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