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

Cache object: 8b3857bb1c3c539f8a1d2d71b94cb9f1


[ 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.