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

          Line data    Source code
       1             : /*      $OpenBSD: rt2860.c,v 1.95 2017/10/26 15:00:28 mpi Exp $ */
       2             : 
       3             : /*-
       4             :  * Copyright (c) 2007-2010 Damien Bergamini <damien.bergamini@free.fr>
       5             :  *
       6             :  * Permission to use, copy, modify, and distribute this software for any
       7             :  * purpose with or without fee is hereby granted, provided that the above
       8             :  * copyright notice and this permission notice appear in all copies.
       9             :  *
      10             :  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
      11             :  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
      12             :  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
      13             :  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
      14             :  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
      15             :  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
      16             :  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
      17             :  */
      18             : 
      19             : /*-
      20             :  * Ralink Technology RT2860/RT3090/RT3390/RT3562/RT5390/RT5392 chipset driver
      21             :  * http://www.ralinktech.com/
      22             :  */
      23             : 
      24             : #include "bpfilter.h"
      25             : 
      26             : #include <sys/param.h>
      27             : #include <sys/sockio.h>
      28             : #include <sys/mbuf.h>
      29             : #include <sys/kernel.h>
      30             : #include <sys/socket.h>
      31             : #include <sys/systm.h>
      32             : #include <sys/malloc.h>
      33             : #include <sys/queue.h>
      34             : #include <sys/timeout.h>
      35             : #include <sys/conf.h>
      36             : #include <sys/device.h>
      37             : #include <sys/endian.h>
      38             : 
      39             : #include <machine/bus.h>
      40             : #include <machine/intr.h>
      41             : 
      42             : #if NBPFILTER > 0
      43             : #include <net/bpf.h>
      44             : #endif
      45             : #include <net/if.h>
      46             : #include <net/if_dl.h>
      47             : #include <net/if_media.h>
      48             : 
      49             : #include <netinet/in.h>
      50             : #include <netinet/if_ether.h>
      51             : 
      52             : #include <net80211/ieee80211_var.h>
      53             : #include <net80211/ieee80211_amrr.h>
      54             : #include <net80211/ieee80211_radiotap.h>
      55             : 
      56             : #include <dev/ic/rt2860var.h>
      57             : #include <dev/ic/rt2860reg.h>
      58             : 
      59             : #include <dev/pci/pcidevs.h>
      60             : 
      61             : #ifdef RAL_DEBUG
      62             : #define DPRINTF(x)      do { if (rt2860_debug > 0) printf x; } while (0)
      63             : #define DPRINTFN(n, x)  do { if (rt2860_debug >= (n)) printf x; } while (0)
      64             : int rt2860_debug = 0;
      65             : #else
      66             : #define DPRINTF(x)
      67             : #define DPRINTFN(n, x)
      68             : #endif
      69             : 
      70             : void            rt2860_attachhook(struct device *);
      71             : int             rt2860_alloc_tx_ring(struct rt2860_softc *,
      72             :                     struct rt2860_tx_ring *);
      73             : void            rt2860_reset_tx_ring(struct rt2860_softc *,
      74             :                     struct rt2860_tx_ring *);
      75             : void            rt2860_free_tx_ring(struct rt2860_softc *,
      76             :                     struct rt2860_tx_ring *);
      77             : int             rt2860_alloc_tx_pool(struct rt2860_softc *);
      78             : void            rt2860_free_tx_pool(struct rt2860_softc *);
      79             : int             rt2860_alloc_rx_ring(struct rt2860_softc *,
      80             :                     struct rt2860_rx_ring *);
      81             : void            rt2860_reset_rx_ring(struct rt2860_softc *,
      82             :                     struct rt2860_rx_ring *);
      83             : void            rt2860_free_rx_ring(struct rt2860_softc *,
      84             :                     struct rt2860_rx_ring *);
      85             : struct          ieee80211_node *rt2860_node_alloc(struct ieee80211com *);
      86             : int             rt2860_media_change(struct ifnet *);
      87             : void            rt2860_iter_func(void *, struct ieee80211_node *);
      88             : void            rt2860_updatestats(struct rt2860_softc *);
      89             : void            rt2860_newassoc(struct ieee80211com *, struct ieee80211_node *,
      90             :                     int);
      91             : void            rt2860_node_leave(struct ieee80211com *,
      92             :                     struct ieee80211_node *);
      93             : int             rt2860_ampdu_rx_start(struct ieee80211com *,
      94             :                     struct ieee80211_node *, uint8_t);
      95             : void            rt2860_ampdu_rx_stop(struct ieee80211com *,
      96             :                     struct ieee80211_node *, uint8_t);
      97             : int             rt2860_newstate(struct ieee80211com *, enum ieee80211_state,
      98             :                     int);
      99             : uint16_t        rt3090_efuse_read_2(struct rt2860_softc *, uint16_t);
     100             : uint16_t        rt2860_eeprom_read_2(struct rt2860_softc *, uint16_t);
     101             : void            rt2860_intr_coherent(struct rt2860_softc *);
     102             : void            rt2860_drain_stats_fifo(struct rt2860_softc *);
     103             : void            rt2860_tx_intr(struct rt2860_softc *, int);
     104             : void            rt2860_rx_intr(struct rt2860_softc *);
     105             : void            rt2860_tbtt_intr(struct rt2860_softc *);
     106             : void            rt2860_gp_intr(struct rt2860_softc *);
     107             : int             rt2860_tx(struct rt2860_softc *, struct mbuf *,
     108             :                     struct ieee80211_node *);
     109             : void            rt2860_start(struct ifnet *);
     110             : void            rt2860_watchdog(struct ifnet *);
     111             : int             rt2860_ioctl(struct ifnet *, u_long, caddr_t);
     112             : void            rt2860_mcu_bbp_write(struct rt2860_softc *, uint8_t, uint8_t);
     113             : uint8_t         rt2860_mcu_bbp_read(struct rt2860_softc *, uint8_t);
     114             : void            rt2860_rf_write(struct rt2860_softc *, uint8_t, uint32_t);
     115             : uint8_t         rt3090_rf_read(struct rt2860_softc *, uint8_t);
     116             : void            rt3090_rf_write(struct rt2860_softc *, uint8_t, uint8_t);
     117             : int             rt2860_mcu_cmd(struct rt2860_softc *, uint8_t, uint16_t, int);
     118             : void            rt2860_enable_mrr(struct rt2860_softc *);
     119             : void            rt2860_set_txpreamble(struct rt2860_softc *);
     120             : void            rt2860_set_basicrates(struct rt2860_softc *);
     121             : void            rt2860_select_chan_group(struct rt2860_softc *, int);
     122             : void            rt2860_set_chan(struct rt2860_softc *, u_int);
     123             : void            rt3090_set_chan(struct rt2860_softc *, u_int);
     124             : void            rt5390_set_chan(struct rt2860_softc *, u_int);
     125             : int             rt3090_rf_init(struct rt2860_softc *);
     126             : void            rt5390_rf_init(struct rt2860_softc *);
     127             : void            rt3090_rf_wakeup(struct rt2860_softc *);
     128             : void            rt5390_rf_wakeup(struct rt2860_softc *);
     129             : int             rt3090_filter_calib(struct rt2860_softc *, uint8_t, uint8_t,
     130             :                     uint8_t *);
     131             : void            rt3090_rf_setup(struct rt2860_softc *);
     132             : void            rt2860_set_leds(struct rt2860_softc *, uint16_t);
     133             : void            rt2860_set_gp_timer(struct rt2860_softc *, int);
     134             : void            rt2860_set_bssid(struct rt2860_softc *, const uint8_t *);
     135             : void            rt2860_set_macaddr(struct rt2860_softc *, const uint8_t *);
     136             : void            rt2860_updateslot(struct ieee80211com *);
     137             : void            rt2860_updateprot(struct ieee80211com *);
     138             : void            rt2860_updateedca(struct ieee80211com *);
     139             : int             rt2860_set_key(struct ieee80211com *, struct ieee80211_node *,
     140             :                     struct ieee80211_key *);
     141             : void            rt2860_delete_key(struct ieee80211com *,
     142             :                     struct ieee80211_node *, struct ieee80211_key *);
     143             : #if NBPFILTER > 0
     144             : int8_t          rt2860_rssi2dbm(struct rt2860_softc *, uint8_t, uint8_t);
     145             : #endif
     146             : const char *    rt2860_get_rf(uint16_t);
     147             : int             rt2860_read_eeprom(struct rt2860_softc *);
     148             : int             rt2860_bbp_init(struct rt2860_softc *);
     149             : void            rt5390_bbp_init(struct rt2860_softc *);
     150             : int             rt2860_txrx_enable(struct rt2860_softc *);
     151             : int             rt2860_init(struct ifnet *);
     152             : void            rt2860_stop(struct ifnet *, int);
     153             : int             rt2860_load_microcode(struct rt2860_softc *);
     154             : void            rt2860_calib(struct rt2860_softc *);
     155             : void            rt3090_set_rx_antenna(struct rt2860_softc *, int);
     156             : void            rt2860_switch_chan(struct rt2860_softc *,
     157             :                     struct ieee80211_channel *);
     158             : #ifndef IEEE80211_STA_ONLY
     159             : int             rt2860_setup_beacon(struct rt2860_softc *);
     160             : #endif
     161             : void            rt2860_enable_tsf_sync(struct rt2860_softc *);
     162             : 
     163             : static const struct {
     164             :         uint32_t        reg;
     165             :         uint32_t        val;
     166             : } rt2860_def_mac[] = {
     167             :         RT2860_DEF_MAC
     168             : };
     169             : 
     170             : static const struct {
     171             :         uint8_t reg;
     172             :         uint8_t val;
     173             : } rt2860_def_bbp[] = {
     174             :         RT2860_DEF_BBP
     175             : },rt5390_def_bbp[] = {
     176             :         RT5390_DEF_BBP
     177             : };
     178             : 
     179             : static const struct rfprog {
     180             :         uint8_t         chan;
     181             :         uint32_t        r1, r2, r3, r4;
     182             : } rt2860_rf2850[] = {
     183             :         RT2860_RF2850
     184             : };
     185             : 
     186             : struct {
     187             :         uint8_t n, r, k;
     188             : } rt3090_freqs[] = {
     189             :         RT3070_RF3052
     190             : };
     191             : 
     192             : static const struct {
     193             :         uint8_t reg;
     194             :         uint8_t val;
     195             : }  rt3090_def_rf[] = {
     196             :         RT3070_DEF_RF
     197             : }, rt3572_def_rf[] = {
     198             :         RT3572_DEF_RF
     199             : }, rt5390_def_rf[] = {
     200             :         RT5390_DEF_RF
     201             : }, rt5392_def_rf[] = {
     202             :         RT5392_DEF_RF
     203             : };
     204             : 
     205             : int
     206           0 : rt2860_attach(void *xsc, int id)
     207             : {
     208           0 :         struct rt2860_softc *sc = xsc;
     209           0 :         struct ieee80211com *ic = &sc->sc_ic;
     210             :         int qid, ntries, error;
     211             :         uint32_t tmp;
     212             : 
     213           0 :         sc->amrr.amrr_min_success_threshold =  1;
     214           0 :         sc->amrr.amrr_max_success_threshold = 15;
     215             : 
     216             :         /* wait for NIC to initialize */
     217           0 :         for (ntries = 0; ntries < 100; ntries++) {
     218           0 :                 tmp = RAL_READ(sc, RT2860_ASIC_VER_ID);
     219           0 :                 if (tmp != 0 && tmp != 0xffffffff)
     220             :                         break;
     221           0 :                 DELAY(10);
     222             :         }
     223           0 :         if (ntries == 100) {
     224           0 :                 printf("%s: timeout waiting for NIC to initialize\n",
     225           0 :                     sc->sc_dev.dv_xname);
     226           0 :                 return ETIMEDOUT;
     227             :         }
     228           0 :         sc->mac_ver = tmp >> 16;
     229           0 :         sc->mac_rev = tmp & 0xffff;
     230             : 
     231           0 :         if (sc->mac_ver != 0x2860 &&
     232           0 :             (id == PCI_PRODUCT_RALINK_RT2890 ||
     233           0 :              id == PCI_PRODUCT_RALINK_RT2790 ||
     234           0 :              id == PCI_PRODUCT_AWT_RT2890))
     235           0 :                 sc->sc_flags |= RT2860_ADVANCED_PS;
     236             : 
     237             :         /* retrieve RF rev. no and various other things from EEPROM */
     238           0 :         rt2860_read_eeprom(sc);
     239           0 :         printf(", address %s\n", ether_sprintf(ic->ic_myaddr));
     240           0 :         printf("%s: MAC/BBP RT%X (rev 0x%04X), RF %s (MIMO %dT%dR)\n",
     241           0 :             sc->sc_dev.dv_xname, sc->mac_ver, sc->mac_rev,
     242           0 :             rt2860_get_rf(sc->rf_rev), sc->ntxchains, sc->nrxchains);
     243             : 
     244             :         /*
     245             :          * Allocate Tx (4 EDCAs + HCCA + Mgt) and Rx rings.
     246             :          */
     247           0 :         for (qid = 0; qid < 6; qid++) {
     248           0 :                 if ((error = rt2860_alloc_tx_ring(sc, &sc->txq[qid])) != 0) {
     249           0 :                         printf("%s: could not allocate Tx ring %d\n",
     250             :                             sc->sc_dev.dv_xname, qid);
     251           0 :                         goto fail1;
     252             :                 }
     253             :         }
     254             : 
     255           0 :         if ((error = rt2860_alloc_rx_ring(sc, &sc->rxq)) != 0) {
     256           0 :                 printf("%s: could not allocate Rx ring\n",
     257             :                     sc->sc_dev.dv_xname);
     258           0 :                 goto fail1;
     259             :         }
     260             : 
     261           0 :         if ((error = rt2860_alloc_tx_pool(sc)) != 0) {
     262           0 :                 printf("%s: could not allocate Tx pool\n",
     263             :                     sc->sc_dev.dv_xname);
     264             :                 goto fail2;
     265             :         }
     266             : 
     267             :         /* mgmt ring is broken on RT2860C, use EDCA AC VO ring instead */
     268           0 :         sc->mgtqid = (sc->mac_ver == 0x2860 && sc->mac_rev == 0x0100) ?
     269             :             EDCA_AC_VO : 5;
     270             : 
     271           0 :         config_mountroot(xsc, rt2860_attachhook);
     272             : 
     273           0 :         return 0;
     274             : 
     275           0 : fail2:  rt2860_free_rx_ring(sc, &sc->rxq);
     276           0 : fail1:  while (--qid >= 0)
     277           0 :                 rt2860_free_tx_ring(sc, &sc->txq[qid]);
     278           0 :         return error;
     279           0 : }
     280             : 
     281             : void
     282           0 : rt2860_attachhook(struct device *self)
     283             : {
     284           0 :         struct rt2860_softc *sc = (struct rt2860_softc *)self;
     285           0 :         struct ieee80211com *ic = &sc->sc_ic;
     286           0 :         struct ifnet *ifp = &ic->ic_if;
     287             :         int i, error;
     288             : 
     289           0 :         error = loadfirmware("ral-rt2860", &sc->ucode, &sc->ucsize);
     290           0 :         if (error != 0) {
     291           0 :                 printf("%s: error %d, could not read firmware file %s\n",
     292           0 :                     sc->sc_dev.dv_xname, error, "ral-rt2860");
     293           0 :                 return;
     294             :         }
     295             : 
     296           0 :         ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
     297           0 :         ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */
     298           0 :         ic->ic_state = IEEE80211_S_INIT;
     299             : 
     300             :         /* set device capabilities */
     301           0 :         ic->ic_caps =
     302             :             IEEE80211_C_MONITOR |       /* monitor mode supported */
     303             : #ifndef IEEE80211_STA_ONLY
     304             :             IEEE80211_C_IBSS |          /* IBSS mode supported */
     305             :             IEEE80211_C_HOSTAP |        /* HostAP mode supported */
     306             :             IEEE80211_C_APPMGT |        /* HostAP power management */
     307             : #endif
     308             :             IEEE80211_C_SHPREAMBLE |    /* short preamble supported */
     309             :             IEEE80211_C_SHSLOT |        /* short slot time supported */
     310             :             IEEE80211_C_WEP |           /* s/w WEP */
     311             :             IEEE80211_C_RSN;            /* WPA/RSN */
     312             : 
     313           0 :         if (sc->rf_rev == RT2860_RF_2750 || sc->rf_rev == RT2860_RF_2850) {
     314             :                 /* set supported .11a rates */
     315           0 :                 ic->ic_sup_rates[IEEE80211_MODE_11A] =
     316           0 :                     ieee80211_std_rateset_11a;
     317             : 
     318             :                 /* set supported .11a channels */
     319           0 :                 for (i = 14; i < nitems(rt2860_rf2850); i++) {
     320           0 :                         uint8_t chan = rt2860_rf2850[i].chan;
     321           0 :                         ic->ic_channels[chan].ic_freq =
     322           0 :                             ieee80211_ieee2mhz(chan, IEEE80211_CHAN_5GHZ);
     323           0 :                         ic->ic_channels[chan].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             :         /* HW supports up to 255 STAs (0-254) in HostAP and IBSS modes */
     341           0 :         ic->ic_max_aid = min(IEEE80211_AID_MAX, RT2860_WCID_MAX);
     342             : 
     343           0 :         ifp->if_softc = sc;
     344           0 :         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
     345           0 :         ifp->if_ioctl = rt2860_ioctl;
     346           0 :         ifp->if_start = rt2860_start;
     347           0 :         ifp->if_watchdog = rt2860_watchdog;
     348           0 :         memcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ);
     349             : 
     350           0 :         if_attach(ifp);
     351           0 :         ieee80211_ifattach(ifp);
     352           0 :         ic->ic_node_alloc = rt2860_node_alloc;
     353           0 :         ic->ic_newassoc = rt2860_newassoc;
     354             : #ifndef IEEE80211_STA_ONLY
     355           0 :         ic->ic_node_leave = rt2860_node_leave;
     356             : #endif
     357           0 :         ic->ic_ampdu_rx_start = rt2860_ampdu_rx_start;
     358           0 :         ic->ic_ampdu_rx_stop = rt2860_ampdu_rx_stop;
     359           0 :         ic->ic_updateslot = rt2860_updateslot;
     360           0 :         ic->ic_updateedca = rt2860_updateedca;
     361           0 :         ic->ic_set_key = rt2860_set_key;
     362           0 :         ic->ic_delete_key = rt2860_delete_key;
     363             :         /* override state transition machine */
     364           0 :         sc->sc_newstate = ic->ic_newstate;
     365           0 :         ic->ic_newstate = rt2860_newstate;
     366           0 :         ieee80211_media_init(ifp, rt2860_media_change, ieee80211_media_status);
     367             : 
     368             : #if NBPFILTER > 0
     369           0 :         bpfattach(&sc->sc_drvbpf, ifp, DLT_IEEE802_11_RADIO,
     370             :             sizeof (struct ieee80211_frame) + 64);
     371             : 
     372           0 :         sc->sc_rxtap_len = sizeof sc->sc_rxtapu;
     373           0 :         sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
     374           0 :         sc->sc_rxtap.wr_ihdr.it_present = htole32(RT2860_RX_RADIOTAP_PRESENT);
     375             : 
     376           0 :         sc->sc_txtap_len = sizeof sc->sc_txtapu;
     377           0 :         sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
     378           0 :         sc->sc_txtap.wt_ihdr.it_present = htole32(RT2860_TX_RADIOTAP_PRESENT);
     379             : #endif
     380           0 : }
     381             : 
     382             : int
     383           0 : rt2860_detach(void *xsc)
     384             : {
     385           0 :         struct rt2860_softc *sc = xsc;
     386           0 :         struct ifnet *ifp = &sc->sc_ic.ic_if;
     387             :         int qid;
     388             : 
     389           0 :         ieee80211_ifdetach(ifp);        /* free all nodes */
     390           0 :         if_detach(ifp);
     391             : 
     392           0 :         for (qid = 0; qid < 6; qid++)
     393           0 :                 rt2860_free_tx_ring(sc, &sc->txq[qid]);
     394           0 :         rt2860_free_rx_ring(sc, &sc->rxq);
     395           0 :         rt2860_free_tx_pool(sc);
     396             : 
     397           0 :         if (sc->ucode != NULL)
     398           0 :                 free(sc->ucode, M_DEVBUF, sc->ucsize);
     399             : 
     400           0 :         return 0;
     401             : }
     402             : 
     403             : void
     404           0 : rt2860_suspend(void *xsc)
     405             : {
     406           0 :         struct rt2860_softc *sc = xsc;
     407           0 :         struct ifnet *ifp = &sc->sc_ic.ic_if;
     408             : 
     409           0 :         if (ifp->if_flags & IFF_RUNNING)
     410           0 :                 rt2860_stop(ifp, 1);
     411           0 : }
     412             : 
     413             : void
     414           0 : rt2860_wakeup(void *xsc)
     415             : {
     416           0 :         struct rt2860_softc *sc = xsc;
     417           0 :         struct ifnet *ifp = &sc->sc_ic.ic_if;
     418             : 
     419           0 :         if (ifp->if_flags & IFF_UP)
     420           0 :                 rt2860_init(ifp);
     421           0 : }
     422             : 
     423             : int
     424           0 : rt2860_alloc_tx_ring(struct rt2860_softc *sc, struct rt2860_tx_ring *ring)
     425             : {
     426           0 :         int nsegs, size, error;
     427             : 
     428             :         size = RT2860_TX_RING_COUNT * sizeof (struct rt2860_txd);
     429             : 
     430           0 :         error = bus_dmamap_create(sc->sc_dmat, size, 1, size, 0,
     431             :             BUS_DMA_NOWAIT, &ring->map);
     432           0 :         if (error != 0) {
     433           0 :                 printf("%s: could not create DMA map\n", sc->sc_dev.dv_xname);
     434           0 :                 goto fail;
     435             :         }
     436             : 
     437             :         /* Tx rings must be 4-DWORD aligned */
     438           0 :         error = bus_dmamem_alloc(sc->sc_dmat, size, 16, 0, &ring->seg, 1,
     439             :             &nsegs, BUS_DMA_NOWAIT | BUS_DMA_ZERO);
     440           0 :         if (error != 0) {
     441           0 :                 printf("%s: could not allocate DMA memory\n",
     442           0 :                     sc->sc_dev.dv_xname);
     443           0 :                 goto fail;
     444             :         }
     445             : 
     446           0 :         error = bus_dmamem_map(sc->sc_dmat, &ring->seg, nsegs, size,
     447             :             (caddr_t *)&ring->txd, BUS_DMA_NOWAIT);
     448           0 :         if (error != 0) {
     449           0 :                 printf("%s: can't map DMA memory\n", sc->sc_dev.dv_xname);
     450           0 :                 goto fail;
     451             :         }
     452             : 
     453           0 :         error = bus_dmamap_load(sc->sc_dmat, ring->map, ring->txd, size, NULL,
     454             :             BUS_DMA_NOWAIT);
     455           0 :         if (error != 0) {
     456           0 :                 printf("%s: could not load DMA map\n", sc->sc_dev.dv_xname);
     457           0 :                 goto fail;
     458             :         }
     459             : 
     460           0 :         bus_dmamap_sync(sc->sc_dmat, ring->map, 0, size, BUS_DMASYNC_PREWRITE);
     461             : 
     462           0 :         ring->paddr = ring->map->dm_segs[0].ds_addr;
     463             : 
     464           0 :         return 0;
     465             : 
     466           0 : fail:   rt2860_free_tx_ring(sc, ring);
     467           0 :         return error;
     468           0 : }
     469             : 
     470             : void
     471           0 : rt2860_reset_tx_ring(struct rt2860_softc *sc, struct rt2860_tx_ring *ring)
     472             : {
     473             :         struct rt2860_tx_data *data;
     474             :         int i;
     475             : 
     476           0 :         for (i = 0; i < RT2860_TX_RING_COUNT; i++) {
     477           0 :                 if ((data = ring->data[i]) == NULL)
     478             :                         continue;       /* nothing mapped in this slot */
     479             : 
     480           0 :                 bus_dmamap_sync(sc->sc_dmat, data->map, 0,
     481             :                     data->map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
     482           0 :                 bus_dmamap_unload(sc->sc_dmat, data->map);
     483           0 :                 m_freem(data->m);
     484           0 :                 data->m= NULL;
     485           0 :                 data->ni = NULL;     /* node already freed */
     486             : 
     487           0 :                 SLIST_INSERT_HEAD(&sc->data_pool, data, next);
     488           0 :                 ring->data[i] = NULL;
     489           0 :         }
     490             : 
     491           0 :         ring->queued = 0;
     492           0 :         ring->cur = ring->next = 0;
     493           0 : }
     494             : 
     495             : void
     496           0 : rt2860_free_tx_ring(struct rt2860_softc *sc, struct rt2860_tx_ring *ring)
     497             : {
     498             :         struct rt2860_tx_data *data;
     499             :         int i;
     500             : 
     501           0 :         if (ring->txd != NULL) {
     502           0 :                 bus_dmamap_sync(sc->sc_dmat, ring->map, 0,
     503             :                     ring->map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
     504           0 :                 bus_dmamap_unload(sc->sc_dmat, ring->map);
     505           0 :                 bus_dmamem_unmap(sc->sc_dmat, (caddr_t)ring->txd,
     506             :                     RT2860_TX_RING_COUNT * sizeof (struct rt2860_txd));
     507           0 :                 bus_dmamem_free(sc->sc_dmat, &ring->seg, 1);
     508           0 :         }
     509           0 :         if (ring->map != NULL)
     510           0 :                 bus_dmamap_destroy(sc->sc_dmat, ring->map);
     511             : 
     512           0 :         for (i = 0; i < RT2860_TX_RING_COUNT; i++) {
     513           0 :                 if ((data = ring->data[i]) == NULL)
     514             :                         continue;       /* nothing mapped in this slot */
     515             : 
     516           0 :                 bus_dmamap_sync(sc->sc_dmat, data->map, 0,
     517             :                     data->map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
     518           0 :                 bus_dmamap_unload(sc->sc_dmat, data->map);
     519           0 :                 m_freem(data->m);
     520             : 
     521           0 :                 SLIST_INSERT_HEAD(&sc->data_pool, data, next);
     522           0 :         }
     523           0 : }
     524             : 
     525             : /*
     526             :  * Allocate a pool of TX Wireless Information blocks.
     527             :  */
     528             : int
     529           0 : rt2860_alloc_tx_pool(struct rt2860_softc *sc)
     530             : {
     531             :         caddr_t vaddr;
     532             :         bus_addr_t paddr;
     533           0 :         int i, nsegs, size, error;
     534             : 
     535             :         size = RT2860_TX_POOL_COUNT * RT2860_TXWI_DMASZ;
     536             : 
     537             :         /* init data_pool early in case of failure.. */
     538           0 :         SLIST_INIT(&sc->data_pool);
     539             : 
     540           0 :         error = bus_dmamap_create(sc->sc_dmat, size, 1, size, 0,
     541             :             BUS_DMA_NOWAIT, &sc->txwi_map);
     542           0 :         if (error != 0) {
     543           0 :                 printf("%s: could not create DMA map\n", sc->sc_dev.dv_xname);
     544           0 :                 goto fail;
     545             :         }
     546             : 
     547           0 :         error = bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0,
     548             :             &sc->txwi_seg, 1, &nsegs, BUS_DMA_NOWAIT | BUS_DMA_ZERO);
     549           0 :         if (error != 0) {
     550           0 :                 printf("%s: could not allocate DMA memory\n",
     551           0 :                     sc->sc_dev.dv_xname);
     552           0 :                 goto fail;
     553             :         }
     554             : 
     555           0 :         error = bus_dmamem_map(sc->sc_dmat, &sc->txwi_seg, nsegs, size,
     556             :             &sc->txwi_vaddr, BUS_DMA_NOWAIT);
     557           0 :         if (error != 0) {
     558           0 :                 printf("%s: can't map DMA memory\n", sc->sc_dev.dv_xname);
     559           0 :                 goto fail;
     560             :         }
     561             : 
     562           0 :         error = bus_dmamap_load(sc->sc_dmat, sc->txwi_map, sc->txwi_vaddr,
     563             :             size, NULL, BUS_DMA_NOWAIT);
     564           0 :         if (error != 0) {
     565           0 :                 printf("%s: could not load DMA map\n", sc->sc_dev.dv_xname);
     566           0 :                 goto fail;
     567             :         }
     568             : 
     569           0 :         bus_dmamap_sync(sc->sc_dmat, sc->txwi_map, 0, size,
     570             :             BUS_DMASYNC_PREWRITE);
     571             : 
     572           0 :         vaddr = sc->txwi_vaddr;
     573           0 :         paddr = sc->txwi_map->dm_segs[0].ds_addr;
     574           0 :         for (i = 0; i < RT2860_TX_POOL_COUNT; i++) {
     575           0 :                 struct rt2860_tx_data *data = &sc->data[i];
     576             : 
     577           0 :                 error = bus_dmamap_create(sc->sc_dmat, MCLBYTES,
     578             :                     RT2860_MAX_SCATTER, MCLBYTES, 0, BUS_DMA_NOWAIT,
     579             :                     &data->map); /* <0> */
     580           0 :                 if (error != 0) {
     581           0 :                         printf("%s: could not create DMA map\n",
     582           0 :                             sc->sc_dev.dv_xname);
     583           0 :                         goto fail;
     584             :                 }
     585           0 :                 data->txwi = (struct rt2860_txwi *)vaddr;
     586           0 :                 data->paddr = paddr;
     587           0 :                 vaddr += RT2860_TXWI_DMASZ;
     588           0 :                 paddr += RT2860_TXWI_DMASZ;
     589             : 
     590           0 :                 SLIST_INSERT_HEAD(&sc->data_pool, data, next);
     591           0 :         }
     592             : 
     593           0 :         return 0;
     594             : 
     595           0 : fail:   rt2860_free_tx_pool(sc);
     596           0 :         return error;
     597           0 : }
     598             : 
     599             : void
     600           0 : rt2860_free_tx_pool(struct rt2860_softc *sc)
     601             : {
     602           0 :         if (sc->txwi_vaddr != NULL) {
     603           0 :                 bus_dmamap_sync(sc->sc_dmat, sc->txwi_map, 0,
     604             :                     sc->txwi_map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
     605           0 :                 bus_dmamap_unload(sc->sc_dmat, sc->txwi_map);
     606           0 :                 bus_dmamem_unmap(sc->sc_dmat, sc->txwi_vaddr,
     607             :                     RT2860_TX_POOL_COUNT * RT2860_TXWI_DMASZ);
     608           0 :                 bus_dmamem_free(sc->sc_dmat, &sc->txwi_seg, 1);
     609           0 :         }
     610           0 :         if (sc->txwi_map != NULL)
     611           0 :                 bus_dmamap_destroy(sc->sc_dmat, sc->txwi_map);
     612             : 
     613           0 :         while (!SLIST_EMPTY(&sc->data_pool)) {
     614             :                 struct rt2860_tx_data *data;
     615             :                 data = SLIST_FIRST(&sc->data_pool);
     616           0 :                 bus_dmamap_destroy(sc->sc_dmat, data->map);
     617           0 :                 SLIST_REMOVE_HEAD(&sc->data_pool, next);
     618             :         }
     619           0 : }
     620             : 
     621             : int
     622           0 : rt2860_alloc_rx_ring(struct rt2860_softc *sc, struct rt2860_rx_ring *ring)
     623             : {
     624           0 :         int i, nsegs, size, error;
     625             : 
     626             :         size = RT2860_RX_RING_COUNT * sizeof (struct rt2860_rxd);
     627             : 
     628           0 :         error = bus_dmamap_create(sc->sc_dmat, size, 1, size, 0,
     629             :             BUS_DMA_NOWAIT, &ring->map);
     630           0 :         if (error != 0) {
     631           0 :                 printf("%s: could not create DMA map\n", sc->sc_dev.dv_xname);
     632           0 :                 goto fail;
     633             :         }
     634             : 
     635             :         /* Rx ring must be 4-DWORD aligned */
     636           0 :         error = bus_dmamem_alloc(sc->sc_dmat, size, 16, 0, &ring->seg, 1,
     637             :             &nsegs, BUS_DMA_NOWAIT | BUS_DMA_ZERO);
     638           0 :         if (error != 0) {
     639           0 :                 printf("%s: could not allocate DMA memory\n",
     640           0 :                     sc->sc_dev.dv_xname);
     641           0 :                 goto fail;
     642             :         }
     643             : 
     644           0 :         error = bus_dmamem_map(sc->sc_dmat, &ring->seg, nsegs, size,
     645             :             (caddr_t *)&ring->rxd, BUS_DMA_NOWAIT);
     646           0 :         if (error != 0) {
     647           0 :                 printf("%s: can't map DMA memory\n", sc->sc_dev.dv_xname);
     648           0 :                 goto fail;
     649             :         }
     650             : 
     651           0 :         error = bus_dmamap_load(sc->sc_dmat, ring->map, ring->rxd, size, NULL,
     652             :             BUS_DMA_NOWAIT);
     653           0 :         if (error != 0) {
     654           0 :                 printf("%s: could not load DMA map\n", sc->sc_dev.dv_xname);
     655           0 :                 goto fail;
     656             :         }
     657             : 
     658           0 :         ring->paddr = ring->map->dm_segs[0].ds_addr;
     659             : 
     660           0 :         for (i = 0; i < RT2860_RX_RING_COUNT; i++) {
     661           0 :                 struct rt2860_rx_data *data = &ring->data[i];
     662           0 :                 struct rt2860_rxd *rxd = &ring->rxd[i];
     663             : 
     664           0 :                 error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES,
     665             :                     0, BUS_DMA_NOWAIT, &data->map);
     666           0 :                 if (error != 0) {
     667           0 :                         printf("%s: could not create DMA map\n",
     668           0 :                             sc->sc_dev.dv_xname);
     669           0 :                         goto fail;
     670             :                 }
     671             : 
     672           0 :                 data->m = MCLGETI(NULL, M_DONTWAIT, NULL, MCLBYTES);
     673           0 :                 if (data->m == NULL) {
     674           0 :                         printf("%s: could not allocate Rx mbuf\n",
     675           0 :                             sc->sc_dev.dv_xname);
     676             :                         error = ENOBUFS;
     677           0 :                         goto fail;
     678             :                 }
     679             : 
     680           0 :                 error = bus_dmamap_load(sc->sc_dmat, data->map,
     681             :                     mtod(data->m, void *), MCLBYTES, NULL,
     682             :                     BUS_DMA_READ | BUS_DMA_NOWAIT);
     683           0 :                 if (error != 0) {
     684           0 :                         printf("%s: could not load DMA map\n",
     685           0 :                             sc->sc_dev.dv_xname);
     686           0 :                         goto fail;
     687             :                 }
     688             : 
     689           0 :                 rxd->sdp0 = htole32(data->map->dm_segs[0].ds_addr);
     690           0 :                 rxd->sdl0 = htole16(MCLBYTES);
     691           0 :         }
     692             : 
     693           0 :         bus_dmamap_sync(sc->sc_dmat, ring->map, 0, size, BUS_DMASYNC_PREWRITE);
     694             : 
     695           0 :         return 0;
     696             : 
     697           0 : fail:   rt2860_free_rx_ring(sc, ring);
     698           0 :         return error;
     699           0 : }
     700             : 
     701             : void
     702           0 : rt2860_reset_rx_ring(struct rt2860_softc *sc, struct rt2860_rx_ring *ring)
     703             : {
     704             :         int i;
     705             : 
     706           0 :         for (i = 0; i < RT2860_RX_RING_COUNT; i++)
     707           0 :                 ring->rxd[i].sdl0 &= ~htole16(RT2860_RX_DDONE);
     708             : 
     709           0 :         bus_dmamap_sync(sc->sc_dmat, ring->map, 0, ring->map->dm_mapsize,
     710             :             BUS_DMASYNC_PREWRITE);
     711             : 
     712           0 :         ring->cur = 0;
     713           0 : }
     714             : 
     715             : void
     716           0 : rt2860_free_rx_ring(struct rt2860_softc *sc, struct rt2860_rx_ring *ring)
     717             : {
     718             :         int i;
     719             : 
     720           0 :         if (ring->rxd != NULL) {
     721           0 :                 bus_dmamap_sync(sc->sc_dmat, ring->map, 0,
     722             :                     ring->map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
     723           0 :                 bus_dmamap_unload(sc->sc_dmat, ring->map);
     724           0 :                 bus_dmamem_unmap(sc->sc_dmat, (caddr_t)ring->rxd,
     725             :                     RT2860_RX_RING_COUNT * sizeof (struct rt2860_rxd));
     726           0 :                 bus_dmamem_free(sc->sc_dmat, &ring->seg, 1);
     727           0 :         }
     728           0 :         if (ring->map != NULL)
     729           0 :                 bus_dmamap_destroy(sc->sc_dmat, ring->map);
     730             : 
     731           0 :         for (i = 0; i < RT2860_RX_RING_COUNT; i++) {
     732           0 :                 struct rt2860_rx_data *data = &ring->data[i];
     733             : 
     734           0 :                 if (data->m != NULL) {
     735           0 :                         bus_dmamap_sync(sc->sc_dmat, data->map, 0,
     736             :                             data->map->dm_mapsize, BUS_DMASYNC_POSTREAD);
     737           0 :                         bus_dmamap_unload(sc->sc_dmat, data->map);
     738           0 :                         m_freem(data->m);
     739           0 :                 }
     740           0 :                 if (data->map != NULL)
     741           0 :                         bus_dmamap_destroy(sc->sc_dmat, data->map);
     742             :         }
     743           0 : }
     744             : 
     745             : struct ieee80211_node *
     746           0 : rt2860_node_alloc(struct ieee80211com *ic)
     747             : {
     748           0 :         return malloc(sizeof (struct rt2860_node), M_DEVBUF,
     749             :             M_NOWAIT | M_ZERO);
     750             : }
     751             : 
     752             : int
     753           0 : rt2860_media_change(struct ifnet *ifp)
     754             : {
     755           0 :         struct rt2860_softc *sc = ifp->if_softc;
     756           0 :         struct ieee80211com *ic = &sc->sc_ic;
     757             :         uint8_t rate, ridx;
     758             :         int error;
     759             : 
     760           0 :         error = ieee80211_media_change(ifp);
     761           0 :         if (error != ENETRESET)
     762           0 :                 return error;
     763             : 
     764           0 :         if (ic->ic_fixed_rate != -1) {
     765           0 :                 rate = ic->ic_sup_rates[ic->ic_curmode].
     766           0 :                     rs_rates[ic->ic_fixed_rate] & IEEE80211_RATE_VAL;
     767           0 :                 for (ridx = 0; ridx <= RT2860_RIDX_MAX; ridx++)
     768           0 :                         if (rt2860_rates[ridx].rate == rate)
     769             :                                 break;
     770           0 :                 sc->fixed_ridx = ridx;
     771           0 :         }
     772             : 
     773           0 :         if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
     774             :             (IFF_UP | IFF_RUNNING)) {
     775           0 :                 rt2860_stop(ifp, 0);
     776           0 :                 rt2860_init(ifp);
     777           0 :         }
     778           0 :         return 0;
     779           0 : }
     780             : 
     781             : void
     782           0 : rt2860_iter_func(void *arg, struct ieee80211_node *ni)
     783             : {
     784           0 :         struct rt2860_softc *sc = arg;
     785           0 :         uint8_t wcid = ((struct rt2860_node *)ni)->wcid;
     786             : 
     787           0 :         ieee80211_amrr_choose(&sc->amrr, ni, &sc->amn[wcid]);
     788           0 : }
     789             : 
     790             : void
     791           0 : rt2860_updatestats(struct rt2860_softc *sc)
     792             : {
     793           0 :         struct ieee80211com *ic = &sc->sc_ic;
     794             : 
     795             : #ifndef IEEE80211_STA_ONLY
     796             :         /*
     797             :          * In IBSS or HostAP modes (when the hardware sends beacons), the
     798             :          * MAC can run into a livelock and start sending CTS-to-self frames
     799             :          * like crazy if protection is enabled.  Fortunately, we can detect
     800             :          * when such a situation occurs and reset the MAC.
     801             :          */
     802           0 :         if (ic->ic_curmode != IEEE80211_M_STA) {
     803             :                 /* check if we're in a livelock situation.. */
     804           0 :                 uint32_t tmp = RAL_READ(sc, RT2860_DEBUG);
     805           0 :                 if ((tmp & (1 << 29)) && (tmp & (1 << 7 | 1 << 5))) {
     806             :                         /* ..and reset MAC/BBP for a while.. */
     807             :                         DPRINTF(("CTS-to-self livelock detected\n"));
     808           0 :                         RAL_WRITE(sc, RT2860_MAC_SYS_CTRL, RT2860_MAC_SRST);
     809           0 :                         RAL_BARRIER_WRITE(sc);
     810           0 :                         DELAY(1);
     811           0 :                         RAL_WRITE(sc, RT2860_MAC_SYS_CTRL,
     812             :                             RT2860_MAC_RX_EN | RT2860_MAC_TX_EN);
     813           0 :                 }
     814           0 :         }
     815             : #endif
     816           0 :         if (ic->ic_opmode == IEEE80211_M_STA)
     817           0 :                 rt2860_iter_func(sc, ic->ic_bss);
     818             : #ifndef IEEE80211_STA_ONLY
     819             :         else
     820           0 :                 ieee80211_iterate_nodes(ic, rt2860_iter_func, sc);
     821             : #endif
     822           0 : }
     823             : 
     824             : void
     825           0 : rt2860_newassoc(struct ieee80211com *ic, struct ieee80211_node *ni, int isnew)
     826             : {
     827           0 :         struct rt2860_softc *sc = ic->ic_softc;
     828           0 :         struct rt2860_node *rn = (void *)ni;
     829           0 :         struct ieee80211_rateset *rs = &ni->ni_rates;
     830             :         uint8_t rate, wcid = 0;
     831             :         int ridx, i, j;
     832             : 
     833           0 :         if (isnew && ni->ni_associd != 0) {
     834             :                 /* only interested in true associations */
     835           0 :                 wcid = rn->wcid = IEEE80211_AID(ni->ni_associd);
     836             : 
     837             :                 /* init WCID table entry */
     838           0 :                 RAL_WRITE_REGION_1(sc, RT2860_WCID_ENTRY(wcid),
     839             :                     ni->ni_macaddr, IEEE80211_ADDR_LEN);
     840           0 :         }
     841             :         DPRINTF(("new assoc isnew=%d addr=%s WCID=%d\n",
     842             :             isnew, ether_sprintf(ni->ni_macaddr), wcid));
     843             : 
     844           0 :         ieee80211_amrr_node_init(&sc->amrr, &sc->amn[wcid]);
     845             :         /* start at lowest available bit-rate, AMRR will raise */
     846           0 :         ni->ni_txrate = 0;
     847             : 
     848           0 :         for (i = 0; i < rs->rs_nrates; i++) {
     849           0 :                 rate = rs->rs_rates[i] & IEEE80211_RATE_VAL;
     850             :                 /* convert 802.11 rate to hardware rate index */
     851           0 :                 for (ridx = 0; ridx < RT2860_RIDX_MAX; ridx++)
     852           0 :                         if (rt2860_rates[ridx].rate == rate)
     853             :                                 break;
     854           0 :                 rn->ridx[i] = ridx;
     855             :                 /* determine rate of control response frames */
     856           0 :                 for (j = i; j >= 0; j--) {
     857           0 :                         if ((rs->rs_rates[j] & IEEE80211_RATE_BASIC) &&
     858           0 :                             rt2860_rates[rn->ridx[i]].phy ==
     859           0 :                             rt2860_rates[rn->ridx[j]].phy)
     860             :                                 break;
     861             :                 }
     862           0 :                 if (j >= 0) {
     863           0 :                         rn->ctl_ridx[i] = rn->ridx[j];
     864           0 :                 } else {
     865             :                         /* no basic rate found, use mandatory one */
     866           0 :                         rn->ctl_ridx[i] = rt2860_rates[ridx].ctl_ridx;
     867             :                 }
     868             :                 DPRINTF(("rate=0x%02x ridx=%d ctl_ridx=%d\n",
     869             :                     rs->rs_rates[i], rn->ridx[i], rn->ctl_ridx[i]));
     870             :         }
     871           0 : }
     872             : 
     873             : #ifndef IEEE80211_STA_ONLY
     874             : void
     875           0 : rt2860_node_leave(struct ieee80211com *ic, struct ieee80211_node *ni)
     876             : {
     877           0 :         struct rt2860_softc *sc = ic->ic_softc;
     878           0 :         uint8_t wcid = ((struct rt2860_node *)ni)->wcid;
     879             : 
     880             :         /* clear Rx WCID search table entry */
     881           0 :         RAL_SET_REGION_4(sc, RT2860_WCID_ENTRY(wcid), 0, 2);
     882           0 : }
     883             : #endif
     884             : 
     885             : int
     886           0 : rt2860_ampdu_rx_start(struct ieee80211com *ic, struct ieee80211_node *ni,
     887             :     uint8_t tid)
     888             : {
     889           0 :         struct rt2860_softc *sc = ic->ic_softc;
     890           0 :         uint8_t wcid = ((struct rt2860_node *)ni)->wcid;
     891             :         uint32_t tmp;
     892             : 
     893             :         /* update BA session mask */
     894           0 :         tmp = RAL_READ(sc, RT2860_WCID_ENTRY(wcid) + 4);
     895           0 :         tmp |= (1 << tid) << 16;
     896           0 :         RAL_WRITE(sc, RT2860_WCID_ENTRY(wcid) + 4, tmp);
     897           0 :         return 0;
     898             : }
     899             : 
     900             : void
     901           0 : rt2860_ampdu_rx_stop(struct ieee80211com *ic, struct ieee80211_node *ni,
     902             :     uint8_t tid)
     903             : {
     904           0 :         struct rt2860_softc *sc = ic->ic_softc;
     905           0 :         uint8_t wcid = ((struct rt2860_node *)ni)->wcid;
     906             :         uint32_t tmp;
     907             : 
     908             :         /* update BA session mask */
     909           0 :         tmp = RAL_READ(sc, RT2860_WCID_ENTRY(wcid) + 4);
     910           0 :         tmp &= ~((1 << tid) << 16);
     911           0 :         RAL_WRITE(sc, RT2860_WCID_ENTRY(wcid) + 4, tmp);
     912           0 : }
     913             : 
     914             : int
     915           0 : rt2860_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
     916             : {
     917           0 :         struct rt2860_softc *sc = ic->ic_if.if_softc;
     918             :         enum ieee80211_state ostate;
     919             :         uint32_t tmp;
     920             : 
     921           0 :         ostate = ic->ic_state;
     922             : 
     923           0 :         if (ostate == IEEE80211_S_RUN) {
     924             :                 /* turn link LED off */
     925           0 :                 rt2860_set_leds(sc, RT2860_LED_RADIO);
     926           0 :         }
     927             : 
     928           0 :         switch (nstate) {
     929             :         case IEEE80211_S_INIT:
     930           0 :                 if (ostate == IEEE80211_S_RUN) {
     931             :                         /* abort TSF synchronization */
     932           0 :                         tmp = RAL_READ(sc, RT2860_BCN_TIME_CFG);
     933           0 :                         RAL_WRITE(sc, RT2860_BCN_TIME_CFG,
     934             :                             tmp & ~(RT2860_BCN_TX_EN | RT2860_TSF_TIMER_EN |
     935             :                             RT2860_TBTT_TIMER_EN));
     936           0 :                 }
     937           0 :                 rt2860_set_gp_timer(sc, 0);
     938           0 :                 break;
     939             : 
     940             :         case IEEE80211_S_SCAN:
     941           0 :                 rt2860_switch_chan(sc, ic->ic_bss->ni_chan);
     942           0 :                 if (ostate != IEEE80211_S_SCAN)
     943           0 :                         rt2860_set_gp_timer(sc, 150);
     944             :                 break;
     945             : 
     946             :         case IEEE80211_S_AUTH:
     947             :         case IEEE80211_S_ASSOC:
     948           0 :                 rt2860_set_gp_timer(sc, 0);
     949           0 :                 rt2860_switch_chan(sc, ic->ic_bss->ni_chan);
     950           0 :                 break;
     951             : 
     952             :         case IEEE80211_S_RUN:
     953           0 :                 rt2860_set_gp_timer(sc, 0);
     954           0 :                 rt2860_switch_chan(sc, ic->ic_bss->ni_chan);
     955             : 
     956           0 :                 if (ic->ic_opmode != IEEE80211_M_MONITOR) {
     957           0 :                         rt2860_updateslot(ic);
     958           0 :                         rt2860_enable_mrr(sc);
     959           0 :                         rt2860_set_txpreamble(sc);
     960           0 :                         rt2860_set_basicrates(sc);
     961           0 :                         rt2860_set_bssid(sc, ic->ic_bss->ni_bssid);
     962           0 :                 }
     963             : 
     964             : #ifndef IEEE80211_STA_ONLY
     965           0 :                 if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
     966           0 :                     ic->ic_opmode == IEEE80211_M_IBSS)
     967           0 :                         (void)rt2860_setup_beacon(sc);
     968             : #endif
     969             : 
     970           0 :                 if (ic->ic_opmode == IEEE80211_M_STA) {
     971             :                         /* fake a join to init the tx rate */
     972           0 :                         rt2860_newassoc(ic, ic->ic_bss, 1);
     973           0 :                 }
     974             : 
     975           0 :                 if (ic->ic_opmode != IEEE80211_M_MONITOR) {
     976           0 :                         rt2860_enable_tsf_sync(sc);
     977           0 :                         rt2860_set_gp_timer(sc, 500);
     978           0 :                 }
     979             : 
     980             :                 /* turn link LED on */
     981           0 :                 rt2860_set_leds(sc, RT2860_LED_RADIO |
     982           0 :                     (IEEE80211_IS_CHAN_2GHZ(ic->ic_bss->ni_chan) ?
     983             :                      RT2860_LED_LINK_2GHZ : RT2860_LED_LINK_5GHZ));
     984           0 :                 break;
     985             :         }
     986             : 
     987           0 :         return sc->sc_newstate(ic, nstate, arg);
     988             : }
     989             : 
     990             : /* Read 16-bit from eFUSE ROM (>=RT3071 only.) */
     991             : uint16_t
     992           0 : rt3090_efuse_read_2(struct rt2860_softc *sc, uint16_t addr)
     993             : {
     994             :         uint32_t tmp;
     995             :         uint16_t reg;
     996             :         int ntries;
     997             : 
     998           0 :         addr *= 2;
     999             :         /*-
    1000             :          * Read one 16-byte block into registers EFUSE_DATA[0-3]:
    1001             :          * DATA0: F E D C
    1002             :          * DATA1: B A 9 8
    1003             :          * DATA2: 7 6 5 4
    1004             :          * DATA3: 3 2 1 0
    1005             :          */
    1006           0 :         tmp = RAL_READ(sc, RT3070_EFUSE_CTRL);
    1007           0 :         tmp &= ~(RT3070_EFSROM_MODE_MASK | RT3070_EFSROM_AIN_MASK);
    1008           0 :         tmp |= (addr & ~0xf) << RT3070_EFSROM_AIN_SHIFT | RT3070_EFSROM_KICK;
    1009           0 :         RAL_WRITE(sc, RT3070_EFUSE_CTRL, tmp);
    1010           0 :         for (ntries = 0; ntries < 500; ntries++) {
    1011           0 :                 tmp = RAL_READ(sc, RT3070_EFUSE_CTRL);
    1012           0 :                 if (!(tmp & RT3070_EFSROM_KICK))
    1013             :                         break;
    1014           0 :                 DELAY(2);
    1015             :         }
    1016           0 :         if (ntries == 500)
    1017           0 :                 return 0xffff;
    1018             : 
    1019           0 :         if ((tmp & RT3070_EFUSE_AOUT_MASK) == RT3070_EFUSE_AOUT_MASK)
    1020           0 :                 return 0xffff;  /* address not found */
    1021             : 
    1022             :         /* determine to which 32-bit register our 16-bit word belongs */
    1023           0 :         reg = RT3070_EFUSE_DATA3 - (addr & 0xc);
    1024           0 :         tmp = RAL_READ(sc, reg);
    1025             : 
    1026           0 :         return (addr & 2) ? tmp >> 16 : tmp & 0xffff;
    1027           0 : }
    1028             : 
    1029             : /*
    1030             :  * Read 16 bits at address 'addr' from the serial EEPROM (either 93C46,
    1031             :  * 93C66 or 93C86).
    1032             :  */
    1033             : uint16_t
    1034           0 : rt2860_eeprom_read_2(struct rt2860_softc *sc, uint16_t addr)
    1035             : {
    1036             :         uint32_t tmp;
    1037             :         uint16_t val;
    1038             :         int n;
    1039             : 
    1040             :         /* clock C once before the first command */
    1041           0 :         RT2860_EEPROM_CTL(sc, 0);
    1042             : 
    1043           0 :         RT2860_EEPROM_CTL(sc, RT2860_S);
    1044           0 :         RT2860_EEPROM_CTL(sc, RT2860_S | RT2860_C);
    1045           0 :         RT2860_EEPROM_CTL(sc, RT2860_S);
    1046             : 
    1047             :         /* write start bit (1) */
    1048           0 :         RT2860_EEPROM_CTL(sc, RT2860_S | RT2860_D);
    1049           0 :         RT2860_EEPROM_CTL(sc, RT2860_S | RT2860_D | RT2860_C);
    1050             : 
    1051             :         /* write READ opcode (10) */
    1052           0 :         RT2860_EEPROM_CTL(sc, RT2860_S | RT2860_D);
    1053           0 :         RT2860_EEPROM_CTL(sc, RT2860_S | RT2860_D | RT2860_C);
    1054           0 :         RT2860_EEPROM_CTL(sc, RT2860_S);
    1055           0 :         RT2860_EEPROM_CTL(sc, RT2860_S | RT2860_C);
    1056             : 
    1057             :         /* write address (A5-A0 or A7-A0) */
    1058           0 :         n = ((RAL_READ(sc, RT2860_PCI_EECTRL) & 0x30) == 0) ? 5 : 7;
    1059           0 :         for (; n >= 0; n--) {
    1060           0 :                 RT2860_EEPROM_CTL(sc, RT2860_S |
    1061             :                     (((addr >> n) & 1) << RT2860_SHIFT_D));
    1062           0 :                 RT2860_EEPROM_CTL(sc, RT2860_S |
    1063             :                     (((addr >> n) & 1) << RT2860_SHIFT_D) | RT2860_C);
    1064             :         }
    1065             : 
    1066           0 :         RT2860_EEPROM_CTL(sc, RT2860_S);
    1067             : 
    1068             :         /* read data Q15-Q0 */
    1069             :         val = 0;
    1070           0 :         for (n = 15; n >= 0; n--) {
    1071           0 :                 RT2860_EEPROM_CTL(sc, RT2860_S | RT2860_C);
    1072           0 :                 tmp = RAL_READ(sc, RT2860_PCI_EECTRL);
    1073           0 :                 val |= ((tmp & RT2860_Q) >> RT2860_SHIFT_Q) << n;
    1074           0 :                 RT2860_EEPROM_CTL(sc, RT2860_S);
    1075             :         }
    1076             : 
    1077           0 :         RT2860_EEPROM_CTL(sc, 0);
    1078             : 
    1079             :         /* clear Chip Select and clock C */
    1080           0 :         RT2860_EEPROM_CTL(sc, RT2860_S);
    1081           0 :         RT2860_EEPROM_CTL(sc, 0);
    1082           0 :         RT2860_EEPROM_CTL(sc, RT2860_C);
    1083             : 
    1084           0 :         return val;
    1085             : }
    1086             : 
    1087             : static __inline uint16_t
    1088           0 : rt2860_srom_read(struct rt2860_softc *sc, uint8_t addr)
    1089             : {
    1090             :         /* either eFUSE ROM or EEPROM */
    1091           0 :         return sc->sc_srom_read(sc, addr);
    1092             : }
    1093             : 
    1094             : void
    1095           0 : rt2860_intr_coherent(struct rt2860_softc *sc)
    1096             : {
    1097             :         uint32_t tmp;
    1098             : 
    1099             :         /* DMA finds data coherent event when checking the DDONE bit */
    1100             : 
    1101             :         DPRINTF(("Tx/Rx Coherent interrupt\n"));
    1102             : 
    1103             :         /* restart DMA engine */
    1104           0 :         tmp = RAL_READ(sc, RT2860_WPDMA_GLO_CFG);
    1105           0 :         tmp &= ~(RT2860_TX_WB_DDONE | RT2860_RX_DMA_EN | RT2860_TX_DMA_EN);
    1106           0 :         RAL_WRITE(sc, RT2860_WPDMA_GLO_CFG, tmp);
    1107             : 
    1108           0 :         (void)rt2860_txrx_enable(sc);
    1109           0 : }
    1110             : 
    1111             : void
    1112           0 : rt2860_drain_stats_fifo(struct rt2860_softc *sc)
    1113             : {
    1114           0 :         struct ifnet *ifp = &sc->sc_ic.ic_if;
    1115             :         struct ieee80211_amrr_node *amn;
    1116             :         uint32_t stat;
    1117             :         uint8_t wcid, mcs, pid;
    1118             : 
    1119             :         /* drain Tx status FIFO (maxsize = 16) */
    1120           0 :         while ((stat = RAL_READ(sc, RT2860_TX_STAT_FIFO)) & RT2860_TXQ_VLD) {
    1121             :                 DPRINTFN(4, ("tx stat 0x%08x\n", stat));
    1122             : 
    1123           0 :                 wcid = (stat >> RT2860_TXQ_WCID_SHIFT) & 0xff;
    1124             : 
    1125             :                 /* if no ACK was requested, no feedback is available */
    1126           0 :                 if (!(stat & RT2860_TXQ_ACKREQ) || wcid == 0xff)
    1127           0 :                         continue;
    1128             : 
    1129             :                 /* update per-STA AMRR stats */
    1130           0 :                 amn = &sc->amn[wcid];
    1131           0 :                 amn->amn_txcnt++;
    1132           0 :                 if (stat & RT2860_TXQ_OK) {
    1133             :                         /*
    1134             :                          * Check if there were retries, ie if the Tx success
    1135             :                          * rate is different from the requested rate.  Note
    1136             :                          * that it works only because we do not allow rate
    1137             :                          * fallback from OFDM to CCK.
    1138             :                          */
    1139           0 :                         mcs = (stat >> RT2860_TXQ_MCS_SHIFT) & 0x7f;
    1140           0 :                         pid = (stat >> RT2860_TXQ_PID_SHIFT) & 0xf;
    1141           0 :                         if (mcs + 1 != pid)
    1142           0 :                                 amn->amn_retrycnt++;
    1143             :                 } else {
    1144           0 :                         amn->amn_retrycnt++;
    1145           0 :                         ifp->if_oerrors++;
    1146             :                 }
    1147             :         }
    1148           0 : }
    1149             : 
    1150             : void
    1151           0 : rt2860_tx_intr(struct rt2860_softc *sc, int qid)
    1152             : {
    1153           0 :         struct ieee80211com *ic = &sc->sc_ic;
    1154           0 :         struct ifnet *ifp = &ic->ic_if;
    1155           0 :         struct rt2860_tx_ring *ring = &sc->txq[qid];
    1156             :         uint32_t hw;
    1157             : 
    1158           0 :         rt2860_drain_stats_fifo(sc);
    1159             : 
    1160           0 :         hw = RAL_READ(sc, RT2860_TX_DTX_IDX(qid));
    1161           0 :         while (ring->next != hw) {
    1162           0 :                 struct rt2860_tx_data *data = ring->data[ring->next];
    1163             : 
    1164           0 :                 if (data != NULL) {
    1165           0 :                         bus_dmamap_sync(sc->sc_dmat, data->map, 0,
    1166             :                             data->map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
    1167           0 :                         bus_dmamap_unload(sc->sc_dmat, data->map);
    1168           0 :                         m_freem(data->m);
    1169           0 :                         data->m= NULL;
    1170           0 :                         ieee80211_release_node(ic, data->ni);
    1171           0 :                         data->ni = NULL;
    1172             : 
    1173           0 :                         SLIST_INSERT_HEAD(&sc->data_pool, data, next);
    1174           0 :                         ring->data[ring->next] = NULL;
    1175           0 :                 }
    1176           0 :                 ring->queued--;
    1177           0 :                 ring->next = (ring->next + 1) % RT2860_TX_RING_COUNT;
    1178             :         }
    1179             : 
    1180           0 :         sc->sc_tx_timer = 0;
    1181           0 :         if (ring->queued <= RT2860_TX_RING_ONEMORE)
    1182           0 :                 sc->qfullmsk &= ~(1 << qid);
    1183           0 :         ifq_clr_oactive(&ifp->if_snd);
    1184           0 :         rt2860_start(ifp);
    1185           0 : }
    1186             : 
    1187             : /*
    1188             :  * Return the Rx chain with the highest RSSI for a given frame.
    1189             :  */
    1190             : static __inline uint8_t
    1191           0 : rt2860_maxrssi_chain(struct rt2860_softc *sc, const struct rt2860_rxwi *rxwi)
    1192             : {
    1193             :         uint8_t rxchain = 0;
    1194             : 
    1195           0 :         if (sc->nrxchains > 1) {
    1196           0 :                 if (rxwi->rssi[1] > rxwi->rssi[rxchain])
    1197           0 :                         rxchain = 1;
    1198           0 :                 if (sc->nrxchains > 2)
    1199           0 :                         if (rxwi->rssi[2] > rxwi->rssi[rxchain])
    1200           0 :                                 rxchain = 2;
    1201             :         }
    1202           0 :         return rxchain;
    1203             : }
    1204             : 
    1205             : void
    1206           0 : rt2860_rx_intr(struct rt2860_softc *sc)
    1207             : {
    1208           0 :         struct ieee80211com *ic = &sc->sc_ic;
    1209           0 :         struct ifnet *ifp = &ic->ic_if;
    1210             :         struct ieee80211_frame *wh;
    1211           0 :         struct ieee80211_rxinfo rxi;
    1212             :         struct ieee80211_node *ni;
    1213             :         struct mbuf *m, *m1;
    1214             :         uint32_t hw;
    1215             :         uint8_t ant, rssi;
    1216             :         int error;
    1217             : #if NBPFILTER > 0
    1218             :         struct rt2860_rx_radiotap_header *tap;
    1219           0 :         struct mbuf mb;
    1220             :         uint16_t phy;
    1221             : #endif
    1222             : 
    1223           0 :         hw = RAL_READ(sc, RT2860_FS_DRX_IDX) & 0xfff;
    1224           0 :         while (sc->rxq.cur != hw) {
    1225           0 :                 struct rt2860_rx_data *data = &sc->rxq.data[sc->rxq.cur];
    1226           0 :                 struct rt2860_rxd *rxd = &sc->rxq.rxd[sc->rxq.cur];
    1227             :                 struct rt2860_rxwi *rxwi;
    1228             : 
    1229           0 :                 bus_dmamap_sync(sc->sc_dmat, sc->rxq.map,
    1230             :                     sc->rxq.cur * sizeof (struct rt2860_rxd),
    1231             :                     sizeof (struct rt2860_rxd), BUS_DMASYNC_POSTREAD);
    1232             : 
    1233           0 :                 if (__predict_false(!(rxd->sdl0 & htole16(RT2860_RX_DDONE)))) {
    1234             :                         DPRINTF(("RXD DDONE bit not set!\n"));
    1235           0 :                         break;  /* should not happen */
    1236             :                 }
    1237             : 
    1238           0 :                 if (__predict_false(rxd->flags &
    1239             :                     htole32(RT2860_RX_CRCERR | RT2860_RX_ICVERR))) {
    1240           0 :                         ifp->if_ierrors++;
    1241           0 :                         goto skip;
    1242             :                 }
    1243             : 
    1244           0 :                 if (__predict_false(rxd->flags & htole32(RT2860_RX_MICERR))) {
    1245             :                         /* report MIC failures to net80211 for TKIP */
    1246           0 :                         ic->ic_stats.is_rx_locmicfail++;
    1247           0 :                         ieee80211_michael_mic_failure(ic, 0/* XXX */);
    1248           0 :                         ifp->if_ierrors++;
    1249           0 :                         goto skip;
    1250             :                 }
    1251             : 
    1252           0 :                 m1 = MCLGETI(NULL, M_DONTWAIT, NULL, MCLBYTES);
    1253           0 :                 if (__predict_false(m1 == NULL)) {
    1254           0 :                         ifp->if_ierrors++;
    1255           0 :                         goto skip;
    1256             :                 }
    1257             : 
    1258           0 :                 bus_dmamap_sync(sc->sc_dmat, data->map, 0,
    1259             :                     data->map->dm_mapsize, BUS_DMASYNC_POSTREAD);
    1260           0 :                 bus_dmamap_unload(sc->sc_dmat, data->map);
    1261             : 
    1262           0 :                 error = bus_dmamap_load(sc->sc_dmat, data->map,
    1263             :                     mtod(m1, void *), MCLBYTES, NULL,
    1264             :                     BUS_DMA_READ | BUS_DMA_NOWAIT);
    1265           0 :                 if (__predict_false(error != 0)) {
    1266           0 :                         m_freem(m1);
    1267             : 
    1268             :                         /* try to reload the old mbuf */
    1269           0 :                         error = bus_dmamap_load(sc->sc_dmat, data->map,
    1270             :                             mtod(data->m, void *), MCLBYTES, NULL,
    1271             :                             BUS_DMA_READ | BUS_DMA_NOWAIT);
    1272           0 :                         if (__predict_false(error != 0)) {
    1273           0 :                                 panic("%s: could not load old rx mbuf",
    1274           0 :                                     sc->sc_dev.dv_xname);
    1275             :                         }
    1276             :                         /* physical address may have changed */
    1277           0 :                         rxd->sdp0 = htole32(data->map->dm_segs[0].ds_addr);
    1278           0 :                         ifp->if_ierrors++;
    1279           0 :                         goto skip;
    1280             :                 }
    1281             : 
    1282             :                 /*
    1283             :                  * New mbuf successfully loaded, update Rx ring and continue
    1284             :                  * processing.
    1285             :                  */
    1286           0 :                 m = data->m;
    1287           0 :                 data->m = m1;
    1288           0 :                 rxd->sdp0 = htole32(data->map->dm_segs[0].ds_addr);
    1289             : 
    1290           0 :                 rxwi = mtod(m, struct rt2860_rxwi *);
    1291             : 
    1292             :                 /* finalize mbuf */
    1293           0 :                 m->m_data = (caddr_t)(rxwi + 1);
    1294           0 :                 m->m_pkthdr.len = m->m_len = letoh16(rxwi->len) & 0xfff;
    1295             : 
    1296           0 :                 wh = mtod(m, struct ieee80211_frame *);
    1297           0 :                 rxi.rxi_flags = 0;
    1298           0 :                 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
    1299             :                         /* frame is decrypted by hardware */
    1300           0 :                         wh->i_fc[1] &= ~IEEE80211_FC1_PROTECTED;
    1301           0 :                         rxi.rxi_flags |= IEEE80211_RXI_HWDEC;
    1302           0 :                 }
    1303             : 
    1304             :                 /* HW may insert 2 padding bytes after 802.11 header */
    1305           0 :                 if (rxd->flags & htole32(RT2860_RX_L2PAD)) {
    1306           0 :                         u_int hdrlen = ieee80211_get_hdrlen(wh);
    1307           0 :                         memmove((caddr_t)wh + 2, wh, hdrlen);
    1308           0 :                         m->m_data += 2;
    1309           0 :                         wh = mtod(m, struct ieee80211_frame *);
    1310           0 :                 }
    1311             : 
    1312           0 :                 ant = rt2860_maxrssi_chain(sc, rxwi);
    1313           0 :                 rssi = rxwi->rssi[ant];
    1314             : 
    1315             : #if NBPFILTER > 0
    1316           0 :                 if (__predict_true(sc->sc_drvbpf == NULL))
    1317             :                         goto skipbpf;
    1318             : 
    1319           0 :                 tap = &sc->sc_rxtap;
    1320           0 :                 tap->wr_flags = 0;
    1321           0 :                 tap->wr_chan_freq = htole16(ic->ic_ibss_chan->ic_freq);
    1322           0 :                 tap->wr_chan_flags = htole16(ic->ic_ibss_chan->ic_flags);
    1323           0 :                 tap->wr_antsignal = rssi;
    1324           0 :                 tap->wr_antenna = ant;
    1325           0 :                 tap->wr_dbm_antsignal = rt2860_rssi2dbm(sc, rssi, ant);
    1326           0 :                 tap->wr_rate = 2;    /* in case it can't be found below */
    1327           0 :                 phy = letoh16(rxwi->phy);
    1328           0 :                 switch (phy & RT2860_PHY_MODE) {
    1329             :                 case RT2860_PHY_CCK:
    1330           0 :                         switch ((phy & RT2860_PHY_MCS) & ~RT2860_PHY_SHPRE) {
    1331           0 :                         case 0: tap->wr_rate =   2; break;
    1332           0 :                         case 1: tap->wr_rate =   4; break;
    1333           0 :                         case 2: tap->wr_rate =  11; break;
    1334           0 :                         case 3: tap->wr_rate =  22; break;
    1335             :                         }
    1336           0 :                         if (phy & RT2860_PHY_SHPRE)
    1337           0 :                                 tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
    1338             :                         break;
    1339             :                 case RT2860_PHY_OFDM:
    1340           0 :                         switch (phy & RT2860_PHY_MCS) {
    1341           0 :                         case 0: tap->wr_rate =  12; break;
    1342           0 :                         case 1: tap->wr_rate =  18; break;
    1343           0 :                         case 2: tap->wr_rate =  24; break;
    1344           0 :                         case 3: tap->wr_rate =  36; break;
    1345           0 :                         case 4: tap->wr_rate =  48; break;
    1346           0 :                         case 5: tap->wr_rate =  72; break;
    1347           0 :                         case 6: tap->wr_rate =  96; break;
    1348           0 :                         case 7: tap->wr_rate = 108; break;
    1349             :                         }
    1350             :                         break;
    1351             :                 }
    1352           0 :                 mb.m_data = (caddr_t)tap;
    1353           0 :                 mb.m_len = sc->sc_rxtap_len;
    1354           0 :                 mb.m_next = m;
    1355           0 :                 mb.m_nextpkt = NULL;
    1356           0 :                 mb.m_type = 0;
    1357           0 :                 mb.m_flags = 0;
    1358           0 :                 bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_IN);
    1359             : skipbpf:
    1360             : #endif
    1361             :                 /* grab a reference to the source node */
    1362           0 :                 ni = ieee80211_find_rxnode(ic, wh);
    1363             : 
    1364             :                 /* send the frame to the 802.11 layer */
    1365           0 :                 rxi.rxi_rssi = rssi;
    1366           0 :                 rxi.rxi_tstamp = 0;     /* unused */
    1367           0 :                 ieee80211_input(ifp, m, ni, &rxi);
    1368             : 
    1369             :                 /* node is no longer needed */
    1370           0 :                 ieee80211_release_node(ic, ni);
    1371             : 
    1372           0 : skip:           rxd->sdl0 &= ~htole16(RT2860_RX_DDONE);
    1373             : 
    1374           0 :                 bus_dmamap_sync(sc->sc_dmat, sc->rxq.map,
    1375             :                     sc->rxq.cur * sizeof (struct rt2860_rxd),
    1376             :                     sizeof (struct rt2860_rxd), BUS_DMASYNC_PREWRITE);
    1377             : 
    1378           0 :                 sc->rxq.cur = (sc->rxq.cur + 1) % RT2860_RX_RING_COUNT;
    1379           0 :         }
    1380             : 
    1381             :         /* tell HW what we have processed */
    1382           0 :         RAL_WRITE(sc, RT2860_RX_CALC_IDX,
    1383             :             (sc->rxq.cur - 1) % RT2860_RX_RING_COUNT);
    1384           0 : }
    1385             : 
    1386             : void
    1387           0 : rt2860_tbtt_intr(struct rt2860_softc *sc)
    1388             : {
    1389           0 :         struct ieee80211com *ic = &sc->sc_ic;
    1390             : 
    1391             : #ifndef IEEE80211_STA_ONLY
    1392           0 :         if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
    1393             :                 /* one less beacon until next DTIM */
    1394           0 :                 if (ic->ic_dtim_count == 0)
    1395           0 :                         ic->ic_dtim_count = ic->ic_dtim_period - 1;
    1396             :                 else
    1397           0 :                         ic->ic_dtim_count--;
    1398             : 
    1399             :                 /* update dynamic parts of beacon */
    1400           0 :                 rt2860_setup_beacon(sc);
    1401             : 
    1402             :                 /* flush buffered multicast frames */
    1403           0 :                 if (ic->ic_dtim_count == 0)
    1404           0 :                         ieee80211_notify_dtim(ic);
    1405             :         }
    1406             : #endif
    1407             :         /* check if protection mode has changed */
    1408           0 :         if ((sc->sc_ic_flags ^ ic->ic_flags) & IEEE80211_F_USEPROT) {
    1409           0 :                 rt2860_updateprot(ic);
    1410           0 :                 sc->sc_ic_flags = ic->ic_flags;
    1411           0 :         }
    1412           0 : }
    1413             : 
    1414             : void
    1415           0 : rt2860_gp_intr(struct rt2860_softc *sc)
    1416             : {
    1417           0 :         struct ieee80211com *ic = &sc->sc_ic;
    1418             : 
    1419             :         DPRINTFN(2, ("GP timeout state=%d\n", ic->ic_state));
    1420             : 
    1421           0 :         if (ic->ic_state == IEEE80211_S_SCAN)
    1422           0 :                 ieee80211_next_scan(&ic->ic_if);
    1423           0 :         else if (ic->ic_state == IEEE80211_S_RUN)
    1424           0 :                 rt2860_updatestats(sc);
    1425           0 : }
    1426             : 
    1427             : int
    1428           0 : rt2860_intr(void *arg)
    1429             : {
    1430           0 :         struct rt2860_softc *sc = arg;
    1431             :         uint32_t r;
    1432             : 
    1433           0 :         r = RAL_READ(sc, RT2860_INT_STATUS);
    1434           0 :         if (__predict_false(r == 0xffffffff))
    1435           0 :                 return 0;       /* device likely went away */
    1436           0 :         if (r == 0)
    1437           0 :                 return 0;       /* not for us */
    1438             : 
    1439             :         /* acknowledge interrupts */
    1440           0 :         RAL_WRITE(sc, RT2860_INT_STATUS, r);
    1441             : 
    1442           0 :         if (r & RT2860_TX_RX_COHERENT)
    1443           0 :                 rt2860_intr_coherent(sc);
    1444             : 
    1445           0 :         if (r & RT2860_MAC_INT_2)   /* TX status */
    1446           0 :                 rt2860_drain_stats_fifo(sc);
    1447             : 
    1448           0 :         if (r & RT2860_TX_DONE_INT5)
    1449           0 :                 rt2860_tx_intr(sc, 5);
    1450             : 
    1451           0 :         if (r & RT2860_RX_DONE_INT)
    1452           0 :                 rt2860_rx_intr(sc);
    1453             : 
    1454           0 :         if (r & RT2860_TX_DONE_INT4)
    1455           0 :                 rt2860_tx_intr(sc, 4);
    1456             : 
    1457           0 :         if (r & RT2860_TX_DONE_INT3)
    1458           0 :                 rt2860_tx_intr(sc, 3);
    1459             : 
    1460           0 :         if (r & RT2860_TX_DONE_INT2)
    1461           0 :                 rt2860_tx_intr(sc, 2);
    1462             : 
    1463           0 :         if (r & RT2860_TX_DONE_INT1)
    1464           0 :                 rt2860_tx_intr(sc, 1);
    1465             : 
    1466           0 :         if (r & RT2860_TX_DONE_INT0)
    1467           0 :                 rt2860_tx_intr(sc, 0);
    1468             : 
    1469           0 :         if (r & RT2860_MAC_INT_0)   /* TBTT */
    1470           0 :                 rt2860_tbtt_intr(sc);
    1471             : 
    1472           0 :         if (r & RT2860_MAC_INT_3)   /* Auto wakeup */
    1473             :                 /* TBD wakeup */;
    1474             : 
    1475           0 :         if (r & RT2860_MAC_INT_4)   /* GP timer */
    1476           0 :                 rt2860_gp_intr(sc);
    1477             : 
    1478           0 :         return 1;
    1479           0 : }
    1480             : 
    1481             : int
    1482           0 : rt2860_tx(struct rt2860_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
    1483             : {
    1484           0 :         struct ieee80211com *ic = &sc->sc_ic;
    1485           0 :         struct rt2860_node *rn = (void *)ni;
    1486             :         struct rt2860_tx_ring *ring;
    1487             :         struct rt2860_tx_data *data;
    1488             :         struct rt2860_txd *txd;
    1489             :         struct rt2860_txwi *txwi;
    1490             :         struct ieee80211_frame *wh;
    1491             :         bus_dma_segment_t *seg;
    1492             :         u_int hdrlen;
    1493             :         uint16_t qos, dur;
    1494             :         uint8_t type, qsel, mcs, pid, tid, qid;
    1495             :         int nsegs, hasqos, ridx, ctl_ridx;
    1496             : 
    1497             :         /* the data pool contains at least one element, pick the first */
    1498           0 :         data = SLIST_FIRST(&sc->data_pool);
    1499             : 
    1500           0 :         wh = mtod(m, struct ieee80211_frame *);
    1501           0 :         hdrlen = ieee80211_get_hdrlen(wh);
    1502           0 :         type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
    1503             : 
    1504           0 :         if ((hasqos = ieee80211_has_qos(wh))) {
    1505           0 :                 qos = ieee80211_get_qos(wh);
    1506           0 :                 tid = qos & IEEE80211_QOS_TID;
    1507           0 :                 qid = ieee80211_up_to_ac(ic, tid);
    1508           0 :         } else {
    1509             :                 qos = 0;
    1510             :                 tid = 0;
    1511           0 :                 qid = (type == IEEE80211_FC0_TYPE_MGT) ?
    1512           0 :                     sc->mgtqid : EDCA_AC_BE;
    1513             :         }
    1514           0 :         ring = &sc->txq[qid];
    1515             : 
    1516             :         /* pickup a rate index */
    1517           0 :         if (IEEE80211_IS_MULTICAST(wh->i_addr1) ||
    1518           0 :             type != IEEE80211_FC0_TYPE_DATA) {
    1519           0 :                 ridx = (ic->ic_curmode == IEEE80211_MODE_11A) ?
    1520             :                     RT2860_RIDX_OFDM6 : RT2860_RIDX_CCK1;
    1521           0 :                 ctl_ridx = rt2860_rates[ridx].ctl_ridx;
    1522           0 :         } else if (ic->ic_fixed_rate != -1) {
    1523           0 :                 ridx = sc->fixed_ridx;
    1524           0 :                 ctl_ridx = rt2860_rates[ridx].ctl_ridx;
    1525           0 :         } else {
    1526           0 :                 ridx = rn->ridx[ni->ni_txrate];
    1527           0 :                 ctl_ridx = rn->ctl_ridx[ni->ni_txrate];
    1528             :         }
    1529             : 
    1530             :         /* get MCS code from rate index */
    1531           0 :         mcs = rt2860_rates[ridx].mcs;
    1532             : 
    1533             :         /* setup TX Wireless Information */
    1534           0 :         txwi = data->txwi;
    1535           0 :         txwi->flags = 0;
    1536             :         /* let HW generate seq numbers for non-QoS frames */
    1537           0 :         txwi->xflags = hasqos ? 0 : RT2860_TX_NSEQ;
    1538           0 :         txwi->wcid = (type == IEEE80211_FC0_TYPE_DATA) ? rn->wcid : 0xff;
    1539           0 :         txwi->len = htole16(m->m_pkthdr.len);
    1540           0 :         if (rt2860_rates[ridx].phy == IEEE80211_T_DS) {
    1541           0 :                 txwi->phy = htole16(RT2860_PHY_CCK);
    1542           0 :                 if (ridx != RT2860_RIDX_CCK1 &&
    1543           0 :                     (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
    1544           0 :                         mcs |= RT2860_PHY_SHPRE;
    1545             :         } else
    1546           0 :                 txwi->phy = htole16(RT2860_PHY_OFDM);
    1547           0 :         txwi->phy |= htole16(mcs);
    1548             : 
    1549             :         /*
    1550             :          * We store the MCS code into the driver-private PacketID field.
    1551             :          * The PacketID is latched into TX_STAT_FIFO when Tx completes so
    1552             :          * that we know at which initial rate the frame was transmitted.
    1553             :          * We add 1 to the MCS code because setting the PacketID field to
    1554             :          * 0 means that we don't want feedback in TX_STAT_FIFO.
    1555             :          */
    1556           0 :         pid = (mcs + 1) & 0xf;
    1557           0 :         txwi->len |= htole16(pid << RT2860_TX_PID_SHIFT);
    1558             : 
    1559             :         /* check if RTS/CTS or CTS-to-self protection is required */
    1560           0 :         if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
    1561           0 :             (m->m_pkthdr.len + IEEE80211_CRC_LEN > ic->ic_rtsthreshold ||
    1562           0 :              ((ic->ic_flags & IEEE80211_F_USEPROT) &&
    1563           0 :               rt2860_rates[ridx].phy == IEEE80211_T_OFDM)))
    1564           0 :                 txwi->txop = RT2860_TX_TXOP_HT;
    1565             :         else
    1566           0 :                 txwi->txop = RT2860_TX_TXOP_BACKOFF;
    1567             : 
    1568           0 :         if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
    1569           0 :             (!hasqos || (qos & IEEE80211_QOS_ACK_POLICY_MASK) !=
    1570             :              IEEE80211_QOS_ACK_POLICY_NOACK)) {
    1571           0 :                 txwi->xflags |= RT2860_TX_ACK;
    1572             : 
    1573           0 :                 if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)
    1574           0 :                         dur = rt2860_rates[ctl_ridx].sp_ack_dur;
    1575             :                 else
    1576           0 :                         dur = rt2860_rates[ctl_ridx].lp_ack_dur;
    1577           0 :                 *(uint16_t *)wh->i_dur = htole16(dur);
    1578           0 :         }
    1579             : #ifndef IEEE80211_STA_ONLY
    1580             :         /* ask MAC to insert timestamp into probe responses */
    1581           0 :         if ((wh->i_fc[0] &
    1582           0 :              (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==
    1583             :              (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_RESP))
    1584             :             /* NOTE: beacons do not pass through tx_data() */
    1585           0 :                 txwi->flags |= RT2860_TX_TS;
    1586             : #endif
    1587             : 
    1588             : #if NBPFILTER > 0
    1589           0 :         if (__predict_false(sc->sc_drvbpf != NULL)) {
    1590           0 :                 struct rt2860_tx_radiotap_header *tap = &sc->sc_txtap;
    1591           0 :                 struct mbuf mb;
    1592             : 
    1593           0 :                 tap->wt_flags = 0;
    1594           0 :                 tap->wt_rate = rt2860_rates[ridx].rate;
    1595           0 :                 tap->wt_chan_freq = htole16(ic->ic_ibss_chan->ic_freq);
    1596           0 :                 tap->wt_chan_flags = htole16(ic->ic_ibss_chan->ic_flags);
    1597           0 :                 tap->wt_hwqueue = qid;
    1598           0 :                 if (mcs & RT2860_PHY_SHPRE)
    1599           0 :                         tap->wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
    1600             : 
    1601           0 :                 mb.m_data = (caddr_t)tap;
    1602           0 :                 mb.m_len = sc->sc_txtap_len;
    1603           0 :                 mb.m_next = m;
    1604           0 :                 mb.m_nextpkt = NULL;
    1605           0 :                 mb.m_type = 0;
    1606           0 :                 mb.m_flags = 0;
    1607           0 :                 bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_OUT);
    1608           0 :         }
    1609             : #endif
    1610             : 
    1611             :         /* copy and trim 802.11 header */
    1612           0 :         memcpy(txwi + 1, wh, hdrlen);
    1613           0 :         m_adj(m, hdrlen);
    1614             : 
    1615           0 :         KASSERT (ring->queued <= RT2860_TX_RING_ONEMORE); /* <1> */
    1616             : 
    1617           0 :         if (bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m, BUS_DMA_NOWAIT)) {
    1618           0 :                 if (m_defrag(m, M_DONTWAIT))
    1619           0 :                         return (ENOBUFS);
    1620           0 :                 if (bus_dmamap_load_mbuf(sc->sc_dmat,
    1621             :                     data->map, m, BUS_DMA_NOWAIT))
    1622           0 :                         return (EFBIG);
    1623             :         }
    1624             : 
    1625             :         /* The map will fit into the tx ring: (a "full" ring may have a few
    1626             :          * unused descriptors, at most (txds(MAX_SCATTER) - 1))
    1627             :          *
    1628             :          *   ring->queued + txds(data->map->nsegs)
    1629             :          * <=        { <0> data->map->nsegs <= MAX_SCATTER }
    1630             :          *   ring->queued + txds(MAX_SCATTER)
    1631             :          * <=        { <1> ring->queued <= TX_RING_MAX - txds(MAX_SCATTER) }
    1632             :          *   TX_RING_MAX - txds(MAX_SCATTER) + txds(MAX_SCATTER)
    1633             :          * <=   { arithmetic }
    1634             :          *   TX_RING_MAX
    1635             :          */
    1636             : 
    1637           0 :         qsel = (qid < EDCA_NUM_AC) ? RT2860_TX_QSEL_EDCA : RT2860_TX_QSEL_MGMT;
    1638             : 
    1639             :         /* first segment is TXWI + 802.11 header */
    1640           0 :         txd = &ring->txd[ring->cur];
    1641           0 :         txd->sdp0 = htole32(data->paddr);
    1642           0 :         txd->sdl0 = htole16(sizeof (struct rt2860_txwi) + hdrlen);
    1643           0 :         txd->flags = qsel;
    1644             : 
    1645             :         /* setup payload segments */
    1646           0 :         seg = data->map->dm_segs;
    1647           0 :         for (nsegs = data->map->dm_nsegs; nsegs >= 2; nsegs -= 2) {
    1648           0 :                 txd->sdp1 = htole32(seg->ds_addr);
    1649           0 :                 txd->sdl1 = htole16(seg->ds_len);
    1650           0 :                 seg++;
    1651           0 :                 ring->cur = (ring->cur + 1) % RT2860_TX_RING_COUNT;
    1652             :                 /* grab a new Tx descriptor */
    1653           0 :                 txd = &ring->txd[ring->cur];
    1654           0 :                 txd->sdp0 = htole32(seg->ds_addr);
    1655           0 :                 txd->sdl0 = htole16(seg->ds_len);
    1656           0 :                 txd->flags = qsel;
    1657           0 :                 seg++;
    1658             :         }
    1659             :         /* finalize last segment */
    1660           0 :         if (nsegs > 0) {
    1661           0 :                 txd->sdp1 = htole32(seg->ds_addr);
    1662           0 :                 txd->sdl1 = htole16(seg->ds_len | RT2860_TX_LS1);
    1663           0 :         } else {
    1664           0 :                 txd->sdl0 |= htole16(RT2860_TX_LS0);
    1665           0 :                 txd->sdl1 = 0;
    1666             :         }
    1667             : 
    1668             :         /* remove from the free pool and link it into the SW Tx slot */
    1669           0 :         SLIST_REMOVE_HEAD(&sc->data_pool, next);
    1670           0 :         data->m = m;
    1671           0 :         data->ni = ni;
    1672           0 :         ring->data[ring->cur] = data;
    1673             : 
    1674           0 :         bus_dmamap_sync(sc->sc_dmat, sc->txwi_map,
    1675             :             (caddr_t)txwi - sc->txwi_vaddr, RT2860_TXWI_DMASZ,
    1676             :             BUS_DMASYNC_PREWRITE);
    1677           0 :         bus_dmamap_sync(sc->sc_dmat, data->map, 0, data->map->dm_mapsize,
    1678             :             BUS_DMASYNC_PREWRITE);
    1679           0 :         bus_dmamap_sync(sc->sc_dmat, ring->map, 0, ring->map->dm_mapsize,
    1680             :             BUS_DMASYNC_PREWRITE);
    1681             : 
    1682             :         DPRINTFN(4, ("sending frame qid=%d wcid=%d nsegs=%d ridx=%d\n",
    1683             :             qid, txwi->wcid, data->map->dm_nsegs, ridx));
    1684             : 
    1685           0 :         ring->cur = (ring->cur + 1) % RT2860_TX_RING_COUNT;
    1686           0 :         ring->queued += 1 + (data->map->dm_nsegs / 2);
    1687           0 :         if (ring->queued > RT2860_TX_RING_ONEMORE)
    1688           0 :                 sc->qfullmsk |= 1 << qid;
    1689             : 
    1690             :         /* kick Tx */
    1691           0 :         RAL_WRITE(sc, RT2860_TX_CTX_IDX(qid), ring->cur);
    1692             : 
    1693           0 :         return 0;
    1694           0 : }
    1695             : 
    1696             : void
    1697           0 : rt2860_start(struct ifnet *ifp)
    1698             : {
    1699           0 :         struct rt2860_softc *sc = ifp->if_softc;
    1700           0 :         struct ieee80211com *ic = &sc->sc_ic;
    1701           0 :         struct ieee80211_node *ni;
    1702             :         struct mbuf *m;
    1703             : 
    1704           0 :         if (!(ifp->if_flags & IFF_RUNNING) || ifq_is_oactive(&ifp->if_snd))
    1705           0 :                 return;
    1706             : 
    1707           0 :         for (;;) {
    1708           0 :                 if (SLIST_EMPTY(&sc->data_pool) || sc->qfullmsk != 0) {
    1709           0 :                         ifq_set_oactive(&ifp->if_snd);
    1710           0 :                         break;
    1711             :                 }
    1712             :                 /* send pending management frames first */
    1713           0 :                 m = mq_dequeue(&ic->ic_mgtq);
    1714           0 :                 if (m != NULL) {
    1715           0 :                         ni = m->m_pkthdr.ph_cookie;
    1716           0 :                         goto sendit;
    1717             :                 }
    1718           0 :                 if (ic->ic_state != IEEE80211_S_RUN)
    1719             :                         break;
    1720             : 
    1721             :                 /* send buffered frames for power-save mode */
    1722           0 :                 m = mq_dequeue(&ic->ic_pwrsaveq);
    1723           0 :                 if (m != NULL) {
    1724           0 :                         ni = m->m_pkthdr.ph_cookie;
    1725           0 :                         goto sendit;
    1726             :                 }
    1727             : 
    1728             :                 /* encapsulate and send data frames */
    1729           0 :                 IFQ_DEQUEUE(&ifp->if_snd, m);
    1730           0 :                 if (m == NULL)
    1731             :                         break;
    1732             : #if NBPFILTER > 0
    1733           0 :                 if (ifp->if_bpf != NULL)
    1734           0 :                         bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT);
    1735             : #endif
    1736           0 :                 if ((m = ieee80211_encap(ifp, m, &ni)) == NULL)
    1737           0 :                         continue;
    1738             : sendit:
    1739             : #if NBPFILTER > 0
    1740           0 :                 if (ic->ic_rawbpf != NULL)
    1741           0 :                         bpf_mtap(ic->ic_rawbpf, m, BPF_DIRECTION_OUT);
    1742             : #endif
    1743           0 :                 if (rt2860_tx(sc, m, ni) != 0) {
    1744           0 :                         m_freem(m);
    1745           0 :                         ieee80211_release_node(ic, ni);
    1746           0 :                         ifp->if_oerrors++;
    1747           0 :                         continue;
    1748             :                 }
    1749             : 
    1750           0 :                 sc->sc_tx_timer = 5;
    1751           0 :                 ifp->if_timer = 1;
    1752             :         }
    1753           0 : }
    1754             : 
    1755             : void
    1756           0 : rt2860_watchdog(struct ifnet *ifp)
    1757             : {
    1758           0 :         struct rt2860_softc *sc = ifp->if_softc;
    1759             : 
    1760           0 :         ifp->if_timer = 0;
    1761             : 
    1762           0 :         if (sc->sc_tx_timer > 0) {
    1763           0 :                 if (--sc->sc_tx_timer == 0) {
    1764           0 :                         printf("%s: device timeout\n", sc->sc_dev.dv_xname);
    1765           0 :                         rt2860_stop(ifp, 0);
    1766           0 :                         rt2860_init(ifp);
    1767           0 :                         ifp->if_oerrors++;
    1768           0 :                         return;
    1769             :                 }
    1770           0 :                 ifp->if_timer = 1;
    1771           0 :         }
    1772             : 
    1773           0 :         ieee80211_watchdog(ifp);
    1774           0 : }
    1775             : 
    1776             : int
    1777           0 : rt2860_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
    1778             : {
    1779           0 :         struct rt2860_softc *sc = ifp->if_softc;
    1780           0 :         struct ieee80211com *ic = &sc->sc_ic;
    1781             :         int s, error = 0;
    1782             : 
    1783           0 :         s = splnet();
    1784             : 
    1785           0 :         switch (cmd) {
    1786             :         case SIOCSIFADDR:
    1787           0 :                 ifp->if_flags |= IFF_UP;
    1788             :                 /* FALLTHROUGH */
    1789             :         case SIOCSIFFLAGS:
    1790           0 :                 if (ifp->if_flags & IFF_UP) {
    1791           0 :                         if (!(ifp->if_flags & IFF_RUNNING))
    1792           0 :                                 rt2860_init(ifp);
    1793             :                 } else {
    1794           0 :                         if (ifp->if_flags & IFF_RUNNING)
    1795           0 :                                 rt2860_stop(ifp, 1);
    1796             :                 }
    1797             :                 break;
    1798             : 
    1799             :         case SIOCS80211CHANNEL:
    1800             :                 /*
    1801             :                  * This allows for fast channel switching in monitor mode
    1802             :                  * (used by kismet). In IBSS mode, we must explicitly reset
    1803             :                  * the interface to generate a new beacon frame.
    1804             :                  */
    1805           0 :                 error = ieee80211_ioctl(ifp, cmd, data);
    1806           0 :                 if (error == ENETRESET &&
    1807           0 :                     ic->ic_opmode == IEEE80211_M_MONITOR) {
    1808           0 :                         if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
    1809             :                             (IFF_UP | IFF_RUNNING))
    1810           0 :                                 rt2860_switch_chan(sc, ic->ic_ibss_chan);
    1811             :                         error = 0;
    1812           0 :                 }
    1813             :                 break;
    1814             : 
    1815             :         default:
    1816           0 :                 error = ieee80211_ioctl(ifp, cmd, data);
    1817           0 :         }
    1818             : 
    1819           0 :         if (error == ENETRESET) {
    1820           0 :                 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
    1821             :                     (IFF_UP | IFF_RUNNING)) {
    1822           0 :                         rt2860_stop(ifp, 0);
    1823           0 :                         rt2860_init(ifp);
    1824           0 :                 }
    1825             :                 error = 0;
    1826           0 :         }
    1827             : 
    1828           0 :         splx(s);
    1829             : 
    1830           0 :         return error;
    1831             : }
    1832             : 
    1833             : /*
    1834             :  * Reading and writing from/to the BBP is different from RT2560 and RT2661.
    1835             :  * We access the BBP through the 8051 microcontroller unit which means that
    1836             :  * the microcode must be loaded first.
    1837             :  */
    1838             : void
    1839           0 : rt2860_mcu_bbp_write(struct rt2860_softc *sc, uint8_t reg, uint8_t val)
    1840             : {
    1841             :         int ntries;
    1842             : 
    1843           0 :         for (ntries = 0; ntries < 100; ntries++) {
    1844           0 :                 if (!(RAL_READ(sc, RT2860_H2M_BBPAGENT) & RT2860_BBP_CSR_KICK))
    1845             :                         break;
    1846           0 :                 DELAY(1);
    1847             :         }
    1848           0 :         if (ntries == 100) {
    1849           0 :                 printf("%s: could not write to BBP through MCU\n",
    1850           0 :                     sc->sc_dev.dv_xname);
    1851           0 :                 return;
    1852             :         }
    1853             : 
    1854           0 :         RAL_WRITE(sc, RT2860_H2M_BBPAGENT, RT2860_BBP_RW_PARALLEL |
    1855             :             RT2860_BBP_CSR_KICK | reg << 8 | val);
    1856           0 :         RAL_BARRIER_WRITE(sc);
    1857             : 
    1858           0 :         rt2860_mcu_cmd(sc, RT2860_MCU_CMD_BBP, 0, 0);
    1859           0 :         DELAY(1000);
    1860           0 : }
    1861             : 
    1862             : uint8_t
    1863           0 : rt2860_mcu_bbp_read(struct rt2860_softc *sc, uint8_t reg)
    1864             : {
    1865             :         uint32_t val;
    1866             :         int ntries;
    1867             : 
    1868           0 :         for (ntries = 0; ntries < 100; ntries++) {
    1869           0 :                 if (!(RAL_READ(sc, RT2860_H2M_BBPAGENT) & RT2860_BBP_CSR_KICK))
    1870             :                         break;
    1871           0 :                 DELAY(1);
    1872             :         }
    1873           0 :         if (ntries == 100) {
    1874           0 :                 printf("%s: could not read from BBP through MCU\n",
    1875           0 :                     sc->sc_dev.dv_xname);
    1876           0 :                 return 0;
    1877             :         }
    1878             : 
    1879           0 :         RAL_WRITE(sc, RT2860_H2M_BBPAGENT, RT2860_BBP_RW_PARALLEL |
    1880             :             RT2860_BBP_CSR_KICK | RT2860_BBP_CSR_READ | reg << 8);
    1881           0 :         RAL_BARRIER_WRITE(sc);
    1882             : 
    1883           0 :         rt2860_mcu_cmd(sc, RT2860_MCU_CMD_BBP, 0, 0);
    1884           0 :         DELAY(1000);
    1885             : 
    1886           0 :         for (ntries = 0; ntries < 100; ntries++) {
    1887           0 :                 val = RAL_READ(sc, RT2860_H2M_BBPAGENT);
    1888           0 :                 if (!(val & RT2860_BBP_CSR_KICK))
    1889           0 :                         return val & 0xff;
    1890           0 :                 DELAY(1);
    1891             :         }
    1892           0 :         printf("%s: could not read from BBP through MCU\n",
    1893           0 :             sc->sc_dev.dv_xname);
    1894             : 
    1895           0 :         return 0;
    1896           0 : }
    1897             : 
    1898             : /*
    1899             :  * Write to one of the 4 programmable 24-bit RF registers.
    1900             :  */
    1901             : void
    1902           0 : rt2860_rf_write(struct rt2860_softc *sc, uint8_t reg, uint32_t val)
    1903             : {
    1904             :         uint32_t tmp;
    1905             :         int ntries;
    1906             : 
    1907           0 :         for (ntries = 0; ntries < 100; ntries++) {
    1908           0 :                 if (!(RAL_READ(sc, RT2860_RF_CSR_CFG0) & RT2860_RF_REG_CTRL))
    1909             :                         break;
    1910           0 :                 DELAY(1);
    1911             :         }
    1912           0 :         if (ntries == 100) {
    1913           0 :                 printf("%s: could not write to RF\n", sc->sc_dev.dv_xname);
    1914           0 :                 return;
    1915             :         }
    1916             : 
    1917             :         /* RF registers are 24-bit on the RT2860 */
    1918           0 :         tmp = RT2860_RF_REG_CTRL | 24 << RT2860_RF_REG_WIDTH_SHIFT |
    1919           0 :             (val & 0x3fffff) << 2 | (reg & 3);
    1920           0 :         RAL_WRITE(sc, RT2860_RF_CSR_CFG0, tmp);
    1921           0 : }
    1922             : 
    1923             : uint8_t
    1924           0 : rt3090_rf_read(struct rt2860_softc *sc, uint8_t reg)
    1925             : {
    1926             :         uint32_t tmp;
    1927             :         int ntries;
    1928             : 
    1929           0 :         for (ntries = 0; ntries < 100; ntries++) {
    1930           0 :                 if (!(RAL_READ(sc, RT3070_RF_CSR_CFG) & RT3070_RF_KICK))
    1931             :                         break;
    1932           0 :                 DELAY(1);
    1933             :         }
    1934           0 :         if (ntries == 100) {
    1935           0 :                 printf("%s: could not read RF register\n",
    1936           0 :                     sc->sc_dev.dv_xname);
    1937           0 :                 return 0xff;
    1938             :         }
    1939           0 :         tmp = RT3070_RF_KICK | reg << 8;
    1940           0 :         RAL_WRITE(sc, RT3070_RF_CSR_CFG, tmp);
    1941             : 
    1942           0 :         for (ntries = 0; ntries < 100; ntries++) {
    1943           0 :                 tmp = RAL_READ(sc, RT3070_RF_CSR_CFG);
    1944           0 :                 if (!(tmp & RT3070_RF_KICK))
    1945             :                         break;
    1946           0 :                 DELAY(1);
    1947             :         }
    1948           0 :         if (ntries == 100) {
    1949           0 :                 printf("%s: could not read RF register\n",
    1950           0 :                     sc->sc_dev.dv_xname);
    1951           0 :                 return 0xff;
    1952             :         }
    1953           0 :         return tmp & 0xff;
    1954           0 : }
    1955             : 
    1956             : void
    1957           0 : rt3090_rf_write(struct rt2860_softc *sc, uint8_t reg, uint8_t val)
    1958             : {
    1959             :         uint32_t tmp;
    1960             :         int ntries;
    1961             : 
    1962           0 :         for (ntries = 0; ntries < 10; ntries++) {
    1963           0 :                 if (!(RAL_READ(sc, RT3070_RF_CSR_CFG) & RT3070_RF_KICK))
    1964             :                         break;
    1965           0 :                 DELAY(10);
    1966             :         }
    1967           0 :         if (ntries == 10) {
    1968           0 :                 printf("%s: could not write to RF\n", sc->sc_dev.dv_xname);
    1969           0 :                 return;
    1970             :         }
    1971             : 
    1972           0 :         tmp = RT3070_RF_WRITE | RT3070_RF_KICK | reg << 8 | val;
    1973           0 :         RAL_WRITE(sc, RT3070_RF_CSR_CFG, tmp);
    1974           0 : }
    1975             : 
    1976             : /*
    1977             :  * Send a command to the 8051 microcontroller unit.
    1978             :  */
    1979             : int
    1980           0 : rt2860_mcu_cmd(struct rt2860_softc *sc, uint8_t cmd, uint16_t arg, int wait)
    1981             : {
    1982             :         int slot, ntries;
    1983             :         uint32_t tmp;
    1984             :         uint8_t cid;
    1985             : 
    1986           0 :         for (ntries = 0; ntries < 100; ntries++) {
    1987           0 :                 if (!(RAL_READ(sc, RT2860_H2M_MAILBOX) & RT2860_H2M_BUSY))
    1988             :                         break;
    1989           0 :                 DELAY(2);
    1990             :         }
    1991           0 :         if (ntries == 100)
    1992           0 :                 return EIO;
    1993             : 
    1994           0 :         cid = wait ? cmd : RT2860_TOKEN_NO_INTR;
    1995           0 :         RAL_WRITE(sc, RT2860_H2M_MAILBOX, RT2860_H2M_BUSY | cid << 16 | arg);
    1996           0 :         RAL_BARRIER_WRITE(sc);
    1997           0 :         RAL_WRITE(sc, RT2860_HOST_CMD, cmd);
    1998             : 
    1999           0 :         if (!wait)
    2000           0 :                 return 0;
    2001             :         /* wait for the command to complete */
    2002           0 :         for (ntries = 0; ntries < 200; ntries++) {
    2003           0 :                 tmp = RAL_READ(sc, RT2860_H2M_MAILBOX_CID);
    2004             :                 /* find the command slot */
    2005           0 :                 for (slot = 0; slot < 4; slot++, tmp >>= 8)
    2006           0 :                         if ((tmp & 0xff) == cid)
    2007             :                                 break;
    2008           0 :                 if (slot < 4)
    2009             :                         break;
    2010           0 :                 DELAY(100);
    2011             :         }
    2012           0 :         if (ntries == 200) {
    2013             :                 /* clear command and status */
    2014           0 :                 RAL_WRITE(sc, RT2860_H2M_MAILBOX_STATUS, 0xffffffff);
    2015           0 :                 RAL_WRITE(sc, RT2860_H2M_MAILBOX_CID, 0xffffffff);
    2016           0 :                 return ETIMEDOUT;
    2017             :         }
    2018             :         /* get command status (1 means success) */
    2019           0 :         tmp = RAL_READ(sc, RT2860_H2M_MAILBOX_STATUS);
    2020           0 :         tmp = (tmp >> (slot * 8)) & 0xff;
    2021             :         DPRINTF(("MCU command=0x%02x slot=%d status=0x%02x\n",
    2022             :             cmd, slot, tmp));
    2023             :         /* clear command and status */
    2024           0 :         RAL_WRITE(sc, RT2860_H2M_MAILBOX_STATUS, 0xffffffff);
    2025           0 :         RAL_WRITE(sc, RT2860_H2M_MAILBOX_CID, 0xffffffff);
    2026           0 :         return (tmp == 1) ? 0 : EIO;
    2027           0 : }
    2028             : 
    2029             : void
    2030           0 : rt2860_enable_mrr(struct rt2860_softc *sc)
    2031             : {
    2032             : #define CCK(mcs)        (mcs)
    2033             : #define OFDM(mcs)       (1 << 3 | (mcs))
    2034           0 :         RAL_WRITE(sc, RT2860_LG_FBK_CFG0,
    2035             :             OFDM(6) << 28 |       /* 54->48 */
    2036             :             OFDM(5) << 24 |       /* 48->36 */
    2037             :             OFDM(4) << 20 |       /* 36->24 */
    2038             :             OFDM(3) << 16 |       /* 24->18 */
    2039             :             OFDM(2) << 12 |       /* 18->12 */
    2040             :             OFDM(1) <<  8 |       /* 12-> 9 */
    2041             :             OFDM(0) <<  4 |       /*  9-> 6 */
    2042             :             OFDM(0));           /*  6-> 6 */
    2043             : 
    2044           0 :         RAL_WRITE(sc, RT2860_LG_FBK_CFG1,
    2045             :             CCK(2) << 12 |        /* 11->5.5 */
    2046             :             CCK(1) <<  8 |        /* 5.5-> 2 */
    2047             :             CCK(0) <<  4 |        /*   2-> 1 */
    2048             :             CCK(0));            /*   1-> 1 */
    2049             : #undef OFDM
    2050             : #undef CCK
    2051           0 : }
    2052             : 
    2053             : void
    2054           0 : rt2860_set_txpreamble(struct rt2860_softc *sc)
    2055             : {
    2056             :         uint32_t tmp;
    2057             : 
    2058           0 :         tmp = RAL_READ(sc, RT2860_AUTO_RSP_CFG);
    2059           0 :         tmp &= ~RT2860_CCK_SHORT_EN;
    2060           0 :         if (sc->sc_ic.ic_flags & IEEE80211_F_SHPREAMBLE)
    2061           0 :                 tmp |= RT2860_CCK_SHORT_EN;
    2062           0 :         RAL_WRITE(sc, RT2860_AUTO_RSP_CFG, tmp);
    2063           0 : }
    2064             : 
    2065             : void
    2066           0 : rt2860_set_basicrates(struct rt2860_softc *sc)
    2067             : {
    2068           0 :         struct ieee80211com *ic = &sc->sc_ic;
    2069             : 
    2070             :         /* set basic rates mask */
    2071           0 :         if (ic->ic_curmode == IEEE80211_MODE_11B)
    2072           0 :                 RAL_WRITE(sc, RT2860_LEGACY_BASIC_RATE, 0x003);
    2073           0 :         else if (ic->ic_curmode == IEEE80211_MODE_11A)
    2074           0 :                 RAL_WRITE(sc, RT2860_LEGACY_BASIC_RATE, 0x150);
    2075             :         else    /* 11g */
    2076           0 :                 RAL_WRITE(sc, RT2860_LEGACY_BASIC_RATE, 0x15f);
    2077           0 : }
    2078             : 
    2079             : void
    2080           0 : rt2860_select_chan_group(struct rt2860_softc *sc, int group)
    2081             : {
    2082             :         uint32_t tmp;
    2083             :         uint8_t agc;
    2084             : 
    2085             :         /* Wait for BBP to settle */
    2086           0 :         DELAY(1000);
    2087             : 
    2088           0 :         rt2860_mcu_bbp_write(sc, 62, 0x37 - sc->lna[group]);
    2089           0 :         rt2860_mcu_bbp_write(sc, 63, 0x37 - sc->lna[group]);
    2090           0 :         rt2860_mcu_bbp_write(sc, 64, 0x37 - sc->lna[group]);
    2091           0 :         rt2860_mcu_bbp_write(sc, 86, 0x00);
    2092             : 
    2093           0 :         if (group == 0) {
    2094           0 :                 if (sc->ext_2ghz_lna) {
    2095           0 :                         rt2860_mcu_bbp_write(sc, 82, 0x62);
    2096           0 :                         rt2860_mcu_bbp_write(sc, 75, 0x46);
    2097           0 :                 } else {
    2098           0 :                         rt2860_mcu_bbp_write(sc, 82, 0x84);
    2099           0 :                         rt2860_mcu_bbp_write(sc, 75, 0x50);
    2100             :                 }
    2101             :         } else {
    2102           0 :                 if (sc->mac_ver == 0x3572)
    2103           0 :                         rt2860_mcu_bbp_write(sc, 82, 0x94);
    2104             :                 else
    2105           0 :                         rt2860_mcu_bbp_write(sc, 82, 0xf2);
    2106             : 
    2107           0 :                 if (sc->ext_5ghz_lna)
    2108           0 :                         rt2860_mcu_bbp_write(sc, 75, 0x46);
    2109             :                 else
    2110           0 :                         rt2860_mcu_bbp_write(sc, 75, 0x50);
    2111             :         }
    2112             : 
    2113           0 :         tmp = RAL_READ(sc, RT2860_TX_BAND_CFG);
    2114           0 :         tmp &= ~(RT2860_5G_BAND_SEL_N | RT2860_5G_BAND_SEL_P);
    2115           0 :         tmp |= (group == 0) ? RT2860_5G_BAND_SEL_N : RT2860_5G_BAND_SEL_P;
    2116           0 :         RAL_WRITE(sc, RT2860_TX_BAND_CFG, tmp);
    2117             : 
    2118             :         /* enable appropriate Power Amplifiers and Low Noise Amplifiers */
    2119             :         tmp = RT2860_RFTR_EN | RT2860_TRSW_EN | RT2860_LNA_PE0_EN;
    2120           0 :         if (sc->nrxchains > 1)
    2121           0 :                 tmp |= RT2860_LNA_PE1_EN;
    2122           0 :         if (sc->mac_ver == 0x3593 && sc->nrxchains > 2)
    2123           0 :                 tmp |= RT3593_LNA_PE2_EN;
    2124           0 :         if (group == 0) {       /* 2GHz */
    2125           0 :                 tmp |= RT2860_PA_PE_G0_EN;
    2126           0 :                 if (sc->ntxchains > 1)
    2127           0 :                         tmp |= RT2860_PA_PE_G1_EN;
    2128           0 :                 if (sc->mac_ver == 0x3593 && sc->ntxchains > 2)
    2129           0 :                         tmp |= RT3593_PA_PE_G2_EN;
    2130             :         } else {                /* 5GHz */
    2131           0 :                 tmp |= RT2860_PA_PE_A0_EN;
    2132           0 :                 if (sc->ntxchains > 1)
    2133           0 :                         tmp |= RT2860_PA_PE_A1_EN;
    2134           0 :                 if (sc->mac_ver == 0x3593 && sc->ntxchains > 2)
    2135           0 :                         tmp |= RT3593_PA_PE_A2_EN;
    2136             :         }
    2137           0 :         if (sc->mac_ver == 0x3572) {
    2138           0 :                 rt3090_rf_write(sc, 8, 0x00);
    2139           0 :                 RAL_WRITE(sc, RT2860_TX_PIN_CFG, tmp);
    2140           0 :                 rt3090_rf_write(sc, 8, 0x80);
    2141           0 :         } else
    2142           0 :                 RAL_WRITE(sc, RT2860_TX_PIN_CFG, tmp);
    2143             : 
    2144           0 :         if (sc->mac_ver == 0x3593) {
    2145           0 :                 tmp = RAL_READ(sc, RT2860_GPIO_CTRL);
    2146           0 :                 if (sc->sc_flags & RT2860_PCIE) {
    2147           0 :                         tmp &= ~0x01010000;
    2148           0 :                         if (group == 0)
    2149           0 :                                 tmp |= 0x00010000;
    2150             :                 } else {
    2151           0 :                         tmp &= ~0x00008080;
    2152           0 :                         if (group == 0)
    2153           0 :                                 tmp |= 0x00000080;
    2154             :                 }
    2155           0 :                 tmp = (tmp & ~0x00001000) | 0x00000010;
    2156           0 :                 RAL_WRITE(sc, RT2860_GPIO_CTRL, tmp);
    2157           0 :         }
    2158             : 
    2159             :         /* set initial AGC value */
    2160           0 :         if (group == 0) {       /* 2GHz band */
    2161           0 :                 if (sc->mac_ver >= 0x3071)
    2162           0 :                         agc = 0x1c + sc->lna[0] * 2;
    2163             :                 else
    2164           0 :                         agc = 0x2e + sc->lna[0];
    2165             :         } else {                /* 5GHz band */
    2166           0 :                 if (sc->mac_ver == 0x3572)
    2167           0 :                         agc = 0x22 + (sc->lna[group] * 5) / 3;
    2168             :                 else
    2169           0 :                         agc = 0x32 + (sc->lna[group] * 5) / 3;
    2170             :         }
    2171           0 :         rt2860_mcu_bbp_write(sc, 66, agc);
    2172             : 
    2173           0 :         DELAY(1000);
    2174           0 : }
    2175             : 
    2176             : void
    2177           0 : rt2860_set_chan(struct rt2860_softc *sc, u_int chan)
    2178             : {
    2179             :         const struct rfprog *rfprog = rt2860_rf2850;
    2180             :         uint32_t r2, r3, r4;
    2181             :         int8_t txpow1, txpow2;
    2182             :         u_int i;
    2183             : 
    2184             :         /* find the settings for this channel (we know it exists) */
    2185           0 :         for (i = 0; rfprog[i].chan != chan; i++);
    2186             : 
    2187           0 :         r2 = rfprog[i].r2;
    2188           0 :         if (sc->ntxchains == 1)
    2189           0 :                 r2 |= 1 << 12;            /* 1T: disable Tx chain 2 */
    2190           0 :         if (sc->nrxchains == 1)
    2191           0 :                 r2 |= 1 << 15 | 1 << 4;     /* 1R: disable Rx chains 2 & 3 */
    2192           0 :         else if (sc->nrxchains == 2)
    2193           0 :                 r2 |= 1 << 4;             /* 2R: disable Rx chain 3 */
    2194             : 
    2195             :         /* use Tx power values from EEPROM */
    2196           0 :         txpow1 = sc->txpow1[i];
    2197           0 :         txpow2 = sc->txpow2[i];
    2198           0 :         if (chan > 14) {
    2199           0 :                 if (txpow1 >= 0)
    2200           0 :                         txpow1 = txpow1 << 1 | 1;
    2201             :                 else
    2202           0 :                         txpow1 = (7 + txpow1) << 1;
    2203           0 :                 if (txpow2 >= 0)
    2204           0 :                         txpow2 = txpow2 << 1 | 1;
    2205             :                 else
    2206           0 :                         txpow2 = (7 + txpow2) << 1;
    2207             :         }
    2208           0 :         r3 = rfprog[i].r3 | txpow1 << 7;
    2209           0 :         r4 = rfprog[i].r4 | sc->freq << 13 | txpow2 << 4;
    2210             : 
    2211           0 :         rt2860_rf_write(sc, RT2860_RF1, rfprog[i].r1);
    2212           0 :         rt2860_rf_write(sc, RT2860_RF2, r2);
    2213           0 :         rt2860_rf_write(sc, RT2860_RF3, r3);
    2214           0 :         rt2860_rf_write(sc, RT2860_RF4, r4);
    2215             : 
    2216           0 :         DELAY(200);
    2217             : 
    2218           0 :         rt2860_rf_write(sc, RT2860_RF1, rfprog[i].r1);
    2219           0 :         rt2860_rf_write(sc, RT2860_RF2, r2);
    2220           0 :         rt2860_rf_write(sc, RT2860_RF3, r3 | 1);
    2221           0 :         rt2860_rf_write(sc, RT2860_RF4, r4);
    2222             : 
    2223           0 :         DELAY(200);
    2224             : 
    2225           0 :         rt2860_rf_write(sc, RT2860_RF1, rfprog[i].r1);
    2226           0 :         rt2860_rf_write(sc, RT2860_RF2, r2);
    2227           0 :         rt2860_rf_write(sc, RT2860_RF3, r3);
    2228           0 :         rt2860_rf_write(sc, RT2860_RF4, r4);
    2229           0 : }
    2230             : 
    2231             : void
    2232           0 : rt3090_set_chan(struct rt2860_softc *sc, u_int chan)
    2233             : {
    2234             :         int8_t txpow1, txpow2;
    2235             :         uint8_t rf;
    2236             :         int i;
    2237             : 
    2238           0 :         KASSERT(chan >= 1 && chan <= 14); /* RT3090 is 2GHz only */
    2239             : 
    2240             :         /* find the settings for this channel (we know it exists) */
    2241           0 :         for (i = 0; rt2860_rf2850[i].chan != chan; i++);
    2242             : 
    2243             :         /* use Tx power values from EEPROM */
    2244           0 :         txpow1 = sc->txpow1[i];
    2245           0 :         txpow2 = sc->txpow2[i];
    2246             : 
    2247           0 :         rt3090_rf_write(sc, 2, rt3090_freqs[i].n);
    2248           0 :         rf = rt3090_rf_read(sc, 3);
    2249           0 :         rf = (rf & ~0x0f) | rt3090_freqs[i].k;
    2250           0 :         rt3090_rf_write(sc, 3, rf);
    2251           0 :         rf = rt3090_rf_read(sc, 6);
    2252           0 :         rf = (rf & ~0x03) | rt3090_freqs[i].r;
    2253           0 :         rt3090_rf_write(sc, 6, rf);
    2254             : 
    2255             :         /* set Tx0 power */
    2256           0 :         rf = rt3090_rf_read(sc, 12);
    2257           0 :         rf = (rf & ~0x1f) | txpow1;
    2258           0 :         rt3090_rf_write(sc, 12, rf);
    2259             : 
    2260             :         /* set Tx1 power */
    2261           0 :         rf = rt3090_rf_read(sc, 13);
    2262           0 :         rf = (rf & ~0x1f) | txpow2;
    2263           0 :         rt3090_rf_write(sc, 13, rf);
    2264             : 
    2265           0 :         rf = rt3090_rf_read(sc, 1);
    2266           0 :         rf &= ~0xfc;
    2267           0 :         if (sc->ntxchains == 1)
    2268           0 :                 rf |= RT3070_TX1_PD | RT3070_TX2_PD;
    2269           0 :         else if (sc->ntxchains == 2)
    2270           0 :                 rf |= RT3070_TX2_PD;
    2271           0 :         if (sc->nrxchains == 1)
    2272           0 :                 rf |= RT3070_RX1_PD | RT3070_RX2_PD;
    2273           0 :         else if (sc->nrxchains == 2)
    2274           0 :                 rf |= RT3070_RX2_PD;
    2275           0 :         rt3090_rf_write(sc, 1, rf);
    2276             : 
    2277             :         /* set RF offset */
    2278           0 :         rf = rt3090_rf_read(sc, 23);
    2279           0 :         rf = (rf & ~0x7f) | sc->freq;
    2280           0 :         rt3090_rf_write(sc, 23, rf);
    2281             : 
    2282             :         /* program RF filter */
    2283           0 :         rf = rt3090_rf_read(sc, 24);    /* Tx */
    2284           0 :         rf = (rf & ~0x3f) | sc->rf24_20mhz;
    2285           0 :         rt3090_rf_write(sc, 24, rf);
    2286           0 :         rf = rt3090_rf_read(sc, 31);    /* Rx */
    2287           0 :         rf = (rf & ~0x3f) | sc->rf24_20mhz;
    2288           0 :         rt3090_rf_write(sc, 31, rf);
    2289             : 
    2290             :         /* enable RF tuning */
    2291           0 :         rf = rt3090_rf_read(sc, 7);
    2292           0 :         rt3090_rf_write(sc, 7, rf | RT3070_TUNE);
    2293           0 : }
    2294             : 
    2295             : void
    2296           0 : rt5390_set_chan(struct rt2860_softc *sc, u_int chan)
    2297             : {
    2298             :         uint8_t h20mhz, rf, tmp;
    2299             :         int8_t txpow1, txpow2;
    2300             :         int i;
    2301             : 
    2302             :         /* RT5390 is 2GHz only */
    2303           0 :         KASSERT(chan >= 1 && chan <= 14);
    2304             : 
    2305             :         /* find the settings for this channel (we know it exists) */
    2306           0 :         for (i = 0; rt2860_rf2850[i].chan != chan; i++);
    2307             : 
    2308             :         /* use Tx power values from EEPROM */
    2309           0 :         txpow1 = sc->txpow1[i];
    2310           0 :         txpow2 = sc->txpow2[i];
    2311             : 
    2312           0 :         rt3090_rf_write(sc, 8, rt3090_freqs[i].n);
    2313           0 :         rt3090_rf_write(sc, 9, rt3090_freqs[i].k & 0x0f);
    2314           0 :         rf = rt3090_rf_read(sc, 11);
    2315           0 :         rf = (rf & ~0x03) | (rt3090_freqs[i].r & 0x03);
    2316           0 :         rt3090_rf_write(sc, 11, rf);
    2317             : 
    2318           0 :         rf = rt3090_rf_read(sc, 49);
    2319           0 :         rf = (rf & ~0x3f) | (txpow1 & 0x3f);
    2320             :         /* the valid range of the RF R49 is 0x00~0x27 */
    2321           0 :         if ((rf & 0x3f) > 0x27)
    2322           0 :                 rf = (rf & ~0x3f) | 0x27;
    2323           0 :         rt3090_rf_write(sc, 49, rf);
    2324           0 :         if (sc->mac_ver == 0x5392) {
    2325           0 :                 rf = rt3090_rf_read(sc, 50);
    2326           0 :                 rf = (rf & ~0x3f) | (txpow2 & 0x3f);
    2327             :                 /* the valid range of the RF R50 is 0x00~0x27 */
    2328           0 :                 if ((rf & 0x3f) > 0x27)
    2329           0 :                         rf = (rf & ~0x3f) | 0x27;
    2330           0 :                 rt3090_rf_write(sc, 50, rf);
    2331           0 :         }
    2332             : 
    2333           0 :         rf = rt3090_rf_read(sc, 1);
    2334           0 :         rf |= RT3070_RF_BLOCK | RT3070_PLL_PD | RT3070_RX0_PD | RT3070_TX0_PD;
    2335           0 :         if (sc->mac_ver == 0x5392)
    2336           0 :                 rf |= RT3070_RX1_PD | RT3070_TX1_PD;
    2337           0 :         rt3090_rf_write(sc, 1, rf);
    2338             : 
    2339           0 :         rf = rt3090_rf_read(sc, 2);
    2340           0 :         rt3090_rf_write(sc, 2, rf | RT3593_RESCAL);
    2341           0 :         DELAY(1000);
    2342           0 :         rt3090_rf_write(sc, 2, rf & ~RT3593_RESCAL);
    2343             : 
    2344           0 :         rf = rt3090_rf_read(sc, 17);
    2345             :         tmp = rf;
    2346           0 :         rf = (rf & ~0x7f) | (sc->freq & 0x7f);
    2347           0 :         rf = MIN(rf, 0x5f);
    2348           0 :         if (tmp != rf)
    2349           0 :                 rt2860_mcu_cmd(sc, 0x74, (tmp << 8 ) | rf, 0);
    2350             : 
    2351           0 :         if (sc->mac_ver == 0x5390) {
    2352           0 :                 if (chan <= 4)
    2353           0 :                         rf = 0x73;
    2354           0 :                 else if (chan >= 5 && chan <= 6)
    2355           0 :                         rf = 0x63;
    2356           0 :                 else if (chan >= 7 && chan <= 10)
    2357           0 :                         rf = 0x53;
    2358             :                 else
    2359             :                         rf = 43;
    2360           0 :                 rt3090_rf_write(sc, 55, rf);
    2361             : 
    2362           0 :                 if (chan == 1)
    2363           0 :                         rf = 0x0c;
    2364           0 :                 else if (chan == 2)
    2365           0 :                         rf = 0x0b;
    2366           0 :                 else if (chan == 3)
    2367           0 :                         rf = 0x0a;
    2368           0 :                 else if (chan >= 4 && chan <= 6)
    2369           0 :                         rf = 0x09;
    2370           0 :                 else if (chan >= 7 && chan <= 12)
    2371           0 :                         rf = 0x08;
    2372           0 :                 else if (chan == 13)
    2373           0 :                         rf = 0x07;
    2374             :                 else
    2375             :                         rf = 0x06;
    2376           0 :                 rt3090_rf_write(sc, 59, rf);
    2377           0 :         }
    2378             : 
    2379             :         /* Tx/Rx h20M */
    2380           0 :         h20mhz = (sc->rf24_20mhz & 0x20) >> 5;
    2381           0 :         rf = rt3090_rf_read(sc, 30);
    2382           0 :         rf = (rf & ~0x06) | (h20mhz << 1) | (h20mhz << 2);
    2383           0 :         rt3090_rf_write(sc, 30, rf);
    2384             : 
    2385             :         /* Rx BB filter VCM */
    2386           0 :         rf = rt3090_rf_read(sc, 30);
    2387           0 :         rf = (rf & ~0x18) | 0x10;
    2388           0 :         rt3090_rf_write(sc, 30, rf);
    2389             : 
    2390             :         /* Initiate VCO calibration. */
    2391           0 :         rf = rt3090_rf_read(sc, 3);
    2392           0 :         rf |= RT3593_VCOCAL;
    2393           0 :         rt3090_rf_write(sc, 3, rf);
    2394           0 : }
    2395             : 
    2396             : int
    2397           0 : rt3090_rf_init(struct rt2860_softc *sc)
    2398             : {
    2399             :         uint32_t tmp;
    2400             :         uint8_t rf, bbp;
    2401             :         int i;
    2402             : 
    2403           0 :         rf = rt3090_rf_read(sc, 30);
    2404             :         /* toggle RF R30 bit 7 */
    2405           0 :         rt3090_rf_write(sc, 30, rf | 0x80);
    2406           0 :         DELAY(1000);
    2407           0 :         rt3090_rf_write(sc, 30, rf & ~0x80);
    2408             : 
    2409           0 :         tmp = RAL_READ(sc, RT3070_LDO_CFG0);
    2410           0 :         tmp &= ~0x1f000000;
    2411           0 :         if (sc->patch_dac && sc->mac_rev < 0x0211)
    2412           0 :                 tmp |= 0x0d000000;      /* 1.35V */
    2413             :         else
    2414           0 :                 tmp |= 0x01000000;      /* 1.2V */
    2415           0 :         RAL_WRITE(sc, RT3070_LDO_CFG0, tmp);
    2416             : 
    2417             :         /* patch LNA_PE_G1 */
    2418           0 :         tmp = RAL_READ(sc, RT3070_GPIO_SWITCH);
    2419           0 :         RAL_WRITE(sc, RT3070_GPIO_SWITCH, tmp & ~0x20);
    2420             : 
    2421             :         /* initialize RF registers to default value */
    2422           0 :         if (sc->mac_ver == 0x3572) {
    2423           0 :                 for (i = 0; i < nitems(rt3572_def_rf); i++) {
    2424           0 :                         rt3090_rf_write(sc, rt3572_def_rf[i].reg,
    2425           0 :                             rt3572_def_rf[i].val);
    2426             :                 }
    2427             :         } else {
    2428           0 :                 for (i = 0; i < nitems(rt3090_def_rf); i++) {
    2429           0 :                         rt3090_rf_write(sc, rt3090_def_rf[i].reg,
    2430           0 :                             rt3090_def_rf[i].val);
    2431             :                 }
    2432             :         }
    2433             : 
    2434             :         /* select 20MHz bandwidth */
    2435           0 :         rt3090_rf_write(sc, 31, 0x14);
    2436             : 
    2437           0 :         rf = rt3090_rf_read(sc, 6);
    2438           0 :         rt3090_rf_write(sc, 6, rf | 0x40);
    2439             : 
    2440           0 :         if (sc->mac_ver != 0x3593) {
    2441             :                 /* calibrate filter for 20MHz bandwidth */
    2442           0 :                 sc->rf24_20mhz = 0x1f;       /* default value */
    2443           0 :                 rt3090_filter_calib(sc, 0x07, 0x16, &sc->rf24_20mhz);
    2444             : 
    2445             :                 /* select 40MHz bandwidth */
    2446           0 :                 bbp = rt2860_mcu_bbp_read(sc, 4);
    2447           0 :                 rt2860_mcu_bbp_write(sc, 4, (bbp & ~0x08) | 0x10);
    2448           0 :                 rf = rt3090_rf_read(sc, 31);
    2449           0 :                 rt3090_rf_write(sc, 31, rf | 0x20);
    2450             : 
    2451             :                 /* calibrate filter for 40MHz bandwidth */
    2452           0 :                 sc->rf24_40mhz = 0x2f;       /* default value */
    2453           0 :                 rt3090_filter_calib(sc, 0x27, 0x19, &sc->rf24_40mhz);
    2454             : 
    2455             :                 /* go back to 20MHz bandwidth */
    2456           0 :                 bbp = rt2860_mcu_bbp_read(sc, 4);
    2457           0 :                 rt2860_mcu_bbp_write(sc, 4, bbp & ~0x18);
    2458           0 :         }
    2459           0 :         if (sc->mac_rev < 0x0211)
    2460           0 :                 rt3090_rf_write(sc, 27, 0x03);
    2461             : 
    2462           0 :         tmp = RAL_READ(sc, RT3070_OPT_14);
    2463           0 :         RAL_WRITE(sc, RT3070_OPT_14, tmp | 1);
    2464             : 
    2465           0 :         if (sc->rf_rev == RT3070_RF_3020)
    2466           0 :                 rt3090_set_rx_antenna(sc, 0);
    2467             : 
    2468           0 :         bbp = rt2860_mcu_bbp_read(sc, 138);
    2469           0 :         if (sc->mac_ver == 0x3593) {
    2470           0 :                 if (sc->ntxchains == 1)
    2471           0 :                         bbp |= 0x60;    /* turn off DAC1 and DAC2 */
    2472           0 :                 else if (sc->ntxchains == 2)
    2473           0 :                         bbp |= 0x40;    /* turn off DAC2 */
    2474           0 :                 if (sc->nrxchains == 1)
    2475           0 :                         bbp &= ~0x06;       /* turn off ADC1 and ADC2 */
    2476           0 :                 else if (sc->nrxchains == 2)
    2477           0 :                         bbp &= ~0x04;       /* turn off ADC2 */
    2478             :         } else {
    2479           0 :                 if (sc->ntxchains == 1)
    2480           0 :                         bbp |= 0x20;    /* turn off DAC1 */
    2481           0 :                 if (sc->nrxchains == 1)
    2482           0 :                         bbp &= ~0x02;       /* turn off ADC1 */
    2483             :         }
    2484           0 :         rt2860_mcu_bbp_write(sc, 138, bbp);
    2485             : 
    2486           0 :         rf = rt3090_rf_read(sc, 1);
    2487           0 :         rf &= ~(RT3070_RX0_PD | RT3070_TX0_PD);
    2488           0 :         rf |= RT3070_RF_BLOCK | RT3070_RX1_PD | RT3070_TX1_PD;
    2489           0 :         rt3090_rf_write(sc, 1, rf);
    2490             : 
    2491           0 :         rf = rt3090_rf_read(sc, 15);
    2492           0 :         rt3090_rf_write(sc, 15, rf & ~RT3070_TX_LO2);
    2493             : 
    2494           0 :         rf = rt3090_rf_read(sc, 17);
    2495           0 :         rf &= ~RT3070_TX_LO1;
    2496           0 :         if (sc->mac_rev >= 0x0211 && !sc->ext_2ghz_lna)
    2497           0 :                 rf |= 0x20;     /* fix for long range Rx issue */
    2498           0 :         if (sc->txmixgain_2ghz >= 2)
    2499           0 :                 rf = (rf & ~0x7) | sc->txmixgain_2ghz;
    2500           0 :         rt3090_rf_write(sc, 17, rf);
    2501             : 
    2502           0 :         rf = rt3090_rf_read(sc, 20);
    2503           0 :         rt3090_rf_write(sc, 20, rf & ~RT3070_RX_LO1);
    2504             : 
    2505           0 :         rf = rt3090_rf_read(sc, 21);
    2506           0 :         rt3090_rf_write(sc, 21, rf & ~RT3070_RX_LO2);
    2507             : 
    2508           0 :         return 0;
    2509             : }
    2510             : 
    2511             : void
    2512           0 : rt5390_rf_init(struct rt2860_softc *sc)
    2513             : {
    2514             :         uint8_t rf, bbp;
    2515             :         int i;
    2516             : 
    2517           0 :         rf = rt3090_rf_read(sc, 2);
    2518             :         /* Toggle RF R2 bit 7. */
    2519           0 :         rt3090_rf_write(sc, 2, rf | RT3593_RESCAL);
    2520           0 :         DELAY(1000);
    2521           0 :         rt3090_rf_write(sc, 2, rf & ~RT3593_RESCAL);
    2522             : 
    2523             :         /* Initialize RF registers to default value. */
    2524           0 :         if (sc->mac_ver == 0x5392) {
    2525           0 :                 for (i = 0; i < nitems(rt5392_def_rf); i++) {
    2526           0 :                         rt3090_rf_write(sc, rt5392_def_rf[i].reg,
    2527           0 :                             rt5392_def_rf[i].val);
    2528             :          }
    2529             :         } else {
    2530           0 :                 for (i = 0; i < nitems(rt5390_def_rf); i++) {
    2531           0 :                         rt3090_rf_write(sc, rt5390_def_rf[i].reg,
    2532           0 :                             rt5390_def_rf[i].val);
    2533             :                 }
    2534             :         }
    2535             : 
    2536           0 :         sc->rf24_20mhz = 0x1f;
    2537           0 :         sc->rf24_40mhz = 0x2f;
    2538             : 
    2539           0 :         if (sc->mac_rev < 0x0211)
    2540           0 :                 rt3090_rf_write(sc, 27, 0x03);
    2541             : 
    2542             :         /* Set led open drain enable. */
    2543           0 :         RAL_WRITE(sc, RT3070_OPT_14, RAL_READ(sc, RT3070_OPT_14) | 1);
    2544             : 
    2545           0 :         RAL_WRITE(sc, RT2860_TX_SW_CFG1, 0);
    2546           0 :         RAL_WRITE(sc, RT2860_TX_SW_CFG2, 0);
    2547             : 
    2548           0 :         if (sc->mac_ver == 0x5390)
    2549           0 :                 rt3090_set_rx_antenna(sc, 0);
    2550             : 
    2551             :         /* Patch RSSI inaccurate issue. */
    2552           0 :         rt2860_mcu_bbp_write(sc, 79, 0x13);
    2553           0 :         rt2860_mcu_bbp_write(sc, 80, 0x05);
    2554           0 :         rt2860_mcu_bbp_write(sc, 81, 0x33);
    2555             : 
    2556             :         /* Enable DC filter. */
    2557           0 :         if (sc->mac_rev >= 0x0211)
    2558           0 :                 rt2860_mcu_bbp_write(sc, 103, 0xc0);
    2559             : 
    2560           0 :         bbp = rt2860_mcu_bbp_read(sc, 138);
    2561           0 :         if (sc->ntxchains == 1)
    2562           0 :                 bbp |= 0x20;    /* Turn off DAC1. */
    2563           0 :         if (sc->nrxchains == 1)
    2564           0 :                 bbp &= ~0x02;   /* Turn off ADC1. */
    2565           0 :         rt2860_mcu_bbp_write(sc, 138, bbp);
    2566             : 
    2567             :         /* Enable RX LO1 and LO2. */
    2568           0 :         rt3090_rf_write(sc, 38, rt3090_rf_read(sc, 38) & ~RT5390_RX_LO1);
    2569           0 :         rt3090_rf_write(sc, 39, rt3090_rf_read(sc, 39) & ~RT5390_RX_LO2);
    2570             : 
    2571             :         /* Avoid data lost and CRC error. */
    2572           0 :         rt2860_mcu_bbp_write(sc, 4,
    2573           0 :             rt2860_mcu_bbp_read(sc, 4) | RT5390_MAC_IF_CTRL);
    2574             : 
    2575           0 :         rf = rt3090_rf_read(sc, 30);
    2576           0 :         rf = (rf & ~0x18) | 0x10;
    2577           0 :         rt3090_rf_write(sc, 30, rf);
    2578             : 
    2579             :         /* Disable hardware antenna diversity. */
    2580           0 :         if (sc->mac_ver == 0x5390)
    2581           0 :                 rt2860_mcu_bbp_write(sc, 154, 0);
    2582           0 : }
    2583             : 
    2584             : void
    2585           0 : rt3090_rf_wakeup(struct rt2860_softc *sc)
    2586             : {
    2587             :         uint32_t tmp;
    2588             :         uint8_t rf;
    2589             : 
    2590           0 :         if (sc->mac_ver == 0x3593) {
    2591             :                 /* enable VCO */
    2592             :                 rf = rt3090_rf_read(sc, 1);
    2593             :                 rt3090_rf_write(sc, 1, rf | RT3593_VCO);
    2594             : 
    2595             :                 /* initiate VCO calibration */
    2596           0 :                 rf = rt3090_rf_read(sc, 3);
    2597           0 :                 rt3090_rf_write(sc, 3, rf | RT3593_VCOCAL);
    2598             : 
    2599             :                 /* enable VCO bias current control */
    2600           0 :                 rf = rt3090_rf_read(sc, 6);
    2601           0 :                 rt3090_rf_write(sc, 6, rf | RT3593_VCO_IC);
    2602             : 
    2603             :                 /* initiate res calibration */
    2604           0 :                 rf = rt3090_rf_read(sc, 2);
    2605           0 :                 rt3090_rf_write(sc, 2, rf | RT3593_RESCAL);
    2606             : 
    2607             :                 /* set reference current control to 0.33 mA */
    2608           0 :                 rf = rt3090_rf_read(sc, 22);
    2609           0 :                 rf &= ~RT3593_CP_IC_MASK;
    2610           0 :                 rf |= 1 << RT3593_CP_IC_SHIFT;
    2611           0 :                 rt3090_rf_write(sc, 22, rf);
    2612             : 
    2613             :                 /* enable RX CTB */
    2614           0 :                 rf = rt3090_rf_read(sc, 46);
    2615           0 :                 rt3090_rf_write(sc, 46, rf | RT3593_RX_CTB);
    2616             : 
    2617           0 :                 rf = rt3090_rf_read(sc, 20);
    2618           0 :                 rf &= ~(RT3593_LDO_RF_VC_MASK | RT3593_LDO_PLL_VC_MASK);
    2619           0 :                 rt3090_rf_write(sc, 20, rf);
    2620           0 :         } else {
    2621             :                 /* enable RF block */
    2622             :                 rf = rt3090_rf_read(sc, 1);
    2623             :                 rt3090_rf_write(sc, 1, rf | RT3070_RF_BLOCK);
    2624             : 
    2625             :                 /* enable VCO bias current control */
    2626           0 :                 rf = rt3090_rf_read(sc, 7);
    2627           0 :                 rt3090_rf_write(sc, 7, rf | 0x30);
    2628             : 
    2629           0 :                 rf = rt3090_rf_read(sc, 9);
    2630           0 :                 rt3090_rf_write(sc, 9, rf | 0x0e);
    2631             : 
    2632             :                 /* enable RX CTB */
    2633           0 :                 rf = rt3090_rf_read(sc, 21);
    2634           0 :                 rt3090_rf_write(sc, 21, rf | RT3070_RX_CTB);
    2635             : 
    2636             :                 /* fix Tx to Rx IQ glitch by raising RF voltage */
    2637           0 :                 rf = rt3090_rf_read(sc, 27);
    2638           0 :                 rf &= ~0x77;
    2639           0 :                 if (sc->mac_rev < 0x0211)
    2640           0 :                         rf |= 0x03;
    2641           0 :                 rt3090_rf_write(sc, 27, rf);
    2642             :         }
    2643           0 :         if (sc->patch_dac && sc->mac_rev < 0x0211) {
    2644           0 :                 tmp = RAL_READ(sc, RT3070_LDO_CFG0);
    2645           0 :                 tmp = (tmp & ~0x1f000000) | 0x0d000000;
    2646           0 :                 RAL_WRITE(sc, RT3070_LDO_CFG0, tmp);
    2647           0 :         }
    2648           0 : }
    2649             : 
    2650             : void
    2651           0 : rt5390_rf_wakeup(struct rt2860_softc *sc)
    2652             : {
    2653             :         uint32_t tmp;
    2654             :         uint8_t rf;
    2655             :         
    2656           0 :         rf = rt3090_rf_read(sc, 1);
    2657           0 :         rf |= RT3070_RF_BLOCK | RT3070_PLL_PD | RT3070_RX0_PD |
    2658             :             RT3070_TX0_PD;
    2659           0 :         if (sc->mac_ver == 0x5392)
    2660           0 :                 rf |= RT3070_RX1_PD | RT3070_TX1_PD;
    2661           0 :         rt3090_rf_write(sc, 1, rf);
    2662             : 
    2663           0 :         rf = rt3090_rf_read(sc, 6);
    2664           0 :         rf |= RT3593_VCO_IC | RT3593_VCOCAL;
    2665           0 :         if (sc->mac_ver == 0x5390)
    2666           0 :                 rf &= ~RT3593_VCO_IC;
    2667           0 :         rt3090_rf_write(sc, 6, rf);
    2668             : 
    2669           0 :         rt3090_rf_write(sc, 2, rt3090_rf_read(sc, 2) | RT3593_RESCAL);
    2670             : 
    2671           0 :         rf = rt3090_rf_read(sc, 22);
    2672           0 :         rf = (rf & ~0xe0) | 0x20;
    2673           0 :         rt3090_rf_write(sc, 22, rf);
    2674             : 
    2675           0 :         rt3090_rf_write(sc, 42, rt3090_rf_read(sc, 42) | RT5390_RX_CTB);
    2676           0 :         rt3090_rf_write(sc, 20, rt3090_rf_read(sc, 20) & ~0x77);
    2677           0 :         rt3090_rf_write(sc, 3, rt3090_rf_read(sc, 3) | RT3593_VCOCAL);
    2678             : 
    2679           0 :         if (sc->patch_dac && sc->mac_rev < 0x0211) {
    2680           0 :                 tmp = RAL_READ(sc, RT3070_LDO_CFG0);
    2681           0 :                 tmp = (tmp & ~0x1f000000) | 0x0d000000;
    2682           0 :                 RAL_WRITE(sc, RT3070_LDO_CFG0, tmp);
    2683           0 :         }
    2684           0 : }
    2685             : 
    2686             : int
    2687           0 : rt3090_filter_calib(struct rt2860_softc *sc, uint8_t init, uint8_t target,
    2688             :     uint8_t *val)
    2689             : {
    2690             :         uint8_t rf22, rf24;
    2691             :         uint8_t bbp55_pb, bbp55_sb, delta;
    2692             :         int ntries;
    2693             : 
    2694             :         /* program filter */
    2695           0 :         rf24 = rt3090_rf_read(sc, 24);
    2696           0 :         rf24 = (rf24 & 0xc0) | init;        /* initial filter value */
    2697           0 :         rt3090_rf_write(sc, 24, rf24);
    2698             : 
    2699             :         /* enable baseband loopback mode */
    2700           0 :         rf22 = rt3090_rf_read(sc, 22);
    2701           0 :         rt3090_rf_write(sc, 22, rf22 | RT3070_BB_LOOPBACK);
    2702             : 
    2703             :         /* set power and frequency of passband test tone */
    2704           0 :         rt2860_mcu_bbp_write(sc, 24, 0x00);
    2705           0 :         for (ntries = 0; ntries < 100; ntries++) {
    2706             :                 /* transmit test tone */
    2707           0 :                 rt2860_mcu_bbp_write(sc, 25, 0x90);
    2708           0 :                 DELAY(1000);
    2709             :                 /* read received power */
    2710           0 :                 bbp55_pb = rt2860_mcu_bbp_read(sc, 55);
    2711           0 :                 if (bbp55_pb != 0)
    2712             :                         break;
    2713             :         }
    2714           0 :         if (ntries == 100)
    2715           0 :                 return ETIMEDOUT;
    2716             : 
    2717             :         /* set power and frequency of stopband test tone */
    2718           0 :         rt2860_mcu_bbp_write(sc, 24, 0x06);
    2719           0 :         for (ntries = 0; ntries < 100; ntries++) {
    2720             :                 /* transmit test tone */
    2721           0 :                 rt2860_mcu_bbp_write(sc, 25, 0x90);
    2722           0 :                 DELAY(1000);
    2723             :                 /* read received power */
    2724           0 :                 bbp55_sb = rt2860_mcu_bbp_read(sc, 55);
    2725             : 
    2726           0 :                 delta = bbp55_pb - bbp55_sb;
    2727           0 :                 if (delta > target)
    2728             :                         break;
    2729             : 
    2730             :                 /* reprogram filter */
    2731           0 :                 rf24++;
    2732           0 :                 rt3090_rf_write(sc, 24, rf24);
    2733             :         }
    2734           0 :         if (ntries < 100) {
    2735           0 :                 if (rf24 != init)
    2736           0 :                         rf24--; /* backtrack */
    2737           0 :                 *val = rf24;
    2738           0 :                 rt3090_rf_write(sc, 24, rf24);
    2739           0 :         }
    2740             : 
    2741             :         /* restore initial state */
    2742           0 :         rt2860_mcu_bbp_write(sc, 24, 0x00);
    2743             : 
    2744             :         /* disable baseband loopback mode */
    2745           0 :         rf22 = rt3090_rf_read(sc, 22);
    2746           0 :         rt3090_rf_write(sc, 22, rf22 & ~RT3070_BB_LOOPBACK);
    2747             : 
    2748           0 :         return 0;
    2749           0 : }
    2750             : 
    2751             : void
    2752           0 : rt3090_rf_setup(struct rt2860_softc *sc)
    2753             : {
    2754             :         uint8_t bbp;
    2755             :         int i;
    2756             : 
    2757           0 :         if (sc->mac_rev >= 0x0211) {
    2758             :                 /* enable DC filter */
    2759           0 :                 rt2860_mcu_bbp_write(sc, 103, 0xc0);
    2760             : 
    2761             :                 /* improve power consumption */
    2762           0 :                 bbp = rt2860_mcu_bbp_read(sc, 31);
    2763           0 :                 rt2860_mcu_bbp_write(sc, 31, bbp & ~0x03);
    2764           0 :         }
    2765             : 
    2766           0 :         RAL_WRITE(sc, RT2860_TX_SW_CFG1, 0);
    2767           0 :         if (sc->mac_rev < 0x0211) {
    2768           0 :                 RAL_WRITE(sc, RT2860_TX_SW_CFG2,
    2769             :                     sc->patch_dac ? 0x2c : 0x0f);
    2770           0 :         } else
    2771           0 :                 RAL_WRITE(sc, RT2860_TX_SW_CFG2, 0);
    2772             : 
    2773             :         /* initialize RF registers from ROM */
    2774           0 :         if (sc->mac_ver < 0x5390) {
    2775           0 :                 for (i = 0; i < 10; i++) {
    2776           0 :                         if (sc->rf[i].reg == 0 || sc->rf[i].reg == 0xff)
    2777             :                                 continue;
    2778           0 :                         rt3090_rf_write(sc, sc->rf[i].reg, sc->rf[i].val);
    2779           0 :                 }
    2780             :         }
    2781           0 : }
    2782             : 
    2783             : void
    2784           0 : rt2860_set_leds(struct rt2860_softc *sc, uint16_t which)
    2785             : {
    2786           0 :         rt2860_mcu_cmd(sc, RT2860_MCU_CMD_LEDS,
    2787           0 :             which | (sc->leds & 0x7f), 0);
    2788           0 : }
    2789             : 
    2790             : /*
    2791             :  * Hardware has a general-purpose programmable timer interrupt that can
    2792             :  * periodically raise MAC_INT_4.
    2793             :  */
    2794             : void
    2795           0 : rt2860_set_gp_timer(struct rt2860_softc *sc, int ms)
    2796             : {
    2797             :         uint32_t tmp;
    2798             : 
    2799             :         /* disable GP timer before reprogramming it */
    2800           0 :         tmp = RAL_READ(sc, RT2860_INT_TIMER_EN);
    2801           0 :         RAL_WRITE(sc, RT2860_INT_TIMER_EN, tmp & ~RT2860_GP_TIMER_EN);
    2802             : 
    2803           0 :         if (ms == 0)
    2804           0 :                 return;
    2805             : 
    2806           0 :         tmp = RAL_READ(sc, RT2860_INT_TIMER_CFG);
    2807           0 :         ms *= 16;       /* Unit: 64us */
    2808           0 :         tmp = (tmp & 0xffff) | ms << RT2860_GP_TIMER_SHIFT;
    2809           0 :         RAL_WRITE(sc, RT2860_INT_TIMER_CFG, tmp);
    2810             : 
    2811             :         /* enable GP timer */
    2812           0 :         tmp = RAL_READ(sc, RT2860_INT_TIMER_EN);
    2813           0 :         RAL_WRITE(sc, RT2860_INT_TIMER_EN, tmp | RT2860_GP_TIMER_EN);
    2814           0 : }
    2815             : 
    2816             : void
    2817           0 : rt2860_set_bssid(struct rt2860_softc *sc, const uint8_t *bssid)
    2818             : {
    2819           0 :         RAL_WRITE(sc, RT2860_MAC_BSSID_DW0,
    2820             :             bssid[0] | bssid[1] << 8 | bssid[2] << 16 | bssid[3] << 24);
    2821           0 :         RAL_WRITE(sc, RT2860_MAC_BSSID_DW1,
    2822             :             bssid[4] | bssid[5] << 8);
    2823           0 : }
    2824             : 
    2825             : void
    2826           0 : rt2860_set_macaddr(struct rt2860_softc *sc, const uint8_t *addr)
    2827             : {
    2828           0 :         RAL_WRITE(sc, RT2860_MAC_ADDR_DW0,
    2829             :             addr[0] | addr[1] << 8 | addr[2] << 16 | addr[3] << 24);
    2830           0 :         RAL_WRITE(sc, RT2860_MAC_ADDR_DW1,
    2831             :             addr[4] | addr[5] << 8 | 0xff << 16);
    2832           0 : }
    2833             : 
    2834             : void
    2835           0 : rt2860_updateslot(struct ieee80211com *ic)
    2836             : {
    2837           0 :         struct rt2860_softc *sc = ic->ic_softc;
    2838             :         uint32_t tmp;
    2839             : 
    2840           0 :         tmp = RAL_READ(sc, RT2860_BKOFF_SLOT_CFG);
    2841           0 :         tmp &= ~0xff;
    2842           0 :         tmp |= (ic->ic_flags & IEEE80211_F_SHSLOT) ?
    2843             :             IEEE80211_DUR_DS_SHSLOT : IEEE80211_DUR_DS_SLOT;
    2844           0 :         RAL_WRITE(sc, RT2860_BKOFF_SLOT_CFG, tmp);
    2845           0 : }
    2846             : 
    2847             : void
    2848           0 : rt2860_updateprot(struct ieee80211com *ic)
    2849             : {
    2850           0 :         struct rt2860_softc *sc = ic->ic_softc;
    2851             :         uint32_t tmp;
    2852             : 
    2853             :         tmp = RT2860_RTSTH_EN | RT2860_PROT_NAV_SHORT | RT2860_TXOP_ALLOW_ALL;
    2854             :         /* setup protection frame rate (MCS code) */
    2855           0 :         tmp |= (ic->ic_curmode == IEEE80211_MODE_11A) ?
    2856             :             rt2860_rates[RT2860_RIDX_OFDM6].mcs :
    2857             :             rt2860_rates[RT2860_RIDX_CCK11].mcs;
    2858             : 
    2859             :         /* CCK frames don't require protection */
    2860           0 :         RAL_WRITE(sc, RT2860_CCK_PROT_CFG, tmp);
    2861             : 
    2862           0 :         if (ic->ic_flags & IEEE80211_F_USEPROT) {
    2863           0 :                 if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
    2864           0 :                         tmp |= RT2860_PROT_CTRL_RTS_CTS;
    2865           0 :                 else if (ic->ic_protmode == IEEE80211_PROT_CTSONLY)
    2866           0 :                         tmp |= RT2860_PROT_CTRL_CTS;
    2867             :         }
    2868           0 :         RAL_WRITE(sc, RT2860_OFDM_PROT_CFG, tmp);
    2869           0 : }
    2870             : 
    2871             : void
    2872           0 : rt2860_updateedca(struct ieee80211com *ic)
    2873             : {
    2874           0 :         struct rt2860_softc *sc = ic->ic_softc;
    2875             :         int aci;
    2876             : 
    2877             :         /* update MAC TX configuration registers */
    2878           0 :         for (aci = 0; aci < EDCA_NUM_AC; aci++) {
    2879           0 :                 RAL_WRITE(sc, RT2860_EDCA_AC_CFG(aci),
    2880             :                     ic->ic_edca_ac[aci].ac_ecwmax << 16 |
    2881             :                     ic->ic_edca_ac[aci].ac_ecwmin << 12 |
    2882             :                     ic->ic_edca_ac[aci].ac_aifsn  <<  8 |
    2883             :                     ic->ic_edca_ac[aci].ac_txoplimit);
    2884             :         }
    2885             : 
    2886             :         /* update SCH/DMA registers too */
    2887           0 :         RAL_WRITE(sc, RT2860_WMM_AIFSN_CFG,
    2888             :             ic->ic_edca_ac[EDCA_AC_VO].ac_aifsn  << 12 |
    2889             :             ic->ic_edca_ac[EDCA_AC_VI].ac_aifsn  <<  8 |
    2890             :             ic->ic_edca_ac[EDCA_AC_BK].ac_aifsn  <<  4 |
    2891             :             ic->ic_edca_ac[EDCA_AC_BE].ac_aifsn);
    2892           0 :         RAL_WRITE(sc, RT2860_WMM_CWMIN_CFG,
    2893             :             ic->ic_edca_ac[EDCA_AC_VO].ac_ecwmin << 12 |
    2894             :             ic->ic_edca_ac[EDCA_AC_VI].ac_ecwmin <<  8 |
    2895             :             ic->ic_edca_ac[EDCA_AC_BK].ac_ecwmin <<  4 |
    2896             :             ic->ic_edca_ac[EDCA_AC_BE].ac_ecwmin);
    2897           0 :         RAL_WRITE(sc, RT2860_WMM_CWMAX_CFG,
    2898             :             ic->ic_edca_ac[EDCA_AC_VO].ac_ecwmax << 12 |
    2899             :             ic->ic_edca_ac[EDCA_AC_VI].ac_ecwmax <<  8 |
    2900             :             ic->ic_edca_ac[EDCA_AC_BK].ac_ecwmax <<  4 |
    2901             :             ic->ic_edca_ac[EDCA_AC_BE].ac_ecwmax);
    2902           0 :         RAL_WRITE(sc, RT2860_WMM_TXOP0_CFG,
    2903             :             ic->ic_edca_ac[EDCA_AC_BK].ac_txoplimit << 16 |
    2904             :             ic->ic_edca_ac[EDCA_AC_BE].ac_txoplimit);
    2905           0 :         RAL_WRITE(sc, RT2860_WMM_TXOP1_CFG,
    2906             :             ic->ic_edca_ac[EDCA_AC_VO].ac_txoplimit << 16 |
    2907             :             ic->ic_edca_ac[EDCA_AC_VI].ac_txoplimit);
    2908           0 : }
    2909             : 
    2910             : int
    2911           0 : rt2860_set_key(struct ieee80211com *ic, struct ieee80211_node *ni,
    2912             :     struct ieee80211_key *k)
    2913             : {
    2914           0 :         struct rt2860_softc *sc = ic->ic_softc;
    2915             :         bus_size_t base;
    2916             :         uint32_t attr;
    2917           0 :         uint8_t mode, wcid, iv[8];
    2918             : 
    2919             :         /* defer setting of WEP keys until interface is brought up */
    2920           0 :         if ((ic->ic_if.if_flags & (IFF_UP | IFF_RUNNING)) !=
    2921             :             (IFF_UP | IFF_RUNNING))
    2922           0 :                 return 0;
    2923             : 
    2924             :         /* map net80211 cipher to RT2860 security mode */
    2925           0 :         switch (k->k_cipher) {
    2926             :         case IEEE80211_CIPHER_WEP40:
    2927             :                 mode = RT2860_MODE_WEP40;
    2928           0 :                 break;
    2929             :         case IEEE80211_CIPHER_WEP104:
    2930             :                 mode = RT2860_MODE_WEP104;
    2931           0 :                 break;
    2932             :         case IEEE80211_CIPHER_TKIP:
    2933             :                 mode = RT2860_MODE_TKIP;
    2934           0 :                 break;
    2935             :         case IEEE80211_CIPHER_CCMP:
    2936             :                 mode = RT2860_MODE_AES_CCMP;
    2937           0 :                 break;
    2938             :         default:
    2939           0 :                 return EINVAL;
    2940             :         }
    2941             : 
    2942           0 :         if (k->k_flags & IEEE80211_KEY_GROUP) {
    2943             :                 wcid = 0;       /* NB: update WCID0 for group keys */
    2944           0 :                 base = RT2860_SKEY(0, k->k_id);
    2945           0 :         } else {
    2946           0 :                 wcid = ((struct rt2860_node *)ni)->wcid;
    2947           0 :                 base = RT2860_PKEY(wcid);
    2948             :         }
    2949             : 
    2950           0 :         if (k->k_cipher == IEEE80211_CIPHER_TKIP) {
    2951           0 :                 RAL_WRITE_REGION_1(sc, base, k->k_key, 16);
    2952             : #ifndef IEEE80211_STA_ONLY
    2953           0 :                 if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
    2954           0 :                         RAL_WRITE_REGION_1(sc, base + 16, &k->k_key[16], 8);
    2955           0 :                         RAL_WRITE_REGION_1(sc, base + 24, &k->k_key[24], 8);
    2956           0 :                 } else
    2957             : #endif
    2958             :                 {
    2959           0 :                         RAL_WRITE_REGION_1(sc, base + 16, &k->k_key[24], 8);
    2960           0 :                         RAL_WRITE_REGION_1(sc, base + 24, &k->k_key[16], 8);
    2961             :                 }
    2962             :         } else
    2963           0 :                 RAL_WRITE_REGION_1(sc, base, k->k_key, k->k_len);
    2964             : 
    2965           0 :         if (!(k->k_flags & IEEE80211_KEY_GROUP) ||
    2966           0 :             (k->k_flags & IEEE80211_KEY_TX)) {
    2967             :                 /* set initial packet number in IV+EIV */
    2968           0 :                 if (k->k_cipher == IEEE80211_CIPHER_WEP40 ||
    2969           0 :                     k->k_cipher == IEEE80211_CIPHER_WEP104) {
    2970           0 :                         uint32_t val = arc4random();
    2971             :                         /* skip weak IVs from Fluhrer/Mantin/Shamir */
    2972           0 :                         if (val >= 0x03ff00 && (val & 0xf8ff00) == 0x00ff00)
    2973           0 :                                 val += 0x000100;
    2974           0 :                         iv[0] = val;
    2975           0 :                         iv[1] = val >> 8;
    2976           0 :                         iv[2] = val >> 16;
    2977           0 :                         iv[3] = k->k_id << 6;
    2978           0 :                         iv[4] = iv[5] = iv[6] = iv[7] = 0;
    2979           0 :                 } else {
    2980           0 :                         if (k->k_cipher == IEEE80211_CIPHER_TKIP) {
    2981           0 :                                 iv[0] = k->k_tsc >> 8;
    2982           0 :                                 iv[1] = (iv[0] | 0x20) & 0x7f;
    2983           0 :                                 iv[2] = k->k_tsc;
    2984           0 :                         } else /* CCMP */ {
    2985           0 :                                 iv[0] = k->k_tsc;
    2986           0 :                                 iv[1] = k->k_tsc >> 8;
    2987           0 :                                 iv[2] = 0;
    2988             :                         }
    2989           0 :                         iv[3] = k->k_id << 6 | IEEE80211_WEP_EXTIV;
    2990           0 :                         iv[4] = k->k_tsc >> 16;
    2991           0 :                         iv[5] = k->k_tsc >> 24;
    2992           0 :                         iv[6] = k->k_tsc >> 32;
    2993           0 :                         iv[7] = k->k_tsc >> 40;
    2994             :                 }
    2995           0 :                 RAL_WRITE_REGION_1(sc, RT2860_IVEIV(wcid), iv, 8);
    2996           0 :         }
    2997             : 
    2998           0 :         if (k->k_flags & IEEE80211_KEY_GROUP) {
    2999             :                 /* install group key */
    3000           0 :                 attr = RAL_READ(sc, RT2860_SKEY_MODE_0_7);
    3001           0 :                 attr &= ~(0xf << (k->k_id * 4));
    3002           0 :                 attr |= mode << (k->k_id * 4);
    3003           0 :                 RAL_WRITE(sc, RT2860_SKEY_MODE_0_7, attr);
    3004           0 :         } else {
    3005             :                 /* install pairwise key */
    3006           0 :                 attr = RAL_READ(sc, RT2860_WCID_ATTR(wcid));
    3007           0 :                 attr = (attr & ~0xf) | (mode << 1) | RT2860_RX_PKEY_EN;
    3008           0 :                 RAL_WRITE(sc, RT2860_WCID_ATTR(wcid), attr);
    3009             :         }
    3010           0 :         return 0;
    3011           0 : }
    3012             : 
    3013             : void
    3014           0 : rt2860_delete_key(struct ieee80211com *ic, struct ieee80211_node *ni,
    3015             :     struct ieee80211_key *k)
    3016             : {
    3017           0 :         struct rt2860_softc *sc = ic->ic_softc;
    3018             :         uint32_t attr;
    3019             :         uint8_t wcid;
    3020             : 
    3021           0 :         if (k->k_flags & IEEE80211_KEY_GROUP) {
    3022             :                 /* remove group key */
    3023           0 :                 attr = RAL_READ(sc, RT2860_SKEY_MODE_0_7);
    3024           0 :                 attr &= ~(0xf << (k->k_id * 4));
    3025           0 :                 RAL_WRITE(sc, RT2860_SKEY_MODE_0_7, attr);
    3026             : 
    3027           0 :         } else {
    3028             :                 /* remove pairwise key */
    3029           0 :                 wcid = ((struct rt2860_node *)ni)->wcid;
    3030           0 :                 attr = RAL_READ(sc, RT2860_WCID_ATTR(wcid));
    3031           0 :                 attr &= ~0xf;
    3032           0 :                 RAL_WRITE(sc, RT2860_WCID_ATTR(wcid), attr);
    3033             :         }
    3034           0 : }
    3035             : 
    3036             : #if NBPFILTER > 0
    3037             : int8_t
    3038           0 : rt2860_rssi2dbm(struct rt2860_softc *sc, uint8_t rssi, uint8_t rxchain)
    3039             : {
    3040           0 :         struct ieee80211com *ic = &sc->sc_ic;
    3041           0 :         struct ieee80211_channel *c = ic->ic_ibss_chan;
    3042             :         int delta;
    3043             : 
    3044           0 :         if (IEEE80211_IS_CHAN_5GHZ(c)) {
    3045           0 :                 u_int chan = ieee80211_chan2ieee(ic, c);
    3046           0 :                 delta = sc->rssi_5ghz[rxchain];
    3047             : 
    3048             :                 /* determine channel group */
    3049           0 :                 if (chan <= 64)
    3050           0 :                         delta -= sc->lna[1];
    3051           0 :                 else if (chan <= 128)
    3052           0 :                         delta -= sc->lna[2];
    3053             :                 else
    3054           0 :                         delta -= sc->lna[3];
    3055           0 :         } else
    3056           0 :                 delta = sc->rssi_2ghz[rxchain] - sc->lna[0];
    3057             : 
    3058           0 :         return -12 - delta - rssi;
    3059             : }
    3060             : #endif
    3061             : 
    3062             : /*
    3063             :  * Add `delta' (signed) to each 4-bit sub-word of a 32-bit word.
    3064             :  * Used to adjust per-rate Tx power registers.
    3065             :  */
    3066             : static __inline uint32_t
    3067           0 : b4inc(uint32_t b32, int8_t delta)
    3068             : {
    3069             :         int8_t i, b4;
    3070             : 
    3071           0 :         for (i = 0; i < 8; i++) {
    3072           0 :                 b4 = b32 & 0xf;
    3073           0 :                 b4 += delta;
    3074           0 :                 if (b4 < 0)
    3075           0 :                         b4 = 0;
    3076           0 :                 else if (b4 > 0xf)
    3077           0 :                         b4 = 0xf;
    3078           0 :                 b32 = b32 >> 4 | b4 << 28;
    3079             :         }
    3080           0 :         return b32;
    3081             : }
    3082             : 
    3083             : const char *
    3084           0 : rt2860_get_rf(uint16_t rev)
    3085             : {
    3086           0 :         switch (rev) {
    3087           0 :         case RT2860_RF_2820:    return "RT2820";
    3088           0 :         case RT2860_RF_2850:    return "RT2850";
    3089           0 :         case RT2860_RF_2720:    return "RT2720";
    3090           0 :         case RT2860_RF_2750:    return "RT2750";
    3091           0 :         case RT3070_RF_3020:    return "RT3020";
    3092           0 :         case RT3070_RF_2020:    return "RT2020";
    3093           0 :         case RT3070_RF_3021:    return "RT3021";
    3094           0 :         case RT3070_RF_3022:    return "RT3022";
    3095           0 :         case RT3070_RF_3052:    return "RT3052";
    3096           0 :         case RT3070_RF_3320:    return "RT3320";
    3097           0 :         case RT3070_RF_3053:    return "RT3053";
    3098           0 :         case RT5390_RF_5360:    return "RT5360";
    3099           0 :         case RT5390_RF_5390:    return "RT5390";
    3100           0 :         case RT5390_RF_5392:    return "RT5392";
    3101           0 :         default:                return "unknown";
    3102             :         }
    3103           0 : }
    3104             : 
    3105             : int
    3106           0 : rt2860_read_eeprom(struct rt2860_softc *sc)
    3107             : {
    3108           0 :         struct ieee80211com *ic = &sc->sc_ic;
    3109             :         int8_t delta_2ghz, delta_5ghz;
    3110             :         uint32_t tmp;
    3111             :         uint16_t val;
    3112             :         int ridx, ant, i;
    3113             : 
    3114             :         /* check whether the ROM is eFUSE ROM or EEPROM */
    3115           0 :         sc->sc_srom_read = rt2860_eeprom_read_2;
    3116           0 :         if (sc->mac_ver >= 0x3071) {
    3117           0 :                 tmp = RAL_READ(sc, RT3070_EFUSE_CTRL);
    3118             :                 DPRINTF(("EFUSE_CTRL=0x%08x\n", tmp));
    3119           0 :                 if (tmp & RT3070_SEL_EFUSE)
    3120           0 :                         sc->sc_srom_read = rt3090_efuse_read_2;
    3121             :         }
    3122             : 
    3123             :         /* read EEPROM version */
    3124           0 :         val = rt2860_srom_read(sc, RT2860_EEPROM_VERSION);
    3125             :         DPRINTF(("EEPROM rev=%d, FAE=%d\n", val & 0xff, val >> 8));
    3126             : 
    3127             :         /* read MAC address */
    3128           0 :         val = rt2860_srom_read(sc, RT2860_EEPROM_MAC01);
    3129           0 :         ic->ic_myaddr[0] = val & 0xff;
    3130           0 :         ic->ic_myaddr[1] = val >> 8;
    3131           0 :         val = rt2860_srom_read(sc, RT2860_EEPROM_MAC23);
    3132           0 :         ic->ic_myaddr[2] = val & 0xff;
    3133           0 :         ic->ic_myaddr[3] = val >> 8;
    3134           0 :         val = rt2860_srom_read(sc, RT2860_EEPROM_MAC45);
    3135           0 :         ic->ic_myaddr[4] = val & 0xff;
    3136           0 :         ic->ic_myaddr[5] = val >> 8;
    3137             : 
    3138             :         /* read country code */
    3139           0 :         val = rt2860_srom_read(sc, RT2860_EEPROM_COUNTRY);
    3140             :         DPRINTF(("EEPROM region code=0x%04x\n", val));
    3141             : 
    3142             :         /* read vendor BBP settings */
    3143           0 :         for (i = 0; i < 8; i++) {
    3144           0 :                 val = rt2860_srom_read(sc, RT2860_EEPROM_BBP_BASE + i);
    3145           0 :                 sc->bbp[i].val = val & 0xff;
    3146           0 :                 sc->bbp[i].reg = val >> 8;
    3147             :                 DPRINTF(("BBP%d=0x%02x\n", sc->bbp[i].reg, sc->bbp[i].val));
    3148             :         }
    3149           0 :         if (sc->mac_ver >= 0x3071) {
    3150             :                 /* read vendor RF settings */
    3151           0 :                 for (i = 0; i < 10; i++) {
    3152           0 :                         val = rt2860_srom_read(sc, RT3071_EEPROM_RF_BASE + i);
    3153           0 :                         sc->rf[i].val = val & 0xff;
    3154           0 :                         sc->rf[i].reg = val >> 8;
    3155             :                         DPRINTF(("RF%d=0x%02x\n", sc->rf[i].reg,
    3156             :                             sc->rf[i].val));
    3157             :                 }
    3158             :         }
    3159             : 
    3160             :         /* read RF frequency offset from EEPROM */
    3161           0 :         val = rt2860_srom_read(sc, RT2860_EEPROM_FREQ_LEDS);
    3162           0 :         sc->freq = ((val & 0xff) != 0xff) ? val & 0xff : 0;
    3163             :         DPRINTF(("EEPROM freq offset %d\n", sc->freq & 0xff));
    3164           0 :         if ((val >> 8) != 0xff) {
    3165             :                 /* read LEDs operating mode */
    3166           0 :                 sc->leds = val >> 8;
    3167           0 :                 sc->led[0] = rt2860_srom_read(sc, RT2860_EEPROM_LED1);
    3168           0 :                 sc->led[1] = rt2860_srom_read(sc, RT2860_EEPROM_LED2);
    3169           0 :                 sc->led[2] = rt2860_srom_read(sc, RT2860_EEPROM_LED3);
    3170           0 :         } else {
    3171             :                 /* broken EEPROM, use default settings */
    3172           0 :                 sc->leds = 0x01;
    3173           0 :                 sc->led[0] = 0x5555;
    3174           0 :                 sc->led[1] = 0x2221;
    3175           0 :                 sc->led[2] = 0xa9f8;
    3176             :         }
    3177             :         DPRINTF(("EEPROM LED mode=0x%02x, LEDs=0x%04x/0x%04x/0x%04x\n",
    3178             :             sc->leds, sc->led[0], sc->led[1], sc->led[2]));
    3179             : 
    3180             :         /* read RF information */
    3181           0 :         val = rt2860_srom_read(sc, RT2860_EEPROM_ANTENNA);
    3182           0 :         if (sc->mac_ver >= 0x5390)
    3183           0 :                 sc->rf_rev = rt2860_srom_read(sc, RT2860_EEPROM_CHIPID);
    3184             :         else
    3185           0 :                 sc->rf_rev = (val >> 8) & 0xf;
    3186           0 :         sc->ntxchains = (val >> 4) & 0xf;
    3187           0 :         sc->nrxchains = val & 0xf;
    3188             :         DPRINTF(("EEPROM RF rev=0x%02x chains=%dT%dR\n",
    3189             :             sc->rf_rev, sc->ntxchains, sc->nrxchains));
    3190             : 
    3191             :         /* check if RF supports automatic Tx access gain control */
    3192           0 :         val = rt2860_srom_read(sc, RT2860_EEPROM_CONFIG);
    3193             :         DPRINTF(("EEPROM CFG 0x%04x\n", val));
    3194             :         /* check if driver should patch the DAC issue */
    3195           0 :         if ((val >> 8) != 0xff)
    3196           0 :                 sc->patch_dac = (val >> 15) & 1;
    3197           0 :         if ((val & 0xff) != 0xff) {
    3198           0 :                 sc->ext_5ghz_lna = (val >> 3) & 1;
    3199           0 :                 sc->ext_2ghz_lna = (val >> 2) & 1;
    3200             :                 /* check if RF supports automatic Tx access gain control */
    3201           0 :                 sc->calib_2ghz = sc->calib_5ghz = 0; /* XXX (val >> 1) & 1 */;
    3202             :                 /* check if we have a hardware radio switch */
    3203           0 :                 sc->rfswitch = val & 1;
    3204           0 :         }
    3205           0 :         if (sc->sc_flags & RT2860_ADVANCED_PS) {
    3206             :                 /* read PCIe power save level */
    3207           0 :                 val = rt2860_srom_read(sc, RT2860_EEPROM_PCIE_PSLEVEL);
    3208           0 :                 if ((val & 0xff) != 0xff) {
    3209           0 :                         sc->pslevel = val & 0x3;
    3210           0 :                         val = rt2860_srom_read(sc, RT2860_EEPROM_REV);
    3211           0 :                         if ((val & 0xff80) != 0x9280)
    3212           0 :                                 sc->pslevel = MIN(sc->pslevel, 1);
    3213             :                         DPRINTF(("EEPROM PCIe PS Level=%d\n", sc->pslevel));
    3214             :                 }
    3215             :         }
    3216             : 
    3217             :         /* read power settings for 2GHz channels */
    3218           0 :         for (i = 0; i < 14; i += 2) {
    3219           0 :                 val = rt2860_srom_read(sc,
    3220           0 :                     RT2860_EEPROM_PWR2GHZ_BASE1 + i / 2);
    3221           0 :                 sc->txpow1[i + 0] = (int8_t)(val & 0xff);
    3222           0 :                 sc->txpow1[i + 1] = (int8_t)(val >> 8);
    3223             : 
    3224           0 :                 if (sc->mac_ver != 0x5390) {
    3225           0 :                         val = rt2860_srom_read(sc,
    3226           0 :                             RT2860_EEPROM_PWR2GHZ_BASE2 + i / 2);
    3227           0 :                         sc->txpow2[i + 0] = (int8_t)(val & 0xff);
    3228           0 :                         sc->txpow2[i + 1] = (int8_t)(val >> 8);
    3229           0 :                 }
    3230             :         }
    3231             :         /* fix broken Tx power entries */
    3232           0 :         for (i = 0; i < 14; i++) {
    3233           0 :                 if (sc->txpow1[i] < 0 ||
    3234           0 :                     sc->txpow1[i] > ((sc->mac_ver >= 0x5390) ? 39 : 31))
    3235           0 :                         sc->txpow1[i] = 5;
    3236           0 :                 if (sc->mac_ver != 0x5390) {
    3237           0 :                         if (sc->txpow2[i] < 0 ||
    3238           0 :                             sc->txpow2[i] > ((sc->mac_ver == 0x5392) ? 39 : 31))
    3239           0 :                                 sc->txpow2[i] = 5;
    3240             :                 }
    3241             :                 DPRINTF(("chan %d: power1=%d, power2=%d\n",
    3242             :                     rt2860_rf2850[i].chan, sc->txpow1[i], sc->txpow2[i]));
    3243             :         }
    3244             :         /* read power settings for 5GHz channels */
    3245           0 :         for (i = 0; i < 40; i += 2) {
    3246           0 :                 val = rt2860_srom_read(sc,
    3247           0 :                     RT2860_EEPROM_PWR5GHZ_BASE1 + i / 2);
    3248           0 :                 sc->txpow1[i + 14] = (int8_t)(val & 0xff);
    3249           0 :                 sc->txpow1[i + 15] = (int8_t)(val >> 8);
    3250             : 
    3251           0 :                 val = rt2860_srom_read(sc,
    3252           0 :                     RT2860_EEPROM_PWR5GHZ_BASE2 + i / 2);
    3253           0 :                 sc->txpow2[i + 14] = (int8_t)(val & 0xff);
    3254           0 :                 sc->txpow2[i + 15] = (int8_t)(val >> 8);
    3255             :         }
    3256             :         /* fix broken Tx power entries */
    3257           0 :         for (i = 0; i < 40; i++) {
    3258           0 :                 if (sc->txpow1[14 + i] < -7 || sc->txpow1[14 + i] > 15)
    3259           0 :                         sc->txpow1[14 + i] = 5;
    3260           0 :                 if (sc->txpow2[14 + i] < -7 || sc->txpow2[14 + i] > 15)
    3261           0 :                         sc->txpow2[14 + i] = 5;
    3262             :                 DPRINTF(("chan %d: power1=%d, power2=%d\n",
    3263             :                     rt2860_rf2850[14 + i].chan, sc->txpow1[14 + i],
    3264             :                     sc->txpow2[14 + i]));
    3265             :         }
    3266             : 
    3267             :         /* read Tx power compensation for each Tx rate */
    3268           0 :         val = rt2860_srom_read(sc, RT2860_EEPROM_DELTAPWR);
    3269             :         delta_2ghz = delta_5ghz = 0;
    3270           0 :         if ((val & 0xff) != 0xff && (val & 0x80)) {
    3271           0 :                 delta_2ghz = val & 0xf;
    3272           0 :                 if (!(val & 0x40))  /* negative number */
    3273           0 :                         delta_2ghz = -delta_2ghz;
    3274             :         }
    3275           0 :         val >>= 8;
    3276           0 :         if ((val & 0xff) != 0xff && (val & 0x80)) {
    3277           0 :                 delta_5ghz = val & 0xf;
    3278           0 :                 if (!(val & 0x40))  /* negative number */
    3279           0 :                         delta_5ghz = -delta_5ghz;
    3280             :         }
    3281             :         DPRINTF(("power compensation=%d (2GHz), %d (5GHz)\n",
    3282             :             delta_2ghz, delta_5ghz));
    3283             : 
    3284           0 :         for (ridx = 0; ridx < 5; ridx++) {
    3285             :                 uint32_t reg;
    3286             : 
    3287           0 :                 val = rt2860_srom_read(sc, RT2860_EEPROM_RPWR + ridx * 2);
    3288           0 :                 reg = val;
    3289           0 :                 val = rt2860_srom_read(sc, RT2860_EEPROM_RPWR + ridx * 2 + 1);
    3290           0 :                 reg |= (uint32_t)val << 16;
    3291             : 
    3292           0 :                 sc->txpow20mhz[ridx] = reg;
    3293           0 :                 sc->txpow40mhz_2ghz[ridx] = b4inc(reg, delta_2ghz);
    3294           0 :                 sc->txpow40mhz_5ghz[ridx] = b4inc(reg, delta_5ghz);
    3295             : 
    3296             :                 DPRINTF(("ridx %d: power 20MHz=0x%08x, 40MHz/2GHz=0x%08x, "
    3297             :                     "40MHz/5GHz=0x%08x\n", ridx, sc->txpow20mhz[ridx],
    3298             :                     sc->txpow40mhz_2ghz[ridx], sc->txpow40mhz_5ghz[ridx]));
    3299             :         }
    3300             : 
    3301             :         /* read factory-calibrated samples for temperature compensation */
    3302           0 :         val = rt2860_srom_read(sc, RT2860_EEPROM_TSSI1_2GHZ);
    3303           0 :         sc->tssi_2ghz[0] = val & 0xff;   /* [-4] */
    3304           0 :         sc->tssi_2ghz[1] = val >> 8;   /* [-3] */
    3305           0 :         val = rt2860_srom_read(sc, RT2860_EEPROM_TSSI2_2GHZ);
    3306           0 :         sc->tssi_2ghz[2] = val & 0xff;   /* [-2] */
    3307           0 :         sc->tssi_2ghz[3] = val >> 8;   /* [-1] */
    3308           0 :         val = rt2860_srom_read(sc, RT2860_EEPROM_TSSI3_2GHZ);
    3309           0 :         sc->tssi_2ghz[4] = val & 0xff;   /* [+0] */
    3310           0 :         sc->tssi_2ghz[5] = val >> 8;   /* [+1] */
    3311           0 :         val = rt2860_srom_read(sc, RT2860_EEPROM_TSSI4_2GHZ);
    3312           0 :         sc->tssi_2ghz[6] = val & 0xff;   /* [+2] */
    3313           0 :         sc->tssi_2ghz[7] = val >> 8;   /* [+3] */
    3314           0 :         val = rt2860_srom_read(sc, RT2860_EEPROM_TSSI5_2GHZ);
    3315           0 :         sc->tssi_2ghz[8] = val & 0xff;   /* [+4] */
    3316           0 :         sc->step_2ghz = val >> 8;
    3317             :         DPRINTF(("TSSI 2GHz: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x "
    3318             :             "0x%02x 0x%02x step=%d\n", sc->tssi_2ghz[0], sc->tssi_2ghz[1],
    3319             :             sc->tssi_2ghz[2], sc->tssi_2ghz[3], sc->tssi_2ghz[4],
    3320             :             sc->tssi_2ghz[5], sc->tssi_2ghz[6], sc->tssi_2ghz[7],
    3321             :             sc->tssi_2ghz[8], sc->step_2ghz));
    3322             :         /* check that ref value is correct, otherwise disable calibration */
    3323           0 :         if (sc->tssi_2ghz[4] == 0xff)
    3324           0 :                 sc->calib_2ghz = 0;
    3325             : 
    3326           0 :         val = rt2860_srom_read(sc, RT2860_EEPROM_TSSI1_5GHZ);
    3327           0 :         sc->tssi_5ghz[0] = val & 0xff;   /* [-4] */
    3328           0 :         sc->tssi_5ghz[1] = val >> 8;   /* [-3] */
    3329           0 :         val = rt2860_srom_read(sc, RT2860_EEPROM_TSSI2_5GHZ);
    3330           0 :         sc->tssi_5ghz[2] = val & 0xff;   /* [-2] */
    3331           0 :         sc->tssi_5ghz[3] = val >> 8;   /* [-1] */
    3332           0 :         val = rt2860_srom_read(sc, RT2860_EEPROM_TSSI3_5GHZ);
    3333           0 :         sc->tssi_5ghz[4] = val & 0xff;   /* [+0] */
    3334           0 :         sc->tssi_5ghz[5] = val >> 8;   /* [+1] */
    3335           0 :         val = rt2860_srom_read(sc, RT2860_EEPROM_TSSI4_5GHZ);
    3336           0 :         sc->tssi_5ghz[6] = val & 0xff;   /* [+2] */
    3337           0 :         sc->tssi_5ghz[7] = val >> 8;   /* [+3] */
    3338           0 :         val = rt2860_srom_read(sc, RT2860_EEPROM_TSSI5_5GHZ);
    3339           0 :         sc->tssi_5ghz[8] = val & 0xff;   /* [+4] */
    3340           0 :         sc->step_5ghz = val >> 8;
    3341             :         DPRINTF(("TSSI 5GHz: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x "
    3342             :             "0x%02x 0x%02x step=%d\n", sc->tssi_5ghz[0], sc->tssi_5ghz[1],
    3343             :             sc->tssi_5ghz[2], sc->tssi_5ghz[3], sc->tssi_5ghz[4],
    3344             :             sc->tssi_5ghz[5], sc->tssi_5ghz[6], sc->tssi_5ghz[7],
    3345             :             sc->tssi_5ghz[8], sc->step_5ghz));
    3346             :         /* check that ref value is correct, otherwise disable calibration */
    3347           0 :         if (sc->tssi_5ghz[4] == 0xff)
    3348           0 :                 sc->calib_5ghz = 0;
    3349             : 
    3350             :         /* read RSSI offsets and LNA gains from EEPROM */
    3351           0 :         val = rt2860_srom_read(sc, RT2860_EEPROM_RSSI1_2GHZ);
    3352           0 :         sc->rssi_2ghz[0] = val & 0xff;   /* Ant A */
    3353           0 :         sc->rssi_2ghz[1] = val >> 8;   /* Ant B */
    3354           0 :         val = rt2860_srom_read(sc, RT2860_EEPROM_RSSI2_2GHZ);
    3355           0 :         if (sc->mac_ver >= 0x3071) {
    3356             :                 /*
    3357             :                  * On RT3090 chips (limited to 2 Rx chains), this ROM
    3358             :                  * field contains the Tx mixer gain for the 2GHz band.
    3359             :                  */
    3360           0 :                 if ((val & 0xff) != 0xff)
    3361           0 :                         sc->txmixgain_2ghz = val & 0x7;
    3362             :                 DPRINTF(("tx mixer gain=%u (2GHz)\n", sc->txmixgain_2ghz));
    3363             :         } else
    3364           0 :                 sc->rssi_2ghz[2] = val & 0xff;   /* Ant C */
    3365           0 :         sc->lna[2] = val >> 8;         /* channel group 2 */
    3366             : 
    3367           0 :         val = rt2860_srom_read(sc, RT2860_EEPROM_RSSI1_5GHZ);
    3368           0 :         sc->rssi_5ghz[0] = val & 0xff;   /* Ant A */
    3369           0 :         sc->rssi_5ghz[1] = val >> 8;   /* Ant B */
    3370           0 :         val = rt2860_srom_read(sc, RT2860_EEPROM_RSSI2_5GHZ);
    3371           0 :         sc->rssi_5ghz[2] = val & 0xff;   /* Ant C */
    3372           0 :         sc->lna[3] = val >> 8;         /* channel group 3 */
    3373             : 
    3374           0 :         val = rt2860_srom_read(sc, RT2860_EEPROM_LNA);
    3375           0 :         if (sc->mac_ver >= 0x3071)
    3376           0 :                 sc->lna[0] = RT3090_DEF_LNA;
    3377             :         else                            /* channel group 0 */
    3378           0 :                 sc->lna[0] = val & 0xff;
    3379           0 :         sc->lna[1] = val >> 8;         /* channel group 1 */
    3380             : 
    3381             :         /* fix broken 5GHz LNA entries */
    3382           0 :         if (sc->lna[2] == 0 || sc->lna[2] == 0xff) {
    3383             :                 DPRINTF(("invalid LNA for channel group %d\n", 2));
    3384           0 :                 sc->lna[2] = sc->lna[1];
    3385           0 :         }
    3386           0 :         if (sc->lna[3] == 0 || sc->lna[3] == 0xff) {
    3387             :                 DPRINTF(("invalid LNA for channel group %d\n", 3));
    3388           0 :                 sc->lna[3] = sc->lna[1];
    3389           0 :         }
    3390             : 
    3391             :         /* fix broken RSSI offset entries */
    3392           0 :         for (ant = 0; ant < 3; ant++) {
    3393           0 :                 if (sc->rssi_2ghz[ant] < -10 || sc->rssi_2ghz[ant] > 10) {
    3394             :                         DPRINTF(("invalid RSSI%d offset: %d (2GHz)\n",
    3395             :                             ant + 1, sc->rssi_2ghz[ant]));
    3396           0 :                         sc->rssi_2ghz[ant] = 0;
    3397           0 :                 }
    3398           0 :                 if (sc->rssi_5ghz[ant] < -10 || sc->rssi_5ghz[ant] > 10) {
    3399             :                         DPRINTF(("invalid RSSI%d offset: %d (5GHz)\n",
    3400             :                             ant + 1, sc->rssi_5ghz[ant]));
    3401           0 :                         sc->rssi_5ghz[ant] = 0;
    3402           0 :                 }
    3403             :         }
    3404             : 
    3405           0 :         return 0;
    3406             : }
    3407             : 
    3408             : int
    3409           0 : rt2860_bbp_init(struct rt2860_softc *sc)
    3410             : {
    3411             :         int i, ntries;
    3412             : 
    3413             :         /* wait for BBP to wake up */
    3414           0 :         for (ntries = 0; ntries < 20; ntries++) {
    3415           0 :                 uint8_t bbp0 = rt2860_mcu_bbp_read(sc, 0);
    3416           0 :                 if (bbp0 != 0 && bbp0 != 0xff)
    3417           0 :                         break;
    3418           0 :         }
    3419           0 :         if (ntries == 20) {
    3420           0 :                 printf("%s: timeout waiting for BBP to wake up\n",
    3421           0 :                     sc->sc_dev.dv_xname);
    3422           0 :                 return ETIMEDOUT;
    3423             :         }
    3424             : 
    3425             :         /* initialize BBP registers to default values */
    3426           0 :         if (sc->mac_ver >= 0x5390)
    3427           0 :                 rt5390_bbp_init(sc);
    3428             :         else {
    3429           0 :                 for (i = 0; i < nitems(rt2860_def_bbp); i++) {
    3430           0 :                         rt2860_mcu_bbp_write(sc, rt2860_def_bbp[i].reg,
    3431           0 :                             rt2860_def_bbp[i].val);
    3432             :                 }
    3433             :         }
    3434             : 
    3435             :         /* fix BBP84 for RT2860E */
    3436           0 :         if (sc->mac_ver == 0x2860 && sc->mac_rev != 0x0101)
    3437           0 :                 rt2860_mcu_bbp_write(sc, 84, 0x19);
    3438             : 
    3439           0 :         if (sc->mac_ver >= 0x3071) {
    3440           0 :                 rt2860_mcu_bbp_write(sc, 79, 0x13);
    3441           0 :                 rt2860_mcu_bbp_write(sc, 80, 0x05);
    3442           0 :                 rt2860_mcu_bbp_write(sc, 81, 0x33);
    3443           0 :         } else if (sc->mac_ver == 0x2860 && sc->mac_rev == 0x0100) {
    3444           0 :                 rt2860_mcu_bbp_write(sc, 69, 0x16);
    3445           0 :                 rt2860_mcu_bbp_write(sc, 73, 0x12);
    3446           0 :         }
    3447             : 
    3448           0 :         return 0;
    3449           0 : }
    3450             : 
    3451             : void
    3452           0 : rt5390_bbp_init(struct rt2860_softc *sc)
    3453             : {
    3454             :         uint8_t bbp;
    3455             :         int i;
    3456             : 
    3457             :         /* Apply maximum likelihood detection for 2 stream case. */
    3458           0 :         if (sc->nrxchains > 1) {
    3459           0 :                 bbp = rt2860_mcu_bbp_read(sc, 105);
    3460           0 :                 rt2860_mcu_bbp_write(sc, 105, bbp | RT5390_MLD);
    3461           0 :         }
    3462             : 
    3463             :         /* Avoid data lost and CRC error. */
    3464           0 :         bbp = rt2860_mcu_bbp_read(sc, 4);
    3465           0 :         rt2860_mcu_bbp_write(sc, 4, bbp | RT5390_MAC_IF_CTRL);
    3466             : 
    3467           0 :         for (i = 0; i < nitems(rt5390_def_bbp); i++) {
    3468           0 :                 rt2860_mcu_bbp_write(sc, rt5390_def_bbp[i].reg,
    3469           0 :                     rt5390_def_bbp[i].val);
    3470             :         }
    3471             : 
    3472           0 :         if (sc->mac_ver == 0x5392) {
    3473           0 :                 rt2860_mcu_bbp_write(sc, 84, 0x9a);
    3474           0 :                 rt2860_mcu_bbp_write(sc, 95, 0x9a);
    3475           0 :                 rt2860_mcu_bbp_write(sc, 98, 0x12);
    3476           0 :                 rt2860_mcu_bbp_write(sc, 106, 0x05);
    3477           0 :                 rt2860_mcu_bbp_write(sc, 134, 0xd0);
    3478           0 :                 rt2860_mcu_bbp_write(sc, 135, 0xf6);
    3479           0 :         }
    3480             : 
    3481           0 :         bbp = rt2860_mcu_bbp_read(sc, 152);
    3482           0 :         rt2860_mcu_bbp_write(sc, 152, bbp | 0x80);
    3483             : 
    3484             :         /* Disable hardware antenna diversity. */
    3485           0 :         if (sc->mac_ver == 0x5390)
    3486           0 :                 rt2860_mcu_bbp_write(sc, 154, 0);
    3487           0 : }
    3488             : 
    3489             : int
    3490           0 : rt2860_txrx_enable(struct rt2860_softc *sc)
    3491             : {
    3492             :         uint32_t tmp;
    3493             :         int ntries;
    3494             : 
    3495             :         /* enable Tx/Rx DMA engine */
    3496           0 :         RAL_WRITE(sc, RT2860_MAC_SYS_CTRL, RT2860_MAC_TX_EN);
    3497           0 :         RAL_BARRIER_READ_WRITE(sc);
    3498           0 :         for (ntries = 0; ntries < 200; ntries++) {
    3499           0 :                 tmp = RAL_READ(sc, RT2860_WPDMA_GLO_CFG);
    3500           0 :                 if ((tmp & (RT2860_TX_DMA_BUSY | RT2860_RX_DMA_BUSY)) == 0)
    3501             :                         break;
    3502           0 :                 DELAY(1000);
    3503             :         }
    3504           0 :         if (ntries == 200) {
    3505           0 :                 printf("%s: timeout waiting for DMA engine\n",
    3506           0 :                     sc->sc_dev.dv_xname);
    3507           0 :                 return ETIMEDOUT;
    3508             :         }
    3509             : 
    3510           0 :         DELAY(50);
    3511             : 
    3512           0 :         tmp |= RT2860_RX_DMA_EN | RT2860_TX_DMA_EN |
    3513             :             RT2860_WPDMA_BT_SIZE64 << RT2860_WPDMA_BT_SIZE_SHIFT;
    3514           0 :         RAL_WRITE(sc, RT2860_WPDMA_GLO_CFG, tmp);
    3515             : 
    3516             :         /* set Rx filter */
    3517             :         tmp = RT2860_DROP_CRC_ERR | RT2860_DROP_PHY_ERR;
    3518           0 :         if (sc->sc_ic.ic_opmode != IEEE80211_M_MONITOR) {
    3519             :                 tmp |= RT2860_DROP_UC_NOME | RT2860_DROP_DUPL |
    3520             :                     RT2860_DROP_CTS | RT2860_DROP_BA | RT2860_DROP_ACK |
    3521             :                     RT2860_DROP_VER_ERR | RT2860_DROP_CTRL_RSV |
    3522             :                     RT2860_DROP_CFACK | RT2860_DROP_CFEND;
    3523           0 :                 if (sc->sc_ic.ic_opmode == IEEE80211_M_STA)
    3524           0 :                         tmp |= RT2860_DROP_RTS | RT2860_DROP_PSPOLL;
    3525             :         }
    3526           0 :         RAL_WRITE(sc, RT2860_RX_FILTR_CFG, tmp);
    3527             : 
    3528           0 :         RAL_WRITE(sc, RT2860_MAC_SYS_CTRL,
    3529             :             RT2860_MAC_RX_EN | RT2860_MAC_TX_EN);
    3530             : 
    3531           0 :         return 0;
    3532           0 : }
    3533             : 
    3534             : int
    3535           0 : rt2860_init(struct ifnet *ifp)
    3536             : {
    3537           0 :         struct rt2860_softc *sc = ifp->if_softc;
    3538           0 :         struct ieee80211com *ic = &sc->sc_ic;
    3539             :         uint32_t tmp;
    3540             :         uint8_t bbp1, bbp3;
    3541             :         int i, qid, ridx, ntries, error;
    3542             : 
    3543             :         /* for CardBus, power on the socket */
    3544           0 :         if (!(sc->sc_flags & RT2860_ENABLED)) {
    3545           0 :                 if (sc->sc_enable != NULL && (*sc->sc_enable)(sc) != 0) {
    3546           0 :                         printf("%s: could not enable device\n",
    3547           0 :                             sc->sc_dev.dv_xname);
    3548           0 :                         return EIO;
    3549             :                 }
    3550           0 :                 sc->sc_flags |= RT2860_ENABLED;
    3551           0 :         }
    3552             : 
    3553           0 :         if (sc->rfswitch) {
    3554             :                 /* hardware has a radio switch on GPIO pin 2 */
    3555           0 :                 if (!(RAL_READ(sc, RT2860_GPIO_CTRL) & (1 << 2))) {
    3556           0 :                         printf("%s: radio is disabled by hardware switch\n",
    3557           0 :                             sc->sc_dev.dv_xname);
    3558             : #ifdef notyet
    3559             :                         rt2860_stop(ifp, 1);
    3560             :                         return EPERM;
    3561             : #endif
    3562           0 :                 }
    3563             :         }
    3564           0 :         RAL_WRITE(sc, RT2860_PWR_PIN_CFG, RT2860_IO_RA_PE);
    3565             : 
    3566             :         /* disable DMA */
    3567           0 :         tmp = RAL_READ(sc, RT2860_WPDMA_GLO_CFG);
    3568           0 :         tmp &= 0xff0;
    3569           0 :         RAL_WRITE(sc, RT2860_WPDMA_GLO_CFG, tmp);
    3570             : 
    3571             :         /* PBF hardware reset */
    3572           0 :         RAL_WRITE(sc, RT2860_SYS_CTRL, 0xe1f);
    3573           0 :         RAL_BARRIER_WRITE(sc);
    3574           0 :         RAL_WRITE(sc, RT2860_SYS_CTRL, 0xe00);
    3575             : 
    3576           0 :         if ((error = rt2860_load_microcode(sc)) != 0) {
    3577           0 :                 printf("%s: could not load 8051 microcode\n",
    3578           0 :                     sc->sc_dev.dv_xname);
    3579           0 :                 rt2860_stop(ifp, 1);
    3580           0 :                 return error;
    3581             :         }
    3582             : 
    3583           0 :         IEEE80211_ADDR_COPY(ic->ic_myaddr, LLADDR(ifp->if_sadl));
    3584           0 :         rt2860_set_macaddr(sc, ic->ic_myaddr);
    3585             : 
    3586             :         /* init Tx power for all Tx rates (from EEPROM) */
    3587           0 :         for (ridx = 0; ridx < 5; ridx++) {
    3588           0 :                 if (sc->txpow20mhz[ridx] == 0xffffffff)
    3589             :                         continue;
    3590           0 :                 RAL_WRITE(sc, RT2860_TX_PWR_CFG(ridx), sc->txpow20mhz[ridx]);
    3591           0 :         }
    3592             : 
    3593           0 :         for (ntries = 0; ntries < 100; ntries++) {
    3594           0 :                 tmp = RAL_READ(sc, RT2860_WPDMA_GLO_CFG);
    3595           0 :                 if ((tmp & (RT2860_TX_DMA_BUSY | RT2860_RX_DMA_BUSY)) == 0)
    3596             :                         break;
    3597           0 :                 DELAY(1000);
    3598             :         }
    3599           0 :         if (ntries == 100) {
    3600           0 :                 printf("%s: timeout waiting for DMA engine\n",
    3601           0 :                     sc->sc_dev.dv_xname);
    3602           0 :                 rt2860_stop(ifp, 1);
    3603           0 :                 return ETIMEDOUT;
    3604             :         }
    3605           0 :         tmp &= 0xff0;
    3606           0 :         RAL_WRITE(sc, RT2860_WPDMA_GLO_CFG, tmp);
    3607             : 
    3608             :         /* reset Rx ring and all 6 Tx rings */
    3609           0 :         RAL_WRITE(sc, RT2860_WPDMA_RST_IDX, 0x1003f);
    3610             : 
    3611             :         /* PBF hardware reset */
    3612           0 :         RAL_WRITE(sc, RT2860_SYS_CTRL, 0xe1f);
    3613           0 :         RAL_BARRIER_WRITE(sc);
    3614           0 :         RAL_WRITE(sc, RT2860_SYS_CTRL, 0xe00);
    3615             : 
    3616           0 :         RAL_WRITE(sc, RT2860_PWR_PIN_CFG, RT2860_IO_RA_PE | RT2860_IO_RF_PE);
    3617             : 
    3618           0 :         RAL_WRITE(sc, RT2860_MAC_SYS_CTRL, RT2860_BBP_HRST | RT2860_MAC_SRST);
    3619           0 :         RAL_BARRIER_WRITE(sc);
    3620           0 :         RAL_WRITE(sc, RT2860_MAC_SYS_CTRL, 0);
    3621             : 
    3622           0 :         for (i = 0; i < nitems(rt2860_def_mac); i++)
    3623           0 :                 RAL_WRITE(sc, rt2860_def_mac[i].reg, rt2860_def_mac[i].val);
    3624           0 :         if (sc->mac_ver >= 0x5390)
    3625           0 :                 RAL_WRITE(sc, RT2860_TX_SW_CFG0, 0x00000404);
    3626           0 :         else if (sc->mac_ver >= 0x3071) {
    3627             :                 /* set delay of PA_PE assertion to 1us (unit of 0.25us) */
    3628           0 :                 RAL_WRITE(sc, RT2860_TX_SW_CFG0,
    3629             :                     4 << RT2860_DLY_PAPE_EN_SHIFT);
    3630           0 :         }
    3631             : 
    3632           0 :         if (!(RAL_READ(sc, RT2860_PCI_CFG) & RT2860_PCI_CFG_PCI)) {
    3633           0 :                 sc->sc_flags |= RT2860_PCIE;
    3634             :                 /* PCIe has different clock cycle count than PCI */
    3635           0 :                 tmp = RAL_READ(sc, RT2860_US_CYC_CNT);
    3636           0 :                 tmp = (tmp & ~0xff) | 0x7d;
    3637           0 :                 RAL_WRITE(sc, RT2860_US_CYC_CNT, tmp);
    3638           0 :         }
    3639             : 
    3640             :         /* wait while MAC is busy */
    3641           0 :         for (ntries = 0; ntries < 100; ntries++) {
    3642           0 :                 if (!(RAL_READ(sc, RT2860_MAC_STATUS_REG) &
    3643             :                     (RT2860_RX_STATUS_BUSY | RT2860_TX_STATUS_BUSY)))
    3644             :                         break;
    3645           0 :                 DELAY(1000);
    3646             :         }
    3647           0 :         if (ntries == 100) {
    3648           0 :                 printf("%s: timeout waiting for MAC\n", sc->sc_dev.dv_xname);
    3649           0 :                 rt2860_stop(ifp, 1);
    3650           0 :                 return ETIMEDOUT;
    3651             :         }
    3652             : 
    3653             :         /* clear Host to MCU mailbox */
    3654           0 :         RAL_WRITE(sc, RT2860_H2M_BBPAGENT, 0);
    3655           0 :         RAL_WRITE(sc, RT2860_H2M_MAILBOX, 0);
    3656             : 
    3657           0 :         rt2860_mcu_cmd(sc, RT2860_MCU_CMD_RFRESET, 0, 0);
    3658           0 :         DELAY(1000);
    3659             : 
    3660           0 :         if ((error = rt2860_bbp_init(sc)) != 0) {
    3661           0 :                 rt2860_stop(ifp, 1);
    3662           0 :                 return error;
    3663             :         }
    3664             : 
    3665             :         /* clear RX WCID search table */
    3666           0 :         RAL_SET_REGION_4(sc, RT2860_WCID_ENTRY(0), 0, 512);
    3667             :         /* clear pairwise key table */
    3668           0 :         RAL_SET_REGION_4(sc, RT2860_PKEY(0), 0, 2048);
    3669             :         /* clear IV/EIV table */
    3670           0 :         RAL_SET_REGION_4(sc, RT2860_IVEIV(0), 0, 512);
    3671             :         /* clear WCID attribute table */
    3672           0 :         RAL_SET_REGION_4(sc, RT2860_WCID_ATTR(0), 0, 256);
    3673             :         /* clear shared key table */
    3674           0 :         RAL_SET_REGION_4(sc, RT2860_SKEY(0, 0), 0, 8 * 32);
    3675             :         /* clear shared key mode */
    3676           0 :         RAL_SET_REGION_4(sc, RT2860_SKEY_MODE_0_7, 0, 4);
    3677             : 
    3678             :         /* init Tx rings (4 EDCAs + HCCA + Mgt) */
    3679           0 :         for (qid = 0; qid < 6; qid++) {
    3680           0 :                 RAL_WRITE(sc, RT2860_TX_BASE_PTR(qid), sc->txq[qid].paddr);
    3681           0 :                 RAL_WRITE(sc, RT2860_TX_MAX_CNT(qid), RT2860_TX_RING_COUNT);
    3682           0 :                 RAL_WRITE(sc, RT2860_TX_CTX_IDX(qid), 0);
    3683             :         }
    3684             : 
    3685             :         /* init Rx ring */
    3686           0 :         RAL_WRITE(sc, RT2860_RX_BASE_PTR, sc->rxq.paddr);
    3687           0 :         RAL_WRITE(sc, RT2860_RX_MAX_CNT, RT2860_RX_RING_COUNT);
    3688           0 :         RAL_WRITE(sc, RT2860_RX_CALC_IDX, RT2860_RX_RING_COUNT - 1);
    3689             : 
    3690             :         /* setup maximum buffer sizes */
    3691           0 :         RAL_WRITE(sc, RT2860_MAX_LEN_CFG, 1 << 12 |
    3692             :             (MCLBYTES - sizeof (struct rt2860_rxwi) - 2));
    3693             : 
    3694           0 :         for (ntries = 0; ntries < 100; ntries++) {
    3695           0 :                 tmp = RAL_READ(sc, RT2860_WPDMA_GLO_CFG);
    3696           0 :                 if ((tmp & (RT2860_TX_DMA_BUSY | RT2860_RX_DMA_BUSY)) == 0)
    3697             :                         break;
    3698           0 :                 DELAY(1000);
    3699             :         }
    3700           0 :         if (ntries == 100) {
    3701           0 :                 printf("%s: timeout waiting for DMA engine\n",
    3702           0 :                     sc->sc_dev.dv_xname);
    3703           0 :                 rt2860_stop(ifp, 1);
    3704           0 :                 return ETIMEDOUT;
    3705             :         }
    3706           0 :         tmp &= 0xff0;
    3707           0 :         RAL_WRITE(sc, RT2860_WPDMA_GLO_CFG, tmp);
    3708             : 
    3709             :         /* disable interrupts mitigation */
    3710           0 :         RAL_WRITE(sc, RT2860_DELAY_INT_CFG, 0);
    3711             : 
    3712             :         /* write vendor-specific BBP values (from EEPROM) */
    3713           0 :         for (i = 0; i < 8; i++) {
    3714           0 :                 if (sc->bbp[i].reg == 0 || sc->bbp[i].reg == 0xff)
    3715             :                         continue;
    3716           0 :                 rt2860_mcu_bbp_write(sc, sc->bbp[i].reg, sc->bbp[i].val);
    3717           0 :         }
    3718             : 
    3719             :         /* select Main antenna for 1T1R devices */
    3720           0 :         if (sc->rf_rev == RT3070_RF_2020 ||
    3721           0 :             sc->rf_rev == RT3070_RF_3020 ||
    3722           0 :             sc->rf_rev == RT3070_RF_3320 ||
    3723           0 :             sc->rf_rev == RT5390_RF_5390)
    3724           0 :                 rt3090_set_rx_antenna(sc, 0);
    3725             : 
    3726             :         /* send LEDs operating mode to microcontroller */
    3727           0 :         rt2860_mcu_cmd(sc, RT2860_MCU_CMD_LED1, sc->led[0], 0);
    3728           0 :         rt2860_mcu_cmd(sc, RT2860_MCU_CMD_LED2, sc->led[1], 0);
    3729           0 :         rt2860_mcu_cmd(sc, RT2860_MCU_CMD_LED3, sc->led[2], 0);
    3730             : 
    3731           0 :         if (sc->mac_ver >= 0x5390)
    3732           0 :                 rt5390_rf_init(sc);
    3733           0 :         else if (sc->mac_ver >= 0x3071)
    3734           0 :                 rt3090_rf_init(sc);
    3735             : 
    3736           0 :         rt2860_mcu_cmd(sc, RT2860_MCU_CMD_SLEEP, 0x02ff, 1);
    3737           0 :         rt2860_mcu_cmd(sc, RT2860_MCU_CMD_WAKEUP, 0, 1);
    3738             : 
    3739           0 :         if (sc->mac_ver >= 0x5390)
    3740           0 :                 rt5390_rf_wakeup(sc);
    3741           0 :         else if (sc->mac_ver >= 0x3071)
    3742           0 :                 rt3090_rf_wakeup(sc);
    3743             : 
    3744             :         /* disable non-existing Rx chains */
    3745           0 :         bbp3 = rt2860_mcu_bbp_read(sc, 3);
    3746           0 :         bbp3 &= ~(1 << 3 | 1 << 4);
    3747           0 :         if (sc->nrxchains == 2)
    3748           0 :                 bbp3 |= 1 << 3;
    3749           0 :         else if (sc->nrxchains == 3)
    3750           0 :                 bbp3 |= 1 << 4;
    3751           0 :         rt2860_mcu_bbp_write(sc, 3, bbp3);
    3752             : 
    3753             :         /* disable non-existing Tx chains */
    3754           0 :         bbp1 = rt2860_mcu_bbp_read(sc, 1);
    3755           0 :         if (sc->ntxchains == 1)
    3756           0 :                 bbp1 = (bbp1 & ~(1 << 3 | 1 << 4));
    3757           0 :         else if (sc->mac_ver == 0x3593 && sc->ntxchains == 2)
    3758           0 :                 bbp1 = (bbp1 & ~(1 << 4)) | 1 << 3;
    3759           0 :         else if (sc->mac_ver == 0x3593 && sc->ntxchains == 3)
    3760           0 :                 bbp1 = (bbp1 & ~(1 << 3)) | 1 << 4;
    3761           0 :         rt2860_mcu_bbp_write(sc, 1, bbp1);
    3762             : 
    3763           0 :         if (sc->mac_ver >= 0x3071)
    3764           0 :                 rt3090_rf_setup(sc);
    3765             : 
    3766             :         /* select default channel */
    3767           0 :         ic->ic_bss->ni_chan = ic->ic_ibss_chan;
    3768           0 :         rt2860_switch_chan(sc, ic->ic_ibss_chan);
    3769             : 
    3770             :         /* reset RF from MCU */
    3771           0 :         rt2860_mcu_cmd(sc, RT2860_MCU_CMD_RFRESET, 0, 0);
    3772             : 
    3773             :         /* set RTS threshold */
    3774           0 :         tmp = RAL_READ(sc, RT2860_TX_RTS_CFG);
    3775           0 :         tmp &= ~0xffff00;
    3776           0 :         tmp |= ic->ic_rtsthreshold << 8;
    3777           0 :         RAL_WRITE(sc, RT2860_TX_RTS_CFG, tmp);
    3778             : 
    3779             :         /* setup initial protection mode */
    3780           0 :         sc->sc_ic_flags = ic->ic_flags;
    3781           0 :         rt2860_updateprot(ic);
    3782             : 
    3783             :         /* turn radio LED on */
    3784           0 :         rt2860_set_leds(sc, RT2860_LED_RADIO);
    3785             : 
    3786             :         /* enable Tx/Rx DMA engine */
    3787           0 :         if ((error = rt2860_txrx_enable(sc)) != 0) {
    3788           0 :                 rt2860_stop(ifp, 1);
    3789           0 :                 return error;
    3790             :         }
    3791             : 
    3792             :         /* clear pending interrupts */
    3793           0 :         RAL_WRITE(sc, RT2860_INT_STATUS, 0xffffffff);
    3794             :         /* enable interrupts */
    3795           0 :         RAL_WRITE(sc, RT2860_INT_MASK, 0x3fffc);
    3796             : 
    3797           0 :         if (sc->sc_flags & RT2860_ADVANCED_PS)
    3798           0 :                 rt2860_mcu_cmd(sc, RT2860_MCU_CMD_PSLEVEL, sc->pslevel, 0);
    3799             : 
    3800           0 :         ifp->if_flags |= IFF_RUNNING;
    3801           0 :         ifq_clr_oactive(&ifp->if_snd);
    3802             : 
    3803           0 :         if (ic->ic_flags & IEEE80211_F_WEPON) {
    3804             :                 /* install WEP keys */
    3805           0 :                 for (i = 0; i < IEEE80211_WEP_NKID; i++)
    3806           0 :                         (void)rt2860_set_key(ic, NULL, &ic->ic_nw_keys[i]);
    3807             :         }
    3808             : 
    3809           0 :         if (ic->ic_opmode != IEEE80211_M_MONITOR)
    3810           0 :                 ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
    3811             :         else
    3812           0 :                 ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
    3813             : 
    3814           0 :         return 0;
    3815           0 : }
    3816             : 
    3817             : void
    3818           0 : rt2860_stop(struct ifnet *ifp, int disable)
    3819             : {
    3820           0 :         struct rt2860_softc *sc = ifp->if_softc;
    3821           0 :         struct ieee80211com *ic = &sc->sc_ic;
    3822             :         uint32_t tmp;
    3823             :         int qid;
    3824             : 
    3825           0 :         if (ifp->if_flags & IFF_RUNNING)
    3826           0 :                 rt2860_set_leds(sc, 0); /* turn all LEDs off */
    3827             : 
    3828           0 :         sc->sc_tx_timer = 0;
    3829           0 :         ifp->if_timer = 0;
    3830           0 :         ifp->if_flags &= ~IFF_RUNNING;
    3831           0 :         ifq_clr_oactive(&ifp->if_snd);
    3832             : 
    3833           0 :         ieee80211_new_state(ic, IEEE80211_S_INIT, -1);  /* free all nodes */
    3834             : 
    3835             :         /* disable interrupts */
    3836           0 :         RAL_WRITE(sc, RT2860_INT_MASK, 0);
    3837             : 
    3838             :         /* disable GP timer */
    3839           0 :         rt2860_set_gp_timer(sc, 0);
    3840             : 
    3841             :         /* disable Rx */
    3842           0 :         tmp = RAL_READ(sc, RT2860_MAC_SYS_CTRL);
    3843           0 :         tmp &= ~(RT2860_MAC_RX_EN | RT2860_MAC_TX_EN);
    3844           0 :         RAL_WRITE(sc, RT2860_MAC_SYS_CTRL, tmp);
    3845             : 
    3846             :         /* reset adapter */
    3847           0 :         RAL_WRITE(sc, RT2860_MAC_SYS_CTRL, RT2860_BBP_HRST | RT2860_MAC_SRST);
    3848           0 :         RAL_BARRIER_WRITE(sc);
    3849           0 :         RAL_WRITE(sc, RT2860_MAC_SYS_CTRL, 0);
    3850             : 
    3851             :         /* reset Tx and Rx rings (and reclaim TXWIs) */
    3852           0 :         sc->qfullmsk = 0;
    3853           0 :         for (qid = 0; qid < 6; qid++)
    3854           0 :                 rt2860_reset_tx_ring(sc, &sc->txq[qid]);
    3855           0 :         rt2860_reset_rx_ring(sc, &sc->rxq);
    3856             : 
    3857             :         /* for CardBus, power down the socket */
    3858           0 :         if (disable && sc->sc_disable != NULL) {
    3859           0 :                 if (sc->sc_flags & RT2860_ENABLED) {
    3860           0 :                         (*sc->sc_disable)(sc);
    3861           0 :                         sc->sc_flags &= ~RT2860_ENABLED;
    3862           0 :                 }
    3863             :         }
    3864           0 : }
    3865             : 
    3866             : int
    3867           0 : rt2860_load_microcode(struct rt2860_softc *sc)
    3868             : {
    3869             :         int ntries;
    3870             : 
    3871             :         /* set "host program ram write selection" bit */
    3872           0 :         RAL_WRITE(sc, RT2860_SYS_CTRL, RT2860_HST_PM_SEL);
    3873             :         /* write microcode image */
    3874           0 :         RAL_WRITE_REGION_1(sc, RT2860_FW_BASE, sc->ucode, sc->ucsize);
    3875             :         /* kick microcontroller unit */
    3876           0 :         RAL_WRITE(sc, RT2860_SYS_CTRL, 0);
    3877           0 :         RAL_BARRIER_WRITE(sc);
    3878           0 :         RAL_WRITE(sc, RT2860_SYS_CTRL, RT2860_MCU_RESET);
    3879             : 
    3880           0 :         RAL_WRITE(sc, RT2860_H2M_BBPAGENT, 0);
    3881           0 :         RAL_WRITE(sc, RT2860_H2M_MAILBOX, 0);
    3882             : 
    3883             :         /* wait until microcontroller is ready */
    3884           0 :         RAL_BARRIER_READ_WRITE(sc);
    3885           0 :         for (ntries = 0; ntries < 1000; ntries++) {
    3886           0 :                 if (RAL_READ(sc, RT2860_SYS_CTRL) & RT2860_MCU_READY)
    3887             :                         break;
    3888           0 :                 DELAY(1000);
    3889             :         }
    3890           0 :         if (ntries == 1000) {
    3891           0 :                 printf("%s: timeout waiting for MCU to initialize\n",
    3892           0 :                     sc->sc_dev.dv_xname);
    3893           0 :                 return ETIMEDOUT;
    3894             :         }
    3895           0 :         return 0;
    3896           0 : }
    3897             : 
    3898             : /*
    3899             :  * This function is called periodically to adjust Tx power based on
    3900             :  * temperature variation.
    3901             :  */
    3902             : void
    3903           0 : rt2860_calib(struct rt2860_softc *sc)
    3904             : {
    3905           0 :         struct ieee80211com *ic = &sc->sc_ic;
    3906             :         const uint8_t *tssi;
    3907             :         uint8_t step, bbp49;
    3908             :         int8_t ridx, d;
    3909             : 
    3910             :         /* read current temperature */
    3911           0 :         bbp49 = rt2860_mcu_bbp_read(sc, 49);
    3912             : 
    3913           0 :         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_bss->ni_chan)) {
    3914           0 :                 tssi = &sc->tssi_2ghz[4];
    3915           0 :                 step = sc->step_2ghz;
    3916           0 :         } else {
    3917           0 :                 tssi = &sc->tssi_5ghz[4];
    3918           0 :                 step = sc->step_5ghz;
    3919             :         }
    3920             : 
    3921           0 :         if (bbp49 < tssi[0]) {               /* lower than reference */
    3922             :                 /* use higher Tx power than default */
    3923           0 :                 for (d = 0; d > -4 && bbp49 <= tssi[d - 1]; d--);
    3924           0 :         } else if (bbp49 > tssi[0]) {        /* greater than reference */
    3925             :                 /* use lower Tx power than default */
    3926           0 :                 for (d = 0; d < +4 && bbp49 >= tssi[d + 1]; d++);
    3927             :         } else {
    3928             :                 /* use default Tx power */
    3929             :                 d = 0;
    3930             :         }
    3931           0 :         d *= step;
    3932             : 
    3933             :         DPRINTF(("BBP49=0x%02x, adjusting Tx power by %d\n", bbp49, d));
    3934             : 
    3935             :         /* write adjusted Tx power values for each Tx rate */
    3936           0 :         for (ridx = 0; ridx < 5; ridx++) {
    3937           0 :                 if (sc->txpow20mhz[ridx] == 0xffffffff)
    3938             :                         continue;
    3939           0 :                 RAL_WRITE(sc, RT2860_TX_PWR_CFG(ridx),
    3940             :                     b4inc(sc->txpow20mhz[ridx], d));
    3941           0 :         }
    3942           0 : }
    3943             : 
    3944             : void
    3945           0 : rt3090_set_rx_antenna(struct rt2860_softc *sc, int aux)
    3946             : {
    3947             :         uint32_t tmp;
    3948           0 :         if (aux) {
    3949           0 :                 if (sc->mac_ver == 0x5390) {
    3950           0 :                         rt2860_mcu_bbp_write(sc, 152,
    3951           0 :                             rt2860_mcu_bbp_read(sc, 152) & ~0x80);
    3952           0 :                 } else {
    3953           0 :                         tmp = RAL_READ(sc, RT2860_PCI_EECTRL);
    3954           0 :                         RAL_WRITE(sc, RT2860_PCI_EECTRL,
    3955             :                             tmp & ~RT2860_C);
    3956           0 :                         tmp = RAL_READ(sc, RT2860_GPIO_CTRL);
    3957           0 :                         RAL_WRITE(sc, RT2860_GPIO_CTRL,
    3958             :                             (tmp & ~0x0808) | 0x08);
    3959             :                 }
    3960             :         } else {
    3961           0 :                 if (sc->mac_ver == 0x5390) {
    3962           0 :                         rt2860_mcu_bbp_write(sc, 152,
    3963           0 :                             rt2860_mcu_bbp_read(sc, 152) | 0x80);
    3964           0 :                 } else {
    3965           0 :                         tmp = RAL_READ(sc, RT2860_PCI_EECTRL);
    3966           0 :                         RAL_WRITE(sc, RT2860_PCI_EECTRL,
    3967             :                             tmp | RT2860_C);
    3968           0 :                         tmp = RAL_READ(sc, RT2860_GPIO_CTRL);
    3969           0 :                         RAL_WRITE(sc, RT2860_GPIO_CTRL,
    3970             :                             tmp & ~0x0808);
    3971             :                 }
    3972             :         }
    3973           0 : }
    3974             : 
    3975             : void
    3976           0 : rt2860_switch_chan(struct rt2860_softc *sc, struct ieee80211_channel *c)
    3977             : {
    3978           0 :         struct ieee80211com *ic = &sc->sc_ic;
    3979             :         u_int chan, group;
    3980             : 
    3981           0 :         chan = ieee80211_chan2ieee(ic, c);
    3982           0 :         if (chan == 0 || chan == IEEE80211_CHAN_ANY)
    3983           0 :                 return;
    3984             : 
    3985           0 :         if (sc->mac_ver >= 0x5390)
    3986           0 :                 rt5390_set_chan(sc, chan);
    3987           0 :         else if (sc->mac_ver >= 0x3071)
    3988           0 :                 rt3090_set_chan(sc, chan);
    3989             :         else
    3990           0 :                 rt2860_set_chan(sc, chan);
    3991             : 
    3992             :         /* determine channel group */
    3993           0 :         if (chan <= 14)
    3994           0 :                 group = 0;
    3995           0 :         else if (chan <= 64)
    3996           0 :                 group = 1;
    3997           0 :         else if (chan <= 128)
    3998           0 :                 group = 2;
    3999             :         else
    4000             :                 group = 3;
    4001             : 
    4002             :         /* XXX necessary only when group has changed! */
    4003           0 :         if (sc->mac_ver <= 0x5390)
    4004           0 :                 rt2860_select_chan_group(sc, group);
    4005             : 
    4006           0 :         DELAY(1000);
    4007           0 : }
    4008             : 
    4009             : #ifndef IEEE80211_STA_ONLY
    4010             : int
    4011           0 : rt2860_setup_beacon(struct rt2860_softc *sc)
    4012             : {
    4013           0 :         struct ieee80211com *ic = &sc->sc_ic;
    4014           0 :         struct rt2860_txwi txwi;
    4015             :         struct mbuf *m;
    4016             :         int ridx;
    4017             : 
    4018           0 :         if ((m = ieee80211_beacon_alloc(ic, ic->ic_bss)) == NULL)
    4019           0 :                 return ENOBUFS;
    4020             : 
    4021           0 :         memset(&txwi, 0, sizeof txwi);
    4022           0 :         txwi.wcid = 0xff;
    4023           0 :         txwi.len = htole16(m->m_pkthdr.len);
    4024             :         /* send beacons at the lowest available rate */
    4025           0 :         ridx = (ic->ic_curmode == IEEE80211_MODE_11A) ?
    4026             :             RT2860_RIDX_OFDM6 : RT2860_RIDX_CCK1;
    4027           0 :         txwi.phy = htole16(rt2860_rates[ridx].mcs);
    4028           0 :         if (rt2860_rates[ridx].phy == IEEE80211_T_OFDM)
    4029           0 :                 txwi.phy |= htole16(RT2860_PHY_OFDM);
    4030           0 :         txwi.txop = RT2860_TX_TXOP_HT;
    4031           0 :         txwi.flags = RT2860_TX_TS;
    4032           0 :         txwi.xflags = RT2860_TX_NSEQ;
    4033             : 
    4034           0 :         RAL_WRITE_REGION_1(sc, RT2860_BCN_BASE(0),
    4035             :             (uint8_t *)&txwi, sizeof txwi);
    4036           0 :         RAL_WRITE_REGION_1(sc, RT2860_BCN_BASE(0) + sizeof txwi,
    4037             :             mtod(m, uint8_t *), m->m_pkthdr.len);
    4038             : 
    4039           0 :         m_freem(m);
    4040             : 
    4041           0 :         return 0;
    4042           0 : }
    4043             : #endif
    4044             : 
    4045             : void
    4046           0 : rt2860_enable_tsf_sync(struct rt2860_softc *sc)
    4047             : {
    4048           0 :         struct ieee80211com *ic = &sc->sc_ic;
    4049             :         uint32_t tmp;
    4050             : 
    4051           0 :         tmp = RAL_READ(sc, RT2860_BCN_TIME_CFG);
    4052             : 
    4053           0 :         tmp &= ~0x1fffff;
    4054           0 :         tmp |= ic->ic_bss->ni_intval * 16;
    4055           0 :         tmp |= RT2860_TSF_TIMER_EN | RT2860_TBTT_TIMER_EN;
    4056           0 :         if (ic->ic_opmode == IEEE80211_M_STA) {
    4057             :                 /*
    4058             :                  * Local TSF is always updated with remote TSF on beacon
    4059             :                  * reception.
    4060             :                  */
    4061           0 :                 tmp |= 1 << RT2860_TSF_SYNC_MODE_SHIFT;
    4062           0 :         }
    4063             : #ifndef IEEE80211_STA_ONLY
    4064           0 :         else if (ic->ic_opmode == IEEE80211_M_IBSS) {
    4065           0 :                 tmp |= RT2860_BCN_TX_EN;
    4066             :                 /*
    4067             :                  * Local TSF is updated with remote TSF on beacon reception
    4068             :                  * only if the remote TSF is greater than local TSF.
    4069             :                  */
    4070           0 :                 tmp |= 2 << RT2860_TSF_SYNC_MODE_SHIFT;
    4071           0 :         } else if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
    4072           0 :                 tmp |= RT2860_BCN_TX_EN;
    4073             :                 /* SYNC with nobody */
    4074           0 :                 tmp |= 3 << RT2860_TSF_SYNC_MODE_SHIFT;
    4075           0 :         }
    4076             : #endif
    4077             : 
    4078           0 :         RAL_WRITE(sc, RT2860_BCN_TIME_CFG, tmp);
    4079           0 : }

Generated by: LCOV version 1.13