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-2009
    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 WiFi Link 4965 and 1000/5000/6000 Series 802.11 network
   23  * adapters.
   24  */
   25 
   26 #include <sys/cdefs.h>
   27 __FBSDID("$FreeBSD: releng/8.1/sys/dev/iwn/if_iwn.c 207927 2010-05-11 17:21:54Z bschmidt $");
   28 
   29 #include <sys/param.h>
   30 #include <sys/sockio.h>
   31 #include <sys/sysctl.h>
   32 #include <sys/mbuf.h>
   33 #include <sys/kernel.h>
   34 #include <sys/socket.h>
   35 #include <sys/systm.h>
   36 #include <sys/malloc.h>
   37 #include <sys/bus.h>
   38 #include <sys/rman.h>
   39 #include <sys/endian.h>
   40 #include <sys/firmware.h>
   41 #include <sys/limits.h>
   42 #include <sys/module.h>
   43 #include <sys/queue.h>
   44 #include <sys/taskqueue.h>
   45 
   46 #include <machine/bus.h>
   47 #include <machine/resource.h>
   48 #include <machine/clock.h>
   49 
   50 #include <dev/pci/pcireg.h>
   51 #include <dev/pci/pcivar.h>
   52 
   53 #include <net/bpf.h>
   54 #include <net/if.h>
   55 #include <net/if_arp.h>
   56 #include <net/ethernet.h>
   57 #include <net/if_dl.h>
   58 #include <net/if_media.h>
   59 #include <net/if_types.h>
   60 
   61 #include <netinet/in.h>
   62 #include <netinet/in_systm.h>
   63 #include <netinet/in_var.h>
   64 #include <netinet/if_ether.h>
   65 #include <netinet/ip.h>
   66 
   67 #include <net80211/ieee80211_var.h>
   68 #include <net80211/ieee80211_radiotap.h>
   69 #include <net80211/ieee80211_regdomain.h>
   70 #include <net80211/ieee80211_ratectl.h>
   71 
   72 #include <dev/iwn/if_iwnreg.h>
   73 #include <dev/iwn/if_iwnvar.h>
   74 
   75 static int      iwn_probe(device_t);
   76 static int      iwn_attach(device_t);
   77 static const struct iwn_hal *iwn_hal_attach(struct iwn_softc *);
   78 static void     iwn_radiotap_attach(struct iwn_softc *);
   79 static struct ieee80211vap *iwn_vap_create(struct ieee80211com *,
   80                     const char name[IFNAMSIZ], int unit, int opmode,
   81                     int flags, const uint8_t bssid[IEEE80211_ADDR_LEN],
   82                     const uint8_t mac[IEEE80211_ADDR_LEN]);
   83 static void     iwn_vap_delete(struct ieee80211vap *);
   84 static int      iwn_cleanup(device_t);
   85 static int      iwn_detach(device_t);
   86 static int      iwn_nic_lock(struct iwn_softc *);
   87 static int      iwn_eeprom_lock(struct iwn_softc *);
   88 static int      iwn_init_otprom(struct iwn_softc *);
   89 static int      iwn_read_prom_data(struct iwn_softc *, uint32_t, void *, int);
   90 static void     iwn_dma_map_addr(void *, bus_dma_segment_t *, int, int);
   91 static int      iwn_dma_contig_alloc(struct iwn_softc *, struct iwn_dma_info *,
   92                     void **, bus_size_t, bus_size_t, int);
   93 static void     iwn_dma_contig_free(struct iwn_dma_info *);
   94 static int      iwn_alloc_sched(struct iwn_softc *);
   95 static void     iwn_free_sched(struct iwn_softc *);
   96 static int      iwn_alloc_kw(struct iwn_softc *);
   97 static void     iwn_free_kw(struct iwn_softc *);
   98 static int      iwn_alloc_ict(struct iwn_softc *);
   99 static void     iwn_free_ict(struct iwn_softc *);
  100 static int      iwn_alloc_fwmem(struct iwn_softc *);
  101 static void     iwn_free_fwmem(struct iwn_softc *);
  102 static int      iwn_alloc_rx_ring(struct iwn_softc *, struct iwn_rx_ring *);
  103 static void     iwn_reset_rx_ring(struct iwn_softc *, struct iwn_rx_ring *);
  104 static void     iwn_free_rx_ring(struct iwn_softc *, struct iwn_rx_ring *);
  105 static int      iwn_alloc_tx_ring(struct iwn_softc *, struct iwn_tx_ring *,
  106                     int);
  107 static void     iwn_reset_tx_ring(struct iwn_softc *, struct iwn_tx_ring *);
  108 static void     iwn_free_tx_ring(struct iwn_softc *, struct iwn_tx_ring *);
  109 static void     iwn5000_ict_reset(struct iwn_softc *);
  110 static int      iwn_read_eeprom(struct iwn_softc *,
  111                     uint8_t macaddr[IEEE80211_ADDR_LEN]);
  112 static void     iwn4965_read_eeprom(struct iwn_softc *);
  113 static void     iwn4965_print_power_group(struct iwn_softc *, int);
  114 static void     iwn5000_read_eeprom(struct iwn_softc *);
  115 static uint32_t iwn_eeprom_channel_flags(struct iwn_eeprom_chan *);
  116 static void     iwn_read_eeprom_band(struct iwn_softc *, int);
  117 #if 0   /* HT */
  118 static void     iwn_read_eeprom_ht40(struct iwn_softc *, int);
  119 #endif
  120 static void     iwn_read_eeprom_channels(struct iwn_softc *, int,
  121                     uint32_t);
  122 static void     iwn_read_eeprom_enhinfo(struct iwn_softc *);
  123 static struct ieee80211_node *iwn_node_alloc(struct ieee80211vap *,
  124                     const uint8_t mac[IEEE80211_ADDR_LEN]);
  125 static void     iwn_newassoc(struct ieee80211_node *, int);
  126 static int      iwn_media_change(struct ifnet *);
  127 static int      iwn_newstate(struct ieee80211vap *, enum ieee80211_state, int);
  128 static void     iwn_rx_phy(struct iwn_softc *, struct iwn_rx_desc *,
  129                     struct iwn_rx_data *);
  130 static void     iwn_timer_timeout(void *);
  131 static void     iwn_calib_reset(struct iwn_softc *);
  132 static void     iwn_rx_done(struct iwn_softc *, struct iwn_rx_desc *,
  133                     struct iwn_rx_data *);
  134 #if 0   /* HT */
  135 static void     iwn_rx_compressed_ba(struct iwn_softc *, struct iwn_rx_desc *,
  136                     struct iwn_rx_data *);
  137 #endif
  138 static void     iwn5000_rx_calib_results(struct iwn_softc *,
  139                     struct iwn_rx_desc *, struct iwn_rx_data *);
  140 static void     iwn_rx_statistics(struct iwn_softc *, struct iwn_rx_desc *,
  141                     struct iwn_rx_data *);
  142 static void     iwn4965_tx_done(struct iwn_softc *, struct iwn_rx_desc *,
  143                     struct iwn_rx_data *);
  144 static void     iwn5000_tx_done(struct iwn_softc *, struct iwn_rx_desc *,
  145                     struct iwn_rx_data *);
  146 static void     iwn_tx_done(struct iwn_softc *, struct iwn_rx_desc *, int,
  147                     uint8_t);
  148 static void     iwn_cmd_done(struct iwn_softc *, struct iwn_rx_desc *);
  149 static void     iwn_notif_intr(struct iwn_softc *);
  150 static void     iwn_wakeup_intr(struct iwn_softc *);
  151 static void     iwn_rftoggle_intr(struct iwn_softc *);
  152 static void     iwn_fatal_intr(struct iwn_softc *);
  153 static void     iwn_intr(void *);
  154 static void     iwn4965_update_sched(struct iwn_softc *, int, int, uint8_t,
  155                     uint16_t);
  156 static void     iwn5000_update_sched(struct iwn_softc *, int, int, uint8_t,
  157                     uint16_t);
  158 #ifdef notyet
  159 static void     iwn5000_reset_sched(struct iwn_softc *, int, int);
  160 #endif
  161 static uint8_t  iwn_plcp_signal(int);
  162 static int      iwn_tx_data(struct iwn_softc *, struct mbuf *,
  163                     struct ieee80211_node *, struct iwn_tx_ring *);
  164 static int      iwn_raw_xmit(struct ieee80211_node *, struct mbuf *,
  165                     const struct ieee80211_bpf_params *);
  166 static void     iwn_start(struct ifnet *);
  167 static void     iwn_start_locked(struct ifnet *);
  168 static void     iwn_watchdog(struct iwn_softc *sc);
  169 static int      iwn_ioctl(struct ifnet *, u_long, caddr_t);
  170 static int      iwn_cmd(struct iwn_softc *, int, const void *, int, int);
  171 static int      iwn4965_add_node(struct iwn_softc *, struct iwn_node_info *,
  172                     int);
  173 static int      iwn5000_add_node(struct iwn_softc *, struct iwn_node_info *,
  174                     int);
  175 static int      iwn_set_link_quality(struct iwn_softc *, uint8_t, int);
  176 static int      iwn_add_broadcast_node(struct iwn_softc *, int);
  177 static int      iwn_wme_update(struct ieee80211com *);
  178 static void     iwn_update_mcast(struct ifnet *);
  179 static void     iwn_set_led(struct iwn_softc *, uint8_t, uint8_t, uint8_t);
  180 static int      iwn_set_critical_temp(struct iwn_softc *);
  181 static int      iwn_set_timing(struct iwn_softc *, struct ieee80211_node *);
  182 static void     iwn4965_power_calibration(struct iwn_softc *, int);
  183 static int      iwn4965_set_txpower(struct iwn_softc *,
  184                     struct ieee80211_channel *, int);
  185 static int      iwn5000_set_txpower(struct iwn_softc *,
  186                     struct ieee80211_channel *, int);
  187 static int      iwn4965_get_rssi(struct iwn_softc *, struct iwn_rx_stat *);
  188 static int      iwn5000_get_rssi(struct iwn_softc *, struct iwn_rx_stat *);
  189 static int      iwn_get_noise(const struct iwn_rx_general_stats *);
  190 static int      iwn4965_get_temperature(struct iwn_softc *);
  191 static int      iwn5000_get_temperature(struct iwn_softc *);
  192 static int      iwn_init_sensitivity(struct iwn_softc *);
  193 static void     iwn_collect_noise(struct iwn_softc *,
  194                     const struct iwn_rx_general_stats *);
  195 static int      iwn4965_init_gains(struct iwn_softc *);
  196 static int      iwn5000_init_gains(struct iwn_softc *);
  197 static int      iwn4965_set_gains(struct iwn_softc *);
  198 static int      iwn5000_set_gains(struct iwn_softc *);
  199 static void     iwn_tune_sensitivity(struct iwn_softc *,
  200                     const struct iwn_rx_stats *);
  201 static int      iwn_send_sensitivity(struct iwn_softc *);
  202 static int      iwn_set_pslevel(struct iwn_softc *, int, int, int);
  203 static int      iwn_config(struct iwn_softc *);
  204 static int      iwn_scan(struct iwn_softc *);
  205 static int      iwn_auth(struct iwn_softc *, struct ieee80211vap *vap);
  206 static int      iwn_run(struct iwn_softc *, struct ieee80211vap *vap);
  207 #if 0   /* HT */
  208 static int      iwn_ampdu_rx_start(struct ieee80211com *,
  209                     struct ieee80211_node *, uint8_t);
  210 static void     iwn_ampdu_rx_stop(struct ieee80211com *,
  211                     struct ieee80211_node *, uint8_t);
  212 static int      iwn_ampdu_tx_start(struct ieee80211com *,
  213                     struct ieee80211_node *, uint8_t);
  214 static void     iwn_ampdu_tx_stop(struct ieee80211com *,
  215                     struct ieee80211_node *, uint8_t);
  216 static void     iwn4965_ampdu_tx_start(struct iwn_softc *,
  217                     struct ieee80211_node *, uint8_t, uint16_t);
  218 static void     iwn4965_ampdu_tx_stop(struct iwn_softc *, uint8_t, uint16_t);
  219 static void     iwn5000_ampdu_tx_start(struct iwn_softc *,
  220                     struct ieee80211_node *, uint8_t, uint16_t);
  221 static void     iwn5000_ampdu_tx_stop(struct iwn_softc *, uint8_t, uint16_t);
  222 #endif
  223 static int      iwn5000_query_calibration(struct iwn_softc *);
  224 static int      iwn5000_send_calibration(struct iwn_softc *);
  225 static int      iwn5000_send_wimax_coex(struct iwn_softc *);
  226 static int      iwn4965_post_alive(struct iwn_softc *);
  227 static int      iwn5000_post_alive(struct iwn_softc *);
  228 static int      iwn4965_load_bootcode(struct iwn_softc *, const uint8_t *,
  229                     int);
  230 static int      iwn4965_load_firmware(struct iwn_softc *);
  231 static int      iwn5000_load_firmware_section(struct iwn_softc *, uint32_t,
  232                     const uint8_t *, int);
  233 static int      iwn5000_load_firmware(struct iwn_softc *);
  234 static int      iwn_read_firmware(struct iwn_softc *);
  235 static int      iwn_clock_wait(struct iwn_softc *);
  236 static int      iwn_apm_init(struct iwn_softc *);
  237 static void     iwn_apm_stop_master(struct iwn_softc *);
  238 static void     iwn_apm_stop(struct iwn_softc *);
  239 static int      iwn4965_nic_config(struct iwn_softc *);
  240 static int      iwn5000_nic_config(struct iwn_softc *);
  241 static int      iwn_hw_prepare(struct iwn_softc *);
  242 static int      iwn_hw_init(struct iwn_softc *);
  243 static void     iwn_hw_stop(struct iwn_softc *);
  244 static void     iwn_init_locked(struct iwn_softc *);
  245 static void     iwn_init(void *);
  246 static void     iwn_stop_locked(struct iwn_softc *);
  247 static void     iwn_stop(struct iwn_softc *);
  248 static void     iwn_scan_start(struct ieee80211com *);
  249 static void     iwn_scan_end(struct ieee80211com *);
  250 static void     iwn_set_channel(struct ieee80211com *);
  251 static void     iwn_scan_curchan(struct ieee80211_scan_state *, unsigned long);
  252 static void     iwn_scan_mindwell(struct ieee80211_scan_state *);
  253 static struct iwn_eeprom_chan *iwn_find_eeprom_channel(struct iwn_softc *,
  254                     struct ieee80211_channel *);
  255 static int      iwn_setregdomain(struct ieee80211com *,
  256                     struct ieee80211_regdomain *, int,
  257                     struct ieee80211_channel []);
  258 static void     iwn_hw_reset(void *, int);
  259 static void     iwn_radio_on(void *, int);
  260 static void     iwn_radio_off(void *, int);
  261 static void     iwn_sysctlattach(struct iwn_softc *);
  262 static int      iwn_shutdown(device_t);
  263 static int      iwn_suspend(device_t);
  264 static int      iwn_resume(device_t);
  265 
  266 #define IWN_DEBUG
  267 #ifdef IWN_DEBUG
  268 enum {
  269         IWN_DEBUG_XMIT          = 0x00000001,   /* basic xmit operation */
  270         IWN_DEBUG_RECV          = 0x00000002,   /* basic recv operation */
  271         IWN_DEBUG_STATE         = 0x00000004,   /* 802.11 state transitions */
  272         IWN_DEBUG_TXPOW         = 0x00000008,   /* tx power processing */
  273         IWN_DEBUG_RESET         = 0x00000010,   /* reset processing */
  274         IWN_DEBUG_OPS           = 0x00000020,   /* iwn_ops processing */
  275         IWN_DEBUG_BEACON        = 0x00000040,   /* beacon handling */
  276         IWN_DEBUG_WATCHDOG      = 0x00000080,   /* watchdog timeout */
  277         IWN_DEBUG_INTR          = 0x00000100,   /* ISR */
  278         IWN_DEBUG_CALIBRATE     = 0x00000200,   /* periodic calibration */
  279         IWN_DEBUG_NODE          = 0x00000400,   /* node management */
  280         IWN_DEBUG_LED           = 0x00000800,   /* led management */
  281         IWN_DEBUG_CMD           = 0x00001000,   /* cmd submission */
  282         IWN_DEBUG_FATAL         = 0x80000000,   /* fatal errors */
  283         IWN_DEBUG_ANY           = 0xffffffff
  284 };
  285 
  286 #define DPRINTF(sc, m, fmt, ...) do {                   \
  287         if (sc->sc_debug & (m))                         \
  288                 printf(fmt, __VA_ARGS__);               \
  289 } while (0)
  290 
  291 static const char *iwn_intr_str(uint8_t);
  292 #else
  293 #define DPRINTF(sc, m, fmt, ...) do { (void) sc; } while (0)
  294 #endif
  295 
  296 struct iwn_ident {
  297         uint16_t        vendor;
  298         uint16_t        device;
  299         const char      *name;
  300 };
  301 
  302 static const struct iwn_ident iwn_ident_table [] = {
  303         { 0x8086, 0x4229, "Intel(R) PRO/Wireless 4965BGN" },
  304         { 0x8086, 0x422D, "Intel(R) PRO/Wireless 4965BGN" },
  305         { 0x8086, 0x4230, "Intel(R) PRO/Wireless 4965BGN" },
  306         { 0x8086, 0x4233, "Intel(R) PRO/Wireless 4965BGN" },
  307         { 0x8086, 0x4232, "Intel(R) PRO/Wireless 5100" },
  308         { 0x8086, 0x4237, "Intel(R) PRO/Wireless 5100" },
  309         { 0x8086, 0x423C, "Intel(R) PRO/Wireless 5150" },
  310         { 0x8086, 0x423D, "Intel(R) PRO/Wireless 5150" },
  311         { 0x8086, 0x4235, "Intel(R) PRO/Wireless 5300" },
  312         { 0x8086, 0x4236, "Intel(R) PRO/Wireless 5300" },
  313         { 0x8086, 0x4236, "Intel(R) PRO/Wireless 5350" },
  314         { 0x8086, 0x423A, "Intel(R) PRO/Wireless 5350" },
  315         { 0x8086, 0x423B, "Intel(R) PRO/Wireless 5350" },
  316         { 0x8086, 0x0083, "Intel(R) PRO/Wireless 1000" },
  317         { 0x8086, 0x0084, "Intel(R) PRO/Wireless 1000" },
  318         { 0x8086, 0x008D, "Intel(R) PRO/Wireless 6000" },
  319         { 0x8086, 0x008E, "Intel(R) PRO/Wireless 6000" },
  320         { 0x8086, 0x4238, "Intel(R) PRO/Wireless 6000" },
  321         { 0x8086, 0x4239, "Intel(R) PRO/Wireless 6000" },
  322         { 0x8086, 0x422B, "Intel(R) PRO/Wireless 6000" },
  323         { 0x8086, 0x422C, "Intel(R) PRO/Wireless 6000" },
  324         { 0x8086, 0x0086, "Intel(R) PRO/Wireless 6050" },
  325         { 0x8086, 0x0087, "Intel(R) PRO/Wireless 6050" },
  326         { 0, 0, NULL }
  327 };
  328 
  329 static const struct iwn_hal iwn4965_hal = {
  330         iwn4965_load_firmware,
  331         iwn4965_read_eeprom,
  332         iwn4965_post_alive,
  333         iwn4965_nic_config,
  334         iwn4965_update_sched,
  335         iwn4965_get_temperature,
  336         iwn4965_get_rssi,
  337         iwn4965_set_txpower,
  338         iwn4965_init_gains,
  339         iwn4965_set_gains,
  340         iwn4965_add_node,
  341         iwn4965_tx_done,
  342 #if 0   /* HT */
  343         iwn4965_ampdu_tx_start,
  344         iwn4965_ampdu_tx_stop,
  345 #endif
  346         IWN4965_NTXQUEUES,
  347         IWN4965_NDMACHNLS,
  348         IWN4965_ID_BROADCAST,
  349         IWN4965_RXONSZ,
  350         IWN4965_SCHEDSZ,
  351         IWN4965_FW_TEXT_MAXSZ,
  352         IWN4965_FW_DATA_MAXSZ,
  353         IWN4965_FWSZ,
  354         IWN4965_SCHED_TXFACT
  355 };
  356 
  357 static const struct iwn_hal iwn5000_hal = {
  358         iwn5000_load_firmware,
  359         iwn5000_read_eeprom,
  360         iwn5000_post_alive,
  361         iwn5000_nic_config,
  362         iwn5000_update_sched,
  363         iwn5000_get_temperature,
  364         iwn5000_get_rssi,
  365         iwn5000_set_txpower,
  366         iwn5000_init_gains,
  367         iwn5000_set_gains,
  368         iwn5000_add_node,
  369         iwn5000_tx_done,
  370 #if 0   /* HT */
  371         iwn5000_ampdu_tx_start,
  372         iwn5000_ampdu_tx_stop,
  373 #endif
  374         IWN5000_NTXQUEUES,
  375         IWN5000_NDMACHNLS,
  376         IWN5000_ID_BROADCAST,
  377         IWN5000_RXONSZ,
  378         IWN5000_SCHEDSZ,
  379         IWN5000_FW_TEXT_MAXSZ,
  380         IWN5000_FW_DATA_MAXSZ,
  381         IWN5000_FWSZ,
  382         IWN5000_SCHED_TXFACT
  383 };
  384 
  385 static int
  386 iwn_probe(device_t dev)
  387 {
  388         const struct iwn_ident *ident;
  389 
  390         for (ident = iwn_ident_table; ident->name != NULL; ident++) {
  391                 if (pci_get_vendor(dev) == ident->vendor &&
  392                     pci_get_device(dev) == ident->device) {
  393                         device_set_desc(dev, ident->name);
  394                         return 0;
  395                 }
  396         }
  397         return ENXIO;
  398 }
  399 
  400 static int
  401 iwn_attach(device_t dev)
  402 {
  403         struct iwn_softc *sc = (struct iwn_softc *)device_get_softc(dev);
  404         struct ieee80211com *ic;
  405         struct ifnet *ifp;
  406         const struct iwn_hal *hal;
  407         uint32_t tmp;
  408         int i, error, result;
  409         uint8_t macaddr[IEEE80211_ADDR_LEN];
  410 
  411         sc->sc_dev = dev;
  412 
  413         /*
  414          * Get the offset of the PCI Express Capability Structure in PCI
  415          * Configuration Space.
  416          */
  417         error = pci_find_extcap(dev, PCIY_EXPRESS, &sc->sc_cap_off);
  418         if (error != 0) {
  419                 device_printf(dev, "PCIe capability structure not found!\n");
  420                 return error;
  421         }
  422 
  423         /* Clear device-specific "PCI retry timeout" register (41h). */
  424         pci_write_config(dev, 0x41, 0, 1);
  425 
  426         /* Hardware bug workaround. */
  427         tmp = pci_read_config(dev, PCIR_COMMAND, 1);
  428         if (tmp & PCIM_CMD_INTxDIS) {
  429                 DPRINTF(sc, IWN_DEBUG_RESET, "%s: PCIe INTx Disable set\n",
  430                     __func__);
  431                 tmp &= ~PCIM_CMD_INTxDIS;
  432                 pci_write_config(dev, PCIR_COMMAND, tmp, 1);
  433         }
  434 
  435         /* Enable bus-mastering. */
  436         pci_enable_busmaster(dev);
  437 
  438         sc->mem_rid = PCIR_BAR(0);
  439         sc->mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->mem_rid,
  440             RF_ACTIVE);
  441         if (sc->mem == NULL ) {
  442                 device_printf(dev, "could not allocate memory resources\n");
  443                 error = ENOMEM;
  444                 return error;
  445         }
  446 
  447         sc->sc_st = rman_get_bustag(sc->mem);
  448         sc->sc_sh = rman_get_bushandle(sc->mem);
  449         sc->irq_rid = 0;
  450         if ((result = pci_msi_count(dev)) == 1 &&
  451             pci_alloc_msi(dev, &result) == 0)
  452                 sc->irq_rid = 1;
  453         sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irq_rid,
  454             RF_ACTIVE | RF_SHAREABLE);
  455         if (sc->irq == NULL) {
  456                 device_printf(dev, "could not allocate interrupt resource\n");
  457                 error = ENOMEM;
  458                 goto fail;
  459         }
  460 
  461         IWN_LOCK_INIT(sc);
  462         callout_init_mtx(&sc->sc_timer_to, &sc->sc_mtx, 0);
  463         TASK_INIT(&sc->sc_reinit_task, 0, iwn_hw_reset, sc );
  464         TASK_INIT(&sc->sc_radioon_task, 0, iwn_radio_on, sc );
  465         TASK_INIT(&sc->sc_radiooff_task, 0, iwn_radio_off, sc );
  466 
  467         /* Attach Hardware Abstraction Layer. */
  468         hal = iwn_hal_attach(sc);
  469         if (hal == NULL) {
  470                 error = ENXIO;  /* XXX: Wrong error code? */
  471                 goto fail;
  472         }
  473 
  474         error = iwn_hw_prepare(sc);
  475         if (error != 0) {
  476                 device_printf(dev, "hardware not ready, error %d\n", error);
  477                 goto fail;
  478         }
  479 
  480         /* Allocate DMA memory for firmware transfers. */
  481         error = iwn_alloc_fwmem(sc);
  482         if (error != 0) {
  483                 device_printf(dev,
  484                     "could not allocate memory for firmware, error %d\n",
  485                     error);
  486                 goto fail;
  487         }
  488 
  489         /* Allocate "Keep Warm" page. */
  490         error = iwn_alloc_kw(sc);
  491         if (error != 0) {
  492                 device_printf(dev,
  493                     "could not allocate \"Keep Warm\" page, error %d\n", error);
  494                 goto fail;
  495         }
  496 
  497         /* Allocate ICT table for 5000 Series. */
  498         if (sc->hw_type != IWN_HW_REV_TYPE_4965 &&
  499             (error = iwn_alloc_ict(sc)) != 0) {
  500                 device_printf(dev,
  501                     "%s: could not allocate ICT table, error %d\n",
  502                     __func__, error);
  503                 goto fail;
  504         }
  505 
  506         /* Allocate TX scheduler "rings". */
  507         error = iwn_alloc_sched(sc);
  508         if (error != 0) {
  509                 device_printf(dev,
  510                     "could not allocate TX scheduler rings, error %d\n",
  511                     error);
  512                 goto fail;
  513         }
  514 
  515         /* Allocate TX rings (16 on 4965AGN, 20 on 5000). */
  516         for (i = 0; i < hal->ntxqs; i++) {
  517                 error = iwn_alloc_tx_ring(sc, &sc->txq[i], i);
  518                 if (error != 0) {
  519                         device_printf(dev,
  520                             "could not allocate Tx ring %d, error %d\n",
  521                             i, error);
  522                         goto fail;
  523                 }
  524         }
  525 
  526         /* Allocate RX ring. */
  527         error = iwn_alloc_rx_ring(sc, &sc->rxq);
  528         if (error != 0 ){
  529                 device_printf(dev,
  530                     "could not allocate Rx ring, error %d\n", error);
  531                 goto fail;
  532         }
  533 
  534         /* Clear pending interrupts. */
  535         IWN_WRITE(sc, IWN_INT, 0xffffffff);
  536 
  537         /* Count the number of available chains. */
  538         sc->ntxchains =
  539             ((sc->txchainmask >> 2) & 1) +
  540             ((sc->txchainmask >> 1) & 1) +
  541             ((sc->txchainmask >> 0) & 1);
  542         sc->nrxchains =
  543             ((sc->rxchainmask >> 2) & 1) +
  544             ((sc->rxchainmask >> 1) & 1) +
  545             ((sc->rxchainmask >> 0) & 1);
  546 
  547         ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
  548         if (ifp == NULL) {
  549                 device_printf(dev, "can not allocate ifnet structure\n");
  550                 goto fail;
  551         }
  552         ic = ifp->if_l2com;
  553 
  554         ic->ic_ifp = ifp;
  555         ic->ic_phytype = IEEE80211_T_OFDM;      /* not only, but not used */
  556         ic->ic_opmode = IEEE80211_M_STA;        /* default to BSS mode */
  557 
  558         /* Set device capabilities. */
  559         ic->ic_caps =
  560                   IEEE80211_C_STA               /* station mode supported */
  561                 | IEEE80211_C_MONITOR           /* monitor mode supported */
  562                 | IEEE80211_C_TXPMGT            /* tx power management */
  563                 | IEEE80211_C_SHSLOT            /* short slot time supported */
  564                 | IEEE80211_C_WPA
  565                 | IEEE80211_C_SHPREAMBLE        /* short preamble supported */
  566                 | IEEE80211_C_BGSCAN            /* background scanning */
  567 #if 0
  568                 | IEEE80211_C_IBSS              /* ibss/adhoc mode */
  569 #endif
  570                 | IEEE80211_C_WME               /* WME */
  571                 ;
  572 #if 0   /* HT */
  573         /* XXX disable until HT channel setup works */
  574         ic->ic_htcaps =
  575                   IEEE80211_HTCAP_SMPS_ENA      /* SM PS mode enabled */
  576                 | IEEE80211_HTCAP_CHWIDTH40     /* 40MHz channel width */
  577                 | IEEE80211_HTCAP_SHORTGI20     /* short GI in 20MHz */
  578                 | IEEE80211_HTCAP_SHORTGI40     /* short GI in 40MHz */
  579                 | IEEE80211_HTCAP_RXSTBC_2STREAM/* 1-2 spatial streams */
  580                 | IEEE80211_HTCAP_MAXAMSDU_3839 /* max A-MSDU length */
  581                 /* s/w capabilities */
  582                 | IEEE80211_HTC_HT              /* HT operation */
  583                 | IEEE80211_HTC_AMPDU           /* tx A-MPDU */
  584                 | IEEE80211_HTC_AMSDU           /* tx A-MSDU */
  585                 ;
  586 
  587         /* Set HT capabilities. */
  588         ic->ic_htcaps =
  589 #if IWN_RBUF_SIZE == 8192
  590             IEEE80211_HTCAP_AMSDU7935 |
  591 #endif
  592             IEEE80211_HTCAP_CBW20_40 |
  593             IEEE80211_HTCAP_SGI20 |
  594             IEEE80211_HTCAP_SGI40;
  595         if (sc->hw_type != IWN_HW_REV_TYPE_4965)
  596                 ic->ic_htcaps |= IEEE80211_HTCAP_GF;
  597         if (sc->hw_type == IWN_HW_REV_TYPE_6050)
  598                 ic->ic_htcaps |= IEEE80211_HTCAP_SMPS_DYN;
  599         else
  600                 ic->ic_htcaps |= IEEE80211_HTCAP_SMPS_DIS;
  601 #endif
  602 
  603         /* Read MAC address, channels, etc from EEPROM. */
  604         error = iwn_read_eeprom(sc, macaddr);
  605         if (error != 0) {
  606                 device_printf(dev, "could not read EEPROM, error %d\n",
  607                     error);
  608                 goto fail;
  609         }
  610 
  611         device_printf(sc->sc_dev, "MIMO %dT%dR, %.4s, address %6D\n",
  612             sc->ntxchains, sc->nrxchains, sc->eeprom_domain,
  613             macaddr, ":");
  614 
  615 #if 0   /* HT */
  616         /* Set supported HT rates. */
  617         ic->ic_sup_mcs[0] = 0xff;
  618         if (sc->nrxchains > 1)
  619                 ic->ic_sup_mcs[1] = 0xff;
  620         if (sc->nrxchains > 2)
  621                 ic->ic_sup_mcs[2] = 0xff;
  622 #endif
  623 
  624         if_initname(ifp, device_get_name(dev), device_get_unit(dev));
  625         ifp->if_softc = sc;
  626         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
  627         ifp->if_init = iwn_init;
  628         ifp->if_ioctl = iwn_ioctl;
  629         ifp->if_start = iwn_start;
  630         IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
  631         ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
  632         IFQ_SET_READY(&ifp->if_snd);
  633 
  634         ieee80211_ifattach(ic, macaddr);
  635         ic->ic_vap_create = iwn_vap_create;
  636         ic->ic_vap_delete = iwn_vap_delete;
  637         ic->ic_raw_xmit = iwn_raw_xmit;
  638         ic->ic_node_alloc = iwn_node_alloc;
  639         ic->ic_newassoc = iwn_newassoc;
  640         ic->ic_wme.wme_update = iwn_wme_update;
  641         ic->ic_update_mcast = iwn_update_mcast;
  642         ic->ic_scan_start = iwn_scan_start;
  643         ic->ic_scan_end = iwn_scan_end;
  644         ic->ic_set_channel = iwn_set_channel;
  645         ic->ic_scan_curchan = iwn_scan_curchan;
  646         ic->ic_scan_mindwell = iwn_scan_mindwell;
  647         ic->ic_setregdomain = iwn_setregdomain;
  648 #if 0   /* HT */
  649         ic->ic_ampdu_rx_start = iwn_ampdu_rx_start;
  650         ic->ic_ampdu_rx_stop = iwn_ampdu_rx_stop;
  651         ic->ic_ampdu_tx_start = iwn_ampdu_tx_start;
  652         ic->ic_ampdu_tx_stop = iwn_ampdu_tx_stop;
  653 #endif
  654 
  655         iwn_radiotap_attach(sc);
  656         iwn_sysctlattach(sc);
  657 
  658         /*
  659          * Hook our interrupt after all initialization is complete.
  660          */
  661         error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET | INTR_MPSAFE,
  662             NULL, iwn_intr, sc, &sc->sc_ih);
  663         if (error != 0) {
  664                 device_printf(dev, "could not set up interrupt, error %d\n",
  665                     error);
  666                 goto fail;
  667         }
  668 
  669         ieee80211_announce(ic);
  670         return 0;
  671 fail:
  672         iwn_cleanup(dev);
  673         return error;
  674 }
  675 
  676 static const struct iwn_hal *
  677 iwn_hal_attach(struct iwn_softc *sc)
  678 {
  679         sc->hw_type = (IWN_READ(sc, IWN_HW_REV) >> 4) & 0xf;
  680 
  681         switch (sc->hw_type) {
  682         case IWN_HW_REV_TYPE_4965:
  683                 sc->sc_hal = &iwn4965_hal;
  684                 sc->limits = &iwn4965_sensitivity_limits;
  685                 sc->fwname = "iwn4965fw";
  686                 sc->txchainmask = IWN_ANT_AB;
  687                 sc->rxchainmask = IWN_ANT_ABC;
  688                 break;
  689         case IWN_HW_REV_TYPE_5100:
  690                 sc->sc_hal = &iwn5000_hal;
  691                 sc->limits = &iwn5000_sensitivity_limits;
  692                 sc->fwname = "iwn5000fw";
  693                 sc->txchainmask = IWN_ANT_B;
  694                 sc->rxchainmask = IWN_ANT_AB;
  695                 break;
  696         case IWN_HW_REV_TYPE_5150:
  697                 sc->sc_hal = &iwn5000_hal;
  698                 sc->limits = &iwn5150_sensitivity_limits;
  699                 sc->fwname = "iwn5150fw";
  700                 sc->txchainmask = IWN_ANT_A;
  701                 sc->rxchainmask = IWN_ANT_AB;
  702                 break;
  703         case IWN_HW_REV_TYPE_5300:
  704         case IWN_HW_REV_TYPE_5350:
  705                 sc->sc_hal = &iwn5000_hal;
  706                 sc->limits = &iwn5000_sensitivity_limits;
  707                 sc->fwname = "iwn5000fw";
  708                 sc->txchainmask = IWN_ANT_ABC;
  709                 sc->rxchainmask = IWN_ANT_ABC;
  710                 break;
  711         case IWN_HW_REV_TYPE_1000:
  712                 sc->sc_hal = &iwn5000_hal;
  713                 sc->limits = &iwn1000_sensitivity_limits;
  714                 sc->fwname = "iwn1000fw";
  715                 sc->txchainmask = IWN_ANT_A;
  716                 sc->rxchainmask = IWN_ANT_AB;
  717                 break;
  718         case IWN_HW_REV_TYPE_6000:
  719                 sc->sc_hal = &iwn5000_hal;
  720                 sc->limits = &iwn6000_sensitivity_limits;
  721                 sc->fwname = "iwn6000fw";
  722                 switch (pci_get_device(sc->sc_dev)) {
  723                 case 0x422C:
  724                 case 0x4239:
  725                         sc->sc_flags |= IWN_FLAG_INTERNAL_PA;
  726                         sc->txchainmask = IWN_ANT_BC;
  727                         sc->rxchainmask = IWN_ANT_BC;
  728                         break;
  729                 default:
  730                         sc->txchainmask = IWN_ANT_ABC;
  731                         sc->rxchainmask = IWN_ANT_ABC;
  732                         break;
  733                 }
  734                 break;
  735         case IWN_HW_REV_TYPE_6050:
  736                 sc->sc_hal = &iwn5000_hal;
  737                 sc->limits = &iwn6000_sensitivity_limits;
  738                 sc->fwname = "iwn6000fw";
  739                 sc->txchainmask = IWN_ANT_AB;
  740                 sc->rxchainmask = IWN_ANT_AB;
  741                 break;
  742         default:
  743                 device_printf(sc->sc_dev, "adapter type %d not supported\n",
  744                     sc->hw_type);
  745                 return NULL;
  746         }
  747         return sc->sc_hal;
  748 }
  749 
  750 /*
  751  * Attach the interface to 802.11 radiotap.
  752  */
  753 static void
  754 iwn_radiotap_attach(struct iwn_softc *sc)
  755 {
  756         struct ifnet *ifp = sc->sc_ifp;
  757         struct ieee80211com *ic = ifp->if_l2com;
  758 
  759         ieee80211_radiotap_attach(ic,
  760             &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
  761                 IWN_TX_RADIOTAP_PRESENT,
  762             &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
  763                 IWN_RX_RADIOTAP_PRESENT);
  764 }
  765 
  766 static struct ieee80211vap *
  767 iwn_vap_create(struct ieee80211com *ic,
  768         const char name[IFNAMSIZ], int unit, int opmode, int flags,
  769         const uint8_t bssid[IEEE80211_ADDR_LEN],
  770         const uint8_t mac[IEEE80211_ADDR_LEN])
  771 {
  772         struct iwn_vap *ivp;
  773         struct ieee80211vap *vap;
  774 
  775         if (!TAILQ_EMPTY(&ic->ic_vaps))         /* only one at a time */
  776                 return NULL;
  777         ivp = (struct iwn_vap *) malloc(sizeof(struct iwn_vap),
  778             M_80211_VAP, M_NOWAIT | M_ZERO);
  779         if (ivp == NULL)
  780                 return NULL;
  781         vap = &ivp->iv_vap;
  782         ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
  783         vap->iv_bmissthreshold = 10;            /* override default */
  784         /* Override with driver methods. */
  785         ivp->iv_newstate = vap->iv_newstate;
  786         vap->iv_newstate = iwn_newstate;
  787 
  788         ieee80211_ratectl_init(vap);
  789         /* Complete setup. */
  790         ieee80211_vap_attach(vap, iwn_media_change, ieee80211_media_status);
  791         ic->ic_opmode = opmode;
  792         return vap;
  793 }
  794 
  795 static void
  796 iwn_vap_delete(struct ieee80211vap *vap)
  797 {
  798         struct iwn_vap *ivp = IWN_VAP(vap);
  799 
  800         ieee80211_ratectl_deinit(vap);
  801         ieee80211_vap_detach(vap);
  802         free(ivp, M_80211_VAP);
  803 }
  804 
  805 static int
  806 iwn_cleanup(device_t dev)
  807 {
  808         struct iwn_softc *sc = device_get_softc(dev);
  809         struct ifnet *ifp = sc->sc_ifp;
  810         struct ieee80211com *ic;
  811         int i;
  812 
  813         if (ifp != NULL) {
  814                 ic = ifp->if_l2com;
  815 
  816                 ieee80211_draintask(ic, &sc->sc_reinit_task);
  817                 ieee80211_draintask(ic, &sc->sc_radioon_task);
  818                 ieee80211_draintask(ic, &sc->sc_radiooff_task);
  819 
  820                 iwn_stop(sc);
  821                 callout_drain(&sc->sc_timer_to);
  822                 ieee80211_ifdetach(ic);
  823         }
  824 
  825         /* Free DMA resources. */
  826         iwn_free_rx_ring(sc, &sc->rxq);
  827         if (sc->sc_hal != NULL)
  828                 for (i = 0; i < sc->sc_hal->ntxqs; i++)
  829                         iwn_free_tx_ring(sc, &sc->txq[i]);
  830         iwn_free_sched(sc);
  831         iwn_free_kw(sc);
  832         if (sc->ict != NULL)
  833                 iwn_free_ict(sc);
  834         iwn_free_fwmem(sc);
  835 
  836         if (sc->irq != NULL) {
  837                 bus_teardown_intr(dev, sc->irq, sc->sc_ih);
  838                 bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, sc->irq);
  839                 if (sc->irq_rid == 1)
  840                         pci_release_msi(dev);
  841         }
  842 
  843         if (sc->mem != NULL)
  844                 bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, sc->mem);
  845 
  846         if (ifp != NULL)
  847                 if_free(ifp);
  848 
  849         IWN_LOCK_DESTROY(sc);
  850         return 0;
  851 }
  852 
  853 static int
  854 iwn_detach(device_t dev)
  855 {
  856         iwn_cleanup(dev);
  857         return 0;
  858 }
  859 
  860 static int
  861 iwn_nic_lock(struct iwn_softc *sc)
  862 {
  863         int ntries;
  864 
  865         /* Request exclusive access to NIC. */
  866         IWN_SETBITS(sc, IWN_GP_CNTRL, IWN_GP_CNTRL_MAC_ACCESS_REQ);
  867 
  868         /* Spin until we actually get the lock. */
  869         for (ntries = 0; ntries < 1000; ntries++) {
  870                 if ((IWN_READ(sc, IWN_GP_CNTRL) &
  871                     (IWN_GP_CNTRL_MAC_ACCESS_ENA | IWN_GP_CNTRL_SLEEP)) ==
  872                     IWN_GP_CNTRL_MAC_ACCESS_ENA)
  873                         return 0;
  874                 DELAY(10);
  875         }
  876         return ETIMEDOUT;
  877 }
  878 
  879 static __inline void
  880 iwn_nic_unlock(struct iwn_softc *sc)
  881 {
  882         IWN_CLRBITS(sc, IWN_GP_CNTRL, IWN_GP_CNTRL_MAC_ACCESS_REQ);
  883 }
  884 
  885 static __inline uint32_t
  886 iwn_prph_read(struct iwn_softc *sc, uint32_t addr)
  887 {
  888         IWN_WRITE(sc, IWN_PRPH_RADDR, IWN_PRPH_DWORD | addr);
  889         IWN_BARRIER_READ_WRITE(sc);
  890         return IWN_READ(sc, IWN_PRPH_RDATA);
  891 }
  892 
  893 static __inline void
  894 iwn_prph_write(struct iwn_softc *sc, uint32_t addr, uint32_t data)
  895 {
  896         IWN_WRITE(sc, IWN_PRPH_WADDR, IWN_PRPH_DWORD | addr);
  897         IWN_BARRIER_WRITE(sc);
  898         IWN_WRITE(sc, IWN_PRPH_WDATA, data);
  899 }
  900 
  901 static __inline void
  902 iwn_prph_setbits(struct iwn_softc *sc, uint32_t addr, uint32_t mask)
  903 {
  904         iwn_prph_write(sc, addr, iwn_prph_read(sc, addr) | mask);
  905 }
  906 
  907 static __inline void
  908 iwn_prph_clrbits(struct iwn_softc *sc, uint32_t addr, uint32_t mask)
  909 {
  910         iwn_prph_write(sc, addr, iwn_prph_read(sc, addr) & ~mask);
  911 }
  912 
  913 static __inline void
  914 iwn_prph_write_region_4(struct iwn_softc *sc, uint32_t addr,
  915     const uint32_t *data, int count)
  916 {
  917         for (; count > 0; count--, data++, addr += 4)
  918                 iwn_prph_write(sc, addr, *data);
  919 }
  920 
  921 static __inline uint32_t
  922 iwn_mem_read(struct iwn_softc *sc, uint32_t addr)
  923 {
  924         IWN_WRITE(sc, IWN_MEM_RADDR, addr);
  925         IWN_BARRIER_READ_WRITE(sc);
  926         return IWN_READ(sc, IWN_MEM_RDATA);
  927 }
  928 
  929 static __inline void
  930 iwn_mem_write(struct iwn_softc *sc, uint32_t addr, uint32_t data)
  931 {
  932         IWN_WRITE(sc, IWN_MEM_WADDR, addr);
  933         IWN_BARRIER_WRITE(sc);
  934         IWN_WRITE(sc, IWN_MEM_WDATA, data);
  935 }
  936 
  937 static __inline void
  938 iwn_mem_write_2(struct iwn_softc *sc, uint32_t addr, uint16_t data)
  939 {
  940         uint32_t tmp;
  941 
  942         tmp = iwn_mem_read(sc, addr & ~3);
  943         if (addr & 3)
  944                 tmp = (tmp & 0x0000ffff) | data << 16;
  945         else
  946                 tmp = (tmp & 0xffff0000) | data;
  947         iwn_mem_write(sc, addr & ~3, tmp);
  948 }
  949 
  950 static __inline void
  951 iwn_mem_read_region_4(struct iwn_softc *sc, uint32_t addr, uint32_t *data,
  952     int count)
  953 {
  954         for (; count > 0; count--, addr += 4)
  955                 *data++ = iwn_mem_read(sc, addr);
  956 }
  957 
  958 static __inline void
  959 iwn_mem_set_region_4(struct iwn_softc *sc, uint32_t addr, uint32_t val,
  960     int count)
  961 {
  962         for (; count > 0; count--, addr += 4)
  963                 iwn_mem_write(sc, addr, val);
  964 }
  965 
  966 static int
  967 iwn_eeprom_lock(struct iwn_softc *sc)
  968 {
  969         int i, ntries;
  970 
  971         for (i = 0; i < 100; i++) {
  972                 /* Request exclusive access to EEPROM. */
  973                 IWN_SETBITS(sc, IWN_HW_IF_CONFIG,
  974                     IWN_HW_IF_CONFIG_EEPROM_LOCKED);
  975 
  976                 /* Spin until we actually get the lock. */
  977                 for (ntries = 0; ntries < 100; ntries++) {
  978                         if (IWN_READ(sc, IWN_HW_IF_CONFIG) &
  979                             IWN_HW_IF_CONFIG_EEPROM_LOCKED)
  980                                 return 0;
  981                         DELAY(10);
  982                 }
  983         }
  984         return ETIMEDOUT;
  985 }
  986 
  987 static __inline void
  988 iwn_eeprom_unlock(struct iwn_softc *sc)
  989 {
  990         IWN_CLRBITS(sc, IWN_HW_IF_CONFIG, IWN_HW_IF_CONFIG_EEPROM_LOCKED);
  991 }
  992 
  993 /*
  994  * Initialize access by host to One Time Programmable ROM.
  995  * NB: This kind of ROM can be found on 1000 or 6000 Series only.
  996  */
  997 static int
  998 iwn_init_otprom(struct iwn_softc *sc)
  999 {
 1000         uint16_t prev, base, next;
 1001         int count, error;
 1002 
 1003         /* Wait for clock stabilization before accessing prph. */
 1004         error = iwn_clock_wait(sc);
 1005         if (error != 0)
 1006                 return error;
 1007 
 1008         error = iwn_nic_lock(sc);
 1009         if (error != 0)
 1010                 return error;
 1011         iwn_prph_setbits(sc, IWN_APMG_PS, IWN_APMG_PS_RESET_REQ);
 1012         DELAY(5);
 1013         iwn_prph_clrbits(sc, IWN_APMG_PS, IWN_APMG_PS_RESET_REQ);
 1014         iwn_nic_unlock(sc);
 1015 
 1016         /* Set auto clock gate disable bit for HW with OTP shadow RAM. */
 1017         if (sc->hw_type != IWN_HW_REV_TYPE_1000) {
 1018                 IWN_SETBITS(sc, IWN_DBG_LINK_PWR_MGMT,
 1019                     IWN_RESET_LINK_PWR_MGMT_DIS);
 1020         }
 1021         IWN_CLRBITS(sc, IWN_EEPROM_GP, IWN_EEPROM_GP_IF_OWNER);
 1022         /* Clear ECC status. */
 1023         IWN_SETBITS(sc, IWN_OTP_GP,
 1024             IWN_OTP_GP_ECC_CORR_STTS | IWN_OTP_GP_ECC_UNCORR_STTS);
 1025 
 1026         /*
 1027          * Find the block before last block (contains the EEPROM image)
 1028          * for HW without OTP shadow RAM.
 1029          */
 1030         if (sc->hw_type == IWN_HW_REV_TYPE_1000) {
 1031                 /* Switch to absolute addressing mode. */
 1032                 IWN_CLRBITS(sc, IWN_OTP_GP, IWN_OTP_GP_RELATIVE_ACCESS);
 1033                 base = prev = 0;
 1034                 for (count = 0; count < IWN1000_OTP_NBLOCKS; count++) {
 1035                         error = iwn_read_prom_data(sc, base, &next, 2);
 1036                         if (error != 0)
 1037                                 return error;
 1038                         if (next == 0)  /* End of linked-list. */
 1039                                 break;
 1040                         prev = base;
 1041                         base = le16toh(next);
 1042                 }
 1043                 if (count == 0 || count == IWN1000_OTP_NBLOCKS)
 1044                         return EIO;
 1045                 /* Skip "next" word. */
 1046                 sc->prom_base = prev + 1;
 1047         }
 1048         return 0;
 1049 }
 1050 
 1051 static int
 1052 iwn_read_prom_data(struct iwn_softc *sc, uint32_t addr, void *data, int count)
 1053 {
 1054         uint32_t val, tmp;
 1055         int ntries;
 1056         uint8_t *out = data;
 1057 
 1058         addr += sc->prom_base;
 1059         for (; count > 0; count -= 2, addr++) {
 1060                 IWN_WRITE(sc, IWN_EEPROM, addr << 2);
 1061                 for (ntries = 0; ntries < 10; ntries++) {
 1062                         val = IWN_READ(sc, IWN_EEPROM);
 1063                         if (val & IWN_EEPROM_READ_VALID)
 1064                                 break;
 1065                         DELAY(5);
 1066                 }
 1067                 if (ntries == 10) {
 1068                         device_printf(sc->sc_dev,
 1069                             "timeout reading ROM at 0x%x\n", addr);
 1070                         return ETIMEDOUT;
 1071                 }
 1072                 if (sc->sc_flags & IWN_FLAG_HAS_OTPROM) {
 1073                         /* OTPROM, check for ECC errors. */
 1074                         tmp = IWN_READ(sc, IWN_OTP_GP);
 1075                         if (tmp & IWN_OTP_GP_ECC_UNCORR_STTS) {
 1076                                 device_printf(sc->sc_dev,
 1077                                     "OTPROM ECC error at 0x%x\n", addr);
 1078                                 return EIO;
 1079                         }
 1080                         if (tmp & IWN_OTP_GP_ECC_CORR_STTS) {
 1081                                 /* Correctable ECC error, clear bit. */
 1082                                 IWN_SETBITS(sc, IWN_OTP_GP,
 1083                                     IWN_OTP_GP_ECC_CORR_STTS);
 1084                         }
 1085                 }
 1086                 *out++ = val >> 16;
 1087                 if (count > 1)
 1088                         *out++ = val >> 24;
 1089         }
 1090         return 0;
 1091 }
 1092 
 1093 static void
 1094 iwn_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
 1095 {
 1096         if (error != 0)
 1097                 return;
 1098         KASSERT(nsegs == 1, ("too many DMA segments, %d should be 1", nsegs));
 1099         *(bus_addr_t *)arg = segs[0].ds_addr;
 1100 }
 1101 
 1102 static int
 1103 iwn_dma_contig_alloc(struct iwn_softc *sc, struct iwn_dma_info *dma,
 1104         void **kvap, bus_size_t size, bus_size_t alignment, int flags)
 1105 {
 1106         int error;
 1107 
 1108         dma->size = size;
 1109         dma->tag = NULL;
 1110 
 1111         error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), alignment,
 1112             0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, size,
 1113             1, size, flags, NULL, NULL, &dma->tag);
 1114         if (error != 0) {
 1115                 device_printf(sc->sc_dev,
 1116                     "%s: bus_dma_tag_create failed, error %d\n",
 1117                     __func__, error);
 1118                 goto fail;
 1119         }
 1120         error = bus_dmamem_alloc(dma->tag, (void **)&dma->vaddr,
 1121             flags | BUS_DMA_ZERO, &dma->map);
 1122         if (error != 0) {
 1123                 device_printf(sc->sc_dev,
 1124                     "%s: bus_dmamem_alloc failed, error %d\n", __func__, error);
 1125                 goto fail;
 1126         }
 1127         error = bus_dmamap_load(dma->tag, dma->map, dma->vaddr,
 1128             size, iwn_dma_map_addr, &dma->paddr, flags);
 1129         if (error != 0) {
 1130                 device_printf(sc->sc_dev,
 1131                     "%s: bus_dmamap_load failed, error %d\n", __func__, error);
 1132                 goto fail;
 1133         }
 1134 
 1135         if (kvap != NULL)
 1136                 *kvap = dma->vaddr;
 1137         return 0;
 1138 fail:
 1139         iwn_dma_contig_free(dma);
 1140         return error;
 1141 }
 1142 
 1143 static void
 1144 iwn_dma_contig_free(struct iwn_dma_info *dma)
 1145 {
 1146         if (dma->tag != NULL) {
 1147                 if (dma->map != NULL) {
 1148                         if (dma->paddr == 0) {
 1149                                 bus_dmamap_sync(dma->tag, dma->map,
 1150                                     BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
 1151                                 bus_dmamap_unload(dma->tag, dma->map);
 1152                         }
 1153                         bus_dmamem_free(dma->tag, &dma->vaddr, dma->map);
 1154                 }
 1155                 bus_dma_tag_destroy(dma->tag);
 1156         }
 1157 }
 1158 
 1159 static int
 1160 iwn_alloc_sched(struct iwn_softc *sc)
 1161 {
 1162         /* TX scheduler rings must be aligned on a 1KB boundary. */
 1163         return iwn_dma_contig_alloc(sc, &sc->sched_dma,
 1164             (void **)&sc->sched, sc->sc_hal->schedsz, 1024, BUS_DMA_NOWAIT);
 1165 }
 1166 
 1167 static void
 1168 iwn_free_sched(struct iwn_softc *sc)
 1169 {
 1170         iwn_dma_contig_free(&sc->sched_dma);
 1171 }
 1172 
 1173 static int
 1174 iwn_alloc_kw(struct iwn_softc *sc)
 1175 {
 1176         /* "Keep Warm" page must be aligned on a 4KB boundary. */
 1177         return iwn_dma_contig_alloc(sc, &sc->kw_dma, NULL, 4096, 4096,
 1178             BUS_DMA_NOWAIT);
 1179 }
 1180 
 1181 static void
 1182 iwn_free_kw(struct iwn_softc *sc)
 1183 {
 1184         iwn_dma_contig_free(&sc->kw_dma);
 1185 }
 1186 
 1187 static int
 1188 iwn_alloc_ict(struct iwn_softc *sc)
 1189 {
 1190         /* ICT table must be aligned on a 4KB boundary. */
 1191         return iwn_dma_contig_alloc(sc, &sc->ict_dma,
 1192             (void **)&sc->ict, IWN_ICT_SIZE, 4096, BUS_DMA_NOWAIT);
 1193 }
 1194 
 1195 static void
 1196 iwn_free_ict(struct iwn_softc *sc)
 1197 {
 1198         iwn_dma_contig_free(&sc->ict_dma);
 1199 }
 1200 
 1201 static int
 1202 iwn_alloc_fwmem(struct iwn_softc *sc)
 1203 {
 1204         /* Must be aligned on a 16-byte boundary. */
 1205         return iwn_dma_contig_alloc(sc, &sc->fw_dma, NULL,
 1206             sc->sc_hal->fwsz, 16, BUS_DMA_NOWAIT);
 1207 }
 1208 
 1209 static void
 1210 iwn_free_fwmem(struct iwn_softc *sc)
 1211 {
 1212         iwn_dma_contig_free(&sc->fw_dma);
 1213 }
 1214 
 1215 static int
 1216 iwn_alloc_rx_ring(struct iwn_softc *sc, struct iwn_rx_ring *ring)
 1217 {
 1218         bus_size_t size;
 1219         int i, error;
 1220 
 1221         ring->cur = 0;
 1222 
 1223         /* Allocate RX descriptors (256-byte aligned). */
 1224         size = IWN_RX_RING_COUNT * sizeof (uint32_t);
 1225         error = iwn_dma_contig_alloc(sc, &ring->desc_dma,
 1226             (void **)&ring->desc, size, 256, BUS_DMA_NOWAIT);
 1227         if (error != 0) {
 1228                 device_printf(sc->sc_dev,
 1229                     "%s: could not allocate Rx ring DMA memory, error %d\n",
 1230                     __func__, error);
 1231                 goto fail;
 1232         }
 1233 
 1234         error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0,
 1235             BUS_SPACE_MAXADDR_32BIT,
 1236             BUS_SPACE_MAXADDR, NULL, NULL, MJUMPAGESIZE, 1,
 1237             MJUMPAGESIZE, BUS_DMA_NOWAIT, NULL, NULL, &ring->data_dmat);
 1238         if (error != 0) {
 1239                 device_printf(sc->sc_dev,
 1240                     "%s: bus_dma_tag_create_failed, error %d\n",
 1241                     __func__, error);
 1242                 goto fail;
 1243         }
 1244 
 1245         /* Allocate RX status area (16-byte aligned). */
 1246         error = iwn_dma_contig_alloc(sc, &ring->stat_dma,
 1247             (void **)&ring->stat, sizeof (struct iwn_rx_status),
 1248             16, BUS_DMA_NOWAIT);
 1249         if (error != 0) {
 1250                 device_printf(sc->sc_dev,
 1251                     "%s: could not allocate Rx status DMA memory, error %d\n",
 1252                     __func__, error);
 1253                 goto fail;
 1254         }
 1255 
 1256         /*
 1257          * Allocate and map RX buffers.
 1258          */
 1259         for (i = 0; i < IWN_RX_RING_COUNT; i++) {
 1260                 struct iwn_rx_data *data = &ring->data[i];
 1261                 bus_addr_t paddr;
 1262 
 1263                 error = bus_dmamap_create(ring->data_dmat, 0, &data->map);
 1264                 if (error != 0) {
 1265                         device_printf(sc->sc_dev,
 1266                             "%s: bus_dmamap_create failed, error %d\n",
 1267                             __func__, error);
 1268                         goto fail;
 1269                 }
 1270 
 1271                 data->m = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, MJUMPAGESIZE);
 1272                 if (data->m == NULL) {
 1273                         device_printf(sc->sc_dev,
 1274                             "%s: could not allocate rx mbuf\n", __func__);
 1275                         error = ENOMEM;
 1276                         goto fail;
 1277                 }
 1278 
 1279                 /* Map page. */
 1280                 error = bus_dmamap_load(ring->data_dmat, data->map,
 1281                     mtod(data->m, caddr_t), MJUMPAGESIZE,
 1282                     iwn_dma_map_addr, &paddr, BUS_DMA_NOWAIT);
 1283                 if (error != 0 && error != EFBIG) {
 1284                         device_printf(sc->sc_dev,
 1285                             "%s: bus_dmamap_load failed, error %d\n",
 1286                             __func__, error);
 1287                         m_freem(data->m);
 1288                         error = ENOMEM; /* XXX unique code */
 1289                         goto fail;
 1290                 }
 1291                 bus_dmamap_sync(ring->data_dmat, data->map,
 1292                     BUS_DMASYNC_PREWRITE);
 1293 
 1294                 /* Set physical address of RX buffer (256-byte aligned). */
 1295                 ring->desc[i] = htole32(paddr >> 8);
 1296         }
 1297         bus_dmamap_sync(ring->desc_dma.tag, ring->desc_dma.map,
 1298             BUS_DMASYNC_PREWRITE);
 1299         return 0;
 1300 fail:
 1301         iwn_free_rx_ring(sc, ring);
 1302         return error;
 1303 }
 1304 
 1305 static void
 1306 iwn_reset_rx_ring(struct iwn_softc *sc, struct iwn_rx_ring *ring)
 1307 {
 1308         int ntries;
 1309 
 1310         if (iwn_nic_lock(sc) == 0) {
 1311                 IWN_WRITE(sc, IWN_FH_RX_CONFIG, 0);
 1312                 for (ntries = 0; ntries < 1000; ntries++) {
 1313                         if (IWN_READ(sc, IWN_FH_RX_STATUS) &
 1314                             IWN_FH_RX_STATUS_IDLE)
 1315                                 break;
 1316                         DELAY(10);
 1317                 }
 1318                 iwn_nic_unlock(sc);
 1319 #ifdef IWN_DEBUG
 1320                 if (ntries == 1000)
 1321                         DPRINTF(sc, IWN_DEBUG_ANY, "%s\n",
 1322                             "timeout resetting Rx ring");
 1323 #endif
 1324         }
 1325         ring->cur = 0;
 1326         sc->last_rx_valid = 0;
 1327 }
 1328 
 1329 static void
 1330 iwn_free_rx_ring(struct iwn_softc *sc, struct iwn_rx_ring *ring)
 1331 {
 1332         int i;
 1333 
 1334         iwn_dma_contig_free(&ring->desc_dma);
 1335         iwn_dma_contig_free(&ring->stat_dma);
 1336 
 1337         for (i = 0; i < IWN_RX_RING_COUNT; i++) {
 1338                 struct iwn_rx_data *data = &ring->data[i];
 1339 
 1340                 if (data->m != NULL) {
 1341                         bus_dmamap_sync(ring->data_dmat, data->map,
 1342                             BUS_DMASYNC_POSTREAD);
 1343                         bus_dmamap_unload(ring->data_dmat, data->map);
 1344                         m_freem(data->m);
 1345                 }
 1346                 if (data->map != NULL)
 1347                         bus_dmamap_destroy(ring->data_dmat, data->map);
 1348         }
 1349 }
 1350 
 1351 static int
 1352 iwn_alloc_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring, int qid)
 1353 {
 1354         bus_size_t size;
 1355         bus_addr_t paddr;
 1356         int i, error;
 1357 
 1358         ring->qid = qid;
 1359         ring->queued = 0;
 1360         ring->cur = 0;
 1361 
 1362         /* Allocate TX descriptors (256-byte aligned.) */
 1363         size = IWN_TX_RING_COUNT * sizeof(struct iwn_tx_desc);
 1364         error = iwn_dma_contig_alloc(sc, &ring->desc_dma,
 1365             (void **)&ring->desc, size, 256, BUS_DMA_NOWAIT);
 1366         if (error != 0) {
 1367                 device_printf(sc->sc_dev,
 1368                     "%s: could not allocate TX ring DMA memory, error %d\n",
 1369                     __func__, error);
 1370                 goto fail;
 1371         }
 1372 
 1373         /*
 1374          * We only use rings 0 through 4 (4 EDCA + cmd) so there is no need
 1375          * to allocate commands space for other rings.
 1376          */
 1377         if (qid > 4)
 1378                 return 0;
 1379 
 1380         size = IWN_TX_RING_COUNT * sizeof(struct iwn_tx_cmd);
 1381         error = iwn_dma_contig_alloc(sc, &ring->cmd_dma,
 1382             (void **)&ring->cmd, size, 4, BUS_DMA_NOWAIT);
 1383         if (error != 0) {
 1384                 device_printf(sc->sc_dev,
 1385                     "%s: could not allocate TX cmd DMA memory, error %d\n",
 1386                     __func__, error);
 1387                 goto fail;
 1388         }
 1389 
 1390         error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0,
 1391             BUS_SPACE_MAXADDR_32BIT,
 1392             BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES, IWN_MAX_SCATTER - 1,
 1393             MCLBYTES, BUS_DMA_NOWAIT, NULL, NULL, &ring->data_dmat);
 1394         if (error != 0) {
 1395                 device_printf(sc->sc_dev,
 1396                     "%s: bus_dma_tag_create_failed, error %d\n",
 1397                     __func__, error);
 1398                 goto fail;
 1399         }
 1400 
 1401         paddr = ring->cmd_dma.paddr;
 1402         for (i = 0; i < IWN_TX_RING_COUNT; i++) {
 1403                 struct iwn_tx_data *data = &ring->data[i];
 1404 
 1405                 data->cmd_paddr = paddr;
 1406                 data->scratch_paddr = paddr + 12;
 1407                 paddr += sizeof (struct iwn_tx_cmd);
 1408 
 1409                 error = bus_dmamap_create(ring->data_dmat, 0, &data->map);
 1410                 if (error != 0) {
 1411                         device_printf(sc->sc_dev,
 1412                             "%s: bus_dmamap_create failed, error %d\n",
 1413                             __func__, error);
 1414                         goto fail;
 1415                 }
 1416                 bus_dmamap_sync(ring->data_dmat, data->map,
 1417                     BUS_DMASYNC_PREWRITE);
 1418         }
 1419         return 0;
 1420 fail:
 1421         iwn_free_tx_ring(sc, ring);
 1422         return error;
 1423 }
 1424 
 1425 static void
 1426 iwn_reset_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring)
 1427 {
 1428         int i;
 1429 
 1430         for (i = 0; i < IWN_TX_RING_COUNT; i++) {
 1431                 struct iwn_tx_data *data = &ring->data[i];
 1432 
 1433                 if (data->m != NULL) {
 1434                         bus_dmamap_unload(ring->data_dmat, data->map);
 1435                         m_freem(data->m);
 1436                         data->m = NULL;
 1437                 }
 1438         }
 1439         /* Clear TX descriptors. */
 1440         memset(ring->desc, 0, ring->desc_dma.size);
 1441         bus_dmamap_sync(ring->desc_dma.tag, ring->desc_dma.map,
 1442             BUS_DMASYNC_PREWRITE);
 1443         sc->qfullmsk &= ~(1 << ring->qid);
 1444         ring->queued = 0;
 1445         ring->cur = 0;
 1446 }
 1447 
 1448 static void
 1449 iwn_free_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring)
 1450 {
 1451         int i;
 1452 
 1453         iwn_dma_contig_free(&ring->desc_dma);
 1454         iwn_dma_contig_free(&ring->cmd_dma);
 1455 
 1456         for (i = 0; i < IWN_TX_RING_COUNT; i++) {
 1457                 struct iwn_tx_data *data = &ring->data[i];
 1458 
 1459                 if (data->m != NULL) {
 1460                         bus_dmamap_sync(ring->data_dmat, data->map,
 1461                             BUS_DMASYNC_POSTWRITE);
 1462                         bus_dmamap_unload(ring->data_dmat, data->map);
 1463                         m_freem(data->m);
 1464                 }
 1465                 if (data->map != NULL)
 1466                         bus_dmamap_destroy(ring->data_dmat, data->map);
 1467         }
 1468 }
 1469 
 1470 static void
 1471 iwn5000_ict_reset(struct iwn_softc *sc)
 1472 {
 1473         /* Disable interrupts. */
 1474         IWN_WRITE(sc, IWN_INT_MASK, 0);
 1475 
 1476         /* Reset ICT table. */
 1477         memset(sc->ict, 0, IWN_ICT_SIZE);
 1478         sc->ict_cur = 0;
 1479 
 1480         /* Set physical address of ICT table (4KB aligned.) */
 1481         DPRINTF(sc, IWN_DEBUG_RESET, "%s: enabling ICT\n", __func__);
 1482         IWN_WRITE(sc, IWN_DRAM_INT_TBL, IWN_DRAM_INT_TBL_ENABLE |
 1483             IWN_DRAM_INT_TBL_WRAP_CHECK | sc->ict_dma.paddr >> 12);
 1484 
 1485         /* Enable periodic RX interrupt. */
 1486         sc->int_mask |= IWN_INT_RX_PERIODIC;
 1487         /* Switch to ICT interrupt mode in driver. */
 1488         sc->sc_flags |= IWN_FLAG_USE_ICT;
 1489 
 1490         /* Re-enable interrupts. */
 1491         IWN_WRITE(sc, IWN_INT, 0xffffffff);
 1492         IWN_WRITE(sc, IWN_INT_MASK, sc->int_mask);
 1493 }
 1494 
 1495 static int
 1496 iwn_read_eeprom(struct iwn_softc *sc, uint8_t macaddr[IEEE80211_ADDR_LEN])
 1497 {
 1498         const struct iwn_hal *hal = sc->sc_hal;
 1499         int error;
 1500         uint16_t val;
 1501 
 1502         /* Check whether adapter has an EEPROM or an OTPROM. */
 1503         if (sc->hw_type >= IWN_HW_REV_TYPE_1000 &&
 1504             (IWN_READ(sc, IWN_OTP_GP) & IWN_OTP_GP_DEV_SEL_OTP))
 1505                 sc->sc_flags |= IWN_FLAG_HAS_OTPROM;
 1506         DPRINTF(sc, IWN_DEBUG_RESET, "%s found\n",
 1507             (sc->sc_flags & IWN_FLAG_HAS_OTPROM) ? "OTPROM" : "EEPROM");
 1508 
 1509         /* Adapter has to be powered on for EEPROM access to work. */
 1510         error = iwn_apm_init(sc);
 1511         if (error != 0) {
 1512                 device_printf(sc->sc_dev,
 1513                     "%s: could not power ON adapter, error %d\n",
 1514                     __func__, error);
 1515                 return error;
 1516         }
 1517 
 1518         if ((IWN_READ(sc, IWN_EEPROM_GP) & 0x7) == 0) {
 1519                 device_printf(sc->sc_dev, "%s: bad ROM signature\n", __func__);
 1520                 return EIO;
 1521         }
 1522         error = iwn_eeprom_lock(sc);
 1523         if (error != 0) {
 1524                 device_printf(sc->sc_dev,
 1525                     "%s: could not lock ROM, error %d\n",
 1526                     __func__, error);
 1527                 return error;
 1528         }
 1529 
 1530         if (sc->sc_flags & IWN_FLAG_HAS_OTPROM) {
 1531                 error = iwn_init_otprom(sc);
 1532                 if (error != 0) {
 1533                         device_printf(sc->sc_dev,
 1534                             "%s: could not initialize OTPROM, error %d\n",
 1535                             __func__, error);
 1536                         return error;
 1537                 }
 1538         }
 1539 
 1540         iwn_read_prom_data(sc, IWN_EEPROM_RFCFG, &val, 2);
 1541         sc->rfcfg = le16toh(val);
 1542         DPRINTF(sc, IWN_DEBUG_RESET, "radio config=0x%04x\n", sc->rfcfg);
 1543 
 1544         /* Read MAC address. */
 1545         iwn_read_prom_data(sc, IWN_EEPROM_MAC, macaddr, 6);
 1546 
 1547         /* Read adapter-specific information from EEPROM. */
 1548         hal->read_eeprom(sc);
 1549 
 1550         iwn_apm_stop(sc);       /* Power OFF adapter. */
 1551 
 1552         iwn_eeprom_unlock(sc);
 1553         return 0;
 1554 }
 1555 
 1556 static void
 1557 iwn4965_read_eeprom(struct iwn_softc *sc)
 1558 {
 1559         uint32_t addr;
 1560         int i;
 1561         uint16_t val;
 1562 
 1563         /* Read regulatory domain (4 ASCII characters.) */
 1564         iwn_read_prom_data(sc, IWN4965_EEPROM_DOMAIN, sc->eeprom_domain, 4);
 1565 
 1566         /* Read the list of authorized channels (20MHz ones only.) */
 1567         for (i = 0; i < 5; i++) {
 1568                 addr = iwn4965_regulatory_bands[i];
 1569                 iwn_read_eeprom_channels(sc, i, addr);
 1570         }
 1571 
 1572         /* Read maximum allowed TX power for 2GHz and 5GHz bands. */
 1573         iwn_read_prom_data(sc, IWN4965_EEPROM_MAXPOW, &val, 2);
 1574         sc->maxpwr2GHz = val & 0xff;
 1575         sc->maxpwr5GHz = val >> 8;
 1576         /* Check that EEPROM values are within valid range. */
 1577         if (sc->maxpwr5GHz < 20 || sc->maxpwr5GHz > 50)
 1578                 sc->maxpwr5GHz = 38;
 1579         if (sc->maxpwr2GHz < 20 || sc->maxpwr2GHz > 50)
 1580                 sc->maxpwr2GHz = 38;
 1581         DPRINTF(sc, IWN_DEBUG_RESET, "maxpwr 2GHz=%d 5GHz=%d\n",
 1582             sc->maxpwr2GHz, sc->maxpwr5GHz);
 1583 
 1584         /* Read samples for each TX power group. */
 1585         iwn_read_prom_data(sc, IWN4965_EEPROM_BANDS, sc->bands,
 1586             sizeof sc->bands);
 1587 
 1588         /* Read voltage at which samples were taken. */
 1589         iwn_read_prom_data(sc, IWN4965_EEPROM_VOLTAGE, &val, 2);
 1590         sc->eeprom_voltage = (int16_t)le16toh(val);
 1591         DPRINTF(sc, IWN_DEBUG_RESET, "voltage=%d (in 0.3V)\n",
 1592             sc->eeprom_voltage);
 1593 
 1594 #ifdef IWN_DEBUG
 1595         /* Print samples. */
 1596         if (sc->sc_debug & IWN_DEBUG_ANY) {
 1597                 for (i = 0; i < IWN_NBANDS; i++)
 1598                         iwn4965_print_power_group(sc, i);
 1599         }
 1600 #endif
 1601 }
 1602 
 1603 #ifdef IWN_DEBUG
 1604 static void
 1605 iwn4965_print_power_group(struct iwn_softc *sc, int i)
 1606 {
 1607         struct iwn4965_eeprom_band *band = &sc->bands[i];
 1608         struct iwn4965_eeprom_chan_samples *chans = band->chans;
 1609         int j, c;
 1610 
 1611         printf("===band %d===\n", i);
 1612         printf("chan lo=%d, chan hi=%d\n", band->lo, band->hi);
 1613         printf("chan1 num=%d\n", chans[0].num);
 1614         for (c = 0; c < 2; c++) {
 1615                 for (j = 0; j < IWN_NSAMPLES; j++) {
 1616                         printf("chain %d, sample %d: temp=%d gain=%d "
 1617                             "power=%d pa_det=%d\n", c, j,
 1618                             chans[0].samples[c][j].temp,
 1619                             chans[0].samples[c][j].gain,
 1620                             chans[0].samples[c][j].power,
 1621                             chans[0].samples[c][j].pa_det);
 1622                 }
 1623         }
 1624         printf("chan2 num=%d\n", chans[1].num);
 1625         for (c = 0; c < 2; c++) {
 1626                 for (j = 0; j < IWN_NSAMPLES; j++) {
 1627                         printf("chain %d, sample %d: temp=%d gain=%d "
 1628                             "power=%d pa_det=%d\n", c, j,
 1629                             chans[1].samples[c][j].temp,
 1630                             chans[1].samples[c][j].gain,
 1631                             chans[1].samples[c][j].power,
 1632                             chans[1].samples[c][j].pa_det);
 1633                 }
 1634         }
 1635 }
 1636 #endif
 1637 
 1638 static void
 1639 iwn5000_read_eeprom(struct iwn_softc *sc)
 1640 {
 1641         struct iwn5000_eeprom_calib_hdr hdr;
 1642         int32_t temp, volt;
 1643         uint32_t addr, base;
 1644         int i;
 1645         uint16_t val;
 1646 
 1647         /* Read regulatory domain (4 ASCII characters.) */
 1648         iwn_read_prom_data(sc, IWN5000_EEPROM_REG, &val, 2);
 1649         base = le16toh(val);
 1650         iwn_read_prom_data(sc, base + IWN5000_EEPROM_DOMAIN,
 1651             sc->eeprom_domain, 4);
 1652 
 1653         /* Read the list of authorized channels (20MHz ones only.) */
 1654         for (i = 0; i < 5; i++) {
 1655                 addr = base + iwn5000_regulatory_bands[i];
 1656                 iwn_read_eeprom_channels(sc, i, addr);
 1657         }
 1658 
 1659         /* Read enhanced TX power information for 6000 Series. */
 1660         if (sc->hw_type >= IWN_HW_REV_TYPE_6000)
 1661                 iwn_read_eeprom_enhinfo(sc);
 1662 
 1663         iwn_read_prom_data(sc, IWN5000_EEPROM_CAL, &val, 2);
 1664         base = le16toh(val);
 1665         iwn_read_prom_data(sc, base, &hdr, sizeof hdr);
 1666         DPRINTF(sc, IWN_DEBUG_CALIBRATE,
 1667             "%s: calib version=%u pa type=%u voltage=%u\n",
 1668             __func__, hdr.version, hdr.pa_type, le16toh(hdr.volt));
 1669             sc->calib_ver = hdr.version;
 1670 
 1671         if (sc->hw_type == IWN_HW_REV_TYPE_5150) {
 1672                 /* Compute temperature offset. */
 1673                 iwn_read_prom_data(sc, base + IWN5000_EEPROM_TEMP, &val, 2);
 1674                 temp = le16toh(val);
 1675                 iwn_read_prom_data(sc, base + IWN5000_EEPROM_VOLT, &val, 2);
 1676                 volt = le16toh(val);
 1677                 sc->temp_off = temp - (volt / -5);
 1678                 DPRINTF(sc, IWN_DEBUG_CALIBRATE, "temp=%d volt=%d offset=%dK\n",
 1679                     temp, volt, sc->temp_off);
 1680         } else {
 1681                 /* Read crystal calibration. */
 1682                 iwn_read_prom_data(sc, base + IWN5000_EEPROM_CRYSTAL,
 1683                     &sc->eeprom_crystal, sizeof (uint32_t));
 1684                 DPRINTF(sc, IWN_DEBUG_CALIBRATE, "crystal calibration 0x%08x\n",
 1685                 le32toh(sc->eeprom_crystal));
 1686         }
 1687 }
 1688 
 1689 /*
 1690  * Translate EEPROM flags to net80211.
 1691  */
 1692 static uint32_t
 1693 iwn_eeprom_channel_flags(struct iwn_eeprom_chan *channel)
 1694 {
 1695         uint32_t nflags;
 1696 
 1697         nflags = 0;
 1698         if ((channel->flags & IWN_EEPROM_CHAN_ACTIVE) == 0)
 1699                 nflags |= IEEE80211_CHAN_PASSIVE;
 1700         if ((channel->flags & IWN_EEPROM_CHAN_IBSS) == 0)
 1701                 nflags |= IEEE80211_CHAN_NOADHOC;
 1702         if (channel->flags & IWN_EEPROM_CHAN_RADAR) {
 1703                 nflags |= IEEE80211_CHAN_DFS;
 1704                 /* XXX apparently IBSS may still be marked */
 1705                 nflags |= IEEE80211_CHAN_NOADHOC;
 1706         }
 1707 
 1708         return nflags;
 1709 }
 1710 
 1711 static void
 1712 iwn_read_eeprom_band(struct iwn_softc *sc, int n)
 1713 {
 1714         struct ifnet *ifp = sc->sc_ifp;
 1715         struct ieee80211com *ic = ifp->if_l2com;
 1716         struct iwn_eeprom_chan *channels = sc->eeprom_channels[n];
 1717         const struct iwn_chan_band *band = &iwn_bands[n];
 1718         struct ieee80211_channel *c;
 1719         int i, chan, nflags;
 1720 
 1721         for (i = 0; i < band->nchan; i++) {
 1722                 if (!(channels[i].flags & IWN_EEPROM_CHAN_VALID)) {
 1723                         DPRINTF(sc, IWN_DEBUG_RESET,
 1724                             "skip chan %d flags 0x%x maxpwr %d\n",
 1725                             band->chan[i], channels[i].flags,
 1726                             channels[i].maxpwr);
 1727                         continue;
 1728                 }
 1729                 chan = band->chan[i];
 1730                 nflags = iwn_eeprom_channel_flags(&channels[i]);
 1731 
 1732                 DPRINTF(sc, IWN_DEBUG_RESET,
 1733                     "add chan %d flags 0x%x maxpwr %d\n",
 1734                     chan, channels[i].flags, channels[i].maxpwr);
 1735 
 1736                 c = &ic->ic_channels[ic->ic_nchans++];
 1737                 c->ic_ieee = chan;
 1738                 c->ic_maxregpower = channels[i].maxpwr;
 1739                 c->ic_maxpower = 2*c->ic_maxregpower;
 1740 
 1741                 /* Save maximum allowed TX power for this channel. */
 1742                 sc->maxpwr[chan] = channels[i].maxpwr;
 1743 
 1744                 if (n == 0) {   /* 2GHz band */
 1745                         c->ic_freq = ieee80211_ieee2mhz(chan,
 1746                             IEEE80211_CHAN_G);
 1747 
 1748                         /* G =>'s B is supported */
 1749                         c->ic_flags = IEEE80211_CHAN_B | nflags;
 1750 
 1751                         c = &ic->ic_channels[ic->ic_nchans++];
 1752                         c[0] = c[-1];
 1753                         c->ic_flags = IEEE80211_CHAN_G | nflags;
 1754                 } else {        /* 5GHz band */
 1755                         c->ic_freq = ieee80211_ieee2mhz(chan,
 1756                             IEEE80211_CHAN_A);
 1757                         c->ic_flags = IEEE80211_CHAN_A | nflags;
 1758                         sc->sc_flags |= IWN_FLAG_HAS_5GHZ;
 1759                 }
 1760 #if 0   /* HT */
 1761                 /* XXX no constraints on using HT20 */
 1762                 /* add HT20, HT40 added separately */
 1763                 c = &ic->ic_channels[ic->ic_nchans++];
 1764                 c[0] = c[-1];
 1765                 c->ic_flags |= IEEE80211_CHAN_HT20;
 1766                 /* XXX NARROW =>'s 1/2 and 1/4 width? */
 1767 #endif
 1768         }
 1769 }
 1770 
 1771 #if 0   /* HT */
 1772 static void
 1773 iwn_read_eeprom_ht40(struct iwn_softc *sc, int n)
 1774 {
 1775         struct ifnet *ifp = sc->sc_ifp;
 1776         struct ieee80211com *ic = ifp->if_l2com;
 1777         struct iwn_eeprom_chan *channels = sc->eeprom_channels[n];
 1778         const struct iwn_chan_band *band = &iwn_bands[n];
 1779         struct ieee80211_channel *c, *cent, *extc;
 1780         int i;
 1781 
 1782         for (i = 0; i < band->nchan; i++) {
 1783                 if (!(channels[i].flags & IWN_EEPROM_CHAN_VALID) ||
 1784                     !(channels[i].flags & IWN_EEPROM_CHAN_WIDE)) {
 1785                         DPRINTF(sc, IWN_DEBUG_RESET,
 1786                             "skip chan %d flags 0x%x maxpwr %d\n",
 1787                             band->chan[i], channels[i].flags,
 1788                             channels[i].maxpwr);
 1789                         continue;
 1790                 }
 1791                 /*
 1792                  * Each entry defines an HT40 channel pair; find the
 1793                  * center channel, then the extension channel above.
 1794                  */
 1795                 cent = ieee80211_find_channel_byieee(ic, band->chan[i],
 1796                     band->flags & ~IEEE80211_CHAN_HT);
 1797                 if (cent == NULL) {     /* XXX shouldn't happen */
 1798                         device_printf(sc->sc_dev,
 1799                             "%s: no entry for channel %d\n",
 1800                             __func__, band->chan[i]);
 1801                         continue;
 1802                 }
 1803                 extc = ieee80211_find_channel(ic, cent->ic_freq+20,
 1804                     band->flags & ~IEEE80211_CHAN_HT);
 1805                 if (extc == NULL) {
 1806                         DPRINTF(sc, IWN_DEBUG_RESET,
 1807                             "skip chan %d, extension channel not found\n",
 1808                             band->chan[i]);
 1809                         continue;
 1810                 }
 1811 
 1812                 DPRINTF(sc, IWN_DEBUG_RESET,
 1813                     "add ht40 chan %d flags 0x%x maxpwr %d\n",
 1814                     band->chan[i], channels[i].flags, channels[i].maxpwr);
 1815 
 1816                 c = &ic->ic_channels[ic->ic_nchans++];
 1817                 c[0] = cent[0];
 1818                 c->ic_extieee = extc->ic_ieee;
 1819                 c->ic_flags &= ~IEEE80211_CHAN_HT;
 1820                 c->ic_flags |= IEEE80211_CHAN_HT40U;
 1821                 c = &ic->ic_channels[ic->ic_nchans++];
 1822                 c[0] = extc[0];
 1823                 c->ic_extieee = cent->ic_ieee;
 1824                 c->ic_flags &= ~IEEE80211_CHAN_HT;
 1825                 c->ic_flags |= IEEE80211_CHAN_HT40D;
 1826         }
 1827 }
 1828 #endif
 1829 
 1830 static void
 1831 iwn_read_eeprom_channels(struct iwn_softc *sc, int n, uint32_t addr)
 1832 {
 1833         struct ifnet *ifp = sc->sc_ifp;
 1834         struct ieee80211com *ic = ifp->if_l2com;
 1835 
 1836         iwn_read_prom_data(sc, addr, &sc->eeprom_channels[n],
 1837             iwn_bands[n].nchan * sizeof (struct iwn_eeprom_chan));
 1838 
 1839         if (n < 5)
 1840                 iwn_read_eeprom_band(sc, n);
 1841 #if 0   /* HT */
 1842         else
 1843                 iwn_read_eeprom_ht40(sc, n);
 1844 #endif
 1845         ieee80211_sort_channels(ic->ic_channels, ic->ic_nchans);
 1846 }
 1847 
 1848 #define nitems(_a)      (sizeof((_a)) / sizeof((_a)[0]))
 1849 
 1850 static void
 1851 iwn_read_eeprom_enhinfo(struct iwn_softc *sc)
 1852 {
 1853         struct iwn_eeprom_enhinfo enhinfo[35];
 1854         uint16_t val, base;
 1855         int8_t maxpwr;
 1856         int i;
 1857 
 1858         iwn_read_prom_data(sc, IWN5000_EEPROM_REG, &val, 2);
 1859         base = le16toh(val);
 1860         iwn_read_prom_data(sc, base + IWN6000_EEPROM_ENHINFO,
 1861             enhinfo, sizeof enhinfo);
 1862 
 1863         memset(sc->enh_maxpwr, 0, sizeof sc->enh_maxpwr);
 1864         for (i = 0; i < nitems(enhinfo); i++) {
 1865                 if (enhinfo[i].chan == 0 || enhinfo[i].reserved != 0)
 1866                         continue;       /* Skip invalid entries. */
 1867 
 1868                 maxpwr = 0;
 1869                 if (sc->txchainmask & IWN_ANT_A)
 1870                         maxpwr = MAX(maxpwr, enhinfo[i].chain[0]);
 1871                 if (sc->txchainmask & IWN_ANT_B)
 1872                         maxpwr = MAX(maxpwr, enhinfo[i].chain[1]);
 1873                 if (sc->txchainmask & IWN_ANT_C)
 1874                         maxpwr = MAX(maxpwr, enhinfo[i].chain[2]);
 1875                 if (sc->ntxchains == 2)
 1876                         maxpwr = MAX(maxpwr, enhinfo[i].mimo2);
 1877                 else if (sc->ntxchains == 3)
 1878                         maxpwr = MAX(maxpwr, enhinfo[i].mimo3);
 1879                 maxpwr /= 2;    /* Convert half-dBm to dBm. */
 1880 
 1881                 DPRINTF(sc, IWN_DEBUG_RESET, "enhinfo %d, maxpwr=%d\n", i,
 1882                     maxpwr);
 1883                 sc->enh_maxpwr[i] = maxpwr;
 1884         }
 1885 }
 1886 
 1887 static struct ieee80211_node *
 1888 iwn_node_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN])
 1889 {
 1890         return malloc(sizeof (struct iwn_node), M_80211_NODE,M_NOWAIT | M_ZERO);
 1891 }
 1892 
 1893 static void
 1894 iwn_newassoc(struct ieee80211_node *ni, int isnew)
 1895 {
 1896         /* XXX move */
 1897         ieee80211_ratectl_node_init(ni);
 1898 }
 1899 
 1900 static int
 1901 iwn_media_change(struct ifnet *ifp)
 1902 {
 1903         int error = ieee80211_media_change(ifp);
 1904         /* NB: only the fixed rate can change and that doesn't need a reset */
 1905         return (error == ENETRESET ? 0 : error);
 1906 }
 1907 
 1908 static int
 1909 iwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
 1910 {
 1911         struct iwn_vap *ivp = IWN_VAP(vap);
 1912         struct ieee80211com *ic = vap->iv_ic;
 1913         struct iwn_softc *sc = ic->ic_ifp->if_softc;
 1914         int error;
 1915 
 1916         DPRINTF(sc, IWN_DEBUG_STATE, "%s: %s -> %s\n", __func__,
 1917                 ieee80211_state_name[vap->iv_state],
 1918                 ieee80211_state_name[nstate]);
 1919 
 1920         IEEE80211_UNLOCK(ic);
 1921         IWN_LOCK(sc);
 1922         callout_stop(&sc->sc_timer_to);
 1923 
 1924         if (nstate == IEEE80211_S_AUTH && vap->iv_state != IEEE80211_S_AUTH) {
 1925                 /* !AUTH -> AUTH requires adapter config */
 1926                 /* Reset state to handle reassociations correctly. */
 1927                 sc->rxon.associd = 0;
 1928                 sc->rxon.filter &= ~htole32(IWN_FILTER_BSS);
 1929                 iwn_calib_reset(sc);
 1930                 error = iwn_auth(sc, vap);
 1931         }
 1932         if (nstate == IEEE80211_S_RUN && vap->iv_state != IEEE80211_S_RUN) {
 1933                 /*
 1934                  * !RUN -> RUN requires setting the association id
 1935                  * which is done with a firmware cmd.  We also defer
 1936                  * starting the timers until that work is done.
 1937                  */
 1938                 error = iwn_run(sc, vap);
 1939         }
 1940         if (nstate == IEEE80211_S_RUN) {
 1941                 /*
 1942                  * RUN -> RUN transition; just restart the timers.
 1943                  */
 1944                 iwn_calib_reset(sc);
 1945         }
 1946         IWN_UNLOCK(sc);
 1947         IEEE80211_LOCK(ic);
 1948         return ivp->iv_newstate(vap, nstate, arg);
 1949 }
 1950 
 1951 /*
 1952  * Process an RX_PHY firmware notification.  This is usually immediately
 1953  * followed by an MPDU_RX_DONE notification.
 1954  */
 1955 static void
 1956 iwn_rx_phy(struct iwn_softc *sc, struct iwn_rx_desc *desc,
 1957     struct iwn_rx_data *data)
 1958 {
 1959         struct iwn_rx_stat *stat = (struct iwn_rx_stat *)(desc + 1);
 1960 
 1961         DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: received PHY stats\n", __func__);
 1962         bus_dmamap_sync(sc->rxq.data_dmat, data->map, BUS_DMASYNC_POSTREAD);
 1963 
 1964         /* Save RX statistics, they will be used on MPDU_RX_DONE. */
 1965         memcpy(&sc->last_rx_stat, stat, sizeof (*stat));
 1966         sc->last_rx_valid = 1;
 1967 }
 1968 
 1969 static void
 1970 iwn_timer_timeout(void *arg)
 1971 {
 1972         struct iwn_softc *sc = arg;
 1973         uint32_t flags = 0;
 1974 
 1975         IWN_LOCK_ASSERT(sc);
 1976 
 1977         if (sc->calib_cnt && --sc->calib_cnt == 0) {
 1978                 DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s\n",
 1979                     "send statistics request");
 1980                 (void) iwn_cmd(sc, IWN_CMD_GET_STATISTICS, &flags,
 1981                     sizeof flags, 1);
 1982                 sc->calib_cnt = 60;     /* do calibration every 60s */
 1983         }
 1984         iwn_watchdog(sc);               /* NB: piggyback tx watchdog */
 1985         callout_reset(&sc->sc_timer_to, hz, iwn_timer_timeout, sc);
 1986 }
 1987 
 1988 static void
 1989 iwn_calib_reset(struct iwn_softc *sc)
 1990 {
 1991         callout_reset(&sc->sc_timer_to, hz, iwn_timer_timeout, sc);
 1992         sc->calib_cnt = 60;             /* do calibration every 60s */
 1993 }
 1994 
 1995 /*
 1996  * Process an RX_DONE (4965AGN only) or MPDU_RX_DONE firmware notification.
 1997  * Each MPDU_RX_DONE notification must be preceded by an RX_PHY one.
 1998  */
 1999 static void
 2000 iwn_rx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc,
 2001     struct iwn_rx_data *data)
 2002 {
 2003         const struct iwn_hal *hal = sc->sc_hal;
 2004         struct ifnet *ifp = sc->sc_ifp;
 2005         struct ieee80211com *ic = ifp->if_l2com;
 2006         struct iwn_rx_ring *ring = &sc->rxq;
 2007         struct ieee80211_frame *wh;
 2008         struct ieee80211_node *ni;
 2009         struct mbuf *m, *m1;
 2010         struct iwn_rx_stat *stat;
 2011         caddr_t head;
 2012         bus_addr_t paddr;
 2013         uint32_t flags;
 2014         int error, len, rssi, nf;
 2015 
 2016         if (desc->type == IWN_MPDU_RX_DONE) {
 2017                 /* Check for prior RX_PHY notification. */
 2018                 if (!sc->last_rx_valid) {
 2019                         DPRINTF(sc, IWN_DEBUG_ANY,
 2020                             "%s: missing RX_PHY\n", __func__);
 2021                         ifp->if_ierrors++;
 2022                         return;
 2023                 }
 2024                 sc->last_rx_valid = 0;
 2025                 stat = &sc->last_rx_stat;
 2026         } else
 2027                 stat = (struct iwn_rx_stat *)(desc + 1);
 2028 
 2029         bus_dmamap_sync(ring->data_dmat, data->map, BUS_DMASYNC_POSTREAD);
 2030 
 2031         if (stat->cfg_phy_len > IWN_STAT_MAXLEN) {
 2032                 device_printf(sc->sc_dev,
 2033                     "%s: invalid rx statistic header, len %d\n",
 2034                     __func__, stat->cfg_phy_len);
 2035                 ifp->if_ierrors++;
 2036                 return;
 2037         }
 2038         if (desc->type == IWN_MPDU_RX_DONE) {
 2039                 struct iwn_rx_mpdu *mpdu = (struct iwn_rx_mpdu *)(desc + 1);
 2040                 head = (caddr_t)(mpdu + 1);
 2041                 len = le16toh(mpdu->len);
 2042         } else {
 2043                 head = (caddr_t)(stat + 1) + stat->cfg_phy_len;
 2044                 len = le16toh(stat->len);
 2045         }
 2046 
 2047         flags = le32toh(*(uint32_t *)(head + len));
 2048 
 2049         /* Discard frames with a bad FCS early. */
 2050         if ((flags & IWN_RX_NOERROR) != IWN_RX_NOERROR) {
 2051                 DPRINTF(sc, IWN_DEBUG_RECV, "%s: rx flags error %x\n",
 2052                     __func__, flags);
 2053                 ifp->if_ierrors++;
 2054                 return;
 2055         }
 2056         /* Discard frames that are too short. */
 2057         if (len < sizeof (*wh)) {
 2058                 DPRINTF(sc, IWN_DEBUG_RECV, "%s: frame too short: %d\n",
 2059                     __func__, len);
 2060                 ifp->if_ierrors++;
 2061                 return;
 2062         }
 2063 
 2064         /* XXX don't need mbuf, just dma buffer */
 2065         m1 = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, MJUMPAGESIZE);
 2066         if (m1 == NULL) {
 2067                 DPRINTF(sc, IWN_DEBUG_ANY, "%s: no mbuf to restock ring\n",
 2068                     __func__);
 2069                 ifp->if_ierrors++;
 2070                 return;
 2071         }
 2072         bus_dmamap_unload(ring->data_dmat, data->map);
 2073 
 2074         error = bus_dmamap_load(ring->data_dmat, data->map,
 2075             mtod(m1, caddr_t), MJUMPAGESIZE,
 2076             iwn_dma_map_addr, &paddr, BUS_DMA_NOWAIT);
 2077         if (error != 0 && error != EFBIG) {
 2078                 device_printf(sc->sc_dev,
 2079                     "%s: bus_dmamap_load failed, error %d\n", __func__, error);
 2080                 m_freem(m1);
 2081                 ifp->if_ierrors++;
 2082                 return;
 2083         }
 2084 
 2085         m = data->m;
 2086         data->m = m1;
 2087         /* Update RX descriptor. */
 2088         ring->desc[ring->cur] = htole32(paddr >> 8);
 2089         bus_dmamap_sync(ring->desc_dma.tag, ring->desc_dma.map,
 2090             BUS_DMASYNC_PREWRITE);
 2091 
 2092         /* Finalize mbuf. */
 2093         m->m_pkthdr.rcvif = ifp;
 2094         m->m_data = head;
 2095         m->m_pkthdr.len = m->m_len = len;
 2096 
 2097         rssi = hal->get_rssi(sc, stat);
 2098 
 2099         /* Grab a reference to the source node. */
 2100         wh = mtod(m, struct ieee80211_frame *);
 2101         ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh);
 2102         nf = (ni != NULL && ni->ni_vap->iv_state == IEEE80211_S_RUN &&
 2103             (ic->ic_flags & IEEE80211_F_SCAN) == 0) ? sc->noise : -95;
 2104 
 2105         if (ieee80211_radiotap_active(ic)) {
 2106                 struct iwn_rx_radiotap_header *tap = &sc->sc_rxtap;
 2107 
 2108                 tap->wr_tsft = htole64(stat->tstamp);
 2109                 tap->wr_flags = 0;
 2110                 if (stat->flags & htole16(IWN_STAT_FLAG_SHPREAMBLE))
 2111                         tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
 2112                 switch (stat->rate) {
 2113                 /* CCK rates. */
 2114                 case  10: tap->wr_rate =   2; break;
 2115                 case  20: tap->wr_rate =   4; break;
 2116                 case  55: tap->wr_rate =  11; break;
 2117                 case 110: tap->wr_rate =  22; break;
 2118                 /* OFDM rates. */
 2119                 case 0xd: tap->wr_rate =  12; break;
 2120                 case 0xf: tap->wr_rate =  18; break;
 2121                 case 0x5: tap->wr_rate =  24; break;
 2122                 case 0x7: tap->wr_rate =  36; break;
 2123                 case 0x9: tap->wr_rate =  48; break;
 2124                 case 0xb: tap->wr_rate =  72; break;
 2125                 case 0x1: tap->wr_rate =  96; break;
 2126                 case 0x3: tap->wr_rate = 108; break;
 2127                 /* Unknown rate: should not happen. */
 2128                 default:  tap->wr_rate =   0;
 2129                 }
 2130                 tap->wr_dbm_antsignal = rssi;
 2131                 tap->wr_dbm_antnoise = nf;
 2132         }
 2133 
 2134         IWN_UNLOCK(sc);
 2135 
 2136         /* Send the frame to the 802.11 layer. */
 2137         if (ni != NULL) {
 2138                 (void) ieee80211_input(ni, m, rssi - nf, nf);
 2139                 /* Node is no longer needed. */
 2140                 ieee80211_free_node(ni);
 2141         } else
 2142                 (void) ieee80211_input_all(ic, m, rssi - nf, nf);
 2143 
 2144         IWN_LOCK(sc);
 2145 }
 2146 
 2147 #if 0   /* HT */
 2148 /* Process an incoming Compressed BlockAck. */
 2149 static void
 2150 iwn_rx_compressed_ba(struct iwn_softc *sc, struct iwn_rx_desc *desc,
 2151     struct iwn_rx_data *data)
 2152 {
 2153         struct iwn_compressed_ba *ba = (struct iwn_compressed_ba *)(desc + 1);
 2154         struct iwn_tx_ring *txq;
 2155 
 2156         txq = &sc->txq[letoh16(ba->qid)];
 2157         /* XXX TBD */
 2158 }
 2159 #endif
 2160 
 2161 /*
 2162  * Process a CALIBRATION_RESULT notification sent by the initialization
 2163  * firmware on response to a CMD_CALIB_CONFIG command (5000 only.)
 2164  */
 2165 static void
 2166 iwn5000_rx_calib_results(struct iwn_softc *sc, struct iwn_rx_desc *desc,
 2167     struct iwn_rx_data *data)
 2168 {
 2169         struct iwn_phy_calib *calib = (struct iwn_phy_calib *)(desc + 1);
 2170         int len, idx = -1;
 2171 
 2172         /* Runtime firmware should not send such a notification. */
 2173         if (sc->sc_flags & IWN_FLAG_CALIB_DONE)
 2174                 return;
 2175 
 2176         bus_dmamap_sync(sc->rxq.data_dmat, data->map, BUS_DMASYNC_POSTREAD);
 2177         len = (le32toh(desc->len) & 0x3fff) - 4;
 2178 
 2179         switch (calib->code) {
 2180         case IWN5000_PHY_CALIB_DC:
 2181                 if (sc->hw_type == IWN_HW_REV_TYPE_5150 ||
 2182                     sc->hw_type == IWN_HW_REV_TYPE_6050)
 2183                         idx = 0;
 2184                 break;
 2185         case IWN5000_PHY_CALIB_LO:
 2186                 idx = 1;
 2187                 break;
 2188         case IWN5000_PHY_CALIB_TX_IQ:
 2189                 idx = 2;
 2190                 break;
 2191         case IWN5000_PHY_CALIB_TX_IQ_PERIODIC:
 2192                 if (sc->hw_type < IWN_HW_REV_TYPE_6000 &&
 2193                     sc->hw_type != IWN_HW_REV_TYPE_5150)
 2194                         idx = 3;
 2195                 break;
 2196         case IWN5000_PHY_CALIB_BASE_BAND:
 2197                 idx = 4;
 2198                 break;
 2199         }
 2200         if (idx == -1)  /* Ignore other results. */
 2201                 return;
 2202 
 2203         /* Save calibration result. */
 2204         if (sc->calibcmd[idx].buf != NULL)
 2205                 free(sc->calibcmd[idx].buf, M_DEVBUF);
 2206         sc->calibcmd[idx].buf = malloc(len, M_DEVBUF, M_NOWAIT);
 2207         if (sc->calibcmd[idx].buf == NULL) {
 2208                 DPRINTF(sc, IWN_DEBUG_CALIBRATE,
 2209                     "not enough memory for calibration result %d\n",
 2210                     calib->code);
 2211                 return;
 2212         }
 2213         DPRINTF(sc, IWN_DEBUG_CALIBRATE,
 2214             "saving calibration result code=%d len=%d\n", calib->code, len);
 2215         sc->calibcmd[idx].len = len;
 2216         memcpy(sc->calibcmd[idx].buf, calib, len);
 2217 }
 2218 
 2219 /*
 2220  * Process an RX_STATISTICS or BEACON_STATISTICS firmware notification.
 2221  * The latter is sent by the firmware after each received beacon.
 2222  */
 2223 static void
 2224 iwn_rx_statistics(struct iwn_softc *sc, struct iwn_rx_desc *desc,
 2225     struct iwn_rx_data *data)
 2226 {
 2227         const struct iwn_hal *hal = sc->sc_hal;
 2228         struct ifnet *ifp = sc->sc_ifp;
 2229         struct ieee80211com *ic = ifp->if_l2com;
 2230         struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
 2231         struct iwn_calib_state *calib = &sc->calib;
 2232         struct iwn_stats *stats = (struct iwn_stats *)(desc + 1);
 2233         int temp;
 2234 
 2235         /* Beacon stats are meaningful only when associated and not scanning. */
 2236         if (vap->iv_state != IEEE80211_S_RUN ||
 2237             (ic->ic_flags & IEEE80211_F_SCAN))
 2238                 return;
 2239 
 2240         bus_dmamap_sync(sc->rxq.data_dmat, data->map, BUS_DMASYNC_POSTREAD);
 2241         DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: cmd %d\n", __func__, desc->type);
 2242         iwn_calib_reset(sc);    /* Reset TX power calibration timeout. */
 2243 
 2244         /* Test if temperature has changed. */
 2245         if (stats->general.temp != sc->rawtemp) {
 2246                 /* Convert "raw" temperature to degC. */
 2247                 sc->rawtemp = stats->general.temp;
 2248                 temp = hal->get_temperature(sc);
 2249                 DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: temperature %d\n",
 2250                     __func__, temp);
 2251 
 2252                 /* Update TX power if need be (4965AGN only.) */
 2253                 if (sc->hw_type == IWN_HW_REV_TYPE_4965)
 2254                         iwn4965_power_calibration(sc, temp);
 2255         }
 2256 
 2257         if (desc->type != IWN_BEACON_STATISTICS)
 2258                 return; /* Reply to a statistics request. */
 2259 
 2260         sc->noise = iwn_get_noise(&stats->rx.general);
 2261         DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: noise %d\n", __func__, sc->noise);
 2262 
 2263         /* Test that RSSI and noise are present in stats report. */
 2264         if (le32toh(stats->rx.general.flags) != 1) {
 2265                 DPRINTF(sc, IWN_DEBUG_ANY, "%s\n",
 2266                     "received statistics without RSSI");
 2267                 return;
 2268         }
 2269 
 2270         if (calib->state == IWN_CALIB_STATE_ASSOC)
 2271                 iwn_collect_noise(sc, &stats->rx.general);
 2272         else if (calib->state == IWN_CALIB_STATE_RUN)
 2273                 iwn_tune_sensitivity(sc, &stats->rx);
 2274 }
 2275 
 2276 /*
 2277  * Process a TX_DONE firmware notification.  Unfortunately, the 4965AGN
 2278  * and 5000 adapters have different incompatible TX status formats.
 2279  */
 2280 static void
 2281 iwn4965_tx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc,
 2282     struct iwn_rx_data *data)
 2283 {
 2284         struct iwn4965_tx_stat *stat = (struct iwn4965_tx_stat *)(desc + 1);
 2285         struct iwn_tx_ring *ring = &sc->txq[desc->qid & 0xf];
 2286 
 2287         DPRINTF(sc, IWN_DEBUG_XMIT, "%s: "
 2288             "qid %d idx %d retries %d nkill %d rate %x duration %d status %x\n",
 2289             __func__, desc->qid, desc->idx, stat->ackfailcnt,
 2290             stat->btkillcnt, stat->rate, le16toh(stat->duration),
 2291             le32toh(stat->status));
 2292 
 2293         bus_dmamap_sync(ring->data_dmat, data->map, BUS_DMASYNC_POSTREAD);
 2294         iwn_tx_done(sc, desc, stat->ackfailcnt, le32toh(stat->status) & 0xff);
 2295 }
 2296 
 2297 static void
 2298 iwn5000_tx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc,
 2299     struct iwn_rx_data *data)
 2300 {
 2301         struct iwn5000_tx_stat *stat = (struct iwn5000_tx_stat *)(desc + 1);
 2302         struct iwn_tx_ring *ring = &sc->txq[desc->qid & 0xf];
 2303 
 2304         DPRINTF(sc, IWN_DEBUG_XMIT, "%s: "
 2305             "qid %d idx %d retries %d nkill %d rate %x duration %d status %x\n",
 2306             __func__, desc->qid, desc->idx, stat->ackfailcnt,
 2307             stat->btkillcnt, stat->rate, le16toh(stat->duration),
 2308             le32toh(stat->status));
 2309 
 2310 #ifdef notyet
 2311         /* Reset TX scheduler slot. */
 2312         iwn5000_reset_sched(sc, desc->qid & 0xf, desc->idx);
 2313 #endif
 2314 
 2315         bus_dmamap_sync(ring->data_dmat, data->map, BUS_DMASYNC_POSTREAD);
 2316         iwn_tx_done(sc, desc, stat->ackfailcnt, le16toh(stat->status) & 0xff);
 2317 }
 2318 
 2319 /*
 2320  * Adapter-independent backend for TX_DONE firmware notifications.
 2321  */
 2322 static void
 2323 iwn_tx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc, int ackfailcnt,
 2324     uint8_t status)
 2325 {
 2326         struct ifnet *ifp = sc->sc_ifp;
 2327         struct iwn_tx_ring *ring = &sc->txq[desc->qid & 0xf];
 2328         struct iwn_tx_data *data = &ring->data[desc->idx];
 2329         struct mbuf *m;
 2330         struct ieee80211_node *ni;
 2331         struct ieee80211vap *vap;
 2332 
 2333         KASSERT(data->ni != NULL, ("no node"));
 2334 
 2335         /* Unmap and free mbuf. */
 2336         bus_dmamap_sync(ring->data_dmat, data->map, BUS_DMASYNC_POSTWRITE);
 2337         bus_dmamap_unload(ring->data_dmat, data->map);
 2338         m = data->m, data->m = NULL;
 2339         ni = data->ni, data->ni = NULL;
 2340         vap = ni->ni_vap;
 2341 
 2342         if (m->m_flags & M_TXCB) {
 2343                 /*
 2344                  * Channels marked for "radar" require traffic to be received
 2345                  * to unlock before we can transmit.  Until traffic is seen
 2346                  * any attempt to transmit is returned immediately with status
 2347                  * set to IWN_TX_FAIL_TX_LOCKED.  Unfortunately this can easily
 2348                  * happen on first authenticate after scanning.  To workaround
 2349                  * this we ignore a failure of this sort in AUTH state so the
 2350                  * 802.11 layer will fall back to using a timeout to wait for
 2351                  * the AUTH reply.  This allows the firmware time to see
 2352                  * traffic so a subsequent retry of AUTH succeeds.  It's
 2353                  * unclear why the firmware does not maintain state for
 2354                  * channels recently visited as this would allow immediate
 2355                  * use of the channel after a scan (where we see traffic).
 2356                  */
 2357                 if (status == IWN_TX_FAIL_TX_LOCKED &&
 2358                     ni->ni_vap->iv_state == IEEE80211_S_AUTH)
 2359                         ieee80211_process_callback(ni, m, 0);
 2360                 else
 2361                         ieee80211_process_callback(ni, m,
 2362                             (status & IWN_TX_FAIL) != 0);
 2363         }
 2364 
 2365         /*
 2366          * Update rate control statistics for the node.
 2367          */
 2368         if (status & 0x80) {
 2369                 ifp->if_oerrors++;
 2370                 ieee80211_ratectl_tx_complete(vap, ni,
 2371                     IEEE80211_RATECTL_TX_FAILURE, &ackfailcnt, NULL);
 2372         } else {
 2373                 ieee80211_ratectl_tx_complete(vap, ni,
 2374                     IEEE80211_RATECTL_TX_SUCCESS, &ackfailcnt, NULL);
 2375         }
 2376         m_freem(m);
 2377         ieee80211_free_node(ni);
 2378 
 2379         sc->sc_tx_timer = 0;
 2380         if (--ring->queued < IWN_TX_RING_LOMARK) {
 2381                 sc->qfullmsk &= ~(1 << ring->qid);
 2382                 if (sc->qfullmsk == 0 &&
 2383                     (ifp->if_drv_flags & IFF_DRV_OACTIVE)) {
 2384                         ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 2385                         iwn_start_locked(ifp);
 2386                 }
 2387         }
 2388 }
 2389 
 2390 /*
 2391  * Process a "command done" firmware notification.  This is where we wakeup
 2392  * processes waiting for a synchronous command completion.
 2393  */
 2394 static void
 2395 iwn_cmd_done(struct iwn_softc *sc, struct iwn_rx_desc *desc)
 2396 {
 2397         struct iwn_tx_ring *ring = &sc->txq[4];
 2398         struct iwn_tx_data *data;
 2399 
 2400         if ((desc->qid & 0xf) != 4)
 2401                 return; /* Not a command ack. */
 2402 
 2403         data = &ring->data[desc->idx];
 2404 
 2405         /* If the command was mapped in an mbuf, free it. */
 2406         if (data->m != NULL) {
 2407                 bus_dmamap_unload(ring->data_dmat, data->map);
 2408                 m_freem(data->m);
 2409                 data->m = NULL;
 2410         }
 2411         wakeup(&ring->desc[desc->idx]);
 2412 }
 2413 
 2414 /*
 2415  * Process an INT_FH_RX or INT_SW_RX interrupt.
 2416  */
 2417 static void
 2418 iwn_notif_intr(struct iwn_softc *sc)
 2419 {
 2420         struct ifnet *ifp = sc->sc_ifp;
 2421         struct ieee80211com *ic = ifp->if_l2com;
 2422         struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
 2423         uint16_t hw;
 2424 
 2425         bus_dmamap_sync(sc->rxq.stat_dma.tag, sc->rxq.stat_dma.map,
 2426             BUS_DMASYNC_POSTREAD);
 2427 
 2428         hw = le16toh(sc->rxq.stat->closed_count) & 0xfff;
 2429         while (sc->rxq.cur != hw) {
 2430                 struct iwn_rx_data *data = &sc->rxq.data[sc->rxq.cur];
 2431                 struct iwn_rx_desc *desc;
 2432 
 2433                 bus_dmamap_sync(sc->rxq.data_dmat, data->map,
 2434                     BUS_DMASYNC_POSTREAD);
 2435                 desc = mtod(data->m, struct iwn_rx_desc *);
 2436 
 2437                 DPRINTF(sc, IWN_DEBUG_RECV,
 2438                     "%s: qid %x idx %d flags %x type %d(%s) len %d\n",
 2439                     __func__, desc->qid & 0xf, desc->idx, desc->flags,
 2440                     desc->type, iwn_intr_str(desc->type),
 2441                     le16toh(desc->len));
 2442 
 2443                 if (!(desc->qid & 0x80))        /* Reply to a command. */
 2444                         iwn_cmd_done(sc, desc);
 2445 
 2446                 switch (desc->type) {
 2447                 case IWN_RX_PHY:
 2448                         iwn_rx_phy(sc, desc, data);
 2449                         break;
 2450 
 2451                 case IWN_RX_DONE:               /* 4965AGN only. */
 2452                 case IWN_MPDU_RX_DONE:
 2453                         /* An 802.11 frame has been received. */
 2454                         iwn_rx_done(sc, desc, data);
 2455                         break;
 2456 
 2457 #if 0   /* HT */
 2458                 case IWN_RX_COMPRESSED_BA:
 2459                         /* A Compressed BlockAck has been received. */
 2460                         iwn_rx_compressed_ba(sc, desc, data);
 2461                         break;
 2462 #endif
 2463 
 2464                 case IWN_TX_DONE:
 2465                         /* An 802.11 frame has been transmitted. */
 2466                         sc->sc_hal->tx_done(sc, desc, data);
 2467                         break;
 2468 
 2469                 case IWN_RX_STATISTICS:
 2470                 case IWN_BEACON_STATISTICS:
 2471                         iwn_rx_statistics(sc, desc, data);
 2472                         break;
 2473 
 2474                 case IWN_BEACON_MISSED:
 2475                 {
 2476                         struct iwn_beacon_missed *miss =
 2477                             (struct iwn_beacon_missed *)(desc + 1);
 2478                         int misses;
 2479 
 2480                         bus_dmamap_sync(sc->rxq.data_dmat, data->map,
 2481                             BUS_DMASYNC_POSTREAD);
 2482                         misses = le32toh(miss->consecutive);
 2483 
 2484                         /* XXX not sure why we're notified w/ zero */
 2485                         if (misses == 0)
 2486                                 break;
 2487                         DPRINTF(sc, IWN_DEBUG_STATE,
 2488                             "%s: beacons missed %d/%d\n", __func__,
 2489                             misses, le32toh(miss->total));
 2490 
 2491                         /*
 2492                          * If more than 5 consecutive beacons are missed,
 2493                          * reinitialize the sensitivity state machine.
 2494                          */
 2495                         if (vap->iv_state == IEEE80211_S_RUN && misses > 5)
 2496                                 (void) iwn_init_sensitivity(sc);
 2497                         if (misses >= vap->iv_bmissthreshold) {
 2498                                 IWN_UNLOCK(sc);
 2499                                 ieee80211_beacon_miss(ic);
 2500                                 IWN_LOCK(sc);
 2501                         }
 2502                         break;
 2503                 }
 2504                 case IWN_UC_READY:
 2505                 {
 2506                         struct iwn_ucode_info *uc =
 2507                             (struct iwn_ucode_info *)(desc + 1);
 2508 
 2509                         /* The microcontroller is ready. */
 2510                         bus_dmamap_sync(sc->rxq.data_dmat, data->map,
 2511                             BUS_DMASYNC_POSTREAD);
 2512                         DPRINTF(sc, IWN_DEBUG_RESET,
 2513                             "microcode alive notification version=%d.%d "
 2514                             "subtype=%x alive=%x\n", uc->major, uc->minor,
 2515                             uc->subtype, le32toh(uc->valid));
 2516 
 2517                         if (le32toh(uc->valid) != 1) {
 2518                                 device_printf(sc->sc_dev,
 2519                                     "microcontroller initialization failed");
 2520                                 break;
 2521                         }
 2522                         if (uc->subtype == IWN_UCODE_INIT) {
 2523                                 /* Save microcontroller report. */
 2524                                 memcpy(&sc->ucode_info, uc, sizeof (*uc));
 2525                         }
 2526                         /* Save the address of the error log in SRAM. */
 2527                         sc->errptr = le32toh(uc->errptr);
 2528                         break;
 2529                 }
 2530                 case IWN_STATE_CHANGED:
 2531                 {
 2532                         uint32_t *status = (uint32_t *)(desc + 1);
 2533 
 2534                         /*
 2535                          * State change allows hardware switch change to be
 2536                          * noted. However, we handle this in iwn_intr as we
 2537                          * get both the enable/disble intr.
 2538                          */
 2539                         bus_dmamap_sync(sc->rxq.data_dmat, data->map,
 2540                             BUS_DMASYNC_POSTREAD);
 2541                         DPRINTF(sc, IWN_DEBUG_INTR, "state changed to %x\n",
 2542                             le32toh(*status));
 2543                         break;
 2544                 }
 2545                 case IWN_START_SCAN:
 2546                 {
 2547                         struct iwn_start_scan *scan =
 2548                             (struct iwn_start_scan *)(desc + 1);
 2549 
 2550                         bus_dmamap_sync(sc->rxq.data_dmat, data->map,
 2551                             BUS_DMASYNC_POSTREAD);
 2552                         DPRINTF(sc, IWN_DEBUG_ANY,
 2553                             "%s: scanning channel %d status %x\n",
 2554                             __func__, scan->chan, le32toh(scan->status));
 2555                         break;
 2556                 }
 2557                 case IWN_STOP_SCAN:
 2558                 {
 2559                         struct iwn_stop_scan *scan =
 2560                             (struct iwn_stop_scan *)(desc + 1);
 2561 
 2562                         bus_dmamap_sync(sc->rxq.data_dmat, data->map,
 2563                             BUS_DMASYNC_POSTREAD);
 2564                         DPRINTF(sc, IWN_DEBUG_STATE,
 2565                             "scan finished nchan=%d status=%d chan=%d\n",
 2566                             scan->nchan, scan->status, scan->chan);
 2567 
 2568                         IWN_UNLOCK(sc);
 2569                         ieee80211_scan_next(vap);
 2570                         IWN_LOCK(sc);
 2571                         break;
 2572                 }
 2573                 case IWN5000_CALIBRATION_RESULT:
 2574                         iwn5000_rx_calib_results(sc, desc, data);
 2575                         break;
 2576 
 2577                 case IWN5000_CALIBRATION_DONE:
 2578                         sc->sc_flags |= IWN_FLAG_CALIB_DONE;
 2579                         wakeup(sc);
 2580                         break;
 2581                 }
 2582 
 2583                 sc->rxq.cur = (sc->rxq.cur + 1) % IWN_RX_RING_COUNT;
 2584         }
 2585 
 2586         /* Tell the firmware what we have processed. */
 2587         hw = (hw == 0) ? IWN_RX_RING_COUNT - 1 : hw - 1;
 2588         IWN_WRITE(sc, IWN_FH_RX_WPTR, hw & ~7);
 2589 }
 2590 
 2591 /*
 2592  * Process an INT_WAKEUP interrupt raised when the microcontroller wakes up
 2593  * from power-down sleep mode.
 2594  */
 2595 static void
 2596 iwn_wakeup_intr(struct iwn_softc *sc)
 2597 {
 2598         int qid;
 2599 
 2600         DPRINTF(sc, IWN_DEBUG_RESET, "%s: ucode wakeup from power-down sleep\n",
 2601             __func__);
 2602 
 2603         /* Wakeup RX and TX rings. */
 2604         IWN_WRITE(sc, IWN_FH_RX_WPTR, sc->rxq.cur & ~7);
 2605         for (qid = 0; qid < sc->sc_hal->ntxqs; qid++) {
 2606                 struct iwn_tx_ring *ring = &sc->txq[qid];
 2607                 IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, qid << 8 | ring->cur);
 2608         }
 2609 }
 2610 
 2611 static void
 2612 iwn_rftoggle_intr(struct iwn_softc *sc)
 2613 {
 2614         struct ifnet *ifp = sc->sc_ifp;
 2615         struct ieee80211com *ic = ifp->if_l2com;
 2616         uint32_t tmp = IWN_READ(sc, IWN_GP_CNTRL);
 2617 
 2618         IWN_LOCK_ASSERT(sc);
 2619 
 2620         device_printf(sc->sc_dev, "RF switch: radio %s\n",
 2621             (tmp & IWN_GP_CNTRL_RFKILL) ? "enabled" : "disabled");
 2622         if (tmp & IWN_GP_CNTRL_RFKILL)
 2623                 ieee80211_runtask(ic, &sc->sc_radioon_task);
 2624         else
 2625                 ieee80211_runtask(ic, &sc->sc_radiooff_task);
 2626 }
 2627 
 2628 /*
 2629  * Dump the error log of the firmware when a firmware panic occurs.  Although
 2630  * we can't debug the firmware because it is neither open source nor free, it
 2631  * can help us to identify certain classes of problems.
 2632  */
 2633 static void
 2634 iwn_fatal_intr(struct iwn_softc *sc)
 2635 {
 2636         const struct iwn_hal *hal = sc->sc_hal;
 2637         struct iwn_fw_dump dump;
 2638         int i;
 2639 
 2640         IWN_LOCK_ASSERT(sc);
 2641 
 2642         /* Force a complete recalibration on next init. */
 2643         sc->sc_flags &= ~IWN_FLAG_CALIB_DONE;
 2644 
 2645         /* Check that the error log address is valid. */
 2646         if (sc->errptr < IWN_FW_DATA_BASE ||
 2647             sc->errptr + sizeof (dump) >
 2648             IWN_FW_DATA_BASE + hal->fw_data_maxsz) {
 2649                 printf("%s: bad firmware error log address 0x%08x\n",
 2650                     __func__, sc->errptr);
 2651                 return;
 2652         }
 2653         if (iwn_nic_lock(sc) != 0) {
 2654                 printf("%s: could not read firmware error log\n",
 2655                     __func__);
 2656                 return;
 2657         }
 2658         /* Read firmware error log from SRAM. */
 2659         iwn_mem_read_region_4(sc, sc->errptr, (uint32_t *)&dump,
 2660             sizeof (dump) / sizeof (uint32_t));
 2661         iwn_nic_unlock(sc);
 2662 
 2663         if (dump.valid == 0) {
 2664                 printf("%s: firmware error log is empty\n",
 2665                     __func__);
 2666                 return;
 2667         }
 2668         printf("firmware error log:\n");
 2669         printf("  error type      = \"%s\" (0x%08X)\n",
 2670             (dump.id < nitems(iwn_fw_errmsg)) ?
 2671                 iwn_fw_errmsg[dump.id] : "UNKNOWN",
 2672             dump.id);
 2673         printf("  program counter = 0x%08X\n", dump.pc);
 2674         printf("  source line     = 0x%08X\n", dump.src_line);
 2675         printf("  error data      = 0x%08X%08X\n",
 2676             dump.error_data[0], dump.error_data[1]);
 2677         printf("  branch link     = 0x%08X%08X\n",
 2678             dump.branch_link[0], dump.branch_link[1]);
 2679         printf("  interrupt link  = 0x%08X%08X\n",
 2680             dump.interrupt_link[0], dump.interrupt_link[1]);
 2681         printf("  time            = %u\n", dump.time[0]);
 2682 
 2683         /* Dump driver status (TX and RX rings) while we're here. */
 2684         printf("driver status:\n");
 2685         for (i = 0; i < hal->ntxqs; i++) {
 2686                 struct iwn_tx_ring *ring = &sc->txq[i];
 2687                 printf("  tx ring %2d: qid=%-2d cur=%-3d queued=%-3d\n",
 2688                     i, ring->qid, ring->cur, ring->queued);
 2689         }
 2690         printf("  rx ring: cur=%d\n", sc->rxq.cur);
 2691 }
 2692 
 2693 static void
 2694 iwn_intr(void *arg)
 2695 {
 2696         struct iwn_softc *sc = arg;
 2697         struct ifnet *ifp = sc->sc_ifp;
 2698         uint32_t r1, r2, tmp;
 2699 
 2700         IWN_LOCK(sc);
 2701 
 2702         /* Disable interrupts. */
 2703         IWN_WRITE(sc, IWN_INT_MASK, 0);
 2704 
 2705         /* Read interrupts from ICT (fast) or from registers (slow). */
 2706         if (sc->sc_flags & IWN_FLAG_USE_ICT) {
 2707                 tmp = 0;
 2708                 while (sc->ict[sc->ict_cur] != 0) {
 2709                         tmp |= sc->ict[sc->ict_cur];
 2710                         sc->ict[sc->ict_cur] = 0;       /* Acknowledge. */
 2711                         sc->ict_cur = (sc->ict_cur + 1) % IWN_ICT_COUNT;
 2712                 }
 2713                 tmp = le32toh(tmp);
 2714                 if (tmp == 0xffffffff)  /* Shouldn't happen. */
 2715                         tmp = 0;
 2716                 else if (tmp & 0xc0000) /* Workaround a HW bug. */
 2717                         tmp |= 0x8000;
 2718                 r1 = (tmp & 0xff00) << 16 | (tmp & 0xff);
 2719                 r2 = 0; /* Unused. */
 2720         } else {
 2721                 r1 = IWN_READ(sc, IWN_INT);
 2722                 if (r1 == 0xffffffff || (r1 & 0xfffffff0) == 0xa5a5a5a0)
 2723                         return; /* Hardware gone! */
 2724                 r2 = IWN_READ(sc, IWN_FH_INT);
 2725         }
 2726 
 2727         DPRINTF(sc, IWN_DEBUG_INTR, "interrupt reg1=%x reg2=%x\n", r1, r2);
 2728 
 2729         if (r1 == 0 && r2 == 0)
 2730                 goto done;      /* Interrupt not for us. */
 2731 
 2732         /* Acknowledge interrupts. */
 2733         IWN_WRITE(sc, IWN_INT, r1);
 2734         if (!(sc->sc_flags & IWN_FLAG_USE_ICT))
 2735                 IWN_WRITE(sc, IWN_FH_INT, r2);
 2736 
 2737         if (r1 & IWN_INT_RF_TOGGLED) {
 2738                 iwn_rftoggle_intr(sc);
 2739                 goto done;
 2740         }
 2741         if (r1 & IWN_INT_CT_REACHED) {
 2742                 device_printf(sc->sc_dev, "%s: critical temperature reached!\n",
 2743                     __func__);
 2744         }
 2745         if (r1 & (IWN_INT_SW_ERR | IWN_INT_HW_ERR)) {
 2746                 iwn_fatal_intr(sc);
 2747                 ifp->if_flags &= ~IFF_UP;
 2748                 iwn_stop_locked(sc);
 2749                 goto done;
 2750         }
 2751         if ((r1 & (IWN_INT_FH_RX | IWN_INT_SW_RX | IWN_INT_RX_PERIODIC)) ||
 2752             (r2 & IWN_FH_INT_RX)) {
 2753                 if (sc->sc_flags & IWN_FLAG_USE_ICT) {
 2754                         if (r1 & (IWN_INT_FH_RX | IWN_INT_SW_RX))
 2755                                 IWN_WRITE(sc, IWN_FH_INT, IWN_FH_INT_RX);
 2756                         IWN_WRITE_1(sc, IWN_INT_PERIODIC,
 2757                             IWN_INT_PERIODIC_DIS);
 2758                         iwn_notif_intr(sc);
 2759                         if (r1 & (IWN_INT_FH_RX | IWN_INT_SW_RX)) {
 2760                                 IWN_WRITE_1(sc, IWN_INT_PERIODIC,
 2761                                     IWN_INT_PERIODIC_ENA);
 2762                         }
 2763                 } else
 2764                         iwn_notif_intr(sc);
 2765         }
 2766 
 2767         if ((r1 & IWN_INT_FH_TX) || (r2 & IWN_FH_INT_TX)) {
 2768                 if (sc->sc_flags & IWN_FLAG_USE_ICT)
 2769                         IWN_WRITE(sc, IWN_FH_INT, IWN_FH_INT_TX);
 2770                 wakeup(sc);     /* FH DMA transfer completed. */
 2771         }
 2772 
 2773         if (r1 & IWN_INT_ALIVE)
 2774                 wakeup(sc);     /* Firmware is alive. */
 2775 
 2776         if (r1 & IWN_INT_WAKEUP)
 2777                 iwn_wakeup_intr(sc);
 2778 
 2779 done:
 2780         /* Re-enable interrupts. */
 2781         if (ifp->if_flags & IFF_UP)
 2782                 IWN_WRITE(sc, IWN_INT_MASK, sc->int_mask);
 2783 
 2784         IWN_UNLOCK(sc);
 2785 }
 2786 
 2787 /*
 2788  * Update TX scheduler ring when transmitting an 802.11 frame (4965AGN and
 2789  * 5000 adapters use a slightly different format.)
 2790  */
 2791 static void
 2792 iwn4965_update_sched(struct iwn_softc *sc, int qid, int idx, uint8_t id,
 2793     uint16_t len)
 2794 {
 2795         uint16_t *w = &sc->sched[qid * IWN4965_SCHED_COUNT + idx];
 2796 
 2797         *w = htole16(len + 8);
 2798         bus_dmamap_sync(sc->sched_dma.tag, sc->sched_dma.map,
 2799             BUS_DMASYNC_PREWRITE);
 2800         if (idx < IWN_SCHED_WINSZ) {
 2801                 *(w + IWN_TX_RING_COUNT) = *w;
 2802                 bus_dmamap_sync(sc->sched_dma.tag, sc->sched_dma.map,
 2803                     BUS_DMASYNC_PREWRITE);
 2804         }
 2805 }
 2806 
 2807 static void
 2808 iwn5000_update_sched(struct iwn_softc *sc, int qid, int idx, uint8_t id,
 2809     uint16_t len)
 2810 {
 2811         uint16_t *w = &sc->sched[qid * IWN5000_SCHED_COUNT + idx];
 2812 
 2813         *w = htole16(id << 12 | (len + 8));
 2814 
 2815         bus_dmamap_sync(sc->sched_dma.tag, sc->sched_dma.map,
 2816             BUS_DMASYNC_PREWRITE);
 2817         if (idx < IWN_SCHED_WINSZ) {
 2818                 *(w + IWN_TX_RING_COUNT) = *w;
 2819                 bus_dmamap_sync(sc->sched_dma.tag, sc->sched_dma.map,
 2820                     BUS_DMASYNC_PREWRITE);
 2821         }
 2822 }
 2823 
 2824 #ifdef notyet
 2825 static void
 2826 iwn5000_reset_sched(struct iwn_softc *sc, int qid, int idx)
 2827 {
 2828         uint16_t *w = &sc->sched[qid * IWN5000_SCHED_COUNT + idx];
 2829 
 2830         *w = (*w & htole16(0xf000)) | htole16(1);
 2831         bus_dmamap_sync(sc->sched_dma.tag, sc->sched_dma.map,
 2832             BUS_DMASYNC_PREWRITE);
 2833         if (idx < IWN_SCHED_WINSZ) {
 2834                 *(w + IWN_TX_RING_COUNT) = *w;
 2835                 bus_dmamap_sync(sc->sched_dma.tag, sc->sched_dma.map,
 2836                     BUS_DMASYNC_PREWRITE);
 2837         }
 2838 }
 2839 #endif
 2840 
 2841 static uint8_t
 2842 iwn_plcp_signal(int rate) {
 2843         int i;
 2844 
 2845         for (i = 0; i < IWN_RIDX_MAX + 1; i++) {
 2846                 if (rate == iwn_rates[i].rate)
 2847                         return i;
 2848         }
 2849 
 2850         return 0;
 2851 }
 2852 
 2853 static int
 2854 iwn_tx_data(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni,
 2855     struct iwn_tx_ring *ring)
 2856 {
 2857         const struct iwn_hal *hal = sc->sc_hal;
 2858         const struct ieee80211_txparam *tp;
 2859         const struct iwn_rate *rinfo;
 2860         struct ieee80211vap *vap = ni->ni_vap;
 2861         struct ieee80211com *ic = ni->ni_ic;
 2862         struct iwn_node *wn = (void *)ni;
 2863         struct iwn_tx_desc *desc;
 2864         struct iwn_tx_data *data;
 2865         struct iwn_tx_cmd *cmd;
 2866         struct iwn_cmd_data *tx;
 2867         struct ieee80211_frame *wh;
 2868         struct ieee80211_key *k = NULL;
 2869         struct mbuf *mnew;
 2870         bus_dma_segment_t segs[IWN_MAX_SCATTER];
 2871         uint32_t flags;
 2872         u_int hdrlen;
 2873         int totlen, error, pad, nsegs = 0, i, rate;
 2874         uint8_t ridx, type, txant;
 2875 
 2876         IWN_LOCK_ASSERT(sc);
 2877 
 2878         wh = mtod(m, struct ieee80211_frame *);
 2879         hdrlen = ieee80211_anyhdrsize(wh);
 2880         type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
 2881 
 2882         desc = &ring->desc[ring->cur];
 2883         data = &ring->data[ring->cur];
 2884 
 2885         /* Choose a TX rate index. */
 2886         tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)];
 2887         if (type == IEEE80211_FC0_TYPE_MGT)
 2888                 rate = tp->mgmtrate;
 2889         else if (IEEE80211_IS_MULTICAST(wh->i_addr1))
 2890                 rate = tp->mcastrate;
 2891         else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
 2892                 rate = tp->ucastrate;
 2893         else {
 2894                 /* XXX pass pktlen */
 2895                 (void) ieee80211_ratectl_rate(ni, NULL, 0);
 2896                 rate = ni->ni_txrate;
 2897         }
 2898         ridx = iwn_plcp_signal(rate);
 2899         rinfo = &iwn_rates[ridx];
 2900 
 2901         /* Encrypt the frame if need be. */
 2902         if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
 2903                 k = ieee80211_crypto_encap(ni, m);
 2904                 if (k == NULL) {
 2905                         m_freem(m);
 2906                         return ENOBUFS;
 2907                 }
 2908                 /* Packet header may have moved, reset our local pointer. */
 2909                 wh = mtod(m, struct ieee80211_frame *);
 2910         }
 2911         totlen = m->m_pkthdr.len;
 2912 
 2913         if (ieee80211_radiotap_active_vap(vap)) {
 2914                 struct iwn_tx_radiotap_header *tap = &sc->sc_txtap;
 2915 
 2916                 tap->wt_flags = 0;
 2917                 tap->wt_rate = rinfo->rate;
 2918                 if (k != NULL)
 2919                         tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP;
 2920 
 2921                 ieee80211_radiotap_tx(vap, m);
 2922         }
 2923 
 2924         /* Prepare TX firmware command. */
 2925         cmd = &ring->cmd[ring->cur];
 2926         cmd->code = IWN_CMD_TX_DATA;
 2927         cmd->flags = 0;
 2928         cmd->qid = ring->qid;
 2929         cmd->idx = ring->cur;
 2930 
 2931         tx = (struct iwn_cmd_data *)cmd->data;
 2932         /* NB: No need to clear tx, all fields are reinitialized here. */
 2933         tx->scratch = 0;        /* clear "scratch" area */
 2934 
 2935         flags = 0;
 2936         if (!IEEE80211_IS_MULTICAST(wh->i_addr1))
 2937                 flags |= IWN_TX_NEED_ACK;
 2938         if ((wh->i_fc[0] &
 2939             (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==
 2940             (IEEE80211_FC0_TYPE_CTL | IEEE80211_FC0_SUBTYPE_BAR))
 2941                 flags |= IWN_TX_IMM_BA;         /* Cannot happen yet. */
 2942 
 2943         if (wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG)
 2944                 flags |= IWN_TX_MORE_FRAG;      /* Cannot happen yet. */
 2945 
 2946         /* Check if frame must be protected using RTS/CTS or CTS-to-self. */
 2947         if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
 2948                 /* NB: Group frames are sent using CCK in 802.11b/g. */
 2949                 if (totlen + IEEE80211_CRC_LEN > vap->iv_rtsthreshold) {
 2950                         flags |= IWN_TX_NEED_RTS;
 2951                 } else if ((ic->ic_flags & IEEE80211_F_USEPROT) &&
 2952                     ridx >= IWN_RIDX_OFDM6) {
 2953                         if (ic->ic_protmode == IEEE80211_PROT_CTSONLY)
 2954                                 flags |= IWN_TX_NEED_CTS;
 2955                         else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
 2956                                 flags |= IWN_TX_NEED_RTS;
 2957                 }
 2958                 if (flags & (IWN_TX_NEED_RTS | IWN_TX_NEED_CTS)) {
 2959                         if (sc->hw_type != IWN_HW_REV_TYPE_4965) {
 2960                                 /* 5000 autoselects RTS/CTS or CTS-to-self. */
 2961                                 flags &= ~(IWN_TX_NEED_RTS | IWN_TX_NEED_CTS);
 2962                                 flags |= IWN_TX_NEED_PROTECTION;
 2963                         } else
 2964                                 flags |= IWN_TX_FULL_TXOP;
 2965                 }
 2966         }
 2967 
 2968         if (IEEE80211_IS_MULTICAST(wh->i_addr1) ||
 2969             type != IEEE80211_FC0_TYPE_DATA)
 2970                 tx->id = hal->broadcast_id;
 2971         else
 2972                 tx->id = wn->id;
 2973 
 2974         if (type == IEEE80211_FC0_TYPE_MGT) {
 2975                 uint8_t subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
 2976 
 2977                 /* Tell HW to set timestamp in probe responses. */
 2978                 if (subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP)
 2979                         flags |= IWN_TX_INSERT_TSTAMP;
 2980 
 2981                 if (subtype == IEEE80211_FC0_SUBTYPE_ASSOC_REQ ||
 2982                     subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ)
 2983                         tx->timeout = htole16(3);
 2984                 else
 2985                         tx->timeout = htole16(2);
 2986         } else
 2987                 tx->timeout = htole16(0);
 2988 
 2989         if (hdrlen & 3) {
 2990                 /* First segment length must be a multiple of 4. */
 2991                 flags |= IWN_TX_NEED_PADDING;
 2992                 pad = 4 - (hdrlen & 3);
 2993         } else
 2994                 pad = 0;
 2995 
 2996         tx->len = htole16(totlen);
 2997         tx->tid = 0;
 2998         tx->rts_ntries = 60;
 2999         tx->data_ntries = 15;
 3000         tx->lifetime = htole32(IWN_LIFETIME_INFINITE);
 3001         tx->plcp = rinfo->plcp;
 3002         tx->rflags = rinfo->flags;
 3003         if (tx->id == hal->broadcast_id) {
 3004                 /* Group or management frame. */
 3005                 tx->linkq = 0;
 3006                 /* XXX Alternate between antenna A and B? */
 3007                 txant = IWN_LSB(sc->txchainmask);
 3008                 tx->rflags |= IWN_RFLAG_ANT(txant);
 3009         } else {
 3010                 tx->linkq = 0;
 3011                 flags |= IWN_TX_LINKQ;  /* enable MRR */
 3012         }
 3013 
 3014         /* Set physical address of "scratch area". */
 3015         tx->loaddr = htole32(IWN_LOADDR(data->scratch_paddr));
 3016         tx->hiaddr = IWN_HIADDR(data->scratch_paddr);
 3017 
 3018         /* Copy 802.11 header in TX command. */
 3019         memcpy((uint8_t *)(tx + 1), wh, hdrlen);
 3020 
 3021         /* Trim 802.11 header. */
 3022         m_adj(m, hdrlen);
 3023         tx->security = 0;
 3024         tx->flags = htole32(flags);
 3025 
 3026         if (m->m_len > 0) {
 3027                 error = bus_dmamap_load_mbuf_sg(ring->data_dmat, data->map,
 3028                     m, segs, &nsegs, BUS_DMA_NOWAIT);
 3029                 if (error == EFBIG) {
 3030                         /* too many fragments, linearize */
 3031                         mnew = m_collapse(m, M_DONTWAIT, IWN_MAX_SCATTER);
 3032                         if (mnew == NULL) {
 3033                                 device_printf(sc->sc_dev,
 3034                                     "%s: could not defrag mbuf\n", __func__);
 3035                                 m_freem(m);
 3036                                 return ENOBUFS;
 3037                         }
 3038                         m = mnew;
 3039                         error = bus_dmamap_load_mbuf_sg(ring->data_dmat,
 3040                             data->map, m, segs, &nsegs, BUS_DMA_NOWAIT);
 3041                 }
 3042                 if (error != 0) {
 3043                         device_printf(sc->sc_dev,
 3044                             "%s: bus_dmamap_load_mbuf_sg failed, error %d\n",
 3045                             __func__, error);
 3046                         m_freem(m);
 3047                         return error;
 3048                 }
 3049         }
 3050 
 3051         data->m = m;
 3052         data->ni = ni;
 3053 
 3054         DPRINTF(sc, IWN_DEBUG_XMIT, "%s: qid %d idx %d len %d nsegs %d\n",
 3055             __func__, ring->qid, ring->cur, m->m_pkthdr.len, nsegs);
 3056 
 3057         /* Fill TX descriptor. */
 3058         desc->nsegs = 1 + nsegs;
 3059         /* First DMA segment is used by the TX command. */
 3060         desc->segs[0].addr = htole32(IWN_LOADDR(data->cmd_paddr));
 3061         desc->segs[0].len  = htole16(IWN_HIADDR(data->cmd_paddr) |
 3062             (4 + sizeof (*tx) + hdrlen + pad) << 4);
 3063         /* Other DMA segments are for data payload. */
 3064         for (i = 1; i <= nsegs; i++) {
 3065                 desc->segs[i].addr = htole32(IWN_LOADDR(segs[i - 1].ds_addr));
 3066                 desc->segs[i].len  = htole16(IWN_HIADDR(segs[i - 1].ds_addr) |
 3067                     segs[i - 1].ds_len << 4);
 3068         }
 3069 
 3070         bus_dmamap_sync(ring->data_dmat, data->map, BUS_DMASYNC_PREWRITE);
 3071         bus_dmamap_sync(ring->data_dmat, ring->cmd_dma.map,
 3072             BUS_DMASYNC_PREWRITE);
 3073         bus_dmamap_sync(ring->desc_dma.tag, ring->desc_dma.map,
 3074             BUS_DMASYNC_PREWRITE);
 3075 
 3076 #ifdef notyet
 3077         /* Update TX scheduler. */
 3078         hal->update_sched(sc, ring->qid, ring->cur, tx->id, totlen);
 3079 #endif
 3080 
 3081         /* Kick TX ring. */
 3082         ring->cur = (ring->cur + 1) % IWN_TX_RING_COUNT;
 3083         IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, ring->qid << 8 | ring->cur);
 3084 
 3085         /* Mark TX ring as full if we reach a certain threshold. */
 3086         if (++ring->queued > IWN_TX_RING_HIMARK)
 3087                 sc->qfullmsk |= 1 << ring->qid;
 3088 
 3089         return 0;
 3090 }
 3091 
 3092 static int
 3093 iwn_tx_data_raw(struct iwn_softc *sc, struct mbuf *m,
 3094     struct ieee80211_node *ni, struct iwn_tx_ring *ring,
 3095     const struct ieee80211_bpf_params *params)
 3096 {
 3097         const struct iwn_hal *hal = sc->sc_hal;
 3098         const struct iwn_rate *rinfo;
 3099         struct ifnet *ifp = sc->sc_ifp;
 3100         struct ieee80211vap *vap = ni->ni_vap;
 3101         struct ieee80211com *ic = ifp->if_l2com;
 3102         struct iwn_tx_cmd *cmd;
 3103         struct iwn_cmd_data *tx;
 3104         struct ieee80211_frame *wh;
 3105         struct iwn_tx_desc *desc;
 3106         struct iwn_tx_data *data;
 3107         struct mbuf *mnew;
 3108         bus_addr_t paddr;
 3109         bus_dma_segment_t segs[IWN_MAX_SCATTER];
 3110         uint32_t flags;
 3111         u_int hdrlen;
 3112         int totlen, error, pad, nsegs = 0, i, rate;
 3113         uint8_t ridx, type, txant;
 3114 
 3115         IWN_LOCK_ASSERT(sc);
 3116 
 3117         wh = mtod(m, struct ieee80211_frame *);
 3118         hdrlen = ieee80211_anyhdrsize(wh);
 3119         type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
 3120 
 3121         desc = &ring->desc[ring->cur];
 3122         data = &ring->data[ring->cur];
 3123 
 3124         /* Choose a TX rate index. */
 3125         rate = params->ibp_rate0;
 3126         if (!ieee80211_isratevalid(ic->ic_rt, rate)) {
 3127                 /* XXX fall back to mcast/mgmt rate? */
 3128                 m_freem(m);
 3129                 return EINVAL;
 3130         }
 3131         ridx = iwn_plcp_signal(rate);
 3132         rinfo = &iwn_rates[ridx];
 3133 
 3134         totlen = m->m_pkthdr.len;
 3135 
 3136         /* Prepare TX firmware command. */
 3137         cmd = &ring->cmd[ring->cur];
 3138         cmd->code = IWN_CMD_TX_DATA;
 3139         cmd->flags = 0;
 3140         cmd->qid = ring->qid;
 3141         cmd->idx = ring->cur;
 3142 
 3143         tx = (struct iwn_cmd_data *)cmd->data;
 3144         /* NB: No need to clear tx, all fields are reinitialized here. */
 3145         tx->scratch = 0;        /* clear "scratch" area */
 3146 
 3147         flags = 0;
 3148         if ((params->ibp_flags & IEEE80211_BPF_NOACK) == 0)
 3149                 flags |= IWN_TX_NEED_ACK;
 3150         if (params->ibp_flags & IEEE80211_BPF_RTS) {
 3151                 if (sc->hw_type != IWN_HW_REV_TYPE_4965) {
 3152                         /* 5000 autoselects RTS/CTS or CTS-to-self. */
 3153                         flags &= ~IWN_TX_NEED_RTS;
 3154                         flags |= IWN_TX_NEED_PROTECTION;
 3155                 } else
 3156                         flags |= IWN_TX_NEED_RTS | IWN_TX_FULL_TXOP;
 3157         }
 3158         if (params->ibp_flags & IEEE80211_BPF_CTS) {
 3159                 if (sc->hw_type != IWN_HW_REV_TYPE_4965) {
 3160                         /* 5000 autoselects RTS/CTS or CTS-to-self. */
 3161                         flags &= ~IWN_TX_NEED_CTS;
 3162                         flags |= IWN_TX_NEED_PROTECTION;
 3163                 } else
 3164                         flags |= IWN_TX_NEED_CTS | IWN_TX_FULL_TXOP;
 3165         }
 3166         if (type == IEEE80211_FC0_TYPE_MGT) {
 3167                 uint8_t subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
 3168 
 3169                 if (subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP)
 3170                         flags |= IWN_TX_INSERT_TSTAMP;
 3171 
 3172                 if (subtype == IEEE80211_FC0_SUBTYPE_ASSOC_REQ ||
 3173                     subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ)
 3174                         tx->timeout = htole16(3);
 3175                 else
 3176                         tx->timeout = htole16(2);
 3177         } else
 3178                 tx->timeout = htole16(0);
 3179 
 3180         if (hdrlen & 3) {
 3181                 /* First segment length must be a multiple of 4. */
 3182                 flags |= IWN_TX_NEED_PADDING;
 3183                 pad = 4 - (hdrlen & 3);
 3184         } else
 3185                 pad = 0;
 3186 
 3187         if (ieee80211_radiotap_active_vap(vap)) {
 3188                 struct iwn_tx_radiotap_header *tap = &sc->sc_txtap;
 3189 
 3190                 tap->wt_flags = 0;
 3191                 tap->wt_rate = rate;
 3192 
 3193                 ieee80211_radiotap_tx(vap, m);
 3194         }
 3195 
 3196         tx->len = htole16(totlen);
 3197         tx->tid = 0;
 3198         tx->id = hal->broadcast_id;
 3199         tx->rts_ntries = params->ibp_try1;
 3200         tx->data_ntries = params->ibp_try0;
 3201         tx->lifetime = htole32(IWN_LIFETIME_INFINITE);
 3202         tx->plcp = rinfo->plcp;
 3203         tx->rflags = rinfo->flags;
 3204         /* Group or management frame. */
 3205         tx->linkq = 0;
 3206         txant = IWN_LSB(sc->txchainmask);
 3207         tx->rflags |= IWN_RFLAG_ANT(txant);
 3208         /* Set physical address of "scratch area". */
 3209         paddr = ring->cmd_dma.paddr + ring->cur * sizeof (struct iwn_tx_cmd);
 3210         tx->loaddr = htole32(IWN_LOADDR(paddr));
 3211         tx->hiaddr = IWN_HIADDR(paddr);
 3212 
 3213         /* Copy 802.11 header in TX command. */
 3214         memcpy((uint8_t *)(tx + 1), wh, hdrlen);
 3215 
 3216         /* Trim 802.11 header. */
 3217         m_adj(m, hdrlen);
 3218         tx->security = 0;
 3219         tx->flags = htole32(flags);
 3220 
 3221         if (m->m_len > 0) {
 3222                 error = bus_dmamap_load_mbuf_sg(ring->data_dmat, data->map,
 3223                     m, segs, &nsegs, BUS_DMA_NOWAIT);
 3224                 if (error == EFBIG) {
 3225                         /* Too many fragments, linearize. */
 3226                         mnew = m_collapse(m, M_DONTWAIT, IWN_MAX_SCATTER);
 3227                         if (mnew == NULL) {
 3228                                 device_printf(sc->sc_dev,
 3229                                     "%s: could not defrag mbuf\n", __func__);
 3230                                 m_freem(m);
 3231                                 return ENOBUFS;
 3232                         }
 3233                         m = mnew;
 3234                         error = bus_dmamap_load_mbuf_sg(ring->data_dmat,
 3235                             data->map, m, segs, &nsegs, BUS_DMA_NOWAIT);
 3236                 }
 3237                 if (error != 0) {
 3238                         device_printf(sc->sc_dev,
 3239                             "%s: bus_dmamap_load_mbuf_sg failed, error %d\n",
 3240                             __func__, error);
 3241                         m_freem(m);
 3242                         return error;
 3243                 }
 3244         }
 3245 
 3246         data->m = m;
 3247         data->ni = ni;
 3248 
 3249         DPRINTF(sc, IWN_DEBUG_XMIT, "%s: qid %d idx %d len %d nsegs %d\n",
 3250             __func__, ring->qid, ring->cur, m->m_pkthdr.len, nsegs);
 3251 
 3252         /* Fill TX descriptor. */
 3253         desc->nsegs = 1 + nsegs;
 3254         /* First DMA segment is used by the TX command. */
 3255         desc->segs[0].addr = htole32(IWN_LOADDR(data->cmd_paddr));
 3256         desc->segs[0].len  = htole16(IWN_HIADDR(data->cmd_paddr) |
 3257             (4 + sizeof (*tx) + hdrlen + pad) << 4);
 3258         /* Other DMA segments are for data payload. */
 3259         for (i = 1; i <= nsegs; i++) {
 3260                 desc->segs[i].addr = htole32(IWN_LOADDR(segs[i - 1].ds_addr));
 3261                 desc->segs[i].len  = htole16(IWN_HIADDR(segs[i - 1].ds_addr) |
 3262                     segs[i - 1].ds_len << 4);
 3263         }
 3264 
 3265         bus_dmamap_sync(ring->data_dmat, data->map, BUS_DMASYNC_PREWRITE);
 3266         bus_dmamap_sync(ring->data_dmat, ring->cmd_dma.map,
 3267             BUS_DMASYNC_PREWRITE);
 3268         bus_dmamap_sync(ring->desc_dma.tag, ring->desc_dma.map,
 3269             BUS_DMASYNC_PREWRITE);
 3270 
 3271 #ifdef notyet
 3272         /* Update TX scheduler. */
 3273         hal->update_sched(sc, ring->qid, ring->cur, tx->id, totlen);
 3274 #endif
 3275 
 3276         /* Kick TX ring. */
 3277         ring->cur = (ring->cur + 1) % IWN_TX_RING_COUNT;
 3278         IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, ring->qid << 8 | ring->cur);
 3279 
 3280         /* Mark TX ring as full if we reach a certain threshold. */
 3281         if (++ring->queued > IWN_TX_RING_HIMARK)
 3282                 sc->qfullmsk |= 1 << ring->qid;
 3283 
 3284         return 0;
 3285 }
 3286 
 3287 static int
 3288 iwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
 3289         const struct ieee80211_bpf_params *params)
 3290 {
 3291         struct ieee80211com *ic = ni->ni_ic;
 3292         struct ifnet *ifp = ic->ic_ifp;
 3293         struct iwn_softc *sc = ifp->if_softc;
 3294         struct iwn_tx_ring *txq;
 3295         int error = 0;
 3296 
 3297         if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
 3298                 ieee80211_free_node(ni);
 3299                 m_freem(m);
 3300                 return ENETDOWN;
 3301         }
 3302 
 3303         IWN_LOCK(sc);
 3304         if (params == NULL)
 3305                 txq = &sc->txq[M_WME_GETAC(m)];
 3306         else
 3307                 txq = &sc->txq[params->ibp_pri & 3];
 3308 
 3309         if (params == NULL) {
 3310                 /*
 3311                  * Legacy path; interpret frame contents to decide
 3312                  * precisely how to send the frame.
 3313                  */
 3314                 error = iwn_tx_data(sc, m, ni, txq);
 3315         } else {
 3316                 /*
 3317                  * Caller supplied explicit parameters to use in
 3318                  * sending the frame.
 3319                  */
 3320                 error = iwn_tx_data_raw(sc, m, ni, txq, params);
 3321         }
 3322         if (error != 0) {
 3323                 /* NB: m is reclaimed on tx failure */
 3324                 ieee80211_free_node(ni);
 3325                 ifp->if_oerrors++;
 3326         }
 3327         IWN_UNLOCK(sc);
 3328         return error;
 3329 }
 3330 
 3331 static void
 3332 iwn_start(struct ifnet *ifp)
 3333 {
 3334         struct iwn_softc *sc = ifp->if_softc;
 3335 
 3336         IWN_LOCK(sc);
 3337         iwn_start_locked(ifp);
 3338         IWN_UNLOCK(sc);
 3339 }
 3340 
 3341 static void
 3342 iwn_start_locked(struct ifnet *ifp)
 3343 {
 3344         struct iwn_softc *sc = ifp->if_softc;
 3345         struct ieee80211_node *ni;
 3346         struct iwn_tx_ring *txq;
 3347         struct mbuf *m;
 3348         int pri;
 3349 
 3350         IWN_LOCK_ASSERT(sc);
 3351 
 3352         for (;;) {
 3353                 if (sc->qfullmsk != 0) {
 3354                         ifp->if_drv_flags |= IFF_DRV_OACTIVE;
 3355                         break;
 3356                 }
 3357                 IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
 3358                 if (m == NULL)
 3359                         break;
 3360                 ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
 3361                 pri = M_WME_GETAC(m);
 3362                 txq = &sc->txq[pri];
 3363                 if (iwn_tx_data(sc, m, ni, txq) != 0) {
 3364                         ifp->if_oerrors++;
 3365                         ieee80211_free_node(ni);
 3366                         break;
 3367                 }
 3368                 sc->sc_tx_timer = 5;
 3369         }
 3370 }
 3371 
 3372 static void
 3373 iwn_watchdog(struct iwn_softc *sc)
 3374 {
 3375         if (sc->sc_tx_timer > 0 && --sc->sc_tx_timer == 0) {
 3376                 struct ifnet *ifp = sc->sc_ifp;
 3377                 struct ieee80211com *ic = ifp->if_l2com;
 3378 
 3379                 if_printf(ifp, "device timeout\n");
 3380                 ieee80211_runtask(ic, &sc->sc_reinit_task);
 3381         }
 3382 }
 3383 
 3384 static int
 3385 iwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
 3386 {
 3387         struct iwn_softc *sc = ifp->if_softc;
 3388         struct ieee80211com *ic = ifp->if_l2com;
 3389         struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
 3390         struct ifreq *ifr = (struct ifreq *) data;
 3391         int error = 0, startall = 0, stop = 0;
 3392 
 3393         switch (cmd) {
 3394         case SIOCSIFFLAGS:
 3395                 IWN_LOCK(sc);
 3396                 if (ifp->if_flags & IFF_UP) {
 3397                         if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
 3398                                 iwn_init_locked(sc);
 3399                                 if (IWN_READ(sc, IWN_GP_CNTRL) & IWN_GP_CNTRL_RFKILL)
 3400                                         startall = 1;
 3401                                 else
 3402                                         stop = 1;
 3403                         }
 3404                 } else {
 3405                         if (ifp->if_drv_flags & IFF_DRV_RUNNING)
 3406                                 iwn_stop_locked(sc);
 3407                 }
 3408                 IWN_UNLOCK(sc);
 3409                 if (startall)
 3410                         ieee80211_start_all(ic);
 3411                 else if (vap != NULL && stop)
 3412                         ieee80211_stop(vap);
 3413                 break;
 3414         case SIOCGIFMEDIA:
 3415                 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
 3416                 break;
 3417         case SIOCGIFADDR:
 3418                 error = ether_ioctl(ifp, cmd, data);
 3419                 break;
 3420         default:
 3421                 error = EINVAL;
 3422                 break;
 3423         }
 3424         return error;
 3425 }
 3426 
 3427 /*
 3428  * Send a command to the firmware.
 3429  */
 3430 static int
 3431 iwn_cmd(struct iwn_softc *sc, int code, const void *buf, int size, int async)
 3432 {
 3433         struct iwn_tx_ring *ring = &sc->txq[4];
 3434         struct iwn_tx_desc *desc;
 3435         struct iwn_tx_data *data;
 3436         struct iwn_tx_cmd *cmd;
 3437         struct mbuf *m;
 3438         bus_addr_t paddr;
 3439         int totlen, error;
 3440 
 3441         IWN_LOCK_ASSERT(sc);
 3442 
 3443         desc = &ring->desc[ring->cur];
 3444         data = &ring->data[ring->cur];
 3445         totlen = 4 + size;
 3446 
 3447         if (size > sizeof cmd->data) {
 3448                 /* Command is too large to fit in a descriptor. */
 3449                 if (totlen > MCLBYTES)
 3450                         return EINVAL;
 3451                 m = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, MJUMPAGESIZE);
 3452                 if (m == NULL)
 3453                         return ENOMEM;
 3454                 cmd = mtod(m, struct iwn_tx_cmd *);
 3455                 error = bus_dmamap_load(ring->data_dmat, data->map, cmd,
 3456                     totlen, iwn_dma_map_addr, &paddr, BUS_DMA_NOWAIT);
 3457                 if (error != 0) {
 3458                         m_freem(m);
 3459                         return error;
 3460                 }
 3461                 data->m = m;
 3462         } else {
 3463                 cmd = &ring->cmd[ring->cur];
 3464                 paddr = data->cmd_paddr;
 3465         }
 3466 
 3467         cmd->code = code;
 3468         cmd->flags = 0;
 3469         cmd->qid = ring->qid;
 3470         cmd->idx = ring->cur;
 3471         memcpy(cmd->data, buf, size);
 3472 
 3473         desc->nsegs = 1;
 3474         desc->segs[0].addr = htole32(IWN_LOADDR(paddr));
 3475         desc->segs[0].len  = htole16(IWN_HIADDR(paddr) | totlen << 4);
 3476 
 3477         DPRINTF(sc, IWN_DEBUG_CMD, "%s: %s (0x%x) flags %d qid %d idx %d\n",
 3478             __func__, iwn_intr_str(cmd->code), cmd->code,
 3479             cmd->flags, cmd->qid, cmd->idx);
 3480 
 3481         if (size > sizeof cmd->data) {
 3482                 bus_dmamap_sync(ring->data_dmat, data->map,
 3483                     BUS_DMASYNC_PREWRITE);
 3484         } else {
 3485                 bus_dmamap_sync(ring->data_dmat, ring->cmd_dma.map,
 3486                     BUS_DMASYNC_PREWRITE);
 3487         }
 3488         bus_dmamap_sync(ring->desc_dma.tag, ring->desc_dma.map,
 3489             BUS_DMASYNC_PREWRITE);
 3490 
 3491 #ifdef notyet
 3492         /* Update TX scheduler. */
 3493         sc->sc_hal->update_sched(sc, ring->qid, ring->cur, 0, 0);
 3494 #endif
 3495 
 3496         /* Kick command ring. */
 3497         ring->cur = (ring->cur + 1) % IWN_TX_RING_COUNT;
 3498         IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, ring->qid << 8 | ring->cur);
 3499 
 3500         return async ? 0 : msleep(desc, &sc->sc_mtx, PCATCH, "iwncmd", hz);
 3501 }
 3502 
 3503 static int
 3504 iwn4965_add_node(struct iwn_softc *sc, struct iwn_node_info *node, int async)
 3505 {
 3506         struct iwn4965_node_info hnode;
 3507         caddr_t src, dst;
 3508 
 3509         /*
 3510          * We use the node structure for 5000 Series internally (it is
 3511          * a superset of the one for 4965AGN). We thus copy the common
 3512          * fields before sending the command.
 3513          */
 3514         src = (caddr_t)node;
 3515         dst = (caddr_t)&hnode;
 3516         memcpy(dst, src, 48);
 3517         /* Skip TSC, RX MIC and TX MIC fields from ``src''. */
 3518         memcpy(dst + 48, src + 72, 20);
 3519         return iwn_cmd(sc, IWN_CMD_ADD_NODE, &hnode, sizeof hnode, async);
 3520 }
 3521 
 3522 static int
 3523 iwn5000_add_node(struct iwn_softc *sc, struct iwn_node_info *node, int async)
 3524 {
 3525         /* Direct mapping. */
 3526         return iwn_cmd(sc, IWN_CMD_ADD_NODE, node, sizeof (*node), async);
 3527 }
 3528 
 3529 #if 0   /* HT */
 3530 static const uint8_t iwn_ridx_to_plcp[] = {
 3531         10, 20, 55, 110, /* CCK */
 3532         0xd, 0xf, 0x5, 0x7, 0x9, 0xb, 0x1, 0x3, 0x3 /* OFDM R1-R4 */
 3533 };
 3534 static const uint8_t iwn_siso_mcs_to_plcp[] = {
 3535         0, 0, 0, 0,                     /* CCK */
 3536         0, 0, 1, 2, 3, 4, 5, 6, 7       /* HT */
 3537 };
 3538 static const uint8_t iwn_mimo_mcs_to_plcp[] = {
 3539         0, 0, 0, 0,                     /* CCK */
 3540         8, 8, 9, 10, 11, 12, 13, 14, 15 /* HT */
 3541 };
 3542 #endif
 3543 static const uint8_t iwn_prev_ridx[] = {
 3544         /* NB: allow fallback from CCK11 to OFDM9 and from OFDM6 to CCK5 */
 3545         0, 0, 1, 5,                     /* CCK */
 3546         2, 4, 3, 6, 7, 8, 9, 10, 10     /* OFDM */
 3547 };
 3548 
 3549 /*
 3550  * Configure hardware link parameters for the specified
 3551  * node operating on the specified channel.
 3552  */
 3553 static int
 3554 iwn_set_link_quality(struct iwn_softc *sc, uint8_t id, int async)
 3555 {
 3556         struct ifnet *ifp = sc->sc_ifp;
 3557         struct ieee80211com *ic = ifp->if_l2com;
 3558         struct iwn_cmd_link_quality linkq;
 3559         const struct iwn_rate *rinfo;
 3560         int i;
 3561         uint8_t txant, ridx;
 3562 
 3563         /* Use the first valid TX antenna. */
 3564         txant = IWN_LSB(sc->txchainmask);
 3565 
 3566         memset(&linkq, 0, sizeof linkq);
 3567         linkq.id = id;
 3568         linkq.antmsk_1stream = txant;
 3569         linkq.antmsk_2stream = IWN_ANT_AB;
 3570         linkq.ampdu_max = 31;
 3571         linkq.ampdu_threshold = 3;
 3572         linkq.ampdu_limit = htole16(4000);      /* 4ms */
 3573 
 3574 #if 0   /* HT */
 3575         if (IEEE80211_IS_CHAN_HT(c))
 3576                 linkq.mimo = 1;
 3577 #endif
 3578 
 3579         if (id == IWN_ID_BSS)
 3580                 ridx = IWN_RIDX_OFDM54;
 3581         else if (IEEE80211_IS_CHAN_A(ic->ic_curchan))
 3582                 ridx = IWN_RIDX_OFDM6;
 3583         else
 3584                 ridx = IWN_RIDX_CCK1;
 3585 
 3586         for (i = 0; i < IWN_MAX_TX_RETRIES; i++) {
 3587                 rinfo = &iwn_rates[ridx];
 3588 #if 0   /* HT */
 3589                 if (IEEE80211_IS_CHAN_HT40(c)) {
 3590                         linkq.retry[i].plcp = iwn_mimo_mcs_to_plcp[ridx]
 3591                                          | IWN_RIDX_MCS;
 3592                         linkq.retry[i].rflags = IWN_RFLAG_HT
 3593                                          | IWN_RFLAG_HT40;
 3594                         /* XXX shortGI */
 3595                 } else if (IEEE80211_IS_CHAN_HT(c)) {
 3596                         linkq.retry[i].plcp = iwn_siso_mcs_to_plcp[ridx]
 3597                                          | IWN_RIDX_MCS;
 3598                         linkq.retry[i].rflags = IWN_RFLAG_HT;
 3599                         /* XXX shortGI */
 3600                 } else
 3601 #endif
 3602                 {
 3603                         linkq.retry[i].plcp = rinfo->plcp;
 3604                         linkq.retry[i].rflags = rinfo->flags;
 3605                 }
 3606                 linkq.retry[i].rflags |= IWN_RFLAG_ANT(txant);
 3607                 ridx = iwn_prev_ridx[ridx];
 3608         }
 3609 #ifdef IWN_DEBUG
 3610         if (sc->sc_debug & IWN_DEBUG_STATE) {
 3611                 printf("%s: set link quality for node %d, mimo %d ssmask %d\n",
 3612                     __func__, id, linkq.mimo, linkq.antmsk_1stream);
 3613                 printf("%s:", __func__);
 3614                 for (i = 0; i < IWN_MAX_TX_RETRIES; i++)
 3615                         printf(" %d:%x", linkq.retry[i].plcp,
 3616                             linkq.retry[i].rflags);
 3617                 printf("\n");
 3618         }
 3619 #endif
 3620         return iwn_cmd(sc, IWN_CMD_LINK_QUALITY, &linkq, sizeof linkq, async);
 3621 }
 3622 
 3623 /*
 3624  * Broadcast node is used to send group-addressed and management frames.
 3625  */
 3626 static int
 3627 iwn_add_broadcast_node(struct iwn_softc *sc, int async)
 3628 {
 3629         const struct iwn_hal *hal = sc->sc_hal;
 3630         struct ifnet *ifp = sc->sc_ifp;
 3631         struct iwn_node_info node;
 3632         int error;
 3633 
 3634         memset(&node, 0, sizeof node);
 3635         IEEE80211_ADDR_COPY(node.macaddr, ifp->if_broadcastaddr);
 3636         node.id = hal->broadcast_id;
 3637         DPRINTF(sc, IWN_DEBUG_RESET, "%s: adding broadcast node\n", __func__);
 3638         error = hal->add_node(sc, &node, async);
 3639         if (error != 0)
 3640                 return error;
 3641 
 3642         error = iwn_set_link_quality(sc, hal->broadcast_id, async);
 3643         return error;
 3644 }
 3645 
 3646 static int
 3647 iwn_wme_update(struct ieee80211com *ic)
 3648 {
 3649 #define IWN_EXP2(x)     ((1 << (x)) - 1)        /* CWmin = 2^ECWmin - 1 */
 3650 #define IWN_TXOP_TO_US(v)               (v<<5)
 3651         struct iwn_softc *sc = ic->ic_ifp->if_softc;
 3652         struct iwn_edca_params cmd;
 3653         int i;
 3654 
 3655         memset(&cmd, 0, sizeof cmd);
 3656         cmd.flags = htole32(IWN_EDCA_UPDATE);
 3657         for (i = 0; i < WME_NUM_AC; i++) {
 3658                 const struct wmeParams *wmep =
 3659                     &ic->ic_wme.wme_chanParams.cap_wmeParams[i];
 3660                 cmd.ac[i].aifsn = wmep->wmep_aifsn;
 3661                 cmd.ac[i].cwmin = htole16(IWN_EXP2(wmep->wmep_logcwmin));
 3662                 cmd.ac[i].cwmax = htole16(IWN_EXP2(wmep->wmep_logcwmax));
 3663                 cmd.ac[i].txoplimit =
 3664                     htole16(IWN_TXOP_TO_US(wmep->wmep_txopLimit));
 3665         }
 3666         IEEE80211_UNLOCK(ic);
 3667         IWN_LOCK(sc);
 3668         (void) iwn_cmd(sc, IWN_CMD_EDCA_PARAMS, &cmd, sizeof cmd, 1 /*async*/);
 3669         IWN_UNLOCK(sc);
 3670         IEEE80211_LOCK(ic);
 3671         return 0;
 3672 #undef IWN_TXOP_TO_US
 3673 #undef IWN_EXP2
 3674 }
 3675 
 3676 static void
 3677 iwn_update_mcast(struct ifnet *ifp)
 3678 {
 3679         /* Ignore */
 3680 }
 3681 
 3682 static void
 3683 iwn_set_led(struct iwn_softc *sc, uint8_t which, uint8_t off, uint8_t on)
 3684 {
 3685         struct iwn_cmd_led led;
 3686 
 3687         /* Clear microcode LED ownership. */
 3688         IWN_CLRBITS(sc, IWN_LED, IWN_LED_BSM_CTRL);
 3689 
 3690         led.which = which;
 3691         led.unit = htole32(10000);      /* on/off in unit of 100ms */
 3692         led.off = off;
 3693         led.on = on;
 3694         (void)iwn_cmd(sc, IWN_CMD_SET_LED, &led, sizeof led, 1);
 3695 }
 3696 
 3697 /*
 3698  * Set the critical temperature at which the firmware will stop the radio
 3699  * and notify us.
 3700  */
 3701 static int
 3702 iwn_set_critical_temp(struct iwn_softc *sc)
 3703 {
 3704         struct iwn_critical_temp crit;
 3705         int32_t temp;
 3706 
 3707         IWN_WRITE(sc, IWN_UCODE_GP1_CLR, IWN_UCODE_GP1_CTEMP_STOP_RF);
 3708 
 3709         if (sc->hw_type == IWN_HW_REV_TYPE_5150)
 3710                 temp = (IWN_CTOK(110) - sc->temp_off) * -5;
 3711         else if (sc->hw_type == IWN_HW_REV_TYPE_4965)
 3712                 temp = IWN_CTOK(110);
 3713         else
 3714                 temp = 110;
 3715         memset(&crit, 0, sizeof crit);
 3716         crit.tempR = htole32(temp);
 3717         DPRINTF(sc, IWN_DEBUG_RESET, "setting critical temp to %d\n",
 3718             temp);
 3719         return iwn_cmd(sc, IWN_CMD_SET_CRITICAL_TEMP, &crit, sizeof crit, 0);
 3720 }
 3721 
 3722 static int
 3723 iwn_set_timing(struct iwn_softc *sc, struct ieee80211_node *ni)
 3724 {
 3725         struct iwn_cmd_timing cmd;
 3726         uint64_t val, mod;
 3727 
 3728         memset(&cmd, 0, sizeof cmd);
 3729         memcpy(&cmd.tstamp, ni->ni_tstamp.data, sizeof (uint64_t));
 3730         cmd.bintval = htole16(ni->ni_intval);
 3731         cmd.lintval = htole16(10);
 3732 
 3733         /* Compute remaining time until next beacon. */
 3734         val = (uint64_t)ni->ni_intval * 1024;   /* msecs -> usecs */
 3735         mod = le64toh(cmd.tstamp) % val;
 3736         cmd.binitval = htole32((uint32_t)(val - mod));
 3737 
 3738         DPRINTF(sc, IWN_DEBUG_RESET, "timing bintval=%u tstamp=%ju, init=%u\n",
 3739             ni->ni_intval, le64toh(cmd.tstamp), (uint32_t)(val - mod));
 3740 
 3741         return iwn_cmd(sc, IWN_CMD_TIMING, &cmd, sizeof cmd, 1);
 3742 }
 3743 
 3744 static void
 3745 iwn4965_power_calibration(struct iwn_softc *sc, int temp)
 3746 {
 3747         struct ifnet *ifp = sc->sc_ifp;
 3748         struct ieee80211com *ic = ifp->if_l2com;
 3749 
 3750         /* Adjust TX power if need be (delta >= 3 degC.) */
 3751         DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: temperature %d->%d\n",
 3752             __func__, sc->temp, temp);
 3753         if (abs(temp - sc->temp) >= 3) {
 3754                 /* Record temperature of last calibration. */
 3755                 sc->temp = temp;
 3756                 (void)iwn4965_set_txpower(sc, ic->ic_bsschan, 1);
 3757         }
 3758 }
 3759 
 3760 /*
 3761  * Set TX power for current channel (each rate has its own power settings).
 3762  * This function takes into account the regulatory information from EEPROM,
 3763  * the current temperature and the current voltage.
 3764  */
 3765 static int
 3766 iwn4965_set_txpower(struct iwn_softc *sc, struct ieee80211_channel *ch,
 3767     int async)
 3768 {
 3769 /* Fixed-point arithmetic division using a n-bit fractional part. */
 3770 #define fdivround(a, b, n)      \
 3771         ((((1 << n) * (a)) / (b) + (1 << n) / 2) / (1 << n))
 3772 /* Linear interpolation. */
 3773 #define interpolate(x, x1, y1, x2, y2, n)       \
 3774         ((y1) + fdivround(((int)(x) - (x1)) * ((y2) - (y1)), (x2) - (x1), n))
 3775 
 3776         static const int tdiv[IWN_NATTEN_GROUPS] = { 9, 8, 8, 8, 6 };
 3777         struct ifnet *ifp = sc->sc_ifp;
 3778         struct ieee80211com *ic = ifp->if_l2com;
 3779         struct iwn_ucode_info *uc = &sc->ucode_info;
 3780         struct iwn4965_cmd_txpower cmd;
 3781         struct iwn4965_eeprom_chan_samples *chans;
 3782         int32_t vdiff, tdiff;
 3783         int i, c, grp, maxpwr;
 3784         const uint8_t *rf_gain, *dsp_gain;
 3785         uint8_t chan;
 3786 
 3787         /* Retrieve channel number. */
 3788         chan = ieee80211_chan2ieee(ic, ch);
 3789         DPRINTF(sc, IWN_DEBUG_RESET, "setting TX power for channel %d\n",
 3790             chan);
 3791 
 3792         memset(&cmd, 0, sizeof cmd);
 3793         cmd.band = IEEE80211_IS_CHAN_5GHZ(ch) ? 0 : 1;
 3794         cmd.chan = chan;
 3795 
 3796         if (IEEE80211_IS_CHAN_5GHZ(ch)) {
 3797                 maxpwr   = sc->maxpwr5GHz;
 3798                 rf_gain  = iwn4965_rf_gain_5ghz;
 3799                 dsp_gain = iwn4965_dsp_gain_5ghz;
 3800         } else {
 3801                 maxpwr   = sc->maxpwr2GHz;
 3802                 rf_gain  = iwn4965_rf_gain_2ghz;
 3803                 dsp_gain = iwn4965_dsp_gain_2ghz;
 3804         }
 3805 
 3806         /* Compute voltage compensation. */
 3807         vdiff = ((int32_t)le32toh(uc->volt) - sc->eeprom_voltage) / 7;
 3808         if (vdiff > 0)
 3809                 vdiff *= 2;
 3810         if (abs(vdiff) > 2)
 3811                 vdiff = 0;
 3812         DPRINTF(sc, IWN_DEBUG_CALIBRATE | IWN_DEBUG_TXPOW,
 3813             "%s: voltage compensation=%d (UCODE=%d, EEPROM=%d)\n",
 3814             __func__, vdiff, le32toh(uc->volt), sc->eeprom_voltage);
 3815 
 3816         /* Get channel attenuation group. */
 3817         if (chan <= 20)         /* 1-20 */
 3818                 grp = 4;
 3819         else if (chan <= 43)    /* 34-43 */
 3820                 grp = 0;
 3821         else if (chan <= 70)    /* 44-70 */
 3822                 grp = 1;
 3823         else if (chan <= 124)   /* 71-124 */
 3824                 grp = 2;
 3825         else                    /* 125-200 */
 3826                 grp = 3;
 3827         DPRINTF(sc, IWN_DEBUG_CALIBRATE | IWN_DEBUG_TXPOW,
 3828             "%s: chan %d, attenuation group=%d\n", __func__, chan, grp);
 3829 
 3830         /* Get channel sub-band. */
 3831         for (i = 0; i < IWN_NBANDS; i++)
 3832                 if (sc->bands[i].lo != 0 &&
 3833                     sc->bands[i].lo <= chan && chan <= sc->bands[i].hi)
 3834                         break;
 3835         if (i == IWN_NBANDS)    /* Can't happen in real-life. */
 3836                 return EINVAL;
 3837         chans = sc->bands[i].chans;
 3838         DPRINTF(sc, IWN_DEBUG_CALIBRATE | IWN_DEBUG_TXPOW,
 3839             "%s: chan %d sub-band=%d\n", __func__, chan, i);
 3840 
 3841         for (c = 0; c < 2; c++) {
 3842                 uint8_t power, gain, temp;
 3843                 int maxchpwr, pwr, ridx, idx;
 3844 
 3845                 power = interpolate(chan,
 3846                     chans[0].num, chans[0].samples[c][1].power,
 3847                     chans[1].num, chans[1].samples[c][1].power, 1);
 3848                 gain  = interpolate(chan,
 3849                     chans[0].num, chans[0].samples[c][1].gain,
 3850                     chans[1].num, chans[1].samples[c][1].gain, 1);
 3851                 temp  = interpolate(chan,
 3852                     chans[0].num, chans[0].samples[c][1].temp,
 3853                     chans[1].num, chans[1].samples[c][1].temp, 1);
 3854                 DPRINTF(sc, IWN_DEBUG_CALIBRATE | IWN_DEBUG_TXPOW,
 3855                     "%s: Tx chain %d: power=%d gain=%d temp=%d\n",
 3856                     __func__, c, power, gain, temp);
 3857 
 3858                 /* Compute temperature compensation. */
 3859                 tdiff = ((sc->temp - temp) * 2) / tdiv[grp];
 3860                 DPRINTF(sc, IWN_DEBUG_CALIBRATE | IWN_DEBUG_TXPOW,
 3861                     "%s: temperature compensation=%d (current=%d, EEPROM=%d)\n",
 3862                     __func__, tdiff, sc->temp, temp);
 3863 
 3864                 for (ridx = 0; ridx <= IWN_RIDX_MAX; ridx++) {
 3865                         /* Convert dBm to half-dBm. */
 3866                         maxchpwr = sc->maxpwr[chan] * 2;
 3867                         if ((ridx / 8) & 1)
 3868                                 maxchpwr -= 6;  /* MIMO 2T: -3dB */
 3869 
 3870                         pwr = maxpwr;
 3871 
 3872                         /* Adjust TX power based on rate. */
 3873                         if ((ridx % 8) == 5)
 3874                                 pwr -= 15;      /* OFDM48: -7.5dB */
 3875                         else if ((ridx % 8) == 6)
 3876                                 pwr -= 17;      /* OFDM54: -8.5dB */
 3877                         else if ((ridx % 8) == 7)
 3878                                 pwr -= 20;      /* OFDM60: -10dB */
 3879                         else
 3880                                 pwr -= 10;      /* Others: -5dB */
 3881 
 3882                         /* Do not exceed channel max TX power. */
 3883                         if (pwr > maxchpwr)
 3884                                 pwr = maxchpwr;
 3885 
 3886                         idx = gain - (pwr - power) - tdiff - vdiff;
 3887                         if ((ridx / 8) & 1)     /* MIMO */
 3888                                 idx += (int32_t)le32toh(uc->atten[grp][c]);
 3889 
 3890                         if (cmd.band == 0)
 3891                                 idx += 9;       /* 5GHz */
 3892                         if (ridx == IWN_RIDX_MAX)
 3893                                 idx += 5;       /* CCK */
 3894 
 3895                         /* Make sure idx stays in a valid range. */
 3896                         if (idx < 0)
 3897                                 idx = 0;
 3898                         else if (idx > IWN4965_MAX_PWR_INDEX)
 3899                                 idx = IWN4965_MAX_PWR_INDEX;
 3900 
 3901                         DPRINTF(sc, IWN_DEBUG_CALIBRATE | IWN_DEBUG_TXPOW,
 3902                             "%s: Tx chain %d, rate idx %d: power=%d\n",
 3903                             __func__, c, ridx, idx);
 3904                         cmd.power[ridx].rf_gain[c] = rf_gain[idx];
 3905                         cmd.power[ridx].dsp_gain[c] = dsp_gain[idx];
 3906                 }
 3907         }
 3908 
 3909         DPRINTF(sc, IWN_DEBUG_CALIBRATE | IWN_DEBUG_TXPOW,
 3910             "%s: set tx power for chan %d\n", __func__, chan);
 3911         return iwn_cmd(sc, IWN_CMD_TXPOWER, &cmd, sizeof cmd, async);
 3912 
 3913 #undef interpolate
 3914 #undef fdivround
 3915 }
 3916 
 3917 static int
 3918 iwn5000_set_txpower(struct iwn_softc *sc, struct ieee80211_channel *ch,
 3919     int async)
 3920 {
 3921         struct iwn5000_cmd_txpower cmd;
 3922 
 3923         /*
 3924          * TX power calibration is handled automatically by the firmware
 3925          * for 5000 Series.
 3926          */
 3927         memset(&cmd, 0, sizeof cmd);
 3928         cmd.global_limit = 2 * IWN5000_TXPOWER_MAX_DBM; /* 16 dBm */
 3929         cmd.flags = IWN5000_TXPOWER_NO_CLOSED;
 3930         cmd.srv_limit = IWN5000_TXPOWER_AUTO;
 3931         DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: setting TX power\n", __func__);
 3932         return iwn_cmd(sc, IWN_CMD_TXPOWER_DBM, &cmd, sizeof cmd, async);
 3933 }
 3934 
 3935 /*
 3936  * Retrieve the maximum RSSI (in dBm) among receivers.
 3937  */
 3938 static int
 3939 iwn4965_get_rssi(struct iwn_softc *sc, struct iwn_rx_stat *stat)
 3940 {
 3941         struct iwn4965_rx_phystat *phy = (void *)stat->phybuf;
 3942         uint8_t mask, agc;
 3943         int rssi;
 3944 
 3945         mask = (le16toh(phy->antenna) >> 4) & IWN_ANT_ABC;
 3946         agc  = (le16toh(phy->agc) >> 7) & 0x7f;
 3947 
 3948         rssi = 0;
 3949 #if 0
 3950         if (mask & IWN_ANT_A)   /* Ant A */
 3951                 rssi = max(rssi, phy->rssi[0]);
 3952         if (mask & IWN_ATH_B)   /* Ant B */
 3953                 rssi = max(rssi, phy->rssi[2]);
 3954         if (mask & IWN_ANT_C)   /* Ant C */
 3955                 rssi = max(rssi, phy->rssi[4]);
 3956 #else
 3957         rssi = max(rssi, phy->rssi[0]);
 3958         rssi = max(rssi, phy->rssi[2]);
 3959         rssi = max(rssi, phy->rssi[4]);
 3960 #endif
 3961 
 3962         DPRINTF(sc, IWN_DEBUG_RECV, "%s: agc %d mask 0x%x rssi %d %d %d "
 3963             "result %d\n", __func__, agc, mask,
 3964             phy->rssi[0], phy->rssi[2], phy->rssi[4],
 3965             rssi - agc - IWN_RSSI_TO_DBM);
 3966         return rssi - agc - IWN_RSSI_TO_DBM;
 3967 }
 3968 
 3969 static int
 3970 iwn5000_get_rssi(struct iwn_softc *sc, struct iwn_rx_stat *stat)
 3971 {
 3972         struct iwn5000_rx_phystat *phy = (void *)stat->phybuf;
 3973         int rssi;
 3974         uint8_t agc;
 3975 
 3976         agc = (le32toh(phy->agc) >> 9) & 0x7f;
 3977 
 3978         rssi = MAX(le16toh(phy->rssi[0]) & 0xff,
 3979                    le16toh(phy->rssi[1]) & 0xff);
 3980         rssi = MAX(le16toh(phy->rssi[2]) & 0xff, rssi);
 3981 
 3982         DPRINTF(sc, IWN_DEBUG_RECV, "%s: agc %d rssi %d %d %d "
 3983             "result %d\n", __func__, agc,
 3984             phy->rssi[0], phy->rssi[1], phy->rssi[2],
 3985             rssi - agc - IWN_RSSI_TO_DBM);
 3986         return rssi - agc - IWN_RSSI_TO_DBM;
 3987 }
 3988 
 3989 /*
 3990  * Retrieve the average noise (in dBm) among receivers.
 3991  */
 3992 static int
 3993 iwn_get_noise(const struct iwn_rx_general_stats *stats)
 3994 {
 3995         int i, total, nbant, noise;
 3996 
 3997         total = nbant = 0;
 3998         for (i = 0; i < 3; i++) {
 3999                 if ((noise = le32toh(stats->noise[i]) & 0xff) == 0)
 4000                         continue;
 4001                 total += noise;
 4002                 nbant++;
 4003         }
 4004         /* There should be at least one antenna but check anyway. */
 4005         return (nbant == 0) ? -127 : (total / nbant) - 107;
 4006 }
 4007 
 4008 /*
 4009  * Compute temperature (in degC) from last received statistics.
 4010  */
 4011 static int
 4012 iwn4965_get_temperature(struct iwn_softc *sc)
 4013 {
 4014         struct iwn_ucode_info *uc = &sc->ucode_info;
 4015         int32_t r1, r2, r3, r4, temp;
 4016 
 4017         r1 = le32toh(uc->temp[0].chan20MHz);
 4018         r2 = le32toh(uc->temp[1].chan20MHz);
 4019         r3 = le32toh(uc->temp[2].chan20MHz);
 4020         r4 = le32toh(sc->rawtemp);
 4021 
 4022         if (r1 == r3)   /* Prevents division by 0 (should not happen.) */
 4023                 return 0;
 4024 
 4025         /* Sign-extend 23-bit R4 value to 32-bit. */
 4026         r4 = (r4 << 8) >> 8;
 4027         /* Compute temperature in Kelvin. */
 4028         temp = (259 * (r4 - r2)) / (r3 - r1);
 4029         temp = (temp * 97) / 100 + 8;
 4030 
 4031         DPRINTF(sc, IWN_DEBUG_ANY, "temperature %dK/%dC\n", temp,
 4032             IWN_KTOC(temp));
 4033         return IWN_KTOC(temp);
 4034 }
 4035 
 4036 static int
 4037 iwn5000_get_temperature(struct iwn_softc *sc)
 4038 {
 4039         int32_t temp;
 4040 
 4041         /*
 4042          * Temperature is not used by the driver for 5000 Series because
 4043          * TX power calibration is handled by firmware.  We export it to
 4044          * users through the sensor framework though.
 4045          */
 4046         temp = le32toh(sc->rawtemp);
 4047         if (sc->hw_type == IWN_HW_REV_TYPE_5150) {
 4048                 temp = (temp / -5) + sc->temp_off;
 4049                 temp = IWN_KTOC(temp);
 4050         }
 4051         return temp;
 4052 }
 4053 
 4054 /*
 4055  * Initialize sensitivity calibration state machine.
 4056  */
 4057 static int
 4058 iwn_init_sensitivity(struct iwn_softc *sc)
 4059 {
 4060         const struct iwn_hal *hal = sc->sc_hal;
 4061         struct iwn_calib_state *calib = &sc->calib;
 4062         uint32_t flags;
 4063         int error;
 4064 
 4065         /* Reset calibration state machine. */
 4066         memset(calib, 0, sizeof (*calib));
 4067         calib->state = IWN_CALIB_STATE_INIT;
 4068         calib->cck_state = IWN_CCK_STATE_HIFA;
 4069         /* Set initial correlation values. */
 4070         calib->ofdm_x1     = sc->limits->min_ofdm_x1;
 4071         calib->ofdm_mrc_x1 = sc->limits->min_ofdm_mrc_x1;
 4072         calib->ofdm_x4     = sc->limits->min_ofdm_x4;
 4073         calib->ofdm_mrc_x4 = sc->limits->min_ofdm_mrc_x4;
 4074         calib->cck_x4      = 125;
 4075         calib->cck_mrc_x4  = sc->limits->min_cck_mrc_x4;
 4076         calib->energy_cck  = sc->limits->energy_cck;
 4077 
 4078         /* Write initial sensitivity. */
 4079         error = iwn_send_sensitivity(sc);
 4080         if (error != 0)
 4081                 return error;
 4082 
 4083         /* Write initial gains. */
 4084         error = hal->init_gains(sc);
 4085         if (error != 0)
 4086                 return error;
 4087 
 4088         /* Request statistics at each beacon interval. */
 4089         flags = 0;
 4090         DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: calibrate phy\n", __func__);
 4091         return iwn_cmd(sc, IWN_CMD_GET_STATISTICS, &flags, sizeof flags, 1);
 4092 }
 4093 
 4094 /*
 4095  * Collect noise and RSSI statistics for the first 20 beacons received
 4096  * after association and use them to determine connected antennas and
 4097  * to set differential gains.
 4098  */
 4099 static void
 4100 iwn_collect_noise(struct iwn_softc *sc,
 4101     const struct iwn_rx_general_stats *stats)
 4102 {
 4103         const struct iwn_hal *hal = sc->sc_hal;
 4104         struct iwn_calib_state *calib = &sc->calib;
 4105         uint32_t val;
 4106         int i;
 4107 
 4108         /* Accumulate RSSI and noise for all 3 antennas. */
 4109         for (i = 0; i < 3; i++) {
 4110                 calib->rssi[i] += le32toh(stats->rssi[i]) & 0xff;
 4111                 calib->noise[i] += le32toh(stats->noise[i]) & 0xff;
 4112         }
 4113         /* NB: We update differential gains only once after 20 beacons. */
 4114         if (++calib->nbeacons < 20)
 4115                 return;
 4116 
 4117         /* Determine highest average RSSI. */
 4118         val = MAX(calib->rssi[0], calib->rssi[1]);
 4119         val = MAX(calib->rssi[2], val);
 4120 
 4121         /* Determine which antennas are connected. */
 4122         sc->chainmask = 0;
 4123         for (i = 0; i < 3; i++)
 4124                 if (val - calib->rssi[i] <= 15 * 20)
 4125                         sc->chainmask |= 1 << i;
 4126         /* If none of the TX antennas are connected, keep at least one. */
 4127         if ((sc->chainmask & sc->txchainmask) == 0)
 4128                 sc->chainmask |= IWN_LSB(sc->txchainmask);
 4129 
 4130         (void)hal->set_gains(sc);
 4131         calib->state = IWN_CALIB_STATE_RUN;
 4132 
 4133 #ifdef notyet
 4134         /* XXX Disable RX chains with no antennas connected. */
 4135         sc->rxon.rxchain = htole16(IWN_RXCHAIN_SEL(sc->chainmask));
 4136         (void)iwn_cmd(sc, IWN_CMD_RXON, &sc->rxon, hal->rxonsz, 1);
 4137 #endif
 4138 
 4139 #if 0
 4140         /* XXX: not yet */
 4141         /* Enable power-saving mode if requested by user. */
 4142         if (sc->sc_ic.ic_flags & IEEE80211_F_PMGTON)
 4143                 (void)iwn_set_pslevel(sc, 0, 3, 1);
 4144 #endif
 4145 }
 4146 
 4147 static int
 4148 iwn4965_init_gains(struct iwn_softc *sc)
 4149 {
 4150         struct iwn_phy_calib_gain cmd;
 4151 
 4152         memset(&cmd, 0, sizeof cmd);
 4153         cmd.code = IWN4965_PHY_CALIB_DIFF_GAIN;
 4154         /* Differential gains initially set to 0 for all 3 antennas. */
 4155         DPRINTF(sc, IWN_DEBUG_CALIBRATE,
 4156             "%s: setting initial differential gains\n", __func__);
 4157         return iwn_cmd(sc, IWN_CMD_PHY_CALIB, &cmd, sizeof cmd, 1);
 4158 }
 4159 
 4160 static int
 4161 iwn5000_init_gains(struct iwn_softc *sc)
 4162 {
 4163         struct iwn_phy_calib cmd;
 4164 
 4165         memset(&cmd, 0, sizeof cmd);
 4166         cmd.code = IWN5000_PHY_CALIB_RESET_NOISE_GAIN;
 4167         cmd.ngroups = 1;
 4168         cmd.isvalid = 1;
 4169         DPRINTF(sc, IWN_DEBUG_CALIBRATE,
 4170             "%s: setting initial differential gains\n", __func__);
 4171         return iwn_cmd(sc, IWN_CMD_PHY_CALIB, &cmd, sizeof cmd, 1);
 4172 }
 4173 
 4174 static int
 4175 iwn4965_set_gains(struct iwn_softc *sc)
 4176 {
 4177         struct iwn_calib_state *calib = &sc->calib;
 4178         struct iwn_phy_calib_gain cmd;
 4179         int i, delta, noise;
 4180 
 4181         /* Get minimal noise among connected antennas. */
 4182         noise = INT_MAX;        /* NB: There's at least one antenna. */
 4183         for (i = 0; i < 3; i++)
 4184                 if (sc->chainmask & (1 << i))
 4185                         noise = MIN(calib->noise[i], noise);
 4186 
 4187         memset(&cmd, 0, sizeof cmd);
 4188         cmd.code = IWN4965_PHY_CALIB_DIFF_GAIN;
 4189         /* Set differential gains for connected antennas. */
 4190         for (i = 0; i < 3; i++) {
 4191                 if (sc->chainmask & (1 << i)) {
 4192                         /* Compute attenuation (in unit of 1.5dB). */
 4193                         delta = (noise - (int32_t)calib->noise[i]) / 30;
 4194                         /* NB: delta <= 0 */
 4195                         /* Limit to [-4.5dB,0]. */
 4196                         cmd.gain[i] = MIN(abs(delta), 3);
 4197                         if (delta < 0)
 4198                                 cmd.gain[i] |= 1 << 2;  /* sign bit */
 4199                 }
 4200         }
 4201         DPRINTF(sc, IWN_DEBUG_CALIBRATE,
 4202             "setting differential gains Ant A/B/C: %x/%x/%x (%x)\n",
 4203             cmd.gain[0], cmd.gain[1], cmd.gain[2], sc->chainmask);
 4204         return iwn_cmd(sc, IWN_CMD_PHY_CALIB, &cmd, sizeof cmd, 1);
 4205 }
 4206 
 4207 static int
 4208 iwn5000_set_gains(struct iwn_softc *sc)
 4209 {
 4210         struct iwn_calib_state *calib = &sc->calib;
 4211         struct iwn_phy_calib_gain cmd;
 4212         int i, ant, delta, div;
 4213 
 4214         /* We collected 20 beacons and !=6050 need a 1.5 factor. */
 4215         div = (sc->hw_type == IWN_HW_REV_TYPE_6050) ? 20 : 30;
 4216 
 4217         memset(&cmd, 0, sizeof cmd);
 4218         cmd.code = IWN5000_PHY_CALIB_NOISE_GAIN;
 4219         cmd.ngroups = 1;
 4220         cmd.isvalid = 1;
 4221         /* Get first available RX antenna as referential. */
 4222         ant = IWN_LSB(sc->rxchainmask);
 4223         /* Set differential gains for other antennas. */
 4224         for (i = ant + 1; i < 3; i++) {
 4225                 if (sc->chainmask & (1 << i)) {
 4226                         /* The delta is relative to antenna "ant". */
 4227                         delta = ((int32_t)calib->noise[ant] -
 4228                             (int32_t)calib->noise[i]) / div;
 4229                         /* Limit to [-4.5dB,+4.5dB]. */
 4230                         cmd.gain[i - 1] = MIN(abs(delta), 3);
 4231                         if (delta < 0)
 4232                                 cmd.gain[i - 1] |= 1 << 2;      /* sign bit */
 4233                 }
 4234         }
 4235         DPRINTF(sc, IWN_DEBUG_CALIBRATE,
 4236             "setting differential gains Ant B/C: %x/%x (%x)\n",
 4237             cmd.gain[0], cmd.gain[1], sc->chainmask);
 4238         return iwn_cmd(sc, IWN_CMD_PHY_CALIB, &cmd, sizeof cmd, 1);
 4239 }
 4240 
 4241 /*
 4242  * Tune RF RX sensitivity based on the number of false alarms detected
 4243  * during the last beacon period.
 4244  */
 4245 static void
 4246 iwn_tune_sensitivity(struct iwn_softc *sc, const struct iwn_rx_stats *stats)
 4247 {
 4248 #define inc(val, inc, max)                      \
 4249         if ((val) < (max)) {                    \
 4250                 if ((val) < (max) - (inc))      \
 4251                         (val) += (inc);         \
 4252                 else                            \
 4253                         (val) = (max);          \
 4254                 needs_update = 1;               \
 4255         }
 4256 #define dec(val, dec, min)                      \
 4257         if ((val) > (min)) {                    \
 4258                 if ((val) > (min) + (dec))      \
 4259                         (val) -= (dec);         \
 4260                 else                            \
 4261                         (val) = (min);          \
 4262                 needs_update = 1;               \
 4263         }
 4264 
 4265         const struct iwn_sensitivity_limits *limits = sc->limits;
 4266         struct iwn_calib_state *calib = &sc->calib;
 4267         uint32_t val, rxena, fa;
 4268         uint32_t energy[3], energy_min;
 4269         uint8_t noise[3], noise_ref;
 4270         int i, needs_update = 0;
 4271 
 4272         /* Check that we've been enabled long enough. */
 4273         rxena = le32toh(stats->general.load);
 4274         if (rxena == 0)
 4275                 return;
 4276 
 4277         /* Compute number of false alarms since last call for OFDM. */
 4278         fa  = le32toh(stats->ofdm.bad_plcp) - calib->bad_plcp_ofdm;
 4279         fa += le32toh(stats->ofdm.fa) - calib->fa_ofdm;
 4280         fa *= 200 * 1024;       /* 200TU */
 4281 
 4282         /* Save counters values for next call. */
 4283         calib->bad_plcp_ofdm = le32toh(stats->ofdm.bad_plcp);
 4284         calib->fa_ofdm = le32toh(stats->ofdm.fa);
 4285 
 4286         if (fa > 50 * rxena) {
 4287                 /* High false alarm count, decrease sensitivity. */
 4288                 DPRINTF(sc, IWN_DEBUG_CALIBRATE,
 4289                     "%s: OFDM high false alarm count: %u\n", __func__, fa);
 4290                 inc(calib->ofdm_x1,     1, limits->max_ofdm_x1);
 4291                 inc(calib->ofdm_mrc_x1, 1, limits->max_ofdm_mrc_x1);
 4292                 inc(calib->ofdm_x4,     1, limits->max_ofdm_x4);
 4293                 inc(calib->ofdm_mrc_x4, 1, limits->max_ofdm_mrc_x4);
 4294 
 4295         } else if (fa < 5 * rxena) {
 4296                 /* Low false alarm count, increase sensitivity. */
 4297                 DPRINTF(sc, IWN_DEBUG_CALIBRATE,
 4298                     "%s: OFDM low false alarm count: %u\n", __func__, fa);
 4299                 dec(calib->ofdm_x1,     1, limits->min_ofdm_x1);
 4300                 dec(calib->ofdm_mrc_x1, 1, limits->min_ofdm_mrc_x1);
 4301                 dec(calib->ofdm_x4,     1, limits->min_ofdm_x4);
 4302                 dec(calib->ofdm_mrc_x4, 1, limits->min_ofdm_mrc_x4);
 4303         }
 4304 
 4305         /* Compute maximum noise among 3 receivers. */
 4306         for (i = 0; i < 3; i++)
 4307                 noise[i] = (le32toh(stats->general.noise[i]) >> 8) & 0xff;
 4308         val = MAX(noise[0], noise[1]);
 4309         val = MAX(noise[2], val);
 4310         /* Insert it into our samples table. */
 4311         calib->noise_samples[calib->cur_noise_sample] = val;
 4312         calib->cur_noise_sample = (calib->cur_noise_sample + 1) % 20;
 4313 
 4314         /* Compute maximum noise among last 20 samples. */
 4315         noise_ref = calib->noise_samples[0];
 4316         for (i = 1; i < 20; i++)
 4317                 noise_ref = MAX(noise_ref, calib->noise_samples[i]);
 4318 
 4319         /* Compute maximum energy among 3 receivers. */
 4320         for (i = 0; i < 3; i++)
 4321                 energy[i] = le32toh(stats->general.energy[i]);
 4322         val = MIN(energy[0], energy[1]);
 4323         val = MIN(energy[2], val);
 4324         /* Insert it into our samples table. */
 4325         calib->energy_samples[calib->cur_energy_sample] = val;
 4326         calib->cur_energy_sample = (calib->cur_energy_sample + 1) % 10;
 4327 
 4328         /* Compute minimum energy among last 10 samples. */
 4329         energy_min = calib->energy_samples[0];
 4330         for (i = 1; i < 10; i++)
 4331                 energy_min = MAX(energy_min, calib->energy_samples[i]);
 4332         energy_min += 6;
 4333 
 4334         /* Compute number of false alarms since last call for CCK. */
 4335         fa  = le32toh(stats->cck.bad_plcp) - calib->bad_plcp_cck;
 4336         fa += le32toh(stats->cck.fa) - calib->fa_cck;
 4337         fa *= 200 * 1024;       /* 200TU */
 4338 
 4339         /* Save counters values for next call. */
 4340         calib->bad_plcp_cck = le32toh(stats->cck.bad_plcp);
 4341         calib->fa_cck = le32toh(stats->cck.fa);
 4342 
 4343         if (fa > 50 * rxena) {
 4344                 /* High false alarm count, decrease sensitivity. */
 4345                 DPRINTF(sc, IWN_DEBUG_CALIBRATE,
 4346                     "%s: CCK high false alarm count: %u\n", __func__, fa);
 4347                 calib->cck_state = IWN_CCK_STATE_HIFA;
 4348                 calib->low_fa = 0;
 4349 
 4350                 if (calib->cck_x4 > 160) {
 4351                         calib->noise_ref = noise_ref;
 4352                         if (calib->energy_cck > 2)
 4353                                 dec(calib->energy_cck, 2, energy_min);
 4354                 }
 4355                 if (calib->cck_x4 < 160) {
 4356                         calib->cck_x4 = 161;
 4357                         needs_update = 1;
 4358                 } else
 4359                         inc(calib->cck_x4, 3, limits->max_cck_x4);
 4360 
 4361                 inc(calib->cck_mrc_x4, 3, limits->max_cck_mrc_x4);
 4362 
 4363         } else if (fa < 5 * rxena) {
 4364                 /* Low false alarm count, increase sensitivity. */
 4365                 DPRINTF(sc, IWN_DEBUG_CALIBRATE,
 4366                     "%s: CCK low false alarm count: %u\n", __func__, fa);
 4367                 calib->cck_state = IWN_CCK_STATE_LOFA;
 4368                 calib->low_fa++;
 4369 
 4370                 if (calib->cck_state != IWN_CCK_STATE_INIT &&
 4371                     (((int32_t)calib->noise_ref - (int32_t)noise_ref) > 2 ||
 4372                     calib->low_fa > 100)) {
 4373                         inc(calib->energy_cck, 2, limits->min_energy_cck);
 4374                         dec(calib->cck_x4,     3, limits->min_cck_x4);
 4375                         dec(calib->cck_mrc_x4, 3, limits->min_cck_mrc_x4);
 4376                 }
 4377         } else {
 4378                 /* Not worth to increase or decrease sensitivity. */
 4379                 DPRINTF(sc, IWN_DEBUG_CALIBRATE,
 4380                     "%s: CCK normal false alarm count: %u\n", __func__, fa);
 4381                 calib->low_fa = 0;
 4382                 calib->noise_ref = noise_ref;
 4383 
 4384                 if (calib->cck_state == IWN_CCK_STATE_HIFA) {
 4385                         /* Previous interval had many false alarms. */
 4386                         dec(calib->energy_cck, 8, energy_min);
 4387                 }
 4388                 calib->cck_state = IWN_CCK_STATE_INIT;
 4389         }
 4390 
 4391         if (needs_update)
 4392                 (void)iwn_send_sensitivity(sc);
 4393 #undef dec
 4394 #undef inc
 4395 }
 4396 
 4397 static int
 4398 iwn_send_sensitivity(struct iwn_softc *sc)
 4399 {
 4400         struct iwn_calib_state *calib = &sc->calib;
 4401         struct iwn_sensitivity_cmd cmd;
 4402 
 4403         memset(&cmd, 0, sizeof cmd);
 4404         cmd.which = IWN_SENSITIVITY_WORKTBL;
 4405         /* OFDM modulation. */
 4406         cmd.corr_ofdm_x1     = htole16(calib->ofdm_x1);
 4407         cmd.corr_ofdm_mrc_x1 = htole16(calib->ofdm_mrc_x1);
 4408         cmd.corr_ofdm_x4     = htole16(calib->ofdm_x4);
 4409         cmd.corr_ofdm_mrc_x4 = htole16(calib->ofdm_mrc_x4);
 4410         cmd.energy_ofdm      = htole16(sc->limits->energy_ofdm);
 4411         cmd.energy_ofdm_th   = htole16(62);
 4412         /* CCK modulation. */
 4413         cmd.corr_cck_x4      = htole16(calib->cck_x4);
 4414         cmd.corr_cck_mrc_x4  = htole16(calib->cck_mrc_x4);
 4415         cmd.energy_cck       = htole16(calib->energy_cck);
 4416         /* Barker modulation: use default values. */
 4417         cmd.corr_barker      = htole16(190);
 4418         cmd.corr_barker_mrc  = htole16(390);
 4419 
 4420         DPRINTF(sc, IWN_DEBUG_CALIBRATE,
 4421             "%s: set sensitivity %d/%d/%d/%d/%d/%d/%d\n", __func__,
 4422             calib->ofdm_x1, calib->ofdm_mrc_x1, calib->ofdm_x4,
 4423             calib->ofdm_mrc_x4, calib->cck_x4,
 4424             calib->cck_mrc_x4, calib->energy_cck);
 4425         return iwn_cmd(sc, IWN_CMD_SET_SENSITIVITY, &cmd, sizeof cmd, 1);
 4426 }
 4427 
 4428 /*
 4429  * Set STA mode power saving level (between 0 and 5).
 4430  * Level 0 is CAM (Continuously Aware Mode), 5 is for maximum power saving.
 4431  */
 4432 static int
 4433 iwn_set_pslevel(struct iwn_softc *sc, int dtim, int level, int async)
 4434 {
 4435         const struct iwn_pmgt *pmgt;
 4436         struct iwn_pmgt_cmd cmd;
 4437         uint32_t max, skip_dtim;
 4438         uint32_t tmp;
 4439         int i;
 4440 
 4441         /* Select which PS parameters to use. */
 4442         if (dtim <= 2)
 4443                 pmgt = &iwn_pmgt[0][level];
 4444         else if (dtim <= 10)
 4445                 pmgt = &iwn_pmgt[1][level];
 4446         else
 4447                 pmgt = &iwn_pmgt[2][level];
 4448 
 4449         memset(&cmd, 0, sizeof cmd);
 4450         if (level != 0) /* not CAM */
 4451                 cmd.flags |= htole16(IWN_PS_ALLOW_SLEEP);
 4452         if (level == 5)
 4453                 cmd.flags |= htole16(IWN_PS_FAST_PD);
 4454         /* Retrieve PCIe Active State Power Management (ASPM). */
 4455         tmp = pci_read_config(sc->sc_dev, sc->sc_cap_off + 0x10, 1);
 4456         if (!(tmp & 0x1))       /* L0s Entry disabled. */
 4457                 cmd.flags |= htole16(IWN_PS_PCI_PMGT);
 4458         cmd.rxtimeout = htole32(pmgt->rxtimeout * 1024);
 4459         cmd.txtimeout = htole32(pmgt->txtimeout * 1024);
 4460 
 4461         if (dtim == 0) {
 4462                 dtim = 1;
 4463                 skip_dtim = 0;
 4464         } else
 4465                 skip_dtim = pmgt->skip_dtim;
 4466         if (skip_dtim != 0) {
 4467                 cmd.flags |= htole16(IWN_PS_SLEEP_OVER_DTIM);
 4468                 max = pmgt->intval[4];
 4469                 if (max == (uint32_t)-1)
 4470                         max = dtim * (skip_dtim + 1);
 4471                 else if (max > dtim)
 4472                         max = (max / dtim) * dtim;
 4473         } else
 4474                 max = dtim;
 4475         for (i = 0; i < 5; i++)
 4476                 cmd.intval[i] = htole32(MIN(max, pmgt->intval[i]));
 4477 
 4478         DPRINTF(sc, IWN_DEBUG_RESET, "setting power saving level to %d\n",
 4479             level);
 4480         return iwn_cmd(sc, IWN_CMD_SET_POWER_MODE, &cmd, sizeof cmd, async);
 4481 }
 4482 
 4483 static int
 4484 iwn_config(struct iwn_softc *sc)
 4485 {
 4486         const struct iwn_hal *hal = sc->sc_hal;
 4487         struct ifnet *ifp = sc->sc_ifp;
 4488         struct ieee80211com *ic = ifp->if_l2com;
 4489         struct iwn_bluetooth bluetooth;
 4490         uint32_t txmask;
 4491         int error;
 4492         uint16_t rxchain;
 4493 
 4494         /* Configure valid TX chains for 5000 Series. */
 4495         if (sc->hw_type != IWN_HW_REV_TYPE_4965) {
 4496                 txmask = htole32(sc->txchainmask);
 4497                 DPRINTF(sc, IWN_DEBUG_RESET,
 4498                     "%s: configuring valid TX chains 0x%x\n", __func__, txmask);
 4499                 error = iwn_cmd(sc, IWN5000_CMD_TX_ANT_CONFIG, &txmask,
 4500                     sizeof txmask, 0);
 4501                 if (error != 0) {
 4502                         device_printf(sc->sc_dev,
 4503                             "%s: could not configure valid TX chains, "
 4504                             "error %d\n", __func__, error);
 4505                         return error;
 4506                 }
 4507         }
 4508 
 4509         /* Configure bluetooth coexistence. */
 4510         memset(&bluetooth, 0, sizeof bluetooth);
 4511         bluetooth.flags = IWN_BT_COEX_CHAN_ANN | IWN_BT_COEX_BT_PRIO;
 4512         bluetooth.lead_time = IWN_BT_LEAD_TIME_DEF;
 4513         bluetooth.max_kill = IWN_BT_MAX_KILL_DEF;
 4514         DPRINTF(sc, IWN_DEBUG_RESET, "%s: config bluetooth coexistence\n",
 4515             __func__);
 4516         error = iwn_cmd(sc, IWN_CMD_BT_COEX, &bluetooth, sizeof bluetooth, 0);
 4517         if (error != 0) {
 4518                 device_printf(sc->sc_dev,
 4519                     "%s: could not configure bluetooth coexistence, error %d\n",
 4520                     __func__, error);
 4521                 return error;
 4522         }
 4523 
 4524         /* Set mode, channel, RX filter and enable RX. */
 4525         memset(&sc->rxon, 0, sizeof (struct iwn_rxon));
 4526         IEEE80211_ADDR_COPY(sc->rxon.myaddr, IF_LLADDR(ifp));
 4527         IEEE80211_ADDR_COPY(sc->rxon.wlap, IF_LLADDR(ifp));
 4528         sc->rxon.chan = ieee80211_chan2ieee(ic, ic->ic_curchan);
 4529         sc->rxon.flags = htole32(IWN_RXON_TSF | IWN_RXON_CTS_TO_SELF);
 4530         if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
 4531                 sc->rxon.flags |= htole32(IWN_RXON_AUTO | IWN_RXON_24GHZ);
 4532         switch (ic->ic_opmode) {
 4533         case IEEE80211_M_STA:
 4534                 sc->rxon.mode = IWN_MODE_STA;
 4535                 sc->rxon.filter = htole32(IWN_FILTER_MULTICAST);
 4536                 break;
 4537         case IEEE80211_M_MONITOR:
 4538                 sc->rxon.mode = IWN_MODE_MONITOR;
 4539                 sc->rxon.filter = htole32(IWN_FILTER_MULTICAST |
 4540                     IWN_FILTER_CTL | IWN_FILTER_PROMISC);
 4541                 break;
 4542         default:
 4543                 /* Should not get there. */
 4544                 break;
 4545         }
 4546         sc->rxon.cck_mask  = 0x0f;      /* not yet negotiated */
 4547         sc->rxon.ofdm_mask = 0xff;      /* not yet negotiated */
 4548         sc->rxon.ht_single_mask = 0xff;
 4549         sc->rxon.ht_dual_mask = 0xff;
 4550         sc->rxon.ht_triple_mask = 0xff;
 4551         rxchain =
 4552             IWN_RXCHAIN_VALID(sc->rxchainmask) |
 4553             IWN_RXCHAIN_MIMO_COUNT(2) |
 4554             IWN_RXCHAIN_IDLE_COUNT(2);
 4555         sc->rxon.rxchain = htole16(rxchain);
 4556         DPRINTF(sc, IWN_DEBUG_RESET, "%s: setting configuration\n", __func__);
 4557         error = iwn_cmd(sc, IWN_CMD_RXON, &sc->rxon, hal->rxonsz, 0);
 4558         if (error != 0) {
 4559                 device_printf(sc->sc_dev,
 4560                     "%s: RXON command failed\n", __func__);
 4561                 return error;
 4562         }
 4563 
 4564         error = iwn_add_broadcast_node(sc, 0);
 4565         if (error != 0) {
 4566                 device_printf(sc->sc_dev,
 4567                     "%s: could not add broadcast node\n", __func__);
 4568                 return error;
 4569         }
 4570 
 4571         /* Configuration has changed, set TX power accordingly. */
 4572         error = hal->set_txpower(sc, ic->ic_curchan, 0);
 4573         if (error != 0) {
 4574                 device_printf(sc->sc_dev,
 4575                     "%s: could not set TX power\n", __func__);
 4576                 return error;
 4577         }
 4578 
 4579         error = iwn_set_critical_temp(sc);
 4580         if (error != 0) {
 4581                 device_printf(sc->sc_dev,
 4582                     "%s: ccould not set critical temperature\n", __func__);
 4583                 return error;
 4584         }
 4585 
 4586         /* Set power saving level to CAM during initialization. */
 4587         error = iwn_set_pslevel(sc, 0, 0, 0);
 4588         if (error != 0) {
 4589                 device_printf(sc->sc_dev,
 4590                     "%s: could not set power saving level\n", __func__);
 4591                 return error;
 4592         }
 4593         return 0;
 4594 }
 4595 
 4596 static int
 4597 iwn_scan(struct iwn_softc *sc)
 4598 {
 4599         struct ifnet *ifp = sc->sc_ifp;
 4600         struct ieee80211com *ic = ifp->if_l2com;
 4601         struct ieee80211_scan_state *ss = ic->ic_scan;  /*XXX*/
 4602         struct iwn_scan_hdr *hdr;
 4603         struct iwn_cmd_data *tx;
 4604         struct iwn_scan_essid *essid;
 4605         struct iwn_scan_chan *chan;
 4606         struct ieee80211_frame *wh;
 4607         struct ieee80211_rateset *rs;
 4608         struct ieee80211_channel *c;
 4609         int buflen, error, nrates;
 4610         uint16_t rxchain;
 4611         uint8_t *buf, *frm, txant;
 4612 
 4613         buf = malloc(IWN_SCAN_MAXSZ, M_DEVBUF, M_NOWAIT | M_ZERO);
 4614         if (buf == NULL) {
 4615                 device_printf(sc->sc_dev,
 4616                     "%s: could not allocate buffer for scan command\n",
 4617                     __func__);
 4618                 return ENOMEM;
 4619         }
 4620         hdr = (struct iwn_scan_hdr *)buf;
 4621 
 4622         /*
 4623          * Move to the next channel if no frames are received within 10ms
 4624          * after sending the probe request.
 4625          */
 4626         hdr->quiet_time = htole16(10);          /* timeout in milliseconds */
 4627         hdr->quiet_threshold = htole16(1);      /* min # of packets */
 4628 
 4629         /* Select antennas for scanning. */
 4630         rxchain =
 4631             IWN_RXCHAIN_VALID(sc->rxchainmask) |
 4632             IWN_RXCHAIN_FORCE_MIMO_SEL(sc->rxchainmask) |
 4633             IWN_RXCHAIN_DRIVER_FORCE;
 4634         if (IEEE80211_IS_CHAN_A(ic->ic_curchan) &&
 4635             sc->hw_type == IWN_HW_REV_TYPE_4965) {
 4636                 /* Ant A must be avoided in 5GHz because of an HW bug. */
 4637                 rxchain |= IWN_RXCHAIN_FORCE_SEL(IWN_ANT_BC);
 4638         } else  /* Use all available RX antennas. */
 4639                 rxchain |= IWN_RXCHAIN_FORCE_SEL(sc->rxchainmask);
 4640         hdr->rxchain = htole16(rxchain);
 4641         hdr->filter = htole32(IWN_FILTER_MULTICAST | IWN_FILTER_BEACON);
 4642 
 4643         tx = (struct iwn_cmd_data *)(hdr + 1);
 4644         tx->flags = htole32(IWN_TX_AUTO_SEQ);
 4645         tx->id = sc->sc_hal->broadcast_id;
 4646         tx->lifetime = htole32(IWN_LIFETIME_INFINITE);
 4647 
 4648         if (IEEE80211_IS_CHAN_A(ic->ic_curchan)) {
 4649                 /* Send probe requests at 6Mbps. */
 4650                 tx->plcp = iwn_rates[IWN_RIDX_OFDM6].plcp;
 4651                 rs = &ic->ic_sup_rates[IEEE80211_MODE_11A];
 4652         } else {
 4653                 hdr->flags = htole32(IWN_RXON_24GHZ | IWN_RXON_AUTO);
 4654                 /* Send probe requests at 1Mbps. */
 4655                 tx->plcp = iwn_rates[IWN_RIDX_CCK1].plcp;
 4656                 tx->rflags = IWN_RFLAG_CCK;
 4657                 rs = &ic->ic_sup_rates[IEEE80211_MODE_11G];
 4658         }
 4659         /* Use the first valid TX antenna. */
 4660         txant = IWN_LSB(sc->txchainmask);
 4661         tx->rflags |= IWN_RFLAG_ANT(txant);
 4662 
 4663         essid = (struct iwn_scan_essid *)(tx + 1);
 4664         if (ss->ss_ssid[0].len != 0) {
 4665                 essid[0].id = IEEE80211_ELEMID_SSID;
 4666                 essid[0].len = ss->ss_ssid[0].len;
 4667                 memcpy(essid[0].data, ss->ss_ssid[0].ssid, ss->ss_ssid[0].len);
 4668         }
 4669 
 4670         /*
 4671          * Build a probe request frame.  Most of the following code is a
 4672          * copy & paste of what is done in net80211.
 4673          */
 4674         wh = (struct ieee80211_frame *)(essid + 20);
 4675         wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT |
 4676             IEEE80211_FC0_SUBTYPE_PROBE_REQ;
 4677         wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
 4678         IEEE80211_ADDR_COPY(wh->i_addr1, ifp->if_broadcastaddr);
 4679         IEEE80211_ADDR_COPY(wh->i_addr2, IF_LLADDR(ifp));
 4680         IEEE80211_ADDR_COPY(wh->i_addr3, ifp->if_broadcastaddr);
 4681         *(uint16_t *)&wh->i_dur[0] = 0; /* filled by HW */
 4682         *(uint16_t *)&wh->i_seq[0] = 0; /* filled by HW */
 4683 
 4684         frm = (uint8_t *)(wh + 1);
 4685 
 4686         /* Add SSID IE. */
 4687         *frm++ = IEEE80211_ELEMID_SSID;
 4688         *frm++ = ss->ss_ssid[0].len;
 4689         memcpy(frm, ss->ss_ssid[0].ssid, ss->ss_ssid[0].len);
 4690         frm += ss->ss_ssid[0].len;
 4691 
 4692         /* Add supported rates IE. */
 4693         *frm++ = IEEE80211_ELEMID_RATES;
 4694         nrates = rs->rs_nrates;
 4695         if (nrates > IEEE80211_RATE_SIZE)
 4696                 nrates = IEEE80211_RATE_SIZE;
 4697         *frm++ = nrates;
 4698         memcpy(frm, rs->rs_rates, nrates);
 4699         frm += nrates;
 4700 
 4701         /* Add supported xrates IE. */
 4702         if (rs->rs_nrates > IEEE80211_RATE_SIZE) {
 4703                 nrates = rs->rs_nrates - IEEE80211_RATE_SIZE;
 4704                 *frm++ = IEEE80211_ELEMID_XRATES;
 4705                 *frm++ = (uint8_t)nrates;
 4706                 memcpy(frm, rs->rs_rates + IEEE80211_RATE_SIZE, nrates);
 4707                 frm += nrates;
 4708         }
 4709 
 4710         /* Set length of probe request. */
 4711         tx->len = htole16(frm - (uint8_t *)wh);
 4712 
 4713         c = ic->ic_curchan;
 4714         chan = (struct iwn_scan_chan *)frm;
 4715         chan->chan = htole16(ieee80211_chan2ieee(ic, c));
 4716         chan->flags = 0;
 4717         if (ss->ss_nssid > 0)
 4718                 chan->flags |= htole32(IWN_CHAN_NPBREQS(1));
 4719         chan->dsp_gain = 0x6e;
 4720         if (IEEE80211_IS_CHAN_5GHZ(c) &&
 4721             !(c->ic_flags & IEEE80211_CHAN_PASSIVE)) {
 4722                 chan->rf_gain = 0x3b;
 4723                 chan->active  = htole16(24);
 4724                 chan->passive = htole16(110);
 4725                 chan->flags |= htole32(IWN_CHAN_ACTIVE);
 4726         } else if (IEEE80211_IS_CHAN_5GHZ(c)) {
 4727                 chan->rf_gain = 0x3b;
 4728                 chan->active  = htole16(24);
 4729                 if (sc->rxon.associd)
 4730                         chan->passive = htole16(78);
 4731                 else
 4732                         chan->passive = htole16(110);
 4733                 hdr->crc_threshold = 0xffff;
 4734         } else if (!(c->ic_flags & IEEE80211_CHAN_PASSIVE)) {
 4735                 chan->rf_gain = 0x28;
 4736                 chan->active  = htole16(36);
 4737                 chan->passive = htole16(120);
 4738                 chan->flags |= htole32(IWN_CHAN_ACTIVE);
 4739         } else {
 4740                 chan->rf_gain = 0x28;
 4741                 chan->active  = htole16(36);
 4742                 if (sc->rxon.associd)
 4743                         chan->passive = htole16(88);
 4744                 else
 4745                         chan->passive = htole16(120);
 4746                 hdr->crc_threshold = 0xffff;
 4747         }
 4748 
 4749         DPRINTF(sc, IWN_DEBUG_STATE,
 4750             "%s: chan %u flags 0x%x rf_gain 0x%x "
 4751             "dsp_gain 0x%x active 0x%x passive 0x%x\n", __func__,
 4752             chan->chan, chan->flags, chan->rf_gain, chan->dsp_gain,
 4753             chan->active, chan->passive);
 4754 
 4755         hdr->nchan++;
 4756         chan++;
 4757         buflen = (uint8_t *)chan - buf;
 4758         hdr->len = htole16(buflen);
 4759 
 4760         DPRINTF(sc, IWN_DEBUG_STATE, "sending scan command nchan=%d\n",
 4761             hdr->nchan);
 4762         error = iwn_cmd(sc, IWN_CMD_SCAN, buf, buflen, 1);
 4763         free(buf, M_DEVBUF);
 4764         return error;
 4765 }
 4766 
 4767 static int
 4768 iwn_auth(struct iwn_softc *sc, struct ieee80211vap *vap)
 4769 {
 4770         const struct iwn_hal *hal = sc->sc_hal;
 4771         struct ifnet *ifp = sc->sc_ifp;
 4772         struct ieee80211com *ic = ifp->if_l2com;
 4773         struct ieee80211_node *ni = vap->iv_bss;
 4774         int error;
 4775 
 4776         sc->calib.state = IWN_CALIB_STATE_INIT;
 4777 
 4778         /* Update adapter configuration. */
 4779         IEEE80211_ADDR_COPY(sc->rxon.bssid, ni->ni_bssid);
 4780         sc->rxon.chan = htole16(ieee80211_chan2ieee(ic, ni->ni_chan));
 4781         sc->rxon.flags = htole32(IWN_RXON_TSF | IWN_RXON_CTS_TO_SELF);
 4782         if (IEEE80211_IS_CHAN_2GHZ(ni->ni_chan))
 4783                 sc->rxon.flags |= htole32(IWN_RXON_AUTO | IWN_RXON_24GHZ);
 4784         if (ic->ic_flags & IEEE80211_F_SHSLOT)
 4785                 sc->rxon.flags |= htole32(IWN_RXON_SHSLOT);
 4786         if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)
 4787                 sc->rxon.flags |= htole32(IWN_RXON_SHPREAMBLE);
 4788         if (IEEE80211_IS_CHAN_A(ni->ni_chan)) {
 4789                 sc->rxon.cck_mask  = 0;
 4790                 sc->rxon.ofdm_mask = 0x15;
 4791         } else if (IEEE80211_IS_CHAN_B(ni->ni_chan)) {
 4792                 sc->rxon.cck_mask  = 0x03;
 4793                 sc->rxon.ofdm_mask = 0;
 4794         } else {
 4795                 /* XXX assume 802.11b/g */
 4796                 sc->rxon.cck_mask  = 0x0f;
 4797                 sc->rxon.ofdm_mask = 0x15;
 4798         }
 4799         DPRINTF(sc, IWN_DEBUG_STATE,
 4800             "%s: config chan %d mode %d flags 0x%x cck 0x%x ofdm 0x%x "
 4801             "ht_single 0x%x ht_dual 0x%x rxchain 0x%x "
 4802             "myaddr %6D wlap %6D bssid %6D associd %d filter 0x%x\n",
 4803             __func__,
 4804             le16toh(sc->rxon.chan), sc->rxon.mode, le32toh(sc->rxon.flags),
 4805             sc->rxon.cck_mask, sc->rxon.ofdm_mask,
 4806             sc->rxon.ht_single_mask, sc->rxon.ht_dual_mask,
 4807             le16toh(sc->rxon.rxchain),
 4808             sc->rxon.myaddr, ":", sc->rxon.wlap, ":", sc->rxon.bssid, ":",
 4809             le16toh(sc->rxon.associd), le32toh(sc->rxon.filter));
 4810         error = iwn_cmd(sc, IWN_CMD_RXON, &sc->rxon, hal->rxonsz, 1);
 4811         if (error != 0) {
 4812                 device_printf(sc->sc_dev,
 4813                     "%s: RXON command failed, error %d\n", __func__, error);
 4814                 return error;
 4815         }
 4816 
 4817         /* Configuration has changed, set TX power accordingly. */
 4818         error = hal->set_txpower(sc, ni->ni_chan, 1);
 4819         if (error != 0) {
 4820                 device_printf(sc->sc_dev,
 4821                     "%s: could not set Tx power, error %d\n", __func__, error);
 4822                 return error;
 4823         }
 4824         /*
 4825          * Reconfiguring RXON clears the firmware nodes table so we must
 4826          * add the broadcast node again.
 4827          */
 4828         error = iwn_add_broadcast_node(sc, 1);
 4829         if (error != 0) {
 4830                 device_printf(sc->sc_dev,
 4831                     "%s: could not add broadcast node, error %d\n",
 4832                     __func__, error);
 4833                 return error;
 4834         }
 4835         return 0;
 4836 }
 4837 
 4838 /*
 4839  * Configure the adapter for associated state.
 4840  */
 4841 static int
 4842 iwn_run(struct iwn_softc *sc, struct ieee80211vap *vap)
 4843 {
 4844 #define MS(v,x) (((v) & x) >> x##_S)
 4845         const struct iwn_hal *hal = sc->sc_hal;
 4846         struct ifnet *ifp = sc->sc_ifp;
 4847         struct ieee80211com *ic = ifp->if_l2com;
 4848         struct ieee80211_node *ni = vap->iv_bss;
 4849         struct iwn_node_info node;
 4850         int error;
 4851 
 4852         sc->calib.state = IWN_CALIB_STATE_INIT;
 4853 
 4854         if (ic->ic_opmode == IEEE80211_M_MONITOR) {
 4855                 /* Link LED blinks while monitoring. */
 4856                 iwn_set_led(sc, IWN_LED_LINK, 5, 5);
 4857                 return 0;
 4858         }
 4859         error = iwn_set_timing(sc, ni);
 4860         if (error != 0) {
 4861                 device_printf(sc->sc_dev,
 4862                     "%s: could not set timing, error %d\n", __func__, error);
 4863                 return error;
 4864         }
 4865 
 4866         /* Update adapter configuration. */
 4867         IEEE80211_ADDR_COPY(sc->rxon.bssid, ni->ni_bssid);
 4868         sc->rxon.chan = htole16(ieee80211_chan2ieee(ic, ni->ni_chan));
 4869         sc->rxon.associd = htole16(IEEE80211_AID(ni->ni_associd));
 4870         /* Short preamble and slot time are negotiated when associating. */
 4871         sc->rxon.flags &= ~htole32(IWN_RXON_SHPREAMBLE | IWN_RXON_SHSLOT);
 4872         sc->rxon.flags |= htole32(IWN_RXON_TSF | IWN_RXON_CTS_TO_SELF);
 4873         if (IEEE80211_IS_CHAN_2GHZ(ni->ni_chan))
 4874                 sc->rxon.flags |= htole32(IWN_RXON_AUTO | IWN_RXON_24GHZ);
 4875         else
 4876                 sc->rxon.flags &= ~htole32(IWN_RXON_AUTO | IWN_RXON_24GHZ);
 4877         if (ic->ic_flags & IEEE80211_F_SHSLOT)
 4878                 sc->rxon.flags |= htole32(IWN_RXON_SHSLOT);
 4879         if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)
 4880                 sc->rxon.flags |= htole32(IWN_RXON_SHPREAMBLE);
 4881         if (IEEE80211_IS_CHAN_A(ni->ni_chan)) {
 4882                 sc->rxon.cck_mask  = 0;
 4883                 sc->rxon.ofdm_mask = 0x15;
 4884         } else if (IEEE80211_IS_CHAN_B(ni->ni_chan)) {
 4885                 sc->rxon.cck_mask  = 0x03;
 4886                 sc->rxon.ofdm_mask = 0;
 4887         } else {
 4888                 /* XXX assume 802.11b/g */
 4889                 sc->rxon.cck_mask  = 0x0f;
 4890                 sc->rxon.ofdm_mask = 0x15;
 4891         }
 4892 #if 0   /* HT */
 4893         if (IEEE80211_IS_CHAN_HT(ni->ni_chan)) {
 4894                 sc->rxon.flags &= ~htole32(IWN_RXON_HT);
 4895                 if (IEEE80211_IS_CHAN_HT40U(ni->ni_chan))
 4896                         sc->rxon.flags |= htole32(IWN_RXON_HT40U);
 4897                 else if (IEEE80211_IS_CHAN_HT40D(ni->ni_chan))
 4898                         sc->rxon.flags |= htole32(IWN_RXON_HT40D);
 4899                 else
 4900                         sc->rxon.flags |= htole32(IWN_RXON_HT20);
 4901                 sc->rxon.rxchain = htole16(
 4902                           IWN_RXCHAIN_VALID(3)
 4903                         | IWN_RXCHAIN_MIMO_COUNT(3)
 4904                         | IWN_RXCHAIN_IDLE_COUNT(1)
 4905                         | IWN_RXCHAIN_MIMO_FORCE);
 4906 
 4907                 maxrxampdu = MS(ni->ni_htparam, IEEE80211_HTCAP_MAXRXAMPDU);
 4908                 ampdudensity = MS(ni->ni_htparam, IEEE80211_HTCAP_MPDUDENSITY);
 4909         } else
 4910                 maxrxampdu = ampdudensity = 0;
 4911 #endif
 4912         sc->rxon.filter |= htole32(IWN_FILTER_BSS);
 4913 
 4914         DPRINTF(sc, IWN_DEBUG_STATE,
 4915             "%s: config chan %d mode %d flags 0x%x cck 0x%x ofdm 0x%x "
 4916             "ht_single 0x%x ht_dual 0x%x rxchain 0x%x "
 4917             "myaddr %6D wlap %6D bssid %6D associd %d filter 0x%x\n",
 4918             __func__,
 4919             le16toh(sc->rxon.chan), sc->rxon.mode, le32toh(sc->rxon.flags),
 4920             sc->rxon.cck_mask, sc->rxon.ofdm_mask,
 4921             sc->rxon.ht_single_mask, sc->rxon.ht_dual_mask,
 4922             le16toh(sc->rxon.rxchain),
 4923             sc->rxon.myaddr, ":", sc->rxon.wlap, ":", sc->rxon.bssid, ":",
 4924             le16toh(sc->rxon.associd), le32toh(sc->rxon.filter));
 4925         error = iwn_cmd(sc, IWN_CMD_RXON, &sc->rxon, hal->rxonsz, 1);
 4926         if (error != 0) {
 4927                 device_printf(sc->sc_dev,
 4928                     "%s: could not update configuration, error %d\n",
 4929                     __func__, error);
 4930                 return error;
 4931         }
 4932 
 4933         /* Configuration has changed, set TX power accordingly. */
 4934         error = hal->set_txpower(sc, ni->ni_chan, 1);
 4935         if (error != 0) {
 4936                 device_printf(sc->sc_dev,
 4937                     "%s: could not set Tx power, error %d\n", __func__, error);
 4938                 return error;
 4939         }
 4940 
 4941         /* Add BSS node. */
 4942         memset(&node, 0, sizeof node);
 4943         IEEE80211_ADDR_COPY(node.macaddr, ni->ni_macaddr);
 4944         node.id = IWN_ID_BSS;
 4945 #ifdef notyet
 4946         node.htflags = htole32(IWN_AMDPU_SIZE_FACTOR(3) |
 4947             IWN_AMDPU_DENSITY(5));      /* 2us */
 4948 #endif
 4949         DPRINTF(sc, IWN_DEBUG_STATE, "%s: add BSS node, id %d htflags 0x%x\n",
 4950             __func__, node.id, le32toh(node.htflags));
 4951         error = hal->add_node(sc, &node, 1);
 4952         if (error != 0) {
 4953                 device_printf(sc->sc_dev, "could not add BSS node\n");
 4954                 return error;
 4955         }
 4956         DPRINTF(sc, IWN_DEBUG_STATE, "setting link quality for node %d\n",
 4957             node.id);
 4958         error = iwn_set_link_quality(sc, node.id, 1);
 4959         if (error != 0) {
 4960                 device_printf(sc->sc_dev,
 4961                     "%s: could not setup MRR for node %d, error %d\n",
 4962                     __func__, node.id, error);
 4963                 return error;
 4964         }
 4965 
 4966         error = iwn_init_sensitivity(sc);
 4967         if (error != 0) {
 4968                 device_printf(sc->sc_dev,
 4969                     "%s: could not set sensitivity, error %d\n",
 4970                     __func__, error);
 4971                 return error;
 4972         }
 4973 
 4974         /* Start periodic calibration timer. */
 4975         sc->calib.state = IWN_CALIB_STATE_ASSOC;
 4976         iwn_calib_reset(sc);
 4977 
 4978         /* Link LED always on while associated. */
 4979         iwn_set_led(sc, IWN_LED_LINK, 0, 1);
 4980 
 4981         return 0;
 4982 #undef MS
 4983 }
 4984 
 4985 #if 0   /* HT */
 4986 /*
 4987  * This function is called by upper layer when an ADDBA request is received
 4988  * from another STA and before the ADDBA response is sent.
 4989  */
 4990 static int
 4991 iwn_ampdu_rx_start(struct ieee80211com *ic, struct ieee80211_node *ni,
 4992     uint8_t tid)
 4993 {
 4994         struct ieee80211_rx_ba *ba = &ni->ni_rx_ba[tid];
 4995         struct iwn_softc *sc = ic->ic_softc;
 4996         struct iwn_node *wn = (void *)ni;
 4997         struct iwn_node_info node;
 4998 
 4999         memset(&node, 0, sizeof node);
 5000         node.id = wn->id;
 5001         node.control = IWN_NODE_UPDATE;
 5002         node.flags = IWN_FLAG_SET_ADDBA;
 5003         node.addba_tid = tid;
 5004         node.addba_ssn = htole16(ba->ba_winstart);
 5005         DPRINTF(sc, IWN_DEBUG_RECV, "ADDBA RA=%d TID=%d SSN=%d\n",
 5006             wn->id, tid, ba->ba_winstart));
 5007         return sc->sc_hal->add_node(sc, &node, 1);
 5008 }
 5009 
 5010 /*
 5011  * This function is called by upper layer on teardown of an HT-immediate
 5012  * Block Ack agreement (eg. uppon receipt of a DELBA frame.)
 5013  */
 5014 static void
 5015 iwn_ampdu_rx_stop(struct ieee80211com *ic, struct ieee80211_node *ni,
 5016     uint8_t tid)
 5017 {
 5018         struct iwn_softc *sc = ic->ic_softc;
 5019         struct iwn_node *wn = (void *)ni;
 5020         struct iwn_node_info node;
 5021 
 5022         memset(&node, 0, sizeof node);
 5023         node.id = wn->id;
 5024         node.control = IWN_NODE_UPDATE;
 5025         node.flags = IWN_FLAG_SET_DELBA;
 5026         node.delba_tid = tid;
 5027         DPRINTF(sc, IWN_DEBUG_RECV, "DELBA RA=%d TID=%d\n", wn->id, tid);
 5028         (void)sc->sc_hal->add_node(sc, &node, 1);
 5029 }
 5030 
 5031 /*
 5032  * This function is called by upper layer when an ADDBA response is received
 5033  * from another STA.
 5034  */
 5035 static int
 5036 iwn_ampdu_tx_start(struct ieee80211com *ic, struct ieee80211_node *ni,
 5037     uint8_t tid)
 5038 {
 5039         struct ieee80211_tx_ba *ba = &ni->ni_tx_ba[tid];
 5040         struct iwn_softc *sc = ic->ic_softc;
 5041         const struct iwn_hal *hal = sc->sc_hal;
 5042         struct iwn_node *wn = (void *)ni;
 5043         struct iwn_node_info node;
 5044         int error;
 5045 
 5046         /* Enable TX for the specified RA/TID. */
 5047         wn->disable_tid &= ~(1 << tid);
 5048         memset(&node, 0, sizeof node);
 5049         node.id = wn->id;
 5050         node.control = IWN_NODE_UPDATE;
 5051         node.flags = IWN_FLAG_SET_DISABLE_TID;
 5052         node.disable_tid = htole16(wn->disable_tid);
 5053         error = hal->add_node(sc, &node, 1);
 5054         if (error != 0)
 5055                 return error;
 5056 
 5057         if ((error = iwn_nic_lock(sc)) != 0)
 5058                 return error;
 5059         hal->ampdu_tx_start(sc, ni, tid, ba->ba_winstart);
 5060         iwn_nic_unlock(sc);
 5061         return 0;
 5062 }
 5063 
 5064 static void
 5065 iwn_ampdu_tx_stop(struct ieee80211com *ic, struct ieee80211_node *ni,
 5066     uint8_t tid)
 5067 {
 5068         struct ieee80211_tx_ba *ba = &ni->ni_tx_ba[tid];
 5069         struct iwn_softc *sc = ic->ic_softc;
 5070         int error;
 5071 
 5072         error = iwn_nic_lock(sc);
 5073         if (error != 0)
 5074                 return;
 5075         sc->sc_hal->ampdu_tx_stop(sc, tid, ba->ba_winstart);
 5076         iwn_nic_unlock(sc);
 5077 }
 5078 
 5079 static void
 5080 iwn4965_ampdu_tx_start(struct iwn_softc *sc, struct ieee80211_node *ni,
 5081     uint8_t tid, uint16_t ssn)
 5082 {
 5083         struct iwn_node *wn = (void *)ni;
 5084         int qid = 7 + tid;
 5085 
 5086         /* Stop TX scheduler while we're changing its configuration. */
 5087         iwn_prph_write(sc, IWN4965_SCHED_QUEUE_STATUS(qid),
 5088             IWN4965_TXQ_STATUS_CHGACT);
 5089 
 5090         /* Assign RA/TID translation to the queue. */
 5091         iwn_mem_write_2(sc, sc->sched_base + IWN4965_SCHED_TRANS_TBL(qid),
 5092             wn->id << 4 | tid);
 5093 
 5094         /* Enable chain-building mode for the queue. */
 5095         iwn_prph_setbits(sc, IWN4965_SCHED_QCHAIN_SEL, 1 << qid);
 5096 
 5097         /* Set starting sequence number from the ADDBA request. */
 5098         IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, qid << 8 | (ssn & 0xff));
 5099         iwn_prph_write(sc, IWN4965_SCHED_QUEUE_RDPTR(qid), ssn);
 5100 
 5101         /* Set scheduler window size. */
 5102         iwn_mem_write(sc, sc->sched_base + IWN4965_SCHED_QUEUE_OFFSET(qid),
 5103             IWN_SCHED_WINSZ);
 5104         /* Set scheduler frame limit. */
 5105         iwn_mem_write(sc, sc->sched_base + IWN4965_SCHED_QUEUE_OFFSET(qid) + 4,
 5106             IWN_SCHED_LIMIT << 16);
 5107 
 5108         /* Enable interrupts for the queue. */
 5109         iwn_prph_setbits(sc, IWN4965_SCHED_INTR_MASK, 1 << qid);
 5110 
 5111         /* Mark the queue as active. */
 5112         iwn_prph_write(sc, IWN4965_SCHED_QUEUE_STATUS(qid),
 5113             IWN4965_TXQ_STATUS_ACTIVE | IWN4965_TXQ_STATUS_AGGR_ENA |
 5114             iwn_tid2fifo[tid] << 1);
 5115 }
 5116 
 5117 static void
 5118 iwn4965_ampdu_tx_stop(struct iwn_softc *sc, uint8_t tid, uint16_t ssn)
 5119 {
 5120         int qid = 7 + tid;
 5121 
 5122         /* Stop TX scheduler while we're changing its configuration. */
 5123         iwn_prph_write(sc, IWN4965_SCHED_QUEUE_STATUS(qid),
 5124             IWN4965_TXQ_STATUS_CHGACT);
 5125 
 5126         /* Set starting sequence number from the ADDBA request. */
 5127         IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, qid << 8 | (ssn & 0xff));
 5128         iwn_prph_write(sc, IWN4965_SCHED_QUEUE_RDPTR(qid), ssn);
 5129 
 5130         /* Disable interrupts for the queue. */
 5131         iwn_prph_clrbits(sc, IWN4965_SCHED_INTR_MASK, 1 << qid);
 5132 
 5133         /* Mark the queue as inactive. */
 5134         iwn_prph_write(sc, IWN4965_SCHED_QUEUE_STATUS(qid),
 5135             IWN4965_TXQ_STATUS_INACTIVE | iwn_tid2fifo[tid] << 1);
 5136 }
 5137 
 5138 static void
 5139 iwn5000_ampdu_tx_start(struct iwn_softc *sc, struct ieee80211_node *ni,
 5140     uint8_t tid, uint16_t ssn)
 5141 {
 5142         struct iwn_node *wn = (void *)ni;
 5143         int qid = 10 + tid;
 5144 
 5145         /* Stop TX scheduler while we're changing its configuration. */
 5146         iwn_prph_write(sc, IWN5000_SCHED_QUEUE_STATUS(qid),
 5147             IWN5000_TXQ_STATUS_CHGACT);
 5148 
 5149         /* Assign RA/TID translation to the queue. */
 5150         iwn_mem_write_2(sc, sc->sched_base + IWN5000_SCHED_TRANS_TBL(qid),
 5151             wn->id << 4 | tid);
 5152 
 5153         /* Enable chain-building mode for the queue. */
 5154         iwn_prph_setbits(sc, IWN5000_SCHED_QCHAIN_SEL, 1 << qid);
 5155 
 5156         /* Enable aggregation for the queue. */
 5157         iwn_prph_setbits(sc, IWN5000_SCHED_AGGR_SEL, 1 << qid);
 5158 
 5159         /* Set starting sequence number from the ADDBA request. */
 5160         IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, qid << 8 | (ssn & 0xff));
 5161         iwn_prph_write(sc, IWN5000_SCHED_QUEUE_RDPTR(qid), ssn);
 5162 
 5163         /* Set scheduler window size and frame limit. */
 5164         iwn_mem_write(sc, sc->sched_base + IWN5000_SCHED_QUEUE_OFFSET(qid) + 4,
 5165             IWN_SCHED_LIMIT << 16 | IWN_SCHED_WINSZ);
 5166 
 5167         /* Enable interrupts for the queue. */
 5168         iwn_prph_setbits(sc, IWN5000_SCHED_INTR_MASK, 1 << qid);
 5169 
 5170         /* Mark the queue as active. */
 5171         iwn_prph_write(sc, IWN5000_SCHED_QUEUE_STATUS(qid),
 5172             IWN5000_TXQ_STATUS_ACTIVE | iwn_tid2fifo[tid]);
 5173 }
 5174 
 5175 static void
 5176 iwn5000_ampdu_tx_stop(struct iwn_softc *sc, uint8_t tid, uint16_t ssn)
 5177 {
 5178         int qid = 10 + tid;
 5179 
 5180         /* Stop TX scheduler while we're changing its configuration. */
 5181         iwn_prph_write(sc, IWN5000_SCHED_QUEUE_STATUS(qid),
 5182             IWN5000_TXQ_STATUS_CHGACT);
 5183 
 5184         /* Disable aggregation for the queue. */
 5185         iwn_prph_clrbits(sc, IWN5000_SCHED_AGGR_SEL, 1 << qid);
 5186 
 5187         /* Set starting sequence number from the ADDBA request. */
 5188         IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, qid << 8 | (ssn & 0xff));
 5189         iwn_prph_write(sc, IWN5000_SCHED_QUEUE_RDPTR(qid), ssn);
 5190 
 5191         /* Disable interrupts for the queue. */
 5192         iwn_prph_clrbits(sc, IWN5000_SCHED_INTR_MASK, 1 << qid);
 5193 
 5194         /* Mark the queue as inactive. */
 5195         iwn_prph_write(sc, IWN5000_SCHED_QUEUE_STATUS(qid),
 5196             IWN5000_TXQ_STATUS_INACTIVE | iwn_tid2fifo[tid]);
 5197 }
 5198 #endif
 5199 
 5200 /*
 5201  * Query calibration tables from the initialization firmware.  We do this
 5202  * only once at first boot.  Called from a process context.
 5203  */
 5204 static int
 5205 iwn5000_query_calibration(struct iwn_softc *sc)
 5206 {
 5207         struct iwn5000_calib_config cmd;
 5208         int error;
 5209 
 5210         memset(&cmd, 0, sizeof cmd);
 5211         cmd.ucode.once.enable = 0xffffffff;
 5212         cmd.ucode.once.start  = 0xffffffff;
 5213         cmd.ucode.once.send   = 0xffffffff;
 5214         cmd.ucode.flags       = 0xffffffff;
 5215         DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: sending calibration query\n",
 5216             __func__);
 5217         error = iwn_cmd(sc, IWN5000_CMD_CALIB_CONFIG, &cmd, sizeof cmd, 0);
 5218         if (error != 0)
 5219                 return error;
 5220 
 5221         /* Wait at most two seconds for calibration to complete. */
 5222         if (!(sc->sc_flags & IWN_FLAG_CALIB_DONE))
 5223                 error = msleep(sc, &sc->sc_mtx, PCATCH, "iwninit", 2 * hz);
 5224         return error;
 5225 }
 5226 
 5227 /*
 5228  * Send calibration results to the runtime firmware.  These results were
 5229  * obtained on first boot from the initialization firmware.
 5230  */
 5231 static int
 5232 iwn5000_send_calibration(struct iwn_softc *sc)
 5233 {
 5234         int idx, error;
 5235 
 5236         for (idx = 0; idx < 5; idx++) {
 5237                 if (sc->calibcmd[idx].buf == NULL)
 5238                         continue;       /* No results available. */
 5239                 DPRINTF(sc, IWN_DEBUG_CALIBRATE,
 5240                     "send calibration result idx=%d len=%d\n",
 5241                     idx, sc->calibcmd[idx].len);
 5242                 error = iwn_cmd(sc, IWN_CMD_PHY_CALIB, sc->calibcmd[idx].buf,
 5243                     sc->calibcmd[idx].len, 0);
 5244                 if (error != 0) {
 5245                         device_printf(sc->sc_dev,
 5246                             "%s: could not send calibration result, error %d\n",
 5247                             __func__, error);
 5248                         return error;
 5249                 }
 5250         }
 5251         return 0;
 5252 }
 5253 
 5254 static int
 5255 iwn5000_send_wimax_coex(struct iwn_softc *sc)
 5256 {
 5257         struct iwn5000_wimax_coex wimax;
 5258 
 5259 #ifdef notyet
 5260         if (sc->hw_type == IWN_HW_REV_TYPE_6050) {
 5261                 /* Enable WiMAX coexistence for combo adapters. */
 5262                 wimax.flags =
 5263                     IWN_WIMAX_COEX_ASSOC_WA_UNMASK |
 5264                     IWN_WIMAX_COEX_UNASSOC_WA_UNMASK |
 5265                     IWN_WIMAX_COEX_STA_TABLE_VALID |
 5266                     IWN_WIMAX_COEX_ENABLE;
 5267                 memcpy(wimax.events, iwn6050_wimax_events,
 5268                     sizeof iwn6050_wimax_events);
 5269         } else
 5270 #endif
 5271         {
 5272                 /* Disable WiMAX coexistence. */
 5273                 wimax.flags = 0;
 5274                 memset(wimax.events, 0, sizeof wimax.events);
 5275         }
 5276         DPRINTF(sc, IWN_DEBUG_RESET, "%s: Configuring WiMAX coexistence\n",
 5277             __func__);
 5278         return iwn_cmd(sc, IWN5000_CMD_WIMAX_COEX, &wimax, sizeof wimax, 0);
 5279 }
 5280 
 5281 /*
 5282  * This function is called after the runtime firmware notifies us of its
 5283  * readiness (called in a process context.)
 5284  */
 5285 static int
 5286 iwn4965_post_alive(struct iwn_softc *sc)
 5287 {
 5288         int error, qid;
 5289 
 5290         if ((error = iwn_nic_lock(sc)) != 0)
 5291                 return error;
 5292 
 5293         /* Clear TX scheduler state in SRAM. */
 5294         sc->sched_base = iwn_prph_read(sc, IWN_SCHED_SRAM_ADDR);
 5295         iwn_mem_set_region_4(sc, sc->sched_base + IWN4965_SCHED_CTX_OFF, 0,
 5296             IWN4965_SCHED_CTX_LEN / sizeof (uint32_t));
 5297 
 5298         /* Set physical address of TX scheduler rings (1KB aligned.) */
 5299         iwn_prph_write(sc, IWN4965_SCHED_DRAM_ADDR, sc->sched_dma.paddr >> 10);
 5300 
 5301         IWN_SETBITS(sc, IWN_FH_TX_CHICKEN, IWN_FH_TX_CHICKEN_SCHED_RETRY);
 5302 
 5303         /* Disable chain mode for all our 16 queues. */
 5304         iwn_prph_write(sc, IWN4965_SCHED_QCHAIN_SEL, 0);
 5305 
 5306         for (qid = 0; qid < IWN4965_NTXQUEUES; qid++) {
 5307                 iwn_prph_write(sc, IWN4965_SCHED_QUEUE_RDPTR(qid), 0);
 5308                 IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, qid << 8 | 0);
 5309 
 5310                 /* Set scheduler window size. */
 5311                 iwn_mem_write(sc, sc->sched_base +
 5312                     IWN4965_SCHED_QUEUE_OFFSET(qid), IWN_SCHED_WINSZ);
 5313                 /* Set scheduler frame limit. */
 5314                 iwn_mem_write(sc, sc->sched_base +
 5315                     IWN4965_SCHED_QUEUE_OFFSET(qid) + 4,
 5316                     IWN_SCHED_LIMIT << 16);
 5317         }
 5318 
 5319         /* Enable interrupts for all our 16 queues. */
 5320         iwn_prph_write(sc, IWN4965_SCHED_INTR_MASK, 0xffff);
 5321         /* Identify TX FIFO rings (0-7). */
 5322         iwn_prph_write(sc, IWN4965_SCHED_TXFACT, 0xff);
 5323 
 5324         /* Mark TX rings (4 EDCA + cmd + 2 HCCA) as active. */
 5325         for (qid = 0; qid < 7; qid++) {
 5326                 static uint8_t qid2fifo[] = { 3, 2, 1, 0, 4, 5, 6 };
 5327                 iwn_prph_write(sc, IWN4965_SCHED_QUEUE_STATUS(qid),
 5328                     IWN4965_TXQ_STATUS_ACTIVE | qid2fifo[qid] << 1);
 5329         }
 5330         iwn_nic_unlock(sc);
 5331         return 0;
 5332 }
 5333 
 5334 /*
 5335  * This function is called after the initialization or runtime firmware
 5336  * notifies us of its readiness (called in a process context.)
 5337  */
 5338 static int
 5339 iwn5000_post_alive(struct iwn_softc *sc)
 5340 {
 5341         int error, qid;
 5342 
 5343         /* Switch to using ICT interrupt mode. */
 5344         iwn5000_ict_reset(sc);
 5345 
 5346         error = iwn_nic_lock(sc);
 5347         if (error != 0)
 5348                 return error;
 5349 
 5350         /* Clear TX scheduler state in SRAM. */
 5351         sc->sched_base = iwn_prph_read(sc, IWN_SCHED_SRAM_ADDR);
 5352         iwn_mem_set_region_4(sc, sc->sched_base + IWN5000_SCHED_CTX_OFF, 0,
 5353             IWN5000_SCHED_CTX_LEN / sizeof (uint32_t));
 5354 
 5355         /* Set physical address of TX scheduler rings (1KB aligned.) */
 5356         iwn_prph_write(sc, IWN5000_SCHED_DRAM_ADDR, sc->sched_dma.paddr >> 10);
 5357 
 5358         IWN_SETBITS(sc, IWN_FH_TX_CHICKEN, IWN_FH_TX_CHICKEN_SCHED_RETRY);
 5359 
 5360         /* Enable chain mode for all queues, except command queue. */
 5361         iwn_prph_write(sc, IWN5000_SCHED_QCHAIN_SEL, 0xfffef);
 5362         iwn_prph_write(sc, IWN5000_SCHED_AGGR_SEL, 0);
 5363 
 5364         for (qid = 0; qid < IWN5000_NTXQUEUES; qid++) {
 5365                 iwn_prph_write(sc, IWN5000_SCHED_QUEUE_RDPTR(qid), 0);
 5366                 IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, qid << 8 | 0);
 5367 
 5368                 iwn_mem_write(sc, sc->sched_base +
 5369                     IWN5000_SCHED_QUEUE_OFFSET(qid), 0);
 5370                 /* Set scheduler window size and frame limit. */
 5371                 iwn_mem_write(sc, sc->sched_base +
 5372                     IWN5000_SCHED_QUEUE_OFFSET(qid) + 4,
 5373                     IWN_SCHED_LIMIT << 16 | IWN_SCHED_WINSZ);
 5374         }
 5375 
 5376         /* Enable interrupts for all our 20 queues. */
 5377         iwn_prph_write(sc, IWN5000_SCHED_INTR_MASK, 0xfffff);
 5378         /* Identify TX FIFO rings (0-7). */
 5379         iwn_prph_write(sc, IWN5000_SCHED_TXFACT, 0xff);
 5380 
 5381         /* Mark TX rings (4 EDCA + cmd + 2 HCCA) as active. */
 5382         for (qid = 0; qid < 7; qid++) {
 5383                 static uint8_t qid2fifo[] = { 3, 2, 1, 0, 7, 5, 6 };
 5384                 iwn_prph_write(sc, IWN5000_SCHED_QUEUE_STATUS(qid),
 5385                     IWN5000_TXQ_STATUS_ACTIVE | qid2fifo[qid]);
 5386         }
 5387         iwn_nic_unlock(sc);
 5388 
 5389         /* Configure WiMAX coexistence for combo adapters. */
 5390         error = iwn5000_send_wimax_coex(sc);
 5391         if (error != 0) {
 5392                 device_printf(sc->sc_dev,
 5393                     "%s: could not configure WiMAX coexistence, error %d\n",
 5394                     __func__, error);
 5395                 return error;
 5396         }
 5397         if (sc->hw_type != IWN_HW_REV_TYPE_5150) {
 5398                 struct iwn5000_phy_calib_crystal cmd;
 5399 
 5400                 /* Perform crystal calibration. */
 5401                 memset(&cmd, 0, sizeof cmd);
 5402                 cmd.code = IWN5000_PHY_CALIB_CRYSTAL;
 5403                 cmd.ngroups = 1;
 5404                 cmd.isvalid = 1;
 5405                 cmd.cap_pin[0] = le32toh(sc->eeprom_crystal) & 0xff;
 5406                 cmd.cap_pin[1] = (le32toh(sc->eeprom_crystal) >> 16) & 0xff;
 5407                 DPRINTF(sc, IWN_DEBUG_CALIBRATE,
 5408                     "sending crystal calibration %d, %d\n",
 5409                     cmd.cap_pin[0], cmd.cap_pin[1]);
 5410                 error = iwn_cmd(sc, IWN_CMD_PHY_CALIB, &cmd, sizeof cmd, 0);
 5411                 if (error != 0) {
 5412                         device_printf(sc->sc_dev,
 5413                             "%s: crystal calibration failed, error %d\n",
 5414                             __func__, error);
 5415                         return error;
 5416                 }
 5417         }
 5418         if (!(sc->sc_flags & IWN_FLAG_CALIB_DONE)) {
 5419                 /* Query calibration from the initialization firmware. */
 5420                 error = iwn5000_query_calibration(sc);
 5421                 if (error != 0) {
 5422                         device_printf(sc->sc_dev,
 5423                             "%s: could not query calibration, error %d\n",
 5424                             __func__, error);
 5425                         return error;
 5426                 }
 5427                 /*
 5428                  * We have the calibration results now, reboot with the
 5429                  * runtime firmware (call ourselves recursively!)
 5430                  */
 5431                 iwn_hw_stop(sc);
 5432                 error = iwn_hw_init(sc);
 5433         } else {
 5434                 /* Send calibration results to runtime firmware. */
 5435                 error = iwn5000_send_calibration(sc);
 5436         }
 5437         return error;
 5438 }
 5439 
 5440 /*
 5441  * The firmware boot code is small and is intended to be copied directly into
 5442  * the NIC internal memory (no DMA transfer.)
 5443  */
 5444 static int
 5445 iwn4965_load_bootcode(struct iwn_softc *sc, const uint8_t *ucode, int size)
 5446 {
 5447         int error, ntries;
 5448 
 5449         size /= sizeof (uint32_t);
 5450 
 5451         error = iwn_nic_lock(sc);
 5452         if (error != 0)
 5453                 return error;
 5454 
 5455         /* Copy microcode image into NIC memory. */
 5456         iwn_prph_write_region_4(sc, IWN_BSM_SRAM_BASE,
 5457             (const uint32_t *)ucode, size);
 5458 
 5459         iwn_prph_write(sc, IWN_BSM_WR_MEM_SRC, 0);
 5460         iwn_prph_write(sc, IWN_BSM_WR_MEM_DST, IWN_FW_TEXT_BASE);
 5461         iwn_prph_write(sc, IWN_BSM_WR_DWCOUNT, size);
 5462 
 5463         /* Start boot load now. */
 5464         iwn_prph_write(sc, IWN_BSM_WR_CTRL, IWN_BSM_WR_CTRL_START);
 5465 
 5466         /* Wait for transfer to complete. */
 5467         for (ntries = 0; ntries < 1000; ntries++) {
 5468                 if (!(iwn_prph_read(sc, IWN_BSM_WR_CTRL) &
 5469                     IWN_BSM_WR_CTRL_START))
 5470                         break;
 5471                 DELAY(10);
 5472         }
 5473         if (ntries == 1000) {
 5474                 device_printf(sc->sc_dev, "%s: could not load boot firmware\n",
 5475                     __func__);
 5476                 iwn_nic_unlock(sc);
 5477                 return ETIMEDOUT;
 5478         }
 5479 
 5480         /* Enable boot after power up. */
 5481         iwn_prph_write(sc, IWN_BSM_WR_CTRL, IWN_BSM_WR_CTRL_START_EN);
 5482 
 5483         iwn_nic_unlock(sc);
 5484         return 0;
 5485 }
 5486 
 5487 static int
 5488 iwn4965_load_firmware(struct iwn_softc *sc)
 5489 {
 5490         struct iwn_fw_info *fw = &sc->fw;
 5491         struct iwn_dma_info *dma = &sc->fw_dma;
 5492         int error;
 5493 
 5494         /* Copy initialization sections into pre-allocated DMA-safe memory. */
 5495         memcpy(dma->vaddr, fw->init.data, fw->init.datasz);
 5496         bus_dmamap_sync(sc->fw_dma.tag, dma->map, BUS_DMASYNC_PREWRITE);
 5497         memcpy(dma->vaddr + IWN4965_FW_DATA_MAXSZ,
 5498             fw->init.text, fw->init.textsz);
 5499         bus_dmamap_sync(sc->fw_dma.tag, dma->map, BUS_DMASYNC_PREWRITE);
 5500 
 5501         /* Tell adapter where to find initialization sections. */
 5502         error = iwn_nic_lock(sc);
 5503         if (error != 0)
 5504                 return error;
 5505         iwn_prph_write(sc, IWN_BSM_DRAM_DATA_ADDR, dma->paddr >> 4);
 5506         iwn_prph_write(sc, IWN_BSM_DRAM_DATA_SIZE, fw->init.datasz);
 5507         iwn_prph_write(sc, IWN_BSM_DRAM_TEXT_ADDR,
 5508             (dma->paddr + IWN4965_FW_DATA_MAXSZ) >> 4);
 5509         iwn_prph_write(sc, IWN_BSM_DRAM_TEXT_SIZE, fw->init.textsz);
 5510         iwn_nic_unlock(sc);
 5511 
 5512         /* Load firmware boot code. */
 5513         error = iwn4965_load_bootcode(sc, fw->boot.text, fw->boot.textsz);
 5514         if (error != 0) {
 5515                 device_printf(sc->sc_dev, "%s: could not load boot firmware\n",
 5516                     __func__);
 5517                 return error;
 5518         }
 5519         /* Now press "execute". */
 5520         IWN_WRITE(sc, IWN_RESET, 0);
 5521 
 5522         /* Wait at most one second for first alive notification. */
 5523         error = msleep(sc, &sc->sc_mtx, PCATCH, "iwninit", hz);
 5524         if (error) {
 5525                 device_printf(sc->sc_dev,
 5526                     "%s: timeout waiting for adapter to initialize, error %d\n",
 5527                     __func__, error);
 5528                 return error;
 5529         }
 5530 
 5531         /* Retrieve current temperature for initial TX power calibration. */
 5532         sc->rawtemp = sc->ucode_info.temp[3].chan20MHz;
 5533         sc->temp = iwn4965_get_temperature(sc);
 5534 
 5535         /* Copy runtime sections into pre-allocated DMA-safe memory. */
 5536         memcpy(dma->vaddr, fw->main.data, fw->main.datasz);
 5537         bus_dmamap_sync(sc->fw_dma.tag, dma->map, BUS_DMASYNC_PREWRITE);
 5538         memcpy(dma->vaddr + IWN4965_FW_DATA_MAXSZ,
 5539             fw->main.text, fw->main.textsz);
 5540         bus_dmamap_sync(sc->fw_dma.tag, dma->map, BUS_DMASYNC_PREWRITE);
 5541 
 5542         /* Tell adapter where to find runtime sections. */
 5543         error = iwn_nic_lock(sc);
 5544         if (error != 0)
 5545                 return error;
 5546 
 5547         iwn_prph_write(sc, IWN_BSM_DRAM_DATA_ADDR, dma->paddr >> 4);
 5548         iwn_prph_write(sc, IWN_BSM_DRAM_DATA_SIZE, fw->main.datasz);
 5549         iwn_prph_write(sc, IWN_BSM_DRAM_TEXT_ADDR,
 5550             (dma->paddr + IWN4965_FW_DATA_MAXSZ) >> 4);
 5551         iwn_prph_write(sc, IWN_BSM_DRAM_TEXT_SIZE,
 5552             IWN_FW_UPDATED | fw->main.textsz);
 5553         iwn_nic_unlock(sc);
 5554 
 5555         return 0;
 5556 }
 5557 
 5558 static int
 5559 iwn5000_load_firmware_section(struct iwn_softc *sc, uint32_t dst,
 5560     const uint8_t *section, int size)
 5561 {
 5562         struct iwn_dma_info *dma = &sc->fw_dma;
 5563         int error;
 5564 
 5565         /* Copy firmware section into pre-allocated DMA-safe memory. */
 5566         memcpy(dma->vaddr, section, size);
 5567         bus_dmamap_sync(sc->fw_dma.tag, dma->map, BUS_DMASYNC_PREWRITE);
 5568 
 5569         error = iwn_nic_lock(sc);
 5570         if (error != 0)
 5571                 return error;
 5572 
 5573         IWN_WRITE(sc, IWN_FH_TX_CONFIG(IWN_SRVC_DMACHNL),
 5574             IWN_FH_TX_CONFIG_DMA_PAUSE);
 5575 
 5576         IWN_WRITE(sc, IWN_FH_SRAM_ADDR(IWN_SRVC_DMACHNL), dst);
 5577         IWN_WRITE(sc, IWN_FH_TFBD_CTRL0(IWN_SRVC_DMACHNL),
 5578             IWN_LOADDR(dma->paddr));
 5579         IWN_WRITE(sc, IWN_FH_TFBD_CTRL1(IWN_SRVC_DMACHNL),
 5580             IWN_HIADDR(dma->paddr) << 28 | size);
 5581         IWN_WRITE(sc, IWN_FH_TXBUF_STATUS(IWN_SRVC_DMACHNL),
 5582             IWN_FH_TXBUF_STATUS_TBNUM(1) |
 5583             IWN_FH_TXBUF_STATUS_TBIDX(1) |
 5584             IWN_FH_TXBUF_STATUS_TFBD_VALID);
 5585 
 5586         /* Kick Flow Handler to start DMA transfer. */
 5587         IWN_WRITE(sc, IWN_FH_TX_CONFIG(IWN_SRVC_DMACHNL),
 5588             IWN_FH_TX_CONFIG_DMA_ENA | IWN_FH_TX_CONFIG_CIRQ_HOST_ENDTFD);
 5589 
 5590         iwn_nic_unlock(sc);
 5591 
 5592         /* Wait at most five seconds for FH DMA transfer to complete. */
 5593         return msleep(sc, &sc->sc_mtx, PCATCH, "iwninit", hz);
 5594 }
 5595 
 5596 static int
 5597 iwn5000_load_firmware(struct iwn_softc *sc)
 5598 {
 5599         struct iwn_fw_part *fw;
 5600         int error;
 5601 
 5602         /* Load the initialization firmware on first boot only. */
 5603         fw = (sc->sc_flags & IWN_FLAG_CALIB_DONE) ?
 5604             &sc->fw.main : &sc->fw.init;
 5605 
 5606         error = iwn5000_load_firmware_section(sc, IWN_FW_TEXT_BASE,
 5607             fw->text, fw->textsz);
 5608         if (error != 0) {
 5609                 device_printf(sc->sc_dev,
 5610                     "%s: could not load firmware %s section, error %d\n",
 5611                     __func__, ".text", error);
 5612                 return error;
 5613         }
 5614         error = iwn5000_load_firmware_section(sc, IWN_FW_DATA_BASE,
 5615             fw->data, fw->datasz);
 5616         if (error != 0) {
 5617                 device_printf(sc->sc_dev,
 5618                     "%s: could not load firmware %s section, error %d\n",
 5619                     __func__, ".data", error);
 5620                 return error;
 5621         }
 5622 
 5623         /* Now press "execute". */
 5624         IWN_WRITE(sc, IWN_RESET, 0);
 5625         return 0;
 5626 }
 5627 
 5628 static int
 5629 iwn_read_firmware(struct iwn_softc *sc)
 5630 {
 5631         const struct iwn_hal *hal = sc->sc_hal;
 5632         struct iwn_fw_info *fw = &sc->fw;
 5633         const uint32_t *ptr;
 5634         uint32_t rev;
 5635         size_t size;
 5636 
 5637         IWN_UNLOCK(sc);
 5638 
 5639         /* Read firmware image from filesystem. */
 5640         sc->fw_fp = firmware_get(sc->fwname);
 5641         if (sc->fw_fp == NULL) {
 5642                 device_printf(sc->sc_dev,
 5643                     "%s: could not load firmare image \"%s\"\n", __func__,
 5644                     sc->fwname);
 5645                 IWN_LOCK(sc);
 5646                 return EINVAL;
 5647         }
 5648         IWN_LOCK(sc);
 5649 
 5650         size = sc->fw_fp->datasize;
 5651         if (size < 28) {
 5652                 device_printf(sc->sc_dev,
 5653                     "%s: truncated firmware header: %zu bytes\n",
 5654                     __func__, size);
 5655                 return EINVAL;
 5656         }
 5657 
 5658         /* Process firmware header. */
 5659         ptr = (const uint32_t *)sc->fw_fp->data;
 5660         rev = le32toh(*ptr++);
 5661         /* Check firmware API version. */
 5662         if (IWN_FW_API(rev) <= 1) {
 5663                 device_printf(sc->sc_dev,
 5664                     "%s: bad firmware, need API version >=2\n", __func__);
 5665                 return EINVAL;
 5666         }
 5667         if (IWN_FW_API(rev) >= 3) {
 5668                 /* Skip build number (version 2 header). */
 5669                 size -= 4;
 5670                 ptr++;
 5671         }
 5672         fw->main.textsz = le32toh(*ptr++);
 5673         fw->main.datasz = le32toh(*ptr++);
 5674         fw->init.textsz = le32toh(*ptr++);
 5675         fw->init.datasz = le32toh(*ptr++);
 5676         fw->boot.textsz = le32toh(*ptr++);
 5677         size -= 24;
 5678 
 5679         /* Sanity-check firmware header. */
 5680         if (fw->main.textsz > hal->fw_text_maxsz ||
 5681             fw->main.datasz > hal->fw_data_maxsz ||
 5682             fw->init.textsz > hal->fw_text_maxsz ||
 5683             fw->init.datasz > hal->fw_data_maxsz ||
 5684             fw->boot.textsz > IWN_FW_BOOT_TEXT_MAXSZ ||
 5685             (fw->boot.textsz & 3) != 0) {
 5686                 device_printf(sc->sc_dev, "%s: invalid firmware header\n",
 5687                     __func__);
 5688                 return EINVAL;
 5689         }
 5690 
 5691         /* Check that all firmware sections fit. */
 5692         if (fw->main.textsz + fw->main.datasz + fw->init.textsz +
 5693             fw->init.datasz + fw->boot.textsz > size) {
 5694                 device_printf(sc->sc_dev,
 5695                     "%s: firmware file too short: %zu bytes\n",
 5696                     __func__, size);
 5697                 return EINVAL;
 5698         }
 5699 
 5700         /* Get pointers to firmware sections. */
 5701         fw->main.text = (const uint8_t *)ptr;
 5702         fw->main.data = fw->main.text + fw->main.textsz;
 5703         fw->init.text = fw->main.data + fw->main.datasz;
 5704         fw->init.data = fw->init.text + fw->init.textsz;
 5705         fw->boot.text = fw->init.data + fw->init.datasz;
 5706 
 5707         return 0;
 5708 }
 5709 
 5710 static int
 5711 iwn_clock_wait(struct iwn_softc *sc)
 5712 {
 5713         int ntries;
 5714 
 5715         /* Set "initialization complete" bit. */
 5716         IWN_SETBITS(sc, IWN_GP_CNTRL, IWN_GP_CNTRL_INIT_DONE);
 5717 
 5718         /* Wait for clock stabilization. */
 5719         for (ntries = 0; ntries < 2500; ntries++) {
 5720                 if (IWN_READ(sc, IWN_GP_CNTRL) & IWN_GP_CNTRL_MAC_CLOCK_READY)
 5721                         return 0;
 5722                 DELAY(10);
 5723         }
 5724         device_printf(sc->sc_dev,
 5725             "%s: timeout waiting for clock stabilization\n", __func__);
 5726         return ETIMEDOUT;
 5727 }
 5728 
 5729 static int
 5730 iwn_apm_init(struct iwn_softc *sc)
 5731 {
 5732         uint32_t tmp;
 5733         int error;
 5734 
 5735         /* Disable L0s exit timer (NMI bug workaround.) */
 5736         IWN_SETBITS(sc, IWN_GIO_CHICKEN, IWN_GIO_CHICKEN_DIS_L0S_TIMER);
 5737         /* Don't wait for ICH L0s (ICH bug workaround.) */
 5738         IWN_SETBITS(sc, IWN_GIO_CHICKEN, IWN_GIO_CHICKEN_L1A_NO_L0S_RX);
 5739 
 5740         /* Set FH wait threshold to max (HW bug under stress workaround.) */
 5741         IWN_SETBITS(sc, IWN_DBG_HPET_MEM, 0xffff0000);
 5742 
 5743         /* Enable HAP INTA to move adapter from L1a to L0s. */
 5744         IWN_SETBITS(sc, IWN_HW_IF_CONFIG, IWN_HW_IF_CONFIG_HAP_WAKE_L1A);
 5745 
 5746         /* Retrieve PCIe Active State Power Management (ASPM). */
 5747         tmp = pci_read_config(sc->sc_dev, sc->sc_cap_off + 0x10, 1);
 5748         /* Workaround for HW instability in PCIe L0->L0s->L1 transition. */
 5749         if (tmp & 0x02) /* L1 Entry enabled. */
 5750                 IWN_SETBITS(sc, IWN_GIO, IWN_GIO_L0S_ENA);
 5751         else
 5752                 IWN_CLRBITS(sc, IWN_GIO, IWN_GIO_L0S_ENA);
 5753 
 5754         if (sc->hw_type != IWN_HW_REV_TYPE_4965 &&
 5755             sc->hw_type != IWN_HW_REV_TYPE_6000 &&
 5756             sc->hw_type != IWN_HW_REV_TYPE_6050)
 5757                 IWN_SETBITS(sc, IWN_ANA_PLL, IWN_ANA_PLL_INIT);
 5758 
 5759         /* Wait for clock stabilization before accessing prph. */
 5760         error = iwn_clock_wait(sc);
 5761         if (error != 0)
 5762                 return error;
 5763 
 5764         error = iwn_nic_lock(sc);
 5765         if (error != 0)
 5766                 return error;
 5767 
 5768         if (sc->hw_type == IWN_HW_REV_TYPE_4965) {
 5769                 /* Enable DMA and BSM (Bootstrap State Machine.) */
 5770                 iwn_prph_write(sc, IWN_APMG_CLK_EN,
 5771                     IWN_APMG_CLK_CTRL_DMA_CLK_RQT |
 5772                     IWN_APMG_CLK_CTRL_BSM_CLK_RQT);
 5773         } else {
 5774                 /* Enable DMA. */
 5775                 iwn_prph_write(sc, IWN_APMG_CLK_EN,
 5776                     IWN_APMG_CLK_CTRL_DMA_CLK_RQT);
 5777         }
 5778         DELAY(20);
 5779 
 5780         /* Disable L1-Active. */
 5781         iwn_prph_setbits(sc, IWN_APMG_PCI_STT, IWN_APMG_PCI_STT_L1A_DIS);
 5782         iwn_nic_unlock(sc);
 5783 
 5784         return 0;
 5785 }
 5786 
 5787 static void
 5788 iwn_apm_stop_master(struct iwn_softc *sc)
 5789 {
 5790         int ntries;
 5791 
 5792         /* Stop busmaster DMA activity. */
 5793         IWN_SETBITS(sc, IWN_RESET, IWN_RESET_STOP_MASTER);
 5794         for (ntries = 0; ntries < 100; ntries++) {
 5795                 if (IWN_READ(sc, IWN_RESET) & IWN_RESET_MASTER_DISABLED)
 5796                         return;
 5797                 DELAY(10);
 5798         }
 5799         device_printf(sc->sc_dev, "%s: timeout waiting for master\n",
 5800             __func__);
 5801 }
 5802 
 5803 static void
 5804 iwn_apm_stop(struct iwn_softc *sc)
 5805 {
 5806         iwn_apm_stop_master(sc);
 5807 
 5808         /* Reset the entire device. */
 5809         IWN_SETBITS(sc, IWN_RESET, IWN_RESET_SW);
 5810         DELAY(10);
 5811         /* Clear "initialization complete" bit. */
 5812         IWN_CLRBITS(sc, IWN_GP_CNTRL, IWN_GP_CNTRL_INIT_DONE);
 5813 }
 5814 
 5815 static int
 5816 iwn4965_nic_config(struct iwn_softc *sc)
 5817 {
 5818         if (IWN_RFCFG_TYPE(sc->rfcfg) == 1) {
 5819                 /*
 5820                  * I don't believe this to be correct but this is what the
 5821                  * vendor driver is doing. Probably the bits should not be
 5822                  * shifted in IWN_RFCFG_*.
 5823                  */
 5824                 IWN_SETBITS(sc, IWN_HW_IF_CONFIG,
 5825                     IWN_RFCFG_TYPE(sc->rfcfg) |
 5826                     IWN_RFCFG_STEP(sc->rfcfg) |
 5827                     IWN_RFCFG_DASH(sc->rfcfg));
 5828         }
 5829         IWN_SETBITS(sc, IWN_HW_IF_CONFIG,
 5830             IWN_HW_IF_CONFIG_RADIO_SI | IWN_HW_IF_CONFIG_MAC_SI);
 5831         return 0;
 5832 }
 5833 
 5834 static int
 5835 iwn5000_nic_config(struct iwn_softc *sc)
 5836 {
 5837         uint32_t tmp;
 5838         int error;
 5839 
 5840         if (IWN_RFCFG_TYPE(sc->rfcfg) < 3) {
 5841                 IWN_SETBITS(sc, IWN_HW_IF_CONFIG,
 5842                     IWN_RFCFG_TYPE(sc->rfcfg) |
 5843                     IWN_RFCFG_STEP(sc->rfcfg) |
 5844                     IWN_RFCFG_DASH(sc->rfcfg));
 5845         }
 5846         IWN_SETBITS(sc, IWN_HW_IF_CONFIG,
 5847             IWN_HW_IF_CONFIG_RADIO_SI | IWN_HW_IF_CONFIG_MAC_SI);
 5848 
 5849         error = iwn_nic_lock(sc);
 5850         if (error != 0)
 5851                 return error;
 5852         iwn_prph_setbits(sc, IWN_APMG_PS, IWN_APMG_PS_EARLY_PWROFF_DIS);
 5853 
 5854         if (sc->hw_type == IWN_HW_REV_TYPE_1000) {
 5855                 /*
 5856                  * Select first Switching Voltage Regulator (1.32V) to
 5857                  * solve a stability issue related to noisy DC2DC line
 5858                  * in the silicon of 1000 Series.
 5859                  */
 5860                 tmp = iwn_prph_read(sc, IWN_APMG_DIGITAL_SVR);
 5861                 tmp &= ~IWN_APMG_DIGITAL_SVR_VOLTAGE_MASK;
 5862                 tmp |= IWN_APMG_DIGITAL_SVR_VOLTAGE_1_