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

          Line data    Source code
       1             : /*      $OpenBSD: ath.c,v 1.116 2018/01/31 11:27:03 stsp Exp $  */
       2             : /*      $NetBSD: ath.c,v 1.37 2004/08/18 21:59:39 dyoung Exp $  */
       3             : 
       4             : /*-
       5             :  * Copyright (c) 2002-2004 Sam Leffler, Errno Consulting
       6             :  * All rights reserved.
       7             :  *
       8             :  * Redistribution and use in source and binary forms, with or without
       9             :  * modification, are permitted provided that the following conditions
      10             :  * are met:
      11             :  * 1. Redistributions of source code must retain the above copyright
      12             :  *    notice, this list of conditions and the following disclaimer,
      13             :  *    without modification.
      14             :  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
      15             :  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
      16             :  *    redistribution must be conditioned upon including a substantially
      17             :  *    similar Disclaimer requirement for further binary redistribution.
      18             :  * 3. Neither the names of the above-listed copyright holders nor the names
      19             :  *    of any contributors may be used to endorse or promote products derived
      20             :  *    from this software without specific prior written permission.
      21             :  *
      22             :  * NO WARRANTY
      23             :  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      24             :  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
      25             :  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
      26             :  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
      27             :  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
      28             :  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
      29             :  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
      30             :  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
      31             :  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
      32             :  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
      33             :  * THE POSSIBILITY OF SUCH DAMAGES.
      34             :  */
      35             : 
      36             : /*
      37             :  * Driver for the Atheros Wireless LAN controller.
      38             :  *
      39             :  * This software is derived from work of Atsushi Onoe; his contribution
      40             :  * is greatly appreciated. It has been modified for OpenBSD to use an
      41             :  * open source HAL instead of the original binary-only HAL. 
      42             :  */
      43             : 
      44             : #include "bpfilter.h"
      45             : 
      46             : #include <sys/param.h>
      47             : #include <sys/systm.h>
      48             : #include <sys/mbuf.h>
      49             : #include <sys/malloc.h>
      50             : #include <sys/lock.h>
      51             : #include <sys/kernel.h>
      52             : #include <sys/socket.h>
      53             : #include <sys/sockio.h>
      54             : #include <sys/device.h>
      55             : #include <sys/errno.h>
      56             : #include <sys/timeout.h>
      57             : #include <sys/gpio.h>
      58             : #include <sys/endian.h>
      59             : 
      60             : #include <machine/bus.h>
      61             : 
      62             : #include <net/if.h>
      63             : #include <net/if_dl.h>
      64             : #include <net/if_media.h>
      65             : #if NBPFILTER > 0
      66             : #include <net/bpf.h>
      67             : #endif
      68             : #include <netinet/in.h>
      69             : #include <netinet/if_ether.h>
      70             : 
      71             : #include <net80211/ieee80211_var.h>
      72             : #include <net80211/ieee80211_rssadapt.h>
      73             : 
      74             : #include <dev/pci/pcidevs.h>
      75             : #include <dev/gpio/gpiovar.h>
      76             : 
      77             : #include <dev/ic/athvar.h>
      78             : 
      79             : int     ath_init(struct ifnet *);
      80             : int     ath_init1(struct ath_softc *);
      81             : int     ath_intr1(struct ath_softc *);
      82             : void    ath_stop(struct ifnet *);
      83             : void    ath_start(struct ifnet *);
      84             : void    ath_reset(struct ath_softc *, int);
      85             : int     ath_media_change(struct ifnet *);
      86             : void    ath_watchdog(struct ifnet *);
      87             : int     ath_ioctl(struct ifnet *, u_long, caddr_t);
      88             : void    ath_fatal_proc(void *, int);
      89             : void    ath_rxorn_proc(void *, int);
      90             : void    ath_bmiss_proc(void *, int);
      91             : int     ath_initkeytable(struct ath_softc *);
      92             : void    ath_mcastfilter_accum(caddr_t, u_int32_t (*)[2]);
      93             : void    ath_mcastfilter_compute(struct ath_softc *, u_int32_t (*)[2]);
      94             : u_int32_t ath_calcrxfilter(struct ath_softc *);
      95             : void    ath_mode_init(struct ath_softc *);
      96             : #ifndef IEEE80211_STA_ONLY
      97             : int     ath_beacon_alloc(struct ath_softc *, struct ieee80211_node *);
      98             : void    ath_beacon_proc(void *, int);
      99             : void    ath_beacon_free(struct ath_softc *);
     100             : #endif
     101             : void    ath_beacon_config(struct ath_softc *);
     102             : int     ath_desc_alloc(struct ath_softc *);
     103             : void    ath_desc_free(struct ath_softc *);
     104             : struct ieee80211_node *ath_node_alloc(struct ieee80211com *);
     105             : struct mbuf *ath_getmbuf(int, int, u_int);
     106             : void    ath_node_free(struct ieee80211com *, struct ieee80211_node *);
     107             : void    ath_node_copy(struct ieee80211com *,
     108             :             struct ieee80211_node *, const struct ieee80211_node *);
     109             : u_int8_t ath_node_getrssi(struct ieee80211com *,
     110             :             const struct ieee80211_node *);
     111             : int     ath_rxbuf_init(struct ath_softc *, struct ath_buf *);
     112             : void    ath_rx_proc(void *, int);
     113             : int     ath_tx_start(struct ath_softc *, struct ieee80211_node *,
     114             :             struct ath_buf *, struct mbuf *);
     115             : void    ath_tx_proc(void *, int);
     116             : int     ath_chan_set(struct ath_softc *, struct ieee80211_channel *);
     117             : void    ath_draintxq(struct ath_softc *);
     118             : void    ath_stoprecv(struct ath_softc *);
     119             : int     ath_startrecv(struct ath_softc *);
     120             : void    ath_next_scan(void *);
     121             : int     ath_set_slot_time(struct ath_softc *);
     122             : void    ath_calibrate(void *);
     123             : void    ath_ledstate(struct ath_softc *, enum ieee80211_state);
     124             : int     ath_newstate(struct ieee80211com *, enum ieee80211_state, int);
     125             : void    ath_newassoc(struct ieee80211com *,
     126             :             struct ieee80211_node *, int);
     127             : int     ath_getchannels(struct ath_softc *, HAL_BOOL outdoor,
     128             :             HAL_BOOL xchanmode);
     129             : int     ath_rate_setup(struct ath_softc *sc, u_int mode);
     130             : void    ath_setcurmode(struct ath_softc *, enum ieee80211_phymode);
     131             : void    ath_rssadapt_updatenode(void *, struct ieee80211_node *);
     132             : void    ath_rssadapt_updatestats(void *);
     133             : #ifndef IEEE80211_STA_ONLY
     134             : void    ath_recv_mgmt(struct ieee80211com *, struct mbuf *,
     135             :             struct ieee80211_node *, struct ieee80211_rxinfo *, int);
     136             : #endif
     137             : void    ath_disable(struct ath_softc *);
     138             : 
     139             : int     ath_gpio_attach(struct ath_softc *, u_int16_t);
     140             : int     ath_gpio_pin_read(void *, int);
     141             : void    ath_gpio_pin_write(void *, int, int);
     142             : void    ath_gpio_pin_ctl(void *, int, int);
     143             : 
     144             : #ifdef AR_DEBUG
     145             : void    ath_printrxbuf(struct ath_buf *, int);
     146             : void    ath_printtxbuf(struct ath_buf *, int);
     147             : int ath_debug = 0;
     148             : #endif
     149             : 
     150             : int ath_dwelltime = 200;                /* 5 channels/second */
     151             : int ath_calinterval = 30;               /* calibrate every 30 secs */
     152             : int ath_outdoor = AH_TRUE;              /* outdoor operation */
     153             : int ath_xchanmode = AH_TRUE;            /* enable extended channels */
     154             : int ath_softcrypto = 1;                 /* 1=enable software crypto */
     155             : 
     156             : struct cfdriver ath_cd = {
     157             :         NULL, "ath", DV_IFNET
     158             : };
     159             : 
     160             : int
     161           0 : ath_activate(struct device *self, int act)
     162             : {
     163           0 :         struct ath_softc *sc = (struct ath_softc *)self;
     164           0 :         struct ifnet *ifp = &sc->sc_ic.ic_if;
     165             : 
     166           0 :         switch (act) {
     167             :         case DVACT_SUSPEND:
     168           0 :                 if (ifp->if_flags & IFF_RUNNING) {
     169           0 :                         ath_stop(ifp);
     170           0 :                         if (sc->sc_power != NULL)
     171           0 :                                 (*sc->sc_power)(sc, act);
     172             :                 }
     173             :                 break;
     174             :         case DVACT_RESUME:
     175           0 :                 if (ifp->if_flags & IFF_UP) {
     176           0 :                         ath_init(ifp);
     177           0 :                         if (ifp->if_flags & IFF_RUNNING)
     178           0 :                                 ath_start(ifp);
     179             :                 }
     180             :                 break;
     181             :         }
     182           0 :         return 0;
     183             : }
     184             : 
     185             : int
     186           0 : ath_enable(struct ath_softc *sc)
     187             : {
     188           0 :         if (ATH_IS_ENABLED(sc) == 0) {
     189           0 :                 if (sc->sc_enable != NULL && (*sc->sc_enable)(sc) != 0) {
     190           0 :                         printf("%s: device enable failed\n",
     191           0 :                                 sc->sc_dev.dv_xname);
     192           0 :                         return (EIO);
     193             :                 }
     194           0 :                 sc->sc_flags |= ATH_ENABLED;
     195           0 :         }
     196           0 :         return (0);
     197           0 : }
     198             : 
     199             : void
     200           0 : ath_disable(struct ath_softc *sc)
     201             : {
     202           0 :         if (!ATH_IS_ENABLED(sc))
     203             :                 return;
     204           0 :         if (sc->sc_disable != NULL)
     205           0 :                 (*sc->sc_disable)(sc);
     206           0 :         sc->sc_flags &= ~ATH_ENABLED;
     207           0 : }
     208             : 
     209             : int
     210           0 : ath_attach(u_int16_t devid, struct ath_softc *sc)
     211             : {
     212           0 :         struct ieee80211com *ic = &sc->sc_ic;
     213           0 :         struct ifnet *ifp = &ic->ic_if;
     214             :         struct ath_hal *ah;
     215           0 :         HAL_STATUS status;
     216           0 :         HAL_TXQ_INFO qinfo;
     217             :         int error = 0, i;
     218             : 
     219             :         DPRINTF(ATH_DEBUG_ANY, ("%s: devid 0x%x\n", __func__, devid));
     220             : 
     221           0 :         bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
     222           0 :         sc->sc_flags &= ~ATH_ATTACHED;   /* make sure that it's not attached */
     223             : 
     224           0 :         ah = ath_hal_attach(devid, sc, sc->sc_st, sc->sc_sh,
     225           0 :             sc->sc_pcie, &status);
     226           0 :         if (ah == NULL) {
     227           0 :                 printf("%s: unable to attach hardware; HAL status %d\n",
     228           0 :                         ifp->if_xname, status);
     229             :                 error = ENXIO;
     230           0 :                 goto bad;
     231             :         }
     232           0 :         if (ah->ah_abi != HAL_ABI_VERSION) {
     233           0 :                 printf("%s: HAL ABI mismatch detected (0x%x != 0x%x)\n",
     234             :                         ifp->if_xname, ah->ah_abi, HAL_ABI_VERSION);
     235             :                 error = ENXIO;
     236           0 :                 goto bad;
     237             :         }
     238             : 
     239           0 :         if (ah->ah_single_chip == AH_TRUE) {
     240           0 :                 printf("%s: AR%s %u.%u phy %u.%u rf %u.%u", ifp->if_xname,
     241           0 :                     ar5k_printver(AR5K_VERSION_DEV, devid),
     242           0 :                     ah->ah_mac_version, ah->ah_mac_revision,
     243           0 :                     ah->ah_phy_revision >> 4, ah->ah_phy_revision & 0xf,
     244           0 :                     ah->ah_radio_5ghz_revision >> 4,
     245           0 :                     ah->ah_radio_5ghz_revision & 0xf);
     246           0 :         } else {
     247           0 :                 printf("%s: AR%s %u.%u phy %u.%u", ifp->if_xname,
     248           0 :                     ar5k_printver(AR5K_VERSION_VER, ah->ah_mac_srev),
     249           0 :                     ah->ah_mac_version, ah->ah_mac_revision,
     250           0 :                     ah->ah_phy_revision >> 4, ah->ah_phy_revision & 0xf);
     251           0 :                 printf(" rf%s %u.%u",
     252           0 :                     ar5k_printver(AR5K_VERSION_RAD, ah->ah_radio_5ghz_revision),
     253           0 :                     ah->ah_radio_5ghz_revision >> 4,
     254           0 :                     ah->ah_radio_5ghz_revision & 0xf);
     255           0 :                 if (ah->ah_radio_2ghz_revision != 0) {
     256           0 :                         printf(" rf%s %u.%u",
     257           0 :                             ar5k_printver(AR5K_VERSION_RAD,
     258             :                             ah->ah_radio_2ghz_revision),
     259           0 :                             ah->ah_radio_2ghz_revision >> 4,
     260           0 :                             ah->ah_radio_2ghz_revision & 0xf);
     261           0 :                 }
     262             :         }
     263           0 :         if (ah->ah_ee_version == AR5K_EEPROM_VERSION_4_7)
     264           0 :                 printf(" eeprom 4.7");
     265             :         else
     266           0 :                 printf(" eeprom %1x.%1x", ah->ah_ee_version >> 12,
     267           0 :                     ah->ah_ee_version & 0xff);
     268             : 
     269             : #if 0
     270             :         if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_UNSUPP ||
     271             :             ah->ah_radio_2ghz_revision >= AR5K_SREV_RAD_UNSUPP) {
     272             :                 printf(": RF radio not supported\n");
     273             :                 error = EOPNOTSUPP;
     274             :                 goto bad;
     275             :         }
     276             : #endif
     277             : 
     278           0 :         sc->sc_ah = ah;
     279           0 :         sc->sc_invalid = 0;  /* ready to go, enable interrupt handling */
     280             : 
     281             :         /*
     282             :          * Get regulation domain either stored in the EEPROM or defined
     283             :          * as the default value. Some devices are known to have broken
     284             :          * regulation domain values in their EEPROM.
     285             :          */
     286           0 :         ath_hal_get_regdomain(ah, &ah->ah_regdomain);
     287             : 
     288             :         /*
     289             :          * Construct channel list based on the current regulation domain.
     290             :          */
     291           0 :         error = ath_getchannels(sc, ath_outdoor, ath_xchanmode);
     292           0 :         if (error != 0)
     293             :                 goto bad;
     294             : 
     295             :         /*
     296             :          * Setup rate tables for all potential media types.
     297             :          */
     298           0 :         ath_rate_setup(sc, IEEE80211_MODE_11A);
     299           0 :         ath_rate_setup(sc, IEEE80211_MODE_11B);
     300           0 :         ath_rate_setup(sc, IEEE80211_MODE_11G);
     301             : 
     302           0 :         error = ath_desc_alloc(sc);
     303           0 :         if (error != 0) {
     304           0 :                 printf(": failed to allocate descriptors: %d\n", error);
     305           0 :                 goto bad;
     306             :         }
     307           0 :         timeout_set(&sc->sc_scan_to, ath_next_scan, sc);
     308           0 :         timeout_set(&sc->sc_cal_to, ath_calibrate, sc);
     309           0 :         timeout_set(&sc->sc_rssadapt_to, ath_rssadapt_updatestats, sc);
     310             : 
     311             : #ifdef __FreeBSD__
     312             :         ATH_TXBUF_LOCK_INIT(sc);
     313             :         ATH_TXQ_LOCK_INIT(sc);
     314             : #endif
     315             : 
     316           0 :         ATH_TASK_INIT(&sc->sc_txtask, ath_tx_proc, sc);
     317           0 :         ATH_TASK_INIT(&sc->sc_rxtask, ath_rx_proc, sc);
     318           0 :         ATH_TASK_INIT(&sc->sc_rxorntask, ath_rxorn_proc, sc);
     319           0 :         ATH_TASK_INIT(&sc->sc_fataltask, ath_fatal_proc, sc);
     320           0 :         ATH_TASK_INIT(&sc->sc_bmisstask, ath_bmiss_proc, sc);
     321             : #ifndef IEEE80211_STA_ONLY
     322           0 :         ATH_TASK_INIT(&sc->sc_swbatask, ath_beacon_proc, sc);
     323             : #endif
     324             : 
     325             :         /*
     326             :          * For now just pre-allocate one data queue and one
     327             :          * beacon queue.  Note that the HAL handles resetting
     328             :          * them at the needed time.  Eventually we'll want to
     329             :          * allocate more tx queues for splitting management
     330             :          * frames and for QOS support.
     331             :          */
     332           0 :         sc->sc_bhalq = ath_hal_setup_tx_queue(ah, HAL_TX_QUEUE_BEACON, NULL);
     333           0 :         if (sc->sc_bhalq == (u_int) -1) {
     334           0 :                 printf(": unable to setup a beacon xmit queue!\n");
     335           0 :                 goto bad2;
     336             :         }
     337             : 
     338           0 :         for (i = 0; i <= HAL_TX_QUEUE_ID_DATA_MAX; i++) {
     339           0 :                 bzero(&qinfo, sizeof(qinfo));
     340           0 :                 qinfo.tqi_type = HAL_TX_QUEUE_DATA;
     341           0 :                 qinfo.tqi_subtype = i; /* should be mapped to WME types */
     342           0 :                 sc->sc_txhalq[i] = ath_hal_setup_tx_queue(ah,
     343             :                     HAL_TX_QUEUE_DATA, &qinfo);
     344           0 :                 if (sc->sc_txhalq[i] == (u_int) -1) {
     345           0 :                         printf(": unable to setup a data xmit queue %u!\n", i);
     346           0 :                         goto bad2;
     347             :                 }
     348             :         }
     349             : 
     350           0 :         ifp->if_softc = sc;
     351           0 :         ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST;
     352           0 :         ifp->if_start = ath_start;
     353           0 :         ifp->if_watchdog = ath_watchdog;
     354           0 :         ifp->if_ioctl = ath_ioctl;
     355             : #ifndef __OpenBSD__
     356             :         ifp->if_stop = ath_stop;             /* XXX */
     357             : #endif
     358           0 :         IFQ_SET_MAXLEN(&ifp->if_snd, ATH_TXBUF * ATH_TXDESC);
     359             : 
     360           0 :         ic->ic_softc = sc;
     361           0 :         ic->ic_newassoc = ath_newassoc;
     362             :         /* XXX not right but it's not used anywhere important */
     363           0 :         ic->ic_phytype = IEEE80211_T_OFDM;
     364           0 :         ic->ic_opmode = IEEE80211_M_STA;
     365           0 :         ic->ic_caps = IEEE80211_C_WEP        /* wep supported */
     366             :             | IEEE80211_C_PMGT          /* power management */
     367             : #ifndef IEEE80211_STA_ONLY
     368             :             | IEEE80211_C_IBSS          /* ibss, nee adhoc, mode */
     369             :             | IEEE80211_C_HOSTAP        /* hostap mode */
     370             : #endif
     371             :             | IEEE80211_C_MONITOR       /* monitor mode */
     372             :             | IEEE80211_C_SHSLOT        /* short slot time supported */
     373             :             | IEEE80211_C_SHPREAMBLE;   /* short preamble supported */
     374           0 :         if (ath_softcrypto)
     375           0 :                 ic->ic_caps |= IEEE80211_C_RSN;      /* wpa/rsn supported */
     376             : 
     377             :         /*
     378             :          * Not all chips have the VEOL support we want to use with
     379             :          * IBSS beacon; check here for it.
     380             :          */
     381           0 :         sc->sc_veol = ath_hal_has_veol(ah);
     382             : 
     383             :         /* get mac address from hardware */
     384           0 :         ath_hal_get_lladdr(ah, ic->ic_myaddr);
     385             : 
     386           0 :         if_attach(ifp);
     387             : 
     388             :         /* call MI attach routine. */
     389           0 :         ieee80211_ifattach(ifp);
     390             : 
     391             :         /* override default methods */
     392           0 :         ic->ic_node_alloc = ath_node_alloc;
     393           0 :         sc->sc_node_free = ic->ic_node_free;
     394           0 :         ic->ic_node_free = ath_node_free;
     395           0 :         sc->sc_node_copy = ic->ic_node_copy;
     396           0 :         ic->ic_node_copy = ath_node_copy;
     397           0 :         ic->ic_node_getrssi = ath_node_getrssi;
     398           0 :         sc->sc_newstate = ic->ic_newstate;
     399           0 :         ic->ic_newstate = ath_newstate;
     400             : #ifndef IEEE80211_STA_ONLY
     401           0 :         sc->sc_recv_mgmt = ic->ic_recv_mgmt;
     402           0 :         ic->ic_recv_mgmt = ath_recv_mgmt;
     403             : #endif
     404           0 :         ic->ic_max_rssi = AR5K_MAX_RSSI;
     405           0 :         bcopy(etherbroadcastaddr, sc->sc_broadcast_addr, IEEE80211_ADDR_LEN);
     406             : 
     407             :         /* complete initialization */
     408           0 :         ieee80211_media_init(ifp, ath_media_change, ieee80211_media_status);
     409             : 
     410             : #if NBPFILTER > 0
     411           0 :         bpfattach(&sc->sc_drvbpf, ifp, DLT_IEEE802_11_RADIO,
     412             :             sizeof(struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN);
     413             : 
     414           0 :         sc->sc_rxtap_len = sizeof(sc->sc_rxtapu);
     415           0 :         bzero(&sc->sc_rxtapu, sc->sc_rxtap_len);
     416           0 :         sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
     417           0 :         sc->sc_rxtap.wr_ihdr.it_present = htole32(ATH_RX_RADIOTAP_PRESENT);
     418             : 
     419           0 :         sc->sc_txtap_len = sizeof(sc->sc_txtapu);
     420           0 :         bzero(&sc->sc_txtapu, sc->sc_txtap_len);
     421           0 :         sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
     422           0 :         sc->sc_txtap.wt_ihdr.it_present = htole32(ATH_TX_RADIOTAP_PRESENT);
     423             : #endif
     424             : 
     425           0 :         sc->sc_flags |= ATH_ATTACHED;
     426             : 
     427             :         /*
     428             :          * Print regulation domain and the mac address. The regulation domain
     429             :          * will be marked with a * if the EEPROM value has been overwritten.
     430             :          */
     431           0 :         printf(", %s%s, address %s\n",
     432           0 :             ieee80211_regdomain2name(ah->ah_regdomain),
     433           0 :             ah->ah_regdomain != ah->ah_regdomain_hw ? "*" : "",
     434           0 :             ether_sprintf(ic->ic_myaddr));
     435             : 
     436           0 :         if (ath_gpio_attach(sc, devid) == 0)
     437           0 :                 sc->sc_flags |= ATH_GPIO;
     438             : 
     439           0 :         return 0;
     440             : bad2:
     441           0 :         ath_desc_free(sc);
     442             : bad:
     443           0 :         if (ah)
     444           0 :                 ath_hal_detach(ah);
     445           0 :         sc->sc_invalid = 1;
     446           0 :         return error;
     447           0 : }
     448             : 
     449             : int
     450           0 : ath_detach(struct ath_softc *sc, int flags)
     451             : {
     452           0 :         struct ifnet *ifp = &sc->sc_ic.ic_if;
     453             :         int s;
     454             : 
     455           0 :         if ((sc->sc_flags & ATH_ATTACHED) == 0)
     456           0 :                 return (0);
     457             : 
     458           0 :         config_detach_children(&sc->sc_dev, flags);
     459             : 
     460             :         DPRINTF(ATH_DEBUG_ANY, ("%s: if_flags %x\n", __func__, ifp->if_flags));
     461             : 
     462           0 :         timeout_del(&sc->sc_scan_to);
     463           0 :         timeout_del(&sc->sc_cal_to);
     464           0 :         timeout_del(&sc->sc_rssadapt_to);
     465             : 
     466           0 :         s = splnet();
     467           0 :         ath_stop(ifp);
     468           0 :         ath_desc_free(sc);
     469           0 :         ath_hal_detach(sc->sc_ah);
     470             : 
     471           0 :         ieee80211_ifdetach(ifp);
     472           0 :         if_detach(ifp);
     473             : 
     474           0 :         splx(s);
     475             : #ifdef __FreeBSD__
     476             :         ATH_TXBUF_LOCK_DESTROY(sc);
     477             :         ATH_TXQ_LOCK_DESTROY(sc);
     478             : #endif
     479             : 
     480           0 :         return 0;
     481           0 : }
     482             : 
     483             : int
     484           0 : ath_intr(void *arg)
     485             : {
     486           0 :         return ath_intr1((struct ath_softc *)arg);
     487             : }
     488             : 
     489             : int
     490           0 : ath_intr1(struct ath_softc *sc)
     491             : {
     492           0 :         struct ieee80211com *ic = &sc->sc_ic;
     493           0 :         struct ifnet *ifp = &ic->ic_if;
     494           0 :         struct ath_hal *ah = sc->sc_ah;
     495           0 :         HAL_INT status;
     496             : 
     497           0 :         if (sc->sc_invalid) {
     498             :                 /*
     499             :                  * The hardware is not ready/present, don't touch anything.
     500             :                  * Note this can happen early on if the IRQ is shared.
     501             :                  */
     502             :                 DPRINTF(ATH_DEBUG_ANY, ("%s: invalid; ignored\n", __func__));
     503           0 :                 return 0;
     504             :         }
     505           0 :         if (!ath_hal_is_intr_pending(ah))               /* shared irq, not for us */
     506           0 :                 return 0;
     507           0 :         if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) != (IFF_RUNNING|IFF_UP)) {
     508             :                 DPRINTF(ATH_DEBUG_ANY, ("%s: if_flags 0x%x\n",
     509             :                     __func__, ifp->if_flags));
     510             :                 ath_hal_get_isr(ah, &status);       /* clear ISR */
     511           0 :                 ath_hal_set_intr(ah, 0);                /* disable further intr's */
     512           0 :                 return 1; /* XXX */
     513             :         }
     514             :         ath_hal_get_isr(ah, &status);               /* NB: clears ISR too */
     515             :         DPRINTF(ATH_DEBUG_INTR, ("%s: status 0x%x\n", __func__, status));
     516           0 :         status &= sc->sc_imask;                  /* discard unasked for bits */
     517           0 :         if (status & HAL_INT_FATAL) {
     518           0 :                 sc->sc_stats.ast_hardware++;
     519           0 :                 ath_hal_set_intr(ah, 0);                /* disable intr's until reset */
     520           0 :                 ATH_TASK_RUN_OR_ENQUEUE(&sc->sc_fataltask);
     521           0 :         } else if (status & HAL_INT_RXORN) {
     522           0 :                 sc->sc_stats.ast_rxorn++;
     523           0 :                 ath_hal_set_intr(ah, 0);                /* disable intr's until reset */
     524           0 :                 ATH_TASK_RUN_OR_ENQUEUE(&sc->sc_rxorntask);
     525           0 :         } else if (status & HAL_INT_MIB) {
     526             :                 DPRINTF(ATH_DEBUG_INTR,
     527             :                     ("%s: resetting MIB counters\n", __func__));
     528           0 :                 sc->sc_stats.ast_mib++;
     529           0 :                 ath_hal_update_mib_counters(ah, &sc->sc_mib_stats);
     530           0 :         } else {
     531           0 :                 if (status & HAL_INT_RXEOL) {
     532             :                         /*
     533             :                          * NB: the hardware should re-read the link when
     534             :                          *     RXE bit is written, but it doesn't work at
     535             :                          *     least on older hardware revs.
     536             :                          */
     537           0 :                         sc->sc_stats.ast_rxeol++;
     538           0 :                         sc->sc_rxlink = NULL;
     539           0 :                 }
     540           0 :                 if (status & HAL_INT_TXURN) {
     541           0 :                         sc->sc_stats.ast_txurn++;
     542             :                         /* bump tx trigger level */
     543           0 :                         ath_hal_update_tx_triglevel(ah, AH_TRUE);
     544           0 :                 }
     545           0 :                 if (status & HAL_INT_RX)
     546           0 :                         ATH_TASK_RUN_OR_ENQUEUE(&sc->sc_rxtask);
     547           0 :                 if (status & HAL_INT_TX)
     548           0 :                         ATH_TASK_RUN_OR_ENQUEUE(&sc->sc_txtask);
     549           0 :                 if (status & HAL_INT_SWBA)
     550           0 :                         ATH_TASK_RUN_OR_ENQUEUE(&sc->sc_swbatask);
     551           0 :                 if (status & HAL_INT_BMISS) {
     552           0 :                         sc->sc_stats.ast_bmiss++;
     553           0 :                         ATH_TASK_RUN_OR_ENQUEUE(&sc->sc_bmisstask);
     554           0 :                 }
     555             :         }
     556           0 :         return 1;
     557           0 : }
     558             : 
     559             : void
     560           0 : ath_fatal_proc(void *arg, int pending)
     561             : {
     562           0 :         struct ath_softc *sc = arg;
     563           0 :         struct ieee80211com *ic = &sc->sc_ic;
     564           0 :         struct ifnet *ifp = &ic->ic_if;
     565             : 
     566           0 :         if (ifp->if_flags & IFF_DEBUG)
     567           0 :                 printf("%s: hardware error; resetting\n", ifp->if_xname);
     568           0 :         ath_reset(sc, 1);
     569           0 : }
     570             : 
     571             : void
     572           0 : ath_rxorn_proc(void *arg, int pending)
     573             : {
     574           0 :         struct ath_softc *sc = arg;
     575           0 :         struct ieee80211com *ic = &sc->sc_ic;
     576           0 :         struct ifnet *ifp = &ic->ic_if;
     577             : 
     578           0 :         if (ifp->if_flags & IFF_DEBUG)
     579           0 :                 printf("%s: rx FIFO overrun; resetting\n", ifp->if_xname);
     580           0 :         ath_reset(sc, 1);
     581           0 : }
     582             : 
     583             : void
     584           0 : ath_bmiss_proc(void *arg, int pending)
     585             : {
     586           0 :         struct ath_softc *sc = arg;
     587           0 :         struct ieee80211com *ic = &sc->sc_ic;
     588             : 
     589             :         DPRINTF(ATH_DEBUG_ANY, ("%s: pending %u\n", __func__, pending));
     590           0 :         if (ic->ic_opmode != IEEE80211_M_STA)
     591           0 :                 return;
     592           0 :         if (ic->ic_state == IEEE80211_S_RUN) {
     593             :                 /*
     594             :                  * Rather than go directly to scan state, try to
     595             :                  * reassociate first.  If that fails then the state
     596             :                  * machine will drop us into scanning after timing
     597             :                  * out waiting for a probe response.
     598             :                  */
     599           0 :                 ieee80211_new_state(ic, IEEE80211_S_ASSOC, -1);
     600           0 :         }
     601           0 : }
     602             : 
     603             : int
     604           0 : ath_init(struct ifnet *ifp)
     605             : {
     606           0 :         return ath_init1((struct ath_softc *)ifp->if_softc);
     607             : }
     608             : 
     609             : int
     610           0 : ath_init1(struct ath_softc *sc)
     611             : {
     612           0 :         struct ieee80211com *ic = &sc->sc_ic;
     613           0 :         struct ifnet *ifp = &ic->ic_if;
     614             :         struct ieee80211_node *ni;
     615             :         enum ieee80211_phymode mode;
     616           0 :         struct ath_hal *ah = sc->sc_ah;
     617           0 :         HAL_STATUS status;
     618           0 :         HAL_CHANNEL hchan;
     619             :         int error = 0, s;
     620             : 
     621             :         DPRINTF(ATH_DEBUG_ANY, ("%s: if_flags 0x%x\n",
     622             :             __func__, ifp->if_flags));
     623             : 
     624           0 :         if ((error = ath_enable(sc)) != 0)
     625           0 :                 return error;
     626             : 
     627           0 :         s = splnet();
     628             :         /*
     629             :          * Stop anything previously setup.  This is safe
     630             :          * whether this is the first time through or not.
     631             :          */
     632           0 :         ath_stop(ifp);
     633             : 
     634             :         /*
     635             :          * Reset the link layer address to the latest value.
     636             :          */
     637           0 :         IEEE80211_ADDR_COPY(ic->ic_myaddr, LLADDR(ifp->if_sadl));
     638           0 :         ath_hal_set_lladdr(ah, ic->ic_myaddr);
     639             : 
     640             :         /*
     641             :          * The basic interface to setting the hardware in a good
     642             :          * state is ``reset''.  On return the hardware is known to
     643             :          * be powered up and with interrupts disabled.  This must
     644             :          * be followed by initialization of the appropriate bits
     645             :          * and then setup of the interrupt mask.
     646             :          */
     647           0 :         hchan.channel = ic->ic_ibss_chan->ic_freq;
     648           0 :         hchan.channelFlags = ic->ic_ibss_chan->ic_flags;
     649           0 :         if (!ath_hal_reset(ah, ic->ic_opmode, &hchan, AH_TRUE, &status)) {
     650           0 :                 printf("%s: unable to reset hardware; hal status %u\n",
     651           0 :                         ifp->if_xname, status);
     652             :                 error = EIO;
     653           0 :                 goto done;
     654             :         }
     655           0 :         ath_set_slot_time(sc);
     656             : 
     657           0 :         if ((error = ath_initkeytable(sc)) != 0) {
     658           0 :                 printf("%s: unable to reset the key cache\n",
     659           0 :                     ifp->if_xname);
     660           0 :                 goto done;
     661             :         }
     662             : 
     663           0 :         if ((error = ath_startrecv(sc)) != 0) {
     664           0 :                 printf("%s: unable to start recv logic\n", ifp->if_xname);
     665           0 :                 goto done;
     666             :         }
     667             : 
     668             :         /*
     669             :          * Enable interrupts.
     670             :          */
     671           0 :         sc->sc_imask = HAL_INT_RX | HAL_INT_TX
     672             :             | HAL_INT_RXEOL | HAL_INT_RXORN
     673             :             | HAL_INT_FATAL | HAL_INT_GLOBAL;
     674             : #ifndef IEEE80211_STA_ONLY
     675           0 :         if (ic->ic_opmode == IEEE80211_M_HOSTAP)
     676           0 :                 sc->sc_imask |= HAL_INT_MIB;
     677             : #endif
     678           0 :         ath_hal_set_intr(ah, sc->sc_imask);
     679             : 
     680           0 :         ifp->if_flags |= IFF_RUNNING;
     681           0 :         ic->ic_state = IEEE80211_S_INIT;
     682             : 
     683             :         /*
     684             :          * The hardware should be ready to go now so it's safe
     685             :          * to kick the 802.11 state machine as it's likely to
     686             :          * immediately call back to us to send mgmt frames.
     687             :          */
     688           0 :         ni = ic->ic_bss;
     689           0 :         ni->ni_chan = ic->ic_ibss_chan;
     690           0 :         mode = ieee80211_chan2mode(ic, ni->ni_chan);
     691           0 :         if (mode != sc->sc_curmode)
     692           0 :                 ath_setcurmode(sc, mode);
     693           0 :         if (ic->ic_opmode != IEEE80211_M_MONITOR) {
     694           0 :                 ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
     695           0 :         } else {
     696           0 :                 ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
     697             :         }
     698             : done:
     699           0 :         splx(s);
     700           0 :         return error;
     701           0 : }
     702             : 
     703             : void
     704           0 : ath_stop(struct ifnet *ifp)
     705             : {
     706           0 :         struct ieee80211com *ic = (struct ieee80211com *) ifp;
     707           0 :         struct ath_softc *sc = ifp->if_softc;
     708           0 :         struct ath_hal *ah = sc->sc_ah;
     709             :         int s;
     710             : 
     711             :         DPRINTF(ATH_DEBUG_ANY, ("%s: invalid %u if_flags 0x%x\n",
     712             :             __func__, sc->sc_invalid, ifp->if_flags));
     713             : 
     714           0 :         s = splnet();
     715           0 :         if (ifp->if_flags & IFF_RUNNING) {
     716             :                 /*
     717             :                  * Shutdown the hardware and driver:
     718             :                  *    disable interrupts
     719             :                  *    turn off timers
     720             :                  *    clear transmit machinery
     721             :                  *    clear receive machinery
     722             :                  *    drain and release tx queues
     723             :                  *    reclaim beacon resources
     724             :                  *    reset 802.11 state machine
     725             :                  *    power down hardware
     726             :                  *
     727             :                  * Note that some of this work is not possible if the
     728             :                  * hardware is gone (invalid).
     729             :                  */
     730           0 :                 ifp->if_flags &= ~IFF_RUNNING;
     731           0 :                 ifp->if_timer = 0;
     732           0 :                 if (!sc->sc_invalid)
     733           0 :                         ath_hal_set_intr(ah, 0);
     734           0 :                 ath_draintxq(sc);
     735           0 :                 if (!sc->sc_invalid) {
     736           0 :                         ath_stoprecv(sc);
     737           0 :                 } else {
     738           0 :                         sc->sc_rxlink = NULL;
     739             :                 }
     740           0 :                 IFQ_PURGE(&ifp->if_snd);
     741             : #ifndef IEEE80211_STA_ONLY
     742           0 :                 ath_beacon_free(sc);
     743             : #endif
     744           0 :                 ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
     745           0 :                 if (!sc->sc_invalid) {
     746           0 :                         ath_hal_set_power(ah, HAL_PM_FULL_SLEEP, 0);
     747           0 :                 }
     748           0 :                 ath_disable(sc);
     749           0 :         }
     750           0 :         splx(s);
     751           0 : }
     752             : 
     753             : /*
     754             :  * Reset the hardware w/o losing operational state.  This is
     755             :  * basically a more efficient way of doing ath_stop, ath_init,
     756             :  * followed by state transitions to the current 802.11
     757             :  * operational state.  Used to recover from errors rx overrun
     758             :  * and to reset the hardware when rf gain settings must be reset.
     759             :  */
     760             : void
     761           0 : ath_reset(struct ath_softc *sc, int full)
     762             : {
     763           0 :         struct ieee80211com *ic = &sc->sc_ic;
     764           0 :         struct ifnet *ifp = &ic->ic_if;
     765           0 :         struct ath_hal *ah = sc->sc_ah;
     766             :         struct ieee80211_channel *c;
     767           0 :         HAL_STATUS status;
     768           0 :         HAL_CHANNEL hchan;
     769             : 
     770             :         /*
     771             :          * Convert to a HAL channel description.
     772             :          */
     773           0 :         c = ic->ic_ibss_chan;
     774           0 :         hchan.channel = c->ic_freq;
     775           0 :         hchan.channelFlags = c->ic_flags;
     776             : 
     777           0 :         ath_hal_set_intr(ah, 0);                /* disable interrupts */
     778           0 :         ath_draintxq(sc);               /* stop xmit side */
     779           0 :         ath_stoprecv(sc);               /* stop recv side */
     780             :         /* NB: indicate channel change so we do a full reset */
     781           0 :         if (!ath_hal_reset(ah, ic->ic_opmode, &hchan,
     782             :             full ? AH_TRUE : AH_FALSE, &status)) {
     783           0 :                 printf("%s: %s: unable to reset hardware; hal status %u\n",
     784           0 :                         ifp->if_xname, __func__, status);
     785           0 :         }
     786           0 :         ath_set_slot_time(sc);
     787             :         /* In case channel changed, save as a node channel */
     788           0 :         ic->ic_bss->ni_chan = ic->ic_ibss_chan;
     789           0 :         ath_hal_set_intr(ah, sc->sc_imask);
     790           0 :         if (ath_startrecv(sc) != 0)     /* restart recv */
     791           0 :                 printf("%s: %s: unable to start recv logic\n", ifp->if_xname,
     792             :                     __func__);
     793           0 :         ath_start(ifp);                 /* restart xmit */
     794           0 :         if (ic->ic_state == IEEE80211_S_RUN)
     795           0 :                 ath_beacon_config(sc);  /* restart beacons */
     796           0 : }
     797             : 
     798             : void
     799           0 : ath_start(struct ifnet *ifp)
     800             : {
     801           0 :         struct ath_softc *sc = ifp->if_softc;
     802           0 :         struct ath_hal *ah = sc->sc_ah;
     803           0 :         struct ieee80211com *ic = &sc->sc_ic;
     804           0 :         struct ieee80211_node *ni;
     805             :         struct ath_buf *bf;
     806             :         struct mbuf *m;
     807             :         struct ieee80211_frame *wh;
     808             :         int s;
     809             : 
     810           0 :         if (!(ifp->if_flags & IFF_RUNNING) || ifq_is_oactive(&ifp->if_snd) ||
     811           0 :             sc->sc_invalid)
     812           0 :                 return;
     813           0 :         for (;;) {
     814             :                 /*
     815             :                  * Grab a TX buffer and associated resources.
     816             :                  */
     817           0 :                 s = splnet();
     818           0 :                 bf = TAILQ_FIRST(&sc->sc_txbuf);
     819           0 :                 if (bf != NULL)
     820           0 :                         TAILQ_REMOVE(&sc->sc_txbuf, bf, bf_list);
     821           0 :                 splx(s);
     822           0 :                 if (bf == NULL) {
     823             :                         DPRINTF(ATH_DEBUG_ANY, ("%s: out of xmit buffers\n",
     824             :                             __func__));
     825           0 :                         sc->sc_stats.ast_tx_qstop++;
     826           0 :                         ifq_set_oactive(&ifp->if_snd);
     827           0 :                         break;
     828             :                 }
     829             :                 /*
     830             :                  * Poll the management queue for frames; they
     831             :                  * have priority over normal data frames.
     832             :                  */
     833           0 :                 m = mq_dequeue(&ic->ic_mgtq);
     834           0 :                 if (m == NULL) {
     835             :                         /*
     836             :                          * No data frames go out unless we're associated.
     837             :                          */
     838           0 :                         if (ic->ic_state != IEEE80211_S_RUN) {
     839             :                                 DPRINTF(ATH_DEBUG_ANY,
     840             :                                     ("%s: ignore data packet, state %u\n",
     841             :                                     __func__, ic->ic_state));
     842           0 :                                 sc->sc_stats.ast_tx_discard++;
     843           0 :                                 s = splnet();
     844           0 :                                 TAILQ_INSERT_TAIL(&sc->sc_txbuf, bf, bf_list);
     845           0 :                                 splx(s);
     846           0 :                                 break;
     847             :                         }
     848           0 :                         IFQ_DEQUEUE(&ifp->if_snd, m);
     849           0 :                         if (m == NULL) {
     850           0 :                                 s = splnet();
     851           0 :                                 TAILQ_INSERT_TAIL(&sc->sc_txbuf, bf, bf_list);
     852           0 :                                 splx(s);
     853           0 :                                 break;
     854             :                         }
     855             : 
     856             : #if NBPFILTER > 0
     857           0 :                         if (ifp->if_bpf)
     858           0 :                                 bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT);
     859             : #endif
     860             : 
     861             :                         /*
     862             :                          * Encapsulate the packet in prep for transmission.
     863             :                          */
     864           0 :                         m = ieee80211_encap(ifp, m, &ni);
     865           0 :                         if (m == NULL) {
     866             :                                 DPRINTF(ATH_DEBUG_ANY,
     867             :                                     ("%s: encapsulation failure\n",
     868             :                                     __func__));
     869           0 :                                 sc->sc_stats.ast_tx_encap++;
     870           0 :                                 goto bad;
     871             :                         }
     872           0 :                         wh = mtod(m, struct ieee80211_frame *);
     873           0 :                 } else {
     874           0 :                         ni = m->m_pkthdr.ph_cookie;
     875             : 
     876           0 :                         wh = mtod(m, struct ieee80211_frame *);
     877           0 :                         if ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) ==
     878             :                             IEEE80211_FC0_SUBTYPE_PROBE_RESP) {
     879             :                                 /* fill time stamp */
     880             :                                 u_int64_t tsf;
     881             :                                 u_int32_t *tstamp;
     882             : 
     883           0 :                                 tsf = ath_hal_get_tsf64(ah);
     884             :                                 /* XXX: adjust 100us delay to xmit */
     885           0 :                                 tsf += 100;
     886           0 :                                 tstamp = (u_int32_t *)&wh[1];
     887           0 :                                 tstamp[0] = htole32(tsf & 0xffffffff);
     888           0 :                                 tstamp[1] = htole32(tsf >> 32);
     889           0 :                         }
     890           0 :                         sc->sc_stats.ast_tx_mgmt++;
     891             :                 }
     892             : 
     893           0 :                 if (ath_tx_start(sc, ni, bf, m)) {
     894             :         bad:
     895           0 :                         s = splnet();
     896           0 :                         TAILQ_INSERT_TAIL(&sc->sc_txbuf, bf, bf_list);
     897           0 :                         splx(s);
     898           0 :                         ifp->if_oerrors++;
     899           0 :                         if (ni != NULL)
     900           0 :                                 ieee80211_release_node(ic, ni);
     901           0 :                         continue;
     902             :                 }
     903             : 
     904           0 :                 sc->sc_tx_timer = 5;
     905           0 :                 ifp->if_timer = 1;
     906             :         }
     907           0 : }
     908             : 
     909             : int
     910           0 : ath_media_change(struct ifnet *ifp)
     911             : {
     912             :         int error;
     913             : 
     914           0 :         error = ieee80211_media_change(ifp);
     915           0 :         if (error == ENETRESET) {
     916           0 :                 if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) ==
     917             :                     (IFF_RUNNING|IFF_UP))
     918           0 :                         ath_init(ifp);          /* XXX lose error */
     919             :                 error = 0;
     920           0 :         }
     921           0 :         return error;
     922             : }
     923             : 
     924             : void
     925           0 : ath_watchdog(struct ifnet *ifp)
     926             : {
     927           0 :         struct ath_softc *sc = ifp->if_softc;
     928             : 
     929           0 :         ifp->if_timer = 0;
     930           0 :         if ((ifp->if_flags & IFF_RUNNING) == 0 || sc->sc_invalid)
     931           0 :                 return;
     932           0 :         if (sc->sc_tx_timer) {
     933           0 :                 if (--sc->sc_tx_timer == 0) {
     934           0 :                         printf("%s: device timeout\n", ifp->if_xname);
     935           0 :                         ath_reset(sc, 1);
     936           0 :                         ifp->if_oerrors++;
     937           0 :                         sc->sc_stats.ast_watchdog++;
     938           0 :                         return;
     939             :                 }
     940           0 :                 ifp->if_timer = 1;
     941           0 :         }
     942             : 
     943           0 :         ieee80211_watchdog(ifp);
     944           0 : }
     945             : 
     946             : int
     947           0 : ath_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
     948             : {
     949           0 :         struct ath_softc *sc = ifp->if_softc;
     950           0 :         struct ieee80211com *ic = &sc->sc_ic;
     951           0 :         struct ifreq *ifr = (struct ifreq *)data;
     952             :         int error = 0, s;
     953             : 
     954           0 :         s = splnet();
     955           0 :         switch (cmd) {
     956             :         case SIOCSIFADDR:
     957           0 :                 ifp->if_flags |= IFF_UP;
     958             :                 /* FALLTHROUGH */
     959             :         case SIOCSIFFLAGS:
     960           0 :                 if (ifp->if_flags & IFF_UP) {
     961           0 :                         if (ifp->if_flags & IFF_RUNNING) {
     962             :                                 /*
     963             :                                  * To avoid rescanning another access point,
     964             :                                  * do not call ath_init() here.  Instead,
     965             :                                  * only reflect promisc mode settings.
     966             :                                  */
     967           0 :                                 ath_mode_init(sc);
     968           0 :                         } else {
     969             :                                 /*
     970             :                                  * Beware of being called during detach to
     971             :                                  * reset promiscuous mode.  In that case we
     972             :                                  * will still be marked UP but not RUNNING.
     973             :                                  * However trying to re-init the interface
     974             :                                  * is the wrong thing to do as we've already
     975             :                                  * torn down much of our state.  There's
     976             :                                  * probably a better way to deal with this.
     977             :                                  */
     978           0 :                                 if (!sc->sc_invalid)
     979           0 :                                         ath_init(ifp);  /* XXX lose error */
     980             :                         }
     981             :                 } else
     982           0 :                         ath_stop(ifp);
     983             :                 break;
     984             :         case SIOCADDMULTI:
     985             :         case SIOCDELMULTI:
     986             : #ifdef __FreeBSD__
     987             :                 /*
     988             :                  * The upper layer has already installed/removed
     989             :                  * the multicast address(es), just recalculate the
     990             :                  * multicast filter for the card.
     991             :                  */
     992             :                 if (ifp->if_flags & IFF_RUNNING)
     993             :                         ath_mode_init(sc);
     994             : #endif
     995           0 :                 error = (cmd == SIOCADDMULTI) ?
     996           0 :                     ether_addmulti(ifr, &sc->sc_ic.ic_ac) :
     997           0 :                     ether_delmulti(ifr, &sc->sc_ic.ic_ac);
     998           0 :                 if (error == ENETRESET) {
     999           0 :                         if (ifp->if_flags & IFF_RUNNING)
    1000           0 :                                 ath_mode_init(sc);
    1001             :                         error = 0;
    1002           0 :                 }
    1003             :                 break;
    1004             :         case SIOCGATHSTATS:
    1005           0 :                 error = copyout(&sc->sc_stats,
    1006           0 :                     ifr->ifr_data, sizeof (sc->sc_stats));
    1007           0 :                 break;
    1008             :         default:
    1009           0 :                 error = ieee80211_ioctl(ifp, cmd, data);
    1010           0 :                 if (error == ENETRESET) {
    1011           0 :                         if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) ==
    1012             :                             (IFF_RUNNING|IFF_UP)) {
    1013           0 :                                 if (ic->ic_opmode != IEEE80211_M_MONITOR)
    1014           0 :                                         ath_init(ifp);  /* XXX lose error */
    1015             :                                 else
    1016           0 :                                         ath_reset(sc, 1);
    1017             :                         }
    1018             :                         error = 0;
    1019           0 :                 }
    1020             :                 break;
    1021             :         }
    1022           0 :         splx(s);
    1023           0 :         return error;
    1024             : }
    1025             : 
    1026             : /*
    1027             :  * Fill the hardware key cache with key entries.
    1028             :  */
    1029             : int
    1030           0 : ath_initkeytable(struct ath_softc *sc)
    1031             : {
    1032           0 :         struct ieee80211com *ic = &sc->sc_ic;
    1033           0 :         struct ath_hal *ah = sc->sc_ah;
    1034             :         int i;
    1035             : 
    1036           0 :         if (ath_softcrypto) {
    1037             :                 /*
    1038             :                  * Disable the hardware crypto engine and reset the key cache
    1039             :                  * to allow software crypto operation for WEP/RSN/WPA2
    1040             :                  */
    1041           0 :                 if (ic->ic_flags & (IEEE80211_F_WEPON|IEEE80211_F_RSNON))
    1042           0 :                         (void)ath_hal_softcrypto(ah, AH_TRUE);
    1043             :                 else
    1044           0 :                         (void)ath_hal_softcrypto(ah, AH_FALSE);
    1045           0 :                 return (0);
    1046             :         }
    1047             : 
    1048             :         /* WEP is disabled, we only support WEP in hardware yet */
    1049           0 :         if ((ic->ic_flags & IEEE80211_F_WEPON) == 0)
    1050           0 :                 return (0);
    1051             : 
    1052             :         /*
    1053             :          * Setup the hardware after reset: the key cache is filled as
    1054             :          * needed and the receive engine is set going.  Frame transmit
    1055             :          * is handled entirely in the frame output path; there's nothing
    1056             :          * to do here except setup the interrupt mask.
    1057             :          */
    1058             : 
    1059             :         /* XXX maybe should reset all keys when !WEPON */
    1060           0 :         for (i = 0; i < IEEE80211_WEP_NKID; i++) {
    1061           0 :                 struct ieee80211_key *k = &ic->ic_nw_keys[i];
    1062           0 :                 if (k->k_len == 0)
    1063           0 :                         ath_hal_reset_key(ah, i);
    1064             :                 else {
    1065           0 :                         HAL_KEYVAL hk;
    1066             : 
    1067           0 :                         bzero(&hk, sizeof(hk));
    1068             :                         /*
    1069             :                          * Pad the key to a supported key length. It
    1070             :                          * is always a good idea to use full-length
    1071             :                          * keys without padded zeros but this seems
    1072             :                          * to be the default behaviour used by many
    1073             :                          * implementations.
    1074             :                          */
    1075           0 :                         if (k->k_cipher == IEEE80211_CIPHER_WEP40)
    1076           0 :                                 hk.wk_len = AR5K_KEYVAL_LENGTH_40;
    1077           0 :                         else if (k->k_cipher == IEEE80211_CIPHER_WEP104)
    1078           0 :                                 hk.wk_len = AR5K_KEYVAL_LENGTH_104;
    1079             :                         else
    1080           0 :                                 return (EINVAL);
    1081           0 :                         bcopy(k->k_key, hk.wk_key, hk.wk_len);
    1082             : 
    1083           0 :                         if (ath_hal_set_key(ah, i, &hk) != AH_TRUE)
    1084           0 :                                 return (EINVAL);
    1085           0 :                 }
    1086           0 :         }
    1087             : 
    1088           0 :         return (0);
    1089           0 : }
    1090             : 
    1091             : void
    1092           0 : ath_mcastfilter_accum(caddr_t dl, u_int32_t (*mfilt)[2])
    1093             : {
    1094             :         u_int32_t val;
    1095             :         u_int8_t pos;
    1096             : 
    1097           0 :         val = LE_READ_4(dl + 0);
    1098           0 :         pos = (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val;
    1099           0 :         val = LE_READ_4(dl + 3);
    1100           0 :         pos ^= (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val;
    1101           0 :         pos &= 0x3f;
    1102           0 :         (*mfilt)[pos / 32] |= (1 << (pos % 32));
    1103           0 : }
    1104             : 
    1105             : void
    1106           0 : ath_mcastfilter_compute(struct ath_softc *sc, u_int32_t (*mfilt)[2])
    1107             : {
    1108           0 :         struct arpcom *ac = &sc->sc_ic.ic_ac;
    1109           0 :         struct ifnet *ifp = &sc->sc_ic.ic_if;
    1110             :         struct ether_multi *enm;
    1111             :         struct ether_multistep estep;
    1112             : 
    1113           0 :         if (ac->ac_multirangecnt > 0) {
    1114             :                 /* XXX Punt on ranges. */
    1115           0 :                 (*mfilt)[0] = (*mfilt)[1] = ~((u_int32_t)0);
    1116           0 :                 ifp->if_flags |= IFF_ALLMULTI;
    1117           0 :                 return;
    1118             :         }
    1119             : 
    1120           0 :         ETHER_FIRST_MULTI(estep, ac, enm);
    1121           0 :         while (enm != NULL) {
    1122           0 :                 ath_mcastfilter_accum(enm->enm_addrlo, mfilt);
    1123           0 :                 ETHER_NEXT_MULTI(estep, enm);
    1124             :         }
    1125           0 :         ifp->if_flags &= ~IFF_ALLMULTI;
    1126           0 : }
    1127             : 
    1128             : /*
    1129             :  * Calculate the receive filter according to the
    1130             :  * operating mode and state:
    1131             :  *
    1132             :  * o always accept unicast, broadcast, and multicast traffic
    1133             :  * o maintain current state of phy error reception
    1134             :  * o probe request frames are accepted only when operating in
    1135             :  *   hostap, adhoc, or monitor modes
    1136             :  * o enable promiscuous mode according to the interface state
    1137             :  * o accept beacons:
    1138             :  *   - when operating in adhoc mode so the 802.11 layer creates
    1139             :  *     node table entries for peers,
    1140             :  *   - when operating in station mode for collecting rssi data when
    1141             :  *     the station is otherwise quiet, or
    1142             :  *   - when scanning
    1143             :  */
    1144             : u_int32_t
    1145           0 : ath_calcrxfilter(struct ath_softc *sc)
    1146             : {
    1147           0 :         struct ieee80211com *ic = &sc->sc_ic;
    1148           0 :         struct ath_hal *ah = sc->sc_ah;
    1149           0 :         struct ifnet *ifp = &ic->ic_if;
    1150             :         u_int32_t rfilt;
    1151             : 
    1152           0 :         rfilt = (ath_hal_get_rx_filter(ah) & HAL_RX_FILTER_PHYERR)
    1153           0 :             | HAL_RX_FILTER_UCAST | HAL_RX_FILTER_BCAST | HAL_RX_FILTER_MCAST;
    1154           0 :         if (ic->ic_opmode != IEEE80211_M_STA)
    1155           0 :                 rfilt |= HAL_RX_FILTER_PROBEREQ;
    1156             : #ifndef IEEE80211_STA_ONLY
    1157           0 :         if (ic->ic_opmode != IEEE80211_M_AHDEMO)
    1158             : #endif
    1159           0 :                 rfilt |= HAL_RX_FILTER_BEACON;
    1160           0 :         if (ifp->if_flags & IFF_PROMISC)
    1161           0 :                 rfilt |= HAL_RX_FILTER_PROM;
    1162           0 :         return rfilt;
    1163             : }
    1164             : 
    1165             : void
    1166           0 : ath_mode_init(struct ath_softc *sc)
    1167             : {
    1168           0 :         struct ath_hal *ah = sc->sc_ah;
    1169           0 :         u_int32_t rfilt, mfilt[2];
    1170             : 
    1171             :         /* configure rx filter */
    1172           0 :         rfilt = ath_calcrxfilter(sc);
    1173           0 :         ath_hal_set_rx_filter(ah, rfilt);
    1174             : 
    1175             :         /* configure operational mode */
    1176           0 :         ath_hal_set_opmode(ah);
    1177             : 
    1178             :         /* calculate and install multicast filter */
    1179           0 :         mfilt[0] = mfilt[1] = 0;
    1180           0 :         ath_mcastfilter_compute(sc, &mfilt);
    1181           0 :         ath_hal_set_mcast_filter(ah, mfilt[0], mfilt[1]);
    1182             :         DPRINTF(ATH_DEBUG_MODE, ("%s: RX filter 0x%x, MC filter %08x:%08x\n",
    1183             :             __func__, rfilt, mfilt[0], mfilt[1]));
    1184           0 : }
    1185             : 
    1186             : struct mbuf *
    1187           0 : ath_getmbuf(int flags, int type, u_int pktlen)
    1188             : {
    1189             :         struct mbuf *m;
    1190             : 
    1191           0 :         KASSERT(pktlen <= MCLBYTES, ("802.11 packet too large: %u", pktlen));
    1192             : #ifdef __FreeBSD__
    1193             :         if (pktlen <= MHLEN) {
    1194             :                 MGETHDR(m, flags, type);
    1195             :         } else {
    1196             :                 m = m_getcl(flags, type, M_PKTHDR);
    1197             :         }
    1198             : #else
    1199           0 :         MGETHDR(m, flags, type);
    1200           0 :         if (m != NULL && pktlen > MHLEN) {
    1201           0 :                 MCLGET(m, flags);
    1202           0 :                 if ((m->m_flags & M_EXT) == 0) {
    1203           0 :                         m_free(m);
    1204             :                         m = NULL;
    1205           0 :                 }
    1206             :         }
    1207             : #endif
    1208           0 :         return m;
    1209             : }
    1210             : 
    1211             : #ifndef IEEE80211_STA_ONLY
    1212             : int
    1213           0 : ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_node *ni)
    1214             : {
    1215           0 :         struct ieee80211com *ic = &sc->sc_ic;
    1216           0 :         struct ath_hal *ah = sc->sc_ah;
    1217             :         struct ath_buf *bf;
    1218             :         struct ath_desc *ds;
    1219             :         struct mbuf *m;
    1220             :         int error;
    1221             :         u_int8_t rate;
    1222             :         const HAL_RATE_TABLE *rt;
    1223             :         u_int flags = 0;
    1224             : 
    1225           0 :         bf = sc->sc_bcbuf;
    1226           0 :         if (bf->bf_m != NULL) {
    1227           0 :                 bus_dmamap_unload(sc->sc_dmat, bf->bf_dmamap);
    1228           0 :                 m_freem(bf->bf_m);
    1229           0 :                 bf->bf_m = NULL;
    1230           0 :                 bf->bf_node = NULL;
    1231           0 :         }
    1232             :         /*
    1233             :          * NB: the beacon data buffer must be 32-bit aligned;
    1234             :          * we assume the mbuf routines will return us something
    1235             :          * with this alignment (perhaps should assert).
    1236             :          */
    1237           0 :         m = ieee80211_beacon_alloc(ic, ni);
    1238           0 :         if (m == NULL) {
    1239             :                 DPRINTF(ATH_DEBUG_BEACON, ("%s: cannot get mbuf/cluster\n",
    1240             :                     __func__));
    1241           0 :                 sc->sc_stats.ast_be_nombuf++;
    1242           0 :                 return ENOMEM;
    1243             :         }
    1244             : 
    1245             :         DPRINTF(ATH_DEBUG_BEACON, ("%s: m %p len %u\n", __func__, m, m->m_len));
    1246           0 :         error = bus_dmamap_load_mbuf(sc->sc_dmat, bf->bf_dmamap, m,
    1247             :             BUS_DMA_NOWAIT);
    1248           0 :         if (error != 0) {
    1249           0 :                 m_freem(m);
    1250           0 :                 return error;
    1251             :         }
    1252           0 :         KASSERT(bf->bf_nseg == 1,
    1253             :                 ("%s: multi-segment packet; nseg %u", __func__, bf->bf_nseg));
    1254           0 :         bf->bf_m = m;
    1255             : 
    1256             :         /* setup descriptors */
    1257           0 :         ds = bf->bf_desc;
    1258           0 :         bzero(ds, sizeof(struct ath_desc));
    1259             : 
    1260           0 :         if (ic->ic_opmode == IEEE80211_M_IBSS && sc->sc_veol) {
    1261           0 :                 ds->ds_link = bf->bf_daddr;       /* link to self */
    1262             :                 flags |= HAL_TXDESC_VEOL;
    1263           0 :         } else {
    1264           0 :                 ds->ds_link = 0;
    1265             :         }
    1266           0 :         ds->ds_data = bf->bf_segs[0].ds_addr;
    1267             : 
    1268             :         DPRINTF(ATH_DEBUG_ANY, ("%s: segaddr %p seglen %u\n", __func__,
    1269             :             (caddr_t)bf->bf_segs[0].ds_addr, (u_int)bf->bf_segs[0].ds_len));
    1270             : 
    1271             :         /*
    1272             :          * Calculate rate code.
    1273             :          * XXX everything at min xmit rate
    1274             :          */
    1275           0 :         rt = sc->sc_currates;
    1276           0 :         KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode));
    1277           0 :         if (ic->ic_flags & IEEE80211_F_SHPREAMBLE) {
    1278           0 :                 rate = rt->info[0].rateCode | rt->info[0].shortPreamble;
    1279           0 :         } else {
    1280             :                 rate = rt->info[0].rateCode;
    1281             :         }
    1282             : 
    1283             :         flags = HAL_TXDESC_NOACK;
    1284           0 :         if (ic->ic_opmode == IEEE80211_M_IBSS)
    1285           0 :                 flags |= HAL_TXDESC_VEOL;
    1286             : 
    1287           0 :         if (!ath_hal_setup_tx_desc(ah, ds
    1288             :                 , m->m_pkthdr.len + IEEE80211_CRC_LEN        /* packet length */
    1289             :                 , sizeof(struct ieee80211_frame)        /* header length */
    1290             :                 , HAL_PKT_TYPE_BEACON           /* Atheros packet type */
    1291             :                 , 60                            /* txpower XXX */
    1292             :                 , rate, 1                       /* series 0 rate/tries */
    1293             :                 , HAL_TXKEYIX_INVALID           /* no encryption */
    1294             :                 , 0                             /* antenna mode */
    1295             :                 , flags                         /* no ack for beacons */
    1296             :                 , 0                             /* rts/cts rate */
    1297             :                 , 0                             /* rts/cts duration */
    1298             :         )) {
    1299           0 :                 printf("%s: ath_hal_setup_tx_desc failed\n", __func__);
    1300           0 :                 return -1;
    1301             :         }
    1302             :         /* NB: beacon's BufLen must be a multiple of 4 bytes */
    1303             :         /* XXX verify mbuf data area covers this roundup */
    1304           0 :         if (!ath_hal_fill_tx_desc(ah, ds
    1305             :                 , roundup(bf->bf_segs[0].ds_len, 4)  /* buffer length */
    1306             :                 , AH_TRUE                               /* first segment */
    1307             :                 , AH_TRUE                               /* last segment */
    1308             :         )) {
    1309           0 :                 printf("%s: ath_hal_fill_tx_desc failed\n", __func__);
    1310           0 :                 return -1;
    1311             :         }
    1312             : 
    1313             :         /* XXX it is not appropriate to bus_dmamap_sync? -dcy */
    1314             : 
    1315           0 :         return 0;
    1316           0 : }
    1317             : 
    1318             : void
    1319           0 : ath_beacon_proc(void *arg, int pending)
    1320             : {
    1321           0 :         struct ath_softc *sc = arg;
    1322           0 :         struct ieee80211com *ic = &sc->sc_ic;
    1323           0 :         struct ath_buf *bf = sc->sc_bcbuf;
    1324           0 :         struct ath_hal *ah = sc->sc_ah;
    1325             : 
    1326             :         DPRINTF(ATH_DEBUG_BEACON_PROC, ("%s: pending %u\n", __func__, pending));
    1327           0 :         if (ic->ic_opmode == IEEE80211_M_STA ||
    1328           0 :             bf == NULL || bf->bf_m == NULL) {
    1329             :                 DPRINTF(ATH_DEBUG_ANY, ("%s: ic_flags=%x bf=%p bf_m=%p\n",
    1330             :                     __func__, ic->ic_flags, bf, bf ? bf->bf_m : NULL));
    1331           0 :                 return;
    1332             :         }
    1333             :         /* TODO: update beacon to reflect PS poll state */
    1334           0 :         if (!ath_hal_stop_tx_dma(ah, sc->sc_bhalq)) {
    1335             :                 DPRINTF(ATH_DEBUG_ANY, ("%s: beacon queue %u did not stop?\n",
    1336             :                     __func__, sc->sc_bhalq));
    1337             :         }
    1338           0 :         bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap, 0,
    1339             :             bf->bf_dmamap->dm_mapsize, BUS_DMASYNC_PREWRITE);
    1340             : 
    1341           0 :         ath_hal_put_tx_buf(ah, sc->sc_bhalq, bf->bf_daddr);
    1342           0 :         ath_hal_tx_start(ah, sc->sc_bhalq);
    1343             :         DPRINTF(ATH_DEBUG_BEACON_PROC,
    1344             :             ("%s: TXDP%u = %p (%p)\n", __func__,
    1345             :             sc->sc_bhalq, (caddr_t)bf->bf_daddr, bf->bf_desc));
    1346           0 : }
    1347             : 
    1348             : void
    1349           0 : ath_beacon_free(struct ath_softc *sc)
    1350             : {
    1351           0 :         struct ath_buf *bf = sc->sc_bcbuf;
    1352             : 
    1353           0 :         if (bf->bf_m != NULL) {
    1354           0 :                 bus_dmamap_unload(sc->sc_dmat, bf->bf_dmamap);
    1355           0 :                 m_freem(bf->bf_m);
    1356           0 :                 bf->bf_m = NULL;
    1357           0 :                 bf->bf_node = NULL;
    1358           0 :         }
    1359           0 : }
    1360             : #endif  /* IEEE80211_STA_ONLY */
    1361             : 
    1362             : /*
    1363             :  * Configure the beacon and sleep timers.
    1364             :  *
    1365             :  * When operating as an AP this resets the TSF and sets
    1366             :  * up the hardware to notify us when we need to issue beacons.
    1367             :  *
    1368             :  * When operating in station mode this sets up the beacon
    1369             :  * timers according to the timestamp of the last received
    1370             :  * beacon and the current TSF, configures PCF and DTIM
    1371             :  * handling, programs the sleep registers so the hardware
    1372             :  * will wakeup in time to receive beacons, and configures
    1373             :  * the beacon miss handling so we'll receive a BMISS
    1374             :  * interrupt when we stop seeing beacons from the AP
    1375             :  * we've associated with.
    1376             :  */
    1377             : void
    1378           0 : ath_beacon_config(struct ath_softc *sc)
    1379             : {
    1380             : #define MS_TO_TU(x)     (((x) * 1000) / 1024)
    1381           0 :         struct ath_hal *ah = sc->sc_ah;
    1382           0 :         struct ieee80211com *ic = &sc->sc_ic;
    1383           0 :         struct ieee80211_node *ni = ic->ic_bss;
    1384             :         u_int32_t nexttbtt, intval;
    1385             : 
    1386           0 :         nexttbtt = (LE_READ_4(ni->ni_tstamp + 4) << 22) |
    1387           0 :             (LE_READ_4(ni->ni_tstamp) >> 10);
    1388           0 :         intval = MAX(1, ni->ni_intval) & HAL_BEACON_PERIOD;
    1389           0 :         if (nexttbtt == 0) {    /* e.g. for ap mode */
    1390             :                 nexttbtt = intval;
    1391           0 :         } else if (intval) {
    1392           0 :                 nexttbtt = roundup(nexttbtt, intval);
    1393           0 :         }
    1394             :         DPRINTF(ATH_DEBUG_BEACON, ("%s: intval %u nexttbtt %u\n",
    1395             :             __func__, ni->ni_intval, nexttbtt));
    1396           0 :         if (ic->ic_opmode == IEEE80211_M_STA) {
    1397           0 :                 HAL_BEACON_STATE bs;
    1398             : 
    1399             :                 /* NB: no PCF support right now */
    1400           0 :                 bzero(&bs, sizeof(bs));
    1401           0 :                 bs.bs_intval = intval;
    1402           0 :                 bs.bs_nexttbtt = nexttbtt;
    1403           0 :                 bs.bs_dtimperiod = bs.bs_intval;
    1404           0 :                 bs.bs_nextdtim = nexttbtt;
    1405             :                 /*
    1406             :                  * Calculate the number of consecutive beacons to miss
    1407             :                  * before taking a BMISS interrupt. 
    1408             :                  * Note that we clamp the result to at most 7 beacons.
    1409             :                  */
    1410           0 :                 bs.bs_bmissthreshold = ic->ic_bmissthres;
    1411           0 :                 if (bs.bs_bmissthreshold > 7) {
    1412           0 :                         bs.bs_bmissthreshold = 7;
    1413           0 :                 } else if (bs.bs_bmissthreshold <= 0) {
    1414           0 :                         bs.bs_bmissthreshold = 1;
    1415           0 :                 }
    1416             : 
    1417             :                 /*
    1418             :                  * Calculate sleep duration.  The configuration is
    1419             :                  * given in ms.  We insure a multiple of the beacon
    1420             :                  * period is used.  Also, if the sleep duration is
    1421             :                  * greater than the DTIM period then it makes senses
    1422             :                  * to make it a multiple of that.
    1423             :                  *
    1424             :                  * XXX fixed at 100ms
    1425             :                  */
    1426           0 :                 bs.bs_sleepduration =
    1427           0 :                         roundup(MS_TO_TU(100), bs.bs_intval);
    1428           0 :                 if (bs.bs_sleepduration > bs.bs_dtimperiod) {
    1429           0 :                         bs.bs_sleepduration =
    1430           0 :                             roundup(bs.bs_sleepduration, bs.bs_dtimperiod);
    1431           0 :                 }
    1432             : 
    1433             :                 DPRINTF(ATH_DEBUG_BEACON,
    1434             :                     ("%s: intval %u nexttbtt %u dtim %u nextdtim %u bmiss %u"
    1435             :                     " sleep %u\n"
    1436             :                     , __func__
    1437             :                     , bs.bs_intval
    1438             :                     , bs.bs_nexttbtt
    1439             :                     , bs.bs_dtimperiod
    1440             :                     , bs.bs_nextdtim
    1441             :                     , bs.bs_bmissthreshold
    1442             :                     , bs.bs_sleepduration
    1443             :                 ));
    1444           0 :                 ath_hal_set_intr(ah, 0);
    1445           0 :                 ath_hal_set_beacon_timers(ah, &bs, 0/*XXX*/, 0, 0);
    1446           0 :                 sc->sc_imask |= HAL_INT_BMISS;
    1447           0 :                 ath_hal_set_intr(ah, sc->sc_imask);
    1448           0 :         }
    1449             : #ifndef IEEE80211_STA_ONLY
    1450             :         else {
    1451           0 :                 ath_hal_set_intr(ah, 0);
    1452           0 :                 if (nexttbtt == intval)
    1453           0 :                         intval |= HAL_BEACON_RESET_TSF;
    1454           0 :                 if (ic->ic_opmode == IEEE80211_M_IBSS) {
    1455             :                         /*
    1456             :                          * In IBSS mode enable the beacon timers but only
    1457             :                          * enable SWBA interrupts if we need to manually
    1458             :                          * prepare beacon frames. Otherwise we use a
    1459             :                          * self-linked tx descriptor and let the hardware
    1460             :                          * deal with things.
    1461             :                          */
    1462           0 :                         intval |= HAL_BEACON_ENA;
    1463           0 :                         if (!sc->sc_veol)
    1464           0 :                                 sc->sc_imask |= HAL_INT_SWBA;
    1465           0 :                 } else if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
    1466             :                         /*
    1467             :                          * In AP mode we enable the beacon timers and
    1468             :                          * SWBA interrupts to prepare beacon frames.
    1469             :                          */
    1470           0 :                         intval |= HAL_BEACON_ENA;
    1471           0 :                         sc->sc_imask |= HAL_INT_SWBA;        /* beacon prepare */
    1472           0 :                 }
    1473           0 :                 ath_hal_init_beacon(ah, nexttbtt, intval);
    1474           0 :                 ath_hal_set_intr(ah, sc->sc_imask);
    1475             :                 /*
    1476             :                  * When using a self-linked beacon descriptor in IBBS
    1477             :                  * mode load it once here.
    1478             :                  */
    1479           0 :                 if (ic->ic_opmode == IEEE80211_M_IBSS && sc->sc_veol)
    1480           0 :                         ath_beacon_proc(sc, 0);
    1481             :         }
    1482             : #endif
    1483           0 : }
    1484             : 
    1485             : int
    1486           0 : ath_desc_alloc(struct ath_softc *sc)
    1487             : {
    1488             :         int i, bsize, error = -1;
    1489             :         struct ath_desc *ds;
    1490             :         struct ath_buf *bf;
    1491             : 
    1492             :         /* allocate descriptors */
    1493           0 :         sc->sc_desc_len = sizeof(struct ath_desc) *
    1494             :                                 (ATH_TXBUF * ATH_TXDESC + ATH_RXBUF + 1);
    1495           0 :         if ((error = bus_dmamem_alloc(sc->sc_dmat, sc->sc_desc_len, PAGE_SIZE,
    1496           0 :             0, &sc->sc_dseg, 1, &sc->sc_dnseg, 0)) != 0) {
    1497           0 :                 printf("%s: unable to allocate control data, error = %d\n",
    1498           0 :                     sc->sc_dev.dv_xname, error);
    1499           0 :                 goto fail0;
    1500             :         }
    1501             : 
    1502           0 :         if ((error = bus_dmamem_map(sc->sc_dmat, &sc->sc_dseg, sc->sc_dnseg,
    1503           0 :             sc->sc_desc_len, (caddr_t *)&sc->sc_desc, BUS_DMA_COHERENT)) != 0) {
    1504           0 :                 printf("%s: unable to map control data, error = %d\n",
    1505           0 :                     sc->sc_dev.dv_xname, error);
    1506           0 :                 goto fail1;
    1507             :         }
    1508             : 
    1509           0 :         if ((error = bus_dmamap_create(sc->sc_dmat, sc->sc_desc_len, 1,
    1510           0 :             sc->sc_desc_len, 0, 0, &sc->sc_ddmamap)) != 0) {
    1511           0 :                 printf("%s: unable to create control data DMA map, "
    1512           0 :                     "error = %d\n", sc->sc_dev.dv_xname, error);
    1513           0 :                 goto fail2;
    1514             :         }
    1515             : 
    1516           0 :         if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_ddmamap, sc->sc_desc,
    1517           0 :             sc->sc_desc_len, NULL, 0)) != 0) {
    1518           0 :                 printf("%s: unable to load control data DMA map, error = %d\n",
    1519           0 :                     sc->sc_dev.dv_xname, error);
    1520           0 :                 goto fail3;
    1521             :         }
    1522             : 
    1523           0 :         ds = sc->sc_desc;
    1524           0 :         sc->sc_desc_paddr = sc->sc_ddmamap->dm_segs[0].ds_addr;
    1525             : 
    1526             :         DPRINTF(ATH_DEBUG_XMIT_DESC|ATH_DEBUG_RECV_DESC,
    1527             :             ("ath_desc_alloc: DMA map: %p (%lu) -> %p (%lu)\n",
    1528             :             ds, (u_long)sc->sc_desc_len,
    1529             :             (caddr_t) sc->sc_desc_paddr, /*XXX*/ (u_long) sc->sc_desc_len));
    1530             : 
    1531             :         /* allocate buffers */
    1532             :         bsize = sizeof(struct ath_buf) * (ATH_TXBUF + ATH_RXBUF + 1);
    1533           0 :         bf = malloc(bsize, M_DEVBUF, M_NOWAIT | M_ZERO);
    1534           0 :         if (bf == NULL) {
    1535           0 :                 printf("%s: unable to allocate Tx/Rx buffers\n",
    1536           0 :                     sc->sc_dev.dv_xname);
    1537             :                 error = ENOMEM;
    1538           0 :                 goto fail3;
    1539             :         }
    1540           0 :         sc->sc_bufptr = bf;
    1541             : 
    1542           0 :         TAILQ_INIT(&sc->sc_rxbuf);
    1543           0 :         for (i = 0; i < ATH_RXBUF; i++, bf++, ds++) {
    1544           0 :                 bf->bf_desc = ds;
    1545           0 :                 bf->bf_daddr = sc->sc_desc_paddr +
    1546           0 :                     ((caddr_t)ds - (caddr_t)sc->sc_desc);
    1547           0 :                 if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1,
    1548           0 :                     MCLBYTES, 0, 0, &bf->bf_dmamap)) != 0) {
    1549           0 :                         printf("%s: unable to create Rx dmamap, error = %d\n",
    1550           0 :                             sc->sc_dev.dv_xname, error);
    1551           0 :                         goto fail4;
    1552             :                 }
    1553           0 :                 TAILQ_INSERT_TAIL(&sc->sc_rxbuf, bf, bf_list);
    1554             :         }
    1555             : 
    1556           0 :         TAILQ_INIT(&sc->sc_txbuf);
    1557           0 :         for (i = 0; i < ATH_TXBUF; i++, bf++, ds += ATH_TXDESC) {
    1558           0 :                 bf->bf_desc = ds;
    1559           0 :                 bf->bf_daddr = sc->sc_desc_paddr +
    1560           0 :                     ((caddr_t)ds - (caddr_t)sc->sc_desc);
    1561           0 :                 if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES,
    1562           0 :                     ATH_TXDESC, MCLBYTES, 0, 0, &bf->bf_dmamap)) != 0) {
    1563           0 :                         printf("%s: unable to create Tx dmamap, error = %d\n",
    1564           0 :                             sc->sc_dev.dv_xname, error);
    1565           0 :                         goto fail5;
    1566             :                 }
    1567           0 :                 TAILQ_INSERT_TAIL(&sc->sc_txbuf, bf, bf_list);
    1568             :         }
    1569           0 :         TAILQ_INIT(&sc->sc_txq);
    1570             : 
    1571             :         /* beacon buffer */
    1572           0 :         bf->bf_desc = ds;
    1573           0 :         bf->bf_daddr = sc->sc_desc_paddr + ((caddr_t)ds - (caddr_t)sc->sc_desc);
    1574           0 :         if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES, 0, 0,
    1575           0 :             &bf->bf_dmamap)) != 0) {
    1576           0 :                 printf("%s: unable to create beacon dmamap, error = %d\n",
    1577           0 :                     sc->sc_dev.dv_xname, error);
    1578           0 :                 goto fail5;
    1579             :         }
    1580           0 :         sc->sc_bcbuf = bf;
    1581           0 :         return 0;
    1582             : 
    1583             : fail5:
    1584           0 :         for (i = ATH_RXBUF; i < ATH_RXBUF + ATH_TXBUF; i++) {
    1585           0 :                 if (sc->sc_bufptr[i].bf_dmamap == NULL)
    1586             :                         continue;
    1587           0 :                 bus_dmamap_destroy(sc->sc_dmat, sc->sc_bufptr[i].bf_dmamap);
    1588           0 :         }
    1589             : fail4:
    1590           0 :         for (i = 0; i < ATH_RXBUF; i++) {
    1591           0 :                 if (sc->sc_bufptr[i].bf_dmamap == NULL)
    1592             :                         continue;
    1593           0 :                 bus_dmamap_destroy(sc->sc_dmat, sc->sc_bufptr[i].bf_dmamap);
    1594           0 :         }
    1595             : fail3:
    1596           0 :         bus_dmamap_unload(sc->sc_dmat, sc->sc_ddmamap);
    1597             : fail2:
    1598           0 :         bus_dmamap_destroy(sc->sc_dmat, sc->sc_ddmamap);
    1599           0 :         sc->sc_ddmamap = NULL;
    1600             : fail1:
    1601           0 :         bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_desc, sc->sc_desc_len);
    1602             : fail0:
    1603           0 :         bus_dmamem_free(sc->sc_dmat, &sc->sc_dseg, sc->sc_dnseg);
    1604           0 :         return error;
    1605           0 : }
    1606             : 
    1607             : void
    1608           0 : ath_desc_free(struct ath_softc *sc)
    1609             : {
    1610             :         struct ath_buf *bf;
    1611             : 
    1612           0 :         bus_dmamap_unload(sc->sc_dmat, sc->sc_ddmamap);
    1613           0 :         bus_dmamap_destroy(sc->sc_dmat, sc->sc_ddmamap);
    1614           0 :         bus_dmamem_free(sc->sc_dmat, &sc->sc_dseg, sc->sc_dnseg);
    1615             : 
    1616           0 :         TAILQ_FOREACH(bf, &sc->sc_txq, bf_list) {
    1617           0 :                 bus_dmamap_unload(sc->sc_dmat, bf->bf_dmamap);
    1618           0 :                 bus_dmamap_destroy(sc->sc_dmat, bf->bf_dmamap);
    1619           0 :                 m_freem(bf->bf_m);
    1620             :         }
    1621           0 :         TAILQ_FOREACH(bf, &sc->sc_txbuf, bf_list)
    1622           0 :                 bus_dmamap_destroy(sc->sc_dmat, bf->bf_dmamap);
    1623           0 :         TAILQ_FOREACH(bf, &sc->sc_rxbuf, bf_list) {
    1624           0 :                 if (bf->bf_m) {
    1625           0 :                         bus_dmamap_unload(sc->sc_dmat, bf->bf_dmamap);
    1626           0 :                         bus_dmamap_destroy(sc->sc_dmat, bf->bf_dmamap);
    1627           0 :                         m_freem(bf->bf_m);
    1628           0 :                         bf->bf_m = NULL;
    1629           0 :                 }
    1630             :         }
    1631           0 :         if (sc->sc_bcbuf != NULL) {
    1632           0 :                 bus_dmamap_unload(sc->sc_dmat, sc->sc_bcbuf->bf_dmamap);
    1633           0 :                 bus_dmamap_destroy(sc->sc_dmat, sc->sc_bcbuf->bf_dmamap);
    1634           0 :                 sc->sc_bcbuf = NULL;
    1635           0 :         }
    1636             : 
    1637           0 :         TAILQ_INIT(&sc->sc_rxbuf);
    1638           0 :         TAILQ_INIT(&sc->sc_txbuf);
    1639           0 :         TAILQ_INIT(&sc->sc_txq);
    1640           0 :         free(sc->sc_bufptr, M_DEVBUF, 0);
    1641           0 :         sc->sc_bufptr = NULL;
    1642           0 : }
    1643             : 
    1644             : struct ieee80211_node *
    1645           0 : ath_node_alloc(struct ieee80211com *ic)
    1646             : {
    1647             :         struct ath_node *an;
    1648             : 
    1649           0 :         an = malloc(sizeof(*an), M_DEVBUF, M_NOWAIT | M_ZERO);
    1650           0 :         if (an) {
    1651             :                 int i;
    1652           0 :                 for (i = 0; i < ATH_RHIST_SIZE; i++)
    1653           0 :                         an->an_rx_hist[i].arh_ticks = ATH_RHIST_NOTIME;
    1654           0 :                 an->an_rx_hist_next = ATH_RHIST_SIZE-1;
    1655           0 :                 return &an->an_node;
    1656             :         } else
    1657           0 :                 return NULL;
    1658           0 : }
    1659             : 
    1660             : void
    1661           0 : ath_node_free(struct ieee80211com *ic, struct ieee80211_node *ni)
    1662             : {
    1663           0 :         struct ath_softc *sc = ic->ic_if.if_softc;
    1664             :         struct ath_buf *bf;
    1665             : 
    1666           0 :         TAILQ_FOREACH(bf, &sc->sc_txq, bf_list) {
    1667           0 :                 if (bf->bf_node == ni)
    1668           0 :                         bf->bf_node = NULL;
    1669             :         }
    1670           0 :         (*sc->sc_node_free)(ic, ni);
    1671           0 : }
    1672             : 
    1673             : void
    1674           0 : ath_node_copy(struct ieee80211com *ic,
    1675             :         struct ieee80211_node *dst, const struct ieee80211_node *src)
    1676             : {
    1677           0 :         struct ath_softc *sc = ic->ic_if.if_softc;
    1678             : 
    1679           0 :         bcopy(&src[1], &dst[1],
    1680             :                 sizeof(struct ath_node) - sizeof(struct ieee80211_node));
    1681           0 :         (*sc->sc_node_copy)(ic, dst, src);
    1682           0 : }
    1683             : 
    1684             : u_int8_t
    1685           0 : ath_node_getrssi(struct ieee80211com *ic, const struct ieee80211_node *ni)
    1686             : {
    1687           0 :         const struct ath_node *an = ATH_NODE(ni);
    1688             :         int i, now, nsamples, rssi;
    1689             : 
    1690             :         /*
    1691             :          * Calculate the average over the last second of sampled data.
    1692             :          */
    1693           0 :         now = ATH_TICKS();
    1694             :         nsamples = 0;
    1695             :         rssi = 0;
    1696           0 :         i = an->an_rx_hist_next;
    1697           0 :         do {
    1698           0 :                 const struct ath_recv_hist *rh = &an->an_rx_hist[i];
    1699           0 :                 if (rh->arh_ticks == ATH_RHIST_NOTIME)
    1700           0 :                         goto done;
    1701           0 :                 if (now - rh->arh_ticks > hz)
    1702           0 :                         goto done;
    1703           0 :                 rssi += rh->arh_rssi;
    1704           0 :                 nsamples++;
    1705           0 :                 if (i == 0) {
    1706             :                         i = ATH_RHIST_SIZE-1;
    1707           0 :                 } else {
    1708           0 :                         i--;
    1709             :                 }
    1710           0 :         } while (i != an->an_rx_hist_next);
    1711             : done:
    1712             :         /*
    1713             :          * Return either the average or the last known
    1714             :          * value if there is no recent data.
    1715             :          */
    1716           0 :         return (nsamples ? rssi / nsamples : an->an_rx_hist[i].arh_rssi);
    1717           0 : }
    1718             : 
    1719             : int
    1720           0 : ath_rxbuf_init(struct ath_softc *sc, struct ath_buf *bf)
    1721             : {
    1722           0 :         struct ath_hal *ah = sc->sc_ah;
    1723             :         int error;
    1724             :         struct mbuf *m;
    1725             :         struct ath_desc *ds;
    1726             : 
    1727           0 :         m = bf->bf_m;
    1728           0 :         if (m == NULL) {
    1729             :                 /*
    1730             :                  * NB: by assigning a page to the rx dma buffer we
    1731             :                  * implicitly satisfy the Atheros requirement that
    1732             :                  * this buffer be cache-line-aligned and sized to be
    1733             :                  * multiple of the cache line size.  Not doing this
    1734             :                  * causes weird stuff to happen (for the 5210 at least).
    1735             :                  */
    1736           0 :                 m = ath_getmbuf(M_DONTWAIT, MT_DATA, MCLBYTES);
    1737           0 :                 if (m == NULL) {
    1738             :                         DPRINTF(ATH_DEBUG_ANY,
    1739             :                             ("%s: no mbuf/cluster\n", __func__));
    1740           0 :                         sc->sc_stats.ast_rx_nombuf++;
    1741           0 :                         return ENOMEM;
    1742             :                 }
    1743           0 :                 bf->bf_m = m;
    1744           0 :                 m->m_pkthdr.len = m->m_len = m->m_ext.ext_size;
    1745             : 
    1746           0 :                 error = bus_dmamap_load_mbuf(sc->sc_dmat, bf->bf_dmamap, m,
    1747             :                     BUS_DMA_NOWAIT);
    1748           0 :                 if (error != 0) {
    1749             :                         DPRINTF(ATH_DEBUG_ANY,
    1750             :                             ("%s: ath_bus_dmamap_load_mbuf failed;"
    1751             :                             " error %d\n", __func__, error));
    1752           0 :                         sc->sc_stats.ast_rx_busdma++;
    1753           0 :                         return error;
    1754             :                 }
    1755           0 :                 KASSERT(bf->bf_nseg == 1,
    1756             :                         ("ath_rxbuf_init: multi-segment packet; nseg %u",
    1757             :                         bf->bf_nseg));
    1758             :         }
    1759           0 :         bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap, 0,
    1760             :             bf->bf_dmamap->dm_mapsize, BUS_DMASYNC_PREREAD);
    1761             : 
    1762             :         /*
    1763             :          * Setup descriptors.  For receive we always terminate
    1764             :          * the descriptor list with a self-linked entry so we'll
    1765             :          * not get overrun under high load (as can happen with a
    1766             :          * 5212 when ANI processing enables PHY errors).
    1767             :          *
    1768             :          * To insure the last descriptor is self-linked we create
    1769             :          * each descriptor as self-linked and add it to the end.  As
    1770             :          * each additional descriptor is added the previous self-linked
    1771             :          * entry is ``fixed'' naturally.  This should be safe even
    1772             :          * if DMA is happening.  When processing RX interrupts we
    1773             :          * never remove/process the last, self-linked, entry on the
    1774             :          * descriptor list.  This insures the hardware always has
    1775             :          * someplace to write a new frame.
    1776             :          */
    1777           0 :         ds = bf->bf_desc;
    1778           0 :         bzero(ds, sizeof(struct ath_desc));
    1779             : #ifndef IEEE80211_STA_ONLY
    1780           0 :         if (sc->sc_ic.ic_opmode != IEEE80211_M_HOSTAP)
    1781           0 :                 ds->ds_link = bf->bf_daddr;       /* link to self */
    1782             : #endif
    1783           0 :         ds->ds_data = bf->bf_segs[0].ds_addr;
    1784           0 :         ath_hal_setup_rx_desc(ah, ds
    1785             :                 , m->m_len           /* buffer size */
    1786             :                 , 0
    1787             :         );
    1788             : 
    1789           0 :         if (sc->sc_rxlink != NULL)
    1790           0 :                 *sc->sc_rxlink = bf->bf_daddr;
    1791           0 :         sc->sc_rxlink = &ds->ds_link;
    1792           0 :         return 0;
    1793           0 : }
    1794             : 
    1795             : void
    1796           0 : ath_rx_proc(void *arg, int npending)
    1797             : {
    1798             : #define PA2DESC(_sc, _pa) \
    1799             :         ((struct ath_desc *)((caddr_t)(_sc)->sc_desc + \
    1800             :                 ((_pa) - (_sc)->sc_desc_paddr)))
    1801           0 :         struct ath_softc *sc = arg;
    1802             :         struct ath_buf *bf;
    1803           0 :         struct ieee80211com *ic = &sc->sc_ic;
    1804           0 :         struct ifnet *ifp = &ic->ic_if;
    1805           0 :         struct ath_hal *ah = sc->sc_ah;
    1806             :         struct ath_desc *ds;
    1807             :         struct mbuf *m;
    1808             :         struct ieee80211_frame *wh;
    1809           0 :         struct ieee80211_frame whbuf;
    1810           0 :         struct ieee80211_rxinfo rxi;
    1811             :         struct ieee80211_node *ni;
    1812             :         struct ath_node *an;
    1813             :         struct ath_recv_hist *rh;
    1814             :         int len;
    1815             :         u_int phyerr;
    1816             :         HAL_STATUS status;
    1817             : 
    1818             :         DPRINTF(ATH_DEBUG_RX_PROC, ("%s: pending %u\n", __func__, npending));
    1819           0 :         do {
    1820           0 :                 bf = TAILQ_FIRST(&sc->sc_rxbuf);
    1821           0 :                 if (bf == NULL) {               /* NB: shouldn't happen */
    1822           0 :                         printf("%s: ath_rx_proc: no buffer!\n", ifp->if_xname);
    1823           0 :                         break;
    1824             :                 }
    1825           0 :                 ds = bf->bf_desc;
    1826           0 :                 if (ds->ds_link == bf->bf_daddr) {
    1827             :                         /* NB: never process the self-linked entry at the end */
    1828             :                         break;
    1829             :                 }
    1830           0 :                 m = bf->bf_m;
    1831           0 :                 if (m == NULL) {                /* NB: shouldn't happen */
    1832           0 :                         printf("%s: ath_rx_proc: no mbuf!\n", ifp->if_xname);
    1833           0 :                         continue;
    1834             :                 }
    1835             :                 /* XXX sync descriptor memory */
    1836             :                 /*
    1837             :                  * Must provide the virtual address of the current
    1838             :                  * descriptor, the physical address, and the virtual
    1839             :                  * address of the next descriptor in the h/w chain.
    1840             :                  * This allows the HAL to look ahead to see if the
    1841             :                  * hardware is done with a descriptor by checking the
    1842             :                  * done bit in the following descriptor and the address
    1843             :                  * of the current descriptor the DMA engine is working
    1844             :                  * on.  All this is necessary because of our use of
    1845             :                  * a self-linked list to avoid rx overruns.
    1846             :                  */
    1847           0 :                 status = ath_hal_proc_rx_desc(ah, ds,
    1848             :                     bf->bf_daddr, PA2DESC(sc, ds->ds_link));
    1849             : #ifdef AR_DEBUG
    1850             :                 if (ath_debug & ATH_DEBUG_RECV_DESC)
    1851             :                     ath_printrxbuf(bf, status == HAL_OK);
    1852             : #endif
    1853           0 :                 if (status == HAL_EINPROGRESS)
    1854             :                         break;
    1855           0 :                 TAILQ_REMOVE(&sc->sc_rxbuf, bf, bf_list);
    1856             : 
    1857           0 :                 if (ds->ds_rxstat.rs_more) {
    1858             :                         /*
    1859             :                          * Frame spans multiple descriptors; this
    1860             :                          * cannot happen yet as we don't support
    1861             :                          * jumbograms.  If not in monitor mode,
    1862             :                          * discard the frame.
    1863             :                          */
    1864             : 
    1865             :                         /* 
    1866             :                          * Enable this if you want to see error
    1867             :                          * frames in Monitor mode.
    1868             :                          */
    1869             : #ifdef ERROR_FRAMES
    1870             :                         if (ic->ic_opmode != IEEE80211_M_MONITOR) {
    1871             :                                 /* XXX statistic */
    1872             :                                 goto rx_next;
    1873             :                         }
    1874             : #endif
    1875             :                         /* fall thru for monitor mode handling... */
    1876             : 
    1877           0 :                 } else if (ds->ds_rxstat.rs_status != 0) {
    1878           0 :                         if (ds->ds_rxstat.rs_status & HAL_RXERR_CRC)
    1879           0 :                                 sc->sc_stats.ast_rx_crcerr++;
    1880           0 :                         if (ds->ds_rxstat.rs_status & HAL_RXERR_FIFO)
    1881           0 :                                 sc->sc_stats.ast_rx_fifoerr++;
    1882           0 :                         if (ds->ds_rxstat.rs_status & HAL_RXERR_DECRYPT)
    1883           0 :                                 sc->sc_stats.ast_rx_badcrypt++;
    1884           0 :                         if (ds->ds_rxstat.rs_status & HAL_RXERR_PHY) {
    1885           0 :                                 sc->sc_stats.ast_rx_phyerr++;
    1886           0 :                                 phyerr = ds->ds_rxstat.rs_phyerr & 0x1f;
    1887           0 :                                 sc->sc_stats.ast_rx_phy[phyerr]++;
    1888           0 :                         }
    1889             : 
    1890             :                         /*
    1891             :                          * reject error frames, we normally don't want
    1892             :                          * to see them in monitor mode.
    1893             :                          */
    1894           0 :                         if ((ds->ds_rxstat.rs_status & HAL_RXERR_DECRYPT ) ||
    1895           0 :                             (ds->ds_rxstat.rs_status & HAL_RXERR_PHY))
    1896             :                             goto rx_next;
    1897             : 
    1898             :                         /*
    1899             :                          * In monitor mode, allow through packets that
    1900             :                          * cannot be decrypted
    1901             :                          */
    1902           0 :                         if ((ds->ds_rxstat.rs_status & ~HAL_RXERR_DECRYPT) ||
    1903           0 :                             sc->sc_ic.ic_opmode != IEEE80211_M_MONITOR)
    1904             :                                 goto rx_next;
    1905             :                 }
    1906             : 
    1907           0 :                 len = ds->ds_rxstat.rs_datalen;
    1908           0 :                 if (len < IEEE80211_MIN_LEN) {
    1909             :                         DPRINTF(ATH_DEBUG_RECV, ("%s: short packet %d\n",
    1910             :                             __func__, len));
    1911           0 :                         sc->sc_stats.ast_rx_tooshort++;
    1912           0 :                         goto rx_next;
    1913             :                 }
    1914             : 
    1915           0 :                 bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap, 0,
    1916             :                     bf->bf_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
    1917             : 
    1918           0 :                 bus_dmamap_unload(sc->sc_dmat, bf->bf_dmamap);
    1919           0 :                 bf->bf_m = NULL;
    1920           0 :                 m->m_pkthdr.len = m->m_len = len;
    1921             : 
    1922             : #if NBPFILTER > 0
    1923           0 :                 if (sc->sc_drvbpf) {
    1924           0 :                         struct mbuf mb;
    1925             : 
    1926           0 :                         sc->sc_rxtap.wr_flags = IEEE80211_RADIOTAP_F_FCS;
    1927           0 :                         sc->sc_rxtap.wr_rate =
    1928           0 :                             sc->sc_hwmap[ds->ds_rxstat.rs_rate] &
    1929             :                             IEEE80211_RATE_VAL;
    1930           0 :                         sc->sc_rxtap.wr_antenna = ds->ds_rxstat.rs_antenna;
    1931           0 :                         sc->sc_rxtap.wr_rssi = ds->ds_rxstat.rs_rssi;
    1932           0 :                         sc->sc_rxtap.wr_max_rssi = ic->ic_max_rssi;
    1933             : 
    1934           0 :                         mb.m_data = (caddr_t)&sc->sc_rxtap;
    1935           0 :                         mb.m_len = sc->sc_rxtap_len;
    1936           0 :                         mb.m_next = m;
    1937           0 :                         mb.m_nextpkt = NULL;
    1938           0 :                         mb.m_type = 0;
    1939           0 :                         mb.m_flags = 0;
    1940           0 :                         bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_IN);
    1941           0 :                 }
    1942             : #endif
    1943           0 :                 m_adj(m, -IEEE80211_CRC_LEN);
    1944           0 :                 wh = mtod(m, struct ieee80211_frame *);
    1945           0 :                 rxi.rxi_flags = 0;
    1946           0 :                 if (!ath_softcrypto && (wh->i_fc[1] & IEEE80211_FC1_WEP)) {
    1947             :                         /*
    1948             :                          * WEP is decrypted by hardware. Clear WEP bit
    1949             :                          * and trim WEP header for ieee80211_input().
    1950             :                          */
    1951           0 :                         wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
    1952           0 :                         bcopy(wh, &whbuf, sizeof(whbuf));
    1953           0 :                         m_adj(m, IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN);
    1954           0 :                         wh = mtod(m, struct ieee80211_frame *);
    1955           0 :                         bcopy(&whbuf, wh, sizeof(whbuf));
    1956             :                         /*
    1957             :                          * Also trim WEP ICV from the tail.
    1958             :                          */
    1959           0 :                         m_adj(m, -IEEE80211_WEP_CRCLEN);
    1960             :                         /*
    1961             :                          * The header has probably moved.
    1962             :                          */
    1963           0 :                         wh = mtod(m, struct ieee80211_frame *);
    1964             : 
    1965           0 :                         rxi.rxi_flags |= IEEE80211_RXI_HWDEC;
    1966           0 :                 }
    1967             : 
    1968             :                 /*
    1969             :                  * Locate the node for sender, track state, and
    1970             :                  * then pass this node (referenced) up to the 802.11
    1971             :                  * layer for its use.
    1972             :                  */
    1973           0 :                 ni = ieee80211_find_rxnode(ic, wh);
    1974             : 
    1975             :                 /*
    1976             :                  * Record driver-specific state.
    1977             :                  */
    1978           0 :                 an = ATH_NODE(ni);
    1979           0 :                 if (++(an->an_rx_hist_next) == ATH_RHIST_SIZE)
    1980           0 :                         an->an_rx_hist_next = 0;
    1981           0 :                 rh = &an->an_rx_hist[an->an_rx_hist_next];
    1982           0 :                 rh->arh_ticks = ATH_TICKS();
    1983           0 :                 rh->arh_rssi = ds->ds_rxstat.rs_rssi;
    1984           0 :                 rh->arh_antenna = ds->ds_rxstat.rs_antenna;
    1985             : 
    1986             :                 /*
    1987             :                  * Send frame up for processing.
    1988             :                  */
    1989           0 :                 rxi.rxi_rssi = ds->ds_rxstat.rs_rssi;
    1990           0 :                 rxi.rxi_tstamp = ds->ds_rxstat.rs_tstamp;
    1991           0 :                 ieee80211_input(ifp, m, ni, &rxi);
    1992             : 
    1993             :                 /* Handle the rate adaption */
    1994           0 :                 ieee80211_rssadapt_input(ic, ni, &an->an_rssadapt,
    1995           0 :                     ds->ds_rxstat.rs_rssi);
    1996             : 
    1997             :                 /*
    1998             :                  * The frame may have caused the node to be marked for
    1999             :                  * reclamation (e.g. in response to a DEAUTH message)
    2000             :                  * so use release_node here instead of unref_node.
    2001             :                  */
    2002           0 :                 ieee80211_release_node(ic, ni);
    2003             : 
    2004             :         rx_next:
    2005           0 :                 TAILQ_INSERT_TAIL(&sc->sc_rxbuf, bf, bf_list);
    2006           0 :         } while (ath_rxbuf_init(sc, bf) == 0);
    2007             : 
    2008           0 :         ath_hal_set_rx_signal(ah);              /* rx signal state monitoring */
    2009           0 :         ath_hal_start_rx(ah);                   /* in case of RXEOL */
    2010             : #undef PA2DESC
    2011           0 : }
    2012             : 
    2013             : /*
    2014             :  * XXX Size of an ACK control frame in bytes.
    2015             :  */
    2016             : #define IEEE80211_ACK_SIZE      (2+2+IEEE80211_ADDR_LEN+4)
    2017             : 
    2018             : int
    2019           0 : ath_tx_start(struct ath_softc *sc, struct ieee80211_node *ni,
    2020             :     struct ath_buf *bf, struct mbuf *m0)
    2021             : {
    2022           0 :         struct ieee80211com *ic = &sc->sc_ic;
    2023           0 :         struct ath_hal *ah = sc->sc_ah;
    2024           0 :         struct ifnet *ifp = &sc->sc_ic.ic_if;
    2025             :         int i, error, iswep, hdrlen, pktlen, len, s, tries;
    2026             :         u_int8_t rix, cix, txrate, ctsrate;
    2027             :         struct ath_desc *ds;
    2028             :         struct ieee80211_frame *wh;
    2029             :         struct ieee80211_key *k;
    2030             :         u_int32_t iv;
    2031             :         u_int8_t *ivp;
    2032           0 :         u_int8_t hdrbuf[sizeof(struct ieee80211_frame) +
    2033             :             IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN];
    2034             :         u_int subtype, flags, ctsduration, antenna;
    2035             :         HAL_PKT_TYPE atype;
    2036             :         const HAL_RATE_TABLE *rt;
    2037             :         HAL_BOOL shortPreamble;
    2038             :         struct ath_node *an;
    2039             :         u_int8_t hwqueue = HAL_TX_QUEUE_ID_DATA_MIN;
    2040             : 
    2041           0 :         wh = mtod(m0, struct ieee80211_frame *);
    2042           0 :         iswep = wh->i_fc[1] & IEEE80211_FC1_PROTECTED;
    2043             :         hdrlen = sizeof(struct ieee80211_frame);
    2044           0 :         pktlen = m0->m_pkthdr.len;
    2045             : 
    2046           0 :         if (ath_softcrypto && iswep) {
    2047           0 :                 k = ieee80211_get_txkey(ic, wh, ni);    
    2048           0 :                 if ((m0 = ieee80211_encrypt(ic, m0, k)) == NULL)
    2049           0 :                         return ENOMEM;
    2050           0 :                 wh = mtod(m0, struct ieee80211_frame *);
    2051             : 
    2052             :                 /* reset len in case we got a new mbuf */
    2053           0 :                 pktlen = m0->m_pkthdr.len;
    2054           0 :         } else if (!ath_softcrypto && iswep) {
    2055           0 :                 bcopy(mtod(m0, caddr_t), hdrbuf, hdrlen);
    2056           0 :                 m_adj(m0, hdrlen);
    2057           0 :                 M_PREPEND(m0, sizeof(hdrbuf), M_DONTWAIT);
    2058           0 :                 if (m0 == NULL) {
    2059           0 :                         sc->sc_stats.ast_tx_nombuf++;
    2060           0 :                         return ENOMEM;
    2061             :                 }
    2062           0 :                 ivp = hdrbuf + hdrlen;
    2063           0 :                 wh = mtod(m0, struct ieee80211_frame *);
    2064             :                 /*
    2065             :                  * XXX
    2066             :                  * IV must not duplicate during the lifetime of the key.
    2067             :                  * But no mechanism to renew keys is defined in IEEE 802.11
    2068             :                  * for WEP.  And the IV may be duplicated at other stations
    2069             :                  * because the session key itself is shared.  So we use a
    2070             :                  * pseudo random IV for now, though it is not the right way.
    2071             :                  *
    2072             :                  * NB: Rather than use a strictly random IV we select a
    2073             :                  * random one to start and then increment the value for
    2074             :                  * each frame.  This is an explicit tradeoff between
    2075             :                  * overhead and security.  Given the basic insecurity of
    2076             :                  * WEP this seems worthwhile.
    2077             :                  */
    2078             : 
    2079             :                 /*
    2080             :                  * Skip 'bad' IVs from Fluhrer/Mantin/Shamir:
    2081             :                  * (B, 255, N) with 3 <= B < 16 and 0 <= N <= 255
    2082             :                  */
    2083           0 :                 iv = ic->ic_iv;
    2084           0 :                 if ((iv & 0xff00) == 0xff00) {
    2085           0 :                         int B = (iv & 0xff0000) >> 16;
    2086           0 :                         if (3 <= B && B < 16)
    2087           0 :                                 iv = (B+1) << 16;
    2088           0 :                 }
    2089           0 :                 ic->ic_iv = iv + 1;
    2090             : 
    2091             :                 /*
    2092             :                  * NB: Preserve byte order of IV for packet
    2093             :                  *     sniffers; it doesn't matter otherwise.
    2094             :                  */
    2095             : #if BYTE_ORDER == BIG_ENDIAN
    2096             :                 ivp[0] = iv >> 0;
    2097             :                 ivp[1] = iv >> 8;
    2098             :                 ivp[2] = iv >> 16;
    2099             : #else
    2100           0 :                 ivp[2] = iv >> 0;
    2101           0 :                 ivp[1] = iv >> 8;
    2102           0 :                 ivp[0] = iv >> 16;
    2103             : #endif
    2104           0 :                 ivp[3] = ic->ic_wep_txkey << 6; /* Key ID and pad */
    2105           0 :                 bcopy(hdrbuf, mtod(m0, caddr_t), sizeof(hdrbuf));
    2106             :                 /*
    2107             :                  * The length of hdrlen and pktlen must be increased for WEP
    2108             :                  */
    2109             :                 len = IEEE80211_WEP_IVLEN +
    2110             :                     IEEE80211_WEP_KIDLEN +
    2111             :                     IEEE80211_WEP_CRCLEN;
    2112             :                 hdrlen += len;
    2113           0 :                 pktlen += len;
    2114           0 :         }
    2115           0 :         pktlen += IEEE80211_CRC_LEN;
    2116             : 
    2117             :         /*
    2118             :          * Load the DMA map so any coalescing is done.  This
    2119             :          * also calculates the number of descriptors we need.
    2120             :          */
    2121           0 :         error = bus_dmamap_load_mbuf(sc->sc_dmat, bf->bf_dmamap, m0,
    2122             :             BUS_DMA_NOWAIT);
    2123             :         /*
    2124             :          * Discard null packets and check for packets that
    2125             :          * require too many TX descriptors.  We try to convert
    2126             :          * the latter to a cluster.
    2127             :          */
    2128           0 :         if (error == EFBIG) {           /* too many desc's, linearize */
    2129           0 :                 sc->sc_stats.ast_tx_linear++;
    2130           0 :                 if (m_defrag(m0, M_DONTWAIT)) {
    2131           0 :                         sc->sc_stats.ast_tx_nomcl++;
    2132           0 :                         m_freem(m0);
    2133           0 :                         return ENOMEM;
    2134             :                 }
    2135           0 :                 error = bus_dmamap_load_mbuf(sc->sc_dmat, bf->bf_dmamap, m0,
    2136             :                     BUS_DMA_NOWAIT);
    2137           0 :                 if (error != 0) {
    2138           0 :                         sc->sc_stats.ast_tx_busdma++;
    2139           0 :                         m_freem(m0);
    2140           0 :                         return error;
    2141             :                 }
    2142           0 :                 KASSERT(bf->bf_nseg == 1,
    2143             :                         ("ath_tx_start: packet not one segment; nseg %u",
    2144             :                         bf->bf_nseg));
    2145           0 :         } else if (error != 0) {
    2146           0 :                 sc->sc_stats.ast_tx_busdma++;
    2147           0 :                 m_freem(m0);
    2148           0 :                 return error;
    2149           0 :         } else if (bf->bf_nseg == 0) {               /* null packet, discard */
    2150           0 :                 sc->sc_stats.ast_tx_nodata++;
    2151           0 :                 m_freem(m0);
    2152           0 :                 return EIO;
    2153             :         }
    2154             :         DPRINTF(ATH_DEBUG_XMIT, ("%s: m %p len %u\n", __func__, m0, pktlen));
    2155           0 :         bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap, 0,
    2156             :             bf->bf_dmamap->dm_mapsize, BUS_DMASYNC_PREWRITE);
    2157           0 :         bf->bf_m = m0;
    2158           0 :         bf->bf_node = ni;                    /* NB: held reference */
    2159           0 :         an = ATH_NODE(ni);
    2160             : 
    2161             :         /* setup descriptors */
    2162           0 :         ds = bf->bf_desc;
    2163           0 :         rt = sc->sc_currates;
    2164           0 :         KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode));
    2165             : 
    2166             :         /*
    2167             :          * Calculate Atheros packet type from IEEE80211 packet header
    2168             :          * and setup for rate calculations.
    2169             :          */
    2170           0 :         bf->bf_id.id_node = NULL;
    2171             :         atype = HAL_PKT_TYPE_NORMAL;                    /* default */
    2172           0 :         switch (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) {
    2173             :         case IEEE80211_FC0_TYPE_MGT:
    2174           0 :                 subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
    2175           0 :                 if (subtype == IEEE80211_FC0_SUBTYPE_BEACON) {
    2176             :                         atype = HAL_PKT_TYPE_BEACON;
    2177           0 :                 } else if (subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP) {
    2178             :                         atype = HAL_PKT_TYPE_PROBE_RESP;
    2179           0 :                 } else if (subtype == IEEE80211_FC0_SUBTYPE_ATIM) {
    2180             :                         atype = HAL_PKT_TYPE_ATIM;
    2181           0 :                 }
    2182             :                 rix = 0;                        /* XXX lowest rate */
    2183           0 :                 break;
    2184             :         case IEEE80211_FC0_TYPE_CTL:
    2185           0 :                 subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
    2186           0 :                 if (subtype == IEEE80211_FC0_SUBTYPE_PS_POLL)
    2187           0 :                         atype = HAL_PKT_TYPE_PSPOLL;
    2188             :                 rix = 0;                        /* XXX lowest rate */
    2189           0 :                 break;
    2190             :         default:
    2191             :                 /* remember link conditions for rate adaptation algorithm */
    2192           0 :                 if (ic->ic_fixed_rate == -1) {
    2193           0 :                         bf->bf_id.id_len = m0->m_pkthdr.len;
    2194           0 :                         bf->bf_id.id_rateidx = ni->ni_txrate;
    2195           0 :                         bf->bf_id.id_node = ni;
    2196           0 :                         bf->bf_id.id_rssi = ath_node_getrssi(ic, ni);
    2197           0 :                 }
    2198           0 :                 ni->ni_txrate = ieee80211_rssadapt_choose(&an->an_rssadapt,
    2199           0 :                     &ni->ni_rates, wh, m0->m_pkthdr.len, ic->ic_fixed_rate,
    2200           0 :                     ifp->if_xname, 0);
    2201           0 :                 rix = sc->sc_rixmap[ni->ni_rates.rs_rates[ni->ni_txrate] &
    2202             :                     IEEE80211_RATE_VAL];
    2203           0 :                 if (rix == 0xff) {
    2204           0 :                         printf("%s: bogus xmit rate 0x%x (idx 0x%x)\n",
    2205             :                             ifp->if_xname, ni->ni_rates.rs_rates[ni->ni_txrate],
    2206             :                             ni->ni_txrate);
    2207           0 :                         sc->sc_stats.ast_tx_badrate++;
    2208           0 :                         m_freem(m0);
    2209           0 :                         return EIO;
    2210             :                 }
    2211             :                 break;
    2212             :         }
    2213             : 
    2214             :         /*
    2215             :          * NB: the 802.11 layer marks whether or not we should
    2216             :          * use short preamble based on the current mode and
    2217             :          * negotiated parameters.
    2218             :          */
    2219           0 :         if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
    2220           0 :             (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE)) {
    2221           0 :                 txrate = rt->info[rix].rateCode | rt->info[rix].shortPreamble;
    2222             :                 shortPreamble = AH_TRUE;
    2223           0 :                 sc->sc_stats.ast_tx_shortpre++;
    2224           0 :         } else {
    2225           0 :                 txrate = rt->info[rix].rateCode;
    2226             :                 shortPreamble = AH_FALSE;
    2227             :         }
    2228             : 
    2229             :         /*
    2230             :          * Calculate miscellaneous flags.
    2231             :          */
    2232             :         flags = HAL_TXDESC_CLRDMASK;            /* XXX needed for wep errors */
    2233           0 :         if (IEEE80211_IS_MULTICAST(wh->i_addr1)) {
    2234             :                 flags |= HAL_TXDESC_NOACK;      /* no ack on broad/multicast */
    2235           0 :                 sc->sc_stats.ast_tx_noack++;
    2236           0 :         } else if (pktlen > ic->ic_rtsthreshold) {
    2237             :                 flags |= HAL_TXDESC_RTSENA;     /* RTS based on frame length */
    2238           0 :                 sc->sc_stats.ast_tx_rts++;
    2239           0 :         }
    2240             : 
    2241             :         /*
    2242             :          * Calculate duration.  This logically belongs in the 802.11
    2243             :          * layer but it lacks sufficient information to calculate it.
    2244             :          */
    2245           0 :         if ((flags & HAL_TXDESC_NOACK) == 0 &&
    2246           0 :             (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_CTL) {
    2247             :                 u_int16_t dur;
    2248             :                 /*
    2249             :                  * XXX not right with fragmentation.
    2250             :                  */
    2251           0 :                 dur = ath_hal_computetxtime(ah, rt, IEEE80211_ACK_SIZE,
    2252           0 :                                 rix, shortPreamble);
    2253           0 :                 *((u_int16_t*) wh->i_dur) = htole16(dur);
    2254           0 :         }
    2255             : 
    2256             :         /*
    2257             :          * Calculate RTS/CTS rate and duration if needed.
    2258             :          */
    2259             :         ctsduration = 0;
    2260           0 :         if (flags & (HAL_TXDESC_RTSENA|HAL_TXDESC_CTSENA)) {
    2261             :                 /*
    2262             :                  * CTS transmit rate is derived from the transmit rate
    2263             :                  * by looking in the h/w rate table.  We must also factor
    2264             :                  * in whether or not a short preamble is to be used.
    2265             :                  */
    2266           0 :                 cix = rt->info[rix].controlRate;
    2267           0 :                 ctsrate = rt->info[cix].rateCode;
    2268           0 :                 if (shortPreamble)
    2269           0 :                         ctsrate |= rt->info[cix].shortPreamble;
    2270             :                 /*
    2271             :                  * Compute the transmit duration based on the size
    2272             :                  * of an ACK frame.  We call into the HAL to do the
    2273             :                  * computation since it depends on the characteristics
    2274             :                  * of the actual PHY being used.
    2275             :                  */
    2276           0 :                 if (flags & HAL_TXDESC_RTSENA) {    /* SIFS + CTS */
    2277           0 :                         ctsduration += ath_hal_computetxtime(ah,
    2278           0 :                                 rt, IEEE80211_ACK_SIZE, cix, shortPreamble);
    2279           0 :                 }
    2280             :                 /* SIFS + data */
    2281           0 :                 ctsduration += ath_hal_computetxtime(ah,
    2282           0 :                         rt, pktlen, rix, shortPreamble);
    2283           0 :                 if ((flags & HAL_TXDESC_NOACK) == 0) {      /* SIFS + ACK */
    2284           0 :                         ctsduration += ath_hal_computetxtime(ah,
    2285           0 :                                 rt, IEEE80211_ACK_SIZE, cix, shortPreamble);
    2286           0 :                 }
    2287             :         } else
    2288             :                 ctsrate = 0;
    2289             : 
    2290             :         /*
    2291             :          * For now use the antenna on which the last good
    2292             :          * frame was received on.  We assume this field is
    2293             :          * initialized to 0 which gives us ``auto'' or the
    2294             :          * ``default'' antenna.
    2295             :          */
    2296           0 :         if (an->an_tx_antenna) {
    2297             :                 antenna = an->an_tx_antenna;
    2298           0 :         } else {
    2299           0 :                 antenna = an->an_rx_hist[an->an_rx_hist_next].arh_antenna;
    2300             :         }
    2301             : 
    2302             : #if NBPFILTER > 0
    2303           0 :         if (ic->ic_rawbpf)
    2304           0 :                 bpf_mtap(ic->ic_rawbpf, m0, BPF_DIRECTION_OUT);
    2305             : 
    2306           0 :         if (sc->sc_drvbpf) {
    2307           0 :                 struct mbuf mb;
    2308             : 
    2309           0 :                 sc->sc_txtap.wt_flags = 0;
    2310           0 :                 if (shortPreamble)
    2311           0 :                         sc->sc_txtap.wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
    2312           0 :                 if (!ath_softcrypto && iswep)
    2313           0 :                         sc->sc_txtap.wt_flags |= IEEE80211_RADIOTAP_F_WEP;
    2314           0 :                 sc->sc_txtap.wt_rate = ni->ni_rates.rs_rates[ni->ni_txrate] &
    2315             :                     IEEE80211_RATE_VAL;
    2316           0 :                 sc->sc_txtap.wt_txpower = 30;
    2317           0 :                 sc->sc_txtap.wt_antenna = antenna;
    2318           0 :                 sc->sc_txtap.wt_hwqueue = hwqueue;
    2319             : 
    2320           0 :                 mb.m_data = (caddr_t)&sc->sc_txtap;
    2321           0 :                 mb.m_len = sc->sc_txtap_len;
    2322           0 :                 mb.m_next = m0;
    2323           0 :                 mb.m_nextpkt = NULL;
    2324           0 :                 mb.m_type = 0;
    2325           0 :                 mb.m_flags = 0;
    2326           0 :                 bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_OUT);
    2327           0 :         }
    2328             : #endif
    2329             : 
    2330             :         /*
    2331             :          * Formulate first tx descriptor with tx controls.
    2332             :          */
    2333           0 :         tries = IEEE80211_IS_MULTICAST(wh->i_addr1) ? 1 : 15;
    2334             :         /* XXX check return value? */
    2335           0 :         ath_hal_setup_tx_desc(ah, ds
    2336             :                 , pktlen                /* packet length */
    2337             :                 , hdrlen                /* header length */
    2338             :                 , atype                 /* Atheros packet type */
    2339             :                 , 60                    /* txpower XXX */
    2340             :                 , txrate, tries         /* series 0 rate/tries */
    2341             :                 , iswep ? sc->sc_ic.ic_wep_txkey : HAL_TXKEYIX_INVALID
    2342             :                 , antenna               /* antenna mode */
    2343             :                 , flags                 /* flags */
    2344             :                 , ctsrate               /* rts/cts rate */
    2345             :                 , ctsduration           /* rts/cts duration */
    2346             :         );
    2347             : #ifdef notyet
    2348             :         ath_hal_setup_xtx_desc(ah, ds
    2349             :                 , AH_FALSE              /* short preamble */
    2350             :                 , 0, 0                  /* series 1 rate/tries */
    2351             :                 , 0, 0                  /* series 2 rate/tries */
    2352             :                 , 0, 0                  /* series 3 rate/tries */
    2353             :         );
    2354             : #endif
    2355             :         /*
    2356             :          * Fillin the remainder of the descriptor info.
    2357             :          */
    2358           0 :         for (i = 0; i < bf->bf_nseg; i++, ds++) {
    2359           0 :                 ds->ds_data = bf->bf_segs[i].ds_addr;
    2360           0 :                 if (i == bf->bf_nseg - 1) {
    2361           0 :                         ds->ds_link = 0;
    2362           0 :                 } else {
    2363           0 :                         ds->ds_link = bf->bf_daddr + sizeof(*ds) * (i + 1);
    2364             :                 }
    2365           0 :                 ath_hal_fill_tx_desc(ah, ds
    2366             :                         , bf->bf_segs[i].ds_len      /* segment length */
    2367             :                         , i == 0                /* first segment */
    2368             :                         , i == bf->bf_nseg - 1       /* last segment */
    2369             :                 );
    2370             :                 DPRINTF(ATH_DEBUG_XMIT,
    2371             :                     ("%s: %d: %08x %08x %08x %08x %08x %08x\n",
    2372             :                     __func__, i, ds->ds_link, ds->ds_data,
    2373             :                     ds->ds_ctl0, ds->ds_ctl1, ds->ds_hw[0], ds->ds_hw[1]));
    2374             :         }
    2375             : 
    2376             :         /*
    2377             :          * Insert the frame on the outbound list and
    2378             :          * pass it on to the hardware.
    2379             :          */
    2380           0 :         s = splnet();
    2381           0 :         TAILQ_INSERT_TAIL(&sc->sc_txq, bf, bf_list);
    2382           0 :         if (sc->sc_txlink == NULL) {
    2383           0 :                 ath_hal_put_tx_buf(ah, sc->sc_txhalq[hwqueue], bf->bf_daddr);
    2384             :                 DPRINTF(ATH_DEBUG_XMIT, ("%s: TXDP0 = %p (%p)\n", __func__,
    2385             :                     (caddr_t)bf->bf_daddr, bf->bf_desc));
    2386           0 :         } else {
    2387           0 :                 *sc->sc_txlink = bf->bf_daddr;
    2388             :                 DPRINTF(ATH_DEBUG_XMIT, ("%s: link(%p)=%p (%p)\n", __func__,
    2389             :                     sc->sc_txlink, (caddr_t)bf->bf_daddr, bf->bf_desc));
    2390             :         }
    2391           0 :         sc->sc_txlink = &bf->bf_desc[bf->bf_nseg - 1].ds_link;
    2392           0 :         splx(s);
    2393             : 
    2394           0 :         ath_hal_tx_start(ah, sc->sc_txhalq[hwqueue]);
    2395           0 :         return 0;
    2396           0 : }
    2397             : 
    2398             : void
    2399           0 : ath_tx_proc(void *arg, int npending)
    2400             : {
    2401           0 :         struct ath_softc *sc = arg;
    2402           0 :         struct ath_hal *ah = sc->sc_ah;
    2403             :         struct ath_buf *bf;
    2404           0 :         struct ieee80211com *ic = &sc->sc_ic;
    2405           0 :         struct ifnet *ifp = &ic->ic_if;
    2406             :         struct ath_desc *ds;
    2407             :         struct ieee80211_node *ni;
    2408             :         struct ath_node *an;
    2409             :         int sr, lr, s;
    2410             :         HAL_STATUS status;
    2411             : 
    2412           0 :         for (;;) {
    2413           0 :                 s = splnet();
    2414           0 :                 bf = TAILQ_FIRST(&sc->sc_txq);
    2415           0 :                 if (bf == NULL) {
    2416           0 :                         sc->sc_txlink = NULL;
    2417           0 :                         splx(s);
    2418           0 :                         break;
    2419             :                 }
    2420             :                 /* only the last descriptor is needed */
    2421           0 :                 ds = &bf->bf_desc[bf->bf_nseg - 1];
    2422           0 :                 status = ath_hal_proc_tx_desc(ah, ds);
    2423             : #ifdef AR_DEBUG
    2424             :                 if (ath_debug & ATH_DEBUG_XMIT_DESC)
    2425             :                         ath_printtxbuf(bf, status == HAL_OK);
    2426             : #endif
    2427           0 :                 if (status == HAL_EINPROGRESS) {
    2428           0 :                         splx(s);
    2429           0 :                         break;
    2430             :                 }
    2431           0 :                 TAILQ_REMOVE(&sc->sc_txq, bf, bf_list);
    2432           0 :                 splx(s);
    2433             : 
    2434           0 :                 ni = bf->bf_node;
    2435           0 :                 if (ni != NULL) {
    2436           0 :                         an = (struct ath_node *) ni;
    2437           0 :                         if (ds->ds_txstat.ts_status == 0) {
    2438           0 :                                 if (bf->bf_id.id_node != NULL)
    2439           0 :                                         ieee80211_rssadapt_raise_rate(ic,
    2440           0 :                                             &an->an_rssadapt, &bf->bf_id);
    2441           0 :                                 an->an_tx_antenna = ds->ds_txstat.ts_antenna;
    2442           0 :                         } else {
    2443           0 :                                 if (bf->bf_id.id_node != NULL)
    2444           0 :                                         ieee80211_rssadapt_lower_rate(ic, ni,
    2445           0 :                                             &an->an_rssadapt, &bf->bf_id);
    2446           0 :                                 if (ds->ds_txstat.ts_status & HAL_TXERR_XRETRY)
    2447           0 :                                         sc->sc_stats.ast_tx_xretries++;
    2448           0 :                                 if (ds->ds_txstat.ts_status & HAL_TXERR_FIFO)
    2449           0 :                                         sc->sc_stats.ast_tx_fifoerr++;
    2450           0 :                                 if (ds->ds_txstat.ts_status & HAL_TXERR_FILT)
    2451           0 :                                         sc->sc_stats.ast_tx_filtered++;
    2452           0 :                                 an->an_tx_antenna = 0;       /* invalidate */
    2453             :                         }
    2454           0 :                         sr = ds->ds_txstat.ts_shortretry;
    2455           0 :                         lr = ds->ds_txstat.ts_longretry;
    2456           0 :                         sc->sc_stats.ast_tx_shortretry += sr;
    2457           0 :                         sc->sc_stats.ast_tx_longretry += lr;
    2458             :                         /*
    2459             :                          * Reclaim reference to node.
    2460             :                          *
    2461             :                          * NB: the node may be reclaimed here if, for example
    2462             :                          *     this is a DEAUTH message that was sent and the
    2463             :                          *     node was timed out due to inactivity.
    2464             :                          */
    2465           0 :                         ieee80211_release_node(ic, ni);
    2466           0 :                 }
    2467           0 :                 bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap, 0,
    2468             :                     bf->bf_dmamap->dm_mapsize, BUS_DMASYNC_POSTWRITE);
    2469           0 :                 bus_dmamap_unload(sc->sc_dmat, bf->bf_dmamap);
    2470           0 :                 m_freem(bf->bf_m);
    2471           0 :                 bf->bf_m = NULL;
    2472           0 :                 bf->bf_node = NULL;
    2473             : 
    2474           0 :                 s = splnet();
    2475           0 :                 TAILQ_INSERT_TAIL(&sc->sc_txbuf, bf, bf_list);
    2476           0 :                 splx(s);
    2477             :         }
    2478           0 :         ifq_clr_oactive(&ifp->if_snd);
    2479           0 :         sc->sc_tx_timer = 0;
    2480             : 
    2481           0 :         ath_start(ifp);
    2482           0 : }
    2483             : 
    2484             : /*
    2485             :  * Drain the transmit queue and reclaim resources.
    2486             :  */
    2487             : void
    2488           0 : ath_draintxq(struct ath_softc *sc)
    2489             : {
    2490           0 :         struct ath_hal *ah = sc->sc_ah;
    2491           0 :         struct ieee80211com *ic = &sc->sc_ic;
    2492           0 :         struct ifnet *ifp = &ic->ic_if;
    2493             :         struct ieee80211_node *ni;
    2494             :         struct ath_buf *bf;
    2495             :         int s, i;
    2496             : 
    2497             :         /* XXX return value */
    2498           0 :         if (!sc->sc_invalid) {
    2499           0 :                 for (i = 0; i <= HAL_TX_QUEUE_ID_DATA_MAX; i++) {
    2500             :                         /* don't touch the hardware if marked invalid */
    2501           0 :                         (void) ath_hal_stop_tx_dma(ah, sc->sc_txhalq[i]);
    2502             :                         DPRINTF(ATH_DEBUG_RESET,
    2503             :                             ("%s: tx queue %d (%p), link %p\n", __func__, i,
    2504             :                             (caddr_t)(u_intptr_t)ath_hal_get_tx_buf(ah,
    2505             :                             sc->sc_txhalq[i]), sc->sc_txlink));
    2506             :                 }
    2507           0 :                 (void) ath_hal_stop_tx_dma(ah, sc->sc_bhalq);
    2508             :                 DPRINTF(ATH_DEBUG_RESET,
    2509             :                     ("%s: beacon queue (%p)\n", __func__,
    2510             :                     (caddr_t)(u_intptr_t)ath_hal_get_tx_buf(ah, sc->sc_bhalq)));
    2511           0 :         }
    2512           0 :         for (;;) {
    2513           0 :                 s = splnet();
    2514           0 :                 bf = TAILQ_FIRST(&sc->sc_txq);
    2515           0 :                 if (bf == NULL) {
    2516           0 :                         sc->sc_txlink = NULL;
    2517           0 :                         splx(s);
    2518             :                         break;
    2519             :                 }
    2520           0 :                 TAILQ_REMOVE(&sc->sc_txq, bf, bf_list);
    2521           0 :                 splx(s);
    2522             : #ifdef AR_DEBUG
    2523             :                 if (ath_debug & ATH_DEBUG_RESET) {
    2524             :                         ath_printtxbuf(bf,
    2525             :                             ath_hal_proc_tx_desc(ah, bf->bf_desc) == HAL_OK);
    2526             :                 }
    2527             : #endif /* AR_DEBUG */
    2528           0 :                 bus_dmamap_unload(sc->sc_dmat, bf->bf_dmamap);
    2529           0 :                 m_freem(bf->bf_m);
    2530           0 :                 bf->bf_m = NULL;
    2531           0 :                 ni = bf->bf_node;
    2532           0 :                 bf->bf_node = NULL;
    2533           0 :                 s = splnet();
    2534           0 :                 if (ni != NULL) {
    2535             :                         /*
    2536             :                          * Reclaim node reference.
    2537             :                          */
    2538           0 :                         ieee80211_release_node(ic, ni);
    2539           0 :                 }
    2540           0 :                 TAILQ_INSERT_TAIL(&sc->sc_txbuf, bf, bf_list);
    2541           0 :                 splx(s);
    2542             :         }
    2543           0 :         ifq_clr_oactive(&ifp->if_snd);
    2544           0 :         sc->sc_tx_timer = 0;
    2545           0 : }
    2546             : 
    2547             : /*
    2548             :  * Disable the receive h/w in preparation for a reset.
    2549             :  */
    2550             : void
    2551           0 : ath_stoprecv(struct ath_softc *sc)
    2552             : {
    2553             : #define PA2DESC(_sc, _pa) \
    2554             :         ((struct ath_desc *)((caddr_t)(_sc)->sc_desc + \
    2555             :                 ((_pa) - (_sc)->sc_desc_paddr)))
    2556           0 :         struct ath_hal *ah = sc->sc_ah;
    2557             : 
    2558           0 :         ath_hal_stop_pcu_recv(ah);      /* disable PCU */
    2559           0 :         ath_hal_set_rx_filter(ah, 0);   /* clear recv filter */
    2560           0 :         ath_hal_stop_rx_dma(ah);        /* disable DMA engine */
    2561             : #ifdef AR_DEBUG
    2562             :         if (ath_debug & ATH_DEBUG_RESET) {
    2563             :                 struct ath_buf *bf;
    2564             : 
    2565             :                 printf("%s: rx queue %p, link %p\n", __func__,
    2566             :                     (caddr_t)(u_intptr_t)ath_hal_get_rx_buf(ah), sc->sc_rxlink);
    2567             :                 TAILQ_FOREACH(bf, &sc->sc_rxbuf, bf_list) {
    2568             :                         struct ath_desc *ds = bf->bf_desc;
    2569             :                         if (ath_hal_proc_rx_desc(ah, ds, bf->bf_daddr,
    2570             :                             PA2DESC(sc, ds->ds_link)) == HAL_OK)
    2571             :                                 ath_printrxbuf(bf, 1);
    2572             :                 }
    2573             :         }
    2574             : #endif
    2575           0 :         sc->sc_rxlink = NULL;                /* just in case */
    2576             : #undef PA2DESC
    2577           0 : }
    2578             : 
    2579             : /*
    2580             :  * Enable the receive h/w following a reset.
    2581             :  */
    2582             : int
    2583           0 : ath_startrecv(struct ath_softc *sc)
    2584             : {
    2585           0 :         struct ath_hal *ah = sc->sc_ah;
    2586             :         struct ath_buf *bf;
    2587             : 
    2588           0 :         sc->sc_rxlink = NULL;
    2589           0 :         TAILQ_FOREACH(bf, &sc->sc_rxbuf, bf_list) {
    2590           0 :                 int error = ath_rxbuf_init(sc, bf);
    2591           0 :                 if (error != 0) {
    2592             :                         DPRINTF(ATH_DEBUG_RECV,
    2593             :                             ("%s: ath_rxbuf_init failed %d\n",
    2594             :                             __func__, error));
    2595           0 :                         return error;
    2596             :                 }
    2597           0 :         }
    2598             : 
    2599           0 :         bf = TAILQ_FIRST(&sc->sc_rxbuf);
    2600           0 :         ath_hal_put_rx_buf(ah, bf->bf_daddr);
    2601           0 :         ath_hal_start_rx(ah);           /* enable recv descriptors */
    2602           0 :         ath_mode_init(sc);              /* set filters, etc. */
    2603           0 :         ath_hal_start_rx_pcu(ah);       /* re-enable PCU/DMA engine */
    2604           0 :         return 0;
    2605           0 : }
    2606             : 
    2607             : /*
    2608             :  * Set/change channels.  If the channel is really being changed,
    2609             :  * it's done by resetting the chip.  To accomplish this we must
    2610             :  * first cleanup any pending DMA, then restart stuff after a la
    2611             :  * ath_init.
    2612             :  */
    2613             : int
    2614           0 : ath_chan_set(struct ath_softc *sc, struct ieee80211_channel *chan)
    2615             : {
    2616           0 :         struct ath_hal *ah = sc->sc_ah;
    2617           0 :         struct ieee80211com *ic = &sc->sc_ic;
    2618           0 :         struct ifnet *ifp = &ic->ic_if;
    2619             : 
    2620             :         DPRINTF(ATH_DEBUG_ANY, ("%s: %u (%u MHz) -> %u (%u MHz)\n", __func__,
    2621             :             ieee80211_chan2ieee(ic, ic->ic_ibss_chan),
    2622             :             ic->ic_ibss_chan->ic_freq,
    2623             :             ieee80211_chan2ieee(ic, chan), chan->ic_freq));
    2624           0 :         if (chan != ic->ic_ibss_chan) {
    2625           0 :                 HAL_STATUS status;
    2626           0 :                 HAL_CHANNEL hchan;
    2627             :                 enum ieee80211_phymode mode;
    2628             : 
    2629             :                 /*
    2630             :                  * To switch channels clear any pending DMA operations;
    2631             :                  * wait long enough for the RX fifo to drain, reset the
    2632             :                  * hardware at the new frequency, and then re-enable
    2633             :                  * the relevant bits of the h/w.
    2634             :                  */
    2635           0 :                 ath_hal_set_intr(ah, 0);                /* disable interrupts */
    2636           0 :                 ath_draintxq(sc);               /* clear pending tx frames */
    2637           0 :                 ath_stoprecv(sc);               /* turn off frame recv */
    2638             :                 /*
    2639             :                  * Convert to a HAL channel description.
    2640             :                  */
    2641           0 :                 hchan.channel = chan->ic_freq;
    2642           0 :                 hchan.channelFlags = chan->ic_flags;
    2643           0 :                 if (!ath_hal_reset(ah, ic->ic_opmode, &hchan, AH_TRUE,
    2644             :                     &status)) {
    2645           0 :                         printf("%s: ath_chan_set: unable to reset "
    2646           0 :                                 "channel %u (%u MHz)\n", ifp->if_xname,
    2647           0 :                                 ieee80211_chan2ieee(ic, chan), chan->ic_freq);
    2648           0 :                         return EIO;
    2649             :                 }
    2650           0 :                 ath_set_slot_time(sc);
    2651             :                 /*
    2652             :                  * Re-enable rx framework.
    2653             :                  */
    2654           0 :                 if (ath_startrecv(sc) != 0) {
    2655           0 :                         printf("%s: ath_chan_set: unable to restart recv "
    2656           0 :                             "logic\n", ifp->if_xname);
    2657           0 :                         return EIO;
    2658             :                 }
    2659             : 
    2660             : #if NBPFILTER > 0
    2661             :                 /*
    2662             :                  * Update BPF state.
    2663             :                  */
    2664           0 :                 sc->sc_txtap.wt_chan_freq = sc->sc_rxtap.wr_chan_freq =
    2665           0 :                     htole16(chan->ic_freq);
    2666           0 :                 sc->sc_txtap.wt_chan_flags = sc->sc_rxtap.wr_chan_flags =
    2667           0 :                     htole16(chan->ic_flags);
    2668             : #endif
    2669             : 
    2670             :                 /*
    2671             :                  * Change channels and update the h/w rate map
    2672             :                  * if we're switching; e.g. 11a to 11b/g.
    2673             :                  */
    2674           0 :                 ic->ic_ibss_chan = chan;
    2675           0 :                 mode = ieee80211_chan2mode(ic, chan);
    2676           0 :                 if (mode != sc->sc_curmode)
    2677           0 :                         ath_setcurmode(sc, mode);
    2678             : 
    2679             :                 /*
    2680             :                  * Re-enable interrupts.
    2681             :                  */
    2682           0 :                 ath_hal_set_intr(ah, sc->sc_imask);
    2683           0 :         }
    2684           0 :         return 0;
    2685           0 : }
    2686             : 
    2687             : void
    2688           0 : ath_next_scan(void *arg)
    2689             : {
    2690           0 :         struct ath_softc *sc = arg;
    2691           0 :         struct ieee80211com *ic = &sc->sc_ic;
    2692           0 :         struct ifnet *ifp = &ic->ic_if;
    2693             :         int s;
    2694             : 
    2695             :         /* don't call ath_start w/o network interrupts blocked */
    2696           0 :         s = splnet();
    2697             : 
    2698           0 :         if (ic->ic_state == IEEE80211_S_SCAN)
    2699           0 :                 ieee80211_next_scan(ifp);
    2700           0 :         splx(s);
    2701           0 : }
    2702             : 
    2703             : int
    2704           0 : ath_set_slot_time(struct ath_softc *sc)
    2705             : {
    2706           0 :         struct ath_hal *ah = sc->sc_ah;
    2707           0 :         struct ieee80211com *ic = &sc->sc_ic;
    2708             : 
    2709           0 :         if (ic->ic_flags & IEEE80211_F_SHSLOT)
    2710           0 :                 return (ath_hal_set_slot_time(ah, HAL_SLOT_TIME_9));
    2711             : 
    2712           0 :         return (0);
    2713           0 : }
    2714             : 
    2715             : /*
    2716             :  * Periodically recalibrate the PHY to account
    2717             :  * for temperature/environment changes.
    2718             :  */
    2719             : void
    2720           0 : ath_calibrate(void *arg)
    2721             : {
    2722           0 :         struct ath_softc *sc = arg;
    2723           0 :         struct ath_hal *ah = sc->sc_ah;
    2724           0 :         struct ieee80211com *ic = &sc->sc_ic;
    2725             :         struct ieee80211_channel *c;
    2726           0 :         HAL_CHANNEL hchan;
    2727             :         int s;
    2728             : 
    2729           0 :         sc->sc_stats.ast_per_cal++;
    2730             : 
    2731             :         /*
    2732             :          * Convert to a HAL channel description.
    2733             :          */
    2734           0 :         c = ic->ic_ibss_chan;
    2735           0 :         hchan.channel = c->ic_freq;
    2736           0 :         hchan.channelFlags = c->ic_flags;
    2737             : 
    2738           0 :         s = splnet();
    2739             :         DPRINTF(ATH_DEBUG_CALIBRATE,
    2740             :             ("%s: channel %u/%x\n", __func__, c->ic_freq, c->ic_flags));
    2741             : 
    2742           0 :         if (ath_hal_get_rf_gain(ah) == HAL_RFGAIN_NEED_CHANGE) {
    2743             :                 /*
    2744             :                  * Rfgain is out of bounds, reset the chip
    2745             :                  * to load new gain values.
    2746             :                  */
    2747           0 :                 sc->sc_stats.ast_per_rfgain++;
    2748           0 :                 ath_reset(sc, 1);
    2749           0 :         }
    2750           0 :         if (!ath_hal_calibrate(ah, &hchan)) {
    2751             :                 DPRINTF(ATH_DEBUG_ANY,
    2752             :                     ("%s: calibration of channel %u failed\n",
    2753             :                     __func__, c->ic_freq));
    2754           0 :                 sc->sc_stats.ast_per_calfail++;
    2755           0 :         }
    2756           0 :         timeout_add_sec(&sc->sc_cal_to, ath_calinterval);
    2757           0 :         splx(s);
    2758           0 : }
    2759             : 
    2760             : void
    2761           0 : ath_ledstate(struct ath_softc *sc, enum ieee80211_state state)
    2762             : {
    2763             :         HAL_LED_STATE led = HAL_LED_INIT;
    2764             :         u_int32_t softled = AR5K_SOFTLED_OFF;
    2765             : 
    2766           0 :         switch (state) {
    2767             :         case IEEE80211_S_INIT:
    2768             :                 break;
    2769             :         case IEEE80211_S_SCAN:
    2770             :                 led = HAL_LED_SCAN;
    2771           0 :                 break;
    2772             :         case IEEE80211_S_AUTH:
    2773             :                 led = HAL_LED_AUTH;
    2774           0 :                 break;
    2775             :         case IEEE80211_S_ASSOC:
    2776             :                 led = HAL_LED_ASSOC;
    2777             :                 softled = AR5K_SOFTLED_ON;
    2778           0 :                 break;
    2779             :         case IEEE80211_S_RUN:
    2780             :                 led = HAL_LED_RUN;
    2781             :                 softled = AR5K_SOFTLED_ON;
    2782           0 :                 break;
    2783             :         }
    2784             : 
    2785           0 :         ath_hal_set_ledstate(sc->sc_ah, led);
    2786           0 :         if (sc->sc_softled) {
    2787           0 :                 ath_hal_set_gpio_output(sc->sc_ah, AR5K_SOFTLED_PIN);
    2788           0 :                 ath_hal_set_gpio(sc->sc_ah, AR5K_SOFTLED_PIN, softled);
    2789           0 :         }
    2790           0 : }
    2791             : 
    2792             : int
    2793           0 : ath_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
    2794             : {
    2795           0 :         struct ifnet *ifp = &ic->ic_if;
    2796           0 :         struct ath_softc *sc = ifp->if_softc;
    2797           0 :         struct ath_hal *ah = sc->sc_ah;
    2798             :         struct ieee80211_node *ni;
    2799             :         const u_int8_t *bssid;
    2800             :         int error, i;
    2801             : 
    2802             :         u_int32_t rfilt;
    2803             : 
    2804             :         DPRINTF(ATH_DEBUG_ANY, ("%s: %s -> %s\n", __func__,
    2805             :             ieee80211_state_name[ic->ic_state],
    2806             :             ieee80211_state_name[nstate]));
    2807             : 
    2808           0 :         timeout_del(&sc->sc_scan_to);
    2809           0 :         timeout_del(&sc->sc_cal_to);
    2810           0 :         ath_ledstate(sc, nstate);
    2811             : 
    2812           0 :         if (nstate == IEEE80211_S_INIT) {
    2813           0 :                 timeout_del(&sc->sc_rssadapt_to);
    2814           0 :                 sc->sc_imask &= ~(HAL_INT_SWBA | HAL_INT_BMISS);
    2815           0 :                 ath_hal_set_intr(ah, sc->sc_imask);
    2816           0 :                 return (*sc->sc_newstate)(ic, nstate, arg);
    2817             :         }
    2818           0 :         ni = ic->ic_bss;
    2819           0 :         error = ath_chan_set(sc, ni->ni_chan);
    2820           0 :         if (error != 0)
    2821             :                 goto bad;
    2822           0 :         rfilt = ath_calcrxfilter(sc);
    2823           0 :         if (nstate == IEEE80211_S_SCAN ||
    2824           0 :             ic->ic_opmode == IEEE80211_M_MONITOR) {
    2825           0 :                 bssid = sc->sc_broadcast_addr;
    2826           0 :         } else {
    2827           0 :                 bssid = ni->ni_bssid;
    2828             :         }
    2829           0 :         ath_hal_set_rx_filter(ah, rfilt);
    2830             :         DPRINTF(ATH_DEBUG_ANY, ("%s: RX filter 0x%x bssid %s\n",
    2831             :             __func__, rfilt, ether_sprintf((u_char*)bssid)));
    2832             : 
    2833           0 :         if (nstate == IEEE80211_S_RUN && ic->ic_opmode == IEEE80211_M_STA) {
    2834           0 :                 ath_hal_set_associd(ah, bssid, ni->ni_associd);
    2835           0 :         } else {
    2836           0 :                 ath_hal_set_associd(ah, bssid, 0);
    2837             :         }
    2838             : 
    2839           0 :         if (!ath_softcrypto && (ic->ic_flags & IEEE80211_F_WEPON)) {
    2840           0 :                 for (i = 0; i < IEEE80211_WEP_NKID; i++) {
    2841           0 :                         if (ath_hal_is_key_valid(ah, i))
    2842           0 :                                 ath_hal_set_key_lladdr(ah, i, bssid);
    2843             :                 }
    2844             :         }
    2845             : 
    2846           0 :         if (ic->ic_opmode == IEEE80211_M_MONITOR) {
    2847             :                 /* nothing to do */
    2848           0 :         } else if (nstate == IEEE80211_S_RUN) {
    2849             :                 DPRINTF(ATH_DEBUG_ANY, ("%s(RUN): "
    2850             :                     "ic_flags=0x%08x iv=%d bssid=%s "
    2851             :                     "capinfo=0x%04x chan=%d\n",
    2852             :                     __func__,
    2853             :                     ic->ic_flags,
    2854             :                     ni->ni_intval,
    2855             :                     ether_sprintf(ni->ni_bssid),
    2856             :                     ni->ni_capinfo,
    2857             :                     ieee80211_chan2ieee(ic, ni->ni_chan)));
    2858             : 
    2859             :                 /*
    2860             :                  * Allocate and setup the beacon frame for AP or adhoc mode.
    2861             :                  */
    2862             : #ifndef IEEE80211_STA_ONLY
    2863           0 :                 if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
    2864           0 :                     ic->ic_opmode == IEEE80211_M_IBSS) {
    2865           0 :                         error = ath_beacon_alloc(sc, ni);
    2866           0 :                         if (error != 0)
    2867             :                                 goto bad;
    2868             :                 }
    2869             : #endif
    2870             :                 /*
    2871             :                  * Configure the beacon and sleep timers.
    2872             :                  */
    2873           0 :                 ath_beacon_config(sc);
    2874           0 :         } else {
    2875           0 :                 sc->sc_imask &= ~(HAL_INT_SWBA | HAL_INT_BMISS);
    2876           0 :                 ath_hal_set_intr(ah, sc->sc_imask);
    2877             :         }
    2878             : 
    2879             :         /*
    2880             :          * Invoke the parent method to complete the work.
    2881             :          */
    2882           0 :         error = (*sc->sc_newstate)(ic, nstate, arg);
    2883             : 
    2884           0 :         if (nstate == IEEE80211_S_RUN) {
    2885             :                 /* start periodic recalibration timer */
    2886           0 :                 timeout_add_sec(&sc->sc_cal_to, ath_calinterval);
    2887             : 
    2888           0 :                 if (ic->ic_opmode != IEEE80211_M_MONITOR)
    2889           0 :                         timeout_add_msec(&sc->sc_rssadapt_to, 100);
    2890           0 :         } else if (nstate == IEEE80211_S_SCAN) {
    2891             :                 /* start ap/neighbor scan timer */
    2892           0 :                 timeout_add_msec(&sc->sc_scan_to, ath_dwelltime);
    2893           0 :         }
    2894             : bad:
    2895           0 :         return error;
    2896           0 : }
    2897             : 
    2898             : #ifndef IEEE80211_STA_ONLY
    2899             : void
    2900           0 : ath_recv_mgmt(struct ieee80211com *ic, struct mbuf *m,
    2901             :     struct ieee80211_node *ni, struct ieee80211_rxinfo *rxi, int subtype)
    2902             : {
    2903           0 :         struct ath_softc *sc = (struct ath_softc*)ic->ic_softc;
    2904           0 :         struct ath_hal *ah = sc->sc_ah;
    2905             : 
    2906           0 :         (*sc->sc_recv_mgmt)(ic, m, ni, rxi, subtype);
    2907             : 
    2908           0 :         switch (subtype) {
    2909             :         case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
    2910             :         case IEEE80211_FC0_SUBTYPE_BEACON:
    2911           0 :                 if (ic->ic_opmode != IEEE80211_M_IBSS ||
    2912           0 :                     ic->ic_state != IEEE80211_S_RUN)
    2913             :                         break;
    2914           0 :                 if (ieee80211_ibss_merge(ic, ni, ath_hal_get_tsf64(ah)) ==
    2915             :                     ENETRESET)
    2916           0 :                         ath_hal_set_associd(ah, ic->ic_bss->ni_bssid, 0);
    2917             :                 break;
    2918             :         default:
    2919             :                 break;
    2920             :         }
    2921             :         return;
    2922           0 : }
    2923             : #endif
    2924             : 
    2925             : /*
    2926             :  * Setup driver-specific state for a newly associated node.
    2927             :  * Note that we're called also on a re-associate, the isnew
    2928             :  * param tells us if this is the first time or not.
    2929             :  */
    2930             : void
    2931           0 : ath_newassoc(struct ieee80211com *ic, struct ieee80211_node *ni, int isnew)
    2932             : {
    2933           0 :         if (ic->ic_opmode == IEEE80211_M_MONITOR)
    2934             :                 return;
    2935           0 : }
    2936             : 
    2937             : int
    2938           0 : ath_getchannels(struct ath_softc *sc, HAL_BOOL outdoor, HAL_BOOL xchanmode)
    2939             : {
    2940           0 :         struct ieee80211com *ic = &sc->sc_ic;
    2941           0 :         struct ifnet *ifp = &ic->ic_if;
    2942           0 :         struct ath_hal *ah = sc->sc_ah;
    2943             :         HAL_CHANNEL *chans;
    2944           0 :         int i, ix, nchan;
    2945             : 
    2946           0 :         sc->sc_nchan = 0;
    2947           0 :         chans = malloc(IEEE80211_CHAN_MAX * sizeof(HAL_CHANNEL),
    2948             :                         M_TEMP, M_NOWAIT);
    2949           0 :         if (chans == NULL) {
    2950           0 :                 printf("%s: unable to allocate channel table\n", ifp->if_xname);
    2951           0 :                 return ENOMEM;
    2952             :         }
    2953           0 :         if (!ath_hal_init_channels(ah, chans, IEEE80211_CHAN_MAX, &nchan,
    2954             :             HAL_MODE_ALL, outdoor, xchanmode)) {
    2955           0 :                 printf("%s: unable to collect channel list from hal\n",
    2956           0 :                     ifp->if_xname);
    2957           0 :                 free(chans, M_TEMP, 0);
    2958           0 :                 return EINVAL;
    2959             :         }
    2960             : 
    2961             :         /*
    2962             :          * Convert HAL channels to ieee80211 ones and insert
    2963             :          * them in the table according to their channel number.
    2964             :          */
    2965           0 :         for (i = 0; i < nchan; i++) {
    2966           0 :                 HAL_CHANNEL *c = &chans[i];
    2967           0 :                 ix = ieee80211_mhz2ieee(c->channel, c->channelFlags);
    2968           0 :                 if (ix > IEEE80211_CHAN_MAX) {
    2969           0 :                         printf("%s: bad hal channel %u (%u/%x) ignored\n",
    2970           0 :                                 ifp->if_xname, ix, c->channel, c->channelFlags);
    2971           0 :                         continue;
    2972             :                 }
    2973             :                 DPRINTF(ATH_DEBUG_ANY,
    2974             :                     ("%s: HAL channel %d/%d freq %d flags %#04x idx %d\n",
    2975             :                     sc->sc_dev.dv_xname, i, nchan, c->channel, c->channelFlags,
    2976             :                     ix));
    2977             :                 /* NB: flags are known to be compatible */
    2978           0 :                 if (ic->ic_channels[ix].ic_freq == 0) {
    2979           0 :                         ic->ic_channels[ix].ic_freq = c->channel;
    2980           0 :                         ic->ic_channels[ix].ic_flags = c->channelFlags;
    2981           0 :                 } else {
    2982             :                         /* channels overlap; e.g. 11g and 11b */
    2983           0 :                         ic->ic_channels[ix].ic_flags |= c->channelFlags;
    2984             :                 }
    2985             :                 /* count valid channels */
    2986           0 :                 sc->sc_nchan++;
    2987           0 :         }
    2988           0 :         free(chans, M_TEMP, 0);
    2989             : 
    2990           0 :         if (sc->sc_nchan < 1) {
    2991           0 :                 printf("%s: no valid channels for regdomain %s(%u)\n",
    2992           0 :                     ifp->if_xname, ieee80211_regdomain2name(ah->ah_regdomain),
    2993           0 :                     ah->ah_regdomain);
    2994           0 :                 return ENOENT;
    2995             :         }
    2996             : 
    2997             :         /* set an initial channel */
    2998           0 :         ic->ic_ibss_chan = &ic->ic_channels[0];
    2999             : 
    3000           0 :         return 0;
    3001           0 : }
    3002             : 
    3003             : int
    3004           0 : ath_rate_setup(struct ath_softc *sc, u_int mode)
    3005             : {
    3006           0 :         struct ath_hal *ah = sc->sc_ah;
    3007           0 :         struct ieee80211com *ic = &sc->sc_ic;
    3008             :         const HAL_RATE_TABLE *rt;
    3009             :         struct ieee80211_rateset *rs;
    3010             :         int i, maxrates;
    3011             : 
    3012           0 :         switch (mode) {
    3013             :         case IEEE80211_MODE_11A:
    3014           0 :                 sc->sc_rates[mode] = ath_hal_get_rate_table(ah, HAL_MODE_11A);
    3015           0 :                 break;
    3016             :         case IEEE80211_MODE_11B:
    3017           0 :                 sc->sc_rates[mode] = ath_hal_get_rate_table(ah, HAL_MODE_11B);
    3018           0 :                 break;
    3019             :         case IEEE80211_MODE_11G:
    3020           0 :                 sc->sc_rates[mode] = ath_hal_get_rate_table(ah, HAL_MODE_11G);
    3021           0 :                 break;
    3022             :         default:
    3023             :                 DPRINTF(ATH_DEBUG_ANY,
    3024             :                     ("%s: invalid mode %u\n", __func__, mode));
    3025           0 :                 return 0;
    3026             :         }
    3027           0 :         rt = sc->sc_rates[mode];
    3028           0 :         if (rt == NULL)
    3029           0 :                 return 0;
    3030           0 :         if (rt->rateCount > IEEE80211_RATE_MAXSIZE) {
    3031             :                 DPRINTF(ATH_DEBUG_ANY,
    3032             :                     ("%s: rate table too small (%u > %u)\n",
    3033             :                     __func__, rt->rateCount, IEEE80211_RATE_MAXSIZE));
    3034             :                 maxrates = IEEE80211_RATE_MAXSIZE;
    3035           0 :         } else {
    3036             :                 maxrates = rt->rateCount;
    3037             :         }
    3038           0 :         rs = &ic->ic_sup_rates[mode];
    3039           0 :         for (i = 0; i < maxrates; i++)
    3040           0 :                 rs->rs_rates[i] = rt->info[i].dot11Rate;
    3041           0 :         rs->rs_nrates = maxrates;
    3042           0 :         return 1;
    3043           0 : }
    3044             : 
    3045             : void
    3046           0 : ath_setcurmode(struct ath_softc *sc, enum ieee80211_phymode mode)
    3047             : {
    3048             :         const HAL_RATE_TABLE *rt;
    3049           0 :         struct ieee80211com *ic = &sc->sc_ic;
    3050             :         struct ieee80211_node *ni;
    3051             :         int i;
    3052             : 
    3053           0 :         memset(sc->sc_rixmap, 0xff, sizeof(sc->sc_rixmap));
    3054           0 :         rt = sc->sc_rates[mode];
    3055           0 :         KASSERT(rt != NULL, ("no h/w rate set for phy mode %u", mode));
    3056           0 :         for (i = 0; i < rt->rateCount; i++)
    3057           0 :                 sc->sc_rixmap[rt->info[i].dot11Rate & IEEE80211_RATE_VAL] = i;
    3058           0 :         bzero(sc->sc_hwmap, sizeof(sc->sc_hwmap));
    3059           0 :         for (i = 0; i < 32; i++)
    3060           0 :                 sc->sc_hwmap[i] = rt->info[rt->rateCodeToIndex[i]].dot11Rate;
    3061           0 :         sc->sc_currates = rt;
    3062           0 :         sc->sc_curmode = mode;
    3063           0 :         ni = ic->ic_bss;
    3064           0 :         ni->ni_rates.rs_nrates = sc->sc_currates->rateCount;
    3065           0 :         if (ni->ni_txrate >= ni->ni_rates.rs_nrates)
    3066           0 :                 ni->ni_txrate = 0;
    3067           0 : }
    3068             : 
    3069             : void
    3070           0 : ath_rssadapt_updatenode(void *arg, struct ieee80211_node *ni)
    3071             : {
    3072           0 :         struct ath_node *an = ATH_NODE(ni);
    3073             : 
    3074           0 :         ieee80211_rssadapt_updatestats(&an->an_rssadapt);
    3075           0 : }
    3076             : 
    3077             : void
    3078           0 : ath_rssadapt_updatestats(void *arg)
    3079             : {
    3080           0 :         struct ath_softc *sc = (struct ath_softc *)arg;
    3081           0 :         struct ieee80211com *ic = &sc->sc_ic;
    3082             : 
    3083           0 :         if (ic->ic_opmode == IEEE80211_M_STA) {
    3084           0 :                 ath_rssadapt_updatenode(arg, ic->ic_bss);
    3085           0 :         } else {
    3086           0 :                 ieee80211_iterate_nodes(ic, ath_rssadapt_updatenode, arg);
    3087             :         }
    3088             : 
    3089           0 :         timeout_add_msec(&sc->sc_rssadapt_to, 100);
    3090           0 : }
    3091             : 
    3092             : #ifdef AR_DEBUG
    3093             : void
    3094             : ath_printrxbuf(struct ath_buf *bf, int done)
    3095             : {
    3096             :         struct ath_desc *ds;
    3097             :         int i;
    3098             : 
    3099             :         for (i = 0, ds = bf->bf_desc; i < bf->bf_nseg; i++, ds++) {
    3100             :                 printf("R%d (%p %p) %08x %08x %08x %08x %08x %08x %c\n",
    3101             :                     i, ds, (struct ath_desc *)bf->bf_daddr + i,
    3102             :                     ds->ds_link, ds->ds_data,
    3103             :                     ds->ds_ctl0, ds->ds_ctl1,
    3104             :                     ds->ds_hw[0], ds->ds_hw[1],
    3105             :                     !done ? ' ' : (ds->ds_rxstat.rs_status == 0) ? '*' : '!');
    3106             :         }
    3107             : }
    3108             : 
    3109             : void
    3110             : ath_printtxbuf(struct ath_buf *bf, int done)
    3111             : {
    3112             :         struct ath_desc *ds;
    3113             :         int i;
    3114             : 
    3115             :         for (i = 0, ds = bf->bf_desc; i < bf->bf_nseg; i++, ds++) {
    3116             :                 printf("T%d (%p %p) "
    3117             :                     "%08x %08x %08x %08x %08x %08x %08x %08x %c\n",
    3118             :                     i, ds, (struct ath_desc *)bf->bf_daddr + i,
    3119             :                     ds->ds_link, ds->ds_data,
    3120             :                     ds->ds_ctl0, ds->ds_ctl1,
    3121             :                     ds->ds_hw[0], ds->ds_hw[1], ds->ds_hw[2], ds->ds_hw[3],
    3122             :                     !done ? ' ' : (ds->ds_txstat.ts_status == 0) ? '*' : '!');
    3123             :         }
    3124             : }
    3125             : #endif /* AR_DEBUG */
    3126             : 
    3127             : int
    3128           0 : ath_gpio_attach(struct ath_softc *sc, u_int16_t devid)
    3129             : {
    3130           0 :         struct ath_hal *ah = sc->sc_ah;
    3131             :         struct gpiobus_attach_args gba;
    3132             :         int i;
    3133             : 
    3134           0 :         if (ah->ah_gpio_npins < 1)
    3135           0 :                 return 0;
    3136             : 
    3137             :         /* Initialize gpio pins array */
    3138           0 :         for (i = 0; i < ah->ah_gpio_npins && i < AR5K_MAX_GPIO; i++) {
    3139           0 :                 sc->sc_gpio_pins[i].pin_num = i;
    3140           0 :                 sc->sc_gpio_pins[i].pin_caps = GPIO_PIN_INPUT |
    3141             :                     GPIO_PIN_OUTPUT;
    3142             : 
    3143             :                 /* Set pin mode to input */
    3144           0 :                 ath_hal_set_gpio_input(ah, i);
    3145           0 :                 sc->sc_gpio_pins[i].pin_flags = GPIO_PIN_INPUT;
    3146             : 
    3147             :                 /* Get pin input */
    3148           0 :                 sc->sc_gpio_pins[i].pin_state = ath_hal_get_gpio(ah, i) ?
    3149             :                     GPIO_PIN_HIGH : GPIO_PIN_LOW;
    3150             :         }
    3151             : 
    3152             :         /* Enable GPIO-controlled software LED if available */
    3153           0 :         if ((ah->ah_version == AR5K_AR5211) ||
    3154           0 :             (devid == PCI_PRODUCT_ATHEROS_AR5212_IBM)) {
    3155           0 :                 sc->sc_softled = 1;
    3156           0 :                 ath_hal_set_gpio_output(ah, AR5K_SOFTLED_PIN);
    3157           0 :                 ath_hal_set_gpio(ah, AR5K_SOFTLED_PIN, AR5K_SOFTLED_OFF);
    3158           0 :         }
    3159             : 
    3160             :         /* Create gpio controller tag */
    3161           0 :         sc->sc_gpio_gc.gp_cookie = sc;
    3162           0 :         sc->sc_gpio_gc.gp_pin_read = ath_gpio_pin_read;
    3163           0 :         sc->sc_gpio_gc.gp_pin_write = ath_gpio_pin_write;
    3164           0 :         sc->sc_gpio_gc.gp_pin_ctl = ath_gpio_pin_ctl;
    3165             : 
    3166             :         gba.gba_name = "gpio";
    3167             :         gba.gba_gc = &sc->sc_gpio_gc;
    3168           0 :         gba.gba_pins = sc->sc_gpio_pins;
    3169             :         gba.gba_npins = ah->ah_gpio_npins;
    3170             : 
    3171             : #ifdef notyet
    3172             : #if NGPIO > 0
    3173             :         if (config_found(&sc->sc_dev, &gba, gpiobus_print) == NULL)
    3174             :                 return (ENODEV);
    3175             : #endif
    3176             : #endif
    3177             : 
    3178           0 :         return (0);
    3179           0 : }
    3180             : 
    3181             : int
    3182           0 : ath_gpio_pin_read(void *arg, int pin)
    3183             : {
    3184           0 :         struct ath_softc *sc = arg;
    3185           0 :         struct ath_hal *ah = sc->sc_ah;
    3186           0 :         return (ath_hal_get_gpio(ah, pin) ? GPIO_PIN_HIGH : GPIO_PIN_LOW);
    3187             : }
    3188             : 
    3189             : void
    3190           0 : ath_gpio_pin_write(void *arg, int pin, int value)
    3191             : {
    3192           0 :         struct ath_softc *sc = arg;
    3193           0 :         struct ath_hal *ah = sc->sc_ah;
    3194           0 :         ath_hal_set_gpio(ah, pin, value ? GPIO_PIN_HIGH : GPIO_PIN_LOW);
    3195           0 : }
    3196             : 
    3197             : void
    3198           0 : ath_gpio_pin_ctl(void *arg, int pin, int flags)
    3199             : {
    3200           0 :         struct ath_softc *sc = arg;
    3201           0 :         struct ath_hal *ah = sc->sc_ah;
    3202             : 
    3203           0 :         if (flags & GPIO_PIN_INPUT) {
    3204           0 :                 ath_hal_set_gpio_input(ah, pin);
    3205           0 :         } else if (flags & GPIO_PIN_OUTPUT) {
    3206           0 :                 ath_hal_set_gpio_output(ah, pin);
    3207           0 :         }
    3208           0 : }

Generated by: LCOV version 1.13