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