*/
#include <linux/nl80211.h>
+#include <net/cfg80211.h>
#include "ieee80211_i.h"
static enum ieee80211_chan_mode
return result;
}
+
+/*
+ * ieee80211_get_tx_channel_type returns the channel type we should
+ * use for packet transmission, given the channel capability and
+ * whatever regulatory flags we have been given.
+ */
+enum nl80211_channel_type ieee80211_get_tx_channel_type(
+ struct ieee80211_local *local,
+ enum nl80211_channel_type channel_type)
+{
+ switch (channel_type) {
+ case NL80211_CHAN_HT40PLUS:
+ if (local->hw.conf.channel->flags &
+ IEEE80211_CHAN_NO_HT40PLUS)
+ return NL80211_CHAN_HT20;
+ break;
+ case NL80211_CHAN_HT40MINUS:
+ if (local->hw.conf.channel->flags &
+ IEEE80211_CHAN_NO_HT40MINUS)
+ return NL80211_CHAN_HT20;
+ break;
+ default:
+ break;
+ }
+ return channel_type;
+}
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;
}
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) &&
(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
/* 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)
/* 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;