Home | History | Annotate | Line # | Download | only in pci
if_iwm.c revision 1.33
      1  1.33  knakahar /*	$NetBSD: if_iwm.c,v 1.33 2015/05/15 08:44:15 knakahara Exp $	*/
      2  1.29    nonaka /*	OpenBSD: if_iwm.c,v 1.39 2015/03/23 00:35:19 jsg Exp	*/
      3   1.1     pooka 
      4   1.1     pooka /*
      5   1.1     pooka  * Copyright (c) 2014 genua mbh <info (at) genua.de>
      6   1.1     pooka  * Copyright (c) 2014 Fixup Software Ltd.
      7   1.1     pooka  *
      8   1.1     pooka  * Permission to use, copy, modify, and distribute this software for any
      9   1.1     pooka  * purpose with or without fee is hereby granted, provided that the above
     10   1.1     pooka  * copyright notice and this permission notice appear in all copies.
     11   1.1     pooka  *
     12   1.1     pooka  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
     13   1.1     pooka  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     14   1.1     pooka  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     15   1.1     pooka  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     16   1.1     pooka  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     17   1.1     pooka  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     18   1.1     pooka  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     19   1.1     pooka  */
     20   1.1     pooka 
     21   1.1     pooka /*-
     22   1.1     pooka  * Based on BSD-licensed source modules in the Linux iwlwifi driver,
     23   1.1     pooka  * which were used as the reference documentation for this implementation.
     24   1.1     pooka  *
     25   1.1     pooka  * Driver version we are currently based off of is
     26   1.1     pooka  * Linux 3.14.3 (tag id a2df521e42b1d9a23f620ac79dbfe8655a8391dd)
     27   1.1     pooka  *
     28   1.1     pooka  ***********************************************************************
     29   1.1     pooka  *
     30   1.1     pooka  * This file is provided under a dual BSD/GPLv2 license.  When using or
     31   1.1     pooka  * redistributing this file, you may do so under either license.
     32   1.1     pooka  *
     33   1.1     pooka  * GPL LICENSE SUMMARY
     34   1.1     pooka  *
     35   1.1     pooka  * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved.
     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.1     pooka  * All rights reserved.
     63   1.1     pooka  *
     64   1.1     pooka  * Redistribution and use in source and binary forms, with or without
     65   1.1     pooka  * modification, are permitted provided that the following conditions
     66   1.1     pooka  * are met:
     67   1.1     pooka  *
     68   1.1     pooka  *  * Redistributions of source code must retain the above copyright
     69   1.1     pooka  *    notice, this list of conditions and the following disclaimer.
     70   1.1     pooka  *  * Redistributions in binary form must reproduce the above copyright
     71   1.1     pooka  *    notice, this list of conditions and the following disclaimer in
     72   1.1     pooka  *    the documentation and/or other materials provided with the
     73   1.1     pooka  *    distribution.
     74   1.1     pooka  *  * Neither the name Intel Corporation nor the names of its
     75   1.1     pooka  *    contributors may be used to endorse or promote products derived
     76   1.1     pooka  *    from this software without specific prior written permission.
     77   1.1     pooka  *
     78   1.1     pooka  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     79   1.1     pooka  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     80   1.1     pooka  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     81   1.1     pooka  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     82   1.1     pooka  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     83   1.1     pooka  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     84   1.1     pooka  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     85   1.1     pooka  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     86   1.1     pooka  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     87   1.1     pooka  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     88   1.1     pooka  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     89   1.1     pooka  */
     90   1.1     pooka 
     91   1.1     pooka /*-
     92   1.1     pooka  * Copyright (c) 2007-2010 Damien Bergamini <damien.bergamini (at) free.fr>
     93   1.1     pooka  *
     94   1.1     pooka  * Permission to use, copy, modify, and distribute this software for any
     95   1.1     pooka  * purpose with or without fee is hereby granted, provided that the above
     96   1.1     pooka  * copyright notice and this permission notice appear in all copies.
     97   1.1     pooka  *
     98   1.1     pooka  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
     99   1.1     pooka  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
    100   1.1     pooka  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
    101   1.1     pooka  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
    102   1.1     pooka  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
    103   1.1     pooka  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
    104   1.1     pooka  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
    105   1.1     pooka  */
    106   1.1     pooka 
    107   1.1     pooka #include <sys/cdefs.h>
    108  1.33  knakahar __KERNEL_RCSID(0, "$NetBSD: if_iwm.c,v 1.33 2015/05/15 08:44:15 knakahara Exp $");
    109   1.1     pooka 
    110   1.1     pooka #include <sys/param.h>
    111   1.1     pooka #include <sys/conf.h>
    112   1.1     pooka #include <sys/kernel.h>
    113   1.1     pooka #include <sys/kmem.h>
    114   1.1     pooka #include <sys/mbuf.h>
    115   1.1     pooka #include <sys/mutex.h>
    116   1.1     pooka #include <sys/proc.h>
    117   1.1     pooka #include <sys/socket.h>
    118   1.1     pooka #include <sys/sockio.h>
    119  1.32    nonaka #include <sys/sysctl.h>
    120   1.1     pooka #include <sys/systm.h>
    121   1.1     pooka 
    122   1.1     pooka #include <sys/cpu.h>
    123   1.1     pooka #include <sys/bus.h>
    124   1.1     pooka #include <sys/workqueue.h>
    125   1.1     pooka #include <machine/endian.h>
    126   1.1     pooka #include <machine/intr.h>
    127   1.1     pooka 
    128   1.1     pooka #include <dev/pci/pcireg.h>
    129   1.1     pooka #include <dev/pci/pcivar.h>
    130   1.1     pooka #include <dev/pci/pcidevs.h>
    131   1.1     pooka #include <dev/firmload.h>
    132   1.1     pooka 
    133   1.1     pooka #include <net/bpf.h>
    134   1.1     pooka #include <net/if.h>
    135   1.1     pooka #include <net/if_arp.h>
    136   1.1     pooka #include <net/if_dl.h>
    137   1.1     pooka #include <net/if_media.h>
    138   1.1     pooka #include <net/if_types.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/in_systm.h>
    143   1.1     pooka #include <netinet/ip.h>
    144   1.1     pooka 
    145   1.1     pooka #include <net80211/ieee80211_var.h>
    146   1.1     pooka #include <net80211/ieee80211_amrr.h>
    147   1.1     pooka #include <net80211/ieee80211_radiotap.h>
    148   1.1     pooka 
    149   1.1     pooka #define DEVNAME(_s)	device_xname((_s)->sc_dev)
    150   1.1     pooka #define IC2IFP(_ic_)	((_ic_)->ic_ifp)
    151   1.1     pooka 
    152   1.1     pooka #define le16_to_cpup(_a_) (le16toh(*(const uint16_t *)(_a_)))
    153   1.1     pooka #define le32_to_cpup(_a_) (le32toh(*(const uint32_t *)(_a_)))
    154   1.1     pooka 
    155   1.1     pooka #ifdef IWM_DEBUG
    156   1.1     pooka #define DPRINTF(x)	do { if (iwm_debug > 0) printf x; } while (0)
    157   1.1     pooka #define DPRINTFN(n, x)	do { if (iwm_debug >= (n)) printf x; } while (0)
    158  1.32    nonaka int iwm_debug = 0;
    159   1.1     pooka #else
    160   1.1     pooka #define DPRINTF(x)	do { ; } while (0)
    161   1.1     pooka #define DPRINTFN(n, x)	do { ; } while (0)
    162   1.1     pooka #endif
    163   1.1     pooka 
    164   1.1     pooka #include <dev/pci/if_iwmreg.h>
    165   1.1     pooka #include <dev/pci/if_iwmvar.h>
    166   1.1     pooka 
    167   1.4    nonaka static const uint8_t iwm_nvm_channels[] = {
    168   1.1     pooka 	/* 2.4 GHz */
    169   1.1     pooka 	1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
    170   1.1     pooka 	/* 5 GHz */
    171   1.1     pooka 	36, 40, 44 , 48, 52, 56, 60, 64,
    172   1.1     pooka 	100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144,
    173   1.1     pooka 	149, 153, 157, 161, 165
    174   1.1     pooka };
    175   1.1     pooka #define IWM_NUM_2GHZ_CHANNELS	14
    176   1.1     pooka 
    177   1.4    nonaka static const struct iwm_rate {
    178   1.1     pooka 	uint8_t rate;
    179   1.1     pooka 	uint8_t plcp;
    180   1.1     pooka } iwm_rates[] = {
    181   1.1     pooka 	{   2,	IWM_RATE_1M_PLCP  },
    182   1.1     pooka 	{   4,	IWM_RATE_2M_PLCP  },
    183   1.1     pooka 	{  11,	IWM_RATE_5M_PLCP  },
    184   1.1     pooka 	{  22,	IWM_RATE_11M_PLCP },
    185   1.1     pooka 	{  12,	IWM_RATE_6M_PLCP  },
    186   1.1     pooka 	{  18,	IWM_RATE_9M_PLCP  },
    187   1.1     pooka 	{  24,	IWM_RATE_12M_PLCP },
    188   1.1     pooka 	{  36,	IWM_RATE_18M_PLCP },
    189   1.1     pooka 	{  48,	IWM_RATE_24M_PLCP },
    190   1.1     pooka 	{  72,	IWM_RATE_36M_PLCP },
    191   1.1     pooka 	{  96,	IWM_RATE_48M_PLCP },
    192   1.1     pooka 	{ 108,	IWM_RATE_54M_PLCP },
    193   1.1     pooka };
    194   1.1     pooka #define IWM_RIDX_CCK	0
    195   1.1     pooka #define IWM_RIDX_OFDM	4
    196   1.1     pooka #define IWM_RIDX_MAX	(__arraycount(iwm_rates)-1)
    197   1.1     pooka #define IWM_RIDX_IS_CCK(_i_) ((_i_) < IWM_RIDX_OFDM)
    198   1.1     pooka #define IWM_RIDX_IS_OFDM(_i_) ((_i_) >= IWM_RIDX_OFDM)
    199   1.1     pooka 
    200   1.1     pooka struct iwm_newstate_state {
    201   1.1     pooka 	struct work ns_wk;
    202   1.1     pooka 	enum ieee80211_state ns_nstate;
    203   1.1     pooka 	int ns_arg;
    204   1.1     pooka 	int ns_generation;
    205   1.1     pooka };
    206   1.1     pooka 
    207   1.4    nonaka static int	iwm_store_cscheme(struct iwm_softc *, uint8_t *, size_t);
    208   1.4    nonaka static int	iwm_firmware_store_section(struct iwm_softc *,
    209   1.4    nonaka 		    enum iwm_ucode_type, uint8_t *, size_t);
    210   1.4    nonaka static int	iwm_set_default_calib(struct iwm_softc *, const void *);
    211   1.4    nonaka static int	iwm_read_firmware(struct iwm_softc *);
    212   1.4    nonaka static uint32_t iwm_read_prph(struct iwm_softc *, uint32_t);
    213   1.4    nonaka static void	iwm_write_prph(struct iwm_softc *, uint32_t, uint32_t);
    214   1.2    nonaka #ifdef IWM_DEBUG
    215   1.4    nonaka static int	iwm_read_mem(struct iwm_softc *, uint32_t, void *, int);
    216   1.2    nonaka #endif
    217   1.4    nonaka static int	iwm_write_mem(struct iwm_softc *, uint32_t, const void *, int);
    218   1.4    nonaka static int	iwm_write_mem32(struct iwm_softc *, uint32_t, uint32_t);
    219   1.4    nonaka static int	iwm_poll_bit(struct iwm_softc *, int, uint32_t, uint32_t, int);
    220   1.4    nonaka static int	iwm_nic_lock(struct iwm_softc *);
    221   1.4    nonaka static void	iwm_nic_unlock(struct iwm_softc *);
    222   1.4    nonaka static void	iwm_set_bits_mask_prph(struct iwm_softc *, uint32_t, uint32_t,
    223   1.8    nonaka 		    uint32_t);
    224   1.4    nonaka static void	iwm_set_bits_prph(struct iwm_softc *, uint32_t, uint32_t);
    225   1.4    nonaka static void	iwm_clear_bits_prph(struct iwm_softc *, uint32_t, uint32_t);
    226   1.4    nonaka static int	iwm_dma_contig_alloc(bus_dma_tag_t, struct iwm_dma_info *,
    227   1.4    nonaka 		    bus_size_t, bus_size_t);
    228   1.4    nonaka static void	iwm_dma_contig_free(struct iwm_dma_info *);
    229   1.4    nonaka static int	iwm_alloc_fwmem(struct iwm_softc *);
    230   1.4    nonaka static void	iwm_free_fwmem(struct iwm_softc *);
    231   1.4    nonaka static int	iwm_alloc_sched(struct iwm_softc *);
    232   1.4    nonaka static void	iwm_free_sched(struct iwm_softc *);
    233   1.4    nonaka static int	iwm_alloc_kw(struct iwm_softc *);
    234   1.4    nonaka static void	iwm_free_kw(struct iwm_softc *);
    235   1.4    nonaka static int	iwm_alloc_ict(struct iwm_softc *);
    236   1.4    nonaka static void	iwm_free_ict(struct iwm_softc *);
    237   1.4    nonaka static int	iwm_alloc_rx_ring(struct iwm_softc *, struct iwm_rx_ring *);
    238   1.4    nonaka static void	iwm_reset_rx_ring(struct iwm_softc *, struct iwm_rx_ring *);
    239   1.4    nonaka static void	iwm_free_rx_ring(struct iwm_softc *, struct iwm_rx_ring *);
    240   1.4    nonaka static int	iwm_alloc_tx_ring(struct iwm_softc *, struct iwm_tx_ring *,
    241   1.4    nonaka 		    int);
    242   1.4    nonaka static void	iwm_reset_tx_ring(struct iwm_softc *, struct iwm_tx_ring *);
    243   1.4    nonaka static void	iwm_free_tx_ring(struct iwm_softc *, struct iwm_tx_ring *);
    244   1.4    nonaka static void	iwm_enable_rfkill_int(struct iwm_softc *);
    245   1.4    nonaka static int	iwm_check_rfkill(struct iwm_softc *);
    246   1.4    nonaka static void	iwm_enable_interrupts(struct iwm_softc *);
    247   1.4    nonaka static void	iwm_restore_interrupts(struct iwm_softc *);
    248   1.4    nonaka static void	iwm_disable_interrupts(struct iwm_softc *);
    249   1.4    nonaka static void	iwm_ict_reset(struct iwm_softc *);
    250   1.4    nonaka static int	iwm_set_hw_ready(struct iwm_softc *);
    251   1.4    nonaka static int	iwm_prepare_card_hw(struct iwm_softc *);
    252   1.4    nonaka static void	iwm_apm_config(struct iwm_softc *);
    253   1.4    nonaka static int	iwm_apm_init(struct iwm_softc *);
    254   1.4    nonaka static void	iwm_apm_stop(struct iwm_softc *);
    255  1.11    nonaka static int	iwm_allow_mcast(struct iwm_softc *);
    256   1.4    nonaka static int	iwm_start_hw(struct iwm_softc *);
    257   1.4    nonaka static void	iwm_stop_device(struct iwm_softc *);
    258   1.4    nonaka static void	iwm_set_pwr(struct iwm_softc *);
    259   1.4    nonaka static void	iwm_mvm_nic_config(struct iwm_softc *);
    260   1.4    nonaka static int	iwm_nic_rx_init(struct iwm_softc *);
    261   1.4    nonaka static int	iwm_nic_tx_init(struct iwm_softc *);
    262   1.4    nonaka static int	iwm_nic_init(struct iwm_softc *);
    263   1.4    nonaka static void	iwm_enable_txq(struct iwm_softc *, int, int);
    264   1.4    nonaka static int	iwm_post_alive(struct iwm_softc *);
    265   1.4    nonaka static int	iwm_is_valid_channel(uint16_t);
    266   1.4    nonaka static uint8_t	iwm_ch_id_to_ch_index(uint16_t);
    267   1.4    nonaka static uint16_t iwm_channel_id_to_papd(uint16_t);
    268   1.4    nonaka static uint16_t iwm_channel_id_to_txp(struct iwm_softc *, uint16_t);
    269   1.4    nonaka static int	iwm_phy_db_get_section_data(struct iwm_softc *, uint32_t,
    270   1.4    nonaka 		    uint8_t **, uint16_t *, uint16_t);
    271   1.4    nonaka static int	iwm_send_phy_db_cmd(struct iwm_softc *, uint16_t, uint16_t,
    272   1.4    nonaka 		    void *);
    273   1.4    nonaka static int	iwm_send_phy_db_data(struct iwm_softc *);
    274   1.4    nonaka static int	iwm_send_phy_db_data(struct iwm_softc *);
    275   1.4    nonaka static void	iwm_mvm_te_v2_to_v1(const struct iwm_time_event_cmd_v2 *,
    276   1.4    nonaka 		    struct iwm_time_event_cmd_v1 *);
    277   1.4    nonaka static int	iwm_mvm_send_time_event_cmd(struct iwm_softc *,
    278   1.4    nonaka 		    const struct iwm_time_event_cmd_v2 *);
    279   1.4    nonaka static int	iwm_mvm_time_event_send_add(struct iwm_softc *,
    280   1.4    nonaka 		    struct iwm_node *, void *, struct iwm_time_event_cmd_v2 *);
    281   1.4    nonaka static void	iwm_mvm_protect_session(struct iwm_softc *, struct iwm_node *,
    282   1.4    nonaka 		    uint32_t, uint32_t, uint32_t);
    283   1.4    nonaka static int	iwm_nvm_read_chunk(struct iwm_softc *, uint16_t, uint16_t,
    284   1.4    nonaka 		    uint16_t, uint8_t *, uint16_t *);
    285   1.4    nonaka static int	iwm_nvm_read_section(struct iwm_softc *, uint16_t, uint8_t *,
    286   1.4    nonaka 		    uint16_t *);
    287   1.4    nonaka static void	iwm_init_channel_map(struct iwm_softc *,
    288   1.4    nonaka 		    const uint16_t * const);
    289   1.4    nonaka static int	iwm_parse_nvm_data(struct iwm_softc *, const uint16_t *,
    290   1.4    nonaka 		    const uint16_t *, const uint16_t *, uint8_t, uint8_t);
    291   1.4    nonaka static int	iwm_nvm_init(struct iwm_softc *);
    292   1.4    nonaka static int	iwm_firmware_load_chunk(struct iwm_softc *, uint32_t,
    293   1.4    nonaka 		    const uint8_t *, uint32_t);
    294   1.4    nonaka static int	iwm_load_firmware(struct iwm_softc *, enum iwm_ucode_type);
    295   1.4    nonaka static int	iwm_start_fw(struct iwm_softc *, enum iwm_ucode_type);
    296   1.4    nonaka static int	iwm_fw_alive(struct iwm_softc *, uint32_t);
    297   1.4    nonaka static int	iwm_send_tx_ant_cfg(struct iwm_softc *, uint8_t);
    298   1.4    nonaka static int	iwm_send_phy_cfg_cmd(struct iwm_softc *);
    299   1.4    nonaka static int	iwm_mvm_load_ucode_wait_alive(struct iwm_softc *,
    300   1.4    nonaka 		    enum iwm_ucode_type);
    301   1.4    nonaka static int	iwm_run_init_mvm_ucode(struct iwm_softc *, int);
    302   1.4    nonaka static int	iwm_rx_addbuf(struct iwm_softc *, int, int);
    303   1.4    nonaka static int	iwm_mvm_calc_rssi(struct iwm_softc *, struct iwm_rx_phy_info *);
    304   1.4    nonaka static int	iwm_mvm_get_signal_strength(struct iwm_softc *,
    305   1.4    nonaka 		    struct iwm_rx_phy_info *);
    306   1.4    nonaka static void	iwm_mvm_rx_rx_phy_cmd(struct iwm_softc *,
    307   1.4    nonaka 		    struct iwm_rx_packet *, struct iwm_rx_data *);
    308   1.4    nonaka static int	iwm_get_noise(const struct iwm_mvm_statistics_rx_non_phy *);
    309   1.4    nonaka static void	iwm_mvm_rx_rx_mpdu(struct iwm_softc *, struct iwm_rx_packet *,
    310   1.4    nonaka 		    struct iwm_rx_data *);
    311   1.4    nonaka static void	iwm_mvm_rx_tx_cmd_single(struct iwm_softc *,
    312   1.4    nonaka 		    struct iwm_rx_packet *, struct iwm_node *);
    313   1.4    nonaka static void	iwm_mvm_rx_tx_cmd(struct iwm_softc *, struct iwm_rx_packet *,
    314   1.4    nonaka 		    struct iwm_rx_data *);
    315   1.4    nonaka static int	iwm_mvm_binding_cmd(struct iwm_softc *, struct iwm_node *,
    316   1.4    nonaka 		    uint32_t);
    317   1.4    nonaka static int	iwm_mvm_binding_update(struct iwm_softc *, struct iwm_node *,
    318   1.4    nonaka 		    int);
    319   1.4    nonaka static int	iwm_mvm_binding_add_vif(struct iwm_softc *, struct iwm_node *);
    320   1.4    nonaka static void	iwm_mvm_phy_ctxt_cmd_hdr(struct iwm_softc *,
    321   1.4    nonaka 		    struct iwm_mvm_phy_ctxt *, struct iwm_phy_context_cmd *,
    322   1.4    nonaka 		    uint32_t, uint32_t);
    323   1.4    nonaka static void	iwm_mvm_phy_ctxt_cmd_data(struct iwm_softc *,
    324   1.4    nonaka 		    struct iwm_phy_context_cmd *, struct ieee80211_channel *,
    325   1.4    nonaka 		    uint8_t, uint8_t);
    326   1.4    nonaka static int	iwm_mvm_phy_ctxt_apply(struct iwm_softc *,
    327   1.4    nonaka 		    struct iwm_mvm_phy_ctxt *, uint8_t, uint8_t, uint32_t,
    328   1.4    nonaka 		    uint32_t);
    329   1.4    nonaka static int	iwm_mvm_phy_ctxt_add(struct iwm_softc *,
    330   1.4    nonaka 		    struct iwm_mvm_phy_ctxt *, struct ieee80211_channel *,
    331   1.4    nonaka 		    uint8_t, uint8_t);
    332   1.4    nonaka static int	iwm_mvm_phy_ctxt_changed(struct iwm_softc *,
    333   1.4    nonaka 		    struct iwm_mvm_phy_ctxt *, struct ieee80211_channel *,
    334   1.4    nonaka 		    uint8_t, uint8_t);
    335   1.4    nonaka static int	iwm_send_cmd(struct iwm_softc *, struct iwm_host_cmd *);
    336   1.4    nonaka static int	iwm_mvm_send_cmd_pdu(struct iwm_softc *, uint8_t, uint32_t,
    337   1.4    nonaka 		    uint16_t, const void *);
    338   1.4    nonaka static int	iwm_mvm_send_cmd_status(struct iwm_softc *,
    339   1.4    nonaka 		    struct iwm_host_cmd *, uint32_t *);
    340   1.4    nonaka static int	iwm_mvm_send_cmd_pdu_status(struct iwm_softc *, uint8_t,
    341   1.4    nonaka 		    uint16_t, const void *, uint32_t *);
    342   1.4    nonaka static void	iwm_free_resp(struct iwm_softc *, struct iwm_host_cmd *);
    343   1.4    nonaka static void	iwm_cmd_done(struct iwm_softc *, struct iwm_rx_packet *);
    344   1.4    nonaka #if 0
    345   1.4    nonaka static void	iwm_update_sched(struct iwm_softc *, int, int, uint8_t,
    346   1.4    nonaka 		    uint16_t);
    347   1.4    nonaka #endif
    348   1.4    nonaka static const struct iwm_rate *iwm_tx_fill_cmd(struct iwm_softc *,
    349   1.4    nonaka 		    struct iwm_node *, struct ieee80211_frame *,
    350   1.4    nonaka 		    struct iwm_tx_cmd *);
    351   1.4    nonaka static int	iwm_tx(struct iwm_softc *, struct mbuf *,
    352   1.4    nonaka 		    struct ieee80211_node *, int);
    353   1.4    nonaka static int	iwm_mvm_beacon_filter_send_cmd(struct iwm_softc *,
    354   1.4    nonaka 		    struct iwm_beacon_filter_cmd *);
    355   1.4    nonaka static void	iwm_mvm_beacon_filter_set_cqm_params(struct iwm_softc *,
    356   1.4    nonaka 		    struct iwm_node *, struct iwm_beacon_filter_cmd *);
    357   1.4    nonaka static int	iwm_mvm_update_beacon_abort(struct iwm_softc *,
    358   1.4    nonaka 		    struct iwm_node *, int);
    359   1.4    nonaka static void	iwm_mvm_power_log(struct iwm_softc *,
    360   1.4    nonaka 		    struct iwm_mac_power_cmd *);
    361   1.4    nonaka static void	iwm_mvm_power_build_cmd(struct iwm_softc *, struct iwm_node *,
    362   1.4    nonaka 		    struct iwm_mac_power_cmd *);
    363   1.4    nonaka static int	iwm_mvm_power_mac_update_mode(struct iwm_softc *,
    364   1.4    nonaka 		    struct iwm_node *);
    365   1.4    nonaka static int	iwm_mvm_power_update_device(struct iwm_softc *);
    366   1.4    nonaka static int	iwm_mvm_enable_beacon_filter(struct iwm_softc *,
    367   1.4    nonaka 		    struct iwm_node *);
    368   1.4    nonaka static int	iwm_mvm_disable_beacon_filter(struct iwm_softc *,
    369   1.4    nonaka 		    struct iwm_node *);
    370   1.4    nonaka static void	iwm_mvm_add_sta_cmd_v6_to_v5(struct iwm_mvm_add_sta_cmd_v6 *,
    371   1.4    nonaka 		    struct iwm_mvm_add_sta_cmd_v5 *);
    372   1.4    nonaka static int	iwm_mvm_send_add_sta_cmd_status(struct iwm_softc *,
    373   1.4    nonaka 		    struct iwm_mvm_add_sta_cmd_v6 *, int *);
    374   1.4    nonaka static int	iwm_mvm_sta_send_to_fw(struct iwm_softc *, struct iwm_node *,
    375   1.4    nonaka 		    int);
    376   1.4    nonaka static int	iwm_mvm_add_sta(struct iwm_softc *, struct iwm_node *);
    377   1.4    nonaka static int	iwm_mvm_update_sta(struct iwm_softc *, struct iwm_node *);
    378   1.4    nonaka static int	iwm_mvm_add_int_sta_common(struct iwm_softc *,
    379   1.4    nonaka 		    struct iwm_int_sta *, const uint8_t *, uint16_t, uint16_t);
    380   1.4    nonaka static int	iwm_mvm_add_aux_sta(struct iwm_softc *);
    381   1.4    nonaka static uint16_t iwm_mvm_scan_rx_chain(struct iwm_softc *);
    382   1.4    nonaka static uint32_t iwm_mvm_scan_max_out_time(struct iwm_softc *, uint32_t, int);
    383   1.4    nonaka static uint32_t iwm_mvm_scan_suspend_time(struct iwm_softc *, int);
    384   1.4    nonaka static uint32_t iwm_mvm_scan_rxon_flags(struct iwm_softc *, int);
    385   1.4    nonaka static uint32_t iwm_mvm_scan_rate_n_flags(struct iwm_softc *, int, int);
    386   1.4    nonaka static uint16_t iwm_mvm_get_active_dwell(struct iwm_softc *, int, int);
    387   1.4    nonaka static uint16_t iwm_mvm_get_passive_dwell(struct iwm_softc *, int);
    388   1.4    nonaka static int	iwm_mvm_scan_fill_channels(struct iwm_softc *,
    389   1.4    nonaka 		    struct iwm_scan_cmd *, int, int, int);
    390   1.4    nonaka static uint16_t iwm_mvm_fill_probe_req(struct iwm_softc *,
    391   1.4    nonaka 		    struct ieee80211_frame *, const uint8_t *, int,
    392   1.4    nonaka 		    const uint8_t *, int, const uint8_t *, int, int);
    393   1.4    nonaka static int	iwm_mvm_scan_request(struct iwm_softc *, int, int, uint8_t *,
    394   1.4    nonaka 		    int);
    395   1.4    nonaka static void	iwm_mvm_ack_rates(struct iwm_softc *, struct iwm_node *, int *,
    396   1.4    nonaka 		    int *);
    397   1.4    nonaka static void	iwm_mvm_mac_ctxt_cmd_common(struct iwm_softc *,
    398   1.4    nonaka 		    struct iwm_node *, struct iwm_mac_ctx_cmd *, uint32_t);
    399   1.4    nonaka static int	iwm_mvm_mac_ctxt_send_cmd(struct iwm_softc *,
    400   1.4    nonaka 		    struct iwm_mac_ctx_cmd *);
    401   1.4    nonaka static void	iwm_mvm_mac_ctxt_cmd_fill_sta(struct iwm_softc *,
    402   1.4    nonaka 		    struct iwm_node *, struct iwm_mac_data_sta *, int);
    403   1.4    nonaka static int	iwm_mvm_mac_ctxt_cmd_station(struct iwm_softc *,
    404   1.4    nonaka 		    struct iwm_node *, uint32_t);
    405   1.4    nonaka static int	iwm_mvm_mac_ctx_send(struct iwm_softc *, struct iwm_node *,
    406   1.4    nonaka 		    uint32_t);
    407   1.4    nonaka static int	iwm_mvm_mac_ctxt_add(struct iwm_softc *, struct iwm_node *);
    408   1.4    nonaka static int	iwm_mvm_mac_ctxt_changed(struct iwm_softc *, struct iwm_node *);
    409   1.4    nonaka static int	iwm_mvm_update_quotas(struct iwm_softc *, struct iwm_node *);
    410   1.4    nonaka static int	iwm_auth(struct iwm_softc *);
    411   1.4    nonaka static int	iwm_assoc(struct iwm_softc *);
    412   1.4    nonaka static int	iwm_release(struct iwm_softc *, struct iwm_node *);
    413   1.4    nonaka static void	iwm_calib_timeout(void *);
    414   1.4    nonaka static void	iwm_setrates(struct iwm_node *);
    415   1.4    nonaka static int	iwm_media_change(struct ifnet *);
    416   1.5    nonaka static void	iwm_newstate_cb(struct work *, void *);
    417   1.4    nonaka static int	iwm_newstate(struct ieee80211com *, enum ieee80211_state, int);
    418   1.5    nonaka static void	iwm_endscan_cb(struct work *, void *);
    419   1.4    nonaka static int	iwm_init_hw(struct iwm_softc *);
    420   1.4    nonaka static int	iwm_init(struct ifnet *);
    421   1.4    nonaka static void	iwm_start(struct ifnet *);
    422   1.4    nonaka static void	iwm_stop(struct ifnet *, int);
    423   1.4    nonaka static void	iwm_watchdog(struct ifnet *);
    424   1.4    nonaka static int	iwm_ioctl(struct ifnet *, u_long, void *);
    425   1.4    nonaka #ifdef IWM_DEBUG
    426   1.4    nonaka static const char *iwm_desc_lookup(uint32_t);
    427   1.4    nonaka static void	iwm_nic_error(struct iwm_softc *);
    428   1.4    nonaka #endif
    429   1.4    nonaka static void	iwm_notif_intr(struct iwm_softc *);
    430   1.4    nonaka static int	iwm_intr(void *);
    431   1.4    nonaka static int	iwm_preinit(struct iwm_softc *);
    432   1.4    nonaka static void	iwm_attach_hook(device_t);
    433   1.4    nonaka static void	iwm_attach(device_t, device_t, void *);
    434   1.4    nonaka #if 0
    435   1.4    nonaka static void	iwm_init_task(void *);
    436   1.4    nonaka static int	iwm_activate(device_t, enum devact);
    437   1.4    nonaka static void	iwm_wakeup(struct iwm_softc *);
    438   1.4    nonaka #endif
    439   1.4    nonaka static void	iwm_radiotap_attach(struct iwm_softc *);
    440   1.1     pooka 
    441   1.1     pooka static int
    442   1.1     pooka iwm_firmload(struct iwm_softc *sc)
    443   1.1     pooka {
    444   1.1     pooka 	struct iwm_fw_info *fw = &sc->sc_fw;
    445   1.1     pooka 	firmware_handle_t fwh;
    446   1.1     pooka 	int error;
    447   1.1     pooka 
    448   1.1     pooka 	/* Open firmware image. */
    449   1.1     pooka 	if ((error = firmware_open("if_iwm", sc->sc_fwname, &fwh)) != 0) {
    450   1.1     pooka 		aprint_error_dev(sc->sc_dev,
    451   1.1     pooka 		    "could not get firmware handle %s\n", sc->sc_fwname);
    452   1.1     pooka 		return error;
    453   1.1     pooka 	}
    454   1.1     pooka 
    455   1.1     pooka 	fw->fw_rawsize = firmware_get_size(fwh);
    456   1.1     pooka 	/*
    457   1.1     pooka 	 * Well, this is how the Linux driver checks it ....
    458   1.1     pooka 	 */
    459   1.1     pooka 	if (fw->fw_rawsize < sizeof(uint32_t)) {
    460   1.1     pooka 		aprint_error_dev(sc->sc_dev,
    461   1.1     pooka 		    "firmware too short: %zd bytes\n", fw->fw_rawsize);
    462   1.1     pooka 		error = EINVAL;
    463   1.1     pooka 		goto out;
    464   1.1     pooka 	}
    465   1.1     pooka 
    466   1.1     pooka 	/* some sanity */
    467   1.1     pooka 	if (fw->fw_rawsize > IWM_FWMAXSIZE) {
    468   1.1     pooka 		aprint_error_dev(sc->sc_dev,
    469   1.1     pooka 		    "firmware size is ridiculous: %zd bytes\n",
    470   1.1     pooka 		fw->fw_rawsize);
    471   1.1     pooka 		error = EINVAL;
    472   1.1     pooka 		goto out;
    473   1.1     pooka 	}
    474   1.1     pooka 
    475   1.1     pooka 	/* Read the firmware. */
    476   1.1     pooka 	fw->fw_rawdata = kmem_alloc(fw->fw_rawsize, KM_SLEEP);
    477   1.1     pooka 	if (fw->fw_rawdata == NULL) {
    478   1.1     pooka 		aprint_error_dev(sc->sc_dev,
    479   1.1     pooka 		    "not enough memory to stock firmware %s\n", sc->sc_fwname);
    480   1.1     pooka 		error = ENOMEM;
    481   1.1     pooka 		goto out;
    482   1.1     pooka 	}
    483   1.1     pooka 	error = firmware_read(fwh, 0, fw->fw_rawdata, fw->fw_rawsize);
    484   1.1     pooka 	if (error) {
    485   1.1     pooka 		aprint_error_dev(sc->sc_dev,
    486   1.1     pooka 		    "could not read firmware %s\n", sc->sc_fwname);
    487   1.1     pooka 		goto out;
    488   1.1     pooka 	}
    489   1.1     pooka 
    490   1.1     pooka  out:
    491   1.1     pooka 	/* caller will release memory, if necessary */
    492   1.1     pooka 
    493   1.1     pooka 	firmware_close(fwh);
    494   1.1     pooka 	return error;
    495   1.1     pooka }
    496   1.1     pooka 
    497   1.1     pooka /*
    498   1.1     pooka  * just maintaining status quo.
    499   1.1     pooka  */
    500   1.1     pooka static void
    501   1.1     pooka iwm_fix_channel(struct ieee80211com *ic, struct mbuf *m)
    502   1.1     pooka {
    503   1.1     pooka 	struct ieee80211_frame *wh;
    504   1.1     pooka 	uint8_t subtype;
    505   1.1     pooka 	uint8_t *frm, *efrm;
    506   1.1     pooka 
    507   1.1     pooka 	wh = mtod(m, struct ieee80211_frame *);
    508   1.1     pooka 
    509   1.1     pooka 	if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_MGT)
    510   1.1     pooka 		return;
    511   1.1     pooka 
    512   1.1     pooka 	subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
    513   1.1     pooka 
    514   1.1     pooka 	if (subtype != IEEE80211_FC0_SUBTYPE_BEACON &&
    515   1.1     pooka 	    subtype != IEEE80211_FC0_SUBTYPE_PROBE_RESP)
    516   1.1     pooka 		return;
    517   1.1     pooka 
    518   1.1     pooka 	frm = (uint8_t *)(wh + 1);
    519   1.1     pooka 	efrm = mtod(m, uint8_t *) + m->m_len;
    520   1.1     pooka 
    521   1.1     pooka 	frm += 12;      /* skip tstamp, bintval and capinfo fields */
    522   1.1     pooka 	while (frm < efrm) {
    523   1.1     pooka 		if (*frm == IEEE80211_ELEMID_DSPARMS) {
    524   1.1     pooka #if IEEE80211_CHAN_MAX < 255
    525   1.1     pooka 			if (frm[2] <= IEEE80211_CHAN_MAX)
    526   1.1     pooka #endif
    527   1.1     pooka 				ic->ic_curchan = &ic->ic_channels[frm[2]];
    528   1.1     pooka 		}
    529   1.1     pooka 		frm += frm[1] + 2;
    530   1.1     pooka 	}
    531   1.1     pooka }
    532   1.1     pooka 
    533   1.1     pooka /*
    534   1.1     pooka  * Firmware parser.
    535   1.1     pooka  */
    536   1.1     pooka 
    537   1.4    nonaka static int
    538   1.1     pooka iwm_store_cscheme(struct iwm_softc *sc, uint8_t *data, size_t dlen)
    539   1.1     pooka {
    540   1.1     pooka 	struct iwm_fw_cscheme_list *l = (void *)data;
    541   1.1     pooka 
    542   1.1     pooka 	if (dlen < sizeof(*l) ||
    543   1.1     pooka 	    dlen < sizeof(l->size) + l->size * sizeof(*l->cs))
    544   1.1     pooka 		return EINVAL;
    545   1.1     pooka 
    546   1.1     pooka 	/* we don't actually store anything for now, always use s/w crypto */
    547   1.1     pooka 
    548   1.1     pooka 	return 0;
    549   1.1     pooka }
    550   1.1     pooka 
    551   1.4    nonaka static int
    552   1.1     pooka iwm_firmware_store_section(struct iwm_softc *sc,
    553   1.1     pooka 	enum iwm_ucode_type type, uint8_t *data, size_t dlen)
    554   1.1     pooka {
    555   1.1     pooka 	struct iwm_fw_sects *fws;
    556   1.1     pooka 	struct iwm_fw_onesect *fwone;
    557   1.1     pooka 
    558   1.1     pooka 	if (type >= IWM_UCODE_TYPE_MAX)
    559   1.1     pooka 		return EINVAL;
    560   1.1     pooka 	if (dlen < sizeof(uint32_t))
    561   1.1     pooka 		return EINVAL;
    562   1.1     pooka 
    563   1.1     pooka 	fws = &sc->sc_fw.fw_sects[type];
    564   1.1     pooka 	if (fws->fw_count >= IWM_UCODE_SECT_MAX)
    565   1.1     pooka 		return EINVAL;
    566   1.1     pooka 
    567   1.1     pooka 	fwone = &fws->fw_sect[fws->fw_count];
    568   1.1     pooka 
    569   1.1     pooka 	/* first 32bit are device load offset */
    570   1.1     pooka 	memcpy(&fwone->fws_devoff, data, sizeof(uint32_t));
    571   1.1     pooka 
    572   1.1     pooka 	/* rest is data */
    573   1.1     pooka 	fwone->fws_data = data + sizeof(uint32_t);
    574   1.1     pooka 	fwone->fws_len = dlen - sizeof(uint32_t);
    575   1.1     pooka 
    576   1.1     pooka 	/* for freeing the buffer during driver unload */
    577   1.1     pooka 	fwone->fws_alloc = data;
    578   1.1     pooka 	fwone->fws_allocsize = dlen;
    579   1.1     pooka 
    580   1.1     pooka 	fws->fw_count++;
    581   1.1     pooka 	fws->fw_totlen += fwone->fws_len;
    582   1.1     pooka 
    583   1.1     pooka 	return 0;
    584   1.1     pooka }
    585   1.1     pooka 
    586   1.1     pooka /* iwlwifi: iwl-drv.c */
    587   1.1     pooka struct iwm_tlv_calib_data {
    588   1.1     pooka 	uint32_t ucode_type;
    589   1.1     pooka 	struct iwm_tlv_calib_ctrl calib;
    590   1.1     pooka } __packed;
    591   1.1     pooka 
    592   1.4    nonaka static int
    593   1.1     pooka iwm_set_default_calib(struct iwm_softc *sc, const void *data)
    594   1.1     pooka {
    595   1.1     pooka 	const struct iwm_tlv_calib_data *def_calib = data;
    596   1.1     pooka 	uint32_t ucode_type = le32toh(def_calib->ucode_type);
    597   1.1     pooka 
    598   1.1     pooka 	if (ucode_type >= IWM_UCODE_TYPE_MAX) {
    599   1.2    nonaka 		DPRINTF(("%s: Wrong ucode_type %u for default "
    600   1.2    nonaka 		    "calibration.\n", DEVNAME(sc), ucode_type));
    601   1.1     pooka 		return EINVAL;
    602   1.1     pooka 	}
    603   1.1     pooka 
    604   1.1     pooka 	sc->sc_default_calib[ucode_type].flow_trigger =
    605   1.1     pooka 	    def_calib->calib.flow_trigger;
    606   1.1     pooka 	sc->sc_default_calib[ucode_type].event_trigger =
    607   1.1     pooka 	    def_calib->calib.event_trigger;
    608   1.1     pooka 
    609   1.1     pooka 	return 0;
    610   1.1     pooka }
    611   1.1     pooka 
    612   1.4    nonaka static int
    613   1.1     pooka iwm_read_firmware(struct iwm_softc *sc)
    614   1.1     pooka {
    615   1.1     pooka 	struct iwm_fw_info *fw = &sc->sc_fw;
    616   1.8    nonaka 	struct iwm_tlv_ucode_header *uhdr;
    617   1.8    nonaka 	struct iwm_ucode_tlv tlv;
    618   1.1     pooka 	enum iwm_ucode_tlv_type tlv_type;
    619   1.1     pooka 	uint8_t *data;
    620   1.2    nonaka 	int error, status;
    621   1.2    nonaka 	size_t len;
    622   1.1     pooka 
    623   1.1     pooka 	if (fw->fw_status == IWM_FW_STATUS_NONE) {
    624   1.1     pooka 		fw->fw_status = IWM_FW_STATUS_INPROGRESS;
    625   1.1     pooka 	} else {
    626   1.1     pooka 		while (fw->fw_status == IWM_FW_STATUS_INPROGRESS)
    627   1.1     pooka 			tsleep(&sc->sc_fw, 0, "iwmfwp", 0);
    628   1.1     pooka 	}
    629   1.1     pooka 	status = fw->fw_status;
    630   1.1     pooka 
    631   1.1     pooka 	if (status == IWM_FW_STATUS_DONE)
    632   1.1     pooka 		return 0;
    633   1.1     pooka 
    634   1.1     pooka 	/*
    635   1.1     pooka 	 * Load firmware into driver memory.
    636   1.1     pooka 	 * fw_rawdata and fw_rawsize will be set.
    637   1.1     pooka 	 */
    638   1.1     pooka 	error = iwm_firmload(sc);
    639   1.1     pooka 	if (error != 0) {
    640   1.3    nonaka 		aprint_error_dev(sc->sc_dev,
    641   1.3    nonaka 		    "could not read firmware %s (error %d)\n",
    642   1.3    nonaka 		    sc->sc_fwname, error);
    643   1.1     pooka 		goto out;
    644   1.1     pooka 	}
    645   1.1     pooka 
    646   1.1     pooka 	/*
    647   1.1     pooka 	 * Parse firmware contents
    648   1.1     pooka 	 */
    649   1.1     pooka 
    650   1.1     pooka 	uhdr = (void *)fw->fw_rawdata;
    651   1.1     pooka 	if (*(uint32_t *)fw->fw_rawdata != 0
    652   1.1     pooka 	    || le32toh(uhdr->magic) != IWM_TLV_UCODE_MAGIC) {
    653   1.3    nonaka 		aprint_error_dev(sc->sc_dev, "invalid firmware %s\n",
    654   1.3    nonaka 		    sc->sc_fwname);
    655   1.1     pooka 		error = EINVAL;
    656   1.1     pooka 		goto out;
    657   1.1     pooka 	}
    658   1.1     pooka 
    659   1.1     pooka 	sc->sc_fwver = le32toh(uhdr->ver);
    660   1.1     pooka 	data = uhdr->data;
    661   1.1     pooka 	len = fw->fw_rawsize - sizeof(*uhdr);
    662   1.1     pooka 
    663   1.1     pooka 	while (len >= sizeof(tlv)) {
    664   1.2    nonaka 		size_t tlv_len;
    665   1.1     pooka 		void *tlv_data;
    666   1.1     pooka 
    667   1.1     pooka 		memcpy(&tlv, data, sizeof(tlv));
    668   1.1     pooka 		tlv_len = le32toh(tlv.length);
    669   1.1     pooka 		tlv_type = le32toh(tlv.type);
    670   1.1     pooka 
    671   1.1     pooka 		len -= sizeof(tlv);
    672   1.1     pooka 		data += sizeof(tlv);
    673   1.1     pooka 		tlv_data = data;
    674   1.1     pooka 
    675   1.1     pooka 		if (len < tlv_len) {
    676   1.3    nonaka 			aprint_error_dev(sc->sc_dev,
    677   1.3    nonaka 			    "firmware too short: %zu bytes\n", len);
    678   1.1     pooka 			error = EINVAL;
    679   1.1     pooka 			goto parse_out;
    680   1.1     pooka 		}
    681   1.1     pooka 
    682   1.1     pooka 		switch ((int)tlv_type) {
    683   1.1     pooka 		case IWM_UCODE_TLV_PROBE_MAX_LEN:
    684   1.1     pooka 			if (tlv_len < sizeof(uint32_t)) {
    685   1.1     pooka 				error = EINVAL;
    686   1.1     pooka 				goto parse_out;
    687   1.1     pooka 			}
    688   1.1     pooka 			sc->sc_capa_max_probe_len
    689   1.1     pooka 			    = le32toh(*(uint32_t *)tlv_data);
    690   1.1     pooka 			/* limit it to something sensible */
    691   1.1     pooka 			if (sc->sc_capa_max_probe_len > (1<<16)) {
    692   1.2    nonaka 				DPRINTF(("%s: IWM_UCODE_TLV_PROBE_MAX_LEN "
    693   1.2    nonaka 				    "ridiculous\n", DEVNAME(sc)));
    694   1.1     pooka 				error = EINVAL;
    695   1.1     pooka 				goto parse_out;
    696   1.1     pooka 			}
    697   1.1     pooka 			break;
    698   1.1     pooka 		case IWM_UCODE_TLV_PAN:
    699   1.1     pooka 			if (tlv_len) {
    700   1.1     pooka 				error = EINVAL;
    701   1.1     pooka 				goto parse_out;
    702   1.1     pooka 			}
    703   1.1     pooka 			sc->sc_capaflags |= IWM_UCODE_TLV_FLAGS_PAN;
    704   1.1     pooka 			break;
    705   1.1     pooka 		case IWM_UCODE_TLV_FLAGS:
    706   1.1     pooka 			if (tlv_len < sizeof(uint32_t)) {
    707   1.1     pooka 				error = EINVAL;
    708   1.1     pooka 				goto parse_out;
    709   1.1     pooka 			}
    710   1.1     pooka 			/*
    711   1.1     pooka 			 * Apparently there can be many flags, but Linux driver
    712   1.1     pooka 			 * parses only the first one, and so do we.
    713   1.1     pooka 			 *
    714   1.1     pooka 			 * XXX: why does this override IWM_UCODE_TLV_PAN?
    715   1.1     pooka 			 * Intentional or a bug?  Observations from
    716   1.1     pooka 			 * current firmware file:
    717   1.1     pooka 			 *  1) TLV_PAN is parsed first
    718   1.1     pooka 			 *  2) TLV_FLAGS contains TLV_FLAGS_PAN
    719   1.1     pooka 			 * ==> this resets TLV_PAN to itself... hnnnk
    720   1.1     pooka 			 */
    721   1.1     pooka 			sc->sc_capaflags = le32toh(*(uint32_t *)tlv_data);
    722   1.1     pooka 			break;
    723   1.1     pooka 		case IWM_UCODE_TLV_CSCHEME:
    724   1.1     pooka 			if ((error = iwm_store_cscheme(sc,
    725   1.1     pooka 			    tlv_data, tlv_len)) != 0)
    726   1.1     pooka 				goto parse_out;
    727   1.1     pooka 			break;
    728   1.1     pooka 		case IWM_UCODE_TLV_NUM_OF_CPU:
    729   1.1     pooka 			if (tlv_len != sizeof(uint32_t)) {
    730   1.1     pooka 				error = EINVAL;
    731   1.1     pooka 				goto parse_out;
    732   1.1     pooka 			}
    733   1.1     pooka 			if (le32toh(*(uint32_t*)tlv_data) != 1) {
    734   1.2    nonaka 				DPRINTF(("%s: driver supports "
    735   1.2    nonaka 				    "only TLV_NUM_OF_CPU == 1", DEVNAME(sc)));
    736   1.1     pooka 				error = EINVAL;
    737   1.1     pooka 				goto parse_out;
    738   1.1     pooka 			}
    739   1.1     pooka 			break;
    740   1.1     pooka 		case IWM_UCODE_TLV_SEC_RT:
    741   1.1     pooka 			if ((error = iwm_firmware_store_section(sc,
    742   1.1     pooka 			    IWM_UCODE_TYPE_REGULAR, tlv_data, tlv_len)) != 0)
    743   1.1     pooka 				goto parse_out;
    744   1.1     pooka 			break;
    745   1.1     pooka 		case IWM_UCODE_TLV_SEC_INIT:
    746   1.1     pooka 			if ((error = iwm_firmware_store_section(sc,
    747   1.1     pooka 			    IWM_UCODE_TYPE_INIT, tlv_data, tlv_len)) != 0)
    748   1.1     pooka 				goto parse_out;
    749   1.1     pooka 			break;
    750   1.1     pooka 		case IWM_UCODE_TLV_SEC_WOWLAN:
    751   1.1     pooka 			if ((error = iwm_firmware_store_section(sc,
    752   1.1     pooka 			    IWM_UCODE_TYPE_WOW, tlv_data, tlv_len)) != 0)
    753   1.1     pooka 				goto parse_out;
    754   1.1     pooka 			break;
    755   1.1     pooka 		case IWM_UCODE_TLV_DEF_CALIB:
    756   1.1     pooka 			if (tlv_len != sizeof(struct iwm_tlv_calib_data)) {
    757   1.1     pooka 				error = EINVAL;
    758   1.1     pooka 				goto parse_out;
    759   1.1     pooka 			}
    760   1.1     pooka 			if ((error = iwm_set_default_calib(sc, tlv_data)) != 0)
    761   1.1     pooka 				goto parse_out;
    762   1.1     pooka 			break;
    763   1.1     pooka 		case IWM_UCODE_TLV_PHY_SKU:
    764   1.1     pooka 			if (tlv_len != sizeof(uint32_t)) {
    765   1.1     pooka 				error = EINVAL;
    766   1.1     pooka 				goto parse_out;
    767   1.1     pooka 			}
    768   1.1     pooka 			sc->sc_fw_phy_config = le32toh(*(uint32_t *)tlv_data);
    769   1.1     pooka 			break;
    770   1.1     pooka 
    771   1.1     pooka 		case IWM_UCODE_TLV_API_CHANGES_SET:
    772   1.1     pooka 		case IWM_UCODE_TLV_ENABLED_CAPABILITIES:
    773   1.1     pooka 			/* ignore, not used by current driver */
    774   1.1     pooka 			break;
    775   1.1     pooka 
    776   1.1     pooka 		default:
    777   1.2    nonaka 			DPRINTF(("%s: unknown firmware section %d, abort\n",
    778   1.2    nonaka 			    DEVNAME(sc), tlv_type));
    779   1.1     pooka 			error = EINVAL;
    780   1.1     pooka 			goto parse_out;
    781   1.1     pooka 		}
    782   1.1     pooka 
    783   1.1     pooka 		len -= roundup(tlv_len, 4);
    784   1.1     pooka 		data += roundup(tlv_len, 4);
    785   1.1     pooka 	}
    786   1.1     pooka 
    787   1.1     pooka 	KASSERT(error == 0);
    788   1.1     pooka 
    789   1.1     pooka  parse_out:
    790   1.1     pooka 	if (error) {
    791   1.3    nonaka 		aprint_error_dev(sc->sc_dev,
    792   1.3    nonaka 		    "firmware parse error, section type %d\n", tlv_type);
    793   1.1     pooka 	}
    794   1.1     pooka 
    795   1.1     pooka 	if (!(sc->sc_capaflags & IWM_UCODE_TLV_FLAGS_PM_CMD_SUPPORT)) {
    796   1.3    nonaka 		aprint_error_dev(sc->sc_dev,
    797   1.3    nonaka 		    "device uses unsupported power ops\n");
    798   1.1     pooka 		error = ENOTSUP;
    799   1.1     pooka 	}
    800   1.1     pooka 
    801   1.1     pooka  out:
    802   1.2    nonaka 	if (error)
    803   1.2    nonaka 		fw->fw_status = IWM_FW_STATUS_NONE;
    804   1.2    nonaka 	else
    805   1.1     pooka 		fw->fw_status = IWM_FW_STATUS_DONE;
    806   1.1     pooka 	wakeup(&sc->sc_fw);
    807   1.1     pooka 
    808  1.27   khorben 	if (error && fw->fw_rawdata != NULL) {
    809   1.1     pooka 		kmem_free(fw->fw_rawdata, fw->fw_rawsize);
    810   1.1     pooka 		fw->fw_rawdata = NULL;
    811   1.1     pooka 	}
    812   1.1     pooka 	return error;
    813   1.1     pooka }
    814   1.1     pooka 
    815   1.1     pooka /*
    816   1.1     pooka  * basic device access
    817   1.1     pooka  */
    818   1.1     pooka 
    819   1.4    nonaka static uint32_t
    820   1.1     pooka iwm_read_prph(struct iwm_softc *sc, uint32_t addr)
    821   1.1     pooka {
    822   1.1     pooka 	IWM_WRITE(sc,
    823   1.1     pooka 	    IWM_HBUS_TARG_PRPH_RADDR, ((addr & 0x000fffff) | (3 << 24)));
    824   1.1     pooka 	IWM_BARRIER_READ_WRITE(sc);
    825   1.1     pooka 	return IWM_READ(sc, IWM_HBUS_TARG_PRPH_RDAT);
    826   1.1     pooka }
    827   1.1     pooka 
    828   1.4    nonaka static void
    829   1.1     pooka iwm_write_prph(struct iwm_softc *sc, uint32_t addr, uint32_t val)
    830   1.1     pooka {
    831   1.1     pooka 	IWM_WRITE(sc,
    832   1.1     pooka 	    IWM_HBUS_TARG_PRPH_WADDR, ((addr & 0x000fffff) | (3 << 24)));
    833   1.1     pooka 	IWM_BARRIER_WRITE(sc);
    834   1.1     pooka 	IWM_WRITE(sc, IWM_HBUS_TARG_PRPH_WDAT, val);
    835   1.1     pooka }
    836   1.1     pooka 
    837   1.4    nonaka #ifdef IWM_DEBUG
    838   1.1     pooka /* iwlwifi: pcie/trans.c */
    839   1.4    nonaka static int
    840   1.1     pooka iwm_read_mem(struct iwm_softc *sc, uint32_t addr, void *buf, int dwords)
    841   1.1     pooka {
    842   1.1     pooka 	int offs, ret = 0;
    843   1.1     pooka 	uint32_t *vals = buf;
    844   1.1     pooka 
    845   1.1     pooka 	if (iwm_nic_lock(sc)) {
    846   1.1     pooka 		IWM_WRITE(sc, IWM_HBUS_TARG_MEM_RADDR, addr);
    847   1.1     pooka 		for (offs = 0; offs < dwords; offs++)
    848   1.1     pooka 			vals[offs] = IWM_READ(sc, IWM_HBUS_TARG_MEM_RDAT);
    849   1.1     pooka 		iwm_nic_unlock(sc);
    850   1.1     pooka 	} else {
    851   1.1     pooka 		ret = EBUSY;
    852   1.1     pooka 	}
    853   1.1     pooka 	return ret;
    854   1.1     pooka }
    855   1.4    nonaka #endif
    856   1.1     pooka 
    857   1.1     pooka /* iwlwifi: pcie/trans.c */
    858   1.4    nonaka static int
    859   1.1     pooka iwm_write_mem(struct iwm_softc *sc, uint32_t addr, const void *buf, int dwords)
    860   1.1     pooka {
    861   1.5    nonaka 	int offs;
    862   1.1     pooka 	const uint32_t *vals = buf;
    863   1.1     pooka 
    864   1.1     pooka 	if (iwm_nic_lock(sc)) {
    865   1.1     pooka 		IWM_WRITE(sc, IWM_HBUS_TARG_MEM_WADDR, addr);
    866   1.1     pooka 		/* WADDR auto-increments */
    867   1.1     pooka 		for (offs = 0; offs < dwords; offs++) {
    868   1.1     pooka 			uint32_t val = vals ? vals[offs] : 0;
    869   1.1     pooka 			IWM_WRITE(sc, IWM_HBUS_TARG_MEM_WDAT, val);
    870   1.1     pooka 		}
    871   1.1     pooka 		iwm_nic_unlock(sc);
    872   1.1     pooka 	} else {
    873   1.2    nonaka 		DPRINTF(("%s: write_mem failed\n", DEVNAME(sc)));
    874   1.2    nonaka 		return EBUSY;
    875   1.1     pooka 	}
    876   1.2    nonaka 	return 0;
    877   1.1     pooka }
    878   1.1     pooka 
    879   1.4    nonaka static int
    880   1.1     pooka iwm_write_mem32(struct iwm_softc *sc, uint32_t addr, uint32_t val)
    881   1.1     pooka {
    882   1.1     pooka 	return iwm_write_mem(sc, addr, &val, 1);
    883   1.1     pooka }
    884   1.1     pooka 
    885   1.4    nonaka static int
    886   1.1     pooka iwm_poll_bit(struct iwm_softc *sc, int reg,
    887   1.1     pooka 	uint32_t bits, uint32_t mask, int timo)
    888   1.1     pooka {
    889   1.1     pooka 	for (;;) {
    890   1.1     pooka 		if ((IWM_READ(sc, reg) & mask) == (bits & mask)) {
    891   1.1     pooka 			return 1;
    892   1.1     pooka 		}
    893   1.1     pooka 		if (timo < 10) {
    894   1.1     pooka 			return 0;
    895   1.1     pooka 		}
    896   1.1     pooka 		timo -= 10;
    897   1.1     pooka 		DELAY(10);
    898   1.1     pooka 	}
    899   1.1     pooka }
    900   1.1     pooka 
    901   1.4    nonaka static int
    902   1.1     pooka iwm_nic_lock(struct iwm_softc *sc)
    903   1.1     pooka {
    904   1.1     pooka 	int rv = 0;
    905   1.1     pooka 
    906   1.1     pooka 	IWM_SETBITS(sc, IWM_CSR_GP_CNTRL,
    907   1.1     pooka 	    IWM_CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
    908   1.1     pooka 
    909   1.1     pooka 	if (iwm_poll_bit(sc, IWM_CSR_GP_CNTRL,
    910   1.1     pooka 	    IWM_CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
    911   1.1     pooka 	    IWM_CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY
    912   1.1     pooka 	     | IWM_CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP, 15000)) {
    913   1.1     pooka 	    	rv = 1;
    914   1.1     pooka 	} else {
    915   1.1     pooka 		/* jolt */
    916   1.1     pooka 		IWM_WRITE(sc, IWM_CSR_RESET, IWM_CSR_RESET_REG_FLAG_FORCE_NMI);
    917   1.1     pooka 	}
    918   1.1     pooka 
    919   1.1     pooka 	return rv;
    920   1.1     pooka }
    921   1.1     pooka 
    922   1.4    nonaka static void
    923   1.1     pooka iwm_nic_unlock(struct iwm_softc *sc)
    924   1.1     pooka {
    925   1.1     pooka 	IWM_CLRBITS(sc, IWM_CSR_GP_CNTRL,
    926   1.1     pooka 	    IWM_CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
    927   1.1     pooka }
    928   1.1     pooka 
    929   1.4    nonaka static void
    930   1.1     pooka iwm_set_bits_mask_prph(struct iwm_softc *sc,
    931   1.1     pooka 	uint32_t reg, uint32_t bits, uint32_t mask)
    932   1.1     pooka {
    933   1.1     pooka 	uint32_t val;
    934   1.1     pooka 
    935   1.1     pooka 	/* XXX: no error path? */
    936   1.1     pooka 	if (iwm_nic_lock(sc)) {
    937   1.1     pooka 		val = iwm_read_prph(sc, reg) & mask;
    938   1.1     pooka 		val |= bits;
    939   1.1     pooka 		iwm_write_prph(sc, reg, val);
    940   1.1     pooka 		iwm_nic_unlock(sc);
    941   1.1     pooka 	}
    942   1.1     pooka }
    943   1.1     pooka 
    944   1.4    nonaka static void
    945   1.1     pooka iwm_set_bits_prph(struct iwm_softc *sc, uint32_t reg, uint32_t bits)
    946   1.1     pooka {
    947   1.1     pooka 	iwm_set_bits_mask_prph(sc, reg, bits, ~0);
    948   1.1     pooka }
    949   1.1     pooka 
    950   1.4    nonaka static void
    951   1.1     pooka iwm_clear_bits_prph(struct iwm_softc *sc, uint32_t reg, uint32_t bits)
    952   1.1     pooka {
    953   1.1     pooka 	iwm_set_bits_mask_prph(sc, reg, 0, ~bits);
    954   1.1     pooka }
    955   1.1     pooka 
    956   1.1     pooka /*
    957   1.1     pooka  * DMA resource routines
    958   1.1     pooka  */
    959   1.1     pooka 
    960   1.4    nonaka static int
    961   1.1     pooka iwm_dma_contig_alloc(bus_dma_tag_t tag, struct iwm_dma_info *dma,
    962   1.1     pooka     bus_size_t size, bus_size_t alignment)
    963   1.1     pooka {
    964   1.1     pooka 	int nsegs, error;
    965   1.1     pooka 	void *va;
    966   1.1     pooka 
    967   1.1     pooka 	dma->tag = tag;
    968   1.1     pooka 	dma->size = size;
    969   1.1     pooka 
    970   1.1     pooka 	error = bus_dmamap_create(tag, size, 1, size, 0, BUS_DMA_NOWAIT,
    971   1.1     pooka 	    &dma->map);
    972   1.1     pooka 	if (error != 0)
    973   1.1     pooka 		goto fail;
    974   1.1     pooka 
    975   1.1     pooka 	error = bus_dmamem_alloc(tag, size, alignment, 0, &dma->seg, 1, &nsegs,
    976   1.1     pooka 	    BUS_DMA_NOWAIT);
    977   1.1     pooka 	if (error != 0)
    978   1.1     pooka 		goto fail;
    979   1.1     pooka 
    980   1.1     pooka 	error = bus_dmamem_map(tag, &dma->seg, 1, size, &va,
    981   1.1     pooka 	    BUS_DMA_NOWAIT);
    982   1.1     pooka 	if (error != 0)
    983   1.1     pooka 		goto fail;
    984   1.1     pooka 	dma->vaddr = va;
    985   1.1     pooka 
    986   1.1     pooka 	error = bus_dmamap_load(tag, dma->map, dma->vaddr, size, NULL,
    987   1.1     pooka 	    BUS_DMA_NOWAIT);
    988   1.1     pooka 	if (error != 0)
    989   1.1     pooka 		goto fail;
    990   1.1     pooka 
    991   1.1     pooka 	memset(dma->vaddr, 0, size);
    992   1.1     pooka 	bus_dmamap_sync(tag, dma->map, 0, size, BUS_DMASYNC_PREWRITE);
    993   1.1     pooka 	dma->paddr = dma->map->dm_segs[0].ds_addr;
    994   1.1     pooka 
    995   1.1     pooka 	return 0;
    996   1.1     pooka 
    997   1.1     pooka fail:	iwm_dma_contig_free(dma);
    998   1.1     pooka 	return error;
    999   1.1     pooka }
   1000   1.1     pooka 
   1001   1.4    nonaka static void
   1002   1.1     pooka iwm_dma_contig_free(struct iwm_dma_info *dma)
   1003   1.1     pooka {
   1004   1.1     pooka 	if (dma->map != NULL) {
   1005   1.1     pooka 		if (dma->vaddr != NULL) {
   1006   1.1     pooka 			bus_dmamap_sync(dma->tag, dma->map, 0, dma->size,
   1007   1.1     pooka 			    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
   1008   1.1     pooka 			bus_dmamap_unload(dma->tag, dma->map);
   1009   1.1     pooka 			bus_dmamem_unmap(dma->tag, dma->vaddr, dma->size);
   1010   1.1     pooka 			bus_dmamem_free(dma->tag, &dma->seg, 1);
   1011   1.1     pooka 			dma->vaddr = NULL;
   1012   1.1     pooka 		}
   1013   1.1     pooka 		bus_dmamap_destroy(dma->tag, dma->map);
   1014   1.1     pooka 		dma->map = NULL;
   1015   1.1     pooka 	}
   1016   1.1     pooka }
   1017   1.1     pooka 
   1018   1.1     pooka /* fwmem is used to load firmware onto the card */
   1019   1.4    nonaka static int
   1020   1.1     pooka iwm_alloc_fwmem(struct iwm_softc *sc)
   1021   1.1     pooka {
   1022   1.1     pooka 	/* Must be aligned on a 16-byte boundary. */
   1023   1.1     pooka 	return iwm_dma_contig_alloc(sc->sc_dmat, &sc->fw_dma,
   1024   1.1     pooka 	    sc->sc_fwdmasegsz, 16);
   1025   1.1     pooka }
   1026   1.1     pooka 
   1027   1.4    nonaka static void
   1028   1.1     pooka iwm_free_fwmem(struct iwm_softc *sc)
   1029   1.1     pooka {
   1030   1.1     pooka 	iwm_dma_contig_free(&sc->fw_dma);
   1031   1.1     pooka }
   1032   1.1     pooka 
   1033   1.1     pooka /* tx scheduler rings.  not used? */
   1034   1.4    nonaka static int
   1035   1.1     pooka iwm_alloc_sched(struct iwm_softc *sc)
   1036   1.1     pooka {
   1037   1.1     pooka 	int rv;
   1038   1.1     pooka 
   1039   1.1     pooka 	/* TX scheduler rings must be aligned on a 1KB boundary. */
   1040   1.1     pooka 	rv = iwm_dma_contig_alloc(sc->sc_dmat, &sc->sched_dma,
   1041   1.1     pooka 	    __arraycount(sc->txq) * sizeof(struct iwm_agn_scd_bc_tbl), 1024);
   1042   1.1     pooka 	return rv;
   1043   1.1     pooka }
   1044   1.1     pooka 
   1045   1.4    nonaka static void
   1046   1.1     pooka iwm_free_sched(struct iwm_softc *sc)
   1047   1.1     pooka {
   1048   1.1     pooka 	iwm_dma_contig_free(&sc->sched_dma);
   1049   1.1     pooka }
   1050   1.1     pooka 
   1051   1.1     pooka /* keep-warm page is used internally by the card.  see iwl-fh.h for more info */
   1052   1.4    nonaka static int
   1053   1.1     pooka iwm_alloc_kw(struct iwm_softc *sc)
   1054   1.1     pooka {
   1055   1.1     pooka 	return iwm_dma_contig_alloc(sc->sc_dmat, &sc->kw_dma, 4096, 4096);
   1056   1.1     pooka }
   1057   1.1     pooka 
   1058   1.4    nonaka static void
   1059   1.1     pooka iwm_free_kw(struct iwm_softc *sc)
   1060   1.1     pooka {
   1061   1.1     pooka 	iwm_dma_contig_free(&sc->kw_dma);
   1062   1.1     pooka }
   1063   1.1     pooka 
   1064   1.1     pooka /* interrupt cause table */
   1065   1.4    nonaka static int
   1066   1.1     pooka iwm_alloc_ict(struct iwm_softc *sc)
   1067   1.1     pooka {
   1068   1.1     pooka 	return iwm_dma_contig_alloc(sc->sc_dmat, &sc->ict_dma,
   1069   1.1     pooka 	    IWM_ICT_SIZE, 1<<IWM_ICT_PADDR_SHIFT);
   1070   1.1     pooka }
   1071   1.1     pooka 
   1072   1.4    nonaka static void
   1073   1.1     pooka iwm_free_ict(struct iwm_softc *sc)
   1074   1.1     pooka {
   1075   1.1     pooka 	iwm_dma_contig_free(&sc->ict_dma);
   1076   1.1     pooka }
   1077   1.1     pooka 
   1078   1.4    nonaka static int
   1079   1.1     pooka iwm_alloc_rx_ring(struct iwm_softc *sc, struct iwm_rx_ring *ring)
   1080   1.1     pooka {
   1081   1.1     pooka 	bus_size_t size;
   1082   1.1     pooka 	int i, error;
   1083   1.1     pooka 
   1084   1.1     pooka 	ring->cur = 0;
   1085   1.1     pooka 
   1086   1.1     pooka 	/* Allocate RX descriptors (256-byte aligned). */
   1087   1.1     pooka 	size = IWM_RX_RING_COUNT * sizeof(uint32_t);
   1088   1.1     pooka 	error = iwm_dma_contig_alloc(sc->sc_dmat, &ring->desc_dma, size, 256);
   1089   1.1     pooka 	if (error != 0) {
   1090   1.3    nonaka 		aprint_error_dev(sc->sc_dev,
   1091   1.3    nonaka 		    "could not allocate RX ring DMA memory\n");
   1092   1.1     pooka 		goto fail;
   1093   1.1     pooka 	}
   1094   1.1     pooka 	ring->desc = ring->desc_dma.vaddr;
   1095   1.1     pooka 
   1096   1.1     pooka 	/* Allocate RX status area (16-byte aligned). */
   1097   1.1     pooka 	error = iwm_dma_contig_alloc(sc->sc_dmat, &ring->stat_dma,
   1098   1.1     pooka 	    sizeof(*ring->stat), 16);
   1099   1.1     pooka 	if (error != 0) {
   1100   1.3    nonaka 		aprint_error_dev(sc->sc_dev,
   1101   1.3    nonaka 		    "could not allocate RX status DMA memory\n");
   1102   1.1     pooka 		goto fail;
   1103   1.1     pooka 	}
   1104   1.1     pooka 	ring->stat = ring->stat_dma.vaddr;
   1105   1.1     pooka 
   1106   1.1     pooka 	/*
   1107   1.1     pooka 	 * Allocate and map RX buffers.
   1108   1.1     pooka 	 */
   1109   1.1     pooka 	for (i = 0; i < IWM_RX_RING_COUNT; i++) {
   1110   1.1     pooka 		struct iwm_rx_data *data = &ring->data[i];
   1111   1.1     pooka 
   1112   1.1     pooka 		memset(data, 0, sizeof(*data));
   1113   1.1     pooka 		error = bus_dmamap_create(sc->sc_dmat, IWM_RBUF_SIZE, 1,
   1114   1.1     pooka 		    IWM_RBUF_SIZE, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
   1115   1.1     pooka 		    &data->map);
   1116   1.1     pooka 		if (error != 0) {
   1117   1.3    nonaka 			aprint_error_dev(sc->sc_dev,
   1118   1.3    nonaka 			    "could not create RX buf DMA map\n");
   1119   1.1     pooka 			goto fail;
   1120   1.1     pooka 		}
   1121   1.1     pooka 
   1122   1.1     pooka 		if ((error = iwm_rx_addbuf(sc, IWM_RBUF_SIZE, i)) != 0) {
   1123   1.1     pooka 			goto fail;
   1124   1.1     pooka 		}
   1125   1.1     pooka 	}
   1126   1.1     pooka 	return 0;
   1127   1.1     pooka 
   1128   1.1     pooka fail:	iwm_free_rx_ring(sc, ring);
   1129   1.1     pooka 	return error;
   1130   1.1     pooka }
   1131   1.1     pooka 
   1132   1.4    nonaka static void
   1133   1.1     pooka iwm_reset_rx_ring(struct iwm_softc *sc, struct iwm_rx_ring *ring)
   1134   1.1     pooka {
   1135   1.1     pooka 	int ntries;
   1136   1.1     pooka 
   1137   1.1     pooka 	if (iwm_nic_lock(sc)) {
   1138   1.1     pooka 		IWM_WRITE(sc, IWM_FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
   1139   1.1     pooka 		for (ntries = 0; ntries < 1000; ntries++) {
   1140   1.1     pooka 			if (IWM_READ(sc, IWM_FH_MEM_RSSR_RX_STATUS_REG) &
   1141   1.1     pooka 			    IWM_FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE)
   1142   1.1     pooka 				break;
   1143   1.1     pooka 			DELAY(10);
   1144   1.1     pooka 		}
   1145   1.1     pooka 		iwm_nic_unlock(sc);
   1146   1.1     pooka 	}
   1147   1.1     pooka 	ring->cur = 0;
   1148   1.1     pooka }
   1149   1.1     pooka 
   1150   1.4    nonaka static void
   1151   1.1     pooka iwm_free_rx_ring(struct iwm_softc *sc, struct iwm_rx_ring *ring)
   1152   1.1     pooka {
   1153   1.1     pooka 	int i;
   1154   1.1     pooka 
   1155   1.1     pooka 	iwm_dma_contig_free(&ring->desc_dma);
   1156   1.1     pooka 	iwm_dma_contig_free(&ring->stat_dma);
   1157   1.1     pooka 
   1158   1.1     pooka 	for (i = 0; i < IWM_RX_RING_COUNT; i++) {
   1159   1.1     pooka 		struct iwm_rx_data *data = &ring->data[i];
   1160   1.1     pooka 
   1161   1.1     pooka 		if (data->m != NULL) {
   1162   1.1     pooka 			bus_dmamap_sync(sc->sc_dmat, data->map, 0,
   1163   1.1     pooka 			    data->map->dm_mapsize, BUS_DMASYNC_POSTREAD);
   1164   1.1     pooka 			bus_dmamap_unload(sc->sc_dmat, data->map);
   1165   1.1     pooka 			m_freem(data->m);
   1166   1.1     pooka 		}
   1167   1.1     pooka 		if (data->map != NULL)
   1168   1.1     pooka 			bus_dmamap_destroy(sc->sc_dmat, data->map);
   1169   1.1     pooka 	}
   1170   1.1     pooka }
   1171   1.1     pooka 
   1172   1.4    nonaka static int
   1173   1.1     pooka iwm_alloc_tx_ring(struct iwm_softc *sc, struct iwm_tx_ring *ring, int qid)
   1174   1.1     pooka {
   1175   1.1     pooka 	bus_addr_t paddr;
   1176   1.1     pooka 	bus_size_t size;
   1177   1.1     pooka 	int i, error;
   1178   1.1     pooka 
   1179   1.1     pooka 	ring->qid = qid;
   1180   1.1     pooka 	ring->queued = 0;
   1181   1.1     pooka 	ring->cur = 0;
   1182   1.1     pooka 
   1183   1.1     pooka 	/* Allocate TX descriptors (256-byte aligned). */
   1184   1.1     pooka 	size = IWM_TX_RING_COUNT * sizeof (struct iwm_tfd);
   1185   1.1     pooka 	error = iwm_dma_contig_alloc(sc->sc_dmat, &ring->desc_dma, size, 256);
   1186   1.1     pooka 	if (error != 0) {
   1187   1.3    nonaka 		aprint_error_dev(sc->sc_dev,
   1188   1.3    nonaka 		    "could not allocate TX ring DMA memory\n");
   1189   1.1     pooka 		goto fail;
   1190   1.1     pooka 	}
   1191   1.1     pooka 	ring->desc = ring->desc_dma.vaddr;
   1192   1.1     pooka 
   1193   1.1     pooka 	/*
   1194   1.1     pooka 	 * We only use rings 0 through 9 (4 EDCA + cmd) so there is no need
   1195   1.1     pooka 	 * to allocate commands space for other rings.
   1196   1.1     pooka 	 */
   1197   1.1     pooka 	if (qid > IWM_MVM_CMD_QUEUE)
   1198   1.1     pooka 		return 0;
   1199   1.1     pooka 
   1200   1.1     pooka 	size = IWM_TX_RING_COUNT * sizeof(struct iwm_device_cmd);
   1201   1.1     pooka 	error = iwm_dma_contig_alloc(sc->sc_dmat, &ring->cmd_dma, size, 4);
   1202   1.1     pooka 	if (error != 0) {
   1203   1.3    nonaka 		aprint_error_dev(sc->sc_dev,
   1204   1.3    nonaka 		    "could not allocate TX cmd DMA memory\n");
   1205   1.1     pooka 		goto fail;
   1206   1.1     pooka 	}
   1207   1.1     pooka 	ring->cmd = ring->cmd_dma.vaddr;
   1208   1.1     pooka 
   1209   1.1     pooka 	paddr = ring->cmd_dma.paddr;
   1210   1.1     pooka 	for (i = 0; i < IWM_TX_RING_COUNT; i++) {
   1211   1.1     pooka 		struct iwm_tx_data *data = &ring->data[i];
   1212   1.1     pooka 
   1213   1.1     pooka 		data->cmd_paddr = paddr;
   1214   1.1     pooka 		data->scratch_paddr = paddr + sizeof(struct iwm_cmd_header)
   1215   1.1     pooka 		    + offsetof(struct iwm_tx_cmd, scratch);
   1216   1.1     pooka 		paddr += sizeof(struct iwm_device_cmd);
   1217   1.1     pooka 
   1218   1.5    nonaka 		error = bus_dmamap_create(sc->sc_dmat, IWM_RBUF_SIZE,
   1219   1.5    nonaka 		    IWM_NUM_OF_TBS, IWM_RBUF_SIZE, 0, BUS_DMA_NOWAIT,
   1220   1.5    nonaka 		    &data->map);
   1221   1.1     pooka 		if (error != 0) {
   1222   1.3    nonaka 			aprint_error_dev(sc->sc_dev,
   1223   1.3    nonaka 			    "could not create TX buf DMA map\n");
   1224   1.1     pooka 			goto fail;
   1225   1.1     pooka 		}
   1226   1.1     pooka 	}
   1227   1.1     pooka 	KASSERT(paddr == ring->cmd_dma.paddr + size);
   1228   1.1     pooka 	return 0;
   1229   1.1     pooka 
   1230   1.1     pooka fail:	iwm_free_tx_ring(sc, ring);
   1231   1.1     pooka 	return error;
   1232   1.1     pooka }
   1233   1.1     pooka 
   1234   1.4    nonaka static void
   1235   1.1     pooka iwm_reset_tx_ring(struct iwm_softc *sc, struct iwm_tx_ring *ring)
   1236   1.1     pooka {
   1237   1.1     pooka 	int i;
   1238   1.1     pooka 
   1239   1.1     pooka 	for (i = 0; i < IWM_TX_RING_COUNT; i++) {
   1240   1.1     pooka 		struct iwm_tx_data *data = &ring->data[i];
   1241   1.1     pooka 
   1242   1.1     pooka 		if (data->m != NULL) {
   1243   1.1     pooka 			bus_dmamap_sync(sc->sc_dmat, data->map, 0,
   1244   1.1     pooka 			    data->map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
   1245   1.1     pooka 			bus_dmamap_unload(sc->sc_dmat, data->map);
   1246   1.1     pooka 			m_freem(data->m);
   1247   1.1     pooka 			data->m = NULL;
   1248   1.1     pooka 		}
   1249   1.1     pooka 	}
   1250   1.1     pooka 	/* Clear TX descriptors. */
   1251   1.1     pooka 	memset(ring->desc, 0, ring->desc_dma.size);
   1252   1.1     pooka 	bus_dmamap_sync(sc->sc_dmat, ring->desc_dma.map, 0,
   1253   1.1     pooka 	    ring->desc_dma.size, BUS_DMASYNC_PREWRITE);
   1254   1.1     pooka 	sc->qfullmsk &= ~(1 << ring->qid);
   1255   1.1     pooka 	ring->queued = 0;
   1256   1.1     pooka 	ring->cur = 0;
   1257   1.1     pooka }
   1258   1.1     pooka 
   1259   1.4    nonaka static void
   1260   1.1     pooka iwm_free_tx_ring(struct iwm_softc *sc, struct iwm_tx_ring *ring)
   1261   1.1     pooka {
   1262   1.1     pooka 	int i;
   1263   1.1     pooka 
   1264   1.1     pooka 	iwm_dma_contig_free(&ring->desc_dma);
   1265   1.1     pooka 	iwm_dma_contig_free(&ring->cmd_dma);
   1266   1.1     pooka 
   1267   1.1     pooka 	for (i = 0; i < IWM_TX_RING_COUNT; i++) {
   1268   1.1     pooka 		struct iwm_tx_data *data = &ring->data[i];
   1269   1.1     pooka 
   1270   1.1     pooka 		if (data->m != NULL) {
   1271   1.1     pooka 			bus_dmamap_sync(sc->sc_dmat, data->map, 0,
   1272   1.1     pooka 			    data->map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
   1273   1.1     pooka 			bus_dmamap_unload(sc->sc_dmat, data->map);
   1274   1.1     pooka 			m_freem(data->m);
   1275   1.1     pooka 		}
   1276   1.1     pooka 		if (data->map != NULL)
   1277   1.1     pooka 			bus_dmamap_destroy(sc->sc_dmat, data->map);
   1278   1.1     pooka 	}
   1279   1.1     pooka }
   1280   1.1     pooka 
   1281   1.1     pooka /*
   1282   1.1     pooka  * High-level hardware frobbing routines
   1283   1.1     pooka  */
   1284   1.1     pooka 
   1285   1.4    nonaka static void
   1286   1.1     pooka iwm_enable_rfkill_int(struct iwm_softc *sc)
   1287   1.1     pooka {
   1288   1.1     pooka 	sc->sc_intmask = IWM_CSR_INT_BIT_RF_KILL;
   1289   1.1     pooka 	IWM_WRITE(sc, IWM_CSR_INT_MASK, sc->sc_intmask);
   1290   1.1     pooka }
   1291   1.1     pooka 
   1292   1.4    nonaka static int
   1293   1.1     pooka iwm_check_rfkill(struct iwm_softc *sc)
   1294   1.1     pooka {
   1295   1.1     pooka 	uint32_t v;
   1296   1.1     pooka 	int s;
   1297   1.1     pooka 	int rv;
   1298   1.8    nonaka 
   1299   1.1     pooka 	s = splnet();
   1300   1.1     pooka 
   1301   1.1     pooka 	/*
   1302   1.1     pooka 	 * "documentation" is not really helpful here:
   1303   1.1     pooka 	 *  27:	HW_RF_KILL_SW
   1304   1.1     pooka 	 *	Indicates state of (platform's) hardware RF-Kill switch
   1305   1.1     pooka 	 *
   1306   1.1     pooka 	 * But apparently when it's off, it's on ...
   1307   1.1     pooka 	 */
   1308   1.1     pooka 	v = IWM_READ(sc, IWM_CSR_GP_CNTRL);
   1309   1.1     pooka 	rv = (v & IWM_CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) == 0;
   1310   1.1     pooka 	if (rv) {
   1311   1.1     pooka 		sc->sc_flags |= IWM_FLAG_RFKILL;
   1312   1.1     pooka 	} else {
   1313   1.1     pooka 		sc->sc_flags &= ~IWM_FLAG_RFKILL;
   1314   1.1     pooka 	}
   1315   1.1     pooka 
   1316   1.1     pooka 	splx(s);
   1317   1.1     pooka 	return rv;
   1318   1.1     pooka }
   1319   1.1     pooka 
   1320   1.4    nonaka static void
   1321   1.1     pooka iwm_enable_interrupts(struct iwm_softc *sc)
   1322   1.1     pooka {
   1323   1.1     pooka 	sc->sc_intmask = IWM_CSR_INI_SET_MASK;
   1324   1.1     pooka 	IWM_WRITE(sc, IWM_CSR_INT_MASK, sc->sc_intmask);
   1325   1.1     pooka }
   1326   1.1     pooka 
   1327   1.4    nonaka static void
   1328   1.1     pooka iwm_restore_interrupts(struct iwm_softc *sc)
   1329   1.1     pooka {
   1330   1.1     pooka 	IWM_WRITE(sc, IWM_CSR_INT_MASK, sc->sc_intmask);
   1331   1.1     pooka }
   1332   1.1     pooka 
   1333   1.4    nonaka static void
   1334   1.1     pooka iwm_disable_interrupts(struct iwm_softc *sc)
   1335   1.1     pooka {
   1336   1.1     pooka 	int s = splnet();
   1337   1.1     pooka 
   1338   1.1     pooka 	/* disable interrupts */
   1339   1.1     pooka 	IWM_WRITE(sc, IWM_CSR_INT_MASK, 0);
   1340   1.1     pooka 
   1341   1.1     pooka 	/* acknowledge all interrupts */
   1342   1.1     pooka 	IWM_WRITE(sc, IWM_CSR_INT, ~0);
   1343   1.1     pooka 	IWM_WRITE(sc, IWM_CSR_FH_INT_STATUS, ~0);
   1344   1.1     pooka 
   1345   1.1     pooka 	splx(s);
   1346   1.1     pooka }
   1347   1.1     pooka 
   1348   1.4    nonaka static void
   1349   1.1     pooka iwm_ict_reset(struct iwm_softc *sc)
   1350   1.1     pooka {
   1351   1.1     pooka 	iwm_disable_interrupts(sc);
   1352   1.1     pooka 
   1353   1.1     pooka 	/* Reset ICT table. */
   1354   1.1     pooka 	memset(sc->ict_dma.vaddr, 0, IWM_ICT_SIZE);
   1355   1.1     pooka 	sc->ict_cur = 0;
   1356   1.1     pooka 
   1357   1.1     pooka 	/* Set physical address of ICT table (4KB aligned). */
   1358   1.1     pooka 	IWM_WRITE(sc, IWM_CSR_DRAM_INT_TBL_REG,
   1359   1.1     pooka 	    IWM_CSR_DRAM_INT_TBL_ENABLE
   1360   1.1     pooka 	    | IWM_CSR_DRAM_INIT_TBL_WRAP_CHECK
   1361   1.1     pooka 	    | sc->ict_dma.paddr >> IWM_ICT_PADDR_SHIFT);
   1362   1.1     pooka 
   1363   1.1     pooka 	/* Switch to ICT interrupt mode in driver. */
   1364   1.1     pooka 	sc->sc_flags |= IWM_FLAG_USE_ICT;
   1365   1.1     pooka 
   1366   1.1     pooka 	/* Re-enable interrupts. */
   1367   1.1     pooka 	IWM_WRITE(sc, IWM_CSR_INT, ~0);
   1368   1.1     pooka 	iwm_enable_interrupts(sc);
   1369   1.1     pooka }
   1370   1.1     pooka 
   1371   1.1     pooka #define IWM_HW_READY_TIMEOUT 50
   1372   1.4    nonaka static int
   1373   1.1     pooka iwm_set_hw_ready(struct iwm_softc *sc)
   1374   1.1     pooka {
   1375   1.1     pooka 	IWM_SETBITS(sc, IWM_CSR_HW_IF_CONFIG_REG,
   1376   1.1     pooka 	    IWM_CSR_HW_IF_CONFIG_REG_BIT_NIC_READY);
   1377   1.1     pooka 
   1378   1.8    nonaka 	return iwm_poll_bit(sc, IWM_CSR_HW_IF_CONFIG_REG,
   1379   1.1     pooka 	    IWM_CSR_HW_IF_CONFIG_REG_BIT_NIC_READY,
   1380   1.1     pooka 	    IWM_CSR_HW_IF_CONFIG_REG_BIT_NIC_READY,
   1381   1.1     pooka 	    IWM_HW_READY_TIMEOUT);
   1382   1.1     pooka }
   1383   1.1     pooka #undef IWM_HW_READY_TIMEOUT
   1384   1.1     pooka 
   1385   1.4    nonaka static int
   1386   1.1     pooka iwm_prepare_card_hw(struct iwm_softc *sc)
   1387   1.1     pooka {
   1388   1.1     pooka 	int rv = 0;
   1389   1.1     pooka 	int t = 0;
   1390   1.1     pooka 
   1391  1.10    nonaka 	if (iwm_set_hw_ready(sc))
   1392   1.1     pooka 		goto out;
   1393   1.1     pooka 
   1394   1.1     pooka 	/* If HW is not ready, prepare the conditions to check again */
   1395   1.1     pooka 	IWM_SETBITS(sc, IWM_CSR_HW_IF_CONFIG_REG,
   1396   1.1     pooka 	    IWM_CSR_HW_IF_CONFIG_REG_PREPARE);
   1397   1.1     pooka 
   1398   1.1     pooka 	do {
   1399   1.1     pooka 		if (iwm_set_hw_ready(sc))
   1400   1.1     pooka 			goto out;
   1401   1.1     pooka 		DELAY(200);
   1402   1.1     pooka 		t += 200;
   1403   1.1     pooka 	} while (t < 150000);
   1404   1.1     pooka 
   1405   1.1     pooka 	rv = ETIMEDOUT;
   1406   1.1     pooka 
   1407   1.1     pooka  out:
   1408   1.1     pooka 	return rv;
   1409   1.1     pooka }
   1410   1.1     pooka 
   1411   1.4    nonaka static void
   1412   1.1     pooka iwm_apm_config(struct iwm_softc *sc)
   1413   1.1     pooka {
   1414   1.1     pooka 	pcireg_t reg;
   1415   1.1     pooka 
   1416   1.1     pooka 	reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag,
   1417   1.1     pooka 	    sc->sc_cap_off + PCIE_LCSR);
   1418   1.1     pooka 	if (reg & PCIE_LCSR_ASPM_L1) {
   1419   1.1     pooka 		/* Um the Linux driver prints "Disabling L0S for this one ... */
   1420   1.1     pooka 		IWM_SETBITS(sc, IWM_CSR_GIO_REG,
   1421   1.1     pooka 		    IWM_CSR_GIO_REG_VAL_L0S_ENABLED);
   1422   1.1     pooka 	} else {
   1423   1.1     pooka 		/* ... and "Enabling" here */
   1424   1.1     pooka 		IWM_CLRBITS(sc, IWM_CSR_GIO_REG,
   1425   1.1     pooka 		    IWM_CSR_GIO_REG_VAL_L0S_ENABLED);
   1426   1.1     pooka 	}
   1427   1.1     pooka }
   1428   1.1     pooka 
   1429   1.1     pooka /*
   1430   1.1     pooka  * Start up NIC's basic functionality after it has been reset
   1431   1.1     pooka  * (e.g. after platform boot, or shutdown via iwm_pcie_apm_stop())
   1432   1.1     pooka  * NOTE:  This does not load uCode nor start the embedded processor
   1433   1.1     pooka  */
   1434   1.4    nonaka static int
   1435   1.1     pooka iwm_apm_init(struct iwm_softc *sc)
   1436   1.1     pooka {
   1437   1.1     pooka 	int error = 0;
   1438   1.1     pooka 
   1439   1.1     pooka 	DPRINTF(("iwm apm start\n"));
   1440   1.1     pooka 
   1441   1.1     pooka 	/* Disable L0S exit timer (platform NMI Work/Around) */
   1442   1.1     pooka 	IWM_SETBITS(sc, IWM_CSR_GIO_CHICKEN_BITS,
   1443   1.1     pooka 	    IWM_CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
   1444   1.1     pooka 
   1445   1.1     pooka 	/*
   1446   1.1     pooka 	 * Disable L0s without affecting L1;
   1447   1.1     pooka 	 *  don't wait for ICH L0s (ICH bug W/A)
   1448   1.1     pooka 	 */
   1449   1.1     pooka 	IWM_SETBITS(sc, IWM_CSR_GIO_CHICKEN_BITS,
   1450   1.1     pooka 	    IWM_CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX);
   1451   1.1     pooka 
   1452   1.1     pooka 	/* Set FH wait threshold to maximum (HW error during stress W/A) */
   1453   1.1     pooka 	IWM_SETBITS(sc, IWM_CSR_DBG_HPET_MEM_REG, IWM_CSR_DBG_HPET_MEM_REG_VAL);
   1454   1.1     pooka 
   1455   1.1     pooka 	/*
   1456   1.1     pooka 	 * Enable HAP INTA (interrupt from management bus) to
   1457   1.1     pooka 	 * wake device's PCI Express link L1a -> L0s
   1458   1.1     pooka 	 */
   1459   1.1     pooka 	IWM_SETBITS(sc, IWM_CSR_HW_IF_CONFIG_REG,
   1460   1.1     pooka 	    IWM_CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A);
   1461   1.1     pooka 
   1462   1.1     pooka 	iwm_apm_config(sc);
   1463   1.1     pooka 
   1464   1.1     pooka #if 0 /* not for 7k */
   1465   1.1     pooka 	/* Configure analog phase-lock-loop before activating to D0A */
   1466   1.1     pooka 	if (trans->cfg->base_params->pll_cfg_val)
   1467   1.1     pooka 		IWM_SETBITS(trans, IWM_CSR_ANA_PLL_CFG,
   1468   1.1     pooka 		    trans->cfg->base_params->pll_cfg_val);
   1469   1.1     pooka #endif
   1470   1.1     pooka 
   1471   1.1     pooka 	/*
   1472   1.1     pooka 	 * Set "initialization complete" bit to move adapter from
   1473   1.1     pooka 	 * D0U* --> D0A* (powered-up active) state.
   1474   1.1     pooka 	 */
   1475   1.1     pooka 	IWM_SETBITS(sc, IWM_CSR_GP_CNTRL, IWM_CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
   1476   1.1     pooka 
   1477   1.1     pooka 	/*
   1478   1.1     pooka 	 * Wait for clock stabilization; once stabilized, access to
   1479   1.1     pooka 	 * device-internal resources is supported, e.g. iwm_write_prph()
   1480   1.1     pooka 	 * and accesses to uCode SRAM.
   1481   1.1     pooka 	 */
   1482   1.1     pooka 	if (!iwm_poll_bit(sc, IWM_CSR_GP_CNTRL,
   1483   1.1     pooka 	    IWM_CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
   1484   1.1     pooka 	    IWM_CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000)) {
   1485   1.3    nonaka 		aprint_error_dev(sc->sc_dev,
   1486   1.3    nonaka 		    "timeout waiting for clock stabilization\n");
   1487   1.1     pooka 		goto out;
   1488   1.1     pooka 	}
   1489   1.1     pooka 
   1490  1.17    nonaka 	if (sc->host_interrupt_operation_mode) {
   1491  1.17    nonaka 		/*
   1492  1.17    nonaka 		 * This is a bit of an abuse - This is needed for 7260 / 3160
   1493  1.17    nonaka 		 * only check host_interrupt_operation_mode even if this is
   1494  1.17    nonaka 		 * not related to host_interrupt_operation_mode.
   1495  1.17    nonaka 		 *
   1496  1.17    nonaka 		 * Enable the oscillator to count wake up time for L1 exit. This
   1497  1.17    nonaka 		 * consumes slightly more power (100uA) - but allows to be sure
   1498  1.17    nonaka 		 * that we wake up from L1 on time.
   1499  1.17    nonaka 		 *
   1500  1.17    nonaka 		 * This looks weird: read twice the same register, discard the
   1501  1.17    nonaka 		 * value, set a bit, and yet again, read that same register
   1502  1.17    nonaka 		 * just to discard the value. But that's the way the hardware
   1503  1.17    nonaka 		 * seems to like it.
   1504  1.17    nonaka 		 */
   1505  1.17    nonaka 		iwm_read_prph(sc, IWM_OSC_CLK);
   1506  1.17    nonaka 		iwm_read_prph(sc, IWM_OSC_CLK);
   1507  1.17    nonaka 		iwm_set_bits_prph(sc, IWM_OSC_CLK, IWM_OSC_CLK_FORCE_CONTROL);
   1508  1.17    nonaka 		iwm_read_prph(sc, IWM_OSC_CLK);
   1509  1.17    nonaka 		iwm_read_prph(sc, IWM_OSC_CLK);
   1510  1.17    nonaka 	}
   1511   1.1     pooka 
   1512   1.1     pooka 	/*
   1513   1.1     pooka 	 * Enable DMA clock and wait for it to stabilize.
   1514   1.1     pooka 	 *
   1515   1.1     pooka 	 * Write to "CLK_EN_REG"; "1" bits enable clocks, while "0" bits
   1516   1.1     pooka 	 * do not disable clocks.  This preserves any hardware bits already
   1517   1.1     pooka 	 * set by default in "CLK_CTRL_REG" after reset.
   1518   1.1     pooka 	 */
   1519   1.1     pooka 	iwm_write_prph(sc, IWM_APMG_CLK_EN_REG, IWM_APMG_CLK_VAL_DMA_CLK_RQT);
   1520   1.1     pooka 	//kpause("iwmapm", 0, mstohz(20), NULL);
   1521   1.1     pooka 	DELAY(20);
   1522   1.1     pooka 
   1523   1.1     pooka 	/* Disable L1-Active */
   1524   1.1     pooka 	iwm_set_bits_prph(sc, IWM_APMG_PCIDEV_STT_REG,
   1525   1.1     pooka 	    IWM_APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
   1526   1.1     pooka 
   1527   1.1     pooka 	/* Clear the interrupt in APMG if the NIC is in RFKILL */
   1528   1.1     pooka 	iwm_write_prph(sc, IWM_APMG_RTC_INT_STT_REG,
   1529   1.1     pooka 	    IWM_APMG_RTC_INT_STT_RFKILL);
   1530   1.1     pooka 
   1531   1.1     pooka  out:
   1532   1.1     pooka 	if (error)
   1533   1.3    nonaka 		aprint_error_dev(sc->sc_dev, "apm init error %d\n", error);
   1534   1.1     pooka 	return error;
   1535   1.1     pooka }
   1536   1.1     pooka 
   1537   1.1     pooka /* iwlwifi/pcie/trans.c */
   1538   1.4    nonaka static void
   1539   1.1     pooka iwm_apm_stop(struct iwm_softc *sc)
   1540   1.1     pooka {
   1541   1.1     pooka 	/* stop device's busmaster DMA activity */
   1542   1.1     pooka 	IWM_SETBITS(sc, IWM_CSR_RESET, IWM_CSR_RESET_REG_FLAG_STOP_MASTER);
   1543   1.1     pooka 
   1544   1.1     pooka 	if (!iwm_poll_bit(sc, IWM_CSR_RESET,
   1545   1.1     pooka 	    IWM_CSR_RESET_REG_FLAG_MASTER_DISABLED,
   1546   1.1     pooka 	    IWM_CSR_RESET_REG_FLAG_MASTER_DISABLED, 100))
   1547   1.3    nonaka 		aprint_error_dev(sc->sc_dev, "timeout waiting for master\n");
   1548   1.3    nonaka 	DPRINTF(("iwm apm stop\n"));
   1549   1.1     pooka }
   1550   1.1     pooka 
   1551   1.1     pooka /* iwlwifi pcie/trans.c */
   1552   1.4    nonaka static int
   1553   1.1     pooka iwm_start_hw(struct iwm_softc *sc)
   1554   1.1     pooka {
   1555   1.1     pooka 	int error;
   1556   1.1     pooka 
   1557   1.1     pooka 	if ((error = iwm_prepare_card_hw(sc)) != 0)
   1558   1.1     pooka 		return error;
   1559   1.1     pooka 
   1560   1.8    nonaka 	/* Reset the entire device */
   1561   1.1     pooka 	IWM_WRITE(sc, IWM_CSR_RESET,
   1562   1.1     pooka 	    IWM_CSR_RESET_REG_FLAG_SW_RESET |
   1563   1.1     pooka 	    IWM_CSR_RESET_REG_FLAG_NEVO_RESET);
   1564   1.1     pooka 	DELAY(10);
   1565   1.1     pooka 
   1566   1.1     pooka 	if ((error = iwm_apm_init(sc)) != 0)
   1567   1.1     pooka 		return error;
   1568   1.1     pooka 
   1569   1.1     pooka 	iwm_enable_rfkill_int(sc);
   1570   1.1     pooka 	iwm_check_rfkill(sc);
   1571   1.1     pooka 
   1572   1.1     pooka 	return 0;
   1573   1.1     pooka }
   1574   1.1     pooka 
   1575   1.1     pooka /* iwlwifi pcie/trans.c */
   1576   1.1     pooka 
   1577   1.4    nonaka static void
   1578   1.1     pooka iwm_stop_device(struct iwm_softc *sc)
   1579   1.1     pooka {
   1580   1.1     pooka 	int chnl, ntries;
   1581   1.1     pooka 	int qid;
   1582   1.1     pooka 
   1583   1.1     pooka 	/* tell the device to stop sending interrupts */
   1584   1.1     pooka 	iwm_disable_interrupts(sc);
   1585   1.1     pooka 
   1586   1.1     pooka 	/* device going down, Stop using ICT table */
   1587   1.1     pooka 	sc->sc_flags &= ~IWM_FLAG_USE_ICT;
   1588   1.1     pooka 
   1589   1.1     pooka 	/* stop tx and rx.  tx and rx bits, as usual, are from if_iwn */
   1590   1.1     pooka 
   1591   1.1     pooka 	iwm_write_prph(sc, IWM_SCD_TXFACT, 0);
   1592   1.1     pooka 
   1593   1.1     pooka 	/* Stop all DMA channels. */
   1594   1.1     pooka 	if (iwm_nic_lock(sc)) {
   1595   1.1     pooka 		for (chnl = 0; chnl < IWM_FH_TCSR_CHNL_NUM; chnl++) {
   1596   1.1     pooka 			IWM_WRITE(sc,
   1597   1.1     pooka 			    IWM_FH_TCSR_CHNL_TX_CONFIG_REG(chnl), 0);
   1598   1.1     pooka 			for (ntries = 0; ntries < 200; ntries++) {
   1599   1.1     pooka 				uint32_t r;
   1600   1.1     pooka 
   1601   1.1     pooka 				r = IWM_READ(sc, IWM_FH_TSSR_TX_STATUS_REG);
   1602   1.1     pooka 				if (r & IWM_FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(
   1603   1.1     pooka 				    chnl))
   1604   1.1     pooka 					break;
   1605   1.1     pooka 				DELAY(20);
   1606   1.1     pooka 			}
   1607   1.1     pooka 		}
   1608   1.1     pooka 		iwm_nic_unlock(sc);
   1609   1.1     pooka 	}
   1610   1.1     pooka 
   1611   1.1     pooka 	/* Stop RX ring. */
   1612   1.1     pooka 	iwm_reset_rx_ring(sc, &sc->rxq);
   1613   1.1     pooka 
   1614   1.1     pooka 	/* Reset all TX rings. */
   1615   1.1     pooka 	for (qid = 0; qid < __arraycount(sc->txq); qid++)
   1616   1.1     pooka 		iwm_reset_tx_ring(sc, &sc->txq[qid]);
   1617   1.1     pooka 
   1618   1.1     pooka 	/*
   1619   1.1     pooka 	 * Power-down device's busmaster DMA clocks
   1620   1.1     pooka 	 */
   1621   1.1     pooka 	iwm_write_prph(sc, IWM_APMG_CLK_DIS_REG, IWM_APMG_CLK_VAL_DMA_CLK_RQT);
   1622   1.1     pooka 	DELAY(5);
   1623   1.1     pooka 
   1624   1.1     pooka 	/* Make sure (redundant) we've released our request to stay awake */
   1625   1.1     pooka 	IWM_CLRBITS(sc, IWM_CSR_GP_CNTRL,
   1626   1.1     pooka 	    IWM_CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
   1627   1.1     pooka 
   1628   1.1     pooka 	/* Stop the device, and put it in low power state */
   1629   1.1     pooka 	iwm_apm_stop(sc);
   1630   1.1     pooka 
   1631   1.8    nonaka 	/* Upon stop, the APM issues an interrupt if HW RF kill is set.
   1632   1.8    nonaka 	 * Clean again the interrupt here
   1633   1.8    nonaka 	 */
   1634   1.1     pooka 	iwm_disable_interrupts(sc);
   1635   1.1     pooka 	/* stop and reset the on-board processor */
   1636   1.1     pooka 	IWM_WRITE(sc, IWM_CSR_RESET, IWM_CSR_RESET_REG_FLAG_NEVO_RESET);
   1637   1.1     pooka 
   1638   1.1     pooka 	/*
   1639   1.1     pooka 	 * Even if we stop the HW, we still want the RF kill
   1640   1.1     pooka 	 * interrupt
   1641   1.1     pooka 	 */
   1642   1.1     pooka 	iwm_enable_rfkill_int(sc);
   1643   1.1     pooka 	iwm_check_rfkill(sc);
   1644   1.1     pooka }
   1645   1.1     pooka 
   1646   1.1     pooka /* iwlwifi pcie/trans.c (always main power) */
   1647   1.4    nonaka static void
   1648   1.1     pooka iwm_set_pwr(struct iwm_softc *sc)
   1649   1.1     pooka {
   1650   1.1     pooka 	iwm_set_bits_mask_prph(sc, IWM_APMG_PS_CTRL_REG,
   1651   1.1     pooka 	    IWM_APMG_PS_CTRL_VAL_PWR_SRC_VMAIN, ~IWM_APMG_PS_CTRL_MSK_PWR_SRC);
   1652   1.1     pooka }
   1653   1.1     pooka 
   1654   1.1     pooka /* iwlwifi: mvm/ops.c */
   1655   1.4    nonaka static void
   1656   1.1     pooka iwm_mvm_nic_config(struct iwm_softc *sc)
   1657   1.1     pooka {
   1658   1.1     pooka 	uint8_t radio_cfg_type, radio_cfg_step, radio_cfg_dash;
   1659   1.1     pooka 	uint32_t reg_val = 0;
   1660   1.1     pooka 
   1661   1.1     pooka 	radio_cfg_type = (sc->sc_fw_phy_config & IWM_FW_PHY_CFG_RADIO_TYPE) >>
   1662   1.1     pooka 	    IWM_FW_PHY_CFG_RADIO_TYPE_POS;
   1663   1.1     pooka 	radio_cfg_step = (sc->sc_fw_phy_config & IWM_FW_PHY_CFG_RADIO_STEP) >>
   1664   1.1     pooka 	    IWM_FW_PHY_CFG_RADIO_STEP_POS;
   1665   1.1     pooka 	radio_cfg_dash = (sc->sc_fw_phy_config & IWM_FW_PHY_CFG_RADIO_DASH) >>
   1666   1.1     pooka 	    IWM_FW_PHY_CFG_RADIO_DASH_POS;
   1667   1.1     pooka 
   1668   1.1     pooka 	/* SKU control */
   1669   1.1     pooka 	reg_val |= IWM_CSR_HW_REV_STEP(sc->sc_hw_rev) <<
   1670   1.1     pooka 	    IWM_CSR_HW_IF_CONFIG_REG_POS_MAC_STEP;
   1671   1.1     pooka 	reg_val |= IWM_CSR_HW_REV_DASH(sc->sc_hw_rev) <<
   1672   1.1     pooka 	    IWM_CSR_HW_IF_CONFIG_REG_POS_MAC_DASH;
   1673   1.1     pooka 
   1674   1.1     pooka 	/* radio configuration */
   1675   1.1     pooka 	reg_val |= radio_cfg_type << IWM_CSR_HW_IF_CONFIG_REG_POS_PHY_TYPE;
   1676   1.1     pooka 	reg_val |= radio_cfg_step << IWM_CSR_HW_IF_CONFIG_REG_POS_PHY_STEP;
   1677   1.1     pooka 	reg_val |= radio_cfg_dash << IWM_CSR_HW_IF_CONFIG_REG_POS_PHY_DASH;
   1678   1.1     pooka 
   1679   1.1     pooka 	IWM_WRITE(sc, IWM_CSR_HW_IF_CONFIG_REG, reg_val);
   1680   1.1     pooka 
   1681   1.8    nonaka 	DPRINTF(("Radio type=0x%x-0x%x-0x%x\n", radio_cfg_type,
   1682   1.8    nonaka 	    radio_cfg_step, radio_cfg_dash));
   1683   1.1     pooka 
   1684   1.1     pooka 	/*
   1685   1.1     pooka 	 * W/A : NIC is stuck in a reset state after Early PCIe power off
   1686   1.1     pooka 	 * (PCIe power is lost before PERST# is asserted), causing ME FW
   1687   1.1     pooka 	 * to lose ownership and not being able to obtain it back.
   1688   1.1     pooka 	 */
   1689   1.1     pooka 	iwm_set_bits_mask_prph(sc, IWM_APMG_PS_CTRL_REG,
   1690   1.1     pooka 	    IWM_APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS,
   1691   1.1     pooka 	    ~IWM_APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS);
   1692   1.1     pooka }
   1693   1.1     pooka 
   1694   1.4    nonaka static int
   1695   1.1     pooka iwm_nic_rx_init(struct iwm_softc *sc)
   1696   1.1     pooka {
   1697   1.1     pooka 	if (!iwm_nic_lock(sc))
   1698   1.1     pooka 		return EBUSY;
   1699   1.1     pooka 
   1700   1.1     pooka 	/*
   1701   1.1     pooka 	 * Initialize RX ring.  This is from the iwn driver.
   1702   1.1     pooka 	 */
   1703   1.1     pooka 	memset(sc->rxq.stat, 0, sizeof(*sc->rxq.stat));
   1704   1.1     pooka 
   1705   1.1     pooka 	/* stop DMA */
   1706   1.1     pooka 	IWM_WRITE(sc, IWM_FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
   1707   1.1     pooka 	IWM_WRITE(sc, IWM_FH_MEM_RCSR_CHNL0_RBDCB_WPTR, 0);
   1708   1.1     pooka 	IWM_WRITE(sc, IWM_FH_MEM_RCSR_CHNL0_FLUSH_RB_REQ, 0);
   1709   1.1     pooka 	IWM_WRITE(sc, IWM_FH_RSCSR_CHNL0_RDPTR, 0);
   1710   1.1     pooka 	IWM_WRITE(sc, IWM_FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0);
   1711   1.1     pooka 
   1712   1.1     pooka 	/* Set physical address of RX ring (256-byte aligned). */
   1713   1.1     pooka 	IWM_WRITE(sc,
   1714   1.1     pooka 	    IWM_FH_RSCSR_CHNL0_RBDCB_BASE_REG, sc->rxq.desc_dma.paddr >> 8);
   1715   1.1     pooka 
   1716   1.1     pooka 	/* Set physical address of RX status (16-byte aligned). */
   1717   1.1     pooka 	IWM_WRITE(sc,
   1718   1.1     pooka 	    IWM_FH_RSCSR_CHNL0_STTS_WPTR_REG, sc->rxq.stat_dma.paddr >> 4);
   1719   1.1     pooka 
   1720   1.1     pooka 	/* Enable RX. */
   1721   1.1     pooka 	/*
   1722   1.1     pooka 	 * Note: Linux driver also sets this:
   1723   1.1     pooka 	 *  (IWM_RX_RB_TIMEOUT << IWM_FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS) |
   1724   1.1     pooka 	 *
   1725   1.1     pooka 	 * It causes weird behavior.  YMMV.
   1726   1.1     pooka 	 */
   1727   1.1     pooka 	IWM_WRITE(sc, IWM_FH_MEM_RCSR_CHNL0_CONFIG_REG,
   1728   1.1     pooka 	    IWM_FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL		|
   1729   1.1     pooka 	    IWM_FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY		|  /* HW bug */
   1730   1.1     pooka 	    IWM_FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL	|
   1731   1.1     pooka 	    IWM_FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K		|
   1732   1.1     pooka 	    IWM_RX_QUEUE_SIZE_LOG << IWM_FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS);
   1733   1.1     pooka 
   1734   1.1     pooka 	IWM_WRITE_1(sc, IWM_CSR_INT_COALESCING, IWM_HOST_INT_TIMEOUT_DEF);
   1735  1.17    nonaka 
   1736  1.17    nonaka 	/* W/A for interrupt coalescing bug in 7260 and 3160 */
   1737  1.17    nonaka 	if (sc->host_interrupt_operation_mode)
   1738  1.17    nonaka 		IWM_SETBITS(sc, IWM_CSR_INT_COALESCING, IWM_HOST_INT_OPER_MODE);
   1739   1.1     pooka 
   1740   1.1     pooka 	/*
   1741   1.1     pooka 	 * Thus sayeth el jefe (iwlwifi) via a comment:
   1742   1.1     pooka 	 *
   1743   1.1     pooka 	 * This value should initially be 0 (before preparing any
   1744   1.1     pooka  	 * RBs), should be 8 after preparing the first 8 RBs (for example)
   1745   1.1     pooka 	 */
   1746   1.1     pooka 	IWM_WRITE(sc, IWM_FH_RSCSR_CHNL0_WPTR, 8);
   1747   1.1     pooka 
   1748   1.1     pooka 	iwm_nic_unlock(sc);
   1749   1.1     pooka 
   1750   1.1     pooka 	return 0;
   1751   1.1     pooka }
   1752   1.1     pooka 
   1753   1.4    nonaka static int
   1754   1.1     pooka iwm_nic_tx_init(struct iwm_softc *sc)
   1755   1.1     pooka {
   1756   1.1     pooka 	int qid;
   1757   1.1     pooka 
   1758   1.1     pooka 	if (!iwm_nic_lock(sc))
   1759   1.1     pooka 		return EBUSY;
   1760   1.1     pooka 
   1761   1.1     pooka 	/* Deactivate TX scheduler. */
   1762   1.1     pooka 	iwm_write_prph(sc, IWM_SCD_TXFACT, 0);
   1763   1.1     pooka 
   1764   1.1     pooka 	/* Set physical address of "keep warm" page (16-byte aligned). */
   1765   1.1     pooka 	IWM_WRITE(sc, IWM_FH_KW_MEM_ADDR_REG, sc->kw_dma.paddr >> 4);
   1766   1.1     pooka 
   1767   1.1     pooka 	/* Initialize TX rings. */
   1768   1.1     pooka 	for (qid = 0; qid < __arraycount(sc->txq); qid++) {
   1769   1.1     pooka 		struct iwm_tx_ring *txq = &sc->txq[qid];
   1770   1.1     pooka 
   1771   1.1     pooka 		/* Set physical address of TX ring (256-byte aligned). */
   1772   1.1     pooka 		IWM_WRITE(sc, IWM_FH_MEM_CBBC_QUEUE(qid),
   1773   1.1     pooka 		    txq->desc_dma.paddr >> 8);
   1774   1.9    nonaka 		DPRINTF(("loading ring %d descriptors (%p) at %"PRIxMAX"\n",
   1775   1.9    nonaka 		    qid, txq->desc, (uintmax_t)(txq->desc_dma.paddr >> 8)));
   1776   1.1     pooka 	}
   1777   1.1     pooka 	iwm_nic_unlock(sc);
   1778   1.1     pooka 
   1779   1.1     pooka 	return 0;
   1780   1.1     pooka }
   1781   1.1     pooka 
   1782   1.4    nonaka static int
   1783   1.1     pooka iwm_nic_init(struct iwm_softc *sc)
   1784   1.1     pooka {
   1785   1.1     pooka 	int error;
   1786   1.1     pooka 
   1787   1.1     pooka 	iwm_apm_init(sc);
   1788   1.1     pooka 	iwm_set_pwr(sc);
   1789   1.1     pooka 
   1790   1.1     pooka 	iwm_mvm_nic_config(sc);
   1791   1.1     pooka 
   1792   1.1     pooka 	if ((error = iwm_nic_rx_init(sc)) != 0)
   1793   1.1     pooka 		return error;
   1794   1.1     pooka 
   1795   1.1     pooka 	/*
   1796   1.1     pooka 	 * Ditto for TX, from iwn
   1797   1.1     pooka 	 */
   1798   1.1     pooka 	if ((error = iwm_nic_tx_init(sc)) != 0)
   1799   1.1     pooka 		return error;
   1800   1.1     pooka 
   1801   1.1     pooka 	DPRINTF(("shadow registers enabled\n"));
   1802   1.1     pooka 	IWM_SETBITS(sc, IWM_CSR_MAC_SHADOW_REG_CTRL, 0x800fffff);
   1803   1.1     pooka 
   1804   1.8    nonaka 	return 0;
   1805   1.1     pooka }
   1806   1.1     pooka 
   1807   1.7    nonaka #if 0
   1808   1.1     pooka enum iwm_mvm_tx_fifo {
   1809   1.1     pooka 	IWM_MVM_TX_FIFO_BK = 0,
   1810   1.1     pooka 	IWM_MVM_TX_FIFO_BE,
   1811   1.1     pooka 	IWM_MVM_TX_FIFO_VI,
   1812   1.1     pooka 	IWM_MVM_TX_FIFO_VO,
   1813   1.1     pooka 	IWM_MVM_TX_FIFO_MCAST = 5,
   1814   1.1     pooka };
   1815   1.1     pooka 
   1816   1.4    nonaka static const uint8_t iwm_mvm_ac_to_tx_fifo[] = {
   1817   1.8    nonaka 	IWM_MVM_TX_FIFO_VO,
   1818   1.8    nonaka 	IWM_MVM_TX_FIFO_VI,
   1819   1.8    nonaka 	IWM_MVM_TX_FIFO_BE,
   1820   1.8    nonaka 	IWM_MVM_TX_FIFO_BK,
   1821   1.1     pooka };
   1822   1.7    nonaka #endif
   1823   1.1     pooka 
   1824   1.4    nonaka static void
   1825   1.1     pooka iwm_enable_txq(struct iwm_softc *sc, int qid, int fifo)
   1826   1.1     pooka {
   1827   1.1     pooka 	if (!iwm_nic_lock(sc)) {
   1828   1.2    nonaka 		DPRINTF(("%s: cannot enable txq %d\n", DEVNAME(sc), qid));
   1829   1.2    nonaka 		return; /* XXX return EBUSY */
   1830   1.1     pooka 	}
   1831   1.1     pooka 
   1832   1.1     pooka 	/* unactivate before configuration */
   1833   1.1     pooka 	iwm_write_prph(sc, IWM_SCD_QUEUE_STATUS_BITS(qid),
   1834   1.1     pooka 	    (0 << IWM_SCD_QUEUE_STTS_REG_POS_ACTIVE)
   1835   1.1     pooka 	    | (1 << IWM_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN));
   1836   1.1     pooka 
   1837   1.1     pooka 	if (qid != IWM_MVM_CMD_QUEUE) {
   1838   1.1     pooka 		iwm_set_bits_prph(sc, IWM_SCD_QUEUECHAIN_SEL, (1 << qid));
   1839   1.1     pooka 	}
   1840   1.1     pooka 
   1841   1.1     pooka 	iwm_clear_bits_prph(sc, IWM_SCD_AGGR_SEL, (1 << qid));
   1842   1.1     pooka 
   1843   1.1     pooka 	IWM_WRITE(sc, IWM_HBUS_TARG_WRPTR, qid << 8 | 0);
   1844   1.1     pooka 	iwm_write_prph(sc, IWM_SCD_QUEUE_RDPTR(qid), 0);
   1845   1.1     pooka 
   1846   1.1     pooka 	iwm_write_mem32(sc, sc->sched_base + IWM_SCD_CONTEXT_QUEUE_OFFSET(qid), 0);
   1847   1.1     pooka 	/* Set scheduler window size and frame limit. */
   1848   1.1     pooka 	iwm_write_mem32(sc,
   1849   1.1     pooka 	    sc->sched_base + IWM_SCD_CONTEXT_QUEUE_OFFSET(qid) +
   1850   1.1     pooka 	    sizeof(uint32_t),
   1851   1.1     pooka 	    ((IWM_FRAME_LIMIT << IWM_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) &
   1852   1.1     pooka 	    IWM_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) |
   1853   1.1     pooka 	    ((IWM_FRAME_LIMIT << IWM_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) &
   1854   1.1     pooka 	    IWM_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK));
   1855   1.1     pooka 
   1856   1.1     pooka 	iwm_write_prph(sc, IWM_SCD_QUEUE_STATUS_BITS(qid),
   1857   1.1     pooka 	    (1 << IWM_SCD_QUEUE_STTS_REG_POS_ACTIVE) |
   1858   1.1     pooka 	    (fifo << IWM_SCD_QUEUE_STTS_REG_POS_TXF) |
   1859   1.1     pooka 	    (1 << IWM_SCD_QUEUE_STTS_REG_POS_WSL) |
   1860   1.1     pooka 	    IWM_SCD_QUEUE_STTS_REG_MSK);
   1861   1.1     pooka 
   1862   1.1     pooka 	iwm_nic_unlock(sc);
   1863   1.1     pooka 
   1864   1.1     pooka 	DPRINTF(("enabled txq %d FIFO %d\n", qid, fifo));
   1865   1.1     pooka }
   1866   1.1     pooka 
   1867   1.4    nonaka static int
   1868   1.1     pooka iwm_post_alive(struct iwm_softc *sc)
   1869   1.1     pooka {
   1870   1.1     pooka 	int nwords;
   1871   1.1     pooka 	int error, chnl;
   1872   1.1     pooka 
   1873   1.1     pooka 	if (!iwm_nic_lock(sc))
   1874   1.1     pooka 		return EBUSY;
   1875   1.1     pooka 
   1876   1.1     pooka 	if (sc->sched_base != iwm_read_prph(sc, IWM_SCD_SRAM_BASE_ADDR)) {
   1877   1.5    nonaka 		DPRINTF(("%s: sched addr mismatch\n", DEVNAME(sc)));
   1878   1.1     pooka 		error = EINVAL;
   1879   1.1     pooka 		goto out;
   1880   1.1     pooka 	}
   1881   1.1     pooka 
   1882   1.1     pooka 	iwm_ict_reset(sc);
   1883   1.1     pooka 
   1884   1.1     pooka 	/* Clear TX scheduler state in SRAM. */
   1885   1.1     pooka 	nwords = (IWM_SCD_TRANS_TBL_MEM_UPPER_BOUND -
   1886   1.1     pooka 	    IWM_SCD_CONTEXT_MEM_LOWER_BOUND)
   1887   1.1     pooka 	    / sizeof(uint32_t);
   1888   1.1     pooka 	error = iwm_write_mem(sc,
   1889   1.1     pooka 	    sc->sched_base + IWM_SCD_CONTEXT_MEM_LOWER_BOUND,
   1890   1.1     pooka 	    NULL, nwords);
   1891   1.1     pooka 	if (error)
   1892   1.1     pooka 		goto out;
   1893   1.1     pooka 
   1894   1.1     pooka 	/* Set physical address of TX scheduler rings (1KB aligned). */
   1895   1.1     pooka 	iwm_write_prph(sc, IWM_SCD_DRAM_BASE_ADDR, sc->sched_dma.paddr >> 10);
   1896   1.1     pooka 
   1897   1.1     pooka 	iwm_write_prph(sc, IWM_SCD_CHAINEXT_EN, 0);
   1898   1.1     pooka 
   1899   1.1     pooka 	/* enable command channel */
   1900   1.1     pooka 	iwm_enable_txq(sc, IWM_MVM_CMD_QUEUE, 7);
   1901   1.1     pooka 
   1902   1.1     pooka 	iwm_write_prph(sc, IWM_SCD_TXFACT, 0xff);
   1903   1.1     pooka 
   1904   1.1     pooka 	/* Enable DMA channels. */
   1905   1.1     pooka 	for (chnl = 0; chnl < IWM_FH_TCSR_CHNL_NUM; chnl++) {
   1906   1.1     pooka 		IWM_WRITE(sc, IWM_FH_TCSR_CHNL_TX_CONFIG_REG(chnl),
   1907   1.1     pooka 		    IWM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE |
   1908   1.1     pooka 		    IWM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE);
   1909   1.1     pooka 	}
   1910   1.1     pooka 
   1911   1.1     pooka 	IWM_SETBITS(sc, IWM_FH_TX_CHICKEN_BITS_REG,
   1912   1.1     pooka 	    IWM_FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN);
   1913   1.1     pooka 
   1914   1.8    nonaka 	/* Enable L1-Active */
   1915   1.1     pooka 	iwm_clear_bits_prph(sc, IWM_APMG_PCIDEV_STT_REG,
   1916   1.1     pooka 	    IWM_APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
   1917   1.1     pooka 
   1918   1.1     pooka  out:
   1919   1.1     pooka  	iwm_nic_unlock(sc);
   1920   1.1     pooka 	return error;
   1921   1.1     pooka }
   1922   1.1     pooka 
   1923   1.1     pooka /*
   1924   1.1     pooka  * PHY db
   1925   1.1     pooka  * iwlwifi/iwl-phy-db.c
   1926   1.1     pooka  */
   1927   1.1     pooka 
   1928   1.1     pooka /*
   1929   1.1     pooka  * BEGIN iwl-phy-db.c
   1930   1.1     pooka  */
   1931   1.1     pooka 
   1932   1.1     pooka enum iwm_phy_db_section_type {
   1933   1.1     pooka 	IWM_PHY_DB_CFG = 1,
   1934   1.1     pooka 	IWM_PHY_DB_CALIB_NCH,
   1935   1.1     pooka 	IWM_PHY_DB_UNUSED,
   1936   1.1     pooka 	IWM_PHY_DB_CALIB_CHG_PAPD,
   1937   1.1     pooka 	IWM_PHY_DB_CALIB_CHG_TXP,
   1938   1.1     pooka 	IWM_PHY_DB_MAX
   1939   1.1     pooka };
   1940   1.1     pooka 
   1941   1.1     pooka #define IWM_PHY_DB_CMD 0x6c /* TEMP API - The actual is 0x8c */
   1942   1.1     pooka 
   1943   1.1     pooka /*
   1944   1.1     pooka  * phy db - configure operational ucode
   1945   1.1     pooka  */
   1946   1.1     pooka struct iwm_phy_db_cmd {
   1947   1.1     pooka 	uint16_t type;
   1948   1.1     pooka 	uint16_t length;
   1949   1.1     pooka 	uint8_t data[];
   1950   1.1     pooka } __packed;
   1951   1.1     pooka 
   1952   1.1     pooka /* for parsing of tx power channel group data that comes from the firmware*/
   1953   1.1     pooka struct iwm_phy_db_chg_txp {
   1954   1.1     pooka 	uint32_t space;
   1955   1.1     pooka 	uint16_t max_channel_idx;
   1956   1.1     pooka } __packed;
   1957   1.1     pooka 
   1958   1.1     pooka /*
   1959   1.1     pooka  * phy db - Receive phy db chunk after calibrations
   1960   1.1     pooka  */
   1961   1.1     pooka struct iwm_calib_res_notif_phy_db {
   1962   1.1     pooka 	uint16_t type;
   1963   1.1     pooka 	uint16_t length;
   1964   1.1     pooka 	uint8_t data[];
   1965   1.1     pooka } __packed;
   1966   1.1     pooka 
   1967   1.1     pooka /*
   1968   1.1     pooka  * get phy db section: returns a pointer to a phy db section specified by
   1969   1.1     pooka  * type and channel group id.
   1970   1.1     pooka  */
   1971   1.1     pooka static struct iwm_phy_db_entry *
   1972   1.1     pooka iwm_phy_db_get_section(struct iwm_softc *sc,
   1973   1.1     pooka 	enum iwm_phy_db_section_type type, uint16_t chg_id)
   1974   1.1     pooka {
   1975   1.1     pooka 	struct iwm_phy_db *phy_db = &sc->sc_phy_db;
   1976   1.1     pooka 
   1977   1.1     pooka 	if (type >= IWM_PHY_DB_MAX)
   1978   1.1     pooka 		return NULL;
   1979   1.1     pooka 
   1980   1.1     pooka 	switch (type) {
   1981   1.1     pooka 	case IWM_PHY_DB_CFG:
   1982   1.1     pooka 		return &phy_db->cfg;
   1983   1.1     pooka 	case IWM_PHY_DB_CALIB_NCH:
   1984   1.1     pooka 		return &phy_db->calib_nch;
   1985   1.1     pooka 	case IWM_PHY_DB_CALIB_CHG_PAPD:
   1986   1.1     pooka 		if (chg_id >= IWM_NUM_PAPD_CH_GROUPS)
   1987   1.1     pooka 			return NULL;
   1988   1.1     pooka 		return &phy_db->calib_ch_group_papd[chg_id];
   1989   1.1     pooka 	case IWM_PHY_DB_CALIB_CHG_TXP:
   1990   1.1     pooka 		if (chg_id >= IWM_NUM_TXP_CH_GROUPS)
   1991   1.1     pooka 			return NULL;
   1992   1.1     pooka 		return &phy_db->calib_ch_group_txp[chg_id];
   1993   1.1     pooka 	default:
   1994   1.1     pooka 		return NULL;
   1995   1.1     pooka 	}
   1996   1.1     pooka 	return NULL;
   1997   1.1     pooka }
   1998   1.1     pooka 
   1999   1.1     pooka static int
   2000   1.1     pooka iwm_phy_db_set_section(struct iwm_softc *sc,
   2001   1.5    nonaka     struct iwm_calib_res_notif_phy_db *phy_db_notif, uint16_t size)
   2002   1.1     pooka {
   2003   1.1     pooka 	enum iwm_phy_db_section_type type = le16toh(phy_db_notif->type);
   2004   1.1     pooka 	struct iwm_phy_db_entry *entry;
   2005   1.1     pooka 	uint16_t chg_id = 0;
   2006   1.1     pooka 
   2007   1.1     pooka 	if (type == IWM_PHY_DB_CALIB_CHG_PAPD ||
   2008   1.1     pooka 	    type == IWM_PHY_DB_CALIB_CHG_TXP)
   2009   1.1     pooka 		chg_id = le16toh(*(uint16_t *)phy_db_notif->data);
   2010   1.1     pooka 
   2011   1.1     pooka 	entry = iwm_phy_db_get_section(sc, type, chg_id);
   2012   1.1     pooka 	if (!entry)
   2013   1.1     pooka 		return EINVAL;
   2014   1.1     pooka 
   2015   1.1     pooka 	if (entry->data)
   2016   1.5    nonaka 		kmem_intr_free(entry->data, entry->size);
   2017   1.5    nonaka 	entry->data = kmem_intr_alloc(size, KM_NOSLEEP);
   2018   1.1     pooka 	if (!entry->data) {
   2019   1.1     pooka 		entry->size = 0;
   2020   1.1     pooka 		return ENOMEM;
   2021   1.1     pooka 	}
   2022   1.1     pooka 	memcpy(entry->data, phy_db_notif->data, size);
   2023   1.1     pooka 	entry->size = size;
   2024   1.1     pooka 
   2025   1.5    nonaka 	DPRINTFN(10, ("%s(%d): [PHYDB]SET: Type %d, Size: %d, data: %p\n",
   2026   1.1     pooka 	    __func__, __LINE__, type, size, entry->data));
   2027   1.1     pooka 
   2028   1.1     pooka 	return 0;
   2029   1.1     pooka }
   2030   1.1     pooka 
   2031   1.4    nonaka static int
   2032   1.1     pooka iwm_is_valid_channel(uint16_t ch_id)
   2033   1.1     pooka {
   2034   1.1     pooka 	if (ch_id <= 14 ||
   2035   1.1     pooka 	    (36 <= ch_id && ch_id <= 64 && ch_id % 4 == 0) ||
   2036   1.1     pooka 	    (100 <= ch_id && ch_id <= 140 && ch_id % 4 == 0) ||
   2037   1.1     pooka 	    (145 <= ch_id && ch_id <= 165 && ch_id % 4 == 1))
   2038   1.1     pooka 		return 1;
   2039   1.1     pooka 	return 0;
   2040   1.1     pooka }
   2041   1.1     pooka 
   2042   1.4    nonaka static uint8_t
   2043   1.1     pooka iwm_ch_id_to_ch_index(uint16_t ch_id)
   2044   1.1     pooka {
   2045   1.1     pooka 	if (!iwm_is_valid_channel(ch_id))
   2046   1.1     pooka 		return 0xff;
   2047   1.1     pooka 
   2048   1.1     pooka 	if (ch_id <= 14)
   2049   1.1     pooka 		return ch_id - 1;
   2050   1.1     pooka 	if (ch_id <= 64)
   2051   1.1     pooka 		return (ch_id + 20) / 4;
   2052   1.1     pooka 	if (ch_id <= 140)
   2053   1.1     pooka 		return (ch_id - 12) / 4;
   2054   1.1     pooka 	return (ch_id - 13) / 4;
   2055   1.1     pooka }
   2056   1.1     pooka 
   2057   1.1     pooka 
   2058   1.4    nonaka static uint16_t
   2059   1.1     pooka iwm_channel_id_to_papd(uint16_t ch_id)
   2060   1.1     pooka {
   2061   1.1     pooka 	if (!iwm_is_valid_channel(ch_id))
   2062   1.1     pooka 		return 0xff;
   2063   1.1     pooka 
   2064   1.1     pooka 	if (1 <= ch_id && ch_id <= 14)
   2065   1.1     pooka 		return 0;
   2066   1.1     pooka 	if (36 <= ch_id && ch_id <= 64)
   2067   1.1     pooka 		return 1;
   2068   1.1     pooka 	if (100 <= ch_id && ch_id <= 140)
   2069   1.1     pooka 		return 2;
   2070   1.1     pooka 	return 3;
   2071   1.1     pooka }
   2072   1.1     pooka 
   2073   1.4    nonaka static uint16_t
   2074   1.1     pooka iwm_channel_id_to_txp(struct iwm_softc *sc, uint16_t ch_id)
   2075   1.1     pooka {
   2076   1.1     pooka 	struct iwm_phy_db *phy_db = &sc->sc_phy_db;
   2077   1.1     pooka 	struct iwm_phy_db_chg_txp *txp_chg;
   2078   1.1     pooka 	int i;
   2079   1.1     pooka 	uint8_t ch_index = iwm_ch_id_to_ch_index(ch_id);
   2080   1.1     pooka 
   2081   1.1     pooka 	if (ch_index == 0xff)
   2082   1.1     pooka 		return 0xff;
   2083   1.1     pooka 
   2084   1.1     pooka 	for (i = 0; i < IWM_NUM_TXP_CH_GROUPS; i++) {
   2085   1.1     pooka 		txp_chg = (void *)phy_db->calib_ch_group_txp[i].data;
   2086   1.1     pooka 		if (!txp_chg)
   2087   1.1     pooka 			return 0xff;
   2088   1.1     pooka 		/*
   2089   1.1     pooka 		 * Looking for the first channel group that its max channel is
   2090   1.1     pooka 		 * higher then wanted channel.
   2091   1.1     pooka 		 */
   2092   1.1     pooka 		if (le16toh(txp_chg->max_channel_idx) >= ch_index)
   2093   1.1     pooka 			return i;
   2094   1.1     pooka 	}
   2095   1.1     pooka 	return 0xff;
   2096   1.1     pooka }
   2097   1.1     pooka 
   2098   1.4    nonaka static int
   2099   1.1     pooka iwm_phy_db_get_section_data(struct iwm_softc *sc,
   2100   1.1     pooka 	uint32_t type, uint8_t **data, uint16_t *size, uint16_t ch_id)
   2101   1.1     pooka {
   2102   1.1     pooka 	struct iwm_phy_db_entry *entry;
   2103   1.1     pooka 	uint16_t ch_group_id = 0;
   2104   1.1     pooka 
   2105   1.1     pooka 	/* find wanted channel group */
   2106   1.1     pooka 	if (type == IWM_PHY_DB_CALIB_CHG_PAPD)
   2107   1.1     pooka 		ch_group_id = iwm_channel_id_to_papd(ch_id);
   2108   1.1     pooka 	else if (type == IWM_PHY_DB_CALIB_CHG_TXP)
   2109   1.1     pooka 		ch_group_id = iwm_channel_id_to_txp(sc, ch_id);
   2110   1.1     pooka 
   2111   1.1     pooka 	entry = iwm_phy_db_get_section(sc, type, ch_group_id);
   2112   1.1     pooka 	if (!entry)
   2113   1.1     pooka 		return EINVAL;
   2114   1.1     pooka 
   2115   1.1     pooka 	*data = entry->data;
   2116   1.1     pooka 	*size = entry->size;
   2117   1.1     pooka 
   2118   1.1     pooka 	DPRINTFN(10, ("%s(%d): [PHYDB] GET: Type %d , Size: %d\n",
   2119   1.1     pooka 		       __func__, __LINE__, type, *size));
   2120   1.1     pooka 
   2121   1.1     pooka 	return 0;
   2122   1.1     pooka }
   2123   1.1     pooka 
   2124   1.4    nonaka static int
   2125   1.1     pooka iwm_send_phy_db_cmd(struct iwm_softc *sc, uint16_t type,
   2126   1.1     pooka 	uint16_t length, void *data)
   2127   1.1     pooka {
   2128   1.1     pooka 	struct iwm_phy_db_cmd phy_db_cmd;
   2129   1.1     pooka 	struct iwm_host_cmd cmd = {
   2130   1.1     pooka 		.id = IWM_PHY_DB_CMD,
   2131   1.1     pooka 		.flags = IWM_CMD_SYNC,
   2132   1.1     pooka 	};
   2133   1.1     pooka 
   2134   1.5    nonaka 	DPRINTFN(10, ("Sending PHY-DB hcmd of type %d, of length %d\n",
   2135   1.5    nonaka 	    type, length));
   2136   1.1     pooka 
   2137   1.1     pooka 	/* Set phy db cmd variables */
   2138   1.1     pooka 	phy_db_cmd.type = le16toh(type);
   2139   1.1     pooka 	phy_db_cmd.length = le16toh(length);
   2140   1.1     pooka 
   2141   1.1     pooka 	/* Set hcmd variables */
   2142   1.1     pooka 	cmd.data[0] = &phy_db_cmd;
   2143   1.1     pooka 	cmd.len[0] = sizeof(struct iwm_phy_db_cmd);
   2144   1.1     pooka 	cmd.data[1] = data;
   2145   1.1     pooka 	cmd.len[1] = length;
   2146   1.1     pooka 	cmd.dataflags[1] = IWM_HCMD_DFL_NOCOPY;
   2147   1.1     pooka 
   2148   1.1     pooka 	return iwm_send_cmd(sc, &cmd);
   2149   1.1     pooka }
   2150   1.1     pooka 
   2151   1.1     pooka static int
   2152   1.1     pooka iwm_phy_db_send_all_channel_groups(struct iwm_softc *sc,
   2153   1.1     pooka 	enum iwm_phy_db_section_type type, uint8_t max_ch_groups)
   2154   1.1     pooka {
   2155   1.1     pooka 	uint16_t i;
   2156   1.1     pooka 	int err;
   2157   1.1     pooka 	struct iwm_phy_db_entry *entry;
   2158   1.1     pooka 
   2159   1.1     pooka 	/* Send all the channel-specific groups to operational fw */
   2160   1.1     pooka 	for (i = 0; i < max_ch_groups; i++) {
   2161   1.1     pooka 		entry = iwm_phy_db_get_section(sc, type, i);
   2162   1.1     pooka 		if (!entry)
   2163   1.1     pooka 			return EINVAL;
   2164   1.1     pooka 
   2165   1.1     pooka 		if (!entry->size)
   2166   1.1     pooka 			continue;
   2167   1.1     pooka 
   2168   1.1     pooka 		/* Send the requested PHY DB section */
   2169   1.1     pooka 		err = iwm_send_phy_db_cmd(sc, type, entry->size, entry->data);
   2170   1.1     pooka 		if (err) {
   2171   1.2    nonaka 			DPRINTF(("%s: Can't SEND phy_db section %d (%d), "
   2172   1.2    nonaka 			    "err %d\n", DEVNAME(sc), type, i, err));
   2173   1.1     pooka 			return err;
   2174   1.1     pooka 		}
   2175   1.1     pooka 
   2176   1.1     pooka 		DPRINTFN(10, ("Sent PHY_DB HCMD, type = %d num = %d\n", type, i));
   2177   1.1     pooka 	}
   2178   1.1     pooka 
   2179   1.1     pooka 	return 0;
   2180   1.1     pooka }
   2181   1.1     pooka 
   2182   1.4    nonaka static int
   2183   1.1     pooka iwm_send_phy_db_data(struct iwm_softc *sc)
   2184   1.1     pooka {
   2185   1.1     pooka 	uint8_t *data = NULL;
   2186   1.1     pooka 	uint16_t size = 0;
   2187   1.1     pooka 	int err;
   2188   1.1     pooka 
   2189   1.1     pooka 	DPRINTF(("Sending phy db data and configuration to runtime image\n"));
   2190   1.1     pooka 
   2191   1.1     pooka 	/* Send PHY DB CFG section */
   2192   1.1     pooka 	err = iwm_phy_db_get_section_data(sc, IWM_PHY_DB_CFG, &data, &size, 0);
   2193   1.1     pooka 	if (err) {
   2194   1.2    nonaka 		DPRINTF(("%s: Cannot get Phy DB cfg section, %d\n",
   2195   1.2    nonaka 		    DEVNAME(sc), err));
   2196   1.1     pooka 		return err;
   2197   1.1     pooka 	}
   2198   1.1     pooka 
   2199   1.1     pooka 	err = iwm_send_phy_db_cmd(sc, IWM_PHY_DB_CFG, size, data);
   2200   1.1     pooka 	if (err) {
   2201   1.2    nonaka 		DPRINTF(("%s: Cannot send HCMD of Phy DB cfg section, %d\n",
   2202   1.2    nonaka 		    DEVNAME(sc), err));
   2203   1.1     pooka 		return err;
   2204   1.1     pooka 	}
   2205   1.1     pooka 
   2206   1.1     pooka 	err = iwm_phy_db_get_section_data(sc, IWM_PHY_DB_CALIB_NCH,
   2207   1.1     pooka 	    &data, &size, 0);
   2208   1.1     pooka 	if (err) {
   2209   1.2    nonaka 		DPRINTF(("%s: Cannot get Phy DB non specific channel section, "
   2210   1.2    nonaka 		    "%d\n", DEVNAME(sc), err));
   2211   1.1     pooka 		return err;
   2212   1.1     pooka 	}
   2213   1.1     pooka 
   2214   1.1     pooka 	err = iwm_send_phy_db_cmd(sc, IWM_PHY_DB_CALIB_NCH, size, data);
   2215   1.1     pooka 	if (err) {
   2216   1.2    nonaka 		DPRINTF(("%s: Cannot send HCMD of Phy DB non specific channel "
   2217   1.2    nonaka 		    "sect, %d\n", DEVNAME(sc), err));
   2218   1.1     pooka 		return err;
   2219   1.1     pooka 	}
   2220   1.1     pooka 
   2221   1.1     pooka 	/* Send all the TXP channel specific data */
   2222   1.1     pooka 	err = iwm_phy_db_send_all_channel_groups(sc,
   2223   1.1     pooka 	    IWM_PHY_DB_CALIB_CHG_PAPD, IWM_NUM_PAPD_CH_GROUPS);
   2224   1.1     pooka 	if (err) {
   2225   1.2    nonaka 		DPRINTF(("%s: Cannot send channel specific PAPD groups, %d\n",
   2226   1.2    nonaka 		    DEVNAME(sc), err));
   2227   1.1     pooka 		return err;
   2228   1.1     pooka 	}
   2229   1.1     pooka 
   2230   1.1     pooka 	/* Send all the TXP channel specific data */
   2231   1.1     pooka 	err = iwm_phy_db_send_all_channel_groups(sc,
   2232   1.1     pooka 	    IWM_PHY_DB_CALIB_CHG_TXP, IWM_NUM_TXP_CH_GROUPS);
   2233   1.1     pooka 	if (err) {
   2234   1.2    nonaka 		DPRINTF(("%s: Cannot send channel specific TX power groups, "
   2235   1.2    nonaka 		    "%d\n", DEVNAME(sc), err));
   2236   1.1     pooka 		return err;
   2237   1.1     pooka 	}
   2238   1.1     pooka 
   2239   1.1     pooka 	DPRINTF(("Finished sending phy db non channel data\n"));
   2240   1.1     pooka 	return 0;
   2241   1.1     pooka }
   2242   1.1     pooka 
   2243   1.1     pooka /*
   2244   1.1     pooka  * END iwl-phy-db.c
   2245   1.1     pooka  */
   2246   1.1     pooka 
   2247   1.1     pooka /*
   2248   1.1     pooka  * BEGIN iwlwifi/mvm/time-event.c
   2249   1.1     pooka  */
   2250   1.1     pooka 
   2251   1.1     pooka /*
   2252   1.1     pooka  * For the high priority TE use a time event type that has similar priority to
   2253   1.1     pooka  * the FW's action scan priority.
   2254   1.1     pooka  */
   2255   1.1     pooka #define IWM_MVM_ROC_TE_TYPE_NORMAL IWM_TE_P2P_DEVICE_DISCOVERABLE
   2256   1.1     pooka #define IWM_MVM_ROC_TE_TYPE_MGMT_TX IWM_TE_P2P_CLIENT_ASSOC
   2257   1.1     pooka 
   2258   1.1     pooka /* used to convert from time event API v2 to v1 */
   2259   1.1     pooka #define IWM_TE_V2_DEP_POLICY_MSK (IWM_TE_V2_DEP_OTHER | IWM_TE_V2_DEP_TSF |\
   2260   1.1     pooka 			     IWM_TE_V2_EVENT_SOCIOPATHIC)
   2261   1.1     pooka static inline uint16_t
   2262   1.1     pooka iwm_te_v2_get_notify(uint16_t policy)
   2263   1.1     pooka {
   2264   1.1     pooka 	return le16toh(policy) & IWM_TE_V2_NOTIF_MSK;
   2265   1.1     pooka }
   2266   1.1     pooka 
   2267   1.1     pooka static inline uint16_t
   2268   1.1     pooka iwm_te_v2_get_dep_policy(uint16_t policy)
   2269   1.1     pooka {
   2270   1.1     pooka 	return (le16toh(policy) & IWM_TE_V2_DEP_POLICY_MSK) >>
   2271   1.1     pooka 		IWM_TE_V2_PLACEMENT_POS;
   2272   1.1     pooka }
   2273   1.1     pooka 
   2274   1.1     pooka static inline uint16_t
   2275   1.1     pooka iwm_te_v2_get_absence(uint16_t policy)
   2276   1.1     pooka {
   2277   1.1     pooka 	return (le16toh(policy) & IWM_TE_V2_ABSENCE) >> IWM_TE_V2_ABSENCE_POS;
   2278   1.1     pooka }
   2279   1.1     pooka 
   2280   1.4    nonaka static void
   2281   1.1     pooka iwm_mvm_te_v2_to_v1(const struct iwm_time_event_cmd_v2 *cmd_v2,
   2282   1.1     pooka 	struct iwm_time_event_cmd_v1 *cmd_v1)
   2283   1.1     pooka {
   2284   1.1     pooka 	cmd_v1->id_and_color = cmd_v2->id_and_color;
   2285   1.1     pooka 	cmd_v1->action = cmd_v2->action;
   2286   1.1     pooka 	cmd_v1->id = cmd_v2->id;
   2287   1.1     pooka 	cmd_v1->apply_time = cmd_v2->apply_time;
   2288   1.1     pooka 	cmd_v1->max_delay = cmd_v2->max_delay;
   2289   1.1     pooka 	cmd_v1->depends_on = cmd_v2->depends_on;
   2290   1.1     pooka 	cmd_v1->interval = cmd_v2->interval;
   2291   1.1     pooka 	cmd_v1->duration = cmd_v2->duration;
   2292   1.1     pooka 	if (cmd_v2->repeat == IWM_TE_V2_REPEAT_ENDLESS)
   2293   1.1     pooka 		cmd_v1->repeat = htole32(IWM_TE_V1_REPEAT_ENDLESS);
   2294   1.1     pooka 	else
   2295   1.1     pooka 		cmd_v1->repeat = htole32(cmd_v2->repeat);
   2296   1.1     pooka 	cmd_v1->max_frags = htole32(cmd_v2->max_frags);
   2297   1.1     pooka 	cmd_v1->interval_reciprocal = 0; /* unused */
   2298   1.1     pooka 
   2299   1.1     pooka 	cmd_v1->dep_policy = htole32(iwm_te_v2_get_dep_policy(cmd_v2->policy));
   2300   1.1     pooka 	cmd_v1->is_present = htole32(!iwm_te_v2_get_absence(cmd_v2->policy));
   2301   1.1     pooka 	cmd_v1->notify = htole32(iwm_te_v2_get_notify(cmd_v2->policy));
   2302   1.1     pooka }
   2303   1.1     pooka 
   2304   1.4    nonaka static int
   2305   1.1     pooka iwm_mvm_send_time_event_cmd(struct iwm_softc *sc,
   2306   1.1     pooka 	const struct iwm_time_event_cmd_v2 *cmd)
   2307   1.1     pooka {
   2308   1.1     pooka 	struct iwm_time_event_cmd_v1 cmd_v1;
   2309   1.1     pooka 
   2310   1.1     pooka 	if (sc->sc_capaflags & IWM_UCODE_TLV_FLAGS_TIME_EVENT_API_V2)
   2311   1.1     pooka 		return iwm_mvm_send_cmd_pdu(sc, IWM_TIME_EVENT_CMD,
   2312   1.1     pooka 		    IWM_CMD_SYNC, sizeof(*cmd), cmd);
   2313   1.1     pooka 
   2314   1.1     pooka 	iwm_mvm_te_v2_to_v1(cmd, &cmd_v1);
   2315   1.1     pooka 	return iwm_mvm_send_cmd_pdu(sc, IWM_TIME_EVENT_CMD, IWM_CMD_SYNC,
   2316   1.1     pooka 	    sizeof(cmd_v1), &cmd_v1);
   2317   1.1     pooka }
   2318   1.1     pooka 
   2319   1.4    nonaka static int
   2320   1.1     pooka iwm_mvm_time_event_send_add(struct iwm_softc *sc, struct iwm_node *in,
   2321   1.1     pooka 	void *te_data, struct iwm_time_event_cmd_v2 *te_cmd)
   2322   1.1     pooka {
   2323   1.1     pooka 	int ret;
   2324   1.1     pooka 
   2325   1.1     pooka 	DPRINTF(("Add new TE, duration %d TU\n", le32toh(te_cmd->duration)));
   2326   1.1     pooka 
   2327   1.1     pooka 	ret = iwm_mvm_send_time_event_cmd(sc, te_cmd);
   2328   1.1     pooka 	if (ret) {
   2329   1.2    nonaka 		DPRINTF(("%s: Couldn't send IWM_TIME_EVENT_CMD: %d\n",
   2330   1.2    nonaka 		    DEVNAME(sc), ret));
   2331   1.1     pooka 	}
   2332   1.1     pooka 
   2333   1.1     pooka 	return ret;
   2334   1.1     pooka }
   2335   1.1     pooka 
   2336   1.4    nonaka static void
   2337   1.1     pooka iwm_mvm_protect_session(struct iwm_softc *sc, struct iwm_node *in,
   2338   1.1     pooka 	uint32_t duration, uint32_t min_duration, uint32_t max_delay)
   2339   1.1     pooka {
   2340   1.1     pooka 	struct iwm_time_event_cmd_v2 time_cmd;
   2341   1.1     pooka 
   2342   1.1     pooka 	memset(&time_cmd, 0, sizeof(time_cmd));
   2343   1.1     pooka 
   2344   1.1     pooka 	time_cmd.action = htole32(IWM_FW_CTXT_ACTION_ADD);
   2345   1.1     pooka 	time_cmd.id_and_color =
   2346   1.1     pooka 	    htole32(IWM_FW_CMD_ID_AND_COLOR(in->in_id, in->in_color));
   2347   1.1     pooka 	time_cmd.id = htole32(IWM_TE_BSS_STA_AGGRESSIVE_ASSOC);
   2348   1.1     pooka 
   2349   1.1     pooka 	time_cmd.apply_time = htole32(iwm_read_prph(sc,
   2350   1.1     pooka 	    IWM_DEVICE_SYSTEM_TIME_REG));
   2351   1.1     pooka 
   2352   1.1     pooka 	time_cmd.max_frags = IWM_TE_V2_FRAG_NONE;
   2353   1.1     pooka 	time_cmd.max_delay = htole32(max_delay);
   2354   1.1     pooka 	/* TODO: why do we need to interval = bi if it is not periodic? */
   2355   1.1     pooka 	time_cmd.interval = htole32(1);
   2356   1.1     pooka 	time_cmd.duration = htole32(duration);
   2357   1.1     pooka 	time_cmd.repeat = 1;
   2358   1.1     pooka 	time_cmd.policy
   2359   1.1     pooka 	    = htole32(IWM_TE_V2_NOTIF_HOST_EVENT_START |
   2360   1.1     pooka 	        IWM_TE_V2_NOTIF_HOST_EVENT_END);
   2361   1.1     pooka 
   2362   1.1     pooka 	iwm_mvm_time_event_send_add(sc, in, /*te_data*/NULL, &time_cmd);
   2363   1.1     pooka }
   2364   1.1     pooka 
   2365   1.1     pooka /*
   2366   1.1     pooka  * END iwlwifi/mvm/time-event.c
   2367   1.1     pooka  */
   2368   1.1     pooka 
   2369   1.1     pooka /*
   2370   1.1     pooka  * NVM read access and content parsing.  We do not support
   2371   1.1     pooka  * external NVM or writing NVM.
   2372   1.1     pooka  * iwlwifi/mvm/nvm.c
   2373   1.1     pooka  */
   2374   1.1     pooka 
   2375   1.1     pooka /* list of NVM sections we are allowed/need to read */
   2376   1.4    nonaka static const int nvm_to_read[] = {
   2377   1.1     pooka 	IWM_NVM_SECTION_TYPE_HW,
   2378   1.1     pooka 	IWM_NVM_SECTION_TYPE_SW,
   2379   1.1     pooka 	IWM_NVM_SECTION_TYPE_CALIBRATION,
   2380   1.1     pooka 	IWM_NVM_SECTION_TYPE_PRODUCTION,
   2381   1.1     pooka };
   2382   1.1     pooka 
   2383   1.1     pooka /* Default NVM size to read */
   2384   1.1     pooka #define IWM_NVM_DEFAULT_CHUNK_SIZE (2*1024)
   2385   1.1     pooka #define IWM_MAX_NVM_SECTION_SIZE 7000
   2386   1.1     pooka 
   2387   1.1     pooka #define IWM_NVM_WRITE_OPCODE 1
   2388   1.1     pooka #define IWM_NVM_READ_OPCODE 0
   2389   1.1     pooka 
   2390   1.4    nonaka static int
   2391   1.1     pooka iwm_nvm_read_chunk(struct iwm_softc *sc, uint16_t section,
   2392   1.1     pooka 	uint16_t offset, uint16_t length, uint8_t *data, uint16_t *len)
   2393   1.1     pooka {
   2394   1.1     pooka 	offset = 0;
   2395   1.1     pooka 	struct iwm_nvm_access_cmd nvm_access_cmd = {
   2396   1.1     pooka 		.offset = htole16(offset),
   2397   1.1     pooka 		.length = htole16(length),
   2398   1.1     pooka 		.type = htole16(section),
   2399   1.1     pooka 		.op_code = IWM_NVM_READ_OPCODE,
   2400   1.1     pooka 	};
   2401   1.1     pooka 	struct iwm_nvm_access_resp *nvm_resp;
   2402   1.1     pooka 	struct iwm_rx_packet *pkt;
   2403   1.1     pooka 	struct iwm_host_cmd cmd = {
   2404   1.1     pooka 		.id = IWM_NVM_ACCESS_CMD,
   2405   1.1     pooka 		.flags = IWM_CMD_SYNC | IWM_CMD_WANT_SKB |
   2406   1.1     pooka 		    IWM_CMD_SEND_IN_RFKILL,
   2407   1.1     pooka 		.data = { &nvm_access_cmd, },
   2408   1.1     pooka 	};
   2409   1.1     pooka 	int ret, bytes_read, offset_read;
   2410   1.1     pooka 	uint8_t *resp_data;
   2411   1.1     pooka 
   2412   1.1     pooka 	cmd.len[0] = sizeof(struct iwm_nvm_access_cmd);
   2413   1.1     pooka 
   2414   1.1     pooka 	ret = iwm_send_cmd(sc, &cmd);
   2415   1.1     pooka 	if (ret)
   2416   1.1     pooka 		return ret;
   2417   1.1     pooka 
   2418   1.1     pooka 	pkt = cmd.resp_pkt;
   2419   1.1     pooka 	if (pkt->hdr.flags & IWM_CMD_FAILED_MSK) {
   2420   1.2    nonaka 		DPRINTF(("%s: Bad return from IWM_NVM_ACCES_COMMAND (0x%08X)\n",
   2421   1.2    nonaka 		    DEVNAME(sc), pkt->hdr.flags));
   2422   1.1     pooka 		ret = EIO;
   2423   1.1     pooka 		goto exit;
   2424   1.1     pooka 	}
   2425   1.1     pooka 
   2426   1.1     pooka 	/* Extract NVM response */
   2427   1.1     pooka 	nvm_resp = (void *)pkt->data;
   2428   1.1     pooka 
   2429   1.1     pooka 	ret = le16toh(nvm_resp->status);
   2430   1.1     pooka 	bytes_read = le16toh(nvm_resp->length);
   2431   1.1     pooka 	offset_read = le16toh(nvm_resp->offset);
   2432   1.1     pooka 	resp_data = nvm_resp->data;
   2433   1.1     pooka 	if (ret) {
   2434   1.2    nonaka 		DPRINTF(("%s: NVM access command failed with status %d\n",
   2435   1.2    nonaka 		    DEVNAME(sc), ret));
   2436   1.1     pooka 		ret = EINVAL;
   2437   1.1     pooka 		goto exit;
   2438   1.1     pooka 	}
   2439   1.1     pooka 
   2440   1.1     pooka 	if (offset_read != offset) {
   2441   1.2    nonaka 		DPRINTF(("%s: NVM ACCESS response with invalid offset %d\n",
   2442   1.2    nonaka 		    DEVNAME(sc), offset_read));
   2443   1.1     pooka 		ret = EINVAL;
   2444   1.1     pooka 		goto exit;
   2445   1.1     pooka 	}
   2446   1.1     pooka 
   2447   1.1     pooka 	memcpy(data + offset, resp_data, bytes_read);
   2448   1.1     pooka 	*len = bytes_read;
   2449   1.1     pooka 
   2450   1.1     pooka  exit:
   2451   1.1     pooka 	iwm_free_resp(sc, &cmd);
   2452   1.1     pooka 	return ret;
   2453   1.1     pooka }
   2454   1.1     pooka 
   2455   1.1     pooka /*
   2456   1.1     pooka  * Reads an NVM section completely.
   2457   1.1     pooka  * NICs prior to 7000 family doesn't have a real NVM, but just read
   2458   1.1     pooka  * section 0 which is the EEPROM. Because the EEPROM reading is unlimited
   2459   1.1     pooka  * by uCode, we need to manually check in this case that we don't
   2460   1.1     pooka  * overflow and try to read more than the EEPROM size.
   2461   1.1     pooka  * For 7000 family NICs, we supply the maximal size we can read, and
   2462   1.1     pooka  * the uCode fills the response with as much data as we can,
   2463   1.1     pooka  * without overflowing, so no check is needed.
   2464   1.1     pooka  */
   2465   1.4    nonaka static int
   2466   1.1     pooka iwm_nvm_read_section(struct iwm_softc *sc,
   2467   1.1     pooka 	uint16_t section, uint8_t *data, uint16_t *len)
   2468   1.1     pooka {
   2469   1.1     pooka 	uint16_t length, seglen;
   2470   1.1     pooka 	int error;
   2471   1.1     pooka 
   2472   1.1     pooka 	/* Set nvm section read length */
   2473   1.1     pooka 	length = seglen = IWM_NVM_DEFAULT_CHUNK_SIZE;
   2474   1.1     pooka 	*len = 0;
   2475   1.1     pooka 
   2476   1.1     pooka 	/* Read the NVM until exhausted (reading less than requested) */
   2477   1.1     pooka 	while (seglen == length) {
   2478   1.1     pooka 		error = iwm_nvm_read_chunk(sc,
   2479   1.1     pooka 		    section, *len, length, data, &seglen);
   2480   1.1     pooka 		if (error) {
   2481   1.3    nonaka 			aprint_error_dev(sc->sc_dev,
   2482   1.3    nonaka 			    "Cannot read NVM from section %d offset %d, "
   2483   1.3    nonaka 			    "length %d\n", section, *len, length);
   2484   1.1     pooka 			return error;
   2485   1.1     pooka 		}
   2486   1.1     pooka 		*len += seglen;
   2487   1.1     pooka 	}
   2488   1.1     pooka 
   2489   1.1     pooka 	DPRINTFN(4, ("NVM section %d read completed\n", section));
   2490   1.1     pooka 	return 0;
   2491   1.1     pooka }
   2492   1.1     pooka 
   2493   1.1     pooka /*
   2494   1.1     pooka  * BEGIN IWM_NVM_PARSE
   2495   1.1     pooka  */
   2496   1.1     pooka 
   2497   1.1     pooka /* iwlwifi/iwl-nvm-parse.c */
   2498   1.1     pooka 
   2499   1.1     pooka /* NVM offsets (in words) definitions */
   2500   1.1     pooka enum wkp_nvm_offsets {
   2501   1.1     pooka 	/* NVM HW-Section offset (in words) definitions */
   2502   1.1     pooka 	IWM_HW_ADDR = 0x15,
   2503   1.1     pooka 
   2504   1.1     pooka /* NVM SW-Section offset (in words) definitions */
   2505   1.1     pooka 	IWM_NVM_SW_SECTION = 0x1C0,
   2506   1.1     pooka 	IWM_NVM_VERSION = 0,
   2507   1.1     pooka 	IWM_RADIO_CFG = 1,
   2508   1.1     pooka 	IWM_SKU = 2,
   2509   1.1     pooka 	IWM_N_HW_ADDRS = 3,
   2510   1.1     pooka 	IWM_NVM_CHANNELS = 0x1E0 - IWM_NVM_SW_SECTION,
   2511   1.1     pooka 
   2512   1.1     pooka /* NVM calibration section offset (in words) definitions */
   2513   1.1     pooka 	IWM_NVM_CALIB_SECTION = 0x2B8,
   2514   1.1     pooka 	IWM_XTAL_CALIB = 0x316 - IWM_NVM_CALIB_SECTION
   2515   1.1     pooka };
   2516   1.1     pooka 
   2517   1.1     pooka /* SKU Capabilities (actual values from NVM definition) */
   2518   1.1     pooka enum nvm_sku_bits {
   2519   1.1     pooka 	IWM_NVM_SKU_CAP_BAND_24GHZ	= (1 << 0),
   2520   1.1     pooka 	IWM_NVM_SKU_CAP_BAND_52GHZ	= (1 << 1),
   2521   1.1     pooka 	IWM_NVM_SKU_CAP_11N_ENABLE	= (1 << 2),
   2522   1.1     pooka 	IWM_NVM_SKU_CAP_11AC_ENABLE	= (1 << 3),
   2523   1.1     pooka };
   2524   1.1     pooka 
   2525   1.1     pooka /* radio config bits (actual values from NVM definition) */
   2526   1.1     pooka #define IWM_NVM_RF_CFG_DASH_MSK(x)   (x & 0x3)         /* bits 0-1   */
   2527   1.1     pooka #define IWM_NVM_RF_CFG_STEP_MSK(x)   ((x >> 2)  & 0x3) /* bits 2-3   */
   2528   1.1     pooka #define IWM_NVM_RF_CFG_TYPE_MSK(x)   ((x >> 4)  & 0x3) /* bits 4-5   */
   2529   1.1     pooka #define IWM_NVM_RF_CFG_PNUM_MSK(x)   ((x >> 6)  & 0x3) /* bits 6-7   */
   2530   1.1     pooka #define IWM_NVM_RF_CFG_TX_ANT_MSK(x) ((x >> 8)  & 0xF) /* bits 8-11  */
   2531   1.1     pooka #define IWM_NVM_RF_CFG_RX_ANT_MSK(x) ((x >> 12) & 0xF) /* bits 12-15 */
   2532   1.1     pooka 
   2533   1.1     pooka #define DEFAULT_MAX_TX_POWER 16
   2534   1.1     pooka 
   2535   1.1     pooka /**
   2536   1.1     pooka  * enum iwm_nvm_channel_flags - channel flags in NVM
   2537   1.1     pooka  * @IWM_NVM_CHANNEL_VALID: channel is usable for this SKU/geo
   2538   1.1     pooka  * @IWM_NVM_CHANNEL_IBSS: usable as an IBSS channel
   2539   1.1     pooka  * @IWM_NVM_CHANNEL_ACTIVE: active scanning allowed
   2540   1.1     pooka  * @IWM_NVM_CHANNEL_RADAR: radar detection required
   2541   1.1     pooka  * @IWM_NVM_CHANNEL_DFS: dynamic freq selection candidate
   2542   1.1     pooka  * @IWM_NVM_CHANNEL_WIDE: 20 MHz channel okay (?)
   2543   1.1     pooka  * @IWM_NVM_CHANNEL_40MHZ: 40 MHz channel okay (?)
   2544   1.1     pooka  * @IWM_NVM_CHANNEL_80MHZ: 80 MHz channel okay (?)
   2545   1.1     pooka  * @IWM_NVM_CHANNEL_160MHZ: 160 MHz channel okay (?)
   2546   1.1     pooka  */
   2547   1.1     pooka enum iwm_nvm_channel_flags {
   2548   1.1     pooka 	IWM_NVM_CHANNEL_VALID = (1 << 0),
   2549   1.1     pooka 	IWM_NVM_CHANNEL_IBSS = (1 << 1),
   2550   1.1     pooka 	IWM_NVM_CHANNEL_ACTIVE = (1 << 3),
   2551   1.1     pooka 	IWM_NVM_CHANNEL_RADAR = (1 << 4),
   2552   1.1     pooka 	IWM_NVM_CHANNEL_DFS = (1 << 7),
   2553   1.1     pooka 	IWM_NVM_CHANNEL_WIDE = (1 << 8),
   2554   1.1     pooka 	IWM_NVM_CHANNEL_40MHZ = (1 << 9),
   2555   1.1     pooka 	IWM_NVM_CHANNEL_80MHZ = (1 << 10),
   2556   1.1     pooka 	IWM_NVM_CHANNEL_160MHZ = (1 << 11),
   2557   1.1     pooka };
   2558   1.1     pooka 
   2559   1.4    nonaka static void
   2560   1.1     pooka iwm_init_channel_map(struct iwm_softc *sc, const uint16_t * const nvm_ch_flags)
   2561   1.1     pooka {
   2562   1.1     pooka 	struct ieee80211com *ic = &sc->sc_ic;
   2563   1.1     pooka 	struct iwm_nvm_data *data = &sc->sc_nvm;
   2564   1.1     pooka 	int ch_idx;
   2565   1.1     pooka 	struct ieee80211_channel *channel;
   2566   1.1     pooka 	uint16_t ch_flags;
   2567   1.1     pooka 	int is_5ghz;
   2568   1.1     pooka 	int flags, hw_value;
   2569   1.1     pooka 
   2570   1.1     pooka 	for (ch_idx = 0; ch_idx < __arraycount(iwm_nvm_channels); ch_idx++) {
   2571   1.1     pooka 		ch_flags = le16_to_cpup(nvm_ch_flags + ch_idx);
   2572   1.1     pooka 
   2573   1.1     pooka 		if (ch_idx >= IWM_NUM_2GHZ_CHANNELS &&
   2574   1.1     pooka 		    !data->sku_cap_band_52GHz_enable)
   2575   1.1     pooka 			ch_flags &= ~IWM_NVM_CHANNEL_VALID;
   2576   1.1     pooka 
   2577   1.1     pooka 		if (!(ch_flags & IWM_NVM_CHANNEL_VALID)) {
   2578   1.1     pooka 			DPRINTF(("Ch. %d Flags %x [%sGHz] - No traffic\n",
   2579   1.1     pooka 			    iwm_nvm_channels[ch_idx],
   2580   1.1     pooka 			    ch_flags,
   2581   1.1     pooka 			    (ch_idx >= IWM_NUM_2GHZ_CHANNELS) ?
   2582   1.1     pooka 			    "5.2" : "2.4"));
   2583   1.1     pooka 			continue;
   2584   1.1     pooka 		}
   2585   1.1     pooka 
   2586   1.1     pooka 		hw_value = iwm_nvm_channels[ch_idx];
   2587   1.1     pooka 		channel = &ic->ic_channels[hw_value];
   2588   1.1     pooka 
   2589   1.1     pooka 		is_5ghz = ch_idx >= IWM_NUM_2GHZ_CHANNELS;
   2590   1.1     pooka 		if (!is_5ghz) {
   2591   1.1     pooka 			flags = IEEE80211_CHAN_2GHZ;
   2592   1.1     pooka 			channel->ic_flags
   2593   1.1     pooka 			    = IEEE80211_CHAN_CCK
   2594   1.1     pooka 			    | IEEE80211_CHAN_OFDM
   2595   1.1     pooka 			    | IEEE80211_CHAN_DYN
   2596   1.1     pooka 			    | IEEE80211_CHAN_2GHZ;
   2597   1.1     pooka 		} else {
   2598   1.1     pooka 			flags = IEEE80211_CHAN_5GHZ;
   2599   1.1     pooka 			channel->ic_flags =
   2600   1.1     pooka 			    IEEE80211_CHAN_A;
   2601   1.1     pooka 		}
   2602   1.1     pooka 		channel->ic_freq = ieee80211_ieee2mhz(hw_value, flags);
   2603   1.1     pooka 
   2604   1.1     pooka 		if (!(ch_flags & IWM_NVM_CHANNEL_ACTIVE))
   2605   1.1     pooka 			channel->ic_flags |= IEEE80211_CHAN_PASSIVE;
   2606   1.1     pooka 	}
   2607   1.1     pooka }
   2608   1.1     pooka 
   2609   1.4    nonaka static int
   2610   1.1     pooka iwm_parse_nvm_data(struct iwm_softc *sc,
   2611   1.1     pooka 	const uint16_t *nvm_hw, const uint16_t *nvm_sw,
   2612   1.1     pooka 	const uint16_t *nvm_calib, uint8_t tx_chains, uint8_t rx_chains)
   2613   1.1     pooka {
   2614   1.1     pooka 	struct iwm_nvm_data *data = &sc->sc_nvm;
   2615   1.1     pooka 	uint8_t hw_addr[ETHER_ADDR_LEN];
   2616   1.1     pooka 	uint16_t radio_cfg, sku;
   2617   1.1     pooka 
   2618   1.1     pooka 	data->nvm_version = le16_to_cpup(nvm_sw + IWM_NVM_VERSION);
   2619   1.1     pooka 
   2620   1.1     pooka 	radio_cfg = le16_to_cpup(nvm_sw + IWM_RADIO_CFG);
   2621   1.1     pooka 	data->radio_cfg_type = IWM_NVM_RF_CFG_TYPE_MSK(radio_cfg);
   2622   1.1     pooka 	data->radio_cfg_step = IWM_NVM_RF_CFG_STEP_MSK(radio_cfg);
   2623   1.1     pooka 	data->radio_cfg_dash = IWM_NVM_RF_CFG_DASH_MSK(radio_cfg);
   2624   1.1     pooka 	data->radio_cfg_pnum = IWM_NVM_RF_CFG_PNUM_MSK(radio_cfg);
   2625   1.1     pooka 	data->valid_tx_ant = IWM_NVM_RF_CFG_TX_ANT_MSK(radio_cfg);
   2626   1.1     pooka 	data->valid_rx_ant = IWM_NVM_RF_CFG_RX_ANT_MSK(radio_cfg);
   2627   1.1     pooka 
   2628   1.1     pooka 	sku = le16_to_cpup(nvm_sw + IWM_SKU);
   2629   1.1     pooka 	data->sku_cap_band_24GHz_enable = sku & IWM_NVM_SKU_CAP_BAND_24GHZ;
   2630   1.1     pooka 	data->sku_cap_band_52GHz_enable = sku & IWM_NVM_SKU_CAP_BAND_52GHZ;
   2631   1.1     pooka 	data->sku_cap_11n_enable = 0;
   2632   1.1     pooka 
   2633   1.1     pooka 	if (!data->valid_tx_ant || !data->valid_rx_ant) {
   2634   1.5    nonaka 		DPRINTF(("%s: invalid antennas (0x%x, 0x%x)\n", DEVNAME(sc),
   2635   1.5    nonaka 		    data->valid_tx_ant, data->valid_rx_ant));
   2636   1.1     pooka 		return EINVAL;
   2637   1.1     pooka 	}
   2638   1.1     pooka 
   2639   1.1     pooka 	data->n_hw_addrs = le16_to_cpup(nvm_sw + IWM_N_HW_ADDRS);
   2640   1.1     pooka 
   2641   1.1     pooka 	data->xtal_calib[0] = *(nvm_calib + IWM_XTAL_CALIB);
   2642   1.1     pooka 	data->xtal_calib[1] = *(nvm_calib + IWM_XTAL_CALIB + 1);
   2643   1.1     pooka 
   2644   1.1     pooka 	/* The byte order is little endian 16 bit, meaning 214365 */
   2645   1.1     pooka 	memcpy(hw_addr, nvm_hw + IWM_HW_ADDR, ETHER_ADDR_LEN);
   2646   1.1     pooka 	data->hw_addr[0] = hw_addr[1];
   2647   1.1     pooka 	data->hw_addr[1] = hw_addr[0];
   2648   1.1     pooka 	data->hw_addr[2] = hw_addr[3];
   2649   1.1     pooka 	data->hw_addr[3] = hw_addr[2];
   2650   1.1     pooka 	data->hw_addr[4] = hw_addr[5];
   2651   1.1     pooka 	data->hw_addr[5] = hw_addr[4];
   2652   1.1     pooka 
   2653   1.1     pooka 	iwm_init_channel_map(sc, &nvm_sw[IWM_NVM_CHANNELS]);
   2654   1.1     pooka 	data->calib_version = 255;   /* TODO:
   2655   1.1     pooka 					this value will prevent some checks from
   2656   1.1     pooka 					failing, we need to check if this
   2657   1.1     pooka 					field is still needed, and if it does,
   2658   1.1     pooka 					where is it in the NVM */
   2659   1.1     pooka 
   2660   1.1     pooka 	return 0;
   2661   1.1     pooka }
   2662   1.1     pooka 
   2663   1.1     pooka /*
   2664   1.1     pooka  * END NVM PARSE
   2665   1.1     pooka  */
   2666   1.1     pooka 
   2667   1.1     pooka struct iwm_nvm_section {
   2668   1.8    nonaka 	uint16_t length;
   2669   1.8    nonaka 	const uint8_t *data;
   2670   1.1     pooka };
   2671   1.1     pooka 
   2672   1.1     pooka #define IWM_FW_VALID_TX_ANT(sc) \
   2673   1.1     pooka     ((sc->sc_fw_phy_config & IWM_FW_PHY_CFG_TX_CHAIN) \
   2674   1.1     pooka     >> IWM_FW_PHY_CFG_TX_CHAIN_POS)
   2675   1.1     pooka #define IWM_FW_VALID_RX_ANT(sc) \
   2676   1.1     pooka     ((sc->sc_fw_phy_config & IWM_FW_PHY_CFG_RX_CHAIN) \
   2677   1.1     pooka     >> IWM_FW_PHY_CFG_RX_CHAIN_POS)
   2678   1.1     pooka 
   2679   1.1     pooka static int
   2680   1.1     pooka iwm_parse_nvm_sections(struct iwm_softc *sc, struct iwm_nvm_section *sections)
   2681   1.1     pooka {
   2682   1.1     pooka 	const uint16_t *hw, *sw, *calib;
   2683   1.1     pooka 
   2684   1.1     pooka 	/* Checking for required sections */
   2685   1.1     pooka 	if (!sections[IWM_NVM_SECTION_TYPE_SW].data ||
   2686   1.1     pooka 	    !sections[IWM_NVM_SECTION_TYPE_HW].data) {
   2687   1.2    nonaka 		DPRINTF(("%s: Can't parse empty NVM sections\n", DEVNAME(sc)));
   2688   1.1     pooka 		return ENOENT;
   2689   1.1     pooka 	}
   2690   1.1     pooka 
   2691   1.1     pooka 	hw = (const uint16_t *)sections[IWM_NVM_SECTION_TYPE_HW].data;
   2692   1.1     pooka 	sw = (const uint16_t *)sections[IWM_NVM_SECTION_TYPE_SW].data;
   2693   1.1     pooka 	calib = (const uint16_t *)sections[IWM_NVM_SECTION_TYPE_CALIBRATION].data;
   2694   1.1     pooka 	return iwm_parse_nvm_data(sc, hw, sw, calib,
   2695   1.1     pooka 	    IWM_FW_VALID_TX_ANT(sc), IWM_FW_VALID_RX_ANT(sc));
   2696   1.1     pooka }
   2697   1.1     pooka 
   2698   1.4    nonaka static int
   2699   1.1     pooka iwm_nvm_init(struct iwm_softc *sc)
   2700   1.1     pooka {
   2701   1.1     pooka 	struct iwm_nvm_section nvm_sections[IWM_NVM_NUM_OF_SECTIONS];
   2702   1.1     pooka 	int i, section, error;
   2703   1.1     pooka 	uint16_t len;
   2704   1.1     pooka 	uint8_t *nvm_buffer, *temp;
   2705   1.1     pooka 
   2706   1.1     pooka 	/* Read From FW NVM */
   2707   1.1     pooka 	DPRINTF(("Read NVM\n"));
   2708   1.1     pooka 
   2709   1.1     pooka 	/* TODO: find correct NVM max size for a section */
   2710   1.1     pooka 	nvm_buffer = kmem_alloc(IWM_OTP_LOW_IMAGE_SIZE, KM_SLEEP);
   2711   1.1     pooka 	for (i = 0; i < __arraycount(nvm_to_read); i++) {
   2712   1.1     pooka 		section = nvm_to_read[i];
   2713   1.1     pooka 		KASSERT(section <= __arraycount(nvm_sections));
   2714   1.1     pooka 
   2715   1.1     pooka 		error = iwm_nvm_read_section(sc, section, nvm_buffer, &len);
   2716   1.1     pooka 		if (error)
   2717   1.1     pooka 			break;
   2718   1.1     pooka 
   2719   1.1     pooka 		temp = kmem_alloc(len, KM_SLEEP);
   2720   1.1     pooka 		memcpy(temp, nvm_buffer, len);
   2721   1.1     pooka 		nvm_sections[section].data = temp;
   2722   1.1     pooka 		nvm_sections[section].length = len;
   2723   1.1     pooka 	}
   2724   1.1     pooka 	kmem_free(nvm_buffer, IWM_OTP_LOW_IMAGE_SIZE);
   2725   1.1     pooka 	if (error)
   2726   1.1     pooka 		return error;
   2727   1.1     pooka 
   2728   1.1     pooka 	return iwm_parse_nvm_sections(sc, nvm_sections);
   2729   1.1     pooka }
   2730   1.1     pooka 
   2731   1.1     pooka /*
   2732   1.1     pooka  * Firmware loading gunk.  This is kind of a weird hybrid between the
   2733   1.1     pooka  * iwn driver and the Linux iwlwifi driver.
   2734   1.1     pooka  */
   2735   1.1     pooka 
   2736   1.4    nonaka static int
   2737   1.1     pooka iwm_firmware_load_chunk(struct iwm_softc *sc, uint32_t dst_addr,
   2738   1.1     pooka 	const uint8_t *section, uint32_t byte_cnt)
   2739   1.1     pooka {
   2740   1.1     pooka 	struct iwm_dma_info *dma = &sc->fw_dma;
   2741   1.1     pooka 	int error;
   2742   1.1     pooka 
   2743   1.1     pooka 	/* Copy firmware section into pre-allocated DMA-safe memory. */
   2744   1.1     pooka 	memcpy(dma->vaddr, section, byte_cnt);
   2745   1.1     pooka 	bus_dmamap_sync(sc->sc_dmat,
   2746   1.1     pooka 	    dma->map, 0, byte_cnt, BUS_DMASYNC_PREWRITE);
   2747   1.1     pooka 
   2748   1.1     pooka 	if (!iwm_nic_lock(sc))
   2749   1.1     pooka 		return EBUSY;
   2750   1.1     pooka 
   2751   1.1     pooka 	sc->sc_fw_chunk_done = 0;
   2752   1.1     pooka 
   2753   1.1     pooka 	IWM_WRITE(sc, IWM_FH_TCSR_CHNL_TX_CONFIG_REG(IWM_FH_SRVC_CHNL),
   2754   1.1     pooka 	    IWM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE);
   2755   1.1     pooka 	IWM_WRITE(sc, IWM_FH_SRVC_CHNL_SRAM_ADDR_REG(IWM_FH_SRVC_CHNL),
   2756   1.1     pooka 	    dst_addr);
   2757   1.1     pooka 	IWM_WRITE(sc, IWM_FH_TFDIB_CTRL0_REG(IWM_FH_SRVC_CHNL),
   2758   1.1     pooka 	    dma->paddr & IWM_FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK);
   2759   1.1     pooka 	IWM_WRITE(sc, IWM_FH_TFDIB_CTRL1_REG(IWM_FH_SRVC_CHNL),
   2760   1.8    nonaka 	    (iwm_get_dma_hi_addr(dma->paddr)
   2761   1.1     pooka 	      << IWM_FH_MEM_TFDIB_REG1_ADDR_BITSHIFT) | byte_cnt);
   2762   1.1     pooka 	IWM_WRITE(sc, IWM_FH_TCSR_CHNL_TX_BUF_STS_REG(IWM_FH_SRVC_CHNL),
   2763   1.1     pooka 	    1 << IWM_FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_NUM |
   2764   1.1     pooka 	    1 << IWM_FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_IDX |
   2765   1.1     pooka 	    IWM_FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID);
   2766   1.1     pooka 	IWM_WRITE(sc, IWM_FH_TCSR_CHNL_TX_CONFIG_REG(IWM_FH_SRVC_CHNL),
   2767   1.1     pooka 	    IWM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE    |
   2768   1.1     pooka 	    IWM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE |
   2769   1.1     pooka 	    IWM_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD);
   2770   1.8    nonaka 
   2771   1.1     pooka 	iwm_nic_unlock(sc);
   2772   1.1     pooka 
   2773   1.1     pooka 	/* wait 1s for this segment to load */
   2774   1.1     pooka 	while (!sc->sc_fw_chunk_done)
   2775   1.1     pooka 		if ((error = tsleep(&sc->sc_fw, 0, "iwmfw", hz)) != 0)
   2776   1.1     pooka 			break;
   2777   1.1     pooka 
   2778   1.8    nonaka 	return error;
   2779   1.1     pooka }
   2780   1.1     pooka 
   2781   1.4    nonaka static int
   2782   1.1     pooka iwm_load_firmware(struct iwm_softc *sc, enum iwm_ucode_type ucode_type)
   2783   1.1     pooka {
   2784   1.1     pooka 	struct iwm_fw_sects *fws;
   2785   1.1     pooka 	int error, i, w;
   2786   1.1     pooka 	void *data;
   2787   1.1     pooka 	uint32_t dlen;
   2788   1.1     pooka 	uint32_t offset;
   2789   1.1     pooka 
   2790   1.1     pooka 	sc->sc_uc.uc_intr = 0;
   2791   1.1     pooka 
   2792   1.1     pooka 	fws = &sc->sc_fw.fw_sects[ucode_type];
   2793   1.1     pooka 	for (i = 0; i < fws->fw_count; i++) {
   2794   1.1     pooka 		data = fws->fw_sect[i].fws_data;
   2795   1.1     pooka 		dlen = fws->fw_sect[i].fws_len;
   2796   1.1     pooka 		offset = fws->fw_sect[i].fws_devoff;
   2797   1.1     pooka 		DPRINTF(("LOAD FIRMWARE type %d offset %u len %d\n",
   2798   1.1     pooka 		    ucode_type, offset, dlen));
   2799   1.1     pooka 		error = iwm_firmware_load_chunk(sc, offset, data, dlen);
   2800   1.1     pooka 		if (error) {
   2801   1.5    nonaka 			DPRINTF(("iwm_firmware_load_chunk() chunk %u of %u "
   2802   1.5    nonaka 			    "returned error %02d\n", i, fws->fw_count, error));
   2803   1.1     pooka 			return error;
   2804   1.1     pooka 		}
   2805   1.1     pooka 	}
   2806   1.1     pooka 
   2807   1.1     pooka 	/* wait for the firmware to load */
   2808   1.1     pooka 	IWM_WRITE(sc, IWM_CSR_RESET, 0);
   2809   1.1     pooka 
   2810   1.1     pooka 	for (w = 0; !sc->sc_uc.uc_intr && w < 10; w++) {
   2811   1.1     pooka 		error = tsleep(&sc->sc_uc, 0, "iwmuc", hz/10);
   2812   1.1     pooka 	}
   2813   1.1     pooka 
   2814   1.1     pooka 	return error;
   2815   1.1     pooka }
   2816   1.1     pooka 
   2817   1.1     pooka /* iwlwifi: pcie/trans.c */
   2818   1.4    nonaka static int
   2819   1.1     pooka iwm_start_fw(struct iwm_softc *sc, enum iwm_ucode_type ucode_type)
   2820   1.1     pooka {
   2821   1.1     pooka 	int error;
   2822   1.1     pooka 
   2823   1.1     pooka 	IWM_WRITE(sc, IWM_CSR_INT, ~0);
   2824   1.1     pooka 
   2825   1.1     pooka 	if ((error = iwm_nic_init(sc)) != 0) {
   2826   1.3    nonaka 		aprint_error_dev(sc->sc_dev, "Unable to init nic\n");
   2827   1.1     pooka 		return error;
   2828   1.1     pooka 	}
   2829   1.1     pooka 
   2830   1.1     pooka 	/* make sure rfkill handshake bits are cleared */
   2831   1.1     pooka 	IWM_WRITE(sc, IWM_CSR_UCODE_DRV_GP1_CLR, IWM_CSR_UCODE_SW_BIT_RFKILL);
   2832   1.1     pooka 	IWM_WRITE(sc, IWM_CSR_UCODE_DRV_GP1_CLR,
   2833   1.1     pooka 	    IWM_CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
   2834   1.1     pooka 
   2835   1.1     pooka 	/* clear (again), then enable host interrupts */
   2836   1.1     pooka 	IWM_WRITE(sc, IWM_CSR_INT, ~0);
   2837   1.1     pooka 	iwm_enable_interrupts(sc);
   2838   1.1     pooka 
   2839   1.1     pooka 	/* really make sure rfkill handshake bits are cleared */
   2840   1.1     pooka 	/* maybe we should write a few times more?  just to make sure */
   2841   1.1     pooka 	IWM_WRITE(sc, IWM_CSR_UCODE_DRV_GP1_CLR, IWM_CSR_UCODE_SW_BIT_RFKILL);
   2842   1.1     pooka 	IWM_WRITE(sc, IWM_CSR_UCODE_DRV_GP1_CLR, IWM_CSR_UCODE_SW_BIT_RFKILL);
   2843   1.1     pooka 
   2844   1.1     pooka 	/* Load the given image to the HW */
   2845   1.6    nonaka 	error = iwm_load_firmware(sc, ucode_type);
   2846   1.6    nonaka 	if (error) {
   2847   1.6    nonaka 		aprint_error_dev(sc->sc_dev, "failed to load firmware: %d\n",
   2848   1.6    nonaka 		    error);
   2849   1.6    nonaka 	}
   2850   1.6    nonaka 	return error;
   2851   1.1     pooka }
   2852   1.1     pooka 
   2853   1.4    nonaka static int
   2854   1.1     pooka iwm_fw_alive(struct iwm_softc *sc, uint32_t sched_base)
   2855   1.1     pooka {
   2856   1.1     pooka 	return iwm_post_alive(sc);
   2857   1.1     pooka }
   2858   1.1     pooka 
   2859   1.4    nonaka static int
   2860   1.1     pooka iwm_send_tx_ant_cfg(struct iwm_softc *sc, uint8_t valid_tx_ant)
   2861   1.1     pooka {
   2862   1.1     pooka 	struct iwm_tx_ant_cfg_cmd tx_ant_cmd = {
   2863   1.1     pooka 		.valid = htole32(valid_tx_ant),
   2864   1.1     pooka 	};
   2865   1.1     pooka 
   2866   1.1     pooka 	return iwm_mvm_send_cmd_pdu(sc, IWM_TX_ANT_CONFIGURATION_CMD,
   2867   1.1     pooka 	    IWM_CMD_SYNC, sizeof(tx_ant_cmd), &tx_ant_cmd);
   2868   1.1     pooka }
   2869   1.1     pooka 
   2870   1.1     pooka /* iwlwifi: mvm/fw.c */
   2871   1.4    nonaka static int
   2872   1.1     pooka iwm_send_phy_cfg_cmd(struct iwm_softc *sc)
   2873   1.1     pooka {
   2874   1.1     pooka 	struct iwm_phy_cfg_cmd phy_cfg_cmd;
   2875   1.1     pooka 	enum iwm_ucode_type ucode_type = sc->sc_uc_current;
   2876   1.1     pooka 
   2877   1.1     pooka 	/* Set parameters */
   2878   1.1     pooka 	phy_cfg_cmd.phy_cfg = htole32(sc->sc_fw_phy_config);
   2879   1.1     pooka 	phy_cfg_cmd.calib_control.event_trigger =
   2880   1.1     pooka 	    sc->sc_default_calib[ucode_type].event_trigger;
   2881   1.1     pooka 	phy_cfg_cmd.calib_control.flow_trigger =
   2882   1.1     pooka 	    sc->sc_default_calib[ucode_type].flow_trigger;
   2883   1.1     pooka 
   2884   1.1     pooka 	DPRINTFN(10, ("Sending Phy CFG command: 0x%x\n", phy_cfg_cmd.phy_cfg));
   2885   1.1     pooka 	return iwm_mvm_send_cmd_pdu(sc, IWM_PHY_CONFIGURATION_CMD, IWM_CMD_SYNC,
   2886   1.1     pooka 	    sizeof(phy_cfg_cmd), &phy_cfg_cmd);
   2887   1.1     pooka }
   2888   1.1     pooka 
   2889   1.4    nonaka static int
   2890   1.1     pooka iwm_mvm_load_ucode_wait_alive(struct iwm_softc *sc,
   2891   1.1     pooka 	enum iwm_ucode_type ucode_type)
   2892   1.1     pooka {
   2893   1.1     pooka 	enum iwm_ucode_type old_type = sc->sc_uc_current;
   2894   1.1     pooka 	int error;
   2895   1.1     pooka 
   2896   1.1     pooka 	if ((error = iwm_read_firmware(sc)) != 0)
   2897   1.1     pooka 		return error;
   2898   1.1     pooka 
   2899   1.1     pooka 	sc->sc_uc_current = ucode_type;
   2900   1.8    nonaka 	error = iwm_start_fw(sc, ucode_type);
   2901   1.1     pooka 	if (error) {
   2902   1.1     pooka 		sc->sc_uc_current = old_type;
   2903   1.1     pooka 		return error;
   2904   1.1     pooka 	}
   2905   1.1     pooka 
   2906   1.1     pooka 	return iwm_fw_alive(sc, sc->sched_base);
   2907   1.1     pooka }
   2908   1.1     pooka 
   2909   1.1     pooka /*
   2910   1.1     pooka  * mvm misc bits
   2911   1.1     pooka  */
   2912   1.1     pooka 
   2913   1.1     pooka /*
   2914   1.1     pooka  * follows iwlwifi/fw.c
   2915   1.1     pooka  */
   2916   1.4    nonaka static int
   2917   1.1     pooka iwm_run_init_mvm_ucode(struct iwm_softc *sc, int justnvm)
   2918   1.1     pooka {
   2919   1.1     pooka 	int error;
   2920   1.1     pooka 
   2921   1.1     pooka 	/* do not operate with rfkill switch turned on */
   2922   1.1     pooka 	if ((sc->sc_flags & IWM_FLAG_RFKILL) && !justnvm) {
   2923   1.3    nonaka 		aprint_error_dev(sc->sc_dev,
   2924   1.3    nonaka 		    "radio is disabled by hardware switch\n");
   2925   1.1     pooka 		return EPERM;
   2926   1.1     pooka 	}
   2927   1.1     pooka 
   2928   1.1     pooka 	sc->sc_init_complete = 0;
   2929   1.8    nonaka 	if ((error = iwm_mvm_load_ucode_wait_alive(sc,
   2930   1.1     pooka 	    IWM_UCODE_TYPE_INIT)) != 0)
   2931   1.1     pooka 		return error;
   2932   1.1     pooka 
   2933   1.1     pooka 	if (justnvm) {
   2934   1.1     pooka 		if ((error = iwm_nvm_init(sc)) != 0) {
   2935   1.3    nonaka 			aprint_error_dev(sc->sc_dev, "failed to read nvm\n");
   2936   1.1     pooka 			return error;
   2937   1.1     pooka 		}
   2938   1.1     pooka 		memcpy(&sc->sc_ic.ic_myaddr,
   2939   1.1     pooka 		    &sc->sc_nvm.hw_addr, ETHER_ADDR_LEN);
   2940   1.1     pooka 
   2941   1.1     pooka 		sc->sc_scan_cmd_len = sizeof(struct iwm_scan_cmd)
   2942   1.1     pooka 		    + sc->sc_capa_max_probe_len
   2943   1.1     pooka 		    + IWM_MAX_NUM_SCAN_CHANNELS
   2944   1.1     pooka 		    * sizeof(struct iwm_scan_channel);
   2945   1.1     pooka 		sc->sc_scan_cmd = kmem_alloc(sc->sc_scan_cmd_len, KM_SLEEP);
   2946   1.1     pooka 
   2947   1.1     pooka 		return 0;
   2948   1.1     pooka 	}
   2949   1.1     pooka 
   2950   1.1     pooka 	/* Send TX valid antennas before triggering calibrations */
   2951   1.1     pooka 	if ((error = iwm_send_tx_ant_cfg(sc, IWM_FW_VALID_TX_ANT(sc))) != 0)
   2952   1.1     pooka 		return error;
   2953   1.1     pooka 
   2954   1.1     pooka 	/*
   2955   1.1     pooka 	* Send phy configurations command to init uCode
   2956   1.1     pooka 	* to start the 16.0 uCode init image internal calibrations.
   2957   1.1     pooka 	*/
   2958   1.1     pooka 	if ((error = iwm_send_phy_cfg_cmd(sc)) != 0 ) {
   2959   1.2    nonaka 		DPRINTF(("%s: failed to run internal calibration: %d\n",
   2960   1.2    nonaka 		    DEVNAME(sc), error));
   2961   1.1     pooka 		return error;
   2962   1.1     pooka 	}
   2963   1.1     pooka 
   2964   1.1     pooka 	/*
   2965   1.1     pooka 	 * Nothing to do but wait for the init complete notification
   2966   1.1     pooka 	 * from the firmware
   2967   1.1     pooka 	 */
   2968   1.1     pooka 	while (!sc->sc_init_complete)
   2969   1.1     pooka 		if ((error = tsleep(&sc->sc_init_complete,
   2970   1.1     pooka 		    0, "iwminit", 2*hz)) != 0)
   2971   1.1     pooka 			break;
   2972   1.1     pooka 
   2973   1.1     pooka 	return error;
   2974   1.1     pooka }
   2975   1.1     pooka 
   2976   1.1     pooka /*
   2977   1.1     pooka  * receive side
   2978   1.1     pooka  */
   2979   1.1     pooka 
   2980   1.1     pooka /* (re)stock rx ring, called at init-time and at runtime */
   2981   1.4    nonaka static int
   2982   1.1     pooka iwm_rx_addbuf(struct iwm_softc *sc, int size, int idx)
   2983   1.1     pooka {
   2984   1.1     pooka 	struct iwm_rx_ring *ring = &sc->rxq;
   2985   1.1     pooka 	struct iwm_rx_data *data = &ring->data[idx];
   2986   1.1     pooka 	struct mbuf *m;
   2987   1.1     pooka 	int error;
   2988   1.1     pooka 	int fatal = 0;
   2989   1.1     pooka 
   2990   1.1     pooka 	m = m_gethdr(M_DONTWAIT, MT_DATA);
   2991   1.1     pooka 	if (m == NULL)
   2992   1.1     pooka 		return ENOBUFS;
   2993   1.1     pooka 
   2994   1.1     pooka 	if (size <= MCLBYTES) {
   2995   1.1     pooka 		MCLGET(m, M_DONTWAIT);
   2996   1.1     pooka 	} else {
   2997   1.1     pooka 		MEXTMALLOC(m, IWM_RBUF_SIZE, M_DONTWAIT);
   2998   1.1     pooka 	}
   2999   1.1     pooka 	if ((m->m_flags & M_EXT) == 0) {
   3000   1.1     pooka 		m_freem(m);
   3001   1.1     pooka 		return ENOBUFS;
   3002   1.1     pooka 	}
   3003   1.1     pooka 
   3004   1.1     pooka 	if (data->m != NULL) {
   3005   1.1     pooka 		bus_dmamap_unload(sc->sc_dmat, data->map);
   3006   1.1     pooka 		fatal = 1;
   3007   1.1     pooka 	}
   3008   1.1     pooka 
   3009   1.1     pooka 	m->m_len = m->m_pkthdr.len = m->m_ext.ext_size;
   3010   1.1     pooka 	if ((error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m,
   3011   1.1     pooka 	    BUS_DMA_READ|BUS_DMA_NOWAIT)) != 0) {
   3012   1.1     pooka 		/* XXX */
   3013   1.1     pooka 		if (fatal)
   3014   1.1     pooka 			panic("iwm: could not load RX mbuf");
   3015   1.1     pooka 		m_freem(m);
   3016   1.1     pooka 		return error;
   3017   1.1     pooka 	}
   3018   1.1     pooka 	data->m = m;
   3019   1.1     pooka 	bus_dmamap_sync(sc->sc_dmat, data->map, 0, size, BUS_DMASYNC_PREREAD);
   3020   1.1     pooka 
   3021   1.8    nonaka 	/* Update RX descriptor. */
   3022   1.1     pooka 	ring->desc[idx] = htole32(data->map->dm_segs[0].ds_addr >> 8);
   3023   1.1     pooka 	bus_dmamap_sync(sc->sc_dmat, ring->desc_dma.map,
   3024   1.1     pooka 	    idx * sizeof(uint32_t), sizeof(uint32_t), BUS_DMASYNC_PREWRITE);
   3025   1.1     pooka 
   3026   1.1     pooka 	return 0;
   3027   1.1     pooka }
   3028   1.1     pooka 
   3029   1.1     pooka /* iwlwifi: mvm/rx.c */
   3030   1.1     pooka #define IWM_RSSI_OFFSET 50
   3031   1.4    nonaka static int
   3032   1.1     pooka iwm_mvm_calc_rssi(struct iwm_softc *sc, struct iwm_rx_phy_info *phy_info)
   3033   1.1     pooka {
   3034   1.1     pooka 	int rssi_a, rssi_b, rssi_a_dbm, rssi_b_dbm, max_rssi_dbm;
   3035   1.1     pooka 	uint32_t agc_a, agc_b;
   3036   1.1     pooka 	uint32_t val;
   3037   1.1     pooka 
   3038   1.1     pooka 	val = le32toh(phy_info->non_cfg_phy[IWM_RX_INFO_AGC_IDX]);
   3039   1.1     pooka 	agc_a = (val & IWM_OFDM_AGC_A_MSK) >> IWM_OFDM_AGC_A_POS;
   3040   1.1     pooka 	agc_b = (val & IWM_OFDM_AGC_B_MSK) >> IWM_OFDM_AGC_B_POS;
   3041   1.1     pooka 
   3042   1.1     pooka 	val = le32toh(phy_info->non_cfg_phy[IWM_RX_INFO_RSSI_AB_IDX]);
   3043   1.1     pooka 	rssi_a = (val & IWM_OFDM_RSSI_INBAND_A_MSK) >> IWM_OFDM_RSSI_A_POS;
   3044   1.1     pooka 	rssi_b = (val & IWM_OFDM_RSSI_INBAND_B_MSK) >> IWM_OFDM_RSSI_B_POS;
   3045   1.1     pooka 
   3046   1.1     pooka 	/*
   3047   1.1     pooka 	 * dBm = rssi dB - agc dB - constant.
   3048   1.1     pooka 	 * Higher AGC (higher radio gain) means lower signal.
   3049   1.1     pooka 	 */
   3050   1.1     pooka 	rssi_a_dbm = rssi_a - IWM_RSSI_OFFSET - agc_a;
   3051   1.1     pooka 	rssi_b_dbm = rssi_b - IWM_RSSI_OFFSET - agc_b;
   3052   1.1     pooka 	max_rssi_dbm = MAX(rssi_a_dbm, rssi_b_dbm);
   3053   1.1     pooka 
   3054   1.1     pooka 	DPRINTF(("Rssi In A %d B %d Max %d AGCA %d AGCB %d\n",
   3055   1.1     pooka 	    rssi_a_dbm, rssi_b_dbm, max_rssi_dbm, agc_a, agc_b));
   3056   1.1     pooka 
   3057   1.1     pooka 	return max_rssi_dbm;
   3058   1.1     pooka }
   3059   1.1     pooka 
   3060   1.1     pooka /* iwlwifi: mvm/rx.c */
   3061   1.1     pooka /*
   3062   1.1     pooka  * iwm_mvm_get_signal_strength - use new rx PHY INFO API
   3063   1.1     pooka  * values are reported by the fw as positive values - need to negate
   3064   1.1     pooka  * to obtain their dBM.  Account for missing antennas by replacing 0
   3065   1.1     pooka  * values by -256dBm: practically 0 power and a non-feasible 8 bit value.
   3066   1.1     pooka  */
   3067   1.4    nonaka static int
   3068   1.5    nonaka iwm_mvm_get_signal_strength(struct iwm_softc *sc,
   3069   1.5    nonaka     struct iwm_rx_phy_info *phy_info)
   3070   1.1     pooka {
   3071   1.1     pooka 	int energy_a, energy_b, energy_c, max_energy;
   3072   1.1     pooka 	uint32_t val;
   3073   1.1     pooka 
   3074   1.1     pooka 	val = le32toh(phy_info->non_cfg_phy[IWM_RX_INFO_ENERGY_ANT_ABC_IDX]);
   3075   1.1     pooka 	energy_a = (val & IWM_RX_INFO_ENERGY_ANT_A_MSK) >>
   3076   1.1     pooka 	    IWM_RX_INFO_ENERGY_ANT_A_POS;
   3077   1.1     pooka 	energy_a = energy_a ? -energy_a : -256;
   3078   1.1     pooka 	energy_b = (val & IWM_RX_INFO_ENERGY_ANT_B_MSK) >>
   3079   1.1     pooka 	    IWM_RX_INFO_ENERGY_ANT_B_POS;
   3080   1.1     pooka 	energy_b = energy_b ? -energy_b : -256;
   3081   1.1     pooka 	energy_c = (val & IWM_RX_INFO_ENERGY_ANT_C_MSK) >>
   3082   1.1     pooka 	    IWM_RX_INFO_ENERGY_ANT_C_POS;
   3083   1.1     pooka 	energy_c = energy_c ? -energy_c : -256;
   3084   1.1     pooka 	max_energy = MAX(energy_a, energy_b);
   3085   1.1     pooka 	max_energy = MAX(max_energy, energy_c);
   3086   1.1     pooka 
   3087   1.5    nonaka 	DPRINTFN(12, ("energy In A %d B %d C %d, and max %d\n",
   3088   1.1     pooka 	    energy_a, energy_b, energy_c, max_energy));
   3089   1.1     pooka 
   3090   1.1     pooka 	return max_energy;
   3091   1.1     pooka }
   3092   1.1     pooka 
   3093   1.4    nonaka static void
   3094   1.1     pooka iwm_mvm_rx_rx_phy_cmd(struct iwm_softc *sc,
   3095   1.1     pooka 	struct iwm_rx_packet *pkt, struct iwm_rx_data *data)
   3096   1.1     pooka {
   3097   1.1     pooka 	struct iwm_rx_phy_info *phy_info = (void *)pkt->data;
   3098   1.1     pooka 
   3099   1.1     pooka 	DPRINTFN(20, ("received PHY stats\n"));
   3100   1.1     pooka 	bus_dmamap_sync(sc->sc_dmat, data->map, sizeof(*pkt),
   3101   1.1     pooka 	    sizeof(*phy_info), BUS_DMASYNC_POSTREAD);
   3102   1.1     pooka 
   3103   1.1     pooka 	memcpy(&sc->sc_last_phy_info, phy_info, sizeof(sc->sc_last_phy_info));
   3104   1.1     pooka }
   3105   1.1     pooka 
   3106   1.1     pooka /*
   3107   1.1     pooka  * Retrieve the average noise (in dBm) among receivers.
   3108   1.1     pooka  */
   3109   1.4    nonaka static int
   3110   1.1     pooka iwm_get_noise(const struct iwm_mvm_statistics_rx_non_phy *stats)
   3111   1.1     pooka {
   3112   1.1     pooka 	int i, total, nbant, noise;
   3113   1.1     pooka 
   3114   1.1     pooka 	total = nbant = noise = 0;
   3115   1.1     pooka 	for (i = 0; i < 3; i++) {
   3116   1.1     pooka 		noise = le32toh(stats->beacon_silence_rssi[i]) & 0xff;
   3117   1.1     pooka 		if (noise) {
   3118   1.1     pooka 			total += noise;
   3119   1.1     pooka 			nbant++;
   3120   1.1     pooka 		}
   3121   1.1     pooka 	}
   3122   1.1     pooka 
   3123   1.1     pooka 	/* There should be at least one antenna but check anyway. */
   3124   1.1     pooka 	return (nbant == 0) ? -127 : (total / nbant) - 107;
   3125   1.1     pooka }
   3126   1.1     pooka 
   3127   1.1     pooka /*
   3128   1.1     pooka  * iwm_mvm_rx_rx_mpdu - IWM_REPLY_RX_MPDU_CMD handler
   3129   1.1     pooka  *
   3130   1.1     pooka  * Handles the actual data of the Rx packet from the fw
   3131   1.1     pooka  */
   3132   1.4    nonaka static void
   3133   1.1     pooka iwm_mvm_rx_rx_mpdu(struct iwm_softc *sc,
   3134   1.1     pooka 	struct iwm_rx_packet *pkt, struct iwm_rx_data *data)
   3135   1.1     pooka {
   3136   1.1     pooka 	struct ieee80211com *ic = &sc->sc_ic;
   3137   1.1     pooka 	struct ieee80211_frame *wh;
   3138   1.1     pooka 	struct ieee80211_node *ni;
   3139   1.1     pooka 	struct ieee80211_channel *c = NULL;
   3140   1.1     pooka 	struct mbuf *m;
   3141   1.1     pooka 	struct iwm_rx_phy_info *phy_info;
   3142   1.1     pooka 	struct iwm_rx_mpdu_res_start *rx_res;
   3143   1.1     pooka 	int device_timestamp;
   3144   1.1     pooka 	uint32_t len;
   3145   1.1     pooka 	uint32_t rx_pkt_status;
   3146   1.1     pooka 	int rssi;
   3147   1.1     pooka 
   3148   1.1     pooka 	bus_dmamap_sync(sc->sc_dmat, data->map, 0, IWM_RBUF_SIZE,
   3149   1.1     pooka 	    BUS_DMASYNC_POSTREAD);
   3150   1.1     pooka 
   3151   1.1     pooka 	phy_info = &sc->sc_last_phy_info;
   3152   1.1     pooka 	rx_res = (struct iwm_rx_mpdu_res_start *)pkt->data;
   3153   1.1     pooka 	wh = (struct ieee80211_frame *)(pkt->data + sizeof(*rx_res));
   3154   1.1     pooka 	len = le16toh(rx_res->byte_count);
   3155   1.1     pooka 	rx_pkt_status = le32toh(*(uint32_t *)(pkt->data + sizeof(*rx_res) + len));
   3156   1.1     pooka 
   3157   1.1     pooka 	m = data->m;
   3158   1.1     pooka 	m->m_data = pkt->data + sizeof(*rx_res);
   3159   1.1     pooka 	m->m_pkthdr.len = m->m_len = len;
   3160   1.1     pooka 
   3161   1.1     pooka 	if (__predict_false(phy_info->cfg_phy_cnt > 20)) {
   3162   1.1     pooka 		DPRINTF(("dsp size out of range [0,20]: %d\n",
   3163   1.1     pooka 		    phy_info->cfg_phy_cnt));
   3164   1.1     pooka 		return;
   3165   1.1     pooka 	}
   3166   1.1     pooka 
   3167   1.1     pooka 	if (!(rx_pkt_status & IWM_RX_MPDU_RES_STATUS_CRC_OK) ||
   3168   1.1     pooka 	    !(rx_pkt_status & IWM_RX_MPDU_RES_STATUS_OVERRUN_OK)) {
   3169   1.1     pooka 		DPRINTF(("Bad CRC or FIFO: 0x%08X.\n", rx_pkt_status));
   3170   1.1     pooka 		return; /* drop */
   3171   1.1     pooka 	}
   3172   1.1     pooka 
   3173   1.1     pooka 	device_timestamp = le32toh(phy_info->system_timestamp);
   3174   1.1     pooka 
   3175   1.1     pooka 	if (sc->sc_capaflags & IWM_UCODE_TLV_FLAGS_RX_ENERGY_API) {
   3176   1.1     pooka 		rssi = iwm_mvm_get_signal_strength(sc, phy_info);
   3177   1.1     pooka 	} else {
   3178   1.1     pooka 		rssi = iwm_mvm_calc_rssi(sc, phy_info);
   3179   1.1     pooka 	}
   3180   1.1     pooka 	rssi = -rssi;
   3181   1.1     pooka 
   3182   1.1     pooka 	if (ic->ic_state == IEEE80211_S_SCAN)
   3183   1.1     pooka 		iwm_fix_channel(ic, m);
   3184   1.1     pooka 
   3185   1.1     pooka 	/* replenish ring for the buffer we're going to feed to the sharks */
   3186   1.1     pooka 	if (iwm_rx_addbuf(sc, IWM_RBUF_SIZE, sc->rxq.cur) != 0)
   3187   1.1     pooka 		return;
   3188   1.1     pooka 
   3189   1.1     pooka 	m->m_pkthdr.rcvif = IC2IFP(ic);
   3190   1.1     pooka 
   3191   1.1     pooka 	if (sc->sc_scanband == IEEE80211_CHAN_5GHZ) {
   3192   1.1     pooka 		if (le32toh(phy_info->channel) < __arraycount(ic->ic_channels))
   3193   1.1     pooka 			c = &ic->ic_channels[le32toh(phy_info->channel)];
   3194   1.1     pooka 	}
   3195   1.1     pooka 
   3196   1.1     pooka 	ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh);
   3197   1.1     pooka 	if (c)
   3198   1.1     pooka 		ni->ni_chan = c;
   3199   1.1     pooka 
   3200   1.1     pooka 	if (sc->sc_drvbpf != NULL) {
   3201   1.1     pooka 		struct iwm_rx_radiotap_header *tap = &sc->sc_rxtap;
   3202   1.1     pooka 
   3203   1.1     pooka 		tap->wr_flags = 0;
   3204   1.1     pooka 		if (phy_info->phy_flags & htole16(IWM_PHY_INFO_FLAG_SHPREAMBLE))
   3205   1.1     pooka 			tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
   3206   1.1     pooka 		tap->wr_chan_freq =
   3207   1.1     pooka 		    htole16(ic->ic_channels[phy_info->channel].ic_freq);
   3208   1.1     pooka 		tap->wr_chan_flags =
   3209   1.1     pooka 		    htole16(ic->ic_channels[phy_info->channel].ic_flags);
   3210   1.1     pooka 		tap->wr_dbm_antsignal = (int8_t)rssi;
   3211   1.1     pooka 		tap->wr_dbm_antnoise = (int8_t)sc->sc_noise;
   3212   1.1     pooka 		tap->wr_tsft = phy_info->system_timestamp;
   3213   1.1     pooka 		switch (phy_info->rate) {
   3214   1.1     pooka 		/* CCK rates. */
   3215   1.1     pooka 		case  10: tap->wr_rate =   2; break;
   3216   1.1     pooka 		case  20: tap->wr_rate =   4; break;
   3217   1.1     pooka 		case  55: tap->wr_rate =  11; break;
   3218   1.1     pooka 		case 110: tap->wr_rate =  22; break;
   3219   1.1     pooka 		/* OFDM rates. */
   3220   1.1     pooka 		case 0xd: tap->wr_rate =  12; break;
   3221   1.1     pooka 		case 0xf: tap->wr_rate =  18; break;
   3222   1.1     pooka 		case 0x5: tap->wr_rate =  24; break;
   3223   1.1     pooka 		case 0x7: tap->wr_rate =  36; break;
   3224   1.1     pooka 		case 0x9: tap->wr_rate =  48; break;
   3225   1.1     pooka 		case 0xb: tap->wr_rate =  72; break;
   3226   1.1     pooka 		case 0x1: tap->wr_rate =  96; break;
   3227   1.1     pooka 		case 0x3: tap->wr_rate = 108; break;
   3228   1.1     pooka 		/* Unknown rate: should not happen. */
   3229   1.1     pooka 		default:  tap->wr_rate =   0;
   3230   1.1     pooka 		}
   3231   1.1     pooka 
   3232   1.1     pooka 		bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_rxtap_len, m);
   3233   1.1     pooka 	}
   3234   1.1     pooka 	ieee80211_input(ic, m, ni, rssi, device_timestamp);
   3235   1.1     pooka 	ieee80211_free_node(ni);
   3236   1.1     pooka }
   3237   1.1     pooka 
   3238   1.4    nonaka static void
   3239   1.1     pooka iwm_mvm_rx_tx_cmd_single(struct iwm_softc *sc, struct iwm_rx_packet *pkt,
   3240   1.1     pooka 	struct iwm_node *in)
   3241   1.1     pooka {
   3242   1.1     pooka 	struct ieee80211com *ic = &sc->sc_ic;
   3243   1.1     pooka 	struct ifnet *ifp = IC2IFP(ic);
   3244   1.1     pooka 	struct iwm_mvm_tx_resp *tx_resp = (void *)pkt->data;
   3245   1.1     pooka 	int status = le16toh(tx_resp->status.status) & IWM_TX_STATUS_MSK;
   3246   1.1     pooka 	int failack = tx_resp->failure_frame;
   3247   1.1     pooka 
   3248   1.1     pooka 	KASSERT(tx_resp->frame_count == 1);
   3249   1.1     pooka 
   3250   1.1     pooka 	/* Update rate control statistics. */
   3251   1.1     pooka 	in->in_amn.amn_txcnt++;
   3252   1.1     pooka 	if (failack > 0) {
   3253   1.1     pooka 		in->in_amn.amn_retrycnt++;
   3254   1.1     pooka 	}
   3255   1.1     pooka 
   3256   1.1     pooka 	if (status != IWM_TX_STATUS_SUCCESS &&
   3257   1.1     pooka 	    status != IWM_TX_STATUS_DIRECT_DONE)
   3258   1.1     pooka 		ifp->if_oerrors++;
   3259   1.1     pooka 	else
   3260   1.1     pooka 		ifp->if_opackets++;
   3261   1.1     pooka }
   3262   1.1     pooka 
   3263   1.4    nonaka static void
   3264   1.8    nonaka iwm_mvm_rx_tx_cmd(struct iwm_softc *sc,
   3265   1.1     pooka 	struct iwm_rx_packet *pkt, struct iwm_rx_data *data)
   3266   1.1     pooka {
   3267   1.1     pooka 	struct ieee80211com *ic = &sc->sc_ic;
   3268   1.1     pooka 	struct ifnet *ifp = IC2IFP(ic);
   3269   1.1     pooka 	struct iwm_cmd_header *cmd_hdr = &pkt->hdr;
   3270   1.1     pooka 	int idx = cmd_hdr->idx;
   3271   1.1     pooka 	int qid = cmd_hdr->qid;
   3272   1.1     pooka 	struct iwm_tx_ring *ring = &sc->txq[qid];
   3273   1.1     pooka 	struct iwm_tx_data *txd = &ring->data[idx];
   3274   1.1     pooka 	struct iwm_node *in = txd->in;
   3275   1.1     pooka 
   3276   1.1     pooka 	if (txd->done) {
   3277   1.2    nonaka 		DPRINTF(("%s: got tx interrupt that's already been handled!\n",
   3278   1.2    nonaka 		    DEVNAME(sc)));
   3279   1.1     pooka 		return;
   3280   1.1     pooka 	}
   3281   1.1     pooka 
   3282   1.1     pooka 	bus_dmamap_sync(sc->sc_dmat, data->map, 0, IWM_RBUF_SIZE,
   3283   1.1     pooka 	    BUS_DMASYNC_POSTREAD);
   3284   1.1     pooka 
   3285   1.1     pooka 	sc->sc_tx_timer = 0;
   3286   1.1     pooka 
   3287   1.1     pooka 	iwm_mvm_rx_tx_cmd_single(sc, pkt, in);
   3288   1.1     pooka 
   3289   1.1     pooka 	/* Unmap and free mbuf. */
   3290   1.1     pooka 	bus_dmamap_sync(sc->sc_dmat, txd->map, 0, txd->map->dm_mapsize,
   3291   1.1     pooka 	    BUS_DMASYNC_POSTWRITE);
   3292   1.1     pooka 	bus_dmamap_unload(sc->sc_dmat, txd->map);
   3293   1.1     pooka 	m_freem(txd->m);
   3294   1.1     pooka 
   3295   1.1     pooka 	DPRINTFN(8, ("free txd %p, in %p\n", txd, txd->in));
   3296   1.1     pooka 	KASSERT(txd->done == 0);
   3297   1.1     pooka 	txd->done = 1;
   3298   1.1     pooka 	KASSERT(txd->in);
   3299   1.1     pooka 
   3300   1.1     pooka 	txd->m = NULL;
   3301   1.1     pooka 	txd->in = NULL;
   3302   1.1     pooka 	ieee80211_free_node(&in->in_ni);
   3303   1.1     pooka 
   3304   1.1     pooka 	if (--ring->queued < IWM_TX_RING_LOMARK) {
   3305   1.1     pooka 		sc->qfullmsk &= ~(1 << ring->qid);
   3306   1.1     pooka 		if (sc->qfullmsk == 0 && (ifp->if_flags & IFF_OACTIVE)) {
   3307   1.1     pooka 			ifp->if_flags &= ~IFF_OACTIVE;
   3308   1.1     pooka 			/*
   3309   1.1     pooka 			 * Well, we're in interrupt context, but then again
   3310   1.1     pooka 			 * I guess net80211 does all sorts of stunts in
   3311   1.1     pooka 			 * interrupt context, so maybe this is no biggie.
   3312   1.1     pooka 			 */
   3313   1.1     pooka 			(*ifp->if_start)(ifp);
   3314   1.1     pooka 		}
   3315   1.1     pooka 	}
   3316   1.1     pooka }
   3317   1.1     pooka 
   3318   1.1     pooka /*
   3319   1.1     pooka  * BEGIN iwlwifi/mvm/binding.c
   3320   1.1     pooka  */
   3321   1.1     pooka 
   3322   1.4    nonaka static int
   3323   1.1     pooka iwm_mvm_binding_cmd(struct iwm_softc *sc, struct iwm_node *in, uint32_t action)
   3324   1.1     pooka {
   3325   1.1     pooka 	struct iwm_binding_cmd cmd;
   3326   1.1     pooka 	struct iwm_mvm_phy_ctxt *phyctxt = in->in_phyctxt;
   3327   1.1     pooka 	int i, ret;
   3328   1.1     pooka 	uint32_t status;
   3329   1.1     pooka 
   3330   1.1     pooka 	memset(&cmd, 0, sizeof(cmd));
   3331   1.1     pooka 
   3332   1.1     pooka 	cmd.id_and_color
   3333   1.1     pooka 	    = htole32(IWM_FW_CMD_ID_AND_COLOR(phyctxt->id, phyctxt->color));
   3334   1.1     pooka 	cmd.action = htole32(action);
   3335   1.1     pooka 	cmd.phy = htole32(IWM_FW_CMD_ID_AND_COLOR(phyctxt->id, phyctxt->color));
   3336   1.1     pooka 
   3337   1.1     pooka 	cmd.macs[0] = htole32(IWM_FW_CMD_ID_AND_COLOR(in->in_id, in->in_color));
   3338   1.1     pooka 	for (i = 1; i < IWM_MAX_MACS_IN_BINDING; i++)
   3339   1.1     pooka 		cmd.macs[i] = htole32(IWM_FW_CTXT_INVALID);
   3340   1.1     pooka 
   3341   1.1     pooka 	status = 0;
   3342   1.1     pooka 	ret = iwm_mvm_send_cmd_pdu_status(sc, IWM_BINDING_CONTEXT_CMD,
   3343   1.1     pooka 	    sizeof(cmd), &cmd, &status);
   3344   1.1     pooka 	if (ret) {
   3345   1.2    nonaka 		DPRINTF(("%s: Failed to send binding (action:%d): %d\n",
   3346   1.2    nonaka 		    DEVNAME(sc), action, ret));
   3347   1.1     pooka 		return ret;
   3348   1.1     pooka 	}
   3349   1.1     pooka 
   3350   1.1     pooka 	if (status) {
   3351   1.2    nonaka 		DPRINTF(("%s: Binding command failed: %u\n", DEVNAME(sc),
   3352   1.2    nonaka 		    status));
   3353   1.1     pooka 		ret = EIO;
   3354   1.1     pooka 	}
   3355   1.1     pooka 
   3356   1.1     pooka 	return ret;
   3357   1.1     pooka }
   3358   1.1     pooka 
   3359   1.4    nonaka static int
   3360   1.1     pooka iwm_mvm_binding_update(struct iwm_softc *sc, struct iwm_node *in, int add)
   3361   1.1     pooka {
   3362   1.1     pooka 	return iwm_mvm_binding_cmd(sc, in, IWM_FW_CTXT_ACTION_ADD);
   3363   1.1     pooka }
   3364   1.1     pooka 
   3365   1.4    nonaka static int
   3366   1.1     pooka iwm_mvm_binding_add_vif(struct iwm_softc *sc, struct iwm_node *in)
   3367   1.1     pooka {
   3368   1.1     pooka 	return iwm_mvm_binding_update(sc, in, IWM_FW_CTXT_ACTION_ADD);
   3369   1.1     pooka }
   3370   1.1     pooka 
   3371   1.1     pooka /*
   3372   1.1     pooka  * END iwlwifi/mvm/binding.c
   3373   1.1     pooka  */
   3374   1.1     pooka 
   3375   1.1     pooka /*
   3376   1.1     pooka  * BEGIN iwlwifi/mvm/phy-ctxt.c
   3377   1.1     pooka  */
   3378   1.1     pooka 
   3379   1.1     pooka /*
   3380   1.1     pooka  * Construct the generic fields of the PHY context command
   3381   1.1     pooka  */
   3382   1.4    nonaka static void
   3383   1.1     pooka iwm_mvm_phy_ctxt_cmd_hdr(struct iwm_softc *sc, struct iwm_mvm_phy_ctxt *ctxt,
   3384   1.1     pooka 	struct iwm_phy_context_cmd *cmd, uint32_t action, uint32_t apply_time)
   3385   1.1     pooka {
   3386   1.1     pooka 	memset(cmd, 0, sizeof(struct iwm_phy_context_cmd));
   3387   1.1     pooka 
   3388   1.1     pooka 	cmd->id_and_color = htole32(IWM_FW_CMD_ID_AND_COLOR(ctxt->id,
   3389   1.1     pooka 	    ctxt->color));
   3390   1.1     pooka 	cmd->action = htole32(action);
   3391   1.1     pooka 	cmd->apply_time = htole32(apply_time);
   3392   1.1     pooka }
   3393   1.1     pooka 
   3394   1.1     pooka /*
   3395   1.1     pooka  * Add the phy configuration to the PHY context command
   3396   1.1     pooka  */
   3397   1.4    nonaka static void
   3398   1.1     pooka iwm_mvm_phy_ctxt_cmd_data(struct iwm_softc *sc,
   3399   1.1     pooka 	struct iwm_phy_context_cmd *cmd, struct ieee80211_channel *chan,
   3400   1.1     pooka 	uint8_t chains_static, uint8_t chains_dynamic)
   3401   1.1     pooka {
   3402   1.1     pooka 	struct ieee80211com *ic = &sc->sc_ic;
   3403   1.1     pooka 	uint8_t active_cnt, idle_cnt;
   3404   1.1     pooka 
   3405   1.1     pooka 	cmd->ci.band = IEEE80211_IS_CHAN_2GHZ(chan) ?
   3406   1.1     pooka 	    IWM_PHY_BAND_24 : IWM_PHY_BAND_5;
   3407   1.1     pooka 
   3408   1.1     pooka 	cmd->ci.channel = ieee80211_chan2ieee(ic, chan);
   3409   1.1     pooka 	cmd->ci.width = IWM_PHY_VHT_CHANNEL_MODE20;
   3410   1.1     pooka 	cmd->ci.ctrl_pos = IWM_PHY_VHT_CTRL_POS_1_BELOW;
   3411   1.1     pooka 
   3412   1.1     pooka 	/* Set rx the chains */
   3413   1.1     pooka 	idle_cnt = chains_static;
   3414   1.1     pooka 	active_cnt = chains_dynamic;
   3415   1.1     pooka 
   3416   1.1     pooka 	cmd->rxchain_info = htole32(IWM_FW_VALID_RX_ANT(sc) <<
   3417   1.1     pooka 					IWM_PHY_RX_CHAIN_VALID_POS);
   3418   1.1     pooka 	cmd->rxchain_info |= htole32(idle_cnt << IWM_PHY_RX_CHAIN_CNT_POS);
   3419   1.1     pooka 	cmd->rxchain_info |= htole32(active_cnt <<
   3420   1.1     pooka 	    IWM_PHY_RX_CHAIN_MIMO_CNT_POS);
   3421   1.1     pooka 
   3422   1.1     pooka 	cmd->txchain_info = htole32(IWM_FW_VALID_TX_ANT(sc));
   3423   1.1     pooka }
   3424   1.1     pooka 
   3425   1.1     pooka /*
   3426   1.1     pooka  * Send a command
   3427   1.1     pooka  * only if something in the configuration changed: in case that this is the
   3428   1.1     pooka  * first time that the phy configuration is applied or in case that the phy
   3429   1.1     pooka  * configuration changed from the previous apply.
   3430   1.1     pooka  */
   3431   1.4    nonaka static int
   3432   1.1     pooka iwm_mvm_phy_ctxt_apply(struct iwm_softc *sc,
   3433   1.1     pooka 	struct iwm_mvm_phy_ctxt *ctxt,
   3434   1.1     pooka 	uint8_t chains_static, uint8_t chains_dynamic,
   3435   1.1     pooka 	uint32_t action, uint32_t apply_time)
   3436   1.1     pooka {
   3437   1.1     pooka 	struct iwm_phy_context_cmd cmd;
   3438   1.1     pooka 	int ret;
   3439   1.1     pooka 
   3440   1.1     pooka 	/* Set the command header fields */
   3441   1.1     pooka 	iwm_mvm_phy_ctxt_cmd_hdr(sc, ctxt, &cmd, action, apply_time);
   3442   1.1     pooka 
   3443   1.1     pooka 	/* Set the command data */
   3444   1.1     pooka 	iwm_mvm_phy_ctxt_cmd_data(sc, &cmd, ctxt->channel,
   3445   1.1     pooka 	    chains_static, chains_dynamic);
   3446   1.1     pooka 
   3447   1.1     pooka 	ret = iwm_mvm_send_cmd_pdu(sc, IWM_PHY_CONTEXT_CMD, IWM_CMD_SYNC,
   3448   1.1     pooka 	    sizeof(struct iwm_phy_context_cmd), &cmd);
   3449   1.1     pooka 	if (ret) {
   3450   1.1     pooka 		DPRINTF(("PHY ctxt cmd error. ret=%d\n", ret));
   3451   1.1     pooka 	}
   3452   1.1     pooka 	return ret;
   3453   1.1     pooka }
   3454   1.1     pooka 
   3455   1.1     pooka /*
   3456   1.1     pooka  * Send a command to add a PHY context based on the current HW configuration.
   3457   1.1     pooka  */
   3458   1.4    nonaka static int
   3459   1.1     pooka iwm_mvm_phy_ctxt_add(struct iwm_softc *sc, struct iwm_mvm_phy_ctxt *ctxt,
   3460   1.1     pooka 	struct ieee80211_channel *chan,
   3461   1.1     pooka 	uint8_t chains_static, uint8_t chains_dynamic)
   3462   1.1     pooka {
   3463   1.1     pooka 	ctxt->channel = chan;
   3464   1.1     pooka 	return iwm_mvm_phy_ctxt_apply(sc, ctxt,
   3465   1.1     pooka 	    chains_static, chains_dynamic, IWM_FW_CTXT_ACTION_ADD, 0);
   3466   1.1     pooka }
   3467   1.1     pooka 
   3468   1.1     pooka /*
   3469   1.1     pooka  * Send a command to modify the PHY context based on the current HW
   3470   1.1     pooka  * configuration. Note that the function does not check that the configuration
   3471   1.1     pooka  * changed.
   3472   1.1     pooka  */
   3473   1.4    nonaka static int
   3474   1.1     pooka iwm_mvm_phy_ctxt_changed(struct iwm_softc *sc,
   3475   1.1     pooka 	struct iwm_mvm_phy_ctxt *ctxt, struct ieee80211_channel *chan,
   3476   1.1     pooka 	uint8_t chains_static, uint8_t chains_dynamic)
   3477   1.1     pooka {
   3478   1.1     pooka 	ctxt->channel = chan;
   3479   1.1     pooka 	return iwm_mvm_phy_ctxt_apply(sc, ctxt,
   3480   1.1     pooka 	    chains_static, chains_dynamic, IWM_FW_CTXT_ACTION_MODIFY, 0);
   3481   1.1     pooka }
   3482   1.1     pooka 
   3483   1.8    nonaka /*
   3484   1.1     pooka  * END iwlwifi/mvm/phy-ctxt.c
   3485   1.1     pooka  */
   3486   1.1     pooka 
   3487   1.1     pooka /*
   3488   1.1     pooka  * transmit side
   3489   1.1     pooka  */
   3490   1.1     pooka 
   3491   1.1     pooka /*
   3492   1.1     pooka  * Send a command to the firmware.  We try to implement the Linux
   3493   1.1     pooka  * driver interface for the routine.
   3494   1.1     pooka  * mostly from if_iwn (iwn_cmd()).
   3495   1.1     pooka  *
   3496   1.1     pooka  * For now, we always copy the first part and map the second one (if it exists).
   3497   1.1     pooka  */
   3498   1.4    nonaka static int
   3499   1.1     pooka iwm_send_cmd(struct iwm_softc *sc, struct iwm_host_cmd *hcmd)
   3500   1.1     pooka {
   3501   1.1     pooka 	struct iwm_tx_ring *ring = &sc->txq[IWM_MVM_CMD_QUEUE];
   3502   1.1     pooka 	struct iwm_tfd *desc;
   3503   1.1     pooka 	struct iwm_tx_data *data;
   3504   1.1     pooka 	struct iwm_device_cmd *cmd;
   3505   1.1     pooka 	struct mbuf *m;
   3506   1.1     pooka 	bus_addr_t paddr;
   3507   1.1     pooka 	uint32_t addr_lo;
   3508  1.19    nonaka 	int error = 0, i, paylen, off, s;
   3509   1.1     pooka 	int code;
   3510   1.1     pooka 	int async, wantresp;
   3511   1.1     pooka 
   3512   1.1     pooka 	code = hcmd->id;
   3513   1.1     pooka 	async = hcmd->flags & IWM_CMD_ASYNC;
   3514   1.1     pooka 	wantresp = hcmd->flags & IWM_CMD_WANT_SKB;
   3515   1.1     pooka 
   3516   1.1     pooka 	for (i = 0, paylen = 0; i < __arraycount(hcmd->len); i++) {
   3517   1.1     pooka 		paylen += hcmd->len[i];
   3518   1.1     pooka 	}
   3519   1.1     pooka 
   3520   1.1     pooka 	/* if the command wants an answer, busy sc_cmd_resp */
   3521   1.1     pooka 	if (wantresp) {
   3522   1.1     pooka 		KASSERT(!async);
   3523   1.1     pooka 		while (sc->sc_wantresp != -1)
   3524   1.1     pooka 			tsleep(&sc->sc_wantresp, 0, "iwmcmdsl", 0);
   3525   1.1     pooka 		sc->sc_wantresp = ring->qid << 16 | ring->cur;
   3526   1.1     pooka 		DPRINTFN(12, ("wantresp is %x\n", sc->sc_wantresp));
   3527   1.1     pooka 	}
   3528   1.1     pooka 
   3529   1.1     pooka 	/*
   3530   1.1     pooka 	 * Is the hardware still available?  (after e.g. above wait).
   3531   1.1     pooka 	 */
   3532   1.1     pooka 	s = splnet();
   3533   1.1     pooka 	if (sc->sc_flags & IWM_FLAG_STOPPED) {
   3534   1.1     pooka 		error = ENXIO;
   3535   1.1     pooka 		goto out;
   3536   1.1     pooka 	}
   3537   1.1     pooka 
   3538   1.1     pooka 	desc = &ring->desc[ring->cur];
   3539   1.1     pooka 	data = &ring->data[ring->cur];
   3540   1.1     pooka 
   3541   1.1     pooka 	if (paylen > sizeof(cmd->data)) {
   3542   1.1     pooka 		/* Command is too large */
   3543   1.1     pooka 		if (sizeof(cmd->hdr) + paylen > IWM_RBUF_SIZE) {
   3544   1.1     pooka 			error = EINVAL;
   3545   1.1     pooka 			goto out;
   3546   1.1     pooka 		}
   3547   1.1     pooka 		m = m_gethdr(M_DONTWAIT, MT_DATA);
   3548   1.1     pooka 		if (m == NULL) {
   3549   1.1     pooka 			error = ENOMEM;
   3550   1.1     pooka 			goto out;
   3551   1.1     pooka 		}
   3552   1.1     pooka 		MEXTMALLOC(m, IWM_RBUF_SIZE, M_DONTWAIT);
   3553   1.1     pooka 		if (!(m->m_flags & M_EXT)) {
   3554   1.1     pooka 			m_freem(m);
   3555   1.1     pooka 			error = ENOMEM;
   3556   1.1     pooka 			goto out;
   3557   1.1     pooka 		}
   3558   1.1     pooka 		cmd = mtod(m, struct iwm_device_cmd *);
   3559   1.1     pooka 		error = bus_dmamap_load(sc->sc_dmat, data->map, cmd,
   3560   1.5    nonaka 		    IWM_RBUF_SIZE, NULL, BUS_DMA_NOWAIT | BUS_DMA_WRITE);
   3561   1.1     pooka 		if (error != 0) {
   3562   1.1     pooka 			m_freem(m);
   3563   1.1     pooka 			goto out;
   3564   1.1     pooka 		}
   3565   1.1     pooka 		data->m = m;
   3566   1.1     pooka 		paddr = data->map->dm_segs[0].ds_addr;
   3567   1.1     pooka 	} else {
   3568   1.1     pooka 		cmd = &ring->cmd[ring->cur];
   3569   1.1     pooka 		paddr = data->cmd_paddr;
   3570   1.1     pooka 	}
   3571   1.1     pooka 
   3572   1.1     pooka 	cmd->hdr.code = code;
   3573   1.1     pooka 	cmd->hdr.flags = 0;
   3574   1.1     pooka 	cmd->hdr.qid = ring->qid;
   3575   1.1     pooka 	cmd->hdr.idx = ring->cur;
   3576   1.1     pooka 
   3577   1.1     pooka 	for (i = 0, off = 0; i < __arraycount(hcmd->data); i++) {
   3578   1.1     pooka 		if (hcmd->len[i] == 0)
   3579   1.1     pooka 			continue;
   3580   1.1     pooka 		memcpy(cmd->data + off, hcmd->data[i], hcmd->len[i]);
   3581   1.1     pooka 		off += hcmd->len[i];
   3582   1.1     pooka 	}
   3583   1.1     pooka 	KASSERT(off == paylen);
   3584   1.1     pooka 
   3585   1.1     pooka 	/* lo field is not aligned */
   3586   1.1     pooka 	addr_lo = htole32((uint32_t)paddr);
   3587   1.1     pooka 	memcpy(&desc->tbs[0].lo, &addr_lo, sizeof(uint32_t));
   3588   1.1     pooka 	desc->tbs[0].hi_n_len  = htole16(iwm_get_dma_hi_addr(paddr)
   3589   1.1     pooka 	    | ((sizeof(cmd->hdr) + paylen) << 4));
   3590   1.1     pooka 	desc->num_tbs = 1;
   3591   1.1     pooka 
   3592   1.9    nonaka 	DPRINTFN(8, ("iwm_send_cmd 0x%x size=%zu %s\n",
   3593   1.5    nonaka 	    code, sizeof(cmd->hdr) + paylen, async ? " (async)" : ""));
   3594   1.1     pooka 
   3595   1.5    nonaka 	if (paylen > sizeof(cmd->data)) {
   3596   1.5    nonaka 		bus_dmamap_sync(sc->sc_dmat, data->map, 0,
   3597   1.5    nonaka 		    sizeof(cmd->hdr) + paylen, BUS_DMASYNC_PREWRITE);
   3598   1.1     pooka 	} else {
   3599   1.1     pooka 		bus_dmamap_sync(sc->sc_dmat, ring->cmd_dma.map,
   3600   1.1     pooka 		    (char *)(void *)cmd - (char *)(void *)ring->cmd_dma.vaddr,
   3601   1.5    nonaka 		    sizeof(cmd->hdr) + paylen, BUS_DMASYNC_PREWRITE);
   3602   1.1     pooka 	}
   3603   1.1     pooka 	bus_dmamap_sync(sc->sc_dmat, ring->desc_dma.map,
   3604   1.1     pooka 	    (char *)(void *)desc - (char *)(void *)ring->desc_dma.vaddr,
   3605   1.1     pooka 	    sizeof (*desc), BUS_DMASYNC_PREWRITE);
   3606   1.1     pooka 
   3607   1.1     pooka 	IWM_SETBITS(sc, IWM_CSR_GP_CNTRL,
   3608   1.1     pooka 	    IWM_CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
   3609   1.1     pooka 	if (!iwm_poll_bit(sc, IWM_CSR_GP_CNTRL,
   3610   1.1     pooka 	    IWM_CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
   3611   1.1     pooka 	    (IWM_CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
   3612   1.1     pooka 	     IWM_CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000)) {
   3613   1.2    nonaka 		DPRINTF(("%s: acquiring device failed\n", DEVNAME(sc)));
   3614   1.1     pooka 		error = EBUSY;
   3615   1.1     pooka 		goto out;
   3616   1.1     pooka 	}
   3617   1.1     pooka 
   3618   1.1     pooka #if 0
   3619   1.1     pooka 	iwm_update_sched(sc, ring->qid, ring->cur, 0, 0);
   3620   1.1     pooka #endif
   3621   1.1     pooka 	DPRINTF(("sending command 0x%x qid %d, idx %d\n",
   3622   1.1     pooka 	    code, ring->qid, ring->cur));
   3623   1.1     pooka 
   3624   1.1     pooka 	/* Kick command ring. */
   3625   1.1     pooka 	ring->cur = (ring->cur + 1) % IWM_TX_RING_COUNT;
   3626   1.1     pooka 	IWM_WRITE(sc, IWM_HBUS_TARG_WRPTR, ring->qid << 8 | ring->cur);
   3627   1.1     pooka 
   3628   1.1     pooka 	if (!async) {
   3629   1.1     pooka 		/* m..m-mmyy-mmyyyy-mym-ym m-my generation */
   3630   1.1     pooka 		int generation = sc->sc_generation;
   3631   1.1     pooka 		error = tsleep(desc, PCATCH, "iwmcmd", hz);
   3632   1.1     pooka 		if (error == 0) {
   3633   1.1     pooka 			/* if hardware is no longer up, return error */
   3634   1.1     pooka 			if (generation != sc->sc_generation) {
   3635   1.1     pooka 				error = ENXIO;
   3636   1.1     pooka 			} else {
   3637   1.1     pooka 				hcmd->resp_pkt = (void *)sc->sc_cmd_resp;
   3638   1.1     pooka 			}
   3639   1.1     pooka 		}
   3640   1.1     pooka 	}
   3641   1.1     pooka  out:
   3642   1.1     pooka 	if (wantresp && error != 0) {
   3643   1.1     pooka 		iwm_free_resp(sc, hcmd);
   3644   1.1     pooka 	}
   3645   1.1     pooka 	splx(s);
   3646   1.1     pooka 
   3647   1.1     pooka 	return error;
   3648   1.1     pooka }
   3649   1.1     pooka 
   3650   1.1     pooka /* iwlwifi: mvm/utils.c */
   3651   1.4    nonaka static int
   3652   1.1     pooka iwm_mvm_send_cmd_pdu(struct iwm_softc *sc, uint8_t id,
   3653   1.1     pooka 	uint32_t flags, uint16_t len, const void *data)
   3654   1.1     pooka {
   3655   1.1     pooka 	struct iwm_host_cmd cmd = {
   3656   1.1     pooka 		.id = id,
   3657   1.1     pooka 		.len = { len, },
   3658   1.1     pooka 		.data = { data, },
   3659   1.1     pooka 		.flags = flags,
   3660   1.1     pooka 	};
   3661   1.1     pooka 
   3662   1.1     pooka 	return iwm_send_cmd(sc, &cmd);
   3663   1.1     pooka }
   3664   1.1     pooka 
   3665   1.1     pooka /* iwlwifi: mvm/utils.c */
   3666   1.4    nonaka static int
   3667   1.1     pooka iwm_mvm_send_cmd_status(struct iwm_softc *sc,
   3668   1.1     pooka 	struct iwm_host_cmd *cmd, uint32_t *status)
   3669   1.1     pooka {
   3670   1.1     pooka 	struct iwm_rx_packet *pkt;
   3671   1.1     pooka 	struct iwm_cmd_response *resp;
   3672   1.1     pooka 	int error, resp_len;
   3673   1.1     pooka 
   3674   1.1     pooka 	//lockdep_assert_held(&mvm->mutex);
   3675   1.1     pooka 
   3676   1.1     pooka 	KASSERT((cmd->flags & IWM_CMD_WANT_SKB) == 0);
   3677   1.1     pooka 	cmd->flags |= IWM_CMD_SYNC | IWM_CMD_WANT_SKB;
   3678   1.1     pooka 
   3679   1.1     pooka 	if ((error = iwm_send_cmd(sc, cmd)) != 0)
   3680   1.1     pooka 		return error;
   3681   1.1     pooka 	pkt = cmd->resp_pkt;
   3682   1.1     pooka 
   3683   1.1     pooka 	/* Can happen if RFKILL is asserted */
   3684   1.1     pooka 	if (!pkt) {
   3685   1.1     pooka 		error = 0;
   3686   1.1     pooka 		goto out_free_resp;
   3687   1.1     pooka 	}
   3688   1.1     pooka 
   3689   1.1     pooka 	if (pkt->hdr.flags & IWM_CMD_FAILED_MSK) {
   3690   1.1     pooka 		error = EIO;
   3691   1.1     pooka 		goto out_free_resp;
   3692   1.1     pooka 	}
   3693   1.1     pooka 
   3694   1.1     pooka 	resp_len = iwm_rx_packet_payload_len(pkt);
   3695   1.1     pooka 	if (resp_len != sizeof(*resp)) {
   3696   1.1     pooka 		error = EIO;
   3697   1.1     pooka 		goto out_free_resp;
   3698   1.1     pooka 	}
   3699   1.1     pooka 
   3700   1.1     pooka 	resp = (void *)pkt->data;
   3701   1.1     pooka 	*status = le32toh(resp->status);
   3702   1.1     pooka  out_free_resp:
   3703   1.1     pooka 	iwm_free_resp(sc, cmd);
   3704   1.1     pooka 	return error;
   3705   1.1     pooka }
   3706   1.1     pooka 
   3707   1.1     pooka /* iwlwifi/mvm/utils.c */
   3708   1.4    nonaka static int
   3709   1.1     pooka iwm_mvm_send_cmd_pdu_status(struct iwm_softc *sc, uint8_t id,
   3710   1.1     pooka 	uint16_t len, const void *data, uint32_t *status)
   3711   1.1     pooka {
   3712   1.1     pooka 	struct iwm_host_cmd cmd = {
   3713   1.1     pooka 		.id = id,
   3714   1.1     pooka 		.len = { len, },
   3715   1.1     pooka 		.data = { data, },
   3716   1.1     pooka 	};
   3717   1.1     pooka 
   3718   1.1     pooka 	return iwm_mvm_send_cmd_status(sc, &cmd, status);
   3719   1.1     pooka }
   3720   1.1     pooka 
   3721   1.4    nonaka static void
   3722   1.1     pooka iwm_free_resp(struct iwm_softc *sc, struct iwm_host_cmd *hcmd)
   3723   1.1     pooka {
   3724   1.1     pooka 	KASSERT(sc->sc_wantresp != -1);
   3725   1.1     pooka 	KASSERT((hcmd->flags & (IWM_CMD_WANT_SKB|IWM_CMD_SYNC))
   3726   1.1     pooka 	    == (IWM_CMD_WANT_SKB|IWM_CMD_SYNC));
   3727   1.1     pooka 	sc->sc_wantresp = -1;
   3728   1.1     pooka 	wakeup(&sc->sc_wantresp);
   3729   1.1     pooka }
   3730   1.1     pooka 
   3731   1.1     pooka /*
   3732   1.1     pooka  * Process a "command done" firmware notification.  This is where we wakeup
   3733   1.1     pooka  * processes waiting for a synchronous command completion.
   3734   1.1     pooka  * from if_iwn
   3735   1.1     pooka  */
   3736   1.4    nonaka static void
   3737   1.1     pooka iwm_cmd_done(struct iwm_softc *sc, struct iwm_rx_packet *pkt)
   3738   1.1     pooka {
   3739   1.1     pooka 	struct iwm_tx_ring *ring = &sc->txq[IWM_MVM_CMD_QUEUE];
   3740   1.1     pooka 	struct iwm_tx_data *data;
   3741   1.1     pooka 
   3742   1.1     pooka 	if (pkt->hdr.qid != IWM_MVM_CMD_QUEUE) {
   3743   1.1     pooka 		return;	/* Not a command ack. */
   3744   1.1     pooka 	}
   3745   1.1     pooka 
   3746   1.1     pooka 	data = &ring->data[pkt->hdr.idx];
   3747   1.1     pooka 
   3748   1.1     pooka 	/* If the command was mapped in an mbuf, free it. */
   3749   1.1     pooka 	if (data->m != NULL) {
   3750   1.1     pooka 		bus_dmamap_sync(sc->sc_dmat, data->map, 0,
   3751   1.1     pooka 		    data->map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
   3752   1.1     pooka 		bus_dmamap_unload(sc->sc_dmat, data->map);
   3753   1.1     pooka 		m_freem(data->m);
   3754   1.1     pooka 		data->m = NULL;
   3755   1.1     pooka 	}
   3756   1.1     pooka 	wakeup(&ring->desc[pkt->hdr.idx]);
   3757   1.1     pooka }
   3758   1.1     pooka 
   3759   1.1     pooka #if 0
   3760   1.1     pooka /*
   3761   1.1     pooka  * necessary only for block ack mode
   3762   1.1     pooka  */
   3763   1.1     pooka void
   3764   1.1     pooka iwm_update_sched(struct iwm_softc *sc, int qid, int idx, uint8_t sta_id,
   3765   1.1     pooka 	uint16_t len)
   3766   1.1     pooka {
   3767   1.1     pooka 	struct iwm_agn_scd_bc_tbl *scd_bc_tbl;
   3768   1.1     pooka 	uint16_t w_val;
   3769   1.1     pooka 
   3770   1.1     pooka 	scd_bc_tbl = sc->sched_dma.vaddr;
   3771   1.1     pooka 
   3772   1.1     pooka 	len += 8; /* magic numbers came naturally from paris */
   3773   1.1     pooka 	if (sc->sc_capaflags & IWM_UCODE_TLV_FLAGS_DW_BC_TABLE)
   3774   1.1     pooka 		len = roundup(len, 4) / 4;
   3775   1.1     pooka 
   3776   1.1     pooka 	w_val = htole16(sta_id << 12 | len);
   3777   1.1     pooka 
   3778   1.1     pooka 	/* Update TX scheduler. */
   3779   1.1     pooka 	scd_bc_tbl[qid].tfd_offset[idx] = w_val;
   3780   1.1     pooka 	bus_dmamap_sync(sc->sc_dmat, sc->sched_dma.map,
   3781   1.1     pooka 	    (char *)(void *)w - (char *)(void *)sc->sched_dma.vaddr,
   3782   1.1     pooka 	    sizeof(uint16_t), BUS_DMASYNC_PREWRITE);
   3783   1.1     pooka 
   3784   1.1     pooka 	/* I really wonder what this is ?!? */
   3785   1.1     pooka 	if (idx < IWM_TFD_QUEUE_SIZE_BC_DUP) {
   3786   1.1     pooka 		scd_bc_tbl[qid].tfd_offset[IWM_TFD_QUEUE_SIZE_MAX + idx] = w_val;
   3787   1.1     pooka 		bus_dmamap_sync(sc->sc_dmat, sc->sched_dma.map,
   3788   1.1     pooka 		    (char *)(void *)(w + IWM_TFD_QUEUE_SIZE_MAX) -
   3789   1.1     pooka 		    (char *)(void *)sc->sched_dma.vaddr,
   3790   1.1     pooka 		    sizeof (uint16_t), BUS_DMASYNC_PREWRITE);
   3791   1.1     pooka 	}
   3792   1.1     pooka }
   3793   1.1     pooka #endif
   3794   1.1     pooka 
   3795   1.1     pooka /*
   3796   1.1     pooka  * Fill in various bit for management frames, and leave them
   3797   1.1     pooka  * unfilled for data frames (firmware takes care of that).
   3798   1.1     pooka  * Return the selected TX rate.
   3799   1.1     pooka  */
   3800   1.4    nonaka static const struct iwm_rate *
   3801   1.1     pooka iwm_tx_fill_cmd(struct iwm_softc *sc, struct iwm_node *in,
   3802   1.1     pooka 	struct ieee80211_frame *wh, struct iwm_tx_cmd *tx)
   3803   1.1     pooka {
   3804  1.24    nonaka 	struct ieee80211com *ic = &sc->sc_ic;
   3805  1.28    nonaka 	struct ieee80211_node *ni = &in->in_ni;
   3806   1.1     pooka 	const struct iwm_rate *rinfo;
   3807   1.1     pooka 	int type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
   3808   1.1     pooka 	int ridx, rate_flags;
   3809  1.28    nonaka 	int nrates = ni->ni_rates.rs_nrates;
   3810   1.1     pooka 
   3811   1.1     pooka 	tx->rts_retry_limit = IWM_RTS_DFAULT_RETRY_LIMIT;
   3812   1.1     pooka 	tx->data_retry_limit = IWM_DEFAULT_TX_RETRY;
   3813   1.1     pooka 
   3814  1.28    nonaka 	if (type != IEEE80211_FC0_TYPE_DATA) {
   3815  1.28    nonaka 		/* for non-data, use the lowest supported rate */
   3816  1.28    nonaka 		ridx = (ic->ic_curmode == IEEE80211_MODE_11A) ?
   3817  1.28    nonaka 		    IWM_RIDX_OFDM : IWM_RIDX_CCK;
   3818  1.28    nonaka 	} else if (ic->ic_fixed_rate != -1) {
   3819  1.28    nonaka 		ridx = sc->sc_fixed_ridx;
   3820  1.28    nonaka 	} else {
   3821  1.28    nonaka 		/* for data frames, use RS table */
   3822  1.28    nonaka 		tx->initial_rate_index = (nrates - 1) - ni->ni_txrate;
   3823   1.8    nonaka 		tx->tx_flags |= htole32(IWM_TX_CMD_FLG_STA_RATE);
   3824   1.1     pooka 		DPRINTFN(12, ("start with txrate %d\n", tx->initial_rate_index));
   3825  1.28    nonaka 		ridx = in->in_ridx[ni->ni_txrate];
   3826  1.28    nonaka 		return &iwm_rates[ridx];
   3827   1.1     pooka 	}
   3828   1.1     pooka 
   3829   1.1     pooka 	rinfo = &iwm_rates[ridx];
   3830   1.1     pooka 	rate_flags = 1 << IWM_RATE_MCS_ANT_POS;
   3831   1.1     pooka 	if (IWM_RIDX_IS_CCK(ridx))
   3832   1.1     pooka 		rate_flags |= IWM_RATE_MCS_CCK_MSK;
   3833   1.1     pooka 	tx->rate_n_flags = htole32(rate_flags | rinfo->plcp);
   3834   1.1     pooka 
   3835   1.1     pooka 	return rinfo;
   3836   1.1     pooka }
   3837   1.1     pooka 
   3838   1.1     pooka #define TB0_SIZE 16
   3839   1.4    nonaka static int
   3840   1.1     pooka iwm_tx(struct iwm_softc *sc, struct mbuf *m, struct ieee80211_node *ni, int ac)
   3841   1.1     pooka {
   3842   1.1     pooka 	struct ieee80211com *ic = &sc->sc_ic;
   3843   1.1     pooka 	struct iwm_node *in = (void *)ni;
   3844   1.1     pooka 	struct iwm_tx_ring *ring;
   3845   1.1     pooka 	struct iwm_tx_data *data;
   3846   1.1     pooka 	struct iwm_tfd *desc;
   3847   1.1     pooka 	struct iwm_device_cmd *cmd;
   3848   1.1     pooka 	struct iwm_tx_cmd *tx;
   3849   1.1     pooka 	struct ieee80211_frame *wh;
   3850   1.1     pooka 	struct ieee80211_key *k = NULL;
   3851   1.1     pooka 	struct mbuf *m1;
   3852   1.1     pooka 	const struct iwm_rate *rinfo;
   3853   1.1     pooka 	uint32_t flags;
   3854   1.1     pooka 	u_int hdrlen;
   3855   1.1     pooka 	bus_dma_segment_t *seg;
   3856   1.1     pooka 	uint8_t tid, type;
   3857   1.1     pooka 	int i, totlen, error, pad;
   3858   1.1     pooka 	int hdrlen2;
   3859   1.1     pooka 
   3860   1.1     pooka 	wh = mtod(m, struct ieee80211_frame *);
   3861   1.1     pooka 	hdrlen = ieee80211_anyhdrsize(wh);
   3862   1.1     pooka 	type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
   3863   1.1     pooka 
   3864   1.1     pooka 	hdrlen2 = (ieee80211_has_qos(wh)) ?
   3865   1.1     pooka 	    sizeof (struct ieee80211_qosframe) :
   3866   1.1     pooka 	    sizeof (struct ieee80211_frame);
   3867   1.1     pooka 
   3868   1.1     pooka 	if (hdrlen != hdrlen2)
   3869   1.2    nonaka 		DPRINTF(("%s: hdrlen error (%d != %d)\n",
   3870   1.2    nonaka 		    DEVNAME(sc), hdrlen, hdrlen2));
   3871   1.1     pooka 
   3872   1.1     pooka 	tid = 0;
   3873   1.1     pooka 
   3874   1.1     pooka 	ring = &sc->txq[ac];
   3875   1.1     pooka 	desc = &ring->desc[ring->cur];
   3876   1.1     pooka 	memset(desc, 0, sizeof(*desc));
   3877   1.1     pooka 	data = &ring->data[ring->cur];
   3878   1.1     pooka 
   3879   1.1     pooka 	/* Fill out iwm_tx_cmd to send to the firmware */
   3880   1.1     pooka 	cmd = &ring->cmd[ring->cur];
   3881   1.1     pooka 	cmd->hdr.code = IWM_TX_CMD;
   3882   1.1     pooka 	cmd->hdr.flags = 0;
   3883   1.1     pooka 	cmd->hdr.qid = ring->qid;
   3884   1.1     pooka 	cmd->hdr.idx = ring->cur;
   3885   1.1     pooka 
   3886   1.1     pooka 	tx = (void *)cmd->data;
   3887   1.1     pooka 	memset(tx, 0, sizeof(*tx));
   3888   1.1     pooka 
   3889   1.1     pooka 	rinfo = iwm_tx_fill_cmd(sc, in, wh, tx);
   3890   1.1     pooka 
   3891   1.1     pooka 	if (sc->sc_drvbpf != NULL) {
   3892   1.1     pooka 		struct iwm_tx_radiotap_header *tap = &sc->sc_txtap;
   3893   1.1     pooka 
   3894   1.1     pooka 		tap->wt_flags = 0;
   3895   1.1     pooka 		tap->wt_chan_freq = htole16(ni->ni_chan->ic_freq);
   3896   1.1     pooka 		tap->wt_chan_flags = htole16(ni->ni_chan->ic_flags);
   3897   1.1     pooka 		tap->wt_rate = rinfo->rate;
   3898   1.1     pooka 		tap->wt_hwqueue = ac;
   3899   1.1     pooka 		if (wh->i_fc[1] & IEEE80211_FC1_WEP)
   3900   1.1     pooka 			tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP;
   3901   1.1     pooka 
   3902   1.1     pooka 		bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m);
   3903   1.1     pooka 	}
   3904   1.1     pooka 
   3905   1.1     pooka 	/* Encrypt the frame if need be. */
   3906   1.1     pooka 	if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
   3907   1.1     pooka 		k = ieee80211_crypto_encap(ic, ni, m);
   3908   1.1     pooka 		if (k == NULL) {
   3909   1.1     pooka 			m_freem(m);
   3910   1.1     pooka 			return ENOBUFS;
   3911   1.1     pooka 		}
   3912   1.1     pooka 		/* Packet header may have moved, reset our local pointer. */
   3913   1.1     pooka 		wh = mtod(m, struct ieee80211_frame *);
   3914   1.1     pooka 	}
   3915   1.1     pooka 	totlen = m->m_pkthdr.len;
   3916   1.1     pooka 
   3917   1.1     pooka 	flags = 0;
   3918   1.1     pooka 	if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
   3919   1.1     pooka 		flags |= IWM_TX_CMD_FLG_ACK;
   3920   1.1     pooka 	}
   3921   1.1     pooka 
   3922   1.1     pooka 	if (type != IEEE80211_FC0_TYPE_DATA
   3923   1.1     pooka 	    && (totlen + IEEE80211_CRC_LEN > ic->ic_rtsthreshold)
   3924   1.1     pooka 	    && !IEEE80211_IS_MULTICAST(wh->i_addr1)) {
   3925   1.1     pooka 		flags |= IWM_TX_CMD_FLG_PROT_REQUIRE;
   3926   1.1     pooka 	}
   3927   1.1     pooka 
   3928   1.1     pooka 	if (IEEE80211_IS_MULTICAST(wh->i_addr1) ||
   3929   1.1     pooka 	    type != IEEE80211_FC0_TYPE_DATA)
   3930   1.1     pooka 		tx->sta_id = sc->sc_aux_sta.sta_id;
   3931   1.1     pooka 	else
   3932   1.1     pooka 		tx->sta_id = IWM_STATION_ID;
   3933   1.1     pooka 
   3934   1.1     pooka 	if (type == IEEE80211_FC0_TYPE_MGT) {
   3935   1.1     pooka 		uint8_t subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
   3936   1.1     pooka 
   3937   1.1     pooka 		if (subtype == IEEE80211_FC0_SUBTYPE_ASSOC_REQ ||
   3938   1.1     pooka 		    subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ)
   3939   1.1     pooka 			tx->pm_frame_timeout = htole16(3);
   3940   1.1     pooka 		else
   3941   1.1     pooka 			tx->pm_frame_timeout = htole16(2);
   3942   1.1     pooka 	} else {
   3943   1.1     pooka 		tx->pm_frame_timeout = htole16(0);
   3944   1.1     pooka 	}
   3945   1.1     pooka 
   3946   1.8    nonaka 	if (hdrlen & 3) {
   3947   1.8    nonaka 		/* First segment length must be a multiple of 4. */
   3948   1.8    nonaka 		flags |= IWM_TX_CMD_FLG_MH_PAD;
   3949   1.8    nonaka 		pad = 4 - (hdrlen & 3);
   3950   1.8    nonaka 	} else
   3951   1.8    nonaka 		pad = 0;
   3952   1.1     pooka 
   3953   1.1     pooka 	tx->driver_txop = 0;
   3954   1.1     pooka 	tx->next_frame_len = 0;
   3955   1.1     pooka 
   3956   1.1     pooka 	tx->len = htole16(totlen);
   3957   1.1     pooka 	tx->tid_tspec = tid;
   3958   1.1     pooka 	tx->life_time = htole32(IWM_TX_CMD_LIFE_TIME_INFINITE);
   3959   1.1     pooka 
   3960   1.1     pooka 	/* Set physical address of "scratch area". */
   3961   1.1     pooka 	tx->dram_lsb_ptr = htole32(data->scratch_paddr);
   3962   1.1     pooka 	tx->dram_msb_ptr = iwm_get_dma_hi_addr(data->scratch_paddr);
   3963   1.1     pooka 
   3964   1.1     pooka 	/* Copy 802.11 header in TX command. */
   3965   1.1     pooka 	memcpy(((uint8_t *)tx) + sizeof(*tx), wh, hdrlen);
   3966   1.1     pooka 
   3967   1.1     pooka 	flags |= IWM_TX_CMD_FLG_BT_DIS | IWM_TX_CMD_FLG_SEQ_CTL;
   3968   1.1     pooka 
   3969   1.1     pooka 	tx->sec_ctl = 0;
   3970   1.1     pooka 	tx->tx_flags |= htole32(flags);
   3971   1.1     pooka 
   3972   1.1     pooka 	/* Trim 802.11 header. */
   3973   1.1     pooka 	m_adj(m, hdrlen);
   3974   1.1     pooka 
   3975   1.1     pooka 	error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m,
   3976   1.1     pooka 	    BUS_DMA_NOWAIT | BUS_DMA_WRITE);
   3977   1.1     pooka 	if (error != 0) {
   3978   1.1     pooka 		if (error != EFBIG) {
   3979   1.3    nonaka 			aprint_error_dev(sc->sc_dev,
   3980   1.3    nonaka 			    "can't map mbuf (error %d)\n", error);
   3981   1.1     pooka 			m_freem(m);
   3982   1.1     pooka 			return error;
   3983   1.1     pooka 		}
   3984   1.1     pooka 		/* Too many DMA segments, linearize mbuf. */
   3985   1.1     pooka 		MGETHDR(m1, M_DONTWAIT, MT_DATA);
   3986   1.1     pooka 		if (m1 == NULL) {
   3987   1.1     pooka 			m_freem(m);
   3988   1.1     pooka 			return ENOBUFS;
   3989   1.1     pooka 		}
   3990   1.1     pooka 		if (m->m_pkthdr.len > MHLEN) {
   3991   1.1     pooka 			MCLGET(m1, M_DONTWAIT);
   3992   1.1     pooka 			if (!(m1->m_flags & M_EXT)) {
   3993   1.1     pooka 				m_freem(m);
   3994   1.1     pooka 				m_freem(m1);
   3995   1.1     pooka 				return ENOBUFS;
   3996   1.1     pooka 			}
   3997   1.1     pooka 		}
   3998   1.1     pooka 		m_copydata(m, 0, m->m_pkthdr.len, mtod(m1, void *));
   3999   1.1     pooka 		m1->m_pkthdr.len = m1->m_len = m->m_pkthdr.len;
   4000   1.1     pooka 		m_freem(m);
   4001   1.1     pooka 		m = m1;
   4002   1.1     pooka 
   4003   1.1     pooka 		error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m,
   4004   1.1     pooka 		    BUS_DMA_NOWAIT | BUS_DMA_WRITE);
   4005   1.1     pooka 		if (error != 0) {
   4006   1.3    nonaka 			aprint_error_dev(sc->sc_dev,
   4007   1.3    nonaka 			    "can't map mbuf (error %d)\n", error);
   4008   1.1     pooka 			m_freem(m);
   4009   1.1     pooka 			return error;
   4010   1.1     pooka 		}
   4011   1.1     pooka 	}
   4012   1.1     pooka 	data->m = m;
   4013   1.1     pooka 	data->in = in;
   4014   1.1     pooka 	data->done = 0;
   4015   1.1     pooka 
   4016   1.1     pooka 	DPRINTFN(8, ("sending txd %p, in %p\n", data, data->in));
   4017   1.1     pooka 	KASSERT(data->in != NULL);
   4018   1.1     pooka 
   4019   1.1     pooka 	DPRINTFN(8, ("sending data: qid=%d idx=%d len=%d nsegs=%d\n",
   4020   1.1     pooka 	    ring->qid, ring->cur, totlen, data->map->dm_nsegs));
   4021   1.1     pooka 
   4022   1.1     pooka 	/* Fill TX descriptor. */
   4023   1.1     pooka 	desc->num_tbs = 2 + data->map->dm_nsegs;
   4024   1.1     pooka 
   4025   1.1     pooka 	desc->tbs[0].lo = htole32(data->cmd_paddr);
   4026   1.1     pooka 	desc->tbs[0].hi_n_len = htole16(iwm_get_dma_hi_addr(data->cmd_paddr)) |
   4027   1.1     pooka 	    (TB0_SIZE << 4);
   4028   1.1     pooka 	desc->tbs[1].lo = htole32(data->cmd_paddr + TB0_SIZE);
   4029   1.1     pooka 	desc->tbs[1].hi_n_len = htole16(iwm_get_dma_hi_addr(data->cmd_paddr)) |
   4030   1.1     pooka 	    ((sizeof(struct iwm_cmd_header) + sizeof(*tx)
   4031   1.1     pooka 	      + hdrlen + pad - TB0_SIZE) << 4);
   4032   1.1     pooka 
   4033   1.1     pooka 	/* Other DMA segments are for data payload. */
   4034   1.1     pooka 	seg = data->map->dm_segs;
   4035   1.1     pooka 	for (i = 0; i < data->map->dm_nsegs; i++, seg++) {
   4036   1.1     pooka 		desc->tbs[i+2].lo = htole32(seg->ds_addr);
   4037   1.1     pooka 		desc->tbs[i+2].hi_n_len = \
   4038   1.1     pooka 		    htole16(iwm_get_dma_hi_addr(seg->ds_addr))
   4039   1.1     pooka 		    | ((seg->ds_len) << 4);
   4040   1.1     pooka 	}
   4041   1.1     pooka 
   4042   1.1     pooka 	bus_dmamap_sync(sc->sc_dmat, data->map, 0, data->map->dm_mapsize,
   4043   1.1     pooka 	    BUS_DMASYNC_PREWRITE);
   4044   1.1     pooka 	bus_dmamap_sync(sc->sc_dmat, ring->cmd_dma.map,
   4045   1.1     pooka 	    (char *)(void *)cmd - (char *)(void *)ring->cmd_dma.vaddr,
   4046   1.1     pooka 	    sizeof (*cmd), BUS_DMASYNC_PREWRITE);
   4047   1.1     pooka 	bus_dmamap_sync(sc->sc_dmat, ring->desc_dma.map,
   4048   1.1     pooka 	    (char *)(void *)desc - (char *)(void *)ring->desc_dma.vaddr,
   4049   1.1     pooka 	    sizeof (*desc), BUS_DMASYNC_PREWRITE);
   4050   1.1     pooka 
   4051   1.1     pooka #if 0
   4052   1.1     pooka 	iwm_update_sched(sc, ring->qid, ring->cur, tx->sta_id, le16toh(tx->len));
   4053   1.1     pooka #endif
   4054   1.1     pooka 
   4055   1.1     pooka 	/* Kick TX ring. */
   4056   1.1     pooka 	ring->cur = (ring->cur + 1) % IWM_TX_RING_COUNT;
   4057   1.1     pooka 	IWM_WRITE(sc, IWM_HBUS_TARG_WRPTR, ring->qid << 8 | ring->cur);
   4058   1.1     pooka 
   4059   1.1     pooka 	/* Mark TX ring as full if we reach a certain threshold. */
   4060   1.1     pooka 	if (++ring->queued > IWM_TX_RING_HIMARK) {
   4061   1.1     pooka 		sc->qfullmsk |= 1 << ring->qid;
   4062   1.1     pooka 	}
   4063   1.1     pooka 
   4064   1.1     pooka 	return 0;
   4065   1.1     pooka }
   4066   1.1     pooka 
   4067   1.1     pooka #if 0
   4068   1.1     pooka /* not necessary? */
   4069   1.4    nonaka static int
   4070   1.1     pooka iwm_mvm_flush_tx_path(struct iwm_softc *sc, int tfd_msk, int sync)
   4071   1.1     pooka {
   4072   1.1     pooka 	struct iwm_tx_path_flush_cmd flush_cmd = {
   4073   1.1     pooka 		.queues_ctl = htole32(tfd_msk),
   4074   1.1     pooka 		.flush_ctl = htole16(IWM_DUMP_TX_FIFO_FLUSH),
   4075   1.1     pooka 	};
   4076   1.1     pooka 	int ret;
   4077   1.1     pooka 
   4078   1.1     pooka 	ret = iwm_mvm_send_cmd_pdu(sc, IWM_TXPATH_FLUSH,
   4079   1.1     pooka 	    sync ? IWM_CMD_SYNC : IWM_CMD_ASYNC,
   4080   1.1     pooka 	    sizeof(flush_cmd), &flush_cmd);
   4081   1.1     pooka 	if (ret)
   4082   1.3    nonaka 		aprint_error_dev(sc->sc_dev, "Flushing tx queue failed: %d\n",
   4083   1.3    nonaka 		    ret);
   4084   1.1     pooka 	return ret;
   4085   1.1     pooka }
   4086   1.1     pooka #endif
   4087   1.1     pooka 
   4088   1.1     pooka 
   4089   1.1     pooka /*
   4090   1.1     pooka  * BEGIN mvm/power.c
   4091   1.1     pooka  */
   4092   1.1     pooka 
   4093   1.1     pooka #define IWM_POWER_KEEP_ALIVE_PERIOD_SEC    25
   4094   1.1     pooka 
   4095   1.4    nonaka static int
   4096   1.1     pooka iwm_mvm_beacon_filter_send_cmd(struct iwm_softc *sc,
   4097   1.1     pooka 	struct iwm_beacon_filter_cmd *cmd)
   4098   1.1     pooka {
   4099   1.1     pooka 	int ret;
   4100   1.1     pooka 
   4101   1.1     pooka 	ret = iwm_mvm_send_cmd_pdu(sc, IWM_REPLY_BEACON_FILTERING_CMD,
   4102   1.1     pooka 	    IWM_CMD_SYNC, sizeof(struct iwm_beacon_filter_cmd), cmd);
   4103   1.1     pooka 
   4104   1.1     pooka 	if (!ret) {
   4105   1.1     pooka 		DPRINTF(("ba_enable_beacon_abort is: %d\n",
   4106   1.1     pooka 		    le32toh(cmd->ba_enable_beacon_abort)));
   4107   1.1     pooka 		DPRINTF(("ba_escape_timer is: %d\n",
   4108   1.1     pooka 		    le32toh(cmd->ba_escape_timer)));
   4109   1.1     pooka 		DPRINTF(("bf_debug_flag is: %d\n",
   4110   1.1     pooka 		    le32toh(cmd->bf_debug_flag)));
   4111   1.1     pooka 		DPRINTF(("bf_enable_beacon_filter is: %d\n",
   4112   1.1     pooka 		    le32toh(cmd->bf_enable_beacon_filter)));
   4113   1.1     pooka 		DPRINTF(("bf_energy_delta is: %d\n",
   4114   1.1     pooka 		    le32toh(cmd->bf_energy_delta)));
   4115   1.1     pooka 		DPRINTF(("bf_escape_timer is: %d\n",
   4116   1.1     pooka 		    le32toh(cmd->bf_escape_timer)));
   4117   1.1     pooka 		DPRINTF(("bf_roaming_energy_delta is: %d\n",
   4118   1.1     pooka 		    le32toh(cmd->bf_roaming_energy_delta)));
   4119   1.1     pooka 		DPRINTF(("bf_roaming_state is: %d\n",
   4120   1.1     pooka 		    le32toh(cmd->bf_roaming_state)));
   4121   1.1     pooka 		DPRINTF(("bf_temp_threshold is: %d\n",
   4122   1.1     pooka 		    le32toh(cmd->bf_temp_threshold)));
   4123   1.1     pooka 		DPRINTF(("bf_temp_fast_filter is: %d\n",
   4124   1.1     pooka 		    le32toh(cmd->bf_temp_fast_filter)));
   4125   1.1     pooka 		DPRINTF(("bf_temp_slow_filter is: %d\n",
   4126   1.1     pooka 		    le32toh(cmd->bf_temp_slow_filter)));
   4127   1.1     pooka 	}
   4128   1.1     pooka 	return ret;
   4129   1.1     pooka }
   4130   1.1     pooka 
   4131   1.4    nonaka static void
   4132   1.1     pooka iwm_mvm_beacon_filter_set_cqm_params(struct iwm_softc *sc,
   4133   1.1     pooka 	struct iwm_node *in, struct iwm_beacon_filter_cmd *cmd)
   4134   1.1     pooka {
   4135   1.1     pooka 	cmd->ba_enable_beacon_abort = htole32(sc->sc_bf.ba_enabled);
   4136   1.1     pooka }
   4137   1.1     pooka 
   4138   1.4    nonaka static int
   4139   1.1     pooka iwm_mvm_update_beacon_abort(struct iwm_softc *sc, struct iwm_node *in,
   4140   1.1     pooka 	int enable)
   4141   1.1     pooka {
   4142   1.1     pooka 	struct iwm_beacon_filter_cmd cmd = {
   4143   1.1     pooka 		IWM_BF_CMD_CONFIG_DEFAULTS,
   4144   1.1     pooka 		.bf_enable_beacon_filter = htole32(1),
   4145   1.1     pooka 		.ba_enable_beacon_abort = htole32(enable),
   4146   1.1     pooka 	};
   4147   1.1     pooka 
   4148   1.1     pooka 	if (!sc->sc_bf.bf_enabled)
   4149   1.1     pooka 		return 0;
   4150   1.1     pooka 
   4151   1.1     pooka 	sc->sc_bf.ba_enabled = enable;
   4152   1.1     pooka 	iwm_mvm_beacon_filter_set_cqm_params(sc, in, &cmd);
   4153   1.1     pooka 	return iwm_mvm_beacon_filter_send_cmd(sc, &cmd);
   4154   1.1     pooka }
   4155   1.1     pooka 
   4156   1.4    nonaka static void
   4157   1.1     pooka iwm_mvm_power_log(struct iwm_softc *sc, struct iwm_mac_power_cmd *cmd)
   4158   1.1     pooka {
   4159   1.1     pooka 	DPRINTF(("Sending power table command on mac id 0x%X for "
   4160   1.1     pooka 	    "power level %d, flags = 0x%X\n",
   4161   1.1     pooka 	    cmd->id_and_color, IWM_POWER_SCHEME_CAM, le16toh(cmd->flags)));
   4162   1.1     pooka 	DPRINTF(("Keep alive = %u sec\n", le16toh(cmd->keep_alive_seconds)));
   4163   1.1     pooka 
   4164   1.1     pooka 	if (!(cmd->flags & htole16(IWM_POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK))) {
   4165   1.1     pooka 		DPRINTF(("Disable power management\n"));
   4166   1.1     pooka 		return;
   4167   1.1     pooka 	}
   4168   1.1     pooka 	KASSERT(0);
   4169   1.1     pooka 
   4170   1.1     pooka #if 0
   4171   1.1     pooka 	DPRINTF(mvm, "Rx timeout = %u usec\n",
   4172   1.1     pooka 			le32_to_cpu(cmd->rx_data_timeout));
   4173   1.1     pooka 	DPRINTF(mvm, "Tx timeout = %u usec\n",
   4174   1.1     pooka 			le32_to_cpu(cmd->tx_data_timeout));
   4175   1.1     pooka 	if (cmd->flags & cpu_to_le16(IWM_POWER_FLAGS_SKIP_OVER_DTIM_MSK))
   4176   1.1     pooka 		DPRINTF(mvm, "DTIM periods to skip = %u\n",
   4177   1.1     pooka 				cmd->skip_dtim_periods);
   4178   1.1     pooka 	if (cmd->flags & cpu_to_le16(IWM_POWER_FLAGS_LPRX_ENA_MSK))
   4179   1.1     pooka 		DPRINTF(mvm, "LP RX RSSI threshold = %u\n",
   4180   1.1     pooka 				cmd->lprx_rssi_threshold);
   4181   1.1     pooka 	if (cmd->flags & cpu_to_le16(IWM_POWER_FLAGS_ADVANCE_PM_ENA_MSK)) {
   4182   1.1     pooka 		DPRINTF(mvm, "uAPSD enabled\n");
   4183   1.1     pooka 		DPRINTF(mvm, "Rx timeout (uAPSD) = %u usec\n",
   4184   1.1     pooka 				le32_to_cpu(cmd->rx_data_timeout_uapsd));
   4185   1.1     pooka 		DPRINTF(mvm, "Tx timeout (uAPSD) = %u usec\n",
   4186   1.1     pooka 				le32_to_cpu(cmd->tx_data_timeout_uapsd));
   4187   1.1     pooka 		DPRINTF(mvm, "QNDP TID = %d\n", cmd->qndp_tid);
   4188   1.1     pooka 		DPRINTF(mvm, "ACs flags = 0x%x\n", cmd->uapsd_ac_flags);
   4189   1.1     pooka 		DPRINTF(mvm, "Max SP = %d\n", cmd->uapsd_max_sp);
   4190   1.1     pooka 	}
   4191   1.1     pooka #endif
   4192   1.1     pooka }
   4193   1.1     pooka 
   4194   1.4    nonaka static void
   4195   1.1     pooka iwm_mvm_power_build_cmd(struct iwm_softc *sc, struct iwm_node *in,
   4196   1.1     pooka 	struct iwm_mac_power_cmd *cmd)
   4197   1.1     pooka {
   4198   1.1     pooka 	struct ieee80211com *ic = &sc->sc_ic;
   4199   1.1     pooka 	struct ieee80211_node *ni = &in->in_ni;
   4200   1.1     pooka 	int dtimper, dtimper_msec;
   4201   1.1     pooka 	int keep_alive;
   4202   1.1     pooka 
   4203   1.1     pooka 	cmd->id_and_color = htole32(IWM_FW_CMD_ID_AND_COLOR(in->in_id,
   4204   1.1     pooka 	    in->in_color));
   4205   1.1     pooka 	dtimper = ic->ic_dtim_period ?: 1;
   4206   1.1     pooka 
   4207   1.1     pooka 	/*
   4208   1.1     pooka 	 * Regardless of power management state the driver must set
   4209   1.1     pooka 	 * keep alive period. FW will use it for sending keep alive NDPs
   4210   1.1     pooka 	 * immediately after association. Check that keep alive period
   4211   1.1     pooka 	 * is at least 3 * DTIM
   4212   1.1     pooka 	 */
   4213   1.1     pooka 	dtimper_msec = dtimper * ni->ni_intval;
   4214   1.1     pooka 	keep_alive
   4215   1.1     pooka 	    = MAX(3 * dtimper_msec, 1000 * IWM_POWER_KEEP_ALIVE_PERIOD_SEC);
   4216   1.1     pooka 	keep_alive = roundup(keep_alive, 1000) / 1000;
   4217   1.1     pooka 	cmd->keep_alive_seconds = htole16(keep_alive);
   4218   1.1     pooka }
   4219   1.1     pooka 
   4220   1.4    nonaka static int
   4221   1.1     pooka iwm_mvm_power_mac_update_mode(struct iwm_softc *sc, struct iwm_node *in)
   4222   1.1     pooka {
   4223   1.1     pooka 	int ret;
   4224   1.1     pooka 	int ba_enable;
   4225   1.1     pooka 	struct iwm_mac_power_cmd cmd;
   4226   1.1     pooka 
   4227   1.1     pooka 	memset(&cmd, 0, sizeof(cmd));
   4228   1.1     pooka 
   4229   1.1     pooka 	iwm_mvm_power_build_cmd(sc, in, &cmd);
   4230   1.1     pooka 	iwm_mvm_power_log(sc, &cmd);
   4231   1.1     pooka 
   4232   1.1     pooka 	if ((ret = iwm_mvm_send_cmd_pdu(sc, IWM_MAC_PM_POWER_TABLE,
   4233   1.1     pooka 	    IWM_CMD_SYNC, sizeof(cmd), &cmd)) != 0)
   4234   1.1     pooka 		return ret;
   4235   1.1     pooka 
   4236   1.1     pooka 	ba_enable = !!(cmd.flags &
   4237   1.1     pooka 	    htole16(IWM_POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK));
   4238   1.1     pooka 	return iwm_mvm_update_beacon_abort(sc, in, ba_enable);
   4239   1.1     pooka }
   4240   1.1     pooka 
   4241   1.4    nonaka static int
   4242   1.1     pooka iwm_mvm_power_update_device(struct iwm_softc *sc)
   4243   1.1     pooka {
   4244   1.1     pooka 	struct iwm_device_power_cmd cmd = {
   4245   1.1     pooka 		.flags = htole16(IWM_DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK),
   4246   1.1     pooka 	};
   4247   1.1     pooka 
   4248   1.1     pooka 	if (!(sc->sc_capaflags & IWM_UCODE_TLV_FLAGS_DEVICE_PS_CMD))
   4249   1.1     pooka 		return 0;
   4250   1.1     pooka 
   4251   1.1     pooka 	cmd.flags |= htole16(IWM_DEVICE_POWER_FLAGS_CAM_MSK);
   4252   1.1     pooka 	DPRINTF(("Sending device power command with flags = 0x%X\n", cmd.flags));
   4253   1.1     pooka 
   4254   1.1     pooka 	return iwm_mvm_send_cmd_pdu(sc,
   4255   1.1     pooka 	    IWM_POWER_TABLE_CMD, IWM_CMD_SYNC, sizeof(cmd), &cmd);
   4256   1.1     pooka }
   4257   1.1     pooka 
   4258   1.4    nonaka static int
   4259   1.1     pooka iwm_mvm_enable_beacon_filter(struct iwm_softc *sc, struct iwm_node *in)
   4260   1.1     pooka {
   4261   1.1     pooka 	struct iwm_beacon_filter_cmd cmd = {
   4262   1.1     pooka 		IWM_BF_CMD_CONFIG_DEFAULTS,
   4263   1.1     pooka 		.bf_enable_beacon_filter = htole32(1),
   4264   1.1     pooka 	};
   4265   1.1     pooka 	int ret;
   4266   1.1     pooka 
   4267   1.1     pooka 	iwm_mvm_beacon_filter_set_cqm_params(sc, in, &cmd);
   4268   1.1     pooka 	ret = iwm_mvm_beacon_filter_send_cmd(sc, &cmd);
   4269   1.1     pooka 
   4270   1.1     pooka 	if (ret == 0)
   4271   1.1     pooka 		sc->sc_bf.bf_enabled = 1;
   4272   1.1     pooka 
   4273   1.1     pooka 	return ret;
   4274   1.1     pooka }
   4275   1.1     pooka 
   4276   1.4    nonaka static int
   4277   1.1     pooka iwm_mvm_disable_beacon_filter(struct iwm_softc *sc, struct iwm_node *in)
   4278   1.1     pooka {
   4279   1.1     pooka 	struct iwm_beacon_filter_cmd cmd;
   4280   1.1     pooka 	int ret;
   4281   1.1     pooka 
   4282   1.1     pooka 	memset(&cmd, 0, sizeof(cmd));
   4283   1.1     pooka 	if ((sc->sc_capaflags & IWM_UCODE_TLV_FLAGS_BF_UPDATED) == 0)
   4284   1.1     pooka 		return 0;
   4285   1.1     pooka 
   4286   1.1     pooka 	ret = iwm_mvm_beacon_filter_send_cmd(sc, &cmd);
   4287   1.1     pooka 	if (ret == 0)
   4288   1.1     pooka 		sc->sc_bf.bf_enabled = 0;
   4289   1.1     pooka 
   4290   1.1     pooka 	return ret;
   4291   1.1     pooka }
   4292   1.1     pooka 
   4293   1.1     pooka #if 0
   4294   1.4    nonaka static int
   4295   1.1     pooka iwm_mvm_update_beacon_filter(struct iwm_softc *sc, struct iwm_node *in)
   4296   1.1     pooka {
   4297   1.1     pooka 	if (!sc->sc_bf.bf_enabled)
   4298   1.1     pooka 		return 0;
   4299   1.1     pooka 
   4300   1.1     pooka 	return iwm_mvm_enable_beacon_filter(sc, in);
   4301   1.1     pooka }
   4302   1.1     pooka #endif
   4303   1.1     pooka 
   4304   1.1     pooka /*
   4305   1.1     pooka  * END mvm/power.c
   4306   1.1     pooka  */
   4307   1.1     pooka 
   4308   1.1     pooka /*
   4309   1.1     pooka  * BEGIN mvm/sta.c
   4310   1.1     pooka  */
   4311   1.1     pooka 
   4312   1.4    nonaka static void
   4313   1.1     pooka iwm_mvm_add_sta_cmd_v6_to_v5(struct iwm_mvm_add_sta_cmd_v6 *cmd_v6,
   4314   1.1     pooka 	struct iwm_mvm_add_sta_cmd_v5 *cmd_v5)
   4315   1.1     pooka {
   4316   1.1     pooka 	memset(cmd_v5, 0, sizeof(*cmd_v5));
   4317   1.1     pooka 
   4318   1.1     pooka 	cmd_v5->add_modify = cmd_v6->add_modify;
   4319   1.1     pooka 	cmd_v5->tid_disable_tx = cmd_v6->tid_disable_tx;
   4320   1.1     pooka 	cmd_v5->mac_id_n_color = cmd_v6->mac_id_n_color;
   4321   1.1     pooka 	memcpy(cmd_v5->addr, cmd_v6->addr, ETHER_ADDR_LEN);
   4322   1.1     pooka 	cmd_v5->sta_id = cmd_v6->sta_id;
   4323   1.1     pooka 	cmd_v5->modify_mask = cmd_v6->modify_mask;
   4324   1.1     pooka 	cmd_v5->station_flags = cmd_v6->station_flags;
   4325   1.1     pooka 	cmd_v5->station_flags_msk = cmd_v6->station_flags_msk;
   4326   1.1     pooka 	cmd_v5->add_immediate_ba_tid = cmd_v6->add_immediate_ba_tid;
   4327   1.1     pooka 	cmd_v5->remove_immediate_ba_tid = cmd_v6->remove_immediate_ba_tid;
   4328   1.1     pooka 	cmd_v5->add_immediate_ba_ssn = cmd_v6->add_immediate_ba_ssn;
   4329   1.1     pooka 	cmd_v5->sleep_tx_count = cmd_v6->sleep_tx_count;
   4330   1.1     pooka 	cmd_v5->sleep_state_flags = cmd_v6->sleep_state_flags;
   4331   1.1     pooka 	cmd_v5->assoc_id = cmd_v6->assoc_id;
   4332   1.1     pooka 	cmd_v5->beamform_flags = cmd_v6->beamform_flags;
   4333   1.1     pooka 	cmd_v5->tfd_queue_msk = cmd_v6->tfd_queue_msk;
   4334   1.1     pooka }
   4335   1.1     pooka 
   4336   1.4    nonaka static int
   4337   1.1     pooka iwm_mvm_send_add_sta_cmd_status(struct iwm_softc *sc,
   4338   1.1     pooka 	struct iwm_mvm_add_sta_cmd_v6 *cmd, int *status)
   4339   1.1     pooka {
   4340   1.1     pooka 	struct iwm_mvm_add_sta_cmd_v5 cmd_v5;
   4341   1.1     pooka 
   4342   1.1     pooka 	if (sc->sc_capaflags & IWM_UCODE_TLV_FLAGS_STA_KEY_CMD) {
   4343   1.1     pooka 		return iwm_mvm_send_cmd_pdu_status(sc, IWM_ADD_STA,
   4344   1.1     pooka 		    sizeof(*cmd), cmd, status);
   4345   1.1     pooka 	}
   4346   1.1     pooka 
   4347   1.1     pooka 	iwm_mvm_add_sta_cmd_v6_to_v5(cmd, &cmd_v5);
   4348   1.1     pooka 
   4349   1.1     pooka 	return iwm_mvm_send_cmd_pdu_status(sc, IWM_ADD_STA, sizeof(cmd_v5),
   4350   1.1     pooka 	    &cmd_v5, status);
   4351   1.1     pooka }
   4352   1.1     pooka 
   4353   1.1     pooka /* send station add/update command to firmware */
   4354   1.4    nonaka static int
   4355   1.1     pooka iwm_mvm_sta_send_to_fw(struct iwm_softc *sc, struct iwm_node *in, int update)
   4356   1.1     pooka {
   4357   1.1     pooka 	struct iwm_mvm_add_sta_cmd_v6 add_sta_cmd;
   4358   1.1     pooka 	int ret;
   4359   1.1     pooka 	uint32_t status;
   4360   1.1     pooka 
   4361   1.1     pooka 	memset(&add_sta_cmd, 0, sizeof(add_sta_cmd));
   4362   1.1     pooka 
   4363   1.1     pooka 	add_sta_cmd.sta_id = IWM_STATION_ID;
   4364   1.1     pooka 	add_sta_cmd.mac_id_n_color
   4365   1.1     pooka 	    = htole32(IWM_FW_CMD_ID_AND_COLOR(in->in_id, in->in_color));
   4366   1.1     pooka 	if (!update) {
   4367   1.1     pooka 		add_sta_cmd.tfd_queue_msk = htole32(0xf);
   4368   1.1     pooka 		IEEE80211_ADDR_COPY(&add_sta_cmd.addr, in->in_ni.ni_bssid);
   4369   1.1     pooka 	}
   4370   1.1     pooka 	add_sta_cmd.add_modify = update ? 1 : 0;
   4371   1.1     pooka 	add_sta_cmd.station_flags_msk
   4372   1.1     pooka 	    |= htole32(IWM_STA_FLG_FAT_EN_MSK | IWM_STA_FLG_MIMO_EN_MSK);
   4373   1.1     pooka 
   4374   1.1     pooka 	status = IWM_ADD_STA_SUCCESS;
   4375   1.1     pooka 	ret = iwm_mvm_send_add_sta_cmd_status(sc, &add_sta_cmd, &status);
   4376   1.1     pooka 	if (ret)
   4377   1.1     pooka 		return ret;
   4378   1.1     pooka 
   4379   1.1     pooka 	switch (status) {
   4380   1.1     pooka 	case IWM_ADD_STA_SUCCESS:
   4381   1.1     pooka 		break;
   4382   1.1     pooka 	default:
   4383   1.1     pooka 		ret = EIO;
   4384   1.1     pooka 		DPRINTF(("IWM_ADD_STA failed\n"));
   4385   1.1     pooka 		break;
   4386   1.1     pooka 	}
   4387   1.1     pooka 
   4388   1.1     pooka 	return ret;
   4389   1.1     pooka }
   4390   1.1     pooka 
   4391   1.4    nonaka static int
   4392   1.1     pooka iwm_mvm_add_sta(struct iwm_softc *sc, struct iwm_node *in)
   4393   1.1     pooka {
   4394   1.1     pooka 	int ret;
   4395   1.1     pooka 
   4396   1.1     pooka 	ret = iwm_mvm_sta_send_to_fw(sc, in, 0);
   4397   1.1     pooka 	if (ret)
   4398   1.1     pooka 		return ret;
   4399   1.1     pooka 
   4400   1.1     pooka 	return 0;
   4401   1.1     pooka }
   4402   1.1     pooka 
   4403   1.4    nonaka static int
   4404   1.1     pooka iwm_mvm_update_sta(struct iwm_softc *sc, struct iwm_node *in)
   4405   1.1     pooka {
   4406   1.1     pooka 	return iwm_mvm_sta_send_to_fw(sc, in, 1);
   4407   1.1     pooka }
   4408   1.1     pooka 
   4409   1.4    nonaka static int
   4410   1.1     pooka iwm_mvm_add_int_sta_common(struct iwm_softc *sc, struct iwm_int_sta *sta,
   4411   1.1     pooka 	const uint8_t *addr, uint16_t mac_id, uint16_t color)
   4412   1.1     pooka {
   4413   1.1     pooka 	struct iwm_mvm_add_sta_cmd_v6 cmd;
   4414   1.1     pooka 	int ret;
   4415   1.1     pooka 	uint32_t status;
   4416   1.1     pooka 
   4417   1.1     pooka 	memset(&cmd, 0, sizeof(cmd));
   4418   1.1     pooka 	cmd.sta_id = sta->sta_id;
   4419   1.1     pooka 	cmd.mac_id_n_color = htole32(IWM_FW_CMD_ID_AND_COLOR(mac_id, color));
   4420   1.1     pooka 
   4421   1.1     pooka 	cmd.tfd_queue_msk = htole32(sta->tfd_queue_msk);
   4422   1.1     pooka 
   4423   1.1     pooka 	if (addr)
   4424   1.1     pooka 		memcpy(cmd.addr, addr, ETHER_ADDR_LEN);
   4425   1.1     pooka 
   4426   1.1     pooka 	ret = iwm_mvm_send_add_sta_cmd_status(sc, &cmd, &status);
   4427   1.1     pooka 	if (ret)
   4428   1.1     pooka 		return ret;
   4429   1.1     pooka 
   4430   1.1     pooka 	switch (status) {
   4431   1.1     pooka 	case IWM_ADD_STA_SUCCESS:
   4432   1.1     pooka 		DPRINTF(("Internal station added.\n"));
   4433   1.1     pooka 		return 0;
   4434   1.1     pooka 	default:
   4435   1.2    nonaka 		DPRINTF(("%s: Add internal station failed, status=0x%x\n",
   4436   1.2    nonaka 		    DEVNAME(sc), status));
   4437   1.1     pooka 		ret = EIO;
   4438   1.1     pooka 		break;
   4439   1.1     pooka 	}
   4440   1.1     pooka 	return ret;
   4441   1.1     pooka }
   4442   1.1     pooka 
   4443   1.4    nonaka static int
   4444   1.1     pooka iwm_mvm_add_aux_sta(struct iwm_softc *sc)
   4445   1.1     pooka {
   4446   1.1     pooka 	int ret;
   4447   1.1     pooka 
   4448   1.1     pooka 	sc->sc_aux_sta.sta_id = 3;
   4449   1.1     pooka 	sc->sc_aux_sta.tfd_queue_msk = 0;
   4450   1.1     pooka 
   4451   1.1     pooka 	ret = iwm_mvm_add_int_sta_common(sc,
   4452   1.1     pooka 	    &sc->sc_aux_sta, NULL, IWM_MAC_INDEX_AUX, 0);
   4453   1.1     pooka 
   4454   1.1     pooka 	if (ret)
   4455   1.1     pooka 		memset(&sc->sc_aux_sta, 0, sizeof(sc->sc_aux_sta));
   4456   1.1     pooka 	return ret;
   4457   1.1     pooka }
   4458   1.1     pooka 
   4459   1.1     pooka /*
   4460   1.1     pooka  * END mvm/sta.c
   4461   1.1     pooka  */
   4462   1.1     pooka 
   4463   1.1     pooka /*
   4464   1.1     pooka  * BEGIN mvm/scan.c
   4465   1.1     pooka  */
   4466   1.1     pooka 
   4467   1.1     pooka #define IWM_PLCP_QUIET_THRESH 1
   4468   1.1     pooka #define IWM_ACTIVE_QUIET_TIME 10
   4469   1.1     pooka #define LONG_OUT_TIME_PERIOD 600
   4470   1.1     pooka #define SHORT_OUT_TIME_PERIOD 200
   4471   1.1     pooka #define SUSPEND_TIME_PERIOD 100
   4472   1.1     pooka 
   4473   1.4    nonaka static uint16_t
   4474   1.1     pooka iwm_mvm_scan_rx_chain(struct iwm_softc *sc)
   4475   1.1     pooka {
   4476   1.1     pooka 	uint16_t rx_chain;
   4477   1.1     pooka 	uint8_t rx_ant;
   4478   1.1     pooka 
   4479   1.1     pooka 	rx_ant = IWM_FW_VALID_RX_ANT(sc);
   4480   1.1     pooka 	rx_chain = rx_ant << IWM_PHY_RX_CHAIN_VALID_POS;
   4481   1.1     pooka 	rx_chain |= rx_ant << IWM_PHY_RX_CHAIN_FORCE_MIMO_SEL_POS;
   4482   1.1     pooka 	rx_chain |= rx_ant << IWM_PHY_RX_CHAIN_FORCE_SEL_POS;
   4483   1.1     pooka 	rx_chain |= 0x1 << IWM_PHY_RX_CHAIN_DRIVER_FORCE_POS;
   4484   1.1     pooka 	return htole16(rx_chain);
   4485   1.1     pooka }
   4486   1.1     pooka 
   4487   1.1     pooka #define ieee80211_tu_to_usec(a) (1024*(a))
   4488   1.1     pooka 
   4489   1.4    nonaka static uint32_t
   4490   1.1     pooka iwm_mvm_scan_max_out_time(struct iwm_softc *sc, uint32_t flags, int is_assoc)
   4491   1.1     pooka {
   4492   1.1     pooka 	if (!is_assoc)
   4493   1.1     pooka 		return 0;
   4494   1.1     pooka 	if (flags & 0x1)
   4495   1.1     pooka 		return htole32(ieee80211_tu_to_usec(SHORT_OUT_TIME_PERIOD));
   4496   1.1     pooka 	return htole32(ieee80211_tu_to_usec(LONG_OUT_TIME_PERIOD));
   4497   1.1     pooka }
   4498   1.1     pooka 
   4499   1.4    nonaka static uint32_t
   4500   1.1     pooka iwm_mvm_scan_suspend_time(struct iwm_softc *sc, int is_assoc)
   4501   1.1     pooka {
   4502   1.1     pooka 	if (!is_assoc)
   4503   1.1     pooka 		return 0;
   4504   1.1     pooka 	return htole32(ieee80211_tu_to_usec(SUSPEND_TIME_PERIOD));
   4505   1.1     pooka }
   4506   1.1     pooka 
   4507   1.4    nonaka static uint32_t
   4508   1.1     pooka iwm_mvm_scan_rxon_flags(struct iwm_softc *sc, int flags)
   4509   1.1     pooka {
   4510   1.1     pooka 	if (flags & IEEE80211_CHAN_2GHZ)
   4511   1.1     pooka 		return htole32(IWM_PHY_BAND_24);
   4512   1.1     pooka 	else
   4513   1.1     pooka 		return htole32(IWM_PHY_BAND_5);
   4514   1.1     pooka }
   4515   1.1     pooka 
   4516   1.4    nonaka static uint32_t
   4517   1.1     pooka iwm_mvm_scan_rate_n_flags(struct iwm_softc *sc, int flags, int no_cck)
   4518   1.1     pooka {
   4519   1.1     pooka 	uint32_t tx_ant;
   4520   1.1     pooka 	int i, ind;
   4521   1.1     pooka 
   4522   1.1     pooka 	for (i = 0, ind = sc->sc_scan_last_antenna;
   4523   1.1     pooka 	    i < IWM_RATE_MCS_ANT_NUM; i++) {
   4524   1.1     pooka 		ind = (ind + 1) % IWM_RATE_MCS_ANT_NUM;
   4525   1.1     pooka 		if (IWM_FW_VALID_TX_ANT(sc) & (1 << ind)) {
   4526   1.1     pooka 			sc->sc_scan_last_antenna = ind;
   4527   1.1     pooka 			break;
   4528   1.1     pooka 		}
   4529   1.1     pooka 	}
   4530   1.1     pooka 	tx_ant = (1 << sc->sc_scan_last_antenna) << IWM_RATE_MCS_ANT_POS;
   4531   1.1     pooka 
   4532   1.1     pooka 	if ((flags & IEEE80211_CHAN_2GHZ) && !no_cck)
   4533   1.1     pooka 		return htole32(IWM_RATE_1M_PLCP | IWM_RATE_MCS_CCK_MSK |
   4534   1.1     pooka 				   tx_ant);
   4535   1.1     pooka 	else
   4536   1.1     pooka 		return htole32(IWM_RATE_6M_PLCP | tx_ant);
   4537   1.1     pooka }
   4538   1.1     pooka 
   4539   1.1     pooka /*
   4540   1.1     pooka  * If req->n_ssids > 0, it means we should do an active scan.
   4541   1.1     pooka  * In case of active scan w/o directed scan, we receive a zero-length SSID
   4542   1.1     pooka  * just to notify that this scan is active and not passive.
   4543   1.1     pooka  * In order to notify the FW of the number of SSIDs we wish to scan (including
   4544   1.1     pooka  * the zero-length one), we need to set the corresponding bits in chan->type,
   4545   1.1     pooka  * one for each SSID, and set the active bit (first). If the first SSID is
   4546   1.1     pooka  * already included in the probe template, so we need to set only
   4547   1.1     pooka  * req->n_ssids - 1 bits in addition to the first bit.
   4548   1.1     pooka  */
   4549   1.4    nonaka static uint16_t
   4550   1.1     pooka iwm_mvm_get_active_dwell(struct iwm_softc *sc, int flags, int n_ssids)
   4551   1.1     pooka {
   4552   1.1     pooka 	if (flags & IEEE80211_CHAN_2GHZ)
   4553   1.1     pooka 		return 30  + 3 * (n_ssids + 1);
   4554   1.1     pooka 	return 20  + 2 * (n_ssids + 1);
   4555   1.1     pooka }
   4556   1.1     pooka 
   4557   1.4    nonaka static uint16_t
   4558   1.1     pooka iwm_mvm_get_passive_dwell(struct iwm_softc *sc, int flags)
   4559   1.1     pooka {
   4560   1.1     pooka 	return (flags & IEEE80211_CHAN_2GHZ) ? 100 + 20 : 100 + 10;
   4561   1.1     pooka }
   4562   1.1     pooka 
   4563   1.4    nonaka static int
   4564   1.1     pooka iwm_mvm_scan_fill_channels(struct iwm_softc *sc, struct iwm_scan_cmd *cmd,
   4565   1.1     pooka 	int flags, int n_ssids, int basic_ssid)
   4566   1.1     pooka {
   4567   1.1     pooka 	struct ieee80211com *ic = &sc->sc_ic;
   4568   1.1     pooka 	uint16_t passive_dwell = iwm_mvm_get_passive_dwell(sc, flags);
   4569   1.1     pooka 	uint16_t active_dwell = iwm_mvm_get_active_dwell(sc, flags, n_ssids);
   4570   1.1     pooka 	struct iwm_scan_channel *chan = (struct iwm_scan_channel *)
   4571   1.1     pooka 		(cmd->data + le16toh(cmd->tx_cmd.len));
   4572   1.1     pooka 	int type = (1 << n_ssids) - 1;
   4573   1.1     pooka 	struct ieee80211_channel *c;
   4574   1.1     pooka 	int nchan;
   4575   1.1     pooka 
   4576   1.1     pooka 	if (!basic_ssid)
   4577   1.1     pooka 		type |= (1 << n_ssids);
   4578   1.1     pooka 
   4579   1.1     pooka 	for (nchan = 0, c = &ic->ic_channels[1];
   4580   1.1     pooka 	    c <= &ic->ic_channels[IEEE80211_CHAN_MAX];
   4581   1.1     pooka 	    c++) {
   4582   1.1     pooka 		if ((c->ic_flags & flags) != flags)
   4583   1.1     pooka 			continue;
   4584   1.1     pooka 
   4585   1.1     pooka 		chan->channel = htole16(ieee80211_mhz2ieee(c->ic_freq, flags));
   4586   1.1     pooka 		chan->type = htole32(type);
   4587   1.1     pooka 		if (c->ic_flags & IEEE80211_CHAN_PASSIVE)
   4588   1.1     pooka 			chan->type &= htole32(~IWM_SCAN_CHANNEL_TYPE_ACTIVE);
   4589   1.1     pooka 		chan->active_dwell = htole16(active_dwell);
   4590   1.1     pooka 		chan->passive_dwell = htole16(passive_dwell);
   4591   1.1     pooka 		chan->iteration_count = htole16(1);
   4592   1.1     pooka 		chan++;
   4593   1.1     pooka 		nchan++;
   4594   1.1     pooka 	}
   4595   1.1     pooka 	if (nchan == 0)
   4596   1.2    nonaka 		DPRINTF(("%s: NO CHANNEL!\n", DEVNAME(sc)));
   4597   1.1     pooka 	return nchan;
   4598   1.1     pooka }
   4599   1.1     pooka 
   4600   1.1     pooka /*
   4601   1.1     pooka  * Fill in probe request with the following parameters:
   4602   1.1     pooka  * TA is our vif HW address, which mac80211 ensures we have.
   4603   1.1     pooka  * Packet is broadcasted, so this is both SA and DA.
   4604   1.1     pooka  * The probe request IE is made out of two: first comes the most prioritized
   4605   1.1     pooka  * SSID if a directed scan is requested. Second comes whatever extra
   4606   1.1     pooka  * information was given to us as the scan request IE.
   4607   1.1     pooka  */
   4608   1.4    nonaka static uint16_t
   4609   1.1     pooka iwm_mvm_fill_probe_req(struct iwm_softc *sc, struct ieee80211_frame *frame,
   4610   1.1     pooka 	const uint8_t *ta, int n_ssids, const uint8_t *ssid, int ssid_len,
   4611   1.1     pooka 	const uint8_t *ie, int ie_len, int left)
   4612   1.1     pooka {
   4613   1.1     pooka 	int len = 0;
   4614   1.1     pooka 	uint8_t *pos = NULL;
   4615   1.1     pooka 
   4616   1.1     pooka 	/* Make sure there is enough space for the probe request,
   4617   1.1     pooka 	 * two mandatory IEs and the data */
   4618   1.1     pooka 	left -= sizeof(*frame);
   4619   1.1     pooka 	if (left < 0)
   4620   1.1     pooka 		return 0;
   4621   1.1     pooka 
   4622   1.1     pooka 	frame->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT |
   4623   1.1     pooka 	    IEEE80211_FC0_SUBTYPE_PROBE_REQ;
   4624   1.1     pooka 	frame->i_fc[1] = IEEE80211_FC1_DIR_NODS;
   4625   1.1     pooka 	IEEE80211_ADDR_COPY(frame->i_addr1, etherbroadcastaddr);
   4626   1.1     pooka 	memcpy(frame->i_addr2, ta, ETHER_ADDR_LEN);
   4627   1.1     pooka 	IEEE80211_ADDR_COPY(frame->i_addr3, etherbroadcastaddr);
   4628   1.1     pooka 
   4629   1.1     pooka 	len += sizeof(*frame);
   4630   1.1     pooka 	CTASSERT(sizeof(*frame) == 24);
   4631   1.1     pooka 
   4632   1.1     pooka 	/* for passive scans, no need to fill anything */
   4633   1.1     pooka 	if (n_ssids == 0)
   4634   1.1     pooka 		return (uint16_t)len;
   4635   1.1     pooka 
   4636   1.1     pooka 	/* points to the payload of the request */
   4637   1.1     pooka 	pos = (uint8_t *)frame + sizeof(*frame);
   4638   1.1     pooka 
   4639   1.1     pooka 	/* fill in our SSID IE */
   4640   1.1     pooka 	left -= ssid_len + 2;
   4641   1.1     pooka 	if (left < 0)
   4642   1.1     pooka 		return 0;
   4643   1.1     pooka 	*pos++ = IEEE80211_ELEMID_SSID;
   4644   1.1     pooka 	*pos++ = ssid_len;
   4645   1.1     pooka 	if (ssid && ssid_len) { /* ssid_len may be == 0 even if ssid is valid */
   4646   1.1     pooka 		memcpy(pos, ssid, ssid_len);
   4647   1.1     pooka 		pos += ssid_len;
   4648   1.1     pooka 	}
   4649   1.1     pooka 
   4650   1.1     pooka 	len += ssid_len + 2;
   4651   1.1     pooka 
   4652   1.1     pooka 	if (left < ie_len)
   4653   1.1     pooka 		return len;
   4654   1.1     pooka 
   4655   1.1     pooka 	if (ie && ie_len) {
   4656   1.1     pooka 		memcpy(pos, ie, ie_len);
   4657   1.1     pooka 		len += ie_len;
   4658   1.1     pooka 	}
   4659   1.1     pooka 
   4660   1.1     pooka 	return (uint16_t)len;
   4661   1.1     pooka }
   4662   1.1     pooka 
   4663   1.4    nonaka static int
   4664   1.1     pooka iwm_mvm_scan_request(struct iwm_softc *sc, int flags,
   4665   1.1     pooka 	int n_ssids, uint8_t *ssid, int ssid_len)
   4666   1.1     pooka {
   4667   1.1     pooka 	struct ieee80211com *ic = &sc->sc_ic;
   4668   1.1     pooka 	struct iwm_host_cmd hcmd = {
   4669   1.1     pooka 		.id = IWM_SCAN_REQUEST_CMD,
   4670   1.1     pooka 		.len = { 0, },
   4671   1.1     pooka 		.data = { sc->sc_scan_cmd, },
   4672   1.1     pooka 		.flags = IWM_CMD_SYNC,
   4673   1.1     pooka 		.dataflags = { IWM_HCMD_DFL_NOCOPY, },
   4674   1.1     pooka 	};
   4675   1.1     pooka 	struct iwm_scan_cmd *cmd = sc->sc_scan_cmd;
   4676   1.1     pooka 	int is_assoc = 0;
   4677   1.1     pooka 	int ret;
   4678   1.1     pooka 	uint32_t status;
   4679   1.1     pooka 	int basic_ssid = !(sc->sc_capaflags & IWM_UCODE_TLV_FLAGS_NO_BASIC_SSID);
   4680   1.1     pooka 
   4681   1.1     pooka 	//lockdep_assert_held(&mvm->mutex);
   4682   1.1     pooka 
   4683   1.1     pooka 	sc->sc_scanband = flags & (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_5GHZ);
   4684   1.1     pooka 
   4685   1.1     pooka 	DPRINTF(("Handling ieee80211 scan request\n"));
   4686   1.1     pooka 	memset(cmd, 0, sc->sc_scan_cmd_len);
   4687   1.1     pooka 
   4688   1.1     pooka 	cmd->quiet_time = htole16(IWM_ACTIVE_QUIET_TIME);
   4689   1.1     pooka 	cmd->quiet_plcp_th = htole16(IWM_PLCP_QUIET_THRESH);
   4690   1.1     pooka 	cmd->rxchain_sel_flags = iwm_mvm_scan_rx_chain(sc);
   4691   1.1     pooka 	cmd->max_out_time = iwm_mvm_scan_max_out_time(sc, 0, is_assoc);
   4692   1.1     pooka 	cmd->suspend_time = iwm_mvm_scan_suspend_time(sc, is_assoc);
   4693   1.1     pooka 	cmd->rxon_flags = iwm_mvm_scan_rxon_flags(sc, flags);
   4694   1.1     pooka 	cmd->filter_flags = htole32(IWM_MAC_FILTER_ACCEPT_GRP |
   4695   1.1     pooka 	    IWM_MAC_FILTER_IN_BEACON);
   4696   1.1     pooka 
   4697   1.1     pooka 	cmd->type = htole32(IWM_SCAN_TYPE_FORCED);
   4698   1.1     pooka 	cmd->repeats = htole32(1);
   4699   1.1     pooka 
   4700   1.1     pooka 	/*
   4701   1.1     pooka 	 * If the user asked for passive scan, don't change to active scan if
   4702   1.1     pooka 	 * you see any activity on the channel - remain passive.
   4703   1.1     pooka 	 */
   4704   1.1     pooka 	if (n_ssids > 0) {
   4705   1.1     pooka 		cmd->passive2active = htole16(1);
   4706   1.1     pooka 		cmd->scan_flags |= IWM_SCAN_FLAGS_PASSIVE2ACTIVE;
   4707   1.1     pooka #if 0
   4708   1.1     pooka 		if (basic_ssid) {
   4709   1.1     pooka 			ssid = req->ssids[0].ssid;
   4710   1.1     pooka 			ssid_len = req->ssids[0].ssid_len;
   4711   1.1     pooka 		}
   4712   1.1     pooka #endif
   4713   1.1     pooka 	} else {
   4714   1.1     pooka 		cmd->passive2active = 0;
   4715   1.1     pooka 		cmd->scan_flags &= ~IWM_SCAN_FLAGS_PASSIVE2ACTIVE;
   4716   1.1     pooka 	}
   4717   1.1     pooka 
   4718   1.1     pooka 	cmd->tx_cmd.tx_flags = htole32(IWM_TX_CMD_FLG_SEQ_CTL |
   4719   1.1     pooka 	    IWM_TX_CMD_FLG_BT_DIS);
   4720   1.1     pooka 	cmd->tx_cmd.sta_id = sc->sc_aux_sta.sta_id;
   4721   1.1     pooka 	cmd->tx_cmd.life_time = htole32(IWM_TX_CMD_LIFE_TIME_INFINITE);
   4722   1.1     pooka 	cmd->tx_cmd.rate_n_flags = iwm_mvm_scan_rate_n_flags(sc, flags, 1/*XXX*/);
   4723   1.1     pooka 
   4724   1.1     pooka 	cmd->tx_cmd.len = htole16(iwm_mvm_fill_probe_req(sc,
   4725   1.1     pooka 			    (struct ieee80211_frame *)cmd->data,
   4726   1.1     pooka 			    ic->ic_myaddr, n_ssids, ssid, ssid_len,
   4727   1.1     pooka 			    NULL, 0, sc->sc_capa_max_probe_len));
   4728   1.1     pooka 
   4729   1.1     pooka 	cmd->channel_count
   4730   1.1     pooka 	    = iwm_mvm_scan_fill_channels(sc, cmd, flags, n_ssids, basic_ssid);
   4731   1.1     pooka 
   4732   1.1     pooka 	cmd->len = htole16(sizeof(struct iwm_scan_cmd) +
   4733   1.1     pooka 		le16toh(cmd->tx_cmd.len) +
   4734   1.1     pooka 		(cmd->channel_count * sizeof(struct iwm_scan_channel)));
   4735   1.1     pooka 	hcmd.len[0] = le16toh(cmd->len);
   4736   1.1     pooka 
   4737   1.1     pooka 	status = IWM_SCAN_RESPONSE_OK;
   4738   1.1     pooka 	ret = iwm_mvm_send_cmd_status(sc, &hcmd, &status);
   4739   1.1     pooka 	if (!ret && status == IWM_SCAN_RESPONSE_OK) {
   4740   1.1     pooka 		DPRINTF(("Scan request was sent successfully\n"));
   4741   1.1     pooka 	} else {
   4742   1.1     pooka 		/*
   4743   1.1     pooka 		 * If the scan failed, it usually means that the FW was unable
   4744   1.1     pooka 		 * to allocate the time events. Warn on it, but maybe we
   4745   1.1     pooka 		 * should try to send the command again with different params.
   4746   1.1     pooka 		 */
   4747   1.1     pooka 		sc->sc_scanband = 0;
   4748   1.1     pooka 		ret = EIO;
   4749   1.1     pooka 	}
   4750   1.1     pooka 	return ret;
   4751   1.1     pooka }
   4752   1.1     pooka 
   4753   1.1     pooka /*
   4754   1.1     pooka  * END mvm/scan.c
   4755   1.1     pooka  */
   4756   1.1     pooka 
   4757   1.1     pooka /*
   4758   1.1     pooka  * BEGIN mvm/mac-ctxt.c
   4759   1.1     pooka  */
   4760   1.1     pooka 
   4761   1.4    nonaka static void
   4762   1.1     pooka iwm_mvm_ack_rates(struct iwm_softc *sc, struct iwm_node *in,
   4763   1.1     pooka 	int *cck_rates, int *ofdm_rates)
   4764   1.1     pooka {
   4765  1.24    nonaka 	struct ieee80211_node *ni = &in->in_ni;
   4766   1.1     pooka 	int lowest_present_ofdm = 100;
   4767   1.1     pooka 	int lowest_present_cck = 100;
   4768   1.1     pooka 	uint8_t cck = 0;
   4769   1.1     pooka 	uint8_t ofdm = 0;
   4770   1.1     pooka 	int i;
   4771   1.1     pooka 
   4772  1.24    nonaka 	if (IEEE80211_IS_CHAN_2GHZ(ni->ni_chan)) {
   4773  1.24    nonaka 		for (i = 0; i <= IWM_LAST_CCK_RATE; i++) {
   4774  1.24    nonaka 			cck |= (1 << i);
   4775  1.24    nonaka 			if (lowest_present_cck > i)
   4776  1.24    nonaka 				lowest_present_cck = i;
   4777  1.24    nonaka 		}
   4778   1.1     pooka 	}
   4779   1.1     pooka 	for (i = IWM_FIRST_OFDM_RATE; i <= IWM_LAST_NON_HT_RATE; i++) {
   4780   1.1     pooka 		int adj = i - IWM_FIRST_OFDM_RATE;
   4781   1.1     pooka 		ofdm |= (1 << adj);
   4782  1.20    nonaka 		if (lowest_present_ofdm > i)
   4783  1.20    nonaka 			lowest_present_ofdm = i;
   4784   1.1     pooka 	}
   4785   1.1     pooka 
   4786   1.1     pooka 	/*
   4787   1.1     pooka 	 * Now we've got the basic rates as bitmaps in the ofdm and cck
   4788   1.1     pooka 	 * variables. This isn't sufficient though, as there might not
   4789   1.1     pooka 	 * be all the right rates in the bitmap. E.g. if the only basic
   4790   1.1     pooka 	 * rates are 5.5 Mbps and 11 Mbps, we still need to add 1 Mbps
   4791   1.1     pooka 	 * and 6 Mbps because the 802.11-2007 standard says in 9.6:
   4792   1.1     pooka 	 *
   4793   1.1     pooka 	 *    [...] a STA responding to a received frame shall transmit
   4794   1.1     pooka 	 *    its Control Response frame [...] at the highest rate in the
   4795   1.1     pooka 	 *    BSSBasicRateSet parameter that is less than or equal to the
   4796   1.1     pooka 	 *    rate of the immediately previous frame in the frame exchange
   4797   1.1     pooka 	 *    sequence ([...]) and that is of the same modulation class
   4798   1.1     pooka 	 *    ([...]) as the received frame. If no rate contained in the
   4799   1.1     pooka 	 *    BSSBasicRateSet parameter meets these conditions, then the
   4800   1.1     pooka 	 *    control frame sent in response to a received frame shall be
   4801   1.1     pooka 	 *    transmitted at the highest mandatory rate of the PHY that is
   4802   1.1     pooka 	 *    less than or equal to the rate of the received frame, and
   4803   1.1     pooka 	 *    that is of the same modulation class as the received frame.
   4804   1.1     pooka 	 *
   4805   1.1     pooka 	 * As a consequence, we need to add all mandatory rates that are
   4806   1.1     pooka 	 * lower than all of the basic rates to these bitmaps.
   4807   1.1     pooka 	 */
   4808   1.1     pooka 
   4809   1.1     pooka 	if (IWM_RATE_24M_INDEX < lowest_present_ofdm)
   4810   1.1     pooka 		ofdm |= IWM_RATE_BIT_MSK(24) >> IWM_FIRST_OFDM_RATE;
   4811   1.1     pooka 	if (IWM_RATE_12M_INDEX < lowest_present_ofdm)
   4812   1.1     pooka 		ofdm |= IWM_RATE_BIT_MSK(12) >> IWM_FIRST_OFDM_RATE;
   4813   1.1     pooka 	/* 6M already there or needed so always add */
   4814   1.1     pooka 	ofdm |= IWM_RATE_BIT_MSK(6) >> IWM_FIRST_OFDM_RATE;
   4815   1.1     pooka 
   4816   1.1     pooka 	/*
   4817   1.1     pooka 	 * CCK is a bit more complex with DSSS vs. HR/DSSS vs. ERP.
   4818   1.1     pooka 	 * Note, however:
   4819   1.1     pooka 	 *  - if no CCK rates are basic, it must be ERP since there must
   4820   1.1     pooka 	 *    be some basic rates at all, so they're OFDM => ERP PHY
   4821   1.1     pooka 	 *    (or we're in 5 GHz, and the cck bitmap will never be used)
   4822   1.1     pooka 	 *  - if 11M is a basic rate, it must be ERP as well, so add 5.5M
   4823   1.1     pooka 	 *  - if 5.5M is basic, 1M and 2M are mandatory
   4824   1.1     pooka 	 *  - if 2M is basic, 1M is mandatory
   4825   1.1     pooka 	 *  - if 1M is basic, that's the only valid ACK rate.
   4826   1.1     pooka 	 * As a consequence, it's not as complicated as it sounds, just add
   4827   1.1     pooka 	 * any lower rates to the ACK rate bitmap.
   4828   1.1     pooka 	 */
   4829   1.1     pooka 	if (IWM_RATE_11M_INDEX < lowest_present_cck)
   4830   1.1     pooka 		cck |= IWM_RATE_BIT_MSK(11) >> IWM_FIRST_CCK_RATE;
   4831   1.1     pooka 	if (IWM_RATE_5M_INDEX < lowest_present_cck)
   4832   1.1     pooka 		cck |= IWM_RATE_BIT_MSK(5) >> IWM_FIRST_CCK_RATE;
   4833   1.1     pooka 	if (IWM_RATE_2M_INDEX < lowest_present_cck)
   4834   1.1     pooka 		cck |= IWM_RATE_BIT_MSK(2) >> IWM_FIRST_CCK_RATE;
   4835   1.1     pooka 	/* 1M already there or needed so always add */
   4836   1.1     pooka 	cck |= IWM_RATE_BIT_MSK(1) >> IWM_FIRST_CCK_RATE;
   4837   1.1     pooka 
   4838   1.1     pooka 	*cck_rates = cck;
   4839   1.1     pooka 	*ofdm_rates = ofdm;
   4840   1.1     pooka }
   4841   1.1     pooka 
   4842   1.4    nonaka static void
   4843   1.1     pooka iwm_mvm_mac_ctxt_cmd_common(struct iwm_softc *sc, struct iwm_node *in,
   4844   1.1     pooka 	struct iwm_mac_ctx_cmd *cmd, uint32_t action)
   4845   1.1     pooka {
   4846   1.1     pooka 	struct ieee80211com *ic = &sc->sc_ic;
   4847   1.1     pooka 	struct ieee80211_node *ni = ic->ic_bss;
   4848   1.1     pooka 	int cck_ack_rates, ofdm_ack_rates;
   4849   1.1     pooka 	int i;
   4850   1.1     pooka 
   4851   1.1     pooka 	cmd->id_and_color = htole32(IWM_FW_CMD_ID_AND_COLOR(in->in_id,
   4852   1.1     pooka 	    in->in_color));
   4853   1.1     pooka 	cmd->action = htole32(action);
   4854   1.1     pooka 
   4855   1.1     pooka 	cmd->mac_type = htole32(IWM_FW_MAC_TYPE_BSS_STA);
   4856   1.1     pooka 	cmd->tsf_id = htole32(in->in_tsfid);
   4857   1.1     pooka 
   4858   1.1     pooka 	IEEE80211_ADDR_COPY(cmd->node_addr, ic->ic_myaddr);
   4859   1.1     pooka 	if (in->in_assoc) {
   4860   1.1     pooka 		IEEE80211_ADDR_COPY(cmd->bssid_addr, ni->ni_bssid);
   4861   1.1     pooka 	} else {
   4862   1.1     pooka 		memset(cmd->bssid_addr, 0, sizeof(cmd->bssid_addr));
   4863   1.1     pooka 	}
   4864   1.1     pooka 	iwm_mvm_ack_rates(sc, in, &cck_ack_rates, &ofdm_ack_rates);
   4865   1.1     pooka 	cmd->cck_rates = htole32(cck_ack_rates);
   4866   1.1     pooka 	cmd->ofdm_rates = htole32(ofdm_ack_rates);
   4867   1.1     pooka 
   4868   1.1     pooka 	cmd->cck_short_preamble
   4869   1.1     pooka 	    = htole32((ic->ic_flags & IEEE80211_F_SHPREAMBLE)
   4870   1.1     pooka 	      ? IWM_MAC_FLG_SHORT_PREAMBLE : 0);
   4871   1.1     pooka 	cmd->short_slot
   4872   1.1     pooka 	    = htole32((ic->ic_flags & IEEE80211_F_SHSLOT)
   4873   1.1     pooka 	      ? IWM_MAC_FLG_SHORT_SLOT : 0);
   4874   1.1     pooka 
   4875   1.1     pooka 	for (i = 0; i < IWM_AC_NUM+1; i++) {
   4876   1.1     pooka 		int txf = i;
   4877   1.1     pooka 
   4878   1.1     pooka 		cmd->ac[txf].cw_min = htole16(0x0f);
   4879   1.1     pooka 		cmd->ac[txf].cw_max = htole16(0x3f);
   4880   1.1     pooka 		cmd->ac[txf].aifsn = 1;
   4881   1.1     pooka 		cmd->ac[txf].fifos_mask = (1 << txf);
   4882   1.1     pooka 		cmd->ac[txf].edca_txop = 0;
   4883   1.1     pooka 	}
   4884   1.1     pooka 
   4885  1.23    nonaka 	if (ic->ic_flags & IEEE80211_F_USEPROT)
   4886  1.23    nonaka 		cmd->protection_flags |= htole32(IWM_MAC_PROT_FLG_TGG_PROTECT);
   4887   1.1     pooka 
   4888   1.1     pooka 	cmd->filter_flags = htole32(IWM_MAC_FILTER_ACCEPT_GRP);
   4889   1.1     pooka }
   4890   1.1     pooka 
   4891   1.4    nonaka static int
   4892   1.1     pooka iwm_mvm_mac_ctxt_send_cmd(struct iwm_softc *sc, struct iwm_mac_ctx_cmd *cmd)
   4893   1.1     pooka {
   4894   1.1     pooka 	int ret = iwm_mvm_send_cmd_pdu(sc, IWM_MAC_CONTEXT_CMD, IWM_CMD_SYNC,
   4895   1.1     pooka 				       sizeof(*cmd), cmd);
   4896   1.1     pooka 	if (ret)
   4897   1.2    nonaka 		DPRINTF(("%s: Failed to send MAC context (action:%d): %d\n",
   4898   1.2    nonaka 		    DEVNAME(sc), le32toh(cmd->action), ret));
   4899   1.1     pooka 	return ret;
   4900   1.1     pooka }
   4901   1.1     pooka 
   4902   1.1     pooka /*
   4903   1.1     pooka  * Fill the specific data for mac context of type station or p2p client
   4904   1.1     pooka  */
   4905   1.4    nonaka static void
   4906   1.1     pooka iwm_mvm_mac_ctxt_cmd_fill_sta(struct iwm_softc *sc, struct iwm_node *in,
   4907   1.1     pooka 	struct iwm_mac_data_sta *ctxt_sta, int force_assoc_off)
   4908   1.1     pooka {
   4909   1.1     pooka 	struct ieee80211_node *ni = &in->in_ni;
   4910   1.1     pooka 	unsigned dtim_period, dtim_count;
   4911   1.1     pooka 
   4912   1.1     pooka 	dtim_period = ni->ni_dtim_period;
   4913   1.1     pooka 	dtim_count = ni->ni_dtim_count;
   4914   1.1     pooka 
   4915   1.1     pooka 	/* We need the dtim_period to set the MAC as associated */
   4916   1.1     pooka 	if (in->in_assoc && dtim_period && !force_assoc_off) {
   4917   1.1     pooka 		uint64_t tsf;
   4918   1.1     pooka 		uint32_t dtim_offs;
   4919   1.1     pooka 
   4920   1.1     pooka 		/*
   4921   1.1     pooka 		 * The DTIM count counts down, so when it is N that means N
   4922   1.1     pooka 		 * more beacon intervals happen until the DTIM TBTT. Therefore
   4923   1.1     pooka 		 * add this to the current time. If that ends up being in the
   4924   1.1     pooka 		 * future, the firmware will handle it.
   4925   1.1     pooka 		 *
   4926   1.1     pooka 		 * Also note that the system_timestamp (which we get here as
   4927   1.1     pooka 		 * "sync_device_ts") and TSF timestamp aren't at exactly the
   4928   1.1     pooka 		 * same offset in the frame -- the TSF is at the first symbol
   4929   1.1     pooka 		 * of the TSF, the system timestamp is at signal acquisition
   4930   1.1     pooka 		 * time. This means there's an offset between them of at most
   4931   1.1     pooka 		 * a few hundred microseconds (24 * 8 bits + PLCP time gives
   4932   1.1     pooka 		 * 384us in the longest case), this is currently not relevant
   4933   1.1     pooka 		 * as the firmware wakes up around 2ms before the TBTT.
   4934   1.1     pooka 		 */
   4935   1.1     pooka 		dtim_offs = dtim_count * ni->ni_intval;
   4936   1.1     pooka 		/* convert TU to usecs */
   4937   1.1     pooka 		dtim_offs *= 1024;
   4938   1.1     pooka 
   4939   1.1     pooka 		tsf = ni->ni_tstamp.tsf;
   4940   1.1     pooka 
   4941   1.1     pooka 		ctxt_sta->dtim_tsf = htole64(tsf + dtim_offs);
   4942   1.1     pooka 		ctxt_sta->dtim_time = htole64(ni->ni_rstamp + dtim_offs);
   4943   1.1     pooka 
   4944   1.1     pooka 		DPRINTF(("DTIM TBTT is 0x%llx/0x%x, offset %d\n",
   4945   1.1     pooka 		    (long long)le64toh(ctxt_sta->dtim_tsf),
   4946   1.1     pooka 		    le32toh(ctxt_sta->dtim_time), dtim_offs));
   4947   1.1     pooka 
   4948   1.1     pooka 		ctxt_sta->is_assoc = htole32(1);
   4949   1.1     pooka 	} else {
   4950   1.1     pooka 		ctxt_sta->is_assoc = htole32(0);
   4951   1.1     pooka 	}
   4952   1.1     pooka 
   4953   1.1     pooka 	ctxt_sta->bi = htole32(ni->ni_intval);
   4954   1.1     pooka 	ctxt_sta->bi_reciprocal = htole32(iwm_mvm_reciprocal(ni->ni_intval));
   4955   1.1     pooka 	ctxt_sta->dtim_interval = htole32(ni->ni_intval * dtim_period);
   4956   1.1     pooka 	ctxt_sta->dtim_reciprocal =
   4957   1.1     pooka 	    htole32(iwm_mvm_reciprocal(ni->ni_intval * dtim_period));
   4958   1.1     pooka 
   4959   1.1     pooka 	/* 10 = CONN_MAX_LISTEN_INTERVAL */
   4960   1.1     pooka 	ctxt_sta->listen_interval = htole32(10);
   4961   1.1     pooka 	ctxt_sta->assoc_id = htole32(ni->ni_associd);
   4962   1.1     pooka }
   4963   1.1     pooka 
   4964   1.4    nonaka static int
   4965   1.1     pooka iwm_mvm_mac_ctxt_cmd_station(struct iwm_softc *sc, struct iwm_node *in,
   4966   1.1     pooka 	uint32_t action)
   4967   1.1     pooka {
   4968   1.1     pooka 	struct iwm_mac_ctx_cmd cmd;
   4969   1.1     pooka 
   4970   1.1     pooka 	memset(&cmd, 0, sizeof(cmd));
   4971   1.1     pooka 
   4972   1.1     pooka 	/* Fill the common data for all mac context types */
   4973   1.1     pooka 	iwm_mvm_mac_ctxt_cmd_common(sc, in, &cmd, action);
   4974   1.1     pooka 
   4975  1.25    nonaka 	/* Allow beacons to pass through as long as we are not associated,or we
   4976  1.25    nonaka 	 * do not have dtim period information */
   4977  1.25    nonaka 	if (!in->in_assoc || !sc->sc_ic.ic_dtim_period)
   4978   1.1     pooka 		cmd.filter_flags |= htole32(IWM_MAC_FILTER_IN_BEACON);
   4979   1.1     pooka 	else
   4980   1.1     pooka 		cmd.filter_flags &= ~htole32(IWM_MAC_FILTER_IN_BEACON);
   4981   1.1     pooka 
   4982   1.1     pooka 	/* Fill the data specific for station mode */
   4983   1.1     pooka 	iwm_mvm_mac_ctxt_cmd_fill_sta(sc, in,
   4984   1.1     pooka 	    &cmd.sta, action == IWM_FW_CTXT_ACTION_ADD);
   4985   1.1     pooka 
   4986   1.1     pooka 	return iwm_mvm_mac_ctxt_send_cmd(sc, &cmd);
   4987   1.1     pooka }
   4988   1.1     pooka 
   4989   1.4    nonaka static int
   4990   1.1     pooka iwm_mvm_mac_ctx_send(struct iwm_softc *sc, struct iwm_node *in, uint32_t action)
   4991   1.1     pooka {
   4992   1.1     pooka 	return iwm_mvm_mac_ctxt_cmd_station(sc, in, action);
   4993   1.1     pooka }
   4994   1.1     pooka 
   4995   1.4    nonaka static int
   4996   1.1     pooka iwm_mvm_mac_ctxt_add(struct iwm_softc *sc, struct iwm_node *in)
   4997   1.1     pooka {
   4998   1.1     pooka 	int ret;
   4999   1.1     pooka 
   5000   1.1     pooka 	ret = iwm_mvm_mac_ctx_send(sc, in, IWM_FW_CTXT_ACTION_ADD);
   5001   1.1     pooka 	if (ret)
   5002   1.1     pooka 		return ret;
   5003   1.1     pooka 
   5004   1.1     pooka 	return 0;
   5005   1.1     pooka }
   5006   1.1     pooka 
   5007   1.4    nonaka static int
   5008   1.1     pooka iwm_mvm_mac_ctxt_changed(struct iwm_softc *sc, struct iwm_node *in)
   5009   1.1     pooka {
   5010   1.1     pooka 	return iwm_mvm_mac_ctx_send(sc, in, IWM_FW_CTXT_ACTION_MODIFY);
   5011   1.1     pooka }
   5012   1.1     pooka 
   5013   1.1     pooka #if 0
   5014   1.4    nonaka static int
   5015   1.1     pooka iwm_mvm_mac_ctxt_remove(struct iwm_softc *sc, struct iwm_node *in)
   5016   1.1     pooka {
   5017   1.1     pooka 	struct iwm_mac_ctx_cmd cmd;
   5018   1.1     pooka 	int ret;
   5019   1.1     pooka 
   5020   1.1     pooka 	if (!in->in_uploaded) {
   5021   1.1     pooka 		print("%s: attempt to remove !uploaded node %p", DEVNAME(sc), in);
   5022   1.1     pooka 		return EIO;
   5023   1.1     pooka 	}
   5024   1.1     pooka 
   5025   1.1     pooka 	memset(&cmd, 0, sizeof(cmd));
   5026   1.1     pooka 
   5027   1.1     pooka 	cmd.id_and_color = htole32(IWM_FW_CMD_ID_AND_COLOR(in->in_id,
   5028   1.1     pooka 	    in->in_color));
   5029   1.1     pooka 	cmd.action = htole32(IWM_FW_CTXT_ACTION_REMOVE);
   5030   1.1     pooka 
   5031   1.1     pooka 	ret = iwm_mvm_send_cmd_pdu(sc,
   5032   1.1     pooka 	    IWM_MAC_CONTEXT_CMD, IWM_CMD_SYNC, sizeof(cmd), &cmd);
   5033   1.1     pooka 	if (ret) {
   5034   1.3    nonaka 		aprint_error_dev(sc->sc_dev,
   5035   1.3    nonaka 		    "Failed to remove MAC context: %d\n", ret);
   5036   1.1     pooka 		return ret;
   5037   1.1     pooka 	}
   5038   1.1     pooka 	in->in_uploaded = 0;
   5039   1.1     pooka 
   5040   1.1     pooka 	return 0;
   5041   1.1     pooka }
   5042   1.1     pooka #endif
   5043   1.1     pooka 
   5044   1.1     pooka #define IWM_MVM_MISSED_BEACONS_THRESHOLD 8
   5045   1.1     pooka 
   5046   1.1     pooka static void
   5047   1.1     pooka iwm_mvm_rx_missed_beacons_notif(struct iwm_softc *sc,
   5048   1.1     pooka 	struct iwm_rx_packet *pkt, struct iwm_rx_data *data)
   5049   1.1     pooka {
   5050   1.1     pooka 	struct iwm_missed_beacons_notif *mb = (void *)pkt->data;
   5051   1.1     pooka 
   5052   1.1     pooka 	DPRINTF(("missed bcn mac_id=%u, consecutive=%u (%u, %u, %u)\n",
   5053   1.1     pooka 	    le32toh(mb->mac_id),
   5054   1.1     pooka 	    le32toh(mb->consec_missed_beacons),
   5055   1.1     pooka 	    le32toh(mb->consec_missed_beacons_since_last_rx),
   5056   1.1     pooka 	    le32toh(mb->num_recvd_beacons),
   5057   1.1     pooka 	    le32toh(mb->num_expected_beacons)));
   5058   1.1     pooka 
   5059   1.1     pooka 	/*
   5060   1.1     pooka 	 * TODO: the threshold should be adjusted based on latency conditions,
   5061   1.1     pooka 	 * and/or in case of a CS flow on one of the other AP vifs.
   5062   1.1     pooka 	 */
   5063   1.1     pooka 	if (le32toh(mb->consec_missed_beacons_since_last_rx) >
   5064   1.1     pooka 	    IWM_MVM_MISSED_BEACONS_THRESHOLD)
   5065   1.1     pooka 		ieee80211_beacon_miss(&sc->sc_ic);
   5066   1.1     pooka }
   5067   1.1     pooka 
   5068   1.1     pooka /*
   5069   1.1     pooka  * END mvm/mac-ctxt.c
   5070   1.1     pooka  */
   5071   1.1     pooka 
   5072   1.1     pooka /*
   5073   1.1     pooka  * BEGIN mvm/quota.c
   5074   1.1     pooka  */
   5075   1.1     pooka 
   5076   1.4    nonaka static int
   5077   1.1     pooka iwm_mvm_update_quotas(struct iwm_softc *sc, struct iwm_node *in)
   5078   1.1     pooka {
   5079   1.1     pooka 	struct iwm_time_quota_cmd cmd;
   5080   1.1     pooka 	int i, idx, ret, num_active_macs, quota, quota_rem;
   5081   1.1     pooka 	int colors[IWM_MAX_BINDINGS] = { -1, -1, -1, -1, };
   5082   1.1     pooka 	int n_ifs[IWM_MAX_BINDINGS] = {0, };
   5083   1.1     pooka 	uint16_t id;
   5084   1.1     pooka 
   5085   1.1     pooka 	memset(&cmd, 0, sizeof(cmd));
   5086   1.1     pooka 
   5087   1.1     pooka 	/* currently, PHY ID == binding ID */
   5088   1.1     pooka 	if (in) {
   5089   1.1     pooka 		id = in->in_phyctxt->id;
   5090   1.1     pooka 		KASSERT(id < IWM_MAX_BINDINGS);
   5091   1.1     pooka 		colors[id] = in->in_phyctxt->color;
   5092   1.1     pooka 
   5093   1.1     pooka 		if (1)
   5094   1.1     pooka 			n_ifs[id] = 1;
   5095   1.1     pooka 	}
   5096   1.1     pooka 
   5097   1.1     pooka 	/*
   5098   1.1     pooka 	 * The FW's scheduling session consists of
   5099   1.1     pooka 	 * IWM_MVM_MAX_QUOTA fragments. Divide these fragments
   5100   1.1     pooka 	 * equally between all the bindings that require quota
   5101   1.1     pooka 	 */
   5102   1.1     pooka 	num_active_macs = 0;
   5103   1.1     pooka 	for (i = 0; i < IWM_MAX_BINDINGS; i++) {
   5104   1.1     pooka 		cmd.quotas[i].id_and_color = htole32(IWM_FW_CTXT_INVALID);
   5105   1.1     pooka 		num_active_macs += n_ifs[i];
   5106   1.1     pooka 	}
   5107   1.1     pooka 
   5108   1.1     pooka 	quota = 0;
   5109   1.1     pooka 	quota_rem = 0;
   5110   1.1     pooka 	if (num_active_macs) {
   5111   1.1     pooka 		quota = IWM_MVM_MAX_QUOTA / num_active_macs;
   5112   1.1     pooka 		quota_rem = IWM_MVM_MAX_QUOTA % num_active_macs;
   5113   1.1     pooka 	}
   5114   1.1     pooka 
   5115   1.1     pooka 	for (idx = 0, i = 0; i < IWM_MAX_BINDINGS; i++) {
   5116   1.1     pooka 		if (colors[i] < 0)
   5117   1.1     pooka 			continue;
   5118   1.1     pooka 
   5119   1.1     pooka 		cmd.quotas[idx].id_and_color =
   5120   1.1     pooka 			htole32(IWM_FW_CMD_ID_AND_COLOR(i, colors[i]));
   5121   1.1     pooka 
   5122   1.1     pooka 		if (n_ifs[i] <= 0) {
   5123   1.1     pooka 			cmd.quotas[idx].quota = htole32(0);
   5124   1.1     pooka 			cmd.quotas[idx].max_duration = htole32(0);
   5125   1.1     pooka 		} else {
   5126   1.1     pooka 			cmd.quotas[idx].quota = htole32(quota * n_ifs[i]);
   5127   1.1     pooka 			cmd.quotas[idx].max_duration = htole32(0);
   5128   1.1     pooka 		}
   5129   1.1     pooka 		idx++;
   5130   1.1     pooka 	}
   5131   1.1     pooka 
   5132   1.1     pooka 	/* Give the remainder of the session to the first binding */
   5133   1.1     pooka 	cmd.quotas[0].quota = htole32(le32toh(cmd.quotas[0].quota) + quota_rem);
   5134   1.1     pooka 
   5135   1.1     pooka 	ret = iwm_mvm_send_cmd_pdu(sc, IWM_TIME_QUOTA_CMD, IWM_CMD_SYNC,
   5136   1.1     pooka 	    sizeof(cmd), &cmd);
   5137   1.1     pooka 	if (ret)
   5138   1.2    nonaka 		DPRINTF(("%s: Failed to send quota: %d\n", DEVNAME(sc), ret));
   5139   1.1     pooka 	return ret;
   5140   1.1     pooka }
   5141   1.1     pooka 
   5142   1.1     pooka /*
   5143   1.1     pooka  * END mvm/quota.c
   5144   1.1     pooka  */
   5145   1.1     pooka 
   5146   1.1     pooka /*
   5147   1.1     pooka  * aieee80211 routines
   5148   1.1     pooka  */
   5149   1.1     pooka 
   5150   1.1     pooka /*
   5151   1.1     pooka  * Change to AUTH state in 80211 state machine.  Roughly matches what
   5152   1.1     pooka  * Linux does in bss_info_changed().
   5153   1.1     pooka  */
   5154   1.4    nonaka static int
   5155   1.1     pooka iwm_auth(struct iwm_softc *sc)
   5156   1.1     pooka {
   5157   1.1     pooka 	struct ieee80211com *ic = &sc->sc_ic;
   5158   1.1     pooka 	struct iwm_node *in = (void *)ic->ic_bss;
   5159   1.1     pooka 	uint32_t duration;
   5160   1.1     pooka 	uint32_t min_duration;
   5161   1.1     pooka 	int error;
   5162   1.1     pooka 
   5163   1.1     pooka 	in->in_assoc = 0;
   5164  1.11    nonaka 
   5165  1.11    nonaka 	if ((error = iwm_allow_mcast(sc)) != 0)
   5166  1.11    nonaka 		return error;
   5167  1.11    nonaka 
   5168   1.1     pooka 	if ((error = iwm_mvm_mac_ctxt_add(sc, in)) != 0) {
   5169   1.2    nonaka 		DPRINTF(("%s: failed to add MAC\n", DEVNAME(sc)));
   5170   1.1     pooka 		return error;
   5171   1.1     pooka 	}
   5172   1.1     pooka 
   5173   1.1     pooka 	if ((error = iwm_mvm_phy_ctxt_changed(sc, &sc->sc_phyctxt[0],
   5174   1.1     pooka 	    in->in_ni.ni_chan, 1, 1)) != 0) {
   5175   1.2    nonaka 		DPRINTF(("%s: failed add phy ctxt\n", DEVNAME(sc)));
   5176   1.1     pooka 		return error;
   5177   1.1     pooka 	}
   5178   1.1     pooka 	in->in_phyctxt = &sc->sc_phyctxt[0];
   5179   1.1     pooka 
   5180   1.1     pooka 	if ((error = iwm_mvm_binding_add_vif(sc, in)) != 0) {
   5181   1.2    nonaka 		DPRINTF(("%s: binding cmd\n", DEVNAME(sc)));
   5182   1.1     pooka 		return error;
   5183   1.1     pooka 	}
   5184   1.1     pooka 
   5185   1.1     pooka 	if ((error = iwm_mvm_add_sta(sc, in)) != 0) {
   5186   1.2    nonaka 		DPRINTF(("%s: failed to add MAC\n", DEVNAME(sc)));
   5187   1.1     pooka 		return error;
   5188   1.1     pooka 	}
   5189   1.1     pooka 
   5190   1.1     pooka 	/* a bit superfluous? */
   5191   1.1     pooka 	while (sc->sc_auth_prot)
   5192   1.1     pooka 		tsleep(&sc->sc_auth_prot, 0, "iwmauth", 0);
   5193   1.1     pooka 	sc->sc_auth_prot = 1;
   5194   1.8    nonaka 
   5195   1.1     pooka 	duration = min(IWM_MVM_TE_SESSION_PROTECTION_MAX_TIME_MS,
   5196   1.1     pooka 	    200 + in->in_ni.ni_intval);
   5197   1.1     pooka 	min_duration = min(IWM_MVM_TE_SESSION_PROTECTION_MIN_TIME_MS,
   5198   1.1     pooka 	    100 + in->in_ni.ni_intval);
   5199   1.1     pooka 	iwm_mvm_protect_session(sc, in, duration, min_duration, 500);
   5200   1.1     pooka 
   5201   1.1     pooka 	while (sc->sc_auth_prot != 2) {
   5202   1.1     pooka 		/*
   5203   1.1     pooka 		 * well, meh, but if the kernel is sleeping for half a
   5204   1.1     pooka 		 * second, we have bigger problems
   5205   1.1     pooka 		 */
   5206   1.1     pooka 		if (sc->sc_auth_prot == 0) {
   5207   1.2    nonaka 			DPRINTF(("%s: missed auth window!\n", DEVNAME(sc)));
   5208   1.1     pooka 			return ETIMEDOUT;
   5209   1.1     pooka 		} else if (sc->sc_auth_prot == -1) {
   5210   1.2    nonaka 			DPRINTF(("%s: no time event, denied!\n", DEVNAME(sc)));
   5211   1.1     pooka 			sc->sc_auth_prot = 0;
   5212   1.1     pooka 			return EAUTH;
   5213   1.1     pooka 		}
   5214   1.1     pooka 		tsleep(&sc->sc_auth_prot, 0, "iwmau2", 0);
   5215   1.1     pooka 	}
   5216   1.1     pooka 
   5217   1.1     pooka 	return 0;
   5218   1.1     pooka }
   5219   1.1     pooka 
   5220   1.4    nonaka static int
   5221   1.1     pooka iwm_assoc(struct iwm_softc *sc)
   5222   1.1     pooka {
   5223   1.1     pooka 	struct ieee80211com *ic = &sc->sc_ic;
   5224   1.1     pooka 	struct iwm_node *in = (void *)ic->ic_bss;
   5225   1.1     pooka 	int error;
   5226   1.1     pooka 
   5227   1.1     pooka 	if ((error = iwm_mvm_update_sta(sc, in)) != 0) {
   5228   1.2    nonaka 		DPRINTF(("%s: failed to update STA\n", DEVNAME(sc)));
   5229   1.1     pooka 		return error;
   5230   1.1     pooka 	}
   5231   1.1     pooka 
   5232   1.1     pooka 	in->in_assoc = 1;
   5233   1.1     pooka 	if ((error = iwm_mvm_mac_ctxt_changed(sc, in)) != 0) {
   5234   1.2    nonaka 		DPRINTF(("%s: failed to update MAC\n", DEVNAME(sc)));
   5235   1.1     pooka 		return error;
   5236   1.1     pooka 	}
   5237   1.1     pooka 
   5238   1.1     pooka 	return 0;
   5239   1.1     pooka }
   5240   1.1     pooka 
   5241   1.4    nonaka static int
   5242   1.1     pooka iwm_release(struct iwm_softc *sc, struct iwm_node *in)
   5243   1.1     pooka {
   5244   1.1     pooka 	/*
   5245   1.1     pooka 	 * Ok, so *technically* the proper set of calls for going
   5246   1.1     pooka 	 * from RUN back to SCAN is:
   5247   1.1     pooka 	 *
   5248   1.1     pooka 	 * iwm_mvm_power_mac_disable(sc, in);
   5249   1.1     pooka 	 * iwm_mvm_mac_ctxt_changed(sc, in);
   5250   1.1     pooka 	 * iwm_mvm_rm_sta(sc, in);
   5251   1.1     pooka 	 * iwm_mvm_update_quotas(sc, NULL);
   5252   1.1     pooka 	 * iwm_mvm_mac_ctxt_changed(sc, in);
   5253   1.1     pooka 	 * iwm_mvm_binding_remove_vif(sc, in);
   5254   1.1     pooka 	 * iwm_mvm_mac_ctxt_remove(sc, in);
   5255   1.1     pooka 	 *
   5256   1.1     pooka 	 * However, that freezes the device not matter which permutations
   5257   1.1     pooka 	 * and modifications are attempted.  Obviously, this driver is missing
   5258   1.1     pooka 	 * something since it works in the Linux driver, but figuring out what
   5259   1.1     pooka 	 * is missing is a little more complicated.  Now, since we're going
   5260   1.1     pooka 	 * back to nothing anyway, we'll just do a complete device reset.
   5261   1.1     pooka 	 * Up your's, device!
   5262   1.1     pooka 	 */
   5263   1.1     pooka 	//iwm_mvm_flush_tx_path(sc, 0xf, 1);
   5264   1.1     pooka 	iwm_stop_device(sc);
   5265   1.1     pooka 	iwm_init_hw(sc);
   5266   1.1     pooka 	if (in)
   5267   1.1     pooka 		in->in_assoc = 0;
   5268   1.1     pooka 	return 0;
   5269   1.1     pooka 
   5270   1.1     pooka #if 0
   5271   1.1     pooka 	int error;
   5272   1.1     pooka 
   5273   1.1     pooka 	iwm_mvm_power_mac_disable(sc, in);
   5274   1.1     pooka 
   5275   1.1     pooka 	if ((error = iwm_mvm_mac_ctxt_changed(sc, in)) != 0) {
   5276   1.3    nonaka 		aprint_error_dev(sc->sc_dev, "mac ctxt change fail 1 %d\n",
   5277   1.3    nonaka 		    error);
   5278   1.1     pooka 		return error;
   5279   1.1     pooka 	}
   5280   1.1     pooka 
   5281   1.1     pooka 	if ((error = iwm_mvm_rm_sta(sc, in)) != 0) {
   5282   1.3    nonaka 		aprint_error_dev(sc->sc_dev, "sta remove fail %d\n", error);
   5283   1.1     pooka 		return error;
   5284   1.1     pooka 	}
   5285   1.1     pooka 	error = iwm_mvm_rm_sta(sc, in);
   5286   1.1     pooka 	in->in_assoc = 0;
   5287   1.1     pooka 	iwm_mvm_update_quotas(sc, NULL);
   5288   1.1     pooka 	if ((error = iwm_mvm_mac_ctxt_changed(sc, in)) != 0) {
   5289   1.3    nonaka 		aprint_error_dev(sc->sc_dev, "mac ctxt change fail 2 %d\n",
   5290   1.3    nonaka 		    error);
   5291   1.1     pooka 		return error;
   5292   1.1     pooka 	}
   5293   1.1     pooka 	iwm_mvm_binding_remove_vif(sc, in);
   5294   1.1     pooka 
   5295   1.1     pooka 	iwm_mvm_mac_ctxt_remove(sc, in);
   5296   1.1     pooka 
   5297   1.1     pooka 	return error;
   5298   1.1     pooka #endif
   5299   1.1     pooka }
   5300   1.1     pooka 
   5301   1.1     pooka 
   5302   1.1     pooka static struct ieee80211_node *
   5303   1.1     pooka iwm_node_alloc(struct ieee80211_node_table *nt)
   5304   1.1     pooka {
   5305   1.5    nonaka 	return malloc(sizeof(struct iwm_node), M_80211_NODE, M_NOWAIT | M_ZERO);
   5306   1.1     pooka }
   5307   1.1     pooka 
   5308   1.4    nonaka static void
   5309   1.1     pooka iwm_calib_timeout(void *arg)
   5310   1.1     pooka {
   5311   1.1     pooka 	struct iwm_softc *sc = arg;
   5312   1.1     pooka 	struct ieee80211com *ic = &sc->sc_ic;
   5313   1.1     pooka 	int s;
   5314   1.1     pooka 
   5315   1.1     pooka 	s = splnet();
   5316   1.1     pooka 	if (ic->ic_fixed_rate == -1
   5317   1.1     pooka 	    && ic->ic_opmode == IEEE80211_M_STA
   5318   1.1     pooka 	    && ic->ic_bss) {
   5319   1.1     pooka 		struct iwm_node *in = (void *)ic->ic_bss;
   5320   1.1     pooka 		ieee80211_amrr_choose(&sc->sc_amrr, &in->in_ni, &in->in_amn);
   5321   1.1     pooka 	}
   5322   1.1     pooka 	splx(s);
   5323   1.1     pooka 
   5324   1.1     pooka 	callout_schedule(&sc->sc_calib_to, hz/2);
   5325   1.1     pooka }
   5326   1.1     pooka 
   5327   1.4    nonaka static void
   5328   1.1     pooka iwm_setrates(struct iwm_node *in)
   5329   1.1     pooka {
   5330   1.1     pooka 	struct ieee80211_node *ni = &in->in_ni;
   5331   1.1     pooka 	struct ieee80211com *ic = ni->ni_ic;
   5332   1.1     pooka 	struct iwm_softc *sc = IC2IFP(ic)->if_softc;
   5333   1.1     pooka 	struct iwm_lq_cmd *lq = &in->in_lq;
   5334   1.1     pooka 	int nrates = ni->ni_rates.rs_nrates;
   5335   1.1     pooka 	int i, ridx, tab = 0;
   5336   1.1     pooka 	int txant = 0;
   5337   1.1     pooka 
   5338  1.14  christos 	if (nrates > __arraycount(lq->rs_table) ||
   5339  1.14  christos 	    nrates > IEEE80211_RATE_MAXSIZE) {
   5340   1.2    nonaka 		DPRINTF(("%s: node supports %d rates, driver handles only "
   5341   1.2    nonaka 		    "%zu\n", DEVNAME(sc), nrates, __arraycount(lq->rs_table)));
   5342   1.1     pooka 		return;
   5343   1.1     pooka 	}
   5344   1.1     pooka 
   5345   1.1     pooka 	/* first figure out which rates we should support */
   5346   1.1     pooka 	memset(&in->in_ridx, -1, sizeof(in->in_ridx));
   5347   1.1     pooka 	for (i = 0; i < nrates; i++) {
   5348   1.1     pooka 		int rate = ni->ni_rates.rs_rates[i] & IEEE80211_RATE_VAL;
   5349   1.8    nonaka 
   5350   1.1     pooka 		/* Map 802.11 rate to HW rate index. */
   5351   1.1     pooka 		for (ridx = 0; ridx <= IWM_RIDX_MAX; ridx++)
   5352   1.1     pooka 			if (iwm_rates[ridx].rate == rate)
   5353   1.1     pooka 				break;
   5354   1.1     pooka 		if (ridx > IWM_RIDX_MAX)
   5355   1.2    nonaka 			DPRINTF(("%s: WARNING: device rate for %d not found!\n",
   5356   1.2    nonaka 			    DEVNAME(sc), rate));
   5357  1.13    nonaka 		else
   5358  1.12    nonaka 			in->in_ridx[i] = ridx;
   5359   1.1     pooka 	}
   5360   1.1     pooka 
   5361   1.1     pooka 	/* then construct a lq_cmd based on those */
   5362   1.1     pooka 	memset(lq, 0, sizeof(*lq));
   5363   1.1     pooka 	lq->sta_id = IWM_STATION_ID;
   5364   1.1     pooka 
   5365   1.1     pooka 	/*
   5366   1.1     pooka 	 * are these used? (we don't do SISO or MIMO)
   5367   1.1     pooka 	 * need to set them to non-zero, though, or we get an error.
   5368   1.1     pooka 	 */
   5369   1.1     pooka 	lq->single_stream_ant_msk = 1;
   5370   1.1     pooka 	lq->dual_stream_ant_msk = 1;
   5371   1.1     pooka 
   5372   1.1     pooka 	/*
   5373   1.1     pooka 	 * Build the actual rate selection table.
   5374   1.1     pooka 	 * The lowest bits are the rates.  Additionally,
   5375   1.1     pooka 	 * CCK needs bit 9 to be set.  The rest of the bits
   5376   1.1     pooka 	 * we add to the table select the tx antenna
   5377   1.1     pooka 	 * Note that we add the rates in the highest rate first
   5378   1.1     pooka 	 * (opposite of ni_rates).
   5379   1.1     pooka 	 */
   5380   1.1     pooka 	for (i = 0; i < nrates; i++) {
   5381   1.1     pooka 		int nextant;
   5382   1.1     pooka 
   5383   1.1     pooka 		if (txant == 0)
   5384   1.1     pooka 			txant = IWM_FW_VALID_TX_ANT(sc);
   5385   1.1     pooka 		nextant = 1<<(ffs(txant)-1);
   5386   1.1     pooka 		txant &= ~nextant;
   5387   1.1     pooka 
   5388   1.1     pooka 		ridx = in->in_ridx[(nrates-1)-i];
   5389   1.1     pooka 		tab = iwm_rates[ridx].plcp;
   5390   1.1     pooka 		tab |= nextant << IWM_RATE_MCS_ANT_POS;
   5391   1.1     pooka 		if (IWM_RIDX_IS_CCK(ridx))
   5392   1.1     pooka 			tab |= IWM_RATE_MCS_CCK_MSK;
   5393   1.1     pooka 		DPRINTFN(2, ("station rate %d %x\n", i, tab));
   5394   1.1     pooka 		lq->rs_table[i] = htole32(tab);
   5395   1.1     pooka 	}
   5396   1.1     pooka 	/* then fill the rest with the lowest possible rate */
   5397   1.1     pooka 	for (i = nrates; i < __arraycount(lq->rs_table); i++) {
   5398   1.1     pooka 		KASSERT(tab != 0);
   5399   1.1     pooka 		lq->rs_table[i] = htole32(tab);
   5400   1.1     pooka 	}
   5401   1.1     pooka 
   5402   1.1     pooka 	/* init amrr */
   5403   1.1     pooka 	ieee80211_amrr_node_init(&sc->sc_amrr, &in->in_amn);
   5404  1.18    nonaka 	/* Start at lowest available bit-rate, AMRR will raise. */
   5405  1.18    nonaka 	ni->ni_txrate = 0;
   5406   1.1     pooka }
   5407   1.1     pooka 
   5408   1.4    nonaka static int
   5409   1.1     pooka iwm_media_change(struct ifnet *ifp)
   5410   1.1     pooka {
   5411   1.1     pooka 	struct iwm_softc *sc = ifp->if_softc;
   5412   1.1     pooka 	struct ieee80211com *ic = &sc->sc_ic;
   5413   1.1     pooka 	uint8_t rate, ridx;
   5414   1.1     pooka 	int error;
   5415   1.1     pooka 
   5416   1.1     pooka 	error = ieee80211_media_change(ifp);
   5417   1.1     pooka 	if (error != ENETRESET)
   5418   1.1     pooka 		return error;
   5419   1.1     pooka 
   5420   1.1     pooka 	if (ic->ic_fixed_rate != -1) {
   5421   1.1     pooka 		rate = ic->ic_sup_rates[ic->ic_curmode].
   5422   1.1     pooka 		    rs_rates[ic->ic_fixed_rate] & IEEE80211_RATE_VAL;
   5423   1.1     pooka 		/* Map 802.11 rate to HW rate index. */
   5424   1.1     pooka 		for (ridx = 0; ridx <= IWM_RIDX_MAX; ridx++)
   5425   1.1     pooka 			if (iwm_rates[ridx].rate == rate)
   5426   1.1     pooka 				break;
   5427   1.1     pooka 		sc->sc_fixed_ridx = ridx;
   5428   1.1     pooka 	}
   5429   1.1     pooka 
   5430   1.1     pooka 	if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
   5431   1.1     pooka 	    (IFF_UP | IFF_RUNNING)) {
   5432   1.1     pooka 		iwm_stop(ifp, 0);
   5433   1.1     pooka 		error = iwm_init(ifp);
   5434   1.1     pooka 	}
   5435   1.1     pooka 	return error;
   5436   1.1     pooka }
   5437   1.1     pooka 
   5438   1.4    nonaka static void
   5439   1.5    nonaka iwm_newstate_cb(struct work *wk, void *v)
   5440   1.1     pooka {
   5441   1.5    nonaka 	struct iwm_softc *sc = v;
   5442   1.5    nonaka 	struct ieee80211com *ic = &sc->sc_ic;
   5443   1.1     pooka 	struct iwm_newstate_state *iwmns = (void *)wk;
   5444   1.1     pooka 	enum ieee80211_state nstate = iwmns->ns_nstate;
   5445   1.1     pooka 	int generation = iwmns->ns_generation;
   5446   1.1     pooka 	struct iwm_node *in;
   5447   1.1     pooka 	int arg = iwmns->ns_arg;
   5448   1.1     pooka 	int error;
   5449   1.1     pooka 
   5450   1.1     pooka 	kmem_free(iwmns, sizeof(*iwmns));
   5451   1.1     pooka 
   5452   1.1     pooka 	DPRINTF(("Prepare to switch state %d->%d\n", ic->ic_state, nstate));
   5453   1.1     pooka 	if (sc->sc_generation != generation) {
   5454   1.1     pooka 		DPRINTF(("newstate_cb: someone pulled the plug meanwhile\n"));
   5455   1.1     pooka 		if (nstate == IEEE80211_S_INIT) {
   5456   1.1     pooka 			DPRINTF(("newstate_cb: nstate == IEEE80211_S_INIT: calling sc_newstate()\n"));
   5457   1.1     pooka 			sc->sc_newstate(ic, nstate, arg);
   5458   1.1     pooka 		}
   5459   1.1     pooka 		return;
   5460   1.1     pooka 	}
   5461   1.1     pooka 
   5462   1.1     pooka 	DPRINTF(("switching state %d->%d\n", ic->ic_state, nstate));
   5463   1.1     pooka 
   5464   1.1     pooka 	/* disable beacon filtering if we're hopping out of RUN */
   5465   1.1     pooka 	if (ic->ic_state == IEEE80211_S_RUN && nstate != ic->ic_state) {
   5466   1.1     pooka 		iwm_mvm_disable_beacon_filter(sc, (void *)ic->ic_bss);
   5467   1.1     pooka 
   5468   1.1     pooka 		if (((in = (void *)ic->ic_bss) != NULL))
   5469   1.1     pooka 			in->in_assoc = 0;
   5470   1.1     pooka 		iwm_release(sc, NULL);
   5471   1.1     pooka 
   5472   1.1     pooka 		/*
   5473   1.1     pooka 		 * It's impossible to directly go RUN->SCAN. If we iwm_release()
   5474   1.1     pooka 		 * above then the card will be completely reinitialized,
   5475   1.1     pooka 		 * so the driver must do everything necessary to bring the card
   5476   1.1     pooka 		 * from INIT to SCAN.
   5477   1.1     pooka 		 *
   5478   1.1     pooka 		 * Additionally, upon receiving deauth frame from AP,
   5479   1.1     pooka 		 * OpenBSD 802.11 stack puts the driver in IEEE80211_S_AUTH
   5480   1.1     pooka 		 * state. This will also fail with this driver, so bring the FSM
   5481   1.1     pooka 		 * from IEEE80211_S_RUN to IEEE80211_S_SCAN in this case as well.
   5482   1.1     pooka 		 */
   5483   1.1     pooka 		if (nstate == IEEE80211_S_SCAN ||
   5484   1.1     pooka 		    nstate == IEEE80211_S_AUTH ||
   5485   1.1     pooka 		    nstate == IEEE80211_S_ASSOC) {
   5486   1.1     pooka 			DPRINTF(("Force transition to INIT; MGT=%d\n", arg));
   5487   1.1     pooka 			sc->sc_newstate(ic, IEEE80211_S_INIT, arg);
   5488   1.1     pooka 			DPRINTF(("Going INIT->SCAN\n"));
   5489   1.1     pooka 			nstate = IEEE80211_S_SCAN;
   5490   1.1     pooka 		}
   5491   1.1     pooka 	}
   5492   1.1     pooka 
   5493   1.1     pooka 	switch (nstate) {
   5494   1.1     pooka 	case IEEE80211_S_INIT:
   5495   1.1     pooka 		sc->sc_scanband = 0;
   5496   1.1     pooka 		break;
   5497   1.1     pooka 
   5498   1.1     pooka 	case IEEE80211_S_SCAN:
   5499   1.2    nonaka 		if (sc->sc_scanband)
   5500   1.1     pooka 			break;
   5501   1.1     pooka 
   5502   1.1     pooka 		if ((error = iwm_mvm_scan_request(sc, IEEE80211_CHAN_2GHZ,
   5503   1.1     pooka 		    ic->ic_des_esslen != 0,
   5504   1.1     pooka 		    ic->ic_des_essid, ic->ic_des_esslen)) != 0) {
   5505   1.8    nonaka 			DPRINTF(("%s: could not initiate scan\n", DEVNAME(sc)));
   5506   1.1     pooka 			return;
   5507   1.1     pooka 		}
   5508   1.1     pooka 		ic->ic_state = nstate;
   5509   1.1     pooka 		return;
   5510   1.1     pooka 
   5511   1.1     pooka 	case IEEE80211_S_AUTH:
   5512   1.1     pooka 		if ((error = iwm_auth(sc)) != 0) {
   5513   1.2    nonaka 			DPRINTF(("%s: could not move to auth state: %d\n",
   5514   1.2    nonaka 			    DEVNAME(sc), error));
   5515   1.1     pooka 			return;
   5516   1.1     pooka 		}
   5517   1.1     pooka 
   5518   1.1     pooka 		break;
   5519   1.1     pooka 
   5520   1.1     pooka 	case IEEE80211_S_ASSOC:
   5521   1.1     pooka 		if ((error = iwm_assoc(sc)) != 0) {
   5522   1.2    nonaka 			DPRINTF(("%s: failed to associate: %d\n", DEVNAME(sc),
   5523   1.2    nonaka 			    error));
   5524   1.1     pooka 			return;
   5525   1.1     pooka 		}
   5526   1.1     pooka 		break;
   5527   1.1     pooka 
   5528   1.1     pooka 	case IEEE80211_S_RUN: {
   5529   1.1     pooka 		struct iwm_host_cmd cmd = {
   5530   1.1     pooka 			.id = IWM_LQ_CMD,
   5531   1.1     pooka 			.len = { sizeof(in->in_lq), },
   5532   1.1     pooka 			.flags = IWM_CMD_SYNC,
   5533   1.1     pooka 		};
   5534   1.1     pooka 
   5535   1.1     pooka 		in = (struct iwm_node *)ic->ic_bss;
   5536   1.1     pooka 		iwm_mvm_power_mac_update_mode(sc, in);
   5537   1.1     pooka 		iwm_mvm_enable_beacon_filter(sc, in);
   5538   1.1     pooka 		iwm_mvm_update_quotas(sc, in);
   5539   1.1     pooka 		iwm_setrates(in);
   5540   1.1     pooka 
   5541   1.1     pooka 		cmd.data[0] = &in->in_lq;
   5542   1.1     pooka 		if ((error = iwm_send_cmd(sc, &cmd)) != 0) {
   5543   1.2    nonaka 			DPRINTF(("%s: IWM_LQ_CMD failed\n", DEVNAME(sc)));
   5544   1.1     pooka 		}
   5545   1.1     pooka 
   5546   1.1     pooka 		callout_schedule(&sc->sc_calib_to, hz/2);
   5547   1.1     pooka 
   5548   1.1     pooka 		break; }
   5549   1.1     pooka 
   5550   1.1     pooka 	default:
   5551   1.5    nonaka 		DPRINTF(("%s: unsupported state %d\n", DEVNAME(sc), nstate));
   5552   1.2    nonaka 		break;
   5553   1.1     pooka 	}
   5554   1.1     pooka 
   5555   1.1     pooka 	sc->sc_newstate(ic, nstate, arg);
   5556   1.1     pooka }
   5557   1.1     pooka 
   5558   1.4    nonaka static int
   5559   1.1     pooka iwm_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
   5560   1.1     pooka {
   5561   1.1     pooka 	struct iwm_newstate_state *iwmns;
   5562   1.1     pooka 	struct ifnet *ifp = IC2IFP(ic);
   5563   1.1     pooka 	struct iwm_softc *sc = ifp->if_softc;
   5564   1.1     pooka 
   5565   1.1     pooka 	callout_stop(&sc->sc_calib_to);
   5566   1.1     pooka 
   5567   1.5    nonaka 	iwmns = kmem_intr_alloc(sizeof(*iwmns), KM_NOSLEEP);
   5568   1.1     pooka 	if (!iwmns) {
   5569   1.2    nonaka 		DPRINTF(("%s: allocating state cb mem failed\n", DEVNAME(sc)));
   5570   1.1     pooka 		return ENOMEM;
   5571   1.1     pooka 	}
   5572   1.1     pooka 
   5573   1.1     pooka 	iwmns->ns_nstate = nstate;
   5574   1.1     pooka 	iwmns->ns_arg = arg;
   5575   1.1     pooka 	iwmns->ns_generation = sc->sc_generation;
   5576   1.1     pooka 
   5577   1.1     pooka 	workqueue_enqueue(sc->sc_nswq, &iwmns->ns_wk, NULL);
   5578   1.1     pooka 
   5579   1.1     pooka 	return 0;
   5580   1.1     pooka }
   5581   1.1     pooka 
   5582   1.4    nonaka static void
   5583   1.5    nonaka iwm_endscan_cb(struct work *work __unused, void *arg)
   5584   1.1     pooka {
   5585   1.1     pooka 	struct iwm_softc *sc = arg;
   5586   1.1     pooka 	struct ieee80211com *ic = &sc->sc_ic;
   5587   1.1     pooka 	int done;
   5588   1.1     pooka 
   5589   1.1     pooka 	DPRINTF(("scan ended\n"));
   5590   1.1     pooka 
   5591  1.29    nonaka 	if (sc->sc_scanband == IEEE80211_CHAN_2GHZ &&
   5592  1.29    nonaka 	    sc->sc_nvm.sku_cap_band_52GHz_enable) {
   5593   1.1     pooka 		int error;
   5594   1.1     pooka 		done = 0;
   5595   1.1     pooka 		if ((error = iwm_mvm_scan_request(sc,
   5596   1.1     pooka 		    IEEE80211_CHAN_5GHZ, ic->ic_des_esslen != 0,
   5597   1.1     pooka 		    ic->ic_des_essid, ic->ic_des_esslen)) != 0) {
   5598   1.3    nonaka 			DPRINTF(("%s: could not initiate scan\n", DEVNAME(sc)));
   5599   1.1     pooka 			done = 1;
   5600   1.1     pooka 		}
   5601   1.1     pooka 	} else {
   5602   1.1     pooka 		done = 1;
   5603   1.1     pooka 	}
   5604   1.1     pooka 
   5605   1.1     pooka 	if (done) {
   5606   1.1     pooka 		if (!sc->sc_scanband) {
   5607   1.1     pooka 			ieee80211_cancel_scan(ic);
   5608   1.1     pooka 		} else {
   5609   1.1     pooka 			ieee80211_end_scan(ic);
   5610   1.1     pooka 		}
   5611   1.1     pooka 		sc->sc_scanband = 0;
   5612   1.1     pooka 	}
   5613   1.1     pooka }
   5614   1.1     pooka 
   5615   1.4    nonaka static int
   5616   1.1     pooka iwm_init_hw(struct iwm_softc *sc)
   5617   1.1     pooka {
   5618   1.1     pooka 	struct ieee80211com *ic = &sc->sc_ic;
   5619   1.1     pooka 	int error, i, qid;
   5620   1.1     pooka 
   5621   1.2    nonaka 	if ((error = iwm_preinit(sc)) != 0)
   5622   1.1     pooka 		return error;
   5623   1.1     pooka 
   5624   1.1     pooka 	if ((error = iwm_start_hw(sc)) != 0)
   5625   1.1     pooka 		return error;
   5626   1.1     pooka 
   5627   1.1     pooka 	if ((error = iwm_run_init_mvm_ucode(sc, 0)) != 0) {
   5628   1.1     pooka 		return error;
   5629   1.1     pooka 	}
   5630   1.1     pooka 
   5631   1.1     pooka 	/*
   5632   1.1     pooka 	 * should stop and start HW since that INIT
   5633   1.1     pooka 	 * image just loaded
   5634   1.1     pooka 	 */
   5635   1.1     pooka 	iwm_stop_device(sc);
   5636   1.2    nonaka 	if ((error = iwm_start_hw(sc)) != 0) {
   5637   1.3    nonaka 		aprint_error_dev(sc->sc_dev, "could not initialize hardware\n");
   5638   1.1     pooka 		return error;
   5639   1.2    nonaka 	}
   5640   1.1     pooka 
   5641   1.1     pooka 	/* omstart, this time with the regular firmware */
   5642   1.1     pooka 	error = iwm_mvm_load_ucode_wait_alive(sc, IWM_UCODE_TYPE_REGULAR);
   5643   1.1     pooka 	if (error) {
   5644   1.3    nonaka 		aprint_error_dev(sc->sc_dev, "could not load firmware\n");
   5645   1.1     pooka 		goto error;
   5646   1.1     pooka 	}
   5647   1.1     pooka 
   5648   1.8    nonaka 	if ((error = iwm_send_tx_ant_cfg(sc, IWM_FW_VALID_TX_ANT(sc))) != 0)
   5649   1.8    nonaka 		goto error;
   5650   1.1     pooka 
   5651   1.8    nonaka 	/* Send phy db control command and then phy db calibration*/
   5652   1.8    nonaka 	if ((error = iwm_send_phy_db_data(sc)) != 0)
   5653   1.8    nonaka 		goto error;
   5654   1.1     pooka 
   5655   1.8    nonaka 	if ((error = iwm_send_phy_cfg_cmd(sc)) != 0)
   5656   1.8    nonaka 		goto error;
   5657   1.1     pooka 
   5658   1.1     pooka 	/* Add auxiliary station for scanning */
   5659   1.1     pooka 	if ((error = iwm_mvm_add_aux_sta(sc)) != 0)
   5660   1.1     pooka 		goto error;
   5661   1.1     pooka 
   5662   1.1     pooka 	for (i = 0; i < IWM_NUM_PHY_CTX; i++) {
   5663   1.1     pooka 		/*
   5664   1.1     pooka 		 * The channel used here isn't relevant as it's
   5665   1.1     pooka 		 * going to be overwritten in the other flows.
   5666   1.1     pooka 		 * For now use the first channel we have.
   5667   1.1     pooka 		 */
   5668   1.1     pooka 		if ((error = iwm_mvm_phy_ctxt_add(sc,
   5669   1.1     pooka 		    &sc->sc_phyctxt[i], &ic->ic_channels[1], 1, 1)) != 0)
   5670   1.1     pooka 			goto error;
   5671   1.1     pooka 	}
   5672   1.1     pooka 
   5673   1.8    nonaka 	error = iwm_mvm_power_update_device(sc);
   5674   1.8    nonaka 	if (error)
   5675   1.8    nonaka 		goto error;
   5676   1.1     pooka 
   5677   1.1     pooka 	/* Mark TX rings as active. */
   5678   1.1     pooka 	for (qid = 0; qid < 4; qid++) {
   5679   1.1     pooka 		iwm_enable_txq(sc, qid, qid);
   5680   1.1     pooka 	}
   5681   1.1     pooka 
   5682   1.1     pooka 	return 0;
   5683   1.1     pooka 
   5684   1.1     pooka  error:
   5685   1.1     pooka 	iwm_stop_device(sc);
   5686   1.1     pooka 	return error;
   5687   1.1     pooka }
   5688   1.1     pooka 
   5689  1.11    nonaka /* Allow multicast from our BSSID. */
   5690  1.11    nonaka static int
   5691  1.11    nonaka iwm_allow_mcast(struct iwm_softc *sc)
   5692  1.11    nonaka {
   5693  1.11    nonaka 	struct ieee80211com *ic = &sc->sc_ic;
   5694  1.11    nonaka 	struct ieee80211_node *ni = ic->ic_bss;
   5695  1.11    nonaka 	struct iwm_mcast_filter_cmd *cmd;
   5696  1.11    nonaka 	size_t size;
   5697  1.11    nonaka 	int error;
   5698  1.11    nonaka 
   5699  1.11    nonaka 	size = roundup(sizeof(*cmd), 4);
   5700  1.11    nonaka 	cmd = kmem_intr_zalloc(size, KM_NOSLEEP);
   5701  1.11    nonaka 	if (cmd == NULL)
   5702  1.11    nonaka 		return ENOMEM;
   5703  1.11    nonaka 	cmd->filter_own = 1;
   5704  1.11    nonaka 	cmd->port_id = 0;
   5705  1.11    nonaka 	cmd->count = 0;
   5706  1.11    nonaka 	cmd->pass_all = 1;
   5707  1.11    nonaka 	IEEE80211_ADDR_COPY(cmd->bssid, ni->ni_bssid);
   5708  1.11    nonaka 
   5709  1.11    nonaka 	error = iwm_mvm_send_cmd_pdu(sc, IWM_MCAST_FILTER_CMD,
   5710  1.11    nonaka 	    IWM_CMD_SYNC, size, cmd);
   5711  1.11    nonaka 	kmem_intr_free(cmd, size);
   5712  1.11    nonaka 	return error;
   5713  1.11    nonaka }
   5714  1.11    nonaka 
   5715   1.1     pooka /*
   5716   1.1     pooka  * ifnet interfaces
   5717   1.1     pooka  */
   5718   1.1     pooka 
   5719   1.4    nonaka static int
   5720   1.1     pooka iwm_init(struct ifnet *ifp)
   5721   1.1     pooka {
   5722   1.1     pooka 	struct iwm_softc *sc = ifp->if_softc;
   5723   1.1     pooka 	int error;
   5724   1.1     pooka 
   5725   1.1     pooka 	if (sc->sc_flags & IWM_FLAG_HW_INITED) {
   5726   1.1     pooka 		return 0;
   5727   1.1     pooka 	}
   5728   1.1     pooka 	sc->sc_generation++;
   5729   1.1     pooka 	sc->sc_flags &= ~IWM_FLAG_STOPPED;
   5730   1.1     pooka 
   5731   1.1     pooka 	if ((error = iwm_init_hw(sc)) != 0) {
   5732   1.1     pooka 		iwm_stop(ifp, 1);
   5733   1.1     pooka 		return error;
   5734   1.1     pooka 	}
   5735   1.1     pooka 
   5736   1.1     pooka 	/*
   5737   1.1     pooka  	 * Ok, firmware loaded and we are jogging
   5738   1.1     pooka 	 */
   5739   1.1     pooka 
   5740   1.1     pooka 	ifp->if_flags &= ~IFF_OACTIVE;
   5741   1.1     pooka 	ifp->if_flags |= IFF_RUNNING;
   5742   1.1     pooka 
   5743   1.1     pooka 	ieee80211_begin_scan(&sc->sc_ic, 0);
   5744   1.1     pooka 	sc->sc_flags |= IWM_FLAG_HW_INITED;
   5745   1.1     pooka 
   5746   1.1     pooka 	return 0;
   5747   1.1     pooka }
   5748   1.1     pooka 
   5749   1.1     pooka /*
   5750   1.1     pooka  * Dequeue packets from sendq and call send.
   5751   1.1     pooka  * mostly from iwn
   5752   1.1     pooka  */
   5753   1.4    nonaka static void
   5754   1.1     pooka iwm_start(struct ifnet *ifp)
   5755   1.1     pooka {
   5756   1.1     pooka 	struct iwm_softc *sc = ifp->if_softc;
   5757   1.1     pooka 	struct ieee80211com *ic = &sc->sc_ic;
   5758   1.1     pooka 	struct ieee80211_node *ni;
   5759   1.8    nonaka 	struct ether_header *eh;
   5760   1.1     pooka 	struct mbuf *m;
   5761   1.1     pooka 	int ac;
   5762   1.1     pooka 
   5763   1.1     pooka 	if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
   5764   1.1     pooka 		return;
   5765   1.1     pooka 
   5766   1.1     pooka 	for (;;) {
   5767   1.1     pooka 		/* why isn't this done per-queue? */
   5768   1.1     pooka 		if (sc->qfullmsk != 0) {
   5769   1.1     pooka 			ifp->if_flags |= IFF_OACTIVE;
   5770   1.1     pooka 			break;
   5771   1.1     pooka 		}
   5772   1.1     pooka 
   5773   1.1     pooka 		/* need to send management frames even if we're not RUNning */
   5774   1.1     pooka 		IF_DEQUEUE(&ic->ic_mgtq, m);
   5775   1.1     pooka 		if (m) {
   5776   1.1     pooka 			ni = (void *)m->m_pkthdr.rcvif;
   5777   1.1     pooka 			ac = 0;
   5778   1.1     pooka 			goto sendit;
   5779   1.1     pooka 		}
   5780   1.1     pooka 		if (ic->ic_state != IEEE80211_S_RUN) {
   5781   1.1     pooka 			break;
   5782   1.1     pooka 		}
   5783   1.1     pooka 
   5784   1.1     pooka 		IFQ_DEQUEUE(&ifp->if_snd, m);
   5785   1.1     pooka 		if (!m)
   5786   1.1     pooka 			break;
   5787   1.8    nonaka 		if (m->m_len < sizeof (*eh) &&
   5788   1.8    nonaka 		   (m = m_pullup(m, sizeof (*eh))) == NULL) {
   5789   1.8    nonaka 			ifp->if_oerrors++;
   5790   1.8    nonaka 			continue;
   5791   1.8    nonaka 		}
   5792   1.1     pooka 		if (ifp->if_bpf != NULL)
   5793   1.1     pooka 			bpf_mtap(ifp, m);
   5794   1.1     pooka 
   5795   1.1     pooka 		eh = mtod(m, struct ether_header *);
   5796   1.1     pooka 		ni = ieee80211_find_txnode(ic, eh->ether_dhost);
   5797   1.1     pooka 		if (ni == NULL) {
   5798   1.1     pooka 			m_freem(m);
   5799   1.1     pooka 			ifp->if_oerrors++;
   5800   1.1     pooka 			continue;
   5801   1.1     pooka 		}
   5802   1.1     pooka 		/* classify mbuf so we can find which tx ring to use */
   5803   1.1     pooka 		if (ieee80211_classify(ic, m, ni) != 0) {
   5804   1.1     pooka 			m_freem(m);
   5805   1.1     pooka 			ieee80211_free_node(ni);
   5806   1.1     pooka 			ifp->if_oerrors++;
   5807   1.1     pooka 			continue;
   5808   1.1     pooka 		}
   5809   1.1     pooka 
   5810   1.1     pooka 		/* No QoS encapsulation for EAPOL frames. */
   5811   1.1     pooka 		ac = (eh->ether_type != htons(ETHERTYPE_PAE)) ?
   5812   1.1     pooka 		    M_WME_GETAC(m) : WME_AC_BE;
   5813   1.1     pooka 
   5814   1.1     pooka 		if ((m = ieee80211_encap(ic, m, ni)) == NULL) {
   5815   1.1     pooka 			ieee80211_free_node(ni);
   5816   1.1     pooka 			ifp->if_oerrors++;
   5817   1.1     pooka 			continue;
   5818   1.1     pooka 		}
   5819   1.1     pooka 
   5820   1.1     pooka  sendit:
   5821   1.1     pooka 		if (ic->ic_rawbpf != NULL)
   5822   1.1     pooka 			bpf_mtap3(ic->ic_rawbpf, m);
   5823   1.1     pooka 		if (iwm_tx(sc, m, ni, ac) != 0) {
   5824   1.1     pooka 			ieee80211_free_node(ni);
   5825   1.1     pooka 			ifp->if_oerrors++;
   5826   1.1     pooka 			continue;
   5827   1.1     pooka 		}
   5828   1.1     pooka 
   5829   1.1     pooka 		if (ifp->if_flags & IFF_UP) {
   5830   1.1     pooka 			sc->sc_tx_timer = 15;
   5831   1.1     pooka 			ifp->if_timer = 1;
   5832   1.1     pooka 		}
   5833   1.1     pooka 	}
   5834   1.1     pooka 
   5835   1.1     pooka 	return;
   5836   1.1     pooka }
   5837   1.1     pooka 
   5838   1.4    nonaka static void
   5839   1.1     pooka iwm_stop(struct ifnet *ifp, int disable)
   5840   1.1     pooka {
   5841   1.1     pooka 	struct iwm_softc *sc = ifp->if_softc;
   5842   1.1     pooka 	struct ieee80211com *ic = &sc->sc_ic;
   5843   1.1     pooka 
   5844   1.1     pooka 	sc->sc_flags &= ~IWM_FLAG_HW_INITED;
   5845   1.1     pooka 	sc->sc_flags |= IWM_FLAG_STOPPED;
   5846   1.1     pooka 	sc->sc_generation++;
   5847   1.1     pooka 	sc->sc_scanband = 0;
   5848   1.1     pooka 	sc->sc_auth_prot = 0;
   5849   1.1     pooka 	ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
   5850   1.1     pooka 
   5851   1.1     pooka 	if (ic->ic_state != IEEE80211_S_INIT)
   5852   1.1     pooka 		ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
   5853   1.1     pooka 
   5854  1.26    nonaka 	callout_stop(&sc->sc_calib_to);
   5855   1.1     pooka 	ifp->if_timer = sc->sc_tx_timer = 0;
   5856   1.1     pooka 	iwm_stop_device(sc);
   5857   1.1     pooka }
   5858   1.1     pooka 
   5859   1.4    nonaka static void
   5860   1.1     pooka iwm_watchdog(struct ifnet *ifp)
   5861   1.1     pooka {
   5862   1.1     pooka 	struct iwm_softc *sc = ifp->if_softc;
   5863   1.1     pooka 
   5864   1.1     pooka 	ifp->if_timer = 0;
   5865   1.1     pooka 	if (sc->sc_tx_timer > 0) {
   5866   1.1     pooka 		if (--sc->sc_tx_timer == 0) {
   5867   1.5    nonaka 			aprint_error_dev(sc->sc_dev, "device timeout\n");
   5868   1.2    nonaka #ifdef IWM_DEBUG
   5869   1.1     pooka 			iwm_nic_error(sc);
   5870   1.2    nonaka #endif
   5871   1.1     pooka 			ifp->if_flags &= ~IFF_UP;
   5872   1.1     pooka 			iwm_stop(ifp, 1);
   5873   1.1     pooka 			ifp->if_oerrors++;
   5874   1.1     pooka 			return;
   5875   1.1     pooka 		}
   5876   1.1     pooka 		ifp->if_timer = 1;
   5877   1.1     pooka 	}
   5878   1.1     pooka 
   5879   1.1     pooka 	ieee80211_watchdog(&sc->sc_ic);
   5880   1.1     pooka }
   5881   1.1     pooka 
   5882   1.4    nonaka static int
   5883   1.1     pooka iwm_ioctl(struct ifnet *ifp, u_long cmd, void *data)
   5884   1.1     pooka {
   5885   1.1     pooka 	struct iwm_softc *sc = ifp->if_softc;
   5886   1.1     pooka 	struct ieee80211com *ic = &sc->sc_ic;
   5887   1.1     pooka 	const struct sockaddr *sa;
   5888   1.1     pooka 	int s, error = 0;
   5889   1.1     pooka 
   5890   1.1     pooka 	s = splnet();
   5891   1.1     pooka 
   5892   1.1     pooka 	switch (cmd) {
   5893   1.1     pooka 	case SIOCSIFADDR:
   5894   1.1     pooka 		ifp->if_flags |= IFF_UP;
   5895   1.1     pooka 		/* FALLTHROUGH */
   5896   1.1     pooka 	case SIOCSIFFLAGS:
   5897   1.1     pooka 		if ((error = ifioctl_common(ifp, cmd, data)) != 0)
   5898   1.1     pooka 			break;
   5899   1.1     pooka 		if (ifp->if_flags & IFF_UP) {
   5900   1.1     pooka 			if (!(ifp->if_flags & IFF_RUNNING)) {
   5901   1.1     pooka 				if ((error = iwm_init(ifp)) != 0)
   5902   1.1     pooka 					ifp->if_flags &= ~IFF_UP;
   5903   1.1     pooka 			}
   5904   1.1     pooka 		} else {
   5905   1.1     pooka 			if (ifp->if_flags & IFF_RUNNING)
   5906   1.1     pooka 				iwm_stop(ifp, 1);
   5907   1.1     pooka 		}
   5908   1.1     pooka 		break;
   5909   1.1     pooka 
   5910   1.1     pooka 	case SIOCADDMULTI:
   5911   1.1     pooka 	case SIOCDELMULTI:
   5912   1.1     pooka 		sa = ifreq_getaddr(SIOCADDMULTI, (struct ifreq *)data);
   5913   1.1     pooka 		error = (cmd == SIOCADDMULTI) ?
   5914   1.1     pooka 		    ether_addmulti(sa, &sc->sc_ec) :
   5915   1.1     pooka 		    ether_delmulti(sa, &sc->sc_ec);
   5916   1.1     pooka 
   5917   1.1     pooka 		if (error == ENETRESET)
   5918   1.1     pooka 			error = 0;
   5919   1.1     pooka 		break;
   5920   1.1     pooka 
   5921   1.1     pooka 	default:
   5922   1.1     pooka 		error = ieee80211_ioctl(ic, cmd, data);
   5923   1.1     pooka 	}
   5924   1.1     pooka 
   5925   1.1     pooka 	if (error == ENETRESET) {
   5926   1.1     pooka 		error = 0;
   5927   1.1     pooka 		if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
   5928   1.1     pooka 		    (IFF_UP | IFF_RUNNING)) {
   5929   1.1     pooka 			iwm_stop(ifp, 0);
   5930   1.1     pooka 			error = iwm_init(ifp);
   5931   1.1     pooka 		}
   5932   1.1     pooka 	}
   5933   1.1     pooka 
   5934   1.1     pooka 	splx(s);
   5935   1.1     pooka 	return error;
   5936   1.1     pooka }
   5937   1.1     pooka 
   5938   1.1     pooka /*
   5939   1.1     pooka  * The interrupt side of things
   5940   1.1     pooka  */
   5941   1.1     pooka 
   5942   1.1     pooka /*
   5943   1.1     pooka  * error dumping routines are from iwlwifi/mvm/utils.c
   5944   1.1     pooka  */
   5945   1.1     pooka 
   5946   1.1     pooka /*
   5947   1.1     pooka  * Note: This structure is read from the device with IO accesses,
   5948   1.1     pooka  * and the reading already does the endian conversion. As it is
   5949   1.1     pooka  * read with uint32_t-sized accesses, any members with a different size
   5950   1.1     pooka  * need to be ordered correctly though!
   5951   1.1     pooka  */
   5952   1.1     pooka struct iwm_error_event_table {
   5953   1.1     pooka 	uint32_t valid;		/* (nonzero) valid, (0) log is empty */
   5954   1.1     pooka 	uint32_t error_id;		/* type of error */
   5955   1.1     pooka 	uint32_t pc;			/* program counter */
   5956   1.1     pooka 	uint32_t blink1;		/* branch link */
   5957   1.1     pooka 	uint32_t blink2;		/* branch link */
   5958   1.1     pooka 	uint32_t ilink1;		/* interrupt link */
   5959   1.1     pooka 	uint32_t ilink2;		/* interrupt link */
   5960   1.1     pooka 	uint32_t data1;		/* error-specific data */
   5961   1.1     pooka 	uint32_t data2;		/* error-specific data */
   5962   1.1     pooka 	uint32_t data3;		/* error-specific data */
   5963   1.1     pooka 	uint32_t bcon_time;		/* beacon timer */
   5964   1.1     pooka 	uint32_t tsf_low;		/* network timestamp function timer */
   5965   1.1     pooka 	uint32_t tsf_hi;		/* network timestamp function timer */
   5966   1.1     pooka 	uint32_t gp1;		/* GP1 timer register */
   5967   1.1     pooka 	uint32_t gp2;		/* GP2 timer register */
   5968   1.1     pooka 	uint32_t gp3;		/* GP3 timer register */
   5969   1.1     pooka 	uint32_t ucode_ver;		/* uCode version */
   5970   1.1     pooka 	uint32_t hw_ver;		/* HW Silicon version */
   5971   1.1     pooka 	uint32_t brd_ver;		/* HW board version */
   5972   1.1     pooka 	uint32_t log_pc;		/* log program counter */
   5973   1.1     pooka 	uint32_t frame_ptr;		/* frame pointer */
   5974   1.1     pooka 	uint32_t stack_ptr;		/* stack pointer */
   5975   1.1     pooka 	uint32_t hcmd;		/* last host command header */
   5976   1.1     pooka 	uint32_t isr0;		/* isr status register LMPM_NIC_ISR0:
   5977   1.1     pooka 				 * rxtx_flag */
   5978   1.1     pooka 	uint32_t isr1;		/* isr status register LMPM_NIC_ISR1:
   5979   1.1     pooka 				 * host_flag */
   5980   1.1     pooka 	uint32_t isr2;		/* isr status register LMPM_NIC_ISR2:
   5981   1.1     pooka 				 * enc_flag */
   5982   1.1     pooka 	uint32_t isr3;		/* isr status register LMPM_NIC_ISR3:
   5983   1.1     pooka 				 * time_flag */
   5984   1.1     pooka 	uint32_t isr4;		/* isr status register LMPM_NIC_ISR4:
   5985   1.1     pooka 				 * wico interrupt */
   5986   1.1     pooka 	uint32_t isr_pref;		/* isr status register LMPM_NIC_PREF_STAT */
   5987   1.1     pooka 	uint32_t wait_event;		/* wait event() caller address */
   5988   1.1     pooka 	uint32_t l2p_control;	/* L2pControlField */
   5989   1.1     pooka 	uint32_t l2p_duration;	/* L2pDurationField */
   5990   1.1     pooka 	uint32_t l2p_mhvalid;	/* L2pMhValidBits */
   5991   1.1     pooka 	uint32_t l2p_addr_match;	/* L2pAddrMatchStat */
   5992   1.1     pooka 	uint32_t lmpm_pmg_sel;	/* indicate which clocks are turned on
   5993   1.1     pooka 				 * (LMPM_PMG_SEL) */
   5994   1.1     pooka 	uint32_t u_timestamp;	/* indicate when the date and time of the
   5995   1.1     pooka 				 * compilation */
   5996   1.1     pooka 	uint32_t flow_handler;	/* FH read/write pointers, RX credit */
   5997   1.1     pooka } __packed;
   5998   1.1     pooka 
   5999   1.1     pooka #define ERROR_START_OFFSET  (1 * sizeof(uint32_t))
   6000   1.1     pooka #define ERROR_ELEM_SIZE     (7 * sizeof(uint32_t))
   6001   1.1     pooka 
   6002   1.4    nonaka #ifdef IWM_DEBUG
   6003   1.4    nonaka static const struct {
   6004   1.1     pooka 	const char *name;
   6005   1.1     pooka 	uint8_t num;
   6006   1.1     pooka } advanced_lookup[] = {
   6007   1.1     pooka 	{ "NMI_INTERRUPT_WDG", 0x34 },
   6008   1.1     pooka 	{ "SYSASSERT", 0x35 },
   6009   1.1     pooka 	{ "UCODE_VERSION_MISMATCH", 0x37 },
   6010   1.1     pooka 	{ "BAD_COMMAND", 0x38 },
   6011   1.1     pooka 	{ "NMI_INTERRUPT_DATA_ACTION_PT", 0x3C },
   6012   1.1     pooka 	{ "FATAL_ERROR", 0x3D },
   6013   1.1     pooka 	{ "NMI_TRM_HW_ERR", 0x46 },
   6014   1.1     pooka 	{ "NMI_INTERRUPT_TRM", 0x4C },
   6015   1.1     pooka 	{ "NMI_INTERRUPT_BREAK_POINT", 0x54 },
   6016   1.1     pooka 	{ "NMI_INTERRUPT_WDG_RXF_FULL", 0x5C },
   6017   1.1     pooka 	{ "NMI_INTERRUPT_WDG_NO_RBD_RXF_FULL", 0x64 },
   6018   1.1     pooka 	{ "NMI_INTERRUPT_HOST", 0x66 },
   6019   1.1     pooka 	{ "NMI_INTERRUPT_ACTION_PT", 0x7C },
   6020   1.1     pooka 	{ "NMI_INTERRUPT_UNKNOWN", 0x84 },
   6021   1.1     pooka 	{ "NMI_INTERRUPT_INST_ACTION_PT", 0x86 },
   6022   1.1     pooka 	{ "ADVANCED_SYSASSERT", 0 },
   6023   1.1     pooka };
   6024   1.1     pooka 
   6025   1.4    nonaka static const char *
   6026   1.1     pooka iwm_desc_lookup(uint32_t num)
   6027   1.1     pooka {
   6028   1.1     pooka 	int i;
   6029   1.1     pooka 
   6030   1.1     pooka 	for (i = 0; i < __arraycount(advanced_lookup) - 1; i++)
   6031   1.1     pooka 		if (advanced_lookup[i].num == num)
   6032   1.1     pooka 			return advanced_lookup[i].name;
   6033   1.1     pooka 
   6034   1.1     pooka 	/* No entry matches 'num', so it is the last: ADVANCED_SYSASSERT */
   6035   1.1     pooka 	return advanced_lookup[i].name;
   6036   1.1     pooka }
   6037   1.1     pooka 
   6038   1.1     pooka /*
   6039   1.1     pooka  * Support for dumping the error log seemed like a good idea ...
   6040   1.1     pooka  * but it's mostly hex junk and the only sensible thing is the
   6041   1.1     pooka  * hw/ucode revision (which we know anyway).  Since it's here,
   6042   1.1     pooka  * I'll just leave it in, just in case e.g. the Intel guys want to
   6043   1.1     pooka  * help us decipher some "ADVANCED_SYSASSERT" later.
   6044   1.1     pooka  */
   6045   1.4    nonaka static void
   6046   1.1     pooka iwm_nic_error(struct iwm_softc *sc)
   6047   1.1     pooka {
   6048   1.1     pooka 	struct iwm_error_event_table table;
   6049   1.1     pooka 	uint32_t base;
   6050   1.1     pooka 
   6051   1.3    nonaka 	aprint_error_dev(sc->sc_dev, "dumping device error log\n");
   6052   1.1     pooka 	base = sc->sc_uc.uc_error_event_table;
   6053   1.1     pooka 	if (base < 0x800000 || base >= 0x80C000) {
   6054   1.3    nonaka 		aprint_error_dev(sc->sc_dev,
   6055   1.3    nonaka 		    "Not valid error log pointer 0x%08x\n", base);
   6056   1.1     pooka 		return;
   6057   1.1     pooka 	}
   6058   1.1     pooka 
   6059   1.1     pooka 	if (iwm_read_mem(sc, base, &table, sizeof(table)/sizeof(uint32_t)) != 0) {
   6060   1.3    nonaka 		aprint_error_dev(sc->sc_dev, "reading errlog failed\n");
   6061   1.1     pooka 		return;
   6062   1.1     pooka 	}
   6063   1.1     pooka 
   6064   1.1     pooka 	if (!table.valid) {
   6065   1.3    nonaka 		aprint_error_dev(sc->sc_dev, "errlog not found, skipping\n");
   6066   1.1     pooka 		return;
   6067   1.1     pooka 	}
   6068   1.1     pooka 
   6069   1.1     pooka 	if (ERROR_START_OFFSET <= table.valid * ERROR_ELEM_SIZE) {
   6070   1.3    nonaka 		aprint_error_dev(sc->sc_dev, "Start IWL Error Log Dump:\n");
   6071   1.3    nonaka 		aprint_error_dev(sc->sc_dev, "Status: 0x%x, count: %d\n",
   6072   1.1     pooka 		    sc->sc_flags, table.valid);
   6073   1.1     pooka 	}
   6074   1.1     pooka 
   6075   1.3    nonaka 	aprint_error_dev(sc->sc_dev, "%08X | %-28s\n", table.error_id,
   6076   1.1     pooka 		iwm_desc_lookup(table.error_id));
   6077   1.3    nonaka 	aprint_error_dev(sc->sc_dev, "%08X | uPc\n", table.pc);
   6078   1.3    nonaka 	aprint_error_dev(sc->sc_dev, "%08X | branchlink1\n", table.blink1);
   6079   1.3    nonaka 	aprint_error_dev(sc->sc_dev, "%08X | branchlink2\n", table.blink2);
   6080   1.3    nonaka 	aprint_error_dev(sc->sc_dev, "%08X | interruptlink1\n", table.ilink1);
   6081   1.3    nonaka 	aprint_error_dev(sc->sc_dev, "%08X | interruptlink2\n", table.ilink2);
   6082   1.3    nonaka 	aprint_error_dev(sc->sc_dev, "%08X | data1\n", table.data1);
   6083   1.3    nonaka 	aprint_error_dev(sc->sc_dev, "%08X | data2\n", table.data2);
   6084   1.3    nonaka 	aprint_error_dev(sc->sc_dev, "%08X | data3\n", table.data3);
   6085   1.3    nonaka 	aprint_error_dev(sc->sc_dev, "%08X | beacon time\n", table.bcon_time);
   6086   1.3    nonaka 	aprint_error_dev(sc->sc_dev, "%08X | tsf low\n", table.tsf_low);
   6087   1.3    nonaka 	aprint_error_dev(sc->sc_dev, "%08X | tsf hi\n", table.tsf_hi);
   6088   1.3    nonaka 	aprint_error_dev(sc->sc_dev, "%08X | time gp1\n", table.gp1);
   6089   1.3    nonaka 	aprint_error_dev(sc->sc_dev, "%08X | time gp2\n", table.gp2);
   6090   1.3    nonaka 	aprint_error_dev(sc->sc_dev, "%08X | time gp3\n", table.gp3);
   6091   1.3    nonaka 	aprint_error_dev(sc->sc_dev, "%08X | uCode version\n", table.ucode_ver);
   6092   1.3    nonaka 	aprint_error_dev(sc->sc_dev, "%08X | hw version\n", table.hw_ver);
   6093   1.3    nonaka 	aprint_error_dev(sc->sc_dev, "%08X | board version\n", table.brd_ver);
   6094   1.3    nonaka 	aprint_error_dev(sc->sc_dev, "%08X | hcmd\n", table.hcmd);
   6095   1.3    nonaka 	aprint_error_dev(sc->sc_dev, "%08X | isr0\n", table.isr0);
   6096   1.3    nonaka 	aprint_error_dev(sc->sc_dev, "%08X | isr1\n", table.isr1);
   6097   1.3    nonaka 	aprint_error_dev(sc->sc_dev, "%08X | isr2\n", table.isr2);
   6098   1.3    nonaka 	aprint_error_dev(sc->sc_dev, "%08X | isr3\n", table.isr3);
   6099   1.3    nonaka 	aprint_error_dev(sc->sc_dev, "%08X | isr4\n", table.isr4);
   6100   1.3    nonaka 	aprint_error_dev(sc->sc_dev, "%08X | isr_pref\n", table.isr_pref);
   6101   1.3    nonaka 	aprint_error_dev(sc->sc_dev, "%08X | wait_event\n", table.wait_event);
   6102   1.3    nonaka 	aprint_error_dev(sc->sc_dev, "%08X | l2p_control\n", table.l2p_control);
   6103   1.3    nonaka 	aprint_error_dev(sc->sc_dev, "%08X | l2p_duration\n",
   6104   1.3    nonaka 	    table.l2p_duration);
   6105   1.3    nonaka 	aprint_error_dev(sc->sc_dev, "%08X | l2p_mhvalid\n", table.l2p_mhvalid);
   6106   1.3    nonaka 	aprint_error_dev(sc->sc_dev, "%08X | l2p_addr_match\n",
   6107   1.3    nonaka 	    table.l2p_addr_match);
   6108   1.3    nonaka 	aprint_error_dev(sc->sc_dev, "%08X | lmpm_pmg_sel\n",
   6109   1.3    nonaka 	    table.lmpm_pmg_sel);
   6110   1.3    nonaka 	aprint_error_dev(sc->sc_dev, "%08X | timestamp\n", table.u_timestamp);
   6111   1.3    nonaka 	aprint_error_dev(sc->sc_dev, "%08X | flow_handler\n",
   6112   1.3    nonaka 	    table.flow_handler);
   6113   1.1     pooka }
   6114   1.2    nonaka #endif
   6115   1.1     pooka 
   6116   1.1     pooka #define SYNC_RESP_STRUCT(_var_, _pkt_)					\
   6117   1.1     pooka do {									\
   6118   1.1     pooka 	bus_dmamap_sync(sc->sc_dmat, data->map, sizeof(*(_pkt_)),	\
   6119   1.1     pooka 	    sizeof(*(_var_)), BUS_DMASYNC_POSTREAD);			\
   6120   1.1     pooka 	_var_ = (void *)((_pkt_)+1);					\
   6121   1.1     pooka } while (/*CONSTCOND*/0)
   6122   1.1     pooka 
   6123   1.1     pooka #define SYNC_RESP_PTR(_ptr_, _len_, _pkt_)				\
   6124   1.1     pooka do {									\
   6125   1.1     pooka 	bus_dmamap_sync(sc->sc_dmat, data->map, sizeof(*(_pkt_)),	\
   6126   1.1     pooka 	    sizeof(len), BUS_DMASYNC_POSTREAD);				\
   6127   1.1     pooka 	_ptr_ = (void *)((_pkt_)+1);					\
   6128   1.1     pooka } while (/*CONSTCOND*/0)
   6129   1.1     pooka 
   6130   1.1     pooka #define ADVANCE_RXQ(sc) (sc->rxq.cur = (sc->rxq.cur + 1) % IWM_RX_RING_COUNT);
   6131   1.1     pooka 
   6132   1.1     pooka /*
   6133   1.1     pooka  * Process an IWM_CSR_INT_BIT_FH_RX or IWM_CSR_INT_BIT_SW_RX interrupt.
   6134   1.1     pooka  * Basic structure from if_iwn
   6135   1.1     pooka  */
   6136   1.4    nonaka static void
   6137   1.1     pooka iwm_notif_intr(struct iwm_softc *sc)
   6138   1.1     pooka {
   6139   1.1     pooka 	uint16_t hw;
   6140   1.1     pooka 
   6141   1.1     pooka 	bus_dmamap_sync(sc->sc_dmat, sc->rxq.stat_dma.map,
   6142   1.1     pooka 	    0, sc->rxq.stat_dma.size, BUS_DMASYNC_POSTREAD);
   6143   1.1     pooka 
   6144   1.1     pooka 	hw = le16toh(sc->rxq.stat->closed_rb_num) & 0xfff;
   6145   1.1     pooka 	while (sc->rxq.cur != hw) {
   6146   1.1     pooka 		struct iwm_rx_data *data = &sc->rxq.data[sc->rxq.cur];
   6147   1.5    nonaka 		struct iwm_rx_packet *pkt, tmppkt;
   6148   1.1     pooka 		struct iwm_cmd_response *cresp;
   6149   1.1     pooka 		int qid, idx;
   6150   1.1     pooka 
   6151   1.1     pooka 		bus_dmamap_sync(sc->sc_dmat, data->map, 0, sizeof(*pkt),
   6152   1.1     pooka 		    BUS_DMASYNC_POSTREAD);
   6153   1.1     pooka 		pkt = mtod(data->m, struct iwm_rx_packet *);
   6154   1.1     pooka 
   6155   1.1     pooka 		qid = pkt->hdr.qid & ~0x80;
   6156   1.1     pooka 		idx = pkt->hdr.idx;
   6157   1.1     pooka 
   6158   1.1     pooka 		DPRINTFN(12, ("rx packet qid=%d idx=%d flags=%x type=%x %d %d\n",
   6159   1.1     pooka 		    pkt->hdr.qid & ~0x80, pkt->hdr.idx, pkt->hdr.flags,
   6160   1.1     pooka 		    pkt->hdr.code, sc->rxq.cur, hw));
   6161   1.1     pooka 
   6162   1.1     pooka 		/*
   6163   1.1     pooka 		 * randomly get these from the firmware, no idea why.
   6164   1.1     pooka 		 * they at least seem harmless, so just ignore them for now
   6165   1.1     pooka 		 */
   6166   1.1     pooka 		if (__predict_false((pkt->hdr.code == 0 && qid == 0 && idx == 0)
   6167   1.1     pooka 		    || pkt->len_n_flags == htole32(0x55550000))) {
   6168   1.1     pooka 			ADVANCE_RXQ(sc);
   6169   1.1     pooka 			continue;
   6170   1.1     pooka 		}
   6171   1.1     pooka 
   6172   1.1     pooka 		switch (pkt->hdr.code) {
   6173   1.1     pooka 		case IWM_REPLY_RX_PHY_CMD:
   6174   1.1     pooka 			iwm_mvm_rx_rx_phy_cmd(sc, pkt, data);
   6175   1.1     pooka 			break;
   6176   1.1     pooka 
   6177   1.1     pooka 		case IWM_REPLY_RX_MPDU_CMD:
   6178   1.5    nonaka 			tmppkt = *pkt; // XXX m is freed by ieee80211_input()
   6179   1.1     pooka 			iwm_mvm_rx_rx_mpdu(sc, pkt, data);
   6180   1.5    nonaka 			pkt = &tmppkt;
   6181   1.1     pooka 			break;
   6182   1.1     pooka 
   6183   1.1     pooka 		case IWM_TX_CMD:
   6184   1.1     pooka 			iwm_mvm_rx_tx_cmd(sc, pkt, data);
   6185   1.1     pooka 			break;
   6186   1.1     pooka 
   6187   1.1     pooka 		case IWM_MISSED_BEACONS_NOTIFICATION:
   6188   1.1     pooka 			iwm_mvm_rx_missed_beacons_notif(sc, pkt, data);
   6189   1.1     pooka 			break;
   6190   1.1     pooka 
   6191   1.1     pooka 		case IWM_MVM_ALIVE: {
   6192   1.1     pooka 			struct iwm_mvm_alive_resp *resp;
   6193   1.1     pooka 			SYNC_RESP_STRUCT(resp, pkt);
   6194   1.1     pooka 
   6195   1.1     pooka 			sc->sc_uc.uc_error_event_table
   6196   1.1     pooka 			    = le32toh(resp->error_event_table_ptr);
   6197   1.1     pooka 			sc->sc_uc.uc_log_event_table
   6198   1.1     pooka 			    = le32toh(resp->log_event_table_ptr);
   6199   1.1     pooka 			sc->sched_base = le32toh(resp->scd_base_ptr);
   6200   1.1     pooka 			sc->sc_uc.uc_ok = resp->status == IWM_ALIVE_STATUS_OK;
   6201   1.1     pooka 
   6202   1.1     pooka 			sc->sc_uc.uc_intr = 1;
   6203   1.1     pooka 			wakeup(&sc->sc_uc);
   6204   1.1     pooka 			break; }
   6205   1.1     pooka 
   6206   1.1     pooka 		case IWM_CALIB_RES_NOTIF_PHY_DB: {
   6207   1.1     pooka 			struct iwm_calib_res_notif_phy_db *phy_db_notif;
   6208   1.1     pooka 			SYNC_RESP_STRUCT(phy_db_notif, pkt);
   6209   1.1     pooka 
   6210   1.5    nonaka 			uint16_t size = le16toh(phy_db_notif->length);
   6211   1.5    nonaka 			bus_dmamap_sync(sc->sc_dmat, data->map,
   6212   1.5    nonaka 			    sizeof(*pkt) + sizeof(*phy_db_notif),
   6213   1.5    nonaka 			    size, BUS_DMASYNC_POSTREAD);
   6214   1.5    nonaka 			iwm_phy_db_set_section(sc, phy_db_notif, size);
   6215   1.1     pooka 
   6216   1.1     pooka 			break; }
   6217   1.1     pooka 
   6218   1.1     pooka 		case IWM_STATISTICS_NOTIFICATION: {
   6219   1.1     pooka 			struct iwm_notif_statistics *stats;
   6220   1.1     pooka 			SYNC_RESP_STRUCT(stats, pkt);
   6221   1.1     pooka 			memcpy(&sc->sc_stats, stats, sizeof(sc->sc_stats));
   6222   1.1     pooka 			sc->sc_noise = iwm_get_noise(&stats->rx.general);
   6223   1.1     pooka 			break; }
   6224   1.1     pooka 
   6225   1.1     pooka 		case IWM_NVM_ACCESS_CMD:
   6226   1.1     pooka 			if (sc->sc_wantresp == ((qid << 16) | idx)) {
   6227   1.1     pooka 				bus_dmamap_sync(sc->sc_dmat, data->map, 0,
   6228   1.1     pooka 				    sizeof(sc->sc_cmd_resp),
   6229   1.1     pooka 				    BUS_DMASYNC_POSTREAD);
   6230   1.1     pooka 				memcpy(sc->sc_cmd_resp,
   6231   1.1     pooka 				    pkt, sizeof(sc->sc_cmd_resp));
   6232   1.1     pooka 			}
   6233   1.1     pooka 			break;
   6234   1.1     pooka 
   6235   1.1     pooka 		case IWM_PHY_CONFIGURATION_CMD:
   6236   1.1     pooka 		case IWM_TX_ANT_CONFIGURATION_CMD:
   6237   1.1     pooka 		case IWM_ADD_STA:
   6238   1.1     pooka 		case IWM_MAC_CONTEXT_CMD:
   6239   1.1     pooka 		case IWM_REPLY_SF_CFG_CMD:
   6240   1.1     pooka 		case IWM_POWER_TABLE_CMD:
   6241   1.1     pooka 		case IWM_PHY_CONTEXT_CMD:
   6242   1.1     pooka 		case IWM_BINDING_CONTEXT_CMD:
   6243   1.1     pooka 		case IWM_TIME_EVENT_CMD:
   6244   1.1     pooka 		case IWM_SCAN_REQUEST_CMD:
   6245   1.1     pooka 		case IWM_REPLY_BEACON_FILTERING_CMD:
   6246   1.1     pooka 		case IWM_MAC_PM_POWER_TABLE:
   6247   1.1     pooka 		case IWM_TIME_QUOTA_CMD:
   6248   1.1     pooka 		case IWM_REMOVE_STA:
   6249   1.1     pooka 		case IWM_TXPATH_FLUSH:
   6250   1.1     pooka 		case IWM_LQ_CMD:
   6251   1.1     pooka 			SYNC_RESP_STRUCT(cresp, pkt);
   6252   1.1     pooka 			if (sc->sc_wantresp == ((qid << 16) | idx)) {
   6253   1.1     pooka 				memcpy(sc->sc_cmd_resp,
   6254   1.1     pooka 				    pkt, sizeof(*pkt)+sizeof(*cresp));
   6255   1.1     pooka 			}
   6256   1.1     pooka 			break;
   6257   1.1     pooka 
   6258   1.1     pooka 		/* ignore */
   6259   1.1     pooka 		case 0x6c: /* IWM_PHY_DB_CMD, no idea why it's not in fw-api.h */
   6260   1.1     pooka 			break;
   6261   1.1     pooka 
   6262   1.1     pooka 		case IWM_INIT_COMPLETE_NOTIF:
   6263   1.1     pooka 			sc->sc_init_complete = 1;
   6264   1.1     pooka 			wakeup(&sc->sc_init_complete);
   6265   1.1     pooka 			break;
   6266   1.1     pooka 
   6267   1.1     pooka 		case IWM_SCAN_COMPLETE_NOTIFICATION: {
   6268   1.1     pooka 			struct iwm_scan_complete_notif *notif;
   6269   1.1     pooka 			SYNC_RESP_STRUCT(notif, pkt);
   6270   1.1     pooka 
   6271   1.1     pooka 			workqueue_enqueue(sc->sc_eswq, &sc->sc_eswk, NULL);
   6272   1.1     pooka 			break; }
   6273   1.1     pooka 
   6274   1.1     pooka 		case IWM_REPLY_ERROR: {
   6275   1.1     pooka 			struct iwm_error_resp *resp;
   6276   1.1     pooka 			SYNC_RESP_STRUCT(resp, pkt);
   6277   1.1     pooka 
   6278   1.3    nonaka 			aprint_error_dev(sc->sc_dev,
   6279   1.3    nonaka 			    "firmware error 0x%x, cmd 0x%x\n",
   6280   1.3    nonaka 			    le32toh(resp->error_type), resp->cmd_id);
   6281   1.1     pooka 			break; }
   6282   1.1     pooka 
   6283   1.1     pooka 		case IWM_TIME_EVENT_NOTIFICATION: {
   6284   1.1     pooka 			struct iwm_time_event_notif *notif;
   6285   1.1     pooka 			SYNC_RESP_STRUCT(notif, pkt);
   6286   1.8    nonaka 
   6287   1.1     pooka 			if (notif->status) {
   6288   1.1     pooka 				if (le32toh(notif->action) &
   6289   1.1     pooka 				    IWM_TE_V2_NOTIF_HOST_EVENT_START)
   6290   1.1     pooka 					sc->sc_auth_prot = 2;
   6291   1.1     pooka 				else
   6292   1.1     pooka 					sc->sc_auth_prot = 0;
   6293   1.1     pooka 			} else {
   6294   1.1     pooka 				sc->sc_auth_prot = -1;
   6295   1.1     pooka 			}
   6296   1.1     pooka 			wakeup(&sc->sc_auth_prot);
   6297   1.1     pooka 			break; }
   6298   1.1     pooka 
   6299  1.11    nonaka 		case IWM_MCAST_FILTER_CMD:
   6300  1.11    nonaka 			break;
   6301  1.11    nonaka 
   6302   1.1     pooka 		default:
   6303   1.3    nonaka 			aprint_error_dev(sc->sc_dev,
   6304  1.15    nonaka 			    "code %02x frame %d/%d %x UNHANDLED "
   6305  1.15    nonaka 			    "(this should not happen)\n",
   6306  1.15    nonaka 			    pkt->hdr.code, qid, idx, pkt->len_n_flags);
   6307   1.1     pooka 			break;
   6308   1.1     pooka 		}
   6309   1.1     pooka 
   6310   1.1     pooka 		/*
   6311   1.1     pooka 		 * Why test bit 0x80?  The Linux driver:
   6312   1.1     pooka 		 *
   6313   1.1     pooka 		 * There is one exception:  uCode sets bit 15 when it
   6314   1.1     pooka 		 * originates the response/notification, i.e. when the
   6315   1.1     pooka 		 * response/notification is not a direct response to a
   6316   1.1     pooka 		 * command sent by the driver.  For example, uCode issues
   6317   1.1     pooka 		 * IWM_REPLY_RX when it sends a received frame to the driver;
   6318   1.1     pooka 		 * it is not a direct response to any driver command.
   6319   1.1     pooka 		 *
   6320   1.1     pooka 		 * Ok, so since when is 7 == 15?  Well, the Linux driver
   6321   1.1     pooka 		 * uses a slightly different format for pkt->hdr, and "qid"
   6322   1.1     pooka 		 * is actually the upper byte of a two-byte field.
   6323   1.1     pooka 		 */
   6324   1.1     pooka 		if (!(pkt->hdr.qid & (1 << 7))) {
   6325   1.1     pooka 			iwm_cmd_done(sc, pkt);
   6326   1.1     pooka 		}
   6327   1.1     pooka 
   6328   1.1     pooka 		ADVANCE_RXQ(sc);
   6329   1.1     pooka 	}
   6330   1.1     pooka 
   6331   1.1     pooka 	IWM_CLRBITS(sc, IWM_CSR_GP_CNTRL,
   6332   1.1     pooka 	    IWM_CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
   6333   1.1     pooka 
   6334   1.1     pooka 	/*
   6335   1.1     pooka 	 * Tell the firmware what we have processed.
   6336   1.1     pooka 	 * Seems like the hardware gets upset unless we align
   6337   1.1     pooka 	 * the write by 8??
   6338   1.1     pooka 	 */
   6339   1.1     pooka 	hw = (hw == 0) ? IWM_RX_RING_COUNT - 1 : hw - 1;
   6340   1.1     pooka 	IWM_WRITE(sc, IWM_FH_RSCSR_CHNL0_WPTR, hw & ~7);
   6341   1.1     pooka }
   6342   1.1     pooka 
   6343   1.4    nonaka static int
   6344   1.1     pooka iwm_intr(void *arg)
   6345   1.1     pooka {
   6346   1.1     pooka 	struct iwm_softc *sc = arg;
   6347   1.1     pooka 	struct ifnet *ifp = IC2IFP(&sc->sc_ic);
   6348   1.1     pooka 	int handled = 0;
   6349   1.1     pooka 	int r1, r2, rv = 0;
   6350   1.1     pooka 	int isperiodic = 0;
   6351   1.1     pooka 
   6352   1.1     pooka 	IWM_WRITE(sc, IWM_CSR_INT_MASK, 0);
   6353   1.1     pooka 
   6354   1.1     pooka 	if (sc->sc_flags & IWM_FLAG_USE_ICT) {
   6355   1.1     pooka 		uint32_t *ict = sc->ict_dma.vaddr;
   6356   1.1     pooka 		int tmp;
   6357   1.1     pooka 
   6358   1.1     pooka 		tmp = htole32(ict[sc->ict_cur]);
   6359   1.1     pooka 		if (!tmp)
   6360   1.1     pooka 			goto out_ena;
   6361   1.1     pooka 
   6362   1.1     pooka 		/*
   6363   1.1     pooka 		 * ok, there was something.  keep plowing until we have all.
   6364   1.1     pooka 		 */
   6365   1.1     pooka 		r1 = r2 = 0;
   6366   1.1     pooka 		while (tmp) {
   6367   1.1     pooka 			r1 |= tmp;
   6368   1.1     pooka 			ict[sc->ict_cur] = 0;
   6369   1.1     pooka 			sc->ict_cur = (sc->ict_cur+1) % IWM_ICT_COUNT;
   6370   1.1     pooka 			tmp = htole32(ict[sc->ict_cur]);
   6371   1.1     pooka 		}
   6372   1.1     pooka 
   6373   1.1     pooka 		/* this is where the fun begins.  don't ask */
   6374   1.1     pooka 		if (r1 == 0xffffffff)
   6375   1.1     pooka 			r1 = 0;
   6376   1.1     pooka 
   6377   1.1     pooka 		/* i am not expected to understand this */
   6378   1.1     pooka 		if (r1 & 0xc0000)
   6379   1.1     pooka 			r1 |= 0x8000;
   6380   1.1     pooka 		r1 = (0xff & r1) | ((0xff00 & r1) << 16);
   6381   1.1     pooka 	} else {
   6382   1.1     pooka 		r1 = IWM_READ(sc, IWM_CSR_INT);
   6383   1.1     pooka 		/* "hardware gone" (where, fishing?) */
   6384   1.1     pooka 		if (r1 == 0xffffffff || (r1 & 0xfffffff0) == 0xa5a5a5a0)
   6385   1.1     pooka 			goto out;
   6386   1.1     pooka 		r2 = IWM_READ(sc, IWM_CSR_FH_INT_STATUS);
   6387   1.1     pooka 	}
   6388   1.1     pooka 	if (r1 == 0 && r2 == 0) {
   6389   1.1     pooka 		goto out_ena;
   6390   1.1     pooka 	}
   6391   1.1     pooka 
   6392   1.1     pooka 	IWM_WRITE(sc, IWM_CSR_INT, r1 | ~sc->sc_intmask);
   6393   1.1     pooka 
   6394   1.1     pooka 	/* ignored */
   6395   1.1     pooka 	handled |= (r1 & (IWM_CSR_INT_BIT_ALIVE /*| IWM_CSR_INT_BIT_SCD*/));
   6396   1.1     pooka 
   6397   1.1     pooka 	if (r1 & IWM_CSR_INT_BIT_SW_ERR) {
   6398   1.1     pooka #ifdef IWM_DEBUG
   6399   1.1     pooka 		int i;
   6400   1.1     pooka 
   6401   1.1     pooka 		iwm_nic_error(sc);
   6402   1.1     pooka 
   6403   1.1     pooka 		/* Dump driver status (TX and RX rings) while we're here. */
   6404   1.1     pooka 		DPRINTF(("driver status:\n"));
   6405   1.1     pooka 		for (i = 0; i < IWM_MVM_MAX_QUEUES; i++) {
   6406   1.1     pooka 			struct iwm_tx_ring *ring = &sc->txq[i];
   6407   1.1     pooka 			DPRINTF(("  tx ring %2d: qid=%-2d cur=%-3d "
   6408   1.1     pooka 			    "queued=%-3d\n",
   6409   1.1     pooka 			    i, ring->qid, ring->cur, ring->queued));
   6410   1.1     pooka 		}
   6411   1.1     pooka 		DPRINTF(("  rx ring: cur=%d\n", sc->rxq.cur));
   6412   1.1     pooka 		DPRINTF(("  802.11 state %d\n", sc->sc_ic.ic_state));
   6413   1.1     pooka #endif
   6414   1.1     pooka 
   6415   1.3    nonaka 		aprint_error_dev(sc->sc_dev, "fatal firmware error\n");
   6416   1.1     pooka 		ifp->if_flags &= ~IFF_UP;
   6417   1.1     pooka 		iwm_stop(ifp, 1);
   6418   1.1     pooka 		rv = 1;
   6419   1.1     pooka 		goto out;
   6420   1.1     pooka 
   6421   1.1     pooka 	}
   6422   1.1     pooka 
   6423   1.1     pooka 	if (r1 & IWM_CSR_INT_BIT_HW_ERR) {
   6424   1.1     pooka 		handled |= IWM_CSR_INT_BIT_HW_ERR;
   6425   1.3    nonaka 		aprint_error_dev(sc->sc_dev,
   6426   1.3    nonaka 		    "hardware error, stopping device\n");
   6427   1.1     pooka 		ifp->if_flags &= ~IFF_UP;
   6428   1.1     pooka 		iwm_stop(ifp, 1);
   6429   1.1     pooka 		rv = 1;
   6430   1.1     pooka 		goto out;
   6431   1.1     pooka 	}
   6432   1.1     pooka 
   6433   1.1     pooka 	/* firmware chunk loaded */
   6434   1.1     pooka 	if (r1 & IWM_CSR_INT_BIT_FH_TX) {
   6435   1.1     pooka 		IWM_WRITE(sc, IWM_CSR_FH_INT_STATUS, IWM_CSR_FH_INT_TX_MASK);
   6436   1.1     pooka 		handled |= IWM_CSR_INT_BIT_FH_TX;
   6437   1.1     pooka 
   6438   1.1     pooka 		sc->sc_fw_chunk_done = 1;
   6439   1.1     pooka 		wakeup(&sc->sc_fw);
   6440   1.1     pooka 	}
   6441   1.1     pooka 
   6442   1.1     pooka 	if (r1 & IWM_CSR_INT_BIT_RF_KILL) {
   6443   1.1     pooka 		handled |= IWM_CSR_INT_BIT_RF_KILL;
   6444   1.1     pooka 		if (iwm_check_rfkill(sc) && (ifp->if_flags & IFF_UP)) {
   6445   1.2    nonaka 			DPRINTF(("%s: rfkill switch, disabling interface\n",
   6446   1.2    nonaka 			    DEVNAME(sc)));
   6447   1.1     pooka 			ifp->if_flags &= ~IFF_UP;
   6448   1.1     pooka 			iwm_stop(ifp, 1);
   6449   1.1     pooka 		}
   6450   1.1     pooka 	}
   6451   1.1     pooka 
   6452   1.1     pooka 	/*
   6453   1.1     pooka 	 * The Linux driver uses periodic interrupts to avoid races.
   6454   1.1     pooka 	 * We cargo-cult like it's going out of fashion.
   6455   1.1     pooka 	 */
   6456   1.1     pooka 	if (r1 & IWM_CSR_INT_BIT_RX_PERIODIC) {
   6457   1.1     pooka 		handled |= IWM_CSR_INT_BIT_RX_PERIODIC;
   6458   1.1     pooka 		IWM_WRITE(sc, IWM_CSR_INT, IWM_CSR_INT_BIT_RX_PERIODIC);
   6459   1.1     pooka 		if ((r1 & (IWM_CSR_INT_BIT_FH_RX | IWM_CSR_INT_BIT_SW_RX)) == 0)
   6460   1.1     pooka 			IWM_WRITE_1(sc,
   6461   1.1     pooka 			    IWM_CSR_INT_PERIODIC_REG, IWM_CSR_INT_PERIODIC_DIS);
   6462   1.1     pooka 		isperiodic = 1;
   6463   1.1     pooka 	}
   6464   1.1     pooka 
   6465   1.1     pooka 	if ((r1 & (IWM_CSR_INT_BIT_FH_RX | IWM_CSR_INT_BIT_SW_RX)) || isperiodic) {
   6466   1.1     pooka 		handled |= (IWM_CSR_INT_BIT_FH_RX | IWM_CSR_INT_BIT_SW_RX);
   6467   1.1     pooka 		IWM_WRITE(sc, IWM_CSR_FH_INT_STATUS, IWM_CSR_FH_INT_RX_MASK);
   6468   1.1     pooka 
   6469   1.1     pooka 		iwm_notif_intr(sc);
   6470   1.1     pooka 
   6471   1.1     pooka 		/* enable periodic interrupt, see above */
   6472   1.1     pooka 		if (r1 & (IWM_CSR_INT_BIT_FH_RX | IWM_CSR_INT_BIT_SW_RX) && !isperiodic)
   6473   1.1     pooka 			IWM_WRITE_1(sc, IWM_CSR_INT_PERIODIC_REG,
   6474   1.1     pooka 			    IWM_CSR_INT_PERIODIC_ENA);
   6475   1.1     pooka 	}
   6476   1.1     pooka 
   6477   1.1     pooka 	if (__predict_false(r1 & ~handled))
   6478   1.2    nonaka 		DPRINTF(("%s: unhandled interrupts: %x\n", DEVNAME(sc), r1));
   6479   1.1     pooka 	rv = 1;
   6480   1.1     pooka 
   6481   1.1     pooka  out_ena:
   6482   1.1     pooka 	iwm_restore_interrupts(sc);
   6483   1.1     pooka  out:
   6484   1.1     pooka 	return rv;
   6485   1.1     pooka }
   6486   1.1     pooka 
   6487   1.1     pooka /*
   6488   1.1     pooka  * Autoconf glue-sniffing
   6489   1.1     pooka  */
   6490   1.1     pooka 
   6491   1.1     pooka static const pci_product_id_t iwm_devices[] = {
   6492   1.5    nonaka 	PCI_PRODUCT_INTEL_WIFI_LINK_7260_1,
   6493   1.5    nonaka 	PCI_PRODUCT_INTEL_WIFI_LINK_7260_2,
   6494   1.5    nonaka 	PCI_PRODUCT_INTEL_WIFI_LINK_3160_1,
   6495   1.5    nonaka 	PCI_PRODUCT_INTEL_WIFI_LINK_3160_2,
   6496   1.5    nonaka 	PCI_PRODUCT_INTEL_WIFI_LINK_7265_1,
   6497   1.5    nonaka 	PCI_PRODUCT_INTEL_WIFI_LINK_7265_2,
   6498   1.1     pooka };
   6499   1.1     pooka 
   6500   1.1     pooka static int
   6501   1.4    nonaka iwm_match(device_t parent, cfdata_t match __unused, void *aux)
   6502   1.1     pooka {
   6503   1.1     pooka 	struct pci_attach_args *pa = aux;
   6504   1.1     pooka 
   6505   1.1     pooka 	if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_INTEL)
   6506   1.1     pooka 		return 0;
   6507   1.1     pooka 
   6508   1.5    nonaka 	for (size_t i = 0; i < __arraycount(iwm_devices); i++)
   6509   1.1     pooka 		if (PCI_PRODUCT(pa->pa_id) == iwm_devices[i])
   6510   1.1     pooka 			return 1;
   6511   1.1     pooka 
   6512   1.1     pooka 	return 0;
   6513   1.1     pooka }
   6514   1.1     pooka 
   6515   1.4    nonaka static int
   6516   1.1     pooka iwm_preinit(struct iwm_softc *sc)
   6517   1.1     pooka {
   6518   1.1     pooka 	int error;
   6519   1.1     pooka 
   6520   1.2    nonaka 	if ((error = iwm_prepare_card_hw(sc)) != 0) {
   6521   1.3    nonaka 		aprint_error_dev(sc->sc_dev, "could not initialize hardware\n");
   6522   1.1     pooka 		return error;
   6523   1.2    nonaka 	}
   6524   1.1     pooka 
   6525   1.2    nonaka 	if (sc->sc_flags & IWM_FLAG_ATTACHED)
   6526   1.2    nonaka 		return 0;
   6527   1.1     pooka 
   6528   1.2    nonaka 	if ((error = iwm_start_hw(sc)) != 0) {
   6529   1.3    nonaka 		aprint_error_dev(sc->sc_dev, "could not initialize hardware\n");
   6530   1.1     pooka 		return error;
   6531   1.1     pooka 	}
   6532   1.1     pooka 
   6533   1.2    nonaka 	error = iwm_run_init_mvm_ucode(sc, 1);
   6534   1.1     pooka 	iwm_stop_device(sc);
   6535   1.2    nonaka 	return error;
   6536   1.1     pooka }
   6537   1.1     pooka 
   6538   1.4    nonaka static void
   6539   1.4    nonaka iwm_attach_hook(device_t dev)
   6540   1.1     pooka {
   6541   1.1     pooka 	struct iwm_softc *sc = device_private(dev);
   6542   1.1     pooka 	struct ieee80211com *ic = &sc->sc_ic;
   6543   1.1     pooka 	struct ifnet *ifp = &sc->sc_ec.ec_if;
   6544   1.1     pooka 
   6545   1.1     pooka 	KASSERT(!cold);
   6546   1.1     pooka 
   6547   1.2    nonaka 	if (iwm_preinit(sc) != 0)
   6548   1.1     pooka 		return;
   6549   1.1     pooka 
   6550   1.2    nonaka 	sc->sc_flags |= IWM_FLAG_ATTACHED;
   6551   1.1     pooka 
   6552   1.3    nonaka 	aprint_normal_dev(sc->sc_dev,
   6553   1.3    nonaka 	    "hw rev: 0x%x, fw ver %d.%d (API ver %d), address %s\n",
   6554   1.3    nonaka 	    sc->sc_hw_rev & IWM_CSR_HW_REV_TYPE_MSK,
   6555   1.1     pooka 	    IWM_UCODE_MAJOR(sc->sc_fwver),
   6556   1.1     pooka 	    IWM_UCODE_MINOR(sc->sc_fwver),
   6557   1.1     pooka 	    IWM_UCODE_API(sc->sc_fwver),
   6558   1.1     pooka 	    ether_sprintf(sc->sc_nvm.hw_addr));
   6559   1.8    nonaka 
   6560   1.5    nonaka 	ic->ic_ifp = ifp;
   6561   1.1     pooka 	ic->ic_phytype = IEEE80211_T_OFDM;	/* not only, but not used */
   6562   1.1     pooka 	ic->ic_opmode = IEEE80211_M_STA;	/* default to BSS mode */
   6563   1.1     pooka 	ic->ic_state = IEEE80211_S_INIT;
   6564   1.1     pooka 
   6565   1.1     pooka 	/* Set device capabilities. */
   6566   1.1     pooka 	ic->ic_caps =
   6567   1.2    nonaka 	    IEEE80211_C_WEP |		/* WEP */
   6568   1.1     pooka 	    IEEE80211_C_WPA |		/* 802.11i */
   6569   1.1     pooka 	    IEEE80211_C_SHSLOT |	/* short slot time supported */
   6570   1.1     pooka 	    IEEE80211_C_SHPREAMBLE;	/* short preamble supported */
   6571   1.1     pooka 
   6572  1.29    nonaka 	/* not all hardware can do 5GHz band */
   6573  1.29    nonaka 	if (sc->sc_nvm.sku_cap_band_52GHz_enable)
   6574  1.29    nonaka 		ic->ic_sup_rates[IEEE80211_MODE_11A] = ieee80211_std_rateset_11a;
   6575   1.2    nonaka 	ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b;
   6576   1.2    nonaka 	ic->ic_sup_rates[IEEE80211_MODE_11G] = ieee80211_std_rateset_11g;
   6577   1.1     pooka 
   6578   1.2    nonaka 	for (int i = 0; i < __arraycount(sc->sc_phyctxt); i++) {
   6579   1.1     pooka 		sc->sc_phyctxt[i].id = i;
   6580   1.1     pooka 	}
   6581   1.1     pooka 
   6582   1.1     pooka 	sc->sc_amrr.amrr_min_success_threshold =  1;
   6583   1.1     pooka 	sc->sc_amrr.amrr_max_success_threshold = 15;
   6584   1.1     pooka 
   6585   1.1     pooka 	/* IBSS channel undefined for now. */
   6586   1.1     pooka 	ic->ic_ibss_chan = &ic->ic_channels[1];
   6587   1.1     pooka 
   6588   1.1     pooka #if 0
   6589   1.1     pooka 	/* Max RSSI */
   6590   1.1     pooka 	ic->ic_max_rssi = IWM_MAX_DBM - IWM_MIN_DBM;
   6591   1.1     pooka #endif
   6592   1.1     pooka 
   6593   1.1     pooka 	ifp->if_softc = sc;
   6594   1.1     pooka 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
   6595   1.1     pooka 	ifp->if_init = iwm_init;
   6596   1.1     pooka 	ifp->if_stop = iwm_stop;
   6597   1.1     pooka 	ifp->if_ioctl = iwm_ioctl;
   6598   1.1     pooka 	ifp->if_start = iwm_start;
   6599   1.1     pooka 	ifp->if_watchdog = iwm_watchdog;
   6600   1.1     pooka 	IFQ_SET_READY(&ifp->if_snd);
   6601   1.1     pooka 	memcpy(ifp->if_xname, DEVNAME(sc), IFNAMSIZ);
   6602   1.1     pooka 
   6603   1.5    nonaka 	if_initialize(ifp);
   6604   1.1     pooka 	ieee80211_ifattach(ic);
   6605   1.5    nonaka 	if_register(ifp);
   6606   1.1     pooka 
   6607   1.1     pooka 	ic->ic_node_alloc = iwm_node_alloc;
   6608   1.1     pooka 
   6609   1.1     pooka 	/* Override 802.11 state transition machine. */
   6610   1.1     pooka 	sc->sc_newstate = ic->ic_newstate;
   6611   1.1     pooka 	ic->ic_newstate = iwm_newstate;
   6612   1.1     pooka 	ieee80211_media_init(ic, iwm_media_change, ieee80211_media_status);
   6613   1.1     pooka 	ieee80211_announce(ic);
   6614   1.1     pooka 
   6615   1.1     pooka 	iwm_radiotap_attach(sc);
   6616   1.1     pooka 	callout_init(&sc->sc_calib_to, 0);
   6617   1.1     pooka 	callout_setfunc(&sc->sc_calib_to, iwm_calib_timeout, sc);
   6618   1.1     pooka 
   6619   1.1     pooka 	//task_set(&sc->init_task, iwm_init_task, sc);
   6620  1.30    nonaka 
   6621  1.30    nonaka 	if (pmf_device_register(dev, NULL, NULL))
   6622  1.30    nonaka 		pmf_class_network_register(dev, ifp);
   6623  1.30    nonaka 	else
   6624  1.30    nonaka 		aprint_error_dev(dev, "couldn't establish power handler\n");
   6625   1.1     pooka }
   6626   1.1     pooka 
   6627   1.4    nonaka static void
   6628   1.4    nonaka iwm_attach(device_t parent, device_t self, void *aux)
   6629   1.1     pooka {
   6630   1.1     pooka 	struct iwm_softc *sc = device_private(self);
   6631   1.1     pooka 	struct pci_attach_args *pa = aux;
   6632  1.31    nonaka #ifndef __HAVE_PCI_MSI_MSIX
   6633   1.1     pooka 	pci_intr_handle_t ih;
   6634  1.31    nonaka #endif
   6635   1.1     pooka 	pcireg_t reg, memtype;
   6636   1.1     pooka 	const char *intrstr;
   6637   1.1     pooka 	int error;
   6638   1.2    nonaka 	int txq_i;
   6639   1.1     pooka 
   6640   1.3    nonaka 	sc->sc_dev = self;
   6641   1.1     pooka 	sc->sc_pct = pa->pa_pc;
   6642   1.1     pooka 	sc->sc_pcitag = pa->pa_tag;
   6643   1.1     pooka 	sc->sc_dmat = pa->pa_dmat;
   6644   1.5    nonaka 	sc->sc_pciid = pa->pa_id;
   6645   1.1     pooka 
   6646   1.1     pooka 	pci_aprint_devinfo(pa, NULL);
   6647   1.1     pooka 
   6648   1.1     pooka 	/*
   6649   1.1     pooka 	 * Get the offset of the PCI Express Capability Structure in PCI
   6650   1.1     pooka 	 * Configuration Space.
   6651   1.1     pooka 	 */
   6652   1.1     pooka 	error = pci_get_capability(sc->sc_pct, sc->sc_pcitag,
   6653   1.1     pooka 	    PCI_CAP_PCIEXPRESS, &sc->sc_cap_off, NULL);
   6654   1.1     pooka 	if (error == 0) {
   6655   1.3    nonaka 		aprint_error_dev(self,
   6656   1.3    nonaka 		    "PCIe capability structure not found!\n");
   6657   1.1     pooka 		return;
   6658   1.1     pooka 	}
   6659   1.1     pooka 
   6660   1.1     pooka 	/* Clear device-specific "PCI retry timeout" register (41h). */
   6661   1.1     pooka 	reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag, 0x40);
   6662   1.1     pooka 	pci_conf_write(sc->sc_pct, sc->sc_pcitag, 0x40, reg & ~0xff00);
   6663   1.1     pooka 
   6664   1.1     pooka 	/* Enable bus-mastering and hardware bug workaround. */
   6665   1.1     pooka 	reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag, PCI_COMMAND_STATUS_REG);
   6666   1.1     pooka 	reg |= PCI_COMMAND_MASTER_ENABLE;
   6667   1.1     pooka 	/* if !MSI */
   6668   1.1     pooka 	if (reg & PCI_COMMAND_INTERRUPT_DISABLE) {
   6669   1.1     pooka 		reg &= ~PCI_COMMAND_INTERRUPT_DISABLE;
   6670   1.1     pooka 	}
   6671   1.1     pooka 	pci_conf_write(sc->sc_pct, sc->sc_pcitag, PCI_COMMAND_STATUS_REG, reg);
   6672   1.1     pooka 
   6673   1.1     pooka 	memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, PCI_MAPREG_START);
   6674   1.1     pooka 	error = pci_mapreg_map(pa, PCI_MAPREG_START, memtype, 0,
   6675   1.1     pooka 	    &sc->sc_st, &sc->sc_sh, NULL, &sc->sc_sz);
   6676   1.1     pooka 	if (error != 0) {
   6677   1.3    nonaka 		aprint_error_dev(self, "can't map mem space\n");
   6678   1.1     pooka 		return;
   6679   1.1     pooka 	}
   6680   1.1     pooka 
   6681   1.1     pooka 	/* Install interrupt handler. */
   6682  1.31    nonaka #ifdef __HAVE_PCI_MSI_MSIX
   6683  1.31    nonaka 	error = ENODEV;
   6684  1.33  knakahar 	if (pci_msi_count(pa) > 0)
   6685  1.31    nonaka 		error = pci_msi_alloc_exact(pa, &sc->sc_pihp, 1);
   6686  1.31    nonaka 	if (error != 0) {
   6687  1.31    nonaka 		if (pci_intx_alloc(pa, &sc->sc_pihp)) {
   6688  1.31    nonaka 			aprint_error_dev(self, "can't map interrupt\n");
   6689  1.31    nonaka 			return;
   6690  1.31    nonaka 		}
   6691  1.31    nonaka 	}
   6692  1.31    nonaka #else	/* !__HAVE_PCI_MSI_MSIX */
   6693   1.1     pooka 	if (pci_intr_map(pa, &ih)) {
   6694   1.3    nonaka 		aprint_error_dev(self, "can't map interrupt\n");
   6695   1.1     pooka 		return;
   6696   1.1     pooka 	}
   6697  1.31    nonaka #endif	/* __HAVE_PCI_MSI_MSIX */
   6698   1.1     pooka 
   6699   1.1     pooka 	char intrbuf[PCI_INTRSTR_LEN];
   6700  1.31    nonaka #ifdef __HAVE_PCI_MSI_MSIX
   6701  1.31    nonaka 	intrstr = pci_intr_string(sc->sc_pct, sc->sc_pihp[0], intrbuf,
   6702  1.31    nonaka 	    sizeof(intrbuf));
   6703  1.33  knakahar 	sc->sc_ih = pci_intr_establish(sc->sc_pct, sc->sc_pihp[0], IPL_NET,
   6704  1.33  knakahar 	    iwm_intr, sc);
   6705  1.31    nonaka #else	/* !__HAVE_PCI_MSI_MSIX */
   6706   1.1     pooka 	intrstr = pci_intr_string(sc->sc_pct, ih, intrbuf, sizeof(intrbuf));
   6707   1.1     pooka 	sc->sc_ih = pci_intr_establish(sc->sc_pct, ih, IPL_NET, iwm_intr, sc);
   6708  1.31    nonaka #endif	/* __HAVE_PCI_MSI_MSIX */
   6709   1.1     pooka 	if (sc->sc_ih == NULL) {
   6710   1.3    nonaka 		aprint_error_dev(self, "can't establish interrupt");
   6711   1.1     pooka 		if (intrstr != NULL)
   6712   1.3    nonaka 			aprint_error(" at %s", intrstr);
   6713   1.3    nonaka 		aprint_error("\n");
   6714   1.1     pooka 		return;
   6715   1.1     pooka 	}
   6716   1.3    nonaka 	aprint_normal_dev(self, "interrupting at %s\n", intrstr);
   6717   1.1     pooka 
   6718   1.5    nonaka 	sc->sc_wantresp = -1;
   6719   1.5    nonaka 
   6720   1.5    nonaka 	switch (PCI_PRODUCT(sc->sc_pciid)) {
   6721   1.5    nonaka 	case PCI_PRODUCT_INTEL_WIFI_LINK_7260_1:
   6722   1.5    nonaka 	case PCI_PRODUCT_INTEL_WIFI_LINK_7260_2:
   6723   1.5    nonaka 		sc->sc_fwname = "iwlwifi-7260-9.ucode";
   6724  1.17    nonaka 		sc->host_interrupt_operation_mode = 1;
   6725   1.5    nonaka 		break;
   6726   1.5    nonaka 	case PCI_PRODUCT_INTEL_WIFI_LINK_3160_1:
   6727   1.5    nonaka 	case PCI_PRODUCT_INTEL_WIFI_LINK_3160_2:
   6728   1.5    nonaka 		sc->sc_fwname = "iwlwifi-3160-9.ucode";
   6729  1.17    nonaka 		sc->host_interrupt_operation_mode = 1;
   6730   1.5    nonaka 		break;
   6731   1.5    nonaka 	case PCI_PRODUCT_INTEL_WIFI_LINK_7265_1:
   6732   1.5    nonaka 	case PCI_PRODUCT_INTEL_WIFI_LINK_7265_2:
   6733   1.5    nonaka 		sc->sc_fwname = "iwlwifi-7265-9.ucode";
   6734  1.17    nonaka 		sc->host_interrupt_operation_mode = 0;
   6735   1.5    nonaka 		break;
   6736   1.5    nonaka 	default:
   6737   1.5    nonaka 		aprint_error_dev(self, "unknown product %#x",
   6738   1.5    nonaka 		    PCI_PRODUCT(sc->sc_pciid));
   6739   1.5    nonaka 		return;
   6740   1.5    nonaka 	}
   6741   1.5    nonaka 	DPRINTF(("%s: firmware=%s\n", DEVNAME(sc), sc->sc_fwname));
   6742   1.2    nonaka 	sc->sc_fwdmasegsz = IWM_FWDMASEGSZ;
   6743   1.2    nonaka 
   6744   1.2    nonaka 	/*
   6745   1.2    nonaka 	 * We now start fiddling with the hardware
   6746   1.2    nonaka 	 */
   6747   1.2    nonaka 
   6748   1.2    nonaka 	sc->sc_hw_rev = IWM_READ(sc, IWM_CSR_HW_REV);
   6749   1.2    nonaka 	if (iwm_prepare_card_hw(sc) != 0) {
   6750   1.3    nonaka 		aprint_error_dev(sc->sc_dev, "could not initialize hardware\n");
   6751   1.2    nonaka 		return;
   6752   1.2    nonaka 	}
   6753   1.2    nonaka 
   6754   1.2    nonaka 	/* Allocate DMA memory for firmware transfers. */
   6755   1.2    nonaka 	if ((error = iwm_alloc_fwmem(sc)) != 0) {
   6756   1.3    nonaka 		aprint_error_dev(sc->sc_dev,
   6757   1.3    nonaka 		    "could not allocate memory for firmware\n");
   6758   1.2    nonaka 		return;
   6759   1.2    nonaka 	}
   6760   1.2    nonaka 
   6761   1.2    nonaka 	/* Allocate "Keep Warm" page. */
   6762   1.2    nonaka 	if ((error = iwm_alloc_kw(sc)) != 0) {
   6763   1.3    nonaka 		aprint_error_dev(sc->sc_dev,
   6764   1.3    nonaka 		    "could not allocate keep warm page\n");
   6765   1.2    nonaka 		goto fail1;
   6766   1.2    nonaka 	}
   6767   1.2    nonaka 
   6768   1.2    nonaka 	/* We use ICT interrupts */
   6769   1.2    nonaka 	if ((error = iwm_alloc_ict(sc)) != 0) {
   6770   1.3    nonaka 		aprint_error_dev(sc->sc_dev, "could not allocate ICT table\n");
   6771   1.2    nonaka 		goto fail2;
   6772   1.2    nonaka 	}
   6773   1.2    nonaka 
   6774   1.2    nonaka 	/* Allocate TX scheduler "rings". */
   6775   1.2    nonaka 	if ((error = iwm_alloc_sched(sc)) != 0) {
   6776   1.3    nonaka 		aprint_error_dev(sc->sc_dev,
   6777   1.3    nonaka 		    "could not allocate TX scheduler rings\n");
   6778   1.2    nonaka 		goto fail3;
   6779   1.2    nonaka 	}
   6780   1.2    nonaka 
   6781   1.2    nonaka 	/* Allocate TX rings */
   6782   1.2    nonaka 	for (txq_i = 0; txq_i < __arraycount(sc->txq); txq_i++) {
   6783   1.2    nonaka 		if ((error = iwm_alloc_tx_ring(sc,
   6784   1.2    nonaka 		    &sc->txq[txq_i], txq_i)) != 0) {
   6785   1.3    nonaka 			aprint_error_dev(sc->sc_dev,
   6786   1.3    nonaka 			    "could not allocate TX ring %d\n", txq_i);
   6787   1.2    nonaka 			goto fail4;
   6788   1.2    nonaka 		}
   6789   1.2    nonaka 	}
   6790   1.2    nonaka 
   6791   1.2    nonaka 	/* Allocate RX ring. */
   6792   1.2    nonaka 	if ((error = iwm_alloc_rx_ring(sc, &sc->rxq)) != 0) {
   6793   1.3    nonaka 		aprint_error_dev(sc->sc_dev, "could not allocate RX ring\n");
   6794   1.2    nonaka 		goto fail4;
   6795   1.2    nonaka 	}
   6796   1.2    nonaka 
   6797   1.2    nonaka 	workqueue_create(&sc->sc_eswq, "iwmes",
   6798   1.5    nonaka 	    iwm_endscan_cb, sc, PRI_NONE, IPL_NET, 0);
   6799   1.2    nonaka 	workqueue_create(&sc->sc_nswq, "iwmns",
   6800   1.5    nonaka 	    iwm_newstate_cb, sc, PRI_NONE, IPL_NET, 0);
   6801   1.2    nonaka 
   6802   1.2    nonaka 	/* Clear pending interrupts. */
   6803   1.2    nonaka 	IWM_WRITE(sc, IWM_CSR_INT, 0xffffffff);
   6804   1.2    nonaka 
   6805   1.1     pooka 	/*
   6806   1.1     pooka 	 * We can't do normal attach before the file system is mounted
   6807   1.1     pooka 	 * because we cannot read the MAC address without loading the
   6808   1.1     pooka 	 * firmware from disk.  So we postpone until mountroot is done.
   6809   1.1     pooka 	 * Notably, this will require a full driver unload/load cycle
   6810   1.1     pooka 	 * (or reboot) in case the firmware is not present when the
   6811   1.1     pooka 	 * hook runs.
   6812   1.1     pooka 	 */
   6813   1.1     pooka 	config_mountroot(self, iwm_attach_hook);
   6814   1.2    nonaka 
   6815   1.2    nonaka 	return;
   6816   1.2    nonaka 
   6817   1.2    nonaka 	/* Free allocated memory if something failed during attachment. */
   6818   1.2    nonaka fail4:	while (--txq_i >= 0)
   6819   1.2    nonaka 		iwm_free_tx_ring(sc, &sc->txq[txq_i]);
   6820   1.2    nonaka 	iwm_free_sched(sc);
   6821   1.2    nonaka fail3:	if (sc->ict_dma.vaddr != NULL)
   6822   1.2    nonaka 		iwm_free_ict(sc);
   6823   1.2    nonaka fail2:	iwm_free_kw(sc);
   6824   1.2    nonaka fail1:	iwm_free_fwmem(sc);
   6825   1.1     pooka }
   6826   1.1     pooka 
   6827   1.1     pooka /*
   6828   1.1     pooka  * Attach the interface to 802.11 radiotap.
   6829   1.1     pooka  */
   6830   1.1     pooka void
   6831   1.1     pooka iwm_radiotap_attach(struct iwm_softc *sc)
   6832   1.1     pooka {
   6833   1.1     pooka 	struct ifnet *ifp = sc->sc_ic.ic_ifp;
   6834   1.1     pooka 
   6835   1.1     pooka 	bpf_attach2(ifp, DLT_IEEE802_11_RADIO,
   6836   1.1     pooka 	    sizeof (struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN,
   6837   1.1     pooka 	    &sc->sc_drvbpf);
   6838   1.1     pooka 
   6839   1.1     pooka 	sc->sc_rxtap_len = sizeof sc->sc_rxtapu;
   6840   1.1     pooka 	sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
   6841   1.1     pooka 	sc->sc_rxtap.wr_ihdr.it_present = htole32(IWM_RX_RADIOTAP_PRESENT);
   6842   1.1     pooka 
   6843   1.1     pooka 	sc->sc_txtap_len = sizeof sc->sc_txtapu;
   6844   1.1     pooka 	sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
   6845   1.1     pooka 	sc->sc_txtap.wt_ihdr.it_present = htole32(IWM_TX_RADIOTAP_PRESENT);
   6846   1.1     pooka }
   6847   1.1     pooka 
   6848   1.1     pooka #if 0
   6849   1.4    nonaka static void
   6850   1.1     pooka iwm_init_task(void *arg1)
   6851   1.1     pooka {
   6852   1.1     pooka 	struct iwm_softc *sc = arg1;
   6853   1.1     pooka 	struct ifnet *ifp = &sc->sc_ic.ic_if;
   6854   1.1     pooka 	int s;
   6855   1.8    nonaka 
   6856   1.1     pooka 	s = splnet();
   6857   1.1     pooka 	while (sc->sc_flags & IWM_FLAG_BUSY)
   6858   1.1     pooka 		tsleep(&sc->sc_flags, 0, "iwmpwr", 0);
   6859   1.1     pooka 	sc->sc_flags |= IWM_FLAG_BUSY;
   6860   1.8    nonaka 
   6861   1.1     pooka 	iwm_stop(ifp, 0);
   6862   1.1     pooka 	if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == IFF_UP)
   6863   1.1     pooka 		iwm_init(ifp);
   6864   1.1     pooka 
   6865   1.1     pooka 	sc->sc_flags &= ~IWM_FLAG_BUSY;
   6866   1.1     pooka 	wakeup(&sc->sc_flags);
   6867   1.1     pooka 	splx(s);
   6868   1.1     pooka }
   6869   1.1     pooka 
   6870   1.4    nonaka static void
   6871   1.1     pooka iwm_wakeup(struct iwm_softc *sc)
   6872   1.1     pooka {
   6873   1.1     pooka 	pcireg_t reg;
   6874   1.1     pooka 
   6875   1.1     pooka 	/* Clear device-specific "PCI retry timeout" register (41h). */
   6876   1.1     pooka 	reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag, 0x40);
   6877   1.1     pooka 	pci_conf_write(sc->sc_pct, sc->sc_pcitag, 0x40, reg & ~0xff00);
   6878   1.1     pooka 
   6879   1.1     pooka 	iwm_init_task(sc);
   6880   1.1     pooka }
   6881   1.1     pooka 
   6882   1.4    nonaka static int
   6883   1.4    nonaka iwm_activate(device_t self, enum devact act)
   6884   1.1     pooka {
   6885   1.4    nonaka 	struct iwm_softc *sc = device_private(self);
   6886   1.4    nonaka 	struct ifnet *ifp = IC2IFP(&sc->sc_ic);
   6887   1.1     pooka 
   6888   1.1     pooka 	switch (act) {
   6889   1.4    nonaka 	case DVACT_DEACTIVATE:
   6890   1.1     pooka 		if (ifp->if_flags & IFF_RUNNING)
   6891   1.1     pooka 			iwm_stop(ifp, 0);
   6892   1.4    nonaka 		return 0;
   6893   1.4    nonaka 	default:
   6894   1.4    nonaka 		return EOPNOTSUPP;
   6895   1.1     pooka 	}
   6896   1.1     pooka }
   6897   1.1     pooka #endif
   6898   1.1     pooka 
   6899   1.1     pooka CFATTACH_DECL_NEW(iwm, sizeof(struct iwm_softc), iwm_match, iwm_attach,
   6900   1.1     pooka 	NULL, NULL);
   6901  1.32    nonaka 
   6902  1.32    nonaka #ifdef IWM_DEBUG
   6903  1.32    nonaka SYSCTL_SETUP(sysctl_iwm, "sysctl iwm(4) subtree setup")
   6904  1.32    nonaka {
   6905  1.32    nonaka 	const struct sysctlnode *rnode, *cnode;
   6906  1.32    nonaka 	int rc;
   6907  1.32    nonaka 
   6908  1.32    nonaka 	if ((rc = sysctl_createv(clog, 0, NULL, &rnode,
   6909  1.32    nonaka 	    CTLFLAG_PERMANENT, CTLTYPE_NODE, "iwm",
   6910  1.32    nonaka 	    SYSCTL_DESCR("iwm global controls"),
   6911  1.32    nonaka 	    NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL)) != 0)
   6912  1.32    nonaka 		goto err;
   6913  1.32    nonaka 
   6914  1.32    nonaka 	/* control debugging printfs */
   6915  1.32    nonaka 	if ((rc = sysctl_createv(clog, 0, &rnode, &cnode,
   6916  1.32    nonaka 	    CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
   6917  1.32    nonaka 	    "debug", SYSCTL_DESCR("Enable debugging output"),
   6918  1.32    nonaka 	    NULL, 0, &iwm_debug, 0, CTL_CREATE, CTL_EOL)) != 0)
   6919  1.32    nonaka 		goto err;
   6920  1.32    nonaka 
   6921  1.32    nonaka 	return;
   6922  1.32    nonaka 
   6923  1.32    nonaka  err:
   6924  1.32    nonaka 	aprint_error("%s: sysctl_createv failed (rc = %d)\n", __func__, rc);
   6925  1.32    nonaka }
   6926  1.32    nonaka #endif /* IWM_DEBUG */
   6927