xref: /openbsd-src/sys/dev/ic/malo.c (revision f2da64fbbbf1b03f09f390ab01267c93dfd77c4c)
1 /*	$OpenBSD: malo.c,v 1.112 2016/04/13 10:49:26 mpi Exp $ */
2 
3 /*
4  * Copyright (c) 2006 Claudio Jeker <claudio@openbsd.org>
5  * Copyright (c) 2006 Marcus Glocker <mglocker@openbsd.org>
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include "bpfilter.h"
21 
22 #include <sys/param.h>
23 #include <sys/types.h>
24 
25 #include <sys/device.h>
26 #include <sys/kernel.h>
27 #include <sys/malloc.h>
28 #include <sys/mbuf.h>
29 #include <sys/socket.h>
30 #include <sys/sockio.h>
31 #include <sys/systm.h>
32 #include <sys/endian.h>
33 
34 #include <machine/bus.h>
35 #include <machine/intr.h>
36 
37 #include <net/if.h>
38 #include <net/if_media.h>
39 
40 #if NBPFILTER > 0
41 #include <net/bpf.h>
42 #endif
43 
44 #include <netinet/in.h>
45 #include <netinet/if_ether.h>
46 
47 #include <net80211/ieee80211_var.h>
48 #include <net80211/ieee80211_radiotap.h>
49 
50 #include <dev/ic/malo.h>
51 
52 #ifdef MALO_DEBUG
53 int malo_d = 1;
54 #define DPRINTF(l, x...)	do { if ((l) <= malo_d) printf(x); } while (0)
55 #else
56 #define DPRINTF(l, x...)
57 #endif
58 
59 /* internal structures and defines */
60 struct malo_node {
61 	struct ieee80211_node		ni;
62 };
63 
64 struct malo_rx_data {
65 	bus_dmamap_t	map;
66 	struct mbuf	*m;
67 };
68 
69 struct malo_tx_data {
70 	bus_dmamap_t		map;
71 	struct mbuf		*m;
72 	uint32_t		softstat;
73 	struct ieee80211_node	*ni;
74 };
75 
76 /* RX descriptor used by HW */
77 struct malo_rx_desc {
78 	uint8_t		rxctrl;
79 	uint8_t		rssi;
80 	uint8_t		status;
81 	uint8_t		channel;
82 	uint16_t	len;
83 	uint8_t		reserved1;	/* actually unused */
84 	uint8_t		datarate;
85 	uint32_t	physdata;	/* DMA address of data */
86 	uint32_t	physnext;	/* DMA address of next control block */
87 	uint16_t	qosctrl;
88 	uint16_t	reserved2;
89 } __packed;
90 
91 /* TX descriptor used by HW */
92 struct malo_tx_desc {
93 	uint32_t	status;
94 	uint8_t		datarate;
95 	uint8_t		txpriority;
96 	uint16_t	qosctrl;
97 	uint32_t	physdata;	/* DMA address of data */
98 	uint16_t	len;
99 	uint8_t		destaddr[6];
100 	uint32_t	physnext;	/* DMA address of next control block */
101 	uint32_t	reserved1;	/* SAP packet info ??? */
102 	uint32_t	reserved2;
103 } __packed;
104 
105 #define MALO_RX_RING_COUNT	256
106 #define MALO_TX_RING_COUNT	256
107 #define MALO_MAX_SCATTER	8	/* XXX unknown, wild guess */
108 #define MALO_CMD_TIMEOUT	50	/* MALO_CMD_TIMEOUT * 100us */
109 
110 /*
111  * Firmware commands
112  */
113 #define MALO_CMD_GET_HW_SPEC		0x0003
114 #define MALO_CMD_SET_RADIO		0x001c
115 #define MALO_CMD_SET_AID		0x010d
116 #define MALO_CMD_SET_TXPOWER		0x001e
117 #define MALO_CMD_SET_ANTENNA		0x0020
118 #define MALO_CMD_SET_PRESCAN		0x0107
119 #define MALO_CMD_SET_POSTSCAN		0x0108
120 #define MALO_CMD_SET_RATE		0x0110
121 #define MALO_CMD_SET_CHANNEL		0x010a
122 #define MALO_CMD_SET_RTS		0x0113
123 #define MALO_CMD_SET_SLOT		0x0114
124 #define MALO_CMD_RESPONSE		0x8000
125 
126 #define MALO_CMD_RESULT_OK		0x0000	/* everything is fine */
127 #define MALO_CMD_RESULT_ERROR		0x0001	/* general error */
128 #define MALO_CMD_RESULT_NOSUPPORT	0x0002	/* command not valid */
129 #define MALO_CMD_RESULT_PENDING		0x0003	/* will be processed */
130 #define MALO_CMD_RESULT_BUSY		0x0004	/* command ignored */
131 #define MALO_CMD_RESULT_PARTIALDATA	0x0005	/* buffer too small */
132 
133 struct malo_cmdheader {
134 	uint16_t	cmd;
135 	uint16_t	size;		/* size of the command, incl. header */
136 	uint16_t	seqnum;		/* seems not to matter that much */
137 	uint16_t	result;		/* set to 0 on request */
138 	/* following the data payload, up to 256 bytes */
139 };
140 
141 struct malo_hw_spec {
142 	uint16_t	HwVersion;
143 	uint16_t	NumOfWCB;
144 	uint16_t	NumOfMCastAdr;
145 	uint8_t		PermanentAddress[6];
146 	uint16_t	RegionCode;
147 	uint16_t	NumberOfAntenna;
148 	uint32_t	FWReleaseNumber;
149 	uint32_t	WcbBase0;
150 	uint32_t	RxPdWrPtr;
151 	uint32_t	RxPdRdPtr;
152 	uint32_t	CookiePtr;
153 	uint32_t	WcbBase1;
154 	uint32_t	WcbBase2;
155 	uint32_t	WcbBase3;
156 } __packed;
157 
158 struct malo_cmd_radio {
159 	uint16_t	action;
160 	uint16_t	preamble_mode;
161 	uint16_t	enable;
162 } __packed;
163 
164 struct malo_cmd_aid {
165 	uint16_t	associd;
166 	uint8_t		macaddr[6];
167 	uint32_t	gprotection;
168 	uint8_t		aprates[14];
169 } __packed;
170 
171 struct malo_cmd_txpower {
172 	uint16_t	action;
173 	uint16_t	supportpowerlvl;
174 	uint16_t	currentpowerlvl;
175 	uint16_t	reserved;
176 	uint16_t	powerlvllist[8];
177 } __packed;
178 
179 struct malo_cmd_antenna {
180 	uint16_t	action;
181 	uint16_t	mode;
182 } __packed;
183 
184 struct malo_cmd_postscan {
185 	uint32_t	isibss;
186 	uint8_t		bssid[6];
187 } __packed;
188 
189 struct malo_cmd_channel {
190 	uint16_t	action;
191 	uint8_t		channel;
192 } __packed;
193 
194 struct malo_cmd_rate {
195 	uint8_t		dataratetype;
196 	uint8_t		rateindex;
197 	uint8_t		aprates[14];
198 } __packed;
199 
200 struct malo_cmd_rts {
201 	uint16_t	action;
202 	uint32_t	threshold;
203 } __packed;
204 
205 struct malo_cmd_slot {
206 	uint16_t	action;
207 	uint8_t		slot;
208 } __packed;
209 
210 #define malo_mem_write4(sc, off, x) \
211 	bus_space_write_4((sc)->sc_mem1_bt, (sc)->sc_mem1_bh, (off), (x))
212 #define malo_mem_write2(sc, off, x) \
213 	bus_space_write_2((sc)->sc_mem1_bt, (sc)->sc_mem1_bh, (off), (x))
214 #define malo_mem_write1(sc, off, x) \
215 	bus_space_write_1((sc)->sc_mem1_bt, (sc)->sc_mem1_bh, (off), (x))
216 
217 #define malo_mem_read4(sc, off) \
218 	bus_space_read_4((sc)->sc_mem1_bt, (sc)->sc_mem1_bh, (off))
219 #define malo_mem_read1(sc, off) \
220 	bus_space_read_1((sc)->sc_mem1_bt, (sc)->sc_mem1_bh, (off))
221 
222 #define malo_ctl_write4(sc, off, x) \
223 	bus_space_write_4((sc)->sc_mem2_bt, (sc)->sc_mem2_bh, (off), (x))
224 #define malo_ctl_read4(sc, off) \
225 	bus_space_read_4((sc)->sc_mem2_bt, (sc)->sc_mem2_bh, (off))
226 #define malo_ctl_read1(sc, off) \
227 	bus_space_read_1((sc)->sc_mem2_bt, (sc)->sc_mem2_bh, (off))
228 
229 #define malo_ctl_barrier(sc, t) \
230 	bus_space_barrier((sc)->sc_mem2_bt, (sc)->sc_mem2_bh, 0x0c00, 0xff, (t))
231 
232 struct cfdriver malo_cd = {
233 	NULL, "malo", DV_IFNET
234 };
235 
236 int	malo_alloc_cmd(struct malo_softc *sc);
237 void	malo_free_cmd(struct malo_softc *sc);
238 void	malo_send_cmd(struct malo_softc *sc, bus_addr_t addr);
239 int	malo_send_cmd_dma(struct malo_softc *sc, bus_addr_t addr);
240 int	malo_alloc_rx_ring(struct malo_softc *sc, struct malo_rx_ring *ring,
241 	    int count);
242 void	malo_reset_rx_ring(struct malo_softc *sc, struct malo_rx_ring *ring);
243 void	malo_free_rx_ring(struct malo_softc *sc, struct malo_rx_ring *ring);
244 int	malo_alloc_tx_ring(struct malo_softc *sc, struct malo_tx_ring *ring,
245 	    int count);
246 void	malo_reset_tx_ring(struct malo_softc *sc, struct malo_tx_ring *ring);
247 void	malo_free_tx_ring(struct malo_softc *sc, struct malo_tx_ring *ring);
248 int	malo_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data);
249 void	malo_start(struct ifnet *ifp);
250 void	malo_watchdog(struct ifnet *ifp);
251 int	malo_newstate(struct ieee80211com *ic, enum ieee80211_state nstate,
252 	    int arg);
253 void	malo_newassoc(struct ieee80211com *ic, struct ieee80211_node *ni,
254 	    int isnew);
255 struct ieee80211_node *
256 	malo_node_alloc(struct ieee80211com *ic);
257 int	malo_media_change(struct ifnet *ifp);
258 void	malo_media_status(struct ifnet *ifp, struct ifmediareq *imr);
259 int	malo_chip2rate(int chip_rate);
260 int	malo_fix2rate(int fix_rate);
261 void	malo_next_scan(void *arg);
262 void	malo_tx_intr(struct malo_softc *sc);
263 int	malo_tx_mgt(struct malo_softc *sc, struct mbuf *m0,
264 	    struct ieee80211_node *ni);
265 int	malo_tx_data(struct malo_softc *sc, struct mbuf *m0,
266 	    struct ieee80211_node *ni);
267 void	malo_tx_setup_desc(struct malo_softc *sc, struct malo_tx_desc *desc,
268 	    int len, int rate, const bus_dma_segment_t *segs, int nsegs);
269 void	malo_rx_intr(struct malo_softc *sc);
270 int	malo_load_bootimg(struct malo_softc *sc);
271 int	malo_load_firmware(struct malo_softc *sc);
272 
273 int	malo_set_slot(struct malo_softc *sc);
274 void	malo_update_slot(struct ieee80211com *ic);
275 #ifdef MALO_DEBUG
276 void	malo_hexdump(void *buf, int len);
277 #endif
278 static char *
279 	malo_cmd_string(uint16_t cmd);
280 static char *
281 	malo_cmd_string_result(uint16_t result);
282 int	malo_cmd_get_spec(struct malo_softc *sc);
283 int	malo_cmd_set_prescan(struct malo_softc *sc);
284 int	malo_cmd_set_postscan(struct malo_softc *sc, uint8_t *macaddr,
285 	    uint8_t ibsson);
286 int	malo_cmd_set_channel(struct malo_softc *sc, uint8_t channel);
287 int	malo_cmd_set_antenna(struct malo_softc *sc, uint16_t antenna_type);
288 int	malo_cmd_set_radio(struct malo_softc *sc, uint16_t mode,
289 	    uint16_t preamble);
290 int	malo_cmd_set_aid(struct malo_softc *sc, uint8_t *bssid,
291 	    uint16_t associd);
292 int	malo_cmd_set_txpower(struct malo_softc *sc, unsigned int powerlevel);
293 int	malo_cmd_set_rts(struct malo_softc *sc, uint32_t threshold);
294 int	malo_cmd_set_slot(struct malo_softc *sc, uint8_t slot);
295 int	malo_cmd_set_rate(struct malo_softc *sc, uint8_t rate);
296 void	malo_cmd_response(struct malo_softc *sc);
297 
298 int
299 malo_intr(void *arg)
300 {
301 	struct malo_softc *sc = arg;
302 	uint32_t status;
303 
304 	status = malo_ctl_read4(sc, 0x0c30);
305 	if (status == 0xffffffff || status == 0)
306 		/* not for us */
307 		return (0);
308 
309 	if (status & 0x1)
310 		malo_tx_intr(sc);
311 	if (status & 0x2)
312 		malo_rx_intr(sc);
313 	if (status & 0x4) {
314 		/* XXX cmd done interrupt handling doesn't work yet */
315 		DPRINTF(1, "%s: got cmd done interrupt\n", sc->sc_dev.dv_xname);
316 		//malo_cmd_response(sc);
317 	}
318 
319 	if (status & ~0x7)
320 		DPRINTF(1, "%s: unknown interrupt %x\n",
321 		    sc->sc_dev.dv_xname, status);
322 
323 	/* just ack the interrupt */
324 	malo_ctl_write4(sc, 0x0c30, 0);
325 
326 	return (1);
327 }
328 
329 int
330 malo_attach(struct malo_softc *sc)
331 {
332 	struct ieee80211com *ic = &sc->sc_ic;
333 	struct ifnet *ifp = &sc->sc_ic.ic_if;
334 	int i;
335 
336 	/* initialize channel scanning timer */
337 	timeout_set(&sc->sc_scan_to, malo_next_scan, sc);
338 
339 	/* allocate DMA structures */
340 	malo_alloc_cmd(sc);
341 	malo_alloc_rx_ring(sc, &sc->sc_rxring, MALO_RX_RING_COUNT);
342 	malo_alloc_tx_ring(sc, &sc->sc_txring, MALO_TX_RING_COUNT);
343 
344 	/* setup interface */
345 	ifp->if_softc = sc;
346 	ifp->if_ioctl = malo_ioctl;
347 	ifp->if_start = malo_start;
348 	ifp->if_watchdog = malo_watchdog;
349 	ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST;
350 	strlcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ);
351 	IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
352 
353 	/* set supported rates */
354 	ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b;
355 	ic->ic_sup_rates[IEEE80211_MODE_11G] = ieee80211_std_rateset_11g;
356 	sc->sc_last_txrate = -1;
357 
358 	/* set channels */
359 	for (i = 1; i <= 14; i++) {
360 		ic->ic_channels[i].ic_freq =
361 		    ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ);
362 		ic->ic_channels[i].ic_flags =
363 		    IEEE80211_CHAN_PUREG |
364 		    IEEE80211_CHAN_B |
365 		    IEEE80211_CHAN_G;
366 	}
367 
368 	/* set the rest */
369 	ic->ic_caps =
370 	    IEEE80211_C_IBSS |
371 	    IEEE80211_C_MONITOR |
372 	    IEEE80211_C_SHPREAMBLE |
373 	    IEEE80211_C_SHSLOT |
374 	    IEEE80211_C_WEP |
375 	    IEEE80211_C_RSN;
376 	ic->ic_opmode = IEEE80211_M_STA;
377 	ic->ic_state = IEEE80211_S_INIT;
378 	ic->ic_max_rssi = 75;
379 	for (i = 0; i < 6; i++)
380 		ic->ic_myaddr[i] = malo_ctl_read1(sc, 0xa528 + i);
381 
382 	/* show our mac address */
383 	printf(", address %s\n", ether_sprintf(ic->ic_myaddr));
384 
385 	/* attach interface */
386 	if_attach(ifp);
387 	ieee80211_ifattach(ifp);
388 
389 	/* post attach vector functions */
390 	sc->sc_newstate = ic->ic_newstate;
391 	ic->ic_newstate = malo_newstate;
392 	ic->ic_newassoc = malo_newassoc;
393 	ic->ic_node_alloc = malo_node_alloc;
394 	ic->ic_updateslot = malo_update_slot;
395 
396 	ieee80211_media_init(ifp, malo_media_change, malo_media_status);
397 
398 #if NBPFILTER > 0
399 	bpfattach(&sc->sc_drvbpf, ifp, DLT_IEEE802_11_RADIO,
400 	    sizeof(struct ieee80211_frame) + 64);
401 
402 	sc->sc_rxtap_len = sizeof(sc->sc_rxtapu);
403 	sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
404 	sc->sc_rxtap.wr_ihdr.it_present = htole32(MALO_RX_RADIOTAP_PRESENT);
405 
406 	sc->sc_txtap_len = sizeof(sc->sc_txtapu);
407 	sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
408 	sc->sc_txtap.wt_ihdr.it_present = htole32(MALO_TX_RADIOTAP_PRESENT);
409 #endif
410 
411 	return (0);
412 }
413 
414 int
415 malo_detach(void *arg)
416 {
417 	struct malo_softc *sc = arg;
418 	struct ieee80211com *ic = &sc->sc_ic;
419 	struct ifnet *ifp = &ic->ic_if;
420 
421 	/* remove channel scanning timer */
422 	timeout_del(&sc->sc_scan_to);
423 
424 	malo_stop(sc);
425 	ieee80211_ifdetach(ifp);
426 	if_detach(ifp);
427 	malo_free_cmd(sc);
428 	malo_free_rx_ring(sc, &sc->sc_rxring);
429 	malo_free_tx_ring(sc, &sc->sc_txring);
430 
431 	return (0);
432 }
433 
434 int
435 malo_alloc_cmd(struct malo_softc *sc)
436 {
437 	int error, nsegs;
438 
439 	error = bus_dmamap_create(sc->sc_dmat, PAGE_SIZE, 1,
440 	    PAGE_SIZE, 0, BUS_DMA_ALLOCNOW, &sc->sc_cmd_dmam);
441 	if (error != 0) {
442 		printf("%s: can not create DMA tag\n", sc->sc_dev.dv_xname);
443 		return (-1);
444 	}
445 
446 	error = bus_dmamem_alloc(sc->sc_dmat, PAGE_SIZE, PAGE_SIZE,
447 	    0, &sc->sc_cmd_dmas, 1, &nsegs, BUS_DMA_WAITOK);
448 	if (error != 0) {
449 		printf("%s: error alloc dma memory\n", sc->sc_dev.dv_xname);
450 		return (-1);
451 	}
452 
453 	error = bus_dmamem_map(sc->sc_dmat, &sc->sc_cmd_dmas, nsegs,
454 	    PAGE_SIZE, (caddr_t *)&sc->sc_cmd_mem, BUS_DMA_WAITOK);
455 	if (error != 0) {
456 		printf("%s: error map dma memory\n", sc->sc_dev.dv_xname);
457 		return (-1);
458 	}
459 
460 	error = bus_dmamap_load(sc->sc_dmat, sc->sc_cmd_dmam,
461 	    sc->sc_cmd_mem, PAGE_SIZE, NULL, BUS_DMA_NOWAIT);
462 	if (error != 0) {
463 		printf("%s: error load dma memory\n", sc->sc_dev.dv_xname);
464 		bus_dmamem_free(sc->sc_dmat, &sc->sc_cmd_dmas, nsegs);
465 		return (-1);
466 	}
467 
468 	sc->sc_cookie = sc->sc_cmd_mem;
469 	*sc->sc_cookie = htole32(0xaa55aa55);
470 	sc->sc_cmd_mem = (caddr_t)sc->sc_cmd_mem + sizeof(uint32_t);
471 	sc->sc_cookie_dmaaddr = sc->sc_cmd_dmam->dm_segs[0].ds_addr;
472 	sc->sc_cmd_dmaaddr = sc->sc_cmd_dmam->dm_segs[0].ds_addr +
473 	    sizeof(uint32_t);
474 
475 	return (0);
476 }
477 
478 void
479 malo_free_cmd(struct malo_softc *sc)
480 {
481 	bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,
482 	    BUS_DMASYNC_POSTWRITE);
483 	bus_dmamap_unload(sc->sc_dmat, sc->sc_cmd_dmam);
484 	bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_cookie, PAGE_SIZE);
485 	bus_dmamem_free(sc->sc_dmat, &sc->sc_cmd_dmas, 1);
486 }
487 
488 void
489 malo_send_cmd(struct malo_softc *sc, bus_addr_t addr)
490 {
491 	malo_ctl_write4(sc, 0x0c10, (uint32_t)addr);
492 	malo_ctl_barrier(sc, BUS_SPACE_BARRIER_WRITE);
493 	malo_ctl_write4(sc, 0x0c18, 2); /* CPU_TRANSFER_CMD */
494 	malo_ctl_barrier(sc, BUS_SPACE_BARRIER_WRITE);
495 }
496 
497 int
498 malo_send_cmd_dma(struct malo_softc *sc, bus_addr_t addr)
499 {
500 	int i;
501 	struct malo_cmdheader *hdr = sc->sc_cmd_mem;
502 
503 	malo_ctl_write4(sc, 0x0c10, (uint32_t)addr);
504 	malo_ctl_barrier(sc, BUS_SPACE_BARRIER_WRITE);
505 	malo_ctl_write4(sc, 0x0c18, 2); /* CPU_TRANSFER_CMD */
506 	malo_ctl_barrier(sc, BUS_SPACE_BARRIER_WRITE);
507 
508 	for (i = 0; i < MALO_CMD_TIMEOUT; i++) {
509 		delay(100);
510 		bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,
511 		    BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
512 		if (hdr->cmd & htole16(0x8000))
513 			break;
514 	}
515 	if (i == MALO_CMD_TIMEOUT) {
516 		printf("%s: timeout while waiting for cmd response!\n",
517 		    sc->sc_dev.dv_xname);
518 		return (ETIMEDOUT);
519 	}
520 
521 	malo_cmd_response(sc);
522 
523 	return (0);
524 }
525 
526 int
527 malo_alloc_rx_ring(struct malo_softc *sc, struct malo_rx_ring *ring, int count)
528 {
529 	struct malo_rx_desc *desc;
530 	struct malo_rx_data *data;
531 	int i, nsegs, error;
532 
533 	ring->count = count;
534 	ring->cur = ring->next = 0;
535 
536 	error = bus_dmamap_create(sc->sc_dmat,
537 	    count * sizeof(struct malo_rx_desc), 1,
538 	    count * sizeof(struct malo_rx_desc), 0,
539 	    BUS_DMA_NOWAIT, &ring->map);
540 	if (error != 0) {
541 		printf("%s: could not create desc DMA map\n",
542 		    sc->sc_dev.dv_xname);
543 		goto fail;
544 	}
545 
546 	error = bus_dmamem_alloc(sc->sc_dmat,
547 	    count * sizeof(struct malo_rx_desc),
548 	    PAGE_SIZE, 0, &ring->seg, 1, &nsegs,
549 	    BUS_DMA_NOWAIT | BUS_DMA_ZERO);
550 	if (error != 0) {
551 		printf("%s: could not allocate DMA memory\n",
552 		    sc->sc_dev.dv_xname);
553 		goto fail;
554 	}
555 
556 	error = bus_dmamem_map(sc->sc_dmat, &ring->seg, nsegs,
557 	    count * sizeof(struct malo_rx_desc), (caddr_t *)&ring->desc,
558 	    BUS_DMA_NOWAIT);
559 	if (error != 0) {
560 		printf("%s: can't map desc DMA memory\n",
561 		    sc->sc_dev.dv_xname);
562 		goto fail;
563 	}
564 
565 	error = bus_dmamap_load(sc->sc_dmat, ring->map, ring->desc,
566 	    count * sizeof(struct malo_rx_desc), NULL, BUS_DMA_NOWAIT);
567 	if (error != 0) {
568 		printf("%s: could not load desc DMA map\n",
569 		    sc->sc_dev.dv_xname);
570 		goto fail;
571 	}
572 
573 	ring->physaddr = ring->map->dm_segs->ds_addr;
574 
575 	ring->data = mallocarray(count, sizeof (struct malo_rx_data),
576 	    M_DEVBUF, M_NOWAIT);
577 	if (ring->data == NULL) {
578 		printf("%s: could not allocate soft data\n",
579 		    sc->sc_dev.dv_xname);
580 		error = ENOMEM;
581 		goto fail;
582 	}
583 
584 	/*
585 	 * Pre-allocate Rx buffers and populate Rx ring.
586 	 */
587 	bzero(ring->data, count * sizeof (struct malo_rx_data));
588 	for (i = 0; i < count; i++) {
589 		desc = &ring->desc[i];
590 		data = &ring->data[i];
591 
592 		error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES,
593 		    0, BUS_DMA_NOWAIT, &data->map);
594 		if (error != 0) {
595 			printf("%s: could not create DMA map\n",
596 			    sc->sc_dev.dv_xname);
597 			goto fail;
598 		}
599 
600 		MGETHDR(data->m, M_DONTWAIT, MT_DATA);
601 		if (data->m == NULL) {
602 			printf("%s: could not allocate rx mbuf\n",
603 			    sc->sc_dev.dv_xname);
604 			error = ENOMEM;
605 			goto fail;
606 		}
607 
608 		MCLGET(data->m, M_DONTWAIT);
609 		if (!(data->m->m_flags & M_EXT)) {
610 			printf("%s: could not allocate rx mbuf cluster\n",
611 			    sc->sc_dev.dv_xname);
612 			error = ENOMEM;
613 			goto fail;
614 		}
615 
616 		error = bus_dmamap_load(sc->sc_dmat, data->map,
617 		    mtod(data->m, void *), MCLBYTES, NULL, BUS_DMA_NOWAIT);
618 		if (error != 0) {
619 			printf("%s: could not load rx buf DMA map",
620 			    sc->sc_dev.dv_xname);
621 			goto fail;
622 		}
623 
624 		desc->status = htole16(1);
625 		desc->physdata = htole32(data->map->dm_segs->ds_addr);
626 		desc->physnext = htole32(ring->physaddr +
627 		    (i + 1) % count * sizeof(struct malo_rx_desc));
628 	}
629 
630 	bus_dmamap_sync(sc->sc_dmat, ring->map, 0, ring->map->dm_mapsize,
631 	    BUS_DMASYNC_PREWRITE);
632 
633 	return (0);
634 
635 fail:	malo_free_rx_ring(sc, ring);
636 	return (error);
637 }
638 
639 void
640 malo_reset_rx_ring(struct malo_softc *sc, struct malo_rx_ring *ring)
641 {
642 	int i;
643 
644 	for (i = 0; i < ring->count; i++)
645 		ring->desc[i].status = 0;
646 
647 	bus_dmamap_sync(sc->sc_dmat, ring->map, 0, ring->map->dm_mapsize,
648 	    BUS_DMASYNC_PREWRITE);
649 
650 	ring->cur = ring->next = 0;
651 }
652 
653 void
654 malo_free_rx_ring(struct malo_softc *sc, struct malo_rx_ring *ring)
655 {
656 	struct malo_rx_data *data;
657 	int i;
658 
659 	if (ring->desc != NULL) {
660 		bus_dmamap_sync(sc->sc_dmat, ring->map, 0,
661 		    ring->map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
662 		bus_dmamap_unload(sc->sc_dmat, ring->map);
663 		bus_dmamem_unmap(sc->sc_dmat, (caddr_t)ring->desc,
664 		    ring->count * sizeof(struct malo_rx_desc));
665 		bus_dmamem_free(sc->sc_dmat, &ring->seg, 1);
666 	}
667 
668 	if (ring->data != NULL) {
669 		for (i = 0; i < ring->count; i++) {
670 			data = &ring->data[i];
671 
672 			if (data->m != NULL) {
673 				bus_dmamap_sync(sc->sc_dmat, data->map, 0,
674 				    data->map->dm_mapsize,
675 				    BUS_DMASYNC_POSTREAD);
676 				bus_dmamap_unload(sc->sc_dmat, data->map);
677 				m_freem(data->m);
678 			}
679 
680 			if (data->map != NULL)
681 				bus_dmamap_destroy(sc->sc_dmat, data->map);
682 		}
683 		free(ring->data, M_DEVBUF, 0);
684 	}
685 }
686 
687 int
688 malo_alloc_tx_ring(struct malo_softc *sc, struct malo_tx_ring *ring,
689     int count)
690 {
691 	int i, nsegs, error;
692 
693 	ring->count = count;
694 	ring->queued = 0;
695 	ring->cur = ring->next = ring->stat = 0;
696 
697 	error = bus_dmamap_create(sc->sc_dmat,
698 	    count * sizeof(struct malo_tx_desc), 1,
699 	    count * sizeof(struct malo_tx_desc), 0, BUS_DMA_NOWAIT, &ring->map);
700 	if (error != 0) {
701 		printf("%s: could not create desc DMA map\n",
702 		    sc->sc_dev.dv_xname);
703 		goto fail;
704 	}
705 
706 	error = bus_dmamem_alloc(sc->sc_dmat,
707 	    count * sizeof(struct malo_tx_desc), PAGE_SIZE, 0,
708 	    &ring->seg, 1, &nsegs, BUS_DMA_NOWAIT | BUS_DMA_ZERO);
709 	if (error != 0) {
710 		printf("%s: could not allocate DMA memory\n",
711 		    sc->sc_dev.dv_xname);
712 		goto fail;
713 	}
714 
715 	error = bus_dmamem_map(sc->sc_dmat, &ring->seg, nsegs,
716 	    count * sizeof(struct malo_tx_desc), (caddr_t *)&ring->desc,
717 	    BUS_DMA_NOWAIT);
718 	if (error != 0) {
719 		printf("%s: can't map desc DMA memory\n",
720 		    sc->sc_dev.dv_xname);
721 		goto fail;
722 	}
723 
724 	error = bus_dmamap_load(sc->sc_dmat, ring->map, ring->desc,
725 	    count * sizeof(struct malo_tx_desc), NULL, BUS_DMA_NOWAIT);
726 	if (error != 0) {
727 		printf("%s: could not load desc DMA map\n",
728 		    sc->sc_dev.dv_xname);
729 		goto fail;
730 	}
731 
732 	ring->physaddr = ring->map->dm_segs->ds_addr;
733 
734 	ring->data = mallocarray(count, sizeof(struct malo_tx_data),
735 	    M_DEVBUF, M_NOWAIT);
736 	if (ring->data == NULL) {
737 		printf("%s: could not allocate soft data\n",
738 		    sc->sc_dev.dv_xname);
739 		error = ENOMEM;
740 		goto fail;
741 	}
742 
743 	memset(ring->data, 0, count * sizeof(struct malo_tx_data));
744 	for (i = 0; i < count; i++) {
745 		error = bus_dmamap_create(sc->sc_dmat, MCLBYTES,
746 		    MALO_MAX_SCATTER, MCLBYTES, 0, BUS_DMA_NOWAIT,
747 		    &ring->data[i].map);
748 		if (error != 0) {
749 			printf("%s: could not create DMA map\n",
750 			    sc->sc_dev.dv_xname);
751 			goto fail;
752 		}
753 		ring->desc[i].physnext = htole32(ring->physaddr +
754 		    (i + 1) % count * sizeof(struct malo_tx_desc));
755 	}
756 
757 	return (0);
758 
759 fail:	malo_free_tx_ring(sc, ring);
760 	return (error);
761 }
762 
763 void
764 malo_reset_tx_ring(struct malo_softc *sc, struct malo_tx_ring *ring)
765 {
766 	struct malo_tx_desc *desc;
767 	struct malo_tx_data *data;
768 	int i;
769 
770 	for (i = 0; i < ring->count; i++) {
771 		desc = &ring->desc[i];
772 		data = &ring->data[i];
773 
774 		if (data->m != NULL) {
775 			bus_dmamap_sync(sc->sc_dmat, data->map, 0,
776 			    data->map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
777 			bus_dmamap_unload(sc->sc_dmat, data->map);
778 			m_freem(data->m);
779 			data->m = NULL;
780 		}
781 
782 		/*
783 		 * The node has already been freed at that point so don't call
784 		 * ieee80211_release_node() here.
785 		 */
786 		data->ni = NULL;
787 
788 		desc->status = 0;
789 	}
790 
791 	bus_dmamap_sync(sc->sc_dmat, ring->map, 0, ring->map->dm_mapsize,
792 	    BUS_DMASYNC_PREWRITE);
793 
794 	ring->queued = 0;
795 	ring->cur = ring->next = ring->stat = 0;
796 }
797 
798 void
799 malo_free_tx_ring(struct malo_softc *sc, struct malo_tx_ring *ring)
800 {
801 	struct malo_tx_data *data;
802 	int i;
803 
804 	if (ring->desc != NULL) {
805 		bus_dmamap_sync(sc->sc_dmat, ring->map, 0,
806 		    ring->map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
807 		bus_dmamap_unload(sc->sc_dmat, ring->map);
808 		bus_dmamem_unmap(sc->sc_dmat, (caddr_t)ring->desc,
809 		    ring->count * sizeof(struct malo_tx_desc));
810 		bus_dmamem_free(sc->sc_dmat, &ring->seg, 1);
811 	}
812 
813 	if (ring->data != NULL) {
814 		for (i = 0; i < ring->count; i++) {
815 			data = &ring->data[i];
816 
817 			if (data->m != NULL) {
818 				bus_dmamap_sync(sc->sc_dmat, data->map, 0,
819 				    data->map->dm_mapsize,
820 				    BUS_DMASYNC_POSTWRITE);
821 				bus_dmamap_unload(sc->sc_dmat, data->map);
822 				m_freem(data->m);
823 			}
824 
825 			/*
826 			 * The node has already been freed at that point so
827 			 * don't call ieee80211_release_node() here.
828 			 */
829 			data->ni = NULL;
830 
831 			if (data->map != NULL)
832 				bus_dmamap_destroy(sc->sc_dmat, data->map);
833 		}
834 		free(ring->data, M_DEVBUF, 0);
835 	}
836 }
837 
838 int
839 malo_init(struct ifnet *ifp)
840 {
841 	struct malo_softc *sc = ifp->if_softc;
842 	struct ieee80211com *ic = &sc->sc_ic;
843 	uint8_t chan;
844 	int error;
845 
846 	DPRINTF(1, "%s: %s\n", ifp->if_xname, __func__);
847 
848 	/* if interface already runs stop it first */
849 	if (ifp->if_flags & IFF_RUNNING)
850 		malo_stop(sc);
851 
852 	/* power on cardbus socket */
853 	if (sc->sc_enable)
854 		sc->sc_enable(sc);
855 
856 	/* disable interrupts */
857 	malo_ctl_read4(sc, 0x0c30);
858 	malo_ctl_write4(sc, 0x0c30, 0);
859 	malo_ctl_write4(sc, 0x0c34, 0);
860 	malo_ctl_write4(sc, 0x0c3c, 0);
861 
862 	/* load firmware */
863 	if ((error = malo_load_bootimg(sc)))
864 		goto fail;
865 	if ((error = malo_load_firmware(sc)))
866 		goto fail;
867 
868 	/* enable interrupts */
869 	malo_ctl_write4(sc, 0x0c34, 0x1f);
870 	malo_ctl_barrier(sc, BUS_SPACE_BARRIER_WRITE);
871 	malo_ctl_write4(sc, 0x0c3c, 0x1f);
872 	malo_ctl_barrier(sc, BUS_SPACE_BARRIER_WRITE);
873 
874 	if ((error = malo_cmd_get_spec(sc)))
875 		goto fail;
876 
877 	/* select default channel */
878 	ic->ic_bss->ni_chan = ic->ic_ibss_chan;
879 	chan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan);
880 
881 	/* initialize hardware */
882 	if ((error = malo_cmd_set_channel(sc, chan))) {
883 		printf("%s: setting channel failed!\n",
884 		    sc->sc_dev.dv_xname);
885 		goto fail;
886 	}
887 	if ((error = malo_cmd_set_antenna(sc, 1))) {
888 		printf("%s: setting RX antenna failed!\n",
889 		    sc->sc_dev.dv_xname);
890 		goto fail;
891 	}
892 	if ((error = malo_cmd_set_antenna(sc, 2))) {
893 		printf("%s: setting TX antenna failed!\n",
894 		    sc->sc_dev.dv_xname);
895 		goto fail;
896 	}
897 	if ((error = malo_cmd_set_radio(sc, 1, 5))) {
898 		printf("%s: turn radio on failed!\n",
899 		    sc->sc_dev.dv_xname);
900 		goto fail;
901 	}
902 	if ((error = malo_cmd_set_txpower(sc, 100))) {
903 		printf("%s: setting TX power failed!\n",
904 		    sc->sc_dev.dv_xname);
905 		goto fail;
906 	}
907 	if ((error = malo_cmd_set_rts(sc, IEEE80211_RTS_MAX))) {
908 		printf("%s: setting RTS failed!\n",
909 		    sc->sc_dev.dv_xname);
910 		goto fail;
911 	}
912 
913 	ifp->if_flags |= IFF_RUNNING;
914 
915 	if (ic->ic_opmode != IEEE80211_M_MONITOR)
916 		/* start background scanning */
917 		ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
918 	else
919 		/* in monitor mode change directly into run state */
920 		ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
921 
922 	return (0);
923 
924 fail:
925 	/* reset adapter */
926 	DPRINTF(1, "%s: malo_init failed, resetting card\n",
927 	    sc->sc_dev.dv_xname);
928 	malo_stop(sc);
929 	return (error);
930 }
931 
932 int
933 malo_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
934 {
935 	struct malo_softc *sc = ifp->if_softc;
936 	struct ieee80211com *ic = &sc->sc_ic;
937 	struct ifreq *ifr;
938 	int s, error = 0;
939 	uint8_t chan;
940 
941 	s = splnet();
942 
943 	switch (cmd) {
944 	case SIOCSIFADDR:
945 		ifp->if_flags |= IFF_UP;
946 		/* FALLTHROUGH */
947 	case SIOCSIFFLAGS:
948 		if (ifp->if_flags & IFF_UP) {
949 			if ((ifp->if_flags & IFF_RUNNING) == 0)
950 				malo_init(ifp);
951 		} else {
952 			if (ifp->if_flags & IFF_RUNNING)
953 				malo_stop(sc);
954 		}
955 		break;
956         case SIOCADDMULTI:
957         case SIOCDELMULTI:
958 		ifr = (struct ifreq *)data;
959 		error = (cmd == SIOCADDMULTI) ?
960 		    ether_addmulti(ifr, &ic->ic_ac) :
961 		    ether_delmulti(ifr, &ic->ic_ac);
962 
963 		if (error == ENETRESET)
964 			error = 0;
965 		break;
966 	case SIOCS80211CHANNEL:
967 		/* allow fast channel switching in monitor mode */
968 		error = ieee80211_ioctl(ifp, cmd, data);
969 		if (error == ENETRESET &&
970 		    ic->ic_opmode == IEEE80211_M_MONITOR) {
971 			if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
972 			    (IFF_UP | IFF_RUNNING)) {
973 				ic->ic_bss->ni_chan = ic->ic_ibss_chan;
974 				chan = ieee80211_chan2ieee(ic,
975 				    ic->ic_bss->ni_chan);
976 				malo_cmd_set_channel(sc, chan);
977 			}
978 			error = 0;
979 		}
980 		break;
981 	default:
982 		error = ieee80211_ioctl(ifp, cmd, data);
983 		break;
984 	}
985 
986 	if (error == ENETRESET) {
987 		if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
988 		    (IFF_UP | IFF_RUNNING))
989 			malo_init(ifp);
990 		error = 0;
991 	}
992 
993 	splx(s);
994 
995 	return (error);
996 }
997 
998 void
999 malo_start(struct ifnet *ifp)
1000 {
1001 	struct malo_softc *sc = ifp->if_softc;
1002 	struct ieee80211com *ic = &sc->sc_ic;
1003 	struct mbuf *m0;
1004 	struct ieee80211_node *ni;
1005 
1006 	DPRINTF(2, "%s: %s\n", sc->sc_dev.dv_xname, __func__);
1007 
1008 	if (!(ifp->if_flags & IFF_RUNNING) || ifq_is_oactive(&ifp->if_snd))
1009 		return;
1010 
1011 	for (;;) {
1012 		if (sc->sc_txring.queued >= MALO_TX_RING_COUNT - 1) {
1013 			ifq_set_oactive(&ifp->if_snd);
1014 			break;
1015 		}
1016 
1017 		m0 = mq_dequeue(&ic->ic_mgtq);
1018 		if (m0 != NULL) {
1019 			ni = m0->m_pkthdr.ph_cookie;
1020 #if NBPFILTER > 0
1021 			if (ic->ic_rawbpf != NULL)
1022 				bpf_mtap(ic->ic_rawbpf, m0, BPF_DIRECTION_OUT);
1023 #endif
1024 			if (malo_tx_mgt(sc, m0, ni) != 0)
1025 				break;
1026 		} else {
1027 			if (ic->ic_state != IEEE80211_S_RUN)
1028 				break;
1029 
1030 			IFQ_DEQUEUE(&ifp->if_snd, m0);
1031 			if (m0 == NULL)
1032 				break;
1033 #if NBPFILTER > 0
1034 			if (ifp->if_bpf != NULL)
1035 				bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_OUT);
1036 #endif
1037 			m0 = ieee80211_encap(ifp, m0, &ni);
1038 			if (m0 == NULL)
1039 				continue;
1040 #if NBPFILTER > 0
1041 			if (ic->ic_rawbpf != NULL)
1042 				bpf_mtap(ic->ic_rawbpf, m0, BPF_DIRECTION_OUT);
1043 #endif
1044 			if (malo_tx_data(sc, m0, ni) != 0) {
1045 				if (ni != NULL)
1046 					ieee80211_release_node(ic, ni);
1047 				ifp->if_oerrors++;
1048 				break;
1049 			}
1050 		}
1051 	}
1052 }
1053 
1054 void
1055 malo_stop(struct malo_softc *sc)
1056 {
1057 	struct ieee80211com *ic = &sc->sc_ic;
1058 	struct ifnet *ifp = &ic->ic_if;
1059 
1060 	DPRINTF(1, "%s: %s\n", ifp->if_xname, __func__);
1061 
1062 	/* reset adapter */
1063 	if (ifp->if_flags & IFF_RUNNING)
1064 		malo_ctl_write4(sc, 0x0c18, (1 << 15));
1065 
1066 	/* device is not running anymore */
1067 	ifp->if_flags &= ~IFF_RUNNING;
1068 	ifq_clr_oactive(&ifp->if_snd);
1069 
1070 	/* change back to initial state */
1071 	ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
1072 
1073 	/* reset RX / TX rings */
1074 	malo_reset_tx_ring(sc, &sc->sc_txring);
1075 	malo_reset_rx_ring(sc, &sc->sc_rxring);
1076 
1077 	/* set initial rate */
1078 	sc->sc_last_txrate = -1;
1079 
1080 	/* power off cardbus socket */
1081 	if (sc->sc_disable)
1082 		sc->sc_disable(sc);
1083 }
1084 
1085 void
1086 malo_watchdog(struct ifnet *ifp)
1087 {
1088 
1089 }
1090 
1091 int
1092 malo_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
1093 {
1094 	struct malo_softc *sc = ic->ic_if.if_softc;
1095 	enum ieee80211_state ostate;
1096 	uint8_t chan;
1097 	int rate;
1098 
1099 	DPRINTF(2, "%s: %s\n", sc->sc_dev.dv_xname, __func__);
1100 
1101 	ostate = ic->ic_state;
1102 	timeout_del(&sc->sc_scan_to);
1103 
1104 	switch (nstate) {
1105 	case IEEE80211_S_INIT:
1106 		break;
1107 	case IEEE80211_S_SCAN:
1108 		if (ostate == IEEE80211_S_INIT) {
1109 			if (malo_cmd_set_prescan(sc) != 0)
1110 				DPRINTF(1, "%s: can't set prescan\n",
1111 				    sc->sc_dev.dv_xname);
1112 		} else {
1113 			chan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan);
1114 
1115 			malo_cmd_set_channel(sc, chan);
1116 		}
1117 		timeout_add_msec(&sc->sc_scan_to, 500);
1118 		break;
1119 	case IEEE80211_S_AUTH:
1120 		DPRINTF(1, "%s: newstate AUTH\n", sc->sc_dev.dv_xname);
1121 		malo_cmd_set_postscan(sc, ic->ic_myaddr, 1);
1122 		chan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan);
1123 		malo_cmd_set_channel(sc, chan);
1124 		break;
1125 	case IEEE80211_S_ASSOC:
1126 		DPRINTF(1, "%s: newstate ASSOC\n", sc->sc_dev.dv_xname);
1127 		if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)
1128 			malo_cmd_set_radio(sc, 1, 3); /* short preamble */
1129 		else
1130 			malo_cmd_set_radio(sc, 1, 1); /* long preamble */
1131 
1132 		malo_cmd_set_aid(sc, ic->ic_bss->ni_bssid,
1133 		    ic->ic_bss->ni_associd);
1134 
1135 		if (ic->ic_fixed_rate == -1)
1136 			/* automatic rate adaption */
1137 			malo_cmd_set_rate(sc, 0);
1138 		else {
1139 			/* fixed rate */
1140 			rate = malo_fix2rate(ic->ic_fixed_rate);
1141 			malo_cmd_set_rate(sc, rate);
1142 		}
1143 
1144 		malo_set_slot(sc);
1145 		break;
1146 	case IEEE80211_S_RUN:
1147 		DPRINTF(1, "%s: newstate RUN\n", sc->sc_dev.dv_xname);
1148 		break;
1149 	default:
1150 		break;
1151 	}
1152 
1153 	return (sc->sc_newstate(ic, nstate, arg));
1154 }
1155 
1156 void
1157 malo_newassoc(struct ieee80211com *ic, struct ieee80211_node *ni, int isnew)
1158 {
1159 
1160 }
1161 
1162 struct ieee80211_node *
1163 malo_node_alloc(struct ieee80211com *ic)
1164 {
1165 	struct malo_node *wn;
1166 
1167 	wn = malloc(sizeof(*wn), M_DEVBUF, M_NOWAIT | M_ZERO);
1168 	if (wn == NULL)
1169 		return (NULL);
1170 
1171 	return ((struct ieee80211_node *)wn);
1172 }
1173 
1174 int
1175 malo_media_change(struct ifnet *ifp)
1176 {
1177 	int error;
1178 
1179 	DPRINTF(1, "%s: %s\n", ifp->if_xname, __func__);
1180 
1181 	error = ieee80211_media_change(ifp);
1182 	if (error != ENETRESET)
1183 		return (error);
1184 
1185 	if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING))
1186 		malo_init(ifp);
1187 
1188 	return (0);
1189 }
1190 
1191 void
1192 malo_media_status(struct ifnet *ifp, struct ifmediareq *imr)
1193 {
1194 	struct malo_softc *sc = ifp->if_softc;
1195 	struct ieee80211com *ic = &sc->sc_ic;
1196 
1197 	imr->ifm_status = IFM_AVALID;
1198 	imr->ifm_active = IFM_IEEE80211;
1199 	if (ic->ic_state == IEEE80211_S_RUN)
1200 		imr->ifm_status |= IFM_ACTIVE;
1201 
1202 	/* report last TX rate used by chip */
1203 	imr->ifm_active |= ieee80211_rate2media(ic, sc->sc_last_txrate,
1204 	    ic->ic_curmode);
1205 
1206 	switch (ic->ic_opmode) {
1207 	case IEEE80211_M_STA:
1208 		break;
1209 #ifndef IEEE80211_STA_ONLY
1210 	case IEEE80211_M_IBSS:
1211 		imr->ifm_active |= IFM_IEEE80211_ADHOC;
1212 		break;
1213 	case IEEE80211_M_AHDEMO:
1214 		break;
1215 	case IEEE80211_M_HOSTAP:
1216 		break;
1217 #endif
1218 	case IEEE80211_M_MONITOR:
1219 		imr->ifm_active |= IFM_IEEE80211_MONITOR;
1220 		break;
1221 	default:
1222 		break;
1223 	}
1224 
1225 	switch (ic->ic_curmode) {
1226 		case IEEE80211_MODE_11B:
1227 			imr->ifm_active |= IFM_IEEE80211_11B;
1228 			break;
1229 		case IEEE80211_MODE_11G:
1230 			imr->ifm_active |= IFM_IEEE80211_11G;
1231 			break;
1232 	}
1233 }
1234 
1235 int
1236 malo_chip2rate(int chip_rate)
1237 {
1238 	switch (chip_rate) {
1239 	/* CCK rates */
1240 	case  0:	return (2);
1241 	case  1:	return (4);
1242 	case  2:	return (11);
1243 	case  3:	return (22);
1244 
1245 	/* OFDM rates */
1246 	case  4:	return (0); /* reserved */
1247 	case  5:	return (12);
1248 	case  6:	return (18);
1249 	case  7:	return (24);
1250 	case  8:	return (36);
1251 	case  9:	return (48);
1252 	case 10:	return (72);
1253 	case 11:	return (96);
1254 	case 12:	return (108);
1255 
1256 	/* no rate select yet or unknown rate */
1257 	default:	return (-1);
1258 	}
1259 }
1260 
1261 int
1262 malo_fix2rate(int fix_rate)
1263 {
1264 	switch (fix_rate) {
1265 	/* CCK rates */
1266 	case  0:	return (2);
1267 	case  1:	return (4);
1268 	case  2:	return (11);
1269 	case  3:	return (22);
1270 
1271 	/* OFDM rates */
1272 	case  4:	return (12);
1273 	case  5:	return (18);
1274 	case  6:	return (24);
1275 	case  7:	return (36);
1276 	case  8:	return (48);
1277 	case  9:	return (72);
1278 	case 10:	return (96);
1279 	case 11:	return (108);
1280 
1281 	/* unknown rate: should not happen */
1282 	default:	return (0);
1283 	}
1284 }
1285 
1286 void
1287 malo_next_scan(void *arg)
1288 {
1289 	struct malo_softc *sc = arg;
1290 	struct ieee80211com *ic = &sc->sc_ic;
1291 	struct ifnet *ifp = &ic->ic_if;
1292 	int s;
1293 
1294 	DPRINTF(1, "%s: %s\n", ifp->if_xname, __func__);
1295 
1296 	s = splnet();
1297 
1298 	if (ic->ic_state == IEEE80211_S_SCAN)
1299 		ieee80211_next_scan(ifp);
1300 
1301 	splx(s);
1302 }
1303 
1304 void
1305 malo_tx_intr(struct malo_softc *sc)
1306 {
1307 	struct ieee80211com *ic = &sc->sc_ic;
1308 	struct ifnet *ifp = &ic->ic_if;
1309 	struct malo_tx_desc *desc;
1310 	struct malo_tx_data *data;
1311 	struct malo_node *rn;
1312 	int stat;
1313 
1314 	DPRINTF(2, "%s: %s\n", sc->sc_dev.dv_xname, __func__);
1315 
1316 	stat = sc->sc_txring.stat;
1317 	for (;;) {
1318 		desc = &sc->sc_txring.desc[sc->sc_txring.stat];
1319 		data = &sc->sc_txring.data[sc->sc_txring.stat];
1320 		rn = (struct malo_node *)data->ni;
1321 
1322 		/* check if TX descriptor is not owned by FW anymore */
1323 		if ((letoh32(desc->status) & 0x80000000) ||
1324 		    !(letoh32(data->softstat) & 0x80))
1325 			break;
1326 
1327 		/* if no frame has been sent, ignore */
1328 		if (rn == NULL)
1329 			goto next;
1330 
1331 		/* check TX state */
1332 		switch (letoh32(desc->status) & 0x1) {
1333 		case 0x1:
1334 			DPRINTF(2, "%s: data frame was sent successfully\n",
1335 			    sc->sc_dev.dv_xname);
1336 			ifp->if_opackets++;
1337 			break;
1338 		default:
1339 			DPRINTF(1, "%s: data frame sending error\n",
1340 			    sc->sc_dev.dv_xname);
1341 			ifp->if_oerrors++;
1342 			break;
1343 		}
1344 
1345 		/* save last used TX rate */
1346 		sc->sc_last_txrate = malo_chip2rate(desc->datarate);
1347 
1348 		/* cleanup TX data and TX descriptor */
1349 		bus_dmamap_sync(sc->sc_dmat, data->map, 0,
1350 		    data->map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
1351 		bus_dmamap_unload(sc->sc_dmat, data->map);
1352 		m_freem(data->m);
1353 		ieee80211_release_node(ic, data->ni);
1354 		data->m = NULL;
1355 		data->ni = NULL;
1356 		data->softstat &= htole32(~0x80);
1357 		desc->status = 0;
1358 		desc->len = 0;
1359 
1360 		DPRINTF(2, "%s: tx done idx=%d\n",
1361 		    sc->sc_dev.dv_xname, sc->sc_txring.stat);
1362 
1363 		sc->sc_txring.queued--;
1364 next:
1365 		if (++sc->sc_txring.stat >= sc->sc_txring.count)
1366 			sc->sc_txring.stat = 0;
1367 		if (sc->sc_txring.stat == stat)
1368 			break;
1369 	}
1370 
1371 	sc->sc_tx_timer = 0;
1372 	ifq_clr_oactive(&ifp->if_snd);
1373 	malo_start(ifp);
1374 }
1375 
1376 int
1377 malo_tx_mgt(struct malo_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
1378 {
1379 	struct ieee80211com *ic = &sc->sc_ic;
1380 	struct ifnet *ifp = &ic->ic_if;
1381 	struct malo_tx_desc *desc;
1382 	struct malo_tx_data *data;
1383 	struct ieee80211_frame *wh;
1384 	int error;
1385 
1386 	DPRINTF(2, "%s: %s\n", sc->sc_dev.dv_xname, __func__);
1387 
1388 	desc = &sc->sc_txring.desc[sc->sc_txring.cur];
1389 	data = &sc->sc_txring.data[sc->sc_txring.cur];
1390 
1391 	if (m0->m_len < sizeof(struct ieee80211_frame)) {
1392 		m0 = m_pullup(m0, sizeof(struct ieee80211_frame));
1393 		if (m0 == NULL) {
1394 			ifp->if_ierrors++;
1395 			return (ENOBUFS);
1396 		}
1397 	}
1398 	wh = mtod(m0, struct ieee80211_frame *);
1399 
1400 #if NBPFILTER > 0
1401 	if (sc->sc_drvbpf != NULL) {
1402 		struct mbuf mb;
1403 		struct malo_tx_radiotap_hdr *tap = &sc->sc_txtap;
1404 
1405 		tap->wt_flags = 0;
1406 		tap->wt_rate = sc->sc_last_txrate;
1407 		tap->wt_chan_freq = htole16(ic->ic_bss->ni_chan->ic_freq);
1408 		tap->wt_chan_flags = htole16(ic->ic_bss->ni_chan->ic_flags);
1409 
1410 		mb.m_data = (caddr_t)tap;
1411 		mb.m_len = sc->sc_txtap_len;
1412 		mb.m_next = m0;
1413 		mb.m_nextpkt = NULL;
1414 		mb.m_type = 0;
1415 		mb.m_flags = 0;
1416 		bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_OUT);
1417 	}
1418 #endif
1419 	/*
1420 	 * inject FW specific fields into the 802.11 frame
1421 	 *
1422 	 *  2 bytes FW len (inject)
1423 	 * 24 bytes 802.11 frame header
1424 	 *  6 bytes addr4 (inject)
1425 	 *  n bytes 802.11 frame body
1426 	 */
1427 	if (M_LEADINGSPACE(m0) < 8) {
1428 		if (M_TRAILINGSPACE(m0) < 8)
1429 			panic("%s: not enough space for mbuf dance",
1430 			    sc->sc_dev.dv_xname);
1431 		bcopy(m0->m_data, m0->m_data + 8, m0->m_len);
1432 		m0->m_data += 8;
1433 	}
1434 
1435 	/* move frame header */
1436 	bcopy(m0->m_data, m0->m_data - 6, sizeof(*wh));
1437 	m0->m_data -= 8;
1438 	m0->m_len += 8;
1439 	m0->m_pkthdr.len += 8;
1440 	*mtod(m0, uint16_t *) = htole16(m0->m_len - 32); /* FW len */
1441 
1442 	error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m0,
1443 	    BUS_DMA_NOWAIT);
1444 	if (error != 0) {
1445 		printf("%s: can't map mbuf (error %d)\n",
1446 		    sc->sc_dev.dv_xname, error);
1447 		m_freem(m0);
1448 		return (error);
1449 	}
1450 
1451 	data->m = m0;
1452 	data->ni = ni;
1453 	data->softstat |= htole32(0x80);
1454 
1455 	malo_tx_setup_desc(sc, desc, m0->m_pkthdr.len, 0,
1456 	    data->map->dm_segs, data->map->dm_nsegs);
1457 
1458 	bus_dmamap_sync(sc->sc_dmat, data->map, 0, data->map->dm_mapsize,
1459 	    BUS_DMASYNC_PREWRITE);
1460 	bus_dmamap_sync(sc->sc_dmat, sc->sc_txring.map,
1461 	    sc->sc_txring.cur * sizeof(struct malo_tx_desc),
1462 	    sizeof(struct malo_tx_desc), BUS_DMASYNC_PREWRITE);
1463 
1464 	DPRINTF(2, "%s: sending mgmt frame, pktlen=%u, idx=%u\n",
1465 	    sc->sc_dev.dv_xname, m0->m_pkthdr.len, sc->sc_txring.cur);
1466 
1467 	sc->sc_txring.queued++;
1468 	sc->sc_txring.cur = (sc->sc_txring.cur + 1) % MALO_TX_RING_COUNT;
1469 
1470 	/* kick mgmt TX */
1471 	malo_ctl_write4(sc, 0x0c18, 1);
1472 	malo_ctl_barrier(sc, BUS_SPACE_BARRIER_WRITE);
1473 
1474 	return (0);
1475 }
1476 
1477 int
1478 malo_tx_data(struct malo_softc *sc, struct mbuf *m0,
1479     struct ieee80211_node *ni)
1480 {
1481 	struct ieee80211com *ic = &sc->sc_ic;
1482 	struct ifnet *ifp = &ic->ic_if;
1483 	struct malo_tx_desc *desc;
1484 	struct malo_tx_data *data;
1485 	struct ieee80211_frame *wh;
1486 	struct ieee80211_key *k;
1487 	struct mbuf *mnew;
1488 	int error;
1489 
1490 	DPRINTF(2, "%s: %s\n", sc->sc_dev.dv_xname, __func__);
1491 
1492 	desc = &sc->sc_txring.desc[sc->sc_txring.cur];
1493 	data = &sc->sc_txring.data[sc->sc_txring.cur];
1494 
1495 	if (m0->m_len < sizeof(struct ieee80211_frame)) {
1496 		m0 = m_pullup(m0, sizeof(struct ieee80211_frame));
1497 		if (m0 == NULL) {
1498 			ifp->if_ierrors++;
1499 			return (ENOBUFS);
1500 		}
1501 	}
1502 	wh = mtod(m0, struct ieee80211_frame *);
1503 
1504 	if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
1505 		k = ieee80211_get_txkey(ic, wh, ni);
1506 		if ((m0 = ieee80211_encrypt(ic, m0, k)) == NULL)
1507 			return (ENOBUFS);
1508 
1509 		/* packet header may have moved, reset our local pointer */
1510 		wh = mtod(m0, struct ieee80211_frame *);
1511 	}
1512 
1513 #if NBPFILTER > 0
1514 	if (sc->sc_drvbpf != NULL) {
1515 		struct mbuf mb;
1516 		struct malo_tx_radiotap_hdr *tap = &sc->sc_txtap;
1517 
1518 		tap->wt_flags = 0;
1519 		tap->wt_rate = sc->sc_last_txrate;
1520 		tap->wt_chan_freq = htole16(ic->ic_bss->ni_chan->ic_freq);
1521 		tap->wt_chan_flags = htole16(ic->ic_bss->ni_chan->ic_flags);
1522 
1523 		mb.m_data = (caddr_t)tap;
1524 		mb.m_len = sc->sc_txtap_len;
1525 		mb.m_next = m0;
1526 		mb.m_nextpkt = NULL;
1527 		mb.m_type = 0;
1528 		mb.m_flags = 0;
1529 		bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_OUT);
1530 	}
1531 #endif
1532 
1533 	/*
1534 	 * inject FW specific fields into the 802.11 frame
1535 	 *
1536 	 *  2 bytes FW len (inject)
1537 	 * 24 bytes 802.11 frame header
1538 	 *  6 bytes addr4 (inject)
1539 	 *  n bytes 802.11 frame body
1540 	 *
1541 	 * For now copy all into a new mcluster.
1542 	 */
1543 	MGETHDR(mnew, M_DONTWAIT, MT_DATA);
1544 	if (mnew == NULL)
1545 		return (ENOBUFS);
1546 	MCLGET(mnew, M_DONTWAIT);
1547 	if (!(mnew->m_flags & M_EXT)) {
1548 		m_free(mnew);
1549 		return (ENOBUFS);
1550 	}
1551 
1552 	*mtod(mnew, uint16_t *) = htole16(m0->m_pkthdr.len - 24); /* FW len */
1553 	bcopy(wh, mtod(mnew, caddr_t) + 2, sizeof(*wh));
1554 	bzero(mtod(mnew, caddr_t) + 26, 6);
1555 	m_copydata(m0, sizeof(*wh), m0->m_pkthdr.len - sizeof(*wh),
1556 	    mtod(mnew, caddr_t) + 32);
1557 	mnew->m_pkthdr.len = mnew->m_len = m0->m_pkthdr.len + 8;
1558 	m_freem(m0);
1559 	m0 = mnew;
1560 
1561 	error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m0,
1562 	    BUS_DMA_NOWAIT);
1563 	if (error != 0) {
1564 		printf("%s: can't map mbuf (error %d)\n",
1565 		    sc->sc_dev.dv_xname, error);
1566 		m_freem(m0);
1567 		return (error);
1568 	}
1569 
1570 	data->m = m0;
1571 	data->ni = ni;
1572 	data->softstat |= htole32(0x80);
1573 
1574 	malo_tx_setup_desc(sc, desc, m0->m_pkthdr.len, 1,
1575 	    data->map->dm_segs, data->map->dm_nsegs);
1576 
1577 	bus_dmamap_sync(sc->sc_dmat, data->map, 0, data->map->dm_mapsize,
1578 	    BUS_DMASYNC_PREWRITE);
1579 	bus_dmamap_sync(sc->sc_dmat, sc->sc_txring.map,
1580 	    sc->sc_txring.cur * sizeof(struct malo_tx_desc),
1581 	    sizeof(struct malo_tx_desc), BUS_DMASYNC_PREWRITE);
1582 
1583 	DPRINTF(2, "%s: sending data frame, pktlen=%u, idx=%u\n",
1584 	    sc->sc_dev.dv_xname, m0->m_pkthdr.len, sc->sc_txring.cur);
1585 
1586 	sc->sc_txring.queued++;
1587 	sc->sc_txring.cur = (sc->sc_txring.cur + 1) % MALO_TX_RING_COUNT;
1588 
1589 	/* kick data TX */
1590 	malo_ctl_write4(sc, 0x0c18, 1);
1591 	malo_ctl_barrier(sc, BUS_SPACE_BARRIER_WRITE);
1592 
1593 	return (0);
1594 }
1595 
1596 void
1597 malo_tx_setup_desc(struct malo_softc *sc, struct malo_tx_desc *desc,
1598     int len, int rate, const bus_dma_segment_t *segs, int nsegs)
1599 {
1600 	desc->len = htole16(segs[0].ds_len);
1601 	desc->datarate = rate; /* 0 = mgmt frame, 1 = data frame */
1602 	desc->physdata = htole32(segs[0].ds_addr);
1603 	desc->status = htole32(0x00000001 | 0x80000000);
1604 }
1605 
1606 void
1607 malo_rx_intr(struct malo_softc *sc)
1608 {
1609 	struct ieee80211com *ic = &sc->sc_ic;
1610 	struct ifnet *ifp = &ic->ic_if;
1611 	struct malo_rx_desc *desc;
1612 	struct malo_rx_data *data;
1613 	struct ieee80211_frame *wh;
1614 	struct ieee80211_rxinfo rxi;
1615 	struct ieee80211_node *ni;
1616 	struct mbuf *mnew, *m;
1617 	uint32_t rxRdPtr, rxWrPtr;
1618 	int error, i;
1619 
1620 	rxRdPtr = malo_mem_read4(sc, sc->sc_RxPdRdPtr);
1621 	rxWrPtr = malo_mem_read4(sc, sc->sc_RxPdWrPtr);
1622 
1623 	for (i = 0; i < MALO_RX_RING_COUNT && rxRdPtr != rxWrPtr; i++) {
1624 		desc = &sc->sc_rxring.desc[sc->sc_rxring.cur];
1625 		data = &sc->sc_rxring.data[sc->sc_rxring.cur];
1626 
1627 		bus_dmamap_sync(sc->sc_dmat, sc->sc_rxring.map,
1628 		    sc->sc_rxring.cur * sizeof(struct malo_rx_desc),
1629 		    sizeof(struct malo_rx_desc), BUS_DMASYNC_POSTREAD);
1630 
1631 		DPRINTF(3, "%s: rx intr idx=%d, rxctrl=0x%02x, rssi=%d, "
1632 		    "status=0x%02x, channel=%d, len=%d, res1=%02x, rate=%d, "
1633 		    "physdata=0x%04x, physnext=0x%04x, qosctrl=%02x, res2=%d\n",
1634 		    sc->sc_dev.dv_xname,
1635 		    sc->sc_rxring.cur, desc->rxctrl, desc->rssi, desc->status,
1636 		    desc->channel, letoh16(desc->len), desc->reserved1,
1637 		    desc->datarate, letoh32(desc->physdata),
1638 		    letoh32(desc->physnext), desc->qosctrl, desc->reserved2);
1639 
1640 		if ((desc->rxctrl & 0x80) == 0)
1641 			break;
1642 
1643 		MGETHDR(mnew, M_DONTWAIT, MT_DATA);
1644 		if (mnew == NULL) {
1645 			ifp->if_ierrors++;
1646 			goto skip;
1647 		}
1648 
1649 		MCLGET(mnew, M_DONTWAIT);
1650 		if (!(mnew->m_flags & M_EXT)) {
1651 			m_freem(mnew);
1652 			ifp->if_ierrors++;
1653 			goto skip;
1654 		}
1655 
1656 		bus_dmamap_sync(sc->sc_dmat, data->map, 0,
1657 		    data->map->dm_mapsize, BUS_DMASYNC_POSTREAD);
1658 		bus_dmamap_unload(sc->sc_dmat, data->map);
1659 
1660 		error = bus_dmamap_load(sc->sc_dmat, data->map,
1661 		    mtod(mnew, void *), MCLBYTES, NULL, BUS_DMA_NOWAIT);
1662 		if (error != 0) {
1663 			m_freem(mnew);
1664 
1665 			error = bus_dmamap_load(sc->sc_dmat, data->map,
1666 			    mtod(data->m, void *), MCLBYTES, NULL,
1667 			    BUS_DMA_NOWAIT);
1668 			if (error != 0) {
1669 				panic("%s: could not load old rx mbuf",
1670 				    sc->sc_dev.dv_xname);
1671 			}
1672 			ifp->if_ierrors++;
1673 			goto skip;
1674 		}
1675 
1676 		/*
1677 		 * New mbuf mbuf successfully loaded
1678 		 */
1679 		m = data->m;
1680 		data->m = mnew;
1681 		desc->physdata = htole32(data->map->dm_segs->ds_addr);
1682 
1683 		/* finalize mbuf */
1684 		m->m_pkthdr.len = m->m_len = letoh16(desc->len);
1685 
1686 		/*
1687 		 * cut out FW specific fields from the 802.11 frame
1688 		 *
1689 		 *  2 bytes FW len (cut out)
1690 		 * 24 bytes 802.11 frame header
1691 		 *  6 bytes addr4 (cut out)
1692 		 *  n bytes 802.11 frame data
1693 		 */
1694 		bcopy(m->m_data, m->m_data + 6, 26);
1695 		m_adj(m, 8);
1696 
1697 #if NBPFILTER > 0
1698 		if (sc->sc_drvbpf != NULL) {
1699 			struct mbuf mb;
1700 			struct malo_rx_radiotap_hdr *tap = &sc->sc_rxtap;
1701 
1702 			tap->wr_flags = 0;
1703 			tap->wr_chan_freq =
1704 			    htole16(ic->ic_bss->ni_chan->ic_freq);
1705 			tap->wr_chan_flags =
1706 			    htole16(ic->ic_bss->ni_chan->ic_flags);
1707 			tap->wr_rssi = desc->rssi;
1708 			tap->wr_max_rssi = ic->ic_max_rssi;
1709 
1710 			mb.m_data = (caddr_t)tap;
1711 			mb.m_len = sc->sc_rxtap_len;
1712 			mb.m_next = m;
1713 			mb.m_nextpkt = NULL;
1714 			mb.m_type = 0;
1715 			mb.m_flags = 0;
1716 			bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_IN);
1717 		}
1718 #endif
1719 
1720 		wh = mtod(m, struct ieee80211_frame *);
1721 		ni = ieee80211_find_rxnode(ic, wh);
1722 
1723 		/* send the frame to the 802.11 layer */
1724 		rxi.rxi_flags = 0;
1725 		rxi.rxi_rssi = desc->rssi;
1726 		rxi.rxi_tstamp = 0;	/* unused */
1727 		ieee80211_input(ifp, m, ni, &rxi);
1728 
1729 		/* node is no longer needed */
1730 		ieee80211_release_node(ic, ni);
1731 
1732 skip:
1733 		desc->rxctrl = 0;
1734 		rxRdPtr = letoh32(desc->physnext);
1735 
1736 		bus_dmamap_sync(sc->sc_dmat, sc->sc_rxring.map,
1737 		    sc->sc_rxring.cur * sizeof(struct malo_rx_desc),
1738 		    sizeof(struct malo_rx_desc), BUS_DMASYNC_PREWRITE);
1739 
1740 		sc->sc_rxring.cur = (sc->sc_rxring.cur + 1) %
1741 		    MALO_RX_RING_COUNT;
1742 	}
1743 
1744 	malo_mem_write4(sc, sc->sc_RxPdRdPtr, rxRdPtr);
1745 }
1746 
1747 int
1748 malo_load_bootimg(struct malo_softc *sc)
1749 {
1750 	char *name = "malo8335-h";
1751 	uint8_t	*ucode;
1752 	size_t size;
1753 	int error, i;
1754 
1755 	/* load boot firmware */
1756 	if ((error = loadfirmware(name, &ucode, &size)) != 0) {
1757 		printf("%s: error %d, could not read firmware %s\n",
1758 		    sc->sc_dev.dv_xname, error, name);
1759 		return (EIO);
1760 	}
1761 
1762 	/*
1763 	 * It seems we are putting this code directly onto the stack of
1764 	 * the ARM cpu. I don't know why we need to instruct the DMA
1765 	 * engine to move the code. This is a big riddle without docu.
1766 	 */
1767 	DPRINTF(1, "%s: loading boot firmware\n", sc->sc_dev.dv_xname);
1768 	malo_mem_write2(sc, 0xbef8, 0x001);
1769 	malo_mem_write2(sc, 0xbefa, size);
1770 	malo_mem_write4(sc, 0xbefc, 0);
1771 
1772 	bus_space_write_region_1(sc->sc_mem1_bt, sc->sc_mem1_bh, 0xbf00,
1773 	    ucode, size);
1774 
1775 	/*
1776 	 * we loaded the firmware into card memory now tell the CPU
1777 	 * to fetch the code and execute it. The memory mapped via the
1778 	 * first bar is internaly mapped to 0xc0000000.
1779 	 */
1780 	malo_send_cmd(sc, 0xc000bef8);
1781 
1782 	/* wait for the device to go into FW loading mode */
1783 	for (i = 0; i < 10; i++) {
1784 		delay(50);
1785 		malo_ctl_barrier(sc, BUS_SPACE_BARRIER_READ);
1786 		if (malo_ctl_read4(sc, 0x0c14) == 0x5)
1787 			break;
1788 	}
1789 	if (i == 10) {
1790 		printf("%s: timeout at boot firmware load!\n",
1791 		    sc->sc_dev.dv_xname);
1792 		free(ucode, M_DEVBUF, size);
1793 		return (ETIMEDOUT);
1794 	}
1795 	free(ucode, M_DEVBUF, size);
1796 
1797 	/* tell the card we're done and... */
1798 	malo_mem_write2(sc, 0xbef8, 0x001);
1799 	malo_mem_write2(sc, 0xbefa, 0);
1800 	malo_mem_write4(sc, 0xbefc, 0);
1801 	malo_send_cmd(sc, 0xc000bef8);
1802 
1803 	DPRINTF(1, "%s: boot firmware loaded\n", sc->sc_dev.dv_xname);
1804 
1805 	return (0);
1806 }
1807 
1808 int
1809 malo_load_firmware(struct malo_softc *sc)
1810 {
1811 	struct malo_cmdheader *hdr;
1812 	char *name = "malo8335-m";
1813 	void *data;
1814 	uint8_t *ucode;
1815 	size_t size, count, bsize;
1816 	int i, sn, error;
1817 
1818 	/* load real firmware now */
1819 	if ((error = loadfirmware(name, &ucode, &size)) != 0) {
1820 		printf("%s: error %d, could not read firmware %s\n",
1821 		    sc->sc_dev.dv_xname, error, name);
1822 		return (EIO);
1823 	}
1824 
1825 	DPRINTF(1, "%s: uploading firmware\n", sc->sc_dev.dv_xname);
1826 
1827 	hdr = sc->sc_cmd_mem;
1828 	data = hdr + 1;
1829 	sn = 1;
1830 	for (count = 0; count < size; count += bsize) {
1831 		bsize = MIN(256, size - count);
1832 
1833 		hdr->cmd = htole16(0x0001);
1834 		hdr->size = htole16(bsize);
1835 		hdr->seqnum = htole16(sn++);
1836 		hdr->result = 0;
1837 
1838 		bcopy(ucode + count, data, bsize);
1839 
1840 		bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,
1841 		    BUS_DMASYNC_PREWRITE);
1842 		malo_send_cmd(sc, sc->sc_cmd_dmaaddr);
1843 		bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,
1844 		    BUS_DMASYNC_POSTWRITE);
1845 		delay(500);
1846 	}
1847 	free(ucode, M_DEVBUF, 0);
1848 
1849 	DPRINTF(1, "%s: firmware upload finished\n", sc->sc_dev.dv_xname);
1850 
1851 	/*
1852 	 * send a command with size 0 to tell that the firmware has been
1853 	 * uploaded
1854 	 */
1855 	hdr->cmd = htole16(0x0001);
1856 	hdr->size = 0;
1857 	hdr->seqnum = htole16(sn++);
1858 	hdr->result = 0;
1859 
1860 	bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,
1861 	    BUS_DMASYNC_PREWRITE);
1862 	malo_send_cmd(sc, sc->sc_cmd_dmaaddr);
1863 	bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,
1864 	    BUS_DMASYNC_POSTWRITE);
1865 	delay(100);
1866 
1867 	DPRINTF(1, "%s: loading firmware\n", sc->sc_dev.dv_xname);
1868 
1869 	/* wait until firmware has been loaded */
1870 	for (i = 0; i < 200; i++) {
1871 		malo_ctl_write4(sc, 0x0c10, 0x5a);
1872 		delay(500);
1873 		malo_ctl_barrier(sc, BUS_SPACE_BARRIER_WRITE |
1874 		     BUS_SPACE_BARRIER_READ);
1875 		if (malo_ctl_read4(sc, 0x0c14) == 0xf0f1f2f4)
1876 			break;
1877 	}
1878 	if (i == 200) {
1879 		printf("%s: timeout at firmware load!\n", sc->sc_dev.dv_xname);
1880 		return (ETIMEDOUT);
1881 	}
1882 
1883 	DPRINTF(1, "%s: firmware loaded\n", sc->sc_dev.dv_xname);
1884 
1885 	return (0);
1886 }
1887 
1888 int
1889 malo_set_slot(struct malo_softc *sc)
1890 {
1891 	struct ieee80211com *ic = &sc->sc_ic;
1892 
1893 	if (ic->ic_flags & IEEE80211_F_SHSLOT) {
1894 		/* set short slot */
1895 		if (malo_cmd_set_slot(sc, 1)) {
1896 			printf("%s: setting short slot failed\n",
1897 			    sc->sc_dev.dv_xname);
1898 			return (ENXIO);
1899 		}
1900 	} else {
1901 		/* set long slot */
1902 		if (malo_cmd_set_slot(sc, 0)) {
1903 			printf("%s: setting long slot failed\n",
1904 			    sc->sc_dev.dv_xname);
1905 			return (ENXIO);
1906 		}
1907 	}
1908 
1909 	return (0);
1910 }
1911 
1912 void
1913 malo_update_slot(struct ieee80211com *ic)
1914 {
1915 	struct malo_softc *sc = ic->ic_if.if_softc;
1916 
1917 	malo_set_slot(sc);
1918 
1919 #ifndef IEEE80211_STA_ONLY
1920 	if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
1921 		/* TODO */
1922 	}
1923 #endif
1924 }
1925 
1926 #ifdef MALO_DEBUG
1927 void
1928 malo_hexdump(void *buf, int len)
1929 {
1930 	u_char b[16];
1931 	int i, j, l;
1932 
1933 	for (i = 0; i < len; i += l) {
1934 		printf("%4i:", i);
1935 		l = min(sizeof(b), len - i);
1936 		bcopy(buf + i, b, l);
1937 
1938 		for (j = 0; j < sizeof(b); j++) {
1939 			if (j % 2 == 0)
1940 				printf(" ");
1941 			if (j % 8 == 0)
1942 				printf(" ");
1943 			if (j < l)
1944 				printf("%02x", (int)b[j]);
1945 			else
1946 				printf("  ");
1947 		}
1948 		printf("  |");
1949 		for (j = 0; j < l; j++) {
1950 			if (b[j] >= 0x20 && b[j] <= 0x7e)
1951 				printf("%c", b[j]);
1952 			else
1953 				printf(".");
1954 		}
1955 		printf("|\n");
1956 	}
1957 }
1958 #endif
1959 
1960 static char *
1961 malo_cmd_string(uint16_t cmd)
1962 {
1963 	int i;
1964 	static char cmd_buf[16];
1965 	static const struct {
1966 		uint16_t	 cmd_code;
1967 		char		*cmd_string;
1968 	} cmds[] = {
1969 		{ MALO_CMD_GET_HW_SPEC,		"GetHwSpecifications"	},
1970 		{ MALO_CMD_SET_RADIO,		"SetRadio"		},
1971 		{ MALO_CMD_SET_AID,		"SetAid"		},
1972 		{ MALO_CMD_SET_TXPOWER,		"SetTxPower"		},
1973 		{ MALO_CMD_SET_ANTENNA,		"SetAntenna"		},
1974 		{ MALO_CMD_SET_PRESCAN,		"SetPrescan"		},
1975 		{ MALO_CMD_SET_POSTSCAN,	"SetPostscan"		},
1976 		{ MALO_CMD_SET_RATE,		"SetRate"		},
1977 		{ MALO_CMD_SET_CHANNEL,		"SetChannel"		},
1978 		{ MALO_CMD_SET_RTS,		"SetRTS"		},
1979 		{ MALO_CMD_SET_SLOT,		"SetSlot"		},
1980 	};
1981 
1982 	for (i = 0; i < sizeof(cmds) / sizeof(cmds[0]); i++)
1983 		if ((letoh16(cmd) & 0x7fff) == cmds[i].cmd_code)
1984 			return (cmds[i].cmd_string);
1985 
1986 	snprintf(cmd_buf, sizeof(cmd_buf), "unknown %#x", cmd);
1987 	return (cmd_buf);
1988 }
1989 
1990 static char *
1991 malo_cmd_string_result(uint16_t result)
1992 {
1993 	int i;
1994 	static const struct {
1995 		uint16_t	 result_code;
1996 		char		*result_string;
1997 	} results[] = {
1998 		{ MALO_CMD_RESULT_OK,		"OK"		},
1999 		{ MALO_CMD_RESULT_ERROR,	"general error"	},
2000 		{ MALO_CMD_RESULT_NOSUPPORT,	"not supported" },
2001 		{ MALO_CMD_RESULT_PENDING,	"pending"	},
2002 		{ MALO_CMD_RESULT_BUSY,		"ignored"	},
2003 		{ MALO_CMD_RESULT_PARTIALDATA,	"incomplete"	},
2004 	};
2005 
2006 	for (i = 0; i < sizeof(results) / sizeof(results[0]); i++)
2007 		if (letoh16(result) == results[i].result_code)
2008 			return (results[i].result_string);
2009 
2010 	return ("unknown");
2011 }
2012 
2013 int
2014 malo_cmd_get_spec(struct malo_softc *sc)
2015 {
2016 	struct malo_cmdheader *hdr = sc->sc_cmd_mem;
2017 	struct malo_hw_spec *spec;
2018 
2019 	hdr->cmd = htole16(MALO_CMD_GET_HW_SPEC);
2020 	hdr->size = htole16(sizeof(*hdr) + sizeof(*spec));
2021 	hdr->seqnum = htole16(42);	/* the one and only */
2022 	hdr->result = 0;
2023 	spec = (struct malo_hw_spec *)(hdr + 1);
2024 
2025 	bzero(spec, sizeof(*spec));
2026 	memset(spec->PermanentAddress, 0xff, ETHER_ADDR_LEN);
2027 	spec->CookiePtr = htole32(sc->sc_cookie_dmaaddr);
2028 
2029 	bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,
2030 	    BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
2031 
2032 	if (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr) != 0)
2033 		return (ETIMEDOUT);
2034 
2035 	/* get the data from the buffer */
2036 	DPRINTF(1, "%s: get_hw_spec: V%x R%x, #WCB %d, #Mcast %d, Regcode %d, "
2037 	    "#Ant %d\n", sc->sc_dev.dv_xname, htole16(spec->HwVersion),
2038 	    htole32(spec->FWReleaseNumber), htole16(spec->NumOfWCB),
2039 	    htole16(spec->NumOfMCastAdr), htole16(spec->RegionCode),
2040 	    htole16(spec->NumberOfAntenna));
2041 
2042 	/* tell the DMA engine where our rings are */
2043 	malo_mem_write4(sc, letoh32(spec->RxPdRdPtr) & 0xffff,
2044 	    sc->sc_rxring.physaddr);
2045 	malo_mem_write4(sc, letoh32(spec->RxPdWrPtr) & 0xffff,
2046 	    sc->sc_rxring.physaddr);
2047 	malo_mem_write4(sc, letoh32(spec->WcbBase0) & 0xffff,
2048 	    sc->sc_txring.physaddr);
2049 
2050 	/* save DMA RX pointers for later use */
2051 	sc->sc_RxPdRdPtr = letoh32(spec->RxPdRdPtr) & 0xffff;
2052 	sc->sc_RxPdWrPtr = letoh32(spec->RxPdWrPtr) & 0xffff;
2053 
2054 	return (0);
2055 }
2056 
2057 int
2058 malo_cmd_set_prescan(struct malo_softc *sc)
2059 {
2060 	struct malo_cmdheader *hdr = sc->sc_cmd_mem;
2061 
2062 	hdr->cmd = htole16(MALO_CMD_SET_PRESCAN);
2063 	hdr->size = htole16(sizeof(*hdr));
2064 	hdr->seqnum = 1;
2065 	hdr->result = 0;
2066 
2067 	bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,
2068 	    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
2069 
2070 	return (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr));
2071 }
2072 
2073 int
2074 malo_cmd_set_postscan(struct malo_softc *sc, uint8_t *macaddr, uint8_t ibsson)
2075 {
2076 	struct malo_cmdheader *hdr = sc->sc_cmd_mem;
2077 	struct malo_cmd_postscan *body;
2078 
2079 	hdr->cmd = htole16(MALO_CMD_SET_POSTSCAN);
2080 	hdr->size = htole16(sizeof(*hdr) + sizeof(*body));
2081 	hdr->seqnum = 1;
2082 	hdr->result = 0;
2083 	body = (struct malo_cmd_postscan *)(hdr + 1);
2084 
2085 	bzero(body, sizeof(*body));
2086 	memcpy(&body->bssid, macaddr, ETHER_ADDR_LEN);
2087 	body->isibss = htole32(ibsson);
2088 
2089 	bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,
2090 	    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
2091 
2092 	return (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr));
2093 }
2094 
2095 int
2096 malo_cmd_set_channel(struct malo_softc *sc, uint8_t channel)
2097 {
2098 	struct malo_cmdheader *hdr = sc->sc_cmd_mem;
2099 	struct malo_cmd_channel *body;
2100 
2101 	hdr->cmd = htole16(MALO_CMD_SET_CHANNEL);
2102 	hdr->size = htole16(sizeof(*hdr) + sizeof(*body));
2103 	hdr->seqnum = 1;
2104 	hdr->result = 0;
2105 	body = (struct malo_cmd_channel *)(hdr + 1);
2106 
2107 	bzero(body, sizeof(*body));
2108 	body->action = htole16(1);
2109 	body->channel = channel;
2110 
2111 	bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,
2112 	    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
2113 
2114 	return (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr));
2115 }
2116 
2117 int
2118 malo_cmd_set_antenna(struct malo_softc *sc, uint16_t antenna)
2119 {
2120 	struct malo_cmdheader *hdr = sc->sc_cmd_mem;
2121 	struct malo_cmd_antenna *body;
2122 
2123 	hdr->cmd = htole16(MALO_CMD_SET_ANTENNA);
2124 	hdr->size = htole16(sizeof(*hdr) + sizeof(*body));
2125 	hdr->seqnum = 1;
2126 	hdr->result = 0;
2127 	body = (struct malo_cmd_antenna *)(hdr + 1);
2128 
2129 	bzero(body, sizeof(*body));
2130 	body->action = htole16(antenna);
2131 	if (antenna == 1)
2132 		body->mode = htole16(0xffff);
2133 	else
2134 		body->mode = htole16(2);
2135 
2136 	bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,
2137 	    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
2138 
2139 	return (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr));
2140 }
2141 
2142 int
2143 malo_cmd_set_radio(struct malo_softc *sc, uint16_t enable,
2144     uint16_t preamble_mode)
2145 {
2146 	struct malo_cmdheader *hdr = sc->sc_cmd_mem;
2147 	struct malo_cmd_radio *body;
2148 
2149 	hdr->cmd = htole16(MALO_CMD_SET_RADIO);
2150 	hdr->size = htole16(sizeof(*hdr) + sizeof(*body));
2151 	hdr->seqnum = 1;
2152 	hdr->result = 0;
2153 	body = (struct malo_cmd_radio *)(hdr + 1);
2154 
2155 	bzero(body, sizeof(*body));
2156 	body->action = htole16(1);
2157 	body->preamble_mode = htole16(preamble_mode);
2158 	body->enable = htole16(enable);
2159 
2160 	bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,
2161 	    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
2162 
2163 	return (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr));
2164 }
2165 
2166 int
2167 malo_cmd_set_aid(struct malo_softc *sc, uint8_t *bssid, uint16_t associd)
2168 {
2169 	struct malo_cmdheader *hdr = sc->sc_cmd_mem;
2170 	struct malo_cmd_aid *body;
2171 
2172 	hdr->cmd = htole16(MALO_CMD_SET_AID);
2173 	hdr->size = htole16(sizeof(*hdr) + sizeof(*body));
2174 	hdr->seqnum = 1;
2175 	hdr->result = 0;
2176 	body = (struct malo_cmd_aid *)(hdr + 1);
2177 
2178 	bzero(body, sizeof(*body));
2179 	body->associd = htole16(associd);
2180 	memcpy(&body->macaddr[0], bssid, IEEE80211_ADDR_LEN);
2181 
2182 	bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,
2183 	    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
2184 
2185 	return (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr));
2186 }
2187 
2188 int
2189 malo_cmd_set_txpower(struct malo_softc *sc, unsigned int powerlevel)
2190 {
2191 	struct malo_cmdheader *hdr = sc->sc_cmd_mem;
2192 	struct malo_cmd_txpower *body;
2193 
2194 	hdr->cmd = htole16(MALO_CMD_SET_TXPOWER);
2195 	hdr->size = htole16(sizeof(*hdr) + sizeof(*body));
2196 	hdr->seqnum = 1;
2197 	hdr->result = 0;
2198 	body = (struct malo_cmd_txpower *)(hdr + 1);
2199 
2200 	bzero(body, sizeof(*body));
2201 	body->action = htole16(1);
2202 	if (powerlevel < 30)
2203 		body->supportpowerlvl = htole16(5);	/* LOW */
2204 	else if (powerlevel >= 30 && powerlevel < 60)
2205 		body->supportpowerlvl = htole16(10);	/* MEDIUM */
2206 	else
2207 		body->supportpowerlvl = htole16(15);	/* HIGH */
2208 
2209 	bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,
2210 	    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
2211 
2212 	return (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr));
2213 }
2214 
2215 int
2216 malo_cmd_set_rts(struct malo_softc *sc, uint32_t threshold)
2217 {
2218 	struct malo_cmdheader *hdr = sc->sc_cmd_mem;
2219 	struct malo_cmd_rts *body;
2220 
2221 	hdr->cmd = htole16(MALO_CMD_SET_RTS);
2222 	hdr->size = htole16(sizeof(*hdr) + sizeof(*body));
2223 	hdr->seqnum = 1;
2224 	hdr->result = 0;
2225 	body = (struct malo_cmd_rts *)(hdr + 1);
2226 
2227 	bzero(body, sizeof(*body));
2228 	body->action = htole16(1);
2229 	body->threshold = htole32(threshold);
2230 
2231 	bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,
2232 	    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
2233 
2234 	return (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr));
2235 }
2236 
2237 int
2238 malo_cmd_set_slot(struct malo_softc *sc, uint8_t slot)
2239 {
2240 	struct malo_cmdheader *hdr = sc->sc_cmd_mem;
2241 	struct malo_cmd_slot *body;
2242 
2243 	hdr->cmd = htole16(MALO_CMD_SET_SLOT);
2244 	hdr->size = htole16(sizeof(*hdr) + sizeof(*body));
2245 	hdr->seqnum = 1;
2246 	hdr->result = 0;
2247 	body = (struct malo_cmd_slot *)(hdr + 1);
2248 
2249 	bzero(body, sizeof(*body));
2250 	body->action = htole16(1);
2251 	body->slot = slot;
2252 
2253 	bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,
2254 	    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
2255 
2256 	return (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr));
2257 }
2258 
2259 int
2260 malo_cmd_set_rate(struct malo_softc *sc, uint8_t rate)
2261 {
2262 	struct ieee80211com *ic = &sc->sc_ic;
2263 	struct malo_cmdheader *hdr = sc->sc_cmd_mem;
2264 	struct malo_cmd_rate *body;
2265 	int i;
2266 
2267 	hdr->cmd = htole16(MALO_CMD_SET_RATE);
2268 	hdr->size = htole16(sizeof(*hdr) + sizeof(*body));
2269 	hdr->seqnum = 1;
2270 	hdr->result = 0;
2271 	body = (struct malo_cmd_rate *)(hdr + 1);
2272 
2273 	bzero(body, sizeof(*body));
2274 
2275 #ifndef IEEE80211_STA_ONLY
2276 	if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
2277 		/* TODO */
2278 	} else
2279 #endif
2280 	{
2281 		body->aprates[0] = 2;
2282 		body->aprates[1] = 4;
2283 		body->aprates[2] = 11;
2284 		body->aprates[3] = 22;
2285 		if (ic->ic_curmode == IEEE80211_MODE_11G) {
2286 			body->aprates[4] = 0;
2287 			body->aprates[5] = 12;
2288 			body->aprates[6] = 18;
2289 			body->aprates[7] = 24;
2290 			body->aprates[8] = 36;
2291 			body->aprates[9] = 48;
2292 			body->aprates[10] = 72;
2293 			body->aprates[11] = 96;
2294 			body->aprates[12] = 108;
2295 		}
2296 	}
2297 
2298 	if (rate != 0) {
2299 		/* fixed rate */
2300 		for (i = 0; i < 13; i++) {
2301 			if (body->aprates[i] == rate) {
2302 				body->rateindex = i;
2303 				body->dataratetype = 1;
2304 				break;
2305 			}
2306 		}
2307 	}
2308 
2309 	bus_dmamap_sync(sc->sc_dmat, sc->sc_cmd_dmam, 0, PAGE_SIZE,
2310 	    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
2311 
2312 	return (malo_send_cmd_dma(sc, sc->sc_cmd_dmaaddr));
2313 }
2314 
2315 void
2316 malo_cmd_response(struct malo_softc *sc)
2317 {
2318 	struct malo_cmdheader *hdr = sc->sc_cmd_mem;
2319 
2320 	if (letoh16(hdr->result) != MALO_CMD_RESULT_OK) {
2321 		printf("%s: firmware cmd %s failed with %s\n",
2322 		    sc->sc_dev.dv_xname,
2323 		    malo_cmd_string(hdr->cmd),
2324 		    malo_cmd_string_result(hdr->result));
2325 	}
2326 
2327 #ifdef MALO_DEBUG
2328 	printf("%s: cmd answer for %s=%s\n",
2329 	    sc->sc_dev.dv_xname,
2330 	    malo_cmd_string(hdr->cmd),
2331 	    malo_cmd_string_result(hdr->result));
2332 
2333 	if (malo_d > 2)
2334 		malo_hexdump(hdr, letoh16(hdr->size));
2335 #endif
2336 }
2337