Re: [PATCH] ath9k_hw: fix channel maximum power level test

2017-04-07 Thread Weedy
On 22 March 2017 at 15:42, Felix Fietkau  wrote:
> The tx power applied by set_txpower is limited by the CTL (conformance
> test limit) entries in the EEPROM. These can change based on the user
> configured regulatory domain.
> Depending on the EEPROM data this can cause the tx power to become too
> limited, if the original regdomain CTLs impose lowr limits than the CTLs
> of the user configured regdomain.

When merged, should this this fix this annoyance? Or is TP-Link just
shipping junk cal data?

root@LEDE:~# iw phy
Wiphy phy1
...
Frequencies:
* 5180 MHz [36] (21.0 dBm)
* 5200 MHz [40] (21.0 dBm)
* 5220 MHz [44] (21.0 dBm)
* 5240 MHz [48] (21.0 dBm)
* 5260 MHz [52] (21.0 dBm) (radar detection)
* 5280 MHz [56] (21.0 dBm) (radar detection)
* 5300 MHz [60] (21.0 dBm) (radar detection)
* 5320 MHz [64] (21.0 dBm) (radar detection)
* 5500 MHz [100] (21.0 dBm) (radar detection)
* 5520 MHz [104] (21.0 dBm) (radar detection)
* 5540 MHz [108] (21.0 dBm) (radar detection)
* 5560 MHz [112] (21.0 dBm) (radar detection)
* 5580 MHz [116] (21.0 dBm) (radar detection)
* 5600 MHz [120] (disabled)
* 5620 MHz [124] (disabled)
* 5640 MHz [128] (disabled)
* 5660 MHz [132] (21.0 dBm) (radar detection)
* 5680 MHz [136] (21.0 dBm) (radar detection)
* 5700 MHz [140] (21.0 dBm) (radar detection)
* 5745 MHz [149] (21.0 dBm)
* 5765 MHz [153] (21.0 dBm)
* 5785 MHz [157] (21.0 dBm)
* 5805 MHz [161] (21.0 dBm)
* 5825 MHz [165] (21.0 dBm)
root@LEDE:~# iw reg get
global
country CA: DFS-FCC
(2402 - 2472 @ 40), (N/A, 30), (N/A)
(5150 - 5250 @ 80), (N/A, 23), (N/A), AUTO-BW
(5250 - 5350 @ 80), (N/A, 24), (0 ms), DFS, AUTO-BW
(5470 - 5600 @ 80), (N/A, 24), (0 ms), DFS
(5650 - 5730 @ 80), (N/A, 24), (0 ms), DFS
(5735 - 5835 @ 80), (N/A, 30), (N/A)

phy#1
country US: DFS-FCC
(2402 - 2472 @ 40), (N/A, 30), (N/A)
(5170 - 5250 @ 80), (N/A, 23), (N/A), AUTO-BW
(5250 - 5330 @ 80), (N/A, 23), (0 ms), DFS, AUTO-BW
(5490 - 5730 @ 160), (N/A, 23), (0 ms), DFS
(5735 - 5835 @ 80), (N/A, 30), (N/A)
(57240 - 63720 @ 2160), (N/A, 40), (N/A)

root@LEDE:~# iw phy phy1 set txpower fixed 1500
root@LEDE:~# iwinfo
wlan1 ESSID: nah
  Access Point: still nah
  Mode: Master  Channel: 48 (5.240 GHz)
  Tx-Power: 15 dBm  Link Quality: 44/70
  Signal: -66 dBm  Noise: -90 dBm
  Bit Rate: 147.5 MBit/s
  Encryption: WPA2 PSK (CCMP)
  Type: nl80211  HW Mode(s): 802.11an
  Hardware: 168C:0033 168C:A120 [Atheros AR9580]
  TX power offset: none
  Frequency offset: none
  Supports VAPs: yes  PHY name: phy1

root@LEDE:~# iw phy phy1 set txpower fixed 2000
root@LEDE:~# iwinfo
wlan1 ESSID: nah
  Access Point: still nah
  Mode: Master  Channel: 48 (5.240 GHz)
  Tx-Power: 17 dBm  Link Quality: 45/70
  Signal: -65 dBm  Noise: -90 dBm
  Bit Rate: 177.5 MBit/s
  Encryption: WPA2 PSK (CCMP)
  Type: nl80211  HW Mode(s): 802.11an
  Hardware: 168C:0033 168C:A120 [Atheros AR9580]
  TX power offset: none
  Frequency offset: none
  Supports VAPs: yes  PHY name: phy1


[PATCH] staging: wilc1000: fix incorrect strncasecmp length

2017-04-07 Thread Colin King
From: Colin Ian King 

The strncasecmp of buff against the literal string RSSI
is using variable length which is zero. This should be instead
using the variable size instead.  Also remove the redundant
variable length.

Detected by PVS-Studio, warning: V575

Signed-off-by: Colin Ian King 
---
 drivers/staging/wilc1000/linux_wlan.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/wilc1000/linux_wlan.c 
b/drivers/staging/wilc1000/linux_wlan.c
index 2eebc6215cac..6aeaf19182e7 100644
--- a/drivers/staging/wilc1000/linux_wlan.c
+++ b/drivers/staging/wilc1000/linux_wlan.c
@@ -1074,7 +1074,7 @@ static int mac_ioctl(struct net_device *ndev, struct 
ifreq *req, int cmd)
 {
u8 *buff = NULL;
s8 rssi;
-   u32 size = 0, length = 0;
+   u32 size = 0;
struct wilc_vif *vif;
s32 ret = 0;
struct wilc *wilc;
@@ -1098,7 +1098,7 @@ static int mac_ioctl(struct net_device *ndev, struct 
ifreq *req, int cmd)
if (IS_ERR(buff))
return PTR_ERR(buff);
 
-   if (strncasecmp(buff, "RSSI", length) == 0) {
+   if (strncasecmp(buff, "RSSI", size) == 0) {
ret = wilc_get_rssi(vif, &rssi);
netdev_info(ndev, "RSSI :%d\n", rssi);
 
-- 
2.11.0



Re: brcmfmac: don't warn user if requested nvram fails

2017-04-07 Thread Arend Van Spriel


On 6-4-2017 14:14, Hans de Goede wrote:
> Hi,
> 
> I noticed your patch-series on the lwn.net kernel page,
> and I took a peek :)
> 
> I don't think that this patch:
> 
> https://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/linux-next.git/commit/?h=20170329-driver-data-v2-try3&id=3968dd3031d1ff7e7be4acfb810948c70c2d4490
> 
> 
> Is a good idea, specifically the "do not warn" part,
> although the brcmfmac driver will indeed try to continue
> without a nvram file, in my experience it almost all
> the time will not work properly without the nvram file.

Actually, brcmfmac will only continue without nvram for PCIe devices.
For SDIO it is a different story, which may be the kind of devices you
have experienced.

> Arend, should we maybe just make the missing nvram file
> a fatal error ?
> 
> ###
> 
> While on the subject of nvram file loading, I want to make
> some changes to how brcmfmac does this, for pcie
> devices I want it to first try:
> 
> brcmfmac-4xxx-sdio--.txt
> and only if that is not present fallback to
> brcmfmac-4xxx-sdio.txt, so that we can include the
> brcmfmac-4xxx-sdio--.txt
> in the linux-firmware repo and have things just work.

You got me confused. I suppose the -sdio- should not be in the filename
examples above. So who is going to provide these nvram files. We can not
maintain that as there are too many variants and they are under control
of the OEM/ODM.

> Likewise for sdio devices on devicetree platforms
> first try brcmfmac-4xxx-sdio-.txt.
> 
> And for sdio devices on ACPI/x86 systems I want to
> do something similar too.
> 
> Luis, do you think it would be a good idea to add
> .optional_postfix member to driver_data_req_params
> for this? I believe other sdio based wifi devices
> may want to do the same, or should this be handled
> in the driver by doing 2 driver_data_request_async
> calls (the 2nd when the 1st fails) ?

I think we briefly touched this subject a while ago. It would be great
if the driver_data api could be given a list/array of files which can be
flagged as required or optional. Just not sure how to deal with drivers
that request a firmware file and fallback to requesting older ones
repeatedly thus stop processing upon first successful load. Both
use-cases seem present in drivers.

Regards,
Arend

> Regards,
> 
> Hans
> 
> 


Re: [RFC 0/3] netlink: extended error reporting

2017-04-07 Thread Johannes Berg
On Fri, 2017-04-07 at 12:55 -0700, David Miller wrote:
> 
> One idea.  We use the macro thing to generate a "netlink.pot" file
> and then some userland tree can contain the latest netlink.pot and
> the translations.

Right. For the record - since we just talked about it - I was thinking
of putting it into a special section so that we could easily write a
script to generate the pot file from the kernel binary after doing
"allyesconfig" or collecting it from modules or so.

Thinking of modules though - do we need to adjust the module loading
code to load a new section? I'll have to look into that.

johannes


Re: [RFC 0/3] netlink: extended error reporting

2017-04-07 Thread David Miller
From: Johannes Berg 
Date: Fri, 07 Apr 2017 21:46:46 +0200

> On Fri, 2017-04-07 at 12:43 -0700, David Miller wrote:
>> I suspect that someone will eventually give us a hard time about the
>> strings wrt. internationalization. :-) It's solvable at least
>> partially in userspace I suppose.
> 
> I tend to think of the strings more of a debugging aid, but that's a
> good point.
> 
> Perhaps we should have a macro that has the strings - similar to the
> inline function I put into netlink - but if we make that a macro we can
> put the strings into a separate section to be able to find them more
> easily for later translation, and optionally even omit them entirely
> (to satisfy the kernel tinification folks)?

One idea.  We use the macro thing to generate a "netlink.pot" file and
then some userland tree can contain the latest netlink.pot and the
translations.

I'm suggesting it this way because whilst putting the netlink.pot file
in the kernel tree is probably OK, putting all the translation there
might not be.


Re: [RFC 0/3] netlink: extended error reporting

2017-04-07 Thread Johannes Berg
On Fri, 2017-04-07 at 21:45 +0200, Pablo Neira Ayuso wrote:
> 
> We only need to store the pointer to the attribute in the error
> container structure. We can calculate the offset from nl_err() by
> pasing the skbuff as parameter there, right?

Ah, that's a good point, we could store the nlattr pointer and
calculate the offset later. I'll need to try this, but yeah, good idea!

johannes


Re: [RFC 0/3] netlink: extended error reporting

2017-04-07 Thread Johannes Berg
On Fri, 2017-04-07 at 12:43 -0700, David Miller wrote:
> 
> I have no strong opinions about string length.
> 
> In my opinion, I would like to believe that if someone tried to get a
> networking patch applied that emitted a rediculously long string then
> we would give them feedback about how that is not acceptable.  Right?

Agree with this, I don't really see much point in adding an extra
warning. There's an implicit (multi-KB though) limit as well in the
message size ;-)

> I suspect that someone will eventually give us a hard time about the
> strings wrt. internationalization. :-) It's solvable at least
> partially in userspace I suppose.

I tend to think of the strings more of a debugging aid, but that's a
good point.

Perhaps we should have a macro that has the strings - similar to the
inline function I put into netlink - but if we make that a macro we can
put the strings into a separate section to be able to find them more
easily for later translation, and optionally even omit them entirely
(to satisfy the kernel tinification folks)?

johannes


Re: [RFC 0/3] netlink: extended error reporting

2017-04-07 Thread Pablo Neira Ayuso
On Fri, Apr 07, 2017 at 09:29:17PM +0200, Johannes Berg wrote:
> On Fri, 2017-04-07 at 21:21 +0200, Pablo Neira Ayuso wrote:
> > I think the most flexible way is to pass the container error
> > structure to nla_parse() so it sets this for you. This would also
> > save tons of "malformed attribute" strings.
> 
> Yes, for sure. The thing is we'll probalby have to pass down the
> request skb *and* the error struct so that we can get the offset, and
> this seems like the generic thing that we really should try to get the
> most information generated.

We only need to store the pointer to the attribute in the error
container structure. We can calculate the offset from nl_err() by
pasing the skbuff as parameter there, right?


[RFC] netlink: send exterr cookie on success

2017-04-07 Thread Johannes Berg
From: Johannes Berg 

This is for Jamal, it allows the subsystem to return an arbitrary
cookie to identify a new object/operation, perhaps to delete or
cancel it later.

This is actually something we use a lot in wifi too, though I'm
not sure how we could do the backport necessary for that (since
we sadly need to ship to all kinds of old kernels)

Also contains the missing (err) check I pointed out - I'll squash
this patch into the first of the exterr after I test it.

Signed-off-by: Johannes Berg 
---
 include/linux/netlink.h  |  2 ++
 include/uapi/linux/netlink.h |  4 
 net/netlink/af_netlink.c | 28 +++-
 3 files changed, 25 insertions(+), 9 deletions(-)

diff --git a/include/linux/netlink.h b/include/linux/netlink.h
index 662f343dc68b..76a0b0a22349 100644
--- a/include/linux/netlink.h
+++ b/include/linux/netlink.h
@@ -67,6 +67,8 @@ struct netlink_ext_err {
u32 ext_code;
u32 msg_offset;
u16 attr;
+   const u8 *cookie;
+   u8 cookie_len;
 };
 
 extern void netlink_kernel_release(struct sock *sk);
diff --git a/include/uapi/linux/netlink.h b/include/uapi/linux/netlink.h
index 0ef970e6f9f5..72a398e0f332 100644
--- a/include/uapi/linux/netlink.h
+++ b/include/uapi/linux/netlink.h
@@ -119,6 +119,9 @@ struct nlmsgerr {
  * @NLMSGERR_ATTR_CODE: extended per-subsystem error code (u32)
  * @NLMSGERR_ATTR_ATTR: top-level attribute that caused the error
  * (or is missing, u16)
+ * @NLMSGERR_ATTR_COOKIE: arbitrary subsystem specific cookie to
+ * be used - in the success case - to identify a created
+ * object or operation or similar (binary)
  */
 enum nlmsgerr_attrs {
NLMSGERR_ATTR_UNUSED,
@@ -126,6 +129,7 @@ enum nlmsgerr_attrs {
NLMSGERR_ATTR_OFFS,
NLMSGERR_ATTR_CODE,
NLMSGERR_ATTR_ATTR,
+   NLMSGERR_ATTR_COOKIE,
 };
 
 #define NETLINK_ADD_MEMBERSHIP 1
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 532d906af3be..6b256e540bc1 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -2277,6 +2277,9 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr 
*nlh, int err,
if (exterr && exterr->attr)
payload += nla_total_size(sizeof(u16));
}
+   } else if (nlk->flags & NETLINK_F_EXT_ACK) {
+   if (exterr && exterr->cookie_len)
+   payload += nla_total_size(exterr->cookie_len);
}
 
skb = nlmsg_new(payload, GFP_KERNEL);
@@ -2301,15 +2304,22 @@ void netlink_ack(struct sk_buff *in_skb, struct 
nlmsghdr *nlh, int err,
memcpy(&errmsg->msg, nlh, payload > sizeof(*errmsg) ? nlh->nlmsg_len : 
sizeof(*nlh));
 
if (nlk->flags & NETLINK_F_EXT_ACK) {
-   if (exterr && exterr->msg)
-   WARN_ON(nla_put_string(skb, NLMSGERR_ATTR_MSG,
-  exterr->msg));
-   if (exterr && exterr->msg_offset)
-   WARN_ON(nla_put_u32(skb, NLMSGERR_ATTR_OFFS,
-   exterr->msg_offset));
-   if (exterr && exterr->attr)
-   WARN_ON(nla_put_u16(skb, NLMSGERR_ATTR_ATTR,
-   exterr->attr));
+   if (err) {
+   if (exterr && exterr->msg)
+   WARN_ON(nla_put_string(skb, NLMSGERR_ATTR_MSG,
+  exterr->msg));
+   if (exterr && exterr->msg_offset)
+   WARN_ON(nla_put_u32(skb, NLMSGERR_ATTR_OFFS,
+   exterr->msg_offset));
+   if (exterr && exterr->attr)
+   WARN_ON(nla_put_u16(skb, NLMSGERR_ATTR_ATTR,
+   exterr->attr));
+   } else {
+   if (exterr && exterr->attr)
+   WARN_ON(nla_put(skb, NLMSGERR_ATTR_COOKIE,
+   exterr->cookie_len,
+   exterr->cookie));
+   }
}
 
netlink_unicast(in_skb->sk, skb, NETLINK_CB(in_skb).portid, 
MSG_DONTWAIT);
-- 
2.11.0



Re: [RFC 0/3] netlink: extended error reporting

2017-04-07 Thread David Miller
From: Pablo Neira Ayuso 
Date: Fri, 7 Apr 2017 21:35:50 +0200

> On Fri, Apr 07, 2017 at 12:20:53PM -0700, David Miller wrote:
> [...]
>> Let's just discuss the UAPI, since people complain we don't talk
>> about that enough :-)  For those playing at home it is three new
>> attributes returned in a netlink ACK when the application asks
>> for the extended response:
>> 
>>  NLMSGERR_ATTR_MSG   string  Extended error string
>>  NLMSGERR_ATTR_OFFS  u32 Byte offset to netlink element causing 
>> error
>>  NLMSGERR_ATTR_CODE  u32 Subsystem specific error code
>>  NLMSGERR_ATTR_ATTR  u16 Netlink attribute triggering error or 
>> missing
> 
> I think it would be good if we get a definition to cap the maximum
> string length to something reasonable? This can be added in a follow
> up patch BTW. Thus, we get people coming back to us and request larger
> strings with a reason why they need more room for this.
> 
> In general, my main concern with strings is that they can be used in a
> more freely way than these u32 offsets and error codes, and
> specifically how inconsistent these string will look like across
> different netlink subsystems.
> 
> Anyway, as long as this is optional (not every subsystem if forced to
> use strings) I'm fine with it :).

I have no strong opinions about string length.

In my opinion, I would like to believe that if someone tried to get a
networking patch applied that emitted a rediculously long string then
we would give them feedback about how that is not acceptable.  Right?

I suspect that someone will eventually give us a hard time about the
strings wrt. internationalization. :-) It's solvable at least
partially in userspace I suppose.



Re: [RFC 1/3] netlink: extended error reporting

2017-04-07 Thread Johannes Berg
On Fri, 2017-04-07 at 20:26 +0200, Johannes Berg wrote:
> 
> + if (nlk->flags & NETLINK_F_EXT_ACK) {
> + if (exterr && exterr->msg)
> + WARN_ON(nla_put_string(skb,
> NLMSGERR_ATTR_MSG,
> +    exterr->msg));
> + if (exterr && exterr->msg_offset)
> + WARN_ON(nla_put_u32(skb, NLMSGERR_ATTR_OFFS,
> + exterr->msg_offset));
> + if (exterr && exterr->attr)
> + WARN_ON(nla_put_u16(skb, NLMSGERR_ATTR_ATTR,
> + exterr->attr));
> + }

I forgot to check (err != 0) here, which can cause inconsistencies -
noticed that while just adding the error case Jamal wanted. I'll send
out that as a separate patch, and squash it later when I resubmit.

johannes


Re: [RFC 0/3] netlink: extended error reporting

2017-04-07 Thread Pablo Neira Ayuso
On Fri, Apr 07, 2017 at 12:20:53PM -0700, David Miller wrote:
[...]
> Let's just discuss the UAPI, since people complain we don't talk
> about that enough :-)  For those playing at home it is three new
> attributes returned in a netlink ACK when the application asks
> for the extended response:
> 
>   NLMSGERR_ATTR_MSG   string  Extended error string
>   NLMSGERR_ATTR_OFFS  u32 Byte offset to netlink element causing 
> error
>   NLMSGERR_ATTR_CODE  u32 Subsystem specific error code
>   NLMSGERR_ATTR_ATTR  u16 Netlink attribute triggering error or 
> missing

I think it would be good if we get a definition to cap the maximum
string length to something reasonable? This can be added in a follow
up patch BTW. Thus, we get people coming back to us and request larger
strings with a reason why they need more room for this.

In general, my main concern with strings is that they can be used in a
more freely way than these u32 offsets and error codes, and
specifically how inconsistent these string will look like across
different netlink subsystems.

Anyway, as long as this is optional (not every subsystem if forced to
use strings) I'm fine with it :).


Re: [RFC 0/3] netlink: extended error reporting

2017-04-07 Thread David Miller
From: Pablo Neira Ayuso 
Date: Fri, 7 Apr 2017 21:21:34 +0200

> For my usecases in netfilter, the attributes and an specific error
> code should be enough to figure out what is wrong. Will not need
> strings.
> 
> BTW, we may not have an offset, eg. EINVAL because of missing
> attribute. Given we have different requirements, I would leave it to
> each subsystem to decide what netlink error attributes are specified.

Yep, completely agreed.

The use cases for offset and missing attribute I see as follows:

1) Top-level attribute is missing. Here, offset is set to zero
   and the missing attribute number is given as well.

2) Nested attribute is missing.  Offset is set to the location of the
   beginning of nesting, inside of which the missing attribute was
   needed.


Re: [RFC 0/3] netlink: extended error reporting

2017-04-07 Thread David Miller
From: Pablo Neira Ayuso 
Date: Fri, 7 Apr 2017 21:27:14 +0200

> On Fri, Apr 07, 2017 at 12:22:23PM -0700, David Miller wrote:
>> From: Johannes Berg 
>> Date: Fri, 07 Apr 2017 21:09:45 +0200
>> 
>> > On Fri, 2017-04-07 at 21:06 +0200, Pablo Neira Ayuso wrote:
>> >> On Fri, Apr 07, 2017 at 08:59:12PM +0200, Johannes Berg wrote:
>> >> [...]
>> >> > Heh. I think I really want to solve - at least partially -
>> >> > nla_parse()
>> >> > to see that it can be done this way. It'd be nice to even transform
>> >> > all
>> >> > the callers (I generated half of these patches with spatch anyway)
>> >> > to
>> >> > have at least that.
>> >> 
>> >> We can just have a modified version of nla_parse that deals with
>> >> this.
>> > 
>> > Yes, but we need to figure out a good way to have the offset.
>> > 
>> > We also need to see if we want to *force* having the offset. In some
>> > sense that'd be useful, in another it might be very complicated to fill
>> > it in at all times, if for example errors come from lower layers like
>> > drivers.
>> 
>> It has to be optional, some kinds of errors don't have an exact
>> context per-se.
>> 
>> Also another way to look at this is that we're providing a lot of
>> new power and expressability.  So even if only one aspect of the
>> new error reporting is used it's a positive step forward.
>> 
>> So allow offset "0" meaning "unspecified".
> 
> Instead, we can just not send the offset attribute to userspace if
> it's not specified. So missing attribute means "unspecified".

Agreed, not providing the attribute to indicate this is fine.


Re: [RFC 0/3] netlink: extended error reporting

2017-04-07 Thread Johannes Berg
On Fri, 2017-04-07 at 21:27 +0200, Pablo Neira Ayuso wrote:
> 
> > Also another way to look at this is that we're providing a lot of
> > new power and expressability.  So even if only one aspect of the
> > new error reporting is used it's a positive step forward.

True.

> > So allow offset "0" meaning "unspecified".
> 
> Instead, we can just not send the offset attribute to userspace if
> it's not specified. So missing attribute means "unspecified".
> 
> I'm always a bit worried this "0 means something" semantics :)

Yeah, I have that. If it's 0 internally the attribute will be omitted.

johannes


Re: [RFC 0/3] netlink: extended error reporting

2017-04-07 Thread Johannes Berg
On Fri, 2017-04-07 at 21:21 +0200, Pablo Neira Ayuso wrote:
> 
> For my usecases in netfilter, the attributes and an specific error
> code should be enough to figure out what is wrong. Will not need
> strings.

Fair enough.

> BTW, we may not have an offset, eg. EINVAL because of missing
> attribute. Given we have different requirements, I would leave it to
> each subsystem to decide what netlink error attributes are specified.
> 
> > (It's ultimately always going to be optional since we'll continue
> > returning errors without *any* extended error information - likely
> > indefinitely - but if we have a wrong attribute, should we always
> > have
> > an offset? Would be nice, but could be difficult in practice)
> > 
> > > We can probably use struct nla_policy to place the extended error
> > > code or the string (as we discussed I don't need string errors,
> > > but
> > > I'm fine if other people find it useful).
> > 
> > I don't think for the error strings really would be useful for
> > nla_parse() or a policy - we can return something generic like
> > "malformed attribute" there as a string, and hopefully point to the
> > attribute/offset from there generically. I just really want to see
> > how
> > to actually do that.
> 
> I think the most flexible way is to pass the container error
> structure to nla_parse() so it sets this for you. This would also
> save tons of "malformed attribute" strings.

Yes, for sure. The thing is we'll probalby have to pass down the
request skb *and* the error struct so that we can get the offset, and
this seems like the generic thing that we really should try to get the
most information generated.

johannes


Re: [RFC 0/3] netlink: extended error reporting

2017-04-07 Thread Pablo Neira Ayuso
On Fri, Apr 07, 2017 at 12:22:23PM -0700, David Miller wrote:
> From: Johannes Berg 
> Date: Fri, 07 Apr 2017 21:09:45 +0200
> 
> > On Fri, 2017-04-07 at 21:06 +0200, Pablo Neira Ayuso wrote:
> >> On Fri, Apr 07, 2017 at 08:59:12PM +0200, Johannes Berg wrote:
> >> [...]
> >> > Heh. I think I really want to solve - at least partially -
> >> > nla_parse()
> >> > to see that it can be done this way. It'd be nice to even transform
> >> > all
> >> > the callers (I generated half of these patches with spatch anyway)
> >> > to
> >> > have at least that.
> >> 
> >> We can just have a modified version of nla_parse that deals with
> >> this.
> > 
> > Yes, but we need to figure out a good way to have the offset.
> > 
> > We also need to see if we want to *force* having the offset. In some
> > sense that'd be useful, in another it might be very complicated to fill
> > it in at all times, if for example errors come from lower layers like
> > drivers.
> 
> It has to be optional, some kinds of errors don't have an exact
> context per-se.
> 
> Also another way to look at this is that we're providing a lot of
> new power and expressability.  So even if only one aspect of the
> new error reporting is used it's a positive step forward.
> 
> So allow offset "0" meaning "unspecified".

Instead, we can just not send the offset attribute to userspace if
it's not specified. So missing attribute means "unspecified".

I'm always a bit worried this "0 means something" semantics :)


Re: [RFC 2/3] genetlink: pass extended error report down

2017-04-07 Thread Ben Greear

On 04/07/2017 12:12 PM, Johannes Berg wrote:

On Fri, 2017-04-07 at 11:37 -0700, Ben Greear wrote:


I guess the error string must be constant and always available in
memory in this implementation?


Yes.


I think it would be nice to dynamically create strings (malloc,
snprintf, etc) and have the err_str logic free it when done?


We can think about that later, but I don't actually think it makes a
lot of sense - if we point to the attribute and/or offset you really
ought to have enough info to figure out what's up.


We can think about it later, but lots of things in the wifi stack
could use a descriptive message specific to the failure.  Often these
messages are much more useful if you explain why the failure conflicts
with regulatory, channel, virtual-dev combination, etc info, so that needs
to be dynamic.  The code that is failing knows, so I'd like to pass it
back to user-space.

Thanks,
Ben

--
Ben Greear 
Candela Technologies Inc  http://www.candelatech.com



Re: [RFC 0/3] netlink: extended error reporting

2017-04-07 Thread Johannes Berg
On Fri, 2017-04-07 at 12:20 -0700, David Miller wrote:

> But what it lacks fundamentally is context.  Therefore it can't be
> used to provide the offset or the bad attribute number.  So it can't
> meet our requirements.

Yes, it doesn't address the requirements here, and in a sense I suspect
this will be true anywhere else too - perhaps that's the reason why it
was never applied even over in perf. I've not gotten a good answer for
that question yet :)

> We've passed down new arguments into core method call chains for much
> less useful facilitites than this.  So that doesn't bother me.  And
> as that is a kernel internal matter, we can refine it later.

Yes, both are true.

> Wrt. nla_parse(), we can solve that problem as follow-on patches too.

Yes. I just want to be sure we can solve it, but OTOH we're not locking
down anything but the UAPI so whatever way we find to solve it, even if
it requires a complete rearchitecture internally, it still doesn't
matter.

> So I consider this change ready as far as the implementation is
> concerned.

Fair enough. I still do need to test it though :)

> Ok, Jiri, start reading.  I will try to make you happy here.
> 
> Let's just discuss the UAPI, since people complain we don't talk
> about that enough :-)  For those playing at home it is three new
> attributes returned in a netlink ACK when the application asks
> for the extended response:
> 
> NLMSGERR_ATTR_MSG   string  Extended error string
> NLMSGERR_ATTR_OFFS  u32 Byte offset to netlink
> element causing error
> NLMSGERR_ATTR_CODE  u32 Subsystem specific error code
> NLMSGERR_ATTR_ATTR  u16 Netlink attribute triggering
> error or missing

That's four ;-)

Since you're carefully listing it here, you should also say that

 * the new behaviour is entirely optional, enabled by a new netlink
   socket option
 * the ACK message format ends up being
   [nlmsg header]
   [ack header including errno]
   [request message nlmsg hdr]
   [request message payload - optional, controlled by socket option,
aligned to 4 byte length if present]
   [new TLVs - optional, controlled by socket option]

johannes


Re: [RFC 0/3] netlink: extended error reporting

2017-04-07 Thread David Miller
From: Johannes Berg 
Date: Fri, 07 Apr 2017 21:09:45 +0200

> On Fri, 2017-04-07 at 21:06 +0200, Pablo Neira Ayuso wrote:
>> On Fri, Apr 07, 2017 at 08:59:12PM +0200, Johannes Berg wrote:
>> [...]
>> > Heh. I think I really want to solve - at least partially -
>> > nla_parse()
>> > to see that it can be done this way. It'd be nice to even transform
>> > all
>> > the callers (I generated half of these patches with spatch anyway)
>> > to
>> > have at least that.
>> 
>> We can just have a modified version of nla_parse that deals with
>> this.
> 
> Yes, but we need to figure out a good way to have the offset.
> 
> We also need to see if we want to *force* having the offset. In some
> sense that'd be useful, in another it might be very complicated to fill
> it in at all times, if for example errors come from lower layers like
> drivers.

It has to be optional, some kinds of errors don't have an exact
context per-se.

Also another way to look at this is that we're providing a lot of
new power and expressability.  So even if only one aspect of the
new error reporting is used it's a positive step forward.

So allow offset "0" meaning "unspecified".


Re: [RFC 0/3] netlink: extended error reporting

2017-04-07 Thread Pablo Neira Ayuso
On Fri, Apr 07, 2017 at 09:09:45PM +0200, Johannes Berg wrote:
> On Fri, 2017-04-07 at 21:06 +0200, Pablo Neira Ayuso wrote:
> > On Fri, Apr 07, 2017 at 08:59:12PM +0200, Johannes Berg wrote:
> > [...]
> > > Heh. I think I really want to solve - at least partially -
> > > nla_parse()
> > > to see that it can be done this way. It'd be nice to even transform
> > > all
> > > the callers (I generated half of these patches with spatch anyway)
> > > to
> > > have at least that.
> > 
> > We can just have a modified version of nla_parse that deals with
> > this.
> 
> Yes, but we need to figure out a good way to have the offset.
> 
> We also need to see if we want to *force* having the offset. In some
> sense that'd be useful, in another it might be very complicated to fill
> it in at all times, if for example errors come from lower layers like
> drivers.

For my usecases in netfilter, the attributes and an specific error
code should be enough to figure out what is wrong. Will not need
strings.

BTW, we may not have an offset, eg. EINVAL because of missing
attribute. Given we have different requirements, I would leave it to
each subsystem to decide what netlink error attributes are specified.

> (It's ultimately always going to be optional since we'll continue
> returning errors without *any* extended error information - likely
> indefinitely - but if we have a wrong attribute, should we always have
> an offset? Would be nice, but could be difficult in practice)
> 
> > We can probably use struct nla_policy to place the extended error
> > code or the string (as we discussed I don't need string errors, but
> > I'm fine if other people find it useful).
> 
> I don't think for the error strings really would be useful for
> nla_parse() or a policy - we can return something generic like
> "malformed attribute" there as a string, and hopefully point to the
> attribute/offset from there generically. I just really want to see how
> to actually do that.

I think the most flexible way is to pass the container error structure
to nla_parse() so it sets this for you. This would also save tons of
"malformed attribute" strings.


Re: [RFC 0/3] netlink: extended error reporting

2017-04-07 Thread David Miller
From: Johannes Berg 
Date: Fri, 07 Apr 2017 20:59:12 +0200

> Alexander Shishkin's patch
> https://patchwork.kernel.org/patch/7162421/
> 
> was nice in a way because you could get away without passing the error
> structure down all the time, but like I said it doesn't deal with
> dynamic errors (even the offset/attr from nla_parse) and if it's not
> done *everywhere* it risks leaking those exterr numbers (-1024..-4095)
> to userspace through syscalls if it's used in a non-netlink path for
> some reason (e.g. a single driver call being called through both
> netlink and ioctl, and trying to return an extended error)

Alexander's patch is cute in that it annotates errors using the special
section blobs.

But what it lacks fundamentally is context.  Therefore it can't be
used to provide the offset or the bad attribute number.  So it can't
meet our requirements.

We've passed down new arguments into core method call chains for much
less useful facilitites than this.  So that doesn't bother me.  And
as that is a kernel internal matter, we can refine it later.

Wrt. nla_parse(), we can solve that problem as follow-on patches too.

So I consider this change ready as far as the implementation is
concerned.

Ok, Jiri, start reading.  I will try to make you happy here.

Let's just discuss the UAPI, since people complain we don't talk
about that enough :-)  For those playing at home it is three new
attributes returned in a netlink ACK when the application asks
for the extended response:

NLMSGERR_ATTR_MSG   string  Extended error string
NLMSGERR_ATTR_OFFS  u32 Byte offset to netlink element causing 
error
NLMSGERR_ATTR_CODE  u32 Subsystem specific error code
NLMSGERR_ATTR_ATTR  u16 Netlink attribute triggering error or 
missing

So please consider this interface carefully.


Re: [RFC 2/3] genetlink: pass extended error report down

2017-04-07 Thread Johannes Berg
On Fri, 2017-04-07 at 11:37 -0700, Ben Greear wrote:
> 
> I guess the error string must be constant and always available in
> memory in this implementation?

Yes.

> I think it would be nice to dynamically create strings (malloc,
> snprintf, etc) and have the err_str logic free it when done?

We can think about that later, but I don't actually think it makes a
lot of sense - if we point to the attribute and/or offset you really
ought to have enough info to figure out what's up.

johannes


Re: [RFC 0/3] netlink: extended error reporting

2017-04-07 Thread Johannes Berg
On Fri, 2017-04-07 at 21:06 +0200, Pablo Neira Ayuso wrote:
> On Fri, Apr 07, 2017 at 08:59:12PM +0200, Johannes Berg wrote:
> [...]
> > Heh. I think I really want to solve - at least partially -
> > nla_parse()
> > to see that it can be done this way. It'd be nice to even transform
> > all
> > the callers (I generated half of these patches with spatch anyway)
> > to
> > have at least that.
> 
> We can just have a modified version of nla_parse that deals with
> this.

Yes, but we need to figure out a good way to have the offset.

We also need to see if we want to *force* having the offset. In some
sense that'd be useful, in another it might be very complicated to fill
it in at all times, if for example errors come from lower layers like
drivers.

(It's ultimately always going to be optional since we'll continue
returning errors without *any* extended error information - likely
indefinitely - but if we have a wrong attribute, should we always have
an offset? Would be nice, but could be difficult in practice)

> We can probably use struct nla_policy to place the extended error
> code or the string (as we discussed I don't need string errors, but
> I'm fine if other people find it useful).

I don't think for the error strings really would be useful for
nla_parse() or a policy - we can return something generic like
"malformed attribute" there as a string, and hopefully point to the
attribute/offset from there generically. I just really want to see how
to actually do that.

johannes


Re: [RFC 0/3] netlink: extended error reporting

2017-04-07 Thread Johannes Berg
On Fri, 2017-04-07 at 21:02 +0200, Pablo Neira Ayuso wrote:
> 
> > I'm tempted to apply this as-is just to show that person that
> > things do in fact happen eventually :-)
> 
> We can just send follow up patches to refine, I think it's a good
> start, Johannes?

I guess we can. Like I just said though - I do have a plan to make
nla_parse() work but the week's been exhausting enough that I don't
feel entirely comfortable saying that will definitely work.

OTOH, arguably this is something that seems to work - as evidenced by
the nl80211 changes - for at least some error reporting, so I guess we
can continue to refine it, and the only thing we're really locking in
to is the ABI, which is TLVs now, so that should be safe.

That said, the nl80211 patch really should be bigger, and I've not even
tested this at all yet, so I really need to do that first.

Also, I'd like to point to the genl_info change, does that seem like a
reasonable way to pass it around in genetlink? I'm much less familiar
with the "regular" netlink to say how to pass it around there beyond
what I already did.

johannes


Re: [RFC 0/3] netlink: extended error reporting

2017-04-07 Thread Pablo Neira Ayuso
On Fri, Apr 07, 2017 at 08:59:12PM +0200, Johannes Berg wrote:
[...]
> Heh. I think I really want to solve - at least partially - nla_parse()
> to see that it can be done this way. It'd be nice to even transform all
> the callers (I generated half of these patches with spatch anyway) to
> have at least that.

We can just have a modified version of nla_parse that deals with this.
We can probably use struct nla_policy to place the extended error code
or the string (as we discussed I don't need string errors, but I'm
fine if other people find it useful).

Thanks!


Re: [RFC 0/3] netlink: extended error reporting

2017-04-07 Thread Pablo Neira Ayuso
On Fri, Apr 07, 2017 at 11:53:15AM -0700, David Miller wrote:
> From: Johannes Berg 
> Date: Fri,  7 Apr 2017 20:26:17 +0200
> 
> > So this is my first draft of what we'd talked about at netconf.
> > I'm not super happy with the way we have to pass the extended
> > error struct, but I don't see a way to implement reporting any
> > dynamic information (like error offsets) in any other way.
> > 
> > Alexander Shishkin had a nice way of reporting static extended
> > error data, but that isn't really suitable for reporting the
> > offset or even reporting the broken attribute from nla_parse().
> > 
> > Speaking of nla_parse(), that'll be somewhat complicated to do
> > since we'll have to track the offsets of where we're parsing,
> > but it might be possible since the nlattrs are just pointers
> > into the message, so (optionally?) passing the skb as well can
> > allow us to fill the offset information.
> 
> I like it, nice work.
> 
> I know people want dynamically generated strings and stuff, and we can
> get there, but I prefer that the first thing we commit is super simple.
> 
> Someone gave me a hard time about the fact that we've been talking
> about this idea for years but nothing ever happens.
> 
> I'm tempted to apply this as-is just to show that person that things
> do in fact happen eventually :-)

We can just send follow up patches to refine, I think it's a good
start, Johannes?

BTW, for this co-authored effort in designing this:

Signed-off-by: Pablo Neira Ayuso 

Thanks!


Re: [RFC 0/3] netlink: extended error reporting

2017-04-07 Thread Johannes Berg
On Fri, 2017-04-07 at 11:53 -0700, David Miller wrote:

> > Alexander Shishkin had a nice way of reporting static extended
> > error data, but that isn't really suitable for reporting the
> > offset or even reporting the broken attribute from nla_parse().
> > 
> > Speaking of nla_parse(), that'll be somewhat complicated to do
> > since we'll have to track the offsets of where we're parsing,
> > but it might be possible since the nlattrs are just pointers
> > into the message, so (optionally?) passing the skb as well can
> > allow us to fill the offset information.
> 
> I like it, nice work.

I don't like it all that much ;-)

Alexander Shishkin's patch
https://patchwork.kernel.org/patch/7162421/

was nice in a way because you could get away without passing the error
structure down all the time, but like I said it doesn't deal with
dynamic errors (even the offset/attr from nla_parse) and if it's not
done *everywhere* it risks leaking those exterr numbers (-1024..-4095)
to userspace through syscalls if it's used in a non-netlink path for
some reason (e.g. a single driver call being called through both
netlink and ioctl, and trying to return an extended error)

> I know people want dynamically generated strings and stuff, and we
> can get there, but I prefer that the first thing we commit is super
> simple.
> 
> Someone gave me a hard time about the fact that we've been talking
> about this idea for years but nothing ever happens.
> 
> I'm tempted to apply this as-is just to show that person that things
> do in fact happen eventually :-)

Heh. I think I really want to solve - at least partially - nla_parse()
to see that it can be done this way. It'd be nice to even transform all
the callers (I generated half of these patches with spatch anyway) to
have at least that.

johannes


Re: [RFC 0/3] netlink: extended error reporting

2017-04-07 Thread David Miller
From: Johannes Berg 
Date: Fri,  7 Apr 2017 20:26:17 +0200

> So this is my first draft of what we'd talked about at netconf.
> I'm not super happy with the way we have to pass the extended
> error struct, but I don't see a way to implement reporting any
> dynamic information (like error offsets) in any other way.
> 
> Alexander Shishkin had a nice way of reporting static extended
> error data, but that isn't really suitable for reporting the
> offset or even reporting the broken attribute from nla_parse().
> 
> Speaking of nla_parse(), that'll be somewhat complicated to do
> since we'll have to track the offsets of where we're parsing,
> but it might be possible since the nlattrs are just pointers
> into the message, so (optionally?) passing the skb as well can
> allow us to fill the offset information.

I like it, nice work.

I know people want dynamically generated strings and stuff, and we can
get there, but I prefer that the first thing we commit is super simple.

Someone gave me a hard time about the fact that we've been talking
about this idea for years but nothing ever happens.

I'm tempted to apply this as-is just to show that person that things
do in fact happen eventually :-)


Re: [RFC 2/3] genetlink: pass extended error report down

2017-04-07 Thread Ben Greear

On 04/07/2017 11:26 AM, Johannes Berg wrote:

From: Johannes Berg 

Signed-off-by: Johannes Berg 
---
 include/net/genetlink.h | 27 +++
 net/netlink/genetlink.c |  6 --
 2 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/include/net/genetlink.h b/include/net/genetlink.h
index a34275be3600..67ad2326cfa6 100644
--- a/include/net/genetlink.h
+++ b/include/net/genetlink.h
@@ -84,6 +84,7 @@ struct nlattr **genl_family_attrbuf(const struct genl_family 
*family);
  * @attrs: netlink attributes
  * @_net: network namespace
  * @user_ptr: user pointers
+ * @exterr: extended error report struct
  */
 struct genl_info {
u32 snd_seq;
@@ -94,6 +95,7 @@ struct genl_info {
struct nlattr **attrs;
possible_net_t  _net;
void *  user_ptr[2];
+   struct netlink_ext_err *exterr;
 };

 static inline struct net *genl_info_net(struct genl_info *info)
@@ -106,6 +108,31 @@ static inline void genl_info_net_set(struct genl_info 
*info, struct net *net)
write_pnet(&info->_net, net);
 }

+static inline int genl_err_str(struct genl_info *info, int err,
+  const char *msg)
+{
+   info->exterr->msg = msg;
+
+   return err;
+}


I guess the error string must be constant and always available in memory
in this implementation?

I think it would be nice to dynamically create strings (malloc, snprintf, etc)
and have the err_str logic free it when done?

Thanks,
Ben

--
Ben Greear 
Candela Technologies Inc  http://www.candelatech.com



[RFC 2/3] genetlink: pass extended error report down

2017-04-07 Thread Johannes Berg
From: Johannes Berg 

Signed-off-by: Johannes Berg 
---
 include/net/genetlink.h | 27 +++
 net/netlink/genetlink.c |  6 --
 2 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/include/net/genetlink.h b/include/net/genetlink.h
index a34275be3600..67ad2326cfa6 100644
--- a/include/net/genetlink.h
+++ b/include/net/genetlink.h
@@ -84,6 +84,7 @@ struct nlattr **genl_family_attrbuf(const struct genl_family 
*family);
  * @attrs: netlink attributes
  * @_net: network namespace
  * @user_ptr: user pointers
+ * @exterr: extended error report struct
  */
 struct genl_info {
u32 snd_seq;
@@ -94,6 +95,7 @@ struct genl_info {
struct nlattr **attrs;
possible_net_t  _net;
void *  user_ptr[2];
+   struct netlink_ext_err *exterr;
 };
 
 static inline struct net *genl_info_net(struct genl_info *info)
@@ -106,6 +108,31 @@ static inline void genl_info_net_set(struct genl_info 
*info, struct net *net)
write_pnet(&info->_net, net);
 }
 
+static inline int genl_err_str(struct genl_info *info, int err,
+  const char *msg)
+{
+   info->exterr->msg = msg;
+
+   return err;
+}
+
+static inline int genl_err_attr(struct genl_info *info, int err,
+   u16 attr)
+{
+   info->exterr->attr = attr;
+
+   return err;
+}
+
+static inline int genl_err_str_attr(struct genl_info *info, int err,
+   const char *msg, u16 attr)
+{
+   info->exterr->msg = msg;
+   info->exterr->attr = attr;
+
+   return err;
+}
+
 /**
  * struct genl_ops - generic netlink operations
  * @cmd: command identifier
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index 48f21dc467a7..39182d6a990e 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -497,7 +497,8 @@ static int genl_lock_done(struct netlink_callback *cb)
 
 static int genl_family_rcv_msg(const struct genl_family *family,
   struct sk_buff *skb,
-  struct nlmsghdr *nlh)
+  struct nlmsghdr *nlh,
+  struct netlink_ext_err *exterr)
 {
const struct genl_ops *ops;
struct net *net = sock_net(skb->sk);
@@ -584,6 +585,7 @@ static int genl_family_rcv_msg(const struct genl_family 
*family,
info.genlhdr = nlmsg_data(nlh);
info.userhdr = nlmsg_data(nlh) + GENL_HDRLEN;
info.attrs = attrbuf;
+   info.exterr = exterr;
genl_info_net_set(&info, net);
memset(&info.user_ptr, 0, sizeof(info.user_ptr));
 
@@ -618,7 +620,7 @@ static int genl_rcv_msg(struct sk_buff *skb, struct 
nlmsghdr *nlh,
if (!family->parallel_ops)
genl_lock();
 
-   err = genl_family_rcv_msg(family, skb, nlh);
+   err = genl_family_rcv_msg(family, skb, nlh, exterr);
 
if (!family->parallel_ops)
genl_unlock();
-- 
2.11.0



[RFC 0/3] netlink: extended error reporting

2017-04-07 Thread Johannes Berg
So this is my first draft of what we'd talked about at netconf.
I'm not super happy with the way we have to pass the extended
error struct, but I don't see a way to implement reporting any
dynamic information (like error offsets) in any other way.

Alexander Shishkin had a nice way of reporting static extended
error data, but that isn't really suitable for reporting the
offset or even reporting the broken attribute from nla_parse().

Speaking of nla_parse(), that'll be somewhat complicated to do
since we'll have to track the offsets of where we're parsing,
but it might be possible since the nlattrs are just pointers
into the message, so (optionally?) passing the skb as well can
allow us to fill the offset information.

johannes



[RFC 3/3] nl80211: add a few extended error strings

2017-04-07 Thread Johannes Berg
From: Johannes Berg 

Signed-off-by: Johannes Berg 
---
 net/wireless/nl80211.c | 33 ++---
 1 file changed, 18 insertions(+), 15 deletions(-)

diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 9910aae08f1a..8808099db909 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -740,7 +740,8 @@ struct key_parse {
bool def_uni, def_multi;
 };
 
-static int nl80211_parse_key_new(struct nlattr *key, struct key_parse *k)
+static int nl80211_parse_key_new(struct genl_info *info, struct nlattr *key,
+struct key_parse *k)
 {
struct nlattr *tb[NL80211_KEY_MAX + 1];
int err = nla_parse_nested(tb, NL80211_KEY_MAX, key,
@@ -777,7 +778,7 @@ static int nl80211_parse_key_new(struct nlattr *key, struct 
key_parse *k)
if (tb[NL80211_KEY_TYPE]) {
k->type = nla_get_u32(tb[NL80211_KEY_TYPE]);
if (k->type < 0 || k->type >= NUM_NL80211_KEYTYPES)
-   return -EINVAL;
+   return genl_err_attr(info, -EINVAL, NL80211_KEY_TYPE);
}
 
if (tb[NL80211_KEY_DEFAULT_TYPES]) {
@@ -855,7 +856,7 @@ static int nl80211_parse_key(struct genl_info *info, struct 
key_parse *k)
k->type = -1;
 
if (info->attrs[NL80211_ATTR_KEY])
-   err = nl80211_parse_key_new(info->attrs[NL80211_ATTR_KEY], k);
+   err = nl80211_parse_key_new(info, 
info->attrs[NL80211_ATTR_KEY], k);
else
err = nl80211_parse_key_old(info, k);
 
@@ -863,23 +864,27 @@ static int nl80211_parse_key(struct genl_info *info, 
struct key_parse *k)
return err;
 
if (k->def && k->defmgmt)
-   return -EINVAL;
+   return genl_err_str(info, -EINVAL, "def && defmgmt is invalid");
 
if (k->defmgmt) {
if (k->def_uni || !k->def_multi)
-   return -EINVAL;
+   return genl_err_str(info, -EINVAL,
+   "defmgmt must be mcast");
}
 
if (k->idx != -1) {
if (k->defmgmt) {
if (k->idx < 4 || k->idx > 5)
-   return -EINVAL;
+   return genl_err_str(info, -EINVAL,
+   "defmgmt key idx not 4 or 
5");
} else if (k->def) {
if (k->idx < 0 || k->idx > 3)
-   return -EINVAL;
+   return genl_err_str(info, -EINVAL,
+   "def key idx not 0-3");
} else {
if (k->idx < 0 || k->idx > 5)
-   return -EINVAL;
+   return genl_err_str(info, -EINVAL,
+   "key idx not 0-5");
}
}
 
@@ -888,8 +893,9 @@ static int nl80211_parse_key(struct genl_info *info, struct 
key_parse *k)
 
 static struct cfg80211_cached_keys *
 nl80211_parse_connkeys(struct cfg80211_registered_device *rdev,
-  struct nlattr *keys, bool *no_ht)
+  struct genl_info *info, bool *no_ht)
 {
+   struct nlattr *keys = info->attrs[NL80211_ATTR_KEYS];
struct key_parse parse;
struct nlattr *key;
struct cfg80211_cached_keys *result;
@@ -914,7 +920,7 @@ nl80211_parse_connkeys(struct cfg80211_registered_device 
*rdev,
memset(&parse, 0, sizeof(parse));
parse.idx = -1;
 
-   err = nl80211_parse_key_new(key, &parse);
+   err = nl80211_parse_key_new(info, key, &parse);
if (err)
goto error;
err = -EINVAL;
@@ -8460,9 +8466,7 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct 
genl_info *info)
if (ibss.privacy && info->attrs[NL80211_ATTR_KEYS]) {
bool no_ht = false;
 
-   connkeys = nl80211_parse_connkeys(rdev,
- info->attrs[NL80211_ATTR_KEYS],
- &no_ht);
+   connkeys = nl80211_parse_connkeys(rdev, info, &no_ht);
if (IS_ERR(connkeys))
return PTR_ERR(connkeys);
 
@@ -8853,8 +8857,7 @@ static int nl80211_connect(struct sk_buff *skb, struct 
genl_info *info)
}
 
if (connect.privacy && info->attrs[NL80211_ATTR_KEYS]) {
-   connkeys = nl80211_parse_connkeys(rdev,
- info->attrs[NL80211_ATTR_KEYS], NULL);
+   connkeys = nl80211_parse_connkeys(rdev, info, NULL);
if (IS_ERR(connkeys))
return PTR_ERR(connkeys);
}
-- 
2.11.0



[RFC 1/3] netlink: extended error reporting

2017-04-07 Thread Johannes Berg
From: Johannes Berg 

Signed-off-by: Johannes Berg 
---
 crypto/crypto_user.c  |  3 +-
 drivers/infiniband/core/netlink.c |  3 +-
 drivers/scsi/scsi_netlink.c   |  2 +-
 include/linux/netlink.h   | 10 ++-
 include/net/netlink.h |  3 +-
 include/uapi/linux/netlink.h  | 26 +
 kernel/audit.c|  2 +-
 net/core/rtnetlink.c  |  3 +-
 net/core/sock_diag.c  |  3 +-
 net/hsr/hsr_netlink.c |  4 +--
 net/netfilter/ipset/ip_set_core.c |  2 +-
 net/netfilter/nfnetlink.c | 18 ++--
 net/netlink/af_netlink.c  | 60 ++-
 net/netlink/genetlink.c   |  3 +-
 net/xfrm/xfrm_user.c  |  3 +-
 15 files changed, 117 insertions(+), 28 deletions(-)

diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c
index a90404a0c5ff..4d4433e80866 100644
--- a/crypto/crypto_user.c
+++ b/crypto/crypto_user.c
@@ -483,7 +483,8 @@ static const struct crypto_link {
[CRYPTO_MSG_DELRNG  - CRYPTO_MSG_BASE] = { .doit = crypto_del_rng },
 };
 
-static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
+static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
+  struct netlink_ext_err *exterr)
 {
struct nlattr *attrs[CRYPTOCFGA_MAX+1];
const struct crypto_link *link;
diff --git a/drivers/infiniband/core/netlink.c 
b/drivers/infiniband/core/netlink.c
index 10469b0088b5..679d65430113 100644
--- a/drivers/infiniband/core/netlink.c
+++ b/drivers/infiniband/core/netlink.c
@@ -146,7 +146,8 @@ int ibnl_put_attr(struct sk_buff *skb, struct nlmsghdr *nlh,
 }
 EXPORT_SYMBOL(ibnl_put_attr);
 
-static int ibnl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
+static int ibnl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
+   struct netlink_ext_err *exterr)
 {
struct ibnl_client *client;
int type = nlh->nlmsg_type;
diff --git a/drivers/scsi/scsi_netlink.c b/drivers/scsi/scsi_netlink.c
index 109802f776ed..50e624fb8307 100644
--- a/drivers/scsi/scsi_netlink.c
+++ b/drivers/scsi/scsi_netlink.c
@@ -111,7 +111,7 @@ scsi_nl_rcv_msg(struct sk_buff *skb)
 
 next_msg:
if ((err) || (nlh->nlmsg_flags & NLM_F_ACK))
-   netlink_ack(skb, nlh, err);
+   netlink_ack(skb, nlh, err, NULL);
 
skb_pull(skb, rlen);
}
diff --git a/include/linux/netlink.h b/include/linux/netlink.h
index da14ab61f363..662f343dc68b 100644
--- a/include/linux/netlink.h
+++ b/include/linux/netlink.h
@@ -62,11 +62,19 @@ netlink_kernel_create(struct net *net, int unit, struct 
netlink_kernel_cfg *cfg)
return __netlink_kernel_create(net, unit, THIS_MODULE, cfg);
 }
 
+struct netlink_ext_err {
+   const char *msg;
+   u32 ext_code;
+   u32 msg_offset;
+   u16 attr;
+};
+
 extern void netlink_kernel_release(struct sock *sk);
 extern int __netlink_change_ngroups(struct sock *sk, unsigned int groups);
 extern int netlink_change_ngroups(struct sock *sk, unsigned int groups);
 extern void __netlink_clear_multicast_users(struct sock *sk, unsigned int 
group);
-extern void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err);
+extern void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err,
+   const struct netlink_ext_err *exterr);
 extern int netlink_has_listeners(struct sock *sk, unsigned int group);
 
 extern int netlink_unicast(struct sock *ssk, struct sk_buff *skb, __u32 
portid, int nonblock);
diff --git a/include/net/netlink.h b/include/net/netlink.h
index b239fcd33d80..f06c2e00ebc3 100644
--- a/include/net/netlink.h
+++ b/include/net/netlink.h
@@ -233,7 +233,8 @@ struct nl_info {
 };
 
 int netlink_rcv_skb(struct sk_buff *skb,
-   int (*cb)(struct sk_buff *, struct nlmsghdr *));
+   int (*cb)(struct sk_buff *, struct nlmsghdr *,
+ struct netlink_ext_err *));
 int nlmsg_notify(struct sock *sk, struct sk_buff *skb, u32 portid,
 unsigned int group, int report, gfp_t flags);
 
diff --git a/include/uapi/linux/netlink.h b/include/uapi/linux/netlink.h
index b2c9c26ea30f..0ef970e6f9f5 100644
--- a/include/uapi/linux/netlink.h
+++ b/include/uapi/linux/netlink.h
@@ -101,6 +101,31 @@ struct nlmsghdr {
 struct nlmsgerr {
int error;
struct nlmsghdr msg;
+   /*
+* followed by the message contents unless NETLINK_CAP_ACK was set,
+* message length is aligned with NLMSG_ALIGN()
+*/
+   /*
+* followed by TLVs defined in enum nlmsgerr_attrs
+* if NETLINK_EXT_ACK was set
+*/
+};
+
+/**
+ * enum nlmsgerr_attrs - netlink error message attributes
+ * @NLMSGERR_ATTR_UNUSED: unused
+ * @NLMSGERR_ATTR_MSG: error message string (string)
+ * @NLMSGERR_ATTR_OFFS: error offset in the original message (u32)
+ * @NLMSG

Re: [PATCH v2 2/4] mwifiex: fall back mwifiex_dbg to pr_info when adapter->dev not set

2017-04-07 Thread Dmitry Torokhov
Hi Xinming,

On Fri, Apr 7, 2017 at 3:51 AM, Xinming Hu  wrote:
> From: Xinming Hu 
>
> mwifiex_dbg will do nothing before adapter->dev get assigned. several logs
> lost in this case. it can be avoided by fall back to pr_info.
>
> Signed-off-by: Xinming Hu 
> ---
> v2: enhance adapter->dev null case.(Brain)
> ---
>  drivers/net/wireless/marvell/mwifiex/main.c | 17 -
>  drivers/net/wireless/marvell/mwifiex/main.h |  2 ++
>  2 files changed, 14 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/net/wireless/marvell/mwifiex/main.c 
> b/drivers/net/wireless/marvell/mwifiex/main.c
> index 98fd491..f3e772f 100644
> --- a/drivers/net/wireless/marvell/mwifiex/main.c
> +++ b/drivers/net/wireless/marvell/mwifiex/main.c
> @@ -1749,18 +1749,25 @@ void _mwifiex_dbg(const struct mwifiex_adapter 
> *adapter, int mask,
>  {
> struct va_format vaf;
> va_list args;
> +   char msg[MWIFIEX_LOG_LEN];
>
> -   if (!adapter->dev || !(adapter->debug_mask & mask))
> +   if (!(adapter->debug_mask & mask))
> return;
>
> va_start(args, fmt);
>
> -   vaf.fmt = fmt;
> -   vaf.va = &args;
> -
> -   dev_info(adapter->dev, "%pV", &vaf);
> +   if (!adapter->dev) {
> +   vsnprintf(msg, MWIFIEX_LOG_LEN, fmt, args);
> +   } else {
> +   vaf.fmt = fmt;
> +   vaf.va = &args;
> +   dev_info(adapter->dev, "%pV", &vaf);
> +   }
>
> va_end(args);
> +
> +   if (!adapter->dev)
> +   pr_info("%s", msg);

Why not:

vaf.fmt = fmt;
vaf.va = &args;

if (adapter->dev)
dev_info(adapter->dev, "%pV", &vaf);
else
pr_info("mwifiex: %pV", &vaf);

va_end(args);

Also, instead of static "mwifiex" prefix maybe make sure you have
pr_fmt() set properly (I am not sure if it is set or not).

Thanks.

-- 
Dmitry


pull-request: wireless-drivers-next 2017-04-07

2017-04-07 Thread Kalle Valo
Hi Dave,

here's a pull request for net-next, more info in the signed tag below.
Please let me know if there are any problems.

Kalle

The following changes since commit 9c28286b1b4b9bce6e35dd4c8a1265f03802a89a:

  decnet: Use TCP nagle macro instead of literal number in decnet (2017-03-07 
14:07:55 -0800)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next.git 
tags/wireless-drivers-next-for-davem-2017-04-07

for you to fetch changes up to 1aed89640a899cd695bbfc976a4356affa474646:

  mwifiex: apply radar flag (2017-04-05 15:54:52 +0300)


wireless-drivers-next patches for 4.12

Lots of bugfixes as usual but also some new features.

Major changes:

ath10k

* improve firmware download time for QCA6174 and QCA9377, especially
  helps resume time

ath9k_htc

* add support AirTies 1eda:2315 AR9271 device

rt2x00

* add support MT7620

mwifiex

* enable auto deep sleep mode for USB chipsets

brcmfmac

* add support for network namespaces (WIPHY_FLAG_NETNS_OK)


Alexandre Belloni (1):
  atmel: remove time_t usage

Amitkumar Karwar (2):
  mwifiex: send fewer channels to scan while connected
  mwifiex: enable auto deep sleep mode for USB chipsets

Arend Van Spriel (3):
  brcmfmac: add support to move wiphy instance into network namespace
  brcmfmac: restore bus state when enter_D3 fails
  brcmfmac: no need for d11inf instance in brcmf_pno_start_sched_scan()

Brian Norris (4):
  mwifiex: pcie: clean up error prints in mwifiex_pcie_reset_notify()
  mwifiex: fix kernel crash after shutdown command timeout
  mwifiex: fix use-after-free for FW reinit errors
  mwifiex: catch mwifiex_fw_dpc() errors properly in reset

Christophe Jaillet (1):
  wcn36xx: Fix error handling

Colin Ian King (5):
  rtlwifi: fix spelling mistake: "conuntry" -> "country"
  ath10k: remove redundant error check
  ath10k: remove redundant check of len with buf_len
  ipw2200: remove redundant check of rc < 0
  wlcore: fix spelling mistakes in wl1271_warning

Daniel Golle (1):
  rt2x00: fix TX_PWR_CFG_4 register definition

Daniel Mentz (1):
  mwifiex: Use accessors routines for unaligned values

Dedy Lansky (4):
  wil6210: use print_hex_dump_debug instead of print_hex_dump_bytes
  wil6210: store bss object and use cfg80211_connect_bss()
  wil6210: use WMI_DISCONNECT_CMDID upon connect timeout
  wil6210: correctly report locally generated disconnect in STA mode

Devidas Puranik (1):
  mwifiex: fix for unaligned reads

Dmitry Tunin (1):
  ath9k_htc: Add support of AirTies 1eda:2315 AR9271 device

Franky Lin (7):
  brcmfmac: move brcmf_txflowblock to bcdc layer
  brcmfmac: move brcmf_txcomplete to bcdc layer
  brcmfmac: wrap brcmf_fws_add_interface into bcdc layer
  brcmfmac: wrap brcmf_fws_del_interface into bcdc layer
  brcmfmac: wrap brcmf_fws_reset_interface into bcdc layer
  brcmfmac: wrap brcmf_fws_init into bcdc layer
  brcmfmac: move brcmf_fws_deinit to bcdc layer

Gabor Juhos (1):
  rt2x00: rt2800lib: move rt2800_drv_data declaration into rt2800lib.h

Ganapathi Bhat (1):
  mwifiex: Support USB interrupt endpoint for command response/event

Hamad Kadmany (2):
  wil6210: set dma mask to reflect device capability
  wil6210: protect list of pending wmi events during flush

Hans de Goede (3):
  brcmfmac: Do not print the firmware version as an error
  brcmfmac: Do not complain about country code "00"
  brcmfmac: Handle status == BRCMF_E_STATUS_ABORT in cfg80211_escan_handler

Jeffy Chen (1):
  mwifiex: wake system up when receives a wake irq

Johan Hovold (1):
  zd1211rw: fix NULL-deref at probe

Kalle Valo (2):
  ath10k: fix warnings from an earlier commit
  Merge ath-next from git://git.kernel.org/.../kvalo/ath.git

Karthik Ananthapadmanabha (3):
  mwifiex: add qualifier to firmware structures
  mwifiex: add missing IEs related to TDLS operation
  mwifiex: apply radar flag

Larry Finger (1):
  rtlwifi: Add code to read new versions of firmware

Lior David (3):
  wil6210: do not start regular scan on stopped p2p device
  wil6210: bus_request platform operation refinement
  wil6210: add oob_mode for AP certification

Maya Erez (1):
  wil6210: missing reinit_completion in HALP voting

Mohammed Shafi Shajakhan (4):
  ath10k: fix a warning during channel switch with multiple vaps
  ath10k: disallow DFS simulation if DFS channel is not enabled
  ath10k: fix fetching channel during potential radar detection
  ath10k: fix typo in wmi header file

Nils Holland (1):
  rtl8187: Enable monitor mode to fix multicast reception

Ping-Ke Shih (3):
  rtlwifi: Update 8821ae new phy parameters and its parser.
  rtlwifi: Update 8812ae new phy paramete

[PATCH] staging: wilc1000: Fix problem with wrong vif index

2017-04-07 Thread Aditya Shankar
The vif->idx value is always 0 for two interfaces.

wl->vif_num = 0;

loop {
 ...

 vif->idx = wl->vif_num;
 ...
 wl->vif_num = i;
  
 i++;
 ...
}

At present, vif->idx is assigned the value of wl->vif_num
at the beginning of this block and device is initialized
based on this index value.
In the next iteration, wl->vif_num is still 0 as it is only updated
later but gets assigned to vif->idx in the beginning. This causes problems
later when we try to reference a particular interface and also while
configuring the firmware.

This patch moves the assignment to vif->idx from the beginning
of the block to after wl->vif_num is updated with latest value of i.

Fixes: commit 735bb39ca3be ("staging: wilc1000: simplify vif[i]->ndev accesses")
Cc: 
Signed-off-by: Aditya Shankar 
---
 drivers/staging/wilc1000/linux_wlan.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/staging/wilc1000/linux_wlan.c 
b/drivers/staging/wilc1000/linux_wlan.c
index cd2f602..a2c2ce6 100644
--- a/drivers/staging/wilc1000/linux_wlan.c
+++ b/drivers/staging/wilc1000/linux_wlan.c
@@ -1232,11 +1232,12 @@ int wilc_netdev_init(struct wilc **wilc, struct device 
*dev, int io_type,
else
strcpy(ndev->name, "p2p%d");
 
-   vif->idx = wl->vif_num;
vif->wilc = *wilc;
vif->ndev = ndev;
wl->vif[i] = vif;
wl->vif_num = i;
+   vif->idx = wl->vif_num;
+
ndev->netdev_ops = &wilc_netdev_ops;
 
{
-- 
2.7.4




[PATCH] staging: wilc1000: Update handler assignment logic

2017-04-07 Thread Aditya Shankar
With this update, the host driver is consistent with the
implementation on the firmware side with respect to obtaining
the driver handler for all modes.
With this new format, the calls to set the wilc operation mode
is simplified.

Signed-off-by: Aditya Shankar 
---
 drivers/staging/wilc1000/host_interface.c | 56 +++
 drivers/staging/wilc1000/host_interface.h |  9 +++-
 drivers/staging/wilc1000/linux_wlan.c | 29 ++--
 drivers/staging/wilc1000/wilc_wfi_cfgoperations.c |  2 +-
 drivers/staging/wilc1000/wilc_wlan_if.h   |  2 +-
 5 files changed, 61 insertions(+), 37 deletions(-)

diff --git a/drivers/staging/wilc1000/host_interface.c 
b/drivers/staging/wilc1000/host_interface.c
index c3a8af0..c04643e 100644
--- a/drivers/staging/wilc1000/host_interface.c
+++ b/drivers/staging/wilc1000/host_interface.c
@@ -198,6 +198,7 @@ struct host_if_msg {
union message_body body;
struct wilc_vif *vif;
struct work_struct work;
+   void *drv_handler;
 };
 
 struct join_bss_param {
@@ -334,14 +335,44 @@ static void handle_set_wfi_drv_handler(struct wilc_vif 
*vif,
 {
int ret = 0;
struct wid wid;
+   u8 *currbyte;
+   struct host_if_drv *hif_drv = NULL;
+   int driver_handler_id = 0;
+   u8 *buffer = kzalloc(DRV_HANDLER_SIZE, GFP_ATOMIC);
+
+   if (!vif->hif_drv)
+   return;
+
+   if (!hif_drv_handler)
+   return;
+
+   hif_drv = vif->hif_drv;
+
+   if (hif_drv)
+   driver_handler_id = hif_drv->driver_handler_id;
+   else
+   driver_handler_id = 0;
+
+   driver_handler_id = hif_drv->driver_handler_id;
+
+   currbyte = buffer;
+   *currbyte = driver_handler_id & DRV_HANDLER_MASK;
+   currbyte++;
+   *currbyte = (u32)0 & DRV_HANDLER_MASK;
+   currbyte++;
+   *currbyte = (u32)0 & DRV_HANDLER_MASK;
+   currbyte++;
+   *currbyte = (u32)0 & DRV_HANDLER_MASK;
+   currbyte++;
+   *currbyte = (hif_drv_handler->name | (hif_drv_handler->mode << 1));
 
wid.id = (u16)WID_SET_DRV_HANDLER;
wid.type = WID_STR;
-   wid.val = (s8 *)hif_drv_handler;
-   wid.size = sizeof(*hif_drv_handler);
+   wid.val = (s8 *)buffer;
+   wid.size = DRV_HANDLER_SIZE;
 
ret = wilc_send_config_pkt(vif, SET_CFG, &wid, 1,
-  hif_drv_handler->handler);
+  driver_handler_id);
 
if (!hif_drv_handler->handler)
complete(&hif_driver_comp);
@@ -2403,9 +2434,9 @@ static void Handle_SetMulticastFilter(struct wilc_vif 
*vif,
 
pu8CurrByte = wid.val;
*pu8CurrByte++ = (strHostIfSetMulti->enabled & 0xFF);
-   *pu8CurrByte++ = 0;
-   *pu8CurrByte++ = 0;
-   *pu8CurrByte++ = 0;
+   *pu8CurrByte++ = ((strHostIfSetMulti->enabled >> 8) & 0xFF);
+   *pu8CurrByte++ = ((strHostIfSetMulti->enabled >> 16) & 0xFF);
+   *pu8CurrByte++ = ((strHostIfSetMulti->enabled >> 24) & 0xFF);
 
*pu8CurrByte++ = (strHostIfSetMulti->cnt & 0xFF);
*pu8CurrByte++ = ((strHostIfSetMulti->cnt >> 8) & 0xFF);
@@ -3099,7 +3130,8 @@ int wilc_set_mac_chnl_num(struct wilc_vif *vif, u8 
channel)
return 0;
 }
 
-int wilc_set_wfi_drv_handler(struct wilc_vif *vif, int index, u8 mac_idx)
+int wilc_set_wfi_drv_handler(struct wilc_vif *vif, int index, u8 mode, char
+*ifname)
 {
int result = 0;
struct host_if_msg msg;
@@ -3107,9 +3139,14 @@ int wilc_set_wfi_drv_handler(struct wilc_vif *vif, int 
index, u8 mac_idx)
memset(&msg, 0, sizeof(struct host_if_msg));
msg.id = HOST_IF_MSG_SET_WFIDRV_HANDLER;
msg.body.drv.handler = index;
-   msg.body.drv.mac_idx = mac_idx;
+   msg.body.drv.mode = mode;
msg.vif = vif;
 
+   if (!memcmp(ifname, "wlan0", 5))
+   msg.body.drv.name = 1;
+   else if (!memcmp(ifname, "p2p0", 4))
+   msg.body.drv.name = 0;
+
result = wilc_enqueue_cmd(&msg);
if (result) {
netdev_err(vif->ndev, "wilc mq send fail\n");
@@ -3330,6 +3367,7 @@ int wilc_init(struct net_device *dev, struct host_if_drv 
**hif_drv_handler)
for (i = 0; i < wilc->vif_num; i++)
if (dev == wilc->vif[i]->ndev) {
wilc->vif[i]->hif_drv = hif_drv;
+   hif_drv->driver_handler_id = i + 1;
break;
}
 
@@ -3403,7 +3441,7 @@ int wilc_deinit(struct wilc_vif *vif)
del_timer_sync(&periodic_rssi);
del_timer_sync(&hif_drv->remain_on_ch_timer);
 
-   wilc_set_wfi_drv_handler(vif, 0, 0);
+   wilc_set_wfi_drv_handler(vif, 0, 0, 0);
wait_for_completion(&hif_driver_comp);
 
if (hif_drv->usr_scan_req.scan_result) {
diff --git a/drivers/staging/wilc1000/host_interface.h 
b/drivers/staging/wilc1000/host_interface.h
index f36d3b5..77e7f26 100644
--- a/drivers/staging/w

[PATCH] staging: wilc1000: Use new format for configuring firmware

2017-04-07 Thread Aditya Shankar
The configuration packet format has changed in the newer wilc
firmware versions 14.2 and up. This update ensures that the
firmware is initialized correctly by the host and configured
in the required mode.

Signed-off-by: Aditya Shankar 
---
 drivers/staging/wilc1000/wilc_wlan_cfg.c | 59 +++-
 1 file changed, 36 insertions(+), 23 deletions(-)

diff --git a/drivers/staging/wilc1000/wilc_wlan_cfg.c 
b/drivers/staging/wilc1000/wilc_wlan_cfg.c
index 926fc16..d3e5b1b 100644
--- a/drivers/staging/wilc1000/wilc_wlan_cfg.c
+++ b/drivers/staging/wilc1000/wilc_wlan_cfg.c
@@ -175,8 +175,9 @@ static int wilc_wlan_cfg_set_byte(u8 *frame, u32 offset, 
u16 id, u8 val8)
buf[0] = (u8)id;
buf[1] = (u8)(id >> 8);
buf[2] = 1;
-   buf[3] = val8;
-   return 4;
+   buf[3] = 0;
+   buf[4] = val8;
+   return 5;
 }
 
 static int wilc_wlan_cfg_set_hword(u8 *frame, u32 offset, u16 id, u16 val16)
@@ -191,10 +192,11 @@ static int wilc_wlan_cfg_set_hword(u8 *frame, u32 offset, 
u16 id, u16 val16)
buf[0] = (u8)id;
buf[1] = (u8)(id >> 8);
buf[2] = 2;
-   buf[3] = (u8)val16;
-   buf[4] = (u8)(val16 >> 8);
+   buf[3] = 0;
+   buf[4] = (u8)val16;
+   buf[5] = (u8)(val16 >> 8);
 
-   return 5;
+   return 6;
 }
 
 static int wilc_wlan_cfg_set_word(u8 *frame, u32 offset, u16 id, u32 val32)
@@ -209,19 +211,20 @@ static int wilc_wlan_cfg_set_word(u8 *frame, u32 offset, 
u16 id, u32 val32)
buf[0] = (u8)id;
buf[1] = (u8)(id >> 8);
buf[2] = 4;
-   buf[3] = (u8)val32;
-   buf[4] = (u8)(val32 >> 8);
-   buf[5] = (u8)(val32 >> 16);
-   buf[6] = (u8)(val32 >> 24);
+   buf[3] = 0;
+   buf[4] = (u8)val32;
+   buf[5] = (u8)(val32 >> 8);
+   buf[6] = (u8)(val32 >> 16);
+   buf[7] = (u8)(val32 >> 24);
 
-   return 7;
+   return 8;
 }
 
 static int wilc_wlan_cfg_set_str(u8 *frame, u32 offset, u16 id, u8 *str, u32 
size)
 {
u8 *buf;
 
-   if ((offset + size + 3) >= MAX_CFG_FRAME_SIZE)
+   if ((offset + size + 4) >= MAX_CFG_FRAME_SIZE)
return 0;
 
buf = &frame[offset];
@@ -229,11 +232,12 @@ static int wilc_wlan_cfg_set_str(u8 *frame, u32 offset, 
u16 id, u8 *str, u32 siz
buf[0] = (u8)id;
buf[1] = (u8)(id >> 8);
buf[2] = (u8)size;
+   buf[3] = (u8)(size >> 8);
 
if ((str) && (size != 0))
-   memcpy(&buf[3], str, size);
+   memcpy(&buf[4], str, size);
 
-   return (size + 3);
+   return (size + 4);
 }
 
 static int wilc_wlan_cfg_set_bin(u8 *frame, u32 offset, u16 id, u8 *b, u32 
size)
@@ -284,12 +288,12 @@ static void wilc_wlan_parse_response_frame(u8 *info, int 
size)
break;
 
if (g_cfg_byte[i].id == wid) {
-   g_cfg_byte[i].val = info[3];
+   g_cfg_byte[i].val = info[4];
break;
}
i++;
} while (1);
-   len = 2;
+   len = 3;
break;
 
case WID_SHORT:
@@ -298,12 +302,14 @@ static void wilc_wlan_parse_response_frame(u8 *info, int 
size)
break;
 
if (g_cfg_hword[i].id == wid) {
-   g_cfg_hword[i].val = 
cpu_to_le16(info[3] | (info[4] << 8));
+   g_cfg_hword[i].val =
+   cpu_to_le16(info[4] |
+   (info[5] << 8));
break;
}
i++;
} while (1);
-   len = 3;
+   len = 4;
break;
 
case WID_INT:
@@ -312,12 +318,16 @@ static void wilc_wlan_parse_response_frame(u8 *info, int 
size)
break;
 
if (g_cfg_word[i].id == wid) {
-   g_cfg_word[i].val = cpu_to_le32(info[3] 
| (info[4] << 8) | (info[5] << 16) | (info[6] << 24));
+   g_cfg_word[i].val =
+   cpu_to_le32(info[4] |
+   (info[5] << 8) |
+   (info[6] << 16) |
+   (info[7] << 24));
break;
}
i++;
} while (1);
-   len = 5;
+   len = 6

[PATCH v2 4/4] mwifiex: pcie: extract wifi part from combo firmware during function level reset

2017-04-07 Thread Xinming Hu
From: Xinming Hu 

A seperate wifi-only firmware was download during pcie function level reset.
It is in fact the tail part of wifi/bt combo firmware. Per Brian's and
Dmitry's suggestion, this patch extract the wifi part from combo firmware.

After that, we can discard the redudant image in linux-firmware repo.

Signed-off-by: Xinming Hu 
Signed-off-by: Ganapathi Bhat 
Signed-off-by: Cathy Luo 
---
v2: extract wifi part from combo firmware(Dimtry and Brain)
add more description(Kalle)
---
 drivers/net/wireless/marvell/mwifiex/fw.h   | 18 +++
 drivers/net/wireless/marvell/mwifiex/pcie.c | 83 ++---
 drivers/net/wireless/marvell/mwifiex/pcie.h |  2 +
 3 files changed, 96 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/marvell/mwifiex/fw.h 
b/drivers/net/wireless/marvell/mwifiex/fw.h
index 0b68374..6cf9ab9 100644
--- a/drivers/net/wireless/marvell/mwifiex/fw.h
+++ b/drivers/net/wireless/marvell/mwifiex/fw.h
@@ -43,6 +43,24 @@ struct tx_packet_hdr {
struct rfc_1042_hdr rfc1042_hdr;
 } __packed;
 
+struct mwifiex_fw_header {
+   __le32 dnld_cmd;
+   __le32 base_addr;
+   __le32 data_length;
+   __le32 crc;
+} __packed;
+
+struct mwifiex_fw_data {
+   struct mwifiex_fw_header header;
+   __le32 seq_num;
+   u8 data[1];
+} __packed;
+
+#define MWIFIEX_FW_DNLD_CMD_1 0x1
+#define MWIFIEX_FW_DNLD_CMD_5 0x5
+#define MWIFIEX_FW_DNLD_CMD_6 0x6
+#define MWIFIEX_FW_DNLD_CMD_7 0x7
+
 #define B_SUPPORTED_RATES   5
 #define G_SUPPORTED_RATES   9
 #define BG_SUPPORTED_RATES  13
diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c 
b/drivers/net/wireless/marvell/mwifiex/pcie.c
index a07cb0a..ebf00d9 100644
--- a/drivers/net/wireless/marvell/mwifiex/pcie.c
+++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
@@ -1956,6 +1956,63 @@ static int mwifiex_pcie_event_complete(struct 
mwifiex_adapter *adapter,
return ret;
 }
 
+/* Extract wifi part from wifi-bt combo firmware image.
+ */
+
+static int mwifiex_extract_wifi_fw(struct mwifiex_adapter *adapter,
+  u8 *firmware, u32 firmware_len) {
+   struct mwifiex_fw_data fwdata;
+   u32 offset = 0, data_len, dnld_cmd;
+   int ret = 0;
+   bool cmd7_before = false;
+
+   while (1) {
+   if (offset + sizeof(fwdata.header) >= firmware_len) {
+   mwifiex_dbg(adapter, ERROR,
+   "extract wifi-only firmware failure!");
+   ret = -1;
+   goto done;
+   }
+
+   memcpy(&fwdata.header, firmware + offset,
+  sizeof(fwdata.header));
+   dnld_cmd = le32_to_cpu(fwdata.header.dnld_cmd);
+   data_len = le32_to_cpu(fwdata.header.data_length);
+
+   switch (dnld_cmd) {
+   case MWIFIEX_FW_DNLD_CMD_1:
+   if (!cmd7_before) {
+   mwifiex_dbg(adapter, ERROR,
+   "no cmd7 before cmd1!");
+   ret = -1;
+   goto done;
+   }
+   offset += data_len + sizeof(fwdata.header);
+   break;
+   case MWIFIEX_FW_DNLD_CMD_5:
+   offset += data_len + sizeof(fwdata.header);
+   break;
+   case MWIFIEX_FW_DNLD_CMD_6:
+   offset += data_len + sizeof(fwdata.header);
+   ret = offset;
+   goto done;
+   case MWIFIEX_FW_DNLD_CMD_7:
+   if (!cmd7_before)
+   cmd7_before = true;
+   offset += sizeof(fwdata.header);
+   break;
+   default:
+   mwifiex_dbg(adapter, ERROR, "unknown dnld_cmd %d\n",
+   dnld_cmd);
+   ret = -1;
+   goto done;
+   }
+   }
+
+done:
+   return ret;
+}
+
 /*
  * This function downloads the firmware to the card.
  *
@@ -1971,7 +2028,7 @@ static int mwifiex_prog_fw_w_helper(struct 
mwifiex_adapter *adapter,
u32 firmware_len = fw->fw_len;
u32 offset = 0;
struct sk_buff *skb;
-   u32 txlen, tx_blocks = 0, tries, len;
+   u32 txlen, tx_blocks = 0, tries, len, val;
u32 block_retry_cnt = 0;
struct pcie_service_card *card = adapter->card;
const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
@@ -1998,6 +2055,24 @@ static int mwifiex_prog_fw_w_helper(struct 
mwifiex_adapter *adapter,
goto done;
}
 
+   ret = mwifiex_read_reg(adapter, PCIE_SCRATCH_13_REG, &val);
+   if (ret) {
+   mwifiex_dbg(adapter, FATAL, "Failed to read scratch register 
13\n");
+   goto done;
+   }
+
+   /* PCI

[PATCH v2 2/4] mwifiex: fall back mwifiex_dbg to pr_info when adapter->dev not set

2017-04-07 Thread Xinming Hu
From: Xinming Hu 

mwifiex_dbg will do nothing before adapter->dev get assigned. several logs
lost in this case. it can be avoided by fall back to pr_info.

Signed-off-by: Xinming Hu 
---
v2: enhance adapter->dev null case.(Brain)
---
 drivers/net/wireless/marvell/mwifiex/main.c | 17 -
 drivers/net/wireless/marvell/mwifiex/main.h |  2 ++
 2 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/marvell/mwifiex/main.c 
b/drivers/net/wireless/marvell/mwifiex/main.c
index 98fd491..f3e772f 100644
--- a/drivers/net/wireless/marvell/mwifiex/main.c
+++ b/drivers/net/wireless/marvell/mwifiex/main.c
@@ -1749,18 +1749,25 @@ void _mwifiex_dbg(const struct mwifiex_adapter 
*adapter, int mask,
 {
struct va_format vaf;
va_list args;
+   char msg[MWIFIEX_LOG_LEN];
 
-   if (!adapter->dev || !(adapter->debug_mask & mask))
+   if (!(adapter->debug_mask & mask))
return;
 
va_start(args, fmt);
 
-   vaf.fmt = fmt;
-   vaf.va = &args;
-
-   dev_info(adapter->dev, "%pV", &vaf);
+   if (!adapter->dev) {
+   vsnprintf(msg, MWIFIEX_LOG_LEN, fmt, args);
+   } else {
+   vaf.fmt = fmt;
+   vaf.va = &args;
+   dev_info(adapter->dev, "%pV", &vaf);
+   }
 
va_end(args);
+
+   if (!adapter->dev)
+   pr_info("%s", msg);
 }
 EXPORT_SYMBOL_GPL(_mwifiex_dbg);
 
diff --git a/drivers/net/wireless/marvell/mwifiex/main.h 
b/drivers/net/wireless/marvell/mwifiex/main.h
index f1cb875..d4289a9 100644
--- a/drivers/net/wireless/marvell/mwifiex/main.h
+++ b/drivers/net/wireless/marvell/mwifiex/main.h
@@ -164,6 +164,8 @@ enum {
 /* Address alignment */
 #define MWIFIEX_ALIGN_ADDR(p, a) (((long)(p) + (a) - 1) & ~((a) - 1))
 
+#define MWIFIEX_LOG_LEN 120
+
 /**
  *enum mwifiex_debug_level  -  marvell wifi debug level
  */
-- 
1.8.1.4



[PATCH v2 1/4] mwifiex: remove unnecessary wakeup interrupt number sanity check

2017-04-07 Thread Xinming Hu
From: Xinming Hu 

If wakeup interrupt handler is called, we know that the wakeup
interrupt number is valid, there is no need to check it.

Signed-off-by: Xinming Hu 
Signed-off-by: Cathy Luo 
Reviewed-by: Dmitry Torokhov 
Reviewed-by: Brian Norris 
---
v2: modify description(Dimtry)
---
 drivers/net/wireless/marvell/mwifiex/main.c | 8 +++-
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/marvell/mwifiex/main.c 
b/drivers/net/wireless/marvell/mwifiex/main.c
index 0dfbac8..98fd491 100644
--- a/drivers/net/wireless/marvell/mwifiex/main.c
+++ b/drivers/net/wireless/marvell/mwifiex/main.c
@@ -1513,11 +1513,9 @@ static irqreturn_t mwifiex_irq_wakeup_handler(int irq, 
void *priv)
 {
struct mwifiex_adapter *adapter = priv;
 
-   if (adapter->irq_wakeup >= 0) {
-   dev_dbg(adapter->dev, "%s: wake by wifi", __func__);
-   adapter->wake_by_wifi = true;
-   disable_irq_nosync(irq);
-   }
+   dev_dbg(adapter->dev, "%s: wake by wifi", __func__);
+   adapter->wake_by_wifi = true;
+   disable_irq_nosync(irq);
 
/* Notify PM core we are wakeup source */
pm_wakeup_event(adapter->dev, 0);
-- 
1.8.1.4



[PATCH v2 3/4] mwifiex: pcie: correct scratch register name

2017-04-07 Thread Xinming Hu
From: Xinming Hu 

This patch correct pcie scratch register name, to keep the same with
chipset side definition.

Signed-off-by: Xinming Hu 
---
v2: code clean and prepare for next patch 4/4
---
 drivers/net/wireless/marvell/mwifiex/pcie.c |  4 ++--
 drivers/net/wireless/marvell/mwifiex/pcie.h | 13 +++--
 2 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c 
b/drivers/net/wireless/marvell/mwifiex/pcie.c
index f45ab12..a07cb0a 100644
--- a/drivers/net/wireless/marvell/mwifiex/pcie.c
+++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
@@ -2494,8 +2494,8 @@ static int mwifiex_pcie_host_to_card(struct 
mwifiex_adapter *adapter, u8 type,
struct pcie_service_card *card = adapter->card;
const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
int pcie_scratch_reg[] = {PCIE_SCRATCH_12_REG,
- PCIE_SCRATCH_13_REG,
- PCIE_SCRATCH_14_REG};
+ PCIE_SCRATCH_14_REG,
+ PCIE_SCRATCH_15_REG};
 
if (!p)
return 0;
diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.h 
b/drivers/net/wireless/marvell/mwifiex/pcie.h
index 00e8ee5..7e2450c 100644
--- a/drivers/net/wireless/marvell/mwifiex/pcie.h
+++ b/drivers/net/wireless/marvell/mwifiex/pcie.h
@@ -77,8 +77,9 @@
 #define PCIE_SCRATCH_10_REG0xCE8
 #define PCIE_SCRATCH_11_REG0xCEC
 #define PCIE_SCRATCH_12_REG0xCF0
-#define PCIE_SCRATCH_13_REG0xCF8
-#define PCIE_SCRATCH_14_REG0xCFC
+#define PCIE_SCRATCH_13_REG0xCF4
+#define PCIE_SCRATCH_14_REG0xCF8
+#define PCIE_SCRATCH_15_REG0xCFC
 #define PCIE_RD_DATA_PTR_Q0_Q1  0xC08C
 #define PCIE_WR_DATA_PTR_Q0_Q1  0xC05C
 
@@ -217,8 +218,8 @@ struct mwifiex_pcie_card_reg {
.ring_tx_start_ptr = MWIFIEX_BD_FLAG_TX_START_PTR,
.pfu_enabled = 1,
.sleep_cookie = 0,
-   .fw_dump_ctrl = 0xcf4,
-   .fw_dump_start = 0xcf8,
+   .fw_dump_ctrl = PCIE_SCRATCH_13_REG,
+   .fw_dump_start = PCIE_SCRATCH_14_REG,
.fw_dump_end = 0xcff,
.fw_dump_host_ready = 0xee,
.fw_dump_read_done = 0xfe,
@@ -254,8 +255,8 @@ struct mwifiex_pcie_card_reg {
.ring_tx_start_ptr = MWIFIEX_BD_FLAG_TX_START_PTR,
.pfu_enabled = 1,
.sleep_cookie = 0,
-   .fw_dump_ctrl = 0xcf4,
-   .fw_dump_start = 0xcf8,
+   .fw_dump_ctrl = PCIE_SCRATCH_13_REG,
+   .fw_dump_start = PCIE_SCRATCH_14_REG,
.fw_dump_end = 0xcff,
.fw_dump_host_ready = 0xcc,
.fw_dump_read_done = 0xdd,
-- 
1.8.1.4



Re: [PATCH 00/10] cfg80211: support multiple scheduled scans

2017-04-07 Thread Arend Van Spriel
On 7-4-2017 11:23, Arend van Spriel wrote:
> After the RFC rounds here is multi-scheduled scan submission. What
> has been added since the RFC is support for user-space to specify a
> BSSID in the matchset (PATCH 3/10). As example this could be used for
> roaming algorithm done in user-space. The patches for scheduled scan
> notification api have been collapsed into a single patch and rtnl
> locking was needed for the cfg80211_sched_scan_results() function.
> 
> This series also adds a driver implementation for the new features.
> Not surprisingly being brcmfmac.
> 
> This series applies to master branch of the mac80211-next
> repository. However, there is a patch pending for the
> wireless-drivers-next repository [1] that may give a merge
> conflict.
> 
> [1] https://patchwork.kernel.org/patch/9666945/

Hi Johannes, Kalle,

So in this patch the following hunk is removed:

@@ -,8 +3342,6 @@ static int brcmf_start_internal_escan(struct
brcmf_if *ifp,
goto out_err;
}

-   netinfo_start = brcmf_get_netinfo_array(pfn_result);
-
for (i = 0; i < result_count; i++) {
netinfo = &netinfo_start[i];
if (!netinfo) {

And in this series patch 8/10 adds the following:

@@ -3332,6 +3349,7 @@ static int brcmf_start_internal_escan(struct
brcmf_if *ifp,

netinfo_start = brcmf_get_netinfo_array(pfn_result);

+   bucket_map = 0;
for (i = 0; i < result_count; i++) {
netinfo = &netinfo_start[i];
if (!netinfo) {

So I guess that would cause a merge conflict, right?

Regards,
Arend

> Arend van Spriel (10):
>   nl80211: add request id in scheduled scan event messages
>   nl80211: allow multiple active scheduled scan requests
>   nl80211: add support for BSSIDs in scheduled scan matchsets
>   cfg80211: add request id parameter to .sched_scan_stop() signature
>   cfg80211: add request id to cfg80211_sched_scan_*() api
>   brcmfmac: add firmware feature detection for gscan feature
>   brcmfmac: move scheduled scan wiphy param setting to pno module
>   brcmfmac: add support multi-scheduled scan
>   brcmfmac: add mutex to protect pno requests
>   brcmfmac: add scheduled scan support for specified BSSIDs
> 
>  drivers/net/wireless/ath/ath6kl/cfg80211.c |   6 +-
>  drivers/net/wireless/ath/ath6kl/wmi.c  |   2 +-
>  .../broadcom/brcm80211/brcmfmac/cfg80211.c |  93 +++--
>  .../broadcom/brcm80211/brcmfmac/cfg80211.h |   8 +-
>  .../wireless/broadcom/brcm80211/brcmfmac/core.c|   1 +
>  .../wireless/broadcom/brcm80211/brcmfmac/debug.h   |   2 +
>  .../wireless/broadcom/brcm80211/brcmfmac/feature.c |  22 +-
>  .../wireless/broadcom/brcm80211/brcmfmac/feature.h |   4 +-
>  .../broadcom/brcm80211/brcmfmac/fwil_types.h   |  75 
>  .../net/wireless/broadcom/brcm80211/brcmfmac/pno.c | 460 
> ++---
>  .../net/wireless/broadcom/brcm80211/brcmfmac/pno.h |  55 ++-
>  drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c  |   2 +-
>  drivers/net/wireless/marvell/mwifiex/cfg80211.c|  10 +-
>  drivers/net/wireless/marvell/mwifiex/main.c|   2 +-
>  drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c |   2 +-
>  drivers/net/wireless/marvell/mwifiex/sta_event.c   |   2 +-
>  drivers/net/wireless/marvell/mwifiex/sta_ioctl.c   |   2 +-
>  drivers/net/wireless/ti/wlcore/main.c  |   2 +-
>  include/net/cfg80211.h |  40 +-
>  include/uapi/linux/nl80211.h   |  14 +-
>  net/mac80211/cfg.c |   3 +-
>  net/mac80211/pm.c  |   2 +-
>  net/mac80211/scan.c|   4 +-
>  net/mac80211/util.c|   2 +-
>  net/wireless/core.c|  27 +-
>  net/wireless/core.h|  11 +-
>  net/wireless/nl80211.c | 116 --
>  net/wireless/nl80211.h |   3 +-
>  net/wireless/rdev-ops.h|   8 +-
>  net/wireless/scan.c| 146 +--
>  net/wireless/trace.h   |  54 ++-
>  31 files changed, 945 insertions(+), 235 deletions(-)
> 


[PATCH 01/10] nl80211: add request id in scheduled scan event messages

2017-04-07 Thread Arend van Spriel
For multi-scheduled scan support in subsequent patch a request id
will be added. This patch add this request id to the scheduled
scan event messages. For now the request id will always be zero.
With multi-scheduled scan its value will inform user-space to which
scan the event relates.

Reviewed-by: Hante Meuleman 
Reviewed-by: Pieter-Paul Giesberts 
Reviewed-by: Franky Lin 
Signed-off-by: Arend van Spriel 
---
 include/net/cfg80211.h |  2 ++
 net/wireless/nl80211.c | 23 +++
 net/wireless/nl80211.h |  3 +--
 net/wireless/scan.c|  5 ++---
 4 files changed, 16 insertions(+), 17 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 273b1dc..de3962d 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1641,6 +1641,7 @@ struct cfg80211_bss_select_adjust {
 /**
  * struct cfg80211_sched_scan_request - scheduled scan request description
  *
+ * @reqid: identifies this request.
  * @ssids: SSIDs to scan for (passed in the probe_reqs in active scans)
  * @n_ssids: number of SSIDs
  * @n_channels: total number of channels to scan
@@ -1685,6 +1686,7 @@ struct cfg80211_bss_select_adjust {
  * comparisions.
  */
 struct cfg80211_sched_scan_request {
+   u64 reqid;
struct cfg80211_ssid *ssids;
int n_ssids;
u32 n_channels;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 9910aae..d73f37e 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -7355,8 +7355,7 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
 
rcu_assign_pointer(rdev->sched_scan_req, sched_scan_req);
 
-   nl80211_send_sched_scan(rdev, dev,
-   NL80211_CMD_START_SCHED_SCAN);
+   nl80211_send_sched_scan(sched_scan_req, NL80211_CMD_START_SCHED_SCAN);
return 0;
 
 out_free:
@@ -13203,18 +13202,19 @@ static int nl80211_prep_scan_msg(struct sk_buff *msg,
 
 static int
 nl80211_prep_sched_scan_msg(struct sk_buff *msg,
-   struct cfg80211_registered_device *rdev,
-   struct net_device *netdev,
-   u32 portid, u32 seq, int flags, u32 cmd)
+   struct cfg80211_sched_scan_request *req, u32 cmd)
 {
void *hdr;
 
-   hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
+   hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
if (!hdr)
return -1;
 
-   if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
-   nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex))
+   if (nla_put_u32(msg, NL80211_ATTR_WIPHY,
+   wiphy_to_rdev(req->wiphy)->wiphy_idx) ||
+   nla_put_u32(msg, NL80211_ATTR_IFINDEX, req->dev->ifindex) ||
+   nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, req->reqid,
+ NL80211_ATTR_PAD))
goto nla_put_failure;
 
genlmsg_end(msg, hdr);
@@ -13274,8 +13274,7 @@ void nl80211_send_scan_msg(struct 
cfg80211_registered_device *rdev,
NL80211_MCGRP_SCAN, GFP_KERNEL);
 }
 
-void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev,
-struct net_device *netdev, u32 cmd)
+void nl80211_send_sched_scan(struct cfg80211_sched_scan_request *req, u32 cmd)
 {
struct sk_buff *msg;
 
@@ -13283,12 +13282,12 @@ void nl80211_send_sched_scan(struct 
cfg80211_registered_device *rdev,
if (!msg)
return;
 
-   if (nl80211_prep_sched_scan_msg(msg, rdev, netdev, 0, 0, 0, cmd) < 0) {
+   if (nl80211_prep_sched_scan_msg(msg, req, cmd) < 0) {
nlmsg_free(msg);
return;
}
 
-   genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
+   genlmsg_multicast_netns(&nl80211_fam, wiphy_net(req->wiphy), msg, 0,
NL80211_MCGRP_SCAN, GFP_KERNEL);
 }
 
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index 3cb17cd..d5f6860 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -16,8 +16,7 @@ struct sk_buff *nl80211_build_scan_msg(struct 
cfg80211_registered_device *rdev,
   struct wireless_dev *wdev, bool aborted);
 void nl80211_send_scan_msg(struct cfg80211_registered_device *rdev,
   struct sk_buff *msg);
-void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev,
-struct net_device *netdev, u32 cmd);
+void nl80211_send_sched_scan(struct cfg80211_sched_scan_request *req, u32 cmd);
 void nl80211_common_reg_change_event(enum nl80211_commands cmd_id,
 struct regulatory_request *request);
 
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 21be56b..6f4996c 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -321,8 +321,7 @@ void __cfg80211_sched_scan_results(struct work_struct *wk)
spin_unlock

[PATCH 05/10] cfg80211: add request id to cfg80211_sched_scan_*() api

2017-04-07 Thread Arend van Spriel
Have proper request id filled in the SCHED_SCAN_RESULTS and
SCHED_SCAN_STOPPED notifications toward user-space by having the
driver provide it through the api.

Reviewed-by: Hante Meuleman 
Reviewed-by: Pieter-Paul Giesberts 
Reviewed-by: Franky Lin 
Signed-off-by: Arend van Spriel 
---
 drivers/net/wireless/ath/ath6kl/cfg80211.c |  2 +-
 drivers/net/wireless/ath/ath6kl/wmi.c  |  2 +-
 .../broadcom/brcm80211/brcmfmac/cfg80211.c |  4 +-
 drivers/net/wireless/marvell/mwifiex/cfg80211.c|  6 +--
 drivers/net/wireless/marvell/mwifiex/main.c|  2 +-
 drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c |  2 +-
 drivers/net/wireless/marvell/mwifiex/sta_event.c   |  2 +-
 drivers/net/wireless/marvell/mwifiex/sta_ioctl.c   |  2 +-
 include/net/cfg80211.h | 10 +++--
 net/mac80211/pm.c  |  2 +-
 net/mac80211/scan.c|  4 +-
 net/mac80211/util.c|  2 +-
 net/wireless/core.c|  1 -
 net/wireless/core.h|  1 -
 net/wireless/nl80211.c |  2 +
 net/wireless/scan.c| 45 --
 net/wireless/trace.h   | 26 ++---
 17 files changed, 69 insertions(+), 46 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c 
b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index f7dd45e..d14cc9c 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -171,7 +171,7 @@ static void ath6kl_cfg80211_sscan_disable(struct ath6kl_vif 
*vif)
if (!stopped)
return;
 
-   cfg80211_sched_scan_stopped(ar->wiphy);
+   cfg80211_sched_scan_stopped(ar->wiphy, 0);
 }
 
 static int ath6kl_set_wpa_version(struct ath6kl_vif *vif,
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c 
b/drivers/net/wireless/ath/ath6kl/wmi.c
index 84a6d12..04df853 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.c
+++ b/drivers/net/wireless/ath/ath6kl/wmi.c
@@ -1082,7 +1082,7 @@ void ath6kl_wmi_sscan_timer(unsigned long ptr)
 {
struct ath6kl_vif *vif = (struct ath6kl_vif *) ptr;
 
-   cfg80211_sched_scan_results(vif->ar->wiphy);
+   cfg80211_sched_scan_results(vif->ar->wiphy, 0);
 }
 
 static int ath6kl_wmi_bssinfo_event_rx(struct wmi *wmi, u8 *datap, int len,
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index 42243f7..f2a2026 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -764,7 +764,7 @@ s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info 
*cfg,
brcmf_dbg(SCAN, "scheduled scan completed\n");
cfg->internal_escan = false;
if (!aborted)
-   cfg80211_sched_scan_results(cfg_to_wiphy(cfg));
+   cfg80211_sched_scan_results(cfg_to_wiphy(cfg), 0);
} else if (scan_request) {
struct cfg80211_scan_info info = {
.aborted = aborted,
@@ -3356,7 +3356,7 @@ static int brcmf_start_internal_escan(struct brcmf_if 
*ifp,
goto free_req;
 
 out_err:
-   cfg80211_sched_scan_stopped(wiphy);
+   cfg80211_sched_scan_stopped(wiphy, 0);
 free_req:
kfree(request);
return err;
diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c 
b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
index 91c71066..d7dd58b 100644
--- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
@@ -2036,7 +2036,7 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
 
if (!mwifiex_stop_bg_scan(priv))
-   cfg80211_sched_scan_stopped_rtnl(priv->wdev.wiphy);
+   cfg80211_sched_scan_stopped_rtnl(priv->wdev.wiphy, 0);
 
if (mwifiex_deauthenticate(priv, NULL))
return -EFAULT;
@@ -2304,7 +2304,7 @@ static int mwifiex_cfg80211_inform_ibss_bss(struct 
mwifiex_private *priv)
(int)sme->ssid_len, (char *)sme->ssid, sme->bssid);
 
if (!mwifiex_stop_bg_scan(priv))
-   cfg80211_sched_scan_stopped_rtnl(priv->wdev.wiphy);
+   cfg80211_sched_scan_stopped_rtnl(priv->wdev.wiphy, 0);
 
ret = mwifiex_cfg80211_assoc(priv, sme->ssid_len, sme->ssid, sme->bssid,
 priv->bss_mode, sme->channel, sme, 0);
@@ -2513,7 +2513,7 @@ static int mwifiex_set_ibss_params(struct mwifiex_private 
*priv,
priv->scan_block = false;
 
if (!mwifiex_stop_bg_scan(priv))
-   cfg80211_sched_scan_stopped_rtnl(priv->wdev.wiphy);
+   cfg80211_sched_scan_stopped_rtnl(priv->w

[PATCH 08/10] brcmfmac: add support multi-scheduled scan

2017-04-07 Thread Arend van Spriel
This change adds support for multi-scheduled scan in the driver. It
currently relies on g-scan support in firmware and will set struct
wiphy::max_sched_scan_reqs accordingly. This is limited to 16 concurrent
requests.

The firmware currently has a limit of 64 channels that can be configured
for all requests in total regardless whether there are duplicates. So if
a request uses 35 channels there are 29 channels left for another request.
When user-space does not specify any channels cfg80211 will add all channels
defined by the wiphy instance to the request, which makes reaching the limit
rather easy for dual-band devices.

Reviewed-by: Hante Meuleman 
Reviewed-by: Pieter-Paul Giesberts 
Reviewed-by: Franky Lin 
Signed-off-by: Arend van Spriel 
---
 .../broadcom/brcm80211/brcmfmac/cfg80211.c |  67 +++-
 .../broadcom/brcm80211/brcmfmac/cfg80211.h |   6 +-
 .../wireless/broadcom/brcm80211/brcmfmac/core.c|   1 +
 .../wireless/broadcom/brcm80211/brcmfmac/debug.h   |   2 +
 .../broadcom/brcm80211/brcmfmac/fwil_types.h   |  31 +-
 .../net/wireless/broadcom/brcm80211/brcmfmac/pno.c | 405 ++---
 .../net/wireless/broadcom/brcm80211/brcmfmac/pno.h |  47 ++-
 7 files changed, 468 insertions(+), 91 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index 8d0a5a1..0629ea6 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -721,6 +721,8 @@ s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info 
*cfg,
 {
struct brcmf_scan_params_le params_le;
struct cfg80211_scan_request *scan_request;
+   u64 reqid;
+   u32 bucket;
s32 err = 0;
 
brcmf_dbg(SCAN, "Enter\n");
@@ -751,7 +753,7 @@ s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info 
*cfg,
err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
 ¶ms_le, sizeof(params_le));
if (err)
-   brcmf_err("Scan abort  failed\n");
+   brcmf_err("Scan abort failed\n");
}
 
brcmf_scan_config_mpc(ifp, 1);
@@ -760,11 +762,21 @@ s32 brcmf_notify_escan_complete(struct 
brcmf_cfg80211_info *cfg,
 * e-scan can be initiated internally
 * which takes precedence.
 */
-   if (cfg->internal_escan) {
-   brcmf_dbg(SCAN, "scheduled scan completed\n");
-   cfg->internal_escan = false;
-   if (!aborted)
-   cfg80211_sched_scan_results(cfg_to_wiphy(cfg), 0);
+   if (cfg->int_escan_map) {
+   brcmf_dbg(SCAN, "scheduled scan completed (%x)\n",
+ cfg->int_escan_map);
+   while (cfg->int_escan_map) {
+   bucket = __ffs(cfg->int_escan_map);
+   cfg->int_escan_map &= ~BIT(bucket);
+   reqid = brcmf_pno_find_reqid_by_bucket(cfg->pno,
+  bucket);
+   if (!aborted) {
+   brcmf_dbg(SCAN, "report results: reqid=%llu\n",
+ reqid);
+   cfg80211_sched_scan_results(cfg_to_wiphy(cfg),
+   reqid);
+   }
+   }
} else if (scan_request) {
struct cfg80211_scan_info info = {
.aborted = aborted,
@@ -1013,7 +1025,7 @@ static void brcmf_escan_prep(struct brcmf_cfg80211_info 
*cfg,
if (!ssid_le.SSID_len)
brcmf_dbg(SCAN, "%d: Broadcast scan\n", i);
else
-   brcmf_dbg(SCAN, "%d: scan for  %s size =%d\n",
+   brcmf_dbg(SCAN, "%d: scan for  %.32s size=%d\n",
  i, ssid_le.SSID, ssid_le.SSID_len);
memcpy(ptr, &ssid_le, sizeof(ssid_le));
ptr += sizeof(ssid_le);
@@ -3013,7 +3025,7 @@ void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg)
struct escan_info *escan = &cfg->escan_info;
 
set_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
-   if (cfg->internal_escan || cfg->scan_request) {
+   if (cfg->int_escan_map || cfg->scan_request) {
escan->escan_state = WL_ESCAN_STATE_IDLE;
brcmf_notify_escan_complete(cfg, escan->ifp, true, true);
}
@@ -3036,7 +3048,7 @@ static void brcmf_escan_timeout(unsigned long data)
struct brcmf_cfg80211_info *cfg =
(struct brcmf_cfg80211_info *)data;
 
-   if (cfg->internal_escan || cfg->scan_request) {
+   if (cfg->int_escan_map || cfg->scan_request) {
brcmf_err("timer expi

[PATCH 00/10] cfg80211: support multiple scheduled scans

2017-04-07 Thread Arend van Spriel
After the RFC rounds here is multi-scheduled scan submission. What
has been added since the RFC is support for user-space to specify a
BSSID in the matchset (PATCH 3/10). As example this could be used for
roaming algorithm done in user-space. The patches for scheduled scan
notification api have been collapsed into a single patch and rtnl
locking was needed for the cfg80211_sched_scan_results() function.

This series also adds a driver implementation for the new features.
Not surprisingly being brcmfmac.

This series applies to master branch of the mac80211-next
repository. However, there is a patch pending for the
wireless-drivers-next repository [1] that may give a merge
conflict.

[1] https://patchwork.kernel.org/patch/9666945/

Arend van Spriel (10):
  nl80211: add request id in scheduled scan event messages
  nl80211: allow multiple active scheduled scan requests
  nl80211: add support for BSSIDs in scheduled scan matchsets
  cfg80211: add request id parameter to .sched_scan_stop() signature
  cfg80211: add request id to cfg80211_sched_scan_*() api
  brcmfmac: add firmware feature detection for gscan feature
  brcmfmac: move scheduled scan wiphy param setting to pno module
  brcmfmac: add support multi-scheduled scan
  brcmfmac: add mutex to protect pno requests
  brcmfmac: add scheduled scan support for specified BSSIDs

 drivers/net/wireless/ath/ath6kl/cfg80211.c |   6 +-
 drivers/net/wireless/ath/ath6kl/wmi.c  |   2 +-
 .../broadcom/brcm80211/brcmfmac/cfg80211.c |  93 +++--
 .../broadcom/brcm80211/brcmfmac/cfg80211.h |   8 +-
 .../wireless/broadcom/brcm80211/brcmfmac/core.c|   1 +
 .../wireless/broadcom/brcm80211/brcmfmac/debug.h   |   2 +
 .../wireless/broadcom/brcm80211/brcmfmac/feature.c |  22 +-
 .../wireless/broadcom/brcm80211/brcmfmac/feature.h |   4 +-
 .../broadcom/brcm80211/brcmfmac/fwil_types.h   |  75 
 .../net/wireless/broadcom/brcm80211/brcmfmac/pno.c | 460 ++---
 .../net/wireless/broadcom/brcm80211/brcmfmac/pno.h |  55 ++-
 drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c  |   2 +-
 drivers/net/wireless/marvell/mwifiex/cfg80211.c|  10 +-
 drivers/net/wireless/marvell/mwifiex/main.c|   2 +-
 drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c |   2 +-
 drivers/net/wireless/marvell/mwifiex/sta_event.c   |   2 +-
 drivers/net/wireless/marvell/mwifiex/sta_ioctl.c   |   2 +-
 drivers/net/wireless/ti/wlcore/main.c  |   2 +-
 include/net/cfg80211.h |  40 +-
 include/uapi/linux/nl80211.h   |  14 +-
 net/mac80211/cfg.c |   3 +-
 net/mac80211/pm.c  |   2 +-
 net/mac80211/scan.c|   4 +-
 net/mac80211/util.c|   2 +-
 net/wireless/core.c|  27 +-
 net/wireless/core.h|  11 +-
 net/wireless/nl80211.c | 116 --
 net/wireless/nl80211.h |   3 +-
 net/wireless/rdev-ops.h|   8 +-
 net/wireless/scan.c| 146 +--
 net/wireless/trace.h   |  54 ++-
 31 files changed, 945 insertions(+), 235 deletions(-)

-- 
1.9.1



[PATCH 06/10] brcmfmac: add firmware feature detection for gscan feature

2017-04-07 Thread Arend van Spriel
From: Arend van Spriel 

Detect gscan support in firmware by doing pfn_gscan_cfg iovar with
invalid version.

Reviewed-by: Hante Meuleman 
Reviewed-by: Pieter-Paul Giesberts 
Reviewed-by: Franky Lin 
Signed-off-by: Arend van Spriel 
---
 .../wireless/broadcom/brcm80211/brcmfmac/feature.c | 22 +++-
 .../wireless/broadcom/brcm80211/brcmfmac/feature.h |  4 +-
 .../broadcom/brcm80211/brcmfmac/fwil_types.h   | 59 ++
 3 files changed, 83 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
index 62985f2..8c7ef59 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
@@ -27,6 +27,7 @@
 #include "feature.h"
 #include "common.h"
 
+#define BRCMF_FW_UNSUPPORTED   23
 
 /*
  * expand feature list to array of feature strings.
@@ -113,6 +114,22 @@ static void brcmf_feat_iovar_int_get(struct brcmf_if *ifp,
}
 }
 
+static void brcmf_feat_iovar_data_set(struct brcmf_if *ifp,
+ enum brcmf_feat_id id, char *name,
+ const void *data, size_t len)
+{
+   int err;
+
+   err = brcmf_fil_iovar_data_set(ifp, name, data, len);
+   if (err != -BRCMF_FW_UNSUPPORTED) {
+   brcmf_dbg(INFO, "enabling feature: %s\n", brcmf_feat_names[id]);
+   ifp->drvr->feat_flags |= BIT(id);
+   } else {
+   brcmf_dbg(TRACE, "%s feature check failed: %d\n",
+ brcmf_feat_names[id], err);
+   }
+}
+
 static void brcmf_feat_firmware_capabilities(struct brcmf_if *ifp)
 {
char caps[256];
@@ -136,11 +153,14 @@ void brcmf_feat_attach(struct brcmf_pub *drvr)
 {
struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0);
struct brcmf_pno_macaddr_le pfn_mac;
+   struct brcmf_gscan_config gscan_cfg;
u32 wowl_cap;
s32 err;
 
brcmf_feat_firmware_capabilities(ifp);
-
+   memset(&gscan_cfg, 0, sizeof(gscan_cfg));
+   brcmf_feat_iovar_data_set(ifp, BRCMF_FEAT_GSCAN, "pfn_gscan_cfg",
+ &gscan_cfg, sizeof(gscan_cfg));
brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_PNO, "pfn");
if (drvr->bus_if->wowl_supported)
brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_WOWL, "wowl");
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h
index db4733a..c1dbd17 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h
@@ -31,6 +31,7 @@
  * WOWL_GTK: (WOWL) GTK rekeying offload
  * WOWL_ARP_ND: ARP and Neighbor Discovery offload support during WOWL.
  * MFP: 802.11w Management Frame Protection.
+ * GSCAN: enhanced scan offload feature.
  */
 #define BRCMF_FEAT_LIST \
BRCMF_FEAT_DEF(MBSS) \
@@ -44,7 +45,8 @@
BRCMF_FEAT_DEF(WOWL_ND) \
BRCMF_FEAT_DEF(WOWL_GTK) \
BRCMF_FEAT_DEF(WOWL_ARP_ND) \
-   BRCMF_FEAT_DEF(MFP)
+   BRCMF_FEAT_DEF(MFP) \
+   BRCMF_FEAT_DEF(GSCAN)
 
 /*
  * Quirks:
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
index 9a1eb5a..8c18fad 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
@@ -835,4 +835,63 @@ struct brcmf_gtk_keyinfo_le {
u8 replay_counter[BRCMF_RSN_REPLAY_LEN];
 };
 
+/**
+ * struct brcmf_gscan_bucket_config - configuration data for channel bucket.
+ *
+ * @bucket_end_index: !unknown!
+ * @bucket_freq_multiple: !unknown!
+ * @flag: !unknown!
+ * @reserved: !unknown!
+ * @repeat: !unknown!
+ * @max_freq_multiple: !unknown!
+ */
+struct brcmf_gscan_bucket_config {
+   u8 bucket_end_index;
+   u8 bucket_freq_multiple;
+   u8 flag;
+   u8 reserved;
+   __le16 repeat;
+   __le16 max_freq_multiple;
+};
+
+/* version supported which must match firmware */
+#define BRCMF_GSCAN_CFG_VERSION 1
+
+/**
+ * enum brcmf_gscan_cfg_flags - bit values for gscan flags.
+ *
+ * @BRCMF_GSCAN_CFG_FLAGS_ALL_RESULTS: send probe responses/beacons to host.
+ * @BRCMF_GSCAN_CFG_FLAGS_CHANGE_ONLY: indicated only flags member is changed.
+ */
+enum brcmf_gscan_cfg_flags {
+   BRCMF_GSCAN_CFG_FLAGS_ALL_RESULTS = BIT(0),
+   BRCMF_GSCAN_CFG_FLAGS_CHANGE_ONLY = BIT(7),
+};
+
+/**
+ * struct brcmf_gscan_config - configuration data for gscan.
+ *
+ * @version: version of the api to match firmware.
+ * @flags: flags according %enum brcmf_gscan_cfg_flags.
+ * @buffer_threshold: percentage threshold of buffer to generate an event.
+ * @swc_nbssid_threshold: number of BSSIDs with significant change that
+ * will generate an event.
+ * @swc_rssi_window_size: size of rssi cache buff

[PATCH 10/10] brcmfmac: add scheduled scan support for specified BSSIDs

2017-04-07 Thread Arend van Spriel
Add support to handle scheduled scan request containing BSSID in
the matchsets. The firmware can send event upon finding BSSIDs and
SSIDs. To get these in one event the bit REPORT_SEPERATELY needed
to be removed from the flags in brcmf_pno_config().

Reviewed-by: Hante Meuleman 
Reviewed-by: Pieter-Paul Giesberts 
Reviewed-by: Franky Lin 
Signed-off-by: Arend van Spriel 
---
 .../broadcom/brcm80211/brcmfmac/fwil_types.h   | 11 +
 .../net/wireless/broadcom/brcm80211/brcmfmac/pno.c | 56 --
 2 files changed, 52 insertions(+), 15 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
index cc832ab..51d89c6 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
@@ -806,6 +806,17 @@ struct brcmf_pno_macaddr_le {
 };
 
 /**
+ * struct brcmf_pno_bssid_le - bssid configuration for PNO scan.
+ *
+ * @bssid: BSS network identifier.
+ * @flags: flags for this BSSID.
+ */
+struct brcmf_pno_bssid_le {
+   u8 bssid[ETH_ALEN];
+   __le16 flags;
+};
+
+/**
  * struct brcmf_pktcnt_le - packet counters.
  *
  * @rx_good_pkt: packets (MSDUs & MMPDUs) received from this station
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c
index 4c17a1c..f178af0 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c
@@ -120,7 +120,6 @@ static int brcmf_pno_config(struct brcmf_if *ifp, u32 
scan_freq,
 
/* set extra pno params */
flags = BIT(BRCMF_PNO_IMMEDIATE_SCAN_BIT) |
-   BIT(BRCMF_PNO_REPORT_SEPARATELY_BIT) |
BIT(BRCMF_PNO_ENABLE_ADAPTSCAN_BIT);
pfn_param.repeat = BRCMF_PNO_REPEAT;
pfn_param.exp = BRCMF_PNO_FREQ_EXPO_MAX;
@@ -205,6 +204,7 @@ static int brcmf_pno_add_ssid(struct brcmf_if *ifp, struct 
cfg80211_ssid *ssid,
  bool active)
 {
struct brcmf_pno_net_param_le pfn;
+   int err;
 
pfn.auth = cpu_to_le32(WLAN_AUTH_OPEN);
pfn.wpa_auth = cpu_to_le32(BRCMF_PNO_WPA_AUTH_ANY);
@@ -215,7 +215,28 @@ static int brcmf_pno_add_ssid(struct brcmf_if *ifp, struct 
cfg80211_ssid *ssid,
pfn.flags = cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT);
pfn.ssid.SSID_len = cpu_to_le32(ssid->ssid_len);
memcpy(pfn.ssid.SSID, ssid->ssid, ssid->ssid_len);
-   return brcmf_fil_iovar_data_set(ifp, "pfn_add", &pfn, sizeof(pfn));
+
+   brcmf_dbg(SCAN, "adding ssid=%.32s (active=%d)\n", ssid->ssid, active);
+   err = brcmf_fil_iovar_data_set(ifp, "pfn_add", &pfn, sizeof(pfn));
+   if (err < 0)
+   brcmf_err("adding failed: err=%d\n", err);
+   return err;
+}
+
+static int brcmf_pno_add_bssid(struct brcmf_if *ifp, const u8 *bssid)
+{
+   struct brcmf_pno_bssid_le bssid_cfg;
+   int err;
+
+   memcpy(bssid_cfg.bssid, bssid, ETH_ALEN);
+   bssid_cfg.flags = 0;
+
+   brcmf_dbg(SCAN, "adding bssid=%pM\n", bssid);
+   err = brcmf_fil_iovar_data_set(ifp, "pfn_add_bssid", &bssid_cfg,
+  sizeof(bssid_cfg));
+   if (err < 0)
+   brcmf_err("adding failed: err=%d\n", err);
+   return err;
 }
 
 static bool brcmf_is_ssid_active(struct cfg80211_ssid *ssid,
@@ -342,8 +363,8 @@ static int brcmf_pno_prep_fwconfig(struct brcmf_pno_info 
*pi,
return err;
 }
 
-static int brcmf_pno_config_ssids(struct brcmf_if *ifp,
- struct brcmf_pno_info *pi)
+static int brcmf_pno_config_networks(struct brcmf_if *ifp,
+struct brcmf_pno_info *pi)
 {
struct cfg80211_sched_scan_request *r;
struct cfg80211_match_set *ms;
@@ -355,16 +376,16 @@ static int brcmf_pno_config_ssids(struct brcmf_if *ifp,
 
for (j = 0; j < r->n_match_sets; j++) {
ms = &r->match_sets[j];
-   if (!ms->ssid.ssid_len)
-   continue;
-   active = brcmf_is_ssid_active(&ms->ssid, r);
-   brcmf_dbg(SCAN, "adding %.32s (active=%d)\n",
- ms->ssid.ssid, active);
-   err = brcmf_pno_add_ssid(ifp, &ms->ssid, active);
-   if (err < 0) {
-   brcmf_err("adding failed: err=%d\n", err);
-   return err;
+   if (ms->ssid.ssid_len) {
+   active = brcmf_is_ssid_active(&ms->ssid, r);
+   err = brcmf_pno_add_ssid(ifp, &ms->ssid,
+active);
}
+   if (!err && is_valid_ether_addr(ms->bssid))
+   e

[PATCH 09/10] brcmfmac: add mutex to protect pno requests

2017-04-07 Thread Arend van Spriel
The request references kept in pno are accessed in user-space context
and in firmware event handler context. As such we need to protect it
with a lock. As both context allow sleep a mutex seems appropriate.

Reviewed-by: Hante Meuleman 
Reviewed-by: Pieter-Paul Giesberts 
Reviewed-by: Franky Lin 
Signed-off-by: Arend van Spriel 
---
 .../net/wireless/broadcom/brcm80211/brcmfmac/pno.c | 33 --
 1 file changed, 25 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c
index aa323534..4c17a1c 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c
@@ -43,6 +43,7 @@
 struct brcmf_pno_info {
int n_reqs;
struct cfg80211_sched_scan_request *reqs[BRCMF_PNO_MAX_BUCKETS];
+   struct mutex req_lock;
 };
 
 #define ifp_to_pno(_ifp)   (_ifp)->drvr->config->pno
@@ -55,13 +56,17 @@ static int brcmf_pno_store_request(struct brcmf_pno_info 
*pi,
return -ENOSPC;
}
brcmf_dbg(SCAN, "reqid=%llu\n", req->reqid);
+   mutex_lock(&pi->req_lock);
pi->reqs[pi->n_reqs++] = req;
+   mutex_unlock(&pi->req_lock);
return 0;
 }
 
 static int brcmf_pno_remove_request(struct brcmf_pno_info *pi, u64 reqid)
 {
-   int i;
+   int i, err = 0;
+
+   mutex_lock(&pi->req_lock);
 
/* find request */
for (i = 0; i < pi->n_reqs; i++) {
@@ -71,7 +76,8 @@ static int brcmf_pno_remove_request(struct brcmf_pno_info 
*pi, u64 reqid)
/* request not found */
if (WARN_ON(i == pi->n_reqs)) {
brcmf_err("reqid not found\n");
-   return -ENOENT;
+   err = -ENOENT;
+   goto done;
}
 
brcmf_dbg(SCAN, "reqid=%llu\n", reqid);
@@ -79,14 +85,17 @@ static int brcmf_pno_remove_request(struct brcmf_pno_info 
*pi, u64 reqid)
 
/* if last we are done */
if (!pi->n_reqs || i == pi->n_reqs)
-   return 0;
+   goto done;
 
/* fill the gap with remaining requests */
while (i <= pi->n_reqs - 1) {
pi->reqs[i] = pi->reqs[i + 1];
i++;
}
-   return 0;
+
+done:
+   mutex_unlock(&pi->req_lock);
+   return err;
 }
 
 static int brcmf_pno_channel_config(struct brcmf_if *ifp,
@@ -494,6 +503,7 @@ int brcmf_pno_attach(struct brcmf_cfg80211_info *cfg)
return -ENOMEM;
 
cfg->pno = pi;
+   mutex_init(&pi->req_lock);
return 0;
 }
 
@@ -506,6 +516,7 @@ void brcmf_pno_detach(struct brcmf_cfg80211_info *cfg)
cfg->pno = NULL;
 
WARN_ON(pi->n_reqs);
+   mutex_destroy(&pi->req_lock);
kfree(pi);
 }
 
@@ -521,11 +532,15 @@ void brcmf_pno_wiphy_params(struct wiphy *wiphy, bool 
gscan)
 
 u64 brcmf_pno_find_reqid_by_bucket(struct brcmf_pno_info *pi, u32 bucket)
 {
-   /* bucket appears to be gone */
-   if (bucket >= pi->n_reqs)
-   return 0;
+   u64 reqid = 0;
+
+   mutex_lock(&pi->req_lock);
+
+   if (bucket < pi->n_reqs)
+   reqid = pi->reqs[bucket]->reqid;
 
-   return pi->reqs[bucket]->reqid;
+   mutex_unlock(&pi->req_lock);
+   return reqid;
 }
 
 u32 brcmf_pno_get_bucket_map(struct brcmf_pno_info *pi,
@@ -536,6 +551,7 @@ u32 brcmf_pno_get_bucket_map(struct brcmf_pno_info *pi,
u32 bucket_map = 0;
int i, j;
 
+   mutex_lock(&pi->req_lock);
for (i = 0; i < pi->n_reqs; i++) {
req = pi->reqs[i];
 
@@ -550,5 +566,6 @@ u32 brcmf_pno_get_bucket_map(struct brcmf_pno_info *pi,
}
}
}
+   mutex_unlock(&pi->req_lock);
return bucket_map;
 }
-- 
1.9.1



[PATCH 04/10] cfg80211: add request id parameter to .sched_scan_stop() signature

2017-04-07 Thread Arend van Spriel
For multiple scheduled scan support the driver needs to know which
scheduled scan request is being stopped. Pass the request id in the
.sched_scan_stop() callback.

Reviewed-by: Hante Meuleman 
Reviewed-by: Pieter-Paul Giesberts 
Reviewed-by: Franky Lin 
Signed-off-by: Arend van Spriel 
---
 drivers/net/wireless/ath/ath6kl/cfg80211.c|  2 +-
 .../net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c   |  6 +++---
 drivers/net/wireless/marvell/mwifiex/cfg80211.c   |  2 +-
 include/net/cfg80211.h| 15 ---
 net/mac80211/cfg.c|  3 ++-
 net/wireless/rdev-ops.h   |  6 +++---
 net/wireless/scan.c   |  2 +-
 net/wireless/trace.h  | 10 +-
 8 files changed, 24 insertions(+), 22 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c 
b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index b7dd6f4..f7dd45e 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -3355,7 +3355,7 @@ static int ath6kl_cfg80211_sscan_start(struct wiphy 
*wiphy,
 }
 
 static int ath6kl_cfg80211_sscan_stop(struct wiphy *wiphy,
- struct net_device *dev)
+ struct net_device *dev, u64 reqid)
 {
struct ath6kl_vif *vif = netdev_priv(dev);
bool stopped;
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index 4725a0a..42243f7 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -3389,7 +3389,7 @@ static int brcmf_start_internal_escan(struct brcmf_if 
*ifp,
 }
 
 static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,
- struct net_device *ndev)
+ struct net_device *ndev, u64 reqid)
 {
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
struct brcmf_if *ifp = netdev_priv(ndev);
@@ -3591,7 +3591,7 @@ static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
  cfg->wowl.pre_pmmode);
cfg->wowl.active = false;
if (cfg->wowl.nd_enabled) {
-   brcmf_cfg80211_sched_scan_stop(cfg->wiphy, ifp->ndev);
+   brcmf_cfg80211_sched_scan_stop(cfg->wiphy, ifp->ndev, 
0);
brcmf_fweh_unregister(cfg->pub, BRCMF_E_PFN_NET_FOUND);
brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
brcmf_notify_sched_scan_results);
@@ -3675,7 +3675,7 @@ static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
 
/* Stop scheduled scan */
if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO))
-   brcmf_cfg80211_sched_scan_stop(wiphy, ndev);
+   brcmf_cfg80211_sched_scan_stop(wiphy, ndev, 0);
 
/* end any scanning */
if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c 
b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
index b734197..91c71066 100644
--- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
@@ -2701,7 +2701,7 @@ static int mwifiex_set_ibss_params(struct mwifiex_private 
*priv,
  * previous bgscan configuration in the firmware
  */
 static int mwifiex_cfg80211_sched_scan_stop(struct wiphy *wiphy,
-   struct net_device *dev)
+   struct net_device *dev, u64 reqid)
 {
struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
 
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 0736aea..be36606 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2763,12 +2763,12 @@ struct cfg80211_nan_func {
  * @set_cqm_txe_config: Configure connection quality monitor TX error
  * thresholds.
  * @sched_scan_start: Tell the driver to start a scheduled scan.
- * @sched_scan_stop: Tell the driver to stop an ongoing scheduled scan. This
- * call must stop the scheduled scan and be ready for starting a new one
- * before it returns, i.e. @sched_scan_start may be called immediately
- * after that again and should not fail in that case. The driver should
- * not call cfg80211_sched_scan_stopped() for a requested stop (when this
- * method returns 0.)
+ * @sched_scan_stop: Tell the driver to stop an ongoing scheduled scan with
+ * given request id. This call must stop the scheduled scan and be ready
+ * for starting a new one before it returns, i.e. @sched_scan_start may be
+ * called immediately after that again and should not fail in that case.
+ * Th

[PATCH 03/10] nl80211: add support for BSSIDs in scheduled scan matchsets

2017-04-07 Thread Arend van Spriel
This patch allows for the scheduled scan request to specify matchsets
for specific BSSIDs.

Reviewed-by: Hante Meuleman 
Reviewed-by: Pieter-Paul Giesberts 
Reviewed-by: Franky Lin 
Signed-off-by: Arend van Spriel 
---
 include/net/cfg80211.h   |  6 +-
 include/uapi/linux/nl80211.h |  2 ++
 net/wireless/nl80211.c   | 41 +++--
 3 files changed, 38 insertions(+), 11 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 4d9d49a..0736aea 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1605,11 +1605,15 @@ static inline void get_random_mask_addr(u8 *buf, const 
u8 *addr, const u8 *mask)
 /**
  * struct cfg80211_match_set - sets of attributes to match
  *
- * @ssid: SSID to be matched; may be zero-length for no match (RSSI only)
+ * @ssid: SSID to be matched; may be zero-length in case of BSSID match
+ * or no match (RSSI only)
+ * @bssid: BSSID to be matched; may be all-zero BSSID in case of SSID match
+ * or no match (RSSI only)
  * @rssi_thold: don't report scan results below this threshold (in s32 dBm)
  */
 struct cfg80211_match_set {
struct cfg80211_ssid ssid;
+   u8 bssid[ETH_ALEN];
s32 rssi_thold;
 };
 
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index f34127d..925eb38 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -3209,6 +3209,7 @@ enum nl80211_reg_rule_attr {
  * BSS-es in the specified band is to be adjusted before doing
  * RSSI-based BSS selection. The attribute value is a packed structure
  * value as specified by &struct nl80211_bss_select_rssi_adjust.
+ * @NL80211_SCHED_SCAN_MATCH_ATTR_BSSID: BSSID to be used for matching.
  * @NL80211_SCHED_SCAN_MATCH_ATTR_MAX: highest scheduled scan filter
  * attribute number currently defined
  * @__NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST: internal use
@@ -3220,6 +3221,7 @@ enum nl80211_sched_scan_match_attr {
NL80211_SCHED_SCAN_MATCH_ATTR_RSSI,
NL80211_SCHED_SCAN_MATCH_ATTR_RELATIVE_RSSI,
NL80211_SCHED_SCAN_MATCH_ATTR_RSSI_ADJUST,
+   NL80211_SCHED_SCAN_MATCH_ATTR_BSSID,
 
/* keep last */
__NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 2150cfe..611d92c 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -497,6 +497,8 @@ enum nl80211_multicast_groups {
 nl80211_match_policy[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1] = {
[NL80211_SCHED_SCAN_MATCH_ATTR_SSID] = { .type = NLA_BINARY,
 .len = IEEE80211_MAX_SSID_LEN 
},
+   [NL80211_SCHED_SCAN_MATCH_ATTR_BSSID] = { .type = NLA_BINARY,
+ .len = ETH_ALEN },
[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI] = { .type = NLA_U32 },
 };
 
@@ -7027,8 +7029,15 @@ static int nl80211_abort_scan(struct sk_buff *skb, 
struct genl_info *info)
   attr, nl80211_match_policy);
if (err)
return ERR_PTR(err);
+
+   /* SSID and BSSID are mutually exclusive */
+   if (tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID] &&
+   tb[NL80211_SCHED_SCAN_MATCH_ATTR_BSSID])
+   return ERR_PTR(-EINVAL);
+
/* add other standalone attributes here */
-   if (tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID]) {
+   if (tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID] ||
+   tb[NL80211_SCHED_SCAN_MATCH_ATTR_BSSID]) {
n_match_sets++;
continue;
}
@@ -7199,7 +7208,7 @@ static int nl80211_abort_scan(struct sk_buff *skb, struct 
genl_info *info)
nla_for_each_nested(attr,
attrs[NL80211_ATTR_SCHED_SCAN_MATCH],
tmp) {
-   struct nlattr *ssid, *rssi;
+   struct nlattr *ssid, *bssid, *rssi;
 
err = nla_parse_nested(tb,
   
NL80211_SCHED_SCAN_MATCH_ATTR_MAX,
@@ -7207,7 +7216,8 @@ static int nl80211_abort_scan(struct sk_buff *skb, struct 
genl_info *info)
if (err)
goto out_free;
ssid = tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID];
-   if (ssid) {
+   bssid = tb[NL80211_SCHED_SCAN_MATCH_ATTR_BSSID];
+   if (ssid || bssid) {
if (WARN_ON(i >= n_match_sets)) {
/* this indicates a programming error,
 * the loop above should have verified
@@ -7217,14 +7227,25 @@ static int nl80211_abort_sc

[PATCH 07/10] brcmfmac: move scheduled scan wiphy param setting to pno module

2017-04-07 Thread Arend van Spriel
As pno module is providing scheduled scan functionality have it taking
care of setting related wiphy parameters as well.

Reviewed-by: Hante Meuleman 
Reviewed-by: Pieter-Paul Giesberts 
Reviewed-by: Franky Lin 
Signed-off-by: Arend van Spriel 
---
 .../wireless/broadcom/brcm80211/brcmfmac/cfg80211.c| 18 +-
 .../wireless/broadcom/brcm80211/brcmfmac/cfg80211.h|  2 ++
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c | 10 ++
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.h |  8 
 4 files changed, 25 insertions(+), 13 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index f2a2026..8d0a5a1 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -6355,16 +6355,6 @@ static int brcmf_setup_ifmodes(struct wiphy *wiphy, 
struct brcmf_if *ifp)
return -ENOMEM;
 }
 
-static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
-{
-   /* scheduled scan settings */
-   wiphy->max_sched_scan_reqs = 1;
-   wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT;
-   wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
-   wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
-   wiphy->max_sched_scan_plan_interval = BRCMF_PNO_SCHED_SCAN_MAX_PERIOD;
-}
-
 #ifdef CONFIG_PM
 static const struct wiphy_wowlan_support brcmf_wowlan_support = {
.flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT,
@@ -6411,6 +6401,7 @@ static int brcmf_setup_wiphy(struct wiphy *wiphy, struct 
brcmf_if *ifp)
const struct ieee80211_iface_combination *combo;
struct ieee80211_supported_band *band;
u16 max_interfaces = 0;
+   bool gscan;
__le32 bandlist[3];
u32 n_bands;
int err, i;
@@ -6459,9 +6450,10 @@ static int brcmf_setup_wiphy(struct wiphy *wiphy, struct 
brcmf_if *ifp)
wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
wiphy->mgmt_stypes = brcmf_txrx_stypes;
wiphy->max_remain_on_channel_duration = 5000;
-   if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO))
-   brcmf_wiphy_pno_params(wiphy);
-
+   if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO)) {
+   gscan = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_GSCAN);
+   brcmf_pno_wiphy_params(wiphy, gscan);
+   }
/* vendor commands/events support */
wiphy->vendor_commands = brcmf_vendor_cmds;
wiphy->n_vendor_commands = BRCMF_VNDR_CMDS_LAST - 1;
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
index 8f19d95..a1c2e0a 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
@@ -24,6 +24,8 @@
 #include "fwil_types.h"
 #include "p2p.h"
 
+#define BRCMF_SCAN_IE_LEN_MAX  2048
+
 #define WL_NUM_SCAN_MAX10
 #define WL_TLV_INFO_MAX1024
 #define WL_BSS_INFO_MAX2048
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c
index 9a25e79..cc0e6a4 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c
@@ -241,3 +241,13 @@ int brcmf_pno_start_sched_scan(struct brcmf_if *ifp,
return ret;
 }
 
+void brcmf_pno_wiphy_params(struct wiphy *wiphy, bool gscan)
+{
+   /* scheduled scan settings */
+   wiphy->max_sched_scan_reqs = gscan ? 2 : 1;
+   wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT;
+   wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
+   wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
+   wiphy->max_sched_scan_plan_interval = BRCMF_PNO_SCHED_SCAN_MAX_PERIOD;
+}
+
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.h 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.h
index bae55b2..07ec51f 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.h
@@ -37,4 +37,12 @@
 int brcmf_pno_start_sched_scan(struct brcmf_if *ifp,
   struct cfg80211_sched_scan_request *req);
 
+/**
+ * brcmf_pno_wiphy_params - fill scheduled scan parameters in wiphy instance.
+ *
+ * @wiphy: wiphy instance to be used.
+ * @gscan: indicates whether the device has support for g-scan feature.
+ */
+void brcmf_pno_wiphy_params(struct wiphy *wiphy, bool gscan);
+
 #endif /* _BRCMF_PNO_H */
-- 
1.9.1



[PATCH 02/10] nl80211: allow multiple active scheduled scan requests

2017-04-07 Thread Arend van Spriel
This patch implements the idea to have multiple scheduled scan requests
running concurrently. It mainly illustrates how to deal with the incoming
request from user-space in terms of backward compatibility. In order to
use multiple scheduled scans user-space needs to provide a flag attribute
NL80211_ATTR_SCHED_SCAN_MULTI to indicate support. If not the request is
treated as a legacy scan.

Drivers currently supporting scheduled scan are now indicating they support
a single scheduled scan request. This obsoletes WIPHY_FLAG_SUPPORTS_SCHED_SCAN.

Reviewed-by: Hante Meuleman 
Reviewed-by: Pieter-Paul Giesberts 
Reviewed-by: Franky Lin 
Signed-off-by: Arend van Spriel 
---
 drivers/net/wireless/ath/ath6kl/cfg80211.c |   2 +-
 .../broadcom/brcm80211/brcmfmac/cfg80211.c |   2 +-
 drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c  |   2 +-
 drivers/net/wireless/marvell/mwifiex/cfg80211.c|   2 +-
 drivers/net/wireless/ti/wlcore/main.c  |   2 +-
 include/net/cfg80211.h |   7 +-
 include/uapi/linux/nl80211.h   |  12 ++-
 net/wireless/core.c|  26 --
 net/wireless/core.h|  10 +-
 net/wireless/nl80211.c |  50 --
 net/wireless/rdev-ops.h|   2 +-
 net/wireless/scan.c| 102 +
 net/wireless/trace.h   |  18 ++--
 13 files changed, 186 insertions(+), 51 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c 
b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index 363b30a..b7dd6f4 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -3976,7 +3976,7 @@ int ath6kl_cfg80211_init(struct ath6kl *ar)
WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
 
if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN_V2, ar->fw_capabilities))
-   ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
+   ar->wiphy->max_sched_scan_reqs = 1;
 
if (test_bit(ATH6KL_FW_CAPABILITY_INACTIVITY_TIMEOUT,
 ar->fw_capabilities))
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index 944b83c..4725a0a 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -6358,11 +6358,11 @@ static int brcmf_setup_ifmodes(struct wiphy *wiphy, 
struct brcmf_if *ifp)
 static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
 {
/* scheduled scan settings */
+   wiphy->max_sched_scan_reqs = 1;
wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT;
wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
wiphy->max_sched_scan_plan_interval = BRCMF_PNO_SCHED_SCAN_MAX_PERIOD;
-   wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
 }
 
 #ifdef CONFIG_PM
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
index d37b169..5f1d648 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
@@ -619,7 +619,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
else
hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
 
-   hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
+   hw->wiphy->max_sched_scan_reqs = 1;
hw->wiphy->max_sched_scan_ssids = PROBE_OPTION_MAX;
hw->wiphy->max_match_sets = IWL_SCAN_MAX_PROFILES;
/* we create the 802.11 header and zero length SSID IE. */
diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c 
b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
index 1e3bd43..b734197 100644
--- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
@@ -4279,7 +4279,6 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter 
*adapter)
wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME |
WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD |
WIPHY_FLAG_AP_UAPSD |
-   WIPHY_FLAG_SUPPORTS_SCHED_SCAN |
WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
WIPHY_FLAG_HAS_CHANNEL_SWITCH |
WIPHY_FLAG_PS_ON_BY_DEFAULT;
@@ -4298,6 +4297,7 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter 
*adapter)
NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P;
 
+   wiphy->max_sched_scan_reqs = 1;
wiphy->max_sched_scan_ssids = MWIFIEX_MAX_SSID_LIST_LENGTH;
wiphy->max_sched_scan_ie_len = MWIFIEX_MAX_VSIE_LEN;
wiphy->max_match_sets = MWIFIEX_MAX_SSID_LIST_LENGTH;
diff --git 

Re: [PATCH] nfc: fix get_unaligned_...() misuses

2017-04-07 Thread kbuild test robot
Hi Al,

[auto build test ERROR on linus/master]
[also build test ERROR on v4.11-rc5 next-20170406]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Al-Viro/nfc-fix-get_unaligned_-misuses/20170407-123722
config: x86_64-randconfig-a0-04071419 (attached as .config)
compiler: gcc-4.4 (Debian 4.4.7-8) 4.4.7
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64 

All errors (new ones prefixed by >>):

>> drivers/nfc//nfcmrvl/fw_dnld.c:20:29: error: linux/unaligned.h: No such file 
>> or directory
   drivers/nfc//nfcmrvl/fw_dnld.c: In function 'process_state_fw_dnld':
>> drivers/nfc//nfcmrvl/fw_dnld.c:284: error: implicit declaration of function 
>> 'get_unaligned_le16'

vim +/get_unaligned_le16 +284 drivers/nfc//nfcmrvl/fw_dnld.c

   278  skb_pull(skb, 3);
   279  if (skb->data[0] != HELPER_CMD_PACKET_FORMAT || 
skb->len != 5) {
   280  nfc_err(priv->dev, "bad command");
   281  return -EINVAL;
   282  }
   283  skb_pull(skb, 1);
 > 284  len = get_unaligned_le16(skb->data);
   285  skb_pull(skb, 2);
   286  comp_len = get_unaligned_le16(skb->data);
   287  memcpy(&comp_len, skb->data, 2);

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation


.config.gz
Description: application/gzip


Re: [PATCH] nfc: fix get_unaligned_...() misuses

2017-04-07 Thread kbuild test robot
Hi Al,

[auto build test ERROR on linus/master]
[also build test ERROR on v4.11-rc5 next-20170406]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Al-Viro/nfc-fix-get_unaligned_-misuses/20170407-123722
config: i386-allmodconfig (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
# save the attached .config to linux build tree
make ARCH=i386 

All errors (new ones prefixed by >>):

>> drivers/nfc/nxp-nci/firmware.c:27:29: fatal error: linux/unaligned.h: No 
>> such file or directory
#include 
^
   compilation terminated.

vim +27 drivers/nfc/nxp-nci/firmware.c

21   * along with this program; if not, see <http://www.gnu.org/licenses/>.
22   */
23  
24  #include 
25  #include 
26  #include 
  > 27  #include 
28  
29  #include "nxp-nci.h"
30  

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation


.config.gz
Description: application/gzip