aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/cfg.c
diff options
context:
space:
mode:
authorPeter Große <pegro@friiks.de>2017-12-13 12:29:46 -0500
committerJohannes Berg <johannes.berg@intel.com>2018-01-04 09:27:48 -0500
commit3a3713ec360138f806c6fc368d1de570f692b347 (patch)
tree68f4ae3b6753666bc31d9d0129f1e76fab4ad3d4 /net/mac80211/cfg.c
parent983dafaab799511e092ffd006f3a064b37ccbccf (diff)
mac80211: Fix setting TX power on monitor interfaces
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>
Diffstat (limited to 'net/mac80211/cfg.c')
-rw-r--r--net/mac80211/cfg.c28
1 files changed, 27 insertions, 1 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index b77ee342b5f8..46028e12e216 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -2376,10 +2376,17 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy,
2376 struct ieee80211_sub_if_data *sdata; 2376 struct ieee80211_sub_if_data *sdata;
2377 enum nl80211_tx_power_setting txp_type = type; 2377 enum nl80211_tx_power_setting txp_type = type;
2378 bool update_txp_type = false; 2378 bool update_txp_type = false;
2379 bool has_monitor = false;
2379 2380
2380 if (wdev) { 2381 if (wdev) {
2381 sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); 2382 sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
2382 2383
2384 if (sdata->vif.type == NL80211_IFTYPE_MONITOR) {
2385 sdata = rtnl_dereference(local->monitor_sdata);
2386 if (!sdata)
2387 return -EOPNOTSUPP;
2388 }
2389
2383 switch (type) { 2390 switch (type) {
2384 case NL80211_TX_POWER_AUTOMATIC: 2391 case NL80211_TX_POWER_AUTOMATIC:
2385 sdata->user_power_level = IEEE80211_UNSET_POWER_LEVEL; 2392 sdata->user_power_level = IEEE80211_UNSET_POWER_LEVEL;
@@ -2418,15 +2425,34 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy,
2418 2425
2419 mutex_lock(&local->iflist_mtx); 2426 mutex_lock(&local->iflist_mtx);
2420 list_for_each_entry(sdata, &local->interfaces, list) { 2427 list_for_each_entry(sdata, &local->interfaces, list) {
2428 if (sdata->vif.type == NL80211_IFTYPE_MONITOR) {
2429 has_monitor = true;
2430 continue;
2431 }
2421 sdata->user_power_level = local->user_power_level; 2432 sdata->user_power_level = local->user_power_level;
2422 if (txp_type != sdata->vif.bss_conf.txpower_type) 2433 if (txp_type != sdata->vif.bss_conf.txpower_type)
2423 update_txp_type = true; 2434 update_txp_type = true;
2424 sdata->vif.bss_conf.txpower_type = txp_type; 2435 sdata->vif.bss_conf.txpower_type = txp_type;
2425 } 2436 }
2426 list_for_each_entry(sdata, &local->interfaces, list) 2437 list_for_each_entry(sdata, &local->interfaces, list) {
2438 if (sdata->vif.type == NL80211_IFTYPE_MONITOR)
2439 continue;
2427 ieee80211_recalc_txpower(sdata, update_txp_type); 2440 ieee80211_recalc_txpower(sdata, update_txp_type);
2441 }
2428 mutex_unlock(&local->iflist_mtx); 2442 mutex_unlock(&local->iflist_mtx);
2429 2443
2444 if (has_monitor) {
2445 sdata = rtnl_dereference(local->monitor_sdata);
2446 if (sdata) {
2447 sdata->user_power_level = local->user_power_level;
2448 if (txp_type != sdata->vif.bss_conf.txpower_type)
2449 update_txp_type = true;
2450 sdata->vif.bss_conf.txpower_type = txp_type;
2451
2452 ieee80211_recalc_txpower(sdata, update_txp_type);
2453 }
2454 }
2455
2430 return 0; 2456 return 0;
2431} 2457}
2432 2458