mac80211: Don't let regulatory make us deaf
[cascardo/linux.git] / net / mac80211 / mlme.c
index 90d1db3..0df2237 100644 (file)
@@ -189,7 +189,8 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
        u16 ht_opmode;
        bool enable_ht = true;
        enum nl80211_channel_type prev_chantype;
-       enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
+       enum nl80211_channel_type rx_channel_type = NL80211_CHAN_NO_HT;
+       enum nl80211_channel_type tx_channel_type;
 
        sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
        prev_chantype = sdata->vif.bss_conf.channel_type;
@@ -216,7 +217,7 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
        }
 
        if (enable_ht) {
-               channel_type = NL80211_CHAN_HT20;
+               rx_channel_type = NL80211_CHAN_HT20;
 
                if (!(ap_ht_cap_flags & IEEE80211_HT_CAP_40MHZ_INTOLERANT) &&
                    !ieee80111_cfg_override_disables_ht40(sdata) &&
@@ -224,29 +225,28 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
                    (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:
-                               if (!(local->hw.conf.channel->flags &
-                                   IEEE80211_CHAN_NO_HT40PLUS))
-                                       channel_type = NL80211_CHAN_HT40PLUS;
+                               rx_channel_type = NL80211_CHAN_HT40PLUS;
                                break;
                        case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
-                               if (!(local->hw.conf.channel->flags &
-                                   IEEE80211_CHAN_NO_HT40MINUS))
-                                       channel_type = NL80211_CHAN_HT40MINUS;
+                               rx_channel_type = NL80211_CHAN_HT40MINUS;
                                break;
                        }
                }
        }
 
+       tx_channel_type = ieee80211_get_tx_channel_type(local, rx_channel_type);
+
        if (local->tmp_channel)
-               local->tmp_channel_type = channel_type;
+               local->tmp_channel_type = rx_channel_type;
 
-       if (!ieee80211_set_channel_type(local, sdata, channel_type)) {
+       if (!ieee80211_set_channel_type(local, sdata, rx_channel_type)) {
                /* can only fail due to HT40+/- mismatch */
-               channel_type = NL80211_CHAN_HT20;
-               WARN_ON(!ieee80211_set_channel_type(local, sdata, channel_type));
+               rx_channel_type = NL80211_CHAN_HT20;
+               WARN_ON(!ieee80211_set_channel_type(local, sdata,
+                                                   rx_channel_type));
        }
 
-       if (beacon_htcap_ie && (prev_chantype != 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
@@ -264,13 +264,13 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
        /* channel_type change automatically detected */
        ieee80211_hw_config(local, 0);
 
-       if (prev_chantype != channel_type) {
+       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,
-                                                channel_type);
+                                                tx_channel_type);
                rcu_read_unlock();
 
                if (beacon_htcap_ie)
@@ -283,7 +283,7 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
        /* 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 != channel_type) {
+           prev_chantype != rx_channel_type) {
                changed |= BSS_CHANGED_HT;
                sdata->vif.bss_conf.ht_operation_mode = ht_opmode;
                sdata->ht_opmode_valid = enable_ht;