if_wi.c revision 253756
1/*-
2 * Copyright (c) 1997, 1998, 1999
3 *	Bill Paul <wpaul@ctr.columbia.edu>.  All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 *    must display the following acknowledgement:
15 *	This product includes software developed by Bill Paul.
16 * 4. Neither the name of the author nor the names of any co-contributors
17 *    may be used to endorse or promote products derived from this software
18 *    without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
30 * THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33/*
34 * Lucent WaveLAN/IEEE 802.11 PCMCIA driver.
35 *
36 * Original FreeBSD driver written by Bill Paul <wpaul@ctr.columbia.edu>
37 * Electrical Engineering Department
38 * Columbia University, New York City
39 */
40
41/*
42 * The WaveLAN/IEEE adapter is the second generation of the WaveLAN
43 * from Lucent. Unlike the older cards, the new ones are programmed
44 * entirely via a firmware-driven controller called the Hermes.
45 * Unfortunately, Lucent will not release the Hermes programming manual
46 * without an NDA (if at all). What they do release is an API library
47 * called the HCF (Hardware Control Functions) which is supposed to
48 * do the device-specific operations of a device driver for you. The
49 * publically available version of the HCF library (the 'HCF Light') is
50 * a) extremely gross, b) lacks certain features, particularly support
51 * for 802.11 frames, and c) is contaminated by the GNU Public License.
52 *
53 * This driver does not use the HCF or HCF Light at all. Instead, it
54 * programs the Hermes controller directly, using information gleaned
55 * from the HCF Light code and corresponding documentation.
56 *
57 * This driver supports the ISA, PCMCIA and PCI versions of the Lucent
58 * WaveLan cards (based on the Hermes chipset), as well as the newer
59 * Prism 2 chipsets with firmware from Intersil and Symbol.
60 */
61
62#include <sys/cdefs.h>
63__FBSDID("$FreeBSD: head/sys/dev/wi/if_wi.c 253756 2013-07-29 05:39:20Z jhibbits $");
64
65#include "opt_wlan.h"
66
67#define WI_HERMES_STATS_WAR	/* Work around stats counter bug. */
68
69#include <sys/param.h>
70#include <sys/systm.h>
71#include <sys/endian.h>
72#include <sys/sockio.h>
73#include <sys/mbuf.h>
74#include <sys/priv.h>
75#include <sys/proc.h>
76#include <sys/kernel.h>
77#include <sys/socket.h>
78#include <sys/module.h>
79#include <sys/bus.h>
80#include <sys/random.h>
81#include <sys/syslog.h>
82#include <sys/sysctl.h>
83
84#include <machine/bus.h>
85#include <machine/resource.h>
86#include <machine/atomic.h>
87#include <sys/rman.h>
88
89#include <net/if.h>
90#include <net/if_arp.h>
91#include <net/ethernet.h>
92#include <net/if_dl.h>
93#include <net/if_llc.h>
94#include <net/if_media.h>
95#include <net/if_types.h>
96
97#include <net80211/ieee80211_var.h>
98#include <net80211/ieee80211_ioctl.h>
99#include <net80211/ieee80211_radiotap.h>
100
101#include <netinet/in.h>
102#include <netinet/in_systm.h>
103#include <netinet/in_var.h>
104#include <netinet/ip.h>
105#include <netinet/if_ether.h>
106
107#include <net/bpf.h>
108
109#include <dev/wi/if_wavelan_ieee.h>
110#include <dev/wi/if_wireg.h>
111#include <dev/wi/if_wivar.h>
112
113static struct ieee80211vap *wi_vap_create(struct ieee80211com *,
114		    const char [IFNAMSIZ], int, enum ieee80211_opmode, int,
115		    const uint8_t [IEEE80211_ADDR_LEN],
116		    const uint8_t [IEEE80211_ADDR_LEN]);
117static void wi_vap_delete(struct ieee80211vap *vap);
118static void wi_stop_locked(struct wi_softc *sc, int disable);
119static void wi_start_locked(struct ifnet *);
120static void wi_start(struct ifnet *);
121static int  wi_start_tx(struct ifnet *ifp, struct wi_frame *frmhdr,
122		struct mbuf *m0);
123static int  wi_raw_xmit(struct ieee80211_node *, struct mbuf *,
124		const struct ieee80211_bpf_params *);
125static int  wi_newstate_sta(struct ieee80211vap *, enum ieee80211_state, int);
126static int  wi_newstate_hostap(struct ieee80211vap *, enum ieee80211_state,
127		int);
128static void wi_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m,
129		int subtype, int rssi, int nf);
130static int  wi_reset(struct wi_softc *);
131static void wi_watchdog(void *);
132static int  wi_ioctl(struct ifnet *, u_long, caddr_t);
133static void wi_media_status(struct ifnet *, struct ifmediareq *);
134
135static void wi_rx_intr(struct wi_softc *);
136static void wi_tx_intr(struct wi_softc *);
137static void wi_tx_ex_intr(struct wi_softc *);
138
139static void wi_info_intr(struct wi_softc *);
140
141static int  wi_write_txrate(struct wi_softc *, struct ieee80211vap *);
142static int  wi_write_wep(struct wi_softc *, struct ieee80211vap *);
143static int  wi_write_multi(struct wi_softc *);
144static void wi_update_mcast(struct ifnet *);
145static void wi_update_promisc(struct ifnet *);
146static int  wi_alloc_fid(struct wi_softc *, int, int *);
147static void wi_read_nicid(struct wi_softc *);
148static int  wi_write_ssid(struct wi_softc *, int, u_int8_t *, int);
149
150static int  wi_cmd(struct wi_softc *, int, int, int, int);
151static int  wi_seek_bap(struct wi_softc *, int, int);
152static int  wi_read_bap(struct wi_softc *, int, int, void *, int);
153static int  wi_write_bap(struct wi_softc *, int, int, void *, int);
154static int  wi_mwrite_bap(struct wi_softc *, int, int, struct mbuf *, int);
155static int  wi_read_rid(struct wi_softc *, int, void *, int *);
156static int  wi_write_rid(struct wi_softc *, int, void *, int);
157static int  wi_write_appie(struct wi_softc *, int, const struct ieee80211_appie *);
158
159static void wi_scan_start(struct ieee80211com *);
160static void wi_scan_end(struct ieee80211com *);
161static void wi_set_channel(struct ieee80211com *);
162
163static __inline int
164wi_write_val(struct wi_softc *sc, int rid, u_int16_t val)
165{
166
167	val = htole16(val);
168	return wi_write_rid(sc, rid, &val, sizeof(val));
169}
170
171static SYSCTL_NODE(_hw, OID_AUTO, wi, CTLFLAG_RD, 0,
172	    "Wireless driver parameters");
173
174static	struct timeval lasttxerror;	/* time of last tx error msg */
175static	int curtxeps;			/* current tx error msgs/sec */
176static	int wi_txerate = 0;		/* tx error rate: max msgs/sec */
177SYSCTL_INT(_hw_wi, OID_AUTO, txerate, CTLFLAG_RW, &wi_txerate,
178	    0, "max tx error msgs/sec; 0 to disable msgs");
179
180#define	WI_DEBUG
181#ifdef WI_DEBUG
182static	int wi_debug = 0;
183SYSCTL_INT(_hw_wi, OID_AUTO, debug, CTLFLAG_RW, &wi_debug,
184	    0, "control debugging printfs");
185#define	DPRINTF(X)	if (wi_debug) printf X
186#else
187#define	DPRINTF(X)
188#endif
189
190#define WI_INTRS	(WI_EV_RX | WI_EV_ALLOC | WI_EV_INFO)
191
192struct wi_card_ident wi_card_ident[] = {
193	/* CARD_ID			CARD_NAME		FIRM_TYPE */
194	{ WI_NIC_LUCENT_ID,		WI_NIC_LUCENT_STR,	WI_LUCENT },
195	{ WI_NIC_SONY_ID,		WI_NIC_SONY_STR,	WI_LUCENT },
196	{ WI_NIC_LUCENT_EMB_ID,		WI_NIC_LUCENT_EMB_STR,	WI_LUCENT },
197	{ WI_NIC_EVB2_ID,		WI_NIC_EVB2_STR,	WI_INTERSIL },
198	{ WI_NIC_HWB3763_ID,		WI_NIC_HWB3763_STR,	WI_INTERSIL },
199	{ WI_NIC_HWB3163_ID,		WI_NIC_HWB3163_STR,	WI_INTERSIL },
200	{ WI_NIC_HWB3163B_ID,		WI_NIC_HWB3163B_STR,	WI_INTERSIL },
201	{ WI_NIC_EVB3_ID,		WI_NIC_EVB3_STR,	WI_INTERSIL },
202	{ WI_NIC_HWB1153_ID,		WI_NIC_HWB1153_STR,	WI_INTERSIL },
203	{ WI_NIC_P2_SST_ID,		WI_NIC_P2_SST_STR,	WI_INTERSIL },
204	{ WI_NIC_EVB2_SST_ID,		WI_NIC_EVB2_SST_STR,	WI_INTERSIL },
205	{ WI_NIC_3842_EVA_ID,		WI_NIC_3842_EVA_STR,	WI_INTERSIL },
206	{ WI_NIC_3842_PCMCIA_AMD_ID,	WI_NIC_3842_PCMCIA_STR,	WI_INTERSIL },
207	{ WI_NIC_3842_PCMCIA_SST_ID,	WI_NIC_3842_PCMCIA_STR,	WI_INTERSIL },
208	{ WI_NIC_3842_PCMCIA_ATL_ID,	WI_NIC_3842_PCMCIA_STR,	WI_INTERSIL },
209	{ WI_NIC_3842_PCMCIA_ATS_ID,	WI_NIC_3842_PCMCIA_STR,	WI_INTERSIL },
210	{ WI_NIC_3842_MINI_AMD_ID,	WI_NIC_3842_MINI_STR,	WI_INTERSIL },
211	{ WI_NIC_3842_MINI_SST_ID,	WI_NIC_3842_MINI_STR,	WI_INTERSIL },
212	{ WI_NIC_3842_MINI_ATL_ID,	WI_NIC_3842_MINI_STR,	WI_INTERSIL },
213	{ WI_NIC_3842_MINI_ATS_ID,	WI_NIC_3842_MINI_STR,	WI_INTERSIL },
214	{ WI_NIC_3842_PCI_AMD_ID,	WI_NIC_3842_PCI_STR,	WI_INTERSIL },
215	{ WI_NIC_3842_PCI_SST_ID,	WI_NIC_3842_PCI_STR,	WI_INTERSIL },
216	{ WI_NIC_3842_PCI_ATS_ID,	WI_NIC_3842_PCI_STR,	WI_INTERSIL },
217	{ WI_NIC_3842_PCI_ATL_ID,	WI_NIC_3842_PCI_STR,	WI_INTERSIL },
218	{ WI_NIC_P3_PCMCIA_AMD_ID,	WI_NIC_P3_PCMCIA_STR,	WI_INTERSIL },
219	{ WI_NIC_P3_PCMCIA_SST_ID,	WI_NIC_P3_PCMCIA_STR,	WI_INTERSIL },
220	{ WI_NIC_P3_PCMCIA_ATL_ID,	WI_NIC_P3_PCMCIA_STR,	WI_INTERSIL },
221	{ WI_NIC_P3_PCMCIA_ATS_ID,	WI_NIC_P3_PCMCIA_STR,	WI_INTERSIL },
222	{ WI_NIC_P3_MINI_AMD_ID,	WI_NIC_P3_MINI_STR,	WI_INTERSIL },
223	{ WI_NIC_P3_MINI_SST_ID,	WI_NIC_P3_MINI_STR,	WI_INTERSIL },
224	{ WI_NIC_P3_MINI_ATL_ID,	WI_NIC_P3_MINI_STR,	WI_INTERSIL },
225	{ WI_NIC_P3_MINI_ATS_ID,	WI_NIC_P3_MINI_STR,	WI_INTERSIL },
226	{ 0,	NULL,	0 },
227};
228
229static char *wi_firmware_names[] = { "none", "Hermes", "Intersil", "Symbol" };
230
231devclass_t wi_devclass;
232
233int
234wi_attach(device_t dev)
235{
236	struct wi_softc	*sc = device_get_softc(dev);
237	struct ieee80211com *ic;
238	struct ifnet *ifp;
239	int i, nrates, buflen;
240	u_int16_t val;
241	u_int8_t ratebuf[2 + IEEE80211_RATE_SIZE];
242	struct ieee80211_rateset *rs;
243	struct sysctl_ctx_list *sctx;
244	struct sysctl_oid *soid;
245	static const u_int8_t empty_macaddr[IEEE80211_ADDR_LEN] = {
246		0x00, 0x00, 0x00, 0x00, 0x00, 0x00
247	};
248	int error;
249	uint8_t macaddr[IEEE80211_ADDR_LEN];
250
251	ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
252	if (ifp == NULL) {
253		device_printf(dev, "can not if_alloc\n");
254		wi_free(dev);
255		return ENOSPC;
256	}
257	ic = ifp->if_l2com;
258
259	sc->sc_firmware_type = WI_NOTYPE;
260	sc->wi_cmd_count = 500;
261	/* Reset the NIC. */
262	if (wi_reset(sc) != 0) {
263		wi_free(dev);
264		return ENXIO;		/* XXX */
265	}
266
267	/* Read NIC identification */
268	wi_read_nicid(sc);
269	switch (sc->sc_firmware_type) {
270	case WI_LUCENT:
271		if (sc->sc_sta_firmware_ver < 60006)
272			goto reject;
273		break;
274	case WI_INTERSIL:
275		if (sc->sc_sta_firmware_ver < 800)
276			goto reject;
277		break;
278	default:
279	reject:
280		device_printf(dev, "Sorry, this card is not supported "
281		    "(type %d, firmware ver %d)\n",
282		    sc->sc_firmware_type, sc->sc_sta_firmware_ver);
283		wi_free(dev);
284		return EOPNOTSUPP;
285	}
286
287	/* Export info about the device via sysctl */
288	sctx = device_get_sysctl_ctx(dev);
289	soid = device_get_sysctl_tree(dev);
290	SYSCTL_ADD_STRING(sctx, SYSCTL_CHILDREN(soid), OID_AUTO,
291	    "firmware_type", CTLFLAG_RD,
292	    wi_firmware_names[sc->sc_firmware_type], 0,
293	    "Firmware type string");
294	SYSCTL_ADD_INT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "sta_version",
295	    CTLFLAG_RD, &sc->sc_sta_firmware_ver, 0,
296	    "Station Firmware version");
297	if (sc->sc_firmware_type == WI_INTERSIL)
298		SYSCTL_ADD_INT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO,
299		    "pri_version", CTLFLAG_RD, &sc->sc_pri_firmware_ver, 0,
300		    "Primary Firmware version");
301	SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "nic_id",
302	    CTLFLAG_RD, &sc->sc_nic_id, 0, "NIC id");
303	SYSCTL_ADD_STRING(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "nic_name",
304	    CTLFLAG_RD, sc->sc_nic_name, 0, "NIC name");
305
306	mtx_init(&sc->sc_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
307	    MTX_DEF | MTX_RECURSE);
308	callout_init_mtx(&sc->sc_watchdog, &sc->sc_mtx, 0);
309
310	/*
311	 * Read the station address.
312	 * And do it twice. I've seen PRISM-based cards that return
313	 * an error when trying to read it the first time, which causes
314	 * the probe to fail.
315	 */
316	buflen = IEEE80211_ADDR_LEN;
317	error = wi_read_rid(sc, WI_RID_MAC_NODE, macaddr, &buflen);
318	if (error != 0) {
319		buflen = IEEE80211_ADDR_LEN;
320		error = wi_read_rid(sc, WI_RID_MAC_NODE, macaddr, &buflen);
321	}
322	if (error || IEEE80211_ADDR_EQ(macaddr, empty_macaddr)) {
323		if (error != 0)
324			device_printf(dev, "mac read failed %d\n", error);
325		else {
326			device_printf(dev, "mac read failed (all zeros)\n");
327			error = ENXIO;
328		}
329		wi_free(dev);
330		return (error);
331	}
332
333	ifp->if_softc = sc;
334	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
335	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
336	ifp->if_ioctl = wi_ioctl;
337	ifp->if_start = wi_start;
338	ifp->if_init = wi_init;
339	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
340	ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
341	IFQ_SET_READY(&ifp->if_snd);
342
343	ic->ic_ifp = ifp;
344	ic->ic_phytype = IEEE80211_T_DS;
345	ic->ic_opmode = IEEE80211_M_STA;
346	ic->ic_caps = IEEE80211_C_STA
347		    | IEEE80211_C_PMGT
348		    | IEEE80211_C_MONITOR
349		    ;
350
351	/*
352	 * Query the card for available channels and setup the
353	 * channel table.  We assume these are all 11b channels.
354	 */
355	buflen = sizeof(val);
356	if (wi_read_rid(sc, WI_RID_CHANNEL_LIST, &val, &buflen) != 0)
357		val = htole16(0x1fff);	/* assume 1-11 */
358	KASSERT(val != 0, ("wi_attach: no available channels listed!"));
359
360	val <<= 1;			/* shift for base 1 indices */
361	for (i = 1; i < 16; i++) {
362		struct ieee80211_channel *c;
363
364		if (!isset((u_int8_t*)&val, i))
365			continue;
366		c = &ic->ic_channels[ic->ic_nchans++];
367		c->ic_freq = ieee80211_ieee2mhz(i, IEEE80211_CHAN_B);
368		c->ic_flags = IEEE80211_CHAN_B;
369		c->ic_ieee = i;
370		/* XXX txpowers? */
371	}
372
373	/*
374	 * Set flags based on firmware version.
375	 */
376	switch (sc->sc_firmware_type) {
377	case WI_LUCENT:
378		sc->sc_ntxbuf = 1;
379		ic->ic_caps |= IEEE80211_C_IBSS;
380
381		sc->sc_ibss_port = WI_PORTTYPE_BSS;
382		sc->sc_monitor_port = WI_PORTTYPE_ADHOC;
383		sc->sc_min_rssi = WI_LUCENT_MIN_RSSI;
384		sc->sc_max_rssi = WI_LUCENT_MAX_RSSI;
385		sc->sc_dbm_offset = WI_LUCENT_DBM_OFFSET;
386		break;
387	case WI_INTERSIL:
388		sc->sc_ntxbuf = WI_NTXBUF;
389		sc->sc_flags |= WI_FLAGS_HAS_FRAGTHR
390			     |  WI_FLAGS_HAS_ROAMING;
391		/*
392		 * Old firmware are slow, so give peace a chance.
393		 */
394		if (sc->sc_sta_firmware_ver < 10000)
395			sc->wi_cmd_count = 5000;
396		if (sc->sc_sta_firmware_ver > 10101)
397			sc->sc_flags |= WI_FLAGS_HAS_DBMADJUST;
398		ic->ic_caps |= IEEE80211_C_IBSS;
399		/*
400		 * version 0.8.3 and newer are the only ones that are known
401		 * to currently work.  Earlier versions can be made to work,
402		 * at least according to the Linux driver but we require
403		 * monitor mode so this is irrelevant.
404		 */
405		ic->ic_caps |= IEEE80211_C_HOSTAP;
406		if (sc->sc_sta_firmware_ver >= 10603)
407			sc->sc_flags |= WI_FLAGS_HAS_ENHSECURITY;
408		if (sc->sc_sta_firmware_ver >= 10700) {
409			/*
410			 * 1.7.0+ have the necessary support for sta mode WPA.
411			 */
412			sc->sc_flags |= WI_FLAGS_HAS_WPASUPPORT;
413			ic->ic_caps |= IEEE80211_C_WPA;
414		}
415
416		sc->sc_ibss_port = WI_PORTTYPE_IBSS;
417		sc->sc_monitor_port = WI_PORTTYPE_APSILENT;
418		sc->sc_min_rssi = WI_PRISM_MIN_RSSI;
419		sc->sc_max_rssi = WI_PRISM_MAX_RSSI;
420		sc->sc_dbm_offset = WI_PRISM_DBM_OFFSET;
421		break;
422	}
423
424	/*
425	 * Find out if we support WEP on this card.
426	 */
427	buflen = sizeof(val);
428	if (wi_read_rid(sc, WI_RID_WEP_AVAIL, &val, &buflen) == 0 &&
429	    val != htole16(0))
430		ic->ic_cryptocaps |= IEEE80211_CRYPTO_WEP;
431
432	/* Find supported rates. */
433	buflen = sizeof(ratebuf);
434	rs = &ic->ic_sup_rates[IEEE80211_MODE_11B];
435	if (wi_read_rid(sc, WI_RID_DATA_RATES, ratebuf, &buflen) == 0) {
436		nrates = le16toh(*(u_int16_t *)ratebuf);
437		if (nrates > IEEE80211_RATE_MAXSIZE)
438			nrates = IEEE80211_RATE_MAXSIZE;
439		rs->rs_nrates = 0;
440		for (i = 0; i < nrates; i++)
441			if (ratebuf[2+i])
442				rs->rs_rates[rs->rs_nrates++] = ratebuf[2+i];
443	} else {
444		/* XXX fallback on error? */
445	}
446
447	buflen = sizeof(val);
448	if ((sc->sc_flags & WI_FLAGS_HAS_DBMADJUST) &&
449	    wi_read_rid(sc, WI_RID_DBM_ADJUST, &val, &buflen) == 0) {
450		sc->sc_dbm_offset = le16toh(val);
451	}
452
453	sc->sc_portnum = WI_DEFAULT_PORT;
454
455	ieee80211_ifattach(ic, macaddr);
456	ic->ic_raw_xmit = wi_raw_xmit;
457	ic->ic_scan_start = wi_scan_start;
458	ic->ic_scan_end = wi_scan_end;
459	ic->ic_set_channel = wi_set_channel;
460
461	ic->ic_vap_create = wi_vap_create;
462	ic->ic_vap_delete = wi_vap_delete;
463	ic->ic_update_mcast = wi_update_mcast;
464	ic->ic_update_promisc = wi_update_promisc;
465
466	ieee80211_radiotap_attach(ic,
467	    &sc->sc_tx_th.wt_ihdr, sizeof(sc->sc_tx_th),
468		WI_TX_RADIOTAP_PRESENT,
469	    &sc->sc_rx_th.wr_ihdr, sizeof(sc->sc_rx_th),
470		WI_RX_RADIOTAP_PRESENT);
471
472	if (bootverbose)
473		ieee80211_announce(ic);
474
475	error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET | INTR_MPSAFE,
476	    NULL, wi_intr, sc, &sc->wi_intrhand);
477	if (error) {
478		device_printf(dev, "bus_setup_intr() failed! (%d)\n", error);
479		ieee80211_ifdetach(ic);
480		if_free(sc->sc_ifp);
481		wi_free(dev);
482		return error;
483	}
484
485	return (0);
486}
487
488int
489wi_detach(device_t dev)
490{
491	struct wi_softc	*sc = device_get_softc(dev);
492	struct ifnet *ifp = sc->sc_ifp;
493	struct ieee80211com *ic = ifp->if_l2com;
494
495	WI_LOCK(sc);
496
497	/* check if device was removed */
498	sc->wi_gone |= !bus_child_present(dev);
499
500	wi_stop_locked(sc, 0);
501	WI_UNLOCK(sc);
502	ieee80211_ifdetach(ic);
503
504	bus_teardown_intr(dev, sc->irq, sc->wi_intrhand);
505	if_free(sc->sc_ifp);
506	wi_free(dev);
507	mtx_destroy(&sc->sc_mtx);
508	return (0);
509}
510
511static struct ieee80211vap *
512wi_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
513    enum ieee80211_opmode opmode, int flags,
514    const uint8_t bssid[IEEE80211_ADDR_LEN],
515    const uint8_t mac[IEEE80211_ADDR_LEN])
516{
517	struct wi_softc *sc = ic->ic_ifp->if_softc;
518	struct wi_vap *wvp;
519	struct ieee80211vap *vap;
520
521	if (!TAILQ_EMPTY(&ic->ic_vaps))		/* only one at a time */
522		return NULL;
523	wvp = (struct wi_vap *) malloc(sizeof(struct wi_vap),
524	    M_80211_VAP, M_NOWAIT | M_ZERO);
525	if (wvp == NULL)
526		return NULL;
527
528	vap = &wvp->wv_vap;
529	ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
530
531	vap->iv_max_aid = WI_MAX_AID;
532
533	switch (opmode) {
534	case IEEE80211_M_STA:
535		sc->sc_porttype = WI_PORTTYPE_BSS;
536		wvp->wv_newstate = vap->iv_newstate;
537		vap->iv_newstate = wi_newstate_sta;
538		/* need to filter mgt frames to avoid confusing state machine */
539		wvp->wv_recv_mgmt = vap->iv_recv_mgmt;
540		vap->iv_recv_mgmt = wi_recv_mgmt;
541		break;
542	case IEEE80211_M_IBSS:
543		sc->sc_porttype = sc->sc_ibss_port;
544		wvp->wv_newstate = vap->iv_newstate;
545		vap->iv_newstate = wi_newstate_sta;
546		break;
547	case IEEE80211_M_AHDEMO:
548		sc->sc_porttype = WI_PORTTYPE_ADHOC;
549		break;
550	case IEEE80211_M_HOSTAP:
551		sc->sc_porttype = WI_PORTTYPE_HOSTAP;
552		wvp->wv_newstate = vap->iv_newstate;
553		vap->iv_newstate = wi_newstate_hostap;
554		break;
555	case IEEE80211_M_MONITOR:
556		sc->sc_porttype = sc->sc_monitor_port;
557		break;
558	default:
559		break;
560	}
561
562	/* complete setup */
563	ieee80211_vap_attach(vap, ieee80211_media_change, wi_media_status);
564	ic->ic_opmode = opmode;
565	return vap;
566}
567
568static void
569wi_vap_delete(struct ieee80211vap *vap)
570{
571	struct wi_vap *wvp = WI_VAP(vap);
572
573	ieee80211_vap_detach(vap);
574	free(wvp, M_80211_VAP);
575}
576
577int
578wi_shutdown(device_t dev)
579{
580	struct wi_softc *sc = device_get_softc(dev);
581
582	wi_stop(sc, 1);
583	return (0);
584}
585
586void
587wi_intr(void *arg)
588{
589	struct wi_softc *sc = arg;
590	struct ifnet *ifp = sc->sc_ifp;
591	u_int16_t status;
592
593	WI_LOCK(sc);
594
595	if (sc->wi_gone || !sc->sc_enabled || (ifp->if_flags & IFF_UP) == 0) {
596		CSR_WRITE_2(sc, WI_INT_EN, 0);
597		CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF);
598		WI_UNLOCK(sc);
599		return;
600	}
601
602	/* Disable interrupts. */
603	CSR_WRITE_2(sc, WI_INT_EN, 0);
604
605	status = CSR_READ_2(sc, WI_EVENT_STAT);
606	if (status & WI_EV_RX)
607		wi_rx_intr(sc);
608	if (status & WI_EV_ALLOC)
609		wi_tx_intr(sc);
610	if (status & WI_EV_TX_EXC)
611		wi_tx_ex_intr(sc);
612	if (status & WI_EV_INFO)
613		wi_info_intr(sc);
614	if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0 &&
615	    !IFQ_DRV_IS_EMPTY(&ifp->if_snd))
616		wi_start_locked(ifp);
617
618	/* Re-enable interrupts. */
619	CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS);
620
621	WI_UNLOCK(sc);
622
623	return;
624}
625
626static void
627wi_enable(struct wi_softc *sc)
628{
629	/* Enable interrupts */
630	CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS);
631
632	/* enable port */
633	wi_cmd(sc, WI_CMD_ENABLE | sc->sc_portnum, 0, 0, 0);
634	sc->sc_enabled = 1;
635}
636
637static int
638wi_setup_locked(struct wi_softc *sc, int porttype, int mode,
639	uint8_t mac[IEEE80211_ADDR_LEN])
640{
641	int i;
642
643	wi_reset(sc);
644
645	wi_write_val(sc, WI_RID_PORTTYPE, porttype);
646	wi_write_val(sc, WI_RID_CREATE_IBSS, mode);
647	wi_write_val(sc, WI_RID_MAX_DATALEN, 2304);
648	/* XXX IEEE80211_BPF_NOACK wants 0 */
649	wi_write_val(sc, WI_RID_ALT_RETRY_CNT, 2);
650	if (sc->sc_flags & WI_FLAGS_HAS_ROAMING)
651		wi_write_val(sc, WI_RID_ROAMING_MODE, 3); /* NB: disabled */
652
653	wi_write_rid(sc, WI_RID_MAC_NODE, mac, IEEE80211_ADDR_LEN);
654
655	/* Allocate fids for the card */
656	sc->sc_buflen = IEEE80211_MAX_LEN + sizeof(struct wi_frame);
657	for (i = 0; i < sc->sc_ntxbuf; i++) {
658		int error = wi_alloc_fid(sc, sc->sc_buflen,
659		    &sc->sc_txd[i].d_fid);
660		if (error) {
661			device_printf(sc->sc_dev,
662			    "tx buffer allocation failed (error %u)\n",
663			    error);
664			return error;
665		}
666		sc->sc_txd[i].d_len = 0;
667	}
668	sc->sc_txcur = sc->sc_txnext = 0;
669
670	return 0;
671}
672
673static void
674wi_init_locked(struct wi_softc *sc)
675{
676	struct ifnet *ifp = sc->sc_ifp;
677	int wasenabled;
678
679	WI_LOCK_ASSERT(sc);
680
681	wasenabled = sc->sc_enabled;
682	if (wasenabled)
683		wi_stop_locked(sc, 1);
684
685	if (wi_setup_locked(sc, sc->sc_porttype, 3, IF_LLADDR(ifp)) != 0) {
686		if_printf(ifp, "interface not running\n");
687		wi_stop_locked(sc, 1);
688		return;
689	}
690
691	ifp->if_drv_flags |= IFF_DRV_RUNNING;
692	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
693
694	callout_reset(&sc->sc_watchdog, hz, wi_watchdog, sc);
695
696	wi_enable(sc);			/* Enable desired port */
697}
698
699void
700wi_init(void *arg)
701{
702	struct wi_softc *sc = arg;
703	struct ifnet *ifp = sc->sc_ifp;
704	struct ieee80211com *ic = ifp->if_l2com;
705
706	WI_LOCK(sc);
707	wi_init_locked(sc);
708	WI_UNLOCK(sc);
709
710	if (ifp->if_drv_flags & IFF_DRV_RUNNING)
711		ieee80211_start_all(ic);		/* start all vap's */
712}
713
714static void
715wi_stop_locked(struct wi_softc *sc, int disable)
716{
717	struct ifnet *ifp = sc->sc_ifp;
718
719	WI_LOCK_ASSERT(sc);
720
721	if (sc->sc_enabled && !sc->wi_gone) {
722		CSR_WRITE_2(sc, WI_INT_EN, 0);
723		wi_cmd(sc, WI_CMD_DISABLE | sc->sc_portnum, 0, 0, 0);
724		if (disable)
725			sc->sc_enabled = 0;
726	} else if (sc->wi_gone && disable)	/* gone --> not enabled */
727		sc->sc_enabled = 0;
728
729	callout_stop(&sc->sc_watchdog);
730	sc->sc_tx_timer = 0;
731	sc->sc_false_syns = 0;
732
733	ifp->if_drv_flags &= ~(IFF_DRV_OACTIVE | IFF_DRV_RUNNING);
734}
735
736void
737wi_stop(struct wi_softc *sc, int disable)
738{
739	WI_LOCK(sc);
740	wi_stop_locked(sc, disable);
741	WI_UNLOCK(sc);
742}
743
744static void
745wi_set_channel(struct ieee80211com *ic)
746{
747	struct ifnet *ifp = ic->ic_ifp;
748	struct wi_softc *sc = ifp->if_softc;
749
750	DPRINTF(("%s: channel %d, %sscanning\n", __func__,
751	    ieee80211_chan2ieee(ic, ic->ic_curchan),
752	    ic->ic_flags & IEEE80211_F_SCAN ? "" : "!"));
753
754	WI_LOCK(sc);
755	wi_write_val(sc, WI_RID_OWN_CHNL,
756	    ieee80211_chan2ieee(ic, ic->ic_curchan));
757	WI_UNLOCK(sc);
758}
759
760static void
761wi_scan_start(struct ieee80211com *ic)
762{
763	struct ifnet *ifp = ic->ic_ifp;
764	struct wi_softc *sc = ifp->if_softc;
765	struct ieee80211_scan_state *ss = ic->ic_scan;
766
767	DPRINTF(("%s\n", __func__));
768
769	WI_LOCK(sc);
770	/*
771	 * Switch device to monitor mode.
772	 */
773	wi_write_val(sc, WI_RID_PORTTYPE, sc->sc_monitor_port);
774	if (sc->sc_firmware_type == WI_INTERSIL) {
775		wi_cmd(sc, WI_CMD_DISABLE | WI_PORT0, 0, 0, 0);
776		wi_cmd(sc, WI_CMD_ENABLE | WI_PORT0, 0, 0, 0);
777	}
778	/* force full dwell time to compensate for firmware overhead */
779	ss->ss_mindwell = ss->ss_maxdwell = msecs_to_ticks(400);
780	WI_UNLOCK(sc);
781
782}
783
784static void
785wi_scan_end(struct ieee80211com *ic)
786{
787	struct ifnet *ifp = ic->ic_ifp;
788	struct wi_softc *sc = ifp->if_softc;
789
790	DPRINTF(("%s: restore port type %d\n", __func__, sc->sc_porttype));
791
792	WI_LOCK(sc);
793	wi_write_val(sc, WI_RID_PORTTYPE, sc->sc_porttype);
794	if (sc->sc_firmware_type == WI_INTERSIL) {
795		wi_cmd(sc, WI_CMD_DISABLE | WI_PORT0, 0, 0, 0);
796		wi_cmd(sc, WI_CMD_ENABLE | WI_PORT0, 0, 0, 0);
797	}
798	WI_UNLOCK(sc);
799}
800
801static void
802wi_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m,
803	int subtype, int rssi, int nf)
804{
805	struct ieee80211vap *vap = ni->ni_vap;
806
807	switch (subtype) {
808	case IEEE80211_FC0_SUBTYPE_AUTH:
809	case IEEE80211_FC0_SUBTYPE_ASSOC_RESP:
810	case IEEE80211_FC0_SUBTYPE_REASSOC_RESP:
811		/* NB: filter frames that trigger state changes */
812		return;
813	}
814	WI_VAP(vap)->wv_recv_mgmt(ni, m, subtype, rssi, nf);
815}
816
817static int
818wi_newstate_sta(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
819{
820	struct ieee80211com *ic = vap->iv_ic;
821	struct ifnet *ifp = ic->ic_ifp;
822	struct ieee80211_node *bss;
823	struct wi_softc *sc = ifp->if_softc;
824
825	DPRINTF(("%s: %s -> %s\n", __func__,
826		ieee80211_state_name[vap->iv_state],
827		ieee80211_state_name[nstate]));
828
829	if (nstate == IEEE80211_S_AUTH) {
830		WI_LOCK(sc);
831		wi_setup_locked(sc, WI_PORTTYPE_BSS, 3, vap->iv_myaddr);
832
833		if (vap->iv_flags & IEEE80211_F_PMGTON) {
834			wi_write_val(sc, WI_RID_MAX_SLEEP, ic->ic_lintval);
835			wi_write_val(sc, WI_RID_PM_ENABLED, 1);
836		}
837		wi_write_val(sc, WI_RID_RTS_THRESH, vap->iv_rtsthreshold);
838		if (sc->sc_flags & WI_FLAGS_HAS_FRAGTHR)
839			wi_write_val(sc, WI_RID_FRAG_THRESH,
840			    vap->iv_fragthreshold);
841		wi_write_txrate(sc, vap);
842
843		bss = vap->iv_bss;
844		wi_write_ssid(sc, WI_RID_DESIRED_SSID, bss->ni_essid, bss->ni_esslen);
845		wi_write_val(sc, WI_RID_OWN_CHNL,
846		    ieee80211_chan2ieee(ic, bss->ni_chan));
847
848		/* Configure WEP. */
849		if (ic->ic_cryptocaps & IEEE80211_CRYPTO_WEP)
850			wi_write_wep(sc, vap);
851		else
852			sc->sc_encryption = 0;
853
854		if ((sc->sc_flags & WI_FLAGS_HAS_WPASUPPORT) &&
855		    (vap->iv_flags & IEEE80211_F_WPA)) {
856			wi_write_val(sc, WI_RID_WPA_HANDLING, 1);
857			if (vap->iv_appie_wpa != NULL)
858				wi_write_appie(sc, WI_RID_WPA_DATA,
859				    vap->iv_appie_wpa);
860		}
861
862		wi_enable(sc);		/* enable port */
863
864		/* Lucent firmware does not support the JOIN RID. */
865		if (sc->sc_firmware_type == WI_INTERSIL) {
866			struct wi_joinreq join;
867
868			memset(&join, 0, sizeof(join));
869			IEEE80211_ADDR_COPY(&join.wi_bssid, bss->ni_bssid);
870			join.wi_chan = htole16(
871			    ieee80211_chan2ieee(ic, bss->ni_chan));
872			wi_write_rid(sc, WI_RID_JOIN_REQ, &join, sizeof(join));
873		}
874		WI_UNLOCK(sc);
875
876		/*
877		 * NB: don't go through 802.11 layer, it'll send auth frame;
878		 * instead we drive the state machine from the link status
879		 * notification we get on association.
880		 */
881		vap->iv_state = nstate;
882		return (0);
883	}
884	return WI_VAP(vap)->wv_newstate(vap, nstate, arg);
885}
886
887static int
888wi_newstate_hostap(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
889{
890	struct ieee80211com *ic = vap->iv_ic;
891	struct ifnet *ifp = ic->ic_ifp;
892	struct ieee80211_node *bss;
893	struct wi_softc *sc = ifp->if_softc;
894	int error;
895
896	DPRINTF(("%s: %s -> %s\n", __func__,
897		ieee80211_state_name[vap->iv_state],
898		ieee80211_state_name[nstate]));
899
900	error = WI_VAP(vap)->wv_newstate(vap, nstate, arg);
901	if (error == 0 && nstate == IEEE80211_S_RUN) {
902		WI_LOCK(sc);
903		wi_setup_locked(sc, WI_PORTTYPE_HOSTAP, 0, vap->iv_myaddr);
904
905		bss = vap->iv_bss;
906		wi_write_ssid(sc, WI_RID_OWN_SSID,
907		    bss->ni_essid, bss->ni_esslen);
908		wi_write_val(sc, WI_RID_OWN_CHNL,
909		    ieee80211_chan2ieee(ic, bss->ni_chan));
910		wi_write_val(sc, WI_RID_BASIC_RATE, 0x3);
911		wi_write_val(sc, WI_RID_SUPPORT_RATE, 0xf);
912		wi_write_txrate(sc, vap);
913
914		wi_write_val(sc, WI_RID_OWN_BEACON_INT, bss->ni_intval);
915		wi_write_val(sc, WI_RID_DTIM_PERIOD, vap->iv_dtim_period);
916
917		wi_write_val(sc, WI_RID_RTS_THRESH, vap->iv_rtsthreshold);
918		if (sc->sc_flags & WI_FLAGS_HAS_FRAGTHR)
919			wi_write_val(sc, WI_RID_FRAG_THRESH,
920			    vap->iv_fragthreshold);
921
922		if ((sc->sc_flags & WI_FLAGS_HAS_ENHSECURITY) &&
923		    (vap->iv_flags & IEEE80211_F_HIDESSID)) {
924			/*
925			 * bit 0 means hide SSID in beacons,
926			 * bit 1 means don't respond to bcast probe req
927			 */
928			wi_write_val(sc, WI_RID_ENH_SECURITY, 0x3);
929		}
930
931		if ((sc->sc_flags & WI_FLAGS_HAS_WPASUPPORT) &&
932		    (vap->iv_flags & IEEE80211_F_WPA) &&
933		    vap->iv_appie_wpa != NULL)
934			wi_write_appie(sc, WI_RID_WPA_DATA, vap->iv_appie_wpa);
935
936		wi_write_val(sc, WI_RID_PROMISC, 0);
937
938		/* Configure WEP. */
939		if (ic->ic_cryptocaps & IEEE80211_CRYPTO_WEP)
940			wi_write_wep(sc, vap);
941		else
942			sc->sc_encryption = 0;
943
944		wi_enable(sc);		/* enable port */
945		WI_UNLOCK(sc);
946	}
947	return error;
948}
949
950static void
951wi_start_locked(struct ifnet *ifp)
952{
953	struct wi_softc	*sc = ifp->if_softc;
954	struct ieee80211_node *ni;
955	struct ieee80211_frame *wh;
956	struct mbuf *m0;
957	struct ieee80211_key *k;
958	struct wi_frame frmhdr;
959	const struct llc *llc;
960	int cur;
961
962	WI_LOCK_ASSERT(sc);
963
964	if (sc->wi_gone)
965		return;
966
967	memset(&frmhdr, 0, sizeof(frmhdr));
968	cur = sc->sc_txnext;
969	for (;;) {
970		IFQ_DRV_DEQUEUE(&ifp->if_snd, m0);
971		if (m0 == NULL)
972			break;
973		if (sc->sc_txd[cur].d_len != 0) {
974			IFQ_DRV_PREPEND(&ifp->if_snd, m0);
975			ifp->if_drv_flags |= IFF_DRV_OACTIVE;
976			break;
977		}
978		ni = (struct ieee80211_node *) m0->m_pkthdr.rcvif;
979
980		/* reconstruct 802.3 header */
981		wh = mtod(m0, struct ieee80211_frame *);
982		switch (wh->i_fc[1]) {
983		case IEEE80211_FC1_DIR_TODS:
984			IEEE80211_ADDR_COPY(frmhdr.wi_ehdr.ether_shost,
985			    wh->i_addr2);
986			IEEE80211_ADDR_COPY(frmhdr.wi_ehdr.ether_dhost,
987			    wh->i_addr3);
988			break;
989		case IEEE80211_FC1_DIR_NODS:
990			IEEE80211_ADDR_COPY(frmhdr.wi_ehdr.ether_shost,
991			    wh->i_addr2);
992			IEEE80211_ADDR_COPY(frmhdr.wi_ehdr.ether_dhost,
993			    wh->i_addr1);
994			break;
995		case IEEE80211_FC1_DIR_FROMDS:
996			IEEE80211_ADDR_COPY(frmhdr.wi_ehdr.ether_shost,
997			    wh->i_addr3);
998			IEEE80211_ADDR_COPY(frmhdr.wi_ehdr.ether_dhost,
999			    wh->i_addr1);
1000			break;
1001		}
1002		llc = (const struct llc *)(
1003		    mtod(m0, const uint8_t *) + ieee80211_hdrsize(wh));
1004		frmhdr.wi_ehdr.ether_type = llc->llc_snap.ether_type;
1005		frmhdr.wi_tx_ctl = htole16(WI_ENC_TX_802_11|WI_TXCNTL_TX_EX);
1006		if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
1007			k = ieee80211_crypto_encap(ni, m0);
1008			if (k == NULL) {
1009				ieee80211_free_node(ni);
1010				m_freem(m0);
1011				continue;
1012			}
1013			frmhdr.wi_tx_ctl |= htole16(WI_TXCNTL_NOCRYPT);
1014		}
1015
1016		if (ieee80211_radiotap_active_vap(ni->ni_vap)) {
1017			sc->sc_tx_th.wt_rate = ni->ni_txrate;
1018			ieee80211_radiotap_tx(ni->ni_vap, m0);
1019		}
1020
1021		m_copydata(m0, 0, sizeof(struct ieee80211_frame),
1022		    (caddr_t)&frmhdr.wi_whdr);
1023		m_adj(m0, sizeof(struct ieee80211_frame));
1024		frmhdr.wi_dat_len = htole16(m0->m_pkthdr.len);
1025		ieee80211_free_node(ni);
1026		if (wi_start_tx(ifp, &frmhdr, m0))
1027			continue;
1028
1029		sc->sc_txnext = cur = (cur + 1) % sc->sc_ntxbuf;
1030		ifp->if_opackets++;
1031	}
1032}
1033
1034static void
1035wi_start(struct ifnet *ifp)
1036{
1037	struct wi_softc	*sc = ifp->if_softc;
1038
1039	WI_LOCK(sc);
1040	wi_start_locked(ifp);
1041	WI_UNLOCK(sc);
1042}
1043
1044static int
1045wi_start_tx(struct ifnet *ifp, struct wi_frame *frmhdr, struct mbuf *m0)
1046{
1047	struct wi_softc	*sc = ifp->if_softc;
1048	int cur = sc->sc_txnext;
1049	int fid, off, error;
1050
1051	fid = sc->sc_txd[cur].d_fid;
1052	off = sizeof(*frmhdr);
1053	error = wi_write_bap(sc, fid, 0, frmhdr, sizeof(*frmhdr)) != 0
1054	     || wi_mwrite_bap(sc, fid, off, m0, m0->m_pkthdr.len) != 0;
1055	m_freem(m0);
1056	if (error) {
1057		ifp->if_oerrors++;
1058		return -1;
1059	}
1060	sc->sc_txd[cur].d_len = off;
1061	if (sc->sc_txcur == cur) {
1062		if (wi_cmd(sc, WI_CMD_TX | WI_RECLAIM, fid, 0, 0)) {
1063			if_printf(ifp, "xmit failed\n");
1064			sc->sc_txd[cur].d_len = 0;
1065			return -1;
1066		}
1067		sc->sc_tx_timer = 5;
1068	}
1069	return 0;
1070}
1071
1072static int
1073wi_raw_xmit(struct ieee80211_node *ni, struct mbuf *m0,
1074	    const struct ieee80211_bpf_params *params)
1075{
1076	struct ieee80211com *ic = ni->ni_ic;
1077	struct ifnet *ifp = ic->ic_ifp;
1078	struct ieee80211vap *vap = ni->ni_vap;
1079	struct wi_softc	*sc = ifp->if_softc;
1080	struct ieee80211_key *k;
1081	struct ieee80211_frame *wh;
1082	struct wi_frame frmhdr;
1083	int cur;
1084	int rc = 0;
1085
1086	WI_LOCK(sc);
1087
1088	if (sc->wi_gone) {
1089		rc = ENETDOWN;
1090		goto out;
1091	}
1092	memset(&frmhdr, 0, sizeof(frmhdr));
1093	cur = sc->sc_txnext;
1094	if (sc->sc_txd[cur].d_len != 0) {
1095		ifp->if_drv_flags |= IFF_DRV_OACTIVE;
1096		rc = ENOBUFS;
1097		goto out;
1098	}
1099	m0->m_pkthdr.rcvif = NULL;
1100
1101	m_copydata(m0, 4, ETHER_ADDR_LEN * 2,
1102	    (caddr_t)&frmhdr.wi_ehdr);
1103	frmhdr.wi_ehdr.ether_type = 0;
1104	wh = mtod(m0, struct ieee80211_frame *);
1105
1106	frmhdr.wi_tx_ctl = htole16(WI_ENC_TX_802_11|WI_TXCNTL_TX_EX);
1107	if (params && (params->ibp_flags & IEEE80211_BPF_NOACK))
1108		frmhdr.wi_tx_ctl |= htole16(WI_TXCNTL_ALTRTRY);
1109	if ((wh->i_fc[1] & IEEE80211_FC1_WEP) &&
1110	    (!params || (params && (params->ibp_flags & IEEE80211_BPF_CRYPTO)))) {
1111		k = ieee80211_crypto_encap(ni, m0);
1112		if (k == NULL) {
1113			rc = ENOMEM;
1114			goto out;
1115		}
1116		frmhdr.wi_tx_ctl |= htole16(WI_TXCNTL_NOCRYPT);
1117	}
1118	if (ieee80211_radiotap_active_vap(vap)) {
1119		sc->sc_tx_th.wt_rate = ni->ni_txrate;
1120		ieee80211_radiotap_tx(vap, m0);
1121	}
1122	m_copydata(m0, 0, sizeof(struct ieee80211_frame),
1123	    (caddr_t)&frmhdr.wi_whdr);
1124	m_adj(m0, sizeof(struct ieee80211_frame));
1125	frmhdr.wi_dat_len = htole16(m0->m_pkthdr.len);
1126	if (wi_start_tx(ifp, &frmhdr, m0) < 0) {
1127		m0 = NULL;
1128		rc = EIO;
1129		goto out;
1130	}
1131	m0 = NULL;
1132
1133	sc->sc_txnext = cur = (cur + 1) % sc->sc_ntxbuf;
1134out:
1135	WI_UNLOCK(sc);
1136
1137	if (m0 != NULL)
1138		m_freem(m0);
1139	ieee80211_free_node(ni);
1140	return rc;
1141}
1142
1143static int
1144wi_reset(struct wi_softc *sc)
1145{
1146#define WI_INIT_TRIES 3
1147	int i, error = 0;
1148
1149	for (i = 0; i < WI_INIT_TRIES; i++) {
1150		error = wi_cmd(sc, WI_CMD_INI, 0, 0, 0);
1151		if (error == 0)
1152			break;
1153		DELAY(WI_DELAY * 1000);
1154	}
1155	sc->sc_reset = 1;
1156	if (i == WI_INIT_TRIES) {
1157		if_printf(sc->sc_ifp, "reset failed\n");
1158		return error;
1159	}
1160
1161	CSR_WRITE_2(sc, WI_INT_EN, 0);
1162	CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF);
1163
1164	/* Calibrate timer. */
1165	wi_write_val(sc, WI_RID_TICK_TIME, 8);
1166
1167	return 0;
1168#undef WI_INIT_TRIES
1169}
1170
1171static void
1172wi_watchdog(void *arg)
1173{
1174	struct wi_softc	*sc = arg;
1175	struct ifnet *ifp = sc->sc_ifp;
1176
1177	WI_LOCK_ASSERT(sc);
1178
1179	if (!sc->sc_enabled)
1180		return;
1181
1182	if (sc->sc_tx_timer && --sc->sc_tx_timer == 0) {
1183		if_printf(ifp, "device timeout\n");
1184		ifp->if_oerrors++;
1185		wi_init_locked(ifp->if_softc);
1186		return;
1187	}
1188	callout_reset(&sc->sc_watchdog, hz, wi_watchdog, sc);
1189}
1190
1191static int
1192wi_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
1193{
1194	struct wi_softc *sc = ifp->if_softc;
1195	struct ieee80211com *ic = ifp->if_l2com;
1196	struct ifreq *ifr = (struct ifreq *) data;
1197	int error = 0, startall = 0;
1198
1199	switch (cmd) {
1200	case SIOCSIFFLAGS:
1201		WI_LOCK(sc);
1202		/*
1203		 * Can't do promisc and hostap at the same time.  If all that's
1204		 * changing is the promisc flag, try to short-circuit a call to
1205		 * wi_init() by just setting PROMISC in the hardware.
1206		 */
1207		if (ifp->if_flags & IFF_UP) {
1208			if (ic->ic_opmode != IEEE80211_M_HOSTAP &&
1209			    ifp->if_drv_flags & IFF_DRV_RUNNING) {
1210				if ((ifp->if_flags ^ sc->sc_if_flags) & IFF_PROMISC) {
1211					wi_write_val(sc, WI_RID_PROMISC,
1212					    (ifp->if_flags & IFF_PROMISC) != 0);
1213				} else {
1214					wi_init_locked(sc);
1215					startall = 1;
1216				}
1217			} else {
1218				wi_init_locked(sc);
1219				startall = 1;
1220			}
1221		} else {
1222			if (ifp->if_drv_flags & IFF_DRV_RUNNING)
1223				wi_stop_locked(sc, 1);
1224			sc->wi_gone = 0;
1225		}
1226		sc->sc_if_flags = ifp->if_flags;
1227		WI_UNLOCK(sc);
1228		if (startall)
1229			ieee80211_start_all(ic);
1230		break;
1231	case SIOCGIFMEDIA:
1232		error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
1233		break;
1234	case SIOCGIFADDR:
1235		error = ether_ioctl(ifp, cmd, data);
1236		break;
1237	default:
1238		error = EINVAL;
1239		break;
1240	}
1241	return error;
1242}
1243
1244static void
1245wi_media_status(struct ifnet *ifp, struct ifmediareq *imr)
1246{
1247	struct ieee80211vap *vap = ifp->if_softc;
1248	struct ieee80211com *ic = vap->iv_ic;
1249	struct wi_softc *sc = ic->ic_ifp->if_softc;
1250	u_int16_t val;
1251	int rate, len;
1252
1253	len = sizeof(val);
1254	if (sc->sc_enabled &&
1255	    wi_read_rid(sc, WI_RID_CUR_TX_RATE, &val, &len) == 0 &&
1256	    len == sizeof(val)) {
1257		/* convert to 802.11 rate */
1258		val = le16toh(val);
1259		rate = val * 2;
1260		if (sc->sc_firmware_type == WI_LUCENT) {
1261			if (rate == 10)
1262				rate = 11;	/* 5.5Mbps */
1263		} else {
1264			if (rate == 4*2)
1265				rate = 11;	/* 5.5Mbps */
1266			else if (rate == 8*2)
1267				rate = 22;	/* 11Mbps */
1268		}
1269		vap->iv_bss->ni_txrate = rate;
1270	}
1271	ieee80211_media_status(ifp, imr);
1272}
1273
1274static void
1275wi_sync_bssid(struct wi_softc *sc, u_int8_t new_bssid[IEEE80211_ADDR_LEN])
1276{
1277	struct ifnet *ifp = sc->sc_ifp;
1278	struct ieee80211com *ic = ifp->if_l2com;
1279	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
1280	struct ieee80211_node *ni = vap->iv_bss;
1281
1282	if (IEEE80211_ADDR_EQ(new_bssid, ni->ni_bssid))
1283		return;
1284
1285	DPRINTF(("wi_sync_bssid: bssid %s -> ", ether_sprintf(ni->ni_bssid)));
1286	DPRINTF(("%s ?\n", ether_sprintf(new_bssid)));
1287
1288	/* In promiscuous mode, the BSSID field is not a reliable
1289	 * indicator of the firmware's BSSID. Damp spurious
1290	 * change-of-BSSID indications.
1291	 */
1292	if ((ifp->if_flags & IFF_PROMISC) != 0 &&
1293	    !ppsratecheck(&sc->sc_last_syn, &sc->sc_false_syns,
1294	                 WI_MAX_FALSE_SYNS))
1295		return;
1296
1297	sc->sc_false_syns = MAX(0, sc->sc_false_syns - 1);
1298#if 0
1299	/*
1300	 * XXX hack; we should create a new node with the new bssid
1301	 * and replace the existing ic_bss with it but since we don't
1302	 * process management frames to collect state we cheat by
1303	 * reusing the existing node as we know wi_newstate will be
1304	 * called and it will overwrite the node state.
1305	 */
1306	ieee80211_sta_join(ic, ieee80211_ref_node(ni));
1307#endif
1308}
1309
1310static __noinline void
1311wi_rx_intr(struct wi_softc *sc)
1312{
1313	struct ifnet *ifp = sc->sc_ifp;
1314	struct ieee80211com *ic = ifp->if_l2com;
1315	struct wi_frame frmhdr;
1316	struct mbuf *m;
1317	struct ieee80211_frame *wh;
1318	struct ieee80211_node *ni;
1319	int fid, len, off;
1320	u_int8_t dir;
1321	u_int16_t status;
1322	int8_t rssi, nf;
1323
1324	fid = CSR_READ_2(sc, WI_RX_FID);
1325
1326	/* First read in the frame header */
1327	if (wi_read_bap(sc, fid, 0, &frmhdr, sizeof(frmhdr))) {
1328		CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX);
1329		ifp->if_ierrors++;
1330		DPRINTF(("wi_rx_intr: read fid %x failed\n", fid));
1331		return;
1332	}
1333
1334	/*
1335	 * Drop undecryptable or packets with receive errors here
1336	 */
1337	status = le16toh(frmhdr.wi_status);
1338	if (status & WI_STAT_ERRSTAT) {
1339		CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX);
1340		ifp->if_ierrors++;
1341		DPRINTF(("wi_rx_intr: fid %x error status %x\n", fid, status));
1342		return;
1343	}
1344
1345	len = le16toh(frmhdr.wi_dat_len);
1346	off = ALIGN(sizeof(struct ieee80211_frame));
1347
1348	/*
1349	 * Sometimes the PRISM2.x returns bogusly large frames. Except
1350	 * in monitor mode, just throw them away.
1351	 */
1352	if (off + len > MCLBYTES) {
1353		if (ic->ic_opmode != IEEE80211_M_MONITOR) {
1354			CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX);
1355			ifp->if_ierrors++;
1356			DPRINTF(("wi_rx_intr: oversized packet\n"));
1357			return;
1358		} else
1359			len = 0;
1360	}
1361
1362	if (off + len > MHLEN)
1363		m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
1364	else
1365		m = m_gethdr(M_NOWAIT, MT_DATA);
1366	if (m == NULL) {
1367		CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX);
1368		ifp->if_ierrors++;
1369		DPRINTF(("wi_rx_intr: MGET failed\n"));
1370		return;
1371	}
1372	m->m_data += off - sizeof(struct ieee80211_frame);
1373	memcpy(m->m_data, &frmhdr.wi_whdr, sizeof(struct ieee80211_frame));
1374	wi_read_bap(sc, fid, sizeof(frmhdr),
1375	    m->m_data + sizeof(struct ieee80211_frame), len);
1376	m->m_pkthdr.len = m->m_len = sizeof(struct ieee80211_frame) + len;
1377	m->m_pkthdr.rcvif = ifp;
1378
1379	CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX);
1380
1381	rssi = frmhdr.wi_rx_signal;
1382	nf = frmhdr.wi_rx_silence;
1383	if (ieee80211_radiotap_active(ic)) {
1384		struct wi_rx_radiotap_header *tap = &sc->sc_rx_th;
1385		uint32_t rstamp;
1386
1387		rstamp = (le16toh(frmhdr.wi_rx_tstamp0) << 16) |
1388		    le16toh(frmhdr.wi_rx_tstamp1);
1389		tap->wr_tsf = htole64((uint64_t)rstamp);
1390		/* XXX replace divide by table */
1391		tap->wr_rate = frmhdr.wi_rx_rate / 5;
1392		tap->wr_flags = 0;
1393		if (frmhdr.wi_status & WI_STAT_PCF)
1394			tap->wr_flags |= IEEE80211_RADIOTAP_F_CFP;
1395		if (m->m_flags & M_WEP)
1396			tap->wr_flags |= IEEE80211_RADIOTAP_F_WEP;
1397		tap->wr_antsignal = rssi;
1398		tap->wr_antnoise = nf;
1399	}
1400
1401	/* synchronize driver's BSSID with firmware's BSSID */
1402	wh = mtod(m, struct ieee80211_frame *);
1403	dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK;
1404	if (ic->ic_opmode == IEEE80211_M_IBSS && dir == IEEE80211_FC1_DIR_NODS)
1405		wi_sync_bssid(sc, wh->i_addr3);
1406
1407	WI_UNLOCK(sc);
1408
1409	ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *));
1410	if (ni != NULL) {
1411		(void) ieee80211_input(ni, m, rssi, nf);
1412		ieee80211_free_node(ni);
1413	} else
1414		(void) ieee80211_input_all(ic, m, rssi, nf);
1415
1416	WI_LOCK(sc);
1417}
1418
1419static __noinline void
1420wi_tx_ex_intr(struct wi_softc *sc)
1421{
1422	struct ifnet *ifp = sc->sc_ifp;
1423	struct wi_frame frmhdr;
1424	int fid;
1425
1426	fid = CSR_READ_2(sc, WI_TX_CMP_FID);
1427	/* Read in the frame header */
1428	if (wi_read_bap(sc, fid, 0, &frmhdr, sizeof(frmhdr)) == 0) {
1429		u_int16_t status = le16toh(frmhdr.wi_status);
1430		/*
1431		 * Spontaneous station disconnects appear as xmit
1432		 * errors.  Don't announce them and/or count them
1433		 * as an output error.
1434		 */
1435		if ((status & WI_TXSTAT_DISCONNECT) == 0) {
1436			if (ppsratecheck(&lasttxerror, &curtxeps, wi_txerate)) {
1437				if_printf(ifp, "tx failed");
1438				if (status & WI_TXSTAT_RET_ERR)
1439					printf(", retry limit exceeded");
1440				if (status & WI_TXSTAT_AGED_ERR)
1441					printf(", max transmit lifetime exceeded");
1442				if (status & WI_TXSTAT_DISCONNECT)
1443					printf(", port disconnected");
1444				if (status & WI_TXSTAT_FORM_ERR)
1445					printf(", invalid format (data len %u src %6D)",
1446						le16toh(frmhdr.wi_dat_len),
1447						frmhdr.wi_ehdr.ether_shost, ":");
1448				if (status & ~0xf)
1449					printf(", status=0x%x", status);
1450				printf("\n");
1451			}
1452			ifp->if_oerrors++;
1453		} else {
1454			DPRINTF(("port disconnected\n"));
1455			ifp->if_collisions++;	/* XXX */
1456		}
1457	} else
1458		DPRINTF(("wi_tx_ex_intr: read fid %x failed\n", fid));
1459	CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_TX_EXC);
1460}
1461
1462static __noinline void
1463wi_tx_intr(struct wi_softc *sc)
1464{
1465	struct ifnet *ifp = sc->sc_ifp;
1466	int fid, cur;
1467
1468	if (sc->wi_gone)
1469		return;
1470
1471	fid = CSR_READ_2(sc, WI_ALLOC_FID);
1472	CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_ALLOC);
1473
1474	cur = sc->sc_txcur;
1475	if (sc->sc_txd[cur].d_fid != fid) {
1476		if_printf(ifp, "bad alloc %x != %x, cur %d nxt %d\n",
1477		    fid, sc->sc_txd[cur].d_fid, cur, sc->sc_txnext);
1478		return;
1479	}
1480	sc->sc_tx_timer = 0;
1481	sc->sc_txd[cur].d_len = 0;
1482	sc->sc_txcur = cur = (cur + 1) % sc->sc_ntxbuf;
1483	if (sc->sc_txd[cur].d_len == 0)
1484		ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
1485	else {
1486		if (wi_cmd(sc, WI_CMD_TX | WI_RECLAIM, sc->sc_txd[cur].d_fid,
1487		    0, 0)) {
1488			if_printf(ifp, "xmit failed\n");
1489			sc->sc_txd[cur].d_len = 0;
1490		} else {
1491			sc->sc_tx_timer = 5;
1492		}
1493	}
1494}
1495
1496static __noinline void
1497wi_info_intr(struct wi_softc *sc)
1498{
1499	struct ifnet *ifp = sc->sc_ifp;
1500	struct ieee80211com *ic = ifp->if_l2com;
1501	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
1502	int i, fid, len, off;
1503	u_int16_t ltbuf[2];
1504	u_int16_t stat;
1505	u_int32_t *ptr;
1506
1507	fid = CSR_READ_2(sc, WI_INFO_FID);
1508	wi_read_bap(sc, fid, 0, ltbuf, sizeof(ltbuf));
1509
1510	switch (le16toh(ltbuf[1])) {
1511	case WI_INFO_LINK_STAT:
1512		wi_read_bap(sc, fid, sizeof(ltbuf), &stat, sizeof(stat));
1513		DPRINTF(("wi_info_intr: LINK_STAT 0x%x\n", le16toh(stat)));
1514
1515		if (vap == NULL)
1516			goto finish;
1517
1518		switch (le16toh(stat)) {
1519		case WI_INFO_LINK_STAT_CONNECTED:
1520			if (vap->iv_state == IEEE80211_S_RUN &&
1521			    vap->iv_opmode != IEEE80211_M_IBSS)
1522				break;
1523			/* fall thru... */
1524		case WI_INFO_LINK_STAT_AP_CHG:
1525			IEEE80211_LOCK(ic);
1526			vap->iv_bss->ni_associd = 1 | 0xc000;	/* NB: anything will do */
1527			ieee80211_new_state(vap, IEEE80211_S_RUN, 0);
1528			IEEE80211_UNLOCK(ic);
1529			break;
1530		case WI_INFO_LINK_STAT_AP_INR:
1531			break;
1532		case WI_INFO_LINK_STAT_DISCONNECTED:
1533			/* we dropped off the net; e.g. due to deauth/disassoc */
1534			IEEE80211_LOCK(ic);
1535			vap->iv_bss->ni_associd = 0;
1536			vap->iv_stats.is_rx_deauth++;
1537			ieee80211_new_state(vap, IEEE80211_S_SCAN, 0);
1538			IEEE80211_UNLOCK(ic);
1539			break;
1540		case WI_INFO_LINK_STAT_AP_OOR:
1541			/* XXX does this need to be per-vap? */
1542			ieee80211_beacon_miss(ic);
1543			break;
1544		case WI_INFO_LINK_STAT_ASSOC_FAILED:
1545			if (vap->iv_opmode == IEEE80211_M_STA)
1546				ieee80211_new_state(vap, IEEE80211_S_SCAN,
1547				    IEEE80211_SCAN_FAIL_TIMEOUT);
1548			break;
1549		}
1550		break;
1551	case WI_INFO_COUNTERS:
1552		/* some card versions have a larger stats structure */
1553		len = min(le16toh(ltbuf[0]) - 1, sizeof(sc->sc_stats) / 4);
1554		ptr = (u_int32_t *)&sc->sc_stats;
1555		off = sizeof(ltbuf);
1556		for (i = 0; i < len; i++, off += 2, ptr++) {
1557			wi_read_bap(sc, fid, off, &stat, sizeof(stat));
1558#ifdef WI_HERMES_STATS_WAR
1559			if (stat & 0xf000)
1560				stat = ~stat;
1561#endif
1562			*ptr += stat;
1563		}
1564		ifp->if_collisions = sc->sc_stats.wi_tx_single_retries +
1565		    sc->sc_stats.wi_tx_multi_retries +
1566		    sc->sc_stats.wi_tx_retry_limit;
1567		break;
1568	default:
1569		DPRINTF(("wi_info_intr: got fid %x type %x len %d\n", fid,
1570		    le16toh(ltbuf[1]), le16toh(ltbuf[0])));
1571		break;
1572	}
1573finish:
1574	CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_INFO);
1575}
1576
1577static int
1578wi_write_multi(struct wi_softc *sc)
1579{
1580	struct ifnet *ifp = sc->sc_ifp;
1581	int n;
1582	struct ifmultiaddr *ifma;
1583	struct wi_mcast mlist;
1584
1585	if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
1586allmulti:
1587		memset(&mlist, 0, sizeof(mlist));
1588		return wi_write_rid(sc, WI_RID_MCAST_LIST, &mlist,
1589		    sizeof(mlist));
1590	}
1591
1592	n = 0;
1593	if_maddr_rlock(ifp);
1594	TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
1595		if (ifma->ifma_addr->sa_family != AF_LINK)
1596			continue;
1597		if (n >= 16)
1598			goto allmulti;
1599		IEEE80211_ADDR_COPY(&mlist.wi_mcast[n],
1600		    (LLADDR((struct sockaddr_dl *)ifma->ifma_addr)));
1601		n++;
1602	}
1603	if_maddr_runlock(ifp);
1604	return wi_write_rid(sc, WI_RID_MCAST_LIST, &mlist,
1605	    IEEE80211_ADDR_LEN * n);
1606}
1607
1608static void
1609wi_update_mcast(struct ifnet *ifp)
1610{
1611	wi_write_multi(ifp->if_softc);
1612}
1613
1614static void
1615wi_update_promisc(struct ifnet *ifp)
1616{
1617	struct wi_softc *sc = ifp->if_softc;
1618	struct ieee80211com *ic = ifp->if_l2com;
1619
1620	WI_LOCK(sc);
1621	/* XXX handle WEP special case handling? */
1622	wi_write_val(sc, WI_RID_PROMISC,
1623	    (ic->ic_opmode == IEEE80211_M_MONITOR ||
1624	     (ifp->if_flags & IFF_PROMISC)));
1625	WI_UNLOCK(sc);
1626}
1627
1628static void
1629wi_read_nicid(struct wi_softc *sc)
1630{
1631	struct wi_card_ident *id;
1632	char *p;
1633	int len;
1634	u_int16_t ver[4];
1635
1636	/* getting chip identity */
1637	memset(ver, 0, sizeof(ver));
1638	len = sizeof(ver);
1639	wi_read_rid(sc, WI_RID_CARD_ID, ver, &len);
1640
1641	sc->sc_firmware_type = WI_NOTYPE;
1642	sc->sc_nic_id = le16toh(ver[0]);
1643	for (id = wi_card_ident; id->card_name != NULL; id++) {
1644		if (sc->sc_nic_id == id->card_id) {
1645			sc->sc_nic_name = id->card_name;
1646			sc->sc_firmware_type = id->firm_type;
1647			break;
1648		}
1649	}
1650	if (sc->sc_firmware_type == WI_NOTYPE) {
1651		if (sc->sc_nic_id & 0x8000) {
1652			sc->sc_firmware_type = WI_INTERSIL;
1653			sc->sc_nic_name = "Unknown Prism chip";
1654		} else {
1655			sc->sc_firmware_type = WI_LUCENT;
1656			sc->sc_nic_name = "Unknown Lucent chip";
1657		}
1658	}
1659	if (bootverbose)
1660		device_printf(sc->sc_dev, "using %s\n", sc->sc_nic_name);
1661
1662	/* get primary firmware version (Only Prism chips) */
1663	if (sc->sc_firmware_type != WI_LUCENT) {
1664		memset(ver, 0, sizeof(ver));
1665		len = sizeof(ver);
1666		wi_read_rid(sc, WI_RID_PRI_IDENTITY, ver, &len);
1667		sc->sc_pri_firmware_ver = le16toh(ver[2]) * 10000 +
1668		    le16toh(ver[3]) * 100 + le16toh(ver[1]);
1669	}
1670
1671	/* get station firmware version */
1672	memset(ver, 0, sizeof(ver));
1673	len = sizeof(ver);
1674	wi_read_rid(sc, WI_RID_STA_IDENTITY, ver, &len);
1675	sc->sc_sta_firmware_ver = le16toh(ver[2]) * 10000 +
1676	    le16toh(ver[3]) * 100 + le16toh(ver[1]);
1677	if (sc->sc_firmware_type == WI_INTERSIL &&
1678	    (sc->sc_sta_firmware_ver == 10102 ||
1679	     sc->sc_sta_firmware_ver == 20102)) {
1680		char ident[12];
1681		memset(ident, 0, sizeof(ident));
1682		len = sizeof(ident);
1683		/* value should be the format like "V2.00-11" */
1684		if (wi_read_rid(sc, WI_RID_SYMBOL_IDENTITY, ident, &len) == 0 &&
1685		    *(p = (char *)ident) >= 'A' &&
1686		    p[2] == '.' && p[5] == '-' && p[8] == '\0') {
1687			sc->sc_firmware_type = WI_SYMBOL;
1688			sc->sc_sta_firmware_ver = (p[1] - '0') * 10000 +
1689			    (p[3] - '0') * 1000 + (p[4] - '0') * 100 +
1690			    (p[6] - '0') * 10 + (p[7] - '0');
1691		}
1692	}
1693	if (bootverbose) {
1694		device_printf(sc->sc_dev, "%s Firmware: ",
1695		    wi_firmware_names[sc->sc_firmware_type]);
1696		if (sc->sc_firmware_type != WI_LUCENT)	/* XXX */
1697			printf("Primary (%u.%u.%u), ",
1698			    sc->sc_pri_firmware_ver / 10000,
1699			    (sc->sc_pri_firmware_ver % 10000) / 100,
1700			    sc->sc_pri_firmware_ver % 100);
1701		printf("Station (%u.%u.%u)\n",
1702		    sc->sc_sta_firmware_ver / 10000,
1703		    (sc->sc_sta_firmware_ver % 10000) / 100,
1704		    sc->sc_sta_firmware_ver % 100);
1705	}
1706}
1707
1708static int
1709wi_write_ssid(struct wi_softc *sc, int rid, u_int8_t *buf, int buflen)
1710{
1711	struct wi_ssid ssid;
1712
1713	if (buflen > IEEE80211_NWID_LEN)
1714		return ENOBUFS;
1715	memset(&ssid, 0, sizeof(ssid));
1716	ssid.wi_len = htole16(buflen);
1717	memcpy(ssid.wi_ssid, buf, buflen);
1718	return wi_write_rid(sc, rid, &ssid, sizeof(ssid));
1719}
1720
1721static int
1722wi_write_txrate(struct wi_softc *sc, struct ieee80211vap *vap)
1723{
1724	static const uint16_t lucent_rates[12] = {
1725	    [ 0] = 3,	/* auto */
1726	    [ 1] = 1,	/* 1Mb/s */
1727	    [ 2] = 2,	/* 2Mb/s */
1728	    [ 5] = 4,	/* 5.5Mb/s */
1729	    [11] = 5	/* 11Mb/s */
1730	};
1731	static const uint16_t intersil_rates[12] = {
1732	    [ 0] = 0xf,	/* auto */
1733	    [ 1] = 0,	/* 1Mb/s */
1734	    [ 2] = 1,	/* 2Mb/s */
1735	    [ 5] = 2,	/* 5.5Mb/s */
1736	    [11] = 3,	/* 11Mb/s */
1737	};
1738	const uint16_t *rates = sc->sc_firmware_type == WI_LUCENT ?
1739	    lucent_rates : intersil_rates;
1740	struct ieee80211com *ic = vap->iv_ic;
1741	const struct ieee80211_txparam *tp;
1742
1743	tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_bsschan)];
1744	return wi_write_val(sc, WI_RID_TX_RATE,
1745	    (tp->ucastrate == IEEE80211_FIXED_RATE_NONE ?
1746		rates[0] : rates[tp->ucastrate / 2]));
1747}
1748
1749static int
1750wi_write_wep(struct wi_softc *sc, struct ieee80211vap *vap)
1751{
1752	int error = 0;
1753	int i, keylen;
1754	u_int16_t val;
1755	struct wi_key wkey[IEEE80211_WEP_NKID];
1756
1757	switch (sc->sc_firmware_type) {
1758	case WI_LUCENT:
1759		val = (vap->iv_flags & IEEE80211_F_PRIVACY) ? 1 : 0;
1760		error = wi_write_val(sc, WI_RID_ENCRYPTION, val);
1761		if (error)
1762			break;
1763		if ((vap->iv_flags & IEEE80211_F_PRIVACY) == 0)
1764			break;
1765		error = wi_write_val(sc, WI_RID_TX_CRYPT_KEY, vap->iv_def_txkey);
1766		if (error)
1767			break;
1768		memset(wkey, 0, sizeof(wkey));
1769		for (i = 0; i < IEEE80211_WEP_NKID; i++) {
1770			keylen = vap->iv_nw_keys[i].wk_keylen;
1771			wkey[i].wi_keylen = htole16(keylen);
1772			memcpy(wkey[i].wi_keydat, vap->iv_nw_keys[i].wk_key,
1773			    keylen);
1774		}
1775		error = wi_write_rid(sc, WI_RID_DEFLT_CRYPT_KEYS,
1776		    wkey, sizeof(wkey));
1777		sc->sc_encryption = 0;
1778		break;
1779
1780	case WI_INTERSIL:
1781		val = HOST_ENCRYPT | HOST_DECRYPT;
1782		if (vap->iv_flags & IEEE80211_F_PRIVACY) {
1783			/*
1784			 * ONLY HWB3163 EVAL-CARD Firmware version
1785			 * less than 0.8 variant2
1786			 *
1787			 *   If promiscuous mode disable, Prism2 chip
1788			 *  does not work with WEP .
1789			 * It is under investigation for details.
1790			 * (ichiro@netbsd.org)
1791			 */
1792			if (sc->sc_sta_firmware_ver < 802 ) {
1793				/* firm ver < 0.8 variant 2 */
1794				wi_write_val(sc, WI_RID_PROMISC, 1);
1795			}
1796			wi_write_val(sc, WI_RID_CNFAUTHMODE,
1797			    vap->iv_bss->ni_authmode);
1798			val |= PRIVACY_INVOKED;
1799		} else {
1800			wi_write_val(sc, WI_RID_CNFAUTHMODE, IEEE80211_AUTH_OPEN);
1801		}
1802		error = wi_write_val(sc, WI_RID_P2_ENCRYPTION, val);
1803		if (error)
1804			break;
1805		sc->sc_encryption = val;
1806		if ((val & PRIVACY_INVOKED) == 0)
1807			break;
1808		error = wi_write_val(sc, WI_RID_P2_TX_CRYPT_KEY, vap->iv_def_txkey);
1809		break;
1810	}
1811	return error;
1812}
1813
1814static int
1815wi_cmd(struct wi_softc *sc, int cmd, int val0, int val1, int val2)
1816{
1817	int i, s = 0;
1818
1819	if (sc->wi_gone)
1820		return (ENODEV);
1821
1822	/* wait for the busy bit to clear */
1823	for (i = sc->wi_cmd_count; i > 0; i--) {	/* 500ms */
1824		if (!(CSR_READ_2(sc, WI_COMMAND) & WI_CMD_BUSY))
1825			break;
1826		DELAY(1*1000);	/* 1ms */
1827	}
1828	if (i == 0) {
1829		device_printf(sc->sc_dev, "%s: busy bit won't clear, cmd 0x%x\n",
1830		   __func__, cmd);
1831		sc->wi_gone = 1;
1832		return(ETIMEDOUT);
1833	}
1834
1835	CSR_WRITE_2(sc, WI_PARAM0, val0);
1836	CSR_WRITE_2(sc, WI_PARAM1, val1);
1837	CSR_WRITE_2(sc, WI_PARAM2, val2);
1838	CSR_WRITE_2(sc, WI_COMMAND, cmd);
1839
1840	if (cmd == WI_CMD_INI) {
1841		/* XXX: should sleep here. */
1842		DELAY(100*1000);		/* 100ms delay for init */
1843	}
1844	for (i = 0; i < WI_TIMEOUT; i++) {
1845		/*
1846		 * Wait for 'command complete' bit to be
1847		 * set in the event status register.
1848		 */
1849		s = CSR_READ_2(sc, WI_EVENT_STAT);
1850		if (s & WI_EV_CMD) {
1851			/* Ack the event and read result code. */
1852			s = CSR_READ_2(sc, WI_STATUS);
1853			CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_CMD);
1854			if (s & WI_STAT_CMD_RESULT) {
1855				return(EIO);
1856			}
1857			break;
1858		}
1859		DELAY(WI_DELAY);
1860	}
1861
1862	if (i == WI_TIMEOUT) {
1863		device_printf(sc->sc_dev, "%s: timeout on cmd 0x%04x; "
1864		    "event status 0x%04x\n", __func__, cmd, s);
1865		if (s == 0xffff)
1866			sc->wi_gone = 1;
1867		return(ETIMEDOUT);
1868	}
1869	return (0);
1870}
1871
1872static int
1873wi_seek_bap(struct wi_softc *sc, int id, int off)
1874{
1875	int i, status;
1876
1877	CSR_WRITE_2(sc, WI_SEL0, id);
1878	CSR_WRITE_2(sc, WI_OFF0, off);
1879
1880	for (i = 0; ; i++) {
1881		status = CSR_READ_2(sc, WI_OFF0);
1882		if ((status & WI_OFF_BUSY) == 0)
1883			break;
1884		if (i == WI_TIMEOUT) {
1885			device_printf(sc->sc_dev, "%s: timeout, id %x off %x\n",
1886			    __func__, id, off);
1887			sc->sc_bap_off = WI_OFF_ERR;	/* invalidate */
1888			if (status == 0xffff)
1889				sc->wi_gone = 1;
1890			return ETIMEDOUT;
1891		}
1892		DELAY(1);
1893	}
1894	if (status & WI_OFF_ERR) {
1895		device_printf(sc->sc_dev, "%s: error, id %x off %x\n",
1896		    __func__, id, off);
1897		sc->sc_bap_off = WI_OFF_ERR;	/* invalidate */
1898		return EIO;
1899	}
1900	sc->sc_bap_id = id;
1901	sc->sc_bap_off = off;
1902	return 0;
1903}
1904
1905static int
1906wi_read_bap(struct wi_softc *sc, int id, int off, void *buf, int buflen)
1907{
1908	int error, cnt;
1909
1910	if (buflen == 0)
1911		return 0;
1912	if (id != sc->sc_bap_id || off != sc->sc_bap_off) {
1913		if ((error = wi_seek_bap(sc, id, off)) != 0)
1914			return error;
1915	}
1916	cnt = (buflen + 1) / 2;
1917	CSR_READ_MULTI_STREAM_2(sc, WI_DATA0, (u_int16_t *)buf, cnt);
1918	sc->sc_bap_off += cnt * 2;
1919	return 0;
1920}
1921
1922static int
1923wi_write_bap(struct wi_softc *sc, int id, int off, void *buf, int buflen)
1924{
1925	int error, cnt;
1926
1927	if (buflen == 0)
1928		return 0;
1929
1930	if (id != sc->sc_bap_id || off != sc->sc_bap_off) {
1931		if ((error = wi_seek_bap(sc, id, off)) != 0)
1932			return error;
1933	}
1934	cnt = (buflen + 1) / 2;
1935	CSR_WRITE_MULTI_STREAM_2(sc, WI_DATA0, (u_int16_t *)buf, cnt);
1936	sc->sc_bap_off += cnt * 2;
1937
1938	return 0;
1939}
1940
1941static int
1942wi_mwrite_bap(struct wi_softc *sc, int id, int off, struct mbuf *m0, int totlen)
1943{
1944	int error, len;
1945	struct mbuf *m;
1946
1947	for (m = m0; m != NULL && totlen > 0; m = m->m_next) {
1948		if (m->m_len == 0)
1949			continue;
1950
1951		len = min(m->m_len, totlen);
1952
1953		if (((u_long)m->m_data) % 2 != 0 || len % 2 != 0) {
1954			m_copydata(m, 0, totlen, (caddr_t)&sc->sc_txbuf);
1955			return wi_write_bap(sc, id, off, (caddr_t)&sc->sc_txbuf,
1956			    totlen);
1957		}
1958
1959		if ((error = wi_write_bap(sc, id, off, m->m_data, len)) != 0)
1960			return error;
1961
1962		off += m->m_len;
1963		totlen -= len;
1964	}
1965	return 0;
1966}
1967
1968static int
1969wi_alloc_fid(struct wi_softc *sc, int len, int *idp)
1970{
1971	int i;
1972
1973	if (wi_cmd(sc, WI_CMD_ALLOC_MEM, len, 0, 0)) {
1974		device_printf(sc->sc_dev, "%s: failed to allocate %d bytes on NIC\n",
1975		    __func__, len);
1976		return ENOMEM;
1977	}
1978
1979	for (i = 0; i < WI_TIMEOUT; i++) {
1980		if (CSR_READ_2(sc, WI_EVENT_STAT) & WI_EV_ALLOC)
1981			break;
1982		DELAY(1);
1983	}
1984	if (i == WI_TIMEOUT) {
1985		device_printf(sc->sc_dev, "%s: timeout in alloc\n", __func__);
1986		return ETIMEDOUT;
1987	}
1988	*idp = CSR_READ_2(sc, WI_ALLOC_FID);
1989	CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_ALLOC);
1990	return 0;
1991}
1992
1993static int
1994wi_read_rid(struct wi_softc *sc, int rid, void *buf, int *buflenp)
1995{
1996	int error, len;
1997	u_int16_t ltbuf[2];
1998
1999	/* Tell the NIC to enter record read mode. */
2000	error = wi_cmd(sc, WI_CMD_ACCESS | WI_ACCESS_READ, rid, 0, 0);
2001	if (error)
2002		return error;
2003
2004	error = wi_read_bap(sc, rid, 0, ltbuf, sizeof(ltbuf));
2005	if (error)
2006		return error;
2007
2008	if (le16toh(ltbuf[1]) != rid) {
2009		device_printf(sc->sc_dev, "record read mismatch, rid=%x, got=%x\n",
2010		    rid, le16toh(ltbuf[1]));
2011		return EIO;
2012	}
2013	len = (le16toh(ltbuf[0]) - 1) * 2;	 /* already got rid */
2014	if (*buflenp < len) {
2015		device_printf(sc->sc_dev, "record buffer is too small, "
2016		    "rid=%x, size=%d, len=%d\n",
2017		    rid, *buflenp, len);
2018		return ENOSPC;
2019	}
2020	*buflenp = len;
2021	return wi_read_bap(sc, rid, sizeof(ltbuf), buf, len);
2022}
2023
2024static int
2025wi_write_rid(struct wi_softc *sc, int rid, void *buf, int buflen)
2026{
2027	int error;
2028	u_int16_t ltbuf[2];
2029
2030	ltbuf[0] = htole16((buflen + 1) / 2 + 1);	 /* includes rid */
2031	ltbuf[1] = htole16(rid);
2032
2033	error = wi_write_bap(sc, rid, 0, ltbuf, sizeof(ltbuf));
2034	if (error) {
2035		device_printf(sc->sc_dev, "%s: bap0 write failure, rid 0x%x\n",
2036		    __func__, rid);
2037		return error;
2038	}
2039	error = wi_write_bap(sc, rid, sizeof(ltbuf), buf, buflen);
2040	if (error) {
2041		device_printf(sc->sc_dev, "%s: bap1 write failure, rid 0x%x\n",
2042		    __func__, rid);
2043		return error;
2044	}
2045
2046	return wi_cmd(sc, WI_CMD_ACCESS | WI_ACCESS_WRITE, rid, 0, 0);
2047}
2048
2049static int
2050wi_write_appie(struct wi_softc *sc, int rid, const struct ieee80211_appie *ie)
2051{
2052	/* NB: 42 bytes is probably ok to have on the stack */
2053	char buf[sizeof(uint16_t) + 40];
2054
2055	if (ie->ie_len > 40)
2056		return EINVAL;
2057	/* NB: firmware requires 16-bit ie length before ie data */
2058	*(uint16_t *) buf = htole16(ie->ie_len);
2059	memcpy(buf + sizeof(uint16_t), ie->ie_data, ie->ie_len);
2060	return wi_write_rid(sc, rid, buf, ie->ie_len + sizeof(uint16_t));
2061}
2062
2063int
2064wi_alloc(device_t dev, int rid)
2065{
2066	struct wi_softc	*sc = device_get_softc(dev);
2067
2068	if (sc->wi_bus_type != WI_BUS_PCI_NATIVE) {
2069		sc->iobase_rid = rid;
2070		sc->iobase = bus_alloc_resource(dev, SYS_RES_IOPORT,
2071		    &sc->iobase_rid, 0, ~0, (1 << 6),
2072		    rman_make_alignment_flags(1 << 6) | RF_ACTIVE);
2073		if (sc->iobase == NULL) {
2074			device_printf(dev, "No I/O space?!\n");
2075			return ENXIO;
2076		}
2077
2078		sc->wi_io_addr = rman_get_start(sc->iobase);
2079		sc->wi_btag = rman_get_bustag(sc->iobase);
2080		sc->wi_bhandle = rman_get_bushandle(sc->iobase);
2081	} else {
2082		sc->mem_rid = rid;
2083		sc->mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
2084		    &sc->mem_rid, RF_ACTIVE);
2085		if (sc->mem == NULL) {
2086			device_printf(dev, "No Mem space on prism2.5?\n");
2087			return ENXIO;
2088		}
2089
2090		sc->wi_btag = rman_get_bustag(sc->mem);
2091		sc->wi_bhandle = rman_get_bushandle(sc->mem);
2092	}
2093
2094	sc->irq_rid = 0;
2095	sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irq_rid,
2096	    RF_ACTIVE |
2097	    ((sc->wi_bus_type == WI_BUS_PCCARD) ? 0 : RF_SHAREABLE));
2098	if (sc->irq == NULL) {
2099		wi_free(dev);
2100		device_printf(dev, "No irq?!\n");
2101		return ENXIO;
2102	}
2103
2104	sc->sc_dev = dev;
2105	sc->sc_unit = device_get_unit(dev);
2106	return 0;
2107}
2108
2109void
2110wi_free(device_t dev)
2111{
2112	struct wi_softc	*sc = device_get_softc(dev);
2113
2114	if (sc->iobase != NULL) {
2115		bus_release_resource(dev, SYS_RES_IOPORT, sc->iobase_rid, sc->iobase);
2116		sc->iobase = NULL;
2117	}
2118	if (sc->irq != NULL) {
2119		bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, sc->irq);
2120		sc->irq = NULL;
2121	}
2122	if (sc->mem != NULL) {
2123		bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, sc->mem);
2124		sc->mem = NULL;
2125	}
2126}
2127