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