if_wi.c revision 105076
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 for FreeBSD.
35 *
36 * 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/param.h>
63#include <sys/systm.h>
64#if __FreeBSD_version >= 500033
65#include <sys/endian.h>
66#endif
67#include <sys/sockio.h>
68#include <sys/mbuf.h>
69#include <sys/proc.h>
70#include <sys/kernel.h>
71#include <sys/socket.h>
72#include <sys/module.h>
73#include <sys/bus.h>
74#include <sys/random.h>
75#include <sys/syslog.h>
76#include <sys/sysctl.h>
77
78#include <machine/bus.h>
79#include <machine/resource.h>
80#include <machine/clock.h>
81#include <sys/rman.h>
82
83#include <net/if.h>
84#include <net/if_arp.h>
85#include <net/ethernet.h>
86#include <net/if_dl.h>
87#include <net/if_media.h>
88#include <net/if_types.h>
89#include <net/if_ieee80211.h>
90
91#include <netinet/in.h>
92#include <netinet/in_systm.h>
93#include <netinet/in_var.h>
94#include <netinet/ip.h>
95#include <netinet/if_ether.h>
96
97#include <net/bpf.h>
98
99#include <dev/wi/if_wavelan_ieee.h>
100#include <dev/wi/wi_hostap.h>
101#include <dev/wi/if_wivar.h>
102#include <dev/wi/if_wireg.h>
103
104#if !defined(lint)
105static const char rcsid[] =
106  "$FreeBSD: head/sys/dev/wi/if_wi.c 105076 2002-10-14 01:59:57Z imp $";
107#endif
108
109static void wi_intr(void *);
110static void wi_reset(struct wi_softc *);
111static int wi_ioctl(struct ifnet *, u_long, caddr_t);
112static void wi_init(void *);
113static void wi_start(struct ifnet *);
114static void wi_stop(struct wi_softc *);
115static void wi_watchdog(struct ifnet *);
116static void wi_rxeof(struct wi_softc *);
117static void wi_txeof(struct wi_softc *, int);
118static void wi_update_stats(struct wi_softc *);
119static void wi_setmulti(struct wi_softc *);
120
121static int wi_cmd(struct wi_softc *, int, int, int, int);
122static int wi_read_record(struct wi_softc *, struct wi_ltv_gen *);
123static int wi_write_record(struct wi_softc *, struct wi_ltv_gen *);
124static int wi_read_data(struct wi_softc *, int, int, caddr_t, int);
125static int wi_write_data(struct wi_softc *, int, int, caddr_t, int);
126static int wi_seek(struct wi_softc *, int, int, int);
127static int wi_alloc_nicmem(struct wi_softc *, int, int *);
128static void wi_inquire(void *);
129static void wi_setdef(struct wi_softc *, struct wi_req *);
130
131#ifdef WICACHE
132static
133void wi_cache_store(struct wi_softc *, struct ether_header *,
134	struct mbuf *, unsigned short);
135#endif
136
137static int wi_get_cur_ssid(struct wi_softc *, char *, int *);
138static void wi_get_id(struct wi_softc *);
139static int wi_media_change(struct ifnet *);
140static void wi_media_status(struct ifnet *, struct ifmediareq *);
141
142static int wi_get_debug(struct wi_softc *, struct wi_req *);
143static int wi_set_debug(struct wi_softc *, struct wi_req *);
144
145#if __FreeBSD_version >= 500000
146/* support to download firmware for symbol CF card */
147static int wi_symbol_write_firm(struct wi_softc *, const void *, int,
148		const void *, int);
149static int wi_symbol_set_hcr(struct wi_softc *, int);
150#endif
151
152devclass_t wi_devclass;
153
154struct wi_card_ident wi_card_ident[] = {
155	/* CARD_ID			CARD_NAME		FIRM_TYPE */
156	{ WI_NIC_LUCENT_ID,		WI_NIC_LUCENT_STR,	WI_LUCENT },
157	{ WI_NIC_SONY_ID,		WI_NIC_SONY_STR,	WI_LUCENT },
158	{ WI_NIC_LUCENT_EMB_ID,		WI_NIC_LUCENT_EMB_STR,	WI_LUCENT },
159	{ WI_NIC_EVB2_ID,		WI_NIC_EVB2_STR,	WI_INTERSIL },
160	{ WI_NIC_HWB3763_ID,		WI_NIC_HWB3763_STR,	WI_INTERSIL },
161	{ WI_NIC_HWB3163_ID,		WI_NIC_HWB3163_STR,	WI_INTERSIL },
162	{ WI_NIC_HWB3163B_ID,		WI_NIC_HWB3163B_STR,	WI_INTERSIL },
163	{ WI_NIC_EVB3_ID,		WI_NIC_EVB3_STR,	WI_INTERSIL },
164	{ WI_NIC_HWB1153_ID,		WI_NIC_HWB1153_STR,	WI_INTERSIL },
165	{ WI_NIC_P2_SST_ID,		WI_NIC_P2_SST_STR,	WI_INTERSIL },
166	{ WI_NIC_EVB2_SST_ID,		WI_NIC_EVB2_SST_STR,	WI_INTERSIL },
167	{ WI_NIC_3842_EVA_ID,		WI_NIC_3842_EVA_STR,	WI_INTERSIL },
168	{ WI_NIC_3842_PCMCIA_AMD_ID,	WI_NIC_3842_PCMCIA_STR,	WI_INTERSIL },
169	{ WI_NIC_3842_PCMCIA_SST_ID,	WI_NIC_3842_PCMCIA_STR,	WI_INTERSIL },
170	{ WI_NIC_3842_PCMCIA_ATL_ID,	WI_NIC_3842_PCMCIA_STR,	WI_INTERSIL },
171	{ WI_NIC_3842_PCMCIA_ATS_ID,	WI_NIC_3842_PCMCIA_STR,	WI_INTERSIL },
172	{ WI_NIC_3842_MINI_AMD_ID,	WI_NIC_3842_MINI_STR,	WI_INTERSIL },
173	{ WI_NIC_3842_MINI_SST_ID,	WI_NIC_3842_MINI_STR,	WI_INTERSIL },
174	{ WI_NIC_3842_MINI_ATL_ID,	WI_NIC_3842_MINI_STR,	WI_INTERSIL },
175	{ WI_NIC_3842_MINI_ATS_ID,	WI_NIC_3842_MINI_STR,	WI_INTERSIL },
176	{ WI_NIC_3842_PCI_AMD_ID,	WI_NIC_3842_PCI_STR,	WI_INTERSIL },
177	{ WI_NIC_3842_PCI_SST_ID,	WI_NIC_3842_PCI_STR,	WI_INTERSIL },
178	{ WI_NIC_3842_PCI_ATS_ID,	WI_NIC_3842_PCI_STR,	WI_INTERSIL },
179	{ WI_NIC_3842_PCI_ATL_ID,	WI_NIC_3842_PCI_STR,	WI_INTERSIL },
180	{ WI_NIC_P3_PCMCIA_AMD_ID,	WI_NIC_P3_PCMCIA_STR,	WI_INTERSIL },
181	{ WI_NIC_P3_PCMCIA_SST_ID,	WI_NIC_P3_PCMCIA_STR,	WI_INTERSIL },
182	{ WI_NIC_P3_PCMCIA_ATL_ID,	WI_NIC_P3_PCMCIA_STR,	WI_INTERSIL },
183	{ WI_NIC_P3_PCMCIA_ATS_ID,	WI_NIC_P3_PCMCIA_STR,	WI_INTERSIL },
184	{ WI_NIC_P3_MINI_AMD_ID,	WI_NIC_P3_MINI_STR,	WI_INTERSIL },
185	{ WI_NIC_P3_MINI_SST_ID,	WI_NIC_P3_MINI_STR,	WI_INTERSIL },
186	{ WI_NIC_P3_MINI_ATL_ID,	WI_NIC_P3_MINI_STR,	WI_INTERSIL },
187	{ WI_NIC_P3_MINI_ATS_ID,	WI_NIC_P3_MINI_STR,	WI_INTERSIL },
188	{ 0,	NULL,	0 },
189};
190
191int
192wi_generic_detach(dev)
193	device_t		dev;
194{
195	struct wi_softc		*sc;
196	struct ifnet		*ifp;
197	int			s;
198
199	sc = device_get_softc(dev);
200	WI_LOCK(sc, s);
201	ifp = &sc->arpcom.ac_if;
202
203	if (sc->wi_gone) {
204		device_printf(dev, "already unloaded\n");
205		WI_UNLOCK(sc, s);
206		return(ENODEV);
207	}
208
209	wi_stop(sc);
210
211	/* Delete all remaining media. */
212	ifmedia_removeall(&sc->ifmedia);
213
214	ether_ifdetach(ifp, ETHER_BPF_SUPPORTED);
215	bus_teardown_intr(dev, sc->irq, sc->wi_intrhand);
216	wi_free(dev);
217	sc->wi_gone = 1;
218
219	WI_UNLOCK(sc, s);
220#if __FreeBSD_version >= 500000
221	mtx_destroy(&sc->wi_mtx);
222#endif
223
224	return(0);
225}
226
227int
228wi_generic_attach(device_t dev)
229{
230	struct wi_softc		*sc;
231	struct wi_ltv_macaddr	mac;
232	struct wi_ltv_gen	gen;
233	struct ifnet		*ifp;
234	int			error;
235	int			s;
236
237	/* XXX maybe we need the splimp stuff here XXX */
238	sc = device_get_softc(dev);
239	ifp = &sc->arpcom.ac_if;
240
241	error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET,
242	    wi_intr, sc, &sc->wi_intrhand);
243
244	if (error) {
245		device_printf(dev, "bus_setup_intr() failed! (%d)\n", error);
246		wi_free(dev);
247		return (error);
248	}
249
250#if __FreeBSD_version >= 500000
251	mtx_init(&sc->wi_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
252	    MTX_DEF | MTX_RECURSE);
253#endif
254	WI_LOCK(sc, s);
255
256	/* Reset the NIC. */
257	wi_reset(sc);
258
259	/*
260	 * Read the station address.
261	 * And do it twice. I've seen PRISM-based cards that return
262	 * an error when trying to read it the first time, which causes
263	 * the probe to fail.
264	 */
265	mac.wi_type = WI_RID_MAC_NODE;
266	mac.wi_len = 4;
267	wi_read_record(sc, (struct wi_ltv_gen *)&mac);
268	if ((error = wi_read_record(sc, (struct wi_ltv_gen *)&mac)) != 0) {
269		device_printf(dev, "mac read failed %d\n", error);
270		wi_free(dev);
271		return (error);
272	}
273	bcopy((char *)&mac.wi_mac_addr,
274	   (char *)&sc->arpcom.ac_enaddr, ETHER_ADDR_LEN);
275
276	device_printf(dev, "802.11 address: %6D\n", sc->arpcom.ac_enaddr, ":");
277
278	wi_get_id(sc);
279
280	ifp->if_softc = sc;
281	ifp->if_unit = sc->wi_unit;
282	ifp->if_name = "wi";
283	ifp->if_mtu = ETHERMTU;
284	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
285	ifp->if_ioctl = wi_ioctl;
286	ifp->if_output = ether_output;
287	ifp->if_start = wi_start;
288	ifp->if_watchdog = wi_watchdog;
289	ifp->if_init = wi_init;
290	ifp->if_baudrate = 10000000;
291	ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
292
293	bzero(sc->wi_node_name, sizeof(sc->wi_node_name));
294	bcopy(WI_DEFAULT_NODENAME, sc->wi_node_name,
295	    sizeof(WI_DEFAULT_NODENAME) - 1);
296
297	bzero(sc->wi_net_name, sizeof(sc->wi_net_name));
298	bcopy(WI_DEFAULT_NETNAME, sc->wi_net_name,
299	    sizeof(WI_DEFAULT_NETNAME) - 1);
300
301	bzero(sc->wi_ibss_name, sizeof(sc->wi_ibss_name));
302	bcopy(WI_DEFAULT_IBSS, sc->wi_ibss_name,
303	    sizeof(WI_DEFAULT_IBSS) - 1);
304
305	sc->wi_portnum = WI_DEFAULT_PORT;
306	sc->wi_ptype = WI_PORTTYPE_BSS;
307	sc->wi_ap_density = WI_DEFAULT_AP_DENSITY;
308	sc->wi_rts_thresh = WI_DEFAULT_RTS_THRESH;
309	sc->wi_tx_rate = WI_DEFAULT_TX_RATE;
310	sc->wi_max_data_len = WI_DEFAULT_DATALEN;
311	sc->wi_create_ibss = WI_DEFAULT_CREATE_IBSS;
312	sc->wi_pm_enabled = WI_DEFAULT_PM_ENABLED;
313	sc->wi_max_sleep = WI_DEFAULT_MAX_SLEEP;
314	sc->wi_roaming = WI_DEFAULT_ROAMING;
315	sc->wi_authtype = WI_DEFAULT_AUTHTYPE;
316	sc->wi_authmode = IEEE80211_AUTH_OPEN;
317
318	/*
319	 * Read the default channel from the NIC. This may vary
320	 * depending on the country where the NIC was purchased, so
321	 * we can't hard-code a default and expect it to work for
322	 * everyone.
323	 */
324	gen.wi_type = WI_RID_OWN_CHNL;
325	gen.wi_len = 2;
326	wi_read_record(sc, &gen);
327	sc->wi_channel = gen.wi_val;
328
329	/*
330	 * Set flags based on firmware version.
331	 */
332	switch (sc->sc_firmware_type) {
333	case WI_LUCENT:
334		sc->wi_flags |= WI_FLAGS_HAS_ROAMING;
335		if (sc->sc_sta_firmware_ver >= 60000)
336			sc->wi_flags |= WI_FLAGS_HAS_MOR;
337		if (sc->sc_sta_firmware_ver >= 60006) {
338			sc->wi_flags |= WI_FLAGS_HAS_IBSS;
339			sc->wi_flags |= WI_FLAGS_HAS_CREATE_IBSS;
340		}
341		sc->wi_ibss_port = htole16(1);
342		break;
343	case WI_INTERSIL:
344		sc->wi_flags |= WI_FLAGS_HAS_ROAMING;
345		if (sc->sc_sta_firmware_ver >= 800) {
346			sc->wi_flags |= WI_FLAGS_HAS_IBSS;
347			sc->wi_flags |= WI_FLAGS_HAS_CREATE_IBSS;
348		}
349		/*
350		 * version 0.8.3 and newer are the only ones that are known
351		 * to currently work.  Earlier versions can be made to work,
352		 * at least according to the Linux driver.
353		 */
354		if (sc->sc_sta_firmware_ver >= 803)
355			sc->wi_flags |= WI_FLAGS_HAS_HOSTAP;
356		sc->wi_ibss_port = htole16(0);
357		break;
358	case WI_SYMBOL:
359		sc->wi_flags |= WI_FLAGS_HAS_DIVERSITY;
360		if (sc->sc_sta_firmware_ver >= 20000)
361			sc->wi_flags |= WI_FLAGS_HAS_IBSS;
362		/* Older Symbol firmware does not support IBSS creation. */
363		if (sc->sc_sta_firmware_ver >= 25000)
364			sc->wi_flags |= WI_FLAGS_HAS_CREATE_IBSS;
365		sc->wi_ibss_port = htole16(4);
366		break;
367	}
368
369	/*
370	 * Find out if we support WEP on this card.
371	 */
372	gen.wi_type = WI_RID_WEP_AVAIL;
373	gen.wi_len = 2;
374	wi_read_record(sc, &gen);
375	sc->wi_has_wep = gen.wi_val;
376
377	if (bootverbose)
378		device_printf(sc->dev, "wi_has_wep = %d\n", sc->wi_has_wep);
379
380	/*
381	 * Find supported rates.
382	 */
383	gen.wi_type = WI_RID_DATA_RATES;
384	gen.wi_len = 2;
385	if (wi_read_record(sc, &gen))
386		sc->wi_supprates = WI_SUPPRATES_1M | WI_SUPPRATES_2M |
387		    WI_SUPPRATES_5M | WI_SUPPRATES_11M;
388	else
389		sc->wi_supprates = gen.wi_val;
390
391	bzero((char *)&sc->wi_stats, sizeof(sc->wi_stats));
392
393	wi_init(sc);
394	wi_stop(sc);
395
396	ifmedia_init(&sc->ifmedia, 0, wi_media_change, wi_media_status);
397#define ADD(m, c)       ifmedia_add(&sc->ifmedia, (m), (c), NULL)
398	if (sc->wi_supprates & WI_SUPPRATES_1M) {
399		ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1, 0, 0), 0);
400		ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1,
401		    IFM_IEEE80211_ADHOC, 0), 0);
402		if (sc->wi_flags & WI_FLAGS_HAS_IBSS)
403			ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1,
404			    IFM_IEEE80211_IBSS, 0), 0);
405		if (sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS)
406			ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1,
407			    IFM_IEEE80211_IBSSMASTER, 0), 0);
408		if (sc->wi_flags & WI_FLAGS_HAS_HOSTAP)
409			ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS1,
410			    IFM_IEEE80211_HOSTAP, 0), 0);
411	}
412	if (sc->wi_supprates & WI_SUPPRATES_2M) {
413		ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2, 0, 0), 0);
414		ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2,
415		    IFM_IEEE80211_ADHOC, 0), 0);
416		if (sc->wi_flags & WI_FLAGS_HAS_IBSS)
417			ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2,
418			    IFM_IEEE80211_IBSS, 0), 0);
419		if (sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS)
420			ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2,
421			    IFM_IEEE80211_IBSSMASTER, 0), 0);
422		if (sc->wi_flags & WI_FLAGS_HAS_HOSTAP)
423			ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS2,
424			    IFM_IEEE80211_HOSTAP, 0), 0);
425	}
426	if (sc->wi_supprates & WI_SUPPRATES_5M) {
427		ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5, 0, 0), 0);
428		ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5,
429		    IFM_IEEE80211_ADHOC, 0), 0);
430		if (sc->wi_flags & WI_FLAGS_HAS_IBSS)
431			ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5,
432			    IFM_IEEE80211_IBSS, 0), 0);
433		if (sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS)
434			ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5,
435			    IFM_IEEE80211_IBSSMASTER, 0), 0);
436		if (sc->wi_flags & WI_FLAGS_HAS_HOSTAP)
437			ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS5,
438			    IFM_IEEE80211_HOSTAP, 0), 0);
439	}
440	if (sc->wi_supprates & WI_SUPPRATES_11M) {
441		ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11, 0, 0), 0);
442		ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11,
443		    IFM_IEEE80211_ADHOC, 0), 0);
444		if (sc->wi_flags & WI_FLAGS_HAS_IBSS)
445			ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11,
446			    IFM_IEEE80211_IBSS, 0), 0);
447		if (sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS)
448			ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11,
449			    IFM_IEEE80211_IBSSMASTER, 0), 0);
450		if (sc->wi_flags & WI_FLAGS_HAS_HOSTAP)
451			ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_IEEE80211_DS11,
452			    IFM_IEEE80211_HOSTAP, 0), 0);
453		ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_MANUAL, 0, 0), 0);
454	}
455	ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, IFM_IEEE80211_ADHOC, 0), 0);
456	if (sc->wi_flags & WI_FLAGS_HAS_IBSS)
457		ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, IFM_IEEE80211_IBSS,
458		    0), 0);
459	if (sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS)
460		ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO,
461		    IFM_IEEE80211_IBSSMASTER, 0), 0);
462	if (sc->wi_flags & WI_FLAGS_HAS_HOSTAP)
463		ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO,
464		    IFM_IEEE80211_HOSTAP, 0), 0);
465	ADD(IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, 0, 0), 0);
466#undef ADD
467	ifmedia_set(&sc->ifmedia, IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, 0, 0));
468
469	/*
470	 * Call MI attach routine.
471	 */
472	ether_ifattach(ifp, ETHER_BPF_SUPPORTED);
473	callout_handle_init(&sc->wi_stat_ch);
474	WI_UNLOCK(sc, s);
475
476	return(0);
477}
478
479static void
480wi_get_id(sc)
481	struct wi_softc *sc;
482{
483	struct wi_ltv_ver       ver;
484	struct wi_card_ident	*id;
485
486	/* getting chip identity */
487	memset(&ver, 0, sizeof(ver));
488	ver.wi_type = WI_RID_CARD_ID;
489	ver.wi_len = 5;
490	wi_read_record(sc, (struct wi_ltv_gen *)&ver);
491	device_printf(sc->dev, "using ");
492	sc->sc_firmware_type = WI_NOTYPE;
493	for (id = wi_card_ident; id->card_name != NULL; id++) {
494		if (le16toh(ver.wi_ver[0]) == id->card_id) {
495			printf("%s", id->card_name);
496			sc->sc_firmware_type = id->firm_type;
497			break;
498		}
499	}
500	if (sc->sc_firmware_type == WI_NOTYPE) {
501		if (le16toh(ver.wi_ver[0]) & 0x8000) {
502			printf("Unknown PRISM2 chip");
503			sc->sc_firmware_type = WI_INTERSIL;
504		} else {
505			printf("Unknown Lucent chip");
506			sc->sc_firmware_type = WI_LUCENT;
507		}
508	}
509
510	if (sc->sc_firmware_type != WI_LUCENT) {
511		/* get primary firmware version */
512		memset(&ver, 0, sizeof(ver));
513		ver.wi_type = WI_RID_PRI_IDENTITY;
514		ver.wi_len = 5;
515		wi_read_record(sc, (struct wi_ltv_gen *)&ver);
516		ver.wi_ver[1] = le16toh(ver.wi_ver[1]);
517		ver.wi_ver[2] = le16toh(ver.wi_ver[2]);
518		ver.wi_ver[3] = le16toh(ver.wi_ver[3]);
519		sc->sc_pri_firmware_ver = ver.wi_ver[2] * 10000 +
520		    ver.wi_ver[3] * 100 + ver.wi_ver[1];
521	}
522
523	/* get station firmware version */
524	memset(&ver, 0, sizeof(ver));
525	ver.wi_type = WI_RID_STA_IDENTITY;
526	ver.wi_len = 5;
527	wi_read_record(sc, (struct wi_ltv_gen *)&ver);
528	ver.wi_ver[1] = le16toh(ver.wi_ver[1]);
529	ver.wi_ver[2] = le16toh(ver.wi_ver[2]);
530	ver.wi_ver[3] = le16toh(ver.wi_ver[3]);
531	sc->sc_sta_firmware_ver = ver.wi_ver[2] * 10000 +
532	    ver.wi_ver[3] * 100 + ver.wi_ver[1];
533	if (sc->sc_firmware_type == WI_INTERSIL &&
534	    (sc->sc_sta_firmware_ver == 10102 ||
535	     sc->sc_sta_firmware_ver == 20102)) {
536		struct wi_ltv_str sver;
537		char *p;
538
539		memset(&sver, 0, sizeof(sver));
540		sver.wi_type = WI_RID_SYMBOL_IDENTITY;
541		sver.wi_len = 7;
542		/* value should be the format like "V2.00-11" */
543		if (wi_read_record(sc, (struct wi_ltv_gen *)&sver) == 0 &&
544		    *(p = (char *)sver.wi_str) >= 'A' &&
545		    p[2] == '.' && p[5] == '-' && p[8] == '\0') {
546			sc->sc_firmware_type = WI_SYMBOL;
547			sc->sc_sta_firmware_ver = (p[1] - '0') * 10000 +
548			    (p[3] - '0') * 1000 + (p[4] - '0') * 100 +
549			    (p[6] - '0') * 10 + (p[7] - '0');
550		}
551	}
552	printf("\n");
553	device_printf(sc->dev, "%s Firmware: ",
554	     sc->sc_firmware_type == WI_LUCENT ? "Lucent" :
555	    (sc->sc_firmware_type == WI_SYMBOL ? "Symbol" : "Intersil"));
556
557	/*
558	 * The primary firmware is only valid on Prism based chipsets
559	 * (INTERSIL or SYMBOL).
560	 */
561	if (sc->sc_firmware_type != WI_LUCENT)
562	    printf("Primary %u.%02u.%02u, ", sc->sc_pri_firmware_ver / 10000,
563		    (sc->sc_pri_firmware_ver % 10000) / 100,
564		    sc->sc_pri_firmware_ver % 100);
565	printf("Station %u.%02u.%02u\n",
566	    sc->sc_sta_firmware_ver / 10000, (sc->sc_sta_firmware_ver % 10000) / 100,
567	    sc->sc_sta_firmware_ver % 100);
568	return;
569}
570
571static void
572wi_rxeof(sc)
573	struct wi_softc		*sc;
574{
575	struct ifnet		*ifp;
576	struct ether_header	*eh;
577	struct mbuf		*m;
578	int			id;
579
580	ifp = &sc->arpcom.ac_if;
581
582	id = CSR_READ_2(sc, WI_RX_FID);
583
584	/*
585	 * if we have the procframe flag set, disregard all this and just
586	 * read the data from the device.
587	 */
588	if (sc->wi_procframe || sc->wi_debug.wi_monitor) {
589		struct wi_frame		*rx_frame;
590		int			datlen, hdrlen;
591
592		/* first allocate mbuf for packet storage */
593		MGETHDR(m, M_DONTWAIT, MT_DATA);
594		if (m == NULL) {
595			ifp->if_ierrors++;
596			return;
597		}
598		MCLGET(m, M_DONTWAIT);
599		if (!(m->m_flags & M_EXT)) {
600			m_freem(m);
601			ifp->if_ierrors++;
602			return;
603		}
604
605		m->m_pkthdr.rcvif = ifp;
606
607		/* now read wi_frame first so we know how much data to read */
608		if (wi_read_data(sc, id, 0, mtod(m, caddr_t),
609		    sizeof(struct wi_frame))) {
610			m_freem(m);
611			ifp->if_ierrors++;
612			return;
613		}
614
615		rx_frame = mtod(m, struct wi_frame *);
616
617		switch ((rx_frame->wi_status & WI_STAT_MAC_PORT) >> 8) {
618		case 7:
619			switch (rx_frame->wi_frame_ctl & WI_FCTL_FTYPE) {
620			case WI_FTYPE_DATA:
621				hdrlen = WI_DATA_HDRLEN;
622				datlen = rx_frame->wi_dat_len + WI_FCS_LEN;
623				break;
624			case WI_FTYPE_MGMT:
625				hdrlen = WI_MGMT_HDRLEN;
626				datlen = rx_frame->wi_dat_len + WI_FCS_LEN;
627				break;
628			case WI_FTYPE_CTL:
629				/*
630				 * prism2 cards don't pass control packets
631				 * down properly or consistently, so we'll only
632				 * pass down the header.
633				 */
634				hdrlen = WI_CTL_HDRLEN;
635				datlen = 0;
636				break;
637			default:
638				device_printf(sc->dev, "received packet of "
639				    "unknown type on port 7\n");
640				m_freem(m);
641				ifp->if_ierrors++;
642				return;
643			}
644			break;
645		case 0:
646			hdrlen = WI_DATA_HDRLEN;
647			datlen = rx_frame->wi_dat_len + WI_FCS_LEN;
648			break;
649		default:
650			device_printf(sc->dev, "received packet on invalid "
651			    "port (wi_status=0x%x)\n", rx_frame->wi_status);
652			m_freem(m);
653			ifp->if_ierrors++;
654			return;
655		}
656
657		if ((hdrlen + datlen + 2) > MCLBYTES) {
658			device_printf(sc->dev, "oversized packet received "
659			    "(wi_dat_len=%d, wi_status=0x%x)\n",
660			    datlen, rx_frame->wi_status);
661			m_freem(m);
662			ifp->if_ierrors++;
663			return;
664		}
665
666		if (wi_read_data(sc, id, hdrlen, mtod(m, caddr_t) + hdrlen,
667		    datlen + 2)) {
668			m_freem(m);
669			ifp->if_ierrors++;
670			return;
671		}
672
673		m->m_pkthdr.len = m->m_len = hdrlen + datlen;
674
675		ifp->if_ipackets++;
676
677		/* Handle BPF listeners. */
678		if (ifp->if_bpf)
679			bpf_mtap(ifp, m);
680
681		m_freem(m);
682	} else {
683		struct wi_frame		rx_frame;
684
685		/* First read in the frame header */
686		if (wi_read_data(sc, id, 0, (caddr_t)&rx_frame,
687		    sizeof(rx_frame))) {
688			ifp->if_ierrors++;
689			return;
690		}
691
692		if (rx_frame.wi_status & WI_STAT_ERRSTAT) {
693			ifp->if_ierrors++;
694			return;
695		}
696
697		MGETHDR(m, M_DONTWAIT, MT_DATA);
698		if (m == NULL) {
699			ifp->if_ierrors++;
700			return;
701		}
702		MCLGET(m, M_DONTWAIT);
703		if (!(m->m_flags & M_EXT)) {
704			m_freem(m);
705			ifp->if_ierrors++;
706			return;
707		}
708
709		eh = mtod(m, struct ether_header *);
710		m->m_pkthdr.rcvif = ifp;
711
712		if (rx_frame.wi_status == WI_STAT_MGMT &&
713		    sc->wi_ptype == WI_PORTTYPE_HOSTAP) {
714			if ((WI_802_11_OFFSET_RAW + rx_frame.wi_dat_len + 2) >
715			    MCLBYTES) {
716				device_printf(sc->dev, "oversized mgmt packet "
717				    "received in hostap mode "
718				    "(wi_dat_len=%d, wi_status=0x%x)\n",
719				    rx_frame.wi_dat_len, rx_frame.wi_status);
720				m_freem(m);
721				ifp->if_ierrors++;
722				return;
723			}
724
725			/* Put the whole header in there. */
726			bcopy(&rx_frame, mtod(m, void *),
727			    sizeof(struct wi_frame));
728			if (wi_read_data(sc, id, WI_802_11_OFFSET_RAW,
729			    mtod(m, caddr_t) + WI_802_11_OFFSET_RAW,
730			    rx_frame.wi_dat_len + 2)) {
731				m_freem(m);
732				ifp->if_ierrors++;
733				return;
734			}
735			m->m_pkthdr.len = m->m_len =
736			    WI_802_11_OFFSET_RAW + rx_frame.wi_dat_len;
737			/* XXX: consider giving packet to bhp? */
738			wihap_mgmt_input(sc, &rx_frame, m);
739			return;
740		}
741
742		if (rx_frame.wi_status == WI_STAT_1042 ||
743		    rx_frame.wi_status == WI_STAT_TUNNEL ||
744		    rx_frame.wi_status == WI_STAT_WMP_MSG) {
745			if((rx_frame.wi_dat_len + WI_SNAPHDR_LEN) > MCLBYTES) {
746				device_printf(sc->dev,
747				    "oversized packet received "
748				    "(wi_dat_len=%d, wi_status=0x%x)\n",
749				    rx_frame.wi_dat_len, rx_frame.wi_status);
750				m_freem(m);
751				ifp->if_ierrors++;
752				return;
753			}
754			m->m_pkthdr.len = m->m_len =
755			    rx_frame.wi_dat_len + WI_SNAPHDR_LEN;
756
757#if 0
758			bcopy((char *)&rx_frame.wi_addr1,
759			    (char *)&eh->ether_dhost, ETHER_ADDR_LEN);
760			if (sc->wi_ptype == WI_PORTTYPE_ADHOC) {
761				bcopy((char *)&rx_frame.wi_addr2,
762				    (char *)&eh->ether_shost, ETHER_ADDR_LEN);
763			} else {
764				bcopy((char *)&rx_frame.wi_addr3,
765				    (char *)&eh->ether_shost, ETHER_ADDR_LEN);
766			}
767#else
768			bcopy((char *)&rx_frame.wi_dst_addr,
769				(char *)&eh->ether_dhost, ETHER_ADDR_LEN);
770			bcopy((char *)&rx_frame.wi_src_addr,
771				(char *)&eh->ether_shost, ETHER_ADDR_LEN);
772#endif
773
774			bcopy((char *)&rx_frame.wi_type,
775			    (char *)&eh->ether_type, ETHER_TYPE_LEN);
776
777			if (wi_read_data(sc, id, WI_802_11_OFFSET,
778			    mtod(m, caddr_t) + sizeof(struct ether_header),
779			    m->m_len + 2)) {
780				m_freem(m);
781				ifp->if_ierrors++;
782				return;
783			}
784		} else {
785			if((rx_frame.wi_dat_len +
786			    sizeof(struct ether_header)) > MCLBYTES) {
787				device_printf(sc->dev,
788				    "oversized packet received "
789				    "(wi_dat_len=%d, wi_status=0x%x)\n",
790				    rx_frame.wi_dat_len, rx_frame.wi_status);
791				m_freem(m);
792				ifp->if_ierrors++;
793				return;
794			}
795			m->m_pkthdr.len = m->m_len =
796			    rx_frame.wi_dat_len + sizeof(struct ether_header);
797
798			if (wi_read_data(sc, id, WI_802_3_OFFSET,
799			    mtod(m, caddr_t), m->m_len + 2)) {
800				m_freem(m);
801				ifp->if_ierrors++;
802				return;
803			}
804		}
805
806		ifp->if_ipackets++;
807
808		if (sc->wi_ptype == WI_PORTTYPE_HOSTAP) {
809			/*
810			 * Give host AP code first crack at data
811			 * packets.  If it decides to handle it (or
812			 * drop it), it will return a non-zero.
813			 * Otherwise, it is destined for this host.
814			 */
815			if (wihap_data_input(sc, &rx_frame, m))
816				return;
817		}
818		/* Receive packet. */
819		m_adj(m, sizeof(struct ether_header));
820#ifdef WICACHE
821		wi_cache_store(sc, eh, m, rx_frame.wi_q_info);
822#endif
823		ether_input(ifp, eh, m);
824	}
825}
826
827static void
828wi_txeof(sc, status)
829	struct wi_softc		*sc;
830	int			status;
831{
832	struct ifnet		*ifp;
833
834	ifp = &sc->arpcom.ac_if;
835
836	ifp->if_timer = 0;
837	ifp->if_flags &= ~IFF_OACTIVE;
838
839	if (status & WI_EV_TX_EXC)
840		ifp->if_oerrors++;
841	else
842		ifp->if_opackets++;
843
844	return;
845}
846
847static void
848wi_inquire(xsc)
849	void			*xsc;
850{
851	struct wi_softc		*sc;
852	struct ifnet		*ifp;
853	int			s;
854
855	sc = xsc;
856	ifp = &sc->arpcom.ac_if;
857
858	sc->wi_stat_ch = timeout(wi_inquire, sc, hz * 60);
859
860	/* Don't do this while we're transmitting */
861	if (ifp->if_flags & IFF_OACTIVE)
862		return;
863
864	WI_LOCK(sc, s);
865	wi_cmd(sc, WI_CMD_INQUIRE, WI_INFO_COUNTERS, 0, 0);
866	WI_UNLOCK(sc, s);
867
868	return;
869}
870
871static void
872wi_update_stats(sc)
873	struct wi_softc		*sc;
874{
875	struct wi_ltv_gen	gen;
876	u_int16_t		id;
877	struct ifnet		*ifp;
878	u_int32_t		*ptr;
879	int			len, i;
880	u_int16_t		t;
881
882	ifp = &sc->arpcom.ac_if;
883
884	id = CSR_READ_2(sc, WI_INFO_FID);
885
886	wi_read_data(sc, id, 0, (char *)&gen, 4);
887
888	/*
889	 * if we just got our scan results, copy it over into the scan buffer
890	 * so we can return it to anyone that asks for it. (add a little
891	 * compatibility with the prism2 scanning mechanism)
892	 */
893	if (gen.wi_type == WI_INFO_SCAN_RESULTS)
894	{
895		sc->wi_scanbuf_len = gen.wi_len;
896		wi_read_data(sc, id, 4, (char *)sc->wi_scanbuf,
897		    sc->wi_scanbuf_len * 2);
898
899		return;
900	}
901	else if (gen.wi_type != WI_INFO_COUNTERS)
902		return;
903
904	len = (gen.wi_len - 1 < sizeof(sc->wi_stats) / 4) ?
905		gen.wi_len - 1 : sizeof(sc->wi_stats) / 4;
906	ptr = (u_int32_t *)&sc->wi_stats;
907
908	for (i = 0; i < len - 1; i++) {
909		t = CSR_READ_2(sc, WI_DATA1);
910#ifdef WI_HERMES_STATS_WAR
911		if (t > 0xF000)
912			t = ~t & 0xFFFF;
913#endif
914		ptr[i] += t;
915	}
916
917	ifp->if_collisions = sc->wi_stats.wi_tx_single_retries +
918	    sc->wi_stats.wi_tx_multi_retries +
919	    sc->wi_stats.wi_tx_retry_limit;
920
921	return;
922}
923
924static void
925wi_intr(xsc)
926	void		*xsc;
927{
928	struct wi_softc		*sc = xsc;
929	struct ifnet		*ifp;
930	u_int16_t		status;
931	int			s;
932
933	WI_LOCK(sc, s);
934
935	ifp = &sc->arpcom.ac_if;
936
937	if (sc->wi_gone || !(ifp->if_flags & IFF_UP)) {
938		CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF);
939		CSR_WRITE_2(sc, WI_INT_EN, 0);
940		WI_UNLOCK(sc, s);
941		return;
942	}
943
944	/* Disable interrupts. */
945	CSR_WRITE_2(sc, WI_INT_EN, 0);
946
947	status = CSR_READ_2(sc, WI_EVENT_STAT);
948	CSR_WRITE_2(sc, WI_EVENT_ACK, ~WI_INTRS);
949
950	if (status & WI_EV_RX) {
951		wi_rxeof(sc);
952		CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX);
953	}
954
955	if (status & WI_EV_TX) {
956		wi_txeof(sc, status);
957		CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_TX);
958	}
959
960	if (status & WI_EV_ALLOC) {
961		int			id;
962
963		id = CSR_READ_2(sc, WI_ALLOC_FID);
964		CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_ALLOC);
965		if (id == sc->wi_tx_data_id)
966			wi_txeof(sc, status);
967	}
968
969	if (status & WI_EV_INFO) {
970		wi_update_stats(sc);
971		CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_INFO);
972	}
973
974	if (status & WI_EV_TX_EXC) {
975		wi_txeof(sc, status);
976		CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_TX_EXC);
977	}
978
979	if (status & WI_EV_INFO_DROP) {
980		CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_INFO_DROP);
981	}
982
983	/* Re-enable interrupts. */
984	CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS);
985
986	if (ifp->if_snd.ifq_head != NULL) {
987		wi_start(ifp);
988	}
989
990	WI_UNLOCK(sc, s);
991
992	return;
993}
994
995static int
996wi_cmd(sc, cmd, val0, val1, val2)
997	struct wi_softc		*sc;
998	int			cmd;
999	int			val0;
1000	int			val1;
1001	int			val2;
1002{
1003	int			i, s = 0;
1004	static volatile int count  = 0;
1005
1006	if (count > 1)
1007		panic("Hey partner, hold on there!");
1008	count++;
1009
1010	/* wait for the busy bit to clear */
1011	for (i = 500; i > 0; i--) {	/* 5s */
1012		if (!(CSR_READ_2(sc, WI_COMMAND) & WI_CMD_BUSY)) {
1013			break;
1014		}
1015		DELAY(10*1000);	/* 10 m sec */
1016	}
1017	if (i == 0) {
1018		device_printf(sc->dev, "wi_cmd: busy bit won't clear.\n" );
1019		count--;
1020		return(ETIMEDOUT);
1021	}
1022
1023	CSR_WRITE_2(sc, WI_PARAM0, val0);
1024	CSR_WRITE_2(sc, WI_PARAM1, val1);
1025	CSR_WRITE_2(sc, WI_PARAM2, val2);
1026	CSR_WRITE_2(sc, WI_COMMAND, cmd);
1027
1028	for (i = 0; i < WI_TIMEOUT; i++) {
1029		/*
1030		 * Wait for 'command complete' bit to be
1031		 * set in the event status register.
1032		 */
1033		s = CSR_READ_2(sc, WI_EVENT_STAT);
1034		if (s & WI_EV_CMD) {
1035			/* Ack the event and read result code. */
1036			s = CSR_READ_2(sc, WI_STATUS);
1037			CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_CMD);
1038#ifdef foo
1039			if ((s & WI_CMD_CODE_MASK) != (cmd & WI_CMD_CODE_MASK))
1040				return(EIO);
1041#endif
1042			if (s & WI_STAT_CMD_RESULT) {
1043				count--;
1044				return(EIO);
1045			}
1046			break;
1047		}
1048		DELAY(WI_DELAY);
1049	}
1050
1051	count--;
1052	if (i == WI_TIMEOUT) {
1053		device_printf(sc->dev,
1054		    "timeout in wi_cmd 0x%04x; event status 0x%04x\n", cmd, s);
1055		return(ETIMEDOUT);
1056	}
1057	return(0);
1058}
1059
1060static void
1061wi_reset(sc)
1062	struct wi_softc		*sc;
1063{
1064#define WI_INIT_TRIES 3
1065	int i;
1066	int tries;
1067
1068	/* Symbol firmware cannot be initialized more than once */
1069	if (sc->sc_firmware_type == WI_SYMBOL && sc->sc_enabled)
1070		return;
1071	if (sc->sc_firmware_type == WI_SYMBOL)
1072		tries = 1;
1073	else
1074		tries = WI_INIT_TRIES;
1075
1076	for (i = 0; i < tries; i++) {
1077		if (wi_cmd(sc, WI_CMD_INI, 0, 0, 0) == 0)
1078			break;
1079		DELAY(WI_DELAY * 1000);
1080	}
1081	sc->sc_enabled = 1;
1082
1083	if (i == tries) {
1084		device_printf(sc->dev, "init failed\n");
1085		return;
1086	}
1087
1088	CSR_WRITE_2(sc, WI_INT_EN, 0);
1089	CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF);
1090
1091	/* Calibrate timer. */
1092	WI_SETVAL(WI_RID_TICK_TIME, 8);
1093
1094	return;
1095}
1096
1097/*
1098 * Read an LTV record from the NIC.
1099 */
1100static int
1101wi_read_record(sc, ltv)
1102	struct wi_softc		*sc;
1103	struct wi_ltv_gen	*ltv;
1104{
1105	u_int16_t		*ptr;
1106	int			i, len, code;
1107	struct wi_ltv_gen	*oltv, p2ltv;
1108
1109	oltv = ltv;
1110	if (sc->sc_firmware_type != WI_LUCENT) {
1111		switch (ltv->wi_type) {
1112		case WI_RID_ENCRYPTION:
1113			p2ltv.wi_type = WI_RID_P2_ENCRYPTION;
1114			p2ltv.wi_len = 2;
1115			ltv = &p2ltv;
1116			break;
1117		case WI_RID_TX_CRYPT_KEY:
1118			p2ltv.wi_type = WI_RID_P2_TX_CRYPT_KEY;
1119			p2ltv.wi_len = 2;
1120			ltv = &p2ltv;
1121			break;
1122		case WI_RID_ROAMING_MODE:
1123			if (sc->sc_firmware_type == WI_INTERSIL)
1124				break;
1125			/* not supported */
1126			ltv->wi_len = 1;
1127			return 0;
1128		case WI_RID_MICROWAVE_OVEN:
1129			/* not supported */
1130			ltv->wi_len = 1;
1131			return 0;
1132		}
1133	}
1134
1135	/* Tell the NIC to enter record read mode. */
1136	if (wi_cmd(sc, WI_CMD_ACCESS|WI_ACCESS_READ, ltv->wi_type, 0, 0))
1137		return(EIO);
1138
1139	/* Seek to the record. */
1140	if (wi_seek(sc, ltv->wi_type, 0, WI_BAP1))
1141		return(EIO);
1142
1143	/*
1144	 * Read the length and record type and make sure they
1145	 * match what we expect (this verifies that we have enough
1146	 * room to hold all of the returned data).
1147	 */
1148	len = CSR_READ_2(sc, WI_DATA1);
1149	if (len > ltv->wi_len)
1150		return(ENOSPC);
1151	code = CSR_READ_2(sc, WI_DATA1);
1152	if (code != ltv->wi_type)
1153		return(EIO);
1154
1155	ltv->wi_len = len;
1156	ltv->wi_type = code;
1157
1158	/* Now read the data. */
1159	ptr = &ltv->wi_val;
1160	for (i = 0; i < ltv->wi_len - 1; i++)
1161		ptr[i] = CSR_READ_2(sc, WI_DATA1);
1162
1163	if (ltv->wi_type == WI_RID_PORTTYPE && sc->wi_ptype == WI_PORTTYPE_IBSS
1164	    && ltv->wi_val == sc->wi_ibss_port) {
1165		/*
1166		 * Convert vendor IBSS port type to WI_PORTTYPE_IBSS.
1167		 * Since Lucent uses port type 1 for BSS *and* IBSS we
1168		 * have to rely on wi_ptype to distinguish this for us.
1169		 */
1170		ltv->wi_val = htole16(WI_PORTTYPE_IBSS);
1171	} else if (sc->sc_firmware_type != WI_LUCENT) {
1172		switch (oltv->wi_type) {
1173		case WI_RID_TX_RATE:
1174		case WI_RID_CUR_TX_RATE:
1175			switch (ltv->wi_val) {
1176			case 1: oltv->wi_val = 1; break;
1177			case 2: oltv->wi_val = 2; break;
1178			case 3:	oltv->wi_val = 6; break;
1179			case 4: oltv->wi_val = 5; break;
1180			case 7: oltv->wi_val = 7; break;
1181			case 8: oltv->wi_val = 11; break;
1182			case 15: oltv->wi_val = 3; break;
1183			default: oltv->wi_val = 0x100 + ltv->wi_val; break;
1184			}
1185			break;
1186		case WI_RID_ENCRYPTION:
1187			oltv->wi_len = 2;
1188			if (ltv->wi_val & 0x01)
1189				oltv->wi_val = 1;
1190			else
1191				oltv->wi_val = 0;
1192			break;
1193		case WI_RID_TX_CRYPT_KEY:
1194			oltv->wi_len = 2;
1195			oltv->wi_val = ltv->wi_val;
1196			break;
1197		case WI_RID_CNFAUTHMODE:
1198                        oltv->wi_len = 2;
1199			if (le16toh(ltv->wi_val) & 0x01)
1200				oltv->wi_val = htole16(1);
1201			else if (le16toh(ltv->wi_val) & 0x02)
1202				oltv->wi_val = htole16(2);
1203			break;
1204		}
1205	}
1206
1207	return(0);
1208}
1209
1210/*
1211 * Same as read, except we inject data instead of reading it.
1212 */
1213static int
1214wi_write_record(sc, ltv)
1215	struct wi_softc		*sc;
1216	struct wi_ltv_gen	*ltv;
1217{
1218	uint16_t		*ptr;
1219	uint16_t		val;
1220	int			i;
1221	struct wi_ltv_gen	p2ltv;
1222
1223	if (ltv->wi_type == WI_RID_PORTTYPE &&
1224	    le16toh(ltv->wi_val) == WI_PORTTYPE_IBSS) {
1225		/* Convert WI_PORTTYPE_IBSS to vendor IBSS port type. */
1226		p2ltv.wi_type = WI_RID_PORTTYPE;
1227		p2ltv.wi_len = 2;
1228		p2ltv.wi_val = sc->wi_ibss_port;
1229		ltv = &p2ltv;
1230	} else if (sc->sc_firmware_type != WI_LUCENT) {
1231		switch (ltv->wi_type) {
1232		case WI_RID_TX_RATE:
1233			p2ltv.wi_type = WI_RID_TX_RATE;
1234			p2ltv.wi_len = 2;
1235			switch (ltv->wi_val) {
1236			case 1: p2ltv.wi_val = 1; break;
1237			case 2: p2ltv.wi_val = 2; break;
1238			case 3:	p2ltv.wi_val = 15; break;
1239			case 5: p2ltv.wi_val = 4; break;
1240			case 6: p2ltv.wi_val = 3; break;
1241			case 7: p2ltv.wi_val = 7; break;
1242			case 11: p2ltv.wi_val = 8; break;
1243			default: return EINVAL;
1244			}
1245			p2ltv.wi_val = htole16(p2ltv.wi_val);
1246			ltv = &p2ltv;
1247			break;
1248		case WI_RID_ENCRYPTION:
1249			p2ltv.wi_type = WI_RID_P2_ENCRYPTION;
1250			p2ltv.wi_len = 2;
1251			if (ltv->wi_val & htole16(0x01)) {
1252				val = PRIVACY_INVOKED;
1253				/*
1254				 * If using shared key WEP we must set the
1255				 * EXCLUDE_UNENCRYPTED bit.  Symbol cards
1256				 * need this bit set even when not using
1257				 * shared key. We can't just test for
1258				 * IEEE80211_AUTH_SHARED since Symbol cards
1259				 * have 2 shared key modes.
1260				 */
1261				if (sc->wi_authtype != IEEE80211_AUTH_OPEN ||
1262				    sc->sc_firmware_type == WI_SYMBOL)
1263					val |= EXCLUDE_UNENCRYPTED;
1264				/* TX encryption is broken in Host AP mode. */
1265				if (sc->wi_ptype == WI_PORTTYPE_HOSTAP)
1266					val |= HOST_ENCRYPT;
1267			} else
1268				val = HOST_ENCRYPT | HOST_DECRYPT;
1269			p2ltv.wi_val = htole16(val);
1270			ltv = &p2ltv;
1271			break;
1272		case WI_RID_TX_CRYPT_KEY:
1273			if (ltv->wi_val > WI_NLTV_KEYS)
1274				return (EINVAL);
1275			p2ltv.wi_type = WI_RID_P2_TX_CRYPT_KEY;
1276			p2ltv.wi_len = 2;
1277			p2ltv.wi_val = ltv->wi_val;
1278			ltv = &p2ltv;
1279			break;
1280		case WI_RID_DEFLT_CRYPT_KEYS:
1281		    {
1282			int error;
1283			int keylen;
1284			struct wi_ltv_str	ws;
1285			struct wi_ltv_keys	*wk =
1286			    (struct wi_ltv_keys *)ltv;
1287
1288			keylen = wk->wi_keys[sc->wi_tx_key].wi_keylen;
1289
1290			for (i = 0; i < 4; i++) {
1291				bzero(&ws, sizeof(ws));
1292				ws.wi_len = (keylen > 5) ? 8 : 4;
1293				ws.wi_type = WI_RID_P2_CRYPT_KEY0 + i;
1294				memcpy(ws.wi_str,
1295				    &wk->wi_keys[i].wi_keydat, keylen);
1296				error = wi_write_record(sc,
1297				    (struct wi_ltv_gen *)&ws);
1298				if (error)
1299					return error;
1300			}
1301			return 0;
1302		    }
1303		case WI_RID_CNFAUTHMODE:
1304			p2ltv.wi_type = WI_RID_CNFAUTHMODE;
1305			p2ltv.wi_len = 2;
1306			if (le16toh(ltv->wi_val) == 1)
1307				p2ltv.wi_val = htole16(0x01);
1308			else if (le16toh(ltv->wi_val) == 2)
1309				p2ltv.wi_val = htole16(0x02);
1310			ltv = &p2ltv;
1311			break;
1312		case WI_RID_ROAMING_MODE:
1313			if (sc->sc_firmware_type == WI_INTERSIL)
1314				break;
1315			/* not supported */
1316			return 0;
1317		case WI_RID_MICROWAVE_OVEN:
1318			/* not supported */
1319			return 0;
1320		}
1321	} else {
1322		/* LUCENT */
1323		switch (ltv->wi_type) {
1324		case WI_RID_TX_RATE:
1325			switch (ltv->wi_val) {
1326			case 1: ltv->wi_val = 1; break;  /* 1Mb/s fixed */
1327			case 2: ltv->wi_val = 2; break;  /* 2Mb/s fixed */
1328			case 3: ltv->wi_val = 3; break;  /* 11Mb/s auto */
1329			case 5: ltv->wi_val = 4; break;  /* 5.5Mb/s fixed */
1330			case 6: ltv->wi_val = 6; break;  /* 2Mb/s auto */
1331			case 7: ltv->wi_val = 7; break;  /* 5.5Mb/s auto */
1332			case 11: ltv->wi_val = 5; break; /* 11Mb/s fixed */
1333			default: return EINVAL;
1334			}
1335		case WI_RID_TX_CRYPT_KEY:
1336			if (ltv->wi_val > WI_NLTV_KEYS)
1337				return (EINVAL);
1338			break;
1339		}
1340	}
1341
1342	if (wi_seek(sc, ltv->wi_type, 0, WI_BAP1))
1343		return(EIO);
1344
1345	CSR_WRITE_2(sc, WI_DATA1, ltv->wi_len);
1346	CSR_WRITE_2(sc, WI_DATA1, ltv->wi_type);
1347
1348	ptr = &ltv->wi_val;
1349	for (i = 0; i < ltv->wi_len - 1; i++)
1350		CSR_WRITE_2(sc, WI_DATA1, ptr[i]);
1351
1352	if (wi_cmd(sc, WI_CMD_ACCESS|WI_ACCESS_WRITE, ltv->wi_type, 0, 0))
1353		return(EIO);
1354
1355	return(0);
1356}
1357
1358static int
1359wi_seek(sc, id, off, chan)
1360	struct wi_softc		*sc;
1361	int			id, off, chan;
1362{
1363	int			i;
1364	int			selreg, offreg;
1365	int			status;
1366
1367	switch (chan) {
1368	case WI_BAP0:
1369		selreg = WI_SEL0;
1370		offreg = WI_OFF0;
1371		break;
1372	case WI_BAP1:
1373		selreg = WI_SEL1;
1374		offreg = WI_OFF1;
1375		break;
1376	default:
1377		device_printf(sc->dev, "invalid data path: %x\n", chan);
1378		return(EIO);
1379	}
1380
1381	CSR_WRITE_2(sc, selreg, id);
1382	CSR_WRITE_2(sc, offreg, off);
1383
1384	for (i = 0; i < WI_TIMEOUT; i++) {
1385		status = CSR_READ_2(sc, offreg);
1386		if (!(status & (WI_OFF_BUSY|WI_OFF_ERR)))
1387			break;
1388		DELAY(WI_DELAY);
1389	}
1390
1391	if (i == WI_TIMEOUT) {
1392		device_printf(sc->dev, "timeout in wi_seek to %x/%x; last status %x\n",
1393			id, off, status);
1394		return(ETIMEDOUT);
1395	}
1396
1397	return(0);
1398}
1399
1400static int
1401wi_read_data(sc, id, off, buf, len)
1402	struct wi_softc		*sc;
1403	int			id, off;
1404	caddr_t			buf;
1405	int			len;
1406{
1407	int			i;
1408	u_int16_t		*ptr;
1409
1410	if (wi_seek(sc, id, off, WI_BAP1))
1411		return(EIO);
1412
1413	ptr = (u_int16_t *)buf;
1414	for (i = 0; i < len / 2; i++)
1415		ptr[i] = CSR_READ_2(sc, WI_DATA1);
1416
1417	return(0);
1418}
1419
1420/*
1421 * According to the comments in the HCF Light code, there is a bug in
1422 * the Hermes (or possibly in certain Hermes firmware revisions) where
1423 * the chip's internal autoincrement counter gets thrown off during
1424 * data writes: the autoincrement is missed, causing one data word to
1425 * be overwritten and subsequent words to be written to the wrong memory
1426 * locations. The end result is that we could end up transmitting bogus
1427 * frames without realizing it. The workaround for this is to write a
1428 * couple of extra guard words after the end of the transfer, then
1429 * attempt to read then back. If we fail to locate the guard words where
1430 * we expect them, we preform the transfer over again.
1431 */
1432static int
1433wi_write_data(sc, id, off, buf, len)
1434	struct wi_softc		*sc;
1435	int			id, off;
1436	caddr_t			buf;
1437	int			len;
1438{
1439	int			i;
1440	u_int16_t		*ptr;
1441#ifdef WI_HERMES_AUTOINC_WAR
1442	int			retries;
1443
1444	retries = 512;
1445again:
1446#endif
1447
1448	if (wi_seek(sc, id, off, WI_BAP0))
1449		return(EIO);
1450
1451	ptr = (u_int16_t *)buf;
1452	for (i = 0; i < (len / 2); i++)
1453		CSR_WRITE_2(sc, WI_DATA0, ptr[i]);
1454
1455#ifdef WI_HERMES_AUTOINC_WAR
1456	CSR_WRITE_2(sc, WI_DATA0, 0x1234);
1457	CSR_WRITE_2(sc, WI_DATA0, 0x5678);
1458
1459	if (wi_seek(sc, id, off + len, WI_BAP0))
1460		return(EIO);
1461
1462	if (CSR_READ_2(sc, WI_DATA0) != 0x1234 ||
1463	    CSR_READ_2(sc, WI_DATA0) != 0x5678) {
1464		if (--retries >= 0)
1465			goto again;
1466		device_printf(sc->dev, "wi_write_data device timeout\n");
1467		return (EIO);
1468	}
1469#endif
1470
1471	return(0);
1472}
1473
1474/*
1475 * Allocate a region of memory inside the NIC and zero
1476 * it out.
1477 */
1478static int
1479wi_alloc_nicmem(sc, len, id)
1480	struct wi_softc		*sc;
1481	int			len;
1482	int			*id;
1483{
1484	int			i;
1485
1486	if (wi_cmd(sc, WI_CMD_ALLOC_MEM, len, 0, 0)) {
1487		device_printf(sc->dev,
1488		    "failed to allocate %d bytes on NIC\n", len);
1489		return(ENOMEM);
1490	}
1491
1492	for (i = 0; i < WI_TIMEOUT; i++) {
1493		if (CSR_READ_2(sc, WI_EVENT_STAT) & WI_EV_ALLOC)
1494			break;
1495		DELAY(WI_DELAY);
1496	}
1497
1498	if (i == WI_TIMEOUT) {
1499		device_printf(sc->dev, "time out allocating memory on card\n");
1500		return(ETIMEDOUT);
1501	}
1502
1503	CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_ALLOC);
1504	*id = CSR_READ_2(sc, WI_ALLOC_FID);
1505
1506	if (wi_seek(sc, *id, 0, WI_BAP0)) {
1507		device_printf(sc->dev, "seek failed while allocating memory on card\n");
1508		return(EIO);
1509	}
1510
1511	for (i = 0; i < len / 2; i++)
1512		CSR_WRITE_2(sc, WI_DATA0, 0);
1513
1514	return(0);
1515}
1516
1517static void
1518wi_setmulti(sc)
1519	struct wi_softc		*sc;
1520{
1521	struct ifnet		*ifp;
1522	int			i = 0;
1523	struct ifmultiaddr	*ifma;
1524	struct wi_ltv_mcast	mcast;
1525
1526	ifp = &sc->arpcom.ac_if;
1527
1528	bzero((char *)&mcast, sizeof(mcast));
1529
1530	mcast.wi_type = WI_RID_MCAST_LIST;
1531	mcast.wi_len = (3 * 16) + 1;
1532
1533	if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
1534		wi_write_record(sc, (struct wi_ltv_gen *)&mcast);
1535		return;
1536	}
1537
1538#if __FreeBSD_version < 500000
1539	LIST_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
1540#else
1541	TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
1542#endif
1543		if (ifma->ifma_addr->sa_family != AF_LINK)
1544			continue;
1545		if (i < 16) {
1546			bcopy(LLADDR((struct sockaddr_dl *)ifma->ifma_addr),
1547			    (char *)&mcast.wi_mcast[i], ETHER_ADDR_LEN);
1548			i++;
1549		} else {
1550			bzero((char *)&mcast, sizeof(mcast));
1551			break;
1552		}
1553	}
1554
1555	mcast.wi_len = (i * 3) + 1;
1556	wi_write_record(sc, (struct wi_ltv_gen *)&mcast);
1557
1558	return;
1559}
1560
1561static void
1562wi_setdef(sc, wreq)
1563	struct wi_softc		*sc;
1564	struct wi_req		*wreq;
1565{
1566	struct sockaddr_dl	*sdl;
1567	struct ifaddr		*ifa;
1568	struct ifnet		*ifp;
1569
1570	ifp = &sc->arpcom.ac_if;
1571
1572	switch(wreq->wi_type) {
1573	case WI_RID_MAC_NODE:
1574		ifa = ifaddr_byindex(ifp->if_index);
1575		sdl = (struct sockaddr_dl *)ifa->ifa_addr;
1576		bcopy((char *)&wreq->wi_val, (char *)&sc->arpcom.ac_enaddr,
1577		   ETHER_ADDR_LEN);
1578		bcopy((char *)&wreq->wi_val, LLADDR(sdl), ETHER_ADDR_LEN);
1579		break;
1580	case WI_RID_PORTTYPE:
1581		sc->wi_ptype = le16toh(wreq->wi_val[0]);
1582		break;
1583	case WI_RID_TX_RATE:
1584		sc->wi_tx_rate = le16toh(wreq->wi_val[0]);
1585		break;
1586	case WI_RID_MAX_DATALEN:
1587		sc->wi_max_data_len = le16toh(wreq->wi_val[0]);
1588		break;
1589	case WI_RID_RTS_THRESH:
1590		sc->wi_rts_thresh = le16toh(wreq->wi_val[0]);
1591		break;
1592	case WI_RID_SYSTEM_SCALE:
1593		sc->wi_ap_density = le16toh(wreq->wi_val[0]);
1594		break;
1595	case WI_RID_CREATE_IBSS:
1596		sc->wi_create_ibss = le16toh(wreq->wi_val[0]);
1597		break;
1598	case WI_RID_OWN_CHNL:
1599		sc->wi_channel = le16toh(wreq->wi_val[0]);
1600		break;
1601	case WI_RID_NODENAME:
1602		bzero(sc->wi_node_name, sizeof(sc->wi_node_name));
1603		bcopy((char *)&wreq->wi_val[1], sc->wi_node_name, 30);
1604		break;
1605	case WI_RID_DESIRED_SSID:
1606		bzero(sc->wi_net_name, sizeof(sc->wi_net_name));
1607		bcopy((char *)&wreq->wi_val[1], sc->wi_net_name, 30);
1608		break;
1609	case WI_RID_OWN_SSID:
1610		bzero(sc->wi_ibss_name, sizeof(sc->wi_ibss_name));
1611		bcopy((char *)&wreq->wi_val[1], sc->wi_ibss_name, 30);
1612		break;
1613	case WI_RID_PM_ENABLED:
1614		sc->wi_pm_enabled = le16toh(wreq->wi_val[0]);
1615		break;
1616	case WI_RID_MICROWAVE_OVEN:
1617		sc->wi_mor_enabled = le16toh(wreq->wi_val[0]);
1618		break;
1619	case WI_RID_MAX_SLEEP:
1620		sc->wi_max_sleep = le16toh(wreq->wi_val[0]);
1621		break;
1622	case WI_RID_CNFAUTHMODE:
1623		sc->wi_authtype = le16toh(wreq->wi_val[0]);
1624		break;
1625	case WI_RID_ROAMING_MODE:
1626		sc->wi_roaming = le16toh(wreq->wi_val[0]);
1627		break;
1628	case WI_RID_ENCRYPTION:
1629		sc->wi_use_wep = le16toh(wreq->wi_val[0]);
1630		break;
1631	case WI_RID_TX_CRYPT_KEY:
1632		sc->wi_tx_key = le16toh(wreq->wi_val[0]);
1633		break;
1634	case WI_RID_DEFLT_CRYPT_KEYS:
1635		bcopy((char *)wreq, (char *)&sc->wi_keys,
1636		    sizeof(struct wi_ltv_keys));
1637		break;
1638	default:
1639		break;
1640	}
1641
1642	/* Reinitialize WaveLAN. */
1643	wi_init(sc);
1644
1645	return;
1646}
1647
1648static int
1649wi_ioctl(ifp, command, data)
1650	struct ifnet		*ifp;
1651	u_long			command;
1652	caddr_t			data;
1653{
1654	int			error = 0;
1655	int			len;
1656	int			s;
1657	uint16_t		mif;
1658	uint16_t		val;
1659	u_int8_t		tmpkey[14];
1660	char			tmpssid[IEEE80211_NWID_LEN];
1661	struct wi_softc		*sc;
1662	struct wi_req		wreq;
1663	struct ifreq		*ifr;
1664	struct ieee80211req	*ireq;
1665#if __FreeBSD_version >= 500000
1666	struct thread		*td = curthread;
1667#else
1668	struct proc		*td = curproc;		/* Little white lie */
1669#endif
1670
1671	sc = ifp->if_softc;
1672	WI_LOCK(sc, s);
1673	ifr = (struct ifreq *)data;
1674	ireq = (struct ieee80211req *)data;
1675
1676	if (sc->wi_gone) {
1677		error = ENODEV;
1678		goto out;
1679	}
1680
1681	switch(command) {
1682	case SIOCSIFADDR:
1683	case SIOCGIFADDR:
1684	case SIOCSIFMTU:
1685		error = ether_ioctl(ifp, command, data);
1686		break;
1687	case SIOCSIFFLAGS:
1688		/*
1689		 * Can't do promisc and hostap at the same time.  If all that's
1690		 * changing is the promisc flag, try to short-circuit a call to
1691		 * wi_init() by just setting PROMISC in the hardware.
1692		 */
1693		if (ifp->if_flags & IFF_UP) {
1694			if (sc->wi_ptype != WI_PORTTYPE_HOSTAP &&
1695			    ifp->if_flags & IFF_RUNNING) {
1696				if (ifp->if_flags & IFF_PROMISC &&
1697				    !(sc->wi_if_flags & IFF_PROMISC)) {
1698					WI_SETVAL(WI_RID_PROMISC, 1);
1699				} else if (!(ifp->if_flags & IFF_PROMISC) &&
1700				    sc->wi_if_flags & IFF_PROMISC) {
1701					WI_SETVAL(WI_RID_PROMISC, 0);
1702				} else {
1703					wi_init(sc);
1704				}
1705			} else {
1706				wi_init(sc);
1707			}
1708		} else {
1709			if (ifp->if_flags & IFF_RUNNING) {
1710				wi_stop(sc);
1711			}
1712		}
1713		sc->wi_if_flags = ifp->if_flags;
1714		error = 0;
1715		break;
1716	case SIOCSIFMEDIA:
1717	case SIOCGIFMEDIA:
1718		error = ifmedia_ioctl(ifp, ifr, &sc->ifmedia, command);
1719		break;
1720	case SIOCADDMULTI:
1721	case SIOCDELMULTI:
1722		wi_setmulti(sc);
1723		error = 0;
1724		break;
1725	case SIOCGWAVELAN:
1726		error = copyin(ifr->ifr_data, &wreq, sizeof(wreq));
1727		if (error)
1728			break;
1729		if (wreq.wi_len > WI_MAX_DATALEN) {
1730			error = EINVAL;
1731			break;
1732		}
1733		/* Don't show WEP keys to non-root users. */
1734		if (wreq.wi_type == WI_RID_DEFLT_CRYPT_KEYS && suser(td))
1735			break;
1736		if (wreq.wi_type == WI_RID_IFACE_STATS) {
1737			bcopy((char *)&sc->wi_stats, (char *)&wreq.wi_val,
1738			    sizeof(sc->wi_stats));
1739			wreq.wi_len = (sizeof(sc->wi_stats) / 2) + 1;
1740		} else if (wreq.wi_type == WI_RID_DEFLT_CRYPT_KEYS) {
1741			bcopy((char *)&sc->wi_keys, (char *)&wreq,
1742			    sizeof(struct wi_ltv_keys));
1743		}
1744#ifdef WICACHE
1745		else if (wreq.wi_type == WI_RID_ZERO_CACHE) {
1746			sc->wi_sigitems = sc->wi_nextitem = 0;
1747		} else if (wreq.wi_type == WI_RID_READ_CACHE) {
1748			char *pt = (char *)&wreq.wi_val;
1749			bcopy((char *)&sc->wi_sigitems,
1750			    (char *)pt, sizeof(int));
1751			pt += (sizeof (int));
1752			wreq.wi_len = sizeof(int) / 2;
1753			bcopy((char *)&sc->wi_sigcache, (char *)pt,
1754			    sizeof(struct wi_sigcache) * sc->wi_sigitems);
1755			wreq.wi_len += ((sizeof(struct wi_sigcache) *
1756			    sc->wi_sigitems) / 2) + 1;
1757		}
1758#endif
1759		else if (wreq.wi_type == WI_RID_PROCFRAME) {
1760			wreq.wi_len = 2;
1761			wreq.wi_val[0] = sc->wi_procframe;
1762		} else if (wreq.wi_type == WI_RID_PRISM2) {
1763			wreq.wi_len = 2;
1764			wreq.wi_val[0] = sc->sc_firmware_type != WI_LUCENT;
1765		} else if (wreq.wi_type == WI_RID_SCAN_RES &&
1766		    sc->sc_firmware_type == WI_LUCENT) {
1767			memcpy((char *)wreq.wi_val, (char *)sc->wi_scanbuf,
1768			    sc->wi_scanbuf_len * 2);
1769			wreq.wi_len = sc->wi_scanbuf_len;
1770		} else if (wreq.wi_type == WI_RID_MIF) {
1771			mif = wreq.wi_val[0];
1772			error = wi_cmd(sc, WI_CMD_READMIF, mif, 0, 0);
1773			val = CSR_READ_2(sc, WI_RESP0);
1774			wreq.wi_len = 2;
1775			wreq.wi_val[0] = val;
1776		} else {
1777			if (wi_read_record(sc, (struct wi_ltv_gen *)&wreq)) {
1778				error = EINVAL;
1779				break;
1780			}
1781		}
1782		error = copyout(&wreq, ifr->ifr_data, sizeof(wreq));
1783		break;
1784	case SIOCSWAVELAN:
1785		if ((error = suser(td)))
1786			goto out;
1787		error = copyin(ifr->ifr_data, &wreq, sizeof(wreq));
1788		if (error)
1789			break;
1790		if (wreq.wi_len > WI_MAX_DATALEN) {
1791			error = EINVAL;
1792			break;
1793		}
1794		if (wreq.wi_type == WI_RID_IFACE_STATS) {
1795			error = EINVAL;
1796			break;
1797		} else if (wreq.wi_type == WI_RID_MGMT_XMIT) {
1798			error = wi_mgmt_xmit(sc, (caddr_t)&wreq.wi_val,
1799			    wreq.wi_len);
1800		} else if (wreq.wi_type == WI_RID_PROCFRAME) {
1801			sc->wi_procframe = wreq.wi_val[0];
1802		/*
1803		 * if we're getting a scan request from a wavelan card
1804		 * (non-prism2), send out a cmd_inquire to the card to scan
1805		 * results for the scan will be received through the info
1806		 * interrupt handler. otherwise the scan request can be
1807		 * directly handled by a prism2 card's rid interface.
1808		 */
1809		} else if (wreq.wi_type == WI_RID_SCAN_REQ &&
1810		    sc->sc_firmware_type == WI_LUCENT) {
1811			wi_cmd(sc, WI_CMD_INQUIRE, WI_INFO_SCAN_RESULTS, 0, 0);
1812		} else if (wreq.wi_type == WI_RID_MIF) {
1813			mif = wreq.wi_val[0];
1814			val = wreq.wi_val[1];
1815			error = wi_cmd(sc, WI_CMD_WRITEMIF, mif, val, 0);
1816		} else {
1817			error = wi_write_record(sc, (struct wi_ltv_gen *)&wreq);
1818			if (!error)
1819				wi_setdef(sc, &wreq);
1820		}
1821		break;
1822	case SIOCGPRISM2DEBUG:
1823		error = copyin(ifr->ifr_data, &wreq, sizeof(wreq));
1824		if (error)
1825			break;
1826		if (!(ifp->if_flags & IFF_RUNNING) ||
1827		    sc->sc_firmware_type == WI_LUCENT) {
1828			error = EIO;
1829			break;
1830		}
1831		error = wi_get_debug(sc, &wreq);
1832		if (error == 0)
1833			error = copyout(&wreq, ifr->ifr_data, sizeof(wreq));
1834		break;
1835	case SIOCSPRISM2DEBUG:
1836		if ((error = suser(td)))
1837			goto out;
1838		error = copyin(ifr->ifr_data, &wreq, sizeof(wreq));
1839		if (error)
1840			break;
1841		error = wi_set_debug(sc, &wreq);
1842		break;
1843	case SIOCG80211:
1844		switch(ireq->i_type) {
1845		case IEEE80211_IOC_SSID:
1846			if(ireq->i_val == -1) {
1847				bzero(tmpssid, IEEE80211_NWID_LEN);
1848				error = wi_get_cur_ssid(sc, tmpssid, &len);
1849				if (error != 0)
1850					break;
1851				error = copyout(tmpssid, ireq->i_data,
1852					IEEE80211_NWID_LEN);
1853				ireq->i_len = len;
1854			} else if (ireq->i_val == 0) {
1855				error = copyout(sc->wi_net_name,
1856				    ireq->i_data,
1857				    IEEE80211_NWID_LEN);
1858				ireq->i_len = IEEE80211_NWID_LEN;
1859			} else
1860				error = EINVAL;
1861			break;
1862		case IEEE80211_IOC_NUMSSIDS:
1863			ireq->i_val = 1;
1864			break;
1865		case IEEE80211_IOC_WEP:
1866			if(!sc->wi_has_wep) {
1867				ireq->i_val = IEEE80211_WEP_NOSUP;
1868			} else {
1869				if(sc->wi_use_wep) {
1870					ireq->i_val =
1871					    IEEE80211_WEP_MIXED;
1872				} else {
1873					ireq->i_val =
1874					    IEEE80211_WEP_OFF;
1875				}
1876			}
1877			break;
1878		case IEEE80211_IOC_WEPKEY:
1879			if(!sc->wi_has_wep ||
1880			    ireq->i_val < 0 || ireq->i_val > 3) {
1881				error = EINVAL;
1882				break;
1883			}
1884			len = sc->wi_keys.wi_keys[ireq->i_val].wi_keylen;
1885			if (suser(td))
1886				bcopy(sc->wi_keys.wi_keys[ireq->i_val].wi_keydat,
1887				    tmpkey, len);
1888			else
1889				bzero(tmpkey, len);
1890
1891			ireq->i_len = len;
1892			error = copyout(tmpkey, ireq->i_data, len);
1893
1894			break;
1895		case IEEE80211_IOC_NUMWEPKEYS:
1896			if(!sc->wi_has_wep)
1897				error = EINVAL;
1898			else
1899				ireq->i_val = 4;
1900			break;
1901		case IEEE80211_IOC_WEPTXKEY:
1902			if(!sc->wi_has_wep)
1903				error = EINVAL;
1904			else
1905				ireq->i_val = sc->wi_tx_key;
1906			break;
1907		case IEEE80211_IOC_AUTHMODE:
1908			ireq->i_val = sc->wi_authmode;
1909			break;
1910		case IEEE80211_IOC_STATIONNAME:
1911			error = copyout(sc->wi_node_name,
1912			    ireq->i_data, IEEE80211_NWID_LEN);
1913			ireq->i_len = IEEE80211_NWID_LEN;
1914			break;
1915		case IEEE80211_IOC_CHANNEL:
1916			wreq.wi_type = WI_RID_CURRENT_CHAN;
1917			wreq.wi_len = WI_MAX_DATALEN;
1918			if (wi_read_record(sc, (struct wi_ltv_gen *)&wreq))
1919				error = EINVAL;
1920			else {
1921				ireq->i_val = wreq.wi_val[0];
1922			}
1923			break;
1924		case IEEE80211_IOC_POWERSAVE:
1925			if(sc->wi_pm_enabled)
1926				ireq->i_val = IEEE80211_POWERSAVE_ON;
1927			else
1928				ireq->i_val = IEEE80211_POWERSAVE_OFF;
1929			break;
1930		case IEEE80211_IOC_POWERSAVESLEEP:
1931			ireq->i_val = sc->wi_max_sleep;
1932			break;
1933		default:
1934			error = EINVAL;
1935		}
1936		break;
1937	case SIOCS80211:
1938		if ((error = suser(td)))
1939			goto out;
1940		switch(ireq->i_type) {
1941		case IEEE80211_IOC_SSID:
1942			if (ireq->i_val != 0 ||
1943			    ireq->i_len > IEEE80211_NWID_LEN) {
1944				error = EINVAL;
1945				break;
1946			}
1947			/* We set both of them */
1948			bzero(sc->wi_net_name, IEEE80211_NWID_LEN);
1949			error = copyin(ireq->i_data,
1950			    sc->wi_net_name, ireq->i_len);
1951			bcopy(sc->wi_net_name, sc->wi_ibss_name, IEEE80211_NWID_LEN);
1952			break;
1953		case IEEE80211_IOC_WEP:
1954			/*
1955			 * These cards only support one mode so
1956			 * we just turn wep on what ever is
1957			 * passed in if it's not OFF.
1958			 */
1959			if (ireq->i_val == IEEE80211_WEP_OFF) {
1960				sc->wi_use_wep = 0;
1961			} else {
1962				sc->wi_use_wep = 1;
1963			}
1964			break;
1965		case IEEE80211_IOC_WEPKEY:
1966			if (ireq->i_val < 0 || ireq->i_val > 3 ||
1967				ireq->i_len > 13) {
1968				error = EINVAL;
1969				break;
1970			}
1971			bzero(sc->wi_keys.wi_keys[ireq->i_val].wi_keydat, 13);
1972			error = copyin(ireq->i_data,
1973			    sc->wi_keys.wi_keys[ireq->i_val].wi_keydat,
1974			    ireq->i_len);
1975			if(error)
1976				break;
1977			sc->wi_keys.wi_keys[ireq->i_val].wi_keylen =
1978				    ireq->i_len;
1979			break;
1980		case IEEE80211_IOC_WEPTXKEY:
1981			if (ireq->i_val < 0 || ireq->i_val > 3) {
1982				error = EINVAL;
1983				break;
1984			}
1985			sc->wi_tx_key = ireq->i_val;
1986			break;
1987		case IEEE80211_IOC_AUTHMODE:
1988			sc->wi_authmode = ireq->i_val;
1989			break;
1990		case IEEE80211_IOC_STATIONNAME:
1991			if (ireq->i_len > 32) {
1992				error = EINVAL;
1993				break;
1994			}
1995			bzero(sc->wi_node_name, 32);
1996			error = copyin(ireq->i_data,
1997			    sc->wi_node_name, ireq->i_len);
1998			break;
1999		case IEEE80211_IOC_CHANNEL:
2000			/*
2001			 * The actual range is 1-14, but if you
2002			 * set it to 0 you get the default. So
2003			 * we let that work too.
2004			 */
2005			if (ireq->i_val < 0 || ireq->i_val > 14) {
2006				error = EINVAL;
2007				break;
2008			}
2009			sc->wi_channel = ireq->i_val;
2010			break;
2011		case IEEE80211_IOC_POWERSAVE:
2012			switch (ireq->i_val) {
2013			case IEEE80211_POWERSAVE_OFF:
2014				sc->wi_pm_enabled = 0;
2015				break;
2016			case IEEE80211_POWERSAVE_ON:
2017				sc->wi_pm_enabled = 1;
2018				break;
2019			default:
2020				error = EINVAL;
2021				break;
2022			}
2023			break;
2024		case IEEE80211_IOC_POWERSAVESLEEP:
2025			if (ireq->i_val < 0) {
2026				error = EINVAL;
2027				break;
2028			}
2029			sc->wi_max_sleep = ireq->i_val;
2030			break;
2031		default:
2032			error = EINVAL;
2033			break;
2034		}
2035
2036		/* Reinitialize WaveLAN. */
2037		wi_init(sc);
2038
2039	break;
2040	case SIOCHOSTAP_ADD:
2041	case SIOCHOSTAP_DEL:
2042	case SIOCHOSTAP_GET:
2043	case SIOCHOSTAP_GETALL:
2044	case SIOCHOSTAP_GFLAGS:
2045	case SIOCHOSTAP_SFLAGS:
2046		/* Send all Host AP specific ioctl's to Host AP code. */
2047		error = wihap_ioctl(sc, command, data);
2048		break;
2049	default:
2050		error = EINVAL;
2051		break;
2052	}
2053out:
2054	WI_UNLOCK(sc, s);
2055
2056	return(error);
2057}
2058
2059static void
2060wi_init(xsc)
2061	void			*xsc;
2062{
2063	struct wi_softc		*sc = xsc;
2064	struct ifnet		*ifp = &sc->arpcom.ac_if;
2065	struct wi_ltv_macaddr	mac;
2066	int			id = 0;
2067	int			s;
2068
2069	WI_LOCK(sc, s);
2070
2071	if (sc->wi_gone) {
2072		WI_UNLOCK(sc, s);
2073		return;
2074	}
2075
2076	if (ifp->if_flags & IFF_RUNNING)
2077		wi_stop(sc);
2078
2079	wi_reset(sc);
2080
2081	/* Program max data length. */
2082	WI_SETVAL(WI_RID_MAX_DATALEN, sc->wi_max_data_len);
2083
2084	/* Set the port type. */
2085	WI_SETVAL(WI_RID_PORTTYPE, sc->wi_ptype);
2086
2087	/* Enable/disable IBSS creation. */
2088	WI_SETVAL(WI_RID_CREATE_IBSS, sc->wi_create_ibss);
2089
2090	/* Program the RTS/CTS threshold. */
2091	WI_SETVAL(WI_RID_RTS_THRESH, sc->wi_rts_thresh);
2092
2093	/* Program the TX rate */
2094	WI_SETVAL(WI_RID_TX_RATE, sc->wi_tx_rate);
2095
2096	/* Access point density */
2097	WI_SETVAL(WI_RID_SYSTEM_SCALE, sc->wi_ap_density);
2098
2099	/* Power Management Enabled */
2100	WI_SETVAL(WI_RID_PM_ENABLED, sc->wi_pm_enabled);
2101
2102	/* Power Managment Max Sleep */
2103	WI_SETVAL(WI_RID_MAX_SLEEP, sc->wi_max_sleep);
2104
2105	/* Roaming type */
2106	WI_SETVAL(WI_RID_ROAMING_MODE, sc->wi_roaming);
2107
2108	/* Specify the IBSS name */
2109	WI_SETSTR(WI_RID_OWN_SSID, sc->wi_ibss_name);
2110
2111	/* Specify the network name */
2112	WI_SETSTR(WI_RID_DESIRED_SSID, sc->wi_net_name);
2113
2114	/* Specify the frequency to use */
2115	WI_SETVAL(WI_RID_OWN_CHNL, sc->wi_channel);
2116
2117	/* Program the nodename. */
2118	WI_SETSTR(WI_RID_NODENAME, sc->wi_node_name);
2119
2120	/* Specify the authentication mode. */
2121	WI_SETVAL(WI_RID_CNFAUTHMODE, sc->wi_authmode);
2122
2123	/* Set our MAC address. */
2124	mac.wi_len = 4;
2125	mac.wi_type = WI_RID_MAC_NODE;
2126	bcopy((char *)&sc->arpcom.ac_enaddr,
2127	   (char *)&mac.wi_mac_addr, ETHER_ADDR_LEN);
2128	wi_write_record(sc, (struct wi_ltv_gen *)&mac);
2129
2130	/*
2131	 * Initialize promisc mode.
2132	 *      Being in the Host-AP mode causes
2133	 *      great deal of pain if promisc mode is set.
2134	 *      Therefore we avoid confusing the firmware
2135	 *      and always reset promisc mode in Host-AP regime,
2136	 *      it shows us all the packets anyway.
2137	 */
2138	if (sc->wi_ptype != WI_PORTTYPE_HOSTAP && ifp->if_flags & IFF_PROMISC)
2139		WI_SETVAL(WI_RID_PROMISC, 1);
2140	else
2141		WI_SETVAL(WI_RID_PROMISC, 0);
2142
2143	/* Configure WEP. */
2144	if (sc->wi_has_wep) {
2145		WI_SETVAL(WI_RID_ENCRYPTION, sc->wi_use_wep);
2146		WI_SETVAL(WI_RID_TX_CRYPT_KEY, sc->wi_tx_key);
2147		sc->wi_keys.wi_len = (sizeof(struct wi_ltv_keys) / 2) + 1;
2148		sc->wi_keys.wi_type = WI_RID_DEFLT_CRYPT_KEYS;
2149		wi_write_record(sc, (struct wi_ltv_gen *)&sc->wi_keys);
2150		if (sc->sc_firmware_type != WI_LUCENT && sc->wi_use_wep) {
2151			/*
2152			 * ONLY HWB3163 EVAL-CARD Firmware version
2153			 * less than 0.8 variant2
2154			 *
2155			 * If promiscuous mode disable, Prism2 chip
2156			 * does not work with WEP.
2157			 * It is under investigation for details.
2158			 * (ichiro@netbsd.org)
2159			 *
2160			 * And make sure that we don't need to do it
2161			 * in hostap mode, since it interferes with
2162			 * the above hostap workaround.
2163			 */
2164			if (sc->wi_ptype != WI_PORTTYPE_HOSTAP &&
2165			    sc->sc_firmware_type == WI_INTERSIL &&
2166			    sc->sc_sta_firmware_ver < 802 ) {
2167				/* firm ver < 0.8 variant 2 */
2168				WI_SETVAL(WI_RID_PROMISC, 1);
2169			}
2170			WI_SETVAL(WI_RID_CNFAUTHMODE, sc->wi_authtype);
2171		}
2172	}
2173
2174	/* Set multicast filter. */
2175	wi_setmulti(sc);
2176
2177	/* Enable desired port */
2178	wi_cmd(sc, WI_CMD_ENABLE | sc->wi_portnum, 0, 0, 0);
2179
2180	if (wi_alloc_nicmem(sc, ETHER_MAX_LEN + sizeof(struct wi_frame) + 8, &id))
2181		device_printf(sc->dev, "tx buffer allocation failed\n");
2182	sc->wi_tx_data_id = id;
2183
2184	if (wi_alloc_nicmem(sc, ETHER_MAX_LEN + sizeof(struct wi_frame) + 8, &id))
2185		device_printf(sc->dev, "mgmt. buffer allocation failed\n");
2186	sc->wi_tx_mgmt_id = id;
2187
2188	/* enable interrupts */
2189	CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS);
2190
2191	wihap_init(sc);
2192
2193	ifp->if_flags |= IFF_RUNNING;
2194	ifp->if_flags &= ~IFF_OACTIVE;
2195
2196	sc->wi_stat_ch = timeout(wi_inquire, sc, hz * 60);
2197	WI_UNLOCK(sc, s);
2198
2199	return;
2200}
2201
2202#define RC4STATE 256
2203#define RC4KEYLEN 16
2204#define RC4SWAP(x,y) \
2205    do { u_int8_t t = state[x]; state[x] = state[y]; state[y] = t; } while(0)
2206
2207static void
2208wi_do_hostencrypt(struct wi_softc *sc, caddr_t buf, int len)
2209{
2210	u_int32_t i, crc, klen;
2211	u_int8_t state[RC4STATE], key[RC4KEYLEN];
2212	u_int8_t x, y, *dat;
2213
2214	if (!sc->wi_icv_flag) {
2215		sc->wi_icv = arc4random();
2216		sc->wi_icv_flag++;
2217        } else
2218		sc->wi_icv++;
2219	/*
2220	 * Skip 'bad' IVs from Fluhrer/Mantin/Shamir:
2221	 * (B, 255, N) with 3 <= B < 8
2222	 */
2223	if (sc->wi_icv >= 0x03ff00 &&
2224            (sc->wi_icv & 0xf8ff00) == 0x00ff00)
2225                sc->wi_icv += 0x000100;
2226
2227	/* prepend 24bit IV to tx key, byte order does not matter */
2228	key[0] = sc->wi_icv >> 16;
2229	key[1] = sc->wi_icv >> 8;
2230	key[2] = sc->wi_icv;
2231
2232	klen = sc->wi_keys.wi_keys[sc->wi_tx_key].wi_keylen +
2233	    IEEE80211_WEP_IVLEN;
2234	klen = (klen >= RC4KEYLEN) ? RC4KEYLEN : RC4KEYLEN/2;
2235	bcopy((char *)&sc->wi_keys.wi_keys[sc->wi_tx_key].wi_keydat,
2236	    (char *)key + IEEE80211_WEP_IVLEN, klen - IEEE80211_WEP_IVLEN);
2237
2238	/* rc4 keysetup */
2239	x = y = 0;
2240	for (i = 0; i < RC4STATE; i++)
2241		state[i] = i;
2242	for (i = 0; i < RC4STATE; i++) {
2243		y = (key[x] + state[i] + y) % RC4STATE;
2244		RC4SWAP(i, y);
2245		x = (x + 1) % klen;
2246	}
2247
2248	/* output: IV, tx keyid, rc4(data), rc4(crc32(data)) */
2249	dat = buf;
2250	dat[0] = key[0];
2251	dat[1] = key[1];
2252	dat[2] = key[2];
2253	dat[3] = sc->wi_tx_key << 6;		/* pad and keyid */
2254	dat += 4;
2255
2256	/* compute rc4 over data, crc32 over data */
2257	crc = ~0;
2258	x = y = 0;
2259	for (i = 0; i < len; i++) {
2260		x = (x + 1) % RC4STATE;
2261		y = (state[x] + y) % RC4STATE;
2262		RC4SWAP(x, y);
2263		crc = crc32_tab[(crc ^ dat[i]) & 0xff] ^ (crc >> 8);
2264		dat[i] ^= state[(state[x] + state[y]) % RC4STATE];
2265	}
2266	crc = ~crc;
2267	dat += len;
2268
2269	/* append little-endian crc32 and encrypt */
2270	dat[0] = crc;
2271	dat[1] = crc >> 8;
2272	dat[2] = crc >> 16;
2273	dat[3] = crc >> 24;
2274	for (i = 0; i < IEEE80211_WEP_CRCLEN; i++) {
2275		x = (x + 1) % RC4STATE;
2276		y = (state[x] + y) % RC4STATE;
2277		RC4SWAP(x, y);
2278		dat[i] ^= state[(state[x] + state[y]) % RC4STATE];
2279	}
2280}
2281
2282static void
2283wi_start(ifp)
2284	struct ifnet		*ifp;
2285{
2286	struct wi_softc		*sc;
2287	struct mbuf		*m0;
2288	struct wi_frame		tx_frame;
2289	struct ether_header	*eh;
2290	int			id;
2291	int			s;
2292
2293	sc = ifp->if_softc;
2294	WI_LOCK(sc, s);
2295
2296	if (sc->wi_gone) {
2297		WI_UNLOCK(sc, s);
2298		return;
2299	}
2300
2301	if (ifp->if_flags & IFF_OACTIVE) {
2302		WI_UNLOCK(sc, s);
2303		return;
2304	}
2305
2306nextpkt:
2307	IF_DEQUEUE(&ifp->if_snd, m0);
2308	if (m0 == NULL) {
2309		WI_UNLOCK(sc, s);
2310		return;
2311	}
2312
2313	bzero((char *)&tx_frame, sizeof(tx_frame));
2314	tx_frame.wi_frame_ctl = htole16(WI_FTYPE_DATA);
2315	id = sc->wi_tx_data_id;
2316	eh = mtod(m0, struct ether_header *);
2317
2318	if (sc->wi_ptype == WI_PORTTYPE_HOSTAP) {
2319		if (!wihap_check_tx(&sc->wi_hostap_info,
2320		    eh->ether_dhost, &tx_frame.wi_tx_rate)) {
2321			if (ifp->if_flags & IFF_DEBUG)
2322				printf("wi_start: dropping unassoc "
2323				       "dst %6D\n", eh->ether_dhost, ":");
2324			m_freem(m0);
2325			goto nextpkt;
2326		}
2327	}
2328	/*
2329	 * Use RFC1042 encoding for IP and ARP datagrams,
2330	 * 802.3 for anything else.
2331	 */
2332	if (ntohs(eh->ether_type) > ETHER_MAX_LEN) {
2333		bcopy((char *)&eh->ether_dhost,
2334		    (char *)&tx_frame.wi_addr1, ETHER_ADDR_LEN);
2335		if (sc->wi_ptype == WI_PORTTYPE_HOSTAP) {
2336			tx_frame.wi_tx_ctl = WI_ENC_TX_MGMT; /* XXX */
2337			tx_frame.wi_frame_ctl |= WI_FCTL_FROMDS;
2338			if (sc->wi_use_wep)
2339				tx_frame.wi_frame_ctl |= WI_FCTL_WEP;
2340			bcopy((char *)&sc->arpcom.ac_enaddr,
2341			      (char *)&tx_frame.wi_addr2, ETHER_ADDR_LEN);
2342			bcopy((char *)&eh->ether_shost,
2343			      (char *)&tx_frame.wi_addr3, ETHER_ADDR_LEN);
2344		}
2345		else
2346			bcopy((char *)&eh->ether_shost,
2347			    (char *)&tx_frame.wi_addr2, ETHER_ADDR_LEN);
2348		bcopy((char *)&eh->ether_dhost,
2349		    (char *)&tx_frame.wi_dst_addr, ETHER_ADDR_LEN);
2350		bcopy((char *)&eh->ether_shost,
2351		    (char *)&tx_frame.wi_src_addr, ETHER_ADDR_LEN);
2352
2353		tx_frame.wi_dat_len = m0->m_pkthdr.len - WI_SNAPHDR_LEN;
2354		tx_frame.wi_dat[0] = htons(WI_SNAP_WORD0);
2355		tx_frame.wi_dat[1] = htons(WI_SNAP_WORD1);
2356		tx_frame.wi_len = htons(m0->m_pkthdr.len - WI_SNAPHDR_LEN);
2357		tx_frame.wi_type = eh->ether_type;
2358
2359		if (sc->wi_ptype == WI_PORTTYPE_HOSTAP && sc->wi_use_wep) {
2360			/* Do host encryption. */
2361			bcopy(&tx_frame.wi_dat[0], &sc->wi_txbuf[4], 8);
2362			m_copydata(m0, sizeof(struct ether_header),
2363			    m0->m_pkthdr.len - sizeof(struct ether_header),
2364			    (caddr_t)&sc->wi_txbuf[12]);
2365			wi_do_hostencrypt(sc, &sc->wi_txbuf[0],
2366			    tx_frame.wi_dat_len);
2367			tx_frame.wi_dat_len += IEEE80211_WEP_IVLEN +
2368			    IEEE80211_WEP_KIDLEN + IEEE80211_WEP_CRCLEN;
2369			wi_write_data(sc, id, 0, (caddr_t)&tx_frame,
2370			    sizeof(struct wi_frame));
2371			wi_write_data(sc, id, WI_802_11_OFFSET_RAW,
2372			    (caddr_t)&sc->wi_txbuf, (m0->m_pkthdr.len -
2373			    sizeof(struct ether_header)) + 18);
2374		} else {
2375			m_copydata(m0, sizeof(struct ether_header),
2376			    m0->m_pkthdr.len - sizeof(struct ether_header),
2377			    (caddr_t)&sc->wi_txbuf);
2378			wi_write_data(sc, id, 0, (caddr_t)&tx_frame,
2379			    sizeof(struct wi_frame));
2380			wi_write_data(sc, id, WI_802_11_OFFSET,
2381			    (caddr_t)&sc->wi_txbuf, (m0->m_pkthdr.len -
2382			    sizeof(struct ether_header)) + 2);
2383		}
2384	} else {
2385		tx_frame.wi_dat_len = m0->m_pkthdr.len;
2386
2387		if (sc->wi_ptype == WI_PORTTYPE_HOSTAP && sc->wi_use_wep) {
2388			/* Do host encryption. */
2389			printf( "XXX: host encrypt not implemented for 802.3\n" );
2390		} else {
2391			eh->ether_type = htons(m0->m_pkthdr.len -
2392			    WI_SNAPHDR_LEN);
2393			m_copydata(m0, 0, m0->m_pkthdr.len,
2394			    (caddr_t)&sc->wi_txbuf);
2395
2396			wi_write_data(sc, id, 0, (caddr_t)&tx_frame,
2397			    sizeof(struct wi_frame));
2398			wi_write_data(sc, id, WI_802_3_OFFSET,
2399			    (caddr_t)&sc->wi_txbuf, m0->m_pkthdr.len + 2);
2400		}
2401	}
2402
2403	/*
2404	 * If there's a BPF listner, bounce a copy of
2405 	 * this frame to him. Also, don't send this to the bpf sniffer
2406 	 * if we're in procframe or monitor sniffing mode.
2407	 */
2408 	if (!(sc->wi_procframe || sc->wi_debug.wi_monitor) && ifp->if_bpf)
2409		bpf_mtap(ifp, m0);
2410
2411	m_freem(m0);
2412
2413	if (wi_cmd(sc, WI_CMD_TX|WI_RECLAIM, id, 0, 0))
2414		device_printf(sc->dev, "xmit failed\n");
2415
2416	ifp->if_flags |= IFF_OACTIVE;
2417
2418	/*
2419	 * Set a timeout in case the chip goes out to lunch.
2420	 */
2421	ifp->if_timer = 5;
2422
2423	WI_UNLOCK(sc, s);
2424	return;
2425}
2426
2427int
2428wi_mgmt_xmit(sc, data, len)
2429	struct wi_softc		*sc;
2430	caddr_t			data;
2431	int			len;
2432{
2433	struct wi_frame		tx_frame;
2434	int			id;
2435	struct wi_80211_hdr	*hdr;
2436	caddr_t			dptr;
2437
2438	if (sc->wi_gone)
2439		return(ENODEV);
2440
2441	hdr = (struct wi_80211_hdr *)data;
2442	dptr = data + sizeof(struct wi_80211_hdr);
2443
2444	bzero((char *)&tx_frame, sizeof(tx_frame));
2445	id = sc->wi_tx_mgmt_id;
2446
2447	bcopy((char *)hdr, (char *)&tx_frame.wi_frame_ctl,
2448	   sizeof(struct wi_80211_hdr));
2449
2450	tx_frame.wi_tx_ctl = WI_ENC_TX_MGMT;
2451	tx_frame.wi_dat_len = len - sizeof(struct wi_80211_hdr);
2452	tx_frame.wi_len = htons(tx_frame.wi_dat_len);
2453
2454	wi_write_data(sc, id, 0, (caddr_t)&tx_frame, sizeof(struct wi_frame));
2455	wi_write_data(sc, id, WI_802_11_OFFSET_RAW, dptr,
2456	    len - sizeof(struct wi_80211_hdr) + 2);
2457
2458	if (wi_cmd(sc, WI_CMD_TX|WI_RECLAIM, id, 0, 0)) {
2459		device_printf(sc->dev, "xmit failed\n");
2460		return(EIO);
2461	}
2462
2463	return(0);
2464}
2465
2466static void
2467wi_stop(sc)
2468	struct wi_softc		*sc;
2469{
2470	struct ifnet		*ifp;
2471	int			s;
2472
2473	WI_LOCK(sc, s);
2474
2475	if (sc->wi_gone) {
2476		WI_UNLOCK(sc, s);
2477		return;
2478	}
2479
2480	wihap_shutdown(sc);
2481
2482	ifp = &sc->arpcom.ac_if;
2483
2484	/*
2485	 * If the card is gone and the memory port isn't mapped, we will
2486	 * (hopefully) get 0xffff back from the status read, which is not
2487	 * a valid status value.
2488	 */
2489	if (CSR_READ_2(sc, WI_STATUS) != 0xffff) {
2490		CSR_WRITE_2(sc, WI_INT_EN, 0);
2491		wi_cmd(sc, WI_CMD_DISABLE|sc->wi_portnum, 0, 0, 0);
2492	}
2493
2494	untimeout(wi_inquire, sc, sc->wi_stat_ch);
2495
2496	ifp->if_flags &= ~(IFF_RUNNING|IFF_OACTIVE);
2497
2498	WI_UNLOCK(sc, s);
2499	return;
2500}
2501
2502static void
2503wi_watchdog(ifp)
2504	struct ifnet		*ifp;
2505{
2506	struct wi_softc		*sc;
2507
2508	sc = ifp->if_softc;
2509
2510	device_printf(sc->dev, "watchdog timeout\n");
2511
2512	wi_init(sc);
2513
2514	ifp->if_oerrors++;
2515
2516	return;
2517}
2518
2519int
2520wi_alloc(dev, rid)
2521	device_t		dev;
2522	int			rid;
2523{
2524	struct wi_softc		*sc = device_get_softc(dev);
2525
2526	if (sc->wi_bus_type != WI_BUS_PCI_NATIVE) {
2527		sc->iobase_rid = rid;
2528		sc->iobase = bus_alloc_resource(dev, SYS_RES_IOPORT,
2529		    &sc->iobase_rid, 0, ~0, (1 << 6),
2530		    rman_make_alignment_flags(1 << 6) | RF_ACTIVE);
2531		if (!sc->iobase) {
2532			device_printf(dev, "No I/O space?!\n");
2533			return (ENXIO);
2534		}
2535
2536		sc->wi_io_addr = rman_get_start(sc->iobase);
2537		sc->wi_btag = rman_get_bustag(sc->iobase);
2538		sc->wi_bhandle = rman_get_bushandle(sc->iobase);
2539	} else {
2540		sc->mem_rid = rid;
2541		sc->mem = bus_alloc_resource(dev, SYS_RES_MEMORY,
2542		    &sc->mem_rid, 0, ~0, 1, RF_ACTIVE);
2543
2544		if (!sc->mem) {
2545			device_printf(dev, "No Mem space on prism2.5?\n");
2546			return (ENXIO);
2547		}
2548
2549		sc->wi_btag = rman_get_bustag(sc->mem);
2550		sc->wi_bhandle = rman_get_bushandle(sc->mem);
2551	}
2552
2553
2554	sc->irq_rid = 0;
2555	sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irq_rid,
2556	    0, ~0, 1, RF_ACTIVE |
2557	    ((sc->wi_bus_type == WI_BUS_PCCARD) ? 0 : RF_SHAREABLE));
2558
2559	if (!sc->irq) {
2560		wi_free(dev);
2561		device_printf(dev, "No irq?!\n");
2562		return (ENXIO);
2563	}
2564
2565	sc->dev = dev;
2566	sc->wi_unit = device_get_unit(dev);
2567
2568	return (0);
2569}
2570
2571void
2572wi_free(dev)
2573	device_t		dev;
2574{
2575	struct wi_softc		*sc = device_get_softc(dev);
2576
2577	if (sc->iobase != NULL) {
2578		bus_release_resource(dev, SYS_RES_IOPORT, sc->iobase_rid, sc->iobase);
2579		sc->iobase = NULL;
2580	}
2581	if (sc->irq != NULL) {
2582		bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, sc->irq);
2583		sc->irq = NULL;
2584	}
2585	if (sc->mem != NULL) {
2586		bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, sc->mem);
2587		sc->mem = NULL;
2588	}
2589
2590	return;
2591}
2592
2593void
2594wi_shutdown(dev)
2595	device_t		dev;
2596{
2597	struct wi_softc		*sc;
2598
2599	sc = device_get_softc(dev);
2600	wi_stop(sc);
2601
2602	return;
2603}
2604
2605#ifdef WICACHE
2606/* wavelan signal strength cache code.
2607 * store signal/noise/quality on per MAC src basis in
2608 * a small fixed cache.  The cache wraps if > MAX slots
2609 * used.  The cache may be zeroed out to start over.
2610 * Two simple filters exist to reduce computation:
2611 * 1. ip only (literally 0x800) which may be used
2612 * to ignore some packets.  It defaults to ip only.
2613 * it could be used to focus on broadcast, non-IP 802.11 beacons.
2614 * 2. multicast/broadcast only.  This may be used to
2615 * ignore unicast packets and only cache signal strength
2616 * for multicast/broadcast packets (beacons); e.g., Mobile-IP
2617 * beacons and not unicast traffic.
2618 *
2619 * The cache stores (MAC src(index), IP src (major clue), signal,
2620 *	quality, noise)
2621 *
2622 * No apologies for storing IP src here.  It's easy and saves much
2623 * trouble elsewhere.  The cache is assumed to be INET dependent,
2624 * although it need not be.
2625 */
2626
2627#ifdef documentation
2628
2629int wi_sigitems;                                /* number of cached entries */
2630struct wi_sigcache wi_sigcache[MAXWICACHE];  /*  array of cache entries */
2631int wi_nextitem;                                /*  index/# of entries */
2632
2633
2634#endif
2635
2636/* control variables for cache filtering.  Basic idea is
2637 * to reduce cost (e.g., to only Mobile-IP agent beacons
2638 * which are broadcast or multicast).  Still you might
2639 * want to measure signal strength with unicast ping packets
2640 * on a pt. to pt. ant. setup.
2641 */
2642/* set true if you want to limit cache items to broadcast/mcast
2643 * only packets (not unicast).  Useful for mobile-ip beacons which
2644 * are broadcast/multicast at network layer.  Default is all packets
2645 * so ping/unicast will work say with pt. to pt. antennae setup.
2646 */
2647static int wi_cache_mcastonly = 0;
2648SYSCTL_INT(_machdep, OID_AUTO, wi_cache_mcastonly, CTLFLAG_RW,
2649	&wi_cache_mcastonly, 0, "");
2650
2651/* set true if you want to limit cache items to IP packets only
2652*/
2653static int wi_cache_iponly = 1;
2654SYSCTL_INT(_machdep, OID_AUTO, wi_cache_iponly, CTLFLAG_RW,
2655	&wi_cache_iponly, 0, "");
2656
2657/*
2658 * Original comments:
2659 * -----------------
2660 * wi_cache_store, per rx packet store signal
2661 * strength in MAC (src) indexed cache.
2662 *
2663 * follows linux driver in how signal strength is computed.
2664 * In ad hoc mode, we use the rx_quality field.
2665 * signal and noise are trimmed to fit in the range from 47..138.
2666 * rx_quality field MSB is signal strength.
2667 * rx_quality field LSB is noise.
2668 * "quality" is (signal - noise) as is log value.
2669 * note: quality CAN be negative.
2670 *
2671 * In BSS mode, we use the RID for communication quality.
2672 * TBD:  BSS mode is currently untested.
2673 *
2674 * Bill's comments:
2675 * ---------------
2676 * Actually, we use the rx_quality field all the time for both "ad-hoc"
2677 * and BSS modes. Why? Because reading an RID is really, really expensive:
2678 * there's a bunch of PIO operations that have to be done to read a record
2679 * from the NIC, and reading the comms quality RID each time a packet is
2680 * received can really hurt performance. We don't have to do this anyway:
2681 * the comms quality field only reflects the values in the rx_quality field
2682 * anyway. The comms quality RID is only meaningful in infrastructure mode,
2683 * but the values it contains are updated based on the rx_quality from
2684 * frames received from the access point.
2685 *
2686 * Also, according to Lucent, the signal strength and noise level values
2687 * can be converted to dBms by subtracting 149, so I've modified the code
2688 * to do that instead of the scaling it did originally.
2689 */
2690static void
2691wi_cache_store(struct wi_softc *sc, struct ether_header *eh,
2692                     struct mbuf *m, unsigned short rx_quality)
2693{
2694	struct ip *ip = 0;
2695	int i;
2696	static int cache_slot = 0; 	/* use this cache entry */
2697	static int wrapindex = 0;       /* next "free" cache entry */
2698	int sig, noise;
2699	int sawip=0;
2700
2701	/*
2702	 * filters:
2703	 * 1. ip only
2704	 * 2. configurable filter to throw out unicast packets,
2705	 * keep multicast only.
2706	 */
2707
2708	if ((ntohs(eh->ether_type) == ETHERTYPE_IP)) {
2709		sawip = 1;
2710	}
2711
2712	/*
2713	 * filter for ip packets only
2714	*/
2715	if (wi_cache_iponly && !sawip) {
2716		return;
2717	}
2718
2719	/*
2720	 *  filter for broadcast/multicast only
2721	 */
2722	if (wi_cache_mcastonly && ((eh->ether_dhost[0] & 1) == 0)) {
2723		return;
2724	}
2725
2726#ifdef SIGDEBUG
2727	printf("wi%d: q value %x (MSB=0x%x, LSB=0x%x) \n", sc->wi_unit,
2728	    rx_quality & 0xffff, rx_quality >> 8, rx_quality & 0xff);
2729#endif
2730
2731	/*
2732	 *  find the ip header.  we want to store the ip_src
2733	 * address.
2734	 */
2735	if (sawip)
2736		ip = mtod(m, struct ip *);
2737
2738	/*
2739	 * do a linear search for a matching MAC address
2740	 * in the cache table
2741	 * . MAC address is 6 bytes,
2742	 * . var w_nextitem holds total number of entries already cached
2743	 */
2744	for(i = 0; i < sc->wi_nextitem; i++) {
2745		if (! bcmp(eh->ether_shost , sc->wi_sigcache[i].macsrc,  6 )) {
2746			/*
2747			 * Match!,
2748			 * so we already have this entry,
2749			 * update the data
2750			 */
2751			break;
2752		}
2753	}
2754
2755	/*
2756	 *  did we find a matching mac address?
2757	 * if yes, then overwrite a previously existing cache entry
2758	 */
2759	if (i < sc->wi_nextitem )   {
2760		cache_slot = i;
2761	}
2762	/*
2763	 * else, have a new address entry,so
2764	 * add this new entry,
2765	 * if table full, then we need to replace LRU entry
2766	 */
2767	else    {
2768
2769		/*
2770		 * check for space in cache table
2771		 * note: wi_nextitem also holds number of entries
2772		 * added in the cache table
2773		 */
2774		if ( sc->wi_nextitem < MAXWICACHE ) {
2775			cache_slot = sc->wi_nextitem;
2776			sc->wi_nextitem++;
2777			sc->wi_sigitems = sc->wi_nextitem;
2778		}
2779        	/* no space found, so simply wrap with wrap index
2780		 * and "zap" the next entry
2781		 */
2782		else {
2783			if (wrapindex == MAXWICACHE) {
2784				wrapindex = 0;
2785			}
2786			cache_slot = wrapindex++;
2787		}
2788	}
2789
2790	/*
2791	 * invariant: cache_slot now points at some slot
2792	 * in cache.
2793	 */
2794	if (cache_slot < 0 || cache_slot >= MAXWICACHE) {
2795		log(LOG_ERR, "wi_cache_store, bad index: %d of "
2796		    "[0..%d], gross cache error\n",
2797		    cache_slot, MAXWICACHE);
2798		return;
2799	}
2800
2801	/*
2802	 *  store items in cache
2803	 *  .ip source address
2804	 *  .mac src
2805	 *  .signal, etc.
2806	 */
2807	if (sawip)
2808		sc->wi_sigcache[cache_slot].ipsrc = ip->ip_src.s_addr;
2809	bcopy( eh->ether_shost, sc->wi_sigcache[cache_slot].macsrc,  6);
2810
2811	sig = (rx_quality >> 8) & 0xFF;
2812	noise = rx_quality & 0xFF;
2813
2814	/*
2815	 * -149 is Lucent specific to convert to dBm.  Prism2 cards do
2816	 * things differently, sometimes don't have a noise measurement,
2817	 * and is firmware dependent :-(
2818	 */
2819	sc->wi_sigcache[cache_slot].signal = sig - 149;
2820	sc->wi_sigcache[cache_slot].noise = noise - 149;
2821	sc->wi_sigcache[cache_slot].quality = sig - noise;
2822
2823	return;
2824}
2825#endif
2826
2827static int
2828wi_get_cur_ssid(sc, ssid, len)
2829	struct wi_softc		*sc;
2830	char			*ssid;
2831	int			*len;
2832{
2833	int			error = 0;
2834	struct wi_req		wreq;
2835
2836	wreq.wi_len = WI_MAX_DATALEN;
2837	switch (sc->wi_ptype) {
2838	case WI_PORTTYPE_HOSTAP:
2839		*len = IEEE80211_NWID_LEN;
2840		bcopy(sc->wi_net_name, ssid, IEEE80211_NWID_LEN);
2841		break;
2842	case WI_PORTTYPE_IBSS:
2843	case WI_PORTTYPE_ADHOC:
2844		wreq.wi_type = WI_RID_CURRENT_SSID;
2845		error = wi_read_record(sc, (struct wi_ltv_gen *)&wreq);
2846		if (error != 0)
2847			break;
2848		if (wreq.wi_val[0] > IEEE80211_NWID_LEN) {
2849			error = EINVAL;
2850			break;
2851		}
2852		*len = wreq.wi_val[0];
2853		bcopy(&wreq.wi_val[1], ssid, IEEE80211_NWID_LEN);
2854		break;
2855	case WI_PORTTYPE_BSS:
2856		wreq.wi_type = WI_RID_COMMQUAL;
2857		error = wi_read_record(sc, (struct wi_ltv_gen *)&wreq);
2858		if (error != 0)
2859			break;
2860		if (wreq.wi_val[0] != 0) /* associated */ {
2861			wreq.wi_type = WI_RID_CURRENT_SSID;
2862			wreq.wi_len = WI_MAX_DATALEN;
2863			error = wi_read_record(sc, (struct wi_ltv_gen *)&wreq);
2864			if (error != 0)
2865				break;
2866			if (wreq.wi_val[0] > IEEE80211_NWID_LEN) {
2867				error = EINVAL;
2868				break;
2869			}
2870			*len = wreq.wi_val[0];
2871			bcopy(&wreq.wi_val[1], ssid, IEEE80211_NWID_LEN);
2872		} else {
2873			*len = IEEE80211_NWID_LEN;
2874			bcopy(sc->wi_net_name, ssid, IEEE80211_NWID_LEN);
2875		}
2876		break;
2877	default:
2878		error = EINVAL;
2879		break;
2880	}
2881
2882	return error;
2883}
2884
2885static int
2886wi_media_change(ifp)
2887	struct ifnet		*ifp;
2888{
2889	struct wi_softc		*sc = ifp->if_softc;
2890	int			otype = sc->wi_ptype;
2891	int			orate = sc->wi_tx_rate;
2892	int			ocreate_ibss = sc->wi_create_ibss;
2893
2894	if ((sc->ifmedia.ifm_cur->ifm_media & IFM_IEEE80211_HOSTAP) &&
2895	    sc->sc_firmware_type != WI_INTERSIL)
2896		return (EINVAL);
2897
2898	sc->wi_create_ibss = 0;
2899
2900	switch (sc->ifmedia.ifm_cur->ifm_media & IFM_OMASK) {
2901	case 0:
2902		sc->wi_ptype = WI_PORTTYPE_BSS;
2903		break;
2904	case IFM_IEEE80211_ADHOC:
2905		sc->wi_ptype = WI_PORTTYPE_ADHOC;
2906		break;
2907	case IFM_IEEE80211_HOSTAP:
2908		sc->wi_ptype = WI_PORTTYPE_HOSTAP;
2909		break;
2910	case IFM_IEEE80211_IBSSMASTER:
2911	case IFM_IEEE80211_IBSSMASTER|IFM_IEEE80211_IBSS:
2912		if (!(sc->wi_flags & WI_FLAGS_HAS_CREATE_IBSS))
2913			return (EINVAL);
2914		sc->wi_create_ibss = 1;
2915		/* FALLTHROUGH */
2916	case IFM_IEEE80211_IBSS:
2917		sc->wi_ptype = WI_PORTTYPE_IBSS;
2918		break;
2919	default:
2920		/* Invalid combination. */
2921		return (EINVAL);
2922	}
2923
2924	switch (IFM_SUBTYPE(sc->ifmedia.ifm_cur->ifm_media)) {
2925	case IFM_IEEE80211_DS1:
2926		sc->wi_tx_rate = 1;
2927		break;
2928	case IFM_IEEE80211_DS2:
2929		sc->wi_tx_rate = 2;
2930		break;
2931	case IFM_IEEE80211_DS5:
2932		sc->wi_tx_rate = 5;
2933		break;
2934	case IFM_IEEE80211_DS11:
2935		sc->wi_tx_rate = 11;
2936		break;
2937	case IFM_AUTO:
2938		sc->wi_tx_rate = 3;
2939		break;
2940	}
2941
2942	if (ocreate_ibss != sc->wi_create_ibss || otype != sc->wi_ptype ||
2943	    orate != sc->wi_tx_rate)
2944		wi_init(sc);
2945
2946	return(0);
2947}
2948
2949static void
2950wi_media_status(ifp, imr)
2951	struct ifnet		*ifp;
2952	struct ifmediareq	*imr;
2953{
2954	struct wi_req		wreq;
2955	struct wi_softc		*sc = ifp->if_softc;
2956
2957	if (sc->wi_tx_rate == 3) {
2958		imr->ifm_active = IFM_IEEE80211|IFM_AUTO;
2959		if (sc->wi_ptype == WI_PORTTYPE_ADHOC)
2960			imr->ifm_active |= IFM_IEEE80211_ADHOC;
2961		else if (sc->wi_ptype == WI_PORTTYPE_HOSTAP)
2962			imr->ifm_active |= IFM_IEEE80211_HOSTAP;
2963		else if (sc->wi_ptype == WI_PORTTYPE_IBSS) {
2964			if (sc->wi_create_ibss)
2965				imr->ifm_active |= IFM_IEEE80211_IBSSMASTER;
2966			else
2967				imr->ifm_active |= IFM_IEEE80211_IBSS;
2968		}
2969		wreq.wi_type = WI_RID_CUR_TX_RATE;
2970		wreq.wi_len = WI_MAX_DATALEN;
2971		if (wi_read_record(sc, (struct wi_ltv_gen *)&wreq) == 0) {
2972			switch(wreq.wi_val[0]) {
2973			case 1:
2974				imr->ifm_active |= IFM_IEEE80211_DS1;
2975				break;
2976			case 2:
2977				imr->ifm_active |= IFM_IEEE80211_DS2;
2978				break;
2979			case 6:
2980				imr->ifm_active |= IFM_IEEE80211_DS5;
2981				break;
2982			case 11:
2983				imr->ifm_active |= IFM_IEEE80211_DS11;
2984				break;
2985				}
2986		}
2987	} else {
2988		imr->ifm_active = sc->ifmedia.ifm_cur->ifm_media;
2989	}
2990
2991	imr->ifm_status = IFM_AVALID;
2992	if (sc->wi_ptype == WI_PORTTYPE_ADHOC ||
2993	    sc->wi_ptype == WI_PORTTYPE_IBSS)
2994		/*
2995		 * XXX: It would be nice if we could give some actually
2996		 * useful status like whether we joined another IBSS or
2997		 * created one ourselves.
2998		 */
2999		imr->ifm_status |= IFM_ACTIVE;
3000	else if (sc->wi_ptype == WI_PORTTYPE_HOSTAP)
3001		imr->ifm_status |= IFM_ACTIVE;
3002	else {
3003		wreq.wi_type = WI_RID_COMMQUAL;
3004		wreq.wi_len = WI_MAX_DATALEN;
3005		if (wi_read_record(sc, (struct wi_ltv_gen *)&wreq) == 0 &&
3006		    wreq.wi_val[0] != 0)
3007			imr->ifm_status |= IFM_ACTIVE;
3008	}
3009}
3010
3011static int
3012wi_get_debug(sc, wreq)
3013	struct wi_softc		*sc;
3014	struct wi_req		*wreq;
3015{
3016	int			error = 0;
3017
3018	wreq->wi_len = 1;
3019
3020	switch (wreq->wi_type) {
3021	case WI_DEBUG_SLEEP:
3022		wreq->wi_len++;
3023		wreq->wi_val[0] = sc->wi_debug.wi_sleep;
3024		break;
3025	case WI_DEBUG_DELAYSUPP:
3026		wreq->wi_len++;
3027		wreq->wi_val[0] = sc->wi_debug.wi_delaysupp;
3028		break;
3029	case WI_DEBUG_TXSUPP:
3030		wreq->wi_len++;
3031		wreq->wi_val[0] = sc->wi_debug.wi_txsupp;
3032		break;
3033	case WI_DEBUG_MONITOR:
3034		wreq->wi_len++;
3035		wreq->wi_val[0] = sc->wi_debug.wi_monitor;
3036		break;
3037	case WI_DEBUG_LEDTEST:
3038		wreq->wi_len += 3;
3039		wreq->wi_val[0] = sc->wi_debug.wi_ledtest;
3040		wreq->wi_val[1] = sc->wi_debug.wi_ledtest_param0;
3041		wreq->wi_val[2] = sc->wi_debug.wi_ledtest_param1;
3042		break;
3043	case WI_DEBUG_CONTTX:
3044		wreq->wi_len += 2;
3045		wreq->wi_val[0] = sc->wi_debug.wi_conttx;
3046		wreq->wi_val[1] = sc->wi_debug.wi_conttx_param0;
3047		break;
3048	case WI_DEBUG_CONTRX:
3049		wreq->wi_len++;
3050		wreq->wi_val[0] = sc->wi_debug.wi_contrx;
3051		break;
3052	case WI_DEBUG_SIGSTATE:
3053		wreq->wi_len += 2;
3054		wreq->wi_val[0] = sc->wi_debug.wi_sigstate;
3055		wreq->wi_val[1] = sc->wi_debug.wi_sigstate_param0;
3056		break;
3057	case WI_DEBUG_CONFBITS:
3058		wreq->wi_len += 2;
3059		wreq->wi_val[0] = sc->wi_debug.wi_confbits;
3060		wreq->wi_val[1] = sc->wi_debug.wi_confbits_param0;
3061		break;
3062	default:
3063		error = EIO;
3064		break;
3065	}
3066
3067	return (error);
3068}
3069
3070static int
3071wi_set_debug(sc, wreq)
3072	struct wi_softc		*sc;
3073	struct wi_req		*wreq;
3074{
3075	int			error = 0;
3076	u_int16_t		cmd, param0 = 0, param1 = 0;
3077
3078	switch (wreq->wi_type) {
3079	case WI_DEBUG_RESET:
3080	case WI_DEBUG_INIT:
3081	case WI_DEBUG_CALENABLE:
3082		break;
3083	case WI_DEBUG_SLEEP:
3084		sc->wi_debug.wi_sleep = 1;
3085		break;
3086	case WI_DEBUG_WAKE:
3087		sc->wi_debug.wi_sleep = 0;
3088		break;
3089	case WI_DEBUG_CHAN:
3090		param0 = wreq->wi_val[0];
3091		break;
3092	case WI_DEBUG_DELAYSUPP:
3093		sc->wi_debug.wi_delaysupp = 1;
3094		break;
3095	case WI_DEBUG_TXSUPP:
3096		sc->wi_debug.wi_txsupp = 1;
3097		break;
3098	case WI_DEBUG_MONITOR:
3099		sc->wi_debug.wi_monitor = 1;
3100		break;
3101	case WI_DEBUG_LEDTEST:
3102		param0 = wreq->wi_val[0];
3103		param1 = wreq->wi_val[1];
3104		sc->wi_debug.wi_ledtest = 1;
3105		sc->wi_debug.wi_ledtest_param0 = param0;
3106		sc->wi_debug.wi_ledtest_param1 = param1;
3107		break;
3108	case WI_DEBUG_CONTTX:
3109		param0 = wreq->wi_val[0];
3110		sc->wi_debug.wi_conttx = 1;
3111		sc->wi_debug.wi_conttx_param0 = param0;
3112		break;
3113	case WI_DEBUG_STOPTEST:
3114		sc->wi_debug.wi_delaysupp = 0;
3115		sc->wi_debug.wi_txsupp = 0;
3116		sc->wi_debug.wi_monitor = 0;
3117		sc->wi_debug.wi_ledtest = 0;
3118		sc->wi_debug.wi_ledtest_param0 = 0;
3119		sc->wi_debug.wi_ledtest_param1 = 0;
3120		sc->wi_debug.wi_conttx = 0;
3121		sc->wi_debug.wi_conttx_param0 = 0;
3122		sc->wi_debug.wi_contrx = 0;
3123		sc->wi_debug.wi_sigstate = 0;
3124		sc->wi_debug.wi_sigstate_param0 = 0;
3125		break;
3126	case WI_DEBUG_CONTRX:
3127		sc->wi_debug.wi_contrx = 1;
3128		break;
3129	case WI_DEBUG_SIGSTATE:
3130		param0 = wreq->wi_val[0];
3131		sc->wi_debug.wi_sigstate = 1;
3132		sc->wi_debug.wi_sigstate_param0 = param0;
3133		break;
3134	case WI_DEBUG_CONFBITS:
3135		param0 = wreq->wi_val[0];
3136		param1 = wreq->wi_val[1];
3137		sc->wi_debug.wi_confbits = param0;
3138		sc->wi_debug.wi_confbits_param0 = param1;
3139		break;
3140	default:
3141		error = EIO;
3142		break;
3143	}
3144
3145	if (error)
3146		return (error);
3147
3148	cmd = WI_CMD_DEBUG | (wreq->wi_type << 8);
3149	error = wi_cmd(sc, cmd, param0, param1, 0);
3150
3151	return (error);
3152}
3153
3154#if __FreeBSD_version >= 500000
3155/*
3156 * Special routines to download firmware for Symbol CF card.
3157 * XXX: This should be modified generic into any PRISM-2 based card.
3158 */
3159
3160#define	WI_SBCF_PDIADDR		0x3100
3161
3162/* unaligned load little endian */
3163#define	GETLE32(p)	((p)[0] | ((p)[1]<<8) | ((p)[2]<<16) | ((p)[3]<<24))
3164#define	GETLE16(p)	((p)[0] | ((p)[1]<<8))
3165
3166int
3167wi_symbol_load_firm(struct wi_softc *sc, const void *primsym, int primlen,
3168    const void *secsym, int seclen)
3169{
3170	uint8_t ebuf[256];
3171	int i;
3172
3173	/* load primary code and run it */
3174	wi_symbol_set_hcr(sc, WI_HCR_EEHOLD);
3175	if (wi_symbol_write_firm(sc, primsym, primlen, NULL, 0))
3176		return EIO;
3177	wi_symbol_set_hcr(sc, WI_HCR_RUN);
3178	for (i = 0; ; i++) {
3179		if (i == 10)
3180			return ETIMEDOUT;
3181		tsleep(sc, PWAIT, "wiinit", 1);
3182		if (CSR_READ_2(sc, WI_CNTL) == WI_CNTL_AUX_ENA_STAT)
3183			break;
3184		/* write the magic key value to unlock aux port */
3185		CSR_WRITE_2(sc, WI_PARAM0, WI_AUX_KEY0);
3186		CSR_WRITE_2(sc, WI_PARAM1, WI_AUX_KEY1);
3187		CSR_WRITE_2(sc, WI_PARAM2, WI_AUX_KEY2);
3188		CSR_WRITE_2(sc, WI_CNTL, WI_CNTL_AUX_ENA_CNTL);
3189	}
3190
3191	/* issue read EEPROM command: XXX copied from wi_cmd() */
3192	CSR_WRITE_2(sc, WI_PARAM0, 0);
3193	CSR_WRITE_2(sc, WI_PARAM1, 0);
3194	CSR_WRITE_2(sc, WI_PARAM2, 0);
3195	CSR_WRITE_2(sc, WI_COMMAND, WI_CMD_READEE);
3196        for (i = 0; i < WI_TIMEOUT; i++) {
3197                if (CSR_READ_2(sc, WI_EVENT_STAT) & WI_EV_CMD)
3198                        break;
3199                DELAY(1);
3200        }
3201        CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_CMD);
3202
3203	CSR_WRITE_2(sc, WI_AUX_PAGE, WI_SBCF_PDIADDR / WI_AUX_PGSZ);
3204	CSR_WRITE_2(sc, WI_AUX_OFFSET, WI_SBCF_PDIADDR % WI_AUX_PGSZ);
3205	CSR_READ_MULTI_STREAM_2(sc, WI_AUX_DATA,
3206	    (uint16_t *)ebuf, sizeof(ebuf) / 2);
3207	if (GETLE16(ebuf) > sizeof(ebuf))
3208		return EIO;
3209	if (wi_symbol_write_firm(sc, secsym, seclen, ebuf + 4, GETLE16(ebuf)))
3210		return EIO;
3211	return 0;
3212}
3213
3214static int
3215wi_symbol_write_firm(struct wi_softc *sc, const void *buf, int buflen,
3216    const void *ebuf, int ebuflen)
3217{
3218	const uint8_t *p, *ep, *q, *eq;
3219	char *tp;
3220	uint32_t addr, id, eid;
3221	int i, len, elen, nblk, pdrlen;
3222
3223	/*
3224	 * Parse the header of the firmware image.
3225	 */
3226	p = buf;
3227	ep = p + buflen;
3228	while (p < ep && *p++ != ' ');	/* FILE: */
3229	while (p < ep && *p++ != ' ');	/* filename */
3230	while (p < ep && *p++ != ' ');	/* type of the firmware */
3231	nblk = strtoul(p, &tp, 10);
3232	p = tp;
3233	pdrlen = strtoul(p + 1, &tp, 10);
3234	p = tp;
3235	while (p < ep && *p++ != 0x1a);	/* skip rest of header */
3236
3237	/*
3238	 * Block records: address[4], length[2], data[length];
3239	 */
3240	for (i = 0; i < nblk; i++) {
3241		addr = GETLE32(p);	p += 4;
3242		len  = GETLE16(p);	p += 2;
3243		CSR_WRITE_2(sc, WI_AUX_PAGE, addr / WI_AUX_PGSZ);
3244		CSR_WRITE_2(sc, WI_AUX_OFFSET, addr % WI_AUX_PGSZ);
3245		CSR_WRITE_MULTI_STREAM_2(sc, WI_AUX_DATA,
3246		    (const uint16_t *)p, len / 2);
3247		p += len;
3248	}
3249
3250	/*
3251	 * PDR: id[4], address[4], length[4];
3252	 */
3253	for (i = 0; i < pdrlen; ) {
3254		id   = GETLE32(p);	p += 4; i += 4;
3255		addr = GETLE32(p);	p += 4; i += 4;
3256		len  = GETLE32(p);	p += 4; i += 4;
3257		/* replace PDR entry with the values from EEPROM, if any */
3258		for (q = ebuf, eq = q + ebuflen; q < eq; q += elen * 2) {
3259			elen = GETLE16(q);	q += 2;
3260			eid  = GETLE16(q);	q += 2;
3261			elen--;		/* elen includes eid */
3262			if (eid == 0)
3263				break;
3264			if (eid != id)
3265				continue;
3266			CSR_WRITE_2(sc, WI_AUX_PAGE, addr / WI_AUX_PGSZ);
3267			CSR_WRITE_2(sc, WI_AUX_OFFSET, addr % WI_AUX_PGSZ);
3268			CSR_WRITE_MULTI_STREAM_2(sc, WI_AUX_DATA,
3269			    (const uint16_t *)q, len / 2);
3270			break;
3271		}
3272	}
3273	return 0;
3274}
3275
3276static int
3277wi_symbol_set_hcr(struct wi_softc *sc, int mode)
3278{
3279	uint16_t hcr;
3280
3281	CSR_WRITE_2(sc, WI_COR, WI_COR_RESET);
3282	tsleep(sc, PWAIT, "wiinit", 1);
3283	hcr = CSR_READ_2(sc, WI_HCR);
3284	hcr = (hcr & WI_HCR_4WIRE) | (mode & ~WI_HCR_4WIRE);
3285	CSR_WRITE_2(sc, WI_HCR, hcr);
3286	tsleep(sc, PWAIT, "wiinit", 1);
3287	CSR_WRITE_2(sc, WI_COR, WI_COR_IOMODE);
3288	tsleep(sc, PWAIT, "wiinit", 1);
3289	return 0;
3290}
3291#endif
3292