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