Handling user regdom hints while having intersected world regdom

2018-09-28 Thread Peter Große
Hi.

When a setup has multiple wifi cards anounncing different regdoms, the
regularitory subsystem stores an intersected world regdom using aplha2 "98".

I wonder what the correct result should be, when I call "iw reg set 00" or with
any other country code?

Because in my system with multiple cards nothing happened.

I added a lot of debug messages and I found the request is rejected with
REG_REQ_IGNORE in __reg_process_hint_user (in net/wireless/reg.c:2371).

In this check, last_request is considered (the request before my user request),
which in my case was the driver request for the second card leading to the
intersected regdom. But since "98" doesn't match the regdom provided by the
driver, the check returns true and the request gets rejected.

The comment above the check mentions not yet processed requests, but I doubt
that checking the current regdom against the last_request regdom helps in my
case. But from reading the code I got there is a "processed" flag for each
requst.

So maybe a patch like below is enough? Or are there more things to consider?
Or maybe I'm wrong and the current behavior is intended?!

Regards
Peter

diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 4fc66a117b7d..ed4543c7b255 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -2428,15 +2428,15 @@ __reg_process_hint_user(struct regulatory_request
*user_request) /*
 * Process user requests only after previous user/driver/core
 * requests have been processed
 */
if ((lr->initiator == NL80211_REGDOM_SET_BY_CORE ||
 lr->initiator == NL80211_REGDOM_SET_BY_DRIVER ||
 lr->initiator == NL80211_REGDOM_SET_BY_USER) &&
-   regdom_changes(lr->alpha2))
+   !lr->processed)
return REG_REQ_IGNORE;
 
if (!regdom_changes(user_request->alpha2))
return REG_REQ_ALREADY_SET;
 
return REG_REQ_OK;
 }


pgpcSQrLCxKCS.pgp
Description: OpenPGP digital signature


[PATCH] ath9k: spelling s/premble/preamble/

2018-03-06 Thread Peter Große
Signed-off-by: Peter Große <pe...@friiks.de>
---
 drivers/net/wireless/ath/ath9k/common-init.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath9k/common-init.c 
b/drivers/net/wireless/ath/ath9k/common-init.c
index 8b4f7fdabf58..82de0fadbc95 100644
--- a/drivers/net/wireless/ath/ath9k/common-init.c
+++ b/drivers/net/wireless/ath/ath9k/common-init.c
@@ -88,7 +88,7 @@ static const struct ieee80211_channel ath9k_5ghz_chantable[] 
= {
CHAN5G(5825, 37), /* Channel 165 */
 };
 
-/* Atheros hardware rate code addition for short premble */
+/* Atheros hardware rate code addition for short preamble */
 #define SHPCHECK(__hw_rate, __flags) \
((__flags & IEEE80211_RATE_SHORT_PREAMBLE) ? (__hw_rate | 0x04 ) : 0)
 
-- 
2.16.1



[PATCH] mac80211: Fix setting TX power on monitor interfaces

2017-12-13 Thread Peter Große
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   O4.12.12-gentoo #2 task:
 880186fd5cc0 task.stack: c90001b54000 RIP:
 0010:ieee80211_bss_info_change_notify+0x111/0x190 RSP: 0018:c90001b57a10
 EFLAGS: 00010246 RAX: 0006 RBX: 8801052ce840 RCX:
 0064 RDX: fffc RSI: 0004 RDI:
 8801052ce840 RBP: c90001b57a38 R08: 0062 R09:
  R10: 8802144b5000 R11: 880049dc4614 R12:
 0004 R13: 0064 R14: 8802105f0760 R15:
 c90001b57b48 FS:  7f92644b4580() GS:88021e20()
 knlGS: CS:  0010 DS:  ES:  CR0: 80050033
 CR2: 7f9263c109f0 CR3: 0001df85 CR4: 000406f0
 Call Trace:
  ieee80211_recalc_txpower+0x33/0x40
  ieee80211_set_tx_power+0x40/0x180
  nl80211_set_wiphy+0x32e/0x950

Reported-by: Peter Große <pe...@friiks.de>
Signed-off-by: Peter Große <pe...@friiks.de>
---

Since monitor_sdata->vif.type is also NL80211_IFTYPE_MONITOR,
the warning would still appear with the patch to cfg.c, so I excluded 
that case from the WARN_ON_ONCE condition.

I hope that makes sense?!

It fixes the warning for me though.

Regards
Peter

 net/mac80211/cfg.c| 28 +++-
 net/mac80211/driver-ops.h |  3 ++-
 2 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index a354f1939e49..29874052e162 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(>iflist_mtx);
list_for_each_entry(sdata, >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, >interfaces, list)
+   list_for_each_entry(sdata, >interfaces, list) {
+   if (sdata->vif.type == NL80211_IFTYPE_MONITOR)
+   continue;
ieee80211_recalc_txpower(sdata, update_txp_type);
+   }
mutex_unlock(>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 09f77e4a8a79..49c8a9c9b91f 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -164,7 +164,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_IFT

[PATCH] ocb: Use common freqchan helper for setting the operating channel

2017-12-13 Thread Peter Große
Simplify code by using the helper which has been introduced earlier.

Signed-off-by: Peter Große <pe...@friiks.de>
---

Mh, the patch is against the full tree of iw, not the kernel, so there is no
net/wireless/ path.

But yeah, whitespace got mangled.

Regards
Peter

 ocb.c | 50 --
 1 file changed, 8 insertions(+), 42 deletions(-)

diff --git a/ocb.c b/ocb.c
index bcf0474..dfdaf59 100644
--- a/ocb.c
+++ b/ocb.c
@@ -10,56 +10,22 @@ static int join_ocb(struct nl80211_state *state,
struct nl_msg *msg, int argc, char **argv,
enum id_input id)
 {
-   unsigned long freq;
-   char *end;
-   unsigned int i;
-   const struct chanmode *chanmode_selected = NULL;
-   static const struct chanmode chanmode[] = {
-   { .name = "5MHz",
- .width = NL80211_CHAN_WIDTH_5,
- .freq1_diff = 0,
- .chantype = -1 },
-   { .name = "10MHz",
- .width = NL80211_CHAN_WIDTH_10,
- .freq1_diff = 0,
- .chantype = -1 },
-   };
+   struct chandef chandef;
+   int err, parsed;
 
if (argc < 2)
return 1;
 
-   /* freq */
-   freq = strtoul(argv[0], , 10);
-   if (*end != '\0')
-   return 1;
-
-   NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq);
-   argv++;
-   argc--;
+   err = parse_freqchan(, false, argc, argv, );
 
-   /* channel width */
-   for (i = 0; i < ARRAY_SIZE(chanmode); i++) {
-   if (strcasecmp(chanmode[i].name, argv[0]) == 0) {
-   chanmode_selected = [i];
-   break;
-   }
-   }
-   if (chanmode_selected) {
-   NLA_PUT_U32(msg, NL80211_ATTR_CHANNEL_WIDTH,
-   chanmode_selected->width);
-   NLA_PUT_U32(msg, NL80211_ATTR_CENTER_FREQ1,
-   get_cf1(chanmode_selected, freq));
+   if (err)
+   return err;
 
-   argv++;
-   argc--;
-   } else {
-   return 1;
-   }
+   put_chandef(msg, );
+   if (err)
+   return err;
 
return 0;
-
-nla_put_failure:
-   return -ENOBUFS;
 }
 COMMAND(ocb, join, " <5MHz|10MHz>",
NL80211_CMD_JOIN_OCB, 0, CIB_NETDEV, join_ocb,
-- 
2.13.6



Re: Setting TX power on a monitoring interface

2017-12-01 Thread Peter Große
Hi Johannes,

On Fri, 01 Dec 2017 15:49:02 +0100
Johannes Berg <johan...@sipsolutions.net> wrote:

> On Mon, 2017-11-27 at 16:07 +0100, Peter Große wrote:
> 
> > > I think if the driver has WANT_MONITOR_VIF, then we can pass that
> > > through and let the driver sort it out.
> > > 
> > > But if not, we probably just have to reject the configuration?  
> > 
> > With passing through you mean calling bss_info_changed on the driver for the
> > monitor interface?  
> 
> I meant to pass the _sdata.vif pointer instead of the real
> monitor interface that's coming through cfg80211. The former is virtual
> and has no netdev, but the diver is aware of it.

I'm not sure I get where to pass this to what. Do you mean in
drv_bss_info_changed or ieee80211_set_tx_power?

> You can check that
> 
>   local->monitor_sdata
> 
> exists, and use it if yes, and reject if no.

Assuming you meant ieee80211_set_tx_power, then I'd have to check whether wdev
is a monitor interface and reject the configuration, if local->monitor_sdata
doesn't exist?

But in ieee80211_set_tx_power no vif pointers get handed around, so I'm
confused. Sorry.

Regards 
Peter


pgpectvX1rNHV.pgp
Description: OpenPGP digital signature


Re: Setting TX power on a monitoring interface

2017-11-27 Thread Peter Große
On Mon, 27 Nov 2017 12:43:13 +0100
Johannes Berg  wrote:

> > What would be the correct way of fixing it? Maybe I can provide a patch.  
> 
> That's a really good question :-)
> 
> I think if the driver has WANT_MONITOR_VIF, then we can pass that
> through and let the driver sort it out.
>
> But if not, we probably just have to reject the configuration?

With passing through you mean calling bss_info_changed on the driver for the
monitor interface?

Are monitor interfaces allowed to exist when WANT_MONITOR_VIF is not set?
I ask, whether I would have to check 
  sdata->vif.type == NL80211_IFTYPE_MONITOR
_and_ also
  ieee80211_hw_check(>hw, WANT_MONITOR_VIF)
?

Regards
Peter


pgpjak_9TtR1A.pgp
Description: OpenPGP digital signature


Setting TX power on a monitoring interface

2017-11-20 Thread Peter Große
Hi everyone.

The iw tool allows to set TX power settings on network interfaces.

If I try to set the TX power level on a _monitor_ interface, I get
a kernel 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   O4.12.12-gentoo #2 task:
 880186fd5cc0 task.stack: c90001b54000 RIP:
 0010:ieee80211_bss_info_change_notify+0x111/0x190 RSP: 0018:c90001b57a10
 EFLAGS: 00010246 RAX: 0006 RBX: 8801052ce840 RCX:
 0064 RDX: fffc RSI: 0004 RDI:
 8801052ce840 RBP: c90001b57a38 R08: 0062 R09:
  R10: 8802144b5000 R11: 880049dc4614 R12:
 0004 R13: 0064 R14: 8802105f0760 R15:
 c90001b57b48 FS:  7f92644b4580() GS:88021e20()
 knlGS: CS:  0010 DS:  ES:  CR0: 80050033
 CR2: 7f9263c109f0 CR3: 0001df85 CR4: 000406f0
 Call Trace:
  ieee80211_recalc_txpower+0x33/0x40
  ieee80211_set_tx_power+0x40/0x180
  nl80211_set_wiphy+0x32e/0x950

Steps to reproduce:

  iw dev wlan0 interface add mon0 type monitor
  ip link set dev mon0 up
  iw dev mon0 set txpower fixed 100

Is that a bug to be fixed?
What would be the correct way of fixing it? Maybe I can provide a patch.

Regards
Peter


pgp6Im04oFYlV.pgp
Description: OpenPGP digital signature


[PATCH 1/1] ocb: Use common freqchan helper for setting the operating channel

2017-10-27 Thread Peter Große
Simplify code by using the helper which has been introduced earlier.

Signed-off-by: Peter Große <pe...@friiks.de>
---
 ocb.c | 50 --
 1 file changed, 8 insertions(+), 42 deletions(-)

diff --git a/ocb.c b/ocb.c
index bcf0474..dfdaf59 100644
--- a/ocb.c
+++ b/ocb.c
@@ -10,56 +10,22 @@ static int join_ocb(struct nl80211_state *state,
struct nl_msg *msg, int argc, char **argv,
enum id_input id)
 {
-   unsigned long freq;
-   char *end;
-   unsigned int i;
-   const struct chanmode *chanmode_selected = NULL;
-   static const struct chanmode chanmode[] = {
-   { .name = "5MHz",
- .width = NL80211_CHAN_WIDTH_5,
- .freq1_diff = 0,
- .chantype = -1 },
-   { .name = "10MHz",
- .width = NL80211_CHAN_WIDTH_10,
- .freq1_diff = 0,
- .chantype = -1 },
-   };
+   struct chandef chandef;
+   int err, parsed;
 
if (argc < 2)
return 1;
 
-   /* freq */
-   freq = strtoul(argv[0], , 10);
-   if (*end != '\0')
-   return 1;
-
-   NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq);
-   argv++;
-   argc--;
+   err = parse_freqchan(, false, argc, argv, );
 
-   /* channel width */
-   for (i = 0; i < ARRAY_SIZE(chanmode); i++) {
-   if (strcasecmp(chanmode[i].name, argv[0]) == 0) {
-   chanmode_selected = [i];
-   break;
-   }
-   }
-   if (chanmode_selected) {
-   NLA_PUT_U32(msg, NL80211_ATTR_CHANNEL_WIDTH,
-   chanmode_selected->width);
-   NLA_PUT_U32(msg, NL80211_ATTR_CENTER_FREQ1,
-   get_cf1(chanmode_selected, freq));
+   if (err)
+   return err;
 
-   argv++;
-   argc--;
-   } else {
-   return 1;
-   }
+   put_chandef(msg, );
+   if (err)
+   return err;
 
return 0;
-
-nla_put_failure:
-   return -ENOBUFS;
 }
 COMMAND(ocb, join, " <5MHz|10MHz>",
NL80211_CMD_JOIN_OCB, 0, CIB_NETDEV, join_ocb,
-- 
2.13.6