aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/main.c')
-rw-r--r--net/mac80211/main.c27
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
96static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local) 96static 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);