[BACK]Return to if_iwn.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / dev / pci

Annotation of src/sys/dev/pci/if_iwn.c, Revision 1.96

1.96    ! riastrad    1: /*     $NetBSD: if_iwn.c,v 1.95 2021/05/08 00:27:02 thorpej Exp $      */
1.72      nonaka      2: /*     $OpenBSD: if_iwn.c,v 1.135 2014/09/10 07:22:09 dcoppa Exp $     */
1.1       ober        3:
                      4: /*-
1.40      christos    5:  * Copyright (c) 2007-2010 Damien Bergamini <damien.bergamini@free.fr>
1.1       ober        6:  *
                      7:  * Permission to use, copy, modify, and distribute this software for any
                      8:  * purpose with or without fee is hereby granted, provided that the above
                      9:  * copyright notice and this permission notice appear in all copies.
                     10:  *
                     11:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
                     12:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     13:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
                     14:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     15:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                     16:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
                     17:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     18:  */
                     19:
                     20: /*
1.40      christos   21:  * Driver for Intel WiFi Link 4965 and 1000/5000/6000 Series 802.11 network
                     22:  * adapters.
1.1       ober       23:  */
1.33      christos   24: #include <sys/cdefs.h>
1.96    ! riastrad   25: __KERNEL_RCSID(0, "$NetBSD: if_iwn.c,v 1.95 2021/05/08 00:27:02 thorpej Exp $");
1.1       ober       26:
1.40      christos   27: #define IWN_USE_RBUF   /* Use local storage for RX */
                     28: #undef IWN_HWCRYPTO    /* XXX does not even compile yet */
                     29:
1.1       ober       30: #include <sys/param.h>
                     31: #include <sys/sockio.h>
1.46      christos   32: #include <sys/proc.h>
1.1       ober       33: #include <sys/mbuf.h>
                     34: #include <sys/kernel.h>
                     35: #include <sys/socket.h>
                     36: #include <sys/systm.h>
                     37: #include <sys/malloc.h>
1.67      prlw1      38: #ifdef notyetMODULE
                     39: #include <sys/module.h>
                     40: #endif
1.17      cube       41: #include <sys/mutex.h>
1.1       ober       42: #include <sys/conf.h>
                     43: #include <sys/kauth.h>
                     44: #include <sys/callout.h>
                     45:
1.40      christos   46: #include <dev/sysmon/sysmonvar.h>
                     47:
1.54      dyoung     48: #include <sys/bus.h>
1.1       ober       49: #include <machine/endian.h>
1.84      nonaka     50: #include <sys/intr.h>
1.1       ober       51:
                     52: #include <dev/pci/pcireg.h>
                     53: #include <dev/pci/pcivar.h>
                     54: #include <dev/pci/pcidevs.h>
                     55:
                     56: #include <net/bpf.h>
                     57: #include <net/if.h>
                     58: #include <net/if_arp.h>
                     59: #include <net/if_dl.h>
                     60: #include <net/if_media.h>
                     61: #include <net/if_types.h>
                     62:
                     63: #include <netinet/in.h>
                     64: #include <netinet/in_systm.h>
                     65: #include <netinet/in_var.h>
                     66: #include <net/if_ether.h>
                     67: #include <netinet/ip.h>
                     68:
                     69: #include <net80211/ieee80211_var.h>
                     70: #include <net80211/ieee80211_amrr.h>
                     71: #include <net80211/ieee80211_radiotap.h>
                     72:
                     73: #include <dev/firmload.h>
                     74:
                     75: #include <dev/pci/if_iwnreg.h>
                     76: #include <dev/pci/if_iwnvar.h>
                     77:
1.95      thorpej    78: static const struct device_compatible_entry compat_data[] = {
                     79:        { .id = PCI_ID_CODE(PCI_VENDOR_INTEL,
                     80:                PCI_PRODUCT_INTEL_WIFI_LINK_1030_1), },
                     81:
                     82:        { .id = PCI_ID_CODE(PCI_VENDOR_INTEL,
                     83:                PCI_PRODUCT_INTEL_WIFI_LINK_1030_2), },
                     84:
                     85:        { .id = PCI_ID_CODE(PCI_VENDOR_INTEL,
                     86:                PCI_PRODUCT_INTEL_WIFI_LINK_4965_1), },
                     87:
                     88:        { .id = PCI_ID_CODE(PCI_VENDOR_INTEL,
                     89:                PCI_PRODUCT_INTEL_WIFI_LINK_4965_2), },
                     90:
                     91:        { .id = PCI_ID_CODE(PCI_VENDOR_INTEL,
                     92:                PCI_PRODUCT_INTEL_WIFI_LINK_4965_3), },
                     93:
                     94:        { .id = PCI_ID_CODE(PCI_VENDOR_INTEL,
                     95:                PCI_PRODUCT_INTEL_WIFI_LINK_4965_4), },
                     96:
                     97:        { .id = PCI_ID_CODE(PCI_VENDOR_INTEL,
                     98:                PCI_PRODUCT_INTEL_WIFI_LINK_5100_1), },
                     99:
                    100:        { .id = PCI_ID_CODE(PCI_VENDOR_INTEL,
                    101:                PCI_PRODUCT_INTEL_WIFI_LINK_5100_2), },
                    102:
                    103:        { .id = PCI_ID_CODE(PCI_VENDOR_INTEL,
                    104:                PCI_PRODUCT_INTEL_WIFI_LINK_5150_1), },
                    105:
                    106:        { .id = PCI_ID_CODE(PCI_VENDOR_INTEL,
                    107:                PCI_PRODUCT_INTEL_WIFI_LINK_5150_2), },
                    108:
                    109:        { .id = PCI_ID_CODE(PCI_VENDOR_INTEL,
                    110:                PCI_PRODUCT_INTEL_WIFI_LINK_5300_1), },
                    111:
                    112:        { .id = PCI_ID_CODE(PCI_VENDOR_INTEL,
                    113:                PCI_PRODUCT_INTEL_WIFI_LINK_5300_2), },
                    114:
                    115:        { .id = PCI_ID_CODE(PCI_VENDOR_INTEL,
                    116:                PCI_PRODUCT_INTEL_WIFI_LINK_5350_1), },
                    117:
                    118:        { .id = PCI_ID_CODE(PCI_VENDOR_INTEL,
                    119:                PCI_PRODUCT_INTEL_WIFI_LINK_5350_2), },
                    120:
                    121:        { .id = PCI_ID_CODE(PCI_VENDOR_INTEL,
                    122:                PCI_PRODUCT_INTEL_WIFI_LINK_1000_1), },
                    123:
                    124:        { .id = PCI_ID_CODE(PCI_VENDOR_INTEL,
                    125:                PCI_PRODUCT_INTEL_WIFI_LINK_1000_2), },
                    126:
                    127:        { .id = PCI_ID_CODE(PCI_VENDOR_INTEL,
                    128:                PCI_PRODUCT_INTEL_WIFI_LINK_6000_3X3_1), },
                    129:
                    130:        { .id = PCI_ID_CODE(PCI_VENDOR_INTEL,
                    131:                PCI_PRODUCT_INTEL_WIFI_LINK_6000_3X3_2), },
                    132:
                    133:        { .id = PCI_ID_CODE(PCI_VENDOR_INTEL,
                    134:                PCI_PRODUCT_INTEL_WIFI_LINK_6000_IPA_1), },
                    135:
                    136:        { .id = PCI_ID_CODE(PCI_VENDOR_INTEL,
                    137:                PCI_PRODUCT_INTEL_WIFI_LINK_6000_IPA_2), },
                    138:
                    139:        { .id = PCI_ID_CODE(PCI_VENDOR_INTEL,
                    140:                PCI_PRODUCT_INTEL_WIFI_LINK_6050_2X2_1), },
                    141:
                    142:        { .id = PCI_ID_CODE(PCI_VENDOR_INTEL,
                    143:                PCI_PRODUCT_INTEL_WIFI_LINK_6050_2X2_2), },
                    144:
                    145:        { .id = PCI_ID_CODE(PCI_VENDOR_INTEL,
                    146:                PCI_PRODUCT_INTEL_WIFI_LINK_6005_2X2_1), },
                    147:
                    148:        { .id = PCI_ID_CODE(PCI_VENDOR_INTEL,
                    149:                PCI_PRODUCT_INTEL_WIFI_LINK_6005_2X2_2), },
                    150:
                    151:        { .id = PCI_ID_CODE(PCI_VENDOR_INTEL,
                    152:                PCI_PRODUCT_INTEL_WIFI_LINK_6230_1), },
                    153:
                    154:        { .id = PCI_ID_CODE(PCI_VENDOR_INTEL,
                    155:                PCI_PRODUCT_INTEL_WIFI_LINK_6230_2), },
                    156:
                    157:        { .id = PCI_ID_CODE(PCI_VENDOR_INTEL,
                    158:                PCI_PRODUCT_INTEL_WIFI_LINK_6235), },
                    159:
                    160:        { .id = PCI_ID_CODE(PCI_VENDOR_INTEL,
                    161:                PCI_PRODUCT_INTEL_WIFI_LINK_6235_2), },
                    162:
                    163:        { .id = PCI_ID_CODE(PCI_VENDOR_INTEL,
                    164:                PCI_PRODUCT_INTEL_WIFI_LINK_100_1), },
                    165:
                    166:        { .id = PCI_ID_CODE(PCI_VENDOR_INTEL,
                    167:                PCI_PRODUCT_INTEL_WIFI_LINK_100_2), },
                    168:
                    169:        { .id = PCI_ID_CODE(PCI_VENDOR_INTEL,
                    170:                PCI_PRODUCT_INTEL_WIFI_LINK_130_1), },
                    171:
                    172:        { .id = PCI_ID_CODE(PCI_VENDOR_INTEL,
                    173:                PCI_PRODUCT_INTEL_WIFI_LINK_130_2), },
                    174:
                    175:        { .id = PCI_ID_CODE(PCI_VENDOR_INTEL,
                    176:                PCI_PRODUCT_INTEL_WIFI_LINK_2230_1), },
                    177:
                    178:        { .id = PCI_ID_CODE(PCI_VENDOR_INTEL,
                    179:                PCI_PRODUCT_INTEL_WIFI_LINK_2230_2), },
                    180:
                    181:        { .id = PCI_ID_CODE(PCI_VENDOR_INTEL,
                    182:                PCI_PRODUCT_INTEL_WIFI_LINK_2200_1), },
                    183:
                    184:        { .id = PCI_ID_CODE(PCI_VENDOR_INTEL,
                    185:                PCI_PRODUCT_INTEL_WIFI_LINK_2200_2), },
                    186:
                    187:        { .id = PCI_ID_CODE(PCI_VENDOR_INTEL,
                    188:                PCI_PRODUCT_INTEL_WIFI_LINK_135_1), },
                    189:
                    190:        { .id = PCI_ID_CODE(PCI_VENDOR_INTEL,
                    191:                PCI_PRODUCT_INTEL_WIFI_LINK_135_2), },
                    192:
                    193:        { .id = PCI_ID_CODE(PCI_VENDOR_INTEL,
                    194:                PCI_PRODUCT_INTEL_WIFI_LINK_105_1), },
                    195:
                    196:        { .id = PCI_ID_CODE(PCI_VENDOR_INTEL,
                    197:                PCI_PRODUCT_INTEL_WIFI_LINK_105_2), },
                    198:
                    199:        PCI_COMPAT_EOL
1.1       ober      200: };
                    201:
1.40      christos  202: static int     iwn_match(device_t , struct cfdata *, void *);
                    203: static void    iwn_attach(device_t , device_t , void *);
1.53      christos  204: static int     iwn4965_attach(struct iwn_softc *, pci_product_id_t);
                    205: static int     iwn5000_attach(struct iwn_softc *, pci_product_id_t);
1.40      christos  206: static void    iwn_radiotap_attach(struct iwn_softc *);
                    207: static int     iwn_detach(device_t , int);
                    208: #if 0
                    209: static void    iwn_power(int, void *);
                    210: #endif
                    211: static bool    iwn_resume(device_t, const pmf_qual_t *);
1.33      christos  212: static int     iwn_nic_lock(struct iwn_softc *);
                    213: static int     iwn_eeprom_lock(struct iwn_softc *);
1.40      christos  214: static int     iwn_init_otprom(struct iwn_softc *);
1.33      christos  215: static int     iwn_read_prom_data(struct iwn_softc *, uint32_t, void *, int);
                    216: static int     iwn_dma_contig_alloc(bus_dma_tag_t, struct iwn_dma_info *,
1.40      christos  217:                    void **, bus_size_t, bus_size_t);
1.33      christos  218: static void    iwn_dma_contig_free(struct iwn_dma_info *);
                    219: static int     iwn_alloc_sched(struct iwn_softc *);
                    220: static void    iwn_free_sched(struct iwn_softc *);
                    221: static int     iwn_alloc_kw(struct iwn_softc *);
                    222: static void    iwn_free_kw(struct iwn_softc *);
1.40      christos  223: static int     iwn_alloc_ict(struct iwn_softc *);
                    224: static void    iwn_free_ict(struct iwn_softc *);
1.33      christos  225: static int     iwn_alloc_fwmem(struct iwn_softc *);
                    226: static void    iwn_free_fwmem(struct iwn_softc *);
                    227: static int     iwn_alloc_rx_ring(struct iwn_softc *, struct iwn_rx_ring *);
                    228: static void    iwn_reset_rx_ring(struct iwn_softc *, struct iwn_rx_ring *);
                    229: static void    iwn_free_rx_ring(struct iwn_softc *, struct iwn_rx_ring *);
                    230: static int     iwn_alloc_tx_ring(struct iwn_softc *, struct iwn_tx_ring *,
1.40      christos  231:                    int);
1.33      christos  232: static void    iwn_reset_tx_ring(struct iwn_softc *, struct iwn_tx_ring *);
                    233: static void    iwn_free_tx_ring(struct iwn_softc *, struct iwn_tx_ring *);
1.40      christos  234: static void    iwn5000_ict_reset(struct iwn_softc *);
1.33      christos  235: static int     iwn_read_eeprom(struct iwn_softc *);
                    236: static void    iwn4965_read_eeprom(struct iwn_softc *);
1.53      christos  237:
1.40      christos  238: #ifdef IWN_DEBUG
                    239: static void    iwn4965_print_power_group(struct iwn_softc *, int);
                    240: #endif
1.33      christos  241: static void    iwn5000_read_eeprom(struct iwn_softc *);
                    242: static void    iwn_read_eeprom_channels(struct iwn_softc *, int, uint32_t);
1.40      christos  243: static void    iwn_read_eeprom_enhinfo(struct iwn_softc *);
1.33      christos  244: static struct  ieee80211_node *iwn_node_alloc(struct ieee80211_node_table *);
                    245: static void    iwn_newassoc(struct ieee80211_node *, int);
                    246: static int     iwn_media_change(struct ifnet *);
                    247: static int     iwn_newstate(struct ieee80211com *, enum ieee80211_state, int);
                    248: static void    iwn_iter_func(void *, struct ieee80211_node *);
                    249: static void    iwn_calib_timeout(void *);
1.40      christos  250: static void    iwn_rx_phy(struct iwn_softc *, struct iwn_rx_desc *,
                    251:                    struct iwn_rx_data *);
1.33      christos  252: static void    iwn_rx_done(struct iwn_softc *, struct iwn_rx_desc *,
                    253:                    struct iwn_rx_data *);
1.40      christos  254: #ifndef IEEE80211_NO_HT
                    255: static void    iwn_rx_compressed_ba(struct iwn_softc *, struct iwn_rx_desc *,
                    256:                    struct iwn_rx_data *);
                    257: #endif
1.33      christos  258: static void    iwn5000_rx_calib_results(struct iwn_softc *,
1.40      christos  259:                    struct iwn_rx_desc *, struct iwn_rx_data *);
1.33      christos  260: static void    iwn_rx_statistics(struct iwn_softc *, struct iwn_rx_desc *,
1.40      christos  261:                    struct iwn_rx_data *);
1.33      christos  262: static void    iwn4965_tx_done(struct iwn_softc *, struct iwn_rx_desc *,
1.40      christos  263:                    struct iwn_rx_data *);
1.33      christos  264: static void    iwn5000_tx_done(struct iwn_softc *, struct iwn_rx_desc *,
1.40      christos  265:                    struct iwn_rx_data *);
1.33      christos  266: static void    iwn_tx_done(struct iwn_softc *, struct iwn_rx_desc *, int,
                    267:                    uint8_t);
                    268: static void    iwn_cmd_done(struct iwn_softc *, struct iwn_rx_desc *);
                    269: static void    iwn_notif_intr(struct iwn_softc *);
                    270: static void    iwn_wakeup_intr(struct iwn_softc *);
                    271: static void    iwn_fatal_intr(struct iwn_softc *);
                    272: static int     iwn_intr(void *);
1.84      nonaka    273: static void    iwn_softintr(void *);
1.33      christos  274: static void    iwn4965_update_sched(struct iwn_softc *, int, int, uint8_t,
                    275:                    uint16_t);
                    276: static void    iwn5000_update_sched(struct iwn_softc *, int, int, uint8_t,
                    277:                    uint16_t);
1.40      christos  278: #ifdef notyet
1.33      christos  279: static void    iwn5000_reset_sched(struct iwn_softc *, int, int);
1.40      christos  280: #endif
1.33      christos  281: static int     iwn_tx(struct iwn_softc *, struct mbuf *,
                    282:                    struct ieee80211_node *, int);
                    283: static void    iwn_start(struct ifnet *);
                    284: static void    iwn_watchdog(struct ifnet *);
                    285: static int     iwn_ioctl(struct ifnet *, u_long, void *);
                    286: static int     iwn_cmd(struct iwn_softc *, int, const void *, int, int);
                    287: static int     iwn4965_add_node(struct iwn_softc *, struct iwn_node_info *,
                    288:                    int);
                    289: static int     iwn5000_add_node(struct iwn_softc *, struct iwn_node_info *,
                    290:                    int);
                    291: static int     iwn_set_link_quality(struct iwn_softc *,
                    292:                    struct ieee80211_node *);
                    293: static int     iwn_add_broadcast_node(struct iwn_softc *, int);
                    294: static void    iwn_set_led(struct iwn_softc *, uint8_t, uint8_t, uint8_t);
                    295: static int     iwn_set_critical_temp(struct iwn_softc *);
                    296: static int     iwn_set_timing(struct iwn_softc *, struct ieee80211_node *);
1.40      christos  297: static void    iwn4965_power_calibration(struct iwn_softc *, int);
1.33      christos  298: static int     iwn4965_set_txpower(struct iwn_softc *, int);
                    299: static int     iwn5000_set_txpower(struct iwn_softc *, int);
                    300: static int     iwn4965_get_rssi(const struct iwn_rx_stat *);
                    301: static int     iwn5000_get_rssi(const struct iwn_rx_stat *);
                    302: static int     iwn_get_noise(const struct iwn_rx_general_stats *);
                    303: static int     iwn4965_get_temperature(struct iwn_softc *);
                    304: static int     iwn5000_get_temperature(struct iwn_softc *);
                    305: static int     iwn_init_sensitivity(struct iwn_softc *);
                    306: static void    iwn_collect_noise(struct iwn_softc *,
                    307:                    const struct iwn_rx_general_stats *);
                    308: static int     iwn4965_init_gains(struct iwn_softc *);
                    309: static int     iwn5000_init_gains(struct iwn_softc *);
                    310: static int     iwn4965_set_gains(struct iwn_softc *);
                    311: static int     iwn5000_set_gains(struct iwn_softc *);
                    312: static void    iwn_tune_sensitivity(struct iwn_softc *,
                    313:                    const struct iwn_rx_stats *);
                    314: static int     iwn_send_sensitivity(struct iwn_softc *);
1.40      christos  315: static int     iwn_set_pslevel(struct iwn_softc *, int, int, int);
1.59      elric     316: static int     iwn5000_runtime_calib(struct iwn_softc *);
1.67      prlw1     317:
                    318: static int     iwn_config_bt_coex_bluetooth(struct iwn_softc *);
                    319: static int     iwn_config_bt_coex_prio_table(struct iwn_softc *);
                    320: static int     iwn_config_bt_coex_adv1(struct iwn_softc *);
1.72      nonaka    321: static int     iwn_config_bt_coex_adv2(struct iwn_softc *);
1.67      prlw1     322:
1.33      christos  323: static int     iwn_config(struct iwn_softc *);
1.72      nonaka    324: static uint16_t        iwn_get_active_dwell_time(struct iwn_softc *, uint16_t,
                    325:                    uint8_t);
                    326: static uint16_t        iwn_limit_dwell(struct iwn_softc *, uint16_t);
                    327: static uint16_t        iwn_get_passive_dwell_time(struct iwn_softc *, uint16_t);
1.33      christos  328: static int     iwn_scan(struct iwn_softc *, uint16_t);
                    329: static int     iwn_auth(struct iwn_softc *);
                    330: static int     iwn_run(struct iwn_softc *);
1.40      christos  331: #ifdef IWN_HWCRYPTO
                    332: static int     iwn_set_key(struct ieee80211com *, struct ieee80211_node *,
                    333:                    struct ieee80211_key *);
1.33      christos  334: static void    iwn_delete_key(struct ieee80211com *, struct ieee80211_node *,
                    335:                    struct ieee80211_key *);
                    336: #endif
1.40      christos  337: static int     iwn_wme_update(struct ieee80211com *);
1.33      christos  338: #ifndef IEEE80211_NO_HT
                    339: static int     iwn_ampdu_rx_start(struct ieee80211com *,
1.40      christos  340:                    struct ieee80211_node *, uint8_t);
1.33      christos  341: static void    iwn_ampdu_rx_stop(struct ieee80211com *,
1.40      christos  342:                    struct ieee80211_node *, uint8_t);
1.33      christos  343: static int     iwn_ampdu_tx_start(struct ieee80211com *,
1.40      christos  344:                    struct ieee80211_node *, uint8_t);
1.33      christos  345: static void    iwn_ampdu_tx_stop(struct ieee80211com *,
1.40      christos  346:                    struct ieee80211_node *, uint8_t);
1.33      christos  347: static void    iwn4965_ampdu_tx_start(struct iwn_softc *,
                    348:                    struct ieee80211_node *, uint8_t, uint16_t);
                    349: static void    iwn4965_ampdu_tx_stop(struct iwn_softc *,
                    350:                    uint8_t, uint16_t);
                    351: static void    iwn5000_ampdu_tx_start(struct iwn_softc *,
                    352:                    struct ieee80211_node *, uint8_t, uint16_t);
                    353: static void    iwn5000_ampdu_tx_stop(struct iwn_softc *,
                    354:                    uint8_t, uint16_t);
                    355: #endif
                    356: static int     iwn5000_query_calibration(struct iwn_softc *);
                    357: static int     iwn5000_send_calibration(struct iwn_softc *);
1.40      christos  358: static int     iwn5000_send_wimax_coex(struct iwn_softc *);
1.72      nonaka    359: static int     iwn6000_temp_offset_calib(struct iwn_softc *);
                    360: static int     iwn2000_temp_offset_calib(struct iwn_softc *);
1.33      christos  361: static int     iwn4965_post_alive(struct iwn_softc *);
                    362: static int     iwn5000_post_alive(struct iwn_softc *);
                    363: static int     iwn4965_load_bootcode(struct iwn_softc *, const uint8_t *,
                    364:                    int);
                    365: static int     iwn4965_load_firmware(struct iwn_softc *);
                    366: static int     iwn5000_load_firmware_section(struct iwn_softc *, uint32_t,
                    367:                    const uint8_t *, int);
1.53      christos  368: static int     iwn5000_load_firmware(struct iwn_softc *);
1.46      christos  369: static int     iwn_read_firmware_leg(struct iwn_softc *,
                    370:                    struct iwn_fw_info *);
                    371: static int     iwn_read_firmware_tlv(struct iwn_softc *,
                    372:                    struct iwn_fw_info *, uint16_t);
1.33      christos  373: static int     iwn_read_firmware(struct iwn_softc *);
                    374: static int     iwn_clock_wait(struct iwn_softc *);
1.40      christos  375: static int     iwn_apm_init(struct iwn_softc *);
1.33      christos  376: static void    iwn_apm_stop_master(struct iwn_softc *);
                    377: static void    iwn_apm_stop(struct iwn_softc *);
                    378: static int     iwn4965_nic_config(struct iwn_softc *);
                    379: static int     iwn5000_nic_config(struct iwn_softc *);
1.40      christos  380: static int     iwn_hw_prepare(struct iwn_softc *);
1.33      christos  381: static int     iwn_hw_init(struct iwn_softc *);
                    382: static void    iwn_hw_stop(struct iwn_softc *);
                    383: static int     iwn_init(struct ifnet *);
                    384: static void    iwn_stop(struct ifnet *, int);
1.40      christos  385:
                    386: /* XXX MCLGETI alternative */
                    387: static struct  mbuf *MCLGETIalt(struct iwn_softc *, int,
                    388:                    struct ifnet *, u_int);
                    389: #ifdef IWN_USE_RBUF
                    390: static struct  iwn_rbuf *iwn_alloc_rbuf(struct iwn_softc *);
                    391: static void    iwn_free_rbuf(struct mbuf *, void *, size_t, void *);
                    392: static int     iwn_alloc_rpool(struct iwn_softc *);
                    393: static void    iwn_free_rpool(struct iwn_softc *);
                    394: #endif
                    395:
1.76      nonaka    396: static void    iwn_fix_channel(struct ieee80211com *, struct mbuf *,
                    397:                    struct iwn_rx_stat *);
1.1       ober      398:
                    399: #ifdef IWN_DEBUG
                    400: #define DPRINTF(x)     do { if (iwn_debug > 0) printf x; } while (0)
                    401: #define DPRINTFN(n, x) do { if (iwn_debug >= (n)) printf x; } while (0)
1.58      elric     402: int iwn_debug = 0;
1.1       ober      403: #else
                    404: #define DPRINTF(x)
                    405: #define DPRINTFN(n, x)
                    406: #endif
1.33      christos  407:
1.8       blymn     408: CFATTACH_DECL_NEW(iwn, sizeof(struct iwn_softc), iwn_match, iwn_attach,
1.40      christos  409:        iwn_detach, NULL);
1.1       ober      410:
                    411: static int
1.29      cegger    412: iwn_match(device_t parent, cfdata_t match __unused, void *aux)
1.1       ober      413: {
1.2       ober      414:        struct pci_attach_args *pa = aux;
1.1       ober      415:
1.95      thorpej   416:        return pci_compatible_match(pa, compat_data);
1.1       ober      417: }
                    418:
                    419: static void
                    420: iwn_attach(device_t parent __unused, device_t self, void *aux)
                    421: {
                    422:        struct iwn_softc *sc = device_private(self);
                    423:        struct ieee80211com *ic = &sc->sc_ic;
                    424:        struct ifnet *ifp = &sc->sc_ec.ec_if;
                    425:        struct pci_attach_args *pa = aux;
                    426:        const char *intrstr;
1.33      christos  427:        pcireg_t memtype, reg;
1.40      christos  428:        int i, error;
1.71      christos  429:        char intrbuf[PCI_INTRSTR_LEN];
1.1       ober      430:
                    431:        sc->sc_dev = self;
1.2       ober      432:        sc->sc_pct = pa->pa_pc;
1.1       ober      433:        sc->sc_pcitag = pa->pa_tag;
1.40      christos  434:        sc->sc_dmat = pa->pa_dmat;
1.47      christos  435:        mutex_init(&sc->sc_mtx, MUTEX_DEFAULT, IPL_NONE);
1.1       ober      436:
                    437:        callout_init(&sc->calib_to, 0);
                    438:        callout_setfunc(&sc->calib_to, iwn_calib_timeout, sc);
1.8       blymn     439:
1.62      drochner  440:        pci_aprint_devinfo(pa, NULL);
1.8       blymn     441:
1.33      christos  442:        /*
                    443:         * Get the offset of the PCI Express Capability Structure in PCI
1.40      christos  444:         * Configuration Space.
1.33      christos  445:         */
                    446:        error = pci_get_capability(sc->sc_pct, sc->sc_pcitag,
                    447:            PCI_CAP_PCIEXPRESS, &sc->sc_cap_off, NULL);
                    448:        if (error == 0) {
1.73      nonaka    449:                aprint_error_dev(self,
                    450:                    "PCIe capability structure not found!\n");
1.33      christos  451:                return;
                    452:        }
1.1       ober      453:
1.33      christos  454:        /* Clear device-specific "PCI retry timeout" register (41h). */
                    455:        reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag, 0x40);
1.53      christos  456:        if (reg & 0xff00)
                    457:                pci_conf_write(sc->sc_pct, sc->sc_pcitag, 0x40, reg & ~0xff00);
1.1       ober      458:
1.83      nonaka    459:        /* Enable bus-mastering. */
1.40      christos  460:        /* XXX verify the bus-mastering is really needed (not in OpenBSD) */
1.33      christos  461:        reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag, PCI_COMMAND_STATUS_REG);
                    462:        reg |= PCI_COMMAND_MASTER_ENABLE;
                    463:        pci_conf_write(sc->sc_pct, sc->sc_pcitag, PCI_COMMAND_STATUS_REG, reg);
1.1       ober      464:
                    465:        memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, IWN_PCI_BAR0);
                    466:        error = pci_mapreg_map(pa, IWN_PCI_BAR0, memtype, 0, &sc->sc_st,
                    467:            &sc->sc_sh, NULL, &sc->sc_sz);
                    468:        if (error != 0) {
1.73      nonaka    469:                aprint_error_dev(self, "can't map mem space\n");
1.1       ober      470:                return;
                    471:        }
                    472:
1.84      nonaka    473:        sc->sc_soft_ih = softint_establish(SOFTINT_NET, iwn_softintr, sc);
                    474:        if (sc->sc_soft_ih == NULL) {
                    475:                aprint_error_dev(self, "can't establish soft interrupt\n");
                    476:                goto unmap;
                    477:        }
                    478:
1.33      christos  479:        /* Install interrupt handler. */
1.83      nonaka    480:        error = pci_intr_alloc(pa, &sc->sc_pihp, NULL, 0);
                    481:        if (error) {
                    482:                aprint_error_dev(self, "can't allocate interrupt\n");
1.84      nonaka    483:                goto failsi;
1.1       ober      484:        }
1.83      nonaka    485:        reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag, PCI_COMMAND_STATUS_REG);
                    486:        if (pci_intr_type(sc->sc_pct, sc->sc_pihp[0]) == PCI_INTR_TYPE_INTX)
                    487:                CLR(reg, PCI_COMMAND_INTERRUPT_DISABLE);
                    488:        else
                    489:                SET(reg, PCI_COMMAND_INTERRUPT_DISABLE);
                    490:        pci_conf_write(sc->sc_pct, sc->sc_pcitag, PCI_COMMAND_STATUS_REG, reg);
                    491:        intrstr = pci_intr_string(sc->sc_pct, sc->sc_pihp[0], intrbuf,
                    492:            sizeof(intrbuf));
                    493:        sc->sc_ih = pci_intr_establish_xname(sc->sc_pct, sc->sc_pihp[0],
                    494:            IPL_NET, iwn_intr, sc, device_xname(self));
1.1       ober      495:        if (sc->sc_ih == NULL) {
1.73      nonaka    496:                aprint_error_dev(self, "can't establish interrupt");
1.1       ober      497:                if (intrstr != NULL)
                    498:                        aprint_error(" at %s", intrstr);
                    499:                aprint_error("\n");
1.83      nonaka    500:                goto failia;
1.1       ober      501:        }
                    502:        aprint_normal_dev(self, "interrupting at %s\n", intrstr);
                    503:
1.53      christos  504:        /* Read hardware revision and attach. */
1.74      nonaka    505:        sc->hw_type =
                    506:            (IWN_READ(sc, IWN_HW_REV) & IWN_HW_REV_TYPE_MASK)
                    507:              >> IWN_HW_REV_TYPE_SHIFT;
1.53      christos  508:        if (sc->hw_type == IWN_HW_REV_TYPE_4965)
                    509:                error = iwn4965_attach(sc, PCI_PRODUCT(pa->pa_id));
                    510:        else
                    511:                error = iwn5000_attach(sc, PCI_PRODUCT(pa->pa_id));
                    512:        if (error != 0) {
1.73      nonaka    513:                aprint_error_dev(self, "could not attach device\n");
1.83      nonaka    514:                goto failih;
1.63      christos  515:        }
1.33      christos  516:
1.40      christos  517:        if ((error = iwn_hw_prepare(sc)) != 0) {
1.73      nonaka    518:                aprint_error_dev(self, "hardware not ready\n");
1.83      nonaka    519:                goto failih;
1.33      christos  520:        }
                    521:
                    522:        /* Read MAC address, channels, etc from EEPROM. */
                    523:        if ((error = iwn_read_eeprom(sc)) != 0) {
1.73      nonaka    524:                aprint_error_dev(self, "could not read EEPROM\n");
1.83      nonaka    525:                goto failih;
1.1       ober      526:        }
1.8       blymn     527:
1.33      christos  528:        /* Allocate DMA memory for firmware transfers. */
1.1       ober      529:        if ((error = iwn_alloc_fwmem(sc)) != 0) {
1.73      nonaka    530:                aprint_error_dev(self,
                    531:                    "could not allocate memory for firmware\n");
1.83      nonaka    532:                goto failih;
1.1       ober      533:        }
                    534:
1.33      christos  535:        /* Allocate "Keep Warm" page. */
1.1       ober      536:        if ((error = iwn_alloc_kw(sc)) != 0) {
1.73      nonaka    537:                aprint_error_dev(self, "could not allocate keep warm page\n");
1.1       ober      538:                goto fail1;
                    539:        }
                    540:
1.40      christos  541:        /* Allocate ICT table for 5000 Series. */
                    542:        if (sc->hw_type != IWN_HW_REV_TYPE_4965 &&
                    543:            (error = iwn_alloc_ict(sc)) != 0) {
1.73      nonaka    544:                aprint_error_dev(self, "could not allocate ICT table\n");
1.40      christos  545:                goto fail2;
                    546:        }
                    547:
1.33      christos  548:        /* Allocate TX scheduler "rings". */
                    549:        if ((error = iwn_alloc_sched(sc)) != 0) {
1.73      nonaka    550:                aprint_error_dev(self,
                    551:                    "could not allocate TX scheduler rings\n");
1.40      christos  552:                goto fail3;
1.1       ober      553:        }
                    554:
1.40      christos  555: #ifdef IWN_USE_RBUF
1.33      christos  556:        /* Allocate RX buffers. */
1.1       ober      557:        if ((error = iwn_alloc_rpool(sc)) != 0) {
1.33      christos  558:                aprint_error_dev(self, "could not allocate RX buffers\n");
1.1       ober      559:                goto fail3;
                    560:        }
1.40      christos  561: #endif
1.1       ober      562:
1.53      christos  563:        /* Allocate TX rings (16 on 4965AGN, 20 on >=5000). */
                    564:        for (i = 0; i < sc->ntxqs; i++) {
1.40      christos  565:                if ((error = iwn_alloc_tx_ring(sc, &sc->txq[i], i)) != 0) {
1.73      nonaka    566:                        aprint_error_dev(self,
                    567:                            "could not allocate TX ring %d\n", i);
1.1       ober      568:                        goto fail4;
                    569:                }
                    570:        }
1.8       blymn     571:
1.33      christos  572:        /* Allocate RX ring. */
1.40      christos  573:        if ((error = iwn_alloc_rx_ring(sc, &sc->rxq)) != 0) {
1.73      nonaka    574:                aprint_error_dev(self, "could not allocate RX ring\n");
1.2       ober      575:                goto fail4;
1.1       ober      576:        }
                    577:
1.33      christos  578:        /* Clear pending interrupts. */
                    579:        IWN_WRITE(sc, IWN_INT, 0xffffffff);
                    580:
1.40      christos  581:        /* Count the number of available chains. */
                    582:        sc->ntxchains =
                    583:            ((sc->txchainmask >> 2) & 1) +
                    584:            ((sc->txchainmask >> 1) & 1) +
                    585:            ((sc->txchainmask >> 0) & 1);
                    586:        sc->nrxchains =
                    587:            ((sc->rxchainmask >> 2) & 1) +
                    588:            ((sc->rxchainmask >> 1) & 1) +
                    589:            ((sc->rxchainmask >> 0) & 1);
                    590:        aprint_normal_dev(self, "MIMO %dT%dR, %.4s, address %s\n",
                    591:            sc->ntxchains, sc->nrxchains, sc->eeprom_domain,
                    592:            ether_sprintf(ic->ic_myaddr));
1.28      blymn     593:
1.1       ober      594:        ic->ic_ifp = ifp;
                    595:        ic->ic_phytype = IEEE80211_T_OFDM;      /* not only, but not used */
                    596:        ic->ic_opmode = IEEE80211_M_STA;        /* default to BSS mode */
                    597:        ic->ic_state = IEEE80211_S_INIT;
                    598:
1.91      gutterid  599:        /*
                    600:         * Set device capabilities.
                    601:         * XXX OpenBSD has IEEE80211_C_WEP, IEEE80211_C_RSN, and
                    602:         * IEEE80211_C_PMGT too.
                    603:         */
1.1       ober      604:        ic->ic_caps =
                    605:            IEEE80211_C_IBSS |          /* IBSS mode support */
1.33      christos  606:            IEEE80211_C_WPA |           /* 802.11i */
1.1       ober      607:            IEEE80211_C_MONITOR |       /* monitor mode supported */
                    608:            IEEE80211_C_TXPMGT |        /* tx power management */
                    609:            IEEE80211_C_SHSLOT |        /* short slot time supported */
1.33      christos  610:            IEEE80211_C_SHPREAMBLE |    /* short preamble supported */
1.15      christos  611:            IEEE80211_C_WME;            /* 802.11e */
1.8       blymn     612:
1.40      christos  613: #ifndef IEEE80211_NO_HT
1.53      christos  614:        if (sc->sc_flags & IWN_FLAG_HAS_11N) {
                    615:                /* Set HT capabilities. */
                    616:                ic->ic_htcaps =
1.40      christos  617: #if IWN_RBUF_SIZE == 8192
1.53      christos  618:                    IEEE80211_HTCAP_AMSDU7935 |
1.40      christos  619: #endif
1.53      christos  620:                    IEEE80211_HTCAP_CBW20_40 |
                    621:                    IEEE80211_HTCAP_SGI20 |
                    622:                    IEEE80211_HTCAP_SGI40;
                    623:                if (sc->hw_type != IWN_HW_REV_TYPE_4965)
                    624:                        ic->ic_htcaps |= IEEE80211_HTCAP_GF;
                    625:                if (sc->hw_type == IWN_HW_REV_TYPE_6050)
                    626:                        ic->ic_htcaps |= IEEE80211_HTCAP_SMPS_DYN;
                    627:                else
                    628:                        ic->ic_htcaps |= IEEE80211_HTCAP_SMPS_DIS;
                    629:        }
1.40      christos  630: #endif /* !IEEE80211_NO_HT */
                    631:
                    632:        /* Set supported legacy rates. */
1.89      maya      633:        ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b;
                    634:        ic->ic_sup_rates[IEEE80211_MODE_11G] = ieee80211_std_rateset_11g;
1.33      christos  635:        if (sc->sc_flags & IWN_FLAG_HAS_5GHZ) {
1.89      maya      636:                ic->ic_sup_rates[IEEE80211_MODE_11A] = ieee80211_std_rateset_11a;
1.33      christos  637:        }
1.40      christos  638: #ifndef IEEE80211_NO_HT
1.53      christos  639:        if (sc->sc_flags & IWN_FLAG_HAS_11N) {
                    640:                /* Set supported HT rates. */
                    641:                ic->ic_sup_mcs[0] = 0xff;               /* MCS 0-7 */
                    642:                if (sc->nrxchains > 1)
                    643:                        ic->ic_sup_mcs[1] = 0xff;       /* MCS 7-15 */
                    644:                if (sc->nrxchains > 2)
                    645:                        ic->ic_sup_mcs[2] = 0xff;       /* MCS 16-23 */
                    646:        }
1.40      christos  647: #endif
1.1       ober      648:
1.33      christos  649:        /* IBSS channel undefined for now. */
1.1       ober      650:        ic->ic_ibss_chan = &ic->ic_channels[0];
                    651:
                    652:        ifp->if_softc = sc;
                    653:        ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
                    654:        ifp->if_init = iwn_init;
                    655:        ifp->if_ioctl = iwn_ioctl;
                    656:        ifp->if_start = iwn_start;
1.51      jruoho    657:        ifp->if_stop = iwn_stop;
1.1       ober      658:        ifp->if_watchdog = iwn_watchdog;
                    659:        IFQ_SET_READY(&ifp->if_snd);
                    660:        memcpy(ifp->if_xname, device_xname(self), IFNAMSIZ);
                    661:
1.96    ! riastrad  662:        if_initialize(ifp);
1.1       ober      663:        ieee80211_ifattach(ic);
1.84      nonaka    664:        /* Use common softint-based if_input */
                    665:        ifp->if_percpuq = if_percpuq_create(ifp);
                    666:        if_register(ifp);
                    667:
1.1       ober      668:        ic->ic_node_alloc = iwn_node_alloc;
                    669:        ic->ic_newassoc = iwn_newassoc;
1.40      christos  670: #ifdef IWN_HWCRYPTO
                    671:        ic->ic_crypto.cs_key_set = iwn_set_key;
                    672:        ic->ic_crypto.cs_key_delete = iwn_delete_key;
                    673: #endif
1.1       ober      674:        ic->ic_wme.wme_update = iwn_wme_update;
1.33      christos  675: #ifndef IEEE80211_NO_HT
                    676:        ic->ic_ampdu_rx_start = iwn_ampdu_rx_start;
                    677:        ic->ic_ampdu_rx_stop = iwn_ampdu_rx_stop;
                    678:        ic->ic_ampdu_tx_start = iwn_ampdu_tx_start;
                    679:        ic->ic_ampdu_tx_stop = iwn_ampdu_tx_stop;
                    680: #endif
1.1       ober      681:
1.33      christos  682:        /* Override 802.11 state transition machine. */
1.1       ober      683:        sc->sc_newstate = ic->ic_newstate;
                    684:        ic->ic_newstate = iwn_newstate;
1.94      sevan     685:
                    686:        /* XXX media locking needs revisiting */
                    687:        mutex_init(&sc->sc_media_mtx, MUTEX_DEFAULT, IPL_SOFTNET);
                    688:        ieee80211_media_init_with_lock(ic,
                    689:            iwn_media_change, ieee80211_media_status, &sc->sc_media_mtx);
1.1       ober      690:
                    691:        sc->amrr.amrr_min_success_threshold =  1;
                    692:        sc->amrr.amrr_max_success_threshold = 15;
                    693:
1.40      christos  694:        iwn_radiotap_attach(sc);
                    695:
1.44      christos  696:        /*
                    697:         * XXX for NetBSD, OpenBSD timeout_set replaced by
                    698:         * callout_init and callout_setfunc, above.
1.91      gutterid  699:         */
1.40      christos  700:
1.32      tsutsui   701:        if (pmf_device_register(self, NULL, iwn_resume))
                    702:                pmf_class_network_register(self, ifp);
                    703:        else
1.1       ober      704:                aprint_error_dev(self, "couldn't establish power handler\n");
                    705:
1.44      christos  706:        /* XXX NetBSD add call to ieee80211_announce for dmesg. */
1.1       ober      707:        ieee80211_announce(ic);
                    708:
1.84      nonaka    709:        sc->sc_flags |= IWN_FLAG_ATTACHED;
1.1       ober      710:        return;
                    711:
1.33      christos  712:        /* Free allocated memory if something failed during attachment. */
1.1       ober      713: fail4: while (--i >= 0)
                    714:                iwn_free_tx_ring(sc, &sc->txq[i]);
1.40      christos  715: #ifdef IWN_USE_RBUF
1.1       ober      716:        iwn_free_rpool(sc);
1.40      christos  717: #endif
                    718:        iwn_free_sched(sc);
                    719: fail3: if (sc->ict != NULL)
                    720:                iwn_free_ict(sc);
1.1       ober      721: fail2: iwn_free_kw(sc);
                    722: fail1: iwn_free_fwmem(sc);
1.83      nonaka    723: failih:        pci_intr_disestablish(sc->sc_pct, sc->sc_ih);
                    724:        sc->sc_ih = NULL;
                    725: failia:        pci_intr_release(sc->sc_pct, sc->sc_pihp, 1);
                    726:        sc->sc_pihp = NULL;
1.84      nonaka    727: failsi:        softint_disestablish(sc->sc_soft_ih);
                    728:        sc->sc_soft_ih = NULL;
1.83      nonaka    729: unmap: bus_space_unmap(sc->sc_st, sc->sc_sh, sc->sc_sz);
1.1       ober      730: }
                    731:
1.53      christos  732: int
                    733: iwn4965_attach(struct iwn_softc *sc, pci_product_id_t pid)
                    734: {
                    735:        struct iwn_ops *ops = &sc->ops;
                    736:
                    737:        ops->load_firmware = iwn4965_load_firmware;
                    738:        ops->read_eeprom = iwn4965_read_eeprom;
                    739:        ops->post_alive = iwn4965_post_alive;
                    740:        ops->nic_config = iwn4965_nic_config;
1.67      prlw1     741:        ops->config_bt_coex = iwn_config_bt_coex_bluetooth;
1.53      christos  742:        ops->update_sched = iwn4965_update_sched;
                    743:        ops->get_temperature = iwn4965_get_temperature;
                    744:        ops->get_rssi = iwn4965_get_rssi;
                    745:        ops->set_txpower = iwn4965_set_txpower;
                    746:        ops->init_gains = iwn4965_init_gains;
                    747:        ops->set_gains = iwn4965_set_gains;
                    748:        ops->add_node = iwn4965_add_node;
                    749:        ops->tx_done = iwn4965_tx_done;
                    750: #ifndef IEEE80211_NO_HT
                    751:        ops->ampdu_tx_start = iwn4965_ampdu_tx_start;
                    752:        ops->ampdu_tx_stop = iwn4965_ampdu_tx_stop;
                    753: #endif
                    754:        sc->ntxqs = IWN4965_NTXQUEUES;
                    755:        sc->ndmachnls = IWN4965_NDMACHNLS;
                    756:        sc->broadcast_id = IWN4965_ID_BROADCAST;
                    757:        sc->rxonsz = IWN4965_RXONSZ;
                    758:        sc->schedsz = IWN4965_SCHEDSZ;
                    759:        sc->fw_text_maxsz = IWN4965_FW_TEXT_MAXSZ;
                    760:        sc->fw_data_maxsz = IWN4965_FW_DATA_MAXSZ;
                    761:        sc->fwsz = IWN4965_FWSZ;
                    762:        sc->sched_txfact_addr = IWN4965_SCHED_TXFACT;
                    763:        sc->limits = &iwn4965_sensitivity_limits;
                    764:        sc->fwname = "iwlwifi-4965-2.ucode";
                    765:        /* Override chains masks, ROM is known to be broken. */
                    766:        sc->txchainmask = IWN_ANT_AB;
                    767:        sc->rxchainmask = IWN_ANT_ABC;
                    768:
                    769:        return 0;
                    770: }
                    771:
                    772: int
                    773: iwn5000_attach(struct iwn_softc *sc, pci_product_id_t pid)
1.33      christos  774: {
1.53      christos  775:        struct iwn_ops *ops = &sc->ops;
                    776:
                    777:        ops->load_firmware = iwn5000_load_firmware;
                    778:        ops->read_eeprom = iwn5000_read_eeprom;
                    779:        ops->post_alive = iwn5000_post_alive;
                    780:        ops->nic_config = iwn5000_nic_config;
1.67      prlw1     781:        ops->config_bt_coex = iwn_config_bt_coex_bluetooth;
1.53      christos  782:        ops->update_sched = iwn5000_update_sched;
                    783:        ops->get_temperature = iwn5000_get_temperature;
                    784:        ops->get_rssi = iwn5000_get_rssi;
                    785:        ops->set_txpower = iwn5000_set_txpower;
                    786:        ops->init_gains = iwn5000_init_gains;
                    787:        ops->set_gains = iwn5000_set_gains;
                    788:        ops->add_node = iwn5000_add_node;
                    789:        ops->tx_done = iwn5000_tx_done;
                    790: #ifndef IEEE80211_NO_HT
                    791:        ops->ampdu_tx_start = iwn5000_ampdu_tx_start;
                    792:        ops->ampdu_tx_stop = iwn5000_ampdu_tx_stop;
                    793: #endif
                    794:        sc->ntxqs = IWN5000_NTXQUEUES;
                    795:        sc->ndmachnls = IWN5000_NDMACHNLS;
                    796:        sc->broadcast_id = IWN5000_ID_BROADCAST;
                    797:        sc->rxonsz = IWN5000_RXONSZ;
                    798:        sc->schedsz = IWN5000_SCHEDSZ;
                    799:        sc->fw_text_maxsz = IWN5000_FW_TEXT_MAXSZ;
                    800:        sc->fw_data_maxsz = IWN5000_FW_DATA_MAXSZ;
                    801:        sc->fwsz = IWN5000_FWSZ;
                    802:        sc->sched_txfact_addr = IWN5000_SCHED_TXFACT;
1.33      christos  803:
                    804:        switch (sc->hw_type) {
                    805:        case IWN_HW_REV_TYPE_5100:
1.40      christos  806:                sc->limits = &iwn5000_sensitivity_limits;
                    807:                sc->fwname = "iwlwifi-5000-2.ucode";
1.53      christos  808:                /* Override chains masks, ROM is known to be broken. */
1.40      christos  809:                sc->txchainmask = IWN_ANT_B;
                    810:                sc->rxchainmask = IWN_ANT_AB;
1.33      christos  811:                break;
                    812:        case IWN_HW_REV_TYPE_5150:
1.40      christos  813:                sc->limits = &iwn5150_sensitivity_limits;
                    814:                sc->fwname = "iwlwifi-5150-2.ucode";
1.33      christos  815:                break;
                    816:        case IWN_HW_REV_TYPE_5300:
                    817:        case IWN_HW_REV_TYPE_5350:
1.40      christos  818:                sc->limits = &iwn5000_sensitivity_limits;
                    819:                sc->fwname = "iwlwifi-5000-2.ucode";
1.33      christos  820:                break;
                    821:        case IWN_HW_REV_TYPE_1000:
1.40      christos  822:                sc->limits = &iwn1000_sensitivity_limits;
1.72      nonaka    823:                if (pid == PCI_PRODUCT_INTEL_WIFI_LINK_100_1 ||
                    824:                    pid == PCI_PRODUCT_INTEL_WIFI_LINK_100_2)
                    825:                        sc->fwname = "iwlwifi-100-5.ucode";
                    826:                else
                    827:                        sc->fwname = "iwlwifi-1000-3.ucode";
1.33      christos  828:                break;
                    829:        case IWN_HW_REV_TYPE_6000:
1.40      christos  830:                sc->limits = &iwn6000_sensitivity_limits;
                    831:                sc->fwname = "iwlwifi-6000-4.ucode";
1.53      christos  832:                if (pid == PCI_PRODUCT_INTEL_WIFI_LINK_6000_IPA_1 ||
                    833:                    pid == PCI_PRODUCT_INTEL_WIFI_LINK_6000_IPA_2) {
1.40      christos  834:                        sc->sc_flags |= IWN_FLAG_INTERNAL_PA;
1.53      christos  835:                        /* Override chains masks, ROM is known to be broken. */
1.40      christos  836:                        sc->txchainmask = IWN_ANT_BC;
                    837:                        sc->rxchainmask = IWN_ANT_BC;
                    838:                }
1.33      christos  839:                break;
                    840:        case IWN_HW_REV_TYPE_6050:
1.40      christos  841:                sc->limits = &iwn6000_sensitivity_limits;
1.55      msaitoh   842:                sc->fwname = "iwlwifi-6050-5.ucode";
1.40      christos  843:                break;
                    844:        case IWN_HW_REV_TYPE_6005:
                    845:                sc->limits = &iwn6000_sensitivity_limits;
1.67      prlw1     846:                /* Type 6030 cards return IWN_HW_REV_TYPE_6005 */
                    847:                if (pid == PCI_PRODUCT_INTEL_WIFI_LINK_1030_1 ||
                    848:                    pid == PCI_PRODUCT_INTEL_WIFI_LINK_1030_2 ||
                    849:                    pid == PCI_PRODUCT_INTEL_WIFI_LINK_6230_1 ||
1.68      christos  850:                    pid == PCI_PRODUCT_INTEL_WIFI_LINK_6230_2 ||
1.72      nonaka    851:                    pid == PCI_PRODUCT_INTEL_WIFI_LINK_6235   ||
                    852:                    pid == PCI_PRODUCT_INTEL_WIFI_LINK_6235_2) {
1.67      prlw1     853:                        sc->fwname = "iwlwifi-6000g2b-6.ucode";
                    854:                        ops->config_bt_coex = iwn_config_bt_coex_adv1;
                    855:                }
1.91      gutterid  856:                /*
                    857:                 * This covers:
                    858:                 * PCI_PRODUCT_INTEL_WIFI_LINK_6005_2X2_1
                    859:                 * PCI_PRODUCT_INTEL_WIFI_LINK_6005_2X2_2
                    860:                 */
1.67      prlw1     861:                else
                    862:                        sc->fwname = "iwlwifi-6000g2a-5.ucode";
1.33      christos  863:                break;
1.72      nonaka    864:        case IWN_HW_REV_TYPE_2030:
1.85      mlelstv   865:                sc->limits = &iwn2030_sensitivity_limits;
1.72      nonaka    866:                sc->fwname = "iwlwifi-2030-6.ucode";
                    867:                ops->config_bt_coex = iwn_config_bt_coex_adv2;
                    868:                break;
                    869:        case IWN_HW_REV_TYPE_2000:
                    870:                sc->limits = &iwn2000_sensitivity_limits;
                    871:                sc->fwname = "iwlwifi-2000-6.ucode";
                    872:                break;
                    873:        case IWN_HW_REV_TYPE_135:
                    874:                sc->limits = &iwn2000_sensitivity_limits;
                    875:                sc->fwname = "iwlwifi-135-6.ucode";
                    876:                ops->config_bt_coex = iwn_config_bt_coex_adv2;
                    877:                break;
                    878:        case IWN_HW_REV_TYPE_105:
                    879:                sc->limits = &iwn2000_sensitivity_limits;
                    880:                sc->fwname = "iwlwifi-105-6.ucode";
                    881:                break;
1.33      christos  882:        default:
1.40      christos  883:                aprint_normal(": adapter type %d not supported\n", sc->hw_type);
1.53      christos  884:                return ENOTSUP;
1.33      christos  885:        }
1.53      christos  886:        return 0;
1.33      christos  887: }
                    888:
1.1       ober      889: /*
                    890:  * Attach the interface to 802.11 radiotap.
                    891:  */
                    892: static void
                    893: iwn_radiotap_attach(struct iwn_softc *sc)
                    894: {
                    895:        struct ifnet *ifp = sc->sc_ic.ic_ifp;
1.36      pooka     896:
1.38      joerg     897:        bpf_attach2(ifp, DLT_IEEE802_11_RADIO,
1.40      christos  898:            sizeof (struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN,
1.36      pooka     899:            &sc->sc_drvbpf);
1.1       ober      900:
                    901:        sc->sc_rxtap_len = sizeof sc->sc_rxtapu;
                    902:        sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
                    903:        sc->sc_rxtap.wr_ihdr.it_present = htole32(IWN_RX_RADIOTAP_PRESENT);
                    904:
                    905:        sc->sc_txtap_len = sizeof sc->sc_txtapu;
                    906:        sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
                    907:        sc->sc_txtap.wt_ihdr.it_present = htole32(IWN_TX_RADIOTAP_PRESENT);
                    908: }
                    909:
                    910: static int
1.40      christos  911: iwn_detach(device_t self, int flags __unused)
1.1       ober      912: {
1.40      christos  913:        struct iwn_softc *sc = device_private(self);
                    914:        struct ifnet *ifp = sc->sc_ic.ic_ifp;
                    915:        int qid;
                    916:
1.84      nonaka    917:        if (!(sc->sc_flags & IWN_FLAG_ATTACHED))
                    918:                return 0;
                    919:
1.40      christos  920:        callout_stop(&sc->calib_to);
                    921:
                    922:        /* Uninstall interrupt handler. */
                    923:        if (sc->sc_ih != NULL)
                    924:                pci_intr_disestablish(sc->sc_pct, sc->sc_ih);
1.83      nonaka    925:        if (sc->sc_pihp != NULL)
                    926:                pci_intr_release(sc->sc_pct, sc->sc_pihp, 1);
1.84      nonaka    927:        if (sc->sc_soft_ih != NULL)
                    928:                softint_disestablish(sc->sc_soft_ih);
1.40      christos  929:
                    930:        /* Free DMA resources. */
                    931:        iwn_free_rx_ring(sc, &sc->rxq);
1.53      christos  932:        for (qid = 0; qid < sc->ntxqs; qid++)
1.40      christos  933:                iwn_free_tx_ring(sc, &sc->txq[qid]);
                    934: #ifdef IWN_USE_RBUF
                    935:        iwn_free_rpool(sc);
                    936: #endif
                    937:        iwn_free_sched(sc);
                    938:        iwn_free_kw(sc);
                    939:        if (sc->ict != NULL)
                    940:                iwn_free_ict(sc);
                    941:        iwn_free_fwmem(sc);
1.1       ober      942:
1.40      christos  943:        bus_space_unmap(sc->sc_st, sc->sc_sh, sc->sc_sz);
1.1       ober      944:
1.40      christos  945:        ieee80211_ifdetach(&sc->sc_ic);
                    946:        if_detach(ifp);
1.1       ober      947:
1.40      christos  948:        return 0;
                    949: }
1.1       ober      950:
1.40      christos  951: #if 0
                    952: /*
                    953:  * XXX Investigate if clearing the PCI retry timeout could eliminate
                    954:  * the repeated scan calls.  Also the calls to if_init and if_start
                    955:  * are similar to the effect of adding the call to ifioctl_common .
                    956:  */
                    957: static void
                    958: iwn_power(int why, void *arg)
                    959: {
                    960:        struct iwn_softc *sc = arg;
                    961:        struct ifnet *ifp;
                    962:        pcireg_t reg;
                    963:        int s;
1.8       blymn     964:
1.40      christos  965:        if (why != PWR_RESUME)
                    966:                return;
1.8       blymn     967:
1.40      christos  968:        /* Clear device-specific "PCI retry timeout" register (41h). */
                    969:        reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag, 0x40);
1.53      christos  970:        if (reg & 0xff00)
                    971:                pci_conf_write(sc->sc_pct, sc->sc_pcitag, 0x40, reg & ~0xff00);
1.1       ober      972:
1.40      christos  973:        s = splnet();
                    974:        ifp = &sc->sc_ic.ic_if;
                    975:        if (ifp->if_flags & IFF_UP) {
                    976:                ifp->if_init(ifp);
                    977:                if (ifp->if_flags & IFF_RUNNING)
                    978:                        ifp->if_start(ifp);
                    979:        }
                    980:        splx(s);
1.33      christos  981: }
                    982: #endif
                    983:
1.40      christos  984: static bool
                    985: iwn_resume(device_t dv, const pmf_qual_t *qual)
                    986: {
                    987:        return true;
                    988: }
                    989:
1.33      christos  990: static int
                    991: iwn_nic_lock(struct iwn_softc *sc)
                    992: {
                    993:        int ntries;
                    994:
                    995:        /* Request exclusive access to NIC. */
                    996:        IWN_SETBITS(sc, IWN_GP_CNTRL, IWN_GP_CNTRL_MAC_ACCESS_REQ);
                    997:
                    998:        /* Spin until we actually get the lock. */
                    999:        for (ntries = 0; ntries < 1000; ntries++) {
                   1000:                if ((IWN_READ(sc, IWN_GP_CNTRL) &
                   1001:                     (IWN_GP_CNTRL_MAC_ACCESS_ENA | IWN_GP_CNTRL_SLEEP)) ==
                   1002:                    IWN_GP_CNTRL_MAC_ACCESS_ENA)
                   1003:                        return 0;
                   1004:                DELAY(10);
                   1005:        }
                   1006:        return ETIMEDOUT;
                   1007: }
                   1008:
                   1009: static __inline void
                   1010: iwn_nic_unlock(struct iwn_softc *sc)
                   1011: {
                   1012:        IWN_CLRBITS(sc, IWN_GP_CNTRL, IWN_GP_CNTRL_MAC_ACCESS_REQ);
                   1013: }
                   1014:
                   1015: static __inline uint32_t
                   1016: iwn_prph_read(struct iwn_softc *sc, uint32_t addr)
                   1017: {
                   1018:        IWN_WRITE(sc, IWN_PRPH_RADDR, IWN_PRPH_DWORD | addr);
1.40      christos 1019:        IWN_BARRIER_READ_WRITE(sc);
1.33      christos 1020:        return IWN_READ(sc, IWN_PRPH_RDATA);
                   1021: }
                   1022:
                   1023: static __inline void
                   1024: iwn_prph_write(struct iwn_softc *sc, uint32_t addr, uint32_t data)
                   1025: {
                   1026:        IWN_WRITE(sc, IWN_PRPH_WADDR, IWN_PRPH_DWORD | addr);
1.40      christos 1027:        IWN_BARRIER_WRITE(sc);
1.33      christos 1028:        IWN_WRITE(sc, IWN_PRPH_WDATA, data);
                   1029: }
                   1030:
                   1031: static __inline void
                   1032: iwn_prph_setbits(struct iwn_softc *sc, uint32_t addr, uint32_t mask)
                   1033: {
                   1034:        iwn_prph_write(sc, addr, iwn_prph_read(sc, addr) | mask);
                   1035: }
                   1036:
                   1037: static __inline void
                   1038: iwn_prph_clrbits(struct iwn_softc *sc, uint32_t addr, uint32_t mask)
                   1039: {
                   1040:        iwn_prph_write(sc, addr, iwn_prph_read(sc, addr) & ~mask);
                   1041: }
                   1042:
                   1043: static __inline void
                   1044: iwn_prph_write_region_4(struct iwn_softc *sc, uint32_t addr,
                   1045:     const uint32_t *data, int count)
                   1046: {
                   1047:        for (; count > 0; count--, data++, addr += 4)
                   1048:                iwn_prph_write(sc, addr, *data);
                   1049: }
                   1050:
                   1051: static __inline uint32_t
                   1052: iwn_mem_read(struct iwn_softc *sc, uint32_t addr)
                   1053: {
                   1054:        IWN_WRITE(sc, IWN_MEM_RADDR, addr);
1.40      christos 1055:        IWN_BARRIER_READ_WRITE(sc);
1.33      christos 1056:        return IWN_READ(sc, IWN_MEM_RDATA);
                   1057: }
                   1058:
                   1059: static __inline void
                   1060: iwn_mem_write(struct iwn_softc *sc, uint32_t addr, uint32_t data)
                   1061: {
                   1062:        IWN_WRITE(sc, IWN_MEM_WADDR, addr);
1.40      christos 1063:        IWN_BARRIER_WRITE(sc);
1.33      christos 1064:        IWN_WRITE(sc, IWN_MEM_WDATA, data);
                   1065: }
                   1066:
1.69      joerg    1067: #ifndef IEEE80211_NO_HT
1.33      christos 1068: static __inline void
                   1069: iwn_mem_write_2(struct iwn_softc *sc, uint32_t addr, uint16_t data)
                   1070: {
                   1071:        uint32_t tmp;
                   1072:
                   1073:        tmp = iwn_mem_read(sc, addr & ~3);
                   1074:        if (addr & 3)
                   1075:                tmp = (tmp & 0x0000ffff) | data << 16;
                   1076:        else
                   1077:                tmp = (tmp & 0xffff0000) | data;
                   1078:        iwn_mem_write(sc, addr & ~3, tmp);
                   1079: }
1.69      joerg    1080: #endif
1.33      christos 1081:
                   1082: static __inline void
                   1083: iwn_mem_read_region_4(struct iwn_softc *sc, uint32_t addr, uint32_t *data,
                   1084:     int count)
                   1085: {
                   1086:        for (; count > 0; count--, addr += 4)
                   1087:                *data++ = iwn_mem_read(sc, addr);
                   1088: }
                   1089:
                   1090: static __inline void
                   1091: iwn_mem_set_region_4(struct iwn_softc *sc, uint32_t addr, uint32_t val,
                   1092:     int count)
                   1093: {
                   1094:        for (; count > 0; count--, addr += 4)
                   1095:                iwn_mem_write(sc, addr, val);
                   1096: }
                   1097:
                   1098: static int
                   1099: iwn_eeprom_lock(struct iwn_softc *sc)
                   1100: {
                   1101:        int i, ntries;
                   1102:
                   1103:        for (i = 0; i < 100; i++) {
                   1104:                /* Request exclusive access to EEPROM. */
                   1105:                IWN_SETBITS(sc, IWN_HW_IF_CONFIG,
                   1106:                    IWN_HW_IF_CONFIG_EEPROM_LOCKED);
                   1107:
                   1108:                /* Spin until we actually get the lock. */
                   1109:                for (ntries = 0; ntries < 100; ntries++) {
                   1110:                        if (IWN_READ(sc, IWN_HW_IF_CONFIG) &
                   1111:                            IWN_HW_IF_CONFIG_EEPROM_LOCKED)
                   1112:                                return 0;
                   1113:                        DELAY(10);
                   1114:                }
                   1115:        }
                   1116:        return ETIMEDOUT;
                   1117: }
                   1118:
                   1119: static __inline void
                   1120: iwn_eeprom_unlock(struct iwn_softc *sc)
                   1121: {
                   1122:        IWN_CLRBITS(sc, IWN_HW_IF_CONFIG, IWN_HW_IF_CONFIG_EEPROM_LOCKED);
                   1123: }
                   1124:
1.40      christos 1125: /*
                   1126:  * Initialize access by host to One Time Programmable ROM.
                   1127:  * NB: This kind of ROM can be found on 1000 or 6000 Series only.
                   1128:  */
                   1129: static int
                   1130: iwn_init_otprom(struct iwn_softc *sc)
                   1131: {
                   1132:        uint16_t prev = 0, base, next;
                   1133:        int count, error;
                   1134:
                   1135:        /* Wait for clock stabilization before accessing prph. */
                   1136:        if ((error = iwn_clock_wait(sc)) != 0)
                   1137:                return error;
                   1138:
                   1139:        if ((error = iwn_nic_lock(sc)) != 0)
                   1140:                return error;
                   1141:        iwn_prph_setbits(sc, IWN_APMG_PS, IWN_APMG_PS_RESET_REQ);
                   1142:        DELAY(5);
                   1143:        iwn_prph_clrbits(sc, IWN_APMG_PS, IWN_APMG_PS_RESET_REQ);
                   1144:        iwn_nic_unlock(sc);
                   1145:
                   1146:        /* Set auto clock gate disable bit for HW with OTP shadow RAM. */
                   1147:        if (sc->hw_type != IWN_HW_REV_TYPE_1000) {
                   1148:                IWN_SETBITS(sc, IWN_DBG_LINK_PWR_MGMT,
                   1149:                    IWN_RESET_LINK_PWR_MGMT_DIS);
                   1150:        }
                   1151:        IWN_CLRBITS(sc, IWN_EEPROM_GP, IWN_EEPROM_GP_IF_OWNER);
                   1152:        /* Clear ECC status. */
                   1153:        IWN_SETBITS(sc, IWN_OTP_GP,
                   1154:            IWN_OTP_GP_ECC_CORR_STTS | IWN_OTP_GP_ECC_UNCORR_STTS);
                   1155:
                   1156:        /*
                   1157:         * Find the block before last block (contains the EEPROM image)
                   1158:         * for HW without OTP shadow RAM.
                   1159:         */
                   1160:        if (sc->hw_type == IWN_HW_REV_TYPE_1000) {
                   1161:                /* Switch to absolute addressing mode. */
                   1162:                IWN_CLRBITS(sc, IWN_OTP_GP, IWN_OTP_GP_RELATIVE_ACCESS);
                   1163:                base = 0;
                   1164:                for (count = 0; count < IWN1000_OTP_NBLOCKS; count++) {
                   1165:                        error = iwn_read_prom_data(sc, base, &next, 2);
                   1166:                        if (error != 0)
                   1167:                                return error;
                   1168:                        if (next == 0)  /* End of linked-list. */
                   1169:                                break;
                   1170:                        prev = base;
                   1171:                        base = le16toh(next);
                   1172:                }
                   1173:                if (count == 0 || count == IWN1000_OTP_NBLOCKS)
                   1174:                        return EIO;
                   1175:                /* Skip "next" word. */
                   1176:                sc->prom_base = prev + 1;
                   1177:        }
                   1178:        return 0;
                   1179: }
                   1180:
1.33      christos 1181: static int
                   1182: iwn_read_prom_data(struct iwn_softc *sc, uint32_t addr, void *data, int count)
                   1183: {
                   1184:        uint8_t *out = data;
1.40      christos 1185:        uint32_t val, tmp;
1.33      christos 1186:        int ntries;
1.1       ober     1187:
1.40      christos 1188:        addr += sc->prom_base;
1.33      christos 1189:        for (; count > 0; count -= 2, addr++) {
                   1190:                IWN_WRITE(sc, IWN_EEPROM, addr << 2);
                   1191:                for (ntries = 0; ntries < 10; ntries++) {
                   1192:                        val = IWN_READ(sc, IWN_EEPROM);
                   1193:                        if (val & IWN_EEPROM_READ_VALID)
                   1194:                                break;
                   1195:                        DELAY(5);
                   1196:                }
                   1197:                if (ntries == 10) {
1.40      christos 1198:                        aprint_error_dev(sc->sc_dev,
                   1199:                            "timeout reading ROM at 0x%x\n", addr);
1.33      christos 1200:                        return ETIMEDOUT;
                   1201:                }
1.40      christos 1202:                if (sc->sc_flags & IWN_FLAG_HAS_OTPROM) {
                   1203:                        /* OTPROM, check for ECC errors. */
                   1204:                        tmp = IWN_READ(sc, IWN_OTP_GP);
                   1205:                        if (tmp & IWN_OTP_GP_ECC_UNCORR_STTS) {
                   1206:                                aprint_error_dev(sc->sc_dev,
                   1207:                                    "OTPROM ECC error at 0x%x\n", addr);
                   1208:                                return EIO;
                   1209:                        }
                   1210:                        if (tmp & IWN_OTP_GP_ECC_CORR_STTS) {
                   1211:                                /* Correctable ECC error, clear bit. */
                   1212:                                IWN_SETBITS(sc, IWN_OTP_GP,
                   1213:                                    IWN_OTP_GP_ECC_CORR_STTS);
                   1214:                        }
                   1215:                }
1.33      christos 1216:                *out++ = val >> 16;
                   1217:                if (count > 1)
                   1218:                        *out++ = val >> 24;
                   1219:        }
1.1       ober     1220:        return 0;
                   1221: }
                   1222:
                   1223: static int
                   1224: iwn_dma_contig_alloc(bus_dma_tag_t tag, struct iwn_dma_info *dma, void **kvap,
1.40      christos 1225:     bus_size_t size, bus_size_t alignment)
1.1       ober     1226: {
                   1227:        int nsegs, error;
                   1228:
                   1229:        dma->tag = tag;
                   1230:        dma->size = size;
                   1231:
1.40      christos 1232:        error = bus_dmamap_create(tag, size, 1, size, 0, BUS_DMA_NOWAIT,
                   1233:            &dma->map);
1.1       ober     1234:        if (error != 0)
                   1235:                goto fail;
                   1236:
                   1237:        error = bus_dmamem_alloc(tag, size, alignment, 0, &dma->seg, 1, &nsegs,
1.40      christos 1238:            BUS_DMA_NOWAIT); /* XXX OpenBSD adds BUS_DMA_ZERO */
1.1       ober     1239:        if (error != 0)
                   1240:                goto fail;
                   1241:
1.40      christos 1242:        error = bus_dmamem_map(tag, &dma->seg, 1, size, &dma->vaddr,
                   1243:            BUS_DMA_NOWAIT); /* XXX OpenBSD adds BUS_DMA_COHERENT */
1.1       ober     1244:        if (error != 0)
                   1245:                goto fail;
                   1246:
1.40      christos 1247:        error = bus_dmamap_load(tag, dma->map, dma->vaddr, size, NULL,
                   1248:            BUS_DMA_NOWAIT);
1.1       ober     1249:        if (error != 0)
                   1250:                goto fail;
                   1251:
1.44      christos 1252:        /* XXX Presumably needed because of missing BUS_DMA_ZERO, above. */
1.1       ober     1253:        memset(dma->vaddr, 0, size);
1.33      christos 1254:        bus_dmamap_sync(tag, dma->map, 0, size, BUS_DMASYNC_PREWRITE);
1.1       ober     1255:
                   1256:        dma->paddr = dma->map->dm_segs[0].ds_addr;
                   1257:        if (kvap != NULL)
                   1258:                *kvap = dma->vaddr;
                   1259:
                   1260:        return 0;
                   1261:
                   1262: fail:  iwn_dma_contig_free(dma);
                   1263:        return error;
                   1264: }
                   1265:
                   1266: static void
                   1267: iwn_dma_contig_free(struct iwn_dma_info *dma)
                   1268: {
                   1269:        if (dma->map != NULL) {
                   1270:                if (dma->vaddr != NULL) {
1.33      christos 1271:                        bus_dmamap_sync(dma->tag, dma->map, 0, dma->size,
                   1272:                            BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
1.1       ober     1273:                        bus_dmamap_unload(dma->tag, dma->map);
                   1274:                        bus_dmamem_unmap(dma->tag, dma->vaddr, dma->size);
                   1275:                        bus_dmamem_free(dma->tag, &dma->seg, 1);
                   1276:                        dma->vaddr = NULL;
                   1277:                }
                   1278:                bus_dmamap_destroy(dma->tag, dma->map);
                   1279:                dma->map = NULL;
                   1280:        }
                   1281: }
                   1282:
                   1283: static int
1.33      christos 1284: iwn_alloc_sched(struct iwn_softc *sc)
1.1       ober     1285: {
1.33      christos 1286:        /* TX scheduler rings must be aligned on a 1KB boundary. */
1.40      christos 1287:        return iwn_dma_contig_alloc(sc->sc_dmat, &sc->sched_dma,
1.53      christos 1288:            (void **)&sc->sched, sc->schedsz, 1024);
1.1       ober     1289: }
                   1290:
                   1291: static void
1.33      christos 1292: iwn_free_sched(struct iwn_softc *sc)
1.1       ober     1293: {
1.33      christos 1294:        iwn_dma_contig_free(&sc->sched_dma);
1.1       ober     1295: }
                   1296:
                   1297: static int
                   1298: iwn_alloc_kw(struct iwn_softc *sc)
                   1299: {
1.40      christos 1300:        /* "Keep Warm" page must be aligned on a 4KB boundary. */
1.33      christos 1301:        return iwn_dma_contig_alloc(sc->sc_dmat, &sc->kw_dma, NULL, 4096,
1.40      christos 1302:            4096);
1.1       ober     1303: }
                   1304:
                   1305: static void
                   1306: iwn_free_kw(struct iwn_softc *sc)
                   1307: {
                   1308:        iwn_dma_contig_free(&sc->kw_dma);
                   1309: }
                   1310:
                   1311: static int
1.40      christos 1312: iwn_alloc_ict(struct iwn_softc *sc)
                   1313: {
                   1314:        /* ICT table must be aligned on a 4KB boundary. */
                   1315:        return iwn_dma_contig_alloc(sc->sc_dmat, &sc->ict_dma,
                   1316:            (void **)&sc->ict, IWN_ICT_SIZE, 4096);
                   1317: }
                   1318:
                   1319: static void
                   1320: iwn_free_ict(struct iwn_softc *sc)
                   1321: {
                   1322:        iwn_dma_contig_free(&sc->ict_dma);
                   1323: }
                   1324:
                   1325: static int
1.1       ober     1326: iwn_alloc_fwmem(struct iwn_softc *sc)
                   1327: {
1.33      christos 1328:        /* Must be aligned on a 16-byte boundary. */
1.40      christos 1329:        return iwn_dma_contig_alloc(sc->sc_dmat, &sc->fw_dma, NULL,
1.53      christos 1330:            sc->fwsz, 16);
1.1       ober     1331: }
                   1332:
                   1333: static void
                   1334: iwn_free_fwmem(struct iwn_softc *sc)
                   1335: {
                   1336:        iwn_dma_contig_free(&sc->fw_dma);
                   1337: }
                   1338:
1.40      christos 1339: static int
                   1340: iwn_alloc_rx_ring(struct iwn_softc *sc, struct iwn_rx_ring *ring)
                   1341: {
1.33      christos 1342:        bus_size_t size;
1.15      christos 1343:        int i, error;
1.8       blymn    1344:
1.1       ober     1345:        ring->cur = 0;
                   1346:
1.53      christos 1347:        /* Allocate RX descriptors (256-byte aligned). */
1.40      christos 1348:        size = IWN_RX_RING_COUNT * sizeof (uint32_t);
1.1       ober     1349:        error = iwn_dma_contig_alloc(sc->sc_dmat, &ring->desc_dma,
1.40      christos 1350:            (void **)&ring->desc, size, 256);
1.33      christos 1351:        if (error != 0) {
                   1352:                aprint_error_dev(sc->sc_dev,
                   1353:                    "could not allocate RX ring DMA memory\n");
                   1354:                goto fail;
                   1355:        }
                   1356:
1.53      christos 1357:        /* Allocate RX status area (16-byte aligned). */
1.33      christos 1358:        error = iwn_dma_contig_alloc(sc->sc_dmat, &ring->stat_dma,
1.40      christos 1359:            (void **)&ring->stat, sizeof (struct iwn_rx_status), 16);
1.1       ober     1360:        if (error != 0) {
1.3       skrll    1361:                aprint_error_dev(sc->sc_dev,
1.33      christos 1362:                    "could not allocate RX status DMA memory\n");
1.1       ober     1363:                goto fail;
                   1364:        }
                   1365:
                   1366:        /*
1.33      christos 1367:         * Allocate and map RX buffers.
1.1       ober     1368:         */
                   1369:        for (i = 0; i < IWN_RX_RING_COUNT; i++) {
1.40      christos 1370:                struct iwn_rx_data *data = &ring->data[i];
1.8       blymn    1371:
1.33      christos 1372:                error = bus_dmamap_create(sc->sc_dmat, IWN_RBUF_SIZE, 1,
1.40      christos 1373:                    IWN_RBUF_SIZE, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
                   1374:                    &data->map);
1.33      christos 1375:                if (error != 0) {
                   1376:                        aprint_error_dev(sc->sc_dev,
                   1377:                            "could not create RX buf DMA map\n");
                   1378:                        goto fail;
                   1379:                }
1.40      christos 1380:
                   1381:                data->m = MCLGETIalt(sc, M_DONTWAIT, NULL, IWN_RBUF_SIZE);
1.1       ober     1382:                if (data->m == NULL) {
1.33      christos 1383:                        aprint_error_dev(sc->sc_dev,
                   1384:                            "could not allocate RX mbuf\n");
1.40      christos 1385:                        error = ENOBUFS;
1.1       ober     1386:                        goto fail;
                   1387:                }
1.40      christos 1388:
1.33      christos 1389:                error = bus_dmamap_load(sc->sc_dmat, data->map,
1.40      christos 1390:                    mtod(data->m, void *), IWN_RBUF_SIZE, NULL,
                   1391:                    BUS_DMA_NOWAIT | BUS_DMA_READ);
1.33      christos 1392:                if (error != 0) {
1.40      christos 1393:                        aprint_error_dev(sc->sc_dev,
                   1394:                            "can't not map mbuf (error %d)\n", error);
1.33      christos 1395:                        goto fail;
                   1396:                }
1.1       ober     1397:
1.53      christos 1398:                /* Set physical address of RX buffer (256-byte aligned). */
1.33      christos 1399:                ring->desc[i] = htole32(data->map->dm_segs[0].ds_addr >> 8);
1.1       ober     1400:        }
                   1401:
1.40      christos 1402:        bus_dmamap_sync(sc->sc_dmat, ring->desc_dma.map, 0, size,
                   1403:            BUS_DMASYNC_PREWRITE);
1.33      christos 1404:
1.1       ober     1405:        return 0;
                   1406:
                   1407: fail:  iwn_free_rx_ring(sc, ring);
                   1408:        return error;
                   1409: }
                   1410:
                   1411: static void
                   1412: iwn_reset_rx_ring(struct iwn_softc *sc, struct iwn_rx_ring *ring)
                   1413: {
                   1414:        int ntries;
                   1415:
1.33      christos 1416:        if (iwn_nic_lock(sc) == 0) {
                   1417:                IWN_WRITE(sc, IWN_FH_RX_CONFIG, 0);
                   1418:                for (ntries = 0; ntries < 1000; ntries++) {
                   1419:                        if (IWN_READ(sc, IWN_FH_RX_STATUS) &
                   1420:                            IWN_FH_RX_STATUS_IDLE)
                   1421:                                break;
                   1422:                        DELAY(10);
                   1423:                }
                   1424:                iwn_nic_unlock(sc);
1.1       ober     1425:        }
                   1426:        ring->cur = 0;
1.33      christos 1427:        sc->last_rx_valid = 0;
1.1       ober     1428: }
                   1429:
                   1430: static void
                   1431: iwn_free_rx_ring(struct iwn_softc *sc, struct iwn_rx_ring *ring)
                   1432: {
                   1433:        int i;
                   1434:
                   1435:        iwn_dma_contig_free(&ring->desc_dma);
1.33      christos 1436:        iwn_dma_contig_free(&ring->stat_dma);
1.1       ober     1437:
                   1438:        for (i = 0; i < IWN_RX_RING_COUNT; i++) {
1.33      christos 1439:                struct iwn_rx_data *data = &ring->data[i];
                   1440:
                   1441:                if (data->m != NULL) {
                   1442:                        bus_dmamap_sync(sc->sc_dmat, data->map, 0,
                   1443:                            data->map->dm_mapsize, BUS_DMASYNC_POSTREAD);
                   1444:                        bus_dmamap_unload(sc->sc_dmat, data->map);
                   1445:                        m_freem(data->m);
                   1446:                }
                   1447:                if (data->map != NULL)
                   1448:                        bus_dmamap_destroy(sc->sc_dmat, data->map);
1.1       ober     1449:        }
                   1450: }
                   1451:
                   1452: static int
1.40      christos 1453: iwn_alloc_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring, int qid)
1.1       ober     1454: {
1.33      christos 1455:        bus_addr_t paddr;
1.40      christos 1456:        bus_size_t size;
                   1457:        int i, error;
1.1       ober     1458:
                   1459:        ring->qid = qid;
                   1460:        ring->queued = 0;
                   1461:        ring->cur = 0;
                   1462:
1.53      christos 1463:        /* Allocate TX descriptors (256-byte aligned). */
1.40      christos 1464:        size = IWN_TX_RING_COUNT * sizeof (struct iwn_tx_desc);
1.1       ober     1465:        error = iwn_dma_contig_alloc(sc->sc_dmat, &ring->desc_dma,
1.40      christos 1466:            (void **)&ring->desc, size, 256);
1.1       ober     1467:        if (error != 0) {
1.33      christos 1468:                aprint_error_dev(sc->sc_dev,
                   1469:                    "could not allocate TX ring DMA memory\n");
1.1       ober     1470:                goto fail;
                   1471:        }
1.33      christos 1472:        /*
                   1473:         * We only use rings 0 through 4 (4 EDCA + cmd) so there is no need
                   1474:         * to allocate commands space for other rings.
                   1475:         * XXX Do we really need to allocate descriptors for other rings?
                   1476:         */
                   1477:        if (qid > 4)
                   1478:                return 0;
1.1       ober     1479:
1.40      christos 1480:        size = IWN_TX_RING_COUNT * sizeof (struct iwn_tx_cmd);
1.1       ober     1481:        error = iwn_dma_contig_alloc(sc->sc_dmat, &ring->cmd_dma,
1.40      christos 1482:            (void **)&ring->cmd, size, 4);
1.1       ober     1483:        if (error != 0) {
1.33      christos 1484:                aprint_error_dev(sc->sc_dev,
                   1485:                    "could not allocate TX cmd DMA memory\n");
1.1       ober     1486:                goto fail;
                   1487:        }
                   1488:
1.33      christos 1489:        paddr = ring->cmd_dma.paddr;
1.40      christos 1490:        for (i = 0; i < IWN_TX_RING_COUNT; i++) {
                   1491:                struct iwn_tx_data *data = &ring->data[i];
1.1       ober     1492:
1.33      christos 1493:                data->cmd_paddr = paddr;
                   1494:                data->scratch_paddr = paddr + 12;
                   1495:                paddr += sizeof (struct iwn_tx_cmd);
                   1496:
1.1       ober     1497:                error = bus_dmamap_create(sc->sc_dmat, MCLBYTES,
                   1498:                    IWN_MAX_SCATTER - 1, MCLBYTES, 0, BUS_DMA_NOWAIT,
                   1499:                    &data->map);
                   1500:                if (error != 0) {
1.33      christos 1501:                        aprint_error_dev(sc->sc_dev,
                   1502:                            "could not create TX buf DMA map\n");
1.1       ober     1503:                        goto fail;
                   1504:                }
                   1505:        }
                   1506:        return 0;
                   1507:
                   1508: fail:  iwn_free_tx_ring(sc, ring);
                   1509:        return error;
                   1510: }
                   1511:
                   1512: static void
                   1513: iwn_reset_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring)
                   1514: {
1.40      christos 1515:        int i;
1.1       ober     1516:
1.40      christos 1517:        for (i = 0; i < IWN_TX_RING_COUNT; i++) {
                   1518:                struct iwn_tx_data *data = &ring->data[i];
1.1       ober     1519:
                   1520:                if (data->m != NULL) {
1.33      christos 1521:                        bus_dmamap_sync(sc->sc_dmat, data->map, 0,
                   1522:                            data->map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
1.1       ober     1523:                        bus_dmamap_unload(sc->sc_dmat, data->map);
                   1524:                        m_freem(data->m);
                   1525:                        data->m = NULL;
                   1526:                }
                   1527:        }
1.33      christos 1528:        /* Clear TX descriptors. */
                   1529:        memset(ring->desc, 0, ring->desc_dma.size);
                   1530:        bus_dmamap_sync(sc->sc_dmat, ring->desc_dma.map, 0,
                   1531:            ring->desc_dma.size, BUS_DMASYNC_PREWRITE);
                   1532:        sc->qfullmsk &= ~(1 << ring->qid);
1.1       ober     1533:        ring->queued = 0;
                   1534:        ring->cur = 0;
                   1535: }
                   1536:
                   1537: static void
                   1538: iwn_free_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring)
                   1539: {
1.2       ober     1540:        int i;
1.1       ober     1541:
                   1542:        iwn_dma_contig_free(&ring->desc_dma);
                   1543:        iwn_dma_contig_free(&ring->cmd_dma);
                   1544:
1.40      christos 1545:        for (i = 0; i < IWN_TX_RING_COUNT; i++) {
                   1546:                struct iwn_tx_data *data = &ring->data[i];
                   1547:
                   1548:                if (data->m != NULL) {
                   1549:                        bus_dmamap_sync(sc->sc_dmat, data->map, 0,
                   1550:                            data->map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
                   1551:                        bus_dmamap_unload(sc->sc_dmat, data->map);
                   1552:                        m_freem(data->m);
1.1       ober     1553:                }
1.40      christos 1554:                if (data->map != NULL)
                   1555:                        bus_dmamap_destroy(sc->sc_dmat, data->map);
1.1       ober     1556:        }
                   1557: }
                   1558:
1.40      christos 1559: static void
                   1560: iwn5000_ict_reset(struct iwn_softc *sc)
                   1561: {
                   1562:        /* Disable interrupts. */
                   1563:        IWN_WRITE(sc, IWN_INT_MASK, 0);
                   1564:
                   1565:        /* Reset ICT table. */
                   1566:        memset(sc->ict, 0, IWN_ICT_SIZE);
1.84      nonaka   1567:        bus_dmamap_sync(sc->sc_dmat, sc->ict_dma.map, 0, IWN_ICT_SIZE,
                   1568:            BUS_DMASYNC_PREWRITE);
1.40      christos 1569:        sc->ict_cur = 0;
                   1570:
1.53      christos 1571:        /* Set physical address of ICT table (4KB aligned). */
1.40      christos 1572:        DPRINTF(("enabling ICT\n"));
                   1573:        IWN_WRITE(sc, IWN_DRAM_INT_TBL, IWN_DRAM_INT_TBL_ENABLE |
                   1574:            IWN_DRAM_INT_TBL_WRAP_CHECK | sc->ict_dma.paddr >> 12);
                   1575:
                   1576:        /* Enable periodic RX interrupt. */
                   1577:        sc->int_mask |= IWN_INT_RX_PERIODIC;
                   1578:        /* Switch to ICT interrupt mode in driver. */
                   1579:        sc->sc_flags |= IWN_FLAG_USE_ICT;
                   1580:
                   1581:        /* Re-enable interrupts. */
                   1582:        IWN_WRITE(sc, IWN_INT, 0xffffffff);
                   1583:        IWN_WRITE(sc, IWN_INT_MASK, sc->int_mask);
                   1584: }
                   1585:
1.33      christos 1586: static int
                   1587: iwn_read_eeprom(struct iwn_softc *sc)
1.1       ober     1588: {
1.53      christos 1589:        struct iwn_ops *ops = &sc->ops;
1.33      christos 1590:        struct ieee80211com *ic = &sc->sc_ic;
                   1591:        uint16_t val;
                   1592:        int error;
                   1593:
1.40      christos 1594:        /* Check whether adapter has an EEPROM or an OTPROM. */
                   1595:        if (sc->hw_type >= IWN_HW_REV_TYPE_1000 &&
                   1596:            (IWN_READ(sc, IWN_OTP_GP) & IWN_OTP_GP_DEV_SEL_OTP))
                   1597:                sc->sc_flags |= IWN_FLAG_HAS_OTPROM;
                   1598:        DPRINTF(("%s found\n", (sc->sc_flags & IWN_FLAG_HAS_OTPROM) ?
                   1599:            "OTPROM" : "EEPROM"));
                   1600:
                   1601:        /* Adapter has to be powered on for EEPROM access to work. */
                   1602:        if ((error = iwn_apm_init(sc)) != 0) {
                   1603:                aprint_error_dev(sc->sc_dev,
                   1604:                    "could not power ON adapter\n");
                   1605:                return error;
                   1606:        }
                   1607:
                   1608:        if ((IWN_READ(sc, IWN_EEPROM_GP) & 0x7) == 0) {
                   1609:                aprint_error_dev(sc->sc_dev,
                   1610:                    "bad ROM signature\n");
1.33      christos 1611:                return EIO;
                   1612:        }
                   1613:        if ((error = iwn_eeprom_lock(sc)) != 0) {
                   1614:                aprint_error_dev(sc->sc_dev,
1.40      christos 1615:                    "could not lock ROM (error=%d)\n", error);
1.33      christos 1616:                return error;
                   1617:        }
1.40      christos 1618:        if (sc->sc_flags & IWN_FLAG_HAS_OTPROM) {
                   1619:                if ((error = iwn_init_otprom(sc)) != 0) {
                   1620:                        aprint_error_dev(sc->sc_dev,
                   1621:                            "could not initialize OTPROM\n");
                   1622:                        return error;
                   1623:                }
                   1624:        }
1.33      christos 1625:
1.53      christos 1626:        iwn_read_prom_data(sc, IWN_EEPROM_SKU_CAP, &val, 2);
                   1627:        DPRINTF(("SKU capabilities=0x%04x\n", le16toh(val)));
                   1628:        /* Check if HT support is bonded out. */
                   1629:        if (val & htole16(IWN_EEPROM_SKU_CAP_11N))
                   1630:                sc->sc_flags |= IWN_FLAG_HAS_11N;
                   1631:
1.33      christos 1632:        iwn_read_prom_data(sc, IWN_EEPROM_RFCFG, &val, 2);
                   1633:        sc->rfcfg = le16toh(val);
                   1634:        DPRINTF(("radio config=0x%04x\n", sc->rfcfg));
1.53      christos 1635:        /* Read Tx/Rx chains from ROM unless it's known to be broken. */
                   1636:        if (sc->txchainmask == 0)
                   1637:                sc->txchainmask = IWN_RFCFG_TXANTMSK(sc->rfcfg);
                   1638:        if (sc->rxchainmask == 0)
                   1639:                sc->rxchainmask = IWN_RFCFG_RXANTMSK(sc->rfcfg);
1.33      christos 1640:
                   1641:        /* Read MAC address. */
1.92      bad      1642:        iwn_read_prom_data(sc, IWN_EEPROM_MAC, ic->ic_myaddr, ETHER_ADDR_LEN);
1.33      christos 1643:
                   1644:        /* Read adapter-specific information from EEPROM. */
1.53      christos 1645:        ops->read_eeprom(sc);
1.33      christos 1646:
1.40      christos 1647:        iwn_apm_stop(sc);       /* Power OFF adapter. */
                   1648:
1.33      christos 1649:        iwn_eeprom_unlock(sc);
                   1650:        return 0;
                   1651: }
                   1652:
                   1653: static void
                   1654: iwn4965_read_eeprom(struct iwn_softc *sc)
                   1655: {
                   1656:        uint32_t addr;
                   1657:        uint16_t val;
                   1658:        int i;
                   1659:
1.53      christos 1660:        /* Read regulatory domain (4 ASCII characters). */
1.33      christos 1661:        iwn_read_prom_data(sc, IWN4965_EEPROM_DOMAIN, sc->eeprom_domain, 4);
                   1662:
1.53      christos 1663:        /* Read the list of authorized channels (20MHz ones only). */
1.33      christos 1664:        for (i = 0; i < 5; i++) {
                   1665:                addr = iwn4965_regulatory_bands[i];
                   1666:                iwn_read_eeprom_channels(sc, i, addr);
                   1667:        }
                   1668:
                   1669:        /* Read maximum allowed TX power for 2GHz and 5GHz bands. */
                   1670:        iwn_read_prom_data(sc, IWN4965_EEPROM_MAXPOW, &val, 2);
                   1671:        sc->maxpwr2GHz = val & 0xff;
                   1672:        sc->maxpwr5GHz = val >> 8;
                   1673:        /* Check that EEPROM values are within valid range. */
                   1674:        if (sc->maxpwr5GHz < 20 || sc->maxpwr5GHz > 50)
                   1675:                sc->maxpwr5GHz = 38;
                   1676:        if (sc->maxpwr2GHz < 20 || sc->maxpwr2GHz > 50)
                   1677:                sc->maxpwr2GHz = 38;
                   1678:        DPRINTF(("maxpwr 2GHz=%d 5GHz=%d\n", sc->maxpwr2GHz, sc->maxpwr5GHz));
                   1679:
                   1680:        /* Read samples for each TX power group. */
                   1681:        iwn_read_prom_data(sc, IWN4965_EEPROM_BANDS, sc->bands,
                   1682:            sizeof sc->bands);
                   1683:
                   1684:        /* Read voltage at which samples were taken. */
                   1685:        iwn_read_prom_data(sc, IWN4965_EEPROM_VOLTAGE, &val, 2);
                   1686:        sc->eeprom_voltage = (int16_t)le16toh(val);
                   1687:        DPRINTF(("voltage=%d (in 0.3V)\n", sc->eeprom_voltage));
                   1688:
                   1689: #ifdef IWN_DEBUG
                   1690:        /* Print samples. */
                   1691:        if (iwn_debug > 0) {
                   1692:                for (i = 0; i < IWN_NBANDS; i++)
                   1693:                        iwn4965_print_power_group(sc, i);
                   1694:        }
                   1695: #endif
                   1696: }
                   1697:
                   1698: #ifdef IWN_DEBUG
                   1699: static void
                   1700: iwn4965_print_power_group(struct iwn_softc *sc, int i)
                   1701: {
                   1702:        struct iwn4965_eeprom_band *band = &sc->bands[i];
                   1703:        struct iwn4965_eeprom_chan_samples *chans = band->chans;
                   1704:        int j, c;
                   1705:
1.40      christos 1706:        aprint_normal("===band %d===\n", i);
                   1707:        aprint_normal("chan lo=%d, chan hi=%d\n", band->lo, band->hi);
                   1708:        aprint_normal("chan1 num=%d\n", chans[0].num);
1.33      christos 1709:        for (c = 0; c < 2; c++) {
                   1710:                for (j = 0; j < IWN_NSAMPLES; j++) {
1.40      christos 1711:                        aprint_normal("chain %d, sample %d: temp=%d gain=%d "
1.33      christos 1712:                            "power=%d pa_det=%d\n", c, j,
                   1713:                            chans[0].samples[c][j].temp,
                   1714:                            chans[0].samples[c][j].gain,
                   1715:                            chans[0].samples[c][j].power,
                   1716:                            chans[0].samples[c][j].pa_det);
                   1717:                }
                   1718:        }
1.40      christos 1719:        aprint_normal("chan2 num=%d\n", chans[1].num);
1.33      christos 1720:        for (c = 0; c < 2; c++) {
                   1721:                for (j = 0; j < IWN_NSAMPLES; j++) {
1.40      christos 1722:                        aprint_normal("chain %d, sample %d: temp=%d gain=%d "
1.33      christos 1723:                            "power=%d pa_det=%d\n", c, j,
                   1724:                            chans[1].samples[c][j].temp,
                   1725:                            chans[1].samples[c][j].gain,
                   1726:                            chans[1].samples[c][j].power,
                   1727:                            chans[1].samples[c][j].pa_det);
                   1728:                }
                   1729:        }
                   1730: }
                   1731: #endif
                   1732:
                   1733: static void
                   1734: iwn5000_read_eeprom(struct iwn_softc *sc)
                   1735: {
1.40      christos 1736:        struct iwn5000_eeprom_calib_hdr hdr;
1.53      christos 1737:        int32_t volt;
1.33      christos 1738:        uint32_t base, addr;
                   1739:        uint16_t val;
                   1740:        int i;
                   1741:
1.53      christos 1742:        /* Read regulatory domain (4 ASCII characters). */
1.33      christos 1743:        iwn_read_prom_data(sc, IWN5000_EEPROM_REG, &val, 2);
                   1744:        base = le16toh(val);
                   1745:        iwn_read_prom_data(sc, base + IWN5000_EEPROM_DOMAIN,
                   1746:            sc->eeprom_domain, 4);
                   1747:
1.53      christos 1748:        /* Read the list of authorized channels (20MHz ones only). */
1.33      christos 1749:        for (i = 0; i < 5; i++) {
                   1750:                addr = base + iwn5000_regulatory_bands[i];
                   1751:                iwn_read_eeprom_channels(sc, i, addr);
                   1752:        }
                   1753:
1.40      christos 1754:        /* Read enhanced TX power information for 6000 Series. */
                   1755:        if (sc->hw_type >= IWN_HW_REV_TYPE_6000)
                   1756:                iwn_read_eeprom_enhinfo(sc);
                   1757:
1.33      christos 1758:        iwn_read_prom_data(sc, IWN5000_EEPROM_CAL, &val, 2);
                   1759:        base = le16toh(val);
1.40      christos 1760:        iwn_read_prom_data(sc, base, &hdr, sizeof hdr);
                   1761:        DPRINTF(("calib version=%u pa type=%u voltage=%u\n",
                   1762:            hdr.version, hdr.pa_type, le16toh(hdr.volt)));
                   1763:        sc->calib_ver = hdr.version;
1.44      christos 1764:
1.72      nonaka   1765:        if (sc->hw_type == IWN_HW_REV_TYPE_2030 ||
                   1766:            sc->hw_type == IWN_HW_REV_TYPE_2000 ||
                   1767:            sc->hw_type == IWN_HW_REV_TYPE_135  ||
                   1768:            sc->hw_type == IWN_HW_REV_TYPE_105) {
                   1769:                sc->eeprom_voltage = le16toh(hdr.volt);
                   1770:                iwn_read_prom_data(sc, base + IWN5000_EEPROM_TEMP, &val, 2);
                   1771:                sc->eeprom_temp = le16toh(val);
                   1772:                iwn_read_prom_data(sc, base + IWN2000_EEPROM_RAWTEMP, &val, 2);
                   1773:                sc->eeprom_rawtemp = le16toh(val);
                   1774:        }
                   1775:
1.33      christos 1776:        if (sc->hw_type == IWN_HW_REV_TYPE_5150) {
1.40      christos 1777:                /* Compute temperature offset. */
1.33      christos 1778:                iwn_read_prom_data(sc, base + IWN5000_EEPROM_TEMP, &val, 2);
1.53      christos 1779:                sc->eeprom_temp = le16toh(val);
1.33      christos 1780:                iwn_read_prom_data(sc, base + IWN5000_EEPROM_VOLT, &val, 2);
                   1781:                volt = le16toh(val);
1.53      christos 1782:                sc->temp_off = sc->eeprom_temp - (volt / -5);
1.40      christos 1783:                DPRINTF(("temp=%d volt=%d offset=%dK\n",
1.53      christos 1784:                    sc->eeprom_temp, volt, sc->temp_off));
1.33      christos 1785:        } else {
                   1786:                /* Read crystal calibration. */
                   1787:                iwn_read_prom_data(sc, base + IWN5000_EEPROM_CRYSTAL,
                   1788:                    &sc->eeprom_crystal, sizeof (uint32_t));
                   1789:                DPRINTF(("crystal calibration 0x%08x\n",
                   1790:                    le32toh(sc->eeprom_crystal)));
                   1791:        }
                   1792: }
                   1793:
                   1794: static void
                   1795: iwn_read_eeprom_channels(struct iwn_softc *sc, int n, uint32_t addr)
                   1796: {
                   1797:        struct ieee80211com *ic = &sc->sc_ic;
                   1798:        const struct iwn_chan_band *band = &iwn_bands[n];
                   1799:        struct iwn_eeprom_chan channels[IWN_MAX_CHAN_PER_BAND];
                   1800:        uint8_t chan;
                   1801:        int i;
                   1802:
                   1803:        iwn_read_prom_data(sc, addr, channels,
                   1804:            band->nchan * sizeof (struct iwn_eeprom_chan));
                   1805:
                   1806:        for (i = 0; i < band->nchan; i++) {
                   1807:                if (!(channels[i].flags & IWN_EEPROM_CHAN_VALID))
                   1808:                        continue;
                   1809:
                   1810:                chan = band->chan[i];
                   1811:
                   1812:                if (n == 0) {   /* 2GHz band */
                   1813:                        ic->ic_channels[chan].ic_freq =
                   1814:                            ieee80211_ieee2mhz(chan, IEEE80211_CHAN_2GHZ);
                   1815:                        ic->ic_channels[chan].ic_flags =
                   1816:                            IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM |
                   1817:                            IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ;
                   1818:
                   1819:                } else {        /* 5GHz band */
                   1820:                        /*
                   1821:                         * Some adapters support channels 7, 8, 11 and 12
                   1822:                         * both in the 2GHz and 4.9GHz bands.
                   1823:                         * Because of limitations in our net80211 layer,
                   1824:                         * we don't support them in the 4.9GHz band.
                   1825:                         */
                   1826:                        if (chan <= 14)
                   1827:                                continue;
                   1828:
                   1829:                        ic->ic_channels[chan].ic_freq =
                   1830:                            ieee80211_ieee2mhz(chan, IEEE80211_CHAN_5GHZ);
                   1831:                        ic->ic_channels[chan].ic_flags = IEEE80211_CHAN_A;
                   1832:                        /* We have at least one valid 5GHz channel. */
                   1833:                        sc->sc_flags |= IWN_FLAG_HAS_5GHZ;
                   1834:                }
                   1835:
                   1836:                /* Is active scan allowed on this channel? */
                   1837:                if (!(channels[i].flags & IWN_EEPROM_CHAN_ACTIVE)) {
                   1838:                        ic->ic_channels[chan].ic_flags |=
                   1839:                            IEEE80211_CHAN_PASSIVE;
                   1840:                }
                   1841:
                   1842:                /* Save maximum allowed TX power for this channel. */
                   1843:                sc->maxpwr[chan] = channels[i].maxpwr;
                   1844:
                   1845:                DPRINTF(("adding chan %d flags=0x%x maxpwr=%d\n",
                   1846:                    chan, channels[i].flags, sc->maxpwr[chan]));
                   1847:        }
                   1848: }
                   1849:
1.40      christos 1850: static void
                   1851: iwn_read_eeprom_enhinfo(struct iwn_softc *sc)
                   1852: {
                   1853:        struct iwn_eeprom_enhinfo enhinfo[35];
                   1854:        uint16_t val, base;
                   1855:        int8_t maxpwr;
1.85      mlelstv  1856:        uint8_t flags;
1.40      christos 1857:        int i;
                   1858:
                   1859:        iwn_read_prom_data(sc, IWN5000_EEPROM_REG, &val, 2);
                   1860:        base = le16toh(val);
                   1861:        iwn_read_prom_data(sc, base + IWN6000_EEPROM_ENHINFO,
                   1862:            enhinfo, sizeof enhinfo);
                   1863:
                   1864:        memset(sc->enh_maxpwr, 0, sizeof sc->enh_maxpwr);
                   1865:        for (i = 0; i < __arraycount(enhinfo); i++) {
1.85      mlelstv  1866:                flags = enhinfo[i].flags;
                   1867:                if (!(flags & IWN_ENHINFO_VALID))
1.40      christos 1868:                        continue;       /* Skip invalid entries. */
                   1869:
                   1870:                maxpwr = 0;
                   1871:                if (sc->txchainmask & IWN_ANT_A)
                   1872:                        maxpwr = MAX(maxpwr, enhinfo[i].chain[0]);
                   1873:                if (sc->txchainmask & IWN_ANT_B)
                   1874:                        maxpwr = MAX(maxpwr, enhinfo[i].chain[1]);
                   1875:                if (sc->txchainmask & IWN_ANT_C)
                   1876:                        maxpwr = MAX(maxpwr, enhinfo[i].chain[2]);
                   1877:                if (sc->ntxchains == 2)
                   1878:                        maxpwr = MAX(maxpwr, enhinfo[i].mimo2);
                   1879:                else if (sc->ntxchains == 3)
                   1880:                        maxpwr = MAX(maxpwr, enhinfo[i].mimo3);
                   1881:                maxpwr /= 2;    /* Convert half-dBm to dBm. */
                   1882:
                   1883:                DPRINTF(("enhinfo %d, maxpwr=%d\n", i, maxpwr));
                   1884:                sc->enh_maxpwr[i] = maxpwr;
                   1885:        }
                   1886: }
                   1887:
1.33      christos 1888: static struct ieee80211_node *
1.40      christos 1889: iwn_node_alloc(struct ieee80211_node_table *ic __unused)
1.33      christos 1890: {
1.42      christos 1891:        return malloc(sizeof (struct iwn_node), M_80211_NODE, M_NOWAIT | M_ZERO);
1.1       ober     1892: }
                   1893:
                   1894: static void
                   1895: iwn_newassoc(struct ieee80211_node *ni, int isnew)
                   1896: {
                   1897:        struct iwn_softc *sc = ni->ni_ic->ic_ifp->if_softc;
1.33      christos 1898:        struct iwn_node *wn = (void *)ni;
                   1899:        uint8_t rate;
                   1900:        int ridx, i;
                   1901:
                   1902:        ieee80211_amrr_node_init(&sc->amrr, &wn->amn);
1.40      christos 1903:        /* Start at lowest available bit-rate, AMRR will raise. */
                   1904:        ni->ni_txrate = 0;
1.33      christos 1905:
                   1906:        for (i = 0; i < ni->ni_rates.rs_nrates; i++) {
                   1907:                rate = ni->ni_rates.rs_rates[i] & IEEE80211_RATE_VAL;
                   1908:                /* Map 802.11 rate to HW rate index. */
                   1909:                for (ridx = 0; ridx <= IWN_RIDX_MAX; ridx++)
                   1910:                        if (iwn_rates[ridx].rate == rate)
                   1911:                                break;
                   1912:                wn->ridx[i] = ridx;
                   1913:        }
1.1       ober     1914: }
                   1915:
                   1916: static int
                   1917: iwn_media_change(struct ifnet *ifp)
                   1918: {
1.33      christos 1919:        struct iwn_softc *sc = ifp->if_softc;
                   1920:        struct ieee80211com *ic = &sc->sc_ic;
                   1921:        uint8_t rate, ridx;
1.1       ober     1922:        int error;
                   1923:
                   1924:        error = ieee80211_media_change(ifp);
                   1925:        if (error != ENETRESET)
                   1926:                return error;
                   1927:
1.33      christos 1928:        if (ic->ic_fixed_rate != -1) {
                   1929:                rate = ic->ic_sup_rates[ic->ic_curmode].
                   1930:                    rs_rates[ic->ic_fixed_rate] & IEEE80211_RATE_VAL;
                   1931:                /* Map 802.11 rate to HW rate index. */
                   1932:                for (ridx = 0; ridx <= IWN_RIDX_MAX; ridx++)
                   1933:                        if (iwn_rates[ridx].rate == rate)
                   1934:                                break;
                   1935:                sc->fixed_ridx = ridx;
                   1936:        }
1.1       ober     1937:
1.33      christos 1938:        if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
                   1939:            (IFF_UP | IFF_RUNNING)) {
                   1940:                iwn_stop(ifp, 0);
                   1941:                error = iwn_init(ifp);
                   1942:        }
                   1943:        return error;
1.1       ober     1944: }
                   1945:
                   1946: static int
                   1947: iwn_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
                   1948: {
                   1949:        struct ifnet *ifp = ic->ic_ifp;
                   1950:        struct iwn_softc *sc = ifp->if_softc;
                   1951:        int error;
                   1952:
                   1953:        callout_stop(&sc->calib_to);
                   1954:
                   1955:        switch (nstate) {
                   1956:        case IEEE80211_S_SCAN:
1.44      christos 1957:                /* XXX Do not abort a running scan. */
1.40      christos 1958:                if (sc->sc_flags & IWN_FLAG_SCANNING) {
1.47      christos 1959:                        if (ic->ic_state != nstate)
1.79      mlelstv  1960:                                aprint_debug_dev(sc->sc_dev, "scan request(%d) "
1.47      christos 1961:                                    "while scanning(%d) ignored\n", nstate,
                   1962:                                    ic->ic_state);
1.1       ober     1963:                        break;
1.40      christos 1964:                }
                   1965:
1.44      christos 1966:                /* XXX Not sure if call and flags are needed. */
1.1       ober     1967:                ieee80211_node_table_reset(&ic->ic_scan);
                   1968:                ic->ic_flags |= IEEE80211_F_SCAN | IEEE80211_F_ASCAN;
1.76      nonaka   1969:                sc->sc_flags |= IWN_FLAG_SCANNING_2GHZ;
1.1       ober     1970:
1.33      christos 1971:                /* Make the link LED blink while we're scanning. */
                   1972:                iwn_set_led(sc, IWN_LED_LINK, 10, 10);
1.1       ober     1973:
1.33      christos 1974:                if ((error = iwn_scan(sc, IEEE80211_CHAN_2GHZ)) != 0) {
                   1975:                        aprint_error_dev(sc->sc_dev,
                   1976:                            "could not initiate scan\n");
1.1       ober     1977:                        return error;
                   1978:                }
                   1979:                ic->ic_state = nstate;
                   1980:                return 0;
                   1981:
                   1982:        case IEEE80211_S_ASSOC:
                   1983:                if (ic->ic_state != IEEE80211_S_RUN)
                   1984:                        break;
                   1985:                /* FALLTHROUGH */
                   1986:        case IEEE80211_S_AUTH:
1.33      christos 1987:                /* Reset state to handle reassociations correctly. */
                   1988:                sc->rxon.associd = 0;
                   1989:                sc->rxon.filter &= ~htole32(IWN_FILTER_BSS);
                   1990:                sc->calib.state = IWN_CALIB_STATE_INIT;
1.1       ober     1991:
1.85      mlelstv  1992:                /* Wait until we hear a beacon before we transmit */
                   1993:                if (IEEE80211_IS_CHAN_PASSIVE(ic->ic_curchan))
                   1994:                        sc->sc_beacon_wait = 1;
                   1995:
1.1       ober     1996:                if ((error = iwn_auth(sc)) != 0) {
1.20      blymn    1997:                        aprint_error_dev(sc->sc_dev,
1.33      christos 1998:                            "could not move to auth state\n");
1.1       ober     1999:                        return error;
                   2000:                }
                   2001:                break;
                   2002:
                   2003:        case IEEE80211_S_RUN:
1.85      mlelstv  2004:                /*
                   2005:                 * RUN -> RUN transition; Just restart timers.
                   2006:                 */
                   2007:                if (ic->ic_state == IEEE80211_S_RUN) {
                   2008:                        sc->calib_cnt = 0;
                   2009:                        break;
                   2010:                }
                   2011:
                   2012:                /* Wait until we hear a beacon before we transmit */
                   2013:                if (IEEE80211_IS_CHAN_PASSIVE(ic->ic_curchan))
                   2014:                        sc->sc_beacon_wait = 1;
                   2015:
1.1       ober     2016:                if ((error = iwn_run(sc)) != 0) {
1.20      blymn    2017:                        aprint_error_dev(sc->sc_dev,
1.33      christos 2018:                            "could not move to run state\n");
1.1       ober     2019:                        return error;
                   2020:                }
                   2021:                break;
                   2022:
                   2023:        case IEEE80211_S_INIT:
1.40      christos 2024:                sc->sc_flags &= ~IWN_FLAG_SCANNING;
1.33      christos 2025:                sc->calib.state = IWN_CALIB_STATE_INIT;
1.85      mlelstv  2026:                /*
                   2027:                 * Purge the xmit queue so we don't have old frames
                   2028:                 * during a new association attempt.
                   2029:                 */
                   2030:                sc->sc_beacon_wait = 0;
                   2031:                ifp->if_flags &= ~IFF_OACTIVE;
                   2032:                iwn_start(ifp);
1.1       ober     2033:                break;
                   2034:        }
                   2035:
                   2036:        return sc->sc_newstate(ic, nstate, arg);
                   2037: }
                   2038:
                   2039: static void
1.33      christos 2040: iwn_iter_func(void *arg, struct ieee80211_node *ni)
1.1       ober     2041: {
1.33      christos 2042:        struct iwn_softc *sc = arg;
                   2043:        struct iwn_node *wn = (struct iwn_node *)ni;
1.1       ober     2044:
1.33      christos 2045:        ieee80211_amrr_choose(&sc->amrr, ni, &wn->amn);
1.1       ober     2046: }
                   2047:
                   2048: static void
1.33      christos 2049: iwn_calib_timeout(void *arg)
1.1       ober     2050: {
1.33      christos 2051:        struct iwn_softc *sc = arg;
                   2052:        struct ieee80211com *ic = &sc->sc_ic;
                   2053:        int s;
1.1       ober     2054:
1.40      christos 2055:        s = splnet();
1.33      christos 2056:        if (ic->ic_fixed_rate == -1) {
                   2057:                if (ic->ic_opmode == IEEE80211_M_STA)
                   2058:                        iwn_iter_func(sc, ic->ic_bss);
                   2059:                else
                   2060:                        ieee80211_iterate_nodes(&ic->ic_sta, iwn_iter_func, sc);
                   2061:        }
                   2062:        /* Force automatic TX power calibration every 60 secs. */
                   2063:        if (++sc->calib_cnt >= 120) {
                   2064:                uint32_t flags = 0;
1.1       ober     2065:
1.33      christos 2066:                DPRINTF(("sending request for statistics\n"));
                   2067:                (void)iwn_cmd(sc, IWN_CMD_GET_STATISTICS, &flags,
                   2068:                    sizeof flags, 1);
                   2069:                sc->calib_cnt = 0;
                   2070:        }
1.40      christos 2071:        splx(s);
                   2072:
1.33      christos 2073:        /* Automatic rate control triggered every 500ms. */
1.84      nonaka   2074:        callout_schedule(&sc->calib_to, mstohz(500));
1.1       ober     2075: }
                   2076:
                   2077: /*
1.33      christos 2078:  * Process an RX_PHY firmware notification.  This is usually immediately
                   2079:  * followed by an MPDU_RX_DONE notification.
1.1       ober     2080:  */
1.40      christos 2081: static void
                   2082: iwn_rx_phy(struct iwn_softc *sc, struct iwn_rx_desc *desc,
                   2083:     struct iwn_rx_data *data)
1.1       ober     2084: {
1.33      christos 2085:        struct iwn_rx_stat *stat = (struct iwn_rx_stat *)(desc + 1);
1.1       ober     2086:
1.33      christos 2087:        DPRINTFN(2, ("received PHY stats\n"));
1.40      christos 2088:        bus_dmamap_sync(sc->sc_dmat, data->map, sizeof (*desc),
                   2089:            sizeof (*stat), BUS_DMASYNC_POSTREAD);
1.1       ober     2090:
1.33      christos 2091:        /* Save RX statistics, they will be used on MPDU_RX_DONE. */
                   2092:        memcpy(&sc->last_rx_stat, stat, sizeof (*stat));
                   2093:        sc->last_rx_valid = 1;
1.1       ober     2094: }
                   2095:
                   2096: /*
1.33      christos 2097:  * Process an RX_DONE (4965AGN only) or MPDU_RX_DONE firmware notification.
                   2098:  * Each MPDU_RX_DONE notification must be preceded by an RX_PHY one.
1.1       ober     2099:  */
1.40      christos 2100: static void
1.33      christos 2101: iwn_rx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc,
                   2102:     struct iwn_rx_data *data)
1.1       ober     2103: {
1.53      christos 2104:        struct iwn_ops *ops = &sc->ops;
1.33      christos 2105:        struct ieee80211com *ic = &sc->sc_ic;
                   2106:        struct ifnet *ifp = ic->ic_ifp;
                   2107:        struct iwn_rx_ring *ring = &sc->rxq;
                   2108:        struct ieee80211_frame *wh;
                   2109:        struct ieee80211_node *ni;
                   2110:        struct mbuf *m, *m1;
                   2111:        struct iwn_rx_stat *stat;
1.40      christos 2112:        char    *head;
1.33      christos 2113:        uint32_t flags;
1.84      nonaka   2114:        int error, len, rssi, s;
1.1       ober     2115:
1.33      christos 2116:        if (desc->type == IWN_MPDU_RX_DONE) {
                   2117:                /* Check for prior RX_PHY notification. */
                   2118:                if (!sc->last_rx_valid) {
                   2119:                        DPRINTF(("missing RX_PHY\n"));
                   2120:                        return;
                   2121:                }
                   2122:                sc->last_rx_valid = 0;
                   2123:                stat = &sc->last_rx_stat;
                   2124:        } else
                   2125:                stat = (struct iwn_rx_stat *)(desc + 1);
1.1       ober     2126:
1.33      christos 2127:        bus_dmamap_sync(sc->sc_dmat, data->map, 0, IWN_RBUF_SIZE,
                   2128:            BUS_DMASYNC_POSTREAD);
1.1       ober     2129:
1.33      christos 2130:        if (stat->cfg_phy_len > IWN_STAT_MAXLEN) {
1.40      christos 2131:                aprint_error_dev(sc->sc_dev,
                   2132:                    "invalid RX statistic header\n");
1.33      christos 2133:                return;
                   2134:        }
                   2135:        if (desc->type == IWN_MPDU_RX_DONE) {
1.40      christos 2136:                struct iwn_rx_mpdu *mpdu = (struct iwn_rx_mpdu *)(desc + 1);
1.33      christos 2137:                head = (char *)(mpdu + 1);
                   2138:                len = le16toh(mpdu->len);
                   2139:        } else {
                   2140:                head = (char *)(stat + 1) + stat->cfg_phy_len;
                   2141:                len = le16toh(stat->len);
                   2142:        }
1.1       ober     2143:
1.33      christos 2144:        flags = le32toh(*(uint32_t *)(head + len));
1.1       ober     2145:
1.33      christos 2146:        /* Discard frames with a bad FCS early. */
                   2147:        if ((flags & IWN_RX_NOERROR) != IWN_RX_NOERROR) {
                   2148:                DPRINTFN(2, ("RX flags error %x\n", flags));
1.93      thorpej  2149:                if_statinc(ifp, if_ierrors);
1.33      christos 2150:                return;
1.1       ober     2151:        }
1.33      christos 2152:        /* Discard frames that are too short. */
1.40      christos 2153:        if (len < sizeof (*wh)) {
1.33      christos 2154:                DPRINTF(("frame too short: %d\n", len));
                   2155:                ic->ic_stats.is_rx_tooshort++;
1.93      thorpej  2156:                if_statinc(ifp, if_ierrors);
1.33      christos 2157:                return;
1.1       ober     2158:        }
                   2159:
1.40      christos 2160:        m1 = MCLGETIalt(sc, M_DONTWAIT, NULL, IWN_RBUF_SIZE);
1.33      christos 2161:        if (m1 == NULL) {
                   2162:                ic->ic_stats.is_rx_nobuf++;
1.93      thorpej  2163:                if_statinc(ifp, if_ierrors);
1.33      christos 2164:                return;
1.1       ober     2165:        }
1.33      christos 2166:        bus_dmamap_unload(sc->sc_dmat, data->map);
1.1       ober     2167:
1.40      christos 2168:        error = bus_dmamap_load(sc->sc_dmat, data->map, mtod(m1, void *),
                   2169:            IWN_RBUF_SIZE, NULL, BUS_DMA_NOWAIT | BUS_DMA_READ);
1.33      christos 2170:        if (error != 0) {
                   2171:                m_freem(m1);
1.1       ober     2172:
1.33      christos 2173:                /* Try to reload the old mbuf. */
                   2174:                error = bus_dmamap_load(sc->sc_dmat, data->map,
1.40      christos 2175:                    mtod(data->m, void *), IWN_RBUF_SIZE, NULL,
                   2176:                    BUS_DMA_NOWAIT | BUS_DMA_READ);
1.33      christos 2177:                if (error != 0) {
                   2178:                        panic("%s: could not load old RX mbuf",
                   2179:                            device_xname(sc->sc_dev));
                   2180:                }
                   2181:                /* Physical address may have changed. */
                   2182:                ring->desc[ring->cur] =
                   2183:                    htole32(data->map->dm_segs[0].ds_addr >> 8);
                   2184:                bus_dmamap_sync(sc->sc_dmat, ring->desc_dma.map,
                   2185:                    ring->cur * sizeof (uint32_t), sizeof (uint32_t),
                   2186:                    BUS_DMASYNC_PREWRITE);
1.93      thorpej  2187:                if_statinc(ifp, if_ierrors);
1.1       ober     2188:                return;
                   2189:        }
1.40      christos 2190:
1.33      christos 2191:        m = data->m;
                   2192:        data->m = m1;
                   2193:        /* Update RX descriptor. */
                   2194:        ring->desc[ring->cur] = htole32(data->map->dm_segs[0].ds_addr >> 8);
                   2195:        bus_dmamap_sync(sc->sc_dmat, ring->desc_dma.map,
                   2196:            ring->cur * sizeof (uint32_t), sizeof (uint32_t),
                   2197:            BUS_DMASYNC_PREWRITE);
1.1       ober     2198:
1.33      christos 2199:        /* Finalize mbuf. */
1.78      ozaki-r  2200:        m_set_rcvif(m, ifp);
1.1       ober     2201:        m->m_data = head;
                   2202:        m->m_pkthdr.len = m->m_len = len;
                   2203:
1.84      nonaka   2204:        s = splnet();
                   2205:
1.33      christos 2206:        /* Grab a reference to the source node. */
                   2207:        wh = mtod(m, struct ieee80211_frame *);
1.40      christos 2208:        ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh);
1.33      christos 2209:
1.44      christos 2210:        /* XXX OpenBSD adds decryption here (see also comments in iwn_tx). */
                   2211:        /* NetBSD does decryption in ieee80211_input. */
                   2212:
1.53      christos 2213:        rssi = ops->get_rssi(stat);
1.1       ober     2214:
1.44      christos 2215:        /* XXX Added for NetBSD: scans never stop without it */
1.22      rtr      2216:        if (ic->ic_state == IEEE80211_S_SCAN)
1.76      nonaka   2217:                iwn_fix_channel(ic, m, stat);
1.1       ober     2218:
                   2219:        if (sc->sc_drvbpf != NULL) {
1.2       ober     2220:                struct iwn_rx_radiotap_header *tap = &sc->sc_rxtap;
1.1       ober     2221:
                   2222:                tap->wr_flags = 0;
1.33      christos 2223:                if (stat->flags & htole16(IWN_STAT_FLAG_SHPREAMBLE))
                   2224:                        tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
1.1       ober     2225:                tap->wr_chan_freq =
                   2226:                    htole16(ic->ic_channels[stat->chan].ic_freq);
                   2227:                tap->wr_chan_flags =
                   2228:                    htole16(ic->ic_channels[stat->chan].ic_flags);
                   2229:                tap->wr_dbm_antsignal = (int8_t)rssi;
                   2230:                tap->wr_dbm_antnoise = (int8_t)sc->noise;
                   2231:                tap->wr_tsft = stat->tstamp;
                   2232:                switch (stat->rate) {
1.33      christos 2233:                /* CCK rates. */
1.1       ober     2234:                case  10: tap->wr_rate =   2; break;
                   2235:                case  20: tap->wr_rate =   4; break;
                   2236:                case  55: tap->wr_rate =  11; break;
                   2237:                case 110: tap->wr_rate =  22; break;
1.33      christos 2238:                /* OFDM rates. */
1.1       ober     2239:                case 0xd: tap->wr_rate =  12; break;
                   2240:                case 0xf: tap->wr_rate =  18; break;
                   2241:                case 0x5: tap->wr_rate =  24; break;
                   2242:                case 0x7: tap->wr_rate =  36; break;
                   2243:                case 0x9: tap->wr_rate =  48; break;
                   2244:                case 0xb: tap->wr_rate =  72; break;
                   2245:                case 0x1: tap->wr_rate =  96; break;
                   2246:                case 0x3: tap->wr_rate = 108; break;
1.33      christos 2247:                /* Unknown rate: should not happen. */
1.1       ober     2248:                default:  tap->wr_rate =   0;
                   2249:                }
                   2250:
1.90      msaitoh  2251:                bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_rxtap_len, m, BPF_D_IN);
1.1       ober     2252:        }
                   2253:
1.85      mlelstv  2254:        /*
                   2255:         * If it's a beacon and we're waiting, then do the wakeup.
                   2256:         */
                   2257:        if (sc->sc_beacon_wait) {
                   2258:                uint8_t type, subtype;
                   2259:                type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
                   2260:                subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
                   2261:                /*
                   2262:                 * This assumes at this point we've received our own
                   2263:                 * beacon.
                   2264:                 */
                   2265:                if (type == IEEE80211_FC0_TYPE_MGT &&
                   2266:                    subtype == IEEE80211_FC0_SUBTYPE_BEACON) {
                   2267:                        sc->sc_beacon_wait = 0;
                   2268:                        ifp->if_flags &= ~IFF_OACTIVE;
                   2269:                        iwn_start(ifp);
                   2270:                }
                   2271:        }
                   2272:
1.33      christos 2273:        /* Send the frame to the 802.11 layer. */
1.1       ober     2274:        ieee80211_input(ic, m, ni, rssi, 0);
                   2275:
1.33      christos 2276:        /* Node is no longer needed. */
1.1       ober     2277:        ieee80211_free_node(ni);
1.84      nonaka   2278:
                   2279:        splx(s);
1.1       ober     2280: }
                   2281:
1.40      christos 2282: #ifndef IEEE80211_NO_HT
                   2283: /* Process an incoming Compressed BlockAck. */
                   2284: static void
                   2285: iwn_rx_compressed_ba(struct iwn_softc *sc, struct iwn_rx_desc *desc,
                   2286:     struct iwn_rx_data *data)
                   2287: {
                   2288:        struct iwn_compressed_ba *ba = (struct iwn_compressed_ba *)(desc + 1);
                   2289:        struct iwn_tx_ring *txq;
                   2290:
                   2291:        bus_dmamap_sync(sc->sc_dmat, data->map, sizeof (*desc), sizeof (*ba),
                   2292:            BUS_DMASYNC_POSTREAD);
                   2293:
                   2294:        txq = &sc->txq[le16toh(ba->qid)];
                   2295:        /* XXX TBD */
                   2296: }
                   2297: #endif
                   2298:
1.33      christos 2299: /*
                   2300:  * Process a CALIBRATION_RESULT notification sent by the initialization
1.53      christos 2301:  * firmware on response to a CMD_CALIB_CONFIG command (5000 only).
1.33      christos 2302:  */
1.40      christos 2303: static void
1.33      christos 2304: iwn5000_rx_calib_results(struct iwn_softc *sc, struct iwn_rx_desc *desc,
                   2305:     struct iwn_rx_data *data)
                   2306: {
                   2307:        struct iwn_phy_calib *calib = (struct iwn_phy_calib *)(desc + 1);
                   2308:        int len, idx = -1;
                   2309:
                   2310:        /* Runtime firmware should not send such a notification. */
1.40      christos 2311:        if (sc->sc_flags & IWN_FLAG_CALIB_DONE)
1.33      christos 2312:                return;
                   2313:
                   2314:        len = (le32toh(desc->len) & 0x3fff) - 4;
                   2315:        bus_dmamap_sync(sc->sc_dmat, data->map, sizeof (*desc), len,
                   2316:            BUS_DMASYNC_POSTREAD);
                   2317:
                   2318:        switch (calib->code) {
                   2319:        case IWN5000_PHY_CALIB_DC:
1.72      nonaka   2320:                if (sc->hw_type == IWN_HW_REV_TYPE_5150 ||
                   2321:                    sc->hw_type == IWN_HW_REV_TYPE_2030 ||
                   2322:                    sc->hw_type == IWN_HW_REV_TYPE_2000 ||
                   2323:                    sc->hw_type == IWN_HW_REV_TYPE_135  ||
                   2324:                    sc->hw_type == IWN_HW_REV_TYPE_105)
1.33      christos 2325:                        idx = 0;
                   2326:                break;
                   2327:        case IWN5000_PHY_CALIB_LO:
                   2328:                idx = 1;
                   2329:                break;
                   2330:        case IWN5000_PHY_CALIB_TX_IQ:
                   2331:                idx = 2;
                   2332:                break;
1.40      christos 2333:        case IWN5000_PHY_CALIB_TX_IQ_PERIODIC:
                   2334:                if (sc->hw_type < IWN_HW_REV_TYPE_6000 &&
                   2335:                    sc->hw_type != IWN_HW_REV_TYPE_5150)
1.33      christos 2336:                        idx = 3;
                   2337:                break;
                   2338:        case IWN5000_PHY_CALIB_BASE_BAND:
                   2339:                idx = 4;
                   2340:                break;
                   2341:        }
                   2342:        if (idx == -1)  /* Ignore other results. */
                   2343:                return;
                   2344:
                   2345:        /* Save calibration result. */
                   2346:        if (sc->calibcmd[idx].buf != NULL)
                   2347:                free(sc->calibcmd[idx].buf, M_DEVBUF);
                   2348:        sc->calibcmd[idx].buf = malloc(len, M_DEVBUF, M_NOWAIT);
                   2349:        if (sc->calibcmd[idx].buf == NULL) {
                   2350:                DPRINTF(("not enough memory for calibration result %d\n",
                   2351:                    calib->code));
                   2352:                return;
                   2353:        }
                   2354:        DPRINTF(("saving calibration result code=%d len=%d\n",
                   2355:            calib->code, len));
                   2356:        sc->calibcmd[idx].len = len;
                   2357:        memcpy(sc->calibcmd[idx].buf, calib, len);
                   2358: }
                   2359:
                   2360: /*
                   2361:  * Process an RX_STATISTICS or BEACON_STATISTICS firmware notification.
                   2362:  * The latter is sent by the firmware after each received beacon.
                   2363:  */
1.1       ober     2364: static void
1.33      christos 2365: iwn_rx_statistics(struct iwn_softc *sc, struct iwn_rx_desc *desc,
                   2366:     struct iwn_rx_data *data)
1.1       ober     2367: {
1.53      christos 2368:        struct iwn_ops *ops = &sc->ops;
1.1       ober     2369:        struct ieee80211com *ic = &sc->sc_ic;
                   2370:        struct iwn_calib_state *calib = &sc->calib;
                   2371:        struct iwn_stats *stats = (struct iwn_stats *)(desc + 1);
1.40      christos 2372:        int temp;
1.1       ober     2373:
1.33      christos 2374:        /* Ignore statistics received during a scan. */
1.1       ober     2375:        if (ic->ic_state != IEEE80211_S_RUN)
                   2376:                return;
                   2377:
1.33      christos 2378:        bus_dmamap_sync(sc->sc_dmat, data->map, sizeof (*desc),
                   2379:            sizeof (*stats), BUS_DMASYNC_POSTREAD);
                   2380:
1.1       ober     2381:        DPRINTFN(3, ("received statistics (cmd=%d)\n", desc->type));
1.33      christos 2382:        sc->calib_cnt = 0;      /* Reset TX power calibration timeout. */
1.1       ober     2383:
1.33      christos 2384:        /* Test if temperature has changed. */
1.1       ober     2385:        if (stats->general.temp != sc->rawtemp) {
1.33      christos 2386:                /* Convert "raw" temperature to degC. */
1.1       ober     2387:                sc->rawtemp = stats->general.temp;
1.53      christos 2388:                temp = ops->get_temperature(sc);
1.33      christos 2389:                DPRINTFN(2, ("temperature=%dC\n", temp));
1.1       ober     2390:
1.53      christos 2391:                /* Update TX power if need be (4965AGN only). */
1.33      christos 2392:                if (sc->hw_type == IWN_HW_REV_TYPE_4965)
                   2393:                        iwn4965_power_calibration(sc, temp);
1.1       ober     2394:        }
                   2395:
                   2396:        if (desc->type != IWN_BEACON_STATISTICS)
1.33      christos 2397:                return; /* Reply to a statistics request. */
1.1       ober     2398:
                   2399:        sc->noise = iwn_get_noise(&stats->rx.general);
                   2400:
1.33      christos 2401:        /* Test that RSSI and noise are present in stats report. */
1.1       ober     2402:        if (le32toh(stats->rx.general.flags) != 1) {
                   2403:                DPRINTF(("received statistics without RSSI\n"));
                   2404:                return;
                   2405:        }
                   2406:
1.59      elric    2407:        /*
                   2408:         * XXX Differential gain calibration makes the 6005 firmware
                   2409:         * crap out, so skip it for now.  This effectively disables
                   2410:         * sensitivity tuning as well.
                   2411:         */
                   2412:        if (sc->hw_type == IWN_HW_REV_TYPE_6005)
                   2413:                return;
                   2414:
1.1       ober     2415:        if (calib->state == IWN_CALIB_STATE_ASSOC)
1.33      christos 2416:                iwn_collect_noise(sc, &stats->rx.general);
1.1       ober     2417:        else if (calib->state == IWN_CALIB_STATE_RUN)
                   2418:                iwn_tune_sensitivity(sc, &stats->rx);
                   2419: }
                   2420:
1.33      christos 2421: /*
                   2422:  * Process a TX_DONE firmware notification.  Unfortunately, the 4965AGN
                   2423:  * and 5000 adapters have different incompatible TX status formats.
                   2424:  */
                   2425: static void
                   2426: iwn4965_tx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc,
                   2427:     struct iwn_rx_data *data)
                   2428: {
                   2429:        struct iwn4965_tx_stat *stat = (struct iwn4965_tx_stat *)(desc + 1);
                   2430:
                   2431:        bus_dmamap_sync(sc->sc_dmat, data->map, sizeof (*desc),
                   2432:            sizeof (*stat), BUS_DMASYNC_POSTREAD);
1.40      christos 2433:        iwn_tx_done(sc, desc, stat->ackfailcnt, le32toh(stat->status) & 0xff);
1.33      christos 2434: }
                   2435:
                   2436: static void
                   2437: iwn5000_tx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc,
                   2438:     struct iwn_rx_data *data)
                   2439: {
                   2440:        struct iwn5000_tx_stat *stat = (struct iwn5000_tx_stat *)(desc + 1);
                   2441:
1.40      christos 2442: #ifdef notyet
1.33      christos 2443:        /* Reset TX scheduler slot. */
                   2444:        iwn5000_reset_sched(sc, desc->qid & 0xf, desc->idx);
1.40      christos 2445: #endif
1.33      christos 2446:
                   2447:        bus_dmamap_sync(sc->sc_dmat, data->map, sizeof (*desc),
                   2448:            sizeof (*stat), BUS_DMASYNC_POSTREAD);
1.40      christos 2449:        iwn_tx_done(sc, desc, stat->ackfailcnt, le16toh(stat->status) & 0xff);
1.33      christos 2450: }
                   2451:
                   2452: /*
                   2453:  * Adapter-independent backend for TX_DONE firmware notifications.
                   2454:  */
1.1       ober     2455: static void
1.40      christos 2456: iwn_tx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc, int ackfailcnt,
1.33      christos 2457:     uint8_t status)
1.1       ober     2458: {
1.40      christos 2459:        struct ieee80211com *ic = &sc->sc_ic;
                   2460:        struct ifnet *ifp = ic->ic_ifp;
1.1       ober     2461:        struct iwn_tx_ring *ring = &sc->txq[desc->qid & 0xf];
1.33      christos 2462:        struct iwn_tx_data *data = &ring->data[desc->idx];
                   2463:        struct iwn_node *wn = (struct iwn_node *)data->ni;
1.84      nonaka   2464:        int s;
                   2465:
                   2466:        s = splnet();
1.1       ober     2467:
1.33      christos 2468:        /* Update rate control statistics. */
1.1       ober     2469:        wn->amn.amn_txcnt++;
1.40      christos 2470:        if (ackfailcnt > 0)
1.1       ober     2471:                wn->amn.amn_retrycnt++;
                   2472:
                   2473:        if (status != 1 && status != 2)
1.93      thorpej  2474:                if_statinc(ifp, if_oerrors);
1.1       ober     2475:        else
1.93      thorpej  2476:                if_statinc(ifp, if_opackets);
1.1       ober     2477:
1.33      christos 2478:        /* Unmap and free mbuf. */
                   2479:        bus_dmamap_sync(sc->sc_dmat, data->map, 0, data->map->dm_mapsize,
                   2480:            BUS_DMASYNC_POSTWRITE);
                   2481:        bus_dmamap_unload(sc->sc_dmat, data->map);
                   2482:        m_freem(data->m);
                   2483:        data->m = NULL;
                   2484:        ieee80211_free_node(data->ni);
                   2485:        data->ni = NULL;
1.1       ober     2486:
                   2487:        sc->sc_tx_timer = 0;
1.33      christos 2488:        if (--ring->queued < IWN_TX_RING_LOMARK) {
                   2489:                sc->qfullmsk &= ~(1 << ring->qid);
                   2490:                if (sc->qfullmsk == 0 && (ifp->if_flags & IFF_OACTIVE)) {
                   2491:                        ifp->if_flags &= ~IFF_OACTIVE;
1.84      nonaka   2492:                        iwn_start(ifp);
1.33      christos 2493:                }
                   2494:        }
1.84      nonaka   2495:
                   2496:        splx(s);
1.1       ober     2497: }
                   2498:
1.33      christos 2499: /*
                   2500:  * Process a "command done" firmware notification.  This is where we wakeup
                   2501:  * processes waiting for a synchronous command completion.
                   2502:  */
1.1       ober     2503: static void
1.33      christos 2504: iwn_cmd_done(struct iwn_softc *sc, struct iwn_rx_desc *desc)
1.1       ober     2505: {
                   2506:        struct iwn_tx_ring *ring = &sc->txq[4];
                   2507:        struct iwn_tx_data *data;
                   2508:
                   2509:        if ((desc->qid & 0xf) != 4)
1.33      christos 2510:                return; /* Not a command ack. */
1.1       ober     2511:
                   2512:        data = &ring->data[desc->idx];
                   2513:
1.33      christos 2514:        /* If the command was mapped in an mbuf, free it. */
1.1       ober     2515:        if (data->m != NULL) {
1.33      christos 2516:                bus_dmamap_sync(sc->sc_dmat, data->map, 0,
                   2517:                    data->map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
1.1       ober     2518:                bus_dmamap_unload(sc->sc_dmat, data->map);
                   2519:                m_freem(data->m);
                   2520:                data->m = NULL;
                   2521:        }
1.33      christos 2522:        wakeup(&ring->desc[desc->idx]);
1.1       ober     2523: }
                   2524:
1.33      christos 2525: /*
                   2526:  * Process an INT_FH_RX or INT_SW_RX interrupt.
                   2527:  */
1.1       ober     2528: static void
                   2529: iwn_notif_intr(struct iwn_softc *sc)
                   2530: {
1.53      christos 2531:        struct iwn_ops *ops = &sc->ops;
1.1       ober     2532:        struct ieee80211com *ic = &sc->sc_ic;
                   2533:        struct ifnet *ifp = ic->ic_ifp;
                   2534:        uint16_t hw;
1.84      nonaka   2535:        int s;
1.1       ober     2536:
1.33      christos 2537:        bus_dmamap_sync(sc->sc_dmat, sc->rxq.stat_dma.map,
                   2538:            0, sc->rxq.stat_dma.size, BUS_DMASYNC_POSTREAD);
                   2539:
                   2540:        hw = le16toh(sc->rxq.stat->closed_count) & 0xfff;
1.1       ober     2541:        while (sc->rxq.cur != hw) {
1.40      christos 2542:                struct iwn_rx_data *data = &sc->rxq.data[sc->rxq.cur];
                   2543:                struct iwn_rx_desc *desc;
1.1       ober     2544:
1.33      christos 2545:                bus_dmamap_sync(sc->sc_dmat, data->map, 0, sizeof (*desc),
                   2546:                    BUS_DMASYNC_POSTREAD);
1.40      christos 2547:                desc = mtod(data->m, struct iwn_rx_desc *);
1.33      christos 2548:
                   2549:                DPRINTFN(4, ("notification qid=%d idx=%d flags=%x type=%d\n",
                   2550:                    desc->qid & 0xf, desc->idx, desc->flags, desc->type));
1.1       ober     2551:
1.33      christos 2552:                if (!(desc->qid & 0x80))        /* Reply to a command. */
                   2553:                        iwn_cmd_done(sc, desc);
1.1       ober     2554:
                   2555:                switch (desc->type) {
1.33      christos 2556:                case IWN_RX_PHY:
1.40      christos 2557:                        iwn_rx_phy(sc, desc, data);
1.1       ober     2558:                        break;
                   2559:
1.33      christos 2560:                case IWN_RX_DONE:               /* 4965AGN only. */
                   2561:                case IWN_MPDU_RX_DONE:
                   2562:                        /* An 802.11 frame has been received. */
                   2563:                        iwn_rx_done(sc, desc, data);
1.1       ober     2564:                        break;
1.40      christos 2565: #ifndef IEEE80211_NO_HT
                   2566:                case IWN_RX_COMPRESSED_BA:
                   2567:                        /* A Compressed BlockAck has been received. */
                   2568:                        iwn_rx_compressed_ba(sc, desc, data);
                   2569:                        break;
                   2570: #endif
1.1       ober     2571:                case IWN_TX_DONE:
1.33      christos 2572:                        /* An 802.11 frame has been transmitted. */
1.53      christos 2573:                        ops->tx_done(sc, desc, data);
1.1       ober     2574:                        break;
                   2575:
                   2576:                case IWN_RX_STATISTICS:
                   2577:                case IWN_BEACON_STATISTICS:
1.33      christos 2578:                        iwn_rx_statistics(sc, desc, data);
1.1       ober     2579:                        break;
                   2580:
                   2581:                case IWN_BEACON_MISSED:
                   2582:                {
                   2583:                        struct iwn_beacon_missed *miss =
                   2584:                            (struct iwn_beacon_missed *)(desc + 1);
1.33      christos 2585:
                   2586:                        bus_dmamap_sync(sc->sc_dmat, data->map, sizeof (*desc),
                   2587:                            sizeof (*miss), BUS_DMASYNC_POSTREAD);
1.1       ober     2588:                        /*
                   2589:                         * If more than 5 consecutive beacons are missed,
                   2590:                         * reinitialize the sensitivity state machine.
                   2591:                         */
1.33      christos 2592:                        DPRINTF(("beacons missed %d/%d\n",
                   2593:                            le32toh(miss->consecutive), le32toh(miss->total)));
1.1       ober     2594:                        if (ic->ic_state == IEEE80211_S_RUN &&
                   2595:                            le32toh(miss->consecutive) > 5)
                   2596:                                (void)iwn_init_sensitivity(sc);
                   2597:                        break;
                   2598:                }
                   2599:                case IWN_UC_READY:
                   2600:                {
1.40      christos 2601:                        struct iwn_ucode_info *uc =
                   2602:                            (struct iwn_ucode_info *)(desc + 1);
                   2603:
                   2604:                        /* The microcontroller is ready. */
                   2605:                        bus_dmamap_sync(sc->sc_dmat, data->map, sizeof (*desc),
                   2606:                            sizeof (*uc), BUS_DMASYNC_POSTREAD);
                   2607:                        DPRINTF(("microcode alive notification version=%d.%d "
                   2608:                            "subtype=%x alive=%x\n", uc->major, uc->minor,
                   2609:                            uc->subtype, le32toh(uc->valid)));
                   2610:
                   2611:                        if (le32toh(uc->valid) != 1) {
                   2612:                                aprint_error_dev(sc->sc_dev,
                   2613:                                    "microcontroller initialization "
                   2614:                                    "failed\n");
                   2615:                                break;
                   2616:                        }
                   2617:                        if (uc->subtype == IWN_UCODE_INIT) {
                   2618:                                /* Save microcontroller report. */
                   2619:                                memcpy(&sc->ucode_info, uc, sizeof (*uc));
                   2620:                        }
                   2621:                        /* Save the address of the error log in SRAM. */
                   2622:                        sc->errptr = le32toh(uc->errptr);
1.1       ober     2623:                        break;
                   2624:                }
                   2625:                case IWN_STATE_CHANGED:
                   2626:                {
                   2627:                        uint32_t *status = (uint32_t *)(desc + 1);
                   2628:
1.33      christos 2629:                        /* Enabled/disabled notification. */
                   2630:                        bus_dmamap_sync(sc->sc_dmat, data->map, sizeof (*desc),
                   2631:                            sizeof (*status), BUS_DMASYNC_POSTREAD);
1.1       ober     2632:                        DPRINTF(("state changed to %x\n", le32toh(*status)));
                   2633:
                   2634:                        if (le32toh(*status) & 1) {
1.33      christos 2635:                                /* The radio button has to be pushed. */
                   2636:                                aprint_error_dev(sc->sc_dev,
                   2637:                                    "Radio transmitter is off\n");
                   2638:                                /* Turn the interface down. */
1.84      nonaka   2639:                                s = splnet();
1.40      christos 2640:                                ifp->if_flags &= ~IFF_UP;
1.1       ober     2641:                                iwn_stop(ifp, 1);
1.84      nonaka   2642:                                splx(s);
1.33      christos 2643:                                return; /* No further processing. */
1.1       ober     2644:                        }
                   2645:                        break;
                   2646:                }
                   2647:                case IWN_START_SCAN:
                   2648:                {
                   2649:                        struct iwn_start_scan *scan =
                   2650:                            (struct iwn_start_scan *)(desc + 1);
                   2651:
1.33      christos 2652:                        bus_dmamap_sync(sc->sc_dmat, data->map, sizeof (*desc),
                   2653:                            sizeof (*scan), BUS_DMASYNC_POSTREAD);
1.1       ober     2654:                        DPRINTFN(2, ("scanning channel %d status %x\n",
1.33      christos 2655:                            scan->chan, le32toh(scan->status)));
1.1       ober     2656:
1.33      christos 2657:                        /* Fix current channel. */
1.1       ober     2658:                        ic->ic_bss->ni_chan = &ic->ic_channels[scan->chan];
                   2659:                        break;
                   2660:                }
                   2661:                case IWN_STOP_SCAN:
                   2662:                {
                   2663:                        struct iwn_stop_scan *scan =
                   2664:                            (struct iwn_stop_scan *)(desc + 1);
                   2665:
1.33      christos 2666:                        bus_dmamap_sync(sc->sc_dmat, data->map, sizeof (*desc),
                   2667:                            sizeof (*scan), BUS_DMASYNC_POSTREAD);
1.1       ober     2668:                        DPRINTF(("scan finished nchan=%d status=%d chan=%d\n",
1.33      christos 2669:                            scan->nchan, scan->status, scan->chan));
1.1       ober     2670:
1.33      christos 2671:                        if (scan->status == 1 && scan->chan <= 14 &&
                   2672:                            (sc->sc_flags & IWN_FLAG_HAS_5GHZ)) {
1.1       ober     2673:                                /*
1.33      christos 2674:                                 * We just finished scanning 2GHz channels,
                   2675:                                 * start scanning 5GHz ones.
1.1       ober     2676:                                 */
1.76      nonaka   2677:                                sc->sc_flags &= ~IWN_FLAG_SCANNING_2GHZ;
                   2678:                                sc->sc_flags |= IWN_FLAG_SCANNING_5GHZ;
1.33      christos 2679:                                if (iwn_scan(sc, IEEE80211_CHAN_5GHZ) == 0)
1.1       ober     2680:                                        break;
                   2681:                        }
1.40      christos 2682:                        sc->sc_flags &= ~IWN_FLAG_SCANNING;
1.1       ober     2683:                        ieee80211_end_scan(ic);
                   2684:                        break;
                   2685:                }
1.33      christos 2686:                case IWN5000_CALIBRATION_RESULT:
                   2687:                        iwn5000_rx_calib_results(sc, desc, data);
                   2688:                        break;
                   2689:
                   2690:                case IWN5000_CALIBRATION_DONE:
1.40      christos 2691:                        sc->sc_flags |= IWN_FLAG_CALIB_DONE;
1.33      christos 2692:                        wakeup(sc);
                   2693:                        break;
1.1       ober     2694:                }
                   2695:
                   2696:                sc->rxq.cur = (sc->rxq.cur + 1) % IWN_RX_RING_COUNT;
                   2697:        }
                   2698:
1.33      christos 2699:        /* Tell the firmware what we have processed. */
1.1       ober     2700:        hw = (hw == 0) ? IWN_RX_RING_COUNT - 1 : hw - 1;
1.33      christos 2701:        IWN_WRITE(sc, IWN_FH_RX_WPTR, hw & ~7);
1.1       ober     2702: }
                   2703:
1.33      christos 2704: /*
                   2705:  * Process an INT_WAKEUP interrupt raised when the microcontroller wakes up
                   2706:  * from power-down sleep mode.
                   2707:  */
                   2708: static void
                   2709: iwn_wakeup_intr(struct iwn_softc *sc)
1.1       ober     2710: {
1.33      christos 2711:        int qid;
1.1       ober     2712:
1.33      christos 2713:        DPRINTF(("ucode wakeup from power-down sleep\n"));
1.1       ober     2714:
1.33      christos 2715:        /* Wakeup RX and TX rings. */
                   2716:        IWN_WRITE(sc, IWN_FH_RX_WPTR, sc->rxq.cur & ~7);
1.53      christos 2717:        for (qid = 0; qid < sc->ntxqs; qid++) {
1.33      christos 2718:                struct iwn_tx_ring *ring = &sc->txq[qid];
                   2719:                IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, qid << 8 | ring->cur);
1.1       ober     2720:        }
1.33      christos 2721: }
1.1       ober     2722:
1.33      christos 2723: /*
                   2724:  * Dump the error log of the firmware when a firmware panic occurs.  Although
                   2725:  * we can't debug the firmware because it is neither open source nor free, it
                   2726:  * can help us to identify certain classes of problems.
                   2727:  */
1.40      christos 2728: static void
1.33      christos 2729: iwn_fatal_intr(struct iwn_softc *sc)
                   2730: {
                   2731:        struct iwn_fw_dump dump;
                   2732:        int i;
1.1       ober     2733:
1.40      christos 2734:        /* Force a complete recalibration on next init. */
                   2735:        sc->sc_flags &= ~IWN_FLAG_CALIB_DONE;
                   2736:
1.33      christos 2737:        /* Check that the error log address is valid. */
                   2738:        if (sc->errptr < IWN_FW_DATA_BASE ||
                   2739:            sc->errptr + sizeof (dump) >
1.53      christos 2740:            IWN_FW_DATA_BASE + sc->fw_data_maxsz) {
1.33      christos 2741:                aprint_error_dev(sc->sc_dev,
                   2742:                    "bad firmware error log address 0x%08x\n", sc->errptr);
                   2743:                return;
                   2744:        }
                   2745:        if (iwn_nic_lock(sc) != 0) {
                   2746:                aprint_error_dev(sc->sc_dev,
                   2747:                    "could not read firmware error log\n");
                   2748:                return;
                   2749:        }
                   2750:        /* Read firmware error log from SRAM. */
                   2751:        iwn_mem_read_region_4(sc, sc->errptr, (uint32_t *)&dump,
                   2752:            sizeof (dump) / sizeof (uint32_t));
                   2753:        iwn_nic_unlock(sc);
1.1       ober     2754:
1.33      christos 2755:        if (dump.valid == 0) {
1.40      christos 2756:                aprint_error_dev(sc->sc_dev,
                   2757:                    "firmware error log is empty\n");
1.33      christos 2758:                return;
                   2759:        }
1.40      christos 2760:        aprint_error("firmware error log:\n");
                   2761:        aprint_error("  error type      = \"%s\" (0x%08X)\n",
                   2762:            (dump.id < __arraycount(iwn_fw_errmsg)) ?
1.33      christos 2763:                iwn_fw_errmsg[dump.id] : "UNKNOWN",
                   2764:            dump.id);
1.40      christos 2765:        aprint_error("  program counter = 0x%08X\n", dump.pc);
                   2766:        aprint_error("  source line     = 0x%08X\n", dump.src_line);
                   2767:        aprint_error("  error data      = 0x%08X%08X\n",
1.33      christos 2768:            dump.error_data[0], dump.error_data[1]);
1.40      christos 2769:        aprint_error("  branch link     = 0x%08X%08X\n",
1.33      christos 2770:            dump.branch_link[0], dump.branch_link[1]);
1.40      christos 2771:        aprint_error("  interrupt link  = 0x%08X%08X\n",
1.33      christos 2772:            dump.interrupt_link[0], dump.interrupt_link[1]);
1.40      christos 2773:        aprint_error("  time            = %u\n", dump.time[0]);
1.33      christos 2774:
                   2775:        /* Dump driver status (TX and RX rings) while we're here. */
1.40      christos 2776:        aprint_error("driver status:\n");
1.53      christos 2777:        for (i = 0; i < sc->ntxqs; i++) {
1.33      christos 2778:                struct iwn_tx_ring *ring = &sc->txq[i];
1.40      christos 2779:                aprint_error("  tx ring %2d: qid=%-2d cur=%-3d queued=%-3d\n",
1.33      christos 2780:                    i, ring->qid, ring->cur, ring->queued);
                   2781:        }
1.40      christos 2782:        aprint_error("  rx ring: cur=%d\n", sc->rxq.cur);
                   2783:        aprint_error("  802.11 state %d\n", sc->sc_ic.ic_state);
1.33      christos 2784: }
                   2785:
                   2786: static int
                   2787: iwn_intr(void *arg)
                   2788: {
                   2789:        struct iwn_softc *sc = arg;
                   2790:
                   2791:        /* Disable interrupts. */
1.40      christos 2792:        IWN_WRITE(sc, IWN_INT_MASK, 0);
1.33      christos 2793:
1.84      nonaka   2794:        softint_schedule(sc->sc_soft_ih);
                   2795:        return 1;
                   2796: }
                   2797:
                   2798: static void
                   2799: iwn_softintr(void *arg)
                   2800: {
                   2801:        struct iwn_softc *sc = arg;
                   2802:        struct ifnet *ifp = sc->sc_ic.ic_ifp;
                   2803:        uint32_t r1, r2, tmp;
                   2804:        int s;
                   2805:
1.40      christos 2806:        /* Read interrupts from ICT (fast) or from registers (slow). */
                   2807:        if (sc->sc_flags & IWN_FLAG_USE_ICT) {
1.80      hkenken  2808:                bus_dmamap_sync(sc->sc_dmat, sc->ict_dma.map, 0,
                   2809:                    IWN_ICT_SIZE, BUS_DMASYNC_POSTREAD);
1.40      christos 2810:                tmp = 0;
                   2811:                while (sc->ict[sc->ict_cur] != 0) {
                   2812:                        tmp |= sc->ict[sc->ict_cur];
                   2813:                        sc->ict[sc->ict_cur] = 0;       /* Acknowledge. */
                   2814:                        sc->ict_cur = (sc->ict_cur + 1) % IWN_ICT_COUNT;
                   2815:                }
1.80      hkenken  2816:                bus_dmamap_sync(sc->sc_dmat, sc->ict_dma.map, 0,
                   2817:                    IWN_ICT_SIZE, BUS_DMASYNC_PREWRITE);
1.40      christos 2818:                tmp = le32toh(tmp);
                   2819:                if (tmp == 0xffffffff)  /* Shouldn't happen. */
                   2820:                        tmp = 0;
1.44      christos 2821:                else if (tmp & 0xc0000) /* Workaround a HW bug. */
1.40      christos 2822:                        tmp |= 0x8000;
                   2823:                r1 = (tmp & 0xff00) << 16 | (tmp & 0xff);
                   2824:                r2 = 0; /* Unused. */
                   2825:        } else {
                   2826:                r1 = IWN_READ(sc, IWN_INT);
                   2827:                if (r1 == 0xffffffff || (r1 & 0xfffffff0) == 0xa5a5a5a0)
1.84      nonaka   2828:                        return; /* Hardware gone! */
1.40      christos 2829:                r2 = IWN_READ(sc, IWN_FH_INT);
                   2830:        }
1.33      christos 2831:        if (r1 == 0 && r2 == 0) {
1.84      nonaka   2832:                goto out;       /* Interrupt not for us. */
1.33      christos 2833:        }
                   2834:
                   2835:        /* Acknowledge interrupts. */
                   2836:        IWN_WRITE(sc, IWN_INT, r1);
1.40      christos 2837:        if (!(sc->sc_flags & IWN_FLAG_USE_ICT))
                   2838:                IWN_WRITE(sc, IWN_FH_INT, r2);
1.1       ober     2839:
1.33      christos 2840:        if (r1 & IWN_INT_RF_TOGGLED) {
1.40      christos 2841:                tmp = IWN_READ(sc, IWN_GP_CNTRL);
                   2842:                aprint_error_dev(sc->sc_dev,
                   2843:                    "RF switch: radio %s\n",
1.33      christos 2844:                    (tmp & IWN_GP_CNTRL_RFKILL) ? "enabled" : "disabled");
1.1       ober     2845:        }
1.33      christos 2846:        if (r1 & IWN_INT_CT_REACHED) {
1.40      christos 2847:                aprint_error_dev(sc->sc_dev,
                   2848:                    "critical temperature reached!\n");
1.1       ober     2849:        }
1.33      christos 2850:        if (r1 & (IWN_INT_SW_ERR | IWN_INT_HW_ERR)) {
1.40      christos 2851:                aprint_error_dev(sc->sc_dev,
                   2852:                    "fatal firmware error\n");
1.33      christos 2853:                /* Dump firmware error log and stop. */
                   2854:                iwn_fatal_intr(sc);
1.84      nonaka   2855:                s = splnet();
1.40      christos 2856:                ifp->if_flags &= ~IFF_UP;
                   2857:                iwn_stop(ifp, 1);
1.84      nonaka   2858:                splx(s);
                   2859:                return;
1.1       ober     2860:        }
1.40      christos 2861:        if ((r1 & (IWN_INT_FH_RX | IWN_INT_SW_RX | IWN_INT_RX_PERIODIC)) ||
                   2862:            (r2 & IWN_FH_INT_RX)) {
                   2863:                if (sc->sc_flags & IWN_FLAG_USE_ICT) {
                   2864:                        if (r1 & (IWN_INT_FH_RX | IWN_INT_SW_RX))
                   2865:                                IWN_WRITE(sc, IWN_FH_INT, IWN_FH_INT_RX);
1.84      nonaka   2866:                        IWN_WRITE_1(sc, IWN_INT_PERIODIC, IWN_INT_PERIODIC_DIS);
1.40      christos 2867:                        iwn_notif_intr(sc);
                   2868:                        if (r1 & (IWN_INT_FH_RX | IWN_INT_SW_RX)) {
                   2869:                                IWN_WRITE_1(sc, IWN_INT_PERIODIC,
                   2870:                                    IWN_INT_PERIODIC_ENA);
                   2871:                        }
                   2872:                } else
                   2873:                        iwn_notif_intr(sc);
                   2874:        }
1.33      christos 2875:
1.40      christos 2876:        if ((r1 & IWN_INT_FH_TX) || (r2 & IWN_FH_INT_TX)) {
                   2877:                if (sc->sc_flags & IWN_FLAG_USE_ICT)
                   2878:                        IWN_WRITE(sc, IWN_FH_INT, IWN_FH_INT_TX);
1.33      christos 2879:                wakeup(sc);     /* FH DMA transfer completed. */
1.40      christos 2880:        }
1.1       ober     2881:
1.33      christos 2882:        if (r1 & IWN_INT_ALIVE)
                   2883:                wakeup(sc);     /* Firmware is alive. */
1.1       ober     2884:
1.33      christos 2885:        if (r1 & IWN_INT_WAKEUP)
                   2886:                iwn_wakeup_intr(sc);
1.1       ober     2887:
1.84      nonaka   2888: out:
1.33      christos 2889:        /* Re-enable interrupts. */
1.1       ober     2890:        if (ifp->if_flags & IFF_UP)
1.40      christos 2891:                IWN_WRITE(sc, IWN_INT_MASK, sc->int_mask);
1.1       ober     2892: }
                   2893:
1.33      christos 2894: /*
                   2895:  * Update TX scheduler ring when transmitting an 802.11 frame (4965AGN and
1.53      christos 2896:  * 5000 adapters use a slightly different format).
1.33      christos 2897:  */
                   2898: static void
                   2899: iwn4965_update_sched(struct iwn_softc *sc, int qid, int idx, uint8_t id,
                   2900:     uint16_t len)
                   2901: {
                   2902:        uint16_t *w = &sc->sched[qid * IWN4965_SCHED_COUNT + idx];
                   2903:
                   2904:        *w = htole16(len + 8);
                   2905:        bus_dmamap_sync(sc->sc_dmat, sc->sched_dma.map,
                   2906:            (char *)(void *)w - (char *)(void *)sc->sched_dma.vaddr,
1.40      christos 2907:            sizeof (uint16_t),
                   2908:            BUS_DMASYNC_PREWRITE);
1.33      christos 2909:        if (idx < IWN_SCHED_WINSZ) {
                   2910:                *(w + IWN_TX_RING_COUNT) = *w;
                   2911:                bus_dmamap_sync(sc->sc_dmat, sc->sched_dma.map,
                   2912:                    (char *)(void *)(w + IWN_TX_RING_COUNT) -
                   2913:                    (char *)(void *)sc->sched_dma.vaddr,
                   2914:                    sizeof (uint16_t), BUS_DMASYNC_PREWRITE);
                   2915:        }
                   2916: }
                   2917:
                   2918: static void
                   2919: iwn5000_update_sched(struct iwn_softc *sc, int qid, int idx, uint8_t id,
                   2920:     uint16_t len)
1.1       ober     2921: {
1.33      christos 2922:        uint16_t *w = &sc->sched[qid * IWN5000_SCHED_COUNT + idx];
                   2923:
                   2924:        *w = htole16(id << 12 | (len + 8));
                   2925:        bus_dmamap_sync(sc->sc_dmat, sc->sched_dma.map,
                   2926:            (char *)(void *)w - (char *)(void *)sc->sched_dma.vaddr,
                   2927:            sizeof (uint16_t), BUS_DMASYNC_PREWRITE);
                   2928:        if (idx < IWN_SCHED_WINSZ) {
                   2929:                *(w + IWN_TX_RING_COUNT) = *w;
                   2930:                bus_dmamap_sync(sc->sc_dmat, sc->sched_dma.map,
                   2931:                    (char *)(void *)(w + IWN_TX_RING_COUNT) -
                   2932:                    (char *)(void *)sc->sched_dma.vaddr,
                   2933:                    sizeof (uint16_t), BUS_DMASYNC_PREWRITE);
                   2934:        }
1.1       ober     2935: }
                   2936:
1.40      christos 2937: #ifdef notyet
1.33      christos 2938: static void
                   2939: iwn5000_reset_sched(struct iwn_softc *sc, int qid, int idx)
                   2940: {
                   2941:        uint16_t *w = &sc->sched[qid * IWN5000_SCHED_COUNT + idx];
                   2942:
                   2943:        *w = (*w & htole16(0xf000)) | htole16(1);
                   2944:        bus_dmamap_sync(sc->sc_dmat, sc->sched_dma.map,
                   2945:            (char *)(void *)w - (char *)(void *)sc->sched_dma.vaddr,
                   2946:            sizeof (uint16_t), BUS_DMASYNC_PREWRITE);
                   2947:        if (idx < IWN_SCHED_WINSZ) {
                   2948:                *(w + IWN_TX_RING_COUNT) = *w;
                   2949:                bus_dmamap_sync(sc->sc_dmat, sc->sched_dma.map,
                   2950:                    (char *)(void *)(w + IWN_TX_RING_COUNT) -
                   2951:                    (char *)(void *)sc->sched_dma.vaddr,
                   2952:                    sizeof (uint16_t), BUS_DMASYNC_PREWRITE);
                   2953:        }
                   2954: }
1.40      christos 2955: #endif
1.1       ober     2956:
                   2957: static int
1.33      christos 2958: iwn_tx(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni, int ac)
1.1       ober     2959: {
                   2960:        struct ieee80211com *ic = &sc->sc_ic;
1.33      christos 2961:        struct iwn_node *wn = (void *)ni;
                   2962:        struct iwn_tx_ring *ring;
1.1       ober     2963:        struct iwn_tx_desc *desc;
                   2964:        struct iwn_tx_data *data;
                   2965:        struct iwn_tx_cmd *cmd;
                   2966:        struct iwn_cmd_data *tx;
1.33      christos 2967:        const struct iwn_rate *rinfo;
1.1       ober     2968:        struct ieee80211_frame *wh;
1.33      christos 2969:        struct ieee80211_key *k = NULL;
                   2970:        struct mbuf *m1;
1.1       ober     2971:        uint32_t flags;
1.33      christos 2972:        u_int hdrlen;
                   2973:        bus_dma_segment_t *seg;
1.40      christos 2974:        uint8_t tid, ridx, txant, type;
                   2975:        int i, totlen, error, pad;
                   2976:
                   2977:        const struct chanAccParams *cap;
                   2978:        int noack;
                   2979:        int hdrlen2;
1.1       ober     2980:
1.33      christos 2981:        wh = mtod(m, struct ieee80211_frame *);
1.44      christos 2982:        hdrlen = ieee80211_anyhdrsize(wh);
1.33      christos 2983:        type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
1.1       ober     2984:
1.64      christos 2985:        hdrlen2 = (ieee80211_has_qos(wh)) ?
1.40      christos 2986:            sizeof (struct ieee80211_qosframe) :
                   2987:            sizeof (struct ieee80211_frame);
                   2988:
                   2989:        if (hdrlen != hdrlen2)
                   2990:            aprint_error_dev(sc->sc_dev, "hdrlen error (%d != %d)\n",
                   2991:                hdrlen, hdrlen2);
                   2992:
1.44      christos 2993:        /* XXX OpenBSD sets a different tid when using QOS */
1.40      christos 2994:        tid = 0;
1.64      christos 2995:        if (ieee80211_has_qos(wh)) {
1.44      christos 2996:                cap = &ic->ic_wme.wme_chanParams;
                   2997:                noack = cap->cap_wmeParams[ac].wmep_noackPolicy;
1.1       ober     2998:        }
1.44      christos 2999:        else
                   3000:                noack = 0;
1.1       ober     3001:
1.33      christos 3002:        ring = &sc->txq[ac];
                   3003:        desc = &ring->desc[ring->cur];
                   3004:        data = &ring->data[ring->cur];
                   3005:
                   3006:        /* Choose a TX rate index. */
1.40      christos 3007:        if (IEEE80211_IS_MULTICAST(wh->i_addr1) ||
                   3008:            type != IEEE80211_FC0_TYPE_DATA) {
1.33      christos 3009:                ridx = (ic->ic_curmode == IEEE80211_MODE_11A) ?
                   3010:                    IWN_RIDX_OFDM6 : IWN_RIDX_CCK1;
1.40      christos 3011:        } else if (ic->ic_fixed_rate != -1) {
                   3012:                ridx = sc->fixed_ridx;
                   3013:        } else
                   3014:                ridx = wn->ridx[ni->ni_txrate];
1.33      christos 3015:        rinfo = &iwn_rates[ridx];
1.1       ober     3016:
1.44      christos 3017:        /* Encrypt the frame if need be. */
                   3018:        /*
                   3019:         * XXX For now, NetBSD swaps the encryption and bpf sections
                   3020:         * in order to match old code and other drivers. Tests with
                   3021:         * tcpdump indicates that the order is irrelevant, however,
                   3022:         * as bpf produces unencrypted data for both ordering choices.
                   3023:         */
1.40      christos 3024:        if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
                   3025:                k = ieee80211_crypto_encap(ic, ni, m);
                   3026:                if (k == NULL) {
                   3027:                        m_freem(m);
                   3028:                        return ENOBUFS;
                   3029:                }
1.44      christos 3030:                /* Packet header may have moved, reset our local pointer. */
1.40      christos 3031:                wh = mtod(m, struct ieee80211_frame *);
                   3032:        }
1.44      christos 3033:        totlen = m->m_pkthdr.len;
1.40      christos 3034:
                   3035:        if (sc->sc_drvbpf != NULL) {
                   3036:                struct iwn_tx_radiotap_header *tap = &sc->sc_txtap;
                   3037:
                   3038:                tap->wt_flags = 0;
                   3039:                tap->wt_chan_freq = htole16(ni->ni_chan->ic_freq);
                   3040:                tap->wt_chan_flags = htole16(ni->ni_chan->ic_flags);
                   3041:                tap->wt_rate = rinfo->rate;
                   3042:                tap->wt_hwqueue = ac;
                   3043:                if (wh->i_fc[1] & IEEE80211_FC1_WEP)
                   3044:                        tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP;
                   3045:
1.90      msaitoh  3046:                bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m, BPF_D_OUT);
1.40      christos 3047:        }
                   3048:
                   3049:        /* Prepare TX firmware command. */
                   3050:        cmd = &ring->cmd[ring->cur];
                   3051:        cmd->code = IWN_CMD_TX_DATA;
                   3052:        cmd->flags = 0;
                   3053:        cmd->qid = ring->qid;
                   3054:        cmd->idx = ring->cur;
                   3055:
                   3056:        tx = (struct iwn_cmd_data *)cmd->data;
                   3057:        /* NB: No need to clear tx, all fields are reinitialized here. */
                   3058:        tx->scratch = 0;        /* clear "scratch" area */
                   3059:
                   3060:        flags = 0;
1.44      christos 3061:        if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
                   3062:                /* Unicast frame, check if an ACK is expected. */
                   3063:                if (!noack)
                   3064:                        flags |= IWN_TX_NEED_ACK;
                   3065:        }
1.40      christos 3066:
                   3067: #ifdef notyet
1.44      christos 3068:        /* XXX NetBSD does not define IEEE80211_FC0_SUBTYPE_BAR */
1.40      christos 3069:        if ((wh->i_fc[0] &
                   3070:            (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==
                   3071:            (IEEE80211_FC0_TYPE_CTL | IEEE80211_FC0_SUBTYPE_BAR))
                   3072:                flags |= IWN_TX_IMM_BA;         /* Cannot happen yet. */
1.63      christos 3073: #endif
1.40      christos 3074:
                   3075:        if (wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG)
                   3076:                flags |= IWN_TX_MORE_FRAG;      /* Cannot happen yet. */
                   3077:
                   3078:        /* Check if frame must be protected using RTS/CTS or CTS-to-self. */
                   3079:        if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
                   3080:                /* NB: Group frames are sent using CCK in 802.11b/g. */
                   3081:                if (totlen + IEEE80211_CRC_LEN > ic->ic_rtsthreshold) {
                   3082:                        flags |= IWN_TX_NEED_RTS;
                   3083:                } else if ((ic->ic_flags & IEEE80211_F_USEPROT) &&
                   3084:                    ridx >= IWN_RIDX_OFDM6) {
                   3085:                        if (ic->ic_protmode == IEEE80211_PROT_CTSONLY)
                   3086:                                flags |= IWN_TX_NEED_CTS;
                   3087:                        else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
                   3088:                                flags |= IWN_TX_NEED_RTS;
                   3089:                }
                   3090:                if (flags & (IWN_TX_NEED_RTS | IWN_TX_NEED_CTS)) {
                   3091:                        if (sc->hw_type != IWN_HW_REV_TYPE_4965) {
                   3092:                                /* 5000 autoselects RTS/CTS or CTS-to-self. */
                   3093:                                flags &= ~(IWN_TX_NEED_RTS | IWN_TX_NEED_CTS);
                   3094:                                flags |= IWN_TX_NEED_PROTECTION;
                   3095:                        } else
                   3096:                                flags |= IWN_TX_FULL_TXOP;
                   3097:                }
                   3098:        }
                   3099:
                   3100:        if (IEEE80211_IS_MULTICAST(wh->i_addr1) ||
                   3101:            type != IEEE80211_FC0_TYPE_DATA)
1.53      christos 3102:                tx->id = sc->broadcast_id;
1.40      christos 3103:        else
                   3104:                tx->id = wn->id;
                   3105:
                   3106:        if (type == IEEE80211_FC0_TYPE_MGT) {
                   3107:                uint8_t subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
                   3108:
                   3109: #ifndef IEEE80211_STA_ONLY
                   3110:                /* Tell HW to set timestamp in probe responses. */
1.44      christos 3111:                /* XXX NetBSD rev 1.11 added probe requests here but */
                   3112:                /* probe requests do not take timestamps (from Bergamini). */
                   3113:                if (subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP)
1.40      christos 3114:                        flags |= IWN_TX_INSERT_TSTAMP;
                   3115: #endif
1.44      christos 3116:                /* XXX NetBSD rev 1.11 and 1.20 added AUTH/DAUTH and RTS/CTS */
                   3117:                /* changes here. These are not needed (from Bergamini). */
1.40      christos 3118:                if (subtype == IEEE80211_FC0_SUBTYPE_ASSOC_REQ ||
1.44      christos 3119:                    subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ)
1.40      christos 3120:                        tx->timeout = htole16(3);
1.44      christos 3121:                else
1.40      christos 3122:                        tx->timeout = htole16(2);
                   3123:        } else
                   3124:                tx->timeout = htole16(0);
                   3125:
                   3126:        if (hdrlen & 3) {
1.53      christos 3127:                /* First segment length must be a multiple of 4. */
1.40      christos 3128:                flags |= IWN_TX_NEED_PADDING;
                   3129:                pad = 4 - (hdrlen & 3);
                   3130:        } else
                   3131:                pad = 0;
                   3132:
                   3133:        tx->len = htole16(totlen);
1.44      christos 3134:        tx->tid = tid;
1.40      christos 3135:        tx->rts_ntries = 60;
                   3136:        tx->data_ntries = 15;
                   3137:        tx->lifetime = htole32(IWN_LIFETIME_INFINITE);
                   3138:        tx->plcp = rinfo->plcp;
                   3139:        tx->rflags = rinfo->flags;
1.53      christos 3140:        if (tx->id == sc->broadcast_id) {
1.40      christos 3141:                /* Group or management frame. */
                   3142:                tx->linkq = 0;
                   3143:                /* XXX Alternate between antenna A and B? */
                   3144:                txant = IWN_LSB(sc->txchainmask);
                   3145:                tx->rflags |= IWN_RFLAG_ANT(txant);
                   3146:        } else {
                   3147:                tx->linkq = ni->ni_rates.rs_nrates - ni->ni_txrate - 1;
                   3148:                flags |= IWN_TX_LINKQ;  /* enable MRR */
                   3149:        }
                   3150:        /* Set physical address of "scratch area". */
                   3151:        tx->loaddr = htole32(IWN_LOADDR(data->scratch_paddr));
                   3152:        tx->hiaddr = IWN_HIADDR(data->scratch_paddr);
                   3153:
                   3154:        /* Copy 802.11 header in TX command. */
1.44      christos 3155:        /* XXX NetBSD changed this in rev 1.20 */
1.40      christos 3156:        memcpy(((uint8_t *)tx) + sizeof(*tx), wh, hdrlen);
                   3157:
                   3158:        /* Trim 802.11 header. */
1.44      christos 3159:        m_adj(m, hdrlen);
                   3160:        tx->security = 0;
1.40      christos 3161:        tx->flags = htole32(flags);
                   3162:
                   3163:        error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m,
1.44      christos 3164:            BUS_DMA_NOWAIT | BUS_DMA_WRITE);
1.40      christos 3165:        if (error != 0) {
1.44      christos 3166:                if (error != EFBIG) {
                   3167:                        aprint_error_dev(sc->sc_dev,
                   3168:                            "can't map mbuf (error %d)\n", error);
                   3169:                        m_freem(m);
                   3170:                        return error;
                   3171:                }
1.40      christos 3172:                /* Too many DMA segments, linearize mbuf. */
                   3173:                MGETHDR(m1, M_DONTWAIT, MT_DATA);
                   3174:                if (m1 == NULL) {
                   3175:                        m_freem(m);
                   3176:                        return ENOBUFS;
                   3177:                }
                   3178:                if (m->m_pkthdr.len > MHLEN) {
                   3179:                        MCLGET(m1, M_DONTWAIT);
                   3180:                        if (!(m1->m_flags & M_EXT)) {
                   3181:                                m_freem(m);
                   3182:                                m_freem(m1);
                   3183:                                return ENOBUFS;
                   3184:                        }
                   3185:                }
                   3186:                m_copydata(m, 0, m->m_pkthdr.len, mtod(m1, void *));
                   3187:                m1->m_pkthdr.len = m1->m_len = m->m_pkthdr.len;
                   3188:                m_freem(m);
                   3189:                m = m1;
                   3190:
                   3191:                error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m,
1.44      christos 3192:                    BUS_DMA_NOWAIT | BUS_DMA_WRITE);
1.40      christos 3193:                if (error != 0) {
                   3194:                        aprint_error_dev(sc->sc_dev,
                   3195:                            "can't map mbuf (error %d)\n", error);
                   3196:                        m_freem(m);
                   3197:                        return error;
                   3198:                }
                   3199:        }
                   3200:
                   3201:        data->m = m;
                   3202:        data->ni = ni;
                   3203:
                   3204:        DPRINTFN(4, ("sending data: qid=%d idx=%d len=%d nsegs=%d\n",
                   3205:            ring->qid, ring->cur, m->m_pkthdr.len, data->map->dm_nsegs));
                   3206:
                   3207:        /* Fill TX descriptor. */
                   3208:        desc->nsegs = 1 + data->map->dm_nsegs;
                   3209:        /* First DMA segment is used by the TX command. */
                   3210:        desc->segs[0].addr = htole32(IWN_LOADDR(data->cmd_paddr));
                   3211:        desc->segs[0].len  = htole16(IWN_HIADDR(data->cmd_paddr) |
                   3212:            (4 + sizeof (*tx) + hdrlen + pad) << 4);
                   3213:        /* Other DMA segments are for data payload. */
                   3214:        seg = data->map->dm_segs;
                   3215:        for (i = 1; i <= data->map->dm_nsegs; i++) {
                   3216:                desc->segs[i].addr = htole32(IWN_LOADDR(seg->ds_addr));
                   3217:                desc->segs[i].len  = htole16(IWN_HIADDR(seg->ds_addr) |
                   3218:                    seg->ds_len << 4);
                   3219:                seg++;
                   3220:        }
                   3221:
                   3222:        bus_dmamap_sync(sc->sc_dmat, data->map, 0, data->map->dm_mapsize,
                   3223:            BUS_DMASYNC_PREWRITE);
                   3224:        bus_dmamap_sync(sc->sc_dmat, ring->cmd_dma.map,
                   3225:            (char *)(void *)cmd - (char *)(void *)ring->cmd_dma.vaddr,
                   3226:            sizeof (*cmd), BUS_DMASYNC_PREWRITE);
                   3227:        bus_dmamap_sync(sc->sc_dmat, ring->desc_dma.map,
                   3228:            (char *)(void *)desc - (char *)(void *)ring->desc_dma.vaddr,
                   3229:            sizeof (*desc), BUS_DMASYNC_PREWRITE);
                   3230:
                   3231: #ifdef notyet
                   3232:        /* Update TX scheduler. */
1.53      christos 3233:        ops->update_sched(sc, ring->qid, ring->cur, tx->id, totlen);
1.40      christos 3234: #endif
                   3235:
                   3236:        /* Kick TX ring. */
                   3237:        ring->cur = (ring->cur + 1) % IWN_TX_RING_COUNT;
                   3238:        IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, ring->qid << 8 | ring->cur);
                   3239:
                   3240:        /* Mark TX ring as full if we reach a certain threshold. */
                   3241:        if (++ring->queued > IWN_TX_RING_HIMARK)
                   3242:                sc->qfullmsk |= 1 << ring->qid;
                   3243:
                   3244:        return 0;
                   3245: }
                   3246:
                   3247: static void
                   3248: iwn_start(struct ifnet *ifp)
                   3249: {
                   3250:        struct iwn_softc *sc = ifp->if_softc;
                   3251:        struct ieee80211com *ic = &sc->sc_ic;
                   3252:        struct ieee80211_node *ni;
                   3253:        struct ether_header *eh;
                   3254:        struct mbuf *m;
                   3255:        int ac;
                   3256:
                   3257:        if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
                   3258:                return;
                   3259:
                   3260:        for (;;) {
1.85      mlelstv  3261:                if (sc->sc_beacon_wait == 1) {
                   3262:                        ifp->if_flags |= IFF_OACTIVE;
                   3263:                        break;
                   3264:                }
                   3265:
1.40      christos 3266:                if (sc->qfullmsk != 0) {
                   3267:                        ifp->if_flags |= IFF_OACTIVE;
                   3268:                        break;
1.33      christos 3269:                }
                   3270:                /* Send pending management frames first. */
                   3271:                IF_DEQUEUE(&ic->ic_mgtq, m);
                   3272:                if (m != NULL) {
1.77      ozaki-r  3273:                        ni = M_GETCTX(m, struct ieee80211_node *);
1.33      christos 3274:                        ac = 0;
                   3275:                        goto sendit;
                   3276:                }
                   3277:                if (ic->ic_state != IEEE80211_S_RUN)
                   3278:                        break;
1.8       blymn    3279:
1.33      christos 3280:                /* Encapsulate and send data frames. */
                   3281:                IFQ_DEQUEUE(&ifp->if_snd, m);
                   3282:                if (m == NULL)
                   3283:                        break;
                   3284:                if (m->m_len < sizeof (*eh) &&
                   3285:                    (m = m_pullup(m, sizeof (*eh))) == NULL) {
1.93      thorpej  3286:                        if_statinc(ifp, if_oerrors);
1.33      christos 3287:                        continue;
                   3288:                }
                   3289:                eh = mtod(m, struct ether_header *);
                   3290:                ni = ieee80211_find_txnode(ic, eh->ether_dhost);
                   3291:                if (ni == NULL) {
                   3292:                        m_freem(m);
1.93      thorpej  3293:                        if_statinc(ifp, if_oerrors);
1.33      christos 3294:                        continue;
                   3295:                }
                   3296:                /* classify mbuf so we can find which tx ring to use */
                   3297:                if (ieee80211_classify(ic, m, ni) != 0) {
                   3298:                        m_freem(m);
                   3299:                        ieee80211_free_node(ni);
1.93      thorpej  3300:                        if_statinc(ifp, if_oerrors);
1.33      christos 3301:                        continue;
                   3302:                }
1.1       ober     3303:
1.40      christos 3304:                /* No QoS encapsulation for EAPOL frames. */
1.33      christos 3305:                ac = (eh->ether_type != htons(ETHERTYPE_PAE)) ?
                   3306:                    M_WME_GETAC(m) : WME_AC_BE;
1.40      christos 3307:
1.85      mlelstv  3308:                if (sc->sc_beacon_wait == 0)
1.90      msaitoh  3309:                        bpf_mtap(ifp, m, BPF_D_OUT);
1.40      christos 3310:
1.33      christos 3311:                if ((m = ieee80211_encap(ic, m, ni)) == NULL) {
                   3312:                        ieee80211_free_node(ni);
1.93      thorpej  3313:                        if_statinc(ifp, if_oerrors);
1.33      christos 3314:                        continue;
                   3315:                }
                   3316: sendit:
1.85      mlelstv  3317:                if (sc->sc_beacon_wait)
                   3318:                        continue;
                   3319:
1.90      msaitoh  3320:                bpf_mtap3(ic->ic_rawbpf, m, BPF_D_OUT);
1.40      christos 3321:
1.33      christos 3322:                if (iwn_tx(sc, m, ni, ac) != 0) {
                   3323:                        ieee80211_free_node(ni);
1.93      thorpej  3324:                        if_statinc(ifp, if_oerrors);
1.33      christos 3325:                        continue;
1.1       ober     3326:                }
                   3327:
                   3328:                sc->sc_tx_timer = 5;
                   3329:                ifp->if_timer = 1;
                   3330:        }
1.85      mlelstv  3331:
                   3332:        if (sc->sc_beacon_wait > 1)
                   3333:                sc->sc_beacon_wait = 0;
1.1       ober     3334: }
                   3335:
                   3336: static void
                   3337: iwn_watchdog(struct ifnet *ifp)
                   3338: {
                   3339:        struct iwn_softc *sc = ifp->if_softc;
                   3340:
                   3341:        ifp->if_timer = 0;
                   3342:
                   3343:        if (sc->sc_tx_timer > 0) {
                   3344:                if (--sc->sc_tx_timer == 0) {
1.40      christos 3345:                        aprint_error_dev(sc->sc_dev,
                   3346:                            "device timeout\n");
                   3347:                        ifp->if_flags &= ~IFF_UP;
1.1       ober     3348:                        iwn_stop(ifp, 1);
1.93      thorpej  3349:                        if_statinc(ifp, if_oerrors);
1.1       ober     3350:                        return;
                   3351:                }
                   3352:                ifp->if_timer = 1;
                   3353:        }
                   3354:
                   3355:        ieee80211_watchdog(&sc->sc_ic);
                   3356: }
                   3357:
                   3358: static int
1.40      christos 3359: iwn_ioctl(struct ifnet *ifp, u_long cmd, void *data)
1.1       ober     3360: {
                   3361:        struct iwn_softc *sc = ifp->if_softc;
                   3362:        struct ieee80211com *ic = &sc->sc_ic;
1.40      christos 3363:        const struct sockaddr *sa;
1.1       ober     3364:        int s, error = 0;
                   3365:
                   3366:        s = splnet();
                   3367:
                   3368:        switch (cmd) {
1.33      christos 3369:        case SIOCSIFADDR:
1.40      christos 3370:                ifp->if_flags |= IFF_UP;
1.33      christos 3371:                /* FALLTHROUGH */
1.1       ober     3372:        case SIOCSIFFLAGS:
1.44      christos 3373:                /* XXX Added as it is in every NetBSD driver */
1.25      dyoung   3374:                if ((error = ifioctl_common(ifp, cmd, data)) != 0)
                   3375:                        break;
1.1       ober     3376:                if (ifp->if_flags & IFF_UP) {
1.40      christos 3377:                        if (!(ifp->if_flags & IFF_RUNNING))
1.33      christos 3378:                                error = iwn_init(ifp);
1.1       ober     3379:                } else {
                   3380:                        if (ifp->if_flags & IFF_RUNNING)
                   3381:                                iwn_stop(ifp, 1);
                   3382:                }
                   3383:                break;
                   3384:
                   3385:        case SIOCADDMULTI:
                   3386:        case SIOCDELMULTI:
1.40      christos 3387:                sa = ifreq_getaddr(SIOCADDMULTI, (struct ifreq *)data);
                   3388:                error = (cmd == SIOCADDMULTI) ?
                   3389:                    ether_addmulti(sa, &sc->sc_ec) :
                   3390:                    ether_delmulti(sa, &sc->sc_ec);
1.33      christos 3391:
1.40      christos 3392:                if (error == ENETRESET)
1.1       ober     3393:                        error = 0;
                   3394:                break;
                   3395:
                   3396:        default:
                   3397:                error = ieee80211_ioctl(ic, cmd, data);
                   3398:        }
                   3399:
                   3400:        if (error == ENETRESET) {
1.33      christos 3401:                error = 0;
1.40      christos 3402:                if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
                   3403:                    (IFF_UP | IFF_RUNNING)) {
1.33      christos 3404:                        iwn_stop(ifp, 0);
                   3405:                        error = iwn_init(ifp);
                   3406:                }
1.1       ober     3407:        }
1.46      christos 3408:
1.1       ober     3409:        splx(s);
                   3410:        return error;
                   3411: }
                   3412:
1.33      christos 3413: /*
                   3414:  * Send a command to the firmware.
                   3415:  */
                   3416: static int
                   3417: iwn_cmd(struct iwn_softc *sc, int code, const void *buf, int size, int async)
1.1       ober     3418: {
1.33      christos 3419:        struct iwn_tx_ring *ring = &sc->txq[4];
                   3420:        struct iwn_tx_desc *desc;
                   3421:        struct iwn_tx_data *data;
                   3422:        struct iwn_tx_cmd *cmd;
                   3423:        struct mbuf *m;
                   3424:        bus_addr_t paddr;
                   3425:        int totlen, error;
                   3426:
                   3427:        desc = &ring->desc[ring->cur];
                   3428:        data = &ring->data[ring->cur];
                   3429:        totlen = 4 + size;
1.1       ober     3430:
1.33      christos 3431:        if (size > sizeof cmd->data) {
                   3432:                /* Command is too large to fit in a descriptor. */
                   3433:                if (totlen > MCLBYTES)
                   3434:                        return EINVAL;
                   3435:                MGETHDR(m, M_DONTWAIT, MT_DATA);
                   3436:                if (m == NULL)
                   3437:                        return ENOMEM;
                   3438:                if (totlen > MHLEN) {
                   3439:                        MCLGET(m, M_DONTWAIT);
                   3440:                        if (!(m->m_flags & M_EXT)) {
                   3441:                                m_freem(m);
                   3442:                                return ENOMEM;
                   3443:                        }
                   3444:                }
                   3445:                cmd = mtod(m, struct iwn_tx_cmd *);
                   3446:                error = bus_dmamap_load(sc->sc_dmat, data->map, cmd, totlen,
1.40      christos 3447:                    NULL, BUS_DMA_NOWAIT | BUS_DMA_WRITE);
1.33      christos 3448:                if (error != 0) {
                   3449:                        m_freem(m);
                   3450:                        return error;
                   3451:                }
                   3452:                data->m = m;
                   3453:                paddr = data->map->dm_segs[0].ds_addr;
                   3454:        } else {
                   3455:                cmd = &ring->cmd[ring->cur];
                   3456:                paddr = data->cmd_paddr;
1.1       ober     3457:        }
                   3458:
1.33      christos 3459:        cmd->code = code;
                   3460:        cmd->flags = 0;
                   3461:        cmd->qid = ring->qid;
                   3462:        cmd->idx = ring->cur;
1.88      christos 3463:        /*
                   3464:         * Coverity:[OUT_OF_BOUNDS]
                   3465:         * false positive since, allocated in mbuf if it does not fit
                   3466:         */
1.33      christos 3467:        memcpy(cmd->data, buf, size);
1.1       ober     3468:
1.33      christos 3469:        desc->nsegs = 1;
                   3470:        desc->segs[0].addr = htole32(IWN_LOADDR(paddr));
                   3471:        desc->segs[0].len  = htole16(IWN_HIADDR(paddr) | totlen << 4);
                   3472:
                   3473:        if (size > sizeof cmd->data) {
                   3474:                bus_dmamap_sync(sc->sc_dmat, data->map, 0, totlen,
                   3475:                    BUS_DMASYNC_PREWRITE);
                   3476:        } else {
                   3477:                bus_dmamap_sync(sc->sc_dmat, ring->cmd_dma.map,
                   3478:                    (char *)(void *)cmd - (char *)(void *)ring->cmd_dma.vaddr,
                   3479:                    totlen, BUS_DMASYNC_PREWRITE);
                   3480:        }
                   3481:        bus_dmamap_sync(sc->sc_dmat, ring->desc_dma.map,
                   3482:            (char *)(void *)desc - (char *)(void *)ring->desc_dma.vaddr,
                   3483:            sizeof (*desc), BUS_DMASYNC_PREWRITE);
1.1       ober     3484:
1.40      christos 3485: #ifdef notyet
1.33      christos 3486:        /* Update TX scheduler. */
1.53      christos 3487:        ops->update_sched(sc, ring->qid, ring->cur, 0, 0);
1.40      christos 3488: #endif
                   3489:        DPRINTFN(4, ("iwn_cmd %d size=%d %s\n", code, size, async ? " (async)" : ""));
1.1       ober     3490:
1.33      christos 3491:        /* Kick command ring. */
                   3492:        ring->cur = (ring->cur + 1) % IWN_TX_RING_COUNT;
                   3493:        IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, ring->qid << 8 | ring->cur);
1.1       ober     3494:
1.33      christos 3495:        return async ? 0 : tsleep(desc, PCATCH, "iwncmd", hz);
1.1       ober     3496: }
                   3497:
1.33      christos 3498: static int
                   3499: iwn4965_add_node(struct iwn_softc *sc, struct iwn_node_info *node, int async)
                   3500: {
                   3501:        struct iwn4965_node_info hnode;
                   3502:        char *src, *dst;
1.1       ober     3503:
1.33      christos 3504:        /*
                   3505:         * We use the node structure for 5000 Series internally (it is
                   3506:         * a superset of the one for 4965AGN). We thus copy the common
                   3507:         * fields before sending the command.
                   3508:         */
                   3509:        src = (char *)node;
                   3510:        dst = (char *)&hnode;
                   3511:        memcpy(dst, src, 48);
                   3512:        /* Skip TSC, RX MIC and TX MIC fields from ``src''. */
                   3513:        memcpy(dst + 48, src + 72, 20);
                   3514:        return iwn_cmd(sc, IWN_CMD_ADD_NODE, &hnode, sizeof hnode, async);
1.1       ober     3515: }
                   3516:
1.33      christos 3517: static int
                   3518: iwn5000_add_node(struct iwn_softc *sc, struct iwn_node_info *node, int async)
1.1       ober     3519: {
1.33      christos 3520:        /* Direct mapping. */
                   3521:        return iwn_cmd(sc, IWN_CMD_ADD_NODE, node, sizeof (*node), async);
1.1       ober     3522: }
                   3523:
                   3524: static int
1.33      christos 3525: iwn_set_link_quality(struct iwn_softc *sc, struct ieee80211_node *ni)
1.1       ober     3526: {
1.33      christos 3527:        struct iwn_node *wn = (void *)ni;
                   3528:        struct ieee80211_rateset *rs = &ni->ni_rates;
                   3529:        struct iwn_cmd_link_quality linkq;
                   3530:        const struct iwn_rate *rinfo;
                   3531:        uint8_t txant;
                   3532:        int i, txrate;
                   3533:
                   3534:        /* Use the first valid TX antenna. */
1.40      christos 3535:        txant = IWN_LSB(sc->txchainmask);
1.33      christos 3536:
                   3537:        memset(&linkq, 0, sizeof linkq);
                   3538:        linkq.id = wn->id;
                   3539:        linkq.antmsk_1stream = txant;
1.40      christos 3540:        linkq.antmsk_2stream = IWN_ANT_AB;
                   3541:        linkq.ampdu_max = 31;
1.33      christos 3542:        linkq.ampdu_threshold = 3;
                   3543:        linkq.ampdu_limit = htole16(4000);      /* 4ms */
1.1       ober     3544:
1.33      christos 3545:        /* Start at highest available bit-rate. */
                   3546:        txrate = rs->rs_nrates - 1;
                   3547:        for (i = 0; i < IWN_MAX_TX_RETRIES; i++) {
                   3548:                rinfo = &iwn_rates[wn->ridx[txrate]];
                   3549:                linkq.retry[i].plcp = rinfo->plcp;
                   3550:                linkq.retry[i].rflags = rinfo->flags;
                   3551:                linkq.retry[i].rflags |= IWN_RFLAG_ANT(txant);
                   3552:                /* Next retry at immediate lower bit-rate. */
                   3553:                if (txrate > 0)
                   3554:                        txrate--;
1.1       ober     3555:        }
1.33      christos 3556:        return iwn_cmd(sc, IWN_CMD_LINK_QUALITY, &linkq, sizeof linkq, 1);
1.1       ober     3557: }
                   3558:
                   3559: /*
1.33      christos 3560:  * Broadcast node is used to send group-addressed and management frames.
1.1       ober     3561:  */
                   3562: static int
1.33      christos 3563: iwn_add_broadcast_node(struct iwn_softc *sc, int async)
1.1       ober     3564: {
1.53      christos 3565:        struct iwn_ops *ops = &sc->ops;
1.33      christos 3566:        struct iwn_node_info node;
                   3567:        struct iwn_cmd_link_quality linkq;
                   3568:        const struct iwn_rate *rinfo;
                   3569:        uint8_t txant;
                   3570:        int i, error;
1.1       ober     3571:
1.33      christos 3572:        memset(&node, 0, sizeof node);
                   3573:        IEEE80211_ADDR_COPY(node.macaddr, etherbroadcastaddr);
1.53      christos 3574:        node.id = sc->broadcast_id;
1.33      christos 3575:        DPRINTF(("adding broadcast node\n"));
1.53      christos 3576:        if ((error = ops->add_node(sc, &node, async)) != 0)
1.33      christos 3577:                return error;
1.1       ober     3578:
1.33      christos 3579:        /* Use the first valid TX antenna. */
1.40      christos 3580:        txant = IWN_LSB(sc->txchainmask);
1.1       ober     3581:
1.33      christos 3582:        memset(&linkq, 0, sizeof linkq);
1.53      christos 3583:        linkq.id = sc->broadcast_id;
1.33      christos 3584:        linkq.antmsk_1stream = txant;
1.40      christos 3585:        linkq.antmsk_2stream = IWN_ANT_AB;
1.33      christos 3586:        linkq.ampdu_max = 64;
                   3587:        linkq.ampdu_threshold = 3;
                   3588:        linkq.ampdu_limit = htole16(4000);      /* 4ms */
                   3589:
                   3590:        /* Use lowest mandatory bit-rate. */
                   3591:        rinfo = (sc->sc_ic.ic_curmode != IEEE80211_MODE_11A) ?
                   3592:            &iwn_rates[IWN_RIDX_CCK1] : &iwn_rates[IWN_RIDX_OFDM6];
                   3593:        linkq.retry[0].plcp = rinfo->plcp;
                   3594:        linkq.retry[0].rflags = rinfo->flags;
                   3595:        linkq.retry[0].rflags |= IWN_RFLAG_ANT(txant);
                   3596:        /* Use same bit-rate for all TX retries. */
                   3597:        for (i = 1; i < IWN_MAX_TX_RETRIES; i++) {
                   3598:                linkq.retry[i].plcp = linkq.retry[0].plcp;
                   3599:                linkq.retry[i].rflags = linkq.retry[0].rflags;
                   3600:        }
1.40      christos 3601:        return iwn_cmd(sc, IWN_CMD_LINK_QUALITY, &linkq, sizeof linkq, async);
1.1       ober     3602: }
                   3603:
                   3604: static void
                   3605: iwn_set_led(struct iwn_softc *sc, uint8_t which, uint8_t off, uint8_t on)
                   3606: {
                   3607:        struct iwn_cmd_led led;
                   3608:
1.33      christos 3609:        /* Clear microcode LED ownership. */
                   3610:        IWN_CLRBITS(sc, IWN_LED, IWN_LED_BSM_CTRL);
                   3611:
1.1       ober     3612:        led.which = which;
1.33      christos 3613:        led.unit = htole32(10000);      /* on/off in unit of 100ms */
1.1       ober     3614:        led.off = off;
                   3615:        led.on = on;
                   3616:        (void)iwn_cmd(sc, IWN_CMD_SET_LED, &led, sizeof led, 1);
                   3617: }
                   3618:
                   3619: /*
1.40      christos 3620:  * Set the critical temperature at which the firmware will stop the radio
                   3621:  * and notify us.
1.1       ober     3622:  */
                   3623: static int
                   3624: iwn_set_critical_temp(struct iwn_softc *sc)
                   3625: {
                   3626:        struct iwn_critical_temp crit;
1.40      christos 3627:        int32_t temp;
1.1       ober     3628:
1.33      christos 3629:        IWN_WRITE(sc, IWN_UCODE_GP1_CLR, IWN_UCODE_GP1_CTEMP_STOP_RF);
1.1       ober     3630:
1.40      christos 3631:        if (sc->hw_type == IWN_HW_REV_TYPE_5150)
                   3632:                temp = (IWN_CTOK(110) - sc->temp_off) * -5;
                   3633:        else if (sc->hw_type == IWN_HW_REV_TYPE_4965)
                   3634:                temp = IWN_CTOK(110);
                   3635:        else
                   3636:                temp = 110;
1.1       ober     3637:        memset(&crit, 0, sizeof crit);
1.40      christos 3638:        crit.tempR = htole32(temp);
                   3639:        DPRINTF(("setting critical temperature to %d\n", temp));
1.1       ober     3640:        return iwn_cmd(sc, IWN_CMD_SET_CRITICAL_TEMP, &crit, sizeof crit, 0);
                   3641: }
                   3642:
1.33      christos 3643: static int
                   3644: iwn_set_timing(struct iwn_softc *sc, struct ieee80211_node *ni)
1.1       ober     3645: {
1.33      christos 3646:        struct iwn_cmd_timing cmd;
1.1       ober     3647:        uint64_t val, mod;
                   3648:
1.33      christos 3649:        memset(&cmd, 0, sizeof cmd);
                   3650:        memcpy(&cmd.tstamp, ni->ni_tstamp.data, sizeof (uint64_t));
                   3651:        cmd.bintval = htole16(ni->ni_intval);
                   3652:        cmd.lintval = htole16(10);
1.1       ober     3653:
1.33      christos 3654:        /* Compute remaining time until next beacon. */
1.1       ober     3655:        val = (uint64_t)ni->ni_intval * 1024;   /* msecs -> usecs */
1.33      christos 3656:        mod = le64toh(cmd.tstamp) % val;
                   3657:        cmd.binitval = htole32((uint32_t)(val - mod));
1.1       ober     3658:
1.53      christos 3659:        DPRINTF(("timing bintval=%u, tstamp=%" PRIu64 ", init=%" PRIu32 "\n",
1.40      christos 3660:            ni->ni_intval, le64toh(cmd.tstamp), (uint32_t)(val - mod)));
1.1       ober     3661:
1.33      christos 3662:        return iwn_cmd(sc, IWN_CMD_TIMING, &cmd, sizeof cmd, 1);
1.1       ober     3663: }
                   3664:
                   3665: static void
1.33      christos 3666: iwn4965_power_calibration(struct iwn_softc *sc, int temp)
1.1       ober     3667: {
1.53      christos 3668:        /* Adjust TX power if need be (delta >= 3 degC). */
1.1       ober     3669:        DPRINTF(("temperature %d->%d\n", sc->temp, temp));
1.33      christos 3670:        if (abs(temp - sc->temp) >= 3) {
                   3671:                /* Record temperature of last calibration. */
                   3672:                sc->temp = temp;
                   3673:                (void)iwn4965_set_txpower(sc, 1);
1.1       ober     3674:        }
                   3675: }
                   3676:
                   3677: /*
1.33      christos 3678:  * Set TX power for current channel (each rate has its own power settings).
1.1       ober     3679:  * This function takes into account the regulatory information from EEPROM,
                   3680:  * the current temperature and the current voltage.
                   3681:  */
                   3682: static int
1.33      christos 3683: iwn4965_set_txpower(struct iwn_softc *sc, int async)
1.1       ober     3684: {
1.33      christos 3685: /* Fixed-point arithmetic division using a n-bit fractional part. */
                   3686: #define fdivround(a, b, n)     \
1.1       ober     3687:        ((((1 << n) * (a)) / (b) + (1 << n) / 2) / (1 << n))
1.33      christos 3688: /* Linear interpolation. */
                   3689: #define interpolate(x, x1, y1, x2, y2, n)      \
1.1       ober     3690:        ((y1) + fdivround(((int)(x) - (x1)) * ((y2) - (y1)), (x2) - (x1), n))
                   3691:
                   3692:        static const int tdiv[IWN_NATTEN_GROUPS] = { 9, 8, 8, 8, 6 };
                   3693:        struct ieee80211com *ic = &sc->sc_ic;
                   3694:        struct iwn_ucode_info *uc = &sc->ucode_info;
1.33      christos 3695:        struct ieee80211_channel *ch;
                   3696:        struct iwn4965_cmd_txpower cmd;
                   3697:        struct iwn4965_eeprom_chan_samples *chans;
1.1       ober     3698:        const uint8_t *rf_gain, *dsp_gain;
                   3699:        int32_t vdiff, tdiff;
                   3700:        int i, c, grp, maxpwr;
1.33      christos 3701:        uint8_t chan;
1.1       ober     3702:
1.33      christos 3703:        /* Retrieve current channel from last RXON. */
                   3704:        chan = sc->rxon.chan;
                   3705:        DPRINTF(("setting TX power for channel %d\n", chan));
                   3706:        ch = &ic->ic_channels[chan];
1.1       ober     3707:
                   3708:        memset(&cmd, 0, sizeof cmd);
                   3709:        cmd.band = IEEE80211_IS_CHAN_5GHZ(ch) ? 0 : 1;
                   3710:        cmd.chan = chan;
                   3711:
                   3712:        if (IEEE80211_IS_CHAN_5GHZ(ch)) {
1.33      christos 3713:                maxpwr   = sc->maxpwr5GHz;
                   3714:                rf_gain  = iwn4965_rf_gain_5ghz;
                   3715:                dsp_gain = iwn4965_dsp_gain_5ghz;
1.1       ober     3716:        } else {
1.33      christos 3717:                maxpwr   = sc->maxpwr2GHz;
                   3718:                rf_gain  = iwn4965_rf_gain_2ghz;
                   3719:                dsp_gain = iwn4965_dsp_gain_2ghz;
1.1       ober     3720:        }
                   3721:
1.33      christos 3722:        /* Compute voltage compensation. */
1.1       ober     3723:        vdiff = ((int32_t)le32toh(uc->volt) - sc->eeprom_voltage) / 7;
                   3724:        if (vdiff > 0)
                   3725:                vdiff *= 2;
                   3726:        if (abs(vdiff) > 2)
                   3727:                vdiff = 0;
                   3728:        DPRINTF(("voltage compensation=%d (UCODE=%d, EEPROM=%d)\n",
1.33      christos 3729:            vdiff, le32toh(uc->volt), sc->eeprom_voltage));
1.1       ober     3730:
1.40      christos 3731:        /* Get channel attenuation group. */
1.1       ober     3732:        if (chan <= 20)         /* 1-20 */
                   3733:                grp = 4;
                   3734:        else if (chan <= 43)    /* 34-43 */
                   3735:                grp = 0;
                   3736:        else if (chan <= 70)    /* 44-70 */
                   3737:                grp = 1;
                   3738:        else if (chan <= 124)   /* 71-124 */
                   3739:                grp = 2;
                   3740:        else                    /* 125-200 */
                   3741:                grp = 3;
                   3742:        DPRINTF(("chan %d, attenuation group=%d\n", chan, grp));
                   3743:
1.40      christos 3744:        /* Get channel sub-band. */
1.1       ober     3745:        for (i = 0; i < IWN_NBANDS; i++)
                   3746:                if (sc->bands[i].lo != 0 &&
                   3747:                    sc->bands[i].lo <= chan && chan <= sc->bands[i].hi)
                   3748:                        break;
1.40      christos 3749:        if (i == IWN_NBANDS)    /* Can't happen in real-life. */
                   3750:                return EINVAL;
1.1       ober     3751:        chans = sc->bands[i].chans;
                   3752:        DPRINTF(("chan %d sub-band=%d\n", chan, i));
                   3753:
1.33      christos 3754:        for (c = 0; c < 2; c++) {
1.1       ober     3755:                uint8_t power, gain, temp;
                   3756:                int maxchpwr, pwr, ridx, idx;
                   3757:
                   3758:                power = interpolate(chan,
                   3759:                    chans[0].num, chans[0].samples[c][1].power,
                   3760:                    chans[1].num, chans[1].samples[c][1].power, 1);
                   3761:                gain  = interpolate(chan,
                   3762:                    chans[0].num, chans[0].samples[c][1].gain,
                   3763:                    chans[1].num, chans[1].samples[c][1].gain, 1);
                   3764:                temp  = interpolate(chan,
                   3765:                    chans[0].num, chans[0].samples[c][1].temp,
                   3766:                    chans[1].num, chans[1].samples[c][1].temp, 1);
1.33      christos 3767:                DPRINTF(("TX chain %d: power=%d gain=%d temp=%d\n",
                   3768:                    c, power, gain, temp));
1.1       ober     3769:
1.33      christos 3770:                /* Compute temperature compensation. */
1.1       ober     3771:                tdiff = ((sc->temp - temp) * 2) / tdiv[grp];
                   3772:                DPRINTF(("temperature compensation=%d (current=%d, "
1.33      christos 3773:                    "EEPROM=%d)\n", tdiff, sc->temp, temp));
1.1       ober     3774:
                   3775:                for (ridx = 0; ridx <= IWN_RIDX_MAX; ridx++) {
1.40      christos 3776:                        /* Convert dBm to half-dBm. */
1.1       ober     3777:                        maxchpwr = sc->maxpwr[chan] * 2;
1.33      christos 3778:                        if ((ridx / 8) & 1)
                   3779:                                maxchpwr -= 6;  /* MIMO 2T: -3dB */
1.1       ober     3780:
1.33      christos 3781:                        pwr = maxpwr;
1.1       ober     3782:
1.33      christos 3783:                        /* Adjust TX power based on rate. */
                   3784:                        if ((ridx % 8) == 5)
                   3785:                                pwr -= 15;      /* OFDM48: -7.5dB */
                   3786:                        else if ((ridx % 8) == 6)
                   3787:                                pwr -= 17;      /* OFDM54: -8.5dB */
                   3788:                        else if ((ridx % 8) == 7)
                   3789:                                pwr -= 20;      /* OFDM60: -10dB */
                   3790:                        else
                   3791:                                pwr -= 10;      /* Others: -5dB */
1.1       ober     3792:
1.40      christos 3793:                        /* Do not exceed channel max TX power. */
1.1       ober     3794:                        if (pwr > maxchpwr)
                   3795:                                pwr = maxchpwr;
                   3796:
                   3797:                        idx = gain - (pwr - power) - tdiff - vdiff;
                   3798:                        if ((ridx / 8) & 1)     /* MIMO */
                   3799:                                idx += (int32_t)le32toh(uc->atten[grp][c]);
                   3800:
                   3801:                        if (cmd.band == 0)
                   3802:                                idx += 9;       /* 5GHz */
                   3803:                        if (ridx == IWN_RIDX_MAX)
                   3804:                                idx += 5;       /* CCK */
                   3805:
1.33      christos 3806:                        /* Make sure idx stays in a valid range. */
1.1       ober     3807:                        if (idx < 0)
                   3808:                                idx = 0;
1.33      christos 3809:                        else if (idx > IWN4965_MAX_PWR_INDEX)
                   3810:                                idx = IWN4965_MAX_PWR_INDEX;
1.1       ober     3811:
1.33      christos 3812:                        DPRINTF(("TX chain %d, rate idx %d: power=%d\n",
                   3813:                            c, ridx, idx));
1.1       ober     3814:                        cmd.power[ridx].rf_gain[c] = rf_gain[idx];
                   3815:                        cmd.power[ridx].dsp_gain[c] = dsp_gain[idx];
                   3816:                }
                   3817:        }
                   3818:
1.33      christos 3819:        DPRINTF(("setting TX power for chan %d\n", chan));
1.1       ober     3820:        return iwn_cmd(sc, IWN_CMD_TXPOWER, &cmd, sizeof cmd, async);
                   3821:
                   3822: #undef interpolate
                   3823: #undef fdivround
                   3824: }
                   3825:
1.33      christos 3826: static int
                   3827: iwn5000_set_txpower(struct iwn_softc *sc, int async)
                   3828: {
                   3829:        struct iwn5000_cmd_txpower cmd;
1.85      mlelstv  3830:        int cmdid;
1.33      christos 3831:
                   3832:        /*
                   3833:         * TX power calibration is handled automatically by the firmware
                   3834:         * for 5000 Series.
                   3835:         */
                   3836:        memset(&cmd, 0, sizeof cmd);
                   3837:        cmd.global_limit = 2 * IWN5000_TXPOWER_MAX_DBM; /* 16 dBm */
                   3838:        cmd.flags = IWN5000_TXPOWER_NO_CLOSED;
                   3839:        cmd.srv_limit = IWN5000_TXPOWER_AUTO;
                   3840:        DPRINTF(("setting TX power\n"));
1.85      mlelstv  3841:        if (IWN_UCODE_API(sc->ucode_rev) == 1)
                   3842:                cmdid = IWN_CMD_TXPOWER_DBM_V1;
                   3843:        else
                   3844:                cmdid = IWN_CMD_TXPOWER_DBM;
                   3845:        return iwn_cmd(sc, cmdid, &cmd, sizeof cmd, async);
1.33      christos 3846: }
                   3847:
1.1       ober     3848: /*
1.33      christos 3849:  * Retrieve the maximum RSSI (in dBm) among receivers.
1.1       ober     3850:  */
                   3851: static int
1.33      christos 3852: iwn4965_get_rssi(const struct iwn_rx_stat *stat)
1.1       ober     3853: {
1.33      christos 3854:        const struct iwn4965_rx_phystat *phy = (const void *)stat->phybuf;
1.1       ober     3855:        uint8_t mask, agc;
                   3856:        int rssi;
                   3857:
1.40      christos 3858:        mask = (le16toh(phy->antenna) >> 4) & IWN_ANT_ABC;
1.33      christos 3859:        agc  = (le16toh(phy->agc) >> 7) & 0x7f;
1.1       ober     3860:
                   3861:        rssi = 0;
1.33      christos 3862:        if (mask & IWN_ANT_A)
                   3863:                rssi = MAX(rssi, phy->rssi[0]);
                   3864:        if (mask & IWN_ANT_B)
                   3865:                rssi = MAX(rssi, phy->rssi[2]);
                   3866:        if (mask & IWN_ANT_C)
                   3867:                rssi = MAX(rssi, phy->rssi[4]);
                   3868:
                   3869:        return rssi - agc - IWN_RSSI_TO_DBM;
                   3870: }
                   3871:
                   3872: static int
                   3873: iwn5000_get_rssi(const struct iwn_rx_stat *stat)
                   3874: {
                   3875:        const struct iwn5000_rx_phystat *phy = (const void *)stat->phybuf;
                   3876:        uint8_t agc;
                   3877:        int rssi;
                   3878:
                   3879:        agc = (le32toh(phy->agc) >> 9) & 0x7f;
                   3880:
                   3881:        rssi = MAX(le16toh(phy->rssi[0]) & 0xff,
                   3882:                   le16toh(phy->rssi[1]) & 0xff);
                   3883:        rssi = MAX(le16toh(phy->rssi[2]) & 0xff, rssi);
1.1       ober     3884:
                   3885:        return rssi - agc - IWN_RSSI_TO_DBM;
                   3886: }
                   3887:
                   3888: /*
1.33      christos 3889:  * Retrieve the average noise (in dBm) among receivers.
1.1       ober     3890:  */
                   3891: static int
                   3892: iwn_get_noise(const struct iwn_rx_general_stats *stats)
                   3893: {
                   3894:        int i, total, nbant, noise;
                   3895:
                   3896:        total = nbant = 0;
                   3897:        for (i = 0; i < 3; i++) {
                   3898:                if ((noise = le32toh(stats->noise[i]) & 0xff) == 0)
                   3899:                        continue;
                   3900:                total += noise;
                   3901:                nbant++;
                   3902:        }
1.33      christos 3903:        /* There should be at least one antenna but check anyway. */
1.1       ober     3904:        return (nbant == 0) ? -127 : (total / nbant) - 107;
                   3905: }
                   3906:
                   3907: /*
1.33      christos 3908:  * Compute temperature (in degC) from last received statistics.
1.1       ober     3909:  */
                   3910: static int
1.33      christos 3911: iwn4965_get_temperature(struct iwn_softc *sc)
1.1       ober     3912: {
                   3913:        struct iwn_ucode_info *uc = &sc->ucode_info;
                   3914:        int32_t r1, r2, r3, r4, temp;
                   3915:
                   3916:        r1 = le32toh(uc->temp[0].chan20MHz);
                   3917:        r2 = le32toh(uc->temp[1].chan20MHz);
                   3918:        r3 = le32toh(uc->temp[2].chan20MHz);
                   3919:        r4 = le32toh(sc->rawtemp);
                   3920:
1.53      christos 3921:        if (r1 == r3)   /* Prevents division by 0 (should not happen). */
1.1       ober     3922:                return 0;
                   3923:
1.33      christos 3924:        /* Sign-extend 23-bit R4 value to 32-bit. */
1.53      christos 3925:        r4 = ((r4 & 0xffffff) ^ 0x800000) - 0x800000;
1.33      christos 3926:        /* Compute temperature in Kelvin. */
1.1       ober     3927:        temp = (259 * (r4 - r2)) / (r3 - r1);
                   3928:        temp = (temp * 97) / 100 + 8;
                   3929:
                   3930:        DPRINTF(("temperature %dK/%dC\n", temp, IWN_KTOC(temp)));
                   3931:        return IWN_KTOC(temp);
                   3932: }
                   3933:
1.33      christos 3934: static int
                   3935: iwn5000_get_temperature(struct iwn_softc *sc)
                   3936: {
1.40      christos 3937:        int32_t temp;
                   3938:
1.33      christos 3939:        /*
                   3940:         * Temperature is not used by the driver for 5000 Series because
                   3941:         * TX power calibration is handled by firmware.  We export it to
                   3942:         * users through the sensor framework though.
                   3943:         */
1.40      christos 3944:        temp = le32toh(sc->rawtemp);
                   3945:        if (sc->hw_type == IWN_HW_REV_TYPE_5150) {
                   3946:                temp = (temp / -5) + sc->temp_off;
                   3947:                temp = IWN_KTOC(temp);
                   3948:        }
                   3949:        return temp;
1.33      christos 3950: }
                   3951:
1.1       ober     3952: /*
                   3953:  * Initialize sensitivity calibration state machine.
                   3954:  */
                   3955: static int
                   3956: iwn_init_sensitivity(struct iwn_softc *sc)
                   3957: {
1.53      christos 3958:        struct iwn_ops *ops = &sc->ops;
1.1       ober     3959:        struct iwn_calib_state *calib = &sc->calib;
1.33      christos 3960:        uint32_t flags;
1.1       ober     3961:        int error;
                   3962:
1.33      christos 3963:        /* Reset calibration state machine. */
1.1       ober     3964:        memset(calib, 0, sizeof (*calib));
                   3965:        calib->state = IWN_CALIB_STATE_INIT;
                   3966:        calib->cck_state = IWN_CCK_STATE_HIFA;
1.33      christos 3967:        /* Set initial correlation values. */
1.40      christos 3968:        calib->ofdm_x1     = sc->limits->min_ofdm_x1;
                   3969:        calib->ofdm_mrc_x1 = sc->limits->min_ofdm_mrc_x1;
                   3970:        calib->ofdm_x4     = sc->limits->min_ofdm_x4;
                   3971:        calib->ofdm_mrc_x4 = sc->limits->min_ofdm_mrc_x4;
1.33      christos 3972:        calib->cck_x4      = 125;
1.40      christos 3973:        calib->cck_mrc_x4  = sc->limits->min_cck_mrc_x4;
                   3974:        calib->energy_cck  = sc->limits->energy_cck;
1.1       ober     3975:
1.33      christos 3976:        /* Write initial sensitivity. */
1.1       ober     3977:        if ((error = iwn_send_sensitivity(sc)) != 0)
                   3978:                return error;
                   3979:
1.33      christos 3980:        /* Write initial gains. */
1.53      christos 3981:        if ((error = ops->init_gains(sc)) != 0)
1.33      christos 3982:                return error;
                   3983:
                   3984:        /* Request statistics at each beacon interval. */
                   3985:        flags = 0;
                   3986:        DPRINTF(("sending request for statistics\n"));
                   3987:        return iwn_cmd(sc, IWN_CMD_GET_STATISTICS, &flags, sizeof flags, 1);
1.1       ober     3988: }
                   3989:
                   3990: /*
                   3991:  * Collect noise and RSSI statistics for the first 20 beacons received
                   3992:  * after association and use them to determine connected antennas and
1.33      christos 3993:  * to set differential gains.
1.1       ober     3994:  */
                   3995: static void
1.33      christos 3996: iwn_collect_noise(struct iwn_softc *sc,
1.1       ober     3997:     const struct iwn_rx_general_stats *stats)
                   3998: {
1.53      christos 3999:        struct iwn_ops *ops = &sc->ops;
1.1       ober     4000:        struct iwn_calib_state *calib = &sc->calib;
1.33      christos 4001:        uint32_t val;
                   4002:        int i;
1.1       ober     4003:
1.33      christos 4004:        /* Accumulate RSSI and noise for all 3 antennas. */
1.1       ober     4005:        for (i = 0; i < 3; i++) {
                   4006:                calib->rssi[i] += le32toh(stats->rssi[i]) & 0xff;
                   4007:                calib->noise[i] += le32toh(stats->noise[i]) & 0xff;
                   4008:        }
1.33      christos 4009:        /* NB: We update differential gains only once after 20 beacons. */
1.1       ober     4010:        if (++calib->nbeacons < 20)
                   4011:                return;
                   4012:
1.33      christos 4013:        /* Determine highest average RSSI. */
                   4014:        val = MAX(calib->rssi[0], calib->rssi[1]);
                   4015:        val = MAX(calib->rssi[2], val);
1.1       ober     4016:
1.33      christos 4017:        /* Determine which antennas are connected. */
1.40      christos 4018:        sc->chainmask = sc->rxchainmask;
1.1       ober     4019:        for (i = 0; i < 3; i++)
1.40      christos 4020:                if (val - calib->rssi[i] > 15 * 20)
                   4021:                        sc->chainmask &= ~(1 << i);
1.44      christos 4022:        DPRINTF(("RX chains mask: theoretical=0x%x, actual=0x%x\n",
                   4023:            sc->rxchainmask, sc->chainmask));
                   4024:
1.33      christos 4025:        /* If none of the TX antennas are connected, keep at least one. */
1.40      christos 4026:        if ((sc->chainmask & sc->txchainmask) == 0)
                   4027:                sc->chainmask |= IWN_LSB(sc->txchainmask);
1.33      christos 4028:
1.53      christos 4029:        (void)ops->set_gains(sc);
1.33      christos 4030:        calib->state = IWN_CALIB_STATE_RUN;
                   4031:
                   4032: #ifdef notyet
                   4033:        /* XXX Disable RX chains with no antennas connected. */
1.40      christos 4034:        sc->rxon.rxchain = htole16(IWN_RXCHAIN_SEL(sc->chainmask));
1.53      christos 4035:        (void)iwn_cmd(sc, IWN_CMD_RXON, &sc->rxon, sc->rxonsz, 1);
1.40      christos 4036: #endif
1.33      christos 4037:
                   4038:        /* Enable power-saving mode if requested by user. */
                   4039:        if (sc->sc_ic.ic_flags & IEEE80211_F_PMGTON)
                   4040:                (void)iwn_set_pslevel(sc, 0, 3, 1);
                   4041: }
                   4042:
                   4043: static int
                   4044: iwn4965_init_gains(struct iwn_softc *sc)
                   4045: {
                   4046:        struct iwn_phy_calib_gain cmd;
                   4047:
                   4048:        memset(&cmd, 0, sizeof cmd);
                   4049:        cmd.code = IWN4965_PHY_CALIB_DIFF_GAIN;
                   4050:        /* Differential gains initially set to 0 for all 3 antennas. */
                   4051:        DPRINTF(("setting initial differential gains\n"));
                   4052:        return iwn_cmd(sc, IWN_CMD_PHY_CALIB, &cmd, sizeof cmd, 1);
                   4053: }
                   4054:
                   4055: static int
                   4056: iwn5000_init_gains(struct iwn_softc *sc)
                   4057: {
                   4058:        struct iwn_phy_calib cmd;
                   4059:
                   4060:        memset(&cmd, 0, sizeof cmd);
1.72      nonaka   4061:        cmd.code = sc->reset_noise_gain;
1.33      christos 4062:        cmd.ngroups = 1;
                   4063:        cmd.isvalid = 1;
                   4064:        DPRINTF(("setting initial differential gains\n"));
                   4065:        return iwn_cmd(sc, IWN_CMD_PHY_CALIB, &cmd, sizeof cmd, 1);
                   4066: }
                   4067:
                   4068: static int
                   4069: iwn4965_set_gains(struct iwn_softc *sc)
                   4070: {
                   4071:        struct iwn_calib_state *calib = &sc->calib;
                   4072:        struct iwn_phy_calib_gain cmd;
                   4073:        int i, delta, noise;
1.1       ober     4074:
1.33      christos 4075:        /* Get minimal noise among connected antennas. */
                   4076:        noise = INT_MAX;        /* NB: There's at least one antenna. */
1.1       ober     4077:        for (i = 0; i < 3; i++)
1.40      christos 4078:                if (sc->chainmask & (1 << i))
1.33      christos 4079:                        noise = MIN(calib->noise[i], noise);
1.1       ober     4080:
                   4081:        memset(&cmd, 0, sizeof cmd);
1.33      christos 4082:        cmd.code = IWN4965_PHY_CALIB_DIFF_GAIN;
                   4083:        /* Set differential gains for connected antennas. */
1.1       ober     4084:        for (i = 0; i < 3; i++) {
1.40      christos 4085:                if (sc->chainmask & (1 << i)) {
1.33      christos 4086:                        /* Compute attenuation (in unit of 1.5dB). */
                   4087:                        delta = (noise - (int32_t)calib->noise[i]) / 30;
                   4088:                        /* NB: delta <= 0 */
                   4089:                        /* Limit to [-4.5dB,0]. */
                   4090:                        cmd.gain[i] = MIN(abs(delta), 3);
                   4091:                        if (delta < 0)
                   4092:                                cmd.gain[i] |= 1 << 2;  /* sign bit */
1.1       ober     4093:                }
                   4094:        }
                   4095:        DPRINTF(("setting differential gains Ant A/B/C: %x/%x/%x (%x)\n",
1.40      christos 4096:            cmd.gain[0], cmd.gain[1], cmd.gain[2], sc->chainmask));
1.33      christos 4097:        return iwn_cmd(sc, IWN_CMD_PHY_CALIB, &cmd, sizeof cmd, 1);
                   4098: }
                   4099:
                   4100: static int
                   4101: iwn5000_set_gains(struct iwn_softc *sc)
                   4102: {
                   4103:        struct iwn_calib_state *calib = &sc->calib;
                   4104:        struct iwn_phy_calib_gain cmd;
1.40      christos 4105:        int i, ant, div, delta;
1.33      christos 4106:
1.40      christos 4107:        /* We collected 20 beacons and !=6050 need a 1.5 factor. */
                   4108:        div = (sc->hw_type == IWN_HW_REV_TYPE_6050) ? 20 : 30;
1.33      christos 4109:
                   4110:        memset(&cmd, 0, sizeof cmd);
1.72      nonaka   4111:        cmd.code = sc->noise_gain;
1.33      christos 4112:        cmd.ngroups = 1;
                   4113:        cmd.isvalid = 1;
1.40      christos 4114:        /* Get first available RX antenna as referential. */
                   4115:        ant = IWN_LSB(sc->rxchainmask);
                   4116:        /* Set differential gains for other antennas. */
                   4117:        for (i = ant + 1; i < 3; i++) {
                   4118:                if (sc->chainmask & (1 << i)) {
                   4119:                        /* The delta is relative to antenna "ant". */
                   4120:                        delta = ((int32_t)calib->noise[ant] -
                   4121:                            (int32_t)calib->noise[i]) / div;
1.33      christos 4122:                        /* Limit to [-4.5dB,+4.5dB]. */
                   4123:                        cmd.gain[i - 1] = MIN(abs(delta), 3);
                   4124:                        if (delta < 0)
                   4125:                                cmd.gain[i - 1] |= 1 << 2;      /* sign bit */
                   4126:                }
                   4127:        }
1.40      christos 4128:        DPRINTF(("setting differential gains: %x/%x (%x)\n",
                   4129:            cmd.gain[0], cmd.gain[1], sc->chainmask));
1.33      christos 4130:        return iwn_cmd(sc, IWN_CMD_PHY_CALIB, &cmd, sizeof cmd, 1);
1.1       ober     4131: }
                   4132:
                   4133: /*
1.33      christos 4134:  * Tune RF RX sensitivity based on the number of false alarms detected
1.1       ober     4135:  * during the last beacon period.
                   4136:  */
                   4137: static void
                   4138: iwn_tune_sensitivity(struct iwn_softc *sc, const struct iwn_rx_stats *stats)
                   4139: {
1.33      christos 4140: #define inc(val, inc, max)                     \
                   4141:        if ((val) < (max)) {                    \
                   4142:                if ((val) < (max) - (inc))      \
                   4143:                        (val) += (inc);         \
                   4144:                else                            \
                   4145:                        (val) = (max);          \
                   4146:                needs_update = 1;               \
                   4147:        }
                   4148: #define dec(val, dec, min)                     \
                   4149:        if ((val) > (min)) {                    \
                   4150:                if ((val) > (min) + (dec))      \
                   4151:                        (val) -= (dec);         \
                   4152:                else                            \
                   4153:                        (val) = (min);          \
                   4154:                needs_update = 1;               \
1.1       ober     4155:        }
                   4156:
1.40      christos 4157:        const struct iwn_sensitivity_limits *limits = sc->limits;
1.1       ober     4158:        struct iwn_calib_state *calib = &sc->calib;
                   4159:        uint32_t val, rxena, fa;
                   4160:        uint32_t energy[3], energy_min;
                   4161:        uint8_t noise[3], noise_ref;
                   4162:        int i, needs_update = 0;
                   4163:
1.33      christos 4164:        /* Check that we've been enabled long enough. */
1.1       ober     4165:        if ((rxena = le32toh(stats->general.load)) == 0)
                   4166:                return;
                   4167:
1.33      christos 4168:        /* Compute number of false alarms since last call for OFDM. */
1.1       ober     4169:        fa  = le32toh(stats->ofdm.bad_plcp) - calib->bad_plcp_ofdm;
                   4170:        fa += le32toh(stats->ofdm.fa) - calib->fa_ofdm;
                   4171:        fa *= 200 * 1024;       /* 200TU */
                   4172:
1.33      christos 4173:        /* Save counters values for next call. */
1.1       ober     4174:        calib->bad_plcp_ofdm = le32toh(stats->ofdm.bad_plcp);
                   4175:        calib->fa_ofdm = le32toh(stats->ofdm.fa);
                   4176:
                   4177:        if (fa > 50 * rxena) {
1.33      christos 4178:                /* High false alarm count, decrease sensitivity. */
1.1       ober     4179:                DPRINTFN(2, ("OFDM high false alarm count: %u\n", fa));
1.33      christos 4180:                inc(calib->ofdm_x1,     1, limits->max_ofdm_x1);
                   4181:                inc(calib->ofdm_mrc_x1, 1, limits->max_ofdm_mrc_x1);
                   4182:                inc(calib->ofdm_x4,     1, limits->max_ofdm_x4);
                   4183:                inc(calib->ofdm_mrc_x4, 1, limits->max_ofdm_mrc_x4);
1.1       ober     4184:
                   4185:        } else if (fa < 5 * rxena) {
1.33      christos 4186:                /* Low false alarm count, increase sensitivity. */
1.1       ober     4187:                DPRINTFN(2, ("OFDM low false alarm count: %u\n", fa));
1.33      christos 4188:                dec(calib->ofdm_x1,     1, limits->min_ofdm_x1);
                   4189:                dec(calib->ofdm_mrc_x1, 1, limits->min_ofdm_mrc_x1);
                   4190:                dec(calib->ofdm_x4,     1, limits->min_ofdm_x4);
                   4191:                dec(calib->ofdm_mrc_x4, 1, limits->min_ofdm_mrc_x4);
1.1       ober     4192:        }
                   4193:
1.33      christos 4194:        /* Compute maximum noise among 3 receivers. */
1.1       ober     4195:        for (i = 0; i < 3; i++)
                   4196:                noise[i] = (le32toh(stats->general.noise[i]) >> 8) & 0xff;
1.33      christos 4197:        val = MAX(noise[0], noise[1]);
                   4198:        val = MAX(noise[2], val);
                   4199:        /* Insert it into our samples table. */
1.1       ober     4200:        calib->noise_samples[calib->cur_noise_sample] = val;
                   4201:        calib->cur_noise_sample = (calib->cur_noise_sample + 1) % 20;
                   4202:
1.33      christos 4203:        /* Compute maximum noise among last 20 samples. */
1.1       ober     4204:        noise_ref = calib->noise_samples[0];
                   4205:        for (i = 1; i < 20; i++)
1.33      christos 4206:                noise_ref = MAX(noise_ref, calib->noise_samples[i]);
1.1       ober     4207:
1.33      christos 4208:        /* Compute maximum energy among 3 receivers. */
1.1       ober     4209:        for (i = 0; i < 3; i++)
                   4210:                energy[i] = le32toh(stats->general.energy[i]);
1.33      christos 4211:        val = MIN(energy[0], energy[1]);
                   4212:        val = MIN(energy[2], val);
                   4213:        /* Insert it into our samples table. */
1.1       ober     4214:        calib->energy_samples[calib->cur_energy_sample] = val;
                   4215:        calib->cur_energy_sample = (calib->cur_energy_sample + 1) % 10;
                   4216:
1.33      christos 4217:        /* Compute minimum energy among last 10 samples. */
1.1       ober     4218:        energy_min = calib->energy_samples[0];
                   4219:        for (i = 1; i < 10; i++)
1.33      christos 4220:                energy_min = MAX(energy_min, calib->energy_samples[i]);
1.1       ober     4221:        energy_min += 6;
                   4222:
1.33      christos 4223:        /* Compute number of false alarms since last call for CCK. */
1.1       ober     4224:        fa  = le32toh(stats->cck.bad_plcp) - calib->bad_plcp_cck;
                   4225:        fa += le32toh(stats->cck.fa) - calib->fa_cck;
                   4226:        fa *= 200 * 1024;       /* 200TU */
                   4227:
1.33      christos 4228:        /* Save counters values for next call. */
1.1       ober     4229:        calib->bad_plcp_cck = le32toh(stats->cck.bad_plcp);
                   4230:        calib->fa_cck = le32toh(stats->cck.fa);
                   4231:
                   4232:        if (fa > 50 * rxena) {
1.33      christos 4233:                /* High false alarm count, decrease sensitivity. */
1.1       ober     4234:                DPRINTFN(2, ("CCK high false alarm count: %u\n", fa));
                   4235:                calib->cck_state = IWN_CCK_STATE_HIFA;
                   4236:                calib->low_fa = 0;
                   4237:
1.33      christos 4238:                if (calib->cck_x4 > 160) {
1.1       ober     4239:                        calib->noise_ref = noise_ref;
                   4240:                        if (calib->energy_cck > 2)
1.33      christos 4241:                                dec(calib->energy_cck, 2, energy_min);
1.1       ober     4242:                }
1.33      christos 4243:                if (calib->cck_x4 < 160) {
                   4244:                        calib->cck_x4 = 161;
1.1       ober     4245:                        needs_update = 1;
                   4246:                } else
1.33      christos 4247:                        inc(calib->cck_x4, 3, limits->max_cck_x4);
1.1       ober     4248:
1.33      christos 4249:                inc(calib->cck_mrc_x4, 3, limits->max_cck_mrc_x4);
1.1       ober     4250:
                   4251:        } else if (fa < 5 * rxena) {
1.33      christos 4252:                /* Low false alarm count, increase sensitivity. */
1.1       ober     4253:                DPRINTFN(2, ("CCK low false alarm count: %u\n", fa));
                   4254:                calib->cck_state = IWN_CCK_STATE_LOFA;
                   4255:                calib->low_fa++;
                   4256:
1.33      christos 4257:                if (calib->cck_state != IWN_CCK_STATE_INIT &&
                   4258:                    (((int32_t)calib->noise_ref - (int32_t)noise_ref) > 2 ||
                   4259:                     calib->low_fa > 100)) {
                   4260:                        inc(calib->energy_cck, 2, limits->min_energy_cck);
                   4261:                        dec(calib->cck_x4,     3, limits->min_cck_x4);
                   4262:                        dec(calib->cck_mrc_x4, 3, limits->min_cck_mrc_x4);
1.1       ober     4263:                }
                   4264:        } else {
1.33      christos 4265:                /* Not worth to increase or decrease sensitivity. */
1.1       ober     4266:                DPRINTFN(2, ("CCK normal false alarm count: %u\n", fa));
                   4267:                calib->low_fa = 0;
                   4268:                calib->noise_ref = noise_ref;
                   4269:
                   4270:                if (calib->cck_state == IWN_CCK_STATE_HIFA) {
1.33      christos 4271:                        /* Previous interval had many false alarms. */
                   4272:                        dec(calib->energy_cck, 8, energy_min);
1.1       ober     4273:                }
                   4274:                calib->cck_state = IWN_CCK_STATE_INIT;
                   4275:        }
                   4276:
                   4277:        if (needs_update)
                   4278:                (void)iwn_send_sensitivity(sc);
1.33      christos 4279: #undef dec
                   4280: #undef inc
1.1       ober     4281: }
                   4282:
                   4283: static int
                   4284: iwn_send_sensitivity(struct iwn_softc *sc)
                   4285: {
                   4286:        struct iwn_calib_state *calib = &sc->calib;
1.72      nonaka   4287:        struct iwn_enhanced_sensitivity_cmd cmd;
                   4288:        int len;
1.1       ober     4289:
                   4290:        memset(&cmd, 0, sizeof cmd);
1.72      nonaka   4291:        len = sizeof (struct iwn_sensitivity_cmd);
1.1       ober     4292:        cmd.which = IWN_SENSITIVITY_WORKTBL;
1.33      christos 4293:        /* OFDM modulation. */
                   4294:        cmd.corr_ofdm_x1     = htole16(calib->ofdm_x1);
                   4295:        cmd.corr_ofdm_mrc_x1 = htole16(calib->ofdm_mrc_x1);
                   4296:        cmd.corr_ofdm_x4     = htole16(calib->ofdm_x4);
                   4297:        cmd.corr_ofdm_mrc_x4 = htole16(calib->ofdm_mrc_x4);
1.40      christos 4298:        cmd.energy_ofdm      = htole16(sc->limits->energy_ofdm);
1.33      christos 4299:        cmd.energy_ofdm_th   = htole16(62);
                   4300:        /* CCK modulation. */
                   4301:        cmd.corr_cck_x4      = htole16(calib->cck_x4);
                   4302:        cmd.corr_cck_mrc_x4  = htole16(calib->cck_mrc_x4);
                   4303:        cmd.energy_cck       = htole16(calib->energy_cck);
                   4304:        /* Barker modulation: use default values. */
                   4305:        cmd.corr_barker      = htole16(190);
1.85      mlelstv  4306:        cmd.corr_barker_mrc  = htole16(sc->limits->barker_mrc);
1.72      nonaka   4307:        if (!(sc->sc_flags & IWN_FLAG_ENH_SENS))
                   4308:                goto send;
                   4309:        /* Enhanced sensitivity settings. */
                   4310:        len = sizeof (struct iwn_enhanced_sensitivity_cmd);
                   4311:        cmd.ofdm_det_slope_mrc = htole16(668);
                   4312:        cmd.ofdm_det_icept_mrc = htole16(4);
                   4313:        cmd.ofdm_det_slope     = htole16(486);
                   4314:        cmd.ofdm_det_icept     = htole16(37);
                   4315:        cmd.cck_det_slope_mrc  = htole16(853);
                   4316:        cmd.cck_det_icept_mrc  = htole16(4);
                   4317:        cmd.cck_det_slope      = htole16(476);
                   4318:        cmd.cck_det_icept      = htole16(99);
                   4319: send:
1.33      christos 4320:        DPRINTFN(2, ("setting sensitivity %d/%d/%d/%d/%d/%d/%d\n",
                   4321:            calib->ofdm_x1, calib->ofdm_mrc_x1, calib->ofdm_x4,
                   4322:            calib->ofdm_mrc_x4, calib->cck_x4, calib->cck_mrc_x4,
                   4323:            calib->energy_cck));
1.72      nonaka   4324:        return iwn_cmd(sc, IWN_CMD_SET_SENSITIVITY, &cmd, len, 1);
1.33      christos 4325: }
                   4326:
                   4327: /*
                   4328:  * Set STA mode power saving level (between 0 and 5).
                   4329:  * Level 0 is CAM (Continuously Aware Mode), 5 is for maximum power saving.
                   4330:  */
                   4331: static int
                   4332: iwn_set_pslevel(struct iwn_softc *sc, int dtim, int level, int async)
                   4333: {
                   4334:        struct iwn_pmgt_cmd cmd;
                   4335:        const struct iwn_pmgt *pmgt;
1.40      christos 4336:        uint32_t maxp, skip_dtim;
1.33      christos 4337:        pcireg_t reg;
                   4338:        int i;
                   4339:
                   4340:        /* Select which PS parameters to use. */
                   4341:        if (dtim <= 2)
                   4342:                pmgt = &iwn_pmgt[0][level];
                   4343:        else if (dtim <= 10)
                   4344:                pmgt = &iwn_pmgt[1][level];
                   4345:        else
                   4346:                pmgt = &iwn_pmgt[2][level];
                   4347:
                   4348:        memset(&cmd, 0, sizeof cmd);
                   4349:        if (level != 0) /* not CAM */
                   4350:                cmd.flags |= htole16(IWN_PS_ALLOW_SLEEP);
                   4351:        if (level == 5)
                   4352:                cmd.flags |= htole16(IWN_PS_FAST_PD);
                   4353:        /* Retrieve PCIe Active State Power Management (ASPM). */
                   4354:        reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag,
1.65      msaitoh  4355:            sc->sc_cap_off + PCIE_LCSR);
                   4356:        if (!(reg & PCIE_LCSR_ASPM_L0S))        /* L0s Entry disabled. */
1.33      christos 4357:                cmd.flags |= htole16(IWN_PS_PCI_PMGT);
                   4358:        cmd.rxtimeout = htole32(pmgt->rxtimeout * 1024);
                   4359:        cmd.txtimeout = htole32(pmgt->txtimeout * 1024);
                   4360:
                   4361:        if (dtim == 0) {
                   4362:                dtim = 1;
                   4363:                skip_dtim = 0;
                   4364:        } else
                   4365:                skip_dtim = pmgt->skip_dtim;
                   4366:        if (skip_dtim != 0) {
                   4367:                cmd.flags |= htole16(IWN_PS_SLEEP_OVER_DTIM);
1.40      christos 4368:                maxp = pmgt->intval[4];
                   4369:                if (maxp == (uint32_t)-1)
                   4370:                        maxp = dtim * (skip_dtim + 1);
                   4371:                else if (maxp > dtim)
                   4372:                        maxp = (maxp / dtim) * dtim;
1.33      christos 4373:        } else
1.40      christos 4374:                maxp = dtim;
1.33      christos 4375:        for (i = 0; i < 5; i++)
1.40      christos 4376:                cmd.intval[i] = htole32(MIN(maxp, pmgt->intval[i]));
1.1       ober     4377:
1.33      christos 4378:        DPRINTF(("setting power saving level to %d\n", level));
                   4379:        return iwn_cmd(sc, IWN_CMD_SET_POWER_MODE, &cmd, sizeof cmd, async);
1.1       ober     4380: }
                   4381:
1.60      mbalmer  4382: int
1.59      elric    4383: iwn5000_runtime_calib(struct iwn_softc *sc)
                   4384: {
                   4385:        struct iwn5000_calib_config cmd;
                   4386:
                   4387:        memset(&cmd, 0, sizeof cmd);
                   4388:        cmd.ucode.once.enable = 0xffffffff;
                   4389:        cmd.ucode.once.start = IWN5000_CALIB_DC;
                   4390:        DPRINTF(("configuring runtime calibration\n"));
                   4391:        return iwn_cmd(sc, IWN5000_CMD_CALIB_CONFIG, &cmd, sizeof(cmd), 0);
                   4392: }
                   4393:
1.1       ober     4394: static int
1.67      prlw1    4395: iwn_config_bt_coex_bluetooth(struct iwn_softc *sc)
                   4396: {
                   4397:        struct iwn_bluetooth bluetooth;
                   4398:
                   4399:        memset(&bluetooth, 0, sizeof bluetooth);
                   4400:        bluetooth.flags = IWN_BT_COEX_ENABLE;
                   4401:        bluetooth.lead_time = IWN_BT_LEAD_TIME_DEF;
                   4402:        bluetooth.max_kill = IWN_BT_MAX_KILL_DEF;
                   4403:
                   4404:        DPRINTF(("configuring bluetooth coexistence\n"));
                   4405:        return iwn_cmd(sc, IWN_CMD_BT_COEX, &bluetooth, sizeof bluetooth, 0);
                   4406: }
                   4407:
                   4408: static int
                   4409: iwn_config_bt_coex_prio_table(struct iwn_softc *sc)
                   4410: {
                   4411:        uint8_t prio_table[16];
                   4412:
                   4413:        memset(&prio_table, 0, sizeof prio_table);
                   4414:        prio_table[ 0] =  6;    /* init calibration 1           */
                   4415:        prio_table[ 1] =  7;    /* init calibration 2           */
                   4416:        prio_table[ 2] =  2;    /* periodic calib low 1         */
                   4417:        prio_table[ 3] =  3;    /* periodic calib low 2         */
                   4418:        prio_table[ 4] =  4;    /* periodic calib high 1        */
                   4419:        prio_table[ 5] =  5;    /* periodic calib high 2        */
                   4420:        prio_table[ 6] =  6;    /* dtim                         */
                   4421:        prio_table[ 7] =  8;    /* scan52                       */
                   4422:        prio_table[ 8] = 10;    /* scan24                       */
                   4423:
                   4424:        DPRINTF(("sending priority lookup table\n"));
                   4425:        return iwn_cmd(sc, IWN_CMD_BT_COEX_PRIO_TABLE,
                   4426:                       &prio_table, sizeof prio_table, 0);
                   4427: }
                   4428:
                   4429: static int
1.72      nonaka   4430: iwn_config_bt_coex_adv_config(struct iwn_softc *sc, struct iwn_bt_basic *basic,
                   4431:     size_t len)
1.67      prlw1    4432: {
1.72      nonaka   4433:        struct iwn_btcoex_prot btprot;
1.67      prlw1    4434:        int error;
                   4435:
1.72      nonaka   4436:        basic->bt.flags = IWN_BT_COEX_ENABLE;
                   4437:        basic->bt.lead_time = IWN_BT_LEAD_TIME_DEF;
                   4438:        basic->bt.max_kill = IWN_BT_MAX_KILL_DEF;
                   4439:        basic->bt.bt3_timer_t7_value = IWN_BT_BT3_T7_DEF;
                   4440:        basic->bt.kill_ack_mask = IWN_BT_KILL_ACK_MASK_DEF;
                   4441:        basic->bt.kill_cts_mask = IWN_BT_KILL_CTS_MASK_DEF;
                   4442:        basic->bt3_prio_sample_time = IWN_BT_BT3_PRIO_SAMPLE_DEF;
                   4443:        basic->bt3_timer_t2_value = IWN_BT_BT3_T2_DEF;
                   4444:        basic->bt3_lookup_table[ 0] = htole32(0xaaaaaaaa); /* Normal */
                   4445:        basic->bt3_lookup_table[ 1] = htole32(0xaaaaaaaa);
                   4446:        basic->bt3_lookup_table[ 2] = htole32(0xaeaaaaaa);
                   4447:        basic->bt3_lookup_table[ 3] = htole32(0xaaaaaaaa);
                   4448:        basic->bt3_lookup_table[ 4] = htole32(0xcc00ff28);
                   4449:        basic->bt3_lookup_table[ 5] = htole32(0x0000aaaa);
                   4450:        basic->bt3_lookup_table[ 6] = htole32(0xcc00aaaa);
                   4451:        basic->bt3_lookup_table[ 7] = htole32(0x0000aaaa);
                   4452:        basic->bt3_lookup_table[ 8] = htole32(0xc0004000);
                   4453:        basic->bt3_lookup_table[ 9] = htole32(0x00004000);
                   4454:        basic->bt3_lookup_table[10] = htole32(0xf0005000);
                   4455:        basic->bt3_lookup_table[11] = htole32(0xf0005000);
                   4456:        basic->reduce_txpower = 0; /* as not implemented */
                   4457:        basic->valid = IWN_BT_ALL_VALID_MASK;
1.67      prlw1    4458:
                   4459:        DPRINTF(("configuring advanced bluetooth coexistence v1\n"));
1.72      nonaka   4460:        error = iwn_cmd(sc, IWN_CMD_BT_COEX, basic, len, 0);
1.67      prlw1    4461:        if (error != 0) {
                   4462:                aprint_error_dev(sc->sc_dev,
                   4463:                        "could not configure advanced bluetooth coexistence\n");
                   4464:                return error;
                   4465:        }
                   4466:
                   4467:        error = iwn_config_bt_coex_prio_table(sc);
                   4468:        if (error != 0) {
                   4469:                aprint_error_dev(sc->sc_dev,
                   4470:                        "could not configure send BT priority table\n");
                   4471:                return error;
                   4472:        }
                   4473:
1.72      nonaka   4474:        /* Force BT state machine change */
                   4475:        memset(&btprot, 0, sizeof btprot);
                   4476:        btprot.open = 1;
                   4477:        btprot.type = 1;
                   4478:        error = iwn_cmd(sc, IWN_CMD_BT_COEX_PROT, &btprot, sizeof btprot, 1);
                   4479:        if (error != 0) {
                   4480:                aprint_error_dev(sc->sc_dev, "could not open BT protcol\n");
                   4481:                return error;
                   4482:        }
                   4483:
                   4484:        btprot.open = 0;
                   4485:        error = iwn_cmd(sc, IWN_CMD_BT_COEX_PROT, &btprot, sizeof btprot, 1);
                   4486:        if (error != 0) {
                   4487:                aprint_error_dev(sc->sc_dev, "could not close BT protcol\n");
                   4488:                return error;
                   4489:        }
                   4490:        return 0;
                   4491: }
                   4492:
                   4493: static int
                   4494: iwn_config_bt_coex_adv1(struct iwn_softc *sc)
                   4495: {
                   4496:        struct iwn_bt_adv1 d;
                   4497:
                   4498:        memset(&d, 0, sizeof d);
                   4499:        d.prio_boost = IWN_BT_PRIO_BOOST_DEF;
                   4500:        d.tx_prio_boost = 0;
                   4501:        d.rx_prio_boost = 0;
                   4502:        return iwn_config_bt_coex_adv_config(sc, &d.basic, sizeof d);
                   4503: }
                   4504:
                   4505: static int
                   4506: iwn_config_bt_coex_adv2(struct iwn_softc *sc)
                   4507: {
                   4508:        struct iwn_bt_adv2 d;
                   4509:
                   4510:        memset(&d, 0, sizeof d);
                   4511:        d.prio_boost = IWN_BT_PRIO_BOOST_DEF;
                   4512:        d.tx_prio_boost = 0;
                   4513:        d.rx_prio_boost = 0;
                   4514:        return iwn_config_bt_coex_adv_config(sc, &d.basic, sizeof d);
1.67      prlw1    4515: }
                   4516:
                   4517: static int
1.33      christos 4518: iwn_config(struct iwn_softc *sc)
1.11      blymn    4519: {
1.53      christos 4520:        struct iwn_ops *ops = &sc->ops;
1.33      christos 4521:        struct ieee80211com *ic = &sc->sc_ic;
                   4522:        struct ifnet *ifp = ic->ic_ifp;
1.40      christos 4523:        uint32_t txmask;
1.33      christos 4524:        uint16_t rxchain;
1.11      blymn    4525:        int error;
                   4526:
1.67      prlw1    4527:        error = ops->config_bt_coex(sc);
                   4528:        if (error != 0) {
                   4529:                aprint_error_dev(sc->sc_dev,
                   4530:                        "could not configure bluetooth coexistence\n");
                   4531:                return error;
                   4532:        }
                   4533:
1.72      nonaka   4534:        /* Set radio temperature sensor offset. */
                   4535:        if (sc->hw_type == IWN_HW_REV_TYPE_6005) {
                   4536:                error = iwn6000_temp_offset_calib(sc);
                   4537:                if (error != 0) {
                   4538:                        aprint_error_dev(sc->sc_dev,
                   4539:                            "could not set temperature offset\n");
                   4540:                        return error;
                   4541:                }
                   4542:        }
                   4543:
                   4544:        if (sc->hw_type == IWN_HW_REV_TYPE_2030 ||
                   4545:            sc->hw_type == IWN_HW_REV_TYPE_2000 ||
                   4546:            sc->hw_type == IWN_HW_REV_TYPE_135  ||
                   4547:            sc->hw_type == IWN_HW_REV_TYPE_105) {
                   4548:                error = iwn2000_temp_offset_calib(sc);
                   4549:                if (error != 0) {
                   4550:                        aprint_error_dev(sc->sc_dev,
                   4551:                            "could not set temperature offset\n");
                   4552:                        return error;
                   4553:                }
                   4554:        }
                   4555:
1.59      elric    4556:        if (sc->hw_type == IWN_HW_REV_TYPE_6050 ||
                   4557:            sc->hw_type == IWN_HW_REV_TYPE_6005) {
                   4558:                /* Configure runtime DC calibration. */
                   4559:                error = iwn5000_runtime_calib(sc);
                   4560:                if (error != 0) {
1.61      elric    4561:                        aprint_error_dev(sc->sc_dev,
                   4562:                            "could not configure runtime calibration\n");
1.59      elric    4563:                        return error;
                   4564:                }
                   4565:        }
                   4566:
1.40      christos 4567:        /* Configure valid TX chains for 5000 Series. */
                   4568:        if (sc->hw_type != IWN_HW_REV_TYPE_4965) {
                   4569:                txmask = htole32(sc->txchainmask);
                   4570:                DPRINTF(("configuring valid TX chains 0x%x\n", txmask));
                   4571:                error = iwn_cmd(sc, IWN5000_CMD_TX_ANT_CONFIG, &txmask,
                   4572:                    sizeof txmask, 0);
                   4573:                if (error != 0) {
                   4574:                        aprint_error_dev(sc->sc_dev,
                   4575:                            "could not configure valid TX chains\n");
                   4576:                        return error;
                   4577:                }
1.11      blymn    4578:        }
1.33      christos 4579:
1.40      christos 4580:        /* Set mode, channel, RX filter and enable RX. */
1.33      christos 4581:        memset(&sc->rxon, 0, sizeof (struct iwn_rxon));
                   4582:        IEEE80211_ADDR_COPY(ic->ic_myaddr, CLLADDR(ifp->if_sadl));
                   4583:        IEEE80211_ADDR_COPY(sc->rxon.myaddr, ic->ic_myaddr);
                   4584:        IEEE80211_ADDR_COPY(sc->rxon.wlap, ic->ic_myaddr);
1.40      christos 4585:        sc->rxon.chan = ieee80211_chan2ieee(ic, ic->ic_ibss_chan);
1.33      christos 4586:        sc->rxon.flags = htole32(IWN_RXON_TSF | IWN_RXON_CTS_TO_SELF);
                   4587:        if (IEEE80211_IS_CHAN_2GHZ(ic->ic_ibss_chan))
                   4588:                sc->rxon.flags |= htole32(IWN_RXON_AUTO | IWN_RXON_24GHZ);
                   4589:        switch (ic->ic_opmode) {
                   4590:        case IEEE80211_M_STA:
                   4591:                sc->rxon.mode = IWN_MODE_STA;
                   4592:                sc->rxon.filter = htole32(IWN_FILTER_MULTICAST);
                   4593:                break;
                   4594:        case IEEE80211_M_MONITOR:
                   4595:                sc->rxon.mode = IWN_MODE_MONITOR;
                   4596:                sc->rxon.filter = htole32(IWN_FILTER_MULTICAST |
                   4597:                    IWN_FILTER_CTL | IWN_FILTER_PROMISC);
                   4598:                break;
                   4599:        default:
                   4600:                /* Should not get there. */
                   4601:                break;
1.1       ober     4602:        }
1.33      christos 4603:        sc->rxon.cck_mask  = 0x0f;      /* not yet negotiated */
                   4604:        sc->rxon.ofdm_mask = 0xff;      /* not yet negotiated */
                   4605:        sc->rxon.ht_single_mask = 0xff;
                   4606:        sc->rxon.ht_dual_mask = 0xff;
1.40      christos 4607:        sc->rxon.ht_triple_mask = 0xff;
                   4608:        rxchain =
                   4609:            IWN_RXCHAIN_VALID(sc->rxchainmask) |
                   4610:            IWN_RXCHAIN_MIMO_COUNT(2) |
                   4611:            IWN_RXCHAIN_IDLE_COUNT(2);
1.33      christos 4612:        sc->rxon.rxchain = htole16(rxchain);
                   4613:        DPRINTF(("setting configuration\n"));
1.53      christos 4614:        error = iwn_cmd(sc, IWN_CMD_RXON, &sc->rxon, sc->rxonsz, 0);
1.1       ober     4615:        if (error != 0) {
1.40      christos 4616:                aprint_error_dev(sc->sc_dev,
                   4617:                    "RXON command failed\n");
                   4618:                return error;
                   4619:        }
                   4620:
                   4621:        if ((error = iwn_add_broadcast_node(sc, 0)) != 0) {
                   4622:                aprint_error_dev(sc->sc_dev,
                   4623:                    "could not add broadcast node\n");
1.1       ober     4624:                return error;
                   4625:        }
                   4626:
1.33      christos 4627:        /* Configuration has changed, set TX power accordingly. */
1.53      christos 4628:        if ((error = ops->set_txpower(sc, 0)) != 0) {
1.40      christos 4629:                aprint_error_dev(sc->sc_dev,
                   4630:                    "could not set TX power\n");
1.1       ober     4631:                return error;
                   4632:        }
                   4633:
1.40      christos 4634:        if ((error = iwn_set_critical_temp(sc)) != 0) {
                   4635:                aprint_error_dev(sc->sc_dev,
                   4636:                    "could not set critical temperature\n");
1.11      blymn    4637:                return error;
1.33      christos 4638:        }
1.11      blymn    4639:
1.40      christos 4640:        /* Set power saving level to CAM during initialization. */
                   4641:        if ((error = iwn_set_pslevel(sc, 0, 0, 0)) != 0) {
1.33      christos 4642:                aprint_error_dev(sc->sc_dev,
1.40      christos 4643:                    "could not set power saving level\n");
1.33      christos 4644:                return error;
                   4645:        }
                   4646:        return 0;
                   4647: }
                   4648:
1.72      nonaka   4649: static uint16_t
                   4650: iwn_get_active_dwell_time(struct iwn_softc *sc, uint16_t flags,
                   4651:     uint8_t n_probes)
                   4652: {
                   4653:        /* No channel? Default to 2GHz settings */
                   4654:        if (flags & IEEE80211_CHAN_2GHZ)
                   4655:                return IWN_ACTIVE_DWELL_TIME_2GHZ +
                   4656:                    IWN_ACTIVE_DWELL_FACTOR_2GHZ * (n_probes + 1);
                   4657:
                   4658:        /* 5GHz dwell time */
                   4659:        return IWN_ACTIVE_DWELL_TIME_5GHZ +
                   4660:            IWN_ACTIVE_DWELL_FACTOR_5GHZ * (n_probes + 1);
                   4661: }
                   4662:
                   4663: /*
                   4664:  * Limit the total dwell time to 85% of the beacon interval.
                   4665:  *
                   4666:  * Returns the dwell time in milliseconds.
                   4667:  */
                   4668: static uint16_t
                   4669: iwn_limit_dwell(struct iwn_softc *sc, uint16_t dwell_time)
                   4670: {
                   4671:        struct ieee80211com *ic = &sc->sc_ic;
                   4672:        struct ieee80211_node *ni = ic->ic_bss;
                   4673:        int bintval = 0;
                   4674:
                   4675:        /* bintval is in TU (1.024mS) */
                   4676:        if (ni != NULL)
                   4677:                bintval = ni->ni_intval;
                   4678:
                   4679:        /*
                   4680:         * If it's non-zero, we should calculate the minimum of
                   4681:         * it and the DWELL_BASE.
                   4682:         *
                   4683:         * XXX Yes, the math should take into account that bintval
                   4684:         * is 1.024mS, not 1mS..
                   4685:         */
                   4686:        if (bintval > 0)
                   4687:                return MIN(IWN_PASSIVE_DWELL_BASE, ((bintval * 85) / 100));
                   4688:
                   4689:        /* No association context? Default */
                   4690:        return IWN_PASSIVE_DWELL_BASE;
                   4691: }
                   4692:
                   4693: static uint16_t
                   4694: iwn_get_passive_dwell_time(struct iwn_softc *sc, uint16_t flags)
                   4695: {
                   4696:        uint16_t passive;
                   4697:        if (flags & IEEE80211_CHAN_2GHZ)
                   4698:                passive = IWN_PASSIVE_DWELL_BASE + IWN_PASSIVE_DWELL_TIME_2GHZ;
                   4699:        else
                   4700:                passive = IWN_PASSIVE_DWELL_BASE + IWN_PASSIVE_DWELL_TIME_5GHZ;
                   4701:
                   4702:        /* Clamp to the beacon interval if we're associated */
                   4703:        return iwn_limit_dwell(sc, passive);
                   4704: }
                   4705:
1.33      christos 4706: static int
                   4707: iwn_scan(struct iwn_softc *sc, uint16_t flags)
                   4708: {
                   4709:        struct ieee80211com *ic = &sc->sc_ic;
                   4710:        struct iwn_scan_hdr *hdr;
                   4711:        struct iwn_cmd_data *tx;
1.40      christos 4712:        struct iwn_scan_essid *essid;
1.33      christos 4713:        struct iwn_scan_chan *chan;
                   4714:        struct ieee80211_frame *wh;
                   4715:        struct ieee80211_rateset *rs;
                   4716:        struct ieee80211_channel *c;
                   4717:        uint8_t *buf, *frm;
1.72      nonaka   4718:        uint16_t rxchain, dwell_active, dwell_passive;
1.33      christos 4719:        uint8_t txant;
1.72      nonaka   4720:        int buflen, error, is_active;
1.33      christos 4721:
                   4722:        buf = malloc(IWN_SCAN_MAXSZ, M_DEVBUF, M_NOWAIT | M_ZERO);
                   4723:        if (buf == NULL) {
                   4724:                aprint_error_dev(sc->sc_dev,
                   4725:                    "could not allocate buffer for scan command\n");
                   4726:                return ENOMEM;
                   4727:        }
                   4728:        hdr = (struct iwn_scan_hdr *)buf;
                   4729:        /*
                   4730:         * Move to the next channel if no frames are received within 10ms
                   4731:         * after sending the probe request.
                   4732:         */
                   4733:        hdr->quiet_time = htole16(10);          /* timeout in milliseconds */
                   4734:        hdr->quiet_threshold = htole16(1);      /* min # of packets */
                   4735:
                   4736:        /* Select antennas for scanning. */
1.40      christos 4737:        rxchain =
                   4738:            IWN_RXCHAIN_VALID(sc->rxchainmask) |
                   4739:            IWN_RXCHAIN_FORCE_MIMO_SEL(sc->rxchainmask) |
                   4740:            IWN_RXCHAIN_DRIVER_FORCE;
1.33      christos 4741:        if ((flags & IEEE80211_CHAN_5GHZ) &&
                   4742:            sc->hw_type == IWN_HW_REV_TYPE_4965) {
                   4743:                /* Ant A must be avoided in 5GHz because of an HW bug. */
1.40      christos 4744:                rxchain |= IWN_RXCHAIN_FORCE_SEL(IWN_ANT_BC);
1.33      christos 4745:        } else  /* Use all available RX antennas. */
1.40      christos 4746:                rxchain |= IWN_RXCHAIN_FORCE_SEL(sc->rxchainmask);
1.33      christos 4747:        hdr->rxchain = htole16(rxchain);
                   4748:        hdr->filter = htole32(IWN_FILTER_MULTICAST | IWN_FILTER_BEACON);
                   4749:
1.40      christos 4750:        tx = (struct iwn_cmd_data *)(hdr + 1);
1.33      christos 4751:        tx->flags = htole32(IWN_TX_AUTO_SEQ);
1.53      christos 4752:        tx->id = sc->broadcast_id;
1.33      christos 4753:        tx->lifetime = htole32(IWN_LIFETIME_INFINITE);
                   4754:
                   4755:        if (flags & IEEE80211_CHAN_5GHZ) {
1.46      christos 4756:                hdr->crc_threshold = 0xffff;
1.33      christos 4757:                /* Send probe requests at 6Mbps. */
                   4758:                tx->plcp = iwn_rates[IWN_RIDX_OFDM6].plcp;
                   4759:                rs = &ic->ic_sup_rates[IEEE80211_MODE_11A];
                   4760:        } else {
                   4761:                hdr->flags = htole32(IWN_RXON_24GHZ | IWN_RXON_AUTO);
                   4762:                /* Send probe requests at 1Mbps. */
                   4763:                tx->plcp = iwn_rates[IWN_RIDX_CCK1].plcp;
                   4764:                tx->rflags = IWN_RFLAG_CCK;
                   4765:                rs = &ic->ic_sup_rates[IEEE80211_MODE_11G];
                   4766:        }
                   4767:        /* Use the first valid TX antenna. */
1.40      christos 4768:        txant = IWN_LSB(sc->txchainmask);
1.33      christos 4769:        tx->rflags |= IWN_RFLAG_ANT(txant);
                   4770:
1.72      nonaka   4771:        /*
                   4772:         * Only do active scanning if we're announcing a probe request
                   4773:         * for a given SSID (or more, if we ever add it to the driver.)
                   4774:         */
                   4775:        is_active = 0;
                   4776:
1.40      christos 4777:        essid = (struct iwn_scan_essid *)(tx + 1);
1.33      christos 4778:        if (ic->ic_des_esslen != 0) {
1.40      christos 4779:                essid[0].id = IEEE80211_ELEMID_SSID;
                   4780:                essid[0].len = ic->ic_des_esslen;
                   4781:                memcpy(essid[0].data, ic->ic_des_essid, ic->ic_des_esslen);
1.72      nonaka   4782:
                   4783:                is_active = 1;
1.33      christos 4784:        }
                   4785:        /*
                   4786:         * Build a probe request frame.  Most of the following code is a
                   4787:         * copy & paste of what is done in net80211.
                   4788:         */
1.40      christos 4789:        wh = (struct ieee80211_frame *)(essid + 20);
1.33      christos 4790:        wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT |
                   4791:            IEEE80211_FC0_SUBTYPE_PROBE_REQ;
                   4792:        wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
                   4793:        IEEE80211_ADDR_COPY(wh->i_addr1, etherbroadcastaddr);
                   4794:        IEEE80211_ADDR_COPY(wh->i_addr2, ic->ic_myaddr);
                   4795:        IEEE80211_ADDR_COPY(wh->i_addr3, etherbroadcastaddr);
                   4796:        *(uint16_t *)&wh->i_dur[0] = 0; /* filled by HW */
                   4797:        *(uint16_t *)&wh->i_seq[0] = 0; /* filled by HW */
                   4798:
1.40      christos 4799:        frm = (uint8_t *)(wh + 1);
                   4800:        frm = ieee80211_add_ssid(frm, NULL, 0);
                   4801:        frm = ieee80211_add_rates(frm, rs);
1.46      christos 4802: #ifndef IEEE80211_NO_HT
                   4803:        if (ic->ic_flags & IEEE80211_F_HTON)
                   4804:                frm = ieee80211_add_htcaps(frm, ic);
                   4805: #endif
1.40      christos 4806:        if (rs->rs_nrates > IEEE80211_RATE_SIZE)
                   4807:                frm = ieee80211_add_xrates(frm, rs);
1.33      christos 4808:
                   4809:        /* Set length of probe request. */
                   4810:        tx->len = htole16(frm - (uint8_t *)wh);
                   4811:
1.72      nonaka   4812:
                   4813:        /*
                   4814:         * If active scanning is requested but a certain channel is
                   4815:         * marked passive, we can do active scanning if we detect
                   4816:         * transmissions.
                   4817:         *
                   4818:         * There is an issue with some firmware versions that triggers
                   4819:         * a sysassert on a "good CRC threshold" of zero (== disabled),
                   4820:         * on a radar channel even though this means that we should NOT
                   4821:         * send probes.
                   4822:         *
                   4823:         * The "good CRC threshold" is the number of frames that we
                   4824:         * need to receive during our dwell time on a channel before
                   4825:         * sending out probes -- setting this to a huge value will
                   4826:         * mean we never reach it, but at the same time work around
                   4827:         * the aforementioned issue. Thus use IWN_GOOD_CRC_TH_NEVER
                   4828:         * here instead of IWN_GOOD_CRC_TH_DISABLED.
                   4829:         *
                   4830:         * This was fixed in later versions along with some other
                   4831:         * scan changes, and the threshold behaves as a flag in those
                   4832:         * versions.
                   4833:         */
                   4834:
                   4835:        /*
                   4836:         * If we're doing active scanning, set the crc_threshold
                   4837:         * to a suitable value.  This is different to active veruss
                   4838:         * passive scanning depending upon the channel flags; the
                   4839:         * firmware will obey that particular check for us.
                   4840:         */
                   4841:        if (sc->tlv_feature_flags & IWN_UCODE_TLV_FLAGS_NEWSCAN)
                   4842:                hdr->crc_threshold = is_active ?
                   4843:                    IWN_GOOD_CRC_TH_DEFAULT : IWN_GOOD_CRC_TH_DISABLED;
                   4844:        else
                   4845:                hdr->crc_threshold = is_active ?
                   4846:                    IWN_GOOD_CRC_TH_DEFAULT : IWN_GOOD_CRC_TH_NEVER;
                   4847:
1.33      christos 4848:        chan = (struct iwn_scan_chan *)frm;
                   4849:        for (c  = &ic->ic_channels[1];
                   4850:             c <= &ic->ic_channels[IEEE80211_CHAN_MAX]; c++) {
                   4851:                if ((c->ic_flags & flags) != flags)
                   4852:                        continue;
                   4853:
                   4854:                chan->chan = htole16(ieee80211_chan2ieee(ic, c));
                   4855:                DPRINTFN(2, ("adding channel %d\n", chan->chan));
                   4856:                chan->flags = 0;
                   4857:                if (!(c->ic_flags & IEEE80211_CHAN_PASSIVE))
                   4858:                        chan->flags |= htole32(IWN_CHAN_ACTIVE);
                   4859:                if (ic->ic_des_esslen != 0)
                   4860:                        chan->flags |= htole32(IWN_CHAN_NPBREQS(1));
1.72      nonaka   4861:
                   4862:                /*
                   4863:                 * Calculate the active/passive dwell times.
                   4864:                 */
                   4865:
                   4866:                dwell_active = iwn_get_active_dwell_time(sc, flags, is_active);
                   4867:                dwell_passive = iwn_get_passive_dwell_time(sc, flags);
                   4868:
                   4869:                /* Make sure they're valid */
                   4870:                if (dwell_passive <= dwell_active)
                   4871:                        dwell_passive = dwell_active + 1;
                   4872:
                   4873:                chan->active = htole16(dwell_active);
                   4874:                chan->passive = htole16(dwell_passive);
                   4875:
1.33      christos 4876:                chan->dsp_gain = 0x6e;
                   4877:                if (IEEE80211_IS_CHAN_5GHZ(c)) {
                   4878:                        chan->rf_gain = 0x3b;
                   4879:                } else {
                   4880:                        chan->rf_gain = 0x28;
                   4881:                }
                   4882:                hdr->nchan++;
                   4883:                chan++;
                   4884:        }
                   4885:
                   4886:        buflen = (uint8_t *)chan - buf;
                   4887:        hdr->len = htole16(buflen);
                   4888:
                   4889:        DPRINTF(("sending scan command nchan=%d\n", hdr->nchan));
                   4890:        error = iwn_cmd(sc, IWN_CMD_SCAN, buf, buflen, 1);
                   4891:        free(buf, M_DEVBUF);
                   4892:        return error;
                   4893: }
                   4894:
                   4895: static int
                   4896: iwn_auth(struct iwn_softc *sc)
                   4897: {
1.53      christos 4898:        struct iwn_ops *ops = &sc->ops;
1.33      christos 4899:        struct ieee80211com *ic = &sc->sc_ic;
                   4900:        struct ieee80211_node *ni = ic->ic_bss;
                   4901:        int error;
                   4902:
1.40      christos 4903:        /* Update adapter configuration. */
1.33      christos 4904:        IEEE80211_ADDR_COPY(sc->rxon.bssid, ni->ni_bssid);
1.40      christos 4905:        sc->rxon.chan = ieee80211_chan2ieee(ic, ni->ni_chan);
1.33      christos 4906:        sc->rxon.flags = htole32(IWN_RXON_TSF | IWN_RXON_CTS_TO_SELF);
                   4907:        if (IEEE80211_IS_CHAN_2GHZ(ni->ni_chan))
                   4908:                sc->rxon.flags |= htole32(IWN_RXON_AUTO | IWN_RXON_24GHZ);
                   4909:        if (ic->ic_flags & IEEE80211_F_SHSLOT)
                   4910:                sc->rxon.flags |= htole32(IWN_RXON_SHSLOT);
                   4911:        if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)
                   4912:                sc->rxon.flags |= htole32(IWN_RXON_SHPREAMBLE);
                   4913:        switch (ic->ic_curmode) {
                   4914:        case IEEE80211_MODE_11A:
                   4915:                sc->rxon.cck_mask  = 0;
                   4916:                sc->rxon.ofdm_mask = 0x15;
                   4917:                break;
                   4918:        case IEEE80211_MODE_11B:
                   4919:                sc->rxon.cck_mask  = 0x03;
                   4920:                sc->rxon.ofdm_mask = 0;
                   4921:                break;
                   4922:        default:        /* Assume 802.11b/g. */
                   4923:                sc->rxon.cck_mask  = 0x0f;
                   4924:                sc->rxon.ofdm_mask = 0x15;
                   4925:        }
                   4926:        DPRINTF(("rxon chan %d flags %x cck %x ofdm %x\n", sc->rxon.chan,
                   4927:            sc->rxon.flags, sc->rxon.cck_mask, sc->rxon.ofdm_mask));
1.53      christos 4928:        error = iwn_cmd(sc, IWN_CMD_RXON, &sc->rxon, sc->rxonsz, 1);
1.33      christos 4929:        if (error != 0) {
1.40      christos 4930:                aprint_error_dev(sc->sc_dev,
                   4931:                    "RXON command failed\n");
1.33      christos 4932:                return error;
                   4933:        }
                   4934:
                   4935:        /* Configuration has changed, set TX power accordingly. */
1.53      christos 4936:        if ((error = ops->set_txpower(sc, 1)) != 0) {
1.40      christos 4937:                aprint_error_dev(sc->sc_dev,
                   4938:                    "could not set TX power\n");
1.33      christos 4939:                return error;
                   4940:        }
                   4941:        /*
1.40      christos 4942:         * Reconfiguring RXON clears the firmware nodes table so we must
1.33      christos 4943:         * add the broadcast node again.
                   4944:         */
                   4945:        if ((error = iwn_add_broadcast_node(sc, 1)) != 0) {
1.40      christos 4946:                aprint_error_dev(sc->sc_dev,
                   4947:                    "could not add broadcast node\n");
1.1       ober     4948:                return error;
                   4949:        }
                   4950:        return 0;
                   4951: }
                   4952:
                   4953: static int
                   4954: iwn_run(struct iwn_softc *sc)
                   4955: {
1.53      christos 4956:        struct iwn_ops *ops = &sc->ops;
1.1       ober     4957:        struct ieee80211com *ic = &sc->sc_ic;
                   4958:        struct ieee80211_node *ni = ic->ic_bss;
1.40      christos 4959:        struct iwn_node_info node;
1.1       ober     4960:        int error;
                   4961:
                   4962:        if (ic->ic_opmode == IEEE80211_M_MONITOR) {
1.33      christos 4963:                /* Link LED blinks while monitoring. */
1.1       ober     4964:                iwn_set_led(sc, IWN_LED_LINK, 5, 5);
                   4965:                return 0;
                   4966:        }
1.33      christos 4967:        if ((error = iwn_set_timing(sc, ni)) != 0) {
1.40      christos 4968:                aprint_error_dev(sc->sc_dev,
                   4969:                    "could not set timing\n");
1.33      christos 4970:                return error;
                   4971:        }
1.1       ober     4972:
1.40      christos 4973:        /* Update adapter configuration. */
1.33      christos 4974:        sc->rxon.associd = htole16(IEEE80211_AID(ni->ni_associd));
                   4975:        /* Short preamble and slot time are negotiated when associating. */
                   4976:        sc->rxon.flags &= ~htole32(IWN_RXON_SHPREAMBLE | IWN_RXON_SHSLOT);
1.1       ober     4977:        if (ic->ic_flags & IEEE80211_F_SHSLOT)
1.33      christos 4978:                sc->rxon.flags |= htole32(IWN_RXON_SHSLOT);
1.1       ober     4979:        if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)
1.33      christos 4980:                sc->rxon.flags |= htole32(IWN_RXON_SHPREAMBLE);
                   4981:        sc->rxon.filter |= htole32(IWN_FILTER_BSS);
                   4982:        DPRINTF(("rxon chan %d flags %x\n", sc->rxon.chan, sc->rxon.flags));
1.53      christos 4983:        error = iwn_cmd(sc, IWN_CMD_RXON, &sc->rxon, sc->rxonsz, 1);
1.1       ober     4984:        if (error != 0) {
1.11      blymn    4985:                aprint_error_dev(sc->sc_dev,
1.33      christos 4986:                    "could not update configuration\n");
1.1       ober     4987:                return error;
                   4988:        }
                   4989:
1.33      christos 4990:        /* Configuration has changed, set TX power accordingly. */
1.53      christos 4991:        if ((error = ops->set_txpower(sc, 1)) != 0) {
1.40      christos 4992:                aprint_error_dev(sc->sc_dev,
                   4993:                    "could not set TX power\n");
1.1       ober     4994:                return error;
                   4995:        }
                   4996:
1.33      christos 4997:        /* Fake a join to initialize the TX rate. */
                   4998:        ((struct iwn_node *)ni)->id = IWN_ID_BSS;
                   4999:        iwn_newassoc(ni, 1);
                   5000:
                   5001:        /* Add BSS node. */
1.40      christos 5002:        memset(&node, 0, sizeof node);
                   5003:        IEEE80211_ADDR_COPY(node.macaddr, ni->ni_macaddr);
                   5004:        node.id = IWN_ID_BSS;
                   5005: #ifdef notyet
                   5006:        node.htflags = htole32(IWN_AMDPU_SIZE_FACTOR(3) |
                   5007:            IWN_AMDPU_DENSITY(5));      /* 2us */
                   5008: #endif
                   5009:        DPRINTF(("adding BSS node\n"));
1.53      christos 5010:        error = ops->add_node(sc, &node, 1);
1.40      christos 5011:        if (error != 0) {
                   5012:                aprint_error_dev(sc->sc_dev,
                   5013:                    "could not add BSS node\n");
                   5014:                return error;
                   5015:        }
                   5016:        DPRINTF(("setting link quality for node %d\n", node.id));
                   5017:        if ((error = iwn_set_link_quality(sc, ni)) != 0) {
                   5018:                aprint_error_dev(sc->sc_dev,
                   5019:                    "could not setup link quality for node %d\n", node.id);
                   5020:                return error;
                   5021:        }
                   5022:
                   5023:        if ((error = iwn_init_sensitivity(sc)) != 0) {
                   5024:                aprint_error_dev(sc->sc_dev,
                   5025:                    "could not set sensitivity\n");
                   5026:                return error;
                   5027:        }
1.33      christos 5028:        /* Start periodic calibration timer. */
                   5029:        sc->calib.state = IWN_CALIB_STATE_ASSOC;
                   5030:        sc->calib_cnt = 0;
1.40      christos 5031:        callout_schedule(&sc->calib_to, hz/2);
1.33      christos 5032:
                   5033:        /* Link LED always on while associated. */
                   5034:        iwn_set_led(sc, IWN_LED_LINK, 0, 1);
                   5035:        return 0;
                   5036: }
                   5037:
1.40      christos 5038: #ifdef IWN_HWCRYPTO
1.33      christos 5039: /*
                   5040:  * We support CCMP hardware encryption/decryption of unicast frames only.
                   5041:  * HW support for TKIP really sucks.  We should let TKIP die anyway.
                   5042:  */
                   5043: static int
                   5044: iwn_set_key(struct ieee80211com *ic, struct ieee80211_node *ni,
                   5045:     struct ieee80211_key *k)
                   5046: {
                   5047:        struct iwn_softc *sc = ic->ic_softc;
1.53      christos 5048:        struct iwn_ops *ops = &sc->ops;
1.33      christos 5049:        struct iwn_node *wn = (void *)ni;
                   5050:        struct iwn_node_info node;
                   5051:        uint16_t kflags;
                   5052:
                   5053:        if ((k->k_flags & IEEE80211_KEY_GROUP) ||
                   5054:            k->k_cipher != IEEE80211_CIPHER_CCMP)
                   5055:                return ieee80211_set_key(ic, ni, k);
                   5056:
                   5057:        kflags = IWN_KFLAG_CCMP | IWN_KFLAG_MAP | IWN_KFLAG_KID(k->k_id);
                   5058:        if (k->k_flags & IEEE80211_KEY_GROUP)
                   5059:                kflags |= IWN_KFLAG_GROUP;
                   5060:
                   5061:        memset(&node, 0, sizeof node);
                   5062:        node.id = (k->k_flags & IEEE80211_KEY_GROUP) ?
1.53      christos 5063:            sc->broadcast_id : wn->id;
1.33      christos 5064:        node.control = IWN_NODE_UPDATE;
                   5065:        node.flags = IWN_FLAG_SET_KEY;
                   5066:        node.kflags = htole16(kflags);
                   5067:        node.kid = k->k_id;
                   5068:        memcpy(node.key, k->k_key, k->k_len);
                   5069:        DPRINTF(("set key id=%d for node %d\n", k->k_id, node.id));
1.53      christos 5070:        return ops->add_node(sc, &node, 1);
1.33      christos 5071: }
                   5072:
                   5073: static void
                   5074: iwn_delete_key(struct ieee80211com *ic, struct ieee80211_node *ni,
                   5075:     struct ieee80211_key *k)
                   5076: {
                   5077:        struct iwn_softc *sc = ic->ic_softc;
1.53      christos 5078:        struct iwn_ops *ops = &sc->ops;
1.33      christos 5079:        struct iwn_node *wn = (void *)ni;
                   5080:        struct iwn_node_info node;
1.1       ober     5081:
1.33      christos 5082:        if ((k->k_flags & IEEE80211_KEY_GROUP) ||
                   5083:            k->k_cipher != IEEE80211_CIPHER_CCMP) {
                   5084:                /* See comment about other ciphers above. */
                   5085:                ieee80211_delete_key(ic, ni, k);
                   5086:                return;
1.1       ober     5087:        }
1.33      christos 5088:        if (ic->ic_state != IEEE80211_S_RUN)
                   5089:                return; /* Nothing to do. */
                   5090:        memset(&node, 0, sizeof node);
                   5091:        node.id = (k->k_flags & IEEE80211_KEY_GROUP) ?
1.53      christos 5092:            sc->broadcast_id : wn->id;
1.33      christos 5093:        node.control = IWN_NODE_UPDATE;
                   5094:        node.flags = IWN_FLAG_SET_KEY;
                   5095:        node.kflags = htole16(IWN_KFLAG_INVALID);
                   5096:        node.kid = 0xff;
                   5097:        DPRINTF(("delete keys for node %d\n", node.id));
1.53      christos 5098:        (void)ops->add_node(sc, &node, 1);
1.33      christos 5099: }
                   5100: #endif
                   5101:
1.44      christos 5102: /* XXX Added for NetBSD (copied from rev 1.39). */
1.40      christos 5103:
                   5104: static int
                   5105: iwn_wme_update(struct ieee80211com *ic)
                   5106: {
                   5107: #define IWN_EXP2(v)    htole16((1 << (v)) - 1)
                   5108: #define IWN_USEC(v)    htole16(IEEE80211_TXOP_TO_US(v))
                   5109:        struct iwn_softc *sc = ic->ic_ifp->if_softc;
                   5110:        const struct wmeParams *wmep;
                   5111:        struct iwn_edca_params cmd;
                   5112:        int ac;
                   5113:
                   5114:        /* don't override default WME values if WME is not actually enabled */
                   5115:        if (!(ic->ic_flags & IEEE80211_F_WME))
                   5116:                return 0;
                   5117:        cmd.flags = 0;
                   5118:        for (ac = 0; ac < WME_NUM_AC; ac++) {
                   5119:                wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[ac];
                   5120:                cmd.ac[ac].aifsn = wmep->wmep_aifsn;
                   5121:                cmd.ac[ac].cwmin = IWN_EXP2(wmep->wmep_logcwmin);
                   5122:                cmd.ac[ac].cwmax = IWN_EXP2(wmep->wmep_logcwmax);
                   5123:                cmd.ac[ac].txoplimit  = IWN_USEC(wmep->wmep_txopLimit);
                   5124:
                   5125:                DPRINTF(("setting WME for queue %d aifsn=%d cwmin=%d cwmax=%d "
                   5126:                                        "txop=%d\n", ac, cmd.ac[ac].aifsn,
                   5127:                                        cmd.ac[ac].cwmin,
                   5128:                                        cmd.ac[ac].cwmax, cmd.ac[ac].txoplimit));
                   5129:        }
                   5130:        return iwn_cmd(sc, IWN_CMD_EDCA_PARAMS, &cmd, sizeof cmd, 1);
                   5131: #undef IWN_USEC
                   5132: #undef IWN_EXP2
                   5133: }
                   5134:
1.33      christos 5135: #ifndef IEEE80211_NO_HT
                   5136: /*
1.40      christos 5137:  * This function is called by upper layer when an ADDBA request is received
1.33      christos 5138:  * from another STA and before the ADDBA response is sent.
                   5139:  */
                   5140: static int
                   5141: iwn_ampdu_rx_start(struct ieee80211com *ic, struct ieee80211_node *ni,
1.40      christos 5142:     uint8_t tid)
1.33      christos 5143: {
1.40      christos 5144:        struct ieee80211_rx_ba *ba = &ni->ni_rx_ba[tid];
1.33      christos 5145:        struct iwn_softc *sc = ic->ic_softc;
1.53      christos 5146:        struct iwn_ops *ops = &sc->ops;
1.33      christos 5147:        struct iwn_node *wn = (void *)ni;
                   5148:        struct iwn_node_info node;
                   5149:
                   5150:        memset(&node, 0, sizeof node);
                   5151:        node.id = wn->id;
                   5152:        node.control = IWN_NODE_UPDATE;
                   5153:        node.flags = IWN_FLAG_SET_ADDBA;
                   5154:        node.addba_tid = tid;
1.40      christos 5155:        node.addba_ssn = htole16(ba->ba_winstart);
                   5156:        DPRINTFN(2, ("ADDBA RA=%d TID=%d SSN=%d\n", wn->id, tid,
                   5157:            ba->ba_winstart));
1.53      christos 5158:        return ops->add_node(sc, &node, 1);
1.33      christos 5159: }
                   5160:
                   5161: /*
                   5162:  * This function is called by upper layer on teardown of an HT-immediate
1.53      christos 5163:  * Block Ack agreement (eg. uppon receipt of a DELBA frame).
1.33      christos 5164:  */
                   5165: static void
                   5166: iwn_ampdu_rx_stop(struct ieee80211com *ic, struct ieee80211_node *ni,
1.40      christos 5167:     uint8_t tid)
1.33      christos 5168: {
                   5169:        struct iwn_softc *sc = ic->ic_softc;
1.53      christos 5170:        struct iwn_ops *ops = &sc->ops;
1.33      christos 5171:        struct iwn_node *wn = (void *)ni;
                   5172:        struct iwn_node_info node;
1.1       ober     5173:
1.33      christos 5174:        memset(&node, 0, sizeof node);
                   5175:        node.id = wn->id;
                   5176:        node.control = IWN_NODE_UPDATE;
                   5177:        node.flags = IWN_FLAG_SET_DELBA;
                   5178:        node.delba_tid = tid;
                   5179:        DPRINTFN(2, ("DELBA RA=%d TID=%d\n", wn->id, tid));
1.53      christos 5180:        (void)ops->add_node(sc, &node, 1);
1.33      christos 5181: }
                   5182:
                   5183: /*
1.40      christos 5184:  * This function is called by upper layer when an ADDBA response is received
1.33      christos 5185:  * from another STA.
                   5186:  */
                   5187: static int
                   5188: iwn_ampdu_tx_start(struct ieee80211com *ic, struct ieee80211_node *ni,
1.40      christos 5189:     uint8_t tid)
1.33      christos 5190: {
1.40      christos 5191:        struct ieee80211_tx_ba *ba = &ni->ni_tx_ba[tid];
1.33      christos 5192:        struct iwn_softc *sc = ic->ic_softc;
1.53      christos 5193:        struct iwn_ops *ops = &sc->ops;
1.33      christos 5194:        struct iwn_node *wn = (void *)ni;
                   5195:        struct iwn_node_info node;
                   5196:        int error;
                   5197:
                   5198:        /* Enable TX for the specified RA/TID. */
                   5199:        wn->disable_tid &= ~(1 << tid);
                   5200:        memset(&node, 0, sizeof node);
                   5201:        node.id = wn->id;
                   5202:        node.control = IWN_NODE_UPDATE;
                   5203:        node.flags = IWN_FLAG_SET_DISABLE_TID;
                   5204:        node.disable_tid = htole16(wn->disable_tid);
1.53      christos 5205:        error = ops->add_node(sc, &node, 1);
1.33      christos 5206:        if (error != 0)
                   5207:                return error;
                   5208:
                   5209:        if ((error = iwn_nic_lock(sc)) != 0)
                   5210:                return error;
1.53      christos 5211:        ops->ampdu_tx_start(sc, ni, tid, ba->ba_winstart);
1.33      christos 5212:        iwn_nic_unlock(sc);
                   5213:        return 0;
                   5214: }
                   5215:
                   5216: static void
                   5217: iwn_ampdu_tx_stop(struct ieee80211com *ic, struct ieee80211_node *ni,
1.40      christos 5218:     uint8_t tid)
1.33      christos 5219: {
1.40      christos 5220:        struct ieee80211_tx_ba *ba = &ni->ni_tx_ba[tid];
1.33      christos 5221:        struct iwn_softc *sc = ic->ic_softc;
1.53      christos 5222:        struct iwn_ops *ops = &sc->ops;
1.33      christos 5223:
                   5224:        if (iwn_nic_lock(sc) != 0)
                   5225:                return;
1.53      christos 5226:        ops->ampdu_tx_stop(sc, tid, ba->ba_winstart);
1.33      christos 5227:        iwn_nic_unlock(sc);
                   5228: }
                   5229:
                   5230: static void
                   5231: iwn4965_ampdu_tx_start(struct iwn_softc *sc, struct ieee80211_node *ni,
                   5232:     uint8_t tid, uint16_t ssn)
                   5233: {
                   5234:        struct iwn_node *wn = (void *)ni;
                   5235:        int qid = 7 + tid;
                   5236:
                   5237:        /* Stop TX scheduler while we're changing its configuration. */
                   5238:        iwn_prph_write(sc, IWN4965_SCHED_QUEUE_STATUS(qid),
                   5239:            IWN4965_TXQ_STATUS_CHGACT);
                   5240:
                   5241:        /* Assign RA/TID translation to the queue. */
                   5242:        iwn_mem_write_2(sc, sc->sched_base + IWN4965_SCHED_TRANS_TBL(qid),
                   5243:            wn->id << 4 | tid);
                   5244:
1.40      christos 5245:        /* Enable chain-building mode for the queue. */
1.33      christos 5246:        iwn_prph_setbits(sc, IWN4965_SCHED_QCHAIN_SEL, 1 << qid);
                   5247:
                   5248:        /* Set starting sequence number from the ADDBA request. */
1.40      christos 5249:        IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, qid << 8 | (ssn & 0xff));
1.33      christos 5250:        iwn_prph_write(sc, IWN4965_SCHED_QUEUE_RDPTR(qid), ssn);
                   5251:
                   5252:        /* Set scheduler window size. */
                   5253:        iwn_mem_write(sc, sc->sched_base + IWN4965_SCHED_QUEUE_OFFSET(qid),
                   5254:            IWN_SCHED_WINSZ);
                   5255:        /* Set scheduler frame limit. */
                   5256:        iwn_mem_write(sc, sc->sched_base + IWN4965_SCHED_QUEUE_OFFSET(qid) + 4,
                   5257:            IWN_SCHED_LIMIT << 16);
                   5258:
                   5259:        /* Enable interrupts for the queue. */
                   5260:        iwn_prph_setbits(sc, IWN4965_SCHED_INTR_MASK, 1 << qid);
                   5261:
                   5262:        /* Mark the queue as active. */
                   5263:        iwn_prph_write(sc, IWN4965_SCHED_QUEUE_STATUS(qid),
                   5264:            IWN4965_TXQ_STATUS_ACTIVE | IWN4965_TXQ_STATUS_AGGR_ENA |
                   5265:            iwn_tid2fifo[tid] << 1);
                   5266: }
                   5267:
                   5268: static void
                   5269: iwn4965_ampdu_tx_stop(struct iwn_softc *sc, uint8_t tid, uint16_t ssn)
                   5270: {
                   5271:        int qid = 7 + tid;
                   5272:
                   5273:        /* Stop TX scheduler while we're changing its configuration. */
                   5274:        iwn_prph_write(sc, IWN4965_SCHED_QUEUE_STATUS(qid),
                   5275:            IWN4965_TXQ_STATUS_CHGACT);
                   5276:
                   5277:        /* Set starting sequence number from the ADDBA request. */
1.40      christos 5278:        IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, qid << 8 | (ssn & 0xff));
1.33      christos 5279:        iwn_prph_write(sc, IWN4965_SCHED_QUEUE_RDPTR(qid), ssn);
                   5280:
                   5281:        /* Disable interrupts for the queue. */
                   5282:        iwn_prph_clrbits(sc, IWN4965_SCHED_INTR_MASK, 1 << qid);
                   5283:
                   5284:        /* Mark the queue as inactive. */
                   5285:        iwn_prph_write(sc, IWN4965_SCHED_QUEUE_STATUS(qid),
                   5286:            IWN4965_TXQ_STATUS_INACTIVE | iwn_tid2fifo[tid] << 1);
                   5287: }
                   5288:
                   5289: static void
                   5290: iwn5000_ampdu_tx_start(struct iwn_softc *sc, struct ieee80211_node *ni,
                   5291:     uint8_t tid, uint16_t ssn)
                   5292: {
                   5293:        struct iwn_node *wn = (void *)ni;
                   5294:        int qid = 10 + tid;
                   5295:
                   5296:        /* Stop TX scheduler while we're changing its configuration. */
                   5297:        iwn_prph_write(sc, IWN5000_SCHED_QUEUE_STATUS(qid),
                   5298:            IWN5000_TXQ_STATUS_CHGACT);
                   5299:
                   5300:        /* Assign RA/TID translation to the queue. */
                   5301:        iwn_mem_write_2(sc, sc->sched_base + IWN5000_SCHED_TRANS_TBL(qid),
                   5302:            wn->id << 4 | tid);
                   5303:
1.40      christos 5304:        /* Enable chain-building mode for the queue. */
1.33      christos 5305:        iwn_prph_setbits(sc, IWN5000_SCHED_QCHAIN_SEL, 1 << qid);
                   5306:
                   5307:        /* Enable aggregation for the queue. */
                   5308:        iwn_prph_setbits(sc, IWN5000_SCHED_AGGR_SEL, 1 << qid);
                   5309:
                   5310:        /* Set starting sequence number from the ADDBA request. */
1.40      christos 5311:        IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, qid << 8 | (ssn & 0xff));
1.33      christos 5312:        iwn_prph_write(sc, IWN5000_SCHED_QUEUE_RDPTR(qid), ssn);
                   5313:
                   5314:        /* Set scheduler window size and frame limit. */
                   5315:        iwn_mem_write(sc, sc->sched_base + IWN5000_SCHED_QUEUE_OFFSET(qid) + 4,
                   5316:            IWN_SCHED_LIMIT << 16 | IWN_SCHED_WINSZ);
                   5317:
                   5318:        /* Enable interrupts for the queue. */
                   5319:        iwn_prph_setbits(sc, IWN5000_SCHED_INTR_MASK, 1 << qid);
                   5320:
                   5321:        /* Mark the queue as active. */
                   5322:        iwn_prph_write(sc, IWN5000_SCHED_QUEUE_STATUS(qid),
                   5323:            IWN5000_TXQ_STATUS_ACTIVE | iwn_tid2fifo[tid]);
                   5324: }
                   5325:
                   5326: static void
                   5327: iwn5000_ampdu_tx_stop(struct iwn_softc *sc, uint8_t tid, uint16_t ssn)
                   5328: {
                   5329:        int qid = 10 + tid;
                   5330:
                   5331:        /* Stop TX scheduler while we're changing its configuration. */
                   5332:        iwn_prph_write(sc, IWN5000_SCHED_QUEUE_STATUS(qid),
                   5333:            IWN5000_TXQ_STATUS_CHGACT);
                   5334:
                   5335:        /* Disable aggregation for the queue. */
                   5336:        iwn_prph_clrbits(sc, IWN5000_SCHED_AGGR_SEL, 1 << qid);
                   5337:
                   5338:        /* Set starting sequence number from the ADDBA request. */
1.40      christos 5339:        IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, qid << 8 | (ssn & 0xff));
1.33      christos 5340:        iwn_prph_write(sc, IWN5000_SCHED_QUEUE_RDPTR(qid), ssn);
                   5341:
                   5342:        /* Disable interrupts for the queue. */
                   5343:        iwn_prph_clrbits(sc, IWN5000_SCHED_INTR_MASK, 1 << qid);
                   5344:
                   5345:        /* Mark the queue as inactive. */
                   5346:        iwn_prph_write(sc, IWN5000_SCHED_QUEUE_STATUS(qid),
                   5347:            IWN5000_TXQ_STATUS_INACTIVE | iwn_tid2fifo[tid]);
                   5348: }
1.40      christos 5349: #endif /* !IEEE80211_NO_HT */
1.33      christos 5350:
                   5351: /*
                   5352:  * Query calibration tables from the initialization firmware.  We do this
                   5353:  * only once at first boot.  Called from a process context.
                   5354:  */
                   5355: static int
                   5356: iwn5000_query_calibration(struct iwn_softc *sc)
                   5357: {
                   5358:        struct iwn5000_calib_config cmd;
                   5359:        int error;
                   5360:
                   5361:        memset(&cmd, 0, sizeof cmd);
                   5362:        cmd.ucode.once.enable = 0xffffffff;
                   5363:        cmd.ucode.once.start  = 0xffffffff;
                   5364:        cmd.ucode.once.send   = 0xffffffff;
                   5365:        cmd.ucode.flags       = 0xffffffff;
                   5366:        DPRINTF(("sending calibration query\n"));
                   5367:        error = iwn_cmd(sc, IWN5000_CMD_CALIB_CONFIG, &cmd, sizeof cmd, 0);
                   5368:        if (error != 0)
1.1       ober     5369:                return error;
                   5370:
1.33      christos 5371:        /* Wait at most two seconds for calibration to complete. */
1.40      christos 5372:        if (!(sc->sc_flags & IWN_FLAG_CALIB_DONE))
                   5373:                error = tsleep(sc, PCATCH, "iwncal", 2 * hz);
                   5374:        return error;
1.33      christos 5375: }
                   5376:
                   5377: /*
                   5378:  * Send calibration results to the runtime firmware.  These results were
                   5379:  * obtained on first boot from the initialization firmware.
                   5380:  */
                   5381: static int
                   5382: iwn5000_send_calibration(struct iwn_softc *sc)
                   5383: {
                   5384:        int idx, error;
1.1       ober     5385:
1.33      christos 5386:        for (idx = 0; idx < 5; idx++) {
                   5387:                if (sc->calibcmd[idx].buf == NULL)
                   5388:                        continue;       /* No results available. */
                   5389:                DPRINTF(("send calibration result idx=%d len=%d\n",
                   5390:                    idx, sc->calibcmd[idx].len));
                   5391:                error = iwn_cmd(sc, IWN_CMD_PHY_CALIB, sc->calibcmd[idx].buf,
                   5392:                    sc->calibcmd[idx].len, 0);
                   5393:                if (error != 0) {
1.11      blymn    5394:                        aprint_error_dev(sc->sc_dev,
1.33      christos 5395:                            "could not send calibration result\n");
1.11      blymn    5396:                        return error;
                   5397:                }
                   5398:        }
1.33      christos 5399:        return 0;
                   5400: }
                   5401:
1.40      christos 5402: static int
                   5403: iwn5000_send_wimax_coex(struct iwn_softc *sc)
                   5404: {
                   5405:        struct iwn5000_wimax_coex wimax;
                   5406:
                   5407: #ifdef notyet
                   5408:        if (sc->hw_type == IWN_HW_REV_TYPE_6050) {
                   5409:                /* Enable WiMAX coexistence for combo adapters. */
                   5410:                wimax.flags =
                   5411:                    IWN_WIMAX_COEX_ASSOC_WA_UNMASK |
                   5412:                    IWN_WIMAX_COEX_UNASSOC_WA_UNMASK |
                   5413:                    IWN_WIMAX_COEX_STA_TABLE_VALID |
                   5414:                    IWN_WIMAX_COEX_ENABLE;
                   5415:                memcpy(wimax.events, iwn6050_wimax_events,
                   5416:                    sizeof iwn6050_wimax_events);
                   5417:        } else
                   5418: #endif
                   5419:        {
                   5420:                /* Disable WiMAX coexistence. */
                   5421:                wimax.flags = 0;
                   5422:                memset(wimax.events, 0, sizeof wimax.events);
                   5423:        }
                   5424:        DPRINTF(("Configuring WiMAX coexistence\n"));
                   5425:        return iwn_cmd(sc, IWN5000_CMD_WIMAX_COEX, &wimax, sizeof wimax, 0);
                   5426: }
                   5427:
1.72      nonaka   5428: static int
                   5429: iwn6000_temp_offset_calib(struct iwn_softc *sc)
                   5430: {
                   5431:        struct iwn6000_phy_calib_temp_offset cmd;
                   5432:
                   5433:        memset(&cmd, 0, sizeof cmd);
                   5434:        cmd.code = IWN6000_PHY_CALIB_TEMP_OFFSET;
                   5435:        cmd.ngroups = 1;
                   5436:        cmd.isvalid = 1;
                   5437:        if (sc->eeprom_temp != 0)
                   5438:                cmd.offset = htole16(sc->eeprom_temp);
                   5439:        else
                   5440:                cmd.offset = htole16(IWN_DEFAULT_TEMP_OFFSET);
                   5441:        DPRINTF(("setting radio sensor offset to %d\n", le16toh(cmd.offset)));
                   5442:        return iwn_cmd(sc, IWN_CMD_PHY_CALIB, &cmd, sizeof cmd, 0);
                   5443: }
                   5444:
                   5445: static int
                   5446: iwn2000_temp_offset_calib(struct iwn_softc *sc)
                   5447: {
                   5448:        struct iwn2000_phy_calib_temp_offset cmd;
                   5449:
                   5450:        memset(&cmd, 0, sizeof cmd);
                   5451:        cmd.code = IWN2000_PHY_CALIB_TEMP_OFFSET;
                   5452:        cmd.ngroups = 1;
                   5453:        cmd.isvalid = 1;
                   5454:        if (sc->eeprom_rawtemp != 0) {
                   5455:                cmd.offset_low = htole16(sc->eeprom_rawtemp);
                   5456:                cmd.offset_high = htole16(sc->eeprom_temp);
                   5457:        } else {
                   5458:                cmd.offset_low = htole16(IWN_DEFAULT_TEMP_OFFSET);
                   5459:                cmd.offset_high = htole16(IWN_DEFAULT_TEMP_OFFSET);
                   5460:        }
                   5461:        cmd.burnt_voltage_ref = htole16(sc->eeprom_voltage);
                   5462:        DPRINTF(("setting radio sensor offset to %d:%d, voltage to %d\n",
                   5463:            le16toh(cmd.offset_low), le16toh(cmd.offset_high),
                   5464:            le16toh(cmd.burnt_voltage_ref)));
                   5465:        return iwn_cmd(sc, IWN_CMD_PHY_CALIB, &cmd, sizeof cmd, 0);
                   5466: }
                   5467:
1.33      christos 5468: /*
                   5469:  * This function is called after the runtime firmware notifies us of its
1.53      christos 5470:  * readiness (called in a process context).
1.33      christos 5471:  */
                   5472: static int
                   5473: iwn4965_post_alive(struct iwn_softc *sc)
                   5474: {
                   5475:        int error, qid;
1.11      blymn    5476:
1.33      christos 5477:        if ((error = iwn_nic_lock(sc)) != 0)
                   5478:                return error;
1.11      blymn    5479:
1.40      christos 5480:        /* Clear TX scheduler state in SRAM. */
1.33      christos 5481:        sc->sched_base = iwn_prph_read(sc, IWN_SCHED_SRAM_ADDR);
                   5482:        iwn_mem_set_region_4(sc, sc->sched_base + IWN4965_SCHED_CTX_OFF, 0,
1.40      christos 5483:            IWN4965_SCHED_CTX_LEN / sizeof (uint32_t));
1.33      christos 5484:
1.53      christos 5485:        /* Set physical address of TX scheduler rings (1KB aligned). */
1.33      christos 5486:        iwn_prph_write(sc, IWN4965_SCHED_DRAM_ADDR, sc->sched_dma.paddr >> 10);
                   5487:
                   5488:        IWN_SETBITS(sc, IWN_FH_TX_CHICKEN, IWN_FH_TX_CHICKEN_SCHED_RETRY);
                   5489:
                   5490:        /* Disable chain mode for all our 16 queues. */
                   5491:        iwn_prph_write(sc, IWN4965_SCHED_QCHAIN_SEL, 0);
                   5492:
                   5493:        for (qid = 0; qid < IWN4965_NTXQUEUES; qid++) {
                   5494:                iwn_prph_write(sc, IWN4965_SCHED_QUEUE_RDPTR(qid), 0);
                   5495:                IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, qid << 8 | 0);
                   5496:
                   5497:                /* Set scheduler window size. */
                   5498:                iwn_mem_write(sc, sc->sched_base +
                   5499:                    IWN4965_SCHED_QUEUE_OFFSET(qid), IWN_SCHED_WINSZ);
                   5500:                /* Set scheduler frame limit. */
                   5501:                iwn_mem_write(sc, sc->sched_base +
                   5502:                    IWN4965_SCHED_QUEUE_OFFSET(qid) + 4,
                   5503:                    IWN_SCHED_LIMIT << 16);
                   5504:        }
                   5505:
                   5506:        /* Enable interrupts for all our 16 queues. */
                   5507:        iwn_prph_write(sc, IWN4965_SCHED_INTR_MASK, 0xffff);
                   5508:        /* Identify TX FIFO rings (0-7). */
                   5509:        iwn_prph_write(sc, IWN4965_SCHED_TXFACT, 0xff);
1.1       ober     5510:
1.33      christos 5511:        /* Mark TX rings (4 EDCA + cmd + 2 HCCA) as active. */
                   5512:        for (qid = 0; qid < 7; qid++) {
                   5513:                static uint8_t qid2fifo[] = { 3, 2, 1, 0, 4, 5, 6 };
                   5514:                iwn_prph_write(sc, IWN4965_SCHED_QUEUE_STATUS(qid),
                   5515:                    IWN4965_TXQ_STATUS_ACTIVE | qid2fifo[qid] << 1);
                   5516:        }
                   5517:        iwn_nic_unlock(sc);
1.1       ober     5518:        return 0;
                   5519: }
                   5520:
                   5521: /*
1.33      christos 5522:  * This function is called after the initialization or runtime firmware
1.53      christos 5523:  * notifies us of its readiness (called in a process context).
1.1       ober     5524:  */
                   5525: static int
1.33      christos 5526: iwn5000_post_alive(struct iwn_softc *sc)
1.1       ober     5527: {
1.33      christos 5528:        int error, qid;
                   5529:
1.40      christos 5530:        /* Switch to using ICT interrupt mode. */
                   5531:        iwn5000_ict_reset(sc);
                   5532:
1.33      christos 5533:        if ((error = iwn_nic_lock(sc)) != 0)
                   5534:                return error;
1.1       ober     5535:
1.40      christos 5536:        /* Clear TX scheduler state in SRAM. */
1.33      christos 5537:        sc->sched_base = iwn_prph_read(sc, IWN_SCHED_SRAM_ADDR);
                   5538:        iwn_mem_set_region_4(sc, sc->sched_base + IWN5000_SCHED_CTX_OFF, 0,
1.40      christos 5539:            IWN5000_SCHED_CTX_LEN / sizeof (uint32_t));
1.33      christos 5540:
1.53      christos 5541:        /* Set physical address of TX scheduler rings (1KB aligned). */
1.33      christos 5542:        iwn_prph_write(sc, IWN5000_SCHED_DRAM_ADDR, sc->sched_dma.paddr >> 10);
                   5543:
                   5544:        IWN_SETBITS(sc, IWN_FH_TX_CHICKEN, IWN_FH_TX_CHICKEN_SCHED_RETRY);
                   5545:
1.40      christos 5546:        /* Enable chain mode for all queues, except command queue. */
                   5547:        iwn_prph_write(sc, IWN5000_SCHED_QCHAIN_SEL, 0xfffef);
1.33      christos 5548:        iwn_prph_write(sc, IWN5000_SCHED_AGGR_SEL, 0);
                   5549:
                   5550:        for (qid = 0; qid < IWN5000_NTXQUEUES; qid++) {
                   5551:                iwn_prph_write(sc, IWN5000_SCHED_QUEUE_RDPTR(qid), 0);
                   5552:                IWN_WRITE(sc, IWN_HBUS_TARG_WRPTR, qid << 8 | 0);
                   5553:
                   5554:                iwn_mem_write(sc, sc->sched_base +
                   5555:                    IWN5000_SCHED_QUEUE_OFFSET(qid), 0);
                   5556:                /* Set scheduler window size and frame limit. */
                   5557:                iwn_mem_write(sc, sc->sched_base +
                   5558:                    IWN5000_SCHED_QUEUE_OFFSET(qid) + 4,
                   5559:                    IWN_SCHED_LIMIT << 16 | IWN_SCHED_WINSZ);
                   5560:        }
                   5561:
                   5562:        /* Enable interrupts for all our 20 queues. */
                   5563:        iwn_prph_write(sc, IWN5000_SCHED_INTR_MASK, 0xfffff);
                   5564:        /* Identify TX FIFO rings (0-7). */
                   5565:        iwn_prph_write(sc, IWN5000_SCHED_TXFACT, 0xff);
1.1       ober     5566:
1.33      christos 5567:        /* Mark TX rings (4 EDCA + cmd + 2 HCCA) as active. */
                   5568:        for (qid = 0; qid < 7; qid++) {
                   5569:                static uint8_t qid2fifo[] = { 3, 2, 1, 0, 7, 5, 6 };
                   5570:                iwn_prph_write(sc, IWN5000_SCHED_QUEUE_STATUS(qid),
                   5571:                    IWN5000_TXQ_STATUS_ACTIVE | qid2fifo[qid]);
                   5572:        }
                   5573:        iwn_nic_unlock(sc);
                   5574:
1.40      christos 5575:        /* Configure WiMAX coexistence for combo adapters. */
                   5576:        error = iwn5000_send_wimax_coex(sc);
1.33      christos 5577:        if (error != 0) {
                   5578:                aprint_error_dev(sc->sc_dev,
                   5579:                    "could not configure WiMAX coexistence\n");
                   5580:                return error;
1.1       ober     5581:        }
1.33      christos 5582:        if (sc->hw_type != IWN_HW_REV_TYPE_5150) {
                   5583:                struct iwn5000_phy_calib_crystal cmd;
                   5584:
                   5585:                /* Perform crystal calibration. */
                   5586:                memset(&cmd, 0, sizeof cmd);
                   5587:                cmd.code = IWN5000_PHY_CALIB_CRYSTAL;
                   5588:                cmd.ngroups = 1;
                   5589:                cmd.isvalid = 1;
                   5590:                cmd.cap_pin[0] = le32toh(sc->eeprom_crystal) & 0xff;
                   5591:                cmd.cap_pin[1] = (le32toh(sc->eeprom_crystal) >> 16) & 0xff;
                   5592:                DPRINTF(("sending crystal calibration %d, %d\n",
                   5593:                    cmd.cap_pin[0], cmd.cap_pin[1]));
                   5594:                error = iwn_cmd(sc, IWN_CMD_PHY_CALIB, &cmd, sizeof cmd, 0);
                   5595:                if (error != 0) {
                   5596:                        aprint_error_dev(sc->sc_dev,
                   5597:                            "crystal calibration failed\n");
                   5598:                        return error;
                   5599:                }
                   5600:        }
1.40      christos 5601:        if (!(sc->sc_flags & IWN_FLAG_CALIB_DONE)) {
1.33      christos 5602:                /* Query calibration from the initialization firmware. */
                   5603:                if ((error = iwn5000_query_calibration(sc)) != 0) {
                   5604:                        aprint_error_dev(sc->sc_dev,
                   5605:                            "could not query calibration\n");
                   5606:                        return error;
                   5607:                }
                   5608:                /*
1.40      christos 5609:                 * We have the calibration results now, reboot with the
                   5610:                 * runtime firmware (call ourselves recursively!)
1.33      christos 5611:                 */
                   5612:                iwn_hw_stop(sc);
                   5613:                error = iwn_hw_init(sc);
                   5614:        } else {
                   5615:                /* Send calibration results to runtime firmware. */
                   5616:                error = iwn5000_send_calibration(sc);
1.1       ober     5617:        }
1.33      christos 5618:        return error;
                   5619: }
                   5620:
                   5621: /*
                   5622:  * The firmware boot code is small and is intended to be copied directly into
1.53      christos 5623:  * the NIC internal memory (no DMA transfer).
1.33      christos 5624:  */
                   5625: static int
                   5626: iwn4965_load_bootcode(struct iwn_softc *sc, const uint8_t *ucode, int size)
                   5627: {
                   5628:        int error, ntries;
                   5629:
                   5630:        size /= sizeof (uint32_t);
1.1       ober     5631:
1.33      christos 5632:        if ((error = iwn_nic_lock(sc)) != 0)
                   5633:                return error;
1.1       ober     5634:
1.33      christos 5635:        /* Copy microcode image into NIC memory. */
                   5636:        iwn_prph_write_region_4(sc, IWN_BSM_SRAM_BASE,
                   5637:            (const uint32_t *)ucode, size);
1.1       ober     5638:
1.33      christos 5639:        iwn_prph_write(sc, IWN_BSM_WR_MEM_SRC, 0);
                   5640:        iwn_prph_write(sc, IWN_BSM_WR_MEM_DST, IWN_FW_TEXT_BASE);
                   5641:        iwn_prph_write(sc, IWN_BSM_WR_DWCOUNT, size);
1.1       ober     5642:
1.33      christos 5643:        /* Start boot load now. */
                   5644:        iwn_prph_write(sc, IWN_BSM_WR_CTRL, IWN_BSM_WR_CTRL_START);
1.1       ober     5645:
1.33      christos 5646:        /* Wait for transfer to complete. */
                   5647:        for (ntries = 0; ntries < 1000; ntries++) {
                   5648:                if (!(iwn_prph_read(sc, IWN_BSM_WR_CTRL) &
                   5649:                    IWN_BSM_WR_CTRL_START))
                   5650:                        break;
                   5651:                DELAY(10);
                   5652:        }
                   5653:        if (ntries == 1000) {
1.40      christos 5654:                aprint_error_dev(sc->sc_dev,
                   5655:                    "could not load boot firmware\n");
1.33      christos 5656:                iwn_nic_unlock(sc);
                   5657:                return ETIMEDOUT;
1.1       ober     5658:        }
                   5659:
1.33      christos 5660:        /* Enable boot after power up. */
                   5661:        iwn_prph_write(sc, IWN_BSM_WR_CTRL, IWN_BSM_WR_CTRL_START_EN);
1.1       ober     5662:
1.33      christos 5663:        iwn_nic_unlock(sc);
                   5664:        return 0;
                   5665: }
1.1       ober     5666:
1.33      christos 5667: static int
                   5668: iwn4965_load_firmware(struct iwn_softc *sc)
                   5669: {
                   5670:        struct iwn_fw_info *fw = &sc->fw;
                   5671:        struct iwn_dma_info *dma = &sc->fw_dma;
                   5672:        int error;
1.1       ober     5673:
1.33      christos 5674:        /* Copy initialization sections into pre-allocated DMA-safe memory. */
                   5675:        memcpy(dma->vaddr, fw->init.data, fw->init.datasz);
                   5676:        bus_dmamap_sync(sc->sc_dmat, dma->map, 0, fw->init.datasz,
                   5677:            BUS_DMASYNC_PREWRITE);
                   5678:        memcpy((char *)dma->vaddr + IWN4965_FW_DATA_MAXSZ,
                   5679:            fw->init.text, fw->init.textsz);
                   5680:        bus_dmamap_sync(sc->sc_dmat, dma->map, IWN4965_FW_DATA_MAXSZ,
                   5681:            fw->init.textsz, BUS_DMASYNC_PREWRITE);
1.1       ober     5682:
1.33      christos 5683:        /* Tell adapter where to find initialization sections. */
                   5684:        if ((error = iwn_nic_lock(sc)) != 0)
                   5685:                return error;
                   5686:        iwn_prph_write(sc, IWN_BSM_DRAM_DATA_ADDR, dma->paddr >> 4);
                   5687:        iwn_prph_write(sc, IWN_BSM_DRAM_DATA_SIZE, fw->init.datasz);
                   5688:        iwn_prph_write(sc, IWN_BSM_DRAM_TEXT_ADDR,
                   5689:            (dma->paddr + IWN4965_FW_DATA_MAXSZ) >> 4);
                   5690:        iwn_prph_write(sc, IWN_BSM_DRAM_TEXT_SIZE, fw->init.textsz);
                   5691:        iwn_nic_unlock(sc);
1.1       ober     5692:
1.33      christos 5693:        /* Load firmware boot code. */
                   5694:        error = iwn4965_load_bootcode(sc, fw->boot.text, fw->boot.textsz);
                   5695:        if (error != 0) {
1.40      christos 5696:                aprint_error_dev(sc->sc_dev,
                   5697:                    "could not load boot firmware\n");
1.33      christos 5698:                return error;
                   5699:        }
                   5700:        /* Now press "execute". */
                   5701:        IWN_WRITE(sc, IWN_RESET, 0);
1.1       ober     5702:
1.33      christos 5703:        /* Wait at most one second for first alive notification. */
                   5704:        if ((error = tsleep(sc, PCATCH, "iwninit", hz)) != 0) {
                   5705:                aprint_error_dev(sc->sc_dev,
1.40      christos 5706:                    "timeout waiting for adapter to initialize\n");
1.33      christos 5707:                return error;
                   5708:        }
1.1       ober     5709:
1.33      christos 5710:        /* Retrieve current temperature for initial TX power calibration. */
                   5711:        sc->rawtemp = sc->ucode_info.temp[3].chan20MHz;
                   5712:        sc->temp = iwn4965_get_temperature(sc);
1.1       ober     5713:
1.33      christos 5714:        /* Copy runtime sections into pre-allocated DMA-safe memory. */
                   5715:        memcpy(dma->vaddr, fw->main.data, fw->main.datasz);
                   5716:        bus_dmamap_sync(sc->sc_dmat, dma->map, 0, fw->main.datasz,
                   5717:            BUS_DMASYNC_PREWRITE);
                   5718:        memcpy((char *)dma->vaddr + IWN4965_FW_DATA_MAXSZ,
                   5719:            fw->main.text, fw->main.textsz);
                   5720:        bus_dmamap_sync(sc->sc_dmat, dma->map, IWN4965_FW_DATA_MAXSZ,
                   5721:            fw->main.textsz, BUS_DMASYNC_PREWRITE);
1.1       ober     5722:
1.33      christos 5723:        /* Tell adapter where to find runtime sections. */
                   5724:        if ((error = iwn_nic_lock(sc)) != 0)
                   5725:                return error;
                   5726:        iwn_prph_write(sc, IWN_BSM_DRAM_DATA_ADDR, dma->paddr >> 4);
                   5727:        iwn_prph_write(sc, IWN_BSM_DRAM_DATA_SIZE, fw->main.datasz);
                   5728:        iwn_prph_write(sc, IWN_BSM_DRAM_TEXT_ADDR,
                   5729:            (dma->paddr + IWN4965_FW_DATA_MAXSZ) >> 4);
                   5730:        iwn_prph_write(sc, IWN_BSM_DRAM_TEXT_SIZE,
                   5731:            IWN_FW_UPDATED | fw->main.textsz);
                   5732:        iwn_nic_unlock(sc);
1.1       ober     5733:
1.33      christos 5734:        return 0;
                   5735: }
1.1       ober     5736:
1.33      christos 5737: static int
                   5738: iwn5000_load_firmware_section(struct iwn_softc *sc, uint32_t dst,
                   5739:     const uint8_t *section, int size)
                   5740: {
                   5741:        struct iwn_dma_info *dma = &sc->fw_dma;
                   5742:        int error;
1.1       ober     5743:
1.33      christos 5744:        /* Copy firmware section into pre-allocated DMA-safe memory. */
                   5745:        memcpy(dma->vaddr, section, size);
                   5746:        bus_dmamap_sync(sc->sc_dmat, dma->map, 0, size, BUS_DMASYNC_PREWRITE);
1.1       ober     5747:
1.33      christos 5748:        if ((error = iwn_nic_lock(sc)) != 0)
1.1       ober     5749:                return error;
                   5750:
1.40      christos 5751:        IWN_WRITE(sc, IWN_FH_TX_CONFIG(IWN_SRVC_DMACHNL),
1.33      christos 5752:            IWN_FH_TX_CONFIG_DMA_PAUSE);
1.1       ober     5753:
1.40      christos 5754:        IWN_WRITE(sc, IWN_FH_SRAM_ADDR(IWN_SRVC_DMACHNL), dst);
                   5755:        IWN_WRITE(sc, IWN_FH_TFBD_CTRL0(IWN_SRVC_DMACHNL),
1.33      christos 5756:            IWN_LOADDR(dma->paddr));
1.40      christos 5757:        IWN_WRITE(sc, IWN_FH_TFBD_CTRL1(IWN_SRVC_DMACHNL),
1.33      christos 5758:            IWN_HIADDR(dma->paddr) << 28 | size);
1.40      christos 5759:        IWN_WRITE(sc, IWN_FH_TXBUF_STATUS(IWN_SRVC_DMACHNL),
1.33      christos 5760:            IWN_FH_TXBUF_STATUS_TBNUM(1) |
                   5761:            IWN_FH_TXBUF_STATUS_TBIDX(1) |
                   5762:            IWN_FH_TXBUF_STATUS_TFBD_VALID);
                   5763:
                   5764:        /* Kick Flow Handler to start DMA transfer. */
1.40      christos 5765:        IWN_WRITE(sc, IWN_FH_TX_CONFIG(IWN_SRVC_DMACHNL),
1.33      christos 5766:            IWN_FH_TX_CONFIG_DMA_ENA | IWN_FH_TX_CONFIG_CIRQ_HOST_ENDTFD);
1.20      blymn    5767:
1.33      christos 5768:        iwn_nic_unlock(sc);
1.1       ober     5769:
1.33      christos 5770:        /* Wait at most five seconds for FH DMA transfer to complete. */
                   5771:        return tsleep(sc, PCATCH, "iwninit", 5 * hz);
1.1       ober     5772: }
                   5773:
                   5774: static int
1.33      christos 5775: iwn5000_load_firmware(struct iwn_softc *sc)
1.1       ober     5776: {
1.33      christos 5777:        struct iwn_fw_part *fw;
1.1       ober     5778:        int error;
                   5779:
1.33      christos 5780:        /* Load the initialization firmware on first boot only. */
1.40      christos 5781:        fw = (sc->sc_flags & IWN_FLAG_CALIB_DONE) ?
                   5782:            &sc->fw.main : &sc->fw.init;
1.33      christos 5783:
                   5784:        error = iwn5000_load_firmware_section(sc, IWN_FW_TEXT_BASE,
                   5785:            fw->text, fw->textsz);
                   5786:        if (error != 0) {
                   5787:                aprint_error_dev(sc->sc_dev,
1.40      christos 5788:                    "could not load firmware %s section\n", ".text");
1.33      christos 5789:                return error;
                   5790:        }
                   5791:        error = iwn5000_load_firmware_section(sc, IWN_FW_DATA_BASE,
                   5792:            fw->data, fw->datasz);
1.1       ober     5793:        if (error != 0) {
1.33      christos 5794:                aprint_error_dev(sc->sc_dev,
1.40      christos 5795:                    "could not load firmware %s section\n", ".data");
1.1       ober     5796:                return error;
                   5797:        }
                   5798:
1.33      christos 5799:        /* Now press "execute". */
                   5800:        IWN_WRITE(sc, IWN_RESET, 0);
                   5801:        return 0;
                   5802: }
                   5803:
1.46      christos 5804: /*
                   5805:  * Extract text and data sections from a legacy firmware image.
                   5806:  */
                   5807: static int
                   5808: iwn_read_firmware_leg(struct iwn_softc *sc, struct iwn_fw_info *fw)
                   5809: {
                   5810:        const uint32_t *ptr;
                   5811:        size_t hdrlen = 24;
                   5812:        uint32_t rev;
                   5813:
                   5814:        ptr = (const uint32_t *)fw->data;
                   5815:        rev = le32toh(*ptr++);
                   5816:
1.85      mlelstv  5817:        sc->ucode_rev = rev;
                   5818:
1.46      christos 5819:        /* Check firmware API version. */
                   5820:        if (IWN_FW_API(rev) <= 1) {
                   5821:                aprint_error_dev(sc->sc_dev,
                   5822:                    "bad firmware, need API version >=2\n");
                   5823:                return EINVAL;
                   5824:        }
                   5825:        if (IWN_FW_API(rev) >= 3) {
                   5826:                /* Skip build number (version 2 header). */
                   5827:                hdrlen += 4;
                   5828:                ptr++;
                   5829:        }
                   5830:        if (fw->size < hdrlen) {
                   5831:                aprint_error_dev(sc->sc_dev,
                   5832:                    "firmware too short: %zd bytes\n", fw->size);
                   5833:                return EINVAL;
                   5834:        }
                   5835:        fw->main.textsz = le32toh(*ptr++);
                   5836:        fw->main.datasz = le32toh(*ptr++);
                   5837:        fw->init.textsz = le32toh(*ptr++);
                   5838:        fw->init.datasz = le32toh(*ptr++);
                   5839:        fw->boot.textsz = le32toh(*ptr++);
                   5840:
                   5841:        /* Check that all firmware sections fit. */
                   5842:        if (fw->size < hdrlen + fw->main.textsz + fw->main.datasz +
                   5843:            fw->init.textsz + fw->init.datasz + fw->boot.textsz) {
                   5844:                aprint_error_dev(sc->sc_dev,
                   5845:                    "firmware too short: %zd bytes\n", fw->size);
                   5846:                return EINVAL;
                   5847:        }
                   5848:
                   5849:        /* Get pointers to firmware sections. */
                   5850:        fw->main.text = (const uint8_t *)ptr;
                   5851:        fw->main.data = fw->main.text + fw->main.textsz;
                   5852:        fw->init.text = fw->main.data + fw->main.datasz;
                   5853:        fw->init.data = fw->init.text + fw->init.textsz;
                   5854:        fw->boot.text = fw->init.data + fw->init.datasz;
                   5855:        return 0;
                   5856: }
                   5857:
                   5858: /*
                   5859:  * Extract text and data sections from a TLV firmware image.
                   5860:  */
                   5861: static int
                   5862: iwn_read_firmware_tlv(struct iwn_softc *sc, struct iwn_fw_info *fw,
                   5863:     uint16_t alt)
                   5864: {
                   5865:        const struct iwn_fw_tlv_hdr *hdr;
                   5866:        const struct iwn_fw_tlv *tlv;
                   5867:        const uint8_t *ptr, *end;
                   5868:        uint64_t altmask;
                   5869:        uint32_t len;
                   5870:
                   5871:        if (fw->size < sizeof (*hdr)) {
                   5872:                aprint_error_dev(sc->sc_dev,
                   5873:                    "firmware too short: %zd bytes\n", fw->size);
                   5874:                return EINVAL;
                   5875:        }
                   5876:        hdr = (const struct iwn_fw_tlv_hdr *)fw->data;
                   5877:        if (hdr->signature != htole32(IWN_FW_SIGNATURE)) {
                   5878:                aprint_error_dev(sc->sc_dev,
                   5879:                    "bad firmware signature 0x%08x\n", le32toh(hdr->signature));
                   5880:                return EINVAL;
                   5881:        }
                   5882:        DPRINTF(("FW: \"%.64s\", build 0x%x\n", hdr->descr,
                   5883:            le32toh(hdr->build)));
1.85      mlelstv  5884:        sc->ucode_rev = le32toh(hdr->rev);
1.46      christos 5885:
                   5886:        /*
                   5887:         * Select the closest supported alternative that is less than
                   5888:         * or equal to the specified one.
                   5889:         */
                   5890:        altmask = le64toh(hdr->altmask);
                   5891:        while (alt > 0 && !(altmask & (1ULL << alt)))
                   5892:                alt--;  /* Downgrade. */
                   5893:        DPRINTF(("using alternative %d\n", alt));
                   5894:
                   5895:        ptr = (const uint8_t *)(hdr + 1);
                   5896:        end = (const uint8_t *)(fw->data + fw->size);
                   5897:
                   5898:        /* Parse type-length-value fields. */
                   5899:        while (ptr + sizeof (*tlv) <= end) {
                   5900:                tlv = (const struct iwn_fw_tlv *)ptr;
                   5901:                len = le32toh(tlv->len);
                   5902:
                   5903:                ptr += sizeof (*tlv);
                   5904:                if (ptr + len > end) {
                   5905:                        aprint_error_dev(sc->sc_dev,
                   5906:                            "firmware too short: %zd bytes\n", fw->size);
                   5907:                        return EINVAL;
                   5908:                }
                   5909:                /* Skip other alternatives. */
                   5910:                if (tlv->alt != 0 && tlv->alt != htole16(alt))
                   5911:                        goto next;
                   5912:
                   5913:                switch (le16toh(tlv->type)) {
                   5914:                case IWN_FW_TLV_MAIN_TEXT:
                   5915:                        fw->main.text = ptr;
                   5916:                        fw->main.textsz = len;
                   5917:                        break;
                   5918:                case IWN_FW_TLV_MAIN_DATA:
                   5919:                        fw->main.data = ptr;
                   5920:                        fw->main.datasz = len;
                   5921:                        break;
                   5922:                case IWN_FW_TLV_INIT_TEXT:
                   5923:                        fw->init.text = ptr;
                   5924:                        fw->init.textsz = len;
                   5925:                        break;
                   5926:                case IWN_FW_TLV_INIT_DATA:
                   5927:                        fw->init.data = ptr;
                   5928:                        fw->init.datasz = len;
                   5929:                        break;
                   5930:                case IWN_FW_TLV_BOOT_TEXT:
                   5931:                        fw->boot.text = ptr;
                   5932:                        fw->boot.textsz = len;
                   5933:                        break;
1.72      nonaka   5934:                case IWN_FW_TLV_ENH_SENS:
                   5935:                        if (len != 0) {
                   5936:                                aprint_error_dev(sc->sc_dev,
                   5937:                                    "TLV type %d has invalid size %u\n",
                   5938:                                    le16toh(tlv->type), len);
                   5939:                                goto next;
                   5940:                        }
                   5941:                        sc->sc_flags |= IWN_FLAG_ENH_SENS;
                   5942:                        break;
                   5943:                case IWN_FW_TLV_PHY_CALIB:
                   5944:                        if (len != sizeof(uint32_t)) {
                   5945:                                aprint_error_dev(sc->sc_dev,
                   5946:                                    "TLV type %d has invalid size %u\n",
                   5947:                                    le16toh(tlv->type), len);
                   5948:                                goto next;
                   5949:                        }
                   5950:                        if (le32toh(*ptr) <= IWN5000_PHY_CALIB_MAX) {
                   5951:                                sc->reset_noise_gain = le32toh(*ptr);
                   5952:                                sc->noise_gain = le32toh(*ptr) + 1;
                   5953:                        }
                   5954:                        break;
                   5955:                case IWN_FW_TLV_FLAGS:
                   5956:                        if (len < sizeof(uint32_t))
                   5957:                                break;
                   5958:                        if (len % sizeof(uint32_t))
                   5959:                                break;
                   5960:                        sc->tlv_feature_flags = le32toh(*ptr);
                   5961:                        DPRINTF(("feature: 0x%08x\n", sc->tlv_feature_flags));
                   5962:                        break;
1.46      christos 5963:                default:
                   5964:                        DPRINTF(("TLV type %d not handled\n",
                   5965:                            le16toh(tlv->type)));
                   5966:                        break;
                   5967:                }
                   5968:  next:         /* TLV fields are 32-bit aligned. */
                   5969:                ptr += (len + 3) & ~3;
                   5970:        }
                   5971:        return 0;
                   5972: }
                   5973:
1.33      christos 5974: static int
                   5975: iwn_read_firmware(struct iwn_softc *sc)
                   5976: {
                   5977:        struct iwn_fw_info *fw = &sc->fw;
                   5978:        firmware_handle_t fwh;
                   5979:        int error;
                   5980:
1.72      nonaka   5981:        /*
                   5982:         * Some PHY calibration commands are firmware-dependent; these
                   5983:         * are the default values that will be overridden if
                   5984:         * necessary.
                   5985:         */
                   5986:        sc->reset_noise_gain = IWN5000_PHY_CALIB_RESET_NOISE_GAIN;
                   5987:        sc->noise_gain = IWN5000_PHY_CALIB_NOISE_GAIN;
                   5988:
1.42      christos 5989:        /* Initialize for error returns */
                   5990:        fw->data = NULL;
1.46      christos 5991:        fw->size = 0;
1.42      christos 5992:
1.40      christos 5993:        /* Open firmware image. */
1.33      christos 5994:        if ((error = firmware_open("if_iwn", sc->fwname, &fwh)) != 0) {
                   5995:                aprint_error_dev(sc->sc_dev,
1.40      christos 5996:                    "could not get firmware handle %s\n", sc->fwname);
1.1       ober     5997:                return error;
                   5998:        }
1.46      christos 5999:        fw->size = firmware_get_size(fwh);
                   6000:        if (fw->size < sizeof (uint32_t)) {
1.33      christos 6001:                aprint_error_dev(sc->sc_dev,
1.46      christos 6002:                    "firmware too short: %zd bytes\n", fw->size);
1.40      christos 6003:                firmware_close(fwh);
                   6004:                return EINVAL;
                   6005:        }
                   6006:
                   6007:        /* Read the firmware. */
1.46      christos 6008:        fw->data = firmware_malloc(fw->size);
1.40      christos 6009:        if (fw->data == NULL) {
                   6010:                aprint_error_dev(sc->sc_dev,
                   6011:                    "not enough memory to stock firmware %s\n", sc->fwname);
                   6012:                firmware_close(fwh);
                   6013:                return ENOMEM;
1.33      christos 6014:        }
1.46      christos 6015:        error = firmware_read(fwh, 0, fw->data, fw->size);
1.42      christos 6016:        firmware_close(fwh);
                   6017:        if (error != 0) {
1.40      christos 6018:                aprint_error_dev(sc->sc_dev,
                   6019:                    "could not read firmware %s\n", sc->fwname);
1.42      christos 6020:                goto out;
1.33      christos 6021:        }
1.40      christos 6022:
1.46      christos 6023:        /* Retrieve text and data sections. */
                   6024:        if (*(const uint32_t *)fw->data != 0)   /* Legacy image. */
                   6025:                error = iwn_read_firmware_leg(sc, fw);
                   6026:        else
                   6027:                error = iwn_read_firmware_tlv(sc, fw, 1);
                   6028:        if (error != 0) {
1.40      christos 6029:                aprint_error_dev(sc->sc_dev,
1.46      christos 6030:                    "could not read firmware sections\n");
1.42      christos 6031:                goto out;
1.40      christos 6032:        }
1.33      christos 6033:
1.46      christos 6034:        /* Make sure text and data sections fit in hardware memory. */
1.53      christos 6035:        if (fw->main.textsz > sc->fw_text_maxsz ||
                   6036:            fw->main.datasz > sc->fw_data_maxsz ||
                   6037:            fw->init.textsz > sc->fw_text_maxsz ||
                   6038:            fw->init.datasz > sc->fw_data_maxsz ||
1.33      christos 6039:            fw->boot.textsz > IWN_FW_BOOT_TEXT_MAXSZ ||
                   6040:            (fw->boot.textsz & 3) != 0) {
1.40      christos 6041:                aprint_error_dev(sc->sc_dev,
1.46      christos 6042:                    "firmware sections too large\n");
1.42      christos 6043:                goto out;
1.1       ober     6044:        }
                   6045:
1.46      christos 6046:        /* We can proceed with loading the firmware. */
1.33      christos 6047:        return 0;
1.42      christos 6048: out:
1.46      christos 6049:        firmware_free(fw->data, fw->size);
1.42      christos 6050:        fw->data = NULL;
1.46      christos 6051:        fw->size = 0;
1.42      christos 6052:        return error ? error : EINVAL;
1.33      christos 6053: }
                   6054:
                   6055: static int
                   6056: iwn_clock_wait(struct iwn_softc *sc)
                   6057: {
                   6058:        int ntries;
                   6059:
                   6060:        /* Set "initialization complete" bit. */
                   6061:        IWN_SETBITS(sc, IWN_GP_CNTRL, IWN_GP_CNTRL_INIT_DONE);
                   6062:
                   6063:        /* Wait for clock stabilization. */
1.40      christos 6064:        for (ntries = 0; ntries < 2500; ntries++) {
1.33      christos 6065:                if (IWN_READ(sc, IWN_GP_CNTRL) & IWN_GP_CNTRL_MAC_CLOCK_READY)
                   6066:                        return 0;
1.40      christos 6067:                DELAY(10);
1.1       ober     6068:        }
1.33      christos 6069:        aprint_error_dev(sc->sc_dev,
                   6070:            "timeout waiting for clock stabilization\n");
                   6071:        return ETIMEDOUT;
                   6072: }
                   6073:
                   6074: static int
1.40      christos 6075: iwn_apm_init(struct iwn_softc *sc)
1.1       ober     6076: {
1.40      christos 6077:        pcireg_t reg;
1.33      christos 6078:        int error;
1.1       ober     6079:
1.53      christos 6080:        /* Disable L0s exit timer (NMI bug workaround). */
1.33      christos 6081:        IWN_SETBITS(sc, IWN_GIO_CHICKEN, IWN_GIO_CHICKEN_DIS_L0S_TIMER);
1.53      christos 6082:        /* Don't wait for ICH L0s (ICH bug workaround). */
1.33      christos 6083:        IWN_SETBITS(sc, IWN_GIO_CHICKEN, IWN_GIO_CHICKEN_L1A_NO_L0S_RX);
1.1       ober     6084:
1.53      christos 6085:        /* Set FH wait threshold to max (HW bug under stress workaround). */
1.33      christos 6086:        IWN_SETBITS(sc, IWN_DBG_HPET_MEM, 0xffff0000);
1.1       ober     6087:
1.40      christos 6088:        /* Enable HAP INTA to move adapter from L1a to L0s. */
1.33      christos 6089:        IWN_SETBITS(sc, IWN_HW_IF_CONFIG, IWN_HW_IF_CONFIG_HAP_WAKE_L1A);
1.1       ober     6090:
1.40      christos 6091:        /* Retrieve PCIe Active State Power Management (ASPM). */
                   6092:        reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag,
1.65      msaitoh  6093:            sc->sc_cap_off + PCIE_LCSR);
1.40      christos 6094:        /* Workaround for HW instability in PCIe L0->L0s->L1 transition. */
1.65      msaitoh  6095:        if (reg & PCIE_LCSR_ASPM_L1)    /* L1 Entry enabled. */
1.40      christos 6096:                IWN_SETBITS(sc, IWN_GIO, IWN_GIO_L0S_ENA);
                   6097:        else
                   6098:                IWN_CLRBITS(sc, IWN_GIO, IWN_GIO_L0S_ENA);
                   6099:
                   6100:        if (sc->hw_type != IWN_HW_REV_TYPE_4965 &&
                   6101:            sc->hw_type <= IWN_HW_REV_TYPE_1000)
1.33      christos 6102:                IWN_SETBITS(sc, IWN_ANA_PLL, IWN_ANA_PLL_INIT);
1.1       ober     6103:
1.40      christos 6104:        /* Wait for clock stabilization before accessing prph. */
1.33      christos 6105:        if ((error = iwn_clock_wait(sc)) != 0)
1.40      christos 6106:                return error;
1.1       ober     6107:
1.33      christos 6108:        if ((error = iwn_nic_lock(sc)) != 0)
                   6109:                return error;
1.40      christos 6110:        if (sc->hw_type == IWN_HW_REV_TYPE_4965) {
1.53      christos 6111:                /* Enable DMA and BSM (Bootstrap State Machine). */
1.40      christos 6112:                iwn_prph_write(sc, IWN_APMG_CLK_EN,
                   6113:                    IWN_APMG_CLK_CTRL_DMA_CLK_RQT |
                   6114:                    IWN_APMG_CLK_CTRL_BSM_CLK_RQT);
                   6115:        } else {
                   6116:                /* Enable DMA. */
                   6117:                iwn_prph_write(sc, IWN_APMG_CLK_EN,
                   6118:                    IWN_APMG_CLK_CTRL_DMA_CLK_RQT);
                   6119:        }
1.33      christos 6120:        DELAY(20);
1.40      christos 6121:        /* Disable L1-Active. */
1.33      christos 6122:        iwn_prph_setbits(sc, IWN_APMG_PCI_STT, IWN_APMG_PCI_STT_L1A_DIS);
                   6123:        iwn_nic_unlock(sc);
1.1       ober     6124:
1.33      christos 6125:        return 0;
1.1       ober     6126: }
                   6127:
                   6128: static void
1.33      christos 6129: iwn_apm_stop_master(struct iwn_softc *sc)
1.1       ober     6130: {
                   6131:        int ntries;
                   6132:
1.40      christos 6133:        /* Stop busmaster DMA activity. */
1.33      christos 6134:        IWN_SETBITS(sc, IWN_RESET, IWN_RESET_STOP_MASTER);
1.1       ober     6135:        for (ntries = 0; ntries < 100; ntries++) {
1.33      christos 6136:                if (IWN_READ(sc, IWN_RESET) & IWN_RESET_MASTER_DISABLED)
                   6137:                        return;
1.1       ober     6138:                DELAY(10);
                   6139:        }
1.84      nonaka   6140:        aprint_error_dev(sc->sc_dev, "timeout waiting for master\n");
1.1       ober     6141: }
                   6142:
1.33      christos 6143: static void
                   6144: iwn_apm_stop(struct iwn_softc *sc)
1.1       ober     6145: {
1.33      christos 6146:        iwn_apm_stop_master(sc);
1.1       ober     6147:
1.40      christos 6148:        /* Reset the entire device. */
1.33      christos 6149:        IWN_SETBITS(sc, IWN_RESET, IWN_RESET_SW);
                   6150:        DELAY(10);
                   6151:        /* Clear "initialization complete" bit. */
                   6152:        IWN_CLRBITS(sc, IWN_GP_CNTRL, IWN_GP_CNTRL_INIT_DONE);
                   6153: }
1.1       ober     6154:
1.33      christos 6155: static int
                   6156: iwn4965_nic_config(struct iwn_softc *sc)
                   6157: {
                   6158:        if (IWN_RFCFG_TYPE(sc->rfcfg) == 1) {
                   6159:                /*
                   6160:                 * I don't believe this to be correct but this is what the
                   6161:                 * vendor driver is doing. Probably the bits should not be
                   6162:                 * shifted in IWN_RFCFG_*.
                   6163:                 */
                   6164:                IWN_SETBITS(sc, IWN_HW_IF_CONFIG,
                   6165:                    IWN_RFCFG_TYPE(sc->rfcfg) |
                   6166:                    IWN_RFCFG_STEP(sc->rfcfg) |
                   6167:                    IWN_RFCFG_DASH(sc->rfcfg));
1.1       ober     6168:        }
1.33      christos 6169:        IWN_SETBITS(sc, IWN_HW_IF_CONFIG,
                   6170:            IWN_HW_IF_CONFIG_RADIO_SI | IWN_HW_IF_CONFIG_MAC_SI);
1.1       ober     6171:        return 0;
                   6172: }
                   6173:
1.33      christos 6174: static int
                   6175: iwn5000_nic_config(struct iwn_softc *sc)
1.1       ober     6176: {
1.40      christos 6177:        uint32_t tmp;
1.33      christos 6178:        int error;
1.1       ober     6179:
1.33      christos 6180:        if (IWN_RFCFG_TYPE(sc->rfcfg) < 3) {
                   6181:                IWN_SETBITS(sc, IWN_HW_IF_CONFIG,
                   6182:                    IWN_RFCFG_TYPE(sc->rfcfg) |
                   6183:                    IWN_RFCFG_STEP(sc->rfcfg) |
                   6184:                    IWN_RFCFG_DASH(sc->rfcfg));
                   6185:        }
                   6186:        IWN_SETBITS(sc, IWN_HW_IF_CONFIG,
                   6187:            IWN_HW_IF_CONFIG_RADIO_SI | IWN_HW_IF_CONFIG_MAC_SI);
1.1       ober     6188:
1.33      christos 6189:        if ((error = iwn_nic_lock(sc)) != 0)
                   6190:                return error;
                   6191:        iwn_prph_setbits(sc, IWN_APMG_PS, IWN_APMG_PS_EARLY_PWROFF_DIS);
1.40      christos 6192:
                   6193:        if (sc->hw_type == IWN_HW_REV_TYPE_1000) {
                   6194:                /*
                   6195:                 * Select first Switching Voltage Regulator (1.32V) to
                   6196:                 * solve a stability issue related to noisy DC2DC line
                   6197:                 * in the silicon of 1000 Series.
                   6198:                 */
                   6199:                tmp = iwn_prph_read(sc, IWN_APMG_DIGITAL_SVR);
                   6200:                tmp &= ~IWN_APMG_DIGITAL_SVR_VOLTAGE_MASK;
                   6201:                tmp |= IWN_APMG_DIGITAL_SVR_VOLTAGE_1_32;
                   6202:                iwn_prph_write(sc, IWN_APMG_DIGITAL_SVR, tmp);
                   6203:        }
1.33      christos 6204:        iwn_nic_unlock(sc);
1.40      christos 6205:
                   6206:        if (sc->sc_flags & IWN_FLAG_INTERNAL_PA) {
                   6207:                /* Use internal power amplifier only. */
                   6208:                IWN_WRITE(sc, IWN_GP_DRIVER, IWN_GP_DRIVER_RADIO_2X2_IPA);
                   6209:        }
1.53      christos 6210:        if ((sc->hw_type == IWN_HW_REV_TYPE_6050 ||
1.84      nonaka   6211:             sc->hw_type == IWN_HW_REV_TYPE_6005) && sc->calib_ver >= 6) {
1.40      christos 6212:                /* Indicate that ROM calibration version is >=6. */
                   6213:                IWN_SETBITS(sc, IWN_GP_DRIVER, IWN_GP_DRIVER_CALIB_VER6);
                   6214:        }
1.53      christos 6215:        if (sc->hw_type == IWN_HW_REV_TYPE_6005)
                   6216:                IWN_SETBITS(sc, IWN_GP_DRIVER, IWN_GP_DRIVER_6050_1X2);
1.72      nonaka   6217:        if (sc->hw_type == IWN_HW_REV_TYPE_2030 ||
                   6218:            sc->hw_type == IWN_HW_REV_TYPE_2000 ||
                   6219:            sc->hw_type == IWN_HW_REV_TYPE_135  ||
                   6220:            sc->hw_type == IWN_HW_REV_TYPE_105)
                   6221:                IWN_SETBITS(sc, IWN_GP_DRIVER, IWN_GP_DRIVER_RADIO_IQ_INVERT);
1.33      christos 6222:        return 0;
1.1       ober     6223: }
                   6224:
1.40      christos 6225: /*
                   6226:  * Take NIC ownership over Intel Active Management Technology (AMT).
                   6227:  */
                   6228: static int
                   6229: iwn_hw_prepare(struct iwn_softc *sc)
                   6230: {
                   6231:        int ntries;
                   6232:
                   6233:        /* Check if hardware is ready. */
                   6234:        IWN_SETBITS(sc, IWN_HW_IF_CONFIG, IWN_HW_IF_CONFIG_NIC_READY);
                   6235:        for (ntries = 0; ntries < 5; ntries++) {
                   6236:                if (IWN_READ(sc, IWN_HW_IF_CONFIG) &
                   6237:                    IWN_HW_IF_CONFIG_NIC_READY)
                   6238:                        return 0;
                   6239:                DELAY(10);
                   6240:        }
                   6241:
                   6242:        /* Hardware not ready, force into ready state. */
                   6243:        IWN_SETBITS(sc, IWN_HW_IF_CONFIG, IWN_HW_IF_CONFIG_PREPARE);
                   6244:        for (ntries = 0; ntries < 15000; ntries++) {
                   6245:                if (!(IWN_READ(sc, IWN_HW_IF_CONFIG) &
                   6246:                    IWN_HW_IF_CONFIG_PREPARE_DONE))
                   6247:                        break;
                   6248:                DELAY(10);
                   6249:        }
                   6250:        if (ntries == 15000)
                   6251:                return ETIMEDOUT;
                   6252:
                   6253:        /* Hardware should be ready now. */
                   6254:        IWN_SETBITS(sc, IWN_HW_IF_CONFIG, IWN_HW_IF_CONFIG_NIC_READY);
                   6255:        for (ntries = 0; ntries < 5; ntries++) {
                   6256:                if (IWN_READ(sc, IWN_HW_IF_CONFIG) &
                   6257:                    IWN_HW_IF_CONFIG_NIC_READY)
                   6258:                        return 0;
                   6259:                DELAY(10);
                   6260:        }
                   6261:        return ETIMEDOUT;
                   6262: }
                   6263:
1.1       ober     6264: static int
1.33      christos 6265: iwn_hw_init(struct iwn_softc *sc)
1.1       ober     6266: {
1.53      christos 6267:        struct iwn_ops *ops = &sc->ops;
1.40      christos 6268:        int error, chnl, qid;
1.1       ober     6269:
1.33      christos 6270:        /* Clear pending interrupts. */
                   6271:        IWN_WRITE(sc, IWN_INT, 0xffffffff);
                   6272:
1.40      christos 6273:        if ((error = iwn_apm_init(sc)) != 0) {
                   6274:                aprint_error_dev(sc->sc_dev,
                   6275:                    "could not power ON adapter\n");
1.33      christos 6276:                return error;
1.1       ober     6277:        }
                   6278:
1.33      christos 6279:        /* Select VMAIN power source. */
                   6280:        if ((error = iwn_nic_lock(sc)) != 0)
                   6281:                return error;
                   6282:        iwn_prph_clrbits(sc, IWN_APMG_PS, IWN_APMG_PS_PWR_SRC_MASK);
                   6283:        iwn_nic_unlock(sc);
                   6284:
                   6285:        /* Perform adapter-specific initialization. */
1.53      christos 6286:        if ((error = ops->nic_config(sc)) != 0)
1.33      christos 6287:                return error;
1.1       ober     6288:
1.33      christos 6289:        /* Initialize RX ring. */
                   6290:        if ((error = iwn_nic_lock(sc)) != 0)
                   6291:                return error;
                   6292:        IWN_WRITE(sc, IWN_FH_RX_CONFIG, 0);
                   6293:        IWN_WRITE(sc, IWN_FH_RX_WPTR, 0);
1.53      christos 6294:        /* Set physical address of RX ring (256-byte aligned). */
1.33      christos 6295:        IWN_WRITE(sc, IWN_FH_RX_BASE, sc->rxq.desc_dma.paddr >> 8);
1.53      christos 6296:        /* Set physical address of RX status (16-byte aligned). */
1.33      christos 6297:        IWN_WRITE(sc, IWN_FH_STATUS_WPTR, sc->rxq.stat_dma.paddr >> 4);
                   6298:        /* Enable RX. */
                   6299:        IWN_WRITE(sc, IWN_FH_RX_CONFIG,
1.40      christos 6300:            IWN_FH_RX_CONFIG_ENA           |
1.33      christos 6301:            IWN_FH_RX_CONFIG_IGN_RXF_EMPTY |    /* HW bug workaround */
                   6302:            IWN_FH_RX_CONFIG_IRQ_DST_HOST  |
                   6303:            IWN_FH_RX_CONFIG_SINGLE_FRAME  |
                   6304:            IWN_FH_RX_CONFIG_RB_TIMEOUT(0) |
                   6305:            IWN_FH_RX_CONFIG_NRBD(IWN_RX_RING_COUNT_LOG));
                   6306:        iwn_nic_unlock(sc);
                   6307:        IWN_WRITE(sc, IWN_FH_RX_WPTR, (IWN_RX_RING_COUNT - 1) & ~7);
1.1       ober     6308:
1.33      christos 6309:        if ((error = iwn_nic_lock(sc)) != 0)
                   6310:                return error;
1.1       ober     6311:
1.33      christos 6312:        /* Initialize TX scheduler. */
1.53      christos 6313:        iwn_prph_write(sc, sc->sched_txfact_addr, 0);
1.1       ober     6314:
1.53      christos 6315:        /* Set physical address of "keep warm" page (16-byte aligned). */
1.33      christos 6316:        IWN_WRITE(sc, IWN_FH_KW_ADDR, sc->kw_dma.paddr >> 4);
1.1       ober     6317:
1.33      christos 6318:        /* Initialize TX rings. */
1.53      christos 6319:        for (qid = 0; qid < sc->ntxqs; qid++) {
1.1       ober     6320:                struct iwn_tx_ring *txq = &sc->txq[qid];
1.33      christos 6321:
1.53      christos 6322:                /* Set physical address of TX ring (256-byte aligned). */
1.33      christos 6323:                IWN_WRITE(sc, IWN_FH_CBBC_QUEUE(qid),
                   6324:                    txq->desc_dma.paddr >> 8);
1.40      christos 6325:        }
                   6326:        iwn_nic_unlock(sc);
                   6327:
                   6328:        /* Enable DMA channels. */
1.53      christos 6329:        for (chnl = 0; chnl < sc->ndmachnls; chnl++) {
1.40      christos 6330:                IWN_WRITE(sc, IWN_FH_TX_CONFIG(chnl),
1.33      christos 6331:                    IWN_FH_TX_CONFIG_DMA_ENA |
                   6332:                    IWN_FH_TX_CONFIG_DMA_CREDIT_ENA);
                   6333:        }
                   6334:
                   6335:        /* Clear "radio off" and "commands blocked" bits. */
                   6336:        IWN_WRITE(sc, IWN_UCODE_GP1_CLR, IWN_UCODE_GP1_RFKILL);
                   6337:        IWN_WRITE(sc, IWN_UCODE_GP1_CLR, IWN_UCODE_GP1_CMD_BLOCKED);
                   6338:
                   6339:        /* Clear pending interrupts. */
                   6340:        IWN_WRITE(sc, IWN_INT, 0xffffffff);
                   6341:        /* Enable interrupt coalescing. */
                   6342:        IWN_WRITE(sc, IWN_INT_COALESCING, 512 / 8);
                   6343:        /* Enable interrupts. */
1.40      christos 6344:        IWN_WRITE(sc, IWN_INT_MASK, sc->int_mask);
1.33      christos 6345:
                   6346:        /* _Really_ make sure "radio off" bit is cleared! */
                   6347:        IWN_WRITE(sc, IWN_UCODE_GP1_CLR, IWN_UCODE_GP1_RFKILL);
                   6348:        IWN_WRITE(sc, IWN_UCODE_GP1_CLR, IWN_UCODE_GP1_RFKILL);
                   6349:
1.53      christos 6350:        /* Enable shadow registers. */
                   6351:        if (sc->hw_type >= IWN_HW_REV_TYPE_6000)
                   6352:                IWN_SETBITS(sc, IWN_SHADOW_REG_CTRL, 0x800fffff);
                   6353:
                   6354:        if ((error = ops->load_firmware(sc)) != 0) {
1.40      christos 6355:                aprint_error_dev(sc->sc_dev,
                   6356:                    "could not load firmware\n");
1.33      christos 6357:                return error;
                   6358:        }
                   6359:        /* Wait at most one second for firmware alive notification. */
                   6360:        if ((error = tsleep(sc, PCATCH, "iwninit", hz)) != 0) {
                   6361:                aprint_error_dev(sc->sc_dev,
1.40      christos 6362:                    "timeout waiting for adapter to initialize\n");
1.33      christos 6363:                return error;
                   6364:        }
                   6365:        /* Do post-firmware initialization. */
1.53      christos 6366:        return ops->post_alive(sc);
1.33      christos 6367: }
                   6368:
                   6369: static void
                   6370: iwn_hw_stop(struct iwn_softc *sc)
                   6371: {
1.40      christos 6372:        int chnl, qid, ntries;
1.33      christos 6373:
                   6374:        IWN_WRITE(sc, IWN_RESET, IWN_RESET_NEVO);
                   6375:
                   6376:        /* Disable interrupts. */
1.40      christos 6377:        IWN_WRITE(sc, IWN_INT_MASK, 0);
1.33      christos 6378:        IWN_WRITE(sc, IWN_INT, 0xffffffff);
                   6379:        IWN_WRITE(sc, IWN_FH_INT, 0xffffffff);
1.40      christos 6380:        sc->sc_flags &= ~IWN_FLAG_USE_ICT;
1.33      christos 6381:
                   6382:        /* Make sure we no longer hold the NIC lock. */
                   6383:        iwn_nic_unlock(sc);
                   6384:
                   6385:        /* Stop TX scheduler. */
1.53      christos 6386:        iwn_prph_write(sc, sc->sched_txfact_addr, 0);
1.33      christos 6387:
1.40      christos 6388:        /* Stop all DMA channels. */
                   6389:        if (iwn_nic_lock(sc) == 0) {
1.53      christos 6390:                for (chnl = 0; chnl < sc->ndmachnls; chnl++) {
1.40      christos 6391:                        IWN_WRITE(sc, IWN_FH_TX_CONFIG(chnl), 0);
                   6392:                        for (ntries = 0; ntries < 200; ntries++) {
1.53      christos 6393:                                if (IWN_READ(sc, IWN_FH_TX_STATUS) &
1.40      christos 6394:                                    IWN_FH_TX_STATUS_IDLE(chnl))
                   6395:                                        break;
                   6396:                                DELAY(10);
                   6397:                        }
                   6398:                }
                   6399:                iwn_nic_unlock(sc);
                   6400:        }
1.33      christos 6401:
                   6402:        /* Stop RX ring. */
                   6403:        iwn_reset_rx_ring(sc, &sc->rxq);
                   6404:
1.40      christos 6405:        /* Reset all TX rings. */
1.53      christos 6406:        for (qid = 0; qid < sc->ntxqs; qid++)
1.40      christos 6407:                iwn_reset_tx_ring(sc, &sc->txq[qid]);
                   6408:
1.33      christos 6409:        if (iwn_nic_lock(sc) == 0) {
1.40      christos 6410:                iwn_prph_write(sc, IWN_APMG_CLK_DIS,
                   6411:                    IWN_APMG_CLK_CTRL_DMA_CLK_RQT);
1.33      christos 6412:                iwn_nic_unlock(sc);
1.1       ober     6413:        }
1.33      christos 6414:        DELAY(5);
                   6415:        /* Power OFF adapter. */
                   6416:        iwn_apm_stop(sc);
                   6417: }
                   6418:
                   6419: static int
                   6420: iwn_init(struct ifnet *ifp)
                   6421: {
                   6422:        struct iwn_softc *sc = ifp->if_softc;
                   6423:        struct ieee80211com *ic = &sc->sc_ic;
                   6424:        int error;
1.1       ober     6425:
1.48      christos 6426:        mutex_enter(&sc->sc_mtx);
1.47      christos 6427:        if (sc->sc_flags & IWN_FLAG_HW_INITED)
1.49      christos 6428:                goto out;
1.40      christos 6429:        if ((error = iwn_hw_prepare(sc)) != 0) {
                   6430:                aprint_error_dev(sc->sc_dev,
                   6431:                    "hardware not ready\n");
                   6432:                goto fail;
                   6433:        }
                   6434:
1.33      christos 6435:        /* Check that the radio is not disabled by hardware switch. */
                   6436:        if (!(IWN_READ(sc, IWN_GP_CNTRL) & IWN_GP_CNTRL_RFKILL)) {
                   6437:                aprint_error_dev(sc->sc_dev,
                   6438:                    "radio is disabled by hardware switch\n");
                   6439:                error = EPERM;  /* :-) */
                   6440:                goto fail;
1.1       ober     6441:        }
1.28      blymn    6442:
1.33      christos 6443:        /* Read firmware images from the filesystem. */
                   6444:        if ((error = iwn_read_firmware(sc)) != 0) {
1.40      christos 6445:                aprint_error_dev(sc->sc_dev,
                   6446:                    "could not read firmware\n");
1.33      christos 6447:                goto fail;
1.1       ober     6448:        }
                   6449:
1.40      christos 6450:        /* Initialize interrupt mask to default value. */
                   6451:        sc->int_mask = IWN_INT_MASK_DEF;
                   6452:        sc->sc_flags &= ~IWN_FLAG_USE_ICT;
                   6453:
1.33      christos 6454:        /* Initialize hardware and upload firmware. */
1.46      christos 6455:        KASSERT(sc->fw.data != NULL && sc->fw.size > 0);
1.33      christos 6456:        error = iwn_hw_init(sc);
1.46      christos 6457:        firmware_free(sc->fw.data, sc->fw.size);
1.42      christos 6458:        sc->fw.data = NULL;
1.46      christos 6459:        sc->fw.size = 0;
1.33      christos 6460:        if (error != 0) {
1.40      christos 6461:                aprint_error_dev(sc->sc_dev,
                   6462:                    "could not initialize hardware\n");
1.33      christos 6463:                goto fail;
                   6464:        }
1.8       blymn    6465:
1.33      christos 6466:        /* Configure adapter now that it is ready. */
1.1       ober     6467:        if ((error = iwn_config(sc)) != 0) {
1.40      christos 6468:                aprint_error_dev(sc->sc_dev,
                   6469:                    "could not configure device\n");
1.33      christos 6470:                goto fail;
1.1       ober     6471:        }
                   6472:
1.85      mlelstv  6473:        sc->sc_beacon_wait = 0;
                   6474:
1.1       ober     6475:        ifp->if_flags &= ~IFF_OACTIVE;
                   6476:        ifp->if_flags |= IFF_RUNNING;
                   6477:
1.40      christos 6478:        if (ic->ic_opmode != IEEE80211_M_MONITOR)
                   6479:                ieee80211_begin_scan(ic, 0);
                   6480:        else
1.1       ober     6481:                ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
                   6482:
1.47      christos 6483:        sc->sc_flags |= IWN_FLAG_HW_INITED;
1.49      christos 6484: out:
1.48      christos 6485:        mutex_exit(&sc->sc_mtx);
1.1       ober     6486:        return 0;
                   6487:
1.48      christos 6488: fail:  mutex_exit(&sc->sc_mtx);
1.47      christos 6489:        iwn_stop(ifp, 1);
1.1       ober     6490:        return error;
                   6491: }
                   6492:
                   6493: static void
                   6494: iwn_stop(struct ifnet *ifp, int disable)
                   6495: {
                   6496:        struct iwn_softc *sc = ifp->if_softc;
                   6497:        struct ieee80211com *ic = &sc->sc_ic;
                   6498:
1.50      christos 6499:        if (!disable)
                   6500:                mutex_enter(&sc->sc_mtx);
1.47      christos 6501:        sc->sc_flags &= ~IWN_FLAG_HW_INITED;
1.1       ober     6502:        ifp->if_timer = sc->sc_tx_timer = 0;
                   6503:        ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
                   6504:
                   6505:        ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
                   6506:
1.33      christos 6507:        /* Power OFF hardware. */
                   6508:        iwn_hw_stop(sc);
1.1       ober     6509:
1.50      christos 6510:        if (!disable)
                   6511:                mutex_exit(&sc->sc_mtx);
1.40      christos 6512: }
                   6513:
1.44      christos 6514: /*
                   6515:  * XXX MCLGETI alternative
                   6516:  *
                   6517:  * With IWN_USE_RBUF defined it uses the rbuf cache for receive buffers
                   6518:  * as long as there are available free buffers then it uses MEXTMALLOC.,
                   6519:  * Without IWN_USE_RBUF defined it uses MEXTMALLOC exclusively.
                   6520:  * The MCLGET4K code is used for testing an alternative mbuf cache.
                   6521:  */
                   6522:
1.40      christos 6523: static struct mbuf *
                   6524: MCLGETIalt(struct iwn_softc *sc, int how,
                   6525:     struct ifnet *ifp __unused, u_int size)
                   6526: {
                   6527:        struct mbuf *m;
                   6528: #ifdef IWN_USE_RBUF
                   6529:        struct iwn_rbuf *rbuf;
                   6530: #endif
                   6531:
                   6532:        MGETHDR(m, how, MT_DATA);
                   6533:        if (m == NULL)
                   6534:                return NULL;
                   6535:
                   6536: #ifdef IWN_USE_RBUF
                   6537:        if (sc->rxq.nb_free_entries > 0 &&
                   6538:            (rbuf = iwn_alloc_rbuf(sc)) != NULL) {
                   6539:                /* Attach buffer to mbuf header. */
                   6540:                MEXTADD(m, rbuf->vaddr, size, 0, iwn_free_rbuf, rbuf);
                   6541:                m->m_flags |= M_EXT_RW;
                   6542:        }
                   6543:        else {
                   6544:                MEXTMALLOC(m, size, how);
                   6545:                if ((m->m_flags & M_EXT) == 0) {
                   6546:                        m_freem(m);
                   6547:                        return NULL;
                   6548:                }
                   6549:        }
                   6550:
                   6551: #else
                   6552: #ifdef MCLGET4K
                   6553:        if (size == 4096)
                   6554:                MCLGET4K(m, how);
                   6555:        else
                   6556:                panic("size must be 4k");
                   6557: #else
                   6558:        MEXTMALLOC(m, size, how);
                   6559: #endif
                   6560:        if ((m->m_flags & M_EXT) == 0) {
                   6561:                m_freem(m);
                   6562:                return NULL;
                   6563:        }
                   6564: #endif
                   6565:
                   6566:        return m;
                   6567: }
                   6568:
                   6569: #ifdef IWN_USE_RBUF
                   6570: static struct iwn_rbuf *
                   6571: iwn_alloc_rbuf(struct iwn_softc *sc)
                   6572: {
                   6573:        struct iwn_rbuf *rbuf;
                   6574:        mutex_enter(&sc->rxq.freelist_mtx);
                   6575:
                   6576:        rbuf = SLIST_FIRST(&sc->rxq.freelist);
                   6577:        if (rbuf != NULL) {
                   6578:                SLIST_REMOVE_HEAD(&sc->rxq.freelist, next);
                   6579:                sc->rxq.nb_free_entries --;
                   6580:        }
                   6581:        mutex_exit(&sc->rxq.freelist_mtx);
                   6582:        return rbuf;
                   6583: }
                   6584:
                   6585: /*
                   6586:  * This is called automatically by the network stack when the mbuf to which
                   6587:  * our RX buffer is attached is freed.
                   6588:  */
                   6589: static void
                   6590: iwn_free_rbuf(struct mbuf* m, void *buf,  size_t size, void *arg)
                   6591: {
                   6592:        struct iwn_rbuf *rbuf = arg;
                   6593:        struct iwn_softc *sc = rbuf->sc;
                   6594:
                   6595:        /* Put the RX buffer back in the free list. */
                   6596:        mutex_enter(&sc->rxq.freelist_mtx);
                   6597:        SLIST_INSERT_HEAD(&sc->rxq.freelist, rbuf, next);
                   6598:        mutex_exit(&sc->rxq.freelist_mtx);
                   6599:
                   6600:        sc->rxq.nb_free_entries ++;
                   6601:        if (__predict_true(m != NULL))
                   6602:                pool_cache_put(mb_cache, m);
                   6603: }
                   6604:
                   6605: static int
                   6606: iwn_alloc_rpool(struct iwn_softc *sc)
                   6607: {
                   6608:        struct iwn_rx_ring *ring = &sc->rxq;
                   6609:        struct iwn_rbuf *rbuf;
                   6610:        int i, error;
                   6611:
                   6612:        mutex_init(&ring->freelist_mtx, MUTEX_DEFAULT, IPL_NET);
                   6613:
                   6614:        /* Allocate a big chunk of DMA'able memory... */
                   6615:        error = iwn_dma_contig_alloc(sc->sc_dmat, &ring->buf_dma, NULL,
                   6616:            IWN_RBUF_COUNT * IWN_RBUF_SIZE, PAGE_SIZE);
                   6617:        if (error != 0) {
                   6618:                aprint_error_dev(sc->sc_dev,
                   6619:                    "could not allocate RX buffers DMA memory\n");
                   6620:                return error;
                   6621:        }
                   6622:        /* ...and split it into chunks of IWN_RBUF_SIZE bytes. */
                   6623:        SLIST_INIT(&ring->freelist);
                   6624:        for (i = 0; i < IWN_RBUF_COUNT; i++) {
                   6625:                rbuf = &ring->rbuf[i];
                   6626:
                   6627:                rbuf->sc = sc;  /* Backpointer for callbacks. */
                   6628:                rbuf->vaddr = (void *)((vaddr_t)ring->buf_dma.vaddr + i * IWN_RBUF_SIZE);
                   6629:                rbuf->paddr = ring->buf_dma.paddr + i * IWN_RBUF_SIZE;
                   6630:
                   6631:                SLIST_INSERT_HEAD(&ring->freelist, rbuf, next);
                   6632:        }
                   6633:        ring->nb_free_entries = IWN_RBUF_COUNT;
                   6634:        return 0;
                   6635: }
                   6636:
                   6637: static void
                   6638: iwn_free_rpool(struct iwn_softc *sc)
                   6639: {
                   6640:        iwn_dma_contig_free(&sc->rxq.buf_dma);
                   6641: }
1.33      christos 6642: #endif
1.40      christos 6643:
                   6644: /*
                   6645:  * XXX: Hack to set the current channel to the value advertised in beacons or
                   6646:  * probe responses. Only used during AP detection.
                   6647:  * XXX: Duplicated from if_iwi.c
                   6648:  */
                   6649: static void
1.76      nonaka   6650: iwn_fix_channel(struct ieee80211com *ic, struct mbuf *m,
                   6651:     struct iwn_rx_stat *stat)
1.1       ober     6652: {
1.76      nonaka   6653:        struct iwn_softc *sc = ic->ic_ifp->if_softc;
1.40      christos 6654:        struct ieee80211_frame *wh;
                   6655:        uint8_t subtype;
                   6656:        uint8_t *frm, *efrm;
                   6657:
                   6658:        wh = mtod(m, struct ieee80211_frame *);
                   6659:
                   6660:        if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_MGT)
                   6661:                return;
                   6662:
                   6663:        subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
                   6664:
                   6665:        if (subtype != IEEE80211_FC0_SUBTYPE_BEACON &&
                   6666:            subtype != IEEE80211_FC0_SUBTYPE_PROBE_RESP)
                   6667:                return;
                   6668:
1.76      nonaka   6669:        if (sc->sc_flags & IWN_FLAG_SCANNING_5GHZ) {
                   6670:                int chan = le16toh(stat->chan);
                   6671:                if (chan < __arraycount(ic->ic_channels))
                   6672:                        ic->ic_curchan = &ic->ic_channels[chan];
                   6673:                return;
                   6674:        }
                   6675:
1.40      christos 6676:        frm = (uint8_t *)(wh + 1);
                   6677:        efrm = mtod(m, uint8_t *) + m->m_len;
1.1       ober     6678:
1.40      christos 6679:        frm += 12;      /* skip tstamp, bintval and capinfo fields */
1.87      maxv     6680:        while (frm + 2 < efrm) {
                   6681:                if (*frm == IEEE80211_ELEMID_DSPARMS) {
1.40      christos 6682: #if IEEE80211_CHAN_MAX < 255
1.87      maxv     6683:                        if (frm[2] <= IEEE80211_CHAN_MAX)
1.33      christos 6684: #endif
1.87      maxv     6685:                                ic->ic_curchan = &ic->ic_channels[frm[2]];
                   6686:                }
1.1       ober     6687:
1.40      christos 6688:                frm += frm[1] + 2;
                   6689:        }
1.1       ober     6690: }
1.40      christos 6691:
1.67      prlw1    6692: #ifdef notyetMODULE
                   6693:
                   6694: MODULE(MODULE_CLASS_DRIVER, if_iwn, "pci");
                   6695:
                   6696: #ifdef _MODULE
                   6697: #include "ioconf.c"
                   6698: #endif
                   6699:
                   6700: static int
                   6701: if_iwn_modcmd(modcmd_t cmd, void *data)
                   6702: {
                   6703:        int error = 0;
                   6704:
                   6705:        switch (cmd) {
                   6706:        case MODULE_CMD_INIT:
                   6707: #ifdef _MODULE
                   6708:                error = config_init_component(cfdriver_ioconf_if_iwn,
                   6709:                        cfattach_ioconf_if_iwn, cfdata_ioconf_if_iwn);
                   6710: #endif
                   6711:                return error;
                   6712:        case MODULE_CMD_FINI:
                   6713: #ifdef _MODULE
                   6714:                error = config_fini_component(cfdriver_ioconf_if_iwn,
                   6715:                        cfattach_ioconf_if_iwn, cfdata_ioconf_if_iwn);
                   6716: #endif
                   6717:                return error;
                   6718:        case MODULE_CMD_AUTOUNLOAD:
                   6719: #ifdef _MODULE
                   6720:                /* XXX This is not optional! */
                   6721: #endif
                   6722:                return error;
                   6723:        default:
                   6724:                return ENOTTY;
                   6725:        }
                   6726: }
                   6727: #endif

CVSweb <webmaster@jp.NetBSD.org>