LCOV - code coverage report
Current view: top level - dev/ic - rt2661.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 1486 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 67 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13