diff options
| author | Peter Große <pegro@friiks.de> | 2017-12-13 12:29:46 -0500 |
|---|---|---|
| committer | Johannes Berg <johannes.berg@intel.com> | 2018-01-04 09:27:48 -0500 |
| commit | 3a3713ec360138f806c6fc368d1de570f692b347 (patch) | |
| tree | 68f4ae3b6753666bc31d9d0129f1e76fab4ad3d4 /net/mac80211/cfg.c | |
| parent | 983dafaab799511e092ffd006f3a064b37ccbccf (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.c | 28 |
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 | ||
