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/iwn/if_iwn.c

Version: -  FREEBSD  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-2  -  FREEBSD-11-1  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-4  -  FREEBSD-10-3  -  FREEBSD-10-2  -  FREEBSD-10-1  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-3  -  FREEBSD-9-2  -  FREEBSD-9-1  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-4  -  FREEBSD-8-3  -  FREEBSD-8-2  -  FREEBSD-8-1  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-4  -  FREEBSD-7-3  -  FREEBSD-7-2  -  FREEBSD-7-1  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-4  -  FREEBSD-6-3  -  FREEBSD-6-2  -  FREEBSD-6-1  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-5  -  FREEBSD-5-4  -  FREEBSD-5-3  -  FREEBSD-5-2  -  FREEBSD-5-1  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 2007
    3  *      Damien Bergamini <damien.bergamini@free.fr>
    4  * Copyright (c) 2008
    5  *      Benjamin Close <benjsc@FreeBSD.org>
    6  * Copyright (c) 2008 Sam Leffler, Errno Consulting
    7  *
    8  * Permission to use, copy, modify, and distribute this software for any
    9  * purpose with or without fee is hereby granted, provided that the above
   10  * copyright notice and this permission notice appear in all copies.
   11  *
   12  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   13  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   14  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   15  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   16  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   17  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   18  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   19  */
   20 
   21 /*
   22  * Driver for Intel Wireless WiFi Link 4965AGN 802.11 network adapters.
   23  */
   24 
   25 #include <sys/cdefs.h>
   26 __FBSDID("$FreeBSD: releng/8.0/sys/dev/iwn/if_iwn.c 195562 2009-07-10 15:28:33Z rpaulo $");
   27 
   28 #include <sys/param.h>
   29 #include <sys/sockio.h>
   30 #include <sys/sysctl.h>
   31 #include <sys/mbuf.h>
   32 #include <sys/kernel.h>
   33 #include <sys/socket.h>
   34 #include <sys/systm.h>
   35 #include <sys/malloc.h>
   36 #include <sys/bus.h>
   37 #include <sys/rman.h>
   38 #include <sys/endian.h>
   39 #include <sys/firmware.h>
   40 #include <sys/limits.h>
   41 #include <sys/module.h>
   42 #include <sys/queue.h>
   43 #include <sys/taskqueue.h>
   44 
   45 #include <machine/bus.h>
   46 #include <machine/resource.h>
   47 #include <machine/clock.h>
   48 
   49 #include <dev/pci/pcireg.h>
   50 #include <dev/pci/pcivar.h>
   51 
   52 #include <net/bpf.h>
   53 #include <net/if.h>
   54 #include <net/if_arp.h>
   55 #include <net/ethernet.h>
   56 #include <net/if_dl.h>
   57 #include <net/if_media.h>
   58 #include <net/if_types.h>
   59 
   60 #include <netinet/in.h>
   61 #include <netinet/in_systm.h>
   62 #include <netinet/in_var.h>
   63 #include <netinet/if_ether.h>
   64 #include <netinet/ip.h>
   65 
   66 #include <net80211/ieee80211_var.h>
   67 #include <net80211/ieee80211_amrr.h>
   68 #include <net80211/ieee80211_radiotap.h>
   69 #include <net80211/ieee80211_regdomain.h>
   70 
   71 #include <dev/iwn/if_iwnreg.h>
   72 #include <dev/iwn/if_iwnvar.h>
   73 
   74 static int      iwn_probe(device_t);
   75 static int      iwn_attach(device_t);
   76 static int      iwn_detach(device_t);
   77 static int      iwn_cleanup(device_t);
   78 static struct ieee80211vap *iwn_vap_create(struct ieee80211com *,
   79                     const char name[IFNAMSIZ], int unit, int opmode,
   80                     int flags, const uint8_t bssid[IEEE80211_ADDR_LEN],
   81                     const uint8_t mac[IEEE80211_ADDR_LEN]);
   82 static void     iwn_vap_delete(struct ieee80211vap *);
   83 static int      iwn_shutdown(device_t);
   84 static int      iwn_suspend(device_t);
   85 static int      iwn_resume(device_t);
   86 static int      iwn_dma_contig_alloc(struct iwn_softc *, struct iwn_dma_info *,
   87                     void **, bus_size_t, bus_size_t, int);
   88 static void     iwn_dma_contig_free(struct iwn_dma_info *);
   89 int             iwn_alloc_shared(struct iwn_softc *);
   90 void            iwn_free_shared(struct iwn_softc *);
   91 int             iwn_alloc_kw(struct iwn_softc *);
   92 void            iwn_free_kw(struct iwn_softc *);
   93 int             iwn_alloc_fwmem(struct iwn_softc *);
   94 void            iwn_free_fwmem(struct iwn_softc *);
   95 struct          iwn_rbuf *iwn_alloc_rbuf(struct iwn_softc *);
   96 void            iwn_free_rbuf(void *, void *);
   97 int             iwn_alloc_rpool(struct iwn_softc *);
   98 void            iwn_free_rpool(struct iwn_softc *);
   99 int             iwn_alloc_rx_ring(struct iwn_softc *, struct iwn_rx_ring *);
  100 void            iwn_reset_rx_ring(struct iwn_softc *, struct iwn_rx_ring *);
  101 void            iwn_free_rx_ring(struct iwn_softc *, struct iwn_rx_ring *);
  102 int             iwn_alloc_tx_ring(struct iwn_softc *, struct iwn_tx_ring *,
  103                     int);
  104 void            iwn_reset_tx_ring(struct iwn_softc *, struct iwn_tx_ring *);
  105 void            iwn_free_tx_ring(struct iwn_softc *, struct iwn_tx_ring *);
  106 static struct ieee80211_node *iwn_node_alloc(struct ieee80211vap *,
  107                     const uint8_t [IEEE80211_ADDR_LEN]);
  108 void            iwn_newassoc(struct ieee80211_node *, int);
  109 int             iwn_media_change(struct ifnet *);
  110 int             iwn_newstate(struct ieee80211vap *, enum ieee80211_state, int);
  111 void            iwn_mem_lock(struct iwn_softc *);
  112 void            iwn_mem_unlock(struct iwn_softc *);
  113 uint32_t        iwn_mem_read(struct iwn_softc *, uint32_t);
  114 void            iwn_mem_write(struct iwn_softc *, uint32_t, uint32_t);
  115 void            iwn_mem_write_region_4(struct iwn_softc *, uint32_t,
  116                     const uint32_t *, int);
  117 int             iwn_eeprom_lock(struct iwn_softc *);
  118 void            iwn_eeprom_unlock(struct iwn_softc *);
  119 int             iwn_read_prom_data(struct iwn_softc *, uint32_t, void *, int);
  120 int             iwn_transfer_microcode(struct iwn_softc *, const uint8_t *, int);
  121 int             iwn_transfer_firmware(struct iwn_softc *);
  122 int             iwn_load_firmware(struct iwn_softc *);
  123 void            iwn_unload_firmware(struct iwn_softc *);
  124 static void     iwn_timer_timeout(void *);
  125 static void     iwn_calib_reset(struct iwn_softc *);
  126 void            iwn_ampdu_rx_start(struct iwn_softc *, struct iwn_rx_desc *);
  127 void            iwn_rx_intr(struct iwn_softc *, struct iwn_rx_desc *,
  128                     struct iwn_rx_data *);
  129 void            iwn_rx_statistics(struct iwn_softc *, struct iwn_rx_desc *);
  130 void            iwn_tx_intr(struct iwn_softc *, struct iwn_rx_desc *);
  131 void            iwn_cmd_intr(struct iwn_softc *, struct iwn_rx_desc *);
  132 void            iwn_notif_intr(struct iwn_softc *);
  133 void            iwn_intr(void *);
  134 void            iwn_read_eeprom(struct iwn_softc *,
  135                     uint8_t macaddr[IEEE80211_ADDR_LEN]);
  136 static void     iwn_read_eeprom_channels(struct iwn_softc *);
  137 void            iwn_print_power_group(struct iwn_softc *, int);
  138 uint8_t         iwn_plcp_signal(int);
  139 int             iwn_tx_data(struct iwn_softc *, struct mbuf *,
  140                     struct ieee80211_node *, struct iwn_tx_ring *);
  141 void            iwn_start(struct ifnet *);
  142 void            iwn_start_locked(struct ifnet *);
  143 static int      iwn_raw_xmit(struct ieee80211_node *, struct mbuf *,
  144                     const struct ieee80211_bpf_params *);
  145 static void     iwn_watchdog(struct iwn_softc *);
  146 int             iwn_ioctl(struct ifnet *, u_long, caddr_t);
  147 int             iwn_cmd(struct iwn_softc *, int, const void *, int, int);
  148 int             iwn_set_link_quality(struct iwn_softc *, uint8_t,
  149                     const struct ieee80211_channel *, int);
  150 int             iwn_set_key(struct ieee80211com *, struct ieee80211_node *,
  151                     const struct ieee80211_key *);
  152 int             iwn_wme_update(struct ieee80211com *);
  153 void            iwn_set_led(struct iwn_softc *, uint8_t, uint8_t, uint8_t);
  154 int             iwn_set_critical_temp(struct iwn_softc *);
  155 void            iwn_enable_tsf(struct iwn_softc *, struct ieee80211_node *);
  156 void            iwn_power_calibration(struct iwn_softc *, int);
  157 int             iwn_set_txpower(struct iwn_softc *,
  158                     struct ieee80211_channel *, int);
  159 int8_t          iwn_get_rssi(struct iwn_softc *, const struct iwn_rx_stat *);
  160 int             iwn_get_noise(const struct iwn_rx_general_stats *);
  161 int             iwn_get_temperature(struct iwn_softc *);
  162 int             iwn_init_sensitivity(struct iwn_softc *);
  163 void            iwn_compute_differential_gain(struct iwn_softc *,
  164                     const struct iwn_rx_general_stats *);
  165 void            iwn_tune_sensitivity(struct iwn_softc *,
  166                     const struct iwn_rx_stats *);
  167 int             iwn_send_sensitivity(struct iwn_softc *);
  168 int             iwn_auth(struct iwn_softc *, struct ieee80211vap *);
  169 int             iwn_run(struct iwn_softc *, struct ieee80211vap *);
  170 int             iwn_scan(struct iwn_softc *);
  171 int             iwn_config(struct iwn_softc *);
  172 void            iwn_post_alive(struct iwn_softc *);
  173 void            iwn_stop_master(struct iwn_softc *);
  174 int             iwn_reset(struct iwn_softc *);
  175 void            iwn_hw_config(struct iwn_softc *);
  176 void            iwn_init_locked(struct iwn_softc *);
  177 void            iwn_init(void *);
  178 void            iwn_stop_locked(struct iwn_softc *);
  179 void            iwn_stop(struct iwn_softc *);
  180 static void     iwn_scan_start(struct ieee80211com *);
  181 static void     iwn_scan_end(struct ieee80211com *);
  182 static void     iwn_set_channel(struct ieee80211com *);
  183 static void     iwn_scan_curchan(struct ieee80211_scan_state *, unsigned long);
  184 static void     iwn_scan_mindwell(struct ieee80211_scan_state *);
  185 static void     iwn_hwreset(void *, int);
  186 static void     iwn_radioon(void *, int);
  187 static void     iwn_radiooff(void *, int);
  188 static void     iwn_sysctlattach(struct iwn_softc *);
  189 
  190 #define IWN_DEBUG
  191 #ifdef IWN_DEBUG
  192 enum {
  193         IWN_DEBUG_XMIT          = 0x00000001,   /* basic xmit operation */
  194         IWN_DEBUG_RECV          = 0x00000002,   /* basic recv operation */
  195         IWN_DEBUG_STATE         = 0x00000004,   /* 802.11 state transitions */
  196         IWN_DEBUG_TXPOW         = 0x00000008,   /* tx power processing */
  197         IWN_DEBUG_RESET         = 0x00000010,   /* reset processing */
  198         IWN_DEBUG_OPS           = 0x00000020,   /* iwn_ops processing */
  199         IWN_DEBUG_BEACON        = 0x00000040,   /* beacon handling */
  200         IWN_DEBUG_WATCHDOG      = 0x00000080,   /* watchdog timeout */
  201         IWN_DEBUG_INTR          = 0x00000100,   /* ISR */
  202         IWN_DEBUG_CALIBRATE     = 0x00000200,   /* periodic calibration */
  203         IWN_DEBUG_NODE          = 0x00000400,   /* node management */
  204         IWN_DEBUG_LED           = 0x00000800,   /* led management */
  205         IWN_DEBUG_CMD           = 0x00001000,   /* cmd submission */
  206         IWN_DEBUG_FATAL         = 0x80000000,   /* fatal errors */
  207         IWN_DEBUG_ANY           = 0xffffffff
  208 };
  209 
  210 #define DPRINTF(sc, m, fmt, ...) do {                   \
  211         if (sc->sc_debug & (m))                         \
  212                 printf(fmt, __VA_ARGS__);               \
  213 } while (0)
  214 
  215 static const char *iwn_intr_str(uint8_t);
  216 #else
  217 #define DPRINTF(sc, m, fmt, ...) do { (void) sc; } while (0)
  218 #endif
  219 
  220 struct iwn_ident {
  221         uint16_t        vendor;
  222         uint16_t        device;
  223         const char      *name;
  224 };
  225 
  226 static const struct iwn_ident iwn_ident_table [] = {
  227         { 0x8086, 0x4229, "Intel(R) PRO/Wireless 4965BGN" },
  228         { 0x8086, 0x422D, "Intel(R) PRO/Wireless 4965BGN" },
  229         { 0x8086, 0x4230, "Intel(R) PRO/Wireless 4965BGN" },
  230         { 0x8086, 0x4233, "Intel(R) PRO/Wireless 4965BGN" },
  231         { 0, 0, NULL }
  232 };
  233 
  234 static int
  235 iwn_probe(device_t dev)
  236 {
  237         const struct iwn_ident *ident;
  238 
  239         for (ident = iwn_ident_table; ident->name != NULL; ident++) {
  240                 if (pci_get_vendor(dev) == ident->vendor &&
  241                     pci_get_device(dev) == ident->device) {
  242                         device_set_desc(dev, ident->name);
  243                         return 0;
  244                 }
  245         }
  246         return ENXIO;
  247 }
  248 
  249 static int
  250 iwn_attach(device_t dev)
  251 {
  252         struct iwn_softc *sc = (struct iwn_softc *)device_get_softc(dev);
  253         struct ieee80211com *ic;
  254         struct ifnet *ifp;
  255         int i, error, result;
  256         uint8_t macaddr[IEEE80211_ADDR_LEN];
  257 
  258         sc->sc_dev = dev;
  259 
  260         /* XXX */
  261         if (pci_get_powerstate(dev) != PCI_POWERSTATE_D0) {
  262                 device_printf(dev, "chip is in D%d power mode "
  263                     "-- setting to D0\n", pci_get_powerstate(dev));
  264                 pci_set_powerstate(dev, PCI_POWERSTATE_D0);
  265         }
  266 
  267         /* clear device specific PCI configuration register 0x41 */
  268         pci_write_config(dev, 0x41, 0, 1);
  269 
  270         /* enable bus-mastering */
  271         pci_enable_busmaster(dev);
  272 
  273         sc->mem_rid= PCIR_BAR(0);
  274         sc->mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->mem_rid,
  275                                          RF_ACTIVE);
  276         if (sc->mem == NULL ) {
  277                 device_printf(dev, "could not allocate memory resources\n");
  278                 error = ENOMEM; 
  279                 return error;
  280         }
  281 
  282         sc->sc_st = rman_get_bustag(sc->mem);
  283         sc->sc_sh = rman_get_bushandle(sc->mem);
  284         sc->irq_rid = 0;
  285         if ((result = pci_msi_count(dev)) == 1 &&
  286             pci_alloc_msi(dev, &result) == 0)
  287                 sc->irq_rid = 1;
  288         sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irq_rid,
  289                                          RF_ACTIVE | RF_SHAREABLE);
  290         if (sc->irq == NULL) {
  291                 device_printf(dev, "could not allocate interrupt resource\n");
  292                 error = ENOMEM;
  293                 return error;
  294         }
  295 
  296         IWN_LOCK_INIT(sc);
  297         callout_init_mtx(&sc->sc_timer_to, &sc->sc_mtx, 0);
  298         TASK_INIT(&sc->sc_reinit_task, 0, iwn_hwreset, sc );
  299         TASK_INIT(&sc->sc_radioon_task, 0, iwn_radioon, sc );
  300         TASK_INIT(&sc->sc_radiooff_task, 0, iwn_radiooff, sc );
  301 
  302         /*
  303          * Put adapter into a known state.
  304          */
  305         error = iwn_reset(sc);
  306         if (error != 0) {
  307                 device_printf(dev,
  308                     "could not reset adapter, error %d\n", error);
  309                 goto fail;
  310         }
  311 
  312         /*
  313          * Allocate DMA memory for firmware transfers.
  314          */
  315         error = iwn_alloc_fwmem(sc);
  316         if (error != 0) {
  317                 device_printf(dev,
  318                     "could not allocate firmware memory, error %d\n", error);
  319                 goto fail;
  320         }
  321 
  322         /*
  323          * Allocate a "keep warm" page.
  324          */
  325         error = iwn_alloc_kw(sc);
  326         if (error != 0) {
  327                 device_printf(dev,
  328                     "could not allocate keep-warm page, error %d\n", error);
  329                 goto fail;
  330         }
  331 
  332         /*
  333          * Allocate shared area (communication area).
  334          */
  335         error = iwn_alloc_shared(sc);
  336         if (error != 0) {
  337                 device_printf(dev,
  338                     "could not allocate shared area, error %d\n", error);
  339                 goto fail;
  340         }
  341 
  342         /*
  343          * Allocate Tx rings.
  344          */
  345         for (i = 0; i < IWN_NTXQUEUES; i++) {
  346                 error = iwn_alloc_tx_ring(sc, &sc->txq[i], i);
  347                 if (error != 0) {
  348                         device_printf(dev,
  349                             "could not allocate Tx ring %d, error %d\n",
  350                             i, error);
  351                         goto fail;
  352                 }
  353         }
  354 
  355         error = iwn_alloc_rx_ring(sc, &sc->rxq);
  356         if (error != 0 ){
  357                 device_printf(dev,
  358                     "could not allocate Rx ring, error %d\n", error);
  359                 goto fail;
  360         }
  361 
  362         ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
  363         if (ifp == NULL) {
  364                 device_printf(dev, "can not allocate ifnet structure\n");
  365                 goto fail;
  366         }
  367         ic = ifp->if_l2com;
  368 
  369         ic->ic_ifp = ifp;       
  370         ic->ic_phytype = IEEE80211_T_OFDM;      /* not only, but not used */
  371         ic->ic_opmode = IEEE80211_M_STA;        /* default to BSS mode */
  372 
  373         /* set device capabilities */
  374         ic->ic_caps =
  375                   IEEE80211_C_STA               /* station mode supported */
  376                 | IEEE80211_C_MONITOR           /* monitor mode supported */
  377                 | IEEE80211_C_TXPMGT            /* tx power management */
  378                 | IEEE80211_C_SHSLOT            /* short slot time supported */
  379                 | IEEE80211_C_WPA
  380                 | IEEE80211_C_SHPREAMBLE        /* short preamble supported */
  381 #if 0
  382                 | IEEE80211_C_BGSCAN            /* background scanning */
  383                 | IEEE80211_C_IBSS              /* ibss/adhoc mode */
  384 #endif
  385                 | IEEE80211_C_WME               /* WME */
  386                 ;
  387 #if 0
  388         /* XXX disable until HT channel setup works */
  389         ic->ic_htcaps =
  390                   IEEE80211_HTCAP_SMPS_ENA      /* SM PS mode enabled */
  391                 | IEEE80211_HTCAP_CHWIDTH40     /* 40MHz channel width */
  392                 | IEEE80211_HTCAP_SHORTGI20     /* short GI in 20MHz */
  393                 | IEEE80211_HTCAP_SHORTGI40     /* short GI in 40MHz */
  394                 | IEEE80211_HTCAP_RXSTBC_2STREAM/* 1-2 spatial streams */
  395                 | IEEE80211_HTCAP_MAXAMSDU_3839 /* max A-MSDU length */
  396                 /* s/w capabilities */
  397                 | IEEE80211_HTC_HT              /* HT operation */
  398                 | IEEE80211_HTC_AMPDU           /* tx A-MPDU */
  399                 | IEEE80211_HTC_AMSDU           /* tx A-MSDU */
  400                 ;
  401 #endif
  402         /* read supported channels and MAC address from EEPROM */
  403         iwn_read_eeprom(sc, macaddr);
  404 
  405         if_initname(ifp, device_get_name(dev), device_get_unit(dev));
  406         ifp->if_softc = sc;
  407         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
  408         ifp->if_init = iwn_init;
  409         ifp->if_ioctl = iwn_ioctl;
  410         ifp->if_start = iwn_start;
  411         IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
  412         ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
  413         IFQ_SET_READY(&ifp->if_snd);
  414 
  415         ieee80211_ifattach(ic, macaddr);
  416         ic->ic_vap_create = iwn_vap_create;
  417         ic->ic_vap_delete = iwn_vap_delete;
  418         ic->ic_raw_xmit = iwn_raw_xmit;
  419         ic->ic_node_alloc = iwn_node_alloc;
  420         ic->ic_newassoc = iwn_newassoc;
  421         ic->ic_wme.wme_update = iwn_wme_update;
  422         ic->ic_scan_start = iwn_scan_start;
  423         ic->ic_scan_end = iwn_scan_end;
  424         ic->ic_set_channel = iwn_set_channel;
  425         ic->ic_scan_curchan = iwn_scan_curchan;
  426         ic->ic_scan_mindwell = iwn_scan_mindwell;
  427 
  428         ieee80211_radiotap_attach(ic,
  429             &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
  430                 IWN_TX_RADIOTAP_PRESENT,
  431             &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
  432                 IWN_RX_RADIOTAP_PRESENT);
  433 
  434         iwn_sysctlattach(sc);
  435 
  436         /*
  437          * Hook our interrupt after all initialization is complete.
  438          */
  439         error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET | INTR_MPSAFE,
  440             NULL, iwn_intr, sc, &sc->sc_ih);
  441         if (error != 0) {
  442                 device_printf(dev, "could not set up interrupt, error %d\n", error);
  443                 goto fail;
  444         }
  445 
  446         ieee80211_announce(ic);
  447         return 0;
  448 fail:
  449         iwn_cleanup(dev);
  450         return error;
  451 }
  452 
  453 static int
  454 iwn_detach(device_t dev)
  455 {
  456         iwn_cleanup(dev);
  457         return 0;
  458 }
  459 
  460 /*
  461  * Cleanup any device resources that were allocated
  462  */
  463 int
  464 iwn_cleanup(device_t dev)
  465 {
  466         struct iwn_softc *sc = device_get_softc(dev);
  467         struct ifnet *ifp = sc->sc_ifp;
  468         struct ieee80211com *ic = ifp->if_l2com;
  469         int i;
  470 
  471         ieee80211_draintask(ic, &sc->sc_reinit_task);
  472         ieee80211_draintask(ic, &sc->sc_radioon_task);
  473         ieee80211_draintask(ic, &sc->sc_radiooff_task);
  474 
  475         if (ifp != NULL) {
  476                 iwn_stop(sc);
  477                 callout_drain(&sc->sc_timer_to);
  478                 ieee80211_ifdetach(ic);
  479         }
  480 
  481         iwn_unload_firmware(sc);
  482 
  483         iwn_free_rx_ring(sc, &sc->rxq);
  484         for (i = 0; i < IWN_NTXQUEUES; i++)
  485                 iwn_free_tx_ring(sc, &sc->txq[i]);
  486         iwn_free_kw(sc);
  487         iwn_free_fwmem(sc);
  488         if (sc->irq != NULL) {
  489                 bus_teardown_intr(dev, sc->irq, sc->sc_ih);
  490                 bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, sc->irq);
  491                 if (sc->irq_rid == 1)
  492                         pci_release_msi(dev);
  493         }
  494         if (sc->mem != NULL)
  495                 bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, sc->mem);
  496         if (ifp != NULL)
  497                 if_free(ifp);
  498         IWN_LOCK_DESTROY(sc);
  499         return 0;
  500 }
  501 
  502 static struct ieee80211vap *
  503 iwn_vap_create(struct ieee80211com *ic,
  504         const char name[IFNAMSIZ], int unit, int opmode, int flags,
  505         const uint8_t bssid[IEEE80211_ADDR_LEN],
  506         const uint8_t mac[IEEE80211_ADDR_LEN])
  507 {
  508         struct iwn_vap *ivp;
  509         struct ieee80211vap *vap;
  510 
  511         if (!TAILQ_EMPTY(&ic->ic_vaps))         /* only one at a time */
  512                 return NULL;
  513         ivp = (struct iwn_vap *) malloc(sizeof(struct iwn_vap),
  514             M_80211_VAP, M_NOWAIT | M_ZERO);
  515         if (ivp == NULL)
  516                 return NULL;
  517         vap = &ivp->iv_vap;
  518         ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
  519         vap->iv_bmissthreshold = 10;            /* override default */
  520         /* override with driver methods */
  521         ivp->iv_newstate = vap->iv_newstate;
  522         vap->iv_newstate = iwn_newstate;
  523 
  524         ieee80211_amrr_init(&ivp->iv_amrr, vap,
  525             IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD,
  526             IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD,
  527             500 /*ms*/);
  528 
  529         /* complete setup */
  530         ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status);
  531         ic->ic_opmode = opmode;
  532         return vap;
  533 }
  534 
  535 static void
  536 iwn_vap_delete(struct ieee80211vap *vap)
  537 {
  538         struct iwn_vap *ivp = IWN_VAP(vap);
  539 
  540         ieee80211_amrr_cleanup(&ivp->iv_amrr);
  541         ieee80211_vap_detach(vap);
  542         free(ivp, M_80211_VAP);
  543 }
  544 
  545 static int
  546 iwn_shutdown(device_t dev)
  547 {
  548         struct iwn_softc *sc = device_get_softc(dev);
  549 
  550         iwn_stop(sc);
  551         return 0;
  552 }
  553 
  554 static int
  555 iwn_suspend(device_t dev)
  556 {
  557         struct iwn_softc *sc = device_get_softc(dev);
  558 
  559         iwn_stop(sc);
  560         return 0;
  561 }
  562 
  563 static int
  564 iwn_resume(device_t dev)
  565 {
  566         struct iwn_softc *sc = device_get_softc(dev);
  567         struct ifnet *ifp = sc->sc_ifp;
  568 
  569         pci_write_config(dev, 0x41, 0, 1);
  570 
  571         if (ifp->if_flags & IFF_UP)
  572                 iwn_init(sc);
  573         return 0;
  574 }
  575 
  576 static void
  577 iwn_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
  578 {
  579         if (error != 0)
  580                 return;
  581         KASSERT(nsegs == 1, ("too many DMA segments, %d should be 1", nsegs));
  582         *(bus_addr_t *)arg = segs[0].ds_addr;
  583 }
  584 
  585 static int 
  586 iwn_dma_contig_alloc(struct iwn_softc *sc, struct iwn_dma_info *dma,
  587         void **kvap, bus_size_t size, bus_size_t alignment, int flags)
  588 {
  589         int error, lalignment, i;
  590 
  591         /*
  592          * FreeBSD can't guarrenty 16k alignment at the moment (11/2007) so
  593          * we allocate an extra 12k with 4k alignement and walk through
  594          * it trying to find where the alignment is. It's a nasty fix for
  595          * a bigger problem.
  596         */
  597         DPRINTF(sc, IWN_DEBUG_RESET,
  598             "Size: %zd - alignment %zd\n", size, alignment);
  599         if (alignment == 0x4000) {
  600                 size += 12*1024;
  601                 lalignment = 4096;
  602                 DPRINTF(sc, IWN_DEBUG_RESET, "%s\n",
  603                     "Attempting to find a 16k boundary");
  604         } else
  605                 lalignment = alignment;
  606         dma->size = size;
  607         dma->tag = NULL;
  608 
  609         error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), lalignment,
  610             0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, size,
  611             1, size, flags, NULL, NULL, &dma->tag);
  612         if (error != 0) {
  613                 device_printf(sc->sc_dev,
  614                     "%s: bus_dma_tag_create failed, error %d\n",
  615                     __func__, error);
  616                 goto fail;
  617         }
  618         error = bus_dmamem_alloc(dma->tag, (void **)&dma->vaddr,
  619             flags | BUS_DMA_ZERO, &dma->map);
  620         if (error != 0) {
  621                 device_printf(sc->sc_dev,
  622                    "%s: bus_dmamem_alloc failed, error %d\n",
  623                    __func__, error);
  624                 goto fail;
  625         }
  626         if (alignment == 0x4000) {
  627                 for (i = 0; i < 3 && (((uintptr_t)dma->vaddr) & 0x3fff); i++) {
  628                         DPRINTF(sc, IWN_DEBUG_RESET,  "%s\n",
  629                             "Memory Unaligned, shifting pointer by 4k");
  630                         dma->vaddr += 4096;
  631                         size -= 4096;
  632                 }
  633                 if ((((uintptr_t)dma->vaddr ) & (alignment-1))) {
  634                         DPRINTF(sc, IWN_DEBUG_ANY,
  635                             "%s: failed to align memory, vaddr %p, align %zd\n",
  636                             __func__, dma->vaddr, alignment);
  637                         error = ENOMEM;
  638                         goto fail;
  639                 }
  640         }
  641 
  642         error = bus_dmamap_load(dma->tag, dma->map, dma->vaddr,
  643             size, iwn_dma_map_addr, &dma->paddr, flags);
  644         if (error != 0) {
  645                 device_printf(sc->sc_dev,
  646                     "%s: bus_dmamap_load failed, error %d\n", __func__, error);
  647                 goto fail;
  648         }
  649 
  650         if (kvap != NULL)
  651                 *kvap = dma->vaddr;
  652         return 0;
  653 fail:
  654         iwn_dma_contig_free(dma);
  655         return error;
  656 }
  657 
  658 static void
  659 iwn_dma_contig_free(struct iwn_dma_info *dma)
  660 {
  661         if (dma->tag != NULL) {
  662                 if (dma->map != NULL) {
  663                         if (dma->paddr == 0) {
  664                                 bus_dmamap_sync(dma->tag, dma->map,
  665                                     BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
  666                                 bus_dmamap_unload(dma->tag, dma->map);
  667                         }
  668                         bus_dmamem_free(dma->tag, &dma->vaddr, dma->map);
  669                 }
  670                 bus_dma_tag_destroy(dma->tag);
  671         }
  672 }
  673 
  674 int
  675 iwn_alloc_shared(struct iwn_softc *sc)
  676 {
  677         /* must be aligned on a 1KB boundary */
  678         return iwn_dma_contig_alloc(sc, &sc->shared_dma,
  679             (void **)&sc->shared, sizeof (struct iwn_shared), 1024,
  680             BUS_DMA_NOWAIT);
  681 }
  682 
  683 void
  684 iwn_free_shared(struct iwn_softc *sc)
  685 {
  686         iwn_dma_contig_free(&sc->shared_dma);
  687 }
  688 
  689 int
  690 iwn_alloc_kw(struct iwn_softc *sc)
  691 {
  692         /* must be aligned on a 4k boundary */
  693         return iwn_dma_contig_alloc(sc, &sc->kw_dma, NULL,
  694             PAGE_SIZE, PAGE_SIZE, BUS_DMA_NOWAIT);
  695 }
  696 
  697 void
  698 iwn_free_kw(struct iwn_softc *sc)
  699 {
  700         iwn_dma_contig_free(&sc->kw_dma);
  701 }
  702 
  703 int
  704 iwn_alloc_fwmem(struct iwn_softc *sc)
  705 {
  706         /* allocate enough contiguous space to store text and data */
  707         return iwn_dma_contig_alloc(sc, &sc->fw_dma, NULL,
  708             IWN_FW_MAIN_TEXT_MAXSZ + IWN_FW_MAIN_DATA_MAXSZ, 16,
  709             BUS_DMA_NOWAIT);
  710 }
  711 
  712 void
  713 iwn_free_fwmem(struct iwn_softc *sc)
  714 {
  715         iwn_dma_contig_free(&sc->fw_dma);
  716 }
  717 
  718 int
  719 iwn_alloc_rx_ring(struct iwn_softc *sc, struct iwn_rx_ring *ring)
  720 {
  721         int i, error;
  722 
  723         ring->cur = 0;
  724 
  725         error = iwn_dma_contig_alloc(sc, &ring->desc_dma,
  726             (void **)&ring->desc, IWN_RX_RING_COUNT * sizeof (uint32_t),
  727             IWN_RING_DMA_ALIGN, BUS_DMA_NOWAIT);
  728         if (error != 0) {
  729                 device_printf(sc->sc_dev,
  730                     "%s: could not allocate rx ring DMA memory, error %d\n",
  731                     __func__, error);
  732                 goto fail;
  733         }
  734 
  735         error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0, 
  736             BUS_SPACE_MAXADDR_32BIT,
  737             BUS_SPACE_MAXADDR, NULL, NULL, MJUMPAGESIZE, 1,
  738             MJUMPAGESIZE, BUS_DMA_NOWAIT, NULL, NULL, &ring->data_dmat);
  739         if (error != 0) {
  740                 device_printf(sc->sc_dev,
  741                     "%s: bus_dma_tag_create_failed, error %d\n",
  742                     __func__, error);
  743                 goto fail;
  744         }
  745 
  746         /*
  747          * Setup Rx buffers.
  748          */
  749         for (i = 0; i < IWN_RX_RING_COUNT; i++) {
  750                 struct iwn_rx_data *data = &ring->data[i];
  751                 struct mbuf *m;
  752                 bus_addr_t paddr;
  753 
  754                 error = bus_dmamap_create(ring->data_dmat, 0, &data->map);
  755                 if (error != 0) {
  756                         device_printf(sc->sc_dev,
  757                             "%s: bus_dmamap_create failed, error %d\n",
  758                             __func__, error);
  759                         goto fail;
  760                 }
  761                 m = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, MJUMPAGESIZE);
  762                 if (m == NULL) {
  763                         device_printf(sc->sc_dev,
  764                            "%s: could not allocate rx mbuf\n", __func__);
  765                         error = ENOMEM;
  766                         goto fail;
  767                 }
  768                 /* map page */
  769                 error = bus_dmamap_load(ring->data_dmat, data->map,
  770                     mtod(m, caddr_t), MJUMPAGESIZE,
  771                     iwn_dma_map_addr, &paddr, BUS_DMA_NOWAIT);
  772                 if (error != 0 && error != EFBIG) {
  773                         device_printf(sc->sc_dev,
  774                             "%s: bus_dmamap_load failed, error %d\n",
  775                             __func__, error);
  776                         m_freem(m);
  777                         error = ENOMEM; /* XXX unique code */
  778                         goto fail;
  779                 }
  780                 bus_dmamap_sync(ring->data_dmat, data->map, 
  781                     BUS_DMASYNC_PREWRITE);
  782 
  783                 data->m = m;
  784                 /* Rx buffers are aligned on a 256-byte boundary */
  785                 ring->desc[i] = htole32(paddr >> 8);
  786         }
  787         bus_dmamap_sync(ring->desc_dma.tag, ring->desc_dma.map,
  788             BUS_DMASYNC_PREWRITE);
  789         return 0;
  790 fail:
  791         iwn_free_rx_ring(sc, ring);
  792         return error;
  793 }
  794 
  795 void
  796 iwn_reset_rx_ring(struct iwn_softc *sc, struct iwn_rx_ring *ring)
  797 {
  798         int ntries;
  799 
  800         iwn_mem_lock(sc);
  801 
  802         IWN_WRITE(sc, IWN_RX_CONFIG, 0);
  803         for (ntries = 0; ntries < 100; ntries++) {
  804                 if (IWN_READ(sc, IWN_RX_STATUS) & IWN_RX_IDLE)
  805                         break;
  806                 DELAY(10);
  807         }
  808 #ifdef IWN_DEBUG
  809         if (ntries == 100)
  810                 DPRINTF(sc, IWN_DEBUG_ANY, "%s\n", "timeout resetting Rx ring");
  811 #endif
  812         iwn_mem_unlock(sc);
  813 
  814         ring->cur = 0;
  815 }
  816 
  817 void
  818 iwn_free_rx_ring(struct iwn_softc *sc, struct iwn_rx_ring *ring)
  819 {
  820         int i;
  821 
  822         iwn_dma_contig_free(&ring->desc_dma);
  823 
  824         for (i = 0; i < IWN_RX_RING_COUNT; i++)
  825                 if (ring->data[i].m != NULL)
  826                         m_freem(ring->data[i].m);
  827 }
  828 
  829 int
  830 iwn_alloc_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring, int qid)
  831 {
  832         bus_size_t size;
  833         int i, error;
  834 
  835         ring->qid = qid;
  836         ring->queued = 0;
  837         ring->cur = 0;
  838 
  839         size = IWN_TX_RING_COUNT * sizeof(struct iwn_tx_desc);
  840         error = iwn_dma_contig_alloc(sc, &ring->desc_dma,
  841             (void **)&ring->desc, size, IWN_RING_DMA_ALIGN, BUS_DMA_NOWAIT);
  842         if (error != 0) {
  843                 device_printf(sc->sc_dev,
  844                     "%s: could not allocate tx ring DMA memory, error %d\n",
  845                     __func__, error);
  846                 goto fail;
  847         }
  848 
  849         size = IWN_TX_RING_COUNT * sizeof(struct iwn_tx_cmd);
  850         error = iwn_dma_contig_alloc(sc, &ring->cmd_dma,
  851             (void **)&ring->cmd, size, 4, BUS_DMA_NOWAIT);
  852         if (error != 0) {
  853                 device_printf(sc->sc_dev,
  854                     "%s: could not allocate tx cmd DMA memory, error %d\n",
  855                     __func__, error);
  856                 goto fail;
  857         }
  858 
  859         error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0, 
  860             BUS_SPACE_MAXADDR_32BIT,
  861             BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES, IWN_MAX_SCATTER - 1,
  862             MCLBYTES, BUS_DMA_NOWAIT, NULL, NULL, &ring->data_dmat);
  863         if (error != 0) {
  864                 device_printf(sc->sc_dev,
  865                     "%s: bus_dma_tag_create_failed, error %d\n",
  866                     __func__, error);
  867                 goto fail;
  868         }
  869 
  870         for (i = 0; i < IWN_TX_RING_COUNT; i++) {
  871                 struct iwn_tx_data *data = &ring->data[i];
  872 
  873                 error = bus_dmamap_create(ring->data_dmat, 0, &data->map);
  874                 if (error != 0) {
  875                         device_printf(sc->sc_dev,
  876                             "%s: bus_dmamap_create failed, error %d\n",
  877                             __func__, error);
  878                         goto fail;
  879                 }
  880                 bus_dmamap_sync(ring->data_dmat, data->map, 
  881                     BUS_DMASYNC_PREWRITE);
  882         }
  883         return 0;
  884 fail:
  885         iwn_free_tx_ring(sc, ring);
  886         return error;
  887 }
  888 
  889 void
  890 iwn_reset_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring)
  891 {
  892         uint32_t tmp;
  893         int i, ntries;
  894 
  895         iwn_mem_lock(sc);
  896 
  897         IWN_WRITE(sc, IWN_TX_CONFIG(ring->qid), 0);
  898         for (ntries = 0; ntries < 20; ntries++) {
  899                 tmp = IWN_READ(sc, IWN_TX_STATUS);
  900                 if ((tmp & IWN_TX_IDLE(ring->qid)) == IWN_TX_IDLE(ring->qid))
  901                         break;
  902                 DELAY(10);
  903         }
  904 #ifdef IWN_DEBUG
  905         if (ntries == 20)
  906                 DPRINTF(sc, IWN_DEBUG_RESET,
  907                     "%s: timeout resetting Tx ring %d\n", __func__, ring->qid);
  908 #endif
  909         iwn_mem_unlock(sc);
  910 
  911         for (i = 0; i < IWN_TX_RING_COUNT; i++) {
  912                 struct iwn_tx_data *data = &ring->data[i];
  913 
  914                 if (data->m != NULL) {
  915                         bus_dmamap_unload(ring->data_dmat, data->map);
  916                         m_freem(data->m);
  917                         data->m = NULL;
  918                 }
  919         }
  920 
  921         ring->queued = 0;
  922         ring->cur = 0;
  923 }
  924 
  925 void
  926 iwn_free_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring)
  927 {
  928         int i;
  929 
  930         iwn_dma_contig_free(&ring->desc_dma);
  931         iwn_dma_contig_free(&ring->cmd_dma);
  932 
  933         if (ring->data != NULL) {
  934                 for (i = 0; i < IWN_TX_RING_COUNT; i++) {
  935                         struct iwn_tx_data *data = &ring->data[i];
  936 
  937                         if (data->m != NULL) {
  938                                 bus_dmamap_unload(ring->data_dmat, data->map);
  939                                 m_freem(data->m);
  940                         }
  941                 }
  942         }
  943 }
  944 
  945 struct ieee80211_node *
  946 iwn_node_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN])
  947 {
  948         return malloc(sizeof (struct iwn_node), M_80211_NODE,M_NOWAIT | M_ZERO);
  949 }
  950 
  951 void
  952 iwn_newassoc(struct ieee80211_node *ni, int isnew)
  953 {
  954         struct ieee80211vap *vap = ni->ni_vap;
  955 
  956         ieee80211_amrr_node_init(&IWN_VAP(vap)->iv_amrr,
  957            &IWN_NODE(ni)->amn, ni);
  958 }
  959 
  960 int
  961 iwn_media_change(struct ifnet *ifp)
  962 {
  963         int error = ieee80211_media_change(ifp);
  964         /* NB: only the fixed rate can change and that doesn't need a reset */
  965         return (error == ENETRESET ? 0 : error);
  966 }
  967 
  968 int
  969 iwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
  970 {
  971         struct iwn_vap *ivp = IWN_VAP(vap);
  972         struct ieee80211com *ic = vap->iv_ic;
  973         struct iwn_softc *sc = ic->ic_ifp->if_softc;
  974         int error;
  975 
  976         DPRINTF(sc, IWN_DEBUG_STATE, "%s: %s -> %s\n", __func__,
  977                 ieee80211_state_name[vap->iv_state],
  978                 ieee80211_state_name[nstate]);
  979 
  980         IEEE80211_UNLOCK(ic);
  981         IWN_LOCK(sc);
  982         callout_stop(&sc->sc_timer_to);
  983 
  984         if (nstate == IEEE80211_S_AUTH && vap->iv_state != IEEE80211_S_AUTH) {
  985                 /* !AUTH -> AUTH requires adapter config */
  986                 error = iwn_auth(sc, vap);
  987         }
  988         if (nstate == IEEE80211_S_RUN && vap->iv_state != IEEE80211_S_RUN) {
  989                 /*
  990                  * !RUN -> RUN requires setting the association id
  991                  * which is done with a firmware cmd.  We also defer
  992                  * starting the timers until that work is done.
  993                  */
  994                 error = iwn_run(sc, vap);
  995         }
  996         if (nstate == IEEE80211_S_RUN) {
  997                 /*
  998                  * RUN -> RUN transition; just restart the timers.
  999                  */
 1000                 iwn_calib_reset(sc);
 1001         }
 1002         IWN_UNLOCK(sc);
 1003         IEEE80211_LOCK(ic);
 1004         return ivp->iv_newstate(vap, nstate, arg);
 1005 }
 1006 
 1007 /*
 1008  * Grab exclusive access to NIC memory.
 1009  */
 1010 void
 1011 iwn_mem_lock(struct iwn_softc *sc)
 1012 {
 1013         uint32_t tmp;
 1014         int ntries;
 1015 
 1016         tmp = IWN_READ(sc, IWN_GPIO_CTL);
 1017         IWN_WRITE(sc, IWN_GPIO_CTL, tmp | IWN_GPIO_MAC);
 1018 
 1019         /* spin until we actually get the lock */
 1020         for (ntries = 0; ntries < 1000; ntries++) {
 1021                 if ((IWN_READ(sc, IWN_GPIO_CTL) &
 1022                     (IWN_GPIO_CLOCK | IWN_GPIO_SLEEP)) == IWN_GPIO_CLOCK)
 1023                         break;
 1024                 DELAY(10);
 1025         }
 1026         if (ntries == 1000)
 1027                 device_printf(sc->sc_dev,
 1028                     "%s: could not lock memory\n", __func__);
 1029 }
 1030 
 1031 /*
 1032  * Release lock on NIC memory.
 1033  */
 1034 void
 1035 iwn_mem_unlock(struct iwn_softc *sc)
 1036 {
 1037         uint32_t tmp = IWN_READ(sc, IWN_GPIO_CTL);
 1038         IWN_WRITE(sc, IWN_GPIO_CTL, tmp & ~IWN_GPIO_MAC);
 1039 }
 1040 
 1041 uint32_t
 1042 iwn_mem_read(struct iwn_softc *sc, uint32_t addr)
 1043 {
 1044         IWN_WRITE(sc, IWN_READ_MEM_ADDR, IWN_MEM_4 | addr);
 1045         return IWN_READ(sc, IWN_READ_MEM_DATA);
 1046 }
 1047 
 1048 void
 1049 iwn_mem_write(struct iwn_softc *sc, uint32_t addr, uint32_t data)
 1050 {
 1051         IWN_WRITE(sc, IWN_WRITE_MEM_ADDR, IWN_MEM_4 | addr);
 1052         IWN_WRITE(sc, IWN_WRITE_MEM_DATA, data);
 1053 }
 1054 
 1055 void
 1056 iwn_mem_write_region_4(struct iwn_softc *sc, uint32_t addr,
 1057     const uint32_t *data, int wlen)
 1058 {
 1059         for (; wlen > 0; wlen--, data++, addr += 4)
 1060                 iwn_mem_write(sc, addr, *data);
 1061 }
 1062 
 1063 int
 1064 iwn_eeprom_lock(struct iwn_softc *sc)
 1065 {
 1066         uint32_t tmp;
 1067         int ntries;
 1068 
 1069         tmp = IWN_READ(sc, IWN_HWCONFIG);
 1070         IWN_WRITE(sc, IWN_HWCONFIG, tmp | IWN_HW_EEPROM_LOCKED);
 1071 
 1072         /* spin until we actually get the lock */
 1073         for (ntries = 0; ntries < 100; ntries++) {
 1074                 if (IWN_READ(sc, IWN_HWCONFIG) & IWN_HW_EEPROM_LOCKED)
 1075                         return 0;
 1076                 DELAY(10);
 1077         }
 1078         return ETIMEDOUT;
 1079 }
 1080 
 1081 void
 1082 iwn_eeprom_unlock(struct iwn_softc *sc)
 1083 {
 1084         uint32_t tmp = IWN_READ(sc, IWN_HWCONFIG);
 1085         IWN_WRITE(sc, IWN_HWCONFIG, tmp & ~IWN_HW_EEPROM_LOCKED);
 1086 }
 1087 
 1088 /*
 1089  * Read `len' bytes from the EEPROM.  We access the EEPROM through the MAC
 1090  * instead of using the traditional bit-bang method.
 1091  */
 1092 int
 1093 iwn_read_prom_data(struct iwn_softc *sc, uint32_t addr, void *data, int len)
 1094 {
 1095         uint8_t *out = data;
 1096         uint32_t val;
 1097         int ntries, tmp;
 1098 
 1099         iwn_mem_lock(sc);
 1100         for (; len > 0; len -= 2, addr++) {
 1101                 IWN_WRITE(sc, IWN_EEPROM_CTL, addr << 2);
 1102                 tmp = IWN_READ(sc, IWN_EEPROM_CTL);     
 1103                 IWN_WRITE(sc, IWN_EEPROM_CTL, tmp & ~IWN_EEPROM_MSK );
 1104 
 1105                 for (ntries = 0; ntries < 10; ntries++) {
 1106                         if ((val = IWN_READ(sc, IWN_EEPROM_CTL)) &
 1107                             IWN_EEPROM_READY)
 1108                                 break;
 1109                         DELAY(5);
 1110                 }
 1111                 if (ntries == 10) {
 1112                         device_printf(sc->sc_dev,"could not read EEPROM\n");
 1113                         return ETIMEDOUT;
 1114                 }
 1115                 *out++ = val >> 16;
 1116                 if (len > 1)
 1117                         *out++ = val >> 24;
 1118         }
 1119         iwn_mem_unlock(sc);
 1120 
 1121         return 0;
 1122 }
 1123 
 1124 /*
 1125  * The firmware boot code is small and is intended to be copied directly into
 1126  * the NIC internal memory.
 1127  */
 1128 int
 1129 iwn_transfer_microcode(struct iwn_softc *sc, const uint8_t *ucode, int size)
 1130 {
 1131         int ntries;
 1132 
 1133         size /= sizeof (uint32_t);
 1134 
 1135         iwn_mem_lock(sc);
 1136 
 1137         /* copy microcode image into NIC memory */
 1138         iwn_mem_write_region_4(sc, IWN_MEM_UCODE_BASE,
 1139             (const uint32_t *)ucode, size);
 1140 
 1141         iwn_mem_write(sc, IWN_MEM_UCODE_SRC, 0);
 1142         iwn_mem_write(sc, IWN_MEM_UCODE_DST, IWN_FW_TEXT);
 1143         iwn_mem_write(sc, IWN_MEM_UCODE_SIZE, size);
 1144 
 1145         /* run microcode */
 1146         iwn_mem_write(sc, IWN_MEM_UCODE_CTL, IWN_UC_RUN);
 1147 
 1148         /* wait for transfer to complete */
 1149         for (ntries = 0; ntries < 1000; ntries++) {
 1150                 if (!(iwn_mem_read(sc, IWN_MEM_UCODE_CTL) & IWN_UC_RUN))
 1151                         break;
 1152                 DELAY(10);
 1153         }
 1154         if (ntries == 1000) {
 1155                 iwn_mem_unlock(sc);
 1156                 device_printf(sc->sc_dev,
 1157                     "%s: could not load boot firmware\n", __func__);
 1158                 return ETIMEDOUT;
 1159         }
 1160         iwn_mem_write(sc, IWN_MEM_UCODE_CTL, IWN_UC_ENABLE);
 1161 
 1162         iwn_mem_unlock(sc);
 1163 
 1164         return 0;
 1165 }
 1166 
 1167 int
 1168 iwn_load_firmware(struct iwn_softc *sc)
 1169 {
 1170         int error;
 1171 
 1172         KASSERT(sc->fw_fp == NULL, ("firmware already loaded"));
 1173 
 1174         IWN_UNLOCK(sc);
 1175         /* load firmware image from disk */
 1176         sc->fw_fp = firmware_get("iwnfw");
 1177         if (sc->fw_fp == NULL) {
 1178                 device_printf(sc->sc_dev,
 1179                     "%s: could not load firmare image \"iwnfw\"\n", __func__);
 1180                 error = EINVAL;
 1181         } else
 1182                 error = 0;
 1183         IWN_LOCK(sc);
 1184         return error;
 1185 }
 1186 
 1187 int
 1188 iwn_transfer_firmware(struct iwn_softc *sc)
 1189 {
 1190         struct iwn_dma_info *dma = &sc->fw_dma;
 1191         const struct iwn_firmware_hdr *hdr;
 1192         const uint8_t *init_text, *init_data, *main_text, *main_data;
 1193         const uint8_t *boot_text;
 1194         uint32_t init_textsz, init_datasz, main_textsz, main_datasz;
 1195         uint32_t boot_textsz;
 1196         int error = 0;
 1197         const struct firmware *fp = sc->fw_fp;
 1198 
 1199         /* extract firmware header information */
 1200         if (fp->datasize < sizeof (struct iwn_firmware_hdr)) {
 1201                 device_printf(sc->sc_dev,
 1202                     "%s: truncated firmware header: %zu bytes, expecting %zu\n",
 1203                     __func__, fp->datasize, sizeof (struct iwn_firmware_hdr));
 1204                 error = EINVAL;
 1205                 goto fail;
 1206         }
 1207         hdr = (const struct iwn_firmware_hdr *)fp->data;
 1208         main_textsz = le32toh(hdr->main_textsz);
 1209         main_datasz = le32toh(hdr->main_datasz);
 1210         init_textsz = le32toh(hdr->init_textsz);
 1211         init_datasz = le32toh(hdr->init_datasz);
 1212         boot_textsz = le32toh(hdr->boot_textsz);
 1213 
 1214         /* sanity-check firmware segments sizes */
 1215         if (main_textsz > IWN_FW_MAIN_TEXT_MAXSZ ||
 1216             main_datasz > IWN_FW_MAIN_DATA_MAXSZ ||
 1217             init_textsz > IWN_FW_INIT_TEXT_MAXSZ ||
 1218             init_datasz > IWN_FW_INIT_DATA_MAXSZ ||
 1219             boot_textsz > IWN_FW_BOOT_TEXT_MAXSZ ||
 1220             (boot_textsz & 3) != 0) {
 1221                 device_printf(sc->sc_dev,
 1222                     "%s: invalid firmware header, main [%d,%d], init [%d,%d] "
 1223                     "boot %d\n", __func__, main_textsz, main_datasz,
 1224                     init_textsz, init_datasz, boot_textsz);
 1225                 error = EINVAL;
 1226                 goto fail;
 1227         }
 1228 
 1229         /* check that all firmware segments are present */
 1230         if (fp->datasize < sizeof (struct iwn_firmware_hdr) + main_textsz +
 1231             main_datasz + init_textsz + init_datasz + boot_textsz) {
 1232                 device_printf(sc->sc_dev, "%s: firmware file too short: "
 1233                     "%zu bytes, main [%d, %d], init [%d,%d] boot %d\n",
 1234                     __func__, fp->datasize, main_textsz, main_datasz,
 1235                     init_textsz, init_datasz, boot_textsz);
 1236                 error = EINVAL;
 1237                 goto fail;
 1238         }
 1239 
 1240         /* get pointers to firmware segments */
 1241         main_text = (const uint8_t *)(hdr + 1);
 1242         main_data = main_text + main_textsz;
 1243         init_text = main_data + main_datasz;
 1244         init_data = init_text + init_textsz;
 1245         boot_text = init_data + init_datasz;
 1246 
 1247         /* copy initialization images into pre-allocated DMA-safe memory */
 1248         memcpy(dma->vaddr, init_data, init_datasz);
 1249         memcpy(dma->vaddr + IWN_FW_INIT_DATA_MAXSZ, init_text, init_textsz);
 1250 
 1251         /* tell adapter where to find initialization images */
 1252         iwn_mem_lock(sc);
 1253         iwn_mem_write(sc, IWN_MEM_DATA_BASE, dma->paddr >> 4);
 1254         iwn_mem_write(sc, IWN_MEM_DATA_SIZE, init_datasz);
 1255         iwn_mem_write(sc, IWN_MEM_TEXT_BASE,
 1256             (dma->paddr + IWN_FW_INIT_DATA_MAXSZ) >> 4);
 1257         iwn_mem_write(sc, IWN_MEM_TEXT_SIZE, init_textsz);
 1258         iwn_mem_unlock(sc);
 1259 
 1260         /* load firmware boot code */
 1261         error = iwn_transfer_microcode(sc, boot_text, boot_textsz);
 1262         if (error != 0) {
 1263                 device_printf(sc->sc_dev,
 1264                     "%s: could not load boot firmware, error %d\n",
 1265                     __func__, error);
 1266                 goto fail;
 1267         }
 1268 
 1269         /* now press "execute" ;-) */
 1270         IWN_WRITE(sc, IWN_RESET, 0);
 1271 
 1272         /* wait at most one second for first alive notification */
 1273         error = msleep(sc, &sc->sc_mtx, PCATCH, "iwninit", hz);
 1274         if (error != 0) {
 1275                 /* this isn't what was supposed to happen.. */
 1276                 device_printf(sc->sc_dev,
 1277                     "%s: timeout waiting for first alive notice, error %d\n",
 1278                     __func__, error);
 1279                 goto fail;
 1280         }
 1281 
 1282         /* copy runtime images into pre-allocated DMA-safe memory */
 1283         memcpy(dma->vaddr, main_data, main_datasz);
 1284         memcpy(dma->vaddr + IWN_FW_MAIN_DATA_MAXSZ, main_text, main_textsz);
 1285 
 1286         /* tell adapter where to find runtime images */
 1287         iwn_mem_lock(sc);
 1288         iwn_mem_write(sc, IWN_MEM_DATA_BASE, dma->paddr >> 4);
 1289         iwn_mem_write(sc, IWN_MEM_DATA_SIZE, main_datasz);
 1290         iwn_mem_write(sc, IWN_MEM_TEXT_BASE,
 1291             (dma->paddr + IWN_FW_MAIN_DATA_MAXSZ) >> 4);
 1292         iwn_mem_write(sc, IWN_MEM_TEXT_SIZE, IWN_FW_UPDATED | main_textsz);
 1293         iwn_mem_unlock(sc);
 1294 
 1295         /* wait at most one second for second alive notification */
 1296         error = msleep(sc, &sc->sc_mtx, PCATCH, "iwninit", hz);
 1297         if (error != 0) {
 1298                 /* this isn't what was supposed to happen.. */
 1299                 device_printf(sc->sc_dev,
 1300                    "%s: timeout waiting for second alive notice, error %d\n",
 1301                    __func__, error);
 1302                 goto fail;
 1303         }
 1304         return 0;
 1305 fail:
 1306         return error;
 1307 }
 1308 
 1309 void
 1310 iwn_unload_firmware(struct iwn_softc *sc)
 1311 {
 1312         if (sc->fw_fp != NULL) {
 1313                 firmware_put(sc->fw_fp, FIRMWARE_UNLOAD);
 1314                 sc->fw_fp = NULL;
 1315         }
 1316 }
 1317 
 1318 static void
 1319 iwn_timer_timeout(void *arg)
 1320 {
 1321         struct iwn_softc *sc = arg;
 1322 
 1323         IWN_LOCK_ASSERT(sc);
 1324 
 1325         if (sc->calib_cnt && --sc->calib_cnt == 0) {
 1326                 DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s\n",
 1327                     "send statistics request");
 1328                 (void) iwn_cmd(sc, IWN_CMD_GET_STATISTICS, NULL, 0, 1);
 1329                 sc->calib_cnt = 60;     /* do calibration every 60s */
 1330         }
 1331         iwn_watchdog(sc);               /* NB: piggyback tx watchdog */
 1332         callout_reset(&sc->sc_timer_to, hz, iwn_timer_timeout, sc);
 1333 }
 1334 
 1335 static void
 1336 iwn_calib_reset(struct iwn_softc *sc)
 1337 {
 1338         callout_reset(&sc->sc_timer_to, hz, iwn_timer_timeout, sc);
 1339         sc->calib_cnt = 60;             /* do calibration every 60s */
 1340 }
 1341 
 1342 void
 1343 iwn_ampdu_rx_start(struct iwn_softc *sc, struct iwn_rx_desc *desc)
 1344 {
 1345         struct iwn_rx_stat *stat;
 1346 
 1347         DPRINTF(sc, IWN_DEBUG_RECV, "%s\n", "received AMPDU stats");
 1348         /* save Rx statistics, they will be used on IWN_AMPDU_RX_DONE */
 1349         stat = (struct iwn_rx_stat *)(desc + 1);
 1350         memcpy(&sc->last_rx_stat, stat, sizeof (*stat));
 1351         sc->last_rx_valid = 1;
 1352 }
 1353 
 1354 static __inline int
 1355 maprate(int iwnrate)
 1356 {
 1357         switch (iwnrate) {
 1358         /* CCK rates */
 1359         case  10: return   2;
 1360         case  20: return   4;
 1361         case  55: return  11;
 1362         case 110: return  22;
 1363         /* OFDM rates */
 1364         case 0xd: return  12;
 1365         case 0xf: return  18;
 1366         case 0x5: return  24;
 1367         case 0x7: return  36;
 1368         case 0x9: return  48;
 1369         case 0xb: return  72;
 1370         case 0x1: return  96;
 1371         case 0x3: return 108;
 1372         /* XXX MCS */
 1373         }
 1374         /* unknown rate: should not happen */
 1375         return 0;
 1376 }
 1377 
 1378 void
 1379 iwn_rx_intr(struct iwn_softc *sc, struct iwn_rx_desc *desc,
 1380     struct iwn_rx_data *data)
 1381 {
 1382         struct ifnet *ifp = sc->sc_ifp;
 1383         struct ieee80211com *ic = ifp->if_l2com;
 1384         struct iwn_rx_ring *ring = &sc->rxq;
 1385         struct ieee80211_frame *wh;
 1386         struct ieee80211_node *ni;
 1387         struct mbuf *m, *mnew;
 1388         struct iwn_rx_stat *stat;
 1389         caddr_t head;
 1390         uint32_t *tail;
 1391         int8_t rssi, nf;
 1392         int len, error;
 1393         bus_addr_t paddr;
 1394 
 1395         if (desc->type == IWN_AMPDU_RX_DONE) {
 1396                 /* check for prior AMPDU_RX_START */
 1397                 if (!sc->last_rx_valid) {
 1398                         DPRINTF(sc, IWN_DEBUG_ANY,
 1399                             "%s: missing AMPDU_RX_START\n", __func__);
 1400                         ifp->if_ierrors++;
 1401                         return;
 1402                 }
 1403                 sc->last_rx_valid = 0;
 1404                 stat = &sc->last_rx_stat;
 1405         } else
 1406                 stat = (struct iwn_rx_stat *)(desc + 1);
 1407 
 1408         if (stat->cfg_phy_len > IWN_STAT_MAXLEN) {
 1409                 device_printf(sc->sc_dev,
 1410                     "%s: invalid rx statistic header, len %d\n",
 1411                     __func__, stat->cfg_phy_len);
 1412                 ifp->if_ierrors++;
 1413                 return;
 1414         }
 1415         if (desc->type == IWN_AMPDU_RX_DONE) {
 1416                 struct iwn_rx_ampdu *ampdu = (struct iwn_rx_ampdu *)(desc + 1);
 1417                 head = (caddr_t)(ampdu + 1);
 1418                 len = le16toh(ampdu->len);
 1419         } else {
 1420                 head = (caddr_t)(stat + 1) + stat->cfg_phy_len;
 1421                 len = le16toh(stat->len);
 1422         }
 1423 
 1424         /* discard Rx frames with bad CRC early */
 1425         tail = (uint32_t *)(head + len);
 1426         if ((le32toh(*tail) & IWN_RX_NOERROR) != IWN_RX_NOERROR) {
 1427                 DPRINTF(sc, IWN_DEBUG_RECV, "%s: rx flags error %x\n",
 1428                     __func__, le32toh(*tail));
 1429                 ifp->if_ierrors++;
 1430                 return;
 1431         }
 1432         if (len < sizeof (struct ieee80211_frame)) {
 1433                 DPRINTF(sc, IWN_DEBUG_RECV, "%s: frame too short: %d\n",
 1434                     __func__, len);
 1435                 ifp->if_ierrors++;
 1436                 return;
 1437         }
 1438 
 1439         /* XXX don't need mbuf, just dma buffer */
 1440         mnew = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, MJUMPAGESIZE);
 1441         if (mnew == NULL) {
 1442                 DPRINTF(sc, IWN_DEBUG_ANY, "%s: no mbuf to restock ring\n",
 1443                     __func__);
 1444                 ifp->if_ierrors++;
 1445                 return;
 1446         }
 1447         error = bus_dmamap_load(ring->data_dmat, data->map,
 1448             mtod(mnew, caddr_t), MJUMPAGESIZE,
 1449             iwn_dma_map_addr, &paddr, BUS_DMA_NOWAIT);
 1450         if (error != 0 && error != EFBIG) {
 1451                 device_printf(sc->sc_dev,
 1452                     "%s: bus_dmamap_load failed, error %d\n", __func__, error);
 1453                 m_freem(mnew);
 1454                 ifp->if_ierrors++;
 1455                 return;
 1456         }
 1457         bus_dmamap_sync(ring->data_dmat, data->map, BUS_DMASYNC_PREWRITE);
 1458 
 1459         /* finalize mbuf and swap in new one */
 1460         m = data->m;
 1461         m->m_pkthdr.rcvif = ifp;
 1462         m->m_data = head;
 1463         m->m_pkthdr.len = m->m_len = len;
 1464 
 1465         data->m = mnew;
 1466         /* update Rx descriptor */
 1467         ring->desc[ring->cur] = htole32(paddr >> 8);
 1468 
 1469         rssi = iwn_get_rssi(sc, stat);
 1470 
 1471         /* grab a reference to the source node */
 1472         wh = mtod(m, struct ieee80211_frame *);
 1473         ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh);
 1474 
 1475         nf = (ni != NULL && ni->ni_vap->iv_state == IEEE80211_S_RUN &&
 1476             (ic->ic_flags & IEEE80211_F_SCAN) == 0) ? sc->noise : -95;
 1477 
 1478         if (ieee80211_radiotap_active(ic)) {
 1479                 struct iwn_rx_radiotap_header *tap = &sc->sc_rxtap;
 1480 
 1481                 tap->wr_tsft = htole64(stat->tstamp);
 1482                 tap->wr_flags = 0;
 1483                 if (stat->flags & htole16(IWN_CONFIG_SHPREAMBLE))
 1484                         tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
 1485                 tap->wr_rate = maprate(stat->rate);
 1486                 tap->wr_dbm_antsignal = rssi;
 1487                 tap->wr_dbm_antnoise = nf;
 1488         }
 1489 
 1490         IWN_UNLOCK(sc);
 1491 
 1492         /* send the frame to the 802.11 layer */
 1493         if (ni != NULL) {
 1494                 (void) ieee80211_input(ni, m, rssi - nf, nf);
 1495                 ieee80211_free_node(ni);
 1496         } else
 1497                 (void) ieee80211_input_all(ic, m, rssi - nf, nf);
 1498 
 1499         IWN_LOCK(sc);
 1500 }
 1501 
 1502 void
 1503 iwn_rx_statistics(struct iwn_softc *sc, struct iwn_rx_desc *desc)
 1504 {
 1505         struct ifnet *ifp = sc->sc_ifp;
 1506         struct ieee80211com *ic = ifp->if_l2com;
 1507         struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
 1508         struct iwn_calib_state *calib = &sc->calib;
 1509         struct iwn_stats *stats = (struct iwn_stats *)(desc + 1);
 1510 
 1511         /* beacon stats are meaningful only when associated and not scanning */
 1512         if (vap->iv_state != IEEE80211_S_RUN ||
 1513             (ic->ic_flags & IEEE80211_F_SCAN))
 1514                 return;
 1515 
 1516         DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: cmd %d\n", __func__, desc->type);
 1517         iwn_calib_reset(sc);
 1518 
 1519         /* test if temperature has changed */
 1520         if (stats->general.temp != sc->rawtemp) {
 1521                 int temp;
 1522 
 1523                 sc->rawtemp = stats->general.temp;
 1524                 temp = iwn_get_temperature(sc);
 1525                 DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: temperature %d\n",
 1526                     __func__, temp);
 1527 
 1528                 /* update Tx power if need be */
 1529                 iwn_power_calibration(sc, temp);
 1530         }
 1531 
 1532         if (desc->type != IWN_BEACON_STATISTICS)
 1533                 return; /* reply to a statistics request */
 1534 
 1535         sc->noise = iwn_get_noise(&stats->rx.general);
 1536         DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: noise %d\n", __func__, sc->noise);
 1537 
 1538         /* test that RSSI and noise are present in stats report */
 1539         if (stats->rx.general.flags != htole32(1)) {
 1540                 DPRINTF(sc, IWN_DEBUG_ANY, "%s\n",
 1541                     "received statistics without RSSI");
 1542                 return;
 1543         }
 1544 
 1545         if (calib->state == IWN_CALIB_STATE_ASSOC)
 1546                 iwn_compute_differential_gain(sc, &stats->rx.general);
 1547         else if (calib->state == IWN_CALIB_STATE_RUN)
 1548                 iwn_tune_sensitivity(sc, &stats->rx);
 1549 }
 1550 
 1551 void
 1552 iwn_tx_intr(struct iwn_softc *sc, struct iwn_rx_desc *desc)
 1553 {
 1554         struct ifnet *ifp = sc->sc_ifp;
 1555         struct iwn_tx_ring *ring = &sc->txq[desc->qid & 0xf];
 1556         struct iwn_tx_data *data = &ring->data[desc->idx];
 1557         struct iwn_tx_stat *stat = (struct iwn_tx_stat *)(desc + 1);
 1558         struct iwn_node *wn = IWN_NODE(data->ni);
 1559         struct mbuf *m;
 1560         struct ieee80211_node *ni;
 1561         uint32_t status;
 1562 
 1563         KASSERT(data->ni != NULL, ("no node"));
 1564 
 1565         DPRINTF(sc, IWN_DEBUG_XMIT, "%s: "
 1566             "qid %d idx %d retries %d nkill %d rate %x duration %d status %x\n",
 1567             __func__, desc->qid, desc->idx, stat->ntries,
 1568             stat->nkill, stat->rate, le16toh(stat->duration),
 1569             le32toh(stat->status));
 1570 
 1571         /*
 1572          * Update rate control statistics for the node.
 1573          */
 1574         status = le32toh(stat->status) & 0xff;
 1575         if (status & 0x80) {
 1576                 DPRINTF(sc, IWN_DEBUG_ANY, "%s: status 0x%x\n",
 1577                     __func__, le32toh(stat->status));
 1578                 ifp->if_oerrors++;
 1579                 ieee80211_amrr_tx_complete(&wn->amn,
 1580                     IEEE80211_AMRR_FAILURE, stat->ntries);
 1581         } else {
 1582                 ieee80211_amrr_tx_complete(&wn->amn,
 1583                     IEEE80211_AMRR_SUCCESS, stat->ntries);
 1584         }
 1585 
 1586         bus_dmamap_sync(ring->data_dmat, data->map, BUS_DMASYNC_POSTWRITE);
 1587         bus_dmamap_unload(ring->data_dmat, data->map);
 1588 
 1589         m = data->m, data->m = NULL;
 1590         ni = data->ni, data->ni = NULL;
 1591 
 1592         if (m->m_flags & M_TXCB) {
 1593                 /*
 1594                  * Channels marked for "radar" require traffic to be received
 1595                  * to unlock before we can transmit.  Until traffic is seen
 1596                  * any attempt to transmit is returned immediately with status
 1597                  * set to IWN_TX_FAIL_TX_LOCKED.  Unfortunately this can easily
 1598                  * happen on first authenticate after scanning.  To workaround
 1599                  * this we ignore a failure of this sort in AUTH state so the
 1600                  * 802.11 layer will fall back to using a timeout to wait for
 1601                  * the AUTH reply.  This allows the firmware time to see
 1602                  * traffic so a subsequent retry of AUTH succeeds.  It's
 1603                  * unclear why the firmware does not maintain state for
 1604                  * channels recently visited as this would allow immediate
 1605                  * use of the channel after a scan (where we see traffic).
 1606                  */
 1607                 if (status == IWN_TX_FAIL_TX_LOCKED &&
 1608                     ni->ni_vap->iv_state == IEEE80211_S_AUTH)
 1609                         ieee80211_process_callback(ni, m, 0);
 1610                 else
 1611                         ieee80211_process_callback(ni, m,
 1612                             (status & IWN_TX_FAIL) != 0);
 1613         }
 1614         m_freem(m);
 1615         ieee80211_free_node(ni);
 1616 
 1617         ring->queued--;
 1618 
 1619         sc->sc_tx_timer = 0;
 1620         ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 1621         iwn_start_locked(ifp);
 1622 }
 1623 
 1624 void
 1625 iwn_cmd_intr(struct iwn_softc *sc, struct iwn_rx_desc *desc)
 1626 {
 1627         struct iwn_tx_ring *ring = &sc->txq[4];
 1628         struct iwn_tx_data *data;
 1629 
 1630         if ((desc->qid & 0xf) != 4)
 1631                 return; /* not a command ack */
 1632 
 1633         data = &ring->data[desc->idx];
 1634 
 1635         /* if the command was mapped in a mbuf, free it */
 1636         if (data->m != NULL) {
 1637                 bus_dmamap_unload(ring->data_dmat, data->map);
 1638                 m_freem(data->m);
 1639                 data->m = NULL;
 1640         }
 1641 
 1642         wakeup(&ring->cmd[desc->idx]);
 1643 }
 1644 
 1645 void
 1646 iwn_notif_intr(struct iwn_softc *sc)
 1647 {
 1648         struct ifnet *ifp = sc->sc_ifp;
 1649         struct ieee80211com *ic = ifp->if_l2com;
 1650         struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
 1651         uint16_t hw;
 1652 
 1653         hw = le16toh(sc->shared->closed_count) & 0xfff;
 1654         while (sc->rxq.cur != hw) {
 1655                 struct iwn_rx_data *data = &sc->rxq.data[sc->rxq.cur];
 1656                 struct iwn_rx_desc *desc = (void *)data->m->m_ext.ext_buf;
 1657 
 1658                 DPRINTF(sc, IWN_DEBUG_RECV,
 1659                     "%s: qid %x idx %d flags %x type %d(%s) len %d\n",
 1660                     __func__, desc->qid, desc->idx, desc->flags,
 1661                     desc->type, iwn_intr_str(desc->type),
 1662                     le16toh(desc->len));
 1663 
 1664                 if (!(desc->qid & 0x80))        /* reply to a command */
 1665                         iwn_cmd_intr(sc, desc);
 1666 
 1667                 switch (desc->type) {
 1668                 case IWN_RX_DONE:
 1669                 case IWN_AMPDU_RX_DONE:
 1670                         iwn_rx_intr(sc, desc, data);
 1671                         break;
 1672 
 1673                 case IWN_AMPDU_RX_START:
 1674                         iwn_ampdu_rx_start(sc, desc);
 1675                         break;
 1676 
 1677                 case IWN_TX_DONE:
 1678                         /* a 802.11 frame has been transmitted */
 1679                         iwn_tx_intr(sc, desc);
 1680                         break;
 1681 
 1682                 case IWN_RX_STATISTICS:
 1683                 case IWN_BEACON_STATISTICS:
 1684                         iwn_rx_statistics(sc, desc);
 1685                         break;
 1686 
 1687                 case IWN_BEACON_MISSED: {
 1688                         struct iwn_beacon_missed *miss =
 1689                             (struct iwn_beacon_missed *)(desc + 1);
 1690                         int misses = le32toh(miss->consecutive);
 1691 
 1692                         /* XXX not sure why we're notified w/ zero */
 1693                         if (misses == 0)
 1694                                 break;
 1695                         DPRINTF(sc, IWN_DEBUG_STATE,
 1696                             "%s: beacons missed %d/%d\n", __func__,
 1697                             misses, le32toh(miss->total));
 1698                         /*
 1699                          * If more than 5 consecutive beacons are missed,
 1700                          * reinitialize the sensitivity state machine.
 1701                          */
 1702                         if (vap->iv_state == IEEE80211_S_RUN && misses > 5)
 1703                                 (void) iwn_init_sensitivity(sc);
 1704                         if (misses >= vap->iv_bmissthreshold)
 1705                                 ieee80211_beacon_miss(ic);
 1706                         break;
 1707                 }
 1708                 case IWN_UC_READY: {
 1709                         struct iwn_ucode_info *uc =
 1710                             (struct iwn_ucode_info *)(desc + 1);
 1711 
 1712                         /* the microcontroller is ready */
 1713                         DPRINTF(sc, IWN_DEBUG_RESET,
 1714                             "microcode alive notification version=%d.%d "
 1715                             "subtype=%x alive=%x\n", uc->major, uc->minor,
 1716                             uc->subtype, le32toh(uc->valid));
 1717 
 1718                         if (le32toh(uc->valid) != 1) {
 1719                                 device_printf(sc->sc_dev,
 1720                                 "microcontroller initialization failed");
 1721                                 break;
 1722                         }
 1723                         if (uc->subtype == IWN_UCODE_INIT) {
 1724                                 /* save microcontroller's report */
 1725                                 memcpy(&sc->ucode_info, uc, sizeof (*uc));
 1726                         }
 1727                         break;
 1728                 }
 1729                 case IWN_STATE_CHANGED: {
 1730                         uint32_t *status = (uint32_t *)(desc + 1);
 1731 
 1732                         /*
 1733                          * State change allows hardware switch change to be
 1734                          * noted. However, we handle this in iwn_intr as we
 1735                          * get both the enable/disble intr.
 1736                          */
 1737                         DPRINTF(sc, IWN_DEBUG_INTR, "state changed to %x\n",
 1738                             le32toh(*status));
 1739                         break;
 1740                 }
 1741                 case IWN_START_SCAN: {
 1742                         struct iwn_start_scan *scan =
 1743                             (struct iwn_start_scan *)(desc + 1);
 1744 
 1745                         DPRINTF(sc, IWN_DEBUG_ANY,
 1746                             "%s: scanning channel %d status %x\n",
 1747                             __func__, scan->chan, le32toh(scan->status));
 1748                         break;
 1749                 }
 1750                 case IWN_STOP_SCAN: {
 1751                         struct iwn_stop_scan *scan =
 1752                             (struct iwn_stop_scan *)(desc + 1);
 1753 
 1754                         DPRINTF(sc, IWN_DEBUG_STATE,
 1755                             "scan finished nchan=%d status=%d chan=%d\n",
 1756                             scan->nchan, scan->status, scan->chan);
 1757 
 1758                         ieee80211_scan_next(vap);
 1759                         break;
 1760                 }
 1761                 }
 1762                 sc->rxq.cur = (sc->rxq.cur + 1) % IWN_RX_RING_COUNT;
 1763         }
 1764 
 1765         /* tell the firmware what we have processed */
 1766         hw = (hw == 0) ? IWN_RX_RING_COUNT - 1 : hw - 1;
 1767         IWN_WRITE(sc, IWN_RX_WIDX, hw & ~7);
 1768 }
 1769 
 1770 static void
 1771 iwn_rftoggle_intr(struct iwn_softc *sc)
 1772 {
 1773         struct ifnet *ifp = sc->sc_ifp;
 1774         struct ieee80211com *ic = ifp->if_l2com;
 1775         uint32_t tmp = IWN_READ(sc, IWN_GPIO_CTL);
 1776 
 1777         IWN_LOCK_ASSERT(sc);
 1778 
 1779         device_printf(sc->sc_dev, "RF switch: radio %s\n",
 1780             (tmp & IWN_GPIO_RF_ENABLED) ? "enabled" : "disabled");
 1781         if (tmp & IWN_GPIO_RF_ENABLED)
 1782                 ieee80211_runtask(ic, &sc->sc_radioon_task);
 1783         else
 1784                 ieee80211_runtask(ic, &sc->sc_radiooff_task);
 1785 }
 1786 
 1787 static void
 1788 iwn_error_intr(struct iwn_softc *sc, uint32_t r1, uint32_t r2)
 1789 {
 1790         struct ifnet *ifp = sc->sc_ifp;
 1791         struct ieee80211com *ic = ifp->if_l2com;
 1792         struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
 1793 
 1794         IWN_LOCK_ASSERT(sc);
 1795 
 1796         device_printf(sc->sc_dev, "error, INTR=%b STATUS=0x%x\n",
 1797             r1, IWN_INTR_BITS, r2);
 1798         if (vap != NULL)
 1799                 ieee80211_cancel_scan(vap);
 1800         ieee80211_runtask(ic, &sc->sc_reinit_task);
 1801 }
 1802 
 1803 void
 1804 iwn_intr(void *arg)
 1805 {
 1806         struct iwn_softc *sc = arg;
 1807         uint32_t r1, r2;
 1808 
 1809         IWN_LOCK(sc);
 1810 
 1811         /* disable interrupts */
 1812         IWN_WRITE(sc, IWN_MASK, 0);
 1813 
 1814         r1 = IWN_READ(sc, IWN_INTR);
 1815         r2 = IWN_READ(sc, IWN_INTR_STATUS);
 1816 
 1817         if (r1 == 0 && r2 == 0) {
 1818                 IWN_WRITE(sc, IWN_MASK, IWN_INTR_MASK);
 1819                 goto done;      /* not for us */
 1820         }
 1821 
 1822         if (r1 == 0xffffffff)
 1823                 goto done;      /* hardware gone */
 1824 
 1825         /* ack interrupts */
 1826         IWN_WRITE(sc, IWN_INTR, r1);
 1827         IWN_WRITE(sc, IWN_INTR_STATUS, r2);
 1828 
 1829         DPRINTF(sc, IWN_DEBUG_INTR, "interrupt reg1=%x reg2=%x\n", r1, r2);
 1830 
 1831         if (r1 & IWN_RF_TOGGLED)
 1832                 iwn_rftoggle_intr(sc);
 1833         if (r1 & IWN_CT_REACHED)
 1834                 device_printf(sc->sc_dev, "critical temperature reached!\n");
 1835         if (r1 & (IWN_SW_ERROR | IWN_HW_ERROR)) {
 1836                 iwn_error_intr(sc, r1, r2);
 1837                 goto done;
 1838         }
 1839         if ((r1 & (IWN_RX_INTR | IWN_SW_RX_INTR)) || (r2 & IWN_RX_STATUS_INTR))
 1840                 iwn_notif_intr(sc);
 1841         if (r1 & IWN_ALIVE_INTR)
 1842                 wakeup(sc);
 1843 
 1844         /* re-enable interrupts */
 1845         IWN_WRITE(sc, IWN_MASK, IWN_INTR_MASK);
 1846 done:
 1847         IWN_UNLOCK(sc);
 1848 }
 1849 
 1850 uint8_t
 1851 iwn_plcp_signal(int rate)
 1852 {
 1853         switch (rate) {
 1854         /* CCK rates (returned values are device-dependent) */
 1855         case 2:         return 10;
 1856         case 4:         return 20;
 1857         case 11:        return 55;
 1858         case 22:        return 110;
 1859 
 1860         /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
 1861         /* R1-R4, (u)ral is R4-R1 */
 1862         case 12:        return 0xd;
 1863         case 18:        return 0xf;
 1864         case 24:        return 0x5;
 1865         case 36:        return 0x7;
 1866         case 48:        return 0x9;
 1867         case 72:        return 0xb;
 1868         case 96:        return 0x1;
 1869         case 108:       return 0x3;
 1870         case 120:       return 0x3;
 1871         }
 1872         /* unknown rate (should not get there) */
 1873         return 0;
 1874 }
 1875 
 1876 /* determine if a given rate is CCK or OFDM */
 1877 #define IWN_RATE_IS_OFDM(rate) ((rate) >= 12 && (rate) != 22)
 1878 
 1879 int
 1880 iwn_tx_data(struct iwn_softc *sc, struct mbuf *m0, struct ieee80211_node *ni,
 1881     struct iwn_tx_ring *ring)
 1882 {
 1883         struct ieee80211vap *vap = ni->ni_vap;
 1884         struct ieee80211com *ic = ni->ni_ic;
 1885         struct ifnet *ifp = sc->sc_ifp;
 1886         const struct ieee80211_txparam *tp;
 1887         struct iwn_tx_desc *desc;
 1888         struct iwn_tx_data *data;
 1889         struct iwn_tx_cmd *cmd;
 1890         struct iwn_cmd_data *tx;
 1891         struct ieee80211_frame *wh;
 1892         struct ieee80211_key *k;
 1893         bus_addr_t paddr;
 1894         uint32_t flags;
 1895         uint16_t timeout;
 1896         uint8_t type;
 1897         u_int hdrlen;
 1898         struct mbuf *mnew;
 1899         int rate, error, pad, nsegs, i, ismcast, id;
 1900         bus_dma_segment_t segs[IWN_MAX_SCATTER];
 1901 
 1902         IWN_LOCK_ASSERT(sc);
 1903 
 1904         wh = mtod(m0, struct ieee80211_frame *);
 1905         type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
 1906         ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
 1907         hdrlen = ieee80211_anyhdrsize(wh);
 1908 
 1909         /* pick a tx rate */
 1910         /* XXX ni_chan */
 1911         tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
 1912         if (type == IEEE80211_FC0_TYPE_MGT)
 1913                 rate = tp->mgmtrate;
 1914         else if (ismcast)
 1915                 rate = tp->mcastrate;
 1916         else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
 1917                 rate = tp->ucastrate;
 1918         else {
 1919                 (void) ieee80211_amrr_choose(ni, &IWN_NODE(ni)->amn);
 1920                 rate = ni->ni_txrate;
 1921         }
 1922 
 1923         if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
 1924                 k = ieee80211_crypto_encap(ni, m0);
 1925                 if (k == NULL) {
 1926                         m_freem(m0);
 1927                         return ENOBUFS;
 1928                 }
 1929                 /* packet header may have moved, reset our local pointer */
 1930                 wh = mtod(m0, struct ieee80211_frame *);
 1931         } else
 1932                 k = NULL;
 1933 
 1934         if (ieee80211_radiotap_active_vap(vap)) {
 1935                 struct iwn_tx_radiotap_header *tap = &sc->sc_txtap;
 1936 
 1937                 tap->wt_flags = 0;
 1938                 tap->wt_rate = rate;
 1939                 if (k != NULL)
 1940                         tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP;
 1941 
 1942                 ieee80211_radiotap_tx(vap, m0);
 1943         }
 1944 
 1945         flags = IWN_TX_AUTO_SEQ;
 1946         /* XXX honor ACM */
 1947         if (!ismcast)
 1948                 flags |= IWN_TX_NEED_ACK;
 1949 
 1950         if (ismcast || type != IEEE80211_FC0_TYPE_DATA)
 1951                 id = IWN_ID_BROADCAST;
 1952         else
 1953                 id = IWN_ID_BSS;
 1954 
 1955         /* check if RTS/CTS or CTS-to-self protection must be used */
 1956         if (!ismcast) {
 1957                 /* multicast frames are not sent at OFDM rates in 802.11b/g */
 1958                 if (m0->m_pkthdr.len+IEEE80211_CRC_LEN > vap->iv_rtsthreshold) {
 1959                         flags |= IWN_TX_NEED_RTS | IWN_TX_FULL_TXOP;
 1960                 } else if ((ic->ic_flags & IEEE80211_F_USEPROT) &&
 1961                     IWN_RATE_IS_OFDM(rate)) {
 1962                         if (ic->ic_protmode == IEEE80211_PROT_CTSONLY)
 1963                                 flags |= IWN_TX_NEED_CTS | IWN_TX_FULL_TXOP;
 1964                         else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
 1965                                 flags |= IWN_TX_NEED_RTS | IWN_TX_FULL_TXOP;
 1966                 }
 1967         }
 1968 
 1969         if (type == IEEE80211_FC0_TYPE_MGT) {
 1970                 uint8_t subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
 1971 
 1972                 /* tell h/w to set timestamp in probe responses */
 1973                 if (subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP)
 1974                         flags |= IWN_TX_INSERT_TSTAMP;
 1975 
 1976                 if (subtype == IEEE80211_FC0_SUBTYPE_ASSOC_REQ ||
 1977                     subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ)
 1978                         timeout = htole16(3);
 1979                 else
 1980                         timeout = htole16(2);
 1981         } else
 1982                 timeout = htole16(0);
 1983 
 1984         if (hdrlen & 3) {
 1985                 /* first segment's length must be a multiple of 4 */
 1986                 flags |= IWN_TX_NEED_PADDING;
 1987                 pad = 4 - (hdrlen & 3);
 1988         } else
 1989                 pad = 0;
 1990 
 1991         desc = &ring->desc[ring->cur];
 1992         data = &ring->data[ring->cur];
 1993 
 1994         cmd = &ring->cmd[ring->cur];
 1995         cmd->code = IWN_CMD_TX_DATA;
 1996         cmd->flags = 0;
 1997         cmd->qid = ring->qid;
 1998         cmd->idx = ring->cur;
 1999 
 2000         tx = (struct iwn_cmd_data *)cmd->data;
 2001         /* NB: no need to bzero tx, all fields are reinitialized here */
 2002         tx->id = id;
 2003         tx->flags = htole32(flags);
 2004         tx->len = htole16(m0->m_pkthdr.len);
 2005         tx->rate = iwn_plcp_signal(rate);
 2006         tx->rts_ntries = 60;            /* XXX? */
 2007         tx->data_ntries = 15;           /* XXX? */
 2008         tx->lifetime = htole32(IWN_LIFETIME_INFINITE);
 2009         tx->timeout = timeout;
 2010 
 2011         if (k != NULL) {
 2012                 /* XXX fill in */;
 2013         } else
 2014                 tx->security = 0;
 2015 
 2016         /* XXX alternate between Ant A and Ant B ? */
 2017         tx->rflags = IWN_RFLAG_ANT_B;
 2018         if (tx->id == IWN_ID_BROADCAST) {
 2019                 tx->ridx = IWN_MAX_TX_RETRIES - 1;
 2020                 if (!IWN_RATE_IS_OFDM(rate))
 2021                         tx->rflags |= IWN_RFLAG_CCK;
 2022         } else {
 2023                 tx->ridx = 0;
 2024                 /* tell adapter to ignore rflags */
 2025                 tx->flags |= htole32(IWN_TX_USE_NODE_RATE);
 2026         }
 2027 
 2028         /* copy and trim IEEE802.11 header */
 2029         memcpy((uint8_t *)(tx + 1), wh, hdrlen);
 2030         m_adj(m0, hdrlen);
 2031 
 2032         error = bus_dmamap_load_mbuf_sg(ring->data_dmat, data->map, m0, segs,
 2033             &nsegs, BUS_DMA_NOWAIT);
 2034         if (error != 0) {
 2035                 if (error == EFBIG) {
 2036                         /* too many fragments, linearize */
 2037                         mnew = m_collapse(m0, M_DONTWAIT, IWN_MAX_SCATTER);
 2038                         if (mnew == NULL) {
 2039                                 IWN_UNLOCK(sc);
 2040                                 device_printf(sc->sc_dev,
 2041                                     "%s: could not defrag mbuf\n", __func__);
 2042                                 m_freem(m0);
 2043                                 return ENOBUFS;
 2044                         }
 2045                         m0 = mnew;
 2046                         error = bus_dmamap_load_mbuf_sg(ring->data_dmat,
 2047                             data->map, m0, segs, &nsegs, BUS_DMA_NOWAIT);
 2048                 }
 2049                 if (error != 0) {
 2050                         IWN_UNLOCK(sc);
 2051                         device_printf(sc->sc_dev,
 2052                             "%s: bus_dmamap_load_mbuf_sg failed, error %d\n",
 2053                              __func__, error);
 2054                         m_freem(m0);
 2055                         return error;
 2056                 }
 2057         }
 2058 
 2059         data->m = m0;
 2060         data->ni = ni;
 2061 
 2062         DPRINTF(sc, IWN_DEBUG_XMIT, "%s: qid %d idx %d len %d nsegs %d\n",
 2063             __func__, ring->qid, ring->cur, m0->m_pkthdr.len, nsegs);
 2064 
 2065         paddr = ring->cmd_dma.paddr + ring->cur * sizeof (struct iwn_tx_cmd);
 2066         tx->loaddr = htole32(paddr + 4 +
 2067             offsetof(struct iwn_cmd_data, ntries));
 2068         tx->hiaddr = 0; /* limit to 32-bit physical addresses */
 2069 
 2070         /* first scatter/gather segment is used by the tx data command */
 2071         IWN_SET_DESC_NSEGS(desc, 1 + nsegs);
 2072         IWN_SET_DESC_SEG(desc, 0, paddr, 4 + sizeof (*tx) + hdrlen + pad);
 2073         for (i = 1; i <= nsegs; i++) {
 2074                 IWN_SET_DESC_SEG(desc, i, segs[i - 1].ds_addr,
 2075                      segs[i - 1].ds_len);
 2076         }
 2077         sc->shared->len[ring->qid][ring->cur] =
 2078             htole16(hdrlen + m0->m_pkthdr.len + 8);
 2079 
 2080         if (ring->cur < IWN_TX_WINDOW)
 2081                 sc->shared->len[ring->qid][ring->cur + IWN_TX_RING_COUNT] =
 2082                         htole16(hdrlen + m0->m_pkthdr.len + 8);
 2083 
 2084         ring->queued++;
 2085 
 2086         /* kick Tx ring */
 2087         ring->cur = (ring->cur + 1) % IWN_TX_RING_COUNT;
 2088         IWN_WRITE(sc, IWN_TX_WIDX, ring->qid << 8 | ring->cur);
 2089 
 2090         ifp->if_opackets++;
 2091         sc->sc_tx_timer = 5;
 2092 
 2093         return 0;
 2094 }
 2095 
 2096 void
 2097 iwn_start(struct ifnet *ifp)
 2098 {
 2099         struct iwn_softc *sc = ifp->if_softc;
 2100 
 2101         IWN_LOCK(sc);
 2102         iwn_start_locked(ifp);
 2103         IWN_UNLOCK(sc);
 2104 }
 2105 
 2106 void
 2107 iwn_start_locked(struct ifnet *ifp)
 2108 {
 2109         struct iwn_softc *sc = ifp->if_softc;
 2110         struct ieee80211_node *ni;
 2111         struct iwn_tx_ring *txq;
 2112         struct mbuf *m;
 2113         int pri;
 2114 
 2115         IWN_LOCK_ASSERT(sc);
 2116 
 2117         for (;;) {
 2118                 IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
 2119                 if (m == NULL)
 2120                         break;
 2121                 ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
 2122                 pri = M_WME_GETAC(m);
 2123                 txq = &sc->txq[pri];
 2124                 if (txq->queued >= IWN_TX_RING_COUNT - 8) {
 2125                         /* XXX not right */
 2126                         /* ring is nearly full, stop flow */
 2127                         ifp->if_drv_flags |= IFF_DRV_OACTIVE;
 2128                 }
 2129                 if (iwn_tx_data(sc, m, ni, txq) != 0) {
 2130                         ifp->if_oerrors++;
 2131                         ieee80211_free_node(ni);
 2132                         break;
 2133                 }
 2134         }
 2135 }
 2136 
 2137 static int
 2138 iwn_tx_handoff(struct iwn_softc *sc,
 2139         struct iwn_tx_ring *ring,
 2140         struct iwn_tx_cmd *cmd,
 2141         struct iwn_cmd_data *tx,
 2142         struct ieee80211_node *ni,
 2143         struct mbuf *m0, u_int hdrlen, int pad)
 2144 {
 2145         struct ifnet *ifp = sc->sc_ifp;
 2146         struct iwn_tx_desc *desc;
 2147         struct iwn_tx_data *data;
 2148         bus_addr_t paddr;
 2149         struct mbuf *mnew;
 2150         int error, nsegs, i;
 2151         bus_dma_segment_t segs[IWN_MAX_SCATTER];
 2152 
 2153         /* copy and trim IEEE802.11 header */
 2154         memcpy((uint8_t *)(tx + 1), mtod(m0, uint8_t *), hdrlen);
 2155         m_adj(m0, hdrlen);
 2156 
 2157         desc = &ring->desc[ring->cur];
 2158         data = &ring->data[ring->cur];
 2159 
 2160         error = bus_dmamap_load_mbuf_sg(ring->data_dmat, data->map, m0, segs,
 2161             &nsegs, BUS_DMA_NOWAIT);
 2162         if (error != 0) {
 2163                 if (error == EFBIG) {
 2164                         /* too many fragments, linearize */
 2165                         mnew = m_collapse(m0, M_DONTWAIT, IWN_MAX_SCATTER);
 2166                         if (mnew == NULL) {
 2167                                 IWN_UNLOCK(sc);
 2168                                 device_printf(sc->sc_dev,
 2169                                     "%s: could not defrag mbuf\n", __func__);
 2170                                 m_freem(m0);
 2171                                 return ENOBUFS;
 2172                         }
 2173                         m0 = mnew;
 2174                         error = bus_dmamap_load_mbuf_sg(ring->data_dmat,
 2175                             data->map, m0, segs, &nsegs, BUS_DMA_NOWAIT);
 2176                 }
 2177                 if (error != 0) {
 2178                         IWN_UNLOCK(sc);
 2179                         device_printf(sc->sc_dev,
 2180                             "%s: bus_dmamap_load_mbuf_sg failed, error %d\n",
 2181                              __func__, error);
 2182                         m_freem(m0);
 2183                         return error;
 2184                 }
 2185         }
 2186 
 2187         data->m = m0;
 2188         data->ni = ni;
 2189 
 2190         DPRINTF(sc, IWN_DEBUG_XMIT, "%s: qid %d idx %d len %d nsegs %d\n",
 2191             __func__, ring->qid, ring->cur, m0->m_pkthdr.len, nsegs);
 2192 
 2193         paddr = ring->cmd_dma.paddr + ring->cur * sizeof (struct iwn_tx_cmd);
 2194         tx->loaddr = htole32(paddr + 4 +
 2195             offsetof(struct iwn_cmd_data, ntries));
 2196         tx->hiaddr = 0; /* limit to 32-bit physical addresses */
 2197 
 2198         /* first scatter/gather segment is used by the tx data command */
 2199         IWN_SET_DESC_NSEGS(desc, 1 + nsegs);
 2200         IWN_SET_DESC_SEG(desc, 0, paddr, 4 + sizeof (*tx) + hdrlen + pad);
 2201         for (i = 1; i <= nsegs; i++) {
 2202                 IWN_SET_DESC_SEG(desc, i, segs[i - 1].ds_addr,
 2203                      segs[i - 1].ds_len);
 2204         }
 2205         sc->shared->len[ring->qid][ring->cur] =
 2206             htole16(hdrlen + m0->m_pkthdr.len + 8);
 2207 
 2208         if (ring->cur < IWN_TX_WINDOW)
 2209                 sc->shared->len[ring->qid][ring->cur + IWN_TX_RING_COUNT] =
 2210                         htole16(hdrlen + m0->m_pkthdr.len + 8);
 2211 
 2212         ring->queued++;
 2213 
 2214         /* kick Tx ring */
 2215         ring->cur = (ring->cur + 1) % IWN_TX_RING_COUNT;
 2216         IWN_WRITE(sc, IWN_TX_WIDX, ring->qid << 8 | ring->cur);
 2217 
 2218         ifp->if_opackets++;
 2219         sc->sc_tx_timer = 5;
 2220 
 2221         return 0;
 2222 }
 2223 
 2224 static int
 2225 iwn_tx_data_raw(struct iwn_softc *sc, struct mbuf *m0,
 2226     struct ieee80211_node *ni, struct iwn_tx_ring *ring,
 2227     const struct ieee80211_bpf_params *params)
 2228 {
 2229         struct ieee80211vap *vap = ni->ni_vap;
 2230         struct ieee80211com *ic = ni->ni_ic;
 2231         struct iwn_tx_cmd *cmd;
 2232         struct iwn_cmd_data *tx;
 2233         struct ieee80211_frame *wh;
 2234         uint32_t flags;
 2235         uint8_t type, subtype;
 2236         u_int hdrlen;
 2237         int rate, pad;
 2238 
 2239         IWN_LOCK_ASSERT(sc);
 2240 
 2241         wh = mtod(m0, struct ieee80211_frame *);
 2242         type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
 2243         subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
 2244         hdrlen = ieee80211_anyhdrsize(wh);
 2245 
 2246         flags = IWN_TX_AUTO_SEQ;
 2247         if ((params->ibp_flags & IEEE80211_BPF_NOACK) == 0)
 2248                 flags |= IWN_TX_NEED_ACK;
 2249         if (params->ibp_flags & IEEE80211_BPF_RTS)
 2250                 flags |= IWN_TX_NEED_RTS | IWN_TX_FULL_TXOP;
 2251         if (params->ibp_flags & IEEE80211_BPF_CTS)
 2252                 flags |= IWN_TX_NEED_CTS | IWN_TX_FULL_TXOP;
 2253         if (type == IEEE80211_FC0_TYPE_MGT &&
 2254             subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP) {
 2255                 /* tell h/w to set timestamp in probe responses */
 2256                 flags |= IWN_TX_INSERT_TSTAMP;
 2257         }
 2258         if (hdrlen & 3) {
 2259                 /* first segment's length must be a multiple of 4 */
 2260                 flags |= IWN_TX_NEED_PADDING;
 2261                 pad = 4 - (hdrlen & 3);
 2262         } else
 2263                 pad = 0;
 2264 
 2265         /* pick a tx rate */
 2266         rate = params->ibp_rate0;
 2267         if (!ieee80211_isratevalid(ic->ic_rt, rate)) {
 2268                 /* XXX fall back to mcast/mgmt rate? */
 2269                 m_freem(m0);
 2270                 return EINVAL;
 2271         }
 2272 
 2273         if (ieee80211_radiotap_active_vap(vap)) {
 2274                 struct iwn_tx_radiotap_header *tap = &sc->sc_txtap;
 2275 
 2276                 tap->wt_flags = 0;
 2277                 tap->wt_rate = rate;
 2278 
 2279                 ieee80211_radiotap_tx(vap, m0);
 2280         }
 2281 
 2282         cmd = &ring->cmd[ring->cur];
 2283         cmd->code = IWN_CMD_TX_DATA;
 2284         cmd->flags = 0;
 2285         cmd->qid = ring->qid;
 2286         cmd->idx = ring->cur;
 2287 
 2288         tx = (struct iwn_cmd_data *)cmd->data;
 2289         /* NB: no need to bzero tx, all fields are reinitialized here */
 2290         tx->id = IWN_ID_BROADCAST;
 2291         tx->flags = htole32(flags);
 2292         tx->len = htole16(m0->m_pkthdr.len);
 2293         tx->rate = iwn_plcp_signal(rate);
 2294         tx->rts_ntries = params->ibp_try1;              /* XXX? */
 2295         tx->data_ntries = params->ibp_try0;
 2296         tx->lifetime = htole32(IWN_LIFETIME_INFINITE);
 2297         /* XXX use try count? */
 2298         if (type == IEEE80211_FC0_TYPE_MGT) {
 2299                 if (subtype == IEEE80211_FC0_SUBTYPE_ASSOC_REQ ||
 2300                     subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ)
 2301                         tx->timeout = htole16(3);
 2302                 else
 2303                         tx->timeout = htole16(2);
 2304         } else
 2305                 tx->timeout = htole16(0);
 2306         tx->security = 0;
 2307         /* XXX alternate between Ant A and Ant B ? */
 2308         tx->rflags = IWN_RFLAG_ANT_B;   /* XXX params->ibp_pri >> 2 */
 2309         tx->ridx = IWN_MAX_TX_RETRIES - 1;
 2310         if (!IWN_RATE_IS_OFDM(rate))
 2311                 tx->rflags |= IWN_RFLAG_CCK;
 2312 
 2313         return iwn_tx_handoff(sc, ring, cmd, tx, ni, m0, hdrlen, pad);
 2314 }
 2315 
 2316 static int
 2317 iwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
 2318         const struct ieee80211_bpf_params *params)
 2319 {
 2320         struct ieee80211com *ic = ni->ni_ic;
 2321         struct ifnet *ifp = ic->ic_ifp;
 2322         struct iwn_softc *sc = ifp->if_softc;
 2323         struct iwn_tx_ring *txq;
 2324         int error;
 2325 
 2326         if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
 2327                 ieee80211_free_node(ni);
 2328                 m_freem(m);
 2329                 return ENETDOWN;
 2330         }
 2331 
 2332         IWN_LOCK(sc);
 2333         if (params == NULL)
 2334                 txq = &sc->txq[M_WME_GETAC(m)];
 2335         else
 2336                 txq = &sc->txq[params->ibp_pri & 3];
 2337         if (txq->queued >= IWN_TX_RING_COUNT - 8) {
 2338                 /* XXX not right */
 2339                 /* ring is nearly full, stop flow */
 2340                 ifp->if_drv_flags |= IFF_DRV_OACTIVE;
 2341         }
 2342         if (params == NULL) {
 2343                 /*
 2344                  * Legacy path; interpret frame contents to decide
 2345                  * precisely how to send the frame.
 2346                  */
 2347                 error = iwn_tx_data(sc, m, ni, txq);
 2348         } else {
 2349                 /*
 2350                  * Caller supplied explicit parameters to use in
 2351                  * sending the frame.
 2352                  */
 2353                 error = iwn_tx_data_raw(sc, m, ni, txq, params);
 2354         }
 2355         if (error != 0) {
 2356                 /* NB: m is reclaimed on tx failure */
 2357                 ieee80211_free_node(ni);
 2358                 ifp->if_oerrors++;
 2359         }
 2360         IWN_UNLOCK(sc);
 2361         return error;
 2362 }
 2363 
 2364 static void
 2365 iwn_watchdog(struct iwn_softc *sc)
 2366 {
 2367         if (sc->sc_tx_timer > 0 && --sc->sc_tx_timer == 0) {
 2368                 struct ifnet *ifp = sc->sc_ifp;
 2369                 struct ieee80211com *ic = ifp->if_l2com;
 2370 
 2371                 if_printf(ifp, "device timeout\n");
 2372                 ieee80211_runtask(ic, &sc->sc_reinit_task);
 2373         }
 2374 }
 2375 
 2376 int
 2377 iwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
 2378 {
 2379         struct iwn_softc *sc = ifp->if_softc;
 2380         struct ieee80211com *ic = ifp->if_l2com;
 2381         struct ifreq *ifr = (struct ifreq *) data;
 2382         int error = 0, startall = 0;
 2383 
 2384         switch (cmd) {
 2385         case SIOCSIFFLAGS:
 2386                 IWN_LOCK(sc);
 2387                 if (ifp->if_flags & IFF_UP) {
 2388                         if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
 2389                                 iwn_init_locked(sc);
 2390                                 startall = 1;
 2391                         }
 2392                 } else {
 2393                         if (ifp->if_drv_flags & IFF_DRV_RUNNING)
 2394                                 iwn_stop_locked(sc);
 2395                 }
 2396                 IWN_UNLOCK(sc);
 2397                 if (startall)
 2398                         ieee80211_start_all(ic);
 2399                 break;
 2400         case SIOCGIFMEDIA:
 2401                 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
 2402                 break;
 2403         case SIOCGIFADDR:
 2404                 error = ether_ioctl(ifp, cmd, data);
 2405                 break;
 2406         default:
 2407                 error = EINVAL;
 2408                 break;
 2409         }
 2410         return error;
 2411 }
 2412 
 2413 void
 2414 iwn_read_eeprom(struct iwn_softc *sc, uint8_t macaddr[IEEE80211_ADDR_LEN])
 2415 {
 2416         char domain[4];
 2417         uint16_t val;
 2418         int i, error;
 2419 
 2420         if ((error = iwn_eeprom_lock(sc)) != 0) {
 2421                 device_printf(sc->sc_dev,
 2422                     "%s: could not lock EEPROM, error %d\n", __func__, error);
 2423                 return;
 2424         }
 2425         /* read and print regulatory domain */
 2426         iwn_read_prom_data(sc, IWN_EEPROM_DOMAIN, domain, 4);
 2427         device_printf(sc->sc_dev,"Reg Domain: %.4s", domain);
 2428 
 2429         /* read and print MAC address */
 2430         iwn_read_prom_data(sc, IWN_EEPROM_MAC, macaddr, 6);
 2431         printf(", address %6D\n", macaddr, ":");
 2432 
 2433         /* read the list of authorized channels */
 2434         iwn_read_eeprom_channels(sc);
 2435 
 2436         /* read maximum allowed Tx power for 2GHz and 5GHz bands */
 2437         iwn_read_prom_data(sc, IWN_EEPROM_MAXPOW, &val, 2);
 2438         sc->maxpwr2GHz = val & 0xff;
 2439         sc->maxpwr5GHz = val >> 8;
 2440         /* check that EEPROM values are correct */
 2441         if (sc->maxpwr5GHz < 20 || sc->maxpwr5GHz > 50)
 2442                 sc->maxpwr5GHz = 38;
 2443         if (sc->maxpwr2GHz < 20 || sc->maxpwr2GHz > 50)
 2444                 sc->maxpwr2GHz = 38;
 2445         DPRINTF(sc, IWN_DEBUG_RESET, "maxpwr 2GHz=%d 5GHz=%d\n",
 2446             sc->maxpwr2GHz, sc->maxpwr5GHz);
 2447 
 2448         /* read voltage at which samples were taken */
 2449         iwn_read_prom_data(sc, IWN_EEPROM_VOLTAGE, &val, 2);
 2450         sc->eeprom_voltage = (int16_t)le16toh(val);
 2451         DPRINTF(sc, IWN_DEBUG_RESET, "voltage=%d (in 0.3V)\n",
 2452             sc->eeprom_voltage);
 2453 
 2454         /* read power groups */
 2455         iwn_read_prom_data(sc, IWN_EEPROM_BANDS, sc->bands, sizeof sc->bands);
 2456 #ifdef IWN_DEBUG
 2457         if (sc->sc_debug & IWN_DEBUG_ANY) {
 2458                 for (i = 0; i < IWN_NBANDS; i++)
 2459                         iwn_print_power_group(sc, i);
 2460         }
 2461 #endif
 2462         iwn_eeprom_unlock(sc);
 2463 }
 2464 
 2465 struct iwn_chan_band {
 2466         uint32_t        addr;   /* offset in EEPROM */
 2467         uint32_t        flags;  /* net80211 flags */
 2468         uint8_t         nchan;
 2469 #define IWN_MAX_CHAN_PER_BAND   14
 2470         uint8_t         chan[IWN_MAX_CHAN_PER_BAND];
 2471 };
 2472 
 2473 static void
 2474 iwn_read_eeprom_band(struct iwn_softc *sc, const struct iwn_chan_band *band)
 2475 {
 2476         struct ifnet *ifp = sc->sc_ifp;
 2477         struct ieee80211com *ic = ifp->if_l2com;
 2478         struct iwn_eeprom_chan channels[IWN_MAX_CHAN_PER_BAND];
 2479         struct ieee80211_channel *c;
 2480         int i, chan, flags;
 2481 
 2482         iwn_read_prom_data(sc, band->addr, channels,
 2483             band->nchan * sizeof (struct iwn_eeprom_chan));
 2484 
 2485         for (i = 0; i < band->nchan; i++) {
 2486                 if (!(channels[i].flags & IWN_EEPROM_CHAN_VALID)) {
 2487                         DPRINTF(sc, IWN_DEBUG_RESET,
 2488                             "skip chan %d flags 0x%x maxpwr %d\n",
 2489                             band->chan[i], channels[i].flags,
 2490                             channels[i].maxpwr);
 2491                         continue;
 2492                 }
 2493                 chan = band->chan[i];
 2494 
 2495                 /* translate EEPROM flags to net80211 */
 2496                 flags = 0;
 2497                 if ((channels[i].flags & IWN_EEPROM_CHAN_ACTIVE) == 0)
 2498                         flags |= IEEE80211_CHAN_PASSIVE;
 2499                 if ((channels[i].flags & IWN_EEPROM_CHAN_IBSS) == 0)
 2500                         flags |= IEEE80211_CHAN_NOADHOC;
 2501                 if (channels[i].flags & IWN_EEPROM_CHAN_RADAR) {
 2502                         flags |= IEEE80211_CHAN_DFS;
 2503                         /* XXX apparently IBSS may still be marked */
 2504                         flags |= IEEE80211_CHAN_NOADHOC;
 2505                 }
 2506 
 2507                 DPRINTF(sc, IWN_DEBUG_RESET,
 2508                     "add chan %d flags 0x%x maxpwr %d\n",
 2509                     chan, channels[i].flags, channels[i].maxpwr);
 2510 
 2511                 c = &ic->ic_channels[ic->ic_nchans++];
 2512                 c->ic_ieee = chan;
 2513                 c->ic_freq = ieee80211_ieee2mhz(chan, band->flags);
 2514                 c->ic_maxregpower = channels[i].maxpwr;
 2515                 c->ic_maxpower = 2*c->ic_maxregpower;
 2516                 if (band->flags & IEEE80211_CHAN_2GHZ) {
 2517                         /* G =>'s B is supported */
 2518                         c->ic_flags = IEEE80211_CHAN_B | flags;
 2519 
 2520                         c = &ic->ic_channels[ic->ic_nchans++];
 2521                         c[0] = c[-1];
 2522                         c->ic_flags = IEEE80211_CHAN_G | flags;
 2523                 } else {        /* 5GHz band */
 2524                         c->ic_flags = IEEE80211_CHAN_A | flags;
 2525                 }
 2526                 /* XXX no constraints on using HT20 */
 2527                 /* add HT20, HT40 added separately */
 2528                 c = &ic->ic_channels[ic->ic_nchans++];
 2529                 c[0] = c[-1];
 2530                 c->ic_flags |= IEEE80211_CHAN_HT20;
 2531                 /* XXX NARROW =>'s 1/2 and 1/4 width? */
 2532         }
 2533 }
 2534 
 2535 static void
 2536 iwn_read_eeprom_ht40(struct iwn_softc *sc, const struct iwn_chan_band *band)
 2537 {
 2538         struct ifnet *ifp = sc->sc_ifp;
 2539         struct ieee80211com *ic = ifp->if_l2com;
 2540         struct iwn_eeprom_chan channels[IWN_MAX_CHAN_PER_BAND];
 2541         struct ieee80211_channel *c, *cent, *extc;
 2542         int i;
 2543 
 2544         iwn_read_prom_data(sc, band->addr, channels,
 2545             band->nchan * sizeof (struct iwn_eeprom_chan));
 2546 
 2547         for (i = 0; i < band->nchan; i++) {
 2548                 if (!(channels[i].flags & IWN_EEPROM_CHAN_VALID) ||
 2549                     !(channels[i].flags & IWN_EEPROM_CHAN_WIDE)) {
 2550                         DPRINTF(sc, IWN_DEBUG_RESET,
 2551                             "skip chan %d flags 0x%x maxpwr %d\n",
 2552                             band->chan[i], channels[i].flags,
 2553                             channels[i].maxpwr);
 2554                         continue;
 2555                 }
 2556                 /*
 2557                  * Each entry defines an HT40 channel pair; find the
 2558                  * center channel, then the extension channel above.
 2559                  */
 2560                 cent = ieee80211_find_channel_byieee(ic, band->chan[i],
 2561                     band->flags & ~IEEE80211_CHAN_HT);
 2562                 if (cent == NULL) {     /* XXX shouldn't happen */
 2563                         device_printf(sc->sc_dev,
 2564                             "%s: no entry for channel %d\n",
 2565                             __func__, band->chan[i]);
 2566                         continue;
 2567                 }
 2568                 extc = ieee80211_find_channel(ic, cent->ic_freq+20,
 2569                     band->flags & ~IEEE80211_CHAN_HT);
 2570                 if (extc == NULL) {
 2571                         DPRINTF(sc, IWN_DEBUG_RESET,
 2572                             "skip chan %d, extension channel not found\n",
 2573                             band->chan[i]);
 2574                         continue;
 2575                 }
 2576 
 2577                 DPRINTF(sc, IWN_DEBUG_RESET,
 2578                     "add ht40 chan %d flags 0x%x maxpwr %d\n",
 2579                     band->chan[i], channels[i].flags, channels[i].maxpwr);
 2580 
 2581                 c = &ic->ic_channels[ic->ic_nchans++];
 2582                 c[0] = cent[0];
 2583                 c->ic_extieee = extc->ic_ieee;
 2584                 c->ic_flags &= ~IEEE80211_CHAN_HT;
 2585                 c->ic_flags |= IEEE80211_CHAN_HT40U;
 2586                 c = &ic->ic_channels[ic->ic_nchans++];
 2587                 c[0] = extc[0];
 2588                 c->ic_extieee = cent->ic_ieee;
 2589                 c->ic_flags &= ~IEEE80211_CHAN_HT;
 2590                 c->ic_flags |= IEEE80211_CHAN_HT40D;
 2591         }
 2592 }
 2593 
 2594 static void
 2595 iwn_read_eeprom_channels(struct iwn_softc *sc)
 2596 {
 2597 #define N(a)    (sizeof(a)/sizeof(a[0]))
 2598         static const struct iwn_chan_band iwn_bands[] = {
 2599             { IWN_EEPROM_BAND1, IEEE80211_CHAN_G, 14,
 2600                 { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 } },
 2601             { IWN_EEPROM_BAND2, IEEE80211_CHAN_A, 13,
 2602                 { 183, 184, 185, 187, 188, 189, 192, 196, 7, 8, 11, 12, 16 } },
 2603             { IWN_EEPROM_BAND3, IEEE80211_CHAN_A, 12,
 2604                 { 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64 } },
 2605             { IWN_EEPROM_BAND4, IEEE80211_CHAN_A, 11,
 2606                 { 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140 } },
 2607             { IWN_EEPROM_BAND5, IEEE80211_CHAN_A, 6,
 2608                 { 145, 149, 153, 157, 161, 165 } },
 2609             { IWN_EEPROM_BAND6, IEEE80211_CHAN_G | IEEE80211_CHAN_HT40, 7,
 2610                 { 1, 2, 3, 4, 5, 6, 7 } },
 2611             { IWN_EEPROM_BAND7, IEEE80211_CHAN_A | IEEE80211_CHAN_HT40, 11,
 2612                 { 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157 } }
 2613         };
 2614         struct ifnet *ifp = sc->sc_ifp;
 2615         struct ieee80211com *ic = ifp->if_l2com;
 2616         int i;
 2617 
 2618         /* read the list of authorized channels */
 2619         for (i = 0; i < N(iwn_bands)-2; i++)
 2620                 iwn_read_eeprom_band(sc, &iwn_bands[i]);
 2621         for (; i < N(iwn_bands); i++)
 2622                 iwn_read_eeprom_ht40(sc, &iwn_bands[i]);
 2623         ieee80211_sort_channels(ic->ic_channels, ic->ic_nchans);
 2624 #undef N
 2625 }
 2626 
 2627 #ifdef IWN_DEBUG
 2628 void
 2629 iwn_print_power_group(struct iwn_softc *sc, int i)
 2630 {
 2631         struct iwn_eeprom_band *band = &sc->bands[i];
 2632         struct iwn_eeprom_chan_samples *chans = band->chans;
 2633         int j, c;
 2634 
 2635         printf("===band %d===\n", i);
 2636         printf("chan lo=%d, chan hi=%d\n", band->lo, band->hi);
 2637         printf("chan1 num=%d\n", chans[0].num);
 2638         for (c = 0; c < IWN_NTXCHAINS; c++) {
 2639                 for (j = 0; j < IWN_NSAMPLES; j++) {
 2640                         printf("chain %d, sample %d: temp=%d gain=%d "
 2641                             "power=%d pa_det=%d\n", c, j,
 2642                             chans[0].samples[c][j].temp,
 2643                             chans[0].samples[c][j].gain,
 2644                             chans[0].samples[c][j].power,
 2645                             chans[0].samples[c][j].pa_det);
 2646                 }
 2647         }
 2648         printf("chan2 num=%d\n", chans[1].num);
 2649         for (c = 0; c < IWN_NTXCHAINS; c++) {
 2650                 for (j = 0; j < IWN_NSAMPLES; j++) {
 2651                         printf("chain %d, sample %d: temp=%d gain=%d "
 2652                             "power=%d pa_det=%d\n", c, j,
 2653                             chans[1].samples[c][j].temp,
 2654                             chans[1].samples[c][j].gain,
 2655                             chans[1].samples[c][j].power,
 2656                             chans[1].samples[c][j].pa_det);
 2657                 }
 2658         }
 2659 }
 2660 #endif
 2661 
 2662 /*
 2663  * Send a command to the firmware.
 2664  */
 2665 int
 2666 iwn_cmd(struct iwn_softc *sc, int code, const void *buf, int size, int async)
 2667 {
 2668         struct iwn_tx_ring *ring = &sc->txq[4];
 2669         struct iwn_tx_desc *desc;
 2670         struct iwn_tx_cmd *cmd;
 2671         bus_addr_t paddr;
 2672 
 2673         IWN_LOCK_ASSERT(sc);
 2674 
 2675         KASSERT(size <= sizeof cmd->data, ("Command too big"));
 2676 
 2677         desc = &ring->desc[ring->cur];
 2678         cmd = &ring->cmd[ring->cur];
 2679 
 2680         cmd->code = code;
 2681         cmd->flags = 0;
 2682         cmd->qid = ring->qid;
 2683         cmd->idx = ring->cur;
 2684         memcpy(cmd->data, buf, size);
 2685 
 2686         paddr = ring->cmd_dma.paddr + ring->cur * sizeof (struct iwn_tx_cmd);
 2687 
 2688         IWN_SET_DESC_NSEGS(desc, 1);
 2689         IWN_SET_DESC_SEG(desc, 0, paddr, 4 + size);
 2690         sc->shared->len[ring->qid][ring->cur] = htole16(8);
 2691         if (ring->cur < IWN_TX_WINDOW) {
 2692             sc->shared->len[ring->qid][ring->cur + IWN_TX_RING_COUNT] =
 2693                 htole16(8);
 2694         }
 2695 
 2696         DPRINTF(sc, IWN_DEBUG_CMD, "%s: %s (0x%x) flags %d qid %d idx %d\n",
 2697             __func__, iwn_intr_str(cmd->code), cmd->code,
 2698             cmd->flags, cmd->qid, cmd->idx);
 2699 
 2700         /* kick cmd ring */
 2701         ring->cur = (ring->cur + 1) % IWN_TX_RING_COUNT;
 2702         IWN_WRITE(sc, IWN_TX_WIDX, ring->qid << 8 | ring->cur);
 2703 
 2704         return async ? 0 : msleep(cmd, &sc->sc_mtx, PCATCH, "iwncmd", hz);
 2705 }
 2706 
 2707 static const uint8_t iwn_ridx_to_plcp[] = {
 2708         10, 20, 55, 110, /* CCK */
 2709         0xd, 0xf, 0x5, 0x7, 0x9, 0xb, 0x1, 0x3, 0x3 /* OFDM R1-R4 */
 2710 };
 2711 static const uint8_t iwn_siso_mcs_to_plcp[] = {
 2712         0, 0, 0, 0,                     /* CCK */
 2713         0, 0, 1, 2, 3, 4, 5, 6, 7       /* HT */
 2714 };
 2715 static const uint8_t iwn_mimo_mcs_to_plcp[] = {
 2716         0, 0, 0, 0,                     /* CCK */
 2717         8, 8, 9, 10, 11, 12, 13, 14, 15 /* HT */
 2718 };
 2719 static const uint8_t iwn_prev_ridx[] = {
 2720         /* NB: allow fallback from CCK11 to OFDM9 and from OFDM6 to CCK5 */
 2721         0, 0, 1, 5,                     /* CCK */
 2722         2, 4, 3, 6, 7, 8, 9, 10, 10     /* OFDM */
 2723 };
 2724 
 2725 /*
 2726  * Configure hardware link parameters for the specified
 2727  * node operating on the specified channel.
 2728  */
 2729 int
 2730 iwn_set_link_quality(struct iwn_softc *sc, uint8_t id,
 2731         const struct ieee80211_channel *c, int async)
 2732 {
 2733         struct iwn_cmd_link_quality lq;
 2734         int i, ridx;
 2735 
 2736         memset(&lq, 0, sizeof(lq));
 2737         lq.id = id;
 2738         if (IEEE80211_IS_CHAN_HT(c)) {
 2739                 lq.mimo = 1;
 2740                 lq.ssmask = 0x1;
 2741         } else
 2742                 lq.ssmask = 0x2;
 2743 
 2744         if (id == IWN_ID_BSS)
 2745                 ridx = IWN_RATE_OFDM54;
 2746         else if (IEEE80211_IS_CHAN_A(c))
 2747                 ridx = IWN_RATE_OFDM6;
 2748         else
 2749                 ridx = IWN_RATE_CCK1;
 2750         for (i = 0; i < IWN_MAX_TX_RETRIES; i++) {
 2751                 /* XXX toggle antenna for retry patterns */
 2752                 if (IEEE80211_IS_CHAN_HT40(c)) {
 2753                         lq.table[i].rate = iwn_mimo_mcs_to_plcp[ridx]
 2754                                          | IWN_RATE_MCS;
 2755                         lq.table[i].rflags = IWN_RFLAG_HT
 2756                                          | IWN_RFLAG_HT40
 2757                                          | IWN_RFLAG_ANT_A;
 2758                         /* XXX shortGI */
 2759                 } else if (IEEE80211_IS_CHAN_HT(c)) {
 2760                         lq.table[i].rate = iwn_siso_mcs_to_plcp[ridx]
 2761                                          | IWN_RATE_MCS;
 2762                         lq.table[i].rflags = IWN_RFLAG_HT
 2763                                          | IWN_RFLAG_ANT_A;
 2764                         /* XXX shortGI */
 2765                 } else {
 2766                         lq.table[i].rate = iwn_ridx_to_plcp[ridx];
 2767                         if (ridx <= IWN_RATE_CCK11)
 2768                                 lq.table[i].rflags = IWN_RFLAG_CCK;
 2769                         lq.table[i].rflags |= IWN_RFLAG_ANT_B;
 2770                 }
 2771                 ridx = iwn_prev_ridx[ridx];
 2772         }
 2773 
 2774         lq.dsmask = 0x3;
 2775         lq.ampdu_disable = 3;
 2776         lq.ampdu_limit = htole16(4000);
 2777 #ifdef IWN_DEBUG
 2778         if (sc->sc_debug & IWN_DEBUG_STATE) {
 2779                 printf("%s: set link quality for node %d, mimo %d ssmask %d\n",
 2780                     __func__, id, lq.mimo, lq.ssmask);
 2781                 printf("%s:", __func__);
 2782                 for (i = 0; i < IWN_MAX_TX_RETRIES; i++)
 2783                         printf(" %d:%x", lq.table[i].rate, lq.table[i].rflags);
 2784                 printf("\n");
 2785         }
 2786 #endif
 2787         return iwn_cmd(sc, IWN_CMD_TX_LINK_QUALITY, &lq, sizeof(lq), async);
 2788 }
 2789 
 2790 #if 0
 2791 
 2792 /*
 2793  * Install a pairwise key into the hardware.
 2794  */
 2795 int
 2796 iwn_set_key(struct ieee80211com *ic, struct ieee80211_node *ni,
 2797     const struct ieee80211_key *k)
 2798 {
 2799         struct iwn_softc *sc = ic->ic_softc;
 2800         struct iwn_node_info node;
 2801 
 2802         if (k->k_flags & IEEE80211_KEY_GROUP)
 2803                 return 0;
 2804 
 2805         memset(&node, 0, sizeof node);
 2806 
 2807         switch (k->k_cipher) {
 2808         case IEEE80211_CIPHER_CCMP:
 2809                 node.security = htole16(IWN_CIPHER_CCMP);
 2810                 memcpy(node.key, k->k_key, k->k_len);
 2811                 break;
 2812         default:
 2813                 return 0;
 2814         }
 2815 
 2816         node.id = IWN_ID_BSS;
 2817         IEEE80211_ADDR_COPY(node.macaddr, ni->ni_macaddr);
 2818         node.control = IWN_NODE_UPDATE;
 2819         node.flags = IWN_FLAG_SET_KEY;
 2820 
 2821         return iwn_cmd(sc, IWN_CMD_ADD_NODE, &node, sizeof node, 1);
 2822 }
 2823 #endif
 2824 
 2825 int
 2826 iwn_wme_update(struct ieee80211com *ic)
 2827 {
 2828 #define IWN_EXP2(x)     ((1 << (x)) - 1)        /* CWmin = 2^ECWmin - 1 */
 2829 #define IWN_TXOP_TO_US(v)               (v<<5)
 2830         struct iwn_softc *sc = ic->ic_ifp->if_softc;
 2831         struct iwn_edca_params cmd;
 2832         int i;
 2833 
 2834         memset(&cmd, 0, sizeof cmd);
 2835         cmd.flags = htole32(IWN_EDCA_UPDATE);
 2836         for (i = 0; i < WME_NUM_AC; i++) {
 2837                 const struct wmeParams *wmep =
 2838                     &ic->ic_wme.wme_chanParams.cap_wmeParams[i];
 2839                 cmd.ac[i].aifsn = wmep->wmep_aifsn;
 2840                 cmd.ac[i].cwmin = htole16(IWN_EXP2(wmep->wmep_logcwmin));
 2841                 cmd.ac[i].cwmax = htole16(IWN_EXP2(wmep->wmep_logcwmax));
 2842                 cmd.ac[i].txoplimit =
 2843                     htole16(IWN_TXOP_TO_US(wmep->wmep_txopLimit));
 2844         }
 2845         IWN_LOCK(sc);
 2846         (void) iwn_cmd(sc, IWN_CMD_EDCA_PARAMS, &cmd, sizeof cmd, 1 /*async*/);
 2847         IWN_UNLOCK(sc);
 2848         return 0;
 2849 #undef IWN_TXOP_TO_US
 2850 #undef IWN_EXP2
 2851 }
 2852 
 2853 void
 2854 iwn_set_led(struct iwn_softc *sc, uint8_t which, uint8_t off, uint8_t on)
 2855 {
 2856         struct iwn_cmd_led led;
 2857 
 2858         led.which = which;
 2859         led.unit = htole32(100000);     /* on/off in unit of 100ms */
 2860         led.off = off;
 2861         led.on = on;
 2862 
 2863         (void) iwn_cmd(sc, IWN_CMD_SET_LED, &led, sizeof led, 1);
 2864 }
 2865 
 2866 /*
 2867  * Set the critical temperature at which the firmware will automatically stop
 2868  * the radio transmitter.
 2869  */
 2870 int
 2871 iwn_set_critical_temp(struct iwn_softc *sc)
 2872 {
 2873         struct iwn_ucode_info *uc = &sc->ucode_info;
 2874         struct iwn_critical_temp crit;
 2875         uint32_t r1, r2, r3, temp;
 2876 
 2877         r1 = le32toh(uc->temp[0].chan20MHz);
 2878         r2 = le32toh(uc->temp[1].chan20MHz);
 2879         r3 = le32toh(uc->temp[2].chan20MHz);
 2880         /* inverse function of iwn_get_temperature() */
 2881         temp = r2 + (IWN_CTOK(110) * (r3 - r1)) / 259;
 2882 
 2883         IWN_WRITE(sc, IWN_UCODE_CLR, IWN_CTEMP_STOP_RF);
 2884 
 2885         memset(&crit, 0, sizeof crit);
 2886         crit.tempR = htole32(temp);
 2887         DPRINTF(sc, IWN_DEBUG_RESET, "setting critical temp to %u\n", temp);
 2888         return iwn_cmd(sc, IWN_CMD_SET_CRITICAL_TEMP, &crit, sizeof crit, 0);
 2889 }
 2890 
 2891 void
 2892 iwn_enable_tsf(struct iwn_softc *sc, struct ieee80211_node *ni)
 2893 {
 2894         struct iwn_cmd_tsf tsf;
 2895         uint64_t val, mod;
 2896 
 2897         memset(&tsf, 0, sizeof tsf);
 2898         memcpy(&tsf.tstamp, ni->ni_tstamp.data, sizeof (uint64_t));
 2899         tsf.bintval = htole16(ni->ni_intval);
 2900         tsf.lintval = htole16(10);
 2901 
 2902         /* XXX all wrong */
 2903         /* compute remaining time until next beacon */
 2904         val = (uint64_t)ni->ni_intval * 1024;   /* msecs -> usecs */
 2905         DPRINTF(sc, IWN_DEBUG_ANY, "%s: val = %ju %s\n", __func__,
 2906             val, val == 0 ? "correcting" : "");
 2907         if (val == 0)
 2908                 val = 1;
 2909         mod = le64toh(tsf.tstamp) % val;
 2910         tsf.binitval = htole32((uint32_t)(val - mod));
 2911 
 2912         DPRINTF(sc, IWN_DEBUG_RESET, "TSF bintval=%u tstamp=%ju, init=%u\n",
 2913             ni->ni_intval, le64toh(tsf.tstamp), (uint32_t)(val - mod));
 2914 
 2915         if (iwn_cmd(sc, IWN_CMD_TSF, &tsf, sizeof tsf, 1) != 0)
 2916                 device_printf(sc->sc_dev,
 2917                     "%s: could not enable TSF\n", __func__);
 2918 }
 2919 
 2920 void
 2921 iwn_power_calibration(struct iwn_softc *sc, int temp)
 2922 {
 2923         struct ifnet *ifp = sc->sc_ifp;
 2924         struct ieee80211com *ic = ifp->if_l2com;
 2925 #if 0
 2926         KASSERT(ic->ic_state == IEEE80211_S_RUN, ("not running"));
 2927 #endif
 2928         DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: temperature %d->%d\n",
 2929             __func__, sc->temp, temp);
 2930 
 2931         /* adjust Tx power if need be (delta >= 3C) */
 2932         if (abs(temp - sc->temp) < 3)
 2933                 return;
 2934 
 2935         sc->temp = temp;
 2936 
 2937         DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: set Tx power for channel %d\n",
 2938             __func__, ieee80211_chan2ieee(ic, ic->ic_bsschan));
 2939         if (iwn_set_txpower(sc, ic->ic_bsschan, 1) != 0) {
 2940                 /* just warn, too bad for the automatic calibration... */
 2941                 device_printf(sc->sc_dev,
 2942                     "%s: could not adjust Tx power\n", __func__);
 2943         }
 2944 }
 2945 
 2946 /*
 2947  * Set Tx power for a given channel (each rate has its own power settings).
 2948  * This function takes into account the regulatory information from EEPROM,
 2949  * the current temperature and the current voltage.
 2950  */
 2951 int
 2952 iwn_set_txpower(struct iwn_softc *sc, struct ieee80211_channel *ch, int async)
 2953 {
 2954 /* fixed-point arithmetic division using a n-bit fractional part */
 2955 #define fdivround(a, b, n)      \
 2956         ((((1 << n) * (a)) / (b) + (1 << n) / 2) / (1 << n))
 2957 /* linear interpolation */
 2958 #define interpolate(x, x1, y1, x2, y2, n)       \
 2959         ((y1) + fdivround(((int)(x) - (x1)) * ((y2) - (y1)), (x2) - (x1), n))
 2960 
 2961         static const int tdiv[IWN_NATTEN_GROUPS] = { 9, 8, 8, 8, 6 };
 2962         struct ifnet *ifp = sc->sc_ifp;
 2963         struct ieee80211com *ic = ifp->if_l2com;
 2964         struct iwn_ucode_info *uc = &sc->ucode_info;
 2965         struct iwn_cmd_txpower cmd;
 2966         struct iwn_eeprom_chan_samples *chans;
 2967         const uint8_t *rf_gain, *dsp_gain;
 2968         int32_t vdiff, tdiff;
 2969         int i, c, grp, maxpwr;
 2970         u_int chan;
 2971 
 2972         /* get channel number */
 2973         chan = ieee80211_chan2ieee(ic, ch);
 2974 
 2975         memset(&cmd, 0, sizeof cmd);
 2976         cmd.band = IEEE80211_IS_CHAN_5GHZ(ch) ? 0 : 1;
 2977         cmd.chan = chan;
 2978 
 2979         if (IEEE80211_IS_CHAN_5GHZ(ch)) {
 2980                 maxpwr   = sc->maxpwr5GHz;
 2981                 rf_gain  = iwn_rf_gain_5ghz;
 2982                 dsp_gain = iwn_dsp_gain_5ghz;
 2983         } else {
 2984                 maxpwr   = sc->maxpwr2GHz;
 2985                 rf_gain  = iwn_rf_gain_2ghz;
 2986                 dsp_gain = iwn_dsp_gain_2ghz;
 2987         }
 2988 
 2989         /* compute voltage compensation */
 2990         vdiff = ((int32_t)le32toh(uc->volt) - sc->eeprom_voltage) / 7;
 2991         if (vdiff > 0)
 2992                 vdiff *= 2;
 2993         if (abs(vdiff) > 2)
 2994                 vdiff = 0;
 2995         DPRINTF(sc, IWN_DEBUG_CALIBRATE | IWN_DEBUG_TXPOW,
 2996             "%s: voltage compensation=%d (UCODE=%d, EEPROM=%d)\n",
 2997             __func__, vdiff, le32toh(uc->volt), sc->eeprom_voltage);
 2998 
 2999         /* get channel's attenuation group */
 3000         if (chan <= 20)         /* 1-20 */
 3001                 grp = 4;
 3002         else if (chan <= 43)    /* 34-43 */
 3003                 grp = 0;
 3004         else if (chan <= 70)    /* 44-70 */
 3005                 grp = 1;
 3006         else if (chan <= 124)   /* 71-124 */
 3007                 grp = 2;
 3008         else                    /* 125-200 */
 3009                 grp = 3;
 3010         DPRINTF(sc, IWN_DEBUG_CALIBRATE | IWN_DEBUG_TXPOW,
 3011             "%s: chan %d, attenuation group=%d\n", __func__, chan, grp);
 3012 
 3013         /* get channel's sub-band */
 3014         for (i = 0; i < IWN_NBANDS; i++)
 3015                 if (sc->bands[i].lo != 0 &&
 3016                     sc->bands[i].lo <= chan && chan <= sc->bands[i].hi)
 3017                         break;
 3018         chans = sc->bands[i].chans;
 3019         DPRINTF(sc, IWN_DEBUG_CALIBRATE | IWN_DEBUG_TXPOW,
 3020             "%s: chan %d sub-band=%d\n", __func__, chan, i);
 3021 
 3022         for (c = 0; c < IWN_NTXCHAINS; c++) {
 3023                 uint8_t power, gain, temp;
 3024                 int maxchpwr, pwr, ridx, idx;
 3025 
 3026                 power = interpolate(chan,
 3027                     chans[0].num, chans[0].samples[c][1].power,
 3028                     chans[1].num, chans[1].samples[c][1].power, 1);
 3029                 gain  = interpolate(chan,
 3030                     chans[0].num, chans[0].samples[c][1].gain,
 3031                     chans[1].num, chans[1].samples[c][1].gain, 1);
 3032                 temp  = interpolate(chan,
 3033                     chans[0].num, chans[0].samples[c][1].temp,
 3034                     chans[1].num, chans[1].samples[c][1].temp, 1);
 3035                 DPRINTF(sc, IWN_DEBUG_CALIBRATE | IWN_DEBUG_TXPOW,
 3036                     "%s: Tx chain %d: power=%d gain=%d temp=%d\n",
 3037                     __func__, c, power, gain, temp);
 3038 
 3039                 /* compute temperature compensation */
 3040                 tdiff = ((sc->temp - temp) * 2) / tdiv[grp];
 3041                 DPRINTF(sc, IWN_DEBUG_CALIBRATE | IWN_DEBUG_TXPOW,
 3042                     "%s: temperature compensation=%d (current=%d, EEPROM=%d)\n",
 3043                     __func__, tdiff, sc->temp, temp);
 3044 
 3045                 for (ridx = 0; ridx <= IWN_RIDX_MAX; ridx++) {
 3046                         maxchpwr = ch->ic_maxpower;
 3047                         if ((ridx / 8) & 1) {
 3048                                 /* MIMO: decrease Tx power (-3dB) */
 3049                                 maxchpwr -= 6;
 3050                         }
 3051 
 3052                         pwr = maxpwr - 10;
 3053 
 3054                         /* decrease power for highest OFDM rates */
 3055                         if ((ridx % 8) == 5)            /* 48Mbit/s */
 3056                                 pwr -= 5;
 3057                         else if ((ridx % 8) == 6)       /* 54Mbit/s */
 3058                                 pwr -= 7;
 3059                         else if ((ridx % 8) == 7)       /* 60Mbit/s */
 3060                                 pwr -= 10;
 3061 
 3062                         if (pwr > maxchpwr)
 3063                                 pwr = maxchpwr;
 3064 
 3065                         idx = gain - (pwr - power) - tdiff - vdiff;
 3066                         if ((ridx / 8) & 1)     /* MIMO */
 3067                                 idx += (int32_t)le32toh(uc->atten[grp][c]);
 3068 
 3069                         if (cmd.band == 0)
 3070                                 idx += 9;       /* 5GHz */
 3071                         if (ridx == IWN_RIDX_MAX)
 3072                                 idx += 5;       /* CCK */
 3073 
 3074                         /* make sure idx stays in a valid range */
 3075                         if (idx < 0)
 3076                                 idx = 0;
 3077                         else if (idx > IWN_MAX_PWR_INDEX)
 3078                                 idx = IWN_MAX_PWR_INDEX;
 3079 
 3080                         DPRINTF(sc, IWN_DEBUG_CALIBRATE | IWN_DEBUG_TXPOW,
 3081                             "%s: Tx chain %d, rate idx %d: power=%d\n",
 3082                             __func__, c, ridx, idx);
 3083                         cmd.power[ridx].rf_gain[c] = rf_gain[idx];
 3084                         cmd.power[ridx].dsp_gain[c] = dsp_gain[idx];
 3085                 }
 3086         }
 3087 
 3088         DPRINTF(sc, IWN_DEBUG_CALIBRATE | IWN_DEBUG_TXPOW,
 3089             "%s: set tx power for chan %d\n", __func__, chan);
 3090         return iwn_cmd(sc, IWN_CMD_TXPOWER, &cmd, sizeof cmd, async);
 3091 
 3092 #undef interpolate
 3093 #undef fdivround
 3094 }
 3095 
 3096 /*
 3097  * Get the best (maximum) RSSI among the
 3098  * connected antennas and convert to dBm.
 3099  */
 3100 int8_t
 3101 iwn_get_rssi(struct iwn_softc *sc, const struct iwn_rx_stat *stat)
 3102 {
 3103         int mask, agc, rssi;
 3104 
 3105         mask = (le16toh(stat->antenna) >> 4) & 0x7;
 3106         agc  = (le16toh(stat->agc) >> 7) & 0x7f;
 3107 
 3108         rssi = 0;
 3109 #if 0
 3110         if (mask & (1 << 0))    /* Ant A */
 3111                 rssi = max(rssi, stat->rssi[0]);
 3112         if (mask & (1 << 1))    /* Ant B */
 3113                 rssi = max(rssi, stat->rssi[2]);
 3114         if (mask & (1 << 2))    /* Ant C */
 3115                 rssi = max(rssi, stat->rssi[4]);
 3116 #else
 3117         rssi = max(rssi, stat->rssi[0]);
 3118         rssi = max(rssi, stat->rssi[2]);
 3119         rssi = max(rssi, stat->rssi[4]);
 3120 #endif
 3121         DPRINTF(sc, IWN_DEBUG_RECV, "%s: agc %d mask 0x%x rssi %d %d %d "
 3122             "result %d\n", __func__, agc, mask,
 3123             stat->rssi[0], stat->rssi[2], stat->rssi[4],
 3124             rssi - agc - IWN_RSSI_TO_DBM);
 3125         return rssi - agc - IWN_RSSI_TO_DBM;
 3126 }
 3127 
 3128 /*
 3129  * Get the average noise among Rx antennas (in dBm).
 3130  */
 3131 int
 3132 iwn_get_noise(const struct iwn_rx_general_stats *stats)
 3133 {
 3134         int i, total, nbant, noise;
 3135 
 3136         total = nbant = 0;
 3137         for (i = 0; i < 3; i++) {
 3138                 noise = le32toh(stats->noise[i]) & 0xff;
 3139                 if (noise != 0) {
 3140                         total += noise;
 3141                         nbant++;
 3142                 }
 3143         }
 3144         /* there should be at least one antenna but check anyway */
 3145         return (nbant == 0) ? -127 : (total / nbant) - 107;
 3146 }
 3147 
 3148 /*
 3149  * Read temperature (in degC) from the on-board thermal sensor.
 3150  */
 3151 int
 3152 iwn_get_temperature(struct iwn_softc *sc)
 3153 {
 3154         struct iwn_ucode_info *uc = &sc->ucode_info;
 3155         int32_t r1, r2, r3, r4, temp;
 3156 
 3157         r1 = le32toh(uc->temp[0].chan20MHz);
 3158         r2 = le32toh(uc->temp[1].chan20MHz);
 3159         r3 = le32toh(uc->temp[2].chan20MHz);
 3160         r4 = le32toh(sc->rawtemp);
 3161 
 3162         if (r1 == r3)   /* prevents division by 0 (should not happen) */
 3163                 return 0;
 3164 
 3165         /* sign-extend 23-bit R4 value to 32-bit */
 3166         r4 = (r4 << 8) >> 8;
 3167         /* compute temperature */
 3168         temp = (259 * (r4 - r2)) / (r3 - r1);
 3169         temp = (temp * 97) / 100 + 8;
 3170 
 3171         return IWN_KTOC(temp);
 3172 }
 3173 
 3174 /*
 3175  * Initialize sensitivity calibration state machine.
 3176  */
 3177 int
 3178 iwn_init_sensitivity(struct iwn_softc *sc)
 3179 {
 3180         struct iwn_calib_state *calib = &sc->calib;
 3181         struct iwn_phy_calib_cmd cmd;
 3182         int error;
 3183 
 3184         /* reset calibration state */
 3185         memset(calib, 0, sizeof (*calib));
 3186         calib->state = IWN_CALIB_STATE_INIT;
 3187         calib->cck_state = IWN_CCK_STATE_HIFA;
 3188         /* initial values taken from the reference driver */
 3189         calib->corr_ofdm_x1     = 105;
 3190         calib->corr_ofdm_mrc_x1 = 220;
 3191         calib->corr_ofdm_x4     =  90;
 3192         calib->corr_ofdm_mrc_x4 = 170;
 3193         calib->corr_cck_x4      = 125;
 3194         calib->corr_cck_mrc_x4  = 200;
 3195         calib->energy_cck       = 100;
 3196 
 3197         /* write initial sensitivity values */
 3198         error = iwn_send_sensitivity(sc);
 3199         if (error != 0)
 3200                 return error;
 3201 
 3202         memset(&cmd, 0, sizeof cmd);
 3203         cmd.code = IWN_SET_DIFF_GAIN;
 3204         /* differential gains initially set to 0 for all 3 antennas */
 3205         DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: calibrate phy\n", __func__);
 3206         return iwn_cmd(sc, IWN_PHY_CALIB, &cmd, sizeof cmd, 1);
 3207 }
 3208 
 3209 /*
 3210  * Collect noise and RSSI statistics for the first 20 beacons received
 3211  * after association and use them to determine connected antennas and
 3212  * set differential gains.
 3213  */
 3214 void
 3215 iwn_compute_differential_gain(struct iwn_softc *sc,
 3216     const struct iwn_rx_general_stats *stats)
 3217 {
 3218         struct iwn_calib_state *calib = &sc->calib;
 3219         struct iwn_phy_calib_cmd cmd;
 3220         int i, val;
 3221 
 3222         /* accumulate RSSI and noise for all 3 antennas */
 3223         for (i = 0; i < 3; i++) {
 3224                 calib->rssi[i] += le32toh(stats->rssi[i]) & 0xff;
 3225                 calib->noise[i] += le32toh(stats->noise[i]) & 0xff;
 3226         }
 3227 
 3228         /* we update differential gain only once after 20 beacons */
 3229         if (++calib->nbeacons < 20)
 3230                 return;
 3231 
 3232         /* determine antenna with highest average RSSI */
 3233         val = max(calib->rssi[0], calib->rssi[1]);
 3234         val = max(calib->rssi[2], val);
 3235 
 3236         /* determine which antennas are connected */
 3237         sc->antmsk = 0;
 3238         for (i = 0; i < 3; i++)
 3239                 if (val - calib->rssi[i] <= 15 * 20)
 3240                         sc->antmsk |= 1 << i;
 3241         /* if neither Ant A and Ant B are connected.. */
 3242         if ((sc->antmsk & (1 << 0 | 1 << 1)) == 0)
 3243                 sc->antmsk |= 1 << 1;   /* ..mark Ant B as connected! */
 3244 
 3245         /* get minimal noise among connected antennas */
 3246         val = INT_MAX;  /* ok, there's at least one */
 3247         for (i = 0; i < 3; i++)
 3248                 if (sc->antmsk & (1 << i))
 3249                         val = min(calib->noise[i], val);
 3250 
 3251         memset(&cmd, 0, sizeof cmd);
 3252         cmd.code = IWN_SET_DIFF_GAIN;
 3253         /* set differential gains for connected antennas */
 3254         for (i = 0; i < 3; i++) {
 3255                 if (sc->antmsk & (1 << i)) {
 3256                         cmd.gain[i] = (calib->noise[i] - val) / 30;
 3257                         /* limit differential gain to 3 */
 3258                         cmd.gain[i] = min(cmd.gain[i], 3);
 3259                         cmd.gain[i] |= IWN_GAIN_SET;
 3260                 }
 3261         }
 3262         DPRINTF(sc, IWN_DEBUG_CALIBRATE,
 3263             "%s: set differential gains Ant A/B/C: %x/%x/%x (%x)\n",
 3264             __func__,cmd.gain[0], cmd.gain[1], cmd.gain[2], sc->antmsk);
 3265         if (iwn_cmd(sc, IWN_PHY_CALIB, &cmd, sizeof cmd, 1) == 0)
 3266                 calib->state = IWN_CALIB_STATE_RUN;
 3267 }
 3268 
 3269 /*
 3270  * Tune RF Rx sensitivity based on the number of false alarms detected
 3271  * during the last beacon period.
 3272  */
 3273 void
 3274 iwn_tune_sensitivity(struct iwn_softc *sc, const struct iwn_rx_stats *stats)
 3275 {
 3276 #define inc_clip(val, inc, max)                 \
 3277         if ((val) < (max)) {                    \
 3278                 if ((val) < (max) - (inc))      \
 3279                         (val) += (inc);         \
 3280                 else                            \
 3281                         (val) = (max);          \
 3282                 needs_update = 1;               \
 3283         }
 3284 #define dec_clip(val, dec, min)                 \
 3285         if ((val) > (min)) {                    \
 3286                 if ((val) > (min) + (dec))      \
 3287                         (val) -= (dec);         \
 3288                 else                            \
 3289                         (val) = (min);          \
 3290                 needs_update = 1;               \
 3291         }
 3292 
 3293         struct iwn_calib_state *calib = &sc->calib;
 3294         uint32_t val, rxena, fa;
 3295         uint32_t energy[3], energy_min;
 3296         uint8_t noise[3], noise_ref;
 3297         int i, needs_update = 0;
 3298 
 3299         /* check that we've been enabled long enough */
 3300         if ((rxena = le32toh(stats->general.load)) == 0)
 3301                 return;
 3302 
 3303         /* compute number of false alarms since last call for OFDM */
 3304         fa  = le32toh(stats->ofdm.bad_plcp) - calib->bad_plcp_ofdm;
 3305         fa += le32toh(stats->ofdm.fa) - calib->fa_ofdm;
 3306         fa *= 200 * 1024;       /* 200TU */
 3307 
 3308         /* save counters values for next call */
 3309         calib->bad_plcp_ofdm = le32toh(stats->ofdm.bad_plcp);
 3310         calib->fa_ofdm = le32toh(stats->ofdm.fa);
 3311 
 3312         if (fa > 50 * rxena) {
 3313                 /* high false alarm count, decrease sensitivity */
 3314                 DPRINTF(sc, IWN_DEBUG_CALIBRATE,
 3315                     "%s: OFDM high false alarm count: %u\n", __func__, fa);
 3316                 inc_clip(calib->corr_ofdm_x1,     1, 140);
 3317                 inc_clip(calib->corr_ofdm_mrc_x1, 1, 270);
 3318                 inc_clip(calib->corr_ofdm_x4,     1, 120);
 3319                 inc_clip(calib->corr_ofdm_mrc_x4, 1, 210);
 3320 
 3321         } else if (fa < 5 * rxena) {
 3322                 /* low false alarm count, increase sensitivity */
 3323                 DPRINTF(sc, IWN_DEBUG_CALIBRATE,
 3324                     "%s: OFDM low false alarm count: %u\n", __func__, fa);
 3325                 dec_clip(calib->corr_ofdm_x1,     1, 105);
 3326                 dec_clip(calib->corr_ofdm_mrc_x1, 1, 220);
 3327                 dec_clip(calib->corr_ofdm_x4,     1,  85);
 3328                 dec_clip(calib->corr_ofdm_mrc_x4, 1, 170);
 3329         }
 3330 
 3331         /* compute maximum noise among 3 antennas */
 3332         for (i = 0; i < 3; i++)
 3333                 noise[i] = (le32toh(stats->general.noise[i]) >> 8) & 0xff;
 3334         val = max(noise[0], noise[1]);
 3335         val = max(noise[2], val);
 3336         /* insert it into our samples table */
 3337         calib->noise_samples[calib->cur_noise_sample] = val;
 3338         calib->cur_noise_sample = (calib->cur_noise_sample + 1) % 20;
 3339 
 3340         /* compute maximum noise among last 20 samples */
 3341         noise_ref = calib->noise_samples[0];
 3342         for (i = 1; i < 20; i++)
 3343                 noise_ref = max(noise_ref, calib->noise_samples[i]);
 3344 
 3345         /* compute maximum energy among 3 antennas */
 3346         for (i = 0; i < 3; i++)
 3347                 energy[i] = le32toh(stats->general.energy[i]);
 3348         val = min(energy[0], energy[1]);
 3349         val = min(energy[2], val);
 3350         /* insert it into our samples table */
 3351         calib->energy_samples[calib->cur_energy_sample] = val;
 3352         calib->cur_energy_sample = (calib->cur_energy_sample + 1) % 10;
 3353 
 3354         /* compute minimum energy among last 10 samples */
 3355         energy_min = calib->energy_samples[0];
 3356         for (i = 1; i < 10; i++)
 3357                 energy_min = max(energy_min, calib->energy_samples[i]);
 3358         energy_min += 6;
 3359 
 3360         /* compute number of false alarms since last call for CCK */
 3361         fa  = le32toh(stats->cck.bad_plcp) - calib->bad_plcp_cck;
 3362         fa += le32toh(stats->cck.fa) - calib->fa_cck;
 3363         fa *= 200 * 1024;       /* 200TU */
 3364 
 3365         /* save counters values for next call */
 3366         calib->bad_plcp_cck = le32toh(stats->cck.bad_plcp);
 3367         calib->fa_cck = le32toh(stats->cck.fa);
 3368 
 3369         if (fa > 50 * rxena) {
 3370                 /* high false alarm count, decrease sensitivity */
 3371                 DPRINTF(sc, IWN_DEBUG_CALIBRATE,
 3372                     "%s: CCK high false alarm count: %u\n", __func__, fa);
 3373                 calib->cck_state = IWN_CCK_STATE_HIFA;
 3374                 calib->low_fa = 0;
 3375 
 3376                 if (calib->corr_cck_x4 > 160) {
 3377                         calib->noise_ref = noise_ref;
 3378                         if (calib->energy_cck > 2)
 3379                                 dec_clip(calib->energy_cck, 2, energy_min);
 3380                 }
 3381                 if (calib->corr_cck_x4 < 160) {
 3382                         calib->corr_cck_x4 = 161;
 3383                         needs_update = 1;
 3384                 } else
 3385                         inc_clip(calib->corr_cck_x4, 3, 200);
 3386 
 3387                 inc_clip(calib->corr_cck_mrc_x4, 3, 400);
 3388 
 3389         } else if (fa < 5 * rxena) {
 3390                 /* low false alarm count, increase sensitivity */
 3391                 DPRINTF(sc, IWN_DEBUG_CALIBRATE,
 3392                     "%s: CCK low false alarm count: %u\n", __func__, fa);
 3393                 calib->cck_state = IWN_CCK_STATE_LOFA;
 3394                 calib->low_fa++;
 3395 
 3396                 if (calib->cck_state != 0 &&
 3397                     ((calib->noise_ref - noise_ref) > 2 ||
 3398                      calib->low_fa > 100)) {
 3399                         inc_clip(calib->energy_cck,      2,  97);
 3400                         dec_clip(calib->corr_cck_x4,     3, 125);
 3401                         dec_clip(calib->corr_cck_mrc_x4, 3, 200);
 3402                 }
 3403         } else {
 3404                 /* not worth to increase or decrease sensitivity */
 3405                 DPRINTF(sc, IWN_DEBUG_CALIBRATE,
 3406                     "%s: CCK normal false alarm count: %u\n", __func__, fa);
 3407                 calib->low_fa = 0;
 3408                 calib->noise_ref = noise_ref;
 3409 
 3410                 if (calib->cck_state == IWN_CCK_STATE_HIFA) {
 3411                         /* previous interval had many false alarms */
 3412                         dec_clip(calib->energy_cck, 8, energy_min);
 3413                 }
 3414                 calib->cck_state = IWN_CCK_STATE_INIT;
 3415         }
 3416 
 3417         if (needs_update)
 3418                 (void)iwn_send_sensitivity(sc);
 3419 #undef dec_clip
 3420 #undef inc_clip
 3421 }
 3422 
 3423 int
 3424 iwn_send_sensitivity(struct iwn_softc *sc)
 3425 {
 3426         struct iwn_calib_state *calib = &sc->calib;
 3427         struct iwn_sensitivity_cmd cmd;
 3428 
 3429         memset(&cmd, 0, sizeof cmd);
 3430         cmd.which = IWN_SENSITIVITY_WORKTBL;
 3431         /* OFDM modulation */
 3432         cmd.corr_ofdm_x1     = htole16(calib->corr_ofdm_x1);
 3433         cmd.corr_ofdm_mrc_x1 = htole16(calib->corr_ofdm_mrc_x1);
 3434         cmd.corr_ofdm_x4     = htole16(calib->corr_ofdm_x4);
 3435         cmd.corr_ofdm_mrc_x4 = htole16(calib->corr_ofdm_mrc_x4);
 3436         cmd.energy_ofdm      = htole16(100);
 3437         cmd.energy_ofdm_th   = htole16(62);
 3438         /* CCK modulation */
 3439         cmd.corr_cck_x4      = htole16(calib->corr_cck_x4);
 3440         cmd.corr_cck_mrc_x4  = htole16(calib->corr_cck_mrc_x4);
 3441         cmd.energy_cck       = htole16(calib->energy_cck);
 3442         /* Barker modulation: use default values */
 3443         cmd.corr_barker      = htole16(190);
 3444         cmd.corr_barker_mrc  = htole16(390);
 3445 
 3446         DPRINTF(sc, IWN_DEBUG_RESET, 
 3447             "%s: set sensitivity %d/%d/%d/%d/%d/%d/%d\n", __func__,
 3448             calib->corr_ofdm_x1, calib->corr_ofdm_mrc_x1, calib->corr_ofdm_x4,
 3449             calib->corr_ofdm_mrc_x4, calib->corr_cck_x4,
 3450             calib->corr_cck_mrc_x4, calib->energy_cck);
 3451         return iwn_cmd(sc, IWN_SENSITIVITY, &cmd, sizeof cmd, 1);
 3452 }
 3453 
 3454 int
 3455 iwn_auth(struct iwn_softc *sc, struct ieee80211vap *vap)
 3456 {
 3457         struct ifnet *ifp = sc->sc_ifp;
 3458         struct ieee80211com *ic = ifp->if_l2com;
 3459         struct ieee80211_node *ni = vap->iv_bss;
 3460         struct iwn_node_info node;
 3461         int error;
 3462 
 3463         sc->calib.state = IWN_CALIB_STATE_INIT;
 3464 
 3465         /* update adapter's configuration */
 3466         sc->config.associd = 0;
 3467         IEEE80211_ADDR_COPY(sc->config.bssid, ni->ni_bssid);
 3468         sc->config.chan = htole16(ieee80211_chan2ieee(ic, ni->ni_chan));
 3469         sc->config.flags = htole32(IWN_CONFIG_TSF);
 3470         if (IEEE80211_IS_CHAN_2GHZ(ni->ni_chan))
 3471                 sc->config.flags |= htole32(IWN_CONFIG_AUTO | IWN_CONFIG_24GHZ);
 3472         if (IEEE80211_IS_CHAN_A(ni->ni_chan)) {
 3473                 sc->config.cck_mask  = 0;
 3474                 sc->config.ofdm_mask = 0x15;
 3475         } else if (IEEE80211_IS_CHAN_B(ni->ni_chan)) {
 3476                 sc->config.cck_mask  = 0x03;
 3477                 sc->config.ofdm_mask = 0;
 3478         } else {
 3479                 /* XXX assume 802.11b/g */
 3480                 sc->config.cck_mask  = 0x0f;
 3481                 sc->config.ofdm_mask = 0x15;
 3482         }
 3483         if (ic->ic_flags & IEEE80211_F_SHSLOT)
 3484                 sc->config.flags |= htole32(IWN_CONFIG_SHSLOT);
 3485         if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)
 3486                 sc->config.flags |= htole32(IWN_CONFIG_SHPREAMBLE);
 3487         sc->config.filter &= ~htole32(IWN_FILTER_BSS);
 3488 
 3489         DPRINTF(sc, IWN_DEBUG_STATE,
 3490            "%s: config chan %d mode %d flags 0x%x cck 0x%x ofdm 0x%x "
 3491            "ht_single 0x%x ht_dual 0x%x rxchain 0x%x "
 3492            "myaddr %6D wlap %6D bssid %6D associd %d filter 0x%x\n",
 3493            __func__,
 3494            le16toh(sc->config.chan), sc->config.mode, le32toh(sc->config.flags),
 3495            sc->config.cck_mask, sc->config.ofdm_mask,
 3496            sc->config.ht_single_mask, sc->config.ht_dual_mask,
 3497            le16toh(sc->config.rxchain),
 3498            sc->config.myaddr, ":", sc->config.wlap, ":", sc->config.bssid, ":",
 3499            le16toh(sc->config.associd), le32toh(sc->config.filter));
 3500         error = iwn_cmd(sc, IWN_CMD_CONFIGURE, &sc->config,
 3501             sizeof (struct iwn_config), 1);
 3502         if (error != 0) {
 3503                 device_printf(sc->sc_dev,
 3504                     "%s: could not configure, error %d\n", __func__, error);
 3505                 return error;
 3506         }
 3507         sc->sc_curchan = ic->ic_curchan;
 3508 
 3509         /* configuration has changed, set Tx power accordingly */
 3510         error = iwn_set_txpower(sc, ni->ni_chan, 1);
 3511         if (error != 0) {
 3512                 device_printf(sc->sc_dev,
 3513                     "%s: could not set Tx power, error %d\n", __func__, error);
 3514                 return error;
 3515         }
 3516 
 3517         /*
 3518          * Reconfiguring clears the adapter's nodes table so we must
 3519          * add the broadcast node again.
 3520          */
 3521         memset(&node, 0, sizeof node);
 3522         IEEE80211_ADDR_COPY(node.macaddr, ifp->if_broadcastaddr);
 3523         node.id = IWN_ID_BROADCAST;
 3524         DPRINTF(sc, IWN_DEBUG_STATE, "%s: add broadcast node\n", __func__);
 3525         error = iwn_cmd(sc, IWN_CMD_ADD_NODE, &node, sizeof node, 1);
 3526         if (error != 0) {
 3527                 device_printf(sc->sc_dev,
 3528                     "%s: could not add broadcast node, error %d\n",
 3529                     __func__, error);
 3530                 return error;
 3531         }
 3532         error = iwn_set_link_quality(sc, node.id, ic->ic_curchan, 1);
 3533         if (error != 0) {
 3534                 device_printf(sc->sc_dev,
 3535                     "%s: could not setup MRR for broadcast node, error %d\n",
 3536                     __func__, error);
 3537                 return error;
 3538         }
 3539 
 3540         return 0;
 3541 }
 3542 
 3543 /*
 3544  * Configure the adapter for associated state.
 3545  */
 3546 int
 3547 iwn_run(struct iwn_softc *sc, struct ieee80211vap *vap)
 3548 {
 3549 #define MS(v,x) (((v) & x) >> x##_S)
 3550         struct ifnet *ifp = sc->sc_ifp;
 3551         struct ieee80211com *ic = ifp->if_l2com;
 3552         struct ieee80211_node *ni = vap->iv_bss;
 3553         struct iwn_node_info node;
 3554         int error, maxrxampdu, ampdudensity;
 3555 
 3556         sc->calib.state = IWN_CALIB_STATE_INIT;
 3557 
 3558         if (ic->ic_opmode == IEEE80211_M_MONITOR) {
 3559                 /* link LED blinks while monitoring */
 3560                 iwn_set_led(sc, IWN_LED_LINK, 5, 5);
 3561                 return 0;
 3562         }
 3563 
 3564         iwn_enable_tsf(sc, ni);
 3565 
 3566         /* update adapter's configuration */
 3567         sc->config.associd = htole16(IEEE80211_AID(ni->ni_associd));
 3568         /* short preamble/slot time are negotiated when associating */
 3569         sc->config.flags &= ~htole32(IWN_CONFIG_SHPREAMBLE | IWN_CONFIG_SHSLOT);
 3570         if (ic->ic_flags & IEEE80211_F_SHSLOT)
 3571                 sc->config.flags |= htole32(IWN_CONFIG_SHSLOT);
 3572         if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)
 3573                 sc->config.flags |= htole32(IWN_CONFIG_SHPREAMBLE);
 3574         if (IEEE80211_IS_CHAN_HT(ni->ni_chan)) {
 3575                 sc->config.flags &= ~htole32(IWN_CONFIG_HT);
 3576                 if (IEEE80211_IS_CHAN_HT40U(ni->ni_chan))
 3577                         sc->config.flags |= htole32(IWN_CONFIG_HT40U);
 3578                 else if (IEEE80211_IS_CHAN_HT40D(ni->ni_chan))
 3579                         sc->config.flags |= htole32(IWN_CONFIG_HT40D);
 3580                 else
 3581                         sc->config.flags |= htole32(IWN_CONFIG_HT20);
 3582                 sc->config.rxchain = htole16(
 3583                           (3 << IWN_RXCHAIN_VALID_S)
 3584                         | (3 << IWN_RXCHAIN_MIMO_CNT_S)
 3585                         | (1 << IWN_RXCHAIN_CNT_S)
 3586                         | IWN_RXCHAIN_MIMO_FORCE);
 3587 
 3588                 maxrxampdu = MS(ni->ni_htparam, IEEE80211_HTCAP_MAXRXAMPDU);
 3589                 ampdudensity = MS(ni->ni_htparam, IEEE80211_HTCAP_MPDUDENSITY);
 3590         } else
 3591                 maxrxampdu = ampdudensity = 0;
 3592         sc->config.filter |= htole32(IWN_FILTER_BSS);
 3593 
 3594         DPRINTF(sc, IWN_DEBUG_STATE,
 3595            "%s: config chan %d mode %d flags 0x%x cck 0x%x ofdm 0x%x "
 3596            "ht_single 0x%x ht_dual 0x%x rxchain 0x%x "
 3597            "myaddr %6D wlap %6D bssid %6D associd %d filter 0x%x\n",
 3598            __func__,
 3599            le16toh(sc->config.chan), sc->config.mode, le32toh(sc->config.flags),
 3600            sc->config.cck_mask, sc->config.ofdm_mask,
 3601            sc->config.ht_single_mask, sc->config.ht_dual_mask,
 3602            le16toh(sc->config.rxchain),
 3603            sc->config.myaddr, ":", sc->config.wlap, ":", sc->config.bssid, ":",
 3604            le16toh(sc->config.associd), le32toh(sc->config.filter));
 3605         error = iwn_cmd(sc, IWN_CMD_CONFIGURE, &sc->config,
 3606             sizeof (struct iwn_config), 1);
 3607         if (error != 0) {
 3608                 device_printf(sc->sc_dev,
 3609                     "%s: could not update configuration, error %d\n",
 3610                     __func__, error);
 3611                 return error;
 3612         }
 3613         sc->sc_curchan = ni->ni_chan;
 3614 
 3615         /* configuration has changed, set Tx power accordingly */
 3616         error = iwn_set_txpower(sc, ni->ni_chan, 1);
 3617         if (error != 0) {
 3618                 device_printf(sc->sc_dev,
 3619                     "%s: could not set Tx power, error %d\n", __func__, error);
 3620                 return error;
 3621         }
 3622 
 3623         /* add BSS node */
 3624         memset(&node, 0, sizeof node);
 3625         IEEE80211_ADDR_COPY(node.macaddr, ni->ni_macaddr);
 3626         node.id = IWN_ID_BSS;
 3627         node.htflags = htole32(
 3628             (maxrxampdu << IWN_MAXRXAMPDU_S) |
 3629             (ampdudensity << IWN_MPDUDENSITY_S));
 3630         DPRINTF(sc, IWN_DEBUG_STATE, "%s: add BSS node, id %d htflags 0x%x\n",
 3631             __func__, node.id, le32toh(node.htflags));
 3632         error = iwn_cmd(sc, IWN_CMD_ADD_NODE, &node, sizeof node, 1);
 3633         if (error != 0) {
 3634                 device_printf(sc->sc_dev,"could not add BSS node\n");
 3635                 return error;
 3636         }
 3637         error = iwn_set_link_quality(sc, node.id, ni->ni_chan, 1);
 3638         if (error != 0) {
 3639                 device_printf(sc->sc_dev,
 3640                     "%s: could not setup MRR for node %d, error %d\n",
 3641                     __func__, node.id, error);
 3642                 return error;
 3643         }
 3644 
 3645         error = iwn_init_sensitivity(sc);
 3646         if (error != 0) {
 3647                 device_printf(sc->sc_dev,
 3648                     "%s: could not set sensitivity, error %d\n",
 3649                     __func__, error);
 3650                 return error;
 3651         }
 3652 
 3653         /* start/restart periodic calibration timer */
 3654         sc->calib.state = IWN_CALIB_STATE_ASSOC;
 3655         iwn_calib_reset(sc);
 3656 
 3657         /* link LED always on while associated */
 3658         iwn_set_led(sc, IWN_LED_LINK, 0, 1);
 3659 
 3660         return 0;
 3661 #undef MS
 3662 }
 3663 
 3664 /*
 3665  * Send a scan request to the firmware.  Since this command is huge, we map it
 3666  * into a mbuf instead of using the pre-allocated set of commands.
 3667  */
 3668 int
 3669 iwn_scan(struct iwn_softc *sc)
 3670 {
 3671         struct ifnet *ifp = sc->sc_ifp;
 3672         struct ieee80211com *ic = ifp->if_l2com;
 3673         struct ieee80211_scan_state *ss = ic->ic_scan;  /*XXX*/
 3674         struct iwn_tx_ring *ring = &sc->txq[4];
 3675         struct iwn_tx_desc *desc;
 3676         struct iwn_tx_data *data;
 3677         struct iwn_tx_cmd *cmd;
 3678         struct iwn_cmd_data *tx;
 3679         struct iwn_scan_hdr *hdr;
 3680         struct iwn_scan_essid *essid;
 3681         struct iwn_scan_chan *chan;
 3682         struct ieee80211_frame *wh;
 3683         struct ieee80211_rateset *rs;
 3684         struct ieee80211_channel *c;
 3685         enum ieee80211_phymode mode;
 3686         uint8_t *frm;
 3687         int pktlen, error, nrates;
 3688         bus_addr_t physaddr;
 3689 
 3690         desc = &ring->desc[ring->cur];
 3691         data = &ring->data[ring->cur];
 3692 
 3693         /* XXX malloc */
 3694         data->m = m_getcl(M_DONTWAIT, MT_DATA, 0);
 3695         if (data->m == NULL) {
 3696                 device_printf(sc->sc_dev,
 3697                     "%s: could not allocate mbuf for scan command\n", __func__);
 3698                 return ENOMEM;
 3699         }
 3700 
 3701         cmd = mtod(data->m, struct iwn_tx_cmd *);
 3702         cmd->code = IWN_CMD_SCAN;
 3703         cmd->flags = 0;
 3704         cmd->qid = ring->qid;
 3705         cmd->idx = ring->cur;
 3706 
 3707         hdr = (struct iwn_scan_hdr *)cmd->data;
 3708         memset(hdr, 0, sizeof (struct iwn_scan_hdr));
 3709 
 3710         /* XXX use scan state */
 3711         /*
 3712          * Move to the next channel if no packets are received within 5 msecs
 3713          * after sending the probe request (this helps to reduce the duration
 3714          * of active scans).
 3715          */
 3716         hdr->quiet = htole16(5);        /* timeout in milliseconds */
 3717         hdr->plcp_threshold = htole16(1);       /* min # of packets */
 3718 
 3719         /* select Ant B and Ant C for scanning */
 3720         hdr->rxchain = htole16(0x3e1 | (7 << IWN_RXCHAIN_VALID_S));
 3721 
 3722         tx = (struct iwn_cmd_data *)(hdr + 1);
 3723         memset(tx, 0, sizeof (struct iwn_cmd_data));
 3724         tx->flags = htole32(IWN_TX_AUTO_SEQ | 0x200);   /* XXX */
 3725         tx->id = IWN_ID_BROADCAST;
 3726         tx->lifetime = htole32(IWN_LIFETIME_INFINITE);
 3727         tx->rflags = IWN_RFLAG_ANT_B;
 3728 
 3729         if (IEEE80211_IS_CHAN_A(ic->ic_curchan)) {
 3730                 hdr->crc_threshold = htole16(1);
 3731                 /* send probe requests at 6Mbps */
 3732                 tx->rate = iwn_ridx_to_plcp[IWN_RATE_OFDM6];
 3733         } else {
 3734                 hdr->flags = htole32(IWN_CONFIG_24GHZ | IWN_CONFIG_AUTO);
 3735                 /* send probe requests at 1Mbps */
 3736                 tx->rate = iwn_ridx_to_plcp[IWN_RATE_CCK1];
 3737                 tx->rflags |= IWN_RFLAG_CCK;
 3738         }
 3739 
 3740         essid = (struct iwn_scan_essid *)(tx + 1);
 3741         memset(essid, 0, 4 * sizeof (struct iwn_scan_essid));
 3742         essid[0].id  = IEEE80211_ELEMID_SSID;
 3743         essid[0].len = ss->ss_ssid[0].len;
 3744         memcpy(essid[0].data, ss->ss_ssid[0].ssid, ss->ss_ssid[0].len);
 3745 
 3746         /*
 3747          * Build a probe request frame.  Most of the following code is a
 3748          * copy & paste of what is done in net80211.
 3749          */
 3750         wh = (struct ieee80211_frame *)&essid[4];
 3751         wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT |
 3752             IEEE80211_FC0_SUBTYPE_PROBE_REQ;
 3753         wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
 3754         IEEE80211_ADDR_COPY(wh->i_addr1, ifp->if_broadcastaddr);
 3755         IEEE80211_ADDR_COPY(wh->i_addr2, IF_LLADDR(ifp));
 3756         IEEE80211_ADDR_COPY(wh->i_addr3, ifp->if_broadcastaddr);
 3757         *(u_int16_t *)&wh->i_dur[0] = 0;        /* filled by h/w */
 3758         *(u_int16_t *)&wh->i_seq[0] = 0;        /* filled by h/w */
 3759 
 3760         frm = (uint8_t *)(wh + 1);
 3761 
 3762         /* add SSID IE */
 3763         *frm++ = IEEE80211_ELEMID_SSID;
 3764         *frm++ = ss->ss_ssid[0].len;
 3765         memcpy(frm, ss->ss_ssid[0].ssid, ss->ss_ssid[0].len);
 3766         frm += ss->ss_ssid[0].len;
 3767 
 3768         mode = ieee80211_chan2mode(ic->ic_curchan);
 3769         rs = &ic->ic_sup_rates[mode];
 3770 
 3771         /* add supported rates IE */
 3772         *frm++ = IEEE80211_ELEMID_RATES;
 3773         nrates = rs->rs_nrates;
 3774         if (nrates > IEEE80211_RATE_SIZE)
 3775                 nrates = IEEE80211_RATE_SIZE;
 3776         *frm++ = nrates;
 3777         memcpy(frm, rs->rs_rates, nrates);
 3778         frm += nrates;
 3779 
 3780         /* add supported xrates IE */
 3781         if (rs->rs_nrates > IEEE80211_RATE_SIZE) {
 3782                 nrates = rs->rs_nrates - IEEE80211_RATE_SIZE;
 3783                 *frm++ = IEEE80211_ELEMID_XRATES;
 3784                 *frm++ = (uint8_t)nrates;
 3785                 memcpy(frm, rs->rs_rates + IEEE80211_RATE_SIZE, nrates);
 3786                 frm += nrates;
 3787         }
 3788 
 3789         /* setup length of probe request */
 3790         tx->len = htole16(frm - (uint8_t *)wh);
 3791 
 3792         c = ic->ic_curchan;
 3793         chan = (struct iwn_scan_chan *)frm;
 3794         chan->chan = ieee80211_chan2ieee(ic, c);
 3795         chan->flags = 0;
 3796         if ((c->ic_flags & IEEE80211_CHAN_PASSIVE) == 0) {
 3797                 chan->flags |= IWN_CHAN_ACTIVE;
 3798                 if (ss->ss_nssid > 0)
 3799                         chan->flags |= IWN_CHAN_DIRECT;
 3800         }
 3801         chan->dsp_gain = 0x6e;
 3802         if (IEEE80211_IS_CHAN_5GHZ(c)) {
 3803                 chan->rf_gain = 0x3b;
 3804                 chan->active  = htole16(10);
 3805                 chan->passive = htole16(110);
 3806         } else {
 3807                 chan->rf_gain = 0x28;
 3808                 chan->active  = htole16(20);
 3809                 chan->passive = htole16(120);
 3810         }
 3811 
 3812         DPRINTF(sc, IWN_DEBUG_STATE, "%s: chan %u flags 0x%x rf_gain 0x%x "
 3813             "dsp_gain 0x%x active 0x%x passive 0x%x\n", __func__,
 3814             chan->chan, chan->flags, chan->rf_gain, chan->dsp_gain,
 3815             chan->active, chan->passive);
 3816         hdr->nchan++;
 3817         chan++;
 3818 
 3819         frm += sizeof (struct iwn_scan_chan);
 3820 
 3821         hdr->len = htole16(frm - (uint8_t *)hdr);
 3822         pktlen = frm - (uint8_t *)cmd;
 3823 
 3824         error = bus_dmamap_load(ring->data_dmat, data->map, cmd, pktlen,
 3825             iwn_dma_map_addr, &physaddr, BUS_DMA_NOWAIT);
 3826         if (error != 0) {
 3827                 device_printf(sc->sc_dev,
 3828                     "%s: could not map scan command, error %d\n",
 3829                     __func__, error);
 3830                 m_freem(data->m);
 3831                 data->m = NULL;
 3832                 return error;
 3833         }
 3834 
 3835         IWN_SET_DESC_NSEGS(desc, 1);
 3836         IWN_SET_DESC_SEG(desc, 0, physaddr, pktlen);
 3837         sc->shared->len[ring->qid][ring->cur] = htole16(8);
 3838         if (ring->cur < IWN_TX_WINDOW)
 3839                 sc->shared->len[ring->qid][ring->cur + IWN_TX_RING_COUNT] =
 3840                     htole16(8);
 3841 
 3842         bus_dmamap_sync(ring->desc_dma.tag, ring->desc_dma.map,
 3843             BUS_DMASYNC_PREWRITE);
 3844         bus_dmamap_sync(ring->data_dmat, data->map, BUS_DMASYNC_PREWRITE);
 3845 
 3846         /* kick cmd ring */
 3847         ring->cur = (ring->cur + 1) % IWN_TX_RING_COUNT;
 3848         IWN_WRITE(sc, IWN_TX_WIDX, ring->qid << 8 | ring->cur);
 3849 
 3850         return 0;       /* will be notified async. of failure/success */
 3851 }
 3852 
 3853 int
 3854 iwn_config(struct iwn_softc *sc)
 3855 {
 3856         struct ifnet *ifp = sc->sc_ifp;
 3857         struct ieee80211com *ic = ifp->if_l2com;
 3858         struct iwn_power power;
 3859         struct iwn_bluetooth bluetooth;
 3860         struct iwn_node_info node;
 3861         int error;
 3862 
 3863         /* set power mode */
 3864         memset(&power, 0, sizeof power);
 3865         power.flags = htole16(IWN_POWER_CAM | 0x8);
 3866         DPRINTF(sc, IWN_DEBUG_RESET, "%s: set power mode\n", __func__);
 3867         error = iwn_cmd(sc, IWN_CMD_SET_POWER_MODE, &power, sizeof power, 0);
 3868         if (error != 0) {
 3869                 device_printf(sc->sc_dev,
 3870                     "%s: could not set power mode, error %d\n",
 3871                     __func__, error);
 3872                 return error;
 3873         }
 3874 
 3875         /* configure bluetooth coexistence */
 3876         memset(&bluetooth, 0, sizeof bluetooth);
 3877         bluetooth.flags = 3;
 3878         bluetooth.lead = 0xaa;
 3879         bluetooth.kill = 1;
 3880         DPRINTF(sc, IWN_DEBUG_RESET, "%s: config bluetooth coexistence\n",
 3881             __func__);
 3882         error = iwn_cmd(sc, IWN_CMD_BLUETOOTH, &bluetooth, sizeof bluetooth,
 3883             0);
 3884         if (error != 0) {
 3885                 device_printf(sc->sc_dev,
 3886                     "%s: could not configure bluetooth coexistence, error %d\n",
 3887                     __func__, error);
 3888                 return error;
 3889         }
 3890 
 3891         /* configure adapter */
 3892         memset(&sc->config, 0, sizeof (struct iwn_config));
 3893         IEEE80211_ADDR_COPY(sc->config.myaddr, IF_LLADDR(ifp));
 3894         IEEE80211_ADDR_COPY(sc->config.wlap, IF_LLADDR(ifp));
 3895         /* set default channel */
 3896         sc->config.chan = htole16(ieee80211_chan2ieee(ic, ic->ic_curchan));
 3897         sc->config.flags = htole32(IWN_CONFIG_TSF);
 3898         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
 3899                 sc->config.flags |= htole32(IWN_CONFIG_AUTO | IWN_CONFIG_24GHZ);
 3900         sc->config.filter = 0;
 3901         switch (ic->ic_opmode) {
 3902         case IEEE80211_M_STA:
 3903                 sc->config.mode = IWN_MODE_STA;
 3904                 sc->config.filter |= htole32(IWN_FILTER_MULTICAST);
 3905                 break;
 3906         case IEEE80211_M_IBSS:
 3907         case IEEE80211_M_AHDEMO:
 3908                 sc->config.mode = IWN_MODE_IBSS;
 3909                 break;
 3910         case IEEE80211_M_HOSTAP:
 3911                 sc->config.mode = IWN_MODE_HOSTAP;
 3912                 break;
 3913         case IEEE80211_M_MONITOR:
 3914                 sc->config.mode = IWN_MODE_MONITOR;
 3915                 sc->config.filter |= htole32(IWN_FILTER_MULTICAST |
 3916                     IWN_FILTER_CTL | IWN_FILTER_PROMISC);
 3917                 break;
 3918         default:
 3919                 device_printf(sc->sc_dev, "unknown opmode %d\n", ic->ic_opmode);
 3920                 return EINVAL;
 3921         }
 3922         sc->config.cck_mask  = 0x0f;    /* not yet negotiated */
 3923         sc->config.ofdm_mask = 0xff;    /* not yet negotiated */
 3924         sc->config.ht_single_mask = 0xff;
 3925         sc->config.ht_dual_mask = 0xff;
 3926         sc->config.rxchain = htole16(0x2800 | (7 << IWN_RXCHAIN_VALID_S));
 3927 
 3928         DPRINTF(sc, IWN_DEBUG_STATE,
 3929            "%s: config chan %d mode %d flags 0x%x cck 0x%x ofdm 0x%x "
 3930            "ht_single 0x%x ht_dual 0x%x rxchain 0x%x "
 3931            "myaddr %6D wlap %6D bssid %6D associd %d filter 0x%x\n",
 3932            __func__,
 3933            le16toh(sc->config.chan), sc->config.mode, le32toh(sc->config.flags),
 3934            sc->config.cck_mask, sc->config.ofdm_mask,
 3935            sc->config.ht_single_mask, sc->config.ht_dual_mask,
 3936            le16toh(sc->config.rxchain),
 3937            sc->config.myaddr, ":", sc->config.wlap, ":", sc->config.bssid, ":",
 3938            le16toh(sc->config.associd), le32toh(sc->config.filter));
 3939         error = iwn_cmd(sc, IWN_CMD_CONFIGURE, &sc->config,
 3940             sizeof (struct iwn_config), 0);
 3941         if (error != 0) {
 3942                 device_printf(sc->sc_dev,
 3943                     "%s: configure command failed, error %d\n",
 3944                     __func__, error);
 3945                 return error;
 3946         }
 3947         sc->sc_curchan = ic->ic_curchan;
 3948 
 3949         /* configuration has changed, set Tx power accordingly */
 3950         error = iwn_set_txpower(sc, ic->ic_curchan, 0);
 3951         if (error != 0) {
 3952                 device_printf(sc->sc_dev,
 3953                     "%s: could not set Tx power, error %d\n", __func__, error);
 3954                 return error;
 3955         }
 3956 
 3957         /* add broadcast node */
 3958         memset(&node, 0, sizeof node);
 3959         IEEE80211_ADDR_COPY(node.macaddr, ic->ic_ifp->if_broadcastaddr);
 3960         node.id = IWN_ID_BROADCAST;
 3961         node.rate = iwn_plcp_signal(2);
 3962         DPRINTF(sc, IWN_DEBUG_RESET, "%s: add broadcast node\n", __func__);
 3963         error = iwn_cmd(sc, IWN_CMD_ADD_NODE, &node, sizeof node, 0);
 3964         if (error != 0) {
 3965                 device_printf(sc->sc_dev,
 3966                     "%s: could not add broadcast node, error %d\n",
 3967                     __func__, error);
 3968                 return error;
 3969         }
 3970         error = iwn_set_link_quality(sc, node.id, ic->ic_curchan, 0);
 3971         if (error != 0) {
 3972                 device_printf(sc->sc_dev,
 3973                     "%s: could not setup MRR for node %d, error %d\n",
 3974                     __func__, node.id, error);
 3975                 return error;
 3976         }
 3977 
 3978         error = iwn_set_critical_temp(sc);
 3979         if (error != 0) {
 3980                 device_printf(sc->sc_dev,
 3981                     "%s: could not set critical temperature, error %d\n",
 3982                     __func__, error);
 3983                 return error;
 3984         }
 3985         return 0;
 3986 }
 3987 
 3988 /*
 3989  * Do post-alive initialization of the NIC (after firmware upload).
 3990  */
 3991 void
 3992 iwn_post_alive(struct iwn_softc *sc)
 3993 {
 3994         uint32_t base;
 3995         uint16_t offset;
 3996         int qid;
 3997 
 3998         iwn_mem_lock(sc);
 3999 
 4000         /* clear SRAM */
 4001         base = iwn_mem_read(sc, IWN_SRAM_BASE);
 4002         for (offset = 0x380; offset < 0x520; offset += 4) {
 4003                 IWN_WRITE(sc, IWN_MEM_WADDR, base + offset);
 4004                 IWN_WRITE(sc, IWN_MEM_WDATA, 0);
 4005         }
 4006 
 4007         /* shared area is aligned on a 1K boundary */
 4008         iwn_mem_write(sc, IWN_SRAM_BASE, sc->shared_dma.paddr >> 10);
 4009         iwn_mem_write(sc, IWN_SELECT_QCHAIN, 0);
 4010 
 4011         for (qid = 0; qid < IWN_NTXQUEUES; qid++) {
 4012                 iwn_mem_write(sc, IWN_QUEUE_RIDX(qid), 0);
 4013                 IWN_WRITE(sc, IWN_TX_WIDX, qid << 8 | 0);
 4014 
 4015                 /* set sched. window size */
 4016                 IWN_WRITE(sc, IWN_MEM_WADDR, base + IWN_QUEUE_OFFSET(qid));
 4017                 IWN_WRITE(sc, IWN_MEM_WDATA, 64);
 4018                 /* set sched. frame limit */
 4019                 IWN_WRITE(sc, IWN_MEM_WADDR, base + IWN_QUEUE_OFFSET(qid) + 4);
 4020                 IWN_WRITE(sc, IWN_MEM_WDATA, 10 << 16);
 4021         }
 4022 
 4023         /* enable interrupts for all 16 queues */
 4024         iwn_mem_write(sc, IWN_QUEUE_INTR_MASK, 0xffff);
 4025 
 4026         /* identify active Tx rings (0-7) */
 4027         iwn_mem_write(sc, IWN_TX_ACTIVE, 0xff);
 4028 
 4029         /* mark Tx rings (4 EDCA + cmd + 2 HCCA) as active */
 4030         for (qid = 0; qid < 7; qid++) {
 4031                 iwn_mem_write(sc, IWN_TXQ_STATUS(qid),
 4032                     IWN_TXQ_STATUS_ACTIVE | qid << 1);
 4033         }
 4034 
 4035         iwn_mem_unlock(sc);
 4036 }
 4037 
 4038 void
 4039 iwn_stop_master(struct iwn_softc *sc)
 4040 {
 4041         uint32_t tmp;
 4042         int ntries;
 4043 
 4044         tmp = IWN_READ(sc, IWN_RESET);
 4045         IWN_WRITE(sc, IWN_RESET, tmp | IWN_STOP_MASTER);
 4046 
 4047         tmp = IWN_READ(sc, IWN_GPIO_CTL);
 4048         if ((tmp & IWN_GPIO_PWR_STATUS) == IWN_GPIO_PWR_SLEEP)
 4049                 return; /* already asleep */
 4050 
 4051         for (ntries = 0; ntries < 100; ntries++) {
 4052                 if (IWN_READ(sc, IWN_RESET) & IWN_MASTER_DISABLED)
 4053                         break;
 4054                 DELAY(10);
 4055         }
 4056         if (ntries == 100)
 4057                 device_printf(sc->sc_dev,
 4058                     "%s: timeout waiting for master\n", __func__);
 4059 }
 4060 
 4061 int
 4062 iwn_reset(struct iwn_softc *sc)
 4063 {
 4064         uint32_t tmp;
 4065         int ntries;
 4066 
 4067         /* clear any pending interrupts */
 4068         IWN_WRITE(sc, IWN_INTR, 0xffffffff);
 4069 
 4070         tmp = IWN_READ(sc, IWN_CHICKEN);
 4071         IWN_WRITE(sc, IWN_CHICKEN, tmp | IWN_CHICKEN_DISLOS);
 4072 
 4073         tmp = IWN_READ(sc, IWN_GPIO_CTL);
 4074         IWN_WRITE(sc, IWN_GPIO_CTL, tmp | IWN_GPIO_INIT);
 4075 
 4076         /* wait for clock stabilization */
 4077         for (ntries = 0; ntries < 1000; ntries++) {
 4078                 if (IWN_READ(sc, IWN_GPIO_CTL) & IWN_GPIO_CLOCK)
 4079                         break;
 4080                 DELAY(10);
 4081         }
 4082         if (ntries == 1000) {
 4083                 device_printf(sc->sc_dev,
 4084                     "%s: timeout waiting for clock stabilization\n", __func__);
 4085                 return ETIMEDOUT;
 4086         }
 4087         return 0;
 4088 }
 4089 
 4090 void
 4091 iwn_hw_config(struct iwn_softc *sc)
 4092 {
 4093         uint32_t tmp, hw;
 4094 
 4095         /* enable interrupts mitigation */
 4096         IWN_WRITE(sc, IWN_INTR_MIT, 512 / 32);
 4097 
 4098         /* voodoo from the reference driver */
 4099         tmp = pci_read_config(sc->sc_dev, PCIR_REVID,1);
 4100         if ((tmp & 0x80) && (tmp & 0x7f) < 8) {
 4101                 /* enable "no snoop" field */
 4102                 tmp = pci_read_config(sc->sc_dev, 0xe8, 1);
 4103                 tmp &= ~IWN_DIS_NOSNOOP;
 4104                 /* clear device specific PCI configuration register 0x41 */
 4105                 pci_write_config(sc->sc_dev, 0xe8, tmp, 1);
 4106         }
 4107 
 4108         /* disable L1 entry to work around a hardware bug */
 4109         tmp = pci_read_config(sc->sc_dev, 0xf0, 1);
 4110         tmp &= ~IWN_ENA_L1;
 4111         pci_write_config(sc->sc_dev, 0xf0, tmp, 1 );
 4112 
 4113         hw = IWN_READ(sc, IWN_HWCONFIG);
 4114         IWN_WRITE(sc, IWN_HWCONFIG, hw | 0x310);
 4115 
 4116         iwn_mem_lock(sc);
 4117         tmp = iwn_mem_read(sc, IWN_MEM_POWER);
 4118         iwn_mem_write(sc, IWN_MEM_POWER, tmp | IWN_POWER_RESET);
 4119         DELAY(5);
 4120         tmp = iwn_mem_read(sc, IWN_MEM_POWER);
 4121         iwn_mem_write(sc, IWN_MEM_POWER, tmp & ~IWN_POWER_RESET);
 4122         iwn_mem_unlock(sc);
 4123 }
 4124 
 4125 void
 4126 iwn_init_locked(struct iwn_softc *sc)
 4127 {
 4128         struct ifnet *ifp = sc->sc_ifp;
 4129         uint32_t tmp;
 4130         int error, qid;
 4131 
 4132         IWN_LOCK_ASSERT(sc);
 4133 
 4134         /* load the firmware */
 4135         if (sc->fw_fp == NULL && (error = iwn_load_firmware(sc)) != 0) {
 4136                 device_printf(sc->sc_dev,
 4137                     "%s: could not load firmware, error %d\n", __func__, error);
 4138                 return;
 4139         }
 4140 
 4141         error = iwn_reset(sc);
 4142         if (error != 0) {
 4143                 device_printf(sc->sc_dev,
 4144                     "%s: could not reset adapter, error %d\n", __func__, error);
 4145                 return;
 4146         }
 4147 
 4148         iwn_mem_lock(sc);
 4149         iwn_mem_read(sc, IWN_CLOCK_CTL);
 4150         iwn_mem_write(sc, IWN_CLOCK_CTL, 0xa00);
 4151         iwn_mem_read(sc, IWN_CLOCK_CTL);
 4152         iwn_mem_unlock(sc);
 4153 
 4154         DELAY(20);
 4155 
 4156         iwn_mem_lock(sc);
 4157         tmp = iwn_mem_read(sc, IWN_MEM_PCIDEV);
 4158         iwn_mem_write(sc, IWN_MEM_PCIDEV, tmp | 0x800);
 4159         iwn_mem_unlock(sc);
 4160 
 4161         iwn_mem_lock(sc);
 4162         tmp = iwn_mem_read(sc, IWN_MEM_POWER);
 4163         iwn_mem_write(sc, IWN_MEM_POWER, tmp & ~0x03000000);
 4164         iwn_mem_unlock(sc);
 4165 
 4166         iwn_hw_config(sc);
 4167 
 4168         /* init Rx ring */
 4169         iwn_mem_lock(sc);
 4170         IWN_WRITE(sc, IWN_RX_CONFIG, 0);
 4171         IWN_WRITE(sc, IWN_RX_WIDX, 0);
 4172         /* Rx ring is aligned on a 256-byte boundary */
 4173         IWN_WRITE(sc, IWN_RX_BASE, sc->rxq.desc_dma.paddr >> 8);
 4174         /* shared area is aligned on a 16-byte boundary */
 4175         IWN_WRITE(sc, IWN_RW_WIDX_PTR, (sc->shared_dma.paddr +
 4176             offsetof(struct iwn_shared, closed_count)) >> 4);
 4177         IWN_WRITE(sc, IWN_RX_CONFIG, 0x80601000);
 4178         iwn_mem_unlock(sc);
 4179 
 4180         IWN_WRITE(sc, IWN_RX_WIDX, (IWN_RX_RING_COUNT - 1) & ~7);
 4181 
 4182         iwn_mem_lock(sc);
 4183         iwn_mem_write(sc, IWN_TX_ACTIVE, 0);
 4184 
 4185         /* set physical address of "keep warm" page */
 4186         IWN_WRITE(sc, IWN_KW_BASE, sc->kw_dma.paddr >> 4);
 4187 
 4188         /* init Tx rings */
 4189         for (qid = 0; qid < IWN_NTXQUEUES; qid++) {
 4190                 struct iwn_tx_ring *txq = &sc->txq[qid];
 4191                 IWN_WRITE(sc, IWN_TX_BASE(qid), txq->desc_dma.paddr >> 8);
 4192                 IWN_WRITE(sc, IWN_TX_CONFIG(qid), 0x80000008);
 4193         }
 4194         iwn_mem_unlock(sc);
 4195 
 4196         /* clear "radio off" and "disable command" bits (reversed logic) */
 4197         IWN_WRITE(sc, IWN_UCODE_CLR, IWN_RADIO_OFF);
 4198         IWN_WRITE(sc, IWN_UCODE_CLR, IWN_DISABLE_CMD);
 4199 
 4200         /* clear any pending interrupts */
 4201         IWN_WRITE(sc, IWN_INTR, 0xffffffff);
 4202         /* enable interrupts */
 4203         IWN_WRITE(sc, IWN_MASK, IWN_INTR_MASK);
 4204 
 4205         /* not sure why/if this is necessary... */
 4206         IWN_WRITE(sc, IWN_UCODE_CLR, IWN_RADIO_OFF);
 4207         IWN_WRITE(sc, IWN_UCODE_CLR, IWN_RADIO_OFF);
 4208 
 4209         /* check that the radio is not disabled by RF switch */
 4210         if (!(IWN_READ(sc, IWN_GPIO_CTL) & IWN_GPIO_RF_ENABLED)) {
 4211                 device_printf(sc->sc_dev,
 4212                     "radio is disabled by hardware switch\n");
 4213                 return;
 4214         }
 4215 
 4216         error = iwn_transfer_firmware(sc);
 4217         if (error != 0) {
 4218                 device_printf(sc->sc_dev,
 4219                     "%s: could not load firmware, error %d\n", __func__, error);
 4220                 return;
 4221         }
 4222 
 4223         /* firmware has notified us that it is alive.. */
 4224         iwn_post_alive(sc);     /* ..do post alive initialization */
 4225 
 4226         sc->rawtemp = sc->ucode_info.temp[3].chan20MHz;
 4227         sc->temp = iwn_get_temperature(sc);
 4228         DPRINTF(sc, IWN_DEBUG_RESET, "%s: temperature=%d\n",
 4229            __func__, sc->temp);
 4230 
 4231         error = iwn_config(sc);
 4232         if (error != 0) {
 4233                 device_printf(sc->sc_dev,
 4234                     "%s: could not configure device, error %d\n",
 4235                     __func__, error);
 4236                 return;
 4237         }
 4238 
 4239         ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 4240         ifp->if_drv_flags |= IFF_DRV_RUNNING;
 4241 }
 4242 
 4243 void
 4244 iwn_init(void *arg)
 4245 {
 4246         struct iwn_softc *sc = arg;
 4247         struct ifnet *ifp = sc->sc_ifp;
 4248         struct ieee80211com *ic = ifp->if_l2com;
 4249 
 4250         IWN_LOCK(sc);
 4251         iwn_init_locked(sc);
 4252         IWN_UNLOCK(sc);
 4253 
 4254         if (ifp->if_drv_flags & IFF_DRV_RUNNING)
 4255                 ieee80211_start_all(ic);
 4256 }
 4257 
 4258 void
 4259 iwn_stop_locked(struct iwn_softc *sc)
 4260 {
 4261         struct ifnet *ifp = sc->sc_ifp;
 4262         uint32_t tmp;
 4263         int i;
 4264 
 4265         IWN_LOCK_ASSERT(sc);
 4266 
 4267         IWN_WRITE(sc, IWN_RESET, IWN_NEVO_RESET);
 4268 
 4269         sc->sc_tx_timer = 0;
 4270         callout_stop(&sc->sc_timer_to);
 4271         ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
 4272 
 4273         /* disable interrupts */
 4274         IWN_WRITE(sc, IWN_MASK, 0);
 4275         IWN_WRITE(sc, IWN_INTR, 0xffffffff);
 4276         IWN_WRITE(sc, IWN_INTR_STATUS, 0xffffffff);
 4277 
 4278         /* reset all Tx rings */
 4279         for (i = 0; i < IWN_NTXQUEUES; i++)
 4280                 iwn_reset_tx_ring(sc, &sc->txq[i]);
 4281 
 4282         /* reset Rx ring */
 4283         iwn_reset_rx_ring(sc, &sc->rxq);
 4284 
 4285         iwn_mem_lock(sc);
 4286         iwn_mem_write(sc, IWN_MEM_CLOCK2, 0x200);
 4287         iwn_mem_unlock(sc);
 4288 
 4289         DELAY(5);
 4290         iwn_stop_master(sc);
 4291 
 4292         tmp = IWN_READ(sc, IWN_RESET);
 4293         IWN_WRITE(sc, IWN_RESET, tmp | IWN_SW_RESET);
 4294 }
 4295 
 4296 void
 4297 iwn_stop(struct iwn_softc *sc)
 4298 {
 4299         IWN_LOCK(sc);
 4300         iwn_stop_locked(sc);
 4301         IWN_UNLOCK(sc);
 4302 }
 4303 
 4304 /*
 4305  * Callback from net80211 to start a scan.
 4306  */
 4307 static void
 4308 iwn_scan_start(struct ieee80211com *ic)
 4309 {
 4310         struct ifnet *ifp = ic->ic_ifp;
 4311         struct iwn_softc *sc = ifp->if_softc;
 4312 
 4313         IWN_LOCK(sc);
 4314         /* make the link LED blink while we're scanning */
 4315         iwn_set_led(sc, IWN_LED_LINK, 20, 2);
 4316         IWN_UNLOCK(sc);
 4317 }
 4318 
 4319 /*
 4320  * Callback from net80211 to terminate a scan.
 4321  */
 4322 static void
 4323 iwn_scan_end(struct ieee80211com *ic)
 4324 {
 4325         /* ignore */
 4326 }
 4327 
 4328 /*
 4329  * Callback from net80211 to force a channel change.
 4330  */
 4331 static void
 4332 iwn_set_channel(struct ieee80211com *ic)
 4333 {
 4334         struct ifnet *ifp = ic->ic_ifp;
 4335         struct iwn_softc *sc = ifp->if_softc;
 4336         struct ieee80211vap *vap;
 4337         const struct ieee80211_channel *c = ic->ic_curchan;
 4338         int error;
 4339 
 4340         vap = TAILQ_FIRST(&ic->ic_vaps);        /* XXX */
 4341 
 4342         IWN_LOCK(sc);
 4343         if (c != sc->sc_curchan) {
 4344                 sc->sc_rxtap.wr_chan_freq = htole16(c->ic_freq);
 4345                 sc->sc_rxtap.wr_chan_flags = htole16(c->ic_flags);
 4346                 sc->sc_txtap.wt_chan_freq = htole16(c->ic_freq);
 4347                 sc->sc_txtap.wt_chan_flags = htole16(c->ic_flags);
 4348 
 4349                 error = iwn_config(sc);
 4350                 if (error != 0) {
 4351                         DPRINTF(sc, IWN_DEBUG_STATE,
 4352                             "%s: set chan failed, cancel scan\n",
 4353                             __func__);
 4354                         //XXX Handle failed scan correctly
 4355                         ieee80211_cancel_scan(vap);
 4356                 }
 4357         }
 4358         IWN_UNLOCK(sc);
 4359 }
 4360 
 4361 /*
 4362  * Callback from net80211 to start scanning of the current channel.
 4363  */
 4364 static void
 4365 iwn_scan_curchan(struct ieee80211_scan_state *ss, unsigned long maxdwell)
 4366 {
 4367         struct ieee80211vap *vap = ss->ss_vap;
 4368         struct iwn_softc *sc = vap->iv_ic->ic_ifp->if_softc;
 4369         int error;
 4370 
 4371         IWN_LOCK(sc);
 4372         error = iwn_scan(sc);
 4373         IWN_UNLOCK(sc);
 4374         if (error != 0)
 4375                 ieee80211_cancel_scan(vap);
 4376 }
 4377 
 4378 /*
 4379  * Callback from net80211 to handle the minimum dwell time being met.
 4380  * The intent is to terminate the scan but we just let the firmware
 4381  * notify us when it's finished as we have no safe way to abort it.
 4382  */
 4383 static void
 4384 iwn_scan_mindwell(struct ieee80211_scan_state *ss)
 4385 {
 4386         /* NB: don't try to abort scan; wait for firmware to finish */
 4387 }
 4388 
 4389 static void
 4390 iwn_hwreset(void *arg0, int pending)
 4391 {
 4392         struct iwn_softc *sc = arg0;
 4393         struct ifnet *ifp = sc->sc_ifp;
 4394         struct ieee80211com *ic = ifp->if_l2com;
 4395 
 4396         iwn_init(sc);
 4397         ieee80211_notify_radio(ic, 1);
 4398 }
 4399 
 4400 static void
 4401 iwn_radioon(void *arg0, int pending)
 4402 {
 4403         struct iwn_softc *sc = arg0;
 4404 
 4405         iwn_init(sc);
 4406 }
 4407 
 4408 static void
 4409 iwn_radiooff(void *arg0, int pending)
 4410 {
 4411         struct iwn_softc *sc = arg0;
 4412         struct ifnet *ifp = sc->sc_ifp;
 4413         struct ieee80211com *ic = ifp->if_l2com;
 4414 
 4415         IWN_LOCK(sc);
 4416         ieee80211_notify_radio(ic, 0);
 4417         iwn_stop_locked(sc);
 4418         IWN_UNLOCK(sc);
 4419 }
 4420 
 4421 static void
 4422 iwn_sysctlattach(struct iwn_softc *sc)
 4423 {
 4424         struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev);
 4425         struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev);
 4426 
 4427 #ifdef IWN_DEBUG
 4428         sc->sc_debug = 0;
 4429         SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
 4430             "debug", CTLFLAG_RW, &sc->sc_debug, 0, "control debugging printfs");
 4431 #endif
 4432 }
 4433 
 4434 #ifdef IWN_DEBUG
 4435 static const char *
 4436 iwn_intr_str(uint8_t cmd)
 4437 {
 4438         switch (cmd) {
 4439         /* Notifications */
 4440         case IWN_UC_READY:              return "UC_READY";
 4441         case IWN_ADD_NODE_DONE:         return "ADD_NODE_DONE";
 4442         case IWN_TX_DONE:               return "TX_DONE";
 4443         case IWN_START_SCAN:            return "START_SCAN";
 4444         case IWN_STOP_SCAN:             return "STOP_SCAN";
 4445         case IWN_RX_STATISTICS:         return "RX_STATS";
 4446         case IWN_BEACON_STATISTICS:     return "BEACON_STATS";
 4447         case IWN_STATE_CHANGED:         return "STATE_CHANGED";
 4448         case IWN_BEACON_MISSED:         return "BEACON_MISSED";
 4449         case IWN_AMPDU_RX_START:        return "AMPDU_RX_START";
 4450         case IWN_AMPDU_RX_DONE:         return "AMPDU_RX_DONE";
 4451         case IWN_RX_DONE:               return "RX_DONE";
 4452 
 4453         /* Command Notifications */
 4454         case IWN_CMD_CONFIGURE:         return "IWN_CMD_CONFIGURE";
 4455         case IWN_CMD_ASSOCIATE:         return "IWN_CMD_ASSOCIATE";
 4456         case IWN_CMD_EDCA_PARAMS:       return "IWN_CMD_EDCA_PARAMS";
 4457         case IWN_CMD_TSF:               return "IWN_CMD_TSF";
 4458         case IWN_CMD_TX_LINK_QUALITY:   return "IWN_CMD_TX_LINK_QUALITY";
 4459         case IWN_CMD_SET_LED:           return "IWN_CMD_SET_LED";
 4460         case IWN_CMD_SET_POWER_MODE:    return "IWN_CMD_SET_POWER_MODE";
 4461         case IWN_CMD_SCAN:              return "IWN_CMD_SCAN";
 4462         case IWN_CMD_TXPOWER:           return "IWN_CMD_TXPOWER";
 4463         case IWN_CMD_BLUETOOTH:         return "IWN_CMD_BLUETOOTH";
 4464         case IWN_CMD_SET_CRITICAL_TEMP: return "IWN_CMD_SET_CRITICAL_TEMP";
 4465         case IWN_SENSITIVITY:           return "IWN_SENSITIVITY";
 4466         case IWN_PHY_CALIB:             return "IWN_PHY_CALIB";
 4467         }
 4468         return "UNKNOWN INTR NOTIF/CMD";
 4469 }
 4470 #endif /* IWN_DEBUG */
 4471 
 4472 static device_method_t iwn_methods[] = {
 4473         /* Device interface */
 4474         DEVMETHOD(device_probe,         iwn_probe),
 4475         DEVMETHOD(device_attach,        iwn_attach),
 4476         DEVMETHOD(device_detach,        iwn_detach),
 4477         DEVMETHOD(device_shutdown,      iwn_shutdown),
 4478         DEVMETHOD(device_suspend,       iwn_suspend),
 4479         DEVMETHOD(device_resume,        iwn_resume),
 4480 
 4481         { 0, 0 }
 4482 };
 4483 
 4484 static driver_t iwn_driver = {
 4485         "iwn",
 4486         iwn_methods,
 4487         sizeof (struct iwn_softc)
 4488 };
 4489 static devclass_t iwn_devclass;
 4490 DRIVER_MODULE(iwn, pci, iwn_driver, iwn_devclass, 0, 0);
 4491 MODULE_DEPEND(iwn, pci, 1, 1, 1);
 4492 MODULE_DEPEND(iwn, firmware, 1, 1, 1);
 4493 MODULE_DEPEND(iwn, wlan, 1, 1, 1);
 4494 MODULE_DEPEND(iwn, wlan_amrr, 1, 1, 1);

Cache object: cb9b4956f76f417a7f07f052b562a723


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