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