Ticket #10729: iwn.patch

File iwn.patch, 200.6 KB (added by jjido, 10 years ago)

Patched iwn source (using FreeBSD sources)

  • src/add-ons/kernel/drivers/network/wlan/iprowifi4965/dev/iwn/if_iwn.c

    diff --git a/src/add-ons/kernel/drivers/network/wlan/iprowifi4965/dev/iwn/if_iwn.c b/src/add-ons/kernel/drivers/network/wlan/iprowifi4965/dev/iwn/if_iwn.c
    index 72cf415..65df8d3 100644
    a b __FBSDID("$FreeBSD$");  
    7272#include <dev/iwn/if_iwnreg.h>
    7373#include <dev/iwn/if_iwnvar.h>
    7474
     75struct iwn_ident {
     76    uint16_t    vendor;
     77    uint16_t    device;
     78    const char  *name;
     79};
     80
     81static const struct iwn_ident iwn_ident_table[] = {
     82    { 0x8086, 0x0082, "Intel Centrino Advanced-N 6205"      },
     83    { 0x8086, 0x0083, "Intel Centrino Wireless-N 1000"      },
     84    { 0x8086, 0x0084, "Intel Centrino Wireless-N 1000"      },
     85    { 0x8086, 0x0085, "Intel Centrino Advanced-N 6205"      },
     86    { 0x8086, 0x0087, "Intel Centrino Advanced-N + WiMAX 6250"  },
     87    { 0x8086, 0x0089, "Intel Centrino Advanced-N + WiMAX 6250"  },
     88    { 0x8086, 0x008a, "Intel Centrino Wireless-N 1030"      },
     89    { 0x8086, 0x008b, "Intel Centrino Wireless-N 1030"      },
     90    { 0x8086, 0x0090, "Intel Centrino Advanced-N 6230"      },
     91    { 0x8086, 0x0091, "Intel Centrino Advanced-N 6230"      },
     92    { 0x8086, 0x0885, "Intel Centrino Wireless-N + WiMAX 6150"  },
     93    { 0x8086, 0x0886, "Intel Centrino Wireless-N + WiMAX 6150"  },
     94    { 0x8086, 0x0896, "Intel Centrino Wireless-N 130"       },
     95    { 0x8086, 0x0887, "Intel Centrino Wireless-N 130"       },
     96    { 0x8086, 0x08ae, "Intel Centrino Wireless-N 100"       },
     97    { 0x8086, 0x08af, "Intel Centrino Wireless-N 100"       },
     98    { 0x8086, 0x4229, "Intel Wireless WiFi Link 4965"       },
     99    { 0x8086, 0x422b, "Intel Centrino Ultimate-N 6300"      },
     100    { 0x8086, 0x422c, "Intel Centrino Advanced-N 6200"      },
     101    { 0x8086, 0x422d, "Intel Wireless WiFi Link 4965"       },
     102    { 0x8086, 0x4230, "Intel Wireless WiFi Link 4965"       },
     103    { 0x8086, 0x4232, "Intel WiFi Link 5100"            },
     104    { 0x8086, 0x4233, "Intel Wireless WiFi Link 4965"       },
     105    { 0x8086, 0x4235, "Intel Ultimate N WiFi Link 5300"     },
     106    { 0x8086, 0x4236, "Intel Ultimate N WiFi Link 5300"     },
     107    { 0x8086, 0x4237, "Intel WiFi Link 5100"            },
     108    { 0x8086, 0x4238, "Intel Centrino Ultimate-N 6300"      },
     109    { 0x8086, 0x4239, "Intel Centrino Advanced-N 6200"      },
     110    { 0x8086, 0x423a, "Intel WiMAX/WiFi Link 5350"          },
     111    { 0x8086, 0x423b, "Intel WiMAX/WiFi Link 5350"          },
     112    { 0x8086, 0x423c, "Intel WiMAX/WiFi Link 5150"          },
     113    { 0x8086, 0x423d, "Intel WiMAX/WiFi Link 5150"          },
     114    { 0, 0, NULL }
     115};
     116
    75117static int  iwn_probe(device_t);
    76118static int  iwn_attach(device_t);
    77 static const struct iwn_hal *iwn_hal_attach(struct iwn_softc *);
     119static int  iwn4965_attach(struct iwn_softc *, uint16_t);
     120static int  iwn5000_attach(struct iwn_softc *, uint16_t);
    78121static void iwn_radiotap_attach(struct iwn_softc *);
     122static void iwn_sysctlattach(struct iwn_softc *);
    79123static struct ieee80211vap *iwn_vap_create(struct ieee80211com *,
    80             const char name[IFNAMSIZ], int unit, int opmode,
     124            const char name[IFNAMSIZ], int unit, enum ieee80211_opmode opmode,
    81125            int flags, const uint8_t bssid[IEEE80211_ADDR_LEN],
    82126            const uint8_t mac[IEEE80211_ADDR_LEN]);
    83127static void iwn_vap_delete(struct ieee80211vap *);
    84 static int  iwn_cleanup(device_t);
    85128static int  iwn_detach(device_t);
     129static int  iwn_shutdown(device_t);
     130static int  iwn_suspend(device_t);
     131static int  iwn_resume(device_t);
    86132static int  iwn_nic_lock(struct iwn_softc *);
    87133static int  iwn_eeprom_lock(struct iwn_softc *);
    88134static int  iwn_init_otprom(struct iwn_softc *);
    89135static int  iwn_read_prom_data(struct iwn_softc *, uint32_t, void *, int);
    90136static void iwn_dma_map_addr(void *, bus_dma_segment_t *, int, int);
    91137static int  iwn_dma_contig_alloc(struct iwn_softc *, struct iwn_dma_info *,
    92             void **, bus_size_t, bus_size_t, int);
     138            void **, bus_size_t, bus_size_t);
    93139static void iwn_dma_contig_free(struct iwn_dma_info *);
    94140static int  iwn_alloc_sched(struct iwn_softc *);
    95141static void iwn_free_sched(struct iwn_softc *);
    static void iwn_read_eeprom_band(struct iwn_softc *, int);  
    117163#if 0   /* HT */
    118164static void iwn_read_eeprom_ht40(struct iwn_softc *, int);
    119165#endif
    120 static void iwn_read_eeprom_channels(struct iwn_softc *, int,
    121             uint32_t);
     166static void iwn_read_eeprom_channels(struct iwn_softc *, int, uint32_t);
     167static struct iwn_eeprom_chan *iwn_find_eeprom_channel(struct iwn_softc *,
     168            struct ieee80211_channel *);
     169static int  iwn_setregdomain(struct ieee80211com *,
     170            struct ieee80211_regdomain *, int,
     171            struct ieee80211_channel[]);
    122172static void iwn_read_eeprom_enhinfo(struct iwn_softc *);
    123173static struct ieee80211_node *iwn_node_alloc(struct ieee80211vap *,
    124174            const uint8_t mac[IEEE80211_ADDR_LEN]);
     175static void iwn_newassoc(struct ieee80211_node *, int);
    125176static int  iwn_media_change(struct ifnet *);
    126177static int  iwn_newstate(struct ieee80211vap *, enum ieee80211_state, int);
     178static void iwn_calib_timeout(void *);
    127179static void iwn_rx_phy(struct iwn_softc *, struct iwn_rx_desc *,
    128180            struct iwn_rx_data *);
    129 static void iwn_timer_timeout(void *);
    130 static void iwn_calib_reset(struct iwn_softc *);
    131181static void iwn_rx_done(struct iwn_softc *, struct iwn_rx_desc *,
    132182            struct iwn_rx_data *);
    133183#if 0   /* HT */
    134184static void iwn_rx_compressed_ba(struct iwn_softc *, struct iwn_rx_desc *,
    135185            struct iwn_rx_data *);
    136186#endif
     187static void iwn5000_rx_calib_results(struct iwn_softc *,
     188            struct iwn_rx_desc *, struct iwn_rx_data *);
    137189static void iwn_rx_statistics(struct iwn_softc *, struct iwn_rx_desc *,
    138190            struct iwn_rx_data *);
    139191static void iwn4965_tx_done(struct iwn_softc *, struct iwn_rx_desc *,
    static void iwn5000_reset_sched(struct iwn_softc *, int, int);  
    157209#endif
    158210static uint8_t  iwn_plcp_signal(int);
    159211static int  iwn_tx_data(struct iwn_softc *, struct mbuf *,
    160             struct ieee80211_node *, struct iwn_tx_ring *);
     212            struct ieee80211_node *);
     213static int  iwn_tx_data_raw(struct iwn_softc *, struct mbuf *,
     214            struct ieee80211_node *,
     215            const struct ieee80211_bpf_params *params);
    161216static int  iwn_raw_xmit(struct ieee80211_node *, struct mbuf *,
    162217            const struct ieee80211_bpf_params *);
    163218static void iwn_start(struct ifnet *);
    164219static void iwn_start_locked(struct ifnet *);
    165 static void iwn_watchdog(struct iwn_softc *sc);
     220static void iwn_watchdog(void *);
    166221static int  iwn_ioctl(struct ifnet *, u_long, caddr_t);
    167222static int  iwn_cmd(struct iwn_softc *, int, const void *, int, int);
    168223static int  iwn4965_add_node(struct iwn_softc *, struct iwn_node_info *,
    169224            int);
    170225static int  iwn5000_add_node(struct iwn_softc *, struct iwn_node_info *,
    171226            int);
    172 static int  iwn_set_link_quality(struct iwn_softc *, uint8_t, int);
     227static int  iwn_set_link_quality(struct iwn_softc *,
     228            struct ieee80211_node *);
    173229static int  iwn_add_broadcast_node(struct iwn_softc *, int);
    174 static int  iwn_wme_update(struct ieee80211com *);
     230static int  iwn_updateedca(struct ieee80211com *);
    175231static void iwn_update_mcast(struct ifnet *);
    176232static void iwn_set_led(struct iwn_softc *, uint8_t, uint8_t, uint8_t);
    177233static int  iwn_set_critical_temp(struct iwn_softc *);
    static void iwn_tune_sensitivity(struct iwn_softc *,  
    197253            const struct iwn_rx_stats *);
    198254static int  iwn_send_sensitivity(struct iwn_softc *);
    199255static int  iwn_set_pslevel(struct iwn_softc *, int, int, int);
     256static int  iwn_send_btcoex(struct iwn_softc *);
     257static int  iwn_send_advanced_btcoex(struct iwn_softc *);
    200258static int  iwn_config(struct iwn_softc *);
     259static uint8_t  *ieee80211_add_ssid(uint8_t *, const uint8_t *, u_int);
    201260static int  iwn_scan(struct iwn_softc *);
    202261static int  iwn_auth(struct iwn_softc *, struct ieee80211vap *vap);
    203262static int  iwn_run(struct iwn_softc *, struct ieee80211vap *vap);
    static void iwn_ampdu_tx_stop(struct ieee80211com *,  
    212271            struct ieee80211_node *, uint8_t);
    213272static void iwn4965_ampdu_tx_start(struct iwn_softc *,
    214273            struct ieee80211_node *, uint8_t, uint16_t);
    215 static void iwn4965_ampdu_tx_stop(struct iwn_softc *, uint8_t, uint16_t);
     274static void iwn4965_ampdu_tx_stop(struct iwn_softc *,
     275            uint8_t, uint16_t);
    216276static void iwn5000_ampdu_tx_start(struct iwn_softc *,
    217277            struct ieee80211_node *, uint8_t, uint16_t);
    218 static void iwn5000_ampdu_tx_stop(struct iwn_softc *, uint8_t, uint16_t);
     278static void iwn5000_ampdu_tx_stop(struct iwn_softc *,
     279            uint8_t, uint16_t);
    219280#endif
    220 static int  iwn5000_send_calib_results(struct iwn_softc *);
    221 static int  iwn5000_save_calib_result(struct iwn_softc *,
    222             struct iwn_phy_calib *, int, int);
    223 static void iwn5000_free_calib_results(struct iwn_softc *);
    224 static int  iwn5000_chrystal_calib(struct iwn_softc *);
    225 static int  iwn5000_send_calib_query(struct iwn_softc *, uint32_t);
    226 static int  iwn5000_rx_calib_result(struct iwn_softc *,
    227             struct iwn_rx_desc *, struct iwn_rx_data *);
     281static int  iwn5000_query_calibration(struct iwn_softc *);
     282static int  iwn5000_send_calibration(struct iwn_softc *);
    228283static int  iwn5000_send_wimax_coex(struct iwn_softc *);
     284static int  iwn5000_crystal_calib(struct iwn_softc *);
     285static int  iwn5000_temp_offset_calib(struct iwn_softc *);
    229286static int  iwn4965_post_alive(struct iwn_softc *);
    230287static int  iwn5000_post_alive(struct iwn_softc *);
    231288static int  iwn4965_load_bootcode(struct iwn_softc *, const uint8_t *,
    static int iwn5000_nic_config(struct iwn_softc *);  
    248305static int  iwn_hw_prepare(struct iwn_softc *);
    249306static int  iwn_hw_init(struct iwn_softc *);
    250307static void iwn_hw_stop(struct iwn_softc *);
     308static void iwn_radio_on(void *, int);
     309static void iwn_radio_off(void *, int);
    251310static void iwn_init_locked(struct iwn_softc *);
    252311static void iwn_init(void *);
    253312static void iwn_stop_locked(struct iwn_softc *);
    254313static void iwn_stop(struct iwn_softc *);
    255 static void     iwn_scan_start(struct ieee80211com *);
    256 static void     iwn_scan_end(struct ieee80211com *);
    257 static void     iwn_set_channel(struct ieee80211com *);
    258 static void     iwn_scan_curchan(struct ieee80211_scan_state *, unsigned long);
    259 static void     iwn_scan_mindwell(struct ieee80211_scan_state *);
    260 static struct iwn_eeprom_chan *iwn_find_eeprom_channel(struct iwn_softc *,
    261             struct ieee80211_channel *);
    262 static int  iwn_setregdomain(struct ieee80211com *,
    263             struct ieee80211_regdomain *, int,
    264             struct ieee80211_channel []);
     314static void iwn_scan_start(struct ieee80211com *);
     315static void iwn_scan_end(struct ieee80211com *);
     316static void iwn_set_channel(struct ieee80211com *);
     317static void iwn_scan_curchan(struct ieee80211_scan_state *, unsigned long);
     318static void iwn_scan_mindwell(struct ieee80211_scan_state *);
    265319static void iwn_hw_reset(void *, int);
    266 static void iwn_radio_on(void *, int);
    267 static void iwn_radio_off(void *, int);
    268 static void iwn_sysctlattach(struct iwn_softc *);
    269 static int  iwn_shutdown(device_t);
    270 static int  iwn_suspend(device_t);
    271 static int  iwn_resume(device_t);
    272320
    273321#define IWN_DEBUG
    274322#ifdef IWN_DEBUG
    enum {  
    295343        printf(fmt, __VA_ARGS__);       \
    296344} while (0)
    297345
    298 static const char *iwn_intr_str(uint8_t);
     346static const char *
     347iwn_intr_str(uint8_t cmd)
     348{
     349    switch (cmd) {
     350    /* Notifications */
     351    case IWN_UC_READY:      return "UC_READY";
     352    case IWN_ADD_NODE_DONE:     return "ADD_NODE_DONE";
     353    case IWN_TX_DONE:       return "TX_DONE";
     354    case IWN_START_SCAN:        return "START_SCAN";
     355    case IWN_STOP_SCAN:     return "STOP_SCAN";
     356    case IWN_RX_STATISTICS:     return "RX_STATS";
     357    case IWN_BEACON_STATISTICS: return "BEACON_STATS";
     358    case IWN_STATE_CHANGED:     return "STATE_CHANGED";
     359    case IWN_BEACON_MISSED:     return "BEACON_MISSED";
     360    case IWN_RX_PHY:        return "RX_PHY";
     361    case IWN_MPDU_RX_DONE:      return "MPDU_RX_DONE";
     362    case IWN_RX_DONE:       return "RX_DONE";
     363
     364    /* Command Notifications */
     365    case IWN_CMD_RXON:      return "IWN_CMD_RXON";
     366    case IWN_CMD_RXON_ASSOC:    return "IWN_CMD_RXON_ASSOC";
     367    case IWN_CMD_EDCA_PARAMS:   return "IWN_CMD_EDCA_PARAMS";
     368    case IWN_CMD_TIMING:        return "IWN_CMD_TIMING";
     369    case IWN_CMD_LINK_QUALITY:  return "IWN_CMD_LINK_QUALITY";
     370    case IWN_CMD_SET_LED:       return "IWN_CMD_SET_LED";
     371    case IWN5000_CMD_WIMAX_COEX:    return "IWN5000_CMD_WIMAX_COEX";
     372    case IWN5000_CMD_CALIB_CONFIG:  return "IWN5000_CMD_CALIB_CONFIG";
     373    case IWN5000_CMD_CALIB_RESULT:  return "IWN5000_CMD_CALIB_RESULT";
     374    case IWN5000_CMD_CALIB_COMPLETE: return "IWN5000_CMD_CALIB_COMPLETE";
     375    case IWN_CMD_SET_POWER_MODE:    return "IWN_CMD_SET_POWER_MODE";
     376    case IWN_CMD_SCAN:      return "IWN_CMD_SCAN";
     377    case IWN_CMD_SCAN_RESULTS:  return "IWN_CMD_SCAN_RESULTS";
     378    case IWN_CMD_TXPOWER:       return "IWN_CMD_TXPOWER";
     379    case IWN_CMD_TXPOWER_DBM:   return "IWN_CMD_TXPOWER_DBM";
     380    case IWN5000_CMD_TX_ANT_CONFIG: return "IWN5000_CMD_TX_ANT_CONFIG";
     381    case IWN_CMD_BT_COEX:       return "IWN_CMD_BT_COEX";
     382    case IWN_CMD_SET_CRITICAL_TEMP: return "IWN_CMD_SET_CRITICAL_TEMP";
     383    case IWN_CMD_SET_SENSITIVITY:   return "IWN_CMD_SET_SENSITIVITY";
     384    case IWN_CMD_PHY_CALIB:     return "IWN_CMD_PHY_CALIB";
     385    }
     386    return "UNKNOWN INTR NOTIF/CMD";
     387}
    299388#else
    300389#define DPRINTF(sc, m, fmt, ...) do { (void) sc; } while (0)
    301390#endif
    302391
    303 struct iwn_ident {
    304     uint16_t    vendor;
    305     uint16_t    device;
    306     const char  *name;
     392static device_method_t iwn_methods[] = {
     393    /* Device interface */
     394    DEVMETHOD(device_probe,     iwn_probe),
     395    DEVMETHOD(device_attach,    iwn_attach),
     396    DEVMETHOD(device_detach,    iwn_detach),
     397    DEVMETHOD(device_shutdown,  iwn_shutdown),
     398    DEVMETHOD(device_suspend,   iwn_suspend),
     399    DEVMETHOD(device_resume,    iwn_resume),
     400    { 0, 0 }
    307401};
    308402
    309 static const struct iwn_ident iwn_ident_table [] = {
    310     { 0x8086, 0x4229, "Intel(R) PRO/Wireless 4965BGN" },
    311     { 0x8086, 0x422D, "Intel(R) PRO/Wireless 4965BGN" },
    312     { 0x8086, 0x4230, "Intel(R) PRO/Wireless 4965BGN" },
    313     { 0x8086, 0x4233, "Intel(R) PRO/Wireless 4965BGN" },
    314     { 0x8086, 0x4232, "Intel(R) PRO/Wireless 5100" },
    315     { 0x8086, 0x4237, "Intel(R) PRO/Wireless 5100" },
    316     { 0x8086, 0x423C, "Intel(R) PRO/Wireless 5150" },
    317     { 0x8086, 0x423D, "Intel(R) PRO/Wireless 5150" },
    318     { 0x8086, 0x4235, "Intel(R) PRO/Wireless 5300" },
    319     { 0x8086, 0x4236, "Intel(R) PRO/Wireless 5300" },
    320     { 0x8086, 0x423A, "Intel(R) PRO/Wireless 5350" },
    321     { 0x8086, 0x423B, "Intel(R) PRO/Wireless 5350" },
    322     { 0x8086, 0x0083, "Intel(R) PRO/Wireless 1000" },
    323     { 0x8086, 0x0084, "Intel(R) PRO/Wireless 1000" },
    324     { 0x8086, 0x008D, "Intel(R) PRO/Wireless 6000" },
    325     { 0x8086, 0x008E, "Intel(R) PRO/Wireless 6000" },
    326     { 0x8086, 0x4238, "Intel(R) PRO/Wireless 6000" },
    327     { 0x8086, 0x4239, "Intel(R) PRO/Wireless 6000" },
    328     { 0x8086, 0x422B, "Intel(R) PRO/Wireless 6000" },
    329     { 0x8086, 0x422C, "Intel(R) PRO/Wireless 6000" },
    330     { 0x8086, 0x0087, "Intel(R) PRO/Wireless 6250" },
    331     { 0x8086, 0x0089, "Intel(R) PRO/Wireless 6250" },
    332     { 0x8086, 0x0082, "Intel(R) PRO/Wireless 6205a" },
    333     { 0x8086, 0x0085, "Intel(R) PRO/Wireless 6205a" },
    334 #ifdef notyet
    335     { 0x8086, 0x008a, "Intel(R) PRO/Wireless 6205b" },
    336     { 0x8086, 0x008b, "Intel(R) PRO/Wireless 6205b" },
    337     { 0x8086, 0x008f, "Intel(R) PRO/Wireless 6205b" },
    338     { 0x8086, 0x0090, "Intel(R) PRO/Wireless 6205b" },
    339     { 0x8086, 0x0091, "Intel(R) PRO/Wireless 6205b" },
    340 #endif
    341     { 0, 0, NULL }
     403static driver_t iwn_driver = {
     404    "iwn",
     405    iwn_methods,
     406    sizeof(struct iwn_softc)
    342407};
     408static devclass_t iwn_devclass;
    343409
    344 static const struct iwn_hal iwn4965_hal = {
    345     iwn4965_load_firmware,
    346     iwn4965_read_eeprom,
    347     iwn4965_post_alive,
    348     iwn4965_nic_config,
    349     iwn4965_update_sched,
    350     iwn4965_get_temperature,
    351     iwn4965_get_rssi,
    352     iwn4965_set_txpower,
    353     iwn4965_init_gains,
    354     iwn4965_set_gains,
    355     iwn4965_add_node,
    356     iwn4965_tx_done,
    357 #if 0   /* HT */
    358     iwn4965_ampdu_tx_start,
    359     iwn4965_ampdu_tx_stop,
    360 #endif
    361     IWN4965_NTXQUEUES,
    362     IWN4965_NDMACHNLS,
    363     IWN4965_ID_BROADCAST,
    364     IWN4965_RXONSZ,
    365     IWN4965_SCHEDSZ,
    366     IWN4965_FW_TEXT_MAXSZ,
    367     IWN4965_FW_DATA_MAXSZ,
    368     IWN4965_FWSZ,
    369     IWN4965_SCHED_TXFACT
    370 };
     410DRIVER_MODULE(iwn, pci, iwn_driver, iwn_devclass, 0, 0);
    371411
    372 static const struct iwn_hal iwn5000_hal = {
    373     iwn5000_load_firmware,
    374     iwn5000_read_eeprom,
    375     iwn5000_post_alive,
    376     iwn5000_nic_config,
    377     iwn5000_update_sched,
    378     iwn5000_get_temperature,
    379     iwn5000_get_rssi,
    380     iwn5000_set_txpower,
    381     iwn5000_init_gains,
    382     iwn5000_set_gains,
    383     iwn5000_add_node,
    384     iwn5000_tx_done,
    385 #if 0   /* HT */
    386     iwn5000_ampdu_tx_start,
    387     iwn5000_ampdu_tx_stop,
    388 #endif
    389     IWN5000_NTXQUEUES,
    390     IWN5000_NDMACHNLS,
    391     IWN5000_ID_BROADCAST,
    392     IWN5000_RXONSZ,
    393     IWN5000_SCHEDSZ,
    394     IWN5000_FW_TEXT_MAXSZ,
    395     IWN5000_FW_DATA_MAXSZ,
    396     IWN5000_FWSZ,
    397     IWN5000_SCHED_TXFACT
    398 };
     412MODULE_DEPEND(iwn, firmware, 1, 1, 1);
     413MODULE_DEPEND(iwn, pci, 1, 1, 1);
     414MODULE_DEPEND(iwn, wlan, 1, 1, 1);
    399415
    400416static int
    401417iwn_probe(device_t dev)
    iwn_attach(device_t dev)  
    418434    struct iwn_softc *sc = (struct iwn_softc *)device_get_softc(dev);
    419435    struct ieee80211com *ic;
    420436    struct ifnet *ifp;
    421     const struct iwn_hal *hal;
    422     uint32_t tmp;
     437    uint32_t reg;
    423438    int i, error, result;
    424439    uint8_t macaddr[IEEE80211_ADDR_LEN];
    425440
    iwn_attach(device_t dev)  
    439454    pci_write_config(dev, 0x41, 0, 1);
    440455
    441456    /* Hardware bug workaround. */
    442     tmp = pci_read_config(dev, PCIR_COMMAND, 1);
    443     if (tmp & PCIM_CMD_INTxDIS) {
     457    reg = pci_read_config(dev, PCIR_COMMAND, 1);
     458    if (reg & PCIM_CMD_INTxDIS) {
    444459        DPRINTF(sc, IWN_DEBUG_RESET, "%s: PCIe INTx Disable set\n",
    445460            __func__);
    446         tmp &= ~PCIM_CMD_INTxDIS;
    447         pci_write_config(dev, PCIR_COMMAND, tmp, 1);
     461        reg &= ~PCIM_CMD_INTxDIS;
     462        pci_write_config(dev, PCIR_COMMAND, reg, 1);
    448463    }
    449464
    450465    /* Enable bus-mastering. */
    iwn_attach(device_t dev)  
    453468    sc->mem_rid = PCIR_BAR(0);
    454469    sc->mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->mem_rid,
    455470        RF_ACTIVE);
    456     if (sc->mem == NULL ) {
    457         device_printf(dev, "could not allocate memory resources\n");
     471    if (sc->mem == NULL) {
     472        device_printf(dev, "can't map mem space\n");
    458473        error = ENOMEM;
    459474        return error;
    460475    }
    461 
    462476    sc->sc_st = rman_get_bustag(sc->mem);
    463477    sc->sc_sh = rman_get_bushandle(sc->mem);
     478
    464479    sc->irq_rid = 0;
    465480    if ((result = pci_msi_count(dev)) == 1 &&
    466481        pci_alloc_msi(dev, &result) == 0)
    467482        sc->irq_rid = 1;
     483    /* Install interrupt handler. */
    468484    sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irq_rid,
    469485        RF_ACTIVE | RF_SHAREABLE);
    470486    if (sc->irq == NULL) {
    471         device_printf(dev, "could not allocate interrupt resource\n");
     487        device_printf(dev, "can't map interrupt\n");
    472488        error = ENOMEM;
    473489        goto fail;
    474490    }
    475491
    476492    IWN_LOCK_INIT(sc);
    477     callout_init_mtx(&sc->sc_timer_to, &sc->sc_mtx, 0);
    478     TASK_INIT(&sc->sc_reinit_task, 0, iwn_hw_reset, sc );
    479     TASK_INIT(&sc->sc_radioon_task, 0, iwn_radio_on, sc );
    480     TASK_INIT(&sc->sc_radiooff_task, 0, iwn_radio_off, sc );
    481 
    482     /* Attach Hardware Abstraction Layer. */
    483     hal = iwn_hal_attach(sc);
    484     if (hal == NULL) {
    485         error = ENXIO;  /* XXX: Wrong error code? */
     493
     494    /* Read hardware revision and attach. */
     495    sc->hw_type = (IWN_READ(sc, IWN_HW_REV) >> 4) & 0xf;
     496    if (sc->hw_type == IWN_HW_REV_TYPE_4965)
     497        error = iwn4965_attach(sc, pci_get_device(dev));
     498    else
     499        error = iwn5000_attach(sc, pci_get_device(dev));
     500    if (error != 0) {
     501        device_printf(dev, "could not attach device, error %d\n",
     502            error);
    486503        goto fail;
    487504    }
    488505
    489     error = iwn_hw_prepare(sc);
    490     if (error != 0) {
     506    if ((error = iwn_hw_prepare(sc)) != 0) {
    491507        device_printf(dev, "hardware not ready, error %d\n", error);
    492508        goto fail;
    493509    }
    494510
    495511    /* Allocate DMA memory for firmware transfers. */
    496     error = iwn_alloc_fwmem(sc);
    497     if (error != 0) {
     512    if ((error = iwn_alloc_fwmem(sc)) != 0) {
    498513        device_printf(dev,
    499514            "could not allocate memory for firmware, error %d\n",
    500515            error);
    iwn_attach(device_t dev)  
    502517    }
    503518
    504519    /* Allocate "Keep Warm" page. */
    505     error = iwn_alloc_kw(sc);
    506     if (error != 0) {
     520    if ((error = iwn_alloc_kw(sc)) != 0) {
    507521        device_printf(dev,
    508             "could not allocate \"Keep Warm\" page, error %d\n", error);
     522            "could not allocate keep warm page, error %d\n", error);
    509523        goto fail;
    510524    }
    511525
    512526    /* Allocate ICT table for 5000 Series. */
    513527    if (sc->hw_type != IWN_HW_REV_TYPE_4965 &&
    514528        (error = iwn_alloc_ict(sc)) != 0) {
    515         device_printf(dev,
    516             "%s: could not allocate ICT table, error %d\n",
    517             __func__, error);
     529        device_printf(dev, "could not allocate ICT table, error %d\n",
     530            error);
    518531        goto fail;
    519532    }
    520533
    521534    /* Allocate TX scheduler "rings". */
    522     error = iwn_alloc_sched(sc);
    523     if (error != 0) {
     535    if ((error = iwn_alloc_sched(sc)) != 0) {
    524536        device_printf(dev,
    525             "could not allocate TX scheduler rings, error %d\n",
    526             error);
     537            "could not allocate TX scheduler rings, error %d\n", error);
    527538        goto fail;
    528539    }
    529540
    530     /* Allocate TX rings (16 on 4965AGN, 20 on 5000). */
    531     for (i = 0; i < hal->ntxqs; i++) {
    532         error = iwn_alloc_tx_ring(sc, &sc->txq[i], i);
    533         if (error != 0) {
     541    /* Allocate TX rings (16 on 4965AGN, 20 on >=5000). */
     542    for (i = 0; i < sc->ntxqs; i++) {
     543        if ((error = iwn_alloc_tx_ring(sc, &sc->txq[i], i)) != 0) {
    534544            device_printf(dev,
    535                 "could not allocate Tx ring %d, error %d\n",
    536                 i, error);
     545                "could not allocate TX ring %d, error %d\n", i,
     546                error);
    537547            goto fail;
    538548        }
    539549    }
    540550
    541551    /* Allocate RX ring. */
    542     error = iwn_alloc_rx_ring(sc, &sc->rxq);
    543     if (error != 0 ){
    544         device_printf(dev,
    545             "could not allocate Rx ring, error %d\n", error);
     552    if ((error = iwn_alloc_rx_ring(sc, &sc->rxq)) != 0) {
     553        device_printf(dev, "could not allocate RX ring, error %d\n",
     554            error);
    546555        goto fail;
    547556    }
    548557
    iwn_attach(device_t dev)  
    558567        ((sc->rxchainmask >> 2) & 1) +
    559568        ((sc->rxchainmask >> 1) & 1) +
    560569        ((sc->rxchainmask >> 0) & 1);
     570    if (bootverbose) {
     571        device_printf(dev, "MIMO %dT%dR, %.4s, address %6D\n",
     572            sc->ntxchains, sc->nrxchains, sc->eeprom_domain,
     573            macaddr, ":");
     574    }
    561575
    562576    ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
    563577    if (ifp == NULL) {
    564578        device_printf(dev, "can not allocate ifnet structure\n");
    565579        goto fail;
    566580    }
    567     ic = ifp->if_l2com;
    568581
     582    ic = ifp->if_l2com;
    569583    ic->ic_ifp = ifp;
    570584    ic->ic_phytype = IEEE80211_T_OFDM;  /* not only, but not used */
    571585    ic->ic_opmode = IEEE80211_M_STA;    /* default to BSS mode */
    iwn_attach(device_t dev)  
    616630#endif
    617631
    618632    /* Read MAC address, channels, etc from EEPROM. */
    619     error = iwn_read_eeprom(sc, macaddr);
    620     if (error != 0) {
     633    if ((error = iwn_read_eeprom(sc, macaddr)) != 0) {
    621634        device_printf(dev, "could not read EEPROM, error %d\n",
    622635            error);
    623636        goto fail;
    624637    }
    625638
    626     device_printf(sc->sc_dev, "MIMO %dT%dR, %.4s, address %6D\n",
    627         sc->ntxchains, sc->nrxchains, sc->eeprom_domain,
    628         macaddr, ":");
    629 
    630639#if 0   /* HT */
    631640    /* Set supported HT rates. */
    632641    ic->ic_sup_mcs[0] = 0xff;
    iwn_attach(device_t dev)  
    651660    ic->ic_vap_delete = iwn_vap_delete;
    652661    ic->ic_raw_xmit = iwn_raw_xmit;
    653662    ic->ic_node_alloc = iwn_node_alloc;
    654     ic->ic_wme.wme_update = iwn_wme_update;
     663#if 0   /* HT */
     664    ic->ic_ampdu_rx_start = iwn_ampdu_rx_start;
     665    ic->ic_ampdu_rx_stop = iwn_ampdu_rx_stop;
     666    ic->ic_ampdu_tx_start = iwn_ampdu_tx_start;
     667    ic->ic_ampdu_tx_stop = iwn_ampdu_tx_stop;
     668#endif
     669    ic->ic_newassoc = iwn_newassoc;
     670    ic->ic_wme.wme_update = iwn_updateedca;
    655671    ic->ic_update_mcast = iwn_update_mcast;
    656672    ic->ic_scan_start = iwn_scan_start;
    657673    ic->ic_scan_end = iwn_scan_end;
    iwn_attach(device_t dev)  
    659675    ic->ic_scan_curchan = iwn_scan_curchan;
    660676    ic->ic_scan_mindwell = iwn_scan_mindwell;
    661677    ic->ic_setregdomain = iwn_setregdomain;
    662 #if 0   /* HT */
    663     ic->ic_ampdu_rx_start = iwn_ampdu_rx_start;
    664     ic->ic_ampdu_rx_stop = iwn_ampdu_rx_stop;
    665     ic->ic_ampdu_tx_start = iwn_ampdu_tx_start;
    666     ic->ic_ampdu_tx_stop = iwn_ampdu_tx_stop;
    667 #endif
    668678
    669679    iwn_radiotap_attach(sc);
     680
     681    callout_init_mtx(&sc->calib_to, &sc->sc_mtx, 0);
     682    callout_init_mtx(&sc->watchdog_to, &sc->sc_mtx, 0);
     683    TASK_INIT(&sc->sc_reinit_task, 0, iwn_hw_reset, sc);
     684    TASK_INIT(&sc->sc_radioon_task, 0, iwn_radio_on, sc);
     685    TASK_INIT(&sc->sc_radiooff_task, 0, iwn_radio_off, sc);
     686
    670687    iwn_sysctlattach(sc);
    671688
    672689    /*
    iwn_attach(device_t dev)  
    675692    error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET | INTR_MPSAFE,
    676693        NULL, iwn_intr, sc, &sc->sc_ih);
    677694    if (error != 0) {
    678         device_printf(dev, "could not set up interrupt, error %d\n",
     695        device_printf(dev, "can't establish interrupt, error %d\n",
    679696            error);
    680697        goto fail;
    681698    }
    682699
    683     ieee80211_announce(ic);
     700    if (bootverbose)
     701        ieee80211_announce(ic);
    684702    return 0;
    685703fail:
    686     iwn_cleanup(dev);
     704    iwn_detach(dev);
    687705    return error;
    688706}
    689707
    690 static const struct iwn_hal *
    691 iwn_hal_attach(struct iwn_softc *sc)
    692 {
    693     sc->hw_type = (IWN_READ(sc, IWN_HW_REV) >> 4) & 0xf;
     708static int
     709iwn4965_attach(struct iwn_softc *sc, uint16_t pid)
     710{
     711    struct iwn_ops *ops = &sc->ops;
     712
     713    ops->load_firmware = iwn4965_load_firmware;
     714    ops->read_eeprom = iwn4965_read_eeprom;
     715    ops->post_alive = iwn4965_post_alive;
     716    ops->nic_config = iwn4965_nic_config;
     717    ops->update_sched = iwn4965_update_sched;
     718    ops->get_temperature = iwn4965_get_temperature;
     719    ops->get_rssi = iwn4965_get_rssi;
     720    ops->set_txpower = iwn4965_set_txpower;
     721    ops->init_gains = iwn4965_init_gains;
     722    ops->set_gains = iwn4965_set_gains;
     723    ops->add_node = iwn4965_add_node;
     724    ops->tx_done = iwn4965_tx_done;
     725#if 0   /* HT */
     726    ops->ampdu_tx_start = iwn4965_ampdu_tx_start;
     727    ops->ampdu_tx_stop = iwn4965_ampdu_tx_stop;
     728#endif
     729    sc->ntxqs = IWN4965_NTXQUEUES;
     730    sc->ndmachnls = IWN4965_NDMACHNLS;
     731    sc->broadcast_id = IWN4965_ID_BROADCAST;
     732    sc->rxonsz = IWN4965_RXONSZ;
     733    sc->schedsz = IWN4965_SCHEDSZ;
     734    sc->fw_text_maxsz = IWN4965_FW_TEXT_MAXSZ;
     735    sc->fw_data_maxsz = IWN4965_FW_DATA_MAXSZ;
     736    sc->fwsz = IWN4965_FWSZ;
     737    sc->sched_txfact_addr = IWN4965_SCHED_TXFACT;
     738    sc->limits = &iwn4965_sensitivity_limits;
     739    sc->fwname = "iwn4965fw";
     740    /* Override chains masks, ROM is known to be broken. */
     741    sc->txchainmask = IWN_ANT_AB;
     742    sc->rxchainmask = IWN_ANT_ABC;
     743
     744    return 0;
     745}
     746
     747static int
     748iwn5000_attach(struct iwn_softc *sc, uint16_t pid)
     749{
     750    struct iwn_ops *ops = &sc->ops;
     751
     752    ops->load_firmware = iwn5000_load_firmware;
     753    ops->read_eeprom = iwn5000_read_eeprom;
     754    ops->post_alive = iwn5000_post_alive;
     755    ops->nic_config = iwn5000_nic_config;
     756    ops->update_sched = iwn5000_update_sched;
     757    ops->get_temperature = iwn5000_get_temperature;
     758    ops->get_rssi = iwn5000_get_rssi;
     759    ops->set_txpower = iwn5000_set_txpower;
     760    ops->init_gains = iwn5000_init_gains;
     761    ops->set_gains = iwn5000_set_gains;
     762    ops->add_node = iwn5000_add_node;
     763    ops->tx_done = iwn5000_tx_done;
     764#if 0   /* HT */
     765    ops->ampdu_tx_start = iwn5000_ampdu_tx_start;
     766    ops->ampdu_tx_stop = iwn5000_ampdu_tx_stop;
     767#endif
     768    sc->ntxqs = IWN5000_NTXQUEUES;
     769    sc->ndmachnls = IWN5000_NDMACHNLS;
     770    sc->broadcast_id = IWN5000_ID_BROADCAST;
     771    sc->rxonsz = IWN5000_RXONSZ;
     772    sc->schedsz = IWN5000_SCHEDSZ;
     773    sc->fw_text_maxsz = IWN5000_FW_TEXT_MAXSZ;
     774    sc->fw_data_maxsz = IWN5000_FW_DATA_MAXSZ;
     775    sc->fwsz = IWN5000_FWSZ;
     776    sc->sched_txfact_addr = IWN5000_SCHED_TXFACT;
     777    sc->reset_noise_gain = IWN5000_PHY_CALIB_RESET_NOISE_GAIN;
     778    sc->noise_gain = IWN5000_PHY_CALIB_NOISE_GAIN;
    694779
    695780    switch (sc->hw_type) {
    696     case IWN_HW_REV_TYPE_4965:
    697         sc->sc_hal = &iwn4965_hal;
    698         sc->limits = &iwn4965_sensitivity_limits;
    699         sc->fwname = "iwn4965fw";
    700         sc->txchainmask = IWN_ANT_AB;
    701         sc->rxchainmask = IWN_ANT_ABC;
    702         break;
    703781    case IWN_HW_REV_TYPE_5100:
    704         sc->sc_hal = &iwn5000_hal;
    705782        sc->limits = &iwn5000_sensitivity_limits;
    706783        sc->fwname = "iwn5000fw";
     784        /* Override chains masks, ROM is known to be broken. */
    707785        sc->txchainmask = IWN_ANT_B;
    708786        sc->rxchainmask = IWN_ANT_AB;
    709         sc->calib_init = IWN_CALIB_XTAL | IWN_CALIB_LO |
    710             IWN_CALIB_TX_IQ | IWN_CALIB_TX_IQ_PERIODIC |
    711             IWN_CALIB_BASE_BAND;
    712787        break;
    713788    case IWN_HW_REV_TYPE_5150:
    714         sc->sc_hal = &iwn5000_hal;
    715789        sc->limits = &iwn5150_sensitivity_limits;
    716790        sc->fwname = "iwn5150fw";
    717         sc->txchainmask = IWN_ANT_A;
    718         sc->rxchainmask = IWN_ANT_AB;
    719         sc->calib_init = IWN_CALIB_DC | IWN_CALIB_LO |
    720             IWN_CALIB_TX_IQ | IWN_CALIB_BASE_BAND;
    721791        break;
    722792    case IWN_HW_REV_TYPE_5300:
    723793    case IWN_HW_REV_TYPE_5350:
    724         sc->sc_hal = &iwn5000_hal;
    725794        sc->limits = &iwn5000_sensitivity_limits;
    726795        sc->fwname = "iwn5000fw";
    727         sc->txchainmask = IWN_ANT_ABC;
    728         sc->rxchainmask = IWN_ANT_ABC;
    729         sc->calib_init = IWN_CALIB_XTAL | IWN_CALIB_LO |
    730             IWN_CALIB_TX_IQ | IWN_CALIB_TX_IQ_PERIODIC |
    731             IWN_CALIB_BASE_BAND;
    732796        break;
    733797    case IWN_HW_REV_TYPE_1000:
    734         sc->sc_hal = &iwn5000_hal;
    735798        sc->limits = &iwn1000_sensitivity_limits;
    736799        sc->fwname = "iwn1000fw";
    737         sc->txchainmask = IWN_ANT_A;
    738         sc->rxchainmask = IWN_ANT_AB;
    739         sc->calib_init = IWN_CALIB_XTAL | IWN_CALIB_LO |
    740             IWN_CALIB_TX_IQ | IWN_CALIB_TX_IQ_PERIODIC |
    741             IWN_CALIB_BASE_BAND;
    742800        break;
    743801    case IWN_HW_REV_TYPE_6000:
    744         sc->sc_hal = &iwn5000_hal;
    745802        sc->limits = &iwn6000_sensitivity_limits;
    746803        sc->fwname = "iwn6000fw";
    747         switch (pci_get_device(sc->sc_dev)) {
    748         case 0x422C:
    749         case 0x4239:
     804        if (pid == 0x422c || pid == 0x4239) {
    750805            sc->sc_flags |= IWN_FLAG_INTERNAL_PA;
     806            /* Override chains masks, ROM is known to be broken. */
    751807            sc->txchainmask = IWN_ANT_BC;
    752808            sc->rxchainmask = IWN_ANT_BC;
    753             break;
    754         default:
    755             sc->txchainmask = IWN_ANT_ABC;
    756             sc->rxchainmask = IWN_ANT_ABC;
    757             sc->calib_runtime = IWN_CALIB_DC;
    758             break;
    759809        }
    760         sc->calib_init = IWN_CALIB_XTAL | IWN_CALIB_LO |
    761             IWN_CALIB_TX_IQ | IWN_CALIB_BASE_BAND;
    762810        break;
    763811    case IWN_HW_REV_TYPE_6050:
    764         sc->sc_hal = &iwn5000_hal;
    765812        sc->limits = &iwn6000_sensitivity_limits;
    766813        sc->fwname = "iwn6050fw";
     814        /* Override chains masks, ROM is known to be broken. */
    767815        sc->txchainmask = IWN_ANT_AB;
    768816        sc->rxchainmask = IWN_ANT_AB;
    769         sc->calib_init = IWN_CALIB_XTAL | IWN_CALIB_LO |
    770             IWN_CALIB_TX_IQ | IWN_CALIB_BASE_BAND;
    771         sc->calib_runtime = IWN_CALIB_DC;
    772817        break;
    773818    case IWN_HW_REV_TYPE_6005:
    774         sc->sc_hal = &iwn5000_hal;
    775819        sc->limits = &iwn6000_sensitivity_limits;
    776         sc->fwname = "iwn6005fw";
    777         sc->txchainmask = IWN_ANT_AB;
    778         sc->rxchainmask = IWN_ANT_AB;
    779         sc->calib_init = IWN_CALIB_XTAL | IWN_CALIB_LO |
    780             IWN_CALIB_TX_IQ | IWN_CALIB_BASE_BAND;
    781         sc->calib_runtime = IWN_CALIB_DC;
     820        if (pid != 0x0082 && pid != 0x0085) {
     821            sc->fwname = "iwn6000g2bfw";
     822            sc->sc_flags |= IWN_FLAG_ADV_BTCOEX;
     823        } else
     824            sc->fwname = "iwn6000g2afw";
    782825        break;
    783826    default:
    784827        device_printf(sc->sc_dev, "adapter type %d not supported\n",
    785828            sc->hw_type);
    786         return NULL;
     829        return ENOTSUP;
    787830    }
    788     return sc->sc_hal;
     831    return 0;
    789832}
    790833
    791834/*
    iwn_radiotap_attach(struct iwn_softc *sc)  
    804847        IWN_RX_RADIOTAP_PRESENT);
    805848}
    806849
     850static void
     851iwn_sysctlattach(struct iwn_softc *sc)
     852{
     853    struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev);
     854    struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev);
     855
     856#ifdef IWN_DEBUG
     857    sc->sc_debug = 0;
     858    SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
     859        "debug", CTLFLAG_RW, &sc->sc_debug, 0, "control debugging printfs");
     860#endif
     861}
     862
    807863static struct ieee80211vap *
    808864iwn_vap_create(struct ieee80211com *ic,
    809     const char name[IFNAMSIZ], int unit, int opmode, int flags,
    810     const uint8_t bssid[IEEE80211_ADDR_LEN],
    811     const uint8_t mac[IEEE80211_ADDR_LEN])
     865    const char name[IFNAMSIZ], int unit, enum ieee80211_opmode opmode, int flags,
     866    const uint8_t bssid[IEEE80211_ADDR_LEN],
     867    const uint8_t mac[IEEE80211_ADDR_LEN])
    812868{
    813869    struct iwn_vap *ivp;
    814870    struct ieee80211vap *vap;
    iwn_vap_delete(struct ieee80211vap *vap)  
    844900}
    845901
    846902static int
    847 iwn_cleanup(device_t dev)
     903iwn_detach(device_t dev)
    848904{
    849905    struct iwn_softc *sc = device_get_softc(dev);
    850906    struct ifnet *ifp = sc->sc_ifp;
    851907    struct ieee80211com *ic;
    852     int i;
     908    int qid;
    853909
    854910    if (ifp != NULL) {
    855911        ic = ifp->if_l2com;
    iwn_cleanup(device_t dev)  
    859915        ieee80211_draintask(ic, &sc->sc_radiooff_task);
    860916
    861917        iwn_stop(sc);
    862         callout_drain(&sc->sc_timer_to);
     918        callout_drain(&sc->watchdog_to);
     919        callout_drain(&sc->calib_to);
    863920        ieee80211_ifdetach(ic);
    864921    }
    865922
    866     iwn5000_free_calib_results(sc);
     923    /* Uninstall interrupt handler. */
     924    if (sc->irq != NULL) {
     925        bus_teardown_intr(dev, sc->irq, sc->sc_ih);
     926        bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, sc->irq);
     927        if (sc->irq_rid == 1)
     928            pci_release_msi(dev);
     929    }
    867930
    868931    /* Free DMA resources. */
    869932    iwn_free_rx_ring(sc, &sc->rxq);
    870     if (sc->sc_hal != NULL)
    871         for (i = 0; i < sc->sc_hal->ntxqs; i++)
    872             iwn_free_tx_ring(sc, &sc->txq[i]);
     933    for (qid = 0; qid < sc->ntxqs; qid++)
     934        iwn_free_tx_ring(sc, &sc->txq[qid]);
    873935    iwn_free_sched(sc);
    874936    iwn_free_kw(sc);
    875937    if (sc->ict != NULL)
    876938        iwn_free_ict(sc);
    877939    iwn_free_fwmem(sc);
    878940
    879     if (sc->irq != NULL) {
    880         bus_teardown_intr(dev, sc->irq, sc->sc_ih);
    881         bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, sc->irq);
    882         if (sc->irq_rid == 1)
    883             pci_release_msi(dev);
    884     }
    885 
    886941    if (sc->mem != NULL)
    887942        bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, sc->mem);
    888943
    iwn_cleanup(device_t dev)  
    894949}
    895950
    896951static int
    897 iwn_detach(device_t dev)
     952iwn_shutdown(device_t dev)
     953{
     954    struct iwn_softc *sc = device_get_softc(dev);
     955
     956    iwn_stop(sc);
     957    return 0;
     958}
     959
     960static int
     961iwn_suspend(device_t dev)
    898962{
    899     iwn_cleanup(dev);
     963    struct iwn_softc *sc = device_get_softc(dev);
     964    struct ieee80211com *ic = sc->sc_ifp->if_l2com;
     965
     966    ieee80211_suspend_all(ic);
     967    return 0;
     968}
     969
     970static int
     971iwn_resume(device_t dev)
     972{
     973    struct iwn_softc *sc = device_get_softc(dev);
     974    struct ieee80211com *ic = sc->sc_ifp->if_l2com;
     975
     976    /* Clear device-specific "PCI retry timeout" register (41h). */
     977    pci_write_config(dev, 0x41, 0, 1);
     978
     979    ieee80211_resume_all(ic);
    900980    return 0;
    901981}
    902982
    iwn_nic_lock(struct iwn_softc *sc)  
    911991    /* Spin until we actually get the lock. */
    912992    for (ntries = 0; ntries < 1000; ntries++) {
    913993        if ((IWN_READ(sc, IWN_GP_CNTRL) &
    914             (IWN_GP_CNTRL_MAC_ACCESS_ENA | IWN_GP_CNTRL_SLEEP)) ==
     994             (IWN_GP_CNTRL_MAC_ACCESS_ENA | IWN_GP_CNTRL_SLEEP)) ==
    915995            IWN_GP_CNTRL_MAC_ACCESS_ENA)
    916996            return 0;
    917997        DELAY(10);
    iwn_init_otprom(struct iwn_softc *sc)  
    10441124    int count, error;
    10451125
    10461126    /* Wait for clock stabilization before accessing prph. */
    1047     error = iwn_clock_wait(sc);
    1048     if (error != 0)
     1127    if ((error = iwn_clock_wait(sc)) != 0)
    10491128        return error;
    10501129
    1051     error = iwn_nic_lock(sc);
    1052     if (error != 0)
     1130    if ((error = iwn_nic_lock(sc)) != 0)
    10531131        return error;
    10541132    iwn_prph_setbits(sc, IWN_APMG_PS, IWN_APMG_PS_RESET_REQ);
    10551133    DELAY(5);
    iwn_init_otprom(struct iwn_softc *sc)  
    10941172static int
    10951173iwn_read_prom_data(struct iwn_softc *sc, uint32_t addr, void *data, int count)
    10961174{
     1175    uint8_t *out = data;
    10971176    uint32_t val, tmp;
    10981177    int ntries;
    1099     uint8_t *out = data;
    11001178
    11011179    addr += sc->prom_base;
    11021180    for (; count > 0; count -= 2, addr++) {
    iwn_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nsegs, int error)  
    11441222
    11451223static int
    11461224iwn_dma_contig_alloc(struct iwn_softc *sc, struct iwn_dma_info *dma,
    1147     void **kvap, bus_size_t size, bus_size_t alignment, int flags)
     1225    void **kvap, bus_size_t size, bus_size_t alignment)
    11481226{
    11491227    int error;
    11501228
    1151     dma->size = size;
    11521229    dma->tag = NULL;
     1230    dma->size = size;
    11531231
    11541232    error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), alignment,
    11551233        0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, size,
    1156         1, size, flags, NULL, NULL, &dma->tag);
    1157     if (error != 0) {
    1158         device_printf(sc->sc_dev,
    1159             "%s: bus_dma_tag_create failed, error %d\n",
    1160             __func__, error);
     1234        1, size, BUS_DMA_NOWAIT, NULL, NULL, &dma->tag);
     1235    if (error != 0)
    11611236        goto fail;
    1162     }
     1237
    11631238    error = bus_dmamem_alloc(dma->tag, (void **)&dma->vaddr,
    1164         flags | BUS_DMA_ZERO, &dma->map);
    1165     if (error != 0) {
    1166         device_printf(sc->sc_dev,
    1167             "%s: bus_dmamem_alloc failed, error %d\n", __func__, error);
     1239        BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT, &dma->map);
     1240    if (error != 0)
    11681241        goto fail;
    1169     }
    1170     error = bus_dmamap_load(dma->tag, dma->map, dma->vaddr,
    1171         size, iwn_dma_map_addr, &dma->paddr, flags);
    1172     if (error != 0) {
    1173         device_printf(sc->sc_dev,
    1174             "%s: bus_dmamap_load failed, error %d\n", __func__, error);
     1242
     1243    error = bus_dmamap_load(dma->tag, dma->map, dma->vaddr, size,
     1244        iwn_dma_map_addr, &dma->paddr, BUS_DMA_NOWAIT);
     1245    if (error != 0)
    11751246        goto fail;
    1176     }
     1247
     1248    bus_dmamap_sync(dma->tag, dma->map, BUS_DMASYNC_PREWRITE);
    11771249
    11781250    if (kvap != NULL)
    11791251        *kvap = dma->vaddr;
     1252
    11801253    return 0;
    1181 fail:
    1182     iwn_dma_contig_free(dma);
     1254
     1255fail:   iwn_dma_contig_free(dma);
    11831256    return error;
    11841257}
    11851258
    11861259static void
    11871260iwn_dma_contig_free(struct iwn_dma_info *dma)
    11881261{
    1189     if (dma->tag != NULL) {
    1190         if (dma->map != NULL) {
    1191             if (dma->paddr == 0) {
    1192                 bus_dmamap_sync(dma->tag, dma->map,
    1193                     BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
    1194                 bus_dmamap_unload(dma->tag, dma->map);
    1195             }
     1262    if (dma->map != NULL) {
     1263        if (dma->vaddr != NULL) {
     1264            bus_dmamap_sync(dma->tag, dma->map,
     1265                BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
     1266            bus_dmamap_unload(dma->tag, dma->map);
    11961267            bus_dmamem_free(dma->tag, &dma->vaddr, dma->map);
     1268            dma->vaddr = NULL;
    11971269        }
     1270        bus_dmamap_destroy(dma->tag, dma->map);
     1271        dma->map = NULL;
     1272    }
     1273    if (dma->tag != NULL) {
    11981274        bus_dma_tag_destroy(dma->tag);
     1275        dma->tag = NULL;
    11991276    }
    12001277}
    12011278
    static int  
    12031280iwn_alloc_sched(struct iwn_softc *sc)
    12041281{
    12051282    /* TX scheduler rings must be aligned on a 1KB boundary. */
    1206     return iwn_dma_contig_alloc(sc, &sc->sched_dma,
    1207         (void **)&sc->sched, sc->sc_hal->schedsz, 1024, BUS_DMA_NOWAIT);
     1283    return iwn_dma_contig_alloc(sc, &sc->sched_dma, (void **)&sc->sched,
     1284        sc->schedsz, 1024);
    12081285}
    12091286
    12101287static void
    static int  
    12171294iwn_alloc_kw(struct iwn_softc *sc)
    12181295{
    12191296    /* "Keep Warm" page must be aligned on a 4KB boundary. */
    1220     return iwn_dma_contig_alloc(sc, &sc->kw_dma, NULL, 4096, 4096,
    1221         BUS_DMA_NOWAIT);
     1297    return iwn_dma_contig_alloc(sc, &sc->kw_dma, NULL, 4096, 4096);
    12221298}
    12231299
    12241300static void
    static int  
    12311307iwn_alloc_ict(struct iwn_softc *sc)
    12321308{
    12331309    /* ICT table must be aligned on a 4KB boundary. */
    1234     return iwn_dma_contig_alloc(sc, &sc->ict_dma,
    1235         (void **)&sc->ict, IWN_ICT_SIZE, 4096, BUS_DMA_NOWAIT);
     1310    return iwn_dma_contig_alloc(sc, &sc->ict_dma, (void **)&sc->ict,
     1311        IWN_ICT_SIZE, 4096);
    12361312}
    12371313
    12381314static void
    static int  
    12451321iwn_alloc_fwmem(struct iwn_softc *sc)
    12461322{
    12471323    /* Must be aligned on a 16-byte boundary. */
    1248     return iwn_dma_contig_alloc(sc, &sc->fw_dma, NULL,
    1249         sc->sc_hal->fwsz, 16, BUS_DMA_NOWAIT);
     1324    return iwn_dma_contig_alloc(sc, &sc->fw_dma, NULL, sc->fwsz, 16);
    12501325}
    12511326
    12521327static void
    iwn_alloc_rx_ring(struct iwn_softc *sc, struct iwn_rx_ring *ring)  
    12651340
    12661341    /* Allocate RX descriptors (256-byte aligned). */
    12671342    size = IWN_RX_RING_COUNT * sizeof (uint32_t);
    1268     error = iwn_dma_contig_alloc(sc, &ring->desc_dma,
    1269         (void **)&ring->desc, size, 256, BUS_DMA_NOWAIT);
     1343    error = iwn_dma_contig_alloc(sc, &ring->desc_dma, (void **)&ring->desc,
     1344        size, 256);
    12701345    if (error != 0) {
    12711346        device_printf(sc->sc_dev,
    1272             "%s: could not allocate Rx ring DMA memory, error %d\n",
     1347            "%s: could not allocate RX ring DMA memory, error %d\n",
    12731348            __func__, error);
    12741349        goto fail;
    12751350    }
    12761351
    1277     error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0,
    1278         BUS_SPACE_MAXADDR_32BIT,
    1279         BUS_SPACE_MAXADDR, NULL, NULL, MJUMPAGESIZE, 1,
    1280         MJUMPAGESIZE, BUS_DMA_NOWAIT, NULL, NULL, &ring->data_dmat);
     1352    /* Allocate RX status area (16-byte aligned). */
     1353    error = iwn_dma_contig_alloc(sc, &ring->stat_dma, (void **)&ring->stat,
     1354        sizeof (struct iwn_rx_status), 16);
    12811355    if (error != 0) {
    12821356        device_printf(sc->sc_dev,
    1283             "%s: bus_dma_tag_create_failed, error %d\n",
     1357            "%s: could not allocate RX status DMA memory, error %d\n",
    12841358            __func__, error);
    12851359        goto fail;
    12861360    }
    12871361
    1288     /* Allocate RX status area (16-byte aligned). */
    1289     error = iwn_dma_contig_alloc(sc, &ring->stat_dma,
    1290         (void **)&ring->stat, sizeof (struct iwn_rx_status),
    1291         16, BUS_DMA_NOWAIT);
     1362    /* Create RX buffer DMA tag. */
     1363    error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0,
     1364        BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
     1365        IWN_RBUF_SIZE, 1, IWN_RBUF_SIZE, BUS_DMA_NOWAIT, NULL, NULL,
     1366        &ring->data_dmat);
    12921367    if (error != 0) {
    12931368        device_printf(sc->sc_dev,
    1294             "%s: could not allocate Rx status DMA memory, error %d\n",
     1369            "%s: could not create RX buf DMA tag, error %d\n",
    12951370            __func__, error);
    12961371        goto fail;
    12971372    }
    iwn_alloc_rx_ring(struct iwn_softc *sc, struct iwn_rx_ring *ring)  
    13061381        error = bus_dmamap_create(ring->data_dmat, 0, &data->map);
    13071382        if (error != 0) {
    13081383            device_printf(sc->sc_dev,
    1309                 "%s: bus_dmamap_create failed, error %d\n",
     1384                "%s: could not create RX buf DMA map, error %d\n",
    13101385                __func__, error);
    13111386            goto fail;
    13121387        }
    13131388
    1314         data->m = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, MJUMPAGESIZE);
     1389        data->m = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR,
     1390            IWN_RBUF_SIZE);
    13151391        if (data->m == NULL) {
    13161392            device_printf(sc->sc_dev,
    1317                 "%s: could not allocate rx mbuf\n", __func__);
    1318             error = ENOMEM;
     1393                "%s: could not allocate RX mbuf\n", __func__);
     1394            error = ENOBUFS;
    13191395            goto fail;
    13201396        }
    13211397
    1322         /* Map page. */
    13231398        error = bus_dmamap_load(ring->data_dmat, data->map,
    1324             mtod(data->m, caddr_t), MJUMPAGESIZE,
    1325             iwn_dma_map_addr, &paddr, BUS_DMA_NOWAIT);
     1399            mtod(data->m, void *), IWN_RBUF_SIZE, iwn_dma_map_addr,
     1400            &paddr, BUS_DMA_NOWAIT);
    13261401        if (error != 0 && error != EFBIG) {
    13271402            device_printf(sc->sc_dev,
    1328                 "%s: bus_dmamap_load failed, error %d\n",
    1329                 __func__, error);
    1330             m_freem(data->m);
    1331             error = ENOMEM; /* XXX unique code */
     1403                "%s: can't not map mbuf, error %d\n", __func__,
     1404                error);
    13321405            goto fail;
    13331406        }
    1334         bus_dmamap_sync(ring->data_dmat, data->map,
    1335             BUS_DMASYNC_PREWRITE);
    13361407
    13371408        /* Set physical address of RX buffer (256-byte aligned). */
    13381409        ring->desc[i] = htole32(paddr >> 8);
    13391410    }
     1411
    13401412    bus_dmamap_sync(ring->desc_dma.tag, ring->desc_dma.map,
    13411413        BUS_DMASYNC_PREWRITE);
     1414
    13421415    return 0;
    1343 fail:
    1344     iwn_free_rx_ring(sc, ring);
     1416
     1417fail:   iwn_free_rx_ring(sc, ring);
    13451418    return error;
    13461419}
    13471420
    iwn_reset_rx_ring(struct iwn_softc *sc, struct iwn_rx_ring *ring)  
    13591432            DELAY(10);
    13601433        }
    13611434        iwn_nic_unlock(sc);
    1362 #ifdef IWN_DEBUG
    1363         if (ntries == 1000)
    1364             DPRINTF(sc, IWN_DEBUG_ANY, "%s\n",
    1365                 "timeout resetting Rx ring");
    1366 #endif
    13671435    }
    13681436    ring->cur = 0;
    13691437    sc->last_rx_valid = 0;
    iwn_free_rx_ring(struct iwn_softc *sc, struct iwn_rx_ring *ring)  
    13851453                BUS_DMASYNC_POSTREAD);
    13861454            bus_dmamap_unload(ring->data_dmat, data->map);
    13871455            m_freem(data->m);
     1456            data->m = NULL;
    13881457        }
    13891458        if (data->map != NULL)
    13901459            bus_dmamap_destroy(ring->data_dmat, data->map);
    13911460    }
     1461    if (ring->data_dmat != NULL) {
     1462        bus_dma_tag_destroy(ring->data_dmat);
     1463        ring->data_dmat = NULL;
     1464    }
    13921465}
    13931466
    13941467static int
    13951468iwn_alloc_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring, int qid)
    13961469{
    1397     bus_size_t size;
    13981470    bus_addr_t paddr;
     1471    bus_size_t size;
    13991472    int i, error;
    14001473
    14011474    ring->qid = qid;
    14021475    ring->queued = 0;
    14031476    ring->cur = 0;
    14041477
    1405     /* Allocate TX descriptors (256-byte aligned.) */
    1406     size = IWN_TX_RING_COUNT * sizeof(struct iwn_tx_desc);
    1407     error = iwn_dma_contig_alloc(sc, &ring->desc_dma,
    1408         (void **)&ring->desc, size, 256, BUS_DMA_NOWAIT);
     1478    /* Allocate TX descriptors (256-byte aligned). */
     1479    size = IWN_TX_RING_COUNT * sizeof (struct iwn_tx_desc);
     1480    error = iwn_dma_contig_alloc(sc, &ring->desc_dma, (void **)&ring->desc,
     1481        size, 256);
    14091482    if (error != 0) {
    14101483        device_printf(sc->sc_dev,
    14111484            "%s: could not allocate TX ring DMA memory, error %d\n",
    14121485            __func__, error);
    14131486        goto fail;
    14141487    }
    1415 
    14161488    /*
    14171489     * We only use rings 0 through 4 (4 EDCA + cmd) so there is no need
    14181490     * to allocate commands space for other rings.
     1491     * XXX Do we really need to allocate descriptors for other rings?
    14191492     */
    14201493    if (qid > 4)
    14211494        return 0;
    14221495
    1423     size = IWN_TX_RING_COUNT * sizeof(struct iwn_tx_cmd);
    1424     error = iwn_dma_contig_alloc(sc, &ring->cmd_dma,
    1425         (void **)&ring->cmd, size, 4, BUS_DMA_NOWAIT);
     1496    size = IWN_TX_RING_COUNT * sizeof (struct iwn_tx_cmd);
     1497    error = iwn_dma_contig_alloc(sc, &ring->cmd_dma, (void **)&ring->cmd,
     1498        size, 4);
    14261499    if (error != 0) {
    14271500        device_printf(sc->sc_dev,
    14281501            "%s: could not allocate TX cmd DMA memory, error %d\n",
    iwn_alloc_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring, int qid)  
    14311504    }
    14321505
    14331506    error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0,
    1434         BUS_SPACE_MAXADDR_32BIT,
    1435         BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES, IWN_MAX_SCATTER - 1,
    1436         MCLBYTES, BUS_DMA_NOWAIT, NULL, NULL, &ring->data_dmat);
     1507        BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES,
     1508        IWN_MAX_SCATTER - 1, MCLBYTES, BUS_DMA_NOWAIT, NULL, NULL,
     1509        &ring->data_dmat);
    14371510    if (error != 0) {
    14381511        device_printf(sc->sc_dev,
    1439             "%s: bus_dma_tag_create_failed, error %d\n",
     1512            "%s: could not create TX buf DMA tag, error %d\n",
    14401513            __func__, error);
    14411514        goto fail;
    14421515    }
    iwn_alloc_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring, int qid)  
    14521525        error = bus_dmamap_create(ring->data_dmat, 0, &data->map);
    14531526        if (error != 0) {
    14541527            device_printf(sc->sc_dev,
    1455                 "%s: bus_dmamap_create failed, error %d\n",
     1528                "%s: could not create TX buf DMA map, error %d\n",
    14561529                __func__, error);
    14571530            goto fail;
    14581531        }
    1459         bus_dmamap_sync(ring->data_dmat, data->map,
    1460             BUS_DMASYNC_PREWRITE);
    14611532    }
    14621533    return 0;
    1463 fail:
    1464     iwn_free_tx_ring(sc, ring);
     1534
     1535fail:   iwn_free_tx_ring(sc, ring);
    14651536    return error;
    14661537}
    14671538
    iwn_reset_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring)  
    14741545        struct iwn_tx_data *data = &ring->data[i];
    14751546
    14761547        if (data->m != NULL) {
     1548            bus_dmamap_sync(ring->data_dmat, data->map,
     1549                BUS_DMASYNC_POSTWRITE);
    14771550            bus_dmamap_unload(ring->data_dmat, data->map);
    14781551            m_freem(data->m);
    14791552            data->m = NULL;
    iwn_free_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring)  
    15081581        if (data->map != NULL)
    15091582            bus_dmamap_destroy(ring->data_dmat, data->map);
    15101583    }
     1584    if (ring->data_dmat != NULL) {
     1585        bus_dma_tag_destroy(ring->data_dmat);
     1586        ring->data_dmat = NULL;
     1587    }
    15111588}
    15121589
    15131590static void
    iwn5000_ict_reset(struct iwn_softc *sc)  
    15201597    memset(sc->ict, 0, IWN_ICT_SIZE);
    15211598    sc->ict_cur = 0;
    15221599
    1523     /* Set physical address of ICT table (4KB aligned.) */
     1600    /* Set physical address of ICT table (4KB aligned). */
    15241601    DPRINTF(sc, IWN_DEBUG_RESET, "%s: enabling ICT\n", __func__);
    15251602    IWN_WRITE(sc, IWN_DRAM_INT_TBL, IWN_DRAM_INT_TBL_ENABLE |
    15261603        IWN_DRAM_INT_TBL_WRAP_CHECK | sc->ict_dma.paddr >> 12);
    iwn5000_ict_reset(struct iwn_softc *sc)  
    15381615static int
    15391616iwn_read_eeprom(struct iwn_softc *sc, uint8_t macaddr[IEEE80211_ADDR_LEN])
    15401617{
    1541     const struct iwn_hal *hal = sc->sc_hal;
    1542     int error;
     1618    struct iwn_ops *ops = &sc->ops;
    15431619    uint16_t val;
     1620    int error;
    15441621
    15451622    /* Check whether adapter has an EEPROM or an OTPROM. */
    15461623    if (sc->hw_type >= IWN_HW_REV_TYPE_1000 &&
    iwn_read_eeprom(struct iwn_softc *sc, uint8_t macaddr[IEEE80211_ADDR_LEN])  
    15501627        (sc->sc_flags & IWN_FLAG_HAS_OTPROM) ? "OTPROM" : "EEPROM");
    15511628
    15521629    /* Adapter has to be powered on for EEPROM access to work. */
    1553     error = iwn_apm_init(sc);
    1554     if (error != 0) {
     1630    if ((error = iwn_apm_init(sc)) != 0) {
    15551631        device_printf(sc->sc_dev,
    1556             "%s: could not power ON adapter, error %d\n",
    1557             __func__, error);
     1632            "%s: could not power ON adapter, error %d\n", __func__,
     1633            error);
    15581634        return error;
    15591635    }
    15601636
    iwn_read_eeprom(struct iwn_softc *sc, uint8_t macaddr[IEEE80211_ADDR_LEN])  
    15621638        device_printf(sc->sc_dev, "%s: bad ROM signature\n", __func__);
    15631639        return EIO;
    15641640    }
    1565     error = iwn_eeprom_lock(sc);
    1566     if (error != 0) {
    1567         device_printf(sc->sc_dev,
    1568             "%s: could not lock ROM, error %d\n",
     1641    if ((error = iwn_eeprom_lock(sc)) != 0) {
     1642        device_printf(sc->sc_dev, "%s: could not lock ROM, error %d\n",
    15691643            __func__, error);
    15701644        return error;
    15711645    }
    1572 
    15731646    if (sc->sc_flags & IWN_FLAG_HAS_OTPROM) {
    1574         error = iwn_init_otprom(sc);
    1575         if (error != 0) {
     1647        if ((error = iwn_init_otprom(sc)) != 0) {
    15761648            device_printf(sc->sc_dev,
    15771649                "%s: could not initialize OTPROM, error %d\n",
    15781650                __func__, error);
    iwn_read_eeprom(struct iwn_softc *sc, uint8_t macaddr[IEEE80211_ADDR_LEN])  
    15801652        }
    15811653    }
    15821654
     1655    iwn_read_prom_data(sc, IWN_EEPROM_SKU_CAP, &val, 2);
     1656    DPRINTF(sc, IWN_DEBUG_RESET, "SKU capabilities=0x%04x\n", le16toh(val));
     1657    /* Check if HT support is bonded out. */
     1658    if (val & htole16(IWN_EEPROM_SKU_CAP_11N))
     1659        sc->sc_flags |= IWN_FLAG_HAS_11N;
     1660
    15831661    iwn_read_prom_data(sc, IWN_EEPROM_RFCFG, &val, 2);
    15841662    sc->rfcfg = le16toh(val);
    15851663    DPRINTF(sc, IWN_DEBUG_RESET, "radio config=0x%04x\n", sc->rfcfg);
     1664    /* Read Tx/Rx chains from ROM unless it's known to be broken. */
     1665    if (sc->txchainmask == 0)
     1666        sc->txchainmask = IWN_RFCFG_TXANTMSK(sc->rfcfg);
     1667    if (sc->rxchainmask == 0)
     1668        sc->rxchainmask = IWN_RFCFG_RXANTMSK(sc->rfcfg);
    15861669
    15871670    /* Read MAC address. */
    15881671    iwn_read_prom_data(sc, IWN_EEPROM_MAC, macaddr, 6);
    15891672
    15901673    /* Read adapter-specific information from EEPROM. */
    1591     hal->read_eeprom(sc);
     1674    ops->read_eeprom(sc);
    15921675
    15931676    iwn_apm_stop(sc);   /* Power OFF adapter. */
    15941677
    static void  
    16001683iwn4965_read_eeprom(struct iwn_softc *sc)
    16011684{
    16021685    uint32_t addr;
    1603     int i;
    16041686    uint16_t val;
     1687    int i;
    16051688
    1606     /* Read regulatory domain (4 ASCII characters.) */
     1689    /* Read regulatory domain (4 ASCII characters). */
    16071690    iwn_read_prom_data(sc, IWN4965_EEPROM_DOMAIN, sc->eeprom_domain, 4);
    16081691
    1609     /* Read the list of authorized channels (20MHz ones only.) */
     1692    /* Read the list of authorized channels (20MHz ones only). */
    16101693    for (i = 0; i < 5; i++) {
    16111694        addr = iwn4965_regulatory_bands[i];
    16121695        iwn_read_eeprom_channels(sc, i, addr);
    static void  
    16821765iwn5000_read_eeprom(struct iwn_softc *sc)
    16831766{
    16841767    struct iwn5000_eeprom_calib_hdr hdr;
    1685     int32_t temp, volt;
    1686     uint32_t addr, base;
    1687     int i;
     1768    int32_t volt;
     1769    uint32_t base, addr;
    16881770    uint16_t val;
     1771    int i;
    16891772
    1690     /* Read regulatory domain (4 ASCII characters.) */
     1773    /* Read regulatory domain (4 ASCII characters). */
    16911774    iwn_read_prom_data(sc, IWN5000_EEPROM_REG, &val, 2);
    16921775    base = le16toh(val);
    16931776    iwn_read_prom_data(sc, base + IWN5000_EEPROM_DOMAIN,
    16941777        sc->eeprom_domain, 4);
    16951778
    1696     /* Read the list of authorized channels (20MHz ones only.) */
     1779    /* Read the list of authorized channels (20MHz ones only). */
    16971780    for (i = 0; i < 5; i++) {
    16981781        addr = base + iwn5000_regulatory_bands[i];
    16991782        iwn_read_eeprom_channels(sc, i, addr);
    iwn5000_read_eeprom(struct iwn_softc *sc)  
    17071790    base = le16toh(val);
    17081791    iwn_read_prom_data(sc, base, &hdr, sizeof hdr);
    17091792    DPRINTF(sc, IWN_DEBUG_CALIBRATE,
    1710         "%s: calib version=%u pa type=%u voltage=%u\n",
    1711         __func__, hdr.version, hdr.pa_type, le16toh(hdr.volt));
     1793        "%s: calib version=%u pa type=%u voltage=%u\n", __func__,
     1794        hdr.version, hdr.pa_type, le16toh(hdr.volt));
    17121795    sc->calib_ver = hdr.version;
    17131796
    17141797    if (sc->hw_type == IWN_HW_REV_TYPE_5150) {
    17151798        /* Compute temperature offset. */
    17161799        iwn_read_prom_data(sc, base + IWN5000_EEPROM_TEMP, &val, 2);
    1717         temp = le16toh(val);
     1800        sc->eeprom_temp = le16toh(val);
    17181801        iwn_read_prom_data(sc, base + IWN5000_EEPROM_VOLT, &val, 2);
    17191802        volt = le16toh(val);
    1720         sc->temp_off = temp - (volt / -5);
     1803        sc->temp_off = sc->eeprom_temp - (volt / -5);
    17211804        DPRINTF(sc, IWN_DEBUG_CALIBRATE, "temp=%d volt=%d offset=%dK\n",
    1722             temp, volt, sc->temp_off);
     1805            sc->eeprom_temp, volt, sc->temp_off);
     1806    } else {
     1807        /* Read crystal calibration. */
     1808        iwn_read_prom_data(sc, base + IWN5000_EEPROM_CRYSTAL,
     1809            &sc->eeprom_crystal, sizeof (uint32_t));
     1810        DPRINTF(sc, IWN_DEBUG_CALIBRATE, "crystal calibration 0x%08x\n",
     1811            le32toh(sc->eeprom_crystal));
    17231812    }
    17241813}
    17251814
    iwn_read_eeprom_band(struct iwn_softc *sc, int n)  
    17531842    struct iwn_eeprom_chan *channels = sc->eeprom_channels[n];
    17541843    const struct iwn_chan_band *band = &iwn_bands[n];
    17551844    struct ieee80211_channel *c;
    1756     int i, chan, nflags;
     1845    uint8_t chan;
     1846    int i, nflags;
    17571847
    17581848    for (i = 0; i < band->nchan; i++) {
    17591849        if (!(channels[i].flags & IWN_EEPROM_CHAN_VALID)) {
    iwn_read_eeprom_band(struct iwn_softc *sc, int n)  
    17661856        chan = band->chan[i];
    17671857        nflags = iwn_eeprom_channel_flags(&channels[i]);
    17681858
    1769         DPRINTF(sc, IWN_DEBUG_RESET,
    1770             "add chan %d flags 0x%x maxpwr %d\n",
    1771             chan, channels[i].flags, channels[i].maxpwr);
    1772 
    17731859        c = &ic->ic_channels[ic->ic_nchans++];
    17741860        c->ic_ieee = chan;
    17751861        c->ic_maxregpower = channels[i].maxpwr;
    17761862        c->ic_maxpower = 2*c->ic_maxregpower;
    17771863
    1778         /* Save maximum allowed TX power for this channel. */
    1779         sc->maxpwr[chan] = channels[i].maxpwr;
    1780 
    17811864        if (n == 0) {   /* 2GHz band */
    1782             c->ic_freq = ieee80211_ieee2mhz(chan,
    1783                 IEEE80211_CHAN_G);
    1784 
     1865            c->ic_freq = ieee80211_ieee2mhz(chan, IEEE80211_CHAN_G);
    17851866            /* G =>'s B is supported */
    17861867            c->ic_flags = IEEE80211_CHAN_B | nflags;
    1787 
    17881868            c = &ic->ic_channels[ic->ic_nchans++];
    17891869            c[0] = c[-1];
    17901870            c->ic_flags = IEEE80211_CHAN_G | nflags;
    17911871        } else {    /* 5GHz band */
    1792             c->ic_freq = ieee80211_ieee2mhz(chan,
    1793                 IEEE80211_CHAN_A);
     1872            c->ic_freq = ieee80211_ieee2mhz(chan, IEEE80211_CHAN_A);
    17941873            c->ic_flags = IEEE80211_CHAN_A | nflags;
    1795             sc->sc_flags |= IWN_FLAG_HAS_5GHZ;
    17961874        }
     1875
     1876        /* Save maximum allowed TX power for this channel. */
     1877        sc->maxpwr[chan] = channels[i].maxpwr;
     1878
     1879        DPRINTF(sc, IWN_DEBUG_RESET,
     1880            "add chan %d flags 0x%x maxpwr %d\n", chan,
     1881            channels[i].flags, channels[i].maxpwr);
     1882
    17971883#if 0   /* HT */
    17981884        /* XXX no constraints on using HT20 */
    17991885        /* add HT20, HT40 added separately */
    iwn_read_eeprom_channels(struct iwn_softc *sc, int n, uint32_t addr)  
    18821968    ieee80211_sort_channels(ic->ic_channels, ic->ic_nchans);
    18831969}
    18841970
    1885 #define nitems(_a)  (sizeof((_a)) / sizeof((_a)[0]))
     1971static struct iwn_eeprom_chan *
     1972iwn_find_eeprom_channel(struct iwn_softc *sc, struct ieee80211_channel *c)
     1973{
     1974    int i, j;
     1975
     1976    for (j = 0; j < 7; j++) {
     1977        for (i = 0; i < iwn_bands[j].nchan; i++) {
     1978            if (iwn_bands[j].chan[i] == c->ic_ieee)
     1979                return &sc->eeprom_channels[j][i];
     1980        }
     1981    }
     1982
     1983    return NULL;
     1984}
     1985
     1986/*
     1987 * Enforce flags read from EEPROM.
     1988 */
     1989static int
     1990iwn_setregdomain(struct ieee80211com *ic, struct ieee80211_regdomain *rd,
     1991    int nchan, struct ieee80211_channel chans[])
     1992{
     1993    struct iwn_softc *sc = ic->ic_ifp->if_softc;
     1994    int i;
     1995
     1996    for (i = 0; i < nchan; i++) {
     1997        struct ieee80211_channel *c = &chans[i];
     1998        struct iwn_eeprom_chan *channel;
     1999
     2000        channel = iwn_find_eeprom_channel(sc, c);
     2001        if (channel == NULL) {
     2002            if_printf(ic->ic_ifp,
     2003                "%s: invalid channel %u freq %u/0x%x\n",
     2004                __func__, c->ic_ieee, c->ic_freq, c->ic_flags);
     2005            return EINVAL;
     2006        }
     2007        c->ic_flags |= iwn_eeprom_channel_flags(channel);
     2008    }
     2009
     2010    return 0;
     2011}
    18862012
    18872013static void
    18882014iwn_read_eeprom_enhinfo(struct iwn_softc *sc)
    iwn_node_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN])  
    19272053    return malloc(sizeof (struct iwn_node), M_80211_NODE,M_NOWAIT | M_ZERO);
    19282054}
    19292055
     2056static void
     2057iwn_newassoc(struct ieee80211_node *ni, int isnew)
     2058{
     2059    struct iwn_node *wn = (void *)ni;
     2060    int ridx, i;
     2061
     2062    for (i = 0; i < ni->ni_rates.rs_nrates; i++) {
     2063        ridx = iwn_plcp_signal(ni->ni_rates.rs_rates[i]);
     2064        wn->ridx[i] = ridx;
     2065    }
     2066}
     2067
    19302068static int
    19312069iwn_media_change(struct ifnet *ifp)
    19322070{
    1933     int error = ieee80211_media_change(ifp);
     2071    int error;
     2072
     2073    error = ieee80211_media_change(ifp);
    19342074    /* NB: only the fixed rate can change and that doesn't need a reset */
    19352075    return (error == ENETRESET ? 0 : error);
    19362076}
    iwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)  
    19412081    struct iwn_vap *ivp = IWN_VAP(vap);
    19422082    struct ieee80211com *ic = vap->iv_ic;
    19432083    struct iwn_softc *sc = ic->ic_ifp->if_softc;
    1944     int error;
     2084    int error = 0;
    19452085
    19462086    DPRINTF(sc, IWN_DEBUG_STATE, "%s: %s -> %s\n", __func__,
    1947         ieee80211_state_name[vap->iv_state],
    1948         ieee80211_state_name[nstate]);
     2087        ieee80211_state_name[vap->iv_state], ieee80211_state_name[nstate]);
    19492088
    19502089    IEEE80211_UNLOCK(ic);
    19512090    IWN_LOCK(sc);
    1952     callout_stop(&sc->sc_timer_to);
     2091    callout_stop(&sc->calib_to);
    19532092
    19542093    switch (nstate) {
    19552094    case IEEE80211_S_ASSOC:
    iwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)  
    19662105         */
    19672106        sc->rxon.associd = 0;
    19682107        sc->rxon.filter &= ~htole32(IWN_FILTER_BSS);
    1969         iwn_calib_reset(sc);
    1970         error = iwn_auth(sc, vap);
     2108        sc->calib.state = IWN_CALIB_STATE_INIT;
     2109
     2110        if ((error = iwn_auth(sc, vap)) != 0) {
     2111            device_printf(sc->sc_dev,
     2112                "%s: could not move to auth state\n", __func__);
     2113        }
    19712114        break;
    19722115
    19732116    case IEEE80211_S_RUN:
    19742117        /*
    19752118         * RUN -> RUN transition; Just restart the timers.
    19762119         */
    1977         if (vap->iv_state == IEEE80211_S_RUN &&
    1978             vap->iv_opmode != IEEE80211_M_MONITOR) {
    1979             iwn_calib_reset(sc);
     2120        if (vap->iv_state == IEEE80211_S_RUN) {
     2121            sc->calib_cnt = 0;
    19802122            break;
    19812123        }
    19822124
    iwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)  
    19852127         * which is done with a firmware cmd.  We also defer
    19862128         * starting the timers until that work is done.
    19872129         */
    1988         error = iwn_run(sc, vap);
     2130        if ((error = iwn_run(sc, vap)) != 0) {
     2131            device_printf(sc->sc_dev,
     2132                "%s: could not move to run state\n", __func__);
     2133        }
     2134        break;
     2135
     2136    case IEEE80211_S_INIT:
     2137        sc->calib.state = IWN_CALIB_STATE_INIT;
    19892138        break;
    19902139
    19912140    default:
    iwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)  
    19932142    }
    19942143    IWN_UNLOCK(sc);
    19952144    IEEE80211_LOCK(ic);
     2145    if (error != 0)
     2146        return error;
    19962147    return ivp->iv_newstate(vap, nstate, arg);
    19972148}
    19982149
     2150static void
     2151iwn_calib_timeout(void *arg)
     2152{
     2153    struct iwn_softc *sc = arg;
     2154
     2155    IWN_LOCK_ASSERT(sc);
     2156
     2157    /* Force automatic TX power calibration every 60 secs. */
     2158    if (++sc->calib_cnt >= 120) {
     2159        uint32_t flags = 0;
     2160
     2161        DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s\n",
     2162            "sending request for statistics");
     2163        (void)iwn_cmd(sc, IWN_CMD_GET_STATISTICS, &flags,
     2164            sizeof flags, 1);
     2165        sc->calib_cnt = 0;
     2166    }
     2167    callout_reset(&sc->calib_to, msecs_to_ticks(500), iwn_calib_timeout,
     2168        sc);
     2169}
     2170
    19992171/*
    20002172 * Process an RX_PHY firmware notification.  This is usually immediately
    20012173 * followed by an MPDU_RX_DONE notification.
    iwn_rx_phy(struct iwn_softc *sc, struct iwn_rx_desc *desc,  
    20142186    sc->last_rx_valid = 1;
    20152187}
    20162188
    2017 static void
    2018 iwn_timer_timeout(void *arg)
    2019 {
    2020     struct iwn_softc *sc = arg;
    2021     uint32_t flags = 0;
    2022 
    2023     IWN_LOCK_ASSERT(sc);
    2024 
    2025     if (sc->calib_cnt && --sc->calib_cnt == 0) {
    2026         DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s\n",
    2027             "send statistics request");
    2028         (void) iwn_cmd(sc, IWN_CMD_GET_STATISTICS, &flags,
    2029             sizeof flags, 1);
    2030         sc->calib_cnt = 60; /* do calibration every 60s */
    2031     }
    2032     iwn_watchdog(sc);       /* NB: piggyback tx watchdog */
    2033     callout_reset(&sc->sc_timer_to, hz, iwn_timer_timeout, sc);
    2034 }
    2035 
    2036 static void
    2037 iwn_calib_reset(struct iwn_softc *sc)
    2038 {
    2039     callout_reset(&sc->sc_timer_to, hz, iwn_timer_timeout, sc);
    2040     sc->calib_cnt = 60;     /* do calibration every 60s */
    2041 }
    2042 
    20432189/*
    20442190 * Process an RX_DONE (4965AGN only) or MPDU_RX_DONE firmware notification.
    20452191 * Each MPDU_RX_DONE notification must be preceded by an RX_PHY one.
    static void  
    20482194iwn_rx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc,
    20492195    struct iwn_rx_data *data)
    20502196{
    2051     const struct iwn_hal *hal = sc->sc_hal;
     2197    struct iwn_ops *ops = &sc->ops;
    20522198    struct ifnet *ifp = sc->sc_ifp;
    20532199    struct ieee80211com *ic = ifp->if_l2com;
    20542200    struct iwn_rx_ring *ring = &sc->rxq;
    iwn_rx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc,  
    20662212        if (!sc->last_rx_valid) {
    20672213            DPRINTF(sc, IWN_DEBUG_ANY,
    20682214                "%s: missing RX_PHY\n", __func__);
    2069             ifp->if_ierrors++;
    20702215            return;
    20712216        }
    20722217        sc->last_rx_valid = 0;
    iwn_rx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc,  
    20782223
    20792224    if (stat->cfg_phy_len > IWN_STAT_MAXLEN) {
    20802225        device_printf(sc->sc_dev,
    2081             "%s: invalid rx statistic header, len %d\n",
    2082             __func__, stat->cfg_phy_len);
    2083         ifp->if_ierrors++;
     2226            "%s: invalid RX statistic header, len %d\n", __func__,
     2227            stat->cfg_phy_len);
    20842228        return;
    20852229    }
    20862230    if (desc->type == IWN_MPDU_RX_DONE) {
    iwn_rx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc,  
    20962240
    20972241    /* Discard frames with a bad FCS early. */
    20982242    if ((flags & IWN_RX_NOERROR) != IWN_RX_NOERROR) {
    2099         DPRINTF(sc, IWN_DEBUG_RECV, "%s: rx flags error %x\n",
     2243        DPRINTF(sc, IWN_DEBUG_RECV, "%s: RX flags error %x\n",
    21002244            __func__, flags);
    21012245        ifp->if_ierrors++;
    21022246        return;
    iwn_rx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc,  
    21092253        return;
    21102254    }
    21112255
    2112     /* XXX don't need mbuf, just dma buffer */
    2113     m1 = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, MJUMPAGESIZE);
     2256    m1 = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, IWN_RBUF_SIZE);
    21142257    if (m1 == NULL) {
    21152258        DPRINTF(sc, IWN_DEBUG_ANY, "%s: no mbuf to restock ring\n",
    21162259            __func__);
    iwn_rx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc,  
    21192262    }
    21202263    bus_dmamap_unload(ring->data_dmat, data->map);
    21212264
    2122     error = bus_dmamap_load(ring->data_dmat, data->map,
    2123         mtod(m1, caddr_t), MJUMPAGESIZE,
    2124         iwn_dma_map_addr, &paddr, BUS_DMA_NOWAIT);
     2265    error = bus_dmamap_load(ring->data_dmat, data->map, mtod(m1, void *),
     2266        IWN_RBUF_SIZE, iwn_dma_map_addr, &paddr, BUS_DMA_NOWAIT);
    21252267    if (error != 0 && error != EFBIG) {
    21262268        device_printf(sc->sc_dev,
    21272269            "%s: bus_dmamap_load failed, error %d\n", __func__, error);
    21282270        m_freem(m1);
     2271
     2272        /* Try to reload the old mbuf. */
     2273        error = bus_dmamap_load(ring->data_dmat, data->map,
     2274            mtod(data->m, void *), IWN_RBUF_SIZE, iwn_dma_map_addr,
     2275            &paddr, BUS_DMA_NOWAIT);
     2276        if (error != 0 && error != EFBIG) {
     2277            panic("%s: could not load old RX mbuf", __func__);
     2278        }
     2279        /* Physical address may have changed. */
     2280        ring->desc[ring->cur] = htole32(paddr >> 8);
     2281        bus_dmamap_sync(ring->data_dmat, ring->desc_dma.map,
     2282            BUS_DMASYNC_PREWRITE);
    21292283        ifp->if_ierrors++;
    21302284        return;
    21312285    }
    iwn_rx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc,  
    21422296    m->m_data = head;
    21432297    m->m_pkthdr.len = m->m_len = len;
    21442298
    2145     rssi = hal->get_rssi(sc, stat);
    2146 
    21472299    /* Grab a reference to the source node. */
    21482300    wh = mtod(m, struct ieee80211_frame *);
    21492301    ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh);
    21502302    nf = (ni != NULL && ni->ni_vap->iv_state == IEEE80211_S_RUN &&
    21512303        (ic->ic_flags & IEEE80211_F_SCAN) == 0) ? sc->noise : -95;
    21522304
     2305    rssi = ops->get_rssi(sc, stat);
     2306
    21532307    if (ieee80211_radiotap_active(ic)) {
    21542308        struct iwn_rx_radiotap_header *tap = &sc->sc_rxtap;
    21552309
    2156         tap->wr_tsft = htole64(stat->tstamp);
    21572310        tap->wr_flags = 0;
    21582311        if (stat->flags & htole16(IWN_STAT_FLAG_SHPREAMBLE))
    21592312            tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
     2313        tap->wr_dbm_antsignal = (int8_t)rssi;
     2314        tap->wr_dbm_antnoise = (int8_t)nf;
     2315        tap->wr_tsft = stat->tstamp;
    21602316        switch (stat->rate) {
    21612317        /* CCK rates. */
    21622318        case  10: tap->wr_rate =   2; break;
    iwn_rx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc,  
    21752331        /* Unknown rate: should not happen. */
    21762332        default:  tap->wr_rate =   0;
    21772333        }
    2178         tap->wr_dbm_antsignal = rssi;
    2179         tap->wr_dbm_antnoise = nf;
    21802334    }
    21812335
    21822336    IWN_UNLOCK(sc);
    21832337
    21842338    /* Send the frame to the 802.11 layer. */
    21852339    if (ni != NULL) {
    2186         (void) ieee80211_input(ni, m, rssi - nf, nf);
     2340        (void)ieee80211_input(ni, m, rssi - nf, nf);
    21872341        /* Node is no longer needed. */
    21882342        ieee80211_free_node(ni);
    21892343    } else
    2190         (void) ieee80211_input_all(ic, m, rssi - nf, nf);
     2344        (void)ieee80211_input_all(ic, m, rssi - nf, nf);
    21912345
    21922346    IWN_LOCK(sc);
    21932347}
    iwn_rx_compressed_ba(struct iwn_softc *sc, struct iwn_rx_desc *desc,  
    22012355    struct iwn_compressed_ba *ba = (struct iwn_compressed_ba *)(desc + 1);
    22022356    struct iwn_tx_ring *txq;
    22032357
     2358    bus_dmamap_sync(sc->rxq.data_dmat, data->map, BUS_DMASYNC_POSTREAD);
     2359
    22042360    txq = &sc->txq[letoh16(ba->qid)];
    22052361    /* XXX TBD */
    22062362}
    22072363#endif
    22082364
    22092365/*
     2366 * Process a CALIBRATION_RESULT notification sent by the initialization
     2367 * firmware on response to a CMD_CALIB_CONFIG command (5000 only).
     2368 */
     2369static void
     2370iwn5000_rx_calib_results(struct iwn_softc *sc, struct iwn_rx_desc *desc,
     2371    struct iwn_rx_data *data)
     2372{
     2373    struct iwn_phy_calib *calib = (struct iwn_phy_calib *)(desc + 1);
     2374    int len, idx = -1;
     2375
     2376    /* Runtime firmware should not send such a notification. */
     2377    if (sc->sc_flags & IWN_FLAG_CALIB_DONE)
     2378        return;
     2379
     2380    len = (le32toh(desc->len) & 0x3fff) - 4;
     2381    bus_dmamap_sync(sc->rxq.data_dmat, data->map, BUS_DMASYNC_POSTREAD);
     2382
     2383    switch (calib->code) {
     2384    case IWN5000_PHY_CALIB_DC:
     2385        if ((sc->sc_flags & IWN_FLAG_INTERNAL_PA) == 0 &&
     2386            (sc->hw_type == IWN_HW_REV_TYPE_5150 ||
     2387             sc->hw_type >= IWN_HW_REV_TYPE_6000))
     2388            idx = 0;
     2389        break;
     2390    case IWN5000_PHY_CALIB_LO:
     2391        idx = 1;
     2392        break;
     2393    case IWN5000_PHY_CALIB_TX_IQ:
     2394        idx = 2;
     2395        break;
     2396    case IWN5000_PHY_CALIB_TX_IQ_PERIODIC:
     2397        if (sc->hw_type < IWN_HW_REV_TYPE_6000 &&
     2398            sc->hw_type != IWN_HW_REV_TYPE_5150)
     2399            idx = 3;
     2400        break;
     2401    case IWN5000_PHY_CALIB_BASE_BAND:
     2402        idx = 4;
     2403        break;
     2404    }
     2405    if (idx == -1)  /* Ignore other results. */
     2406        return;
     2407
     2408    /* Save calibration result. */
     2409    if (sc->calibcmd[idx].buf != NULL)
     2410        free(sc->calibcmd[idx].buf, M_DEVBUF);
     2411    sc->calibcmd[idx].buf = malloc(len, M_DEVBUF, M_NOWAIT);
     2412    if (sc->calibcmd[idx].buf == NULL) {
     2413        DPRINTF(sc, IWN_DEBUG_CALIBRATE,
     2414            "not enough memory for calibration result %d\n",
     2415            calib->code);
     2416        return;
     2417    }
     2418    DPRINTF(sc, IWN_DEBUG_CALIBRATE,
     2419        "saving calibration result code=%d len=%d\n", calib->code, len);
     2420    sc->calibcmd[idx].len = len;
     2421    memcpy(sc->calibcmd[idx].buf, calib, len);
     2422}
     2423
     2424/*
    22102425 * Process an RX_STATISTICS or BEACON_STATISTICS firmware notification.
    22112426 * The latter is sent by the firmware after each received beacon.
    22122427 */
    static void  
    22142429iwn_rx_statistics(struct iwn_softc *sc, struct iwn_rx_desc *desc,
    22152430    struct iwn_rx_data *data)
    22162431{
    2217     const struct iwn_hal *hal = sc->sc_hal;
     2432    struct iwn_ops *ops = &sc->ops;
    22182433    struct ifnet *ifp = sc->sc_ifp;
    22192434    struct ieee80211com *ic = ifp->if_l2com;
    22202435    struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
    iwn_rx_statistics(struct iwn_softc *sc, struct iwn_rx_desc *desc,  
    22222437    struct iwn_stats *stats = (struct iwn_stats *)(desc + 1);
    22232438    int temp;
    22242439
    2225     /* Beacon stats are meaningful only when associated and not scanning. */
     2440    /* Ignore statistics received during a scan. */
    22262441    if (vap->iv_state != IEEE80211_S_RUN ||
    22272442        (ic->ic_flags & IEEE80211_F_SCAN))
    22282443        return;
    22292444
    22302445    bus_dmamap_sync(sc->rxq.data_dmat, data->map, BUS_DMASYNC_POSTREAD);
    2231     DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: cmd %d\n", __func__, desc->type);
    2232     iwn_calib_reset(sc);    /* Reset TX power calibration timeout. */
     2446
     2447    DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: received statistics, cmd %d\n",
     2448        __func__, desc->type);
     2449    sc->calib_cnt = 0;  /* Reset TX power calibration timeout. */
    22332450
    22342451    /* Test if temperature has changed. */
    22352452    if (stats->general.temp != sc->rawtemp) {
    22362453        /* Convert "raw" temperature to degC. */
    22372454        sc->rawtemp = stats->general.temp;
    2238         temp = hal->get_temperature(sc);
     2455        temp = ops->get_temperature(sc);
    22392456        DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: temperature %d\n",
    22402457            __func__, temp);
    22412458
    2242         /* Update TX power if need be (4965AGN only.) */
     2459        /* Update TX power if need be (4965AGN only). */
    22432460        if (sc->hw_type == IWN_HW_REV_TYPE_4965)
    22442461            iwn4965_power_calibration(sc, temp);
    22452462    }
    iwn_tx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc, int ackfailcnt,  
    23552572    /*
    23562573     * Update rate control statistics for the node.
    23572574     */
    2358     if (status & 0x80) {
     2575    if (status & IWN_TX_FAIL) {
    23592576        ifp->if_oerrors++;
    23602577        ieee80211_ratectl_tx_complete(vap, ni,
    23612578            IEEE80211_RATECTL_TX_FAILURE, &ackfailcnt, NULL);
    23622579    } else {
     2580        ifp->if_opackets++;
    23632581        ieee80211_ratectl_tx_complete(vap, ni,
    23642582            IEEE80211_RATECTL_TX_SUCCESS, &ackfailcnt, NULL);
    23652583    }
    iwn_cmd_done(struct iwn_softc *sc, struct iwn_rx_desc *desc)  
    23942612
    23952613    /* If the command was mapped in an mbuf, free it. */
    23962614    if (data->m != NULL) {
     2615        bus_dmamap_sync(ring->data_dmat, data->map,
     2616            BUS_DMASYNC_POSTWRITE);
    23972617        bus_dmamap_unload(ring->data_dmat, data->map);
    23982618        m_freem(data->m);
    23992619        data->m = NULL;
    iwn_cmd_done(struct iwn_softc *sc, struct iwn_rx_desc *desc)  
    24072627static void
    24082628iwn_notif_intr(struct iwn_softc *sc)
    24092629{
     2630    struct iwn_ops *ops = &sc->ops;
    24102631    struct ifnet *ifp = sc->sc_ifp;
    24112632    struct ieee80211com *ic = ifp->if_l2com;
    24122633    struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
    iwn_notif_intr(struct iwn_softc *sc)  
    24532674
    24542675        case IWN_TX_DONE:
    24552676            /* An 802.11 frame has been transmitted. */
    2456             sc->sc_hal->tx_done(sc, desc, data);
     2677            ops->tx_done(sc, desc, data);
    24572678            break;
    24582679
    24592680        case IWN_RX_STATISTICS:
    iwn_notif_intr(struct iwn_softc *sc)  
    24712692                BUS_DMASYNC_POSTREAD);
    24722693            misses = le32toh(miss->consecutive);
    24732694
    2474             /* XXX not sure why we're notified w/ zero */
    2475             if (misses == 0)
    2476                 break;
    24772695            DPRINTF(sc, IWN_DEBUG_STATE,
    24782696                "%s: beacons missed %d/%d\n", __func__,
    24792697                misses, le32toh(miss->total));
    2480 
    24812698            /*
    24822699             * If more than 5 consecutive beacons are missed,
    24832700             * reinitialize the sensitivity state machine.
    24842701             */
    2485             if (vap->iv_state == IEEE80211_S_RUN && misses > 5)
    2486                 (void) iwn_init_sensitivity(sc);
    2487             if (misses >= vap->iv_bmissthreshold) {
    2488                 IWN_UNLOCK(sc);
    2489                 ieee80211_beacon_miss(ic);
    2490                 IWN_LOCK(sc);
     2702            if (vap->iv_state == IEEE80211_S_RUN &&
     2703                (ic->ic_flags & IEEE80211_F_SCAN) == 0) {
     2704                if (misses > 5)
     2705                    (void)iwn_init_sensitivity(sc);
     2706                if (misses >= vap->iv_bmissthreshold) {
     2707                    IWN_UNLOCK(sc);
     2708                    ieee80211_beacon_miss(ic);
     2709                    IWN_LOCK(sc);
     2710                }
    24912711            }
    24922712            break;
    24932713        }
    iwn_notif_intr(struct iwn_softc *sc)  
    25612781            break;
    25622782        }
    25632783        case IWN5000_CALIBRATION_RESULT:
    2564             iwn5000_rx_calib_result(sc, desc, data);
     2784            iwn5000_rx_calib_results(sc, desc, data);
    25652785            break;
    25662786
    25672787        case IWN5000_CALIBRATION_DONE:
    iwn_wakeup_intr(struct iwn_softc *sc)  
    25922812
    25932813    /* Wakeup RX and TX rings. */
    25942814    IWN_WRITE(sc, IWN_FH_RX_WPTR, sc->rxq.cur & ~7);
    2595     for (qid = 0; qid < sc->sc_hal->ntxqs; qid++) {
     2815    for (qid = 0; qid < sc->ntxqs; qid++) {
    25962816        struct iwn_tx_ring *ring = &sc->txq[qid];
    25972817        IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, qid << 8 | ring->cur);
    25982818    }
    iwn_rftoggle_intr(struct iwn_softc *sc)  
    26232843static void
    26242844iwn_fatal_intr(struct iwn_softc *sc)
    26252845{
    2626     const struct iwn_hal *hal = sc->sc_hal;
    26272846    struct iwn_fw_dump dump;
    26282847    int i;
    26292848
    iwn_fatal_intr(struct iwn_softc *sc)  
    26352854    /* Check that the error log address is valid. */
    26362855    if (sc->errptr < IWN_FW_DATA_BASE ||
    26372856        sc->errptr + sizeof (dump) >
    2638         IWN_FW_DATA_BASE + hal->fw_data_maxsz) {
    2639         printf("%s: bad firmware error log address 0x%08x\n",
    2640             __func__, sc->errptr);
     2857        IWN_FW_DATA_BASE + sc->fw_data_maxsz) {
     2858        printf("%s: bad firmware error log address 0x%08x\n", __func__,
     2859            sc->errptr);
    26412860        return;
    26422861    }
    26432862    if (iwn_nic_lock(sc) != 0) {
    2644         printf("%s: could not read firmware error log\n",
    2645             __func__);
     2863        printf("%s: could not read firmware error log\n", __func__);
    26462864        return;
    26472865    }
    26482866    /* Read firmware error log from SRAM. */
    iwn_fatal_intr(struct iwn_softc *sc)  
    26512869    iwn_nic_unlock(sc);
    26522870
    26532871    if (dump.valid == 0) {
    2654         printf("%s: firmware error log is empty\n",
    2655             __func__);
     2872        printf("%s: firmware error log is empty\n", __func__);
    26562873        return;
    26572874    }
    26582875    printf("firmware error log:\n");
    iwn_fatal_intr(struct iwn_softc *sc)  
    26722889
    26732890    /* Dump driver status (TX and RX rings) while we're here. */
    26742891    printf("driver status:\n");
    2675     for (i = 0; i < hal->ntxqs; i++) {
     2892    for (i = 0; i < sc->ntxqs; i++) {
    26762893        struct iwn_tx_ring *ring = &sc->txq[i];
    26772894        printf("  tx ring %2d: qid=%-2d cur=%-3d queued=%-3d\n",
    26782895            i, ring->qid, ring->cur, ring->queued);
    iwn_intr(void *arg)  
    27332950            __func__);
    27342951    }
    27352952    if (r1 & (IWN_INT_SW_ERR | IWN_INT_HW_ERR)) {
     2953        device_printf(sc->sc_dev, "%s: fatal firmware error\n",
     2954            __func__);
     2955        /* Dump firmware error log and stop. */
    27362956        iwn_fatal_intr(sc);
    27372957        ifp->if_flags &= ~IFF_UP;
    27382958        iwn_stop_locked(sc);
    done:  
    27762996
    27772997/*
    27782998 * Update TX scheduler ring when transmitting an 802.11 frame (4965AGN and
    2779  * 5000 adapters use a slightly different format.)
     2999 * 5000 adapters use a slightly different format).
    27803000 */
    27813001static void
    27823002iwn4965_update_sched(struct iwn_softc *sc, int qid, int idx, uint8_t id,
    iwn5000_update_sched(struct iwn_softc *sc, int qid, int idx, uint8_t id,  
    28013021    uint16_t *w = &sc->sched[qid * IWN5000_SCHED_COUNT + idx];
    28023022
    28033023    *w = htole16(id << 12 | (len + 8));
    2804 
    28053024    bus_dmamap_sync(sc->sched_dma.tag, sc->sched_dma.map,
    28063025        BUS_DMASYNC_PREWRITE);
    28073026    if (idx < IWN_SCHED_WINSZ) {
    iwn_plcp_signal(int rate) {  
    28333052    int i;
    28343053
    28353054    for (i = 0; i < IWN_RIDX_MAX + 1; i++) {
    2836         if (rate == iwn_rates[i].rate)
     3055        if ((rate & IEEE80211_RATE_VAL) == iwn_rates[i].rate)
    28373056            return i;
    28383057    }
    28393058
    iwn_plcp_signal(int rate) {  
    28413060}
    28423061
    28433062static int
    2844 iwn_tx_data(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni,
    2845     struct iwn_tx_ring *ring)
     3063iwn_tx_data(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
    28463064{
    2847     const struct iwn_hal *hal = sc->sc_hal;
    28483065    const struct ieee80211_txparam *tp;
    2849     const struct iwn_rate *rinfo;
    28503066    struct ieee80211vap *vap = ni->ni_vap;
    28513067    struct ieee80211com *ic = ni->ni_ic;
    28523068    struct iwn_node *wn = (void *)ni;
     3069    struct iwn_tx_ring *ring;
    28533070    struct iwn_tx_desc *desc;
    28543071    struct iwn_tx_data *data;
    28553072    struct iwn_tx_cmd *cmd;
    28563073    struct iwn_cmd_data *tx;
     3074    const struct iwn_rate *rinfo;
    28573075    struct ieee80211_frame *wh;
    28583076    struct ieee80211_key *k = NULL;
    2859     struct mbuf *mnew;
    2860     bus_dma_segment_t segs[IWN_MAX_SCATTER];
     3077    struct mbuf *m1;
    28613078    uint32_t flags;
     3079    uint16_t qos;
    28623080    u_int hdrlen;
    2863     int totlen, error, pad, nsegs = 0, i, rate;
    2864     uint8_t ridx, type, txant;
     3081    bus_dma_segment_t *seg, segs[IWN_MAX_SCATTER];
     3082    uint8_t tid, ridx, txant, type;
     3083    int ac, i, totlen, error, pad, nsegs = 0, rate;
    28653084
    28663085    IWN_LOCK_ASSERT(sc);
    28673086
    iwn_tx_data(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni,  
    28693088    hdrlen = ieee80211_anyhdrsize(wh);
    28703089    type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
    28713090
     3091    /* Select EDCA Access Category and TX ring for this frame. */
     3092    if (IEEE80211_QOS_HAS_SEQ(wh)) {
     3093        qos = ((const struct ieee80211_qosframe *)wh)->i_qos[0];
     3094        tid = qos & IEEE80211_QOS_TID;
     3095    } else {
     3096        qos = 0;
     3097        tid = 0;
     3098    }
     3099    ac = M_WME_GETAC(m);
     3100
     3101    ring = &sc->txq[ac];
    28723102    desc = &ring->desc[ring->cur];
    28733103    data = &ring->data[ring->cur];
    28743104
    iwn_tx_data(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni,  
    28903120
    28913121    /* Encrypt the frame if need be. */
    28923122    if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
     3123        /* Retrieve key for TX. */
    28933124        k = ieee80211_crypto_encap(ni, m);
    28943125        if (k == NULL) {
    28953126            m_freem(m);
    28963127            return ENOBUFS;
    28973128        }
    2898         /* Packet header may have moved, reset our local pointer. */
     3129        /* 802.11 header may have moved. */
    28993130        wh = mtod(m, struct ieee80211_frame *);
    29003131    }
    29013132    totlen = m->m_pkthdr.len;
    iwn_tx_data(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni,  
    29233154    tx->scratch = 0;    /* clear "scratch" area */
    29243155
    29253156    flags = 0;
    2926     if (!IEEE80211_IS_MULTICAST(wh->i_addr1))
    2927         flags |= IWN_TX_NEED_ACK;
     3157    if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
     3158        /* Unicast frame, check if an ACK is expected. */
     3159        if (!qos || (qos & IEEE80211_QOS_ACKPOLICY) !=
     3160            IEEE80211_QOS_ACKPOLICY_NOACK)
     3161            flags |= IWN_TX_NEED_ACK;
     3162    }
    29283163    if ((wh->i_fc[0] &
    29293164        (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==
    29303165        (IEEE80211_FC0_TYPE_CTL | IEEE80211_FC0_SUBTYPE_BAR))
    iwn_tx_data(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni,  
    29573192
    29583193    if (IEEE80211_IS_MULTICAST(wh->i_addr1) ||
    29593194        type != IEEE80211_FC0_TYPE_DATA)
    2960         tx->id = hal->broadcast_id;
     3195        tx->id = sc->broadcast_id;
    29613196    else
    29623197        tx->id = wn->id;
    29633198
    iwn_tx_data(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni,  
    29673202        /* Tell HW to set timestamp in probe responses. */
    29683203        if (subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP)
    29693204            flags |= IWN_TX_INSERT_TSTAMP;
    2970 
    29713205        if (subtype == IEEE80211_FC0_SUBTYPE_ASSOC_REQ ||
    29723206            subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ)
    29733207            tx->timeout = htole16(3);
    iwn_tx_data(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni,  
    29843218        pad = 0;
    29853219
    29863220    tx->len = htole16(totlen);
    2987     tx->tid = 0;
     3221    tx->tid = tid;
    29883222    tx->rts_ntries = 60;
    29893223    tx->data_ntries = 15;
    29903224    tx->lifetime = htole32(IWN_LIFETIME_INFINITE);
    29913225    tx->plcp = rinfo->plcp;
    29923226    tx->rflags = rinfo->flags;
    2993     if (tx->id == hal->broadcast_id) {
     3227    if (tx->id == sc->broadcast_id) {
    29943228        /* Group or management frame. */
    29953229        tx->linkq = 0;
    29963230        /* XXX Alternate between antenna A and B? */
    29973231        txant = IWN_LSB(sc->txchainmask);
    29983232        tx->rflags |= IWN_RFLAG_ANT(txant);
    29993233    } else {
    3000         tx->linkq = IWN_RIDX_OFDM54 - ridx;
     3234        tx->linkq = ni->ni_rates.rs_nrates - ridx - 1;
    30013235        flags |= IWN_TX_LINKQ;  /* enable MRR */
    30023236    }
    3003 
    30043237    /* Set physical address of "scratch area". */
    30053238    tx->loaddr = htole32(IWN_LOADDR(data->scratch_paddr));
    30063239    tx->hiaddr = IWN_HIADDR(data->scratch_paddr);
    iwn_tx_data(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni,  
    30133246    tx->security = 0;
    30143247    tx->flags = htole32(flags);
    30153248
    3016     if (m->m_len > 0) {
    3017         error = bus_dmamap_load_mbuf_sg(ring->data_dmat, data->map,
    3018             m, segs, &nsegs, BUS_DMA_NOWAIT);
    3019         if (error == EFBIG) {
    3020             /* too many fragments, linearize */
    3021             mnew = m_collapse(m, M_DONTWAIT, IWN_MAX_SCATTER);
    3022             if (mnew == NULL) {
    3023                 device_printf(sc->sc_dev,
    3024                     "%s: could not defrag mbuf\n", __func__);
    3025                 m_freem(m);
    3026                 return ENOBUFS;
    3027             }
    3028             m = mnew;
    3029             error = bus_dmamap_load_mbuf_sg(ring->data_dmat,
    3030                 data->map, m, segs, &nsegs, BUS_DMA_NOWAIT);
     3249    error = bus_dmamap_load_mbuf_sg(ring->data_dmat, data->map, m, segs,
     3250        &nsegs, BUS_DMA_NOWAIT);
     3251    if (error != 0) {
     3252        if (error != EFBIG) {
     3253            device_printf(sc->sc_dev,
     3254                "%s: can't map mbuf (error %d)\n", __func__, error);
     3255            m_freem(m);
     3256            return error;
     3257        }
     3258        /* Too many DMA segments, linearize mbuf. */
     3259        m1 = m_collapse(m, M_DONTWAIT, IWN_MAX_SCATTER);
     3260        if (m1 == NULL) {
     3261            device_printf(sc->sc_dev,
     3262                "%s: could not defrag mbuf\n", __func__);
     3263            m_freem(m);
     3264            return ENOBUFS;
    30313265        }
     3266        m = m1;
     3267
     3268        error = bus_dmamap_load_mbuf_sg(ring->data_dmat, data->map, m,
     3269            segs, &nsegs, BUS_DMA_NOWAIT);
    30323270        if (error != 0) {
    30333271            device_printf(sc->sc_dev,
    3034                 "%s: bus_dmamap_load_mbuf_sg failed, error %d\n",
    3035                 __func__, error);
     3272                "%s: can't map mbuf (error %d)\n", __func__, error);
    30363273            m_freem(m);
    30373274            return error;
    30383275        }
    iwn_tx_data(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni,  
    30453282        __func__, ring->qid, ring->cur, m->m_pkthdr.len, nsegs);
    30463283
    30473284    /* Fill TX descriptor. */
    3048     desc->nsegs = 1 + nsegs;
     3285    desc->nsegs = 1;
     3286    if (m->m_len != 0)
     3287        desc->nsegs += nsegs;
    30493288    /* First DMA segment is used by the TX command. */
    30503289    desc->segs[0].addr = htole32(IWN_LOADDR(data->cmd_paddr));
    30513290    desc->segs[0].len  = htole16(IWN_HIADDR(data->cmd_paddr) |
    30523291        (4 + sizeof (*tx) + hdrlen + pad) << 4);
    30533292    /* Other DMA segments are for data payload. */
     3293    seg = &segs[0];
    30543294    for (i = 1; i <= nsegs; i++) {
    3055         desc->segs[i].addr = htole32(IWN_LOADDR(segs[i - 1].ds_addr));
    3056         desc->segs[i].len  = htole16(IWN_HIADDR(segs[i - 1].ds_addr) |
    3057             segs[i - 1].ds_len << 4);
     3295        desc->segs[i].addr = htole32(IWN_LOADDR(seg->ds_addr));
     3296        desc->segs[i].len  = htole16(IWN_HIADDR(seg->ds_addr) |
     3297            seg->ds_len << 4);
     3298        seg++;
    30583299    }
    30593300
    30603301    bus_dmamap_sync(ring->data_dmat, data->map, BUS_DMASYNC_PREWRITE);
    iwn_tx_data(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni,  
    30653306
    30663307#ifdef notyet
    30673308    /* Update TX scheduler. */
    3068     hal->update_sched(sc, ring->qid, ring->cur, tx->id, totlen);
     3309    ops->update_sched(sc, ring->qid, ring->cur, tx->id, totlen);
    30693310#endif
    30703311
    30713312    /* Kick TX ring. */
    iwn_tx_data(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni,  
    30813322
    30823323static int
    30833324iwn_tx_data_raw(struct iwn_softc *sc, struct mbuf *m,
    3084     struct ieee80211_node *ni, struct iwn_tx_ring *ring,
    3085     const struct ieee80211_bpf_params *params)
     3325    struct ieee80211_node *ni, const struct ieee80211_bpf_params *params)
    30863326{
    3087     const struct iwn_hal *hal = sc->sc_hal;
    30883327    const struct iwn_rate *rinfo;
    30893328    struct ifnet *ifp = sc->sc_ifp;
    30903329    struct ieee80211vap *vap = ni->ni_vap;
    iwn_tx_data_raw(struct iwn_softc *sc, struct mbuf *m,  
    30923331    struct iwn_tx_cmd *cmd;
    30933332    struct iwn_cmd_data *tx;
    30943333    struct ieee80211_frame *wh;
     3334    struct iwn_tx_ring *ring;
    30953335    struct iwn_tx_desc *desc;
    30963336    struct iwn_tx_data *data;
    3097     struct mbuf *mnew;
    3098     bus_addr_t paddr;
    3099     bus_dma_segment_t segs[IWN_MAX_SCATTER];
     3337    struct mbuf *m1;
     3338    bus_dma_segment_t *seg, segs[IWN_MAX_SCATTER];
    31003339    uint32_t flags;
    31013340    u_int hdrlen;
    3102     int totlen, error, pad, nsegs = 0, i, rate;
     3341    int ac, totlen, error, pad, nsegs = 0, i, rate;
    31033342    uint8_t ridx, type, txant;
    31043343
    31053344    IWN_LOCK_ASSERT(sc);
    iwn_tx_data_raw(struct iwn_softc *sc, struct mbuf *m,  
    31083347    hdrlen = ieee80211_anyhdrsize(wh);
    31093348    type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
    31103349
     3350    ac = params->ibp_pri & 3;
     3351
     3352    ring = &sc->txq[ac];
    31113353    desc = &ring->desc[ring->cur];
    31123354    data = &ring->data[ring->cur];
    31133355
    iwn_tx_data_raw(struct iwn_softc *sc, struct mbuf *m,  
    31563398    if (type == IEEE80211_FC0_TYPE_MGT) {
    31573399        uint8_t subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
    31583400
     3401        /* Tell HW to set timestamp in probe responses. */
    31593402        if (subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP)
    31603403            flags |= IWN_TX_INSERT_TSTAMP;
    31613404
    iwn_tx_data_raw(struct iwn_softc *sc, struct mbuf *m,  
    31853428
    31863429    tx->len = htole16(totlen);
    31873430    tx->tid = 0;
    3188     tx->id = hal->broadcast_id;
     3431    tx->id = sc->broadcast_id;
    31893432    tx->rts_ntries = params->ibp_try1;
    31903433    tx->data_ntries = params->ibp_try0;
    31913434    tx->lifetime = htole32(IWN_LIFETIME_INFINITE);
    iwn_tx_data_raw(struct iwn_softc *sc, struct mbuf *m,  
    31963439    txant = IWN_LSB(sc->txchainmask);
    31973440    tx->rflags |= IWN_RFLAG_ANT(txant);
    31983441    /* Set physical address of "scratch area". */
    3199     paddr = ring->cmd_dma.paddr + ring->cur * sizeof (struct iwn_tx_cmd);
    3200     tx->loaddr = htole32(IWN_LOADDR(paddr));
    3201     tx->hiaddr = IWN_HIADDR(paddr);
     3442    tx->loaddr = htole32(IWN_LOADDR(data->scratch_paddr));
     3443    tx->hiaddr = IWN_HIADDR(data->scratch_paddr);
    32023444
    32033445    /* Copy 802.11 header in TX command. */
    32043446    memcpy((uint8_t *)(tx + 1), wh, hdrlen);
    iwn_tx_data_raw(struct iwn_softc *sc, struct mbuf *m,  
    32083450    tx->security = 0;
    32093451    tx->flags = htole32(flags);
    32103452
    3211     if (m->m_len > 0) {
    3212         error = bus_dmamap_load_mbuf_sg(ring->data_dmat, data->map,
    3213             m, segs, &nsegs, BUS_DMA_NOWAIT);
    3214         if (error == EFBIG) {
    3215             /* Too many fragments, linearize. */
    3216             mnew = m_collapse(m, M_DONTWAIT, IWN_MAX_SCATTER);
    3217             if (mnew == NULL) {
    3218                 device_printf(sc->sc_dev,
    3219                     "%s: could not defrag mbuf\n", __func__);
    3220                 m_freem(m);
    3221                 return ENOBUFS;
    3222             }
    3223             m = mnew;
    3224             error = bus_dmamap_load_mbuf_sg(ring->data_dmat,
    3225                 data->map, m, segs, &nsegs, BUS_DMA_NOWAIT);
     3453    error = bus_dmamap_load_mbuf_sg(ring->data_dmat, data->map, m, segs,
     3454        &nsegs, BUS_DMA_NOWAIT);
     3455    if (error != 0) {
     3456        if (error != EFBIG) {
     3457            device_printf(sc->sc_dev,
     3458                "%s: can't map mbuf (error %d)\n", __func__, error);
     3459            m_freem(m);
     3460            return error;
     3461        }
     3462        /* Too many DMA segments, linearize mbuf. */
     3463        m1 = m_collapse(m, M_DONTWAIT, IWN_MAX_SCATTER);
     3464        if (m1 == NULL) {
     3465            device_printf(sc->sc_dev,
     3466                "%s: could not defrag mbuf\n", __func__);
     3467            m_freem(m);
     3468            return ENOBUFS;
    32263469        }
     3470        m = m1;
     3471
     3472        error = bus_dmamap_load_mbuf_sg(ring->data_dmat, data->map, m,
     3473            segs, &nsegs, BUS_DMA_NOWAIT);
    32273474        if (error != 0) {
    32283475            device_printf(sc->sc_dev,
    3229                 "%s: bus_dmamap_load_mbuf_sg failed, error %d\n",
    3230                 __func__, error);
     3476                "%s: can't map mbuf (error %d)\n", __func__, error);
    32313477            m_freem(m);
    32323478            return error;
    32333479        }
    iwn_tx_data_raw(struct iwn_softc *sc, struct mbuf *m,  
    32403486        __func__, ring->qid, ring->cur, m->m_pkthdr.len, nsegs);
    32413487
    32423488    /* Fill TX descriptor. */
    3243     desc->nsegs = 1 + nsegs;
     3489    desc->nsegs = 1;
     3490    if (m->m_len != 0)
     3491        desc->nsegs += nsegs;
    32443492    /* First DMA segment is used by the TX command. */
    32453493    desc->segs[0].addr = htole32(IWN_LOADDR(data->cmd_paddr));
    32463494    desc->segs[0].len  = htole16(IWN_HIADDR(data->cmd_paddr) |
    32473495        (4 + sizeof (*tx) + hdrlen + pad) << 4);
    32483496    /* Other DMA segments are for data payload. */
     3497    seg = &segs[0];
    32493498    for (i = 1; i <= nsegs; i++) {
    3250         desc->segs[i].addr = htole32(IWN_LOADDR(segs[i - 1].ds_addr));
    3251         desc->segs[i].len  = htole16(IWN_HIADDR(segs[i - 1].ds_addr) |
    3252             segs[i - 1].ds_len << 4);
     3499        desc->segs[i].addr = htole32(IWN_LOADDR(seg->ds_addr));
     3500        desc->segs[i].len  = htole16(IWN_HIADDR(seg->ds_addr) |
     3501            seg->ds_len << 4);
     3502        seg++;
    32533503    }
    32543504
    32553505    bus_dmamap_sync(ring->data_dmat, data->map, BUS_DMASYNC_PREWRITE);
    iwn_tx_data_raw(struct iwn_softc *sc, struct mbuf *m,  
    32603510
    32613511#ifdef notyet
    32623512    /* Update TX scheduler. */
    3263     hal->update_sched(sc, ring->qid, ring->cur, tx->id, totlen);
     3513    ops->update_sched(sc, ring->qid, ring->cur, tx->id, totlen);
    32643514#endif
    32653515
    32663516    /* Kick TX ring. */
    iwn_tx_data_raw(struct iwn_softc *sc, struct mbuf *m,  
    32763526
    32773527static int
    32783528iwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
    3279     const struct ieee80211_bpf_params *params)
     3529    const struct ieee80211_bpf_params *params)
    32803530{
    32813531    struct ieee80211com *ic = ni->ni_ic;
    32823532    struct ifnet *ifp = ic->ic_ifp;
    32833533    struct iwn_softc *sc = ifp->if_softc;
    3284     struct iwn_tx_ring *txq;
    32853534    int error = 0;
    32863535
    32873536    if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
    iwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,  
    32913540    }
    32923541
    32933542    IWN_LOCK(sc);
    3294     if (params == NULL)
    3295         txq = &sc->txq[M_WME_GETAC(m)];
    3296     else
    3297         txq = &sc->txq[params->ibp_pri & 3];
    3298 
    32993543    if (params == NULL) {
    33003544        /*
    33013545         * Legacy path; interpret frame contents to decide
    33023546         * precisely how to send the frame.
    33033547         */
    3304         error = iwn_tx_data(sc, m, ni, txq);
     3548        error = iwn_tx_data(sc, m, ni);
    33053549    } else {
    33063550        /*
    33073551         * Caller supplied explicit parameters to use in
    33083552         * sending the frame.
    33093553         */
    3310         error = iwn_tx_data_raw(sc, m, ni, txq, params);
     3554        error = iwn_tx_data_raw(sc, m, ni, params);
    33113555    }
    33123556    if (error != 0) {
    33133557        /* NB: m is reclaimed on tx failure */
    33143558        ieee80211_free_node(ni);
    33153559        ifp->if_oerrors++;
    33163560    }
     3561    sc->sc_tx_timer = 5;
     3562
    33173563    IWN_UNLOCK(sc);
    33183564    return error;
    33193565}
    iwn_start_locked(struct ifnet *ifp)  
    33333579{
    33343580    struct iwn_softc *sc = ifp->if_softc;
    33353581    struct ieee80211_node *ni;
    3336     struct iwn_tx_ring *txq;
    33373582    struct mbuf *m;
    3338     int pri;
    33393583
    33403584    IWN_LOCK_ASSERT(sc);
    33413585
     3586    if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 ||
     3587        (ifp->if_drv_flags & IFF_DRV_OACTIVE))
     3588        return;
     3589
    33423590    for (;;) {
    33433591        if (sc->qfullmsk != 0) {
    33443592            ifp->if_drv_flags |= IFF_DRV_OACTIVE;
    iwn_start_locked(struct ifnet *ifp)  
    33483596        if (m == NULL)
    33493597            break;
    33503598        ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
    3351         pri = M_WME_GETAC(m);
    3352         txq = &sc->txq[pri];
    3353         if (iwn_tx_data(sc, m, ni, txq) != 0) {
    3354             ifp->if_oerrors++;
     3599        if (iwn_tx_data(sc, m, ni) != 0) {
    33553600            ieee80211_free_node(ni);
    3356             break;
     3601            ifp->if_oerrors++;
     3602            continue;
    33573603        }
    33583604        sc->sc_tx_timer = 5;
    33593605    }
    33603606}
    33613607
    33623608static void
    3363 iwn_watchdog(struct iwn_softc *sc)
     3609iwn_watchdog(void *arg)
    33643610{
    3365     if (sc->sc_tx_timer > 0 && --sc->sc_tx_timer == 0) {
    3366         struct ifnet *ifp = sc->sc_ifp;
    3367         struct ieee80211com *ic = ifp->if_l2com;
     3611    struct iwn_softc *sc = arg;
     3612    struct ifnet *ifp = sc->sc_ifp;
     3613    struct ieee80211com *ic = ifp->if_l2com;
     3614
     3615    IWN_LOCK_ASSERT(sc);
     3616
     3617    KASSERT(ifp->if_drv_flags & IFF_DRV_RUNNING, ("not running"));
    33683618
    3369         if_printf(ifp, "device timeout\n");
    3370         ieee80211_runtask(ic, &sc->sc_reinit_task);
     3619    if (sc->sc_tx_timer > 0) {
     3620        if (--sc->sc_tx_timer == 0) {
     3621            if_printf(ifp, "device timeout\n");
     3622            ieee80211_runtask(ic, &sc->sc_reinit_task);
     3623            return;
     3624        }
    33713625    }
     3626    callout_reset(&sc->watchdog_to, hz, iwn_watchdog, sc);
    33723627}
    33733628
    33743629static int
    iwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)  
    33813636    int error = 0, startall = 0, stop = 0;
    33823637
    33833638    switch (cmd) {
     3639    case SIOCGIFADDR:
     3640        error = ether_ioctl(ifp, cmd, data);
     3641        break;
    33843642    case SIOCSIFFLAGS:
    33853643        IWN_LOCK(sc);
    33863644        if (ifp->if_flags & IFF_UP) {
    iwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)  
    34043662    case SIOCGIFMEDIA:
    34053663        error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
    34063664        break;
    3407     case SIOCGIFADDR:
    3408         error = ether_ioctl(ifp, cmd, data);
    3409         break;
    34103665    default:
    34113666        error = EINVAL;
    34123667        break;
    iwn_cmd(struct iwn_softc *sc, int code, const void *buf, int size, int async)  
    34803735
    34813736#ifdef notyet
    34823737    /* Update TX scheduler. */
    3483     sc->sc_hal->update_sched(sc, ring->qid, ring->cur, 0, 0);
     3738    ops->update_sched(sc, ring->qid, ring->cur, 0, 0);
    34843739#endif
    34853740
    34863741    /* Kick command ring. */
    iwn5000_add_node(struct iwn_softc *sc, struct iwn_node_info *node, int async)  
    35163771    return iwn_cmd(sc, IWN_CMD_ADD_NODE, node, sizeof (*node), async);
    35173772}
    35183773
    3519 #if 0   /* HT */
    3520 static const uint8_t iwn_ridx_to_plcp[] = {
    3521     10, 20, 55, 110, /* CCK */
    3522     0xd, 0xf, 0x5, 0x7, 0x9, 0xb, 0x1, 0x3, 0x3 /* OFDM R1-R4 */
    3523 };
    3524 static const uint8_t iwn_siso_mcs_to_plcp[] = {
    3525     0, 0, 0, 0,             /* CCK */
    3526     0, 0, 1, 2, 3, 4, 5, 6, 7   /* HT */
    3527 };
    3528 static const uint8_t iwn_mimo_mcs_to_plcp[] = {
    3529     0, 0, 0, 0,             /* CCK */
    3530     8, 8, 9, 10, 11, 12, 13, 14, 15 /* HT */
    3531 };
    3532 #endif
    3533 static const uint8_t iwn_prev_ridx[] = {
    3534     /* NB: allow fallback from CCK11 to OFDM9 and from OFDM6 to CCK5 */
    3535     0, 0, 1, 5,         /* CCK */
    3536     2, 4, 3, 6, 7, 8, 9, 10, 10 /* OFDM */
    3537 };
    3538 
    3539 /*
    3540  * Configure hardware link parameters for the specified
    3541  * node operating on the specified channel.
    3542  */
    35433774static int
    3544 iwn_set_link_quality(struct iwn_softc *sc, uint8_t id, int async)
     3775iwn_set_link_quality(struct iwn_softc *sc, struct ieee80211_node *ni)
    35453776{
    3546     struct ifnet *ifp = sc->sc_ifp;
    3547     struct ieee80211com *ic = ifp->if_l2com;
     3777    struct iwn_node *wn = (void *)ni;
     3778    struct ieee80211_rateset *rs = &ni->ni_rates;
    35483779    struct iwn_cmd_link_quality linkq;
    35493780    const struct iwn_rate *rinfo;
    3550     int i;
    3551     uint8_t txant, ridx;
     3781    uint8_t txant;
     3782    int i, txrate;
    35523783
    35533784    /* Use the first valid TX antenna. */
    35543785    txant = IWN_LSB(sc->txchainmask);
    35553786
    35563787    memset(&linkq, 0, sizeof linkq);
    3557     linkq.id = id;
     3788    linkq.id = wn->id;
    35583789    linkq.antmsk_1stream = txant;
    35593790    linkq.antmsk_2stream = IWN_ANT_AB;
    35603791    linkq.ampdu_max = 31;
    35613792    linkq.ampdu_threshold = 3;
    35623793    linkq.ampdu_limit = htole16(4000);  /* 4ms */
    35633794
    3564 #if 0   /* HT */
    3565     if (IEEE80211_IS_CHAN_HT(c))
    3566         linkq.mimo = 1;
    3567 #endif
    3568 
    3569     if (id == IWN_ID_BSS)
    3570         ridx = IWN_RIDX_OFDM54;
    3571     else if (IEEE80211_IS_CHAN_A(ic->ic_curchan))
    3572         ridx = IWN_RIDX_OFDM6;
    3573     else
    3574         ridx = IWN_RIDX_CCK1;
    3575 
     3795    /* Start at highest available bit-rate. */
     3796    txrate = rs->rs_nrates - 1;
    35763797    for (i = 0; i < IWN_MAX_TX_RETRIES; i++) {
    3577         rinfo = &iwn_rates[ridx];
    3578 #if 0   /* HT */
    3579         if (IEEE80211_IS_CHAN_HT40(c)) {
    3580             linkq.retry[i].plcp = iwn_mimo_mcs_to_plcp[ridx]
    3581                      | IWN_RIDX_MCS;
    3582             linkq.retry[i].rflags = IWN_RFLAG_HT
    3583                      | IWN_RFLAG_HT40;
    3584             /* XXX shortGI */
    3585         } else if (IEEE80211_IS_CHAN_HT(c)) {
    3586             linkq.retry[i].plcp = iwn_siso_mcs_to_plcp[ridx]
    3587                      | IWN_RIDX_MCS;
    3588             linkq.retry[i].rflags = IWN_RFLAG_HT;
    3589             /* XXX shortGI */
    3590         } else
    3591 #endif
    3592         {
    3593             linkq.retry[i].plcp = rinfo->plcp;
    3594             linkq.retry[i].rflags = rinfo->flags;
    3595         }
     3798        rinfo = &iwn_rates[wn->ridx[txrate]];
     3799        linkq.retry[i].plcp = rinfo->plcp;
     3800        linkq.retry[i].rflags = rinfo->flags;
    35963801        linkq.retry[i].rflags |= IWN_RFLAG_ANT(txant);
    3597         ridx = iwn_prev_ridx[ridx];
    3598     }
    3599 #ifdef IWN_DEBUG
    3600     if (sc->sc_debug & IWN_DEBUG_STATE) {
    3601         printf("%s: set link quality for node %d, mimo %d ssmask %d\n",
    3602             __func__, id, linkq.mimo, linkq.antmsk_1stream);
    3603         printf("%s:", __func__);
    3604         for (i = 0; i < IWN_MAX_TX_RETRIES; i++)
    3605             printf(" %d:%x", linkq.retry[i].plcp,
    3606                 linkq.retry[i].rflags);
    3607         printf("\n");
     3802        /* Next retry at immediate lower bit-rate. */
     3803        if (txrate > 0)
     3804            txrate--;
    36083805    }
    3609 #endif
    3610     return iwn_cmd(sc, IWN_CMD_LINK_QUALITY, &linkq, sizeof linkq, async);
     3806    return iwn_cmd(sc, IWN_CMD_LINK_QUALITY, &linkq, sizeof linkq, 1);
    36113807}
    36123808
    36133809/*
    iwn_set_link_quality(struct iwn_softc *sc, uint8_t id, int async)  
    36163812static int
    36173813iwn_add_broadcast_node(struct iwn_softc *sc, int async)
    36183814{
    3619     const struct iwn_hal *hal = sc->sc_hal;
     3815    struct iwn_ops *ops = &sc->ops;
    36203816    struct ifnet *ifp = sc->sc_ifp;
     3817    struct ieee80211com *ic = ifp->if_l2com;
    36213818    struct iwn_node_info node;
    3622     int error;
     3819    struct iwn_cmd_link_quality linkq;
     3820    const struct iwn_rate *rinfo;
     3821    uint8_t txant;
     3822    int i, error;
    36233823
    36243824    memset(&node, 0, sizeof node);
    36253825    IEEE80211_ADDR_COPY(node.macaddr, ifp->if_broadcastaddr);
    3626     node.id = hal->broadcast_id;
     3826    node.id = sc->broadcast_id;
    36273827    DPRINTF(sc, IWN_DEBUG_RESET, "%s: adding broadcast node\n", __func__);
    3628     error = hal->add_node(sc, &node, async);
    3629     if (error != 0)
     3828    if ((error = ops->add_node(sc, &node, async)) != 0)
    36303829        return error;
    36313830
    3632     error = iwn_set_link_quality(sc, hal->broadcast_id, async);
    3633     return error;
     3831    /* Use the first valid TX antenna. */
     3832    txant = IWN_LSB(sc->txchainmask);
     3833
     3834    memset(&linkq, 0, sizeof linkq);
     3835    linkq.id = sc->broadcast_id;
     3836    linkq.antmsk_1stream = txant;
     3837    linkq.antmsk_2stream = IWN_ANT_AB;
     3838    linkq.ampdu_max = 64;
     3839    linkq.ampdu_threshold = 3;
     3840    linkq.ampdu_limit = htole16(4000);  /* 4ms */
     3841
     3842    /* Use lowest mandatory bit-rate. */
     3843    if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan))
     3844        rinfo = &iwn_rates[IWN_RIDX_OFDM6];
     3845    else
     3846        rinfo = &iwn_rates[IWN_RIDX_CCK1];
     3847    linkq.retry[0].plcp = rinfo->plcp;
     3848    linkq.retry[0].rflags = rinfo->flags;
     3849    linkq.retry[0].rflags |= IWN_RFLAG_ANT(txant);
     3850    /* Use same bit-rate for all TX retries. */
     3851    for (i = 1; i < IWN_MAX_TX_RETRIES; i++) {
     3852        linkq.retry[i].plcp = linkq.retry[0].plcp;
     3853        linkq.retry[i].rflags = linkq.retry[0].rflags;
     3854    }
     3855    return iwn_cmd(sc, IWN_CMD_LINK_QUALITY, &linkq, sizeof linkq, async);
    36343856}
    36353857
    36363858static int
    3637 iwn_wme_update(struct ieee80211com *ic)
     3859iwn_updateedca(struct ieee80211com *ic)
    36383860{
    36393861#define IWN_EXP2(x) ((1 << (x)) - 1)    /* CWmin = 2^ECWmin - 1 */
    3640 #define IWN_TXOP_TO_US(v)       (v<<5)
    36413862    struct iwn_softc *sc = ic->ic_ifp->if_softc;
    36423863    struct iwn_edca_params cmd;
    3643     int i;
     3864    int aci;
    36443865
    36453866    memset(&cmd, 0, sizeof cmd);
    36463867    cmd.flags = htole32(IWN_EDCA_UPDATE);
    3647     for (i = 0; i < WME_NUM_AC; i++) {
    3648         const struct wmeParams *wmep =
    3649             &ic->ic_wme.wme_chanParams.cap_wmeParams[i];
    3650         cmd.ac[i].aifsn = wmep->wmep_aifsn;
    3651         cmd.ac[i].cwmin = htole16(IWN_EXP2(wmep->wmep_logcwmin));
    3652         cmd.ac[i].cwmax = htole16(IWN_EXP2(wmep->wmep_logcwmax));
    3653         cmd.ac[i].txoplimit =
    3654             htole16(IWN_TXOP_TO_US(wmep->wmep_txopLimit));
     3868    for (aci = 0; aci < WME_NUM_AC; aci++) {
     3869        const struct wmeParams *ac =
     3870            &ic->ic_wme.wme_chanParams.cap_wmeParams[aci];
     3871        cmd.ac[aci].aifsn = ac->wmep_aifsn;
     3872        cmd.ac[aci].cwmin = htole16(IWN_EXP2(ac->wmep_logcwmin));
     3873        cmd.ac[aci].cwmax = htole16(IWN_EXP2(ac->wmep_logcwmax));
     3874        cmd.ac[aci].txoplimit =
     3875            htole16(IEEE80211_TXOP_TO_US(ac->wmep_txopLimit));
    36553876    }
    36563877    IEEE80211_UNLOCK(ic);
    36573878    IWN_LOCK(sc);
    3658     (void) iwn_cmd(sc, IWN_CMD_EDCA_PARAMS, &cmd, sizeof cmd, 1 /*async*/);
     3879    (void)iwn_cmd(sc, IWN_CMD_EDCA_PARAMS, &cmd, sizeof cmd, 1);
    36593880    IWN_UNLOCK(sc);
    36603881    IEEE80211_LOCK(ic);
    36613882    return 0;
    3662 #undef IWN_TXOP_TO_US
    36633883#undef IWN_EXP2
    36643884}
    36653885
    iwn_set_critical_temp(struct iwn_softc *sc)  
    37043924        temp = 110;
    37053925    memset(&crit, 0, sizeof crit);
    37063926    crit.tempR = htole32(temp);
    3707     DPRINTF(sc, IWN_DEBUG_RESET, "setting critical temp to %d\n",
    3708         temp);
     3927    DPRINTF(sc, IWN_DEBUG_RESET, "setting critical temp to %d\n", temp);
    37093928    return iwn_cmd(sc, IWN_CMD_SET_CRITICAL_TEMP, &crit, sizeof crit, 0);
    37103929}
    37113930
    iwn_set_timing(struct iwn_softc *sc, struct ieee80211_node *ni)  
    37213940    cmd.lintval = htole16(10);
    37223941
    37233942    /* Compute remaining time until next beacon. */
    3724     val = (uint64_t)ni->ni_intval * 1024;   /* msecs -> usecs */
     3943    val = (uint64_t)ni->ni_intval * IEEE80211_DUR_TU;
    37253944    mod = le64toh(cmd.tstamp) % val;
    37263945    cmd.binitval = htole32((uint32_t)(val - mod));
    37273946
    iwn4965_power_calibration(struct iwn_softc *sc, int temp)  
    37373956    struct ifnet *ifp = sc->sc_ifp;
    37383957    struct ieee80211com *ic = ifp->if_l2com;
    37393958
    3740     /* Adjust TX power if need be (delta >= 3 degC.) */
     3959    /* Adjust TX power if need be (delta >= 3 degC). */
    37413960    DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: temperature %d->%d\n",
    37423961        __func__, sc->temp, temp);
    37433962    if (abs(temp - sc->temp) >= 3) {
    iwn4965_set_txpower(struct iwn_softc *sc, struct ieee80211_channel *ch,  
    37643983    ((y1) + fdivround(((int)(x) - (x1)) * ((y2) - (y1)), (x2) - (x1), n))
    37653984
    37663985    static const int tdiv[IWN_NATTEN_GROUPS] = { 9, 8, 8, 8, 6 };
    3767     struct ifnet *ifp = sc->sc_ifp;
    3768     struct ieee80211com *ic = ifp->if_l2com;
    37693986    struct iwn_ucode_info *uc = &sc->ucode_info;
    37703987    struct iwn4965_cmd_txpower cmd;
    37713988    struct iwn4965_eeprom_chan_samples *chans;
     3989    const uint8_t *rf_gain, *dsp_gain;
    37723990    int32_t vdiff, tdiff;
    37733991    int i, c, grp, maxpwr;
    3774     const uint8_t *rf_gain, *dsp_gain;
    37753992    uint8_t chan;
    37763993
    3777     /* Retrieve channel number. */
    3778     chan = ieee80211_chan2ieee(ic, ch);
     3994    /* Retrieve current channel from last RXON. */
     3995    chan = sc->rxon.chan;
    37793996    DPRINTF(sc, IWN_DEBUG_RESET, "setting TX power for channel %d\n",
    37803997        chan);
    37813998
    iwn4965_get_rssi(struct iwn_softc *sc, struct iwn_rx_stat *stat)  
    39364153    agc  = (le16toh(phy->agc) >> 7) & 0x7f;
    39374154
    39384155    rssi = 0;
    3939 #if 0
    3940     if (mask & IWN_ANT_A)   /* Ant A */
    3941         rssi = max(rssi, phy->rssi[0]);
    3942     if (mask & IWN_ATH_B)   /* Ant B */
    3943         rssi = max(rssi, phy->rssi[2]);
    3944     if (mask & IWN_ANT_C)   /* Ant C */
    3945         rssi = max(rssi, phy->rssi[4]);
    3946 #else
    3947     rssi = max(rssi, phy->rssi[0]);
    3948     rssi = max(rssi, phy->rssi[2]);
    3949     rssi = max(rssi, phy->rssi[4]);
    3950 #endif
    3951 
    3952     DPRINTF(sc, IWN_DEBUG_RECV, "%s: agc %d mask 0x%x rssi %d %d %d "
    3953         "result %d\n", __func__, agc, mask,
    3954         phy->rssi[0], phy->rssi[2], phy->rssi[4],
     4156    if (mask & IWN_ANT_A)
     4157        rssi = MAX(rssi, phy->rssi[0]);
     4158    if (mask & IWN_ANT_B)
     4159        rssi = MAX(rssi, phy->rssi[2]);
     4160    if (mask & IWN_ANT_C)
     4161        rssi = MAX(rssi, phy->rssi[4]);
     4162
     4163    DPRINTF(sc, IWN_DEBUG_RECV,
     4164        "%s: agc %d mask 0x%x rssi %d %d %d result %d\n", __func__, agc,
     4165        mask, phy->rssi[0], phy->rssi[2], phy->rssi[4],
    39554166        rssi - agc - IWN_RSSI_TO_DBM);
    39564167    return rssi - agc - IWN_RSSI_TO_DBM;
    39574168}
    static int  
    39604171iwn5000_get_rssi(struct iwn_softc *sc, struct iwn_rx_stat *stat)
    39614172{
    39624173    struct iwn5000_rx_phystat *phy = (void *)stat->phybuf;
    3963     int rssi;
    39644174    uint8_t agc;
     4175    int rssi;
    39654176
    39664177    agc = (le32toh(phy->agc) >> 9) & 0x7f;
    39674178
    iwn5000_get_rssi(struct iwn_softc *sc, struct iwn_rx_stat *stat)  
    39694180           le16toh(phy->rssi[1]) & 0xff);
    39704181    rssi = MAX(le16toh(phy->rssi[2]) & 0xff, rssi);
    39714182
    3972     DPRINTF(sc, IWN_DEBUG_RECV, "%s: agc %d rssi %d %d %d "
    3973         "result %d\n", __func__, agc,
     4183    DPRINTF(sc, IWN_DEBUG_RECV,
     4184        "%s: agc %d rssi %d %d %d result %d\n", __func__, agc,
    39744185        phy->rssi[0], phy->rssi[1], phy->rssi[2],
    39754186        rssi - agc - IWN_RSSI_TO_DBM);
    39764187    return rssi - agc - IWN_RSSI_TO_DBM;
    iwn4965_get_temperature(struct iwn_softc *sc)  
    40094220    r3 = le32toh(uc->temp[2].chan20MHz);
    40104221    r4 = le32toh(sc->rawtemp);
    40114222
    4012     if (r1 == r3)   /* Prevents division by 0 (should not happen.) */
     4223    if (r1 == r3)   /* Prevents division by 0 (should not happen). */
    40134224        return 0;
    40144225
    40154226    /* Sign-extend 23-bit R4 value to 32-bit. */
    4016     r4 = (r4 << 8) >> 8;
     4227    r4 = ((r4 & 0xffffff) ^ 0x800000) - 0x800000;
    40174228    /* Compute temperature in Kelvin. */
    40184229    temp = (259 * (r4 - r2)) / (r3 - r1);
    40194230    temp = (temp * 97) / 100 + 8;
    iwn5000_get_temperature(struct iwn_softc *sc)  
    40304241
    40314242    /*
    40324243     * Temperature is not used by the driver for 5000 Series because
    4033      * TX power calibration is handled by firmware.  We export it to
    4034      * users through the sensor framework though.
     4244     * TX power calibration is handled by firmware.
    40354245     */
    40364246    temp = le32toh(sc->rawtemp);
    40374247    if (sc->hw_type == IWN_HW_REV_TYPE_5150) {
    iwn5000_get_temperature(struct iwn_softc *sc)  
    40474257static int
    40484258iwn_init_sensitivity(struct iwn_softc *sc)
    40494259{
    4050     const struct iwn_hal *hal = sc->sc_hal;
     4260    struct iwn_ops *ops = &sc->ops;
    40514261    struct iwn_calib_state *calib = &sc->calib;
    40524262    uint32_t flags;
    40534263    int error;
    iwn_init_sensitivity(struct iwn_softc *sc)  
    40664276    calib->energy_cck  = sc->limits->energy_cck;
    40674277
    40684278    /* Write initial sensitivity. */
    4069     error = iwn_send_sensitivity(sc);
    4070     if (error != 0)
     4279    if ((error = iwn_send_sensitivity(sc)) != 0)
    40714280        return error;
    40724281
    40734282    /* Write initial gains. */
    4074     error = hal->init_gains(sc);
    4075     if (error != 0)
     4283    if ((error = ops->init_gains(sc)) != 0)
    40764284        return error;
    40774285
    40784286    /* Request statistics at each beacon interval. */
    40794287    flags = 0;
    4080     DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: calibrate phy\n", __func__);
     4288    DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: sending request for statistics\n",
     4289        __func__);
    40814290    return iwn_cmd(sc, IWN_CMD_GET_STATISTICS, &flags, sizeof flags, 1);
    40824291}
    40834292
    static void  
    40904299iwn_collect_noise(struct iwn_softc *sc,
    40914300    const struct iwn_rx_general_stats *stats)
    40924301{
    4093     const struct iwn_hal *hal = sc->sc_hal;
     4302    struct iwn_ops *ops = &sc->ops;
    40944303    struct iwn_calib_state *calib = &sc->calib;
    40954304    uint32_t val;
    40964305    int i;
    iwn_collect_noise(struct iwn_softc *sc,  
    41214330    if ((sc->chainmask & sc->txchainmask) == 0)
    41224331        sc->chainmask |= IWN_LSB(sc->txchainmask);
    41234332
    4124     (void)hal->set_gains(sc);
     4333    (void)ops->set_gains(sc);
    41254334    calib->state = IWN_CALIB_STATE_RUN;
    41264335
    41274336#ifdef notyet
    41284337    /* XXX Disable RX chains with no antennas connected. */
    41294338    sc->rxon.rxchain = htole16(IWN_RXCHAIN_SEL(sc->chainmask));
    4130     (void)iwn_cmd(sc, IWN_CMD_RXON, &sc->rxon, hal->rxonsz, 1);
     4339    (void)iwn_cmd(sc, IWN_CMD_RXON, &sc->rxon, sc->rxonsz, 1);
    41314340#endif
    41324341
    41334342#if 0
    iwn5000_init_gains(struct iwn_softc *sc)  
    41574366    struct iwn_phy_calib cmd;
    41584367
    41594368    memset(&cmd, 0, sizeof cmd);
    4160     cmd.code = IWN5000_PHY_CALIB_RESET_NOISE_GAIN;
     4369    cmd.code = sc->reset_noise_gain;
    41614370    cmd.ngroups = 1;
    41624371    cmd.isvalid = 1;
    41634372    DPRINTF(sc, IWN_DEBUG_CALIBRATE,
    iwn5000_set_gains(struct iwn_softc *sc)  
    42034412{
    42044413    struct iwn_calib_state *calib = &sc->calib;
    42054414    struct iwn_phy_calib_gain cmd;
    4206     int i, ant, delta, div;
     4415    int i, ant, div, delta;
    42074416
    42084417    /* We collected 20 beacons and !=6050 need a 1.5 factor. */
    42094418    div = (sc->hw_type == IWN_HW_REV_TYPE_6050) ? 20 : 30;
    42104419
    42114420    memset(&cmd, 0, sizeof cmd);
    4212     cmd.code = IWN5000_PHY_CALIB_NOISE_GAIN;
     4421    cmd.code = sc->noise_gain;
    42134422    cmd.ngroups = 1;
    42144423    cmd.isvalid = 1;
    42154424    /* Get first available RX antenna as referential. */
    iwn_tune_sensitivity(struct iwn_softc *sc, const struct iwn_rx_stats *stats)  
    42644473    int i, needs_update = 0;
    42654474
    42664475    /* Check that we've been enabled long enough. */
    4267     rxena = le32toh(stats->general.load);
    4268     if (rxena == 0)
     4476    if ((rxena = le32toh(stats->general.load)) == 0)
    42694477        return;
    42704478
    42714479    /* Compute number of false alarms since last call for OFDM. */
    42724480    fa  = le32toh(stats->ofdm.bad_plcp) - calib->bad_plcp_ofdm;
    42734481    fa += le32toh(stats->ofdm.fa) - calib->fa_ofdm;
    4274     fa *= 200 * 1024;   /* 200TU */
     4482    fa *= 200 * IEEE80211_DUR_TU;   /* 200TU */
    42754483
    42764484    /* Save counters values for next call. */
    42774485    calib->bad_plcp_ofdm = le32toh(stats->ofdm.bad_plcp);
    iwn_tune_sensitivity(struct iwn_softc *sc, const struct iwn_rx_stats *stats)  
    43284536    /* Compute number of false alarms since last call for CCK. */
    43294537    fa  = le32toh(stats->cck.bad_plcp) - calib->bad_plcp_cck;
    43304538    fa += le32toh(stats->cck.fa) - calib->fa_cck;
    4331     fa *= 200 * 1024;   /* 200TU */
     4539    fa *= 200 * IEEE80211_DUR_TU;   /* 200TU */
    43324540
    43334541    /* Save counters values for next call. */
    43344542    calib->bad_plcp_cck = le32toh(stats->cck.bad_plcp);
    iwn_tune_sensitivity(struct iwn_softc *sc, const struct iwn_rx_stats *stats)  
    43634571
    43644572        if (calib->cck_state != IWN_CCK_STATE_INIT &&
    43654573            (((int32_t)calib->noise_ref - (int32_t)noise_ref) > 2 ||
    4366             calib->low_fa > 100)) {
     4574             calib->low_fa > 100)) {
    43674575            inc(calib->energy_cck, 2, limits->min_energy_cck);
    43684576            dec(calib->cck_x4,     3, limits->min_cck_x4);
    43694577            dec(calib->cck_mrc_x4, 3, limits->min_cck_mrc_x4);
    static int  
    43924600iwn_send_sensitivity(struct iwn_softc *sc)
    43934601{
    43944602    struct iwn_calib_state *calib = &sc->calib;
    4395     struct iwn_sensitivity_cmd cmd;
     4603    struct iwn_enhanced_sensitivity_cmd cmd;
     4604    int len;
    43964605
    43974606    memset(&cmd, 0, sizeof cmd);
     4607    len = sizeof (struct iwn_sensitivity_cmd);
    43984608    cmd.which = IWN_SENSITIVITY_WORKTBL;
    43994609    /* OFDM modulation. */
    4400     cmd.corr_ofdm_x1     = htole16(calib->ofdm_x1);
    4401     cmd.corr_ofdm_mrc_x1 = htole16(calib->ofdm_mrc_x1);
    4402     cmd.corr_ofdm_x4     = htole16(calib->ofdm_x4);
    4403     cmd.corr_ofdm_mrc_x4 = htole16(calib->ofdm_mrc_x4);
    4404     cmd.energy_ofdm      = htole16(sc->limits->energy_ofdm);
    4405     cmd.energy_ofdm_th   = htole16(62);
     4610    cmd.corr_ofdm_x1       = htole16(calib->ofdm_x1);
     4611    cmd.corr_ofdm_mrc_x1   = htole16(calib->ofdm_mrc_x1);
     4612    cmd.corr_ofdm_x4       = htole16(calib->ofdm_x4);
     4613    cmd.corr_ofdm_mrc_x4   = htole16(calib->ofdm_mrc_x4);
     4614    cmd.energy_ofdm        = htole16(sc->limits->energy_ofdm);
     4615    cmd.energy_ofdm_th     = htole16(62);
    44064616    /* CCK modulation. */
    4407     cmd.corr_cck_x4      = htole16(calib->cck_x4);
    4408     cmd.corr_cck_mrc_x4  = htole16(calib->cck_mrc_x4);
    4409     cmd.energy_cck       = htole16(calib->energy_cck);
     4617    cmd.corr_cck_x4        = htole16(calib->cck_x4);
     4618    cmd.corr_cck_mrc_x4    = htole16(calib->cck_mrc_x4);
     4619    cmd.energy_cck         = htole16(calib->energy_cck);
    44104620    /* Barker modulation: use default values. */
    4411     cmd.corr_barker      = htole16(190);
    4412     cmd.corr_barker_mrc  = htole16(390);
     4621    cmd.corr_barker        = htole16(190);
     4622    cmd.corr_barker_mrc    = htole16(390);
    44134623
    44144624    DPRINTF(sc, IWN_DEBUG_CALIBRATE,
    44154625        "%s: set sensitivity %d/%d/%d/%d/%d/%d/%d\n", __func__,
    44164626        calib->ofdm_x1, calib->ofdm_mrc_x1, calib->ofdm_x4,
    44174627        calib->ofdm_mrc_x4, calib->cck_x4,
    44184628        calib->cck_mrc_x4, calib->energy_cck);
    4419     return iwn_cmd(sc, IWN_CMD_SET_SENSITIVITY, &cmd, sizeof cmd, 1);
     4629
     4630    if (!(sc->sc_flags & IWN_FLAG_ENH_SENS))
     4631        goto send;
     4632    /* Enhanced sensitivity settings. */
     4633    len = sizeof (struct iwn_enhanced_sensitivity_cmd);
     4634    cmd.ofdm_det_slope_mrc = htole16(668);
     4635    cmd.ofdm_det_icept_mrc = htole16(4);
     4636    cmd.ofdm_det_slope     = htole16(486);
     4637    cmd.ofdm_det_icept     = htole16(37);
     4638    cmd.cck_det_slope_mrc  = htole16(853);
     4639    cmd.cck_det_icept_mrc  = htole16(4);
     4640    cmd.cck_det_slope      = htole16(476);
     4641    cmd.cck_det_icept      = htole16(99);
     4642send:
     4643    return iwn_cmd(sc, IWN_CMD_SET_SENSITIVITY, &cmd, len, 1);
    44204644}
    44214645
    44224646/*
    iwn_send_sensitivity(struct iwn_softc *sc)  
    44264650static int
    44274651iwn_set_pslevel(struct iwn_softc *sc, int dtim, int level, int async)
    44284652{
    4429     const struct iwn_pmgt *pmgt;
    44304653    struct iwn_pmgt_cmd cmd;
     4654    const struct iwn_pmgt *pmgt;
    44314655    uint32_t max, skip_dtim;
    4432     uint32_t tmp;
     4656    uint32_t reg;
    44334657    int i;
    44344658
    44354659    /* Select which PS parameters to use. */
    iwn_set_pslevel(struct iwn_softc *sc, int dtim, int level, int async)  
    44464670    if (level == 5)
    44474671        cmd.flags |= htole16(IWN_PS_FAST_PD);
    44484672    /* Retrieve PCIe Active State Power Management (ASPM). */
    4449     tmp = pci_read_config(sc->sc_dev, sc->sc_cap_off + 0x10, 1);
    4450     if (!(tmp & 0x1))   /* L0s Entry disabled. */
     4673    reg = pci_read_config(sc->sc_dev, sc->sc_cap_off + 0x10, 1);
     4674    if (!(reg & 0x1))   /* L0s Entry disabled. */
    44514675        cmd.flags |= htole16(IWN_PS_PCI_PMGT);
    44524676    cmd.rxtimeout = htole32(pmgt->rxtimeout * 1024);
    44534677    cmd.txtimeout = htole32(pmgt->txtimeout * 1024);
    iwn_set_pslevel(struct iwn_softc *sc, int dtim, int level, int async)  
    44754699}
    44764700
    44774701static int
     4702iwn_send_btcoex(struct iwn_softc *sc)
     4703{
     4704    struct iwn_bluetooth cmd;
     4705
     4706    memset(&cmd, 0, sizeof cmd);
     4707    cmd.flags = IWN_BT_COEX_CHAN_ANN | IWN_BT_COEX_BT_PRIO;
     4708    cmd.lead_time = IWN_BT_LEAD_TIME_DEF;
     4709    cmd.max_kill = IWN_BT_MAX_KILL_DEF;
     4710    DPRINTF(sc, IWN_DEBUG_RESET, "%s: configuring bluetooth coexistence\n",
     4711        __func__);
     4712    return iwn_cmd(sc, IWN_CMD_BT_COEX, &cmd, sizeof(cmd), 0);
     4713}
     4714
     4715static int
     4716iwn_send_advanced_btcoex(struct iwn_softc *sc)
     4717{
     4718    static const uint32_t btcoex_3wire[12] = {
     4719        0xaaaaaaaa, 0xaaaaaaaa, 0xaeaaaaaa, 0xaaaaaaaa,
     4720        0xcc00ff28, 0x0000aaaa, 0xcc00aaaa, 0x0000aaaa,
     4721        0xc0004000, 0x00004000, 0xf0005000, 0xf0005000,
     4722    };
     4723    struct iwn6000_btcoex_config btconfig;
     4724    struct iwn_btcoex_priotable btprio;
     4725    struct iwn_btcoex_prot btprot;
     4726    int error, i;
     4727
     4728    memset(&btconfig, 0, sizeof btconfig);
     4729    btconfig.flags = 145;
     4730    btconfig.max_kill = 5;
     4731    btconfig.bt3_t7_timer = 1;
     4732    btconfig.kill_ack = htole32(0xffff0000);
     4733    btconfig.kill_cts = htole32(0xffff0000);
     4734    btconfig.sample_time = 2;
     4735    btconfig.bt3_t2_timer = 0xc;
     4736    for (i = 0; i < 12; i++)
     4737        btconfig.lookup_table[i] = htole32(btcoex_3wire[i]);
     4738    btconfig.valid = htole16(0xff);
     4739    btconfig.prio_boost = 0xf0;
     4740    DPRINTF(sc, IWN_DEBUG_RESET,
     4741        "%s: configuring advanced bluetooth coexistence\n", __func__);
     4742    error = iwn_cmd(sc, IWN_CMD_BT_COEX, &btconfig, sizeof(btconfig), 1);
     4743    if (error != 0)
     4744        return error;
     4745
     4746    memset(&btprio, 0, sizeof btprio);
     4747    btprio.calib_init1 = 0x6;
     4748    btprio.calib_init2 = 0x7;
     4749    btprio.calib_periodic_low1 = 0x2;
     4750    btprio.calib_periodic_low2 = 0x3;
     4751    btprio.calib_periodic_high1 = 0x4;
     4752    btprio.calib_periodic_high2 = 0x5;
     4753    btprio.dtim = 0x6;
     4754    btprio.scan52 = 0x8;
     4755    btprio.scan24 = 0xa;
     4756    error = iwn_cmd(sc, IWN_CMD_BT_COEX_PRIOTABLE, &btprio, sizeof(btprio),
     4757        1);
     4758    if (error != 0)
     4759        return error;
     4760
     4761    /* Force BT state machine change. */
     4762    memset(&btprot, 0, sizeof btprio);
     4763    btprot.open = 1;
     4764    btprot.type = 1;
     4765    error = iwn_cmd(sc, IWN_CMD_BT_COEX_PROT, &btprot, sizeof(btprot), 1);
     4766    if (error != 0)
     4767        return error;
     4768    btprot.open = 0;
     4769    return iwn_cmd(sc, IWN_CMD_BT_COEX_PROT, &btprot, sizeof(btprot), 1);
     4770}
     4771
     4772static int
    44784773iwn_config(struct iwn_softc *sc)
    44794774{
    4480     const struct iwn_hal *hal = sc->sc_hal;
     4775    struct iwn_ops *ops = &sc->ops;
    44814776    struct ifnet *ifp = sc->sc_ifp;
    44824777    struct ieee80211com *ic = ifp->if_l2com;
    4483     struct iwn_bluetooth bluetooth;
    44844778    uint32_t txmask;
    4485     int error;
    44864779    uint16_t rxchain;
     4780    int error;
     4781
     4782    if (sc->hw_type == IWN_HW_REV_TYPE_6005) {
     4783        /* Set radio temperature sensor offset. */
     4784        error = iwn5000_temp_offset_calib(sc);
     4785        if (error != 0) {
     4786            device_printf(sc->sc_dev,
     4787                "%s: could not set temperature offset\n", __func__);
     4788            return error;
     4789        }
     4790    }
    44874791
    4488     /* Configure valid TX chains for 5000 Series. */
     4792    /* Configure valid TX chains for >=5000 Series. */
    44894793    if (sc->hw_type != IWN_HW_REV_TYPE_4965) {
    44904794        txmask = htole32(sc->txchainmask);
    44914795        DPRINTF(sc, IWN_DEBUG_RESET,
    iwn_config(struct iwn_softc *sc)  
    45014805    }
    45024806
    45034807    /* Configure bluetooth coexistence. */
    4504     memset(&bluetooth, 0, sizeof bluetooth);
    4505     bluetooth.flags = IWN_BT_COEX_CHAN_ANN | IWN_BT_COEX_BT_PRIO;
    4506     bluetooth.lead_time = IWN_BT_LEAD_TIME_DEF;
    4507     bluetooth.max_kill = IWN_BT_MAX_KILL_DEF;
    4508     DPRINTF(sc, IWN_DEBUG_RESET, "%s: config bluetooth coexistence\n",
    4509         __func__);
    4510     error = iwn_cmd(sc, IWN_CMD_BT_COEX, &bluetooth, sizeof bluetooth, 0);
     4808    if (sc->sc_flags & IWN_FLAG_ADV_BTCOEX)
     4809        error = iwn_send_advanced_btcoex(sc);
     4810    else
     4811        error = iwn_send_btcoex(sc);
    45114812    if (error != 0) {
    45124813        device_printf(sc->sc_dev,
    45134814            "%s: could not configure bluetooth coexistence, error %d\n",
    iwn_config(struct iwn_softc *sc)  
    45484849        IWN_RXCHAIN_IDLE_COUNT(2);
    45494850    sc->rxon.rxchain = htole16(rxchain);
    45504851    DPRINTF(sc, IWN_DEBUG_RESET, "%s: setting configuration\n", __func__);
    4551     error = iwn_cmd(sc, IWN_CMD_RXON, &sc->rxon, hal->rxonsz, 0);
     4852    error = iwn_cmd(sc, IWN_CMD_RXON, &sc->rxon, sc->rxonsz, 0);
    45524853    if (error != 0) {
    4553         device_printf(sc->sc_dev,
    4554             "%s: RXON command failed\n", __func__);
     4854        device_printf(sc->sc_dev, "%s: RXON command failed\n",
     4855            __func__);
    45554856        return error;
    45564857    }
    45574858
    4558     error = iwn_add_broadcast_node(sc, 0);
    4559     if (error != 0) {
    4560         device_printf(sc->sc_dev,
    4561             "%s: could not add broadcast node\n", __func__);
     4859    if ((error = iwn_add_broadcast_node(sc, 0)) != 0) {
     4860        device_printf(sc->sc_dev, "%s: could not add broadcast node\n",
     4861            __func__);
    45624862        return error;
    45634863    }
    45644864
    45654865    /* Configuration has changed, set TX power accordingly. */
    4566     error = hal->set_txpower(sc, ic->ic_curchan, 0);
    4567     if (error != 0) {
    4568         device_printf(sc->sc_dev,
    4569             "%s: could not set TX power\n", __func__);
     4866    if ((error = ops->set_txpower(sc, ic->ic_curchan, 0)) != 0) {
     4867        device_printf(sc->sc_dev, "%s: could not set TX power\n",
     4868            __func__);
    45704869        return error;
    45714870    }
    45724871
    4573     error = iwn_set_critical_temp(sc);
    4574     if (error != 0) {
     4872    if ((error = iwn_set_critical_temp(sc)) != 0) {
    45754873        device_printf(sc->sc_dev,
    4576             "%s: ccould not set critical temperature\n", __func__);
     4874            "%s: could not set critical temperature\n", __func__);
    45774875        return error;
    45784876    }
    45794877
    45804878    /* Set power saving level to CAM during initialization. */
    4581     error = iwn_set_pslevel(sc, 0, 0, 0);
    4582     if (error != 0) {
     4879    if ((error = iwn_set_pslevel(sc, 0, 0, 0)) != 0) {
    45834880        device_printf(sc->sc_dev,
    45844881            "%s: could not set power saving level\n", __func__);
    45854882        return error;
    iwn_config(struct iwn_softc *sc)  
    45874884    return 0;
    45884885}
    45894886
     4887/*
     4888 * Add an ssid element to a frame.
     4889 */
     4890static uint8_t *
     4891ieee80211_add_ssid(uint8_t *frm, const uint8_t *ssid, u_int len)
     4892{
     4893    *frm++ = IEEE80211_ELEMID_SSID;
     4894    *frm++ = len;
     4895    memcpy(frm, ssid, len);
     4896    return frm + len;
     4897}
     4898
    45904899static int
    45914900iwn_scan(struct iwn_softc *sc)
    45924901{
    iwn_scan(struct iwn_softc *sc)  
    46004909    struct ieee80211_frame *wh;
    46014910    struct ieee80211_rateset *rs;
    46024911    struct ieee80211_channel *c;
    4603     int buflen, error, nrates;
     4912    uint8_t *buf, *frm;
    46044913    uint16_t rxchain;
    4605     uint8_t *buf, *frm, txant;
     4914    uint8_t txant;
     4915    int buflen, error;
    46064916
    46074917    buf = malloc(IWN_SCAN_MAXSZ, M_DEVBUF, M_NOWAIT | M_ZERO);
    46084918    if (buf == NULL) {
    iwn_scan(struct iwn_softc *sc)  
    46124922        return ENOMEM;
    46134923    }
    46144924    hdr = (struct iwn_scan_hdr *)buf;
    4615 
    46164925    /*
    46174926     * Move to the next channel if no frames are received within 10ms
    46184927     * after sending the probe request.
    iwn_scan(struct iwn_softc *sc)  
    46364945
    46374946    tx = (struct iwn_cmd_data *)(hdr + 1);
    46384947    tx->flags = htole32(IWN_TX_AUTO_SEQ);
    4639     tx->id = sc->sc_hal->broadcast_id;
     4948    tx->id = sc->broadcast_id;
    46404949    tx->lifetime = htole32(IWN_LIFETIME_INFINITE);
    46414950
    46424951    if (IEEE80211_IS_CHAN_A(ic->ic_curchan)) {
    iwn_scan(struct iwn_softc *sc)  
    46604969        essid[0].len = ss->ss_ssid[0].len;
    46614970        memcpy(essid[0].data, ss->ss_ssid[0].ssid, ss->ss_ssid[0].len);
    46624971    }
    4663 
    46644972    /*
    46654973     * Build a probe request frame.  Most of the following code is a
    46664974     * copy & paste of what is done in net80211.
    iwn_scan(struct iwn_softc *sc)  
    46764984    *(uint16_t *)&wh->i_seq[0] = 0; /* filled by HW */
    46774985
    46784986    frm = (uint8_t *)(wh + 1);
    4679 
    4680     /* Add SSID IE. */
    4681     *frm++ = IEEE80211_ELEMID_SSID;
    4682     *frm++ = ss->ss_ssid[0].len;
    4683     memcpy(frm, ss->ss_ssid[0].ssid, ss->ss_ssid[0].len);
    4684     frm += ss->ss_ssid[0].len;
    4685 
    4686     /* Add supported rates IE. */
    4687     *frm++ = IEEE80211_ELEMID_RATES;
    4688     nrates = rs->rs_nrates;
    4689     if (nrates > IEEE80211_RATE_SIZE)
    4690         nrates = IEEE80211_RATE_SIZE;
    4691     *frm++ = nrates;
    4692     memcpy(frm, rs->rs_rates, nrates);
    4693     frm += nrates;
    4694 
    4695     /* Add supported xrates IE. */
    4696     if (rs->rs_nrates > IEEE80211_RATE_SIZE) {
    4697         nrates = rs->rs_nrates - IEEE80211_RATE_SIZE;
    4698         *frm++ = IEEE80211_ELEMID_XRATES;
    4699         *frm++ = (uint8_t)nrates;
    4700         memcpy(frm, rs->rs_rates + IEEE80211_RATE_SIZE, nrates);
    4701         frm += nrates;
    4702     }
     4987    frm = ieee80211_add_ssid(frm, NULL, 0);
     4988    frm = ieee80211_add_rates(frm, rs);
     4989    if (rs->rs_nrates > IEEE80211_RATE_SIZE)
     4990        frm = ieee80211_add_xrates(frm, rs);
     4991#if 0   /* HT */
     4992    if (ic->ic_flags & IEEE80211_F_HTON)
     4993        frm = ieee80211_add_htcaps(frm, ic);
     4994#endif
    47034995
    47044996    /* Set length of probe request. */
    47054997    tx->len = htole16(frm - (uint8_t *)wh);
    iwn_scan(struct iwn_softc *sc)  
    47615053static int
    47625054iwn_auth(struct iwn_softc *sc, struct ieee80211vap *vap)
    47635055{
    4764     const struct iwn_hal *hal = sc->sc_hal;
     5056    struct iwn_ops *ops = &sc->ops;
    47655057    struct ifnet *ifp = sc->sc_ifp;
    47665058    struct ieee80211com *ic = ifp->if_l2com;
    47675059    struct ieee80211_node *ni = vap->iv_bss;
    47685060    int error;
    47695061
    4770     sc->calib.state = IWN_CALIB_STATE_INIT;
    4771 
    47725062    /* Update adapter configuration. */
    47735063    IEEE80211_ADDR_COPY(sc->rxon.bssid, ni->ni_bssid);
    4774     sc->rxon.chan = htole16(ieee80211_chan2ieee(ic, ni->ni_chan));
     5064    sc->rxon.chan = ieee80211_chan2ieee(ic, ni->ni_chan);
    47755065    sc->rxon.flags = htole32(IWN_RXON_TSF | IWN_RXON_CTS_TO_SELF);
    47765066    if (IEEE80211_IS_CHAN_2GHZ(ni->ni_chan))
    47775067        sc->rxon.flags |= htole32(IWN_RXON_AUTO | IWN_RXON_24GHZ);
    iwn_auth(struct iwn_softc *sc, struct ieee80211vap *vap)  
    47865076        sc->rxon.cck_mask  = 0x03;
    47875077        sc->rxon.ofdm_mask = 0;
    47885078    } else {
    4789         /* XXX assume 802.11b/g */
     5079        /* Assume 802.11b/g. */
    47905080        sc->rxon.cck_mask  = 0x0f;
    47915081        sc->rxon.ofdm_mask = 0x15;
    47925082    }
    4793     DPRINTF(sc, IWN_DEBUG_STATE,
    4794         "%s: config chan %d mode %d flags 0x%x cck 0x%x ofdm 0x%x "
    4795         "ht_single 0x%x ht_dual 0x%x rxchain 0x%x "
    4796         "myaddr %6D wlap %6D bssid %6D associd %d filter 0x%x\n",
    4797         __func__,
    4798         le16toh(sc->rxon.chan), sc->rxon.mode, le32toh(sc->rxon.flags),
    4799         sc->rxon.cck_mask, sc->rxon.ofdm_mask,
    4800         sc->rxon.ht_single_mask, sc->rxon.ht_dual_mask,
    4801         le16toh(sc->rxon.rxchain),
    4802         sc->rxon.myaddr, ":", sc->rxon.wlap, ":", sc->rxon.bssid, ":",
    4803         le16toh(sc->rxon.associd), le32toh(sc->rxon.filter));
    4804     error = iwn_cmd(sc, IWN_CMD_RXON, &sc->rxon, hal->rxonsz, 1);
     5083    DPRINTF(sc, IWN_DEBUG_STATE, "rxon chan %d flags %x cck %x ofdm %x\n",
     5084        sc->rxon.chan, sc->rxon.flags, sc->rxon.cck_mask,
     5085        sc->rxon.ofdm_mask);
     5086    error = iwn_cmd(sc, IWN_CMD_RXON, &sc->rxon, sc->rxonsz, 1);
    48055087    if (error != 0) {
    4806         device_printf(sc->sc_dev,
    4807             "%s: RXON command failed, error %d\n", __func__, error);
     5088        device_printf(sc->sc_dev, "%s: RXON command failed, error %d\n",
     5089            __func__, error);
    48085090        return error;
    48095091    }
    48105092
    48115093    /* Configuration has changed, set TX power accordingly. */
    4812     error = hal->set_txpower(sc, ni->ni_chan, 1);
    4813     if (error != 0) {
     5094    if ((error = ops->set_txpower(sc, ni->ni_chan, 1)) != 0) {
    48145095        device_printf(sc->sc_dev,
    4815             "%s: could not set Tx power, error %d\n", __func__, error);
     5096            "%s: could not set TX power, error %d\n", __func__, error);
    48165097        return error;
    48175098    }
    48185099    /*
    48195100     * Reconfiguring RXON clears the firmware nodes table so we must
    48205101     * add the broadcast node again.
    48215102     */
    4822     error = iwn_add_broadcast_node(sc, 1);
    4823     if (error != 0) {
     5103    if ((error = iwn_add_broadcast_node(sc, 1)) != 0) {
    48245104        device_printf(sc->sc_dev,
    4825             "%s: could not add broadcast node, error %d\n",
    4826             __func__, error);
     5105            "%s: could not add broadcast node, error %d\n", __func__,
     5106            error);
    48275107        return error;
    48285108    }
    48295109    return 0;
    48305110}
    48315111
    4832 /*
    4833  * Configure the adapter for associated state.
    4834  */
    48355112static int
    48365113iwn_run(struct iwn_softc *sc, struct ieee80211vap *vap)
    48375114{
    48385115#define MS(v,x) (((v) & x) >> x##_S)
    4839     const struct iwn_hal *hal = sc->sc_hal;
     5116    struct iwn_ops *ops = &sc->ops;
    48405117    struct ifnet *ifp = sc->sc_ifp;
    48415118    struct ieee80211com *ic = ifp->if_l2com;
    48425119    struct ieee80211_node *ni = vap->iv_bss;
    iwn_run(struct iwn_softc *sc, struct ieee80211vap *vap)  
    48455122
    48465123    if (ic->ic_opmode == IEEE80211_M_MONITOR) {
    48475124        /* Link LED blinks while monitoring. */
    4848         iwn_set_led(sc, IWN_LED_LINK, 20, 20);
     5125        iwn_set_led(sc, IWN_LED_LINK, 5, 5);
    48495126        return 0;
    48505127    }
    4851     error = iwn_set_timing(sc, ni);
    4852     if (error != 0) {
     5128    if ((error = iwn_set_timing(sc, ni)) != 0) {
    48535129        device_printf(sc->sc_dev,
    48545130            "%s: could not set timing, error %d\n", __func__, error);
    48555131        return error;
    iwn_run(struct iwn_softc *sc, struct ieee80211vap *vap)  
    48575133
    48585134    /* Update adapter configuration. */
    48595135    IEEE80211_ADDR_COPY(sc->rxon.bssid, ni->ni_bssid);
    4860     sc->rxon.chan = htole16(ieee80211_chan2ieee(ic, ni->ni_chan));
    48615136    sc->rxon.associd = htole16(IEEE80211_AID(ni->ni_associd));
    4862     /* Short preamble and slot time are negotiated when associating. */
    4863     sc->rxon.flags &= ~htole32(IWN_RXON_SHPREAMBLE | IWN_RXON_SHSLOT);
    4864     sc->rxon.flags |= htole32(IWN_RXON_TSF | IWN_RXON_CTS_TO_SELF);
     5137    sc->rxon.chan = ieee80211_chan2ieee(ic, ni->ni_chan);
     5138    sc->rxon.flags = htole32(IWN_RXON_TSF | IWN_RXON_CTS_TO_SELF);
    48655139    if (IEEE80211_IS_CHAN_2GHZ(ni->ni_chan))
    48665140        sc->rxon.flags |= htole32(IWN_RXON_AUTO | IWN_RXON_24GHZ);
    4867     else
    4868         sc->rxon.flags &= ~htole32(IWN_RXON_AUTO | IWN_RXON_24GHZ);
    48695141    if (ic->ic_flags & IEEE80211_F_SHSLOT)
    48705142        sc->rxon.flags |= htole32(IWN_RXON_SHSLOT);
    48715143    if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)
    iwn_run(struct iwn_softc *sc, struct ieee80211vap *vap)  
    48775149        sc->rxon.cck_mask  = 0x03;
    48785150        sc->rxon.ofdm_mask = 0;
    48795151    } else {
    4880         /* XXX assume 802.11b/g */
     5152        /* Assume 802.11b/g. */
    48815153        sc->rxon.cck_mask  = 0x0f;
    48825154        sc->rxon.ofdm_mask = 0x15;
    48835155    }
    iwn_run(struct iwn_softc *sc, struct ieee80211vap *vap)  
    49025174        maxrxampdu = ampdudensity = 0;
    49035175#endif
    49045176    sc->rxon.filter |= htole32(IWN_FILTER_BSS);
    4905 
    4906     DPRINTF(sc, IWN_DEBUG_STATE,
    4907         "%s: config chan %d mode %d flags 0x%x cck 0x%x ofdm 0x%x "
    4908         "ht_single 0x%x ht_dual 0x%x rxchain 0x%x "
    4909         "myaddr %6D wlap %6D bssid %6D associd %d filter 0x%x\n",
    4910         __func__,
    4911         le16toh(sc->rxon.chan), sc->rxon.mode, le32toh(sc->rxon.flags),
    4912         sc->rxon.cck_mask, sc->rxon.ofdm_mask,
    4913         sc->rxon.ht_single_mask, sc->rxon.ht_dual_mask,
    4914         le16toh(sc->rxon.rxchain),
    4915         sc->rxon.myaddr, ":", sc->rxon.wlap, ":", sc->rxon.bssid, ":",
    4916         le16toh(sc->rxon.associd), le32toh(sc->rxon.filter));
    4917     error = iwn_cmd(sc, IWN_CMD_RXON, &sc->rxon, hal->rxonsz, 1);
     5177    DPRINTF(sc, IWN_DEBUG_STATE, "rxon chan %d flags %x\n",
     5178        sc->rxon.chan, sc->rxon.flags);
     5179    error = iwn_cmd(sc, IWN_CMD_RXON, &sc->rxon, sc->rxonsz, 1);
    49185180    if (error != 0) {
    49195181        device_printf(sc->sc_dev,
    4920             "%s: could not update configuration, error %d\n",
    4921             __func__, error);
     5182            "%s: could not update configuration, error %d\n", __func__,
     5183            error);
    49225184        return error;
    49235185    }
    49245186
    49255187    /* Configuration has changed, set TX power accordingly. */
    4926     error = hal->set_txpower(sc, ni->ni_chan, 1);
    4927     if (error != 0) {
     5188    if ((error = ops->set_txpower(sc, ni->ni_chan, 1)) != 0) {
    49285189        device_printf(sc->sc_dev,
    4929             "%s: could not set Tx power, error %d\n", __func__, error);
     5190            "%s: could not set TX power, error %d\n", __func__, error);
    49305191        return error;
    49315192    }
    49325193
     5194    /* Fake a join to initialize the TX rate. */
     5195    ((struct iwn_node *)ni)->id = IWN_ID_BSS;
     5196    iwn_newassoc(ni, 1);
     5197
    49335198    /* Add BSS node. */
    49345199    memset(&node, 0, sizeof node);
    49355200    IEEE80211_ADDR_COPY(node.macaddr, ni->ni_macaddr);
    iwn_run(struct iwn_softc *sc, struct ieee80211vap *vap)  
    49385203    node.htflags = htole32(IWN_AMDPU_SIZE_FACTOR(3) |
    49395204        IWN_AMDPU_DENSITY(5));  /* 2us */
    49405205#endif
    4941     DPRINTF(sc, IWN_DEBUG_STATE, "%s: add BSS node, id %d htflags 0x%x\n",
    4942         __func__, node.id, le32toh(node.htflags));
    4943     error = hal->add_node(sc, &node, 1);
     5206    DPRINTF(sc, IWN_DEBUG_STATE, "%s: adding BSS node\n", __func__);
     5207    error = ops->add_node(sc, &node, 1);
    49445208    if (error != 0) {
    4945         device_printf(sc->sc_dev, "could not add BSS node\n");
     5209        device_printf(sc->sc_dev,
     5210            "%s: could not add BSS node, error %d\n", __func__, error);
    49465211        return error;
    49475212    }
    4948     DPRINTF(sc, IWN_DEBUG_STATE, "setting link quality for node %d\n",
    4949         node.id);
    4950     error = iwn_set_link_quality(sc, node.id, 1);
    4951     if (error != 0) {
     5213    DPRINTF(sc, IWN_DEBUG_STATE, "%s: setting link quality for node %d\n",
     5214        __func__, node.id);
     5215    if ((error = iwn_set_link_quality(sc, ni)) != 0) {
    49525216        device_printf(sc->sc_dev,
    4953             "%s: could not setup MRR for node %d, error %d\n",
     5217            "%s: could not setup link quality for node %d, error %d\n",
    49545218            __func__, node.id, error);
    49555219        return error;
    49565220    }
    49575221
    4958     error = iwn_init_sensitivity(sc);
    4959     if (error != 0) {
     5222    if ((error = iwn_init_sensitivity(sc)) != 0) {
    49605223        device_printf(sc->sc_dev,
    4961             "%s: could not set sensitivity, error %d\n",
    4962             __func__, error);
     5224            "%s: could not set sensitivity, error %d\n", __func__,
     5225            error);
    49635226        return error;
    49645227    }
    4965 
    49665228    /* Start periodic calibration timer. */
    49675229    sc->calib.state = IWN_CALIB_STATE_ASSOC;
    4968     iwn_calib_reset(sc);
     5230    sc->calib_cnt = 0;
     5231    callout_reset(&sc->calib_to, msecs_to_ticks(500), iwn_calib_timeout,
     5232        sc);
    49695233
    49705234    /* Link LED always on while associated. */
    49715235    iwn_set_led(sc, IWN_LED_LINK, 0, 1);
    4972 
    49735236    return 0;
    49745237#undef MS
    49755238}
    iwn_ampdu_rx_start(struct ieee80211com *ic, struct ieee80211_node *ni,  
    49855248{
    49865249    struct ieee80211_rx_ba *ba = &ni->ni_rx_ba[tid];
    49875250    struct iwn_softc *sc = ic->ic_softc;
     5251    struct iwn_ops *ops = &sc->ops;
    49885252    struct iwn_node *wn = (void *)ni;
    49895253    struct iwn_node_info node;
    49905254
    iwn_ampdu_rx_start(struct ieee80211com *ic, struct ieee80211_node *ni,  
    49955259    node.addba_tid = tid;
    49965260    node.addba_ssn = htole16(ba->ba_winstart);
    49975261    DPRINTF(sc, IWN_DEBUG_RECV, "ADDBA RA=%d TID=%d SSN=%d\n",
    4998         wn->id, tid, ba->ba_winstart));
    4999     return sc->sc_hal->add_node(sc, &node, 1);
     5262        wn->id, tid, ba->ba_winstart);
     5263    return ops->add_node(sc, &node, 1);
    50005264}
    50015265
    50025266/*
    50035267 * This function is called by upper layer on teardown of an HT-immediate
    5004  * Block Ack agreement (eg. uppon receipt of a DELBA frame.)
     5268 * Block Ack agreement (eg. uppon receipt of a DELBA frame).
    50055269 */
    50065270static void
    50075271iwn_ampdu_rx_stop(struct ieee80211com *ic, struct ieee80211_node *ni,
    50085272    uint8_t tid)
    50095273{
    50105274    struct iwn_softc *sc = ic->ic_softc;
     5275    struct iwn_ops *ops = &sc->ops;
    50115276    struct iwn_node *wn = (void *)ni;
    50125277    struct iwn_node_info node;
    50135278
    iwn_ampdu_rx_stop(struct ieee80211com *ic, struct ieee80211_node *ni,  
    50175282    node.flags = IWN_FLAG_SET_DELBA;
    50185283    node.delba_tid = tid;
    50195284    DPRINTF(sc, IWN_DEBUG_RECV, "DELBA RA=%d TID=%d\n", wn->id, tid);
    5020     (void)sc->sc_hal->add_node(sc, &node, 1);
     5285    (void)ops->add_node(sc, &node, 1);
    50215286}
    50225287
    50235288/*
    iwn_ampdu_tx_start(struct ieee80211com *ic, struct ieee80211_node *ni,  
    50305295{
    50315296    struct ieee80211_tx_ba *ba = &ni->ni_tx_ba[tid];
    50325297    struct iwn_softc *sc = ic->ic_softc;
    5033     const struct iwn_hal *hal = sc->sc_hal;
     5298    struct iwn_ops *ops = &sc->ops;
    50345299    struct iwn_node *wn = (void *)ni;
    50355300    struct iwn_node_info node;
    50365301    int error;
    iwn_ampdu_tx_start(struct ieee80211com *ic, struct ieee80211_node *ni,  
    50425307    node.control = IWN_NODE_UPDATE;
    50435308    node.flags = IWN_FLAG_SET_DISABLE_TID;
    50445309    node.disable_tid = htole16(wn->disable_tid);
    5045     error = hal->add_node(sc, &node, 1);
     5310    error = ops->add_node(sc, &node, 1);
    50465311    if (error != 0)
    50475312        return error;
    50485313
    50495314    if ((error = iwn_nic_lock(sc)) != 0)
    50505315        return error;
    5051     hal->ampdu_tx_start(sc, ni, tid, ba->ba_winstart);
     5316    ops->ampdu_tx_start(sc, ni, tid, ba->ba_winstart);
    50525317    iwn_nic_unlock(sc);
    50535318    return 0;
    50545319}
    iwn_ampdu_tx_stop(struct ieee80211com *ic, struct ieee80211_node *ni,  
    50595324{
    50605325    struct ieee80211_tx_ba *ba = &ni->ni_tx_ba[tid];
    50615326    struct iwn_softc *sc = ic->ic_softc;
    5062     int error;
     5327    struct iwn_ops *ops = &sc->ops;
    50635328
    5064     error = iwn_nic_lock(sc);
    5065     if (error != 0)
     5329    if (iwn_nic_lock(sc) != 0)
    50665330        return;
    5067     sc->sc_hal->ampdu_tx_stop(sc, tid, ba->ba_winstart);
     5331    ops->ampdu_tx_stop(sc, tid, ba->ba_winstart);
    50685332    iwn_nic_unlock(sc);
    50695333}
    50705334
    iwn5000_ampdu_tx_stop(struct iwn_softc *sc, uint8_t tid, uint16_t ssn)  
    51905454#endif
    51915455
    51925456/*
    5193  * Send calibration results to the runtime firmware.  These results were
    5194  * obtained on first boot from the initialization firmware, or by reading
    5195  * the EEPROM for crystal calibration.
    5196  */
    5197 static int
    5198 iwn5000_send_calib_results(struct iwn_softc *sc)
    5199 {
    5200     struct iwn_calib_info *calib_result;
    5201     int idx, error;
    5202 
    5203     for (idx = 0; idx < IWN_CALIB_NUM; idx++) {
    5204         calib_result = &sc->calib_results[idx];
    5205 
    5206         /* No support for this type of calibration. */
    5207         if ((sc->calib_init & (1 << idx)) == 0)
    5208             continue;
    5209 
    5210         /* No calibration result available. */
    5211         if (calib_result->buf == NULL)
    5212             continue;
    5213 
    5214         DPRINTF(sc, IWN_DEBUG_CALIBRATE,
    5215             "%s: send calibration result idx=%d, len=%d\n",
    5216             __func__, idx, calib_result->len);
    5217 
    5218         error = iwn_cmd(sc, IWN_CMD_PHY_CALIB, calib_result->buf,
    5219             calib_result->len, 0);
    5220         if (error != 0) {
    5221             device_printf(sc->sc_dev,
    5222                 "%s: could not send calibration result "
    5223                 "idx=%d, error=%d\n",
    5224                 __func__, idx, error);
    5225             return error;
    5226         }
    5227     }
    5228     return 0;
    5229 }
    5230 
    5231 /*
    5232  * Save calibration result at the given index.  The index determines
    5233  * in which order the results are sent to the runtime firmware.
     5457 * Query calibration tables from the initialization firmware.  We do this
     5458 * only once at first boot.  Called from a process context.
    52345459 */
    52355460static int
    5236 iwn5000_save_calib_result(struct iwn_softc *sc, struct iwn_phy_calib *calib,
    5237     int len, int idx)
     5461iwn5000_query_calibration(struct iwn_softc *sc)
    52385462{
    5239     struct iwn_calib_info *calib_result = &sc->calib_results[idx];
    5240 
    5241     DPRINTF(sc, IWN_DEBUG_CALIBRATE,
    5242         "%s: saving calibration result code=%d, idx=%d, len=%d\n",
    5243         __func__, calib->code, idx, len);
    5244 
    5245     if (calib_result->buf != NULL)
    5246         free(calib_result->buf, M_DEVBUF);
    5247 
    5248     calib_result->buf = malloc(len, M_DEVBUF, M_NOWAIT);
    5249     if (calib_result->buf == NULL) {
    5250         device_printf(sc->sc_dev,
    5251             "%s: not enough memory for calibration result "
    5252             "code=%d, len=%d\n", __func__, calib->code, len);
    5253         return ENOMEM;
    5254     }
    5255 
    5256     calib_result->len = len;
    5257     memcpy(calib_result->buf, calib, len);
    5258     return 0;
    5259 }
    5260 
    5261 static void
    5262 iwn5000_free_calib_results(struct iwn_softc *sc)
    5263 {
    5264     struct iwn_calib_info *calib_result;
    5265     int idx;
    5266 
    5267     for (idx = 0; idx < IWN_CALIB_NUM; idx++) {
    5268         calib_result = &sc->calib_results[idx];
    5269 
    5270         if (calib_result->buf != NULL)
    5271             free(calib_result->buf, M_DEVBUF);
    5272 
    5273         calib_result->buf = NULL;
    5274         calib_result->len = 0;
    5275     }
    5276 }
    5277 
    5278 /*
    5279  * Obtain the crystal calibration result from the EEPROM.
    5280  */
    5281 static int
    5282 iwn5000_chrystal_calib(struct iwn_softc *sc)
    5283 {
    5284     struct iwn5000_phy_calib_crystal cmd;
    5285     uint32_t base, crystal;
    5286     uint16_t val;
    5287 
    5288     /* Read crystal calibration. */
    5289     iwn_read_prom_data(sc, IWN5000_EEPROM_CAL, &val, 2);
    5290     base = le16toh(val);
    5291     iwn_read_prom_data(sc, base + IWN5000_EEPROM_CRYSTAL, &crystal,
    5292         sizeof(uint32_t));
    5293     DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: crystal calibration=0x%08x\n",
    5294         __func__, le32toh(crystal));
    5295 
    5296     memset(&cmd, 0, sizeof cmd);
    5297     cmd.code = IWN5000_PHY_CALIB_CRYSTAL;
    5298     cmd.ngroups = 1;
    5299     cmd.isvalid = 1;
    5300     cmd.cap_pin[0] = le32toh(crystal) & 0xff;
    5301     cmd.cap_pin[1] = (le32toh(crystal) >> 16) & 0xff;
    5302 
    5303     return iwn5000_save_calib_result(sc, (struct iwn_phy_calib *)&cmd,
    5304         sizeof cmd, IWN_CALIB_IDX_XTAL);
    5305 }
    5306 
    5307 /*
    5308  * Query calibration results from the initialization firmware.  We do this
    5309  * only once at first boot.
    5310  */
    5311 static int
    5312 iwn5000_send_calib_query(struct iwn_softc *sc, uint32_t cfg)
    5313 {
    5314 #define CALIB_INIT_CFG  0xffffffff;
    53155463    struct iwn5000_calib_config cmd;
    53165464    int error;
    53175465
    53185466    memset(&cmd, 0, sizeof cmd);
    5319     cmd.ucode.once.enable = CALIB_INIT_CFG;
    5320     if (cfg == 0) {
    5321         cmd.ucode.once.start  = CALIB_INIT_CFG;
    5322         cmd.ucode.once.send   = CALIB_INIT_CFG;
    5323         cmd.ucode.flags       = CALIB_INIT_CFG;
    5324     } else
    5325         cmd.ucode.once.start  = cfg;
    5326 
    5327     DPRINTF(sc, IWN_DEBUG_CALIBRATE,
    5328         "%s: query calibration results, cfg %x\n", __func__, cfg);
    5329 
     5467    cmd.ucode.once.enable = 0xffffffff;
     5468    cmd.ucode.once.start  = 0xffffffff;
     5469    cmd.ucode.once.send   = 0xffffffff;
     5470    cmd.ucode.flags       = 0xffffffff;
     5471    DPRINTF(sc, IWN_DEBUG_CALIBRATE, "%s: sending calibration query\n",
     5472        __func__);
    53305473    error = iwn_cmd(sc, IWN5000_CMD_CALIB_CONFIG, &cmd, sizeof cmd, 0);
    53315474    if (error != 0)
    53325475        return error;
    53335476
    53345477    /* Wait at most two seconds for calibration to complete. */
    53355478    if (!(sc->sc_flags & IWN_FLAG_CALIB_DONE))
    5336         error = msleep(sc, &sc->sc_mtx, PCATCH, "iwninit", 2 * hz);
    5337 
     5479        error = msleep(sc, &sc->sc_mtx, PCATCH, "iwncal", 2 * hz);
    53385480    return error;
    5339 #undef  CALIB_INIT_CFG
    53405481}
    53415482
    53425483/*
    5343  * Process a CALIBRATION_RESULT notification sent by the initialization
    5344  * firmware on response to a CMD_CALIB_CONFIG command.
     5484 * Send calibration results to the runtime firmware.  These results were
     5485 * obtained on first boot from the initialization firmware.
    53455486 */
    53465487static int
    5347 iwn5000_rx_calib_result(struct iwn_softc *sc, struct iwn_rx_desc *desc,
    5348     struct iwn_rx_data *data)
     5488iwn5000_send_calibration(struct iwn_softc *sc)
    53495489{
    5350 #define FRAME_SIZE_MASK     0x3fff
    5351     struct iwn_phy_calib *calib = (struct iwn_phy_calib *)(desc + 1);
    5352     int len, idx;
    5353 
    5354     bus_dmamap_sync(sc->rxq.data_dmat, data->map, BUS_DMASYNC_POSTREAD);
    5355     len = (le32toh(desc->len) & FRAME_SIZE_MASK);
    5356 
    5357     /* Remove length field itself. */
    5358     len -= 4;
     5490    int idx, error;
    53595491
    5360     /*
    5361      * Determine the order in which the results will be send to the
    5362      * runtime firmware.
    5363      */
    5364     switch (calib->code) {
    5365     case IWN5000_PHY_CALIB_DC:
    5366         idx = IWN_CALIB_IDX_DC;
    5367         break;
    5368     case IWN5000_PHY_CALIB_LO:
    5369         idx = IWN_CALIB_IDX_LO;
    5370         break;
    5371     case IWN5000_PHY_CALIB_TX_IQ:
    5372         idx = IWN_CALIB_IDX_TX_IQ;
    5373         break;
    5374     case IWN5000_PHY_CALIB_TX_IQ_PERIODIC:
    5375         idx = IWN_CALIB_IDX_TX_IQ_PERIODIC;
    5376         break;
    5377     case IWN5000_PHY_CALIB_BASE_BAND:
    5378         idx = IWN_CALIB_IDX_BASE_BAND;
    5379         break;
    5380     default:
     5492    for (idx = 0; idx < 5; idx++) {
     5493        if (sc->calibcmd[idx].buf == NULL)
     5494            continue;   /* No results available. */
    53815495        DPRINTF(sc, IWN_DEBUG_CALIBRATE,
    5382            "%s: unknown calibration code=%d\n", __func__, calib->code);
    5383         return EINVAL;
     5496            "send calibration result idx=%d len=%d\n", idx,
     5497            sc->calibcmd[idx].len);
     5498        error = iwn_cmd(sc, IWN_CMD_PHY_CALIB, sc->calibcmd[idx].buf,
     5499            sc->calibcmd[idx].len, 0);
     5500        if (error != 0) {
     5501            device_printf(sc->sc_dev,
     5502                "%s: could not send calibration result, error %d\n",
     5503                __func__, error);
     5504            return error;
     5505        }
    53845506    }
    5385     return iwn5000_save_calib_result(sc, calib, len, idx);
    5386 #undef  FRAME_SIZE_MASK
     5507    return 0;
    53875508}
    53885509
    53895510static int
    iwn5000_send_wimax_coex(struct iwn_softc *sc)  
    54135534    return iwn_cmd(sc, IWN5000_CMD_WIMAX_COEX, &wimax, sizeof wimax, 0);
    54145535}
    54155536
     5537static int
     5538iwn5000_crystal_calib(struct iwn_softc *sc)
     5539{
     5540    struct iwn5000_phy_calib_crystal cmd;
     5541
     5542    memset(&cmd, 0, sizeof cmd);
     5543    cmd.code = IWN5000_PHY_CALIB_CRYSTAL;
     5544    cmd.ngroups = 1;
     5545    cmd.isvalid = 1;
     5546    cmd.cap_pin[0] = le32toh(sc->eeprom_crystal) & 0xff;
     5547    cmd.cap_pin[1] = (le32toh(sc->eeprom_crystal) >> 16) & 0xff;
     5548    DPRINTF(sc, IWN_DEBUG_CALIBRATE, "sending crystal calibration %d, %d\n",
     5549        cmd.cap_pin[0], cmd.cap_pin[1]);
     5550    return iwn_cmd(sc, IWN_CMD_PHY_CALIB, &cmd, sizeof cmd, 0);
     5551}
     5552
     5553static int
     5554iwn5000_temp_offset_calib(struct iwn_softc *sc)
     5555{
     5556    struct iwn5000_phy_calib_temp_offset cmd;
     5557
     5558    memset(&cmd, 0, sizeof cmd);
     5559    cmd.code = IWN5000_PHY_CALIB_TEMP_OFFSET;
     5560    cmd.ngroups = 1;
     5561    cmd.isvalid = 1;
     5562    if (sc->eeprom_temp != 0)
     5563        cmd.offset = htole16(sc->eeprom_temp);
     5564    else
     5565        cmd.offset = htole16(IWN_DEFAULT_TEMP_OFFSET);
     5566    DPRINTF(sc, IWN_DEBUG_CALIBRATE, "setting radio sensor offset to %d\n",
     5567        le16toh(cmd.offset));
     5568    return iwn_cmd(sc, IWN_CMD_PHY_CALIB, &cmd, sizeof cmd, 0);
     5569}
     5570
    54165571/*
    54175572 * This function is called after the runtime firmware notifies us of its
    5418  * readiness (called in a process context.)
     5573 * readiness (called in a process context).
    54195574 */
    54205575static int
    54215576iwn4965_post_alive(struct iwn_softc *sc)
    iwn4965_post_alive(struct iwn_softc *sc)  
    54305585    iwn_mem_set_region_4(sc, sc->sched_base + IWN4965_SCHED_CTX_OFF, 0,
    54315586        IWN4965_SCHED_CTX_LEN / sizeof (uint32_t));
    54325587
    5433     /* Set physical address of TX scheduler rings (1KB aligned.) */
     5588    /* Set physical address of TX scheduler rings (1KB aligned). */
    54345589    iwn_prph_write(sc, IWN4965_SCHED_DRAM_ADDR, sc->sched_dma.paddr >> 10);
    54355590
    54365591    IWN_SETBITS(sc, IWN_FH_TX_CHICKEN, IWN_FH_TX_CHICKEN_SCHED_RETRY);
    iwn4965_post_alive(struct iwn_softc *sc)  
    54685623
    54695624/*
    54705625 * This function is called after the initialization or runtime firmware
    5471  * notifies us of its readiness (called in a process context.)
     5626 * notifies us of its readiness (called in a process context).
    54725627 */
    54735628static int
    54745629iwn5000_post_alive(struct iwn_softc *sc)
    iwn5000_post_alive(struct iwn_softc *sc)  
    54785633    /* Switch to using ICT interrupt mode. */
    54795634    iwn5000_ict_reset(sc);
    54805635
    5481     error = iwn_nic_lock(sc);
    5482     if (error != 0)
     5636    if ((error = iwn_nic_lock(sc)) != 0)
    54835637        return error;
    54845638
    54855639    /* Clear TX scheduler state in SRAM. */
    iwn5000_post_alive(struct iwn_softc *sc)  
    54875641    iwn_mem_set_region_4(sc, sc->sched_base + IWN5000_SCHED_CTX_OFF, 0,
    54885642        IWN5000_SCHED_CTX_LEN / sizeof (uint32_t));
    54895643
    5490     /* Set physical address of TX scheduler rings (1KB aligned.) */
     5644    /* Set physical address of TX scheduler rings (1KB aligned). */
    54915645    iwn_prph_write(sc, IWN5000_SCHED_DRAM_ADDR, sc->sched_dma.paddr >> 10);
    54925646
    54935647    IWN_SETBITS(sc, IWN_FH_TX_CHICKEN, IWN_FH_TX_CHICKEN_SCHED_RETRY);
    iwn5000_post_alive(struct iwn_softc *sc)  
    55295683            __func__, error);
    55305684        return error;
    55315685    }
    5532 
    5533     if (!(sc->sc_flags & IWN_FLAG_CALIB_DONE)) {
    5534         /*
    5535          * Start calibration by setting and sending the chrystal
    5536          * calibration first, this must be done before we are able
    5537          * to query the other calibration results.
    5538          */
    5539         error = iwn5000_chrystal_calib(sc);
     5686    if (sc->hw_type != IWN_HW_REV_TYPE_5150) {
     5687        /* Perform crystal calibration. */
     5688        error = iwn5000_crystal_calib(sc);
    55405689        if (error != 0) {
    55415690            device_printf(sc->sc_dev,
    5542                 "%s: could not set chrystal calibration, "
    5543                 "error=%d\n", __func__, error);
    5544             return error;
    5545         }
    5546         error = iwn5000_send_calib_results(sc);
    5547         if (error != 0) {
    5548             device_printf(sc->sc_dev,
    5549                 "%s: could not send chrystal calibration, "
    5550                 "error=%d\n", __func__, error);
     5691                "%s: crystal calibration failed, error %d\n",
     5692                __func__, error);
    55515693            return error;
    55525694        }
    5553 
    5554         /*
    5555          * Query other calibration results from the initialization
    5556          * firmware.
    5557          */
    5558         error = iwn5000_send_calib_query(sc, 0);
    5559         if (error != 0) {
     5695    }
     5696    if (!(sc->sc_flags & IWN_FLAG_CALIB_DONE)) {
     5697        /* Query calibration from the initialization firmware. */
     5698        if ((error = iwn5000_query_calibration(sc)) != 0) {
    55605699            device_printf(sc->sc_dev,
    5561                 "%s: could not query calibration, error=%d\n",
     5700                "%s: could not query calibration, error %d\n",
    55625701                __func__, error);
    55635702            return error;
    55645703        }
    5565 
    55665704        /*
    55675705         * We have the calibration results now, reboot with the
    55685706         * runtime firmware (call ourselves recursively!)
    iwn5000_post_alive(struct iwn_softc *sc)  
    55705708        iwn_hw_stop(sc);
    55715709        error = iwn_hw_init(sc);
    55725710    } else {
    5573         /*
    5574          * Send calibration results obtained from the initialization
    5575          * firmware to the runtime firmware.
    5576          */
    5577         error = iwn5000_send_calib_results(sc);
    5578 
    5579         /*
    5580          * Tell the runtime firmware to do certain calibration types.
    5581          */
    5582         if (sc->calib_runtime != 0) {
    5583             error = iwn5000_send_calib_query(sc, sc->calib_runtime);
    5584             if (error != 0) {
    5585                 device_printf(sc->sc_dev,
    5586                     "%s: could not send query calibration, "
    5587                     "error=%d, cfg=%x\n", __func__, error,
    5588                     sc->calib_runtime);
    5589             }
    5590         }
     5711        /* Send calibration results to runtime firmware. */
     5712        error = iwn5000_send_calibration(sc);
    55915713    }
    55925714    return error;
    55935715}
    55945716
    55955717/*
    55965718 * The firmware boot code is small and is intended to be copied directly into
    5597  * the NIC internal memory (no DMA transfer.)
     5719 * the NIC internal memory (no DMA transfer).
    55985720 */
    55995721static int
    56005722iwn4965_load_bootcode(struct iwn_softc *sc, const uint8_t *ucode, int size)
    iwn4965_load_bootcode(struct iwn_softc *sc, const uint8_t *ucode, int size)  
    56035725
    56045726    size /= sizeof (uint32_t);
    56055727
    5606     error = iwn_nic_lock(sc);
    5607     if (error != 0)
     5728    if ((error = iwn_nic_lock(sc)) != 0)
    56085729        return error;
    56095730
    56105731    /* Copy microcode image into NIC memory. */
    iwn4965_load_firmware(struct iwn_softc *sc)  
    56485769
    56495770    /* Copy initialization sections into pre-allocated DMA-safe memory. */
    56505771    memcpy(dma->vaddr, fw->init.data, fw->init.datasz);
    5651     bus_dmamap_sync(sc->fw_dma.tag, dma->map, BUS_DMASYNC_PREWRITE);
     5772    bus_dmamap_sync(dma->tag, dma->map, BUS_DMASYNC_PREWRITE);
    56525773    memcpy(dma->vaddr + IWN4965_FW_DATA_MAXSZ,
    56535774        fw->init.text, fw->init.textsz);
    5654     bus_dmamap_sync(sc->fw_dma.tag, dma->map, BUS_DMASYNC_PREWRITE);
     5775    bus_dmamap_sync(dma->tag, dma->map, BUS_DMASYNC_PREWRITE);
    56555776
    56565777    /* Tell adapter where to find initialization sections. */
    5657     error = iwn_nic_lock(sc);
    5658     if (error != 0)
     5778    if ((error = iwn_nic_lock(sc)) != 0)
    56595779        return error;
    56605780    iwn_prph_write(sc, IWN_BSM_DRAM_DATA_ADDR, dma->paddr >> 4);
    56615781    iwn_prph_write(sc, IWN_BSM_DRAM_DATA_SIZE, fw->init.datasz);
    iwn4965_load_firmware(struct iwn_softc *sc)  
    56755795    IWN_WRITE(sc, IWN_RESET, 0);
    56765796
    56775797    /* Wait at most one second for first alive notification. */
    5678     error = msleep(sc, &sc->sc_mtx, PCATCH, "iwninit", hz);
    5679     if (error) {
     5798    if ((error = msleep(sc, &sc->sc_mtx, PCATCH, "iwninit", hz)) != 0) {
    56805799        device_printf(sc->sc_dev,
    56815800            "%s: timeout waiting for adapter to initialize, error %d\n",
    56825801            __func__, error);
    iwn4965_load_firmware(struct iwn_softc *sc)  
    56895808
    56905809    /* Copy runtime sections into pre-allocated DMA-safe memory. */
    56915810    memcpy(dma->vaddr, fw->main.data, fw->main.datasz);
    5692     bus_dmamap_sync(sc->fw_dma.tag, dma->map, BUS_DMASYNC_PREWRITE);
     5811    bus_dmamap_sync(dma->tag, dma->map, BUS_DMASYNC_PREWRITE);
    56935812    memcpy(dma->vaddr + IWN4965_FW_DATA_MAXSZ,
    56945813        fw->main.text, fw->main.textsz);
    5695     bus_dmamap_sync(sc->fw_dma.tag, dma->map, BUS_DMASYNC_PREWRITE);
     5814    bus_dmamap_sync(dma->tag, dma->map, BUS_DMASYNC_PREWRITE);
    56965815
    56975816    /* Tell adapter where to find runtime sections. */
    5698     error = iwn_nic_lock(sc);
    5699     if (error != 0)
     5817    if ((error = iwn_nic_lock(sc)) != 0)
    57005818        return error;
    5701 
    57025819    iwn_prph_write(sc, IWN_BSM_DRAM_DATA_ADDR, dma->paddr >> 4);
    57035820    iwn_prph_write(sc, IWN_BSM_DRAM_DATA_SIZE, fw->main.datasz);
    57045821    iwn_prph_write(sc, IWN_BSM_DRAM_TEXT_ADDR,
    iwn5000_load_firmware_section(struct iwn_softc *sc, uint32_t dst,  
    57195836
    57205837    /* Copy firmware section into pre-allocated DMA-safe memory. */
    57215838    memcpy(dma->vaddr, section, size);
    5722     bus_dmamap_sync(sc->fw_dma.tag, dma->map, BUS_DMASYNC_PREWRITE);
     5839    bus_dmamap_sync(dma->tag, dma->map, BUS_DMASYNC_PREWRITE);
    57235840
    5724     error = iwn_nic_lock(sc);
    5725     if (error != 0)
     5841    if ((error = iwn_nic_lock(sc)) != 0)
    57265842        return error;
    57275843
    57285844    IWN_WRITE(sc, IWN_FH_TX_CONFIG(IWN_SRVC_DMACHNL),
    iwn5000_load_firmware_section(struct iwn_softc *sc, uint32_t dst,  
    57455861    iwn_nic_unlock(sc);
    57465862
    57475863    /* Wait at most five seconds for FH DMA transfer to complete. */
    5748     return msleep(sc, &sc->sc_mtx, PCATCH, "iwninit", hz);
     5864    return msleep(sc, &sc->sc_mtx, PCATCH, "iwninit", 5 * hz);
    57495865}
    57505866
    57515867static int
    iwn_read_firmware_leg(struct iwn_softc *sc, struct iwn_fw_info *fw)  
    57905906    size_t hdrlen = 24;
    57915907    uint32_t rev;
    57925908
    5793     ptr = (const uint32_t *)sc->fw_fp->data;
     5909    ptr = (const uint32_t *)fw->data;
    57945910    rev = le32toh(*ptr++);
    57955911
    57965912    /* Check firmware API version. */
    iwn_read_firmware_leg(struct iwn_softc *sc, struct iwn_fw_info *fw)  
    58055921        ptr++;
    58065922    }
    58075923    if (fw->size < hdrlen) {
    5808         device_printf(sc->sc_dev,
    5809             "%s: firmware file too short: %zu bytes\n",
     5924        device_printf(sc->sc_dev, "%s: firmware too short: %zu bytes\n",
    58105925            __func__, fw->size);
    58115926        return EINVAL;
    58125927    }
    iwn_read_firmware_leg(struct iwn_softc *sc, struct iwn_fw_info *fw)  
    58195934    /* Check that all firmware sections fit. */
    58205935    if (fw->size < hdrlen + fw->main.textsz + fw->main.datasz +
    58215936        fw->init.textsz + fw->init.datasz + fw->boot.textsz) {
    5822         device_printf(sc->sc_dev,
    5823             "%s: firmware file too short: %zu bytes\n",
     5937        device_printf(sc->sc_dev, "%s: firmware too short: %zu bytes\n",
    58245938            __func__, fw->size);
    58255939        return EINVAL;
    58265940    }
    iwn_read_firmware_leg(struct iwn_softc *sc, struct iwn_fw_info *fw)  
    58315945    fw->init.text = fw->main.data + fw->main.datasz;
    58325946    fw->init.data = fw->init.text + fw->init.textsz;
    58335947    fw->boot.text = fw->init.data + fw->init.datasz;
    5834 
    58355948    return 0;
    58365949}
    58375950
    58385951/*
    58395952 * Extract text and data sections from a TLV firmware image.
    58405953 */
    5841 int
     5954static int
    58425955iwn_read_firmware_tlv(struct iwn_softc *sc, struct iwn_fw_info *fw,
    58435956    uint16_t alt)
    58445957{
    iwn_read_firmware_tlv(struct iwn_softc *sc, struct iwn_fw_info *fw,  
    58465959    const struct iwn_fw_tlv *tlv;
    58475960    const uint8_t *ptr, *end;
    58485961    uint64_t altmask;
    5849     uint32_t len;
     5962    uint32_t len, tmp;
    58505963
    58515964    if (fw->size < sizeof (*hdr)) {
    5852         device_printf(sc->sc_dev,
    5853             "%s: firmware file too short: %zu bytes\n",
     5965        device_printf(sc->sc_dev, "%s: firmware too short: %zu bytes\n",
    58545966            __func__, fw->size);
    58555967        return EINVAL;
    58565968    }
    58575969    hdr = (const struct iwn_fw_tlv_hdr *)fw->data;
    58585970    if (hdr->signature != htole32(IWN_FW_SIGNATURE)) {
    5859         device_printf(sc->sc_dev,
    5860             "%s: bad firmware file signature 0x%08x\n",
     5971        device_printf(sc->sc_dev, "%s: bad firmware signature 0x%08x\n",
    58615972            __func__, le32toh(hdr->signature));
    58625973        return EINVAL;
    58635974    }
     5975    DPRINTF(sc, IWN_DEBUG_RESET, "FW: \"%.64s\", build 0x%x\n", hdr->descr,
     5976        le32toh(hdr->build));
    58645977
    58655978    /*
    58665979     * Select the closest supported alternative that is less than
    iwn_read_firmware_tlv(struct iwn_softc *sc, struct iwn_fw_info *fw,  
    58695982    altmask = le64toh(hdr->altmask);
    58705983    while (alt > 0 && !(altmask & (1ULL << alt)))
    58715984        alt--;  /* Downgrade. */
     5985    DPRINTF(sc, IWN_DEBUG_RESET, "using alternative %d\n", alt);
    58725986
    58735987    ptr = (const uint8_t *)(hdr + 1);
    58745988    end = (const uint8_t *)(fw->data + fw->size);
    iwn_read_firmware_tlv(struct iwn_softc *sc, struct iwn_fw_info *fw,  
    58815995        ptr += sizeof (*tlv);
    58825996        if (ptr + len > end) {
    58835997            device_printf(sc->sc_dev,
    5884                 "%s: firmware file too short: %zu bytes\n",
    5885                 __func__, fw->size);
     5998                "%s: firmware too short: %zu bytes\n", __func__,
     5999                fw->size);
    58866000            return EINVAL;
    58876001        }
    58886002        /* Skip other alternatives. */
    iwn_read_firmware_tlv(struct iwn_softc *sc, struct iwn_fw_info *fw,  
    59106024            fw->boot.text = ptr;
    59116025            fw->boot.textsz = len;
    59126026            break;
     6027        case IWN_FW_TLV_ENH_SENS:
     6028            if (!len)
     6029                sc->sc_flags |= IWN_FLAG_ENH_SENS;
     6030            break;
     6031        case IWN_FW_TLV_PHY_CALIB:
     6032            tmp = htole32(*ptr);
     6033            if (tmp < 253) {
     6034                sc->reset_noise_gain = tmp;
     6035                sc->noise_gain = tmp + 1;
     6036            }
     6037            break;
    59136038        default:
    59146039            DPRINTF(sc, IWN_DEBUG_RESET,
    5915                 "%s: TLV type %d not handled\n",
    5916                 __func__, le16toh(tlv->type));
     6040                "TLV type %d not handled\n", le16toh(tlv->type));
    59176041            break;
    59186042        }
    5919 next:       /* TLV fields are 32-bit aligned. */
     6043 next:      /* TLV fields are 32-bit aligned. */
    59206044        ptr += (len + 3) & ~3;
    59216045    }
    59226046    return 0;
    next: /* TLV fields are 32-bit aligned. */  
    59256049static int
    59266050iwn_read_firmware(struct iwn_softc *sc)
    59276051{
    5928     const struct iwn_hal *hal = sc->sc_hal;
    59296052    struct iwn_fw_info *fw = &sc->fw;
    59306053    int error;
    59316054
    iwn_read_firmware(struct iwn_softc *sc)  
    59366059    /* Read firmware image from filesystem. */
    59376060    sc->fw_fp = firmware_get(sc->fwname);
    59386061    if (sc->fw_fp == NULL) {
    5939         device_printf(sc->sc_dev,
    5940             "%s: could not load firmare image \"%s\"\n", __func__,
    5941             sc->fwname);
     6062        device_printf(sc->sc_dev, "%s: could not read firmware %s\n",
     6063            __func__, sc->fwname);
    59426064        IWN_LOCK(sc);
    59436065        return EINVAL;
    59446066    }
    iwn_read_firmware(struct iwn_softc *sc)  
    59476069    fw->size = sc->fw_fp->datasize;
    59486070    fw->data = (const uint8_t *)sc->fw_fp->data;
    59496071    if (fw->size < sizeof (uint32_t)) {
    5950         device_printf(sc->sc_dev,
    5951             "%s: firmware file too short: %zu bytes\n",
     6072        device_printf(sc->sc_dev, "%s: firmware too short: %zu bytes\n",
    59526073            __func__, fw->size);
     6074        firmware_put(sc->fw_fp, FIRMWARE_UNLOAD);
     6075        sc->fw_fp = NULL;
    59536076        return EINVAL;
    59546077    }
    59556078
    iwn_read_firmware(struct iwn_softc *sc)  
    59606083        error = iwn_read_firmware_tlv(sc, fw, 1);
    59616084    if (error != 0) {
    59626085        device_printf(sc->sc_dev,
    5963             "%s: could not read firmware sections\n", __func__);
     6086            "%s: could not read firmware sections, error %d\n",
     6087            __func__, error);
     6088        firmware_put(sc->fw_fp, FIRMWARE_UNLOAD);
     6089        sc->fw_fp = NULL;
    59646090        return error;
    59656091    }
    59666092
    59676093    /* Make sure text and data sections fit in hardware memory. */
    5968     if (fw->main.textsz > hal->fw_text_maxsz ||
    5969         fw->main.datasz > hal->fw_data_maxsz ||
    5970         fw->init.textsz > hal->fw_text_maxsz ||
    5971         fw->init.datasz > hal->fw_data_maxsz ||
     6094    if (fw->main.textsz > sc->fw_text_maxsz ||
     6095        fw->main.datasz > sc->fw_data_maxsz ||
     6096        fw->init.textsz > sc->fw_text_maxsz ||
     6097        fw->init.datasz > sc->fw_data_maxsz ||
    59726098        fw->boot.textsz > IWN_FW_BOOT_TEXT_MAXSZ ||
    59736099        (fw->boot.textsz & 3) != 0) {
    5974         device_printf(sc->sc_dev,
    5975             "%s: firmware sections too large\n", __func__);
     6100        device_printf(sc->sc_dev, "%s: firmware sections too large\n",
     6101            __func__);
     6102        firmware_put(sc->fw_fp, FIRMWARE_UNLOAD);
     6103        sc->fw_fp = NULL;
    59766104        return EINVAL;
    59776105    }
    59786106
    iwn_clock_wait(struct iwn_softc *sc)  
    60026130static int
    60036131iwn_apm_init(struct iwn_softc *sc)
    60046132{
    6005     uint32_t tmp;
     6133    uint32_t reg;
    60066134    int error;
    60076135
    6008     /* Disable L0s exit timer (NMI bug workaround.) */
     6136    /* Disable L0s exit timer (NMI bug workaround). */
    60096137    IWN_SETBITS(sc, IWN_GIO_CHICKEN, IWN_GIO_CHICKEN_DIS_L0S_TIMER);
    6010     /* Don't wait for ICH L0s (ICH bug workaround.) */
     6138    /* Don't wait for ICH L0s (ICH bug workaround). */
    60116139    IWN_SETBITS(sc, IWN_GIO_CHICKEN, IWN_GIO_CHICKEN_L1A_NO_L0S_RX);
    60126140
    6013     /* Set FH wait threshold to max (HW bug under stress workaround.) */
     6141    /* Set FH wait threshold to max (HW bug under stress workaround). */
    60146142    IWN_SETBITS(sc, IWN_DBG_HPET_MEM, 0xffff0000);
    60156143
    60166144    /* Enable HAP INTA to move adapter from L1a to L0s. */
    60176145    IWN_SETBITS(sc, IWN_HW_IF_CONFIG, IWN_HW_IF_CONFIG_HAP_WAKE_L1A);
    60186146
    60196147    /* Retrieve PCIe Active State Power Management (ASPM). */
    6020     tmp = pci_read_config(sc->sc_dev, sc->sc_cap_off + 0x10, 1);
     6148    reg = pci_read_config(sc->sc_dev, sc->sc_cap_off + 0x10, 1);
    60216149    /* Workaround for HW instability in PCIe L0->L0s->L1 transition. */
    6022     if (tmp & 0x02) /* L1 Entry enabled. */
     6150    if (reg & 0x02) /* L1 Entry enabled. */
    60236151        IWN_SETBITS(sc, IWN_GIO, IWN_GIO_L0S_ENA);
    60246152    else
    60256153        IWN_CLRBITS(sc, IWN_GIO, IWN_GIO_L0S_ENA);
    iwn_apm_init(struct iwn_softc *sc)  
    60296157        IWN_SETBITS(sc, IWN_ANA_PLL, IWN_ANA_PLL_INIT);
    60306158
    60316159    /* Wait for clock stabilization before accessing prph. */
    6032     error = iwn_clock_wait(sc);
    6033     if (error != 0)
     6160    if ((error = iwn_clock_wait(sc)) != 0)
    60346161        return error;
    60356162
    6036     error = iwn_nic_lock(sc);
    6037     if (error != 0)
     6163    if ((error = iwn_nic_lock(sc)) != 0)
    60386164        return error;
    6039 
    60406165    if (sc->hw_type == IWN_HW_REV_TYPE_4965) {
    6041         /* Enable DMA and BSM (Bootstrap State Machine.) */
     6166        /* Enable DMA and BSM (Bootstrap State Machine). */
    60426167        iwn_prph_write(sc, IWN_APMG_CLK_EN,
    60436168            IWN_APMG_CLK_CTRL_DMA_CLK_RQT |
    60446169            IWN_APMG_CLK_CTRL_BSM_CLK_RQT);
    iwn_apm_init(struct iwn_softc *sc)  
    60486173            IWN_APMG_CLK_CTRL_DMA_CLK_RQT);
    60496174    }
    60506175    DELAY(20);
    6051 
    60526176    /* Disable L1-Active. */
    60536177    iwn_prph_setbits(sc, IWN_APMG_PCI_STT, IWN_APMG_PCI_STT_L1A_DIS);
    60546178    iwn_nic_unlock(sc);
    iwn_apm_stop_master(struct iwn_softc *sc)  
    60686192            return;
    60696193        DELAY(10);
    60706194    }
    6071     device_printf(sc->sc_dev, "%s: timeout waiting for master\n",
    6072         __func__);
     6195    device_printf(sc->sc_dev, "%s: timeout waiting for master\n", __func__);
    60736196}
    60746197
    60756198static void
    iwn5000_nic_config(struct iwn_softc *sc)  
    61186241    IWN_SETBITS(sc, IWN_HW_IF_CONFIG,
    61196242        IWN_HW_IF_CONFIG_RADIO_SI | IWN_HW_IF_CONFIG_MAC_SI);
    61206243
    6121     error = iwn_nic_lock(sc);
    6122     if (error != 0)
     6244    if ((error = iwn_nic_lock(sc)) != 0)
    61236245        return error;
    61246246    iwn_prph_setbits(sc, IWN_APMG_PS, IWN_APMG_PS_EARLY_PWROFF_DIS);
    61256247
    iwn5000_nic_config(struct iwn_softc *sc)  
    61406262        /* Use internal power amplifier only. */
    61416263        IWN_WRITE(sc, IWN_GP_DRIVER, IWN_GP_DRIVER_RADIO_2X2_IPA);
    61426264    }
    6143     if (sc->hw_type == IWN_HW_REV_TYPE_6050 && sc->calib_ver >= 6) {
     6265    if ((sc->hw_type == IWN_HW_REV_TYPE_6050 ||
     6266         sc->hw_type == IWN_HW_REV_TYPE_6005) && sc->calib_ver >= 6) {
    61446267        /* Indicate that ROM calibration version is >=6. */
    61456268        IWN_SETBITS(sc, IWN_GP_DRIVER, IWN_GP_DRIVER_CALIB_VER6);
    61466269    }
     6270    if (sc->hw_type == IWN_HW_REV_TYPE_6005)
     6271        IWN_SETBITS(sc, IWN_GP_DRIVER, IWN_GP_DRIVER_6050_1X2);
    61476272    return 0;
    61486273}
    61496274
    iwn_hw_prepare(struct iwn_softc *sc)  
    61896314static int
    61906315iwn_hw_init(struct iwn_softc *sc)
    61916316{
    6192     const struct iwn_hal *hal = sc->sc_hal;
     6317    struct iwn_ops *ops = &sc->ops;
    61936318    int error, chnl, qid;
    61946319
    61956320    /* Clear pending interrupts. */
    61966321    IWN_WRITE(sc, IWN_INT, 0xffffffff);
    61976322
    6198     error = iwn_apm_init(sc);
    6199     if (error != 0) {
     6323    if ((error = iwn_apm_init(sc)) != 0) {
    62006324        device_printf(sc->sc_dev,
    6201             "%s: could not power ON adapter, error %d\n",
    6202             __func__, error);
     6325            "%s: could not power ON adapter, error %d\n", __func__,
     6326            error);
    62036327        return error;
    62046328    }
    62056329
    62066330    /* Select VMAIN power source. */
    6207     error = iwn_nic_lock(sc);
    6208     if (error != 0)
     6331    if ((error = iwn_nic_lock(sc)) != 0)
    62096332        return error;
    62106333    iwn_prph_clrbits(sc, IWN_APMG_PS, IWN_APMG_PS_PWR_SRC_MASK);
    62116334    iwn_nic_unlock(sc);
    62126335
    62136336    /* Perform adapter-specific initialization. */
    6214     error = hal->nic_config(sc);
    6215     if (error != 0)
     6337    if ((error = ops->nic_config(sc)) != 0)
    62166338        return error;
    62176339
    62186340    /* Initialize RX ring. */
    6219     error = iwn_nic_lock(sc);
    6220     if (error != 0)
     6341    if ((error = iwn_nic_lock(sc)) != 0)
    62216342        return error;
    62226343    IWN_WRITE(sc, IWN_FH_RX_CONFIG, 0);
    62236344    IWN_WRITE(sc, IWN_FH_RX_WPTR, 0);
    6224     /* Set physical address of RX ring (256-byte aligned.) */
     6345    /* Set physical address of RX ring (256-byte aligned). */
    62256346    IWN_WRITE(sc, IWN_FH_RX_BASE, sc->rxq.desc_dma.paddr >> 8);
    6226     /* Set physical address of RX status (16-byte aligned.) */
     6347    /* Set physical address of RX status (16-byte aligned). */
    62276348    IWN_WRITE(sc, IWN_FH_STATUS_WPTR, sc->rxq.stat_dma.paddr >> 4);
    62286349    /* Enable RX. */
    62296350    IWN_WRITE(sc, IWN_FH_RX_CONFIG,
    iwn_hw_init(struct iwn_softc *sc)  
    62366357    iwn_nic_unlock(sc);
    62376358    IWN_WRITE(sc, IWN_FH_RX_WPTR, (IWN_RX_RING_COUNT - 1) & ~7);
    62386359
    6239     error = iwn_nic_lock(sc);
    6240     if (error != 0)
     6360    if ((error = iwn_nic_lock(sc)) != 0)
    62416361        return error;
    62426362
    62436363    /* Initialize TX scheduler. */
    6244     iwn_prph_write(sc, hal->sched_txfact_addr, 0);
     6364    iwn_prph_write(sc, sc->sched_txfact_addr, 0);
    62456365
    6246     /* Set physical address of "keep warm" page (16-byte aligned.) */
     6366    /* Set physical address of "keep warm" page (16-byte aligned). */
    62476367    IWN_WRITE(sc, IWN_FH_KW_ADDR, sc->kw_dma.paddr >> 4);
    62486368
    62496369    /* Initialize TX rings. */
    6250     for (qid = 0; qid < hal->ntxqs; qid++) {
     6370    for (qid = 0; qid < sc->ntxqs; qid++) {
    62516371        struct iwn_tx_ring *txq = &sc->txq[qid];
    62526372
    6253         /* Set physical address of TX ring (256-byte aligned.) */
     6373        /* Set physical address of TX ring (256-byte aligned). */
    62546374        IWN_WRITE(sc, IWN_FH_CBBC_QUEUE(qid),
    62556375            txq->desc_dma.paddr >> 8);
    62566376    }
    62576377    iwn_nic_unlock(sc);
    62586378
    62596379    /* Enable DMA channels. */
    6260     for (chnl = 0; chnl < hal->ndmachnls; chnl++) {
     6380    for (chnl = 0; chnl < sc->ndmachnls; chnl++) {
    62616381        IWN_WRITE(sc, IWN_FH_TX_CONFIG(chnl),
    62626382            IWN_FH_TX_CONFIG_DMA_ENA |
    62636383            IWN_FH_TX_CONFIG_DMA_CREDIT_ENA);
    iwn_hw_init(struct iwn_softc *sc)  
    62786398    IWN_WRITE(sc, IWN_UCODE_GP1_CLR, IWN_UCODE_GP1_RFKILL);
    62796399    IWN_WRITE(sc, IWN_UCODE_GP1_CLR, IWN_UCODE_GP1_RFKILL);
    62806400
    6281     error = hal->load_firmware(sc);
    6282     if (error != 0) {
     6401    /* Enable shadow registers. */
     6402    if (sc->hw_type >= IWN_HW_REV_TYPE_6000)
     6403        IWN_SETBITS(sc, IWN_SHADOW_REG_CTRL, 0x800fffff);
     6404
     6405    if ((error = ops->load_firmware(sc)) != 0) {
    62836406        device_printf(sc->sc_dev,
    6284             "%s: could not load firmware, error %d\n",
    6285             __func__, error);
     6407            "%s: could not load firmware, error %d\n", __func__,
     6408            error);
    62866409        return error;
    62876410    }
    62886411    /* Wait at most one second for firmware alive notification. */
    6289     error = msleep(sc, &sc->sc_mtx, PCATCH, "iwninit", hz);
    6290     if (error != 0) {
     6412    if ((error = msleep(sc, &sc->sc_mtx, PCATCH, "iwninit", hz)) != 0) {
    62916413        device_printf(sc->sc_dev,
    62926414            "%s: timeout waiting for adapter to initialize, error %d\n",
    62936415            __func__, error);
    62946416        return error;
    62956417    }
    62966418    /* Do post-firmware initialization. */
    6297     return hal->post_alive(sc);
     6419    return ops->post_alive(sc);
    62986420}
    62996421
    63006422static void
    63016423iwn_hw_stop(struct iwn_softc *sc)
    63026424{
    6303     const struct iwn_hal *hal = sc->sc_hal;
    6304     uint32_t tmp;
    63056425    int chnl, qid, ntries;
    63066426
    63076427    IWN_WRITE(sc, IWN_RESET, IWN_RESET_NEVO);
    iwn_hw_stop(struct iwn_softc *sc)  
    63166436    iwn_nic_unlock(sc);
    63176437
    63186438    /* Stop TX scheduler. */
    6319     iwn_prph_write(sc, hal->sched_txfact_addr, 0);
     6439    iwn_prph_write(sc, sc->sched_txfact_addr, 0);
    63206440
    63216441    /* Stop all DMA channels. */
    63226442    if (iwn_nic_lock(sc) == 0) {
    6323         for (chnl = 0; chnl < hal->ndmachnls; chnl++) {
     6443        for (chnl = 0; chnl < sc->ndmachnls; chnl++) {
    63246444            IWN_WRITE(sc, IWN_FH_TX_CONFIG(chnl), 0);
    63256445            for (ntries = 0; ntries < 200; ntries++) {
    6326                 tmp = IWN_READ(sc, IWN_FH_TX_STATUS);
    6327                 if ((tmp & IWN_FH_TX_STATUS_IDLE(chnl)) ==
     6446                if (IWN_READ(sc, IWN_FH_TX_STATUS) &
    63286447                    IWN_FH_TX_STATUS_IDLE(chnl))
    63296448                    break;
    63306449                DELAY(10);
    iwn_hw_stop(struct iwn_softc *sc)  
    63376456    iwn_reset_rx_ring(sc, &sc->rxq);
    63386457
    63396458    /* Reset all TX rings. */
    6340     for (qid = 0; qid < hal->ntxqs; qid++)
     6459    for (qid = 0; qid < sc->ntxqs; qid++)
    63416460        iwn_reset_tx_ring(sc, &sc->txq[qid]);
    63426461
    63436462    if (iwn_nic_lock(sc) == 0) {
    iwn_hw_stop(struct iwn_softc *sc)  
    63466465        iwn_nic_unlock(sc);
    63476466    }
    63486467    DELAY(5);
    6349 
    63506468    /* Power OFF adapter. */
    63516469    iwn_apm_stop(sc);
    63526470}
    63536471
    63546472static void
     6473iwn_radio_on(void *arg0, int pending)
     6474{
     6475    struct iwn_softc *sc = arg0;
     6476    struct ifnet *ifp = sc->sc_ifp;
     6477    struct ieee80211com *ic = ifp->if_l2com;
     6478    struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
     6479
     6480    if (vap != NULL) {
     6481        iwn_init(sc);
     6482        ieee80211_init(vap);
     6483    }
     6484}
     6485
     6486static void
     6487iwn_radio_off(void *arg0, int pending)
     6488{
     6489    struct iwn_softc *sc = arg0;
     6490    struct ifnet *ifp = sc->sc_ifp;
     6491    struct ieee80211com *ic = ifp->if_l2com;
     6492    struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
     6493
     6494    iwn_stop(sc);
     6495    if (vap != NULL)
     6496        ieee80211_stop(vap);
     6497
     6498    /* Enable interrupts to get RF toggle notification. */
     6499    IWN_LOCK(sc);
     6500    IWN_WRITE(sc, IWN_INT, 0xffffffff);
     6501    IWN_WRITE(sc, IWN_INT_MASK, sc->int_mask);
     6502    IWN_UNLOCK(sc);
     6503}
     6504
     6505static void
    63556506iwn_init_locked(struct iwn_softc *sc)
    63566507{
    63576508    struct ifnet *ifp = sc->sc_ifp;
    iwn_init_locked(struct iwn_softc *sc)  
    63596510
    63606511    IWN_LOCK_ASSERT(sc);
    63616512
    6362     error = iwn_hw_prepare(sc);
    6363     if (error != 0) {
    6364         device_printf(sc->sc_dev, "%s: hardware not ready, eror %d\n",
     6513    if ((error = iwn_hw_prepare(sc)) != 0) {
     6514        device_printf(sc->sc_dev, "%s: hardware not ready, error %d\n",
    63656515            __func__, error);
    63666516        goto fail;
    63676517    }
    iwn_init_locked(struct iwn_softc *sc)  
    63746524    if (!(IWN_READ(sc, IWN_GP_CNTRL) & IWN_GP_CNTRL_RFKILL)) {
    63756525        device_printf(sc->sc_dev,
    63766526            "radio is disabled by hardware switch\n");
    6377 
    63786527        /* Enable interrupts to get RF toggle notifications. */
    63796528        IWN_WRITE(sc, IWN_INT, 0xffffffff);
    63806529        IWN_WRITE(sc, IWN_INT_MASK, sc->int_mask);
    iwn_init_locked(struct iwn_softc *sc)  
    63826531    }
    63836532
    63846533    /* Read firmware images from the filesystem. */
    6385     error = iwn_read_firmware(sc);
    6386     if (error != 0) {
     6534    if ((error = iwn_read_firmware(sc)) != 0) {
    63876535        device_printf(sc->sc_dev,
    6388             "%s: could not read firmware, error %d\n",
    6389             __func__, error);
     6536            "%s: could not read firmware, error %d\n", __func__,
     6537            error);
    63906538        goto fail;
    63916539    }
    63926540
    iwn_init_locked(struct iwn_softc *sc)  
    63966544    sc->fw_fp = NULL;
    63976545    if (error != 0) {
    63986546        device_printf(sc->sc_dev,
    6399             "%s: could not initialize hardware, error %d\n",
    6400             __func__, error);
     6547            "%s: could not initialize hardware, error %d\n", __func__,
     6548            error);
    64016549        goto fail;
    64026550    }
    64036551
    64046552    /* Configure adapter now that it is ready. */
    6405     error = iwn_config(sc);
    6406     if (error != 0) {
     6553    if ((error = iwn_config(sc)) != 0) {
    64076554        device_printf(sc->sc_dev,
    6408             "%s: could not configure device, error %d\n",
    6409             __func__, error);
     6555            "%s: could not configure device, error %d\n", __func__,
     6556            error);
    64106557        goto fail;
    64116558    }
    64126559
    64136560    ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
    64146561    ifp->if_drv_flags |= IFF_DRV_RUNNING;
    64156562
     6563    callout_reset(&sc->watchdog_to, hz, iwn_watchdog, sc);
    64166564    return;
    64176565
    6418 fail:
    6419     iwn_stop_locked(sc);
     6566fail:   iwn_stop_locked(sc);
    64206567}
    64216568
    64226569static void
    iwn_stop_locked(struct iwn_softc *sc)  
    64426589    IWN_LOCK_ASSERT(sc);
    64436590
    64446591    sc->sc_tx_timer = 0;
    6445     callout_stop(&sc->sc_timer_to);
     6592    callout_stop(&sc->watchdog_to);
     6593    callout_stop(&sc->calib_to);
    64466594    ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
    64476595
    64486596    /* Power OFF hardware. */
    iwn_set_channel(struct ieee80211com *ic)  
    64996647    const struct ieee80211_channel *c = ic->ic_curchan;
    65006648    struct ifnet *ifp = ic->ic_ifp;
    65016649    struct iwn_softc *sc = ifp->if_softc;
     6650    int error;
    65026651
    65036652    IWN_LOCK(sc);
    65046653    sc->sc_rxtap.wr_chan_freq = htole16(c->ic_freq);
    65056654    sc->sc_rxtap.wr_chan_flags = htole16(c->ic_flags);
    65066655    sc->sc_txtap.wt_chan_freq = htole16(c->ic_freq);
    65076656    sc->sc_txtap.wt_chan_flags = htole16(c->ic_flags);
     6657
     6658    /*
     6659     * Only need to set the channel in Monitor mode. AP scanning and auth
     6660     * are already taken care of by their respective firmware commands.
     6661     */
     6662    if (ic->ic_opmode == IEEE80211_M_MONITOR) {
     6663        error = iwn_config(sc);
     6664        if (error != 0)
     6665        device_printf(sc->sc_dev,
     6666            "%s: error %d settting channel\n", __func__, error);
     6667    }
    65086668    IWN_UNLOCK(sc);
    65096669}
    65106670
    iwn_scan_mindwell(struct ieee80211_scan_state *ss)  
    65366696    /* NB: don't try to abort scan; wait for firmware to finish */
    65376697}
    65386698
    6539 static struct iwn_eeprom_chan *
    6540 iwn_find_eeprom_channel(struct iwn_softc *sc, struct ieee80211_channel *c)
    6541 {
    6542     int i, j;
    6543 
    6544     for (j = 0; j < 7; j++) {
    6545         for (i = 0; i < iwn_bands[j].nchan; i++) {
    6546             if (iwn_bands[j].chan[i] == c->ic_ieee)
    6547                 return &sc->eeprom_channels[j][i];
    6548         }
    6549     }
    6550 
    6551     return NULL;
    6552 }
    6553 
    6554 /*
    6555  * Enforce flags read from EEPROM.
    6556  */
    6557 static int
    6558 iwn_setregdomain(struct ieee80211com *ic, struct ieee80211_regdomain *rd,
    6559     int nchan, struct ieee80211_channel chans[])
    6560 {
    6561     struct iwn_softc *sc = ic->ic_ifp->if_softc;
    6562     int i;
    6563 
    6564     for (i = 0; i < nchan; i++) {
    6565         struct ieee80211_channel *c = &chans[i];
    6566         struct iwn_eeprom_chan *channel;
    6567 
    6568         channel = iwn_find_eeprom_channel(sc, c);
    6569         if (channel == NULL) {
    6570             if_printf(ic->ic_ifp,
    6571                 "%s: invalid channel %u freq %u/0x%x\n",
    6572                 __func__, c->ic_ieee, c->ic_freq, c->ic_flags);
    6573             return EINVAL;
    6574         }
    6575         c->ic_flags |= iwn_eeprom_channel_flags(channel);
    6576     }
    6577 
    6578     return 0;
    6579 }
    6580 
    65816699static void
    65826700iwn_hw_reset(void *arg0, int pending)
    65836701{
    iwn_hw_reset(void *arg0, int pending)  
    65896707    iwn_init(sc);
    65906708    ieee80211_notify_radio(ic, 1);
    65916709}
    6592 
    6593 static void
    6594 iwn_radio_on(void *arg0, int pending)
    6595 {
    6596     struct iwn_softc *sc = arg0;
    6597     struct ifnet *ifp = sc->sc_ifp;
    6598     struct ieee80211com *ic = ifp->if_l2com;
    6599     struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
    6600 
    6601     if (vap != NULL) {
    6602         iwn_init(sc);
    6603         ieee80211_init(vap);
    6604     }
    6605 }
    6606 
    6607 static void
    6608 iwn_radio_off(void *arg0, int pending)
    6609 {
    6610     struct iwn_softc *sc = arg0;
    6611     struct ifnet *ifp = sc->sc_ifp;
    6612     struct ieee80211com *ic = ifp->if_l2com;
    6613     struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
    6614 
    6615     iwn_stop(sc);
    6616     if (vap != NULL)
    6617         ieee80211_stop(vap);
    6618 
    6619     /* Enable interrupts to get RF toggle notification. */
    6620     IWN_LOCK(sc);
    6621     IWN_WRITE(sc, IWN_INT, 0xffffffff);
    6622     IWN_WRITE(sc, IWN_INT_MASK, sc->int_mask);
    6623     IWN_UNLOCK(sc);
    6624 }
    6625 
    6626 static void
    6627 iwn_sysctlattach(struct iwn_softc *sc)
    6628 {
    6629     struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev);
    6630     struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev);
    6631 
    6632 #ifdef IWN_DEBUG
    6633     sc->sc_debug = 0;
    6634     SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
    6635         "debug", CTLFLAG_RW, &sc->sc_debug, 0, "control debugging printfs");
    6636 #endif
    6637 }
    6638 
    6639 static int
    6640 iwn_shutdown(device_t dev)
    6641 {
    6642     struct iwn_softc *sc = device_get_softc(dev);
    6643 
    6644     iwn_stop(sc);
    6645     return 0;
    6646 }
    6647 
    6648 static int
    6649 iwn_suspend(device_t dev)
    6650 {
    6651     struct iwn_softc *sc = device_get_softc(dev);
    6652     struct ifnet *ifp = sc->sc_ifp;
    6653     struct ieee80211com *ic = ifp->if_l2com;
    6654     struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
    6655 
    6656     iwn_stop(sc);
    6657     if (vap != NULL)
    6658         ieee80211_stop(vap);
    6659     return 0;
    6660 }
    6661 
    6662 static int
    6663 iwn_resume(device_t dev)
    6664 {
    6665     struct iwn_softc *sc = device_get_softc(dev);
    6666     struct ifnet *ifp = sc->sc_ifp;
    6667     struct ieee80211com *ic = ifp->if_l2com;
    6668     struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
    6669 
    6670     /* Clear device-specific "PCI retry timeout" register (41h). */
    6671     pci_write_config(dev, 0x41, 0, 1);
    6672 
    6673     if (ifp->if_flags & IFF_UP) {
    6674         iwn_init(sc);
    6675         if (vap != NULL)
    6676             ieee80211_init(vap);
    6677         if (ifp->if_drv_flags & IFF_DRV_RUNNING)
    6678             iwn_start(ifp);
    6679     }
    6680     return 0;
    6681 }
    6682 
    6683 #ifdef IWN_DEBUG
    6684 static const char *
    6685 iwn_intr_str(uint8_t cmd)
    6686 {
    6687     switch (cmd) {
    6688     /* Notifications */
    6689     case IWN_UC_READY:      return "UC_READY";
    6690     case IWN_ADD_NODE_DONE:     return "ADD_NODE_DONE";
    6691     case IWN_TX_DONE:       return "TX_DONE";
    6692     case IWN_START_SCAN:        return "START_SCAN";
    6693     case IWN_STOP_SCAN:     return "STOP_SCAN";
    6694     case IWN_RX_STATISTICS:     return "RX_STATS";
    6695     case IWN_BEACON_STATISTICS: return "BEACON_STATS";
    6696     case IWN_STATE_CHANGED:     return "STATE_CHANGED";
    6697     case IWN_BEACON_MISSED:     return "BEACON_MISSED";
    6698     case IWN_RX_PHY:        return "RX_PHY";
    6699     case IWN_MPDU_RX_DONE:      return "MPDU_RX_DONE";
    6700     case IWN_RX_DONE:       return "RX_DONE";
    6701 
    6702     /* Command Notifications */
    6703     case IWN_CMD_RXON:      return "IWN_CMD_RXON";
    6704     case IWN_CMD_RXON_ASSOC:    return "IWN_CMD_RXON_ASSOC";
    6705     case IWN_CMD_EDCA_PARAMS:   return "IWN_CMD_EDCA_PARAMS";
    6706     case IWN_CMD_TIMING:        return "IWN_CMD_TIMING";
    6707     case IWN_CMD_LINK_QUALITY:  return "IWN_CMD_LINK_QUALITY";
    6708     case IWN_CMD_SET_LED:       return "IWN_CMD_SET_LED";
    6709     case IWN5000_CMD_WIMAX_COEX:    return "IWN5000_CMD_WIMAX_COEX";
    6710     case IWN5000_CMD_CALIB_CONFIG:  return "IWN5000_CMD_CALIB_CONFIG";
    6711     case IWN5000_CMD_CALIB_RESULT:  return "IWN5000_CMD_CALIB_RESULT";
    6712     case IWN5000_CMD_CALIB_COMPLETE: return "IWN5000_CMD_CALIB_COMPLETE";
    6713     case IWN_CMD_SET_POWER_MODE:    return "IWN_CMD_SET_POWER_MODE";
    6714     case IWN_CMD_SCAN:      return "IWN_CMD_SCAN";
    6715     case IWN_CMD_SCAN_RESULTS:  return "IWN_CMD_SCAN_RESULTS";
    6716     case IWN_CMD_TXPOWER:       return "IWN_CMD_TXPOWER";
    6717     case IWN_CMD_TXPOWER_DBM:   return "IWN_CMD_TXPOWER_DBM";
    6718     case IWN5000_CMD_TX_ANT_CONFIG: return "IWN5000_CMD_TX_ANT_CONFIG";
    6719     case IWN_CMD_BT_COEX:       return "IWN_CMD_BT_COEX";
    6720     case IWN_CMD_SET_CRITICAL_TEMP: return "IWN_CMD_SET_CRITICAL_TEMP";
    6721     case IWN_CMD_SET_SENSITIVITY:   return "IWN_CMD_SET_SENSITIVITY";
    6722     case IWN_CMD_PHY_CALIB:     return "IWN_CMD_PHY_CALIB";
    6723     }
    6724     return "UNKNOWN INTR NOTIF/CMD";
    6725 }
    6726 #endif /* IWN_DEBUG */
    6727 
    6728 static device_method_t iwn_methods[] = {
    6729     /* Device interface */
    6730     DEVMETHOD(device_probe,     iwn_probe),
    6731     DEVMETHOD(device_attach,    iwn_attach),
    6732     DEVMETHOD(device_detach,    iwn_detach),
    6733     DEVMETHOD(device_shutdown,  iwn_shutdown),
    6734     DEVMETHOD(device_suspend,   iwn_suspend),
    6735     DEVMETHOD(device_resume,    iwn_resume),
    6736     { 0, 0 }
    6737 };
    6738 
    6739 static driver_t iwn_driver = {
    6740     "iwn",
    6741     iwn_methods,
    6742     sizeof (struct iwn_softc)
    6743 };
    6744 static devclass_t iwn_devclass;
    6745 
    6746 DRIVER_MODULE(iwn, pci, iwn_driver, iwn_devclass, 0, 0);
    6747 MODULE_DEPEND(iwn, pci, 1, 1, 1);
    6748 MODULE_DEPEND(iwn, firmware, 1, 1, 1);
    6749 MODULE_DEPEND(iwn, wlan, 1, 1, 1);
  • src/add-ons/kernel/drivers/network/wlan/iprowifi4965/dev/iwn/if_iwnreg.h

    diff --git a/src/add-ons/kernel/drivers/network/wlan/iprowifi4965/dev/iwn/if_iwnreg.h b/src/add-ons/kernel/drivers/network/wlan/iprowifi4965/dev/iwn/if_iwnreg.h
    index 5472ea3..e08b309 100644
    a b  
    1717 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
    1818 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
    1919 */
    20 #ifndef __IF_IWNREG_H__
    21 #define __IF_IWNREG_H__
    22 
    23 #define IWN_CT_KILL_THRESHOLD       114 /* in Celsius */
    24 #define IWN_CT_KILL_EXIT_THRESHOLD  95  /* in Celsius */
    2520
    2621#define IWN_TX_RING_COUNT   256
    2722#define IWN_TX_RING_LOMARK  192
     
    3227#define IWN4965_NTXQUEUES   16
    3328#define IWN5000_NTXQUEUES   20
    3429
    35 #define IWN4965_FIRSTAGGQUEUE   7
    36 #define IWN5000_FIRSTAGGQUEUE   10
    37 
    3830#define IWN4965_NDMACHNLS   7
    3931#define IWN5000_NDMACHNLS   8
    4032
     
    4335#define IWN_ICT_SIZE        4096
    4436#define IWN_ICT_COUNT       (IWN_ICT_SIZE / sizeof (uint32_t))
    4537
    46 /* For cards with PAN command, default is IWN_CMD_QUEUE_NUM */
    47 #define IWN_CMD_QUEUE_NUM       4
    48 #define IWN_PAN_CMD_QUEUE       9
    49 
    5038/* Maximum number of DMA segments for TX. */
    5139#define IWN_MAX_SCATTER 20
    5240
     
    7159#define IWN_INT         0x008
    7260#define IWN_INT_MASK        0x00c
    7361#define IWN_FH_INT      0x010
    74 #define IWN_GPIO_IN     0x018   /* read external chip pins */
    7562#define IWN_RESET       0x020
    7663#define IWN_GP_CNTRL        0x024
    7764#define IWN_HW_REV      0x028
     
    7966#define IWN_EEPROM_GP       0x030
    8067#define IWN_OTP_GP      0x034
    8168#define IWN_GIO         0x03c
    82 #define IWN_GP_UCODE        0x048
    8369#define IWN_GP_DRIVER       0x050
    84 #define IWN_UCODE_GP1       0x054
    85 #define IWN_UCODE_GP1_SET   0x058
    8670#define IWN_UCODE_GP1_CLR   0x05c
    87 #define IWN_UCODE_GP2       0x060
    8871#define IWN_LED         0x094
    8972#define IWN_DRAM_INT_TBL    0x0a0
    9073#define IWN_SHADOW_REG_CTRL 0x0a8
     
    9376#define IWN_HW_REV_WA       0x22c
    9477#define IWN_DBG_HPET_MEM    0x240
    9578#define IWN_DBG_LINK_PWR_MGMT   0x250
    96 /* Need nic_lock for use above */
    9779#define IWN_MEM_RADDR       0x40c
    9880#define IWN_MEM_WADDR       0x410
    9981#define IWN_MEM_WDATA       0x418
    10082#define IWN_MEM_RDATA       0x41c
    101 #define IWN_TARG_MBX_C      0x430
    10283#define IWN_PRPH_WADDR      0x444
    10384#define IWN_PRPH_RADDR      0x448
    10485#define IWN_PRPH_WDATA      0x44c
     
    200181#define IWN_RESET_SW            (1 << 7)
    201182#define IWN_RESET_MASTER_DISABLED   (1 << 8)
    202183#define IWN_RESET_STOP_MASTER       (1 << 9)
    203 #define IWN_RESET_LINK_PWR_MGMT_DIS (1U << 31)
     184#define IWN_RESET_LINK_PWR_MGMT_DIS (1 << 31)
    204185
    205186/* Possible flags for register IWN_GP_CNTRL. */
    206187#define IWN_GP_CNTRL_MAC_ACCESS_ENA (1 << 0)
     
    210191#define IWN_GP_CNTRL_SLEEP      (1 << 4)
    211192#define IWN_GP_CNTRL_RFKILL     (1 << 27)
    212193
     194/* Possible flags for register IWN_HW_REV. */
     195#define IWN_HW_REV_TYPE_SHIFT   4
     196#define IWN_HW_REV_TYPE_MASK    0x000000f0
     197#define IWN_HW_REV_TYPE_4965    0
     198#define IWN_HW_REV_TYPE_5300    2
     199#define IWN_HW_REV_TYPE_5350    3
     200#define IWN_HW_REV_TYPE_5150    4
     201#define IWN_HW_REV_TYPE_5100    5
     202#define IWN_HW_REV_TYPE_1000    6
     203#define IWN_HW_REV_TYPE_6000    7
     204#define IWN_HW_REV_TYPE_6050    8
     205#define IWN_HW_REV_TYPE_6005    11
     206
    213207/* Possible flags for register IWN_GIO_CHICKEN. */
    214208#define IWN_GIO_CHICKEN_L1A_NO_L0S_RX   (1 << 23)
    215209#define IWN_GIO_CHICKEN_DIS_L0S_TIMER   (1 << 29)
     
    223217#define IWN_GP_DRIVER_RADIO_2X2_IPA (2 << 0)
    224218#define IWN_GP_DRIVER_CALIB_VER6    (1 << 2)
    225219#define IWN_GP_DRIVER_6050_1X2      (1 << 3)
    226 #define IWN_GP_DRIVER_REG_BIT_RADIO_IQ_INVERT   (1 << 7)
    227 #define IWN_GP_DRIVER_NONE      0
    228220
    229221/* Possible flags for register IWN_UCODE_GP1_CLR. */
    230222#define IWN_UCODE_GP1_RFKILL        (1 << 1)
    231223#define IWN_UCODE_GP1_CMD_BLOCKED   (1 << 2)
    232224#define IWN_UCODE_GP1_CTEMP_STOP_RF (1 << 3)
    233 #define IWN_UCODE_GP1_CFG_COMPLETE  (1 << 5)
    234225
    235226/* Possible flags/values for register IWN_LED. */
    236227#define IWN_LED_BSM_CTRL    (1 << 5)
    237228#define IWN_LED_OFF     0x00000038
    238229#define IWN_LED_ON      0x00000078
    239230
    240 #define IWN_MAX_BLINK_TBL   10
    241 #define IWN_LED_STATIC_ON   0
    242 #define IWN_LED_STATIC_OFF  1
    243 #define IWN_LED_SLOW_BLINK  2
    244 #define IWN_LED_INT_BLINK   3
    245 #define IWN_LED_UNIT        0x1388  /* 5 ms */
    246 
    247 static const struct {
    248     uint16_t    tpt;    /* Mb/s */
    249     uint8_t     on_time;
    250     uint8_t     off_time;
    251 } blink_tbl[] =
    252 {
    253     {300, 5, 5},
    254     {200, 8, 8},
    255     {100, 11, 11},
    256     {70, 13, 13},
    257     {50, 15, 15},
    258     {20, 17, 17},
    259     {10, 19, 19},
    260     {5, 22, 22},
    261     {1, 26, 26},
    262     {0, 33, 33},
    263     /* SOLID_ON */
    264 };
    265 
    266231/* Possible flags for register IWN_DRAM_INT_TBL. */
    267232#define IWN_DRAM_INT_TBL_WRAP_CHECK (1 << 27)
    268 #define IWN_DRAM_INT_TBL_ENABLE     (1U << 31)
     233#define IWN_DRAM_INT_TBL_ENABLE     (1 << 31)
    269234
    270235/* Possible values for register IWN_ANA_PLL. */
    271236#define IWN_ANA_PLL_INIT    0x00880300
    static const struct {  
    275240
    276241/* Possible flags for register IWN_BSM_WR_CTRL. */
    277242#define IWN_BSM_WR_CTRL_START_EN    (1 << 30)
    278 #define IWN_BSM_WR_CTRL_START       (1U << 31)
     243#define IWN_BSM_WR_CTRL_START       (1 << 31)
    279244
    280245/* Possible flags for register IWN_INT. */
    281246#define IWN_INT_ALIVE       (1 <<  0)
    static const struct {  
    288253#define IWN_INT_FH_TX       (1 << 27)
    289254#define IWN_INT_RX_PERIODIC (1 << 28)
    290255#define IWN_INT_HW_ERR      (1 << 29)
    291 #define IWN_INT_FH_RX       (1U << 31)
     256#define IWN_INT_FH_RX       (1 << 31)
    292257
    293258/* Shortcut. */
    294259#define IWN_INT_MASK_DEF                        \
    static const struct {  
    308273
    309274/* Possible flags/values for register IWN_FH_TX_CONFIG. */
    310275#define IWN_FH_TX_CONFIG_DMA_PAUSE      0
    311 #define IWN_FH_TX_CONFIG_DMA_ENA        (1U << 31)
     276#define IWN_FH_TX_CONFIG_DMA_ENA        (1 << 31)
    312277#define IWN_FH_TX_CONFIG_CIRQ_HOST_ENDTFD   (1 << 20)
    313278
    314279/* Possible flags/values for register IWN_FH_TXBUF_STATUS. */
    static const struct {  
    323288#define IWN_FH_TX_STATUS_IDLE(chnl) (1 << ((chnl) + 16))
    324289
    325290/* Possible flags for register IWN_FH_RX_CONFIG. */
    326 #define IWN_FH_RX_CONFIG_ENA        (1U << 31)
     291#define IWN_FH_RX_CONFIG_ENA        (1 << 31)
    327292#define IWN_FH_RX_CONFIG_NRBD(x)    ((x) << 20)
    328293#define IWN_FH_RX_CONFIG_RB_SIZE_8K (1 << 16)
    329294#define IWN_FH_RX_CONFIG_SINGLE_FRAME   (1 << 15)
    static const struct {  
    332297#define IWN_FH_RX_CONFIG_IGN_RXF_EMPTY  (1 <<  2)
    333298
    334299/* Possible flags for register IWN_FH_TX_CONFIG. */
    335 #define IWN_FH_TX_CONFIG_DMA_ENA    (1U << 31)
     300#define IWN_FH_TX_CONFIG_DMA_ENA    (1 << 31)
    336301#define IWN_FH_TX_CONFIG_DMA_CREDIT_ENA (1 <<  3)
    337302
    338303/* Possible flags for register IWN_EEPROM. */
    static const struct {  
    380345#define IWN_APMG_PCI_STT_L1A_DIS    (1 << 11)
    381346
    382347/* Possible flags for register IWN_BSM_DRAM_TEXT_SIZE. */
    383 #define IWN_FW_UPDATED  (1U << 31)
     348#define IWN_FW_UPDATED  (1 << 31)
    384349
    385350#define IWN_SCHED_WINSZ     64
    386351#define IWN_SCHED_LIMIT     64
    struct iwn_rx_status {  
    409374} __packed;
    410375
    411376struct iwn_rx_desc {
    412     /*
    413      * The first 4 bytes of the RX frame header contain both the RX frame
    414      * size and some flags.
    415      * Bit fields:
    416      * 31:    flag flush RB request
    417      * 30:    flag ignore TC (terminal counter) request
    418      * 29:    flag fast IRQ request
    419      * 28-14: Reserved
    420      * 13-00: RX frame size
    421      */
    422377    uint32_t    len;
    423378    uint8_t     type;
    424379#define IWN_UC_READY              1
    425380#define IWN_ADD_NODE_DONE        24
    426381#define IWN_TX_DONE          28
    427 #define IWN_REPLY_LED_CMD       72
    428382#define IWN5000_CALIBRATION_RESULT  102
    429383#define IWN5000_CALIBRATION_DONE    103
    430384#define IWN_START_SCAN          130
    431 #define IWN_NOTIF_SCAN_RESULT       131
    432385#define IWN_STOP_SCAN           132
    433386#define IWN_RX_STATISTICS       156
    434387#define IWN_BEACON_STATISTICS       157
    struct iwn_rx_desc {  
    439392#define IWN_RX_DONE         195
    440393#define IWN_RX_COMPRESSED_BA        197
    441394
    442     uint8_t     flags;  /* 0:5 reserved, 6 abort, 7 internal */
    443     uint8_t     idx;    /* position within TX queue */
     395    uint8_t     flags;
     396    uint8_t     idx;
    444397    uint8_t     qid;
    445     /* 0:4 TX queue id - 5:6 reserved - 7 unsolicited RX
    446      * or uCode-originated notification
    447      */
    448398} __packed;
    449399
    450 #define IWN_RX_DESC_QID_MSK     0x1F
    451 #define IWN_UNSOLICITED_RX_NOTIF    0x80
    452 
    453 /* CARD_STATE_NOTIFICATION */
    454 #define IWN_STATE_CHANGE_HW_CARD_DISABLED       0x01
    455 #define IWN_STATE_CHANGE_SW_CARD_DISABLED       0x02
    456 #define IWN_STATE_CHANGE_CT_CARD_DISABLED       0x04
    457 #define IWN_STATE_CHANGE_RXON_CARD_DISABLED     0x10
    458 
    459400/* Possible RX status flags. */
    460401#define IWN_RX_NO_CRC_ERR   (1 <<  0)
    461402#define IWN_RX_NO_OVFL_ERR  (1 <<  1)
    struct iwn_tx_cmd {  
    479420#define IWN_CMD_LINK_QUALITY         78
    480421#define IWN_CMD_SET_LED          72
    481422#define IWN5000_CMD_WIMAX_COEX       90
    482 #define IWN_TEMP_NOTIFICATION       98
    483423#define IWN5000_CMD_CALIB_CONFIG    101
    484424#define IWN5000_CMD_CALIB_RESULT    102
    485425#define IWN5000_CMD_CALIB_COMPLETE  103
    struct iwn_tx_cmd {  
    496436#define IWN_CMD_PHY_CALIB       176
    497437#define IWN_CMD_BT_COEX_PRIOTABLE   204
    498438#define IWN_CMD_BT_COEX_PROT        205
    499 #define IWN_CMD_BT_COEX_NOTIF       206
    500 /* PAN commands */
    501 #define IWN_CMD_WIPAN_PARAMS            0xb2
    502 #define IWN_CMD_WIPAN_RXON          0xb3
    503 #define IWN_CMD_WIPAN_RXON_TIMING       0xb4
    504 #define IWN_CMD_WIPAN_RXON_ASSOC        0xb6
    505 #define IWN_CMD_WIPAN_QOS_PARAM         0xb7
    506 #define IWN_CMD_WIPAN_WEPKEY            0xb8
    507 #define IWN_CMD_WIPAN_P2P_CHANNEL_SWITCH    0xb9
    508 #define IWN_CMD_WIPAN_NOA_NOTIFICATION      0xbc
    509 #define IWN_CMD_WIPAN_DEACTIVATION_COMPLETE 0xbd
    510439
    511440    uint8_t flags;
    512441    uint8_t idx;
    struct iwn_tx_cmd {  
    514443    uint8_t data[136];
    515444} __packed;
    516445
    517 /*
    518  * Structure for IWN_CMD_GET_STATISTICS = (0x9c) 156
    519  * all devices identical.
    520  *
    521  * This command triggers an immediate response containing uCode statistics.
    522  * The response is in the same format as IWN_BEACON_STATISTICS (0x9d) 157.
    523  *
    524  * If the CLEAR_STATS configuration flag is set, uCode will clear its
    525  * internal copy of the statistics (counters) after issuing the response.
    526  * This flag does not affect IWN_BEACON_STATISTICS after beacons (see below).
    527  *
    528  * If the DISABLE_NOTIF configuration flag is set, uCode will not issue
    529  * IWN_BEACON_STATISTICS after received beacons.  This flag
    530  * does not affect the response to the IWN_CMD_GET_STATISTICS 0x9c itself.
    531  */
    532 struct iwn_statistics_cmd {
    533     uint32_t    configuration_flags;
    534 #define IWN_STATS_CONF_CLEAR_STATS      htole32(0x1)
    535 #define IWN_STATS_CONF_DISABLE_NOTIF    htole32(0x2)
    536 } __packed;
    537 
    538446/* Antenna flags, used in various commands. */
    539447#define IWN_ANT_A   (1 << 0)
    540448#define IWN_ANT_B   (1 << 1)
    struct iwn_statistics_cmd {  
    542450/* Shortcuts. */
    543451#define IWN_ANT_AB  (IWN_ANT_A | IWN_ANT_B)
    544452#define IWN_ANT_BC  (IWN_ANT_B | IWN_ANT_C)
    545 #define IWN_ANT_AC  (IWN_ANT_A | IWN_ANT_C)
    546453#define IWN_ANT_ABC (IWN_ANT_A | IWN_ANT_B | IWN_ANT_C)
    547454
    548455/* Structure for command IWN_CMD_RXON. */
    struct iwn_rxon {  
    558465#define IWN_MODE_STA        3
    559466#define IWN_MODE_IBSS       4
    560467#define IWN_MODE_MONITOR    6
    561 #define IWN_MODE_2STA       8
    562 #define IWN_MODE_P2P        9
    563468
    564469    uint8_t     air;
    565470    uint16_t    rxchain;
    struct iwn_rxon {  
    584489#define IWN_RXON_ANTENNA_A  (1 <<  8)
    585490#define IWN_RXON_ANTENNA_B  (1 <<  9)
    586491#define IWN_RXON_TSF        (1 << 15)
    587 #define IWN_RXON_HT_HT40MINUS   (1 << 22)
    588 #define IWN_RXON_HT_PROTMODE(x) (x << 23)
    589 #define IWN_RXON_HT_MODEPURE40  (1 << 25)
    590 #define IWN_RXON_HT_MODEMIXED   (2 << 25)
    591492#define IWN_RXON_CTS_TO_SELF    (1 << 30)
    592493
    593494    uint32_t    filter;
    struct iwn_cmd_timing {  
    643544    uint16_t    atim;
    644545    uint32_t    binitval;
    645546    uint16_t    lintval;
    646     uint8_t     dtim_period;
    647     uint8_t     delta_cp_bss_tbtts;
     547    uint16_t    reserved;
    648548} __packed;
    649549
    650550/* Structure for command IWN_CMD_ADD_NODE. */
    struct iwn_node_info {  
    658558    uint16_t    reserved2;
    659559    uint8_t     id;
    660560#define IWN_ID_BSS       0
    661 #define IWN_STA_ID      1
    662 
    663 #define IWN_PAN_ID_BCAST        14
    664561#define IWN5000_ID_BROADCAST    15
    665562#define IWN4965_ID_BROADCAST    31
    666563
    struct iwn_node_info {  
    691588    uint8_t     txmic[8];
    692589
    693590    uint32_t    htflags;
    694 #define IWN_SMPS_MIMO_PROT      (1 << 17)
    695591#define IWN_AMDPU_SIZE_FACTOR(x)    ((x) << 19)
    696 #define IWN_NODE_HT40           (1 << 21)
    697 #define IWN_SMPS_MIMO_DIS       (1 << 22)
    698592#define IWN_AMDPU_DENSITY(x)        ((x) << 23)
    699593
    700594    uint32_t    mask;
    struct iwn4965_node_info {  
    731625    uint32_t    reserved7;
    732626} __packed;
    733627
    734 #define IWN_RFLAG_MCS       (1 << 8)
    735 #define IWN_RFLAG_CCK       (1 << 9)
    736 #define IWN_RFLAG_GREENFIELD    (1 << 10)
    737 #define IWN_RFLAG_HT40      (1 << 11)
    738 #define IWN_RFLAG_DUPLICATE (1 << 12)
    739 #define IWN_RFLAG_SGI       (1 << 13)
    740 #define IWN_RFLAG_ANT(x)    ((x) << 14)
     628#define IWN_RFLAG_CCK       (1 << 1)
     629#define IWN_RFLAG_ANT(x)    ((x) << 6)
    741630
    742631/* Structure for command IWN_CMD_TX_DATA. */
    743632struct iwn_cmd_data {
    struct iwn_cmd_data {  
    758647#define IWN_TX_NEED_PADDING (1 << 20)
    759648
    760649    uint32_t    scratch;
    761     uint32_t    rate;
     650    uint8_t     plcp;
     651    uint8_t     rflags;
     652    uint16_t    xrflags;
    762653
    763654    uint8_t     id;
    764655    uint8_t     security;
    struct iwn_cmd_link_quality {  
    799690    uint8_t     ampdu_threshold;
    800691    uint8_t     ampdu_max;
    801692    uint32_t    reserved2;
    802     uint32_t    retry[IWN_MAX_TX_RETRIES];
     693    struct {
     694        uint8_t     plcp;
     695        uint8_t     rflags;
     696        uint16_t    xrflags;
     697    } __packed  retry[IWN_MAX_TX_RETRIES];
    803698    uint32_t    reserved3;
    804699} __packed;
    805700
    struct iwn5000_wimax_coex {  
    835730struct iwn5000_calib_elem {
    836731    uint32_t    enable;
    837732    uint32_t    start;
    838 #define IWN5000_CALIB_DC    (1 << 1)
    839 
    840733    uint32_t    send;
    841734    uint32_t    apply;
    842735    uint32_t    reserved;
    struct iwn_pmgt_cmd {  
    862755#define IWN_PS_SLEEP_OVER_DTIM  (1 << 2)
    863756#define IWN_PS_PCI_PMGT     (1 << 3)
    864757#define IWN_PS_FAST_PD      (1 << 4)
    865 #define IWN_PS_BEACON_FILTERING (1 << 5)
    866 #define IWN_PS_SHADOW_REG   (1 << 6)
    867 #define IWN_PS_CT_KILL      (1 << 7)
    868 #define IWN_PS_BT_SCD       (1 << 8)
    869 #define IWN_PS_ADVANCED_PM  (1 << 9)
    870758
    871759    uint8_t     keepalive;
    872760    uint8_t     debug;
    struct iwn_scan_essid {  
    885773
    886774struct iwn_scan_hdr {
    887775    uint16_t    len;
    888     uint8_t     scan_flags;
     776    uint8_t     reserved1;
    889777    uint8_t     nchan;
    890778    uint16_t    quiet_time;
    891779    uint16_t    quiet_threshold;
    struct iwn_scan_hdr {  
    904792
    905793struct iwn_scan_chan {
    906794    uint32_t    flags;
    907 #define IWN_CHAN_PASSIVE    (0 << 0)
    908795#define IWN_CHAN_ACTIVE     (1 << 0)
    909796#define IWN_CHAN_NPBREQS(x) (((1 << (x)) - 1) << 1)
    910797
    struct iwn_scan_chan {  
    915802    uint16_t    passive;    /* msecs */
    916803} __packed;
    917804
    918 #define IWN_SCAN_CRC_TH_DISABLED    0
    919 #define IWN_SCAN_CRC_TH_DEFAULT     htole16(1)
    920 #define IWN_SCAN_CRC_TH_NEVER       htole16(0xffff)
    921 
    922805/* Maximum size of a scan command. */
    923806#define IWN_SCAN_MAXSZ  (MCLBYTES - 4)
    924807
    925 /*
    926  * For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after
    927  * sending probe req.  This should be set long enough to hear probe responses
    928  * from more than one AP.
    929  */
    930 #define IWN_ACTIVE_DWELL_TIME_2GHZ  (30)    /* all times in msec */
    931 #define IWN_ACTIVE_DWELL_TIME_5GHZ  (20)
    932 #define IWN_ACTIVE_DWELL_FACTOR_2GHZ    (3)
    933 #define IWN_ACTIVE_DWELL_FACTOR_5GHZ    (2)
    934 
    935 /*
    936  * For passive scan, listen PASSIVE_DWELL_TIME (msec) on each channel.
    937  * Must be set longer than active dwell time.
    938  * For the most reliable scan, set > AP beacon interval (typically 100msec).
    939  */
    940 #define IWN_PASSIVE_DWELL_TIME_2GHZ (20)    /* all times in msec */
    941 #define IWN_PASSIVE_DWELL_TIME_5GHZ (10)
    942 #define IWN_PASSIVE_DWELL_BASE      (100)
    943 #define IWN_CHANNEL_TUNE_TIME       (5)
    944 
    945 #define IWN_SCAN_CHAN_TIMEOUT       2
    946 #define IWN_MAX_SCAN_CHANNEL        50
    947 
    948 /*
    949  * If active scanning is requested but a certain channel is
    950  * marked passive, we can do active scanning if we detect
    951  * transmissions.
    952  *
    953  * There is an issue with some firmware versions that triggers
    954  * a sysassert on a "good CRC threshold" of zero (== disabled),
    955  * on a radar channel even though this means that we should NOT
    956  * send probes.
    957  *
    958  * The "good CRC threshold" is the number of frames that we
    959  * need to receive during our dwell time on a channel before
    960  * sending out probes -- setting this to a huge value will
    961  * mean we never reach it, but at the same time work around
    962  * the aforementioned issue. Thus use IWL_GOOD_CRC_TH_NEVER
    963  * here instead of IWL_GOOD_CRC_TH_DISABLED.
    964  *
    965  * This was fixed in later versions along with some other
    966  * scan changes, and the threshold behaves as a flag in those
    967  * versions.
    968  */
    969 #define IWN_GOOD_CRC_TH_DISABLED    0
    970 #define IWN_GOOD_CRC_TH_DEFAULT     htole16(1)
    971 #define IWN_GOOD_CRC_TH_NEVER       htole16(0xffff)
    972 
    973808/* Structure for command IWN_CMD_TXPOWER (4965AGN only.) */
    974809#define IWN_RIDX_MAX    32
    975810struct iwn4965_cmd_txpower {
    struct iwn_bluetooth {  
    1016851
    1017852struct iwn6000_btcoex_config {
    1018853    uint8_t     flags;
    1019 #define IWN_BT_FLAG_COEX6000_CHAN_INHIBITION    1
    1020 #define IWN_BT_FLAG_COEX6000_MODE_MASK      ((1 << 3) | (1 << 4) | (1 << 5 ))
    1021 #define IWN_BT_FLAG_COEX6000_MODE_SHIFT         3
    1022 #define IWN_BT_FLAG_COEX6000_MODE_DISABLED      0
    1023 #define IWN_BT_FLAG_COEX6000_MODE_LEGACY_2W     1
    1024 #define IWN_BT_FLAG_COEX6000_MODE_3W            2
    1025 #define IWN_BT_FLAG_COEX6000_MODE_4W            3
    1026 
    1027 #define IWN_BT_FLAG_UCODE_DEFAULT       (1 << 6)
    1028 #define IWN_BT_FLAG_SYNC_2_BT_DISABLE   (1 << 7)
    1029854    uint8_t     lead_time;
    1030855    uint8_t     max_kill;
    1031856    uint8_t     bt3_t7_timer;
    struct iwn6000_btcoex_config {  
    1042867    uint16_t    rx_prio_boost;
    1043868} __packed;
    1044869
    1045 /* Structure for enhanced command IWN_CMD_BLUETOOTH for 2000 Series. */
    1046 struct iwn2000_btcoex_config {
    1047     uint8_t     flags;  /* Cf Flags in iwn6000_btcoex_config */
    1048     uint8_t     lead_time;
    1049     uint8_t     max_kill;
    1050     uint8_t     bt3_t7_timer;
    1051     uint32_t    kill_ack;
    1052     uint32_t    kill_cts;
    1053     uint8_t     sample_time;
    1054     uint8_t     bt3_t2_timer;
    1055     uint16_t    bt4_reaction;
    1056     uint32_t    lookup_table[12];
    1057     uint16_t    bt4_decision;
    1058     uint16_t    valid;
    1059 
    1060     uint32_t    prio_boost; /* size change prior to iwn6000_btcoex_config */
    1061     uint8_t     reserved;   /* added prior to iwn6000_btcoex_config */
    1062 
    1063     uint8_t     tx_prio_boost;
    1064     uint16_t    rx_prio_boost;
    1065 } __packed;
    1066 
    1067870struct iwn_btcoex_priotable {
    1068871    uint8_t     calib_init1;
    1069872    uint8_t     calib_init2;
    struct iwn_enhanced_sensitivity_cmd {  
    1141944    uint16_t    reserved;
    1142945} __packed;
    1143946
    1144 /*
    1145  * Define maximal number of calib result send to runtime firmware
    1146  * PS: TEMP_OFFSET count for 2 (std and v2)
    1147  */
    1148 #define IWN5000_PHY_CALIB_MAX_RESULT        8
    1149 
    1150947/* Structures for command IWN_CMD_PHY_CALIB. */
    1151948struct iwn_phy_calib {
    1152949    uint8_t code;
    struct iwn5000_phy_calib_temp_offset {  
    1188985    uint16_t    reserved;
    1189986} __packed;
    1190987
    1191 struct iwn5000_phy_calib_temp_offsetv2 {
    1192     uint8_t     code;
    1193     uint8_t     group;
    1194     uint8_t     ngroups;
    1195     uint8_t     isvalid;
    1196     int16_t     offset_high;
    1197     int16_t     offset_low;
    1198     int16_t     burnt_voltage_ref;
    1199     int16_t     reserved;
    1200 } __packed;
    1201 
    1202988struct iwn_phy_calib_gain {
    1203989    uint8_t code;
    1204990    uint8_t group;
    struct iwn_ucode_info {  
    12661052} __packed;
    12671053
    12681054/* Structures for IWN_TX_DONE notification. */
    1269 #define IWN_TX_STATUS_MSK       0xff
    1270 #define TX_STATUS_SUCCESS       0x01
    1271 #define TX_STATUS_DIRECT_DONE       0x02
    1272 
    12731055#define IWN_TX_SUCCESS          0x00
    12741056#define IWN_TX_FAIL         0x80    /* all failures have 0x80 set */
    12751057#define IWN_TX_FAIL_SHORT_LIMIT     0x82    /* too many RTS retries */
    struct iwn_ucode_info {  
    12771059#define IWN_TX_FAIL_FIFO_UNDERRRUN  0x84    /* tx fifo not kept running */
    12781060#define IWN_TX_FAIL_DEST_IN_PS      0x88    /* sta found in power save */
    12791061#define IWN_TX_FAIL_TX_LOCKED       0x90    /* waiting to see traffic */
    1280 #define IWN_TX_FAIL_STA_INVALID     0x8b    /* XXX STA invalid (???) */
    12811062
    12821063struct iwn4965_tx_stat {
    12831064    uint8_t     nframes;
    12841065    uint8_t     btkillcnt;
    12851066    uint8_t     rtsfailcnt;
    12861067    uint8_t     ackfailcnt;
    1287     uint32_t    rate;
     1068    uint8_t     rate;
     1069    uint8_t     rflags;
     1070    uint16_t    xrflags;
    12881071    uint16_t    duration;
    12891072    uint16_t    reserved;
    12901073    uint32_t    power[2];
    struct iwn4965_tx_stat {  
    12921075} __packed;
    12931076
    12941077struct iwn5000_tx_stat {
    1295     uint8_t     nframes;    /* 1 no aggregation, >1 aggregation */
     1078    uint8_t     nframes;
    12961079    uint8_t     btkillcnt;
    12971080    uint8_t     rtsfailcnt;
    12981081    uint8_t     ackfailcnt;
    1299     uint32_t    rate;
     1082    uint8_t     rate;
     1083    uint8_t     rflags;
     1084    uint16_t    xrflags;
    13001085    uint16_t    duration;
    13011086    uint16_t    reserved;
    13021087    uint32_t    power[2];
    struct iwn5000_tx_stat {  
    13041089    uint16_t    seq;
    13051090    uint16_t    len;
    13061091    uint8_t     tlc;
    1307     uint8_t     ratid;  /* tid (0:3), sta_id (4:7) */
     1092    uint8_t     ratid;
    13081093    uint8_t     fc[2];
    13091094    uint16_t    status;
    13101095    uint16_t    sequence;
    struct iwn_rx_stat {  
    13511136
    13521137    uint16_t    chan;
    13531138    uint8_t     phybuf[32];
    1354     uint32_t    rate;
    1355 /*
    1356  * rate bit fields
    1357  *
    1358  * High-throughput (HT) rate format for bits 7:0 (bit 8 must be "1"):
    1359  *  2-0:  0)   6 Mbps
    1360  *        1)  12 Mbps
    1361  *        2)  18 Mbps
    1362  *        3)  24 Mbps
    1363  *        4)  36 Mbps
    1364  *        5)  48 Mbps
    1365  *        6)  54 Mbps
    1366  *        7)  60 Mbps
    1367  *
    1368  *  4-3:  0)  Single stream (SISO)
    1369  *        1)  Dual stream (MIMO)
    1370  *        2)  Triple stream (MIMO)
    1371  *
    1372  *    5:  Value of 0x20 in bits 7:0 indicates 6 Mbps HT40 duplicate data
    1373  *
    1374  * Legacy OFDM rate format for bits 7:0 (bit 8 must be "0", bit 9 "0"):
    1375  *  3-0:  0xD)   6 Mbps
    1376  *        0xF)   9 Mbps
    1377  *        0x5)  12 Mbps
    1378  *        0x7)  18 Mbps
    1379  *        0x9)  24 Mbps
    1380  *        0xB)  36 Mbps
    1381  *        0x1)  48 Mbps
    1382  *        0x3)  54 Mbps
    1383  *
    1384  * Legacy CCK rate format for bits 7:0 (bit 8 must be "0", bit 9 "1"):
    1385  *  6-0:   10)  1 Mbps
    1386  *         20)  2 Mbps
    1387  *         55)  5.5 Mbps
    1388  *        110)  11 Mbps
    1389  *
    1390  */
     1139    uint8_t     rate;
     1140    uint8_t     rflags;
     1141    uint16_t    xrflags;
    13911142    uint16_t    len;
    13921143    uint16_t    reserve3;
    13931144} __packed;
    struct iwn_rx_ht_phy_stats {  
    15091260    uint32_t    good_ampdu_crc32;
    15101261    uint32_t    ampdu;
    15111262    uint32_t    fragment;
    1512     uint32_t    unsupport_mcs;
     1263    uint32_t    reserved;
    15131264} __packed;
    15141265
    15151266struct iwn_rx_stats {
    struct iwn_rx_stats {  
    15191270    struct iwn_rx_ht_phy_stats  ht;
    15201271} __packed;
    15211272
    1522 struct iwn_rx_general_stats_bt {
    1523     struct iwn_rx_general_stats common;
    1524     /* additional stats for bt */
    1525     uint32_t num_bt_kills;
    1526     uint32_t reserved[2];
    1527 } __packed;
    1528 
    1529 struct iwn_rx_stats_bt {
    1530     struct iwn_rx_phy_stats     ofdm;
    1531     struct iwn_rx_phy_stats     cck;
    1532     struct iwn_rx_general_stats_bt  general_bt;
    1533     struct iwn_rx_ht_phy_stats  ht;
    1534 } __packed;
    1535 
    15361273struct iwn_tx_stats {
    15371274    uint32_t    preamble;
    15381275    uint32_t    rx_detected;
    struct iwn_tx_stats {  
    15441281    uint32_t    exp_ack;
    15451282    uint32_t    ack;
    15461283    uint32_t    msdu;
    1547     uint32_t    burst_err1;
     1284    uint32_t    busrt_err1;
    15481285    uint32_t    burst_err2;
    15491286    uint32_t    cts_collision;
    15501287    uint32_t    ack_collision;
    struct iwn_tx_stats {  
    15581295    uint32_t    underrun;
    15591296    uint32_t    bt_ht_kill;
    15601297    uint32_t    rx_ba_resp;
    1561     /*
    1562      * 6000 series only - LSB=ant A, ant B, ant C, MSB=reserved
    1563      * TX power on chain in 1/2 dBm.
    1564      */
    1565     uint32_t    tx_power;
    1566     uint32_t    reserved[1];
     1298    uint32_t    reserved[2];
    15671299} __packed;
    15681300
    15691301struct iwn_general_stats {
    1570     uint32_t    temp;       /* radio temperature */
    1571     uint32_t    temp_m;     /* radio voltage */
     1302    uint32_t    temp;
     1303    uint32_t    temp_m;
    15721304    uint32_t    burst_check;
    15731305    uint32_t    burst;
    1574     uint32_t    wait_for_silence_timeout_cnt;
    1575     uint32_t    reserved1[3];
     1306    uint32_t    reserved1[4];
    15761307    uint32_t    sleep;
    15771308    uint32_t    slot_out;
    15781309    uint32_t    slot_idle;
    struct iwn_general_stats {  
    15831314    uint32_t    probe;
    15841315    uint32_t    reserved2[2];
    15851316    uint32_t    rx_enabled;
    1586     /*
    1587      * This is the number of times we have to re-tune
    1588      * in order to get out of bad PHY status.
    1589      */
    1590     uint32_t    num_of_sos_states;
     1317    uint32_t    reserved3[3];
    15911318} __packed;
    15921319
    15931320struct iwn_stats {
    struct iwn_stats {  
    15951322    struct iwn_rx_stats     rx;
    15961323    struct iwn_tx_stats     tx;
    15971324    struct iwn_general_stats    general;
    1598     uint32_t            reserved1[2];
    15991325} __packed;
    16001326
    1601 struct iwn_bt_activity_stats {
    1602     /* Tx statistics */
    1603     uint32_t hi_priority_tx_req_cnt;
    1604     uint32_t hi_priority_tx_denied_cnt;
    1605     uint32_t lo_priority_tx_req_cnt;
    1606     uint32_t lo_priority_tx_denied_cnt;
    1607     /* Rx statistics */
    1608     uint32_t hi_priority_rx_req_cnt;
    1609     uint32_t hi_priority_rx_denied_cnt;
    1610     uint32_t lo_priority_rx_req_cnt;
    1611     uint32_t lo_priority_rx_denied_cnt;
    1612 } __packed;
    1613 
    1614 struct iwn_stats_bt {
    1615     uint32_t            flags;
    1616     struct iwn_rx_stats_bt      rx_bt;
    1617     struct iwn_tx_stats     tx;
    1618     struct iwn_general_stats    general;
    1619     struct iwn_bt_activity_stats    activity;
    1620     uint32_t            reserved1[2];
    1621 };
    16221327
    16231328/* Firmware error dump. */
    16241329struct iwn_fw_dump {
    struct iwn_fw_tlv {  
    16561361#define IWN_FW_TLV_INIT_DATA        4
    16571362#define IWN_FW_TLV_BOOT_TEXT        5
    16581363#define IWN_FW_TLV_PBREQ_MAXLEN     6
    1659 #define IWN_FW_TLV_PAN          7
    1660 #define IWN_FW_TLV_RUNT_EVTLOG_PTR  8
    1661 #define IWN_FW_TLV_RUNT_EVTLOG_SIZE 9
    1662 #define IWN_FW_TLV_RUNT_ERRLOG_PTR  10
    1663 #define IWN_FW_TLV_INIT_EVTLOG_PTR  11
    1664 #define IWN_FW_TLV_INIT_EVTLOG_SIZE 12
    1665 #define IWN_FW_TLV_INIT_ERRLOG_PTR  13
    16661364#define IWN_FW_TLV_ENH_SENS     14
    16671365#define IWN_FW_TLV_PHY_CALIB        15
    1668 #define IWN_FW_TLV_WOWLAN_INST      16
    1669 #define IWN_FW_TLV_WOWLAN_DATA      17
    1670 #define IWN_FW_TLV_FLAGS        18
    16711366
    16721367    uint16_t    alt;
    16731368    uint32_t    len;
    struct iwn_fw_tlv {  
    16821377#define IWN5000_FWSZ        IWN5000_FW_TEXT_MAXSZ
    16831378
    16841379/*
    1685  * Microcode flags TLV (18.)
    1686  */
    1687 
    1688 /**
    1689  * enum iwn_ucode_tlv_flag - ucode API flags
    1690  * @IWN_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously
    1691  *      was a separate TLV but moved here to save space.
    1692  * @IWN_UCODE_TLV_FLAGS_NEWSCAN: new uCode scan behaviour on hidden SSID,
    1693  *      treats good CRC threshold as a boolean
    1694  * @IWN_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w).
    1695  * @IWN_UCODE_TLV_FLAGS_P2P: This uCode image supports P2P.
    1696  * @IWN_UCODE_TLV_FLAGS_DW_BC_TABLE: The SCD byte count table is in DWORDS
    1697  * @IWN_UCODE_TLV_FLAGS_UAPSD: This uCode image supports uAPSD
    1698  * @IWN_UCODE_TLV_FLAGS_SHORT_BL: 16 entries of black list instead of 64 in scan
    1699  *      offload profile config command.
    1700  * @IWN_UCODE_TLV_FLAGS_RX_ENERGY_API: supports rx signal strength api
    1701  * @IWN_UCODE_TLV_FLAGS_TIME_EVENT_API_V2: using the new time event API.
    1702  * @IWN_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS: D3 image supports up to six
    1703  *      (rather than two) IPv6 addresses
    1704  * @IWN_UCODE_TLV_FLAGS_BF_UPDATED: new beacon filtering API
    1705  * @IWN_UCODE_TLV_FLAGS_NO_BASIC_SSID: not sending a probe with the SSID element
    1706  *      from the probe request template.
    1707  * @IWN_UCODE_TLV_FLAGS_D3_CONTINUITY_API: modified D3 API to allow keeping
    1708  *      connection when going back to D0
    1709  * @IWN_UCODE_TLV_FLAGS_NEW_NSOFFL_SMALL: new NS offload (small version)
    1710  * @IWN_UCODE_TLV_FLAGS_NEW_NSOFFL_LARGE: new NS offload (large version)
    1711  * @IWN_UCODE_TLV_FLAGS_SCHED_SCAN: this uCode image supports scheduled scan.
    1712  * @IWN_UCODE_TLV_FLAGS_STA_KEY_CMD: new ADD_STA and ADD_STA_KEY command API
    1713  * @IWN_UCODE_TLV_FLAGS_DEVICE_PS_CMD: support device wide power command
    1714  *      containing CAM (Continuous Active Mode) indication.
    1715  */
    1716 enum iwn_ucode_tlv_flag {
    1717     IWN_UCODE_TLV_FLAGS_PAN         = (1 << 0),
    1718     IWN_UCODE_TLV_FLAGS_NEWSCAN     = (1 << 1),
    1719     IWN_UCODE_TLV_FLAGS_MFP         = (1 << 2),
    1720     IWN_UCODE_TLV_FLAGS_P2P         = (1 << 3),
    1721     IWN_UCODE_TLV_FLAGS_DW_BC_TABLE     = (1 << 4),
    1722     IWN_UCODE_TLV_FLAGS_NEWBT_COEX      = (1 << 5),
    1723     IWN_UCODE_TLV_FLAGS_UAPSD       = (1 << 6),
    1724     IWN_UCODE_TLV_FLAGS_SHORT_BL        = (1 << 7),
    1725     IWN_UCODE_TLV_FLAGS_RX_ENERGY_API   = (1 << 8),
    1726     IWN_UCODE_TLV_FLAGS_TIME_EVENT_API_V2   = (1 << 9),
    1727     IWN_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS = (1 << 10),
    1728     IWN_UCODE_TLV_FLAGS_BF_UPDATED      = (1 << 11),
    1729     IWN_UCODE_TLV_FLAGS_NO_BASIC_SSID   = (1 << 12),
    1730     IWN_UCODE_TLV_FLAGS_D3_CONTINUITY_API   = (1 << 14),
    1731     IWN_UCODE_TLV_FLAGS_NEW_NSOFFL_SMALL    = (1 << 15),
    1732     IWN_UCODE_TLV_FLAGS_NEW_NSOFFL_LARGE    = (1 << 16),
    1733     IWN_UCODE_TLV_FLAGS_SCHED_SCAN      = (1 << 17),
    1734     IWN_UCODE_TLV_FLAGS_STA_KEY_CMD     = (1 << 19),
    1735     IWN_UCODE_TLV_FLAGS_DEVICE_PS_CMD   = (1 << 20),
    1736 };
    1737 
    1738 /*
    17391380 * Offsets into EEPROM.
    17401381 */
    17411382#define IWN_EEPROM_MAC      0x015
    enum iwn_ucode_tlv_flag {  
    17551396#define IWN4965_EEPROM_VOLTAGE  0x0e9
    17561397#define IWN4965_EEPROM_BANDS    0x0ea
    17571398/* Indirect offsets. */
    1758 #define IWN5000_EEPROM_NO_HT40  0x000
    17591399#define IWN5000_EEPROM_DOMAIN   0x001
    17601400#define IWN5000_EEPROM_BAND1    0x004
    17611401#define IWN5000_EEPROM_BAND2    0x013
    enum iwn_ucode_tlv_flag {  
    17631403#define IWN5000_EEPROM_BAND4    0x02e
    17641404#define IWN5000_EEPROM_BAND5    0x03a
    17651405#define IWN5000_EEPROM_BAND6    0x041
    1766 #define IWN6000_EEPROM_BAND6    0x040
    17671406#define IWN5000_EEPROM_BAND7    0x049
    17681407#define IWN6000_EEPROM_ENHINFO  0x054
    17691408#define IWN5000_EEPROM_CRYSTAL  0x128
    struct iwn_eeprom_chan {  
    17931432} __packed;
    17941433
    17951434struct iwn_eeprom_enhinfo {
    1796     uint8_t     flags;
    1797 #define IWN_ENHINFO_VALID   0x01
    1798 #define IWN_ENHINFO_5GHZ    0x02
    1799 #define IWN_ENHINFO_OFDM    0x04
    1800 #define IWN_ENHINFO_HT40    0x08
    1801 #define IWN_ENHINFO_HTAP    0x10
    1802 #define IWN_ENHINFO_RES1    0x20
    1803 #define IWN_ENHINFO_RES2    0x40
    1804 #define IWN_ENHINFO_COMMON  0x80
    1805 
    1806     uint8_t     chan;
     1435    uint16_t    chan;
    18071436    int8_t      chain[3];   /* max power in half-dBm */
    18081437    uint8_t     reserved;
    18091438    int8_t      mimo2;      /* max power in half-dBm */
    static const uint32_t iwn5000_regulatory_bands[IWN_NBANDS] = {  
    18571486    IWN5000_EEPROM_BAND7
    18581487};
    18591488
    1860 static const uint32_t iwn6000_regulatory_bands[IWN_NBANDS] = {
    1861     IWN5000_EEPROM_BAND1,
    1862     IWN5000_EEPROM_BAND2,
    1863     IWN5000_EEPROM_BAND3,
    1864     IWN5000_EEPROM_BAND4,
    1865     IWN5000_EEPROM_BAND5,
    1866     IWN6000_EEPROM_BAND6,
    1867     IWN5000_EEPROM_BAND7
    1868 };
    1869 
    1870 static const uint32_t iwn1000_regulatory_bands[IWN_NBANDS] = {
    1871     IWN5000_EEPROM_BAND1,
    1872     IWN5000_EEPROM_BAND2,
    1873     IWN5000_EEPROM_BAND3,
    1874     IWN5000_EEPROM_BAND4,
    1875     IWN5000_EEPROM_BAND5,
    1876     IWN5000_EEPROM_BAND6,
    1877     IWN5000_EEPROM_NO_HT40,
    1878 };
    1879 
    1880 static const uint32_t iwn2030_regulatory_bands[IWN_NBANDS] = {
    1881     IWN5000_EEPROM_BAND1,
    1882     IWN5000_EEPROM_BAND2,
    1883     IWN5000_EEPROM_BAND3,
    1884     IWN5000_EEPROM_BAND4,
    1885     IWN5000_EEPROM_BAND5,
    1886     IWN6000_EEPROM_BAND6,
    1887     IWN5000_EEPROM_BAND7
    1888 };
    1889 
    18901489#define IWN_CHAN_BANDS_COUNT     7
    18911490#define IWN_MAX_CHAN_PER_BAND   14
    18921491static const struct iwn_chan_band {
    static const struct iwn_chan_band {  
    19061505    { 11, { 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157 } }
    19071506};
    19081507
    1909 static const uint8_t iwn_bss_ac_to_queue[] = {
    1910     2, 3, 1, 0,
    1911 };
    1912 
    1913 static const uint8_t iwn_pan_ac_to_queue[] = {
    1914     5, 4, 6, 7,
    1915 };
    1916 #define IWN1000_OTP_NBLOCKS 3
    1917 #define IWN6000_OTP_NBLOCKS 4
     1508#define IWN1000_OTP_NBLOCKS 3
     1509#define IWN6000_OTP_NBLOCKS 4
    19181510#define IWN6050_OTP_NBLOCKS 7
    19191511
    19201512/* HW rate indices. */
    19211513#define IWN_RIDX_CCK1   0
    19221514#define IWN_RIDX_OFDM6  4
    19231515
    1924 #define IWN4965_MAX_PWR_INDEX   107
    1925 #define IWN_POWERSAVE_LVL_NONE          0
    1926 #define IWN_POWERSAVE_LVL_VOIP_COMPATIBLE   1
    1927 #define IWN_POWERSAVE_LVL_MAX           5
    1928 
    1929 #define IWN_POWERSAVE_LVL_DEFAULT   IWN_POWERSAVE_LVL_NONE
     1516static const struct iwn_rate {
     1517    uint8_t rate;
     1518    uint8_t plcp;
     1519    uint8_t flags;
     1520} iwn_rates[IWN_RIDX_MAX + 1] = {
     1521    {   2,  10, IWN_RFLAG_CCK },
     1522    {   4,  20, IWN_RFLAG_CCK },
     1523    {  11,  55, IWN_RFLAG_CCK },
     1524    {  22, 110, IWN_RFLAG_CCK },
     1525    {  12, 0xd, 0 },
     1526    {  18, 0xf, 0 },
     1527    {  24, 0x5, 0 },
     1528    {  36, 0x7, 0 },
     1529    {  48, 0x9, 0 },
     1530    {  72, 0xb, 0 },
     1531    {  96, 0x1, 0 },
     1532    { 108, 0x3, 0 },
     1533    { 120, 0x3, 0 }
     1534};
    19301535
    1931 /* DTIM value to pass in for IWN_POWERSAVE_LVL_VOIP_COMPATIBLE */
    1932 #define IWN_POWERSAVE_DTIM_VOIP_COMPATIBLE  2
     1536#define IWN4965_MAX_PWR_INDEX   107
    19331537
    19341538/*
    19351539 * RF Tx gain values from highest to lowest power (values obtained from
    struct iwn_sensitivity_limits {  
    20471651    uint32_t    min_energy_cck;
    20481652    uint32_t    energy_cck;
    20491653    uint32_t    energy_ofdm;
    2050     uint32_t    barker_mrc;
    20511654};
    20521655
    20531656/*
    static const struct iwn_sensitivity_limits iwn4965_sensitivity_limits = {  
    20621665    200, 400,
    20631666     97,
    20641667    100,
    2065     100,
    2066     390
     1668    100
    20671669};
    20681670
    20691671static const struct iwn_sensitivity_limits iwn5000_sensitivity_limits = {
    static const struct iwn_sensitivity_limits iwn5000_sensitivity_limits = {  
    20751677    170, 400,
    20761678     95,
    20771679     95,
    2078      95,
    2079      390
     1680     95
    20801681};
    20811682
    20821683static const struct iwn_sensitivity_limits iwn5150_sensitivity_limits = {
    static const struct iwn_sensitivity_limits iwn5150_sensitivity_limits = {  
    20881689    170, 400,
    20891690     95,
    20901691     95,
    2091      95,
    2092      390,
     1692     95
    20931693};
    20941694
    20951695static const struct iwn_sensitivity_limits iwn1000_sensitivity_limits = {
    static const struct iwn_sensitivity_limits iwn1000_sensitivity_limits = {  
    21011701    170, 400,
    21021702     95,
    21031703     95,
    2104      95,
    2105      390,
     1704     95
    21061705};
    21071706
    21081707static const struct iwn_sensitivity_limits iwn6000_sensitivity_limits = {
    static const struct iwn_sensitivity_limits iwn6000_sensitivity_limits = {  
    21141713    160, 310,
    21151714     97,
    21161715     97,
    2117     100,
    2118     390
    2119 };
    2120 
    2121 static const struct iwn_sensitivity_limits iwn6235_sensitivity_limits = {
    2122     105, 110,
    2123     192, 232,
    2124      80, 145,
    2125     128, 232,
    2126     125, 175,
    2127     160, 310,
    2128     100,
    2129     110,
    2130     110,
    2131     336
    2132 };
    2133 
    2134 
    2135 /* Get value from linux kernel 3.2.+ in Drivers/net/wireless/iwlwifi/iwl-2000.c*/
    2136 static const struct iwn_sensitivity_limits iwn2030_sensitivity_limits = {
    2137     105,110,
    2138     128,232,
    2139     80,145,
    2140     128,232,
    2141     125,175,
    2142     160,310,
    2143     97,
    2144     97,
    2145     110
     1716    100
    21461717};
    21471718
    21481719/* Map TID to TX scheduler's FIFO. */
    static const char * const iwn_fw_errmsg[] = {  
    22281799#define IWN_BARRIER_READ_WRITE(sc)                  \
    22291800    bus_space_barrier((sc)->sc_st, (sc)->sc_sh, 0, (sc)->sc_sz, \
    22301801        BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE)
    2231 
    2232 #endif  /* __IF_IWNREG_H__ */
  • src/add-ons/kernel/drivers/network/wlan/iprowifi4965/dev/iwn/if_iwnvar.h

    diff --git a/src/add-ons/kernel/drivers/network/wlan/iprowifi4965/dev/iwn/if_iwnvar.h b/src/add-ons/kernel/drivers/network/wlan/iprowifi4965/dev/iwn/if_iwnvar.h
    index bcc01b2..e53a5b2 100644
    a b  
    22/*  $OpenBSD: if_iwnvar.h,v 1.18 2010/04/30 16:06:46 damien Exp $   */
    33
    44/*-
    5  * Copyright (c) 2013 Cedric GROSS <cg@cgross.info>
    6  * Copyright (c) 2011 Intel Corporation
    75 * Copyright (c) 2007, 2008
    86 *  Damien Bergamini <damien.bergamini@free.fr>
    97 * Copyright (c) 2008 Sam Leffler, Errno Consulting
     
    2018 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
    2119 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
    2220 */
    23 enum iwn_rxon_ctx_id {
    24         IWN_RXON_BSS_CTX,
    25         IWN_RXON_PAN_CTX,
    26         IWN_NUM_RXON_CTX
    27 };
    28 
    29 struct iwn_pan_slot {
    30     uint16_t    time;
    31     uint8_t     type;
    32     uint8_t     reserved;
    33 } __packed;
    34 
    35 struct iwn_pan_params_cmd {
    36     uint16_t flags;
    37 #define IWN_PAN_PARAMS_FLG_SLOTTED_MODE (1 << 3)
    38 
    39     uint8_t reserved;
    40     uint8_t num_slots;
    41     struct iwn_pan_slot slots[10];
    42 } __packed;
    43 
    44 struct iwn_led_mode
    45 {
    46     uint8_t     led_cur_mode;
    47     uint64_t    led_cur_bt;
    48     uint64_t    led_last_bt;
    49     uint64_t    led_cur_tpt;
    50     uint64_t    led_last_tpt;
    51     uint64_t    led_bt_diff;
    52     int     led_cur_time;
    53     int     led_last_time;
    54 };
    5521
    5622struct iwn_rx_radiotap_header {
    5723    struct ieee80211_radiotap_header wr_ihdr;
    struct iwn_tx_ring {  
    11278    int         qid;
    11379    int         queued;
    11480    int         cur;
    115     int         read;
    11681};
    11782
    11883struct iwn_softc;
    struct iwn_node {  
    136101    struct  ieee80211_node      ni; /* must be the first */
    137102    uint16_t            disable_tid;
    138103    uint8_t             id;
    139     struct {
    140         uint64_t        bitmap;
    141         int         startidx;
    142         int         nframes;
    143     } agg[IEEE80211_TID_SIZE];
     104    uint8_t             ridx[IEEE80211_RATE_MAXSIZE];
    144105};
    145106
    146107struct iwn_calib_state {
    struct iwn_calib_state {  
    163124    uint32_t    bad_plcp_cck;
    164125    uint32_t    fa_cck;
    165126    uint32_t    low_fa;
    166     uint32_t    bad_plcp_ht;
    167127    uint8_t     cck_state;
    168128#define IWN_CCK_STATE_INIT  0
    169129#define IWN_CCK_STATE_LOFA  1
    struct iwn_ops {  
    214174                int);
    215175    void        (*tx_done)(struct iwn_softc *, struct iwn_rx_desc *,
    216176                struct iwn_rx_data *);
     177#if 0   /* HT */
    217178    void        (*ampdu_tx_start)(struct iwn_softc *,
    218                 struct ieee80211_node *, int, uint8_t, uint16_t);
    219     void        (*ampdu_tx_stop)(struct iwn_softc *, int, uint8_t,
     179                struct ieee80211_node *, uint8_t, uint16_t);
     180    void        (*ampdu_tx_stop)(struct iwn_softc *, uint8_t,
    220181                uint16_t);
     182#endif
    221183};
    222184
    223185struct iwn_vap {
    struct iwn_vap {  
    226188
    227189    int         (*iv_newstate)(struct ieee80211vap *,
    228190                    enum ieee80211_state, int);
    229     int         ctx;
    230     int         beacon_int;
    231     uint8_t     macaddr[IEEE80211_ADDR_LEN];
    232 
    233191};
    234192#define IWN_VAP(_vap)   ((struct iwn_vap *)(_vap))
    235193
    struct iwn_softc {  
    249207#define IWN_FLAG_HAS_11N    (1 << 6)
    250208#define IWN_FLAG_ENH_SENS   (1 << 7)
    251209#define IWN_FLAG_ADV_BTCOEX (1 << 8)
    252 #define IWN_FLAG_PAN_SUPPORT    (1 << 9)
    253 #define IWN_FLAG_BTCOEX     (1 << 10)
    254210
    255211    uint8_t         hw_type;
    256     /* subdevice_id used to adjust configuration */
    257     uint16_t        subdevice_id;
    258212
    259213    struct iwn_ops      ops;
    260214    const char      *fwname;
    261215    const struct iwn_sensitivity_limits
    262216                *limits;
    263217    int         ntxqs;
    264     int         firstaggqueue;
    265218    int         ndmachnls;
    266219    uint8_t         broadcast_id;
    267220    int         rxonsz;
    struct iwn_softc {  
    296249    struct iwn_tx_ring  txq[IWN5000_NTXQUEUES];
    297250    struct iwn_rx_ring  rxq;
    298251
     252    int         mem_rid;
    299253    struct resource     *mem;
    300254    bus_space_tag_t     sc_st;
    301255    bus_space_handle_t  sc_sh;
     256    int         irq_rid;
    302257    struct resource     *irq;
    303258    void            *sc_ih;
    304259    bus_size_t      sc_sz;
    struct iwn_softc {  
    309264    struct task     sc_radioon_task;
    310265    struct task     sc_radiooff_task;
    311266
    312     /* Calibration information */
    313267    struct callout      calib_to;
    314268    int         calib_cnt;
    315269    struct iwn_calib_state  calib;
    316     int         last_calib_ticks;
    317270    struct callout      watchdog_to;
    318     struct callout      ct_kill_exit_to;
     271
    319272    struct iwn_fw_info  fw;
    320     struct iwn_calib_info   calibcmd[IWN5000_PHY_CALIB_MAX_RESULT];
     273    struct iwn_calib_info   calibcmd[5];
    321274    uint32_t        errptr;
    322275
    323276    struct iwn_rx_stat  last_rx_stat;
    324277    int         last_rx_valid;
    325278    struct iwn_ucode_info   ucode_info;
    326     struct iwn_rxon     rx_on[IWN_NUM_RXON_CTX];
    327     struct iwn_rxon     *rxon;
    328     int         ctx;
    329     struct ieee80211vap *ivap[IWN_NUM_RXON_CTX];
    330 
    331     /* General statistics */
    332     /*
    333      * The statistics are reset after each channel
    334      * change.  So it may be zeroed after things like
    335      * a background scan.
    336      *
    337      * So for now, this is just a cheap hack to
    338      * expose the last received statistics dump
    339      * via an ioctl().  Later versions of this
    340      * could expose the last 'n' messages, or just
    341      * provide a pipeline for the firmware responses
    342      * via something like BPF.
    343      */
    344     struct iwn_stats    last_stat;
    345     int         last_stat_valid;
    346 
    347     uint8_t         uc_scan_progress;
     279    struct iwn_rxon     rxon;
    348280    uint32_t        rawtemp;
    349281    int         temp;
    350282    int         noise;
    struct iwn_softc {  
    359291    char            eeprom_domain[4];
    360292    uint32_t        eeprom_crystal;
    361293    int16_t         eeprom_temp;
    362     int16_t         eeprom_temp_high;
    363294    int16_t         eeprom_voltage;
    364295    int8_t          maxpwr2GHz;
    365296    int8_t          maxpwr5GHz;
    366297    int8_t          maxpwr[IEEE80211_CHAN_MAX];
    367 
    368     uint32_t        tlv_feature_flags;
     298    int8_t          enh_maxpwr[35];
    369299
    370300    int32_t         temp_off;
    371301    uint32_t        int_mask;
    struct iwn_softc {  
    376306    uint8_t         chainmask;
    377307
    378308    int         sc_tx_timer;
    379     int         sc_scan_timer;
    380 
    381     /* Are we doing a scan? */
    382     int         sc_is_scanning;
    383 
    384     struct ieee80211_tx_ampdu *qid2tap[IWN5000_NTXQUEUES];
    385 
    386     int         (*sc_ampdu_rx_start)(struct ieee80211_node *,
    387                     struct ieee80211_rx_ampdu *, int, int, int);
    388     void            (*sc_ampdu_rx_stop)(struct ieee80211_node *,
    389                     struct ieee80211_rx_ampdu *);
    390     int         (*sc_addba_request)(struct ieee80211_node *,
    391                     struct ieee80211_tx_ampdu *, int, int, int);
    392     int         (*sc_addba_response)(struct ieee80211_node *,
    393                     struct ieee80211_tx_ampdu *, int, int, int);
    394     void            (*sc_addba_stop)(struct ieee80211_node *,
    395                     struct ieee80211_tx_ampdu *);
    396 
    397     struct  iwn_led_mode sc_led;
    398309
    399310    struct iwn_rx_radiotap_header sc_rxtap;
    400311    struct iwn_tx_radiotap_header sc_txtap;
    401 
    402     /* The power save level originally configured by user */
    403     int         desired_pwrsave_level;
    404 
    405     /*
    406      * The current power save level, this may differ from the
    407      * configured value due to thermal throttling etc.
    408      */
    409     int         current_pwrsave_level;
    410 
    411     /* For specific params */
    412     const struct iwn_base_params *base_params;
    413312};
    414313
    415314#define IWN_LOCK_INIT(_sc) \