The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/ic/ath.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 6f980832f81062b83ff505df2afc2a7d


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.