Line data Source code
1 : /* $OpenBSD: rt2661.c,v 1.94 2017/10/26 15:00:28 mpi Exp $ */
2 :
3 : /*-
4 : * Copyright (c) 2006
5 : * Damien Bergamini <damien.bergamini@free.fr>
6 : *
7 : * Permission to use, copy, modify, and distribute this software for any
8 : * purpose with or without fee is hereby granted, provided that the above
9 : * copyright notice and this permission notice appear in all copies.
10 : *
11 : * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 : * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 : * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 : * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 : * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 : * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 : * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 : */
19 :
20 : /*-
21 : * Ralink Technology RT2561, RT2561S and RT2661 chipset driver
22 : * http://www.ralinktech.com/
23 : */
24 :
25 : #include "bpfilter.h"
26 :
27 : #include <sys/param.h>
28 : #include <sys/sockio.h>
29 : #include <sys/mbuf.h>
30 : #include <sys/kernel.h>
31 : #include <sys/socket.h>
32 : #include <sys/systm.h>
33 : #include <sys/malloc.h>
34 : #include <sys/timeout.h>
35 : #include <sys/conf.h>
36 : #include <sys/device.h>
37 : #include <sys/queue.h>
38 : #include <sys/endian.h>
39 :
40 : #include <machine/bus.h>
41 : #include <machine/intr.h>
42 :
43 : #if NBPFILTER > 0
44 : #include <net/bpf.h>
45 : #endif
46 : #include <net/if.h>
47 : #include <net/if_dl.h>
48 : #include <net/if_media.h>
49 :
50 : #include <netinet/in.h>
51 : #include <netinet/if_ether.h>
52 :
53 : #include <net80211/ieee80211_var.h>
54 : #include <net80211/ieee80211_amrr.h>
55 : #include <net80211/ieee80211_radiotap.h>
56 : #include <net80211/ieee80211_node.h>
57 :
58 : #include <dev/ic/rt2661var.h>
59 : #include <dev/ic/rt2661reg.h>
60 :
61 : #include <dev/pci/pcidevs.h>
62 :
63 : #ifdef RAL_DEBUG
64 : #define DPRINTF(x) do { if (rt2661_debug > 0) printf x; } while (0)
65 : #define DPRINTFN(n, x) do { if (rt2661_debug >= (n)) printf x; } while (0)
66 : int rt2661_debug = 1;
67 : #else
68 : #define DPRINTF(x)
69 : #define DPRINTFN(n, x)
70 : #endif
71 :
72 : void rt2661_attachhook(struct device *);
73 : int rt2661_alloc_tx_ring(struct rt2661_softc *,
74 : struct rt2661_tx_ring *, int);
75 : void rt2661_reset_tx_ring(struct rt2661_softc *,
76 : struct rt2661_tx_ring *);
77 : void rt2661_free_tx_ring(struct rt2661_softc *,
78 : struct rt2661_tx_ring *);
79 : int rt2661_alloc_rx_ring(struct rt2661_softc *,
80 : struct rt2661_rx_ring *, int);
81 : void rt2661_reset_rx_ring(struct rt2661_softc *,
82 : struct rt2661_rx_ring *);
83 : void rt2661_free_rx_ring(struct rt2661_softc *,
84 : struct rt2661_rx_ring *);
85 : struct ieee80211_node *rt2661_node_alloc(struct ieee80211com *);
86 : void rt2661_node_free(struct ieee80211com *,
87 : struct ieee80211_node *);
88 : int rt2661_media_change(struct ifnet *);
89 : void rt2661_next_scan(void *);
90 : void rt2661_iter_func(void *, struct ieee80211_node *);
91 : void rt2661_updatestats(void *);
92 : void rt2661_newassoc(struct ieee80211com *, struct ieee80211_node *,
93 : int);
94 : int rt2661_newstate(struct ieee80211com *, enum ieee80211_state,
95 : int);
96 : uint16_t rt2661_eeprom_read(struct rt2661_softc *, uint8_t);
97 : void rt2661_tx_intr(struct rt2661_softc *);
98 : void rt2661_tx_dma_intr(struct rt2661_softc *,
99 : struct rt2661_tx_ring *);
100 : void rt2661_rx_intr(struct rt2661_softc *);
101 : #ifndef IEEE80211_STA_ONLY
102 : void rt2661_mcu_beacon_expire(struct rt2661_softc *);
103 : #endif
104 : void rt2661_mcu_wakeup(struct rt2661_softc *);
105 : void rt2661_mcu_cmd_intr(struct rt2661_softc *);
106 : int rt2661_intr(void *);
107 : #if NBPFILTER > 0
108 : uint8_t rt2661_rxrate(const struct rt2661_rx_desc *);
109 : #endif
110 : int rt2661_ack_rate(struct ieee80211com *, int);
111 : uint16_t rt2661_txtime(int, int, uint32_t);
112 : uint8_t rt2661_plcp_signal(int);
113 : void rt2661_setup_tx_desc(struct rt2661_softc *,
114 : struct rt2661_tx_desc *, uint32_t, uint16_t, int, int,
115 : const bus_dma_segment_t *, int, int, u_int8_t);
116 : int rt2661_tx_mgt(struct rt2661_softc *, struct mbuf *,
117 : struct ieee80211_node *);
118 : int rt2661_tx_data(struct rt2661_softc *, struct mbuf *,
119 : struct ieee80211_node *, int);
120 : void rt2661_start(struct ifnet *);
121 : void rt2661_watchdog(struct ifnet *);
122 : int rt2661_ioctl(struct ifnet *, u_long, caddr_t);
123 : void rt2661_bbp_write(struct rt2661_softc *, uint8_t, uint8_t);
124 : uint8_t rt2661_bbp_read(struct rt2661_softc *, uint8_t);
125 : void rt2661_rf_write(struct rt2661_softc *, uint8_t, uint32_t);
126 : int rt2661_tx_cmd(struct rt2661_softc *, uint8_t, uint16_t);
127 : void rt2661_select_antenna(struct rt2661_softc *);
128 : void rt2661_enable_mrr(struct rt2661_softc *);
129 : void rt2661_set_txpreamble(struct rt2661_softc *);
130 : void rt2661_set_basicrates(struct rt2661_softc *);
131 : void rt2661_select_band(struct rt2661_softc *,
132 : struct ieee80211_channel *);
133 : void rt2661_set_chan(struct rt2661_softc *,
134 : struct ieee80211_channel *);
135 : void rt2661_set_bssid(struct rt2661_softc *, const uint8_t *);
136 : void rt2661_set_macaddr(struct rt2661_softc *, const uint8_t *);
137 : void rt2661_update_promisc(struct rt2661_softc *);
138 : void rt2661_updateslot(struct ieee80211com *);
139 : void rt2661_set_slottime(struct rt2661_softc *);
140 : const char *rt2661_get_rf(int);
141 : void rt2661_read_eeprom(struct rt2661_softc *);
142 : int rt2661_bbp_init(struct rt2661_softc *);
143 : int rt2661_init(struct ifnet *);
144 : void rt2661_stop(struct ifnet *, int);
145 : int rt2661_load_microcode(struct rt2661_softc *);
146 : void rt2661_rx_tune(struct rt2661_softc *);
147 : #ifdef notyet
148 : void rt2661_radar_start(struct rt2661_softc *);
149 : int rt2661_radar_stop(struct rt2661_softc *);
150 : #endif
151 : #ifndef IEEE80211_STA_ONLY
152 : int rt2661_prepare_beacon(struct rt2661_softc *);
153 : #endif
154 : void rt2661_enable_tsf_sync(struct rt2661_softc *);
155 : int rt2661_get_rssi(struct rt2661_softc *, uint8_t);
156 : struct rt2661_amrr_node *rt2661_amrr_node_alloc(struct ieee80211com *,
157 : struct rt2661_node *);
158 : void rt2661_amrr_node_free(struct rt2661_softc *,
159 : struct rt2661_amrr_node *);
160 : void rt2661_amrr_node_free_all(struct rt2661_softc *);
161 : void rt2661_amrr_node_free_unused(struct rt2661_softc *);
162 : struct rt2661_amrr_node *rt2661_amrr_node_find(struct rt2661_softc *,
163 : u_int8_t);
164 :
165 : static const struct {
166 : uint32_t reg;
167 : uint32_t val;
168 : } rt2661_def_mac[] = {
169 : RT2661_DEF_MAC
170 : };
171 :
172 : static const struct {
173 : uint8_t reg;
174 : uint8_t val;
175 : } rt2661_def_bbp[] = {
176 : RT2661_DEF_BBP
177 : };
178 :
179 : static const struct rfprog {
180 : uint8_t chan;
181 : uint32_t r1, r2, r3, r4;
182 : } rt2661_rf5225_1[] = {
183 : RT2661_RF5225_1
184 : }, rt2661_rf5225_2[] = {
185 : RT2661_RF5225_2
186 : };
187 :
188 : int
189 0 : rt2661_attach(void *xsc, int id)
190 : {
191 0 : struct rt2661_softc *sc = xsc;
192 0 : struct ieee80211com *ic = &sc->sc_ic;
193 : uint32_t val;
194 : int error, ac, ntries;
195 :
196 0 : sc->sc_id = id;
197 :
198 0 : sc->amrr.amrr_min_success_threshold = 1;
199 0 : sc->amrr.amrr_max_success_threshold = 15;
200 0 : timeout_set(&sc->amrr_to, rt2661_updatestats, sc);
201 0 : timeout_set(&sc->scan_to, rt2661_next_scan, sc);
202 :
203 0 : TAILQ_INIT(&sc->amn);
204 :
205 : /* wait for NIC to initialize */
206 0 : for (ntries = 0; ntries < 1000; ntries++) {
207 0 : if ((val = RAL_READ(sc, RT2661_MAC_CSR0)) != 0)
208 : break;
209 0 : DELAY(1000);
210 : }
211 0 : if (ntries == 1000) {
212 0 : printf("%s: timeout waiting for NIC to initialize\n",
213 0 : sc->sc_dev.dv_xname);
214 0 : return EIO;
215 : }
216 :
217 : /* retrieve RF rev. no and various other things from EEPROM */
218 0 : rt2661_read_eeprom(sc);
219 0 : printf(", address %s\n", ether_sprintf(ic->ic_myaddr));
220 :
221 0 : printf("%s: MAC/BBP RT%X, RF %s\n", sc->sc_dev.dv_xname, val,
222 0 : rt2661_get_rf(sc->rf_rev));
223 :
224 : /*
225 : * Allocate Tx and Rx rings.
226 : */
227 0 : for (ac = 0; ac < 4; ac++) {
228 0 : error = rt2661_alloc_tx_ring(sc, &sc->txq[ac],
229 : RT2661_TX_RING_COUNT);
230 0 : if (error != 0) {
231 0 : printf("%s: could not allocate Tx ring %d\n",
232 : sc->sc_dev.dv_xname, ac);
233 0 : goto fail1;
234 : }
235 : }
236 :
237 0 : error = rt2661_alloc_tx_ring(sc, &sc->mgtq, RT2661_MGT_RING_COUNT);
238 0 : if (error != 0) {
239 0 : printf("%s: could not allocate Mgt ring\n",
240 : sc->sc_dev.dv_xname);
241 0 : goto fail1;
242 : }
243 :
244 0 : error = rt2661_alloc_rx_ring(sc, &sc->rxq, RT2661_RX_RING_COUNT);
245 0 : if (error != 0) {
246 0 : printf("%s: could not allocate Rx ring\n",
247 : sc->sc_dev.dv_xname);
248 : goto fail2;
249 : }
250 :
251 0 : config_mountroot(xsc, rt2661_attachhook);
252 :
253 0 : return 0;
254 :
255 0 : fail2: rt2661_free_tx_ring(sc, &sc->mgtq);
256 0 : fail1: while (--ac >= 0)
257 0 : rt2661_free_tx_ring(sc, &sc->txq[ac]);
258 0 : return ENXIO;
259 0 : }
260 :
261 : void
262 0 : rt2661_attachhook(struct device *self)
263 : {
264 0 : struct rt2661_softc *sc = (struct rt2661_softc *)self;
265 0 : struct ieee80211com *ic = &sc->sc_ic;
266 0 : struct ifnet *ifp = &ic->ic_if;
267 : const char *name = NULL;
268 : int i, error;
269 :
270 0 : switch (sc->sc_id) {
271 : case PCI_PRODUCT_RALINK_RT2561:
272 : name = "ral-rt2561";
273 0 : break;
274 : case PCI_PRODUCT_RALINK_RT2561S:
275 : name = "ral-rt2561s";
276 0 : break;
277 : case PCI_PRODUCT_RALINK_RT2661:
278 : name = "ral-rt2661";
279 0 : break;
280 : }
281 0 : if ((error = loadfirmware(name, &sc->ucode, &sc->ucsize)) != 0) {
282 0 : printf("%s: error %d, could not read firmware %s\n",
283 0 : sc->sc_dev.dv_xname, error, name);
284 0 : return;
285 : }
286 :
287 0 : ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
288 0 : ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */
289 0 : ic->ic_state = IEEE80211_S_INIT;
290 :
291 : /* set device capabilities */
292 0 : ic->ic_caps =
293 : IEEE80211_C_MONITOR | /* monitor mode supported */
294 : #ifndef IEEE80211_STA_ONLY
295 : IEEE80211_C_IBSS | /* IBSS mode supported */
296 : IEEE80211_C_HOSTAP | /* HostAP mode supported */
297 : #endif
298 : IEEE80211_C_TXPMGT | /* tx power management */
299 : IEEE80211_C_SHPREAMBLE | /* short preamble supported */
300 : IEEE80211_C_SHSLOT | /* short slot time supported */
301 : IEEE80211_C_WEP | /* s/w WEP */
302 : IEEE80211_C_RSN; /* WPA/RSN */
303 :
304 0 : if (sc->rf_rev == RT2661_RF_5225 || sc->rf_rev == RT2661_RF_5325) {
305 : /* set supported .11a rates */
306 0 : ic->ic_sup_rates[IEEE80211_MODE_11A] =
307 0 : ieee80211_std_rateset_11a;
308 :
309 : /* set supported .11a channels */
310 0 : for (i = 36; i <= 64; i += 4) {
311 0 : ic->ic_channels[i].ic_freq =
312 0 : ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ);
313 0 : ic->ic_channels[i].ic_flags = IEEE80211_CHAN_A;
314 : }
315 0 : for (i = 100; i <= 140; i += 4) {
316 0 : ic->ic_channels[i].ic_freq =
317 0 : ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ);
318 0 : ic->ic_channels[i].ic_flags = IEEE80211_CHAN_A;
319 : }
320 0 : for (i = 149; i <= 165; i += 4) {
321 0 : ic->ic_channels[i].ic_freq =
322 0 : ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ);
323 0 : ic->ic_channels[i].ic_flags = IEEE80211_CHAN_A;
324 : }
325 : }
326 :
327 : /* set supported .11b and .11g rates */
328 0 : ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b;
329 0 : ic->ic_sup_rates[IEEE80211_MODE_11G] = ieee80211_std_rateset_11g;
330 :
331 : /* set supported .11b and .11g channels (1 through 14) */
332 0 : for (i = 1; i <= 14; i++) {
333 0 : ic->ic_channels[i].ic_freq =
334 0 : ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ);
335 0 : ic->ic_channels[i].ic_flags =
336 : IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM |
337 : IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ;
338 : }
339 :
340 0 : ifp->if_softc = sc;
341 0 : ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
342 0 : ifp->if_ioctl = rt2661_ioctl;
343 0 : ifp->if_start = rt2661_start;
344 0 : ifp->if_watchdog = rt2661_watchdog;
345 0 : memcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ);
346 :
347 0 : if_attach(ifp);
348 0 : ieee80211_ifattach(ifp);
349 0 : ic->ic_node_alloc = rt2661_node_alloc;
350 0 : sc->sc_node_free = ic->ic_node_free;
351 0 : ic->ic_node_free = rt2661_node_free;
352 0 : ic->ic_newassoc = rt2661_newassoc;
353 0 : ic->ic_updateslot = rt2661_updateslot;
354 :
355 : /* override state transition machine */
356 0 : sc->sc_newstate = ic->ic_newstate;
357 0 : ic->ic_newstate = rt2661_newstate;
358 0 : ieee80211_media_init(ifp, rt2661_media_change, ieee80211_media_status);
359 :
360 : #if NBPFILTER > 0
361 0 : bpfattach(&sc->sc_drvbpf, ifp, DLT_IEEE802_11_RADIO,
362 : sizeof (struct ieee80211_frame) + 64);
363 :
364 0 : sc->sc_rxtap_len = sizeof sc->sc_rxtapu;
365 0 : sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
366 0 : sc->sc_rxtap.wr_ihdr.it_present = htole32(RT2661_RX_RADIOTAP_PRESENT);
367 :
368 0 : sc->sc_txtap_len = sizeof sc->sc_txtapu;
369 0 : sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
370 0 : sc->sc_txtap.wt_ihdr.it_present = htole32(RT2661_TX_RADIOTAP_PRESENT);
371 : #endif
372 0 : }
373 :
374 : int
375 0 : rt2661_detach(void *xsc)
376 : {
377 0 : struct rt2661_softc *sc = xsc;
378 0 : struct ifnet *ifp = &sc->sc_ic.ic_if;
379 : int ac;
380 :
381 0 : timeout_del(&sc->scan_to);
382 0 : timeout_del(&sc->amrr_to);
383 :
384 0 : ieee80211_ifdetach(ifp); /* free all nodes */
385 0 : rt2661_amrr_node_free_all(sc);
386 0 : if_detach(ifp);
387 :
388 0 : for (ac = 0; ac < 4; ac++)
389 0 : rt2661_free_tx_ring(sc, &sc->txq[ac]);
390 0 : rt2661_free_tx_ring(sc, &sc->mgtq);
391 0 : rt2661_free_rx_ring(sc, &sc->rxq);
392 :
393 0 : if (sc->ucode != NULL)
394 0 : free(sc->ucode, M_DEVBUF, sc->ucsize);
395 :
396 0 : return 0;
397 : }
398 :
399 : void
400 0 : rt2661_suspend(void *xsc)
401 : {
402 0 : struct rt2661_softc *sc = xsc;
403 0 : struct ifnet *ifp = &sc->sc_ic.ic_if;
404 :
405 0 : if (ifp->if_flags & IFF_RUNNING) {
406 0 : rt2661_stop(ifp, 1);
407 0 : sc->sc_flags &= ~RT2661_FWLOADED;
408 0 : }
409 0 : }
410 :
411 : void
412 0 : rt2661_wakeup(void *xsc)
413 : {
414 0 : struct rt2661_softc *sc = xsc;
415 0 : struct ifnet *ifp = &sc->sc_ic.ic_if;
416 :
417 0 : if (ifp->if_flags & IFF_UP)
418 0 : rt2661_init(ifp);
419 0 : }
420 :
421 : int
422 0 : rt2661_alloc_tx_ring(struct rt2661_softc *sc, struct rt2661_tx_ring *ring,
423 : int count)
424 : {
425 0 : int i, nsegs, error;
426 :
427 0 : ring->count = count;
428 0 : ring->queued = 0;
429 0 : ring->cur = ring->next = ring->stat = 0;
430 :
431 0 : error = bus_dmamap_create(sc->sc_dmat, count * RT2661_TX_DESC_SIZE, 1,
432 : count * RT2661_TX_DESC_SIZE, 0, BUS_DMA_NOWAIT, &ring->map);
433 0 : if (error != 0) {
434 0 : printf("%s: could not create desc DMA map\n",
435 0 : sc->sc_dev.dv_xname);
436 0 : goto fail;
437 : }
438 :
439 0 : error = bus_dmamem_alloc(sc->sc_dmat, count * RT2661_TX_DESC_SIZE,
440 : PAGE_SIZE, 0, &ring->seg, 1, &nsegs, BUS_DMA_NOWAIT | BUS_DMA_ZERO);
441 0 : if (error != 0) {
442 0 : printf("%s: could not allocate DMA memory\n",
443 0 : sc->sc_dev.dv_xname);
444 0 : goto fail;
445 : }
446 :
447 0 : error = bus_dmamem_map(sc->sc_dmat, &ring->seg, nsegs,
448 : count * RT2661_TX_DESC_SIZE, (caddr_t *)&ring->desc,
449 : BUS_DMA_NOWAIT);
450 0 : if (error != 0) {
451 0 : printf("%s: can't map desc DMA memory\n",
452 0 : sc->sc_dev.dv_xname);
453 0 : goto fail;
454 : }
455 :
456 0 : error = bus_dmamap_load(sc->sc_dmat, ring->map, ring->desc,
457 : count * RT2661_TX_DESC_SIZE, NULL, BUS_DMA_NOWAIT);
458 0 : if (error != 0) {
459 0 : printf("%s: could not load desc DMA map\n",
460 0 : sc->sc_dev.dv_xname);
461 0 : goto fail;
462 : }
463 :
464 0 : ring->physaddr = ring->map->dm_segs->ds_addr;
465 :
466 0 : ring->data = mallocarray(count, sizeof (struct rt2661_tx_data),
467 : M_DEVBUF, M_NOWAIT | M_ZERO);
468 0 : if (ring->data == NULL) {
469 0 : printf("%s: could not allocate soft data\n",
470 0 : sc->sc_dev.dv_xname);
471 : error = ENOMEM;
472 0 : goto fail;
473 : }
474 :
475 0 : for (i = 0; i < count; i++) {
476 0 : error = bus_dmamap_create(sc->sc_dmat, MCLBYTES,
477 : RT2661_MAX_SCATTER, MCLBYTES, 0, BUS_DMA_NOWAIT,
478 : &ring->data[i].map);
479 0 : if (error != 0) {
480 0 : printf("%s: could not create DMA map\n",
481 0 : sc->sc_dev.dv_xname);
482 0 : goto fail;
483 : }
484 : }
485 :
486 0 : return 0;
487 :
488 0 : fail: rt2661_free_tx_ring(sc, ring);
489 0 : return error;
490 0 : }
491 :
492 : void
493 0 : rt2661_reset_tx_ring(struct rt2661_softc *sc, struct rt2661_tx_ring *ring)
494 : {
495 : int i;
496 :
497 0 : for (i = 0; i < ring->count; i++) {
498 0 : struct rt2661_tx_desc *desc = &ring->desc[i];
499 0 : struct rt2661_tx_data *data = &ring->data[i];
500 :
501 0 : if (data->m != NULL) {
502 0 : bus_dmamap_sync(sc->sc_dmat, data->map, 0,
503 : data->map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
504 0 : bus_dmamap_unload(sc->sc_dmat, data->map);
505 0 : m_freem(data->m);
506 0 : data->m = NULL;
507 0 : }
508 :
509 : /*
510 : * The node has already been freed at that point so don't call
511 : * ieee80211_release_node() here.
512 : */
513 0 : data->ni = NULL;
514 :
515 0 : desc->flags = 0;
516 : }
517 :
518 0 : bus_dmamap_sync(sc->sc_dmat, ring->map, 0, ring->map->dm_mapsize,
519 : BUS_DMASYNC_PREWRITE);
520 :
521 0 : ring->queued = 0;
522 0 : ring->cur = ring->next = ring->stat = 0;
523 0 : }
524 :
525 : void
526 0 : rt2661_free_tx_ring(struct rt2661_softc *sc, struct rt2661_tx_ring *ring)
527 : {
528 : int i;
529 :
530 0 : if (ring->desc != NULL) {
531 0 : bus_dmamap_sync(sc->sc_dmat, ring->map, 0,
532 : ring->map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
533 0 : bus_dmamap_unload(sc->sc_dmat, ring->map);
534 0 : bus_dmamem_unmap(sc->sc_dmat, (caddr_t)ring->desc,
535 : ring->count * RT2661_TX_DESC_SIZE);
536 0 : bus_dmamem_free(sc->sc_dmat, &ring->seg, 1);
537 0 : }
538 :
539 0 : if (ring->data != NULL) {
540 0 : for (i = 0; i < ring->count; i++) {
541 0 : struct rt2661_tx_data *data = &ring->data[i];
542 :
543 0 : if (data->m != NULL) {
544 0 : bus_dmamap_sync(sc->sc_dmat, data->map, 0,
545 : data->map->dm_mapsize,
546 : BUS_DMASYNC_POSTWRITE);
547 0 : bus_dmamap_unload(sc->sc_dmat, data->map);
548 0 : m_freem(data->m);
549 0 : }
550 : /*
551 : * The node has already been freed at that point so
552 : * don't call ieee80211_release_node() here.
553 : */
554 0 : data->ni = NULL;
555 :
556 0 : if (data->map != NULL)
557 0 : bus_dmamap_destroy(sc->sc_dmat, data->map);
558 : }
559 0 : free(ring->data, M_DEVBUF, ring->count * sizeof *ring->data);
560 0 : }
561 0 : }
562 :
563 : int
564 0 : rt2661_alloc_rx_ring(struct rt2661_softc *sc, struct rt2661_rx_ring *ring,
565 : int count)
566 : {
567 0 : int i, nsegs, error;
568 :
569 0 : ring->count = count;
570 0 : ring->cur = ring->next = 0;
571 :
572 0 : error = bus_dmamap_create(sc->sc_dmat, count * RT2661_RX_DESC_SIZE, 1,
573 : count * RT2661_RX_DESC_SIZE, 0, BUS_DMA_NOWAIT, &ring->map);
574 0 : if (error != 0) {
575 0 : printf("%s: could not create desc DMA map\n",
576 0 : sc->sc_dev.dv_xname);
577 0 : goto fail;
578 : }
579 :
580 0 : error = bus_dmamem_alloc(sc->sc_dmat, count * RT2661_RX_DESC_SIZE,
581 : PAGE_SIZE, 0, &ring->seg, 1, &nsegs, BUS_DMA_NOWAIT | BUS_DMA_ZERO);
582 0 : if (error != 0) {
583 0 : printf("%s: could not allocate DMA memory\n",
584 0 : sc->sc_dev.dv_xname);
585 0 : goto fail;
586 : }
587 :
588 0 : error = bus_dmamem_map(sc->sc_dmat, &ring->seg, nsegs,
589 : count * RT2661_RX_DESC_SIZE, (caddr_t *)&ring->desc,
590 : BUS_DMA_NOWAIT);
591 0 : if (error != 0) {
592 0 : printf("%s: can't map desc DMA memory\n",
593 0 : sc->sc_dev.dv_xname);
594 0 : goto fail;
595 : }
596 :
597 0 : error = bus_dmamap_load(sc->sc_dmat, ring->map, ring->desc,
598 : count * RT2661_RX_DESC_SIZE, NULL, BUS_DMA_NOWAIT);
599 0 : if (error != 0) {
600 0 : printf("%s: could not load desc DMA map\n",
601 0 : sc->sc_dev.dv_xname);
602 0 : goto fail;
603 : }
604 :
605 0 : ring->physaddr = ring->map->dm_segs->ds_addr;
606 :
607 0 : ring->data = mallocarray(count, sizeof (struct rt2661_rx_data),
608 : M_DEVBUF, M_NOWAIT | M_ZERO);
609 0 : if (ring->data == NULL) {
610 0 : printf("%s: could not allocate soft data\n",
611 0 : sc->sc_dev.dv_xname);
612 : error = ENOMEM;
613 0 : goto fail;
614 : }
615 :
616 : /*
617 : * Pre-allocate Rx buffers and populate Rx ring.
618 : */
619 0 : for (i = 0; i < count; i++) {
620 0 : struct rt2661_rx_desc *desc = &sc->rxq.desc[i];
621 0 : struct rt2661_rx_data *data = &sc->rxq.data[i];
622 :
623 0 : error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES,
624 : 0, BUS_DMA_NOWAIT, &data->map);
625 0 : if (error != 0) {
626 0 : printf("%s: could not create DMA map\n",
627 0 : sc->sc_dev.dv_xname);
628 0 : goto fail;
629 : }
630 :
631 0 : MGETHDR(data->m, M_DONTWAIT, MT_DATA);
632 0 : if (data->m == NULL) {
633 0 : printf("%s: could not allocate rx mbuf\n",
634 0 : sc->sc_dev.dv_xname);
635 : error = ENOMEM;
636 0 : goto fail;
637 : }
638 0 : MCLGET(data->m, M_DONTWAIT);
639 0 : if (!(data->m->m_flags & M_EXT)) {
640 0 : printf("%s: could not allocate rx mbuf cluster\n",
641 0 : sc->sc_dev.dv_xname);
642 : error = ENOMEM;
643 0 : goto fail;
644 : }
645 :
646 0 : error = bus_dmamap_load(sc->sc_dmat, data->map,
647 : mtod(data->m, void *), MCLBYTES, NULL, BUS_DMA_NOWAIT);
648 0 : if (error != 0) {
649 0 : printf("%s: could not load rx buf DMA map",
650 0 : sc->sc_dev.dv_xname);
651 0 : goto fail;
652 : }
653 :
654 0 : desc->flags = htole32(RT2661_RX_BUSY);
655 0 : desc->physaddr = htole32(data->map->dm_segs->ds_addr);
656 0 : }
657 :
658 0 : bus_dmamap_sync(sc->sc_dmat, ring->map, 0, ring->map->dm_mapsize,
659 : BUS_DMASYNC_PREWRITE);
660 :
661 0 : return 0;
662 :
663 0 : fail: rt2661_free_rx_ring(sc, ring);
664 0 : return error;
665 0 : }
666 :
667 : void
668 0 : rt2661_reset_rx_ring(struct rt2661_softc *sc, struct rt2661_rx_ring *ring)
669 : {
670 : int i;
671 :
672 0 : for (i = 0; i < ring->count; i++)
673 0 : ring->desc[i].flags = htole32(RT2661_RX_BUSY);
674 :
675 0 : bus_dmamap_sync(sc->sc_dmat, ring->map, 0, ring->map->dm_mapsize,
676 : BUS_DMASYNC_PREWRITE);
677 :
678 0 : ring->cur = ring->next = 0;
679 0 : }
680 :
681 : void
682 0 : rt2661_free_rx_ring(struct rt2661_softc *sc, struct rt2661_rx_ring *ring)
683 : {
684 : int i;
685 :
686 0 : if (ring->desc != NULL) {
687 0 : bus_dmamap_sync(sc->sc_dmat, ring->map, 0,
688 : ring->map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
689 0 : bus_dmamap_unload(sc->sc_dmat, ring->map);
690 0 : bus_dmamem_unmap(sc->sc_dmat, (caddr_t)ring->desc,
691 : ring->count * RT2661_RX_DESC_SIZE);
692 0 : bus_dmamem_free(sc->sc_dmat, &ring->seg, 1);
693 0 : }
694 :
695 0 : if (ring->data != NULL) {
696 0 : for (i = 0; i < ring->count; i++) {
697 0 : struct rt2661_rx_data *data = &ring->data[i];
698 :
699 0 : if (data->m != NULL) {
700 0 : bus_dmamap_sync(sc->sc_dmat, data->map, 0,
701 : data->map->dm_mapsize,
702 : BUS_DMASYNC_POSTREAD);
703 0 : bus_dmamap_unload(sc->sc_dmat, data->map);
704 0 : m_freem(data->m);
705 0 : }
706 :
707 0 : if (data->map != NULL)
708 0 : bus_dmamap_destroy(sc->sc_dmat, data->map);
709 : }
710 0 : free(ring->data, M_DEVBUF, ring->count * sizeof *ring->data);
711 0 : }
712 0 : }
713 :
714 : struct rt2661_amrr_node *
715 0 : rt2661_amrr_node_alloc(struct ieee80211com *ic, struct rt2661_node *rn)
716 : {
717 0 : struct rt2661_softc *sc = ic->ic_softc;
718 : struct rt2661_amrr_node *amn;
719 : int s;
720 :
721 0 : if (sc->amn_count >= RT2661_AMRR_NODES_MAX)
722 0 : rt2661_amrr_node_free_unused(sc);
723 0 : if (sc->amn_count >= RT2661_AMRR_NODES_MAX)
724 0 : return NULL;
725 :
726 0 : amn = malloc(sizeof (struct rt2661_amrr_node), M_DEVBUF,
727 : M_NOWAIT | M_ZERO);
728 :
729 0 : if (amn) {
730 0 : s = splnet();
731 0 : amn->id = sc->amn_count++;
732 0 : amn->rn = rn;
733 0 : TAILQ_INSERT_TAIL(&sc->amn, amn, entry);
734 0 : splx(s);
735 0 : }
736 :
737 0 : return amn;
738 0 : }
739 :
740 : void
741 0 : rt2661_amrr_node_free(struct rt2661_softc *sc, struct rt2661_amrr_node *amn)
742 : {
743 : int s;
744 :
745 0 : s = splnet();
746 0 : if (amn->rn)
747 0 : amn->rn->amn = NULL;
748 0 : TAILQ_REMOVE(&sc->amn, amn, entry);
749 0 : sc->amn_count--;
750 0 : splx(s);
751 0 : free(amn, M_DEVBUF, sizeof *amn);
752 0 : }
753 :
754 : void
755 0 : rt2661_amrr_node_free_all(struct rt2661_softc *sc)
756 : {
757 : struct rt2661_amrr_node *amn, *a;
758 : int s;
759 :
760 0 : s = splnet();
761 0 : TAILQ_FOREACH_SAFE(amn, &sc->amn, entry, a)
762 0 : rt2661_amrr_node_free(sc, amn);
763 0 : splx(s);
764 0 : }
765 :
766 : void
767 0 : rt2661_amrr_node_free_unused(struct rt2661_softc *sc)
768 : {
769 : struct rt2661_amrr_node *amn, *a;
770 : int s;
771 :
772 0 : s = splnet();
773 0 : TAILQ_FOREACH_SAFE(amn, &sc->amn, entry, a) {
774 0 : if (amn->rn == NULL)
775 0 : rt2661_amrr_node_free(sc, amn);
776 : }
777 0 : splx(s);
778 0 : }
779 :
780 : struct rt2661_amrr_node *
781 0 : rt2661_amrr_node_find(struct rt2661_softc *sc, u_int8_t id)
782 : {
783 : struct rt2661_amrr_node *amn, *a, *ret = NULL;
784 : int s;
785 :
786 0 : if (id == RT2661_AMRR_INVALID_ID)
787 0 : return NULL;
788 :
789 0 : s = splnet();
790 0 : TAILQ_FOREACH_SAFE(amn, &sc->amn, entry, a) {
791 : /* If the corresponding node was freed, free the amrr node. */
792 0 : if (amn->rn == NULL)
793 0 : rt2661_amrr_node_free(sc, amn);
794 0 : else if (amn->id == id)
795 0 : ret = amn;
796 : }
797 0 : splx(s);
798 :
799 0 : return ret;
800 0 : }
801 :
802 : struct ieee80211_node *
803 0 : rt2661_node_alloc(struct ieee80211com *ic)
804 : {
805 : struct rt2661_node *rn;
806 :
807 0 : rn = malloc(sizeof (struct rt2661_node), M_DEVBUF,
808 : M_NOWAIT | M_ZERO);
809 0 : if (rn == NULL)
810 0 : return NULL;
811 :
812 0 : rn->amn = rt2661_amrr_node_alloc(ic, rn);
813 0 : return (struct ieee80211_node *)rn;
814 0 : }
815 :
816 : void
817 0 : rt2661_node_free(struct ieee80211com *ic, struct ieee80211_node *ni)
818 : {
819 0 : struct rt2661_softc *sc = ic->ic_softc;
820 0 : struct rt2661_node *rn = (struct rt2661_node *)ni;
821 :
822 0 : if (rn->amn)
823 0 : rn->amn->rn = NULL;
824 0 : sc->sc_node_free(ic, ni);
825 0 : }
826 :
827 : int
828 0 : rt2661_media_change(struct ifnet *ifp)
829 : {
830 : int error;
831 :
832 0 : error = ieee80211_media_change(ifp);
833 0 : if (error != ENETRESET)
834 0 : return error;
835 :
836 0 : if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING))
837 0 : rt2661_init(ifp);
838 :
839 0 : return 0;
840 0 : }
841 :
842 : /*
843 : * This function is called periodically (every 200ms) during scanning to
844 : * switch from one channel to another.
845 : */
846 : void
847 0 : rt2661_next_scan(void *arg)
848 : {
849 0 : struct rt2661_softc *sc = arg;
850 0 : struct ieee80211com *ic = &sc->sc_ic;
851 0 : struct ifnet *ifp = &ic->ic_if;
852 : int s;
853 :
854 0 : s = splnet();
855 0 : if (ic->ic_state == IEEE80211_S_SCAN)
856 0 : ieee80211_next_scan(ifp);
857 0 : splx(s);
858 0 : }
859 :
860 : /*
861 : * This function is called for each neighbor node.
862 : */
863 : void
864 0 : rt2661_iter_func(void *arg, struct ieee80211_node *ni)
865 : {
866 0 : struct rt2661_softc *sc = arg;
867 0 : struct rt2661_node *rn = (struct rt2661_node *)ni;
868 :
869 0 : if (rn->amn)
870 0 : ieee80211_amrr_choose(&sc->amrr, ni, &rn->amn->amn);
871 0 : }
872 :
873 : /*
874 : * This function is called periodically (every 500ms) in RUN state to update
875 : * various settings like rate control statistics or Rx sensitivity.
876 : */
877 : void
878 0 : rt2661_updatestats(void *arg)
879 : {
880 0 : struct rt2661_softc *sc = arg;
881 0 : struct ieee80211com *ic = &sc->sc_ic;
882 : int s;
883 :
884 0 : s = splnet();
885 0 : if (ic->ic_opmode == IEEE80211_M_STA)
886 0 : rt2661_iter_func(sc, ic->ic_bss);
887 : else
888 0 : ieee80211_iterate_nodes(ic, rt2661_iter_func, arg);
889 :
890 : /* update rx sensitivity and free unused amrr nodes every 1 sec */
891 0 : if (++sc->ncalls & 1) {
892 0 : rt2661_rx_tune(sc);
893 0 : rt2661_amrr_node_free_unused(sc);
894 0 : }
895 0 : splx(s);
896 :
897 0 : timeout_add_msec(&sc->amrr_to, 500);
898 0 : }
899 :
900 : void
901 0 : rt2661_newassoc(struct ieee80211com *ic, struct ieee80211_node *ni, int isnew)
902 : {
903 0 : struct rt2661_softc *sc = ic->ic_softc;
904 0 : struct rt2661_node *rn = (struct rt2661_node *)ni;
905 : int i;
906 :
907 0 : if (rn->amn)
908 0 : ieee80211_amrr_node_init(&sc->amrr, &rn->amn->amn);
909 :
910 : /* set rate to some reasonable initial value */
911 0 : for (i = ni->ni_rates.rs_nrates - 1;
912 0 : i > 0 && (ni->ni_rates.rs_rates[i] & IEEE80211_RATE_VAL) > 72;
913 0 : i--);
914 0 : ni->ni_txrate = i;
915 0 : }
916 :
917 : int
918 0 : rt2661_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
919 : {
920 0 : struct rt2661_softc *sc = ic->ic_if.if_softc;
921 : enum ieee80211_state ostate;
922 : struct ieee80211_node *ni;
923 : uint32_t tmp;
924 :
925 0 : ostate = ic->ic_state;
926 0 : timeout_del(&sc->scan_to);
927 0 : timeout_del(&sc->amrr_to);
928 :
929 0 : switch (nstate) {
930 : case IEEE80211_S_INIT:
931 0 : if (ostate == IEEE80211_S_RUN) {
932 : /* abort TSF synchronization */
933 0 : tmp = RAL_READ(sc, RT2661_TXRX_CSR9);
934 0 : RAL_WRITE(sc, RT2661_TXRX_CSR9, tmp & ~0x00ffffff);
935 0 : }
936 : break;
937 :
938 : case IEEE80211_S_SCAN:
939 0 : rt2661_set_chan(sc, ic->ic_bss->ni_chan);
940 0 : timeout_add_msec(&sc->scan_to, 200);
941 0 : break;
942 :
943 : case IEEE80211_S_AUTH:
944 : case IEEE80211_S_ASSOC:
945 0 : rt2661_set_chan(sc, ic->ic_bss->ni_chan);
946 0 : break;
947 :
948 : case IEEE80211_S_RUN:
949 0 : rt2661_set_chan(sc, ic->ic_bss->ni_chan);
950 :
951 0 : ni = ic->ic_bss;
952 :
953 0 : if (ic->ic_opmode != IEEE80211_M_MONITOR) {
954 0 : rt2661_set_slottime(sc);
955 0 : rt2661_enable_mrr(sc);
956 0 : rt2661_set_txpreamble(sc);
957 0 : rt2661_set_basicrates(sc);
958 0 : rt2661_set_bssid(sc, ni->ni_bssid);
959 0 : }
960 :
961 : #ifndef IEEE80211_STA_ONLY
962 0 : if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
963 0 : ic->ic_opmode == IEEE80211_M_IBSS)
964 0 : rt2661_prepare_beacon(sc);
965 : #endif
966 :
967 0 : if (ic->ic_opmode == IEEE80211_M_STA) {
968 : /* fake a join to init the tx rate */
969 0 : rt2661_newassoc(ic, ni, 1);
970 0 : }
971 :
972 0 : if (ic->ic_opmode != IEEE80211_M_MONITOR) {
973 0 : sc->ncalls = 0;
974 0 : sc->avg_rssi = -95; /* reset EMA */
975 0 : timeout_add_msec(&sc->amrr_to, 500);
976 0 : rt2661_enable_tsf_sync(sc);
977 0 : }
978 : break;
979 : }
980 :
981 0 : return sc->sc_newstate(ic, nstate, arg);
982 : }
983 :
984 : /*
985 : * Read 16 bits at address 'addr' from the serial EEPROM (either 93C46 or
986 : * 93C66).
987 : */
988 : uint16_t
989 0 : rt2661_eeprom_read(struct rt2661_softc *sc, uint8_t addr)
990 : {
991 : uint32_t tmp;
992 : uint16_t val;
993 : int n;
994 :
995 : /* clock C once before the first command */
996 0 : RT2661_EEPROM_CTL(sc, 0);
997 :
998 0 : RT2661_EEPROM_CTL(sc, RT2661_S);
999 0 : RT2661_EEPROM_CTL(sc, RT2661_S | RT2661_C);
1000 0 : RT2661_EEPROM_CTL(sc, RT2661_S);
1001 :
1002 : /* write start bit (1) */
1003 0 : RT2661_EEPROM_CTL(sc, RT2661_S | RT2661_D);
1004 0 : RT2661_EEPROM_CTL(sc, RT2661_S | RT2661_D | RT2661_C);
1005 :
1006 : /* write READ opcode (10) */
1007 0 : RT2661_EEPROM_CTL(sc, RT2661_S | RT2661_D);
1008 0 : RT2661_EEPROM_CTL(sc, RT2661_S | RT2661_D | RT2661_C);
1009 0 : RT2661_EEPROM_CTL(sc, RT2661_S);
1010 0 : RT2661_EEPROM_CTL(sc, RT2661_S | RT2661_C);
1011 :
1012 : /* write address (A5-A0 or A7-A0) */
1013 0 : n = (RAL_READ(sc, RT2661_E2PROM_CSR) & RT2661_93C46) ? 5 : 7;
1014 0 : for (; n >= 0; n--) {
1015 0 : RT2661_EEPROM_CTL(sc, RT2661_S |
1016 : (((addr >> n) & 1) << RT2661_SHIFT_D));
1017 0 : RT2661_EEPROM_CTL(sc, RT2661_S |
1018 : (((addr >> n) & 1) << RT2661_SHIFT_D) | RT2661_C);
1019 : }
1020 :
1021 0 : RT2661_EEPROM_CTL(sc, RT2661_S);
1022 :
1023 : /* read data Q15-Q0 */
1024 : val = 0;
1025 0 : for (n = 15; n >= 0; n--) {
1026 0 : RT2661_EEPROM_CTL(sc, RT2661_S | RT2661_C);
1027 0 : tmp = RAL_READ(sc, RT2661_E2PROM_CSR);
1028 0 : val |= ((tmp & RT2661_Q) >> RT2661_SHIFT_Q) << n;
1029 0 : RT2661_EEPROM_CTL(sc, RT2661_S);
1030 : }
1031 :
1032 0 : RT2661_EEPROM_CTL(sc, 0);
1033 :
1034 : /* clear Chip Select and clock C */
1035 0 : RT2661_EEPROM_CTL(sc, RT2661_S);
1036 0 : RT2661_EEPROM_CTL(sc, 0);
1037 0 : RT2661_EEPROM_CTL(sc, RT2661_C);
1038 :
1039 0 : return val;
1040 : }
1041 :
1042 : /* The TX interrupt handler accumulates statistics based on whether frames
1043 : * were sent successfully by the ASIC. */
1044 : void
1045 0 : rt2661_tx_intr(struct rt2661_softc *sc)
1046 : {
1047 0 : struct ieee80211com *ic = &sc->sc_ic;
1048 0 : struct ifnet *ifp = &ic->ic_if;
1049 : struct rt2661_amrr_node *amn;
1050 : int retrycnt;
1051 : u_int8_t amrr_id;
1052 :
1053 0 : for (;;) {
1054 0 : const uint32_t val = RAL_READ(sc, RT2661_STA_CSR4);
1055 0 : if (!(val & RT2661_TX_STAT_VALID))
1056 0 : break;
1057 :
1058 : /* retrieve rate control algorithm context */
1059 0 : amrr_id = RT2661_TX_PRIV_DATA(val);
1060 0 : amn = rt2661_amrr_node_find(sc, amrr_id);
1061 :
1062 0 : switch (RT2661_TX_RESULT(val)) {
1063 : case RT2661_TX_SUCCESS:
1064 0 : retrycnt = RT2661_TX_RETRYCNT(val);
1065 :
1066 : DPRINTFN(10, ("data frame sent successfully after "
1067 : "%d retries\n", retrycnt));
1068 0 : if (amn) {
1069 0 : amn->amn.amn_txcnt++;
1070 0 : if (retrycnt > 0)
1071 0 : amn->amn.amn_retrycnt++;
1072 : }
1073 : break;
1074 :
1075 : case RT2661_TX_RETRY_FAIL:
1076 : DPRINTFN(9, ("sending data frame failed (too much "
1077 : "retries)\n"));
1078 0 : if (amn) {
1079 0 : amn->amn.amn_txcnt++;
1080 0 : amn->amn.amn_retrycnt++;
1081 0 : }
1082 0 : ifp->if_oerrors++;
1083 0 : break;
1084 :
1085 : default:
1086 : /* other failure */
1087 0 : printf("%s: sending data frame failed 0x%08x\n",
1088 0 : sc->sc_dev.dv_xname, val);
1089 0 : ifp->if_oerrors++;
1090 0 : }
1091 :
1092 : DPRINTFN(15, ("tx done amrr_id=%hhu amn=0x%x\n", amrr_id, amn));
1093 0 : }
1094 0 : }
1095 :
1096 : /* The TX DMA interrupt handler processes frames which have been offloaded
1097 : * to the ASIC for transmission. We can free all resources corresponding
1098 : * to the frame here. */
1099 : void
1100 0 : rt2661_tx_dma_intr(struct rt2661_softc *sc, struct rt2661_tx_ring *txq)
1101 : {
1102 0 : struct ieee80211com *ic = &sc->sc_ic;
1103 0 : struct ifnet *ifp = &ic->ic_if;
1104 :
1105 0 : for (;;) {
1106 0 : struct rt2661_tx_desc *desc = &txq->desc[txq->next];
1107 0 : struct rt2661_tx_data *data = &txq->data[txq->next];
1108 :
1109 0 : bus_dmamap_sync(sc->sc_dmat, txq->map,
1110 : txq->next * RT2661_TX_DESC_SIZE, RT2661_TX_DESC_SIZE,
1111 : BUS_DMASYNC_POSTREAD);
1112 :
1113 0 : if ((letoh32(desc->flags) & RT2661_TX_BUSY) ||
1114 0 : !(letoh32(desc->flags) & RT2661_TX_VALID))
1115 0 : break;
1116 :
1117 : /* descriptor is no longer valid */
1118 0 : desc->flags &= ~htole32(RT2661_TX_VALID);
1119 :
1120 0 : bus_dmamap_sync(sc->sc_dmat, txq->map,
1121 : txq->next * RT2661_TX_DESC_SIZE, RT2661_TX_DESC_SIZE,
1122 : BUS_DMASYNC_PREWRITE);
1123 :
1124 0 : bus_dmamap_sync(sc->sc_dmat, data->map, 0,
1125 : data->map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
1126 0 : bus_dmamap_unload(sc->sc_dmat, data->map);
1127 0 : m_freem(data->m);
1128 0 : data->m = NULL;
1129 0 : ieee80211_release_node(ic, data->ni);
1130 0 : data->ni = NULL;
1131 :
1132 : DPRINTFN(15, ("tx dma done q=%p idx=%u\n", txq, txq->next));
1133 :
1134 0 : txq->queued--;
1135 0 : if (++txq->next >= txq->count) /* faster than % count */
1136 0 : txq->next = 0;
1137 0 : }
1138 :
1139 0 : if (sc->mgtq.queued == 0 && sc->txq[0].queued == 0)
1140 0 : sc->sc_tx_timer = 0;
1141 0 : if (sc->mgtq.queued < RT2661_MGT_RING_COUNT &&
1142 0 : sc->txq[0].queued < RT2661_TX_RING_COUNT - 1) {
1143 0 : if (sc->mgtq.queued < RT2661_MGT_RING_COUNT)
1144 0 : sc->sc_flags &= ~RT2661_MGT_OACTIVE;
1145 0 : if (sc->txq[0].queued < RT2661_TX_RING_COUNT - 1)
1146 0 : sc->sc_flags &= ~RT2661_DATA_OACTIVE;
1147 0 : if (!(sc->sc_flags & (RT2661_MGT_OACTIVE|RT2661_DATA_OACTIVE)))
1148 0 : ifq_clr_oactive(&ifp->if_snd);
1149 0 : rt2661_start(ifp);
1150 0 : }
1151 0 : }
1152 :
1153 : void
1154 0 : rt2661_rx_intr(struct rt2661_softc *sc)
1155 : {
1156 0 : struct ieee80211com *ic = &sc->sc_ic;
1157 0 : struct ifnet *ifp = &ic->ic_if;
1158 : struct ieee80211_frame *wh;
1159 0 : struct ieee80211_rxinfo rxi;
1160 : struct ieee80211_node *ni;
1161 : struct mbuf *mnew, *m;
1162 : int error, rssi;
1163 :
1164 0 : for (;;) {
1165 0 : struct rt2661_rx_desc *desc = &sc->rxq.desc[sc->rxq.cur];
1166 0 : struct rt2661_rx_data *data = &sc->rxq.data[sc->rxq.cur];
1167 :
1168 0 : bus_dmamap_sync(sc->sc_dmat, sc->rxq.map,
1169 : sc->rxq.cur * RT2661_RX_DESC_SIZE, RT2661_RX_DESC_SIZE,
1170 : BUS_DMASYNC_POSTREAD);
1171 :
1172 0 : if (letoh32(desc->flags) & RT2661_RX_BUSY)
1173 0 : break;
1174 :
1175 0 : if ((letoh32(desc->flags) & RT2661_RX_PHY_ERROR) ||
1176 0 : (letoh32(desc->flags) & RT2661_RX_CRC_ERROR)) {
1177 : /*
1178 : * This should not happen since we did not request
1179 : * to receive those frames when we filled TXRX_CSR0.
1180 : */
1181 : DPRINTFN(5, ("PHY or CRC error flags 0x%08x\n",
1182 : letoh32(desc->flags)));
1183 0 : ifp->if_ierrors++;
1184 0 : goto skip;
1185 : }
1186 :
1187 0 : if ((letoh32(desc->flags) & RT2661_RX_CIPHER_MASK) != 0) {
1188 0 : ifp->if_ierrors++;
1189 0 : goto skip;
1190 : }
1191 :
1192 : /*
1193 : * Try to allocate a new mbuf for this ring element and load it
1194 : * before processing the current mbuf. If the ring element
1195 : * cannot be loaded, drop the received packet and reuse the old
1196 : * mbuf. In the unlikely case that the old mbuf can't be
1197 : * reloaded either, explicitly panic.
1198 : */
1199 0 : MGETHDR(mnew, M_DONTWAIT, MT_DATA);
1200 0 : if (mnew == NULL) {
1201 0 : ifp->if_ierrors++;
1202 0 : goto skip;
1203 : }
1204 0 : MCLGET(mnew, M_DONTWAIT);
1205 0 : if (!(mnew->m_flags & M_EXT)) {
1206 0 : m_freem(mnew);
1207 0 : ifp->if_ierrors++;
1208 0 : goto skip;
1209 : }
1210 :
1211 0 : bus_dmamap_sync(sc->sc_dmat, data->map, 0,
1212 : data->map->dm_mapsize, BUS_DMASYNC_POSTREAD);
1213 0 : bus_dmamap_unload(sc->sc_dmat, data->map);
1214 :
1215 0 : error = bus_dmamap_load(sc->sc_dmat, data->map,
1216 : mtod(mnew, void *), MCLBYTES, NULL, BUS_DMA_NOWAIT);
1217 0 : if (error != 0) {
1218 0 : m_freem(mnew);
1219 :
1220 : /* try to reload the old mbuf */
1221 0 : error = bus_dmamap_load(sc->sc_dmat, data->map,
1222 : mtod(data->m, void *), MCLBYTES, NULL,
1223 : BUS_DMA_NOWAIT);
1224 0 : if (error != 0) {
1225 : /* very unlikely that it will fail... */
1226 0 : panic("%s: could not load old rx mbuf",
1227 0 : sc->sc_dev.dv_xname);
1228 : }
1229 : /* physical address may have changed */
1230 0 : desc->physaddr = htole32(data->map->dm_segs->ds_addr);
1231 0 : ifp->if_ierrors++;
1232 0 : goto skip;
1233 : }
1234 :
1235 : /*
1236 : * New mbuf successfully loaded, update Rx ring and continue
1237 : * processing.
1238 : */
1239 0 : m = data->m;
1240 0 : data->m = mnew;
1241 0 : desc->physaddr = htole32(data->map->dm_segs->ds_addr);
1242 :
1243 : /* finalize mbuf */
1244 0 : m->m_pkthdr.len = m->m_len =
1245 0 : (letoh32(desc->flags) >> 16) & 0xfff;
1246 :
1247 : #if NBPFILTER > 0
1248 0 : if (sc->sc_drvbpf != NULL) {
1249 0 : struct mbuf mb;
1250 0 : struct rt2661_rx_radiotap_header *tap = &sc->sc_rxtap;
1251 : uint32_t tsf_lo, tsf_hi;
1252 :
1253 : /* get timestamp (low and high 32 bits) */
1254 0 : tsf_hi = RAL_READ(sc, RT2661_TXRX_CSR13);
1255 0 : tsf_lo = RAL_READ(sc, RT2661_TXRX_CSR12);
1256 :
1257 0 : tap->wr_tsf =
1258 0 : htole64(((uint64_t)tsf_hi << 32) | tsf_lo);
1259 0 : tap->wr_flags = 0;
1260 0 : tap->wr_rate = rt2661_rxrate(desc);
1261 0 : tap->wr_chan_freq = htole16(sc->sc_curchan->ic_freq);
1262 0 : tap->wr_chan_flags = htole16(sc->sc_curchan->ic_flags);
1263 0 : tap->wr_antsignal = desc->rssi;
1264 :
1265 0 : mb.m_data = (caddr_t)tap;
1266 0 : mb.m_len = sc->sc_rxtap_len;
1267 0 : mb.m_next = m;
1268 0 : mb.m_nextpkt = NULL;
1269 0 : mb.m_type = 0;
1270 0 : mb.m_flags = 0;
1271 0 : bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_IN);
1272 0 : }
1273 : #endif
1274 :
1275 0 : wh = mtod(m, struct ieee80211_frame *);
1276 0 : ni = ieee80211_find_rxnode(ic, wh);
1277 :
1278 : /* send the frame to the 802.11 layer */
1279 0 : rxi.rxi_flags = 0;
1280 0 : rxi.rxi_rssi = desc->rssi;
1281 0 : rxi.rxi_tstamp = 0; /* unused */
1282 0 : ieee80211_input(ifp, m, ni, &rxi);
1283 :
1284 : /*-
1285 : * Keep track of the average RSSI using an Exponential Moving
1286 : * Average (EMA) of 8 Wilder's days:
1287 : * avg = (1 / N) x rssi + ((N - 1) / N) x avg
1288 : */
1289 0 : rssi = rt2661_get_rssi(sc, desc->rssi);
1290 0 : sc->avg_rssi = (rssi + 7 * sc->avg_rssi) / 8;
1291 :
1292 : /* node is no longer needed */
1293 0 : ieee80211_release_node(ic, ni);
1294 :
1295 0 : skip: desc->flags |= htole32(RT2661_RX_BUSY);
1296 :
1297 0 : bus_dmamap_sync(sc->sc_dmat, sc->rxq.map,
1298 : sc->rxq.cur * RT2661_RX_DESC_SIZE, RT2661_RX_DESC_SIZE,
1299 : BUS_DMASYNC_PREWRITE);
1300 :
1301 : DPRINTFN(15, ("rx intr idx=%u\n", sc->rxq.cur));
1302 :
1303 0 : sc->rxq.cur = (sc->rxq.cur + 1) % RT2661_RX_RING_COUNT;
1304 0 : }
1305 0 : }
1306 :
1307 : #ifndef IEEE80211_STA_ONLY
1308 : /*
1309 : * This function is called in HostAP or IBSS modes when it's time to send a
1310 : * new beacon (every ni_intval milliseconds).
1311 : */
1312 : void
1313 0 : rt2661_mcu_beacon_expire(struct rt2661_softc *sc)
1314 : {
1315 0 : struct ieee80211com *ic = &sc->sc_ic;
1316 :
1317 0 : if (sc->sc_flags & RT2661_UPDATE_SLOT) {
1318 0 : sc->sc_flags &= ~RT2661_UPDATE_SLOT;
1319 0 : sc->sc_flags |= RT2661_SET_SLOTTIME;
1320 0 : } else if (sc->sc_flags & RT2661_SET_SLOTTIME) {
1321 0 : sc->sc_flags &= ~RT2661_SET_SLOTTIME;
1322 0 : rt2661_set_slottime(sc);
1323 0 : }
1324 :
1325 0 : if (ic->ic_curmode == IEEE80211_MODE_11G) {
1326 : /* update ERP Information Element */
1327 0 : RAL_WRITE_1(sc, sc->erp_csr, ic->ic_bss->ni_erp);
1328 0 : RAL_RW_BARRIER_1(sc, sc->erp_csr);
1329 0 : }
1330 :
1331 : DPRINTFN(15, ("beacon expired\n"));
1332 0 : }
1333 : #endif
1334 :
1335 : void
1336 0 : rt2661_mcu_wakeup(struct rt2661_softc *sc)
1337 : {
1338 0 : RAL_WRITE(sc, RT2661_MAC_CSR11, 5 << 16);
1339 :
1340 0 : RAL_WRITE(sc, RT2661_SOFT_RESET_CSR, 0x7);
1341 0 : RAL_WRITE(sc, RT2661_IO_CNTL_CSR, 0x18);
1342 0 : RAL_WRITE(sc, RT2661_PCI_USEC_CSR, 0x20);
1343 :
1344 : /* send wakeup command to MCU */
1345 0 : rt2661_tx_cmd(sc, RT2661_MCU_CMD_WAKEUP, 0);
1346 0 : }
1347 :
1348 : void
1349 0 : rt2661_mcu_cmd_intr(struct rt2661_softc *sc)
1350 : {
1351 0 : RAL_READ(sc, RT2661_M2H_CMD_DONE_CSR);
1352 0 : RAL_WRITE(sc, RT2661_M2H_CMD_DONE_CSR, 0xffffffff);
1353 0 : }
1354 :
1355 : int
1356 0 : rt2661_intr(void *arg)
1357 : {
1358 0 : struct rt2661_softc *sc = arg;
1359 0 : struct ifnet *ifp = &sc->sc_ic.ic_if;
1360 : uint32_t r1, r2;
1361 :
1362 0 : r1 = RAL_READ(sc, RT2661_INT_SOURCE_CSR);
1363 0 : r2 = RAL_READ(sc, RT2661_MCU_INT_SOURCE_CSR);
1364 0 : if (__predict_false(r1 == 0xffffffff && r2 == 0xffffffff))
1365 0 : return 0; /* device likely went away */
1366 0 : if (r1 == 0 && r2 == 0)
1367 0 : return 0; /* not for us */
1368 :
1369 : /* disable MAC and MCU interrupts */
1370 0 : RAL_WRITE(sc, RT2661_INT_MASK_CSR, 0xffffff7f);
1371 0 : RAL_WRITE(sc, RT2661_MCU_INT_MASK_CSR, 0xffffffff);
1372 :
1373 : /* acknowledge interrupts */
1374 0 : RAL_WRITE(sc, RT2661_INT_SOURCE_CSR, r1);
1375 0 : RAL_WRITE(sc, RT2661_MCU_INT_SOURCE_CSR, r2);
1376 :
1377 : /* don't re-enable interrupts if we're shutting down */
1378 0 : if (!(ifp->if_flags & IFF_RUNNING))
1379 0 : return 0;
1380 :
1381 0 : if (r1 & RT2661_MGT_DONE)
1382 0 : rt2661_tx_dma_intr(sc, &sc->mgtq);
1383 :
1384 0 : if (r1 & RT2661_RX_DONE)
1385 0 : rt2661_rx_intr(sc);
1386 :
1387 0 : if (r1 & RT2661_TX0_DMA_DONE)
1388 0 : rt2661_tx_dma_intr(sc, &sc->txq[0]);
1389 :
1390 0 : if (r1 & RT2661_TX1_DMA_DONE)
1391 0 : rt2661_tx_dma_intr(sc, &sc->txq[1]);
1392 :
1393 0 : if (r1 & RT2661_TX2_DMA_DONE)
1394 0 : rt2661_tx_dma_intr(sc, &sc->txq[2]);
1395 :
1396 0 : if (r1 & RT2661_TX3_DMA_DONE)
1397 0 : rt2661_tx_dma_intr(sc, &sc->txq[3]);
1398 :
1399 0 : if (r1 & RT2661_TX_DONE)
1400 0 : rt2661_tx_intr(sc);
1401 :
1402 0 : if (r2 & RT2661_MCU_CMD_DONE)
1403 0 : rt2661_mcu_cmd_intr(sc);
1404 :
1405 : #ifndef IEEE80211_STA_ONLY
1406 0 : if (r2 & RT2661_MCU_BEACON_EXPIRE)
1407 0 : rt2661_mcu_beacon_expire(sc);
1408 : #endif
1409 :
1410 0 : if (r2 & RT2661_MCU_WAKEUP)
1411 0 : rt2661_mcu_wakeup(sc);
1412 :
1413 : /* re-enable MAC and MCU interrupts */
1414 0 : RAL_WRITE(sc, RT2661_INT_MASK_CSR, 0x0000ff10);
1415 0 : RAL_WRITE(sc, RT2661_MCU_INT_MASK_CSR, 0);
1416 :
1417 0 : return 1;
1418 0 : }
1419 :
1420 : /* quickly determine if a given rate is CCK or OFDM */
1421 : #define RAL_RATE_IS_OFDM(rate) ((rate) >= 12 && (rate) != 22)
1422 :
1423 : #define RAL_ACK_SIZE 14 /* 10 + 4(FCS) */
1424 : #define RAL_CTS_SIZE 14 /* 10 + 4(FCS) */
1425 :
1426 : /*
1427 : * This function is only used by the Rx radiotap code. It returns the rate at
1428 : * which a given frame was received.
1429 : */
1430 : #if NBPFILTER > 0
1431 : uint8_t
1432 0 : rt2661_rxrate(const struct rt2661_rx_desc *desc)
1433 : {
1434 0 : if (letoh32(desc->flags) & RT2661_RX_OFDM) {
1435 : /* reverse function of rt2661_plcp_signal */
1436 0 : switch (desc->rate & 0xf) {
1437 0 : case 0xb: return 12;
1438 0 : case 0xf: return 18;
1439 0 : case 0xa: return 24;
1440 0 : case 0xe: return 36;
1441 0 : case 0x9: return 48;
1442 0 : case 0xd: return 72;
1443 0 : case 0x8: return 96;
1444 0 : case 0xc: return 108;
1445 : }
1446 : } else {
1447 0 : if (desc->rate == 10)
1448 0 : return 2;
1449 0 : if (desc->rate == 20)
1450 0 : return 4;
1451 0 : if (desc->rate == 55)
1452 0 : return 11;
1453 0 : if (desc->rate == 110)
1454 0 : return 22;
1455 : }
1456 0 : return 2; /* should not get there */
1457 0 : }
1458 : #endif
1459 :
1460 : /*
1461 : * Return the expected ack rate for a frame transmitted at rate `rate'.
1462 : */
1463 : int
1464 0 : rt2661_ack_rate(struct ieee80211com *ic, int rate)
1465 : {
1466 0 : switch (rate) {
1467 : /* CCK rates */
1468 : case 2:
1469 0 : return 2;
1470 : case 4:
1471 : case 11:
1472 : case 22:
1473 0 : return (ic->ic_curmode == IEEE80211_MODE_11B) ? 4 : rate;
1474 :
1475 : /* OFDM rates */
1476 : case 12:
1477 : case 18:
1478 0 : return 12;
1479 : case 24:
1480 : case 36:
1481 0 : return 24;
1482 : case 48:
1483 : case 72:
1484 : case 96:
1485 : case 108:
1486 0 : return 48;
1487 : }
1488 :
1489 : /* default to 1Mbps */
1490 0 : return 2;
1491 0 : }
1492 :
1493 : /*
1494 : * Compute the duration (in us) needed to transmit `len' bytes at rate `rate'.
1495 : * The function automatically determines the operating mode depending on the
1496 : * given rate. `flags' indicates whether short preamble is in use or not.
1497 : */
1498 : uint16_t
1499 0 : rt2661_txtime(int len, int rate, uint32_t flags)
1500 : {
1501 : uint16_t txtime;
1502 :
1503 0 : if (RAL_RATE_IS_OFDM(rate)) {
1504 : /* IEEE Std 802.11g-2003, pp. 44 */
1505 0 : txtime = (8 + 4 * len + 3 + rate - 1) / rate;
1506 0 : txtime = 16 + 4 + 4 * txtime + 6;
1507 0 : } else {
1508 : /* IEEE Std 802.11b-1999, pp. 28 */
1509 0 : txtime = (16 * len + rate - 1) / rate;
1510 0 : if (rate != 2 && (flags & IEEE80211_F_SHPREAMBLE))
1511 0 : txtime += 72 + 24;
1512 : else
1513 0 : txtime += 144 + 48;
1514 : }
1515 0 : return txtime;
1516 : }
1517 :
1518 : uint8_t
1519 0 : rt2661_plcp_signal(int rate)
1520 : {
1521 0 : switch (rate) {
1522 : /* CCK rates (returned values are device-dependent) */
1523 0 : case 2: return 0x0;
1524 0 : case 4: return 0x1;
1525 0 : case 11: return 0x2;
1526 0 : case 22: return 0x3;
1527 :
1528 : /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
1529 0 : case 12: return 0xb;
1530 0 : case 18: return 0xf;
1531 0 : case 24: return 0xa;
1532 0 : case 36: return 0xe;
1533 0 : case 48: return 0x9;
1534 0 : case 72: return 0xd;
1535 0 : case 96: return 0x8;
1536 0 : case 108: return 0xc;
1537 :
1538 : /* unsupported rates (should not get there) */
1539 0 : default: return 0xff;
1540 : }
1541 0 : }
1542 :
1543 : void
1544 0 : rt2661_setup_tx_desc(struct rt2661_softc *sc, struct rt2661_tx_desc *desc,
1545 : uint32_t flags, uint16_t xflags, int len, int rate,
1546 : const bus_dma_segment_t *segs, int nsegs, int ac, u_int8_t amrr_id)
1547 : {
1548 0 : struct ieee80211com *ic = &sc->sc_ic;
1549 : uint16_t plcp_length;
1550 : int i, remainder;
1551 :
1552 0 : desc->flags = htole32(flags);
1553 0 : desc->flags |= htole32(len << 16);
1554 0 : desc->flags |= htole32(RT2661_TX_BUSY | RT2661_TX_VALID);
1555 :
1556 0 : desc->xflags = htole16(xflags);
1557 0 : desc->xflags |= htole16(nsegs << 13);
1558 :
1559 0 : desc->wme = htole16(
1560 : RT2661_QID(ac) |
1561 : RT2661_AIFSN(2) |
1562 : RT2661_LOGCWMIN(4) |
1563 : RT2661_LOGCWMAX(10));
1564 :
1565 : /*
1566 : * Remember the ID of the AMRR node to update when Tx completes.
1567 : * This field is driver private data only. It will be made available
1568 : * by the NIC in STA_CSR4 on Tx interrupts.
1569 : */
1570 0 : desc->priv_data = amrr_id;
1571 :
1572 : /* setup PLCP fields */
1573 0 : desc->plcp_signal = rt2661_plcp_signal(rate);
1574 0 : desc->plcp_service = 4;
1575 :
1576 0 : len += IEEE80211_CRC_LEN;
1577 0 : if (RAL_RATE_IS_OFDM(rate)) {
1578 0 : desc->flags |= htole32(RT2661_TX_OFDM);
1579 :
1580 0 : plcp_length = len & 0xfff;
1581 0 : desc->plcp_length_hi = plcp_length >> 6;
1582 0 : desc->plcp_length_lo = plcp_length & 0x3f;
1583 0 : } else {
1584 0 : plcp_length = (16 * len + rate - 1) / rate;
1585 0 : if (rate == 22) {
1586 0 : remainder = (16 * len) % 22;
1587 0 : if (remainder != 0 && remainder < 7)
1588 0 : desc->plcp_service |= RT2661_PLCP_LENGEXT;
1589 : }
1590 0 : desc->plcp_length_hi = plcp_length >> 8;
1591 0 : desc->plcp_length_lo = plcp_length & 0xff;
1592 :
1593 0 : if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
1594 0 : desc->plcp_signal |= 0x08;
1595 : }
1596 :
1597 : /* RT2x61 supports scatter with up to 5 segments */
1598 0 : for (i = 0; i < nsegs; i++) {
1599 0 : desc->addr[i] = htole32(segs[i].ds_addr);
1600 0 : desc->len [i] = htole16(segs[i].ds_len);
1601 : }
1602 0 : }
1603 :
1604 : int
1605 0 : rt2661_tx_mgt(struct rt2661_softc *sc, struct mbuf *m0,
1606 : struct ieee80211_node *ni)
1607 : {
1608 0 : struct ieee80211com *ic = &sc->sc_ic;
1609 : struct rt2661_tx_desc *desc;
1610 : struct rt2661_tx_data *data;
1611 : struct ieee80211_frame *wh;
1612 : uint16_t dur;
1613 : uint32_t flags = 0;
1614 : int rate, error;
1615 :
1616 0 : desc = &sc->mgtq.desc[sc->mgtq.cur];
1617 0 : data = &sc->mgtq.data[sc->mgtq.cur];
1618 :
1619 : /* send mgt frames at the lowest available rate */
1620 0 : rate = IEEE80211_IS_CHAN_5GHZ(ni->ni_chan) ? 12 : 2;
1621 :
1622 0 : error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m0,
1623 : BUS_DMA_NOWAIT);
1624 0 : if (error != 0) {
1625 0 : printf("%s: can't map mbuf (error %d)\n",
1626 0 : sc->sc_dev.dv_xname, error);
1627 0 : m_freem(m0);
1628 0 : return error;
1629 : }
1630 :
1631 : #if NBPFILTER > 0
1632 0 : if (sc->sc_drvbpf != NULL) {
1633 0 : struct mbuf mb;
1634 0 : struct rt2661_tx_radiotap_header *tap = &sc->sc_txtap;
1635 :
1636 0 : tap->wt_flags = 0;
1637 0 : tap->wt_rate = rate;
1638 0 : tap->wt_chan_freq = htole16(sc->sc_curchan->ic_freq);
1639 0 : tap->wt_chan_flags = htole16(sc->sc_curchan->ic_flags);
1640 :
1641 0 : mb.m_data = (caddr_t)tap;
1642 0 : mb.m_len = sc->sc_txtap_len;
1643 0 : mb.m_next = m0;
1644 0 : mb.m_nextpkt = NULL;
1645 0 : mb.m_type = 0;
1646 0 : mb.m_flags = 0;
1647 0 : bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_OUT);
1648 0 : }
1649 : #endif
1650 :
1651 0 : data->m = m0;
1652 0 : data->ni = ni;
1653 :
1654 0 : wh = mtod(m0, struct ieee80211_frame *);
1655 :
1656 0 : if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
1657 : flags |= RT2661_TX_NEED_ACK;
1658 :
1659 0 : dur = rt2661_txtime(RAL_ACK_SIZE, rate, ic->ic_flags) +
1660 0 : sc->sifs;
1661 0 : *(uint16_t *)wh->i_dur = htole16(dur);
1662 :
1663 : #ifndef IEEE80211_STA_ONLY
1664 : /* tell hardware to set timestamp in probe responses */
1665 0 : if ((wh->i_fc[0] &
1666 0 : (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==
1667 : (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_RESP))
1668 0 : flags |= RT2661_TX_TIMESTAMP;
1669 : #endif
1670 : }
1671 :
1672 0 : rt2661_setup_tx_desc(sc, desc, flags, 0 /* XXX HWSEQ */,
1673 0 : m0->m_pkthdr.len, rate, data->map->dm_segs, data->map->dm_nsegs,
1674 : RT2661_QID_MGT, RT2661_AMRR_INVALID_ID);
1675 :
1676 0 : bus_dmamap_sync(sc->sc_dmat, data->map, 0, data->map->dm_mapsize,
1677 : BUS_DMASYNC_PREWRITE);
1678 0 : bus_dmamap_sync(sc->sc_dmat, sc->mgtq.map,
1679 : sc->mgtq.cur * RT2661_TX_DESC_SIZE, RT2661_TX_DESC_SIZE,
1680 : BUS_DMASYNC_PREWRITE);
1681 :
1682 : DPRINTFN(10, ("sending mgt frame len=%u idx=%u rate=%u\n",
1683 : m0->m_pkthdr.len, sc->mgtq.cur, rate));
1684 :
1685 : /* kick mgt */
1686 0 : sc->mgtq.queued++;
1687 0 : sc->mgtq.cur = (sc->mgtq.cur + 1) % RT2661_MGT_RING_COUNT;
1688 0 : RAL_WRITE(sc, RT2661_TX_CNTL_CSR, RT2661_KICK_MGT);
1689 :
1690 0 : return 0;
1691 0 : }
1692 :
1693 : int
1694 0 : rt2661_tx_data(struct rt2661_softc *sc, struct mbuf *m0,
1695 : struct ieee80211_node *ni, int ac)
1696 : {
1697 0 : struct ieee80211com *ic = &sc->sc_ic;
1698 0 : struct rt2661_tx_ring *txq = &sc->txq[ac];
1699 : struct rt2661_node *rn;
1700 : struct rt2661_tx_desc *desc;
1701 : struct rt2661_tx_data *data;
1702 : struct ieee80211_frame *wh;
1703 : struct ieee80211_key *k;
1704 : struct mbuf *m1;
1705 : uint16_t dur;
1706 : uint32_t flags = 0;
1707 : int pktlen, rate, needcts = 0, needrts = 0, error;
1708 :
1709 0 : rn = ((ni == ic->ic_bss) ? NULL : (struct rt2661_node *)ni);
1710 0 : wh = mtod(m0, struct ieee80211_frame *);
1711 :
1712 0 : if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
1713 0 : k = ieee80211_get_txkey(ic, wh, ni);
1714 :
1715 0 : if ((m0 = ieee80211_encrypt(ic, m0, k)) == NULL)
1716 0 : return ENOBUFS;
1717 :
1718 : /* packet header may have moved, reset our local pointer */
1719 0 : wh = mtod(m0, struct ieee80211_frame *);
1720 0 : }
1721 :
1722 : /* compute actual packet length (including CRC and crypto overhead) */
1723 0 : pktlen = m0->m_pkthdr.len + IEEE80211_CRC_LEN;
1724 :
1725 : /* pickup a rate */
1726 0 : if (IEEE80211_IS_MULTICAST(wh->i_addr1)) {
1727 : /* multicast frames are sent at the lowest avail. rate */
1728 0 : rate = ni->ni_rates.rs_rates[0];
1729 0 : } else if (ic->ic_fixed_rate != -1) {
1730 0 : rate = ic->ic_sup_rates[ic->ic_curmode].
1731 0 : rs_rates[ic->ic_fixed_rate];
1732 0 : } else
1733 0 : rate = ni->ni_rates.rs_rates[ni->ni_txrate];
1734 0 : if (rate == 0)
1735 0 : rate = 2; /* XXX should not happen */
1736 0 : rate &= IEEE80211_RATE_VAL;
1737 :
1738 : /*
1739 : * Packet Bursting: backoff after ppb=8 frames to give other STAs a
1740 : * chance to contend for the wireless medium.
1741 : */
1742 0 : if (ic->ic_opmode == IEEE80211_M_STA && (ni->ni_txseq & 7))
1743 0 : flags |= RT2661_TX_IFS_SIFS;
1744 :
1745 : /* check if RTS/CTS or CTS-to-self protection must be used */
1746 0 : if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
1747 : /* multicast frames are not sent at OFDM rates in 802.11b/g */
1748 0 : if (pktlen > ic->ic_rtsthreshold) {
1749 : needrts = 1; /* RTS/CTS based on frame length */
1750 0 : } else if ((ic->ic_flags & IEEE80211_F_USEPROT) &&
1751 0 : RAL_RATE_IS_OFDM(rate)) {
1752 0 : if (ic->ic_protmode == IEEE80211_PROT_CTSONLY)
1753 0 : needcts = 1; /* CTS-to-self */
1754 0 : else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
1755 0 : needrts = 1; /* RTS/CTS */
1756 : }
1757 : }
1758 0 : if (needrts || needcts) {
1759 : struct mbuf *mprot;
1760 : int protrate, ackrate;
1761 :
1762 0 : protrate = IEEE80211_IS_CHAN_5GHZ(ni->ni_chan) ? 12 : 2;
1763 0 : ackrate = rt2661_ack_rate(ic, rate);
1764 :
1765 0 : dur = rt2661_txtime(pktlen, rate, ic->ic_flags) +
1766 0 : rt2661_txtime(RAL_ACK_SIZE, ackrate, ic->ic_flags) +
1767 0 : 2 * sc->sifs;
1768 0 : if (needrts) {
1769 0 : dur += rt2661_txtime(RAL_CTS_SIZE, rt2661_ack_rate(ic,
1770 0 : protrate), ic->ic_flags) + sc->sifs;
1771 0 : mprot = ieee80211_get_rts(ic, wh, dur);
1772 0 : } else {
1773 0 : mprot = ieee80211_get_cts_to_self(ic, dur);
1774 : }
1775 0 : if (mprot == NULL) {
1776 0 : printf("%s: could not allocate protection frame\n",
1777 0 : sc->sc_dev.dv_xname);
1778 0 : m_freem(m0);
1779 0 : return ENOBUFS;
1780 : }
1781 :
1782 0 : desc = &txq->desc[txq->cur];
1783 0 : data = &txq->data[txq->cur];
1784 :
1785 0 : error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, mprot,
1786 : BUS_DMA_NOWAIT);
1787 0 : if (error != 0) {
1788 0 : printf("%s: can't map mbuf (error %d)\n",
1789 0 : sc->sc_dev.dv_xname, error);
1790 0 : m_freem(mprot);
1791 0 : m_freem(m0);
1792 0 : return error;
1793 : }
1794 :
1795 0 : data->m = mprot;
1796 : /* avoid multiple free() of the same node for each fragment */
1797 0 : data->ni = ieee80211_ref_node(ni);
1798 :
1799 : /* XXX may want to pass the protection frame to BPF */
1800 :
1801 0 : rt2661_setup_tx_desc(sc, desc,
1802 0 : (needrts ? RT2661_TX_NEED_ACK : 0) | RT2661_TX_MORE_FRAG,
1803 0 : 0, mprot->m_pkthdr.len, protrate, data->map->dm_segs,
1804 0 : data->map->dm_nsegs, ac,
1805 0 : (rn && rn->amn) ? rn->amn->id : RT2661_AMRR_INVALID_ID);
1806 :
1807 0 : bus_dmamap_sync(sc->sc_dmat, data->map, 0,
1808 : data->map->dm_mapsize, BUS_DMASYNC_PREWRITE);
1809 0 : bus_dmamap_sync(sc->sc_dmat, txq->map,
1810 : txq->cur * RT2661_TX_DESC_SIZE, RT2661_TX_DESC_SIZE,
1811 : BUS_DMASYNC_PREWRITE);
1812 :
1813 0 : txq->queued++;
1814 0 : txq->cur = (txq->cur + 1) % RT2661_TX_RING_COUNT;
1815 :
1816 : flags |= RT2661_TX_LONG_RETRY | RT2661_TX_IFS_SIFS;
1817 0 : }
1818 :
1819 0 : data = &txq->data[txq->cur];
1820 0 : desc = &txq->desc[txq->cur];
1821 :
1822 0 : error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m0,
1823 : BUS_DMA_NOWAIT);
1824 0 : if (error != 0 && error != EFBIG) {
1825 0 : printf("%s: can't map mbuf (error %d)\n",
1826 0 : sc->sc_dev.dv_xname, error);
1827 0 : m_freem(m0);
1828 0 : return error;
1829 : }
1830 0 : if (error != 0) {
1831 : /* too many fragments, linearize */
1832 0 : MGETHDR(m1, M_DONTWAIT, MT_DATA);
1833 0 : if (m1 == NULL) {
1834 0 : m_freem(m0);
1835 0 : return ENOBUFS;
1836 : }
1837 0 : if (m0->m_pkthdr.len > MHLEN) {
1838 0 : MCLGET(m1, M_DONTWAIT);
1839 0 : if (!(m1->m_flags & M_EXT)) {
1840 0 : m_freem(m0);
1841 0 : m_freem(m1);
1842 0 : return ENOBUFS;
1843 : }
1844 : }
1845 0 : m_copydata(m0, 0, m0->m_pkthdr.len, mtod(m1, caddr_t));
1846 0 : m1->m_pkthdr.len = m1->m_len = m0->m_pkthdr.len;
1847 0 : m_freem(m0);
1848 : m0 = m1;
1849 :
1850 0 : error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m0,
1851 : BUS_DMA_NOWAIT);
1852 0 : if (error != 0) {
1853 0 : printf("%s: can't map mbuf (error %d)\n",
1854 0 : sc->sc_dev.dv_xname, error);
1855 0 : m_freem(m0);
1856 0 : return error;
1857 : }
1858 :
1859 : /* packet header have moved, reset our local pointer */
1860 0 : wh = mtod(m0, struct ieee80211_frame *);
1861 0 : }
1862 :
1863 : #if NBPFILTER > 0
1864 0 : if (sc->sc_drvbpf != NULL) {
1865 0 : struct mbuf mb;
1866 0 : struct rt2661_tx_radiotap_header *tap = &sc->sc_txtap;
1867 :
1868 0 : tap->wt_flags = 0;
1869 0 : tap->wt_rate = rate;
1870 0 : tap->wt_chan_freq = htole16(sc->sc_curchan->ic_freq);
1871 0 : tap->wt_chan_flags = htole16(sc->sc_curchan->ic_flags);
1872 :
1873 0 : mb.m_data = (caddr_t)tap;
1874 0 : mb.m_len = sc->sc_txtap_len;
1875 0 : mb.m_next = m0;
1876 0 : mb.m_nextpkt = NULL;
1877 0 : mb.m_type = 0;
1878 0 : mb.m_flags = 0;
1879 0 : bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_OUT);
1880 0 : }
1881 : #endif
1882 :
1883 0 : data->m = m0;
1884 0 : data->ni = ni;
1885 :
1886 0 : if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
1887 0 : flags |= RT2661_TX_NEED_ACK;
1888 :
1889 0 : dur = rt2661_txtime(RAL_ACK_SIZE, rt2661_ack_rate(ic, rate),
1890 0 : ic->ic_flags) + sc->sifs;
1891 0 : *(uint16_t *)wh->i_dur = htole16(dur);
1892 0 : }
1893 :
1894 0 : rt2661_setup_tx_desc(sc, desc, flags, 0, m0->m_pkthdr.len, rate,
1895 0 : data->map->dm_segs, data->map->dm_nsegs, ac,
1896 0 : (rn && rn->amn) ? rn->amn->id : RT2661_AMRR_INVALID_ID);
1897 :
1898 0 : bus_dmamap_sync(sc->sc_dmat, data->map, 0, data->map->dm_mapsize,
1899 : BUS_DMASYNC_PREWRITE);
1900 0 : bus_dmamap_sync(sc->sc_dmat, txq->map, txq->cur * RT2661_TX_DESC_SIZE,
1901 : RT2661_TX_DESC_SIZE, BUS_DMASYNC_PREWRITE);
1902 :
1903 : DPRINTFN(10, ("sending data frame len=%u idx=%u rate=%u\n",
1904 : m0->m_pkthdr.len, txq->cur, rate));
1905 :
1906 : /* kick Tx */
1907 0 : txq->queued++;
1908 0 : txq->cur = (txq->cur + 1) % RT2661_TX_RING_COUNT;
1909 0 : RAL_WRITE(sc, RT2661_TX_CNTL_CSR, 1);
1910 :
1911 0 : return 0;
1912 0 : }
1913 :
1914 : void
1915 0 : rt2661_start(struct ifnet *ifp)
1916 : {
1917 0 : struct rt2661_softc *sc = ifp->if_softc;
1918 0 : struct ieee80211com *ic = &sc->sc_ic;
1919 : struct mbuf *m0;
1920 0 : struct ieee80211_node *ni;
1921 :
1922 : /*
1923 : * net80211 may still try to send management frames even if the
1924 : * IFF_RUNNING flag is not set...
1925 : */
1926 0 : if (!(ifp->if_flags & IFF_RUNNING) || ifq_is_oactive(&ifp->if_snd))
1927 0 : return;
1928 :
1929 0 : for (;;) {
1930 0 : if (mq_len(&ic->ic_mgtq) > 0) {
1931 0 : if (sc->mgtq.queued >= RT2661_MGT_RING_COUNT) {
1932 0 : ifq_set_oactive(&ifp->if_snd);
1933 0 : break;
1934 : }
1935 :
1936 0 : m0 = mq_dequeue(&ic->ic_mgtq);
1937 0 : if (m0 == NULL)
1938 0 : continue;
1939 0 : ni = m0->m_pkthdr.ph_cookie;
1940 : #if NBPFILTER > 0
1941 0 : if (ic->ic_rawbpf != NULL)
1942 0 : bpf_mtap(ic->ic_rawbpf, m0, BPF_DIRECTION_OUT);
1943 : #endif
1944 0 : if (rt2661_tx_mgt(sc, m0, ni) != 0)
1945 : break;
1946 :
1947 : } else {
1948 0 : if (sc->txq[0].queued >= RT2661_TX_RING_COUNT - 1) {
1949 0 : ifq_set_oactive(&ifp->if_snd);
1950 0 : break;
1951 : }
1952 :
1953 0 : if (ic->ic_state != IEEE80211_S_RUN)
1954 : break;
1955 :
1956 0 : IFQ_DEQUEUE(&ifp->if_snd, m0);
1957 0 : if (m0 == NULL)
1958 : break;
1959 : #if NBPFILTER > 0
1960 0 : if (ifp->if_bpf != NULL)
1961 0 : bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_OUT);
1962 : #endif
1963 0 : m0 = ieee80211_encap(ifp, m0, &ni);
1964 0 : if (m0 == NULL)
1965 0 : continue;
1966 : #if NBPFILTER > 0
1967 0 : if (ic->ic_rawbpf != NULL)
1968 0 : bpf_mtap(ic->ic_rawbpf, m0,
1969 : BPF_DIRECTION_OUT);
1970 : #endif
1971 0 : if (rt2661_tx_data(sc, m0, ni, 0) != 0) {
1972 0 : if (ni != NULL)
1973 0 : ieee80211_release_node(ic, ni);
1974 0 : ifp->if_oerrors++;
1975 0 : break;
1976 : }
1977 : }
1978 :
1979 0 : sc->sc_tx_timer = 5;
1980 0 : ifp->if_timer = 1;
1981 : }
1982 0 : }
1983 :
1984 : void
1985 0 : rt2661_watchdog(struct ifnet *ifp)
1986 : {
1987 0 : struct rt2661_softc *sc = ifp->if_softc;
1988 :
1989 0 : ifp->if_timer = 0;
1990 :
1991 0 : if (sc->sc_tx_timer > 0) {
1992 0 : if (--sc->sc_tx_timer == 0) {
1993 0 : printf("%s: device timeout\n", sc->sc_dev.dv_xname);
1994 0 : rt2661_init(ifp);
1995 0 : ifp->if_oerrors++;
1996 0 : return;
1997 : }
1998 0 : ifp->if_timer = 1;
1999 0 : }
2000 :
2001 0 : ieee80211_watchdog(ifp);
2002 0 : }
2003 :
2004 : int
2005 0 : rt2661_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
2006 : {
2007 0 : struct rt2661_softc *sc = ifp->if_softc;
2008 0 : struct ieee80211com *ic = &sc->sc_ic;
2009 : int s, error = 0;
2010 :
2011 0 : s = splnet();
2012 :
2013 0 : switch (cmd) {
2014 : case SIOCSIFADDR:
2015 0 : ifp->if_flags |= IFF_UP;
2016 : /* FALLTHROUGH */
2017 : case SIOCSIFFLAGS:
2018 0 : if (ifp->if_flags & IFF_UP) {
2019 0 : if (ifp->if_flags & IFF_RUNNING)
2020 0 : rt2661_update_promisc(sc);
2021 : else
2022 0 : rt2661_init(ifp);
2023 : } else {
2024 0 : if (ifp->if_flags & IFF_RUNNING)
2025 0 : rt2661_stop(ifp, 1);
2026 : }
2027 : break;
2028 :
2029 : case SIOCS80211CHANNEL:
2030 : /*
2031 : * This allows for fast channel switching in monitor mode
2032 : * (used by kismet). In IBSS mode, we must explicitly reset
2033 : * the interface to generate a new beacon frame.
2034 : */
2035 0 : error = ieee80211_ioctl(ifp, cmd, data);
2036 0 : if (error == ENETRESET &&
2037 0 : ic->ic_opmode == IEEE80211_M_MONITOR) {
2038 0 : if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
2039 : (IFF_UP | IFF_RUNNING))
2040 0 : rt2661_set_chan(sc, ic->ic_ibss_chan);
2041 : error = 0;
2042 0 : }
2043 : break;
2044 :
2045 : default:
2046 0 : error = ieee80211_ioctl(ifp, cmd, data);
2047 0 : }
2048 :
2049 0 : if (error == ENETRESET) {
2050 0 : if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
2051 : (IFF_UP | IFF_RUNNING))
2052 0 : rt2661_init(ifp);
2053 : error = 0;
2054 0 : }
2055 :
2056 0 : splx(s);
2057 :
2058 0 : return error;
2059 : }
2060 :
2061 : void
2062 0 : rt2661_bbp_write(struct rt2661_softc *sc, uint8_t reg, uint8_t val)
2063 : {
2064 : uint32_t tmp;
2065 : int ntries;
2066 :
2067 0 : for (ntries = 0; ntries < 100; ntries++) {
2068 0 : if (!(RAL_READ(sc, RT2661_PHY_CSR3) & RT2661_BBP_BUSY))
2069 : break;
2070 0 : DELAY(1);
2071 : }
2072 0 : if (ntries == 100) {
2073 0 : printf("%s: could not write to BBP\n", sc->sc_dev.dv_xname);
2074 0 : return;
2075 : }
2076 :
2077 0 : tmp = RT2661_BBP_BUSY | (reg & 0x7f) << 8 | val;
2078 0 : RAL_WRITE(sc, RT2661_PHY_CSR3, tmp);
2079 :
2080 : DPRINTFN(15, ("BBP R%u <- 0x%02x\n", reg, val));
2081 0 : }
2082 :
2083 : uint8_t
2084 0 : rt2661_bbp_read(struct rt2661_softc *sc, uint8_t reg)
2085 : {
2086 : uint32_t val;
2087 : int ntries;
2088 :
2089 0 : for (ntries = 0; ntries < 100; ntries++) {
2090 0 : if (!(RAL_READ(sc, RT2661_PHY_CSR3) & RT2661_BBP_BUSY))
2091 : break;
2092 0 : DELAY(1);
2093 : }
2094 0 : if (ntries == 100) {
2095 0 : printf("%s: could not read from BBP\n", sc->sc_dev.dv_xname);
2096 0 : return 0;
2097 : }
2098 :
2099 0 : val = RT2661_BBP_BUSY | RT2661_BBP_READ | reg << 8;
2100 0 : RAL_WRITE(sc, RT2661_PHY_CSR3, val);
2101 :
2102 0 : for (ntries = 0; ntries < 100; ntries++) {
2103 0 : val = RAL_READ(sc, RT2661_PHY_CSR3);
2104 0 : if (!(val & RT2661_BBP_BUSY))
2105 0 : return val & 0xff;
2106 0 : DELAY(1);
2107 : }
2108 :
2109 0 : printf("%s: could not read from BBP\n", sc->sc_dev.dv_xname);
2110 0 : return 0;
2111 0 : }
2112 :
2113 : void
2114 0 : rt2661_rf_write(struct rt2661_softc *sc, uint8_t reg, uint32_t val)
2115 : {
2116 : uint32_t tmp;
2117 : int ntries;
2118 :
2119 0 : for (ntries = 0; ntries < 100; ntries++) {
2120 0 : if (!(RAL_READ(sc, RT2661_PHY_CSR4) & RT2661_RF_BUSY))
2121 : break;
2122 0 : DELAY(1);
2123 : }
2124 0 : if (ntries == 100) {
2125 0 : printf("%s: could not write to RF\n", sc->sc_dev.dv_xname);
2126 0 : return;
2127 : }
2128 :
2129 0 : tmp = RT2661_RF_BUSY | RT2661_RF_21BIT | (val & 0x1fffff) << 2 |
2130 0 : (reg & 3);
2131 0 : RAL_WRITE(sc, RT2661_PHY_CSR4, tmp);
2132 :
2133 : /* remember last written value in sc */
2134 0 : sc->rf_regs[reg] = val;
2135 :
2136 : DPRINTFN(15, ("RF R[%u] <- 0x%05x\n", reg & 3, val & 0x1fffff));
2137 0 : }
2138 :
2139 : int
2140 0 : rt2661_tx_cmd(struct rt2661_softc *sc, uint8_t cmd, uint16_t arg)
2141 : {
2142 0 : if (RAL_READ(sc, RT2661_H2M_MAILBOX_CSR) & RT2661_H2M_BUSY)
2143 0 : return EIO; /* there is already a command pending */
2144 :
2145 0 : RAL_WRITE(sc, RT2661_H2M_MAILBOX_CSR,
2146 0 : RT2661_H2M_BUSY | RT2661_TOKEN_NO_INTR << 16 | arg);
2147 :
2148 0 : RAL_WRITE(sc, RT2661_HOST_CMD_CSR, RT2661_KICK_CMD | cmd);
2149 :
2150 0 : return 0;
2151 0 : }
2152 :
2153 : void
2154 0 : rt2661_select_antenna(struct rt2661_softc *sc)
2155 : {
2156 : uint8_t bbp4, bbp77;
2157 : uint32_t tmp;
2158 :
2159 0 : bbp4 = rt2661_bbp_read(sc, 4);
2160 0 : bbp77 = rt2661_bbp_read(sc, 77);
2161 :
2162 : /* TBD */
2163 :
2164 : /* make sure Rx is disabled before switching antenna */
2165 0 : tmp = RAL_READ(sc, RT2661_TXRX_CSR0);
2166 0 : RAL_WRITE(sc, RT2661_TXRX_CSR0, tmp | RT2661_DISABLE_RX);
2167 :
2168 0 : rt2661_bbp_write(sc, 4, bbp4);
2169 0 : rt2661_bbp_write(sc, 77, bbp77);
2170 :
2171 : /* restore Rx filter */
2172 0 : RAL_WRITE(sc, RT2661_TXRX_CSR0, tmp);
2173 0 : }
2174 :
2175 : /*
2176 : * Enable multi-rate retries for frames sent at OFDM rates.
2177 : * In 802.11b/g mode, allow fallback to CCK rates.
2178 : */
2179 : void
2180 0 : rt2661_enable_mrr(struct rt2661_softc *sc)
2181 : {
2182 0 : struct ieee80211com *ic = &sc->sc_ic;
2183 : uint32_t tmp;
2184 :
2185 0 : tmp = RAL_READ(sc, RT2661_TXRX_CSR4);
2186 :
2187 0 : tmp &= ~RT2661_MRR_CCK_FALLBACK;
2188 0 : if (!IEEE80211_IS_CHAN_5GHZ(ic->ic_bss->ni_chan))
2189 0 : tmp |= RT2661_MRR_CCK_FALLBACK;
2190 0 : tmp |= RT2661_MRR_ENABLED;
2191 :
2192 0 : RAL_WRITE(sc, RT2661_TXRX_CSR4, tmp);
2193 0 : }
2194 :
2195 : void
2196 0 : rt2661_set_txpreamble(struct rt2661_softc *sc)
2197 : {
2198 : uint32_t tmp;
2199 :
2200 0 : tmp = RAL_READ(sc, RT2661_TXRX_CSR4);
2201 :
2202 0 : tmp &= ~RT2661_SHORT_PREAMBLE;
2203 0 : if (sc->sc_ic.ic_flags & IEEE80211_F_SHPREAMBLE)
2204 0 : tmp |= RT2661_SHORT_PREAMBLE;
2205 :
2206 0 : RAL_WRITE(sc, RT2661_TXRX_CSR4, tmp);
2207 0 : }
2208 :
2209 : void
2210 0 : rt2661_set_basicrates(struct rt2661_softc *sc)
2211 : {
2212 0 : struct ieee80211com *ic = &sc->sc_ic;
2213 :
2214 : /* update basic rate set */
2215 0 : if (ic->ic_curmode == IEEE80211_MODE_11B) {
2216 : /* 11b basic rates: 1, 2Mbps */
2217 0 : RAL_WRITE(sc, RT2661_TXRX_CSR5, 0x3);
2218 0 : } else if (ic->ic_curmode == IEEE80211_MODE_11A) {
2219 : /* 11a basic rates: 6, 12, 24Mbps */
2220 0 : RAL_WRITE(sc, RT2661_TXRX_CSR5, 0x150);
2221 0 : } else {
2222 : /* 11b/g basic rates: 1, 2, 5.5, 11Mbps */
2223 0 : RAL_WRITE(sc, RT2661_TXRX_CSR5, 0xf);
2224 : }
2225 0 : }
2226 :
2227 : /*
2228 : * Reprogram MAC/BBP to switch to a new band. Values taken from the reference
2229 : * driver.
2230 : */
2231 : void
2232 0 : rt2661_select_band(struct rt2661_softc *sc, struct ieee80211_channel *c)
2233 : {
2234 : uint8_t bbp17, bbp35, bbp96, bbp97, bbp98, bbp104;
2235 : uint32_t tmp;
2236 :
2237 : /* update all BBP registers that depend on the band */
2238 : bbp17 = 0x20; bbp96 = 0x48; bbp104 = 0x2c;
2239 : bbp35 = 0x50; bbp97 = 0x48; bbp98 = 0x48;
2240 0 : if (IEEE80211_IS_CHAN_5GHZ(c)) {
2241 : bbp17 += 0x08; bbp96 += 0x10; bbp104 += 0x0c;
2242 : bbp35 += 0x10; bbp97 += 0x10; bbp98 += 0x10;
2243 0 : }
2244 0 : if ((IEEE80211_IS_CHAN_2GHZ(c) && sc->ext_2ghz_lna) ||
2245 0 : (IEEE80211_IS_CHAN_5GHZ(c) && sc->ext_5ghz_lna)) {
2246 0 : bbp17 += 0x10; bbp96 += 0x10; bbp104 += 0x10;
2247 0 : }
2248 :
2249 0 : sc->bbp17 = bbp17;
2250 0 : rt2661_bbp_write(sc, 17, bbp17);
2251 0 : rt2661_bbp_write(sc, 96, bbp96);
2252 0 : rt2661_bbp_write(sc, 104, bbp104);
2253 :
2254 0 : if ((IEEE80211_IS_CHAN_2GHZ(c) && sc->ext_2ghz_lna) ||
2255 0 : (IEEE80211_IS_CHAN_5GHZ(c) && sc->ext_5ghz_lna)) {
2256 0 : rt2661_bbp_write(sc, 75, 0x80);
2257 0 : rt2661_bbp_write(sc, 86, 0x80);
2258 0 : rt2661_bbp_write(sc, 88, 0x80);
2259 0 : }
2260 :
2261 0 : rt2661_bbp_write(sc, 35, bbp35);
2262 0 : rt2661_bbp_write(sc, 97, bbp97);
2263 0 : rt2661_bbp_write(sc, 98, bbp98);
2264 :
2265 0 : tmp = RAL_READ(sc, RT2661_PHY_CSR0);
2266 0 : tmp &= ~(RT2661_PA_PE_2GHZ | RT2661_PA_PE_5GHZ);
2267 0 : if (IEEE80211_IS_CHAN_2GHZ(c))
2268 0 : tmp |= RT2661_PA_PE_2GHZ;
2269 : else
2270 0 : tmp |= RT2661_PA_PE_5GHZ;
2271 0 : RAL_WRITE(sc, RT2661_PHY_CSR0, tmp);
2272 :
2273 : /* 802.11a uses a 16 microseconds short interframe space */
2274 0 : sc->sifs = IEEE80211_IS_CHAN_5GHZ(c) ? 16 : 10;
2275 0 : }
2276 :
2277 : void
2278 0 : rt2661_set_chan(struct rt2661_softc *sc, struct ieee80211_channel *c)
2279 : {
2280 0 : struct ieee80211com *ic = &sc->sc_ic;
2281 : const struct rfprog *rfprog;
2282 : uint8_t bbp3, bbp94 = RT2661_BBPR94_DEFAULT;
2283 : int8_t power;
2284 : u_int i, chan;
2285 :
2286 0 : chan = ieee80211_chan2ieee(ic, c);
2287 0 : if (chan == 0 || chan == IEEE80211_CHAN_ANY)
2288 0 : return;
2289 :
2290 : /* select the appropriate RF settings based on what EEPROM says */
2291 0 : rfprog = (sc->rfprog == 0) ? rt2661_rf5225_1 : rt2661_rf5225_2;
2292 :
2293 : /* find the settings for this channel (we know it exists) */
2294 0 : for (i = 0; rfprog[i].chan != chan; i++);
2295 :
2296 0 : power = sc->txpow[i];
2297 0 : if (power < 0) {
2298 0 : bbp94 += power;
2299 : power = 0;
2300 0 : } else if (power > 31) {
2301 0 : bbp94 += power - 31;
2302 : power = 31;
2303 0 : }
2304 :
2305 : /*
2306 : * If we are switching from the 2GHz band to the 5GHz band or
2307 : * vice-versa, BBP registers need to be reprogrammed.
2308 : */
2309 0 : if (c->ic_flags != sc->sc_curchan->ic_flags) {
2310 0 : rt2661_select_band(sc, c);
2311 0 : rt2661_select_antenna(sc);
2312 0 : }
2313 0 : sc->sc_curchan = c;
2314 :
2315 0 : rt2661_rf_write(sc, RAL_RF1, rfprog[i].r1);
2316 0 : rt2661_rf_write(sc, RAL_RF2, rfprog[i].r2);
2317 0 : rt2661_rf_write(sc, RAL_RF3, rfprog[i].r3 | power << 7);
2318 0 : rt2661_rf_write(sc, RAL_RF4, rfprog[i].r4 | sc->rffreq << 10);
2319 :
2320 0 : DELAY(200);
2321 :
2322 0 : rt2661_rf_write(sc, RAL_RF1, rfprog[i].r1);
2323 0 : rt2661_rf_write(sc, RAL_RF2, rfprog[i].r2);
2324 0 : rt2661_rf_write(sc, RAL_RF3, rfprog[i].r3 | power << 7 | 1);
2325 0 : rt2661_rf_write(sc, RAL_RF4, rfprog[i].r4 | sc->rffreq << 10);
2326 :
2327 0 : DELAY(200);
2328 :
2329 0 : rt2661_rf_write(sc, RAL_RF1, rfprog[i].r1);
2330 0 : rt2661_rf_write(sc, RAL_RF2, rfprog[i].r2);
2331 0 : rt2661_rf_write(sc, RAL_RF3, rfprog[i].r3 | power << 7);
2332 0 : rt2661_rf_write(sc, RAL_RF4, rfprog[i].r4 | sc->rffreq << 10);
2333 :
2334 : /* enable smart mode for MIMO-capable RFs */
2335 0 : bbp3 = rt2661_bbp_read(sc, 3);
2336 :
2337 0 : bbp3 &= ~RT2661_SMART_MODE;
2338 0 : if (sc->rf_rev == RT2661_RF_5325 || sc->rf_rev == RT2661_RF_2529)
2339 0 : bbp3 |= RT2661_SMART_MODE;
2340 :
2341 0 : rt2661_bbp_write(sc, 3, bbp3);
2342 :
2343 0 : if (bbp94 != RT2661_BBPR94_DEFAULT)
2344 0 : rt2661_bbp_write(sc, 94, bbp94);
2345 :
2346 : /* 5GHz radio needs a 1ms delay here */
2347 0 : if (IEEE80211_IS_CHAN_5GHZ(c))
2348 0 : DELAY(1000);
2349 0 : }
2350 :
2351 : void
2352 0 : rt2661_set_bssid(struct rt2661_softc *sc, const uint8_t *bssid)
2353 : {
2354 : uint32_t tmp;
2355 :
2356 0 : tmp = bssid[0] | bssid[1] << 8 | bssid[2] << 16 | bssid[3] << 24;
2357 0 : RAL_WRITE(sc, RT2661_MAC_CSR4, tmp);
2358 :
2359 0 : tmp = bssid[4] | bssid[5] << 8 | RT2661_ONE_BSSID << 16;
2360 0 : RAL_WRITE(sc, RT2661_MAC_CSR5, tmp);
2361 0 : }
2362 :
2363 : void
2364 0 : rt2661_set_macaddr(struct rt2661_softc *sc, const uint8_t *addr)
2365 : {
2366 : uint32_t tmp;
2367 :
2368 0 : tmp = addr[0] | addr[1] << 8 | addr[2] << 16 | addr[3] << 24;
2369 0 : RAL_WRITE(sc, RT2661_MAC_CSR2, tmp);
2370 :
2371 0 : tmp = addr[4] | addr[5] << 8 | 0xff << 16;
2372 0 : RAL_WRITE(sc, RT2661_MAC_CSR3, tmp);
2373 0 : }
2374 :
2375 : void
2376 0 : rt2661_update_promisc(struct rt2661_softc *sc)
2377 : {
2378 0 : struct ifnet *ifp = &sc->sc_ic.ic_if;
2379 : uint32_t tmp;
2380 :
2381 0 : tmp = RAL_READ(sc, RT2661_TXRX_CSR0);
2382 :
2383 0 : tmp &= ~RT2661_DROP_NOT_TO_ME;
2384 0 : if (!(ifp->if_flags & IFF_PROMISC))
2385 0 : tmp |= RT2661_DROP_NOT_TO_ME;
2386 :
2387 0 : RAL_WRITE(sc, RT2661_TXRX_CSR0, tmp);
2388 :
2389 : DPRINTF(("%s promiscuous mode\n", (ifp->if_flags & IFF_PROMISC) ?
2390 : "entering" : "leaving"));
2391 0 : }
2392 :
2393 : void
2394 0 : rt2661_updateslot(struct ieee80211com *ic)
2395 : {
2396 0 : struct rt2661_softc *sc = ic->ic_if.if_softc;
2397 :
2398 : #ifndef IEEE80211_STA_ONLY
2399 0 : if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
2400 : /*
2401 : * In HostAP mode, we defer setting of new slot time until
2402 : * updated ERP Information Element has propagated to all
2403 : * associated STAs.
2404 : */
2405 0 : sc->sc_flags |= RT2661_UPDATE_SLOT;
2406 0 : } else
2407 : #endif
2408 0 : rt2661_set_slottime(sc);
2409 0 : }
2410 :
2411 : void
2412 0 : rt2661_set_slottime(struct rt2661_softc *sc)
2413 : {
2414 0 : struct ieee80211com *ic = &sc->sc_ic;
2415 : uint8_t slottime;
2416 : uint32_t tmp;
2417 :
2418 0 : slottime = (ic->ic_flags & IEEE80211_F_SHSLOT) ?
2419 : IEEE80211_DUR_DS_SHSLOT: IEEE80211_DUR_DS_SLOT;
2420 :
2421 0 : tmp = RAL_READ(sc, RT2661_MAC_CSR9);
2422 0 : tmp = (tmp & ~0xff) | slottime;
2423 0 : RAL_WRITE(sc, RT2661_MAC_CSR9, tmp);
2424 :
2425 : DPRINTF(("setting slot time to %uus\n", slottime));
2426 0 : }
2427 :
2428 : const char *
2429 0 : rt2661_get_rf(int rev)
2430 : {
2431 0 : switch (rev) {
2432 0 : case RT2661_RF_5225: return "RT5225";
2433 0 : case RT2661_RF_5325: return "RT5325 (MIMO XR)";
2434 0 : case RT2661_RF_2527: return "RT2527";
2435 0 : case RT2661_RF_2529: return "RT2529 (MIMO XR)";
2436 0 : default: return "unknown";
2437 : }
2438 0 : }
2439 :
2440 : void
2441 0 : rt2661_read_eeprom(struct rt2661_softc *sc)
2442 : {
2443 0 : struct ieee80211com *ic = &sc->sc_ic;
2444 : uint16_t val;
2445 : int i;
2446 :
2447 : /* read MAC address */
2448 0 : val = rt2661_eeprom_read(sc, RT2661_EEPROM_MAC01);
2449 0 : ic->ic_myaddr[0] = val & 0xff;
2450 0 : ic->ic_myaddr[1] = val >> 8;
2451 :
2452 0 : val = rt2661_eeprom_read(sc, RT2661_EEPROM_MAC23);
2453 0 : ic->ic_myaddr[2] = val & 0xff;
2454 0 : ic->ic_myaddr[3] = val >> 8;
2455 :
2456 0 : val = rt2661_eeprom_read(sc, RT2661_EEPROM_MAC45);
2457 0 : ic->ic_myaddr[4] = val & 0xff;
2458 0 : ic->ic_myaddr[5] = val >> 8;
2459 :
2460 0 : val = rt2661_eeprom_read(sc, RT2661_EEPROM_ANTENNA);
2461 : /* XXX: test if different from 0xffff? */
2462 0 : sc->rf_rev = (val >> 11) & 0x1f;
2463 0 : sc->hw_radio = (val >> 10) & 0x1;
2464 0 : sc->rx_ant = (val >> 4) & 0x3;
2465 0 : sc->tx_ant = (val >> 2) & 0x3;
2466 0 : sc->nb_ant = val & 0x3;
2467 :
2468 : DPRINTF(("RF revision=%d\n", sc->rf_rev));
2469 :
2470 0 : val = rt2661_eeprom_read(sc, RT2661_EEPROM_CONFIG2);
2471 0 : sc->ext_5ghz_lna = (val >> 6) & 0x1;
2472 0 : sc->ext_2ghz_lna = (val >> 4) & 0x1;
2473 :
2474 : DPRINTF(("External 2GHz LNA=%d\nExternal 5GHz LNA=%d\n",
2475 : sc->ext_2ghz_lna, sc->ext_5ghz_lna));
2476 :
2477 0 : val = rt2661_eeprom_read(sc, RT2661_EEPROM_RSSI_2GHZ_OFFSET);
2478 0 : if ((val & 0xff) != 0xff)
2479 0 : sc->rssi_2ghz_corr = (int8_t)(val & 0xff); /* signed */
2480 :
2481 0 : val = rt2661_eeprom_read(sc, RT2661_EEPROM_RSSI_5GHZ_OFFSET);
2482 0 : if ((val & 0xff) != 0xff)
2483 0 : sc->rssi_5ghz_corr = (int8_t)(val & 0xff); /* signed */
2484 :
2485 : /* adjust RSSI correction for external low-noise amplifier */
2486 0 : if (sc->ext_2ghz_lna)
2487 0 : sc->rssi_2ghz_corr -= 14;
2488 0 : if (sc->ext_5ghz_lna)
2489 0 : sc->rssi_5ghz_corr -= 14;
2490 :
2491 : DPRINTF(("RSSI 2GHz corr=%d\nRSSI 5GHz corr=%d\n",
2492 : sc->rssi_2ghz_corr, sc->rssi_5ghz_corr));
2493 :
2494 0 : val = rt2661_eeprom_read(sc, RT2661_EEPROM_FREQ_OFFSET);
2495 0 : if ((val >> 8) != 0xff)
2496 0 : sc->rfprog = (val >> 8) & 0x3;
2497 0 : if ((val & 0xff) != 0xff)
2498 0 : sc->rffreq = val & 0xff;
2499 :
2500 : DPRINTF(("RF prog=%d\nRF freq=%d\n", sc->rfprog, sc->rffreq));
2501 :
2502 : /* read Tx power for all a/b/g channels */
2503 0 : for (i = 0; i < 19; i++) {
2504 0 : val = rt2661_eeprom_read(sc, RT2661_EEPROM_TXPOWER + i);
2505 0 : sc->txpow[i * 2] = (int8_t)(val >> 8); /* signed */
2506 : DPRINTF(("Channel=%d Tx power=%d\n",
2507 : rt2661_rf5225_1[i * 2].chan, sc->txpow[i * 2]));
2508 0 : sc->txpow[i * 2 + 1] = (int8_t)(val & 0xff); /* signed */
2509 : DPRINTF(("Channel=%d Tx power=%d\n",
2510 : rt2661_rf5225_1[i * 2 + 1].chan, sc->txpow[i * 2 + 1]));
2511 : }
2512 :
2513 : /* read vendor-specific BBP values */
2514 0 : for (i = 0; i < 16; i++) {
2515 0 : val = rt2661_eeprom_read(sc, RT2661_EEPROM_BBP_BASE + i);
2516 0 : if (val == 0 || val == 0xffff)
2517 : continue; /* skip invalid entries */
2518 0 : sc->bbp_prom[i].reg = val >> 8;
2519 0 : sc->bbp_prom[i].val = val & 0xff;
2520 : DPRINTF(("BBP R%d=%02x\n", sc->bbp_prom[i].reg,
2521 : sc->bbp_prom[i].val));
2522 0 : }
2523 0 : }
2524 :
2525 : int
2526 0 : rt2661_bbp_init(struct rt2661_softc *sc)
2527 : {
2528 : int i, ntries;
2529 :
2530 : /* wait for BBP to be ready */
2531 0 : for (ntries = 0; ntries < 100; ntries++) {
2532 0 : const uint8_t val = rt2661_bbp_read(sc, 0);
2533 0 : if (val != 0 && val != 0xff)
2534 0 : break;
2535 0 : DELAY(100);
2536 0 : }
2537 0 : if (ntries == 100) {
2538 0 : printf("%s: timeout waiting for BBP\n", sc->sc_dev.dv_xname);
2539 0 : return EIO;
2540 : }
2541 :
2542 : /* initialize BBP registers to default values */
2543 0 : for (i = 0; i < nitems(rt2661_def_bbp); i++) {
2544 0 : rt2661_bbp_write(sc, rt2661_def_bbp[i].reg,
2545 0 : rt2661_def_bbp[i].val);
2546 : }
2547 :
2548 : /* write vendor-specific BBP values (from EEPROM) */
2549 0 : for (i = 0; i < 16; i++) {
2550 0 : if (sc->bbp_prom[i].reg == 0)
2551 : continue;
2552 0 : rt2661_bbp_write(sc, sc->bbp_prom[i].reg, sc->bbp_prom[i].val);
2553 0 : }
2554 :
2555 0 : return 0;
2556 0 : }
2557 :
2558 : int
2559 0 : rt2661_init(struct ifnet *ifp)
2560 : {
2561 0 : struct rt2661_softc *sc = ifp->if_softc;
2562 0 : struct ieee80211com *ic = &sc->sc_ic;
2563 0 : uint32_t tmp, sta[3];
2564 : int i, ntries;
2565 :
2566 : /* for CardBus, power on the socket */
2567 0 : if (!(sc->sc_flags & RT2661_ENABLED)) {
2568 0 : if (sc->sc_enable != NULL && (*sc->sc_enable)(sc) != 0) {
2569 0 : printf("%s: could not enable device\n",
2570 0 : sc->sc_dev.dv_xname);
2571 0 : return EIO;
2572 : }
2573 0 : sc->sc_flags |= RT2661_ENABLED;
2574 0 : }
2575 :
2576 0 : rt2661_stop(ifp, 0);
2577 :
2578 0 : if (!(sc->sc_flags & RT2661_FWLOADED)) {
2579 0 : if (rt2661_load_microcode(sc) != 0) {
2580 0 : printf("%s: could not load 8051 microcode\n",
2581 0 : sc->sc_dev.dv_xname);
2582 0 : rt2661_stop(ifp, 1);
2583 0 : return EIO;
2584 : }
2585 0 : sc->sc_flags |= RT2661_FWLOADED;
2586 0 : }
2587 :
2588 : /* initialize Tx rings */
2589 0 : RAL_WRITE(sc, RT2661_AC1_BASE_CSR, sc->txq[1].physaddr);
2590 0 : RAL_WRITE(sc, RT2661_AC0_BASE_CSR, sc->txq[0].physaddr);
2591 0 : RAL_WRITE(sc, RT2661_AC2_BASE_CSR, sc->txq[2].physaddr);
2592 0 : RAL_WRITE(sc, RT2661_AC3_BASE_CSR, sc->txq[3].physaddr);
2593 :
2594 : /* initialize Mgt ring */
2595 0 : RAL_WRITE(sc, RT2661_MGT_BASE_CSR, sc->mgtq.physaddr);
2596 :
2597 : /* initialize Rx ring */
2598 0 : RAL_WRITE(sc, RT2661_RX_BASE_CSR, sc->rxq.physaddr);
2599 :
2600 : /* initialize Tx rings sizes */
2601 0 : RAL_WRITE(sc, RT2661_TX_RING_CSR0,
2602 : RT2661_TX_RING_COUNT << 24 |
2603 : RT2661_TX_RING_COUNT << 16 |
2604 : RT2661_TX_RING_COUNT << 8 |
2605 : RT2661_TX_RING_COUNT);
2606 :
2607 0 : RAL_WRITE(sc, RT2661_TX_RING_CSR1,
2608 : RT2661_TX_DESC_WSIZE << 16 |
2609 : RT2661_TX_RING_COUNT << 8 | /* XXX: HCCA ring unused */
2610 : RT2661_MGT_RING_COUNT);
2611 :
2612 : /* initialize Rx rings */
2613 0 : RAL_WRITE(sc, RT2661_RX_RING_CSR,
2614 : RT2661_RX_DESC_BACK << 16 |
2615 : RT2661_RX_DESC_WSIZE << 8 |
2616 : RT2661_RX_RING_COUNT);
2617 :
2618 : /* XXX: some magic here */
2619 0 : RAL_WRITE(sc, RT2661_TX_DMA_DST_CSR, 0xaa);
2620 :
2621 : /* load base addresses of all 5 Tx rings (4 data + 1 mgt) */
2622 0 : RAL_WRITE(sc, RT2661_LOAD_TX_RING_CSR, 0x1f);
2623 :
2624 : /* load base address of Rx ring */
2625 0 : RAL_WRITE(sc, RT2661_RX_CNTL_CSR, 2);
2626 :
2627 : /* initialize MAC registers to default values */
2628 0 : for (i = 0; i < nitems(rt2661_def_mac); i++)
2629 0 : RAL_WRITE(sc, rt2661_def_mac[i].reg, rt2661_def_mac[i].val);
2630 :
2631 0 : IEEE80211_ADDR_COPY(ic->ic_myaddr, LLADDR(ifp->if_sadl));
2632 0 : rt2661_set_macaddr(sc, ic->ic_myaddr);
2633 :
2634 : /* set host ready */
2635 0 : RAL_WRITE(sc, RT2661_MAC_CSR1, 3);
2636 0 : RAL_WRITE(sc, RT2661_MAC_CSR1, 0);
2637 :
2638 : /* wait for BBP/RF to wakeup */
2639 0 : for (ntries = 0; ntries < 1000; ntries++) {
2640 0 : if (RAL_READ(sc, RT2661_MAC_CSR12) & 8)
2641 : break;
2642 0 : DELAY(1000);
2643 : }
2644 0 : if (ntries == 1000) {
2645 0 : printf("timeout waiting for BBP/RF to wakeup\n");
2646 0 : rt2661_stop(ifp, 1);
2647 0 : return EIO;
2648 : }
2649 :
2650 0 : if (rt2661_bbp_init(sc) != 0) {
2651 0 : rt2661_stop(ifp, 1);
2652 0 : return EIO;
2653 : }
2654 :
2655 : /* select default channel */
2656 0 : sc->sc_curchan = ic->ic_bss->ni_chan = ic->ic_ibss_chan;
2657 0 : rt2661_select_band(sc, sc->sc_curchan);
2658 0 : rt2661_select_antenna(sc);
2659 0 : rt2661_set_chan(sc, sc->sc_curchan);
2660 :
2661 : /* update Rx filter */
2662 0 : tmp = RAL_READ(sc, RT2661_TXRX_CSR0) & 0xffff;
2663 :
2664 0 : tmp |= RT2661_DROP_PHY_ERROR | RT2661_DROP_CRC_ERROR;
2665 0 : if (ic->ic_opmode != IEEE80211_M_MONITOR) {
2666 0 : tmp |= RT2661_DROP_CTL | RT2661_DROP_VER_ERROR |
2667 : RT2661_DROP_ACKCTS;
2668 : #ifndef IEEE80211_STA_ONLY
2669 0 : if (ic->ic_opmode != IEEE80211_M_HOSTAP)
2670 : #endif
2671 0 : tmp |= RT2661_DROP_TODS;
2672 0 : if (!(ifp->if_flags & IFF_PROMISC))
2673 0 : tmp |= RT2661_DROP_NOT_TO_ME;
2674 : }
2675 :
2676 0 : RAL_WRITE(sc, RT2661_TXRX_CSR0, tmp);
2677 :
2678 : /* clear STA registers */
2679 0 : RAL_READ_REGION_4(sc, RT2661_STA_CSR0, sta, nitems(sta));
2680 :
2681 : /* initialize ASIC */
2682 0 : RAL_WRITE(sc, RT2661_MAC_CSR1, 4);
2683 :
2684 : /* clear any pending interrupt */
2685 0 : RAL_WRITE(sc, RT2661_INT_SOURCE_CSR, 0xffffffff);
2686 :
2687 : /* enable interrupts */
2688 0 : RAL_WRITE(sc, RT2661_INT_MASK_CSR, 0x0000ff10);
2689 0 : RAL_WRITE(sc, RT2661_MCU_INT_MASK_CSR, 0);
2690 :
2691 : /* kick Rx */
2692 0 : RAL_WRITE(sc, RT2661_RX_CNTL_CSR, 1);
2693 :
2694 0 : ifp->if_flags |= IFF_RUNNING;
2695 0 : ifq_clr_oactive(&ifp->if_snd);
2696 :
2697 0 : if (ic->ic_opmode != IEEE80211_M_MONITOR)
2698 0 : ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
2699 : else
2700 0 : ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
2701 :
2702 0 : return 0;
2703 0 : }
2704 :
2705 : void
2706 0 : rt2661_stop(struct ifnet *ifp, int disable)
2707 : {
2708 0 : struct rt2661_softc *sc = ifp->if_softc;
2709 0 : struct ieee80211com *ic = &sc->sc_ic;
2710 : uint32_t tmp;
2711 : int ac;
2712 :
2713 0 : sc->sc_tx_timer = 0;
2714 0 : ifp->if_timer = 0;
2715 0 : ifp->if_flags &= ~IFF_RUNNING;
2716 0 : ifq_clr_oactive(&ifp->if_snd);
2717 :
2718 0 : ieee80211_new_state(ic, IEEE80211_S_INIT, -1); /* free all nodes */
2719 0 : rt2661_amrr_node_free_all(sc);
2720 :
2721 : /* abort Tx (for all 5 Tx rings) */
2722 0 : RAL_WRITE(sc, RT2661_TX_CNTL_CSR, 0x1f << 16);
2723 :
2724 : /* disable Rx (value remains after reset!) */
2725 0 : tmp = RAL_READ(sc, RT2661_TXRX_CSR0);
2726 0 : RAL_WRITE(sc, RT2661_TXRX_CSR0, tmp | RT2661_DISABLE_RX);
2727 :
2728 : /* reset ASIC */
2729 0 : RAL_WRITE(sc, RT2661_MAC_CSR1, 3);
2730 0 : RAL_WRITE(sc, RT2661_MAC_CSR1, 0);
2731 :
2732 : /* disable interrupts */
2733 0 : RAL_WRITE(sc, RT2661_INT_MASK_CSR, 0xffffff7f);
2734 0 : RAL_WRITE(sc, RT2661_MCU_INT_MASK_CSR, 0xffffffff);
2735 :
2736 : /* clear any pending interrupt */
2737 0 : RAL_WRITE(sc, RT2661_INT_SOURCE_CSR, 0xffffffff);
2738 0 : RAL_WRITE(sc, RT2661_MCU_INT_SOURCE_CSR, 0xffffffff);
2739 :
2740 : /* reset Tx and Rx rings */
2741 0 : for (ac = 0; ac < 4; ac++)
2742 0 : rt2661_reset_tx_ring(sc, &sc->txq[ac]);
2743 0 : rt2661_reset_tx_ring(sc, &sc->mgtq);
2744 0 : rt2661_reset_rx_ring(sc, &sc->rxq);
2745 :
2746 : /* for CardBus, power down the socket */
2747 0 : if (disable && sc->sc_disable != NULL) {
2748 0 : if (sc->sc_flags & RT2661_ENABLED) {
2749 0 : (*sc->sc_disable)(sc);
2750 0 : sc->sc_flags &= ~(RT2661_ENABLED | RT2661_FWLOADED);
2751 0 : }
2752 : }
2753 0 : }
2754 :
2755 : int
2756 0 : rt2661_load_microcode(struct rt2661_softc *sc)
2757 : {
2758 : int ntries;
2759 :
2760 : /* reset 8051 */
2761 0 : RAL_WRITE(sc, RT2661_MCU_CNTL_CSR, RT2661_MCU_RESET);
2762 :
2763 : /* cancel any pending Host to MCU command */
2764 0 : RAL_WRITE(sc, RT2661_H2M_MAILBOX_CSR, 0);
2765 0 : RAL_WRITE(sc, RT2661_M2H_CMD_DONE_CSR, 0xffffffff);
2766 0 : RAL_WRITE(sc, RT2661_HOST_CMD_CSR, 0);
2767 :
2768 : /* write 8051's microcode */
2769 0 : RAL_WRITE(sc, RT2661_MCU_CNTL_CSR, RT2661_MCU_RESET | RT2661_MCU_SEL);
2770 0 : RAL_WRITE_REGION_1(sc, RT2661_MCU_CODE_BASE, sc->ucode, sc->ucsize);
2771 0 : RAL_WRITE(sc, RT2661_MCU_CNTL_CSR, RT2661_MCU_RESET);
2772 :
2773 : /* kick 8051's ass */
2774 0 : RAL_WRITE(sc, RT2661_MCU_CNTL_CSR, 0);
2775 :
2776 : /* wait for 8051 to initialize */
2777 0 : for (ntries = 0; ntries < 500; ntries++) {
2778 0 : if (RAL_READ(sc, RT2661_MCU_CNTL_CSR) & RT2661_MCU_READY)
2779 : break;
2780 0 : DELAY(100);
2781 : }
2782 0 : if (ntries == 500) {
2783 0 : printf("%s: timeout waiting for MCU to initialize\n",
2784 0 : sc->sc_dev.dv_xname);
2785 0 : return EIO;
2786 : }
2787 0 : return 0;
2788 0 : }
2789 :
2790 : /*
2791 : * Dynamically tune Rx sensitivity (BBP register 17) based on average RSSI and
2792 : * false CCA count. This function is called periodically (every seconds) when
2793 : * in the RUN state. Values taken from the reference driver.
2794 : */
2795 : void
2796 0 : rt2661_rx_tune(struct rt2661_softc *sc)
2797 : {
2798 : uint8_t bbp17;
2799 : uint16_t cca;
2800 : int lo, hi, dbm;
2801 :
2802 : /*
2803 : * Tuning range depends on operating band and on the presence of an
2804 : * external low-noise amplifier.
2805 : */
2806 : lo = 0x20;
2807 0 : if (IEEE80211_IS_CHAN_5GHZ(sc->sc_curchan))
2808 0 : lo += 0x08;
2809 0 : if ((IEEE80211_IS_CHAN_2GHZ(sc->sc_curchan) && sc->ext_2ghz_lna) ||
2810 0 : (IEEE80211_IS_CHAN_5GHZ(sc->sc_curchan) && sc->ext_5ghz_lna))
2811 0 : lo += 0x10;
2812 0 : hi = lo + 0x20;
2813 :
2814 0 : dbm = sc->avg_rssi;
2815 : /* retrieve false CCA count since last call (clear on read) */
2816 0 : cca = RAL_READ(sc, RT2661_STA_CSR1) & 0xffff;
2817 :
2818 : DPRINTFN(2, ("RSSI=%ddBm false CCA=%d\n", dbm, cca));
2819 :
2820 0 : if (dbm < -74) {
2821 : /* very bad RSSI, tune using false CCA count */
2822 0 : bbp17 = sc->bbp17; /* current value */
2823 :
2824 0 : hi -= 2 * (-74 - dbm);
2825 0 : if (hi < lo)
2826 0 : hi = lo;
2827 :
2828 0 : if (bbp17 > hi)
2829 0 : bbp17 = hi;
2830 0 : else if (cca > 512)
2831 0 : bbp17 = min(bbp17 + 1, hi);
2832 0 : else if (cca < 100)
2833 0 : bbp17 = max(bbp17 - 1, lo);
2834 :
2835 0 : } else if (dbm < -66) {
2836 0 : bbp17 = lo + 0x08;
2837 0 : } else if (dbm < -58) {
2838 0 : bbp17 = lo + 0x10;
2839 0 : } else if (dbm < -35) {
2840 0 : bbp17 = hi;
2841 0 : } else { /* very good RSSI >= -35dBm */
2842 : bbp17 = 0x60; /* very low sensitivity */
2843 : }
2844 :
2845 0 : if (bbp17 != sc->bbp17) {
2846 : DPRINTF(("BBP17 %x->%x\n", sc->bbp17, bbp17));
2847 0 : rt2661_bbp_write(sc, 17, bbp17);
2848 0 : sc->bbp17 = bbp17;
2849 0 : }
2850 0 : }
2851 :
2852 : #ifdef notyet
2853 : /*
2854 : * Enter/Leave radar detection mode.
2855 : * This is for 802.11h additional regulatory domains.
2856 : */
2857 : void
2858 : rt2661_radar_start(struct rt2661_softc *sc)
2859 : {
2860 : uint32_t tmp;
2861 :
2862 : /* disable Rx */
2863 : tmp = RAL_READ(sc, RT2661_TXRX_CSR0);
2864 : RAL_WRITE(sc, RT2661_TXRX_CSR0, tmp | RT2661_DISABLE_RX);
2865 :
2866 : rt2661_bbp_write(sc, 82, 0x20);
2867 : rt2661_bbp_write(sc, 83, 0x00);
2868 : rt2661_bbp_write(sc, 84, 0x40);
2869 :
2870 : /* save current BBP registers values */
2871 : sc->bbp18 = rt2661_bbp_read(sc, 18);
2872 : sc->bbp21 = rt2661_bbp_read(sc, 21);
2873 : sc->bbp22 = rt2661_bbp_read(sc, 22);
2874 : sc->bbp16 = rt2661_bbp_read(sc, 16);
2875 : sc->bbp17 = rt2661_bbp_read(sc, 17);
2876 : sc->bbp64 = rt2661_bbp_read(sc, 64);
2877 :
2878 : rt2661_bbp_write(sc, 18, 0xff);
2879 : rt2661_bbp_write(sc, 21, 0x3f);
2880 : rt2661_bbp_write(sc, 22, 0x3f);
2881 : rt2661_bbp_write(sc, 16, 0xbd);
2882 : rt2661_bbp_write(sc, 17, sc->ext_5ghz_lna ? 0x44 : 0x34);
2883 : rt2661_bbp_write(sc, 64, 0x21);
2884 :
2885 : /* restore Rx filter */
2886 : RAL_WRITE(sc, RT2661_TXRX_CSR0, tmp);
2887 : }
2888 :
2889 : int
2890 : rt2661_radar_stop(struct rt2661_softc *sc)
2891 : {
2892 : uint8_t bbp66;
2893 :
2894 : /* read radar detection result */
2895 : bbp66 = rt2661_bbp_read(sc, 66);
2896 :
2897 : /* restore BBP registers values */
2898 : rt2661_bbp_write(sc, 16, sc->bbp16);
2899 : rt2661_bbp_write(sc, 17, sc->bbp17);
2900 : rt2661_bbp_write(sc, 18, sc->bbp18);
2901 : rt2661_bbp_write(sc, 21, sc->bbp21);
2902 : rt2661_bbp_write(sc, 22, sc->bbp22);
2903 : rt2661_bbp_write(sc, 64, sc->bbp64);
2904 :
2905 : return bbp66 == 1;
2906 : }
2907 : #endif
2908 :
2909 : #ifndef IEEE80211_STA_ONLY
2910 : int
2911 0 : rt2661_prepare_beacon(struct rt2661_softc *sc)
2912 : {
2913 0 : struct ieee80211com *ic = &sc->sc_ic;
2914 0 : struct ieee80211_node *ni = ic->ic_bss;
2915 0 : struct rt2661_tx_desc desc;
2916 : struct mbuf *m0;
2917 : int rate;
2918 :
2919 0 : m0 = ieee80211_beacon_alloc(ic, ni);
2920 0 : if (m0 == NULL) {
2921 0 : printf("%s: could not allocate beacon frame\n",
2922 0 : sc->sc_dev.dv_xname);
2923 0 : return ENOBUFS;
2924 : }
2925 :
2926 : /* send beacons at the lowest available rate */
2927 0 : rate = IEEE80211_IS_CHAN_5GHZ(ni->ni_chan) ? 12 : 2;
2928 :
2929 0 : memset(&desc, 0, sizeof(desc));
2930 0 : rt2661_setup_tx_desc(sc, &desc, RT2661_TX_TIMESTAMP, RT2661_TX_HWSEQ,
2931 0 : m0->m_pkthdr.len, rate, NULL, 0, RT2661_QID_MGT,
2932 : RT2661_AMRR_INVALID_ID);
2933 :
2934 : /* copy the first 24 bytes of Tx descriptor into NIC memory */
2935 0 : RAL_WRITE_REGION_1(sc, RT2661_HW_BEACON_BASE0, (uint8_t *)&desc, 24);
2936 :
2937 : /* copy beacon header and payload into NIC memory */
2938 0 : RAL_WRITE_REGION_1(sc, RT2661_HW_BEACON_BASE0 + 24,
2939 0 : mtod(m0, uint8_t *), m0->m_pkthdr.len);
2940 :
2941 0 : m_freem(m0);
2942 :
2943 : /*
2944 : * Store offset of ERP Information Element so that we can update it
2945 : * dynamically when the slot time changes.
2946 : * XXX: this is ugly since it depends on how net80211 builds beacon
2947 : * frames but ieee80211_beacon_alloc() doesn't store offsets for us.
2948 : */
2949 0 : if (ic->ic_curmode == IEEE80211_MODE_11G) {
2950 0 : sc->erp_csr =
2951 0 : RT2661_HW_BEACON_BASE0 + 24 +
2952 : sizeof (struct ieee80211_frame) +
2953 0 : 8 + 2 + 2 +
2954 0 : ((ic->ic_flags & IEEE80211_F_HIDENWID) ?
2955 0 : 1 : 2 + ni->ni_esslen) +
2956 0 : 2 + min(ni->ni_rates.rs_nrates, IEEE80211_RATE_SIZE) +
2957 0 : 2 + 1 +
2958 0 : ((ic->ic_opmode == IEEE80211_M_IBSS) ? 4 : 6) +
2959 : 2;
2960 0 : }
2961 :
2962 0 : return 0;
2963 0 : }
2964 : #endif
2965 :
2966 : /*
2967 : * Enable TSF synchronization and tell h/w to start sending beacons for IBSS
2968 : * and HostAP operating modes.
2969 : */
2970 : void
2971 0 : rt2661_enable_tsf_sync(struct rt2661_softc *sc)
2972 : {
2973 0 : struct ieee80211com *ic = &sc->sc_ic;
2974 : uint32_t tmp;
2975 :
2976 : #ifndef IEEE80211_STA_ONLY
2977 0 : if (ic->ic_opmode != IEEE80211_M_STA) {
2978 : /*
2979 : * Change default 16ms TBTT adjustment to 8ms.
2980 : * Must be done before enabling beacon generation.
2981 : */
2982 0 : RAL_WRITE(sc, RT2661_TXRX_CSR10, 1 << 12 | 8);
2983 0 : }
2984 : #endif
2985 0 : tmp = RAL_READ(sc, RT2661_TXRX_CSR9) & 0xff000000;
2986 :
2987 : /* set beacon interval (in 1/16ms unit) */
2988 0 : tmp |= ic->ic_bss->ni_intval * 16;
2989 :
2990 0 : tmp |= RT2661_TSF_TICKING | RT2661_ENABLE_TBTT;
2991 0 : if (ic->ic_opmode == IEEE80211_M_STA)
2992 0 : tmp |= RT2661_TSF_MODE(1);
2993 : #ifndef IEEE80211_STA_ONLY
2994 : else
2995 0 : tmp |= RT2661_TSF_MODE(2) | RT2661_GENERATE_BEACON;
2996 : #endif
2997 0 : RAL_WRITE(sc, RT2661_TXRX_CSR9, tmp);
2998 0 : }
2999 :
3000 : /*
3001 : * Retrieve the "Received Signal Strength Indicator" from the raw values
3002 : * contained in Rx descriptors. The computation depends on which band the
3003 : * frame was received. Correction values taken from the reference driver.
3004 : */
3005 : int
3006 0 : rt2661_get_rssi(struct rt2661_softc *sc, uint8_t raw)
3007 : {
3008 : int lna, agc, rssi;
3009 :
3010 0 : lna = (raw >> 5) & 0x3;
3011 0 : agc = raw & 0x1f;
3012 :
3013 0 : rssi = 2 * agc;
3014 :
3015 0 : if (IEEE80211_IS_CHAN_2GHZ(sc->sc_curchan)) {
3016 0 : rssi += sc->rssi_2ghz_corr;
3017 :
3018 0 : if (lna == 1)
3019 0 : rssi -= 64;
3020 0 : else if (lna == 2)
3021 0 : rssi -= 74;
3022 0 : else if (lna == 3)
3023 0 : rssi -= 90;
3024 : } else {
3025 0 : rssi += sc->rssi_5ghz_corr;
3026 :
3027 0 : if (lna == 1)
3028 0 : rssi -= 64;
3029 0 : else if (lna == 2)
3030 0 : rssi -= 86;
3031 0 : else if (lna == 3)
3032 0 : rssi -= 100;
3033 : }
3034 0 : return rssi;
3035 : }
|