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