summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorPeter Große <pegro@friiks.de>2017-12-13 18:29:46 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-04-12 12:31:06 +0200
commit7f12c3f9eec6dfa2dec212e0d5d6184413d316e3 (patch)
tree64795484b2b048a83c21246a14497cab6a7041a9 /net
parent110909d7a0c922bac1c9053605c842e02a0f20e9 (diff)
downloadlinux-stable-7f12c3f9eec6dfa2dec212e0d5d6184413d316e3.tar.gz
linux-stable-7f12c3f9eec6dfa2dec212e0d5d6184413d316e3.tar.bz2
linux-stable-7f12c3f9eec6dfa2dec212e0d5d6184413d316e3.zip
mac80211: Fix setting TX power on monitor interfaces
[ Upstream commit 3a3713ec360138f806c6fc368d1de570f692b347 ] Instead of calling ieee80211_recalc_txpower on monitor interfaces directly, call it using the virtual monitor interface, if one exists. In case of a single monitor interface given, reject setting TX power, if no virtual monitor interface exists. That being checked, don't warn in ieee80211_bss_info_change_notify, after setting TX power on a monitor interface. Fixes warning: ------------[ cut here ]------------ WARNING: CPU: 0 PID: 2193 at net/mac80211/driver-ops.h:167 ieee80211_bss_info_change_notify+0x111/0x190 Modules linked in: uvcvideo videobuf2_vmalloc videobuf2_memops videobuf2_v4l2 videobuf2_core rndis_host cdc_ether usbnet mii tp_smapi(O) thinkpad_ec(O) ohci_hcd vboxpci(O) vboxnetadp(O) vboxnetflt(O) v boxdrv(O) x86_pkg_temp_thermal kvm_intel kvm irqbypass iwldvm iwlwifi ehci_pci ehci_hcd tpm_tis tpm_tis_core tpm CPU: 0 PID: 2193 Comm: iw Tainted: G O 4.12.12-gentoo #2 task: ffff880186fd5cc0 task.stack: ffffc90001b54000 RIP: 0010:ieee80211_bss_info_change_notify+0x111/0x190 RSP: 0018:ffffc90001b57a10 EFLAGS: 00010246 RAX: 0000000000000006 RBX: ffff8801052ce840 RCX: 0000000000000064 RDX: 00000000fffffffc RSI: 0000000000040000 RDI: ffff8801052ce840 RBP: ffffc90001b57a38 R08: 0000000000000062 R09: 0000000000000000 R10: ffff8802144b5000 R11: ffff880049dc4614 R12: 0000000000040000 R13: 0000000000000064 R14: ffff8802105f0760 R15: ffffc90001b57b48 FS: 00007f92644b4580(0000) GS:ffff88021e200000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f9263c109f0 CR3: 00000001df850000 CR4: 00000000000406f0 Call Trace: ieee80211_recalc_txpower+0x33/0x40 ieee80211_set_tx_power+0x40/0x180 nl80211_set_wiphy+0x32e/0x950 Reported-by: Peter Große <pegro@friiks.de> Signed-off-by: Peter Große <pegro@friiks.de> Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Sasha Levin <alexander.levin@microsoft.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/cfg.c28
-rw-r--r--net/mac80211/driver-ops.h3
2 files changed, 29 insertions, 2 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 84f757c5d91a..288640471c2f 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -2373,10 +2373,17 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy,
struct ieee80211_sub_if_data *sdata;
enum nl80211_tx_power_setting txp_type = type;
bool update_txp_type = false;
+ bool has_monitor = false;
if (wdev) {
sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
+ if (sdata->vif.type == NL80211_IFTYPE_MONITOR) {
+ sdata = rtnl_dereference(local->monitor_sdata);
+ if (!sdata)
+ return -EOPNOTSUPP;
+ }
+
switch (type) {
case NL80211_TX_POWER_AUTOMATIC:
sdata->user_power_level = IEEE80211_UNSET_POWER_LEVEL;
@@ -2415,15 +2422,34 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy,
mutex_lock(&local->iflist_mtx);
list_for_each_entry(sdata, &local->interfaces, list) {
+ if (sdata->vif.type == NL80211_IFTYPE_MONITOR) {
+ has_monitor = true;
+ continue;
+ }
sdata->user_power_level = local->user_power_level;
if (txp_type != sdata->vif.bss_conf.txpower_type)
update_txp_type = true;
sdata->vif.bss_conf.txpower_type = txp_type;
}
- list_for_each_entry(sdata, &local->interfaces, list)
+ list_for_each_entry(sdata, &local->interfaces, list) {
+ if (sdata->vif.type == NL80211_IFTYPE_MONITOR)
+ continue;
ieee80211_recalc_txpower(sdata, update_txp_type);
+ }
mutex_unlock(&local->iflist_mtx);
+ if (has_monitor) {
+ sdata = rtnl_dereference(local->monitor_sdata);
+ if (sdata) {
+ sdata->user_power_level = local->user_power_level;
+ if (txp_type != sdata->vif.bss_conf.txpower_type)
+ update_txp_type = true;
+ sdata->vif.bss_conf.txpower_type = txp_type;
+
+ ieee80211_recalc_txpower(sdata, update_txp_type);
+ }
+ }
+
return 0;
}
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index c7f93fd9ca7a..4d82fe7d627c 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -165,7 +165,8 @@ static inline void drv_bss_info_changed(struct ieee80211_local *local,
if (WARN_ON_ONCE(sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE ||
sdata->vif.type == NL80211_IFTYPE_NAN ||
(sdata->vif.type == NL80211_IFTYPE_MONITOR &&
- !sdata->vif.mu_mimo_owner)))
+ !sdata->vif.mu_mimo_owner &&
+ !(changed & BSS_CHANGED_TXPOWER))))
return;
if (!check_sdata_in_driver(sdata))