Home | History | Annotate | Line # | Download | only in pci
if_iwm.c revision 1.65
      1  1.65   nonaka /*	$NetBSD: if_iwm.c,v 1.65 2017/01/19 11:24:05 nonaka Exp $	*/
      2  1.56   nonaka /*	OpenBSD: if_iwm.c,v 1.148 2016/11/19 21:07:08 stsp Exp	*/
      3  1.45   nonaka #define IEEE80211_NO_HT
      4   1.1    pooka /*
      5  1.45   nonaka  * Copyright (c) 2014, 2016 genua gmbh <info (at) genua.de>
      6  1.45   nonaka  *   Author: Stefan Sperling <stsp (at) openbsd.org>
      7   1.1    pooka  * Copyright (c) 2014 Fixup Software Ltd.
      8   1.1    pooka  *
      9   1.1    pooka  * Permission to use, copy, modify, and distribute this software for any
     10   1.1    pooka  * purpose with or without fee is hereby granted, provided that the above
     11   1.1    pooka  * copyright notice and this permission notice appear in all copies.
     12   1.1    pooka  *
     13   1.1    pooka  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
     14   1.1    pooka  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     15   1.1    pooka  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     16   1.1    pooka  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     17   1.1    pooka  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     18   1.1    pooka  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     19   1.1    pooka  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     20   1.1    pooka  */
     21   1.1    pooka 
     22   1.1    pooka /*-
     23   1.1    pooka  * Based on BSD-licensed source modules in the Linux iwlwifi driver,
     24   1.1    pooka  * which were used as the reference documentation for this implementation.
     25   1.1    pooka  *
     26   1.1    pooka  ***********************************************************************
     27   1.1    pooka  *
     28   1.1    pooka  * This file is provided under a dual BSD/GPLv2 license.  When using or
     29   1.1    pooka  * redistributing this file, you may do so under either license.
     30   1.1    pooka  *
     31   1.1    pooka  * GPL LICENSE SUMMARY
     32   1.1    pooka  *
     33   1.1    pooka  * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved.
     34  1.45   nonaka  * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
     35  1.45   nonaka  * Copyright(c) 2016 Intel Deutschland GmbH
     36   1.1    pooka  *
     37   1.1    pooka  * This program is free software; you can redistribute it and/or modify
     38   1.1    pooka  * it under the terms of version 2 of the GNU General Public License as
     39   1.1    pooka  * published by the Free Software Foundation.
     40   1.1    pooka  *
     41   1.1    pooka  * This program is distributed in the hope that it will be useful, but
     42   1.1    pooka  * WITHOUT ANY WARRANTY; without even the implied warranty of
     43   1.1    pooka  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     44   1.1    pooka  * General Public License for more details.
     45   1.1    pooka  *
     46   1.1    pooka  * You should have received a copy of the GNU General Public License
     47   1.1    pooka  * along with this program; if not, write to the Free Software
     48   1.1    pooka  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
     49   1.1    pooka  * USA
     50   1.1    pooka  *
     51   1.1    pooka  * The full GNU General Public License is included in this distribution
     52   1.1    pooka  * in the file called COPYING.
     53   1.1    pooka  *
     54   1.1    pooka  * Contact Information:
     55   1.1    pooka  *  Intel Linux Wireless <ilw (at) linux.intel.com>
     56   1.1    pooka  * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
     57   1.1    pooka  *
     58   1.1    pooka  *
     59   1.1    pooka  * BSD LICENSE
     60   1.1    pooka  *
     61   1.1    pooka  * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
     62  1.45   nonaka  * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
     63  1.45   nonaka  * Copyright(c) 2016 Intel Deutschland GmbH
     64   1.1    pooka  * All rights reserved.
     65   1.1    pooka  *
     66   1.1    pooka  * Redistribution and use in source and binary forms, with or without
     67   1.1    pooka  * modification, are permitted provided that the following conditions
     68   1.1    pooka  * are met:
     69   1.1    pooka  *
     70   1.1    pooka  *  * Redistributions of source code must retain the above copyright
     71   1.1    pooka  *    notice, this list of conditions and the following disclaimer.
     72   1.1    pooka  *  * Redistributions in binary form must reproduce the above copyright
     73   1.1    pooka  *    notice, this list of conditions and the following disclaimer in
     74   1.1    pooka  *    the documentation and/or other materials provided with the
     75   1.1    pooka  *    distribution.
     76   1.1    pooka  *  * Neither the name Intel Corporation nor the names of its
     77   1.1    pooka  *    contributors may be used to endorse or promote products derived
     78   1.1    pooka  *    from this software without specific prior written permission.
     79   1.1    pooka  *
     80   1.1    pooka  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     81   1.1    pooka  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     82   1.1    pooka  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     83   1.1    pooka  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     84   1.1    pooka  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     85   1.1    pooka  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     86   1.1    pooka  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     87   1.1    pooka  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     88   1.1    pooka  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     89   1.1    pooka  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     90   1.1    pooka  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     91   1.1    pooka  */
     92   1.1    pooka 
     93   1.1    pooka /*-
     94   1.1    pooka  * Copyright (c) 2007-2010 Damien Bergamini <damien.bergamini (at) free.fr>
     95   1.1    pooka  *
     96   1.1    pooka  * Permission to use, copy, modify, and distribute this software for any
     97   1.1    pooka  * purpose with or without fee is hereby granted, provided that the above
     98   1.1    pooka  * copyright notice and this permission notice appear in all copies.
     99   1.1    pooka  *
    100   1.1    pooka  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
    101   1.1    pooka  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
    102   1.1    pooka  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
    103   1.1    pooka  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
    104   1.1    pooka  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
    105   1.1    pooka  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
    106   1.1    pooka  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
    107   1.1    pooka  */
    108   1.1    pooka 
    109   1.1    pooka #include <sys/cdefs.h>
    110  1.65   nonaka __KERNEL_RCSID(0, "$NetBSD: if_iwm.c,v 1.65 2017/01/19 11:24:05 nonaka Exp $");
    111   1.1    pooka 
    112   1.1    pooka #include <sys/param.h>
    113   1.1    pooka #include <sys/conf.h>
    114   1.1    pooka #include <sys/kernel.h>
    115   1.1    pooka #include <sys/kmem.h>
    116   1.1    pooka #include <sys/mbuf.h>
    117   1.1    pooka #include <sys/mutex.h>
    118   1.1    pooka #include <sys/proc.h>
    119   1.1    pooka #include <sys/socket.h>
    120   1.1    pooka #include <sys/sockio.h>
    121  1.32   nonaka #include <sys/sysctl.h>
    122   1.1    pooka #include <sys/systm.h>
    123   1.1    pooka 
    124   1.1    pooka #include <sys/cpu.h>
    125   1.1    pooka #include <sys/bus.h>
    126   1.1    pooka #include <sys/workqueue.h>
    127   1.1    pooka #include <machine/endian.h>
    128   1.1    pooka #include <machine/intr.h>
    129   1.1    pooka 
    130   1.1    pooka #include <dev/pci/pcireg.h>
    131   1.1    pooka #include <dev/pci/pcivar.h>
    132   1.1    pooka #include <dev/pci/pcidevs.h>
    133   1.1    pooka #include <dev/firmload.h>
    134   1.1    pooka 
    135   1.1    pooka #include <net/bpf.h>
    136   1.1    pooka #include <net/if.h>
    137   1.1    pooka #include <net/if_dl.h>
    138   1.1    pooka #include <net/if_media.h>
    139   1.1    pooka #include <net/if_ether.h>
    140   1.1    pooka 
    141   1.1    pooka #include <netinet/in.h>
    142   1.1    pooka #include <netinet/ip.h>
    143   1.1    pooka 
    144   1.1    pooka #include <net80211/ieee80211_var.h>
    145   1.1    pooka #include <net80211/ieee80211_amrr.h>
    146   1.1    pooka #include <net80211/ieee80211_radiotap.h>
    147   1.1    pooka 
    148   1.1    pooka #define DEVNAME(_s)	device_xname((_s)->sc_dev)
    149   1.1    pooka #define IC2IFP(_ic_)	((_ic_)->ic_ifp)
    150   1.1    pooka 
    151   1.1    pooka #define le16_to_cpup(_a_) (le16toh(*(const uint16_t *)(_a_)))
    152   1.1    pooka #define le32_to_cpup(_a_) (le32toh(*(const uint32_t *)(_a_)))
    153   1.1    pooka 
    154   1.1    pooka #ifdef IWM_DEBUG
    155   1.1    pooka #define DPRINTF(x)	do { if (iwm_debug > 0) printf x; } while (0)
    156   1.1    pooka #define DPRINTFN(n, x)	do { if (iwm_debug >= (n)) printf x; } while (0)
    157  1.32   nonaka int iwm_debug = 0;
    158   1.1    pooka #else
    159   1.1    pooka #define DPRINTF(x)	do { ; } while (0)
    160   1.1    pooka #define DPRINTFN(n, x)	do { ; } while (0)
    161   1.1    pooka #endif
    162   1.1    pooka 
    163   1.1    pooka #include <dev/pci/if_iwmreg.h>
    164   1.1    pooka #include <dev/pci/if_iwmvar.h>
    165   1.1    pooka 
    166   1.4   nonaka static const uint8_t iwm_nvm_channels[] = {
    167   1.1    pooka 	/* 2.4 GHz */
    168   1.1    pooka 	1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
    169   1.1    pooka 	/* 5 GHz */
    170  1.45   nonaka 	36, 40, 44, 48, 52, 56, 60, 64,
    171   1.1    pooka 	100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144,
    172   1.1    pooka 	149, 153, 157, 161, 165
    173   1.1    pooka };
    174  1.45   nonaka 
    175  1.45   nonaka static const uint8_t iwm_nvm_channels_8000[] = {
    176  1.45   nonaka 	/* 2.4 GHz */
    177  1.45   nonaka 	1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
    178  1.45   nonaka 	/* 5 GHz */
    179  1.45   nonaka 	36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92,
    180  1.45   nonaka 	96, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144,
    181  1.45   nonaka 	149, 153, 157, 161, 165, 169, 173, 177, 181
    182  1.45   nonaka };
    183  1.45   nonaka 
    184   1.1    pooka #define IWM_NUM_2GHZ_CHANNELS	14
    185   1.1    pooka 
    186   1.4   nonaka static const struct iwm_rate {
    187   1.1    pooka 	uint8_t rate;
    188   1.1    pooka 	uint8_t plcp;
    189  1.45   nonaka 	uint8_t ht_plcp;
    190   1.1    pooka } iwm_rates[] = {
    191  1.45   nonaka 		/* Legacy */		/* HT */
    192  1.45   nonaka 	{   2,	IWM_RATE_1M_PLCP,	IWM_RATE_HT_SISO_MCS_INV_PLCP  },
    193  1.45   nonaka 	{   4,	IWM_RATE_2M_PLCP,	IWM_RATE_HT_SISO_MCS_INV_PLCP },
    194  1.45   nonaka 	{  11,	IWM_RATE_5M_PLCP,	IWM_RATE_HT_SISO_MCS_INV_PLCP  },
    195  1.45   nonaka 	{  22,	IWM_RATE_11M_PLCP,	IWM_RATE_HT_SISO_MCS_INV_PLCP },
    196  1.45   nonaka 	{  12,	IWM_RATE_6M_PLCP,	IWM_RATE_HT_SISO_MCS_0_PLCP },
    197  1.45   nonaka 	{  18,	IWM_RATE_9M_PLCP,	IWM_RATE_HT_SISO_MCS_INV_PLCP  },
    198  1.45   nonaka 	{  24,	IWM_RATE_12M_PLCP,	IWM_RATE_HT_SISO_MCS_1_PLCP },
    199  1.45   nonaka 	{  36,	IWM_RATE_18M_PLCP,	IWM_RATE_HT_SISO_MCS_2_PLCP },
    200  1.45   nonaka 	{  48,	IWM_RATE_24M_PLCP,	IWM_RATE_HT_SISO_MCS_3_PLCP },
    201  1.45   nonaka 	{  72,	IWM_RATE_36M_PLCP,	IWM_RATE_HT_SISO_MCS_4_PLCP },
    202  1.45   nonaka 	{  96,	IWM_RATE_48M_PLCP,	IWM_RATE_HT_SISO_MCS_5_PLCP },
    203  1.45   nonaka 	{ 108,	IWM_RATE_54M_PLCP,	IWM_RATE_HT_SISO_MCS_6_PLCP },
    204  1.45   nonaka 	{ 128,	IWM_RATE_INVM_PLCP,	IWM_RATE_HT_SISO_MCS_7_PLCP },
    205   1.1    pooka };
    206   1.1    pooka #define IWM_RIDX_CCK	0
    207   1.1    pooka #define IWM_RIDX_OFDM	4
    208   1.1    pooka #define IWM_RIDX_MAX	(__arraycount(iwm_rates)-1)
    209   1.1    pooka #define IWM_RIDX_IS_CCK(_i_) ((_i_) < IWM_RIDX_OFDM)
    210   1.1    pooka #define IWM_RIDX_IS_OFDM(_i_) ((_i_) >= IWM_RIDX_OFDM)
    211   1.1    pooka 
    212  1.45   nonaka #ifndef IEEE80211_NO_HT
    213  1.45   nonaka /* Convert an MCS index into an iwm_rates[] index. */
    214  1.45   nonaka static const int iwm_mcs2ridx[] = {
    215  1.45   nonaka 	IWM_RATE_MCS_0_INDEX,
    216  1.45   nonaka 	IWM_RATE_MCS_1_INDEX,
    217  1.45   nonaka 	IWM_RATE_MCS_2_INDEX,
    218  1.45   nonaka 	IWM_RATE_MCS_3_INDEX,
    219  1.45   nonaka 	IWM_RATE_MCS_4_INDEX,
    220  1.45   nonaka 	IWM_RATE_MCS_5_INDEX,
    221  1.45   nonaka 	IWM_RATE_MCS_6_INDEX,
    222  1.45   nonaka 	IWM_RATE_MCS_7_INDEX,
    223  1.45   nonaka };
    224  1.45   nonaka #endif
    225  1.45   nonaka 
    226  1.45   nonaka struct iwm_nvm_section {
    227  1.45   nonaka 	uint16_t length;
    228  1.45   nonaka 	uint8_t *data;
    229  1.45   nonaka };
    230  1.45   nonaka 
    231   1.1    pooka struct iwm_newstate_state {
    232   1.1    pooka 	struct work ns_wk;
    233   1.1    pooka 	enum ieee80211_state ns_nstate;
    234   1.1    pooka 	int ns_arg;
    235   1.1    pooka 	int ns_generation;
    236   1.1    pooka };
    237   1.1    pooka 
    238   1.4   nonaka static int	iwm_store_cscheme(struct iwm_softc *, uint8_t *, size_t);
    239   1.4   nonaka static int	iwm_firmware_store_section(struct iwm_softc *,
    240   1.4   nonaka 		    enum iwm_ucode_type, uint8_t *, size_t);
    241   1.4   nonaka static int	iwm_set_default_calib(struct iwm_softc *, const void *);
    242  1.61   nonaka static int	iwm_read_firmware(struct iwm_softc *, enum iwm_ucode_type);
    243   1.4   nonaka static uint32_t iwm_read_prph(struct iwm_softc *, uint32_t);
    244   1.4   nonaka static void	iwm_write_prph(struct iwm_softc *, uint32_t, uint32_t);
    245   1.2   nonaka #ifdef IWM_DEBUG
    246   1.4   nonaka static int	iwm_read_mem(struct iwm_softc *, uint32_t, void *, int);
    247   1.2   nonaka #endif
    248   1.4   nonaka static int	iwm_write_mem(struct iwm_softc *, uint32_t, const void *, int);
    249   1.4   nonaka static int	iwm_write_mem32(struct iwm_softc *, uint32_t, uint32_t);
    250   1.4   nonaka static int	iwm_poll_bit(struct iwm_softc *, int, uint32_t, uint32_t, int);
    251   1.4   nonaka static int	iwm_nic_lock(struct iwm_softc *);
    252   1.4   nonaka static void	iwm_nic_unlock(struct iwm_softc *);
    253   1.4   nonaka static void	iwm_set_bits_mask_prph(struct iwm_softc *, uint32_t, uint32_t,
    254   1.8   nonaka 		    uint32_t);
    255   1.4   nonaka static void	iwm_set_bits_prph(struct iwm_softc *, uint32_t, uint32_t);
    256   1.4   nonaka static void	iwm_clear_bits_prph(struct iwm_softc *, uint32_t, uint32_t);
    257   1.4   nonaka static int	iwm_dma_contig_alloc(bus_dma_tag_t, struct iwm_dma_info *,
    258   1.4   nonaka 		    bus_size_t, bus_size_t);
    259   1.4   nonaka static void	iwm_dma_contig_free(struct iwm_dma_info *);
    260   1.4   nonaka static int	iwm_alloc_rx_ring(struct iwm_softc *, struct iwm_rx_ring *);
    261  1.45   nonaka static void	iwm_disable_rx_dma(struct iwm_softc *);
    262   1.4   nonaka static void	iwm_reset_rx_ring(struct iwm_softc *, struct iwm_rx_ring *);
    263   1.4   nonaka static void	iwm_free_rx_ring(struct iwm_softc *, struct iwm_rx_ring *);
    264   1.4   nonaka static int	iwm_alloc_tx_ring(struct iwm_softc *, struct iwm_tx_ring *,
    265   1.4   nonaka 		    int);
    266   1.4   nonaka static void	iwm_reset_tx_ring(struct iwm_softc *, struct iwm_tx_ring *);
    267   1.4   nonaka static void	iwm_free_tx_ring(struct iwm_softc *, struct iwm_tx_ring *);
    268   1.4   nonaka static void	iwm_enable_rfkill_int(struct iwm_softc *);
    269   1.4   nonaka static int	iwm_check_rfkill(struct iwm_softc *);
    270   1.4   nonaka static void	iwm_enable_interrupts(struct iwm_softc *);
    271   1.4   nonaka static void	iwm_restore_interrupts(struct iwm_softc *);
    272   1.4   nonaka static void	iwm_disable_interrupts(struct iwm_softc *);
    273   1.4   nonaka static void	iwm_ict_reset(struct iwm_softc *);
    274   1.4   nonaka static int	iwm_set_hw_ready(struct iwm_softc *);
    275   1.4   nonaka static int	iwm_prepare_card_hw(struct iwm_softc *);
    276   1.4   nonaka static void	iwm_apm_config(struct iwm_softc *);
    277   1.4   nonaka static int	iwm_apm_init(struct iwm_softc *);
    278   1.4   nonaka static void	iwm_apm_stop(struct iwm_softc *);
    279  1.11   nonaka static int	iwm_allow_mcast(struct iwm_softc *);
    280   1.4   nonaka static int	iwm_start_hw(struct iwm_softc *);
    281   1.4   nonaka static void	iwm_stop_device(struct iwm_softc *);
    282  1.45   nonaka static void	iwm_nic_config(struct iwm_softc *);
    283   1.4   nonaka static int	iwm_nic_rx_init(struct iwm_softc *);
    284   1.4   nonaka static int	iwm_nic_tx_init(struct iwm_softc *);
    285   1.4   nonaka static int	iwm_nic_init(struct iwm_softc *);
    286  1.45   nonaka static int	iwm_enable_txq(struct iwm_softc *, int, int, int);
    287   1.4   nonaka static int	iwm_post_alive(struct iwm_softc *);
    288  1.45   nonaka static struct iwm_phy_db_entry *
    289  1.45   nonaka 		iwm_phy_db_get_section(struct iwm_softc *,
    290  1.45   nonaka 		    enum iwm_phy_db_section_type, uint16_t);
    291  1.45   nonaka static int	iwm_phy_db_set_section(struct iwm_softc *,
    292  1.45   nonaka 		    struct iwm_calib_res_notif_phy_db *, uint16_t);
    293   1.4   nonaka static int	iwm_is_valid_channel(uint16_t);
    294   1.4   nonaka static uint8_t	iwm_ch_id_to_ch_index(uint16_t);
    295   1.4   nonaka static uint16_t iwm_channel_id_to_papd(uint16_t);
    296   1.4   nonaka static uint16_t iwm_channel_id_to_txp(struct iwm_softc *, uint16_t);
    297   1.4   nonaka static int	iwm_phy_db_get_section_data(struct iwm_softc *, uint32_t,
    298   1.4   nonaka 		    uint8_t **, uint16_t *, uint16_t);
    299   1.4   nonaka static int	iwm_send_phy_db_cmd(struct iwm_softc *, uint16_t, uint16_t,
    300   1.4   nonaka 		    void *);
    301  1.45   nonaka static int	iwm_phy_db_send_all_channel_groups(struct iwm_softc *,
    302  1.45   nonaka 		    enum iwm_phy_db_section_type, uint8_t);
    303   1.4   nonaka static int	iwm_send_phy_db_data(struct iwm_softc *);
    304  1.45   nonaka static void	iwm_te_v2_to_v1(const struct iwm_time_event_cmd_v2 *,
    305   1.4   nonaka 		    struct iwm_time_event_cmd_v1 *);
    306  1.45   nonaka static int	iwm_send_time_event_cmd(struct iwm_softc *,
    307   1.4   nonaka 		    const struct iwm_time_event_cmd_v2 *);
    308  1.45   nonaka static void	iwm_protect_session(struct iwm_softc *, struct iwm_node *,
    309  1.45   nonaka 		    uint32_t, uint32_t);
    310   1.4   nonaka static int	iwm_nvm_read_chunk(struct iwm_softc *, uint16_t, uint16_t,
    311   1.4   nonaka 		    uint16_t, uint8_t *, uint16_t *);
    312   1.4   nonaka static int	iwm_nvm_read_section(struct iwm_softc *, uint16_t, uint8_t *,
    313  1.45   nonaka 		    uint16_t *, size_t);
    314  1.45   nonaka static void	iwm_init_channel_map(struct iwm_softc *, const uint16_t * const,
    315  1.45   nonaka 		    const uint8_t *, size_t);
    316  1.45   nonaka #ifndef IEEE80211_NO_HT
    317  1.45   nonaka static void	iwm_setup_ht_rates(struct iwm_softc *);
    318  1.45   nonaka static void	iwm_htprot_task(void *);
    319  1.45   nonaka static void	iwm_update_htprot(struct ieee80211com *,
    320  1.45   nonaka 		    struct ieee80211_node *);
    321  1.45   nonaka static int	iwm_ampdu_rx_start(struct ieee80211com *,
    322  1.45   nonaka 		    struct ieee80211_node *, uint8_t);
    323  1.45   nonaka static void	iwm_ampdu_rx_stop(struct ieee80211com *,
    324  1.45   nonaka 		    struct ieee80211_node *, uint8_t);
    325  1.45   nonaka static void	iwm_sta_rx_agg(struct iwm_softc *, struct ieee80211_node *,
    326  1.45   nonaka 		    uint8_t, uint16_t, int);
    327  1.45   nonaka #ifdef notyet
    328  1.45   nonaka static int	iwm_ampdu_tx_start(struct ieee80211com *,
    329  1.45   nonaka 		    struct ieee80211_node *, uint8_t);
    330  1.45   nonaka static void	iwm_ampdu_tx_stop(struct ieee80211com *,
    331  1.45   nonaka 		    struct ieee80211_node *, uint8_t);
    332  1.45   nonaka #endif
    333  1.45   nonaka static void	iwm_ba_task(void *);
    334  1.45   nonaka #endif
    335  1.45   nonaka 
    336   1.4   nonaka static int	iwm_parse_nvm_data(struct iwm_softc *, const uint16_t *,
    337  1.45   nonaka 		    const uint16_t *, const uint16_t *, const uint16_t *,
    338  1.45   nonaka 		    const uint16_t *, const uint16_t *);
    339  1.45   nonaka static void	iwm_set_hw_address_8000(struct iwm_softc *,
    340  1.45   nonaka 		    struct iwm_nvm_data *, const uint16_t *, const uint16_t *);
    341  1.45   nonaka static int	iwm_parse_nvm_sections(struct iwm_softc *,
    342  1.45   nonaka 		    struct iwm_nvm_section *);
    343   1.4   nonaka static int	iwm_nvm_init(struct iwm_softc *);
    344  1.45   nonaka static int	iwm_firmware_load_sect(struct iwm_softc *, uint32_t,
    345  1.45   nonaka 		    const uint8_t *, uint32_t);
    346   1.4   nonaka static int	iwm_firmware_load_chunk(struct iwm_softc *, uint32_t,
    347   1.4   nonaka 		    const uint8_t *, uint32_t);
    348  1.45   nonaka static int	iwm_load_firmware_7000(struct iwm_softc *, enum iwm_ucode_type);
    349  1.45   nonaka static int	iwm_load_cpu_sections_8000(struct iwm_softc *,
    350  1.45   nonaka 		    struct iwm_fw_sects *, int , int *);
    351  1.45   nonaka static int	iwm_load_firmware_8000(struct iwm_softc *, enum iwm_ucode_type);
    352   1.4   nonaka static int	iwm_load_firmware(struct iwm_softc *, enum iwm_ucode_type);
    353   1.4   nonaka static int	iwm_start_fw(struct iwm_softc *, enum iwm_ucode_type);
    354   1.4   nonaka static int	iwm_send_tx_ant_cfg(struct iwm_softc *, uint8_t);
    355   1.4   nonaka static int	iwm_send_phy_cfg_cmd(struct iwm_softc *);
    356  1.45   nonaka static int	iwm_load_ucode_wait_alive(struct iwm_softc *,
    357   1.4   nonaka 		    enum iwm_ucode_type);
    358   1.4   nonaka static int	iwm_run_init_mvm_ucode(struct iwm_softc *, int);
    359   1.4   nonaka static int	iwm_rx_addbuf(struct iwm_softc *, int, int);
    360  1.45   nonaka static int	iwm_calc_rssi(struct iwm_softc *, struct iwm_rx_phy_info *);
    361  1.45   nonaka static int	iwm_get_signal_strength(struct iwm_softc *,
    362   1.4   nonaka 		    struct iwm_rx_phy_info *);
    363  1.45   nonaka static void	iwm_rx_rx_phy_cmd(struct iwm_softc *,
    364   1.4   nonaka 		    struct iwm_rx_packet *, struct iwm_rx_data *);
    365  1.45   nonaka static int	iwm_get_noise(const struct iwm_statistics_rx_non_phy *);
    366  1.45   nonaka static void	iwm_rx_rx_mpdu(struct iwm_softc *, struct iwm_rx_packet *,
    367   1.4   nonaka 		    struct iwm_rx_data *);
    368  1.45   nonaka static void	iwm_rx_tx_cmd_single(struct iwm_softc *, struct iwm_rx_packet *,		    struct iwm_node *);
    369  1.45   nonaka static void	iwm_rx_tx_cmd(struct iwm_softc *, struct iwm_rx_packet *,
    370   1.4   nonaka 		    struct iwm_rx_data *);
    371  1.45   nonaka static int	iwm_binding_cmd(struct iwm_softc *, struct iwm_node *,
    372   1.4   nonaka 		    uint32_t);
    373  1.45   nonaka #if 0
    374  1.45   nonaka static int	iwm_binding_update(struct iwm_softc *, struct iwm_node *, int);
    375  1.45   nonaka static int	iwm_binding_add_vif(struct iwm_softc *, struct iwm_node *);
    376  1.45   nonaka #endif
    377  1.45   nonaka static void	iwm_phy_ctxt_cmd_hdr(struct iwm_softc *, struct iwm_phy_ctxt *,
    378  1.45   nonaka 		    struct iwm_phy_context_cmd *, uint32_t, uint32_t);
    379  1.45   nonaka static void	iwm_phy_ctxt_cmd_data(struct iwm_softc *,
    380   1.4   nonaka 		    struct iwm_phy_context_cmd *, struct ieee80211_channel *,
    381   1.4   nonaka 		    uint8_t, uint8_t);
    382  1.45   nonaka static int	iwm_phy_ctxt_cmd(struct iwm_softc *, struct iwm_phy_ctxt *,
    383  1.45   nonaka 		    uint8_t, uint8_t, uint32_t, uint32_t);
    384   1.4   nonaka static int	iwm_send_cmd(struct iwm_softc *, struct iwm_host_cmd *);
    385  1.45   nonaka static int	iwm_send_cmd_pdu(struct iwm_softc *, uint32_t, uint32_t,
    386   1.4   nonaka 		    uint16_t, const void *);
    387  1.45   nonaka static int	iwm_send_cmd_status(struct iwm_softc *, struct iwm_host_cmd *,
    388  1.45   nonaka 		    uint32_t *);
    389  1.45   nonaka static int	iwm_send_cmd_pdu_status(struct iwm_softc *, uint32_t, uint16_t,
    390  1.45   nonaka 		    const void *, uint32_t *);
    391   1.4   nonaka static void	iwm_free_resp(struct iwm_softc *, struct iwm_host_cmd *);
    392  1.45   nonaka static void	iwm_cmd_done(struct iwm_softc *, int qid, int idx);
    393   1.4   nonaka #if 0
    394   1.4   nonaka static void	iwm_update_sched(struct iwm_softc *, int, int, uint8_t,
    395   1.4   nonaka 		    uint16_t);
    396   1.4   nonaka #endif
    397  1.45   nonaka static const struct iwm_rate *
    398  1.45   nonaka 		iwm_tx_fill_cmd(struct iwm_softc *, struct iwm_node *,
    399  1.45   nonaka 		    struct ieee80211_frame *, struct iwm_tx_cmd *);
    400   1.4   nonaka static int	iwm_tx(struct iwm_softc *, struct mbuf *,
    401   1.4   nonaka 		    struct ieee80211_node *, int);
    402  1.45   nonaka static void	iwm_led_enable(struct iwm_softc *);
    403  1.45   nonaka static void	iwm_led_disable(struct iwm_softc *);
    404  1.45   nonaka static int	iwm_led_is_enabled(struct iwm_softc *);
    405  1.45   nonaka static void	iwm_led_blink_timeout(void *);
    406  1.45   nonaka static void	iwm_led_blink_start(struct iwm_softc *);
    407  1.45   nonaka static void	iwm_led_blink_stop(struct iwm_softc *);
    408  1.45   nonaka static int	iwm_beacon_filter_send_cmd(struct iwm_softc *,
    409   1.4   nonaka 		    struct iwm_beacon_filter_cmd *);
    410  1.45   nonaka static void	iwm_beacon_filter_set_cqm_params(struct iwm_softc *,
    411   1.4   nonaka 		    struct iwm_node *, struct iwm_beacon_filter_cmd *);
    412  1.45   nonaka static int	iwm_update_beacon_abort(struct iwm_softc *, struct iwm_node *,
    413  1.45   nonaka 		    int);
    414  1.45   nonaka static void	iwm_power_build_cmd(struct iwm_softc *, struct iwm_node *,
    415   1.4   nonaka 		    struct iwm_mac_power_cmd *);
    416  1.45   nonaka static int	iwm_power_mac_update_mode(struct iwm_softc *,
    417   1.4   nonaka 		    struct iwm_node *);
    418  1.45   nonaka static int	iwm_power_update_device(struct iwm_softc *);
    419  1.45   nonaka #ifdef notyet
    420  1.45   nonaka static int	iwm_enable_beacon_filter(struct iwm_softc *, struct iwm_node *);
    421  1.45   nonaka #endif
    422  1.45   nonaka static int	iwm_disable_beacon_filter(struct iwm_softc *);
    423  1.45   nonaka static int	iwm_add_sta_cmd(struct iwm_softc *, struct iwm_node *, int);
    424  1.45   nonaka static int	iwm_add_aux_sta(struct iwm_softc *);
    425  1.45   nonaka static uint16_t iwm_scan_rx_chain(struct iwm_softc *);
    426  1.45   nonaka static uint32_t iwm_scan_rate_n_flags(struct iwm_softc *, int, int);
    427  1.45   nonaka #ifdef notyet
    428  1.45   nonaka static uint16_t iwm_get_active_dwell(struct iwm_softc *, int, int);
    429  1.45   nonaka static uint16_t iwm_get_passive_dwell(struct iwm_softc *, int);
    430  1.45   nonaka #endif
    431  1.45   nonaka static uint8_t	iwm_lmac_scan_fill_channels(struct iwm_softc *,
    432  1.45   nonaka 		    struct iwm_scan_channel_cfg_lmac *, int);
    433  1.45   nonaka static int	iwm_fill_probe_req(struct iwm_softc *,
    434  1.45   nonaka 		    struct iwm_scan_probe_req *);
    435  1.45   nonaka static int	iwm_lmac_scan(struct iwm_softc *);
    436  1.45   nonaka static int	iwm_config_umac_scan(struct iwm_softc *);
    437  1.45   nonaka static int	iwm_umac_scan(struct iwm_softc *);
    438  1.45   nonaka static uint8_t	iwm_ridx2rate(struct ieee80211_rateset *, int);
    439  1.45   nonaka static void	iwm_ack_rates(struct iwm_softc *, struct iwm_node *, int *,
    440   1.4   nonaka 		    int *);
    441  1.45   nonaka static void	iwm_mac_ctxt_cmd_common(struct iwm_softc *, struct iwm_node *,
    442  1.45   nonaka 		    struct iwm_mac_ctx_cmd *, uint32_t, int);
    443  1.45   nonaka static void	iwm_mac_ctxt_cmd_fill_sta(struct iwm_softc *, struct iwm_node *,
    444  1.45   nonaka 		    struct iwm_mac_data_sta *, int);
    445  1.45   nonaka static int	iwm_mac_ctxt_cmd(struct iwm_softc *, struct iwm_node *,
    446  1.45   nonaka 		    uint32_t, int);
    447  1.45   nonaka static int	iwm_update_quotas(struct iwm_softc *, struct iwm_node *);
    448   1.4   nonaka static int	iwm_auth(struct iwm_softc *);
    449   1.4   nonaka static int	iwm_assoc(struct iwm_softc *);
    450   1.4   nonaka static void	iwm_calib_timeout(void *);
    451  1.45   nonaka #ifndef IEEE80211_NO_HT
    452  1.45   nonaka static void	iwm_setrates_task(void *);
    453  1.45   nonaka static int	iwm_setrates(struct iwm_node *);
    454  1.45   nonaka #endif
    455   1.4   nonaka static int	iwm_media_change(struct ifnet *);
    456  1.65   nonaka static int	iwm_do_newstate(struct ieee80211com *, enum ieee80211_state,
    457  1.65   nonaka 		    int);
    458   1.5   nonaka static void	iwm_newstate_cb(struct work *, void *);
    459   1.4   nonaka static int	iwm_newstate(struct ieee80211com *, enum ieee80211_state, int);
    460  1.50   nonaka static void	iwm_endscan(struct iwm_softc *);
    461  1.45   nonaka static void	iwm_fill_sf_command(struct iwm_softc *, struct iwm_sf_cfg_cmd *,
    462  1.45   nonaka 		    struct ieee80211_node *);
    463  1.45   nonaka static int	iwm_sf_config(struct iwm_softc *, int);
    464  1.45   nonaka static int	iwm_send_bt_init_conf(struct iwm_softc *);
    465  1.45   nonaka static int	iwm_send_update_mcc_cmd(struct iwm_softc *, const char *);
    466  1.45   nonaka static void	iwm_tt_tx_backoff(struct iwm_softc *, uint32_t);
    467   1.4   nonaka static int	iwm_init_hw(struct iwm_softc *);
    468   1.4   nonaka static int	iwm_init(struct ifnet *);
    469   1.4   nonaka static void	iwm_start(struct ifnet *);
    470   1.4   nonaka static void	iwm_stop(struct ifnet *, int);
    471   1.4   nonaka static void	iwm_watchdog(struct ifnet *);
    472   1.4   nonaka static int	iwm_ioctl(struct ifnet *, u_long, void *);
    473   1.4   nonaka #ifdef IWM_DEBUG
    474   1.4   nonaka static const char *iwm_desc_lookup(uint32_t);
    475   1.4   nonaka static void	iwm_nic_error(struct iwm_softc *);
    476  1.45   nonaka static void	iwm_nic_umac_error(struct iwm_softc *);
    477   1.4   nonaka #endif
    478   1.4   nonaka static void	iwm_notif_intr(struct iwm_softc *);
    479  1.61   nonaka static int	iwm_intr(void *);
    480  1.50   nonaka static void	iwm_softintr(void *);
    481   1.4   nonaka static int	iwm_preinit(struct iwm_softc *);
    482   1.4   nonaka static void	iwm_attach_hook(device_t);
    483   1.4   nonaka static void	iwm_attach(device_t, device_t, void *);
    484   1.4   nonaka #if 0
    485   1.4   nonaka static void	iwm_init_task(void *);
    486   1.4   nonaka static int	iwm_activate(device_t, enum devact);
    487   1.4   nonaka static void	iwm_wakeup(struct iwm_softc *);
    488   1.4   nonaka #endif
    489   1.4   nonaka static void	iwm_radiotap_attach(struct iwm_softc *);
    490  1.36   nonaka static int	iwm_sysctl_fw_loaded_handler(SYSCTLFN_PROTO);
    491  1.36   nonaka 
    492  1.36   nonaka static int iwm_sysctl_root_num;
    493  1.60   nonaka static int iwm_lar_disable;
    494   1.1    pooka 
    495  1.61   nonaka #ifndef	IWM_DEFAULT_MCC
    496  1.61   nonaka #define	IWM_DEFAULT_MCC	"ZZ"
    497  1.61   nonaka #endif
    498  1.61   nonaka static char iwm_default_mcc[3] = IWM_DEFAULT_MCC;
    499  1.61   nonaka 
    500   1.1    pooka static int
    501   1.1    pooka iwm_firmload(struct iwm_softc *sc)
    502   1.1    pooka {
    503   1.1    pooka 	struct iwm_fw_info *fw = &sc->sc_fw;
    504   1.1    pooka 	firmware_handle_t fwh;
    505  1.45   nonaka 	int err;
    506   1.1    pooka 
    507  1.36   nonaka 	if (ISSET(sc->sc_flags, IWM_FLAG_FW_LOADED))
    508  1.36   nonaka 		return 0;
    509  1.36   nonaka 
    510   1.1    pooka 	/* Open firmware image. */
    511  1.45   nonaka 	err = firmware_open("if_iwm", sc->sc_fwname, &fwh);
    512  1.45   nonaka 	if (err) {
    513   1.1    pooka 		aprint_error_dev(sc->sc_dev,
    514   1.1    pooka 		    "could not get firmware handle %s\n", sc->sc_fwname);
    515  1.45   nonaka 		return err;
    516   1.1    pooka 	}
    517   1.1    pooka 
    518  1.36   nonaka 	if (fw->fw_rawdata != NULL && fw->fw_rawsize > 0) {
    519  1.36   nonaka 		kmem_free(fw->fw_rawdata, fw->fw_rawsize);
    520  1.36   nonaka 		fw->fw_rawdata = NULL;
    521  1.36   nonaka 	}
    522  1.36   nonaka 
    523   1.1    pooka 	fw->fw_rawsize = firmware_get_size(fwh);
    524   1.1    pooka 	/*
    525   1.1    pooka 	 * Well, this is how the Linux driver checks it ....
    526   1.1    pooka 	 */
    527   1.1    pooka 	if (fw->fw_rawsize < sizeof(uint32_t)) {
    528   1.1    pooka 		aprint_error_dev(sc->sc_dev,
    529   1.1    pooka 		    "firmware too short: %zd bytes\n", fw->fw_rawsize);
    530  1.45   nonaka 		err = EINVAL;
    531   1.1    pooka 		goto out;
    532   1.1    pooka 	}
    533   1.1    pooka 
    534   1.1    pooka 	/* Read the firmware. */
    535   1.1    pooka 	fw->fw_rawdata = kmem_alloc(fw->fw_rawsize, KM_SLEEP);
    536   1.1    pooka 	if (fw->fw_rawdata == NULL) {
    537   1.1    pooka 		aprint_error_dev(sc->sc_dev,
    538   1.1    pooka 		    "not enough memory to stock firmware %s\n", sc->sc_fwname);
    539  1.45   nonaka 		err = ENOMEM;
    540   1.1    pooka 		goto out;
    541   1.1    pooka 	}
    542  1.45   nonaka 	err = firmware_read(fwh, 0, fw->fw_rawdata, fw->fw_rawsize);
    543  1.45   nonaka 	if (err) {
    544   1.1    pooka 		aprint_error_dev(sc->sc_dev,
    545   1.1    pooka 		    "could not read firmware %s\n", sc->sc_fwname);
    546   1.1    pooka 		goto out;
    547   1.1    pooka 	}
    548   1.1    pooka 
    549  1.36   nonaka 	SET(sc->sc_flags, IWM_FLAG_FW_LOADED);
    550   1.1    pooka  out:
    551   1.1    pooka 	/* caller will release memory, if necessary */
    552   1.1    pooka 
    553   1.1    pooka 	firmware_close(fwh);
    554  1.45   nonaka 	return err;
    555   1.1    pooka }
    556   1.1    pooka 
    557   1.1    pooka /*
    558   1.1    pooka  * just maintaining status quo.
    559   1.1    pooka  */
    560   1.1    pooka static void
    561  1.45   nonaka iwm_fix_channel(struct iwm_softc *sc, struct mbuf *m)
    562   1.1    pooka {
    563  1.45   nonaka 	struct ieee80211com *ic = &sc->sc_ic;
    564   1.1    pooka 	struct ieee80211_frame *wh;
    565   1.1    pooka 	uint8_t subtype;
    566   1.1    pooka 
    567   1.1    pooka 	wh = mtod(m, struct ieee80211_frame *);
    568   1.1    pooka 
    569   1.1    pooka 	if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_MGT)
    570   1.1    pooka 		return;
    571   1.1    pooka 
    572   1.1    pooka 	subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
    573   1.1    pooka 
    574   1.1    pooka 	if (subtype != IEEE80211_FC0_SUBTYPE_BEACON &&
    575   1.1    pooka 	    subtype != IEEE80211_FC0_SUBTYPE_PROBE_RESP)
    576   1.1    pooka 		return;
    577   1.1    pooka 
    578  1.45   nonaka 	int chan = le32toh(sc->sc_last_phy_info.channel);
    579  1.45   nonaka 	if (chan < __arraycount(ic->ic_channels))
    580  1.45   nonaka 		ic->ic_curchan = &ic->ic_channels[chan];
    581   1.1    pooka }
    582   1.1    pooka 
    583   1.4   nonaka static int
    584   1.1    pooka iwm_store_cscheme(struct iwm_softc *sc, uint8_t *data, size_t dlen)
    585   1.1    pooka {
    586  1.45   nonaka 	struct iwm_fw_cscheme_list *l = (struct iwm_fw_cscheme_list *)data;
    587   1.1    pooka 
    588   1.1    pooka 	if (dlen < sizeof(*l) ||
    589   1.1    pooka 	    dlen < sizeof(l->size) + l->size * sizeof(*l->cs))
    590   1.1    pooka 		return EINVAL;
    591   1.1    pooka 
    592   1.1    pooka 	/* we don't actually store anything for now, always use s/w crypto */
    593   1.1    pooka 
    594   1.1    pooka 	return 0;
    595   1.1    pooka }
    596   1.1    pooka 
    597   1.4   nonaka static int
    598  1.45   nonaka iwm_firmware_store_section(struct iwm_softc *sc, enum iwm_ucode_type type,
    599  1.45   nonaka     uint8_t *data, size_t dlen)
    600   1.1    pooka {
    601   1.1    pooka 	struct iwm_fw_sects *fws;
    602   1.1    pooka 	struct iwm_fw_onesect *fwone;
    603   1.1    pooka 
    604   1.1    pooka 	if (type >= IWM_UCODE_TYPE_MAX)
    605   1.1    pooka 		return EINVAL;
    606   1.1    pooka 	if (dlen < sizeof(uint32_t))
    607   1.1    pooka 		return EINVAL;
    608   1.1    pooka 
    609   1.1    pooka 	fws = &sc->sc_fw.fw_sects[type];
    610   1.1    pooka 	if (fws->fw_count >= IWM_UCODE_SECT_MAX)
    611   1.1    pooka 		return EINVAL;
    612   1.1    pooka 
    613   1.1    pooka 	fwone = &fws->fw_sect[fws->fw_count];
    614   1.1    pooka 
    615   1.1    pooka 	/* first 32bit are device load offset */
    616   1.1    pooka 	memcpy(&fwone->fws_devoff, data, sizeof(uint32_t));
    617   1.1    pooka 
    618   1.1    pooka 	/* rest is data */
    619   1.1    pooka 	fwone->fws_data = data + sizeof(uint32_t);
    620   1.1    pooka 	fwone->fws_len = dlen - sizeof(uint32_t);
    621   1.1    pooka 
    622   1.1    pooka 	/* for freeing the buffer during driver unload */
    623   1.1    pooka 	fwone->fws_alloc = data;
    624   1.1    pooka 	fwone->fws_allocsize = dlen;
    625   1.1    pooka 
    626   1.1    pooka 	fws->fw_count++;
    627   1.1    pooka 	fws->fw_totlen += fwone->fws_len;
    628   1.1    pooka 
    629   1.1    pooka 	return 0;
    630   1.1    pooka }
    631   1.1    pooka 
    632   1.1    pooka struct iwm_tlv_calib_data {
    633   1.1    pooka 	uint32_t ucode_type;
    634   1.1    pooka 	struct iwm_tlv_calib_ctrl calib;
    635   1.1    pooka } __packed;
    636   1.1    pooka 
    637   1.4   nonaka static int
    638   1.1    pooka iwm_set_default_calib(struct iwm_softc *sc, const void *data)
    639   1.1    pooka {
    640   1.1    pooka 	const struct iwm_tlv_calib_data *def_calib = data;
    641   1.1    pooka 	uint32_t ucode_type = le32toh(def_calib->ucode_type);
    642   1.1    pooka 
    643   1.1    pooka 	if (ucode_type >= IWM_UCODE_TYPE_MAX) {
    644  1.45   nonaka 		DPRINTF(("%s: Wrong ucode_type %u for default calibration.\n",
    645  1.45   nonaka 		    DEVNAME(sc), ucode_type));
    646   1.1    pooka 		return EINVAL;
    647   1.1    pooka 	}
    648   1.1    pooka 
    649   1.1    pooka 	sc->sc_default_calib[ucode_type].flow_trigger =
    650   1.1    pooka 	    def_calib->calib.flow_trigger;
    651   1.1    pooka 	sc->sc_default_calib[ucode_type].event_trigger =
    652   1.1    pooka 	    def_calib->calib.event_trigger;
    653   1.1    pooka 
    654   1.1    pooka 	return 0;
    655   1.1    pooka }
    656   1.1    pooka 
    657   1.4   nonaka static int
    658  1.61   nonaka iwm_read_firmware(struct iwm_softc *sc, enum iwm_ucode_type ucode_type)
    659   1.1    pooka {
    660   1.1    pooka 	struct iwm_fw_info *fw = &sc->sc_fw;
    661   1.8   nonaka 	struct iwm_tlv_ucode_header *uhdr;
    662   1.8   nonaka 	struct iwm_ucode_tlv tlv;
    663   1.1    pooka 	enum iwm_ucode_tlv_type tlv_type;
    664   1.1    pooka 	uint8_t *data;
    665  1.45   nonaka 	int err, status;
    666   1.2   nonaka 	size_t len;
    667   1.1    pooka 
    668  1.61   nonaka 	if (ucode_type != IWM_UCODE_TYPE_INIT &&
    669  1.61   nonaka 	    fw->fw_status == IWM_FW_STATUS_DONE)
    670  1.61   nonaka 		return 0;
    671  1.61   nonaka 
    672   1.1    pooka 	if (fw->fw_status == IWM_FW_STATUS_NONE) {
    673   1.1    pooka 		fw->fw_status = IWM_FW_STATUS_INPROGRESS;
    674   1.1    pooka 	} else {
    675   1.1    pooka 		while (fw->fw_status == IWM_FW_STATUS_INPROGRESS)
    676   1.1    pooka 			tsleep(&sc->sc_fw, 0, "iwmfwp", 0);
    677   1.1    pooka 	}
    678   1.1    pooka 	status = fw->fw_status;
    679   1.1    pooka 
    680   1.1    pooka 	if (status == IWM_FW_STATUS_DONE)
    681   1.1    pooka 		return 0;
    682   1.1    pooka 
    683  1.45   nonaka 	err = iwm_firmload(sc);
    684  1.45   nonaka 	if (err) {
    685   1.3   nonaka 		aprint_error_dev(sc->sc_dev,
    686   1.3   nonaka 		    "could not read firmware %s (error %d)\n",
    687  1.45   nonaka 		    sc->sc_fwname, err);
    688   1.1    pooka 		goto out;
    689   1.1    pooka 	}
    690   1.1    pooka 
    691  1.45   nonaka 	sc->sc_capaflags = 0;
    692  1.45   nonaka 	sc->sc_capa_n_scan_channels = IWM_MAX_NUM_SCAN_CHANNELS;
    693  1.45   nonaka 	memset(sc->sc_enabled_capa, 0, sizeof(sc->sc_enabled_capa));
    694  1.45   nonaka 	memset(sc->sc_fw_mcc, 0, sizeof(sc->sc_fw_mcc));
    695   1.1    pooka 
    696   1.1    pooka 	uhdr = (void *)fw->fw_rawdata;
    697   1.1    pooka 	if (*(uint32_t *)fw->fw_rawdata != 0
    698   1.1    pooka 	    || le32toh(uhdr->magic) != IWM_TLV_UCODE_MAGIC) {
    699   1.3   nonaka 		aprint_error_dev(sc->sc_dev, "invalid firmware %s\n",
    700   1.3   nonaka 		    sc->sc_fwname);
    701  1.45   nonaka 		err = EINVAL;
    702   1.1    pooka 		goto out;
    703   1.1    pooka 	}
    704   1.1    pooka 
    705  1.45   nonaka 	snprintf(sc->sc_fwver, sizeof(sc->sc_fwver), "%d.%d (API ver %d)",
    706  1.45   nonaka 	    IWM_UCODE_MAJOR(le32toh(uhdr->ver)),
    707  1.45   nonaka 	    IWM_UCODE_MINOR(le32toh(uhdr->ver)),
    708  1.45   nonaka 	    IWM_UCODE_API(le32toh(uhdr->ver)));
    709   1.1    pooka 	data = uhdr->data;
    710   1.1    pooka 	len = fw->fw_rawsize - sizeof(*uhdr);
    711   1.1    pooka 
    712   1.1    pooka 	while (len >= sizeof(tlv)) {
    713   1.2   nonaka 		size_t tlv_len;
    714   1.1    pooka 		void *tlv_data;
    715   1.1    pooka 
    716   1.1    pooka 		memcpy(&tlv, data, sizeof(tlv));
    717   1.1    pooka 		tlv_len = le32toh(tlv.length);
    718   1.1    pooka 		tlv_type = le32toh(tlv.type);
    719   1.1    pooka 
    720   1.1    pooka 		len -= sizeof(tlv);
    721   1.1    pooka 		data += sizeof(tlv);
    722   1.1    pooka 		tlv_data = data;
    723   1.1    pooka 
    724   1.1    pooka 		if (len < tlv_len) {
    725   1.3   nonaka 			aprint_error_dev(sc->sc_dev,
    726   1.3   nonaka 			    "firmware too short: %zu bytes\n", len);
    727  1.45   nonaka 			err = EINVAL;
    728   1.1    pooka 			goto parse_out;
    729   1.1    pooka 		}
    730   1.1    pooka 
    731  1.45   nonaka 		switch (tlv_type) {
    732   1.1    pooka 		case IWM_UCODE_TLV_PROBE_MAX_LEN:
    733   1.1    pooka 			if (tlv_len < sizeof(uint32_t)) {
    734  1.45   nonaka 				err = EINVAL;
    735   1.1    pooka 				goto parse_out;
    736   1.1    pooka 			}
    737   1.1    pooka 			sc->sc_capa_max_probe_len
    738   1.1    pooka 			    = le32toh(*(uint32_t *)tlv_data);
    739   1.1    pooka 			/* limit it to something sensible */
    740  1.45   nonaka 			if (sc->sc_capa_max_probe_len >
    741  1.45   nonaka 			    IWM_SCAN_OFFLOAD_PROBE_REQ_SIZE) {
    742  1.45   nonaka 				err = EINVAL;
    743   1.1    pooka 				goto parse_out;
    744   1.1    pooka 			}
    745   1.1    pooka 			break;
    746   1.1    pooka 		case IWM_UCODE_TLV_PAN:
    747   1.1    pooka 			if (tlv_len) {
    748  1.45   nonaka 				err = EINVAL;
    749   1.1    pooka 				goto parse_out;
    750   1.1    pooka 			}
    751   1.1    pooka 			sc->sc_capaflags |= IWM_UCODE_TLV_FLAGS_PAN;
    752   1.1    pooka 			break;
    753   1.1    pooka 		case IWM_UCODE_TLV_FLAGS:
    754   1.1    pooka 			if (tlv_len < sizeof(uint32_t)) {
    755  1.45   nonaka 				err = EINVAL;
    756   1.1    pooka 				goto parse_out;
    757   1.1    pooka 			}
    758   1.1    pooka 			/*
    759   1.1    pooka 			 * Apparently there can be many flags, but Linux driver
    760   1.1    pooka 			 * parses only the first one, and so do we.
    761   1.1    pooka 			 *
    762   1.1    pooka 			 * XXX: why does this override IWM_UCODE_TLV_PAN?
    763   1.1    pooka 			 * Intentional or a bug?  Observations from
    764   1.1    pooka 			 * current firmware file:
    765   1.1    pooka 			 *  1) TLV_PAN is parsed first
    766   1.1    pooka 			 *  2) TLV_FLAGS contains TLV_FLAGS_PAN
    767   1.1    pooka 			 * ==> this resets TLV_PAN to itself... hnnnk
    768   1.1    pooka 			 */
    769   1.1    pooka 			sc->sc_capaflags = le32toh(*(uint32_t *)tlv_data);
    770   1.1    pooka 			break;
    771   1.1    pooka 		case IWM_UCODE_TLV_CSCHEME:
    772  1.45   nonaka 			err = iwm_store_cscheme(sc, tlv_data, tlv_len);
    773  1.45   nonaka 			if (err)
    774   1.1    pooka 				goto parse_out;
    775   1.1    pooka 			break;
    776  1.45   nonaka 		case IWM_UCODE_TLV_NUM_OF_CPU: {
    777  1.45   nonaka 			uint32_t num_cpu;
    778   1.1    pooka 			if (tlv_len != sizeof(uint32_t)) {
    779  1.45   nonaka 				err = EINVAL;
    780   1.1    pooka 				goto parse_out;
    781   1.1    pooka 			}
    782  1.45   nonaka 			num_cpu = le32toh(*(uint32_t *)tlv_data);
    783  1.45   nonaka 			if (num_cpu < 1 || num_cpu > 2) {
    784  1.45   nonaka 				err = EINVAL;
    785   1.1    pooka 				goto parse_out;
    786   1.1    pooka 			}
    787   1.1    pooka 			break;
    788  1.45   nonaka 		}
    789   1.1    pooka 		case IWM_UCODE_TLV_SEC_RT:
    790  1.45   nonaka 			err = iwm_firmware_store_section(sc,
    791  1.45   nonaka 			    IWM_UCODE_TYPE_REGULAR, tlv_data, tlv_len);
    792  1.45   nonaka 			if (err)
    793   1.1    pooka 				goto parse_out;
    794   1.1    pooka 			break;
    795   1.1    pooka 		case IWM_UCODE_TLV_SEC_INIT:
    796  1.45   nonaka 			err = iwm_firmware_store_section(sc,
    797  1.45   nonaka 			    IWM_UCODE_TYPE_INIT, tlv_data, tlv_len);
    798  1.45   nonaka 			if (err)
    799   1.1    pooka 				goto parse_out;
    800   1.1    pooka 			break;
    801   1.1    pooka 		case IWM_UCODE_TLV_SEC_WOWLAN:
    802  1.45   nonaka 			err = iwm_firmware_store_section(sc,
    803  1.45   nonaka 			    IWM_UCODE_TYPE_WOW, tlv_data, tlv_len);
    804  1.45   nonaka 			if (err)
    805   1.1    pooka 				goto parse_out;
    806   1.1    pooka 			break;
    807   1.1    pooka 		case IWM_UCODE_TLV_DEF_CALIB:
    808   1.1    pooka 			if (tlv_len != sizeof(struct iwm_tlv_calib_data)) {
    809  1.45   nonaka 				err = EINVAL;
    810   1.1    pooka 				goto parse_out;
    811   1.1    pooka 			}
    812  1.45   nonaka 			err = iwm_set_default_calib(sc, tlv_data);
    813  1.45   nonaka 			if (err)
    814   1.1    pooka 				goto parse_out;
    815   1.1    pooka 			break;
    816   1.1    pooka 		case IWM_UCODE_TLV_PHY_SKU:
    817   1.1    pooka 			if (tlv_len != sizeof(uint32_t)) {
    818  1.45   nonaka 				err = EINVAL;
    819   1.1    pooka 				goto parse_out;
    820   1.1    pooka 			}
    821   1.1    pooka 			sc->sc_fw_phy_config = le32toh(*(uint32_t *)tlv_data);
    822   1.1    pooka 			break;
    823   1.1    pooka 
    824  1.45   nonaka 		case IWM_UCODE_TLV_API_CHANGES_SET: {
    825  1.45   nonaka 			struct iwm_ucode_api *api;
    826  1.45   nonaka 			if (tlv_len != sizeof(*api)) {
    827  1.45   nonaka 				err = EINVAL;
    828  1.45   nonaka 				goto parse_out;
    829  1.45   nonaka 			}
    830  1.45   nonaka 			api = (struct iwm_ucode_api *)tlv_data;
    831  1.45   nonaka 			/* Flags may exceed 32 bits in future firmware. */
    832  1.45   nonaka 			if (le32toh(api->api_index) > 0) {
    833  1.61   nonaka 				err = EINVAL;
    834  1.45   nonaka 				goto parse_out;
    835  1.45   nonaka 			}
    836  1.45   nonaka 			sc->sc_ucode_api = le32toh(api->api_flags);
    837  1.45   nonaka 			break;
    838  1.45   nonaka 		}
    839  1.45   nonaka 
    840  1.45   nonaka 		case IWM_UCODE_TLV_ENABLED_CAPABILITIES: {
    841  1.45   nonaka 			struct iwm_ucode_capa *capa;
    842  1.45   nonaka 			int idx, i;
    843  1.45   nonaka 			if (tlv_len != sizeof(*capa)) {
    844  1.45   nonaka 				err = EINVAL;
    845  1.45   nonaka 				goto parse_out;
    846  1.45   nonaka 			}
    847  1.45   nonaka 			capa = (struct iwm_ucode_capa *)tlv_data;
    848  1.45   nonaka 			idx = le32toh(capa->api_index);
    849  1.45   nonaka 			if (idx >= howmany(IWM_NUM_UCODE_TLV_CAPA, 32)) {
    850  1.61   nonaka 				err = EINVAL;
    851  1.45   nonaka 				goto parse_out;
    852  1.45   nonaka 			}
    853  1.45   nonaka 			for (i = 0; i < 32; i++) {
    854  1.45   nonaka 				if (!ISSET(le32toh(capa->api_capa), __BIT(i)))
    855  1.45   nonaka 					continue;
    856  1.45   nonaka 				setbit(sc->sc_enabled_capa, i + (32 * idx));
    857  1.45   nonaka 			}
    858  1.45   nonaka 			break;
    859  1.45   nonaka 		}
    860  1.45   nonaka 
    861  1.45   nonaka 		case IWM_UCODE_TLV_FW_UNDOCUMENTED1:
    862  1.45   nonaka 		case IWM_UCODE_TLV_SDIO_ADMA_ADDR:
    863  1.45   nonaka 		case IWM_UCODE_TLV_FW_GSCAN_CAPA:
    864   1.1    pooka 			/* ignore, not used by current driver */
    865   1.1    pooka 			break;
    866   1.1    pooka 
    867  1.45   nonaka 		case IWM_UCODE_TLV_SEC_RT_USNIFFER:
    868  1.45   nonaka 			err = iwm_firmware_store_section(sc,
    869  1.45   nonaka 			    IWM_UCODE_TYPE_REGULAR_USNIFFER, tlv_data,
    870  1.45   nonaka 			    tlv_len);
    871  1.45   nonaka 			if (err)
    872  1.45   nonaka 				goto parse_out;
    873  1.45   nonaka 			break;
    874  1.45   nonaka 
    875  1.45   nonaka 		case IWM_UCODE_TLV_N_SCAN_CHANNELS:
    876  1.45   nonaka 			if (tlv_len != sizeof(uint32_t)) {
    877  1.45   nonaka 				err = EINVAL;
    878  1.45   nonaka 				goto parse_out;
    879  1.45   nonaka 			}
    880  1.45   nonaka 			sc->sc_capa_n_scan_channels =
    881  1.45   nonaka 			  le32toh(*(uint32_t *)tlv_data);
    882  1.45   nonaka 			break;
    883  1.45   nonaka 
    884  1.45   nonaka 		case IWM_UCODE_TLV_FW_VERSION:
    885  1.45   nonaka 			if (tlv_len != sizeof(uint32_t) * 3) {
    886  1.45   nonaka 				err = EINVAL;
    887  1.45   nonaka 				goto parse_out;
    888  1.45   nonaka 			}
    889  1.45   nonaka 			snprintf(sc->sc_fwver, sizeof(sc->sc_fwver),
    890  1.45   nonaka 			    "%d.%d.%d",
    891  1.45   nonaka 			    le32toh(((uint32_t *)tlv_data)[0]),
    892  1.45   nonaka 			    le32toh(((uint32_t *)tlv_data)[1]),
    893  1.45   nonaka 			    le32toh(((uint32_t *)tlv_data)[2]));
    894  1.45   nonaka 			break;
    895  1.45   nonaka 
    896   1.1    pooka 		default:
    897   1.2   nonaka 			DPRINTF(("%s: unknown firmware section %d, abort\n",
    898   1.2   nonaka 			    DEVNAME(sc), tlv_type));
    899  1.45   nonaka 			err = EINVAL;
    900   1.1    pooka 			goto parse_out;
    901   1.1    pooka 		}
    902   1.1    pooka 
    903   1.1    pooka 		len -= roundup(tlv_len, 4);
    904   1.1    pooka 		data += roundup(tlv_len, 4);
    905   1.1    pooka 	}
    906   1.1    pooka 
    907  1.45   nonaka 	KASSERT(err == 0);
    908   1.1    pooka 
    909   1.1    pooka  parse_out:
    910  1.45   nonaka 	if (err) {
    911   1.3   nonaka 		aprint_error_dev(sc->sc_dev,
    912   1.3   nonaka 		    "firmware parse error, section type %d\n", tlv_type);
    913   1.1    pooka 	}
    914   1.1    pooka 
    915   1.1    pooka 	if (!(sc->sc_capaflags & IWM_UCODE_TLV_FLAGS_PM_CMD_SUPPORT)) {
    916   1.3   nonaka 		aprint_error_dev(sc->sc_dev,
    917   1.3   nonaka 		    "device uses unsupported power ops\n");
    918  1.45   nonaka 		err = ENOTSUP;
    919   1.1    pooka 	}
    920   1.1    pooka 
    921   1.1    pooka  out:
    922  1.45   nonaka 	if (err)
    923   1.2   nonaka 		fw->fw_status = IWM_FW_STATUS_NONE;
    924   1.2   nonaka 	else
    925   1.1    pooka 		fw->fw_status = IWM_FW_STATUS_DONE;
    926   1.1    pooka 	wakeup(&sc->sc_fw);
    927   1.1    pooka 
    928  1.45   nonaka 	if (err && fw->fw_rawdata != NULL) {
    929   1.1    pooka 		kmem_free(fw->fw_rawdata, fw->fw_rawsize);
    930   1.1    pooka 		fw->fw_rawdata = NULL;
    931  1.36   nonaka 		CLR(sc->sc_flags, IWM_FLAG_FW_LOADED);
    932  1.45   nonaka 		/* don't touch fw->fw_status */
    933  1.45   nonaka 		memset(fw->fw_sects, 0, sizeof(fw->fw_sects));
    934   1.1    pooka 	}
    935  1.45   nonaka 	return err;
    936   1.1    pooka }
    937   1.1    pooka 
    938   1.4   nonaka static uint32_t
    939   1.1    pooka iwm_read_prph(struct iwm_softc *sc, uint32_t addr)
    940   1.1    pooka {
    941   1.1    pooka 	IWM_WRITE(sc,
    942   1.1    pooka 	    IWM_HBUS_TARG_PRPH_RADDR, ((addr & 0x000fffff) | (3 << 24)));
    943   1.1    pooka 	IWM_BARRIER_READ_WRITE(sc);
    944   1.1    pooka 	return IWM_READ(sc, IWM_HBUS_TARG_PRPH_RDAT);
    945   1.1    pooka }
    946   1.1    pooka 
    947   1.4   nonaka static void
    948   1.1    pooka iwm_write_prph(struct iwm_softc *sc, uint32_t addr, uint32_t val)
    949   1.1    pooka {
    950   1.1    pooka 	IWM_WRITE(sc,
    951   1.1    pooka 	    IWM_HBUS_TARG_PRPH_WADDR, ((addr & 0x000fffff) | (3 << 24)));
    952   1.1    pooka 	IWM_BARRIER_WRITE(sc);
    953   1.1    pooka 	IWM_WRITE(sc, IWM_HBUS_TARG_PRPH_WDAT, val);
    954   1.1    pooka }
    955   1.1    pooka 
    956   1.4   nonaka #ifdef IWM_DEBUG
    957   1.4   nonaka static int
    958   1.1    pooka iwm_read_mem(struct iwm_softc *sc, uint32_t addr, void *buf, int dwords)
    959   1.1    pooka {
    960  1.53   nonaka 	int offs;
    961   1.1    pooka 	uint32_t *vals = buf;
    962   1.1    pooka 
    963   1.1    pooka 	if (iwm_nic_lock(sc)) {
    964   1.1    pooka 		IWM_WRITE(sc, IWM_HBUS_TARG_MEM_RADDR, addr);
    965   1.1    pooka 		for (offs = 0; offs < dwords; offs++)
    966   1.1    pooka 			vals[offs] = IWM_READ(sc, IWM_HBUS_TARG_MEM_RDAT);
    967   1.1    pooka 		iwm_nic_unlock(sc);
    968  1.53   nonaka 		return 0;
    969   1.1    pooka 	}
    970  1.53   nonaka 	return EBUSY;
    971   1.1    pooka }
    972   1.4   nonaka #endif
    973   1.1    pooka 
    974   1.4   nonaka static int
    975   1.1    pooka iwm_write_mem(struct iwm_softc *sc, uint32_t addr, const void *buf, int dwords)
    976   1.1    pooka {
    977   1.5   nonaka 	int offs;
    978   1.1    pooka 	const uint32_t *vals = buf;
    979   1.1    pooka 
    980   1.1    pooka 	if (iwm_nic_lock(sc)) {
    981   1.1    pooka 		IWM_WRITE(sc, IWM_HBUS_TARG_MEM_WADDR, addr);
    982   1.1    pooka 		/* WADDR auto-increments */
    983   1.1    pooka 		for (offs = 0; offs < dwords; offs++) {
    984   1.1    pooka 			uint32_t val = vals ? vals[offs] : 0;
    985   1.1    pooka 			IWM_WRITE(sc, IWM_HBUS_TARG_MEM_WDAT, val);
    986   1.1    pooka 		}
    987   1.1    pooka 		iwm_nic_unlock(sc);
    988  1.53   nonaka 		return 0;
    989   1.1    pooka 	}
    990  1.53   nonaka 	return EBUSY;
    991   1.1    pooka }
    992   1.1    pooka 
    993   1.4   nonaka static int
    994   1.1    pooka iwm_write_mem32(struct iwm_softc *sc, uint32_t addr, uint32_t val)
    995   1.1    pooka {
    996   1.1    pooka 	return iwm_write_mem(sc, addr, &val, 1);
    997   1.1    pooka }
    998   1.1    pooka 
    999   1.4   nonaka static int
   1000  1.45   nonaka iwm_poll_bit(struct iwm_softc *sc, int reg, uint32_t bits, uint32_t mask,
   1001  1.45   nonaka     int timo)
   1002   1.1    pooka {
   1003   1.1    pooka 	for (;;) {
   1004   1.1    pooka 		if ((IWM_READ(sc, reg) & mask) == (bits & mask)) {
   1005   1.1    pooka 			return 1;
   1006   1.1    pooka 		}
   1007   1.1    pooka 		if (timo < 10) {
   1008   1.1    pooka 			return 0;
   1009   1.1    pooka 		}
   1010   1.1    pooka 		timo -= 10;
   1011   1.1    pooka 		DELAY(10);
   1012   1.1    pooka 	}
   1013   1.1    pooka }
   1014   1.1    pooka 
   1015   1.4   nonaka static int
   1016   1.1    pooka iwm_nic_lock(struct iwm_softc *sc)
   1017   1.1    pooka {
   1018   1.1    pooka 	int rv = 0;
   1019   1.1    pooka 
   1020  1.59   nonaka 	if (sc->sc_cmd_hold_nic_awake)
   1021  1.59   nonaka 		return 1;
   1022  1.59   nonaka 
   1023   1.1    pooka 	IWM_SETBITS(sc, IWM_CSR_GP_CNTRL,
   1024   1.1    pooka 	    IWM_CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
   1025   1.1    pooka 
   1026  1.45   nonaka 	if (sc->sc_device_family == IWM_DEVICE_FAMILY_8000)
   1027  1.45   nonaka 		DELAY(2);
   1028  1.45   nonaka 
   1029   1.1    pooka 	if (iwm_poll_bit(sc, IWM_CSR_GP_CNTRL,
   1030   1.1    pooka 	    IWM_CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
   1031   1.1    pooka 	    IWM_CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY
   1032   1.1    pooka 	     | IWM_CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP, 15000)) {
   1033  1.38    ozaki 		rv = 1;
   1034   1.1    pooka 	} else {
   1035  1.61   nonaka 		aprint_error_dev(sc->sc_dev, "resetting device via NMI\n");
   1036   1.1    pooka 		IWM_WRITE(sc, IWM_CSR_RESET, IWM_CSR_RESET_REG_FLAG_FORCE_NMI);
   1037   1.1    pooka 	}
   1038   1.1    pooka 
   1039   1.1    pooka 	return rv;
   1040   1.1    pooka }
   1041   1.1    pooka 
   1042   1.4   nonaka static void
   1043   1.1    pooka iwm_nic_unlock(struct iwm_softc *sc)
   1044   1.1    pooka {
   1045  1.59   nonaka 
   1046  1.59   nonaka 	if (sc->sc_cmd_hold_nic_awake)
   1047  1.59   nonaka 		return;
   1048  1.59   nonaka 
   1049   1.1    pooka 	IWM_CLRBITS(sc, IWM_CSR_GP_CNTRL,
   1050   1.1    pooka 	    IWM_CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
   1051   1.1    pooka }
   1052   1.1    pooka 
   1053   1.4   nonaka static void
   1054  1.45   nonaka iwm_set_bits_mask_prph(struct iwm_softc *sc, uint32_t reg, uint32_t bits,
   1055  1.45   nonaka     uint32_t mask)
   1056   1.1    pooka {
   1057   1.1    pooka 	uint32_t val;
   1058   1.1    pooka 
   1059   1.1    pooka 	/* XXX: no error path? */
   1060   1.1    pooka 	if (iwm_nic_lock(sc)) {
   1061   1.1    pooka 		val = iwm_read_prph(sc, reg) & mask;
   1062   1.1    pooka 		val |= bits;
   1063   1.1    pooka 		iwm_write_prph(sc, reg, val);
   1064   1.1    pooka 		iwm_nic_unlock(sc);
   1065   1.1    pooka 	}
   1066   1.1    pooka }
   1067   1.1    pooka 
   1068   1.4   nonaka static void
   1069   1.1    pooka iwm_set_bits_prph(struct iwm_softc *sc, uint32_t reg, uint32_t bits)
   1070   1.1    pooka {
   1071   1.1    pooka 	iwm_set_bits_mask_prph(sc, reg, bits, ~0);
   1072   1.1    pooka }
   1073   1.1    pooka 
   1074   1.4   nonaka static void
   1075   1.1    pooka iwm_clear_bits_prph(struct iwm_softc *sc, uint32_t reg, uint32_t bits)
   1076   1.1    pooka {
   1077   1.1    pooka 	iwm_set_bits_mask_prph(sc, reg, 0, ~bits);
   1078   1.1    pooka }
   1079   1.1    pooka 
   1080   1.4   nonaka static int
   1081   1.1    pooka iwm_dma_contig_alloc(bus_dma_tag_t tag, struct iwm_dma_info *dma,
   1082   1.1    pooka     bus_size_t size, bus_size_t alignment)
   1083   1.1    pooka {
   1084  1.45   nonaka 	int nsegs, err;
   1085   1.1    pooka 	void *va;
   1086   1.1    pooka 
   1087   1.1    pooka 	dma->tag = tag;
   1088   1.1    pooka 	dma->size = size;
   1089   1.1    pooka 
   1090  1.45   nonaka 	err = bus_dmamap_create(tag, size, 1, size, 0, BUS_DMA_NOWAIT,
   1091   1.1    pooka 	    &dma->map);
   1092  1.45   nonaka 	if (err)
   1093   1.1    pooka 		goto fail;
   1094   1.1    pooka 
   1095  1.45   nonaka 	err = bus_dmamem_alloc(tag, size, alignment, 0, &dma->seg, 1, &nsegs,
   1096   1.1    pooka 	    BUS_DMA_NOWAIT);
   1097  1.45   nonaka 	if (err)
   1098   1.1    pooka 		goto fail;
   1099   1.1    pooka 
   1100  1.45   nonaka 	err = bus_dmamem_map(tag, &dma->seg, 1, size, &va, BUS_DMA_NOWAIT);
   1101  1.45   nonaka 	if (err)
   1102   1.1    pooka 		goto fail;
   1103   1.1    pooka 	dma->vaddr = va;
   1104   1.1    pooka 
   1105  1.45   nonaka 	err = bus_dmamap_load(tag, dma->map, dma->vaddr, size, NULL,
   1106   1.1    pooka 	    BUS_DMA_NOWAIT);
   1107  1.45   nonaka 	if (err)
   1108   1.1    pooka 		goto fail;
   1109   1.1    pooka 
   1110   1.1    pooka 	memset(dma->vaddr, 0, size);
   1111   1.1    pooka 	bus_dmamap_sync(tag, dma->map, 0, size, BUS_DMASYNC_PREWRITE);
   1112   1.1    pooka 	dma->paddr = dma->map->dm_segs[0].ds_addr;
   1113   1.1    pooka 
   1114   1.1    pooka 	return 0;
   1115   1.1    pooka 
   1116   1.1    pooka fail:	iwm_dma_contig_free(dma);
   1117  1.45   nonaka 	return err;
   1118   1.1    pooka }
   1119   1.1    pooka 
   1120   1.4   nonaka static void
   1121   1.1    pooka iwm_dma_contig_free(struct iwm_dma_info *dma)
   1122   1.1    pooka {
   1123   1.1    pooka 	if (dma->map != NULL) {
   1124   1.1    pooka 		if (dma->vaddr != NULL) {
   1125   1.1    pooka 			bus_dmamap_sync(dma->tag, dma->map, 0, dma->size,
   1126   1.1    pooka 			    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
   1127   1.1    pooka 			bus_dmamap_unload(dma->tag, dma->map);
   1128   1.1    pooka 			bus_dmamem_unmap(dma->tag, dma->vaddr, dma->size);
   1129   1.1    pooka 			bus_dmamem_free(dma->tag, &dma->seg, 1);
   1130   1.1    pooka 			dma->vaddr = NULL;
   1131   1.1    pooka 		}
   1132   1.1    pooka 		bus_dmamap_destroy(dma->tag, dma->map);
   1133   1.1    pooka 		dma->map = NULL;
   1134   1.1    pooka 	}
   1135   1.1    pooka }
   1136   1.1    pooka 
   1137   1.4   nonaka static int
   1138   1.1    pooka iwm_alloc_rx_ring(struct iwm_softc *sc, struct iwm_rx_ring *ring)
   1139   1.1    pooka {
   1140   1.1    pooka 	bus_size_t size;
   1141  1.45   nonaka 	int i, err;
   1142   1.1    pooka 
   1143   1.1    pooka 	ring->cur = 0;
   1144   1.1    pooka 
   1145   1.1    pooka 	/* Allocate RX descriptors (256-byte aligned). */
   1146   1.1    pooka 	size = IWM_RX_RING_COUNT * sizeof(uint32_t);
   1147  1.45   nonaka 	err = iwm_dma_contig_alloc(sc->sc_dmat, &ring->desc_dma, size, 256);
   1148  1.45   nonaka 	if (err) {
   1149   1.3   nonaka 		aprint_error_dev(sc->sc_dev,
   1150   1.3   nonaka 		    "could not allocate RX ring DMA memory\n");
   1151   1.1    pooka 		goto fail;
   1152   1.1    pooka 	}
   1153   1.1    pooka 	ring->desc = ring->desc_dma.vaddr;
   1154   1.1    pooka 
   1155   1.1    pooka 	/* Allocate RX status area (16-byte aligned). */
   1156  1.45   nonaka 	err = iwm_dma_contig_alloc(sc->sc_dmat, &ring->stat_dma,
   1157   1.1    pooka 	    sizeof(*ring->stat), 16);
   1158  1.45   nonaka 	if (err) {
   1159   1.3   nonaka 		aprint_error_dev(sc->sc_dev,
   1160   1.3   nonaka 		    "could not allocate RX status DMA memory\n");
   1161   1.1    pooka 		goto fail;
   1162   1.1    pooka 	}
   1163   1.1    pooka 	ring->stat = ring->stat_dma.vaddr;
   1164   1.1    pooka 
   1165   1.1    pooka 	for (i = 0; i < IWM_RX_RING_COUNT; i++) {
   1166   1.1    pooka 		struct iwm_rx_data *data = &ring->data[i];
   1167   1.1    pooka 
   1168   1.1    pooka 		memset(data, 0, sizeof(*data));
   1169  1.45   nonaka 		err = bus_dmamap_create(sc->sc_dmat, IWM_RBUF_SIZE, 1,
   1170   1.1    pooka 		    IWM_RBUF_SIZE, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
   1171   1.1    pooka 		    &data->map);
   1172  1.45   nonaka 		if (err) {
   1173   1.3   nonaka 			aprint_error_dev(sc->sc_dev,
   1174   1.3   nonaka 			    "could not create RX buf DMA map\n");
   1175   1.1    pooka 			goto fail;
   1176   1.1    pooka 		}
   1177   1.1    pooka 
   1178  1.45   nonaka 		err = iwm_rx_addbuf(sc, IWM_RBUF_SIZE, i);
   1179  1.45   nonaka 		if (err)
   1180   1.1    pooka 			goto fail;
   1181   1.1    pooka 	}
   1182   1.1    pooka 	return 0;
   1183   1.1    pooka 
   1184   1.1    pooka fail:	iwm_free_rx_ring(sc, ring);
   1185  1.45   nonaka 	return err;
   1186   1.1    pooka }
   1187   1.1    pooka 
   1188   1.4   nonaka static void
   1189  1.45   nonaka iwm_disable_rx_dma(struct iwm_softc *sc)
   1190   1.1    pooka {
   1191   1.1    pooka 	int ntries;
   1192   1.1    pooka 
   1193   1.1    pooka 	if (iwm_nic_lock(sc)) {
   1194   1.1    pooka 		IWM_WRITE(sc, IWM_FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
   1195   1.1    pooka 		for (ntries = 0; ntries < 1000; ntries++) {
   1196   1.1    pooka 			if (IWM_READ(sc, IWM_FH_MEM_RSSR_RX_STATUS_REG) &
   1197   1.1    pooka 			    IWM_FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE)
   1198   1.1    pooka 				break;
   1199   1.1    pooka 			DELAY(10);
   1200   1.1    pooka 		}
   1201   1.1    pooka 		iwm_nic_unlock(sc);
   1202   1.1    pooka 	}
   1203  1.45   nonaka }
   1204  1.45   nonaka 
   1205  1.45   nonaka void
   1206  1.45   nonaka iwm_reset_rx_ring(struct iwm_softc *sc, struct iwm_rx_ring *ring)
   1207  1.45   nonaka {
   1208   1.1    pooka 	ring->cur = 0;
   1209  1.45   nonaka 	memset(ring->stat, 0, sizeof(*ring->stat));
   1210  1.45   nonaka 	bus_dmamap_sync(sc->sc_dmat, ring->stat_dma.map, 0,
   1211  1.45   nonaka 	    ring->stat_dma.size, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
   1212   1.1    pooka }
   1213   1.1    pooka 
   1214   1.4   nonaka static void
   1215   1.1    pooka iwm_free_rx_ring(struct iwm_softc *sc, struct iwm_rx_ring *ring)
   1216   1.1    pooka {
   1217   1.1    pooka 	int i;
   1218   1.1    pooka 
   1219   1.1    pooka 	iwm_dma_contig_free(&ring->desc_dma);
   1220   1.1    pooka 	iwm_dma_contig_free(&ring->stat_dma);
   1221   1.1    pooka 
   1222   1.1    pooka 	for (i = 0; i < IWM_RX_RING_COUNT; i++) {
   1223   1.1    pooka 		struct iwm_rx_data *data = &ring->data[i];
   1224   1.1    pooka 
   1225   1.1    pooka 		if (data->m != NULL) {
   1226   1.1    pooka 			bus_dmamap_sync(sc->sc_dmat, data->map, 0,
   1227   1.1    pooka 			    data->map->dm_mapsize, BUS_DMASYNC_POSTREAD);
   1228   1.1    pooka 			bus_dmamap_unload(sc->sc_dmat, data->map);
   1229   1.1    pooka 			m_freem(data->m);
   1230  1.45   nonaka 			data->m = NULL;
   1231   1.1    pooka 		}
   1232  1.45   nonaka 		if (data->map != NULL) {
   1233   1.1    pooka 			bus_dmamap_destroy(sc->sc_dmat, data->map);
   1234  1.45   nonaka 			data->map = NULL;
   1235  1.45   nonaka 		}
   1236   1.1    pooka 	}
   1237   1.1    pooka }
   1238   1.1    pooka 
   1239   1.4   nonaka static int
   1240   1.1    pooka iwm_alloc_tx_ring(struct iwm_softc *sc, struct iwm_tx_ring *ring, int qid)
   1241   1.1    pooka {
   1242   1.1    pooka 	bus_addr_t paddr;
   1243   1.1    pooka 	bus_size_t size;
   1244  1.61   nonaka 	int i, err, nsegs;
   1245   1.1    pooka 
   1246   1.1    pooka 	ring->qid = qid;
   1247   1.1    pooka 	ring->queued = 0;
   1248   1.1    pooka 	ring->cur = 0;
   1249   1.1    pooka 
   1250   1.1    pooka 	/* Allocate TX descriptors (256-byte aligned). */
   1251   1.1    pooka 	size = IWM_TX_RING_COUNT * sizeof (struct iwm_tfd);
   1252  1.45   nonaka 	err = iwm_dma_contig_alloc(sc->sc_dmat, &ring->desc_dma, size, 256);
   1253  1.45   nonaka 	if (err) {
   1254   1.3   nonaka 		aprint_error_dev(sc->sc_dev,
   1255   1.3   nonaka 		    "could not allocate TX ring DMA memory\n");
   1256   1.1    pooka 		goto fail;
   1257   1.1    pooka 	}
   1258   1.1    pooka 	ring->desc = ring->desc_dma.vaddr;
   1259   1.1    pooka 
   1260   1.1    pooka 	/*
   1261   1.1    pooka 	 * We only use rings 0 through 9 (4 EDCA + cmd) so there is no need
   1262   1.1    pooka 	 * to allocate commands space for other rings.
   1263   1.1    pooka 	 */
   1264  1.45   nonaka 	if (qid > IWM_CMD_QUEUE)
   1265   1.1    pooka 		return 0;
   1266   1.1    pooka 
   1267   1.1    pooka 	size = IWM_TX_RING_COUNT * sizeof(struct iwm_device_cmd);
   1268  1.45   nonaka 	err = iwm_dma_contig_alloc(sc->sc_dmat, &ring->cmd_dma, size, 4);
   1269  1.45   nonaka 	if (err) {
   1270   1.3   nonaka 		aprint_error_dev(sc->sc_dev,
   1271   1.3   nonaka 		    "could not allocate TX cmd DMA memory\n");
   1272   1.1    pooka 		goto fail;
   1273   1.1    pooka 	}
   1274   1.1    pooka 	ring->cmd = ring->cmd_dma.vaddr;
   1275   1.1    pooka 
   1276   1.1    pooka 	paddr = ring->cmd_dma.paddr;
   1277   1.1    pooka 	for (i = 0; i < IWM_TX_RING_COUNT; i++) {
   1278   1.1    pooka 		struct iwm_tx_data *data = &ring->data[i];
   1279  1.45   nonaka 		size_t mapsize;
   1280   1.1    pooka 
   1281   1.1    pooka 		data->cmd_paddr = paddr;
   1282   1.1    pooka 		data->scratch_paddr = paddr + sizeof(struct iwm_cmd_header)
   1283   1.1    pooka 		    + offsetof(struct iwm_tx_cmd, scratch);
   1284   1.1    pooka 		paddr += sizeof(struct iwm_device_cmd);
   1285   1.1    pooka 
   1286  1.45   nonaka 		/* FW commands may require more mapped space than packets. */
   1287  1.61   nonaka 		if (qid == IWM_CMD_QUEUE) {
   1288  1.61   nonaka 			mapsize = IWM_RBUF_SIZE;
   1289  1.61   nonaka 			nsegs = 1;
   1290  1.61   nonaka 		} else {
   1291  1.45   nonaka 			mapsize = MCLBYTES;
   1292  1.61   nonaka 			nsegs = IWM_NUM_OF_TBS - 2;
   1293  1.61   nonaka 		}
   1294  1.61   nonaka 		err = bus_dmamap_create(sc->sc_dmat, mapsize, nsegs, mapsize,
   1295  1.61   nonaka 		    0, BUS_DMA_NOWAIT, &data->map);
   1296  1.45   nonaka 		if (err) {
   1297   1.3   nonaka 			aprint_error_dev(sc->sc_dev,
   1298   1.3   nonaka 			    "could not create TX buf DMA map\n");
   1299   1.1    pooka 			goto fail;
   1300   1.1    pooka 		}
   1301   1.1    pooka 	}
   1302   1.1    pooka 	KASSERT(paddr == ring->cmd_dma.paddr + size);
   1303   1.1    pooka 	return 0;
   1304   1.1    pooka 
   1305   1.1    pooka fail:	iwm_free_tx_ring(sc, ring);
   1306  1.45   nonaka 	return err;
   1307   1.1    pooka }
   1308   1.1    pooka 
   1309   1.4   nonaka static void
   1310  1.59   nonaka iwm_clear_cmd_in_flight(struct iwm_softc *sc)
   1311  1.59   nonaka {
   1312  1.59   nonaka 
   1313  1.59   nonaka 	if (!sc->apmg_wake_up_wa)
   1314  1.59   nonaka 		return;
   1315  1.59   nonaka 
   1316  1.59   nonaka 	if (!sc->sc_cmd_hold_nic_awake) {
   1317  1.59   nonaka 		aprint_error_dev(sc->sc_dev,
   1318  1.59   nonaka 		    "cmd_hold_nic_awake not set\n");
   1319  1.59   nonaka 		return;
   1320  1.59   nonaka 	}
   1321  1.59   nonaka 
   1322  1.59   nonaka 	sc->sc_cmd_hold_nic_awake = 0;
   1323  1.59   nonaka 	IWM_CLRBITS(sc, IWM_CSR_GP_CNTRL,
   1324  1.59   nonaka 	    IWM_CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
   1325  1.59   nonaka }
   1326  1.59   nonaka 
   1327  1.59   nonaka static int
   1328  1.59   nonaka iwm_set_cmd_in_flight(struct iwm_softc *sc)
   1329  1.59   nonaka {
   1330  1.59   nonaka 	int ret;
   1331  1.59   nonaka 
   1332  1.59   nonaka 	/*
   1333  1.59   nonaka 	 * wake up the NIC to make sure that the firmware will see the host
   1334  1.59   nonaka 	 * command - we will let the NIC sleep once all the host commands
   1335  1.59   nonaka 	 * returned. This needs to be done only on NICs that have
   1336  1.59   nonaka 	 * apmg_wake_up_wa set.
   1337  1.59   nonaka 	 */
   1338  1.59   nonaka 	if (sc->apmg_wake_up_wa && !sc->sc_cmd_hold_nic_awake) {
   1339  1.59   nonaka 
   1340  1.59   nonaka 		IWM_SETBITS(sc, IWM_CSR_GP_CNTRL,
   1341  1.59   nonaka 		    IWM_CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
   1342  1.59   nonaka 
   1343  1.59   nonaka 		ret = iwm_poll_bit(sc, IWM_CSR_GP_CNTRL,
   1344  1.59   nonaka 		    IWM_CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
   1345  1.59   nonaka 		    (IWM_CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
   1346  1.59   nonaka 		     IWM_CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP),
   1347  1.59   nonaka 		    15000);
   1348  1.59   nonaka 		if (ret == 0) {
   1349  1.59   nonaka 			IWM_CLRBITS(sc, IWM_CSR_GP_CNTRL,
   1350  1.59   nonaka 			    IWM_CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
   1351  1.59   nonaka 			aprint_error_dev(sc->sc_dev,
   1352  1.59   nonaka 			    "failed to wake NIC for hcmd\n");
   1353  1.59   nonaka 			return EIO;
   1354  1.59   nonaka 		}
   1355  1.59   nonaka 		sc->sc_cmd_hold_nic_awake = 1;
   1356  1.59   nonaka 	}
   1357  1.59   nonaka 
   1358  1.59   nonaka 	return 0;
   1359  1.59   nonaka }
   1360  1.59   nonaka static void
   1361   1.1    pooka iwm_reset_tx_ring(struct iwm_softc *sc, struct iwm_tx_ring *ring)
   1362   1.1    pooka {
   1363   1.1    pooka 	int i;
   1364   1.1    pooka 
   1365   1.1    pooka 	for (i = 0; i < IWM_TX_RING_COUNT; i++) {
   1366   1.1    pooka 		struct iwm_tx_data *data = &ring->data[i];
   1367   1.1    pooka 
   1368   1.1    pooka 		if (data->m != NULL) {
   1369   1.1    pooka 			bus_dmamap_sync(sc->sc_dmat, data->map, 0,
   1370   1.1    pooka 			    data->map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
   1371   1.1    pooka 			bus_dmamap_unload(sc->sc_dmat, data->map);
   1372   1.1    pooka 			m_freem(data->m);
   1373   1.1    pooka 			data->m = NULL;
   1374   1.1    pooka 		}
   1375   1.1    pooka 	}
   1376   1.1    pooka 	/* Clear TX descriptors. */
   1377   1.1    pooka 	memset(ring->desc, 0, ring->desc_dma.size);
   1378   1.1    pooka 	bus_dmamap_sync(sc->sc_dmat, ring->desc_dma.map, 0,
   1379   1.1    pooka 	    ring->desc_dma.size, BUS_DMASYNC_PREWRITE);
   1380   1.1    pooka 	sc->qfullmsk &= ~(1 << ring->qid);
   1381   1.1    pooka 	ring->queued = 0;
   1382   1.1    pooka 	ring->cur = 0;
   1383  1.59   nonaka 
   1384  1.59   nonaka 	if (ring->qid == IWM_CMD_QUEUE && sc->sc_cmd_hold_nic_awake)
   1385  1.59   nonaka 		iwm_clear_cmd_in_flight(sc);
   1386   1.1    pooka }
   1387   1.1    pooka 
   1388   1.4   nonaka static void
   1389   1.1    pooka iwm_free_tx_ring(struct iwm_softc *sc, struct iwm_tx_ring *ring)
   1390   1.1    pooka {
   1391   1.1    pooka 	int i;
   1392   1.1    pooka 
   1393   1.1    pooka 	iwm_dma_contig_free(&ring->desc_dma);
   1394   1.1    pooka 	iwm_dma_contig_free(&ring->cmd_dma);
   1395   1.1    pooka 
   1396   1.1    pooka 	for (i = 0; i < IWM_TX_RING_COUNT; i++) {
   1397   1.1    pooka 		struct iwm_tx_data *data = &ring->data[i];
   1398   1.1    pooka 
   1399   1.1    pooka 		if (data->m != NULL) {
   1400   1.1    pooka 			bus_dmamap_sync(sc->sc_dmat, data->map, 0,
   1401   1.1    pooka 			    data->map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
   1402   1.1    pooka 			bus_dmamap_unload(sc->sc_dmat, data->map);
   1403   1.1    pooka 			m_freem(data->m);
   1404  1.57   nonaka 			data->m = NULL;
   1405   1.1    pooka 		}
   1406  1.45   nonaka 		if (data->map != NULL) {
   1407   1.1    pooka 			bus_dmamap_destroy(sc->sc_dmat, data->map);
   1408  1.45   nonaka 			data->map = NULL;
   1409  1.45   nonaka 		}
   1410   1.1    pooka 	}
   1411   1.1    pooka }
   1412   1.1    pooka 
   1413   1.4   nonaka static void
   1414   1.1    pooka iwm_enable_rfkill_int(struct iwm_softc *sc)
   1415   1.1    pooka {
   1416   1.1    pooka 	sc->sc_intmask = IWM_CSR_INT_BIT_RF_KILL;
   1417   1.1    pooka 	IWM_WRITE(sc, IWM_CSR_INT_MASK, sc->sc_intmask);
   1418   1.1    pooka }
   1419   1.1    pooka 
   1420   1.4   nonaka static int
   1421   1.1    pooka iwm_check_rfkill(struct iwm_softc *sc)
   1422   1.1    pooka {
   1423   1.1    pooka 	uint32_t v;
   1424   1.1    pooka 	int s;
   1425   1.1    pooka 	int rv;
   1426   1.8   nonaka 
   1427   1.1    pooka 	s = splnet();
   1428   1.1    pooka 
   1429   1.1    pooka 	/*
   1430   1.1    pooka 	 * "documentation" is not really helpful here:
   1431   1.1    pooka 	 *  27:	HW_RF_KILL_SW
   1432   1.1    pooka 	 *	Indicates state of (platform's) hardware RF-Kill switch
   1433   1.1    pooka 	 *
   1434   1.1    pooka 	 * But apparently when it's off, it's on ...
   1435   1.1    pooka 	 */
   1436   1.1    pooka 	v = IWM_READ(sc, IWM_CSR_GP_CNTRL);
   1437   1.1    pooka 	rv = (v & IWM_CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) == 0;
   1438   1.1    pooka 	if (rv) {
   1439   1.1    pooka 		sc->sc_flags |= IWM_FLAG_RFKILL;
   1440   1.1    pooka 	} else {
   1441   1.1    pooka 		sc->sc_flags &= ~IWM_FLAG_RFKILL;
   1442   1.1    pooka 	}
   1443   1.1    pooka 
   1444   1.1    pooka 	splx(s);
   1445   1.1    pooka 	return rv;
   1446   1.1    pooka }
   1447   1.1    pooka 
   1448   1.4   nonaka static void
   1449   1.1    pooka iwm_enable_interrupts(struct iwm_softc *sc)
   1450   1.1    pooka {
   1451   1.1    pooka 	sc->sc_intmask = IWM_CSR_INI_SET_MASK;
   1452   1.1    pooka 	IWM_WRITE(sc, IWM_CSR_INT_MASK, sc->sc_intmask);
   1453   1.1    pooka }
   1454   1.1    pooka 
   1455   1.4   nonaka static void
   1456   1.1    pooka iwm_restore_interrupts(struct iwm_softc *sc)
   1457   1.1    pooka {
   1458   1.1    pooka 	IWM_WRITE(sc, IWM_CSR_INT_MASK, sc->sc_intmask);
   1459   1.1    pooka }
   1460   1.1    pooka 
   1461   1.4   nonaka static void
   1462   1.1    pooka iwm_disable_interrupts(struct iwm_softc *sc)
   1463   1.1    pooka {
   1464   1.1    pooka 	int s = splnet();
   1465   1.1    pooka 
   1466   1.1    pooka 	IWM_WRITE(sc, IWM_CSR_INT_MASK, 0);
   1467   1.1    pooka 
   1468   1.1    pooka 	/* acknowledge all interrupts */
   1469   1.1    pooka 	IWM_WRITE(sc, IWM_CSR_INT, ~0);
   1470   1.1    pooka 	IWM_WRITE(sc, IWM_CSR_FH_INT_STATUS, ~0);
   1471   1.1    pooka 
   1472   1.1    pooka 	splx(s);
   1473   1.1    pooka }
   1474   1.1    pooka 
   1475   1.4   nonaka static void
   1476   1.1    pooka iwm_ict_reset(struct iwm_softc *sc)
   1477   1.1    pooka {
   1478   1.1    pooka 	iwm_disable_interrupts(sc);
   1479   1.1    pooka 
   1480   1.1    pooka 	memset(sc->ict_dma.vaddr, 0, IWM_ICT_SIZE);
   1481  1.45   nonaka 	bus_dmamap_sync(sc->sc_dmat, sc->ict_dma.map, 0, IWM_ICT_SIZE,
   1482  1.45   nonaka 	    BUS_DMASYNC_PREWRITE);
   1483   1.1    pooka 	sc->ict_cur = 0;
   1484   1.1    pooka 
   1485  1.45   nonaka 	/* Set physical address of ICT (4KB aligned). */
   1486   1.1    pooka 	IWM_WRITE(sc, IWM_CSR_DRAM_INT_TBL_REG,
   1487   1.1    pooka 	    IWM_CSR_DRAM_INT_TBL_ENABLE
   1488   1.1    pooka 	    | IWM_CSR_DRAM_INIT_TBL_WRAP_CHECK
   1489  1.45   nonaka 	    | IWM_CSR_DRAM_INIT_TBL_WRITE_POINTER
   1490   1.1    pooka 	    | sc->ict_dma.paddr >> IWM_ICT_PADDR_SHIFT);
   1491   1.1    pooka 
   1492   1.1    pooka 	/* Switch to ICT interrupt mode in driver. */
   1493   1.1    pooka 	sc->sc_flags |= IWM_FLAG_USE_ICT;
   1494   1.1    pooka 
   1495   1.1    pooka 	IWM_WRITE(sc, IWM_CSR_INT, ~0);
   1496   1.1    pooka 	iwm_enable_interrupts(sc);
   1497   1.1    pooka }
   1498   1.1    pooka 
   1499   1.1    pooka #define IWM_HW_READY_TIMEOUT 50
   1500   1.4   nonaka static int
   1501   1.1    pooka iwm_set_hw_ready(struct iwm_softc *sc)
   1502   1.1    pooka {
   1503  1.45   nonaka 	int ready;
   1504  1.45   nonaka 
   1505   1.1    pooka 	IWM_SETBITS(sc, IWM_CSR_HW_IF_CONFIG_REG,
   1506   1.1    pooka 	    IWM_CSR_HW_IF_CONFIG_REG_BIT_NIC_READY);
   1507   1.1    pooka 
   1508  1.45   nonaka 	ready = iwm_poll_bit(sc, IWM_CSR_HW_IF_CONFIG_REG,
   1509   1.1    pooka 	    IWM_CSR_HW_IF_CONFIG_REG_BIT_NIC_READY,
   1510   1.1    pooka 	    IWM_CSR_HW_IF_CONFIG_REG_BIT_NIC_READY,
   1511   1.1    pooka 	    IWM_HW_READY_TIMEOUT);
   1512  1.45   nonaka 	if (ready)
   1513  1.45   nonaka 		IWM_SETBITS(sc, IWM_CSR_MBOX_SET_REG,
   1514  1.45   nonaka 		    IWM_CSR_MBOX_SET_REG_OS_ALIVE);
   1515  1.45   nonaka 
   1516  1.45   nonaka 	return ready;
   1517   1.1    pooka }
   1518   1.1    pooka #undef IWM_HW_READY_TIMEOUT
   1519   1.1    pooka 
   1520   1.4   nonaka static int
   1521   1.1    pooka iwm_prepare_card_hw(struct iwm_softc *sc)
   1522   1.1    pooka {
   1523   1.1    pooka 	int t = 0;
   1524   1.1    pooka 
   1525  1.10   nonaka 	if (iwm_set_hw_ready(sc))
   1526  1.45   nonaka 		return 0;
   1527  1.45   nonaka 
   1528  1.45   nonaka 	DELAY(100);
   1529   1.1    pooka 
   1530   1.1    pooka 	/* If HW is not ready, prepare the conditions to check again */
   1531   1.1    pooka 	IWM_SETBITS(sc, IWM_CSR_HW_IF_CONFIG_REG,
   1532   1.1    pooka 	    IWM_CSR_HW_IF_CONFIG_REG_PREPARE);
   1533   1.1    pooka 
   1534   1.1    pooka 	do {
   1535   1.1    pooka 		if (iwm_set_hw_ready(sc))
   1536  1.45   nonaka 			return 0;
   1537   1.1    pooka 		DELAY(200);
   1538   1.1    pooka 		t += 200;
   1539   1.1    pooka 	} while (t < 150000);
   1540   1.1    pooka 
   1541  1.45   nonaka 	return ETIMEDOUT;
   1542   1.1    pooka }
   1543   1.1    pooka 
   1544   1.4   nonaka static void
   1545   1.1    pooka iwm_apm_config(struct iwm_softc *sc)
   1546   1.1    pooka {
   1547   1.1    pooka 	pcireg_t reg;
   1548   1.1    pooka 
   1549   1.1    pooka 	reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag,
   1550   1.1    pooka 	    sc->sc_cap_off + PCIE_LCSR);
   1551   1.1    pooka 	if (reg & PCIE_LCSR_ASPM_L1) {
   1552   1.1    pooka 		/* Um the Linux driver prints "Disabling L0S for this one ... */
   1553   1.1    pooka 		IWM_SETBITS(sc, IWM_CSR_GIO_REG,
   1554   1.1    pooka 		    IWM_CSR_GIO_REG_VAL_L0S_ENABLED);
   1555   1.1    pooka 	} else {
   1556   1.1    pooka 		/* ... and "Enabling" here */
   1557   1.1    pooka 		IWM_CLRBITS(sc, IWM_CSR_GIO_REG,
   1558   1.1    pooka 		    IWM_CSR_GIO_REG_VAL_L0S_ENABLED);
   1559   1.1    pooka 	}
   1560   1.1    pooka }
   1561   1.1    pooka 
   1562   1.1    pooka /*
   1563   1.1    pooka  * Start up NIC's basic functionality after it has been reset
   1564  1.45   nonaka  * e.g. after platform boot or shutdown.
   1565   1.1    pooka  * NOTE:  This does not load uCode nor start the embedded processor
   1566   1.1    pooka  */
   1567   1.4   nonaka static int
   1568   1.1    pooka iwm_apm_init(struct iwm_softc *sc)
   1569   1.1    pooka {
   1570  1.45   nonaka 	int err = 0;
   1571   1.1    pooka 
   1572  1.45   nonaka 	/* Disable L0S exit timer (platform NMI workaround) */
   1573  1.61   nonaka 	if (sc->sc_device_family != IWM_DEVICE_FAMILY_8000) {
   1574  1.45   nonaka 		IWM_SETBITS(sc, IWM_CSR_GIO_CHICKEN_BITS,
   1575  1.45   nonaka 		    IWM_CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
   1576  1.61   nonaka 	}
   1577   1.1    pooka 
   1578   1.1    pooka 	/*
   1579   1.1    pooka 	 * Disable L0s without affecting L1;
   1580   1.1    pooka 	 *  don't wait for ICH L0s (ICH bug W/A)
   1581   1.1    pooka 	 */
   1582   1.1    pooka 	IWM_SETBITS(sc, IWM_CSR_GIO_CHICKEN_BITS,
   1583   1.1    pooka 	    IWM_CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX);
   1584   1.1    pooka 
   1585   1.1    pooka 	/* Set FH wait threshold to maximum (HW error during stress W/A) */
   1586   1.1    pooka 	IWM_SETBITS(sc, IWM_CSR_DBG_HPET_MEM_REG, IWM_CSR_DBG_HPET_MEM_REG_VAL);
   1587   1.1    pooka 
   1588   1.1    pooka 	/*
   1589   1.1    pooka 	 * Enable HAP INTA (interrupt from management bus) to
   1590   1.1    pooka 	 * wake device's PCI Express link L1a -> L0s
   1591   1.1    pooka 	 */
   1592   1.1    pooka 	IWM_SETBITS(sc, IWM_CSR_HW_IF_CONFIG_REG,
   1593   1.1    pooka 	    IWM_CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A);
   1594   1.1    pooka 
   1595   1.1    pooka 	iwm_apm_config(sc);
   1596   1.1    pooka 
   1597  1.45   nonaka #if 0 /* not for 7k/8k */
   1598   1.1    pooka 	/* Configure analog phase-lock-loop before activating to D0A */
   1599   1.1    pooka 	if (trans->cfg->base_params->pll_cfg_val)
   1600   1.1    pooka 		IWM_SETBITS(trans, IWM_CSR_ANA_PLL_CFG,
   1601   1.1    pooka 		    trans->cfg->base_params->pll_cfg_val);
   1602   1.1    pooka #endif
   1603   1.1    pooka 
   1604   1.1    pooka 	/*
   1605   1.1    pooka 	 * Set "initialization complete" bit to move adapter from
   1606   1.1    pooka 	 * D0U* --> D0A* (powered-up active) state.
   1607   1.1    pooka 	 */
   1608   1.1    pooka 	IWM_SETBITS(sc, IWM_CSR_GP_CNTRL, IWM_CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
   1609   1.1    pooka 
   1610   1.1    pooka 	/*
   1611   1.1    pooka 	 * Wait for clock stabilization; once stabilized, access to
   1612   1.1    pooka 	 * device-internal resources is supported, e.g. iwm_write_prph()
   1613   1.1    pooka 	 * and accesses to uCode SRAM.
   1614   1.1    pooka 	 */
   1615   1.1    pooka 	if (!iwm_poll_bit(sc, IWM_CSR_GP_CNTRL,
   1616   1.1    pooka 	    IWM_CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
   1617   1.1    pooka 	    IWM_CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000)) {
   1618   1.3   nonaka 		aprint_error_dev(sc->sc_dev,
   1619   1.3   nonaka 		    "timeout waiting for clock stabilization\n");
   1620  1.45   nonaka 		err = ETIMEDOUT;
   1621   1.1    pooka 		goto out;
   1622   1.1    pooka 	}
   1623   1.1    pooka 
   1624  1.17   nonaka 	if (sc->host_interrupt_operation_mode) {
   1625  1.17   nonaka 		/*
   1626  1.17   nonaka 		 * This is a bit of an abuse - This is needed for 7260 / 3160
   1627  1.17   nonaka 		 * only check host_interrupt_operation_mode even if this is
   1628  1.17   nonaka 		 * not related to host_interrupt_operation_mode.
   1629  1.17   nonaka 		 *
   1630  1.17   nonaka 		 * Enable the oscillator to count wake up time for L1 exit. This
   1631  1.17   nonaka 		 * consumes slightly more power (100uA) - but allows to be sure
   1632  1.17   nonaka 		 * that we wake up from L1 on time.
   1633  1.17   nonaka 		 *
   1634  1.17   nonaka 		 * This looks weird: read twice the same register, discard the
   1635  1.17   nonaka 		 * value, set a bit, and yet again, read that same register
   1636  1.17   nonaka 		 * just to discard the value. But that's the way the hardware
   1637  1.17   nonaka 		 * seems to like it.
   1638  1.17   nonaka 		 */
   1639  1.17   nonaka 		iwm_read_prph(sc, IWM_OSC_CLK);
   1640  1.17   nonaka 		iwm_read_prph(sc, IWM_OSC_CLK);
   1641  1.17   nonaka 		iwm_set_bits_prph(sc, IWM_OSC_CLK, IWM_OSC_CLK_FORCE_CONTROL);
   1642  1.17   nonaka 		iwm_read_prph(sc, IWM_OSC_CLK);
   1643  1.17   nonaka 		iwm_read_prph(sc, IWM_OSC_CLK);
   1644  1.17   nonaka 	}
   1645   1.1    pooka 
   1646   1.1    pooka 	/*
   1647   1.1    pooka 	 * Enable DMA clock and wait for it to stabilize.
   1648   1.1    pooka 	 *
   1649   1.1    pooka 	 * Write to "CLK_EN_REG"; "1" bits enable clocks, while "0" bits
   1650   1.1    pooka 	 * do not disable clocks.  This preserves any hardware bits already
   1651   1.1    pooka 	 * set by default in "CLK_CTRL_REG" after reset.
   1652   1.1    pooka 	 */
   1653  1.45   nonaka 	if (sc->sc_device_family == IWM_DEVICE_FAMILY_7000) {
   1654  1.45   nonaka 		iwm_write_prph(sc, IWM_APMG_CLK_EN_REG,
   1655  1.45   nonaka 		    IWM_APMG_CLK_VAL_DMA_CLK_RQT);
   1656  1.45   nonaka 		DELAY(20);
   1657  1.45   nonaka 
   1658  1.45   nonaka 		/* Disable L1-Active */
   1659  1.45   nonaka 		iwm_set_bits_prph(sc, IWM_APMG_PCIDEV_STT_REG,
   1660  1.45   nonaka 		    IWM_APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
   1661  1.45   nonaka 
   1662  1.45   nonaka 		/* Clear the interrupt in APMG if the NIC is in RFKILL */
   1663  1.45   nonaka 		iwm_write_prph(sc, IWM_APMG_RTC_INT_STT_REG,
   1664  1.45   nonaka 		    IWM_APMG_RTC_INT_STT_RFKILL);
   1665  1.45   nonaka 	}
   1666   1.1    pooka  out:
   1667  1.45   nonaka 	if (err)
   1668  1.45   nonaka 		aprint_error_dev(sc->sc_dev, "apm init error %d\n", err);
   1669  1.45   nonaka 	return err;
   1670   1.1    pooka }
   1671   1.1    pooka 
   1672   1.4   nonaka static void
   1673   1.1    pooka iwm_apm_stop(struct iwm_softc *sc)
   1674   1.1    pooka {
   1675   1.1    pooka 	/* stop device's busmaster DMA activity */
   1676   1.1    pooka 	IWM_SETBITS(sc, IWM_CSR_RESET, IWM_CSR_RESET_REG_FLAG_STOP_MASTER);
   1677   1.1    pooka 
   1678   1.1    pooka 	if (!iwm_poll_bit(sc, IWM_CSR_RESET,
   1679   1.1    pooka 	    IWM_CSR_RESET_REG_FLAG_MASTER_DISABLED,
   1680   1.1    pooka 	    IWM_CSR_RESET_REG_FLAG_MASTER_DISABLED, 100))
   1681   1.3   nonaka 		aprint_error_dev(sc->sc_dev, "timeout waiting for master\n");
   1682   1.3   nonaka 	DPRINTF(("iwm apm stop\n"));
   1683   1.1    pooka }
   1684   1.1    pooka 
   1685   1.4   nonaka static int
   1686   1.1    pooka iwm_start_hw(struct iwm_softc *sc)
   1687   1.1    pooka {
   1688  1.45   nonaka 	int err;
   1689   1.1    pooka 
   1690  1.45   nonaka 	err = iwm_prepare_card_hw(sc);
   1691  1.45   nonaka 	if (err)
   1692  1.45   nonaka 		return err;
   1693   1.1    pooka 
   1694   1.8   nonaka 	/* Reset the entire device */
   1695  1.45   nonaka 	IWM_WRITE(sc, IWM_CSR_RESET, IWM_CSR_RESET_REG_FLAG_SW_RESET);
   1696   1.1    pooka 	DELAY(10);
   1697   1.1    pooka 
   1698  1.45   nonaka 	err = iwm_apm_init(sc);
   1699  1.45   nonaka 	if (err)
   1700  1.45   nonaka 		return err;
   1701   1.1    pooka 
   1702   1.1    pooka 	iwm_enable_rfkill_int(sc);
   1703   1.1    pooka 	iwm_check_rfkill(sc);
   1704   1.1    pooka 
   1705   1.1    pooka 	return 0;
   1706   1.1    pooka }
   1707   1.1    pooka 
   1708   1.4   nonaka static void
   1709   1.1    pooka iwm_stop_device(struct iwm_softc *sc)
   1710   1.1    pooka {
   1711   1.1    pooka 	int chnl, ntries;
   1712   1.1    pooka 	int qid;
   1713   1.1    pooka 
   1714   1.1    pooka 	iwm_disable_interrupts(sc);
   1715   1.1    pooka 	sc->sc_flags &= ~IWM_FLAG_USE_ICT;
   1716   1.1    pooka 
   1717  1.45   nonaka 	/* Deactivate TX scheduler. */
   1718   1.1    pooka 	iwm_write_prph(sc, IWM_SCD_TXFACT, 0);
   1719   1.1    pooka 
   1720   1.1    pooka 	/* Stop all DMA channels. */
   1721   1.1    pooka 	if (iwm_nic_lock(sc)) {
   1722   1.1    pooka 		for (chnl = 0; chnl < IWM_FH_TCSR_CHNL_NUM; chnl++) {
   1723   1.1    pooka 			IWM_WRITE(sc,
   1724   1.1    pooka 			    IWM_FH_TCSR_CHNL_TX_CONFIG_REG(chnl), 0);
   1725   1.1    pooka 			for (ntries = 0; ntries < 200; ntries++) {
   1726   1.1    pooka 				uint32_t r;
   1727   1.1    pooka 
   1728   1.1    pooka 				r = IWM_READ(sc, IWM_FH_TSSR_TX_STATUS_REG);
   1729   1.1    pooka 				if (r & IWM_FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(
   1730   1.1    pooka 				    chnl))
   1731   1.1    pooka 					break;
   1732   1.1    pooka 				DELAY(20);
   1733   1.1    pooka 			}
   1734   1.1    pooka 		}
   1735   1.1    pooka 		iwm_nic_unlock(sc);
   1736   1.1    pooka 	}
   1737  1.45   nonaka 	iwm_disable_rx_dma(sc);
   1738   1.1    pooka 
   1739   1.1    pooka 	iwm_reset_rx_ring(sc, &sc->rxq);
   1740   1.1    pooka 
   1741   1.1    pooka 	for (qid = 0; qid < __arraycount(sc->txq); qid++)
   1742   1.1    pooka 		iwm_reset_tx_ring(sc, &sc->txq[qid]);
   1743   1.1    pooka 
   1744  1.61   nonaka 	if (sc->sc_device_family == IWM_DEVICE_FAMILY_7000) {
   1745  1.61   nonaka 		/* Power-down device's busmaster DMA clocks */
   1746  1.61   nonaka 		if (iwm_nic_lock(sc)) {
   1747  1.61   nonaka 			iwm_write_prph(sc, IWM_APMG_CLK_DIS_REG,
   1748  1.61   nonaka 			    IWM_APMG_CLK_VAL_DMA_CLK_RQT);
   1749  1.61   nonaka 			DELAY(5);
   1750  1.61   nonaka 			iwm_nic_unlock(sc);
   1751  1.61   nonaka 		}
   1752  1.61   nonaka 	}
   1753   1.1    pooka 
   1754   1.1    pooka 	/* Make sure (redundant) we've released our request to stay awake */
   1755   1.1    pooka 	IWM_CLRBITS(sc, IWM_CSR_GP_CNTRL,
   1756   1.1    pooka 	    IWM_CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
   1757   1.1    pooka 
   1758   1.1    pooka 	/* Stop the device, and put it in low power state */
   1759   1.1    pooka 	iwm_apm_stop(sc);
   1760   1.1    pooka 
   1761  1.45   nonaka 	/*
   1762  1.45   nonaka 	 * Upon stop, the APM issues an interrupt if HW RF kill is set.
   1763   1.8   nonaka 	 * Clean again the interrupt here
   1764   1.8   nonaka 	 */
   1765   1.1    pooka 	iwm_disable_interrupts(sc);
   1766   1.1    pooka 
   1767  1.45   nonaka 	/* Reset the on-board processor. */
   1768  1.45   nonaka 	IWM_WRITE(sc, IWM_CSR_RESET, IWM_CSR_RESET_REG_FLAG_SW_RESET);
   1769  1.45   nonaka 
   1770  1.45   nonaka 	/* Even though we stop the HW we still want the RF kill interrupt. */
   1771   1.1    pooka 	iwm_enable_rfkill_int(sc);
   1772   1.1    pooka 	iwm_check_rfkill(sc);
   1773   1.1    pooka }
   1774   1.1    pooka 
   1775   1.4   nonaka static void
   1776  1.45   nonaka iwm_nic_config(struct iwm_softc *sc)
   1777   1.1    pooka {
   1778   1.1    pooka 	uint8_t radio_cfg_type, radio_cfg_step, radio_cfg_dash;
   1779   1.1    pooka 	uint32_t reg_val = 0;
   1780   1.1    pooka 
   1781   1.1    pooka 	radio_cfg_type = (sc->sc_fw_phy_config & IWM_FW_PHY_CFG_RADIO_TYPE) >>
   1782   1.1    pooka 	    IWM_FW_PHY_CFG_RADIO_TYPE_POS;
   1783   1.1    pooka 	radio_cfg_step = (sc->sc_fw_phy_config & IWM_FW_PHY_CFG_RADIO_STEP) >>
   1784   1.1    pooka 	    IWM_FW_PHY_CFG_RADIO_STEP_POS;
   1785   1.1    pooka 	radio_cfg_dash = (sc->sc_fw_phy_config & IWM_FW_PHY_CFG_RADIO_DASH) >>
   1786   1.1    pooka 	    IWM_FW_PHY_CFG_RADIO_DASH_POS;
   1787   1.1    pooka 
   1788   1.1    pooka 	reg_val |= IWM_CSR_HW_REV_STEP(sc->sc_hw_rev) <<
   1789   1.1    pooka 	    IWM_CSR_HW_IF_CONFIG_REG_POS_MAC_STEP;
   1790   1.1    pooka 	reg_val |= IWM_CSR_HW_REV_DASH(sc->sc_hw_rev) <<
   1791   1.1    pooka 	    IWM_CSR_HW_IF_CONFIG_REG_POS_MAC_DASH;
   1792   1.1    pooka 
   1793   1.1    pooka 	/* radio configuration */
   1794   1.1    pooka 	reg_val |= radio_cfg_type << IWM_CSR_HW_IF_CONFIG_REG_POS_PHY_TYPE;
   1795   1.1    pooka 	reg_val |= radio_cfg_step << IWM_CSR_HW_IF_CONFIG_REG_POS_PHY_STEP;
   1796   1.1    pooka 	reg_val |= radio_cfg_dash << IWM_CSR_HW_IF_CONFIG_REG_POS_PHY_DASH;
   1797   1.1    pooka 
   1798   1.1    pooka 	IWM_WRITE(sc, IWM_CSR_HW_IF_CONFIG_REG, reg_val);
   1799   1.1    pooka 
   1800   1.8   nonaka 	DPRINTF(("Radio type=0x%x-0x%x-0x%x\n", radio_cfg_type,
   1801   1.8   nonaka 	    radio_cfg_step, radio_cfg_dash));
   1802   1.1    pooka 
   1803   1.1    pooka 	/*
   1804   1.1    pooka 	 * W/A : NIC is stuck in a reset state after Early PCIe power off
   1805   1.1    pooka 	 * (PCIe power is lost before PERST# is asserted), causing ME FW
   1806   1.1    pooka 	 * to lose ownership and not being able to obtain it back.
   1807   1.1    pooka 	 */
   1808  1.61   nonaka 	if (sc->sc_device_family == IWM_DEVICE_FAMILY_7000) {
   1809  1.45   nonaka 		iwm_set_bits_mask_prph(sc, IWM_APMG_PS_CTRL_REG,
   1810  1.45   nonaka 		    IWM_APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS,
   1811  1.45   nonaka 		    ~IWM_APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS);
   1812  1.61   nonaka 	}
   1813   1.1    pooka }
   1814   1.1    pooka 
   1815   1.4   nonaka static int
   1816   1.1    pooka iwm_nic_rx_init(struct iwm_softc *sc)
   1817   1.1    pooka {
   1818   1.1    pooka 	if (!iwm_nic_lock(sc))
   1819   1.1    pooka 		return EBUSY;
   1820   1.1    pooka 
   1821   1.1    pooka 	memset(sc->rxq.stat, 0, sizeof(*sc->rxq.stat));
   1822  1.45   nonaka 	bus_dmamap_sync(sc->sc_dmat, sc->rxq.stat_dma.map,
   1823  1.45   nonaka 	    0, sc->rxq.stat_dma.size,
   1824  1.45   nonaka 	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
   1825   1.1    pooka 
   1826  1.45   nonaka 	iwm_disable_rx_dma(sc);
   1827   1.1    pooka 	IWM_WRITE(sc, IWM_FH_MEM_RCSR_CHNL0_RBDCB_WPTR, 0);
   1828   1.1    pooka 	IWM_WRITE(sc, IWM_FH_MEM_RCSR_CHNL0_FLUSH_RB_REQ, 0);
   1829   1.1    pooka 	IWM_WRITE(sc, IWM_FH_RSCSR_CHNL0_RDPTR, 0);
   1830   1.1    pooka 	IWM_WRITE(sc, IWM_FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0);
   1831   1.1    pooka 
   1832   1.1    pooka 	/* Set physical address of RX ring (256-byte aligned). */
   1833   1.1    pooka 	IWM_WRITE(sc,
   1834   1.1    pooka 	    IWM_FH_RSCSR_CHNL0_RBDCB_BASE_REG, sc->rxq.desc_dma.paddr >> 8);
   1835   1.1    pooka 
   1836   1.1    pooka 	/* Set physical address of RX status (16-byte aligned). */
   1837   1.1    pooka 	IWM_WRITE(sc,
   1838   1.1    pooka 	    IWM_FH_RSCSR_CHNL0_STTS_WPTR_REG, sc->rxq.stat_dma.paddr >> 4);
   1839   1.1    pooka 
   1840   1.1    pooka 	/* Enable RX. */
   1841   1.1    pooka 	IWM_WRITE(sc, IWM_FH_MEM_RCSR_CHNL0_CONFIG_REG,
   1842   1.1    pooka 	    IWM_FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL		|
   1843   1.1    pooka 	    IWM_FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY		|  /* HW bug */
   1844   1.1    pooka 	    IWM_FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL	|
   1845  1.45   nonaka 	    IWM_FH_RCSR_CHNL0_RX_CONFIG_SINGLE_FRAME_MSK	|
   1846  1.61   nonaka 	    IWM_FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K		|
   1847  1.45   nonaka 	    (IWM_RX_RB_TIMEOUT << IWM_FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS) |
   1848   1.1    pooka 	    IWM_RX_QUEUE_SIZE_LOG << IWM_FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS);
   1849   1.1    pooka 
   1850   1.1    pooka 	IWM_WRITE_1(sc, IWM_CSR_INT_COALESCING, IWM_HOST_INT_TIMEOUT_DEF);
   1851  1.17   nonaka 
   1852  1.17   nonaka 	/* W/A for interrupt coalescing bug in 7260 and 3160 */
   1853  1.17   nonaka 	if (sc->host_interrupt_operation_mode)
   1854  1.17   nonaka 		IWM_SETBITS(sc, IWM_CSR_INT_COALESCING, IWM_HOST_INT_OPER_MODE);
   1855   1.1    pooka 
   1856   1.1    pooka 	/*
   1857  1.45   nonaka 	 * This value should initially be 0 (before preparing any RBs),
   1858  1.45   nonaka 	 * and should be 8 after preparing the first 8 RBs (for example).
   1859   1.1    pooka 	 */
   1860   1.1    pooka 	IWM_WRITE(sc, IWM_FH_RSCSR_CHNL0_WPTR, 8);
   1861   1.1    pooka 
   1862   1.1    pooka 	iwm_nic_unlock(sc);
   1863   1.1    pooka 
   1864   1.1    pooka 	return 0;
   1865   1.1    pooka }
   1866   1.1    pooka 
   1867   1.4   nonaka static int
   1868   1.1    pooka iwm_nic_tx_init(struct iwm_softc *sc)
   1869   1.1    pooka {
   1870   1.1    pooka 	int qid;
   1871   1.1    pooka 
   1872   1.1    pooka 	if (!iwm_nic_lock(sc))
   1873   1.1    pooka 		return EBUSY;
   1874   1.1    pooka 
   1875   1.1    pooka 	/* Deactivate TX scheduler. */
   1876   1.1    pooka 	iwm_write_prph(sc, IWM_SCD_TXFACT, 0);
   1877   1.1    pooka 
   1878   1.1    pooka 	/* Set physical address of "keep warm" page (16-byte aligned). */
   1879   1.1    pooka 	IWM_WRITE(sc, IWM_FH_KW_MEM_ADDR_REG, sc->kw_dma.paddr >> 4);
   1880   1.1    pooka 
   1881   1.1    pooka 	for (qid = 0; qid < __arraycount(sc->txq); qid++) {
   1882   1.1    pooka 		struct iwm_tx_ring *txq = &sc->txq[qid];
   1883   1.1    pooka 
   1884   1.1    pooka 		/* Set physical address of TX ring (256-byte aligned). */
   1885   1.1    pooka 		IWM_WRITE(sc, IWM_FH_MEM_CBBC_QUEUE(qid),
   1886   1.1    pooka 		    txq->desc_dma.paddr >> 8);
   1887   1.9   nonaka 		DPRINTF(("loading ring %d descriptors (%p) at %"PRIxMAX"\n",
   1888   1.9   nonaka 		    qid, txq->desc, (uintmax_t)(txq->desc_dma.paddr >> 8)));
   1889   1.1    pooka 	}
   1890  1.45   nonaka 
   1891  1.45   nonaka 	iwm_write_prph(sc, IWM_SCD_GP_CTRL, IWM_SCD_GP_CTRL_AUTO_ACTIVE_MODE);
   1892  1.45   nonaka 
   1893   1.1    pooka 	iwm_nic_unlock(sc);
   1894   1.1    pooka 
   1895   1.1    pooka 	return 0;
   1896   1.1    pooka }
   1897   1.1    pooka 
   1898   1.4   nonaka static int
   1899   1.1    pooka iwm_nic_init(struct iwm_softc *sc)
   1900   1.1    pooka {
   1901  1.45   nonaka 	int err;
   1902   1.1    pooka 
   1903   1.1    pooka 	iwm_apm_init(sc);
   1904  1.61   nonaka 	if (sc->sc_device_family == IWM_DEVICE_FAMILY_7000) {
   1905  1.45   nonaka 		iwm_set_bits_mask_prph(sc, IWM_APMG_PS_CTRL_REG,
   1906  1.45   nonaka 		    IWM_APMG_PS_CTRL_VAL_PWR_SRC_VMAIN,
   1907  1.45   nonaka 		    ~IWM_APMG_PS_CTRL_MSK_PWR_SRC);
   1908  1.61   nonaka 	}
   1909   1.1    pooka 
   1910  1.45   nonaka 	iwm_nic_config(sc);
   1911   1.1    pooka 
   1912  1.45   nonaka 	err = iwm_nic_rx_init(sc);
   1913  1.45   nonaka 	if (err)
   1914  1.45   nonaka 		return err;
   1915   1.1    pooka 
   1916  1.45   nonaka 	err = iwm_nic_tx_init(sc);
   1917  1.45   nonaka 	if (err)
   1918  1.45   nonaka 		return err;
   1919   1.1    pooka 
   1920   1.1    pooka 	DPRINTF(("shadow registers enabled\n"));
   1921   1.1    pooka 	IWM_SETBITS(sc, IWM_CSR_MAC_SHADOW_REG_CTRL, 0x800fffff);
   1922   1.1    pooka 
   1923   1.8   nonaka 	return 0;
   1924   1.1    pooka }
   1925   1.1    pooka 
   1926  1.45   nonaka static const uint8_t iwm_ac_to_tx_fifo[] = {
   1927  1.45   nonaka 	IWM_TX_FIFO_VO,
   1928  1.45   nonaka 	IWM_TX_FIFO_VI,
   1929  1.45   nonaka 	IWM_TX_FIFO_BE,
   1930  1.45   nonaka 	IWM_TX_FIFO_BK,
   1931   1.1    pooka };
   1932   1.1    pooka 
   1933  1.45   nonaka static int
   1934  1.45   nonaka iwm_enable_txq(struct iwm_softc *sc, int sta_id, int qid, int fifo)
   1935   1.1    pooka {
   1936   1.1    pooka 	if (!iwm_nic_lock(sc)) {
   1937   1.2   nonaka 		DPRINTF(("%s: cannot enable txq %d\n", DEVNAME(sc), qid));
   1938  1.45   nonaka 		return EBUSY;
   1939   1.1    pooka 	}
   1940   1.1    pooka 
   1941  1.45   nonaka 	IWM_WRITE(sc, IWM_HBUS_TARG_WRPTR, qid << 8 | 0);
   1942  1.45   nonaka 
   1943  1.45   nonaka 	if (qid == IWM_CMD_QUEUE) {
   1944  1.45   nonaka 		iwm_write_prph(sc, IWM_SCD_QUEUE_STATUS_BITS(qid),
   1945  1.45   nonaka 		    (0 << IWM_SCD_QUEUE_STTS_REG_POS_ACTIVE)
   1946  1.45   nonaka 		    | (1 << IWM_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN));
   1947  1.45   nonaka 
   1948  1.61   nonaka 		iwm_nic_unlock(sc);
   1949  1.61   nonaka 
   1950  1.45   nonaka 		iwm_clear_bits_prph(sc, IWM_SCD_AGGR_SEL, (1 << qid));
   1951  1.45   nonaka 
   1952  1.61   nonaka 		if (!iwm_nic_lock(sc))
   1953  1.61   nonaka 			return EBUSY;
   1954  1.45   nonaka 		iwm_write_prph(sc, IWM_SCD_QUEUE_RDPTR(qid), 0);
   1955  1.61   nonaka 		iwm_nic_unlock(sc);
   1956  1.45   nonaka 
   1957  1.45   nonaka 		iwm_write_mem32(sc,
   1958  1.45   nonaka 		    sc->sched_base + IWM_SCD_CONTEXT_QUEUE_OFFSET(qid), 0);
   1959  1.45   nonaka 
   1960  1.45   nonaka 		/* Set scheduler window size and frame limit. */
   1961  1.45   nonaka 		iwm_write_mem32(sc,
   1962  1.45   nonaka 		    sc->sched_base + IWM_SCD_CONTEXT_QUEUE_OFFSET(qid) +
   1963  1.45   nonaka 		    sizeof(uint32_t),
   1964  1.45   nonaka 		    ((IWM_FRAME_LIMIT << IWM_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) &
   1965  1.45   nonaka 		    IWM_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) |
   1966  1.45   nonaka 		    ((IWM_FRAME_LIMIT
   1967  1.45   nonaka 		        << IWM_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) &
   1968  1.45   nonaka 		    IWM_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK));
   1969  1.45   nonaka 
   1970  1.61   nonaka 		if (!iwm_nic_lock(sc))
   1971  1.61   nonaka 			return EBUSY;
   1972  1.45   nonaka 		iwm_write_prph(sc, IWM_SCD_QUEUE_STATUS_BITS(qid),
   1973  1.45   nonaka 		    (1 << IWM_SCD_QUEUE_STTS_REG_POS_ACTIVE) |
   1974  1.45   nonaka 		    (fifo << IWM_SCD_QUEUE_STTS_REG_POS_TXF) |
   1975  1.45   nonaka 		    (1 << IWM_SCD_QUEUE_STTS_REG_POS_WSL) |
   1976  1.45   nonaka 		    IWM_SCD_QUEUE_STTS_REG_MSK);
   1977  1.45   nonaka 	} else {
   1978  1.45   nonaka 		struct iwm_scd_txq_cfg_cmd cmd;
   1979  1.45   nonaka 		int err;
   1980   1.1    pooka 
   1981  1.45   nonaka 		iwm_nic_unlock(sc);
   1982   1.1    pooka 
   1983  1.45   nonaka 		memset(&cmd, 0, sizeof(cmd));
   1984  1.45   nonaka 		cmd.scd_queue = qid;
   1985  1.45   nonaka 		cmd.enable = 1;
   1986  1.45   nonaka 		cmd.sta_id = sta_id;
   1987  1.45   nonaka 		cmd.tx_fifo = fifo;
   1988  1.45   nonaka 		cmd.aggregate = 0;
   1989  1.45   nonaka 		cmd.window = IWM_FRAME_LIMIT;
   1990  1.45   nonaka 
   1991  1.45   nonaka 		err = iwm_send_cmd_pdu(sc, IWM_SCD_QUEUE_CFG, 0, sizeof(cmd),
   1992  1.45   nonaka 		    &cmd);
   1993  1.45   nonaka 		if (err)
   1994  1.45   nonaka 			return err;
   1995   1.1    pooka 
   1996  1.45   nonaka 		if (!iwm_nic_lock(sc))
   1997  1.45   nonaka 			return EBUSY;
   1998  1.45   nonaka 	}
   1999   1.1    pooka 
   2000  1.45   nonaka 	iwm_write_prph(sc, IWM_SCD_EN_CTRL,
   2001  1.45   nonaka 	    iwm_read_prph(sc, IWM_SCD_EN_CTRL) | qid);
   2002   1.1    pooka 
   2003   1.1    pooka 	iwm_nic_unlock(sc);
   2004   1.1    pooka 
   2005   1.1    pooka 	DPRINTF(("enabled txq %d FIFO %d\n", qid, fifo));
   2006  1.45   nonaka 
   2007  1.45   nonaka 	return 0;
   2008   1.1    pooka }
   2009   1.1    pooka 
   2010   1.4   nonaka static int
   2011   1.1    pooka iwm_post_alive(struct iwm_softc *sc)
   2012   1.1    pooka {
   2013  1.61   nonaka 	int nwords = (IWM_SCD_TRANS_TBL_MEM_UPPER_BOUND -
   2014  1.61   nonaka 	    IWM_SCD_CONTEXT_MEM_LOWER_BOUND) / sizeof(uint32_t);
   2015  1.45   nonaka 	int err, chnl;
   2016  1.45   nonaka 	uint32_t base;
   2017   1.1    pooka 
   2018   1.1    pooka 	if (!iwm_nic_lock(sc))
   2019   1.1    pooka 		return EBUSY;
   2020   1.1    pooka 
   2021  1.45   nonaka 	base = iwm_read_prph(sc, IWM_SCD_SRAM_BASE_ADDR);
   2022  1.45   nonaka 	if (sc->sched_base != base) {
   2023  1.45   nonaka 		DPRINTF(("%s: sched addr mismatch: 0x%08x != 0x%08x\n",
   2024  1.45   nonaka 		    DEVNAME(sc), sc->sched_base, base));
   2025  1.61   nonaka 		sc->sched_base = base;
   2026   1.1    pooka 	}
   2027   1.1    pooka 
   2028  1.61   nonaka 	iwm_nic_unlock(sc);
   2029  1.61   nonaka 
   2030   1.1    pooka 	iwm_ict_reset(sc);
   2031   1.1    pooka 
   2032   1.1    pooka 	/* Clear TX scheduler state in SRAM. */
   2033  1.45   nonaka 	err = iwm_write_mem(sc,
   2034  1.61   nonaka 	    sc->sched_base + IWM_SCD_CONTEXT_MEM_LOWER_BOUND, NULL, nwords);
   2035  1.45   nonaka 	if (err)
   2036  1.61   nonaka 		return err;
   2037  1.61   nonaka 
   2038  1.61   nonaka 	if (!iwm_nic_lock(sc))
   2039  1.61   nonaka 		return EBUSY;
   2040   1.1    pooka 
   2041   1.1    pooka 	/* Set physical address of TX scheduler rings (1KB aligned). */
   2042   1.1    pooka 	iwm_write_prph(sc, IWM_SCD_DRAM_BASE_ADDR, sc->sched_dma.paddr >> 10);
   2043   1.1    pooka 
   2044   1.1    pooka 	iwm_write_prph(sc, IWM_SCD_CHAINEXT_EN, 0);
   2045   1.1    pooka 
   2046  1.45   nonaka 	iwm_nic_unlock(sc);
   2047  1.45   nonaka 
   2048   1.1    pooka 	/* enable command channel */
   2049  1.45   nonaka 	err = iwm_enable_txq(sc, 0 /* unused */, IWM_CMD_QUEUE, 7);
   2050  1.45   nonaka 	if (err)
   2051  1.45   nonaka 		return err;
   2052  1.45   nonaka 
   2053  1.45   nonaka 	if (!iwm_nic_lock(sc))
   2054  1.45   nonaka 		return EBUSY;
   2055   1.1    pooka 
   2056  1.45   nonaka 	/* Activate TX scheduler. */
   2057   1.1    pooka 	iwm_write_prph(sc, IWM_SCD_TXFACT, 0xff);
   2058   1.1    pooka 
   2059   1.1    pooka 	/* Enable DMA channels. */
   2060   1.1    pooka 	for (chnl = 0; chnl < IWM_FH_TCSR_CHNL_NUM; chnl++) {
   2061   1.1    pooka 		IWM_WRITE(sc, IWM_FH_TCSR_CHNL_TX_CONFIG_REG(chnl),
   2062   1.1    pooka 		    IWM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE |
   2063   1.1    pooka 		    IWM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE);
   2064   1.1    pooka 	}
   2065   1.1    pooka 
   2066   1.1    pooka 	IWM_SETBITS(sc, IWM_FH_TX_CHICKEN_BITS_REG,
   2067   1.1    pooka 	    IWM_FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN);
   2068   1.1    pooka 
   2069   1.8   nonaka 	/* Enable L1-Active */
   2070  1.61   nonaka 	if (sc->sc_device_family != IWM_DEVICE_FAMILY_8000) {
   2071  1.45   nonaka 		iwm_clear_bits_prph(sc, IWM_APMG_PCIDEV_STT_REG,
   2072  1.45   nonaka 		    IWM_APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
   2073  1.61   nonaka 	}
   2074   1.1    pooka 
   2075  1.38    ozaki 	iwm_nic_unlock(sc);
   2076  1.61   nonaka 
   2077  1.61   nonaka 	return 0;
   2078   1.1    pooka }
   2079   1.1    pooka 
   2080   1.1    pooka static struct iwm_phy_db_entry *
   2081  1.45   nonaka iwm_phy_db_get_section(struct iwm_softc *sc, enum iwm_phy_db_section_type type,
   2082  1.45   nonaka     uint16_t chg_id)
   2083   1.1    pooka {
   2084   1.1    pooka 	struct iwm_phy_db *phy_db = &sc->sc_phy_db;
   2085   1.1    pooka 
   2086   1.1    pooka 	if (type >= IWM_PHY_DB_MAX)
   2087   1.1    pooka 		return NULL;
   2088   1.1    pooka 
   2089   1.1    pooka 	switch (type) {
   2090   1.1    pooka 	case IWM_PHY_DB_CFG:
   2091   1.1    pooka 		return &phy_db->cfg;
   2092   1.1    pooka 	case IWM_PHY_DB_CALIB_NCH:
   2093   1.1    pooka 		return &phy_db->calib_nch;
   2094   1.1    pooka 	case IWM_PHY_DB_CALIB_CHG_PAPD:
   2095   1.1    pooka 		if (chg_id >= IWM_NUM_PAPD_CH_GROUPS)
   2096   1.1    pooka 			return NULL;
   2097   1.1    pooka 		return &phy_db->calib_ch_group_papd[chg_id];
   2098   1.1    pooka 	case IWM_PHY_DB_CALIB_CHG_TXP:
   2099   1.1    pooka 		if (chg_id >= IWM_NUM_TXP_CH_GROUPS)
   2100   1.1    pooka 			return NULL;
   2101   1.1    pooka 		return &phy_db->calib_ch_group_txp[chg_id];
   2102   1.1    pooka 	default:
   2103   1.1    pooka 		return NULL;
   2104   1.1    pooka 	}
   2105   1.1    pooka 	return NULL;
   2106   1.1    pooka }
   2107   1.1    pooka 
   2108   1.1    pooka static int
   2109   1.1    pooka iwm_phy_db_set_section(struct iwm_softc *sc,
   2110   1.5   nonaka     struct iwm_calib_res_notif_phy_db *phy_db_notif, uint16_t size)
   2111   1.1    pooka {
   2112  1.45   nonaka 	struct iwm_phy_db_entry *entry;
   2113   1.1    pooka 	enum iwm_phy_db_section_type type = le16toh(phy_db_notif->type);
   2114   1.1    pooka 	uint16_t chg_id = 0;
   2115   1.1    pooka 
   2116   1.1    pooka 	if (type == IWM_PHY_DB_CALIB_CHG_PAPD ||
   2117   1.1    pooka 	    type == IWM_PHY_DB_CALIB_CHG_TXP)
   2118   1.1    pooka 		chg_id = le16toh(*(uint16_t *)phy_db_notif->data);
   2119   1.1    pooka 
   2120   1.1    pooka 	entry = iwm_phy_db_get_section(sc, type, chg_id);
   2121   1.1    pooka 	if (!entry)
   2122   1.1    pooka 		return EINVAL;
   2123   1.1    pooka 
   2124   1.1    pooka 	if (entry->data)
   2125   1.5   nonaka 		kmem_intr_free(entry->data, entry->size);
   2126   1.5   nonaka 	entry->data = kmem_intr_alloc(size, KM_NOSLEEP);
   2127   1.1    pooka 	if (!entry->data) {
   2128   1.1    pooka 		entry->size = 0;
   2129   1.1    pooka 		return ENOMEM;
   2130   1.1    pooka 	}
   2131   1.1    pooka 	memcpy(entry->data, phy_db_notif->data, size);
   2132   1.1    pooka 	entry->size = size;
   2133   1.1    pooka 
   2134   1.5   nonaka 	DPRINTFN(10, ("%s(%d): [PHYDB]SET: Type %d, Size: %d, data: %p\n",
   2135   1.1    pooka 	    __func__, __LINE__, type, size, entry->data));
   2136   1.1    pooka 
   2137   1.1    pooka 	return 0;
   2138   1.1    pooka }
   2139   1.1    pooka 
   2140   1.4   nonaka static int
   2141   1.1    pooka iwm_is_valid_channel(uint16_t ch_id)
   2142   1.1    pooka {
   2143   1.1    pooka 	if (ch_id <= 14 ||
   2144   1.1    pooka 	    (36 <= ch_id && ch_id <= 64 && ch_id % 4 == 0) ||
   2145   1.1    pooka 	    (100 <= ch_id && ch_id <= 140 && ch_id % 4 == 0) ||
   2146   1.1    pooka 	    (145 <= ch_id && ch_id <= 165 && ch_id % 4 == 1))
   2147   1.1    pooka 		return 1;
   2148   1.1    pooka 	return 0;
   2149   1.1    pooka }
   2150   1.1    pooka 
   2151   1.4   nonaka static uint8_t
   2152   1.1    pooka iwm_ch_id_to_ch_index(uint16_t ch_id)
   2153   1.1    pooka {
   2154   1.1    pooka 	if (!iwm_is_valid_channel(ch_id))
   2155   1.1    pooka 		return 0xff;
   2156   1.1    pooka 
   2157   1.1    pooka 	if (ch_id <= 14)
   2158   1.1    pooka 		return ch_id - 1;
   2159   1.1    pooka 	if (ch_id <= 64)
   2160   1.1    pooka 		return (ch_id + 20) / 4;
   2161   1.1    pooka 	if (ch_id <= 140)
   2162   1.1    pooka 		return (ch_id - 12) / 4;
   2163   1.1    pooka 	return (ch_id - 13) / 4;
   2164   1.1    pooka }
   2165   1.1    pooka 
   2166   1.1    pooka 
   2167   1.4   nonaka static uint16_t
   2168   1.1    pooka iwm_channel_id_to_papd(uint16_t ch_id)
   2169   1.1    pooka {
   2170   1.1    pooka 	if (!iwm_is_valid_channel(ch_id))
   2171   1.1    pooka 		return 0xff;
   2172   1.1    pooka 
   2173   1.1    pooka 	if (1 <= ch_id && ch_id <= 14)
   2174   1.1    pooka 		return 0;
   2175   1.1    pooka 	if (36 <= ch_id && ch_id <= 64)
   2176   1.1    pooka 		return 1;
   2177   1.1    pooka 	if (100 <= ch_id && ch_id <= 140)
   2178   1.1    pooka 		return 2;
   2179   1.1    pooka 	return 3;
   2180   1.1    pooka }
   2181   1.1    pooka 
   2182   1.4   nonaka static uint16_t
   2183   1.1    pooka iwm_channel_id_to_txp(struct iwm_softc *sc, uint16_t ch_id)
   2184   1.1    pooka {
   2185   1.1    pooka 	struct iwm_phy_db *phy_db = &sc->sc_phy_db;
   2186   1.1    pooka 	struct iwm_phy_db_chg_txp *txp_chg;
   2187   1.1    pooka 	int i;
   2188   1.1    pooka 	uint8_t ch_index = iwm_ch_id_to_ch_index(ch_id);
   2189   1.1    pooka 
   2190   1.1    pooka 	if (ch_index == 0xff)
   2191   1.1    pooka 		return 0xff;
   2192   1.1    pooka 
   2193   1.1    pooka 	for (i = 0; i < IWM_NUM_TXP_CH_GROUPS; i++) {
   2194   1.1    pooka 		txp_chg = (void *)phy_db->calib_ch_group_txp[i].data;
   2195   1.1    pooka 		if (!txp_chg)
   2196   1.1    pooka 			return 0xff;
   2197   1.1    pooka 		/*
   2198  1.45   nonaka 		 * Looking for the first channel group the max channel
   2199  1.45   nonaka 		 * of which is higher than the requested channel.
   2200   1.1    pooka 		 */
   2201   1.1    pooka 		if (le16toh(txp_chg->max_channel_idx) >= ch_index)
   2202   1.1    pooka 			return i;
   2203   1.1    pooka 	}
   2204   1.1    pooka 	return 0xff;
   2205   1.1    pooka }
   2206   1.1    pooka 
   2207   1.4   nonaka static int
   2208  1.45   nonaka iwm_phy_db_get_section_data(struct iwm_softc *sc, uint32_t type, uint8_t **data,
   2209  1.45   nonaka     uint16_t *size, uint16_t ch_id)
   2210   1.1    pooka {
   2211   1.1    pooka 	struct iwm_phy_db_entry *entry;
   2212   1.1    pooka 	uint16_t ch_group_id = 0;
   2213   1.1    pooka 
   2214   1.1    pooka 	if (type == IWM_PHY_DB_CALIB_CHG_PAPD)
   2215   1.1    pooka 		ch_group_id = iwm_channel_id_to_papd(ch_id);
   2216   1.1    pooka 	else if (type == IWM_PHY_DB_CALIB_CHG_TXP)
   2217   1.1    pooka 		ch_group_id = iwm_channel_id_to_txp(sc, ch_id);
   2218   1.1    pooka 
   2219   1.1    pooka 	entry = iwm_phy_db_get_section(sc, type, ch_group_id);
   2220   1.1    pooka 	if (!entry)
   2221   1.1    pooka 		return EINVAL;
   2222   1.1    pooka 
   2223   1.1    pooka 	*data = entry->data;
   2224   1.1    pooka 	*size = entry->size;
   2225   1.1    pooka 
   2226   1.1    pooka 	DPRINTFN(10, ("%s(%d): [PHYDB] GET: Type %d , Size: %d\n",
   2227   1.1    pooka 		       __func__, __LINE__, type, *size));
   2228   1.1    pooka 
   2229   1.1    pooka 	return 0;
   2230   1.1    pooka }
   2231   1.1    pooka 
   2232   1.4   nonaka static int
   2233  1.45   nonaka iwm_send_phy_db_cmd(struct iwm_softc *sc, uint16_t type, uint16_t length,
   2234  1.45   nonaka     void *data)
   2235   1.1    pooka {
   2236   1.1    pooka 	struct iwm_phy_db_cmd phy_db_cmd;
   2237   1.1    pooka 	struct iwm_host_cmd cmd = {
   2238   1.1    pooka 		.id = IWM_PHY_DB_CMD,
   2239  1.45   nonaka 		.flags = IWM_CMD_ASYNC,
   2240   1.1    pooka 	};
   2241   1.1    pooka 
   2242   1.5   nonaka 	DPRINTFN(10, ("Sending PHY-DB hcmd of type %d, of length %d\n",
   2243   1.5   nonaka 	    type, length));
   2244   1.1    pooka 
   2245   1.1    pooka 	phy_db_cmd.type = le16toh(type);
   2246   1.1    pooka 	phy_db_cmd.length = le16toh(length);
   2247   1.1    pooka 
   2248   1.1    pooka 	cmd.data[0] = &phy_db_cmd;
   2249   1.1    pooka 	cmd.len[0] = sizeof(struct iwm_phy_db_cmd);
   2250   1.1    pooka 	cmd.data[1] = data;
   2251   1.1    pooka 	cmd.len[1] = length;
   2252   1.1    pooka 
   2253   1.1    pooka 	return iwm_send_cmd(sc, &cmd);
   2254   1.1    pooka }
   2255   1.1    pooka 
   2256   1.1    pooka static int
   2257   1.1    pooka iwm_phy_db_send_all_channel_groups(struct iwm_softc *sc,
   2258  1.45   nonaka     enum iwm_phy_db_section_type type, uint8_t max_ch_groups)
   2259   1.1    pooka {
   2260   1.1    pooka 	uint16_t i;
   2261   1.1    pooka 	int err;
   2262   1.1    pooka 	struct iwm_phy_db_entry *entry;
   2263   1.1    pooka 
   2264   1.1    pooka 	/* Send all the channel-specific groups to operational fw */
   2265   1.1    pooka 	for (i = 0; i < max_ch_groups; i++) {
   2266   1.1    pooka 		entry = iwm_phy_db_get_section(sc, type, i);
   2267   1.1    pooka 		if (!entry)
   2268   1.1    pooka 			return EINVAL;
   2269   1.1    pooka 
   2270   1.1    pooka 		if (!entry->size)
   2271   1.1    pooka 			continue;
   2272   1.1    pooka 
   2273   1.1    pooka 		err = iwm_send_phy_db_cmd(sc, type, entry->size, entry->data);
   2274   1.1    pooka 		if (err) {
   2275   1.2   nonaka 			DPRINTF(("%s: Can't SEND phy_db section %d (%d), "
   2276   1.2   nonaka 			    "err %d\n", DEVNAME(sc), type, i, err));
   2277   1.1    pooka 			return err;
   2278   1.1    pooka 		}
   2279   1.1    pooka 
   2280  1.45   nonaka 		DPRINTFN(10, ("%s: Sent PHY_DB HCMD, type = %d num = %d\n",
   2281  1.45   nonaka 		    DEVNAME(sc), type, i));
   2282  1.45   nonaka 
   2283  1.45   nonaka 		DELAY(1000);
   2284   1.1    pooka 	}
   2285   1.1    pooka 
   2286   1.1    pooka 	return 0;
   2287   1.1    pooka }
   2288   1.1    pooka 
   2289   1.4   nonaka static int
   2290   1.1    pooka iwm_send_phy_db_data(struct iwm_softc *sc)
   2291   1.1    pooka {
   2292   1.1    pooka 	uint8_t *data = NULL;
   2293   1.1    pooka 	uint16_t size = 0;
   2294   1.1    pooka 	int err;
   2295   1.1    pooka 
   2296   1.1    pooka 	err = iwm_phy_db_get_section_data(sc, IWM_PHY_DB_CFG, &data, &size, 0);
   2297  1.45   nonaka 	if (err)
   2298   1.1    pooka 		return err;
   2299   1.1    pooka 
   2300   1.1    pooka 	err = iwm_send_phy_db_cmd(sc, IWM_PHY_DB_CFG, size, data);
   2301  1.45   nonaka 	if (err)
   2302   1.1    pooka 		return err;
   2303   1.1    pooka 
   2304   1.1    pooka 	err = iwm_phy_db_get_section_data(sc, IWM_PHY_DB_CALIB_NCH,
   2305   1.1    pooka 	    &data, &size, 0);
   2306  1.45   nonaka 	if (err)
   2307   1.1    pooka 		return err;
   2308   1.1    pooka 
   2309   1.1    pooka 	err = iwm_send_phy_db_cmd(sc, IWM_PHY_DB_CALIB_NCH, size, data);
   2310  1.45   nonaka 	if (err)
   2311   1.1    pooka 		return err;
   2312   1.1    pooka 
   2313   1.1    pooka 	err = iwm_phy_db_send_all_channel_groups(sc,
   2314   1.1    pooka 	    IWM_PHY_DB_CALIB_CHG_PAPD, IWM_NUM_PAPD_CH_GROUPS);
   2315  1.45   nonaka 	if (err)
   2316   1.1    pooka 		return err;
   2317   1.1    pooka 
   2318   1.1    pooka 	err = iwm_phy_db_send_all_channel_groups(sc,
   2319   1.1    pooka 	    IWM_PHY_DB_CALIB_CHG_TXP, IWM_NUM_TXP_CH_GROUPS);
   2320  1.45   nonaka 	if (err)
   2321   1.1    pooka 		return err;
   2322   1.1    pooka 
   2323   1.1    pooka 	return 0;
   2324   1.1    pooka }
   2325   1.1    pooka 
   2326   1.1    pooka /*
   2327   1.1    pooka  * For the high priority TE use a time event type that has similar priority to
   2328   1.1    pooka  * the FW's action scan priority.
   2329   1.1    pooka  */
   2330  1.45   nonaka #define IWM_ROC_TE_TYPE_NORMAL IWM_TE_P2P_DEVICE_DISCOVERABLE
   2331  1.45   nonaka #define IWM_ROC_TE_TYPE_MGMT_TX IWM_TE_P2P_CLIENT_ASSOC
   2332   1.1    pooka 
   2333   1.1    pooka /* used to convert from time event API v2 to v1 */
   2334   1.1    pooka #define IWM_TE_V2_DEP_POLICY_MSK (IWM_TE_V2_DEP_OTHER | IWM_TE_V2_DEP_TSF |\
   2335   1.1    pooka 			     IWM_TE_V2_EVENT_SOCIOPATHIC)
   2336   1.1    pooka static inline uint16_t
   2337   1.1    pooka iwm_te_v2_get_notify(uint16_t policy)
   2338   1.1    pooka {
   2339   1.1    pooka 	return le16toh(policy) & IWM_TE_V2_NOTIF_MSK;
   2340   1.1    pooka }
   2341   1.1    pooka 
   2342   1.1    pooka static inline uint16_t
   2343   1.1    pooka iwm_te_v2_get_dep_policy(uint16_t policy)
   2344   1.1    pooka {
   2345   1.1    pooka 	return (le16toh(policy) & IWM_TE_V2_DEP_POLICY_MSK) >>
   2346   1.1    pooka 		IWM_TE_V2_PLACEMENT_POS;
   2347   1.1    pooka }
   2348   1.1    pooka 
   2349   1.1    pooka static inline uint16_t
   2350   1.1    pooka iwm_te_v2_get_absence(uint16_t policy)
   2351   1.1    pooka {
   2352   1.1    pooka 	return (le16toh(policy) & IWM_TE_V2_ABSENCE) >> IWM_TE_V2_ABSENCE_POS;
   2353   1.1    pooka }
   2354   1.1    pooka 
   2355   1.4   nonaka static void
   2356  1.45   nonaka iwm_te_v2_to_v1(const struct iwm_time_event_cmd_v2 *cmd_v2,
   2357  1.45   nonaka     struct iwm_time_event_cmd_v1 *cmd_v1)
   2358   1.1    pooka {
   2359   1.1    pooka 	cmd_v1->id_and_color = cmd_v2->id_and_color;
   2360   1.1    pooka 	cmd_v1->action = cmd_v2->action;
   2361   1.1    pooka 	cmd_v1->id = cmd_v2->id;
   2362   1.1    pooka 	cmd_v1->apply_time = cmd_v2->apply_time;
   2363   1.1    pooka 	cmd_v1->max_delay = cmd_v2->max_delay;
   2364   1.1    pooka 	cmd_v1->depends_on = cmd_v2->depends_on;
   2365   1.1    pooka 	cmd_v1->interval = cmd_v2->interval;
   2366   1.1    pooka 	cmd_v1->duration = cmd_v2->duration;
   2367   1.1    pooka 	if (cmd_v2->repeat == IWM_TE_V2_REPEAT_ENDLESS)
   2368   1.1    pooka 		cmd_v1->repeat = htole32(IWM_TE_V1_REPEAT_ENDLESS);
   2369   1.1    pooka 	else
   2370   1.1    pooka 		cmd_v1->repeat = htole32(cmd_v2->repeat);
   2371   1.1    pooka 	cmd_v1->max_frags = htole32(cmd_v2->max_frags);
   2372   1.1    pooka 	cmd_v1->interval_reciprocal = 0; /* unused */
   2373   1.1    pooka 
   2374   1.1    pooka 	cmd_v1->dep_policy = htole32(iwm_te_v2_get_dep_policy(cmd_v2->policy));
   2375   1.1    pooka 	cmd_v1->is_present = htole32(!iwm_te_v2_get_absence(cmd_v2->policy));
   2376   1.1    pooka 	cmd_v1->notify = htole32(iwm_te_v2_get_notify(cmd_v2->policy));
   2377   1.1    pooka }
   2378   1.1    pooka 
   2379   1.4   nonaka static int
   2380  1.45   nonaka iwm_send_time_event_cmd(struct iwm_softc *sc,
   2381  1.45   nonaka     const struct iwm_time_event_cmd_v2 *cmd)
   2382   1.1    pooka {
   2383   1.1    pooka 	struct iwm_time_event_cmd_v1 cmd_v1;
   2384   1.1    pooka 
   2385   1.1    pooka 	if (sc->sc_capaflags & IWM_UCODE_TLV_FLAGS_TIME_EVENT_API_V2)
   2386  1.45   nonaka 		return iwm_send_cmd_pdu(sc, IWM_TIME_EVENT_CMD, 0, sizeof(*cmd),
   2387  1.45   nonaka 		    cmd);
   2388   1.1    pooka 
   2389  1.45   nonaka 	iwm_te_v2_to_v1(cmd, &cmd_v1);
   2390  1.45   nonaka 	return iwm_send_cmd_pdu(sc, IWM_TIME_EVENT_CMD, 0, sizeof(cmd_v1),
   2391  1.45   nonaka 	    &cmd_v1);
   2392   1.1    pooka }
   2393   1.1    pooka 
   2394   1.4   nonaka static void
   2395  1.45   nonaka iwm_protect_session(struct iwm_softc *sc, struct iwm_node *in,
   2396  1.45   nonaka     uint32_t duration, uint32_t max_delay)
   2397   1.1    pooka {
   2398   1.1    pooka 	struct iwm_time_event_cmd_v2 time_cmd;
   2399   1.1    pooka 
   2400   1.1    pooka 	memset(&time_cmd, 0, sizeof(time_cmd));
   2401   1.1    pooka 
   2402   1.1    pooka 	time_cmd.action = htole32(IWM_FW_CTXT_ACTION_ADD);
   2403   1.1    pooka 	time_cmd.id_and_color =
   2404   1.1    pooka 	    htole32(IWM_FW_CMD_ID_AND_COLOR(in->in_id, in->in_color));
   2405   1.1    pooka 	time_cmd.id = htole32(IWM_TE_BSS_STA_AGGRESSIVE_ASSOC);
   2406   1.1    pooka 
   2407  1.45   nonaka 	time_cmd.apply_time = htole32(0);
   2408   1.1    pooka 
   2409   1.1    pooka 	time_cmd.max_frags = IWM_TE_V2_FRAG_NONE;
   2410   1.1    pooka 	time_cmd.max_delay = htole32(max_delay);
   2411   1.1    pooka 	/* TODO: why do we need to interval = bi if it is not periodic? */
   2412   1.1    pooka 	time_cmd.interval = htole32(1);
   2413   1.1    pooka 	time_cmd.duration = htole32(duration);
   2414   1.1    pooka 	time_cmd.repeat = 1;
   2415   1.1    pooka 	time_cmd.policy
   2416  1.45   nonaka 	    = htole16(IWM_TE_V2_NOTIF_HOST_EVENT_START |
   2417  1.45   nonaka 	        IWM_TE_V2_NOTIF_HOST_EVENT_END |
   2418  1.45   nonaka 		IWM_T2_V2_START_IMMEDIATELY);
   2419   1.1    pooka 
   2420  1.45   nonaka 	iwm_send_time_event_cmd(sc, &time_cmd);
   2421   1.1    pooka }
   2422   1.1    pooka 
   2423   1.1    pooka /*
   2424   1.1    pooka  * NVM read access and content parsing.  We do not support
   2425   1.1    pooka  * external NVM or writing NVM.
   2426   1.1    pooka  */
   2427   1.1    pooka 
   2428   1.1    pooka /* list of NVM sections we are allowed/need to read */
   2429  1.45   nonaka static const int iwm_nvm_to_read[] = {
   2430   1.1    pooka 	IWM_NVM_SECTION_TYPE_HW,
   2431   1.1    pooka 	IWM_NVM_SECTION_TYPE_SW,
   2432  1.45   nonaka 	IWM_NVM_SECTION_TYPE_REGULATORY,
   2433   1.1    pooka 	IWM_NVM_SECTION_TYPE_CALIBRATION,
   2434   1.1    pooka 	IWM_NVM_SECTION_TYPE_PRODUCTION,
   2435  1.45   nonaka 	IWM_NVM_SECTION_TYPE_HW_8000,
   2436  1.45   nonaka 	IWM_NVM_SECTION_TYPE_MAC_OVERRIDE,
   2437  1.45   nonaka 	IWM_NVM_SECTION_TYPE_PHY_SKU,
   2438   1.1    pooka };
   2439   1.1    pooka 
   2440   1.1    pooka /* Default NVM size to read */
   2441  1.45   nonaka #define IWM_NVM_DEFAULT_CHUNK_SIZE	(2*1024)
   2442  1.61   nonaka #define IWM_MAX_NVM_SECTION_SIZE_7000	(16 * 512 * sizeof(uint16_t)) /*16 KB*/
   2443  1.61   nonaka #define IWM_MAX_NVM_SECTION_SIZE_8000	(32 * 512 * sizeof(uint16_t)) /*32 KB*/
   2444   1.1    pooka 
   2445   1.1    pooka #define IWM_NVM_WRITE_OPCODE 1
   2446   1.1    pooka #define IWM_NVM_READ_OPCODE 0
   2447   1.1    pooka 
   2448   1.4   nonaka static int
   2449  1.45   nonaka iwm_nvm_read_chunk(struct iwm_softc *sc, uint16_t section, uint16_t offset,
   2450  1.45   nonaka     uint16_t length, uint8_t *data, uint16_t *len)
   2451   1.1    pooka {
   2452   1.1    pooka 	offset = 0;
   2453   1.1    pooka 	struct iwm_nvm_access_cmd nvm_access_cmd = {
   2454   1.1    pooka 		.offset = htole16(offset),
   2455   1.1    pooka 		.length = htole16(length),
   2456   1.1    pooka 		.type = htole16(section),
   2457   1.1    pooka 		.op_code = IWM_NVM_READ_OPCODE,
   2458   1.1    pooka 	};
   2459   1.1    pooka 	struct iwm_nvm_access_resp *nvm_resp;
   2460   1.1    pooka 	struct iwm_rx_packet *pkt;
   2461   1.1    pooka 	struct iwm_host_cmd cmd = {
   2462   1.1    pooka 		.id = IWM_NVM_ACCESS_CMD,
   2463  1.45   nonaka 		.flags = (IWM_CMD_WANT_SKB | IWM_CMD_SEND_IN_RFKILL),
   2464   1.1    pooka 		.data = { &nvm_access_cmd, },
   2465   1.1    pooka 	};
   2466  1.45   nonaka 	int err, offset_read;
   2467  1.45   nonaka 	size_t bytes_read;
   2468   1.1    pooka 	uint8_t *resp_data;
   2469   1.1    pooka 
   2470   1.1    pooka 	cmd.len[0] = sizeof(struct iwm_nvm_access_cmd);
   2471   1.1    pooka 
   2472  1.45   nonaka 	err = iwm_send_cmd(sc, &cmd);
   2473  1.45   nonaka 	if (err) {
   2474  1.45   nonaka 		DPRINTF(("%s: Could not send NVM_ACCESS command (error=%d)\n",
   2475  1.45   nonaka 		    DEVNAME(sc), err));
   2476  1.45   nonaka 		return err;
   2477  1.45   nonaka 	}
   2478   1.1    pooka 
   2479   1.1    pooka 	pkt = cmd.resp_pkt;
   2480   1.1    pooka 	if (pkt->hdr.flags & IWM_CMD_FAILED_MSK) {
   2481  1.45   nonaka 		err = EIO;
   2482   1.1    pooka 		goto exit;
   2483   1.1    pooka 	}
   2484   1.1    pooka 
   2485   1.1    pooka 	/* Extract NVM response */
   2486   1.1    pooka 	nvm_resp = (void *)pkt->data;
   2487   1.1    pooka 
   2488  1.45   nonaka 	err = le16toh(nvm_resp->status);
   2489   1.1    pooka 	bytes_read = le16toh(nvm_resp->length);
   2490   1.1    pooka 	offset_read = le16toh(nvm_resp->offset);
   2491   1.1    pooka 	resp_data = nvm_resp->data;
   2492  1.45   nonaka 	if (err) {
   2493  1.45   nonaka 		err = EINVAL;
   2494   1.1    pooka 		goto exit;
   2495   1.1    pooka 	}
   2496   1.1    pooka 
   2497   1.1    pooka 	if (offset_read != offset) {
   2498  1.45   nonaka 		err = EINVAL;
   2499  1.45   nonaka 		goto exit;
   2500  1.45   nonaka 	}
   2501  1.45   nonaka 	if (bytes_read > length) {
   2502  1.45   nonaka 		err = EINVAL;
   2503   1.1    pooka 		goto exit;
   2504   1.1    pooka 	}
   2505   1.1    pooka 
   2506   1.1    pooka 	memcpy(data + offset, resp_data, bytes_read);
   2507   1.1    pooka 	*len = bytes_read;
   2508   1.1    pooka 
   2509   1.1    pooka  exit:
   2510   1.1    pooka 	iwm_free_resp(sc, &cmd);
   2511  1.45   nonaka 	return err;
   2512   1.1    pooka }
   2513   1.1    pooka 
   2514   1.1    pooka /*
   2515   1.1    pooka  * Reads an NVM section completely.
   2516   1.1    pooka  * NICs prior to 7000 family doesn't have a real NVM, but just read
   2517   1.1    pooka  * section 0 which is the EEPROM. Because the EEPROM reading is unlimited
   2518   1.1    pooka  * by uCode, we need to manually check in this case that we don't
   2519   1.1    pooka  * overflow and try to read more than the EEPROM size.
   2520   1.1    pooka  */
   2521   1.4   nonaka static int
   2522  1.45   nonaka iwm_nvm_read_section(struct iwm_softc *sc, uint16_t section, uint8_t *data,
   2523  1.45   nonaka     uint16_t *len, size_t max_len)
   2524   1.1    pooka {
   2525  1.45   nonaka 	uint16_t chunklen, seglen;
   2526  1.45   nonaka 	int err;
   2527   1.1    pooka 
   2528  1.45   nonaka 	chunklen = seglen = IWM_NVM_DEFAULT_CHUNK_SIZE;
   2529   1.1    pooka 	*len = 0;
   2530   1.1    pooka 
   2531  1.45   nonaka 	/* Read NVM chunks until exhausted (reading less than requested) */
   2532  1.45   nonaka 	while (seglen == chunklen && *len < max_len) {
   2533  1.45   nonaka 		err = iwm_nvm_read_chunk(sc, section, *len, chunklen, data,
   2534  1.45   nonaka 		    &seglen);
   2535  1.45   nonaka 		if (err) {
   2536  1.61   nonaka 			DPRINTF(("%s: Cannot read NVM from section %d "
   2537  1.45   nonaka 			    "offset %d, length %d\n",
   2538  1.45   nonaka 			    DEVNAME(sc), section, *len, chunklen));
   2539  1.45   nonaka 			return err;
   2540   1.1    pooka 		}
   2541   1.1    pooka 		*len += seglen;
   2542   1.1    pooka 	}
   2543   1.1    pooka 
   2544   1.1    pooka 	DPRINTFN(4, ("NVM section %d read completed\n", section));
   2545   1.1    pooka 	return 0;
   2546   1.1    pooka }
   2547   1.1    pooka 
   2548  1.45   nonaka static uint8_t
   2549  1.45   nonaka iwm_fw_valid_tx_ant(struct iwm_softc *sc)
   2550  1.45   nonaka {
   2551  1.45   nonaka 	uint8_t tx_ant;
   2552  1.45   nonaka 
   2553  1.45   nonaka 	tx_ant = ((sc->sc_fw_phy_config & IWM_FW_PHY_CFG_TX_CHAIN)
   2554  1.45   nonaka 	    >> IWM_FW_PHY_CFG_TX_CHAIN_POS);
   2555  1.45   nonaka 
   2556  1.45   nonaka 	if (sc->sc_nvm.valid_tx_ant)
   2557  1.45   nonaka 		tx_ant &= sc->sc_nvm.valid_tx_ant;
   2558  1.45   nonaka 
   2559  1.45   nonaka 	return tx_ant;
   2560  1.45   nonaka }
   2561   1.1    pooka 
   2562  1.45   nonaka static uint8_t
   2563  1.45   nonaka iwm_fw_valid_rx_ant(struct iwm_softc *sc)
   2564  1.45   nonaka {
   2565  1.45   nonaka 	uint8_t rx_ant;
   2566   1.1    pooka 
   2567  1.45   nonaka 	rx_ant = ((sc->sc_fw_phy_config & IWM_FW_PHY_CFG_RX_CHAIN)
   2568  1.45   nonaka 	    >> IWM_FW_PHY_CFG_RX_CHAIN_POS);
   2569   1.1    pooka 
   2570  1.45   nonaka 	if (sc->sc_nvm.valid_rx_ant)
   2571  1.45   nonaka 		rx_ant &= sc->sc_nvm.valid_rx_ant;
   2572   1.1    pooka 
   2573  1.45   nonaka 	return rx_ant;
   2574  1.45   nonaka }
   2575   1.1    pooka 
   2576   1.4   nonaka static void
   2577  1.45   nonaka iwm_init_channel_map(struct iwm_softc *sc, const uint16_t * const nvm_ch_flags,
   2578  1.45   nonaka     const uint8_t *nvm_channels, size_t nchan)
   2579   1.1    pooka {
   2580   1.1    pooka 	struct ieee80211com *ic = &sc->sc_ic;
   2581   1.1    pooka 	struct iwm_nvm_data *data = &sc->sc_nvm;
   2582   1.1    pooka 	int ch_idx;
   2583   1.1    pooka 	struct ieee80211_channel *channel;
   2584   1.1    pooka 	uint16_t ch_flags;
   2585   1.1    pooka 	int is_5ghz;
   2586   1.1    pooka 	int flags, hw_value;
   2587   1.1    pooka 
   2588  1.45   nonaka 	for (ch_idx = 0; ch_idx < nchan; ch_idx++) {
   2589   1.1    pooka 		ch_flags = le16_to_cpup(nvm_ch_flags + ch_idx);
   2590  1.64   nonaka 		aprint_debug_dev(sc->sc_dev,
   2591  1.64   nonaka 		    "Ch. %d: %svalid %cibss %s %cradar %cdfs"
   2592  1.64   nonaka 		    " %cwide %c40MHz %c80MHz %c160MHz\n",
   2593  1.64   nonaka 		    nvm_channels[ch_idx],
   2594  1.64   nonaka 		    ch_flags & IWM_NVM_CHANNEL_VALID ? "" : "in",
   2595  1.64   nonaka 		    ch_flags & IWM_NVM_CHANNEL_IBSS ? '+' : '-',
   2596  1.64   nonaka 		    ch_flags & IWM_NVM_CHANNEL_ACTIVE ? "active" : "passive",
   2597  1.64   nonaka 		    ch_flags & IWM_NVM_CHANNEL_RADAR ? '+' : '-',
   2598  1.64   nonaka 		    ch_flags & IWM_NVM_CHANNEL_DFS ? '+' : '-',
   2599  1.64   nonaka 		    ch_flags & IWM_NVM_CHANNEL_WIDE ? '+' : '-',
   2600  1.64   nonaka 		    ch_flags & IWM_NVM_CHANNEL_40MHZ ? '+' : '-',
   2601  1.64   nonaka 		    ch_flags & IWM_NVM_CHANNEL_80MHZ ? '+' : '-',
   2602  1.64   nonaka 		    ch_flags & IWM_NVM_CHANNEL_160MHZ ? '+' : '-');
   2603   1.1    pooka 
   2604   1.1    pooka 		if (ch_idx >= IWM_NUM_2GHZ_CHANNELS &&
   2605   1.1    pooka 		    !data->sku_cap_band_52GHz_enable)
   2606   1.1    pooka 			ch_flags &= ~IWM_NVM_CHANNEL_VALID;
   2607   1.1    pooka 
   2608   1.1    pooka 		if (!(ch_flags & IWM_NVM_CHANNEL_VALID)) {
   2609   1.1    pooka 			DPRINTF(("Ch. %d Flags %x [%sGHz] - No traffic\n",
   2610  1.64   nonaka 			    nvm_channels[ch_idx], ch_flags,
   2611  1.64   nonaka 			    (ch_idx >= IWM_NUM_2GHZ_CHANNELS) ? "5" : "2.4"));
   2612   1.1    pooka 			continue;
   2613   1.1    pooka 		}
   2614   1.1    pooka 
   2615  1.45   nonaka 		hw_value = nvm_channels[ch_idx];
   2616   1.1    pooka 		channel = &ic->ic_channels[hw_value];
   2617   1.1    pooka 
   2618   1.1    pooka 		is_5ghz = ch_idx >= IWM_NUM_2GHZ_CHANNELS;
   2619   1.1    pooka 		if (!is_5ghz) {
   2620   1.1    pooka 			flags = IEEE80211_CHAN_2GHZ;
   2621   1.1    pooka 			channel->ic_flags
   2622   1.1    pooka 			    = IEEE80211_CHAN_CCK
   2623   1.1    pooka 			    | IEEE80211_CHAN_OFDM
   2624   1.1    pooka 			    | IEEE80211_CHAN_DYN
   2625   1.1    pooka 			    | IEEE80211_CHAN_2GHZ;
   2626   1.1    pooka 		} else {
   2627   1.1    pooka 			flags = IEEE80211_CHAN_5GHZ;
   2628   1.1    pooka 			channel->ic_flags =
   2629   1.1    pooka 			    IEEE80211_CHAN_A;
   2630   1.1    pooka 		}
   2631   1.1    pooka 		channel->ic_freq = ieee80211_ieee2mhz(hw_value, flags);
   2632   1.1    pooka 
   2633   1.1    pooka 		if (!(ch_flags & IWM_NVM_CHANNEL_ACTIVE))
   2634   1.1    pooka 			channel->ic_flags |= IEEE80211_CHAN_PASSIVE;
   2635  1.45   nonaka 
   2636  1.45   nonaka #ifndef IEEE80211_NO_HT
   2637  1.45   nonaka 		if (data->sku_cap_11n_enable)
   2638  1.45   nonaka 			channel->ic_flags |= IEEE80211_CHAN_HT;
   2639  1.45   nonaka #endif
   2640  1.45   nonaka 	}
   2641  1.45   nonaka }
   2642  1.45   nonaka 
   2643  1.45   nonaka #ifndef IEEE80211_NO_HT
   2644  1.45   nonaka static void
   2645  1.45   nonaka iwm_setup_ht_rates(struct iwm_softc *sc)
   2646  1.45   nonaka {
   2647  1.45   nonaka 	struct ieee80211com *ic = &sc->sc_ic;
   2648  1.45   nonaka 
   2649  1.45   nonaka 	/* TX is supported with the same MCS as RX. */
   2650  1.45   nonaka 	ic->ic_tx_mcs_set = IEEE80211_TX_MCS_SET_DEFINED;
   2651  1.45   nonaka 
   2652  1.45   nonaka 	ic->ic_sup_mcs[0] = 0xff;		/* MCS 0-7 */
   2653  1.45   nonaka 
   2654  1.45   nonaka #ifdef notyet
   2655  1.45   nonaka 	if (sc->sc_nvm.sku_cap_mimo_disable)
   2656  1.45   nonaka 		return;
   2657  1.45   nonaka 
   2658  1.45   nonaka 	if (iwm_fw_valid_rx_ant(sc) > 1)
   2659  1.45   nonaka 		ic->ic_sup_mcs[1] = 0xff;	/* MCS 8-15 */
   2660  1.45   nonaka 	if (iwm_fw_valid_rx_ant(sc) > 2)
   2661  1.45   nonaka 		ic->ic_sup_mcs[2] = 0xff;	/* MCS 16-23 */
   2662  1.45   nonaka #endif
   2663  1.45   nonaka }
   2664  1.45   nonaka 
   2665  1.45   nonaka #define IWM_MAX_RX_BA_SESSIONS 16
   2666  1.45   nonaka 
   2667  1.45   nonaka static void
   2668  1.45   nonaka iwm_sta_rx_agg(struct iwm_softc *sc, struct ieee80211_node *ni, uint8_t tid,
   2669  1.45   nonaka     uint16_t ssn, int start)
   2670  1.45   nonaka {
   2671  1.45   nonaka 	struct ieee80211com *ic = &sc->sc_ic;
   2672  1.45   nonaka 	struct iwm_add_sta_cmd_v7 cmd;
   2673  1.45   nonaka 	struct iwm_node *in = (struct iwm_node *)ni;
   2674  1.45   nonaka 	int err, s;
   2675  1.45   nonaka 	uint32_t status;
   2676  1.45   nonaka 
   2677  1.45   nonaka 	if (start && sc->sc_rx_ba_sessions >= IWM_MAX_RX_BA_SESSIONS) {
   2678  1.45   nonaka 		ieee80211_addba_req_refuse(ic, ni, tid);
   2679  1.45   nonaka 		return;
   2680  1.45   nonaka 	}
   2681  1.45   nonaka 
   2682  1.45   nonaka 	memset(&cmd, 0, sizeof(cmd));
   2683  1.45   nonaka 
   2684  1.45   nonaka 	cmd.sta_id = IWM_STATION_ID;
   2685  1.45   nonaka 	cmd.mac_id_n_color
   2686  1.45   nonaka 	    = htole32(IWM_FW_CMD_ID_AND_COLOR(in->in_id, in->in_color));
   2687  1.45   nonaka 	cmd.add_modify = IWM_STA_MODE_MODIFY;
   2688  1.45   nonaka 
   2689  1.45   nonaka 	if (start) {
   2690  1.45   nonaka 		cmd.add_immediate_ba_tid = (uint8_t)tid;
   2691  1.45   nonaka 		cmd.add_immediate_ba_ssn = ssn;
   2692  1.45   nonaka 	} else {
   2693  1.45   nonaka 		cmd.remove_immediate_ba_tid = (uint8_t)tid;
   2694  1.45   nonaka 	}
   2695  1.45   nonaka 	cmd.modify_mask = start ? IWM_STA_MODIFY_ADD_BA_TID :
   2696  1.45   nonaka 	    IWM_STA_MODIFY_REMOVE_BA_TID;
   2697  1.45   nonaka 
   2698  1.45   nonaka 	status = IWM_ADD_STA_SUCCESS;
   2699  1.45   nonaka 	err = iwm_send_cmd_pdu_status(sc, IWM_ADD_STA, sizeof(cmd), &cmd,
   2700  1.45   nonaka 	    &status);
   2701  1.45   nonaka 
   2702  1.45   nonaka 	s = splnet();
   2703  1.45   nonaka 	if (err == 0 && status == IWM_ADD_STA_SUCCESS) {
   2704  1.45   nonaka 		if (start) {
   2705  1.45   nonaka 			sc->sc_rx_ba_sessions++;
   2706  1.45   nonaka 			ieee80211_addba_req_accept(ic, ni, tid);
   2707  1.45   nonaka 		} else if (sc->sc_rx_ba_sessions > 0)
   2708  1.45   nonaka 			sc->sc_rx_ba_sessions--;
   2709  1.45   nonaka 	} else if (start)
   2710  1.45   nonaka 		ieee80211_addba_req_refuse(ic, ni, tid);
   2711  1.45   nonaka 	splx(s);
   2712  1.45   nonaka }
   2713  1.45   nonaka 
   2714  1.45   nonaka static void
   2715  1.45   nonaka iwm_htprot_task(void *arg)
   2716  1.45   nonaka {
   2717  1.45   nonaka 	struct iwm_softc *sc = arg;
   2718  1.45   nonaka 	struct ieee80211com *ic = &sc->sc_ic;
   2719  1.45   nonaka 	struct iwm_node *in = (struct iwm_node *)ic->ic_bss;
   2720  1.45   nonaka 	int err;
   2721  1.45   nonaka 
   2722  1.45   nonaka 	/* This call updates HT protection based on in->in_ni.ni_htop1. */
   2723  1.45   nonaka 	err = iwm_mac_ctxt_cmd(sc, in, IWM_FW_CTXT_ACTION_MODIFY, 1);
   2724  1.45   nonaka 	if (err)
   2725  1.45   nonaka 		aprint_error_dev(sc->sc_dev,
   2726  1.45   nonaka 		    "could not change HT protection: error %d\n", err);
   2727  1.45   nonaka }
   2728  1.45   nonaka 
   2729  1.45   nonaka /*
   2730  1.45   nonaka  * This function is called by upper layer when HT protection settings in
   2731  1.45   nonaka  * beacons have changed.
   2732  1.45   nonaka  */
   2733  1.45   nonaka static void
   2734  1.45   nonaka iwm_update_htprot(struct ieee80211com *ic, struct ieee80211_node *ni)
   2735  1.45   nonaka {
   2736  1.45   nonaka 	struct iwm_softc *sc = ic->ic_softc;
   2737  1.45   nonaka 
   2738  1.45   nonaka 	/* assumes that ni == ic->ic_bss */
   2739  1.45   nonaka 	task_add(systq, &sc->htprot_task);
   2740  1.45   nonaka }
   2741  1.45   nonaka 
   2742  1.45   nonaka static void
   2743  1.45   nonaka iwm_ba_task(void *arg)
   2744  1.45   nonaka {
   2745  1.45   nonaka 	struct iwm_softc *sc = arg;
   2746  1.45   nonaka 	struct ieee80211com *ic = &sc->sc_ic;
   2747  1.45   nonaka 	struct ieee80211_node *ni = ic->ic_bss;
   2748  1.45   nonaka 
   2749  1.45   nonaka 	if (sc->ba_start)
   2750  1.45   nonaka 		iwm_sta_rx_agg(sc, ni, sc->ba_tid, sc->ba_ssn, 1);
   2751  1.45   nonaka 	else
   2752  1.45   nonaka 		iwm_sta_rx_agg(sc, ni, sc->ba_tid, 0, 0);
   2753  1.45   nonaka }
   2754  1.45   nonaka 
   2755  1.45   nonaka /*
   2756  1.45   nonaka  * This function is called by upper layer when an ADDBA request is received
   2757  1.45   nonaka  * from another STA and before the ADDBA response is sent.
   2758  1.45   nonaka  */
   2759  1.45   nonaka static int
   2760  1.45   nonaka iwm_ampdu_rx_start(struct ieee80211com *ic, struct ieee80211_node *ni,
   2761  1.45   nonaka     uint8_t tid)
   2762  1.45   nonaka {
   2763  1.45   nonaka 	struct ieee80211_rx_ba *ba = &ni->ni_rx_ba[tid];
   2764  1.45   nonaka 	struct iwm_softc *sc = IC2IFP(ic)->if_softc;
   2765  1.45   nonaka 
   2766  1.45   nonaka 	if (sc->sc_rx_ba_sessions >= IWM_MAX_RX_BA_SESSIONS)
   2767  1.45   nonaka 		return ENOSPC;
   2768  1.45   nonaka 
   2769  1.45   nonaka 	sc->ba_start = 1;
   2770  1.45   nonaka 	sc->ba_tid = tid;
   2771  1.45   nonaka 	sc->ba_ssn = htole16(ba->ba_winstart);
   2772  1.45   nonaka 	task_add(systq, &sc->ba_task);
   2773  1.45   nonaka 
   2774  1.45   nonaka 	return EBUSY;
   2775  1.45   nonaka }
   2776  1.45   nonaka 
   2777  1.45   nonaka /*
   2778  1.45   nonaka  * This function is called by upper layer on teardown of an HT-immediate
   2779  1.45   nonaka  * Block Ack agreement (eg. upon receipt of a DELBA frame).
   2780  1.45   nonaka  */
   2781  1.45   nonaka static void
   2782  1.45   nonaka iwm_ampdu_rx_stop(struct ieee80211com *ic, struct ieee80211_node *ni,
   2783  1.45   nonaka     uint8_t tid)
   2784  1.45   nonaka {
   2785  1.45   nonaka 	struct iwm_softc *sc = IC2IFP(ic)->if_softc;
   2786  1.45   nonaka 
   2787  1.45   nonaka 	sc->ba_start = 0;
   2788  1.45   nonaka 	sc->ba_tid = tid;
   2789  1.45   nonaka 	task_add(systq, &sc->ba_task);
   2790  1.45   nonaka }
   2791  1.45   nonaka #endif
   2792  1.45   nonaka 
   2793  1.45   nonaka static void
   2794  1.45   nonaka iwm_set_hw_address_8000(struct iwm_softc *sc, struct iwm_nvm_data *data,
   2795  1.45   nonaka     const uint16_t *mac_override, const uint16_t *nvm_hw)
   2796  1.45   nonaka {
   2797  1.45   nonaka 	static const uint8_t reserved_mac[ETHER_ADDR_LEN] = {
   2798  1.45   nonaka 		0x02, 0xcc, 0xaa, 0xff, 0xee, 0x00
   2799  1.45   nonaka 	};
   2800  1.45   nonaka 	static const u_int8_t etheranyaddr[ETHER_ADDR_LEN] = {
   2801  1.45   nonaka 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00
   2802  1.45   nonaka 	};
   2803  1.45   nonaka 	const uint8_t *hw_addr;
   2804  1.45   nonaka 
   2805  1.45   nonaka 	if (mac_override) {
   2806  1.45   nonaka 		hw_addr = (const uint8_t *)(mac_override +
   2807  1.45   nonaka 		    IWM_MAC_ADDRESS_OVERRIDE_8000);
   2808  1.45   nonaka 
   2809  1.45   nonaka 		/*
   2810  1.45   nonaka 		 * Store the MAC address from MAO section.
   2811  1.45   nonaka 		 * No byte swapping is required in MAO section
   2812  1.45   nonaka 		 */
   2813  1.45   nonaka 		memcpy(data->hw_addr, hw_addr, ETHER_ADDR_LEN);
   2814  1.45   nonaka 
   2815  1.45   nonaka 		/*
   2816  1.45   nonaka 		 * Force the use of the OTP MAC address in case of reserved MAC
   2817  1.45   nonaka 		 * address in the NVM, or if address is given but invalid.
   2818  1.45   nonaka 		 */
   2819  1.45   nonaka 		if (memcmp(reserved_mac, hw_addr, ETHER_ADDR_LEN) != 0 &&
   2820  1.45   nonaka 		    (memcmp(etherbroadcastaddr, data->hw_addr,
   2821  1.45   nonaka 		    sizeof(etherbroadcastaddr)) != 0) &&
   2822  1.45   nonaka 		    (memcmp(etheranyaddr, data->hw_addr,
   2823  1.45   nonaka 		    sizeof(etheranyaddr)) != 0) &&
   2824  1.45   nonaka 		    !ETHER_IS_MULTICAST(data->hw_addr))
   2825  1.45   nonaka 			return;
   2826  1.45   nonaka 	}
   2827  1.45   nonaka 
   2828  1.45   nonaka 	if (nvm_hw) {
   2829  1.45   nonaka 		/* Read the mac address from WFMP registers. */
   2830  1.45   nonaka 		uint32_t mac_addr0 =
   2831  1.45   nonaka 		    htole32(iwm_read_prph(sc, IWM_WFMP_MAC_ADDR_0));
   2832  1.45   nonaka 		uint32_t mac_addr1 =
   2833  1.45   nonaka 		    htole32(iwm_read_prph(sc, IWM_WFMP_MAC_ADDR_1));
   2834  1.45   nonaka 
   2835  1.45   nonaka 		hw_addr = (const uint8_t *)&mac_addr0;
   2836  1.45   nonaka 		data->hw_addr[0] = hw_addr[3];
   2837  1.45   nonaka 		data->hw_addr[1] = hw_addr[2];
   2838  1.45   nonaka 		data->hw_addr[2] = hw_addr[1];
   2839  1.45   nonaka 		data->hw_addr[3] = hw_addr[0];
   2840  1.45   nonaka 
   2841  1.45   nonaka 		hw_addr = (const uint8_t *)&mac_addr1;
   2842  1.45   nonaka 		data->hw_addr[4] = hw_addr[1];
   2843  1.45   nonaka 		data->hw_addr[5] = hw_addr[0];
   2844  1.45   nonaka 
   2845  1.45   nonaka 		return;
   2846   1.1    pooka 	}
   2847  1.45   nonaka 
   2848  1.45   nonaka 	aprint_error_dev(sc->sc_dev, "mac address not found\n");
   2849  1.45   nonaka 	memset(data->hw_addr, 0, sizeof(data->hw_addr));
   2850   1.1    pooka }
   2851   1.1    pooka 
   2852   1.4   nonaka static int
   2853  1.45   nonaka iwm_parse_nvm_data(struct iwm_softc *sc, const uint16_t *nvm_hw,
   2854  1.45   nonaka     const uint16_t *nvm_sw, const uint16_t *nvm_calib,
   2855  1.45   nonaka     const uint16_t *mac_override, const uint16_t *phy_sku,
   2856  1.45   nonaka     const uint16_t *regulatory)
   2857   1.1    pooka {
   2858   1.1    pooka 	struct iwm_nvm_data *data = &sc->sc_nvm;
   2859   1.1    pooka 	uint8_t hw_addr[ETHER_ADDR_LEN];
   2860  1.45   nonaka 	uint32_t sku;
   2861   1.1    pooka 
   2862  1.45   nonaka 	if (sc->sc_device_family == IWM_DEVICE_FAMILY_7000) {
   2863  1.45   nonaka 		uint16_t radio_cfg = le16_to_cpup(nvm_sw + IWM_RADIO_CFG);
   2864  1.45   nonaka 		data->radio_cfg_type = IWM_NVM_RF_CFG_TYPE_MSK(radio_cfg);
   2865  1.45   nonaka 		data->radio_cfg_step = IWM_NVM_RF_CFG_STEP_MSK(radio_cfg);
   2866  1.45   nonaka 		data->radio_cfg_dash = IWM_NVM_RF_CFG_DASH_MSK(radio_cfg);
   2867  1.45   nonaka 		data->radio_cfg_pnum = IWM_NVM_RF_CFG_PNUM_MSK(radio_cfg);
   2868  1.45   nonaka 
   2869  1.61   nonaka 		data->nvm_version = le16_to_cpup(nvm_sw + IWM_NVM_VERSION);
   2870  1.45   nonaka 		sku = le16_to_cpup(nvm_sw + IWM_SKU);
   2871  1.45   nonaka 	} else {
   2872  1.61   nonaka 		uint32_t radio_cfg = le32_to_cpup(phy_sku + IWM_RADIO_CFG_8000);
   2873  1.45   nonaka 		data->radio_cfg_type = IWM_NVM_RF_CFG_TYPE_MSK_8000(radio_cfg);
   2874  1.45   nonaka 		data->radio_cfg_step = IWM_NVM_RF_CFG_STEP_MSK_8000(radio_cfg);
   2875  1.45   nonaka 		data->radio_cfg_dash = IWM_NVM_RF_CFG_DASH_MSK_8000(radio_cfg);
   2876  1.45   nonaka 		data->radio_cfg_pnum = IWM_NVM_RF_CFG_PNUM_MSK_8000(radio_cfg);
   2877  1.45   nonaka 		data->valid_tx_ant = IWM_NVM_RF_CFG_TX_ANT_MSK_8000(radio_cfg);
   2878  1.45   nonaka 		data->valid_rx_ant = IWM_NVM_RF_CFG_RX_ANT_MSK_8000(radio_cfg);
   2879  1.45   nonaka 
   2880  1.61   nonaka 		data->nvm_version = le32_to_cpup(nvm_sw + IWM_NVM_VERSION_8000);
   2881  1.61   nonaka 		sku = le32_to_cpup(phy_sku + IWM_SKU_8000);
   2882  1.45   nonaka 	}
   2883   1.1    pooka 
   2884   1.1    pooka 	data->sku_cap_band_24GHz_enable = sku & IWM_NVM_SKU_CAP_BAND_24GHZ;
   2885   1.1    pooka 	data->sku_cap_band_52GHz_enable = sku & IWM_NVM_SKU_CAP_BAND_52GHZ;
   2886  1.45   nonaka 	data->sku_cap_11n_enable = sku & IWM_NVM_SKU_CAP_11N_ENABLE;
   2887  1.45   nonaka 	data->sku_cap_mimo_disable = sku & IWM_NVM_SKU_CAP_MIMO_DISABLE;
   2888   1.1    pooka 
   2889   1.1    pooka 	data->n_hw_addrs = le16_to_cpup(nvm_sw + IWM_N_HW_ADDRS);
   2890   1.1    pooka 
   2891  1.45   nonaka 	if (sc->sc_device_family == IWM_DEVICE_FAMILY_7000) {
   2892  1.45   nonaka 		memcpy(hw_addr, nvm_hw + IWM_HW_ADDR, ETHER_ADDR_LEN);
   2893  1.45   nonaka 		data->hw_addr[0] = hw_addr[1];
   2894  1.45   nonaka 		data->hw_addr[1] = hw_addr[0];
   2895  1.45   nonaka 		data->hw_addr[2] = hw_addr[3];
   2896  1.45   nonaka 		data->hw_addr[3] = hw_addr[2];
   2897  1.45   nonaka 		data->hw_addr[4] = hw_addr[5];
   2898  1.45   nonaka 		data->hw_addr[5] = hw_addr[4];
   2899  1.45   nonaka 	} else
   2900  1.45   nonaka 		iwm_set_hw_address_8000(sc, data, mac_override, nvm_hw);
   2901   1.1    pooka 
   2902  1.60   nonaka 	if (sc->sc_device_family == IWM_DEVICE_FAMILY_8000) {
   2903  1.60   nonaka 		uint16_t lar_offset, lar_config;
   2904  1.60   nonaka 		lar_offset = data->nvm_version < 0xE39 ?
   2905  1.60   nonaka 		    IWM_NVM_LAR_OFFSET_8000_OLD : IWM_NVM_LAR_OFFSET_8000;
   2906  1.60   nonaka 		lar_config = le16_to_cpup(regulatory + lar_offset);
   2907  1.60   nonaka                 data->lar_enabled = !!(lar_config & IWM_NVM_LAR_ENABLED_8000);
   2908  1.60   nonaka 	}
   2909  1.60   nonaka 
   2910  1.45   nonaka 	if (sc->sc_device_family == IWM_DEVICE_FAMILY_7000)
   2911  1.45   nonaka 		iwm_init_channel_map(sc, &nvm_sw[IWM_NVM_CHANNELS],
   2912  1.45   nonaka 		    iwm_nvm_channels, __arraycount(iwm_nvm_channels));
   2913  1.45   nonaka 	else
   2914  1.45   nonaka 		iwm_init_channel_map(sc, &regulatory[IWM_NVM_CHANNELS_8000],
   2915  1.45   nonaka 		    iwm_nvm_channels_8000, __arraycount(iwm_nvm_channels_8000));
   2916   1.1    pooka 
   2917   1.1    pooka 	data->calib_version = 255;   /* TODO:
   2918   1.1    pooka 					this value will prevent some checks from
   2919   1.1    pooka 					failing, we need to check if this
   2920   1.1    pooka 					field is still needed, and if it does,
   2921   1.1    pooka 					where is it in the NVM */
   2922   1.1    pooka 
   2923   1.1    pooka 	return 0;
   2924   1.1    pooka }
   2925   1.1    pooka 
   2926   1.1    pooka static int
   2927   1.1    pooka iwm_parse_nvm_sections(struct iwm_softc *sc, struct iwm_nvm_section *sections)
   2928   1.1    pooka {
   2929  1.45   nonaka 	const uint16_t *hw, *sw, *calib, *mac_override = NULL, *phy_sku = NULL;
   2930  1.45   nonaka 	const uint16_t *regulatory = NULL;
   2931   1.1    pooka 
   2932   1.1    pooka 	/* Checking for required sections */
   2933  1.45   nonaka 	if (sc->sc_device_family == IWM_DEVICE_FAMILY_7000) {
   2934  1.45   nonaka 		if (!sections[IWM_NVM_SECTION_TYPE_SW].data ||
   2935  1.45   nonaka 		    !sections[IWM_NVM_SECTION_TYPE_HW].data) {
   2936  1.45   nonaka 			return ENOENT;
   2937  1.45   nonaka 		}
   2938  1.45   nonaka 
   2939  1.45   nonaka 		hw = (const uint16_t *) sections[IWM_NVM_SECTION_TYPE_HW].data;
   2940  1.45   nonaka 	} else if (sc->sc_device_family == IWM_DEVICE_FAMILY_8000) {
   2941  1.45   nonaka 		/* SW and REGULATORY sections are mandatory */
   2942  1.45   nonaka 		if (!sections[IWM_NVM_SECTION_TYPE_SW].data ||
   2943  1.45   nonaka 		    !sections[IWM_NVM_SECTION_TYPE_REGULATORY].data) {
   2944  1.45   nonaka 			return ENOENT;
   2945  1.45   nonaka 		}
   2946  1.45   nonaka 		/* MAC_OVERRIDE or at least HW section must exist */
   2947  1.45   nonaka 		if (!sections[IWM_NVM_SECTION_TYPE_HW_8000].data &&
   2948  1.45   nonaka 		    !sections[IWM_NVM_SECTION_TYPE_MAC_OVERRIDE].data) {
   2949  1.45   nonaka 			return ENOENT;
   2950  1.45   nonaka 		}
   2951  1.45   nonaka 
   2952  1.45   nonaka 		/* PHY_SKU section is mandatory in B0 */
   2953  1.45   nonaka 		if (!sections[IWM_NVM_SECTION_TYPE_PHY_SKU].data) {
   2954  1.45   nonaka 			return ENOENT;
   2955  1.45   nonaka 		}
   2956  1.45   nonaka 
   2957  1.45   nonaka 		regulatory = (const uint16_t *)
   2958  1.45   nonaka 		    sections[IWM_NVM_SECTION_TYPE_REGULATORY].data;
   2959  1.45   nonaka 		hw = (const uint16_t *)
   2960  1.45   nonaka 		    sections[IWM_NVM_SECTION_TYPE_HW_8000].data;
   2961  1.45   nonaka 		mac_override =
   2962  1.45   nonaka 			(const uint16_t *)
   2963  1.45   nonaka 			sections[IWM_NVM_SECTION_TYPE_MAC_OVERRIDE].data;
   2964  1.45   nonaka 		phy_sku = (const uint16_t *)
   2965  1.45   nonaka 		    sections[IWM_NVM_SECTION_TYPE_PHY_SKU].data;
   2966  1.45   nonaka 	} else {
   2967  1.45   nonaka 		panic("unknown device family %d\n", sc->sc_device_family);
   2968   1.1    pooka 	}
   2969   1.1    pooka 
   2970   1.1    pooka 	sw = (const uint16_t *)sections[IWM_NVM_SECTION_TYPE_SW].data;
   2971  1.45   nonaka 	calib = (const uint16_t *)
   2972  1.45   nonaka 	    sections[IWM_NVM_SECTION_TYPE_CALIBRATION].data;
   2973  1.45   nonaka 
   2974  1.45   nonaka 	return iwm_parse_nvm_data(sc, hw, sw, calib, mac_override,
   2975  1.45   nonaka 	    phy_sku, regulatory);
   2976   1.1    pooka }
   2977   1.1    pooka 
   2978   1.4   nonaka static int
   2979   1.1    pooka iwm_nvm_init(struct iwm_softc *sc)
   2980   1.1    pooka {
   2981   1.1    pooka 	struct iwm_nvm_section nvm_sections[IWM_NVM_NUM_OF_SECTIONS];
   2982  1.45   nonaka 	int i, section, err;
   2983   1.1    pooka 	uint16_t len;
   2984  1.45   nonaka 	uint8_t *buf;
   2985  1.61   nonaka 	const size_t bufsz = (sc->sc_device_family == IWM_DEVICE_FAMILY_8000) ?
   2986  1.61   nonaka 	    IWM_MAX_NVM_SECTION_SIZE_8000 : IWM_MAX_NVM_SECTION_SIZE_7000;
   2987   1.1    pooka 
   2988   1.1    pooka 	/* Read From FW NVM */
   2989   1.1    pooka 	DPRINTF(("Read NVM\n"));
   2990   1.1    pooka 
   2991  1.45   nonaka 	memset(nvm_sections, 0, sizeof(nvm_sections));
   2992  1.45   nonaka 
   2993  1.45   nonaka 	buf = kmem_alloc(bufsz, KM_SLEEP);
   2994  1.45   nonaka 	if (buf == NULL)
   2995  1.45   nonaka 		return ENOMEM;
   2996  1.45   nonaka 
   2997  1.45   nonaka 	for (i = 0; i < __arraycount(iwm_nvm_to_read); i++) {
   2998  1.45   nonaka 		section = iwm_nvm_to_read[i];
   2999  1.45   nonaka 		KASSERT(section <= IWM_NVM_NUM_OF_SECTIONS);
   3000  1.45   nonaka 
   3001  1.45   nonaka 		err = iwm_nvm_read_section(sc, section, buf, &len, bufsz);
   3002  1.45   nonaka 		if (err) {
   3003  1.45   nonaka 			err = 0;
   3004  1.45   nonaka 			continue;
   3005  1.45   nonaka 		}
   3006  1.45   nonaka 		nvm_sections[section].data = kmem_alloc(len, KM_SLEEP);
   3007  1.45   nonaka 		if (nvm_sections[section].data == NULL) {
   3008  1.45   nonaka 			err = ENOMEM;
   3009   1.1    pooka 			break;
   3010  1.45   nonaka 		}
   3011  1.45   nonaka 		memcpy(nvm_sections[section].data, buf, len);
   3012  1.45   nonaka 		nvm_sections[section].length = len;
   3013  1.45   nonaka 	}
   3014  1.45   nonaka 	kmem_free(buf, bufsz);
   3015  1.45   nonaka 	if (err == 0)
   3016  1.45   nonaka 		err = iwm_parse_nvm_sections(sc, nvm_sections);
   3017   1.1    pooka 
   3018  1.45   nonaka 	for (i = 0; i < IWM_NVM_NUM_OF_SECTIONS; i++) {
   3019  1.45   nonaka 		if (nvm_sections[i].data != NULL)
   3020  1.45   nonaka 			kmem_free(nvm_sections[i].data, nvm_sections[i].length);
   3021   1.1    pooka 	}
   3022   1.1    pooka 
   3023  1.45   nonaka 	return err;
   3024   1.1    pooka }
   3025   1.1    pooka 
   3026  1.45   nonaka static int
   3027  1.45   nonaka iwm_firmware_load_sect(struct iwm_softc *sc, uint32_t dst_addr,
   3028  1.45   nonaka     const uint8_t *section, uint32_t byte_cnt)
   3029  1.45   nonaka {
   3030  1.45   nonaka 	int err = EINVAL;
   3031  1.45   nonaka 	uint32_t chunk_sz, offset;
   3032  1.45   nonaka 
   3033  1.45   nonaka 	chunk_sz = MIN(IWM_FH_MEM_TB_MAX_LENGTH, byte_cnt);
   3034  1.45   nonaka 
   3035  1.45   nonaka 	for (offset = 0; offset < byte_cnt; offset += chunk_sz) {
   3036  1.45   nonaka 		uint32_t addr, len;
   3037  1.45   nonaka 		const uint8_t *data;
   3038  1.61   nonaka 		bool is_extended = false;
   3039  1.45   nonaka 
   3040  1.45   nonaka 		addr = dst_addr + offset;
   3041  1.45   nonaka 		len = MIN(chunk_sz, byte_cnt - offset);
   3042  1.45   nonaka 		data = section + offset;
   3043  1.45   nonaka 
   3044  1.61   nonaka 		if (addr >= IWM_FW_MEM_EXTENDED_START &&
   3045  1.61   nonaka 		    addr <= IWM_FW_MEM_EXTENDED_END)
   3046  1.61   nonaka 			is_extended = true;
   3047  1.61   nonaka 
   3048  1.61   nonaka 		if (is_extended)
   3049  1.61   nonaka 			iwm_set_bits_prph(sc, IWM_LMPM_CHICK,
   3050  1.61   nonaka 			    IWM_LMPM_CHICK_EXTENDED_ADDR_SPACE);
   3051  1.61   nonaka 
   3052  1.45   nonaka 		err = iwm_firmware_load_chunk(sc, addr, data, len);
   3053  1.61   nonaka 
   3054  1.61   nonaka 		if (is_extended)
   3055  1.61   nonaka 			iwm_clear_bits_prph(sc, IWM_LMPM_CHICK,
   3056  1.61   nonaka 			    IWM_LMPM_CHICK_EXTENDED_ADDR_SPACE);
   3057  1.61   nonaka 
   3058  1.45   nonaka 		if (err)
   3059  1.45   nonaka 			break;
   3060  1.45   nonaka 	}
   3061  1.45   nonaka 
   3062  1.45   nonaka 	return err;
   3063  1.45   nonaka }
   3064   1.1    pooka 
   3065   1.4   nonaka static int
   3066   1.1    pooka iwm_firmware_load_chunk(struct iwm_softc *sc, uint32_t dst_addr,
   3067  1.45   nonaka     const uint8_t *section, uint32_t byte_cnt)
   3068   1.1    pooka {
   3069   1.1    pooka 	struct iwm_dma_info *dma = &sc->fw_dma;
   3070  1.45   nonaka 	int err;
   3071   1.1    pooka 
   3072  1.45   nonaka 	/* Copy firmware chunk into pre-allocated DMA-safe memory. */
   3073   1.1    pooka 	memcpy(dma->vaddr, section, byte_cnt);
   3074  1.45   nonaka 	bus_dmamap_sync(sc->sc_dmat, dma->map, 0, byte_cnt,
   3075  1.45   nonaka 	    BUS_DMASYNC_PREWRITE);
   3076   1.1    pooka 
   3077   1.1    pooka 	sc->sc_fw_chunk_done = 0;
   3078   1.1    pooka 
   3079  1.61   nonaka 	if (!iwm_nic_lock(sc))
   3080  1.45   nonaka 		return EBUSY;
   3081  1.45   nonaka 
   3082   1.1    pooka 	IWM_WRITE(sc, IWM_FH_TCSR_CHNL_TX_CONFIG_REG(IWM_FH_SRVC_CHNL),
   3083   1.1    pooka 	    IWM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE);
   3084   1.1    pooka 	IWM_WRITE(sc, IWM_FH_SRVC_CHNL_SRAM_ADDR_REG(IWM_FH_SRVC_CHNL),
   3085   1.1    pooka 	    dst_addr);
   3086   1.1    pooka 	IWM_WRITE(sc, IWM_FH_TFDIB_CTRL0_REG(IWM_FH_SRVC_CHNL),
   3087   1.1    pooka 	    dma->paddr & IWM_FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK);
   3088   1.1    pooka 	IWM_WRITE(sc, IWM_FH_TFDIB_CTRL1_REG(IWM_FH_SRVC_CHNL),
   3089   1.8   nonaka 	    (iwm_get_dma_hi_addr(dma->paddr)
   3090   1.1    pooka 	      << IWM_FH_MEM_TFDIB_REG1_ADDR_BITSHIFT) | byte_cnt);
   3091   1.1    pooka 	IWM_WRITE(sc, IWM_FH_TCSR_CHNL_TX_BUF_STS_REG(IWM_FH_SRVC_CHNL),
   3092   1.1    pooka 	    1 << IWM_FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_NUM |
   3093   1.1    pooka 	    1 << IWM_FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_IDX |
   3094   1.1    pooka 	    IWM_FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID);
   3095   1.1    pooka 	IWM_WRITE(sc, IWM_FH_TCSR_CHNL_TX_CONFIG_REG(IWM_FH_SRVC_CHNL),
   3096   1.1    pooka 	    IWM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE    |
   3097   1.1    pooka 	    IWM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE |
   3098   1.1    pooka 	    IWM_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD);
   3099   1.8   nonaka 
   3100   1.1    pooka 	iwm_nic_unlock(sc);
   3101   1.1    pooka 
   3102  1.45   nonaka 	/* Wait for this segment to load. */
   3103  1.45   nonaka 	err = 0;
   3104  1.45   nonaka 	while (!sc->sc_fw_chunk_done) {
   3105  1.45   nonaka 		err = tsleep(&sc->sc_fw, 0, "iwmfw", mstohz(5000));
   3106  1.45   nonaka 		if (err)
   3107   1.1    pooka 			break;
   3108  1.45   nonaka 	}
   3109  1.45   nonaka 	if (!sc->sc_fw_chunk_done) {
   3110  1.61   nonaka 		DPRINTF(("%s: fw chunk addr 0x%x len %d failed to load\n",
   3111  1.61   nonaka 		    DEVNAME(sc), dst_addr, byte_cnt));
   3112  1.45   nonaka 	}
   3113   1.1    pooka 
   3114  1.45   nonaka 	return err;
   3115   1.1    pooka }
   3116   1.1    pooka 
   3117   1.4   nonaka static int
   3118  1.45   nonaka iwm_load_firmware_7000(struct iwm_softc *sc, enum iwm_ucode_type ucode_type)
   3119   1.1    pooka {
   3120   1.1    pooka 	struct iwm_fw_sects *fws;
   3121  1.45   nonaka 	int err, i;
   3122   1.1    pooka 	void *data;
   3123   1.1    pooka 	uint32_t dlen;
   3124   1.1    pooka 	uint32_t offset;
   3125   1.1    pooka 
   3126   1.1    pooka 	fws = &sc->sc_fw.fw_sects[ucode_type];
   3127   1.1    pooka 	for (i = 0; i < fws->fw_count; i++) {
   3128   1.1    pooka 		data = fws->fw_sect[i].fws_data;
   3129   1.1    pooka 		dlen = fws->fw_sect[i].fws_len;
   3130   1.1    pooka 		offset = fws->fw_sect[i].fws_devoff;
   3131  1.45   nonaka 		if (dlen > sc->sc_fwdmasegsz) {
   3132  1.45   nonaka 			err = EFBIG;
   3133  1.45   nonaka 		} else
   3134  1.45   nonaka 			err = iwm_firmware_load_sect(sc, offset, data, dlen);
   3135  1.45   nonaka 		if (err) {
   3136  1.61   nonaka 			DPRINTF(("%s: could not load firmware chunk %u of %u\n",
   3137  1.61   nonaka 			    DEVNAME(sc), i, fws->fw_count));
   3138  1.45   nonaka 			return err;
   3139   1.1    pooka 		}
   3140   1.1    pooka 	}
   3141   1.1    pooka 
   3142   1.1    pooka 	IWM_WRITE(sc, IWM_CSR_RESET, 0);
   3143   1.1    pooka 
   3144  1.45   nonaka 	return 0;
   3145   1.1    pooka }
   3146   1.1    pooka 
   3147   1.4   nonaka static int
   3148  1.45   nonaka iwm_load_cpu_sections_8000(struct iwm_softc *sc, struct iwm_fw_sects *fws,
   3149  1.45   nonaka     int cpu, int *first_ucode_section)
   3150   1.1    pooka {
   3151  1.45   nonaka 	int shift_param;
   3152  1.45   nonaka 	int i, err = 0, sec_num = 0x1;
   3153  1.45   nonaka 	uint32_t val, last_read_idx = 0;
   3154  1.45   nonaka 	void *data;
   3155  1.45   nonaka 	uint32_t dlen;
   3156  1.45   nonaka 	uint32_t offset;
   3157   1.1    pooka 
   3158  1.45   nonaka 	if (cpu == 1) {
   3159  1.45   nonaka 		shift_param = 0;
   3160  1.45   nonaka 		*first_ucode_section = 0;
   3161  1.45   nonaka 	} else {
   3162  1.45   nonaka 		shift_param = 16;
   3163  1.45   nonaka 		(*first_ucode_section)++;
   3164  1.45   nonaka 	}
   3165   1.1    pooka 
   3166  1.45   nonaka 	for (i = *first_ucode_section; i < IWM_UCODE_SECT_MAX; i++) {
   3167  1.45   nonaka 		last_read_idx = i;
   3168  1.45   nonaka 		data = fws->fw_sect[i].fws_data;
   3169  1.45   nonaka 		dlen = fws->fw_sect[i].fws_len;
   3170  1.45   nonaka 		offset = fws->fw_sect[i].fws_devoff;
   3171   1.1    pooka 
   3172  1.45   nonaka 		/*
   3173  1.45   nonaka 		 * CPU1_CPU2_SEPARATOR_SECTION delimiter - separate between
   3174  1.45   nonaka 		 * CPU1 to CPU2.
   3175  1.45   nonaka 		 * PAGING_SEPARATOR_SECTION delimiter - separate between
   3176  1.45   nonaka 		 * CPU2 non paged to CPU2 paging sec.
   3177  1.45   nonaka 		 */
   3178  1.45   nonaka 		if (!data || offset == IWM_CPU1_CPU2_SEPARATOR_SECTION ||
   3179  1.45   nonaka 		    offset == IWM_PAGING_SEPARATOR_SECTION)
   3180  1.45   nonaka 			break;
   3181   1.1    pooka 
   3182  1.45   nonaka 		if (dlen > sc->sc_fwdmasegsz) {
   3183  1.45   nonaka 			err = EFBIG;
   3184  1.45   nonaka 		} else
   3185  1.45   nonaka 			err = iwm_firmware_load_sect(sc, offset, data, dlen);
   3186  1.45   nonaka 		if (err) {
   3187  1.61   nonaka 			DPRINTF(("%s: could not load firmware chunk %d "
   3188  1.61   nonaka 			    "(error %d)\n", DEVNAME(sc), i, err));
   3189  1.45   nonaka 			return err;
   3190  1.45   nonaka 		}
   3191   1.1    pooka 
   3192  1.45   nonaka 		/* Notify the ucode of the loaded section number and status */
   3193  1.45   nonaka 		if (iwm_nic_lock(sc)) {
   3194  1.45   nonaka 			val = IWM_READ(sc, IWM_FH_UCODE_LOAD_STATUS);
   3195  1.45   nonaka 			val = val | (sec_num << shift_param);
   3196  1.45   nonaka 			IWM_WRITE(sc, IWM_FH_UCODE_LOAD_STATUS, val);
   3197  1.45   nonaka 			sec_num = (sec_num << 1) | 0x1;
   3198  1.45   nonaka 			iwm_nic_unlock(sc);
   3199   1.1    pooka 
   3200  1.45   nonaka 			/*
   3201  1.45   nonaka 			 * The firmware won't load correctly without this delay.
   3202  1.45   nonaka 			 */
   3203  1.45   nonaka 			DELAY(8000);
   3204  1.45   nonaka 		}
   3205  1.45   nonaka 	}
   3206  1.45   nonaka 
   3207  1.45   nonaka 	*first_ucode_section = last_read_idx;
   3208  1.45   nonaka 
   3209  1.45   nonaka 	if (iwm_nic_lock(sc)) {
   3210  1.45   nonaka 		if (cpu == 1)
   3211  1.45   nonaka 			IWM_WRITE(sc, IWM_FH_UCODE_LOAD_STATUS, 0xFFFF);
   3212  1.45   nonaka 		else
   3213  1.45   nonaka 			IWM_WRITE(sc, IWM_FH_UCODE_LOAD_STATUS, 0xFFFFFFFF);
   3214  1.45   nonaka 		iwm_nic_unlock(sc);
   3215   1.6   nonaka 	}
   3216  1.45   nonaka 
   3217  1.45   nonaka 	return 0;
   3218  1.45   nonaka }
   3219  1.45   nonaka 
   3220  1.45   nonaka static int
   3221  1.45   nonaka iwm_load_firmware_8000(struct iwm_softc *sc, enum iwm_ucode_type ucode_type)
   3222  1.45   nonaka {
   3223  1.45   nonaka 	struct iwm_fw_sects *fws;
   3224  1.45   nonaka 	int err = 0;
   3225  1.45   nonaka 	int first_ucode_section;
   3226  1.45   nonaka 
   3227  1.45   nonaka 	fws = &sc->sc_fw.fw_sects[ucode_type];
   3228  1.45   nonaka 
   3229  1.45   nonaka 	/* configure the ucode to be ready to get the secured image */
   3230  1.45   nonaka 	/* release CPU reset */
   3231  1.61   nonaka 	if (iwm_nic_lock(sc)) {
   3232  1.61   nonaka 		iwm_write_prph(sc, IWM_RELEASE_CPU_RESET,
   3233  1.61   nonaka 		    IWM_RELEASE_CPU_RESET_BIT);
   3234  1.61   nonaka 		iwm_nic_unlock(sc);
   3235  1.61   nonaka 	}
   3236  1.45   nonaka 
   3237  1.45   nonaka 	/* load to FW the binary Secured sections of CPU1 */
   3238  1.45   nonaka 	err = iwm_load_cpu_sections_8000(sc, fws, 1, &first_ucode_section);
   3239  1.45   nonaka 	if (err)
   3240  1.45   nonaka 		return err;
   3241  1.45   nonaka 
   3242  1.45   nonaka 	/* load to FW the binary sections of CPU2 */
   3243  1.45   nonaka 	return iwm_load_cpu_sections_8000(sc, fws, 2, &first_ucode_section);
   3244  1.45   nonaka }
   3245  1.45   nonaka 
   3246  1.45   nonaka static int
   3247  1.45   nonaka iwm_load_firmware(struct iwm_softc *sc, enum iwm_ucode_type ucode_type)
   3248  1.45   nonaka {
   3249  1.45   nonaka 	int err, w;
   3250  1.45   nonaka 
   3251  1.45   nonaka 	sc->sc_uc.uc_intr = 0;
   3252  1.45   nonaka 
   3253  1.45   nonaka 	if (sc->sc_device_family == IWM_DEVICE_FAMILY_8000)
   3254  1.45   nonaka 		err = iwm_load_firmware_8000(sc, ucode_type);
   3255  1.45   nonaka 	else
   3256  1.45   nonaka 		err = iwm_load_firmware_7000(sc, ucode_type);
   3257  1.45   nonaka 	if (err)
   3258  1.45   nonaka 		return err;
   3259  1.45   nonaka 
   3260  1.45   nonaka 	/* wait for the firmware to load */
   3261  1.45   nonaka 	for (w = 0; !sc->sc_uc.uc_intr && w < 10; w++)
   3262  1.45   nonaka 		err = tsleep(&sc->sc_uc, 0, "iwmuc", mstohz(100));
   3263  1.61   nonaka 	if (err || !sc->sc_uc.uc_ok) {
   3264  1.61   nonaka 		aprint_error_dev(sc->sc_dev,
   3265  1.61   nonaka 		    "could not load firmware (error %d, ok %d)\n",
   3266  1.61   nonaka 		    err, sc->sc_uc.uc_ok);
   3267  1.61   nonaka 		if (sc->sc_device_family == IWM_DEVICE_FAMILY_8000) {
   3268  1.61   nonaka 			aprint_error_dev(sc->sc_dev, "cpu1 status: 0x%x\n",
   3269  1.61   nonaka 			    iwm_read_prph(sc, IWM_SB_CPU_1_STATUS));
   3270  1.61   nonaka 			aprint_error_dev(sc->sc_dev, "cpu2 status: 0x%x\n",
   3271  1.61   nonaka 			    iwm_read_prph(sc, IWM_SB_CPU_2_STATUS));
   3272  1.61   nonaka 		}
   3273  1.61   nonaka 	}
   3274  1.45   nonaka 
   3275  1.45   nonaka 	return err;
   3276   1.1    pooka }
   3277   1.1    pooka 
   3278   1.4   nonaka static int
   3279  1.45   nonaka iwm_start_fw(struct iwm_softc *sc, enum iwm_ucode_type ucode_type)
   3280   1.1    pooka {
   3281  1.45   nonaka 	int err;
   3282  1.45   nonaka 
   3283  1.45   nonaka 	IWM_WRITE(sc, IWM_CSR_INT, ~0);
   3284  1.45   nonaka 
   3285  1.45   nonaka 	err = iwm_nic_init(sc);
   3286  1.45   nonaka 	if (err) {
   3287  1.45   nonaka 		aprint_error_dev(sc->sc_dev, "Unable to init nic\n");
   3288  1.45   nonaka 		return err;
   3289  1.45   nonaka 	}
   3290  1.45   nonaka 
   3291  1.45   nonaka 	/* make sure rfkill handshake bits are cleared */
   3292  1.45   nonaka 	IWM_WRITE(sc, IWM_CSR_UCODE_DRV_GP1_CLR, IWM_CSR_UCODE_SW_BIT_RFKILL);
   3293  1.45   nonaka 	IWM_WRITE(sc, IWM_CSR_UCODE_DRV_GP1_CLR,
   3294  1.45   nonaka 	    IWM_CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
   3295  1.45   nonaka 
   3296  1.45   nonaka 	/* clear (again), then enable host interrupts */
   3297  1.45   nonaka 	IWM_WRITE(sc, IWM_CSR_INT, ~0);
   3298  1.45   nonaka 	iwm_enable_interrupts(sc);
   3299  1.45   nonaka 
   3300  1.45   nonaka 	/* really make sure rfkill handshake bits are cleared */
   3301  1.45   nonaka 	/* maybe we should write a few times more?  just to make sure */
   3302  1.45   nonaka 	IWM_WRITE(sc, IWM_CSR_UCODE_DRV_GP1_CLR, IWM_CSR_UCODE_SW_BIT_RFKILL);
   3303  1.45   nonaka 	IWM_WRITE(sc, IWM_CSR_UCODE_DRV_GP1_CLR, IWM_CSR_UCODE_SW_BIT_RFKILL);
   3304  1.45   nonaka 
   3305  1.45   nonaka 	return iwm_load_firmware(sc, ucode_type);
   3306   1.1    pooka }
   3307   1.1    pooka 
   3308   1.4   nonaka static int
   3309   1.1    pooka iwm_send_tx_ant_cfg(struct iwm_softc *sc, uint8_t valid_tx_ant)
   3310   1.1    pooka {
   3311   1.1    pooka 	struct iwm_tx_ant_cfg_cmd tx_ant_cmd = {
   3312   1.1    pooka 		.valid = htole32(valid_tx_ant),
   3313   1.1    pooka 	};
   3314   1.1    pooka 
   3315  1.45   nonaka 	return iwm_send_cmd_pdu(sc, IWM_TX_ANT_CONFIGURATION_CMD, 0,
   3316  1.45   nonaka 	    sizeof(tx_ant_cmd), &tx_ant_cmd);
   3317   1.1    pooka }
   3318   1.1    pooka 
   3319   1.4   nonaka static int
   3320   1.1    pooka iwm_send_phy_cfg_cmd(struct iwm_softc *sc)
   3321   1.1    pooka {
   3322   1.1    pooka 	struct iwm_phy_cfg_cmd phy_cfg_cmd;
   3323   1.1    pooka 	enum iwm_ucode_type ucode_type = sc->sc_uc_current;
   3324   1.1    pooka 
   3325   1.1    pooka 	phy_cfg_cmd.phy_cfg = htole32(sc->sc_fw_phy_config);
   3326   1.1    pooka 	phy_cfg_cmd.calib_control.event_trigger =
   3327   1.1    pooka 	    sc->sc_default_calib[ucode_type].event_trigger;
   3328   1.1    pooka 	phy_cfg_cmd.calib_control.flow_trigger =
   3329   1.1    pooka 	    sc->sc_default_calib[ucode_type].flow_trigger;
   3330   1.1    pooka 
   3331   1.1    pooka 	DPRINTFN(10, ("Sending Phy CFG command: 0x%x\n", phy_cfg_cmd.phy_cfg));
   3332  1.45   nonaka 	return iwm_send_cmd_pdu(sc, IWM_PHY_CONFIGURATION_CMD, 0,
   3333   1.1    pooka 	    sizeof(phy_cfg_cmd), &phy_cfg_cmd);
   3334   1.1    pooka }
   3335   1.1    pooka 
   3336   1.4   nonaka static int
   3337  1.51   nonaka iwm_load_ucode_wait_alive(struct iwm_softc *sc, enum iwm_ucode_type ucode_type)
   3338   1.1    pooka {
   3339   1.1    pooka 	enum iwm_ucode_type old_type = sc->sc_uc_current;
   3340  1.45   nonaka 	int err;
   3341   1.1    pooka 
   3342  1.61   nonaka 	err = iwm_read_firmware(sc, ucode_type);
   3343  1.45   nonaka 	if (err)
   3344  1.45   nonaka 		return err;
   3345   1.1    pooka 
   3346   1.1    pooka 	sc->sc_uc_current = ucode_type;
   3347  1.45   nonaka 	err = iwm_start_fw(sc, ucode_type);
   3348  1.45   nonaka 	if (err) {
   3349   1.1    pooka 		sc->sc_uc_current = old_type;
   3350  1.45   nonaka 		return err;
   3351   1.1    pooka 	}
   3352   1.1    pooka 
   3353  1.45   nonaka 	return iwm_post_alive(sc);
   3354   1.1    pooka }
   3355   1.1    pooka 
   3356   1.4   nonaka static int
   3357   1.1    pooka iwm_run_init_mvm_ucode(struct iwm_softc *sc, int justnvm)
   3358   1.1    pooka {
   3359  1.45   nonaka 	int err;
   3360   1.1    pooka 
   3361   1.1    pooka 	if ((sc->sc_flags & IWM_FLAG_RFKILL) && !justnvm) {
   3362   1.3   nonaka 		aprint_error_dev(sc->sc_dev,
   3363   1.3   nonaka 		    "radio is disabled by hardware switch\n");
   3364   1.1    pooka 		return EPERM;
   3365   1.1    pooka 	}
   3366   1.1    pooka 
   3367   1.1    pooka 	sc->sc_init_complete = 0;
   3368  1.45   nonaka 	err = iwm_load_ucode_wait_alive(sc, IWM_UCODE_TYPE_INIT);
   3369  1.45   nonaka 	if (err) {
   3370  1.61   nonaka 		DPRINTF(("%s: failed to load init firmware\n", DEVNAME(sc)));
   3371  1.45   nonaka 		return err;
   3372  1.45   nonaka 	}
   3373   1.1    pooka 
   3374   1.1    pooka 	if (justnvm) {
   3375  1.45   nonaka 		err = iwm_nvm_init(sc);
   3376  1.45   nonaka 		if (err) {
   3377   1.3   nonaka 			aprint_error_dev(sc->sc_dev, "failed to read nvm\n");
   3378  1.45   nonaka 			return err;
   3379   1.1    pooka 		}
   3380   1.1    pooka 
   3381  1.45   nonaka 		memcpy(&sc->sc_ic.ic_myaddr, &sc->sc_nvm.hw_addr,
   3382  1.45   nonaka 		    ETHER_ADDR_LEN);
   3383   1.1    pooka 		return 0;
   3384   1.1    pooka 	}
   3385   1.1    pooka 
   3386  1.45   nonaka 	err = iwm_send_bt_init_conf(sc);
   3387  1.45   nonaka 	if (err)
   3388  1.45   nonaka 		return err;
   3389  1.45   nonaka 
   3390  1.45   nonaka 	err = iwm_sf_config(sc, IWM_SF_INIT_OFF);
   3391  1.45   nonaka 	if (err)
   3392  1.45   nonaka 		return err;
   3393  1.45   nonaka 
   3394  1.45   nonaka 	err = iwm_send_tx_ant_cfg(sc, iwm_fw_valid_tx_ant(sc));
   3395  1.45   nonaka 	if (err)
   3396  1.45   nonaka 		return err;
   3397   1.1    pooka 
   3398   1.1    pooka 	/*
   3399  1.45   nonaka 	 * Send phy configurations command to init uCode
   3400  1.45   nonaka 	 * to start the 16.0 uCode init image internal calibrations.
   3401  1.45   nonaka 	 */
   3402  1.45   nonaka 	err = iwm_send_phy_cfg_cmd(sc);
   3403  1.45   nonaka 	if (err)
   3404  1.45   nonaka 		return err;
   3405   1.1    pooka 
   3406   1.1    pooka 	/*
   3407   1.1    pooka 	 * Nothing to do but wait for the init complete notification
   3408   1.1    pooka 	 * from the firmware
   3409   1.1    pooka 	 */
   3410  1.45   nonaka 	while (!sc->sc_init_complete) {
   3411  1.45   nonaka 		err = tsleep(&sc->sc_init_complete, 0, "iwminit", mstohz(2000));
   3412  1.45   nonaka 		if (err)
   3413   1.1    pooka 			break;
   3414  1.45   nonaka 	}
   3415   1.1    pooka 
   3416  1.45   nonaka 	return err;
   3417   1.1    pooka }
   3418   1.1    pooka 
   3419   1.4   nonaka static int
   3420   1.1    pooka iwm_rx_addbuf(struct iwm_softc *sc, int size, int idx)
   3421   1.1    pooka {
   3422   1.1    pooka 	struct iwm_rx_ring *ring = &sc->rxq;
   3423   1.1    pooka 	struct iwm_rx_data *data = &ring->data[idx];
   3424   1.1    pooka 	struct mbuf *m;
   3425  1.45   nonaka 	int err;
   3426   1.1    pooka 	int fatal = 0;
   3427   1.1    pooka 
   3428   1.1    pooka 	m = m_gethdr(M_DONTWAIT, MT_DATA);
   3429   1.1    pooka 	if (m == NULL)
   3430   1.1    pooka 		return ENOBUFS;
   3431   1.1    pooka 
   3432   1.1    pooka 	if (size <= MCLBYTES) {
   3433   1.1    pooka 		MCLGET(m, M_DONTWAIT);
   3434   1.1    pooka 	} else {
   3435   1.1    pooka 		MEXTMALLOC(m, IWM_RBUF_SIZE, M_DONTWAIT);
   3436   1.1    pooka 	}
   3437   1.1    pooka 	if ((m->m_flags & M_EXT) == 0) {
   3438   1.1    pooka 		m_freem(m);
   3439   1.1    pooka 		return ENOBUFS;
   3440   1.1    pooka 	}
   3441   1.1    pooka 
   3442   1.1    pooka 	if (data->m != NULL) {
   3443   1.1    pooka 		bus_dmamap_unload(sc->sc_dmat, data->map);
   3444   1.1    pooka 		fatal = 1;
   3445   1.1    pooka 	}
   3446   1.1    pooka 
   3447   1.1    pooka 	m->m_len = m->m_pkthdr.len = m->m_ext.ext_size;
   3448  1.45   nonaka 	err = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m,
   3449  1.45   nonaka 	    BUS_DMA_READ|BUS_DMA_NOWAIT);
   3450  1.45   nonaka 	if (err) {
   3451   1.1    pooka 		/* XXX */
   3452   1.1    pooka 		if (fatal)
   3453   1.1    pooka 			panic("iwm: could not load RX mbuf");
   3454   1.1    pooka 		m_freem(m);
   3455  1.45   nonaka 		return err;
   3456   1.1    pooka 	}
   3457   1.1    pooka 	data->m = m;
   3458   1.1    pooka 	bus_dmamap_sync(sc->sc_dmat, data->map, 0, size, BUS_DMASYNC_PREREAD);
   3459   1.1    pooka 
   3460   1.8   nonaka 	/* Update RX descriptor. */
   3461   1.1    pooka 	ring->desc[idx] = htole32(data->map->dm_segs[0].ds_addr >> 8);
   3462   1.1    pooka 	bus_dmamap_sync(sc->sc_dmat, ring->desc_dma.map,
   3463   1.1    pooka 	    idx * sizeof(uint32_t), sizeof(uint32_t), BUS_DMASYNC_PREWRITE);
   3464   1.1    pooka 
   3465   1.1    pooka 	return 0;
   3466   1.1    pooka }
   3467   1.1    pooka 
   3468   1.1    pooka #define IWM_RSSI_OFFSET 50
   3469   1.4   nonaka static int
   3470  1.45   nonaka iwm_calc_rssi(struct iwm_softc *sc, struct iwm_rx_phy_info *phy_info)
   3471   1.1    pooka {
   3472   1.1    pooka 	int rssi_a, rssi_b, rssi_a_dbm, rssi_b_dbm, max_rssi_dbm;
   3473   1.1    pooka 	uint32_t agc_a, agc_b;
   3474   1.1    pooka 	uint32_t val;
   3475   1.1    pooka 
   3476   1.1    pooka 	val = le32toh(phy_info->non_cfg_phy[IWM_RX_INFO_AGC_IDX]);
   3477   1.1    pooka 	agc_a = (val & IWM_OFDM_AGC_A_MSK) >> IWM_OFDM_AGC_A_POS;
   3478   1.1    pooka 	agc_b = (val & IWM_OFDM_AGC_B_MSK) >> IWM_OFDM_AGC_B_POS;
   3479   1.1    pooka 
   3480   1.1    pooka 	val = le32toh(phy_info->non_cfg_phy[IWM_RX_INFO_RSSI_AB_IDX]);
   3481   1.1    pooka 	rssi_a = (val & IWM_OFDM_RSSI_INBAND_A_MSK) >> IWM_OFDM_RSSI_A_POS;
   3482   1.1    pooka 	rssi_b = (val & IWM_OFDM_RSSI_INBAND_B_MSK) >> IWM_OFDM_RSSI_B_POS;
   3483   1.1    pooka 
   3484   1.1    pooka 	/*
   3485   1.1    pooka 	 * dBm = rssi dB - agc dB - constant.
   3486   1.1    pooka 	 * Higher AGC (higher radio gain) means lower signal.
   3487   1.1    pooka 	 */
   3488   1.1    pooka 	rssi_a_dbm = rssi_a - IWM_RSSI_OFFSET - agc_a;
   3489   1.1    pooka 	rssi_b_dbm = rssi_b - IWM_RSSI_OFFSET - agc_b;
   3490   1.1    pooka 	max_rssi_dbm = MAX(rssi_a_dbm, rssi_b_dbm);
   3491   1.1    pooka 
   3492   1.1    pooka 	DPRINTF(("Rssi In A %d B %d Max %d AGCA %d AGCB %d\n",
   3493   1.1    pooka 	    rssi_a_dbm, rssi_b_dbm, max_rssi_dbm, agc_a, agc_b));
   3494   1.1    pooka 
   3495   1.1    pooka 	return max_rssi_dbm;
   3496   1.1    pooka }
   3497   1.1    pooka 
   3498   1.1    pooka /*
   3499  1.45   nonaka  * RSSI values are reported by the FW as positive values - need to negate
   3500   1.1    pooka  * to obtain their dBM.  Account for missing antennas by replacing 0
   3501   1.1    pooka  * values by -256dBm: practically 0 power and a non-feasible 8 bit value.
   3502   1.1    pooka  */
   3503   1.4   nonaka static int
   3504  1.51   nonaka iwm_get_signal_strength(struct iwm_softc *sc, struct iwm_rx_phy_info *phy_info)
   3505   1.1    pooka {
   3506   1.1    pooka 	int energy_a, energy_b, energy_c, max_energy;
   3507   1.1    pooka 	uint32_t val;
   3508   1.1    pooka 
   3509   1.1    pooka 	val = le32toh(phy_info->non_cfg_phy[IWM_RX_INFO_ENERGY_ANT_ABC_IDX]);
   3510   1.1    pooka 	energy_a = (val & IWM_RX_INFO_ENERGY_ANT_A_MSK) >>
   3511   1.1    pooka 	    IWM_RX_INFO_ENERGY_ANT_A_POS;
   3512   1.1    pooka 	energy_a = energy_a ? -energy_a : -256;
   3513   1.1    pooka 	energy_b = (val & IWM_RX_INFO_ENERGY_ANT_B_MSK) >>
   3514   1.1    pooka 	    IWM_RX_INFO_ENERGY_ANT_B_POS;
   3515   1.1    pooka 	energy_b = energy_b ? -energy_b : -256;
   3516   1.1    pooka 	energy_c = (val & IWM_RX_INFO_ENERGY_ANT_C_MSK) >>
   3517   1.1    pooka 	    IWM_RX_INFO_ENERGY_ANT_C_POS;
   3518   1.1    pooka 	energy_c = energy_c ? -energy_c : -256;
   3519   1.1    pooka 	max_energy = MAX(energy_a, energy_b);
   3520   1.1    pooka 	max_energy = MAX(max_energy, energy_c);
   3521   1.1    pooka 
   3522   1.5   nonaka 	DPRINTFN(12, ("energy In A %d B %d C %d, and max %d\n",
   3523   1.1    pooka 	    energy_a, energy_b, energy_c, max_energy));
   3524   1.1    pooka 
   3525   1.1    pooka 	return max_energy;
   3526   1.1    pooka }
   3527   1.1    pooka 
   3528   1.4   nonaka static void
   3529  1.45   nonaka iwm_rx_rx_phy_cmd(struct iwm_softc *sc, struct iwm_rx_packet *pkt,
   3530  1.45   nonaka     struct iwm_rx_data *data)
   3531   1.1    pooka {
   3532   1.1    pooka 	struct iwm_rx_phy_info *phy_info = (void *)pkt->data;
   3533   1.1    pooka 
   3534   1.1    pooka 	DPRINTFN(20, ("received PHY stats\n"));
   3535   1.1    pooka 	bus_dmamap_sync(sc->sc_dmat, data->map, sizeof(*pkt),
   3536   1.1    pooka 	    sizeof(*phy_info), BUS_DMASYNC_POSTREAD);
   3537   1.1    pooka 
   3538   1.1    pooka 	memcpy(&sc->sc_last_phy_info, phy_info, sizeof(sc->sc_last_phy_info));
   3539   1.1    pooka }
   3540   1.1    pooka 
   3541   1.1    pooka /*
   3542   1.1    pooka  * Retrieve the average noise (in dBm) among receivers.
   3543   1.1    pooka  */
   3544   1.4   nonaka static int
   3545  1.45   nonaka iwm_get_noise(const struct iwm_statistics_rx_non_phy *stats)
   3546   1.1    pooka {
   3547   1.1    pooka 	int i, total, nbant, noise;
   3548   1.1    pooka 
   3549   1.1    pooka 	total = nbant = noise = 0;
   3550   1.1    pooka 	for (i = 0; i < 3; i++) {
   3551   1.1    pooka 		noise = le32toh(stats->beacon_silence_rssi[i]) & 0xff;
   3552   1.1    pooka 		if (noise) {
   3553   1.1    pooka 			total += noise;
   3554   1.1    pooka 			nbant++;
   3555   1.1    pooka 		}
   3556   1.1    pooka 	}
   3557   1.1    pooka 
   3558   1.1    pooka 	/* There should be at least one antenna but check anyway. */
   3559   1.1    pooka 	return (nbant == 0) ? -127 : (total / nbant) - 107;
   3560   1.1    pooka }
   3561   1.1    pooka 
   3562   1.4   nonaka static void
   3563  1.45   nonaka iwm_rx_rx_mpdu(struct iwm_softc *sc, struct iwm_rx_packet *pkt,
   3564  1.45   nonaka     struct iwm_rx_data *data)
   3565   1.1    pooka {
   3566   1.1    pooka 	struct ieee80211com *ic = &sc->sc_ic;
   3567   1.1    pooka 	struct ieee80211_frame *wh;
   3568   1.1    pooka 	struct ieee80211_node *ni;
   3569   1.1    pooka 	struct ieee80211_channel *c = NULL;
   3570   1.1    pooka 	struct mbuf *m;
   3571   1.1    pooka 	struct iwm_rx_phy_info *phy_info;
   3572   1.1    pooka 	struct iwm_rx_mpdu_res_start *rx_res;
   3573   1.1    pooka 	int device_timestamp;
   3574   1.1    pooka 	uint32_t len;
   3575   1.1    pooka 	uint32_t rx_pkt_status;
   3576   1.1    pooka 	int rssi;
   3577  1.50   nonaka 	int s;
   3578   1.1    pooka 
   3579   1.1    pooka 	bus_dmamap_sync(sc->sc_dmat, data->map, 0, IWM_RBUF_SIZE,
   3580   1.1    pooka 	    BUS_DMASYNC_POSTREAD);
   3581   1.1    pooka 
   3582   1.1    pooka 	phy_info = &sc->sc_last_phy_info;
   3583   1.1    pooka 	rx_res = (struct iwm_rx_mpdu_res_start *)pkt->data;
   3584   1.1    pooka 	wh = (struct ieee80211_frame *)(pkt->data + sizeof(*rx_res));
   3585   1.1    pooka 	len = le16toh(rx_res->byte_count);
   3586  1.45   nonaka 	rx_pkt_status = le32toh(*(uint32_t *)(pkt->data +
   3587  1.45   nonaka 	    sizeof(*rx_res) + len));
   3588   1.1    pooka 
   3589   1.1    pooka 	m = data->m;
   3590   1.1    pooka 	m->m_data = pkt->data + sizeof(*rx_res);
   3591   1.1    pooka 	m->m_pkthdr.len = m->m_len = len;
   3592   1.1    pooka 
   3593   1.1    pooka 	if (__predict_false(phy_info->cfg_phy_cnt > 20)) {
   3594   1.1    pooka 		DPRINTF(("dsp size out of range [0,20]: %d\n",
   3595   1.1    pooka 		    phy_info->cfg_phy_cnt));
   3596   1.1    pooka 		return;
   3597   1.1    pooka 	}
   3598   1.1    pooka 
   3599   1.1    pooka 	if (!(rx_pkt_status & IWM_RX_MPDU_RES_STATUS_CRC_OK) ||
   3600   1.1    pooka 	    !(rx_pkt_status & IWM_RX_MPDU_RES_STATUS_OVERRUN_OK)) {
   3601   1.1    pooka 		DPRINTF(("Bad CRC or FIFO: 0x%08X.\n", rx_pkt_status));
   3602   1.1    pooka 		return; /* drop */
   3603   1.1    pooka 	}
   3604   1.1    pooka 
   3605   1.1    pooka 	device_timestamp = le32toh(phy_info->system_timestamp);
   3606   1.1    pooka 
   3607   1.1    pooka 	if (sc->sc_capaflags & IWM_UCODE_TLV_FLAGS_RX_ENERGY_API) {
   3608  1.45   nonaka 		rssi = iwm_get_signal_strength(sc, phy_info);
   3609   1.1    pooka 	} else {
   3610  1.45   nonaka 		rssi = iwm_calc_rssi(sc, phy_info);
   3611   1.1    pooka 	}
   3612   1.1    pooka 	rssi = -rssi;
   3613   1.1    pooka 
   3614   1.1    pooka 	if (ic->ic_state == IEEE80211_S_SCAN)
   3615  1.45   nonaka 		iwm_fix_channel(sc, m);
   3616   1.1    pooka 
   3617   1.1    pooka 	if (iwm_rx_addbuf(sc, IWM_RBUF_SIZE, sc->rxq.cur) != 0)
   3618   1.1    pooka 		return;
   3619   1.1    pooka 
   3620  1.42    ozaki 	m_set_rcvif(m, IC2IFP(ic));
   3621   1.1    pooka 
   3622  1.45   nonaka 	if (le32toh(phy_info->channel) < __arraycount(ic->ic_channels))
   3623  1.45   nonaka 		c = &ic->ic_channels[le32toh(phy_info->channel)];
   3624   1.1    pooka 
   3625  1.50   nonaka 	s = splnet();
   3626  1.50   nonaka 
   3627   1.1    pooka 	ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh);
   3628   1.1    pooka 	if (c)
   3629   1.1    pooka 		ni->ni_chan = c;
   3630   1.1    pooka 
   3631  1.48   nonaka 	if (__predict_false(sc->sc_drvbpf != NULL)) {
   3632   1.1    pooka 		struct iwm_rx_radiotap_header *tap = &sc->sc_rxtap;
   3633   1.1    pooka 
   3634   1.1    pooka 		tap->wr_flags = 0;
   3635   1.1    pooka 		if (phy_info->phy_flags & htole16(IWM_PHY_INFO_FLAG_SHPREAMBLE))
   3636   1.1    pooka 			tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
   3637   1.1    pooka 		tap->wr_chan_freq =
   3638   1.1    pooka 		    htole16(ic->ic_channels[phy_info->channel].ic_freq);
   3639   1.1    pooka 		tap->wr_chan_flags =
   3640   1.1    pooka 		    htole16(ic->ic_channels[phy_info->channel].ic_flags);
   3641   1.1    pooka 		tap->wr_dbm_antsignal = (int8_t)rssi;
   3642   1.1    pooka 		tap->wr_dbm_antnoise = (int8_t)sc->sc_noise;
   3643   1.1    pooka 		tap->wr_tsft = phy_info->system_timestamp;
   3644  1.45   nonaka 		if (phy_info->phy_flags &
   3645  1.45   nonaka 		    htole16(IWM_RX_RES_PHY_FLAGS_OFDM_HT)) {
   3646  1.45   nonaka 			uint8_t mcs = (phy_info->rate_n_flags &
   3647  1.61   nonaka 			    htole32(IWM_RATE_HT_MCS_RATE_CODE_MSK |
   3648  1.61   nonaka 			      IWM_RATE_HT_MCS_NSS_MSK));
   3649  1.45   nonaka 			tap->wr_rate = (0x80 | mcs);
   3650  1.45   nonaka 		} else {
   3651  1.45   nonaka 			uint8_t rate = (phy_info->rate_n_flags &
   3652  1.45   nonaka 			    htole32(IWM_RATE_LEGACY_RATE_MSK));
   3653  1.45   nonaka 			switch (rate) {
   3654  1.45   nonaka 			/* CCK rates. */
   3655  1.45   nonaka 			case  10: tap->wr_rate =   2; break;
   3656  1.45   nonaka 			case  20: tap->wr_rate =   4; break;
   3657  1.45   nonaka 			case  55: tap->wr_rate =  11; break;
   3658  1.45   nonaka 			case 110: tap->wr_rate =  22; break;
   3659  1.45   nonaka 			/* OFDM rates. */
   3660  1.45   nonaka 			case 0xd: tap->wr_rate =  12; break;
   3661  1.45   nonaka 			case 0xf: tap->wr_rate =  18; break;
   3662  1.45   nonaka 			case 0x5: tap->wr_rate =  24; break;
   3663  1.45   nonaka 			case 0x7: tap->wr_rate =  36; break;
   3664  1.45   nonaka 			case 0x9: tap->wr_rate =  48; break;
   3665  1.45   nonaka 			case 0xb: tap->wr_rate =  72; break;
   3666  1.45   nonaka 			case 0x1: tap->wr_rate =  96; break;
   3667  1.45   nonaka 			case 0x3: tap->wr_rate = 108; break;
   3668  1.45   nonaka 			/* Unknown rate: should not happen. */
   3669  1.45   nonaka 			default:  tap->wr_rate =   0;
   3670  1.45   nonaka 			}
   3671   1.1    pooka 		}
   3672   1.1    pooka 
   3673   1.1    pooka 		bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_rxtap_len, m);
   3674   1.1    pooka 	}
   3675   1.1    pooka 	ieee80211_input(ic, m, ni, rssi, device_timestamp);
   3676   1.1    pooka 	ieee80211_free_node(ni);
   3677  1.50   nonaka 
   3678  1.50   nonaka 	splx(s);
   3679   1.1    pooka }
   3680   1.1    pooka 
   3681   1.4   nonaka static void
   3682  1.45   nonaka iwm_rx_tx_cmd_single(struct iwm_softc *sc, struct iwm_rx_packet *pkt,
   3683  1.45   nonaka     struct iwm_node *in)
   3684   1.1    pooka {
   3685   1.1    pooka 	struct ieee80211com *ic = &sc->sc_ic;
   3686   1.1    pooka 	struct ifnet *ifp = IC2IFP(ic);
   3687  1.45   nonaka 	struct iwm_tx_resp *tx_resp = (void *)pkt->data;
   3688   1.1    pooka 	int status = le16toh(tx_resp->status.status) & IWM_TX_STATUS_MSK;
   3689   1.1    pooka 	int failack = tx_resp->failure_frame;
   3690   1.1    pooka 
   3691   1.1    pooka 	KASSERT(tx_resp->frame_count == 1);
   3692   1.1    pooka 
   3693   1.1    pooka 	/* Update rate control statistics. */
   3694   1.1    pooka 	in->in_amn.amn_txcnt++;
   3695   1.1    pooka 	if (failack > 0) {
   3696   1.1    pooka 		in->in_amn.amn_retrycnt++;
   3697   1.1    pooka 	}
   3698   1.1    pooka 
   3699   1.1    pooka 	if (status != IWM_TX_STATUS_SUCCESS &&
   3700   1.1    pooka 	    status != IWM_TX_STATUS_DIRECT_DONE)
   3701   1.1    pooka 		ifp->if_oerrors++;
   3702   1.1    pooka 	else
   3703   1.1    pooka 		ifp->if_opackets++;
   3704   1.1    pooka }
   3705   1.1    pooka 
   3706   1.4   nonaka static void
   3707  1.45   nonaka iwm_rx_tx_cmd(struct iwm_softc *sc, struct iwm_rx_packet *pkt,
   3708  1.45   nonaka     struct iwm_rx_data *data)
   3709   1.1    pooka {
   3710   1.1    pooka 	struct ieee80211com *ic = &sc->sc_ic;
   3711   1.1    pooka 	struct ifnet *ifp = IC2IFP(ic);
   3712   1.1    pooka 	struct iwm_cmd_header *cmd_hdr = &pkt->hdr;
   3713   1.1    pooka 	int idx = cmd_hdr->idx;
   3714   1.1    pooka 	int qid = cmd_hdr->qid;
   3715   1.1    pooka 	struct iwm_tx_ring *ring = &sc->txq[qid];
   3716   1.1    pooka 	struct iwm_tx_data *txd = &ring->data[idx];
   3717   1.1    pooka 	struct iwm_node *in = txd->in;
   3718  1.61   nonaka 	int s;
   3719  1.61   nonaka 
   3720  1.61   nonaka 	s = splnet();
   3721   1.1    pooka 
   3722   1.1    pooka 	if (txd->done) {
   3723   1.2   nonaka 		DPRINTF(("%s: got tx interrupt that's already been handled!\n",
   3724   1.2   nonaka 		    DEVNAME(sc)));
   3725  1.61   nonaka 		splx(s);
   3726   1.1    pooka 		return;
   3727   1.1    pooka 	}
   3728   1.1    pooka 
   3729   1.1    pooka 	bus_dmamap_sync(sc->sc_dmat, data->map, 0, IWM_RBUF_SIZE,
   3730   1.1    pooka 	    BUS_DMASYNC_POSTREAD);
   3731   1.1    pooka 
   3732   1.1    pooka 	sc->sc_tx_timer = 0;
   3733   1.1    pooka 
   3734  1.45   nonaka 	iwm_rx_tx_cmd_single(sc, pkt, in);
   3735   1.1    pooka 
   3736   1.1    pooka 	bus_dmamap_sync(sc->sc_dmat, txd->map, 0, txd->map->dm_mapsize,
   3737   1.1    pooka 	    BUS_DMASYNC_POSTWRITE);
   3738   1.1    pooka 	bus_dmamap_unload(sc->sc_dmat, txd->map);
   3739   1.1    pooka 	m_freem(txd->m);
   3740   1.1    pooka 
   3741   1.1    pooka 	DPRINTFN(8, ("free txd %p, in %p\n", txd, txd->in));
   3742   1.1    pooka 	KASSERT(txd->done == 0);
   3743   1.1    pooka 	txd->done = 1;
   3744   1.1    pooka 	KASSERT(txd->in);
   3745   1.1    pooka 
   3746   1.1    pooka 	txd->m = NULL;
   3747   1.1    pooka 	txd->in = NULL;
   3748   1.1    pooka 	ieee80211_free_node(&in->in_ni);
   3749   1.1    pooka 
   3750   1.1    pooka 	if (--ring->queued < IWM_TX_RING_LOMARK) {
   3751  1.61   nonaka 		sc->qfullmsk &= ~(1 << qid);
   3752   1.1    pooka 		if (sc->qfullmsk == 0 && (ifp->if_flags & IFF_OACTIVE)) {
   3753   1.1    pooka 			ifp->if_flags &= ~IFF_OACTIVE;
   3754  1.65   nonaka 			KASSERT(KERNEL_LOCKED_P());
   3755  1.65   nonaka 			iwm_start(ifp);
   3756   1.1    pooka 		}
   3757   1.1    pooka 	}
   3758  1.61   nonaka 
   3759  1.61   nonaka 	splx(s);
   3760   1.1    pooka }
   3761   1.1    pooka 
   3762   1.4   nonaka static int
   3763  1.45   nonaka iwm_binding_cmd(struct iwm_softc *sc, struct iwm_node *in, uint32_t action)
   3764   1.1    pooka {
   3765   1.1    pooka 	struct iwm_binding_cmd cmd;
   3766  1.45   nonaka 	struct iwm_phy_ctxt *phyctxt = in->in_phyctxt;
   3767  1.45   nonaka 	int i, err;
   3768   1.1    pooka 	uint32_t status;
   3769   1.1    pooka 
   3770   1.1    pooka 	memset(&cmd, 0, sizeof(cmd));
   3771   1.1    pooka 
   3772   1.1    pooka 	cmd.id_and_color
   3773   1.1    pooka 	    = htole32(IWM_FW_CMD_ID_AND_COLOR(phyctxt->id, phyctxt->color));
   3774   1.1    pooka 	cmd.action = htole32(action);
   3775   1.1    pooka 	cmd.phy = htole32(IWM_FW_CMD_ID_AND_COLOR(phyctxt->id, phyctxt->color));
   3776   1.1    pooka 
   3777   1.1    pooka 	cmd.macs[0] = htole32(IWM_FW_CMD_ID_AND_COLOR(in->in_id, in->in_color));
   3778   1.1    pooka 	for (i = 1; i < IWM_MAX_MACS_IN_BINDING; i++)
   3779   1.1    pooka 		cmd.macs[i] = htole32(IWM_FW_CTXT_INVALID);
   3780   1.1    pooka 
   3781   1.1    pooka 	status = 0;
   3782  1.45   nonaka 	err = iwm_send_cmd_pdu_status(sc, IWM_BINDING_CONTEXT_CMD,
   3783   1.1    pooka 	    sizeof(cmd), &cmd, &status);
   3784  1.45   nonaka 	if (err == 0 && status != 0)
   3785  1.45   nonaka 		err = EIO;
   3786   1.1    pooka 
   3787  1.45   nonaka 	return err;
   3788   1.1    pooka }
   3789   1.1    pooka 
   3790   1.4   nonaka static void
   3791  1.45   nonaka iwm_phy_ctxt_cmd_hdr(struct iwm_softc *sc, struct iwm_phy_ctxt *ctxt,
   3792  1.45   nonaka     struct iwm_phy_context_cmd *cmd, uint32_t action, uint32_t apply_time)
   3793   1.1    pooka {
   3794   1.1    pooka 	memset(cmd, 0, sizeof(struct iwm_phy_context_cmd));
   3795   1.1    pooka 
   3796   1.1    pooka 	cmd->id_and_color = htole32(IWM_FW_CMD_ID_AND_COLOR(ctxt->id,
   3797   1.1    pooka 	    ctxt->color));
   3798   1.1    pooka 	cmd->action = htole32(action);
   3799   1.1    pooka 	cmd->apply_time = htole32(apply_time);
   3800   1.1    pooka }
   3801   1.1    pooka 
   3802   1.4   nonaka static void
   3803  1.45   nonaka iwm_phy_ctxt_cmd_data(struct iwm_softc *sc, struct iwm_phy_context_cmd *cmd,
   3804  1.45   nonaka     struct ieee80211_channel *chan, uint8_t chains_static,
   3805  1.45   nonaka     uint8_t chains_dynamic)
   3806   1.1    pooka {
   3807   1.1    pooka 	struct ieee80211com *ic = &sc->sc_ic;
   3808   1.1    pooka 	uint8_t active_cnt, idle_cnt;
   3809   1.1    pooka 
   3810   1.1    pooka 	cmd->ci.band = IEEE80211_IS_CHAN_2GHZ(chan) ?
   3811   1.1    pooka 	    IWM_PHY_BAND_24 : IWM_PHY_BAND_5;
   3812   1.1    pooka 
   3813   1.1    pooka 	cmd->ci.channel = ieee80211_chan2ieee(ic, chan);
   3814   1.1    pooka 	cmd->ci.width = IWM_PHY_VHT_CHANNEL_MODE20;
   3815   1.1    pooka 	cmd->ci.ctrl_pos = IWM_PHY_VHT_CTRL_POS_1_BELOW;
   3816   1.1    pooka 
   3817   1.1    pooka 	/* Set rx the chains */
   3818   1.1    pooka 	idle_cnt = chains_static;
   3819   1.1    pooka 	active_cnt = chains_dynamic;
   3820   1.1    pooka 
   3821  1.45   nonaka 	cmd->rxchain_info = htole32(iwm_fw_valid_rx_ant(sc) <<
   3822  1.45   nonaka 	    IWM_PHY_RX_CHAIN_VALID_POS);
   3823   1.1    pooka 	cmd->rxchain_info |= htole32(idle_cnt << IWM_PHY_RX_CHAIN_CNT_POS);
   3824   1.1    pooka 	cmd->rxchain_info |= htole32(active_cnt <<
   3825   1.1    pooka 	    IWM_PHY_RX_CHAIN_MIMO_CNT_POS);
   3826   1.1    pooka 
   3827  1.45   nonaka 	cmd->txchain_info = htole32(iwm_fw_valid_tx_ant(sc));
   3828   1.1    pooka }
   3829   1.1    pooka 
   3830   1.4   nonaka static int
   3831  1.45   nonaka iwm_phy_ctxt_cmd(struct iwm_softc *sc, struct iwm_phy_ctxt *ctxt,
   3832  1.45   nonaka     uint8_t chains_static, uint8_t chains_dynamic, uint32_t action,
   3833  1.45   nonaka     uint32_t apply_time)
   3834   1.1    pooka {
   3835   1.1    pooka 	struct iwm_phy_context_cmd cmd;
   3836   1.1    pooka 
   3837  1.45   nonaka 	iwm_phy_ctxt_cmd_hdr(sc, ctxt, &cmd, action, apply_time);
   3838   1.1    pooka 
   3839  1.45   nonaka 	iwm_phy_ctxt_cmd_data(sc, &cmd, ctxt->channel,
   3840   1.1    pooka 	    chains_static, chains_dynamic);
   3841   1.1    pooka 
   3842  1.45   nonaka 	return iwm_send_cmd_pdu(sc, IWM_PHY_CONTEXT_CMD, 0,
   3843   1.1    pooka 	    sizeof(struct iwm_phy_context_cmd), &cmd);
   3844   1.1    pooka }
   3845   1.1    pooka 
   3846   1.4   nonaka static int
   3847   1.1    pooka iwm_send_cmd(struct iwm_softc *sc, struct iwm_host_cmd *hcmd)
   3848   1.1    pooka {
   3849  1.45   nonaka 	struct iwm_tx_ring *ring = &sc->txq[IWM_CMD_QUEUE];
   3850   1.1    pooka 	struct iwm_tfd *desc;
   3851  1.45   nonaka 	struct iwm_tx_data *txdata;
   3852   1.1    pooka 	struct iwm_device_cmd *cmd;
   3853   1.1    pooka 	struct mbuf *m;
   3854   1.1    pooka 	bus_addr_t paddr;
   3855   1.1    pooka 	uint32_t addr_lo;
   3856  1.45   nonaka 	int err = 0, i, paylen, off, s;
   3857   1.1    pooka 	int code;
   3858   1.1    pooka 	int async, wantresp;
   3859  1.45   nonaka 	int group_id;
   3860  1.45   nonaka 	size_t hdrlen, datasz;
   3861  1.45   nonaka 	uint8_t *data;
   3862   1.1    pooka 
   3863   1.1    pooka 	code = hcmd->id;
   3864   1.1    pooka 	async = hcmd->flags & IWM_CMD_ASYNC;
   3865   1.1    pooka 	wantresp = hcmd->flags & IWM_CMD_WANT_SKB;
   3866   1.1    pooka 
   3867   1.1    pooka 	for (i = 0, paylen = 0; i < __arraycount(hcmd->len); i++) {
   3868   1.1    pooka 		paylen += hcmd->len[i];
   3869   1.1    pooka 	}
   3870   1.1    pooka 
   3871   1.1    pooka 	/* if the command wants an answer, busy sc_cmd_resp */
   3872   1.1    pooka 	if (wantresp) {
   3873   1.1    pooka 		KASSERT(!async);
   3874  1.45   nonaka 		while (sc->sc_wantresp != IWM_CMD_RESP_IDLE)
   3875   1.1    pooka 			tsleep(&sc->sc_wantresp, 0, "iwmcmdsl", 0);
   3876   1.1    pooka 		sc->sc_wantresp = ring->qid << 16 | ring->cur;
   3877   1.1    pooka 	}
   3878   1.1    pooka 
   3879   1.1    pooka 	/*
   3880   1.1    pooka 	 * Is the hardware still available?  (after e.g. above wait).
   3881   1.1    pooka 	 */
   3882   1.1    pooka 	s = splnet();
   3883   1.1    pooka 	if (sc->sc_flags & IWM_FLAG_STOPPED) {
   3884  1.45   nonaka 		err = ENXIO;
   3885   1.1    pooka 		goto out;
   3886   1.1    pooka 	}
   3887   1.1    pooka 
   3888   1.1    pooka 	desc = &ring->desc[ring->cur];
   3889  1.45   nonaka 	txdata = &ring->data[ring->cur];
   3890  1.45   nonaka 
   3891  1.45   nonaka 	group_id = iwm_cmd_groupid(code);
   3892  1.45   nonaka 	if (group_id != 0) {
   3893  1.45   nonaka 		hdrlen = sizeof(cmd->hdr_wide);
   3894  1.45   nonaka 		datasz = sizeof(cmd->data_wide);
   3895  1.45   nonaka 	} else {
   3896  1.45   nonaka 		hdrlen = sizeof(cmd->hdr);
   3897  1.45   nonaka 		datasz = sizeof(cmd->data);
   3898  1.45   nonaka 	}
   3899   1.1    pooka 
   3900  1.45   nonaka 	if (paylen > datasz) {
   3901  1.45   nonaka 		/* Command is too large to fit in pre-allocated space. */
   3902  1.45   nonaka 		size_t totlen = hdrlen + paylen;
   3903  1.45   nonaka 		if (paylen > IWM_MAX_CMD_PAYLOAD_SIZE) {
   3904  1.45   nonaka 			aprint_error_dev(sc->sc_dev,
   3905  1.45   nonaka 			    "firmware command too long (%zd bytes)\n", totlen);
   3906  1.45   nonaka 			err = EINVAL;
   3907   1.1    pooka 			goto out;
   3908   1.1    pooka 		}
   3909   1.1    pooka 		m = m_gethdr(M_DONTWAIT, MT_DATA);
   3910   1.1    pooka 		if (m == NULL) {
   3911  1.45   nonaka 			err = ENOMEM;
   3912   1.1    pooka 			goto out;
   3913   1.1    pooka 		}
   3914   1.1    pooka 		MEXTMALLOC(m, IWM_RBUF_SIZE, M_DONTWAIT);
   3915   1.1    pooka 		if (!(m->m_flags & M_EXT)) {
   3916  1.45   nonaka 			aprint_error_dev(sc->sc_dev,
   3917  1.45   nonaka 			    "could not get fw cmd mbuf (%zd bytes)\n", totlen);
   3918   1.1    pooka 			m_freem(m);
   3919  1.45   nonaka 			err = ENOMEM;
   3920   1.1    pooka 			goto out;
   3921   1.1    pooka 		}
   3922   1.1    pooka 		cmd = mtod(m, struct iwm_device_cmd *);
   3923  1.45   nonaka 		err = bus_dmamap_load(sc->sc_dmat, txdata->map, cmd,
   3924  1.45   nonaka 		    totlen, NULL, BUS_DMA_NOWAIT | BUS_DMA_WRITE);
   3925  1.45   nonaka 		if (err) {
   3926  1.45   nonaka 			aprint_error_dev(sc->sc_dev,
   3927  1.45   nonaka 			    "could not load fw cmd mbuf (%zd bytes)\n", totlen);
   3928   1.1    pooka 			m_freem(m);
   3929   1.1    pooka 			goto out;
   3930   1.1    pooka 		}
   3931  1.45   nonaka 		txdata->m = m;
   3932  1.45   nonaka 		paddr = txdata->map->dm_segs[0].ds_addr;
   3933   1.1    pooka 	} else {
   3934   1.1    pooka 		cmd = &ring->cmd[ring->cur];
   3935  1.45   nonaka 		paddr = txdata->cmd_paddr;
   3936   1.1    pooka 	}
   3937   1.1    pooka 
   3938  1.45   nonaka 	if (group_id != 0) {
   3939  1.45   nonaka 		cmd->hdr_wide.opcode = iwm_cmd_opcode(code);
   3940  1.45   nonaka 		cmd->hdr_wide.group_id = group_id;
   3941  1.45   nonaka 		cmd->hdr_wide.qid = ring->qid;
   3942  1.45   nonaka 		cmd->hdr_wide.idx = ring->cur;
   3943  1.45   nonaka 		cmd->hdr_wide.length = htole16(paylen);
   3944  1.45   nonaka 		cmd->hdr_wide.version = iwm_cmd_version(code);
   3945  1.45   nonaka 		data = cmd->data_wide;
   3946  1.45   nonaka 	} else {
   3947  1.45   nonaka 		cmd->hdr.code = code;
   3948  1.45   nonaka 		cmd->hdr.flags = 0;
   3949  1.45   nonaka 		cmd->hdr.qid = ring->qid;
   3950  1.45   nonaka 		cmd->hdr.idx = ring->cur;
   3951  1.45   nonaka 		data = cmd->data;
   3952  1.45   nonaka 	}
   3953   1.1    pooka 
   3954   1.1    pooka 	for (i = 0, off = 0; i < __arraycount(hcmd->data); i++) {
   3955   1.1    pooka 		if (hcmd->len[i] == 0)
   3956   1.1    pooka 			continue;
   3957  1.45   nonaka 		memcpy(data + off, hcmd->data[i], hcmd->len[i]);
   3958   1.1    pooka 		off += hcmd->len[i];
   3959   1.1    pooka 	}
   3960   1.1    pooka 	KASSERT(off == paylen);
   3961   1.1    pooka 
   3962   1.1    pooka 	/* lo field is not aligned */
   3963   1.1    pooka 	addr_lo = htole32((uint32_t)paddr);
   3964   1.1    pooka 	memcpy(&desc->tbs[0].lo, &addr_lo, sizeof(uint32_t));
   3965   1.1    pooka 	desc->tbs[0].hi_n_len  = htole16(iwm_get_dma_hi_addr(paddr)
   3966  1.45   nonaka 	    | ((hdrlen + paylen) << 4));
   3967   1.1    pooka 	desc->num_tbs = 1;
   3968   1.1    pooka 
   3969   1.9   nonaka 	DPRINTFN(8, ("iwm_send_cmd 0x%x size=%zu %s\n",
   3970  1.52   nonaka 	    code, hdrlen + paylen, async ? " (async)" : ""));
   3971   1.1    pooka 
   3972  1.45   nonaka 	if (paylen > datasz) {
   3973  1.61   nonaka 		bus_dmamap_sync(sc->sc_dmat, txdata->map, 0, hdrlen + paylen,
   3974  1.61   nonaka 		    BUS_DMASYNC_PREWRITE);
   3975   1.1    pooka 	} else {
   3976   1.1    pooka 		bus_dmamap_sync(sc->sc_dmat, ring->cmd_dma.map,
   3977  1.61   nonaka 		    (uint8_t *)cmd - (uint8_t *)ring->cmd, hdrlen + paylen,
   3978  1.61   nonaka 		    BUS_DMASYNC_PREWRITE);
   3979   1.1    pooka 	}
   3980   1.1    pooka 	bus_dmamap_sync(sc->sc_dmat, ring->desc_dma.map,
   3981  1.61   nonaka 	    (uint8_t *)desc - (uint8_t *)ring->desc, sizeof(*desc),
   3982  1.61   nonaka 	    BUS_DMASYNC_PREWRITE);
   3983   1.1    pooka 
   3984  1.59   nonaka 	err = iwm_set_cmd_in_flight(sc);
   3985  1.59   nonaka 	if (err)
   3986   1.1    pooka 		goto out;
   3987  1.59   nonaka 	ring->queued++;
   3988   1.1    pooka 
   3989   1.1    pooka #if 0
   3990   1.1    pooka 	iwm_update_sched(sc, ring->qid, ring->cur, 0, 0);
   3991   1.1    pooka #endif
   3992   1.1    pooka 	DPRINTF(("sending command 0x%x qid %d, idx %d\n",
   3993   1.1    pooka 	    code, ring->qid, ring->cur));
   3994   1.1    pooka 
   3995   1.1    pooka 	/* Kick command ring. */
   3996   1.1    pooka 	ring->cur = (ring->cur + 1) % IWM_TX_RING_COUNT;
   3997   1.1    pooka 	IWM_WRITE(sc, IWM_HBUS_TARG_WRPTR, ring->qid << 8 | ring->cur);
   3998   1.1    pooka 
   3999   1.1    pooka 	if (!async) {
   4000   1.1    pooka 		int generation = sc->sc_generation;
   4001  1.45   nonaka 		err = tsleep(desc, PCATCH, "iwmcmd", mstohz(1000));
   4002  1.45   nonaka 		if (err == 0) {
   4003   1.1    pooka 			/* if hardware is no longer up, return error */
   4004   1.1    pooka 			if (generation != sc->sc_generation) {
   4005  1.45   nonaka 				err = ENXIO;
   4006   1.1    pooka 			} else {
   4007   1.1    pooka 				hcmd->resp_pkt = (void *)sc->sc_cmd_resp;
   4008   1.1    pooka 			}
   4009   1.1    pooka 		}
   4010   1.1    pooka 	}
   4011   1.1    pooka  out:
   4012  1.45   nonaka 	if (wantresp && err) {
   4013   1.1    pooka 		iwm_free_resp(sc, hcmd);
   4014   1.1    pooka 	}
   4015   1.1    pooka 	splx(s);
   4016   1.1    pooka 
   4017  1.45   nonaka 	return err;
   4018   1.1    pooka }
   4019   1.1    pooka 
   4020   1.4   nonaka static int
   4021  1.45   nonaka iwm_send_cmd_pdu(struct iwm_softc *sc, uint32_t id, uint32_t flags,
   4022  1.45   nonaka     uint16_t len, const void *data)
   4023   1.1    pooka {
   4024   1.1    pooka 	struct iwm_host_cmd cmd = {
   4025   1.1    pooka 		.id = id,
   4026   1.1    pooka 		.len = { len, },
   4027   1.1    pooka 		.data = { data, },
   4028   1.1    pooka 		.flags = flags,
   4029   1.1    pooka 	};
   4030   1.1    pooka 
   4031   1.1    pooka 	return iwm_send_cmd(sc, &cmd);
   4032   1.1    pooka }
   4033   1.1    pooka 
   4034   1.4   nonaka static int
   4035  1.45   nonaka iwm_send_cmd_status(struct iwm_softc *sc, struct iwm_host_cmd *cmd,
   4036  1.45   nonaka     uint32_t *status)
   4037   1.1    pooka {
   4038   1.1    pooka 	struct iwm_rx_packet *pkt;
   4039   1.1    pooka 	struct iwm_cmd_response *resp;
   4040  1.45   nonaka 	int err, resp_len;
   4041   1.1    pooka 
   4042   1.1    pooka 	KASSERT((cmd->flags & IWM_CMD_WANT_SKB) == 0);
   4043  1.45   nonaka 	cmd->flags |= IWM_CMD_WANT_SKB;
   4044   1.1    pooka 
   4045  1.45   nonaka 	err = iwm_send_cmd(sc, cmd);
   4046  1.45   nonaka 	if (err)
   4047  1.45   nonaka 		return err;
   4048   1.1    pooka 	pkt = cmd->resp_pkt;
   4049   1.1    pooka 
   4050   1.1    pooka 	/* Can happen if RFKILL is asserted */
   4051   1.1    pooka 	if (!pkt) {
   4052  1.45   nonaka 		err = 0;
   4053   1.1    pooka 		goto out_free_resp;
   4054   1.1    pooka 	}
   4055   1.1    pooka 
   4056   1.1    pooka 	if (pkt->hdr.flags & IWM_CMD_FAILED_MSK) {
   4057  1.45   nonaka 		err = EIO;
   4058   1.1    pooka 		goto out_free_resp;
   4059   1.1    pooka 	}
   4060   1.1    pooka 
   4061   1.1    pooka 	resp_len = iwm_rx_packet_payload_len(pkt);
   4062   1.1    pooka 	if (resp_len != sizeof(*resp)) {
   4063  1.45   nonaka 		err = EIO;
   4064   1.1    pooka 		goto out_free_resp;
   4065   1.1    pooka 	}
   4066   1.1    pooka 
   4067   1.1    pooka 	resp = (void *)pkt->data;
   4068   1.1    pooka 	*status = le32toh(resp->status);
   4069   1.1    pooka  out_free_resp:
   4070   1.1    pooka 	iwm_free_resp(sc, cmd);
   4071  1.45   nonaka 	return err;
   4072   1.1    pooka }
   4073   1.1    pooka 
   4074   1.4   nonaka static int
   4075  1.45   nonaka iwm_send_cmd_pdu_status(struct iwm_softc *sc, uint32_t id, uint16_t len,
   4076  1.45   nonaka     const void *data, uint32_t *status)
   4077   1.1    pooka {
   4078   1.1    pooka 	struct iwm_host_cmd cmd = {
   4079   1.1    pooka 		.id = id,
   4080   1.1    pooka 		.len = { len, },
   4081   1.1    pooka 		.data = { data, },
   4082   1.1    pooka 	};
   4083   1.1    pooka 
   4084  1.45   nonaka 	return iwm_send_cmd_status(sc, &cmd, status);
   4085   1.1    pooka }
   4086   1.1    pooka 
   4087   1.4   nonaka static void
   4088   1.1    pooka iwm_free_resp(struct iwm_softc *sc, struct iwm_host_cmd *hcmd)
   4089   1.1    pooka {
   4090  1.45   nonaka 	KASSERT(sc->sc_wantresp != IWM_CMD_RESP_IDLE);
   4091  1.45   nonaka 	KASSERT((hcmd->flags & IWM_CMD_WANT_SKB) == IWM_CMD_WANT_SKB);
   4092  1.45   nonaka 	sc->sc_wantresp = IWM_CMD_RESP_IDLE;
   4093   1.1    pooka 	wakeup(&sc->sc_wantresp);
   4094   1.1    pooka }
   4095   1.1    pooka 
   4096   1.4   nonaka static void
   4097  1.45   nonaka iwm_cmd_done(struct iwm_softc *sc, int qid, int idx)
   4098   1.1    pooka {
   4099  1.45   nonaka 	struct iwm_tx_ring *ring = &sc->txq[IWM_CMD_QUEUE];
   4100   1.1    pooka 	struct iwm_tx_data *data;
   4101  1.61   nonaka 	int s;
   4102   1.1    pooka 
   4103  1.45   nonaka 	if (qid != IWM_CMD_QUEUE) {
   4104   1.1    pooka 		return;	/* Not a command ack. */
   4105   1.1    pooka 	}
   4106   1.1    pooka 
   4107  1.61   nonaka 	s = splnet();
   4108  1.61   nonaka 
   4109  1.45   nonaka 	data = &ring->data[idx];
   4110   1.1    pooka 
   4111   1.1    pooka 	if (data->m != NULL) {
   4112   1.1    pooka 		bus_dmamap_sync(sc->sc_dmat, data->map, 0,
   4113   1.1    pooka 		    data->map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
   4114   1.1    pooka 		bus_dmamap_unload(sc->sc_dmat, data->map);
   4115   1.1    pooka 		m_freem(data->m);
   4116   1.1    pooka 		data->m = NULL;
   4117   1.1    pooka 	}
   4118  1.45   nonaka 	wakeup(&ring->desc[idx]);
   4119  1.59   nonaka 
   4120  1.59   nonaka 	if (((idx + ring->queued) % IWM_TX_RING_COUNT) != ring->cur) {
   4121  1.59   nonaka 		aprint_error_dev(sc->sc_dev,
   4122  1.59   nonaka 		    "Some HCMDs skipped?: idx=%d queued=%d cur=%d\n",
   4123  1.59   nonaka 		    idx, ring->queued, ring->cur);
   4124  1.59   nonaka 	}
   4125  1.59   nonaka 
   4126  1.59   nonaka 	KASSERT(ring->queued > 0);
   4127  1.59   nonaka 	if (--ring->queued == 0)
   4128  1.59   nonaka 		iwm_clear_cmd_in_flight(sc);
   4129  1.61   nonaka 
   4130  1.61   nonaka 	splx(s);
   4131   1.1    pooka }
   4132   1.1    pooka 
   4133   1.1    pooka #if 0
   4134   1.1    pooka /*
   4135   1.1    pooka  * necessary only for block ack mode
   4136   1.1    pooka  */
   4137   1.1    pooka void
   4138   1.1    pooka iwm_update_sched(struct iwm_softc *sc, int qid, int idx, uint8_t sta_id,
   4139  1.45   nonaka     uint16_t len)
   4140   1.1    pooka {
   4141   1.1    pooka 	struct iwm_agn_scd_bc_tbl *scd_bc_tbl;
   4142   1.1    pooka 	uint16_t w_val;
   4143   1.1    pooka 
   4144   1.1    pooka 	scd_bc_tbl = sc->sched_dma.vaddr;
   4145   1.1    pooka 
   4146   1.1    pooka 	len += 8; /* magic numbers came naturally from paris */
   4147   1.1    pooka 	if (sc->sc_capaflags & IWM_UCODE_TLV_FLAGS_DW_BC_TABLE)
   4148   1.1    pooka 		len = roundup(len, 4) / 4;
   4149   1.1    pooka 
   4150   1.1    pooka 	w_val = htole16(sta_id << 12 | len);
   4151   1.1    pooka 
   4152   1.1    pooka 	/* Update TX scheduler. */
   4153   1.1    pooka 	scd_bc_tbl[qid].tfd_offset[idx] = w_val;
   4154   1.1    pooka 	bus_dmamap_sync(sc->sc_dmat, sc->sched_dma.map,
   4155   1.1    pooka 	    (char *)(void *)w - (char *)(void *)sc->sched_dma.vaddr,
   4156   1.1    pooka 	    sizeof(uint16_t), BUS_DMASYNC_PREWRITE);
   4157   1.1    pooka 
   4158   1.1    pooka 	/* I really wonder what this is ?!? */
   4159   1.1    pooka 	if (idx < IWM_TFD_QUEUE_SIZE_BC_DUP) {
   4160   1.1    pooka 		scd_bc_tbl[qid].tfd_offset[IWM_TFD_QUEUE_SIZE_MAX + idx] = w_val;
   4161   1.1    pooka 		bus_dmamap_sync(sc->sc_dmat, sc->sched_dma.map,
   4162   1.1    pooka 		    (char *)(void *)(w + IWM_TFD_QUEUE_SIZE_MAX) -
   4163   1.1    pooka 		    (char *)(void *)sc->sched_dma.vaddr,
   4164   1.1    pooka 		    sizeof (uint16_t), BUS_DMASYNC_PREWRITE);
   4165   1.1    pooka 	}
   4166   1.1    pooka }
   4167   1.1    pooka #endif
   4168   1.1    pooka 
   4169   1.1    pooka /*
   4170   1.1    pooka  * Fill in various bit for management frames, and leave them
   4171   1.1    pooka  * unfilled for data frames (firmware takes care of that).
   4172   1.1    pooka  * Return the selected TX rate.
   4173   1.1    pooka  */
   4174   1.4   nonaka static const struct iwm_rate *
   4175   1.1    pooka iwm_tx_fill_cmd(struct iwm_softc *sc, struct iwm_node *in,
   4176  1.45   nonaka     struct ieee80211_frame *wh, struct iwm_tx_cmd *tx)
   4177   1.1    pooka {
   4178  1.24   nonaka 	struct ieee80211com *ic = &sc->sc_ic;
   4179  1.28   nonaka 	struct ieee80211_node *ni = &in->in_ni;
   4180   1.1    pooka 	const struct iwm_rate *rinfo;
   4181   1.1    pooka 	int type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
   4182  1.61   nonaka 	int ridx, rate_flags, i, ind;
   4183  1.28   nonaka 	int nrates = ni->ni_rates.rs_nrates;
   4184   1.1    pooka 
   4185   1.1    pooka 	tx->rts_retry_limit = IWM_RTS_DFAULT_RETRY_LIMIT;
   4186   1.1    pooka 	tx->data_retry_limit = IWM_DEFAULT_TX_RETRY;
   4187   1.1    pooka 
   4188  1.45   nonaka 	if (IEEE80211_IS_MULTICAST(wh->i_addr1) ||
   4189  1.45   nonaka 	    type != IEEE80211_FC0_TYPE_DATA) {
   4190  1.28   nonaka 		/* for non-data, use the lowest supported rate */
   4191  1.45   nonaka 		ridx = (IEEE80211_IS_CHAN_5GHZ(ni->ni_chan)) ?
   4192  1.28   nonaka 		    IWM_RIDX_OFDM : IWM_RIDX_CCK;
   4193  1.45   nonaka 		tx->data_retry_limit = IWM_MGMT_DFAULT_RETRY_LIMIT;
   4194  1.45   nonaka #ifndef IEEE80211_NO_HT
   4195  1.45   nonaka 	} else if (ic->ic_fixed_mcs != -1) {
   4196  1.45   nonaka 		ridx = sc->sc_fixed_ridx;
   4197  1.45   nonaka #endif
   4198  1.28   nonaka 	} else if (ic->ic_fixed_rate != -1) {
   4199  1.28   nonaka 		ridx = sc->sc_fixed_ridx;
   4200  1.28   nonaka 	} else {
   4201  1.28   nonaka 		/* for data frames, use RS table */
   4202  1.45   nonaka 		tx->initial_rate_index = 0;
   4203   1.8   nonaka 		tx->tx_flags |= htole32(IWM_TX_CMD_FLG_STA_RATE);
   4204  1.45   nonaka 		DPRINTFN(12, ("start with txrate %d\n",
   4205  1.45   nonaka 		    tx->initial_rate_index));
   4206  1.45   nonaka #ifndef IEEE80211_NO_HT
   4207  1.45   nonaka 		if (ni->ni_flags & IEEE80211_NODE_HT) {
   4208  1.45   nonaka 			ridx = iwm_mcs2ridx[ni->ni_txmcs];
   4209  1.45   nonaka 			return &iwm_rates[ridx];
   4210  1.45   nonaka 		}
   4211  1.45   nonaka #endif
   4212  1.45   nonaka 		ridx = (IEEE80211_IS_CHAN_5GHZ(ni->ni_chan)) ?
   4213  1.45   nonaka 		    IWM_RIDX_OFDM : IWM_RIDX_CCK;
   4214  1.45   nonaka 		for (i = 0; i < nrates; i++) {
   4215  1.45   nonaka 			if (iwm_rates[i].rate == (ni->ni_txrate &
   4216  1.45   nonaka 			    IEEE80211_RATE_VAL)) {
   4217  1.45   nonaka 				ridx = i;
   4218  1.45   nonaka 				break;
   4219  1.45   nonaka 			}
   4220  1.45   nonaka 		}
   4221  1.28   nonaka 		return &iwm_rates[ridx];
   4222   1.1    pooka 	}
   4223   1.1    pooka 
   4224   1.1    pooka 	rinfo = &iwm_rates[ridx];
   4225  1.61   nonaka 	for (i = 0, ind = sc->sc_mgmt_last_antenna;
   4226  1.61   nonaka 	    i < IWM_RATE_MCS_ANT_NUM; i++) {
   4227  1.61   nonaka 		ind = (ind + 1) % IWM_RATE_MCS_ANT_NUM;
   4228  1.61   nonaka 		if (iwm_fw_valid_tx_ant(sc) & (1 << ind)) {
   4229  1.61   nonaka 			sc->sc_mgmt_last_antenna = ind;
   4230  1.61   nonaka 			break;
   4231  1.61   nonaka 		}
   4232  1.61   nonaka 	}
   4233  1.61   nonaka 	rate_flags = (1 << sc->sc_mgmt_last_antenna) << IWM_RATE_MCS_ANT_POS;
   4234   1.1    pooka 	if (IWM_RIDX_IS_CCK(ridx))
   4235   1.1    pooka 		rate_flags |= IWM_RATE_MCS_CCK_MSK;
   4236  1.45   nonaka #ifndef IEEE80211_NO_HT
   4237  1.45   nonaka 	if ((ni->ni_flags & IEEE80211_NODE_HT) &&
   4238  1.45   nonaka 	    rinfo->ht_plcp != IWM_RATE_HT_SISO_MCS_INV_PLCP) {
   4239  1.45   nonaka 		rate_flags |= IWM_RATE_MCS_HT_MSK;
   4240  1.45   nonaka 		tx->rate_n_flags = htole32(rate_flags | rinfo->ht_plcp);
   4241  1.45   nonaka 	} else
   4242  1.45   nonaka #endif
   4243  1.45   nonaka 		tx->rate_n_flags = htole32(rate_flags | rinfo->plcp);
   4244   1.1    pooka 
   4245   1.1    pooka 	return rinfo;
   4246   1.1    pooka }
   4247   1.1    pooka 
   4248   1.1    pooka #define TB0_SIZE 16
   4249   1.4   nonaka static int
   4250   1.1    pooka iwm_tx(struct iwm_softc *sc, struct mbuf *m, struct ieee80211_node *ni, int ac)
   4251   1.1    pooka {
   4252   1.1    pooka 	struct ieee80211com *ic = &sc->sc_ic;
   4253  1.45   nonaka 	struct iwm_node *in = (struct iwm_node *)ni;
   4254   1.1    pooka 	struct iwm_tx_ring *ring;
   4255   1.1    pooka 	struct iwm_tx_data *data;
   4256   1.1    pooka 	struct iwm_tfd *desc;
   4257   1.1    pooka 	struct iwm_device_cmd *cmd;
   4258   1.1    pooka 	struct iwm_tx_cmd *tx;
   4259   1.1    pooka 	struct ieee80211_frame *wh;
   4260   1.1    pooka 	struct ieee80211_key *k = NULL;
   4261   1.1    pooka 	struct mbuf *m1;
   4262   1.1    pooka 	const struct iwm_rate *rinfo;
   4263   1.1    pooka 	uint32_t flags;
   4264   1.1    pooka 	u_int hdrlen;
   4265   1.1    pooka 	bus_dma_segment_t *seg;
   4266   1.1    pooka 	uint8_t tid, type;
   4267  1.45   nonaka 	int i, totlen, err, pad;
   4268   1.1    pooka 
   4269   1.1    pooka 	wh = mtod(m, struct ieee80211_frame *);
   4270   1.1    pooka 	hdrlen = ieee80211_anyhdrsize(wh);
   4271   1.1    pooka 	type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
   4272   1.1    pooka 
   4273   1.1    pooka 	tid = 0;
   4274   1.1    pooka 
   4275   1.1    pooka 	ring = &sc->txq[ac];
   4276   1.1    pooka 	desc = &ring->desc[ring->cur];
   4277   1.1    pooka 	memset(desc, 0, sizeof(*desc));
   4278   1.1    pooka 	data = &ring->data[ring->cur];
   4279   1.1    pooka 
   4280   1.1    pooka 	cmd = &ring->cmd[ring->cur];
   4281   1.1    pooka 	cmd->hdr.code = IWM_TX_CMD;
   4282   1.1    pooka 	cmd->hdr.flags = 0;
   4283   1.1    pooka 	cmd->hdr.qid = ring->qid;
   4284   1.1    pooka 	cmd->hdr.idx = ring->cur;
   4285   1.1    pooka 
   4286   1.1    pooka 	tx = (void *)cmd->data;
   4287   1.1    pooka 	memset(tx, 0, sizeof(*tx));
   4288   1.1    pooka 
   4289   1.1    pooka 	rinfo = iwm_tx_fill_cmd(sc, in, wh, tx);
   4290   1.1    pooka 
   4291  1.48   nonaka 	if (__predict_false(sc->sc_drvbpf != NULL)) {
   4292   1.1    pooka 		struct iwm_tx_radiotap_header *tap = &sc->sc_txtap;
   4293   1.1    pooka 
   4294   1.1    pooka 		tap->wt_flags = 0;
   4295   1.1    pooka 		tap->wt_chan_freq = htole16(ni->ni_chan->ic_freq);
   4296   1.1    pooka 		tap->wt_chan_flags = htole16(ni->ni_chan->ic_flags);
   4297  1.45   nonaka #ifndef IEEE80211_NO_HT
   4298  1.45   nonaka 		if ((ni->ni_flags & IEEE80211_NODE_HT) &&
   4299  1.45   nonaka 		    !IEEE80211_IS_MULTICAST(wh->i_addr1) &&
   4300  1.45   nonaka 		    type == IEEE80211_FC0_TYPE_DATA &&
   4301  1.45   nonaka 		    rinfo->plcp == IWM_RATE_INVM_PLCP) {
   4302  1.45   nonaka 			tap->wt_rate = (0x80 | rinfo->ht_plcp);
   4303  1.45   nonaka 		} else
   4304  1.45   nonaka #endif
   4305  1.45   nonaka 			tap->wt_rate = rinfo->rate;
   4306   1.1    pooka 		tap->wt_hwqueue = ac;
   4307   1.1    pooka 		if (wh->i_fc[1] & IEEE80211_FC1_WEP)
   4308   1.1    pooka 			tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP;
   4309   1.1    pooka 
   4310   1.1    pooka 		bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m);
   4311   1.1    pooka 	}
   4312   1.1    pooka 
   4313   1.1    pooka 	/* Encrypt the frame if need be. */
   4314   1.1    pooka 	if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
   4315   1.1    pooka 		k = ieee80211_crypto_encap(ic, ni, m);
   4316   1.1    pooka 		if (k == NULL) {
   4317   1.1    pooka 			m_freem(m);
   4318   1.1    pooka 			return ENOBUFS;
   4319   1.1    pooka 		}
   4320   1.1    pooka 		/* Packet header may have moved, reset our local pointer. */
   4321   1.1    pooka 		wh = mtod(m, struct ieee80211_frame *);
   4322   1.1    pooka 	}
   4323   1.1    pooka 	totlen = m->m_pkthdr.len;
   4324   1.1    pooka 
   4325   1.1    pooka 	flags = 0;
   4326   1.1    pooka 	if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
   4327   1.1    pooka 		flags |= IWM_TX_CMD_FLG_ACK;
   4328   1.1    pooka 	}
   4329   1.1    pooka 
   4330  1.45   nonaka 	if (type == IEEE80211_FC0_TYPE_DATA &&
   4331  1.45   nonaka 	    !IEEE80211_IS_MULTICAST(wh->i_addr1) &&
   4332  1.45   nonaka 	    (totlen + IEEE80211_CRC_LEN > ic->ic_rtsthreshold ||
   4333  1.45   nonaka 	     (ic->ic_flags & IEEE80211_F_USEPROT)))
   4334   1.1    pooka 		flags |= IWM_TX_CMD_FLG_PROT_REQUIRE;
   4335   1.1    pooka 
   4336   1.1    pooka 	if (IEEE80211_IS_MULTICAST(wh->i_addr1) ||
   4337   1.1    pooka 	    type != IEEE80211_FC0_TYPE_DATA)
   4338  1.45   nonaka 		tx->sta_id = IWM_AUX_STA_ID;
   4339   1.1    pooka 	else
   4340   1.1    pooka 		tx->sta_id = IWM_STATION_ID;
   4341   1.1    pooka 
   4342   1.1    pooka 	if (type == IEEE80211_FC0_TYPE_MGT) {
   4343   1.1    pooka 		uint8_t subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
   4344   1.1    pooka 
   4345   1.1    pooka 		if (subtype == IEEE80211_FC0_SUBTYPE_ASSOC_REQ ||
   4346   1.1    pooka 		    subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ)
   4347  1.54   nonaka 			tx->pm_frame_timeout = htole16(IWM_PM_FRAME_ASSOC);
   4348   1.1    pooka 		else
   4349  1.54   nonaka 			tx->pm_frame_timeout = htole16(IWM_PM_FRAME_MGMT);
   4350   1.1    pooka 	} else {
   4351  1.54   nonaka 		tx->pm_frame_timeout = htole16(IWM_PM_FRAME_NONE);
   4352   1.1    pooka 	}
   4353   1.1    pooka 
   4354   1.8   nonaka 	if (hdrlen & 3) {
   4355   1.8   nonaka 		/* First segment length must be a multiple of 4. */
   4356   1.8   nonaka 		flags |= IWM_TX_CMD_FLG_MH_PAD;
   4357   1.8   nonaka 		pad = 4 - (hdrlen & 3);
   4358   1.8   nonaka 	} else
   4359   1.8   nonaka 		pad = 0;
   4360   1.1    pooka 
   4361   1.1    pooka 	tx->driver_txop = 0;
   4362   1.1    pooka 	tx->next_frame_len = 0;
   4363   1.1    pooka 
   4364   1.1    pooka 	tx->len = htole16(totlen);
   4365   1.1    pooka 	tx->tid_tspec = tid;
   4366   1.1    pooka 	tx->life_time = htole32(IWM_TX_CMD_LIFE_TIME_INFINITE);
   4367   1.1    pooka 
   4368   1.1    pooka 	/* Set physical address of "scratch area". */
   4369   1.1    pooka 	tx->dram_lsb_ptr = htole32(data->scratch_paddr);
   4370   1.1    pooka 	tx->dram_msb_ptr = iwm_get_dma_hi_addr(data->scratch_paddr);
   4371   1.1    pooka 
   4372   1.1    pooka 	/* Copy 802.11 header in TX command. */
   4373  1.61   nonaka 	memcpy(tx + 1, wh, hdrlen);
   4374   1.1    pooka 
   4375   1.1    pooka 	flags |= IWM_TX_CMD_FLG_BT_DIS | IWM_TX_CMD_FLG_SEQ_CTL;
   4376   1.1    pooka 
   4377   1.1    pooka 	tx->sec_ctl = 0;
   4378   1.1    pooka 	tx->tx_flags |= htole32(flags);
   4379   1.1    pooka 
   4380   1.1    pooka 	/* Trim 802.11 header. */
   4381   1.1    pooka 	m_adj(m, hdrlen);
   4382   1.1    pooka 
   4383  1.45   nonaka 	err = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m,
   4384   1.1    pooka 	    BUS_DMA_NOWAIT | BUS_DMA_WRITE);
   4385  1.45   nonaka 	if (err) {
   4386  1.45   nonaka 		if (err != EFBIG) {
   4387   1.3   nonaka 			aprint_error_dev(sc->sc_dev,
   4388  1.45   nonaka 			    "can't map mbuf (error %d)\n", err);
   4389   1.1    pooka 			m_freem(m);
   4390  1.45   nonaka 			return err;
   4391   1.1    pooka 		}
   4392   1.1    pooka 		/* Too many DMA segments, linearize mbuf. */
   4393   1.1    pooka 		MGETHDR(m1, M_DONTWAIT, MT_DATA);
   4394   1.1    pooka 		if (m1 == NULL) {
   4395   1.1    pooka 			m_freem(m);
   4396   1.1    pooka 			return ENOBUFS;
   4397   1.1    pooka 		}
   4398   1.1    pooka 		if (m->m_pkthdr.len > MHLEN) {
   4399   1.1    pooka 			MCLGET(m1, M_DONTWAIT);
   4400   1.1    pooka 			if (!(m1->m_flags & M_EXT)) {
   4401   1.1    pooka 				m_freem(m);
   4402   1.1    pooka 				m_freem(m1);
   4403   1.1    pooka 				return ENOBUFS;
   4404   1.1    pooka 			}
   4405   1.1    pooka 		}
   4406   1.1    pooka 		m_copydata(m, 0, m->m_pkthdr.len, mtod(m1, void *));
   4407   1.1    pooka 		m1->m_pkthdr.len = m1->m_len = m->m_pkthdr.len;
   4408   1.1    pooka 		m_freem(m);
   4409   1.1    pooka 		m = m1;
   4410   1.1    pooka 
   4411  1.45   nonaka 		err = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m,
   4412   1.1    pooka 		    BUS_DMA_NOWAIT | BUS_DMA_WRITE);
   4413  1.45   nonaka 		if (err) {
   4414   1.3   nonaka 			aprint_error_dev(sc->sc_dev,
   4415  1.45   nonaka 			    "can't map mbuf (error %d)\n", err);
   4416   1.1    pooka 			m_freem(m);
   4417  1.45   nonaka 			return err;
   4418   1.1    pooka 		}
   4419   1.1    pooka 	}
   4420   1.1    pooka 	data->m = m;
   4421   1.1    pooka 	data->in = in;
   4422   1.1    pooka 	data->done = 0;
   4423   1.1    pooka 
   4424   1.1    pooka 	DPRINTFN(8, ("sending txd %p, in %p\n", data, data->in));
   4425   1.1    pooka 	KASSERT(data->in != NULL);
   4426   1.1    pooka 
   4427  1.61   nonaka 	DPRINTFN(8, ("sending data: qid=%d idx=%d len=%d nsegs=%d type=%d "
   4428  1.61   nonaka 	    "subtype=%x tx_flags=%08x init_rateidx=%08x rate_n_flags=%08x\n",
   4429  1.61   nonaka 	    ring->qid, ring->cur, totlen, data->map->dm_nsegs, type,
   4430  1.61   nonaka 	    (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) >> 4,
   4431  1.61   nonaka 	    le32toh(tx->tx_flags), le32toh(tx->initial_rate_index),
   4432  1.61   nonaka 	    le32toh(tx->rate_n_flags)));
   4433   1.1    pooka 
   4434   1.1    pooka 	/* Fill TX descriptor. */
   4435   1.1    pooka 	desc->num_tbs = 2 + data->map->dm_nsegs;
   4436   1.1    pooka 
   4437   1.1    pooka 	desc->tbs[0].lo = htole32(data->cmd_paddr);
   4438   1.1    pooka 	desc->tbs[0].hi_n_len = htole16(iwm_get_dma_hi_addr(data->cmd_paddr)) |
   4439   1.1    pooka 	    (TB0_SIZE << 4);
   4440   1.1    pooka 	desc->tbs[1].lo = htole32(data->cmd_paddr + TB0_SIZE);
   4441   1.1    pooka 	desc->tbs[1].hi_n_len = htole16(iwm_get_dma_hi_addr(data->cmd_paddr)) |
   4442   1.1    pooka 	    ((sizeof(struct iwm_cmd_header) + sizeof(*tx)
   4443   1.1    pooka 	      + hdrlen + pad - TB0_SIZE) << 4);
   4444   1.1    pooka 
   4445   1.1    pooka 	/* Other DMA segments are for data payload. */
   4446   1.1    pooka 	seg = data->map->dm_segs;
   4447   1.1    pooka 	for (i = 0; i < data->map->dm_nsegs; i++, seg++) {
   4448   1.1    pooka 		desc->tbs[i+2].lo = htole32(seg->ds_addr);
   4449  1.47   nonaka 		desc->tbs[i+2].hi_n_len =
   4450   1.1    pooka 		    htole16(iwm_get_dma_hi_addr(seg->ds_addr))
   4451   1.1    pooka 		    | ((seg->ds_len) << 4);
   4452   1.1    pooka 	}
   4453   1.1    pooka 
   4454   1.1    pooka 	bus_dmamap_sync(sc->sc_dmat, data->map, 0, data->map->dm_mapsize,
   4455   1.1    pooka 	    BUS_DMASYNC_PREWRITE);
   4456   1.1    pooka 	bus_dmamap_sync(sc->sc_dmat, ring->cmd_dma.map,
   4457  1.61   nonaka 	    (uint8_t *)cmd - (uint8_t *)ring->cmd, sizeof(*cmd),
   4458  1.61   nonaka 	    BUS_DMASYNC_PREWRITE);
   4459   1.1    pooka 	bus_dmamap_sync(sc->sc_dmat, ring->desc_dma.map,
   4460  1.61   nonaka 	    (uint8_t *)desc - (uint8_t *)ring->desc, sizeof(*desc),
   4461  1.61   nonaka 	    BUS_DMASYNC_PREWRITE);
   4462   1.1    pooka 
   4463   1.1    pooka #if 0
   4464  1.45   nonaka 	iwm_update_sched(sc, ring->qid, ring->cur, tx->sta_id,
   4465  1.45   nonaka 	    le16toh(tx->len));
   4466   1.1    pooka #endif
   4467   1.1    pooka 
   4468   1.1    pooka 	/* Kick TX ring. */
   4469   1.1    pooka 	ring->cur = (ring->cur + 1) % IWM_TX_RING_COUNT;
   4470   1.1    pooka 	IWM_WRITE(sc, IWM_HBUS_TARG_WRPTR, ring->qid << 8 | ring->cur);
   4471   1.1    pooka 
   4472   1.1    pooka 	/* Mark TX ring as full if we reach a certain threshold. */
   4473   1.1    pooka 	if (++ring->queued > IWM_TX_RING_HIMARK) {
   4474   1.1    pooka 		sc->qfullmsk |= 1 << ring->qid;
   4475   1.1    pooka 	}
   4476   1.1    pooka 
   4477   1.1    pooka 	return 0;
   4478   1.1    pooka }
   4479   1.1    pooka 
   4480   1.1    pooka #if 0
   4481   1.1    pooka /* not necessary? */
   4482   1.4   nonaka static int
   4483  1.45   nonaka iwm_flush_tx_path(struct iwm_softc *sc, int tfd_msk, int sync)
   4484   1.1    pooka {
   4485   1.1    pooka 	struct iwm_tx_path_flush_cmd flush_cmd = {
   4486   1.1    pooka 		.queues_ctl = htole32(tfd_msk),
   4487   1.1    pooka 		.flush_ctl = htole16(IWM_DUMP_TX_FIFO_FLUSH),
   4488   1.1    pooka 	};
   4489  1.45   nonaka 	int err;
   4490   1.1    pooka 
   4491  1.45   nonaka 	err = iwm_send_cmd_pdu(sc, IWM_TXPATH_FLUSH, sync ? 0 : IWM_CMD_ASYNC,
   4492   1.1    pooka 	    sizeof(flush_cmd), &flush_cmd);
   4493  1.45   nonaka 	if (err)
   4494   1.3   nonaka 		aprint_error_dev(sc->sc_dev, "Flushing tx queue failed: %d\n",
   4495  1.45   nonaka 		    err);
   4496  1.45   nonaka 	return err;
   4497   1.1    pooka }
   4498   1.1    pooka #endif
   4499   1.1    pooka 
   4500  1.45   nonaka static void
   4501  1.45   nonaka iwm_led_enable(struct iwm_softc *sc)
   4502  1.45   nonaka {
   4503  1.45   nonaka 	IWM_WRITE(sc, IWM_CSR_LED_REG, IWM_CSR_LED_REG_TURN_ON);
   4504  1.45   nonaka }
   4505  1.45   nonaka 
   4506  1.45   nonaka static void
   4507  1.45   nonaka iwm_led_disable(struct iwm_softc *sc)
   4508  1.45   nonaka {
   4509  1.45   nonaka 	IWM_WRITE(sc, IWM_CSR_LED_REG, IWM_CSR_LED_REG_TURN_OFF);
   4510  1.45   nonaka }
   4511  1.45   nonaka 
   4512  1.45   nonaka static int
   4513  1.45   nonaka iwm_led_is_enabled(struct iwm_softc *sc)
   4514  1.45   nonaka {
   4515  1.45   nonaka 	return (IWM_READ(sc, IWM_CSR_LED_REG) == IWM_CSR_LED_REG_TURN_ON);
   4516  1.45   nonaka }
   4517  1.45   nonaka 
   4518  1.45   nonaka static void
   4519  1.45   nonaka iwm_led_blink_timeout(void *arg)
   4520  1.45   nonaka {
   4521  1.45   nonaka 	struct iwm_softc *sc = arg;
   4522  1.45   nonaka 
   4523  1.45   nonaka 	if (iwm_led_is_enabled(sc))
   4524  1.45   nonaka 		iwm_led_disable(sc);
   4525  1.45   nonaka 	else
   4526  1.45   nonaka 		iwm_led_enable(sc);
   4527  1.45   nonaka 
   4528  1.45   nonaka 	callout_schedule(&sc->sc_led_blink_to, mstohz(200));
   4529  1.45   nonaka }
   4530  1.45   nonaka 
   4531  1.45   nonaka static void
   4532  1.45   nonaka iwm_led_blink_start(struct iwm_softc *sc)
   4533  1.45   nonaka {
   4534  1.45   nonaka 	callout_schedule(&sc->sc_led_blink_to, mstohz(200));
   4535  1.45   nonaka }
   4536   1.1    pooka 
   4537  1.45   nonaka static void
   4538  1.45   nonaka iwm_led_blink_stop(struct iwm_softc *sc)
   4539  1.45   nonaka {
   4540  1.45   nonaka 	callout_stop(&sc->sc_led_blink_to);
   4541  1.45   nonaka 	iwm_led_disable(sc);
   4542  1.45   nonaka }
   4543   1.1    pooka 
   4544   1.1    pooka #define IWM_POWER_KEEP_ALIVE_PERIOD_SEC    25
   4545   1.1    pooka 
   4546   1.4   nonaka static int
   4547  1.45   nonaka iwm_beacon_filter_send_cmd(struct iwm_softc *sc,
   4548  1.51   nonaka     struct iwm_beacon_filter_cmd *cmd)
   4549   1.1    pooka {
   4550  1.45   nonaka 	return iwm_send_cmd_pdu(sc, IWM_REPLY_BEACON_FILTERING_CMD,
   4551  1.45   nonaka 	    0, sizeof(struct iwm_beacon_filter_cmd), cmd);
   4552   1.1    pooka }
   4553   1.1    pooka 
   4554   1.4   nonaka static void
   4555  1.45   nonaka iwm_beacon_filter_set_cqm_params(struct iwm_softc *sc, struct iwm_node *in,
   4556  1.45   nonaka     struct iwm_beacon_filter_cmd *cmd)
   4557   1.1    pooka {
   4558   1.1    pooka 	cmd->ba_enable_beacon_abort = htole32(sc->sc_bf.ba_enabled);
   4559   1.1    pooka }
   4560   1.1    pooka 
   4561   1.4   nonaka static int
   4562  1.45   nonaka iwm_update_beacon_abort(struct iwm_softc *sc, struct iwm_node *in, int enable)
   4563   1.1    pooka {
   4564   1.1    pooka 	struct iwm_beacon_filter_cmd cmd = {
   4565   1.1    pooka 		IWM_BF_CMD_CONFIG_DEFAULTS,
   4566   1.1    pooka 		.bf_enable_beacon_filter = htole32(1),
   4567   1.1    pooka 		.ba_enable_beacon_abort = htole32(enable),
   4568   1.1    pooka 	};
   4569   1.1    pooka 
   4570   1.1    pooka 	if (!sc->sc_bf.bf_enabled)
   4571   1.1    pooka 		return 0;
   4572   1.1    pooka 
   4573   1.1    pooka 	sc->sc_bf.ba_enabled = enable;
   4574  1.45   nonaka 	iwm_beacon_filter_set_cqm_params(sc, in, &cmd);
   4575  1.45   nonaka 	return iwm_beacon_filter_send_cmd(sc, &cmd);
   4576   1.1    pooka }
   4577   1.1    pooka 
   4578   1.4   nonaka static void
   4579  1.45   nonaka iwm_power_build_cmd(struct iwm_softc *sc, struct iwm_node *in,
   4580  1.45   nonaka     struct iwm_mac_power_cmd *cmd)
   4581   1.1    pooka {
   4582   1.1    pooka 	struct ieee80211_node *ni = &in->in_ni;
   4583  1.45   nonaka 	int dtim_period, dtim_msec, keep_alive;
   4584   1.1    pooka 
   4585   1.1    pooka 	cmd->id_and_color = htole32(IWM_FW_CMD_ID_AND_COLOR(in->in_id,
   4586   1.1    pooka 	    in->in_color));
   4587  1.45   nonaka 	if (ni->ni_dtim_period)
   4588  1.45   nonaka 		dtim_period = ni->ni_dtim_period;
   4589  1.45   nonaka 	else
   4590  1.45   nonaka 		dtim_period = 1;
   4591   1.1    pooka 
   4592   1.1    pooka 	/*
   4593   1.1    pooka 	 * Regardless of power management state the driver must set
   4594   1.1    pooka 	 * keep alive period. FW will use it for sending keep alive NDPs
   4595   1.1    pooka 	 * immediately after association. Check that keep alive period
   4596  1.45   nonaka 	 * is at least 3 * DTIM.
   4597   1.1    pooka 	 */
   4598  1.45   nonaka 	dtim_msec = dtim_period * ni->ni_intval;
   4599  1.45   nonaka 	keep_alive = MAX(3 * dtim_msec, 1000 * IWM_POWER_KEEP_ALIVE_PERIOD_SEC);
   4600   1.1    pooka 	keep_alive = roundup(keep_alive, 1000) / 1000;
   4601   1.1    pooka 	cmd->keep_alive_seconds = htole16(keep_alive);
   4602  1.45   nonaka 
   4603  1.45   nonaka #ifdef notyet
   4604  1.45   nonaka 	cmd->flags = htole16(IWM_POWER_FLAGS_POWER_SAVE_ENA_MSK);
   4605  1.45   nonaka 	cmd->rx_data_timeout = IWM_DEFAULT_PS_RX_DATA_TIMEOUT;
   4606  1.45   nonaka 	cmd->tx_data_timeout = IWM_DEFAULT_PS_TX_DATA_TIMEOUT;
   4607  1.45   nonaka #endif
   4608   1.1    pooka }
   4609   1.1    pooka 
   4610   1.4   nonaka static int
   4611  1.45   nonaka iwm_power_mac_update_mode(struct iwm_softc *sc, struct iwm_node *in)
   4612   1.1    pooka {
   4613  1.45   nonaka 	int err;
   4614   1.1    pooka 	int ba_enable;
   4615   1.1    pooka 	struct iwm_mac_power_cmd cmd;
   4616   1.1    pooka 
   4617   1.1    pooka 	memset(&cmd, 0, sizeof(cmd));
   4618   1.1    pooka 
   4619  1.45   nonaka 	iwm_power_build_cmd(sc, in, &cmd);
   4620   1.1    pooka 
   4621  1.45   nonaka 	err = iwm_send_cmd_pdu(sc, IWM_MAC_PM_POWER_TABLE, 0,
   4622  1.45   nonaka 	    sizeof(cmd), &cmd);
   4623  1.45   nonaka 	if (err)
   4624  1.45   nonaka 		return err;
   4625   1.1    pooka 
   4626   1.1    pooka 	ba_enable = !!(cmd.flags &
   4627   1.1    pooka 	    htole16(IWM_POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK));
   4628  1.45   nonaka 	return iwm_update_beacon_abort(sc, in, ba_enable);
   4629   1.1    pooka }
   4630   1.1    pooka 
   4631   1.4   nonaka static int
   4632  1.45   nonaka iwm_power_update_device(struct iwm_softc *sc)
   4633   1.1    pooka {
   4634   1.1    pooka 	struct iwm_device_power_cmd cmd = {
   4635  1.45   nonaka #ifdef notyet
   4636   1.1    pooka 		.flags = htole16(IWM_DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK),
   4637  1.55  khorben #else
   4638  1.55  khorben 		.flags = 0,
   4639  1.45   nonaka #endif
   4640   1.1    pooka 	};
   4641   1.1    pooka 
   4642   1.1    pooka 	if (!(sc->sc_capaflags & IWM_UCODE_TLV_FLAGS_DEVICE_PS_CMD))
   4643   1.1    pooka 		return 0;
   4644   1.1    pooka 
   4645   1.1    pooka 	cmd.flags |= htole16(IWM_DEVICE_POWER_FLAGS_CAM_MSK);
   4646  1.45   nonaka 	DPRINTF(("Sending device power command with flags = 0x%X\n",
   4647  1.45   nonaka 	    cmd.flags));
   4648   1.1    pooka 
   4649  1.45   nonaka 	return iwm_send_cmd_pdu(sc, IWM_POWER_TABLE_CMD, 0, sizeof(cmd), &cmd);
   4650   1.1    pooka }
   4651   1.1    pooka 
   4652  1.45   nonaka #ifdef notyet
   4653   1.4   nonaka static int
   4654  1.45   nonaka iwm_enable_beacon_filter(struct iwm_softc *sc, struct iwm_node *in)
   4655   1.1    pooka {
   4656   1.1    pooka 	struct iwm_beacon_filter_cmd cmd = {
   4657   1.1    pooka 		IWM_BF_CMD_CONFIG_DEFAULTS,
   4658   1.1    pooka 		.bf_enable_beacon_filter = htole32(1),
   4659   1.1    pooka 	};
   4660  1.45   nonaka 	int err;
   4661   1.1    pooka 
   4662  1.45   nonaka 	iwm_beacon_filter_set_cqm_params(sc, in, &cmd);
   4663  1.45   nonaka 	err = iwm_beacon_filter_send_cmd(sc, &cmd);
   4664   1.1    pooka 
   4665  1.45   nonaka 	if (err == 0)
   4666   1.1    pooka 		sc->sc_bf.bf_enabled = 1;
   4667   1.1    pooka 
   4668  1.45   nonaka 	return err;
   4669   1.1    pooka }
   4670  1.45   nonaka #endif
   4671   1.1    pooka 
   4672   1.4   nonaka static int
   4673  1.45   nonaka iwm_disable_beacon_filter(struct iwm_softc *sc)
   4674   1.1    pooka {
   4675   1.1    pooka 	struct iwm_beacon_filter_cmd cmd;
   4676  1.45   nonaka 	int err;
   4677   1.1    pooka 
   4678   1.1    pooka 	memset(&cmd, 0, sizeof(cmd));
   4679   1.1    pooka 	if ((sc->sc_capaflags & IWM_UCODE_TLV_FLAGS_BF_UPDATED) == 0)
   4680   1.1    pooka 		return 0;
   4681   1.1    pooka 
   4682  1.45   nonaka 	err = iwm_beacon_filter_send_cmd(sc, &cmd);
   4683  1.45   nonaka 	if (err == 0)
   4684   1.1    pooka 		sc->sc_bf.bf_enabled = 0;
   4685   1.1    pooka 
   4686  1.45   nonaka 	return err;
   4687   1.1    pooka }
   4688   1.1    pooka 
   4689   1.4   nonaka static int
   4690  1.45   nonaka iwm_add_sta_cmd(struct iwm_softc *sc, struct iwm_node *in, int update)
   4691   1.1    pooka {
   4692  1.45   nonaka 	struct iwm_add_sta_cmd_v7 add_sta_cmd;
   4693  1.45   nonaka 	int err;
   4694  1.45   nonaka 	uint32_t status;
   4695   1.1    pooka 
   4696  1.45   nonaka 	memset(&add_sta_cmd, 0, sizeof(add_sta_cmd));
   4697   1.1    pooka 
   4698  1.45   nonaka 	add_sta_cmd.sta_id = IWM_STATION_ID;
   4699  1.45   nonaka 	add_sta_cmd.mac_id_n_color
   4700  1.45   nonaka 	    = htole32(IWM_FW_CMD_ID_AND_COLOR(in->in_id, in->in_color));
   4701  1.45   nonaka 	if (!update) {
   4702  1.45   nonaka 		int ac;
   4703  1.45   nonaka 		for (ac = 0; ac < WME_NUM_AC; ac++) {
   4704  1.45   nonaka 			add_sta_cmd.tfd_queue_msk |=
   4705  1.45   nonaka 			    htole32(__BIT(iwm_ac_to_tx_fifo[ac]));
   4706  1.45   nonaka 		}
   4707  1.45   nonaka 		IEEE80211_ADDR_COPY(&add_sta_cmd.addr, in->in_ni.ni_bssid);
   4708  1.45   nonaka 	}
   4709   1.1    pooka 	add_sta_cmd.add_modify = update ? 1 : 0;
   4710   1.1    pooka 	add_sta_cmd.station_flags_msk
   4711   1.1    pooka 	    |= htole32(IWM_STA_FLG_FAT_EN_MSK | IWM_STA_FLG_MIMO_EN_MSK);
   4712  1.45   nonaka 	add_sta_cmd.tid_disable_tx = htole16(0xffff);
   4713  1.45   nonaka 	if (update)
   4714  1.45   nonaka 		add_sta_cmd.modify_mask |= (IWM_STA_MODIFY_TID_DISABLE_TX);
   4715  1.45   nonaka 
   4716  1.45   nonaka #ifndef IEEE80211_NO_HT
   4717  1.45   nonaka 	if (in->in_ni.ni_flags & IEEE80211_NODE_HT) {
   4718  1.45   nonaka 		add_sta_cmd.station_flags_msk
   4719  1.45   nonaka 		    |= htole32(IWM_STA_FLG_MAX_AGG_SIZE_MSK |
   4720  1.45   nonaka 		    IWM_STA_FLG_AGG_MPDU_DENS_MSK);
   4721  1.45   nonaka 
   4722  1.45   nonaka 		add_sta_cmd.station_flags
   4723  1.45   nonaka 		    |= htole32(IWM_STA_FLG_MAX_AGG_SIZE_64K);
   4724  1.45   nonaka 		switch (ic->ic_ampdu_params & IEEE80211_AMPDU_PARAM_SS) {
   4725  1.45   nonaka 		case IEEE80211_AMPDU_PARAM_SS_2:
   4726  1.45   nonaka 			add_sta_cmd.station_flags
   4727  1.45   nonaka 			    |= htole32(IWM_STA_FLG_AGG_MPDU_DENS_2US);
   4728  1.45   nonaka 			break;
   4729  1.45   nonaka 		case IEEE80211_AMPDU_PARAM_SS_4:
   4730  1.45   nonaka 			add_sta_cmd.station_flags
   4731  1.45   nonaka 			    |= htole32(IWM_STA_FLG_AGG_MPDU_DENS_4US);
   4732  1.45   nonaka 			break;
   4733  1.45   nonaka 		case IEEE80211_AMPDU_PARAM_SS_8:
   4734  1.45   nonaka 			add_sta_cmd.station_flags
   4735  1.45   nonaka 			    |= htole32(IWM_STA_FLG_AGG_MPDU_DENS_8US);
   4736  1.45   nonaka 			break;
   4737  1.45   nonaka 		case IEEE80211_AMPDU_PARAM_SS_16:
   4738  1.45   nonaka 			add_sta_cmd.station_flags
   4739  1.45   nonaka 			    |= htole32(IWM_STA_FLG_AGG_MPDU_DENS_16US);
   4740  1.45   nonaka 			break;
   4741  1.45   nonaka 		default:
   4742  1.45   nonaka 			break;
   4743  1.45   nonaka 		}
   4744  1.45   nonaka 	}
   4745  1.45   nonaka #endif
   4746   1.1    pooka 
   4747   1.1    pooka 	status = IWM_ADD_STA_SUCCESS;
   4748  1.45   nonaka 	err = iwm_send_cmd_pdu_status(sc, IWM_ADD_STA, sizeof(add_sta_cmd),
   4749  1.45   nonaka 	    &add_sta_cmd, &status);
   4750  1.45   nonaka 	if (err == 0 && status != IWM_ADD_STA_SUCCESS)
   4751  1.45   nonaka 		err = EIO;
   4752   1.1    pooka 
   4753  1.45   nonaka 	return err;
   4754   1.1    pooka }
   4755   1.1    pooka 
   4756   1.4   nonaka static int
   4757  1.45   nonaka iwm_add_aux_sta(struct iwm_softc *sc)
   4758   1.1    pooka {
   4759  1.45   nonaka 	struct iwm_add_sta_cmd_v7 cmd;
   4760  1.45   nonaka 	int err;
   4761  1.45   nonaka 	uint32_t status;
   4762   1.1    pooka 
   4763  1.45   nonaka 	err = iwm_enable_txq(sc, 0, IWM_AUX_QUEUE, IWM_TX_FIFO_MCAST);
   4764  1.45   nonaka 	if (err)
   4765  1.45   nonaka 		return err;
   4766   1.1    pooka 
   4767   1.1    pooka 	memset(&cmd, 0, sizeof(cmd));
   4768  1.45   nonaka 	cmd.sta_id = IWM_AUX_STA_ID;
   4769  1.45   nonaka 	cmd.mac_id_n_color =
   4770  1.45   nonaka 	    htole32(IWM_FW_CMD_ID_AND_COLOR(IWM_MAC_INDEX_AUX, 0));
   4771  1.45   nonaka 	cmd.tfd_queue_msk = htole32(1 << IWM_AUX_QUEUE);
   4772  1.45   nonaka 	cmd.tid_disable_tx = htole16(0xffff);
   4773   1.1    pooka 
   4774  1.45   nonaka 	status = IWM_ADD_STA_SUCCESS;
   4775  1.45   nonaka 	err = iwm_send_cmd_pdu_status(sc, IWM_ADD_STA, sizeof(cmd), &cmd,
   4776  1.45   nonaka 	    &status);
   4777  1.45   nonaka 	if (err == 0 && status != IWM_ADD_STA_SUCCESS)
   4778  1.45   nonaka 		err = EIO;
   4779   1.1    pooka 
   4780  1.45   nonaka 	return err;
   4781   1.1    pooka }
   4782   1.1    pooka 
   4783   1.1    pooka #define IWM_PLCP_QUIET_THRESH 1
   4784   1.1    pooka #define IWM_ACTIVE_QUIET_TIME 10
   4785   1.1    pooka #define LONG_OUT_TIME_PERIOD 600
   4786   1.1    pooka #define SHORT_OUT_TIME_PERIOD 200
   4787   1.1    pooka #define SUSPEND_TIME_PERIOD 100
   4788   1.1    pooka 
   4789   1.4   nonaka static uint16_t
   4790  1.45   nonaka iwm_scan_rx_chain(struct iwm_softc *sc)
   4791   1.1    pooka {
   4792   1.1    pooka 	uint16_t rx_chain;
   4793   1.1    pooka 	uint8_t rx_ant;
   4794   1.1    pooka 
   4795  1.45   nonaka 	rx_ant = iwm_fw_valid_rx_ant(sc);
   4796   1.1    pooka 	rx_chain = rx_ant << IWM_PHY_RX_CHAIN_VALID_POS;
   4797   1.1    pooka 	rx_chain |= rx_ant << IWM_PHY_RX_CHAIN_FORCE_MIMO_SEL_POS;
   4798   1.1    pooka 	rx_chain |= rx_ant << IWM_PHY_RX_CHAIN_FORCE_SEL_POS;
   4799   1.1    pooka 	rx_chain |= 0x1 << IWM_PHY_RX_CHAIN_DRIVER_FORCE_POS;
   4800   1.1    pooka 	return htole16(rx_chain);
   4801   1.1    pooka }
   4802   1.1    pooka 
   4803   1.4   nonaka static uint32_t
   4804  1.45   nonaka iwm_scan_rate_n_flags(struct iwm_softc *sc, int flags, int no_cck)
   4805   1.1    pooka {
   4806   1.1    pooka 	uint32_t tx_ant;
   4807   1.1    pooka 	int i, ind;
   4808   1.1    pooka 
   4809   1.1    pooka 	for (i = 0, ind = sc->sc_scan_last_antenna;
   4810   1.1    pooka 	    i < IWM_RATE_MCS_ANT_NUM; i++) {
   4811   1.1    pooka 		ind = (ind + 1) % IWM_RATE_MCS_ANT_NUM;
   4812  1.45   nonaka 		if (iwm_fw_valid_tx_ant(sc) & (1 << ind)) {
   4813   1.1    pooka 			sc->sc_scan_last_antenna = ind;
   4814   1.1    pooka 			break;
   4815   1.1    pooka 		}
   4816   1.1    pooka 	}
   4817   1.1    pooka 	tx_ant = (1 << sc->sc_scan_last_antenna) << IWM_RATE_MCS_ANT_POS;
   4818   1.1    pooka 
   4819   1.1    pooka 	if ((flags & IEEE80211_CHAN_2GHZ) && !no_cck)
   4820   1.1    pooka 		return htole32(IWM_RATE_1M_PLCP | IWM_RATE_MCS_CCK_MSK |
   4821   1.1    pooka 				   tx_ant);
   4822   1.1    pooka 	else
   4823   1.1    pooka 		return htole32(IWM_RATE_6M_PLCP | tx_ant);
   4824   1.1    pooka }
   4825   1.1    pooka 
   4826  1.45   nonaka #ifdef notyet
   4827   1.1    pooka /*
   4828   1.1    pooka  * If req->n_ssids > 0, it means we should do an active scan.
   4829   1.1    pooka  * In case of active scan w/o directed scan, we receive a zero-length SSID
   4830   1.1    pooka  * just to notify that this scan is active and not passive.
   4831   1.1    pooka  * In order to notify the FW of the number of SSIDs we wish to scan (including
   4832   1.1    pooka  * the zero-length one), we need to set the corresponding bits in chan->type,
   4833   1.1    pooka  * one for each SSID, and set the active bit (first). If the first SSID is
   4834   1.1    pooka  * already included in the probe template, so we need to set only
   4835   1.1    pooka  * req->n_ssids - 1 bits in addition to the first bit.
   4836   1.1    pooka  */
   4837   1.4   nonaka static uint16_t
   4838  1.45   nonaka iwm_get_active_dwell(struct iwm_softc *sc, int flags, int n_ssids)
   4839   1.1    pooka {
   4840   1.1    pooka 	if (flags & IEEE80211_CHAN_2GHZ)
   4841   1.1    pooka 		return 30  + 3 * (n_ssids + 1);
   4842   1.1    pooka 	return 20  + 2 * (n_ssids + 1);
   4843   1.1    pooka }
   4844   1.1    pooka 
   4845   1.4   nonaka static uint16_t
   4846  1.45   nonaka iwm_get_passive_dwell(struct iwm_softc *sc, int flags)
   4847   1.1    pooka {
   4848   1.1    pooka 	return (flags & IEEE80211_CHAN_2GHZ) ? 100 + 20 : 100 + 10;
   4849   1.1    pooka }
   4850  1.45   nonaka #endif
   4851   1.1    pooka 
   4852  1.45   nonaka static uint8_t
   4853  1.45   nonaka iwm_lmac_scan_fill_channels(struct iwm_softc *sc,
   4854  1.45   nonaka     struct iwm_scan_channel_cfg_lmac *chan, int n_ssids)
   4855   1.1    pooka {
   4856   1.1    pooka 	struct ieee80211com *ic = &sc->sc_ic;
   4857   1.1    pooka 	struct ieee80211_channel *c;
   4858  1.45   nonaka 	uint8_t nchan;
   4859   1.1    pooka 
   4860  1.45   nonaka 	for (nchan = 0, c = &ic->ic_channels[1];
   4861  1.45   nonaka 	    c <= &ic->ic_channels[IEEE80211_CHAN_MAX] &&
   4862  1.45   nonaka 	    nchan < sc->sc_capa_n_scan_channels;
   4863  1.45   nonaka 	    c++) {
   4864  1.45   nonaka 		if (c->ic_flags == 0)
   4865  1.45   nonaka 			continue;
   4866  1.45   nonaka 
   4867  1.45   nonaka 		chan->channel_num = htole16(ieee80211_mhz2ieee(c->ic_freq, 0));
   4868  1.45   nonaka 		chan->iter_count = htole16(1);
   4869  1.61   nonaka 		chan->iter_interval = htole32(0);
   4870  1.45   nonaka 		chan->flags = htole32(IWM_UNIFIED_SCAN_CHANNEL_PARTIAL);
   4871  1.61   nonaka 		chan->flags |= htole32(IWM_SCAN_CHANNEL_NSSIDS(n_ssids));
   4872  1.61   nonaka 		if (!IEEE80211_IS_CHAN_PASSIVE(c) && n_ssids != 0)
   4873  1.61   nonaka 			chan->flags |= htole32(IWM_SCAN_CHANNEL_TYPE_ACTIVE);
   4874  1.45   nonaka 		chan++;
   4875  1.45   nonaka 		nchan++;
   4876  1.45   nonaka 	}
   4877  1.45   nonaka 
   4878  1.45   nonaka 	return nchan;
   4879  1.45   nonaka }
   4880  1.45   nonaka 
   4881  1.45   nonaka static uint8_t
   4882  1.45   nonaka iwm_umac_scan_fill_channels(struct iwm_softc *sc,
   4883  1.45   nonaka     struct iwm_scan_channel_cfg_umac *chan, int n_ssids)
   4884  1.45   nonaka {
   4885  1.45   nonaka 	struct ieee80211com *ic = &sc->sc_ic;
   4886  1.45   nonaka 	struct ieee80211_channel *c;
   4887  1.45   nonaka 	uint8_t nchan;
   4888   1.1    pooka 
   4889   1.1    pooka 	for (nchan = 0, c = &ic->ic_channels[1];
   4890  1.45   nonaka 	    c <= &ic->ic_channels[IEEE80211_CHAN_MAX] &&
   4891  1.45   nonaka 	    nchan < sc->sc_capa_n_scan_channels;
   4892   1.1    pooka 	    c++) {
   4893  1.45   nonaka 		if (c->ic_flags == 0)
   4894   1.1    pooka 			continue;
   4895  1.61   nonaka 
   4896  1.45   nonaka 		chan->channel_num = ieee80211_mhz2ieee(c->ic_freq, 0);
   4897  1.45   nonaka 		chan->iter_count = 1;
   4898  1.45   nonaka 		chan->iter_interval = htole16(0);
   4899  1.61   nonaka 		chan->flags = htole32(IWM_SCAN_CHANNEL_UMAC_NSSIDS(n_ssids));
   4900   1.1    pooka 		chan++;
   4901   1.1    pooka 		nchan++;
   4902   1.1    pooka 	}
   4903  1.45   nonaka 
   4904   1.1    pooka 	return nchan;
   4905   1.1    pooka }
   4906   1.1    pooka 
   4907  1.45   nonaka static int
   4908  1.45   nonaka iwm_fill_probe_req(struct iwm_softc *sc, struct iwm_scan_probe_req *preq)
   4909  1.45   nonaka {
   4910  1.45   nonaka 	struct ieee80211com *ic = &sc->sc_ic;
   4911  1.45   nonaka 	struct ieee80211_frame *wh = (struct ieee80211_frame *)preq->buf;
   4912  1.45   nonaka 	struct ieee80211_rateset *rs;
   4913  1.45   nonaka 	size_t remain = sizeof(preq->buf);
   4914  1.45   nonaka 	uint8_t *frm, *pos;
   4915  1.45   nonaka 
   4916  1.45   nonaka 	memset(preq, 0, sizeof(*preq));
   4917  1.45   nonaka 
   4918  1.45   nonaka 	if (remain < sizeof(*wh) + 2 + ic->ic_des_esslen)
   4919  1.45   nonaka 		return ENOBUFS;
   4920   1.1    pooka 
   4921  1.45   nonaka 	/*
   4922  1.45   nonaka 	 * Build a probe request frame.  Most of the following code is a
   4923  1.45   nonaka 	 * copy & paste of what is done in net80211.
   4924  1.45   nonaka 	 */
   4925  1.45   nonaka 	wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT |
   4926   1.1    pooka 	    IEEE80211_FC0_SUBTYPE_PROBE_REQ;
   4927  1.45   nonaka 	wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
   4928  1.45   nonaka 	IEEE80211_ADDR_COPY(wh->i_addr1, etherbroadcastaddr);
   4929  1.45   nonaka 	IEEE80211_ADDR_COPY(wh->i_addr2, ic->ic_myaddr);
   4930  1.45   nonaka 	IEEE80211_ADDR_COPY(wh->i_addr3, etherbroadcastaddr);
   4931  1.45   nonaka 	*(uint16_t *)&wh->i_dur[0] = 0;	/* filled by HW */
   4932  1.45   nonaka 	*(uint16_t *)&wh->i_seq[0] = 0;	/* filled by HW */
   4933  1.45   nonaka 
   4934  1.45   nonaka 	frm = (uint8_t *)(wh + 1);
   4935  1.45   nonaka 	frm = ieee80211_add_ssid(frm, ic->ic_des_essid, ic->ic_des_esslen);
   4936  1.45   nonaka 
   4937  1.45   nonaka 	/* Tell the firmware where the MAC header is. */
   4938  1.45   nonaka 	preq->mac_header.offset = 0;
   4939  1.45   nonaka 	preq->mac_header.len = htole16(frm - (uint8_t *)wh);
   4940  1.45   nonaka 	remain -= frm - (uint8_t *)wh;
   4941  1.45   nonaka 
   4942  1.45   nonaka 	/* Fill in 2GHz IEs and tell firmware where they are. */
   4943  1.45   nonaka 	rs = &ic->ic_sup_rates[IEEE80211_MODE_11G];
   4944  1.45   nonaka 	if (rs->rs_nrates > IEEE80211_RATE_SIZE) {
   4945  1.45   nonaka 		if (remain < 4 + rs->rs_nrates)
   4946  1.45   nonaka 			return ENOBUFS;
   4947  1.45   nonaka 	} else if (remain < 2 + rs->rs_nrates)
   4948  1.45   nonaka 		return ENOBUFS;
   4949  1.45   nonaka 	preq->band_data[0].offset = htole16(frm - (uint8_t *)wh);
   4950  1.45   nonaka 	pos = frm;
   4951  1.45   nonaka 	frm = ieee80211_add_rates(frm, rs);
   4952  1.45   nonaka 	if (rs->rs_nrates > IEEE80211_RATE_SIZE)
   4953  1.45   nonaka 		frm = ieee80211_add_xrates(frm, rs);
   4954  1.45   nonaka 	preq->band_data[0].len = htole16(frm - pos);
   4955  1.45   nonaka 	remain -= frm - pos;
   4956  1.45   nonaka 
   4957  1.45   nonaka 	if (isset(sc->sc_enabled_capa,
   4958  1.45   nonaka 	    IWM_UCODE_TLV_CAPA_DS_PARAM_SET_IE_SUPPORT)) {
   4959  1.45   nonaka 		if (remain < 3)
   4960  1.45   nonaka 			return ENOBUFS;
   4961  1.45   nonaka 		*frm++ = IEEE80211_ELEMID_DSPARMS;
   4962  1.45   nonaka 		*frm++ = 1;
   4963  1.45   nonaka 		*frm++ = 0;
   4964  1.45   nonaka 		remain -= 3;
   4965  1.45   nonaka 	}
   4966  1.45   nonaka 
   4967  1.45   nonaka 	if (sc->sc_nvm.sku_cap_band_52GHz_enable) {
   4968  1.45   nonaka 		/* Fill in 5GHz IEs. */
   4969  1.45   nonaka 		rs = &ic->ic_sup_rates[IEEE80211_MODE_11A];
   4970  1.45   nonaka 		if (rs->rs_nrates > IEEE80211_RATE_SIZE) {
   4971  1.45   nonaka 			if (remain < 4 + rs->rs_nrates)
   4972  1.45   nonaka 				return ENOBUFS;
   4973  1.45   nonaka 		} else if (remain < 2 + rs->rs_nrates)
   4974  1.45   nonaka 			return ENOBUFS;
   4975  1.45   nonaka 		preq->band_data[1].offset = htole16(frm - (uint8_t *)wh);
   4976  1.45   nonaka 		pos = frm;
   4977  1.45   nonaka 		frm = ieee80211_add_rates(frm, rs);
   4978  1.45   nonaka 		if (rs->rs_nrates > IEEE80211_RATE_SIZE)
   4979  1.45   nonaka 			frm = ieee80211_add_xrates(frm, rs);
   4980  1.45   nonaka 		preq->band_data[1].len = htole16(frm - pos);
   4981  1.45   nonaka 		remain -= frm - pos;
   4982  1.45   nonaka 	}
   4983  1.45   nonaka 
   4984  1.45   nonaka #ifndef IEEE80211_NO_HT
   4985  1.45   nonaka 	/* Send 11n IEs on both 2GHz and 5GHz bands. */
   4986  1.45   nonaka 	preq->common_data.offset = htole16(frm - (uint8_t *)wh);
   4987  1.45   nonaka 	pos = frm;
   4988  1.45   nonaka 	if (ic->ic_flags & IEEE80211_F_HTON) {
   4989  1.45   nonaka 		if (remain < 28)
   4990  1.45   nonaka 			return ENOBUFS;
   4991  1.45   nonaka 		frm = ieee80211_add_htcaps(frm, ic);
   4992  1.45   nonaka 		/* XXX add WME info? */
   4993  1.45   nonaka 	}
   4994  1.45   nonaka #endif
   4995  1.45   nonaka 
   4996  1.45   nonaka 	preq->common_data.len = htole16(frm - pos);
   4997  1.45   nonaka 
   4998  1.45   nonaka 	return 0;
   4999  1.45   nonaka }
   5000  1.45   nonaka 
   5001  1.45   nonaka static int
   5002  1.45   nonaka iwm_lmac_scan(struct iwm_softc *sc)
   5003  1.45   nonaka {
   5004  1.45   nonaka 	struct ieee80211com *ic = &sc->sc_ic;
   5005  1.45   nonaka 	struct iwm_host_cmd hcmd = {
   5006  1.45   nonaka 		.id = IWM_SCAN_OFFLOAD_REQUEST_CMD,
   5007  1.45   nonaka 		.len = { 0, },
   5008  1.45   nonaka 		.data = { NULL, },
   5009  1.45   nonaka 		.flags = 0,
   5010  1.45   nonaka 	};
   5011  1.45   nonaka 	struct iwm_scan_req_lmac *req;
   5012  1.45   nonaka 	size_t req_len;
   5013  1.45   nonaka 	int err;
   5014  1.45   nonaka 
   5015  1.45   nonaka 	DPRINTF(("%s: %s\n", DEVNAME(sc), __func__));
   5016  1.45   nonaka 
   5017  1.45   nonaka 	req_len = sizeof(struct iwm_scan_req_lmac) +
   5018  1.45   nonaka 	    (sizeof(struct iwm_scan_channel_cfg_lmac) *
   5019  1.45   nonaka 	    sc->sc_capa_n_scan_channels) + sizeof(struct iwm_scan_probe_req);
   5020  1.45   nonaka 	if (req_len > IWM_MAX_CMD_PAYLOAD_SIZE)
   5021  1.45   nonaka 		return ENOMEM;
   5022  1.45   nonaka 	req = kmem_zalloc(req_len, KM_SLEEP);
   5023  1.45   nonaka 	if (req == NULL)
   5024  1.45   nonaka 		return ENOMEM;
   5025  1.45   nonaka 
   5026  1.45   nonaka 	hcmd.len[0] = (uint16_t)req_len;
   5027  1.45   nonaka 	hcmd.data[0] = (void *)req;
   5028  1.45   nonaka 
   5029  1.45   nonaka 	/* These timings correspond to iwlwifi's UNASSOC scan. */
   5030  1.45   nonaka 	req->active_dwell = 10;
   5031  1.45   nonaka 	req->passive_dwell = 110;
   5032  1.45   nonaka 	req->fragmented_dwell = 44;
   5033  1.45   nonaka 	req->extended_dwell = 90;
   5034  1.45   nonaka 	req->max_out_time = 0;
   5035  1.45   nonaka 	req->suspend_time = 0;
   5036  1.45   nonaka 
   5037  1.45   nonaka 	req->scan_prio = htole32(IWM_SCAN_PRIORITY_HIGH);
   5038  1.45   nonaka 	req->rx_chain_select = iwm_scan_rx_chain(sc);
   5039  1.45   nonaka 	req->iter_num = htole32(1);
   5040  1.45   nonaka 	req->delay = 0;
   5041  1.45   nonaka 
   5042  1.45   nonaka 	req->scan_flags = htole32(IWM_LMAC_SCAN_FLAG_PASS_ALL |
   5043  1.45   nonaka 	    IWM_LMAC_SCAN_FLAG_ITER_COMPLETE |
   5044  1.45   nonaka 	    IWM_LMAC_SCAN_FLAG_EXTENDED_DWELL);
   5045  1.45   nonaka 	if (ic->ic_des_esslen == 0)
   5046  1.45   nonaka 		req->scan_flags |= htole32(IWM_LMAC_SCAN_FLAG_PASSIVE);
   5047  1.45   nonaka 	else
   5048  1.45   nonaka 		req->scan_flags |= htole32(IWM_LMAC_SCAN_FLAG_PRE_CONNECTION);
   5049  1.45   nonaka 	if (isset(sc->sc_enabled_capa,
   5050  1.45   nonaka 	    IWM_UCODE_TLV_CAPA_DS_PARAM_SET_IE_SUPPORT))
   5051  1.45   nonaka 		req->scan_flags |= htole32(IWM_LMAC_SCAN_FLAGS_RRM_ENABLED);
   5052  1.45   nonaka 
   5053  1.45   nonaka 	req->flags = htole32(IWM_PHY_BAND_24);
   5054  1.45   nonaka 	if (sc->sc_nvm.sku_cap_band_52GHz_enable)
   5055  1.45   nonaka 		req->flags |= htole32(IWM_PHY_BAND_5);
   5056  1.45   nonaka 	req->filter_flags =
   5057  1.45   nonaka 	    htole32(IWM_MAC_FILTER_ACCEPT_GRP | IWM_MAC_FILTER_IN_BEACON);
   5058  1.45   nonaka 
   5059  1.45   nonaka 	/* Tx flags 2 GHz. */
   5060  1.45   nonaka 	req->tx_cmd[0].tx_flags = htole32(IWM_TX_CMD_FLG_SEQ_CTL |
   5061  1.45   nonaka 	    IWM_TX_CMD_FLG_BT_DIS);
   5062  1.45   nonaka 	req->tx_cmd[0].rate_n_flags =
   5063  1.45   nonaka 	    iwm_scan_rate_n_flags(sc, IEEE80211_CHAN_2GHZ, 1/*XXX*/);
   5064  1.45   nonaka 	req->tx_cmd[0].sta_id = IWM_AUX_STA_ID;
   5065  1.45   nonaka 
   5066  1.45   nonaka 	/* Tx flags 5 GHz. */
   5067  1.45   nonaka 	req->tx_cmd[1].tx_flags = htole32(IWM_TX_CMD_FLG_SEQ_CTL |
   5068  1.45   nonaka 	    IWM_TX_CMD_FLG_BT_DIS);
   5069  1.45   nonaka 	req->tx_cmd[1].rate_n_flags =
   5070  1.45   nonaka 	    iwm_scan_rate_n_flags(sc, IEEE80211_CHAN_5GHZ, 1/*XXX*/);
   5071  1.45   nonaka 	req->tx_cmd[1].sta_id = IWM_AUX_STA_ID;
   5072  1.45   nonaka 
   5073  1.45   nonaka 	/* Check if we're doing an active directed scan. */
   5074  1.45   nonaka 	if (ic->ic_des_esslen != 0) {
   5075  1.45   nonaka 		req->direct_scan[0].id = IEEE80211_ELEMID_SSID;
   5076  1.45   nonaka 		req->direct_scan[0].len = ic->ic_des_esslen;
   5077  1.45   nonaka 		memcpy(req->direct_scan[0].ssid, ic->ic_des_essid,
   5078  1.45   nonaka 		    ic->ic_des_esslen);
   5079  1.45   nonaka 	}
   5080  1.45   nonaka 
   5081  1.45   nonaka 	req->n_channels = iwm_lmac_scan_fill_channels(sc,
   5082  1.45   nonaka 	    (struct iwm_scan_channel_cfg_lmac *)req->data,
   5083  1.45   nonaka 	    ic->ic_des_esslen != 0);
   5084  1.45   nonaka 
   5085  1.45   nonaka 	err = iwm_fill_probe_req(sc,
   5086  1.45   nonaka 	    (struct iwm_scan_probe_req *)(req->data +
   5087  1.45   nonaka 	    (sizeof(struct iwm_scan_channel_cfg_lmac) *
   5088  1.45   nonaka 	     sc->sc_capa_n_scan_channels)));
   5089  1.45   nonaka 	if (err) {
   5090  1.45   nonaka 		kmem_free(req, req_len);
   5091  1.45   nonaka 		return err;
   5092   1.1    pooka 	}
   5093   1.1    pooka 
   5094  1.45   nonaka 	/* Specify the scan plan: We'll do one iteration. */
   5095  1.45   nonaka 	req->schedule[0].iterations = 1;
   5096  1.45   nonaka 	req->schedule[0].full_scan_mul = 1;
   5097   1.1    pooka 
   5098  1.45   nonaka 	/* Disable EBS. */
   5099  1.45   nonaka 	req->channel_opt[0].non_ebs_ratio = 1;
   5100  1.45   nonaka 	req->channel_opt[1].non_ebs_ratio = 1;
   5101   1.1    pooka 
   5102  1.45   nonaka 	err = iwm_send_cmd(sc, &hcmd);
   5103  1.45   nonaka 	kmem_free(req, req_len);
   5104  1.45   nonaka 	return err;
   5105  1.45   nonaka }
   5106  1.45   nonaka 
   5107  1.45   nonaka static int
   5108  1.45   nonaka iwm_config_umac_scan(struct iwm_softc *sc)
   5109  1.45   nonaka {
   5110  1.45   nonaka 	struct ieee80211com *ic = &sc->sc_ic;
   5111  1.45   nonaka 	struct iwm_scan_config *scan_config;
   5112  1.45   nonaka 	int err, nchan;
   5113  1.45   nonaka 	size_t cmd_size;
   5114  1.45   nonaka 	struct ieee80211_channel *c;
   5115  1.45   nonaka 	struct iwm_host_cmd hcmd = {
   5116  1.45   nonaka 		.id = iwm_cmd_id(IWM_SCAN_CFG_CMD, IWM_ALWAYS_LONG_GROUP, 0),
   5117  1.45   nonaka 		.flags = 0,
   5118  1.45   nonaka 	};
   5119  1.45   nonaka 	static const uint32_t rates = (IWM_SCAN_CONFIG_RATE_1M |
   5120  1.45   nonaka 	    IWM_SCAN_CONFIG_RATE_2M | IWM_SCAN_CONFIG_RATE_5M |
   5121  1.45   nonaka 	    IWM_SCAN_CONFIG_RATE_11M | IWM_SCAN_CONFIG_RATE_6M |
   5122  1.45   nonaka 	    IWM_SCAN_CONFIG_RATE_9M | IWM_SCAN_CONFIG_RATE_12M |
   5123  1.45   nonaka 	    IWM_SCAN_CONFIG_RATE_18M | IWM_SCAN_CONFIG_RATE_24M |
   5124  1.45   nonaka 	    IWM_SCAN_CONFIG_RATE_36M | IWM_SCAN_CONFIG_RATE_48M |
   5125  1.45   nonaka 	    IWM_SCAN_CONFIG_RATE_54M);
   5126  1.45   nonaka 
   5127  1.45   nonaka 	cmd_size = sizeof(*scan_config) + sc->sc_capa_n_scan_channels;
   5128  1.45   nonaka 
   5129  1.45   nonaka 	scan_config = kmem_zalloc(cmd_size, KM_SLEEP);
   5130  1.45   nonaka 	if (scan_config == NULL)
   5131  1.45   nonaka 		return ENOMEM;
   5132  1.45   nonaka 
   5133  1.45   nonaka 	scan_config->tx_chains = htole32(iwm_fw_valid_tx_ant(sc));
   5134  1.45   nonaka 	scan_config->rx_chains = htole32(iwm_fw_valid_rx_ant(sc));
   5135  1.45   nonaka 	scan_config->legacy_rates = htole32(rates |
   5136  1.45   nonaka 	    IWM_SCAN_CONFIG_SUPPORTED_RATE(rates));
   5137  1.45   nonaka 
   5138  1.45   nonaka 	/* These timings correspond to iwlwifi's UNASSOC scan. */
   5139  1.45   nonaka 	scan_config->dwell_active = 10;
   5140  1.45   nonaka 	scan_config->dwell_passive = 110;
   5141  1.45   nonaka 	scan_config->dwell_fragmented = 44;
   5142  1.45   nonaka 	scan_config->dwell_extended = 90;
   5143  1.45   nonaka 	scan_config->out_of_channel_time = htole32(0);
   5144  1.45   nonaka 	scan_config->suspend_time = htole32(0);
   5145  1.45   nonaka 
   5146  1.45   nonaka 	IEEE80211_ADDR_COPY(scan_config->mac_addr, sc->sc_ic.ic_myaddr);
   5147  1.45   nonaka 
   5148  1.45   nonaka 	scan_config->bcast_sta_id = IWM_AUX_STA_ID;
   5149  1.45   nonaka 	scan_config->channel_flags = IWM_CHANNEL_FLAG_EBS |
   5150  1.45   nonaka 	    IWM_CHANNEL_FLAG_ACCURATE_EBS | IWM_CHANNEL_FLAG_EBS_ADD |
   5151  1.45   nonaka 	    IWM_CHANNEL_FLAG_PRE_SCAN_PASSIVE2ACTIVE;
   5152  1.45   nonaka 
   5153  1.45   nonaka 	for (c = &ic->ic_channels[1], nchan = 0;
   5154  1.45   nonaka 	    c <= &ic->ic_channels[IEEE80211_CHAN_MAX] &&
   5155  1.45   nonaka 	    nchan < sc->sc_capa_n_scan_channels; c++) {
   5156  1.45   nonaka 		if (c->ic_flags == 0)
   5157  1.45   nonaka 			continue;
   5158  1.45   nonaka 		scan_config->channel_array[nchan++] =
   5159  1.45   nonaka 		    ieee80211_mhz2ieee(c->ic_freq, 0);
   5160   1.1    pooka 	}
   5161   1.1    pooka 
   5162  1.45   nonaka 	scan_config->flags = htole32(IWM_SCAN_CONFIG_FLAG_ACTIVATE |
   5163  1.45   nonaka 	    IWM_SCAN_CONFIG_FLAG_ALLOW_CHUB_REQS |
   5164  1.45   nonaka 	    IWM_SCAN_CONFIG_FLAG_SET_TX_CHAINS |
   5165  1.45   nonaka 	    IWM_SCAN_CONFIG_FLAG_SET_RX_CHAINS |
   5166  1.45   nonaka 	    IWM_SCAN_CONFIG_FLAG_SET_AUX_STA_ID |
   5167  1.45   nonaka 	    IWM_SCAN_CONFIG_FLAG_SET_ALL_TIMES |
   5168  1.45   nonaka 	    IWM_SCAN_CONFIG_FLAG_SET_LEGACY_RATES |
   5169  1.45   nonaka 	    IWM_SCAN_CONFIG_FLAG_SET_MAC_ADDR |
   5170  1.45   nonaka 	    IWM_SCAN_CONFIG_FLAG_SET_CHANNEL_FLAGS|
   5171  1.45   nonaka 	    IWM_SCAN_CONFIG_N_CHANNELS(nchan) |
   5172  1.45   nonaka 	    IWM_SCAN_CONFIG_FLAG_CLEAR_FRAGMENTED);
   5173  1.45   nonaka 
   5174  1.45   nonaka 	hcmd.data[0] = scan_config;
   5175  1.45   nonaka 	hcmd.len[0] = cmd_size;
   5176  1.45   nonaka 
   5177  1.45   nonaka 	err = iwm_send_cmd(sc, &hcmd);
   5178  1.45   nonaka 	kmem_free(scan_config, cmd_size);
   5179  1.45   nonaka 	return err;
   5180   1.1    pooka }
   5181   1.1    pooka 
   5182   1.4   nonaka static int
   5183  1.45   nonaka iwm_umac_scan(struct iwm_softc *sc)
   5184   1.1    pooka {
   5185   1.1    pooka 	struct ieee80211com *ic = &sc->sc_ic;
   5186   1.1    pooka 	struct iwm_host_cmd hcmd = {
   5187  1.45   nonaka 		.id = iwm_cmd_id(IWM_SCAN_REQ_UMAC, IWM_ALWAYS_LONG_GROUP, 0),
   5188   1.1    pooka 		.len = { 0, },
   5189  1.45   nonaka 		.data = { NULL, },
   5190  1.45   nonaka 		.flags = 0,
   5191   1.1    pooka 	};
   5192  1.45   nonaka 	struct iwm_scan_req_umac *req;
   5193  1.45   nonaka 	struct iwm_scan_req_umac_tail *tail;
   5194  1.45   nonaka 	size_t req_len;
   5195  1.45   nonaka 	int err;
   5196   1.1    pooka 
   5197  1.45   nonaka 	DPRINTF(("%s: %s\n", DEVNAME(sc), __func__));
   5198   1.1    pooka 
   5199  1.45   nonaka 	req_len = sizeof(struct iwm_scan_req_umac) +
   5200  1.45   nonaka 	    (sizeof(struct iwm_scan_channel_cfg_umac) *
   5201  1.45   nonaka 	    sc->sc_capa_n_scan_channels) +
   5202  1.45   nonaka 	    sizeof(struct iwm_scan_req_umac_tail);
   5203  1.45   nonaka 	if (req_len > IWM_MAX_CMD_PAYLOAD_SIZE)
   5204  1.45   nonaka 		return ENOMEM;
   5205  1.45   nonaka 	req = kmem_zalloc(req_len, KM_SLEEP);
   5206  1.45   nonaka 	if (req == NULL)
   5207  1.45   nonaka 		return ENOMEM;
   5208   1.1    pooka 
   5209  1.45   nonaka 	hcmd.len[0] = (uint16_t)req_len;
   5210  1.45   nonaka 	hcmd.data[0] = (void *)req;
   5211   1.1    pooka 
   5212  1.45   nonaka 	/* These timings correspond to iwlwifi's UNASSOC scan. */
   5213  1.45   nonaka 	req->active_dwell = 10;
   5214  1.45   nonaka 	req->passive_dwell = 110;
   5215  1.45   nonaka 	req->fragmented_dwell = 44;
   5216  1.45   nonaka 	req->extended_dwell = 90;
   5217  1.45   nonaka 	req->max_out_time = 0;
   5218  1.45   nonaka 	req->suspend_time = 0;
   5219  1.45   nonaka 
   5220  1.45   nonaka 	req->scan_priority = htole32(IWM_SCAN_PRIORITY_HIGH);
   5221  1.45   nonaka 	req->ooc_priority = htole32(IWM_SCAN_PRIORITY_HIGH);
   5222  1.45   nonaka 
   5223  1.45   nonaka 	req->n_channels = iwm_umac_scan_fill_channels(sc,
   5224  1.45   nonaka 	    (struct iwm_scan_channel_cfg_umac *)req->data,
   5225  1.45   nonaka 	    ic->ic_des_esslen != 0);
   5226  1.45   nonaka 
   5227  1.45   nonaka 	req->general_flags = htole32(IWM_UMAC_SCAN_GEN_FLAGS_PASS_ALL |
   5228  1.45   nonaka 	    IWM_UMAC_SCAN_GEN_FLAGS_ITER_COMPLETE |
   5229  1.45   nonaka 	    IWM_UMAC_SCAN_GEN_FLAGS_EXTENDED_DWELL);
   5230  1.45   nonaka 
   5231  1.45   nonaka 	tail = (struct iwm_scan_req_umac_tail *)(req->data +
   5232  1.45   nonaka 		sizeof(struct iwm_scan_channel_cfg_umac) *
   5233  1.45   nonaka 			sc->sc_capa_n_scan_channels);
   5234  1.45   nonaka 
   5235  1.45   nonaka 	/* Check if we're doing an active directed scan. */
   5236  1.45   nonaka 	if (ic->ic_des_esslen != 0) {
   5237  1.45   nonaka 		tail->direct_scan[0].id = IEEE80211_ELEMID_SSID;
   5238  1.45   nonaka 		tail->direct_scan[0].len = ic->ic_des_esslen;
   5239  1.45   nonaka 		memcpy(tail->direct_scan[0].ssid, ic->ic_des_essid,
   5240  1.45   nonaka 		    ic->ic_des_esslen);
   5241  1.45   nonaka 		req->general_flags |=
   5242  1.45   nonaka 		    htole32(IWM_UMAC_SCAN_GEN_FLAGS_PRE_CONNECT);
   5243  1.45   nonaka 	} else
   5244  1.45   nonaka 		req->general_flags |= htole32(IWM_UMAC_SCAN_GEN_FLAGS_PASSIVE);
   5245   1.1    pooka 
   5246  1.45   nonaka 	if (isset(sc->sc_enabled_capa,
   5247  1.45   nonaka 	    IWM_UCODE_TLV_CAPA_DS_PARAM_SET_IE_SUPPORT))
   5248  1.45   nonaka 		req->general_flags |=
   5249  1.45   nonaka 		    htole32(IWM_UMAC_SCAN_GEN_FLAGS_RRM_ENABLED);
   5250   1.1    pooka 
   5251  1.45   nonaka 	err = iwm_fill_probe_req(sc, &tail->preq);
   5252  1.45   nonaka 	if (err) {
   5253  1.45   nonaka 		kmem_free(req, req_len);
   5254  1.45   nonaka 		return err;
   5255   1.1    pooka 	}
   5256   1.1    pooka 
   5257  1.45   nonaka 	/* Specify the scan plan: We'll do one iteration. */
   5258  1.45   nonaka 	tail->schedule[0].interval = 0;
   5259  1.45   nonaka 	tail->schedule[0].iter_count = 1;
   5260  1.45   nonaka 
   5261  1.45   nonaka 	err = iwm_send_cmd(sc, &hcmd);
   5262  1.45   nonaka 	kmem_free(req, req_len);
   5263  1.45   nonaka 	return err;
   5264   1.1    pooka }
   5265   1.1    pooka 
   5266  1.45   nonaka static uint8_t
   5267  1.45   nonaka iwm_ridx2rate(struct ieee80211_rateset *rs, int ridx)
   5268  1.45   nonaka {
   5269  1.45   nonaka 	int i;
   5270  1.45   nonaka 	uint8_t rval;
   5271   1.1    pooka 
   5272  1.45   nonaka 	for (i = 0; i < rs->rs_nrates; i++) {
   5273  1.45   nonaka 		rval = (rs->rs_rates[i] & IEEE80211_RATE_VAL);
   5274  1.45   nonaka 		if (rval == iwm_rates[ridx].rate)
   5275  1.45   nonaka 			return rs->rs_rates[i];
   5276  1.45   nonaka 	}
   5277  1.45   nonaka 	return 0;
   5278  1.45   nonaka }
   5279   1.1    pooka 
   5280   1.4   nonaka static void
   5281  1.45   nonaka iwm_ack_rates(struct iwm_softc *sc, struct iwm_node *in, int *cck_rates,
   5282  1.45   nonaka     int *ofdm_rates)
   5283   1.1    pooka {
   5284  1.24   nonaka 	struct ieee80211_node *ni = &in->in_ni;
   5285  1.45   nonaka 	struct ieee80211_rateset *rs = &ni->ni_rates;
   5286  1.56   nonaka 	int lowest_present_ofdm = -1;
   5287  1.56   nonaka 	int lowest_present_cck = -1;
   5288   1.1    pooka 	uint8_t cck = 0;
   5289   1.1    pooka 	uint8_t ofdm = 0;
   5290   1.1    pooka 	int i;
   5291   1.1    pooka 
   5292  1.45   nonaka 	if (ni->ni_chan == IEEE80211_CHAN_ANYC ||
   5293  1.45   nonaka 	    IEEE80211_IS_CHAN_2GHZ(ni->ni_chan)) {
   5294  1.45   nonaka 		for (i = IWM_FIRST_CCK_RATE; i < IWM_FIRST_OFDM_RATE; i++) {
   5295  1.45   nonaka 			if ((iwm_ridx2rate(rs, i) & IEEE80211_RATE_BASIC) == 0)
   5296  1.45   nonaka 				continue;
   5297  1.24   nonaka 			cck |= (1 << i);
   5298  1.56   nonaka 			if (lowest_present_cck == -1 || lowest_present_cck > i)
   5299  1.24   nonaka 				lowest_present_cck = i;
   5300  1.24   nonaka 		}
   5301   1.1    pooka 	}
   5302   1.1    pooka 	for (i = IWM_FIRST_OFDM_RATE; i <= IWM_LAST_NON_HT_RATE; i++) {
   5303  1.45   nonaka 		if ((iwm_ridx2rate(rs, i) & IEEE80211_RATE_BASIC) == 0)
   5304  1.45   nonaka 			continue;
   5305  1.45   nonaka 		ofdm |= (1 << (i - IWM_FIRST_OFDM_RATE));
   5306  1.56   nonaka 		if (lowest_present_ofdm == -1 || lowest_present_ofdm > i)
   5307  1.20   nonaka 			lowest_present_ofdm = i;
   5308   1.1    pooka 	}
   5309   1.1    pooka 
   5310   1.1    pooka 	/*
   5311   1.1    pooka 	 * Now we've got the basic rates as bitmaps in the ofdm and cck
   5312   1.1    pooka 	 * variables. This isn't sufficient though, as there might not
   5313   1.1    pooka 	 * be all the right rates in the bitmap. E.g. if the only basic
   5314   1.1    pooka 	 * rates are 5.5 Mbps and 11 Mbps, we still need to add 1 Mbps
   5315   1.1    pooka 	 * and 6 Mbps because the 802.11-2007 standard says in 9.6:
   5316   1.1    pooka 	 *
   5317   1.1    pooka 	 *    [...] a STA responding to a received frame shall transmit
   5318   1.1    pooka 	 *    its Control Response frame [...] at the highest rate in the
   5319   1.1    pooka 	 *    BSSBasicRateSet parameter that is less than or equal to the
   5320   1.1    pooka 	 *    rate of the immediately previous frame in the frame exchange
   5321   1.1    pooka 	 *    sequence ([...]) and that is of the same modulation class
   5322   1.1    pooka 	 *    ([...]) as the received frame. If no rate contained in the
   5323   1.1    pooka 	 *    BSSBasicRateSet parameter meets these conditions, then the
   5324   1.1    pooka 	 *    control frame sent in response to a received frame shall be
   5325   1.1    pooka 	 *    transmitted at the highest mandatory rate of the PHY that is
   5326   1.1    pooka 	 *    less than or equal to the rate of the received frame, and
   5327   1.1    pooka 	 *    that is of the same modulation class as the received frame.
   5328   1.1    pooka 	 *
   5329   1.1    pooka 	 * As a consequence, we need to add all mandatory rates that are
   5330   1.1    pooka 	 * lower than all of the basic rates to these bitmaps.
   5331   1.1    pooka 	 */
   5332   1.1    pooka 
   5333   1.1    pooka 	if (IWM_RATE_24M_INDEX < lowest_present_ofdm)
   5334   1.1    pooka 		ofdm |= IWM_RATE_BIT_MSK(24) >> IWM_FIRST_OFDM_RATE;
   5335   1.1    pooka 	if (IWM_RATE_12M_INDEX < lowest_present_ofdm)
   5336   1.1    pooka 		ofdm |= IWM_RATE_BIT_MSK(12) >> IWM_FIRST_OFDM_RATE;
   5337   1.1    pooka 	/* 6M already there or needed so always add */
   5338   1.1    pooka 	ofdm |= IWM_RATE_BIT_MSK(6) >> IWM_FIRST_OFDM_RATE;
   5339   1.1    pooka 
   5340   1.1    pooka 	/*
   5341   1.1    pooka 	 * CCK is a bit more complex with DSSS vs. HR/DSSS vs. ERP.
   5342   1.1    pooka 	 * Note, however:
   5343   1.1    pooka 	 *  - if no CCK rates are basic, it must be ERP since there must
   5344   1.1    pooka 	 *    be some basic rates at all, so they're OFDM => ERP PHY
   5345   1.1    pooka 	 *    (or we're in 5 GHz, and the cck bitmap will never be used)
   5346   1.1    pooka 	 *  - if 11M is a basic rate, it must be ERP as well, so add 5.5M
   5347   1.1    pooka 	 *  - if 5.5M is basic, 1M and 2M are mandatory
   5348   1.1    pooka 	 *  - if 2M is basic, 1M is mandatory
   5349   1.1    pooka 	 *  - if 1M is basic, that's the only valid ACK rate.
   5350   1.1    pooka 	 * As a consequence, it's not as complicated as it sounds, just add
   5351   1.1    pooka 	 * any lower rates to the ACK rate bitmap.
   5352   1.1    pooka 	 */
   5353   1.1    pooka 	if (IWM_RATE_11M_INDEX < lowest_present_cck)
   5354   1.1    pooka 		cck |= IWM_RATE_BIT_MSK(11) >> IWM_FIRST_CCK_RATE;
   5355   1.1    pooka 	if (IWM_RATE_5M_INDEX < lowest_present_cck)
   5356   1.1    pooka 		cck |= IWM_RATE_BIT_MSK(5) >> IWM_FIRST_CCK_RATE;
   5357   1.1    pooka 	if (IWM_RATE_2M_INDEX < lowest_present_cck)
   5358   1.1    pooka 		cck |= IWM_RATE_BIT_MSK(2) >> IWM_FIRST_CCK_RATE;
   5359   1.1    pooka 	/* 1M already there or needed so always add */
   5360   1.1    pooka 	cck |= IWM_RATE_BIT_MSK(1) >> IWM_FIRST_CCK_RATE;
   5361   1.1    pooka 
   5362   1.1    pooka 	*cck_rates = cck;
   5363   1.1    pooka 	*ofdm_rates = ofdm;
   5364   1.1    pooka }
   5365   1.1    pooka 
   5366   1.4   nonaka static void
   5367  1.45   nonaka iwm_mac_ctxt_cmd_common(struct iwm_softc *sc, struct iwm_node *in,
   5368  1.45   nonaka     struct iwm_mac_ctx_cmd *cmd, uint32_t action, int assoc)
   5369   1.1    pooka {
   5370  1.45   nonaka #define IWM_EXP2(x)	((1 << (x)) - 1)	/* CWmin = 2^ECWmin - 1 */
   5371   1.1    pooka 	struct ieee80211com *ic = &sc->sc_ic;
   5372   1.1    pooka 	struct ieee80211_node *ni = ic->ic_bss;
   5373   1.1    pooka 	int cck_ack_rates, ofdm_ack_rates;
   5374   1.1    pooka 	int i;
   5375   1.1    pooka 
   5376   1.1    pooka 	cmd->id_and_color = htole32(IWM_FW_CMD_ID_AND_COLOR(in->in_id,
   5377   1.1    pooka 	    in->in_color));
   5378   1.1    pooka 	cmd->action = htole32(action);
   5379   1.1    pooka 
   5380   1.1    pooka 	cmd->mac_type = htole32(IWM_FW_MAC_TYPE_BSS_STA);
   5381  1.45   nonaka 	cmd->tsf_id = htole32(IWM_TSF_ID_A);
   5382   1.1    pooka 
   5383   1.1    pooka 	IEEE80211_ADDR_COPY(cmd->node_addr, ic->ic_myaddr);
   5384  1.45   nonaka 	IEEE80211_ADDR_COPY(cmd->bssid_addr, ni->ni_bssid);
   5385  1.45   nonaka 
   5386  1.45   nonaka 	iwm_ack_rates(sc, in, &cck_ack_rates, &ofdm_ack_rates);
   5387   1.1    pooka 	cmd->cck_rates = htole32(cck_ack_rates);
   5388   1.1    pooka 	cmd->ofdm_rates = htole32(ofdm_ack_rates);
   5389   1.1    pooka 
   5390   1.1    pooka 	cmd->cck_short_preamble
   5391   1.1    pooka 	    = htole32((ic->ic_flags & IEEE80211_F_SHPREAMBLE)
   5392   1.1    pooka 	      ? IWM_MAC_FLG_SHORT_PREAMBLE : 0);
   5393   1.1    pooka 	cmd->short_slot
   5394   1.1    pooka 	    = htole32((ic->ic_flags & IEEE80211_F_SHSLOT)
   5395   1.1    pooka 	      ? IWM_MAC_FLG_SHORT_SLOT : 0);
   5396   1.1    pooka 
   5397  1.45   nonaka 	for (i = 0; i < WME_NUM_AC; i++) {
   5398  1.45   nonaka 		struct wmeParams *wmep = &ic->ic_wme.wme_params[i];
   5399  1.45   nonaka 		int txf = iwm_ac_to_tx_fifo[i];
   5400  1.45   nonaka 
   5401  1.45   nonaka 		cmd->ac[txf].cw_min = htole16(IWM_EXP2(wmep->wmep_logcwmin));
   5402  1.45   nonaka 		cmd->ac[txf].cw_max = htole16(IWM_EXP2(wmep->wmep_logcwmax));
   5403  1.45   nonaka 		cmd->ac[txf].aifsn = wmep->wmep_aifsn;
   5404   1.1    pooka 		cmd->ac[txf].fifos_mask = (1 << txf);
   5405  1.45   nonaka 		cmd->ac[txf].edca_txop = htole16(wmep->wmep_txopLimit * 32);
   5406   1.1    pooka 	}
   5407  1.45   nonaka 	if (ni->ni_flags & IEEE80211_NODE_QOS)
   5408  1.45   nonaka 		cmd->qos_flags |= htole32(IWM_MAC_QOS_FLG_UPDATE_EDCA);
   5409   1.1    pooka 
   5410  1.45   nonaka #ifndef IEEE80211_NO_HT
   5411  1.45   nonaka 	if (ni->ni_flags & IEEE80211_NODE_HT) {
   5412  1.45   nonaka 		enum ieee80211_htprot htprot =
   5413  1.45   nonaka 		    (ni->ni_htop1 & IEEE80211_HTOP1_PROT_MASK);
   5414  1.45   nonaka 		switch (htprot) {
   5415  1.45   nonaka 		case IEEE80211_HTPROT_NONE:
   5416  1.45   nonaka 			break;
   5417  1.45   nonaka 		case IEEE80211_HTPROT_NONMEMBER:
   5418  1.45   nonaka 		case IEEE80211_HTPROT_NONHT_MIXED:
   5419  1.45   nonaka 			cmd->protection_flags |=
   5420  1.45   nonaka 			    htole32(IWM_MAC_PROT_FLG_HT_PROT);
   5421  1.45   nonaka 		case IEEE80211_HTPROT_20MHZ:
   5422  1.45   nonaka 			cmd->protection_flags |=
   5423  1.45   nonaka 			    htole32(IWM_MAC_PROT_FLG_HT_PROT |
   5424  1.45   nonaka 			    IWM_MAC_PROT_FLG_FAT_PROT);
   5425  1.45   nonaka 			break;
   5426  1.45   nonaka 		default:
   5427  1.45   nonaka 			break;
   5428  1.45   nonaka 		}
   5429   1.1    pooka 
   5430  1.45   nonaka 		cmd->qos_flags |= htole32(IWM_MAC_QOS_FLG_TGN);
   5431   1.1    pooka 	}
   5432  1.45   nonaka #endif
   5433   1.1    pooka 
   5434  1.45   nonaka 	if (ic->ic_flags & IEEE80211_F_USEPROT)
   5435  1.45   nonaka 		cmd->protection_flags |= htole32(IWM_MAC_PROT_FLG_TGG_PROTECT);
   5436   1.1    pooka 
   5437  1.45   nonaka 	cmd->filter_flags = htole32(IWM_MAC_FILTER_ACCEPT_GRP);
   5438  1.45   nonaka #undef IWM_EXP2
   5439   1.1    pooka }
   5440   1.1    pooka 
   5441  1.45   nonaka static void
   5442  1.45   nonaka iwm_mac_ctxt_cmd_fill_sta(struct iwm_softc *sc, struct iwm_node *in,
   5443  1.45   nonaka     struct iwm_mac_data_sta *sta, int assoc)
   5444   1.1    pooka {
   5445  1.45   nonaka 	struct ieee80211_node *ni = &in->in_ni;
   5446  1.45   nonaka 	uint32_t dtim_off;
   5447  1.45   nonaka 	uint64_t tsf;
   5448   1.1    pooka 
   5449  1.45   nonaka 	dtim_off = ni->ni_dtim_count * ni->ni_intval * IEEE80211_DUR_TU;
   5450  1.45   nonaka 	tsf = le64toh(ni->ni_tstamp.tsf);
   5451   1.1    pooka 
   5452  1.45   nonaka 	sta->is_assoc = htole32(assoc);
   5453  1.45   nonaka 	sta->dtim_time = htole32(ni->ni_rstamp + dtim_off);
   5454  1.45   nonaka 	sta->dtim_tsf = htole64(tsf + dtim_off);
   5455  1.45   nonaka 	sta->bi = htole32(ni->ni_intval);
   5456  1.45   nonaka 	sta->bi_reciprocal = htole32(iwm_reciprocal(ni->ni_intval));
   5457  1.45   nonaka 	sta->dtim_interval = htole32(ni->ni_intval * ni->ni_dtim_period);
   5458  1.45   nonaka 	sta->dtim_reciprocal = htole32(iwm_reciprocal(sta->dtim_interval));
   5459  1.45   nonaka 	sta->listen_interval = htole32(10);
   5460  1.45   nonaka 	sta->assoc_id = htole32(ni->ni_associd);
   5461  1.45   nonaka 	sta->assoc_beacon_arrive_time = htole32(ni->ni_rstamp);
   5462   1.1    pooka }
   5463   1.1    pooka 
   5464   1.4   nonaka static int
   5465  1.45   nonaka iwm_mac_ctxt_cmd(struct iwm_softc *sc, struct iwm_node *in, uint32_t action,
   5466  1.45   nonaka     int assoc)
   5467   1.1    pooka {
   5468  1.45   nonaka 	struct ieee80211_node *ni = &in->in_ni;
   5469   1.1    pooka 	struct iwm_mac_ctx_cmd cmd;
   5470   1.1    pooka 
   5471   1.1    pooka 	memset(&cmd, 0, sizeof(cmd));
   5472   1.1    pooka 
   5473  1.45   nonaka 	iwm_mac_ctxt_cmd_common(sc, in, &cmd, action, assoc);
   5474   1.1    pooka 
   5475  1.45   nonaka 	/* Allow beacons to pass through as long as we are not associated or we
   5476  1.45   nonaka 	 * do not have dtim period information */
   5477  1.45   nonaka 	if (!assoc || !ni->ni_associd || !ni->ni_dtim_period)
   5478  1.45   nonaka 		cmd.filter_flags |= htole32(IWM_MAC_FILTER_IN_BEACON);
   5479  1.45   nonaka 	else
   5480  1.45   nonaka 		iwm_mac_ctxt_cmd_fill_sta(sc, in, &cmd.sta, assoc);
   5481   1.1    pooka 
   5482  1.45   nonaka 	return iwm_send_cmd_pdu(sc, IWM_MAC_CONTEXT_CMD, 0, sizeof(cmd), &cmd);
   5483   1.1    pooka }
   5484   1.1    pooka 
   5485  1.45   nonaka #define IWM_MISSED_BEACONS_THRESHOLD 8
   5486   1.1    pooka 
   5487   1.1    pooka static void
   5488  1.45   nonaka iwm_rx_missed_beacons_notif(struct iwm_softc *sc,
   5489   1.1    pooka 	struct iwm_rx_packet *pkt, struct iwm_rx_data *data)
   5490   1.1    pooka {
   5491   1.1    pooka 	struct iwm_missed_beacons_notif *mb = (void *)pkt->data;
   5492   1.1    pooka 
   5493   1.1    pooka 	DPRINTF(("missed bcn mac_id=%u, consecutive=%u (%u, %u, %u)\n",
   5494   1.1    pooka 	    le32toh(mb->mac_id),
   5495   1.1    pooka 	    le32toh(mb->consec_missed_beacons),
   5496   1.1    pooka 	    le32toh(mb->consec_missed_beacons_since_last_rx),
   5497   1.1    pooka 	    le32toh(mb->num_recvd_beacons),
   5498   1.1    pooka 	    le32toh(mb->num_expected_beacons)));
   5499   1.1    pooka 
   5500   1.1    pooka 	/*
   5501   1.1    pooka 	 * TODO: the threshold should be adjusted based on latency conditions,
   5502   1.1    pooka 	 * and/or in case of a CS flow on one of the other AP vifs.
   5503   1.1    pooka 	 */
   5504   1.1    pooka 	if (le32toh(mb->consec_missed_beacons_since_last_rx) >
   5505  1.45   nonaka 	    IWM_MISSED_BEACONS_THRESHOLD)
   5506   1.1    pooka 		ieee80211_beacon_miss(&sc->sc_ic);
   5507   1.1    pooka }
   5508   1.1    pooka 
   5509   1.4   nonaka static int
   5510  1.45   nonaka iwm_update_quotas(struct iwm_softc *sc, struct iwm_node *in)
   5511   1.1    pooka {
   5512   1.1    pooka 	struct iwm_time_quota_cmd cmd;
   5513  1.45   nonaka 	int i, idx, num_active_macs, quota, quota_rem;
   5514   1.1    pooka 	int colors[IWM_MAX_BINDINGS] = { -1, -1, -1, -1, };
   5515   1.1    pooka 	int n_ifs[IWM_MAX_BINDINGS] = {0, };
   5516   1.1    pooka 	uint16_t id;
   5517   1.1    pooka 
   5518   1.1    pooka 	memset(&cmd, 0, sizeof(cmd));
   5519   1.1    pooka 
   5520   1.1    pooka 	/* currently, PHY ID == binding ID */
   5521   1.1    pooka 	if (in) {
   5522   1.1    pooka 		id = in->in_phyctxt->id;
   5523   1.1    pooka 		KASSERT(id < IWM_MAX_BINDINGS);
   5524   1.1    pooka 		colors[id] = in->in_phyctxt->color;
   5525   1.1    pooka 
   5526   1.1    pooka 		if (1)
   5527   1.1    pooka 			n_ifs[id] = 1;
   5528   1.1    pooka 	}
   5529   1.1    pooka 
   5530   1.1    pooka 	/*
   5531   1.1    pooka 	 * The FW's scheduling session consists of
   5532  1.45   nonaka 	 * IWM_MAX_QUOTA fragments. Divide these fragments
   5533   1.1    pooka 	 * equally between all the bindings that require quota
   5534   1.1    pooka 	 */
   5535   1.1    pooka 	num_active_macs = 0;
   5536   1.1    pooka 	for (i = 0; i < IWM_MAX_BINDINGS; i++) {
   5537   1.1    pooka 		cmd.quotas[i].id_and_color = htole32(IWM_FW_CTXT_INVALID);
   5538   1.1    pooka 		num_active_macs += n_ifs[i];
   5539   1.1    pooka 	}
   5540   1.1    pooka 
   5541   1.1    pooka 	quota = 0;
   5542   1.1    pooka 	quota_rem = 0;
   5543   1.1    pooka 	if (num_active_macs) {
   5544  1.45   nonaka 		quota = IWM_MAX_QUOTA / num_active_macs;
   5545  1.45   nonaka 		quota_rem = IWM_MAX_QUOTA % num_active_macs;
   5546   1.1    pooka 	}
   5547   1.1    pooka 
   5548   1.1    pooka 	for (idx = 0, i = 0; i < IWM_MAX_BINDINGS; i++) {
   5549   1.1    pooka 		if (colors[i] < 0)
   5550   1.1    pooka 			continue;
   5551   1.1    pooka 
   5552   1.1    pooka 		cmd.quotas[idx].id_and_color =
   5553   1.1    pooka 			htole32(IWM_FW_CMD_ID_AND_COLOR(i, colors[i]));
   5554   1.1    pooka 
   5555   1.1    pooka 		if (n_ifs[i] <= 0) {
   5556   1.1    pooka 			cmd.quotas[idx].quota = htole32(0);
   5557   1.1    pooka 			cmd.quotas[idx].max_duration = htole32(0);
   5558   1.1    pooka 		} else {
   5559   1.1    pooka 			cmd.quotas[idx].quota = htole32(quota * n_ifs[i]);
   5560   1.1    pooka 			cmd.quotas[idx].max_duration = htole32(0);
   5561   1.1    pooka 		}
   5562   1.1    pooka 		idx++;
   5563   1.1    pooka 	}
   5564   1.1    pooka 
   5565   1.1    pooka 	/* Give the remainder of the session to the first binding */
   5566   1.1    pooka 	cmd.quotas[0].quota = htole32(le32toh(cmd.quotas[0].quota) + quota_rem);
   5567   1.1    pooka 
   5568  1.45   nonaka 	return iwm_send_cmd_pdu(sc, IWM_TIME_QUOTA_CMD, 0, sizeof(cmd), &cmd);
   5569   1.1    pooka }
   5570   1.1    pooka 
   5571   1.4   nonaka static int
   5572   1.1    pooka iwm_auth(struct iwm_softc *sc)
   5573   1.1    pooka {
   5574   1.1    pooka 	struct ieee80211com *ic = &sc->sc_ic;
   5575  1.45   nonaka 	struct iwm_node *in = (struct iwm_node *)ic->ic_bss;
   5576   1.1    pooka 	uint32_t duration;
   5577  1.45   nonaka 	int err;
   5578   1.1    pooka 
   5579  1.45   nonaka 	err = iwm_sf_config(sc, IWM_SF_FULL_ON);
   5580  1.45   nonaka 	if (err)
   5581  1.45   nonaka 		return err;
   5582  1.11   nonaka 
   5583  1.45   nonaka 	err = iwm_allow_mcast(sc);
   5584  1.45   nonaka 	if (err)
   5585  1.45   nonaka 		return err;
   5586  1.11   nonaka 
   5587  1.45   nonaka 	sc->sc_phyctxt[0].channel = in->in_ni.ni_chan;
   5588  1.45   nonaka 	err = iwm_phy_ctxt_cmd(sc, &sc->sc_phyctxt[0], 1, 1,
   5589  1.45   nonaka 	    IWM_FW_CTXT_ACTION_MODIFY, 0);
   5590  1.45   nonaka 	if (err)
   5591  1.45   nonaka 		return err;
   5592   1.1    pooka 	in->in_phyctxt = &sc->sc_phyctxt[0];
   5593   1.1    pooka 
   5594  1.45   nonaka 	err = iwm_mac_ctxt_cmd(sc, in, IWM_FW_CTXT_ACTION_ADD, 0);
   5595  1.45   nonaka 	if (err) {
   5596  1.45   nonaka 		aprint_error_dev(sc->sc_dev,
   5597  1.45   nonaka 		    "could not add MAC context (error %d)\n", err);
   5598  1.45   nonaka 		return err;
   5599   1.1    pooka 	}
   5600   1.1    pooka 
   5601  1.45   nonaka 	err = iwm_binding_cmd(sc, in, IWM_FW_CTXT_ACTION_ADD);
   5602  1.45   nonaka 	if (err)
   5603  1.45   nonaka 		return err;
   5604   1.1    pooka 
   5605  1.45   nonaka 	err = iwm_add_sta_cmd(sc, in, 0);
   5606  1.45   nonaka 	if (err)
   5607  1.45   nonaka 		return err;
   5608   1.8   nonaka 
   5609  1.45   nonaka 	err = iwm_mac_ctxt_cmd(sc, in, IWM_FW_CTXT_ACTION_MODIFY, 0);
   5610  1.45   nonaka 	if (err) {
   5611  1.45   nonaka 		aprint_error_dev(sc->sc_dev, "failed to update MAC\n");
   5612  1.45   nonaka 		return err;
   5613  1.45   nonaka 	}
   5614   1.1    pooka 
   5615  1.45   nonaka 	/*
   5616  1.45   nonaka 	 * Prevent the FW from wandering off channel during association
   5617  1.45   nonaka 	 * by "protecting" the session with a time event.
   5618  1.45   nonaka 	 */
   5619  1.45   nonaka 	if (in->in_ni.ni_intval)
   5620  1.45   nonaka 		duration = in->in_ni.ni_intval * 2;
   5621  1.45   nonaka 	else
   5622  1.45   nonaka 		duration = IEEE80211_DUR_TU;
   5623  1.45   nonaka 	iwm_protect_session(sc, in, duration, in->in_ni.ni_intval / 2);
   5624  1.45   nonaka 	DELAY(100);
   5625   1.1    pooka 
   5626   1.1    pooka 	return 0;
   5627   1.1    pooka }
   5628   1.1    pooka 
   5629   1.4   nonaka static int
   5630   1.1    pooka iwm_assoc(struct iwm_softc *sc)
   5631   1.1    pooka {
   5632   1.1    pooka 	struct ieee80211com *ic = &sc->sc_ic;
   5633  1.45   nonaka 	struct iwm_node *in = (struct iwm_node *)ic->ic_bss;
   5634  1.45   nonaka 	int err;
   5635   1.1    pooka 
   5636  1.45   nonaka 	err = iwm_add_sta_cmd(sc, in, 1);
   5637  1.45   nonaka 	if (err)
   5638  1.45   nonaka 		return err;
   5639   1.1    pooka 
   5640   1.1    pooka 	return 0;
   5641   1.1    pooka }
   5642   1.1    pooka 
   5643   1.1    pooka static struct ieee80211_node *
   5644   1.1    pooka iwm_node_alloc(struct ieee80211_node_table *nt)
   5645   1.1    pooka {
   5646   1.5   nonaka 	return malloc(sizeof(struct iwm_node), M_80211_NODE, M_NOWAIT | M_ZERO);
   5647   1.1    pooka }
   5648   1.1    pooka 
   5649   1.4   nonaka static void
   5650   1.1    pooka iwm_calib_timeout(void *arg)
   5651   1.1    pooka {
   5652   1.1    pooka 	struct iwm_softc *sc = arg;
   5653   1.1    pooka 	struct ieee80211com *ic = &sc->sc_ic;
   5654  1.45   nonaka 	struct iwm_node *in = (struct iwm_node *)ic->ic_bss;
   5655  1.45   nonaka #ifndef IEEE80211_NO_HT
   5656  1.45   nonaka 	struct ieee80211_node *ni = &in->in_ni;
   5657  1.45   nonaka 	int otxrate;
   5658  1.45   nonaka #endif
   5659   1.1    pooka 	int s;
   5660   1.1    pooka 
   5661   1.1    pooka 	s = splnet();
   5662  1.45   nonaka 	if ((ic->ic_fixed_rate == -1
   5663  1.45   nonaka #ifndef IEEE80211_NO_HT
   5664  1.45   nonaka 	    || ic->ic_fixed_mcs == -1
   5665  1.45   nonaka #endif
   5666  1.45   nonaka 	    ) &&
   5667  1.45   nonaka 	    ic->ic_opmode == IEEE80211_M_STA && ic->ic_bss) {
   5668  1.45   nonaka #ifndef IEEE80211_NO_HT
   5669  1.45   nonaka 		if (ni->ni_flags & IEEE80211_NODE_HT)
   5670  1.45   nonaka 			otxrate = ni->ni_txmcs;
   5671  1.45   nonaka 		else
   5672  1.45   nonaka 			otxrate = ni->ni_txrate;
   5673  1.45   nonaka #endif
   5674   1.1    pooka 		ieee80211_amrr_choose(&sc->sc_amrr, &in->in_ni, &in->in_amn);
   5675  1.45   nonaka 
   5676  1.45   nonaka #ifndef IEEE80211_NO_HT
   5677  1.45   nonaka 		/*
   5678  1.45   nonaka 		 * If AMRR has chosen a new TX rate we must update
   5679  1.45   nonaka 		 * the firwmare's LQ rate table from process context.
   5680  1.45   nonaka 		 */
   5681  1.45   nonaka 		if ((ni->ni_flags & IEEE80211_NODE_HT) &&
   5682  1.45   nonaka 		    otxrate != ni->ni_txmcs)
   5683  1.45   nonaka 			softint_schedule(sc->setrates_task);
   5684  1.45   nonaka 		else if (otxrate != ni->ni_txrate)
   5685  1.45   nonaka 			softint_schedule(sc->setrates_task);
   5686  1.45   nonaka #endif
   5687   1.1    pooka 	}
   5688   1.1    pooka 	splx(s);
   5689   1.1    pooka 
   5690  1.45   nonaka 	callout_schedule(&sc->sc_calib_to, mstohz(500));
   5691   1.1    pooka }
   5692   1.1    pooka 
   5693  1.45   nonaka #ifndef IEEE80211_NO_HT
   5694   1.4   nonaka static void
   5695  1.45   nonaka iwm_setrates_task(void *arg)
   5696  1.45   nonaka {
   5697  1.45   nonaka 	struct iwm_softc *sc = arg;
   5698  1.45   nonaka 	struct ieee80211com *ic = &sc->sc_ic;
   5699  1.45   nonaka 	struct iwm_node *in = (struct iwm_node *)ic->ic_bss;
   5700  1.45   nonaka 
   5701  1.45   nonaka 	/* Update rates table based on new TX rate determined by AMRR. */
   5702  1.45   nonaka 	iwm_setrates(in);
   5703  1.45   nonaka }
   5704  1.45   nonaka 
   5705  1.45   nonaka static int
   5706   1.1    pooka iwm_setrates(struct iwm_node *in)
   5707   1.1    pooka {
   5708   1.1    pooka 	struct ieee80211_node *ni = &in->in_ni;
   5709   1.1    pooka 	struct ieee80211com *ic = ni->ni_ic;
   5710   1.1    pooka 	struct iwm_softc *sc = IC2IFP(ic)->if_softc;
   5711   1.1    pooka 	struct iwm_lq_cmd *lq = &in->in_lq;
   5712  1.45   nonaka 	struct ieee80211_rateset *rs = &ni->ni_rates;
   5713  1.45   nonaka 	int i, j, ridx, ridx_min, tab = 0;
   5714  1.45   nonaka #ifndef IEEE80211_NO_HT
   5715  1.45   nonaka 	int sgi_ok;
   5716  1.45   nonaka #endif
   5717  1.45   nonaka 	struct iwm_host_cmd cmd = {
   5718  1.45   nonaka 		.id = IWM_LQ_CMD,
   5719  1.45   nonaka 		.len = { sizeof(in->in_lq), },
   5720  1.45   nonaka 	};
   5721   1.1    pooka 
   5722  1.45   nonaka 	memset(lq, 0, sizeof(*lq));
   5723  1.45   nonaka 	lq->sta_id = IWM_STATION_ID;
   5724   1.1    pooka 
   5725  1.45   nonaka 	if (ic->ic_flags & IEEE80211_F_USEPROT)
   5726  1.45   nonaka 		lq->flags |= IWM_LQ_FLAG_USE_RTS_MSK;
   5727   1.8   nonaka 
   5728  1.45   nonaka #ifndef IEEE80211_NO_HT
   5729  1.45   nonaka 	sgi_ok = ((ni->ni_flags & IEEE80211_NODE_HT) &&
   5730  1.45   nonaka 	    (ni->ni_htcaps & IEEE80211_HTCAP_SGI20));
   5731  1.45   nonaka #endif
   5732   1.1    pooka 
   5733   1.1    pooka 
   5734   1.1    pooka 	/*
   5735  1.45   nonaka 	 * Fill the LQ rate selection table with legacy and/or HT rates
   5736  1.45   nonaka 	 * in descending order, i.e. with the node's current TX rate first.
   5737  1.45   nonaka 	 * In cases where throughput of an HT rate corresponds to a legacy
   5738  1.45   nonaka 	 * rate it makes no sense to add both. We rely on the fact that
   5739  1.45   nonaka 	 * iwm_rates is laid out such that equivalent HT/legacy rates share
   5740  1.45   nonaka 	 * the same IWM_RATE_*_INDEX value. Also, rates not applicable to
   5741  1.45   nonaka 	 * legacy/HT are assumed to be marked with an 'invalid' PLCP value.
   5742   1.1    pooka 	 */
   5743  1.45   nonaka 	j = 0;
   5744  1.45   nonaka 	ridx_min = (IEEE80211_IS_CHAN_5GHZ(ni->ni_chan)) ?
   5745  1.45   nonaka 	    IWM_RIDX_OFDM : IWM_RIDX_CCK;
   5746  1.45   nonaka 	for (ridx = IWM_RIDX_MAX; ridx >= ridx_min; ridx--) {
   5747  1.45   nonaka 		if (j >= __arraycount(lq->rs_table))
   5748  1.45   nonaka 			break;
   5749  1.45   nonaka 		tab = 0;
   5750  1.45   nonaka #ifndef IEEE80211_NO_HT
   5751  1.45   nonaka 		if ((ni->ni_flags & IEEE80211_NODE_HT) &&
   5752  1.45   nonaka 		    iwm_rates[ridx].ht_plcp != IWM_RATE_HT_SISO_MCS_INV_PLCP) {
   5753  1.45   nonaka 			for (i = ni->ni_txmcs; i >= 0; i--) {
   5754  1.45   nonaka 				if (isclr(ni->ni_rxmcs, i))
   5755  1.45   nonaka 					continue;
   5756  1.45   nonaka 				if (ridx == iwm_mcs2ridx[i]) {
   5757  1.45   nonaka 					tab = iwm_rates[ridx].ht_plcp;
   5758  1.45   nonaka 					tab |= IWM_RATE_MCS_HT_MSK;
   5759  1.45   nonaka 					if (sgi_ok)
   5760  1.45   nonaka 						tab |= IWM_RATE_MCS_SGI_MSK;
   5761  1.45   nonaka 					break;
   5762  1.45   nonaka 				}
   5763  1.45   nonaka 			}
   5764  1.45   nonaka 		}
   5765  1.45   nonaka #endif
   5766  1.45   nonaka 		if (tab == 0 && iwm_rates[ridx].plcp != IWM_RATE_INVM_PLCP) {
   5767  1.45   nonaka 			for (i = ni->ni_txrate; i >= 0; i--) {
   5768  1.45   nonaka 				if (iwm_rates[ridx].rate == (rs->rs_rates[i] &
   5769  1.45   nonaka 				    IEEE80211_RATE_VAL)) {
   5770  1.45   nonaka 					tab = iwm_rates[ridx].plcp;
   5771  1.45   nonaka 					break;
   5772  1.45   nonaka 				}
   5773  1.45   nonaka 			}
   5774  1.45   nonaka 		}
   5775   1.1    pooka 
   5776  1.45   nonaka 		if (tab == 0)
   5777  1.45   nonaka 			continue;
   5778   1.1    pooka 
   5779  1.45   nonaka 		tab |= 1 << IWM_RATE_MCS_ANT_POS;
   5780   1.1    pooka 		if (IWM_RIDX_IS_CCK(ridx))
   5781   1.1    pooka 			tab |= IWM_RATE_MCS_CCK_MSK;
   5782   1.1    pooka 		DPRINTFN(2, ("station rate %d %x\n", i, tab));
   5783  1.45   nonaka 		lq->rs_table[j++] = htole32(tab);
   5784   1.1    pooka 	}
   5785   1.1    pooka 
   5786  1.45   nonaka 	/* Fill the rest with the lowest possible rate */
   5787  1.45   nonaka 	i = j > 0 ? j - 1 : 0;
   5788  1.45   nonaka 	while (j < __arraycount(lq->rs_table))
   5789  1.45   nonaka 		lq->rs_table[j++] = lq->rs_table[i];
   5790  1.45   nonaka 
   5791  1.45   nonaka 	lq->single_stream_ant_msk = IWM_ANT_A;
   5792  1.45   nonaka 	lq->dual_stream_ant_msk = IWM_ANT_AB;
   5793  1.45   nonaka 
   5794  1.45   nonaka 	lq->agg_time_limit = htole16(4000);	/* 4ms */
   5795  1.45   nonaka 	lq->agg_disable_start_th = 3;
   5796  1.45   nonaka #ifdef notyet
   5797  1.45   nonaka 	lq->agg_frame_cnt_limit = 0x3f;
   5798  1.45   nonaka #else
   5799  1.45   nonaka 	lq->agg_frame_cnt_limit = 1; /* tx agg disabled */
   5800  1.45   nonaka #endif
   5801  1.45   nonaka 
   5802  1.45   nonaka 	cmd.data[0] = &in->in_lq;
   5803  1.45   nonaka 	return iwm_send_cmd(sc, &cmd);
   5804   1.1    pooka }
   5805  1.45   nonaka #endif
   5806   1.1    pooka 
   5807   1.4   nonaka static int
   5808   1.1    pooka iwm_media_change(struct ifnet *ifp)
   5809   1.1    pooka {
   5810   1.1    pooka 	struct iwm_softc *sc = ifp->if_softc;
   5811   1.1    pooka 	struct ieee80211com *ic = &sc->sc_ic;
   5812   1.1    pooka 	uint8_t rate, ridx;
   5813  1.45   nonaka 	int err;
   5814   1.1    pooka 
   5815  1.45   nonaka 	err = ieee80211_media_change(ifp);
   5816  1.45   nonaka 	if (err != ENETRESET)
   5817  1.45   nonaka 		return err;
   5818   1.1    pooka 
   5819  1.45   nonaka #ifndef IEEE80211_NO_HT
   5820  1.45   nonaka 	if (ic->ic_fixed_mcs != -1)
   5821  1.45   nonaka 		sc->sc_fixed_ridx = iwm_mcs2ridx[ic->ic_fixed_mcs];
   5822  1.45   nonaka 	else
   5823  1.45   nonaka #endif
   5824   1.1    pooka 	if (ic->ic_fixed_rate != -1) {
   5825   1.1    pooka 		rate = ic->ic_sup_rates[ic->ic_curmode].
   5826   1.1    pooka 		    rs_rates[ic->ic_fixed_rate] & IEEE80211_RATE_VAL;
   5827   1.1    pooka 		/* Map 802.11 rate to HW rate index. */
   5828   1.1    pooka 		for (ridx = 0; ridx <= IWM_RIDX_MAX; ridx++)
   5829   1.1    pooka 			if (iwm_rates[ridx].rate == rate)
   5830   1.1    pooka 				break;
   5831   1.1    pooka 		sc->sc_fixed_ridx = ridx;
   5832   1.1    pooka 	}
   5833   1.1    pooka 
   5834   1.1    pooka 	if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
   5835   1.1    pooka 	    (IFF_UP | IFF_RUNNING)) {
   5836   1.1    pooka 		iwm_stop(ifp, 0);
   5837  1.45   nonaka 		err = iwm_init(ifp);
   5838   1.1    pooka 	}
   5839  1.45   nonaka 	return err;
   5840   1.1    pooka }
   5841   1.1    pooka 
   5842  1.65   nonaka static int
   5843  1.65   nonaka iwm_do_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
   5844   1.1    pooka {
   5845  1.65   nonaka 	struct ifnet *ifp = IC2IFP(ic);
   5846  1.65   nonaka 	struct iwm_softc *sc = ifp->if_softc;
   5847  1.45   nonaka 	enum ieee80211_state ostate = ic->ic_state;
   5848   1.1    pooka 	struct iwm_node *in;
   5849  1.45   nonaka 	int err;
   5850   1.1    pooka 
   5851  1.45   nonaka 	DPRINTF(("switching state %s->%s\n", ieee80211_state_name[ostate],
   5852  1.45   nonaka 	    ieee80211_state_name[nstate]));
   5853   1.1    pooka 
   5854  1.45   nonaka 	if (ostate == IEEE80211_S_SCAN && nstate != ostate)
   5855  1.45   nonaka 		iwm_led_blink_stop(sc);
   5856  1.45   nonaka 
   5857  1.45   nonaka 	if (ostate == IEEE80211_S_RUN && nstate != ostate)
   5858  1.45   nonaka 		iwm_disable_beacon_filter(sc);
   5859  1.45   nonaka 
   5860  1.45   nonaka 	/* Reset the device if moving out of AUTH, ASSOC, or RUN. */
   5861  1.45   nonaka 	/* XXX Is there a way to switch states without a full reset? */
   5862  1.45   nonaka 	if (ostate > IEEE80211_S_SCAN && nstate < ostate) {
   5863  1.45   nonaka 		iwm_stop_device(sc);
   5864  1.45   nonaka 		iwm_init_hw(sc);
   5865   1.1    pooka 
   5866   1.1    pooka 		/*
   5867  1.45   nonaka 		 * Upon receiving a deauth frame from AP the net80211 stack
   5868  1.45   nonaka 		 * puts the driver into AUTH state. This will fail with this
   5869  1.45   nonaka 		 * driver so bring the FSM from RUN to SCAN in this case.
   5870   1.1    pooka 		 */
   5871   1.1    pooka 		if (nstate == IEEE80211_S_SCAN ||
   5872   1.1    pooka 		    nstate == IEEE80211_S_AUTH ||
   5873   1.1    pooka 		    nstate == IEEE80211_S_ASSOC) {
   5874   1.1    pooka 			DPRINTF(("Force transition to INIT; MGT=%d\n", arg));
   5875  1.45   nonaka 			/* Always pass arg as -1 since we can't Tx right now. */
   5876  1.45   nonaka 			sc->sc_newstate(ic, IEEE80211_S_INIT, -1);
   5877   1.1    pooka 			DPRINTF(("Going INIT->SCAN\n"));
   5878   1.1    pooka 			nstate = IEEE80211_S_SCAN;
   5879   1.1    pooka 		}
   5880   1.1    pooka 	}
   5881   1.1    pooka 
   5882   1.1    pooka 	switch (nstate) {
   5883   1.1    pooka 	case IEEE80211_S_INIT:
   5884   1.1    pooka 		break;
   5885   1.1    pooka 
   5886   1.1    pooka 	case IEEE80211_S_SCAN:
   5887  1.45   nonaka 		if (ostate == nstate &&
   5888  1.45   nonaka 		    ISSET(sc->sc_flags, IWM_FLAG_SCANNING))
   5889  1.65   nonaka 			return 0;
   5890  1.45   nonaka 		if (isset(sc->sc_enabled_capa, IWM_UCODE_TLV_CAPA_UMAC_SCAN))
   5891  1.45   nonaka 			err = iwm_umac_scan(sc);
   5892  1.45   nonaka 		else
   5893  1.45   nonaka 			err = iwm_lmac_scan(sc);
   5894  1.45   nonaka 		if (err) {
   5895   1.8   nonaka 			DPRINTF(("%s: could not initiate scan\n", DEVNAME(sc)));
   5896  1.65   nonaka 			return err;
   5897   1.1    pooka 		}
   5898  1.45   nonaka 		SET(sc->sc_flags, IWM_FLAG_SCANNING);
   5899   1.1    pooka 		ic->ic_state = nstate;
   5900  1.45   nonaka 		iwm_led_blink_start(sc);
   5901  1.65   nonaka 		return 0;
   5902   1.1    pooka 
   5903   1.1    pooka 	case IEEE80211_S_AUTH:
   5904  1.45   nonaka 		err = iwm_auth(sc);
   5905  1.45   nonaka 		if (err) {
   5906   1.2   nonaka 			DPRINTF(("%s: could not move to auth state: %d\n",
   5907  1.45   nonaka 			    DEVNAME(sc), err));
   5908  1.65   nonaka 			return err;
   5909   1.1    pooka 		}
   5910   1.1    pooka 		break;
   5911   1.1    pooka 
   5912   1.1    pooka 	case IEEE80211_S_ASSOC:
   5913  1.45   nonaka 		err = iwm_assoc(sc);
   5914  1.45   nonaka 		if (err) {
   5915   1.2   nonaka 			DPRINTF(("%s: failed to associate: %d\n", DEVNAME(sc),
   5916  1.45   nonaka 			    err));
   5917  1.65   nonaka 			return err;
   5918   1.1    pooka 		}
   5919   1.1    pooka 		break;
   5920   1.1    pooka 
   5921  1.45   nonaka 	case IEEE80211_S_RUN:
   5922  1.45   nonaka 		in = (struct iwm_node *)ic->ic_bss;
   5923  1.45   nonaka 
   5924  1.45   nonaka 		/* We have now been assigned an associd by the AP. */
   5925  1.45   nonaka 		err = iwm_mac_ctxt_cmd(sc, in, IWM_FW_CTXT_ACTION_MODIFY, 1);
   5926  1.45   nonaka 		if (err) {
   5927  1.45   nonaka 			aprint_error_dev(sc->sc_dev, "failed to update MAC\n");
   5928  1.65   nonaka 			return err;
   5929  1.45   nonaka 		}
   5930   1.1    pooka 
   5931  1.45   nonaka 		err = iwm_power_update_device(sc);
   5932  1.45   nonaka 		if (err) {
   5933  1.45   nonaka 			aprint_error_dev(sc->sc_dev,
   5934  1.45   nonaka 			    "could send power command (error %d)\n", err);
   5935  1.65   nonaka 			return err;
   5936  1.45   nonaka 		}
   5937  1.45   nonaka #ifdef notyet
   5938  1.45   nonaka 		/*
   5939  1.45   nonaka 		 * Disabled for now. Default beacon filter settings
   5940  1.45   nonaka 		 * prevent net80211 from getting ERP and HT protection
   5941  1.45   nonaka 		 * updates from beacons.
   5942  1.45   nonaka 		 */
   5943  1.45   nonaka 		err = iwm_enable_beacon_filter(sc, in);
   5944  1.45   nonaka 		if (err) {
   5945  1.45   nonaka 			aprint_error_dev(sc->sc_dev,
   5946  1.45   nonaka 			    "could not enable beacon filter\n");
   5947  1.65   nonaka 			return err;
   5948  1.45   nonaka 		}
   5949  1.45   nonaka #endif
   5950  1.45   nonaka 		err = iwm_power_mac_update_mode(sc, in);
   5951  1.45   nonaka 		if (err) {
   5952  1.45   nonaka 			aprint_error_dev(sc->sc_dev,
   5953  1.45   nonaka 			    "could not update MAC power (error %d)\n", err);
   5954  1.65   nonaka 			return err;
   5955  1.45   nonaka 		}
   5956   1.1    pooka 
   5957  1.45   nonaka 		err = iwm_update_quotas(sc, in);
   5958  1.45   nonaka 		if (err) {
   5959  1.45   nonaka 			aprint_error_dev(sc->sc_dev,
   5960  1.45   nonaka 			    "could not update quotas (error %d)\n", err);
   5961  1.65   nonaka 			return err;
   5962   1.1    pooka 		}
   5963   1.1    pooka 
   5964  1.45   nonaka 		ieee80211_amrr_node_init(&sc->sc_amrr, &in->in_amn);
   5965   1.1    pooka 
   5966  1.45   nonaka 		/* Start at lowest available bit-rate, AMRR will raise. */
   5967  1.45   nonaka 		in->in_ni.ni_txrate = 0;
   5968  1.45   nonaka #ifndef IEEE80211_NO_HT
   5969  1.45   nonaka 		in->in_ni.ni_txmcs = 0;
   5970  1.45   nonaka 		iwm_setrates(in);
   5971  1.45   nonaka #endif
   5972  1.45   nonaka 
   5973  1.45   nonaka 		callout_schedule(&sc->sc_calib_to, mstohz(500));
   5974  1.45   nonaka 		iwm_led_enable(sc);
   5975  1.45   nonaka 		break;
   5976   1.1    pooka 
   5977   1.1    pooka 	default:
   5978   1.2   nonaka 		break;
   5979   1.1    pooka 	}
   5980   1.1    pooka 
   5981  1.65   nonaka 	return sc->sc_newstate(ic, nstate, arg);
   5982  1.65   nonaka }
   5983  1.65   nonaka 
   5984  1.65   nonaka static void
   5985  1.65   nonaka iwm_newstate_cb(struct work *wk, void *v)
   5986  1.65   nonaka {
   5987  1.65   nonaka 	struct iwm_softc *sc = v;
   5988  1.65   nonaka 	struct ieee80211com *ic = &sc->sc_ic;
   5989  1.65   nonaka 	struct iwm_newstate_state *iwmns = (struct iwm_newstate_state *)wk;
   5990  1.65   nonaka 	enum ieee80211_state nstate = iwmns->ns_nstate;
   5991  1.65   nonaka 	int generation = iwmns->ns_generation;
   5992  1.65   nonaka 	int arg = iwmns->ns_arg;
   5993  1.65   nonaka 	int s;
   5994  1.65   nonaka 
   5995  1.65   nonaka 	kmem_free(iwmns, sizeof(*iwmns));
   5996  1.65   nonaka 
   5997  1.65   nonaka 	s = splnet();
   5998  1.65   nonaka 
   5999  1.65   nonaka 	DPRINTF(("Prepare to switch state %d->%d\n", ic->ic_state, nstate));
   6000  1.65   nonaka 	if (sc->sc_generation != generation) {
   6001  1.65   nonaka 		DPRINTF(("newstate_cb: someone pulled the plug meanwhile\n"));
   6002  1.65   nonaka 		if (nstate == IEEE80211_S_INIT) {
   6003  1.65   nonaka 			DPRINTF(("newstate_cb: nstate == IEEE80211_S_INIT: "
   6004  1.65   nonaka 			    "calling sc_newstate()\n"));
   6005  1.65   nonaka 			(void) sc->sc_newstate(ic, nstate, arg);
   6006  1.65   nonaka 		}
   6007  1.65   nonaka 	} else
   6008  1.65   nonaka 		(void) iwm_do_newstate(ic, nstate, arg);
   6009  1.65   nonaka 
   6010  1.65   nonaka 	splx(s);
   6011   1.1    pooka }
   6012   1.1    pooka 
   6013   1.4   nonaka static int
   6014   1.1    pooka iwm_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
   6015   1.1    pooka {
   6016   1.1    pooka 	struct iwm_newstate_state *iwmns;
   6017   1.1    pooka 	struct ifnet *ifp = IC2IFP(ic);
   6018   1.1    pooka 	struct iwm_softc *sc = ifp->if_softc;
   6019   1.1    pooka 
   6020   1.1    pooka 	callout_stop(&sc->sc_calib_to);
   6021   1.1    pooka 
   6022   1.5   nonaka 	iwmns = kmem_intr_alloc(sizeof(*iwmns), KM_NOSLEEP);
   6023   1.1    pooka 	if (!iwmns) {
   6024   1.2   nonaka 		DPRINTF(("%s: allocating state cb mem failed\n", DEVNAME(sc)));
   6025   1.1    pooka 		return ENOMEM;
   6026   1.1    pooka 	}
   6027   1.1    pooka 
   6028   1.1    pooka 	iwmns->ns_nstate = nstate;
   6029   1.1    pooka 	iwmns->ns_arg = arg;
   6030   1.1    pooka 	iwmns->ns_generation = sc->sc_generation;
   6031   1.1    pooka 
   6032   1.1    pooka 	workqueue_enqueue(sc->sc_nswq, &iwmns->ns_wk, NULL);
   6033   1.1    pooka 
   6034   1.1    pooka 	return 0;
   6035   1.1    pooka }
   6036   1.1    pooka 
   6037   1.4   nonaka static void
   6038  1.50   nonaka iwm_endscan(struct iwm_softc *sc)
   6039   1.1    pooka {
   6040   1.1    pooka 	struct ieee80211com *ic = &sc->sc_ic;
   6041  1.61   nonaka 	int s;
   6042   1.1    pooka 
   6043  1.61   nonaka 	DPRINTF(("%s: scan ended\n", DEVNAME(sc)));
   6044   1.1    pooka 
   6045  1.61   nonaka 	s = splnet();
   6046  1.61   nonaka 	if (ic->ic_state == IEEE80211_S_SCAN)
   6047  1.61   nonaka 		ieee80211_end_scan(ic);
   6048  1.61   nonaka 	splx(s);
   6049  1.45   nonaka }
   6050  1.45   nonaka 
   6051  1.45   nonaka /*
   6052  1.45   nonaka  * Aging and idle timeouts for the different possible scenarios
   6053  1.45   nonaka  * in default configuration
   6054  1.45   nonaka  */
   6055  1.45   nonaka static const uint32_t
   6056  1.45   nonaka iwm_sf_full_timeout_def[IWM_SF_NUM_SCENARIO][IWM_SF_NUM_TIMEOUT_TYPES] = {
   6057  1.45   nonaka 	{
   6058  1.45   nonaka 		htole32(IWM_SF_SINGLE_UNICAST_AGING_TIMER_DEF),
   6059  1.45   nonaka 		htole32(IWM_SF_SINGLE_UNICAST_IDLE_TIMER_DEF)
   6060  1.45   nonaka 	},
   6061  1.45   nonaka 	{
   6062  1.45   nonaka 		htole32(IWM_SF_AGG_UNICAST_AGING_TIMER_DEF),
   6063  1.45   nonaka 		htole32(IWM_SF_AGG_UNICAST_IDLE_TIMER_DEF)
   6064  1.45   nonaka 	},
   6065  1.45   nonaka 	{
   6066  1.45   nonaka 		htole32(IWM_SF_MCAST_AGING_TIMER_DEF),
   6067  1.45   nonaka 		htole32(IWM_SF_MCAST_IDLE_TIMER_DEF)
   6068  1.45   nonaka 	},
   6069  1.45   nonaka 	{
   6070  1.45   nonaka 		htole32(IWM_SF_BA_AGING_TIMER_DEF),
   6071  1.45   nonaka 		htole32(IWM_SF_BA_IDLE_TIMER_DEF)
   6072  1.45   nonaka 	},
   6073  1.45   nonaka 	{
   6074  1.45   nonaka 		htole32(IWM_SF_TX_RE_AGING_TIMER_DEF),
   6075  1.45   nonaka 		htole32(IWM_SF_TX_RE_IDLE_TIMER_DEF)
   6076  1.45   nonaka 	},
   6077  1.45   nonaka };
   6078  1.45   nonaka 
   6079  1.45   nonaka /*
   6080  1.45   nonaka  * Aging and idle timeouts for the different possible scenarios
   6081  1.45   nonaka  * in single BSS MAC configuration.
   6082  1.45   nonaka  */
   6083  1.45   nonaka static const uint32_t
   6084  1.45   nonaka iwm_sf_full_timeout[IWM_SF_NUM_SCENARIO][IWM_SF_NUM_TIMEOUT_TYPES] = {
   6085  1.45   nonaka 	{
   6086  1.45   nonaka 		htole32(IWM_SF_SINGLE_UNICAST_AGING_TIMER),
   6087  1.45   nonaka 		htole32(IWM_SF_SINGLE_UNICAST_IDLE_TIMER)
   6088  1.45   nonaka 	},
   6089  1.45   nonaka 	{
   6090  1.45   nonaka 		htole32(IWM_SF_AGG_UNICAST_AGING_TIMER),
   6091  1.45   nonaka 		htole32(IWM_SF_AGG_UNICAST_IDLE_TIMER)
   6092  1.45   nonaka 	},
   6093  1.45   nonaka 	{
   6094  1.45   nonaka 		htole32(IWM_SF_MCAST_AGING_TIMER),
   6095  1.45   nonaka 		htole32(IWM_SF_MCAST_IDLE_TIMER)
   6096  1.45   nonaka 	},
   6097  1.45   nonaka 	{
   6098  1.45   nonaka 		htole32(IWM_SF_BA_AGING_TIMER),
   6099  1.45   nonaka 		htole32(IWM_SF_BA_IDLE_TIMER)
   6100  1.45   nonaka 	},
   6101  1.45   nonaka 	{
   6102  1.45   nonaka 		htole32(IWM_SF_TX_RE_AGING_TIMER),
   6103  1.45   nonaka 		htole32(IWM_SF_TX_RE_IDLE_TIMER)
   6104  1.45   nonaka 	},
   6105  1.45   nonaka };
   6106  1.45   nonaka 
   6107  1.45   nonaka static void
   6108  1.45   nonaka iwm_fill_sf_command(struct iwm_softc *sc, struct iwm_sf_cfg_cmd *sf_cmd,
   6109  1.45   nonaka     struct ieee80211_node *ni)
   6110  1.45   nonaka {
   6111  1.45   nonaka 	int i, j, watermark;
   6112  1.45   nonaka 
   6113  1.45   nonaka 	sf_cmd->watermark[IWM_SF_LONG_DELAY_ON] = htole32(IWM_SF_W_MARK_SCAN);
   6114  1.45   nonaka 
   6115  1.45   nonaka 	/*
   6116  1.45   nonaka 	 * If we are in association flow - check antenna configuration
   6117  1.45   nonaka 	 * capabilities of the AP station, and choose the watermark accordingly.
   6118  1.45   nonaka 	 */
   6119  1.45   nonaka 	if (ni) {
   6120  1.45   nonaka #ifndef IEEE80211_NO_HT
   6121  1.45   nonaka 		if (ni->ni_flags & IEEE80211_NODE_HT) {
   6122  1.45   nonaka #ifdef notyet
   6123  1.45   nonaka 			if (ni->ni_rxmcs[2] != 0)
   6124  1.45   nonaka 				watermark = IWM_SF_W_MARK_MIMO3;
   6125  1.45   nonaka 			else if (ni->ni_rxmcs[1] != 0)
   6126  1.45   nonaka 				watermark = IWM_SF_W_MARK_MIMO2;
   6127  1.45   nonaka 			else
   6128  1.45   nonaka #endif
   6129  1.45   nonaka 				watermark = IWM_SF_W_MARK_SISO;
   6130  1.45   nonaka 		} else
   6131  1.45   nonaka #endif
   6132  1.45   nonaka 			watermark = IWM_SF_W_MARK_LEGACY;
   6133  1.45   nonaka 	/* default watermark value for unassociated mode. */
   6134  1.45   nonaka 	} else {
   6135  1.45   nonaka 		watermark = IWM_SF_W_MARK_MIMO2;
   6136  1.45   nonaka 	}
   6137  1.45   nonaka 	sf_cmd->watermark[IWM_SF_FULL_ON] = htole32(watermark);
   6138  1.45   nonaka 
   6139  1.45   nonaka 	for (i = 0; i < IWM_SF_NUM_SCENARIO; i++) {
   6140  1.45   nonaka 		for (j = 0; j < IWM_SF_NUM_TIMEOUT_TYPES; j++) {
   6141  1.45   nonaka 			sf_cmd->long_delay_timeouts[i][j] =
   6142  1.45   nonaka 					htole32(IWM_SF_LONG_DELAY_AGING_TIMER);
   6143   1.1    pooka 		}
   6144  1.45   nonaka 	}
   6145  1.45   nonaka 
   6146  1.45   nonaka 	if (ni) {
   6147  1.45   nonaka 		memcpy(sf_cmd->full_on_timeouts, iwm_sf_full_timeout,
   6148  1.45   nonaka 		       sizeof(iwm_sf_full_timeout));
   6149   1.1    pooka 	} else {
   6150  1.45   nonaka 		memcpy(sf_cmd->full_on_timeouts, iwm_sf_full_timeout_def,
   6151  1.45   nonaka 		       sizeof(iwm_sf_full_timeout_def));
   6152  1.45   nonaka 	}
   6153  1.45   nonaka }
   6154  1.45   nonaka 
   6155  1.45   nonaka static int
   6156  1.45   nonaka iwm_sf_config(struct iwm_softc *sc, int new_state)
   6157  1.45   nonaka {
   6158  1.45   nonaka 	struct ieee80211com *ic = &sc->sc_ic;
   6159  1.45   nonaka 	struct iwm_sf_cfg_cmd sf_cmd = {
   6160  1.45   nonaka 		.state = htole32(IWM_SF_FULL_ON),
   6161  1.45   nonaka 	};
   6162  1.45   nonaka 
   6163  1.45   nonaka 	if (sc->sc_device_family == IWM_DEVICE_FAMILY_8000)
   6164  1.45   nonaka 		sf_cmd.state |= htole32(IWM_SF_CFG_DUMMY_NOTIF_OFF);
   6165  1.45   nonaka 
   6166  1.45   nonaka 	switch (new_state) {
   6167  1.45   nonaka 	case IWM_SF_UNINIT:
   6168  1.45   nonaka 	case IWM_SF_INIT_OFF:
   6169  1.45   nonaka 		iwm_fill_sf_command(sc, &sf_cmd, NULL);
   6170  1.45   nonaka 		break;
   6171  1.45   nonaka 	case IWM_SF_FULL_ON:
   6172  1.45   nonaka 		iwm_fill_sf_command(sc, &sf_cmd, ic->ic_bss);
   6173  1.45   nonaka 		break;
   6174  1.45   nonaka 	default:
   6175  1.45   nonaka 		return EINVAL;
   6176   1.1    pooka 	}
   6177   1.1    pooka 
   6178  1.45   nonaka 	return iwm_send_cmd_pdu(sc, IWM_REPLY_SF_CFG_CMD, IWM_CMD_ASYNC,
   6179  1.45   nonaka 	    sizeof(sf_cmd), &sf_cmd);
   6180  1.45   nonaka }
   6181  1.45   nonaka 
   6182  1.45   nonaka static int
   6183  1.45   nonaka iwm_send_bt_init_conf(struct iwm_softc *sc)
   6184  1.45   nonaka {
   6185  1.45   nonaka 	struct iwm_bt_coex_cmd bt_cmd;
   6186  1.45   nonaka 
   6187  1.45   nonaka 	bt_cmd.mode = htole32(IWM_BT_COEX_WIFI);
   6188  1.45   nonaka 	bt_cmd.enabled_modules = htole32(IWM_BT_COEX_HIGH_BAND_RET);
   6189  1.45   nonaka 
   6190  1.45   nonaka 	return iwm_send_cmd_pdu(sc, IWM_BT_CONFIG, 0, sizeof(bt_cmd), &bt_cmd);
   6191  1.45   nonaka }
   6192  1.45   nonaka 
   6193  1.60   nonaka static bool
   6194  1.60   nonaka iwm_is_lar_supported(struct iwm_softc *sc)
   6195  1.60   nonaka {
   6196  1.60   nonaka 	bool nvm_lar = sc->sc_nvm.lar_enabled;
   6197  1.60   nonaka 	bool tlv_lar = isset(sc->sc_enabled_capa,
   6198  1.60   nonaka 	    IWM_UCODE_TLV_CAPA_LAR_SUPPORT);
   6199  1.60   nonaka 
   6200  1.60   nonaka 	if (iwm_lar_disable)
   6201  1.60   nonaka 		return false;
   6202  1.60   nonaka 
   6203  1.60   nonaka 	/*
   6204  1.60   nonaka 	 * Enable LAR only if it is supported by the FW (TLV) &&
   6205  1.60   nonaka 	 * enabled in the NVM
   6206  1.60   nonaka 	 */
   6207  1.60   nonaka 	if (sc->sc_device_family == IWM_DEVICE_FAMILY_8000)
   6208  1.60   nonaka 		return nvm_lar && tlv_lar;
   6209  1.60   nonaka 	else
   6210  1.60   nonaka 		return tlv_lar;
   6211  1.60   nonaka }
   6212  1.60   nonaka 
   6213  1.45   nonaka static int
   6214  1.45   nonaka iwm_send_update_mcc_cmd(struct iwm_softc *sc, const char *alpha2)
   6215  1.45   nonaka {
   6216  1.45   nonaka 	struct iwm_mcc_update_cmd mcc_cmd;
   6217  1.45   nonaka 	struct iwm_host_cmd hcmd = {
   6218  1.45   nonaka 		.id = IWM_MCC_UPDATE_CMD,
   6219  1.45   nonaka 		.flags = IWM_CMD_WANT_SKB,
   6220  1.45   nonaka 		.data = { &mcc_cmd },
   6221  1.45   nonaka 	};
   6222  1.60   nonaka 	int err;
   6223  1.45   nonaka 	int resp_v2 = isset(sc->sc_enabled_capa,
   6224  1.45   nonaka 	    IWM_UCODE_TLV_CAPA_LAR_SUPPORT_V2);
   6225  1.60   nonaka 
   6226  1.60   nonaka 	if (!iwm_is_lar_supported(sc)) {
   6227  1.60   nonaka 		DPRINTF(("%s: no LAR support\n", __func__));
   6228  1.60   nonaka 		return 0;
   6229  1.60   nonaka 	}
   6230  1.45   nonaka 
   6231  1.45   nonaka 	memset(&mcc_cmd, 0, sizeof(mcc_cmd));
   6232  1.45   nonaka 	mcc_cmd.mcc = htole16(alpha2[0] << 8 | alpha2[1]);
   6233  1.45   nonaka 	if ((sc->sc_ucode_api & IWM_UCODE_TLV_API_WIFI_MCC_UPDATE) ||
   6234  1.45   nonaka 	    isset(sc->sc_enabled_capa, IWM_UCODE_TLV_CAPA_LAR_MULTI_MCC))
   6235  1.45   nonaka 		mcc_cmd.source_id = IWM_MCC_SOURCE_GET_CURRENT;
   6236  1.45   nonaka 	else
   6237  1.45   nonaka 		mcc_cmd.source_id = IWM_MCC_SOURCE_OLD_FW;
   6238  1.45   nonaka 
   6239  1.45   nonaka 	if (resp_v2)
   6240  1.45   nonaka 		hcmd.len[0] = sizeof(struct iwm_mcc_update_cmd);
   6241  1.45   nonaka 	else
   6242  1.45   nonaka 		hcmd.len[0] = sizeof(struct iwm_mcc_update_cmd_v1);
   6243  1.45   nonaka 
   6244  1.45   nonaka 	err = iwm_send_cmd(sc, &hcmd);
   6245  1.45   nonaka 	if (err)
   6246  1.45   nonaka 		return err;
   6247  1.45   nonaka 
   6248  1.45   nonaka 	iwm_free_resp(sc, &hcmd);
   6249  1.45   nonaka 
   6250  1.45   nonaka 	return 0;
   6251  1.45   nonaka }
   6252  1.45   nonaka 
   6253  1.45   nonaka static void
   6254  1.45   nonaka iwm_tt_tx_backoff(struct iwm_softc *sc, uint32_t backoff)
   6255  1.45   nonaka {
   6256  1.45   nonaka 	struct iwm_host_cmd cmd = {
   6257  1.45   nonaka 		.id = IWM_REPLY_THERMAL_MNG_BACKOFF,
   6258  1.45   nonaka 		.len = { sizeof(uint32_t), },
   6259  1.45   nonaka 		.data = { &backoff, },
   6260  1.45   nonaka 	};
   6261  1.45   nonaka 
   6262  1.45   nonaka 	iwm_send_cmd(sc, &cmd);
   6263   1.1    pooka }
   6264   1.1    pooka 
   6265   1.4   nonaka static int
   6266   1.1    pooka iwm_init_hw(struct iwm_softc *sc)
   6267   1.1    pooka {
   6268   1.1    pooka 	struct ieee80211com *ic = &sc->sc_ic;
   6269  1.45   nonaka 	int err, i, ac;
   6270   1.1    pooka 
   6271  1.45   nonaka 	err = iwm_preinit(sc);
   6272  1.45   nonaka 	if (err)
   6273  1.45   nonaka 		return err;
   6274   1.1    pooka 
   6275  1.45   nonaka 	err = iwm_start_hw(sc);
   6276  1.45   nonaka 	if (err) {
   6277  1.45   nonaka 		aprint_error_dev(sc->sc_dev, "could not initialize hardware\n");
   6278  1.45   nonaka 		return err;
   6279  1.45   nonaka 	}
   6280   1.1    pooka 
   6281  1.45   nonaka 	err = iwm_run_init_mvm_ucode(sc, 0);
   6282  1.45   nonaka 	if (err)
   6283  1.45   nonaka 		return err;
   6284   1.1    pooka 
   6285  1.45   nonaka 	/* Should stop and start HW since INIT image just loaded. */
   6286   1.1    pooka 	iwm_stop_device(sc);
   6287  1.45   nonaka 	err = iwm_start_hw(sc);
   6288  1.45   nonaka 	if (err) {
   6289   1.3   nonaka 		aprint_error_dev(sc->sc_dev, "could not initialize hardware\n");
   6290  1.45   nonaka 		return err;
   6291   1.2   nonaka 	}
   6292   1.1    pooka 
   6293  1.45   nonaka 	/* Restart, this time with the regular firmware */
   6294  1.45   nonaka 	err = iwm_load_ucode_wait_alive(sc, IWM_UCODE_TYPE_REGULAR);
   6295  1.45   nonaka 	if (err) {
   6296  1.61   nonaka 		aprint_error_dev(sc->sc_dev,
   6297  1.61   nonaka 		    "could not load firmware (error %d)\n", err);
   6298  1.45   nonaka 		goto err;
   6299  1.45   nonaka 	}
   6300  1.45   nonaka 
   6301  1.45   nonaka 	err = iwm_send_bt_init_conf(sc);
   6302  1.45   nonaka 	if (err) {
   6303  1.45   nonaka 		aprint_error_dev(sc->sc_dev,
   6304  1.45   nonaka 		    "could not init bt coex (error %d)\n", err);
   6305  1.45   nonaka 		goto err;
   6306   1.1    pooka 	}
   6307   1.1    pooka 
   6308  1.45   nonaka 	err = iwm_send_tx_ant_cfg(sc, iwm_fw_valid_tx_ant(sc));
   6309  1.45   nonaka 	if (err) {
   6310  1.45   nonaka 		aprint_error_dev(sc->sc_dev,
   6311  1.45   nonaka 		    "could not init tx ant config (error %d)\n", err);
   6312  1.45   nonaka 		goto err;
   6313  1.45   nonaka 	}
   6314   1.1    pooka 
   6315   1.8   nonaka 	/* Send phy db control command and then phy db calibration*/
   6316  1.45   nonaka 	err = iwm_send_phy_db_data(sc);
   6317  1.45   nonaka 	if (err) {
   6318  1.45   nonaka 		aprint_error_dev(sc->sc_dev,
   6319  1.45   nonaka 		    "could not init phy db (error %d)\n", err);
   6320  1.45   nonaka 		goto err;
   6321  1.45   nonaka 	}
   6322   1.1    pooka 
   6323  1.45   nonaka 	err = iwm_send_phy_cfg_cmd(sc);
   6324  1.45   nonaka 	if (err) {
   6325  1.45   nonaka 		aprint_error_dev(sc->sc_dev,
   6326  1.45   nonaka 		    "could not send phy config (error %d)\n", err);
   6327  1.45   nonaka 		goto err;
   6328  1.45   nonaka 	}
   6329   1.1    pooka 
   6330   1.1    pooka 	/* Add auxiliary station for scanning */
   6331  1.45   nonaka 	err = iwm_add_aux_sta(sc);
   6332  1.45   nonaka 	if (err) {
   6333  1.45   nonaka 		aprint_error_dev(sc->sc_dev,
   6334  1.45   nonaka 		    "could not add aux station (error %d)\n", err);
   6335  1.45   nonaka 		goto err;
   6336  1.45   nonaka 	}
   6337   1.1    pooka 
   6338   1.1    pooka 	for (i = 0; i < IWM_NUM_PHY_CTX; i++) {
   6339   1.1    pooka 		/*
   6340   1.1    pooka 		 * The channel used here isn't relevant as it's
   6341   1.1    pooka 		 * going to be overwritten in the other flows.
   6342   1.1    pooka 		 * For now use the first channel we have.
   6343   1.1    pooka 		 */
   6344  1.45   nonaka 		sc->sc_phyctxt[i].channel = &ic->ic_channels[1];
   6345  1.45   nonaka 		err = iwm_phy_ctxt_cmd(sc, &sc->sc_phyctxt[i], 1, 1,
   6346  1.45   nonaka 		    IWM_FW_CTXT_ACTION_ADD, 0);
   6347  1.45   nonaka 		if (err) {
   6348  1.45   nonaka 			aprint_error_dev(sc->sc_dev,
   6349  1.45   nonaka 			    "could not add phy context %d (error %d)\n",
   6350  1.45   nonaka 			    i, err);
   6351  1.45   nonaka 			goto err;
   6352  1.45   nonaka 		}
   6353  1.45   nonaka 	}
   6354  1.45   nonaka 
   6355  1.45   nonaka 	/* Initialize tx backoffs to the minimum. */
   6356  1.45   nonaka 	if (sc->sc_device_family == IWM_DEVICE_FAMILY_7000)
   6357  1.45   nonaka 		iwm_tt_tx_backoff(sc, 0);
   6358  1.45   nonaka 
   6359  1.45   nonaka 	err = iwm_power_update_device(sc);
   6360  1.45   nonaka 	if (err) {
   6361  1.45   nonaka 		aprint_error_dev(sc->sc_dev,
   6362  1.45   nonaka 		    "could send power command (error %d)\n", err);
   6363  1.45   nonaka 		goto err;
   6364  1.45   nonaka 	}
   6365  1.45   nonaka 
   6366  1.61   nonaka 	err = iwm_send_update_mcc_cmd(sc, iwm_default_mcc);
   6367  1.60   nonaka 	if (err) {
   6368  1.60   nonaka 		aprint_error_dev(sc->sc_dev,
   6369  1.60   nonaka 		    "could not init LAR (error %d)\n", err);
   6370  1.60   nonaka 		goto err;
   6371  1.45   nonaka 	}
   6372  1.45   nonaka 
   6373  1.45   nonaka 	if (isset(sc->sc_enabled_capa, IWM_UCODE_TLV_CAPA_UMAC_SCAN)) {
   6374  1.45   nonaka 		err = iwm_config_umac_scan(sc);
   6375  1.45   nonaka 		if (err) {
   6376  1.45   nonaka 			aprint_error_dev(sc->sc_dev,
   6377  1.45   nonaka 			    "could not configure scan (error %d)\n", err);
   6378  1.45   nonaka 			goto err;
   6379  1.45   nonaka 		}
   6380  1.45   nonaka 	}
   6381  1.45   nonaka 
   6382  1.45   nonaka 	for (ac = 0; ac < WME_NUM_AC; ac++) {
   6383  1.45   nonaka 		err = iwm_enable_txq(sc, IWM_STATION_ID, ac,
   6384  1.45   nonaka 		    iwm_ac_to_tx_fifo[ac]);
   6385  1.45   nonaka 		if (err) {
   6386  1.45   nonaka 			aprint_error_dev(sc->sc_dev,
   6387  1.45   nonaka 			    "could not enable Tx queue %d (error %d)\n",
   6388  1.45   nonaka 			    i, err);
   6389  1.45   nonaka 			goto err;
   6390  1.45   nonaka 		}
   6391   1.1    pooka 	}
   6392   1.1    pooka 
   6393  1.45   nonaka 	err = iwm_disable_beacon_filter(sc);
   6394  1.45   nonaka 	if (err) {
   6395  1.45   nonaka 		aprint_error_dev(sc->sc_dev,
   6396  1.45   nonaka 		    "could not disable beacon filter (error %d)\n", err);
   6397  1.45   nonaka 		goto err;
   6398   1.1    pooka 	}
   6399   1.1    pooka 
   6400   1.1    pooka 	return 0;
   6401   1.1    pooka 
   6402  1.45   nonaka  err:
   6403   1.1    pooka 	iwm_stop_device(sc);
   6404  1.45   nonaka 	return err;
   6405   1.1    pooka }
   6406   1.1    pooka 
   6407  1.11   nonaka /* Allow multicast from our BSSID. */
   6408  1.11   nonaka static int
   6409  1.11   nonaka iwm_allow_mcast(struct iwm_softc *sc)
   6410  1.11   nonaka {
   6411  1.11   nonaka 	struct ieee80211com *ic = &sc->sc_ic;
   6412  1.11   nonaka 	struct ieee80211_node *ni = ic->ic_bss;
   6413  1.11   nonaka 	struct iwm_mcast_filter_cmd *cmd;
   6414  1.11   nonaka 	size_t size;
   6415  1.45   nonaka 	int err;
   6416  1.11   nonaka 
   6417  1.11   nonaka 	size = roundup(sizeof(*cmd), 4);
   6418  1.11   nonaka 	cmd = kmem_intr_zalloc(size, KM_NOSLEEP);
   6419  1.11   nonaka 	if (cmd == NULL)
   6420  1.11   nonaka 		return ENOMEM;
   6421  1.11   nonaka 	cmd->filter_own = 1;
   6422  1.11   nonaka 	cmd->port_id = 0;
   6423  1.11   nonaka 	cmd->count = 0;
   6424  1.11   nonaka 	cmd->pass_all = 1;
   6425  1.11   nonaka 	IEEE80211_ADDR_COPY(cmd->bssid, ni->ni_bssid);
   6426  1.11   nonaka 
   6427  1.45   nonaka 	err = iwm_send_cmd_pdu(sc, IWM_MCAST_FILTER_CMD, 0, size, cmd);
   6428  1.11   nonaka 	kmem_intr_free(cmd, size);
   6429  1.45   nonaka 	return err;
   6430  1.11   nonaka }
   6431  1.11   nonaka 
   6432   1.4   nonaka static int
   6433   1.1    pooka iwm_init(struct ifnet *ifp)
   6434   1.1    pooka {
   6435   1.1    pooka 	struct iwm_softc *sc = ifp->if_softc;
   6436  1.45   nonaka 	int err;
   6437   1.1    pooka 
   6438  1.45   nonaka 	if (ISSET(sc->sc_flags, IWM_FLAG_HW_INITED))
   6439   1.1    pooka 		return 0;
   6440  1.45   nonaka 
   6441   1.1    pooka 	sc->sc_generation++;
   6442   1.1    pooka 	sc->sc_flags &= ~IWM_FLAG_STOPPED;
   6443   1.1    pooka 
   6444  1.45   nonaka 	err = iwm_init_hw(sc);
   6445  1.45   nonaka 	if (err) {
   6446   1.1    pooka 		iwm_stop(ifp, 1);
   6447  1.45   nonaka 		return err;
   6448   1.1    pooka 	}
   6449   1.1    pooka 
   6450   1.1    pooka 	ifp->if_flags &= ~IFF_OACTIVE;
   6451   1.1    pooka 	ifp->if_flags |= IFF_RUNNING;
   6452   1.1    pooka 
   6453   1.1    pooka 	ieee80211_begin_scan(&sc->sc_ic, 0);
   6454  1.45   nonaka 	SET(sc->sc_flags, IWM_FLAG_HW_INITED);
   6455   1.1    pooka 
   6456   1.1    pooka 	return 0;
   6457   1.1    pooka }
   6458   1.1    pooka 
   6459   1.4   nonaka static void
   6460   1.1    pooka iwm_start(struct ifnet *ifp)
   6461   1.1    pooka {
   6462   1.1    pooka 	struct iwm_softc *sc = ifp->if_softc;
   6463   1.1    pooka 	struct ieee80211com *ic = &sc->sc_ic;
   6464   1.1    pooka 	struct ieee80211_node *ni;
   6465   1.8   nonaka 	struct ether_header *eh;
   6466   1.1    pooka 	struct mbuf *m;
   6467   1.1    pooka 	int ac;
   6468   1.1    pooka 
   6469   1.1    pooka 	if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
   6470   1.1    pooka 		return;
   6471   1.1    pooka 
   6472   1.1    pooka 	for (;;) {
   6473   1.1    pooka 		/* why isn't this done per-queue? */
   6474   1.1    pooka 		if (sc->qfullmsk != 0) {
   6475   1.1    pooka 			ifp->if_flags |= IFF_OACTIVE;
   6476   1.1    pooka 			break;
   6477   1.1    pooka 		}
   6478   1.1    pooka 
   6479   1.1    pooka 		/* need to send management frames even if we're not RUNning */
   6480   1.1    pooka 		IF_DEQUEUE(&ic->ic_mgtq, m);
   6481   1.1    pooka 		if (m) {
   6482  1.41    ozaki 			ni = M_GETCTX(m, struct ieee80211_node *);
   6483  1.50   nonaka 			M_CLEARCTX(m);
   6484  1.45   nonaka 			ac = WME_AC_BE;
   6485   1.1    pooka 			goto sendit;
   6486   1.1    pooka 		}
   6487   1.1    pooka 		if (ic->ic_state != IEEE80211_S_RUN) {
   6488   1.1    pooka 			break;
   6489   1.1    pooka 		}
   6490   1.1    pooka 
   6491   1.1    pooka 		IFQ_DEQUEUE(&ifp->if_snd, m);
   6492  1.50   nonaka 		if (m == NULL)
   6493   1.1    pooka 			break;
   6494  1.50   nonaka 
   6495   1.8   nonaka 		if (m->m_len < sizeof (*eh) &&
   6496   1.8   nonaka 		   (m = m_pullup(m, sizeof (*eh))) == NULL) {
   6497   1.8   nonaka 			ifp->if_oerrors++;
   6498   1.8   nonaka 			continue;
   6499   1.8   nonaka 		}
   6500   1.1    pooka 
   6501   1.1    pooka 		eh = mtod(m, struct ether_header *);
   6502   1.1    pooka 		ni = ieee80211_find_txnode(ic, eh->ether_dhost);
   6503   1.1    pooka 		if (ni == NULL) {
   6504   1.1    pooka 			m_freem(m);
   6505   1.1    pooka 			ifp->if_oerrors++;
   6506   1.1    pooka 			continue;
   6507   1.1    pooka 		}
   6508  1.50   nonaka 
   6509   1.1    pooka 		/* classify mbuf so we can find which tx ring to use */
   6510   1.1    pooka 		if (ieee80211_classify(ic, m, ni) != 0) {
   6511   1.1    pooka 			m_freem(m);
   6512   1.1    pooka 			ieee80211_free_node(ni);
   6513   1.1    pooka 			ifp->if_oerrors++;
   6514   1.1    pooka 			continue;
   6515   1.1    pooka 		}
   6516   1.1    pooka 
   6517   1.1    pooka 		/* No QoS encapsulation for EAPOL frames. */
   6518   1.1    pooka 		ac = (eh->ether_type != htons(ETHERTYPE_PAE)) ?
   6519   1.1    pooka 		    M_WME_GETAC(m) : WME_AC_BE;
   6520   1.1    pooka 
   6521  1.48   nonaka 		bpf_mtap(ifp, m);
   6522  1.48   nonaka 
   6523   1.1    pooka 		if ((m = ieee80211_encap(ic, m, ni)) == NULL) {
   6524   1.1    pooka 			ieee80211_free_node(ni);
   6525   1.1    pooka 			ifp->if_oerrors++;
   6526   1.1    pooka 			continue;
   6527   1.1    pooka 		}
   6528   1.1    pooka 
   6529   1.1    pooka  sendit:
   6530  1.48   nonaka 		bpf_mtap3(ic->ic_rawbpf, m);
   6531  1.48   nonaka 
   6532   1.1    pooka 		if (iwm_tx(sc, m, ni, ac) != 0) {
   6533   1.1    pooka 			ieee80211_free_node(ni);
   6534   1.1    pooka 			ifp->if_oerrors++;
   6535   1.1    pooka 			continue;
   6536   1.1    pooka 		}
   6537   1.1    pooka 
   6538   1.1    pooka 		if (ifp->if_flags & IFF_UP) {
   6539   1.1    pooka 			sc->sc_tx_timer = 15;
   6540   1.1    pooka 			ifp->if_timer = 1;
   6541   1.1    pooka 		}
   6542   1.1    pooka 	}
   6543   1.1    pooka }
   6544   1.1    pooka 
   6545   1.4   nonaka static void
   6546   1.1    pooka iwm_stop(struct ifnet *ifp, int disable)
   6547   1.1    pooka {
   6548   1.1    pooka 	struct iwm_softc *sc = ifp->if_softc;
   6549   1.1    pooka 	struct ieee80211com *ic = &sc->sc_ic;
   6550  1.45   nonaka 	struct iwm_node *in = (struct iwm_node *)ic->ic_bss;
   6551   1.1    pooka 
   6552   1.1    pooka 	sc->sc_flags &= ~IWM_FLAG_HW_INITED;
   6553   1.1    pooka 	sc->sc_flags |= IWM_FLAG_STOPPED;
   6554   1.1    pooka 	sc->sc_generation++;
   6555   1.1    pooka 	ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
   6556   1.1    pooka 
   6557  1.45   nonaka 	if (in)
   6558  1.45   nonaka 		in->in_phyctxt = NULL;
   6559  1.45   nonaka 
   6560   1.1    pooka 	if (ic->ic_state != IEEE80211_S_INIT)
   6561   1.1    pooka 		ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
   6562   1.1    pooka 
   6563  1.26   nonaka 	callout_stop(&sc->sc_calib_to);
   6564  1.45   nonaka 	iwm_led_blink_stop(sc);
   6565   1.1    pooka 	ifp->if_timer = sc->sc_tx_timer = 0;
   6566   1.1    pooka 	iwm_stop_device(sc);
   6567   1.1    pooka }
   6568   1.1    pooka 
   6569   1.4   nonaka static void
   6570   1.1    pooka iwm_watchdog(struct ifnet *ifp)
   6571   1.1    pooka {
   6572   1.1    pooka 	struct iwm_softc *sc = ifp->if_softc;
   6573   1.1    pooka 
   6574   1.1    pooka 	ifp->if_timer = 0;
   6575   1.1    pooka 	if (sc->sc_tx_timer > 0) {
   6576   1.1    pooka 		if (--sc->sc_tx_timer == 0) {
   6577   1.5   nonaka 			aprint_error_dev(sc->sc_dev, "device timeout\n");
   6578   1.2   nonaka #ifdef IWM_DEBUG
   6579   1.1    pooka 			iwm_nic_error(sc);
   6580   1.2   nonaka #endif
   6581   1.1    pooka 			ifp->if_flags &= ~IFF_UP;
   6582   1.1    pooka 			iwm_stop(ifp, 1);
   6583   1.1    pooka 			ifp->if_oerrors++;
   6584   1.1    pooka 			return;
   6585   1.1    pooka 		}
   6586   1.1    pooka 		ifp->if_timer = 1;
   6587   1.1    pooka 	}
   6588   1.1    pooka 
   6589   1.1    pooka 	ieee80211_watchdog(&sc->sc_ic);
   6590   1.1    pooka }
   6591   1.1    pooka 
   6592   1.4   nonaka static int
   6593   1.1    pooka iwm_ioctl(struct ifnet *ifp, u_long cmd, void *data)
   6594   1.1    pooka {
   6595   1.1    pooka 	struct iwm_softc *sc = ifp->if_softc;
   6596   1.1    pooka 	struct ieee80211com *ic = &sc->sc_ic;
   6597   1.1    pooka 	const struct sockaddr *sa;
   6598  1.45   nonaka 	int s, err = 0;
   6599   1.1    pooka 
   6600   1.1    pooka 	s = splnet();
   6601   1.1    pooka 
   6602   1.1    pooka 	switch (cmd) {
   6603   1.1    pooka 	case SIOCSIFADDR:
   6604   1.1    pooka 		ifp->if_flags |= IFF_UP;
   6605   1.1    pooka 		/* FALLTHROUGH */
   6606   1.1    pooka 	case SIOCSIFFLAGS:
   6607  1.45   nonaka 		err = ifioctl_common(ifp, cmd, data);
   6608  1.45   nonaka 		if (err)
   6609   1.1    pooka 			break;
   6610   1.1    pooka 		if (ifp->if_flags & IFF_UP) {
   6611   1.1    pooka 			if (!(ifp->if_flags & IFF_RUNNING)) {
   6612  1.45   nonaka 				err = iwm_init(ifp);
   6613  1.45   nonaka 				if (err)
   6614   1.1    pooka 					ifp->if_flags &= ~IFF_UP;
   6615   1.1    pooka 			}
   6616   1.1    pooka 		} else {
   6617   1.1    pooka 			if (ifp->if_flags & IFF_RUNNING)
   6618   1.1    pooka 				iwm_stop(ifp, 1);
   6619   1.1    pooka 		}
   6620   1.1    pooka 		break;
   6621   1.1    pooka 
   6622   1.1    pooka 	case SIOCADDMULTI:
   6623   1.1    pooka 	case SIOCDELMULTI:
   6624  1.36   nonaka 		if (!ISSET(sc->sc_flags, IWM_FLAG_ATTACHED)) {
   6625  1.45   nonaka 			err = ENXIO;
   6626  1.36   nonaka 			break;
   6627  1.36   nonaka 		}
   6628   1.1    pooka 		sa = ifreq_getaddr(SIOCADDMULTI, (struct ifreq *)data);
   6629  1.45   nonaka 		err = (cmd == SIOCADDMULTI) ?
   6630   1.1    pooka 		    ether_addmulti(sa, &sc->sc_ec) :
   6631   1.1    pooka 		    ether_delmulti(sa, &sc->sc_ec);
   6632  1.45   nonaka 		if (err == ENETRESET)
   6633  1.45   nonaka 			err = 0;
   6634   1.1    pooka 		break;
   6635   1.1    pooka 
   6636   1.1    pooka 	default:
   6637  1.36   nonaka 		if (!ISSET(sc->sc_flags, IWM_FLAG_ATTACHED)) {
   6638  1.45   nonaka 			err = ether_ioctl(ifp, cmd, data);
   6639  1.36   nonaka 			break;
   6640  1.36   nonaka 		}
   6641  1.45   nonaka 		err = ieee80211_ioctl(ic, cmd, data);
   6642  1.36   nonaka 		break;
   6643   1.1    pooka 	}
   6644   1.1    pooka 
   6645  1.45   nonaka 	if (err == ENETRESET) {
   6646  1.45   nonaka 		err = 0;
   6647   1.1    pooka 		if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
   6648   1.1    pooka 		    (IFF_UP | IFF_RUNNING)) {
   6649   1.1    pooka 			iwm_stop(ifp, 0);
   6650  1.45   nonaka 			err = iwm_init(ifp);
   6651   1.1    pooka 		}
   6652   1.1    pooka 	}
   6653   1.1    pooka 
   6654   1.1    pooka 	splx(s);
   6655  1.45   nonaka 	return err;
   6656   1.1    pooka }
   6657   1.1    pooka 
   6658   1.1    pooka /*
   6659   1.1    pooka  * Note: This structure is read from the device with IO accesses,
   6660   1.1    pooka  * and the reading already does the endian conversion. As it is
   6661   1.1    pooka  * read with uint32_t-sized accesses, any members with a different size
   6662   1.1    pooka  * need to be ordered correctly though!
   6663   1.1    pooka  */
   6664   1.1    pooka struct iwm_error_event_table {
   6665   1.1    pooka 	uint32_t valid;		/* (nonzero) valid, (0) log is empty */
   6666   1.1    pooka 	uint32_t error_id;		/* type of error */
   6667  1.45   nonaka 	uint32_t trm_hw_status0;	/* TRM HW status */
   6668  1.45   nonaka 	uint32_t trm_hw_status1;	/* TRM HW status */
   6669   1.1    pooka 	uint32_t blink2;		/* branch link */
   6670   1.1    pooka 	uint32_t ilink1;		/* interrupt link */
   6671   1.1    pooka 	uint32_t ilink2;		/* interrupt link */
   6672   1.1    pooka 	uint32_t data1;		/* error-specific data */
   6673   1.1    pooka 	uint32_t data2;		/* error-specific data */
   6674   1.1    pooka 	uint32_t data3;		/* error-specific data */
   6675   1.1    pooka 	uint32_t bcon_time;		/* beacon timer */
   6676   1.1    pooka 	uint32_t tsf_low;		/* network timestamp function timer */
   6677   1.1    pooka 	uint32_t tsf_hi;		/* network timestamp function timer */
   6678   1.1    pooka 	uint32_t gp1;		/* GP1 timer register */
   6679   1.1    pooka 	uint32_t gp2;		/* GP2 timer register */
   6680  1.45   nonaka 	uint32_t fw_rev_type;	/* firmware revision type */
   6681  1.45   nonaka 	uint32_t major;		/* uCode version major */
   6682  1.45   nonaka 	uint32_t minor;		/* uCode version minor */
   6683   1.1    pooka 	uint32_t hw_ver;		/* HW Silicon version */
   6684   1.1    pooka 	uint32_t brd_ver;		/* HW board version */
   6685   1.1    pooka 	uint32_t log_pc;		/* log program counter */
   6686   1.1    pooka 	uint32_t frame_ptr;		/* frame pointer */
   6687   1.1    pooka 	uint32_t stack_ptr;		/* stack pointer */
   6688   1.1    pooka 	uint32_t hcmd;		/* last host command header */
   6689   1.1    pooka 	uint32_t isr0;		/* isr status register LMPM_NIC_ISR0:
   6690   1.1    pooka 				 * rxtx_flag */
   6691   1.1    pooka 	uint32_t isr1;		/* isr status register LMPM_NIC_ISR1:
   6692   1.1    pooka 				 * host_flag */
   6693   1.1    pooka 	uint32_t isr2;		/* isr status register LMPM_NIC_ISR2:
   6694   1.1    pooka 				 * enc_flag */
   6695   1.1    pooka 	uint32_t isr3;		/* isr status register LMPM_NIC_ISR3:
   6696   1.1    pooka 				 * time_flag */
   6697   1.1    pooka 	uint32_t isr4;		/* isr status register LMPM_NIC_ISR4:
   6698   1.1    pooka 				 * wico interrupt */
   6699  1.45   nonaka 	uint32_t last_cmd_id;	/* last HCMD id handled by the firmware */
   6700   1.1    pooka 	uint32_t wait_event;		/* wait event() caller address */
   6701   1.1    pooka 	uint32_t l2p_control;	/* L2pControlField */
   6702   1.1    pooka 	uint32_t l2p_duration;	/* L2pDurationField */
   6703   1.1    pooka 	uint32_t l2p_mhvalid;	/* L2pMhValidBits */
   6704   1.1    pooka 	uint32_t l2p_addr_match;	/* L2pAddrMatchStat */
   6705   1.1    pooka 	uint32_t lmpm_pmg_sel;	/* indicate which clocks are turned on
   6706   1.1    pooka 				 * (LMPM_PMG_SEL) */
   6707   1.1    pooka 	uint32_t u_timestamp;	/* indicate when the date and time of the
   6708   1.1    pooka 				 * compilation */
   6709   1.1    pooka 	uint32_t flow_handler;	/* FH read/write pointers, RX credit */
   6710  1.45   nonaka } __packed /* LOG_ERROR_TABLE_API_S_VER_3 */;
   6711  1.45   nonaka 
   6712  1.45   nonaka /*
   6713  1.45   nonaka  * UMAC error struct - relevant starting from family 8000 chip.
   6714  1.45   nonaka  * Note: This structure is read from the device with IO accesses,
   6715  1.45   nonaka  * and the reading already does the endian conversion. As it is
   6716  1.45   nonaka  * read with u32-sized accesses, any members with a different size
   6717  1.45   nonaka  * need to be ordered correctly though!
   6718  1.45   nonaka  */
   6719  1.45   nonaka struct iwm_umac_error_event_table {
   6720  1.45   nonaka 	uint32_t valid;		/* (nonzero) valid, (0) log is empty */
   6721  1.45   nonaka 	uint32_t error_id;	/* type of error */
   6722  1.45   nonaka 	uint32_t blink1;	/* branch link */
   6723  1.45   nonaka 	uint32_t blink2;	/* branch link */
   6724  1.45   nonaka 	uint32_t ilink1;	/* interrupt link */
   6725  1.45   nonaka 	uint32_t ilink2;	/* interrupt link */
   6726  1.45   nonaka 	uint32_t data1;		/* error-specific data */
   6727  1.45   nonaka 	uint32_t data2;		/* error-specific data */
   6728  1.45   nonaka 	uint32_t data3;		/* error-specific data */
   6729  1.45   nonaka 	uint32_t umac_major;
   6730  1.45   nonaka 	uint32_t umac_minor;
   6731  1.45   nonaka 	uint32_t frame_pointer;	/* core register 27 */
   6732  1.45   nonaka 	uint32_t stack_pointer;	/* core register 28 */
   6733  1.45   nonaka 	uint32_t cmd_header;	/* latest host cmd sent to UMAC */
   6734  1.45   nonaka 	uint32_t nic_isr_pref;	/* ISR status register */
   6735   1.1    pooka } __packed;
   6736   1.1    pooka 
   6737   1.1    pooka #define ERROR_START_OFFSET  (1 * sizeof(uint32_t))
   6738   1.1    pooka #define ERROR_ELEM_SIZE     (7 * sizeof(uint32_t))
   6739   1.1    pooka 
   6740   1.4   nonaka #ifdef IWM_DEBUG
   6741   1.4   nonaka static const struct {
   6742   1.1    pooka 	const char *name;
   6743   1.1    pooka 	uint8_t num;
   6744   1.1    pooka } advanced_lookup[] = {
   6745   1.1    pooka 	{ "NMI_INTERRUPT_WDG", 0x34 },
   6746   1.1    pooka 	{ "SYSASSERT", 0x35 },
   6747   1.1    pooka 	{ "UCODE_VERSION_MISMATCH", 0x37 },
   6748   1.1    pooka 	{ "BAD_COMMAND", 0x38 },
   6749   1.1    pooka 	{ "NMI_INTERRUPT_DATA_ACTION_PT", 0x3C },
   6750   1.1    pooka 	{ "FATAL_ERROR", 0x3D },
   6751   1.1    pooka 	{ "NMI_TRM_HW_ERR", 0x46 },
   6752   1.1    pooka 	{ "NMI_INTERRUPT_TRM", 0x4C },
   6753   1.1    pooka 	{ "NMI_INTERRUPT_BREAK_POINT", 0x54 },
   6754   1.1    pooka 	{ "NMI_INTERRUPT_WDG_RXF_FULL", 0x5C },
   6755   1.1    pooka 	{ "NMI_INTERRUPT_WDG_NO_RBD_RXF_FULL", 0x64 },
   6756   1.1    pooka 	{ "NMI_INTERRUPT_HOST", 0x66 },
   6757   1.1    pooka 	{ "NMI_INTERRUPT_ACTION_PT", 0x7C },
   6758   1.1    pooka 	{ "NMI_INTERRUPT_UNKNOWN", 0x84 },
   6759   1.1    pooka 	{ "NMI_INTERRUPT_INST_ACTION_PT", 0x86 },
   6760   1.1    pooka 	{ "ADVANCED_SYSASSERT", 0 },
   6761   1.1    pooka };
   6762   1.1    pooka 
   6763   1.4   nonaka static const char *
   6764   1.1    pooka iwm_desc_lookup(uint32_t num)
   6765   1.1    pooka {
   6766   1.1    pooka 	int i;
   6767   1.1    pooka 
   6768   1.1    pooka 	for (i = 0; i < __arraycount(advanced_lookup) - 1; i++)
   6769   1.1    pooka 		if (advanced_lookup[i].num == num)
   6770   1.1    pooka 			return advanced_lookup[i].name;
   6771   1.1    pooka 
   6772   1.1    pooka 	/* No entry matches 'num', so it is the last: ADVANCED_SYSASSERT */
   6773   1.1    pooka 	return advanced_lookup[i].name;
   6774   1.1    pooka }
   6775   1.1    pooka 
   6776   1.1    pooka /*
   6777   1.1    pooka  * Support for dumping the error log seemed like a good idea ...
   6778   1.1    pooka  * but it's mostly hex junk and the only sensible thing is the
   6779   1.1    pooka  * hw/ucode revision (which we know anyway).  Since it's here,
   6780   1.1    pooka  * I'll just leave it in, just in case e.g. the Intel guys want to
   6781   1.1    pooka  * help us decipher some "ADVANCED_SYSASSERT" later.
   6782   1.1    pooka  */
   6783   1.4   nonaka static void
   6784   1.1    pooka iwm_nic_error(struct iwm_softc *sc)
   6785   1.1    pooka {
   6786  1.45   nonaka 	struct iwm_error_event_table t;
   6787   1.1    pooka 	uint32_t base;
   6788   1.1    pooka 
   6789   1.3   nonaka 	aprint_error_dev(sc->sc_dev, "dumping device error log\n");
   6790   1.1    pooka 	base = sc->sc_uc.uc_error_event_table;
   6791  1.45   nonaka 	if (base < 0x800000) {
   6792   1.3   nonaka 		aprint_error_dev(sc->sc_dev,
   6793  1.45   nonaka 		    "Invalid error log pointer 0x%08x\n", base);
   6794   1.1    pooka 		return;
   6795   1.1    pooka 	}
   6796   1.1    pooka 
   6797  1.45   nonaka 	if (iwm_read_mem(sc, base, &t, sizeof(t)/sizeof(uint32_t))) {
   6798   1.3   nonaka 		aprint_error_dev(sc->sc_dev, "reading errlog failed\n");
   6799   1.1    pooka 		return;
   6800   1.1    pooka 	}
   6801   1.1    pooka 
   6802  1.45   nonaka 	if (!t.valid) {
   6803   1.3   nonaka 		aprint_error_dev(sc->sc_dev, "errlog not found, skipping\n");
   6804   1.1    pooka 		return;
   6805   1.1    pooka 	}
   6806   1.1    pooka 
   6807  1.45   nonaka 	if (ERROR_START_OFFSET <= t.valid * ERROR_ELEM_SIZE) {
   6808  1.45   nonaka 		aprint_error_dev(sc->sc_dev, "Start Error Log Dump:\n");
   6809   1.3   nonaka 		aprint_error_dev(sc->sc_dev, "Status: 0x%x, count: %d\n",
   6810  1.45   nonaka 		    sc->sc_flags, t.valid);
   6811   1.1    pooka 	}
   6812   1.1    pooka 
   6813  1.45   nonaka 	aprint_error_dev(sc->sc_dev, "%08X | %-28s\n", t.error_id,
   6814  1.45   nonaka 	    iwm_desc_lookup(t.error_id));
   6815  1.45   nonaka 	aprint_error_dev(sc->sc_dev, "%08X | trm_hw_status0\n",
   6816  1.45   nonaka 	    t.trm_hw_status0);
   6817  1.45   nonaka 	aprint_error_dev(sc->sc_dev, "%08X | trm_hw_status1\n",
   6818  1.45   nonaka 	    t.trm_hw_status1);
   6819  1.45   nonaka 	aprint_error_dev(sc->sc_dev, "%08X | branchlink2\n", t.blink2);
   6820  1.45   nonaka 	aprint_error_dev(sc->sc_dev, "%08X | interruptlink1\n", t.ilink1);
   6821  1.45   nonaka 	aprint_error_dev(sc->sc_dev, "%08X | interruptlink2\n", t.ilink2);
   6822  1.45   nonaka 	aprint_error_dev(sc->sc_dev, "%08X | data1\n", t.data1);
   6823  1.45   nonaka 	aprint_error_dev(sc->sc_dev, "%08X | data2\n", t.data2);
   6824  1.45   nonaka 	aprint_error_dev(sc->sc_dev, "%08X | data3\n", t.data3);
   6825  1.45   nonaka 	aprint_error_dev(sc->sc_dev, "%08X | beacon time\n", t.bcon_time);
   6826  1.45   nonaka 	aprint_error_dev(sc->sc_dev, "%08X | tsf low\n", t.tsf_low);
   6827  1.45   nonaka 	aprint_error_dev(sc->sc_dev, "%08X | tsf hi\n", t.tsf_hi);
   6828  1.45   nonaka 	aprint_error_dev(sc->sc_dev, "%08X | time gp1\n", t.gp1);
   6829  1.45   nonaka 	aprint_error_dev(sc->sc_dev, "%08X | time gp2\n", t.gp2);
   6830  1.45   nonaka 	aprint_error_dev(sc->sc_dev, "%08X | uCode revision type\n",
   6831  1.45   nonaka 	    t.fw_rev_type);
   6832  1.45   nonaka 	aprint_error_dev(sc->sc_dev, "%08X | uCode version major\n",
   6833  1.45   nonaka 	    t.major);
   6834  1.45   nonaka 	aprint_error_dev(sc->sc_dev, "%08X | uCode version minor\n",
   6835  1.45   nonaka 	    t.minor);
   6836  1.45   nonaka 	aprint_error_dev(sc->sc_dev, "%08X | hw version\n", t.hw_ver);
   6837  1.45   nonaka 	aprint_error_dev(sc->sc_dev, "%08X | board version\n", t.brd_ver);
   6838  1.45   nonaka 	aprint_error_dev(sc->sc_dev, "%08X | hcmd\n", t.hcmd);
   6839  1.45   nonaka 	aprint_error_dev(sc->sc_dev, "%08X | isr0\n", t.isr0);
   6840  1.45   nonaka 	aprint_error_dev(sc->sc_dev, "%08X | isr1\n", t.isr1);
   6841  1.45   nonaka 	aprint_error_dev(sc->sc_dev, "%08X | isr2\n", t.isr2);
   6842  1.45   nonaka 	aprint_error_dev(sc->sc_dev, "%08X | isr3\n", t.isr3);
   6843  1.45   nonaka 	aprint_error_dev(sc->sc_dev, "%08X | isr4\n", t.isr4);
   6844  1.45   nonaka 	aprint_error_dev(sc->sc_dev, "%08X | last cmd Id\n", t.last_cmd_id);
   6845  1.45   nonaka 	aprint_error_dev(sc->sc_dev, "%08X | wait_event\n", t.wait_event);
   6846  1.45   nonaka 	aprint_error_dev(sc->sc_dev, "%08X | l2p_control\n", t.l2p_control);
   6847  1.45   nonaka 	aprint_error_dev(sc->sc_dev, "%08X | l2p_duration\n", t.l2p_duration);
   6848  1.45   nonaka 	aprint_error_dev(sc->sc_dev, "%08X | l2p_mhvalid\n", t.l2p_mhvalid);
   6849   1.3   nonaka 	aprint_error_dev(sc->sc_dev, "%08X | l2p_addr_match\n",
   6850  1.45   nonaka 	    t.l2p_addr_match);
   6851  1.45   nonaka 	aprint_error_dev(sc->sc_dev, "%08X | lmpm_pmg_sel\n", t.lmpm_pmg_sel);
   6852  1.45   nonaka 	aprint_error_dev(sc->sc_dev, "%08X | timestamp\n", t.u_timestamp);
   6853  1.45   nonaka 	aprint_error_dev(sc->sc_dev, "%08X | flow_handler\n", t.flow_handler);
   6854  1.45   nonaka 
   6855  1.45   nonaka 	if (sc->sc_uc.uc_umac_error_event_table)
   6856  1.45   nonaka 		iwm_nic_umac_error(sc);
   6857  1.45   nonaka }
   6858  1.45   nonaka 
   6859  1.45   nonaka static void
   6860  1.45   nonaka iwm_nic_umac_error(struct iwm_softc *sc)
   6861  1.45   nonaka {
   6862  1.45   nonaka 	struct iwm_umac_error_event_table t;
   6863  1.45   nonaka 	uint32_t base;
   6864  1.45   nonaka 
   6865  1.45   nonaka 	base = sc->sc_uc.uc_umac_error_event_table;
   6866  1.45   nonaka 
   6867  1.45   nonaka 	if (base < 0x800000) {
   6868  1.45   nonaka 		aprint_error_dev(sc->sc_dev,
   6869  1.45   nonaka 		    "Invalid error log pointer 0x%08x\n", base);
   6870  1.45   nonaka 		return;
   6871  1.45   nonaka 	}
   6872  1.45   nonaka 
   6873  1.45   nonaka 	if (iwm_read_mem(sc, base, &t, sizeof(t)/sizeof(uint32_t))) {
   6874  1.45   nonaka 		aprint_error_dev(sc->sc_dev, "reading errlog failed\n");
   6875  1.45   nonaka 		return;
   6876  1.45   nonaka 	}
   6877  1.45   nonaka 
   6878  1.45   nonaka 	if (ERROR_START_OFFSET <= t.valid * ERROR_ELEM_SIZE) {
   6879  1.45   nonaka 		aprint_error_dev(sc->sc_dev, "Start UMAC Error Log Dump:\n");
   6880  1.45   nonaka 		aprint_error_dev(sc->sc_dev, "Status: 0x%x, count: %d\n",
   6881  1.45   nonaka 		    sc->sc_flags, t.valid);
   6882  1.45   nonaka 	}
   6883  1.45   nonaka 
   6884  1.45   nonaka 	aprint_error_dev(sc->sc_dev, "0x%08X | %s\n", t.error_id,
   6885  1.45   nonaka 		iwm_desc_lookup(t.error_id));
   6886  1.45   nonaka 	aprint_error_dev(sc->sc_dev, "0x%08X | umac branchlink1\n", t.blink1);
   6887  1.45   nonaka 	aprint_error_dev(sc->sc_dev, "0x%08X | umac branchlink2\n", t.blink2);
   6888  1.45   nonaka 	aprint_error_dev(sc->sc_dev, "0x%08X | umac interruptlink1\n",
   6889  1.45   nonaka 	    t.ilink1);
   6890  1.45   nonaka 	aprint_error_dev(sc->sc_dev, "0x%08X | umac interruptlink2\n",
   6891  1.45   nonaka 	    t.ilink2);
   6892  1.45   nonaka 	aprint_error_dev(sc->sc_dev, "0x%08X | umac data1\n", t.data1);
   6893  1.45   nonaka 	aprint_error_dev(sc->sc_dev, "0x%08X | umac data2\n", t.data2);
   6894  1.45   nonaka 	aprint_error_dev(sc->sc_dev, "0x%08X | umac data3\n", t.data3);
   6895  1.45   nonaka 	aprint_error_dev(sc->sc_dev, "0x%08X | umac major\n", t.umac_major);
   6896  1.45   nonaka 	aprint_error_dev(sc->sc_dev, "0x%08X | umac minor\n", t.umac_minor);
   6897  1.45   nonaka 	aprint_error_dev(sc->sc_dev, "0x%08X | frame pointer\n",
   6898  1.45   nonaka 	    t.frame_pointer);
   6899  1.45   nonaka 	aprint_error_dev(sc->sc_dev, "0x%08X | stack pointer\n",
   6900  1.45   nonaka 	    t.stack_pointer);
   6901  1.45   nonaka 	aprint_error_dev(sc->sc_dev, "0x%08X | last host cmd\n", t.cmd_header);
   6902  1.45   nonaka 	aprint_error_dev(sc->sc_dev, "0x%08X | isr status reg\n",
   6903  1.45   nonaka 	    t.nic_isr_pref);
   6904   1.1    pooka }
   6905   1.2   nonaka #endif
   6906   1.1    pooka 
   6907   1.1    pooka #define SYNC_RESP_STRUCT(_var_, _pkt_)					\
   6908   1.1    pooka do {									\
   6909   1.1    pooka 	bus_dmamap_sync(sc->sc_dmat, data->map, sizeof(*(_pkt_)),	\
   6910   1.1    pooka 	    sizeof(*(_var_)), BUS_DMASYNC_POSTREAD);			\
   6911   1.1    pooka 	_var_ = (void *)((_pkt_)+1);					\
   6912   1.1    pooka } while (/*CONSTCOND*/0)
   6913   1.1    pooka 
   6914   1.1    pooka #define SYNC_RESP_PTR(_ptr_, _len_, _pkt_)				\
   6915   1.1    pooka do {									\
   6916   1.1    pooka 	bus_dmamap_sync(sc->sc_dmat, data->map, sizeof(*(_pkt_)),	\
   6917   1.1    pooka 	    sizeof(len), BUS_DMASYNC_POSTREAD);				\
   6918   1.1    pooka 	_ptr_ = (void *)((_pkt_)+1);					\
   6919   1.1    pooka } while (/*CONSTCOND*/0)
   6920   1.1    pooka 
   6921   1.1    pooka #define ADVANCE_RXQ(sc) (sc->rxq.cur = (sc->rxq.cur + 1) % IWM_RX_RING_COUNT);
   6922   1.1    pooka 
   6923   1.4   nonaka static void
   6924   1.1    pooka iwm_notif_intr(struct iwm_softc *sc)
   6925   1.1    pooka {
   6926   1.1    pooka 	uint16_t hw;
   6927   1.1    pooka 
   6928   1.1    pooka 	bus_dmamap_sync(sc->sc_dmat, sc->rxq.stat_dma.map,
   6929   1.1    pooka 	    0, sc->rxq.stat_dma.size, BUS_DMASYNC_POSTREAD);
   6930   1.1    pooka 
   6931   1.1    pooka 	hw = le16toh(sc->rxq.stat->closed_rb_num) & 0xfff;
   6932   1.1    pooka 	while (sc->rxq.cur != hw) {
   6933   1.1    pooka 		struct iwm_rx_data *data = &sc->rxq.data[sc->rxq.cur];
   6934  1.45   nonaka 		struct iwm_rx_packet *pkt;
   6935   1.1    pooka 		struct iwm_cmd_response *cresp;
   6936  1.45   nonaka 		int orig_qid, qid, idx, code;
   6937   1.1    pooka 
   6938   1.1    pooka 		bus_dmamap_sync(sc->sc_dmat, data->map, 0, sizeof(*pkt),
   6939   1.1    pooka 		    BUS_DMASYNC_POSTREAD);
   6940   1.1    pooka 		pkt = mtod(data->m, struct iwm_rx_packet *);
   6941   1.1    pooka 
   6942  1.45   nonaka 		orig_qid = pkt->hdr.qid;
   6943  1.45   nonaka 		qid = orig_qid & ~0x80;
   6944   1.1    pooka 		idx = pkt->hdr.idx;
   6945   1.1    pooka 
   6946  1.45   nonaka 		code = IWM_WIDE_ID(pkt->hdr.flags, pkt->hdr.code);
   6947   1.1    pooka 
   6948   1.1    pooka 		/*
   6949   1.1    pooka 		 * randomly get these from the firmware, no idea why.
   6950   1.1    pooka 		 * they at least seem harmless, so just ignore them for now
   6951   1.1    pooka 		 */
   6952   1.1    pooka 		if (__predict_false((pkt->hdr.code == 0 && qid == 0 && idx == 0)
   6953   1.1    pooka 		    || pkt->len_n_flags == htole32(0x55550000))) {
   6954   1.1    pooka 			ADVANCE_RXQ(sc);
   6955   1.1    pooka 			continue;
   6956   1.1    pooka 		}
   6957   1.1    pooka 
   6958  1.45   nonaka 		switch (code) {
   6959   1.1    pooka 		case IWM_REPLY_RX_PHY_CMD:
   6960  1.45   nonaka 			iwm_rx_rx_phy_cmd(sc, pkt, data);
   6961   1.1    pooka 			break;
   6962   1.1    pooka 
   6963   1.1    pooka 		case IWM_REPLY_RX_MPDU_CMD:
   6964  1.45   nonaka 			iwm_rx_rx_mpdu(sc, pkt, data);
   6965   1.1    pooka 			break;
   6966   1.1    pooka 
   6967   1.1    pooka 		case IWM_TX_CMD:
   6968  1.45   nonaka 			iwm_rx_tx_cmd(sc, pkt, data);
   6969   1.1    pooka 			break;
   6970   1.1    pooka 
   6971   1.1    pooka 		case IWM_MISSED_BEACONS_NOTIFICATION:
   6972  1.45   nonaka 			iwm_rx_missed_beacons_notif(sc, pkt, data);
   6973   1.1    pooka 			break;
   6974   1.1    pooka 
   6975  1.45   nonaka 		case IWM_MFUART_LOAD_NOTIFICATION:
   6976  1.45   nonaka 			break;
   6977   1.1    pooka 
   6978  1.45   nonaka 		case IWM_ALIVE: {
   6979  1.45   nonaka 			struct iwm_alive_resp_v1 *resp1;
   6980  1.45   nonaka 			struct iwm_alive_resp_v2 *resp2;
   6981  1.45   nonaka 			struct iwm_alive_resp_v3 *resp3;
   6982  1.45   nonaka 
   6983  1.45   nonaka 			if (iwm_rx_packet_payload_len(pkt) == sizeof(*resp1)) {
   6984  1.45   nonaka 				SYNC_RESP_STRUCT(resp1, pkt);
   6985  1.45   nonaka 				sc->sc_uc.uc_error_event_table
   6986  1.45   nonaka 				    = le32toh(resp1->error_event_table_ptr);
   6987  1.45   nonaka 				sc->sc_uc.uc_log_event_table
   6988  1.45   nonaka 				    = le32toh(resp1->log_event_table_ptr);
   6989  1.45   nonaka 				sc->sched_base = le32toh(resp1->scd_base_ptr);
   6990  1.45   nonaka 				if (resp1->status == IWM_ALIVE_STATUS_OK)
   6991  1.45   nonaka 					sc->sc_uc.uc_ok = 1;
   6992  1.45   nonaka 				else
   6993  1.45   nonaka 					sc->sc_uc.uc_ok = 0;
   6994  1.45   nonaka 			}
   6995  1.45   nonaka 			if (iwm_rx_packet_payload_len(pkt) == sizeof(*resp2)) {
   6996  1.45   nonaka 				SYNC_RESP_STRUCT(resp2, pkt);
   6997  1.45   nonaka 				sc->sc_uc.uc_error_event_table
   6998  1.45   nonaka 				    = le32toh(resp2->error_event_table_ptr);
   6999  1.45   nonaka 				sc->sc_uc.uc_log_event_table
   7000  1.45   nonaka 				    = le32toh(resp2->log_event_table_ptr);
   7001  1.45   nonaka 				sc->sched_base = le32toh(resp2->scd_base_ptr);
   7002  1.45   nonaka 				sc->sc_uc.uc_umac_error_event_table
   7003  1.45   nonaka 				    = le32toh(resp2->error_info_addr);
   7004  1.45   nonaka 				if (resp2->status == IWM_ALIVE_STATUS_OK)
   7005  1.45   nonaka 					sc->sc_uc.uc_ok = 1;
   7006  1.45   nonaka 				else
   7007  1.45   nonaka 					sc->sc_uc.uc_ok = 0;
   7008  1.45   nonaka 			}
   7009  1.45   nonaka 			if (iwm_rx_packet_payload_len(pkt) == sizeof(*resp3)) {
   7010  1.45   nonaka 				SYNC_RESP_STRUCT(resp3, pkt);
   7011  1.45   nonaka 				sc->sc_uc.uc_error_event_table
   7012  1.45   nonaka 				    = le32toh(resp3->error_event_table_ptr);
   7013  1.45   nonaka 				sc->sc_uc.uc_log_event_table
   7014  1.45   nonaka 				    = le32toh(resp3->log_event_table_ptr);
   7015  1.45   nonaka 				sc->sched_base = le32toh(resp3->scd_base_ptr);
   7016  1.45   nonaka 				sc->sc_uc.uc_umac_error_event_table
   7017  1.45   nonaka 				    = le32toh(resp3->error_info_addr);
   7018  1.45   nonaka 				if (resp3->status == IWM_ALIVE_STATUS_OK)
   7019  1.45   nonaka 					sc->sc_uc.uc_ok = 1;
   7020  1.45   nonaka 				else
   7021  1.45   nonaka 					sc->sc_uc.uc_ok = 0;
   7022  1.45   nonaka 			}
   7023   1.1    pooka 
   7024   1.1    pooka 			sc->sc_uc.uc_intr = 1;
   7025   1.1    pooka 			wakeup(&sc->sc_uc);
   7026  1.45   nonaka 			break;
   7027  1.45   nonaka 		}
   7028   1.1    pooka 
   7029   1.1    pooka 		case IWM_CALIB_RES_NOTIF_PHY_DB: {
   7030   1.1    pooka 			struct iwm_calib_res_notif_phy_db *phy_db_notif;
   7031   1.1    pooka 			SYNC_RESP_STRUCT(phy_db_notif, pkt);
   7032   1.5   nonaka 			uint16_t size = le16toh(phy_db_notif->length);
   7033   1.5   nonaka 			bus_dmamap_sync(sc->sc_dmat, data->map,
   7034   1.5   nonaka 			    sizeof(*pkt) + sizeof(*phy_db_notif),
   7035   1.5   nonaka 			    size, BUS_DMASYNC_POSTREAD);
   7036   1.5   nonaka 			iwm_phy_db_set_section(sc, phy_db_notif, size);
   7037  1.45   nonaka 			break;
   7038  1.45   nonaka 		}
   7039   1.1    pooka 
   7040   1.1    pooka 		case IWM_STATISTICS_NOTIFICATION: {
   7041   1.1    pooka 			struct iwm_notif_statistics *stats;
   7042   1.1    pooka 			SYNC_RESP_STRUCT(stats, pkt);
   7043   1.1    pooka 			memcpy(&sc->sc_stats, stats, sizeof(sc->sc_stats));
   7044   1.1    pooka 			sc->sc_noise = iwm_get_noise(&stats->rx.general);
   7045  1.45   nonaka 			break;
   7046  1.45   nonaka 		}
   7047   1.1    pooka 
   7048   1.1    pooka 		case IWM_NVM_ACCESS_CMD:
   7049  1.45   nonaka 		case IWM_MCC_UPDATE_CMD:
   7050   1.1    pooka 			if (sc->sc_wantresp == ((qid << 16) | idx)) {
   7051   1.1    pooka 				bus_dmamap_sync(sc->sc_dmat, data->map, 0,
   7052   1.1    pooka 				    sizeof(sc->sc_cmd_resp),
   7053   1.1    pooka 				    BUS_DMASYNC_POSTREAD);
   7054   1.1    pooka 				memcpy(sc->sc_cmd_resp,
   7055   1.1    pooka 				    pkt, sizeof(sc->sc_cmd_resp));
   7056   1.1    pooka 			}
   7057   1.1    pooka 			break;
   7058   1.1    pooka 
   7059  1.45   nonaka 		case IWM_MCC_CHUB_UPDATE_CMD: {
   7060  1.45   nonaka 			struct iwm_mcc_chub_notif *notif;
   7061  1.45   nonaka 			SYNC_RESP_STRUCT(notif, pkt);
   7062  1.45   nonaka 
   7063  1.45   nonaka 			sc->sc_fw_mcc[0] = (notif->mcc & 0xff00) >> 8;
   7064  1.45   nonaka 			sc->sc_fw_mcc[1] = notif->mcc & 0xff;
   7065  1.45   nonaka 			sc->sc_fw_mcc[2] = '\0';
   7066  1.45   nonaka 			break;
   7067  1.45   nonaka 		}
   7068  1.45   nonaka 
   7069  1.45   nonaka 		case IWM_DTS_MEASUREMENT_NOTIFICATION:
   7070  1.61   nonaka 		case IWM_WIDE_ID(IWM_PHY_OPS_GROUP,
   7071  1.61   nonaka 		    IWM_DTS_MEASUREMENT_NOTIF_WIDE): {
   7072  1.61   nonaka 			struct iwm_dts_measurement_notif_v1 *notif1;
   7073  1.61   nonaka 			struct iwm_dts_measurement_notif_v2 *notif2;
   7074  1.61   nonaka 
   7075  1.61   nonaka 			if (iwm_rx_packet_payload_len(pkt) == sizeof(*notif1)) {
   7076  1.61   nonaka 				SYNC_RESP_STRUCT(notif1, pkt);
   7077  1.61   nonaka 				DPRINTF(("%s: DTS temp=%d \n",
   7078  1.61   nonaka 				    DEVNAME(sc), notif1->temp));
   7079  1.61   nonaka 				break;
   7080  1.61   nonaka 			}
   7081  1.61   nonaka 			if (iwm_rx_packet_payload_len(pkt) == sizeof(*notif2)) {
   7082  1.61   nonaka 				SYNC_RESP_STRUCT(notif2, pkt);
   7083  1.61   nonaka 				DPRINTF(("%s: DTS temp=%d \n",
   7084  1.61   nonaka 				    DEVNAME(sc), notif2->temp));
   7085  1.61   nonaka 				break;
   7086  1.61   nonaka 			}
   7087  1.45   nonaka 			break;
   7088  1.61   nonaka 		}
   7089  1.45   nonaka 
   7090   1.1    pooka 		case IWM_PHY_CONFIGURATION_CMD:
   7091   1.1    pooka 		case IWM_TX_ANT_CONFIGURATION_CMD:
   7092   1.1    pooka 		case IWM_ADD_STA:
   7093   1.1    pooka 		case IWM_MAC_CONTEXT_CMD:
   7094   1.1    pooka 		case IWM_REPLY_SF_CFG_CMD:
   7095   1.1    pooka 		case IWM_POWER_TABLE_CMD:
   7096   1.1    pooka 		case IWM_PHY_CONTEXT_CMD:
   7097   1.1    pooka 		case IWM_BINDING_CONTEXT_CMD:
   7098   1.1    pooka 		case IWM_TIME_EVENT_CMD:
   7099   1.1    pooka 		case IWM_SCAN_REQUEST_CMD:
   7100  1.45   nonaka 		case IWM_WIDE_ID(IWM_ALWAYS_LONG_GROUP, IWM_SCAN_CFG_CMD):
   7101  1.45   nonaka 		case IWM_WIDE_ID(IWM_ALWAYS_LONG_GROUP, IWM_SCAN_REQ_UMAC):
   7102  1.61   nonaka 		case IWM_WIDE_ID(IWM_ALWAYS_LONG_GROUP, IWM_SCAN_ABORT_UMAC):
   7103  1.45   nonaka 		case IWM_SCAN_OFFLOAD_REQUEST_CMD:
   7104  1.61   nonaka 		case IWM_SCAN_OFFLOAD_ABORT_CMD:
   7105   1.1    pooka 		case IWM_REPLY_BEACON_FILTERING_CMD:
   7106   1.1    pooka 		case IWM_MAC_PM_POWER_TABLE:
   7107   1.1    pooka 		case IWM_TIME_QUOTA_CMD:
   7108   1.1    pooka 		case IWM_REMOVE_STA:
   7109   1.1    pooka 		case IWM_TXPATH_FLUSH:
   7110   1.1    pooka 		case IWM_LQ_CMD:
   7111  1.45   nonaka 		case IWM_BT_CONFIG:
   7112  1.45   nonaka 		case IWM_REPLY_THERMAL_MNG_BACKOFF:
   7113   1.1    pooka 			SYNC_RESP_STRUCT(cresp, pkt);
   7114   1.1    pooka 			if (sc->sc_wantresp == ((qid << 16) | idx)) {
   7115   1.1    pooka 				memcpy(sc->sc_cmd_resp,
   7116  1.45   nonaka 				    pkt, sizeof(*pkt) + sizeof(*cresp));
   7117   1.1    pooka 			}
   7118   1.1    pooka 			break;
   7119   1.1    pooka 
   7120   1.1    pooka 		/* ignore */
   7121  1.61   nonaka 		case IWM_PHY_DB_CMD:
   7122   1.1    pooka 			break;
   7123   1.1    pooka 
   7124   1.1    pooka 		case IWM_INIT_COMPLETE_NOTIF:
   7125   1.1    pooka 			sc->sc_init_complete = 1;
   7126   1.1    pooka 			wakeup(&sc->sc_init_complete);
   7127   1.1    pooka 			break;
   7128   1.1    pooka 
   7129  1.45   nonaka 		case IWM_SCAN_OFFLOAD_COMPLETE: {
   7130  1.45   nonaka 			struct iwm_periodic_scan_complete *notif;
   7131  1.45   nonaka 			SYNC_RESP_STRUCT(notif, pkt);
   7132  1.45   nonaka 			break;
   7133  1.45   nonaka 		}
   7134  1.45   nonaka 
   7135  1.45   nonaka 		case IWM_SCAN_ITERATION_COMPLETE: {
   7136  1.45   nonaka 			struct iwm_lmac_scan_complete_notif *notif;
   7137  1.45   nonaka 			SYNC_RESP_STRUCT(notif, pkt);
   7138  1.61   nonaka 			if (ISSET(sc->sc_flags, IWM_FLAG_SCANNING)) {
   7139  1.61   nonaka 				CLR(sc->sc_flags, IWM_FLAG_SCANNING);
   7140  1.61   nonaka 				iwm_endscan(sc);
   7141  1.61   nonaka 			}
   7142  1.45   nonaka 			break;
   7143  1.45   nonaka 		}
   7144  1.45   nonaka 
   7145  1.45   nonaka 		case IWM_SCAN_COMPLETE_UMAC: {
   7146  1.45   nonaka 			struct iwm_umac_scan_complete *notif;
   7147   1.1    pooka 			SYNC_RESP_STRUCT(notif, pkt);
   7148  1.61   nonaka 			if (ISSET(sc->sc_flags, IWM_FLAG_SCANNING)) {
   7149  1.61   nonaka 				CLR(sc->sc_flags, IWM_FLAG_SCANNING);
   7150  1.61   nonaka 				iwm_endscan(sc);
   7151  1.61   nonaka 			}
   7152  1.45   nonaka 			break;
   7153  1.45   nonaka 		}
   7154   1.1    pooka 
   7155  1.45   nonaka 		case IWM_SCAN_ITERATION_COMPLETE_UMAC: {
   7156  1.45   nonaka 			struct iwm_umac_scan_iter_complete_notif *notif;
   7157  1.45   nonaka 			SYNC_RESP_STRUCT(notif, pkt);
   7158  1.61   nonaka 			if (ISSET(sc->sc_flags, IWM_FLAG_SCANNING)) {
   7159  1.61   nonaka 				CLR(sc->sc_flags, IWM_FLAG_SCANNING);
   7160  1.61   nonaka 				iwm_endscan(sc);
   7161  1.61   nonaka 			}
   7162  1.45   nonaka 			break;
   7163  1.45   nonaka 		}
   7164   1.1    pooka 
   7165   1.1    pooka 		case IWM_REPLY_ERROR: {
   7166   1.1    pooka 			struct iwm_error_resp *resp;
   7167   1.1    pooka 			SYNC_RESP_STRUCT(resp, pkt);
   7168   1.3   nonaka 			aprint_error_dev(sc->sc_dev,
   7169   1.3   nonaka 			    "firmware error 0x%x, cmd 0x%x\n",
   7170   1.3   nonaka 			    le32toh(resp->error_type), resp->cmd_id);
   7171  1.45   nonaka 			break;
   7172  1.45   nonaka 		}
   7173   1.1    pooka 
   7174   1.1    pooka 		case IWM_TIME_EVENT_NOTIFICATION: {
   7175   1.1    pooka 			struct iwm_time_event_notif *notif;
   7176   1.1    pooka 			SYNC_RESP_STRUCT(notif, pkt);
   7177  1.45   nonaka 			break;
   7178  1.45   nonaka 		}
   7179   1.8   nonaka 
   7180  1.45   nonaka 		case IWM_MCAST_FILTER_CMD:
   7181  1.45   nonaka 			break;
   7182   1.1    pooka 
   7183  1.45   nonaka 		case IWM_SCD_QUEUE_CFG: {
   7184  1.45   nonaka 			struct iwm_scd_txq_cfg_rsp *rsp;
   7185  1.45   nonaka 			SYNC_RESP_STRUCT(rsp, pkt);
   7186  1.11   nonaka 			break;
   7187  1.45   nonaka 		}
   7188  1.11   nonaka 
   7189   1.1    pooka 		default:
   7190   1.3   nonaka 			aprint_error_dev(sc->sc_dev,
   7191  1.45   nonaka 			    "unhandled firmware response 0x%x 0x%x/0x%x "
   7192  1.45   nonaka 			    "rx ring %d[%d]\n",
   7193  1.45   nonaka 			    code, pkt->hdr.code, pkt->len_n_flags, qid, idx);
   7194   1.1    pooka 			break;
   7195   1.1    pooka 		}
   7196   1.1    pooka 
   7197   1.1    pooka 		/*
   7198  1.45   nonaka 		 * uCode sets bit 0x80 when it originates the notification,
   7199  1.45   nonaka 		 * i.e. when the notification is not a direct response to a
   7200  1.45   nonaka 		 * command sent by the driver.
   7201  1.45   nonaka 		 * For example, uCode issues IWM_REPLY_RX when it sends a
   7202  1.45   nonaka 		 * received frame to the driver.
   7203   1.1    pooka 		 */
   7204  1.45   nonaka 		if (!(orig_qid & (1 << 7))) {
   7205  1.45   nonaka 			iwm_cmd_done(sc, qid, idx);
   7206   1.1    pooka 		}
   7207   1.1    pooka 
   7208   1.1    pooka 		ADVANCE_RXQ(sc);
   7209   1.1    pooka 	}
   7210   1.1    pooka 
   7211   1.1    pooka 	/*
   7212  1.45   nonaka 	 * Seems like the hardware gets upset unless we align the write by 8??
   7213   1.1    pooka 	 */
   7214   1.1    pooka 	hw = (hw == 0) ? IWM_RX_RING_COUNT - 1 : hw - 1;
   7215   1.1    pooka 	IWM_WRITE(sc, IWM_FH_RSCSR_CHNL0_WPTR, hw & ~7);
   7216   1.1    pooka }
   7217   1.1    pooka 
   7218  1.61   nonaka static int
   7219  1.61   nonaka iwm_intr(void *arg)
   7220  1.61   nonaka {
   7221  1.61   nonaka 	struct iwm_softc *sc = arg;
   7222  1.61   nonaka 	int r1, r2;
   7223  1.61   nonaka 
   7224  1.61   nonaka 	IWM_WRITE(sc, IWM_CSR_INT_MASK, 0);
   7225  1.61   nonaka 
   7226  1.63   nonaka 	if (__predict_true(sc->sc_flags & IWM_FLAG_USE_ICT)) {
   7227  1.61   nonaka 		uint32_t *ict = sc->ict_dma.vaddr;
   7228  1.61   nonaka 		int tmp;
   7229  1.61   nonaka 
   7230  1.61   nonaka 		bus_dmamap_sync(sc->sc_dmat, sc->ict_dma.map,
   7231  1.61   nonaka 		    0, sc->ict_dma.size, BUS_DMASYNC_POSTREAD);
   7232  1.61   nonaka 		tmp = htole32(ict[sc->ict_cur]);
   7233  1.61   nonaka 		if (!tmp)
   7234  1.61   nonaka 			goto out_ena;
   7235  1.61   nonaka 
   7236  1.61   nonaka 		/*
   7237  1.61   nonaka 		 * ok, there was something.  keep plowing until we have all.
   7238  1.61   nonaka 		 */
   7239  1.61   nonaka 		r1 = r2 = 0;
   7240  1.61   nonaka 		while (tmp) {
   7241  1.61   nonaka 			r1 |= tmp;
   7242  1.61   nonaka 			ict[sc->ict_cur] = 0;	/* Acknowledge. */
   7243  1.61   nonaka 			sc->ict_cur = (sc->ict_cur + 1) % IWM_ICT_COUNT;
   7244  1.61   nonaka 			tmp = htole32(ict[sc->ict_cur]);
   7245  1.61   nonaka 		}
   7246  1.61   nonaka 
   7247  1.62   nonaka 		bus_dmamap_sync(sc->sc_dmat, sc->ict_dma.map,
   7248  1.62   nonaka 		    0, sc->ict_dma.size, BUS_DMASYNC_PREWRITE);
   7249  1.62   nonaka 
   7250  1.61   nonaka 		/* this is where the fun begins.  don't ask */
   7251  1.61   nonaka 		if (r1 == 0xffffffff)
   7252  1.61   nonaka 			r1 = 0;
   7253  1.61   nonaka 
   7254  1.61   nonaka 		/* i am not expected to understand this */
   7255  1.61   nonaka 		if (r1 & 0xc0000)
   7256  1.61   nonaka 			r1 |= 0x8000;
   7257  1.61   nonaka 		r1 = (0xff & r1) | ((0xff00 & r1) << 16);
   7258  1.61   nonaka 	} else {
   7259  1.61   nonaka 		r1 = IWM_READ(sc, IWM_CSR_INT);
   7260  1.61   nonaka 		if (r1 == 0xffffffff || (r1 & 0xfffffff0) == 0xa5a5a5a0)
   7261  1.61   nonaka 			goto out;
   7262  1.61   nonaka 		r2 = IWM_READ(sc, IWM_CSR_FH_INT_STATUS);
   7263  1.61   nonaka 	}
   7264  1.61   nonaka 	if (r1 == 0 && r2 == 0) {
   7265  1.61   nonaka 		goto out_ena;
   7266  1.61   nonaka 	}
   7267  1.61   nonaka 
   7268  1.63   nonaka 	/* Acknowledge interrupts. */
   7269  1.61   nonaka 	IWM_WRITE(sc, IWM_CSR_INT, r1 | ~sc->sc_intmask);
   7270  1.63   nonaka 	if (__predict_false(!(sc->sc_flags & IWM_FLAG_USE_ICT)))
   7271  1.63   nonaka 		IWM_WRITE(sc, IWM_CSR_FH_INT_STATUS, r2);
   7272  1.61   nonaka 
   7273  1.61   nonaka 	atomic_or_32(&sc->sc_soft_flags, r1);
   7274  1.61   nonaka 	softint_schedule(sc->sc_soft_ih);
   7275  1.61   nonaka 	return 1;
   7276  1.61   nonaka 
   7277  1.61   nonaka  out_ena:
   7278  1.61   nonaka 	iwm_restore_interrupts(sc);
   7279  1.61   nonaka  out:
   7280  1.61   nonaka 	return 0;
   7281  1.61   nonaka }
   7282  1.61   nonaka 
   7283  1.50   nonaka static void
   7284  1.50   nonaka iwm_softintr(void *arg)
   7285   1.1    pooka {
   7286   1.1    pooka 	struct iwm_softc *sc = arg;
   7287   1.1    pooka 	struct ifnet *ifp = IC2IFP(&sc->sc_ic);
   7288  1.50   nonaka 	uint32_t r1;
   7289   1.1    pooka 	int isperiodic = 0;
   7290   1.1    pooka 
   7291  1.50   nonaka 	r1 = atomic_swap_32(&sc->sc_soft_flags, 0);
   7292   1.1    pooka 
   7293   1.1    pooka 	if (r1 & IWM_CSR_INT_BIT_SW_ERR) {
   7294   1.1    pooka #ifdef IWM_DEBUG
   7295   1.1    pooka 		int i;
   7296   1.1    pooka 
   7297   1.1    pooka 		iwm_nic_error(sc);
   7298   1.1    pooka 
   7299   1.1    pooka 		/* Dump driver status (TX and RX rings) while we're here. */
   7300   1.1    pooka 		DPRINTF(("driver status:\n"));
   7301  1.45   nonaka 		for (i = 0; i < IWM_MAX_QUEUES; i++) {
   7302   1.1    pooka 			struct iwm_tx_ring *ring = &sc->txq[i];
   7303   1.1    pooka 			DPRINTF(("  tx ring %2d: qid=%-2d cur=%-3d "
   7304   1.1    pooka 			    "queued=%-3d\n",
   7305   1.1    pooka 			    i, ring->qid, ring->cur, ring->queued));
   7306   1.1    pooka 		}
   7307   1.1    pooka 		DPRINTF(("  rx ring: cur=%d\n", sc->rxq.cur));
   7308  1.45   nonaka 		DPRINTF(("  802.11 state %s\n",
   7309  1.45   nonaka 		    ieee80211_state_name[sc->sc_ic.ic_state]));
   7310   1.1    pooka #endif
   7311   1.1    pooka 
   7312   1.3   nonaka 		aprint_error_dev(sc->sc_dev, "fatal firmware error\n");
   7313  1.50   nonaka  fatal:
   7314   1.1    pooka 		ifp->if_flags &= ~IFF_UP;
   7315   1.1    pooka 		iwm_stop(ifp, 1);
   7316  1.50   nonaka 		/* Don't restore interrupt mask */
   7317  1.50   nonaka 		return;
   7318   1.1    pooka 
   7319   1.1    pooka 	}
   7320   1.1    pooka 
   7321   1.1    pooka 	if (r1 & IWM_CSR_INT_BIT_HW_ERR) {
   7322   1.3   nonaka 		aprint_error_dev(sc->sc_dev,
   7323   1.3   nonaka 		    "hardware error, stopping device\n");
   7324  1.50   nonaka 		goto fatal;
   7325   1.1    pooka 	}
   7326   1.1    pooka 
   7327   1.1    pooka 	/* firmware chunk loaded */
   7328   1.1    pooka 	if (r1 & IWM_CSR_INT_BIT_FH_TX) {
   7329   1.1    pooka 		IWM_WRITE(sc, IWM_CSR_FH_INT_STATUS, IWM_CSR_FH_INT_TX_MASK);
   7330   1.1    pooka 		sc->sc_fw_chunk_done = 1;
   7331   1.1    pooka 		wakeup(&sc->sc_fw);
   7332   1.1    pooka 	}
   7333   1.1    pooka 
   7334   1.1    pooka 	if (r1 & IWM_CSR_INT_BIT_RF_KILL) {
   7335   1.1    pooka 		if (iwm_check_rfkill(sc) && (ifp->if_flags & IFF_UP)) {
   7336   1.1    pooka 			ifp->if_flags &= ~IFF_UP;
   7337   1.1    pooka 			iwm_stop(ifp, 1);
   7338   1.1    pooka 		}
   7339   1.1    pooka 	}
   7340   1.1    pooka 
   7341   1.1    pooka 	if (r1 & IWM_CSR_INT_BIT_RX_PERIODIC) {
   7342   1.1    pooka 		IWM_WRITE(sc, IWM_CSR_INT, IWM_CSR_INT_BIT_RX_PERIODIC);
   7343   1.1    pooka 		if ((r1 & (IWM_CSR_INT_BIT_FH_RX | IWM_CSR_INT_BIT_SW_RX)) == 0)
   7344   1.1    pooka 			IWM_WRITE_1(sc,
   7345   1.1    pooka 			    IWM_CSR_INT_PERIODIC_REG, IWM_CSR_INT_PERIODIC_DIS);
   7346   1.1    pooka 		isperiodic = 1;
   7347   1.1    pooka 	}
   7348   1.1    pooka 
   7349  1.45   nonaka 	if ((r1 & (IWM_CSR_INT_BIT_FH_RX | IWM_CSR_INT_BIT_SW_RX)) ||
   7350  1.45   nonaka 	    isperiodic) {
   7351   1.1    pooka 		IWM_WRITE(sc, IWM_CSR_FH_INT_STATUS, IWM_CSR_FH_INT_RX_MASK);
   7352   1.1    pooka 
   7353   1.1    pooka 		iwm_notif_intr(sc);
   7354   1.1    pooka 
   7355   1.1    pooka 		/* enable periodic interrupt, see above */
   7356  1.45   nonaka 		if (r1 & (IWM_CSR_INT_BIT_FH_RX | IWM_CSR_INT_BIT_SW_RX) &&
   7357  1.45   nonaka 		    !isperiodic)
   7358   1.1    pooka 			IWM_WRITE_1(sc, IWM_CSR_INT_PERIODIC_REG,
   7359   1.1    pooka 			    IWM_CSR_INT_PERIODIC_ENA);
   7360   1.1    pooka 	}
   7361   1.1    pooka 
   7362   1.1    pooka 	iwm_restore_interrupts(sc);
   7363   1.1    pooka }
   7364   1.1    pooka 
   7365   1.1    pooka /*
   7366   1.1    pooka  * Autoconf glue-sniffing
   7367   1.1    pooka  */
   7368   1.1    pooka 
   7369   1.1    pooka static const pci_product_id_t iwm_devices[] = {
   7370   1.5   nonaka 	PCI_PRODUCT_INTEL_WIFI_LINK_7260_1,
   7371   1.5   nonaka 	PCI_PRODUCT_INTEL_WIFI_LINK_7260_2,
   7372   1.5   nonaka 	PCI_PRODUCT_INTEL_WIFI_LINK_3160_1,
   7373   1.5   nonaka 	PCI_PRODUCT_INTEL_WIFI_LINK_3160_2,
   7374   1.5   nonaka 	PCI_PRODUCT_INTEL_WIFI_LINK_7265_1,
   7375   1.5   nonaka 	PCI_PRODUCT_INTEL_WIFI_LINK_7265_2,
   7376  1.45   nonaka 	PCI_PRODUCT_INTEL_WIFI_LINK_3165_1,
   7377  1.45   nonaka 	PCI_PRODUCT_INTEL_WIFI_LINK_3165_2,
   7378  1.45   nonaka 	PCI_PRODUCT_INTEL_WIFI_LINK_8260_1,
   7379  1.45   nonaka 	PCI_PRODUCT_INTEL_WIFI_LINK_8260_2,
   7380  1.58   nonaka 	PCI_PRODUCT_INTEL_WIFI_LINK_4165_1,
   7381  1.58   nonaka 	PCI_PRODUCT_INTEL_WIFI_LINK_4165_2,
   7382   1.1    pooka };
   7383   1.1    pooka 
   7384   1.1    pooka static int
   7385   1.4   nonaka iwm_match(device_t parent, cfdata_t match __unused, void *aux)
   7386   1.1    pooka {
   7387   1.1    pooka 	struct pci_attach_args *pa = aux;
   7388   1.1    pooka 
   7389   1.1    pooka 	if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_INTEL)
   7390   1.1    pooka 		return 0;
   7391   1.1    pooka 
   7392   1.5   nonaka 	for (size_t i = 0; i < __arraycount(iwm_devices); i++)
   7393   1.1    pooka 		if (PCI_PRODUCT(pa->pa_id) == iwm_devices[i])
   7394   1.1    pooka 			return 1;
   7395   1.1    pooka 
   7396   1.1    pooka 	return 0;
   7397   1.1    pooka }
   7398   1.1    pooka 
   7399   1.4   nonaka static int
   7400   1.1    pooka iwm_preinit(struct iwm_softc *sc)
   7401   1.1    pooka {
   7402  1.36   nonaka 	struct ieee80211com *ic = &sc->sc_ic;
   7403  1.45   nonaka 	int err;
   7404   1.1    pooka 
   7405  1.45   nonaka 	if (ISSET(sc->sc_flags, IWM_FLAG_ATTACHED))
   7406   1.2   nonaka 		return 0;
   7407   1.1    pooka 
   7408  1.45   nonaka 	err = iwm_start_hw(sc);
   7409  1.45   nonaka 	if (err) {
   7410   1.3   nonaka 		aprint_error_dev(sc->sc_dev, "could not initialize hardware\n");
   7411  1.45   nonaka 		return err;
   7412   1.1    pooka 	}
   7413   1.1    pooka 
   7414  1.45   nonaka 	err = iwm_run_init_mvm_ucode(sc, 1);
   7415   1.1    pooka 	iwm_stop_device(sc);
   7416  1.45   nonaka 	if (err)
   7417  1.45   nonaka 		return err;
   7418   1.1    pooka 
   7419   1.2   nonaka 	sc->sc_flags |= IWM_FLAG_ATTACHED;
   7420   1.1    pooka 
   7421  1.45   nonaka 	aprint_normal_dev(sc->sc_dev, "hw rev 0x%x, fw ver %s, address %s\n",
   7422  1.45   nonaka 	    sc->sc_hw_rev & IWM_CSR_HW_REV_TYPE_MSK, sc->sc_fwver,
   7423   1.1    pooka 	    ether_sprintf(sc->sc_nvm.hw_addr));
   7424   1.8   nonaka 
   7425  1.45   nonaka #ifndef IEEE80211_NO_HT
   7426  1.45   nonaka 	if (sc->sc_nvm.sku_cap_11n_enable)
   7427  1.45   nonaka 		iwm_setup_ht_rates(sc);
   7428  1.45   nonaka #endif
   7429  1.45   nonaka 
   7430  1.29   nonaka 	/* not all hardware can do 5GHz band */
   7431  1.29   nonaka 	if (sc->sc_nvm.sku_cap_band_52GHz_enable)
   7432  1.29   nonaka 		ic->ic_sup_rates[IEEE80211_MODE_11A] = ieee80211_std_rateset_11a;
   7433   1.1    pooka 
   7434   1.1    pooka 	ieee80211_ifattach(ic);
   7435   1.1    pooka 
   7436   1.1    pooka 	ic->ic_node_alloc = iwm_node_alloc;
   7437   1.1    pooka 
   7438   1.1    pooka 	/* Override 802.11 state transition machine. */
   7439   1.1    pooka 	sc->sc_newstate = ic->ic_newstate;
   7440   1.1    pooka 	ic->ic_newstate = iwm_newstate;
   7441   1.1    pooka 	ieee80211_media_init(ic, iwm_media_change, ieee80211_media_status);
   7442   1.1    pooka 	ieee80211_announce(ic);
   7443   1.1    pooka 
   7444   1.1    pooka 	iwm_radiotap_attach(sc);
   7445   1.1    pooka 
   7446  1.36   nonaka 	return 0;
   7447  1.36   nonaka }
   7448  1.36   nonaka 
   7449  1.36   nonaka static void
   7450  1.36   nonaka iwm_attach_hook(device_t dev)
   7451  1.36   nonaka {
   7452  1.36   nonaka 	struct iwm_softc *sc = device_private(dev);
   7453  1.30   nonaka 
   7454  1.36   nonaka 	iwm_preinit(sc);
   7455   1.1    pooka }
   7456   1.1    pooka 
   7457   1.4   nonaka static void
   7458   1.4   nonaka iwm_attach(device_t parent, device_t self, void *aux)
   7459   1.1    pooka {
   7460   1.1    pooka 	struct iwm_softc *sc = device_private(self);
   7461   1.1    pooka 	struct pci_attach_args *pa = aux;
   7462  1.36   nonaka 	struct ieee80211com *ic = &sc->sc_ic;
   7463  1.36   nonaka 	struct ifnet *ifp = &sc->sc_ec.ec_if;
   7464   1.1    pooka 	pcireg_t reg, memtype;
   7465  1.37   nonaka 	char intrbuf[PCI_INTRSTR_LEN];
   7466   1.1    pooka 	const char *intrstr;
   7467  1.45   nonaka 	int err;
   7468   1.2   nonaka 	int txq_i;
   7469  1.36   nonaka 	const struct sysctlnode *node;
   7470   1.1    pooka 
   7471   1.3   nonaka 	sc->sc_dev = self;
   7472   1.1    pooka 	sc->sc_pct = pa->pa_pc;
   7473   1.1    pooka 	sc->sc_pcitag = pa->pa_tag;
   7474   1.1    pooka 	sc->sc_dmat = pa->pa_dmat;
   7475   1.5   nonaka 	sc->sc_pciid = pa->pa_id;
   7476   1.1    pooka 
   7477   1.1    pooka 	pci_aprint_devinfo(pa, NULL);
   7478   1.1    pooka 
   7479  1.45   nonaka 	if (workqueue_create(&sc->sc_nswq, "iwmns",
   7480  1.45   nonaka 	    iwm_newstate_cb, sc, PRI_NONE, IPL_NET, 0))
   7481  1.45   nonaka 		panic("%s: could not create workqueue: newstate",
   7482  1.45   nonaka 		    device_xname(self));
   7483  1.50   nonaka 	sc->sc_soft_ih = softint_establish(SOFTINT_NET, iwm_softintr, sc);
   7484  1.50   nonaka 	if (sc->sc_soft_ih == NULL)
   7485  1.50   nonaka 		panic("%s: could not establish softint", device_xname(self));
   7486  1.45   nonaka 
   7487   1.1    pooka 	/*
   7488   1.1    pooka 	 * Get the offset of the PCI Express Capability Structure in PCI
   7489   1.1    pooka 	 * Configuration Space.
   7490   1.1    pooka 	 */
   7491  1.45   nonaka 	err = pci_get_capability(sc->sc_pct, sc->sc_pcitag,
   7492   1.1    pooka 	    PCI_CAP_PCIEXPRESS, &sc->sc_cap_off, NULL);
   7493  1.45   nonaka 	if (err == 0) {
   7494   1.3   nonaka 		aprint_error_dev(self,
   7495   1.3   nonaka 		    "PCIe capability structure not found!\n");
   7496   1.1    pooka 		return;
   7497   1.1    pooka 	}
   7498   1.1    pooka 
   7499   1.1    pooka 	/* Clear device-specific "PCI retry timeout" register (41h). */
   7500   1.1    pooka 	reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag, 0x40);
   7501   1.1    pooka 	pci_conf_write(sc->sc_pct, sc->sc_pcitag, 0x40, reg & ~0xff00);
   7502   1.1    pooka 
   7503  1.45   nonaka 	/* Enable bus-mastering */
   7504   1.1    pooka 	reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag, PCI_COMMAND_STATUS_REG);
   7505   1.1    pooka 	reg |= PCI_COMMAND_MASTER_ENABLE;
   7506   1.1    pooka 	pci_conf_write(sc->sc_pct, sc->sc_pcitag, PCI_COMMAND_STATUS_REG, reg);
   7507   1.1    pooka 
   7508   1.1    pooka 	memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, PCI_MAPREG_START);
   7509  1.45   nonaka 	err = pci_mapreg_map(pa, PCI_MAPREG_START, memtype, 0,
   7510   1.1    pooka 	    &sc->sc_st, &sc->sc_sh, NULL, &sc->sc_sz);
   7511  1.45   nonaka 	if (err) {
   7512   1.3   nonaka 		aprint_error_dev(self, "can't map mem space\n");
   7513   1.1    pooka 		return;
   7514   1.1    pooka 	}
   7515   1.1    pooka 
   7516   1.1    pooka 	/* Install interrupt handler. */
   7517  1.45   nonaka 	err = pci_intr_alloc(pa, &sc->sc_pihp, NULL, 0);
   7518  1.45   nonaka 	if (err) {
   7519  1.37   nonaka 		aprint_error_dev(self, "can't allocate interrupt\n");
   7520   1.1    pooka 		return;
   7521   1.1    pooka 	}
   7522  1.61   nonaka 	reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag, PCI_COMMAND_STATUS_REG);
   7523  1.61   nonaka 	if (pci_intr_type(sc->sc_pct, sc->sc_pihp[0]) == PCI_INTR_TYPE_INTX)
   7524  1.61   nonaka 		CLR(reg, PCI_COMMAND_INTERRUPT_DISABLE);
   7525  1.61   nonaka 	else
   7526  1.61   nonaka 		SET(reg, PCI_COMMAND_INTERRUPT_DISABLE);
   7527  1.61   nonaka 	pci_conf_write(sc->sc_pct, sc->sc_pcitag, PCI_COMMAND_STATUS_REG, reg);
   7528  1.31   nonaka 	intrstr = pci_intr_string(sc->sc_pct, sc->sc_pihp[0], intrbuf,
   7529  1.31   nonaka 	    sizeof(intrbuf));
   7530  1.49   nonaka 	sc->sc_ih = pci_intr_establish_xname(sc->sc_pct, sc->sc_pihp[0],
   7531  1.49   nonaka 	    IPL_NET, iwm_intr, sc, device_xname(self));
   7532   1.1    pooka 	if (sc->sc_ih == NULL) {
   7533   1.3   nonaka 		aprint_error_dev(self, "can't establish interrupt");
   7534   1.1    pooka 		if (intrstr != NULL)
   7535   1.3   nonaka 			aprint_error(" at %s", intrstr);
   7536   1.3   nonaka 		aprint_error("\n");
   7537   1.1    pooka 		return;
   7538   1.1    pooka 	}
   7539   1.3   nonaka 	aprint_normal_dev(self, "interrupting at %s\n", intrstr);
   7540   1.1    pooka 
   7541  1.45   nonaka 	sc->sc_wantresp = IWM_CMD_RESP_IDLE;
   7542   1.5   nonaka 
   7543  1.45   nonaka 	sc->sc_hw_rev = IWM_READ(sc, IWM_CSR_HW_REV);
   7544   1.5   nonaka 	switch (PCI_PRODUCT(sc->sc_pciid)) {
   7545  1.45   nonaka 	case PCI_PRODUCT_INTEL_WIFI_LINK_3160_1:
   7546  1.45   nonaka 	case PCI_PRODUCT_INTEL_WIFI_LINK_3160_2:
   7547  1.45   nonaka 		sc->sc_fwname = "iwlwifi-3160-16.ucode";
   7548  1.45   nonaka 		sc->host_interrupt_operation_mode = 1;
   7549  1.59   nonaka 		sc->apmg_wake_up_wa = 1;
   7550  1.45   nonaka 		sc->sc_device_family = IWM_DEVICE_FAMILY_7000;
   7551  1.45   nonaka 		sc->sc_fwdmasegsz = IWM_FWDMASEGSZ;
   7552  1.45   nonaka 		break;
   7553  1.45   nonaka 	case PCI_PRODUCT_INTEL_WIFI_LINK_3165_1:
   7554  1.45   nonaka 	case PCI_PRODUCT_INTEL_WIFI_LINK_3165_2:
   7555  1.61   nonaka 		sc->sc_fwname = "iwlwifi-7265D-17.ucode";
   7556  1.45   nonaka 		sc->host_interrupt_operation_mode = 0;
   7557  1.59   nonaka 		sc->apmg_wake_up_wa = 1;
   7558  1.45   nonaka 		sc->sc_device_family = IWM_DEVICE_FAMILY_7000;
   7559  1.45   nonaka 		sc->sc_fwdmasegsz = IWM_FWDMASEGSZ;
   7560  1.45   nonaka 		break;
   7561   1.5   nonaka 	case PCI_PRODUCT_INTEL_WIFI_LINK_7260_1:
   7562   1.5   nonaka 	case PCI_PRODUCT_INTEL_WIFI_LINK_7260_2:
   7563  1.45   nonaka 		sc->sc_fwname = "iwlwifi-7260-16.ucode";
   7564  1.17   nonaka 		sc->host_interrupt_operation_mode = 1;
   7565  1.59   nonaka 		sc->apmg_wake_up_wa = 1;
   7566  1.45   nonaka 		sc->sc_device_family = IWM_DEVICE_FAMILY_7000;
   7567  1.45   nonaka 		sc->sc_fwdmasegsz = IWM_FWDMASEGSZ;
   7568   1.5   nonaka 		break;
   7569   1.5   nonaka 	case PCI_PRODUCT_INTEL_WIFI_LINK_7265_1:
   7570   1.5   nonaka 	case PCI_PRODUCT_INTEL_WIFI_LINK_7265_2:
   7571  1.45   nonaka 		sc->sc_fwname = (sc->sc_hw_rev & IWM_CSR_HW_REV_TYPE_MSK) ==
   7572  1.45   nonaka 		    IWM_CSR_HW_REV_TYPE_7265D ?
   7573  1.61   nonaka 		    "iwlwifi-7265D-17.ucode": "iwlwifi-7265-16.ucode";
   7574  1.45   nonaka 		sc->host_interrupt_operation_mode = 0;
   7575  1.59   nonaka 		sc->apmg_wake_up_wa = 1;
   7576  1.45   nonaka 		sc->sc_device_family = IWM_DEVICE_FAMILY_7000;
   7577  1.45   nonaka 		sc->sc_fwdmasegsz = IWM_FWDMASEGSZ;
   7578  1.45   nonaka 		break;
   7579  1.45   nonaka 	case PCI_PRODUCT_INTEL_WIFI_LINK_8260_1:
   7580  1.45   nonaka 	case PCI_PRODUCT_INTEL_WIFI_LINK_8260_2:
   7581  1.58   nonaka 	case PCI_PRODUCT_INTEL_WIFI_LINK_4165_1:
   7582  1.58   nonaka 	case PCI_PRODUCT_INTEL_WIFI_LINK_4165_2:
   7583  1.45   nonaka 		sc->sc_fwname = "iwlwifi-8000C-16.ucode";
   7584  1.17   nonaka 		sc->host_interrupt_operation_mode = 0;
   7585  1.59   nonaka 		sc->apmg_wake_up_wa = 0;
   7586  1.45   nonaka 		sc->sc_device_family = IWM_DEVICE_FAMILY_8000;
   7587  1.45   nonaka 		sc->sc_fwdmasegsz = IWM_FWDMASEGSZ_8000;
   7588   1.5   nonaka 		break;
   7589   1.5   nonaka 	default:
   7590   1.5   nonaka 		aprint_error_dev(self, "unknown product %#x",
   7591   1.5   nonaka 		    PCI_PRODUCT(sc->sc_pciid));
   7592   1.5   nonaka 		return;
   7593   1.5   nonaka 	}
   7594   1.5   nonaka 	DPRINTF(("%s: firmware=%s\n", DEVNAME(sc), sc->sc_fwname));
   7595   1.2   nonaka 
   7596   1.2   nonaka 	/*
   7597  1.45   nonaka 	 * In the 8000 HW family the format of the 4 bytes of CSR_HW_REV have
   7598  1.45   nonaka 	 * changed, and now the revision step also includes bit 0-1 (no more
   7599  1.45   nonaka 	 * "dash" value). To keep hw_rev backwards compatible - we'll store it
   7600  1.45   nonaka 	 * in the old format.
   7601   1.2   nonaka 	 */
   7602   1.2   nonaka 
   7603  1.45   nonaka 	if (sc->sc_device_family == IWM_DEVICE_FAMILY_8000)
   7604  1.45   nonaka 		sc->sc_hw_rev = (sc->sc_hw_rev & 0xfff0) |
   7605  1.45   nonaka 		    (IWM_CSR_HW_REV_STEP(sc->sc_hw_rev << 2) << 2);
   7606  1.45   nonaka 
   7607   1.2   nonaka 	if (iwm_prepare_card_hw(sc) != 0) {
   7608   1.3   nonaka 		aprint_error_dev(sc->sc_dev, "could not initialize hardware\n");
   7609   1.2   nonaka 		return;
   7610   1.2   nonaka 	}
   7611   1.2   nonaka 
   7612  1.45   nonaka 	if (sc->sc_device_family == IWM_DEVICE_FAMILY_8000) {
   7613  1.45   nonaka 		uint32_t hw_step;
   7614  1.45   nonaka 
   7615  1.45   nonaka 		/*
   7616  1.45   nonaka 		 * In order to recognize C step the driver should read the
   7617  1.45   nonaka 		 * chip version id located at the AUX bus MISC address.
   7618  1.45   nonaka 		 */
   7619  1.45   nonaka 		IWM_SETBITS(sc, IWM_CSR_GP_CNTRL,
   7620  1.45   nonaka 			    IWM_CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
   7621  1.45   nonaka 		DELAY(2);
   7622  1.45   nonaka 
   7623  1.45   nonaka 		err = iwm_poll_bit(sc, IWM_CSR_GP_CNTRL,
   7624  1.45   nonaka 				   IWM_CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
   7625  1.45   nonaka 				   IWM_CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
   7626  1.45   nonaka 				   25000);
   7627  1.45   nonaka 		if (!err) {
   7628  1.45   nonaka 			aprint_error_dev(sc->sc_dev,
   7629  1.45   nonaka 			    "failed to wake up the nic\n");
   7630  1.45   nonaka 			return;
   7631  1.45   nonaka 		}
   7632  1.45   nonaka 
   7633  1.45   nonaka 		if (iwm_nic_lock(sc)) {
   7634  1.45   nonaka 			hw_step = iwm_read_prph(sc, IWM_WFPM_CTRL_REG);
   7635  1.45   nonaka 			hw_step |= IWM_ENABLE_WFPM;
   7636  1.45   nonaka 			iwm_write_prph(sc, IWM_WFPM_CTRL_REG, hw_step);
   7637  1.45   nonaka 			hw_step = iwm_read_prph(sc, IWM_AUX_MISC_REG);
   7638  1.45   nonaka 			hw_step = (hw_step >> IWM_HW_STEP_LOCATION_BITS) & 0xF;
   7639  1.45   nonaka 			if (hw_step == 0x3)
   7640  1.45   nonaka 				sc->sc_hw_rev = (sc->sc_hw_rev & 0xFFFFFFF3) |
   7641  1.45   nonaka 				    (IWM_SILICON_C_STEP << 2);
   7642  1.45   nonaka 			iwm_nic_unlock(sc);
   7643  1.45   nonaka 		} else {
   7644  1.45   nonaka 			aprint_error_dev(sc->sc_dev,
   7645  1.45   nonaka 			    "failed to lock the nic\n");
   7646  1.45   nonaka 			return;
   7647  1.45   nonaka 		}
   7648  1.45   nonaka 	}
   7649  1.45   nonaka 
   7650  1.45   nonaka 	/*
   7651  1.45   nonaka 	 * Allocate DMA memory for firmware transfers.
   7652  1.45   nonaka 	 * Must be aligned on a 16-byte boundary.
   7653  1.45   nonaka 	 */
   7654  1.45   nonaka 	err = iwm_dma_contig_alloc(sc->sc_dmat, &sc->fw_dma, sc->sc_fwdmasegsz,
   7655  1.45   nonaka 	    16);
   7656  1.45   nonaka 	if (err) {
   7657   1.3   nonaka 		aprint_error_dev(sc->sc_dev,
   7658   1.3   nonaka 		    "could not allocate memory for firmware\n");
   7659   1.2   nonaka 		return;
   7660   1.2   nonaka 	}
   7661   1.2   nonaka 
   7662  1.45   nonaka 	/* Allocate "Keep Warm" page, used internally by the card. */
   7663  1.45   nonaka 	err = iwm_dma_contig_alloc(sc->sc_dmat, &sc->kw_dma, 4096, 4096);
   7664  1.45   nonaka 	if (err) {
   7665   1.3   nonaka 		aprint_error_dev(sc->sc_dev,
   7666   1.3   nonaka 		    "could not allocate keep warm page\n");
   7667   1.2   nonaka 		goto fail1;
   7668   1.2   nonaka 	}
   7669   1.2   nonaka 
   7670  1.45   nonaka 	/* Allocate interrupt cause table (ICT).*/
   7671  1.45   nonaka 	err = iwm_dma_contig_alloc(sc->sc_dmat, &sc->ict_dma, IWM_ICT_SIZE,
   7672  1.45   nonaka 	    1 << IWM_ICT_PADDR_SHIFT);
   7673  1.45   nonaka 	if (err) {
   7674   1.3   nonaka 		aprint_error_dev(sc->sc_dev, "could not allocate ICT table\n");
   7675   1.2   nonaka 		goto fail2;
   7676   1.2   nonaka 	}
   7677   1.2   nonaka 
   7678  1.45   nonaka 	/* TX scheduler rings must be aligned on a 1KB boundary. */
   7679  1.45   nonaka 	err = iwm_dma_contig_alloc(sc->sc_dmat, &sc->sched_dma,
   7680  1.45   nonaka 	    __arraycount(sc->txq) * sizeof(struct iwm_agn_scd_bc_tbl), 1024);
   7681  1.45   nonaka 	if (err) {
   7682   1.3   nonaka 		aprint_error_dev(sc->sc_dev,
   7683   1.3   nonaka 		    "could not allocate TX scheduler rings\n");
   7684   1.2   nonaka 		goto fail3;
   7685   1.2   nonaka 	}
   7686   1.2   nonaka 
   7687   1.2   nonaka 	for (txq_i = 0; txq_i < __arraycount(sc->txq); txq_i++) {
   7688  1.45   nonaka 		err = iwm_alloc_tx_ring(sc, &sc->txq[txq_i], txq_i);
   7689  1.45   nonaka 		if (err) {
   7690   1.3   nonaka 			aprint_error_dev(sc->sc_dev,
   7691   1.3   nonaka 			    "could not allocate TX ring %d\n", txq_i);
   7692   1.2   nonaka 			goto fail4;
   7693   1.2   nonaka 		}
   7694   1.2   nonaka 	}
   7695   1.2   nonaka 
   7696  1.45   nonaka 	err = iwm_alloc_rx_ring(sc, &sc->rxq);
   7697  1.45   nonaka 	if (err) {
   7698   1.3   nonaka 		aprint_error_dev(sc->sc_dev, "could not allocate RX ring\n");
   7699   1.2   nonaka 		goto fail4;
   7700   1.2   nonaka 	}
   7701   1.2   nonaka 
   7702   1.2   nonaka 	/* Clear pending interrupts. */
   7703   1.2   nonaka 	IWM_WRITE(sc, IWM_CSR_INT, 0xffffffff);
   7704   1.2   nonaka 
   7705  1.45   nonaka 	if ((err = sysctl_createv(&sc->sc_clog, 0, NULL, &node,
   7706  1.36   nonaka 	    0, CTLTYPE_NODE, device_xname(sc->sc_dev),
   7707  1.36   nonaka 	    SYSCTL_DESCR("iwm per-controller controls"),
   7708  1.36   nonaka 	    NULL, 0, NULL, 0,
   7709  1.36   nonaka 	    CTL_HW, iwm_sysctl_root_num, CTL_CREATE,
   7710  1.36   nonaka 	    CTL_EOL)) != 0) {
   7711  1.36   nonaka 		aprint_normal_dev(sc->sc_dev,
   7712  1.36   nonaka 		    "couldn't create iwm per-controller sysctl node\n");
   7713  1.36   nonaka 	}
   7714  1.45   nonaka 	if (err == 0) {
   7715  1.36   nonaka 		int iwm_nodenum = node->sysctl_num;
   7716  1.36   nonaka 
   7717  1.36   nonaka 		/* Reload firmware sysctl node */
   7718  1.45   nonaka 		if ((err = sysctl_createv(&sc->sc_clog, 0, NULL, &node,
   7719  1.36   nonaka 		    CTLFLAG_READWRITE, CTLTYPE_INT, "fw_loaded",
   7720  1.36   nonaka 		    SYSCTL_DESCR("Reload firmware"),
   7721  1.36   nonaka 		    iwm_sysctl_fw_loaded_handler, 0, (void *)sc, 0,
   7722  1.36   nonaka 		    CTL_HW, iwm_sysctl_root_num, iwm_nodenum, CTL_CREATE,
   7723  1.36   nonaka 		    CTL_EOL)) != 0) {
   7724  1.36   nonaka 			aprint_normal_dev(sc->sc_dev,
   7725  1.36   nonaka 			    "couldn't create load_fw sysctl node\n");
   7726  1.36   nonaka 		}
   7727  1.36   nonaka 	}
   7728  1.36   nonaka 
   7729  1.36   nonaka 	/*
   7730  1.36   nonaka 	 * Attach interface
   7731  1.36   nonaka 	 */
   7732  1.36   nonaka 	ic->ic_ifp = ifp;
   7733  1.36   nonaka 	ic->ic_phytype = IEEE80211_T_OFDM;	/* not only, but not used */
   7734  1.36   nonaka 	ic->ic_opmode = IEEE80211_M_STA;	/* default to BSS mode */
   7735  1.36   nonaka 	ic->ic_state = IEEE80211_S_INIT;
   7736  1.36   nonaka 
   7737  1.36   nonaka 	/* Set device capabilities. */
   7738  1.36   nonaka 	ic->ic_caps =
   7739  1.36   nonaka 	    IEEE80211_C_WEP |		/* WEP */
   7740  1.36   nonaka 	    IEEE80211_C_WPA |		/* 802.11i */
   7741  1.45   nonaka #ifdef notyet
   7742  1.45   nonaka 	    IEEE80211_C_SCANALL |	/* device scans all channels at once */
   7743  1.45   nonaka 	    IEEE80211_C_SCANALLBAND |	/* device scans all bands at once */
   7744  1.45   nonaka #endif
   7745  1.36   nonaka 	    IEEE80211_C_SHSLOT |	/* short slot time supported */
   7746  1.36   nonaka 	    IEEE80211_C_SHPREAMBLE;	/* short preamble supported */
   7747  1.36   nonaka 
   7748  1.45   nonaka #ifndef IEEE80211_NO_HT
   7749  1.45   nonaka 	ic->ic_htcaps = IEEE80211_HTCAP_SGI20;
   7750  1.45   nonaka 	ic->ic_htxcaps = 0;
   7751  1.45   nonaka 	ic->ic_txbfcaps = 0;
   7752  1.45   nonaka 	ic->ic_aselcaps = 0;
   7753  1.45   nonaka 	ic->ic_ampdu_params = (IEEE80211_AMPDU_PARAM_SS_4 | 0x3 /* 64k */);
   7754  1.45   nonaka #endif
   7755  1.45   nonaka 
   7756  1.36   nonaka 	/* all hardware can do 2.4GHz band */
   7757  1.36   nonaka 	ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b;
   7758  1.36   nonaka 	ic->ic_sup_rates[IEEE80211_MODE_11G] = ieee80211_std_rateset_11g;
   7759  1.36   nonaka 
   7760  1.36   nonaka 	for (int i = 0; i < __arraycount(sc->sc_phyctxt); i++) {
   7761  1.36   nonaka 		sc->sc_phyctxt[i].id = i;
   7762  1.36   nonaka 	}
   7763  1.36   nonaka 
   7764  1.36   nonaka 	sc->sc_amrr.amrr_min_success_threshold =  1;
   7765  1.36   nonaka 	sc->sc_amrr.amrr_max_success_threshold = 15;
   7766  1.36   nonaka 
   7767  1.36   nonaka 	/* IBSS channel undefined for now. */
   7768  1.36   nonaka 	ic->ic_ibss_chan = &ic->ic_channels[1];
   7769  1.36   nonaka 
   7770  1.36   nonaka #if 0
   7771  1.36   nonaka 	ic->ic_max_rssi = IWM_MAX_DBM - IWM_MIN_DBM;
   7772  1.36   nonaka #endif
   7773  1.36   nonaka 
   7774  1.36   nonaka 	ifp->if_softc = sc;
   7775  1.36   nonaka 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
   7776  1.36   nonaka 	ifp->if_init = iwm_init;
   7777  1.36   nonaka 	ifp->if_stop = iwm_stop;
   7778  1.36   nonaka 	ifp->if_ioctl = iwm_ioctl;
   7779  1.36   nonaka 	ifp->if_start = iwm_start;
   7780  1.36   nonaka 	ifp->if_watchdog = iwm_watchdog;
   7781  1.36   nonaka 	IFQ_SET_READY(&ifp->if_snd);
   7782  1.36   nonaka 	memcpy(ifp->if_xname, DEVNAME(sc), IFNAMSIZ);
   7783  1.36   nonaka 
   7784  1.36   nonaka 	if_initialize(ifp);
   7785  1.36   nonaka #if 0
   7786  1.36   nonaka 	ieee80211_ifattach(ic);
   7787  1.36   nonaka #else
   7788  1.36   nonaka 	ether_ifattach(ifp, ic->ic_myaddr);	/* XXX */
   7789  1.36   nonaka #endif
   7790  1.40    ozaki 	/* Use common softint-based if_input */
   7791  1.40    ozaki 	ifp->if_percpuq = if_percpuq_create(ifp);
   7792  1.44    ozaki 	if_register(ifp);
   7793  1.36   nonaka 
   7794  1.36   nonaka 	callout_init(&sc->sc_calib_to, 0);
   7795  1.36   nonaka 	callout_setfunc(&sc->sc_calib_to, iwm_calib_timeout, sc);
   7796  1.45   nonaka 	callout_init(&sc->sc_led_blink_to, 0);
   7797  1.45   nonaka 	callout_setfunc(&sc->sc_led_blink_to, iwm_led_blink_timeout, sc);
   7798  1.45   nonaka #ifndef IEEE80211_NO_HT
   7799  1.45   nonaka 	if (workqueue_create(&sc->sc_setratewq, "iwmsr",
   7800  1.45   nonaka 	    iwm_setrates_task, sc, PRI_NONE, IPL_NET, 0))
   7801  1.45   nonaka 		panic("%s: could not create workqueue: setrates",
   7802  1.45   nonaka 		    device_xname(self));
   7803  1.45   nonaka 	if (workqueue_create(&sc->sc_bawq, "iwmba",
   7804  1.45   nonaka 	    iwm_ba_task, sc, PRI_NONE, IPL_NET, 0))
   7805  1.45   nonaka 		panic("%s: could not create workqueue: blockack",
   7806  1.45   nonaka 		    device_xname(self));
   7807  1.45   nonaka 	if (workqueue_create(&sc->sc_htprowq, "iwmhtpro",
   7808  1.45   nonaka 	    iwm_htprot_task, sc, PRI_NONE, IPL_NET, 0))
   7809  1.45   nonaka 		panic("%s: could not create workqueue: htprot",
   7810  1.45   nonaka 		    device_xname(self));
   7811  1.45   nonaka #endif
   7812  1.36   nonaka 
   7813  1.36   nonaka 	if (pmf_device_register(self, NULL, NULL))
   7814  1.36   nonaka 		pmf_class_network_register(self, ifp);
   7815  1.36   nonaka 	else
   7816  1.36   nonaka 		aprint_error_dev(self, "couldn't establish power handler\n");
   7817  1.36   nonaka 
   7818   1.1    pooka 	/*
   7819   1.1    pooka 	 * We can't do normal attach before the file system is mounted
   7820   1.1    pooka 	 * because we cannot read the MAC address without loading the
   7821   1.1    pooka 	 * firmware from disk.  So we postpone until mountroot is done.
   7822   1.1    pooka 	 * Notably, this will require a full driver unload/load cycle
   7823   1.1    pooka 	 * (or reboot) in case the firmware is not present when the
   7824   1.1    pooka 	 * hook runs.
   7825   1.1    pooka 	 */
   7826   1.1    pooka 	config_mountroot(self, iwm_attach_hook);
   7827   1.2   nonaka 
   7828   1.2   nonaka 	return;
   7829   1.2   nonaka 
   7830   1.2   nonaka fail4:	while (--txq_i >= 0)
   7831   1.2   nonaka 		iwm_free_tx_ring(sc, &sc->txq[txq_i]);
   7832  1.45   nonaka 	iwm_free_rx_ring(sc, &sc->rxq);
   7833  1.45   nonaka 	iwm_dma_contig_free(&sc->sched_dma);
   7834   1.2   nonaka fail3:	if (sc->ict_dma.vaddr != NULL)
   7835  1.45   nonaka 		iwm_dma_contig_free(&sc->ict_dma);
   7836  1.45   nonaka fail2:	iwm_dma_contig_free(&sc->kw_dma);
   7837  1.45   nonaka fail1:	iwm_dma_contig_free(&sc->fw_dma);
   7838   1.1    pooka }
   7839   1.1    pooka 
   7840   1.1    pooka void
   7841   1.1    pooka iwm_radiotap_attach(struct iwm_softc *sc)
   7842   1.1    pooka {
   7843  1.47   nonaka 	struct ifnet *ifp = IC2IFP(&sc->sc_ic);
   7844   1.1    pooka 
   7845   1.1    pooka 	bpf_attach2(ifp, DLT_IEEE802_11_RADIO,
   7846   1.1    pooka 	    sizeof (struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN,
   7847   1.1    pooka 	    &sc->sc_drvbpf);
   7848   1.1    pooka 
   7849   1.1    pooka 	sc->sc_rxtap_len = sizeof sc->sc_rxtapu;
   7850   1.1    pooka 	sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
   7851   1.1    pooka 	sc->sc_rxtap.wr_ihdr.it_present = htole32(IWM_RX_RADIOTAP_PRESENT);
   7852   1.1    pooka 
   7853   1.1    pooka 	sc->sc_txtap_len = sizeof sc->sc_txtapu;
   7854   1.1    pooka 	sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
   7855   1.1    pooka 	sc->sc_txtap.wt_ihdr.it_present = htole32(IWM_TX_RADIOTAP_PRESENT);
   7856   1.1    pooka }
   7857   1.1    pooka 
   7858   1.1    pooka #if 0
   7859   1.4   nonaka static void
   7860  1.47   nonaka iwm_init_task(void *arg)
   7861   1.1    pooka {
   7862  1.47   nonaka 	struct iwm_softc *sc = arg;
   7863  1.47   nonaka 	struct ifnet *ifp = IC2IFP(&sc->sc_ic);
   7864   1.1    pooka 	int s;
   7865   1.8   nonaka 
   7866  1.45   nonaka 	rw_enter_write(&sc->ioctl_rwl);
   7867   1.1    pooka 	s = splnet();
   7868   1.8   nonaka 
   7869   1.1    pooka 	iwm_stop(ifp, 0);
   7870   1.1    pooka 	if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == IFF_UP)
   7871   1.1    pooka 		iwm_init(ifp);
   7872   1.1    pooka 
   7873   1.1    pooka 	splx(s);
   7874  1.45   nonaka 	rw_exit(&sc->ioctl_rwl);
   7875   1.1    pooka }
   7876   1.1    pooka 
   7877   1.4   nonaka static void
   7878   1.1    pooka iwm_wakeup(struct iwm_softc *sc)
   7879   1.1    pooka {
   7880   1.1    pooka 	pcireg_t reg;
   7881   1.1    pooka 
   7882   1.1    pooka 	/* Clear device-specific "PCI retry timeout" register (41h). */
   7883   1.1    pooka 	reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag, 0x40);
   7884   1.1    pooka 	pci_conf_write(sc->sc_pct, sc->sc_pcitag, 0x40, reg & ~0xff00);
   7885   1.1    pooka 
   7886   1.1    pooka 	iwm_init_task(sc);
   7887   1.1    pooka }
   7888   1.1    pooka 
   7889   1.4   nonaka static int
   7890   1.4   nonaka iwm_activate(device_t self, enum devact act)
   7891   1.1    pooka {
   7892   1.4   nonaka 	struct iwm_softc *sc = device_private(self);
   7893   1.4   nonaka 	struct ifnet *ifp = IC2IFP(&sc->sc_ic);
   7894   1.1    pooka 
   7895   1.1    pooka 	switch (act) {
   7896   1.4   nonaka 	case DVACT_DEACTIVATE:
   7897   1.1    pooka 		if (ifp->if_flags & IFF_RUNNING)
   7898   1.1    pooka 			iwm_stop(ifp, 0);
   7899   1.4   nonaka 		return 0;
   7900   1.4   nonaka 	default:
   7901   1.4   nonaka 		return EOPNOTSUPP;
   7902   1.1    pooka 	}
   7903   1.1    pooka }
   7904   1.1    pooka #endif
   7905   1.1    pooka 
   7906   1.1    pooka CFATTACH_DECL_NEW(iwm, sizeof(struct iwm_softc), iwm_match, iwm_attach,
   7907   1.1    pooka 	NULL, NULL);
   7908  1.32   nonaka 
   7909  1.36   nonaka static int
   7910  1.36   nonaka iwm_sysctl_fw_loaded_handler(SYSCTLFN_ARGS)
   7911  1.36   nonaka {
   7912  1.36   nonaka 	struct sysctlnode node;
   7913  1.36   nonaka 	struct iwm_softc *sc;
   7914  1.45   nonaka 	int err, t;
   7915  1.36   nonaka 
   7916  1.36   nonaka 	node = *rnode;
   7917  1.36   nonaka 	sc = node.sysctl_data;
   7918  1.36   nonaka 	t = ISSET(sc->sc_flags, IWM_FLAG_FW_LOADED) ? 1 : 0;
   7919  1.36   nonaka 	node.sysctl_data = &t;
   7920  1.45   nonaka 	err = sysctl_lookup(SYSCTLFN_CALL(&node));
   7921  1.45   nonaka 	if (err || newp == NULL)
   7922  1.45   nonaka 		return err;
   7923  1.36   nonaka 
   7924  1.36   nonaka 	if (t == 0)
   7925  1.36   nonaka 		CLR(sc->sc_flags, IWM_FLAG_FW_LOADED);
   7926  1.36   nonaka 	return 0;
   7927  1.36   nonaka }
   7928  1.36   nonaka 
   7929  1.32   nonaka SYSCTL_SETUP(sysctl_iwm, "sysctl iwm(4) subtree setup")
   7930  1.32   nonaka {
   7931  1.36   nonaka 	const struct sysctlnode *rnode;
   7932  1.36   nonaka #ifdef IWM_DEBUG
   7933  1.36   nonaka 	const struct sysctlnode *cnode;
   7934  1.36   nonaka #endif /* IWM_DEBUG */
   7935  1.32   nonaka 	int rc;
   7936  1.32   nonaka 
   7937  1.32   nonaka 	if ((rc = sysctl_createv(clog, 0, NULL, &rnode,
   7938  1.32   nonaka 	    CTLFLAG_PERMANENT, CTLTYPE_NODE, "iwm",
   7939  1.32   nonaka 	    SYSCTL_DESCR("iwm global controls"),
   7940  1.32   nonaka 	    NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL)) != 0)
   7941  1.32   nonaka 		goto err;
   7942  1.32   nonaka 
   7943  1.36   nonaka 	iwm_sysctl_root_num = rnode->sysctl_num;
   7944  1.36   nonaka 
   7945  1.36   nonaka #ifdef IWM_DEBUG
   7946  1.32   nonaka 	/* control debugging printfs */
   7947  1.32   nonaka 	if ((rc = sysctl_createv(clog, 0, &rnode, &cnode,
   7948  1.32   nonaka 	    CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
   7949  1.32   nonaka 	    "debug", SYSCTL_DESCR("Enable debugging output"),
   7950  1.32   nonaka 	    NULL, 0, &iwm_debug, 0, CTL_CREATE, CTL_EOL)) != 0)
   7951  1.32   nonaka 		goto err;
   7952  1.36   nonaka #endif /* IWM_DEBUG */
   7953  1.32   nonaka 
   7954  1.32   nonaka 	return;
   7955  1.32   nonaka 
   7956  1.32   nonaka  err:
   7957  1.32   nonaka 	aprint_error("%s: sysctl_createv failed (rc = %d)\n", __func__, rc);
   7958  1.32   nonaka }
   7959