diff options
Diffstat (limited to 'net/mac80211/main.c')
-rw-r--r-- | net/mac80211/main.c | 27 |
1 files changed, 16 insertions, 11 deletions
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index fd8345c20051..70e87600cacc 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -95,11 +95,13 @@ static void ieee80211_reconfig_filter(struct work_struct *work) | |||
95 | 95 | ||
96 | static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local) | 96 | static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local) |
97 | { | 97 | { |
98 | struct ieee80211_sub_if_data *sdata; | ||
98 | struct ieee80211_channel *chan; | 99 | struct ieee80211_channel *chan; |
99 | u32 changed = 0; | 100 | u32 changed = 0; |
100 | int power; | 101 | int power; |
101 | enum nl80211_channel_type channel_type; | 102 | enum nl80211_channel_type channel_type; |
102 | u32 offchannel_flag; | 103 | u32 offchannel_flag; |
104 | bool scanning = false; | ||
103 | 105 | ||
104 | offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL; | 106 | offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL; |
105 | if (local->scan_channel) { | 107 | if (local->scan_channel) { |
@@ -146,16 +148,18 @@ static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local) | |||
146 | changed |= IEEE80211_CONF_CHANGE_SMPS; | 148 | changed |= IEEE80211_CONF_CHANGE_SMPS; |
147 | } | 149 | } |
148 | 150 | ||
149 | if (test_bit(SCAN_SW_SCANNING, &local->scanning) || | 151 | scanning = test_bit(SCAN_SW_SCANNING, &local->scanning) || |
150 | test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning) || | 152 | test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning) || |
151 | test_bit(SCAN_HW_SCANNING, &local->scanning) || | 153 | test_bit(SCAN_HW_SCANNING, &local->scanning); |
152 | !local->ap_power_level) | 154 | power = chan->max_power; |
153 | power = chan->max_power; | ||
154 | else | ||
155 | power = min(chan->max_power, local->ap_power_level); | ||
156 | 155 | ||
157 | if (local->user_power_level >= 0) | 156 | rcu_read_lock(); |
158 | power = min(power, local->user_power_level); | 157 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { |
158 | if (!rcu_access_pointer(sdata->vif.chanctx_conf)) | ||
159 | continue; | ||
160 | power = min(power, sdata->vif.bss_conf.txpower); | ||
161 | } | ||
162 | rcu_read_unlock(); | ||
159 | 163 | ||
160 | if (local->hw.conf.power_level != power) { | 164 | if (local->hw.conf.power_level != power) { |
161 | changed |= IEEE80211_CONF_CHANGE_POWER; | 165 | changed |= IEEE80211_CONF_CHANGE_POWER; |
@@ -600,7 +604,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
600 | 604 | ||
601 | wiphy->features |= NL80211_FEATURE_SK_TX_STATUS | | 605 | wiphy->features |= NL80211_FEATURE_SK_TX_STATUS | |
602 | NL80211_FEATURE_SAE | | 606 | NL80211_FEATURE_SAE | |
603 | NL80211_FEATURE_HT_IBSS; | 607 | NL80211_FEATURE_HT_IBSS | |
608 | NL80211_FEATURE_VIF_TXPOWER; | ||
604 | 609 | ||
605 | if (!ops->hw_scan) | 610 | if (!ops->hw_scan) |
606 | wiphy->features |= NL80211_FEATURE_LOW_PRIORITY_SCAN | | 611 | wiphy->features |= NL80211_FEATURE_LOW_PRIORITY_SCAN | |
@@ -633,7 +638,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
633 | local->hw.radiotap_mcs_details = IEEE80211_RADIOTAP_MCS_HAVE_MCS | | 638 | local->hw.radiotap_mcs_details = IEEE80211_RADIOTAP_MCS_HAVE_MCS | |
634 | IEEE80211_RADIOTAP_MCS_HAVE_GI | | 639 | IEEE80211_RADIOTAP_MCS_HAVE_GI | |
635 | IEEE80211_RADIOTAP_MCS_HAVE_BW; | 640 | IEEE80211_RADIOTAP_MCS_HAVE_BW; |
636 | local->user_power_level = -1; | 641 | local->user_power_level = IEEE80211_UNSET_POWER_LEVEL; |
637 | wiphy->ht_capa_mod_mask = &mac80211_ht_capa_mod_mask; | 642 | wiphy->ht_capa_mod_mask = &mac80211_ht_capa_mod_mask; |
638 | 643 | ||
639 | INIT_LIST_HEAD(&local->interfaces); | 644 | INIT_LIST_HEAD(&local->interfaces); |