Merge tag 'mac80211-next-for-davem-2016-02-26' of git://git.kernel.org/pub/scm/linux...
authorDavid S. Miller <davem@davemloft.net>
Tue, 1 Mar 2016 22:02:30 +0000 (17:02 -0500)
committerDavid S. Miller <davem@davemloft.net>
Tue, 1 Mar 2016 22:03:27 +0000 (17:03 -0500)
Johannes Berg says:

====================
Here's another round of updates for -next:
 * big A-MSDU RX performance improvement (avoid linearize of paged RX)
 * rfkill changes: cleanups, documentation, platform properties
 * basic PBSS support in cfg80211
 * MU-MIMO action frame processing support
 * BlockAck reordering & duplicate detection offload support
 * various cleanups & little fixes
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
16 files changed:
1  2 
drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c
drivers/net/wireless/intel/iwlwifi/mvm/d3.c
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
drivers/net/wireless/intel/iwlwifi/mvm/tx.c
drivers/net/wireless/mac80211_hwsim.c
drivers/net/wireless/ralink/rt2x00/rt2800lib.c
drivers/staging/vt6656/rxtx.c
net/mac80211/debugfs.c
net/mac80211/ibss.c
net/mac80211/mesh.c
net/mac80211/mesh.h
net/mac80211/mlme.c
net/mac80211/sta_info.c
net/mac80211/util.c
net/rfkill/core.c
net/wireless/reg.c

@@@ -396,7 -396,7 +396,7 @@@ static int iwlagn_mac_suspend(struct ie
        iwl_write32(priv->trans, CSR_UCODE_DRV_GP1_SET,
                    CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE);
  
 -      iwl_trans_d3_suspend(priv->trans, false);
 +      iwl_trans_d3_suspend(priv->trans, false, true);
  
        goto out;
  
@@@ -469,7 -469,7 +469,7 @@@ static int iwlagn_mac_resume(struct iee
        /* we'll clear ctx->vif during iwlagn_prepare_restart() */
        vif = ctx->vif;
  
 -      ret = iwl_trans_d3_resume(priv->trans, &d3_status, false);
 +      ret = iwl_trans_d3_resume(priv->trans, &d3_status, false, true);
        if (ret)
                goto out_unlock;
  
@@@ -732,12 -732,15 +732,15 @@@ static inline bool iwl_enable_tx_ampdu(
  
  static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
                                   struct ieee80211_vif *vif,
-                                  enum ieee80211_ampdu_mlme_action action,
-                                  struct ieee80211_sta *sta, u16 tid, u16 *ssn,
-                                  u8 buf_size, bool amsdu)
+                                  struct ieee80211_ampdu_params *params)
  {
        struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
        int ret = -EINVAL;
+       struct ieee80211_sta *sta = params->sta;
+       enum ieee80211_ampdu_mlme_action action = params->action;
+       u16 tid = params->tid;
+       u16 *ssn = &params->ssn;
+       u8 buf_size = params->buf_size;
        struct iwl_station_priv *sta_priv = (void *) sta->drv_priv;
  
        IWL_DEBUG_HT(priv, "A-MPDU action on addr %pM tid %d\n",
@@@ -7,7 -7,6 +7,7 @@@
   *
   * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
   * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
 + * Copyright(c) 2016   Intel Deutschland 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
@@@ -34,7 -33,6 +34,7 @@@
   *
   * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
   * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
 + * Copyright(c) 2016   Intel Deutschland GmbH
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
@@@ -251,16 -249,19 +251,19 @@@ static void iwl_mvm_wowlan_program_keys
                return;
        case WLAN_CIPHER_SUITE_TKIP:
                if (sta) {
+                       u64 pn64;
                        tkip_sc = data->rsc_tsc->all_tsc_rsc.tkip.unicast_rsc;
                        tkip_tx_sc = &data->rsc_tsc->all_tsc_rsc.tkip.tsc;
  
                        rx_p1ks = data->tkip->rx_uni;
  
-                       ieee80211_get_key_tx_seq(key, &seq);
-                       tkip_tx_sc->iv16 = cpu_to_le16(seq.tkip.iv16);
-                       tkip_tx_sc->iv32 = cpu_to_le32(seq.tkip.iv32);
+                       pn64 = atomic64_read(&key->tx_pn);
+                       tkip_tx_sc->iv16 = cpu_to_le16(TKIP_PN_TO_IV16(pn64));
+                       tkip_tx_sc->iv32 = cpu_to_le32(TKIP_PN_TO_IV32(pn64));
  
-                       ieee80211_get_tkip_p1k_iv(key, seq.tkip.iv32, p1k);
+                       ieee80211_get_tkip_p1k_iv(key, TKIP_PN_TO_IV32(pn64),
+                                                 p1k);
                        iwl_mvm_convert_p1k(p1k, data->tkip->tx.p1k);
  
                        memcpy(data->tkip->mic_keys.tx,
@@@ -853,8 -854,7 +856,8 @@@ iwl_mvm_get_wowlan_config(struct iwl_mv
        wowlan_config_cmd->is_11n_connection =
                                        ap_sta->ht_cap.ht_supported;
        wowlan_config_cmd->flags = ENABLE_L3_FILTERING |
 -              ENABLE_NBNS_FILTERING | ENABLE_DHCP_FILTERING;
 +              ENABLE_NBNS_FILTERING | ENABLE_DHCP_FILTERING |
 +              ENABLE_STORE_BEACON;
  
        /* Query the last used seqno and set it */
        ret = iwl_mvm_get_last_nonqos_seq(mvm, vif);
@@@ -1026,18 -1026,14 +1029,18 @@@ iwl_mvm_wowlan_config(struct iwl_mvm *m
                      struct ieee80211_sta *ap_sta)
  {
        int ret;
 +      bool unified_image = fw_has_capa(&mvm->fw->ucode_capa,
 +                                       IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);
  
 -      ret = iwl_mvm_switch_to_d3(mvm);
 -      if (ret)
 -              return ret;
 +      if (!unified_image) {
 +              ret = iwl_mvm_switch_to_d3(mvm);
 +              if (ret)
 +                      return ret;
  
 -      ret = iwl_mvm_d3_reprogram(mvm, vif, ap_sta);
 -      if (ret)
 -              return ret;
 +              ret = iwl_mvm_d3_reprogram(mvm, vif, ap_sta);
 +              if (ret)
 +                      return ret;
 +      }
  
        if (!iwlwifi_mod_params.sw_crypto) {
                /*
@@@ -1079,14 -1075,10 +1082,14 @@@ iwl_mvm_netdetect_config(struct iwl_mv
  {
        struct iwl_wowlan_config_cmd wowlan_config_cmd = {};
        int ret;
 +      bool unified_image = fw_has_capa(&mvm->fw->ucode_capa,
 +                                       IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);
  
 -      ret = iwl_mvm_switch_to_d3(mvm);
 -      if (ret)
 -              return ret;
 +      if (!unified_image) {
 +              ret = iwl_mvm_switch_to_d3(mvm);
 +              if (ret)
 +                      return ret;
 +      }
  
        /* rfkill release can be either for wowlan or netdetect */
        if (wowlan->rfkill_release)
@@@ -1162,8 -1154,6 +1165,8 @@@ static int __iwl_mvm_suspend(struct iee
        };
        int ret;
        int len __maybe_unused;
 +      bool unified_image = fw_has_capa(&mvm->fw->ucode_capa,
 +                                       IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);
  
        if (!wowlan) {
                /*
  
        clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);
  
 -      iwl_trans_d3_suspend(mvm->trans, test);
 +      iwl_trans_d3_suspend(mvm->trans, test, !unified_image);
   out:
        if (ret < 0) {
                iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN);
@@@ -1312,7 -1302,7 +1315,7 @@@ int iwl_mvm_suspend(struct ieee80211_h
                __set_bit(D0I3_DEFER_WAKEUP, &mvm->d0i3_suspend_flags);
                mutex_unlock(&mvm->d0i3_suspend_mutex);
  
 -              iwl_trans_d3_suspend(trans, false);
 +              iwl_trans_d3_suspend(trans, false, false);
  
                return 0;
        }
@@@ -1614,7 -1604,9 +1617,9 @@@ static void iwl_mvm_d3_update_keys(stru
                case WLAN_CIPHER_SUITE_TKIP:
                        iwl_mvm_tkip_sc_to_seq(&sc->tkip.tsc, &seq);
                        iwl_mvm_set_tkip_rx_seq(sc->tkip.unicast_rsc, key);
-                       ieee80211_set_key_tx_seq(key, &seq);
+                       atomic64_set(&key->tx_pn,
+                                    (u64)seq.tkip.iv16 |
+                                    ((u64)seq.tkip.iv32 << 16));
                        break;
                }
  
@@@ -2054,14 -2046,9 +2059,14 @@@ static void iwl_mvm_d3_disconnect_iter(
  static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test)
  {
        struct ieee80211_vif *vif = NULL;
 -      int ret;
 +      int ret = 1;
        enum iwl_d3_status d3_status;
        bool keep = false;
 +      bool unified_image = fw_has_capa(&mvm->fw->ucode_capa,
 +                                       IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);
 +
 +      u32 flags = CMD_ASYNC | CMD_HIGH_PRIO | CMD_SEND_IN_IDLE |
 +                                  CMD_WAKE_UP_TRANS;
  
        mutex_lock(&mvm->mutex);
  
        if (IS_ERR_OR_NULL(vif))
                goto err;
  
 -      ret = iwl_trans_d3_resume(mvm->trans, &d3_status, test);
 +      ret = iwl_trans_d3_resume(mvm->trans, &d3_status, test, !unified_image);
        if (ret)
                goto err;
  
@@@ -2113,28 -2100,17 +2118,28 @@@ out_iterate
                        iwl_mvm_d3_disconnect_iter, keep ? vif : NULL);
  
  out:
 -      /* return 1 to reconfigure the device */
 +      if (unified_image && !ret) {
 +              ret = iwl_mvm_send_cmd_pdu(mvm, D0I3_END_CMD, flags, 0, NULL);
 +              if (!ret) /* D3 ended successfully - no need to reset device */
 +                      return 0;
 +      }
 +
 +      /*
 +       * Reconfigure the device in one of the following cases:
 +       * 1. We are not using a unified image
 +       * 2. We are using a unified image but had an error while exiting D3
 +       */
        set_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);
        set_bit(IWL_MVM_STATUS_D3_RECONFIG, &mvm->status);
 -
 -      /* We always return 1, which causes mac80211 to do a reconfig
 -       * with IEEE80211_RECONFIG_TYPE_RESTART.  This type of
 -       * reconfig calls iwl_mvm_restart_complete(), where we unref
 -       * the IWL_MVM_REF_UCODE_DOWN, so we need to take the
 -       * reference here.
 +      /*
 +       * When switching images we return 1, which causes mac80211
 +       * to do a reconfig with IEEE80211_RECONFIG_TYPE_RESTART.
 +       * This type of reconfig calls iwl_mvm_restart_complete(),
 +       * where we unref the IWL_MVM_REF_UCODE_DOWN, so we need
 +       * to take the reference here.
         */
        iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN);
 +
        return 1;
  }
  
@@@ -2151,7 -2127,7 +2156,7 @@@ static int iwl_mvm_resume_d0i3(struct i
        enum iwl_d3_status d3_status;
        struct iwl_trans *trans = mvm->trans;
  
 -      iwl_trans_d3_resume(trans, &d3_status, false);
 +      iwl_trans_d3_resume(trans, &d3_status, false, false);
  
        /*
         * make sure to clear D0I3_DEFER_WAKEUP before
@@@ -837,13 -837,16 +837,16 @@@ iwl_mvm_ampdu_check_trigger(struct iwl_
  
  static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw,
                                    struct ieee80211_vif *vif,
-                                   enum ieee80211_ampdu_mlme_action action,
-                                   struct ieee80211_sta *sta, u16 tid,
-                                   u16 *ssn, u8 buf_size, bool amsdu)
+                                   struct ieee80211_ampdu_params *params)
  {
        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
        int ret;
        bool tx_agg_ref = false;
+       struct ieee80211_sta *sta = params->sta;
+       enum ieee80211_ampdu_mlme_action action = params->action;
+       u16 tid = params->tid;
+       u16 *ssn = &params->ssn;
+       u8 buf_size = params->buf_size;
  
        IWL_DEBUG_HT(mvm, "A-MPDU action on addr %pM tid %d: action %d\n",
                     sta->addr, tid, action);
                        ret = -EINVAL;
                        break;
                }
 -              ret = iwl_mvm_sta_rx_agg(mvm, sta, tid, *ssn, true);
 +              ret = iwl_mvm_sta_rx_agg(mvm, sta, tid, *ssn, true, buf_size);
                break;
        case IEEE80211_AMPDU_RX_STOP:
 -              ret = iwl_mvm_sta_rx_agg(mvm, sta, tid, 0, false);
 +              ret = iwl_mvm_sta_rx_agg(mvm, sta, tid, 0, false, buf_size);
                break;
        case IEEE80211_AMPDU_TX_START:
                if (!iwl_enable_tx_ampdu(mvm->cfg)) {
@@@ -2582,7 -2585,7 +2585,7 @@@ static int iwl_mvm_mac_set_key(struct i
        switch (key->cipher) {
        case WLAN_CIPHER_SUITE_TKIP:
                key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
-               key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
+               key->flags |= IEEE80211_KEY_FLAG_PUT_IV_SPACE;
                break;
        case WLAN_CIPHER_SUITE_CCMP:
                key->flags |= IEEE80211_KEY_FLAG_PUT_IV_SPACE;
@@@ -299,6 -299,8 +299,8 @@@ static void iwl_mvm_set_tx_cmd_crypto(s
  
        case WLAN_CIPHER_SUITE_TKIP:
                tx_cmd->sec_ctl = TX_CMD_SEC_TKIP;
+               pn = atomic64_inc_return(&keyconf->tx_pn);
+               ieee80211_tkip_add_iv(crypto_hdr, keyconf, pn);
                ieee80211_get_tkip_p2k(keyconf, skb_frag, tx_cmd->key);
                break;
  
@@@ -736,37 -738,6 +738,37 @@@ static void iwl_mvm_hwrate_to_tx_status
        iwl_mvm_hwrate_to_tx_rate(rate_n_flags, info->band, r);
  }
  
 +static void iwl_mvm_tx_status_check_trigger(struct iwl_mvm *mvm,
 +                                          u32 status)
 +{
 +      struct iwl_fw_dbg_trigger_tlv *trig;
 +      struct iwl_fw_dbg_trigger_tx_status *status_trig;
 +      int i;
 +
 +      if (!iwl_fw_dbg_trigger_enabled(mvm->fw, FW_DBG_TRIGGER_TX_STATUS))
 +              return;
 +
 +      trig = iwl_fw_dbg_get_trigger(mvm->fw, FW_DBG_TRIGGER_TX_STATUS);
 +      status_trig = (void *)trig->data;
 +
 +      if (!iwl_fw_dbg_trigger_check_stop(mvm, NULL, trig))
 +              return;
 +
 +      for (i = 0; i < ARRAY_SIZE(status_trig->statuses); i++) {
 +              /* don't collect on status 0 */
 +              if (!status_trig->statuses[i].status)
 +                      break;
 +
 +              if (status_trig->statuses[i].status != (status & TX_STATUS_MSK))
 +                      continue;
 +
 +              iwl_mvm_fw_dbg_collect_trig(mvm, trig,
 +                                          "Tx status %d was received",
 +                                          status & TX_STATUS_MSK);
 +              break;
 +      }
 +}
 +
  static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
                                     struct iwl_rx_packet *pkt)
  {
                        break;
                }
  
 +              iwl_mvm_tx_status_check_trigger(mvm, status);
 +
                info->status.rates[0].count = tx_resp->failure_frame + 1;
                iwl_mvm_hwrate_to_tx_status(le32_to_cpu(tx_resp->initial_rate),
                                            info);
@@@ -1062,6 -1031,7 +1064,6 @@@ static void iwl_mvm_rx_tx_cmd_agg(struc
                struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
                mvmsta->tid_data[tid].rate_n_flags =
                        le32_to_cpu(tx_resp->initial_rate);
 -              mvmsta->tid_data[tid].reduced_tpc = tx_resp->reduced_tpc;
                mvmsta->tid_data[tid].tx_time =
                        le16_to_cpu(tx_resp->wireless_media_time);
        }
@@@ -1092,7 -1062,7 +1094,7 @@@ static void iwl_mvm_tx_info_from_ba_not
        /* TODO: not accounted if the whole A-MPDU failed */
        info->status.tx_time = tid_data->tx_time;
        info->status.status_driver_data[0] =
 -              (void *)(uintptr_t)tid_data->reduced_tpc;
 +              (void *)(uintptr_t)ba_notif->reduced_txp;
        info->status.status_driver_data[1] =
                (void *)(uintptr_t)tid_data->rate_n_flags;
  }
@@@ -1165,8 -1135,6 +1167,8 @@@ void iwl_mvm_rx_ba_notif(struct iwl_mv
                           scd_flow, ba_resp_scd_ssn, ba_notif->txed,
                           ba_notif->txed_2_done);
  
 +      IWL_DEBUG_TX_REPLY(mvm, "reduced txp from ba notif %d\n",
 +                         ba_notif->reduced_txp);
        tid_data->next_reclaimed = ba_resp_scd_ssn;
  
        iwl_mvm_check_ratid_empty(mvm, sta, tid);
@@@ -991,8 -991,7 +991,8 @@@ static void mac80211_hwsim_tx_frame_nl(
                goto nla_put_failure;
        }
  
 -      if (nla_put(skb, HWSIM_ATTR_ADDR_TRANSMITTER, ETH_ALEN, hdr->addr2))
 +      if (nla_put(skb, HWSIM_ATTR_ADDR_TRANSMITTER,
 +                  ETH_ALEN, data->addresses[1].addr))
                goto nla_put_failure;
  
        /* We get the skb->data */
@@@ -1334,10 -1333,8 +1334,8 @@@ static void mac80211_hwsim_tx(struct ie
        data->tx_bytes += skb->len;
        ack = mac80211_hwsim_tx_frame_no_nl(hw, skb, channel);
  
-       if (ack && skb->len >= 16) {
-               struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+       if (ack && skb->len >= 16)
                mac80211_hwsim_monitor_ack(channel, hdr->addr2);
-       }
  
        ieee80211_tx_info_clear_status(txi);
  
@@@ -1846,10 -1843,12 +1844,12 @@@ static int mac80211_hwsim_testmode_cmd(
  
  static int mac80211_hwsim_ampdu_action(struct ieee80211_hw *hw,
                                       struct ieee80211_vif *vif,
-                                      enum ieee80211_ampdu_mlme_action action,
-                                      struct ieee80211_sta *sta, u16 tid, u16 *ssn,
-                                      u8 buf_size, bool amsdu)
+                                      struct ieee80211_ampdu_params *params)
  {
+       struct ieee80211_sta *sta = params->sta;
+       enum ieee80211_ampdu_mlme_action action = params->action;
+       u16 tid = params->tid;
        switch (action) {
        case IEEE80211_AMPDU_TX_START:
                ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
@@@ -2737,7 -2736,7 +2737,7 @@@ static struct mac80211_hwsim_data *get_
  
        spin_lock_bh(&hwsim_radio_lock);
        list_for_each_entry(data, &hwsim_radios, list) {
 -              if (mac80211_hwsim_addr_match(data, addr)) {
 +              if (memcmp(data->addresses[1].addr, addr, ETH_ALEN) == 0) {
                        _found = true;
                        break;
                }
@@@ -1490,8 -1490,7 +1490,8 @@@ void rt2800_config_filter(struct rt2x00
                           !(filter_flags & FIF_FCSFAIL));
        rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_PHY_ERROR,
                           !(filter_flags & FIF_PLCPFAIL));
 -      rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_NOT_TO_ME, 1);
 +      rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_NOT_TO_ME,
 +                         !test_bit(CONFIG_MONITORING, &rt2x00dev->flags));
        rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_NOT_MY_BSSD, 0);
        rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_VER_ERROR, 1);
        rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_MULTICAST,
@@@ -7936,10 -7935,11 +7936,11 @@@ u64 rt2800_get_tsf(struct ieee80211_hw 
  EXPORT_SYMBOL_GPL(rt2800_get_tsf);
  
  int rt2800_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
-                       enum ieee80211_ampdu_mlme_action action,
-                       struct ieee80211_sta *sta, u16 tid, u16 *ssn,
-                       u8 buf_size, bool amsdu)
+                       struct ieee80211_ampdu_params *params)
  {
+       struct ieee80211_sta *sta = params->sta;
+       enum ieee80211_ampdu_mlme_action action = params->action;
+       u16 tid = params->tid;
        struct rt2x00_sta *sta_priv = (struct rt2x00_sta *)sta->drv_priv;
        int ret = 0;
  
@@@ -12,6 -12,9 +12,6 @@@
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
 - * You should have received a copy of the GNU General Public License along
 - * with this program; if not, write to the Free Software Foundation, Inc.,
 - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
   *
   * File: rxtx.c
   *
@@@ -716,7 -719,7 +716,7 @@@ static void vnt_fill_txkey(struct vnt_u
        u16 payload_len, struct vnt_mic_hdr *mic_hdr)
  {
        struct ieee80211_hdr *hdr = tx_context->hdr;
-       struct ieee80211_key_seq seq;
+       u64 pn64;
        u8 *iv = ((u8 *)hdr + ieee80211_get_hdrlen_from_skb(skb));
  
        /* strip header and icv len from payload */
                mic_hdr->payload_len = cpu_to_be16(payload_len);
                ether_addr_copy(mic_hdr->mic_addr2, hdr->addr2);
  
-               ieee80211_get_key_tx_seq(tx_key, &seq);
-               memcpy(mic_hdr->ccmp_pn, seq.ccmp.pn, IEEE80211_CCMP_PN_LEN);
+               pn64 = atomic64_read(&tx_key->tx_pn);
+               mic_hdr->ccmp_pn[5] = pn64;
+               mic_hdr->ccmp_pn[4] = pn64 >> 8;
+               mic_hdr->ccmp_pn[3] = pn64 >> 16;
+               mic_hdr->ccmp_pn[2] = pn64 >> 24;
+               mic_hdr->ccmp_pn[1] = pn64 >> 32;
+               mic_hdr->ccmp_pn[0] = pn64 >> 40;
  
                if (ieee80211_has_a4(hdr->frame_control))
                        mic_hdr->hlen = cpu_to_be16(28);
diff --combined net/mac80211/debugfs.c
@@@ -91,7 -91,7 +91,7 @@@ static const struct file_operations res
  };
  #endif
  
 -static const char *hw_flag_names[NUM_IEEE80211_HW_FLAGS + 1] = {
 +static const char *hw_flag_names[] = {
  #define FLAG(F)       [IEEE80211_HW_##F] = #F
        FLAG(HAS_RATE_CONTROL),
        FLAG(RX_INCLUDES_FCS),
        FLAG(SUPPORTS_AMSDU_IN_AMPDU),
        FLAG(BEACON_TX_STATUS),
        FLAG(NEEDS_UNIQUE_STA_ADDR),
 -
 -      /* keep last for the build bug below */
 -      (void *)0x1
+       FLAG(SUPPORTS_REORDERING_BUFFER),
  #undef FLAG
  };
  
@@@ -145,7 -149,7 +146,7 @@@ static ssize_t hwflags_read(struct fil
        /* fail compilation if somebody adds or removes
         * a flag without updating the name array above
         */
 -      BUILD_BUG_ON(hw_flag_names[NUM_IEEE80211_HW_FLAGS] != (void *)0x1);
 +      BUILD_BUG_ON(ARRAY_SIZE(hw_flag_names) != NUM_IEEE80211_HW_FLAGS);
  
        for (i = 0; i < NUM_IEEE80211_HW_FLAGS; i++) {
                if (test_bit(i, local->hw.flags))
diff --combined net/mac80211/ibss.c
@@@ -7,6 -7,7 +7,7 @@@
   * Copyright 2007, Michael Wu <flamingice@sourmilk.net>
   * Copyright 2009, Johannes Berg <johannes@sipsolutions.net>
   * Copyright 2013-2014  Intel Mobile Communications GmbH
+  * Copyright(c) 2016 Intel Deutschland GmbH
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License version 2 as
@@@ -1050,9 -1051,8 +1051,8 @@@ static void ieee80211_update_sta_info(s
                struct cfg80211_chan_def chandef;
                enum ieee80211_sta_rx_bandwidth bw = sta->sta.bandwidth;
  
-               ieee80211_ht_oper_to_chandef(channel,
-                                            elems->ht_operation,
-                                            &chandef);
+               cfg80211_chandef_create(&chandef, channel, NL80211_CHAN_NO_HT);
+               ieee80211_chandef_ht_oper(elems->ht_operation, &chandef);
  
                memcpy(&htcap_ie, elems->ht_cap_elem, sizeof(htcap_ie));
                rates_updated |= ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
                        struct ieee80211_vht_cap cap_ie;
                        struct ieee80211_sta_vht_cap cap = sta->sta.vht_cap;
  
-                       ieee80211_vht_oper_to_chandef(channel,
-                                                     elems->vht_operation,
-                                                     &chandef);
+                       ieee80211_chandef_vht_oper(elems->vht_operation,
+                                                  &chandef);
                        memcpy(&cap_ie, elems->vht_cap_elem, sizeof(cap_ie));
                        ieee80211_vht_cap_ie_to_sta_vht_cap(sdata, sband,
                                                            &cap_ie, sta);
@@@ -1485,14 -1484,21 +1484,21 @@@ static void ieee80211_sta_find_ibss(str
  
                sdata_info(sdata, "Trigger new scan to find an IBSS to join\n");
  
-               num = ieee80211_ibss_setup_scan_channels(local->hw.wiphy,
-                                                        &ifibss->chandef,
-                                                        channels,
-                                                        ARRAY_SIZE(channels));
                scan_width = cfg80211_chandef_to_scan_width(&ifibss->chandef);
-               ieee80211_request_ibss_scan(sdata, ifibss->ssid,
-                                           ifibss->ssid_len, channels, num,
-                                           scan_width);
+               if (ifibss->fixed_channel) {
+                       num = ieee80211_ibss_setup_scan_channels(local->hw.wiphy,
+                                                                &ifibss->chandef,
+                                                                channels,
+                                                                ARRAY_SIZE(channels));
+                       ieee80211_request_ibss_scan(sdata, ifibss->ssid,
+                                                   ifibss->ssid_len, channels,
+                                                   num, scan_width);
+               } else {
+                       ieee80211_request_ibss_scan(sdata, ifibss->ssid,
+                                                   ifibss->ssid_len, NULL,
+                                                   0, scan_width);
+               }
        } else {
                int interval = IEEE80211_SCAN_INTERVAL;
  
@@@ -1733,6 -1739,7 +1739,6 @@@ void ieee80211_ibss_notify_scan_complet
                if (sdata->vif.type != NL80211_IFTYPE_ADHOC)
                        continue;
                sdata->u.ibss.last_scan_completed = jiffies;
 -              ieee80211_queue_work(&local->hw, &sdata->work);
        }
        mutex_unlock(&local->iflist_mtx);
  }
diff --combined net/mac80211/mesh.c
@@@ -91,11 -91,10 +91,10 @@@ bool mesh_matches_local(struct ieee8021
        if (sdata->vif.bss_conf.basic_rates != basic_rates)
                return false;
  
-       ieee80211_ht_oper_to_chandef(sdata->vif.bss_conf.chandef.chan,
-                                    ie->ht_operation, &sta_chan_def);
-       ieee80211_vht_oper_to_chandef(sdata->vif.bss_conf.chandef.chan,
-                                     ie->vht_operation, &sta_chan_def);
+       cfg80211_chandef_create(&sta_chan_def, sdata->vif.bss_conf.chandef.chan,
+                               NL80211_CHAN_NO_HT);
+       ieee80211_chandef_ht_oper(ie->ht_operation, &sta_chan_def);
+       ieee80211_chandef_vht_oper(ie->vht_operation, &sta_chan_def);
  
        if (!cfg80211_chandef_compatible(&sdata->vif.bss_conf.chandef,
                                         &sta_chan_def))
@@@ -1370,6 -1369,17 +1369,6 @@@ out
        sdata_unlock(sdata);
  }
  
 -void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local)
 -{
 -      struct ieee80211_sub_if_data *sdata;
 -
 -      rcu_read_lock();
 -      list_for_each_entry_rcu(sdata, &local->interfaces, list)
 -              if (ieee80211_vif_is_mesh(&sdata->vif) &&
 -                  ieee80211_sdata_running(sdata))
 -                      ieee80211_queue_work(&local->hw, &sdata->work);
 -      rcu_read_unlock();
 -}
  
  void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata)
  {
diff --combined net/mac80211/mesh.h
@@@ -137,8 -137,6 +137,6 @@@ struct mesh_path 
   * @copy_node: function to copy nodes of the table
   * @size_order: determines size of the table, there will be 2^size_order hash
   *    buckets
-  * @mean_chain_len: maximum average length for the hash buckets' list, if it is
-  *    reached, the table will grow
   * @known_gates: list of known mesh gates and their mpaths by the station. The
   * gate's mpath may or may not be resolved and active.
   *
@@@ -154,7 -152,6 +152,6 @@@ struct mesh_table 
        void (*free_node) (struct hlist_node *p, bool free_leafs);
        int (*copy_node) (struct hlist_node *p, struct mesh_table *newtbl);
        int size_order;
-       int mean_chain_len;
        struct hlist_head *known_gates;
        spinlock_t gates_lock;
  
@@@ -362,10 -359,14 +359,10 @@@ static inline bool mesh_path_sel_is_hwm
        return sdata->u.mesh.mesh_pp_id == IEEE80211_PATH_PROTOCOL_HWMP;
  }
  
 -void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local);
 -
  void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata);
  void mesh_sync_adjust_tbtt(struct ieee80211_sub_if_data *sdata);
  void ieee80211s_stop(void);
  #else
 -static inline void
 -ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local) {}
  static inline bool mesh_path_sel_is_hwmp(struct ieee80211_sub_if_data *sdata)
  { return false; }
  static inline void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata)
diff --combined net/mac80211/mlme.c
@@@ -6,7 -6,7 +6,7 @@@
   * Copyright 2006-2007        Jiri Benc <jbenc@suse.cz>
   * Copyright 2007, Michael Wu <flamingice@sourmilk.net>
   * Copyright 2013-2014  Intel Mobile Communications GmbH
-  * Copyright (C) 2015 Intel Deutschland GmbH
+  * Copyright (C) 2015 - 2016 Intel Deutschland GmbH
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License version 2 as
@@@ -196,16 -196,7 +196,7 @@@ ieee80211_determine_chantype(struct iee
  
        /* check 40 MHz support, if we have it */
        if (sta_ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) {
-               switch (ht_oper->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
-               case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
-                       chandef->width = NL80211_CHAN_WIDTH_40;
-                       chandef->center_freq1 += 10;
-                       break;
-               case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
-                       chandef->width = NL80211_CHAN_WIDTH_40;
-                       chandef->center_freq1 -= 10;
-                       break;
-               }
+               ieee80211_chandef_ht_oper(ht_oper, chandef);
        } else {
                /* 40 MHz (and 80 MHz) must be supported for VHT */
                ret = IEEE80211_STA_DISABLE_VHT;
                goto out;
        }
  
-       vht_chandef.chan = channel;
-       vht_chandef.center_freq1 =
-               ieee80211_channel_to_frequency(vht_oper->center_freq_seg1_idx,
-                                              channel->band);
-       vht_chandef.center_freq2 = 0;
-       switch (vht_oper->chan_width) {
-       case IEEE80211_VHT_CHANWIDTH_USE_HT:
-               vht_chandef.width = chandef->width;
-               vht_chandef.center_freq1 = chandef->center_freq1;
-               break;
-       case IEEE80211_VHT_CHANWIDTH_80MHZ:
-               vht_chandef.width = NL80211_CHAN_WIDTH_80;
-               break;
-       case IEEE80211_VHT_CHANWIDTH_160MHZ:
-               vht_chandef.width = NL80211_CHAN_WIDTH_160;
-               break;
-       case IEEE80211_VHT_CHANWIDTH_80P80MHZ:
-               vht_chandef.width = NL80211_CHAN_WIDTH_80P80;
-               vht_chandef.center_freq2 =
-                       ieee80211_channel_to_frequency(
-                               vht_oper->center_freq_seg2_idx,
-                               channel->band);
-               break;
-       default:
+       vht_chandef = *chandef;
+       if (!ieee80211_chandef_vht_oper(vht_oper, &vht_chandef)) {
                if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT))
                        sdata_info(sdata,
-                                  "AP VHT operation IE has invalid channel width (%d), disable VHT\n",
-                                  vht_oper->chan_width);
+                                  "AP VHT information is invalid, disable VHT\n");
                ret = IEEE80211_STA_DISABLE_VHT;
                goto out;
        }
@@@ -592,7 -559,7 +559,7 @@@ static void ieee80211_add_vht_ie(struc
                struct ieee80211_sub_if_data *other;
  
                list_for_each_entry_rcu(other, &local->interfaces, list) {
-                       if (other->flags & IEEE80211_SDATA_MU_MIMO_OWNER) {
+                       if (other->vif.mu_mimo_owner) {
                                disable_mu_mimo = true;
                                break;
                        }
                if (disable_mu_mimo)
                        cap &= ~IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;
                else
-                       sdata->flags |= IEEE80211_SDATA_MU_MIMO_OWNER;
+                       sdata->vif.mu_mimo_owner = true;
        }
  
        mask = IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;
@@@ -1638,8 -1605,7 +1605,7 @@@ void ieee80211_dynamic_ps_timer(unsigne
  
  void ieee80211_dfs_cac_timer_work(struct work_struct *work)
  {
-       struct delayed_work *delayed_work =
-               container_of(work, struct delayed_work, work);
+       struct delayed_work *delayed_work = to_delayed_work(work);
        struct ieee80211_sub_if_data *sdata =
                container_of(delayed_work, struct ieee80211_sub_if_data,
                             dfs_cac_timer_work);
@@@ -2079,7 -2045,14 +2045,14 @@@ static void ieee80211_set_disassoc(stru
        memset(&ifmgd->ht_capa_mask, 0, sizeof(ifmgd->ht_capa_mask));
        memset(&ifmgd->vht_capa, 0, sizeof(ifmgd->vht_capa));
        memset(&ifmgd->vht_capa_mask, 0, sizeof(ifmgd->vht_capa_mask));
-       sdata->flags &= ~IEEE80211_SDATA_MU_MIMO_OWNER;
+       /* reset MU-MIMO ownership and group data */
+       memset(sdata->vif.bss_conf.mu_group.membership, 0,
+              sizeof(sdata->vif.bss_conf.mu_group.membership));
+       memset(sdata->vif.bss_conf.mu_group.position, 0,
+              sizeof(sdata->vif.bss_conf.mu_group.position));
+       changed |= BSS_CHANGED_MU_GROUPS;
+       sdata->vif.mu_mimo_owner = false;
  
        sdata->ap_power_level = IEEE80211_UNSET_POWER_LEVEL;
  
@@@ -2536,7 -2509,8 +2509,8 @@@ static void ieee80211_destroy_assoc_dat
                eth_zero_addr(sdata->u.mgd.bssid);
                ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID);
                sdata->u.mgd.flags = 0;
-               sdata->flags &= ~IEEE80211_SDATA_MU_MIMO_OWNER;
+               sdata->vif.mu_mimo_owner = false;
                mutex_lock(&sdata->local->mtx);
                ieee80211_vif_release_channel(sdata);
                mutex_unlock(&sdata->local->mtx);
@@@ -3571,6 -3545,9 +3545,9 @@@ static void ieee80211_rx_mgmt_beacon(st
                                elems.ht_cap_elem, elems.ht_operation,
                                elems.vht_operation, bssid, &changed)) {
                mutex_unlock(&local->sta_mtx);
+               sdata_info(sdata,
+                          "failed to follow AP %pM bandwidth change, disconnect\n",
+                          bssid);
                ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
                                       WLAN_REASON_DEAUTH_LEAVING,
                                       true, deauth_buf);
@@@ -3946,11 -3923,9 +3923,9 @@@ void ieee80211_sta_work(struct ieee8021
                         * We actually lost the connection ... or did we?
                         * Let's make sure!
                         */
-                       wiphy_debug(local->hw.wiphy,
-                                   "%s: No probe response from AP %pM"
-                                   " after %dms, disconnecting.\n",
-                                   sdata->name,
-                                   bssid, probe_wait_ms);
+                       mlme_dbg(sdata,
+                                "No probe response from AP %pM after %dms, disconnecting.\n",
+                                bssid, probe_wait_ms);
  
                        ieee80211_sta_connection_lost(sdata, bssid,
                                WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY, false);
@@@ -4005,6 -3980,8 +3980,6 @@@ static void ieee80211_restart_sta_timer
                if (!ieee80211_hw_check(&sdata->local->hw, CONNECTION_MONITOR))
                        ieee80211_queue_work(&sdata->local->hw,
                                             &sdata->u.mgd.monitor_work);
 -              /* and do all the other regular work too */
 -              ieee80211_queue_work(&sdata->local->hw, &sdata->work);
        }
  }
  
@@@ -4536,6 -4513,9 +4511,9 @@@ int ieee80211_mgd_auth(struct ieee80211
        if (ifmgd->associated) {
                u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
  
+               sdata_info(sdata,
+                          "disconnect from AP %pM for new auth to %pM\n",
+                          ifmgd->associated->bssid, req->bss->bssid);
                ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
                                       WLAN_REASON_UNSPECIFIED,
                                       false, frame_buf);
@@@ -4604,6 -4584,9 +4582,9 @@@ int ieee80211_mgd_assoc(struct ieee8021
        if (ifmgd->associated) {
                u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
  
+               sdata_info(sdata,
+                          "disconnect from AP %pM for new assoc to %pM\n",
+                          ifmgd->associated->bssid, req->bss->bssid);
                ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
                                       WLAN_REASON_UNSPECIFIED,
                                       false, frame_buf);
diff --combined net/mac80211/sta_info.c
@@@ -116,6 -116,7 +116,7 @@@ static void __cleanup_single_sta(struc
  
                        ieee80211_purge_tx_queue(&local->hw, &txqi->queue);
                        atomic_sub(n, &sdata->txqs_len[txqi->txq.ac]);
+                       txqi->byte_cnt = 0;
                }
        }
  
@@@ -498,11 -499,17 +499,17 @@@ static int sta_info_insert_finish(struc
  {
        struct ieee80211_local *local = sta->local;
        struct ieee80211_sub_if_data *sdata = sta->sdata;
-       struct station_info sinfo;
+       struct station_info *sinfo;
        int err = 0;
  
        lockdep_assert_held(&local->sta_mtx);
  
+       sinfo = kzalloc(sizeof(struct station_info), GFP_KERNEL);
+       if (!sinfo) {
+               err = -ENOMEM;
+               goto out_err;
+       }
        /* check if STA exists already */
        if (sta_info_get_bss(sdata, sta->sta.addr)) {
                err = -EEXIST;
        /* accept BA sessions now */
        clear_sta_flag(sta, WLAN_STA_BLOCK_BA);
  
-       ieee80211_recalc_min_chandef(sdata);
        ieee80211_sta_debugfs_add(sta);
        rate_control_add_sta_debugfs(sta);
  
-       memset(&sinfo, 0, sizeof(sinfo));
-       sinfo.filled = 0;
-       sinfo.generation = local->sta_generation;
-       cfg80211_new_sta(sdata->dev, sta->sta.addr, &sinfo, GFP_KERNEL);
+       sinfo->generation = local->sta_generation;
+       cfg80211_new_sta(sdata->dev, sta->sta.addr, sinfo, GFP_KERNEL);
+       kfree(sinfo);
  
        sta_dbg(sdata, "Inserted STA %pM\n", sta->sta.addr);
  
        __cleanup_single_sta(sta);
   out_err:
        mutex_unlock(&local->sta_mtx);
+       kfree(sinfo);
        rcu_read_lock();
        return err;
  }
@@@ -898,7 -904,7 +904,7 @@@ static void __sta_info_destroy_part2(st
  {
        struct ieee80211_local *local = sta->local;
        struct ieee80211_sub_if_data *sdata = sta->sdata;
-       struct station_info sinfo = {};
+       struct station_info *sinfo;
        int ret;
  
        /*
  
        sta_dbg(sdata, "Removed STA %pM\n", sta->sta.addr);
  
-       sta_set_sinfo(sta, &sinfo);
-       cfg80211_del_sta_sinfo(sdata->dev, sta->sta.addr, &sinfo, GFP_KERNEL);
+       sinfo = kzalloc(sizeof(*sinfo), GFP_KERNEL);
+       if (sinfo)
+               sta_set_sinfo(sta, sinfo);
+       cfg80211_del_sta_sinfo(sdata->dev, sta->sta.addr, sinfo, GFP_KERNEL);
+       kfree(sinfo);
  
        rate_control_remove_sta_debugfs(sta);
        ieee80211_sta_debugfs_remove(sta);
-       ieee80211_recalc_min_chandef(sdata);
  
        cleanup_single_sta(sta);
  }
@@@ -1453,7 -1461,7 +1461,7 @@@ ieee80211_sta_ps_deliver_response(struc
  
        more_data = ieee80211_sta_ps_more_data(sta, ignored_acs, reason, driver_release_tids);
  
 -      if (reason == IEEE80211_FRAME_RELEASE_PSPOLL)
 +      if (driver_release_tids && reason == IEEE80211_FRAME_RELEASE_PSPOLL)
                driver_release_tids =
                        BIT(find_highest_prio_tid(driver_release_tids));
  
@@@ -1808,14 -1816,17 +1816,17 @@@ int sta_info_move_state(struct sta_inf
                        clear_bit(WLAN_STA_AUTH, &sta->_flags);
                break;
        case IEEE80211_STA_AUTH:
-               if (sta->sta_state == IEEE80211_STA_NONE)
+               if (sta->sta_state == IEEE80211_STA_NONE) {
                        set_bit(WLAN_STA_AUTH, &sta->_flags);
-               else if (sta->sta_state == IEEE80211_STA_ASSOC)
+               } else if (sta->sta_state == IEEE80211_STA_ASSOC) {
                        clear_bit(WLAN_STA_ASSOC, &sta->_flags);
+                       ieee80211_recalc_min_chandef(sta->sdata);
+               }
                break;
        case IEEE80211_STA_ASSOC:
                if (sta->sta_state == IEEE80211_STA_AUTH) {
                        set_bit(WLAN_STA_ASSOC, &sta->_flags);
+                       ieee80211_recalc_min_chandef(sta->sdata);
                } else if (sta->sta_state == IEEE80211_STA_AUTHORIZED) {
                        if (sta->sdata->vif.type == NL80211_IFTYPE_AP ||
                            (sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN &&
diff --combined net/mac80211/util.c
@@@ -4,7 -4,7 +4,7 @@@
   * Copyright 2006-2007        Jiri Benc <jbenc@suse.cz>
   * Copyright 2007     Johannes Berg <johannes@sipsolutions.net>
   * Copyright 2013-2014  Intel Mobile Communications GmbH
-  * Copyright (C) 2015 Intel Deutschland GmbH
+  * Copyright (C) 2015-2016    Intel Deutschland GmbH
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License version 2 as
@@@ -1928,6 -1928,9 +1928,9 @@@ int ieee80211_reconfig(struct ieee80211
                          BSS_CHANGED_IDLE |
                          BSS_CHANGED_TXPOWER;
  
+               if (sdata->vif.mu_mimo_owner)
+                       changed |= BSS_CHANGED_MU_GROUPS;
                switch (sdata->vif.type) {
                case NL80211_IFTYPE_STATION:
                        changed |= BSS_CHANGED_ASSOC |
                 */
                if (sched_scan_req->n_scan_plans > 1 ||
                    __ieee80211_request_sched_scan_start(sched_scan_sdata,
 -                                                       sched_scan_req))
 +                                                       sched_scan_req)) {
 +                      RCU_INIT_POINTER(local->sched_scan_sdata, NULL);
 +                      RCU_INIT_POINTER(local->sched_scan_req, NULL);
                        sched_scan_stopped = true;
 +              }
        mutex_unlock(&local->mtx);
  
        if (sched_scan_stopped)
                cfg80211_sched_scan_stopped_rtnl(local->hw.wiphy);
  
   wake_up:
 -      local->in_reconfig = false;
 -      barrier();
 +      if (local->in_reconfig) {
 +              local->in_reconfig = false;
 +              barrier();
 +
 +              /* Restart deferred ROCs */
 +              mutex_lock(&local->mtx);
 +              ieee80211_start_next_roc(local);
 +              mutex_unlock(&local->mtx);
 +      }
  
        if (local->monitors == local->open_count && local->monitors > 0)
                ieee80211_add_virtual_monitor(local);
@@@ -2371,10 -2364,23 +2374,23 @@@ u8 *ieee80211_ie_build_vht_oper(u8 *pos
  
        switch (chandef->width) {
        case NL80211_CHAN_WIDTH_160:
-               vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_160MHZ;
+               /*
+                * Convert 160 MHz channel width to new style as interop
+                * workaround.
+                */
+               vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_80MHZ;
+               vht_oper->center_freq_seg2_idx = vht_oper->center_freq_seg1_idx;
+               if (chandef->chan->center_freq < chandef->center_freq1)
+                       vht_oper->center_freq_seg1_idx -= 8;
+               else
+                       vht_oper->center_freq_seg1_idx += 8;
                break;
        case NL80211_CHAN_WIDTH_80P80:
-               vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_80P80MHZ;
+               /*
+                * Convert 80+80 MHz channel width to new style as interop
+                * workaround.
+                */
+               vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_80MHZ;
                break;
        case NL80211_CHAN_WIDTH_80:
                vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_80MHZ;
        return pos + sizeof(struct ieee80211_vht_operation);
  }
  
- void ieee80211_ht_oper_to_chandef(struct ieee80211_channel *control_chan,
-                                 const struct ieee80211_ht_operation *ht_oper,
-                                 struct cfg80211_chan_def *chandef)
+ bool ieee80211_chandef_ht_oper(const struct ieee80211_ht_operation *ht_oper,
+                              struct cfg80211_chan_def *chandef)
  {
        enum nl80211_channel_type channel_type;
  
-       if (!ht_oper) {
-               cfg80211_chandef_create(chandef, control_chan,
-                                       NL80211_CHAN_NO_HT);
-               return;
-       }
+       if (!ht_oper)
+               return false;
  
        switch (ht_oper->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
        case IEEE80211_HT_PARAM_CHA_SEC_NONE:
                break;
        default:
                channel_type = NL80211_CHAN_NO_HT;
+               return false;
        }
  
-       cfg80211_chandef_create(chandef, control_chan, channel_type);
+       cfg80211_chandef_create(chandef, chandef->chan, channel_type);
+       return true;
  }
  
- void ieee80211_vht_oper_to_chandef(struct ieee80211_channel *control_chan,
-                                  const struct ieee80211_vht_operation *oper,
-                                  struct cfg80211_chan_def *chandef)
+ bool ieee80211_chandef_vht_oper(const struct ieee80211_vht_operation *oper,
+                               struct cfg80211_chan_def *chandef)
  {
+       struct cfg80211_chan_def new = *chandef;
+       int cf1, cf2;
        if (!oper)
-               return;
+               return false;
  
-       chandef->chan = control_chan;
+       cf1 = ieee80211_channel_to_frequency(oper->center_freq_seg1_idx,
+                                            chandef->chan->band);
+       cf2 = ieee80211_channel_to_frequency(oper->center_freq_seg2_idx,
+                                            chandef->chan->band);
  
        switch (oper->chan_width) {
        case IEEE80211_VHT_CHANWIDTH_USE_HT:
                break;
        case IEEE80211_VHT_CHANWIDTH_80MHZ:
-               chandef->width = NL80211_CHAN_WIDTH_80;
+               new.width = NL80211_CHAN_WIDTH_80;
+               new.center_freq1 = cf1;
+               /* If needed, adjust based on the newer interop workaround. */
+               if (oper->center_freq_seg2_idx) {
+                       unsigned int diff;
+                       diff = abs(oper->center_freq_seg2_idx -
+                                  oper->center_freq_seg1_idx);
+                       if (diff == 8) {
+                               new.width = NL80211_CHAN_WIDTH_160;
+                               new.center_freq1 = cf2;
+                       } else if (diff > 8) {
+                               new.width = NL80211_CHAN_WIDTH_80P80;
+                               new.center_freq2 = cf2;
+                       }
+               }
                break;
        case IEEE80211_VHT_CHANWIDTH_160MHZ:
-               chandef->width = NL80211_CHAN_WIDTH_160;
+               new.width = NL80211_CHAN_WIDTH_160;
+               new.center_freq1 = cf1;
                break;
        case IEEE80211_VHT_CHANWIDTH_80P80MHZ:
-               chandef->width = NL80211_CHAN_WIDTH_80P80;
+               new.width = NL80211_CHAN_WIDTH_80P80;
+               new.center_freq1 = cf1;
+               new.center_freq2 = cf2;
                break;
        default:
-               break;
+               return false;
        }
  
-       chandef->center_freq1 =
-               ieee80211_channel_to_frequency(oper->center_freq_seg1_idx,
-                                              control_chan->band);
-       chandef->center_freq2 =
-               ieee80211_channel_to_frequency(oper->center_freq_seg2_idx,
-                                              control_chan->band);
+       if (!cfg80211_chandef_valid(&new))
+               return false;
+       *chandef = new;
+       return true;
  }
  
  int ieee80211_parse_bitrates(struct cfg80211_chan_def *chandef,
@@@ -2672,6 -2698,18 +2708,18 @@@ u64 ieee80211_calculate_rx_timestamp(st
                sband = local->hw.wiphy->bands[status->band];
                bitrate = sband->bitrates[status->rate_idx].bitrate;
                ri.legacy = DIV_ROUND_UP(bitrate, (1 << shift));
+               if (status->flag & RX_FLAG_MACTIME_PLCP_START) {
+                       /* TODO: handle HT/VHT preambles */
+                       if (status->band == IEEE80211_BAND_5GHZ) {
+                               ts += 20 << shift;
+                               mpdu_offset += 2;
+                       } else if (status->flag & RX_FLAG_SHORTPRE) {
+                               ts += 96;
+                       } else {
+                               ts += 192;
+                       }
+               }
        }
  
        rate = cfg80211_calculate_bitrate(&ri);
@@@ -3357,3 -3395,17 +3405,17 @@@ void ieee80211_init_tx_queue(struct iee
                txqi->txq.ac = IEEE80211_AC_BE;
        }
  }
+ void ieee80211_txq_get_depth(struct ieee80211_txq *txq,
+                            unsigned long *frame_cnt,
+                            unsigned long *byte_cnt)
+ {
+       struct txq_info *txqi = to_txq_info(txq);
+       if (frame_cnt)
+               *frame_cnt = txqi->queue.qlen;
+       if (byte_cnt)
+               *byte_cnt = txqi->byte_cnt;
+ }
+ EXPORT_SYMBOL(ieee80211_txq_get_depth);
diff --combined net/rfkill/core.c
@@@ -57,6 -57,8 +57,8 @@@ struct rfkill 
  
        bool                    registered;
        bool                    persistent;
+       bool                    polling_paused;
+       bool                    suspended;
  
        const struct rfkill_ops *ops;
        void                    *data;
@@@ -233,29 -235,6 +235,6 @@@ static void rfkill_event(struct rfkill 
        rfkill_send_events(rfkill, RFKILL_OP_CHANGE);
  }
  
- static bool __rfkill_set_hw_state(struct rfkill *rfkill,
-                                 bool blocked, bool *change)
- {
-       unsigned long flags;
-       bool prev, any;
-       BUG_ON(!rfkill);
-       spin_lock_irqsave(&rfkill->lock, flags);
-       prev = !!(rfkill->state & RFKILL_BLOCK_HW);
-       if (blocked)
-               rfkill->state |= RFKILL_BLOCK_HW;
-       else
-               rfkill->state &= ~RFKILL_BLOCK_HW;
-       *change = prev != blocked;
-       any = !!(rfkill->state & RFKILL_BLOCK_ANY);
-       spin_unlock_irqrestore(&rfkill->lock, flags);
-       rfkill_led_trigger_event(rfkill);
-       return any;
- }
  /**
   * rfkill_set_block - wrapper for set_block method
   *
@@@ -285,7 -264,7 +264,7 @@@ static void rfkill_set_block(struct rfk
        spin_lock_irqsave(&rfkill->lock, flags);
        prev = rfkill->state & RFKILL_BLOCK_SW;
  
-       if (rfkill->state & RFKILL_BLOCK_SW)
+       if (prev)
                rfkill->state |= RFKILL_BLOCK_SW_PREV;
        else
                rfkill->state &= ~RFKILL_BLOCK_SW_PREV;
        spin_lock_irqsave(&rfkill->lock, flags);
        if (err) {
                /*
-                * Failed -- reset status to _prev, this may be different
-                * from what set set _PREV to earlier in this function
+                * Failed -- reset status to _PREV, which may be different
+                * from what we have set _PREV to earlier in this function
                 * if rfkill_set_sw_state was invoked.
                 */
                if (rfkill->state & RFKILL_BLOCK_SW_PREV)
                rfkill_event(rfkill);
  }
  
+ static void rfkill_update_global_state(enum rfkill_type type, bool blocked)
+ {
+       int i;
+       if (type != RFKILL_TYPE_ALL) {
+               rfkill_global_states[type].cur = blocked;
+               return;
+       }
+       for (i = 0; i < NUM_RFKILL_TYPES; i++)
+               rfkill_global_states[i].cur = blocked;
+ }
  #ifdef CONFIG_RFKILL_INPUT
  static atomic_t rfkill_input_disabled = ATOMIC_INIT(0);
  
   * @blocked: the new state
   *
   * This function sets the state of all switches of given type,
-  * unless a specific switch is claimed by userspace (in which case,
-  * that switch is left alone) or suspended.
+  * unless a specific switch is suspended.
   *
   * Caller must have acquired rfkill_global_mutex.
   */
@@@ -341,15 -332,7 +332,7 @@@ static void __rfkill_switch_all(const e
  {
        struct rfkill *rfkill;
  
-       if (type == RFKILL_TYPE_ALL) {
-               int i;
-               for (i = 0; i < NUM_RFKILL_TYPES; i++)
-                       rfkill_global_states[i].cur = blocked;
-       } else {
-               rfkill_global_states[type].cur = blocked;
-       }
+       rfkill_update_global_state(type, blocked);
        list_for_each_entry(rfkill, &rfkill_list, node) {
                if (rfkill->type != type && type != RFKILL_TYPE_ALL)
                        continue;
@@@ -477,17 -460,28 +460,28 @@@ bool rfkill_get_global_sw_state(const e
  }
  #endif
  
  bool rfkill_set_hw_state(struct rfkill *rfkill, bool blocked)
  {
-       bool ret, change;
+       unsigned long flags;
+       bool ret, prev;
+       BUG_ON(!rfkill);
  
-       ret = __rfkill_set_hw_state(rfkill, blocked, &change);
+       spin_lock_irqsave(&rfkill->lock, flags);
+       prev = !!(rfkill->state & RFKILL_BLOCK_HW);
+       if (blocked)
+               rfkill->state |= RFKILL_BLOCK_HW;
+       else
+               rfkill->state &= ~RFKILL_BLOCK_HW;
+       ret = !!(rfkill->state & RFKILL_BLOCK_ANY);
+       spin_unlock_irqrestore(&rfkill->lock, flags);
+       rfkill_led_trigger_event(rfkill);
  
        if (!rfkill->registered)
                return ret;
  
-       if (change)
+       if (prev != blocked)
                schedule_work(&rfkill->uevent_work);
  
        return ret;
@@@ -582,6 -576,34 +576,34 @@@ void rfkill_set_states(struct rfkill *r
  }
  EXPORT_SYMBOL(rfkill_set_states);
  
+ static const char * const rfkill_types[] = {
+       NULL, /* RFKILL_TYPE_ALL */
+       "wlan",
+       "bluetooth",
+       "ultrawideband",
+       "wimax",
+       "wwan",
+       "gps",
+       "fm",
+       "nfc",
+ };
+ enum rfkill_type rfkill_find_type(const char *name)
+ {
+       int i;
+       BUILD_BUG_ON(ARRAY_SIZE(rfkill_types) != NUM_RFKILL_TYPES);
+       if (!name)
+               return RFKILL_TYPE_ALL;
+       for (i = 1; i < NUM_RFKILL_TYPES; i++)
+               if (!strcmp(name, rfkill_types[i]))
+                       return i;
+       return RFKILL_TYPE_ALL;
+ }
+ EXPORT_SYMBOL(rfkill_find_type);
  static ssize_t name_show(struct device *dev, struct device_attribute *attr,
                         char *buf)
  {
  }
  static DEVICE_ATTR_RO(name);
  
- static const char *rfkill_get_type_str(enum rfkill_type type)
- {
-       BUILD_BUG_ON(NUM_RFKILL_TYPES != RFKILL_TYPE_NFC + 1);
-       switch (type) {
-       case RFKILL_TYPE_WLAN:
-               return "wlan";
-       case RFKILL_TYPE_BLUETOOTH:
-               return "bluetooth";
-       case RFKILL_TYPE_UWB:
-               return "ultrawideband";
-       case RFKILL_TYPE_WIMAX:
-               return "wimax";
-       case RFKILL_TYPE_WWAN:
-               return "wwan";
-       case RFKILL_TYPE_GPS:
-               return "gps";
-       case RFKILL_TYPE_FM:
-               return "fm";
-       case RFKILL_TYPE_NFC:
-               return "nfc";
-       default:
-               BUG();
-       }
- }
  static ssize_t type_show(struct device *dev, struct device_attribute *attr,
                         char *buf)
  {
        struct rfkill *rfkill = to_rfkill(dev);
  
-       return sprintf(buf, "%s\n", rfkill_get_type_str(rfkill->type));
+       return sprintf(buf, "%s\n", rfkill_types[rfkill->type]);
  }
  static DEVICE_ATTR_RO(type);
  
@@@ -730,20 -726,12 +726,12 @@@ static ssize_t state_store(struct devic
  }
  static DEVICE_ATTR_RW(state);
  
- static ssize_t claim_show(struct device *dev, struct device_attribute *attr,
-                         char *buf)
- {
-       return sprintf(buf, "%d\n", 0);
- }
- static DEVICE_ATTR_RO(claim);
  static struct attribute *rfkill_dev_attrs[] = {
        &dev_attr_name.attr,
        &dev_attr_type.attr,
        &dev_attr_index.attr,
        &dev_attr_persistent.attr,
        &dev_attr_state.attr,
-       &dev_attr_claim.attr,
        &dev_attr_soft.attr,
        &dev_attr_hard.attr,
        NULL,
@@@ -768,7 -756,7 +756,7 @@@ static int rfkill_dev_uevent(struct dev
        if (error)
                return error;
        error = add_uevent_var(env, "RFKILL_TYPE=%s",
-                              rfkill_get_type_str(rfkill->type));
+                              rfkill_types[rfkill->type]);
        if (error)
                return error;
        spin_lock_irqsave(&rfkill->lock, flags);
@@@ -786,6 -774,7 +774,7 @@@ void rfkill_pause_polling(struct rfkil
        if (!rfkill->ops->poll)
                return;
  
+       rfkill->polling_paused = true;
        cancel_delayed_work_sync(&rfkill->poll_work);
  }
  EXPORT_SYMBOL(rfkill_pause_polling);
@@@ -797,6 -786,11 +786,11 @@@ void rfkill_resume_polling(struct rfkil
        if (!rfkill->ops->poll)
                return;
  
+       rfkill->polling_paused = false;
+       if (rfkill->suspended)
+               return;
        queue_delayed_work(system_power_efficient_wq,
                           &rfkill->poll_work, 0);
  }
@@@ -807,7 -801,8 +801,8 @@@ static int rfkill_suspend(struct devic
  {
        struct rfkill *rfkill = to_rfkill(dev);
  
-       rfkill_pause_polling(rfkill);
+       rfkill->suspended = true;
+       cancel_delayed_work_sync(&rfkill->poll_work);
  
        return 0;
  }
@@@ -817,12 -812,16 +812,16 @@@ static int rfkill_resume(struct device 
        struct rfkill *rfkill = to_rfkill(dev);
        bool cur;
  
+       rfkill->suspended = false;
        if (!rfkill->persistent) {
                cur = !!(rfkill->state & RFKILL_BLOCK_SW);
                rfkill_set_block(rfkill, cur);
        }
  
-       rfkill_resume_polling(rfkill);
+       if (rfkill->ops->poll && !rfkill->polling_paused)
+               queue_delayed_work(system_power_efficient_wq,
+                                  &rfkill->poll_work, 0);
  
        return 0;
  }
@@@ -1095,6 -1094,17 +1094,6 @@@ static unsigned int rfkill_fop_poll(str
        return res;
  }
  
 -static bool rfkill_readable(struct rfkill_data *data)
 -{
 -      bool r;
 -
 -      mutex_lock(&data->mtx);
 -      r = !list_empty(&data->events);
 -      mutex_unlock(&data->mtx);
 -
 -      return r;
 -}
 -
  static ssize_t rfkill_fop_read(struct file *file, char __user *buf,
                               size_t count, loff_t *pos)
  {
                        goto out;
                }
                mutex_unlock(&data->mtx);
 +              /* since we re-check and it just compares pointers,
 +               * using !list_empty() without locking isn't a problem
 +               */
                ret = wait_event_interruptible(data->read_wait,
 -                                             rfkill_readable(data));
 +                                             !list_empty(&data->events));
                mutex_lock(&data->mtx);
  
                if (ret)
@@@ -1164,15 -1171,8 +1163,8 @@@ static ssize_t rfkill_fop_write(struct 
  
        mutex_lock(&rfkill_global_mutex);
  
-       if (ev.op == RFKILL_OP_CHANGE_ALL) {
-               if (ev.type == RFKILL_TYPE_ALL) {
-                       enum rfkill_type i;
-                       for (i = 0; i < NUM_RFKILL_TYPES; i++)
-                               rfkill_global_states[i].cur = ev.soft;
-               } else {
-                       rfkill_global_states[ev.type].cur = ev.soft;
-               }
-       }
+       if (ev.op == RFKILL_OP_CHANGE_ALL)
+               rfkill_update_global_state(ev.type, ev.soft);
  
        list_for_each_entry(rfkill, &rfkill_list, node) {
                if (rfkill->idx != ev.idx && ev.op != RFKILL_OP_CHANGE_ALL)
@@@ -1261,10 -1261,8 +1253,8 @@@ static struct miscdevice rfkill_miscde
  static int __init rfkill_init(void)
  {
        int error;
-       int i;
  
-       for (i = 0; i < NUM_RFKILL_TYPES; i++)
-               rfkill_global_states[i].cur = !rfkill_default_state;
+       rfkill_update_global_state(RFKILL_TYPE_ALL, !rfkill_default_state);
  
        error = class_register(&rfkill_class);
        if (error)
diff --combined net/wireless/reg.c
  #include "regdb.h"
  #include "nl80211.h"
  
- #ifdef CONFIG_CFG80211_REG_DEBUG
- #define REG_DBG_PRINT(format, args...)                        \
-       printk(KERN_DEBUG pr_fmt(format), ##args)
- #else
- #define REG_DBG_PRINT(args...)
- #endif
  /*
   * Grace period we give before making sure all current interfaces reside on
   * channels allowed by the current regulatory domain.
@@@ -178,12 -171,10 +171,10 @@@ enum nl80211_dfs_regions reg_get_dfs_re
        if (wiphy_regd->dfs_region == regd->dfs_region)
                goto out;
  
-       REG_DBG_PRINT("%s: device specific dfs_region "
-                     "(%s) disagrees with cfg80211's "
-                     "central dfs_region (%s)\n",
-                     dev_name(&wiphy->dev),
-                     reg_dfs_region_str(wiphy_regd->dfs_region),
-                     reg_dfs_region_str(regd->dfs_region));
+       pr_debug("%s: device specific dfs_region (%s) disagrees with cfg80211's central dfs_region (%s)\n",
+                dev_name(&wiphy->dev),
+                reg_dfs_region_str(wiphy_regd->dfs_region),
+                reg_dfs_region_str(regd->dfs_region));
  
  out:
        return regd->dfs_region;
@@@ -231,22 -222,20 +222,22 @@@ static const struct ieee80211_regdomai
                /* IEEE 802.11b/g, channels 1..11 */
                REG_RULE(2412-10, 2462+10, 40, 6, 20, 0),
                /* IEEE 802.11b/g, channels 12..13. */
 -              REG_RULE(2467-10, 2472+10, 40, 6, 20,
 -                      NL80211_RRF_NO_IR),
 +              REG_RULE(2467-10, 2472+10, 20, 6, 20,
 +                      NL80211_RRF_NO_IR | NL80211_RRF_AUTO_BW),
                /* IEEE 802.11 channel 14 - Only JP enables
                 * this and for 802.11b only */
                REG_RULE(2484-10, 2484+10, 20, 6, 20,
                        NL80211_RRF_NO_IR |
                        NL80211_RRF_NO_OFDM),
                /* IEEE 802.11a, channel 36..48 */
 -              REG_RULE(5180-10, 5240+10, 160, 6, 20,
 -                        NL80211_RRF_NO_IR),
 +              REG_RULE(5180-10, 5240+10, 80, 6, 20,
 +                        NL80211_RRF_NO_IR |
 +                        NL80211_RRF_AUTO_BW),
  
                /* IEEE 802.11a, channel 52..64 - DFS required */
 -              REG_RULE(5260-10, 5320+10, 160, 6, 20,
 +              REG_RULE(5260-10, 5320+10, 80, 6, 20,
                        NL80211_RRF_NO_IR |
 +                      NL80211_RRF_AUTO_BW |
                        NL80211_RRF_DFS),
  
                /* IEEE 802.11a, channel 100..144 - DFS required */
@@@ -543,7 -532,7 +534,7 @@@ static DECLARE_DELAYED_WORK(crda_timeou
  
  static void crda_timeout_work(struct work_struct *work)
  {
-       REG_DBG_PRINT("Timeout while waiting for CRDA to reply, restoring regulatory settings\n");
+       pr_debug("Timeout while waiting for CRDA to reply, restoring regulatory settings\n");
        rtnl_lock();
        reg_crda_timeouts++;
        restore_regulatory_settings(true);
@@@ -585,7 -574,7 +576,7 @@@ static int call_crda(const char *alpha2
  
        if (!is_world_regdom((char *) alpha2))
                pr_debug("Calling CRDA for country: %c%c\n",
-                       alpha2[0], alpha2[1]);
+                        alpha2[0], alpha2[1]);
        else
                pr_debug("Calling CRDA to update world regulatory domain\n");
  
@@@ -1132,42 -1121,6 +1123,6 @@@ const char *reg_initiator_name(enum nl8
  }
  EXPORT_SYMBOL(reg_initiator_name);
  
- static void chan_reg_rule_print_dbg(const struct ieee80211_regdomain *regd,
-                                   struct ieee80211_channel *chan,
-                                   const struct ieee80211_reg_rule *reg_rule)
- {
- #ifdef CONFIG_CFG80211_REG_DEBUG
-       const struct ieee80211_power_rule *power_rule;
-       const struct ieee80211_freq_range *freq_range;
-       char max_antenna_gain[32], bw[32];
-       power_rule = &reg_rule->power_rule;
-       freq_range = &reg_rule->freq_range;
-       if (!power_rule->max_antenna_gain)
-               snprintf(max_antenna_gain, sizeof(max_antenna_gain), "N/A");
-       else
-               snprintf(max_antenna_gain, sizeof(max_antenna_gain), "%d mBi",
-                        power_rule->max_antenna_gain);
-       if (reg_rule->flags & NL80211_RRF_AUTO_BW)
-               snprintf(bw, sizeof(bw), "%d KHz, %d KHz AUTO",
-                        freq_range->max_bandwidth_khz,
-                        reg_get_max_bandwidth(regd, reg_rule));
-       else
-               snprintf(bw, sizeof(bw), "%d KHz",
-                        freq_range->max_bandwidth_khz);
-       REG_DBG_PRINT("Updating information on frequency %d MHz with regulatory rule:\n",
-                     chan->center_freq);
-       REG_DBG_PRINT("(%d KHz - %d KHz @ %s), (%s, %d mBm)\n",
-                     freq_range->start_freq_khz, freq_range->end_freq_khz,
-                     bw, max_antenna_gain,
-                     power_rule->max_eirp);
- #endif
- }
  static uint32_t reg_rule_to_chan_bw_flags(const struct ieee80211_regdomain *regd,
                                          const struct ieee80211_reg_rule *reg_rule,
                                          const struct ieee80211_channel *chan)
@@@ -1242,20 -1195,19 +1197,19 @@@ static void handle_channel(struct wiph
                if (lr->initiator == NL80211_REGDOM_SET_BY_DRIVER &&
                    request_wiphy && request_wiphy == wiphy &&
                    request_wiphy->regulatory_flags & REGULATORY_STRICT_REG) {
-                       REG_DBG_PRINT("Disabling freq %d MHz for good\n",
-                                     chan->center_freq);
+                       pr_debug("Disabling freq %d MHz for good\n",
+                                chan->center_freq);
                        chan->orig_flags |= IEEE80211_CHAN_DISABLED;
                        chan->flags = chan->orig_flags;
                } else {
-                       REG_DBG_PRINT("Disabling freq %d MHz\n",
-                                     chan->center_freq);
+                       pr_debug("Disabling freq %d MHz\n",
+                                chan->center_freq);
                        chan->flags |= IEEE80211_CHAN_DISABLED;
                }
                return;
        }
  
        regd = reg_get_regdomain(wiphy);
-       chan_reg_rule_print_dbg(regd, chan, reg_rule);
  
        power_rule = &reg_rule->power_rule;
        bw_flags = reg_rule_to_chan_bw_flags(regd, reg_rule, chan);
@@@ -1393,18 -1345,15 +1347,15 @@@ static bool ignore_reg_update(struct wi
                return true;
  
        if (!lr) {
-               REG_DBG_PRINT("Ignoring regulatory request set by %s "
-                             "since last_request is not set\n",
-                             reg_initiator_name(initiator));
+               pr_debug("Ignoring regulatory request set by %s since last_request is not set\n",
+                        reg_initiator_name(initiator));
                return true;
        }
  
        if (initiator == NL80211_REGDOM_SET_BY_CORE &&
            wiphy->regulatory_flags & REGULATORY_CUSTOM_REG) {
-               REG_DBG_PRINT("Ignoring regulatory request set by %s "
-                             "since the driver uses its own custom "
-                             "regulatory domain\n",
-                             reg_initiator_name(initiator));
+               pr_debug("Ignoring regulatory request set by %s since the driver uses its own custom regulatory domain\n",
+                        reg_initiator_name(initiator));
                return true;
        }
  
        if (wiphy_strict_alpha2_regd(wiphy) && !wiphy->regd &&
            initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE &&
            !is_world_regdom(lr->alpha2)) {
-               REG_DBG_PRINT("Ignoring regulatory request set by %s "
-                             "since the driver requires its own regulatory "
-                             "domain to be set first\n",
-                             reg_initiator_name(initiator));
+               pr_debug("Ignoring regulatory request set by %s since the driver requires its own regulatory domain to be set first\n",
+                        reg_initiator_name(initiator));
                return true;
        }
  
@@@ -1699,7 -1646,7 +1648,7 @@@ static void reg_check_chans_work(struc
  {
        struct cfg80211_registered_device *rdev;
  
-       REG_DBG_PRINT("Verifying active interfaces after reg change\n");
+       pr_debug("Verifying active interfaces after reg change\n");
        rtnl_lock();
  
        list_for_each_entry(rdev, &cfg80211_rdev_list, list)
@@@ -1781,8 -1728,8 +1730,8 @@@ static void handle_channel_custom(struc
        }
  
        if (IS_ERR(reg_rule)) {
-               REG_DBG_PRINT("Disabling freq %d MHz as custom regd has no rule that fits it\n",
-                             chan->center_freq);
+               pr_debug("Disabling freq %d MHz as custom regd has no rule that fits it\n",
+                        chan->center_freq);
                if (wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED) {
                        chan->flags |= IEEE80211_CHAN_DISABLED;
                } else {
                return;
        }
  
-       chan_reg_rule_print_dbg(regd, chan, reg_rule);
        power_rule = &reg_rule->power_rule;
        bw_flags = reg_rule_to_chan_bw_flags(regd, reg_rule, chan);
  
@@@ -2524,7 -2469,7 +2471,7 @@@ static void restore_alpha2(char *alpha2
        if (is_user_regdom_saved()) {
                /* Unless we're asked to ignore it and reset it */
                if (reset_user) {
-                       REG_DBG_PRINT("Restoring regulatory settings including user preference\n");
+                       pr_debug("Restoring regulatory settings including user preference\n");
                        user_alpha2[0] = '9';
                        user_alpha2[1] = '7';
  
                         * back as they were for a full restore.
                         */
                        if (!is_world_regdom(ieee80211_regdom)) {
-                               REG_DBG_PRINT("Keeping preference on module parameter ieee80211_regdom: %c%c\n",
-                                             ieee80211_regdom[0], ieee80211_regdom[1]);
+                               pr_debug("Keeping preference on module parameter ieee80211_regdom: %c%c\n",
+                                        ieee80211_regdom[0], ieee80211_regdom[1]);
                                alpha2[0] = ieee80211_regdom[0];
                                alpha2[1] = ieee80211_regdom[1];
                        }
                } else {
-                       REG_DBG_PRINT("Restoring regulatory settings while preserving user preference for: %c%c\n",
-                                     user_alpha2[0], user_alpha2[1]);
+                       pr_debug("Restoring regulatory settings while preserving user preference for: %c%c\n",
+                                user_alpha2[0], user_alpha2[1]);
                        alpha2[0] = user_alpha2[0];
                        alpha2[1] = user_alpha2[1];
                }
        } else if (!is_world_regdom(ieee80211_regdom)) {
-               REG_DBG_PRINT("Keeping preference on module parameter ieee80211_regdom: %c%c\n",
-                             ieee80211_regdom[0], ieee80211_regdom[1]);
+               pr_debug("Keeping preference on module parameter ieee80211_regdom: %c%c\n",
+                        ieee80211_regdom[0], ieee80211_regdom[1]);
                alpha2[0] = ieee80211_regdom[0];
                alpha2[1] = ieee80211_regdom[1];
        } else
-               REG_DBG_PRINT("Restoring regulatory settings\n");
+               pr_debug("Restoring regulatory settings\n");
  }
  
  static void restore_custom_reg_settings(struct wiphy *wiphy)
@@@ -2663,14 -2608,14 +2610,14 @@@ static void restore_regulatory_settings
        list_splice_tail_init(&tmp_reg_req_list, &reg_requests_list);
        spin_unlock(&reg_requests_lock);
  
-       REG_DBG_PRINT("Kicking the queue\n");
+       pr_debug("Kicking the queue\n");
  
        schedule_work(&reg_work);
  }
  
  void regulatory_hint_disconnect(void)
  {
-       REG_DBG_PRINT("All devices are disconnected, going to restore regulatory settings\n");
+       pr_debug("All devices are disconnected, going to restore regulatory settings\n");
        restore_regulatory_settings(false);
  }
  
@@@ -2718,10 -2663,10 +2665,10 @@@ int regulatory_hint_found_beacon(struc
        if (!reg_beacon)
                return -ENOMEM;
  
-       REG_DBG_PRINT("Found new beacon on frequency: %d MHz (Ch %d) on %s\n",
-                     beacon_chan->center_freq,
-                     ieee80211_frequency_to_channel(beacon_chan->center_freq),
-                     wiphy_name(wiphy));
+       pr_debug("Found new beacon on frequency: %d MHz (Ch %d) on %s\n",
+                beacon_chan->center_freq,
+                ieee80211_frequency_to_channel(beacon_chan->center_freq),
+                wiphy_name(wiphy));
  
        memcpy(&reg_beacon->chan, beacon_chan,
               sizeof(struct ieee80211_channel));
@@@ -2747,7 -2692,7 +2694,7 @@@ static void print_rd_rules(const struc
        const struct ieee80211_power_rule *power_rule = NULL;
        char bw[32], cac_time[32];
  
 -      pr_info("  (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp), (dfs_cac_time)\n");
 +      pr_debug("  (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp), (dfs_cac_time)\n");
  
        for (i = 0; i < rd->n_reg_rules; i++) {
                reg_rule = &rd->reg_rules[i];
                 * in certain regions
                 */
                if (power_rule->max_antenna_gain)
 -                      pr_info("  (%d KHz - %d KHz @ %s), (%d mBi, %d mBm), (%s)\n",
 +                      pr_debug("  (%d KHz - %d KHz @ %s), (%d mBi, %d mBm), (%s)\n",
                                freq_range->start_freq_khz,
                                freq_range->end_freq_khz,
                                bw,
                                power_rule->max_eirp,
                                cac_time);
                else
 -                      pr_info("  (%d KHz - %d KHz @ %s), (N/A, %d mBm), (%s)\n",
 +                      pr_debug("  (%d KHz - %d KHz @ %s), (N/A, %d mBm), (%s)\n",
                                freq_range->start_freq_khz,
                                freq_range->end_freq_khz,
                                bw,
@@@ -2800,8 -2745,7 +2747,7 @@@ bool reg_supported_dfs_region(enum nl80
        case NL80211_DFS_JP:
                return true;
        default:
-               REG_DBG_PRINT("Ignoring uknown DFS master region: %d\n",
-                             dfs_region);
+               pr_debug("Ignoring uknown DFS master region: %d\n", dfs_region);
                return false;
        }
  }
@@@ -2815,35 -2759,35 +2761,35 @@@ static void print_regdomain(const struc
                        struct cfg80211_registered_device *rdev;
                        rdev = cfg80211_rdev_by_wiphy_idx(lr->wiphy_idx);
                        if (rdev) {
 -                              pr_info("Current regulatory domain updated by AP to: %c%c\n",
 +                              pr_debug("Current regulatory domain updated by AP to: %c%c\n",
                                        rdev->country_ie_alpha2[0],
                                        rdev->country_ie_alpha2[1]);
                        } else
 -                              pr_info("Current regulatory domain intersected:\n");
 +                              pr_debug("Current regulatory domain intersected:\n");
                } else
 -                      pr_info("Current regulatory domain intersected:\n");
 +                      pr_debug("Current regulatory domain intersected:\n");
        } else if (is_world_regdom(rd->alpha2)) {
 -              pr_info("World regulatory domain updated:\n");
 +              pr_debug("World regulatory domain updated:\n");
        } else {
                if (is_unknown_alpha2(rd->alpha2))
 -                      pr_info("Regulatory domain changed to driver built-in settings (unknown country)\n");
 +                      pr_debug("Regulatory domain changed to driver built-in settings (unknown country)\n");
                else {
                        if (reg_request_cell_base(lr))
 -                              pr_info("Regulatory domain changed to country: %c%c by Cell Station\n",
 +                              pr_debug("Regulatory domain changed to country: %c%c by Cell Station\n",
                                        rd->alpha2[0], rd->alpha2[1]);
                        else
 -                              pr_info("Regulatory domain changed to country: %c%c\n",
 +                              pr_debug("Regulatory domain changed to country: %c%c\n",
                                        rd->alpha2[0], rd->alpha2[1]);
                }
        }
  
 -      pr_info(" DFS Master region: %s", reg_dfs_region_str(rd->dfs_region));
 +      pr_debug(" DFS Master region: %s", reg_dfs_region_str(rd->dfs_region));
        print_rd_rules(rd);
  }
  
  static void print_regdomain_info(const struct ieee80211_regdomain *rd)
  {
 -      pr_info("Regulatory domain: %c%c\n", rd->alpha2[0], rd->alpha2[1]);
 +      pr_debug("Regulatory domain: %c%c\n", rd->alpha2[0], rd->alpha2[1]);
        print_rd_rules(rd);
  }
  
@@@ -2864,8 -2808,7 +2810,8 @@@ static int reg_set_rd_user(const struc
                return -EALREADY;
  
        if (!is_valid_rd(rd)) {
 -              pr_err("Invalid regulatory domain detected:\n");
 +              pr_err("Invalid regulatory domain detected: %c%c\n",
 +                     rd->alpha2[0], rd->alpha2[1]);
                print_regdomain_info(rd);
                return -EINVAL;
        }
@@@ -2901,8 -2844,7 +2847,8 @@@ static int reg_set_rd_driver(const stru
                return -EALREADY;
  
        if (!is_valid_rd(rd)) {
 -              pr_err("Invalid regulatory domain detected:\n");
 +              pr_err("Invalid regulatory domain detected: %c%c\n",
 +                     rd->alpha2[0], rd->alpha2[1]);
                print_regdomain_info(rd);
                return -EINVAL;
        }
@@@ -2960,8 -2902,7 +2906,8 @@@ static int reg_set_rd_country_ie(const 
         */
  
        if (!is_valid_rd(rd)) {
 -              pr_err("Invalid regulatory domain detected:\n");
 +              pr_err("Invalid regulatory domain detected: %c%c\n",
 +                     rd->alpha2[0], rd->alpha2[1]);
                print_regdomain_info(rd);
                return -EINVAL;
        }