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