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