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