net: mac80211: Convert printk(KERN_DEBUG to pr_debug
[linux-2.6-microblaze.git] / net / mac80211 / mlme.c
index 20c680b..419301c 100644 (file)
@@ -171,122 +171,64 @@ static int ecw2cw(int ecw)
        return (1 << ecw) - 1;
 }
 
-/*
- * ieee80211_enable_ht should be called only after the operating band
- * has been determined as ht configuration depends on the hw's
- * HT abilities for a specific band.
- */
-static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
-                              struct ieee80211_ht_info *hti,
-                              const u8 *bssid, u16 ap_ht_cap_flags,
-                              bool beacon_htcap_ie)
+static u32 ieee80211_config_ht_tx(struct ieee80211_sub_if_data *sdata,
+                                 struct ieee80211_ht_operation *ht_oper,
+                                 const u8 *bssid, bool reconfig)
 {
        struct ieee80211_local *local = sdata->local;
        struct ieee80211_supported_band *sband;
        struct sta_info *sta;
        u32 changed = 0;
-       int hti_cfreq;
        u16 ht_opmode;
-       bool enable_ht = true;
-       enum nl80211_channel_type prev_chantype;
-       enum nl80211_channel_type rx_channel_type = NL80211_CHAN_NO_HT;
-       enum nl80211_channel_type tx_channel_type;
+       bool disable_40 = false;
 
        sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
-       prev_chantype = sdata->vif.bss_conf.channel_type;
 
-
-       hti_cfreq = ieee80211_channel_to_frequency(hti->control_chan,
-                                                  sband->band);
-       /* check that channel matches the right operating channel */
-       if (local->hw.conf.channel->center_freq != hti_cfreq) {
-               /* Some APs mess this up, evidently.
-                * Netgear WNDR3700 sometimes reports 4 higher than
-                * the actual channel, for instance.
-                */
-               printk(KERN_DEBUG
-                      "%s: Wrong control channel in association"
-                      " response: configured center-freq: %d"
-                      " hti-cfreq: %d  hti->control_chan: %d"
-                      " band: %d.  Disabling HT.\n",
-                      sdata->name,
-                      local->hw.conf.channel->center_freq,
-                      hti_cfreq, hti->control_chan,
-                      sband->band);
-               enable_ht = false;
-       }
-
-       if (enable_ht) {
-               rx_channel_type = NL80211_CHAN_HT20;
-
-               if (!(ap_ht_cap_flags & IEEE80211_HT_CAP_40MHZ_INTOLERANT) &&
-                   !ieee80111_cfg_override_disables_ht40(sdata) &&
-                   (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) &&
-                   (hti->ht_param & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) {
-                       switch(hti->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
-                       case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
-                               rx_channel_type = NL80211_CHAN_HT40PLUS;
-                               break;
-                       case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
-                               rx_channel_type = NL80211_CHAN_HT40MINUS;
-                               break;
-                       }
-               }
+       switch (sdata->vif.bss_conf.channel_type) {
+       case NL80211_CHAN_HT40PLUS:
+               if (local->hw.conf.channel->flags & IEEE80211_CHAN_NO_HT40PLUS)
+                       disable_40 = true;
+               break;
+       case NL80211_CHAN_HT40MINUS:
+               if (local->hw.conf.channel->flags & IEEE80211_CHAN_NO_HT40MINUS)
+                       disable_40 = true;
+               break;
+       default:
+               break;
        }
 
-       tx_channel_type = ieee80211_get_tx_channel_type(local, rx_channel_type);
-
-       if (local->tmp_channel)
-               local->tmp_channel_type = rx_channel_type;
+       /* This can change during the lifetime of the BSS */
+       if (!(ht_oper->ht_param & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY))
+               disable_40 = true;
 
-       if (!ieee80211_set_channel_type(local, sdata, rx_channel_type)) {
-               /* can only fail due to HT40+/- mismatch */
-               rx_channel_type = NL80211_CHAN_HT20;
-               WARN_ON(!ieee80211_set_channel_type(local, sdata,
-                                                   rx_channel_type));
-       }
-
-       if (beacon_htcap_ie && (prev_chantype != rx_channel_type)) {
-               /*
-                * Whenever the AP announces the HT mode change that can be
-                * 40MHz intolerant or etc., it would be safer to stop tx
-                * queues before doing hw config to avoid buffer overflow.
-                */
-               ieee80211_stop_queues_by_reason(&sdata->local->hw,
-                               IEEE80211_QUEUE_STOP_REASON_CHTYPE_CHANGE);
+       mutex_lock(&local->sta_mtx);
+       sta = sta_info_get(sdata, bssid);
 
-               /* flush out all packets */
-               synchronize_net();
+       WARN_ON_ONCE(!sta);
 
-               drv_flush(local, false);
-       }
+       if (sta && !sta->supports_40mhz)
+               disable_40 = true;
 
-       /* channel_type change automatically detected */
-       ieee80211_hw_config(local, 0);
+       if (sta && (!reconfig ||
+                   (disable_40 != !(sta->sta.ht_cap.cap &
+                                       IEEE80211_HT_CAP_SUP_WIDTH_20_40)))) {
 
-       if (prev_chantype != tx_channel_type) {
-               rcu_read_lock();
-               sta = sta_info_get(sdata, bssid);
-               if (sta)
-                       rate_control_rate_update(local, sband, sta,
-                                                IEEE80211_RC_HT_CHANGED,
-                                                tx_channel_type);
-               rcu_read_unlock();
+               if (disable_40)
+                       sta->sta.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+               else
+                       sta->sta.ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
 
-               if (beacon_htcap_ie)
-                       ieee80211_wake_queues_by_reason(&sdata->local->hw,
-                               IEEE80211_QUEUE_STOP_REASON_CHTYPE_CHANGE);
+               rate_control_rate_update(local, sband, sta,
+                                        IEEE80211_RC_BW_CHANGED);
        }
+       mutex_unlock(&local->sta_mtx);
 
-       ht_opmode = le16_to_cpu(hti->operation_mode);
+       ht_opmode = le16_to_cpu(ht_oper->operation_mode);
 
        /* if bss configuration changed store the new one */
-       if (sdata->ht_opmode_valid != enable_ht ||
-           sdata->vif.bss_conf.ht_operation_mode != ht_opmode ||
-           prev_chantype != rx_channel_type) {
+       if (!reconfig || (sdata->vif.bss_conf.ht_operation_mode != ht_opmode)) {
                changed |= BSS_CHANGED_HT;
                sdata->vif.bss_conf.ht_operation_mode = ht_opmode;
-               sdata->ht_opmode_valid = enable_ht;
        }
 
        return changed;
@@ -316,12 +258,12 @@ static int ieee80211_compatible_rates(const u8 *supp_rates, int supp_rates_len,
 }
 
 static void ieee80211_add_ht_ie(struct ieee80211_sub_if_data *sdata,
-                               struct sk_buff *skb, const u8 *ht_info_ie,
+                               struct sk_buff *skb, const u8 *ht_oper_ie,
                                struct ieee80211_supported_band *sband,
                                struct ieee80211_channel *channel,
                                enum ieee80211_smps_mode smps)
 {
-       struct ieee80211_ht_info *ht_info;
+       struct ieee80211_ht_operation *ht_oper;
        u8 *pos;
        u32 flags = channel->flags;
        u16 cap;
@@ -329,21 +271,21 @@ static void ieee80211_add_ht_ie(struct ieee80211_sub_if_data *sdata,
 
        BUILD_BUG_ON(sizeof(ht_cap) != sizeof(sband->ht_cap));
 
-       if (!ht_info_ie)
+       if (!ht_oper_ie)
                return;
 
-       if (ht_info_ie[1] < sizeof(struct ieee80211_ht_info))
+       if (ht_oper_ie[1] < sizeof(struct ieee80211_ht_operation))
                return;
 
        memcpy(&ht_cap, &sband->ht_cap, sizeof(ht_cap));
        ieee80211_apply_htcap_overrides(sdata, &ht_cap);
 
-       ht_info = (struct ieee80211_ht_info *)(ht_info_ie + 2);
+       ht_oper = (struct ieee80211_ht_operation *)(ht_oper_ie + 2);
 
        /* determine capability flags */
        cap = ht_cap.cap;
 
-       switch (ht_info->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
+       switch (ht_oper->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
        case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
                if (flags & IEEE80211_CHAN_NO_HT40PLUS) {
                        cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
@@ -358,6 +300,16 @@ static void ieee80211_add_ht_ie(struct ieee80211_sub_if_data *sdata,
                break;
        }
 
+       /*
+        * If 40 MHz was disabled associate as though we weren't
+        * capable of 40 MHz -- some broken APs will never fall
+        * back to trying to transmit in 20 MHz.
+        */
+       if (sdata->u.mgd.flags & IEEE80211_STA_DISABLE_40MHZ) {
+               cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+               cap &= ~IEEE80211_HT_CAP_SGI_40;
+       }
+
        /* set SM PS mode properly */
        cap &= ~IEEE80211_HT_CAP_SM_PS;
        switch (smps) {
@@ -557,7 +509,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
        }
 
        if (!(ifmgd->flags & IEEE80211_STA_DISABLE_11N))
-               ieee80211_add_ht_ie(sdata, skb, assoc_data->ht_information_ie,
+               ieee80211_add_ht_ie(sdata, skb, assoc_data->ht_operation_ie,
                                    sband, local->oper_channel, ifmgd->ap_smps);
 
        /* if present, add any custom non-vendor IEs that go after HT */
@@ -1182,7 +1134,7 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
        if (!local->ops->conf_tx)
                return;
 
-       if (local->hw.queues < 4)
+       if (local->hw.queues < IEEE80211_NUM_ACS)
                return;
 
        if (!wmm_param)
@@ -1435,7 +1387,6 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
        sdata->vif.bss_conf.assoc = false;
 
        /* on the next assoc, re-program HT parameters */
-       sdata->ht_opmode_valid = false;
        memset(&ifmgd->ht_capa, 0, sizeof(ifmgd->ht_capa));
        memset(&ifmgd->ht_capa_mask, 0, sizeof(ifmgd->ht_capa_mask));
 
@@ -1496,19 +1447,24 @@ void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
 static void ieee80211_reset_ap_probe(struct ieee80211_sub_if_data *sdata)
 {
        struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+       struct ieee80211_local *local = sdata->local;
 
+       mutex_lock(&local->mtx);
        if (!(ifmgd->flags & (IEEE80211_STA_BEACON_POLL |
-                             IEEE80211_STA_CONNECTION_POLL)))
-           return;
+                             IEEE80211_STA_CONNECTION_POLL))) {
+               mutex_unlock(&local->mtx);
+               return;
+       }
 
        ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL |
                          IEEE80211_STA_BEACON_POLL);
-       mutex_lock(&sdata->local->iflist_mtx);
-       ieee80211_recalc_ps(sdata->local, -1);
-       mutex_unlock(&sdata->local->iflist_mtx);
+
+       mutex_lock(&local->iflist_mtx);
+       ieee80211_recalc_ps(local, -1);
+       mutex_unlock(&local->iflist_mtx);
 
        if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR)
-               return;
+               goto out;
 
        /*
         * We've received a probe response, but are not sure whether
@@ -1520,6 +1476,9 @@ static void ieee80211_reset_ap_probe(struct ieee80211_sub_if_data *sdata)
        mod_timer(&ifmgd->conn_mon_timer,
                  round_jiffies_up(jiffies +
                                   IEEE80211_CONNECTION_IDLE_TIME));
+out:
+       ieee80211_run_deferred_scan(local);
+       mutex_unlock(&local->mtx);
 }
 
 void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata,
@@ -1563,18 +1522,28 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata)
         * anymore. The timeout will be reset if the frame is ACKed by
         * the AP.
         */
+       ifmgd->probe_send_count++;
+
        if (sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) {
                ifmgd->nullfunc_failed = false;
                ieee80211_send_nullfunc(sdata->local, sdata, 0);
        } else {
+               int ssid_len;
+
                ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID);
-               ieee80211_send_probe_req(sdata, dst, ssid + 2, ssid[1], NULL, 0,
-                                        (u32) -1, true, false);
+               if (WARN_ON_ONCE(ssid == NULL))
+                       ssid_len = 0;
+               else
+                       ssid_len = ssid[1];
+
+               ieee80211_send_probe_req(sdata, dst, ssid + 2, ssid_len, NULL,
+                                        0, (u32) -1, true, false);
        }
 
-       ifmgd->probe_send_count++;
        ifmgd->probe_timeout = jiffies + msecs_to_jiffies(probe_wait_ms);
        run_again(ifmgd, ifmgd->probe_timeout);
+       if (sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)
+               drv_flush(sdata->local, false);
 }
 
 static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata,
@@ -1586,22 +1555,25 @@ static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata,
        if (!ieee80211_sdata_running(sdata))
                return;
 
-       if (sdata->local->scanning)
-               return;
-
-       if (sdata->local->tmp_channel)
-               return;
-
        mutex_lock(&ifmgd->mtx);
 
        if (!ifmgd->associated)
                goto out;
 
+       mutex_lock(&sdata->local->mtx);
+
+       if (sdata->local->tmp_channel || sdata->local->scanning) {
+               mutex_unlock(&sdata->local->mtx);
+               goto out;
+       }
+
 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
-       if (beacon && net_ratelimit())
-               printk(KERN_DEBUG "%s: detected beacon loss from AP "
-                      "- sending probe request\n", sdata->name);
+       if (beacon)
+               net_dbg_ratelimited("%s: detected beacon loss from AP - sending probe request\n",
+                                   sdata->name);
 #endif
+       ieee80211_cqm_rssi_notify(&sdata->vif,
+               NL80211_CQM_RSSI_BEACON_LOSS_EVENT, GFP_KERNEL);
 
        /*
         * The driver/our work has already reported this event or the
@@ -1623,6 +1595,8 @@ static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata,
        else
                ifmgd->flags |= IEEE80211_STA_CONNECTION_POLL;
 
+       mutex_unlock(&sdata->local->mtx);
+
        if (already)
                goto out;
 
@@ -1643,6 +1617,7 @@ struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw,
        struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
        struct sk_buff *skb;
        const u8 *ssid;
+       int ssid_len;
 
        if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION))
                return NULL;
@@ -1653,8 +1628,13 @@ struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw,
                return NULL;
 
        ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID);
+       if (WARN_ON_ONCE(ssid == NULL))
+               ssid_len = 0;
+       else
+               ssid_len = ssid[1];
+
        skb = ieee80211_build_probe_req(sdata, ifmgd->associated->bssid,
-                                       (u32) -1, ssid + 2, ssid[1],
+                                       (u32) -1, ssid + 2, ssid_len,
                                        NULL, 0, true);
 
        return skb;
@@ -1676,8 +1656,7 @@ static void __ieee80211_connection_loss(struct ieee80211_sub_if_data *sdata)
 
        memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN);
 
-       printk(KERN_DEBUG "%s: Connection to AP %pM lost.\n",
-              sdata->name, bssid);
+       pr_debug("%s: Connection to AP %pM lost\n", sdata->name, bssid);
 
        ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
                               WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
@@ -1799,7 +1778,7 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
 
        memcpy(bssid, ifmgd->auth_data->bss->bssid, ETH_ALEN);
 
-       if (compare_ether_addr(bssid, mgmt->bssid))
+       if (!ether_addr_equal(bssid, mgmt->bssid))
                return RX_MGMT_NONE;
 
        auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg);
@@ -1811,9 +1790,10 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
                return RX_MGMT_NONE;
 
        if (status_code != WLAN_STATUS_SUCCESS) {
-               printk(KERN_DEBUG "%s: %pM denied authentication (status %d)\n",
-                      sdata->name, mgmt->sa, status_code);
-               goto out;
+               pr_debug("%s: %pM denied authentication (status %d)\n",
+                        sdata->name, mgmt->sa, status_code);
+               ieee80211_destroy_auth_data(sdata, false);
+               return RX_MGMT_CFG80211_RX_AUTH;
        }
 
        switch (ifmgd->auth_data->algorithm) {
@@ -1834,8 +1814,7 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
                return RX_MGMT_NONE;
        }
 
-       printk(KERN_DEBUG "%s: authenticated\n", sdata->name);
- out:
+       pr_debug("%s: authenticated\n", sdata->name);
        ifmgd->auth_data->done = true;
        ifmgd->auth_data->timeout = jiffies + IEEE80211_AUTH_WAIT_ASSOC;
        run_again(ifmgd, ifmgd->auth_data->timeout);
@@ -1848,8 +1827,7 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
                goto out_err;
        }
        if (sta_info_move_state(sta, IEEE80211_STA_AUTH)) {
-               printk(KERN_DEBUG "%s: failed moving %pM to auth\n",
-                      sdata->name, bssid);
+               pr_debug("%s: failed moving %pM to auth\n", sdata->name, bssid);
                goto out_err;
        }
        mutex_unlock(&sdata->local->sta_mtx);
@@ -1876,15 +1854,15 @@ ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
                return RX_MGMT_NONE;
 
        if (!ifmgd->associated ||
-           compare_ether_addr(mgmt->bssid, ifmgd->associated->bssid))
+           !ether_addr_equal(mgmt->bssid, ifmgd->associated->bssid))
                return RX_MGMT_NONE;
 
        bssid = ifmgd->associated->bssid;
 
        reason_code = le16_to_cpu(mgmt->u.deauth.reason_code);
 
-       printk(KERN_DEBUG "%s: deauthenticated from %pM (Reason: %u)\n",
-                       sdata->name, bssid, reason_code);
+       pr_debug("%s: deauthenticated from %pM (Reason: %u)\n",
+                sdata->name, bssid, reason_code);
 
        ieee80211_set_disassoc(sdata, 0, 0, false, NULL);
 
@@ -1909,13 +1887,13 @@ ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
                return RX_MGMT_NONE;
 
        if (!ifmgd->associated ||
-           compare_ether_addr(mgmt->bssid, ifmgd->associated->bssid))
+           !ether_addr_equal(mgmt->bssid, ifmgd->associated->bssid))
                return RX_MGMT_NONE;
 
        reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code);
 
-       printk(KERN_DEBUG "%s: disassociated from %pM (Reason: %u)\n",
-                       sdata->name, mgmt->sa, reason_code);
+       pr_debug("%s: disassociated from %pM (Reason: %u)\n",
+                sdata->name, mgmt->sa, reason_code);
 
        ieee80211_set_disassoc(sdata, 0, 0, false, NULL);
 
@@ -2000,7 +1978,6 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
        struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
        u32 changed = 0;
        int err;
-       u16 ap_ht_cap_flags;
 
        /* AssocResp and ReassocResp have identical structure */
 
@@ -2008,17 +1985,15 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
        capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info);
 
        if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14)))
-               printk(KERN_DEBUG
-                      "%s: invalid AID value 0x%x; bits 15:14 not set\n",
-                      sdata->name, aid);
+               pr_debug("%s: invalid AID value 0x%x; bits 15:14 not set\n",
+                        sdata->name, aid);
        aid &= ~(BIT(15) | BIT(14));
 
        ifmgd->broken_ap = false;
 
        if (aid == 0 || aid > IEEE80211_MAX_AID) {
-               printk(KERN_DEBUG
-                      "%s: invalid AID value %d (out of range), turn off PS\n",
-                      sdata->name, aid);
+               pr_debug("%s: invalid AID value %d (out of range), turn off PS\n",
+                        sdata->name, aid);
                aid = 0;
                ifmgd->broken_ap = true;
        }
@@ -2027,8 +2002,8 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
        ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
 
        if (!elems.supp_rates) {
-               printk(KERN_DEBUG "%s: no SuppRates element in AssocResp\n",
-                      sdata->name);
+               pr_debug("%s: no SuppRates element in AssocResp\n",
+                        sdata->name);
                return false;
        }
 
@@ -2051,7 +2026,8 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
                ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
                                elems.ht_cap_elem, &sta->sta.ht_cap);
 
-       ap_ht_cap_flags = sta->sta.ht_cap.cap;
+       sta->supports_40mhz =
+               sta->sta.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40;
 
        rate_control_rate_init(sta);
 
@@ -2067,9 +2043,8 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
        if (!err && !(ifmgd->flags & IEEE80211_STA_CONTROL_PORT))
                err = sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED);
        if (err) {
-               printk(KERN_DEBUG
-                      "%s: failed to move station %pM to desired state\n",
-                      sdata->name, sta->sta.addr);
+               pr_debug("%s: failed to move station %pM to desired state\n",
+                        sdata->name, sta->sta.addr);
                WARN_ON(__sta_info_destroy(sta));
                mutex_unlock(&sdata->local->sta_mtx);
                return false;
@@ -2092,11 +2067,10 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
                ieee80211_set_wmm_default(sdata, false);
        changed |= BSS_CHANGED_QOS;
 
-       if (elems.ht_info_elem && elems.wmm_param &&
+       if (elems.ht_operation && elems.wmm_param &&
            !(ifmgd->flags & IEEE80211_STA_DISABLE_11N))
-               changed |= ieee80211_enable_ht(sdata, elems.ht_info_elem,
-                                              cbss->bssid, ap_ht_cap_flags,
-                                              false);
+               changed |= ieee80211_config_ht_tx(sdata, elems.ht_operation,
+                                                 cbss->bssid, false);
 
        /* set AID and assoc capability,
         * ieee80211_set_associated() will tell the driver */
@@ -2137,7 +2111,7 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
 
        if (!assoc_data)
                return RX_MGMT_NONE;
-       if (compare_ether_addr(assoc_data->bss->bssid, mgmt->bssid))
+       if (!ether_addr_equal(assoc_data->bss->bssid, mgmt->bssid))
                return RX_MGMT_NONE;
 
        /*
@@ -2153,10 +2127,9 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
        status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code);
        aid = le16_to_cpu(mgmt->u.assoc_resp.aid);
 
-       printk(KERN_DEBUG "%s: RX %sssocResp from %pM (capab=0x%x "
-              "status=%d aid=%d)\n",
-              sdata->name, reassoc ? "Rea" : "A", mgmt->sa,
-              capab_info, status_code, (u16)(aid & ~(BIT(15) | BIT(14))));
+       pr_debug("%s: RX %sssocResp from %pM (capab=0x%x status=%d aid=%d)\n",
+                sdata->name, reassoc ? "Rea" : "A", mgmt->sa,
+                capab_info, status_code, (u16)(aid & ~(BIT(15) | BIT(14))));
 
        pos = mgmt->u.assoc_resp.variable;
        ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
@@ -2167,9 +2140,8 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
                u32 tu, ms;
                tu = get_unaligned_le32(elems.timeout_int + 1);
                ms = tu * 1024 / 1000;
-               printk(KERN_DEBUG "%s: %pM rejected association temporarily; "
-                      "comeback duration %u TU (%u ms)\n",
-                      sdata->name, mgmt->sa, tu, ms);
+               pr_debug("%s: %pM rejected association temporarily; comeback duration %u TU (%u ms)\n",
+                        sdata->name, mgmt->sa, tu, ms);
                assoc_data->timeout = jiffies + msecs_to_jiffies(ms);
                if (ms > IEEE80211_ASSOC_TIMEOUT)
                        run_again(ifmgd, assoc_data->timeout);
@@ -2179,11 +2151,11 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
        *bss = assoc_data->bss;
 
        if (status_code != WLAN_STATUS_SUCCESS) {
-               printk(KERN_DEBUG "%s: %pM denied association (code=%d)\n",
-                      sdata->name, mgmt->sa, status_code);
+               pr_debug("%s: %pM denied association (code=%d)\n",
+                        sdata->name, mgmt->sa, status_code);
                ieee80211_destroy_assoc_data(sdata, false);
        } else {
-               printk(KERN_DEBUG "%s: associated\n", sdata->name);
+               pr_debug("%s: associated\n", sdata->name);
 
                if (!ieee80211_assoc_success(sdata, *bss, mgmt, len)) {
                        /* oops -- internal error -- send timeout for now */
@@ -2217,8 +2189,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
        bool need_ps = false;
 
        if (sdata->u.mgd.associated &&
-           compare_ether_addr(mgmt->bssid, sdata->u.mgd.associated->bssid)
-           == 0) {
+           ether_addr_equal(mgmt->bssid, sdata->u.mgd.associated->bssid)) {
                bss = (void *)sdata->u.mgd.associated->priv;
                /* not previously set so we may need to recalc */
                need_ps = !bss->dtim_period;
@@ -2273,7 +2244,7 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
 
        ASSERT_MGD_MTX(ifmgd);
 
-       if (compare_ether_addr(mgmt->da, sdata->vif.addr))
+       if (!ether_addr_equal(mgmt->da, sdata->vif.addr))
                return; /* ignore ProbeResp to foreign address */
 
        baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt;
@@ -2286,14 +2257,13 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
        ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, false);
 
        if (ifmgd->associated &&
-           compare_ether_addr(mgmt->bssid, ifmgd->associated->bssid) == 0)
+           ether_addr_equal(mgmt->bssid, ifmgd->associated->bssid))
                ieee80211_reset_ap_probe(sdata);
 
        if (ifmgd->auth_data && !ifmgd->auth_data->bss->proberesp_ies &&
-           compare_ether_addr(mgmt->bssid, ifmgd->auth_data->bss->bssid)
-           == 0) {
+           ether_addr_equal(mgmt->bssid, ifmgd->auth_data->bss->bssid)) {
                /* got probe response, continue with auth */
-               printk(KERN_DEBUG "%s: direct probe responded\n", sdata->name);
+               pr_debug("%s: direct probe responded\n", sdata->name);
                ifmgd->auth_data->tries = 0;
                ifmgd->auth_data->timeout = jiffies;
                run_again(ifmgd, ifmgd->auth_data->timeout);
@@ -2319,7 +2289,7 @@ static const u64 care_about_ies =
        (1ULL << WLAN_EID_CHANNEL_SWITCH) |
        (1ULL << WLAN_EID_PWR_CONSTRAINT) |
        (1ULL << WLAN_EID_HT_CAPABILITY) |
-       (1ULL << WLAN_EID_HT_INFORMATION);
+       (1ULL << WLAN_EID_HT_OPERATION);
 
 static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
                                     struct ieee80211_mgmt *mgmt,
@@ -2348,8 +2318,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
                return;
 
        if (ifmgd->assoc_data && !ifmgd->assoc_data->have_beacon &&
-           compare_ether_addr(mgmt->bssid, ifmgd->assoc_data->bss->bssid)
-           == 0) {
+           ether_addr_equal(mgmt->bssid, ifmgd->assoc_data->bss->bssid)) {
                ieee802_11_parse_elems(mgmt->u.beacon.variable,
                                       len - baselen, &elems);
 
@@ -2364,7 +2333,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
        }
 
        if (!ifmgd->associated ||
-           compare_ether_addr(mgmt->bssid, ifmgd->associated->bssid))
+           !ether_addr_equal(mgmt->bssid, ifmgd->associated->bssid))
                return;
        bssid = ifmgd->associated->bssid;
 
@@ -2431,10 +2400,8 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
 
        if (ifmgd->flags & IEEE80211_STA_BEACON_POLL) {
 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
-               if (net_ratelimit()) {
-                       printk(KERN_DEBUG "%s: cancelling probereq poll due "
-                              "to a received beacon\n", sdata->name);
-               }
+               net_dbg_ratelimited("%s: cancelling probereq poll due to a received beacon\n",
+                                   sdata->name);
 #endif
                ifmgd->flags &= ~IEEE80211_STA_BEACON_POLL;
                mutex_lock(&local->iflist_mtx);
@@ -2468,11 +2435,13 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
        if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) {
                if (directed_tim) {
                        if (local->hw.conf.dynamic_ps_timeout > 0) {
-                               local->hw.conf.flags &= ~IEEE80211_CONF_PS;
-                               ieee80211_hw_config(local,
-                                                   IEEE80211_CONF_CHANGE_PS);
+                               if (local->hw.conf.flags & IEEE80211_CONF_PS) {
+                                       local->hw.conf.flags &= ~IEEE80211_CONF_PS;
+                                       ieee80211_hw_config(local,
+                                                           IEEE80211_CONF_CHANGE_PS);
+                               }
                                ieee80211_send_nullfunc(local, sdata, 0);
-                       } else {
+                       } else if (!local->pspolling && sdata->u.mgd.powersave) {
                                local->pspolling = true;
 
                                /*
@@ -2504,31 +2473,14 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
                        erp_valid, erp_value);
 
 
-       if (elems.ht_cap_elem && elems.ht_info_elem && elems.wmm_param &&
+       if (elems.ht_cap_elem && elems.ht_operation && elems.wmm_param &&
            !(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) {
-               struct sta_info *sta;
                struct ieee80211_supported_band *sband;
-               u16 ap_ht_cap_flags;
-
-               rcu_read_lock();
-
-               sta = sta_info_get(sdata, bssid);
-               if (WARN_ON(!sta)) {
-                       rcu_read_unlock();
-                       return;
-               }
 
                sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
 
-               ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
-                               elems.ht_cap_elem, &sta->sta.ht_cap);
-
-               ap_ht_cap_flags = sta->sta.ht_cap.cap;
-
-               rcu_read_unlock();
-
-               changed |= ieee80211_enable_ht(sdata, elems.ht_info_elem,
-                                              bssid, ap_ht_cap_flags, true);
+               changed |= ieee80211_config_ht_tx(sdata, elems.ht_operation,
+                                                 bssid, true);
        }
 
        /* Note: country IE parsing is done for us by cfg80211 */
@@ -2672,8 +2624,8 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata)
        auth_data->tries++;
 
        if (auth_data->tries > IEEE80211_AUTH_MAX_TRIES) {
-               printk(KERN_DEBUG "%s: authentication with %pM timed out\n",
-                      sdata->name, auth_data->bss->bssid);
+               pr_debug("%s: authentication with %pM timed out\n",
+                        sdata->name, auth_data->bss->bssid);
 
                /*
                 * Most likely AP is not in the range so remove the
@@ -2685,9 +2637,9 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata)
        }
 
        if (auth_data->bss->proberesp_ies) {
-               printk(KERN_DEBUG "%s: send auth to %pM (try %d/%d)\n",
-                      sdata->name, auth_data->bss->bssid, auth_data->tries,
-                      IEEE80211_AUTH_MAX_TRIES);
+               pr_debug("%s: send auth to %pM (try %d/%d)\n",
+                        sdata->name, auth_data->bss->bssid, auth_data->tries,
+                        IEEE80211_AUTH_MAX_TRIES);
 
                auth_data->expected_transaction = 2;
                ieee80211_send_auth(sdata, 1, auth_data->algorithm,
@@ -2697,9 +2649,9 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata)
        } else {
                const u8 *ssidie;
 
-               printk(KERN_DEBUG "%s: direct probe to %pM (try %d/%i)\n",
-                      sdata->name, auth_data->bss->bssid, auth_data->tries,
-                      IEEE80211_AUTH_MAX_TRIES);
+               pr_debug("%s: direct probe to %pM (try %d/%i)\n",
+                        sdata->name, auth_data->bss->bssid, auth_data->tries,
+                        IEEE80211_AUTH_MAX_TRIES);
 
                ssidie = ieee80211_bss_get_ie(auth_data->bss, WLAN_EID_SSID);
                if (!ssidie)
@@ -2727,8 +2679,8 @@ static int ieee80211_do_assoc(struct ieee80211_sub_if_data *sdata)
 
        assoc_data->tries++;
        if (assoc_data->tries > IEEE80211_ASSOC_MAX_TRIES) {
-               printk(KERN_DEBUG "%s: association with %pM timed out\n",
-                      sdata->name, assoc_data->bss->bssid);
+               pr_debug("%s: association with %pM timed out\n",
+                        sdata->name, assoc_data->bss->bssid);
 
                /*
                 * Most likely AP is not in the range so remove the
@@ -2739,9 +2691,9 @@ static int ieee80211_do_assoc(struct ieee80211_sub_if_data *sdata)
                return -ETIMEDOUT;
        }
 
-       printk(KERN_DEBUG "%s: associate with %pM (try %d/%d)\n",
-              sdata->name, assoc_data->bss->bssid, assoc_data->tries,
-              IEEE80211_ASSOC_MAX_TRIES);
+       pr_debug("%s: associate with %pM (try %d/%d)\n",
+                sdata->name, assoc_data->bss->bssid, assoc_data->tries,
+                IEEE80211_ASSOC_MAX_TRIES);
        ieee80211_send_assoc(sdata);
 
        assoc_data->timeout = jiffies + IEEE80211_ASSOC_TIMEOUT;
@@ -3060,6 +3012,11 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
        struct sta_info *sta;
        bool have_sta = false;
        int err;
+       int ht_cfreq;
+       enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
+       const u8 *ht_oper_ie;
+       const struct ieee80211_ht_operation *ht_oper = NULL;
+       struct ieee80211_supported_band *sband;
 
        if (WARN_ON(!ifmgd->auth_data && !ifmgd->assoc_data))
                return -EINVAL;
@@ -3081,17 +3038,72 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
        mutex_unlock(&local->mtx);
 
        /* switch to the right channel */
+       sband = local->hw.wiphy->bands[cbss->channel->band];
+
+       ifmgd->flags &= ~IEEE80211_STA_DISABLE_40MHZ;
+
+       if (sband->ht_cap.ht_supported) {
+               ht_oper_ie = cfg80211_find_ie(WLAN_EID_HT_OPERATION,
+                                             cbss->information_elements,
+                                             cbss->len_information_elements);
+               if (ht_oper_ie && ht_oper_ie[1] >= sizeof(*ht_oper))
+                       ht_oper = (void *)(ht_oper_ie + 2);
+       }
+
+       if (ht_oper) {
+               ht_cfreq = ieee80211_channel_to_frequency(ht_oper->primary_chan,
+                                                         cbss->channel->band);
+               /* check that channel matches the right operating channel */
+               if (cbss->channel->center_freq != ht_cfreq) {
+                       /*
+                        * It's possible that some APs are confused here;
+                        * Netgear WNDR3700 sometimes reports 4 higher than
+                        * the actual channel in association responses, but
+                        * since we look at probe response/beacon data here
+                        * it should be OK.
+                        */
+                       pr_debug("%s: Wrong control channel: center-freq: %d ht-cfreq: %d ht->primary_chan: %d band: %d - Disabling HT\n",
+                                sdata->name, cbss->channel->center_freq,
+                                ht_cfreq, ht_oper->primary_chan,
+                                cbss->channel->band);
+                       ht_oper = NULL;
+               }
+       }
+
+       if (ht_oper) {
+               channel_type = NL80211_CHAN_HT20;
+
+               if (sband->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:
+                               channel_type = NL80211_CHAN_HT40PLUS;
+                               break;
+                       case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
+                               channel_type = NL80211_CHAN_HT40MINUS;
+                               break;
+                       }
+               }
+       }
+
+       if (!ieee80211_set_channel_type(local, sdata, channel_type)) {
+               /* can only fail due to HT40+/- mismatch */
+               channel_type = NL80211_CHAN_HT20;
+               pr_debug("%s: disabling 40 MHz due to multi-vif mismatch\n",
+                        sdata->name);
+               ifmgd->flags |= IEEE80211_STA_DISABLE_40MHZ;
+               WARN_ON(!ieee80211_set_channel_type(local, sdata,
+                                                   channel_type));
+       }
+
        local->oper_channel = cbss->channel;
-       ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
+       ieee80211_hw_config(local, 0);
 
        if (!have_sta) {
-               struct ieee80211_supported_band *sband;
                u32 rates = 0, basic_rates = 0;
                bool have_higher_than_11mbit;
                int min_rate = INT_MAX, min_rate_index = -1;
 
-               sband = sdata->local->hw.wiphy->bands[cbss->channel->band];
-
                ieee80211_get_rates(sband, bss->supp_rates,
                                    bss->supp_rates_len,
                                    &rates, &basic_rates,
@@ -3107,9 +3119,8 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
                 * we can connect -- with a warning.
                 */
                if (!basic_rates && min_rate_index >= 0) {
-                       printk(KERN_DEBUG
-                              "%s: No basic rates, using min rate instead.\n",
-                              sdata->name);
+                       pr_debug("%s: No basic rates, using min rate instead\n",
+                                sdata->name);
                        basic_rates = BIT(min_rate_index);
                }
 
@@ -3135,13 +3146,12 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
                err = sta_info_insert(sta);
                sta = NULL;
                if (err) {
-                       printk(KERN_DEBUG
-                              "%s: failed to insert STA entry for the AP (error %d)\n",
-                              sdata->name, err);
+                       pr_debug("%s: failed to insert STA entry for the AP (error %d)\n",
+                                sdata->name, err);
                        return err;
                }
        } else
-               WARN_ON_ONCE(compare_ether_addr(ifmgd->bssid, cbss->bssid));
+               WARN_ON_ONCE(!ether_addr_equal(ifmgd->bssid, cbss->bssid));
 
        return 0;
 }
@@ -3215,8 +3225,7 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
        if (ifmgd->associated)
                ieee80211_set_disassoc(sdata, 0, 0, false, NULL);
 
-       printk(KERN_DEBUG "%s: authenticate with %pM\n",
-              sdata->name, req->bss->bssid);
+       pr_debug("%s: authenticate with %pM\n", sdata->name, req->bss->bssid);
 
        err = ieee80211_prep_connection(sdata, req->bss, false);
        if (err)
@@ -3281,7 +3290,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
                bool match;
 
                /* keep sta info, bssid if matching */
-               match = compare_ether_addr(ifmgd->bssid, req->bss->bssid) == 0;
+               match = ether_addr_equal(ifmgd->bssid, req->bss->bssid);
                ieee80211_destroy_auth_data(sdata, match);
        }
 
@@ -3311,7 +3320,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
        /* Also disable HT if we don't support it or the AP doesn't use WMM */
        sband = local->hw.wiphy->bands[req->bss->channel->band];
        if (!sband->ht_cap.ht_supported ||
-           local->hw.queues < 4 || !bss->wmm_used)
+           local->hw.queues < IEEE80211_NUM_ACS || !bss->wmm_used)
                ifmgd->flags |= IEEE80211_STA_DISABLE_11N;
 
        memcpy(&ifmgd->ht_capa, &req->ht_capa, sizeof(ifmgd->ht_capa));
@@ -3334,11 +3343,12 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
                ifmgd->ap_smps = ifmgd->req_smps;
 
        assoc_data->capability = req->bss->capability;
-       assoc_data->wmm = bss->wmm_used && (local->hw.queues >= 4);
+       assoc_data->wmm = bss->wmm_used &&
+                         (local->hw.queues >= IEEE80211_NUM_ACS);
        assoc_data->supp_rates = bss->supp_rates;
        assoc_data->supp_rates_len = bss->supp_rates_len;
-       assoc_data->ht_information_ie =
-               ieee80211_bss_get_ie(req->bss, WLAN_EID_HT_INFORMATION);
+       assoc_data->ht_operation_ie =
+               ieee80211_bss_get_ie(req->bss, WLAN_EID_HT_OPERATION);
 
        if (bss->wmm_used && bss->uapsd_supported &&
            (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD)) {
@@ -3385,8 +3395,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
                 * Wait up to one beacon interval ...
                 * should this be more if we miss one?
                 */
-               printk(KERN_DEBUG "%s: waiting for beacon from %pM\n",
-                      sdata->name, ifmgd->bssid);
+               pr_debug("%s: waiting for beacon from %pM\n",
+                        sdata->name, ifmgd->bssid);
                assoc_data->timeout = TU_TO_EXP_TIME(req->bss->beacon_interval);
        } else {
                assoc_data->have_beacon = true;
@@ -3405,8 +3415,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
                                corrupt_type = "beacon";
                } else if (bss->corrupt_data & IEEE80211_BSS_CORRUPT_PROBE_RESP)
                        corrupt_type = "probe response";
-               printk(KERN_DEBUG "%s: associating with AP with corrupt %s\n",
-                      sdata->name, corrupt_type);
+               pr_debug("%s: associating with AP with corrupt %s\n",
+                        sdata->name, corrupt_type);
        }
 
        err = 0;
@@ -3435,12 +3445,11 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
                return 0;
        }
 
-       printk(KERN_DEBUG
-              "%s: deauthenticating from %pM by local choice (reason=%d)\n",
-              sdata->name, req->bssid, req->reason_code);
+       pr_debug("%s: deauthenticating from %pM by local choice (reason=%d)\n",
+                sdata->name, req->bssid, req->reason_code);
 
        if (ifmgd->associated &&
-           compare_ether_addr(ifmgd->associated->bssid, req->bssid) == 0)
+           ether_addr_equal(ifmgd->associated->bssid, req->bssid))
                ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
                                       req->reason_code, true, frame_buf);
        else
@@ -3479,8 +3488,8 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
                return -ENOLINK;
        }
 
-       printk(KERN_DEBUG "%s: disassociating from %pM by local choice (reason=%d)\n",
-              sdata->name, req->bss->bssid, req->reason_code);
+       pr_debug("%s: disassociating from %pM by local choice (reason=%d)\n",
+                sdata->name, req->bss->bssid, req->reason_code);
 
        memcpy(bssid, req->bss->bssid, ETH_ALEN);
        ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DISASSOC,