This source file includes following definitions.
- acx_attach
- acx_detach
- acx_init
- acx_init_info_reg
- acx_set_crypt_keys
- acx_next_scan
- acx_stop
- acx_config
- acx_read_config
- acx_write_config
- acx_rx_config
- acx_ioctl
- acx_start
- acx_watchdog
- acx_intr
- acx_disable_intr
- acx_enable_intr
- acx_txeof
- acx_txerr
- acx_rxeof
- acx_reset
- acx_read_eeprom
- acx_read_phyreg
- acx_write_phyreg
- acx_load_base_firmware
- acx_load_radio_firmware
- acx_load_firmware
- acx_node_alloc
- acx_newstate
- acx_init_tmplt_ordered
- acx_dma_alloc
- acx_dma_free
- acx_init_tx_ring
- acx_init_rx_ring
- acx_newbuf
- acx_encap
- acx_set_null_tmplt
- acx_set_probe_req_tmplt
- acx_set_probe_resp_tmplt
- acx_beacon_locate
- acx_set_beacon_tmplt
- acx_init_cmd_reg
- acx_join_bss
- acx_set_channel
- acx_get_conf
- acx_set_conf
- acx_set_tmplt
- acx_init_radio
- acx_exec_command
- acx_get_rf
- acx_get_maxrssi
- acx_iter_func
- acx_amrr_timeout
- acx_newassoc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89 #include <sys/cdefs.h>
90 #include "bpfilter.h"
91
92 #include <sys/param.h>
93 #include <sys/systm.h>
94 #include <sys/kernel.h>
95 #include <sys/malloc.h>
96 #include <sys/mbuf.h>
97 #include <sys/proc.h>
98 #include <sys/socket.h>
99 #include <sys/sockio.h>
100 #include <sys/ioctl.h>
101 #include <sys/types.h>
102
103 #include <machine/bus.h>
104 #include <machine/endian.h>
105 #include <machine/intr.h>
106
107 #include <net/if.h>
108 #include <net/if_arp.h>
109 #include <net/if_dl.h>
110 #include <net/if_media.h>
111 #include <net/if_types.h>
112
113 #if NBPFILTER > 0
114 #include <net/bpf.h>
115 #endif
116
117 #ifdef INET
118 #include <netinet/in.h>
119 #include <netinet/in_systm.h>
120 #include <netinet/in_var.h>
121 #include <netinet/if_ether.h>
122 #include <netinet/ip.h>
123 #endif
124
125 #include <net80211/ieee80211_var.h>
126 #include <net80211/ieee80211_amrr.h>
127 #include <net80211/ieee80211_radiotap.h>
128
129 #include <dev/pci/pcireg.h>
130 #include <dev/pci/pcivar.h>
131 #include <dev/pci/pcidevs.h>
132
133 #include <dev/ic/acxvar.h>
134 #include <dev/ic/acxreg.h>
135
136 #ifdef ACX_DEBUG
137 int acxdebug = 0;
138 #endif
139
140 int acx_attach(struct acx_softc *);
141 int acx_detach(void *);
142
143 int acx_init(struct ifnet *);
144 int acx_stop(struct acx_softc *);
145 void acx_init_info_reg(struct acx_softc *);
146 int acx_config(struct acx_softc *);
147 int acx_read_config(struct acx_softc *, struct acx_config *);
148 int acx_write_config(struct acx_softc *, struct acx_config *);
149 int acx_rx_config(struct acx_softc *);
150 int acx_set_crypt_keys(struct acx_softc *);
151 void acx_next_scan(void *);
152
153 void acx_start(struct ifnet *);
154 void acx_watchdog(struct ifnet *);
155
156 int acx_ioctl(struct ifnet *, u_long, caddr_t);
157
158 int acx_intr(void *);
159 void acx_disable_intr(struct acx_softc *);
160 void acx_enable_intr(struct acx_softc *);
161 void acx_txeof(struct acx_softc *);
162 void acx_txerr(struct acx_softc *, uint8_t);
163 void acx_rxeof(struct acx_softc *);
164
165 int acx_dma_alloc(struct acx_softc *);
166 void acx_dma_free(struct acx_softc *);
167 int acx_init_tx_ring(struct acx_softc *);
168 int acx_init_rx_ring(struct acx_softc *);
169 int acx_newbuf(struct acx_softc *, struct acx_rxbuf *, int);
170 int acx_encap(struct acx_softc *, struct acx_txbuf *,
171 struct mbuf *, struct ieee80211_node *, int);
172
173 int acx_reset(struct acx_softc *);
174
175 int acx_set_null_tmplt(struct acx_softc *);
176 int acx_set_probe_req_tmplt(struct acx_softc *, const char *, int);
177 int acx_set_probe_resp_tmplt(struct acx_softc *, struct ieee80211_node *);
178 int acx_beacon_locate(struct mbuf *, u_int8_t);
179 int acx_set_beacon_tmplt(struct acx_softc *, struct ieee80211_node *);
180
181 int acx_read_eeprom(struct acx_softc *, uint32_t, uint8_t *);
182 int acx_read_phyreg(struct acx_softc *, uint32_t, uint8_t *);
183 const char * acx_get_rf(int);
184 int acx_get_maxrssi(int);
185
186 int acx_load_firmware(struct acx_softc *, uint32_t,
187 const uint8_t *, int);
188 int acx_load_radio_firmware(struct acx_softc *, const char *);
189 int acx_load_base_firmware(struct acx_softc *, const char *);
190
191 struct ieee80211_node
192 *acx_node_alloc(struct ieee80211com *);
193 int acx_newstate(struct ieee80211com *, enum ieee80211_state, int);
194
195 void acx_init_cmd_reg(struct acx_softc *);
196 int acx_join_bss(struct acx_softc *, uint8_t, struct ieee80211_node *);
197 int acx_set_channel(struct acx_softc *, uint8_t);
198 int acx_init_radio(struct acx_softc *, uint32_t, uint32_t);
199
200 void acx_iter_func(void *, struct ieee80211_node *);
201 void acx_amrr_timeout(void *);
202 void acx_newassoc(struct ieee80211com *, struct ieee80211_node *, int);
203
204 static int acx_chanscan_rate = 5;
205 int acx_beacon_intvl = 100;
206
207
208
209
210 #define ACX_MODE_ADHOC 0
211 #define ACX_MODE_UNUSED 1
212 #define ACX_MODE_STA 2
213 #define ACX_MODE_AP 3
214
215 struct cfdriver acx_cd = {
216 NULL, "acx", DV_IFNET
217 };
218
219 int
220 acx_attach(struct acx_softc *sc)
221 {
222 struct ieee80211com *ic = &sc->sc_ic;
223 struct ifnet *ifp = &sc->sc_ic.ic_if;
224 int i, error;
225
226 ifp->if_softc = sc;
227
228
229 timeout_set(&sc->sc_chanscan_timer, acx_next_scan, sc);
230
231
232 error = acx_dma_alloc(sc);
233 if (error)
234 return (error);
235
236
237 error = acx_reset(sc);
238 if (error)
239 return (error);
240
241
242 acx_disable_intr(sc);
243
244
245 #define EEINFO_RETRY_MAX 50
246 for (i = 0; i < EEINFO_RETRY_MAX; ++i) {
247 uint16_t ee_info;
248
249 ee_info = CSR_READ_2(sc, ACXREG_EEPROM_INFO);
250 if (ACX_EEINFO_HAS_RADIO_TYPE(ee_info)) {
251 sc->sc_form_factor = ACX_EEINFO_FORM_FACTOR(ee_info);
252 sc->sc_radio_type = ACX_EEINFO_RADIO_TYPE(ee_info);
253 break;
254 }
255 DELAY(10000);
256 }
257 if (i == EEINFO_RETRY_MAX)
258 return (ENXIO);
259 #undef EEINFO_RETRY_MAX
260
261 printf("%s: %s, radio %s (0x%02x)", sc->sc_dev.dv_xname,
262 (sc->sc_flags & ACX_FLAG_ACX111) ? "ACX111" : "ACX100",
263 acx_get_rf(sc->sc_radio_type), sc->sc_radio_type);
264
265 #ifdef DUMP_EEPROM
266 for (i = 0; i < 0x40; ++i) {
267 uint8_t val;
268
269 error = acx_read_eeprom(sc, i, &val);
270 if (i % 10 == 0)
271 printf("\n");
272 printf("%02x ", val);
273 }
274 printf("\n");
275 #endif
276
277
278 error = acx_read_eeprom(sc, ACX_EE_VERSION_OFS, &sc->sc_eeprom_ver);
279 if (error)
280 return (error);
281
282 printf(", EEPROM ver %u", sc->sc_eeprom_ver);
283
284 ifp->if_softc = sc;
285 ifp->if_init = acx_init;
286 ifp->if_ioctl = acx_ioctl;
287 ifp->if_start = acx_start;
288 ifp->if_watchdog = acx_watchdog;
289 ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST;
290 strlcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ);
291 IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
292 IFQ_SET_READY(&ifp->if_snd);
293
294
295 for (i = 1; i <= 14; ++i) {
296 ic->ic_channels[i].ic_freq =
297 ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ);
298 ic->ic_channels[i].ic_flags = sc->chip_chan_flags;
299 }
300
301 ic->ic_opmode = IEEE80211_M_STA;
302 ic->ic_state = IEEE80211_S_INIT;
303
304
305
306
307 ic->ic_caps =
308 IEEE80211_C_WEP |
309 IEEE80211_C_IBSS |
310 IEEE80211_C_MONITOR |
311 IEEE80211_C_HOSTAP |
312 IEEE80211_C_SHPREAMBLE;
313
314
315 for (i = 0; i < IEEE80211_ADDR_LEN; ++i) {
316 error = acx_read_eeprom(sc, sc->chip_ee_eaddr_ofs - i,
317 &ic->ic_myaddr[i]);
318 }
319
320 printf(", address %s\n", ether_sprintf(ic->ic_myaddr));
321
322 if_attach(ifp);
323 ieee80211_ifattach(ifp);
324
325
326 ic->ic_node_alloc = acx_node_alloc;
327 ic->ic_newassoc = acx_newassoc;
328
329
330 sc->sc_newstate = ic->ic_newstate;
331 ic->ic_newstate = acx_newstate;
332
333
334 ic->ic_max_rssi = acx_get_maxrssi(sc->sc_radio_type);
335
336 ieee80211_media_init(ifp, ieee80211_media_change,
337 ieee80211_media_status);
338
339
340 sc->amrr.amrr_min_success_threshold = 1;
341 sc->amrr.amrr_max_success_threshold = 15;
342 timeout_set(&sc->amrr_ch, acx_amrr_timeout, sc);
343
344 sc->sc_long_retry_limit = 4;
345 sc->sc_short_retry_limit = 7;
346 sc->sc_msdu_lifetime = 4096;
347
348 #if NBPFILTER > 0
349 bpfattach(&sc->sc_drvbpf, ifp, DLT_IEEE802_11_RADIO,
350 sizeof(struct ieee80211_frame) + 64);
351
352 sc->sc_rxtap_len = sizeof(sc->sc_rxtapu);
353 sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
354 sc->sc_rxtap.wr_ihdr.it_present = htole32(ACX_RX_RADIOTAP_PRESENT);
355
356 sc->sc_txtap_len = sizeof(sc->sc_txtapu);
357 sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
358 sc->sc_txtap.wt_ihdr.it_present = htole32(ACX_TX_RADIOTAP_PRESENT);
359 #endif
360
361 return (0);
362 }
363
364 int
365 acx_detach(void *xsc)
366 {
367 struct acx_softc *sc = xsc;
368 struct ieee80211com *ic = &sc->sc_ic;
369 struct ifnet *ifp = &ic->ic_if;
370
371 acx_stop(sc);
372 ieee80211_ifdetach(ifp);
373 if_detach(ifp);
374
375 acx_dma_free(sc);
376
377 return (0);
378 }
379
380 int
381 acx_init(struct ifnet *ifp)
382 {
383 struct acx_softc *sc = ifp->if_softc;
384 struct ieee80211com *ic = &sc->sc_ic;
385 char fname[] = "tiacx111c16";
386 int error, combined = 0;
387
388 error = acx_stop(sc);
389 if (error)
390 return (EIO);
391
392
393 if (sc->sc_enable != NULL)
394 (*sc->sc_enable)(sc);
395
396 error = acx_init_tx_ring(sc);
397 if (error) {
398 printf("%s: can't initialize TX ring\n",
399 sc->sc_dev.dv_xname);
400 goto back;
401 }
402
403 error = acx_init_rx_ring(sc);
404 if (error) {
405 printf("%s: can't initialize RX ring\n",
406 sc->sc_dev.dv_xname);
407 goto back;
408 }
409
410 if (sc->sc_flags & ACX_FLAG_ACX111) {
411 snprintf(fname, sizeof(fname), "tiacx111c%02X",
412 sc->sc_radio_type);
413 error = acx_load_base_firmware(sc, fname);
414
415 if (!error)
416 combined = 1;
417 }
418
419 if (!combined) {
420 snprintf(fname, sizeof(fname), "tiacx%s",
421 (sc->sc_flags & ACX_FLAG_ACX111) ? "111" : "100");
422 error = acx_load_base_firmware(sc, fname);
423 }
424
425 if (error)
426 goto back;
427
428
429
430
431
432 acx_init_cmd_reg(sc);
433 acx_init_info_reg(sc);
434
435 sc->sc_flags |= ACX_FLAG_FW_LOADED;
436
437 if (!combined) {
438 snprintf(fname, sizeof(fname), "tiacx%sr%02X",
439 (sc->sc_flags & ACX_FLAG_ACX111) ? "111" : "100",
440 sc->sc_radio_type);
441 error = acx_load_radio_firmware(sc, fname);
442
443 if (error)
444 goto back;
445 }
446
447 error = sc->chip_init(sc);
448 if (error)
449 goto back;
450
451
452 error = acx_config(sc);
453 if (error)
454 goto back;
455
456
457 if (sc->sc_ic.ic_flags & IEEE80211_F_WEPON) {
458 error = acx_set_crypt_keys(sc);
459 if (error)
460 goto back;
461 }
462
463
464 CSR_CLRB_2(sc, ACXREG_GPIO_OUT, sc->chip_gpio_pled);
465
466 acx_enable_intr(sc);
467
468 ifp->if_flags |= IFF_RUNNING;
469 ifp->if_flags &= ~IFF_OACTIVE;
470
471 if (ic->ic_opmode != IEEE80211_M_MONITOR)
472
473 ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
474 else
475
476 ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
477
478 back:
479 if (error)
480 acx_stop(sc);
481
482 return (0);
483 }
484
485 void
486 acx_init_info_reg(struct acx_softc *sc)
487 {
488 sc->sc_info = CSR_READ_4(sc, ACXREG_INFO_REG_OFFSET);
489 sc->sc_info_param = sc->sc_info + ACX_INFO_REG_SIZE;
490 }
491
492 int
493 acx_set_crypt_keys(struct acx_softc *sc)
494 {
495 struct ieee80211com *ic = &sc->sc_ic;
496 struct acx_conf_wep_txkey wep_txkey;
497 int i, error, got_wk = 0;
498
499 for (i = 0; i < IEEE80211_WEP_NKID; ++i) {
500 struct ieee80211_key *k = &ic->ic_nw_keys[i];
501
502 if (k->k_len == 0)
503 continue;
504
505 if (sc->chip_hw_crypt) {
506 error = sc->chip_set_wepkey(sc, k, i);
507 if (error)
508 return (error);
509 got_wk = 1;
510 }
511 }
512
513 if (!got_wk)
514 return (0);
515
516
517 wep_txkey.wep_txkey = ic->ic_wep_txkey;
518 if (acx_set_conf(sc, ACX_CONF_WEP_TXKEY, &wep_txkey,
519 sizeof(wep_txkey)) != 0) {
520 printf("%s: set WEP txkey failed\n", sc->sc_dev.dv_xname);
521 return (ENXIO);
522 }
523
524 return (0);
525 }
526
527 void
528 acx_next_scan(void *arg)
529 {
530 struct acx_softc *sc = arg;
531 struct ieee80211com *ic = &sc->sc_ic;
532 struct ifnet *ifp = &ic->ic_if;
533
534 if (ic->ic_state == IEEE80211_S_SCAN)
535 ieee80211_next_scan(ifp);
536 }
537
538 int
539 acx_stop(struct acx_softc *sc)
540 {
541 struct ieee80211com *ic = &sc->sc_ic;
542 struct ifnet *ifp = &ic->ic_if;
543 struct acx_buf_data *bd = &sc->sc_buf_data;
544 struct acx_ring_data *rd = &sc->sc_ring_data;
545 int i, error;
546
547 sc->sc_firmware_ver = 0;
548 sc->sc_hardware_id = 0;
549
550
551 error = acx_reset(sc);
552 if (error)
553 return (error);
554
555
556 sc->sc_flags &= ~ACX_FLAG_FW_LOADED;
557
558 acx_disable_intr(sc);
559
560
561 timeout_del(&sc->sc_chanscan_timer);
562
563
564 CSR_SETB_2(sc, ACXREG_GPIO_OUT, sc->chip_gpio_pled);
565
566
567 for (i = 0; i < ACX_TX_DESC_CNT; ++i) {
568 struct acx_txbuf *buf;
569 struct ieee80211_node *ni;
570
571 buf = &bd->tx_buf[i];
572
573 if (buf->tb_mbuf != NULL) {
574 bus_dmamap_unload(sc->sc_dmat, buf->tb_mbuf_dmamap);
575 m_freem(buf->tb_mbuf);
576 buf->tb_mbuf = NULL;
577 }
578
579 ni = (struct ieee80211_node *)buf->tb_node;
580 if (ni != NULL)
581 ieee80211_release_node(ic, ni);
582 buf->tb_node = NULL;
583 }
584
585
586 bzero(rd->tx_ring, ACX_TX_RING_SIZE);
587
588
589 for (i = 0; i < ACX_RX_DESC_CNT; ++i) {
590 if (bd->rx_buf[i].rb_mbuf != NULL) {
591 bus_dmamap_unload(sc->sc_dmat,
592 bd->rx_buf[i].rb_mbuf_dmamap);
593 m_freem(bd->rx_buf[i].rb_mbuf);
594 bd->rx_buf[i].rb_mbuf = NULL;
595 }
596 }
597
598
599 bzero(rd->rx_ring, ACX_RX_RING_SIZE);
600
601 ifp->if_timer = 0;
602 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
603 ieee80211_new_state(&sc->sc_ic, IEEE80211_S_INIT, -1);
604
605
606 if (sc->sc_disable != NULL)
607 (*sc->sc_disable)(sc);
608
609 return (0);
610 }
611
612 int
613 acx_config(struct acx_softc *sc)
614 {
615 struct acx_config conf;
616 int error;
617
618 error = acx_read_config(sc, &conf);
619 if (error)
620 return (error);
621
622 error = acx_write_config(sc, &conf);
623 if (error)
624 return (error);
625
626 error = acx_rx_config(sc);
627 if (error)
628 return (error);
629
630 if (acx_set_probe_req_tmplt(sc, "", 0) != 0) {
631 printf("%s: can't set probe req template "
632 "(empty ssid)\n", sc->sc_dev.dv_xname);
633 return (ENXIO);
634 }
635
636
637 if (acx_set_null_tmplt(sc) != 0) {
638 printf("%s: can't set null data template\n",
639 sc->sc_dev.dv_xname);
640 return (ENXIO);
641 }
642
643 return (0);
644 }
645
646 int
647 acx_read_config(struct acx_softc *sc, struct acx_config *conf)
648 {
649 struct acx_conf_regdom reg_dom;
650 struct acx_conf_antenna ant;
651 struct acx_conf_fwrev fw_rev;
652 uint32_t fw_rev_no;
653 uint8_t sen;
654 int error;
655
656
657 if (acx_get_conf(sc, ACX_CONF_REGDOM, ®_dom, sizeof(reg_dom)) != 0) {
658 printf("%s: can't get region domain\n", sc->sc_dev.dv_xname);
659 return (ENXIO);
660 }
661 conf->regdom = reg_dom.regdom;
662 DPRINTF(("%s: regdom %02x\n", sc->sc_dev.dv_xname, reg_dom.regdom));
663
664
665 if (acx_get_conf(sc, ACX_CONF_ANTENNA, &ant, sizeof(ant)) != 0) {
666 printf("%s: can't get antenna\n", sc->sc_dev.dv_xname);
667 return (ENXIO);
668 }
669 conf->antenna = ant.antenna;
670 DPRINTF(("%s: antenna %02x\n", sc->sc_dev.dv_xname, ant.antenna));
671
672
673 if (sc->sc_radio_type == ACX_RADIO_TYPE_MAXIM ||
674 sc->sc_radio_type == ACX_RADIO_TYPE_RFMD ||
675 sc->sc_radio_type == ACX_RADIO_TYPE_RALINK) {
676 error = acx_read_phyreg(sc, ACXRV_PHYREG_SENSITIVITY, &sen);
677 if (error) {
678 printf("%s: can't get sensitivity\n",
679 sc->sc_dev.dv_xname);
680 return (error);
681 }
682 } else
683 sen = 0;
684 DPRINTF(("%s: sensitivity %02x\n", sc->sc_dev.dv_xname, sen));
685
686
687 if (acx_get_conf(sc, ACX_CONF_FWREV, &fw_rev, sizeof(fw_rev)) != 0) {
688 printf("%s: can't get firmware revision\n",
689 sc->sc_dev.dv_xname);
690 return (ENXIO);
691 }
692
693 if (strncmp(fw_rev.fw_rev, "Rev ", 4) != 0) {
694 printf("%s: strange revision string -- %s\n",
695 sc->sc_dev.dv_xname, fw_rev.fw_rev);
696 fw_rev_no = 0x01090407;
697 } else {
698
699
700
701
702
703 fw_rev_no = fw_rev.fw_rev[0] << 24;
704 fw_rev_no |= fw_rev.fw_rev[1] << 16;
705 fw_rev_no |= fw_rev.fw_rev[2] << 8;
706 fw_rev_no |= fw_rev.fw_rev[3];
707 }
708 sc->sc_firmware_ver = fw_rev_no;
709 sc->sc_hardware_id = letoh32(fw_rev.hw_id);
710 DPRINTF(("%s: fw rev %08x, hw id %08x\n",
711 sc->sc_dev.dv_xname, sc->sc_firmware_ver, sc->sc_hardware_id));
712
713 if (sc->chip_read_config != NULL) {
714 error = sc->chip_read_config(sc, conf);
715 if (error)
716 return (error);
717 }
718
719 return (0);
720 }
721
722 int
723 acx_write_config(struct acx_softc *sc, struct acx_config *conf)
724 {
725 struct acx_conf_nretry_short sretry;
726 struct acx_conf_nretry_long lretry;
727 struct acx_conf_msdu_lifetime msdu_lifetime;
728 struct acx_conf_rate_fallback rate_fb;
729 struct acx_conf_antenna ant;
730 struct acx_conf_regdom reg_dom;
731 struct ifnet *ifp = &sc->sc_ic.ic_if;
732 int error;
733
734
735 sretry.nretry = sc->sc_short_retry_limit;
736 if (acx_set_conf(sc, ACX_CONF_NRETRY_SHORT, &sretry,
737 sizeof(sretry)) != 0) {
738 printf("%s: can't set short retry limit\n", ifp->if_xname);
739 return (ENXIO);
740 }
741
742 lretry.nretry = sc->sc_long_retry_limit;
743 if (acx_set_conf(sc, ACX_CONF_NRETRY_LONG, &lretry,
744 sizeof(lretry)) != 0) {
745 printf("%s: can't set long retry limit\n", ifp->if_xname);
746 return (ENXIO);
747 }
748
749
750 msdu_lifetime.lifetime = htole32(sc->sc_msdu_lifetime);
751 if (acx_set_conf(sc, ACX_CONF_MSDU_LIFETIME, &msdu_lifetime,
752 sizeof(msdu_lifetime)) != 0) {
753 printf("%s: can't set MSDU lifetime\n", ifp->if_xname);
754 return (ENXIO);
755 }
756
757
758 rate_fb.ratefb_enable = 1;
759 if (acx_set_conf(sc, ACX_CONF_RATE_FALLBACK, &rate_fb,
760 sizeof(rate_fb)) != 0) {
761 printf("%s: can't enable rate fallback\n", ifp->if_xname);
762 return (ENXIO);
763 }
764
765
766 ant.antenna = conf->antenna;
767 if (acx_set_conf(sc, ACX_CONF_ANTENNA, &ant, sizeof(ant)) != 0) {
768 printf("%s: can't set antenna\n", ifp->if_xname);
769 return (ENXIO);
770 }
771
772
773 reg_dom.regdom = conf->regdom;
774 if (acx_set_conf(sc, ACX_CONF_REGDOM, ®_dom, sizeof(reg_dom)) != 0) {
775 printf("%s: can't set region domain\n", ifp->if_xname);
776 return (ENXIO);
777 }
778
779 if (sc->chip_write_config != NULL) {
780 error = sc->chip_write_config(sc, conf);
781 if (error)
782 return (error);
783 }
784
785 return (0);
786 }
787
788 int
789 acx_rx_config(struct acx_softc *sc)
790 {
791 struct ieee80211com *ic = &sc->sc_ic;
792 struct acx_conf_rxopt rx_opt;
793
794
795 rx_opt.opt1 = htole16(RXOPT1_INCL_RXBUF_HDR);
796 rx_opt.opt2 = htole16(
797 RXOPT2_RECV_ASSOC_REQ |
798 RXOPT2_RECV_AUTH |
799 RXOPT2_RECV_BEACON |
800 RXOPT2_RECV_CF |
801 RXOPT2_RECV_CTRL |
802 RXOPT2_RECV_DATA |
803 RXOPT2_RECV_MGMT |
804 RXOPT2_RECV_PROBE_REQ |
805 RXOPT2_RECV_PROBE_RESP |
806 RXOPT2_RECV_OTHER);
807
808
809 if (ic->ic_opmode == IEEE80211_M_MONITOR) {
810 rx_opt.opt1 |= RXOPT1_PROMISC;
811 rx_opt.opt2 |= RXOPT2_RECV_BROKEN | RXOPT2_RECV_ACK;
812 } else
813 rx_opt.opt1 |= RXOPT1_FILT_FDEST;
814
815
816 if (acx_set_conf(sc, ACX_CONF_RXOPT, &rx_opt, sizeof(rx_opt)) != 0) {
817 printf("%s: can not set RX options!\n", sc->sc_dev.dv_xname);
818 return (ENXIO);
819 }
820
821 return (0);
822 }
823
824 int
825 acx_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
826 {
827 struct acx_softc *sc = ifp->if_softc;
828 struct ieee80211com *ic = &sc->sc_ic;
829 struct ifaddr *ifa;
830 struct ifreq *ifr;
831 int s, error = 0;
832 uint8_t chan;
833
834 s = splnet();
835
836 switch (cmd) {
837 case SIOCSIFADDR:
838 ifa = (struct ifaddr *)data;
839 ifp->if_flags |= IFF_UP;
840 #ifdef INET
841 if (ifa->ifa_addr->sa_family == AF_INET)
842 arp_ifinit(&ic->ic_ac, ifa);
843 #endif
844
845 case SIOCSIFFLAGS:
846 if (ifp->if_flags & IFF_UP) {
847 if ((ifp->if_flags & IFF_RUNNING) == 0)
848 acx_init(ifp);
849 } else {
850 if (ifp->if_flags & IFF_RUNNING)
851 acx_stop(sc);
852 }
853 break;
854 case SIOCADDMULTI:
855 case SIOCDELMULTI:
856 ifr = (struct ifreq *)data;
857 error = (cmd == SIOCADDMULTI) ?
858 ether_addmulti(ifr, &ic->ic_ac) :
859 ether_delmulti(ifr, &ic->ic_ac);
860
861 if (error == ENETRESET)
862 error = 0;
863 break;
864 case SIOCS80211CHANNEL:
865
866 error = ieee80211_ioctl(ifp, cmd, data);
867 if (error == ENETRESET &&
868 ic->ic_opmode == IEEE80211_M_MONITOR) {
869 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
870 (IFF_UP | IFF_RUNNING)) {
871 ic->ic_bss->ni_chan = ic->ic_ibss_chan;
872 chan = ieee80211_chan2ieee(ic,
873 ic->ic_bss->ni_chan);
874 (void)acx_set_channel(sc, chan);
875 }
876 error = 0;
877 }
878 break;
879 default:
880 error = ieee80211_ioctl(ifp, cmd, data);
881 break;
882 }
883
884 if (error == ENETRESET) {
885 if ((ifp->if_flags & (IFF_RUNNING | IFF_UP)) ==
886 (IFF_RUNNING | IFF_UP))
887 acx_init(ifp);
888 error = 0;
889 }
890
891 splx(s);
892
893 return (error);
894 }
895
896 void
897 acx_start(struct ifnet *ifp)
898 {
899 struct acx_softc *sc = ifp->if_softc;
900 struct ieee80211com *ic = &sc->sc_ic;
901 struct acx_buf_data *bd = &sc->sc_buf_data;
902 struct acx_txbuf *buf;
903 int trans, idx;
904
905 if ((sc->sc_flags & ACX_FLAG_FW_LOADED) == 0 ||
906 (ifp->if_flags & IFF_RUNNING) == 0 ||
907 (ifp->if_flags & IFF_OACTIVE))
908 return;
909
910
911
912
913
914
915
916 idx = bd->tx_free_start;
917 trans = 0;
918 for (buf = &bd->tx_buf[idx]; buf->tb_mbuf == NULL;
919 buf = &bd->tx_buf[idx]) {
920 struct ieee80211_frame *wh;
921 struct ieee80211_node *ni = NULL;
922 struct mbuf *m;
923 int rate;
924
925 IF_DEQUEUE(&ic->ic_mgtq, m);
926 if (m != NULL) {
927 ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
928 m->m_pkthdr.rcvif = NULL;
929
930
931
932
933
934 wh = mtod(m, struct ieee80211_frame *);
935 if ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) ==
936 IEEE80211_FC0_SUBTYPE_PROBE_RESP) {
937 if (ni != NULL)
938 ieee80211_release_node(ic, ni);
939 m_freem(m);
940 continue;
941 }
942
943
944
945
946
947 rate = ni->ni_rates.rs_rates[0];
948 rate &= IEEE80211_RATE_VAL;
949 } else if (!IFQ_IS_EMPTY(&ifp->if_snd)) {
950 struct ether_header *eh;
951
952 IFQ_DEQUEUE(&ifp->if_snd, m);
953 if (m == NULL)
954 break;
955
956 if (ic->ic_state != IEEE80211_S_RUN) {
957 DPRINTF(("%s: data packet dropped due to "
958 "not RUN. Current state %d\n",
959 ifp->if_xname, ic->ic_state));
960 m_freem(m);
961 break;
962 }
963
964 if (m->m_len < sizeof(struct ether_header)) {
965 m = m_pullup(m, sizeof(struct ether_header));
966 if (m == NULL) {
967 ifp->if_oerrors++;
968 continue;
969 }
970 }
971 eh = mtod(m, struct ether_header *);
972
973
974
975 #if NBPFILTER > 0
976 if (ifp->if_bpf != NULL)
977 bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT);
978 #endif
979
980 if ((m = ieee80211_encap(ifp, m, &ni)) == NULL) {
981 ifp->if_oerrors++;
982 continue;
983 }
984
985 #if NBPFILTER > 0
986 if (ic->ic_rawbpf != NULL)
987 bpf_mtap(ic->ic_rawbpf, m, BPF_DIRECTION_OUT);
988 #endif
989
990 if (ic->ic_fixed_rate != -1) {
991 rate = ic->ic_sup_rates[ic->ic_curmode].
992 rs_rates[ic->ic_fixed_rate];
993 } else
994 rate = ni->ni_rates.rs_rates[ni->ni_txrate];
995 rate &= IEEE80211_RATE_VAL;
996 } else
997 break;
998
999 wh = mtod(m, struct ieee80211_frame *);
1000 if ((wh->i_fc[1] & IEEE80211_FC1_WEP) && !sc->chip_hw_crypt) {
1001 m = ieee80211_wep_crypt(ifp, m, 1);
1002 if (m == NULL) {
1003 ieee80211_release_node(ic, ni);
1004 m_freem(m);
1005 ifp->if_oerrors++;
1006 continue;
1007 }
1008 }
1009
1010 #if NBPFILTER > 0
1011 if (sc->sc_drvbpf != NULL) {
1012 struct mbuf mb;
1013 struct acx_tx_radiotap_hdr *tap = &sc->sc_txtap;
1014
1015 tap->wt_flags = 0;
1016 tap->wt_rate = rate;
1017 tap->wt_chan_freq =
1018 htole16(ic->ic_bss->ni_chan->ic_freq);
1019 tap->wt_chan_flags =
1020 htole16(ic->ic_bss->ni_chan->ic_flags);
1021
1022 mb.m_data = (caddr_t)tap;
1023 mb.m_len = sc->sc_txtap_len;
1024 mb.m_next = m;
1025 mb.m_nextpkt = NULL;
1026 mb.m_type = 0;
1027 mb.m_flags = 0;
1028 bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_OUT);
1029 }
1030 #endif
1031
1032 if (acx_encap(sc, buf, m, ni, rate) != 0) {
1033
1034
1035
1036
1037 if (ni != NULL)
1038 ieee80211_release_node(ic, ni);
1039 ifp->if_oerrors++;
1040 continue;
1041 }
1042
1043
1044
1045
1046
1047
1048
1049
1050 trans = 1;
1051 bd->tx_used_count++;
1052 idx = (idx + 1) % ACX_TX_DESC_CNT;
1053 }
1054 bd->tx_free_start = idx;
1055
1056 if (bd->tx_used_count == ACX_TX_DESC_CNT)
1057 ifp->if_flags |= IFF_OACTIVE;
1058
1059 if (trans && ifp->if_timer == 0)
1060 ifp->if_timer = 5;
1061 sc->sc_txtimer = 5;
1062 }
1063
1064 void
1065 acx_watchdog(struct ifnet *ifp)
1066 {
1067 struct acx_softc *sc = ifp->if_softc;
1068
1069 ifp->if_timer = 0;
1070
1071 if ((ifp->if_flags & IFF_RUNNING) == 0)
1072 return;
1073
1074 if (sc->sc_txtimer) {
1075 if (--sc->sc_txtimer == 0) {
1076 printf("%s: watchdog timeout\n", ifp->if_xname);
1077 acx_txeof(ifp->if_softc);
1078 ifp->if_oerrors++;
1079 return;
1080 }
1081 ifp->if_timer = 5;
1082 }
1083
1084 ieee80211_watchdog(ifp);
1085 }
1086
1087 int
1088 acx_intr(void *arg)
1089 {
1090 struct acx_softc *sc = arg;
1091 uint16_t intr_status;
1092
1093 if ((sc->sc_flags & ACX_FLAG_FW_LOADED) == 0)
1094 return (0);
1095
1096 intr_status = CSR_READ_2(sc, ACXREG_INTR_STATUS_CLR);
1097 if (intr_status == ACXRV_INTR_ALL) {
1098
1099 return (0);
1100 }
1101
1102 intr_status &= sc->chip_intr_enable;
1103 if (intr_status == 0) {
1104
1105 return (1);
1106 }
1107
1108
1109 CSR_WRITE_2(sc, ACXREG_INTR_ACK, ACXRV_INTR_ALL);
1110
1111 if (intr_status & ACXRV_INTR_TX_FINI)
1112 acx_txeof(sc);
1113
1114 if (intr_status & ACXRV_INTR_RX_FINI)
1115 acx_rxeof(sc);
1116
1117 return (1);
1118 }
1119
1120 void
1121 acx_disable_intr(struct acx_softc *sc)
1122 {
1123 CSR_WRITE_2(sc, ACXREG_INTR_MASK, sc->chip_intr_disable);
1124 CSR_WRITE_2(sc, ACXREG_EVENT_MASK, 0);
1125 }
1126
1127 void
1128 acx_enable_intr(struct acx_softc *sc)
1129 {
1130
1131 CSR_WRITE_2(sc, ACXREG_INTR_MASK, ~sc->chip_intr_enable);
1132 CSR_WRITE_2(sc, ACXREG_EVENT_MASK, ACXRV_EVENT_DISABLE);
1133 }
1134
1135 void
1136 acx_txeof(struct acx_softc *sc)
1137 {
1138 struct acx_buf_data *bd;
1139 struct acx_txbuf *buf;
1140 struct ifnet *ifp;
1141 int idx;
1142
1143 ifp = &sc->sc_ic.ic_if;
1144
1145 bd = &sc->sc_buf_data;
1146 idx = bd->tx_used_start;
1147 for (buf = &bd->tx_buf[idx]; buf->tb_mbuf != NULL;
1148 buf = &bd->tx_buf[idx]) {
1149 uint8_t ctrl, error;
1150
1151 ctrl = FW_TXDESC_GETFIELD_1(sc, buf, f_tx_ctrl);
1152 if ((ctrl & (DESC_CTRL_HOSTOWN | DESC_CTRL_ACXDONE)) !=
1153 (DESC_CTRL_HOSTOWN | DESC_CTRL_ACXDONE))
1154 break;
1155
1156 bus_dmamap_unload(sc->sc_dmat, buf->tb_mbuf_dmamap);
1157 m_freem(buf->tb_mbuf);
1158 buf->tb_mbuf = NULL;
1159
1160 error = FW_TXDESC_GETFIELD_1(sc, buf, f_tx_error);
1161 if (error) {
1162 acx_txerr(sc, error);
1163 ifp->if_oerrors++;
1164 } else
1165 ifp->if_opackets++;
1166
1167
1168 if (buf->tb_node != NULL) {
1169 struct ieee80211com *ic;
1170 struct ieee80211_node *ni;
1171 struct acx_node *wn;
1172 int ntries;
1173
1174 ic = &sc->sc_ic;
1175 ni = (struct ieee80211_node *)buf->tb_node;
1176 wn = (struct acx_node *)ni;
1177 ntries = FW_TXDESC_GETFIELD_1(sc, buf, f_tx_rts_fail) +
1178 FW_TXDESC_GETFIELD_1(sc, buf, f_tx_ack_fail);
1179
1180 wn->amn.amn_txcnt++;
1181 if (ntries > 0) {
1182 DPRINTFN(2, ("%s: tx intr ntries %d\n",
1183 sc->sc_dev.dv_xname, ntries));
1184 wn->amn.amn_retrycnt++;
1185 }
1186
1187 ieee80211_release_node(ic, ni);
1188 buf->tb_node = NULL;
1189 }
1190
1191 FW_TXDESC_SETFIELD_1(sc, buf, f_tx_ctrl, DESC_CTRL_HOSTOWN);
1192
1193 bd->tx_used_count--;
1194
1195 idx = (idx + 1) % ACX_TX_DESC_CNT;
1196 }
1197 bd->tx_used_start = idx;
1198
1199 ifp->if_timer = bd->tx_used_count == 0 ? 0 : 5;
1200 sc->sc_txtimer = 0;
1201
1202 if (bd->tx_used_count != ACX_TX_DESC_CNT) {
1203 ifp->if_flags &= ~IFF_OACTIVE;
1204 acx_start(ifp);
1205 }
1206 }
1207
1208 void
1209 acx_txerr(struct acx_softc *sc, uint8_t err)
1210 {
1211 struct ifnet *ifp = &sc->sc_ic.ic_if;
1212 struct acx_stats *stats = &sc->sc_stats;
1213
1214 if (err == DESC_ERR_EXCESSIVE_RETRY) {
1215
1216
1217
1218
1219 DPRINTF(("%s: TX failed -- excessive retry\n",
1220 sc->sc_dev.dv_xname));
1221 } else
1222 printf("%s: TX failed -- ", ifp->if_xname);
1223
1224
1225
1226
1227
1228 switch (err) {
1229 #if 0
1230 case DESC_ERR_OTHER_FRAG:
1231
1232 printf("error in other fragment\n");
1233 stats->err_oth_frag++;
1234 break;
1235 #endif
1236 case DESC_ERR_ABORT:
1237 printf("aborted\n");
1238 stats->err_abort++;
1239 break;
1240 case DESC_ERR_PARAM:
1241 printf("wrong paramters in descriptor\n");
1242 stats->err_param++;
1243 break;
1244 case DESC_ERR_NO_WEPKEY:
1245 printf("WEP key missing\n");
1246 stats->err_no_wepkey++;
1247 break;
1248 case DESC_ERR_MSDU_TIMEOUT:
1249 printf("MSDU life timeout\n");
1250 stats->err_msdu_timeout++;
1251 break;
1252 case DESC_ERR_EXCESSIVE_RETRY:
1253
1254
1255
1256
1257
1258
1259 stats->err_ex_retry++;
1260 break;
1261 case DESC_ERR_BUF_OVERFLOW:
1262 printf("buffer overflow\n");
1263 stats->err_buf_oflow++;
1264 break;
1265 case DESC_ERR_DMA:
1266 printf("DMA error\n");
1267 stats->err_dma++;
1268 break;
1269 default:
1270 printf("unknown error %d\n", err);
1271 stats->err_unkn++;
1272 break;
1273 }
1274 }
1275
1276 void
1277 acx_rxeof(struct acx_softc *sc)
1278 {
1279 struct ieee80211com *ic = &sc->sc_ic;
1280 struct acx_ring_data *rd = &sc->sc_ring_data;
1281 struct acx_buf_data *bd = &sc->sc_buf_data;
1282 struct ifnet *ifp = &ic->ic_if;
1283 int idx, ready;
1284
1285 bus_dmamap_sync(sc->sc_dmat, rd->rx_ring_dmamap, 0,
1286 rd->rx_ring_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
1287
1288
1289
1290
1291
1292 idx = bd->rx_scan_start;
1293 ready = 0;
1294 do {
1295 struct acx_rxbuf *buf;
1296
1297 buf = &bd->rx_buf[idx];
1298 if ((buf->rb_desc->h_ctrl & htole16(DESC_CTRL_HOSTOWN)) &&
1299 (buf->rb_desc->h_status & htole32(DESC_STATUS_FULL))) {
1300 ready = 1;
1301 break;
1302 }
1303 idx = (idx + 1) % ACX_RX_DESC_CNT;
1304 } while (idx != bd->rx_scan_start);
1305
1306 if (!ready)
1307 return;
1308
1309
1310
1311
1312
1313 do {
1314 struct acx_rxbuf_hdr *head;
1315 struct acx_rxbuf *buf;
1316 struct mbuf *m;
1317 uint32_t desc_status;
1318 uint16_t desc_ctrl;
1319 int len, error;
1320
1321 buf = &bd->rx_buf[idx];
1322
1323 desc_ctrl = letoh16(buf->rb_desc->h_ctrl);
1324 desc_status = letoh32(buf->rb_desc->h_status);
1325 if (!(desc_ctrl & DESC_CTRL_HOSTOWN) ||
1326 !(desc_status & DESC_STATUS_FULL))
1327 break;
1328
1329 bus_dmamap_sync(sc->sc_dmat, buf->rb_mbuf_dmamap, 0,
1330 buf->rb_mbuf_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
1331
1332 m = buf->rb_mbuf;
1333
1334 error = acx_newbuf(sc, buf, 0);
1335 if (error) {
1336 ifp->if_ierrors++;
1337 goto next;
1338 }
1339
1340 head = mtod(m, struct acx_rxbuf_hdr *);
1341
1342 len = letoh16(head->rbh_len) & ACX_RXBUF_LEN_MASK;
1343 if (len >= sizeof(struct ieee80211_frame_min) &&
1344 len < MCLBYTES) {
1345 struct ieee80211_frame *wh;
1346 struct ieee80211_node *ni;
1347
1348 m_adj(m, sizeof(struct acx_rxbuf_hdr) +
1349 sc->chip_rxbuf_exhdr);
1350 wh = mtod(m, struct ieee80211_frame *);
1351
1352 if ((wh->i_fc[1] & IEEE80211_FC1_WEP) &&
1353 sc->chip_hw_crypt) {
1354
1355 wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
1356
1357
1358 if (sc->chip_proc_wep_rxbuf != NULL) {
1359 sc->chip_proc_wep_rxbuf(sc, m, &len);
1360 wh = mtod(m, struct ieee80211_frame *);
1361 }
1362 }
1363
1364 m->m_len = m->m_pkthdr.len = len;
1365 m->m_pkthdr.rcvif = &ic->ic_if;
1366
1367 #if NBPFILTER > 0
1368 if (sc->sc_drvbpf != NULL) {
1369 struct mbuf mb;
1370 struct acx_rx_radiotap_hdr *tap = &sc->sc_rxtap;
1371
1372 tap->wr_flags = 0;
1373 tap->wr_chan_freq =
1374 htole16(ic->ic_bss->ni_chan->ic_freq);
1375 tap->wr_chan_flags =
1376 htole16(ic->ic_bss->ni_chan->ic_flags);
1377 tap->wr_rssi = head->rbh_level;
1378 tap->wr_max_rssi = ic->ic_max_rssi;
1379
1380 mb.m_data = (caddr_t)tap;
1381 mb.m_len = sc->sc_rxtap_len;
1382 mb.m_next = m;
1383 mb.m_nextpkt = NULL;
1384 mb.m_type = 0;
1385 mb.m_flags = 0;
1386 bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_IN);
1387 }
1388 #endif
1389
1390 ni = ieee80211_find_rxnode(ic, wh);
1391
1392 ieee80211_input(ifp, m, ni, head->rbh_level,
1393 letoh32(head->rbh_time));
1394
1395 ieee80211_release_node(ic, ni);
1396 ifp->if_ipackets++;
1397 } else {
1398 m_freem(m);
1399 ifp->if_ierrors++;
1400 }
1401
1402 next:
1403 buf->rb_desc->h_ctrl = htole16(desc_ctrl & ~DESC_CTRL_HOSTOWN);
1404 buf->rb_desc->h_status = 0;
1405 bus_dmamap_sync(sc->sc_dmat, rd->rx_ring_dmamap, 0,
1406 rd->rx_ring_dmamap->dm_mapsize, BUS_DMASYNC_PREWRITE);
1407
1408 idx = (idx + 1) % ACX_RX_DESC_CNT;
1409 } while (idx != bd->rx_scan_start);
1410
1411
1412
1413
1414
1415 bd->rx_scan_start = idx;
1416
1417
1418
1419
1420
1421 if (!IFQ_IS_EMPTY(&ifp->if_snd) && !(ifp->if_flags & IFF_OACTIVE))
1422 (*ifp->if_start)(ifp);
1423 }
1424
1425 int
1426 acx_reset(struct acx_softc *sc)
1427 {
1428 uint16_t reg;
1429
1430
1431 CSR_SETB_2(sc, ACXREG_ECPU_CTRL, ACXRV_ECPU_HALT);
1432
1433
1434 reg = CSR_READ_2(sc, ACXREG_SOFT_RESET);
1435 CSR_WRITE_2(sc, ACXREG_SOFT_RESET, reg | ACXRV_SOFT_RESET);
1436 DELAY(100);
1437 CSR_WRITE_2(sc, ACXREG_SOFT_RESET, reg);
1438
1439
1440 CSR_SETB_2(sc, ACXREG_EEPROM_INIT, ACXRV_EEPROM_INIT);
1441 DELAY(50000);
1442
1443
1444 reg = CSR_READ_2(sc, ACXREG_ECPU_CTRL);
1445 if (!(reg & ACXRV_ECPU_HALT)) {
1446 printf("%s: can't halt ECPU\n", sc->sc_dev.dv_xname);
1447 return (ENXIO);
1448 }
1449
1450 return (0);
1451 }
1452
1453 int
1454 acx_read_eeprom(struct acx_softc *sc, uint32_t offset, uint8_t *val)
1455 {
1456 int i;
1457 struct ifnet *ifp = &sc->sc_ic.ic_if;
1458
1459 CSR_WRITE_4(sc, ACXREG_EEPROM_CONF, 0);
1460 CSR_WRITE_4(sc, ACXREG_EEPROM_ADDR, offset);
1461 CSR_WRITE_4(sc, ACXREG_EEPROM_CTRL, ACXRV_EEPROM_READ);
1462
1463 #define EE_READ_RETRY_MAX 100
1464 for (i = 0; i < EE_READ_RETRY_MAX; ++i) {
1465 if (CSR_READ_2(sc, ACXREG_EEPROM_CTRL) == 0)
1466 break;
1467 DELAY(10000);
1468 }
1469 if (i == EE_READ_RETRY_MAX) {
1470 printf("%s: can't read EEPROM offset %x (timeout)\n",
1471 ifp->if_xname, offset);
1472 return (ETIMEDOUT);
1473 }
1474 #undef EE_READ_RETRY_MAX
1475
1476 *val = CSR_READ_1(sc, ACXREG_EEPROM_DATA);
1477
1478 return (0);
1479 }
1480
1481 int
1482 acx_read_phyreg(struct acx_softc *sc, uint32_t reg, uint8_t *val)
1483 {
1484 struct ifnet *ifp = &sc->sc_ic.ic_if;
1485 int i;
1486
1487 CSR_WRITE_4(sc, ACXREG_PHY_ADDR, reg);
1488 CSR_WRITE_4(sc, ACXREG_PHY_CTRL, ACXRV_PHY_READ);
1489
1490 #define PHY_READ_RETRY_MAX 100
1491 for (i = 0; i < PHY_READ_RETRY_MAX; ++i) {
1492 if (CSR_READ_4(sc, ACXREG_PHY_CTRL) == 0)
1493 break;
1494 DELAY(10000);
1495 }
1496 if (i == PHY_READ_RETRY_MAX) {
1497 printf("%s: can't read phy reg %x (timeout)\n",
1498 ifp->if_xname, reg);
1499 return (ETIMEDOUT);
1500 }
1501 #undef PHY_READ_RETRY_MAX
1502
1503 *val = CSR_READ_1(sc, ACXREG_PHY_DATA);
1504
1505 return (0);
1506 }
1507
1508 void
1509 acx_write_phyreg(struct acx_softc *sc, uint32_t reg, uint8_t val)
1510 {
1511 CSR_WRITE_4(sc, ACXREG_PHY_DATA, val);
1512 CSR_WRITE_4(sc, ACXREG_PHY_ADDR, reg);
1513 CSR_WRITE_4(sc, ACXREG_PHY_CTRL, ACXRV_PHY_WRITE);
1514 }
1515
1516 int
1517 acx_load_base_firmware(struct acx_softc *sc, const char *name)
1518 {
1519 struct ifnet *ifp = &sc->sc_ic.ic_if;
1520 int i, error;
1521 uint8_t *ucode;
1522 size_t size;
1523
1524 error = loadfirmware(name, &ucode, &size);
1525
1526 if (error != 0) {
1527 printf("%s: error %d, could not read microcode %s!\n",
1528 ifp->if_xname, error, name);
1529 return (EIO);
1530 }
1531
1532
1533 error = acx_load_firmware(sc, 0, ucode, size);
1534
1535 free(ucode, M_DEVBUF);
1536
1537 if (error) {
1538 printf("%s: can't load base firmware\n", ifp->if_xname);
1539 return error;
1540 }
1541 DPRINTF(("%s: base firmware loaded\n", sc->sc_dev.dv_xname));
1542
1543
1544 CSR_WRITE_2(sc, ACXREG_ECPU_CTRL, ACXRV_ECPU_START);
1545
1546
1547 for (i = 0; i < 500; ++i) {
1548 uint16_t reg;
1549
1550 reg = CSR_READ_2(sc, ACXREG_INTR_STATUS);
1551 if (reg & ACXRV_INTR_FCS_THRESH) {
1552 CSR_WRITE_2(sc, ACXREG_INTR_ACK, ACXRV_INTR_FCS_THRESH);
1553 return (0);
1554 }
1555 DELAY(10000);
1556 }
1557
1558 printf("%s: can't initialize ECPU (timeout)\n", ifp->if_xname);
1559
1560 return (ENXIO);
1561 }
1562
1563 int
1564 acx_load_radio_firmware(struct acx_softc *sc, const char *name)
1565 {
1566 struct ifnet *ifp = &sc->sc_ic.ic_if;
1567 struct acx_conf_mmap mem_map;
1568 uint32_t radio_fw_ofs;
1569 int error;
1570 uint8_t *ucode;
1571 size_t size;
1572
1573 error = loadfirmware(name, &ucode, &size);
1574
1575 if (error != 0) {
1576 printf("%s: error %d, could not read microcode %s!\n",
1577 ifp->if_xname, error, name);
1578 return (EIO);
1579 }
1580
1581
1582
1583
1584
1585 if (acx_get_conf(sc, ACX_CONF_MMAP, &mem_map, sizeof(mem_map)) != 0) {
1586 free(ucode, M_DEVBUF);
1587 return (ENXIO);
1588 }
1589 radio_fw_ofs = letoh32(mem_map.code_end);
1590
1591
1592 if (acx_exec_command(sc, ACXCMD_SLEEP, NULL, 0, NULL, 0) != 0) {
1593 free(ucode, M_DEVBUF);
1594 return (ENXIO);
1595 }
1596
1597
1598 error = acx_load_firmware(sc, radio_fw_ofs, ucode, size);
1599
1600 free(ucode, M_DEVBUF);
1601
1602 if (error) {
1603 printf("%s: can't load radio firmware\n", ifp->if_xname);
1604 return (ENXIO);
1605 }
1606 DPRINTF(("%s: radio firmware loaded\n", sc->sc_dev.dv_xname));
1607
1608
1609 if (acx_exec_command(sc, ACXCMD_WAKEUP, NULL, 0, NULL, 0) != 0)
1610 return (ENXIO);
1611
1612
1613 if (acx_init_radio(sc, radio_fw_ofs, size) != 0)
1614 return (ENXIO);
1615
1616
1617 if (acx_get_conf(sc, ACX_CONF_MMAP, &mem_map, sizeof(mem_map)) != 0)
1618 return (ENXIO);
1619
1620 if (letoh32(mem_map.code_end) != radio_fw_ofs + size) {
1621 printf("%s: loaded radio firmware position mismatch\n",
1622 ifp->if_xname);
1623 return (ENXIO);
1624 }
1625
1626 DPRINTF(("%s: radio firmware initialized\n", sc->sc_dev.dv_xname));
1627
1628 return (0);
1629 }
1630
1631 int
1632 acx_load_firmware(struct acx_softc *sc, uint32_t offset, const uint8_t *data,
1633 int data_len)
1634 {
1635 struct ifnet *ifp = &sc->sc_ic.ic_if;
1636 const uint32_t *fw;
1637 u_int32_t csum = 0;
1638 int i, fw_len;
1639
1640 for (i = 4; i < data_len; i++)
1641 csum += data[i];
1642
1643 fw = (const uint32_t *)data;
1644
1645 if (*fw != htole32(csum)) {
1646 printf("%s: firmware checksum 0x%x does not match 0x%x!\n",
1647 ifp->if_xname, *fw, htole32(csum));
1648 return (ENXIO);
1649 }
1650
1651
1652 data += 8;
1653 data_len -= 8;
1654
1655 fw = (const uint32_t *)data;
1656 fw_len = data_len / sizeof(uint32_t);
1657
1658
1659
1660
1661
1662
1663
1664
1665 CSR_WRITE_4(sc, ACXREG_FWMEM_START, ACXRV_FWMEM_START_OP);
1666 #ifndef LOADFW_AUTO_INC
1667 CSR_WRITE_4(sc, ACXREG_FWMEM_CTRL, 0);
1668 #else
1669 CSR_WRITE_4(sc, ACXREG_FWMEM_CTRL, ACXRV_FWMEM_ADDR_AUTOINC);
1670 CSR_WRITE_4(sc, ACXREG_FWMEM_ADDR, offset);
1671 #endif
1672
1673 for (i = 0; i < fw_len; ++i) {
1674 #ifndef LOADFW_AUTO_INC
1675 CSR_WRITE_4(sc, ACXREG_FWMEM_ADDR, offset + (i * 4));
1676 #endif
1677 CSR_WRITE_4(sc, ACXREG_FWMEM_DATA, betoh32(fw[i]));
1678 }
1679
1680
1681 CSR_WRITE_4(sc, ACXREG_FWMEM_START, ACXRV_FWMEM_START_OP);
1682 #ifndef LOADFW_AUTO_INC
1683 CSR_WRITE_4(sc, ACXREG_FWMEM_CTRL, 0);
1684 #else
1685 CSR_WRITE_4(sc, ACXREG_FWMEM_CTRL, ACXRV_FWMEM_ADDR_AUTOINC);
1686 CSR_WRITE_4(sc, ACXREG_FWMEM_ADDR, offset);
1687 #endif
1688
1689 for (i = 0; i < fw_len; ++i) {
1690 uint32_t val;
1691
1692 #ifndef LOADFW_AUTO_INC
1693 CSR_WRITE_4(sc, ACXREG_FWMEM_ADDR, offset + (i * 4));
1694 #endif
1695 val = CSR_READ_4(sc, ACXREG_FWMEM_DATA);
1696 if (betoh32(fw[i]) != val) {
1697 printf("%s: firmware mismatch fw %08x loaded %08x\n",
1698 ifp->if_xname, fw[i], val);
1699 return (ENXIO);
1700 }
1701 }
1702
1703 return (0);
1704 }
1705
1706 struct ieee80211_node *
1707 acx_node_alloc(struct ieee80211com *ic)
1708 {
1709 struct acx_node *wn;
1710
1711 wn = malloc(sizeof(struct acx_node), M_DEVBUF, M_NOWAIT);
1712 if (wn == NULL)
1713 return (NULL);
1714
1715 bzero(wn, sizeof(struct acx_node));
1716
1717 return ((struct ieee80211_node *)wn);
1718 }
1719
1720 int
1721 acx_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
1722 {
1723 struct acx_softc *sc = ic->ic_if.if_softc;
1724 struct ifnet *ifp = &ic->ic_if;
1725 int error = 0;
1726
1727 timeout_del(&sc->amrr_ch);
1728
1729 switch (nstate) {
1730 case IEEE80211_S_INIT:
1731 break;
1732 case IEEE80211_S_SCAN: {
1733 uint8_t chan;
1734
1735 chan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan);
1736 (void)acx_set_channel(sc, chan);
1737
1738 timeout_add(&sc->sc_chanscan_timer,
1739 hz / acx_chanscan_rate);
1740 }
1741 break;
1742 case IEEE80211_S_AUTH:
1743 if (ic->ic_opmode == IEEE80211_M_STA) {
1744 struct ieee80211_node *ni;
1745 #ifdef ACX_DEBUG
1746 int i;
1747 #endif
1748
1749 ni = ic->ic_bss;
1750
1751 if (acx_join_bss(sc, ACX_MODE_STA, ni) != 0) {
1752 printf("%s: join BSS failed\n", ifp->if_xname);
1753 error = 1;
1754 goto back;
1755 }
1756
1757 DPRINTF(("%s: join BSS\n", sc->sc_dev.dv_xname));
1758 if (ic->ic_state == IEEE80211_S_ASSOC) {
1759 DPRINTF(("%s: change from assoc to run\n",
1760 sc->sc_dev.dv_xname));
1761 ic->ic_state = IEEE80211_S_RUN;
1762 }
1763
1764 #ifdef ACX_DEBUG
1765 printf("%s: AP rates: ", sc->sc_dev.dv_xname);
1766 for (i = 0; i < ni->ni_rates.rs_nrates; ++i)
1767 printf("%d ", ni->ni_rates.rs_rates[i]);
1768 ieee80211_print_essid(ni->ni_essid, ni->ni_esslen);
1769 printf(" %s\n", ether_sprintf(ni->ni_bssid));
1770 #endif
1771 }
1772 break;
1773 case IEEE80211_S_RUN:
1774 if (ic->ic_opmode == IEEE80211_M_IBSS ||
1775 ic->ic_opmode == IEEE80211_M_HOSTAP) {
1776 struct ieee80211_node *ni;
1777 uint8_t chan;
1778
1779 ni = ic->ic_bss;
1780 chan = ieee80211_chan2ieee(ic, ni->ni_chan);
1781
1782 error = 1;
1783
1784 if (acx_set_channel(sc, chan) != 0)
1785 goto back;
1786
1787 if (acx_set_beacon_tmplt(sc, ni) != 0) {
1788 printf("%s: set beacon template failed\n",
1789 ifp->if_xname);
1790 goto back;
1791 }
1792
1793 if (acx_set_probe_resp_tmplt(sc, ni) != 0) {
1794 printf("%s: set probe response template "
1795 "failed\n", ifp->if_xname);
1796 goto back;
1797 }
1798
1799 if (ic->ic_opmode == IEEE80211_M_IBSS) {
1800 if (acx_join_bss(sc, ACX_MODE_ADHOC, ni) != 0) {
1801 printf("%s: join IBSS failed\n",
1802 ifp->if_xname);
1803 goto back;
1804 }
1805 } else {
1806 if (acx_join_bss(sc, ACX_MODE_AP, ni) != 0) {
1807 printf("%s: join HOSTAP failed\n",
1808 ifp->if_xname);
1809 goto back;
1810 }
1811 }
1812
1813 DPRINTF(("%s: join IBSS\n", sc->sc_dev.dv_xname));
1814 error = 0;
1815 }
1816
1817
1818 if (ic->ic_opmode == IEEE80211_M_STA)
1819 acx_newassoc(ic, ic->ic_bss, 1);
1820
1821
1822 if (ic->ic_fixed_rate == -1)
1823 timeout_add(&sc->amrr_ch, hz / 2);
1824 break;
1825 default:
1826 break;
1827 }
1828
1829 back:
1830 if (error) {
1831
1832 nstate = IEEE80211_S_INIT;
1833 arg = -1;
1834 }
1835
1836 return (sc->sc_newstate(ic, nstate, arg));
1837 }
1838
1839 int
1840 acx_init_tmplt_ordered(struct acx_softc *sc)
1841 {
1842 union {
1843 struct acx_tmplt_beacon beacon;
1844 struct acx_tmplt_null_data null;
1845 struct acx_tmplt_probe_req preq;
1846 struct acx_tmplt_probe_resp presp;
1847 struct acx_tmplt_tim tim;
1848 } data;
1849
1850 bzero(&data, sizeof(data));
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861 if (acx_set_tmplt(sc, ACXCMD_TMPLT_PROBE_REQ, &data.preq,
1862 sizeof(data.preq)) != 0)
1863 return (1);
1864
1865 if (acx_set_tmplt(sc, ACXCMD_TMPLT_NULL_DATA, &data.null,
1866 sizeof(data.null)) != 0)
1867 return (1);
1868
1869 if (acx_set_tmplt(sc, ACXCMD_TMPLT_BEACON, &data.beacon,
1870 sizeof(data.beacon)) != 0)
1871 return (1);
1872
1873 if (acx_set_tmplt(sc, ACXCMD_TMPLT_TIM, &data.tim,
1874 sizeof(data.tim)) != 0)
1875 return (1);
1876
1877 if (acx_set_tmplt(sc, ACXCMD_TMPLT_PROBE_RESP, &data.presp,
1878 sizeof(data.presp)) != 0)
1879 return (1);
1880
1881 return (0);
1882 }
1883
1884 int
1885 acx_dma_alloc(struct acx_softc *sc)
1886 {
1887 struct acx_ring_data *rd = &sc->sc_ring_data;
1888 struct acx_buf_data *bd = &sc->sc_buf_data;
1889 struct ifnet *ifp = &sc->sc_ic.ic_if;
1890 int i, error, nsegs;
1891
1892
1893 error = bus_dmamap_create(sc->sc_dmat, ACX_RX_RING_SIZE, 1,
1894 ACX_RX_RING_SIZE, 0, BUS_DMA_NOWAIT, &rd->rx_ring_dmamap);
1895
1896 if (error) {
1897 printf("%s: can't create rx ring dma tag\n",
1898 sc->sc_dev.dv_xname);
1899 return (error);
1900 }
1901
1902 error = bus_dmamem_alloc(sc->sc_dmat, ACX_RX_RING_SIZE, PAGE_SIZE,
1903 0, &rd->rx_ring_seg, 1, &nsegs, BUS_DMA_NOWAIT);
1904
1905 if (error != 0) {
1906 printf("%s: can't allocate rx ring dma memory\n",
1907 sc->sc_dev.dv_xname);
1908 return (error);
1909 }
1910
1911 error = bus_dmamem_map(sc->sc_dmat, &rd->rx_ring_seg, nsegs,
1912 ACX_RX_RING_SIZE, (caddr_t *)&rd->rx_ring,
1913 BUS_DMA_NOWAIT);
1914
1915 if (error != 0) {
1916 printf("%s: could not map rx desc DMA memory\n",
1917 sc->sc_dev.dv_xname);
1918 return (error);
1919 }
1920
1921 error = bus_dmamap_load(sc->sc_dmat, rd->rx_ring_dmamap,
1922 rd->rx_ring, ACX_RX_RING_SIZE, NULL, BUS_DMA_WAITOK);
1923
1924 if (error) {
1925 printf("%s: can't get rx ring dma address\n",
1926 sc->sc_dev.dv_xname);
1927 bus_dmamem_free(sc->sc_dmat, &rd->rx_ring_seg, 1);
1928 return (error);
1929 }
1930
1931 rd->rx_ring_paddr = rd->rx_ring_dmamap->dm_segs[0].ds_addr;
1932
1933
1934 error = bus_dmamap_create(sc->sc_dmat, ACX_TX_RING_SIZE, 1,
1935 ACX_TX_RING_SIZE, 0, BUS_DMA_NOWAIT, &rd->tx_ring_dmamap);
1936
1937 if (error) {
1938 printf("%s: can't create tx ring dma tag\n", ifp->if_xname);
1939 return (error);
1940 }
1941
1942 error = bus_dmamem_alloc(sc->sc_dmat, ACX_TX_RING_SIZE, PAGE_SIZE,
1943 0, &rd->tx_ring_seg, 1, &nsegs, BUS_DMA_NOWAIT);
1944
1945 if (error) {
1946 printf("%s: can't allocate tx ring dma memory\n",
1947 ifp->if_xname);
1948 return (error);
1949 }
1950
1951 error = bus_dmamem_map(sc->sc_dmat, &rd->tx_ring_seg, nsegs,
1952 ACX_TX_RING_SIZE, (caddr_t *)&rd->tx_ring, BUS_DMA_NOWAIT);
1953
1954 if (error != 0) {
1955 printf("%s: could not map tx desc DMA memory\n",
1956 sc->sc_dev.dv_xname);
1957 return (error);
1958 }
1959
1960 error = bus_dmamap_load(sc->sc_dmat, rd->tx_ring_dmamap,
1961 rd->tx_ring, ACX_TX_RING_SIZE, NULL, BUS_DMA_WAITOK);
1962
1963 if (error) {
1964 printf("%s: can't get tx ring dma address\n", ifp->if_xname);
1965 bus_dmamem_free(sc->sc_dmat, &rd->tx_ring_seg, 1);
1966 return (error);
1967 }
1968
1969 rd->tx_ring_paddr = rd->tx_ring_dmamap->dm_segs[0].ds_addr;
1970
1971
1972 error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES,
1973 0, 0, &bd->mbuf_tmp_dmamap);
1974
1975 if (error) {
1976 printf("%s: can't create tmp mbuf dma map\n", ifp->if_xname);
1977 return (error);
1978 }
1979
1980
1981 for (i = 0; i < ACX_RX_DESC_CNT; ++i) {
1982 error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1,
1983 MCLBYTES, 0, 0, &bd->rx_buf[i].rb_mbuf_dmamap);
1984 if (error) {
1985 printf("%s: can't create rx mbuf dma map (%d)\n",
1986 ifp->if_xname, i);
1987 return (error);
1988 }
1989 bd->rx_buf[i].rb_desc = &rd->rx_ring[i];
1990 }
1991
1992
1993 for (i = 0; i < ACX_TX_DESC_CNT; ++i) {
1994 error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1,
1995 MCLBYTES, 0, 0, &bd->tx_buf[i].tb_mbuf_dmamap);
1996 if (error) {
1997 printf("%s: can't create tx mbuf dma map (%d)\n",
1998 ifp->if_xname, i);
1999 return (error);
2000 }
2001 bd->tx_buf[i].tb_desc1 = &rd->tx_ring[i * 2];
2002 bd->tx_buf[i].tb_desc2 = &rd->tx_ring[(i * 2) + 1];
2003 }
2004
2005 return (0);
2006 }
2007
2008 void
2009 acx_dma_free(struct acx_softc *sc)
2010 {
2011 struct acx_ring_data *rd = &sc->sc_ring_data;
2012 struct acx_buf_data *bd = &sc->sc_buf_data;
2013 int i;
2014
2015 if (rd->rx_ring != NULL) {
2016 bus_dmamap_unload(sc->sc_dmat, rd->rx_ring_dmamap);
2017 bus_dmamem_free(sc->sc_dmat, &rd->rx_ring_seg, 1);
2018 }
2019
2020 if (rd->tx_ring != NULL) {
2021 bus_dmamap_unload(sc->sc_dmat, rd->tx_ring_dmamap);
2022 bus_dmamem_free(sc->sc_dmat, &rd->tx_ring_seg, 1);
2023 }
2024
2025 for (i = 0; i < ACX_RX_DESC_CNT; ++i) {
2026 if (bd->rx_buf[i].rb_desc != NULL) {
2027 if (bd->rx_buf[i].rb_mbuf != NULL) {
2028 bus_dmamap_unload(sc->sc_dmat,
2029 bd->rx_buf[i].rb_mbuf_dmamap);
2030 m_freem(bd->rx_buf[i].rb_mbuf);
2031 }
2032 bus_dmamap_destroy(sc->sc_dmat,
2033 bd->rx_buf[i].rb_mbuf_dmamap);
2034 }
2035 }
2036
2037 for (i = 0; i < ACX_TX_DESC_CNT; ++i) {
2038 if (bd->tx_buf[i].tb_desc1 != NULL) {
2039 if (bd->tx_buf[i].tb_mbuf != NULL) {
2040 bus_dmamap_unload(sc->sc_dmat,
2041 bd->tx_buf[i].tb_mbuf_dmamap);
2042 m_freem(bd->tx_buf[i].tb_mbuf);
2043 }
2044 bus_dmamap_destroy(sc->sc_dmat,
2045 bd->tx_buf[i].tb_mbuf_dmamap);
2046 }
2047 }
2048
2049 if (bd->mbuf_tmp_dmamap != NULL)
2050 bus_dmamap_destroy(sc->sc_dmat, bd->mbuf_tmp_dmamap);
2051 }
2052
2053 int
2054 acx_init_tx_ring(struct acx_softc *sc)
2055 {
2056 struct acx_ring_data *rd;
2057 struct acx_buf_data *bd;
2058 uint32_t paddr;
2059 int i;
2060
2061 rd = &sc->sc_ring_data;
2062 paddr = rd->tx_ring_paddr;
2063 for (i = 0; i < (ACX_TX_DESC_CNT * 2) - 1; ++i) {
2064 paddr += sizeof(struct acx_host_desc);
2065
2066 bzero(&rd->tx_ring[i], sizeof(struct acx_host_desc));
2067 rd->tx_ring[i].h_ctrl = htole16(DESC_CTRL_HOSTOWN);
2068
2069 if (i == (ACX_TX_DESC_CNT * 2) - 1)
2070 rd->tx_ring[i].h_next_desc = htole32(rd->tx_ring_paddr);
2071 else
2072 rd->tx_ring[i].h_next_desc = htole32(paddr);
2073 }
2074
2075 bus_dmamap_sync(sc->sc_dmat, rd->tx_ring_dmamap, 0,
2076 rd->tx_ring_dmamap->dm_mapsize, BUS_DMASYNC_PREWRITE);
2077
2078 bd = &sc->sc_buf_data;
2079 bd->tx_free_start = 0;
2080 bd->tx_used_start = 0;
2081 bd->tx_used_count = 0;
2082
2083 return (0);
2084 }
2085
2086 int
2087 acx_init_rx_ring(struct acx_softc *sc)
2088 {
2089 struct acx_ring_data *rd;
2090 struct acx_buf_data *bd;
2091 uint32_t paddr;
2092 int i;
2093
2094 bd = &sc->sc_buf_data;
2095 rd = &sc->sc_ring_data;
2096 paddr = rd->rx_ring_paddr;
2097
2098 for (i = 0; i < ACX_RX_DESC_CNT; ++i) {
2099 int error;
2100
2101 paddr += sizeof(struct acx_host_desc);
2102 bzero(&rd->rx_ring[i], sizeof(struct acx_host_desc));
2103
2104 error = acx_newbuf(sc, &bd->rx_buf[i], 1);
2105 if (error)
2106 return (error);
2107
2108 if (i == ACX_RX_DESC_CNT - 1)
2109 rd->rx_ring[i].h_next_desc = htole32(rd->rx_ring_paddr);
2110 else
2111 rd->rx_ring[i].h_next_desc = htole32(paddr);
2112 }
2113
2114 bus_dmamap_sync(sc->sc_dmat, rd->rx_ring_dmamap, 0,
2115 rd->rx_ring_dmamap->dm_mapsize, BUS_DMASYNC_PREWRITE);
2116
2117 bd->rx_scan_start = 0;
2118
2119 return (0);
2120 }
2121
2122 int
2123 acx_newbuf(struct acx_softc *sc, struct acx_rxbuf *rb, int wait)
2124 {
2125 struct acx_buf_data *bd;
2126 struct mbuf *m;
2127 bus_dmamap_t map;
2128 uint32_t paddr;
2129 int error;
2130
2131 bd = &sc->sc_buf_data;
2132
2133 MGETHDR(m, wait ? M_WAITOK : M_DONTWAIT, MT_DATA);
2134 if (m == NULL)
2135 return (ENOBUFS);
2136
2137 MCLGET(m, wait ? M_WAITOK : M_DONTWAIT);
2138 if (!(m->m_flags & M_EXT)) {
2139 m_freem(m);
2140 return (ENOBUFS);
2141 }
2142
2143 m->m_len = m->m_pkthdr.len = MCLBYTES;
2144
2145 error = bus_dmamap_load_mbuf(sc->sc_dmat, bd->mbuf_tmp_dmamap, m,
2146 wait ? BUS_DMA_WAITOK : BUS_DMA_NOWAIT);
2147 if (error) {
2148 m_freem(m);
2149 printf("%s: can't map rx mbuf %d\n",
2150 sc->sc_dev.dv_xname, error);
2151 return (error);
2152 }
2153
2154
2155 if (rb->rb_mbuf != NULL)
2156 bus_dmamap_unload(sc->sc_dmat, rb->rb_mbuf_dmamap);
2157
2158
2159 map = rb->rb_mbuf_dmamap;
2160 rb->rb_mbuf_dmamap = bd->mbuf_tmp_dmamap;
2161 bd->mbuf_tmp_dmamap = map;
2162 paddr = rb->rb_mbuf_dmamap->dm_segs[0].ds_addr;
2163
2164 rb->rb_mbuf = m;
2165 rb->rb_desc->h_data_paddr = htole32(paddr);
2166 rb->rb_desc->h_data_len = htole16(m->m_len);
2167
2168 bus_dmamap_sync(sc->sc_dmat, rb->rb_mbuf_dmamap, 0,
2169 rb->rb_mbuf_dmamap->dm_mapsize, BUS_DMASYNC_PREREAD);
2170
2171 return (0);
2172 }
2173
2174 int
2175 acx_encap(struct acx_softc *sc, struct acx_txbuf *txbuf, struct mbuf *m,
2176 struct ieee80211_node *ni, int rate)
2177 {
2178 struct acx_ring_data *rd = &sc->sc_ring_data;
2179 struct acx_node *node = (struct acx_node *)ni;
2180 struct ifnet *ifp = &sc->sc_ic.ic_if;
2181 uint32_t paddr;
2182 uint8_t ctrl;
2183 int error;
2184
2185 if (txbuf->tb_mbuf != NULL)
2186 panic("free TX buf has mbuf installed\n");
2187
2188 error = 0;
2189
2190 if (m->m_pkthdr.len > MCLBYTES) {
2191 printf("%s: mbuf too big\n", ifp->if_xname);
2192 error = E2BIG;
2193 goto back;
2194 } else if (m->m_pkthdr.len < ACX_FRAME_HDRLEN) {
2195 printf("%s: mbuf too small\n", ifp->if_xname);
2196 error = EINVAL;
2197 goto back;
2198 }
2199
2200 error = bus_dmamap_load_mbuf(sc->sc_dmat, txbuf->tb_mbuf_dmamap, m,
2201 BUS_DMA_NOWAIT);
2202
2203 if (error && error != EFBIG) {
2204 printf("%s: can't map tx mbuf1 %d\n",
2205 sc->sc_dev.dv_xname, error);
2206 goto back;
2207 }
2208
2209 if (error) {
2210
2211 struct mbuf *mnew;
2212
2213 error = 0;
2214
2215 MGETHDR(mnew, M_DONTWAIT, MT_DATA);
2216 if (mnew == NULL) {
2217 m_freem(m);
2218 error = ENOBUFS;
2219 printf("%s: can't defrag tx mbuf\n", ifp->if_xname);
2220 goto back;
2221 }
2222
2223 M_DUP_PKTHDR(mnew, m);
2224 if (m->m_pkthdr.len > MHLEN) {
2225 MCLGET(mnew, M_DONTWAIT);
2226 if (!(mnew->m_flags & M_EXT)) {
2227 m_freem(m);
2228 m_freem(mnew);
2229 error = ENOBUFS;
2230 }
2231 }
2232
2233 if (error) {
2234 printf("%s: can't defrag tx mbuf\n", ifp->if_xname);
2235 goto back;
2236 }
2237
2238 m_copydata(m, 0, m->m_pkthdr.len, mtod(mnew, caddr_t));
2239 m_freem(m);
2240 mnew->m_len = mnew->m_pkthdr.len;
2241 m = mnew;
2242
2243 error = bus_dmamap_load_mbuf(sc->sc_dmat,
2244 txbuf->tb_mbuf_dmamap, m, BUS_DMA_NOWAIT);
2245 if (error) {
2246 printf("%s: can't map tx mbuf2 %d\n",
2247 sc->sc_dev.dv_xname, error);
2248 goto back;
2249 }
2250 }
2251
2252 error = 0;
2253
2254 bus_dmamap_sync(sc->sc_dmat, txbuf->tb_mbuf_dmamap, 0,
2255 txbuf->tb_mbuf_dmamap->dm_mapsize, BUS_DMASYNC_PREWRITE);
2256
2257 txbuf->tb_mbuf = m;
2258 txbuf->tb_node = node;
2259 txbuf->tb_rate = rate;
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280 paddr = txbuf->tb_mbuf_dmamap->dm_segs[0].ds_addr;
2281 txbuf->tb_desc1->h_data_paddr = htole32(paddr);
2282 txbuf->tb_desc2->h_data_paddr = htole32(paddr + ACX_FRAME_HDRLEN);
2283
2284 txbuf->tb_desc1->h_data_len =
2285 htole16(sc->chip_txdesc1_len ? sc->chip_txdesc1_len
2286 : m->m_pkthdr.len);
2287 txbuf->tb_desc2->h_data_len =
2288 htole16(m->m_pkthdr.len - ACX_FRAME_HDRLEN);
2289
2290
2291
2292
2293
2294
2295 ctrl = FW_TXDESC_GETFIELD_1(sc, txbuf, f_tx_ctrl);
2296 ctrl |= sc->chip_fw_txdesc_ctrl;
2297 ctrl &= ~(DESC_CTRL_HOSTOWN | DESC_CTRL_ACXDONE);
2298
2299 FW_TXDESC_SETFIELD_2(sc, txbuf, f_tx_len, m->m_pkthdr.len);
2300 FW_TXDESC_SETFIELD_1(sc, txbuf, f_tx_error, 0);
2301 FW_TXDESC_SETFIELD_1(sc, txbuf, f_tx_ack_fail, 0);
2302 FW_TXDESC_SETFIELD_1(sc, txbuf, f_tx_rts_fail, 0);
2303 FW_TXDESC_SETFIELD_1(sc, txbuf, f_tx_rts_ok, 0);
2304 sc->chip_set_fw_txdesc_rate(sc, txbuf, rate);
2305
2306 txbuf->tb_desc1->h_ctrl = 0;
2307 txbuf->tb_desc2->h_ctrl = 0;
2308 bus_dmamap_sync(sc->sc_dmat, rd->tx_ring_dmamap, 0,
2309 rd->tx_ring_dmamap->dm_mapsize, BUS_DMASYNC_PREWRITE);
2310
2311 FW_TXDESC_SETFIELD_1(sc, txbuf, f_tx_ctrl2, 0);
2312 FW_TXDESC_SETFIELD_1(sc, txbuf, f_tx_ctrl, ctrl);
2313
2314
2315 CSR_WRITE_2(sc, ACXREG_INTR_TRIG, ACXRV_TRIG_TX_FINI);
2316 back:
2317 if (error)
2318 m_freem(m);
2319
2320 return (error);
2321 }
2322
2323 int
2324 acx_set_null_tmplt(struct acx_softc *sc)
2325 {
2326 struct ieee80211com *ic = &sc->sc_ic;
2327 struct acx_tmplt_null_data n;
2328 struct ieee80211_frame *wh;
2329
2330 bzero(&n, sizeof(n));
2331
2332 wh = &n.data;
2333 wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_DATA |
2334 IEEE80211_FC0_SUBTYPE_NODATA;
2335 wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
2336 IEEE80211_ADDR_COPY(wh->i_addr1, etherbroadcastaddr);
2337 IEEE80211_ADDR_COPY(wh->i_addr2, ic->ic_myaddr);
2338 IEEE80211_ADDR_COPY(wh->i_addr3, etherbroadcastaddr);
2339
2340 return (acx_set_tmplt(sc, ACXCMD_TMPLT_NULL_DATA, &n, sizeof(n)));
2341 }
2342
2343 int
2344 acx_set_probe_req_tmplt(struct acx_softc *sc, const char *ssid, int ssid_len)
2345 {
2346 struct ieee80211com *ic = &sc->sc_ic;
2347 struct acx_tmplt_probe_req req;
2348 struct ieee80211_frame *wh;
2349 uint8_t *frm;
2350 int len;
2351
2352 bzero(&req, sizeof(req));
2353
2354 wh = &req.data.u_data.f;
2355 wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT |
2356 IEEE80211_FC0_SUBTYPE_PROBE_REQ;
2357 wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
2358 IEEE80211_ADDR_COPY(wh->i_addr1, etherbroadcastaddr);
2359 IEEE80211_ADDR_COPY(wh->i_addr2, ic->ic_myaddr);
2360 IEEE80211_ADDR_COPY(wh->i_addr3, etherbroadcastaddr);
2361
2362 frm = req.data.u_data.var;
2363 frm = ieee80211_add_ssid(frm, ssid, ssid_len);
2364 frm = ieee80211_add_rates(frm, &ic->ic_sup_rates[sc->chip_phymode]);
2365 frm = ieee80211_add_xrates(frm, &ic->ic_sup_rates[sc->chip_phymode]);
2366 len = frm - req.data.u_data.var;
2367
2368 return (acx_set_tmplt(sc, ACXCMD_TMPLT_PROBE_REQ, &req,
2369 ACX_TMPLT_PROBE_REQ_SIZ(len)));
2370 }
2371
2372 struct mbuf *ieee80211_get_probe_resp(struct ieee80211com *,
2373 struct ieee80211_node *);
2374
2375 int
2376 acx_set_probe_resp_tmplt(struct acx_softc *sc, struct ieee80211_node *ni)
2377 {
2378 struct ieee80211com *ic = &sc->sc_ic;
2379 struct acx_tmplt_probe_resp resp;
2380 struct ieee80211_frame *wh;
2381 struct mbuf *m;
2382 int len;
2383
2384 bzero(&resp, sizeof(resp));
2385
2386 m = ieee80211_get_probe_resp(ic, ni);
2387 if (m == NULL)
2388 return (1);
2389 M_PREPEND(m, sizeof(struct ieee80211_frame), M_DONTWAIT);
2390 if (m == NULL)
2391 return (1);
2392 wh = mtod(m, struct ieee80211_frame *);
2393 wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT |
2394 IEEE80211_FC0_SUBTYPE_PROBE_RESP;
2395 wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
2396 *(u_int16_t *)&wh->i_dur[0] = 0;
2397 IEEE80211_ADDR_COPY(wh->i_addr1, ni->ni_macaddr);
2398 IEEE80211_ADDR_COPY(wh->i_addr2, ic->ic_myaddr);
2399 IEEE80211_ADDR_COPY(wh->i_addr3, ni->ni_bssid);
2400 *(u_int16_t *)wh->i_seq = 0;
2401
2402 m_copydata(m, 0, m->m_pkthdr.len, (caddr_t)&resp.data);
2403 len = m->m_pkthdr.len + sizeof(resp.size);
2404 m_freem(m);
2405
2406 return (acx_set_tmplt(sc, ACXCMD_TMPLT_PROBE_RESP, &resp, len));
2407 }
2408
2409 int
2410 acx_beacon_locate(struct mbuf *m, u_int8_t type)
2411 {
2412 int off;
2413 u_int8_t *frm;
2414
2415
2416
2417
2418
2419
2420
2421
2422 if (m->m_len != m->m_pkthdr.len)
2423 panic("beacon not in contiguous mbuf");
2424
2425 off = sizeof(struct ieee80211_frame) + 8 + 2 + 2;
2426 frm = mtod(m, u_int8_t *);
2427 for (; off + 1 < m->m_len; off += frm[off + 1] + 2) {
2428 if (frm[off] == type)
2429 return (off);
2430 }
2431
2432 return (m->m_len);
2433 }
2434
2435 int
2436 acx_set_beacon_tmplt(struct acx_softc *sc, struct ieee80211_node *ni)
2437 {
2438 struct ieee80211com *ic = &sc->sc_ic;
2439 struct acx_tmplt_beacon beacon;
2440 struct acx_tmplt_tim tim;
2441 struct mbuf *m;
2442 int len, off;
2443
2444 bzero(&beacon, sizeof(beacon));
2445 bzero(&tim, sizeof(tim));
2446
2447 m = ieee80211_beacon_alloc(ic, ni);
2448 if (m == NULL)
2449 return (1);
2450
2451 off = acx_beacon_locate(m, IEEE80211_ELEMID_TIM);
2452
2453 m_copydata(m, 0, off, (caddr_t)&beacon.data);
2454 len = off + sizeof(beacon.size);
2455
2456 if (acx_set_tmplt(sc, ACXCMD_TMPLT_BEACON, &beacon, len) != 0) {
2457 m_freem(m);
2458 return (1);
2459 }
2460
2461 len = m->m_pkthdr.len - off;
2462 if (len == 0) {
2463
2464 m_freem(m);
2465 return (0);
2466 }
2467
2468 m_copydata(m, off, len, (caddr_t)&tim.data);
2469 len += sizeof(beacon.size);
2470 m_freem(m);
2471
2472 return (acx_set_tmplt(sc, ACXCMD_TMPLT_TIM, &tim, len));
2473 }
2474
2475 void
2476 acx_init_cmd_reg(struct acx_softc *sc)
2477 {
2478 sc->sc_cmd = CSR_READ_4(sc, ACXREG_CMD_REG_OFFSET);
2479 sc->sc_cmd_param = sc->sc_cmd + ACX_CMD_REG_SIZE;
2480
2481
2482 CMD_WRITE_4(sc, 0);
2483 }
2484
2485 int
2486 acx_join_bss(struct acx_softc *sc, uint8_t mode, struct ieee80211_node *node)
2487 {
2488 uint8_t bj_buf[BSS_JOIN_BUFLEN];
2489 struct bss_join_hdr *bj;
2490 int i, dtim_intvl;
2491
2492 bzero(bj_buf, sizeof(bj_buf));
2493 bj = (struct bss_join_hdr *)bj_buf;
2494
2495 for (i = 0; i < IEEE80211_ADDR_LEN; ++i)
2496 bj->bssid[i] = node->ni_bssid[IEEE80211_ADDR_LEN - i - 1];
2497
2498 bj->beacon_intvl = htole16(acx_beacon_intvl);
2499
2500
2501 dtim_intvl = sc->sc_ic.ic_opmode == IEEE80211_M_IBSS ? 1 : 10;
2502 sc->chip_set_bss_join_param(sc, bj->chip_spec, dtim_intvl);
2503
2504 bj->ndata_txrate = ACX_NDATA_TXRATE_2;
2505 bj->ndata_txopt = 0;
2506 bj->mode = mode;
2507 bj->channel = ieee80211_chan2ieee(&sc->sc_ic, node->ni_chan);
2508 bj->esslen = node->ni_esslen;
2509 bcopy(node->ni_essid, bj->essid, node->ni_esslen);
2510
2511 DPRINTF(("%s: join BSS/IBSS on channel %d\n", sc->sc_dev.dv_xname,
2512 bj->channel));
2513 return (acx_exec_command(sc, ACXCMD_JOIN_BSS,
2514 bj, BSS_JOIN_PARAM_SIZE(bj), NULL, 0));
2515 }
2516
2517 int
2518 acx_set_channel(struct acx_softc *sc, uint8_t chan)
2519 {
2520 if (acx_exec_command(sc, ACXCMD_ENABLE_TXCHAN, &chan, sizeof(chan),
2521 NULL, 0) != 0) {
2522 DPRINTF(("%s: setting TX channel %d failed\n",
2523 sc->sc_dev.dv_xname, chan));
2524 return (ENXIO);
2525 }
2526
2527 if (acx_exec_command(sc, ACXCMD_ENABLE_RXCHAN, &chan, sizeof(chan),
2528 NULL, 0) != 0) {
2529 DPRINTF(("%s: setting RX channel %d failed\n",
2530 sc->sc_dev.dv_xname, chan));
2531 return (ENXIO);
2532 }
2533
2534 return (0);
2535 }
2536
2537 int
2538 acx_get_conf(struct acx_softc *sc, uint16_t conf_id, void *conf,
2539 uint16_t conf_len)
2540 {
2541 struct acx_conf *confcom;
2542
2543 if (conf_len < sizeof(*confcom)) {
2544 printf("%s: %s configure data is too short\n",
2545 sc->sc_dev.dv_xname, __func__);
2546 return (1);
2547 }
2548
2549 confcom = conf;
2550 confcom->conf_id = htole16(conf_id);
2551 confcom->conf_data_len = htole16(conf_len - sizeof(*confcom));
2552
2553 return (acx_exec_command(sc, ACXCMD_GET_CONF, confcom, sizeof(*confcom),
2554 conf, conf_len));
2555 }
2556
2557 int
2558 acx_set_conf(struct acx_softc *sc, uint16_t conf_id, void *conf,
2559 uint16_t conf_len)
2560 {
2561 struct acx_conf *confcom;
2562
2563 if (conf_len < sizeof(*confcom)) {
2564 printf("%s: %s configure data is too short\n",
2565 sc->sc_dev.dv_xname, __func__);
2566 return (1);
2567 }
2568
2569 confcom = conf;
2570 confcom->conf_id = htole16(conf_id);
2571 confcom->conf_data_len = htole16(conf_len - sizeof(*confcom));
2572
2573 return (acx_exec_command(sc, ACXCMD_SET_CONF, conf, conf_len, NULL, 0));
2574 }
2575
2576 int
2577 acx_set_tmplt(struct acx_softc *sc, uint16_t cmd, void *tmplt,
2578 uint16_t tmplt_len)
2579 {
2580 uint16_t *size;
2581
2582 if (tmplt_len < sizeof(*size)) {
2583 printf("%s: %s template is too short\n",
2584 sc->sc_dev.dv_xname, __func__);
2585 return (1);
2586 }
2587
2588 size = tmplt;
2589 *size = htole16(tmplt_len - sizeof(*size));
2590
2591 return (acx_exec_command(sc, cmd, tmplt, tmplt_len, NULL, 0));
2592 }
2593
2594 int
2595 acx_init_radio(struct acx_softc *sc, uint32_t radio_ofs, uint32_t radio_len)
2596 {
2597 struct radio_init r;
2598
2599 r.radio_ofs = htole32(radio_ofs);
2600 r.radio_len = htole32(radio_len);
2601
2602 return (acx_exec_command(sc, ACXCMD_INIT_RADIO, &r, sizeof(r), NULL,
2603 0));
2604 }
2605
2606 int
2607 acx_exec_command(struct acx_softc *sc, uint16_t cmd, void *param,
2608 uint16_t param_len, void *result, uint16_t result_len)
2609 {
2610 uint16_t status;
2611 int i, ret;
2612
2613 if ((sc->sc_flags & ACX_FLAG_FW_LOADED) == 0) {
2614 printf("%s: cmd 0x%04x failed (base firmware not loaded)\n",
2615 sc->sc_dev.dv_xname, cmd);
2616 return (1);
2617 }
2618
2619 ret = 0;
2620
2621 if (param != NULL && param_len != 0) {
2622
2623 CMDPRM_WRITE_REGION_1(sc, param, param_len);
2624 }
2625
2626
2627 CMD_WRITE_4(sc, cmd);
2628
2629
2630 CSR_WRITE_2(sc, ACXREG_INTR_TRIG, ACXRV_TRIG_CMD_FINI);
2631 DELAY(50);
2632
2633
2634 if (cmd == ACXCMD_INIT_RADIO) {
2635
2636 tsleep(&cmd, 0, "rdinit", (300 * hz) / 1000);
2637 }
2638
2639 #define CMDWAIT_RETRY_MAX 1000
2640 for (i = 0; i < CMDWAIT_RETRY_MAX; ++i) {
2641 uint16_t reg;
2642
2643 reg = CSR_READ_2(sc, ACXREG_INTR_STATUS);
2644 if (reg & ACXRV_INTR_CMD_FINI) {
2645 CSR_WRITE_2(sc, ACXREG_INTR_ACK, ACXRV_INTR_CMD_FINI);
2646 break;
2647 }
2648 DELAY(50);
2649 }
2650 if (i == CMDWAIT_RETRY_MAX) {
2651 printf("%s: cmd %04x failed (timeout)\n",
2652 sc->sc_dev.dv_xname, cmd);
2653 ret = 1;
2654 goto back;
2655 }
2656 #undef CMDWAIT_RETRY_MAX
2657
2658
2659 status = (CMD_READ_4(sc) >> ACX_CMD_STATUS_SHIFT);
2660 if (status != ACX_CMD_STATUS_OK) {
2661 DPRINTF(("%s: cmd %04x failed\n", sc->sc_dev.dv_xname, cmd));
2662 ret = 1;
2663 goto back;
2664 }
2665
2666 if (result != NULL && result_len != 0) {
2667
2668 CMDPRM_READ_REGION_1(sc, result, result_len);
2669 }
2670
2671 back:
2672 CMD_WRITE_4(sc, 0);
2673
2674 return (ret);
2675 }
2676
2677 const char *
2678 acx_get_rf(int rev)
2679 {
2680 switch (rev) {
2681 case ACX_RADIO_TYPE_MAXIM: return "MAX2820";
2682 case ACX_RADIO_TYPE_RFMD: return "RFMD";
2683 case ACX_RADIO_TYPE_RALINK: return "Ralink";
2684 case ACX_RADIO_TYPE_RADIA: return "Radia";
2685 default: return "unknown";
2686 }
2687 }
2688
2689 int
2690 acx_get_maxrssi(int radio)
2691 {
2692 switch (radio) {
2693 case ACX_RADIO_TYPE_MAXIM: return ACX_RADIO_RSSI_MAXIM;
2694 case ACX_RADIO_TYPE_RFMD: return ACX_RADIO_RSSI_RFMD;
2695 case ACX_RADIO_TYPE_RALINK: return ACX_RADIO_RSSI_RALINK;
2696 case ACX_RADIO_TYPE_RADIA: return ACX_RADIO_RSSI_RADIA;
2697 default: return ACX_RADIO_RSSI_UNKN;
2698 }
2699 }
2700
2701 void
2702 acx_iter_func(void *arg, struct ieee80211_node *ni)
2703 {
2704 struct acx_softc *sc = arg;
2705 struct acx_node *wn = (struct acx_node *)ni;
2706
2707 ieee80211_amrr_choose(&sc->amrr, ni, &wn->amn);
2708 }
2709
2710 void
2711 acx_amrr_timeout(void *arg)
2712 {
2713 struct acx_softc *sc = arg;
2714 struct ieee80211com *ic = &sc->sc_ic;
2715
2716 if (ic->ic_opmode == IEEE80211_M_STA)
2717 acx_iter_func(sc, ic->ic_bss);
2718 else
2719 ieee80211_iterate_nodes(ic, acx_iter_func, sc);
2720
2721 timeout_add(&sc->amrr_ch, hz / 2);
2722 }
2723
2724 void
2725 acx_newassoc(struct ieee80211com *ic, struct ieee80211_node *ni, int isnew)
2726 {
2727 struct acx_softc *sc = ic->ic_if.if_softc;
2728 int i;
2729
2730 ieee80211_amrr_node_init(&sc->amrr, &((struct acx_node *)ni)->amn);
2731
2732
2733 for (i = ni->ni_rates.rs_nrates - 1;
2734 i > 0 && (ni->ni_rates.rs_rates[i] & IEEE80211_RATE_VAL) > 72;
2735 i--);
2736 ni->ni_txrate = i;
2737 }