if_wi.c revision 59391
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 * $FreeBSD: head/sys/dev/wi/if_wi.c 59391 2000-04-19 14:58:28Z phk $
33 */
34
35/*
36 * Lucent WaveLAN/IEEE 802.11 PCMCIA driver for FreeBSD.
37 *
38 * Written by Bill Paul <wpaul@ctr.columbia.edu>
39 * Electrical Engineering Department
40 * Columbia University, New York City
41 */
42
43/*
44 * The WaveLAN/IEEE adapter is the second generation of the WaveLAN
45 * from Lucent. Unlike the older cards, the new ones are programmed
46 * entirely via a firmware-driven controller called the Hermes.
47 * Unfortunately, Lucent will not release the Hermes programming manual
48 * without an NDA (if at all). What they do release is an API library
49 * called the HCF (Hardware Control Functions) which is supposed to
50 * do the device-specific operations of a device driver for you. The
51 * publically available version of the HCF library (the 'HCF Light') is
52 * a) extremely gross, b) lacks certain features, particularly support
53 * for 802.11 frames, and c) is contaminated by the GNU Public License.
54 *
55 * This driver does not use the HCF or HCF Light at all. Instead, it
56 * programs the Hermes controller directly, using information gleaned
57 * from the HCF Light code and corresponding documentation.
58 *
59 * This driver supports both the PCMCIA and ISA versions of the
60 * WaveLAN/IEEE cards. Note however that the ISA card isn't really
61 * anything of the sort: it's actually a PCMCIA bridge adapter
62 * that fits into an ISA slot, into which a PCMCIA WaveLAN card is
63 * inserted. Consequently, you need to use the pccard support for
64 * both the ISA and PCMCIA adapters.
65 */
66
67#define WI_HERMES_AUTOINC_WAR	/* Work around data write autoinc bug. */
68#define WI_HERMES_STATS_WAR	/* Work around stats counter bug. */
69#define WICACHE			/* turn on signal strength cache code */
70
71#include <sys/param.h>
72#include <sys/systm.h>
73#include <sys/sockio.h>
74#include <sys/mbuf.h>
75#include <sys/kernel.h>
76#include <sys/socket.h>
77#include <sys/module.h>
78#include <sys/bus.h>
79#include <sys/syslog.h>
80#include <sys/sysctl.h>
81
82#include <machine/bus.h>
83#include <machine/resource.h>
84#include <machine/clock.h>
85#include <machine/md_var.h>
86#include <machine/bus_pio.h>
87#include <sys/rman.h>
88
89#include <net/if.h>
90#include <net/if_arp.h>
91#include <net/ethernet.h>
92#include <net/if_dl.h>
93#include <net/if_media.h>
94#include <net/if_types.h>
95
96#include <netinet/in.h>
97#include <netinet/in_systm.h>
98#include <netinet/in_var.h>
99#include <netinet/ip.h>
100#include <netinet/if_ether.h>
101
102#include <net/bpf.h>
103
104#include <machine/if_wavelan_ieee.h>
105#include <i386/isa/if_wireg.h>
106
107#if !defined(lint)
108static const char rcsid[] =
109  "$FreeBSD: head/sys/dev/wi/if_wi.c 59391 2000-04-19 14:58:28Z phk $";
110#endif
111
112#ifdef foo
113static u_int8_t	wi_mcast_addr[6] = { 0x01, 0x60, 0x1D, 0x00, 0x01, 0x00 };
114#endif
115
116static void wi_intr		__P((void *));
117static void wi_reset		__P((struct wi_softc *));
118static int wi_ioctl		__P((struct ifnet *, u_long, caddr_t));
119static void wi_init		__P((void *));
120static void wi_start		__P((struct ifnet *));
121static void wi_stop		__P((struct wi_softc *));
122static void wi_watchdog		__P((struct ifnet *));
123static void wi_rxeof		__P((struct wi_softc *));
124static void wi_txeof		__P((struct wi_softc *, int));
125static void wi_update_stats	__P((struct wi_softc *));
126static void wi_setmulti		__P((struct wi_softc *));
127
128static int wi_cmd		__P((struct wi_softc *, int, int));
129static int wi_read_record	__P((struct wi_softc *, struct wi_ltv_gen *));
130static int wi_write_record	__P((struct wi_softc *, struct wi_ltv_gen *));
131static int wi_read_data		__P((struct wi_softc *, int,
132					int, caddr_t, int));
133static int wi_write_data	__P((struct wi_softc *, int,
134					int, caddr_t, int));
135static int wi_seek		__P((struct wi_softc *, int, int, int));
136static int wi_alloc_nicmem	__P((struct wi_softc *, int, int *));
137static void wi_inquire		__P((void *));
138static void wi_setdef		__P((struct wi_softc *, struct wi_req *));
139static int wi_mgmt_xmit		__P((struct wi_softc *, caddr_t, int));
140
141#ifdef WICACHE
142static
143void wi_cache_store __P((struct wi_softc *, struct ether_header *,
144	struct mbuf *, unsigned short));
145#endif
146
147static int wi_pccard_probe	__P((device_t));
148static int wi_pccard_attach	__P((device_t));
149static int wi_pccard_detach	__P((device_t));
150static void wi_shutdown		__P((device_t));
151
152static int wi_alloc		__P((device_t));
153static void wi_free		__P((device_t));
154
155static device_method_t wi_pccard_methods[] = {
156	/* Device interface */
157	DEVMETHOD(device_probe,		wi_pccard_probe),
158	DEVMETHOD(device_attach,	wi_pccard_attach),
159	DEVMETHOD(device_detach,	wi_pccard_detach),
160	DEVMETHOD(device_shutdown,	wi_shutdown),
161
162	{ 0, 0 }
163};
164
165static driver_t wi_pccard_driver = {
166	"wi",
167	wi_pccard_methods,
168	sizeof(struct wi_softc)
169};
170
171static devclass_t wi_pccard_devclass;
172
173DRIVER_MODULE(if_wi, pccard, wi_pccard_driver, wi_pccard_devclass, 0, 0);
174
175static int wi_pccard_probe(dev)
176	device_t	dev;
177{
178	struct wi_softc	*sc;
179	int		error;
180
181	sc = device_get_softc(dev);
182	sc->wi_gone = 0;
183
184	error = wi_alloc(dev);
185	if (error)
186		return (error);
187
188	device_set_desc(dev, "WaveLAN/IEEE 802.11");
189	wi_free(dev);
190
191	/* Make sure interrupts are disabled. */
192	CSR_WRITE_2(sc, WI_INT_EN, 0);
193	CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF);
194
195	return (0);
196}
197
198static int wi_pccard_detach(dev)
199	device_t		dev;
200{
201	struct wi_softc		*sc;
202	struct ifnet		*ifp;
203	int			s;
204
205	s = splimp();
206
207	sc = device_get_softc(dev);
208	ifp = &sc->arpcom.ac_if;
209
210	if (sc->wi_gone) {
211		device_printf(dev, "already unloaded\n");
212		return(ENODEV);
213	}
214
215	wi_stop(sc);
216
217	bpfdetach(ifp);
218	if_detach(ifp);
219	bus_teardown_intr(dev, sc->irq, sc->wi_intrhand);
220	wi_free(dev);
221	sc->wi_gone = 1;
222
223	splx(s);
224	device_printf(dev, "unload\n");
225
226	return(0);
227}
228
229static int wi_pccard_attach(device_t dev)
230{
231	struct wi_softc		*sc;
232	struct wi_ltv_macaddr	mac;
233	struct wi_ltv_gen	gen;
234	struct ifnet		*ifp;
235	int			error;
236
237	sc = device_get_softc(dev);
238	ifp = &sc->arpcom.ac_if;
239
240	error = wi_alloc(dev);
241	if (error) {
242		device_printf(dev, "wi_alloc() failed! (%d)\n", error);
243		return (error);
244	}
245
246	error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET,
247			       wi_intr, sc, &sc->wi_intrhand);
248
249	if (error) {
250		device_printf(dev, "bus_setup_intr() failed! (%d)\n", error);
251		wi_free(dev);
252		return (error);
253	}
254
255	/* Reset the NIC. */
256	wi_reset(sc);
257
258	/* Read the station address. */
259	mac.wi_type = WI_RID_MAC_NODE;
260	mac.wi_len = 4;
261	wi_read_record(sc, (struct wi_ltv_gen *)&mac);
262	bcopy((char *)&mac.wi_mac_addr,
263	   (char *)&sc->arpcom.ac_enaddr, ETHER_ADDR_LEN);
264
265	device_printf(dev, "Ethernet address: %6D\n",
266	    sc->arpcom.ac_enaddr, ":");
267
268	ifp->if_softc = sc;
269	ifp->if_unit = sc->wi_unit;
270	ifp->if_name = "wi";
271	ifp->if_mtu = ETHERMTU;
272	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
273	ifp->if_ioctl = wi_ioctl;
274	ifp->if_output = ether_output;
275	ifp->if_start = wi_start;
276	ifp->if_watchdog = wi_watchdog;
277	ifp->if_init = wi_init;
278	ifp->if_baudrate = 10000000;
279	ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
280
281	bzero(sc->wi_node_name, sizeof(sc->wi_node_name));
282	bcopy(WI_DEFAULT_NODENAME, sc->wi_node_name,
283	    sizeof(WI_DEFAULT_NODENAME) - 1);
284
285	bzero(sc->wi_net_name, sizeof(sc->wi_net_name));
286	bcopy(WI_DEFAULT_NETNAME, sc->wi_net_name,
287	    sizeof(WI_DEFAULT_NETNAME) - 1);
288
289	bzero(sc->wi_ibss_name, sizeof(sc->wi_ibss_name));
290	bcopy(WI_DEFAULT_IBSS, sc->wi_ibss_name,
291	    sizeof(WI_DEFAULT_IBSS) - 1);
292
293	sc->wi_portnum = WI_DEFAULT_PORT;
294	sc->wi_ptype = WI_PORTTYPE_ADHOC;
295	sc->wi_ap_density = WI_DEFAULT_AP_DENSITY;
296	sc->wi_rts_thresh = WI_DEFAULT_RTS_THRESH;
297	sc->wi_tx_rate = WI_DEFAULT_TX_RATE;
298	sc->wi_max_data_len = WI_DEFAULT_DATALEN;
299	sc->wi_create_ibss = WI_DEFAULT_CREATE_IBSS;
300	sc->wi_pm_enabled = WI_DEFAULT_PM_ENABLED;
301	sc->wi_max_sleep = WI_DEFAULT_MAX_SLEEP;
302
303	/*
304	 * Read the default channel from the NIC. This may vary
305	 * depending on the country where the NIC was purchased, so
306	 * we can't hard-code a default and expect it to work for
307	 * everyone.
308	 */
309	gen.wi_type = WI_RID_OWN_CHNL;
310	gen.wi_len = 2;
311	wi_read_record(sc, &gen);
312	sc->wi_channel = gen.wi_val;
313
314	/*
315	 * Find out if we support WEP on this card.
316	 */
317	gen.wi_type = WI_RID_WEP_AVAIL;
318	gen.wi_len = 2;
319	wi_read_record(sc, &gen);
320	sc->wi_has_wep = gen.wi_val;
321
322	bzero((char *)&sc->wi_stats, sizeof(sc->wi_stats));
323
324	wi_init(sc);
325	wi_stop(sc);
326
327	/*
328	 * Call MI attach routines.
329	 */
330	if_attach(ifp);
331	ether_ifattach(ifp);
332	callout_handle_init(&sc->wi_stat_ch);
333	bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header));
334
335	return(0);
336}
337
338static void wi_rxeof(sc)
339	struct wi_softc		*sc;
340{
341	struct ifnet		*ifp;
342	struct ether_header	*eh;
343	struct wi_frame		rx_frame;
344	struct mbuf		*m;
345	int			id;
346
347	ifp = &sc->arpcom.ac_if;
348
349	id = CSR_READ_2(sc, WI_RX_FID);
350
351	/* First read in the frame header */
352	if (wi_read_data(sc, id, 0, (caddr_t)&rx_frame, sizeof(rx_frame))) {
353		ifp->if_ierrors++;
354		return;
355	}
356
357	if (rx_frame.wi_status & WI_STAT_ERRSTAT) {
358		ifp->if_ierrors++;
359		return;
360	}
361
362	MGETHDR(m, M_DONTWAIT, MT_DATA);
363	if (m == NULL) {
364		ifp->if_ierrors++;
365		return;
366	}
367	MCLGET(m, M_DONTWAIT);
368	if (!(m->m_flags & M_EXT)) {
369		m_freem(m);
370		ifp->if_ierrors++;
371		return;
372	}
373
374	eh = mtod(m, struct ether_header *);
375	m->m_pkthdr.rcvif = ifp;
376
377	if (rx_frame.wi_status == WI_STAT_1042 ||
378	    rx_frame.wi_status == WI_STAT_TUNNEL ||
379	    rx_frame.wi_status == WI_STAT_WMP_MSG) {
380		if((rx_frame.wi_dat_len + WI_SNAPHDR_LEN) > MCLBYTES) {
381			device_printf(sc->dev, "oversized packet received "
382			    "(wi_dat_len=%d, wi_status=0x%x)\n",
383			    rx_frame.wi_dat_len, rx_frame.wi_status);
384			m_freem(m);
385			ifp->if_ierrors++;
386			return;
387		}
388		m->m_pkthdr.len = m->m_len =
389		    rx_frame.wi_dat_len + WI_SNAPHDR_LEN;
390
391		bcopy((char *)&rx_frame.wi_addr1,
392		    (char *)&eh->ether_dhost, ETHER_ADDR_LEN);
393		if (sc->wi_ptype == WI_PORTTYPE_ADHOC) {
394			bcopy((char *)&rx_frame.wi_addr2,
395			    (char *)&eh->ether_shost, ETHER_ADDR_LEN);
396		} else {
397			bcopy((char *)&rx_frame.wi_addr3,
398			    (char *)&eh->ether_shost, ETHER_ADDR_LEN);
399		}
400		bcopy((char *)&rx_frame.wi_type,
401		    (char *)&eh->ether_type, sizeof(u_int16_t));
402
403		if (wi_read_data(sc, id, WI_802_11_OFFSET,
404		    mtod(m, caddr_t) + sizeof(struct ether_header),
405		    m->m_len + 2)) {
406			m_freem(m);
407			ifp->if_ierrors++;
408			return;
409		}
410	} else {
411		if((rx_frame.wi_dat_len +
412		    sizeof(struct ether_header)) > MCLBYTES) {
413			device_printf(sc->dev, "oversized packet received "
414			    "(wi_dat_len=%d, wi_status=0x%x)\n",
415			    rx_frame.wi_dat_len, rx_frame.wi_status);
416			m_freem(m);
417			ifp->if_ierrors++;
418			return;
419		}
420		m->m_pkthdr.len = m->m_len =
421		    rx_frame.wi_dat_len + sizeof(struct ether_header);
422
423		if (wi_read_data(sc, id, WI_802_3_OFFSET,
424		    mtod(m, caddr_t), m->m_len + 2)) {
425			m_freem(m);
426			ifp->if_ierrors++;
427			return;
428		}
429	}
430
431	ifp->if_ipackets++;
432
433	/* Handle BPF listeners. */
434	if (ifp->if_bpf) {
435		bpf_mtap(ifp, m);
436		if (ifp->if_flags & IFF_PROMISC &&
437		    (bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr,
438		    ETHER_ADDR_LEN) && (eh->ether_dhost[0] & 1) == 0)) {
439			m_freem(m);
440			return;
441		}
442	}
443
444	/* Receive packet. */
445	m_adj(m, sizeof(struct ether_header));
446#ifdef WICACHE
447	wi_cache_store(sc, eh, m, rx_frame.wi_q_info);
448#endif
449	ether_input(ifp, eh, m);
450
451	return;
452}
453
454static void wi_txeof(sc, status)
455	struct wi_softc		*sc;
456	int			status;
457{
458	struct ifnet		*ifp;
459
460	ifp = &sc->arpcom.ac_if;
461
462	ifp->if_timer = 0;
463	ifp->if_flags &= ~IFF_OACTIVE;
464
465	if (status & WI_EV_TX_EXC)
466		ifp->if_oerrors++;
467	else
468		ifp->if_opackets++;
469
470	return;
471}
472
473void wi_inquire(xsc)
474	void			*xsc;
475{
476	struct wi_softc		*sc;
477	struct ifnet		*ifp;
478
479	sc = xsc;
480	ifp = &sc->arpcom.ac_if;
481
482	sc->wi_stat_ch = timeout(wi_inquire, sc, hz * 60);
483
484	/* Don't do this while we're transmitting */
485	if (ifp->if_flags & IFF_OACTIVE)
486		return;
487
488	wi_cmd(sc, WI_CMD_INQUIRE, WI_INFO_COUNTERS);
489
490	return;
491}
492
493void wi_update_stats(sc)
494	struct wi_softc		*sc;
495{
496	struct wi_ltv_gen	gen;
497	u_int16_t		id;
498	struct ifnet		*ifp;
499	u_int32_t		*ptr;
500	int			i;
501	u_int16_t		t;
502
503	ifp = &sc->arpcom.ac_if;
504
505	id = CSR_READ_2(sc, WI_INFO_FID);
506
507	wi_read_data(sc, id, 0, (char *)&gen, 4);
508
509	if (gen.wi_type != WI_INFO_COUNTERS ||
510	    gen.wi_len > (sizeof(sc->wi_stats) / 4) + 1)
511		return;
512
513	ptr = (u_int32_t *)&sc->wi_stats;
514
515	for (i = 0; i < gen.wi_len - 1; i++) {
516		t = CSR_READ_2(sc, WI_DATA1);
517#ifdef WI_HERMES_STATS_WAR
518		if (t > 0xF000)
519			t = ~t & 0xFFFF;
520#endif
521		ptr[i] += t;
522	}
523
524	ifp->if_collisions = sc->wi_stats.wi_tx_single_retries +
525	    sc->wi_stats.wi_tx_multi_retries +
526	    sc->wi_stats.wi_tx_retry_limit;
527
528	return;
529}
530
531static void wi_intr(xsc)
532	void		*xsc;
533{
534	struct wi_softc		*sc = xsc;
535	struct ifnet		*ifp;
536	u_int16_t		status;
537
538	ifp = &sc->arpcom.ac_if;
539
540	if (!(ifp->if_flags & IFF_UP)) {
541		CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF);
542		CSR_WRITE_2(sc, WI_INT_EN, 0);
543		return;
544	}
545
546	/* Disable interrupts. */
547	CSR_WRITE_2(sc, WI_INT_EN, 0);
548
549	status = CSR_READ_2(sc, WI_EVENT_STAT);
550	CSR_WRITE_2(sc, WI_EVENT_ACK, ~WI_INTRS);
551
552	if (status & WI_EV_RX) {
553		wi_rxeof(sc);
554		CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX);
555	}
556
557	if (status & WI_EV_TX) {
558		wi_txeof(sc, status);
559		CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_TX);
560	}
561
562	if (status & WI_EV_ALLOC) {
563		int			id;
564		id = CSR_READ_2(sc, WI_ALLOC_FID);
565		CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_ALLOC);
566		if (id == sc->wi_tx_data_id)
567			wi_txeof(sc, status);
568	}
569
570	if (status & WI_EV_INFO) {
571		wi_update_stats(sc);
572		CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_INFO);
573	}
574
575	if (status & WI_EV_TX_EXC) {
576		wi_txeof(sc, status);
577		CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_TX_EXC);
578	}
579
580	if (status & WI_EV_INFO_DROP) {
581		CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_INFO_DROP);
582	}
583
584	/* Re-enable interrupts. */
585	CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS);
586
587	if (ifp->if_snd.ifq_head != NULL)
588		wi_start(ifp);
589
590	return;
591}
592
593static int wi_cmd(sc, cmd, val)
594	struct wi_softc		*sc;
595	int			cmd;
596	int			val;
597{
598	int			i, s = 0;
599
600	CSR_WRITE_2(sc, WI_PARAM0, val);
601	CSR_WRITE_2(sc, WI_COMMAND, cmd);
602
603	for (i = 0; i < WI_TIMEOUT; i++) {
604		/*
605		 * Wait for 'command complete' bit to be
606		 * set in the event status register.
607		 */
608		s = CSR_READ_2(sc, WI_EVENT_STAT) & WI_EV_CMD;
609		if (s) {
610			/* Ack the event and read result code. */
611			s = CSR_READ_2(sc, WI_STATUS);
612			CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_CMD);
613#ifdef foo
614			if ((s & WI_CMD_CODE_MASK) != (cmd & WI_CMD_CODE_MASK))
615				return(EIO);
616#endif
617			if (s & WI_STAT_CMD_RESULT)
618				return(EIO);
619			break;
620		}
621	}
622
623	if (i == WI_TIMEOUT)
624		return(ETIMEDOUT);
625
626	return(0);
627}
628
629static void wi_reset(sc)
630	struct wi_softc		*sc;
631{
632	wi_cmd(sc, WI_CMD_INI, 0);
633	DELAY(100000);
634	wi_cmd(sc, WI_CMD_INI, 0);
635	DELAY(100000);
636#ifdef foo
637	if (wi_cmd(sc, WI_CMD_INI, 0))
638		device_printf(sc->dev, "init failed\n");
639	CSR_WRITE_2(sc, WI_INT_EN, 0);
640	CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF);
641
642	/* Calibrate timer. */
643	WI_SETVAL(WI_RID_TICK_TIME, 8);
644#endif
645	return;
646}
647
648/*
649 * Read an LTV record from the NIC.
650 */
651static int wi_read_record(sc, ltv)
652	struct wi_softc		*sc;
653	struct wi_ltv_gen	*ltv;
654{
655	u_int16_t		*ptr;
656	int			i, len, code;
657
658	/* Tell the NIC to enter record read mode. */
659	if (wi_cmd(sc, WI_CMD_ACCESS|WI_ACCESS_READ, ltv->wi_type))
660		return(EIO);
661
662	/* Seek to the record. */
663	if (wi_seek(sc, ltv->wi_type, 0, WI_BAP1))
664		return(EIO);
665
666	/*
667	 * Read the length and record type and make sure they
668	 * match what we expect (this verifies that we have enough
669	 * room to hold all of the returned data).
670	 */
671	len = CSR_READ_2(sc, WI_DATA1);
672	if (len > ltv->wi_len)
673		return(ENOSPC);
674	code = CSR_READ_2(sc, WI_DATA1);
675	if (code != ltv->wi_type)
676		return(EIO);
677
678	ltv->wi_len = len;
679	ltv->wi_type = code;
680
681	/* Now read the data. */
682	ptr = &ltv->wi_val;
683	for (i = 0; i < ltv->wi_len - 1; i++)
684		ptr[i] = CSR_READ_2(sc, WI_DATA1);
685
686	return(0);
687}
688
689/*
690 * Same as read, except we inject data instead of reading it.
691 */
692static int wi_write_record(sc, ltv)
693	struct wi_softc		*sc;
694	struct wi_ltv_gen	*ltv;
695{
696	u_int16_t		*ptr;
697	int			i;
698
699	if (wi_seek(sc, ltv->wi_type, 0, WI_BAP1))
700		return(EIO);
701
702	CSR_WRITE_2(sc, WI_DATA1, ltv->wi_len);
703	CSR_WRITE_2(sc, WI_DATA1, ltv->wi_type);
704
705	ptr = &ltv->wi_val;
706	for (i = 0; i < ltv->wi_len - 1; i++)
707		CSR_WRITE_2(sc, WI_DATA1, ptr[i]);
708
709	if (wi_cmd(sc, WI_CMD_ACCESS|WI_ACCESS_WRITE, ltv->wi_type))
710		return(EIO);
711
712	return(0);
713}
714
715static int wi_seek(sc, id, off, chan)
716	struct wi_softc		*sc;
717	int			id, off, chan;
718{
719	int			i;
720	int			selreg, offreg;
721
722	switch (chan) {
723	case WI_BAP0:
724		selreg = WI_SEL0;
725		offreg = WI_OFF0;
726		break;
727	case WI_BAP1:
728		selreg = WI_SEL1;
729		offreg = WI_OFF1;
730		break;
731	default:
732		device_printf(sc->dev, "invalid data path: %x\n", chan);
733		return(EIO);
734	}
735
736	CSR_WRITE_2(sc, selreg, id);
737	CSR_WRITE_2(sc, offreg, off);
738
739	for (i = 0; i < WI_TIMEOUT; i++) {
740		if (!(CSR_READ_2(sc, offreg) & (WI_OFF_BUSY|WI_OFF_ERR)))
741			break;
742	}
743
744	if (i == WI_TIMEOUT)
745		return(ETIMEDOUT);
746
747	return(0);
748}
749
750static int wi_read_data(sc, id, off, buf, len)
751	struct wi_softc		*sc;
752	int			id, off;
753	caddr_t			buf;
754	int			len;
755{
756	int			i;
757	u_int16_t		*ptr;
758
759	if (wi_seek(sc, id, off, WI_BAP1))
760		return(EIO);
761
762	ptr = (u_int16_t *)buf;
763	for (i = 0; i < len / 2; i++)
764		ptr[i] = CSR_READ_2(sc, WI_DATA1);
765
766	return(0);
767}
768
769/*
770 * According to the comments in the HCF Light code, there is a bug in
771 * the Hermes (or possibly in certain Hermes firmware revisions) where
772 * the chip's internal autoincrement counter gets thrown off during
773 * data writes: the autoincrement is missed, causing one data word to
774 * be overwritten and subsequent words to be written to the wrong memory
775 * locations. The end result is that we could end up transmitting bogus
776 * frames without realizing it. The workaround for this is to write a
777 * couple of extra guard words after the end of the transfer, then
778 * attempt to read then back. If we fail to locate the guard words where
779 * we expect them, we preform the transfer over again.
780 */
781static int wi_write_data(sc, id, off, buf, len)
782	struct wi_softc		*sc;
783	int			id, off;
784	caddr_t			buf;
785	int			len;
786{
787	int			i;
788	u_int16_t		*ptr;
789
790#ifdef WI_HERMES_AUTOINC_WAR
791again:
792#endif
793
794	if (wi_seek(sc, id, off, WI_BAP0))
795		return(EIO);
796
797	ptr = (u_int16_t *)buf;
798	for (i = 0; i < (len / 2); i++)
799		CSR_WRITE_2(sc, WI_DATA0, ptr[i]);
800
801#ifdef WI_HERMES_AUTOINC_WAR
802	CSR_WRITE_2(sc, WI_DATA0, 0x1234);
803	CSR_WRITE_2(sc, WI_DATA0, 0x5678);
804
805	if (wi_seek(sc, id, off + len, WI_BAP0))
806		return(EIO);
807
808	if (CSR_READ_2(sc, WI_DATA0) != 0x1234 ||
809	    CSR_READ_2(sc, WI_DATA0) != 0x5678)
810		goto again;
811#endif
812
813	return(0);
814}
815
816/*
817 * Allocate a region of memory inside the NIC and zero
818 * it out.
819 */
820static int wi_alloc_nicmem(sc, len, id)
821	struct wi_softc		*sc;
822	int			len;
823	int			*id;
824{
825	int			i;
826
827	if (wi_cmd(sc, WI_CMD_ALLOC_MEM, len)) {
828		device_printf(sc->dev, "failed to allocate %d bytes on NIC\n", len);
829		return(ENOMEM);
830	}
831
832	for (i = 0; i < WI_TIMEOUT; i++) {
833		if (CSR_READ_2(sc, WI_EVENT_STAT) & WI_EV_ALLOC)
834			break;
835	}
836
837	if (i == WI_TIMEOUT)
838		return(ETIMEDOUT);
839
840	CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_ALLOC);
841	*id = CSR_READ_2(sc, WI_ALLOC_FID);
842
843	if (wi_seek(sc, *id, 0, WI_BAP0))
844		return(EIO);
845
846	for (i = 0; i < len / 2; i++)
847		CSR_WRITE_2(sc, WI_DATA0, 0);
848
849	return(0);
850}
851
852static void wi_setmulti(sc)
853	struct wi_softc		*sc;
854{
855	struct ifnet		*ifp;
856	int			i = 0;
857	struct ifmultiaddr	*ifma;
858	struct wi_ltv_mcast	mcast;
859
860	ifp = &sc->arpcom.ac_if;
861
862	bzero((char *)&mcast, sizeof(mcast));
863
864	mcast.wi_type = WI_RID_MCAST;
865	mcast.wi_len = (3 * 16) + 1;
866
867	if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
868		wi_write_record(sc, (struct wi_ltv_gen *)&mcast);
869		return;
870	}
871
872	for (ifma = ifp->if_multiaddrs.lh_first; ifma != NULL;
873				ifma = ifma->ifma_link.le_next) {
874		if (ifma->ifma_addr->sa_family != AF_LINK)
875			continue;
876		if (i < 16) {
877			bcopy(LLADDR((struct sockaddr_dl *)ifma->ifma_addr),
878			    (char *)&mcast.wi_mcast[i], ETHER_ADDR_LEN);
879			i++;
880		} else {
881			bzero((char *)&mcast, sizeof(mcast));
882			break;
883		}
884	}
885
886	mcast.wi_len = (i * 3) + 1;
887	wi_write_record(sc, (struct wi_ltv_gen *)&mcast);
888
889	return;
890}
891
892static void wi_setdef(sc, wreq)
893	struct wi_softc		*sc;
894	struct wi_req		*wreq;
895{
896	struct sockaddr_dl	*sdl;
897	struct ifaddr		*ifa;
898	struct ifnet		*ifp;
899
900	ifp = &sc->arpcom.ac_if;
901
902	switch(wreq->wi_type) {
903	case WI_RID_MAC_NODE:
904		ifa = ifnet_addrs[ifp->if_index - 1];
905		sdl = (struct sockaddr_dl *)ifa->ifa_addr;
906		bcopy((char *)&wreq->wi_val, (char *)&sc->arpcom.ac_enaddr,
907		   ETHER_ADDR_LEN);
908		bcopy((char *)&wreq->wi_val, LLADDR(sdl), ETHER_ADDR_LEN);
909		break;
910	case WI_RID_PORTTYPE:
911		sc->wi_ptype = wreq->wi_val[0];
912		break;
913	case WI_RID_TX_RATE:
914		sc->wi_tx_rate = wreq->wi_val[0];
915		break;
916	case WI_RID_MAX_DATALEN:
917		sc->wi_max_data_len = wreq->wi_val[0];
918		break;
919	case WI_RID_RTS_THRESH:
920		sc->wi_rts_thresh = wreq->wi_val[0];
921		break;
922	case WI_RID_SYSTEM_SCALE:
923		sc->wi_ap_density = wreq->wi_val[0];
924		break;
925	case WI_RID_CREATE_IBSS:
926		sc->wi_create_ibss = wreq->wi_val[0];
927		break;
928	case WI_RID_OWN_CHNL:
929		sc->wi_channel = wreq->wi_val[0];
930		break;
931	case WI_RID_NODENAME:
932		bzero(sc->wi_node_name, sizeof(sc->wi_node_name));
933		bcopy((char *)&wreq->wi_val[1], sc->wi_node_name, 30);
934		break;
935	case WI_RID_DESIRED_SSID:
936		bzero(sc->wi_net_name, sizeof(sc->wi_net_name));
937		bcopy((char *)&wreq->wi_val[1], sc->wi_net_name, 30);
938		break;
939	case WI_RID_OWN_SSID:
940		bzero(sc->wi_ibss_name, sizeof(sc->wi_ibss_name));
941		bcopy((char *)&wreq->wi_val[1], sc->wi_ibss_name, 30);
942		break;
943	case WI_RID_PM_ENABLED:
944		sc->wi_pm_enabled = wreq->wi_val[0];
945		break;
946	case WI_RID_MAX_SLEEP:
947		sc->wi_max_sleep = wreq->wi_val[0];
948		break;
949	case WI_RID_ENCRYPTION:
950		sc->wi_use_wep = wreq->wi_val[0];
951		break;
952	case WI_RID_TX_CRYPT_KEY:
953		sc->wi_tx_key = wreq->wi_val[0];
954		break;
955	case WI_RID_DEFLT_CRYPT_KEYS:
956		bcopy((char *)wreq, (char *)&sc->wi_keys,
957		    sizeof(struct wi_ltv_keys));
958		break;
959	default:
960		break;
961	}
962
963	/* Reinitialize WaveLAN. */
964	wi_init(sc);
965
966	return;
967}
968
969static int wi_ioctl(ifp, command, data)
970	struct ifnet		*ifp;
971	u_long			command;
972	caddr_t			data;
973{
974	int			s, error = 0;
975	struct wi_softc		*sc;
976	struct wi_req		wreq;
977	struct ifreq		*ifr;
978
979	s = splimp();
980
981	sc = ifp->if_softc;
982	ifr = (struct ifreq *)data;
983
984	if (sc->wi_gone)
985		return(ENODEV);
986
987	switch(command) {
988	case SIOCSIFADDR:
989	case SIOCGIFADDR:
990	case SIOCSIFMTU:
991		error = ether_ioctl(ifp, command, data);
992		break;
993	case SIOCSIFFLAGS:
994		if (ifp->if_flags & IFF_UP) {
995			if (ifp->if_flags & IFF_RUNNING &&
996			    ifp->if_flags & IFF_PROMISC &&
997			    !(sc->wi_if_flags & IFF_PROMISC)) {
998				WI_SETVAL(WI_RID_PROMISC, 1);
999			} else if (ifp->if_flags & IFF_RUNNING &&
1000			    !(ifp->if_flags & IFF_PROMISC) &&
1001			    sc->wi_if_flags & IFF_PROMISC) {
1002				WI_SETVAL(WI_RID_PROMISC, 0);
1003			} else
1004				wi_init(sc);
1005		} else {
1006			if (ifp->if_flags & IFF_RUNNING) {
1007				wi_stop(sc);
1008			}
1009		}
1010		sc->wi_if_flags = ifp->if_flags;
1011		error = 0;
1012		break;
1013	case SIOCADDMULTI:
1014	case SIOCDELMULTI:
1015		wi_setmulti(sc);
1016		error = 0;
1017		break;
1018	case SIOCGWAVELAN:
1019		error = copyin(ifr->ifr_data, &wreq, sizeof(wreq));
1020		if (error)
1021			break;
1022		if (wreq.wi_type == WI_RID_IFACE_STATS) {
1023			bcopy((char *)&sc->wi_stats, (char *)&wreq.wi_val,
1024			    sizeof(sc->wi_stats));
1025			wreq.wi_len = (sizeof(sc->wi_stats) / 2) + 1;
1026		} else if (wreq.wi_type == WI_RID_DEFLT_CRYPT_KEYS) {
1027			bcopy((char *)&sc->wi_keys, (char *)&wreq,
1028			    sizeof(struct wi_ltv_keys));
1029		}
1030#ifdef WICACHE
1031		else if (wreq.wi_type == WI_RID_ZERO_CACHE) {
1032			sc->wi_sigitems = sc->wi_nextitem = 0;
1033		} else if (wreq.wi_type == WI_RID_READ_CACHE) {
1034			char *pt = (char *)&wreq.wi_val;
1035			bcopy((char *)&sc->wi_sigitems,
1036			    (char *)pt, sizeof(int));
1037			pt += (sizeof (int));
1038			wreq.wi_len = sizeof(int) / 2;
1039			bcopy((char *)&sc->wi_sigcache, (char *)pt,
1040			    sizeof(struct wi_sigcache) * sc->wi_sigitems);
1041			wreq.wi_len += ((sizeof(struct wi_sigcache) *
1042			    sc->wi_sigitems) / 2) + 1;
1043		}
1044#endif
1045		else {
1046			if (wi_read_record(sc, (struct wi_ltv_gen *)&wreq)) {
1047				error = EINVAL;
1048				break;
1049			}
1050		}
1051		error = copyout(&wreq, ifr->ifr_data, sizeof(wreq));
1052		break;
1053	case SIOCSWAVELAN:
1054		error = copyin(ifr->ifr_data, &wreq, sizeof(wreq));
1055		if (error)
1056			break;
1057		if (wreq.wi_type == WI_RID_IFACE_STATS) {
1058			error = EINVAL;
1059			break;
1060		} else if (wreq.wi_type == WI_RID_MGMT_XMIT) {
1061			error = wi_mgmt_xmit(sc, (caddr_t)&wreq.wi_val,
1062			    wreq.wi_len);
1063		} else {
1064			error = wi_write_record(sc, (struct wi_ltv_gen *)&wreq);
1065			if (!error)
1066				wi_setdef(sc, &wreq);
1067		}
1068		break;
1069	default:
1070		error = EINVAL;
1071		break;
1072	}
1073
1074	splx(s);
1075
1076	return(error);
1077}
1078
1079static void wi_init(xsc)
1080	void			*xsc;
1081{
1082	struct wi_softc		*sc = xsc;
1083	struct ifnet		*ifp = &sc->arpcom.ac_if;
1084	int			s;
1085	struct wi_ltv_macaddr	mac;
1086	int			id = 0;
1087
1088	if (sc->wi_gone)
1089		return;
1090
1091	s = splimp();
1092
1093	if (ifp->if_flags & IFF_RUNNING)
1094		wi_stop(sc);
1095
1096	wi_reset(sc);
1097
1098	/* Program max data length. */
1099	WI_SETVAL(WI_RID_MAX_DATALEN, sc->wi_max_data_len);
1100
1101	/* Enable/disable IBSS creation. */
1102	WI_SETVAL(WI_RID_CREATE_IBSS, sc->wi_create_ibss);
1103
1104	/* Set the port type. */
1105	WI_SETVAL(WI_RID_PORTTYPE, sc->wi_ptype);
1106
1107	/* Program the RTS/CTS threshold. */
1108	WI_SETVAL(WI_RID_RTS_THRESH, sc->wi_rts_thresh);
1109
1110	/* Program the TX rate */
1111	WI_SETVAL(WI_RID_TX_RATE, sc->wi_tx_rate);
1112
1113	/* Access point density */
1114	WI_SETVAL(WI_RID_SYSTEM_SCALE, sc->wi_ap_density);
1115
1116	/* Power Management Enabled */
1117	WI_SETVAL(WI_RID_PM_ENABLED, sc->wi_pm_enabled);
1118
1119	/* Power Managment Max Sleep */
1120	WI_SETVAL(WI_RID_MAX_SLEEP, sc->wi_max_sleep);
1121
1122	/* Specify the IBSS name */
1123	WI_SETSTR(WI_RID_OWN_SSID, sc->wi_ibss_name);
1124
1125	/* Specify the network name */
1126	WI_SETSTR(WI_RID_DESIRED_SSID, sc->wi_net_name);
1127
1128	/* Specify the frequency to use */
1129	WI_SETVAL(WI_RID_OWN_CHNL, sc->wi_channel);
1130
1131	/* Program the nodename. */
1132	WI_SETSTR(WI_RID_NODENAME, sc->wi_node_name);
1133
1134	/* Set our MAC address. */
1135	mac.wi_len = 4;
1136	mac.wi_type = WI_RID_MAC_NODE;
1137	bcopy((char *)&sc->arpcom.ac_enaddr,
1138	   (char *)&mac.wi_mac_addr, ETHER_ADDR_LEN);
1139	wi_write_record(sc, (struct wi_ltv_gen *)&mac);
1140
1141	/* Configure WEP. */
1142	if (sc->wi_has_wep) {
1143		WI_SETVAL(WI_RID_ENCRYPTION, sc->wi_use_wep);
1144		WI_SETVAL(WI_RID_TX_CRYPT_KEY, sc->wi_tx_key);
1145		sc->wi_keys.wi_len = (sizeof(struct wi_ltv_keys) / 2) + 1;
1146		sc->wi_keys.wi_type = WI_RID_DEFLT_CRYPT_KEYS;
1147		wi_write_record(sc, (struct wi_ltv_gen *)&sc->wi_keys);
1148	}
1149
1150	/* Initialize promisc mode. */
1151	if (ifp->if_flags & IFF_PROMISC) {
1152		WI_SETVAL(WI_RID_PROMISC, 1);
1153	} else {
1154		WI_SETVAL(WI_RID_PROMISC, 0);
1155	}
1156
1157	/* Set multicast filter. */
1158	wi_setmulti(sc);
1159
1160	/* Enable desired port */
1161	wi_cmd(sc, WI_CMD_ENABLE|sc->wi_portnum, 0);
1162
1163	if (wi_alloc_nicmem(sc, 1518 + sizeof(struct wi_frame) + 8, &id))
1164		device_printf(sc->dev, "tx buffer allocation failed\n");
1165	sc->wi_tx_data_id = id;
1166
1167	if (wi_alloc_nicmem(sc, 1518 + sizeof(struct wi_frame) + 8, &id))
1168		device_printf(sc->dev, "mgmt. buffer allocation failed\n");
1169	sc->wi_tx_mgmt_id = id;
1170
1171	/* enable interrupts */
1172	CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS);
1173
1174	splx(s);
1175
1176	ifp->if_flags |= IFF_RUNNING;
1177	ifp->if_flags &= ~IFF_OACTIVE;
1178
1179	sc->wi_stat_ch = timeout(wi_inquire, sc, hz * 60);
1180
1181	return;
1182}
1183
1184static void wi_start(ifp)
1185	struct ifnet		*ifp;
1186{
1187	struct wi_softc		*sc;
1188	struct mbuf		*m0;
1189	struct wi_frame		tx_frame;
1190	struct ether_header	*eh;
1191	int			id;
1192
1193	sc = ifp->if_softc;
1194
1195	if (sc->wi_gone)
1196		return;
1197
1198	if (ifp->if_flags & IFF_OACTIVE)
1199		return;
1200
1201	IF_DEQUEUE(&ifp->if_snd, m0);
1202	if (m0 == NULL)
1203		return;
1204
1205	bzero((char *)&tx_frame, sizeof(tx_frame));
1206	id = sc->wi_tx_data_id;
1207	eh = mtod(m0, struct ether_header *);
1208
1209	/*
1210	 * Use RFC1042 encoding for IP and ARP datagrams,
1211	 * 802.3 for anything else.
1212	 */
1213	if (ntohs(eh->ether_type) > 1518) {
1214		bcopy((char *)&eh->ether_dhost,
1215		    (char *)&tx_frame.wi_addr1, ETHER_ADDR_LEN);
1216		bcopy((char *)&eh->ether_shost,
1217		    (char *)&tx_frame.wi_addr2, ETHER_ADDR_LEN);
1218		bcopy((char *)&eh->ether_dhost,
1219		    (char *)&tx_frame.wi_dst_addr, ETHER_ADDR_LEN);
1220		bcopy((char *)&eh->ether_shost,
1221		    (char *)&tx_frame.wi_src_addr, ETHER_ADDR_LEN);
1222
1223		tx_frame.wi_dat_len = m0->m_pkthdr.len - WI_SNAPHDR_LEN;
1224		tx_frame.wi_frame_ctl = WI_FTYPE_DATA;
1225		tx_frame.wi_dat[0] = htons(WI_SNAP_WORD0);
1226		tx_frame.wi_dat[1] = htons(WI_SNAP_WORD1);
1227		tx_frame.wi_len = htons(m0->m_pkthdr.len - WI_SNAPHDR_LEN);
1228		tx_frame.wi_type = eh->ether_type;
1229
1230		m_copydata(m0, sizeof(struct ether_header),
1231		    m0->m_pkthdr.len - sizeof(struct ether_header),
1232		    (caddr_t)&sc->wi_txbuf);
1233
1234		wi_write_data(sc, id, 0, (caddr_t)&tx_frame,
1235		    sizeof(struct wi_frame));
1236		wi_write_data(sc, id, WI_802_11_OFFSET, (caddr_t)&sc->wi_txbuf,
1237		    (m0->m_pkthdr.len - sizeof(struct ether_header)) + 2);
1238	} else {
1239		tx_frame.wi_dat_len = m0->m_pkthdr.len;
1240
1241		eh->ether_type = htons(m0->m_pkthdr.len - WI_SNAPHDR_LEN);
1242		m_copydata(m0, 0, m0->m_pkthdr.len, (caddr_t)&sc->wi_txbuf);
1243
1244		wi_write_data(sc, id, 0, (caddr_t)&tx_frame,
1245		    sizeof(struct wi_frame));
1246		wi_write_data(sc, id, WI_802_3_OFFSET, (caddr_t)&sc->wi_txbuf,
1247		    m0->m_pkthdr.len + 2);
1248	}
1249
1250	/*
1251	 * If there's a BPF listner, bounce a copy of
1252	 * this frame to him.
1253	 */
1254	if (ifp->if_bpf)
1255		bpf_mtap(ifp, m0);
1256
1257	m_freem(m0);
1258
1259	if (wi_cmd(sc, WI_CMD_TX|WI_RECLAIM, id))
1260		device_printf(sc->dev, "xmit failed\n");
1261
1262	ifp->if_flags |= IFF_OACTIVE;
1263
1264	/*
1265	 * Set a timeout in case the chip goes out to lunch.
1266	 */
1267	ifp->if_timer = 5;
1268
1269	return;
1270}
1271
1272static int wi_mgmt_xmit(sc, data, len)
1273	struct wi_softc		*sc;
1274	caddr_t			data;
1275	int			len;
1276{
1277	struct wi_frame		tx_frame;
1278	int			id;
1279	struct wi_80211_hdr	*hdr;
1280	caddr_t			dptr;
1281
1282	if (sc->wi_gone)
1283		return(ENODEV);
1284
1285	hdr = (struct wi_80211_hdr *)data;
1286	dptr = data + sizeof(struct wi_80211_hdr);
1287
1288	bzero((char *)&tx_frame, sizeof(tx_frame));
1289	id = sc->wi_tx_mgmt_id;
1290
1291	bcopy((char *)hdr, (char *)&tx_frame.wi_frame_ctl,
1292	   sizeof(struct wi_80211_hdr));
1293
1294	tx_frame.wi_dat_len = len - WI_SNAPHDR_LEN;
1295	tx_frame.wi_len = htons(len - WI_SNAPHDR_LEN);
1296
1297	wi_write_data(sc, id, 0, (caddr_t)&tx_frame, sizeof(struct wi_frame));
1298	wi_write_data(sc, id, WI_802_11_OFFSET_RAW, dptr,
1299	    (len - sizeof(struct wi_80211_hdr)) + 2);
1300
1301	if (wi_cmd(sc, WI_CMD_TX|WI_RECLAIM, id)) {
1302		device_printf(sc->dev, "xmit failed\n");
1303		return(EIO);
1304	}
1305
1306	return(0);
1307}
1308
1309static void wi_stop(sc)
1310	struct wi_softc		*sc;
1311{
1312	struct ifnet		*ifp;
1313
1314	if (sc->wi_gone)
1315		return;
1316
1317	ifp = &sc->arpcom.ac_if;
1318
1319	CSR_WRITE_2(sc, WI_INT_EN, 0);
1320	wi_cmd(sc, WI_CMD_DISABLE|sc->wi_portnum, 0);
1321
1322	untimeout(wi_inquire, sc, sc->wi_stat_ch);
1323
1324	ifp->if_flags &= ~(IFF_RUNNING|IFF_OACTIVE);
1325
1326	return;
1327}
1328
1329static void wi_watchdog(ifp)
1330	struct ifnet		*ifp;
1331{
1332	struct wi_softc		*sc;
1333
1334	sc = ifp->if_softc;
1335
1336	device_printf(sc->dev,"device timeout\n");
1337
1338	wi_init(sc);
1339
1340	ifp->if_oerrors++;
1341
1342	return;
1343}
1344
1345static int wi_alloc(dev)
1346	device_t		dev;
1347{
1348	struct wi_softc		*sc = device_get_softc(dev);
1349	int			rid;
1350
1351	rid = 0;
1352	sc->iobase = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
1353					0, ~0, 1, RF_ACTIVE);
1354	if (!sc->iobase) {
1355		device_printf(dev, "No I/O space?!\n");
1356		return (ENXIO);
1357	}
1358
1359	rid = 0;
1360	sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
1361				     0, ~0, 1, RF_ACTIVE);
1362	if (!sc->irq) {
1363		device_printf(dev, "No irq?!\n");
1364		return (ENXIO);
1365	}
1366
1367	sc->dev = dev;
1368	sc->wi_unit = device_get_unit(dev);
1369	sc->wi_io_addr = rman_get_start(sc->iobase);
1370	sc->wi_btag = rman_get_bustag(sc->iobase);
1371	sc->wi_bhandle = rman_get_bushandle(sc->iobase);
1372
1373	return (0);
1374}
1375
1376static void wi_free(dev)
1377	device_t		dev;
1378{
1379	struct wi_softc		*sc = device_get_softc(dev);
1380
1381	if (sc->iobase != NULL)
1382		bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->iobase);
1383	if (sc->irq != NULL)
1384		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq);
1385
1386	return;
1387}
1388
1389static void wi_shutdown(dev)
1390	device_t		dev;
1391{
1392	struct wi_softc		*sc;
1393
1394	sc = device_get_softc(dev);
1395	wi_stop(sc);
1396
1397	return;
1398}
1399
1400#ifdef WICACHE
1401/* wavelan signal strength cache code.
1402 * store signal/noise/quality on per MAC src basis in
1403 * a small fixed cache.  The cache wraps if > MAX slots
1404 * used.  The cache may be zeroed out to start over.
1405 * Two simple filters exist to reduce computation:
1406 * 1. ip only (literally 0x800) which may be used
1407 * to ignore some packets.  It defaults to ip only.
1408 * it could be used to focus on broadcast, non-IP 802.11 beacons.
1409 * 2. multicast/broadcast only.  This may be used to
1410 * ignore unicast packets and only cache signal strength
1411 * for multicast/broadcast packets (beacons); e.g., Mobile-IP
1412 * beacons and not unicast traffic.
1413 *
1414 * The cache stores (MAC src(index), IP src (major clue), signal,
1415 *	quality, noise)
1416 *
1417 * No apologies for storing IP src here.  It's easy and saves much
1418 * trouble elsewhere.  The cache is assumed to be INET dependent,
1419 * although it need not be.
1420 */
1421
1422#ifdef documentation
1423
1424int wi_sigitems;                                /* number of cached entries */
1425struct wi_sigcache wi_sigcache[MAXWICACHE];  /*  array of cache entries */
1426int wi_nextitem;                                /*  index/# of entries */
1427
1428
1429#endif
1430
1431/* control variables for cache filtering.  Basic idea is
1432 * to reduce cost (e.g., to only Mobile-IP agent beacons
1433 * which are broadcast or multicast).  Still you might
1434 * want to measure signal strength with unicast ping packets
1435 * on a pt. to pt. ant. setup.
1436 */
1437/* set true if you want to limit cache items to broadcast/mcast
1438 * only packets (not unicast).  Useful for mobile-ip beacons which
1439 * are broadcast/multicast at network layer.  Default is all packets
1440 * so ping/unicast will work say with pt. to pt. antennae setup.
1441 */
1442static int wi_cache_mcastonly = 0;
1443SYSCTL_INT(_machdep, OID_AUTO, wi_cache_mcastonly, CTLFLAG_RW,
1444	&wi_cache_mcastonly, 0, "");
1445
1446/* set true if you want to limit cache items to IP packets only
1447*/
1448static int wi_cache_iponly = 1;
1449SYSCTL_INT(_machdep, OID_AUTO, wi_cache_iponly, CTLFLAG_RW,
1450	&wi_cache_iponly, 0, "");
1451
1452/*
1453 * Original comments:
1454 * -----------------
1455 * wi_cache_store, per rx packet store signal
1456 * strength in MAC (src) indexed cache.
1457 *
1458 * follows linux driver in how signal strength is computed.
1459 * In ad hoc mode, we use the rx_quality field.
1460 * signal and noise are trimmed to fit in the range from 47..138.
1461 * rx_quality field MSB is signal strength.
1462 * rx_quality field LSB is noise.
1463 * "quality" is (signal - noise) as is log value.
1464 * note: quality CAN be negative.
1465 *
1466 * In BSS mode, we use the RID for communication quality.
1467 * TBD:  BSS mode is currently untested.
1468 *
1469 * Bill's comments:
1470 * ---------------
1471 * Actually, we use the rx_quality field all the time for both "ad-hoc"
1472 * and BSS modes. Why? Because reading an RID is really, really expensive:
1473 * there's a bunch of PIO operations that have to be done to read a record
1474 * from the NIC, and reading the comms quality RID each time a packet is
1475 * received can really hurt performance. We don't have to do this anyway:
1476 * the comms quality field only reflects the values in the rx_quality field
1477 * anyway. The comms quality RID is only meaningful in infrastructure mode,
1478 * but the values it contains are updated based on the rx_quality from
1479 * frames received from the access point.
1480 *
1481 * Also, according to Lucent, the signal strength and noise level values
1482 * can be converted to dBms by subtracting 149, so I've modified the code
1483 * to do that instead of the scaling it did originally.
1484 */
1485static
1486void wi_cache_store (struct wi_softc *sc, struct ether_header *eh,
1487                     struct mbuf *m, unsigned short rx_quality)
1488{
1489	struct ip *ip = 0;
1490	int i;
1491	static int cache_slot = 0; 	/* use this cache entry */
1492	static int wrapindex = 0;       /* next "free" cache entry */
1493	int sig, noise;
1494	int sawip=0;
1495
1496	/* filters:
1497	 * 1. ip only
1498	 * 2. configurable filter to throw out unicast packets,
1499	 * keep multicast only.
1500	 */
1501
1502	if ((ntohs(eh->ether_type) == 0x800)) {
1503		sawip = 1;
1504	}
1505
1506	/* filter for ip packets only
1507	*/
1508	if (wi_cache_iponly && !sawip) {
1509		return;
1510	}
1511
1512	/* filter for broadcast/multicast only
1513	 */
1514	if (wi_cache_mcastonly && ((eh->ether_dhost[0] & 1) == 0)) {
1515		return;
1516	}
1517
1518#ifdef SIGDEBUG
1519	printf("wi%d: q value %x (MSB=0x%x, LSB=0x%x) \n", sc->wi_unit,
1520	    rx_quality & 0xffff, rx_quality >> 8, rx_quality & 0xff);
1521#endif
1522
1523	/* find the ip header.  we want to store the ip_src
1524	 * address.
1525	 */
1526	if (sawip) {
1527		ip = mtod(m, struct ip *);
1528	}
1529
1530	/* do a linear search for a matching MAC address
1531	 * in the cache table
1532	 * . MAC address is 6 bytes,
1533	 * . var w_nextitem holds total number of entries already cached
1534	 */
1535	for(i = 0; i < sc->wi_nextitem; i++) {
1536		if (! bcmp(eh->ether_shost , sc->wi_sigcache[i].macsrc,  6 )) {
1537			/* Match!,
1538			 * so we already have this entry,
1539			 * update the data
1540			 */
1541			break;
1542		}
1543	}
1544
1545	/* did we find a matching mac address?
1546	 * if yes, then overwrite a previously existing cache entry
1547	 */
1548	if (i < sc->wi_nextitem )   {
1549		cache_slot = i;
1550	}
1551	/* else, have a new address entry,so
1552	 * add this new entry,
1553	 * if table full, then we need to replace LRU entry
1554	 */
1555	else    {
1556
1557		/* check for space in cache table
1558		 * note: wi_nextitem also holds number of entries
1559		 * added in the cache table
1560		 */
1561		if ( sc->wi_nextitem < MAXWICACHE ) {
1562			cache_slot = sc->wi_nextitem;
1563			sc->wi_nextitem++;
1564			sc->wi_sigitems = sc->wi_nextitem;
1565		}
1566        	/* no space found, so simply wrap with wrap index
1567		 * and "zap" the next entry
1568		 */
1569		else {
1570			if (wrapindex == MAXWICACHE) {
1571				wrapindex = 0;
1572			}
1573			cache_slot = wrapindex++;
1574		}
1575	}
1576
1577	/* invariant: cache_slot now points at some slot
1578	 * in cache.
1579	 */
1580	if (cache_slot < 0 || cache_slot >= MAXWICACHE) {
1581		log(LOG_ERR, "wi_cache_store, bad index: %d of "
1582		    "[0..%d], gross cache error\n",
1583		    cache_slot, MAXWICACHE);
1584		return;
1585	}
1586
1587	/*  store items in cache
1588	 *  .ip source address
1589	 *  .mac src
1590	 *  .signal, etc.
1591	 */
1592	if (sawip) {
1593		sc->wi_sigcache[cache_slot].ipsrc = ip->ip_src.s_addr;
1594	}
1595	bcopy( eh->ether_shost, sc->wi_sigcache[cache_slot].macsrc,  6);
1596
1597	sig = (rx_quality >> 8) & 0xFF;
1598	noise = rx_quality & 0xFF;
1599	sc->wi_sigcache[cache_slot].signal = sig - 149;
1600	sc->wi_sigcache[cache_slot].noise = noise - 149;
1601	sc->wi_sigcache[cache_slot].quality = sig - noise;
1602
1603	return;
1604}
1605#endif
1606