[BACK]Return to rt2560.c CVS log [TXT][DIR] Up to [local] / sys / dev / ic

Annotation of sys/dev/ic/rt2560.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: rt2560.c,v 1.32 2007/03/08 21:58:27 deraadt Exp $  */
        !             2:
        !             3: /*-
        !             4:  * Copyright (c) 2005, 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 RT2560 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/rt2560reg.h>
        !            63: #include <dev/ic/rt2560var.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 (rt2560_debug > 0) printf x; } while (0)
        !            71: #define DPRINTFN(n, x) do { if (rt2560_debug >= (n)) printf x; } while (0)
        !            72: int rt2560_debug = 1;
        !            73: #else
        !            74: #define DPRINTF(x)
        !            75: #define DPRINTFN(n, x)
        !            76: #endif
        !            77:
        !            78: int            rt2560_alloc_tx_ring(struct rt2560_softc *,
        !            79:                    struct rt2560_tx_ring *, int);
        !            80: void           rt2560_reset_tx_ring(struct rt2560_softc *,
        !            81:                    struct rt2560_tx_ring *);
        !            82: void           rt2560_free_tx_ring(struct rt2560_softc *,
        !            83:                    struct rt2560_tx_ring *);
        !            84: int            rt2560_alloc_rx_ring(struct rt2560_softc *,
        !            85:                    struct rt2560_rx_ring *, int);
        !            86: void           rt2560_reset_rx_ring(struct rt2560_softc *,
        !            87:                    struct rt2560_rx_ring *);
        !            88: void           rt2560_free_rx_ring(struct rt2560_softc *,
        !            89:                    struct rt2560_rx_ring *);
        !            90: struct         ieee80211_node *rt2560_node_alloc(struct ieee80211com *);
        !            91: int            rt2560_media_change(struct ifnet *);
        !            92: void           rt2560_next_scan(void *);
        !            93: void           rt2560_iter_func(void *, struct ieee80211_node *);
        !            94: void           rt2560_amrr_timeout(void *);
        !            95: void           rt2560_newassoc(struct ieee80211com *, struct ieee80211_node *,
        !            96:                    int);
        !            97: int            rt2560_newstate(struct ieee80211com *, enum ieee80211_state,
        !            98:                    int);
        !            99: uint16_t       rt2560_eeprom_read(struct rt2560_softc *, uint8_t);
        !           100: void           rt2560_encryption_intr(struct rt2560_softc *);
        !           101: void           rt2560_tx_intr(struct rt2560_softc *);
        !           102: void           rt2560_prio_intr(struct rt2560_softc *);
        !           103: void           rt2560_decryption_intr(struct rt2560_softc *);
        !           104: void           rt2560_rx_intr(struct rt2560_softc *);
        !           105: void           rt2560_beacon_expire(struct rt2560_softc *);
        !           106: void           rt2560_wakeup_expire(struct rt2560_softc *);
        !           107: #if NBPFILTER > 0
        !           108: uint8_t                rt2560_rxrate(const struct rt2560_rx_desc *);
        !           109: #endif
        !           110: int            rt2560_ack_rate(struct ieee80211com *, int);
        !           111: uint16_t       rt2560_txtime(int, int, uint32_t);
        !           112: uint8_t                rt2560_plcp_signal(int);
        !           113: void           rt2560_setup_tx_desc(struct rt2560_softc *,
        !           114:                    struct rt2560_tx_desc *, uint32_t, int, int, int,
        !           115:                    bus_addr_t);
        !           116: int            rt2560_tx_bcn(struct rt2560_softc *, struct mbuf *,
        !           117:                    struct ieee80211_node *);
        !           118: int            rt2560_tx_mgt(struct rt2560_softc *, struct mbuf *,
        !           119:                    struct ieee80211_node *);
        !           120: int            rt2560_tx_data(struct rt2560_softc *, struct mbuf *,
        !           121:                    struct ieee80211_node *);
        !           122: void           rt2560_start(struct ifnet *);
        !           123: void           rt2560_watchdog(struct ifnet *);
        !           124: int            rt2560_ioctl(struct ifnet *, u_long, caddr_t);
        !           125: void           rt2560_bbp_write(struct rt2560_softc *, uint8_t, uint8_t);
        !           126: uint8_t                rt2560_bbp_read(struct rt2560_softc *, uint8_t);
        !           127: void           rt2560_rf_write(struct rt2560_softc *, uint8_t, uint32_t);
        !           128: void           rt2560_set_chan(struct rt2560_softc *,
        !           129:                    struct ieee80211_channel *);
        !           130: void           rt2560_disable_rf_tune(struct rt2560_softc *);
        !           131: void           rt2560_enable_tsf_sync(struct rt2560_softc *);
        !           132: void           rt2560_update_plcp(struct rt2560_softc *);
        !           133: void           rt2560_updateslot(struct ieee80211com *);
        !           134: void           rt2560_set_slottime(struct rt2560_softc *);
        !           135: void           rt2560_set_basicrates(struct rt2560_softc *);
        !           136: void           rt2560_update_led(struct rt2560_softc *, int, int);
        !           137: void           rt2560_set_bssid(struct rt2560_softc *, uint8_t *);
        !           138: void           rt2560_set_macaddr(struct rt2560_softc *, uint8_t *);
        !           139: void           rt2560_get_macaddr(struct rt2560_softc *, uint8_t *);
        !           140: void           rt2560_update_promisc(struct rt2560_softc *);
        !           141: void           rt2560_set_txantenna(struct rt2560_softc *, int);
        !           142: void           rt2560_set_rxantenna(struct rt2560_softc *, int);
        !           143: const char     *rt2560_get_rf(int);
        !           144: void           rt2560_read_eeprom(struct rt2560_softc *);
        !           145: int            rt2560_bbp_init(struct rt2560_softc *);
        !           146: int            rt2560_init(struct ifnet *);
        !           147: void           rt2560_stop(struct ifnet *, int);
        !           148: void           rt2560_power(int, void *);
        !           149:
        !           150: static const struct {
        !           151:        uint32_t        reg;
        !           152:        uint32_t        val;
        !           153: } rt2560_def_mac[] = {
        !           154:        RT2560_DEF_MAC
        !           155: };
        !           156:
        !           157: static const struct {
        !           158:        uint8_t reg;
        !           159:        uint8_t val;
        !           160: } rt2560_def_bbp[] = {
        !           161:        RT2560_DEF_BBP
        !           162: };
        !           163:
        !           164: static const uint32_t rt2560_rf2522_r2[]    = RT2560_RF2522_R2;
        !           165: static const uint32_t rt2560_rf2523_r2[]    = RT2560_RF2523_R2;
        !           166: static const uint32_t rt2560_rf2524_r2[]    = RT2560_RF2524_R2;
        !           167: static const uint32_t rt2560_rf2525_r2[]    = RT2560_RF2525_R2;
        !           168: static const uint32_t rt2560_rf2525_hi_r2[] = RT2560_RF2525_HI_R2;
        !           169: static const uint32_t rt2560_rf2525e_r2[]   = RT2560_RF2525E_R2;
        !           170: static const uint32_t rt2560_rf2526_r2[]    = RT2560_RF2526_R2;
        !           171: static const uint32_t rt2560_rf2526_hi_r2[] = RT2560_RF2526_HI_R2;
        !           172:
        !           173: int
        !           174: rt2560_attach(void *xsc, int id)
        !           175: {
        !           176:        struct rt2560_softc *sc = xsc;
        !           177:        struct ieee80211com *ic = &sc->sc_ic;
        !           178:        struct ifnet *ifp = &ic->ic_if;
        !           179:        int error, i;
        !           180:
        !           181:        sc->amrr.amrr_min_success_threshold =  1;
        !           182:        sc->amrr.amrr_max_success_threshold = 15;
        !           183:        timeout_set(&sc->amrr_to, rt2560_amrr_timeout, sc);
        !           184:        timeout_set(&sc->scan_to, rt2560_next_scan, sc);
        !           185:
        !           186:        /* retrieve RT2560 rev. no */
        !           187:        sc->asic_rev = RAL_READ(sc, RT2560_CSR0);
        !           188:
        !           189:        /* retrieve MAC address */
        !           190:        rt2560_get_macaddr(sc, ic->ic_myaddr);
        !           191:        printf(", address %s\n", ether_sprintf(ic->ic_myaddr));
        !           192:
        !           193:        /* retrieve RF rev. no and various other things from EEPROM */
        !           194:        rt2560_read_eeprom(sc);
        !           195:
        !           196:        printf("%s: MAC/BBP RT2560 (rev 0x%02x), RF %s\n", sc->sc_dev.dv_xname,
        !           197:            sc->asic_rev, rt2560_get_rf(sc->rf_rev));
        !           198:
        !           199:        /*
        !           200:         * Allocate Tx and Rx rings.
        !           201:         */
        !           202:        error = rt2560_alloc_tx_ring(sc, &sc->txq, RT2560_TX_RING_COUNT);
        !           203:        if (error != 0) {
        !           204:                printf("%s: could not allocate Tx ring\n",
        !           205:                    sc->sc_dev.dv_xname);
        !           206:                goto fail1;
        !           207:        }
        !           208:        error = rt2560_alloc_tx_ring(sc, &sc->atimq, RT2560_ATIM_RING_COUNT);
        !           209:        if (error != 0) {
        !           210:                printf("%s: could not allocate ATIM ring\n",
        !           211:                    sc->sc_dev.dv_xname);
        !           212:                goto fail2;
        !           213:        }
        !           214:        error = rt2560_alloc_tx_ring(sc, &sc->prioq, RT2560_PRIO_RING_COUNT);
        !           215:        if (error != 0) {
        !           216:                printf("%s: could not allocate Prio ring\n",
        !           217:                    sc->sc_dev.dv_xname);
        !           218:                goto fail3;
        !           219:        }
        !           220:        error = rt2560_alloc_tx_ring(sc, &sc->bcnq, RT2560_BEACON_RING_COUNT);
        !           221:        if (error != 0) {
        !           222:                printf("%s: could not allocate Beacon ring\n",
        !           223:                    sc->sc_dev.dv_xname);
        !           224:                goto fail4;
        !           225:        }
        !           226:        error = rt2560_alloc_rx_ring(sc, &sc->rxq, RT2560_RX_RING_COUNT);
        !           227:        if (error != 0) {
        !           228:                printf("%s: could not allocate Rx ring\n",
        !           229:                    sc->sc_dev.dv_xname);
        !           230:                goto fail5;
        !           231:        }
        !           232:
        !           233:        ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
        !           234:        ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */
        !           235:        ic->ic_state = IEEE80211_S_INIT;
        !           236:
        !           237:        /* set device capabilities */
        !           238:        ic->ic_caps =
        !           239:            IEEE80211_C_IBSS |          /* IBSS mode supported */
        !           240:            IEEE80211_C_MONITOR |       /* monitor mode supported */
        !           241:            IEEE80211_C_HOSTAP |        /* HostAp mode supported */
        !           242:            IEEE80211_C_TXPMGT |        /* tx power management */
        !           243:            IEEE80211_C_SHPREAMBLE |    /* short preamble supported */
        !           244:            IEEE80211_C_SHSLOT |        /* short slot time supported */
        !           245:            IEEE80211_C_WEP;            /* s/w WEP */
        !           246:
        !           247:        /* set supported .11b and .11g rates */
        !           248:        ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b;
        !           249:        ic->ic_sup_rates[IEEE80211_MODE_11G] = ieee80211_std_rateset_11g;
        !           250:
        !           251:        /* set supported .11b and .11g channels (1 through 14) */
        !           252:        for (i = 1; i <= 14; i++) {
        !           253:                ic->ic_channels[i].ic_freq =
        !           254:                    ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ);
        !           255:                ic->ic_channels[i].ic_flags =
        !           256:                    IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM |
        !           257:                    IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ;
        !           258:        }
        !           259:
        !           260:        ifp->if_softc = sc;
        !           261:        ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
        !           262:        ifp->if_init = rt2560_init;
        !           263:        ifp->if_ioctl = rt2560_ioctl;
        !           264:        ifp->if_start = rt2560_start;
        !           265:        ifp->if_watchdog = rt2560_watchdog;
        !           266:        IFQ_SET_READY(&ifp->if_snd);
        !           267:        memcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ);
        !           268:
        !           269:        if_attach(ifp);
        !           270:        ieee80211_ifattach(ifp);
        !           271:        ic->ic_node_alloc = rt2560_node_alloc;
        !           272:        ic->ic_newassoc = rt2560_newassoc;
        !           273:        ic->ic_updateslot = rt2560_updateslot;
        !           274:
        !           275:        /* override state transition machine */
        !           276:        sc->sc_newstate = ic->ic_newstate;
        !           277:        ic->ic_newstate = rt2560_newstate;
        !           278:        ieee80211_media_init(ifp, rt2560_media_change, ieee80211_media_status);
        !           279:
        !           280: #if NBPFILTER > 0
        !           281:        bpfattach(&sc->sc_drvbpf, ifp, DLT_IEEE802_11_RADIO,
        !           282:            sizeof (struct ieee80211_frame) + 64);
        !           283:
        !           284:        sc->sc_rxtap_len = sizeof sc->sc_rxtapu;
        !           285:        sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
        !           286:        sc->sc_rxtap.wr_ihdr.it_present = htole32(RT2560_RX_RADIOTAP_PRESENT);
        !           287:
        !           288:        sc->sc_txtap_len = sizeof sc->sc_txtapu;
        !           289:        sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
        !           290:        sc->sc_txtap.wt_ihdr.it_present = htole32(RT2560_TX_RADIOTAP_PRESENT);
        !           291: #endif
        !           292:
        !           293:        /*
        !           294:         * Make sure the interface is shutdown during reboot.
        !           295:         */
        !           296:        sc->sc_sdhook = shutdownhook_establish(rt2560_shutdown, sc);
        !           297:        if (sc->sc_sdhook == NULL) {
        !           298:                printf("%s: WARNING: unable to establish shutdown hook\n",
        !           299:                    sc->sc_dev.dv_xname);
        !           300:        }
        !           301:        sc->sc_powerhook = powerhook_establish(rt2560_power, sc);
        !           302:        if (sc->sc_powerhook == NULL) {
        !           303:                printf("%s: WARNING: unable to establish power hook\n",
        !           304:                    sc->sc_dev.dv_xname);
        !           305:        }
        !           306:        return 0;
        !           307:
        !           308: fail5: rt2560_free_tx_ring(sc, &sc->bcnq);
        !           309: fail4: rt2560_free_tx_ring(sc, &sc->prioq);
        !           310: fail3: rt2560_free_tx_ring(sc, &sc->atimq);
        !           311: fail2: rt2560_free_tx_ring(sc, &sc->txq);
        !           312: fail1: return ENXIO;
        !           313: }
        !           314:
        !           315: int
        !           316: rt2560_detach(void *xsc)
        !           317: {
        !           318:        struct rt2560_softc *sc = xsc;
        !           319:        struct ifnet *ifp = &sc->sc_ic.ic_if;
        !           320:
        !           321:        timeout_del(&sc->scan_to);
        !           322:        timeout_del(&sc->amrr_to);
        !           323:
        !           324:        ieee80211_ifdetach(ifp);        /* free all nodes */
        !           325:        if_detach(ifp);
        !           326:
        !           327:        if (sc->sc_powerhook != NULL)
        !           328:                powerhook_disestablish(sc->sc_powerhook);
        !           329:        if (sc->sc_sdhook != NULL)
        !           330:                shutdownhook_disestablish(sc->sc_sdhook);
        !           331:
        !           332:        rt2560_free_tx_ring(sc, &sc->txq);
        !           333:        rt2560_free_tx_ring(sc, &sc->atimq);
        !           334:        rt2560_free_tx_ring(sc, &sc->prioq);
        !           335:        rt2560_free_tx_ring(sc, &sc->bcnq);
        !           336:        rt2560_free_rx_ring(sc, &sc->rxq);
        !           337:
        !           338:        return 0;
        !           339: }
        !           340:
        !           341: int
        !           342: rt2560_alloc_tx_ring(struct rt2560_softc *sc, struct rt2560_tx_ring *ring,
        !           343:     int count)
        !           344: {
        !           345:        int i, nsegs, error;
        !           346:
        !           347:        ring->count = count;
        !           348:        ring->queued = 0;
        !           349:        ring->cur = ring->next = 0;
        !           350:        ring->cur_encrypt = ring->next_encrypt = 0;
        !           351:
        !           352:        error = bus_dmamap_create(sc->sc_dmat, count * RT2560_TX_DESC_SIZE, 1,
        !           353:            count * RT2560_TX_DESC_SIZE, 0, BUS_DMA_NOWAIT, &ring->map);
        !           354:        if (error != 0) {
        !           355:                printf("%s: could not create desc DMA map\n",
        !           356:                    sc->sc_dev.dv_xname);
        !           357:                goto fail;
        !           358:        }
        !           359:
        !           360:        error = bus_dmamem_alloc(sc->sc_dmat, count * RT2560_TX_DESC_SIZE,
        !           361:            PAGE_SIZE, 0, &ring->seg, 1, &nsegs, BUS_DMA_NOWAIT);
        !           362:        if (error != 0) {
        !           363:                printf("%s: could not allocate DMA memory\n",
        !           364:                    sc->sc_dev.dv_xname);
        !           365:                goto fail;
        !           366:        }
        !           367:
        !           368:        error = bus_dmamem_map(sc->sc_dmat, &ring->seg, nsegs,
        !           369:            count * RT2560_TX_DESC_SIZE, (caddr_t *)&ring->desc,
        !           370:            BUS_DMA_NOWAIT);
        !           371:        if (error != 0) {
        !           372:                printf("%s: could not map desc DMA memory\n",
        !           373:                    sc->sc_dev.dv_xname);
        !           374:                goto fail;
        !           375:        }
        !           376:
        !           377:        error = bus_dmamap_load(sc->sc_dmat, ring->map, ring->desc,
        !           378:            count * RT2560_TX_DESC_SIZE, NULL, BUS_DMA_NOWAIT);
        !           379:        if (error != 0) {
        !           380:                printf("%s: could not load desc DMA map\n",
        !           381:                    sc->sc_dev.dv_xname);
        !           382:                goto fail;
        !           383:        }
        !           384:
        !           385:        memset(ring->desc, 0, count * RT2560_TX_DESC_SIZE);
        !           386:        ring->physaddr = ring->map->dm_segs->ds_addr;
        !           387:
        !           388:        ring->data = malloc(count * sizeof (struct rt2560_tx_data), M_DEVBUF,
        !           389:            M_NOWAIT);
        !           390:        if (ring->data == NULL) {
        !           391:                printf("%s: could not allocate soft data\n",
        !           392:                    sc->sc_dev.dv_xname);
        !           393:                error = ENOMEM;
        !           394:                goto fail;
        !           395:        }
        !           396:
        !           397:        memset(ring->data, 0, count * sizeof (struct rt2560_tx_data));
        !           398:        for (i = 0; i < count; i++) {
        !           399:                error = bus_dmamap_create(sc->sc_dmat, MCLBYTES,
        !           400:                    RT2560_MAX_SCATTER, MCLBYTES, 0, BUS_DMA_NOWAIT,
        !           401:                    &ring->data[i].map);
        !           402:                if (error != 0) {
        !           403:                        printf("%s: could not create DMA map\n",
        !           404:                            sc->sc_dev.dv_xname);
        !           405:                        goto fail;
        !           406:                }
        !           407:        }
        !           408:
        !           409:        return 0;
        !           410:
        !           411: fail:  rt2560_free_tx_ring(sc, ring);
        !           412:        return error;
        !           413: }
        !           414:
        !           415: void
        !           416: rt2560_reset_tx_ring(struct rt2560_softc *sc, struct rt2560_tx_ring *ring)
        !           417: {
        !           418:        int i;
        !           419:
        !           420:        for (i = 0; i < ring->count; i++) {
        !           421:                struct rt2560_tx_desc *desc = &ring->desc[i];
        !           422:                struct rt2560_tx_data *data = &ring->data[i];
        !           423:
        !           424:                if (data->m != NULL) {
        !           425:                        bus_dmamap_sync(sc->sc_dmat, data->map, 0,
        !           426:                            data->map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
        !           427:                        bus_dmamap_unload(sc->sc_dmat, data->map);
        !           428:                        m_freem(data->m);
        !           429:                        data->m = NULL;
        !           430:                }
        !           431:
        !           432:                /*
        !           433:                 * The node has already been freed at that point so don't call
        !           434:                 * ieee80211_release_node() here.
        !           435:                 */
        !           436:                data->ni = NULL;
        !           437:
        !           438:                desc->flags = 0;
        !           439:        }
        !           440:
        !           441:        bus_dmamap_sync(sc->sc_dmat, ring->map, 0, ring->map->dm_mapsize,
        !           442:            BUS_DMASYNC_PREWRITE);
        !           443:
        !           444:        ring->queued = 0;
        !           445:        ring->cur = ring->next = 0;
        !           446:        ring->cur_encrypt = ring->next_encrypt = 0;
        !           447: }
        !           448:
        !           449: void
        !           450: rt2560_free_tx_ring(struct rt2560_softc *sc, struct rt2560_tx_ring *ring)
        !           451: {
        !           452:        int i;
        !           453:
        !           454:        if (ring->desc != NULL) {
        !           455:                bus_dmamap_sync(sc->sc_dmat, ring->map, 0,
        !           456:                    ring->map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
        !           457:                bus_dmamap_unload(sc->sc_dmat, ring->map);
        !           458:                bus_dmamem_unmap(sc->sc_dmat, (caddr_t)ring->desc,
        !           459:                    ring->count * RT2560_TX_DESC_SIZE);
        !           460:                bus_dmamem_free(sc->sc_dmat, &ring->seg, 1);
        !           461:        }
        !           462:
        !           463:        if (ring->data != NULL) {
        !           464:                for (i = 0; i < ring->count; i++) {
        !           465:                        struct rt2560_tx_data *data = &ring->data[i];
        !           466:
        !           467:                        if (data->m != NULL) {
        !           468:                                bus_dmamap_sync(sc->sc_dmat, data->map, 0,
        !           469:                                    data->map->dm_mapsize,
        !           470:                                    BUS_DMASYNC_POSTWRITE);
        !           471:                                bus_dmamap_unload(sc->sc_dmat, data->map);
        !           472:                                m_freem(data->m);
        !           473:                        }
        !           474:
        !           475:                        /*
        !           476:                         * The node has already been freed at that point so
        !           477:                         * don't call ieee80211_release_node() here.
        !           478:                         */
        !           479:                        data->ni = NULL;
        !           480:
        !           481:                        if (data->map != NULL)
        !           482:                                bus_dmamap_destroy(sc->sc_dmat, data->map);
        !           483:                }
        !           484:                free(ring->data, M_DEVBUF);
        !           485:        }
        !           486: }
        !           487:
        !           488: int
        !           489: rt2560_alloc_rx_ring(struct rt2560_softc *sc, struct rt2560_rx_ring *ring,
        !           490:     int count)
        !           491: {
        !           492:        int i, nsegs, error;
        !           493:
        !           494:        ring->count = count;
        !           495:        ring->cur = ring->next = 0;
        !           496:        ring->cur_decrypt = 0;
        !           497:
        !           498:        error = bus_dmamap_create(sc->sc_dmat, count * RT2560_RX_DESC_SIZE, 1,
        !           499:            count * RT2560_RX_DESC_SIZE, 0, BUS_DMA_NOWAIT, &ring->map);
        !           500:        if (error != 0) {
        !           501:                printf("%s: could not create desc DMA map\n",
        !           502:                    sc->sc_dev.dv_xname);
        !           503:                goto fail;
        !           504:        }
        !           505:
        !           506:        error = bus_dmamem_alloc(sc->sc_dmat, count * RT2560_RX_DESC_SIZE,
        !           507:            PAGE_SIZE, 0, &ring->seg, 1, &nsegs, BUS_DMA_NOWAIT);
        !           508:        if (error != 0) {
        !           509:                printf("%s: could not allocate DMA memory\n",
        !           510:                    sc->sc_dev.dv_xname);
        !           511:                goto fail;
        !           512:        }
        !           513:
        !           514:        error = bus_dmamem_map(sc->sc_dmat, &ring->seg, nsegs,
        !           515:            count * RT2560_RX_DESC_SIZE, (caddr_t *)&ring->desc,
        !           516:            BUS_DMA_NOWAIT);
        !           517:        if (error != 0) {
        !           518:                printf("%s: could not map desc DMA memory\n",
        !           519:                    sc->sc_dev.dv_xname);
        !           520:                goto fail;
        !           521:        }
        !           522:
        !           523:        error = bus_dmamap_load(sc->sc_dmat, ring->map, ring->desc,
        !           524:            count * RT2560_RX_DESC_SIZE, NULL, BUS_DMA_NOWAIT);
        !           525:        if (error != 0) {
        !           526:                printf("%s: could not load desc DMA map\n",
        !           527:                    sc->sc_dev.dv_xname);
        !           528:                goto fail;
        !           529:        }
        !           530:
        !           531:        memset(ring->desc, 0, count * RT2560_RX_DESC_SIZE);
        !           532:        ring->physaddr = ring->map->dm_segs->ds_addr;
        !           533:
        !           534:        ring->data = malloc(count * sizeof (struct rt2560_rx_data), M_DEVBUF,
        !           535:            M_NOWAIT);
        !           536:        if (ring->data == NULL) {
        !           537:                printf("%s: could not allocate soft data\n",
        !           538:                    sc->sc_dev.dv_xname);
        !           539:                error = ENOMEM;
        !           540:                goto fail;
        !           541:        }
        !           542:
        !           543:        /*
        !           544:         * Pre-allocate Rx buffers and populate Rx ring.
        !           545:         */
        !           546:        memset(ring->data, 0, count * sizeof (struct rt2560_rx_data));
        !           547:        for (i = 0; i < count; i++) {
        !           548:                struct rt2560_rx_desc *desc = &sc->rxq.desc[i];
        !           549:                struct rt2560_rx_data *data = &sc->rxq.data[i];
        !           550:
        !           551:                error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES,
        !           552:                    0, BUS_DMA_NOWAIT, &data->map);
        !           553:                if (error != 0) {
        !           554:                        printf("%s: could not create DMA map\n",
        !           555:                            sc->sc_dev.dv_xname);
        !           556:                        goto fail;
        !           557:                }
        !           558:
        !           559:                MGETHDR(data->m, M_DONTWAIT, MT_DATA);
        !           560:                if (data->m == NULL) {
        !           561:                        printf("%s: could not allocate rx mbuf\n",
        !           562:                            sc->sc_dev.dv_xname);
        !           563:                        error = ENOMEM;
        !           564:                        goto fail;
        !           565:                }
        !           566:                MCLGET(data->m, M_DONTWAIT);
        !           567:                if (!(data->m->m_flags & M_EXT)) {
        !           568:                        printf("%s: could not allocate rx mbuf cluster\n",
        !           569:                            sc->sc_dev.dv_xname);
        !           570:                        error = ENOMEM;
        !           571:                        goto fail;
        !           572:                }
        !           573:
        !           574:                error = bus_dmamap_load(sc->sc_dmat, data->map,
        !           575:                    mtod(data->m, void *), MCLBYTES, NULL, BUS_DMA_NOWAIT);
        !           576:                if (error != 0) {
        !           577:                        printf("%s: could not load rx buf DMA map",
        !           578:                            sc->sc_dev.dv_xname);
        !           579:                        goto fail;
        !           580:                }
        !           581:
        !           582:                desc->flags = htole32(RT2560_RX_BUSY);
        !           583:                desc->physaddr = htole32(data->map->dm_segs->ds_addr);
        !           584:        }
        !           585:
        !           586:        bus_dmamap_sync(sc->sc_dmat, ring->map, 0, ring->map->dm_mapsize,
        !           587:            BUS_DMASYNC_PREWRITE);
        !           588:
        !           589:        return 0;
        !           590:
        !           591: fail:  rt2560_free_rx_ring(sc, ring);
        !           592:        return error;
        !           593: }
        !           594:
        !           595: void
        !           596: rt2560_reset_rx_ring(struct rt2560_softc *sc, struct rt2560_rx_ring *ring)
        !           597: {
        !           598:        int i;
        !           599:
        !           600:        for (i = 0; i < ring->count; i++) {
        !           601:                ring->desc[i].flags = htole32(RT2560_RX_BUSY);
        !           602:                ring->data[i].drop = 0;
        !           603:        }
        !           604:
        !           605:        bus_dmamap_sync(sc->sc_dmat, ring->map, 0, ring->map->dm_mapsize,
        !           606:            BUS_DMASYNC_PREWRITE);
        !           607:
        !           608:        ring->cur = ring->next = 0;
        !           609:        ring->cur_decrypt = 0;
        !           610: }
        !           611:
        !           612: void
        !           613: rt2560_free_rx_ring(struct rt2560_softc *sc, struct rt2560_rx_ring *ring)
        !           614: {
        !           615:        int i;
        !           616:
        !           617:        if (ring->desc != NULL) {
        !           618:                bus_dmamap_sync(sc->sc_dmat, ring->map, 0,
        !           619:                    ring->map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
        !           620:                bus_dmamap_unload(sc->sc_dmat, ring->map);
        !           621:                bus_dmamem_unmap(sc->sc_dmat, (caddr_t)ring->desc,
        !           622:                    ring->count * RT2560_RX_DESC_SIZE);
        !           623:                bus_dmamem_free(sc->sc_dmat, &ring->seg, 1);
        !           624:        }
        !           625:
        !           626:        if (ring->data != NULL) {
        !           627:                for (i = 0; i < ring->count; i++) {
        !           628:                        struct rt2560_rx_data *data = &ring->data[i];
        !           629:
        !           630:                        if (data->m != NULL) {
        !           631:                                bus_dmamap_sync(sc->sc_dmat, data->map, 0,
        !           632:                                    data->map->dm_mapsize,
        !           633:                                    BUS_DMASYNC_POSTREAD);
        !           634:                                bus_dmamap_unload(sc->sc_dmat, data->map);
        !           635:                                m_freem(data->m);
        !           636:                        }
        !           637:
        !           638:                        if (data->map != NULL)
        !           639:                                bus_dmamap_destroy(sc->sc_dmat, data->map);
        !           640:                }
        !           641:                free(ring->data, M_DEVBUF);
        !           642:        }
        !           643: }
        !           644:
        !           645: struct ieee80211_node *
        !           646: rt2560_node_alloc(struct ieee80211com *ic)
        !           647: {
        !           648:        struct rt2560_node *rn;
        !           649:
        !           650:        rn = malloc(sizeof (struct rt2560_node), M_DEVBUF, M_NOWAIT);
        !           651:        if (rn != NULL)
        !           652:                bzero(rn, sizeof (struct rt2560_node));
        !           653:        return (struct ieee80211_node *)rn;
        !           654: }
        !           655:
        !           656: int
        !           657: rt2560_media_change(struct ifnet *ifp)
        !           658: {
        !           659:        int error;
        !           660:
        !           661:        error = ieee80211_media_change(ifp);
        !           662:        if (error != ENETRESET)
        !           663:                return error;
        !           664:
        !           665:        if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING))
        !           666:                rt2560_init(ifp);
        !           667:
        !           668:        return 0;
        !           669: }
        !           670:
        !           671: /*
        !           672:  * This function is called periodically (every 200ms) during scanning to
        !           673:  * switch from one channel to another.
        !           674:  */
        !           675: void
        !           676: rt2560_next_scan(void *arg)
        !           677: {
        !           678:        struct rt2560_softc *sc = arg;
        !           679:        struct ieee80211com *ic = &sc->sc_ic;
        !           680:        struct ifnet *ifp = &ic->ic_if;
        !           681:        int s;
        !           682:
        !           683:        s = splnet();
        !           684:        if (ic->ic_state == IEEE80211_S_SCAN)
        !           685:                ieee80211_next_scan(ifp);
        !           686:        splx(s);
        !           687: }
        !           688:
        !           689: /*
        !           690:  * This function is called for each neighbor node.
        !           691:  */
        !           692: void
        !           693: rt2560_iter_func(void *arg, struct ieee80211_node *ni)
        !           694: {
        !           695:        struct rt2560_softc *sc = arg;
        !           696:        struct rt2560_node *rn = (struct rt2560_node *)ni;
        !           697:
        !           698:        ieee80211_amrr_choose(&sc->amrr, ni, &rn->amn);
        !           699: }
        !           700:
        !           701: void
        !           702: rt2560_amrr_timeout(void *arg)
        !           703: {
        !           704:        struct rt2560_softc *sc = arg;
        !           705:        struct ieee80211com *ic = &sc->sc_ic;
        !           706:        int s;
        !           707:
        !           708:        s = splnet();
        !           709:        if (ic->ic_opmode == IEEE80211_M_STA)
        !           710:                rt2560_iter_func(sc, ic->ic_bss);
        !           711:        else
        !           712:                ieee80211_iterate_nodes(ic, rt2560_iter_func, sc);
        !           713:        splx(s);
        !           714:
        !           715:        timeout_add(&sc->amrr_to, hz / 2);
        !           716: }
        !           717:
        !           718: void
        !           719: rt2560_newassoc(struct ieee80211com *ic, struct ieee80211_node *ni, int isnew)
        !           720: {
        !           721:        struct rt2560_softc *sc = ic->ic_softc;
        !           722:        int i;
        !           723:
        !           724:        ieee80211_amrr_node_init(&sc->amrr, &((struct rt2560_node *)ni)->amn);
        !           725:
        !           726:        /* set rate to some reasonable initial value */
        !           727:        for (i = ni->ni_rates.rs_nrates - 1;
        !           728:             i > 0 && (ni->ni_rates.rs_rates[i] & IEEE80211_RATE_VAL) > 72;
        !           729:             i--);
        !           730:        ni->ni_txrate = i;
        !           731: }
        !           732:
        !           733: int
        !           734: rt2560_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
        !           735: {
        !           736:        struct rt2560_softc *sc = ic->ic_if.if_softc;
        !           737:        enum ieee80211_state ostate;
        !           738:        struct ieee80211_node *ni;
        !           739:        struct mbuf *m;
        !           740:        int error = 0;
        !           741:
        !           742:        ostate = ic->ic_state;
        !           743:        timeout_del(&sc->scan_to);
        !           744:        timeout_del(&sc->amrr_to);
        !           745:
        !           746:        switch (nstate) {
        !           747:        case IEEE80211_S_INIT:
        !           748:                if (ostate == IEEE80211_S_RUN) {
        !           749:                        /* abort TSF synchronization */
        !           750:                        RAL_WRITE(sc, RT2560_CSR14, 0);
        !           751:
        !           752:                        /* turn association led off */
        !           753:                        rt2560_update_led(sc, 0, 0);
        !           754:                }
        !           755:                break;
        !           756:
        !           757:        case IEEE80211_S_SCAN:
        !           758:                rt2560_set_chan(sc, ic->ic_bss->ni_chan);
        !           759:                timeout_add(&sc->scan_to, hz / 5);
        !           760:                break;
        !           761:
        !           762:        case IEEE80211_S_AUTH:
        !           763:                rt2560_set_chan(sc, ic->ic_bss->ni_chan);
        !           764:                break;
        !           765:
        !           766:        case IEEE80211_S_ASSOC:
        !           767:                rt2560_set_chan(sc, ic->ic_bss->ni_chan);
        !           768:                break;
        !           769:
        !           770:        case IEEE80211_S_RUN:
        !           771:                rt2560_set_chan(sc, ic->ic_bss->ni_chan);
        !           772:
        !           773:                ni = ic->ic_bss;
        !           774:
        !           775:                if (ic->ic_opmode != IEEE80211_M_MONITOR) {
        !           776:                        rt2560_update_plcp(sc);
        !           777:                        rt2560_set_slottime(sc);
        !           778:                        rt2560_set_basicrates(sc);
        !           779:                        rt2560_set_bssid(sc, ni->ni_bssid);
        !           780:                }
        !           781:
        !           782:                if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
        !           783:                    ic->ic_opmode == IEEE80211_M_IBSS) {
        !           784:                        m = ieee80211_beacon_alloc(ic, ni);
        !           785:                        if (m == NULL) {
        !           786:                                printf("%s: could not allocate beacon\n",
        !           787:                                    sc->sc_dev.dv_xname);
        !           788:                                error = ENOBUFS;
        !           789:                                break;
        !           790:                        }
        !           791:
        !           792:                        error = rt2560_tx_bcn(sc, m, ni);
        !           793:                        if (error != 0)
        !           794:                                break;
        !           795:                }
        !           796:
        !           797:                /* turn assocation led on */
        !           798:                rt2560_update_led(sc, 1, 0);
        !           799:
        !           800:                if (ic->ic_opmode == IEEE80211_M_STA) {
        !           801:                        /* fake a join to init the tx rate */
        !           802:                        rt2560_newassoc(ic, ni, 1);
        !           803:                }
        !           804:
        !           805:                if (ic->ic_opmode != IEEE80211_M_MONITOR) {
        !           806:                        /* start automatic rate control timer */
        !           807:                        if (ic->ic_fixed_rate == -1)
        !           808:                                timeout_add(&sc->amrr_to, hz / 2);
        !           809:
        !           810:                        rt2560_enable_tsf_sync(sc);
        !           811:                }
        !           812:                break;
        !           813:        }
        !           814:
        !           815:        return (error != 0) ? error : sc->sc_newstate(ic, nstate, arg);
        !           816: }
        !           817:
        !           818: /*
        !           819:  * Read 16 bits at address 'addr' from the serial EEPROM (either 93C46 or
        !           820:  * 93C66).
        !           821:  */
        !           822: uint16_t
        !           823: rt2560_eeprom_read(struct rt2560_softc *sc, uint8_t addr)
        !           824: {
        !           825:        uint32_t tmp;
        !           826:        uint16_t val;
        !           827:        int n;
        !           828:
        !           829:        /* clock C once before the first command */
        !           830:        RT2560_EEPROM_CTL(sc, 0);
        !           831:
        !           832:        RT2560_EEPROM_CTL(sc, RT2560_S);
        !           833:        RT2560_EEPROM_CTL(sc, RT2560_S | RT2560_C);
        !           834:        RT2560_EEPROM_CTL(sc, RT2560_S);
        !           835:
        !           836:        /* write start bit (1) */
        !           837:        RT2560_EEPROM_CTL(sc, RT2560_S | RT2560_D);
        !           838:        RT2560_EEPROM_CTL(sc, RT2560_S | RT2560_D | RT2560_C);
        !           839:
        !           840:        /* write READ opcode (10) */
        !           841:        RT2560_EEPROM_CTL(sc, RT2560_S | RT2560_D);
        !           842:        RT2560_EEPROM_CTL(sc, RT2560_S | RT2560_D | RT2560_C);
        !           843:        RT2560_EEPROM_CTL(sc, RT2560_S);
        !           844:        RT2560_EEPROM_CTL(sc, RT2560_S | RT2560_C);
        !           845:
        !           846:        /* write address (A5-A0 or A7-A0) */
        !           847:        n = (RAL_READ(sc, RT2560_CSR21) & RT2560_93C46) ? 5 : 7;
        !           848:        for (; n >= 0; n--) {
        !           849:                RT2560_EEPROM_CTL(sc, RT2560_S |
        !           850:                    (((addr >> n) & 1) << RT2560_SHIFT_D));
        !           851:                RT2560_EEPROM_CTL(sc, RT2560_S |
        !           852:                    (((addr >> n) & 1) << RT2560_SHIFT_D) | RT2560_C);
        !           853:        }
        !           854:
        !           855:        RT2560_EEPROM_CTL(sc, RT2560_S);
        !           856:
        !           857:        /* read data Q15-Q0 */
        !           858:        val = 0;
        !           859:        for (n = 15; n >= 0; n--) {
        !           860:                RT2560_EEPROM_CTL(sc, RT2560_S | RT2560_C);
        !           861:                tmp = RAL_READ(sc, RT2560_CSR21);
        !           862:                val |= ((tmp & RT2560_Q) >> RT2560_SHIFT_Q) << n;
        !           863:                RT2560_EEPROM_CTL(sc, RT2560_S);
        !           864:        }
        !           865:
        !           866:        RT2560_EEPROM_CTL(sc, 0);
        !           867:
        !           868:        /* clear Chip Select and clock C */
        !           869:        RT2560_EEPROM_CTL(sc, RT2560_S);
        !           870:        RT2560_EEPROM_CTL(sc, 0);
        !           871:        RT2560_EEPROM_CTL(sc, RT2560_C);
        !           872:
        !           873:        return val;
        !           874: }
        !           875:
        !           876: /*
        !           877:  * Some frames were processed by the hardware cipher engine and are ready for
        !           878:  * transmission.
        !           879:  */
        !           880: void
        !           881: rt2560_encryption_intr(struct rt2560_softc *sc)
        !           882: {
        !           883:        int hw;
        !           884:
        !           885:        /* retrieve last descriptor index processed by cipher engine */
        !           886:        hw = (RAL_READ(sc, RT2560_SECCSR1) - sc->txq.physaddr) /
        !           887:            RT2560_TX_DESC_SIZE;
        !           888:
        !           889:        for (; sc->txq.next_encrypt != hw;) {
        !           890:                struct rt2560_tx_desc *desc =
        !           891:                    &sc->txq.desc[sc->txq.next_encrypt];
        !           892:
        !           893:                bus_dmamap_sync(sc->sc_dmat, sc->txq.map,
        !           894:                    sc->txq.next_encrypt * RT2560_TX_DESC_SIZE,
        !           895:                    RT2560_TX_DESC_SIZE, BUS_DMASYNC_POSTREAD);
        !           896:
        !           897:                if (letoh32(desc->flags) &
        !           898:                    (RT2560_TX_BUSY | RT2560_TX_CIPHER_BUSY))
        !           899:                        break;
        !           900:
        !           901:                /* for TKIP, swap eiv field to fix a bug in ASIC */
        !           902:                if ((letoh32(desc->flags) & RT2560_TX_CIPHER_MASK) ==
        !           903:                    RT2560_TX_CIPHER_TKIP)
        !           904:                        desc->eiv = swap32(desc->eiv);
        !           905:
        !           906:                /* mark the frame ready for transmission */
        !           907:                desc->flags |= htole32(RT2560_TX_BUSY | RT2560_TX_VALID);
        !           908:
        !           909:                bus_dmamap_sync(sc->sc_dmat, sc->txq.map,
        !           910:                    sc->txq.next_encrypt * RT2560_TX_DESC_SIZE,
        !           911:                    RT2560_TX_DESC_SIZE, BUS_DMASYNC_PREWRITE);
        !           912:
        !           913:                DPRINTFN(15, ("encryption done idx=%u\n",
        !           914:                    sc->txq.next_encrypt));
        !           915:
        !           916:                sc->txq.next_encrypt =
        !           917:                    (sc->txq.next_encrypt + 1) % RT2560_TX_RING_COUNT;
        !           918:        }
        !           919:
        !           920:        /* kick Tx */
        !           921:        RAL_WRITE(sc, RT2560_TXCSR0, RT2560_KICK_TX);
        !           922: }
        !           923:
        !           924: void
        !           925: rt2560_tx_intr(struct rt2560_softc *sc)
        !           926: {
        !           927:        struct ieee80211com *ic = &sc->sc_ic;
        !           928:        struct ifnet *ifp = &ic->ic_if;
        !           929:
        !           930:        for (;;) {
        !           931:                struct rt2560_tx_desc *desc = &sc->txq.desc[sc->txq.next];
        !           932:                struct rt2560_tx_data *data = &sc->txq.data[sc->txq.next];
        !           933:                struct rt2560_node *rn;
        !           934:
        !           935:                bus_dmamap_sync(sc->sc_dmat, sc->txq.map,
        !           936:                    sc->txq.next * RT2560_TX_DESC_SIZE, RT2560_TX_DESC_SIZE,
        !           937:                    BUS_DMASYNC_POSTREAD);
        !           938:
        !           939:                if ((letoh32(desc->flags) & RT2560_TX_BUSY) ||
        !           940:                    (letoh32(desc->flags) & RT2560_TX_CIPHER_BUSY) ||
        !           941:                    !(letoh32(desc->flags) & RT2560_TX_VALID))
        !           942:                        break;
        !           943:
        !           944:                rn = (struct rt2560_node *)data->ni;
        !           945:
        !           946:                switch (letoh32(desc->flags) & RT2560_TX_RESULT_MASK) {
        !           947:                case RT2560_TX_SUCCESS:
        !           948:                        DPRINTFN(10, ("data frame sent successfully\n"));
        !           949:                        rn->amn.amn_txcnt++;
        !           950:                        ifp->if_opackets++;
        !           951:                        break;
        !           952:
        !           953:                case RT2560_TX_SUCCESS_RETRY:
        !           954:                        DPRINTFN(9, ("data frame sent after %u retries\n",
        !           955:                            (letoh32(desc->flags) >> 5) & 0x7));
        !           956:                        rn->amn.amn_txcnt++;
        !           957:                        rn->amn.amn_retrycnt++;
        !           958:                        ifp->if_opackets++;
        !           959:                        break;
        !           960:
        !           961:                case RT2560_TX_FAIL_RETRY:
        !           962:                        DPRINTFN(9, ("sending data frame failed (too much "
        !           963:                            "retries)\n"));
        !           964:                        rn->amn.amn_txcnt++;
        !           965:                        rn->amn.amn_retrycnt++;
        !           966:                        ifp->if_oerrors++;
        !           967:                        break;
        !           968:
        !           969:                case RT2560_TX_FAIL_INVALID:
        !           970:                case RT2560_TX_FAIL_OTHER:
        !           971:                default:
        !           972:                        printf("%s: sending data frame failed 0x%08x\n",
        !           973:                            sc->sc_dev.dv_xname, letoh32(desc->flags));
        !           974:                        ifp->if_oerrors++;
        !           975:                }
        !           976:
        !           977:                bus_dmamap_sync(sc->sc_dmat, data->map, 0,
        !           978:                    data->map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
        !           979:                bus_dmamap_unload(sc->sc_dmat, data->map);
        !           980:                m_freem(data->m);
        !           981:                data->m = NULL;
        !           982:                ieee80211_release_node(ic, data->ni);
        !           983:                data->ni = NULL;
        !           984:
        !           985:                /* descriptor is no longer valid */
        !           986:                desc->flags &= ~htole32(RT2560_TX_VALID);
        !           987:
        !           988:                bus_dmamap_sync(sc->sc_dmat, sc->txq.map,
        !           989:                    sc->txq.next * RT2560_TX_DESC_SIZE, RT2560_TX_DESC_SIZE,
        !           990:                    BUS_DMASYNC_PREWRITE);
        !           991:
        !           992:                DPRINTFN(15, ("tx done idx=%u\n", sc->txq.next));
        !           993:
        !           994:                sc->txq.queued--;
        !           995:                sc->txq.next = (sc->txq.next + 1) % RT2560_TX_RING_COUNT;
        !           996:        }
        !           997:
        !           998:        sc->sc_tx_timer = 0;
        !           999:        ifp->if_flags &= ~IFF_OACTIVE;
        !          1000:        rt2560_start(ifp);
        !          1001: }
        !          1002:
        !          1003: void
        !          1004: rt2560_prio_intr(struct rt2560_softc *sc)
        !          1005: {
        !          1006:        struct ieee80211com *ic = &sc->sc_ic;
        !          1007:        struct ifnet *ifp = &ic->ic_if;
        !          1008:
        !          1009:        for (;;) {
        !          1010:                struct rt2560_tx_desc *desc = &sc->prioq.desc[sc->prioq.next];
        !          1011:                struct rt2560_tx_data *data = &sc->prioq.data[sc->prioq.next];
        !          1012:
        !          1013:                bus_dmamap_sync(sc->sc_dmat, sc->prioq.map,
        !          1014:                    sc->prioq.next * RT2560_TX_DESC_SIZE, RT2560_TX_DESC_SIZE,
        !          1015:                    BUS_DMASYNC_POSTREAD);
        !          1016:
        !          1017:                if ((letoh32(desc->flags) & RT2560_TX_BUSY) ||
        !          1018:                    !(letoh32(desc->flags) & RT2560_TX_VALID))
        !          1019:                        break;
        !          1020:
        !          1021:                switch (letoh32(desc->flags) & RT2560_TX_RESULT_MASK) {
        !          1022:                case RT2560_TX_SUCCESS:
        !          1023:                        DPRINTFN(10, ("mgt frame sent successfully\n"));
        !          1024:                        break;
        !          1025:
        !          1026:                case RT2560_TX_SUCCESS_RETRY:
        !          1027:                        DPRINTFN(9, ("mgt frame sent after %u retries\n",
        !          1028:                            (letoh32(desc->flags) >> 5) & 0x7));
        !          1029:                        break;
        !          1030:
        !          1031:                case RT2560_TX_FAIL_RETRY:
        !          1032:                        DPRINTFN(9, ("sending mgt frame failed (too much "
        !          1033:                            "retries)\n"));
        !          1034:                        break;
        !          1035:
        !          1036:                case RT2560_TX_FAIL_INVALID:
        !          1037:                case RT2560_TX_FAIL_OTHER:
        !          1038:                default:
        !          1039:                        printf("%s: sending mgt frame failed 0x%08x\n",
        !          1040:                            sc->sc_dev.dv_xname, letoh32(desc->flags));
        !          1041:                }
        !          1042:
        !          1043:                bus_dmamap_sync(sc->sc_dmat, data->map, 0,
        !          1044:                    data->map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
        !          1045:                bus_dmamap_unload(sc->sc_dmat, data->map);
        !          1046:                m_freem(data->m);
        !          1047:                data->m = NULL;
        !          1048:                ieee80211_release_node(ic, data->ni);
        !          1049:                data->ni = NULL;
        !          1050:
        !          1051:                /* descriptor is no longer valid */
        !          1052:                desc->flags &= ~htole32(RT2560_TX_VALID);
        !          1053:
        !          1054:                bus_dmamap_sync(sc->sc_dmat, sc->prioq.map,
        !          1055:                    sc->prioq.next * RT2560_TX_DESC_SIZE, RT2560_TX_DESC_SIZE,
        !          1056:                    BUS_DMASYNC_PREWRITE);
        !          1057:
        !          1058:                DPRINTFN(15, ("prio done idx=%u\n", sc->prioq.next));
        !          1059:
        !          1060:                sc->prioq.queued--;
        !          1061:                sc->prioq.next = (sc->prioq.next + 1) % RT2560_PRIO_RING_COUNT;
        !          1062:        }
        !          1063:
        !          1064:        sc->sc_tx_timer = 0;
        !          1065:        ifp->if_flags &= ~IFF_OACTIVE;
        !          1066:        rt2560_start(ifp);
        !          1067: }
        !          1068:
        !          1069: /*
        !          1070:  * Some frames were processed by the hardware cipher engine and are ready for
        !          1071:  * transmission to the IEEE802.11 layer.
        !          1072:  */
        !          1073: void
        !          1074: rt2560_decryption_intr(struct rt2560_softc *sc)
        !          1075: {
        !          1076:        struct ieee80211com *ic = &sc->sc_ic;
        !          1077:        struct ifnet *ifp = &ic->ic_if;
        !          1078:        struct ieee80211_frame *wh;
        !          1079:        struct ieee80211_node *ni;
        !          1080:        struct mbuf *mnew, *m;
        !          1081:        int hw, error;
        !          1082:
        !          1083:        /* retrieve last decriptor index processed by cipher engine */
        !          1084:        hw = (RAL_READ(sc, RT2560_SECCSR0) - sc->rxq.physaddr) /
        !          1085:            RT2560_RX_DESC_SIZE;
        !          1086:
        !          1087:        for (; sc->rxq.cur_decrypt != hw;) {
        !          1088:                struct rt2560_rx_desc *desc =
        !          1089:                    &sc->rxq.desc[sc->rxq.cur_decrypt];
        !          1090:                struct rt2560_rx_data *data =
        !          1091:                    &sc->rxq.data[sc->rxq.cur_decrypt];
        !          1092:
        !          1093:                bus_dmamap_sync(sc->sc_dmat, sc->rxq.map,
        !          1094:                    sc->rxq.cur_decrypt * RT2560_TX_DESC_SIZE,
        !          1095:                    RT2560_TX_DESC_SIZE, BUS_DMASYNC_POSTREAD);
        !          1096:
        !          1097:                if (letoh32(desc->flags) &
        !          1098:                    (RT2560_RX_BUSY | RT2560_RX_CIPHER_BUSY))
        !          1099:                        break;
        !          1100:
        !          1101:                if (data->drop) {
        !          1102:                        ifp->if_ierrors++;
        !          1103:                        goto skip;
        !          1104:                }
        !          1105:
        !          1106:                if ((letoh32(desc->flags) & RT2560_RX_CIPHER_MASK) != 0 &&
        !          1107:                    (letoh32(desc->flags) & RT2560_RX_ICV_ERROR)) {
        !          1108:                        ifp->if_ierrors++;
        !          1109:                        goto skip;
        !          1110:                }
        !          1111:
        !          1112:                /*
        !          1113:                 * Try to allocate a new mbuf for this ring element and load it
        !          1114:                 * before processing the current mbuf.  If the ring element
        !          1115:                 * cannot be loaded, drop the received packet and reuse the old
        !          1116:                 * mbuf.  In the unlikely case that the old mbuf can't be
        !          1117:                 * reloaded either, explicitly panic.
        !          1118:                 */
        !          1119:                MGETHDR(mnew, M_DONTWAIT, MT_DATA);
        !          1120:                if (mnew == NULL) {
        !          1121:                        ifp->if_ierrors++;
        !          1122:                        goto skip;
        !          1123:                }
        !          1124:                MCLGET(mnew, M_DONTWAIT);
        !          1125:                if (!(mnew->m_flags & M_EXT)) {
        !          1126:                        m_freem(mnew);
        !          1127:                        ifp->if_ierrors++;
        !          1128:                        goto skip;
        !          1129:                }
        !          1130:
        !          1131:                bus_dmamap_sync(sc->sc_dmat, data->map, 0,
        !          1132:                    data->map->dm_mapsize, BUS_DMASYNC_POSTREAD);
        !          1133:                bus_dmamap_unload(sc->sc_dmat, data->map);
        !          1134:
        !          1135:                error = bus_dmamap_load(sc->sc_dmat, data->map,
        !          1136:                    mtod(mnew, void *), MCLBYTES, NULL, BUS_DMA_NOWAIT);
        !          1137:                if (error != 0) {
        !          1138:                        m_freem(mnew);
        !          1139:
        !          1140:                        /* try to reload the old mbuf */
        !          1141:                        error = bus_dmamap_load(sc->sc_dmat, data->map,
        !          1142:                            mtod(data->m, void *), MCLBYTES, NULL,
        !          1143:                            BUS_DMA_NOWAIT);
        !          1144:                        if (error != 0) {
        !          1145:                                /* very unlikely that it will fail... */
        !          1146:                                panic("%s: could not load old rx mbuf",
        !          1147:                                    sc->sc_dev.dv_xname);
        !          1148:                        }
        !          1149:                        ifp->if_ierrors++;
        !          1150:                        goto skip;
        !          1151:                }
        !          1152:
        !          1153:                /*
        !          1154:                 * New mbuf successfully loaded, update Rx ring and continue
        !          1155:                 * processing.
        !          1156:                 */
        !          1157:                m = data->m;
        !          1158:                data->m = mnew;
        !          1159:                desc->physaddr = htole32(data->map->dm_segs->ds_addr);
        !          1160:
        !          1161:                /* finalize mbuf */
        !          1162:                m->m_pkthdr.rcvif = ifp;
        !          1163:                m->m_pkthdr.len = m->m_len =
        !          1164:                    (letoh32(desc->flags) >> 16) & 0xfff;
        !          1165:
        !          1166: #if NBPFILTER > 0
        !          1167:                if (sc->sc_drvbpf != NULL) {
        !          1168:                        struct mbuf mb;
        !          1169:                        struct rt2560_rx_radiotap_header *tap = &sc->sc_rxtap;
        !          1170:                        uint32_t tsf_lo, tsf_hi;
        !          1171:
        !          1172:                        /* get timestamp (low and high 32 bits) */
        !          1173:                        tsf_hi = RAL_READ(sc, RT2560_CSR17);
        !          1174:                        tsf_lo = RAL_READ(sc, RT2560_CSR16);
        !          1175:
        !          1176:                        tap->wr_tsf =
        !          1177:                            htole64(((uint64_t)tsf_hi << 32) | tsf_lo);
        !          1178:                        tap->wr_flags = 0;
        !          1179:                        tap->wr_rate = rt2560_rxrate(desc);
        !          1180:                        tap->wr_chan_freq = htole16(ic->ic_ibss_chan->ic_freq);
        !          1181:                        tap->wr_chan_flags =
        !          1182:                            htole16(ic->ic_ibss_chan->ic_flags);
        !          1183:                        tap->wr_antenna = sc->rx_ant;
        !          1184:                        tap->wr_antsignal = desc->rssi;
        !          1185:
        !          1186:                        mb.m_data = (caddr_t)tap;
        !          1187:                        mb.m_len = sc->sc_txtap_len;
        !          1188:                        mb.m_next = m;
        !          1189:                        mb.m_nextpkt = NULL;
        !          1190:                        mb.m_type = 0;
        !          1191:                        mb.m_flags = 0;
        !          1192:                        bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_IN);
        !          1193:                }
        !          1194: #endif
        !          1195:                wh = mtod(m, struct ieee80211_frame *);
        !          1196:                ni = ieee80211_find_rxnode(ic, wh);
        !          1197:
        !          1198:                /* send the frame to the 802.11 layer */
        !          1199:                ieee80211_input(ifp, m, ni, desc->rssi, 0);
        !          1200:
        !          1201:                /* node is no longer needed */
        !          1202:                ieee80211_release_node(ic, ni);
        !          1203:
        !          1204: skip:          desc->flags = htole32(RT2560_RX_BUSY);
        !          1205:
        !          1206:                bus_dmamap_sync(sc->sc_dmat, sc->rxq.map,
        !          1207:                    sc->rxq.cur_decrypt * RT2560_TX_DESC_SIZE,
        !          1208:                    RT2560_TX_DESC_SIZE, BUS_DMASYNC_PREWRITE);
        !          1209:
        !          1210:                DPRINTFN(15, ("decryption done idx=%u\n", sc->rxq.cur_decrypt));
        !          1211:
        !          1212:                sc->rxq.cur_decrypt =
        !          1213:                    (sc->rxq.cur_decrypt + 1) % RT2560_RX_RING_COUNT;
        !          1214:        }
        !          1215:
        !          1216:        /*
        !          1217:         * In HostAP mode, ieee80211_input() will enqueue packets in if_snd
        !          1218:         * without calling if_start().
        !          1219:         */
        !          1220:        if (!IFQ_IS_EMPTY(&ifp->if_snd) && !(ifp->if_flags & IFF_OACTIVE))
        !          1221:                rt2560_start(ifp);
        !          1222: }
        !          1223:
        !          1224: /*
        !          1225:  * Some frames were received. Pass them to the hardware cipher engine before
        !          1226:  * sending them to the 802.11 layer.
        !          1227:  */
        !          1228: void
        !          1229: rt2560_rx_intr(struct rt2560_softc *sc)
        !          1230: {
        !          1231:        for (;;) {
        !          1232:                struct rt2560_rx_desc *desc = &sc->rxq.desc[sc->rxq.cur];
        !          1233:                struct rt2560_rx_data *data = &sc->rxq.data[sc->rxq.cur];
        !          1234:
        !          1235:                bus_dmamap_sync(sc->sc_dmat, sc->rxq.map,
        !          1236:                    sc->rxq.cur * RT2560_RX_DESC_SIZE, RT2560_RX_DESC_SIZE,
        !          1237:                    BUS_DMASYNC_POSTREAD);
        !          1238:
        !          1239:                if (letoh32(desc->flags) &
        !          1240:                    (RT2560_RX_BUSY | RT2560_RX_CIPHER_BUSY))
        !          1241:                        break;
        !          1242:
        !          1243:                data->drop = 0;
        !          1244:
        !          1245:                if (letoh32(desc->flags) &
        !          1246:                    (RT2560_RX_PHY_ERROR | RT2560_RX_CRC_ERROR)) {
        !          1247:                        /*
        !          1248:                         * This should not happen since we did not request
        !          1249:                         * to receive those frames when we filled RXCSR0.
        !          1250:                         */
        !          1251:                        DPRINTFN(5, ("PHY or CRC error flags 0x%08x\n",
        !          1252:                            letoh32(desc->flags)));
        !          1253:                        data->drop = 1;
        !          1254:                }
        !          1255:
        !          1256:                if (((letoh32(desc->flags) >> 16) & 0xfff) > MCLBYTES) {
        !          1257:                        DPRINTFN(5, ("bad length\n"));
        !          1258:                        data->drop = 1;
        !          1259:                }
        !          1260:
        !          1261:                /* mark the frame for decryption */
        !          1262:                desc->flags |= htole32(RT2560_RX_CIPHER_BUSY);
        !          1263:
        !          1264:                bus_dmamap_sync(sc->sc_dmat, sc->rxq.map,
        !          1265:                    sc->rxq.cur * RT2560_RX_DESC_SIZE, RT2560_RX_DESC_SIZE,
        !          1266:                    BUS_DMASYNC_PREWRITE);
        !          1267:
        !          1268:                DPRINTFN(15, ("rx done idx=%u\n", sc->rxq.cur));
        !          1269:
        !          1270:                sc->rxq.cur = (sc->rxq.cur + 1) % RT2560_RX_RING_COUNT;
        !          1271:        }
        !          1272:
        !          1273:        /* kick decrypt */
        !          1274:        RAL_WRITE(sc, RT2560_SECCSR0, RT2560_KICK_DECRYPT);
        !          1275: }
        !          1276:
        !          1277: /*
        !          1278:  * This function is called in HostAP or IBSS modes when it's time to send a
        !          1279:  * new beacon (every ni_intval milliseconds).
        !          1280:  */
        !          1281: void
        !          1282: rt2560_beacon_expire(struct rt2560_softc *sc)
        !          1283: {
        !          1284:        struct ieee80211com *ic = &sc->sc_ic;
        !          1285:        struct rt2560_tx_data *data;
        !          1286:
        !          1287:        if (ic->ic_opmode != IEEE80211_M_IBSS &&
        !          1288:            ic->ic_opmode != IEEE80211_M_HOSTAP)
        !          1289:                return;
        !          1290:
        !          1291:        data = &sc->bcnq.data[sc->bcnq.next];
        !          1292:
        !          1293:        if (sc->sc_flags & RT2560_UPDATE_SLOT) {
        !          1294:                sc->sc_flags &= ~RT2560_UPDATE_SLOT;
        !          1295:                sc->sc_flags |= RT2560_SET_SLOTTIME;
        !          1296:        } else if (sc->sc_flags & RT2560_SET_SLOTTIME) {
        !          1297:                sc->sc_flags &= ~RT2560_SET_SLOTTIME;
        !          1298:                rt2560_set_slottime(sc);
        !          1299:        }
        !          1300:
        !          1301:        if (ic->ic_curmode == IEEE80211_MODE_11G) {
        !          1302:                /* update ERP Information Element */
        !          1303:                *sc->erp = ic->ic_bss->ni_erp;
        !          1304:                bus_dmamap_sync(sc->sc_dmat, data->map, 0,
        !          1305:                    data->map->dm_mapsize, BUS_DMASYNC_PREWRITE);
        !          1306:        }
        !          1307:
        !          1308: #if defined(RT2560_DEBUG) && NBPFILTER > 0
        !          1309:        if (ic->ic_rawbpf != NULL)
        !          1310:                bpf_mtap(ic->ic_rawbpf, data->m, BPF_DIRECTION_OUT);
        !          1311: #endif
        !          1312:
        !          1313:        DPRINTFN(15, ("beacon expired\n"));
        !          1314: }
        !          1315:
        !          1316: void
        !          1317: rt2560_wakeup_expire(struct rt2560_softc *sc)
        !          1318: {
        !          1319:        DPRINTFN(15, ("wakeup expired\n"));
        !          1320: }
        !          1321:
        !          1322: int
        !          1323: rt2560_intr(void *arg)
        !          1324: {
        !          1325:        struct rt2560_softc *sc = arg;
        !          1326:        struct ifnet *ifp = &sc->sc_ic.ic_if;
        !          1327:        uint32_t r;
        !          1328:
        !          1329:        if ((r = RAL_READ(sc, RT2560_CSR7)) == 0)
        !          1330:                return 0;       /* not for us */
        !          1331:
        !          1332:        /* disable interrupts */
        !          1333:        RAL_WRITE(sc, RT2560_CSR8, 0xffffffff);
        !          1334:
        !          1335:        /* acknowledge interrupts */
        !          1336:        RAL_WRITE(sc, RT2560_CSR7, r);
        !          1337:
        !          1338:        /* don't re-enable interrupts if we're shutting down */
        !          1339:        if (!(ifp->if_flags & IFF_RUNNING))
        !          1340:                return 0;
        !          1341:
        !          1342:        if (r & RT2560_BEACON_EXPIRE)
        !          1343:                rt2560_beacon_expire(sc);
        !          1344:
        !          1345:        if (r & RT2560_WAKEUP_EXPIRE)
        !          1346:                rt2560_wakeup_expire(sc);
        !          1347:
        !          1348:        if (r & RT2560_ENCRYPTION_DONE)
        !          1349:                rt2560_encryption_intr(sc);
        !          1350:
        !          1351:        if (r & RT2560_TX_DONE)
        !          1352:                rt2560_tx_intr(sc);
        !          1353:
        !          1354:        if (r & RT2560_PRIO_DONE)
        !          1355:                rt2560_prio_intr(sc);
        !          1356:
        !          1357:        if (r & RT2560_DECRYPTION_DONE)
        !          1358:                rt2560_decryption_intr(sc);
        !          1359:
        !          1360:        if (r & RT2560_RX_DONE)
        !          1361:                rt2560_rx_intr(sc);
        !          1362:
        !          1363:        /* re-enable interrupts */
        !          1364:        RAL_WRITE(sc, RT2560_CSR8, RT2560_INTR_MASK);
        !          1365:
        !          1366:        return 1;
        !          1367: }
        !          1368:
        !          1369: /* quickly determine if a given rate is CCK or OFDM */
        !          1370: #define RAL_RATE_IS_OFDM(rate) ((rate) >= 12 && (rate) != 22)
        !          1371:
        !          1372: #define RAL_ACK_SIZE   14      /* 10 + 4(FCS) */
        !          1373: #define RAL_CTS_SIZE   14      /* 10 + 4(FCS) */
        !          1374:
        !          1375: #define RAL_SIFS               10      /* us */
        !          1376:
        !          1377: #define RT2560_RXTX_TURNAROUND 10      /* us */
        !          1378:
        !          1379: /*
        !          1380:  * This function is only used by the Rx radiotap code. It returns the rate at
        !          1381:  * which a given frame was received.
        !          1382:  */
        !          1383: #if NBPFILTER > 0
        !          1384: uint8_t
        !          1385: rt2560_rxrate(const struct rt2560_rx_desc *desc)
        !          1386: {
        !          1387:        if (letoh32(desc->flags) & RT2560_RX_OFDM) {
        !          1388:                /* reverse function of rt2560_plcp_signal */
        !          1389:                switch (desc->rate) {
        !          1390:                case 0xb:       return 12;
        !          1391:                case 0xf:       return 18;
        !          1392:                case 0xa:       return 24;
        !          1393:                case 0xe:       return 36;
        !          1394:                case 0x9:       return 48;
        !          1395:                case 0xd:       return 72;
        !          1396:                case 0x8:       return 96;
        !          1397:                case 0xc:       return 108;
        !          1398:                }
        !          1399:        } else {
        !          1400:                if (desc->rate == 10)
        !          1401:                        return 2;
        !          1402:                if (desc->rate == 20)
        !          1403:                        return 4;
        !          1404:                if (desc->rate == 55)
        !          1405:                        return 11;
        !          1406:                if (desc->rate == 110)
        !          1407:                        return 22;
        !          1408:        }
        !          1409:        return 2;       /* should not get there */
        !          1410: }
        !          1411: #endif
        !          1412:
        !          1413: /*
        !          1414:  * Return the expected ack rate for a frame transmitted at rate `rate'.
        !          1415:  */
        !          1416: int
        !          1417: rt2560_ack_rate(struct ieee80211com *ic, int rate)
        !          1418: {
        !          1419:        switch (rate) {
        !          1420:        /* CCK rates */
        !          1421:        case 2:
        !          1422:                return 2;
        !          1423:        case 4:
        !          1424:        case 11:
        !          1425:        case 22:
        !          1426:                return (ic->ic_curmode == IEEE80211_MODE_11B) ? 4 : rate;
        !          1427:
        !          1428:        /* OFDM rates */
        !          1429:        case 12:
        !          1430:        case 18:
        !          1431:                return 12;
        !          1432:        case 24:
        !          1433:        case 36:
        !          1434:                return 24;
        !          1435:        case 48:
        !          1436:        case 72:
        !          1437:        case 96:
        !          1438:        case 108:
        !          1439:                return 48;
        !          1440:        }
        !          1441:
        !          1442:        /* default to 1Mbps */
        !          1443:        return 2;
        !          1444: }
        !          1445:
        !          1446: /*
        !          1447:  * Compute the duration (in us) needed to transmit `len' bytes at rate `rate'.
        !          1448:  * The function automatically determines the operating mode depending on the
        !          1449:  * given rate. `flags' indicates whether short preamble is in use or not.
        !          1450:  */
        !          1451: uint16_t
        !          1452: rt2560_txtime(int len, int rate, uint32_t flags)
        !          1453: {
        !          1454:        uint16_t txtime;
        !          1455:
        !          1456:        if (RAL_RATE_IS_OFDM(rate)) {
        !          1457:                /* IEEE Std 802.11g-2003, pp. 44 */
        !          1458:                txtime = (8 + 4 * len + 3 + rate - 1) / rate;
        !          1459:                txtime = 16 + 4 + 4 * txtime + 6;
        !          1460:        } else {
        !          1461:                /* IEEE Std 802.11b-1999, pp. 28 */
        !          1462:                txtime = (16 * len + rate - 1) / rate;
        !          1463:                if (rate != 2 && (flags & IEEE80211_F_SHPREAMBLE))
        !          1464:                        txtime +=  72 + 24;
        !          1465:                else
        !          1466:                        txtime += 144 + 48;
        !          1467:        }
        !          1468:        return txtime;
        !          1469: }
        !          1470:
        !          1471: uint8_t
        !          1472: rt2560_plcp_signal(int rate)
        !          1473: {
        !          1474:        switch (rate) {
        !          1475:        /* CCK rates (returned values are device-dependent) */
        !          1476:        case 2:         return 0x0;
        !          1477:        case 4:         return 0x1;
        !          1478:        case 11:        return 0x2;
        !          1479:        case 22:        return 0x3;
        !          1480:
        !          1481:        /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
        !          1482:        case 12:        return 0xb;
        !          1483:        case 18:        return 0xf;
        !          1484:        case 24:        return 0xa;
        !          1485:        case 36:        return 0xe;
        !          1486:        case 48:        return 0x9;
        !          1487:        case 72:        return 0xd;
        !          1488:        case 96:        return 0x8;
        !          1489:        case 108:       return 0xc;
        !          1490:
        !          1491:        /* unsupported rates (should not get there) */
        !          1492:        default:        return 0xff;
        !          1493:        }
        !          1494: }
        !          1495:
        !          1496: void
        !          1497: rt2560_setup_tx_desc(struct rt2560_softc *sc, struct rt2560_tx_desc *desc,
        !          1498:     uint32_t flags, int len, int rate, int encrypt, bus_addr_t physaddr)
        !          1499: {
        !          1500:        struct ieee80211com *ic = &sc->sc_ic;
        !          1501:        uint16_t plcp_length;
        !          1502:        int remainder;
        !          1503:
        !          1504:        desc->flags = htole32(flags);
        !          1505:        desc->flags |= htole32(len << 16);
        !          1506:        desc->flags |= encrypt ? htole32(RT2560_TX_CIPHER_BUSY) :
        !          1507:            htole32(RT2560_TX_BUSY | RT2560_TX_VALID);
        !          1508:
        !          1509:        desc->physaddr = htole32(physaddr);
        !          1510:        desc->wme = htole16(
        !          1511:            RT2560_AIFSN(2) |
        !          1512:            RT2560_LOGCWMIN(3) |
        !          1513:            RT2560_LOGCWMAX(8));
        !          1514:
        !          1515:        /* setup PLCP fields */
        !          1516:        desc->plcp_signal  = rt2560_plcp_signal(rate);
        !          1517:        desc->plcp_service = 4;
        !          1518:
        !          1519:        len += IEEE80211_CRC_LEN;
        !          1520:        if (RAL_RATE_IS_OFDM(rate)) {
        !          1521:                desc->flags |= htole32(RT2560_TX_OFDM);
        !          1522:
        !          1523:                plcp_length = len & 0xfff;
        !          1524:                desc->plcp_length_hi = plcp_length >> 6;
        !          1525:                desc->plcp_length_lo = plcp_length & 0x3f;
        !          1526:        } else {
        !          1527:                plcp_length = (16 * len + rate - 1) / rate;
        !          1528:                if (rate == 22) {
        !          1529:                        remainder = (16 * len) % 22;
        !          1530:                        if (remainder != 0 && remainder < 7)
        !          1531:                                desc->plcp_service |= RT2560_PLCP_LENGEXT;
        !          1532:                }
        !          1533:                desc->plcp_length_hi = plcp_length >> 8;
        !          1534:                desc->plcp_length_lo = plcp_length & 0xff;
        !          1535:
        !          1536:                if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
        !          1537:                        desc->plcp_signal |= 0x08;
        !          1538:        }
        !          1539: }
        !          1540:
        !          1541: int
        !          1542: rt2560_tx_bcn(struct rt2560_softc *sc, struct mbuf *m0,
        !          1543:     struct ieee80211_node *ni)
        !          1544: {
        !          1545:        struct ieee80211com *ic = &sc->sc_ic;
        !          1546:        struct rt2560_tx_desc *desc;
        !          1547:        struct rt2560_tx_data *data;
        !          1548:        int rate = 2, error;
        !          1549:
        !          1550:        desc = &sc->bcnq.desc[sc->bcnq.cur];
        !          1551:        data = &sc->bcnq.data[sc->bcnq.cur];
        !          1552:
        !          1553:        error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m0,
        !          1554:            BUS_DMA_NOWAIT);
        !          1555:        if (error != 0) {
        !          1556:                printf("%s: could not map mbuf (error %d)\n",
        !          1557:                    sc->sc_dev.dv_xname, error);
        !          1558:                m_freem(m0);
        !          1559:                return error;
        !          1560:        }
        !          1561:
        !          1562:        data->m = m0;
        !          1563:        data->ni = ni;
        !          1564:
        !          1565:        rt2560_setup_tx_desc(sc, desc, RT2560_TX_IFS_NEWBACKOFF |
        !          1566:            RT2560_TX_TIMESTAMP, m0->m_pkthdr.len, rate, 0,
        !          1567:            data->map->dm_segs->ds_addr);
        !          1568:
        !          1569:        bus_dmamap_sync(sc->sc_dmat, data->map, 0, data->map->dm_mapsize,
        !          1570:            BUS_DMASYNC_PREWRITE);
        !          1571:        bus_dmamap_sync(sc->sc_dmat, sc->bcnq.map,
        !          1572:            sc->bcnq.cur * RT2560_TX_DESC_SIZE, RT2560_TX_DESC_SIZE,
        !          1573:            BUS_DMASYNC_PREWRITE);
        !          1574:
        !          1575:        /*
        !          1576:         * Store pointer to ERP Information Element so that we can update it
        !          1577:         * dynamically when the slot time changes.
        !          1578:         * XXX: this is ugly since it depends on how net80211 builds beacon
        !          1579:         * frames but ieee80211_beacon_alloc() don't store offsets for us.
        !          1580:         */
        !          1581:        if (ic->ic_curmode == IEEE80211_MODE_11G) {
        !          1582:                sc->erp =
        !          1583:                    mtod(m0, uint8_t *) +
        !          1584:                    sizeof (struct ieee80211_frame) +
        !          1585:                    8 + 2 + 2 +
        !          1586:                    ((ic->ic_flags & IEEE80211_F_HIDENWID) ?
        !          1587:                        1 : 2 + ni->ni_esslen) +
        !          1588:                    2 + min(ni->ni_rates.rs_nrates, IEEE80211_RATE_SIZE) +
        !          1589:                    2 + 1 +
        !          1590:                    ((ic->ic_opmode == IEEE80211_M_IBSS) ? 4 : 6) +
        !          1591:                    2;
        !          1592:        }
        !          1593:
        !          1594:        return 0;
        !          1595: }
        !          1596:
        !          1597: int
        !          1598: rt2560_tx_mgt(struct rt2560_softc *sc, struct mbuf *m0,
        !          1599:     struct ieee80211_node *ni)
        !          1600: {
        !          1601:        struct ieee80211com *ic = &sc->sc_ic;
        !          1602:        struct ifnet *ifp = &ic->ic_if;
        !          1603:        struct rt2560_tx_desc *desc;
        !          1604:        struct rt2560_tx_data *data;
        !          1605:        struct ieee80211_frame *wh;
        !          1606:        uint16_t dur;
        !          1607:        uint32_t flags = 0;
        !          1608:        int rate = 2, error;
        !          1609:
        !          1610:        desc = &sc->prioq.desc[sc->prioq.cur];
        !          1611:        data = &sc->prioq.data[sc->prioq.cur];
        !          1612:
        !          1613:        wh = mtod(m0, struct ieee80211_frame *);
        !          1614:
        !          1615:        if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
        !          1616:                m0 = ieee80211_wep_crypt(ifp, m0, 1);
        !          1617:                if (m0 == NULL)
        !          1618:                        return ENOBUFS;
        !          1619:
        !          1620:                /* packet header may have moved, reset our local pointer */
        !          1621:                wh = mtod(m0, struct ieee80211_frame *);
        !          1622:        }
        !          1623:
        !          1624:        error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m0,
        !          1625:            BUS_DMA_NOWAIT);
        !          1626:        if (error != 0) {
        !          1627:                printf("%s: could not map mbuf (error %d)\n",
        !          1628:                    sc->sc_dev.dv_xname, error);
        !          1629:                m_freem(m0);
        !          1630:                return error;
        !          1631:        }
        !          1632:
        !          1633: #if NBPFILTER > 0
        !          1634:        if (sc->sc_drvbpf != NULL) {
        !          1635:                struct mbuf mb;
        !          1636:                struct rt2560_tx_radiotap_header *tap = &sc->sc_txtap;
        !          1637:
        !          1638:                tap->wt_flags = 0;
        !          1639:                tap->wt_rate = rate;
        !          1640:                tap->wt_chan_freq = htole16(ic->ic_ibss_chan->ic_freq);
        !          1641:                tap->wt_chan_flags = htole16(ic->ic_ibss_chan->ic_flags);
        !          1642:                tap->wt_antenna = sc->tx_ant;
        !          1643:
        !          1644:                mb.m_data = (caddr_t)tap;
        !          1645:                mb.m_len = sc->sc_txtap_len;
        !          1646:                mb.m_next = m0;
        !          1647:                mb.m_nextpkt = NULL;
        !          1648:                mb.m_type = 0;
        !          1649:                mb.m_flags = 0;
        !          1650:                bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_OUT);
        !          1651:        }
        !          1652: #endif
        !          1653:
        !          1654:        data->m = m0;
        !          1655:        data->ni = ni;
        !          1656:
        !          1657:        wh = mtod(m0, struct ieee80211_frame *);
        !          1658:
        !          1659:        if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
        !          1660:                flags |= RT2560_TX_NEED_ACK;
        !          1661:
        !          1662:                dur = rt2560_txtime(RAL_ACK_SIZE, rate, ic->ic_flags) +
        !          1663:                    RAL_SIFS;
        !          1664:                *(uint16_t *)wh->i_dur = htole16(dur);
        !          1665:
        !          1666:                /* tell hardware to set timestamp for probe responses */
        !          1667:                if ((wh->i_fc[0] &
        !          1668:                    (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==
        !          1669:                    (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_RESP))
        !          1670:                        flags |= RT2560_TX_TIMESTAMP;
        !          1671:        }
        !          1672:
        !          1673:        rt2560_setup_tx_desc(sc, desc, flags, m0->m_pkthdr.len, rate, 0,
        !          1674:            data->map->dm_segs->ds_addr);
        !          1675:
        !          1676:        bus_dmamap_sync(sc->sc_dmat, data->map, 0, data->map->dm_mapsize,
        !          1677:            BUS_DMASYNC_PREWRITE);
        !          1678:        bus_dmamap_sync(sc->sc_dmat, sc->prioq.map,
        !          1679:            sc->prioq.cur * RT2560_TX_DESC_SIZE, RT2560_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->prioq.cur, rate));
        !          1684:
        !          1685:        /* kick prio */
        !          1686:        sc->prioq.queued++;
        !          1687:        sc->prioq.cur = (sc->prioq.cur + 1) % RT2560_PRIO_RING_COUNT;
        !          1688:        RAL_WRITE(sc, RT2560_TXCSR0, RT2560_KICK_PRIO);
        !          1689:
        !          1690:        return 0;
        !          1691: }
        !          1692:
        !          1693: int
        !          1694: rt2560_tx_data(struct rt2560_softc *sc, struct mbuf *m0,
        !          1695:     struct ieee80211_node *ni)
        !          1696: {
        !          1697:        struct ieee80211com *ic = &sc->sc_ic;
        !          1698:        struct ifnet *ifp = &ic->ic_if;
        !          1699:        struct rt2560_tx_ring *txq = &sc->txq;
        !          1700:        struct rt2560_tx_desc *desc;
        !          1701:        struct rt2560_tx_data *data;
        !          1702:        struct ieee80211_frame *wh;
        !          1703:        struct mbuf *mnew;
        !          1704:        uint16_t dur;
        !          1705:        uint32_t flags = 0;
        !          1706:        int pktlen, rate, needcts = 0, needrts = 0, error;
        !          1707:
        !          1708:        wh = mtod(m0, struct ieee80211_frame *);
        !          1709:
        !          1710:        if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
        !          1711:                m0 = ieee80211_wep_crypt(ifp, m0, 1);
        !          1712:                if (m0 == NULL)
        !          1713:                        return ENOBUFS;
        !          1714:
        !          1715:                /* packet header may have moved, reset our local pointer */
        !          1716:                wh = mtod(m0, struct ieee80211_frame *);
        !          1717:        }
        !          1718:
        !          1719:        /* compute actual packet length (including CRC and crypto overhead) */
        !          1720:        pktlen = m0->m_pkthdr.len + IEEE80211_CRC_LEN;
        !          1721:
        !          1722:        /* pickup a rate */
        !          1723:        if (IEEE80211_IS_MULTICAST(wh->i_addr1) ||
        !          1724:            ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
        !          1725:             IEEE80211_FC0_TYPE_MGT)) {
        !          1726:                /* mgmt/multicast frames are sent at the lowest avail. rate */
        !          1727:                rate = ni->ni_rates.rs_rates[0];
        !          1728:        } else if (ic->ic_fixed_rate != -1) {
        !          1729:                rate = ic->ic_sup_rates[ic->ic_curmode].
        !          1730:                    rs_rates[ic->ic_fixed_rate];
        !          1731:        } else
        !          1732:                rate = ni->ni_rates.rs_rates[ni->ni_txrate];
        !          1733:        if (rate == 0)
        !          1734:                rate = 2;       /* XXX should not happen */
        !          1735:        rate &= IEEE80211_RATE_VAL;
        !          1736:
        !          1737:        /*
        !          1738:         * Packet Bursting: backoff after ppb=8 frames to give other STAs a
        !          1739:         * chance to contend for the wireless medium.
        !          1740:         */
        !          1741:        if (ic->ic_opmode == IEEE80211_M_STA && (ni->ni_txseq & 7))
        !          1742:                flags |= RT2560_TX_IFS_SIFS;
        !          1743:
        !          1744:        /* check if RTS/CTS or CTS-to-self protection must be used */
        !          1745:        if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
        !          1746:                /* multicast frames are not sent at OFDM rates in 802.11b/g */
        !          1747:                if (pktlen > ic->ic_rtsthreshold) {
        !          1748:                        needrts = 1;    /* RTS/CTS based on frame length */
        !          1749:                } else if ((ic->ic_flags & IEEE80211_F_USEPROT) &&
        !          1750:                    RAL_RATE_IS_OFDM(rate)) {
        !          1751:                        if (ic->ic_protmode == IEEE80211_PROT_CTSONLY)
        !          1752:                                needcts = 1;    /* CTS-to-self */
        !          1753:                        else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
        !          1754:                                needrts = 1;    /* RTS/CTS */
        !          1755:                }
        !          1756:        }
        !          1757:        if (needrts || needcts) {
        !          1758:                struct mbuf *mprot;
        !          1759:                int protrate, ackrate;
        !          1760:                uint16_t dur;
        !          1761:
        !          1762:                protrate = 2;   /* XXX */
        !          1763:                ackrate  = rt2560_ack_rate(ic, rate);
        !          1764:
        !          1765:                dur = rt2560_txtime(pktlen, rate, ic->ic_flags) +
        !          1766:                      rt2560_txtime(RAL_ACK_SIZE, ackrate, ic->ic_flags) +
        !          1767:                      2 * RAL_SIFS;
        !          1768:                if (needrts) {
        !          1769:                        dur += rt2560_txtime(RAL_CTS_SIZE, rt2560_ack_rate(ic,
        !          1770:                            protrate), ic->ic_flags) + RAL_SIFS;
        !          1771:                        mprot = ieee80211_get_rts(ic, wh, dur);
        !          1772:                } else {
        !          1773:                        mprot = ieee80211_get_cts_to_self(ic, dur);
        !          1774:                }
        !          1775:                if (mprot == NULL) {
        !          1776:                        printf("%s: could not allocate protection frame\n",
        !          1777:                            sc->sc_dev.dv_xname);
        !          1778:                        m_freem(m0);
        !          1779:                        return ENOBUFS;
        !          1780:                }
        !          1781:
        !          1782:                desc = &txq->desc[txq->cur_encrypt];
        !          1783:                data = &txq->data[txq->cur_encrypt];
        !          1784:
        !          1785:                error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, mprot,
        !          1786:                    BUS_DMA_NOWAIT);
        !          1787:                if (error != 0) {
        !          1788:                        printf("%s: could not map mbuf (error %d)\n",
        !          1789:                            sc->sc_dev.dv_xname, error);
        !          1790:                        m_freem(mprot);
        !          1791:                        m_freem(m0);
        !          1792:                        return error;
        !          1793:                }
        !          1794:
        !          1795:                data->m = mprot;
        !          1796:                /* avoid multiple free() of the same node for each fragment */
        !          1797:                data->ni = ieee80211_ref_node(ni);
        !          1798:
        !          1799:                /* XXX may want to pass the protection frame to BPF */
        !          1800:
        !          1801:                rt2560_setup_tx_desc(sc, desc,
        !          1802:                    (needrts ? RT2560_TX_NEED_ACK : 0) | RT2560_TX_MORE_FRAG,
        !          1803:                    mprot->m_pkthdr.len, protrate, 1,
        !          1804:                    data->map->dm_segs->ds_addr);
        !          1805:
        !          1806:                bus_dmamap_sync(sc->sc_dmat, data->map, 0,
        !          1807:                    data->map->dm_mapsize, BUS_DMASYNC_PREWRITE);
        !          1808:                bus_dmamap_sync(sc->sc_dmat, txq->map,
        !          1809:                    txq->cur_encrypt * RT2560_TX_DESC_SIZE,
        !          1810:                    RT2560_TX_DESC_SIZE, BUS_DMASYNC_PREWRITE);
        !          1811:
        !          1812:                txq->queued++;
        !          1813:                if (++txq->cur_encrypt >= txq->count)
        !          1814:                        txq->cur_encrypt = 0;
        !          1815:
        !          1816:                flags |= RT2560_TX_LONG_RETRY | RT2560_TX_IFS_SIFS;
        !          1817:        }
        !          1818:
        !          1819:        data = &txq->data[txq->cur_encrypt];
        !          1820:        desc = &txq->desc[txq->cur_encrypt];
        !          1821:
        !          1822:        error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m0,
        !          1823:            BUS_DMA_NOWAIT);
        !          1824:        if (error != 0 && error != EFBIG) {
        !          1825:                printf("%s: could not map mbuf (error %d)\n",
        !          1826:                    sc->sc_dev.dv_xname, error);
        !          1827:                m_freem(m0);
        !          1828:                return error;
        !          1829:        }
        !          1830:        if (error != 0) {
        !          1831:                /* too many fragments, linearize */
        !          1832:
        !          1833:                MGETHDR(mnew, M_DONTWAIT, MT_DATA);
        !          1834:                if (mnew == NULL) {
        !          1835:                        m_freem(m0);
        !          1836:                        return ENOMEM;
        !          1837:                }
        !          1838:                M_DUP_PKTHDR(mnew, m0);
        !          1839:                if (m0->m_pkthdr.len > MHLEN) {
        !          1840:                        MCLGET(mnew, M_DONTWAIT);
        !          1841:                        if (!(mnew->m_flags & M_EXT)) {
        !          1842:                                m_freem(m0);
        !          1843:                                m_freem(mnew);
        !          1844:                                return ENOMEM;
        !          1845:                        }
        !          1846:                }
        !          1847:
        !          1848:                m_copydata(m0, 0, m0->m_pkthdr.len, mtod(mnew, caddr_t));
        !          1849:                m_freem(m0);
        !          1850:                mnew->m_len = mnew->m_pkthdr.len;
        !          1851:                m0 = mnew;
        !          1852:
        !          1853:                error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m0,
        !          1854:                    BUS_DMA_NOWAIT);
        !          1855:                if (error != 0) {
        !          1856:                        printf("%s: could not map mbuf (error %d)\n",
        !          1857:                            sc->sc_dev.dv_xname, error);
        !          1858:                        m_freem(m0);
        !          1859:                        return error;
        !          1860:                }
        !          1861:
        !          1862:                /* packet header have moved, reset our local pointer */
        !          1863:                wh = mtod(m0, struct ieee80211_frame *);
        !          1864:        }
        !          1865:
        !          1866: #if NBPFILTER > 0
        !          1867:        if (sc->sc_drvbpf != NULL) {
        !          1868:                struct mbuf mb;
        !          1869:                struct rt2560_tx_radiotap_header *tap = &sc->sc_txtap;
        !          1870:
        !          1871:                tap->wt_flags = 0;
        !          1872:                tap->wt_rate = rate;
        !          1873:                tap->wt_chan_freq = htole16(ic->ic_ibss_chan->ic_freq);
        !          1874:                tap->wt_chan_flags = htole16(ic->ic_ibss_chan->ic_flags);
        !          1875:                tap->wt_antenna = sc->tx_ant;
        !          1876:
        !          1877:                mb.m_data = (caddr_t)tap;
        !          1878:                mb.m_len = sc->sc_txtap_len;
        !          1879:                mb.m_next = m0;
        !          1880:                mb.m_nextpkt = NULL;
        !          1881:                mb.m_type = 0;
        !          1882:                mb.m_flags = 0;
        !          1883:                bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_OUT);
        !          1884:        }
        !          1885: #endif
        !          1886:
        !          1887:        data->m = m0;
        !          1888:        data->ni = ni;
        !          1889:
        !          1890:        if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
        !          1891:                flags |= RT2560_TX_NEED_ACK;
        !          1892:
        !          1893:                dur = rt2560_txtime(RAL_ACK_SIZE, rt2560_ack_rate(ic, rate),
        !          1894:                    ic->ic_flags) + RAL_SIFS;
        !          1895:                *(uint16_t *)wh->i_dur = htole16(dur);
        !          1896:        }
        !          1897:
        !          1898:        rt2560_setup_tx_desc(sc, desc, flags, m0->m_pkthdr.len, rate, 1,
        !          1899:            data->map->dm_segs->ds_addr);
        !          1900:
        !          1901:        bus_dmamap_sync(sc->sc_dmat, data->map, 0, data->map->dm_mapsize,
        !          1902:            BUS_DMASYNC_PREWRITE);
        !          1903:        bus_dmamap_sync(sc->sc_dmat, txq->map,
        !          1904:            txq->cur_encrypt * RT2560_TX_DESC_SIZE, RT2560_TX_DESC_SIZE,
        !          1905:            BUS_DMASYNC_PREWRITE);
        !          1906:
        !          1907:        DPRINTFN(10, ("sending frame len=%u idx=%u rate=%u\n",
        !          1908:            m0->m_pkthdr.len, txq->cur_encrypt, rate));
        !          1909:
        !          1910:        /* kick encrypt */
        !          1911:        txq->queued++;
        !          1912:        if (++txq->cur_encrypt >= txq->count)
        !          1913:                txq->cur_encrypt = 0;
        !          1914:        RAL_WRITE(sc, RT2560_SECCSR1, RT2560_KICK_ENCRYPT);
        !          1915:
        !          1916:        return 0;
        !          1917: }
        !          1918:
        !          1919: void
        !          1920: rt2560_start(struct ifnet *ifp)
        !          1921: {
        !          1922:        struct rt2560_softc *sc = ifp->if_softc;
        !          1923:        struct ieee80211com *ic = &sc->sc_ic;
        !          1924:        struct mbuf *m0;
        !          1925:        struct ieee80211_node *ni;
        !          1926:
        !          1927:        /*
        !          1928:         * net80211 may still try to send management frames even if the
        !          1929:         * IFF_RUNNING flag is not set...
        !          1930:         */
        !          1931:        if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
        !          1932:                return;
        !          1933:
        !          1934:        for (;;) {
        !          1935:                IF_POLL(&ic->ic_mgtq, m0);
        !          1936:                if (m0 != NULL) {
        !          1937:                        if (sc->prioq.queued >= RT2560_PRIO_RING_COUNT) {
        !          1938:                                ifp->if_flags |= IFF_OACTIVE;
        !          1939:                                break;
        !          1940:                        }
        !          1941:                        IF_DEQUEUE(&ic->ic_mgtq, m0);
        !          1942:
        !          1943:                        ni = (struct ieee80211_node *)m0->m_pkthdr.rcvif;
        !          1944:                        m0->m_pkthdr.rcvif = NULL;
        !          1945: #if NBPFILTER > 0
        !          1946:                        if (ic->ic_rawbpf != NULL)
        !          1947:                                bpf_mtap(ic->ic_rawbpf, m0, BPF_DIRECTION_OUT);
        !          1948: #endif
        !          1949:                        if (rt2560_tx_mgt(sc, m0, ni) != 0)
        !          1950:                                break;
        !          1951:
        !          1952:                } else {
        !          1953:                        if (ic->ic_state != IEEE80211_S_RUN)
        !          1954:                                break;
        !          1955:                        IFQ_POLL(&ifp->if_snd, m0);
        !          1956:                        if (m0 == NULL)
        !          1957:                                break;
        !          1958:                        if (sc->txq.queued >= RT2560_TX_RING_COUNT - 1) {
        !          1959:                                ifp->if_flags |= IFF_OACTIVE;
        !          1960:                                break;
        !          1961:                        }
        !          1962:                        IFQ_DEQUEUE(&ifp->if_snd, m0);
        !          1963: #if NBPFILTER > 0
        !          1964:                        if (ifp->if_bpf != NULL)
        !          1965:                                bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_OUT);
        !          1966: #endif
        !          1967:                        m0 = ieee80211_encap(ifp, m0, &ni);
        !          1968:                        if (m0 == NULL)
        !          1969:                                continue;
        !          1970: #if NBPFILTER > 0
        !          1971:                        if (ic->ic_rawbpf != NULL)
        !          1972:                                bpf_mtap(ic->ic_rawbpf, m0, BPF_DIRECTION_OUT);
        !          1973: #endif
        !          1974:                        if (rt2560_tx_data(sc, m0, ni) != 0) {
        !          1975:                                if (ni != NULL)
        !          1976:                                        ieee80211_release_node(ic, ni);
        !          1977:                                ifp->if_oerrors++;
        !          1978:                                break;
        !          1979:                        }
        !          1980:                }
        !          1981:
        !          1982:                sc->sc_tx_timer = 5;
        !          1983:                ifp->if_timer = 1;
        !          1984:        }
        !          1985: }
        !          1986:
        !          1987: void
        !          1988: rt2560_watchdog(struct ifnet *ifp)
        !          1989: {
        !          1990:        struct rt2560_softc *sc = ifp->if_softc;
        !          1991:
        !          1992:        ifp->if_timer = 0;
        !          1993:
        !          1994:        if (sc->sc_tx_timer > 0) {
        !          1995:                if (--sc->sc_tx_timer == 0) {
        !          1996:                        printf("%s: device timeout\n", sc->sc_dev.dv_xname);
        !          1997:                        rt2560_init(ifp);
        !          1998:                        ifp->if_oerrors++;
        !          1999:                        return;
        !          2000:                }
        !          2001:                ifp->if_timer = 1;
        !          2002:        }
        !          2003:
        !          2004:        ieee80211_watchdog(ifp);
        !          2005: }
        !          2006:
        !          2007: int
        !          2008: rt2560_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
        !          2009: {
        !          2010:        struct rt2560_softc *sc = ifp->if_softc;
        !          2011:        struct ieee80211com *ic = &sc->sc_ic;
        !          2012:        struct ifaddr *ifa;
        !          2013:        struct ifreq *ifr;
        !          2014:        int s, error = 0;
        !          2015:
        !          2016:        s = splnet();
        !          2017:
        !          2018:        switch (cmd) {
        !          2019:        case SIOCSIFADDR:
        !          2020:                ifa = (struct ifaddr *)data;
        !          2021:                ifp->if_flags |= IFF_UP;
        !          2022: #ifdef INET
        !          2023:                if (ifa->ifa_addr->sa_family == AF_INET)
        !          2024:                        arp_ifinit(&ic->ic_ac, ifa);
        !          2025: #endif
        !          2026:                /* FALLTHROUGH */
        !          2027:        case SIOCSIFFLAGS:
        !          2028:                if (ifp->if_flags & IFF_UP) {
        !          2029:                        if (ifp->if_flags & IFF_RUNNING)
        !          2030:                                rt2560_update_promisc(sc);
        !          2031:                        else
        !          2032:                                rt2560_init(ifp);
        !          2033:                } else {
        !          2034:                        if (ifp->if_flags & IFF_RUNNING)
        !          2035:                                rt2560_stop(ifp, 1);
        !          2036:                }
        !          2037:                break;
        !          2038:
        !          2039:        case SIOCADDMULTI:
        !          2040:        case SIOCDELMULTI:
        !          2041:                ifr = (struct ifreq *)data;
        !          2042:                error = (cmd == SIOCADDMULTI) ?
        !          2043:                    ether_addmulti(ifr, &ic->ic_ac) :
        !          2044:                    ether_delmulti(ifr, &ic->ic_ac);
        !          2045:
        !          2046:                if (error == ENETRESET)
        !          2047:                        error = 0;
        !          2048:                break;
        !          2049:
        !          2050:        case SIOCS80211CHANNEL:
        !          2051:                /*
        !          2052:                 * This allows for fast channel switching in monitor mode
        !          2053:                 * (used by kismet). In IBSS mode, we must explicitly reset
        !          2054:                 * the interface to generate a new beacon frame.
        !          2055:                 */
        !          2056:                error = ieee80211_ioctl(ifp, cmd, data);
        !          2057:                if (error == ENETRESET &&
        !          2058:                    ic->ic_opmode == IEEE80211_M_MONITOR) {
        !          2059:                        if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
        !          2060:                            (IFF_UP | IFF_RUNNING))
        !          2061:                                rt2560_set_chan(sc, ic->ic_ibss_chan);
        !          2062:                        error = 0;
        !          2063:                }
        !          2064:                break;
        !          2065:
        !          2066:        default:
        !          2067:                error = ieee80211_ioctl(ifp, cmd, data);
        !          2068:        }
        !          2069:
        !          2070:        if (error == ENETRESET) {
        !          2071:                if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
        !          2072:                    (IFF_UP | IFF_RUNNING))
        !          2073:                        rt2560_init(ifp);
        !          2074:                error = 0;
        !          2075:        }
        !          2076:
        !          2077:        splx(s);
        !          2078:
        !          2079:        return error;
        !          2080: }
        !          2081:
        !          2082: void
        !          2083: rt2560_bbp_write(struct rt2560_softc *sc, uint8_t reg, uint8_t val)
        !          2084: {
        !          2085:        uint32_t tmp;
        !          2086:        int ntries;
        !          2087:
        !          2088:        for (ntries = 0; ntries < 100; ntries++) {
        !          2089:                if (!(RAL_READ(sc, RT2560_BBPCSR) & RT2560_BBP_BUSY))
        !          2090:                        break;
        !          2091:                DELAY(1);
        !          2092:        }
        !          2093:        if (ntries == 100) {
        !          2094:                printf("%s: could not write to BBP\n", sc->sc_dev.dv_xname);
        !          2095:                return;
        !          2096:        }
        !          2097:
        !          2098:        tmp = RT2560_BBP_WRITE | RT2560_BBP_BUSY | reg << 8 | val;
        !          2099:        RAL_WRITE(sc, RT2560_BBPCSR, tmp);
        !          2100:
        !          2101:        DPRINTFN(15, ("BBP R%u <- 0x%02x\n", reg, val));
        !          2102: }
        !          2103:
        !          2104: uint8_t
        !          2105: rt2560_bbp_read(struct rt2560_softc *sc, uint8_t reg)
        !          2106: {
        !          2107:        uint32_t val;
        !          2108:        int ntries;
        !          2109:
        !          2110:        val = RT2560_BBP_BUSY | reg << 8;
        !          2111:        RAL_WRITE(sc, RT2560_BBPCSR, val);
        !          2112:
        !          2113:        for (ntries = 0; ntries < 100; ntries++) {
        !          2114:                val = RAL_READ(sc, RT2560_BBPCSR);
        !          2115:                if (!(val & RT2560_BBP_BUSY))
        !          2116:                        return val & 0xff;
        !          2117:                DELAY(1);
        !          2118:        }
        !          2119:
        !          2120:        printf("%s: could not read from BBP\n", sc->sc_dev.dv_xname);
        !          2121:        return 0;
        !          2122: }
        !          2123:
        !          2124: void
        !          2125: rt2560_rf_write(struct rt2560_softc *sc, uint8_t reg, uint32_t val)
        !          2126: {
        !          2127:        uint32_t tmp;
        !          2128:        int ntries;
        !          2129:
        !          2130:        for (ntries = 0; ntries < 100; ntries++) {
        !          2131:                if (!(RAL_READ(sc, RT2560_RFCSR) & RT2560_RF_BUSY))
        !          2132:                        break;
        !          2133:                DELAY(1);
        !          2134:        }
        !          2135:        if (ntries == 100) {
        !          2136:                printf("%s: could not write to RF\n", sc->sc_dev.dv_xname);
        !          2137:                return;
        !          2138:        }
        !          2139:
        !          2140:        tmp = RT2560_RF_BUSY | RT2560_RF_20BIT | (val & 0xfffff) << 2 |
        !          2141:            (reg & 0x3);
        !          2142:        RAL_WRITE(sc, RT2560_RFCSR, tmp);
        !          2143:
        !          2144:        /* remember last written value in sc */
        !          2145:        sc->rf_regs[reg] = val;
        !          2146:
        !          2147:        DPRINTFN(15, ("RF R[%u] <- 0x%05x\n", reg & 0x3, val & 0xfffff));
        !          2148: }
        !          2149:
        !          2150: void
        !          2151: rt2560_set_chan(struct rt2560_softc *sc, struct ieee80211_channel *c)
        !          2152: {
        !          2153:        struct ieee80211com *ic = &sc->sc_ic;
        !          2154:        uint8_t power, tmp;
        !          2155:        u_int chan;
        !          2156:
        !          2157:        chan = ieee80211_chan2ieee(ic, c);
        !          2158:        if (chan == 0 || chan == IEEE80211_CHAN_ANY)
        !          2159:                return;
        !          2160:
        !          2161:        power = min(sc->txpow[chan - 1], 31);
        !          2162:
        !          2163:        DPRINTFN(2, ("setting channel to %u, txpower to %u\n", chan, power));
        !          2164:
        !          2165:        switch (sc->rf_rev) {
        !          2166:        case RT2560_RF_2522:
        !          2167:                rt2560_rf_write(sc, RT2560_RF1, 0x00814);
        !          2168:                rt2560_rf_write(sc, RT2560_RF2, rt2560_rf2522_r2[chan - 1]);
        !          2169:                rt2560_rf_write(sc, RT2560_RF3, power << 7 | 0x00040);
        !          2170:                break;
        !          2171:
        !          2172:        case RT2560_RF_2523:
        !          2173:                rt2560_rf_write(sc, RT2560_RF1, 0x08804);
        !          2174:                rt2560_rf_write(sc, RT2560_RF2, rt2560_rf2523_r2[chan - 1]);
        !          2175:                rt2560_rf_write(sc, RT2560_RF3, power << 7 | 0x38044);
        !          2176:                rt2560_rf_write(sc, RT2560_RF4,
        !          2177:                    (chan == 14) ? 0x00280 : 0x00286);
        !          2178:                break;
        !          2179:
        !          2180:        case RT2560_RF_2524:
        !          2181:                rt2560_rf_write(sc, RT2560_RF1, 0x0c808);
        !          2182:                rt2560_rf_write(sc, RT2560_RF2, rt2560_rf2524_r2[chan - 1]);
        !          2183:                rt2560_rf_write(sc, RT2560_RF3, power << 7 | 0x00040);
        !          2184:                rt2560_rf_write(sc, RT2560_RF4,
        !          2185:                    (chan == 14) ? 0x00280 : 0x00286);
        !          2186:                break;
        !          2187:
        !          2188:        case RT2560_RF_2525:
        !          2189:                rt2560_rf_write(sc, RT2560_RF1, 0x08808);
        !          2190:                rt2560_rf_write(sc, RT2560_RF2, rt2560_rf2525_hi_r2[chan - 1]);
        !          2191:                rt2560_rf_write(sc, RT2560_RF3, power << 7 | 0x18044);
        !          2192:                rt2560_rf_write(sc, RT2560_RF4,
        !          2193:                    (chan == 14) ? 0x00280 : 0x00286);
        !          2194:
        !          2195:                rt2560_rf_write(sc, RT2560_RF1, 0x08808);
        !          2196:                rt2560_rf_write(sc, RT2560_RF2, rt2560_rf2525_r2[chan - 1]);
        !          2197:                rt2560_rf_write(sc, RT2560_RF3, power << 7 | 0x18044);
        !          2198:                rt2560_rf_write(sc, RT2560_RF4,
        !          2199:                    (chan == 14) ? 0x00280 : 0x00286);
        !          2200:                break;
        !          2201:
        !          2202:        case RT2560_RF_2525E:
        !          2203:                rt2560_rf_write(sc, RT2560_RF1, 0x08808);
        !          2204:                rt2560_rf_write(sc, RT2560_RF2, rt2560_rf2525e_r2[chan - 1]);
        !          2205:                rt2560_rf_write(sc, RT2560_RF3, power << 7 | 0x18044);
        !          2206:                rt2560_rf_write(sc, RT2560_RF4,
        !          2207:                    (chan == 14) ? 0x00286 : 0x00282);
        !          2208:                break;
        !          2209:
        !          2210:        case RT2560_RF_2526:
        !          2211:                rt2560_rf_write(sc, RT2560_RF2, rt2560_rf2526_hi_r2[chan - 1]);
        !          2212:                rt2560_rf_write(sc, RT2560_RF4,
        !          2213:                   (chan & 1) ? 0x00386 : 0x00381);
        !          2214:                rt2560_rf_write(sc, RT2560_RF1, 0x08804);
        !          2215:
        !          2216:                rt2560_rf_write(sc, RT2560_RF2, rt2560_rf2526_r2[chan - 1]);
        !          2217:                rt2560_rf_write(sc, RT2560_RF3, power << 7 | 0x18044);
        !          2218:                rt2560_rf_write(sc, RT2560_RF4,
        !          2219:                    (chan & 1) ? 0x00386 : 0x00381);
        !          2220:                break;
        !          2221:        }
        !          2222:
        !          2223:        if (ic->ic_opmode != IEEE80211_M_MONITOR &&
        !          2224:            ic->ic_state != IEEE80211_S_SCAN) {
        !          2225:                /* set Japan filter bit for channel 14 */
        !          2226:                tmp = rt2560_bbp_read(sc, 70);
        !          2227:
        !          2228:                tmp &= ~RT2560_JAPAN_FILTER;
        !          2229:                if (chan == 14)
        !          2230:                        tmp |= RT2560_JAPAN_FILTER;
        !          2231:
        !          2232:                rt2560_bbp_write(sc, 70, tmp);
        !          2233:
        !          2234:                DELAY(1000); /* RF needs a 1ms delay here */
        !          2235:                rt2560_disable_rf_tune(sc);
        !          2236:
        !          2237:                /* clear CRC errors */
        !          2238:                RAL_READ(sc, RT2560_CNT0);
        !          2239:        }
        !          2240: }
        !          2241:
        !          2242: /*
        !          2243:  * Disable RF auto-tuning.
        !          2244:  */
        !          2245: void
        !          2246: rt2560_disable_rf_tune(struct rt2560_softc *sc)
        !          2247: {
        !          2248:        uint32_t tmp;
        !          2249:
        !          2250:        if (sc->rf_rev != RT2560_RF_2523) {
        !          2251:                tmp = sc->rf_regs[RT2560_RF1] & ~RT2560_RF1_AUTOTUNE;
        !          2252:                rt2560_rf_write(sc, RT2560_RF1, tmp);
        !          2253:        }
        !          2254:
        !          2255:        tmp = sc->rf_regs[RT2560_RF3] & ~RT2560_RF3_AUTOTUNE;
        !          2256:        rt2560_rf_write(sc, RT2560_RF3, tmp);
        !          2257:
        !          2258:        DPRINTFN(2, ("disabling RF autotune\n"));
        !          2259: }
        !          2260:
        !          2261: /*
        !          2262:  * Refer to IEEE Std 802.11-1999 pp. 123 for more information on TSF
        !          2263:  * synchronization.
        !          2264:  */
        !          2265: void
        !          2266: rt2560_enable_tsf_sync(struct rt2560_softc *sc)
        !          2267: {
        !          2268:        struct ieee80211com *ic = &sc->sc_ic;
        !          2269:        uint16_t logcwmin, preload;
        !          2270:        uint32_t tmp;
        !          2271:
        !          2272:        /* first, disable TSF synchronization */
        !          2273:        RAL_WRITE(sc, RT2560_CSR14, 0);
        !          2274:
        !          2275:        tmp = 16 * ic->ic_bss->ni_intval;
        !          2276:        RAL_WRITE(sc, RT2560_CSR12, tmp);
        !          2277:
        !          2278:        RAL_WRITE(sc, RT2560_CSR13, 0);
        !          2279:
        !          2280:        logcwmin = 5;
        !          2281:        preload = (ic->ic_opmode == IEEE80211_M_STA) ? 384 : 1024;
        !          2282:        tmp = logcwmin << 16 | preload;
        !          2283:        RAL_WRITE(sc, RT2560_BCNOCSR, tmp);
        !          2284:
        !          2285:        /* finally, enable TSF synchronization */
        !          2286:        tmp = RT2560_ENABLE_TSF | RT2560_ENABLE_TBCN;
        !          2287:        if (ic->ic_opmode == IEEE80211_M_STA)
        !          2288:                tmp |= RT2560_ENABLE_TSF_SYNC(1);
        !          2289:        else
        !          2290:                tmp |= RT2560_ENABLE_TSF_SYNC(2) |
        !          2291:                       RT2560_ENABLE_BEACON_GENERATOR;
        !          2292:        RAL_WRITE(sc, RT2560_CSR14, tmp);
        !          2293:
        !          2294:        DPRINTF(("enabling TSF synchronization\n"));
        !          2295: }
        !          2296:
        !          2297: void
        !          2298: rt2560_update_plcp(struct rt2560_softc *sc)
        !          2299: {
        !          2300:        struct ieee80211com *ic = &sc->sc_ic;
        !          2301:
        !          2302:        /* no short preamble for 1Mbps */
        !          2303:        RAL_WRITE(sc, RT2560_PLCP1MCSR, 0x00700400);
        !          2304:
        !          2305:        if (!(ic->ic_flags & IEEE80211_F_SHPREAMBLE)) {
        !          2306:                /* values taken from the reference driver */
        !          2307:                RAL_WRITE(sc, RT2560_PLCP2MCSR,   0x00380401);
        !          2308:                RAL_WRITE(sc, RT2560_PLCP5p5MCSR, 0x00150402);
        !          2309:                RAL_WRITE(sc, RT2560_PLCP11MCSR,  0x000b8403);
        !          2310:        } else {
        !          2311:                /* same values as above or'ed 0x8 */
        !          2312:                RAL_WRITE(sc, RT2560_PLCP2MCSR,   0x00380409);
        !          2313:                RAL_WRITE(sc, RT2560_PLCP5p5MCSR, 0x0015040a);
        !          2314:                RAL_WRITE(sc, RT2560_PLCP11MCSR,  0x000b840b);
        !          2315:        }
        !          2316:
        !          2317:        DPRINTF(("updating PLCP for %s preamble\n",
        !          2318:            (ic->ic_flags & IEEE80211_F_SHPREAMBLE) ? "short" : "long"));
        !          2319: }
        !          2320:
        !          2321: void
        !          2322: rt2560_updateslot(struct ieee80211com *ic)
        !          2323: {
        !          2324:        struct rt2560_softc *sc = ic->ic_if.if_softc;
        !          2325:
        !          2326:        if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
        !          2327:                /*
        !          2328:                 * In HostAP mode, we defer setting of new slot time until
        !          2329:                 * updated ERP Information Element has propagated to all
        !          2330:                 * associated STAs.
        !          2331:                 */
        !          2332:                sc->sc_flags |= RT2560_UPDATE_SLOT;
        !          2333:        } else
        !          2334:                rt2560_set_slottime(sc);
        !          2335: }
        !          2336:
        !          2337: /*
        !          2338:  * IEEE 802.11a (and possibly 802.11g) use short slot time. Refer to
        !          2339:  * IEEE Std 802.11-1999 pp. 85 to know how these values are computed.
        !          2340:  */
        !          2341: void
        !          2342: rt2560_set_slottime(struct rt2560_softc *sc)
        !          2343: {
        !          2344:        struct ieee80211com *ic = &sc->sc_ic;
        !          2345:        uint8_t slottime;
        !          2346:        uint16_t sifs, pifs, difs, eifs;
        !          2347:        uint32_t tmp;
        !          2348:
        !          2349:        slottime = (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20;
        !          2350:
        !          2351:        /* define the MAC slot boundaries */
        !          2352:        sifs = RAL_SIFS - RT2560_RXTX_TURNAROUND;
        !          2353:        pifs = sifs + slottime;
        !          2354:        difs = sifs + 2 * slottime;
        !          2355:        eifs = (ic->ic_curmode == IEEE80211_MODE_11B) ? 364 : 60;
        !          2356:
        !          2357:        tmp = RAL_READ(sc, RT2560_CSR11);
        !          2358:        tmp = (tmp & ~0x1f00) | slottime << 8;
        !          2359:        RAL_WRITE(sc, RT2560_CSR11, tmp);
        !          2360:
        !          2361:        tmp = pifs << 16 | sifs;
        !          2362:        RAL_WRITE(sc, RT2560_CSR18, tmp);
        !          2363:
        !          2364:        tmp = eifs << 16 | difs;
        !          2365:        RAL_WRITE(sc, RT2560_CSR19, tmp);
        !          2366:
        !          2367:        DPRINTF(("setting slottime to %uus\n", slottime));
        !          2368: }
        !          2369:
        !          2370: void
        !          2371: rt2560_set_basicrates(struct rt2560_softc *sc)
        !          2372: {
        !          2373:        struct ieee80211com *ic = &sc->sc_ic;
        !          2374:
        !          2375:        /* update basic rate set */
        !          2376:        if (ic->ic_curmode == IEEE80211_MODE_11B) {
        !          2377:                /* 11b basic rates: 1, 2Mbps */
        !          2378:                RAL_WRITE(sc, RT2560_ARSP_PLCP_1, 0x3);
        !          2379:        } else {
        !          2380:                /* 11b/g basic rates: 1, 2, 5.5, 11Mbps */
        !          2381:                RAL_WRITE(sc, RT2560_ARSP_PLCP_1, 0xf);
        !          2382:        }
        !          2383: }
        !          2384:
        !          2385: void
        !          2386: rt2560_update_led(struct rt2560_softc *sc, int led1, int led2)
        !          2387: {
        !          2388:        uint32_t tmp;
        !          2389:
        !          2390:        /* set ON period to 70ms and OFF period to 30ms */
        !          2391:        tmp = led1 << 16 | led2 << 17 | 70 << 8 | 30;
        !          2392:        RAL_WRITE(sc, RT2560_LEDCSR, tmp);
        !          2393: }
        !          2394:
        !          2395: void
        !          2396: rt2560_set_bssid(struct rt2560_softc *sc, uint8_t *bssid)
        !          2397: {
        !          2398:        uint32_t tmp;
        !          2399:
        !          2400:        tmp = bssid[0] | bssid[1] << 8 | bssid[2] << 16 | bssid[3] << 24;
        !          2401:        RAL_WRITE(sc, RT2560_CSR5, tmp);
        !          2402:
        !          2403:        tmp = bssid[4] | bssid[5] << 8;
        !          2404:        RAL_WRITE(sc, RT2560_CSR6, tmp);
        !          2405:
        !          2406:        DPRINTF(("setting BSSID to %s\n", ether_sprintf(bssid)));
        !          2407: }
        !          2408:
        !          2409: void
        !          2410: rt2560_set_macaddr(struct rt2560_softc *sc, uint8_t *addr)
        !          2411: {
        !          2412:        uint32_t tmp;
        !          2413:
        !          2414:        tmp = addr[0] | addr[1] << 8 | addr[2] << 16 | addr[3] << 24;
        !          2415:        RAL_WRITE(sc, RT2560_CSR3, tmp);
        !          2416:
        !          2417:        tmp = addr[4] | addr[5] << 8;
        !          2418:        RAL_WRITE(sc, RT2560_CSR4, tmp);
        !          2419:
        !          2420:        DPRINTF(("setting MAC address to %s\n", ether_sprintf(addr)));
        !          2421: }
        !          2422:
        !          2423: void
        !          2424: rt2560_get_macaddr(struct rt2560_softc *sc, uint8_t *addr)
        !          2425: {
        !          2426:        uint32_t tmp;
        !          2427:
        !          2428:        tmp = RAL_READ(sc, RT2560_CSR3);
        !          2429:        addr[0] = tmp & 0xff;
        !          2430:        addr[1] = (tmp >>  8) & 0xff;
        !          2431:        addr[2] = (tmp >> 16) & 0xff;
        !          2432:        addr[3] = (tmp >> 24);
        !          2433:
        !          2434:        tmp = RAL_READ(sc, RT2560_CSR4);
        !          2435:        addr[4] = tmp & 0xff;
        !          2436:        addr[5] = (tmp >> 8) & 0xff;
        !          2437: }
        !          2438:
        !          2439: void
        !          2440: rt2560_update_promisc(struct rt2560_softc *sc)
        !          2441: {
        !          2442:        struct ifnet *ifp = &sc->sc_ic.ic_if;
        !          2443:        uint32_t tmp;
        !          2444:
        !          2445:        tmp = RAL_READ(sc, RT2560_RXCSR0);
        !          2446:
        !          2447:        tmp &= ~RT2560_DROP_NOT_TO_ME;
        !          2448:        if (!(ifp->if_flags & IFF_PROMISC))
        !          2449:                tmp |= RT2560_DROP_NOT_TO_ME;
        !          2450:
        !          2451:        RAL_WRITE(sc, RT2560_RXCSR0, tmp);
        !          2452:
        !          2453:        DPRINTF(("%s promiscuous mode\n", (ifp->if_flags & IFF_PROMISC) ?
        !          2454:            "entering" : "leaving"));
        !          2455: }
        !          2456:
        !          2457: void
        !          2458: rt2560_set_txantenna(struct rt2560_softc *sc, int antenna)
        !          2459: {
        !          2460:        uint32_t tmp;
        !          2461:        uint8_t tx;
        !          2462:
        !          2463:        tx = rt2560_bbp_read(sc, RT2560_BBP_TX) & ~RT2560_BBP_ANTMASK;
        !          2464:        if (antenna == 1)
        !          2465:                tx |= RT2560_BBP_ANTA;
        !          2466:        else if (antenna == 2)
        !          2467:                tx |= RT2560_BBP_ANTB;
        !          2468:        else
        !          2469:                tx |= RT2560_BBP_DIVERSITY;
        !          2470:
        !          2471:        /* need to force I/Q flip for RF 2525e, 2526 and 5222 */
        !          2472:        if (sc->rf_rev == RT2560_RF_2525E || sc->rf_rev == RT2560_RF_2526 ||
        !          2473:            sc->rf_rev == RT2560_RF_5222)
        !          2474:                tx |= RT2560_BBP_FLIPIQ;
        !          2475:
        !          2476:        rt2560_bbp_write(sc, RT2560_BBP_TX, tx);
        !          2477:
        !          2478:        /* update values for CCK and OFDM in BBPCSR1 */
        !          2479:        tmp = RAL_READ(sc, RT2560_BBPCSR1) & ~0x00070007;
        !          2480:        tmp |= (tx & 0x7) << 16 | (tx & 0x7);
        !          2481:        RAL_WRITE(sc, RT2560_BBPCSR1, tmp);
        !          2482: }
        !          2483:
        !          2484: void
        !          2485: rt2560_set_rxantenna(struct rt2560_softc *sc, int antenna)
        !          2486: {
        !          2487:        uint8_t rx;
        !          2488:
        !          2489:        rx = rt2560_bbp_read(sc, RT2560_BBP_RX) & ~RT2560_BBP_ANTMASK;
        !          2490:        if (antenna == 1)
        !          2491:                rx |= RT2560_BBP_ANTA;
        !          2492:        else if (antenna == 2)
        !          2493:                rx |= RT2560_BBP_ANTB;
        !          2494:        else
        !          2495:                rx |= RT2560_BBP_DIVERSITY;
        !          2496:
        !          2497:        /* need to force no I/Q flip for RF 2525e and 2526 */
        !          2498:        if (sc->rf_rev == RT2560_RF_2525E || sc->rf_rev == RT2560_RF_2526)
        !          2499:                rx &= ~RT2560_BBP_FLIPIQ;
        !          2500:
        !          2501:        rt2560_bbp_write(sc, RT2560_BBP_RX, rx);
        !          2502: }
        !          2503:
        !          2504: const char *
        !          2505: rt2560_get_rf(int rev)
        !          2506: {
        !          2507:        switch (rev) {
        !          2508:        case RT2560_RF_2522:    return "RT2522";
        !          2509:        case RT2560_RF_2523:    return "RT2523";
        !          2510:        case RT2560_RF_2524:    return "RT2524";
        !          2511:        case RT2560_RF_2525:    return "RT2525";
        !          2512:        case RT2560_RF_2525E:   return "RT2525e";
        !          2513:        case RT2560_RF_2526:    return "RT2526";
        !          2514:        case RT2560_RF_5222:    return "RT5222";
        !          2515:        default:                return "unknown";
        !          2516:        }
        !          2517: }
        !          2518:
        !          2519: void
        !          2520: rt2560_read_eeprom(struct rt2560_softc *sc)
        !          2521: {
        !          2522:        uint16_t val;
        !          2523:        int i;
        !          2524:
        !          2525:        val = rt2560_eeprom_read(sc, RT2560_EEPROM_CONFIG0);
        !          2526:        sc->rf_rev =   (val >> 11) & 0x1f;
        !          2527:        sc->hw_radio = (val >> 10) & 0x1;
        !          2528:        sc->led_mode = (val >> 6)  & 0x7;
        !          2529:        sc->rx_ant =   (val >> 4)  & 0x3;
        !          2530:        sc->tx_ant =   (val >> 2)  & 0x3;
        !          2531:        sc->nb_ant =   val & 0x3;
        !          2532:
        !          2533:        /* read default values for BBP registers */
        !          2534:        for (i = 0; i < 16; i++) {
        !          2535:                val = rt2560_eeprom_read(sc, RT2560_EEPROM_BBP_BASE + i);
        !          2536:                sc->bbp_prom[i].reg = val >> 8;
        !          2537:                sc->bbp_prom[i].val = val & 0xff;
        !          2538:        }
        !          2539:
        !          2540:        /* read Tx power for all b/g channels */
        !          2541:        for (i = 0; i < 14 / 2; i++) {
        !          2542:                val = rt2560_eeprom_read(sc, RT2560_EEPROM_TXPOWER + i);
        !          2543:                sc->txpow[i * 2] = val >> 8;
        !          2544:                sc->txpow[i * 2 + 1] = val & 0xff;
        !          2545:        }
        !          2546: }
        !          2547:
        !          2548: int
        !          2549: rt2560_bbp_init(struct rt2560_softc *sc)
        !          2550: {
        !          2551: #define N(a)   (sizeof (a) / sizeof ((a)[0]))
        !          2552:        int i, ntries;
        !          2553:
        !          2554:        /* wait for BBP to be ready */
        !          2555:        for (ntries = 0; ntries < 100; ntries++) {
        !          2556:                if (rt2560_bbp_read(sc, RT2560_BBP_VERSION) != 0)
        !          2557:                        break;
        !          2558:                DELAY(1);
        !          2559:        }
        !          2560:        if (ntries == 100) {
        !          2561:                printf("%s: timeout waiting for BBP\n", sc->sc_dev.dv_xname);
        !          2562:                return EIO;
        !          2563:        }
        !          2564:
        !          2565:        /* initialize BBP registers to default values */
        !          2566:        for (i = 0; i < N(rt2560_def_bbp); i++) {
        !          2567:                rt2560_bbp_write(sc, rt2560_def_bbp[i].reg,
        !          2568:                    rt2560_def_bbp[i].val);
        !          2569:        }
        !          2570: #if 0
        !          2571:        /* initialize BBP registers to values stored in EEPROM */
        !          2572:        for (i = 0; i < 16; i++) {
        !          2573:                if (sc->bbp_prom[i].reg == 0xff)
        !          2574:                        continue;
        !          2575:                rt2560_bbp_write(sc, sc->bbp_prom[i].reg, sc->bbp_prom[i].val);
        !          2576:        }
        !          2577: #endif
        !          2578:
        !          2579:        return 0;
        !          2580: #undef N
        !          2581: }
        !          2582:
        !          2583: int
        !          2584: rt2560_init(struct ifnet *ifp)
        !          2585: {
        !          2586: #define N(a)   (sizeof (a) / sizeof ((a)[0]))
        !          2587:        struct rt2560_softc *sc = ifp->if_softc;
        !          2588:        struct ieee80211com *ic = &sc->sc_ic;
        !          2589:        uint32_t tmp;
        !          2590:        int i;
        !          2591:
        !          2592:        /* for CardBus, power on the socket */
        !          2593:        if (!(sc->sc_flags & RT2560_ENABLED)) {
        !          2594:                if (sc->sc_enable != NULL && (*sc->sc_enable)(sc) != 0) {
        !          2595:                        printf("%s: could not enable device\n",
        !          2596:                            sc->sc_dev.dv_xname);
        !          2597:                        return EIO;
        !          2598:                }
        !          2599:                sc->sc_flags |= RT2560_ENABLED;
        !          2600:        }
        !          2601:
        !          2602:        rt2560_stop(ifp, 0);
        !          2603:
        !          2604:        /* setup tx rings */
        !          2605:        tmp = RT2560_PRIO_RING_COUNT << 24 |
        !          2606:              RT2560_ATIM_RING_COUNT << 16 |
        !          2607:              RT2560_TX_RING_COUNT   <<  8 |
        !          2608:              RT2560_TX_DESC_SIZE;
        !          2609:
        !          2610:        /* rings _must_ be initialized in this _exact_ order! */
        !          2611:        RAL_WRITE(sc, RT2560_TXCSR2, tmp);
        !          2612:        RAL_WRITE(sc, RT2560_TXCSR3, sc->txq.physaddr);
        !          2613:        RAL_WRITE(sc, RT2560_TXCSR5, sc->prioq.physaddr);
        !          2614:        RAL_WRITE(sc, RT2560_TXCSR4, sc->atimq.physaddr);
        !          2615:        RAL_WRITE(sc, RT2560_TXCSR6, sc->bcnq.physaddr);
        !          2616:
        !          2617:        /* setup rx ring */
        !          2618:        tmp = RT2560_RX_RING_COUNT << 8 | RT2560_RX_DESC_SIZE;
        !          2619:
        !          2620:        RAL_WRITE(sc, RT2560_RXCSR1, tmp);
        !          2621:        RAL_WRITE(sc, RT2560_RXCSR2, sc->rxq.physaddr);
        !          2622:
        !          2623:        /* initialize MAC registers to default values */
        !          2624:        for (i = 0; i < N(rt2560_def_mac); i++)
        !          2625:                RAL_WRITE(sc, rt2560_def_mac[i].reg, rt2560_def_mac[i].val);
        !          2626:
        !          2627:        IEEE80211_ADDR_COPY(ic->ic_myaddr, LLADDR(ifp->if_sadl));
        !          2628:        rt2560_set_macaddr(sc, ic->ic_myaddr);
        !          2629:
        !          2630:        /* set basic rate set (will be updated later) */
        !          2631:        RAL_WRITE(sc, RT2560_ARSP_PLCP_1, 0x153);
        !          2632:
        !          2633:        rt2560_set_txantenna(sc, 1);
        !          2634:        rt2560_set_rxantenna(sc, 1);
        !          2635:        rt2560_set_slottime(sc);
        !          2636:        rt2560_update_plcp(sc);
        !          2637:        rt2560_update_led(sc, 0, 0);
        !          2638:
        !          2639:        RAL_WRITE(sc, RT2560_CSR1, RT2560_RESET_ASIC);
        !          2640:        RAL_WRITE(sc, RT2560_CSR1, RT2560_HOST_READY);
        !          2641:
        !          2642:        if (rt2560_bbp_init(sc) != 0) {
        !          2643:                rt2560_stop(ifp, 1);
        !          2644:                return EIO;
        !          2645:        }
        !          2646:
        !          2647:        /* set default BSS channel */
        !          2648:        ic->ic_bss->ni_chan = ic->ic_ibss_chan;
        !          2649:        rt2560_set_chan(sc, ic->ic_bss->ni_chan);
        !          2650:
        !          2651:        /* kick Rx */
        !          2652:        tmp = RT2560_DROP_PHY_ERROR | RT2560_DROP_CRC_ERROR;
        !          2653:        if (ic->ic_opmode != IEEE80211_M_MONITOR) {
        !          2654:                tmp |= RT2560_DROP_CTL | RT2560_DROP_VERSION_ERROR;
        !          2655:                if (ic->ic_opmode != IEEE80211_M_HOSTAP)
        !          2656:                        tmp |= RT2560_DROP_TODS;
        !          2657:                if (!(ifp->if_flags & IFF_PROMISC))
        !          2658:                        tmp |= RT2560_DROP_NOT_TO_ME;
        !          2659:        }
        !          2660:        RAL_WRITE(sc, RT2560_RXCSR0, tmp);
        !          2661:
        !          2662:        /* clear old FCS and Rx FIFO errors */
        !          2663:        RAL_READ(sc, RT2560_CNT0);
        !          2664:        RAL_READ(sc, RT2560_CNT4);
        !          2665:
        !          2666:        /* clear any pending interrupts */
        !          2667:        RAL_WRITE(sc, RT2560_CSR7, 0xffffffff);
        !          2668:
        !          2669:        /* enable interrupts */
        !          2670:        RAL_WRITE(sc, RT2560_CSR8, RT2560_INTR_MASK);
        !          2671:
        !          2672:        ifp->if_flags &= ~IFF_OACTIVE;
        !          2673:        ifp->if_flags |= IFF_RUNNING;
        !          2674:
        !          2675:        if (ic->ic_opmode == IEEE80211_M_MONITOR)
        !          2676:                ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
        !          2677:        else
        !          2678:                ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
        !          2679:
        !          2680:        return 0;
        !          2681: #undef N
        !          2682: }
        !          2683:
        !          2684: void
        !          2685: rt2560_stop(struct ifnet *ifp, int disable)
        !          2686: {
        !          2687:        struct rt2560_softc *sc = ifp->if_softc;
        !          2688:        struct ieee80211com *ic = &sc->sc_ic;
        !          2689:
        !          2690:        sc->sc_tx_timer = 0;
        !          2691:        ifp->if_timer = 0;
        !          2692:        ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
        !          2693:
        !          2694:        ieee80211_new_state(ic, IEEE80211_S_INIT, -1);  /* free all nodes */
        !          2695:
        !          2696:        /* abort Tx */
        !          2697:        RAL_WRITE(sc, RT2560_TXCSR0, RT2560_ABORT_TX);
        !          2698:
        !          2699:        /* disable Rx */
        !          2700:        RAL_WRITE(sc, RT2560_RXCSR0, RT2560_DISABLE_RX);
        !          2701:
        !          2702:        /* reset ASIC (and thus, BBP) */
        !          2703:        RAL_WRITE(sc, RT2560_CSR1, RT2560_RESET_ASIC);
        !          2704:        RAL_WRITE(sc, RT2560_CSR1, 0);
        !          2705:
        !          2706:        /* disable interrupts */
        !          2707:        RAL_WRITE(sc, RT2560_CSR8, 0xffffffff);
        !          2708:
        !          2709:        /* clear any pending interrupt */
        !          2710:        RAL_WRITE(sc, RT2560_CSR7, 0xffffffff);
        !          2711:
        !          2712:        /* reset Tx and Rx rings */
        !          2713:        rt2560_reset_tx_ring(sc, &sc->txq);
        !          2714:        rt2560_reset_tx_ring(sc, &sc->atimq);
        !          2715:        rt2560_reset_tx_ring(sc, &sc->prioq);
        !          2716:        rt2560_reset_tx_ring(sc, &sc->bcnq);
        !          2717:        rt2560_reset_rx_ring(sc, &sc->rxq);
        !          2718:
        !          2719:        /* for CardBus, power down the socket */
        !          2720:        if (disable && sc->sc_disable != NULL) {
        !          2721:                if (sc->sc_flags & RT2560_ENABLED) {
        !          2722:                        (*sc->sc_disable)(sc);
        !          2723:                        sc->sc_flags &= ~RT2560_ENABLED;
        !          2724:                }
        !          2725:        }
        !          2726: }
        !          2727:
        !          2728: void
        !          2729: rt2560_power(int why, void *arg)
        !          2730: {
        !          2731:        struct rt2560_softc *sc = arg;
        !          2732:        struct ifnet *ifp = &sc->sc_ic.ic_if;
        !          2733:        int s;
        !          2734:
        !          2735:        DPRINTF(("%s: rt2560_power(%d)\n", sc->sc_dev.dv_xname, why));
        !          2736:
        !          2737:        s = splnet();
        !          2738:        switch (why) {
        !          2739:        case PWR_SUSPEND:
        !          2740:        case PWR_STANDBY:
        !          2741:                rt2560_stop(ifp, 1);
        !          2742:                if (sc->sc_power != NULL)
        !          2743:                        (*sc->sc_power)(sc, why);
        !          2744:                break;
        !          2745:        case PWR_RESUME:
        !          2746:                if (ifp->if_flags & IFF_UP) {
        !          2747:                        rt2560_init(ifp);
        !          2748:                        if (sc->sc_power != NULL)
        !          2749:                                (*sc->sc_power)(sc, why);
        !          2750:                        if (ifp->if_flags & IFF_RUNNING)
        !          2751:                                rt2560_start(ifp);
        !          2752:                }
        !          2753:                break;
        !          2754:        }
        !          2755:        splx(s);
        !          2756: }
        !          2757:
        !          2758: void
        !          2759: rt2560_shutdown(void *arg)
        !          2760: {
        !          2761:        struct rt2560_softc *sc = arg;
        !          2762:
        !          2763:        rt2560_stop(&sc->sc_ic.ic_if, 1);
        !          2764: }
        !          2765:
        !          2766: struct cfdriver ral_cd = {
        !          2767:        NULL, "ral", DV_IFNET
        !          2768: };

CVSweb