mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 03:01:39 -04:00
mac80211: Fix HT channel selection
HT management is done differently for AP and STA modes, unify to just the ->config() callback since HT is fundamentally a PHY property and cannot be per-BSS. Rename enum nl80211_sec_chan_offset as nl80211_channel_type to denote the channel type ( NO_HT, HT20, HT40+, HT40- ). Signed-off-by: Johannes Berg <[email protected]> Signed-off-by: Sujith <[email protected]> Signed-off-by: John W. Linville <[email protected]>
This commit is contained in:
parent
420e7fabd9
commit
094d05dc32
13 changed files with 109 additions and 169 deletions
|
|
@ -1122,12 +1122,12 @@ static int ieee80211_set_txq_params(struct wiphy *wiphy,
|
|||
|
||||
static int ieee80211_set_channel(struct wiphy *wiphy,
|
||||
struct ieee80211_channel *chan,
|
||||
enum nl80211_sec_chan_offset sec_chan_offset)
|
||||
enum nl80211_channel_type channel_type)
|
||||
{
|
||||
struct ieee80211_local *local = wiphy_priv(wiphy);
|
||||
|
||||
local->oper_channel = chan;
|
||||
local->oper_sec_chan_offset = sec_chan_offset;
|
||||
local->oper_channel_type = channel_type;
|
||||
|
||||
return ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@ u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
|
|||
struct ieee80211_bss_ht_conf ht;
|
||||
u32 changed = 0;
|
||||
bool enable_ht = true, ht_changed;
|
||||
enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
|
||||
|
||||
sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
|
||||
|
||||
|
|
@ -112,24 +113,36 @@ u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
|
|||
ieee80211_channel_to_frequency(hti->control_chan))
|
||||
enable_ht = false;
|
||||
|
||||
/*
|
||||
* XXX: This is totally incorrect when there are multiple virtual
|
||||
* interfaces, needs to be fixed later.
|
||||
*/
|
||||
ht_changed = local->hw.conf.ht.enabled != enable_ht;
|
||||
if (enable_ht) {
|
||||
channel_type = NL80211_CHAN_HT20;
|
||||
|
||||
if (!(ap_ht_cap_flags & IEEE80211_HT_CAP_40MHZ_INTOLERANT) &&
|
||||
(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:
|
||||
channel_type = NL80211_CHAN_HT40PLUS;
|
||||
break;
|
||||
case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
|
||||
channel_type = NL80211_CHAN_HT40MINUS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ht_changed = local->hw.conf.ht.enabled != enable_ht ||
|
||||
channel_type != local->hw.conf.ht.channel_type;
|
||||
|
||||
local->oper_channel_type = channel_type;
|
||||
local->hw.conf.ht.enabled = enable_ht;
|
||||
|
||||
if (ht_changed)
|
||||
ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_HT);
|
||||
|
||||
/* disable HT */
|
||||
if (!enable_ht)
|
||||
return 0;
|
||||
ht.secondary_channel_offset =
|
||||
hti->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET;
|
||||
ht.width_40_ok =
|
||||
!(ap_ht_cap_flags & IEEE80211_HT_CAP_40MHZ_INTOLERANT) &&
|
||||
(sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) &&
|
||||
(hti->ht_param & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY);
|
||||
|
||||
ht.operation_mode = le16_to_cpu(hti->operation_mode);
|
||||
|
||||
/* if bss configuration changed store the new one */
|
||||
|
|
|
|||
|
|
@ -625,7 +625,7 @@ struct ieee80211_local {
|
|||
struct delayed_work scan_work;
|
||||
struct ieee80211_sub_if_data *scan_sdata;
|
||||
struct ieee80211_channel *oper_channel, *scan_channel;
|
||||
enum nl80211_sec_chan_offset oper_sec_chan_offset;
|
||||
enum nl80211_channel_type oper_channel_type;
|
||||
u8 scan_ssid[IEEE80211_MAX_SSID_LEN];
|
||||
size_t scan_ssid_len;
|
||||
struct list_head bss_list;
|
||||
|
|
|
|||
|
|
@ -195,37 +195,30 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
|
|||
struct ieee80211_channel *chan;
|
||||
int ret = 0;
|
||||
int power;
|
||||
enum nl80211_sec_chan_offset sec_chan_offset;
|
||||
enum nl80211_channel_type channel_type;
|
||||
|
||||
might_sleep();
|
||||
|
||||
if (local->sw_scanning) {
|
||||
chan = local->scan_channel;
|
||||
sec_chan_offset = NL80211_SEC_CHAN_NO_HT;
|
||||
channel_type = NL80211_CHAN_NO_HT;
|
||||
} else {
|
||||
chan = local->oper_channel;
|
||||
sec_chan_offset = local->oper_sec_chan_offset;
|
||||
channel_type = local->oper_channel_type;
|
||||
}
|
||||
|
||||
if (chan != local->hw.conf.channel ||
|
||||
sec_chan_offset != local->hw.conf.ht.sec_chan_offset) {
|
||||
channel_type != local->hw.conf.ht.channel_type) {
|
||||
local->hw.conf.channel = chan;
|
||||
switch (sec_chan_offset) {
|
||||
case NL80211_SEC_CHAN_NO_HT:
|
||||
local->hw.conf.ht.channel_type = channel_type;
|
||||
switch (channel_type) {
|
||||
case NL80211_CHAN_NO_HT:
|
||||
local->hw.conf.ht.enabled = false;
|
||||
local->hw.conf.ht.sec_chan_offset = 0;
|
||||
break;
|
||||
case NL80211_SEC_CHAN_DISABLED:
|
||||
case NL80211_CHAN_HT20:
|
||||
case NL80211_CHAN_HT40MINUS:
|
||||
case NL80211_CHAN_HT40PLUS:
|
||||
local->hw.conf.ht.enabled = true;
|
||||
local->hw.conf.ht.sec_chan_offset = 0;
|
||||
break;
|
||||
case NL80211_SEC_CHAN_BELOW:
|
||||
local->hw.conf.ht.enabled = true;
|
||||
local->hw.conf.ht.sec_chan_offset = -1;
|
||||
break;
|
||||
case NL80211_SEC_CHAN_ABOVE:
|
||||
local->hw.conf.ht.enabled = true;
|
||||
local->hw.conf.ht.sec_chan_offset = 1;
|
||||
break;
|
||||
}
|
||||
changed |= IEEE80211_CONF_CHANGE_CHANNEL;
|
||||
|
|
|
|||
|
|
@ -858,6 +858,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
|
|||
rcu_read_unlock();
|
||||
|
||||
local->hw.conf.ht.enabled = false;
|
||||
local->oper_channel_type = NL80211_CHAN_NO_HT;
|
||||
ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_HT);
|
||||
|
||||
ieee80211_bss_info_change_notify(sdata, changed);
|
||||
|
|
|
|||
|
|
@ -641,7 +641,7 @@ int ieee80211_set_freq(struct ieee80211_sub_if_data *sdata, int freqMHz)
|
|||
chan->flags & IEEE80211_CHAN_NO_IBSS)
|
||||
return ret;
|
||||
local->oper_channel = chan;
|
||||
local->oper_sec_chan_offset = NL80211_SEC_CHAN_NO_HT;
|
||||
local->oper_channel_type = NL80211_CHAN_NO_HT;
|
||||
|
||||
if (local->sw_scanning || local->hw_scanning)
|
||||
ret = 0;
|
||||
|
|
|
|||
Loading…
Reference in a new issue