* Re: [PATCH] Modify is_zero_ether_addr() to handle byte-aligned addresses
From: Joe Perches @ 2016-08-13 4:00 UTC (permalink / raw)
To: David Miller, pgynther; +Cc: linux-wireless, kvalo, akarwar
In-Reply-To: <20160812.202613.197744153887748230.davem@davemloft.net>
On Fri, 2016-08-12 at 20:26 -0700, David Miller wrote:
> From: Petri Gynther <pgynther@google.com>
> Date: Fri, 12 Aug 2016 17:15:30 -0700
>
> > Root cause:
> > mwifiex driver calls is_zero_ether_addr() against byte-aligned address:
>
> MAC addresses really must be 16-bit aligned to be used with any of the
> ethernet address manipulation and test interfaces.
>
> Therefore this driver should do whatever it takes to avoid passing
> a byte-aligned MAC address anywhere.
>
> We _SHOULD NOT_ add support for byte aligned addresses to these
> interfaces, nor add routines which by-name can handle them.
My recollection is that batman uses unaligned addresses
and some form of _unaligned tests are required there.
It seems that other wireless drivers also use _unaligned
in various forms.
> Fix this driver instead of polluting out common interfaces
> unnecessarily.
One solution might be to copy a hardware interface structure
to another struct with appropriate alignment.
^ permalink raw reply
* Re: [PATCH] Modify is_zero_ether_addr() to handle byte-aligned addresses
From: Petri Gynther @ 2016-08-13 3:44 UTC (permalink / raw)
To: David Miller; +Cc: linux-wireless, kvalo, Joe Perches, Amitkumar Karwar
In-Reply-To: <20160812.202613.197744153887748230.davem@davemloft.net>
On Fri, Aug 12, 2016 at 8:26 PM, David Miller <davem@davemloft.net> wrote:
> From: Petri Gynther <pgynther@google.com>
> Date: Fri, 12 Aug 2016 17:15:30 -0700
>
>> Root cause:
>> mwifiex driver calls is_zero_ether_addr() against byte-aligned address:
>
> MAC addresses really must be 16-bit aligned to be used with any of the
> ethernet address manipulation and test interfaces.
>
> Therefore this driver should do whatever it takes to avoid passing
> a byte-aligned MAC address anywhere.
>
> We _SHOULD NOT_ add support for byte aligned addresses to these
> interfaces, nor add routines which by-name can handle them.
>
ether_addr_equal_unaligned() exists.
commit 73eaef87e98a96fe8b8a586f916b2721bf512efa
Author: Joe Perches <joe@perches.com>
Date: Fri Dec 6 14:21:01 2013 -0800
etherdevice: Add ether_addr_equal_unaligned
Add a generic routine to test if possibly unaligned
to u16 Ethernet addresses are equal.
If CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is set,
this uses the slightly faster generic routine
ether_addr_equal, otherwise this uses memcmp.
Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
> Fix this driver instead of polluting out common interfaces
> unnecessarily.
>
Amitkumar -- is this fixable in mwifiex driver and firmware? It looks
like your firmware expects u8 specific_bssid[ETH_ALEN] at byte offset
1, per struct mwifiex_scan_cmd_config definition.
I'll let Marvell take it from here.
> Thanks.
^ permalink raw reply
* Re: [PATCH] Modify is_zero_ether_addr() to handle byte-aligned addresses
From: David Miller @ 2016-08-13 3:26 UTC (permalink / raw)
To: pgynther; +Cc: linux-wireless, kvalo, joe, akarwar
In-Reply-To: <1471047330-8153-1-git-send-email-pgynther@google.com>
From: Petri Gynther <pgynther@google.com>
Date: Fri, 12 Aug 2016 17:15:30 -0700
> Root cause:
> mwifiex driver calls is_zero_ether_addr() against byte-aligned address:
MAC addresses really must be 16-bit aligned to be used with any of the
ethernet address manipulation and test interfaces.
Therefore this driver should do whatever it takes to avoid passing
a byte-aligned MAC address anywhere.
We _SHOULD NOT_ add support for byte aligned addresses to these
interfaces, nor add routines which by-name can handle them.
Fix this driver instead of polluting out common interfaces
unnecessarily.
Thanks.
^ permalink raw reply
* [PATCH 2/2] mwifiex: fix unaligned read in mwifiex_config_scan()
From: Petri Gynther @ 2016-08-13 3:00 UTC (permalink / raw)
To: linux-wireless; +Cc: kvalo, davem, joe, akarwar, Petri Gynther
In-Reply-To: <1471057200-58166-1-git-send-email-pgynther@google.com>
$ iwconfig mlan0 essid MySSID
[ 36.930000] Path: /sbin/iwconfig
[ 36.930000] CPU: 0 PID: 203 Comm: iwconfig Not tainted 4.7.0 #2
[ 36.940000] task: 866f83a0 ti: 866a6000 task.ti: 866a6000
[ 36.940000]
[ECR ]: 0x00230400 => Misaligned r/w from 0x8677f403
[ 36.960000] [EFA ]: 0x8677f403
[ 36.960000] [BLINK ]: mwifiex_scan_networks+0x17a/0x198c [mwifiex]
[ 36.960000] [ERET ]: mwifiex_scan_networks+0x18a/0x198c [mwifiex]
[ 36.980000] [STAT32]: 0x00000206 : K E2 E1
[ 36.980000] BTA: 0x700736e2 SP: 0x866a7d0c FP: 0x5faddc84
[ 37.000000] LPS: 0x806a37ec LPE: 0x806a37fa LPC: 0x00000000
[ 37.000000] r00: 0x8677f401 r01: 0x8668aa08 r02: 0x00000001
r03: 0x00000000 r04: 0x8668b600 r05: 0x8677f406
r06: 0x8702b600 r07: 0x00000000 r08: 0x8702b600
r09: 0x00000000 r10: 0x870b3b00 r11: 0x00000000
r12: 0x00000000
[ 37.040000]
[ 37.040000] Stack Trace:
[ 37.040000] mwifiex_scan_networks+0x18a/0x198c [mwifiex]
Root cause:
mwifiex driver calls is_zero_ether_addr() against byte-aligned address:
drivers/net/wireless/marvell/mwifiex/fw.h:
struct mwifiex_scan_cmd_config {
/*
* BSS mode to be sent in the firmware command
*/
u8 bss_mode;
/* Specific BSSID used to filter scan results in the firmware */
u8 specific_bssid[ETH_ALEN];
...
} __packed;
drivers/net/wireless/marvell/mwifiex/scan.c:
mwifiex_config_scan(..., struct mwifiex_scan_cmd_config *scan_cfg_out, ...)
...
if (adapter->ext_scan &&
!is_zero_ether_addr(scan_cfg_out->specific_bssid)) {
...
}
Since firmware-related struct mwifiex_scan_cmd_config cannot be changed,
we need to use the new function is_zero_ether_addr_unaligned() here.
This is v2 of the original patch:
[PATCH] Modify is_zero_ether_addr() to handle byte-aligned addresses
Per Joe's suggestion -- instead of modifying is_zero_ether_addr() --
add is_zero_ether_addr_unaligned() and use it where needed.
Cc: Kalle Valo <kvalo@codeaurora.org>
Cc: David S. Miller <davem@davemloft.net>
Cc: Joe Perches <joe@perches.com>
Cc: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Petri Gynther <pgynther@google.com>
---
drivers/net/wireless/marvell/mwifiex/scan.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/marvell/mwifiex/scan.c b/drivers/net/wireless/marvell/mwifiex/scan.c
index bc5e52c..d648c88 100644
--- a/drivers/net/wireless/marvell/mwifiex/scan.c
+++ b/drivers/net/wireless/marvell/mwifiex/scan.c
@@ -883,7 +883,8 @@ mwifiex_config_scan(struct mwifiex_private *priv,
sizeof(scan_cfg_out->specific_bssid));
if (adapter->ext_scan &&
- !is_zero_ether_addr(scan_cfg_out->specific_bssid)) {
+ !is_zero_ether_addr_unaligned(
+ scan_cfg_out->specific_bssid)) {
bssid_tlv =
(struct mwifiex_ie_types_bssid_list *)tlv_pos;
bssid_tlv->header.type = cpu_to_le16(TLV_TYPE_BSSID);
--
2.8.0.rc3.226.g39d4020
^ permalink raw reply related
* [PATCH 1/2] etherdevice: add is_zero_ether_addr_unaligned()
From: Petri Gynther @ 2016-08-13 2:59 UTC (permalink / raw)
To: linux-wireless; +Cc: kvalo, davem, joe, akarwar, Petri Gynther
Add a generic routine to test if possibly unaligned to u16
Ethernet address is a zero address.
If CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is set, use
slightly faster generic routine is_zero_ether_addr(),
otherwise use byte accesses.
This is v2 of the original patch:
[PATCH] Modify is_zero_ether_addr() to handle byte-aligned addresses
Per Joe's suggestion -- instead of modifying is_zero_ether_addr() --
add is_zero_ether_addr_unaligned() and use it where needed.
Cc: Kalle Valo <kvalo@codeaurora.org>
Cc: David S. Miller <davem@davemloft.net>
Cc: Joe Perches <joe@perches.com>
Cc: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Petri Gynther <pgynther@google.com>
---
include/linux/etherdevice.h | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h
index 37ff4a6..f609691 100644
--- a/include/linux/etherdevice.h
+++ b/include/linux/etherdevice.h
@@ -105,6 +105,21 @@ static inline bool is_zero_ether_addr(const u8 *addr)
}
/**
+ * is_zero_ether_addr_unaligned - Determine if given Ethernet address is all zeros.
+ * @addr: Pointer to a six-byte array containing the Ethernet address
+ *
+ * Return true if the address is all zeroes.
+ */
+static inline bool is_zero_ether_addr_unaligned(const u8 *addr)
+{
+#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
+ return is_zero_ether_addr(addr);
+#else
+ return (addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5]) == 0;
+#endif
+}
+
+/**
* is_multicast_ether_addr - Determine if the Ethernet address is a multicast.
* @addr: Pointer to a six-byte array containing the Ethernet address
*
--
2.8.0.rc3.226.g39d4020
^ permalink raw reply related
* Re: [PATCH] Modify is_zero_ether_addr() to handle byte-aligned addresses
From: kbuild test robot @ 2016-08-13 2:26 UTC (permalink / raw)
To: Petri Gynther
Cc: kbuild-all, linux-wireless, kvalo, davem, joe, akarwar,
Petri Gynther
In-Reply-To: <1471047330-8153-1-git-send-email-pgynther@google.com>
[-- Attachment #1: Type: text/plain, Size: 1628 bytes --]
Hi Petri,
[auto build test ERROR on net-next/master]
[also build test ERROR on v4.8-rc1 next-20160812]
[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/Petri-Gynther/Modify-is_zero_ether_addr-to-handle-byte-aligned-addresses/20160813-081835
config: powerpc-defconfig (attached as .config)
compiler: powerpc64-linux-gnu-gcc (Debian 5.4.0-6) 5.4.0 20160609
reproduce:
wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=powerpc
All errors (new ones prefixed by >>):
In file included from arch/powerpc/kernel/prom_parse.c:6:0:
include/linux/etherdevice.h: In function 'is_zero_ether_addr':
>> include/linux/etherdevice.h:96:6: error: cast from pointer to integer of different size [-Werror=pointer-to-int-cast]
if ((u32)addr & 0x1)
^
cc1: all warnings being treated as errors
vim +96 include/linux/etherdevice.h
90 * @addr: Pointer to a six-byte array containing the Ethernet address
91 *
92 * Return true if the address is all zeroes.
93 */
94 static inline bool is_zero_ether_addr(const u8 *addr)
95 {
> 96 if ((u32)addr & 0x1)
97 return (addr[0] | addr[1] | addr[2] | addr[3] | addr[4] |
98 addr[5]) == 0;
99
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 22404 bytes --]
^ permalink raw reply
* Re: [PATCH] Modify is_zero_ether_addr() to handle byte-aligned addresses
From: kbuild test robot @ 2016-08-13 2:08 UTC (permalink / raw)
To: Petri Gynther
Cc: kbuild-all, linux-wireless, kvalo, davem, joe, akarwar,
Petri Gynther
In-Reply-To: <1471047330-8153-1-git-send-email-pgynther@google.com>
[-- Attachment #1: Type: text/plain, Size: 3383 bytes --]
Hi Petri,
[auto build test WARNING on net-next/master]
[also build test WARNING on v4.8-rc1 next-20160812]
[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/Petri-Gynther/Modify-is_zero_ether_addr-to-handle-byte-aligned-addresses/20160813-081835
config: x86_64-randconfig-n0-08130925 (attached as .config)
compiler: gcc-6 (Debian 6.1.1-9) 6.1.1 20160705
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64
All warnings (new ones prefixed by >>):
In file included from include/asm-generic/bug.h:4:0,
from arch/x86/include/asm/bug.h:35,
from include/linux/bug.h:4,
from include/linux/mmdebug.h:4,
from include/linux/gfp.h:4,
from net/llc/llc_if.c:14:
include/linux/etherdevice.h: In function 'is_zero_ether_addr':
include/linux/etherdevice.h:96:6: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
if ((u32)addr & 0x1)
^
include/linux/compiler.h:149:30: note: in definition of macro '__trace_if'
if (__builtin_constant_p(!!(cond)) ? !!(cond) : \
^~~~
>> include/linux/etherdevice.h:96:2: note: in expansion of macro 'if'
if ((u32)addr & 0x1)
^~
include/linux/etherdevice.h:96:6: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
if ((u32)addr & 0x1)
^
include/linux/compiler.h:149:42: note: in definition of macro '__trace_if'
if (__builtin_constant_p(!!(cond)) ? !!(cond) : \
^~~~
>> include/linux/etherdevice.h:96:2: note: in expansion of macro 'if'
if ((u32)addr & 0x1)
^~
include/linux/etherdevice.h:96:6: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
if ((u32)addr & 0x1)
^
include/linux/compiler.h:160:16: note: in definition of macro '__trace_if'
______r = !!(cond); \
^~~~
>> include/linux/etherdevice.h:96:2: note: in expansion of macro 'if'
if ((u32)addr & 0x1)
^~
vim +/if +96 include/linux/etherdevice.h
80 #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
81 return (((*(const u32 *)addr) ^ (*(const u32 *)b)) |
82 (__force int)((a[2] ^ b[2]) & m)) == 0;
83 #else
84 return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | ((a[2] ^ b[2]) & m)) == 0;
85 #endif
86 }
87
88 /**
89 * is_zero_ether_addr - Determine if give Ethernet address is all zeros.
90 * @addr: Pointer to a six-byte array containing the Ethernet address
91 *
92 * Return true if the address is all zeroes.
93 */
94 static inline bool is_zero_ether_addr(const u8 *addr)
95 {
> 96 if ((u32)addr & 0x1)
97 return (addr[0] | addr[1] | addr[2] | addr[3] | addr[4] |
98 addr[5]) == 0;
99
100 #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
101 return ((*(const u32 *)addr) | (*(const u16 *)(addr + 4))) == 0;
102 #else
103 return (*(const u16 *)(addr + 0) |
104 *(const u16 *)(addr + 2) |
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 25700 bytes --]
^ permalink raw reply
* Re: [PATCH] Modify is_zero_ether_addr() to handle byte-aligned addresses
From: Petri Gynther @ 2016-08-13 1:41 UTC (permalink / raw)
To: Joe Perches; +Cc: linux-wireless, kvalo, David Miller, akarwar
In-Reply-To: <1471048085.18251.25.camel@perches.com>
Hi Joe,
On Fri, Aug 12, 2016 at 5:28 PM, Joe Perches <joe@perches.com> wrote:
> On Fri, 2016-08-12 at 17:15 -0700, Petri Gynther wrote:
>> $ iwconfig mlan0 essid MySSID
>> [ 36.930000] Path: /sbin/iwconfig
>> [ 36.930000] CPU: 0 PID: 203 Comm: iwconfig Not tainted 4.7.0 #2
>> [ 36.940000] task: 866f83a0 ti: 866a6000 task.ti: 866a6000
>> [ 36.940000]
>> [ECR ]: 0x00230400 => Misaligned r/w from 0x8677f403
>> [ 36.960000] [EFA ]: 0x8677f403
>> [ 36.960000] [BLINK ]: mwifiex_scan_networks+0x17a/0x198c [mwifiex]
>> [ 36.960000] [ERET ]: mwifiex_scan_networks+0x18a/0x198c [mwifiex]
>> [ 36.980000] [STAT32]: 0x00000206 : K E2 E1
>> [ 36.980000] BTA: 0x700736e2 SP: 0x866a7d0c FP: 0x5faddc84
>> [ 37.000000] LPS: 0x806a37ec LPE: 0x806a37fa LPC: 0x00000000
>> [ 37.000000] r00: 0x8677f401 r01: 0x8668aa08 r02: 0x00000001
>> r03: 0x00000000 r04: 0x8668b600 r05: 0x8677f406
>> r06: 0x8702b600 r07: 0x00000000 r08: 0x8702b600
>> r09: 0x00000000 r10: 0x870b3b00 r11: 0x00000000
>> r12: 0x00000000
>> [ 37.040000]
>> [ 37.040000] Stack Trace:
>> [ 37.040000] mwifiex_scan_networks+0x18a/0x198c [mwifiex]
>>
>> Root cause:
>> mwifiex driver calls is_zero_ether_addr() against byte-aligned address:
>>
>> drivers/net/wireless/marvell/mwifiex/fw.h:
>> struct mwifiex_scan_cmd_config {
>> /*
>> * BSS mode to be sent in the firmware command
>> */
>> u8 bss_mode;
>>
>> /* Specific BSSID used to filter scan results in the firmware */
>> u8 specific_bssid[ETH_ALEN];
>>
>> ...
>> } __packed;
>>
>> drivers/net/wireless/marvell/mwifiex/scan.c:
>> mwifiex_config_scan(..., struct mwifiex_scan_cmd_config *scan_cfg_out, ...)
>> ...
>> if (adapter->ext_scan &&
>> !is_zero_ether_addr(scan_cfg_out->specific_bssid)) {
>> ...
>> }
>>
>> Since firmware-related struct mwifiex_scan_cmd_config cannot be changed,
>> modify is_zero_ether_addr() to handle byte-aligned addresses.
>
> Or add is_zero_ether_addr_unaligned and use it here.
>
>> Cc: Kalle Valo <kvalo@codeaurora.org>
>> Cc: David S. Miller <davem@davemloft.net>
>> Cc: Joe Perches <joe@perches.com>
>> Cc: Amitkumar Karwar <akarwar@marvell.com>
>> Signed-off-by: Petri Gynther <pgynther@google.com>
>> ---
>> include/linux/etherdevice.h | 6 ++++--
>> 1 file changed, 4 insertions(+), 2 deletions(-)
>>
>> diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h
>> index 37ff4a6..0cfd243 100644
>> --- a/include/linux/etherdevice.h
>> +++ b/include/linux/etherdevice.h
>> @@ -90,11 +90,13 @@ static inline bool is_link_local_ether_addr(const u8 *addr)
>> * @addr: Pointer to a six-byte array containing the Ethernet address
>> *
>> * Return true if the address is all zeroes.
>> - *
>> - * Please note: addr must be aligned to u16.
>> */
>> static inline bool is_zero_ether_addr(const u8 *addr)
>> {
>> + if ((u32)addr & 0x1)
>> + return (addr[0] | addr[1] | addr[2] | addr[3] | addr[4] |
>> + addr[5]) == 0;
>> +
>
> So why skip the CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
> optimization below?
>
>> #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
>> return ((*(const u32 *)addr) | (*(const u16 *)(addr + 4))) == 0;
>> #else
>
> How about adding:
>
> static inline bool is_zero_ether_addr_unaligned(const u8 *addr)
> {
> #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
> return is_zero_ether_addr(addr);
> #else
> return addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5];
> #endif
> }
>
I like your idea. I'll add is_zero_ether_addr_unaligned() and use it
in mwifiex driver.
^ permalink raw reply
* Re: [PATCH] Modify is_zero_ether_addr() to handle byte-aligned addresses
From: Joe Perches @ 2016-08-13 0:28 UTC (permalink / raw)
To: Petri Gynther, linux-wireless; +Cc: kvalo, davem, akarwar
In-Reply-To: <1471047330-8153-1-git-send-email-pgynther@google.com>
On Fri, 2016-08-12 at 17:15 -0700, Petri Gynther wrote:
> $ iwconfig mlan0 essid MySSID
> [ 36.930000] Path: /sbin/iwconfig
> [ 36.930000] CPU: 0 PID: 203 Comm: iwconfig Not tainted 4.7.0 #2
> [ 36.940000] task: 866f83a0 ti: 866a6000 task.ti: 866a6000
> [ 36.940000]
> [ECR ]: 0x00230400 => Misaligned r/w from 0x8677f403
> [ 36.960000] [EFA ]: 0x8677f403
> [ 36.960000] [BLINK ]: mwifiex_scan_networks+0x17a/0x198c [mwifiex]
> [ 36.960000] [ERET ]: mwifiex_scan_networks+0x18a/0x198c [mwifiex]
> [ 36.980000] [STAT32]: 0x00000206 : K E2 E1
> [ 36.980000] BTA: 0x700736e2 SP: 0x866a7d0c FP: 0x5faddc84
> [ 37.000000] LPS: 0x806a37ec LPE: 0x806a37fa LPC: 0x00000000
> [ 37.000000] r00: 0x8677f401 r01: 0x8668aa08 r02: 0x00000001
> r03: 0x00000000 r04: 0x8668b600 r05: 0x8677f406
> r06: 0x8702b600 r07: 0x00000000 r08: 0x8702b600
> r09: 0x00000000 r10: 0x870b3b00 r11: 0x00000000
> r12: 0x00000000
> [ 37.040000]
> [ 37.040000] Stack Trace:
> [ 37.040000] mwifiex_scan_networks+0x18a/0x198c [mwifiex]
>
> Root cause:
> mwifiex driver calls is_zero_ether_addr() against byte-aligned address:
>
> drivers/net/wireless/marvell/mwifiex/fw.h:
> struct mwifiex_scan_cmd_config {
> /*
> * BSS mode to be sent in the firmware command
> */
> u8 bss_mode;
>
> /* Specific BSSID used to filter scan results in the firmware */
> u8 specific_bssid[ETH_ALEN];
>
> ...
> } __packed;
>
> drivers/net/wireless/marvell/mwifiex/scan.c:
> mwifiex_config_scan(..., struct mwifiex_scan_cmd_config *scan_cfg_out, ...)
> ...
> if (adapter->ext_scan &&
> !is_zero_ether_addr(scan_cfg_out->specific_bssid)) {
> ...
> }
>
> Since firmware-related struct mwifiex_scan_cmd_config cannot be changed,
> modify is_zero_ether_addr() to handle byte-aligned addresses.
Or add is_zero_ether_addr_unaligned and use it here.
> Cc: Kalle Valo <kvalo@codeaurora.org>
> Cc: David S. Miller <davem@davemloft.net>
> Cc: Joe Perches <joe@perches.com>
> Cc: Amitkumar Karwar <akarwar@marvell.com>
> Signed-off-by: Petri Gynther <pgynther@google.com>
> ---
> include/linux/etherdevice.h | 6 ++++--
> 1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h
> index 37ff4a6..0cfd243 100644
> --- a/include/linux/etherdevice.h
> +++ b/include/linux/etherdevice.h
> @@ -90,11 +90,13 @@ static inline bool is_link_local_ether_addr(const u8 *addr)
> * @addr: Pointer to a six-byte array containing the Ethernet address
> *
> * Return true if the address is all zeroes.
> - *
> - * Please note: addr must be aligned to u16.
> */
> static inline bool is_zero_ether_addr(const u8 *addr)
> {
> + if ((u32)addr & 0x1)
> + return (addr[0] | addr[1] | addr[2] | addr[3] | addr[4] |
> + addr[5]) == 0;
> +
So why skip the CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
optimization below?
> #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
> return ((*(const u32 *)addr) | (*(const u16 *)(addr + 4))) == 0;
> #else
How about adding:
static inline bool is_zero_ether_addr_unaligned(const u8 *addr)
{
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
return is_zero_ether_addr(addr);
#else
return addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5];
#endif
}
^ permalink raw reply
* [PATCH v2 2/2] wcn36xx: Implement firmware assisted scan
From: Bjorn Andersson @ 2016-08-13 0:17 UTC (permalink / raw)
To: Eugene Krasnikov, Kalle Valo
Cc: wcn36xx, linux-wireless, netdev, linux-kernel, linux-arm-msm
In-Reply-To: <1471047465-18211-1-git-send-email-bjorn.andersson@linaro.org>
Using the software based channel scan mechanism from mac80211 keeps us
offline for 10-15 second, we should instead issue a start_scan/end_scan
on each channel reducing this time.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
---
It's been a while since I posted this as an RFC, I have not received any
comments on the code but we've been running it in the Linaro kernel with good
results and possitive user feedback for quite some time.
So I'm hoping we can merge it, as it solves the #1 complaint we had with users;
where NetworkManager (or something similar) would stall and time out their
connections by scanning for networks every now and then.
drivers/net/wireless/ath/wcn36xx/main.c | 62 ++++++++++++++++++++++++------
drivers/net/wireless/ath/wcn36xx/smd.c | 8 ++--
drivers/net/wireless/ath/wcn36xx/smd.h | 4 +-
drivers/net/wireless/ath/wcn36xx/txrx.c | 19 ++++++---
drivers/net/wireless/ath/wcn36xx/wcn36xx.h | 9 +++++
5 files changed, 79 insertions(+), 23 deletions(-)
diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c
index 3c2522b07c90..23650b24c5bf 100644
--- a/drivers/net/wireless/ath/wcn36xx/main.c
+++ b/drivers/net/wireless/ath/wcn36xx/main.c
@@ -568,23 +568,57 @@ out:
return ret;
}
-static void wcn36xx_sw_scan_start(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- const u8 *mac_addr)
+static void wcn36xx_hw_scan_worker(struct work_struct *work)
{
- struct wcn36xx *wcn = hw->priv;
+ struct wcn36xx *wcn = container_of(work, struct wcn36xx, scan_work);
+ struct cfg80211_scan_request *req = wcn->scan_req;
+ u8 channels[WCN36XX_HAL_PNO_MAX_NETW_CHANNELS_EX];
+ int i;
+
+ wcn36xx_dbg(WCN36XX_DBG_MAC, "mac80211 scan %d channels worker\n", req->n_channels);
+
+ for (i = 0; i < req->n_channels; i++)
+ channels[i] = req->channels[i]->hw_value;
+
+ wcn36xx_smd_update_scan_params(wcn, channels, req->n_channels);
wcn36xx_smd_init_scan(wcn, HAL_SYS_MODE_SCAN);
- wcn36xx_smd_start_scan(wcn);
+ for (i = 0; i < req->n_channels; i++) {
+ wcn->scan_freq = req->channels[i]->center_freq;
+ wcn->scan_band = req->channels[i]->band;
+
+ wcn36xx_smd_start_scan(wcn, req->channels[i]->hw_value);
+ msleep(30);
+ wcn36xx_smd_end_scan(wcn, req->channels[i]->hw_value);
+
+ wcn->scan_freq = 0;
+ }
+ wcn36xx_smd_finish_scan(wcn, HAL_SYS_MODE_SCAN);
+
+ ieee80211_scan_completed(wcn->hw, false);
+
+ mutex_lock(&wcn->scan_lock);
+ wcn->scan_req = NULL;
+ mutex_unlock(&wcn->scan_lock);
}
-static void wcn36xx_sw_scan_complete(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif)
+static int wcn36xx_hw_scan(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_scan_request *hw_req)
{
struct wcn36xx *wcn = hw->priv;
- wcn36xx_smd_end_scan(wcn);
- wcn36xx_smd_finish_scan(wcn, HAL_SYS_MODE_SCAN);
+ mutex_lock(&wcn->scan_lock);
+ if (wcn->scan_req) {
+ mutex_unlock(&wcn->scan_lock);
+ return -EBUSY;
+ }
+ wcn->scan_req = &hw_req->req;
+ mutex_unlock(&wcn->scan_lock);
+
+ schedule_work(&wcn->scan_work);
+
+ return 0;
}
static void wcn36xx_update_allowed_rates(struct ieee80211_sta *sta,
@@ -997,8 +1031,7 @@ static const struct ieee80211_ops wcn36xx_ops = {
.configure_filter = wcn36xx_configure_filter,
.tx = wcn36xx_tx,
.set_key = wcn36xx_set_key,
- .sw_scan_start = wcn36xx_sw_scan_start,
- .sw_scan_complete = wcn36xx_sw_scan_complete,
+ .hw_scan = wcn36xx_hw_scan,
.bss_info_changed = wcn36xx_bss_info_changed,
.set_rts_threshold = wcn36xx_set_rts_threshold,
.sta_add = wcn36xx_sta_add,
@@ -1023,6 +1056,7 @@ static int wcn36xx_init_ieee80211(struct wcn36xx *wcn)
ieee80211_hw_set(wcn->hw, SUPPORTS_PS);
ieee80211_hw_set(wcn->hw, SIGNAL_DBM);
ieee80211_hw_set(wcn->hw, HAS_RATE_CONTROL);
+ ieee80211_hw_set(wcn->hw, SINGLE_SCAN_ON_ALL_BANDS);
wcn->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_AP) |
@@ -1032,6 +1066,9 @@ static int wcn36xx_init_ieee80211(struct wcn36xx *wcn)
wcn->hw->wiphy->bands[NL80211_BAND_2GHZ] = &wcn_band_2ghz;
wcn->hw->wiphy->bands[NL80211_BAND_5GHZ] = &wcn_band_5ghz;
+ wcn->hw->wiphy->max_scan_ssids = WCN36XX_MAX_SCAN_SSIDS;
+ wcn->hw->wiphy->max_scan_ie_len = WCN36XX_MAX_SCAN_IE_LEN;
+
wcn->hw->wiphy->cipher_suites = cipher_suites;
wcn->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
@@ -1152,6 +1189,9 @@ static int wcn36xx_probe(struct platform_device *pdev)
wcn->hw = hw;
wcn->dev = &pdev->dev;
mutex_init(&wcn->hal_mutex);
+ mutex_init(&wcn->scan_lock);
+
+ INIT_WORK(&wcn->scan_work, wcn36xx_hw_scan_worker);
wcn->smd_channel = qcom_wcnss_open_channel(wcnss, "WLAN_CTRL", wcn36xx_smd_rsp_process);
if (IS_ERR(wcn->smd_channel)) {
diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c b/drivers/net/wireless/ath/wcn36xx/smd.c
index d9ff2e2a8118..83d067876969 100644
--- a/drivers/net/wireless/ath/wcn36xx/smd.c
+++ b/drivers/net/wireless/ath/wcn36xx/smd.c
@@ -522,7 +522,7 @@ out:
return ret;
}
-int wcn36xx_smd_start_scan(struct wcn36xx *wcn)
+int wcn36xx_smd_start_scan(struct wcn36xx *wcn, u8 scan_channel)
{
struct wcn36xx_hal_start_scan_req_msg msg_body;
int ret = 0;
@@ -530,7 +530,7 @@ int wcn36xx_smd_start_scan(struct wcn36xx *wcn)
mutex_lock(&wcn->hal_mutex);
INIT_HAL_MSG(msg_body, WCN36XX_HAL_START_SCAN_REQ);
- msg_body.scan_channel = WCN36XX_HW_CHANNEL(wcn);
+ msg_body.scan_channel = scan_channel;
PREPARE_HAL_BUF(wcn->hal_buf, msg_body);
@@ -552,7 +552,7 @@ out:
return ret;
}
-int wcn36xx_smd_end_scan(struct wcn36xx *wcn)
+int wcn36xx_smd_end_scan(struct wcn36xx *wcn, u8 scan_channel)
{
struct wcn36xx_hal_end_scan_req_msg msg_body;
int ret = 0;
@@ -560,7 +560,7 @@ int wcn36xx_smd_end_scan(struct wcn36xx *wcn)
mutex_lock(&wcn->hal_mutex);
INIT_HAL_MSG(msg_body, WCN36XX_HAL_END_SCAN_REQ);
- msg_body.scan_channel = WCN36XX_HW_CHANNEL(wcn);
+ msg_body.scan_channel = scan_channel;
PREPARE_HAL_BUF(wcn->hal_buf, msg_body);
diff --git a/drivers/net/wireless/ath/wcn36xx/smd.h b/drivers/net/wireless/ath/wcn36xx/smd.h
index 40d829563c2b..8892ccd67b14 100644
--- a/drivers/net/wireless/ath/wcn36xx/smd.h
+++ b/drivers/net/wireless/ath/wcn36xx/smd.h
@@ -60,8 +60,8 @@ int wcn36xx_smd_load_nv(struct wcn36xx *wcn);
int wcn36xx_smd_start(struct wcn36xx *wcn);
int wcn36xx_smd_stop(struct wcn36xx *wcn);
int wcn36xx_smd_init_scan(struct wcn36xx *wcn, enum wcn36xx_hal_sys_mode mode);
-int wcn36xx_smd_start_scan(struct wcn36xx *wcn);
-int wcn36xx_smd_end_scan(struct wcn36xx *wcn);
+int wcn36xx_smd_start_scan(struct wcn36xx *wcn, u8 scan_channel);
+int wcn36xx_smd_end_scan(struct wcn36xx *wcn, u8 scan_channel);
int wcn36xx_smd_finish_scan(struct wcn36xx *wcn,
enum wcn36xx_hal_sys_mode mode);
int wcn36xx_smd_update_scan_params(struct wcn36xx *wcn, u8 *channels, size_t channel_count);
diff --git a/drivers/net/wireless/ath/wcn36xx/txrx.c b/drivers/net/wireless/ath/wcn36xx/txrx.c
index 1f34c2e912d7..8c387a0a3c09 100644
--- a/drivers/net/wireless/ath/wcn36xx/txrx.c
+++ b/drivers/net/wireless/ath/wcn36xx/txrx.c
@@ -45,9 +45,20 @@ int wcn36xx_rx_skb(struct wcn36xx *wcn, struct sk_buff *skb)
skb_put(skb, bd->pdu.mpdu_header_off + bd->pdu.mpdu_len);
skb_pull(skb, bd->pdu.mpdu_header_off);
+ hdr = (struct ieee80211_hdr *) skb->data;
+ fc = __le16_to_cpu(hdr->frame_control);
+ sn = IEEE80211_SEQ_TO_SN(__le16_to_cpu(hdr->seq_ctrl));
+
+ /* When scanning associate beacons to this */
+ if (ieee80211_is_beacon(hdr->frame_control) && wcn->scan_freq) {
+ status.freq = wcn->scan_freq;
+ status.band = wcn->scan_band;
+ } else {
+ status.freq = WCN36XX_CENTER_FREQ(wcn);
+ status.band = WCN36XX_BAND(wcn);
+ }
+
status.mactime = 10;
- status.freq = WCN36XX_CENTER_FREQ(wcn);
- status.band = WCN36XX_BAND(wcn);
status.signal = -get_rssi0(bd);
status.antenna = 1;
status.rate_idx = 1;
@@ -61,10 +72,6 @@ int wcn36xx_rx_skb(struct wcn36xx *wcn, struct sk_buff *skb)
memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
- hdr = (struct ieee80211_hdr *) skb->data;
- fc = __le16_to_cpu(hdr->frame_control);
- sn = IEEE80211_SEQ_TO_SN(__le16_to_cpu(hdr->seq_ctrl));
-
if (ieee80211_is_beacon(hdr->frame_control)) {
wcn36xx_dbg(WCN36XX_DBG_BEACON, "beacon skb %p len %d fc %04x sn %d\n",
skb, skb->len, fc, sn);
diff --git a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
index 68cc06cf9bc0..35a6590c3ee5 100644
--- a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
+++ b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
@@ -35,6 +35,9 @@
/* How many frames until we start a-mpdu TX session */
#define WCN36XX_AMPDU_START_THRESH 20
+#define WCN36XX_MAX_SCAN_SSIDS 9
+#define WCN36XX_MAX_SCAN_IE_LEN 500
+
extern unsigned int wcn36xx_dbg_mask;
enum wcn36xx_debug_mask {
@@ -212,6 +215,12 @@ struct wcn36xx {
spinlock_t hal_ind_lock;
struct list_head hal_ind_queue;
+ struct work_struct scan_work;
+ struct cfg80211_scan_request *scan_req;
+ int scan_freq;
+ int scan_band;
+ struct mutex scan_lock;
+
/* DXE channels */
struct wcn36xx_dxe_ch dxe_tx_l_ch; /* TX low */
struct wcn36xx_dxe_ch dxe_tx_h_ch; /* TX high */
--
2.5.0
^ permalink raw reply related
* [PATCH v2 1/2] wcn36xx: Transition driver to SMD client
From: Bjorn Andersson @ 2016-08-13 0:17 UTC (permalink / raw)
To: Eugene Krasnikov, Kalle Valo
Cc: wcn36xx, linux-wireless, netdev, linux-kernel, linux-arm-msm
The wcn36xx wifi driver follows the life cycle of the WLAN_CTRL SMD
channel, as such it should be a SMD client. This patch makes this
transition, now that we have the necessary frameworks available.
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
---
Resending this as the dependencies and the devicetree binding was merged in
v4.8
drivers/net/wireless/ath/wcn36xx/Kconfig | 2 +-
drivers/net/wireless/ath/wcn36xx/dxe.c | 16 +++---
drivers/net/wireless/ath/wcn36xx/main.c | 79 ++++++++++++++++++++----------
drivers/net/wireless/ath/wcn36xx/smd.c | 29 +++++------
drivers/net/wireless/ath/wcn36xx/smd.h | 5 ++
drivers/net/wireless/ath/wcn36xx/wcn36xx.h | 21 +++-----
6 files changed, 86 insertions(+), 66 deletions(-)
diff --git a/drivers/net/wireless/ath/wcn36xx/Kconfig b/drivers/net/wireless/ath/wcn36xx/Kconfig
index 591ebaea8265..394fe5b77c90 100644
--- a/drivers/net/wireless/ath/wcn36xx/Kconfig
+++ b/drivers/net/wireless/ath/wcn36xx/Kconfig
@@ -1,6 +1,6 @@
config WCN36XX
tristate "Qualcomm Atheros WCN3660/3680 support"
- depends on MAC80211 && HAS_DMA
+ depends on MAC80211 && HAS_DMA && QCOM_SMD
---help---
This module adds support for wireless adapters based on
Qualcomm Atheros WCN3660 and WCN3680 mobile chipsets.
diff --git a/drivers/net/wireless/ath/wcn36xx/dxe.c b/drivers/net/wireless/ath/wcn36xx/dxe.c
index 231fd022f0f5..87dfdaf9044c 100644
--- a/drivers/net/wireless/ath/wcn36xx/dxe.c
+++ b/drivers/net/wireless/ath/wcn36xx/dxe.c
@@ -23,6 +23,7 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/interrupt.h>
+#include <linux/soc/qcom/smem_state.h>
#include "wcn36xx.h"
#include "txrx.h"
@@ -151,9 +152,12 @@ int wcn36xx_dxe_alloc_ctl_blks(struct wcn36xx *wcn)
goto out_err;
/* Initialize SMSM state Clear TX Enable RING EMPTY STATE */
- ret = wcn->ctrl_ops->smsm_change_state(
- WCN36XX_SMSM_WLAN_TX_ENABLE,
- WCN36XX_SMSM_WLAN_TX_RINGS_EMPTY);
+ ret = qcom_smem_state_update_bits(wcn->tx_enable_state,
+ WCN36XX_SMSM_WLAN_TX_ENABLE |
+ WCN36XX_SMSM_WLAN_TX_RINGS_EMPTY,
+ WCN36XX_SMSM_WLAN_TX_RINGS_EMPTY);
+ if (ret)
+ goto out_err;
return 0;
@@ -678,9 +682,9 @@ int wcn36xx_dxe_tx_frame(struct wcn36xx *wcn,
* notify chip about new frame through SMSM bus.
*/
if (is_low && vif_priv->pw_state == WCN36XX_BMPS) {
- wcn->ctrl_ops->smsm_change_state(
- 0,
- WCN36XX_SMSM_WLAN_TX_ENABLE);
+ qcom_smem_state_update_bits(wcn->tx_rings_empty_state,
+ WCN36XX_SMSM_WLAN_TX_ENABLE,
+ WCN36XX_SMSM_WLAN_TX_ENABLE);
} else {
/* indicate End Of Packet and generate interrupt on descriptor
* done.
diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c
index e1d59da2ad20..3c2522b07c90 100644
--- a/drivers/net/wireless/ath/wcn36xx/main.c
+++ b/drivers/net/wireless/ath/wcn36xx/main.c
@@ -21,6 +21,10 @@
#include <linux/platform_device.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
+#include <linux/of_irq.h>
+#include <linux/soc/qcom/smd.h>
+#include <linux/soc/qcom/smem_state.h>
+#include <linux/soc/qcom/wcnss_ctrl.h>
#include "wcn36xx.h"
unsigned int wcn36xx_dbg_mask;
@@ -1058,8 +1062,7 @@ static int wcn36xx_platform_get_resources(struct wcn36xx *wcn,
int ret;
/* Set TX IRQ */
- res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
- "wcnss_wlantx_irq");
+ res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "tx");
if (!res) {
wcn36xx_err("failed to get tx_irq\n");
return -ENOENT;
@@ -1067,14 +1070,29 @@ static int wcn36xx_platform_get_resources(struct wcn36xx *wcn,
wcn->tx_irq = res->start;
/* Set RX IRQ */
- res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
- "wcnss_wlanrx_irq");
+ res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "rx");
if (!res) {
wcn36xx_err("failed to get rx_irq\n");
return -ENOENT;
}
wcn->rx_irq = res->start;
+ /* Acquire SMSM tx enable handle */
+ wcn->tx_enable_state = qcom_smem_state_get(&pdev->dev,
+ "tx-enable", &wcn->tx_enable_state_bit);
+ if (IS_ERR(wcn->tx_enable_state)) {
+ wcn36xx_err("failed to get tx-enable state\n");
+ return PTR_ERR(wcn->tx_enable_state);
+ }
+
+ /* Acquire SMSM tx rings empty handle */
+ wcn->tx_rings_empty_state = qcom_smem_state_get(&pdev->dev,
+ "tx-rings-empty", &wcn->tx_rings_empty_state_bit);
+ if (IS_ERR(wcn->tx_rings_empty_state)) {
+ wcn36xx_err("failed to get tx-rings-empty state\n");
+ return PTR_ERR(wcn->tx_rings_empty_state);
+ }
+
mmio_node = of_parse_phandle(pdev->dev.parent->of_node, "qcom,mmio", 0);
if (!mmio_node) {
wcn36xx_err("failed to acquire qcom,mmio reference\n");
@@ -1115,11 +1133,14 @@ static int wcn36xx_probe(struct platform_device *pdev)
{
struct ieee80211_hw *hw;
struct wcn36xx *wcn;
+ void *wcnss;
int ret;
- u8 addr[ETH_ALEN];
+ const u8 *addr;
wcn36xx_dbg(WCN36XX_DBG_MAC, "platform probe\n");
+ wcnss = dev_get_drvdata(pdev->dev.parent);
+
hw = ieee80211_alloc_hw(sizeof(struct wcn36xx), &wcn36xx_ops);
if (!hw) {
wcn36xx_err("failed to alloc hw\n");
@@ -1130,11 +1151,23 @@ static int wcn36xx_probe(struct platform_device *pdev)
wcn = hw->priv;
wcn->hw = hw;
wcn->dev = &pdev->dev;
- wcn->ctrl_ops = pdev->dev.platform_data;
-
mutex_init(&wcn->hal_mutex);
- if (!wcn->ctrl_ops->get_hw_mac(addr)) {
+ wcn->smd_channel = qcom_wcnss_open_channel(wcnss, "WLAN_CTRL", wcn36xx_smd_rsp_process);
+ if (IS_ERR(wcn->smd_channel)) {
+ wcn36xx_err("failed to open WLAN_CTRL channel\n");
+ ret = PTR_ERR(wcn->smd_channel);
+ goto out_wq;
+ }
+
+ qcom_smd_set_drvdata(wcn->smd_channel, hw);
+
+ addr = of_get_property(pdev->dev.of_node, "local-mac-address", &ret);
+ if (addr && ret != ETH_ALEN) {
+ wcn36xx_err("invalid local-mac-address\n");
+ ret = -EINVAL;
+ goto out_wq;
+ } else if (addr) {
wcn36xx_info("mac address: %pM\n", addr);
SET_IEEE80211_PERM_ADDR(wcn->hw, addr);
}
@@ -1158,6 +1191,7 @@ out_wq:
out_err:
return ret;
}
+
static int wcn36xx_remove(struct platform_device *pdev)
{
struct ieee80211_hw *hw = platform_get_drvdata(pdev);
@@ -1168,42 +1202,33 @@ static int wcn36xx_remove(struct platform_device *pdev)
mutex_destroy(&wcn->hal_mutex);
ieee80211_unregister_hw(hw);
+
+ qcom_smem_state_put(wcn->tx_enable_state);
+ qcom_smem_state_put(wcn->tx_rings_empty_state);
+
iounmap(wcn->dxe_base);
iounmap(wcn->ccu_base);
ieee80211_free_hw(hw);
return 0;
}
-static const struct platform_device_id wcn36xx_platform_id_table[] = {
- {
- .name = "wcn36xx",
- .driver_data = 0
- },
+
+static const struct of_device_id wcn36xx_of_match[] = {
+ { .compatible = "qcom,wcnss-wlan" },
{}
};
-MODULE_DEVICE_TABLE(platform, wcn36xx_platform_id_table);
+MODULE_DEVICE_TABLE(of, wcn36xx_of_match);
static struct platform_driver wcn36xx_driver = {
.probe = wcn36xx_probe,
.remove = wcn36xx_remove,
.driver = {
.name = "wcn36xx",
+ .of_match_table = wcn36xx_of_match,
},
- .id_table = wcn36xx_platform_id_table,
};
-static int __init wcn36xx_init(void)
-{
- platform_driver_register(&wcn36xx_driver);
- return 0;
-}
-module_init(wcn36xx_init);
-
-static void __exit wcn36xx_exit(void)
-{
- platform_driver_unregister(&wcn36xx_driver);
-}
-module_exit(wcn36xx_exit);
+module_platform_driver(wcn36xx_driver);
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("Eugene Krasnikov k.eugene.e@gmail.com");
diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c b/drivers/net/wireless/ath/wcn36xx/smd.c
index a443992320f2..d9ff2e2a8118 100644
--- a/drivers/net/wireless/ath/wcn36xx/smd.c
+++ b/drivers/net/wireless/ath/wcn36xx/smd.c
@@ -19,6 +19,7 @@
#include <linux/etherdevice.h>
#include <linux/firmware.h>
#include <linux/bitops.h>
+#include <linux/soc/qcom/smd.h>
#include "smd.h"
struct wcn36xx_cfg_val {
@@ -253,7 +254,7 @@ static int wcn36xx_smd_send_and_wait(struct wcn36xx *wcn, size_t len)
init_completion(&wcn->hal_rsp_compl);
start = jiffies;
- ret = wcn->ctrl_ops->tx(wcn->hal_buf, len);
+ ret = qcom_smd_send(wcn->smd_channel, wcn->hal_buf, len);
if (ret) {
wcn36xx_err("HAL TX failed\n");
goto out;
@@ -2180,9 +2181,12 @@ out:
return ret;
}
-static void wcn36xx_smd_rsp_process(struct wcn36xx *wcn, void *buf, size_t len)
+int wcn36xx_smd_rsp_process(struct qcom_smd_channel *channel,
+ const void *buf, size_t len)
{
struct wcn36xx_hal_msg_header *msg_header = buf;
+ struct ieee80211_hw *hw = qcom_smd_get_drvdata(channel);
+ struct wcn36xx *wcn = hw->priv;
struct wcn36xx_hal_ind_msg *msg_ind;
wcn36xx_dbg_dump(WCN36XX_DBG_SMD_DUMP, "SMD <<< ", buf, len);
@@ -2233,15 +2237,11 @@ static void wcn36xx_smd_rsp_process(struct wcn36xx *wcn, void *buf, size_t len)
case WCN36XX_HAL_OTA_TX_COMPL_IND:
case WCN36XX_HAL_MISSED_BEACON_IND:
case WCN36XX_HAL_DELETE_STA_CONTEXT_IND:
- msg_ind = kmalloc(sizeof(*msg_ind) + len, GFP_KERNEL);
+ msg_ind = kmalloc(sizeof(*msg_ind) + len, GFP_ATOMIC);
if (!msg_ind) {
- /*
- * FIXME: Do something smarter then just
- * printing an error.
- */
wcn36xx_err("Run out of memory while handling SMD_EVENT (%d)\n",
msg_header->msg_type);
- break;
+ return -ENOMEM;
}
msg_ind->msg_len = len;
@@ -2257,6 +2257,8 @@ static void wcn36xx_smd_rsp_process(struct wcn36xx *wcn, void *buf, size_t len)
wcn36xx_err("SMD_EVENT (%d) not supported\n",
msg_header->msg_type);
}
+
+ return 0;
}
static void wcn36xx_ind_smd_work(struct work_struct *work)
{
@@ -2315,22 +2317,13 @@ int wcn36xx_smd_open(struct wcn36xx *wcn)
INIT_LIST_HEAD(&wcn->hal_ind_queue);
spin_lock_init(&wcn->hal_ind_lock);
- ret = wcn->ctrl_ops->open(wcn, wcn36xx_smd_rsp_process);
- if (ret) {
- wcn36xx_err("failed to open control channel\n");
- goto free_wq;
- }
-
- return ret;
+ return 0;
-free_wq:
- destroy_workqueue(wcn->hal_ind_wq);
out:
return ret;
}
void wcn36xx_smd_close(struct wcn36xx *wcn)
{
- wcn->ctrl_ops->close();
destroy_workqueue(wcn->hal_ind_wq);
}
diff --git a/drivers/net/wireless/ath/wcn36xx/smd.h b/drivers/net/wireless/ath/wcn36xx/smd.h
index df80cbbd9d1b..40d829563c2b 100644
--- a/drivers/net/wireless/ath/wcn36xx/smd.h
+++ b/drivers/net/wireless/ath/wcn36xx/smd.h
@@ -51,6 +51,7 @@ struct wcn36xx_hal_ind_msg {
};
struct wcn36xx;
+struct qcom_smd_channel;
int wcn36xx_smd_open(struct wcn36xx *wcn);
void wcn36xx_smd_close(struct wcn36xx *wcn);
@@ -127,6 +128,10 @@ int wcn36xx_smd_del_ba(struct wcn36xx *wcn, u16 tid, u8 sta_index);
int wcn36xx_smd_trigger_ba(struct wcn36xx *wcn, u8 sta_index);
int wcn36xx_smd_update_cfg(struct wcn36xx *wcn, u32 cfg_id, u32 value);
+
+int wcn36xx_smd_rsp_process(struct qcom_smd_channel *channel,
+ const void *buf, size_t len);
+
int wcn36xx_smd_set_mc_list(struct wcn36xx *wcn,
struct ieee80211_vif *vif,
struct wcn36xx_hal_rcv_flt_mc_addr_list_type *fp);
diff --git a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
index 22242d18e1fe..68cc06cf9bc0 100644
--- a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
+++ b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
@@ -103,19 +103,6 @@ struct nv_data {
u8 table;
};
-/* Interface for platform control path
- *
- * @open: hook must be called when wcn36xx wants to open control channel.
- * @tx: sends a buffer.
- */
-struct wcn36xx_platform_ctrl_ops {
- int (*open)(void *drv_priv, void *rsp_cb);
- void (*close)(void);
- int (*tx)(char *buf, size_t len);
- int (*get_hw_mac)(u8 *addr);
- int (*smsm_change_state)(u32 clear_mask, u32 set_mask);
-};
-
/**
* struct wcn36xx_vif - holds VIF related fields
*
@@ -205,7 +192,13 @@ struct wcn36xx {
void __iomem *ccu_base;
void __iomem *dxe_base;
- struct wcn36xx_platform_ctrl_ops *ctrl_ops;
+ struct qcom_smd_channel *smd_channel;
+
+ struct qcom_smem_state *tx_enable_state;
+ unsigned tx_enable_state_bit;
+ struct qcom_smem_state *tx_rings_empty_state;
+ unsigned tx_rings_empty_state_bit;
+
/*
* smd_buf must be protected with smd_mutex to garantee
* that all messages are sent one after another
--
2.5.0
^ permalink raw reply related
* [PATCH] Modify is_zero_ether_addr() to handle byte-aligned addresses
From: Petri Gynther @ 2016-08-13 0:15 UTC (permalink / raw)
To: linux-wireless; +Cc: kvalo, davem, joe, akarwar, Petri Gynther
$ iwconfig mlan0 essid MySSID
[ 36.930000] Path: /sbin/iwconfig
[ 36.930000] CPU: 0 PID: 203 Comm: iwconfig Not tainted 4.7.0 #2
[ 36.940000] task: 866f83a0 ti: 866a6000 task.ti: 866a6000
[ 36.940000]
[ECR ]: 0x00230400 => Misaligned r/w from 0x8677f403
[ 36.960000] [EFA ]: 0x8677f403
[ 36.960000] [BLINK ]: mwifiex_scan_networks+0x17a/0x198c [mwifiex]
[ 36.960000] [ERET ]: mwifiex_scan_networks+0x18a/0x198c [mwifiex]
[ 36.980000] [STAT32]: 0x00000206 : K E2 E1
[ 36.980000] BTA: 0x700736e2 SP: 0x866a7d0c FP: 0x5faddc84
[ 37.000000] LPS: 0x806a37ec LPE: 0x806a37fa LPC: 0x00000000
[ 37.000000] r00: 0x8677f401 r01: 0x8668aa08 r02: 0x00000001
r03: 0x00000000 r04: 0x8668b600 r05: 0x8677f406
r06: 0x8702b600 r07: 0x00000000 r08: 0x8702b600
r09: 0x00000000 r10: 0x870b3b00 r11: 0x00000000
r12: 0x00000000
[ 37.040000]
[ 37.040000] Stack Trace:
[ 37.040000] mwifiex_scan_networks+0x18a/0x198c [mwifiex]
Root cause:
mwifiex driver calls is_zero_ether_addr() against byte-aligned address:
drivers/net/wireless/marvell/mwifiex/fw.h:
struct mwifiex_scan_cmd_config {
/*
* BSS mode to be sent in the firmware command
*/
u8 bss_mode;
/* Specific BSSID used to filter scan results in the firmware */
u8 specific_bssid[ETH_ALEN];
...
} __packed;
drivers/net/wireless/marvell/mwifiex/scan.c:
mwifiex_config_scan(..., struct mwifiex_scan_cmd_config *scan_cfg_out, ...)
...
if (adapter->ext_scan &&
!is_zero_ether_addr(scan_cfg_out->specific_bssid)) {
...
}
Since firmware-related struct mwifiex_scan_cmd_config cannot be changed,
modify is_zero_ether_addr() to handle byte-aligned addresses.
Cc: Kalle Valo <kvalo@codeaurora.org>
Cc: David S. Miller <davem@davemloft.net>
Cc: Joe Perches <joe@perches.com>
Cc: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Petri Gynther <pgynther@google.com>
---
include/linux/etherdevice.h | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h
index 37ff4a6..0cfd243 100644
--- a/include/linux/etherdevice.h
+++ b/include/linux/etherdevice.h
@@ -90,11 +90,13 @@ static inline bool is_link_local_ether_addr(const u8 *addr)
* @addr: Pointer to a six-byte array containing the Ethernet address
*
* Return true if the address is all zeroes.
- *
- * Please note: addr must be aligned to u16.
*/
static inline bool is_zero_ether_addr(const u8 *addr)
{
+ if ((u32)addr & 0x1)
+ return (addr[0] | addr[1] | addr[2] | addr[3] | addr[4] |
+ addr[5]) == 0;
+
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
return ((*(const u32 *)addr) | (*(const u16 *)(addr + 4))) == 0;
#else
--
2.8.0.rc3.226.g39d4020
^ permalink raw reply related
* Re: [RESEND PATCH] nl80211: Allow GET_INTERFACE dumps to be filtered
From: Denis Kenzior @ 2016-08-12 16:24 UTC (permalink / raw)
To: Johannes Berg, linux-wireless
In-Reply-To: <1470981481.26902.4.camel@sipsolutions.net>
Hi Johannes,
>
> No, I don't see a fault in the logic. I just think it's misleading. You
> make the code look like it relies on filter_wiphy != 0, but then you go
> and treat filter_wiphy==0 as a valid case.
It relies on a sentry condition with all 3 variables being zero, not
just filter_wiphy. The original patch is about the most non-invasive
one I can come up with. Maybe a comment will alleviate any concerns?
Anyway, if you feel this is misleading, fair enough.
>
> In other places, like nl80211_prepare_wdev_dump(), we add 1 to the
> wiphy and subtract it again later to avoid exactly this. Perhaps you
> could do the same, and rely only on filter_wiphy instead of really
> relying only on wp_start/if_start.
Having looked at that particular piece of code, I ran away scared with
the conclusion that the cure is probably much worse than the disease :)
I posted a slightly different solution in v2. It is a bit more
invasive, but is more explicit in what is going on. I ran sanity checks
on it and it works as expected.
Regards,
-Denis
^ permalink raw reply
* [PATCH v2] nl80211: Allow GET_INTERFACE dumps to be filtered
From: Denis Kenzior @ 2016-08-12 16:12 UTC (permalink / raw)
To: linux-wireless; +Cc: Denis Kenzior
This patch allows GET_INTERFACE dumps to be filtered based on
NL80211_ATTR_WIPHY or NL80211_ATTR_WDEV. The documentation for
GET_INTERFACE mentions that this is possible:
"Request an interface's configuration; either a dump request on
a %NL80211_ATTR_WIPHY or ..."
However, this behavior has not been implemented until now.
Signed-off-by: Denis Kenzior <denkenz@gmail.com>
---
net/wireless/nl80211.c | 63 +++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 55 insertions(+), 8 deletions(-)
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 4997857..aa85871 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -2519,27 +2519,74 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flag
return -EMSGSIZE;
}
+static int nl80211_dump_interface_parse(struct sk_buff *skb,
+ struct netlink_callback *cb,
+ int *filter_wiphy)
+{
+ struct nlattr **tb = nl80211_fam.attrbuf;
+ int ret = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
+ tb, nl80211_fam.maxattr, nl80211_policy);
+
+ /* ignore parse errors for backward compatibility */
+ if (ret)
+ return 0;
+
+ if (tb[NL80211_ATTR_WIPHY])
+ *filter_wiphy = nla_get_u32(tb[NL80211_ATTR_WIPHY]);
+ if (tb[NL80211_ATTR_WDEV])
+ *filter_wiphy = nla_get_u64(tb[NL80211_ATTR_WDEV]) >> 32;
+
+ return 0;
+}
+
+struct dump_interface_context {
+ unsigned int wp_start;
+ unsigned int if_start;
+ int filter_wiphy;
+};
+
static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *cb)
{
- int wp_idx = 0;
- int if_idx = 0;
- int wp_start = cb->args[0];
- int if_start = cb->args[1];
struct cfg80211_registered_device *rdev;
struct wireless_dev *wdev;
+ unsigned int wp_idx = 0;
+ unsigned int if_idx;
+ static struct dump_interface_context static_ctx;
+ struct dump_interface_context *ctx = cb->args[0];
+
+ if (!ctx) {
+ int ret;
+
+ static_ctx.wp_start = 0;
+ static_ctx.if_start = 0;
+ static_ctx.filter_wiphy = -1;
+
+ ret = nl80211_dump_interface_parse(skb, cb,
+ &static_ctx.filter_wiphy);
+ if (ret)
+ return ret;
+
+ ctx = &static_ctx;
+ cb->args[0] = ctx;
+ }
rtnl_lock();
list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
if (!net_eq(wiphy_net(&rdev->wiphy), sock_net(skb->sk)))
continue;
- if (wp_idx < wp_start) {
+ if (wp_idx < ctx->wp_start) {
wp_idx++;
continue;
}
+
+ if (ctx->filter_wiphy != -1 &&
+ ctx->filter_wiphy != rdev->wiphy_idx)
+ continue;
+
if_idx = 0;
list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
- if (if_idx < if_start) {
+ if (if_idx < ctx->if_start) {
if_idx++;
continue;
}
@@ -2556,8 +2603,8 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *
out:
rtnl_unlock();
- cb->args[0] = wp_idx;
- cb->args[1] = if_idx;
+ ctx->wp_start = wp_idx;
+ ctx->if_start = if_idx;
return skb->len;
}
--
2.7.3
^ permalink raw reply related
* ath10k crash due to bad memory access in 4.7
From: Ben Greear @ 2016-08-12 14:36 UTC (permalink / raw)
To: linux-wireless@vger.kernel.org
I am seeing this in my 4.7 kernel while debugging QCA 9884 firmware that
is crashing very often. Looks like this must exacerbate some race condition,
as ar->txqs appears to have entries in it that have been deleted already.
Just in case someone has already worked on this, please let me know. I'll
keep hacking on the problem in the meantime...
(gdb) l *(ath10k_mac_tx_push_pending+0x143)
0x147e3 is in ath10k_mac_tx_push_pending (/home/greearb/git/linux-4.7.dev.y/drivers/net/wireless/ath/ath10k/mac.c:4230).
4225 return true;
4226
4227 if (ar->htt.num_pending_tx < ar->htt.tx_q_state.num_push_allowed)
4228 return true;
4229
4230 if (artxq->num_fw_queued < artxq->num_push_allowed)
4231 return true;
4232
4233 return false;
4234 }
==================================================================
BUG: KASAN: use-after-free in ath10k_mac_tx_push_pending+0x143/0x310 [ath10k_core] at addr ffff8801d3137130
Read of size 8 by task ksoftirqd/0/3
=============================================================================
BUG kmalloc-2048 (Tainted: G W ): kasan: bad access detected
-----------------------------------------------------------------------------
INFO: Allocated in sta_info_alloc+0x33c/0x820 [mac80211] age=12766 cpu=1 pid=3548
___slab_alloc+0x480/0x4b0
__slab_alloc.isra.62+0x26/0x40
__kmalloc+0x17c/0x1e0
sta_info_alloc+0x33c/0x820 [mac80211]
ieee80211_prep_connection+0x140/0xf80 [mac80211]
ieee80211_mgd_auth+0x3d2/0x670 [mac80211]
ieee80211_auth+0x13/0x20 [mac80211]
cfg80211_mlme_auth+0x1db/0x380 [cfg80211]
nl80211_authenticate+0x54b/0x5f0 [cfg80211]
genl_family_rcv_msg+0x3b7/0x600
genl_rcv_msg+0xbf/0xf0
netlink_rcv_skb+0x14d/0x180
genl_rcv+0x23/0x40
netlink_unicast+0x2ce/0x390
netlink_sendmsg+0x54c/0x680
sock_sendmsg+0x6f/0x80
INFO: Freed in sta_info_free+0xbb/0x120 [mac80211] age=409 cpu=4 pid=291
__slab_free+0x17a/0x2d0
kfree+0x18d/0x1a0
sta_info_free+0xbb/0x120 [mac80211]
__sta_info_destroy_part2+0x1eb/0x2b0 [mac80211]
__sta_info_flush+0x1fb/0x2f0 [mac80211]
ieee80211_set_disassoc+0x103/0x480 [mac80211]
ieee80211_sta_connection_lost+0x8b/0xe0 [mac80211]
ieee80211_sta_work+0xb3a/0x22e0 [mac80211]
ieee80211_iface_work+0x466/0x500 [mac80211]
process_one_work+0x2b8/0x7f0
worker_thread+0x87/0x820
kthread+0x164/0x190
ret_from_fork+0x1f/0x40
Thanks,
Ben
--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc http://www.candelatech.com
^ permalink raw reply
* Re: [PATCH] Staging: rtl8723au: os_intfs: fixed case statement is variable issue
From: Jes Sorensen @ 2016-08-12 14:30 UTC (permalink / raw)
To: sunbing
Cc: Larry.Finger, gregkh, linux-wireless, devel, linux-kernel,
sunbing.linux
In-Reply-To: <7FC388BC-FD87-44C6-87D3-AC041F1393DB@redflag-linux.com>
sunbing <sunbing@redflag-linux.com> writes:
> On Aug 11, 2016, at 23:25, Jes Sorensen <Jes.Sorensen@redhat.com> wrote:
>
>> Bing Sun <sunbing@redflag-linux.com> writes:
>>> Fixed sparse parse error:
>>> Expected constant expression in case statement.
>>>
>>> Signed-off-by: Bing Sun <sunbing@redflag-linux.com>
>>> ---
>>> drivers/staging/rtl8723au/os_dep/os_intfs.c | 11 +++++------
>>> 1 file changed, 5 insertions(+), 6 deletions(-)
>>>
>>> diff --git a/drivers/staging/rtl8723au/os_dep/os_intfs.c b/drivers/staging/rtl8723au/os_dep/os_intfs.c
>>> index b8848c2..f30d5d2 100644
>>> --- a/drivers/staging/rtl8723au/os_dep/os_intfs.c
>>> +++ b/drivers/staging/rtl8723au/os_dep/os_intfs.c
>>> @@ -283,14 +283,13 @@ static u32 rtw_classify8021d(struct sk_buff *skb)
>>> */
>>> if (skb->priority >= 256 && skb->priority <= 263)
>>> return skb->priority - 256;
>>> - switch (skb->protocol) {
>>> - case htons(ETH_P_IP):
>>> +
>>> + if (skb->protocol == htons(ETH_P_IP)) {
>>> dscp = ip_hdr(skb)->tos & 0xfc;
>>> - break;
>>> - default:
>>> - return 0;
>>> + return dscp >> 5;
>>> }
>>> - return dscp >> 5;
>>> +
>>> + return 0;
>>> }
>>
>> Pardon me here, but I find it really hard to see how this change is an
>> improvement over the old code in any shape or form.
>>
>> Jes
>
> There is no functional improvement.
> But before this patch, when we do: make C=1 M=drivers/staging/rtl8723au/
> An error output:
> drivers/staging/rtl8723au//os_dep/os_intfs.c:287:14: error: Expected
> constant expression in case statement
> To avoid sparse parse error, a case statement converts to an if statement.
> So we got this patch.
Hello
I understand this part, but it seems to me we are changing the code due
to a broken test case in sparse. Does the warning go away if you use
__constant_htons() instead of htons()?
Jes
^ permalink raw reply
* RE: [PATCH v6] cfg80211: Provision to allow the support for different beacon intervals
From: Undekari, Sunil Dutt @ 2016-08-12 12:32 UTC (permalink / raw)
To: Johannes Berg, Kushwaha, Purushottam
Cc: linux-wireless@vger.kernel.org, Malinen, Jouni,
Hullur Subramanyam, Amarnath, Kumar, Deepak (QCA)
In-Reply-To: <1471002165.26902.35.camel@sipsolutions.net>
PiBJIHdhcyBqdXN0IHRoaW5raW5nIG91dCBsb3VkIDopDQoNCmNmZzgwMjExX3ZhbGlkYXRlX2Jl
YWNvbl9pbnQgLT4gY2ZnODAyMTFfaXRlcl9jb21iaW5hdGlvbnMgc2hhbGwgYmUgaW52b2tlZCBm
b3IgdGhlIGludGVyZmFjZSBjb21iaW5hdGlvbnMgLCBjdXJyZW50bHkuIGRpZmZfYmVhY29uX2lu
dF9nY2RfbWluIGlzIGFwcGxpY2FibGUgZm9yIHRoZSBpbnRlcmZhY2UgY29tYmluYXRpb25zIGFu
ZCBhbSBub3Qgc3VyZSBob3cgY2FuIHdlIHZhbGlkYXRlIHRoaXMgZm9yIGEgc2luZ2xlIGludGVy
ZmFjZSAuIFRoaXMgc3BlY2lmaWMgaW50ZXJmYWNlIGNhbiBiZSBwYXJ0IG9mIHR3byBkaWZmZXJl
bnQgZ3JvdXBzICggaW50ZXJmYWNlIGNvbWJpbmF0aW9ucykgd2l0aCBkaWZmZXJlbnQgdmFsdWVz
IGZvciAiZGlmZl9iZWFjb25faW50X2djZF9taW4iLiANCkkgZG9uJ3QgdGhpbmsgd2UgY2FuIGdl
dCB0aGUgbWF0Y2ggZm9yIHRoZSByaWdodCBzZXQgb2YgY29tYmluYXRpb24gaGVyZSAsIGlzbid0
ID8gDQoNClRvIG1ha2UgdGhpbmdzIHNpbXBsZSAsIGNhbiB3ZSBpZ25vcmUgdGhlIGZvbGxvd2lu
ZyBydWxlIA0KIiBXaGVuID4wLCBhbnkgYmVhY29uIGludGVydmFsIG11c3QgYWxzbyBiZSBiaWdn
ZXIgdGhhbiB0aGlzIHZhbHVlLiIgDQphbmQgcmF0aGVyIGhhdmUgb25seSB0aGUgZm9sbG93aW5n
IG9uZSA/IA0KIiBXaGVuID4wLCBkaWZmZXJlbnQgYmVhY29uIGludGVydmFscyBtdXN0IGhhdmUg
YSBHQ0QgdGhhdCdzIGF0IGxlYXN0IGFzIGJpZyBhcyB0aGlzIHZhbHVlLiIgIChUbyBiZSBtb3Jl
IHByZWNpc2UgLCBhbnkgc2Vjb25kIGludGVyZmFjZSB3aGljaCBkb2VzIG5vdCBtZWV0IHRoaXMg
cnVsZSAsIHdpbGwgZmFpbCB0byBzdGFydCApIC4NCg0KUmVnYXJkcywNClN1bmlsDQoNCi0tLS0t
T3JpZ2luYWwgTWVzc2FnZS0tLS0tDQpGcm9tOiBKb2hhbm5lcyBCZXJnIFttYWlsdG86am9oYW5u
ZXNAc2lwc29sdXRpb25zLm5ldF0gDQpTZW50OiBGcmlkYXksIEF1Z3VzdCAxMiwgMjAxNiA1OjEz
IFBNDQpUbzogVW5kZWthcmksIFN1bmlsIER1dHQgPHVzZHV0dEBxdGkucXVhbGNvbW0uY29tPjsg
S3VzaHdhaGEsIFB1cnVzaG90dGFtIDxwa3VzaHdhaEBxdGkucXVhbGNvbW0uY29tPg0KQ2M6IGxp
bnV4LXdpcmVsZXNzQHZnZXIua2VybmVsLm9yZzsgTWFsaW5lbiwgSm91bmkgPGpvdW5pQHFjYS5x
dWFsY29tbS5jb20+OyBIdWxsdXIgU3VicmFtYW55YW0sIEFtYXJuYXRoIDxhbWFybmF0aEBxY2Eu
cXVhbGNvbW0uY29tPjsgS3VtYXIsIERlZXBhayAoUUNBKSA8ZGppbmRhbEBxdGkucXVhbGNvbW0u
Y29tPg0KU3ViamVjdDogUmU6IFtQQVRDSCB2Nl0gY2ZnODAyMTE6IFByb3Zpc2lvbiB0byBhbGxv
dyB0aGUgc3VwcG9ydCBmb3IgZGlmZmVyZW50IGJlYWNvbiBpbnRlcnZhbHMNCg0KT24gRnJpLCAy
MDE2LTA4LTEyIGF0IDExOjM0ICswMDAwLCBVbmRla2FyaSwgU3VuaWwgRHV0dCB3cm90ZToNCj4g
PiANCj4gPiBUaGUgY2xhcmlmaWNhdGlvbiB0aGF0IGl0IGFsc28gcmVwcmVzZW50cyB0aGUgbWlu
aW11bSBmb3IgYSBzaW5nbGUgDQo+ID4gYmVhY29uIGludGVydmFsIHdvdWxkIG1ha2Ugc29tZSBz
ZW5zZSB0byBtZSwgYnV0IGF0IHRoZSBzYW1lIHRpbWUgaXQgDQo+ID4gY2FuJ3QgYmUgdXNlZCBv
bmx5IGZvciB0aGF0LCBzbyBwZXJoYXBzIHNlcGFyYXRpbmcgYSBtaW5pbXVtIG91dA0KPiA+ID4o
cmF0aGVyIHRoYW4gdXNpbmcgdGhlIGhhcmQtY29kZWQgbWluaW11bSBvZiAxMCkgd291bGQgbWFr
ZSBzZW5zZS4NCj4gU29ycnkgLiBDb3VsZCBub3QgZ2V0IHlvdXIgc3RhdGVtZW50IGFib3ZlIC4g
QXJlIHlvdSBzYXlpbmcgdG8gbm90IA0KPiBjaGVjayBpZiB0aGUgYmVhY29uIGludGVydmFsIGlz
IDwgMTAgaW4gY2ZnODAyMTFfdmFsaWRhdGVfYmVhY29uX2ludCANCj4gcmF0aGVyIG9ubHkgY29u
c2lkZXIgPiAxMDAwMCBhbmQgZG8gdGhlIHZhbGlkYXRpb24gaWYgdGhlIGNvbmZpZ3VyZWQgDQo+
IGJlYWNvbiBpbnRlcnZhbCBpcyBsZXNzIHRoYW4gZGlmZl9iZWFjb25faW50X2djZF9taW4gLCB3
aGVuIGNvbmZpZ3VyZWQgDQo+ID8NCj4gSWYgeWVzICwgaG93IGRvIHlvdSB3YW50IHRoZSB2YWxp
ZGF0aW9uIGZvciB0aGUgQkkgKCA8IDEwICkgZm9yIHRoZSANCj4gZmlyc3QgaW50ZXJmYWNlIHRv
IGhhcHBlbiA/DQoNCkkgd2FzIGp1c3QgdGhpbmtpbmcgb3V0IGxvdWQgOikNCg0KUmlnaHQgbm93
IHdlIHZlcmlmeSB0aGF0IGl0J3MgPj0xMCwgYnV0IGRvZXMgdGhhdCBtYWtlIHNlbnNlIGlmIHNh
eSBtaW5fZ2NkIGlzIDIwPyBNYXRoZW1hdGljYWxseSwgZGVmaW5pbmcgZ2NkKG4pPW4gd291bGQg
bWFrZSBzZW5zZSwgc28gaWYgeW91IGp1c3QgaGFkIGEgc2luZ2xlIGludGVyZmFjZSwgYXBwbHlp
bmcgdGhlIG1pbl9nY2Qgd291bGQgbWVhbiB0aGF0IHRoaXMgaXMgYWxzbyB0aGUgbWluaW11bSBi
ZWFjb24gaW50ZXJ2YWwuDQoNCldlIGNhbiBzdGlsbCBsZWF2ZSB0aGUgPDEwIGNoZWNrLCBidXQg
aWYgdGhlIG1pbl9nY2QgaXMgc2V0IHRyZWF0IGp1c3QgYSBzaW5nbGUgaW50ZXJmYWNlIHdpdGgg
YmVhY29uaW5nIHdpdGggdGhlIGFib3ZlIGdjZCgpIGRlZmluaXRpb24gYW5kIGNoZWNrIHRoYXQg
dGhlIGJlYWNvbiBpbnRlcnZhbCBpcyA+PSBtaW5fZ2NkPw0KDQpSZWFsbHkgdGhhdCBqdXN0IG1l
YW5zIGV4dGVuZGluZyB0aGUgZnVuY3Rpb24gdG8gY2FsY3VsYXRlIHRoZSBHQ0QgdG8gYmUgYWJs
ZSB0byByZXR1cm4gYSB2YWx1ZSBmb3IgYSBzaW5nbGUgbnVtYmVyLg0KDQpCdXQgbWF5YmUgSSdt
IG92ZXJkZXNpZ25pbmcgdGhpcyA6KQ0KDQpqb2hhbm5lcw0K
^ permalink raw reply
* Re: [PATCH v6] cfg80211: Provision to allow the support for different beacon intervals
From: Johannes Berg @ 2016-08-12 11:42 UTC (permalink / raw)
To: Undekari, Sunil Dutt, Kushwaha, Purushottam
Cc: linux-wireless@vger.kernel.org, Malinen, Jouni,
Hullur Subramanyam, Amarnath, Kumar, Deepak (QCA)
In-Reply-To: <ba55eb8a461b41a4b7a592ee567d0fbf@aphydexm01f.ap.qualcomm.com>
On Fri, 2016-08-12 at 11:34 +0000, Undekari, Sunil Dutt wrote:
> >
> > The clarification that it also represents the minimum for a single
> > beacon interval would make some sense to me, but at the same time
> > it can't be used only for that, so perhaps separating a minimum out
> > >(rather than using the hard-coded minimum of 10) would make sense.
> Sorry . Could not get your statement above .
> Are you saying to not check if the beacon interval is < 10 in
> cfg80211_validate_beacon_int rather only consider > 10000 and do the
> validation if the configured beacon interval is less than
> diff_beacon_int_gcd_min , when configured ?
> If yes , how do you want the validation for the BI ( < 10 ) for the
> first interface to happen ?
I was just thinking out loud :)
Right now we verify that it's >=10, but does that make sense if say
min_gcd is 20? Mathematically, defining gcd(n)=n would make sense, so
if you just had a single interface, applying the min_gcd would mean
that this is also the minimum beacon interval.
We can still leave the <10 check, but if the min_gcd is set treat just
a single interface with beaconing with the above gcd() definition and
check that the beacon interval is >= min_gcd?
Really that just means extending the function to calculate the GCD to
be able to return a value for a single number.
But maybe I'm overdesigning this :)
johannes
^ permalink raw reply
* RE: [PATCH v6] cfg80211: Provision to allow the support for different beacon intervals
From: Undekari, Sunil Dutt @ 2016-08-12 11:34 UTC (permalink / raw)
To: Johannes Berg, Kushwaha, Purushottam
Cc: linux-wireless@vger.kernel.org, Malinen, Jouni,
Hullur Subramanyam, Amarnath, Kumar, Deepak (QCA)
In-Reply-To: <1470995683.26902.31.camel@sipsolutions.net>
PlRoZSBjbGFyaWZpY2F0aW9uIHRoYXQgaXQgYWxzbyByZXByZXNlbnRzIHRoZSBtaW5pbXVtIGZv
ciBhIHNpbmdsZSBiZWFjb24gaW50ZXJ2YWwgd291bGQgbWFrZSBzb21lIHNlbnNlIHRvIG1lLCBi
dXQgYXQgdGhlIHNhbWUgdGltZSBpdCBjYW4ndCBiZSB1c2VkIG9ubHkgZm9yIHRoYXQsIHNvIHBl
cmhhcHMgc2VwYXJhdGluZyBhIG1pbmltdW0gb3V0ID4ocmF0aGVyIHRoYW4gdXNpbmcgdGhlIGhh
cmQtY29kZWQgbWluaW11bSBvZiAxMCkgd291bGQgbWFrZSBzZW5zZS4NClNvcnJ5IC4gQ291bGQg
bm90IGdldCB5b3VyIHN0YXRlbWVudCBhYm92ZSAuIA0KQXJlIHlvdSBzYXlpbmcgdG8gbm90IGNo
ZWNrIGlmIHRoZSBiZWFjb24gaW50ZXJ2YWwgaXMgPCAxMCBpbiBjZmc4MDIxMV92YWxpZGF0ZV9i
ZWFjb25faW50IHJhdGhlciBvbmx5IGNvbnNpZGVyID4gMTAwMDAgYW5kIGRvIHRoZSB2YWxpZGF0
aW9uIGlmIHRoZSBjb25maWd1cmVkIGJlYWNvbiBpbnRlcnZhbCBpcyBsZXNzIHRoYW4gZGlmZl9i
ZWFjb25faW50X2djZF9taW4gLCB3aGVuIGNvbmZpZ3VyZWQgPyANCklmIHllcyAsIGhvdyBkbyB5
b3Ugd2FudCB0aGUgdmFsaWRhdGlvbiBmb3IgdGhlIEJJICggPCAxMCApIGZvciB0aGUgZmlyc3Qg
aW50ZXJmYWNlIHRvIGhhcHBlbiA/DQoNClJlZ2FyZHMsDQpTdW5pbA0KDQoNCg0KLS0tLS1Pcmln
aW5hbCBNZXNzYWdlLS0tLS0NCkZyb206IEpvaGFubmVzIEJlcmcgW21haWx0bzpqb2hhbm5lc0Bz
aXBzb2x1dGlvbnMubmV0XSANClNlbnQ6IEZyaWRheSwgQXVndXN0IDEyLCAyMDE2IDM6MjUgUE0N
ClRvOiBLdXNod2FoYSwgUHVydXNob3R0YW0gPHBrdXNod2FoQHF0aS5xdWFsY29tbS5jb20+DQpD
YzogbGludXgtd2lyZWxlc3NAdmdlci5rZXJuZWwub3JnOyBNYWxpbmVuLCBKb3VuaSA8am91bmlA
cWNhLnF1YWxjb21tLmNvbT47IFVuZGVrYXJpLCBTdW5pbCBEdXR0IDx1c2R1dHRAcXRpLnF1YWxj
b21tLmNvbT47IEh1bGx1ciBTdWJyYW1hbnlhbSwgQW1hcm5hdGggPGFtYXJuYXRoQHFjYS5xdWFs
Y29tbS5jb20+OyBLdW1hciwgRGVlcGFrIChRQ0EpIDxkamluZGFsQHF0aS5xdWFsY29tbS5jb20+
DQpTdWJqZWN0OiBSZTogW1BBVENIIHY2XSBjZmc4MDIxMTogUHJvdmlzaW9uIHRvIGFsbG93IHRo
ZSBzdXBwb3J0IGZvciBkaWZmZXJlbnQgYmVhY29uIGludGVydmFscw0KDQpPbiBGcmksIDIwMTYt
MDgtMTIgYXQgMTQ6MDkgKzA1MzAsIFB1cnVzaG90dGFtIEt1c2h3YWhhIHdyb3RlOg0KPsKgDQo+
IMKgICogQHJhZGFyX2RldGVjdF9yZWdpb25zOiBiaXRtYXAgb2YgcmVnaW9ucyBzdXBwb3J0ZWQg
Zm9yIHJhZGFyIA0KPiBkZXRlY3Rpb24NCj4gKyAqIEBkaWZmX2JlYWNvbl9pbnRfZ2NkOiBUaGlz
IGludGVyZmFjZSBjb21iaW5hdGlvbiBzdXBwb3J0cw0KPiBkaWZmZXJlbnQgYmVhY29uDQo+ICsg
KglpbnRlcnZhbHMgaW4gbXVsdGlwbGUgb2YgR0NEIHZhbHVlLg0KDQpJIHRoaW5rIHlvdSBzaG91
bGQgYWRkICJMZWF2ZSB0aGlzIHNldCB0byAwIHRvIHJlcXVpcmUgYWxsIGJlYWNvbiBpbnRlcnZh
bHMgdG8gbWF0Y2ggZXhhY3RseS4iDQoNCkFuZCBhbm90aGVyIHRoaW5nIEkganVzdCByZWFsaXpl
ZDogUGVyaGFwcyBzb21lYm9keSBtaWdodCBub3QganVzdCBoYXZlIGEgR0NEIHJlcXVpcmVtZW50
LCBidXQgYWxzbyByZXF1aXJlIHRoYXQgYWxsIGJlYWNvbiBpbnRlcnZhbHMgYXJlIGFuIGV4YWN0
IG11bHRpcGxlIG9mIHRoZSBzbWFsbGVzdCBvZiB0aGVtPyBJLmUuIHRoYXQgdGhlIEdDRChhbGwg
b2YgdGhlbSkgPT0gbWluKGFsbCBvZiB0aGVtKT8NCg0KQW55d2F5LCBpZiB5b3UgZG9uJ3QgaGF2
ZSBzdWNoIGEgcmVxdWlyZW1lbnQgbm93LCB0aGVyZSdzIG5vIHJlYXNvbiB0byBhZGQgaXQgbm93
IGVpdGhlci4NCg0KPiDCoCAqIFdpdGggdGhpcyBzdHJ1Y3R1cmUgdGhlIGRyaXZlciBjYW4gZGVz
Y3JpYmUgd2hpY2ggaW50ZXJmYWNlDQo+IMKgICogY29tYmluYXRpb25zIGl0IHN1cHBvcnRzIGNv
bmN1cnJlbnRseS4NCj4gQEAgLTI5NzAsNiArMjk3Miw3IEBAIHN0cnVjdCBpZWVlODAyMTFfaWZh
Y2VfbGltaXQgew0KPiDCoCAqCS5uX2xpbWl0cyA9IEFSUkFZX1NJWkUobGltaXRzMiksDQo+IMKg
ICoJLm1heF9pbnRlcmZhY2VzID0gOCwNCj4gwqAgKgkubnVtX2RpZmZlcmVudF9jaGFubmVscyA9
IDEsDQo+ICsgKgkuZGlmZl9iZWFjb25faW50X2djZCA9IDEwMCwNCj4gwqAgKsKgwqB9Ow0KDQpU
aGlzIGJlY29tZXMgc29tZXdoYXQgY3VyaW91cy4gRG9lcyBpdCBhbHNvIG1lYW4gdGhhdCB5b3Ug
Y2FuIG9ubHkgc3VwcG9ydCBiZWFjb24gaW50ZXJ2YWxzIHRoYXQgYXJlIG11bHRpcGxlcyBvZiAx
MDA/DQoNClRoaXMgYmVpbmcgeW91ciBleGFtcGxlIGtpbmRhIG1ha2VzIG1lIHRoaW5rIHRoYXQg
eW91ICpkbyogd2FudCB0byBoYXZlIGl0IG11bHRpcGxlcyBvZiB0aGUgc21hbGxlc3QsIGxpa2Ug
SSB3YXMgb3V0bGluaW5nIGJlbG93Pw0KDQpBc3N1bWluZyB5b3VyIGRyaXZlciB3b3VsZCBhZHZl
cnRpc2UgaXQgdGhpcyB3YXksIHdvdWxkIHlvdSBhY3R1YWxseSBiZSBhYmxlIHRvIGRvIEJJcyBv
ZiAyMDAgYW5kIDMwMCBvbiB0d28gaW50ZXJmYWNlcz8NCg0KUmVnYXJkbGVzcywgYWR2ZXJ0aXNp
bmcgMTAwIHdvdWxkIG1lYW4gbm90IHN1cHBvcnRpbmcgYSBiZWFjb24gaW50ZXJ2YWwgb2YgNTAg
YXQgYWxsLCB3aGljaCBzZWVtcyBvZGQuDQoNCg0KSSB0aGluayB0aGUgR0NEIHJlcXVpcmVtZW50
IHNob3VsZCBiZSByZXBocmFzZWQgKGFuZCBteSBvcmlnaW5hbCBtZW50aW9uIG9mIHRoaXMgd2Fz
bid0IHZlcnkgcHJlY2lzZSkgLSBJIHRoaW5rIGl0IHJlYWxseSBzaG91bGRuJ3QgYmUgYW4gZXhh
Y3QgR0NEIHJlcXVpcmVtZW50IGxpa2UgeW91IGRpZCBub3csIGJ1dCBhIHJlcXVpcmVtZW50ICpv
biogdGhlIEdDRCwgbGlrZQ0KDQrCoEBkaWZmX2JlYWNvbl9pbnRfZ2NkX21pbjogV2hlbiAwLCBh
bGwgYmVhY29uIGludGVydmFscyBtdXN0IG1hdGNoLg0KCVdoZW4gPjAsIGRpZmZlcmVudCBiZWFj
b24gaW50ZXJ2YWxzIG11c3QgaGF2ZSBhIEdDRCB0aGF0J3MgYXQNCglsZWFzdCBhcyBiaWcgYXMg
dGhpcyB2YWx1ZS4NCg0KbWF5YmUgYWxzbyBhZGQsIHNpbmNlIHRoZSBHQ0Qgb2YgYSBzaW5nbGUg
dmFsdWUgaXMgZmlzaHk6DQoNCglXaGVuID4wLCBhbnkgYmVhY29uIGludGVydmFsIG11c3QgYWxz
byBiZSBiaWdnZXIgdGhhbiB0aGlzDQoJdmFsdWUuDQoNCldpdGggYSBkaWZmX2JlYWNvbl9pbnRf
Z2NkX21pbj01MCwgdGhpcyB3b3VsZCBzdGlsbCBhbGxvdyBiZWFjb24gaW50ZXJ2YWxzIDEwMiwx
NTMgKEdDRCA1MSksIHdoaWNoIHNlZW1zIG11Y2ggbW9yZSBmbGV4aWJsZS4NCg0KVGhlIGNsYXJp
ZmljYXRpb24gdGhhdCBpdCBhbHNvIHJlcHJlc2VudHMgdGhlIG1pbmltdW0gZm9yIGEgc2luZ2xl
IGJlYWNvbiBpbnRlcnZhbCB3b3VsZCBtYWtlIHNvbWUgc2Vuc2UgdG8gbWUsIGJ1dCBhdCB0aGUg
c2FtZSB0aW1lIGl0IGNhbid0IGJlIHVzZWQgb25seSBmb3IgdGhhdCwgc28gcGVyaGFwcyBzZXBh
cmF0aW5nIGEgbWluaW11bSBvdXQgKHJhdGhlciB0aGFuIHVzaW5nIHRoZSBoYXJkLWNvZGVkIG1p
bmltdW0gb2YgMTApIHdvdWxkIG1ha2Ugc2Vuc2UuDQoNCj4gKyAqIEBOTDgwMjExX0lGQUNFX0NP
TUJfRElGRl9CSV9HQ0Q6IHUzMiBhdHRyaWJ1dGUgc3BlY2lmeWluZyB0aGUgR0NEDQo+IG9mDQo+
ICsgKglkaWZmZXJlbnQgYmVhY29uIGludGVydmFscyBzdXBwb3J0ZWQgYnkgYWxsIHRoZSBpbnRl
cmZhY2UNCj4gY29tYmluYXRpb25zDQo+ICsgKglpbiB0aGlzIGdyb3VwIChub3QgcHJlc2VudCBp
ZiBhbGwgYmVhY29uIGludGVydmFsIG11c3QNCj4gbWF0Y2gpLg0KDQpJJ2QgdHVybiB0aGF0IGFy
b3VuZDogIihpZiBub3QgcHJlc2VudCwgYWxsIGJlYWNvbiBpbnRlcnZhbHMgbXVzdCBtYXRjaCki
DQoNCj4gK3N0cnVjdCBkaWZmX2JlYWNvbl9pbnQgew0KPiA+ICsJdTMyIGJlYWNvbl9pbnQ7DQo+
ID4gKwlib29sIHZhbGlkOw0KPiArfTsNCj4gKw0KPiArc3RhdGljIHZvaWQNCj4gK2NmZzgwMjEx
X3ZhbGlkYXRlX2RpZmZfYmVhY29uX2ludChjb25zdCBzdHJ1Y3QgDQo+ICtpZWVlODAyMTFfaWZh
Y2VfY29tYmluYXRpb24gKmMsDQo+ID4gKwkJCQnCoMKgdm9pZCAqZGF0YSkNCj4gK3sNCj4gPiAr
CXN0cnVjdCBkaWZmX2JlYWNvbl9pbnQgKmRpZmZfYmkgPSBkYXRhOw0KPiArDQo+ID4gKwlpZiAo
Yy0+ZGlmZl9iZWFjb25faW50X2djZCAmJg0KPiA+ICsJwqDCoMKgwqAhKGRpZmZfYmktPmJlYWNv
bl9pbnQgJSBjLT5kaWZmX2JlYWNvbl9pbnRfZ2NkKSkNCj4gPiArCQlkaWZmX2JpLT52YWxpZCA9
IHRydWU7DQo+ICt9DQo+ID4gDQoNCk9idmlvdXNseSwgdGhpcyB2YWxpZGF0aW9uIGlzIGZhciBl
YXNpZXIgdGhhbiBjYWxjdWxhdGluZyB0aGUgR0NEIGZpcnN0LCBidXQgSSB0aGluayBpdCdzIHdv
cnRod2hpbGUgZG9pbmcgaXQgdGhlIG90aGVyIHdheS4NCg0Kam9oYW5uZXMNCg0K
^ permalink raw reply
* Re: [PATCH v6] cfg80211: Provision to allow the support for different beacon intervals
From: Johannes Berg @ 2016-08-12 9:54 UTC (permalink / raw)
To: Purushottam Kushwaha; +Cc: linux-wireless, jouni, usdutt, amarnath, djindal
In-Reply-To: <1470991178-11024-1-git-send-email-pkushwah@qti.qualcomm.com>
On Fri, 2016-08-12 at 14:09 +0530, Purushottam Kushwaha wrote:
>
> * @radar_detect_regions: bitmap of regions supported for radar
> detection
> + * @diff_beacon_int_gcd: This interface combination supports
> different beacon
> + * intervals in multiple of GCD value.
I think you should add "Leave this set to 0 to require all beacon
intervals to match exactly."
And another thing I just realized: Perhaps somebody might not just have
a GCD requirement, but also require that all beacon intervals are an
exact multiple of the smallest of them? I.e. that the GCD(all of them)
== min(all of them)?
Anyway, if you don't have such a requirement now, there's no reason to
add it now either.
> * With this structure the driver can describe which interface
> * combinations it supports concurrently.
> @@ -2970,6 +2972,7 @@ struct ieee80211_iface_limit {
> * .n_limits = ARRAY_SIZE(limits2),
> * .max_interfaces = 8,
> * .num_different_channels = 1,
> + * .diff_beacon_int_gcd = 100,
> * };
This becomes somewhat curious. Does it also mean that you can only
support beacon intervals that are multiples of 100?
This being your example kinda makes me think that you *do* want to have
it multiples of the smallest, like I was outlining below?
Assuming your driver would advertise it this way, would you actually be
able to do BIs of 200 and 300 on two interfaces?
Regardless, advertising 100 would mean not supporting a beacon interval
of 50 at all, which seems odd.
I think the GCD requirement should be rephrased (and my original
mention of this wasn't very precise) - I think it really shouldn't be
an exact GCD requirement like you did now, but a requirement *on* the
GCD, like
@diff_beacon_int_gcd_min: When 0, all beacon intervals must match.
When >0, different beacon intervals must have a GCD that's at
least as big as this value.
maybe also add, since the GCD of a single value is fishy:
When >0, any beacon interval must also be bigger than this
value.
With a diff_beacon_int_gcd_min=50, this would still allow beacon
intervals 102,153 (GCD 51), which seems much more flexible.
The clarification that it also represents the minimum for a single
beacon interval would make some sense to me, but at the same time it
can't be used only for that, so perhaps separating a minimum out
(rather than using the hard-coded minimum of 10) would make sense.
> + * @NL80211_IFACE_COMB_DIFF_BI_GCD: u32 attribute specifying the GCD
> of
> + * different beacon intervals supported by all the interface
> combinations
> + * in this group (not present if all beacon interval must
> match).
I'd turn that around: "(if not present, all beacon intervals must
match)"
> +struct diff_beacon_int {
> > + u32 beacon_int;
> > + bool valid;
> +};
> +
> +static void
> +cfg80211_validate_diff_beacon_int(const struct ieee80211_iface_combination *c,
> > + void *data)
> +{
> > + struct diff_beacon_int *diff_bi = data;
> +
> > + if (c->diff_beacon_int_gcd &&
> > + !(diff_bi->beacon_int % c->diff_beacon_int_gcd))
> > + diff_bi->valid = true;
> +}
> >
Obviously, this validation is far easier than calculating the GCD
first, but I think it's worthwhile doing it the other way.
johannes
^ permalink raw reply
* Re: TCP data throughput for BCM43362
From: Jörg Krause @ 2016-08-12 9:25 UTC (permalink / raw)
To: Arend van Spriel, Franky Lin
Cc: Brett Rudley, brcm80211-dev-list, Hante Meuleman, Franky Lin,
linux-wireless, Arend van Spriel, Jörg Krause
In-Reply-To: <6cdbbae7-8a56-6778-e886-68eeea7add15@broadcom.com>
Am 7. August 2016 13:41:04 MESZ, schrieb Arend van Spriel <arend.vanspriel@broadcom.com>:
>On 06-08-16 16:12, Jörg Krause wrote:
>> Hi all,
>
>A bit weird email format making it a bit hard to determine where your
>last reply starts...
Sorry for my bad mobile mail client. I hope this one can handle in line comments.
>
>> On Fr, 2016-08-05 at 17:56 -0700, Franky Lin wrote:
>>
>> On Fri, Aug 5, 2016 at 2:29 PM, Jörg Krause <joerg.krause@embedded.ro
>> cks>
>> wrote:
>>
>>
>>
>>
>>
>> Am 5. August 2016 23:01:10 MESZ, schrieb Arend Van Spriel <
>> arend.vanspriel@broadcom.com>:
>>
>>
>> Op 5 aug. 2016 22:46 schreef "Jörg Krause"
>> <joerg.krause@embedded.rocks>:
>>
>>
>>
>> Hi,
>>
>> I'm using a custom ARM board with an BCM43362 wifi chip from
>>
>> Broadcom.
>>
>>
>> The wifi chip is attached via SDIO to the controller with a
>> clock of
>> 48MHz. Linux kernel version is 4.7.
>>
>> When measuring the network bandwidth with iperf3 I get a
>> bandwith of
>> only around 5 Mbps. I found a similar thread at the Broadcom
>>
>> community
>>
>>
>> [1] where the test was done with a M4 CPU + BCM43362 and an
>> average
>> result of 3.3 Mbps.
>>
>> Interestingly, a BCM43362 Wi-Fi Dev Kit [2] notes a TCP data
>>
>> throughput
>>
>>
>> greater than 20 Mbps.
>>
>> Why is the throughput I measured much lower? Note that I
>> measured
>> several times with almost no neighbor devices or networks.
>>
>> This is a test sample measured with iperf3:
>>
>> $ iperf3 -c 192.168.2.1 -i 1 -t 10
>> Connecting to host 192.168.2.1, port 5201
>> [ 4] local 192.168.2.155 port 36442 connected to
>> 192.168.2.1
>>
>> port
>>
>>
>> 5201
>> [ ID]
>> Interval Transfer Bandwidth Retr Cwnd
>> [ 4] 0.00-1.00 sec 615 KBytes 5.04
>> Mbits/sec 0 56.6
>> KBytes
>> [ 4] 1.00-2.00 sec 622 KBytes 5.10
>> Mbits/sec 0 84.8
>> KBytes
>> [ 4] 2.00-3.00 sec 625 KBytes 5.12
>> Mbits/sec 0 113
>> KBytes
>> [ 4] 3.00-4.00 sec 571 KBytes 4.68
>> Mbits/sec 0 140
>> KBytes
>> [ 4] 4.00-5.00 sec 594 KBytes 4.87
>> Mbits/sec 0 167
>> KBytes
>> [ 4] 5.00-6.00 sec 628 KBytes 5.14
>> Mbits/sec 0 195
>> KBytes
>> [ 4] 6.00-7.00 sec 619 KBytes 5.07
>> Mbits/sec 0 202
>> KBytes
>> [ 4] 7.00-8.00 sec 608 KBytes 4.98
>> Mbits/sec 0 202
>> KBytes
>> [ 4] 8.00-9.00 sec 602 KBytes 4.93
>> Mbits/sec 0 202
>> KBytes
>> [ 4] 9.00-10.00 sec 537 KBytes 4.40
>> Mbits/sec 0 202
>> KBytes
>> - - - - - - - - - - - - - - - - - - - - - - - - -
>> [ ID] Interval Transfer Bandwidth Retr
>> [ 4] 0.00-10.00 sec 5.88 MBytes 4.93
>> Mbits/sec 0 sender
>> [ 4] 0.00-10.00 sec 5.68 MBytes 4.76
>> Mbits/sec receiver
>>
>>
>> Not overly familiar with iperf3. Do these lines mean you are
>> doing
>> bidirectional test, ie. upstream and downstream at the same time.
>> Another
>> thing affecting tput could be power-save.
>>
>>
>> No, iperf3 does not support bidrectional test. Power-save is turned
>> off.
>>
>> What does iw link say?
>>
>
>but I guess it starts here!
>
>> I compared the results with a Cubietruck I have:
>>
>> # iperf3 -s
>> -----------------------------------------------------------
>> Server listening on 5201
>> -----------------------------------------------------------
>> Accepted connection from 192.168.178.46, port 42906
>> [ 5] local 192.168.178.38 port 5201 connected to 192.168.178.46 port
>> 42908
>> [ ID] Interval Transfer Bandwidth
>> [ 5] 0.00-1.00 sec 2.29 MBytes 19.2 Mbits/sec
>
>> [ 5] 1.00-2.00 sec 2.21 MBytes 18.5 Mbits/sec
>
>> [ 5] 2.00-3.00 sec 2.17 MBytes 18.2 Mbits/sec
>
>> [ 5] 3.00-4.00 sec 2.09 MBytes 17.6 Mbits/sec
>
>> [ 5] 4.00-5.00 sec 2.20 MBytes 18.5 Mbits/sec
>
>> [ 5] 5.00-6.00 sec 2.64 MBytes 22.1 Mbits/sec
>
>> [ 5] 6.00-7.00 sec 2.67 MBytes 22.4 Mbits/sec
>
>> [ 5] 7.00-8.00 sec 2.62 MBytes 22.0 Mbits/sec
>
>> [ 5] 8.00-9.00 sec 2.35 MBytes 19.8 Mbits/sec
>
>> [ 5] 9.00-10.00 sec 2.30 MBytes 19.3 Mbits/sec
>
>> [ 5] 10.00-10.03 sec 83.4 KBytes 23.5 Mbits/sec
>
>> - - - - - - - - - - - - - - - - - - - - - - - - -
>> [ ID] Interval Transfer Bandwidth Retr
>> [ 5] 0.00-10.03 sec 23.9 MBytes 20.0
>> Mbits/sec 0 sender
>> [ 5] 0.00-10.03 sec 23.6 MBytes 19.8
>> Mbits/sec receiver
>>
>> # iw dev wlan0 link
>> Connected to xx:xx:xx:xx:xx (on wlan0)
>> SSID: xxx
>> freq: 2437
>> tx bitrate: 65.0 MBit/s
>>
>> bss flags: short-preamble short-slot-time
>> dtim period: 1
>> beacon int: 100
>
>Too bad RSSI is not in the output above. That may be due to a
>regression
>in our driver which has been fixed by commit 94abd778a7bb ("brcmfmac:
>add fallback for devices that do not report per-chain values").
>However,
>the tx bitrate seems within the same range as the other platform.
>
>> The Cubietruck works also with the brcmfmac driver.
>>
>> May it depend on the NVRAM file?
>
>Not sure. Can you tell me a bit more about the custom ARM board. Does
>it
>use the same wifi module as Cubietruck, ie. the AMPAK AP6210? If you
>can
>make a wireshark sniff we can check the actual bitrate and medium
>density in terms of packets. Another thing to look at is the SDIO host
>controller. In brcmf_sdiod_sgtable_alloc() some key values are used
>from
>the host controller. It only logs the number of entries of the
>scatter-gather table, but could you add the other values in this
>function that are used to determine the number of entries.
Many thanks for your conclusions! I am on vacation right now and I will investigate this issue further when I am back.
Best regards,
Jörg Krause
^ permalink raw reply
* pull-request: mac80211-next 2016-08-12
From: Johannes Berg @ 2016-08-12 9:20 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-wireless
Hi Dave,
This first pull request is pretty small, but there's no point
in hanging on to it for long, so here it goes anyway. Nothing
all that interesting, I think.
We might have a bunch of new APIs that were promised to me
coming up soon, for new features, but I don't know how quickly
that's actually going to happen.
Let me know if there's any problem.
Thanks,
johannes
The following changes since commit 6cdaf03f8c23fcbfe7d4fa6876e114193bb6b632:
RDS: add __printf format attribute to error reporting functions (2016-08-08 16:16:21 -0700)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git tags/mac80211-next-for-davem-2016-08-12
for you to fetch changes up to ff9a71afc948f609c4eaba47cd6788926e7cc105:
nl80211: explicitly check enum nl80211_mesh_power_mode (2016-08-11 20:00:37 +0200)
----------------------------------------------------------------
Not much for -next so far, but here it goes:
* send more nl80211 events for interfaces
* remove useless network/transport offset mangling code
* validate beacon intervals identically for all interface types
* use driver rate estimates for mesh
* fix a compiler type/signedness warning
----------------------------------------------------------------
Denis Kenzior (2):
cfg80211: always notify userspace of new wireless netdevs
cfg80211: always notify userspace when wireless netdev is removed
Felix Fietkau (1):
mac80211: remove skb header offset mangling in ieee80211_build_hdr
Johannes Berg (1):
nl80211: explicitly check enum nl80211_mesh_power_mode
Maxim Altshul (2):
mac80211: mesh: Add support for HW RC implementation
mac80211: call get_expected_throughput only after adding station
Purushottam Kushwaha (1):
cfg80211: identically validate beacon interval for AP/MESH/IBSS
net/mac80211/driver-ops.h | 8 ++--
net/mac80211/mesh_hwmp.c | 27 ++++++++++----
net/mac80211/sta_info.c | 25 ++++++++++---
net/mac80211/sta_info.h | 2 +
net/mac80211/tx.c | 28 +-------------
net/wireless/core.c | 6 +++
net/wireless/nl80211.c | 94 +++++++++++++++++++++++++++--------------------
net/wireless/nl80211.h | 3 ++
net/wireless/util.c | 2 +-
9 files changed, 112 insertions(+), 83 deletions(-)
^ permalink raw reply
* Re: [PATCH 1/2] ath9k: use ieee80211_tx_status_noskb where possible
From: Zefir Kurtisi @ 2016-08-12 8:31 UTC (permalink / raw)
To: Felix Fietkau, linux-wireless; +Cc: kvalo
In-Reply-To: <9e324227-f105-bc16-f0c0-c2a3a79032e8@nbd.name>
On 08/11/2016 09:27 PM, Felix Fietkau wrote:
> On 2016-08-11 18:05, Zefir Kurtisi wrote:
>> On 08/04/2016 11:49 PM, Felix Fietkau wrote:
>>> It removes the need for undoing the padding changes to skb->data and it
>>> improves performance by eliminating one tx status lookup per MPDU in the
>>> status path. It is also useful for preparing a follow-up fix to better
>>> handle powersave filtering.
>>>
>>
>> For me, this one introduces a regression to the statistics, e.g.
>> 'dot11TransmittedFragmentCount' is now accounted differently since it is not
>> updated from within ieee80211_tx_status_noskb().
> Is this important? I guess it would be possible to make this more
> accurate by extending the API, but I wonder if that's worth doing just
> for these debugfs counters.
>
If you want to support the IEEE802dot11.MIB (dot11mac.dot11CountersTable), they
are important. Not sure though if it is used by others besides us.
I think the real issue here is that those counters are regarded as internal debug
values (as the comments or e.g. commit c206ca6709 state) instead of general
purpose statistics that is exposed to SNMP. As such, they should be configurable
as a feature independent of debug settings in mac80211.
Aside from that consideration, this patch (with the follow up ones) increased peak
performance noticeably (we measure some 5%+ higher peak throughput), which for
sure is worth dropping the counters for most.
I am fine handling this internally. A note in the commit message would be helpful
that states that counters dot11TransmittedFragmentCount, dot11FrameDuplicateCount,
dot11ReceivedFragmentCount, and dot11MulticastReceivedFrameCount become invalid.
Cheers,
Zefir
^ permalink raw reply
* [PATCH v6] cfg80211: Provision to allow the support for different beacon intervals
From: Purushottam Kushwaha @ 2016-08-12 8:39 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, jouni, usdutt, amarnath, djindal, pkushwah
This commit provides a mechanism for the host drivers to advertise the
support for different beacon intervals among the respective interface
combinations in a group, through diff_beacon_int_gcd (u32).
The configured BI for a specific interface must be a multiple of this
value and also the active beaconing interfaces (along with the current
one) must match with the interface combinations in a group that advertise
the support for different beacon interval.
Signed-off-by: Purushottam Kushwaha <pkushwah@qti.qualcomm.com>
---
include/net/cfg80211.h | 4 ++++
include/uapi/linux/nl80211.h | 8 ++++++--
net/wireless/core.h | 2 +-
net/wireless/nl80211.c | 13 ++++++++++---
net/wireless/util.c | 36 ++++++++++++++++++++++++++++++++++--
5 files changed, 55 insertions(+), 8 deletions(-)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 9c23f4d3..a0c635a 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2939,6 +2939,8 @@ struct ieee80211_iface_limit {
* only in special cases.
* @radar_detect_widths: bitmap of channel widths supported for radar detection
* @radar_detect_regions: bitmap of regions supported for radar detection
+ * @diff_beacon_int_gcd: This interface combination supports different beacon
+ * intervals in multiple of GCD value.
*
* With this structure the driver can describe which interface
* combinations it supports concurrently.
@@ -2970,6 +2972,7 @@ struct ieee80211_iface_limit {
* .n_limits = ARRAY_SIZE(limits2),
* .max_interfaces = 8,
* .num_different_channels = 1,
+ * .diff_beacon_int_gcd = 100,
* };
*
*
@@ -2997,6 +3000,7 @@ struct ieee80211_iface_combination {
bool beacon_int_infra_match;
u8 radar_detect_widths;
u8 radar_detect_regions;
+ u32 diff_beacon_int_gcd;
};
struct ieee80211_txrx_stypes {
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 2206941..369e403 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -4203,6 +4203,9 @@ enum nl80211_iface_limit_attrs {
* of supported channel widths for radar detection.
* @NL80211_IFACE_COMB_RADAR_DETECT_REGIONS: u32 attribute containing the bitmap
* of supported regulatory regions for radar detection.
+ * @NL80211_IFACE_COMB_DIFF_BI_GCD: u32 attribute specifying the GCD of
+ * different beacon intervals supported by all the interface combinations
+ * in this group (not present if all beacon interval must match).
* @NUM_NL80211_IFACE_COMB: number of attributes
* @MAX_NL80211_IFACE_COMB: highest attribute number
*
@@ -4210,8 +4213,8 @@ enum nl80211_iface_limit_attrs {
* limits = [ #{STA} <= 1, #{AP} <= 1 ], matching BI, channels = 1, max = 2
* => allows an AP and a STA that must match BIs
*
- * numbers = [ #{AP, P2P-GO} <= 8 ], channels = 1, max = 8
- * => allows 8 of AP/GO
+ * numbers = [ #{AP, P2P-GO} <= 8 ], diff BI gcd, channels = 1, max = 8,
+ * => allows 8 of AP/GO that can beacon at multiple of gcd intervals
*
* numbers = [ #{STA} <= 2 ], channels = 2, max = 2
* => allows two STAs on different channels
@@ -4237,6 +4240,7 @@ enum nl80211_if_combination_attrs {
NL80211_IFACE_COMB_NUM_CHANNELS,
NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS,
NL80211_IFACE_COMB_RADAR_DETECT_REGIONS,
+ NL80211_IFACE_COMB_DIFF_BI_GCD,
/* keep last */
NUM_NL80211_IFACE_COMB,
diff --git a/net/wireless/core.h b/net/wireless/core.h
index eee9144..5fffe58 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -475,7 +475,7 @@ int ieee80211_get_ratemask(struct ieee80211_supported_band *sband,
u32 *mask);
int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev,
- u32 beacon_int);
+ enum nl80211_iftype iftype, u32 beacon_int);
void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev,
enum nl80211_iftype iftype, int num);
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 4997857..01945fb 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -1020,6 +1020,10 @@ static int nl80211_put_iface_combinations(struct wiphy *wiphy,
nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_REGIONS,
c->radar_detect_regions)))
goto nla_put_failure;
+ if (c->diff_beacon_int_gcd &&
+ nla_put_u32(msg, NL80211_IFACE_COMB_DIFF_BI_GCD,
+ c->diff_beacon_int_gcd))
+ goto nla_put_failure;
nla_nest_end(msg, nl_combi);
}
@@ -3433,7 +3437,8 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
params.dtim_period =
nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
- err = cfg80211_validate_beacon_int(rdev, params.beacon_interval);
+ err = cfg80211_validate_beacon_int(rdev, dev->ieee80211_ptr->iftype,
+ params.beacon_interval);
if (err)
return err;
@@ -7768,7 +7773,8 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
ibss.beacon_interval =
nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
- err = cfg80211_validate_beacon_int(rdev, ibss.beacon_interval);
+ err = cfg80211_validate_beacon_int(rdev, NL80211_IFTYPE_ADHOC,
+ ibss.beacon_interval);
if (err)
return err;
@@ -9245,7 +9251,8 @@ static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info)
setup.beacon_interval =
nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
- err = cfg80211_validate_beacon_int(rdev, setup.beacon_interval);
+ err = cfg80211_validate_beacon_int(rdev, NL80211_IFTYPE_MESH_POINT,
+ setup.beacon_interval);
if (err)
return err;
}
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 0675f51..a8f0171 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -1553,20 +1553,52 @@ bool ieee80211_chandef_to_operating_class(struct cfg80211_chan_def *chandef,
}
EXPORT_SYMBOL(ieee80211_chandef_to_operating_class);
+struct diff_beacon_int {
+ u32 beacon_int;
+ bool valid;
+};
+
+static void
+cfg80211_validate_diff_beacon_int(const struct ieee80211_iface_combination *c,
+ void *data)
+{
+ struct diff_beacon_int *diff_bi = data;
+
+ if (c->diff_beacon_int_gcd &&
+ !(diff_bi->beacon_int % c->diff_beacon_int_gcd))
+ diff_bi->valid = true;
+}
+
int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev,
- u32 beacon_int)
+ enum nl80211_iftype iftype, u32 beacon_int)
{
struct wireless_dev *wdev;
int res = 0;
+ int iftype_num[NUM_NL80211_IFTYPES];
if (beacon_int < 10 || beacon_int > 10000)
return -EINVAL;
+ memset(iftype_num, 0, sizeof(iftype_num));
+ list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
+ if (!wdev->beacon_interval)
+ continue;
+ iftype_num[wdev->iftype]++;
+ }
+ iftype_num[iftype]++;
+
list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
if (!wdev->beacon_interval)
continue;
if (wdev->beacon_interval != beacon_int) {
- res = -EINVAL;
+ struct diff_beacon_int diff_bi = { beacon_int, false };
+
+ res = cfg80211_iter_combinations(&rdev->wiphy, 0, 0, iftype_num,
+ cfg80211_validate_diff_beacon_int,
+ &diff_bi);
+ if (res)
+ return res;
+ res = (diff_bi.valid) ? 0 : -EINVAL;
break;
}
}
--
1.9.1
^ permalink raw reply related
* Re: Problems with mwifiex_pcie firmware activation
From: Stanislaw Gruszka @ 2016-08-12 8:13 UTC (permalink / raw)
To: Amitkumar Karwar; +Cc: Nishant Sarmukadam, linux-wireless@vger.kernel.org
In-Reply-To: <fc70c75bfcab4e0e932274034b5b4493@SC-EXCH04.marvell.com>
On Fri, Aug 12, 2016 at 07:17:38AM +0000, Amitkumar Karwar wrote:
> The problem looks strange. The patch just splits mwifiex_check_fw_status() and increases poll count. It should not have any side-effects.
> Our code used to check winner status before this patch also.
Ok, I misread the patch. Anyway checking "winner status" seems
does not work well on some condition and prevent loading firmware
into device.
Stanislaw
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox