if_ipw.c revision 1.2
1/*	$Id: if_ipw.c,v 1.2 2004/10/27 21:10:22 damien Exp $  */
2
3/*-
4 * Copyright (c) 2004
5 *      Damien Bergamini <damien.bergamini@free.fr>. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice unmodified, this list of conditions, and the following
12 *    disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30/*-
31 * Intel(R) PRO/Wireless 2100 MiniPCI driver
32 * www.intel.com/network/connectivity/products/wireless/prowireless_mobile.htm
33 */
34
35#include "bpfilter.h"
36
37#include <sys/param.h>
38#include <sys/sockio.h>
39#include <sys/sysctl.h>
40#include <sys/mbuf.h>
41#include <sys/kernel.h>
42#include <sys/socket.h>
43#include <sys/systm.h>
44#include <sys/malloc.h>
45#include <sys/conf.h>
46
47#include <machine/bus.h>
48#include <machine/endian.h>
49#include <machine/intr.h>
50
51#include <dev/pci/pcireg.h>
52#include <dev/pci/pcivar.h>
53#include <dev/pci/pcidevs.h>
54
55#if NBPFILTER > 0
56#include <net/bpf.h>
57#endif
58#include <net/if.h>
59#include <net/if_arp.h>
60#include <net/if_dl.h>
61#include <net/if_media.h>
62#include <net/if_types.h>
63
64#include <netinet/in.h>
65#include <netinet/in_systm.h>
66#include <netinet/in_var.h>
67#include <netinet/if_ether.h>
68#include <netinet/ip.h>
69
70#include <net80211/ieee80211_var.h>
71#include <net80211/ieee80211_radiotap.h>
72
73#include <dev/pci/if_ipwreg.h>
74#include <dev/pci/if_ipwvar.h>
75
76static int ipw_match(struct device *, void *, void *);
77static void ipw_attach(struct device *, struct device *, void *);
78static int ipw_detach(struct device *, int);
79static int ipw_media_change(struct ifnet *);
80static int ipw_newstate(struct ieee80211com *, enum ieee80211_state, int);
81static void ipw_command_intr(struct ipw_softc *, struct ipw_soft_buf *);
82static void ipw_newstate_intr(struct ipw_softc *, struct ipw_soft_buf *);
83static void ipw_data_intr(struct ipw_softc *, struct ipw_status *,
84    struct ipw_soft_bd *, struct ipw_soft_buf *);
85static void ipw_notification_intr(struct ipw_softc *, struct ipw_soft_buf *);
86static void ipw_rx_intr(struct ipw_softc *);
87static void ipw_release_sbd(struct ipw_softc *, struct ipw_soft_bd *);
88static void ipw_tx_intr(struct ipw_softc *);
89static int ipw_intr(void *);
90static int ipw_cmd(struct ipw_softc *, u_int32_t, void *, u_int32_t);
91static int ipw_tx_start(struct ifnet *, struct mbuf *, struct ieee80211_node *);
92static void ipw_start(struct ifnet *);
93static void ipw_watchdog(struct ifnet *);
94static int ipw_get_table1(struct ipw_softc *, u_int32_t *);
95static int ipw_get_radio(struct ipw_softc *, int *);
96static int ipw_ioctl(struct ifnet *, u_long, caddr_t);
97static u_int32_t ipw_read_table1(struct ipw_softc *, u_int32_t);
98static void ipw_write_table1(struct ipw_softc *, u_int32_t, u_int32_t);
99static int ipw_read_table2(struct ipw_softc *, u_int32_t, void *, u_int32_t *);
100static int ipw_tx_init(struct ipw_softc *);
101static void ipw_tx_stop(struct ipw_softc *);
102static int ipw_rx_init(struct ipw_softc *);
103static void ipw_rx_stop(struct ipw_softc *);
104static void ipw_reset(struct ipw_softc *);
105static int ipw_clock_sync(struct ipw_softc *);
106static int ipw_load_ucode(struct ipw_softc *, u_char *, int);
107static int ipw_load_firmware(struct ipw_softc *, u_char *, int);
108static int ipw_firmware_init(struct ipw_softc *, u_char *);
109static int ipw_config(struct ipw_softc *);
110static int ipw_init(struct ifnet *);
111static void ipw_stop(struct ifnet *, int);
112static void ipw_read_mem_1(struct ipw_softc *, bus_size_t, u_int8_t *,
113    bus_size_t);
114static void ipw_write_mem_1(struct ipw_softc *, bus_size_t, u_int8_t *,
115    bus_size_t);
116static void ipw_zero_mem_4(struct ipw_softc *, bus_size_t, bus_size_t);
117
118static __inline u_int8_t MEM_READ_1(struct ipw_softc *sc, u_int32_t addr)
119{
120	CSR_WRITE_4(sc, IPW_CSR_INDIRECT_ADDR, addr);
121	return CSR_READ_1(sc, IPW_CSR_INDIRECT_DATA);
122}
123
124static __inline u_int32_t MEM_READ_4(struct ipw_softc *sc, u_int32_t addr)
125{
126	CSR_WRITE_4(sc, IPW_CSR_INDIRECT_ADDR, addr);
127	return CSR_READ_4(sc, IPW_CSR_INDIRECT_DATA);
128}
129
130#ifdef IPW_DEBUG
131#define DPRINTF(x)	if (ipw_debug > 0) printf x
132#define DPRINTFN(n, x)	if (ipw_debug >= (n)) printf x
133int ipw_debug = 0;
134#else
135#define DPRINTF(x)
136#define DPRINTFN(n, x)
137#endif
138
139struct cfattach ipw_ca = {
140	sizeof (struct ipw_softc), ipw_match, ipw_attach, ipw_detach
141};
142
143static int
144ipw_match(struct device *parent, void *match, void *aux)
145{
146	struct pci_attach_args *pa = aux;
147
148	if (PCI_VENDOR (pa->pa_id) == PCI_VENDOR_INTEL &&
149	    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_PRO_2100_3B)
150		return 1;
151
152	return 0;
153}
154
155/* Base Address Register */
156#define IPW_PCI_BAR0	0x10
157
158static void
159ipw_attach(struct device *parent, struct device *self, void *aux)
160{
161	struct ipw_softc *sc = (struct ipw_softc *)self;
162	struct ieee80211com *ic = &sc->sc_ic;
163	struct ifnet *ifp = &ic->ic_if;
164	struct ieee80211_rateset *rs;
165	struct pci_attach_args *pa = aux;
166	const char *intrstr;
167	bus_space_tag_t memt;
168	bus_space_handle_t memh;
169	bus_addr_t base;
170	pci_intr_handle_t ih;
171	u_int32_t data;
172	int error, i;
173
174	sc->sc_pct = pa->pa_pc;
175
176	/* enable bus-mastering */
177	data = pci_conf_read(sc->sc_pct, pa->pa_tag, PCI_COMMAND_STATUS_REG);
178	data |= PCI_COMMAND_MASTER_ENABLE;
179	pci_conf_write(sc->sc_pct, pa->pa_tag, PCI_COMMAND_STATUS_REG, data);
180
181	/* map the register window */
182	error = pci_mapreg_map(pa, IPW_PCI_BAR0, PCI_MAPREG_TYPE_MEM |
183	    PCI_MAPREG_MEM_TYPE_32BIT, 0, &memt, &memh, &base, &sc->sc_sz, 0);
184	if (error != 0) {
185		printf(": could not map memory space\n");
186		return;
187	}
188
189	sc->sc_st = memt;
190	sc->sc_sh = memh;
191	sc->sc_dmat = pa->pa_dmat;
192
193	/* disable interrupts */
194	CSR_WRITE_4(sc, IPW_CSR_INTR_MASK, 0);
195
196	if (pci_intr_map(pa, &ih) != 0) {
197		printf(": could not map interrupt\n");
198		return;
199	}
200
201	intrstr = pci_intr_string(sc->sc_pct, ih);
202	sc->sc_ih = pci_intr_establish(sc->sc_pct, ih, IPL_NET, ipw_intr, sc,
203	    sc->sc_dev.dv_xname);
204	if (sc->sc_ih == NULL) {
205		printf(": could not establish interrupt");
206		if (intrstr != NULL)
207			printf(" at %s", intrstr);
208		printf("\n");
209		return;
210	}
211	printf(": %s\n", intrstr);
212
213	ic->ic_phytype = IEEE80211_T_DS;
214	ic->ic_opmode = IEEE80211_M_STA;
215	ic->ic_state = IEEE80211_S_INIT;
216
217	/* set device capabilities */
218	ic->ic_caps =  IEEE80211_C_IBSS | IEEE80211_C_MONITOR |
219	    IEEE80211_C_PMGT | IEEE80211_C_TXPMGT | IEEE80211_C_WEP;
220
221	/* set supported .11b rates */
222	rs = &ic->ic_sup_rates[IEEE80211_MODE_11B];
223	rs->rs_nrates = 4;
224	rs->rs_rates[0] = 2;	/* 1Mbps */
225	rs->rs_rates[1] = 4;	/* 2Mbps */
226	rs->rs_rates[2] = 11;	/* 5.5Mbps */
227	rs->rs_rates[3] = 22; 	/* 11Mbps */
228
229	/* set supported .11b channels (1 through 14) */
230	for (i = 1; i <= 14; i++) {
231		ic->ic_channels[i].ic_freq =
232		    ieee80211_ieee2mhz(i, IEEE80211_CHAN_B);
233		ic->ic_channels[i].ic_flags = IEEE80211_CHAN_B;
234	}
235
236	/* IBSS channel undefined for now */
237	ic->ic_ibss_chan = &ic->ic_channels[0];
238
239	ifp->if_softc = sc;
240	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
241	ifp->if_init = ipw_init;
242	ifp->if_ioctl = ipw_ioctl;
243	ifp->if_start = ipw_start;
244	ifp->if_watchdog = ipw_watchdog;
245	IFQ_SET_READY(&ifp->if_snd);
246	bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
247
248	if_attach(ifp);
249	ieee80211_ifattach(ifp);
250	/* override state transition machine */
251	sc->sc_newstate = ic->ic_newstate;
252	ic->ic_newstate = ipw_newstate;
253	ieee80211_media_init(ifp, ipw_media_change, ieee80211_media_status);
254
255#if NBPFILTER > 0
256	bpfattach(&sc->sc_drvbpf, ifp, DLT_IEEE802_11_RADIO,
257	    sizeof (struct ieee80211_frame) + 64);
258
259	sc->sc_rxtap_len = sizeof sc->sc_rxtapu;
260	sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
261	sc->sc_rxtap.wr_ihdr.it_present = htole32(IPW_RX_RADIOTAP_PRESENT);
262
263	sc->sc_txtap_len = sizeof sc->sc_txtapu;
264	sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
265	sc->sc_txtap.wt_ihdr.it_present = htole32(IPW_TX_RADIOTAP_PRESENT);
266#endif
267}
268
269static int
270ipw_detach(struct device* self, int flags)
271{
272	struct ipw_softc *sc = (struct ipw_softc *)self;
273	struct ifnet *ifp = &sc->sc_ic.ic_if;
274
275	ipw_reset(sc);
276
277#if NBPFILTER > 0
278	bpfdetach(ifp);
279#endif
280	ieee80211_ifdetach(ifp);
281	if_detach(ifp);
282
283	if (sc->sc_ih != NULL) {
284		pci_intr_disestablish(sc->sc_pct, sc->sc_ih);
285		sc->sc_ih = NULL;
286	}
287
288	bus_space_unmap(sc->sc_st, sc->sc_sh, sc->sc_sz);
289
290	return 0;
291}
292
293static int
294ipw_media_change(struct ifnet *ifp)
295{
296	int error;
297
298	error = ieee80211_media_change(ifp);
299	if (error != ENETRESET)
300		return error;
301
302	if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING))
303		ipw_init(ifp);
304
305	return 0;
306}
307
308static int
309ipw_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
310{
311	struct ipw_softc *sc = ic->ic_softc;
312	struct ieee80211_node *ni = ic->ic_bss;
313	u_int32_t val, len;
314
315	switch (nstate) {
316	case IEEE80211_S_RUN:
317		len = IEEE80211_NWID_LEN;
318		ipw_read_table2(sc, IPW_INFO_CURRENT_SSID, ni->ni_essid, &len);
319		ni->ni_esslen = len;
320
321		val = ipw_read_table1(sc, IPW_INFO_CURRENT_CHANNEL);
322		ni->ni_chan = &ic->ic_channels[val];
323
324		DELAY(100); /* firmware needs a short delay here */
325
326		len = IEEE80211_ADDR_LEN;
327		ipw_read_table2(sc, IPW_INFO_CURRENT_BSSID, ni->ni_bssid, &len);
328		break;
329
330	case IEEE80211_S_INIT:
331	case IEEE80211_S_SCAN:
332	case IEEE80211_S_AUTH:
333	case IEEE80211_S_ASSOC:
334		break;
335	}
336
337	ic->ic_state = nstate;
338	return 0;
339}
340
341static void
342ipw_command_intr(struct ipw_softc *sc, struct ipw_soft_buf *sbuf)
343{
344	struct ipw_cmd *cmd;
345
346	bus_dmamap_sync(sc->sc_dmat, sbuf->map, 0, sizeof (struct ipw_cmd),
347	    BUS_DMASYNC_POSTREAD);
348
349	cmd = mtod(sbuf->m, struct ipw_cmd *);
350
351	DPRINTFN(2, ("RX!CMD!%u!%u!%u!%u!%u\n",
352	    letoh32(cmd->type), letoh32(cmd->subtype), letoh32(cmd->seq),
353	    letoh32(cmd->len), letoh32(cmd->status)));
354
355	/*
356	 * Wake up processes waiting for command ack. In the case of the
357	 * IPW_CMD_DISABLE command, wake up the process only when the adapter
358	 * enters the IPW_STATE_DISABLED state. This is notified in
359	 * ipw_newstate_intr().
360	 */
361	if (letoh32(cmd->type) != IPW_CMD_DISABLE)
362		wakeup(sc->cmd);
363}
364
365static void
366ipw_newstate_intr(struct ipw_softc *sc, struct ipw_soft_buf *sbuf)
367{
368	struct ieee80211com *ic = &sc->sc_ic;
369	u_int32_t state;
370
371	bus_dmamap_sync(sc->sc_dmat, sbuf->map, 0, sizeof state,
372	    BUS_DMASYNC_POSTREAD);
373
374	state = letoh32(*mtod(sbuf->m, u_int32_t *));
375
376	DPRINTFN(2, ("RX!NEWSTATE!%u\n", state));
377
378	switch (state) {
379	case IPW_STATE_ASSOCIATED:
380		ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
381		break;
382
383	case IPW_STATE_SCANNING:
384		ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
385		break;
386
387	case IPW_STATE_ASSOCIATION_LOST:
388		ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
389		break;
390
391	case IPW_STATE_DISABLED:
392		wakeup(sc->cmd);
393		break;
394
395	case IPW_STATE_RADIO_DISABLED:
396		/* XXX should turn the interface down */
397		break;
398	}
399}
400
401static void
402ipw_data_intr(struct ipw_softc *sc, struct ipw_status *status,
403    struct ipw_soft_bd *sbd, struct ipw_soft_buf *sbuf)
404{
405	struct ieee80211com *ic = &sc->sc_ic;
406	struct ifnet *ifp = &ic->ic_if;
407	struct mbuf *m;
408	struct ieee80211_frame *wh;
409	struct ieee80211_node *ni;
410	int error;
411
412	DPRINTFN(5, ("RX!DATA!%u!%u\n", letoh32(status->len), status->rssi));
413
414	bus_dmamap_sync(sc->sc_dmat, sbuf->map, 0, letoh32(status->len),
415	    BUS_DMASYNC_POSTREAD);
416
417	bus_dmamap_unload(sc->sc_dmat, sbuf->map);
418
419	/* Finalize mbuf */
420	m = sbuf->m;
421	m->m_pkthdr.rcvif = ifp;
422	m->m_pkthdr.len = m->m_len = letoh32(status->len);
423
424#if NBPFILTER > 0
425	if (sc->sc_drvbpf != NULL) {
426		struct mbuf mb;
427		struct ipw_rx_radiotap_header *tap = &sc->sc_rxtap;
428
429		tap->wr_flags = 0;
430		tap->wr_antsignal = status->rssi;
431		tap->wr_chan_freq = htole16(ic->ic_bss->ni_chan->ic_freq);
432		tap->wr_chan_flags = htole16(ic->ic_bss->ni_chan->ic_flags);
433
434		M_DUP_PKTHDR(&mb, m);
435		mb.m_data = (caddr_t)tap;
436		mb.m_len = sc->sc_rxtap_len;
437		mb.m_next = m;
438		mb.m_pkthdr.len += mb.m_len;
439		bpf_mtap(sc->sc_drvbpf, &mb);
440	}
441#endif
442
443	wh = mtod(m, struct ieee80211_frame *);
444
445	ni = ieee80211_find_rxnode(ic, wh);
446
447	/* Send it up to the upper layer */
448	ieee80211_input(ifp, m, ni, status->rssi, 0);
449
450	if (ni == ic->ic_bss)
451		ieee80211_unref_node(&ni);
452	else
453		ieee80211_free_node(ic, ni);
454
455	MGETHDR(m, M_DONTWAIT, MT_DATA);
456	if (m == NULL) {
457		printf("%s: could not allocate rx mbuf\n",
458		    sc->sc_dev.dv_xname);
459		return;
460	}
461	MCLGET(m, M_DONTWAIT);
462	if (!(m->m_flags & M_EXT)) {
463		m_freem(m);
464		printf("%s: could not allocate rx mbuf cluster\n",
465		    sc->sc_dev.dv_xname);
466		return;
467	}
468
469	error = bus_dmamap_load(sc->sc_dmat, sbuf->map, mtod(m, void *),
470	    MCLBYTES, NULL, BUS_DMA_NOWAIT);
471	if (error != 0) {
472		printf("%s: could not map rxbuf dma memory\n",
473		    sc->sc_dev.dv_xname);
474		m_freem(m);
475		return;
476	}
477
478	sbuf->m = m;
479	sbd->bd->physaddr = htole32(sbuf->map->dm_segs[0].ds_addr);
480}
481
482static void
483ipw_notification_intr(struct ipw_softc *sc, struct ipw_soft_buf *sbuf)
484{
485	DPRINTFN(2, ("RX!NOTIFICATION\n"));
486}
487
488static void
489ipw_rx_intr(struct ipw_softc *sc)
490{
491	struct ipw_status *status;
492	struct ipw_soft_bd *sbd;
493	struct ipw_soft_buf *sbuf;
494	u_int32_t r, i;
495
496	r = CSR_READ_4(sc, IPW_CSR_RX_READ_INDEX);
497
498	for (i = (sc->rxcur + 1) % IPW_NRBD; i != r; i = (i + 1) % IPW_NRBD) {
499
500		bus_dmamap_sync(sc->sc_dmat, sc->rbd_map,
501		    i * sizeof (struct ipw_bd), sizeof (struct ipw_bd),
502		    BUS_DMASYNC_POSTREAD);
503
504		bus_dmamap_sync(sc->sc_dmat, sc->status_map,
505		    i * sizeof (struct ipw_status), sizeof (struct ipw_status),
506		    BUS_DMASYNC_POSTREAD);
507
508		status = &sc->status_list[i];
509		sbd = &sc->srbd_list[i];
510		sbuf = sbd->priv;
511
512		switch (letoh16(status->code) & 0xf) {
513		case IPW_STATUS_CODE_COMMAND:
514			ipw_command_intr(sc, sbuf);
515			break;
516
517		case IPW_STATUS_CODE_NEWSTATE:
518			ipw_newstate_intr(sc, sbuf);
519			break;
520
521		case IPW_STATUS_CODE_DATA_802_3:
522		case IPW_STATUS_CODE_DATA_802_11:
523			ipw_data_intr(sc, status, sbd, sbuf);
524			break;
525
526		case IPW_STATUS_CODE_NOTIFICATION:
527			ipw_notification_intr(sc, sbuf);
528			break;
529
530		default:
531			printf("%s: unknown status code %u\n",
532			    sc->sc_dev.dv_xname, letoh16(status->code));
533		}
534		sbd->bd->flags = 0;
535
536		bus_dmamap_sync(sc->sc_dmat, sc->rbd_map,
537		    i * sizeof (struct ipw_bd), sizeof (struct ipw_bd),
538		    BUS_DMASYNC_PREWRITE);
539	}
540
541	/* Tell the firmware what we have processed */
542	sc->rxcur = (r == 0) ? IPW_NRBD - 1 : r - 1;
543	CSR_WRITE_4(sc, IPW_CSR_RX_WRITE_INDEX, sc->rxcur);
544}
545
546static void
547ipw_release_sbd(struct ipw_softc *sc, struct ipw_soft_bd *sbd)
548{
549	struct ieee80211com *ic;
550	struct ipw_soft_hdr *shdr;
551	struct ipw_soft_buf *sbuf;
552
553	switch (sbd->type) {
554	case IPW_SBD_TYPE_COMMAND:
555		bus_dmamap_unload(sc->sc_dmat, sc->cmd_map);
556		break;
557
558	case IPW_SBD_TYPE_HEADER:
559		shdr = sbd->priv;
560		bus_dmamap_unload(sc->sc_dmat, shdr->map);
561		TAILQ_INSERT_TAIL(&sc->sc_free_shdr, shdr, next);
562		break;
563
564	case IPW_SBD_TYPE_DATA:
565		ic = &sc->sc_ic;
566		sbuf = sbd->priv;
567		bus_dmamap_unload(sc->sc_dmat, sbuf->map);
568		m_freem(sbuf->m);
569		if (sbuf->ni != NULL && sbuf->ni != ic->ic_bss)
570			ieee80211_free_node(ic, sbuf->ni);
571		/* kill watchdog timer */
572		sc->sc_tx_timer = 0;
573		TAILQ_INSERT_TAIL(&sc->sc_free_sbuf, sbuf, next);
574		break;
575	}
576	sbd->type = IPW_SBD_TYPE_NOASSOC;
577}
578
579static void
580ipw_tx_intr(struct ipw_softc *sc)
581{
582	struct ifnet *ifp = &sc->sc_ic.ic_if;
583	u_int32_t r, i;
584
585	r = CSR_READ_4(sc, IPW_CSR_TX_READ_INDEX);
586
587	for (i = (sc->txold + 1) % IPW_NTBD; i != r; i = (i + 1) % IPW_NTBD)
588		ipw_release_sbd(sc, &sc->stbd_list[i]);
589
590	/* Remember what the firmware has processed */
591	sc->txold = (r == 0) ? IPW_NTBD - 1 : r - 1;
592
593	/* Call start() since some buffer descriptors have been released */
594	ifp->if_flags &= ~IFF_OACTIVE;
595	(*ifp->if_start)(ifp);
596}
597
598static int
599ipw_intr(void *arg)
600{
601	struct ipw_softc *sc = arg;
602	u_int32_t r;
603
604	if ((r = CSR_READ_4(sc, IPW_CSR_INTR)) == 0)
605		return 0;
606
607	/* Disable interrupts */
608	CSR_WRITE_4(sc, IPW_CSR_INTR_MASK, 0);
609
610	DPRINTFN(8, ("INTR!0x%08x\n", r));
611
612	if (r & IPW_INTR_RX_TRANSFER)
613		ipw_rx_intr(sc);
614
615	if (r & IPW_INTR_TX_TRANSFER)
616		ipw_tx_intr(sc);
617
618	if (r & IPW_INTR_FW_INIT_DONE) {
619		if (!(r & (IPW_INTR_FATAL_ERROR | IPW_INTR_PARITY_ERROR)))
620			wakeup(sc);
621	}
622
623	/* Acknowledge interrupts */
624	CSR_WRITE_4(sc, IPW_CSR_INTR, r);
625
626	/* Re-enable interrupts */
627	CSR_WRITE_4(sc, IPW_CSR_INTR_MASK, IPW_INTR_MASK);
628
629	return 0;
630}
631
632static int
633ipw_cmd(struct ipw_softc *sc, u_int32_t type, void *data, u_int32_t len)
634{
635	struct ipw_soft_bd *sbd;
636	int error;
637
638	sbd = &sc->stbd_list[sc->txcur];
639
640	error = bus_dmamap_load(sc->sc_dmat, sc->cmd_map, sc->cmd,
641	    sizeof (struct ipw_cmd), NULL, BUS_DMA_NOWAIT);
642	if (error != 0) {
643		printf("%s: could not map cmd dma memory\n",
644		    sc->sc_dev.dv_xname);
645		return error;
646	}
647
648	sc->cmd->type = htole32(type);
649	sc->cmd->subtype = htole32(0);
650	sc->cmd->len = htole32(len);
651	sc->cmd->seq = htole32(0);
652	if (data != NULL)
653		bcopy(data, sc->cmd->data, len);
654
655	sbd->type = IPW_SBD_TYPE_COMMAND;
656	sbd->bd->physaddr = htole32(sc->cmd_map->dm_segs[0].ds_addr);
657	sbd->bd->len = htole32(sizeof (struct ipw_cmd));
658	sbd->bd->nfrag = 1;
659	sbd->bd->flags = IPW_BD_FLAG_TX_FRAME_COMMAND |
660			 IPW_BD_FLAG_TX_LAST_FRAGMENT;
661
662	bus_dmamap_sync(sc->sc_dmat, sc->cmd_map, 0, sizeof (struct ipw_cmd),
663	    BUS_DMASYNC_PREWRITE);
664
665	bus_dmamap_sync(sc->sc_dmat, sc->tbd_map,
666	    sc->txcur * sizeof (struct ipw_bd), sizeof (struct ipw_bd),
667	    BUS_DMASYNC_PREWRITE);
668
669	sc->txcur = (sc->txcur + 1) % IPW_NTBD;
670	CSR_WRITE_4(sc, IPW_CSR_TX_WRITE_INDEX, sc->txcur);
671
672	DPRINTFN(2, ("TX!CMD!%u!%u!%u!%u\n", type, 0, 0, len));
673
674	/* Wait at most two seconds for command to complete */
675	return tsleep(sc->cmd, 0, "ipwcmd", 2 * hz);
676}
677
678static int
679ipw_tx_start(struct ifnet *ifp, struct mbuf *m, struct ieee80211_node *ni)
680{
681	struct ipw_softc *sc = ifp->if_softc;
682	struct ieee80211com *ic = &sc->sc_ic;
683	struct ieee80211_frame *wh;
684	struct ipw_soft_bd *sbd;
685	struct ipw_soft_hdr *shdr;
686	struct ipw_soft_buf *sbuf;
687	int error, i;
688
689	if (ic->ic_flags & IEEE80211_F_WEPON) {
690		m = ieee80211_wep_crypt(ifp, m, 1);
691		if (m == NULL)
692			return ENOBUFS;
693	}
694
695#if NBPFILTER > 0
696	if (sc->sc_drvbpf != NULL) {
697		struct mbuf mb;
698		struct ipw_tx_radiotap_header *tap = &sc->sc_txtap;
699
700		tap->wt_flags = 0;
701		tap->wt_chan_freq = htole16(ic->ic_bss->ni_chan->ic_freq);
702		tap->wt_chan_flags = htole16(ic->ic_bss->ni_chan->ic_flags);
703
704		M_DUP_PKTHDR(&mb, m);
705		mb.m_data = (caddr_t)tap;
706		mb.m_len = sc->sc_txtap_len;
707		mb.m_next = m;
708		mb.m_pkthdr.len += mb.m_len;
709		bpf_mtap(sc->sc_drvbpf, &mb);
710	}
711#endif
712
713	wh = mtod(m, struct ieee80211_frame *);
714
715	shdr = TAILQ_FIRST(&sc->sc_free_shdr);
716	sbuf = TAILQ_FIRST(&sc->sc_free_sbuf);
717
718	shdr->hdr.type = htole32(IPW_HDR_TYPE_SEND);
719	shdr->hdr.subtype = htole32(0);
720	shdr->hdr.encrypted = (wh->i_fc[1] & IEEE80211_FC1_WEP) ? 1 : 0;
721	shdr->hdr.encrypt = 0;
722	shdr->hdr.keyidx = 0;
723	shdr->hdr.keysz = 0;
724	shdr->hdr.fragmentsz = htole16(0);
725	IEEE80211_ADDR_COPY(shdr->hdr.src_addr, wh->i_addr2);
726	if (ic->ic_opmode == IEEE80211_M_STA)
727		IEEE80211_ADDR_COPY(shdr->hdr.dst_addr, wh->i_addr3);
728	else
729		IEEE80211_ADDR_COPY(shdr->hdr.dst_addr, wh->i_addr1);
730
731	/* trim IEEE802.11 header */
732	m_adj(m, sizeof (struct ieee80211_frame));
733
734	/*
735	 * We need to map the mbuf first to know how many buffer descriptors
736	 * are needed for this transfer.
737	 */
738	error = bus_dmamap_load_mbuf(sc->sc_dmat, sbuf->map, m, BUS_DMA_NOWAIT);
739	if (error != 0) {
740		printf("%s: could not map mbuf (error %d)\n",
741		    sc->sc_dev.dv_xname, error);
742		m_freem(m);
743		return error;
744	}
745
746	error = bus_dmamap_load(sc->sc_dmat, shdr->map, &shdr->hdr,
747	    sizeof (struct ipw_hdr), NULL, BUS_DMA_NOWAIT);
748	if (error != 0) {
749		printf("%s: could not map header (error %d)\n",
750		    sc->sc_dev.dv_xname, error);
751		bus_dmamap_unload(sc->sc_dmat, sbuf->map);
752		m_freem(m);
753		return error;
754	}
755
756	TAILQ_REMOVE(&sc->sc_free_sbuf, sbuf, next);
757	TAILQ_REMOVE(&sc->sc_free_shdr, shdr, next);
758
759	sbd = &sc->stbd_list[sc->txcur];
760	sbd->type = IPW_SBD_TYPE_HEADER;
761	sbd->priv = shdr;
762	sbd->bd->physaddr = htole32(shdr->map->dm_segs[0].ds_addr);
763	sbd->bd->len = htole32(sizeof (struct ipw_hdr));
764	sbd->bd->nfrag = 1 + sbuf->map->dm_nsegs;
765	sbd->bd->flags = IPW_BD_FLAG_TX_FRAME_802_3 |
766			 IPW_BD_FLAG_TX_NOT_LAST_FRAGMENT;
767
768	DPRINTFN(5, ("TX!HDR!%u!%u!%u!%u", shdr->hdr.type, shdr->hdr.subtype,
769	    shdr->hdr.encrypted, shdr->hdr.encrypt));
770	DPRINTFN(5, ("!%s", ether_sprintf(shdr->hdr.src_addr)));
771	DPRINTFN(5, ("!%s\n", ether_sprintf(shdr->hdr.dst_addr)));
772
773	bus_dmamap_sync(sc->sc_dmat, sc->tbd_map,
774	    sc->txcur * sizeof (struct ipw_bd),
775	    sizeof (struct ipw_bd), BUS_DMASYNC_PREWRITE);
776
777	sc->txcur = (sc->txcur + 1) % IPW_NTBD;
778
779	sbuf->m = m;
780	sbuf->ni = ni;
781
782	for (i = 0; i < sbuf->map->dm_nsegs; i++) {
783		sbd = &sc->stbd_list[sc->txcur];
784		sbd->bd->physaddr = htole32(sbuf->map->dm_segs[i].ds_addr);
785		sbd->bd->len = htole32(sbuf->map->dm_segs[i].ds_len);
786		sbd->bd->nfrag = 0; /* used only in first bd */
787		sbd->bd->flags = IPW_BD_FLAG_TX_FRAME_802_3;
788		if (i == sbuf->map->dm_nsegs - 1) {
789			sbd->type = IPW_SBD_TYPE_DATA;
790			sbd->priv = sbuf;
791			sbd->bd->flags |= IPW_BD_FLAG_TX_LAST_FRAGMENT;
792		} else {
793			sbd->type = IPW_SBD_TYPE_NOASSOC;
794			sbd->bd->flags |= IPW_BD_FLAG_TX_NOT_LAST_FRAGMENT;
795		}
796
797		DPRINTFN(5, ("TX!FRAG!%d!%d\n", i,
798		    sbuf->map->dm_segs[i].ds_len));
799
800		bus_dmamap_sync(sc->sc_dmat, sc->tbd_map,
801		    sc->txcur * sizeof (struct ipw_bd),
802		    sizeof (struct ipw_bd), BUS_DMASYNC_PREWRITE);
803
804		sc->txcur = (sc->txcur + 1) % IPW_NTBD;
805	}
806
807	bus_dmamap_sync(sc->sc_dmat, shdr->map, 0, sizeof (struct ipw_hdr),
808	    BUS_DMASYNC_PREWRITE);
809
810	bus_dmamap_sync(sc->sc_dmat, sbuf->map, 0, MCLBYTES,
811	    BUS_DMASYNC_PREWRITE);
812
813	/* Inform firmware about this new packet */
814	CSR_WRITE_4(sc, IPW_CSR_TX_WRITE_INDEX, sc->txcur);
815
816	return 0;
817}
818
819static void
820ipw_start(struct ifnet *ifp)
821{
822	struct ipw_softc *sc = ifp->if_softc;
823	struct ieee80211com *ic = &sc->sc_ic;
824	struct mbuf *m;
825	struct ieee80211_node *ni;
826
827	for (;;) {
828		IF_DEQUEUE(&ifp->if_snd, m);
829		if (m == NULL)
830			break;
831
832#if NBPFILTER > 0
833		if (ifp->if_bpf != NULL)
834			bpf_mtap(ifp->if_bpf, m);
835#endif
836
837		m = ieee80211_encap(ifp, m, &ni);
838		if (m == NULL)
839			continue;
840
841#if NBPFILTER > 0
842		if (ic->ic_rawbpf != NULL)
843			bpf_mtap(ic->ic_rawbpf, m);
844#endif
845
846		if (ipw_tx_start(ifp, m, ni) != 0) {
847			if (ni != NULL && ni != ic->ic_bss)
848				ieee80211_free_node(ic, ni);
849			break;
850		}
851
852		/* start watchdog timer */
853		sc->sc_tx_timer = 5;
854		ifp->if_timer = 1;
855	}
856}
857
858static void
859ipw_watchdog(struct ifnet *ifp)
860{
861	struct ipw_softc *sc = ifp->if_softc;
862
863	ifp->if_timer = 0;
864
865	if (sc->sc_tx_timer > 0) {
866		if (--sc->sc_tx_timer == 0) {
867			printf("%s: device timeout\n", sc->sc_dev.dv_xname);
868#ifdef notyet
869			ipw_init(ifp);
870#endif
871			return;
872		}
873		ifp->if_timer = 1;
874	}
875
876	ieee80211_watchdog(ifp);
877}
878
879static int
880ipw_get_table1(struct ipw_softc *sc, u_int32_t *tbl)
881{
882	u_int32_t addr, data, size, i;
883
884	if (!(sc->flags & IPW_FLAG_FW_INITED))
885		return ENOTTY;
886
887	CSR_WRITE_4(sc, IPW_CSR_AUTOINC_ADDR, sc->table1_base);
888
889	size = CSR_READ_4(sc, IPW_CSR_AUTOINC_DATA);
890	if (copyout(&size, tbl, sizeof size) != 0)
891		return EFAULT;
892
893	for (i = 1, ++tbl; i < size; i++, tbl++) {
894		addr = CSR_READ_4(sc, IPW_CSR_AUTOINC_DATA);
895		data = MEM_READ_4(sc, addr);
896		if (copyout(&data, tbl, sizeof data) != 0)
897			return EFAULT;
898	}
899	return 0;
900}
901
902static int
903ipw_get_radio(struct ipw_softc *sc, int *ret)
904{
905	u_int32_t addr;
906	int val;
907
908	if (!(sc->flags & IPW_FLAG_FW_INITED))
909		return ENOTTY;
910
911	addr = ipw_read_table1(sc, IPW_INFO_EEPROM_ADDRESS);
912	if ((MEM_READ_4(sc, addr + 32) >> 24) & 1) {
913		val = -1;
914		copyout(&val, ret, sizeof val);
915		return 0;
916	}
917
918	if (CSR_READ_4(sc, IPW_CSR_IO) & IPW_IO_RADIO_DISABLED)
919		val = 0;
920	else
921		val = 1;
922
923	copyout(&val, ret, sizeof val);
924
925	return 0;
926}
927
928static int
929ipw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
930{
931	struct ipw_softc *sc = ifp->if_softc;
932	struct ifreq *ifr;
933	struct ifaddr *ifa;
934	int s, error = 0;
935
936	s = splnet();
937
938	switch (cmd) {
939	case SIOCSIFADDR:
940		ifa = (struct ifaddr *) data;
941		ifp->if_flags |= IFF_UP;
942		switch (ifa->ifa_addr->sa_family) {
943#ifdef INET
944		case AF_INET:
945			arp_ifinit(&sc->sc_ic.ic_ac, ifa);
946			ipw_init(ifp);
947			break;
948#endif
949		default:
950			ipw_init(ifp);
951		}
952		break;
953
954	case SIOCSIFFLAGS:
955		if (ifp->if_flags & IFF_UP) {
956			if (!(ifp->if_flags & IFF_RUNNING))
957				ipw_init(ifp);
958		} else {
959			if (ifp->if_flags & IFF_RUNNING)
960				ipw_stop(ifp, 1);
961		}
962		break;
963
964	case SIOCGTABLE1:
965		ifr = (struct ifreq *)data;
966		error = ipw_get_table1(sc, (u_int32_t *)ifr->ifr_data);
967		break;
968
969	case SIOCGRADIO:
970		ifr = (struct ifreq *)data;
971		error = ipw_get_radio(sc, (int *)ifr->ifr_data);
972		break;
973
974	case SIOCSLOADFW:
975		/* only super-user can do that! */
976		if ((error = suser(curproc, 0)) != 0)
977			break;
978
979		ifr = (struct ifreq *)data;
980		error = ipw_firmware_init(sc, (u_char *)ifr->ifr_data);
981		break;
982
983	case SIOCSKILLFW:
984		/* only super-user can do that! */
985		if ((error = suser(curproc, 0)) != 0)
986			break;
987
988		ipw_reset(sc);
989		break;
990
991	default:
992		error = ieee80211_ioctl(ifp, cmd, data);
993		if (error != ENETRESET)
994			break;
995
996		if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
997		    (IFF_UP | IFF_RUNNING))
998			ipw_init(ifp);
999		error = 0;
1000	}
1001
1002	splx(s);
1003	return error;
1004}
1005
1006static u_int32_t
1007ipw_read_table1(struct ipw_softc *sc, u_int32_t off)
1008{
1009	return MEM_READ_4(sc, MEM_READ_4(sc, sc->table1_base + off));
1010}
1011
1012static void
1013ipw_write_table1(struct ipw_softc *sc, u_int32_t off, u_int32_t info)
1014{
1015	MEM_WRITE_4(sc, MEM_READ_4(sc, sc->table1_base + off), info);
1016}
1017
1018static int
1019ipw_read_table2(struct ipw_softc *sc, u_int32_t off, void *buf, u_int32_t *len)
1020{
1021	u_int32_t addr, info;
1022	u_int16_t count, size;
1023	u_int32_t total;
1024
1025	/* addr[4] + count[2] + size[2] */
1026	addr = MEM_READ_4(sc, sc->table2_base + off);
1027	info = MEM_READ_4(sc, sc->table2_base + off + 4);
1028
1029	count = info >> 16;
1030	size = info & 0xffff;
1031	total = count * size;
1032
1033	if (total > *len) {
1034		*len = total;
1035		return EINVAL;
1036	}
1037
1038	*len = total;
1039	ipw_read_mem_1(sc, addr, buf, total);
1040
1041	return 0;
1042}
1043
1044static int
1045ipw_tx_init(struct ipw_softc *sc)
1046{
1047	char *errmsg;
1048	struct ipw_bd *bd;
1049	struct ipw_soft_bd *sbd;
1050	struct ipw_soft_hdr *shdr;
1051	struct ipw_soft_buf *sbuf;
1052	int error, i, nsegs;
1053
1054	/* Allocate transmission buffer descriptors */
1055	error = bus_dmamap_create(sc->sc_dmat, IPW_TBD_SZ, 1, IPW_TBD_SZ, 0,
1056	    BUS_DMA_NOWAIT, &sc->tbd_map);
1057	if (error != 0) {
1058		errmsg = "could not create tbd dma map";
1059		goto fail;
1060	}
1061
1062	error = bus_dmamem_alloc(sc->sc_dmat, IPW_TBD_SZ, PAGE_SIZE, 0,
1063	    &sc->tbd_seg, 1, &nsegs, BUS_DMA_NOWAIT);
1064	if (error != 0) {
1065		errmsg = "could not allocate tbd dma memory";
1066		goto fail;
1067	}
1068
1069	error = bus_dmamem_map(sc->sc_dmat, &sc->tbd_seg, nsegs, IPW_TBD_SZ,
1070	    (caddr_t *)&sc->tbd_list, BUS_DMA_NOWAIT);
1071	if (error != 0) {
1072		errmsg = "could not map tbd dma memory";
1073		goto fail;
1074	}
1075
1076	error = bus_dmamap_load(sc->sc_dmat, sc->tbd_map, sc->tbd_list,
1077	    IPW_TBD_SZ, NULL, BUS_DMA_NOWAIT);
1078	if (error != 0) {
1079		errmsg = "could not load tbd dma memory";
1080		goto fail;
1081	}
1082
1083	sc->stbd_list = malloc(IPW_NTBD * sizeof (struct ipw_soft_bd),
1084	    M_DEVBUF, M_NOWAIT);
1085	if (sc->stbd_list == NULL) {
1086		errmsg = "could not allocate soft tbd";
1087		error = ENOMEM;
1088		goto fail;
1089	}
1090	sbd = sc->stbd_list;
1091	bd = sc->tbd_list;
1092	for (i = 0; i < IPW_NTBD; i++, sbd++, bd++) {
1093		sbd->type = IPW_SBD_TYPE_NOASSOC;
1094		sbd->bd = bd;
1095	}
1096
1097	CSR_WRITE_4(sc, IPW_CSR_TX_BD_BASE, sc->tbd_map->dm_segs[0].ds_addr);
1098	CSR_WRITE_4(sc, IPW_CSR_TX_BD_SIZE, IPW_NTBD);
1099	CSR_WRITE_4(sc, IPW_CSR_TX_READ_INDEX, 0);
1100	CSR_WRITE_4(sc, IPW_CSR_TX_WRITE_INDEX, 0);
1101	sc->txold = IPW_NTBD - 1; /* latest bd index ack'ed by firmware */
1102	sc->txcur = 0; /* bd index to write to */
1103
1104	/* Allocate a DMA-able command */
1105	error = bus_dmamap_create(sc->sc_dmat, sizeof (struct ipw_cmd), 1,
1106	    sizeof (struct ipw_cmd), 0, BUS_DMA_NOWAIT, &sc->cmd_map);
1107	if (error != 0) {
1108		errmsg = "could not create cmd dma map";
1109		goto fail;
1110	}
1111
1112	error = bus_dmamem_alloc(sc->sc_dmat, sizeof (struct ipw_cmd),
1113	    PAGE_SIZE, 0, &sc->cmd_seg, 1, &nsegs, BUS_DMA_NOWAIT);
1114	if (error != 0) {
1115		errmsg = "could not allocate cmd dma memory";
1116		goto fail;
1117	}
1118
1119	error = bus_dmamem_map(sc->sc_dmat, &sc->cmd_seg, nsegs,
1120	    sizeof (struct ipw_cmd), (caddr_t *)&sc->cmd, BUS_DMA_NOWAIT);
1121	if (error != 0) {
1122		errmsg = "could not map cmd dma memory";
1123		goto fail;
1124	}
1125
1126	/* Allocate a pool of DMA-able headers */
1127	sc->shdr_list = malloc(IPW_NDATA * sizeof (struct ipw_soft_hdr),
1128	    M_DEVBUF, M_NOWAIT);
1129	if (sc->shdr_list == NULL) {
1130		errmsg = "could not allocate soft hdr";
1131		error = ENOMEM;
1132		goto fail;
1133	}
1134	TAILQ_INIT(&sc->sc_free_shdr);
1135	for (i = 0, shdr = sc->shdr_list; i < IPW_NDATA; i++, shdr++) {
1136		error = bus_dmamap_create(sc->sc_dmat,
1137		    sizeof (struct ipw_soft_hdr), 1,
1138	 	    sizeof (struct ipw_soft_hdr), 0, BUS_DMA_NOWAIT,
1139		    &shdr->map);
1140		if (error != 0) {
1141			errmsg = "could not create hdr dma map";
1142			goto fail;
1143		}
1144		TAILQ_INSERT_TAIL(&sc->sc_free_shdr, shdr, next);
1145	}
1146
1147	/* Allocate a pool of DMA-able buffers */
1148	sc->tx_sbuf_list = malloc(IPW_NDATA * sizeof (struct ipw_soft_buf),
1149	    M_DEVBUF, M_NOWAIT);
1150	if (sc->tx_sbuf_list == NULL) {
1151		errmsg = "could not allocate soft txbuf";
1152		error = ENOMEM;
1153		goto fail;
1154	}
1155	TAILQ_INIT(&sc->sc_free_sbuf);
1156	for (i = 0, sbuf = sc->tx_sbuf_list; i < IPW_NDATA; i++, sbuf++) {
1157		error = bus_dmamap_create(sc->sc_dmat, IPW_NDATA * MCLBYTES,
1158		    IPW_NDATA, MCLBYTES, 0, BUS_DMA_NOWAIT, &sbuf->map);
1159		if (error != 0) {
1160			errmsg = "could not create txbuf dma map";
1161			goto fail;
1162		}
1163		TAILQ_INSERT_TAIL(&sc->sc_free_sbuf, sbuf, next);
1164	}
1165
1166	return 0;
1167
1168fail:	printf("%s: %s\n", sc->sc_dev.dv_xname, errmsg);
1169	ipw_tx_stop(sc);
1170
1171	return error;
1172}
1173
1174static void
1175ipw_tx_stop(struct ipw_softc *sc)
1176{
1177	struct ipw_soft_hdr *shdr;
1178	struct ipw_soft_buf *sbuf;
1179	int i;
1180
1181	if (sc->tbd_map != NULL) {
1182		if (sc->tbd_list != NULL) {
1183			bus_dmamap_unload(sc->sc_dmat, sc->tbd_map);
1184			bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->tbd_list,
1185			    IPW_TBD_SZ);
1186			bus_dmamem_free(sc->sc_dmat, &sc->tbd_seg, 1);
1187			sc->tbd_list = NULL;
1188		}
1189		bus_dmamap_destroy(sc->sc_dmat, sc->tbd_map);
1190		sc->tbd_map = NULL;
1191	}
1192
1193	if (sc->stbd_list != NULL) {
1194		for (i = 0; i < IPW_NTBD; i++)
1195			ipw_release_sbd(sc, &sc->stbd_list[i]);
1196		free(sc->stbd_list, M_DEVBUF);
1197		sc->stbd_list = NULL;
1198	}
1199
1200	if (sc->cmd_map != NULL) {
1201		if (sc->cmd != NULL) {
1202			bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->cmd,
1203			    sizeof (struct ipw_cmd));
1204			bus_dmamem_free(sc->sc_dmat, &sc->cmd_seg, 1);
1205			sc->cmd = NULL;
1206		}
1207		bus_dmamap_destroy(sc->sc_dmat, sc->cmd_map);
1208		sc->cmd_map = NULL;
1209	}
1210
1211	if (sc->shdr_list != NULL) {
1212		TAILQ_FOREACH(shdr, &sc->sc_free_shdr, next)
1213			bus_dmamap_destroy(sc->sc_dmat, shdr->map);
1214		free(sc->shdr_list, M_DEVBUF);
1215		sc->shdr_list = NULL;
1216	}
1217
1218
1219	if (sc->tx_sbuf_list != NULL) {
1220		TAILQ_FOREACH(sbuf, &sc->sc_free_sbuf, next)
1221			bus_dmamap_destroy(sc->sc_dmat, sbuf->map);
1222		free(sc->tx_sbuf_list, M_DEVBUF);
1223		sc->tx_sbuf_list = NULL;
1224	}
1225}
1226
1227static int
1228ipw_rx_init(struct ipw_softc *sc)
1229{
1230	char *errmsg;
1231	struct ipw_bd *bd;
1232	struct ipw_soft_bd *sbd;
1233	struct ipw_soft_buf *sbuf;
1234	int error, i, nsegs;
1235
1236	/* Allocate reception buffer descriptors */
1237	error = bus_dmamap_create(sc->sc_dmat, IPW_RBD_SZ, 1, IPW_RBD_SZ, 0,
1238	    BUS_DMA_NOWAIT, &sc->rbd_map);
1239	if (error != 0) {
1240		errmsg = "could not create rbd dma map";
1241		goto fail;
1242	}
1243
1244	error = bus_dmamem_alloc(sc->sc_dmat, IPW_RBD_SZ, PAGE_SIZE, 0,
1245	    &sc->rbd_seg, 1, &nsegs, BUS_DMA_NOWAIT);
1246	if (error != 0) {
1247		errmsg = "could not allocate rbd dma memory";
1248		goto fail;
1249	}
1250
1251	error = bus_dmamem_map(sc->sc_dmat, &sc->rbd_seg, nsegs, IPW_RBD_SZ,
1252	    (caddr_t *)&sc->rbd_list, BUS_DMA_NOWAIT);
1253	if (error != 0) {
1254		errmsg = "could not map rbd dma memory";
1255		goto fail;
1256	}
1257
1258	error = bus_dmamap_load(sc->sc_dmat, sc->rbd_map, sc->rbd_list,
1259	    IPW_RBD_SZ, NULL, BUS_DMA_NOWAIT);
1260	if (error != 0) {
1261		errmsg = "could not load rbd dma memory";
1262		goto fail;
1263	}
1264
1265	sc->srbd_list = malloc(IPW_NRBD * sizeof (struct ipw_soft_bd),
1266	    M_DEVBUF, M_NOWAIT);
1267	if (sc->srbd_list == NULL) {
1268		errmsg = "could not allocate soft rbd";
1269		error = ENOMEM;
1270		goto fail;
1271	}
1272	sbd = sc->srbd_list;
1273	bd = sc->rbd_list;
1274	for (i = 0; i < IPW_NRBD; i++, sbd++, bd++) {
1275		sbd->type = IPW_SBD_TYPE_NOASSOC;
1276		sbd->bd = bd;
1277	}
1278
1279	CSR_WRITE_4(sc, IPW_CSR_RX_BD_BASE, sc->rbd_map->dm_segs[0].ds_addr);
1280	CSR_WRITE_4(sc, IPW_CSR_RX_BD_SIZE, IPW_NRBD);
1281	CSR_WRITE_4(sc, IPW_CSR_RX_READ_INDEX, 0);
1282	CSR_WRITE_4(sc, IPW_CSR_RX_WRITE_INDEX, IPW_NRBD - 1);
1283	sc->rxcur = IPW_NRBD - 1; /* latest bd index I've read */
1284
1285	/* Allocate status descriptors */
1286	error = bus_dmamap_create(sc->sc_dmat, IPW_STATUS_SZ, 1, IPW_STATUS_SZ,
1287	    0, BUS_DMA_NOWAIT, &sc->status_map);
1288	if (error != 0) {
1289		errmsg = "could not create status dma map";
1290		goto fail;
1291	}
1292
1293	error = bus_dmamem_alloc(sc->sc_dmat, IPW_STATUS_SZ, PAGE_SIZE, 0,
1294	    &sc->status_seg, 1, &nsegs, BUS_DMA_NOWAIT);
1295	if (error != 0) {
1296		errmsg = "could not allocate status dma memory";
1297		goto fail;
1298	}
1299
1300	error = bus_dmamem_map(sc->sc_dmat, &sc->status_seg, nsegs,
1301	    IPW_STATUS_SZ, (caddr_t *)&sc->status_list, BUS_DMA_NOWAIT);
1302	if (error != 0) {
1303		errmsg = "could not map status dma memory";
1304		goto fail;
1305	}
1306
1307	error = bus_dmamap_load(sc->sc_dmat, sc->status_map, sc->status_list,
1308	    IPW_STATUS_SZ, NULL, BUS_DMA_NOWAIT);
1309	if (error != 0) {
1310		errmsg = "could not load status dma memory";
1311		goto fail;
1312	}
1313
1314	CSR_WRITE_4(sc, IPW_CSR_RX_STATUS_BASE,
1315	    sc->status_map->dm_segs[0].ds_addr);
1316
1317	sc->rx_sbuf_list = malloc(IPW_NRBD * sizeof (struct ipw_soft_buf),
1318	    M_DEVBUF, M_NOWAIT);
1319	if (sc->rx_sbuf_list == NULL) {
1320		errmsg = "could not allocate soft rxbuf";
1321		error = ENOMEM;
1322		goto fail;
1323	}
1324
1325	sbuf = sc->rx_sbuf_list;
1326	sbd = sc->srbd_list;
1327	for (i = 0; i < IPW_NRBD; i++, sbuf++, sbd++) {
1328
1329		MGETHDR(sbuf->m, M_DONTWAIT, MT_DATA);
1330		if (sbuf->m == NULL) {
1331			errmsg = "could not allocate rx mbuf";
1332			error = ENOMEM;
1333			goto fail;
1334		}
1335		MCLGET(sbuf->m, M_DONTWAIT);
1336		if (!(sbuf->m->m_flags & M_EXT)) {
1337			m_freem(sbuf->m);
1338			errmsg = "could not allocate rx mbuf cluster";
1339			error = ENOMEM;
1340			goto fail;
1341		}
1342
1343		error = bus_dmamap_create(sc->sc_dmat, IPW_NRBD * MCLBYTES,
1344		    IPW_NRBD, MCLBYTES, 0, BUS_DMA_NOWAIT, &sbuf->map);
1345		if (error != 0) {
1346			m_freem(sbuf->m);
1347			errmsg = "could not create rxbuf dma map";
1348			goto fail;
1349		}
1350		error = bus_dmamap_load(sc->sc_dmat, sbuf->map,
1351		    mtod(sbuf->m, void *), MCLBYTES, NULL, BUS_DMA_NOWAIT);
1352		if (error != 0) {
1353			bus_dmamap_destroy(sc->sc_dmat, sbuf->map);
1354			m_freem(sbuf->m);
1355			errmsg = "could not map rxbuf dma memory";
1356			goto fail;
1357		}
1358		sbd->type = IPW_SBD_TYPE_DATA;
1359		sbd->priv = sbuf;
1360		sbd->bd->physaddr = htole32(sbuf->map->dm_segs[0].ds_addr);
1361		sbd->bd->len = htole32(MCLBYTES);
1362	}
1363
1364	return 0;
1365
1366fail:	printf("%s: %s\n", sc->sc_dev.dv_xname, errmsg);
1367	ipw_rx_stop(sc);
1368
1369	return error;
1370}
1371
1372static void
1373ipw_rx_stop(struct ipw_softc *sc)
1374{
1375	struct ipw_soft_bd *sbd;
1376	struct ipw_soft_buf *sbuf;
1377	int i;
1378
1379	if (sc->rbd_map != NULL) {
1380		if (sc->rbd_list != NULL) {
1381			bus_dmamap_unload(sc->sc_dmat, sc->rbd_map);
1382			bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->rbd_list,
1383			    IPW_RBD_SZ);
1384			bus_dmamem_free(sc->sc_dmat, &sc->rbd_seg, 1);
1385			sc->rbd_list = NULL;
1386		}
1387		bus_dmamap_destroy(sc->sc_dmat, sc->rbd_map);
1388		sc->rbd_map = NULL;
1389	}
1390
1391	if (sc->status_map != NULL) {
1392		if (sc->status_list != NULL) {
1393			bus_dmamap_unload(sc->sc_dmat, sc->status_map);
1394			bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->status_list,
1395			    IPW_STATUS_SZ);
1396			bus_dmamem_free(sc->sc_dmat, &sc->status_seg, 1);
1397			sc->status_list = NULL;
1398		}
1399		bus_dmamap_destroy(sc->sc_dmat, sc->status_map);
1400		sc->status_map = NULL;
1401	}
1402
1403	if (sc->srbd_list != NULL) {
1404		for (i = 0, sbd = sc->srbd_list; i < IPW_NRBD; i++, sbd++) {
1405			if (sbd->type == IPW_SBD_TYPE_NOASSOC)
1406				continue;
1407
1408			sbuf = sbd->priv;
1409			bus_dmamap_unload(sc->sc_dmat, sbuf->map);
1410			bus_dmamap_destroy(sc->sc_dmat, sbuf->map);
1411			m_freem(sbuf->m);
1412		}
1413		free(sc->srbd_list, M_DEVBUF);
1414		sc->srbd_list = NULL;
1415	}
1416
1417	if (sc->rx_sbuf_list != NULL) {
1418		free(sc->rx_sbuf_list, M_DEVBUF);
1419		sc->rx_sbuf_list = NULL;
1420	}
1421}
1422
1423static void
1424ipw_reset(struct ipw_softc *sc)
1425{
1426	struct ifnet *ifp = &sc->sc_ic.ic_if;
1427	int ntries;
1428
1429	ipw_stop(ifp, 1);
1430
1431	if (sc->flags & IPW_FLAG_FW_INITED) {
1432		ipw_cmd(sc, IPW_CMD_DISABLE_PHY, NULL, 0);
1433		ipw_cmd(sc, IPW_CMD_PREPARE_POWER_DOWN, NULL, 0);
1434
1435		sc->flags &= ~IPW_FLAG_FW_INITED;
1436	}
1437
1438	/* Disable interrupts */
1439	CSR_WRITE_4(sc, IPW_CSR_INTR_MASK, 0);
1440
1441	CSR_WRITE_4(sc, IPW_CSR_RST, IPW_RST_STOP_MASTER);
1442	for (ntries = 0; ntries < 5; ntries++) {
1443		if (CSR_READ_4(sc, IPW_CSR_RST) & IPW_RST_MASTER_DISABLED)
1444			break;
1445		DELAY(10);
1446	}
1447
1448	CSR_WRITE_4(sc, IPW_CSR_RST, IPW_RST_SW_RESET);
1449
1450	ipw_rx_stop(sc);
1451	ipw_tx_stop(sc);
1452
1453	ifp->if_flags &= ~IFF_UP;
1454}
1455
1456static int
1457ipw_clock_sync(struct ipw_softc *sc)
1458{
1459	int ntries;
1460	u_int32_t r;
1461
1462	CSR_WRITE_4(sc, IPW_CSR_RST, IPW_RST_SW_RESET);
1463	for (ntries = 0; ntries < 1000; ntries++) {
1464		if (CSR_READ_4(sc, IPW_CSR_RST) & IPW_RST_PRINCETON_RESET)
1465			break;
1466		DELAY(10);
1467	}
1468	if (ntries == 1000)
1469		return EIO;
1470
1471	CSR_WRITE_4(sc, IPW_CSR_CTL, IPW_CTL_INIT);
1472	for (ntries = 0; ntries < 1000; ntries++) {
1473		if ((r = CSR_READ_4(sc, IPW_CSR_CTL)) & IPW_CTL_CLOCK_READY)
1474			break;
1475		DELAY(200);
1476	}
1477	if (ntries == 1000)
1478		return EIO;
1479
1480	CSR_WRITE_4(sc, IPW_CSR_CTL, r | IPW_CTL_ALLOW_STANDBY);
1481
1482	return 0;
1483}
1484
1485static int
1486ipw_load_ucode(struct ipw_softc *sc, u_char *uc, int size)
1487{
1488	int ntries;
1489
1490	MEM_WRITE_2(sc, 0x220000, 0x0703);
1491	MEM_WRITE_2(sc, 0x220000, 0x0707);
1492
1493	MEM_WRITE_1(sc, 0x210014, 0x72);
1494	MEM_WRITE_1(sc, 0x210014, 0x72);
1495
1496	MEM_WRITE_1(sc, 0x210000, 0x40);
1497	MEM_WRITE_1(sc, 0x210000, 0x00);
1498	MEM_WRITE_1(sc, 0x210000, 0x40);
1499
1500	MEM_WRITE_MULTI_1(sc, 0x210010, uc, size);
1501
1502	MEM_WRITE_1(sc, 0x210000, 0x00);
1503	MEM_WRITE_1(sc, 0x210000, 0x00);
1504	MEM_WRITE_1(sc, 0x210000, 0x80);
1505
1506	MEM_WRITE_2(sc, 0x220000, 0x0703);
1507	MEM_WRITE_2(sc, 0x220000, 0x0707);
1508
1509	MEM_WRITE_1(sc, 0x210014, 0x72);
1510	MEM_WRITE_1(sc, 0x210014, 0x72);
1511
1512	MEM_WRITE_1(sc, 0x210000, 0x00);
1513	MEM_WRITE_1(sc, 0x210000, 0x80);
1514
1515	for (ntries = 0; ntries < 10; ntries++) {
1516		if (MEM_READ_1(sc, 0x210000) & 1)
1517			break;
1518		DELAY(10);
1519	}
1520	if (ntries == 10)
1521		return EIO;
1522
1523	return 0;
1524}
1525
1526/* set of macros to handle unaligned little endian data in firmware image */
1527#define GETLE32(p) ((p)[0] | (p)[1] << 8 | (p)[2] << 16 | (p)[3] << 24)
1528#define GETLE16(p) ((p)[0] | (p)[1] << 8)
1529static int
1530ipw_load_firmware(struct ipw_softc *sc, u_char *fw, int size)
1531{
1532	u_char *p, *end;
1533	u_int32_t dst;
1534	u_int16_t len;
1535
1536	p = fw;
1537	end = fw + size;
1538	while (p < end) {
1539		if (p + 6 > end)
1540			return EINVAL;
1541
1542		dst = GETLE32(p); p += 4;
1543		len = GETLE16(p); p += 2;
1544
1545		if (p + len > end)
1546			return EINVAL;
1547
1548		ipw_write_mem_1(sc, dst, p, len);
1549		p += len;
1550	}
1551	return 0;
1552}
1553
1554static int
1555ipw_firmware_init(struct ipw_softc *sc, u_char *data)
1556{
1557	struct ieee80211com *ic = &sc->sc_ic;
1558	struct ifnet *ifp = &ic->ic_if;
1559	struct ipw_fw_hdr hdr;
1560	u_int32_t r, len, fw_size, uc_size;
1561	u_char *fw, *uc;
1562	int error;
1563
1564	ipw_reset(sc);
1565
1566	if ((error = copyin(data, &hdr, sizeof hdr)) != 0)
1567		goto fail1;
1568
1569	fw_size = letoh32(hdr.fw_size);
1570	uc_size = letoh32(hdr.uc_size);
1571	data += sizeof hdr;
1572
1573	if ((fw = malloc(fw_size, M_DEVBUF, M_NOWAIT)) == NULL) {
1574		error = ENOMEM;
1575		goto fail1;
1576	}
1577
1578	if ((error = copyin(data, fw, fw_size)) != 0)
1579		goto fail2;
1580
1581	data += fw_size;
1582
1583	if ((uc = malloc(uc_size, M_DEVBUF, M_NOWAIT)) == NULL) {
1584		error = ENOMEM;
1585		goto fail2;
1586	}
1587
1588	if ((error = copyin(data, uc, uc_size)) != 0)
1589		goto fail3;
1590
1591	if ((error = ipw_clock_sync(sc)) != 0) {
1592		printf("%s: clock synchronization failed\n",
1593		    sc->sc_dev.dv_xname);
1594		goto fail3;
1595	}
1596
1597	MEM_WRITE_4(sc, 0x003000e0, 0x80000000);
1598
1599	CSR_WRITE_4(sc, IPW_CSR_RST, 0);
1600
1601	if ((error = ipw_load_ucode(sc, uc, uc_size)) != 0) {
1602		printf("%s: could not load microcode\n", sc->sc_dev.dv_xname);
1603		goto fail3;
1604	}
1605
1606	MEM_WRITE_4(sc, 0x003000e0, 0);
1607
1608	if ((error = ipw_clock_sync(sc)) != 0) {
1609		printf("%s: clock synchronization failed\n",
1610		    sc->sc_dev.dv_xname);
1611		goto fail3;
1612	}
1613
1614	if ((error = ipw_load_firmware(sc, fw, fw_size))) {
1615		printf("%s: could not load firmware\n", sc->sc_dev.dv_xname);
1616		goto fail3;
1617	}
1618
1619	ipw_zero_mem_4(sc, 0x0002f200, 196);
1620	ipw_zero_mem_4(sc, 0x0002f610, 8);
1621	ipw_zero_mem_4(sc, 0x0002fa00, 8);
1622	ipw_zero_mem_4(sc, 0x0002fc00, 4);
1623	ipw_zero_mem_4(sc, 0x0002ff80, 32);
1624
1625	if ((error = ipw_rx_init(sc)) != 0) {
1626		printf("%s: could not initialize rx queue\n",
1627		    sc->sc_dev.dv_xname);
1628		goto fail3;
1629	}
1630
1631	if ((error = ipw_tx_init(sc)) != 0) {
1632		printf("%s: could not initialize tx queue\n",
1633		    sc->sc_dev.dv_xname);
1634		goto fail3;
1635	}
1636
1637	CSR_WRITE_4(sc, IPW_CSR_IO, IPW_IO_GPIO1_ENABLE | IPW_IO_GPIO3_MASK |
1638	    IPW_IO_LED_OFF);
1639
1640	/* Allow interrupts so we know when the firmware is inited */
1641	CSR_WRITE_4(sc, IPW_CSR_INTR_MASK, IPW_INTR_MASK);
1642
1643	/* Tell the adapter to initialize the firmware */
1644	CSR_WRITE_4(sc, IPW_CSR_RST, 0);
1645
1646	/* Wait at most 5 seconds for firmware initialization to complete */
1647	if ((error = tsleep(sc, 0, "ipwinit", 5 * hz)) != 0) {
1648		printf("%s: timeout waiting for firmware initialization to "
1649		    "complete\n", sc->sc_dev.dv_xname);
1650		goto fail3;
1651	}
1652
1653	/* Firmware initialization completed */
1654	sc->flags |= IPW_FLAG_FW_INITED;
1655
1656	free(uc, M_DEVBUF);
1657	free(fw, M_DEVBUF);
1658
1659	r = CSR_READ_4(sc, IPW_CSR_IO);
1660	CSR_WRITE_4(sc, IPW_CSR_IO, r | IPW_IO_GPIO1_MASK | IPW_IO_GPIO3_MASK);
1661
1662	/* Retrieve information tables base addresses */
1663	sc->table1_base = CSR_READ_4(sc, IPW_CSR_TABLE1_BASE);
1664	sc->table2_base = CSR_READ_4(sc, IPW_CSR_TABLE2_BASE);
1665
1666	ipw_write_table1(sc, IPW_INFO_LOCK, 0);
1667
1668	/* Retrieve adapter MAC address */
1669	len = IEEE80211_ADDR_LEN;
1670	ipw_read_table2(sc, IPW_INFO_ADAPTER_MAC, ic->ic_myaddr, &len);
1671
1672	IEEE80211_ADDR_COPY(LLADDR(ifp->if_sadl), ic->ic_myaddr);
1673
1674	return 0;
1675
1676fail3:	free(uc, M_DEVBUF);
1677fail2:	free(fw, M_DEVBUF);
1678fail1:	ipw_reset(sc);
1679
1680	return error;
1681}
1682
1683static int
1684ipw_config(struct ipw_softc *sc)
1685{
1686	struct ieee80211com *ic = &sc->sc_ic;
1687	struct ifnet *ifp = &ic->ic_if;
1688	struct ipw_security security;
1689	struct ieee80211_wepkey *k;
1690	struct ipw_wep_key wepkey;
1691	struct ipw_scan_options options;
1692	struct ipw_configuration config;
1693	u_int32_t data;
1694	int error, i;
1695
1696	switch (ic->ic_opmode) {
1697	case IEEE80211_M_STA:
1698	case IEEE80211_M_HOSTAP:
1699		data = htole32(IPW_MODE_BSS);
1700		break;
1701
1702	case IEEE80211_M_IBSS:
1703	case IEEE80211_M_AHDEMO:
1704		data = htole32(IPW_MODE_IBSS);
1705		break;
1706
1707	case IEEE80211_M_MONITOR:
1708		data = htole32(IPW_MODE_MONITOR);
1709		break;
1710	}
1711	DPRINTF(("Setting adapter mode to %u\n", data));
1712	error = ipw_cmd(sc, IPW_CMD_SET_MODE, &data, sizeof data);
1713	if (error != 0)
1714		return error;
1715
1716	if (ic->ic_opmode == IEEE80211_M_IBSS ||
1717	    ic->ic_opmode == IEEE80211_M_MONITOR) {
1718		data = htole32(ieee80211_chan2ieee(ic, ic->ic_ibss_chan));
1719		DPRINTF(("Setting adapter channel to %u\n", data));
1720		error = ipw_cmd(sc, IPW_CMD_SET_CHANNEL, &data, sizeof data);
1721		if (error != 0)
1722			return error;
1723	}
1724
1725	if (ic->ic_opmode == IEEE80211_M_MONITOR) {
1726		DPRINTF(("Enabling adapter\n"));
1727		return ipw_cmd(sc, IPW_CMD_ENABLE, NULL, 0);
1728	}
1729
1730	DPRINTF(("Setting adapter MAC to %s\n", ether_sprintf(ic->ic_myaddr)));
1731	IEEE80211_ADDR_COPY(((struct arpcom *)ifp)->ac_enaddr, ic->ic_myaddr);
1732	IEEE80211_ADDR_COPY(LLADDR(ifp->if_sadl), ic->ic_myaddr);
1733	error = ipw_cmd(sc, IPW_CMD_SET_MAC_ADDRESS, ic->ic_myaddr,
1734	    IEEE80211_ADDR_LEN);
1735	if (error != 0)
1736		return error;
1737
1738	config.flags = htole32(IPW_CFG_BSS_MASK | IPW_CFG_IBSS_MASK |
1739			       IPW_CFG_PREAMBLE_LEN | IPW_CFG_802_1x_ENABLE);
1740	if (ic->ic_opmode == IEEE80211_M_IBSS)
1741		config.flags |= htole32(IPW_CFG_IBSS_AUTO_START);
1742	if (ifp->if_flags & IFF_PROMISC)
1743		config.flags |= htole32(IPW_CFG_PROMISCUOUS);
1744	config.channels = htole32(0x3fff); /* channels 1-14 */
1745	config.ibss_chan = htole32(0x7ff);
1746	DPRINTF(("Setting adapter configuration 0x%08x\n", config.flags));
1747	error = ipw_cmd(sc, IPW_CMD_SET_CONFIGURATION, &config, sizeof config);
1748	if (error != 0)
1749		return error;
1750
1751	data = htole32(0x3); /* 1, 2 */
1752	DPRINTF(("Setting adapter basic tx rates to 0x%x\n", data));
1753	error = ipw_cmd(sc, IPW_CMD_SET_BASIC_TX_RATES, &data, sizeof data);
1754	if (error != 0)
1755		return error;
1756
1757	data = htole32(0xf); /* 1, 2, 5.5, 11 */
1758	DPRINTF(("Setting adapter tx rates to 0x%x\n", data));
1759	error = ipw_cmd(sc, IPW_CMD_SET_TX_RATES, &data, sizeof data);
1760	if (error != 0)
1761		return error;
1762
1763	data = htole32(IPW_POWER_MODE_CAM);
1764	DPRINTF(("Setting adapter power mode to %u\n", data));
1765	error = ipw_cmd(sc, IPW_CMD_SET_POWER_MODE, &data, sizeof data);
1766	if (error != 0)
1767		return error;
1768
1769	if (ic->ic_opmode == IEEE80211_M_IBSS) {
1770		data = htole32(ic->ic_txpower);
1771		DPRINTF(("Setting adapter tx power index to %u\n", data));
1772		error = ipw_cmd(sc, IPW_CMD_SET_TX_POWER_INDEX, &data,
1773		    sizeof data);
1774		if (error != 0)
1775			return error;
1776	}
1777
1778	data = htole32(ic->ic_rtsthreshold);
1779	DPRINTF(("Setting adapter RTS threshold to %u\n", data));
1780	error = ipw_cmd(sc, IPW_CMD_SET_RTS_THRESHOLD, &data, sizeof data);
1781	if (error != 0)
1782		return error;
1783
1784	data = htole32(ic->ic_fragthreshold);
1785	DPRINTF(("Setting adapter frag threshold to %u\n", data));
1786	error = ipw_cmd(sc, IPW_CMD_SET_FRAG_THRESHOLD, &data, sizeof data);
1787	if (error != 0)
1788		return error;
1789
1790#ifdef IPW_DEBUG
1791	if (ipw_debug > 0) {
1792		printf("Setting adapter ESSID to ");
1793		ieee80211_print_essid(ic->ic_des_essid, ic->ic_des_esslen);
1794		printf("\n");
1795	}
1796#endif
1797	error = ipw_cmd(sc, IPW_CMD_SET_ESSID, ic->ic_des_essid,
1798	    ic->ic_des_esslen);
1799	if (error != 0)
1800		return error;
1801
1802	/* no mandatory BSSID */
1803	error = ipw_cmd(sc, IPW_CMD_SET_MANDATORY_BSSID, NULL, 0);
1804	if (error != 0)
1805		return error;
1806
1807	if (ic->ic_flags & IEEE80211_F_DESBSSID) {
1808		DPRINTF(("Setting adapter desired BSSID to %s\n",
1809		    ether_sprintf(ic->ic_des_bssid)));
1810		error = ipw_cmd(sc, IPW_CMD_SET_DESIRED_BSSID,
1811		    ic->ic_des_bssid, IEEE80211_ADDR_LEN);
1812		if (error != 0)
1813			return error;
1814	}
1815
1816	security.authmode = IPW_AUTH_OPEN;
1817	security.ciphers = htole32(IPW_CIPHER_NONE);
1818	security.version = htole16(0);
1819	security.replay_counters_number = 0;
1820	security.unicast_using_group = 0;
1821	DPRINTF(("Setting adapter authmode to %u\n", security.authmode));
1822	error = ipw_cmd(sc, IPW_CMD_SET_SECURITY_INFORMATION, &security,
1823	    sizeof security);
1824	if (error != 0)
1825		return error;
1826
1827	if (ic->ic_flags & IEEE80211_F_WEPON) {
1828		k = ic->ic_nw_keys;
1829		for (i = 0; i < IEEE80211_WEP_NKID; i++, k++) {
1830			if (k->wk_len == 0)
1831				continue;
1832
1833			wepkey.idx = i;
1834			wepkey.len = k->wk_len;
1835			bzero(wepkey.key, sizeof wepkey.key);
1836			bcopy(k->wk_key, wepkey.key, k->wk_len);
1837			DPRINTF(("Setting wep key index %d len %d\n",
1838			    wepkey.idx, wepkey.len));
1839			error = ipw_cmd(sc, IPW_CMD_SET_WEP_KEY, &wepkey,
1840			    sizeof wepkey);
1841			if (error != 0)
1842				return error;
1843		}
1844
1845		data = htole32(ic->ic_wep_txkey);
1846		DPRINTF(("Setting adapter tx key index to %u\n", data));
1847		error = ipw_cmd(sc, IPW_CMD_SET_WEP_KEY_INDEX, &data,
1848		    sizeof data);
1849		if (error != 0)
1850			return error;
1851	}
1852
1853	data = htole32((sc->sc_ic.ic_flags & IEEE80211_F_WEPON) ? 0x8 : 0);
1854	DPRINTF(("Setting adapter wep flags to 0x%x\n", data));
1855	error = ipw_cmd(sc, IPW_CMD_SET_WEP_FLAGS, &data, sizeof data);
1856	if (error != 0)
1857		return error;
1858
1859	if (ic->ic_opmode == IEEE80211_M_IBSS ||
1860	    ic->ic_opmode == IEEE80211_M_HOSTAP) {
1861		data = htole32(ic->ic_lintval);
1862		DPRINTF(("Setting adapter beacon interval to %u\n", data));
1863		error = ipw_cmd(sc, IPW_CMD_SET_BEACON_INTERVAL, &data,
1864		    sizeof data);
1865		if (error != 0)
1866			return error;
1867	}
1868
1869	options.flags = htole32(0);
1870	options.channels = htole32(0x3fff); /* scan channels 1-14 */
1871	error = ipw_cmd(sc, IPW_CMD_SET_SCAN_OPTIONS, &options, sizeof options);
1872	if (error != 0)
1873		return error;
1874
1875	/* finally, enable adapter (start scanning for an access point) */
1876	DPRINTF(("Enabling adapter\n"));
1877	return ipw_cmd(sc, IPW_CMD_ENABLE, NULL, 0);
1878}
1879
1880static int
1881ipw_init(struct ifnet *ifp)
1882{
1883	struct ipw_softc *sc = ifp->if_softc;
1884	struct ieee80211com *ic = &sc->sc_ic;
1885
1886	/* exit immediately if firmware has not been ioctl'd */
1887	if (!(sc->flags & IPW_FLAG_FW_INITED)) {
1888		ifp->if_flags &= ~IFF_UP;
1889		return EIO;
1890	}
1891
1892	ipw_stop(ifp, 0);
1893
1894	if (ipw_config(sc) != 0) {
1895		printf("%s: device configuration failed\n",
1896		    sc->sc_dev.dv_xname);
1897		goto fail;
1898	}
1899
1900	ifp->if_flags &= ~IFF_OACTIVE;
1901	ifp->if_flags |= IFF_RUNNING;
1902
1903	ic->ic_bss->ni_chan = ic->ic_channels;
1904
1905	return 0;
1906
1907fail:	ipw_stop(ifp, 0);
1908
1909	return EIO;
1910}
1911
1912static void
1913ipw_stop(struct ifnet *ifp, int disable)
1914{
1915	struct ipw_softc *sc = ifp->if_softc;
1916	struct ieee80211com *ic = &sc->sc_ic;
1917
1918	if (ifp->if_flags & IFF_RUNNING) {
1919		DPRINTF(("Disabling adapter\n"));
1920		ipw_cmd(sc, IPW_CMD_DISABLE, NULL, 0);
1921	}
1922
1923	ifp->if_timer = 0;
1924	ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
1925
1926	ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
1927}
1928
1929static void
1930ipw_read_mem_1(struct ipw_softc *sc, bus_size_t offset, u_int8_t *datap,
1931    bus_size_t count)
1932{
1933	for (; count > 0; offset++, datap++, count--) {
1934		CSR_WRITE_4(sc, IPW_CSR_INDIRECT_ADDR, offset & ~3);
1935		*datap = CSR_READ_1(sc, IPW_CSR_INDIRECT_DATA + (offset & 3));
1936	}
1937}
1938
1939static void
1940ipw_write_mem_1(struct ipw_softc *sc, bus_size_t offset, u_int8_t *datap,
1941    bus_size_t count)
1942{
1943	for (; count > 0; offset++, datap++, count--) {
1944		CSR_WRITE_4(sc, IPW_CSR_INDIRECT_ADDR, offset & ~3);
1945		CSR_WRITE_1(sc, IPW_CSR_INDIRECT_DATA + (offset & 3), *datap);
1946	}
1947}
1948
1949static void
1950ipw_zero_mem_4(struct ipw_softc *sc, bus_size_t offset, bus_size_t count)
1951{
1952	CSR_WRITE_4(sc, IPW_CSR_AUTOINC_ADDR, offset);
1953	while (count-- > 0)
1954		CSR_WRITE_4(sc, IPW_CSR_AUTOINC_DATA, 0);
1955}
1956
1957struct cfdriver ipw_cd = {
1958	0, "ipw", DV_IFNET
1959};
1960