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