Merge remote-tracking branch 'iwlwifi-fixes/master' into NEXT
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Sun, 14 Sep 2014 09:54:42 +0000 (12:54 +0300)
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Sun, 14 Sep 2014 09:54:42 +0000 (12:54 +0300)
14 files changed:
1  2 
drivers/net/wireless/iwlwifi/Kconfig
drivers/net/wireless/iwlwifi/iwl-7000.c
drivers/net/wireless/iwlwifi/iwl-8000.c
drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
drivers/net/wireless/iwlwifi/mvm/coex.c
drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c
drivers/net/wireless/iwlwifi/mvm/fw-api.h
drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
drivers/net/wireless/iwlwifi/mvm/mac80211.c
drivers/net/wireless/iwlwifi/mvm/power.c
drivers/net/wireless/iwlwifi/mvm/rx.c
drivers/net/wireless/iwlwifi/mvm/sf.c
drivers/net/wireless/iwlwifi/mvm/tx.c
drivers/net/wireless/iwlwifi/pcie/drv.c

index 760e96f63bb02ed2bd19c1be6582a27a345207c0,824f5e2877835d8a829f643d8b15cf1ed85e2572..267e48a2915e7885993979337619d777c8cb74c8
@@@ -51,7 -51,6 +51,6 @@@ config IWLWIFI_LED
  
  config IWLDVM
        tristate "Intel Wireless WiFi DVM Firmware support"
-       depends on m
        default IWLWIFI
        help
          This is the driver that supports the DVM firmware which is
@@@ -60,7 -59,6 +59,6 @@@
  
  config IWLMVM
        tristate "Intel Wireless WiFi MVM Firmware support"
-       depends on m
        help
          This is the driver that supports the MVM firmware which is
          currently only available for 7260 and 3160 devices.
@@@ -87,16 -85,6 +85,16 @@@ config IWLWIFI_BCAST_FILTERIN
          If unsure, don't enable this option, as some programs might
          expect incoming broadcasts for their normal operations.
  
 +config IWLWIFI_UAPSD
 +      bool "enable U-APSD by default"
 +      depends on IWLMVM
 +      help
 +        Say Y here to enable U-APSD by default. This may cause
 +        interoperability problems with some APs, manifesting in lower than
 +        expected throughput due to those APs not enabling aggregation
 +
 +        If unsure, say N.
 +
  menu "Debugging Options"
  
  config IWLWIFI_DEBUG
index 446654aed0177c6c0f1bb1410d0b50b2cfd40072,d53adc245497cf29940374510c933a40a4704f77..8e99dffa88e8134e7f1540c9fb2d48ddfa452381
@@@ -6,7 -6,6 +6,7 @@@
   * GPL LICENSE SUMMARY
   *
   * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
 + * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of version 2 of the GNU General Public License as
@@@ -32,7 -31,6 +32,7 @@@
   * BSD LICENSE
   *
   * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
 + * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
@@@ -69,8 -67,8 +69,8 @@@
  #include "iwl-agn-hw.h"
  
  /* Highest firmware API version supported */
- #define IWL7260_UCODE_API_MAX 9
- #define IWL3160_UCODE_API_MAX 9
+ #define IWL7260_UCODE_API_MAX 10
+ #define IWL3160_UCODE_API_MAX 10
  
  /* Oldest version we won't warn about */
  #define IWL7260_UCODE_API_OK  9
@@@ -85,6 -83,8 +85,8 @@@
  #define IWL7260_TX_POWER_VERSION      0xffff /* meaningless */
  #define IWL3160_NVM_VERSION           0x709
  #define IWL3160_TX_POWER_VERSION      0xffff /* meaningless */
+ #define IWL3165_NVM_VERSION           0x709
+ #define IWL3165_TX_POWER_VERSION      0xffff /* meaningless */
  #define IWL7265_NVM_VERSION           0x0a1d
  #define IWL7265_TX_POWER_VERSION      0xffff /* meaningless */
  
@@@ -94,6 -94,9 +96,9 @@@
  #define IWL3160_FW_PRE "iwlwifi-3160-"
  #define IWL3160_MODULE_FIRMWARE(api) IWL3160_FW_PRE __stringify(api) ".ucode"
  
+ #define IWL3165_FW_PRE "iwlwifi-3165-"
+ #define IWL3165_MODULE_FIRMWARE(api) IWL3165_FW_PRE __stringify(api) ".ucode"
  #define IWL7265_FW_PRE "iwlwifi-7265-"
  #define IWL7265_MODULE_FIRMWARE(api) IWL7265_FW_PRE __stringify(api) ".ucode"
  
@@@ -215,6 -218,16 +220,16 @@@ static const struct iwl_pwr_tx_backoff 
        {0},
  };
  
+ const struct iwl_cfg iwl3165_2ac_cfg = {
+       .name = "Intel(R) Dual Band Wireless AC 3165",
+       .fw_name_pre = IWL3165_FW_PRE,
+       IWL_DEVICE_7000,
+       .ht_params = &iwl7000_ht_params,
+       .nvm_ver = IWL3165_NVM_VERSION,
+       .nvm_calib_ver = IWL3165_TX_POWER_VERSION,
+       .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs,
+ };
  const struct iwl_cfg iwl7265_2ac_cfg = {
        .name = "Intel(R) Dual Band Wireless AC 7265",
        .fw_name_pre = IWL7265_FW_PRE,
@@@ -247,4 -260,5 +262,5 @@@ const struct iwl_cfg iwl7265_n_cfg = 
  
  MODULE_FIRMWARE(IWL7260_MODULE_FIRMWARE(IWL7260_UCODE_API_OK));
  MODULE_FIRMWARE(IWL3160_MODULE_FIRMWARE(IWL3160_UCODE_API_OK));
+ MODULE_FIRMWARE(IWL3165_MODULE_FIRMWARE(IWL3160_UCODE_API_OK));
  MODULE_FIRMWARE(IWL7265_MODULE_FIRMWARE(IWL7260_UCODE_API_OK));
index 90388e70db9b5f230e3f6e0c89931b6fefb80033,e93c6972290b84de3cf26214ca6894d0db0c4f79..23a67bfc086f3e35c774d4027d9b9b8f3c35b273
@@@ -6,7 -6,6 +6,7 @@@
   * GPL LICENSE SUMMARY
   *
   * Copyright(c) 2014 Intel Corporation. All rights reserved.
 + * Copyright(c) 2014 Intel Mobile Communications GmbH
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of version 2 of the GNU General Public License as
@@@ -32,7 -31,6 +32,7 @@@
   * BSD LICENSE
   *
   * Copyright(c) 2014 Intel Corporation. All rights reserved.
 + * Copyright(c) 2014 Intel Mobile Communications GmbH
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
@@@ -69,7 -67,7 +69,7 @@@
  #include "iwl-agn-hw.h"
  
  /* Highest firmware API version supported */
- #define IWL8000_UCODE_API_MAX 9
+ #define IWL8000_UCODE_API_MAX 10
  
  /* Oldest version we won't warn about */
  #define IWL8000_UCODE_API_OK  8
index 8e7af798abd13b3a8e31f861b4892a40922ce608,354255f087544ea455b708ef853bdb7f1a0fbb72..40718f814f8df58d888fab99248d558a4539ef6b
@@@ -6,7 -6,6 +6,7 @@@
   * GPL LICENSE SUMMARY
   *
   * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
 + * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of version 2 of the GNU General Public License as
@@@ -32,7 -31,6 +32,7 @@@
   * BSD LICENSE
   *
   * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
 + * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
@@@ -148,8 -146,6 +148,6 @@@ static const u8 iwl_nvm_channels_family
  #define LAST_2GHZ_HT_PLUS             9
  #define LAST_5GHZ_HT                  161
  
- #define DEFAULT_MAX_TX_POWER 16
  /* rate data (static) */
  static struct ieee80211_rate iwl_cfg80211_rates[] = {
        { .bitrate = 1 * 10, .hw_value = 0, .hw_value_short = 0, },
@@@ -297,7 -293,7 +295,7 @@@ static int iwl_init_channel_map(struct 
                 * Default value - highest tx power value.  max_power
                 * is not used in mvm, and is used for backwards compatibility
                 */
-               channel->max_power = DEFAULT_MAX_TX_POWER;
+               channel->max_power = IWL_DEFAULT_MAX_TX_POWER;
                is_5ghz = channel->band == IEEE80211_BAND_5GHZ;
                IWL_DEBUG_EEPROM(dev,
                                 "Ch. %d [%sGHz] %s%s%s%s%s%s%s(0x%02x %ddBm): Ad-Hoc %ssupported\n",
index 2262d6dc61aea41548aa57f4eb707e0e4e1b9697,ce71625f497ff8f34384b803121b9312aa35afde..6e8f3e2aef74386b8ccb1aaf74e39eda73f57075
@@@ -6,7 -6,6 +6,7 @@@
   * GPL LICENSE SUMMARY
   *
   * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
 + * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of version 2 of the GNU General Public License as
@@@ -32,7 -31,6 +32,7 @@@
   * BSD LICENSE
   *
   * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
 + * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
@@@ -587,8 -585,6 +587,6 @@@ int iwl_send_bt_init_conf(struct iwl_mv
        lockdep_assert_held(&mvm->mutex);
  
        if (unlikely(mvm->bt_force_ant_mode != BT_FORCE_ANT_DIS)) {
-               u32 mode;
                switch (mvm->bt_force_ant_mode) {
                case BT_FORCE_ANT_BT:
                        mode = BT_COEX_BT;
@@@ -758,7 -754,8 +756,8 @@@ static void iwl_mvm_bt_notif_iterator(v
        struct iwl_bt_iterator_data *data = _data;
        struct iwl_mvm *mvm = data->mvm;
        struct ieee80211_chanctx_conf *chanctx_conf;
-       enum ieee80211_smps_mode smps_mode;
+       /* default smps_mode is AUTOMATIC - only used for client modes */
+       enum ieee80211_smps_mode smps_mode = IEEE80211_SMPS_AUTOMATIC;
        u32 bt_activity_grading;
        int ave_rssi;
  
  
        switch (vif->type) {
        case NL80211_IFTYPE_STATION:
-               /* default smps_mode for BSS / P2P client is AUTOMATIC */
-               smps_mode = IEEE80211_SMPS_AUTOMATIC;
                break;
        case NL80211_IFTYPE_AP:
                if (!mvmvif->ap_ibss_active)
        else if (bt_activity_grading >= BT_LOW_TRAFFIC)
                smps_mode = IEEE80211_SMPS_DYNAMIC;
  
-       /* relax SMPS contraints for next association */
+       /* relax SMPS constraints for next association */
        if (!vif->bss_conf.assoc)
                smps_mode = IEEE80211_SMPS_AUTOMATIC;
  
index d919b4ebc83ccdb6c0adc0912b7edbbbc2e5b86b,87e517bffedc6647a0b1e9fbc27758647ea6907e..9aa2311a776c29f11a595de66eb5f8134c60cec6
@@@ -6,7 -6,6 +6,7 @@@
   * GPL LICENSE SUMMARY
   *
   * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
 + * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of version 2 of the GNU General Public License as
@@@ -32,7 -31,6 +32,7 @@@
   * BSD LICENSE
   *
   * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
 + * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
@@@ -76,8 -74,7 +76,7 @@@ static void iwl_dbgfs_update_pm(struct 
  
        switch (param) {
        case MVM_DEBUGFS_PM_KEEP_ALIVE: {
-               struct ieee80211_hw *hw = mvm->hw;
-               int dtimper = hw->conf.ps_dtim_period ?: 1;
+               int dtimper = vif->bss_conf.dtim_period ?: 1;
                int dtimper_msec = dtimper * vif->bss_conf.beacon_int;
  
                IWL_DEBUG_POWER(mvm, "debugfs: set keep_alive= %d sec\n", val);
                IWL_DEBUG_POWER(mvm, "uapsd_misbehaving_enable=%d\n", val);
                dbgfs_pm->uapsd_misbehaving = val;
                break;
 +      case MVM_DEBUGFS_PM_USE_PS_POLL:
 +              IWL_DEBUG_POWER(mvm, "use_ps_poll=%d\n", val);
 +              dbgfs_pm->use_ps_poll = val;
 +              break;
        }
  }
  
@@@ -175,10 -168,6 +174,10 @@@ static ssize_t iwl_dbgfs_pm_params_writ
                if (sscanf(buf + 18, "%d", &val) != 1)
                        return -EINVAL;
                param = MVM_DEBUGFS_PM_UAPSD_MISBEHAVING;
 +      } else if (!strncmp("use_ps_poll=", buf, 12)) {
 +              if (sscanf(buf + 12, "%d", &val) != 1)
 +                      return -EINVAL;
 +              param = MVM_DEBUGFS_PM_USE_PS_POLL;
        } else {
                return -EINVAL;
        }
index 9c975f9ecfcb02609a9aca92af1f8ede4624e78b,9a922f3bd16bc00b7a5ce0e6484178db9372a24d..541b844c6b5daf3115b270a47d275a7df72b8353
@@@ -6,7 -6,6 +6,7 @@@
   * GPL LICENSE SUMMARY
   *
   * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
 + * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of version 2 of the GNU General Public License as
@@@ -32,7 -31,6 +32,7 @@@
   * BSD LICENSE
   *
   * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
 + * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
  #include "fw-api-coex.h"
  #include "fw-api-scan.h"
  
 -/* maximal number of Tx queues in any platform */
 -#define IWL_MVM_MAX_QUEUES    20
 -
  /* Tx queue numbers */
  enum {
        IWL_MVM_OFFCHANNEL_QUEUE = 8,
        IWL_MVM_CMD_QUEUE = 9,
  };
  
 -#define IWL_MVM_CMD_FIFO      7
 +enum iwl_mvm_tx_fifo {
 +      IWL_MVM_TX_FIFO_BK = 0,
 +      IWL_MVM_TX_FIFO_BE,
 +      IWL_MVM_TX_FIFO_VI,
 +      IWL_MVM_TX_FIFO_VO,
 +      IWL_MVM_TX_FIFO_MCAST = 5,
 +      IWL_MVM_TX_FIFO_CMD = 7,
 +};
  
  #define IWL_MVM_STATION_COUNT 16
  
@@@ -190,8 -184,6 +190,8 @@@ enum 
        REPLY_RX_MPDU_CMD = 0xc1,
        BA_NOTIF = 0xc5,
  
 +      MARKER_CMD = 0xcb,
 +
        /* BT Coex */
        BT_COEX_PRIO_TABLE = 0xcc,
        BT_COEX_PROT_ENV = 0xcd,
@@@ -1315,38 -1307,6 +1315,38 @@@ struct iwl_bcast_filter_cmd 
        struct iwl_fw_bcast_mac macs[NUM_MAC_INDEX_DRIVER];
  } __packed; /* BCAST_FILTERING_HCMD_API_S_VER_1 */
  
 +/*
 + * enum iwl_mvm_marker_id - maker ids
 + *
 + * The ids for different type of markers to insert into the usniffer logs
 + */
 +enum iwl_mvm_marker_id {
 +      MARKER_ID_TX_FRAME_LATENCY = 1,
 +}; /* MARKER_ID_API_E_VER_1 */
 +
 +/**
 + * struct iwl_mvm_marker - mark info into the usniffer logs
 + *
 + * (MARKER_CMD = 0xcb)
 + *
 + * Mark the UTC time stamp into the usniffer logs together with additional
 + * metadata, so the usniffer output can be parsed.
 + * In the command response the ucode will return the GP2 time.
 + *
 + * @dw_len: The amount of dwords following this byte including this byte.
 + * @marker_id: A unique marker id (iwl_mvm_marker_id).
 + * @reserved: reserved.
 + * @timestamp: in milliseconds since 1970-01-01 00:00:00 UTC
 + * @metadata: additional meta data that will be written to the unsiffer log
 + */
 +struct iwl_mvm_marker {
 +      u8 dwLen;
 +      u8 markerId;
 +      __le16 reserved;
 +      __le64 timestamp;
 +      __le32 metadata[0];
 +} __packed; /* MARKER_API_S_VER_1 */
 +
  struct mvm_statistics_dbg {
        __le32 burst_check;
        __le32 burst_count;
@@@ -1603,14 -1563,14 +1603,14 @@@ enum iwl_sf_scenario 
  
  /**
   * Smart Fifo configuration command.
-  * @state: smart fifo state, types listed in iwl_sf_sate.
+  * @state: smart fifo state, types listed in enum %iwl_sf_sate.
   * @watermark: Minimum allowed availabe free space in RXF for transient state.
   * @long_delay_timeouts: aging and idle timer values for each scenario
   * in long delay state.
   * @full_on_timeouts: timer values for each scenario in full on state.
   */
  struct iwl_sf_cfg_cmd {
-       enum iwl_sf_state state;
+       __le32 state;
        __le32 watermark[SF_TRANSIENT_STATES_NUMBER];
        __le32 long_delay_timeouts[SF_NUM_SCENARIO][SF_NUM_TIMEOUT_TYPES];
        __le32 full_on_timeouts[SF_NUM_SCENARIO][SF_NUM_TIMEOUT_TYPES];
index 9cbb192f680e017fe98765aecdde64fcb8337d82,8242e689ddb114af0a2e17a0d5ce266c19392535..158aed5014734501ea2678ef2379064715f5bc27
@@@ -6,7 -6,6 +6,7 @@@
   * GPL LICENSE SUMMARY
   *
   * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
 + * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of version 2 of the GNU General Public License as
@@@ -32,7 -31,6 +32,7 @@@
   * BSD LICENSE
   *
   * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
 + * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
@@@ -83,7 -81,7 +83,7 @@@ struct iwl_mvm_mac_iface_iterator_data 
        struct ieee80211_vif *vif;
        unsigned long available_mac_ids[BITS_TO_LONGS(NUM_MAC_INDEX_DRIVER)];
        unsigned long available_tsf_ids[BITS_TO_LONGS(NUM_TSF_IDS)];
 -      unsigned long used_hw_queues[BITS_TO_LONGS(IWL_MVM_MAX_QUEUES)];
 +      u32 used_hw_queues;
        enum iwl_tsf_id preferred_tsf;
        bool found_vif;
  };
@@@ -194,31 -192,12 +194,31 @@@ static void iwl_mvm_mac_tsf_id_iter(voi
                data->preferred_tsf = NUM_TSF_IDS;
  }
  
 +/*
 + * Get the mask of the queues used by the vif
 + */
 +u32 iwl_mvm_mac_get_queues_mask(struct iwl_mvm *mvm,
 +                              struct ieee80211_vif *vif)
 +{
 +      u32 qmask = 0, ac;
 +
 +      if (vif->type == NL80211_IFTYPE_P2P_DEVICE)
 +              return BIT(IWL_MVM_OFFCHANNEL_QUEUE);
 +
 +      for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
 +              qmask |= BIT(vif->hw_queue[ac]);
 +
 +      if (vif->type == NL80211_IFTYPE_AP)
 +              qmask |= BIT(vif->cab_queue);
 +
 +      return qmask;
 +}
 +
  static void iwl_mvm_mac_iface_iterator(void *_data, u8 *mac,
                                       struct ieee80211_vif *vif)
  {
        struct iwl_mvm_mac_iface_iterator_data *data = _data;
        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
 -      u32 ac;
  
        /* Iterator may already find the interface being added -- skip it */
        if (vif == data->vif) {
        }
  
        /* Mark the queues used by the vif */
 -      for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
 -              if (vif->hw_queue[ac] != IEEE80211_INVAL_HW_QUEUE)
 -                      __set_bit(vif->hw_queue[ac], data->used_hw_queues);
 -
 -      if (vif->cab_queue != IEEE80211_INVAL_HW_QUEUE)
 -              __set_bit(vif->cab_queue, data->used_hw_queues);
 +      data->used_hw_queues |= iwl_mvm_mac_get_queues_mask(data->mvm, vif);
  
        /* Mark MAC IDs as used by clearing the available bit, and
         * (below) mark TSFs as used if their existing use is not
        iwl_mvm_mac_tsf_id_iter(_data, mac, vif);
  }
  
 -/*
 - * Get the mask of the queus used by the vif
 - */
 -u32 iwl_mvm_mac_get_queues_mask(struct iwl_mvm *mvm,
 -                              struct ieee80211_vif *vif)
 -{
 -      u32 qmask = 0, ac;
 -
 -      if (vif->type == NL80211_IFTYPE_P2P_DEVICE)
 -              return BIT(IWL_MVM_OFFCHANNEL_QUEUE);
 -
 -      for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
 -              if (vif->hw_queue[ac] != IEEE80211_INVAL_HW_QUEUE)
 -                      qmask |= BIT(vif->hw_queue[ac]);
 -
 -      return qmask;
 -}
 -
  void iwl_mvm_mac_ctxt_recalc_tsf_id(struct iwl_mvm *mvm,
                                    struct ieee80211_vif *vif)
  {
@@@ -275,15 -277,15 +275,15 @@@ static int iwl_mvm_mac_ctxt_allocate_re
                .available_tsf_ids = { (1 << NUM_TSF_IDS) - 1 },
                /* no preference yet */
                .preferred_tsf = NUM_TSF_IDS,
 -              .used_hw_queues = {
 +              .used_hw_queues =
                        BIT(IWL_MVM_OFFCHANNEL_QUEUE) |
                        BIT(mvm->aux_queue) |
 -                      BIT(IWL_MVM_CMD_QUEUE)
 -              },
 +                      BIT(IWL_MVM_CMD_QUEUE),
                .found_vif = false,
        };
        u32 ac;
        int ret, i;
 +      unsigned long used_hw_queues;
  
        /*
         * Allocate a MAC ID and a TSF for this MAC, along with the queues
                return 0;
        }
  
 +      used_hw_queues = data.used_hw_queues;
 +
        /* Find available queues, and allocate them to the ACs */
        for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
 -              u8 queue = find_first_zero_bit(data.used_hw_queues,
 +              u8 queue = find_first_zero_bit(&used_hw_queues,
                                               mvm->first_agg_queue);
  
                if (queue >= mvm->first_agg_queue) {
                        goto exit_fail;
                }
  
 -              __set_bit(queue, data.used_hw_queues);
 +              __set_bit(queue, &used_hw_queues);
                vif->hw_queue[ac] = queue;
        }
  
        /* Allocate the CAB queue for softAP and GO interfaces */
        if (vif->type == NL80211_IFTYPE_AP) {
 -              u8 queue = find_first_zero_bit(data.used_hw_queues,
 +              u8 queue = find_first_zero_bit(&used_hw_queues,
                                               mvm->first_agg_queue);
  
                if (queue >= mvm->first_agg_queue) {
@@@ -452,16 -452,14 +452,16 @@@ void iwl_mvm_mac_ctxt_release(struct iw
  
        switch (vif->type) {
        case NL80211_IFTYPE_P2P_DEVICE:
 -              iwl_trans_txq_disable(mvm->trans, IWL_MVM_OFFCHANNEL_QUEUE);
 +              iwl_trans_txq_disable(mvm->trans, IWL_MVM_OFFCHANNEL_QUEUE,
 +                                    true);
                break;
        case NL80211_IFTYPE_AP:
 -              iwl_trans_txq_disable(mvm->trans, vif->cab_queue);
 +              iwl_trans_txq_disable(mvm->trans, vif->cab_queue, true);
                /* fall through */
        default:
                for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
 -                      iwl_trans_txq_disable(mvm->trans, vif->hw_queue[ac]);
 +                      iwl_trans_txq_disable(mvm->trans, vif->hw_queue[ac],
 +                                            true);
        }
  }
  
@@@ -588,7 -586,6 +588,7 @@@ static void iwl_mvm_mac_ctxt_set_ht_fla
  static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm,
                                        struct ieee80211_vif *vif,
                                        struct iwl_mac_ctx_cmd *cmd,
 +                                      const u8 *bssid_override,
                                        u32 action)
  {
        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
        bool ht_enabled = !!(vif->bss_conf.ht_operation_mode &
                             IEEE80211_HT_OP_MODE_PROTECTION);
        u8 cck_ack_rates, ofdm_ack_rates;
 +      const u8 *bssid = bssid_override ?: vif->bss_conf.bssid;
        int i;
  
        cmd->id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
        cmd->tsf_id = cpu_to_le32(mvmvif->tsf_id);
  
        memcpy(cmd->node_addr, vif->addr, ETH_ALEN);
 -      if (vif->bss_conf.bssid)
 -              memcpy(cmd->bssid_addr, vif->bss_conf.bssid, ETH_ALEN);
 +
 +      if (bssid)
 +              memcpy(cmd->bssid_addr, bssid, ETH_ALEN);
        else
                eth_broadcast_addr(cmd->bssid_addr);
  
@@@ -700,8 -695,7 +700,8 @@@ static int iwl_mvm_mac_ctxt_send_cmd(st
  
  static int iwl_mvm_mac_ctxt_cmd_sta(struct iwl_mvm *mvm,
                                    struct ieee80211_vif *vif,
 -                                  u32 action, bool force_assoc_off)
 +                                  u32 action, bool force_assoc_off,
 +                                  const u8 *bssid_override)
  {
        struct iwl_mac_ctx_cmd cmd = {};
        struct iwl_mac_data_sta *ctxt_sta;
        WARN_ON(vif->type != NL80211_IFTYPE_STATION);
  
        /* Fill the common data for all mac context types */
 -      iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
 +      iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, bssid_override, action);
  
        if (vif->p2p) {
                struct ieee80211_p2p_noa_attr *noa =
            !force_assoc_off) {
                u32 dtim_offs;
  
-               /* Allow beacons to pass through as long as we are not
-                * associated, or we do not have dtim period information.
-                */
-               cmd.filter_flags |= cpu_to_le32(MAC_FILTER_IN_BEACON);
                /*
                 * The DTIM count counts down, so when it is N that means N
                 * more beacon intervals happen until the DTIM TBTT. Therefore
                ctxt_sta->is_assoc = cpu_to_le32(1);
        } else {
                ctxt_sta->is_assoc = cpu_to_le32(0);
+               /* Allow beacons to pass through as long as we are not
+                * associated, or we do not have dtim period information.
+                */
+               cmd.filter_flags |= cpu_to_le32(MAC_FILTER_IN_BEACON);
        }
  
        ctxt_sta->bi = cpu_to_le32(vif->bss_conf.beacon_int);
@@@ -790,7 -784,7 +790,7 @@@ static int iwl_mvm_mac_ctxt_cmd_listene
  
        WARN_ON(vif->type != NL80211_IFTYPE_MONITOR);
  
 -      iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
 +      iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, NULL, action);
  
        cmd.filter_flags = cpu_to_le32(MAC_FILTER_IN_PROMISC |
                                       MAC_FILTER_IN_CONTROL_AND_MGMT |
@@@ -811,7 -805,7 +811,7 @@@ static int iwl_mvm_mac_ctxt_cmd_ibss(st
  
        WARN_ON(vif->type != NL80211_IFTYPE_ADHOC);
  
 -      iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
 +      iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, NULL, action);
  
        cmd.filter_flags = cpu_to_le32(MAC_FILTER_IN_BEACON |
                                       MAC_FILTER_IN_PROBE_REQUEST);
@@@ -850,7 -844,7 +850,7 @@@ static int iwl_mvm_mac_ctxt_cmd_p2p_dev
  
        WARN_ON(vif->type != NL80211_IFTYPE_P2P_DEVICE);
  
 -      iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
 +      iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, NULL, action);
  
        cmd.protection_flags |= cpu_to_le32(MAC_PROT_FLG_TGG_PROTECT);
  
@@@ -1078,7 -1072,7 +1078,7 @@@ static int iwl_mvm_mac_ctxt_cmd_ap(stru
        WARN_ON(vif->type != NL80211_IFTYPE_AP || vif->p2p);
  
        /* Fill the common data for all mac context types */
 -      iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
 +      iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, NULL, action);
  
        /*
         * pass probe requests and beacons from other APs (needed
@@@ -1104,7 -1098,7 +1104,7 @@@ static int iwl_mvm_mac_ctxt_cmd_go(stru
        WARN_ON(vif->type != NL80211_IFTYPE_AP || !vif->p2p);
  
        /* Fill the common data for all mac context types */
 -      iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
 +      iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, NULL, action);
  
        /*
         * pass probe requests and beacons from other APs (needed
  }
  
  static int iwl_mvm_mac_ctx_send(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
 -                              u32 action, bool force_assoc_off)
 +                              u32 action, bool force_assoc_off,
 +                              const u8 *bssid_override)
  {
        switch (vif->type) {
        case NL80211_IFTYPE_STATION:
                return iwl_mvm_mac_ctxt_cmd_sta(mvm, vif, action,
 -                                              force_assoc_off);
 +                                              force_assoc_off,
 +                                              bssid_override);
                break;
        case NL80211_IFTYPE_AP:
                if (!vif->p2p)
@@@ -1165,7 -1157,7 +1165,7 @@@ int iwl_mvm_mac_ctxt_add(struct iwl_mv
                return -EIO;
  
        ret = iwl_mvm_mac_ctx_send(mvm, vif, FW_CTXT_ACTION_ADD,
 -                                 true);
 +                                 true, NULL);
        if (ret)
                return ret;
  
  }
  
  int iwl_mvm_mac_ctxt_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
 -                           bool force_assoc_off)
 +                           bool force_assoc_off, const u8 *bssid_override)
  {
        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
  
                return -EIO;
  
        return iwl_mvm_mac_ctx_send(mvm, vif, FW_CTXT_ACTION_MODIFY,
 -                                  force_assoc_off);
 +                                  force_assoc_off, bssid_override);
  }
  
  int iwl_mvm_mac_ctxt_remove(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
index 8d1d4b40b0a33cec85b92df7881f81375329f931,cdc272d776e7f298baa6c71dc156ce576021e151..069bb8e81c3656d61fc67105e911b30747a11c9c
@@@ -6,7 -6,6 +6,7 @@@
   * GPL LICENSE SUMMARY
   *
   * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
 + * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of version 2 of the GNU General Public License as
@@@ -32,7 -31,6 +32,7 @@@
   * BSD LICENSE
   *
   * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
 + * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
@@@ -398,12 -396,14 +398,14 @@@ int iwl_mvm_mac_setup_register(struct i
        else
                hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
  
-       /* TODO: enable that only for firmwares that don't crash */
-       /* hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; */
-       hw->wiphy->max_sched_scan_ssids = PROBE_OPTION_MAX;
-       hw->wiphy->max_match_sets = IWL_SCAN_MAX_PROFILES;
-       /* we create the 802.11 header and zero length SSID IE. */
-       hw->wiphy->max_sched_scan_ie_len = SCAN_OFFLOAD_PROBE_REQ_SIZE - 24 - 2;
+       if (IWL_UCODE_API(mvm->fw->ucode_ver) >= 10) {
+               hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
+               hw->wiphy->max_sched_scan_ssids = PROBE_OPTION_MAX;
+               hw->wiphy->max_match_sets = IWL_SCAN_MAX_PROFILES;
+               /* we create the 802.11 header and zero length SSID IE. */
+               hw->wiphy->max_sched_scan_ie_len =
+                       SCAN_OFFLOAD_PROBE_REQ_SIZE - 24 - 2;
+       }
  
        hw->wiphy->features |= NL80211_FEATURE_P2P_GO_CTWIN |
                               NL80211_FEATURE_LOW_PRIORITY_SCAN |
@@@ -778,7 -778,6 +780,7 @@@ static void iwl_mvm_restart_cleanup(str
        iwl_trans_stop_device(mvm->trans);
  
        mvm->scan_status = IWL_MVM_SCAN_NONE;
 +      mvm->ps_disabled = false;
  
        /* just in case one was running */
        ieee80211_remain_on_channel_expired(mvm->hw);
         * ucode_down ref until reconfig is complete */
        iwl_mvm_unref_all_except(mvm, IWL_MVM_REF_UCODE_DOWN);
  
 +      /* clear any stale d0i3 state */
 +      clear_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status);
 +
        mvm->vif_count = 0;
        mvm->rx_ba_sessions = 0;
  }
@@@ -886,7 -882,7 +888,7 @@@ static void iwl_mvm_mac_stop(struct iee
        /* async_handlers_list is empty and will stay empty: HW is stopped */
  
        /* the fw is stopped, the aux sta is dead: clean up driver state */
 -      iwl_mvm_dealloc_int_sta(mvm, &mvm->aux_sta);
 +      iwl_mvm_del_aux_sta(mvm);
  
        mutex_unlock(&mvm->mutex);
  
@@@ -971,7 -967,10 +973,7 @@@ static int iwl_mvm_mac_add_interface(st
         */
        if (vif->type == NL80211_IFTYPE_AP ||
            vif->type == NL80211_IFTYPE_ADHOC) {
 -              u32 qmask = iwl_mvm_mac_get_queues_mask(mvm, vif);
 -              ret = iwl_mvm_allocate_int_sta(mvm, &mvmvif->bcast_sta,
 -                                             qmask,
 -                                             ieee80211_vif_type_p2p(vif));
 +              ret = iwl_mvm_alloc_bcast_sta(mvm, vif);
                if (ret) {
                        IWL_ERR(mvm, "Failed to allocate bcast sta\n");
                        goto out_release;
                if (ret)
                        goto out_unref_phy;
  
 -              ret = iwl_mvm_add_bcast_sta(mvm, vif, &mvmvif->bcast_sta);
 +              ret = iwl_mvm_add_bcast_sta(mvm, vif);
                if (ret)
                        goto out_unbind;
  
  static void iwl_mvm_prepare_mac_removal(struct iwl_mvm *mvm,
                                        struct ieee80211_vif *vif)
  {
 -      u32 tfd_msk = 0, ac;
 -
 -      for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
 -              if (vif->hw_queue[ac] != IEEE80211_INVAL_HW_QUEUE)
 -                      tfd_msk |= BIT(vif->hw_queue[ac]);
 -
 -      if (vif->cab_queue != IEEE80211_INVAL_HW_QUEUE)
 -              tfd_msk |= BIT(vif->cab_queue);
 +      u32 tfd_msk = iwl_mvm_mac_get_queues_mask(mvm, vif);
  
        if (tfd_msk) {
                mutex_lock(&mvm->mutex);
@@@ -1116,13 -1122,13 +1118,13 @@@ static void iwl_mvm_mac_remove_interfac
                        mvm->noa_duration = 0;
                }
  #endif
 -              iwl_mvm_dealloc_int_sta(mvm, &mvmvif->bcast_sta);
 +              iwl_mvm_dealloc_bcast_sta(mvm, vif);
                goto out_release;
        }
  
        if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
                mvm->p2p_device_vif = NULL;
 -              iwl_mvm_rm_bcast_sta(mvm, &mvmvif->bcast_sta);
 +              iwl_mvm_rm_bcast_sta(mvm, vif);
                iwl_mvm_binding_remove_vif(mvm, vif);
                iwl_mvm_phy_ctxt_unref(mvm, mvmvif->phy_ctxt);
                mvmvif->phy_ctxt = NULL;
@@@ -1441,23 -1447,10 +1443,23 @@@ static void iwl_mvm_bss_info_changed_st
        if (changes & BSS_CHANGED_ASSOC && bss_conf->assoc)
                iwl_mvm_mac_ctxt_recalc_tsf_id(mvm, vif);
  
 -      ret = iwl_mvm_mac_ctxt_changed(mvm, vif, false);
 +      /*
 +       * If we're not associated yet, take the (new) BSSID before associating
 +       * so the firmware knows. If we're already associated, then use the old
 +       * BSSID here, and we'll send a cleared one later in the CHANGED_ASSOC
 +       * branch for disassociation below.
 +       */
 +      if (changes & BSS_CHANGED_BSSID && !mvmvif->associated)
 +              memcpy(mvmvif->bssid, bss_conf->bssid, ETH_ALEN);
 +
 +      ret = iwl_mvm_mac_ctxt_changed(mvm, vif, false, mvmvif->bssid);
        if (ret)
                IWL_ERR(mvm, "failed to update MAC %pM\n", vif->addr);
  
 +      /* after sending it once, adopt mac80211 data */
 +      memcpy(mvmvif->bssid, bss_conf->bssid, ETH_ALEN);
 +      mvmvif->associated = bss_conf->assoc;
 +
        if (changes & BSS_CHANGED_ASSOC) {
                if (bss_conf->assoc) {
                        /* add quota for this interface */
                                 */
                                u32 dur = (11 * vif->bss_conf.beacon_int) / 10;
                                iwl_mvm_protect_session(mvm, vif, dur, dur,
 -                                                      5 * dur);
 +                                                      5 * dur, false);
                        }
  
                        iwl_mvm_sf_update(mvm, vif, false);
                        iwl_mvm_power_vif_assoc(mvm, vif);
 -                      if (vif->p2p)
 +                      if (vif->p2p) {
                                iwl_mvm_ref(mvm, IWL_MVM_REF_P2P_CLIENT);
 +                              iwl_mvm_update_smps(mvm, vif,
 +                                                  IWL_MVM_SMPS_REQ_PROT,
 +                                                  IEEE80211_SMPS_DYNAMIC);
 +                      }
                } else if (mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) {
                        /*
                         * If update fails - SF might be running in associated
  
                        if (vif->p2p)
                                iwl_mvm_unref(mvm, IWL_MVM_REF_P2P_CLIENT);
 +
 +                      /* this will take the cleared BSSID from bss_conf */
 +                      ret = iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
 +                      if (ret)
 +                              IWL_ERR(mvm,
 +                                      "failed to update MAC %pM (clear after unassoc)\n",
 +                                      vif->addr);
                }
  
                iwl_mvm_recalc_multicast(mvm);
                 */
                iwl_mvm_remove_time_event(mvm, mvmvif,
                                          &mvmvif->time_event_data);
-       } else if (changes & (BSS_CHANGED_PS | BSS_CHANGED_P2P_PS |
-                             BSS_CHANGED_QOS)) {
-               ret = iwl_mvm_power_update_mac(mvm);
-               if (ret)
-                       IWL_ERR(mvm, "failed to update power mode\n");
        }
  
        if (changes & BSS_CHANGED_BEACON_INFO) {
                WARN_ON(iwl_mvm_enable_beacon_filter(mvm, vif, 0));
        }
  
+       if (changes & (BSS_CHANGED_PS | BSS_CHANGED_P2P_PS | BSS_CHANGED_QOS)) {
+               ret = iwl_mvm_power_update_mac(mvm);
+               if (ret)
+                       IWL_ERR(mvm, "failed to update power mode\n");
+       }
        if (changes & BSS_CHANGED_TXPOWER) {
                IWL_DEBUG_CALIB(mvm, "Changing TX Power to %d\n",
                                bss_conf->txpower);
@@@ -1621,7 -1604,7 +1624,7 @@@ static int iwl_mvm_start_ap_ibss(struc
  
        /* Send the bcast station. At this stage the TBTT and DTIM time events
         * are added and applied to the scheduler */
 -      ret = iwl_mvm_send_bcast_sta(mvm, vif, &mvmvif->bcast_sta);
 +      ret = iwl_mvm_send_add_bcast_sta(mvm, vif);
        if (ret)
                goto out_unbind;
  
  
        /* Need to update the P2P Device MAC (only GO, IBSS is single vif) */
        if (vif->p2p && mvm->p2p_device_vif)
 -              iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif, false);
 +              iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif, false, NULL);
  
        iwl_mvm_ref(mvm, IWL_MVM_REF_AP_IBSS);
  
  out_quota_failed:
        iwl_mvm_power_update_mac(mvm);
        mvmvif->ap_ibss_active = false;
 -      iwl_mvm_send_rm_bcast_sta(mvm, &mvmvif->bcast_sta);
 +      iwl_mvm_send_rm_bcast_sta(mvm, vif);
  out_unbind:
        iwl_mvm_binding_remove_vif(mvm, vif);
  out_remove:
@@@ -1695,10 -1678,10 +1698,10 @@@ static void iwl_mvm_stop_ap_ibss(struc
  
        /* Need to update the P2P Device MAC (only GO, IBSS is single vif) */
        if (vif->p2p && mvm->p2p_device_vif)
 -              iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif, false);
 +              iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif, false, NULL);
  
        iwl_mvm_update_quotas(mvm, NULL);
 -      iwl_mvm_send_rm_bcast_sta(mvm, &mvmvif->bcast_sta);
 +      iwl_mvm_send_rm_bcast_sta(mvm, vif);
        iwl_mvm_binding_remove_vif(mvm, vif);
  
        iwl_mvm_power_update_mac(mvm);
@@@ -1722,7 -1705,7 +1725,7 @@@ iwl_mvm_bss_info_changed_ap_ibss(struc
  
        if (changes & (BSS_CHANGED_ERP_CTS_PROT | BSS_CHANGED_HT |
                       BSS_CHANGED_BANDWIDTH) &&
 -          iwl_mvm_mac_ctxt_changed(mvm, vif, false))
 +          iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL))
                IWL_ERR(mvm, "failed to update MAC %pM\n", vif->addr);
  
        /* Need to send a new beacon template to the FW */
@@@ -2133,7 -2116,7 +2136,7 @@@ static int iwl_mvm_mac_conf_tx(struct i
                int ret;
  
                mutex_lock(&mvm->mutex);
 -              ret = iwl_mvm_mac_ctxt_changed(mvm, vif, false);
 +              ret = iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
                mutex_unlock(&mvm->mutex);
                return ret;
        }
@@@ -2161,7 -2144,7 +2164,7 @@@ static void iwl_mvm_mac_mgd_prepare_tx(
  
        mutex_lock(&mvm->mutex);
        /* Try really hard to protect the session and hear a beacon */
 -      iwl_mvm_protect_session(mvm, vif, duration, min_duration, 500);
 +      iwl_mvm_protect_session(mvm, vif, duration, min_duration, 500, false);
        mutex_unlock(&mvm->mutex);
  
        iwl_mvm_unref(mvm, IWL_MVM_REF_PREPARE_TX);
@@@ -2182,7 -2165,7 +2185,7 @@@ static void iwl_mvm_mac_mgd_protect_tdl
  
        mutex_lock(&mvm->mutex);
        /* Protect the session to hear the TDLS setup response on the channel */
 -      iwl_mvm_protect_session(mvm, vif, duration, duration, 100);
 +      iwl_mvm_protect_session(mvm, vif, duration, duration, 100, true);
        mutex_unlock(&mvm->mutex);
  
        iwl_mvm_unref(mvm, IWL_MVM_REF_PROTECT_TDLS);
@@@ -2720,10 -2703,7 +2723,10 @@@ static int __iwl_mvm_assign_vif_chanctx
                ret = 0;
                goto out;
        case NL80211_IFTYPE_STATION:
 +              break;
        case NL80211_IFTYPE_MONITOR:
 +              /* always disable PS when a monitor interface is active */
 +              mvmvif->ps_disabled = true;
                break;
        default:
                ret = -EINVAL;
        if ((vif->type == NL80211_IFTYPE_AP) ||
            (switching_chanctx && (vif->type == NL80211_IFTYPE_STATION))) {
                iwl_mvm_update_quotas(mvm, NULL);
 -              iwl_mvm_mac_ctxt_changed(mvm, vif, false);
 +              iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
 +      }
 +
 +      if (vif->csa_active && vif->type == NL80211_IFTYPE_STATION) {
 +              struct iwl_mvm_sta *mvmsta;
 +
 +              mvmsta = iwl_mvm_sta_from_staid_protected(mvm,
 +                                                        mvmvif->ap_sta_id);
 +
 +              if (WARN_ON(!mvmsta))
 +                      goto out;
 +
 +              /* TODO: only re-enable after the first beacon */
 +              iwl_mvm_sta_modify_disable_tx(mvm, mvmsta, false);
        }
  
        goto out;
@@@ -2802,7 -2769,6 +2805,7 @@@ static void __iwl_mvm_unassign_vif_chan
  {
        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
        struct ieee80211_vif *disabled_vif = NULL;
 +      struct iwl_mvm_sta *mvmsta;
  
        lockdep_assert_held(&mvm->mutex);
  
                goto out;
        case NL80211_IFTYPE_MONITOR:
                mvmvif->monitor_active = false;
 +              mvmvif->ps_disabled = false;
                break;
        case NL80211_IFTYPE_AP:
                /* This part is triggered only during CSA */
  
                disabled_vif = vif;
  
 -              iwl_mvm_mac_ctxt_changed(mvm, vif, true);
 +              mvmsta = iwl_mvm_sta_from_staid_protected(mvm,
 +                                                        mvmvif->ap_sta_id);
 +
 +              if (!WARN_ON(!mvmsta))
 +                      iwl_mvm_sta_modify_disable_tx(mvm, mvmsta, true);
 +
 +              iwl_mvm_mac_ctxt_changed(mvm, vif, true, NULL);
                break;
        default:
                break;
index e7a6626fe8397691904f6ef1321541f002837ac9,d9769a23c68b44e9b16e3ce6bddd7aa191c45e27..5a29c193b72ac652d7fb19dfc2fd12e89694b43e
@@@ -6,7 -6,6 +6,7 @@@
   * GPL LICENSE SUMMARY
   *
   * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
 + * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of version 2 of the GNU General Public License as
@@@ -32,7 -31,6 +32,7 @@@
   * BSD LICENSE
   *
   * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
 + * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
@@@ -200,15 -198,8 +200,15 @@@ static void iwl_mvm_power_configure_uap
                }
        }
  
 -      if (!(cmd->flags & cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK)))
 +      if (!(cmd->flags & cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK))) {
 +#ifdef CONFIG_IWLWIFI_DEBUGFS
 +              /* set advanced pm flag with no uapsd ACs to enable ps-poll */
 +              if (mvmvif->dbgfs_pm.use_ps_poll)
 +                      cmd->flags |=
 +                              cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK);
 +#endif
                return;
 +      }
  
        cmd->flags |= cpu_to_le16(POWER_FLAGS_UAPSD_MISBEHAVING_ENA_MSK);
  
@@@ -290,7 -281,6 +290,6 @@@ static void iwl_mvm_power_build_cmd(str
                                    struct ieee80211_vif *vif,
                                    struct iwl_mac_power_cmd *cmd)
  {
-       struct ieee80211_hw *hw = mvm->hw;
        struct ieee80211_chanctx_conf *chanctx_conf;
        struct ieee80211_channel *chan;
        int dtimper, dtimper_msec;
  
        cmd->id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
                                                            mvmvif->color));
-       dtimper = hw->conf.ps_dtim_period ?: 1;
+       dtimper = vif->bss_conf.dtim_period;
  
        /*
         * Regardless of power management state the driver must set
@@@ -506,31 -496,13 +505,31 @@@ struct iwl_power_vifs 
        bool p2p_tdls;
  };
  
 -static void iwl_mvm_power_iterator(void *_data, u8 *mac,
 -                                 struct ieee80211_vif *vif)
 +static void iwl_mvm_power_disable_pm_iterator(void *_data, u8* mac,
 +                                            struct ieee80211_vif *vif)
  {
        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
 -      struct iwl_power_vifs *power_iterator = _data;
  
        mvmvif->pm_enabled = false;
 +}
 +
 +static void iwl_mvm_power_ps_disabled_iterator(void *_data, u8* mac,
 +                                             struct ieee80211_vif *vif)
 +{
 +      struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
 +      bool *disable_ps = _data;
 +
 +      if (mvmvif->phy_ctxt)
 +              if (mvmvif->phy_ctxt->id < MAX_PHYS)
 +                      *disable_ps |= mvmvif->ps_disabled;
 +}
 +
 +static void iwl_mvm_power_get_vifs_iterator(void *_data, u8 *mac,
 +                                          struct ieee80211_vif *vif)
 +{
 +      struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
 +      struct iwl_power_vifs *power_iterator = _data;
 +
        switch (ieee80211_vif_type_p2p(vif)) {
        case NL80211_IFTYPE_P2P_DEVICE:
                break;
        }
  }
  
 -static void
 -iwl_mvm_power_set_pm(struct iwl_mvm *mvm,
 -                                  struct iwl_power_vifs *vifs)
 +static void iwl_mvm_power_set_pm(struct iwl_mvm *mvm,
 +                               struct iwl_power_vifs *vifs)
  {
        struct iwl_mvm_vif *bss_mvmvif = NULL;
        struct iwl_mvm_vif *p2p_mvmvif = NULL;
  
        lockdep_assert_held(&mvm->mutex);
  
 -      /* get vifs info + set pm_enable to false */
 +      /* set pm_enable to false */
        ieee80211_iterate_active_interfaces_atomic(mvm->hw,
 -                                          IEEE80211_IFACE_ITER_NORMAL,
 -                                          iwl_mvm_power_iterator, vifs);
 +                                      IEEE80211_IFACE_ITER_NORMAL,
 +                                      iwl_mvm_power_disable_pm_iterator,
 +                                      NULL);
  
        if (vifs->bss_vif)
                bss_mvmvif = iwl_mvm_vif_from_mac80211(vifs->bss_vif);
@@@ -844,92 -816,32 +843,92 @@@ int iwl_mvm_disable_beacon_filter(struc
        return ret;
  }
  
 -int iwl_mvm_power_update_mac(struct iwl_mvm *mvm)
 +static int iwl_mvm_power_set_ps(struct iwl_mvm *mvm)
 +{
 +      bool disable_ps;
 +      int ret;
 +
 +      /* disable PS if CAM */
 +      disable_ps = (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM);
 +      /* ...or if any of the vifs require PS to be off */
 +      ieee80211_iterate_active_interfaces_atomic(mvm->hw,
 +                                      IEEE80211_IFACE_ITER_NORMAL,
 +                                      iwl_mvm_power_ps_disabled_iterator,
 +                                      &disable_ps);
 +
 +      /* update device power state if it has changed */
 +      if (mvm->ps_disabled != disable_ps) {
 +              bool old_ps_disabled = mvm->ps_disabled;
 +
 +              mvm->ps_disabled = disable_ps;
 +              ret = iwl_mvm_power_update_device(mvm);
 +              if (ret) {
 +                      mvm->ps_disabled = old_ps_disabled;
 +                      return ret;
 +              }
 +      }
 +
 +      return 0;
 +}
 +
 +static int iwl_mvm_power_set_ba(struct iwl_mvm *mvm,
 +                              struct iwl_power_vifs *vifs)
  {
        struct iwl_mvm_vif *mvmvif;
 +      bool ba_enable;
 +
 +      if (!vifs->bf_vif)
 +              return 0;
 +
 +      mvmvif = iwl_mvm_vif_from_mac80211(vifs->bf_vif);
 +
 +      ba_enable = !(!mvmvif->pm_enabled || mvm->ps_disabled ||
 +                    !vifs->bf_vif->bss_conf.ps ||
 +                    iwl_mvm_vif_low_latency(mvmvif));
 +
 +      return iwl_mvm_update_beacon_abort(mvm, vifs->bf_vif, ba_enable);
 +}
 +
 +int iwl_mvm_power_update_ps(struct iwl_mvm *mvm)
 +{
 +      struct iwl_power_vifs vifs = {
 +              .mvm = mvm,
 +      };
 +      int ret;
 +
 +      lockdep_assert_held(&mvm->mutex);
 +
 +      /* get vifs info */
 +      ieee80211_iterate_active_interfaces_atomic(mvm->hw,
 +                                      IEEE80211_IFACE_ITER_NORMAL,
 +                                      iwl_mvm_power_get_vifs_iterator, &vifs);
 +
 +      ret = iwl_mvm_power_set_ps(mvm);
 +      if (ret)
 +              return ret;
 +
 +      return iwl_mvm_power_set_ba(mvm, &vifs);
 +}
 +
 +int iwl_mvm_power_update_mac(struct iwl_mvm *mvm)
 +{
        struct iwl_power_vifs vifs = {
                .mvm = mvm,
        };
 -      bool ba_enable;
        int ret;
  
        lockdep_assert_held(&mvm->mutex);
  
 +      /* get vifs info */
 +      ieee80211_iterate_active_interfaces_atomic(mvm->hw,
 +                                      IEEE80211_IFACE_ITER_NORMAL,
 +                                      iwl_mvm_power_get_vifs_iterator, &vifs);
 +
        iwl_mvm_power_set_pm(mvm, &vifs);
  
 -      /* disable PS if CAM */
 -      if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM) {
 -              mvm->ps_disabled = true;
 -      } else {
 -      /* don't update device power state unless we add / remove monitor */
 -              if (vifs.monitor_vif) {
 -                      if (vifs.monitor_active)
 -                              mvm->ps_disabled = true;
 -                      ret = iwl_mvm_power_update_device(mvm);
 -                      if (ret)
 -                              return ret;
 -              }
 -      }
 +      ret = iwl_mvm_power_set_ps(mvm);
 +      if (ret)
 +              return ret;
  
        if (vifs.bss_vif) {
                ret = iwl_mvm_power_send_cmd(mvm, vifs.bss_vif);
                        return ret;
        }
  
 -      if (!vifs.bf_vif)
 -              return 0;
 -
 -      mvmvif = iwl_mvm_vif_from_mac80211(vifs.bf_vif);
 -
 -      ba_enable = !(!mvmvif->pm_enabled || mvm->ps_disabled ||
 -                    !vifs.bf_vif->bss_conf.ps ||
 -                    iwl_mvm_vif_low_latency(mvmvif));
 -
 -      return iwl_mvm_update_beacon_abort(mvm, vifs.bf_vif, ba_enable);
 +      return iwl_mvm_power_set_ba(mvm, &vifs);
  }
  
  int iwl_mvm_update_d0i3_power_mode(struct iwl_mvm *mvm,
        iwl_mvm_power_build_cmd(mvm, vif, &cmd);
        if (enable) {
                /* configure skip over dtim up to 300 msec */
-               int dtimper = mvm->hw->conf.ps_dtim_period ?: 1;
+               int dtimper = vif->bss_conf.dtim_period ?: 1;
                int dtimper_msec = dtimper * vif->bss_conf.beacon_int;
  
                if (WARN_ON(!dtimper_msec))
index 48144e3ad52792db3cf0038c1574b21a1f9a474f,bf5cd8c8b0f798d2a0cebf24236f0730304e6b4a..a6cb84ed653fbd7d6ffb2966095507477fcc4296
@@@ -6,7 -6,6 +6,7 @@@
   * GPL LICENSE SUMMARY
   *
   * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
 + * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of version 2 of the GNU General Public License as
@@@ -32,7 -31,6 +32,7 @@@
   * BSD LICENSE
   *
   * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
 + * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
@@@ -151,13 -149,13 +151,13 @@@ static void iwl_mvm_get_signal_strength
            le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_ENERGY_ANT_ABC_IDX]);
        energy_a = (val & IWL_RX_INFO_ENERGY_ANT_A_MSK) >>
                                                IWL_RX_INFO_ENERGY_ANT_A_POS;
-       energy_a = energy_a ? -energy_a : -256;
+       energy_a = energy_a ? -energy_a : S8_MIN;
        energy_b = (val & IWL_RX_INFO_ENERGY_ANT_B_MSK) >>
                                                IWL_RX_INFO_ENERGY_ANT_B_POS;
-       energy_b = energy_b ? -energy_b : -256;
+       energy_b = energy_b ? -energy_b : S8_MIN;
        energy_c = (val & IWL_RX_INFO_ENERGY_ANT_C_MSK) >>
                                                IWL_RX_INFO_ENERGY_ANT_C_POS;
-       energy_c = energy_c ? -energy_c : -256;
+       energy_c = energy_c ? -energy_c : S8_MIN;
        max_energy = max(energy_a, energy_b);
        max_energy = max(max_energy, energy_c);
  
@@@ -493,29 -491,10 +493,29 @@@ int iwl_mvm_rx_statistics(struct iwl_mv
                .mvm = mvm,
        };
  
 +      /*
 +       * set temperature debug enabled - ignore FW temperature updates
 +       * and use the user set temperature.
 +       */
 +      if (mvm->temperature_test) {
 +              if (mvm->temperature < le32_to_cpu(common->temperature))
 +                      IWL_DEBUG_TEMP(mvm,
 +                                     "Ignoring FW temperature update that is greater than the debug set temperature (debug temp = %d, fw temp = %d)\n",
 +                                     mvm->temperature,
 +                                     le32_to_cpu(common->temperature));
 +              /*
 +               * skip iwl_mvm_tt_handler since we are in
 +               * temperature debug mode and we are ignoring
 +               * the new temperature value
 +               */
 +              goto update;
 +      }
 +
        if (mvm->temperature != le32_to_cpu(common->temperature)) {
                mvm->temperature = le32_to_cpu(common->temperature);
                iwl_mvm_tt_handler(mvm);
        }
 +update:
        iwl_mvm_update_rx_statistics(mvm, stats);
  
        ieee80211_iterate_active_interfaces(mvm->hw,
index d1922afe06f471a501bfd9a5e1ba6da68b763e6e,e843b67f2201f5c3159747c4128d08b1c28638a8..f88410c7cbfbadb608b3a79fe72841a5f4bcd475
@@@ -6,7 -6,6 +6,7 @@@
   * GPL LICENSE SUMMARY
   *
   * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
 + * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of version 2 of the GNU General Public License as
@@@ -32,7 -31,6 +32,7 @@@
   * BSD LICENSE
   *
   * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
 + * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
@@@ -174,7 -172,7 +174,7 @@@ static int iwl_mvm_sf_config(struct iwl
                             enum iwl_sf_state new_state)
  {
        struct iwl_sf_cfg_cmd sf_cmd = {
-               .state = new_state,
+               .state = cpu_to_le32(new_state),
        };
        struct ieee80211_sta *sta;
        int ret = 0;
index 963edb8656adc12f6412b1583ede3ef78ba0152d,9ee410bf6da243ced2b65bf61457eecbe3634916..ed0919465e0e555d0422d98abfc9158515c2fa27
@@@ -6,7 -6,6 +6,7 @@@
   * GPL LICENSE SUMMARY
   *
   * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
 + * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of version 2 of the GNU General Public License as
@@@ -32,7 -31,6 +32,7 @@@
   * BSD LICENSE
   *
   * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
 + * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
@@@ -170,10 -168,14 +170,14 @@@ static void iwl_mvm_set_tx_cmd_rate(str
  
        /*
         * for data packets, rate info comes from the table inside the fw. This
-        * table is controlled by LINK_QUALITY commands
+        * table is controlled by LINK_QUALITY commands. Exclude ctrl port
+        * frames like EAPOLs which should be treated as mgmt frames. This
+        * avoids them being sent initially in high rates which increases the
+        * chances for completion of the 4-Way handshake.
         */
  
-       if (ieee80211_is_data(fc) && sta) {
+       if (ieee80211_is_data(fc) && sta &&
+           !(info->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO)) {
                tx_cmd->initial_rate_index = 0;
                tx_cmd->tx_flags |= cpu_to_le32(TX_CMD_FLG_STA_RATE);
                return;
@@@ -484,7 -486,7 +488,7 @@@ static void iwl_mvm_check_ratid_empty(s
                IWL_DEBUG_TX_QUEUES(mvm,
                                    "Can continue DELBA flow ssn = next_recl = %d\n",
                                    tid_data->next_reclaimed);
 -              iwl_trans_txq_disable(mvm->trans, tid_data->txq_id);
 +              iwl_trans_txq_disable(mvm->trans, tid_data->txq_id, true);
                tid_data->state = IWL_AGG_OFF;
                /*
                 * we can't hold the mutex - but since we are after a sequence
index dbbbf23082a2900e1a3b49fb27fe081739e4facd,8bb8305fc2cee5aa50264d656bc7d7670541111a..b9d5049e52da8f0105c52af050f5fdbd03d87da6
@@@ -6,7 -6,6 +6,7 @@@
   * GPL LICENSE SUMMARY
   *
   * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
 + * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of version 2 of the GNU General Public License as
@@@ -32,7 -31,6 +32,7 @@@
   * BSD LICENSE
   *
   * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
 + * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
@@@ -80,7 -78,7 +80,7 @@@
        .driver_data = (kernel_ulong_t)&(cfg)
  
  /* Hardware specific file defines the PCI IDs table for that hardware module */
 -static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
 +static const struct pci_device_id iwl_hw_card_ids[] = {
  #if IS_ENABLED(CONFIG_IWLDVM)
        {IWL_PCI_DEVICE(0x4232, 0x1201, iwl5100_agn_cfg)}, /* Mini Card */
        {IWL_PCI_DEVICE(0x4232, 0x1301, iwl5100_agn_cfg)}, /* Half Mini Card */
        {IWL_PCI_DEVICE(0x08B3, 0x8060, iwl3160_2n_cfg)},
        {IWL_PCI_DEVICE(0x08B3, 0x8062, iwl3160_n_cfg)},
        {IWL_PCI_DEVICE(0x08B4, 0x8270, iwl3160_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x08B4, 0x8370, iwl3160_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x08B4, 0x8272, iwl3160_2ac_cfg)},
        {IWL_PCI_DEVICE(0x08B3, 0x8470, iwl3160_2ac_cfg)},
        {IWL_PCI_DEVICE(0x08B3, 0x8570, iwl3160_2ac_cfg)},
        {IWL_PCI_DEVICE(0x08B3, 0x1070, iwl3160_2ac_cfg)},
        {IWL_PCI_DEVICE(0x08B3, 0x1170, iwl3160_2ac_cfg)},
  
+ /* 3165 Series */
+       {IWL_PCI_DEVICE(0x3165, 0x4010, iwl3165_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x3165, 0x4210, iwl3165_2ac_cfg)},
  /* 7265 Series */
        {IWL_PCI_DEVICE(0x095A, 0x5010, iwl7265_2ac_cfg)},
        {IWL_PCI_DEVICE(0x095A, 0x5110, iwl7265_2ac_cfg)},
        {IWL_PCI_DEVICE(0x095B, 0x5202, iwl7265_n_cfg)},
        {IWL_PCI_DEVICE(0x095A, 0x9010, iwl7265_2ac_cfg)},
        {IWL_PCI_DEVICE(0x095A, 0x9012, iwl7265_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x095A, 0x900A, iwl7265_2ac_cfg)},
        {IWL_PCI_DEVICE(0x095A, 0x9110, iwl7265_2ac_cfg)},
        {IWL_PCI_DEVICE(0x095A, 0x9112, iwl7265_2ac_cfg)},
        {IWL_PCI_DEVICE(0x095A, 0x9210, iwl7265_2ac_cfg)},