Re: [RFC PATCH v2 0/2] Extended Key ID support for linux

2018-12-08 Thread Alexander Wetzel




I got the impression Extended Key IDs were  added without updating all
sections which should get updates. But the pattern is suspect, even the igtk
numbers fit into the pattern:

  PTK 0 & 1
  GTK 1 & 2 & 3
iGTK 4 & 5


An AP is allowed to do this, but there is no requirement for doing so.
The pairwise key (TK, not PTK) is required to use Key ID 0 unless the > 
optional Extended Key ID for Individually Addressed Frames capability is
negotiated (and 0 or 1 if that capability is negotiated). Group keys
(GTK) are allowed to use Key IDs 0..4. IGTKs are allowed to use Key ID
values 4 and 5.

There is a long history behind this and some de facto constraints due to
that history and possible implementation constraints. However, as far as
the protocol itself is concerned, there would be no real need for having
IGTK use 4..5; it could have as well been 0..1 or 1..2 or whatever
combination the AP would like to use.

These three cases have completely independent namespaces for Key IDs as
far as RSN is concerned with one exception: "Use group cipher suite"
that was added as an option for some AP implementation that did not
support individual key mapping. That special case would end up using GTK
for both group-addressed and individually-addressed frames. That said,
I'm not aware of there having ever been an actually deployed device with
this constraint and even if there were, this mode is highly discouraged
and should not be used for anything today. Anyway, this exception and
similar implementation constraints are likely behind the expectations of
TK and GTK having to use different Key ID values.


Thanks for the clarifications!
If there really are drivers using "Use group cipher suite" it does not 
sound like they would be able to support Extended Key ID with APs using 
key ID 1+2 for GTKs. But sounds not likely anyone would need that...


My experimentation with hw accel and Extended Key ID for existing 
drivers so far are also indicating that it will work using the keyid 1 
for both PTK and GTK, so this should be a trivial change in hostapd only.




As far as the kernel changes are concerned, cfg80211 and mac80211 should
support everything that's allowed by the standard, i.e., use of Key IDs
0..3 for GTK. It is up to the user space implementation on the AP side
(e.g., hostapd) to select which Key IDs are actually taken into use.



I'm pretty sure that is already the case, but so far I only tested it 
with GTK shifted to 2+3. I'll make sure to test the next revision with 
GTK using 1+2 also. I'll test that once I get that working again from 
end2end. The patch here is getting a bit dated and makes no sense to 
invest time for that win it.


Alexander


Re: [PATCH 2/5] mt76x02: fixup MT_PROT_RATE_* defines

2018-12-08 Thread Lorenzo Bianconi
>
> On new mt76 chips, phy mode is configured by last 3 bits
> of rate value. Hence OFDM bit is marked by 0x2000
> instead of 0x4000.
>
> Signed-off-by: Stanislaw Gruszka 
> ---
>  drivers/net/wireless/mediatek/mt76/mt76x02_regs.h | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_regs.h 
> b/drivers/net/wireless/mediatek/mt76/mt76x02_regs.h
> index f7de77d09d28..d1ac847adce5 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76x02_regs.h
> +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_regs.h
> @@ -440,9 +440,9 @@
>  #define MT_PROT_TXOP_ALLOW_GF40BIT(25)
>  #define MT_PROT_RTS_THR_EN BIT(26)
>  #define MT_PROT_RATE_CCK_110x0003
> -#define MT_PROT_RATE_OFDM_60x4000
> -#define MT_PROT_RATE_OFDM_24   0x4004
> -#define MT_PROT_RATE_DUP_OFDM_24   0x4084
> +#define MT_PROT_RATE_OFDM_60x2000
> +#define MT_PROT_RATE_OFDM_24   0x2004
> +#define MT_PROT_RATE_DUP_OFDM_24   0x2084
>  #define MT_PROT_TXOP_ALLOW_ALL GENMASK(25, 20)
>  #define MT_PROT_TXOP_ALLOW_BW20(MT_PROT_TXOP_ALLOW_ALL & 
>   \
>  ~MT_PROT_TXOP_ALLOW_MM40 & \
> --
> 1.9.3
>

Acked-by: Lorenzo Bianconi 


Re: [PATCH 5/5] mt76x2: initialize fall-back rate registers

2018-12-08 Thread Lorenzo Bianconi
>
> Initialize MT_LG_FBK_CFG{0,1} and MT_VHT_HT_FBK_CFG{0,1} registers.
>
> Signed-off-by: Stanislaw Gruszka 
> ---
>  drivers/net/wireless/mediatek/mt76/mt76x0/initvals.h | 4 
>  1 file changed, 4 insertions(+)
>
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/initvals.h 
> b/drivers/net/wireless/mediatek/mt76/mt76x0/initvals.h
> index a1657922758e..01e672bad2f1 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76x0/initvals.h
> +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/initvals.h
> @@ -88,6 +88,10 @@
> { MT_TX_PROT_CFG6,  0xe3f42004 },
> { MT_TX_PROT_CFG7,  0xe3f42084 },
> { MT_TX_PROT_CFG8,  0xe3f42104 },
> +   { MT_VHT_HT_FBK_CFG0,   0x65432100 },
> +   { MT_VHT_HT_FBK_CFG1,   0xedcba980 },
> +   { MT_LG_FBK_CFG0,   0xedcba988 },
> +   { MT_LG_FBK_CFG1,   0x00872100 },
>  };
>

as for mt76x2 patch (except  MT_VHT_HT_FBK_CFG1) MT_VHT_HT_FBK_CFG0,
MT_LG_FBK_CFG{0,1} are default values
(at least for mt7610e, I will double-check for mt7610u)

Regards,
Lorenzo

>  static const struct mt76_reg_pair mt76x0_bbp_init_tab[] = {
> --
> 1.9.3
>


Re: [PATCH 4/5] mt76x2: initialize fall-back rate registers

2018-12-08 Thread Lorenzo Bianconi
>
> Initialize MT_LG_FBK_CFG{0,1} and MT_VHT_HT_FBK_CFG0 registers.
> MT_VHT_HT_FBK_CFG1 was already configured.
>
> Signed-off-by: Stanislaw Gruszka 
> ---
>  drivers/net/wireless/mediatek/mt76/mt76x2/init.c | 3 +++
>  1 file changed, 3 insertions(+)
>
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/init.c 
> b/drivers/net/wireless/mediatek/mt76/mt76x2/init.c
> index 54a9b5fac787..16fd514b5207 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76x2/init.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt76x2/init.c
> @@ -140,7 +140,10 @@ void mt76_write_mac_initvals(struct mt76x02_dev *dev)
> { MT_WPDMA_DELAY_INT_CFG,   0x94ff },
> { MT_TX_SW_CFG3,0x0004 },
> { MT_HT_FBK_TO_LEGACY,  0x1818 },
> +   { MT_VHT_HT_FBK_CFG0,   0x65432100 },
> { MT_VHT_HT_FBK_CFG1,   0xedcba980 },
> +   { MT_LG_FBK_CFG0,   0xedcba988 },
> +   { MT_LG_FBK_CFG1,   0x87872100 },
> { MT_PROT_AUTO_TX_CFG,  0x00830083 },
> { MT_HT_CTRL_CFG,   0x01ff },
> };

I do not think this patch is necessary since these value are default ones:

root@lede:/sys/kernel/debug/ieee80211/phy0/mt76# echo 0x1354 > regidx
root@lede:/sys/kernel/debug/ieee80211/phy0/mt76# cat regval
0x65432100
root@lede:/sys/kernel/debug/ieee80211/phy0/mt76# echo 0x135c > regidx
root@lede:/sys/kernel/debug/ieee80211/phy0/mt76# cat regval
0xedcba988
root@lede:/sys/kernel/debug/ieee80211/phy0/mt76# echo 0x1360 > regidx
root@lede:/sys/kernel/debug/ieee80211/phy0/mt76# cat regval
0x87872100

Regards,
Lorenzo

> --
> 1.9.3
>


Re: [PATCH 1/5] mt76x02: do not set protection on set_rts_threshold callback

2018-12-08 Thread Lorenzo Bianconi
On Fri, Dec 7, 2018 at 2:27 PM Stanislaw Gruszka  wrote:
>
> Use set_rts_threshold calback to enable/disable threshold only for
> legacy traffic.
>
> Protection for HT and VHT traffic is defined by HT operation element
> and it's provided by remote AP or by hostapd.
>
> Signed-off-by: Stanislaw Gruszka 
> ---
>  drivers/net/wireless/mediatek/mt76/mt76x02_mac.c  | 16 +---
>  drivers/net/wireless/mediatek/mt76/mt76x02_mac.h  |  2 +-
>  drivers/net/wireless/mediatek/mt76/mt76x02_util.c |  2 +-
>  3 files changed, 3 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c 
> b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
> index c08bf371e527..9693d6140b3d 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
> @@ -715,7 +715,7 @@ void mt76x02_tx_complete_skb(struct mt76_dev *mdev, 
> struct mt76_queue *q,
>  }
>  EXPORT_SYMBOL_GPL(mt76x02_tx_complete_skb);
>

[...]

> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c 
> b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
> index 3a70e5bf7d42..e7ee2cc76edf 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
> @@ -463,7 +463,7 @@ int mt76x02_set_rts_threshold(struct ieee80211_hw *hw, 
> u32 val)
> return -EINVAL;
>
> mutex_lock(>mutex);
> -   mt76x02_mac_set_tx_protection(dev, val);
> +   mt76x02_mac_set_rts_thresh(dev, val);
> mutex_unlock(>mutex);

I think this patch will not apply since I have recently fixed an
uninitialized mutex access setting rts threshold
1770f0fa978e ("mt76: fix uninitialized mutex access setting rts
threshold"). That patch is in Kalle's pending branch
now. You should probably respin on top of it.

Regards,
Lorenzo

>
> return 0;
> --
> 1.9.3
>


Re: [EXT] Re: [PATCH] mwifiex: fix nested rtnl locking on BG_SCAN_STOPPED

2018-12-07 Thread Brian Norris
Hi Ganapathi,

For some reason, I'm daft enough to reply to this ancient thread. It
appears as if you probably have not resolved this issue yet though, so
I figured I could lend some advice.

On Wed, Apr 25, 2018 at 1:06 AM Ganapathi Bhat  wrote:
> > Ganapathi Bhat  writes:
> > > --- a/drivers/net/wireless/marvell/mwifiex/sta_event.c
> > > +++ b/drivers/net/wireless/marvell/mwifiex/sta_event.c
> > > @@ -848,7 +848,10 @@ int mwifiex_process_sta_event(struct
> > > mwifiex_private *priv)
> > >
> > > case EVENT_BG_SCAN_STOPPED:
> > > dev_dbg(adapter->dev, "event: BGS_STOPPED\n");
> > > -   cfg80211_sched_scan_stopped(priv->wdev.wiphy, 0);
> > > +   if (rtnl_is_locked())
> > > +   cfg80211_sched_scan_stopped_rtnl(priv-
> > >wdev.wiphy, 0);
> > > +   else
> > > +   cfg80211_sched_scan_stopped(priv->wdev.wiphy,
> > 0);
> >
> > IMHO checking if a lock is taking is rather ugly and an indication there's a
> > problem with the locking. Instead making an ugly workaround like this I
> > would rather investigate who is holding the rtnl and solve that.

Agreed, this is not good. You are now bound to hit ASSERT_RTNL()
warnings occasionally, since you might see rtnl locked here, but a
split second later, when you're running in
__cfg80211_stop_sched_scan(), it could be released by some other
thread.

> There can be applications trying to access driver(via cfg80211), holding 
> rtnl_lock.
> For example(in our case):
> 1. "iw dev"  was called, when BG_SCAN was active.
> 2. NL80211_CMD_GET_INTERFACE requires rtnl_lock to be hold(specified in 
> internal_flags)
> 3. cfg80211 will  hold rtnl_lock before calling "get_tx_power"(in pre_doit).
> 4. mwifiex will download RF_TX_PWR command to firmware
> 5. firmware will send BG_SCAN_STOPPED event(since BG_SCAN was active).
> 6. mwifiex will call "cfg80211_sched_scan_stopped" causing nested rtnl 
> locking.

IIUC, it's not exactly a nested lock, but a lock inversion issue.

#1
NL80211_CMD_GET_INTERFACE thread is holding rtnl lock and later
waiting on one of its HostCmd_CMD_* to complete

In the meantime:
#2
a EVENT_BG_SCAN_STOPPED is queued, and it grabs the rtnl lock

Because events are served on the same thread as commands, you get #1
waiting on #2, which is waiting on the lock held in #1. i.e., ABBA.

The way to resolve this is to either move event processing to a
different thread than command processing (that looks it would be very
difficult to do correctly, given the ossified structure of your
driver; but that might be a wise move in the long term)...
...or else maybe you could defer this specific piece of work to its
own thread. That might require yet another workqueue?

Anyway, the key point is that you really don't want to hold rtnl_lock
in your main workqueue, or in any other way that might block the rest
of the operation of your driver.

Brian


Re: [PATCH 2/5] cfg80211: Properly track transmitting and non-transmitting BSS

2018-12-07 Thread kbuild test robot
Hi Sara,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on mac80211-next/master]
[also build test ERROR on v4.20-rc5 next-20181207]
[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/Jouni-Malinen/cfg80211-Parsing-of-Multiple-BSSID-information-in-scanning/20181208-040803
base:   https://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git 
master
config: i386-randconfig-x011-201848 (attached as .config)
compiler: gcc-7 (Debian 7.3.0-1) 7.3.0
reproduce:
# save the attached .config to linux build tree
make ARCH=i386 

All errors (new ones prefixed by >>):

   In file included from net/wireless/nl80211.h:9:0,
from net/wireless/ibss.c:14:
   net/wireless/core.h: In function 'cfg80211_hold_bss':
>> net/wireless/core.h:184:20: error: inlining failed in call to always_inline 
>> 'cfg80211_hold_bss': recursive inlining
static inline void cfg80211_hold_bss(struct cfg80211_internal_bss *bss)
   ^
   net/wireless/core.h:188:3: note: called from here
  cfg80211_hold_bss(container_of(bss->transmitted_bss,
  ^~~~
struct cfg80211_internal_bss,
~
pub));
~
   net/wireless/core.h: In function 'cfg80211_unhold_bss':
>> net/wireless/core.h:193:20: error: inlining failed in call to always_inline 
>> 'cfg80211_unhold_bss': recursive inlining
static inline void cfg80211_unhold_bss(struct cfg80211_internal_bss *bss)
   ^~~
   net/wireless/core.h:198:3: note: called from here
  cfg80211_unhold_bss(container_of(bss->transmitted_bss,
  ^~
   struct cfg80211_internal_bss,
   ~
   pub));
   ~
   net/wireless/core.h: In function '__cfg80211_clear_ibss.constprop':
>> net/wireless/core.h:193:20: error: inlining failed in call to always_inline 
>> 'cfg80211_unhold_bss': recursive inlining
static inline void cfg80211_unhold_bss(struct cfg80211_internal_bss *bss)
   ^~~
   net/wireless/core.h:198:3: note: called from here
  cfg80211_unhold_bss(container_of(bss->transmitted_bss,
  ^~
   struct cfg80211_internal_bss,
   ~
   pub));
   ~
   net/wireless/core.h: In function '__cfg80211_ibss_joined':
>> net/wireless/core.h:193:20: error: inlining failed in call to always_inline 
>> 'cfg80211_unhold_bss': recursive inlining
static inline void cfg80211_unhold_bss(struct cfg80211_internal_bss *bss)
   ^~~
   net/wireless/core.h:198:3: note: called from here
  cfg80211_unhold_bss(container_of(bss->transmitted_bss,
  ^~
   struct cfg80211_internal_bss,
   ~
   pub));
   ~
>> net/wireless/core.h:184:20: error: inlining failed in call to always_inline 
>> 'cfg80211_hold_bss': recursive inlining
static inline void cfg80211_hold_bss(struct cfg80211_internal_bss *bss)
   ^
   net/wireless/core.h:188:3: note: called from here
  cfg80211_hold_bss(container_of(bss->transmitted_bss,
  ^~~~
struct cfg80211_internal_bss,
~
pub));
~
--
   In file included from net/wireless/nl80211.h:9:0,
from net/wireless/sme.c:21:
   net/wireless/core.h: In function 'cfg80211_hold_bss':
>> net/wireless/core.h:184:20: error: inlining failed in call to always_inline 
>> 'cfg80211_hold_bss': recursive inlining
static inline void cfg80211_hold_bss(struct cfg80211_internal_bss *bss)
   ^
   net/wireless/core.h:188:3: note: called from here
  cfg80211_hold_bss(container_of(bss->transmitted_bss,
  ^~~~
struct cfg80211_internal_bss,
~
pub));
~
   net/wireless/core.h: In function 'cfg80211_unhold_bss':
>> net/wireless/core.h:193:20: error: inlining failed in call to always_inline 
>> 'cfg80211_unhold_bss': recursive inlining
static inline void cfg80211_unhold_bss(struct cfg80211_internal_bss *bss)
   ^~~
   net/wireless/core.h:198:3: note: called from here
  cfg80211_unhold_bss(container_of(bss->transmitted_bss,
  ^~
   struct 

Urgently need money? We can help you!

2018-12-07 Thread Mr. Muller Dieter
Urgently need money? We can help you!
Are you by the current situation in trouble or threatens you in trouble?
In this way, we give you the ability to take a new development.
As a rich person I feel obliged to assist people who are struggling to give 
them a chance. Everyone deserved a second chance and since the Government 
fails, it will have to come from others.
No amount is too crazy for us and the maturity we determine by mutual agreement.
No surprises, no extra costs, but just the agreed amounts and nothing else.
Don't wait any longer and comment on this post. Please specify the amount you 
want to borrow and we will contact you with all the possibilities. contact us 
today at stewarrt.l...@gmail.com


[PATCH 5/5] mt76x2: initialize fall-back rate registers

2018-12-07 Thread Stanislaw Gruszka
Initialize MT_LG_FBK_CFG{0,1} and MT_VHT_HT_FBK_CFG{0,1} registers.

Signed-off-by: Stanislaw Gruszka 
---
 drivers/net/wireless/mediatek/mt76/mt76x0/initvals.h | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/initvals.h 
b/drivers/net/wireless/mediatek/mt76/mt76x0/initvals.h
index a1657922758e..01e672bad2f1 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/initvals.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/initvals.h
@@ -88,6 +88,10 @@
{ MT_TX_PROT_CFG6,  0xe3f42004 },
{ MT_TX_PROT_CFG7,  0xe3f42084 },
{ MT_TX_PROT_CFG8,  0xe3f42104 },
+   { MT_VHT_HT_FBK_CFG0,   0x65432100 },
+   { MT_VHT_HT_FBK_CFG1,   0xedcba980 },
+   { MT_LG_FBK_CFG0,   0xedcba988 },
+   { MT_LG_FBK_CFG1,   0x00872100 },
 };
 
 static const struct mt76_reg_pair mt76x0_bbp_init_tab[] = {
-- 
1.9.3



[PATCH 4/5] mt76x2: initialize fall-back rate registers

2018-12-07 Thread Stanislaw Gruszka
Initialize MT_LG_FBK_CFG{0,1} and MT_VHT_HT_FBK_CFG0 registers.
MT_VHT_HT_FBK_CFG1 was already configured.

Signed-off-by: Stanislaw Gruszka 
---
 drivers/net/wireless/mediatek/mt76/mt76x2/init.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/init.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2/init.c
index 54a9b5fac787..16fd514b5207 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/init.c
@@ -140,7 +140,10 @@ void mt76_write_mac_initvals(struct mt76x02_dev *dev)
{ MT_WPDMA_DELAY_INT_CFG,   0x94ff },
{ MT_TX_SW_CFG3,0x0004 },
{ MT_HT_FBK_TO_LEGACY,  0x1818 },
+   { MT_VHT_HT_FBK_CFG0,   0x65432100 },
{ MT_VHT_HT_FBK_CFG1,   0xedcba980 },
+   { MT_LG_FBK_CFG0,   0xedcba988 },
+   { MT_LG_FBK_CFG1,   0x87872100 },
{ MT_PROT_AUTO_TX_CFG,  0x00830083 },
{ MT_HT_CTRL_CFG,   0x01ff },
};
-- 
1.9.3



[PATCH 3/5] mt76x02: set protection according to ht operation element

2018-12-07 Thread Stanislaw Gruszka
Configure protection based on information that are provided to
us either by remote AP or by hostapd via HT operation IE.

Signed-off-by: Stanislaw Gruszka 
---
 drivers/net/wireless/mediatek/mt76/mt76x02_mac.c  | 83 +++
 drivers/net/wireless/mediatek/mt76/mt76x02_mac.h  |  2 +
 drivers/net/wireless/mediatek/mt76/mt76x02_regs.h |  1 +
 drivers/net/wireless/mediatek/mt76/mt76x02_util.c |  4 ++
 4 files changed, 90 insertions(+)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
index 9693d6140b3d..3fc7a722ea53 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
@@ -731,6 +731,89 @@ void mt76x02_mac_set_rts_thresh(struct mt76x02_dev *dev, 
u32 val)
 MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);
 }
 
+void mt76x02_mac_set_tx_protection(struct mt76x02_dev *dev, bool legacy_prot,
+  int ht_mode)
+{
+   int mode = ht_mode & IEEE80211_HT_OP_MODE_PROTECTION;
+   bool non_gf = !!(ht_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
+   u32 prot[6];
+   u32 vht_prot[3];
+   int i;
+   u16 rts_thr;
+
+   for (i = 0; i < ARRAY_SIZE(prot); i++) {
+   prot[i] = mt76_rr(dev, MT_CCK_PROT_CFG + i * 4);
+   prot[i] &= ~MT_PROT_CFG_CTRL;
+   if (i >= 2)
+   prot[i] &= ~MT_PROT_CFG_RATE;
+   }
+
+   for (i = 0; i < ARRAY_SIZE(vht_prot); i++) {
+   vht_prot[i] = mt76_rr(dev, MT_TX_PROT_CFG6 + i * 4);
+   vht_prot[i] &= ~(MT_PROT_CFG_CTRL | MT_PROT_CFG_RATE);
+   }
+
+   rts_thr = mt76_get_field(dev, MT_TX_RTS_CFG, MT_TX_RTS_CFG_THRESH);
+
+   if (rts_thr != 0x)
+   prot[0] |= MT_PROT_CTRL_RTS_CTS;
+
+   if (legacy_prot) {
+   prot[1] |= MT_PROT_CTRL_CTS2SELF;
+
+   prot[2] |= MT_PROT_RATE_CCK_11;
+   prot[3] |= MT_PROT_RATE_CCK_11;
+   prot[4] |= MT_PROT_RATE_CCK_11;
+   prot[5] |= MT_PROT_RATE_CCK_11;
+
+   vht_prot[0] |= MT_PROT_RATE_CCK_11;
+   vht_prot[1] |= MT_PROT_RATE_CCK_11;
+   vht_prot[2] |= MT_PROT_RATE_CCK_11;
+   } else {
+   if (rts_thr != 0x)
+   prot[1] |= MT_PROT_CTRL_RTS_CTS;
+
+   prot[2] |= MT_PROT_RATE_OFDM_24;
+   prot[3] |= MT_PROT_RATE_DUP_OFDM_24;
+   prot[4] |= MT_PROT_RATE_OFDM_24;
+   prot[5] |= MT_PROT_RATE_DUP_OFDM_24;
+
+   vht_prot[0] |= MT_PROT_RATE_OFDM_24;
+   vht_prot[1] |= MT_PROT_RATE_DUP_OFDM_24;
+   vht_prot[2] |= MT_PROT_RATE_SGI_OFDM_24;
+   }
+
+   switch (mode) {
+   case IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER:
+   case IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED:
+   prot[2] |= MT_PROT_CTRL_RTS_CTS;
+   prot[3] |= MT_PROT_CTRL_RTS_CTS;
+   prot[4] |= MT_PROT_CTRL_RTS_CTS;
+   prot[5] |= MT_PROT_CTRL_RTS_CTS;
+   vht_prot[0] |= MT_PROT_CTRL_RTS_CTS;
+   vht_prot[1] |= MT_PROT_CTRL_RTS_CTS;
+   vht_prot[2] |= MT_PROT_CTRL_RTS_CTS;
+   break;
+   case IEEE80211_HT_OP_MODE_PROTECTION_20MHZ:
+   prot[3] |= MT_PROT_CTRL_RTS_CTS;
+   prot[5] |= MT_PROT_CTRL_RTS_CTS;
+   vht_prot[1] |= MT_PROT_CTRL_RTS_CTS;
+   vht_prot[2] |= MT_PROT_CTRL_RTS_CTS;
+   break;
+   }
+
+   if (non_gf) {
+   prot[4] |= MT_PROT_CTRL_RTS_CTS;
+   prot[5] |= MT_PROT_CTRL_RTS_CTS;
+   }
+
+   for (i = 0; i < ARRAY_SIZE(prot); i++)
+   mt76_wr(dev, MT_CCK_PROT_CFG + i * 4, prot[i]);
+
+   for (i = 0; i < ARRAY_SIZE(vht_prot); i++)
+   mt76_wr(dev, MT_TX_PROT_CFG6 + i * 4, vht_prot[i]);
+}
+
 void mt76x02_update_channel(struct mt76_dev *mdev)
 {
struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev, mt76);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h 
b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h
index d1a8ed171537..91c76a050f7e 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h
@@ -194,6 +194,8 @@ void mt76x02_send_tx_status(struct mt76x02_dev *dev,
struct mt76x02_tx_status *stat, u8 *update);
 int mt76x02_mac_process_rx(struct mt76x02_dev *dev, struct sk_buff *skb,
   void *rxi);
+void mt76x02_mac_set_tx_protection(struct mt76x02_dev *dev, bool legacy_prot,
+  int ht_mode);
 void mt76x02_mac_set_rts_thresh(struct mt76x02_dev *dev, u32 val);
 void mt76x02_mac_setaddr(struct mt76x02_dev *dev, u8 *addr);
 void mt76x02_mac_write_txwi(struct mt76x02_dev *dev, struct mt76x02_txwi *txwi,
diff --git 

[PATCH 1/5] mt76x02: do not set protection on set_rts_threshold callback

2018-12-07 Thread Stanislaw Gruszka
Use set_rts_threshold calback to enable/disable threshold only for
legacy traffic.

Protection for HT and VHT traffic is defined by HT operation element
and it's provided by remote AP or by hostapd.

Signed-off-by: Stanislaw Gruszka 
---
 drivers/net/wireless/mediatek/mt76/mt76x02_mac.c  | 16 +---
 drivers/net/wireless/mediatek/mt76/mt76x02_mac.h  |  2 +-
 drivers/net/wireless/mediatek/mt76/mt76x02_util.c |  2 +-
 3 files changed, 3 insertions(+), 17 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
index c08bf371e527..9693d6140b3d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
@@ -715,7 +715,7 @@ void mt76x02_tx_complete_skb(struct mt76_dev *mdev, struct 
mt76_queue *q,
 }
 EXPORT_SYMBOL_GPL(mt76x02_tx_complete_skb);
 
-void mt76x02_mac_set_tx_protection(struct mt76x02_dev *dev, u32 val)
+void mt76x02_mac_set_rts_thresh(struct mt76x02_dev *dev, u32 val)
 {
u32 data = 0;
 
@@ -729,20 +729,6 @@ void mt76x02_mac_set_tx_protection(struct mt76x02_dev 
*dev, u32 val)
 MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);
mt76_rmw(dev, MT_OFDM_PROT_CFG,
 MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);
-   mt76_rmw(dev, MT_MM20_PROT_CFG,
-MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);
-   mt76_rmw(dev, MT_MM40_PROT_CFG,
-MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);
-   mt76_rmw(dev, MT_GF20_PROT_CFG,
-MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);
-   mt76_rmw(dev, MT_GF40_PROT_CFG,
-MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);
-   mt76_rmw(dev, MT_TX_PROT_CFG6,
-MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);
-   mt76_rmw(dev, MT_TX_PROT_CFG7,
-MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);
-   mt76_rmw(dev, MT_TX_PROT_CFG8,
-MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);
 }
 
 void mt76x02_update_channel(struct mt76_dev *mdev)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h 
b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h
index 4e597004c445..d1a8ed171537 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h
@@ -194,7 +194,7 @@ void mt76x02_send_tx_status(struct mt76x02_dev *dev,
struct mt76x02_tx_status *stat, u8 *update);
 int mt76x02_mac_process_rx(struct mt76x02_dev *dev, struct sk_buff *skb,
   void *rxi);
-void mt76x02_mac_set_tx_protection(struct mt76x02_dev *dev, u32 val);
+void mt76x02_mac_set_rts_thresh(struct mt76x02_dev *dev, u32 val);
 void mt76x02_mac_setaddr(struct mt76x02_dev *dev, u8 *addr);
 void mt76x02_mac_write_txwi(struct mt76x02_dev *dev, struct mt76x02_txwi *txwi,
struct sk_buff *skb, struct mt76_wcid *wcid,
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
index 3a70e5bf7d42..e7ee2cc76edf 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
@@ -463,7 +463,7 @@ int mt76x02_set_rts_threshold(struct ieee80211_hw *hw, u32 
val)
return -EINVAL;
 
mutex_lock(>mutex);
-   mt76x02_mac_set_tx_protection(dev, val);
+   mt76x02_mac_set_rts_thresh(dev, val);
mutex_unlock(>mutex);
 
return 0;
-- 
1.9.3



[PATCH 2/5] mt76x02: fixup MT_PROT_RATE_* defines

2018-12-07 Thread Stanislaw Gruszka
On new mt76 chips, phy mode is configured by last 3 bits
of rate value. Hence OFDM bit is marked by 0x2000
instead of 0x4000.

Signed-off-by: Stanislaw Gruszka 
---
 drivers/net/wireless/mediatek/mt76/mt76x02_regs.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_regs.h 
b/drivers/net/wireless/mediatek/mt76/mt76x02_regs.h
index f7de77d09d28..d1ac847adce5 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_regs.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_regs.h
@@ -440,9 +440,9 @@
 #define MT_PROT_TXOP_ALLOW_GF40BIT(25)
 #define MT_PROT_RTS_THR_EN BIT(26)
 #define MT_PROT_RATE_CCK_110x0003
-#define MT_PROT_RATE_OFDM_60x4000
-#define MT_PROT_RATE_OFDM_24   0x4004
-#define MT_PROT_RATE_DUP_OFDM_24   0x4084
+#define MT_PROT_RATE_OFDM_60x2000
+#define MT_PROT_RATE_OFDM_24   0x2004
+#define MT_PROT_RATE_DUP_OFDM_24   0x2084
 #define MT_PROT_TXOP_ALLOW_ALL GENMASK(25, 20)
 #define MT_PROT_TXOP_ALLOW_BW20(MT_PROT_TXOP_ALLOW_ALL &   
\
 ~MT_PROT_TXOP_ALLOW_MM40 & \
-- 
1.9.3



Re: [RFC/RFT 1/4] mt76x02: configure basic rates and fallback on STA mode

2018-12-07 Thread Stanislaw Gruszka
On Thu, Nov 08, 2018 at 05:02:14PM +0100, Felix Fietkau wrote:
> >> > +   if (changed & BSS_CHANGED_BASIC_RATES &&
> >> > +   vif->type == NL80211_IFTYPE_STATION) {
> >> > +   mt76_wr(dev, MT_LEGACY_BASIC_RATE, info->basic_rates);

It's a bit hard to interpret how vendor driver set LEGACY_BIT_RATE
in MlmeUpdateTxRates(). It seems to always enable bits for
OFDM6/OFDM12/OFDM24 (bitmask 0x150) or maybe just do this for 5GHz,
I'm not sure. Need more investigation on this.
 
> >> > +   mt76_wr(dev, MT_VHT_HT_FBK_CFG0, 0x65432100);
> >> > +   mt76_wr(dev, MT_VHT_HT_FBK_CFG1, 0xedcba980);
> >> > +   mt76_wr(dev, MT_LG_FBK_CFG0, 0xedcba988);
> >> > +   if (is_mt76x2(dev))
> >> > +   mt76_wr(dev, MT_LG_FBK_CFG1, 0x87872100);
> >> > +   else
> >> > +   mt76_wr(dev, MT_LG_FBK_CFG1, 0x00872100);
> >> > +   }
> >> > +
> >> 
> >> since these values are constant, why not put them init_vals?
> > 
> > I wanted them to be used only in STA mode like vendor driver does.
> > However if we will have AP+STA , we still will configure them,
> > so better to configure them anyway and put in init_vals .
> Yes, I think we should put them in initvals. Also, I think we should
> keep the values the shared between mt76x0 and mt76x2.
> 
> For MT_LG_FBK_CFG1 there is no need to make a distinction between 76x2
> and 76x0, because 76x0 will simply ignore the upper values (they apply
> to 2SS transmission only).
> Also, I don't think MT_VHT_HT_FBK_CFG1 even gets used on mt76x0, because
> it is for 2SS rates only. However, the value in there seems more useful
> than the one we currently use on mt76x2, because it allows fallback from
> 2SS MCS0 to 1SS MCS0.
> The contents of MT_LG_FBK_CFG0 also match the default initialization
> values documented in the 7612E datasheet.
> 
> I don't think there is any meaningful difference between the 76x2 and
> the 76x0 MAC except for the missing 2SS support.

Since there are different initvals tables for mt76x2 and mt76x0, I use
different values of MT_LG_FBK_CFG1. Will post a patches soon, please
comment there, if something is not correct.

Thanks
Stanislaw


Can't connect to WPA(2)-EAP network (eduroam / TTLS) with iwlwifi (9260 - and some others) ~90% of the time with 4.17.16 through 4.19.7 at least

2018-12-07 Thread Ferry
Hi,

I have a Dell XPS 15 9550 in which I replaced the wireless Broadcom
adapter with an Intel 9260.

So far I have not encountered any issues whatsoever with WPA(2)-PSK
networks, but I do have issues connecting to WPA(2)-EAP networks (at
least eduroam here, which uses TTLS / MSCHAPv2), which I did not have
with the Broadcom 43602 originally in the system).

On this machine I run gentoo linux (~amd64) with KDE/plasma. That said,
we've seen similar issues (they appear identical even though other model
Intel AC adapters) with several other machines containing Intel AC
adapters on Fedora 28 with various kernel releases as well when trying
to connect to the same network / with same credentials. Unfortunately I
don't have the modelnumbers at hand. The issues seem to have been around
for a while. On one of the other machines the issues did not occur with
a 4.16 kernel (think I tested with 4.16.16 then).

The issue is not consistent. That is, every 1 or 2 out of 10 boots,
it'll will just work. This does seem to be somewhat hardware related, on
my machine it mostly does not work, on some others we see different
numbers, some mostly work but show the same behavious on occasion. The
messages below don't appear in the logs when it does work.

In both cases (gentoo / fedora) NetworkManager is used to connect to the
network.

Hope someone can help resolve this. I can build kernels / apply patches
/ aid with debugging, but I'm not a developer.

Attached is dmesg from clean boot after several connection attempts.
Basically repeats the following quite a few times:

[   82.169103] BUG: scheduling while atomic: irq/124-iwlwifi/266/0x0400
[   82.169106] Modules linked in: dm_crypt algif_skcipher
x86_pkg_temp_thermal uvcvideo kvm_intel videobuf2_vmalloc
videobuf2_memops iwlmvm videobuf2_v4l2 kvm irqbypass crc32_pclmul
dell_smbios ghash_clmulni_intel intel_wmi_thunderbolt
dell_wmi_descriptor videodev hid_multitouch btusb btrtl iwlwifi
snd_hda_codec_hdmi videobuf2_common snd_hda_codec_realtek btbcm btintel
bluetooth intel_hid
[   82.169120] CPU: 2 PID: 266 Comm: irq/124-iwlwifi Tainted: G   
W 4.19.7-gentoo #1
[   82.169121] Hardware name: Dell Inc. XPS 15 9550/0N7TVV, BIOS 1.9.0
10/11/2018
[   82.169123] Call Trace:
[   82.169144]  dump_stack+0x46/0x60
[   82.169147]  __schedule_bug.cold.97+0x5/0x1d
[   82.169149]  __schedule+0x4f6/0x730
[   82.169151]  schedule+0x23/0x70
[   82.169153]  schedule_timeout+0x179/0x370
[   82.169156]  ? __next_timer_interrupt+0xc0/0xc0
[   82.169161]  iwl_trans_pcie_send_hcmd+0x316/0x550 [iwlwifi]
[   82.169163]  ? wait_woken+0x80/0x80
[   82.169166]  iwl_trans_send_cmd+0x59/0xc0 [iwlwifi]
[   82.169171]  iwl_mvm_send_cmd+0x1e/0x70 [iwlmvm]
[   82.169174]  ? rs_fill_lq_cmd+0x24b/0x3d0 [iwlmvm]
[   82.169177]  iwl_mvm_send_lq_cmd+0x6e/0x90 [iwlmvm]
[   82.169181]  iwl_mvm_rs_rate_init+0x913/0xcb0 [iwlmvm]
[   82.169184]  iwl_mvm_rs_tx_status+0x39d/0x1f80 [iwlmvm]
[   82.169186]  ? enqueue_task_fair+0x3fa/0xfb0
[   82.169188]  ? enqueue_task_fair+0x3fa/0xfb0
[   82.169190]  rate_control_tx_status+0x99/0xa0
[   82.169193]  __ieee80211_tx_status+0x3b5/0x7b0
[   82.169196]  ? iwl_trans_pcie_set_pmi+0x20/0x20 [iwlwifi]
[   82.169198]  ? sta_info_hash_lookup+0xe1/0x120
[   82.169200]  ieee80211_tx_status+0x7c/0xb0
[   82.169203]  iwl_mvm_rx_tx_cmd+0x2da/0x710 [iwlmvm]
[   82.169206]  ? iwl_pcie_gen2_tx_init+0x130/0x130 [iwlwifi]
[   82.169209]  iwl_pcie_rx_handle+0x276/0x9f0 [iwlwifi]
[   82.169211]  ? irq_forced_thread_fn+0x70/0x70
[   82.169213]  iwl_pcie_irq_rx_msix_handler+0x52/0xf0 [iwlwifi]
[   82.169215]  ? irq_forced_thread_fn+0x70/0x70
[   82.169216]  irq_thread_fn+0x1c/0x60
[   82.169218]  irq_thread+0xe2/0x160
[   82.169219]  ? wake_threads_waitq+0x30/0x30
[   82.169221]  ? irq_thread_dtor+0x80/0x80
[   82.169223]  kthread+0x10e/0x130
[   82.169225]  ? kthread_create_worker_on_cpu+0x60/0x60
[   82.169226]  ret_from_fork+0x35/0x40
[   84.175959] iwlwifi :02:00.0: Error sending LQ_CMD: time out
after 2000ms.
[   84.175963] iwlwifi :02:00.0: Current CMD queue read_ptr 146
write_ptr 147
[   84.176074] iwlwifi :02:00.0: Microcode SW error detected.
Restarting 0x1.
[   84.176102] iwlwifi :02:00.0: Loaded firmware version: 38.755cfdd8.0
[   84.176103] iwlwifi :02:00.0: 0x |
ADVANCED_SYSASSERT 
[   84.176105] iwlwifi :02:00.0: 0x | trm_hw_status0
[   84.176106] iwlwifi :02:00.0: 0x | trm_hw_status1
[   84.176120] iwlwifi :02:00.0: 0x | branchlink2
[   84.176121] iwlwifi :02:00.0: 0x0045E90E | interruptlink1
[   84.176123] iwlwifi :02:00.0: 0x0A42 | interruptlink2
[   84.176124] iwlwifi :02:00.0: 0x | data1
[   84.176125] iwlwifi :02:00.0: 0xFF00 | data2
[   84.176126] iwlwifi :02:00.0: 0xF008 | data3
[   84.176127] iwlwifi :02:00.0: 0x2241419C | beacon time
[   84.176128] iwlwifi :02:00.0: 0xB2A1AA66 | tsf low
[   84.176130] iwlwifi :02:00.0: 0x047D | tsf hi

[PATCH 1/5] cfg80211: Parsing of Multiple BSSID information in scanning

2018-12-07 Thread Jouni Malinen
From: Peng Xu 

This extends cfg80211 BSS table processing to be able to parse Multiple
BSSID element from Beacon and Probe Response frames and to update the
BSS profiles in internal database for non-transmitted BSSs.

Signed-off-by: Peng Xu 
Signed-off-by: Sara Sharon 
Signed-off-by: Johannes Berg 
Signed-off-by: Jouni Malinen 
---
 net/wireless/core.h |   1 +
 net/wireless/scan.c | 504 
 2 files changed, 466 insertions(+), 39 deletions(-)

diff --git a/net/wireless/core.h b/net/wireless/core.h
index c5d6f34..d58c56a 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -152,6 +152,7 @@ extern int cfg80211_rdev_list_generation;
 struct cfg80211_internal_bss {
struct list_head list;
struct list_head hidden_list;
+   struct list_head nontrans_list;
struct rb_node rbn;
u64 ts_boottime;
unsigned long ts;
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index d0e7472..559f56d 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -4,7 +4,7 @@
  *
  * Copyright 2008 Johannes Berg 
  * Copyright 2013-2014  Intel Mobile Communications GmbH
- * Copyright 2016  Intel Deutschland GmbH
+ * Copyright 2016-2017 Intel Deutschland GmbH
  */
 #include 
 #include 
@@ -150,6 +150,7 @@ static bool __cfg80211_unlink_bss(struct 
cfg80211_registered_device *rdev,
}
 
list_del_init(>list);
+   list_del_init(>nontrans_list);
rb_erase(>rbn, >bss_tree);
rdev->bss_entries--;
WARN_ONCE((rdev->bss_entries == 0) ^ list_empty(>bss_list),
@@ -159,6 +160,170 @@ static bool __cfg80211_unlink_bss(struct 
cfg80211_registered_device *rdev,
return true;
 }
 
+static void cfg80211_gen_new_bssid(const u8 *bssid, u8 max_bssid,
+  u8 mbssid_index, u8 *new_bssid_addr)
+{
+   u64 bssid_tmp, new_bssid = 0;
+   u64 lsb_n;
+
+   bssid_tmp = ether_addr_to_u64(bssid);
+
+   lsb_n = bssid_tmp & ((1 << max_bssid) - 1);
+   new_bssid = bssid_tmp;
+   new_bssid &= ~((1 << max_bssid) - 1);
+   new_bssid |= (lsb_n + mbssid_index) % (1 << max_bssid);
+
+   u64_to_ether_addr(new_bssid, new_bssid_addr);
+}
+
+static size_t cfg80211_gen_new_ie(const u8 *ie, size_t ielen,
+ const u8 *subelement, size_t subie_len,
+ u8 *new_ie, gfp_t gfp)
+{
+   u8 *pos, *tmp;
+   const u8 *tmp_old, *tmp_new;
+   u8 *sub_copy;
+
+   /* copy subelement as we need to change its content to
+* mark an ie after it is processed.
+*/
+   sub_copy = kmalloc(subie_len, gfp);
+   if (!sub_copy)
+   return 0;
+   memcpy(sub_copy, subelement, subie_len);
+
+   pos = _ie[0];
+
+   /* set new ssid */
+   tmp_new = cfg80211_find_ie(WLAN_EID_SSID, sub_copy, subie_len);
+   if (tmp_new) {
+   memcpy(pos, tmp_new, tmp_new[1] + 2);
+   pos += (tmp_new[1] + 2);
+   }
+
+   /* go through IEs in ie (skip SSID) and subelement,
+* merge them into new_ie
+*/
+   tmp_old = cfg80211_find_ie(WLAN_EID_SSID, ie, ielen);
+   tmp_old = (tmp_old) ? tmp_old + tmp_old[1] + 2 : ie;
+
+   while (tmp_old + tmp_old[1] + 2 - ie <= ielen) {
+   if (tmp_old[0] == 0) {
+   tmp_old++;
+   continue;
+   }
+
+   tmp = (u8 *)cfg80211_find_ie(tmp_old[0], sub_copy, subie_len);
+   if (!tmp) {
+   /* ie in old ie but not in subelement */
+   if (tmp_old[0] != WLAN_EID_MULTIPLE_BSSID) {
+   memcpy(pos, tmp_old, tmp_old[1] + 2);
+   pos += tmp_old[1] + 2;
+   }
+   } else {
+   /* ie in transmitting ie also in subelement,
+* copy from subelement and flag the ie in subelement
+* as copied (by setting eid field to 0xff). For
+* vendor ie, compare OUI + type + subType to
+* determine if they are the same ie.
+*/
+   if (tmp_old[0] == WLAN_EID_VENDOR_SPECIFIC) {
+   if (!memcmp(tmp_old + 2, tmp + 2, 5)) {
+   /* same vendor ie, copy from
+* subelement
+*/
+   memcpy(pos, tmp, tmp[1] + 2);
+   pos += tmp[1] + 2;
+   tmp[0] = 0xff;
+   } else {
+   memcpy(pos, tmp_old, tmp_old[1] + 2);
+   pos += tmp_old[1] + 2;
+   }
+   } else {
+  

[PATCH 2/5] cfg80211: Properly track transmitting and non-transmitting BSS

2018-12-07 Thread Jouni Malinen
From: Sara Sharon 

When holding data of the non-transmitting BSS, we need to keep the
transmitting BSS data on. Otherwise it will be released, and release
the non-transmitting BSS with it.

Signed-off-by: Sara Sharon 
Signed-off-by: Johannes Berg 
Signed-off-by: Jouni Malinen 
---
 net/wireless/core.h |  9 +
 net/wireless/scan.c | 36 ++--
 2 files changed, 43 insertions(+), 2 deletions(-)

diff --git a/net/wireless/core.h b/net/wireless/core.h
index d58c56a..b1afc4b 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -153,6 +153,7 @@ struct cfg80211_internal_bss {
struct list_head list;
struct list_head hidden_list;
struct list_head nontrans_list;
+   struct cfg80211_bss *transmitted_bss;
struct rb_node rbn;
u64 ts_boottime;
unsigned long ts;
@@ -183,12 +184,20 @@ static inline struct cfg80211_internal_bss 
*bss_from_pub(struct cfg80211_bss *pu
 static inline void cfg80211_hold_bss(struct cfg80211_internal_bss *bss)
 {
atomic_inc(>hold);
+   if (bss->transmitted_bss)
+   cfg80211_hold_bss(container_of(bss->transmitted_bss,
+  struct cfg80211_internal_bss,
+  pub));
 }
 
 static inline void cfg80211_unhold_bss(struct cfg80211_internal_bss *bss)
 {
int r = atomic_dec_return(>hold);
WARN_ON(r < 0);
+   if (bss->transmitted_bss)
+   cfg80211_unhold_bss(container_of(bss->transmitted_bss,
+struct cfg80211_internal_bss,
+pub));
 }
 
 
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 559f56d..6f2fed2 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -109,6 +109,12 @@ static inline void bss_ref_get(struct 
cfg80211_registered_device *rdev,
   pub);
bss->refcount++;
}
+   if (bss->transmitted_bss) {
+   bss = container_of(bss->transmitted_bss,
+  struct cfg80211_internal_bss,
+  pub);
+   bss->refcount++;
+   }
 }
 
 static inline void bss_ref_put(struct cfg80211_registered_device *rdev,
@@ -125,6 +131,18 @@ static inline void bss_ref_put(struct 
cfg80211_registered_device *rdev,
if (hbss->refcount == 0)
bss_free(hbss);
}
+
+   if (bss->transmitted_bss) {
+   struct cfg80211_internal_bss *tbss;
+
+   tbss = container_of(bss->transmitted_bss,
+   struct cfg80211_internal_bss,
+   pub);
+   tbss->refcount--;
+   if (tbss->refcount == 0)
+   bss_free(tbss);
+   }
+
bss->refcount--;
if (bss->refcount == 0)
bss_free(bss);
@@ -1028,6 +1046,7 @@ static bool cfg80211_combine_bsses(struct 
cfg80211_registered_device *rdev,
 static struct cfg80211_internal_bss *
 cfg80211_bss_update(struct cfg80211_registered_device *rdev,
struct cfg80211_internal_bss *tmp,
+   struct cfg80211_bss *trans_bss,
bool signal_valid)
 {
struct cfg80211_internal_bss *found = NULL;
@@ -1184,6 +1203,17 @@ cfg80211_bss_update(struct cfg80211_registered_device 
*rdev,
goto drop;
}
 
+   /* This must be before the call to bss_ref_get */
+   if (trans_bss) {
+   struct cfg80211_internal_bss *pbss =
+   container_of(trans_bss,
+struct cfg80211_internal_bss,
+pub);
+
+   new->transmitted_bss = trans_bss;
+   bss_ref_get(rdev, pbss);
+   }
+
list_add_tail(>list, >bss_list);
rdev->bss_entries++;
rb_insert_bss(rdev, new);
@@ -1339,7 +1369,8 @@ cfg80211_inform_single_bss_data(struct wiphy *wiphy,
 
signal_valid = abs(data->chan->center_freq - channel->center_freq) <=
wiphy->max_adj_channel_rssi_comp;
-   res = cfg80211_bss_update(wiphy_to_rdev(wiphy), , signal_valid);
+   res = cfg80211_bss_update(wiphy_to_rdev(wiphy), , trans_bss,
+ signal_valid);
if (!res)
return NULL;
 
@@ -1657,7 +1688,8 @@ cfg80211_inform_single_bss_frame_data(struct wiphy *wiphy,
 
signal_valid = abs(data->chan->center_freq - channel->center_freq) <=
wiphy->max_adj_channel_rssi_comp;
-   res = cfg80211_bss_update(wiphy_to_rdev(wiphy), , signal_valid);
+   res = cfg80211_bss_update(wiphy_to_rdev(wiphy), , trans_bss,
+ signal_valid);
if (!res)

[PATCH 4/5] mac80211: Declare support for Multi-BSSID if driver supports it

2018-12-07 Thread Jouni Malinen
From: Sara Sharon 

Define bits and flags for indicating support of Multi-BSSID feature and
indicate support for this if the driver supports it.

Signed-off-by: Sara Sharon 
Signed-off-by: Johannes Berg 
Signed-off-by: Jouni Malinen 
---
 include/linux/ieee80211.h | 6 ++
 include/net/mac80211.h| 3 +++
 net/mac80211/debugfs.c| 1 +
 net/mac80211/main.c   | 4 
 4 files changed, 14 insertions(+)

diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 407d6fd..0a84f4e 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -2656,6 +2656,12 @@ enum ieee80211_tdls_actioncode {
  */
 #define WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING   BIT(2)
 
+/* Multiple BSSID capability is set in the 6th bit of the 3rd byte of the
+ * @WLAN_EID_EXT_CAPABILITY information element
+ */
+#define WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT BIT(6)
+
+
 /* TDLS capabilities in the the 4th byte of @WLAN_EID_EXT_CAPABILITY */
 #define WLAN_EXT_CAPA4_TDLS_BUFFER_STA BIT(4)
 #define WLAN_EXT_CAPA4_TDLS_PEER_PSM   BIT(5)
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 9386cf9..e7c4e11 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -2181,6 +2181,8 @@ struct ieee80211_txq {
  * MMPDUs on station interfaces. This of course requires the driver to use
  * TXQs to start with.
  *
+ * @IEEE80211_HW_SUPPORTS_MULTI_BSSID: Hardware supports multi BSSID
+ *
  * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays
  */
 enum ieee80211_hw_flags {
@@ -2229,6 +2231,7 @@ enum ieee80211_hw_flags {
IEEE80211_HW_BUFF_MMPDU_TXQ,
IEEE80211_HW_SUPPORTS_VHT_EXT_NSS_BW,
IEEE80211_HW_STA_MMPDU_TXQ,
+   IEEE80211_HW_SUPPORTS_MULTI_BSSID,
 
/* keep last, obviously */
NUM_IEEE80211_HW_FLAGS
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
index 3fe541e..28a7e60 100644
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -218,6 +218,7 @@ static const char *hw_flag_names[] = {
FLAG(BUFF_MMPDU_TXQ),
FLAG(SUPPORTS_VHT_EXT_NSS_BW),
FLAG(STA_MMPDU_TXQ),
+   FLAG(SUPPORTS_MULTI_BSSID),
 #undef FLAG
 };
 
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 83e71e6..6ad4288 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -1104,6 +1104,10 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
if (ieee80211_hw_check(>hw, CHANCTX_STA_CSA))
local->ext_capa[0] |= WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING;
 
+   /* mac80211 supports multi BSSID, if the driver supports it */
+   if (ieee80211_hw_check(>hw, SUPPORTS_MULTI_BSSID))
+   local->ext_capa[2] |= WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT;
+
local->hw.wiphy->max_num_csa_counters = IEEE80211_MAX_CSA_COUNTERS_NUM;
 
result = wiphy_register(local->hw.wiphy);
-- 
2.7.4



[PATCH 5/5] mac80211_hwsim: Declare support for Multi-BSSID

2018-12-07 Thread Jouni Malinen
This can be used to test cfg80211 support for Multi-BSSID scan result
parsing.

Signed-off-by: Jouni Malinen 
---
 drivers/net/wireless/mac80211_hwsim.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/wireless/mac80211_hwsim.c 
b/drivers/net/wireless/mac80211_hwsim.c
index 0540834..d5024ad 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -2766,6 +2766,7 @@ static int mac80211_hwsim_new_radio(struct genl_info 
*info,
ieee80211_hw_set(hw, TDLS_WIDER_BW);
if (rctbl)
ieee80211_hw_set(hw, SUPPORTS_RC_TABLE);
+   ieee80211_hw_set(hw, SUPPORTS_MULTI_BSSID);
 
hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS |
WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
-- 
2.7.4



[PATCH 3/5] cfg80211: Move Multiple BSS info to struct cfg80211_bss to be visible

2018-12-07 Thread Jouni Malinen
From: Sara Sharon 

Previously the transmitted BSS and the non-trasmitted BSS list were
defined in struct cfg80211_internal_bss. Move them to struct cfg80211_bss
since mac80211 needs this info.

Signed-off-by: Sara Sharon 
Signed-off-by: Johannes Berg 
Signed-off-by: Jouni Malinen 
---
 include/net/cfg80211.h |  2 ++
 net/wireless/core.h| 10 +++
 net/wireless/scan.c| 79 +-
 3 files changed, 45 insertions(+), 46 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index ede7fcd..839f717 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2019,6 +2019,8 @@ struct cfg80211_bss {
const struct cfg80211_bss_ies __rcu *proberesp_ies;
 
struct cfg80211_bss *hidden_beacon_bss;
+   struct cfg80211_bss *transmitted_bss;
+   struct list_head nontrans_list;
 
s32 signal;
 
diff --git a/net/wireless/core.h b/net/wireless/core.h
index b1afc4b..40c01b6 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -152,8 +152,6 @@ extern int cfg80211_rdev_list_generation;
 struct cfg80211_internal_bss {
struct list_head list;
struct list_head hidden_list;
-   struct list_head nontrans_list;
-   struct cfg80211_bss *transmitted_bss;
struct rb_node rbn;
u64 ts_boottime;
unsigned long ts;
@@ -184,8 +182,8 @@ static inline struct cfg80211_internal_bss 
*bss_from_pub(struct cfg80211_bss *pu
 static inline void cfg80211_hold_bss(struct cfg80211_internal_bss *bss)
 {
atomic_inc(>hold);
-   if (bss->transmitted_bss)
-   cfg80211_hold_bss(container_of(bss->transmitted_bss,
+   if (bss->pub.transmitted_bss)
+   cfg80211_hold_bss(container_of(bss->pub.transmitted_bss,
   struct cfg80211_internal_bss,
   pub));
 }
@@ -194,8 +192,8 @@ static inline void cfg80211_unhold_bss(struct 
cfg80211_internal_bss *bss)
 {
int r = atomic_dec_return(>hold);
WARN_ON(r < 0);
-   if (bss->transmitted_bss)
-   cfg80211_unhold_bss(container_of(bss->transmitted_bss,
+   if (bss->pub.transmitted_bss)
+   cfg80211_unhold_bss(container_of(bss->pub.transmitted_bss,
 struct cfg80211_internal_bss,
 pub));
 }
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 6f2fed2..25ce73d 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -109,8 +109,8 @@ static inline void bss_ref_get(struct 
cfg80211_registered_device *rdev,
   pub);
bss->refcount++;
}
-   if (bss->transmitted_bss) {
-   bss = container_of(bss->transmitted_bss,
+   if (bss->pub.transmitted_bss) {
+   bss = container_of(bss->pub.transmitted_bss,
   struct cfg80211_internal_bss,
   pub);
bss->refcount++;
@@ -132,10 +132,10 @@ static inline void bss_ref_put(struct 
cfg80211_registered_device *rdev,
bss_free(hbss);
}
 
-   if (bss->transmitted_bss) {
+   if (bss->pub.transmitted_bss) {
struct cfg80211_internal_bss *tbss;
 
-   tbss = container_of(bss->transmitted_bss,
+   tbss = container_of(bss->pub.transmitted_bss,
struct cfg80211_internal_bss,
pub);
tbss->refcount--;
@@ -168,7 +168,7 @@ static bool __cfg80211_unlink_bss(struct 
cfg80211_registered_device *rdev,
}
 
list_del_init(>list);
-   list_del_init(>nontrans_list);
+   list_del_init(>pub.nontrans_list);
rb_erase(>rbn, >bss_tree);
rdev->bss_entries--;
WARN_ONCE((rdev->bss_entries == 0) ^ list_empty(>bss_list),
@@ -316,15 +316,15 @@ static bool is_bss(struct cfg80211_bss *a, const u8 
*bssid,
 }
 
 static int
-cfg80211_add_nontrans_list(struct cfg80211_internal_bss *trans_bss,
-  struct cfg80211_internal_bss *nontrans_bss)
+cfg80211_add_nontrans_list(struct cfg80211_bss *trans_bss,
+  struct cfg80211_bss *nontrans_bss)
 {
const u8 *ssid;
size_t ssid_len;
-   struct cfg80211_internal_bss *bss = NULL;
+   struct cfg80211_bss *bss = NULL;
 
rcu_read_lock();
-   ssid = ieee80211_bss_get_ie(_bss->pub, WLAN_EID_SSID);
+   ssid = ieee80211_bss_get_ie(nontrans_bss, WLAN_EID_SSID);
if (!ssid)
return -EINVAL;
ssid_len = ssid[1];
@@ -333,7 +333,7 @@ cfg80211_add_nontrans_list(struct cfg80211_internal_bss 
*trans_bss,
 
/* check if nontrans_bss is in the list */
list_for_each_entry(bss, _bss->nontrans_list, nontrans_list) {
-   if (is_bss(>pub, nontrans_bss->pub.bssid, ssid, 

Re: pull request: mt76 2018-11-30

2018-12-07 Thread Kalle Valo
Lorenzo Bianconi  writes:

>> Felix Fietkau  writes:
>>
>> > here's my first pull request for 4.21
>> >
>> > - Felix
>> >
>> > The following changes since commit 
>> > b72c51a58e6d63ef673ac96b8ab5bc98799c5f7b:
>> >
>> >   brcmfmac: Fix out of bounds memory access during fw load (2018-11-29 
>> > 17:33:10 +0200)
>> >
>> > are available in the Git repository at:
>> >
>> >   https://github.com/nbd168/wireless tags/mt76-for-kvalo-2018-11-30
>> >
>> > for you to fetch changes up to e28487ea84a9c081c6d8d7da319427f7fcc32ff5:
>> >
>> >   mt76: replace sta_add/remove ops with common sta_state function
>> > (2018-11-30 12:30:37 +0100)
>> >
>> > 
>> > first batch of mt76 patches for 4.21
>> >
>> > * use the same firmware for mt76x2e and mt76x2u
>> > * mt76x2 fixes
>> > * mt76x0 fixes
>> > * mt76x0e survey support
>> > * more unification between mt76x2 and mt76x0
>> > * mt76x0e AP mode support
>> > * mt76x0e DFS support
>> > * rework and fix tx status handling for mt76x0 and mt76x2
>> >
>> > 
>>
>> I fast forwarded w-d-next to net-next and now there's a conflict. I did
>> a test merge in the pending branch, please double check:
>>
>> https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next.git/commit/?h=pending=e69caab09bf98d0d8b559d06887364cc0090097c
>>
>
> ack

Thanks for checking, I'll pull this soon.

-- 
Kalle Valo


Re: brcmfmac: regression using AP mode

2018-12-07 Thread Stefan Wahren
Hi,

Am 26.11.18 um 11:11 schrieb Arend van Spriel:
> On 11/25/2018 2:14 PM, Stefan Wahren wrote:
>> Hi Rafał,
>>
>>> Rafał Miłecki  hat am 24. November 2018 um 22:23
>>> geschrieben:
>>>
>>>
>>> Possibly you can just update hostapd to anything more recent? I'm
>>> afraid
>>> the version you're using may suffer from a lot of security issues
>>> anyway
>>
>> thanks for your quick reply. I updated hostapd to 2.6.18 from Debian
>> Buster. This makes hostapd work better, but AP mode still does work
>> (kernel output):
>>
>> [    6.085594] cfg80211: Loaded X.509 cert 'sforshee:
>> 00b28ddf47aef9cea7'
>> [    6.085772] platform regulatory.0: Direct firmware load for
>> regulatory.db failed with error -2
>> [    6.085781] cfg80211: failed to load regulatory.db
>> [    6.148788] Console: switching to colour frame buffer device 240x67
>> [    6.170518] brcmfmac: brcmf_fw_alloc_request: using
>> brcm/brcmfmac43455-sdio for chip BCM4345/6
>> [    6.197752] vc4-drm soc:gpu: fb0: DRM emulated frame buffer device
>> [    6.324425] random: crng init done
>> [    6.324438] random: 7 urandom warning(s) missed due to ratelimiting
>> [    6.365083] brcmfmac: brcmf_fw_alloc_request: using
>> brcm/brcmfmac43455-sdio for chip BCM4345/6
>> [    6.398502] brcmfmac: brcmf_c_preinit_dcmds: Firmware: BCM4345/6
>> wl0: Feb 27 2018 03:15:32 version 7.45.154 (r684107 CY) FWID 01-4fbe0b04
>> [    6.800404] Bluetooth: hci0: BCM4345C0 (003.001.025) build 0252
>> [    9.961790] IPv6: ADDRCONF(NETDEV_UP): wlan0: link is not ready
>> [   10.026130] Adding 102396k swap on /var/swap.  Priority:-2
>> extents:1 across:102396k SS
>> [   10.272507] IPv6: ADDRCONF(NETDEV_CHANGE): wlan0: link becomes ready
>> [   13.627905] brcmfmac: brcmf_cfg80211_stop_ap: setting AP mode
>> failed -52
>> [  146.411501] brcmfmac: brcmf_escan_timeout: timer expired
>> [  146.862393] brcmfmac: brcmf_vif_set_mgmt_ie: vndr ie set error : -52
>> [  257.130466] brcmfmac: brcmf_escan_timeout: timer expired
>> [  257.581463] brcmfmac: brcmf_vif_set_mgmt_ie: vndr ie set error : -52
>>
>> Hostapd output:
>>
>> random: Trying to read entropy from /dev/random
>> Configuration file: /etc/hostapd/hostapd.conf
>> nl80211: Using driver-based roaming
>> nl80211: TDLS supported
>> nl80211: Supported cipher 00-0f-ac:1
>> nl80211: Supported cipher 00-0f-ac:5
>> nl80211: Supported cipher 00-0f-ac:2
>> nl80211: Supported cipher 00-0f-ac:4
>> nl80211: Supported cipher 00-0f-ac:6
>> nl80211: Using driver-based off-channel TX
>> nl80211: Supported vendor command: vendor_id=0x1018 subcmd=1
>> nl80211: Use separate P2P group interface (driver advertised support)
>> nl80211: Enable multi-channel concurrent (driver advertised support)
>> nl80211: use P2P_DEVICE support
>> nl80211: interface wlan0 in phy phy0
>> nl80211: Set mode ifindex 3 iftype 3 (AP)
>> nl80211: Setup AP(wlan0) - device_ap_sme=1 use_monitor=0
>> nl80211: Subscribe to mgmt frames with AP handle 0x543340 (device SME)
>> nl80211: Register frame type=0xd0 (WLAN_FC_STYPE_ACTION)
>> nl_handle=0x543340 match=04
>> nl80211: Register frame command failed (type=208): ret=-22 (Invalid
>> argument)
>
> Probably the mgmt_stypes is not properly set:
>
>     if (!(wdev->wiphy->mgmt_stypes[wdev->iftype].rx &
> BIT(mgmt_type)))
>     return -EINVAL;
>
> which makes sense as brcmfmac has following:
>
> static const struct ieee80211_txrx_stypes
> brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = {
>     [NL80211_IFTYPE_STATION] = {
>     .tx = 0x,
>     .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
>   BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
>     },
>     [NL80211_IFTYPE_P2P_CLIENT] = {
>     .tx = 0x,
>     .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
>   BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
>     },
>     [NL80211_IFTYPE_P2P_GO] = {
>     .tx = 0x,
>     .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
>   BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
>   BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
>   BIT(IEEE80211_STYPE_DISASSOC >> 4) |
>   BIT(IEEE80211_STYPE_AUTH >> 4) |
>   BIT(IEEE80211_STYPE_DEAUTH >> 4) |
>   BIT(IEEE80211_STYPE_ACTION >> 4)
>     },
>     [NL80211_IFTYPE_P2P_DEVICE] = {
>     .tx = 0x,
>     .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
>   BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
>     }
> };
>
> So no AP listed here. I suspect Rafał was focusing on "device_ap_sme=1
> use_monitor=1" scenario. You can try adding AP entry with similar rx
> bits as P2P_GO above.

please ignore my last mail, i forgot to terminate wpa_supplicant before :-(

Your suggestion works with hostapd 2.6. I could prepare a patch but i'm
not sure about the proper commit log.

Stefan

>
> Regards,
> Arend



Re: [RFC PATCH v2 0/2] Extended Key ID support for linux

2018-12-07 Thread Jouni Malinen
On Wed, Dec 05, 2018 at 08:06:33PM +0100, Alexander Wetzel wrote:
> >On Sun, 2018-11-11 at 12:02 +0100, Alexander Wetzel wrote:
> >>IEEE 802.11-2012 added support for Extended Key ID, allowing pairwise
> >>keys to also use keyID 1 and moving group keys to IDs 2 and 3.
> >
> >Where do you read this? I've always been under the impression that
> >individually and group addressed frames use key IDs from different
> >"namespaces", so to speak, where PTK/STK can use 0 (0 or 1 with
> >"Extended Key ID" support) and GTK can use 0-3.

There is no such requirement to change group key IDs in the IEEE 802.11
standard when taking Extended Key ID mechanism into use.

> >In fact, the per-frame pseudocode in 802.11-2016 12.9.2.6 clearly
> >states:
> >
> >if MPDU has individual RA then
> > lookup pairwise key using Key ID from MPDU
> >else
> > lookup group key using Key ID from MPDU
> >endif
> >
> >If it weren't different namespaces, you'd not have to differentiate
> >here.
> >
> 
> I was indeed struggling to understand what the intend of the standard is
> here. I may well be wrong, but the note in "12.6.1.1.10 Mesh GTKSA" tipped
> the scales to assume keyIDs are within one namespace only.
> 
> "Since Key ID 0 is reserved for individually addressed frame transmission,
> there are at most three available Key IDs (only two if extended Key IDs for
> individually addressed frames are in use), and the different MGTKs would
> contend for the single remaining Key ID upon rollover."

Please note that this is is an informative note and not normative part
of the standard. IMHO, that note is not accurate and it looks likely
that it was added without full understanding on how the keys are used in
the standard..

> I got the impression Extended Key IDs were  added without updating all
> sections which should get updates. But the pattern is suspect, even the igtk
> numbers fit into the pattern:
> 
>  PTK 0 & 1
>  GTK 1 & 2 & 3
> iGTK 4 & 5

An AP is allowed to do this, but there is no requirement for doing so.
The pairwise key (TK, not PTK) is required to use Key ID 0 unless the
optional Extended Key ID for Individually Addressed Frames capability is
negotiated (and 0 or 1 if that capability is negotiated). Group keys
(GTK) are allowed to use Key IDs 0..4. IGTKs are allowed to use Key ID
values 4 and 5.

There is a long history behind this and some de facto constraints due to
that history and possible implementation constraints. However, as far as
the protocol itself is concerned, there would be no real need for having
IGTK use 4..5; it could have as well been 0..1 or 1..2 or whatever
combination the AP would like to use.

These three cases have completely independent namespaces for Key IDs as
far as RSN is concerned with one exception: "Use group cipher suite"
that was added as an option for some AP implementation that did not
support individual key mapping. That special case would end up using GTK
for both group-addressed and individually-addressed frames. That said,
I'm not aware of there having ever been an actually deployed device with
this constraint and even if there were, this mode is highly discouraged
and should not be used for anything today. Anyway, this exception and
similar implementation constraints are likely behind the expectations of
TK and GTK having to use different Key ID values.

As far as the kernel changes are concerned, cfg80211 and mac80211 should
support everything that's allowed by the standard, i.e., use of Key IDs
0..3 for GTK. It is up to the user space implementation on the AP side
(e.g., hostapd) to select which Key IDs are actually taken into use.

-- 
Jouni MalinenPGP id EFC895FA


RE: [PATCH v2 01/13] rtw88: main files

2018-12-07 Thread Tony Chuang
Hi Kalle,

This patch added a comment about our watch dog timer, please let me know if you 
are OK with it.
Also if you have other questions about the series, just point it out and I will 
try to fix it.
Thanks.

Yan-Hsuan

> -Original Message-
> From: linux-wireless-ow...@vger.kernel.org
> [mailto:linux-wireless-ow...@vger.kernel.org] On Behalf Of
> yhchu...@realtek.com
> Sent: Friday, November 16, 2018 7:31 PM
> To: kv...@codeaurora.org
> Cc: larry.fin...@lwfinger.net; linux-wireless@vger.kernel.org; Pkshih; Andy
> Huang
> Subject: [PATCH v2 01/13] rtw88: main files
> 
> From: Yan-Hsuan Chuang 
> 
> main files for Realtek 802.11ac wireless network chips
> 
> Signed-off-by: Yan-Hsuan Chuang 
> ---
>  drivers/net/wireless/realtek/rtw88/mac80211.c |  480 ++
>  drivers/net/wireless/realtek/rtw88/main.c | 1190
> +
>  drivers/net/wireless/realtek/rtw88/main.h | 1119
> +++
>  drivers/net/wireless/realtek/rtw88/reg.h  |  411 +
>  4 files changed, 3200 insertions(+)
>  create mode 100644 drivers/net/wireless/realtek/rtw88/mac80211.c
>  create mode 100644 drivers/net/wireless/realtek/rtw88/main.c
>  create mode 100644 drivers/net/wireless/realtek/rtw88/main.h
>  create mode 100644 drivers/net/wireless/realtek/rtw88/reg.h
> 
> diff --git a/drivers/net/wireless/realtek/rtw88/mac80211.c
> b/drivers/net/wireless/realtek/rtw88/mac80211.c
> new file mode 100644
> index 000..17b3651
> --- /dev/null
> +++ b/drivers/net/wireless/realtek/rtw88/mac80211.c
> @@ -0,0 +1,480 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/* Copyright(c) 2018  Realtek Corporation.
> + */
> +
> +#include "main.h"
> +#include "sec.h"
> +#include "tx.h"
> +#include "fw.h"
> +#include "mac.h"
> +#include "ps.h"
> +#include "reg.h"
> +#include "debug.h"
> +
> +static void rtw_ops_tx(struct ieee80211_hw *hw,
> +struct ieee80211_tx_control *control,
> +struct sk_buff *skb)
> +{
> + struct rtw_dev *rtwdev = hw->priv;
> + struct rtw_tx_pkt_info pkt_info = {0};
> +
> + if (!rtw_flag_check(rtwdev, RTW_FLAG_RUNNING))
> + goto out;
> +
> + rtw_tx_pkt_info_update(rtwdev, _info, control, skb);
> + if (rtw_hci_tx(rtwdev, _info, skb))
> + goto out;
> +
> + return;
> +
> +out:
> + ieee80211_free_txskb(hw, skb);
> +}
> +
> +static int rtw_ops_start(struct ieee80211_hw *hw)
> +{
> + struct rtw_dev *rtwdev = hw->priv;
> + int ret;
> +
> + mutex_lock(>mutex);
> + ret = rtw_core_start(rtwdev);
> + mutex_unlock(>mutex);
> +
> + return ret;
> +}
> +
> +static void rtw_ops_stop(struct ieee80211_hw *hw)
> +{
> + struct rtw_dev *rtwdev = hw->priv;
> +
> + mutex_lock(>mutex);
> + rtw_core_stop(rtwdev);
> + mutex_unlock(>mutex);
> +}
> +
> +static int rtw_ops_config(struct ieee80211_hw *hw, u32 changed)
> +{
> + struct rtw_dev *rtwdev = hw->priv;
> + int ret = 0;
> +
> + mutex_lock(>mutex);
> +
> + if (changed & IEEE80211_CONF_CHANGE_IDLE) {
> + if (hw->conf.flags & IEEE80211_CONF_IDLE) {
> + rtw_enter_ips(rtwdev);
> + } else {
> + ret = rtw_leave_ips(rtwdev);
> + if (ret) {
> + rtw_err(rtwdev, "failed to leave idle state\n");
> + goto out;
> + }
> + }
> + }
> +
> + if (changed & IEEE80211_CONF_CHANGE_CHANNEL)
> + rtw_set_channel(rtwdev);
> +
> +out:
> + mutex_unlock(>mutex);
> + return ret;
> +}
> +
> +static const struct rtw_vif_port rtw_vif_port[] = {
> + [0] = {
> + .mac_addr   = {.addr = 0x0610},
> + .bssid  = {.addr = 0x0618},
> + .net_type   = {.addr = 0x0100, .mask = 0x3},
> + .aid= {.addr = 0x06a8, .mask = 0x7ff},
> + },
> + [1] = {
> + .mac_addr   = {.addr = 0x0700},
> + .bssid  = {.addr = 0x0708},
> + .net_type   = {.addr = 0x0100, .mask = 0xc},
> + .aid= {.addr = 0x0710, .mask = 0x7ff},
> + },
> + [2] = {
> + .mac_addr   = {.addr = 0x1620},
> + .bssid  = {.addr = 0x1628},
> + .net_type   = {.addr = 0x1100, .mask = 0x3},
> + .aid= {.addr = 0x1600, .mask = 0x7ff},
> + },
> + [3] = {
> + .mac_addr   = {.addr = 0x1630},
> + .bssid  = {.addr = 0x1638},
> + .net_type   = {.addr = 0x1100, .mask = 0xc},
> + .aid= {.addr = 0x1604, .mask = 0x7ff},
> + },
> + [4] = {
> + .mac_addr   = {.addr = 0x1640},
> + .bssid  = {.addr = 0x1648},
> + .net_type   = {.addr = 0x1100, .mask = 0x30},
> + .aid= {.addr = 0x1608, .mask = 0x7ff},
> + },

Re: Request for brcmfmac4366c-pcie.bin

2018-12-06 Thread Hubert Wiedeke
On Wed, 4 Apr 2018 09:38:32 +0200
Arend van Spriel  wrote:

> On 4/4/2018 4:12 AM, Hubert Wiedeke wrote:
> > On Mon, 19 Feb 2018 12:51:07 +0100
> > Arend van Spriel  wrote:
> >
> >> On 2/17/2018 9:19 AM, Hubert Wiedeke wrote:
> >>> Hi,
> >>>
> >>> I'd like to ask about the current status of 4366c firmware preparation 
> >>> for linux-firmware.git . Is it close to finish? What about DFS? Nothing 
> >>> critical, just a question.
> >>
> >> I have prepared some firmware changes for 4366, but did not manage to
> >> get any test-cycles for it.
> >>
> >> Regards,
> >> Arend
> >>
> >
> > Could you please estimate any possible dates for the tested FW to be 
> > released?
> 
> Not really. Linux open-source work is getting rather low prio when it 
> comes to claiming test lab resources. Best I can say is somewhere this year.
> 
> Regards,
> Arend
> 

Hi Arend,

It seems like the year is almost over, and I guess it would be nice to 
reconsider the estimation (no rush, of course).
If you had a spare minute, could you please review the current status/priority 
for this FW?
Linux-powered consumers of 4366c would probably appreciate this information.

-- 
Best regards,
Hubert Wiedeke


Re: [RFC PATCH v2 2/2] mac80211: Add support for Extended Key ID

2018-12-06 Thread Alexander Wetzel



-   /* PTK only using key ID 0 needs special handling on rekey */
-   if (new_key && sta && ptk0rekey) {
+   /* PTK rekey without Extended Key ID needs special handling */
+   if (new_key && pairwise && sta &&
+   !test_sta_flag(sta, WLAN_STA_EXT_KEY_ID)) {
local = old_key->local;
sdata = old_key->sdata;


This seems wrong, even if you have ext key ID support and everything,
but you do 0 -> 0 rekeying, then you still need all the special handling
(in fact also then if you go 1->1!). So it seems you'd instead want to
see if you're going from a TX key to a TX key with the same key ID, and
then you don't need this flag at all.



The intention for Extended Key ID is, to have a comparable short time
frame where both key IDs can be used. When replacing e.g. key ID 0 again
it should be idle for a long time. I guess if someone starts re-keying
in 1s intervals it may become an issue, but then anyone re-keying that
often can't be helped...


Sure. But ... not sure how that's related?


With Extended Key IDs it's impossible to directly switch from a TX key
with one key ID to another one with the same id.

1) Association
2) key ID 0 installed RX only
3) key Id 0 set_tx
4) rekey timeout passes
5) key ID 1 installed RX only
6) key ID 1 set_tx (also making key ID 0 RX only)
7) rekey timeout passes
8) key ID 0 replaced with new RX only key
9) key ID 0 set_tx
10) rekey timeout passes
...

So nobody will use the key being replaced, we don't have to protect
against PN poisoning.


Exactly.


And when a driver supports Extended Key ID we
don't care about if the driver is able to rekey PTK0 correctly.


Strictly speaking, that's false, since you don't know if wpa_s actually
used it, and the peer STA allowed it.

It's also not what you implemented, you implemented checking if
NL80211_KEY_RX_ONLY was ever used.

However, what I'm trying to say is that I'm not sure this makes sense?

It seems to me it would be safer, and easier (no station flag), to just
check

  if ("we're replacing the current TX key")

and trigger the workarounds in that case. No?

Yes, parts of the issue also manifest themselves on the RX side, but if
you're not replacing the current key then you were using extended key ID
support?


Ah, now I get it:-)
Will try that out also.



+++ b/net/mac80211/sta_info.c
@@ -350,6 +350,7 @@ struct sta_info *sta_info_alloc(struct 
ieee80211_sub_if_data *sdata,
sta->sta.max_rx_aggregation_subframes =
local->hw.max_rx_aggregation_subframes;
   
+	sta->ptk_idx = NUM_DEFAULT_KEYS - 1;


That makes no sense? Why should it be 3? That's invalid anyway?


Yes, that's the whole reason for that change:-) Setting it to 2 would
also be fine, as long as it's not 0 or 1.


Hmm, ok. So that probably wants a big comment saying that it relies on
key idx 2/3 being invalid. I'm not sure I like the NUM_DEFAULT_KEYS-1,
better perhaps to do something like

/* comment saying why */
BUILD_BUG_ON(ARRAY_SIZE(sta->ptks) > 2);
sta->ptk_idx = 2;

or so?


ieee80211_tx_h_select_key starts encrypting packets as soon as
sta->ptk[tx->sta->ptk_idx] is not null.


Right, so I guess this makes sense.

johannes
Thank you very much for all the helpful tips and suggestions!


Alexander


[PATCH] mt76: usb: avoid queue/status spinlocks while passing tx status to mac80211

2018-12-06 Thread Lorenzo Bianconi
As already done for pcie code in commit 79d1c94c9c78 ("mt76: avoid
queue/status spinlocks while passing tx status to mac80211") make sure
that no tx related spinlocks are taken during the ieee80211_tx_status call

Signed-off-by: Lorenzo Bianconi 
---
 drivers/net/wireless/mediatek/mt76/usb.c | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/usb.c 
b/drivers/net/wireless/mediatek/mt76/usb.c
index 14ff06c5764e..6a2507524c6c 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -583,6 +583,7 @@ static void mt76u_stop_rx(struct mt76_dev *dev)
 static void mt76u_tx_tasklet(unsigned long data)
 {
struct mt76_dev *dev = (struct mt76_dev *)data;
+   struct mt76_queue_entry entry;
struct mt76u_buf *buf;
struct mt76_queue *q;
bool wake;
@@ -597,17 +598,18 @@ static void mt76u_tx_tasklet(unsigned long data)
if (!buf->done || !q->queued)
break;
 
-   dev->drv->tx_complete_skb(dev, q,
- >entry[q->head],
- false);
-
if (q->entry[q->head].schedule) {
q->entry[q->head].schedule = false;
q->swq_queued--;
}
 
+   entry = q->entry[q->head];
q->head = (q->head + 1) % q->ndesc;
q->queued--;
+
+   spin_unlock_bh(>lock);
+   dev->drv->tx_complete_skb(dev, q, , false);
+   spin_lock_bh(>lock);
}
mt76_txq_schedule(dev, q);
wake = i < IEEE80211_NUM_ACS && q->queued < q->ndesc - 8;
-- 
2.19.2



Re: [RFC PATCH v2 1/2] nl80211/cfg80211: Add support for Extended Key ID

2018-12-06 Thread Alexander Wetzel

On Wed, 2018-12-05 at 21:54 +0100, Alexander Wetzel wrote:


It started out as a flag and I switched to enum later without updating
it. I'll chnage that to nl80211_key_install_mode, much much better...



No, all stations using Extended Key ID will always use RX_ONLY and
SET_TX for pairwise key installs. The AP will install the Key Rx only
prior to sending eapol #3, the sta prior to sending eapol #4.


Actually ... let's see all the operations at nl80211 level.

We have NEW_KEY and SET_KEY, right? SET_KEY basically already says to
use a given key for TX from now on, IIRC?

So realistically, don't we only need

NEW_KEY (RX-only)

as a new variant of NEW_KEY?



Yes, that should indeed work. I'll try that and see how it plays out.


The PTK0 rekey patch added a new line in front of the description. The
next author did not notice that and added the description for
NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER at the wrong place, probably
assuming it was the end of the list. I've noticed that and fixed the
documentation order and the misleading empty line.
I'll break that out as a separate cleanup patch if nobody beats me to it:-)


Oh. OK. It also doesn't really matter ;-)


k->def_multi = true;
   
+	k->rx_only = !!info->attrs[NL80211_ATTR_KEY_RXONLY];

+   k->set_tx = !!info->attrs[NL80211_ATTR_KEY_SETTX];


shouldn't this already be install_mode?



Looks like switching to NL80211_ATTR_INSTALL_MODE will throw out that,
but with the code from this patch that's an interim layer for checks and
mapping it. So I'm not sure I understand that comment.


Well, me neither. Sounds almost like I got ahead of myself.


You need to check if extended key ID is supported


Yes. I have added checks in cfg80211_validate_key_settings current
development version already, making sure only valid combinations can be
called and reach this section.


Ok, great.


NL80211_CMD_SET_KEY is normally only used to set default keys for wep or
managment keys. That changes here.


Right.


In this API draft NL80211_CMD_NEW_KEY is only used when installing a
Extended Key ID key RX only. The switch to TX is added to
NL80211_CMD_SET_KEY. The code has some sanity checks and then tells the
driver to switch the key to tx.


Makes sense.


But that has been changed quite a bit, the procedure in this patch
turned out to be not so good and even had a locking issue, so it has
changed a bit. I guess we should shelf that till I get the new variant
working and then look at it again.


Fair enough.


+++ b/net/wireless/util.c
@@ -236,13 +236,14 @@ int cfg80211_validate_key_settings(struct 
cfg80211_registered_device *rdev,
case WLAN_CIPHER_SUITE_CCMP_256:
case WLAN_CIPHER_SUITE_GCMP:
case WLAN_CIPHER_SUITE_GCMP_256:
-   /* Disallow pairwise keys with non-zero index unless it's WEP
+   /* IEEE802.11-2016 allows only 0 and 1 for pairwise keys.
+* Disallow pairwise keys with index above 1 unless it's WEP
 * or a vendor specific cipher (because current deployments use
-* pairwise WEP keys with non-zero indices and for vendor
+* pairwise WEP keys with higher indices and for vendor
 * specific ciphers this should be validated in the driver or
-* hardware level - but 802.11i clearly specifies to use zero)
+* hardware level.
 */
-   if (pairwise && key_idx)
+   if (pairwise && key_idx > 1)
return -EINVAL;
break;


Again, only if driver support is advertised, and the comment should
probably reference the feature bit from the spec.


That is where I added most of the sanity checks in the meantime.
But what feature bit from the spec are you referring to? The RSN
Capability one?


Well, I wasn't thinking that precisely. I just thought it should mention
that it now says "IEEE802.11-2016 allows only 0 and 1 for pairwise keys"
but doesn't clarify that this is only for stations that actually want to
support it, so it could be read as being always that way.


Makes sense. I'll reword that a bit.



[PATCH] mt76: mac: run mt76x02_mac_work routine atomically

2018-12-06 Thread Lorenzo Bianconi
Grab mt76_dev mutex in mt76x02_mac_work handler since it runs
concurrently with mt76x{0,2}_set_channel routines

Signed-off-by: Lorenzo Bianconi 
---
 drivers/net/wireless/mediatek/mt76/mt76x02_mac.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
index 490368dc9325..64841f40cdcf 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
@@ -784,6 +784,8 @@ void mt76x02_mac_work(struct work_struct *work)
   mac_work.work);
int i, idx;
 
+   mutex_lock(>mt76.mutex);
+
mt76x02_update_channel(>mt76);
for (i = 0, idx = 0; i < 16; i++) {
u32 val = mt76_rr(dev, MT_TX_AGG_CNT(i));
@@ -796,6 +798,8 @@ void mt76x02_mac_work(struct work_struct *work)
if (!dev->beacon_mask)
mt76x02_check_mac_err(dev);
 
+   mutex_unlock(>mt76.mutex);
+
mt76_tx_status_check(>mt76, NULL, false);
 
ieee80211_queue_delayed_work(mt76_hw(dev), >mac_work,
-- 
2.19.2



[PATCH] mt76: fix typo in mt76x02_check_mac_err routine

2018-12-06 Thread Lorenzo Bianconi
Reconfigure properly MT_MAC_SYS_CTRL register after mac sw-reset
in mt76x02_check_mac_err routine

Fixes: 73556561ab9f ("mt76x0: use mt76x02_mac_work as stats handler")
Signed-off-by: Lorenzo Bianconi 
---
 drivers/net/wireless/mediatek/mt76/mt76x02_mac.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
index c08bf371e527..490368dc9325 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
@@ -774,8 +774,8 @@ static void mt76x02_check_mac_err(struct mt76x02_dev *dev)
 
mt76_set(dev, MT_MAC_SYS_CTRL, MT_MAC_SYS_CTRL_RESET_CSR);
udelay(10);
-   mt76_clear(dev, MT_MAC_SYS_CTRL,
-  MT_MAC_SYS_CTRL_ENABLE_TX | MT_MAC_SYS_CTRL_ENABLE_RX);
+   mt76_wr(dev, MT_MAC_SYS_CTRL,
+   MT_MAC_SYS_CTRL_ENABLE_TX | MT_MAC_SYS_CTRL_ENABLE_RX);
 }
 
 void mt76x02_mac_work(struct work_struct *work)
-- 
2.19.2



Re: [PATCH 2/2] mt76: dma: add rx buffer recycle support

2018-12-06 Thread Stanislaw Gruszka
On Wed, Dec 05, 2018 at 04:17:31PM +0100, Lorenzo Bianconi wrote:
> > On Wed, Dec 05, 2018 at 11:37:33AM +0100, Lorenzo Bianconi wrote:
> > > >
> > > > Add support for recycling rx buffers if they are not forwarded
> > > > to network stack instead of reallocate them from scratch
> > > >
> > > > Signed-off-by: Lorenzo Bianconi 
> > > > ---
> > > 
> > > Felix,
> > > 
> > > could you please drop this patch since it does not help to reduce pressure
> > > on page_frag_cache.
> > 
> > What is the problem ? Maybe using kmalloc() instead of page_frag_alloc()
> > could help (kmalloc has standard kmem_cache for 2048 bytes object) ?
> 
> Hi Stanislaw,
> 
> I think the only difference in using a recycle buffer with page_frag_cache is
> we are a little bit less greedy in consuming the compound page since in case 
> of
> error we will reuse the previously allocated fragment. However we will need to
> reallocate a new compound page if we have a leftover fragment that 'locks'
> the previous compound (we have the same issue if we do not use the recycle
> buffer). Does this 'little' improvement worth a more complex code?
> Do you agree or is there something I am missing here?

I was not asking about the patch. I agree it should be droped. 

I was asking what is the problem with "pressure on page_frag_cache" and if
using kmalloc() instead of page_frag_alloc() whould be potential solution.

Regards
Stanislaw



[PATCH] cfg80211: Notify all User Hints To self managed wiphys

2018-12-06 Thread Sriram R
Currently Self Managed WIPHY's are not notified on any
hints other than user cell base station hints.
Self Managed wiphy's basically rely on hints from firmware
and its local regdb for regulatory management, so hints from wireless
core can be ignored. But all user hints needs to be notified
to them to provide flexibility to these drivers to honour or
ignore these user hints.

Currently none of the drivers supporting self managed wiphy
register a notifier with cfg80211. Hence this change does not affect
any other driver behavior.

Signed-off-by: Sriram R 
---
 net/wireless/reg.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index ecfb1a0..7def1ec 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -2724,9 +2724,7 @@ static void notify_self_managed_wiphys(struct 
regulatory_request *request)
list_for_each_entry(rdev, _rdev_list, list) {
wiphy = >wiphy;
if (wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED &&
-   request->initiator == NL80211_REGDOM_SET_BY_USER &&
-   request->user_reg_hint_type ==
-   NL80211_USER_REG_HINT_CELL_BASE)
+   request->initiator == NL80211_REGDOM_SET_BY_USER)
reg_call_notifier(wiphy, request);
}
 }
-- 
2.7.4



Re: [RFC PATCH v2 2/2] mac80211: Add support for Extended Key ID

2018-12-05 Thread Johannes Berg


> > > - /* PTK only using key ID 0 needs special handling on rekey */
> > > - if (new_key && sta && ptk0rekey) {
> > > + /* PTK rekey without Extended Key ID needs special handling */
> > > + if (new_key && pairwise && sta &&
> > > + !test_sta_flag(sta, WLAN_STA_EXT_KEY_ID)) {
> > >   local = old_key->local;
> > >   sdata = old_key->sdata;
> > 
> > This seems wrong, even if you have ext key ID support and everything,
> > but you do 0 -> 0 rekeying, then you still need all the special handling
> > (in fact also then if you go 1->1!). So it seems you'd instead want to
> > see if you're going from a TX key to a TX key with the same key ID, and
> > then you don't need this flag at all.
> > 
> 
> The intention for Extended Key ID is, to have a comparable short time 
> frame where both key IDs can be used. When replacing e.g. key ID 0 again 
> it should be idle for a long time. I guess if someone starts re-keying 
> in 1s intervals it may become an issue, but then anyone re-keying that 
> often can't be helped...

Sure. But ... not sure how that's related?

> With Extended Key IDs it's impossible to directly switch from a TX key 
> with one key ID to another one with the same id.
> 
> 1) Association
> 2) key ID 0 installed RX only
> 3) key Id 0 set_tx
> 4) rekey timeout passes
> 5) key ID 1 installed RX only
> 6) key ID 1 set_tx (also making key ID 0 RX only)
> 7) rekey timeout passes
> 8) key ID 0 replaced with new RX only key
> 9) key ID 0 set_tx
> 10) rekey timeout passes
> ...
> 
> So nobody will use the key being replaced, we don't have to protect 
> against PN poisoning.

Exactly.

> And when a driver supports Extended Key ID we 
> don't care about if the driver is able to rekey PTK0 correctly.

Strictly speaking, that's false, since you don't know if wpa_s actually
used it, and the peer STA allowed it.

It's also not what you implemented, you implemented checking if
NL80211_KEY_RX_ONLY was ever used.

However, what I'm trying to say is that I'm not sure this makes sense?

It seems to me it would be safer, and easier (no station flag), to just
check

 if ("we're replacing the current TX key")

and trigger the workarounds in that case. No?

Yes, parts of the issue also manifest themselves on the RX side, but if
you're not replacing the current key then you were using extended key ID
support?

> > > +++ b/net/mac80211/sta_info.c
> > > @@ -350,6 +350,7 @@ struct sta_info *sta_info_alloc(struct 
> > > ieee80211_sub_if_data *sdata,
> > >   sta->sta.max_rx_aggregation_subframes =
> > >   local->hw.max_rx_aggregation_subframes;
> > >   
> > > + sta->ptk_idx = NUM_DEFAULT_KEYS - 1;
> > 
> > That makes no sense? Why should it be 3? That's invalid anyway?
> 
> Yes, that's the whole reason for that change:-) Setting it to 2 would 
> also be fine, as long as it's not 0 or 1.

Hmm, ok. So that probably wants a big comment saying that it relies on
key idx 2/3 being invalid. I'm not sure I like the NUM_DEFAULT_KEYS-1,
better perhaps to do something like

/* comment saying why */
BUILD_BUG_ON(ARRAY_SIZE(sta->ptks) > 2);
sta->ptk_idx = 2;

or so?

> ieee80211_tx_h_select_key starts encrypting packets as soon as 
> sta->ptk[tx->sta->ptk_idx] is not null.

Right, so I guess this makes sense.

johannes



Re: [RFC PATCH v2 1/2] nl80211/cfg80211: Add support for Extended Key ID

2018-12-05 Thread Johannes Berg
On Wed, 2018-12-05 at 21:54 +0100, Alexander Wetzel wrote:
> 
> It started out as a flag and I switched to enum later without updating 
> it. I'll chnage that to nl80211_key_install_mode, much much better...

> No, all stations using Extended Key ID will always use RX_ONLY and 
> SET_TX for pairwise key installs. The AP will install the Key Rx only 
> prior to sending eapol #3, the sta prior to sending eapol #4.

Actually ... let's see all the operations at nl80211 level.

We have NEW_KEY and SET_KEY, right? SET_KEY basically already says to
use a given key for TX from now on, IIRC?

So realistically, don't we only need

NEW_KEY (RX-only)

as a new variant of NEW_KEY?

> The PTK0 rekey patch added a new line in front of the description. The 
> next author did not notice that and added the description for 
> NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER at the wrong place, probably 
> assuming it was the end of the list. I've noticed that and fixed the 
> documentation order and the misleading empty line.
> I'll break that out as a separate cleanup patch if nobody beats me to it:-)

Oh. OK. It also doesn't really matter ;-)

> > >   k->def_multi = true;
> > >   
> > > + k->rx_only = !!info->attrs[NL80211_ATTR_KEY_RXONLY];
> > > + k->set_tx = !!info->attrs[NL80211_ATTR_KEY_SETTX];
> > 
> > shouldn't this already be install_mode?
> > 
> 
> Looks like switching to NL80211_ATTR_INSTALL_MODE will throw out that, 
> but with the code from this patch that's an interim layer for checks and 
> mapping it. So I'm not sure I understand that comment.

Well, me neither. Sounds almost like I got ahead of myself.

> > You need to check if extended key ID is supported
> 
> Yes. I have added checks in cfg80211_validate_key_settings current 
> development version already, making sure only valid combinations can be 
> called and reach this section.

Ok, great.

> NL80211_CMD_SET_KEY is normally only used to set default keys for wep or 
> managment keys. That changes here.

Right.

> In this API draft NL80211_CMD_NEW_KEY is only used when installing a 
> Extended Key ID key RX only. The switch to TX is added to 
> NL80211_CMD_SET_KEY. The code has some sanity checks and then tells the 
> driver to switch the key to tx.

Makes sense.

> But that has been changed quite a bit, the procedure in this patch 
> turned out to be not so good and even had a locking issue, so it has 
> changed a bit. I guess we should shelf that till I get the new variant 
> working and then look at it again.

Fair enough.

> > > +++ b/net/wireless/util.c
> > > @@ -236,13 +236,14 @@ int cfg80211_validate_key_settings(struct 
> > > cfg80211_registered_device *rdev,
> > >   case WLAN_CIPHER_SUITE_CCMP_256:
> > >   case WLAN_CIPHER_SUITE_GCMP:
> > >   case WLAN_CIPHER_SUITE_GCMP_256:
> > > - /* Disallow pairwise keys with non-zero index unless it's WEP
> > > + /* IEEE802.11-2016 allows only 0 and 1 for pairwise keys.
> > > +  * Disallow pairwise keys with index above 1 unless it's WEP
> > >* or a vendor specific cipher (because current 
> > > deployments use
> > > -  * pairwise WEP keys with non-zero indices and for vendor
> > > +  * pairwise WEP keys with higher indices and for vendor
> > >* specific ciphers this should be validated in the 
> > > driver or
> > > -  * hardware level - but 802.11i clearly specifies to use zero)
> > > +  * hardware level.
> > >*/
> > > - if (pairwise && key_idx)
> > > + if (pairwise && key_idx > 1)
> > >   return -EINVAL;
> > >   break;
> > 
> > Again, only if driver support is advertised, and the comment should
> > probably reference the feature bit from the spec.
> 
> That is where I added most of the sanity checks in the meantime.
> But what feature bit from the spec are you referring to? The RSN 
> Capability one?

Well, I wasn't thinking that precisely. I just thought it should mention
that it now says "IEEE802.11-2016 allows only 0 and 1 for pairwise keys"
but doesn't clarify that this is only for stations that actually want to
support it, so it could be read as being always that way.

johannes



Re: [RFC PATCH v2 1/2] nl80211/cfg80211: Add support for Extended Key ID

2018-12-05 Thread Alexander Wetzel

On Sun, 2018-11-11 at 12:02 +0100, Alexander Wetzel wrote:

Extend cfg80211 and nl80211 to allow pairwise keys to be installed for
RX only, allowing to switching over TX independently, as required by
IEEE-802.11-2016 to support "Extended Key ID for Individually Addressed
Frames"

PTK and STK keys are now also allowed to use Key ID 1.

Signed-off-by: Alexander Wetzel 
---
  include/net/cfg80211.h   |  2 ++
  include/uapi/linux/nl80211.h | 41 ++---
  net/wireless/nl80211.c   | 51 
  net/wireless/rdev-ops.h  |  3 ++-
  net/wireless/trace.h | 31 ++
  net/wireless/util.c  |  9 ---
  6 files changed, 119 insertions(+), 18 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 1fa41b7a1be3..0d59340563e0 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -485,6 +485,7 @@ struct vif_params {
   *with the get_key() callback, must be in little endian,
   *length given by @seq_len.
   * @seq_len: length of @seq.
+ * @flag: One flag from  key_params_flag


That should be nl80211_key_params_flag.

But if only one flag can be set, then maybe this should instead be

enum nl80211_key_install_mode install_mode;

or so?


It started out as a flag and I switched to enum later without updating 
it. I'll chnage that to nl80211_key_install_mode, much much better...



+/**
+ * enum key_params_flag - additional key flag for drivers
+ *
+ * Actions other than @NL80211_KEY_DEFAULT_RX_TX are only required from drivers
+ * supporting Extended Key ID for pairwise keys using keyid 0 or 1.
+ *
+ * @NL80211_KEY_DEFAULT_RX_TX: key can be immediately used for Rx and Tx
+ * @NL80211_KEY_RX_ONLY: key must be installed for Rx only
+ * @NL80211_KEY_SET_TX: switch Tx for sta to specified keyid
+ */
+enum key_params_flag {
+   NL80211_KEY_DEFAULT_RX_TX,
+   NL80211_KEY_RX_ONLY,
+   NL80211_KEY_SET_TX
+};


Clearly those aren't flags anyway.

I guess RX_ONLY and SET_TX are mostly needed AP-side?


No, all stations using Extended Key ID will always use RX_ONLY and 
SET_TX for pairwise key installs. The AP will install the Key Rx only 
prior to sending eapol #3, the sta prior to sending eapol #4.



+ * @NL80211_ATTR_KEY_RXONLY: Flag attribute to request RX key install only for
+ *  a pairwise key. Only supported for keyid's 0 and 1 when driver is
+ *  supporting Extended Key ID.
+ *
+ * @NL80211_ATTR_KEY_SETTX: Flag attribute to switch TX to a specified keyid.
+ *  Only supported for keyid's 0 and 1 when driver is supporting Extended
+ *  Key ID.


Ok, so you have these as separate netlink flags, but then you really
shouldn't also have the "install mode" in nl80211.h, that's not related
to userspace API then.

We might discuss instead having an NL80211_ATTR_INSTALL_MODE attribute,
and that takes the values from the enum, and then you do need the enum -
but if you don't need the enum then don't define it in nl80211.h but
keep it kernel-internal in cfg80211.h (and name it appropriately).

I may have mixed up mac80211 and nl80211 api and/or the correct include 
files..


The idea was, to have NL80211_ATTR_KEY_RXONLY, NL80211_ATTR_KEY_SETTX 
with the new API duplicates of NL80211_KEY_RXONLY and NL80211_KEY_SETTX 
for communication with the userspace and the enums ones in 
key_params_flag for communication with the drivers.


But unifying that with NL80211_ATTR_INSTALL_MODE attribute sounds like a 
good idea. I'll try to sanitize that.



@@ -4312,6 +4343,8 @@ enum nl80211_key_attributes {
NL80211_KEY_DEFAULT_MGMT,
NL80211_KEY_TYPE,
NL80211_KEY_DEFAULT_TYPES,
+   NL80211_KEY_RXONLY,
+   NL80211_KEY_SETTX,


Indeed if you have this, you don't need the corresponding top-level 
NL80211_ATTR_*?

We went through a few iterations with the API, so a lot of this is
backward compatibility stuff, you should update the latest version only.
I believe it's this one.

I did not think of that when writing the code, but came a bit late to 
the same conclusion... I'll drop the old API support.



- * @NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER: Driver supports enabling fine
- * timing measurement responder role.
- *
   * @NL80211_EXT_FEATURE_CAN_REPLACE_PTK0: Driver/device confirm that they are
   *  able to rekey an in-use key correctly. Userspace must not rekey PTK 
keys
   *  if this flag is not set. Ignoring this can leak clear text packets 
and/or
   *  freeze the connection.
+ * @NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER: Driver supports enabling fine
+ * timing measurement responder role.


What's going on here?



The PTK0 rekey patch added a new line in front of the description. The 
next author did not notice that and added the description for 
NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER at the wrong place, probably 
assuming it was the end of the list. I've noticed that and fixed the 
documentation order and the misleading 

Re: [RFC PATCH v2 2/2] mac80211: Add support for Extended Key ID

2018-12-05 Thread Alexander Wetzel

+ * @IEEE80211_KEY_FLAG_RX_ONLY: Set by mac80211 to indicate that the key
+ *  must not be used for TX (yet).


I'm not sure that's relevant, since you have one key pointer for TX?


+ * @IEEE80211_KEY_FLAG_SET_TX: Set by mac80211 to indicate that a previously
+ *  installed key with IEEE80211_KEY_FLAG_RX_ONLY should take over TX also.


That also doesn't seem relevant ...

Oh, all of this is for HW offloads?

I _think_ I would prefer to have new key ops instead. Now you'd have

SET_KEY / 
SET_KEY / RX_ONLY
SET_KEY / SET_TX

but I think maybe

SET_KEY
SET_KEY_RX_ONLY
KEY_ENABLE_TX

would make more sense?


Fine for me and should make it more understandable. So I'll try that.




+   if (pairwise && params->flag == NL80211_KEY_SET_TX) {
+   mutex_lock(>sta_mtx);
+   sta = sta_info_get_bss(sdata, mac_addr);
+
+   if (!sta ||
+  !(key = rcu_dereference(sta->ptk[key_idx])) ||


indentation here is off by one


Thanks.


+  !(key->conf.flags | IEEE80211_KEY_FLAG_RX_ONLY)) {


that makes no sense, should be & I guess


yes, I think that was one of the bugs I fixed the last weeks:-)



-   /* PTK only using key ID 0 needs special handling on rekey */
-   if (new_key && sta && ptk0rekey) {
+   /* PTK rekey without Extended Key ID needs special handling */
+   if (new_key && pairwise && sta &&
+   !test_sta_flag(sta, WLAN_STA_EXT_KEY_ID)) {
local = old_key->local;
sdata = old_key->sdata;


This seems wrong, even if you have ext key ID support and everything,
but you do 0 -> 0 rekeying, then you still need all the special handling
(in fact also then if you go 1->1!). So it seems you'd instead want to
see if you're going from a TX key to a TX key with the same key ID, and
then you don't need this flag at all.

The intention for Extended Key ID is, to have a comparable short time 
frame where both key IDs can be used. When replacing e.g. key ID 0 again 
it should be idle for a long time. I guess if someone starts re-keying 
in 1s intervals it may become an issue, but then anyone re-keying that 
often can't be helped...


With Extended Key IDs it's impossible to directly switch from a TX key 
with one key ID to another one with the same id.


1) Association
2) key ID 0 installed RX only
3) key Id 0 set_tx
4) rekey timeout passes
5) key ID 1 installed RX only
6) key ID 1 set_tx (also making key ID 0 RX only)
7) rekey timeout passes
8) key ID 0 replaced with new RX only key
9) key ID 0 set_tx
10) rekey timeout passes
...

So nobody will use the key being replaced, we don't have to protect 
against PN poisoning. And when a driver supports Extended Key ID we 
don't care about if the driver is able to rekey PTK0 correctly.




+++ b/net/mac80211/sta_info.c
@@ -350,6 +350,7 @@ struct sta_info *sta_info_alloc(struct 
ieee80211_sub_if_data *sdata,
sta->sta.max_rx_aggregation_subframes =
local->hw.max_rx_aggregation_subframes;
  
+	sta->ptk_idx = NUM_DEFAULT_KEYS - 1;


That makes no sense? Why should it be 3? That's invalid anyway?


Yes, that's the whole reason for that change:-) Setting it to 2 would 
also be fine, as long as it's not 0 or 1.


ieee80211_tx_h_select_key starts encrypting packets as soon as 
sta->ptk[tx->sta->ptk_idx] is not null.


So installing the first key as RX only will also activate the key for 
TX. the AP will therefore encrypt EAPOL #3 of the initial connect...


To avoid expensive run time checks I simply switched the default setting 
to make sure sta->ptk[tx->sta->ptk_idx] will be NULL at the initial key 
install.


Alexander







Re: [RFC PATCH v2 0/2] Extended Key ID support for linux

2018-12-05 Thread Alexander Wetzel

Hi,

Sorry for the delay.
No problem. That's hardly urgent:-)



On Sun, 2018-11-11 at 12:02 +0100, Alexander Wetzel wrote:

IEEE 802.11-2012 added support for Extended Key ID, allowing pairwise
keys to also use keyID 1 and moving group keys to IDs 2 and 3.


Where do you read this? I've always been under the impression that
individually and group addressed frames use key IDs from different
"namespaces", so to speak, where PTK/STK can use 0 (0 or 1 with
"Extended Key ID" support) and GTK can use 0-3.

In fact, the per-frame pseudocode in 802.11-2016 12.9.2.6 clearly
states:

if MPDU has individual RA then
lookup pairwise key using Key ID from MPDU
else
lookup group key using Key ID from MPDU
endif

If it weren't different namespaces, you'd not have to differentiate
here.



I was indeed struggling to understand what the intend of the standard is 
here. I may well be wrong, but the note in "12.6.1.1.10 Mesh GTKSA" 
tipped the scales to assume keyIDs are within one namespace only.


"Since Key ID 0 is reserved for individually addressed frame 
transmission, there are at most three available Key IDs (only two if 
extended Key IDs for individually addressed frames are in use), and the 
different MGTKs would contend for the single remaining Key ID upon 
rollover."


I got the impression Extended Key IDs were  added without updating all 
sections which should get updates. But the pattern is suspect, even the 
igtk numbers fit into the pattern:


 PTK 0 & 1
 GTK 1 & 2 & 3
iGTK 4 & 5

That may well be utterly wrong... Any idea how can we sort that out?


Support for Extended Key ID is basically completed and confirmed working
with both hwsim and "on the air" with ath9k/iwldvm using software
encryption and those patches here.


:)


Prior to propose this patch for merging I would like to get Extended
Key ID working with HW encryption for at least some devices, but after
experimenting with ath9k and to a lesser extend with ath10k it's now
clear that this will be an per-driver effort and it may well turn out to
be impossible without firmware updates.


Indeed. I think there might be some support with iwlwifi firmware, at
least newer versions? I can check later.


So I've decided to continue working on the HW support for now but also
ask you for feedback for what I got so far.


Sounds good.



I think I've solved the HW support issue, it looks like we'll be able to 
support Extended Key IDs with minimal changes to the drivers in a 
compatibility mode. It's basically working with iwldvm and ath9k but 
needs some more work.


Alexander


Re: [PATCH 2/2] mt76: dma: add rx buffer recycle support

2018-12-05 Thread Lorenzo Bianconi
> On Wed, Dec 05, 2018 at 11:37:33AM +0100, Lorenzo Bianconi wrote:
> > >
> > > Add support for recycling rx buffers if they are not forwarded
> > > to network stack instead of reallocate them from scratch
> > >
> > > Signed-off-by: Lorenzo Bianconi 
> > > ---
> > 
> > Felix,
> > 
> > could you please drop this patch since it does not help to reduce pressure
> > on page_frag_cache.
> 
> What is the problem ? Maybe using kmalloc() instead of page_frag_alloc()
> could help (kmalloc has standard kmem_cache for 2048 bytes object) ?

Hi Stanislaw,

I think the only difference in using a recycle buffer with page_frag_cache is
we are a little bit less greedy in consuming the compound page since in case of
error we will reuse the previously allocated fragment. However we will need to
reallocate a new compound page if we have a leftover fragment that 'locks'
the previous compound (we have the same issue if we do not use the recycle
buffer). Does this 'little' improvement worth a more complex code?
Do you agree or is there something I am missing here?

Regards,
Lorenzo

> 
> Thanks
> Stanislaw


Re: [RFC PATCH v2 2/2] mac80211: Add support for Extended Key ID

2018-12-05 Thread Johannes Berg


> + * @IEEE80211_KEY_FLAG_RX_ONLY: Set by mac80211 to indicate that the key
> + *  must not be used for TX (yet).

I'm not sure that's relevant, since you have one key pointer for TX?

> + * @IEEE80211_KEY_FLAG_SET_TX: Set by mac80211 to indicate that a previously
> + *  installed key with IEEE80211_KEY_FLAG_RX_ONLY should take over TX 
> also.

That also doesn't seem relevant ...

Oh, all of this is for HW offloads?

I _think_ I would prefer to have new key ops instead. Now you'd have 

SET_KEY / 
SET_KEY / RX_ONLY
SET_KEY / SET_TX

but I think maybe

SET_KEY
SET_KEY_RX_ONLY
KEY_ENABLE_TX

would make more sense?

> + if (pairwise && params->flag == NL80211_KEY_SET_TX) {
> + mutex_lock(>sta_mtx);
> + sta = sta_info_get_bss(sdata, mac_addr);
> +
> + if (!sta ||
> +!(key = rcu_dereference(sta->ptk[key_idx])) ||

indentation here is off by one

> +!(key->conf.flags | IEEE80211_KEY_FLAG_RX_ONLY)) {

that makes no sense, should be & I guess

> - /* PTK only using key ID 0 needs special handling on rekey */
> - if (new_key && sta && ptk0rekey) {
> + /* PTK rekey without Extended Key ID needs special handling */
> + if (new_key && pairwise && sta &&
> + !test_sta_flag(sta, WLAN_STA_EXT_KEY_ID)) {
>   local = old_key->local;
>   sdata = old_key->sdata;

This seems wrong, even if you have ext key ID support and everything,
but you do 0 -> 0 rekeying, then you still need all the special handling
(in fact also then if you go 1->1!). So it seems you'd instead want to
see if you're going from a TX key to a TX key with the same key ID, and
then you don't need this flag at all.

> +++ b/net/mac80211/sta_info.c
> @@ -350,6 +350,7 @@ struct sta_info *sta_info_alloc(struct 
> ieee80211_sub_if_data *sdata,
>   sta->sta.max_rx_aggregation_subframes =
>   local->hw.max_rx_aggregation_subframes;
>  
> + sta->ptk_idx = NUM_DEFAULT_KEYS - 1;

That makes no sense? Why should it be 3? That's invalid anyway?

johannes



Re: [RFC PATCH v2 1/2] nl80211/cfg80211: Add support for Extended Key ID

2018-12-05 Thread Johannes Berg
On Sun, 2018-11-11 at 12:02 +0100, Alexander Wetzel wrote:
> Extend cfg80211 and nl80211 to allow pairwise keys to be installed for
> RX only, allowing to switching over TX independently, as required by
> IEEE-802.11-2016 to support "Extended Key ID for Individually Addressed
> Frames"
> 
> PTK and STK keys are now also allowed to use Key ID 1.
> 
> Signed-off-by: Alexander Wetzel 
> ---
>  include/net/cfg80211.h   |  2 ++
>  include/uapi/linux/nl80211.h | 41 ++---
>  net/wireless/nl80211.c   | 51 
>  net/wireless/rdev-ops.h  |  3 ++-
>  net/wireless/trace.h | 31 ++
>  net/wireless/util.c  |  9 ---
>  6 files changed, 119 insertions(+), 18 deletions(-)
> 
> diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
> index 1fa41b7a1be3..0d59340563e0 100644
> --- a/include/net/cfg80211.h
> +++ b/include/net/cfg80211.h
> @@ -485,6 +485,7 @@ struct vif_params {
>   *   with the get_key() callback, must be in little endian,
>   *   length given by @seq_len.
>   * @seq_len: length of @seq.
> + * @flag: One flag from  key_params_flag

That should be nl80211_key_params_flag.

But if only one flag can be set, then maybe this should instead be

enum nl80211_key_install_mode install_mode;

or so?
> +/**
> + * enum key_params_flag - additional key flag for drivers
> + *
> + * Actions other than @NL80211_KEY_DEFAULT_RX_TX are only required from 
> drivers
> + * supporting Extended Key ID for pairwise keys using keyid 0 or 1.
> + *
> + * @NL80211_KEY_DEFAULT_RX_TX: key can be immediately used for Rx and Tx
> + * @NL80211_KEY_RX_ONLY: key must be installed for Rx only
> + * @NL80211_KEY_SET_TX: switch Tx for sta to specified keyid
> + */
> +enum key_params_flag {
> + NL80211_KEY_DEFAULT_RX_TX,
> + NL80211_KEY_RX_ONLY,
> + NL80211_KEY_SET_TX
> +};

Clearly those aren't flags anyway.

I guess RX_ONLY and SET_TX are mostly needed AP-side?


> + * @NL80211_ATTR_KEY_RXONLY: Flag attribute to request RX key install only 
> for
> + *  a pairwise key. Only supported for keyid's 0 and 1 when driver is
> + *  supporting Extended Key ID.
> + *
> + * @NL80211_ATTR_KEY_SETTX: Flag attribute to switch TX to a specified keyid.
> + *  Only supported for keyid's 0 and 1 when driver is supporting Extended
> + *  Key ID.

Ok, so you have these as separate netlink flags, but then you really
shouldn't also have the "install mode" in nl80211.h, that's not related
to userspace API then.

We might discuss instead having an NL80211_ATTR_INSTALL_MODE attribute,
and that takes the values from the enum, and then you do need the enum -
but if you don't need the enum then don't define it in nl80211.h but
keep it kernel-internal in cfg80211.h (and name it appropriately).

> @@ -4312,6 +4343,8 @@ enum nl80211_key_attributes {
>   NL80211_KEY_DEFAULT_MGMT,
>   NL80211_KEY_TYPE,
>   NL80211_KEY_DEFAULT_TYPES,
> + NL80211_KEY_RXONLY,
> + NL80211_KEY_SETTX,

Indeed if you have this, you don't need the corresponding top-level 
NL80211_ATTR_*?

We went through a few iterations with the API, so a lot of this is
backward compatibility stuff, you should update the latest version only.
I believe it's this one.

> - * @NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER: Driver supports enabling fine
> - *   timing measurement responder role.
> - *
>   * @NL80211_EXT_FEATURE_CAN_REPLACE_PTK0: Driver/device confirm that they are
>   *  able to rekey an in-use key correctly. Userspace must not rekey PTK 
> keys
>   *  if this flag is not set. Ignoring this can leak clear text packets 
> and/or
>   *  freeze the connection.
> + * @NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER: Driver supports enabling fine
> + *   timing measurement responder role.

What's going on here?

> @@ -945,6 +960,16 @@ static int nl80211_parse_key_old(struct genl_info *info, 
> struct key_parse *k)
>   if (k->defmgmt)

Yeah, just don't change parse_key_old, whoever wants to use this stuff
should upgrade to the new API. wpa_s has both IIRC, but of course the
old-side is ignored on newer kernels (and the new on older) so the older
stuff never needs new features.

>   k->def_multi = true;
>  
> + k->rx_only = !!info->attrs[NL80211_ATTR_KEY_RXONLY];
> + k->set_tx = !!info->attrs[NL80211_ATTR_KEY_SETTX];

shouldn't this already be install_mode?

> + /* only support setting default key and
> +  * Extended Key ID action NL80211_KEY_SET_TX */
> + if (!key.def && !key.defmgmt && !key.set_tx)
>   return -EINVAL;

You need to check if extended key ID is supported

> - }
> + } else if (wiphy_ext_feature_isset(>wiphy,
> +NL80211_EXT_FEATURE_EXT_KEY_ID)) {
> + if (info->attrs[NL80211_ATTR_MAC])
> + mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
>  
> + if (!mac_addr || key.idx < 0 || key.idx > 1) {
> +

Re: [RFC PATCH v2 0/2] Extended Key ID support for linux

2018-12-05 Thread Johannes Berg
Hi,

Sorry for the delay.

On Sun, 2018-11-11 at 12:02 +0100, Alexander Wetzel wrote:
> IEEE 802.11-2012 added support for Extended Key ID, allowing pairwise
> keys to also use keyID 1 and moving group keys to IDs 2 and 3.

Where do you read this? I've always been under the impression that
individually and group addressed frames use key IDs from different
"namespaces", so to speak, where PTK/STK can use 0 (0 or 1 with
"Extended Key ID" support) and GTK can use 0-3.

In fact, the per-frame pseudocode in 802.11-2016 12.9.2.6 clearly
states:

if MPDU has individual RA then
lookup pairwise key using Key ID from MPDU
else
lookup group key using Key ID from MPDU
endif

If it weren't different namespaces, you'd not have to differentiate
here.

> Support for Extended Key ID is basically completed and confirmed working
> with both hwsim and "on the air" with ath9k/iwldvm using software
> encryption and those patches here.

:)

> Prior to propose this patch for merging I would like to get Extended
> Key ID working with HW encryption for at least some devices, but after
> experimenting with ath9k and to a lesser extend with ath10k it's now
> clear that this will be an per-driver effort and it may well turn out to
> be impossible without firmware updates.

Indeed. I think there might be some support with iwlwifi firmware, at
least newer versions? I can check later.

> So I've decided to continue working on the HW support for now but also
> ask you for feedback for what I got so far. 

Sounds good.

> Any feedback is welcome and I especially like to learn what you think of
> the API extensions and what has to be changed to get it merged.

I'll look over the individual patches.

johannes



Re: [PATCH 2/2] mt76: dma: add rx buffer recycle support

2018-12-05 Thread Stanislaw Gruszka
On Wed, Dec 05, 2018 at 11:37:33AM +0100, Lorenzo Bianconi wrote:
> >
> > Add support for recycling rx buffers if they are not forwarded
> > to network stack instead of reallocate them from scratch
> >
> > Signed-off-by: Lorenzo Bianconi 
> > ---
> 
> Felix,
> 
> could you please drop this patch since it does not help to reduce pressure
> on page_frag_cache.

What is the problem ? Maybe using kmalloc() instead of page_frag_alloc()
could help (kmalloc has standard kmem_cache for 2048 bytes object) ?

Thanks
Stanislaw


[PATCH] cfg80211: Fix busy loop regression in ieee80211_ie_split_ric()

2018-12-05 Thread Jouni Malinen
This function was modified to support the information element extension
case (WLAN_EID_EXTENSION) in a manner that would result in an infinite
loop when going through set of IEs that include WLAN_EID_RIC_DATA and
contain an IE that is in the after_ric array. The only place where this
can currently happen is in mac80211 ieee80211_send_assoc() where
ieee80211_ie_split_ric() is called with after_ric[].

This can be triggered by valid data from user space nl80211
association/connect request (i.e., requiring GENL_UNS_ADMIN_PERM). The
only known application having an option to include WLAN_EID_RIC_DATA in
these requests is wpa_supplicant and it had a bug that prevented this
specific contents from being used (and because of that, not triggering
this kernel bug in an automated test case ap_ft_ric) and now that this
bug is fixed, it has a workaround to avoid this kernel issue.
WLAN_EID_RIC_DATA is currently used only for testing purposes, so this
does not cause significant harm for production use cases.

Fixes: 2512b1b18d07 ("mac80211: extend ieee80211_ie_split to support EXTENSION")
Signed-off-by: Jouni Malinen 
---
 net/wireless/util.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/net/wireless/util.c b/net/wireless/util.c
index ef14d80..d473bd1 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -1421,6 +1421,8 @@ size_t ieee80211_ie_split_ric(const u8 *ies, size_t ielen,
  ies[pos + ext],
  ext == 2))
pos = skip_ie(ies, ielen, pos);
+   else
+   break;
}
} else {
pos = skip_ie(ies, ielen, pos);
-- 
2.7.4



Re: [PATCH 2/2] mt76: dma: add rx buffer recycle support

2018-12-05 Thread Lorenzo Bianconi
>
> Add support for recycling rx buffers if they are not forwarded
> to network stack instead of reallocate them from scratch
>
> Signed-off-by: Lorenzo Bianconi 
> ---

Felix,

could you please drop this patch since it does not help to reduce pressure
on page_frag_cache.

Regards,
Lorenzo


Re: pull request: mt76 2018-11-30

2018-12-05 Thread Lorenzo Bianconi
> Felix Fietkau  writes:
>
> > here's my first pull request for 4.21
> >
> > - Felix
> >
> > The following changes since commit b72c51a58e6d63ef673ac96b8ab5bc98799c5f7b:
> >
> >   brcmfmac: Fix out of bounds memory access during fw load (2018-11-29 
> > 17:33:10 +0200)
> >
> > are available in the Git repository at:
> >
> >   https://github.com/nbd168/wireless tags/mt76-for-kvalo-2018-11-30
> >
> > for you to fetch changes up to e28487ea84a9c081c6d8d7da319427f7fcc32ff5:
> >
> >   mt76: replace sta_add/remove ops with common sta_state function 
> > (2018-11-30 12:30:37 +0100)
> >
> > 
> > first batch of mt76 patches for 4.21
> >
> > * use the same firmware for mt76x2e and mt76x2u
> > * mt76x2 fixes
> > * mt76x0 fixes
> > * mt76x0e survey support
> > * more unification between mt76x2 and mt76x0
> > * mt76x0e AP mode support
> > * mt76x0e DFS support
> > * rework and fix tx status handling for mt76x0 and mt76x2
> >
> > 
>
> I fast forwarded w-d-next to net-next and now there's a conflict. I did
> a test merge in the pending branch, please double check:
>
> https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next.git/commit/?h=pending=e69caab09bf98d0d8b559d06887364cc0090097c
>

ack

> This was the conflict:
>
> diff --cc drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c
> index 3f001bd6806c,b54a32397486..
> --- a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c
> @@@ -264,21 -173,6 +173,24 @@@ static int mt76x2_get_antenna(struct ie
> return 0;
>   }
>
> ++<<< HEAD
>  +static int
>  +mt76x2_set_rts_threshold(struct ieee80211_hw *hw, u32 val)
>  +{
>  +  struct mt76x02_dev *dev = hw->priv;
>  +
>  +  if (val != ~0 && val > 0x)
>  +  return -EINVAL;
>  +
>  +  mutex_lock(>mt76.mutex);
>  +  mt76x2_mac_set_tx_protection(dev, val);
>  +  mutex_unlock(>mt76.mutex);
>  +
>  +  return 0;
>  +}
>  +
> ++===
> ++>>> 1b0adb0ab8649a1ed44f9840724878cffaaa6896
>   const struct ieee80211_ops mt76x2_ops = {
> .tx = mt76x02_tx,
> .start = mt76x2_start,
>
> I solved it by removing mt76x2_set_rts_threshold(). After there was also
> a compilation error which I fixed like this:

correct, mt76x2_set_rts_threshold has been moved to mt76x02_util.c

>
> diff --cc drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c
> index 3f001bd6806c,b54a32397486..
> --- a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c 
> b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
> index 3a70e5bf7d42..38bd466cff16 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
> @@ -462,9 +462,9 @@ int mt76x02_set_rts_threshold(struct ieee80211_hw *hw, 
> u32 val)
> if (val != ~0 && val > 0x)
> return -EINVAL;
>
> -   mutex_lock(>mutex);
> +   mutex_lock(>mt76.mutex);
> mt76x02_mac_set_tx_protection(dev, val);
> -   mutex_unlock(>mutex);
> +   mutex_unlock(>mt76.mutex);
>
> return 0;
>  }

correct

Regards,
Lorenzo

>
> --
> Kalle Valo

-- 
UNIX is Sexy: who | grep -i blonde | talk; cd ~; wine; talk; touch;
unzip; touch; strip; gasp; finger; gasp; mount; fsck; more; yes; gasp;
umount; make clean; sleep


Re: [PATCH 00/29] staging: wilc1000: avoid deferring of cfg80211 operation callback

2018-12-05 Thread Greg KH
On Sun, Dec 02, 2018 at 06:02:13PM +, ajay.kat...@microchip.com wrote:
>  6 files changed, 755 insertions(+), 2012 deletions(-)

Nice code removal, patch series all now applied.

greg k-h


NXP NFC version and ACPI

2018-12-04 Thread Daniel Lezcano


Hi,

the discussion reference is on github [1].

I acquired a Lenovo x280 with a NFC chip. It is unclear what chip is it
really, it is called NXP NPC300 which could be a PN7xxx chip range.

A hacked version of an old deprecated out-of-tree module made the PN5xxx
to work with my laptop but I suspect it brought some subtle instability
on my system.

Now it would be nice to have this correctly supported upstream.

I dumped the ACPI DSDT table and got the id NXP1001. This one is not
listed in the match table of the nxp-nci driver.

 - is the driver missing for the so called NXP NPC300 ?
 - should the NXP1001 matching string to be added to nxp-nci?
 - is my firmware sending me garbage ?

Thanks in advance for any input

  -- Daniel


-- 
  Linaro.org │ Open source software for ARM SoCs

Follow Linaro:   Facebook |
 Twitter |
 Blog



Re: pull request: mt76 2018-11-30

2018-12-04 Thread Kalle Valo
Felix Fietkau  writes:

> here's my first pull request for 4.21
>
> - Felix
>
> The following changes since commit b72c51a58e6d63ef673ac96b8ab5bc98799c5f7b:
>
>   brcmfmac: Fix out of bounds memory access during fw load (2018-11-29 
> 17:33:10 +0200)
>
> are available in the Git repository at:
>
>   https://github.com/nbd168/wireless tags/mt76-for-kvalo-2018-11-30
>
> for you to fetch changes up to e28487ea84a9c081c6d8d7da319427f7fcc32ff5:
>
>   mt76: replace sta_add/remove ops with common sta_state function (2018-11-30 
> 12:30:37 +0100)
>
> 
> first batch of mt76 patches for 4.21
>
> * use the same firmware for mt76x2e and mt76x2u
> * mt76x2 fixes
> * mt76x0 fixes
> * mt76x0e survey support
> * more unification between mt76x2 and mt76x0
> * mt76x0e AP mode support
> * mt76x0e DFS support
> * rework and fix tx status handling for mt76x0 and mt76x2
>
> 

I fast forwarded w-d-next to net-next and now there's a conflict. I did
a test merge in the pending branch, please double check:

https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next.git/commit/?h=pending=e69caab09bf98d0d8b559d06887364cc0090097c

This was the conflict:

diff --cc drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c
index 3f001bd6806c,b54a32397486..
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c
@@@ -264,21 -173,6 +173,24 @@@ static int mt76x2_get_antenna(struct ie
return 0;
  }
  
++<<< HEAD
 +static int
 +mt76x2_set_rts_threshold(struct ieee80211_hw *hw, u32 val)
 +{
 +  struct mt76x02_dev *dev = hw->priv;
 +
 +  if (val != ~0 && val > 0x)
 +  return -EINVAL;
 +
 +  mutex_lock(>mt76.mutex);
 +  mt76x2_mac_set_tx_protection(dev, val);
 +  mutex_unlock(>mt76.mutex);
 +
 +  return 0;
 +}
 +
++===
++>>> 1b0adb0ab8649a1ed44f9840724878cffaaa6896
  const struct ieee80211_ops mt76x2_ops = {
.tx = mt76x02_tx,
.start = mt76x2_start,

I solved it by removing mt76x2_set_rts_threshold(). After there was also
a compilation error which I fixed like this:

diff --cc drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c
index 3f001bd6806c,b54a32397486..
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
index 3a70e5bf7d42..38bd466cff16 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
@@ -462,9 +462,9 @@ int mt76x02_set_rts_threshold(struct ieee80211_hw *hw, u32 
val)
if (val != ~0 && val > 0x)
return -EINVAL;
 
-   mutex_lock(>mutex);
+   mutex_lock(>mt76.mutex);
mt76x02_mac_set_tx_protection(dev, val);
-   mutex_unlock(>mutex);
+   mutex_unlock(>mt76.mutex);
 
return 0;
 }

-- 
Kalle Valo


[PATCH wireless-drivers] brcmfmac: fix roamoff=1 modparam

2018-12-04 Thread Stijn Tintel
When the update_connect_param callback is set, nl80211 expects the flag
WIPHY_FLAG_SUPPORTS_FW_ROAM to be set as well. However, this flag is
only set when modparam roamoff=0, while the callback is set
unconditionally. Since commit 7f9a3e150ec7 this causes a warning in
wiphy_register, which breaks brcmfmac.

Disable the update_connect_param callback when roamoff=0 to fix this.

Fixes: 7f9a3e150ec7 ("nl80211: Update ERP info using 
NL80211_CMD_UPDATE_CONNECT_PARAMS")
Cc: Stable  # 4.19+
Signed-off-by: Jonas Gorski 
Signed-off-by: Stijn Tintel 
---
 .../wireless/broadcom/brcm80211/brcmfmac/cfg80211.c   | 11 +--
 .../wireless/broadcom/brcm80211/brcmfmac/cfg80211.h   |  2 +-
 .../net/wireless/broadcom/brcm80211/brcmfmac/core.c   |  2 +-
 3 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index 7f0a5bade70a..c0e3ae7bf2ae 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -5196,10 +5196,17 @@ static struct cfg80211_ops brcmf_cfg80211_ops = {
.del_pmk = brcmf_cfg80211_del_pmk,
 };
 
-struct cfg80211_ops *brcmf_cfg80211_get_ops(void)
+struct cfg80211_ops *brcmf_cfg80211_get_ops(struct brcmf_mp_device *settings)
 {
-   return kmemdup(_cfg80211_ops, sizeof(brcmf_cfg80211_ops),
+   struct cfg80211_ops *ops;
+
+   ops = kmemdup(_cfg80211_ops, sizeof(brcmf_cfg80211_ops),
   GFP_KERNEL);
+
+   if (ops && settings->roamoff)
+   ops->update_connect_params = NULL;
+
+   return ops;
 }
 
 struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
index a4aec0004e4f..9a6287f084a9 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
@@ -404,7 +404,7 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct 
brcmf_pub *drvr,
 void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg);
 s32 brcmf_cfg80211_up(struct net_device *ndev);
 s32 brcmf_cfg80211_down(struct net_device *ndev);
-struct cfg80211_ops *brcmf_cfg80211_get_ops(void);
+struct cfg80211_ops *brcmf_cfg80211_get_ops(struct brcmf_mp_device *settings);
 enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp);
 
 struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
index b1f702faff4f..860a4372cb56 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
@@ -1130,7 +1130,7 @@ int brcmf_attach(struct device *dev, struct 
brcmf_mp_device *settings)
 
brcmf_dbg(TRACE, "Enter\n");
 
-   ops = brcmf_cfg80211_get_ops();
+   ops = brcmf_cfg80211_get_ops(settings);
if (!ops)
return -ENOMEM;
 
-- 
2.18.1



Re: [PATCH] mac80211: rewrite Kconfig text for mesh

2018-12-04 Thread Steve deRosier
On Tue, Dec 4, 2018 at 7:25 AM Bob Copeland  wrote:
>
> Lubomir Rintel recently pointed out a dead link for o11s.org, and
> repointed it to a still live, but also stale website.  As far as I
> know, no one is updating the content at open80211s.org.
>

Indeed.  The o11s effort more or less ended after cozybit finished
writing and upstreamed the mesh code. A little maintenance and changes
happened via o11s until the 802.11s stuff was ratified, in, stable,
etc...  including by me and others at cozybit. You are correct -
AFAIK, no one is updating that site, o11s.org is down and actually
cozybit as an entity is no more either. And all of us are long
elsewhere.

> Since this Kconfig text was originally written, though, the 802.11s
> mesh drafts were approved and ultimately rolled into 802.11 proper.
> Meanwhile, the implementation has converged on the final standard,
> so we can lose all of the text here and provide something that's a
> little more helpful and accurate.
>
> Signed-off-by: Bob Copeland 
> ---
>  net/mac80211/Kconfig | 11 +--
>  1 file changed, 5 insertions(+), 6 deletions(-)
>
> diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig
> index f869e35d0974..6b09355dfc90 100644
> --- a/net/mac80211/Kconfig
> +++ b/net/mac80211/Kconfig
> @@ -57,14 +57,13 @@ comment "Some wireless drivers require a rate control 
> algorithm"
> depends on MAC80211 && MAC80211_HAS_RC=n
>
>  config MAC80211_MESH
> -   bool "Enable mac80211 mesh networking (pre-802.11s) support"
> +   bool "Enable mac80211 mesh networking support"
> depends on MAC80211
> ---help---
> -This options enables support of Draft 802.11s mesh networking.
> -The implementation is based on Draft 2.08 of the Mesh Networking
> -amendment.  However, no compliance with that draft is claimed or even
> -possible, as drafts leave a number of identifiers to be defined after
> -ratification.  For more information visit http://o11s.org/.
> + Select this option to enable 802.11 mesh operation in mac80211
> + drivers that support it.  802.11 mesh connects multiple stations
> + over (possibly multi-hop) wireless links to form a single logical
> + LAN.
>

Looks good to me.

Reviewed-by: Steve deRosier 

- Steve


Re: [PATCH] mac80211: rewrite Kconfig text for mesh

2018-12-04 Thread Lubomir Rintel
On Tue, 2018-12-04 at 10:22 -0500, Bob Copeland wrote:
> Lubomir Rintel recently pointed out a dead link for o11s.org, and
> repointed it to a still live, but also stale website.  As far as I
> know, no one is updating the content at open80211s.org.
> 
> Since this Kconfig text was originally written, though, the 802.11s
> mesh drafts were approved and ultimately rolled into 802.11 proper.
> Meanwhile, the implementation has converged on the final standard,
> so we can lose all of the text here and provide something that's a
> little more helpful and accurate.
> 
> Signed-off-by: Bob Copeland 

Thanks. The old text indeed fooled me into thinking that only some pre-
release version of the spec is implemented. It looks better now.

Reviewed-by: Lubomir Rintel 

> ---
>  net/mac80211/Kconfig | 11 +--
>  1 file changed, 5 insertions(+), 6 deletions(-)
> 
> diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig
> index f869e35d0974..6b09355dfc90 100644
> --- a/net/mac80211/Kconfig
> +++ b/net/mac80211/Kconfig
> @@ -57,14 +57,13 @@ comment "Some wireless drivers require a rate control 
> algorithm"
>   depends on MAC80211 && MAC80211_HAS_RC=n
>  
>  config MAC80211_MESH
> - bool "Enable mac80211 mesh networking (pre-802.11s) support"
> + bool "Enable mac80211 mesh networking support"
>   depends on MAC80211
>   ---help---
> -  This options enables support of Draft 802.11s mesh networking.
> -  The implementation is based on Draft 2.08 of the Mesh Networking
> -  amendment.  However, no compliance with that draft is claimed or even
> -  possible, as drafts leave a number of identifiers to be defined after
> -  ratification.  For more information visit http://o11s.org/.
> +   Select this option to enable 802.11 mesh operation in mac80211
> +   drivers that support it.  802.11 mesh connects multiple stations
> +   over (possibly multi-hop) wireless links to form a single logical
> +   LAN.
>  
>  config MAC80211_LEDS
>   bool "Enable LED triggers"



Re: [PATCH] wireless-regdb: add URLs in README

2018-12-04 Thread Seth Forshee
On Fri, Nov 09, 2018 at 06:10:03PM +0100, Xose Vazquez Perez wrote:
> Cc: Seth Forshee 
> Cc: WIRELESS ML 
> Cc: REGDB ML 
> Signed-off-by: Xose Vazquez Perez 

Applied, thanks!


Re: [PATCH] wireless-regdb: delete outdated comment for DE

2018-12-04 Thread Seth Forshee
On Fri, Nov 09, 2018 at 11:24:20AM +0100, Xose Vazquez Perez wrote:
> d46d731c made it obsolete.
> 
> Cc: Sven Eckelmann 
> Cc: Seth Forshee 
> Cc: WIRELESS ML 
> Cc: REGDB ML 
> Signed-off-by: Xose Vazquez Perez 

Applied, thanks!


[PATCH] mac80211: rewrite Kconfig text for mesh

2018-12-04 Thread Bob Copeland
Lubomir Rintel recently pointed out a dead link for o11s.org, and
repointed it to a still live, but also stale website.  As far as I
know, no one is updating the content at open80211s.org.

Since this Kconfig text was originally written, though, the 802.11s
mesh drafts were approved and ultimately rolled into 802.11 proper.
Meanwhile, the implementation has converged on the final standard,
so we can lose all of the text here and provide something that's a
little more helpful and accurate.

Signed-off-by: Bob Copeland 
---
 net/mac80211/Kconfig | 11 +--
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig
index f869e35d0974..6b09355dfc90 100644
--- a/net/mac80211/Kconfig
+++ b/net/mac80211/Kconfig
@@ -57,14 +57,13 @@ comment "Some wireless drivers require a rate control 
algorithm"
depends on MAC80211 && MAC80211_HAS_RC=n
 
 config MAC80211_MESH
-   bool "Enable mac80211 mesh networking (pre-802.11s) support"
+   bool "Enable mac80211 mesh networking support"
depends on MAC80211
---help---
-This options enables support of Draft 802.11s mesh networking.
-The implementation is based on Draft 2.08 of the Mesh Networking
-amendment.  However, no compliance with that draft is claimed or even
-possible, as drafts leave a number of identifiers to be defined after
-ratification.  For more information visit http://o11s.org/.
+ Select this option to enable 802.11 mesh operation in mac80211
+ drivers that support it.  802.11 mesh connects multiple stations
+ over (possibly multi-hop) wireless links to form a single logical
+ LAN.
 
 config MAC80211_LEDS
bool "Enable LED triggers"
-- 
2.11.0



[PATCH v2] nl80211: Add support to notify radar event info received from STA

2018-12-04 Thread Sriram R
Currently radar detection and corresponding channel switch is handled
at the AP device. STA ignores these detected radar events since the
radar signal can be seen mostly by the AP as well. But in scenarios where
a radar signal is seen only at STA, notifying this event to the AP which
can trigger a channel switch can be useful.
Stations can report such radar events autonomously through Spectrum
management (Measurement Report) action frame to its AP. The userspace on
processing the report can notify the kernel with the use of the added
NL80211_CMD_NOTIFY_RADAR to indicate the detected event and inturn adding
the reported channel to NOL.

Signed-off-by: Sriram R 
---

v2:
 - Added netlink error info
 - Return success if the radar event was already processed

 include/uapi/linux/nl80211.h |  7 +
 net/wireless/nl80211.c   | 62 
 2 files changed, 69 insertions(+)

diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 51bd85b..8ff5d2a 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -1060,6 +1060,11 @@
  * the measurement completed, using the measurement cookie
  * (%NL80211_ATTR_COOKIE).
  *
+ * @NL80211_CMD_NOTIFY_RADAR: Notify the kernel that a radar signal was
+ * detected and reported by a neighboring device on the channel
+ * indicated by %NL80211_ATTR_WIPHY_FREQ and other attributes
+ * determining the width and type.
+ *
  * @NL80211_CMD_MAX: highest used command number
  * @__NL80211_CMD_AFTER_LAST: internal use
  */
@@ -1278,6 +1283,8 @@ enum nl80211_commands {
NL80211_CMD_PEER_MEASUREMENT_RESULT,
NL80211_CMD_PEER_MEASUREMENT_COMPLETE,
 
+   NL80211_CMD_NOTIFY_RADAR,
+
/* add new commands above here */
 
/* used to define NL80211_CMD_MAX below */
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 5ec200e..f593498 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -7981,6 +7981,60 @@ static int nl80211_start_radar_detection(struct sk_buff 
*skb,
return err;
 }
 
+static int nl80211_notify_radar_detection(struct sk_buff *skb,
+ struct genl_info *info)
+{
+   struct cfg80211_registered_device *rdev = info->user_ptr[0];
+   struct net_device *dev = info->user_ptr[1];
+   struct wireless_dev *wdev = dev->ieee80211_ptr;
+   struct wiphy *wiphy = wdev->wiphy;
+   struct cfg80211_chan_def chandef;
+   enum nl80211_dfs_regions dfs_region;
+   int err;
+
+   dfs_region = reg_get_dfs_region(wiphy);
+   if (dfs_region == NL80211_DFS_UNSET) {
+   GENL_SET_ERR_MSG(info,
+"DFS Region is not set. Unexpected Radar 
indication");
+   return -EINVAL;
+   }
+
+   err = nl80211_parse_chandef(rdev, info, );
+   if (err) {
+   GENL_SET_ERR_MSG(info, "Unable to extract chandef info");
+   return err;
+   }
+
+   err = cfg80211_chandef_dfs_required(wiphy, , wdev->iftype);
+   if (err < 0) {
+   GENL_SET_ERR_MSG(info, "chandef is invalid");
+   return err;
+   }
+
+   if (err == 0) {
+   GENL_SET_ERR_MSG(info,
+"Unexpected Radar indication for 
chandef/iftype");
+   return -EINVAL;
+   }
+
+   /* Do not process this notification if radar is already detected
+* by kernel on this channel, and return success.
+*/
+   if (chandef.chan->dfs_state == NL80211_DFS_UNAVAILABLE)
+   return 0;
+
+   cfg80211_set_dfs_state(wiphy, , NL80211_DFS_UNAVAILABLE);
+
+   cfg80211_sched_dfs_chan_update(rdev);
+
+   memcpy(>radar_chandef, , sizeof(chandef));
+
+   /* Propagate this notification to other radios as well */
+   queue_work(cfg80211_wq, >propagate_radar_detect_wk);
+
+   return 0;
+}
+
 static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info)
 {
struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -14066,6 +14120,14 @@ static const struct genl_ops nl80211_ops[] = {
.internal_flags = NL80211_FLAG_NEED_WDEV_UP |
  NL80211_FLAG_NEED_RTNL,
},
+   {
+   .cmd = NL80211_CMD_NOTIFY_RADAR,
+   .doit = nl80211_notify_radar_detection,
+   .policy = nl80211_policy,
+   .flags = GENL_UNS_ADMIN_PERM,
+   .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+ NL80211_FLAG_NEED_RTNL,
+   },
 };
 
 static struct genl_family nl80211_fam __ro_after_init = {
-- 
2.7.4



Re: [RFC/RFT 3/4] mt76x02: do not set protection on set_rts_threshold callback

2018-12-04 Thread Stanislaw Gruszka
On Tue, Dec 04, 2018 at 11:45:09AM +0100, Stanislaw Gruszka wrote:

> Only OFDM_PROT_CFG is configured there based on legacy proto
> value. I'm not sure how handle CCK_PROT_CFG.
> 
> > > - mt76_rmw(dev, MT_MM20_PROT_CFG,
> > > -  MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);
> > > - mt76_rmw(dev, MT_MM40_PROT_CFG,
> > > -  MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);
> > > - mt76_rmw(dev, MT_GF20_PROT_CFG,
> > > -  MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);
> > > - mt76_rmw(dev, MT_GF40_PROT_CFG,
> > > -  MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);
> > > - mt76_rmw(dev, MT_TX_PROT_CFG6,
> > > -  MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);
> > > - mt76_rmw(dev, MT_TX_PROT_CFG7,
> > > -  MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);
> > > - mt76_rmw(dev, MT_TX_PROT_CFG8,
> > > -  MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);
> > 
> > Removing these lines we are no longer able to configure protection for VHT
> > rates. Do we have an equivalent for them in vht_capab?
> 
> Actually it's not based on HT capabilities but by on ht operation and
> it's modified dynamically by hostapd based on what stations are
> associated. For STA mode it's provided by remote AP via HT operation IE.
> 
> VHT Operation IE do not define protection. Seems interoperability with
> legacy STA's is not allowed for VHT, so leaving default values from
> initvals where PROT bits are 0 (none protection) is right thing to do.

But vendor driver change the VHT protection bits based on HT
operation element, with the comment:

"TODO: shiang-6590, fix me for this protection mechanism"

So I'm not sure any longer what correct behaviour should be for 
TX_PROT_CFG{6,7,8}.

Regards
Stanislaw


Re: [RFC/RFT 3/4] mt76x02: do not set protection on set_rts_threshold callback

2018-12-04 Thread Stanislaw Gruszka
On Fri, Nov 09, 2018 at 10:23:56AM +0100, Lorenzo Bianconi wrote:
> > Use set_rts_threshold calback to enable/disable threshold only for
> > legacy traffic. RTS/CTS threshold for HT TXOP make make no sense
> > to me since used protection (RTS/CTS , CTS-to-self or none)
> > should be determined by HT capabilities and applied to any HT
> > frames.
> > 
> > Signed-off-by: Stanislaw Gruszka 
> > ---
> >  drivers/net/wireless/mediatek/mt76/mt76x02_mac.c  | 16 +---
> >  drivers/net/wireless/mediatek/mt76/mt76x02_mac.h  |  2 +-
> >  drivers/net/wireless/mediatek/mt76/mt76x02_util.c |  2 +-
> >  3 files changed, 3 insertions(+), 17 deletions(-)
> > 
> > diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c 
> > b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
> > index 59b336e34cb5..567a7ab47fab 100644
> > --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
> > +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
> > @@ -737,7 +737,7 @@ void mt76x02_tx_complete_skb(struct mt76_dev *mdev, 
> > struct mt76_queue *q,
> >  }
> >  EXPORT_SYMBOL_GPL(mt76x02_tx_complete_skb);
> >  
> > -void mt76x02_mac_set_tx_protection(struct mt76x02_dev *dev, u32 val)
> > +void mt76x02_mac_set_rts_thresh(struct mt76x02_dev *dev, u32 val)
> >  {
> > u32 data = 0;
> >  
> > @@ -751,20 +751,6 @@ void mt76x02_mac_set_tx_protection(struct mt76x02_dev 
> > *dev, u32 val)
> >  MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);
> > mt76_rmw(dev, MT_OFDM_PROT_CFG,
> >  MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);
> 
> Do we need to configure MT_OFDM_PROT_CFG and MT_CCK_PROT_CFG here? (since they
> are already configured in 4/4 (mt76x02: set protection according to ht
> capabilities))

Only OFDM_PROT_CFG is configured there based on legacy proto
value. I'm not sure how handle CCK_PROT_CFG.

> > -   mt76_rmw(dev, MT_MM20_PROT_CFG,
> > -MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);
> > -   mt76_rmw(dev, MT_MM40_PROT_CFG,
> > -MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);
> > -   mt76_rmw(dev, MT_GF20_PROT_CFG,
> > -MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);
> > -   mt76_rmw(dev, MT_GF40_PROT_CFG,
> > -MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);
> > -   mt76_rmw(dev, MT_TX_PROT_CFG6,
> > -MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);
> > -   mt76_rmw(dev, MT_TX_PROT_CFG7,
> > -MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);
> > -   mt76_rmw(dev, MT_TX_PROT_CFG8,
> > -MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);
> 
> Removing these lines we are no longer able to configure protection for VHT
> rates. Do we have an equivalent for them in vht_capab?

Actually it's not based on HT capabilities but by on ht operation and
it's modified dynamically by hostapd based on what stations are
associated. For STA mode it's provided by remote AP via HT operation IE.

VHT Operation IE do not define protection. Seems interoperability with
legacy STA's is not allowed for VHT, so leaving default values from
initvals where PROT bits are 0 (none protection) is right thing to do.

Regards
Stanislaw


Re: rt2800 tx frame dropping issue.

2018-12-04 Thread Stanislaw Gruszka
Hi Daniel

On Mon, Dec 03, 2018 at 03:44:46PM -0600, Daniel Santos wrote:
> I almost managed to get that patch in a build to send to somebody who
> can reproduce the error in abundance, but they have 15 different people
> hammer the router to do it and we ended up sending them a few other
> experimental builds instead.
> 
> I'm still learning this driver, but I don't see where it creates a
> struct net_device -- was that something that came out after the driver
> was originally written? (And maybe gets implicitly created somewhere
> else?)  

It is done in ieee80211_if_add(), one netdev per vif.

> iiuc, the best way to do this is by setting tx_queue_len while
> the interface is down (via "ip link") and then allocating the queue when
> it's brought up.

We have diffrent queues at various levels in the network stack.
The queues size I plan to increase are referenced as HW queues

> Unless you know of a problem with this approach, I'm planning on making
> a patch just for that.  It will then be easier to tune for an end user's
> particular application. 

I don't think it's correct approch. Maybe module parameter will be
better just for testing. But since this is for routers/APs just
making build with diffrent tx queues size seems to be better
approach.

> For instance, if there is a small number of
> uses who just use a very large amount of bandwidth then buffer bloat
> could become a problem if it's too high.  But for a larger number of
> users I don't think the buffer bloat probably will matter as much as
> lost performance from dropping frames and needing to re-request many
> lost packets at the TCP layer.  This would also result in more uplink
> bandwidth being consumed.

Well, I guess that correct, but I still wish to see if increase queues
size do not cause big negative effect.

Thanks
Stanislaw


Re: rt2800 tx frame dropping issue.

2018-12-03 Thread Daniel Santos
On 11/26/18 3:38 AM, Stanislaw Gruszka wrote:
> On Fri, Nov 23, 2018 at 08:45:54PM +0100, Johannes Berg wrote:
>> On Tue, 2018-11-20 at 15:20 -0600, Daniel Santos wrote:
>>
>>> I believe I have the answer as to why we're getting frames after we stop
>>> the queue.  I had a little chat about this in #kernelnewbies and some
>>> other devs believe it is intentional.
>>>
>>> There is a race in ieee80211_tx_frags (net/mac80211/tx.c) between
>>> releasing local->queue_stop_reason_lock and calling the driver's tx
>>> until we lock queue->tx_lock in rt2x00queue_write_tx_frame -- in between
>>> these two points the thread can be preempted.  So while we stop the
>>> queue in one thread, there can be 20 other threads in between that have
>>> already checked that the queue was running and have a frame buffer
>>> sitting on their stacks.
>> Not 20, only 1 per netdev queue. I suspect that means just 1 per
>> hardware queue, but I don't know how rt2x00 maps netdev queues to
>> hardware queues. If you have lots of netdevs, that might actually be 20,
>> but I suspect that's not what's going on here.
>>
>>>   I think it could be fixed with the below
>>> patch, but I'm being told that it doesn't need it and that the driver
>>> should just *quietly* drop the frame:
>> [snip patch]
>>
>>> Could anybody illuminate for me why this isn't done?  I know that there
>>> has to be a point where we realize there are too many items in the queue
>>> and we can't keep up, but this would seem to be a terrible way to do
>>> that.  Is it one of those things where it isn't worth the performance
>>> degradation?  Any insights would be most appreciated!! :)
>> There's just not much point, and doing the locking here will mean it's
>> across _all_ queues, whereas if you have multiple hardware queues you
>> wouldn't really need it.
>>
>> Note that with internal TXQs with fq/codel support etc. we actually have
>> the fq->lock and it's global, and it turns out that's still a better
>> deal than actually doing parallel TX. So this may not matter so much.
>>
>> In any case, while this might solve the problem for the specific case
>> you're thinking about, as soon as you have something else starting or
>> stopping queues from outside the TX path it still wouldn't actually
>> help.
>>
>> By the way, one thing that can likely exacerbate the problem is
>> fragmentation, once you have that you're more likely to trigger lots of
>> frames in close succession.
>>
>> What I would suggest doing in the driver is actually stop the queues
>> once a *threshold* is reached, rather than being full. Say if you have
>> 128 entries in the HW queue, you can stop once you reach 120 (you
>> probably don't really need the other 8 places). If you get a 121st
>> frame, then you can still put it on the queue (until you filled 128),
>> but you can also stop the queue again (stopping queues is idempotent).
> That what rt2x00 does, but we have 64 entries on tx queues and
> because of that threshold is small. In:
>
> https://bugzilla.kernel.org/show_bug.cgi?id=82751
>
> I proposed increase of queue size to 256 and hence make threshold
> bigger. However I was concerned about bufferbloat and requested
> testing from users how this affect latency. Never get testing 
> results :-(
>
> Thanks
> Stanislaw
>
Hello Stanislaw,

I almost managed to get that patch in a build to send to somebody who
can reproduce the error in abundance, but they have 15 different people
hammer the router to do it and we ended up sending them a few other
experimental builds instead.

I'm still learning this driver, but I don't see where it creates a
struct net_device -- was that something that came out after the driver
was originally written? (And maybe gets implicitly created somewhere
else?)  iiuc, the best way to do this is by setting tx_queue_len while
the interface is down (via "ip link") and then allocating the queue when
it's brought up.

Unless you know of a problem with this approach, I'm planning on making
a patch just for that.  It will then be easier to tune for an end user's
particular application.  For instance, if there is a small number of
uses who just use a very large amount of bandwidth then buffer bloat
could become a problem if it's too high.  But for a larger number of
users I don't think the buffer bloat probably will matter as much as
lost performance from dropping frames and needing to re-request many
lost packets at the TCP layer.  This would also result in more uplink
bandwidth being consumed.

BTW, I guess we need that struct net_device object in order to increment
tx_dropped properly as well.

Thanks,
Daniel


Re: rt2800 tx frame dropping issue.

2018-12-03 Thread Daniel Santos
Hello!

Sorry for my delay, I got pretty sick last week.

On 11/23/18 1:45 PM, Johannes Berg wrote:
> On Tue, 2018-11-20 at 15:20 -0600, Daniel Santos wrote:
>
>> I believe I have the answer as to why we're getting frames after we stop
>> the queue.  I had a little chat about this in #kernelnewbies and some
>> other devs believe it is intentional.
>>
>> There is a race in ieee80211_tx_frags (net/mac80211/tx.c) between
>> releasing local->queue_stop_reason_lock and calling the driver's tx
>> until we lock queue->tx_lock in rt2x00queue_write_tx_frame -- in between
>> these two points the thread can be preempted.  So while we stop the
>> queue in one thread, there can be 20 other threads in between that have
>> already checked that the queue was running and have a frame buffer
>> sitting on their stacks.
> Not 20, only 1 per netdev queue. I suspect that means just 1 per
> hardware queue, but I don't know how rt2x00 maps netdev queues to
> hardware queues. If you have lots of netdevs, that might actually be 20,
> but I suspect that's not what's going on here.

First of all, thank you for the response!

This code path is reached in at least two different ways that I have
discovered (thus far): from the tasklet and from userspace calling
send(msg,to).  A popular captive portal software called coova-chilli can
have 100 such processes.  While I haven't verified beyond all doubt that
they *can* be preempted here it most certainly seems to be what is
happening. I'm attaching the backtraces for reference.


>>   I think it could be fixed with the below
>> patch, but I'm being told that it doesn't need it and that the driver
>> should just *quietly* drop the frame:
> [snip patch]
>
>> Could anybody illuminate for me why this isn't done?  I know that there
>> has to be a point where we realize there are too many items in the queue
>> and we can't keep up, but this would seem to be a terrible way to do
>> that.  Is it one of those things where it isn't worth the performance
>> degradation?  Any insights would be most appreciated!! :)
> There's just not much point, and doing the locking here will mean it's
> across _all_ queues, whereas if you have multiple hardware queues you
> wouldn't really need it.

So perhaps a better solution would be to either:

a.) define a mechanism for the driver to expose per-queue spinlocks to
the ieee80211 subsystem, or
b.) define a new driver function (or change the existing) to emit a
return value and ask ieee80211 to kindly stick the frame back in its own
queue.

I'm still new to this arena, so please be patient if I've said something
stupid.


> Note that with internal TXQs with fq/codel support etc. we actually have
> the fq->lock and it's global, and it turns out that's still a better
> deal than actually doing parallel TX. So this may not matter so much.
>
> In any case, while this might solve the problem for the specific case
> you're thinking about, as soon as you have something else starting or
> stopping queues from outside the TX path it still wouldn't actually
> help.

I don't think that's quite true.  Even if something else is starting and
stopping the queue, the patch could still *help* if it reduces the
instances of having to drop frames, even if it doesn't eliminate them.


>
> By the way, one thing that can likely exacerbate the problem is
> fragmentation, once you have that you're more likely to trigger lots of
> frames in close succession.


Unfortunately I'm new to this driver so I can't comment on that yet, but
I'm catching up!  I presume that's what RTS and CTS was to the standard
for -- so we can send large frames w/o starving other stations?


> What I would suggest doing in the driver is actually stop the queues
> once a *threshold* is reached, rather than being full. Say if you have
> 128 entries in the HW queue, you can stop once you reach 120 (you
> probably don't really need the other 8 places). If you get a 121st
> frame, then you can still put it on the queue (until you filled 128),
> but you can also stop the queue again (stopping queues is idempotent).
>
> johannes
>
>
Yes, hopefully we can get test data using Stanislaw's patch soon!

Thanks,
Daniel
Thread 72 hit Breakpoint 1, rt2x00queue_write_tx_frame (queue=0x87573a1c, 
skb=0x85f45e40, sta=, local=false)
at 
/home/daniel/proj/embedded/openwrt/gse/build_dir/target-mipsel_24kc_musl/linux-ramips_mt7620/backports-2017-11-01/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c:635
635 skbdesc->tx_rate_idx = rate_idx;
(gdb) bt
#0  rt2x00queue_write_tx_frame (queue=0x87573a1c, skb=0x85f45e40, 
sta=, local=false)
at 
/home/daniel/proj/embedded/openwrt/gse/build_dir/target-mipsel_24kc_musl/linux-ramips_mt7620/backports-2017-11-01/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c:635
#1  0x876224b4 in rt2x00mac_tx (hw=0x868d8d40, control=0x87c39200, 
skb=0x85f45e40)
at 

Re: [PATCH] mac80211: allow AP_VLAN operation on crypto controlled devices

2018-12-03 Thread Alexander Wetzel
yes you just missed that ap_vlan is used for 4addr ap's / wds too so 
that might be related to the weired handling


For my understanding ath10k is supporting 4addr mode with HW ciphers 
only. (As long as you do now switch it to raw mode manually and forcing 
SW crypto only.)


The code in question seems to be only reachable if:
1) set_key returned something other than 0 or 1
2) The driver has set SW_CRYPTO_CONTROL

Once triggered it will overwrite the information from the driver, that 
it's not able to handle this key with either hardware or software 
encryption and try SW encryption anyway.
The packets should then be dropped/scrambled by the card and not be 
useful in any way.


Or the other way round:
4addr frames are still QoS data frames, correct?
So why should SW crypto working after the driver told us it will not?


Alexander


Sebastian

Am 02.12.2018 um 14:02 schrieb Alexander Wetzel:

Hello,


From: Manikanta Pubbisetty 

In the current implementation, mac80211 advertises the support of
AP_VLANs based on the driver's support for AP mode; it also
blocks encrypted AP_VLAN operation on devices advertising
SW_CRYPTO_CONTROL.

The implementation seems weird in it's current form and could be
often confusing, this is because there can be drivers advertising
both SW_CRYPTO_CONTROL and AP mode support (ex: ath10k) in which case
AP_VLAN will still be supported but only in open BSS and not in
secured BSS.

When SW_CRYPTO_CONTROL is enabled, it makes more sense if the decision
to support AP_VLANs is left to the driver. Mac80211 can then allow
AP_VLAN operations depending on the driver support.


This first part of the patch contradicts my current understanding of 
how Software crypto fallback can be triggered: We have a driver 
actively telling us to only fall back to sw crypto when it returns 1 
on set_key, BUT we ignore that when the interface is set to 
@NL80211_IFTYPE_AP_VLAN and allow software encryption unconditionally?


Here the code:
    case WLAN_CIPHER_SUITE_GCMP:
    case WLAN_CIPHER_SUITE_GCMP_256:
    /* all of these we can do in software - if driver can */
    if (ret == 1)
    return 0;
    if (ieee80211_hw_check(>local->hw,
   SW_CRYPTO_CONTROL)) {
    if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
    return 0;
    return -EINVAL;
    }
    return 0;
    default:
    return -EINVAL;
    }


Wouldn't it be preferable to just return "ret" or "-EINVAL" instead of 
"0" when the interface has @NL80211_IFTYPE_AP_VLAN set?

As it is this basically overrides SW_CRYPTO_CONTROL in AP Vlan mode!

For me it looks like the old behavior in this section was already fine 
and does not hurt the intention of this patch: A driver setting 
SW_CRYPTO_CONTROL won't get support for AP VLANs as long as the driver 
is not opting in to it.


Therefore I would like to undo this part of the patch again:

-    if (ieee80211_hw_check(>local->hw,
   SW_CRYPTO_CONTROL))
+    if (ieee80211_hw_check(>local->hw,
   SW_CRYPTO_CONTROL)) {
+    if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
+    return 0;
 return -EINVAL;
+    }


Do I miss something here and would anyone have issues when I revert 
that in another patch?


Alexander



Re: [RFC 0/5] add XDP support to mt76x2e/mt76x0e drivers

2018-12-03 Thread Lorenzo Bianconi
> On Mon, 2018-12-03 at 21:36 +0200, Toke Høiland-Jørgensen wrote:
> > Hi Johannes
> >
> > I think your email can be basically summed up to:
> >
> > > [ ... ] but really I think it's a can of worms.
> >
> > ...right? :)
>
> Heh, yeah :)
>
> > I sort of had a feeling it would be, but thank you for spelling out in
> > excruciating detail why that is so.
>
> :-)
>
> > Given this, I think I agree that it's not worth it for now, and we
> > should hold off on adding XDP support until we have 802.3/.11 conversion
> > offload working... Which I think is also where you ended up? :)
>
> That case is at least easy, yeah. And it seems kinda likely that we'll
> end up with that in all well-maintained drivers in the relatively near
> future anyway?

Hi all,

thanks for sharing your thoughts and concerns, as already stated the
main goal of this series
is get feedbacks and/or blocking points to start experimenting with
eBPF over 802.11 devices.
Reviewing the points indicated by Johannes, 802.11 protocol is too
complicated to be managed without skb
allocation. I agree that for the moment XDP/eBPF can be useful for
devices that supports hw offloading
(or FullMac devices?) since all the tricky aspects are already managed
in the firmware and we can take care of XDP stuff.
Probably in the near future we will respin this argument :)

>
> BTW, in a sense I still kind of want to add eBPF to the mac80211 ingress
> path, just not in the XDP sense. For example, I had a proposal a while
> ago to add a filter to the monitor mode RX path(s) in eBPF; I still
> think that's useful.
>
> I also think it may be useful to put eBPF programs into per-netdev
> ingress path, in order to e.g. collect statistics, rather than hard-
> coding all kinds of statistics into mac80211.
>
> All of these things I consider absolutely useful and helpful. I like
> eBPF and the flexibility it affords. I just really don't think we should
> call it XDP or let it do similar things to XDP like dropping or
> redirecting frames.
>

+1 :)

Regards,
Lorenzo

> johannes
>


Re: [RFC 0/5] add XDP support to mt76x2e/mt76x0e drivers

2018-12-03 Thread Toke Høiland-Jørgensen
Johannes Berg  writes:

> On Mon, 2018-12-03 at 21:36 +0200, Toke Høiland-Jørgensen wrote:
>> Hi Johannes
>> 
>> I think your email can be basically summed up to:
>> 
>> > [ ... ] but really I think it's a can of worms.
>> 
>> ...right? :)
>
> Heh, yeah :)
>
>> I sort of had a feeling it would be, but thank you for spelling out in
>> excruciating detail why that is so.
>
> :-)
>
>> Given this, I think I agree that it's not worth it for now, and we
>> should hold off on adding XDP support until we have 802.3/.11
>> conversion offload working... Which I think is also where you ended
>> up? :)
>
> That case is at least easy, yeah. And it seems kinda likely that we'll
> end up with that in all well-maintained drivers in the relatively near
> future anyway?

Right; you probably know that better than me :)

> BTW, in a sense I still kind of want to add eBPF to the mac80211 ingress
> path, just not in the XDP sense. For example, I had a proposal a while
> ago to add a filter to the monitor mode RX path(s) in eBPF; I still
> think that's useful.
>
> I also think it may be useful to put eBPF programs into per-netdev
> ingress path, in order to e.g. collect statistics, rather than hard-
> coding all kinds of statistics into mac80211.
>
> All of these things I consider absolutely useful and helpful. I like
> eBPF and the flexibility it affords. I just really don't think we should
> call it XDP or let it do similar things to XDP like dropping or
> redirecting frames.

Absolutely; totally on board with that!

-Toke


Re: [RFC 0/5] add XDP support to mt76x2e/mt76x0e drivers

2018-12-03 Thread Johannes Berg
On Mon, 2018-12-03 at 21:36 +0200, Toke Høiland-Jørgensen wrote:
> Hi Johannes
> 
> I think your email can be basically summed up to:
> 
> > [ ... ] but really I think it's a can of worms.
> 
> ...right? :)

Heh, yeah :)

> I sort of had a feeling it would be, but thank you for spelling out in
> excruciating detail why that is so.

:-)

> Given this, I think I agree that it's not worth it for now, and we
> should hold off on adding XDP support until we have 802.3/.11 conversion
> offload working... Which I think is also where you ended up? :)

That case is at least easy, yeah. And it seems kinda likely that we'll
end up with that in all well-maintained drivers in the relatively near
future anyway?

BTW, in a sense I still kind of want to add eBPF to the mac80211 ingress
path, just not in the XDP sense. For example, I had a proposal a while
ago to add a filter to the monitor mode RX path(s) in eBPF; I still
think that's useful.

I also think it may be useful to put eBPF programs into per-netdev
ingress path, in order to e.g. collect statistics, rather than hard-
coding all kinds of statistics into mac80211.

All of these things I consider absolutely useful and helpful. I like
eBPF and the flexibility it affords. I just really don't think we should
call it XDP or let it do similar things to XDP like dropping or
redirecting frames.

johannes



Re: [RFC 0/5] add XDP support to mt76x2e/mt76x0e drivers

2018-12-03 Thread Toke Høiland-Jørgensen
Hi Johannes

I think your email can be basically summed up to:

> [ ... ] but really I think it's a can of worms.

...right? :)

I sort of had a feeling it would be, but thank you for spelling out in
excruciating detail why that is so.

Given this, I think I agree that it's not worth it for now, and we
should hold off on adding XDP support until we have 802.3/.11 conversion
offload working... Which I think is also where you ended up? :)

-Toke


Trade Inquiry 03/12/18

2018-12-03 Thread Daniel Murray
Hi,friend,
 
This is Daniel Murray and i am from Sinara Group Co.Ltd in Russia.
We are glad to know about your company from the web and we are interested in 
your products.
Could you kindly send us your Latest catalog and price list for our trial order.
 
Best Regards,
 
Daniel Murray
Purchasing Manager




[PATCH] mac80211: fix deauth TX when we disconnect

2018-12-03 Thread Emmanuel Grumbach
The iTXQs stop/wake queue mechanism involves a whole bunch
of locks and this is probably why the call to
ieee80211_wake_txqs is deferred to a tasklet when called from
__ieee80211_wake_queue.

Another advantage of that is that ieee80211_wake_txqs might
call the wake_tx_queue() callback and then the driver may
call mac80211 which will call it back in the same context.

The bug I saw is that when we send a deauth frame as a
station we do:

flush(drop=1)
tx deauth
flush(drop=0)

While we flush we stop the queues and wake them up
immediately after we finished flushing. The problem here is
that the tasklet that de-facto enables the queue may not have
run until we send the deauth. Then the deauth frame is sent
to the driver (which is surprising by itself), but the driver
won't get anything useful from ieee80211_tx_dequeue because
the queue is stopped (or more precisely because
vif->txqs_stopped[0] is true).
Then the deauth is not sent. Later on, the tasklet will run,
but that'll be too late. We'll already have removed all the
vif etc...

Fix this by calling ieee80211_wake_txqs synchronously if we
are not waking up the queues from the driver (we check the
reason to determine that). This makes the code really
convoluted because we may call ieee80211_wake_txqs from
__ieee80211_wake_queue. The latter assumes that
queue_stop_reason_lock has been taken by the caller and
ieee80211_wake_txqs may release the lock to send the frames.

Signed-off-by: Emmanuel Grumbach 
---
 net/mac80211/util.c | 50 --
 1 file changed, 36 insertions(+), 14 deletions(-)

diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index bec4243..40ea41a 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -299,16 +299,17 @@ static void __ieee80211_wake_txqs(struct 
ieee80211_sub_if_data *sdata, int ac)
spin_unlock_bh(>lock);
 }
 
-void ieee80211_wake_txqs(unsigned long data)
+static void
+__releases(>queue_stop_reason_lock)
+__acquires(>queue_stop_reason_lock)
+_ieee80211_wake_txqs(struct ieee80211_local *local,
+unsigned long *flags)
 {
-   struct ieee80211_local *local = (struct ieee80211_local *)data;
struct ieee80211_sub_if_data *sdata;
int n_acs = IEEE80211_NUM_ACS;
-   unsigned long flags;
int i;
 
rcu_read_lock();
-   spin_lock_irqsave(>queue_stop_reason_lock, flags);
 
if (local->hw.queues < IEEE80211_NUM_ACS)
n_acs = 1;
@@ -317,7 +318,7 @@ void ieee80211_wake_txqs(unsigned long data)
if (local->queue_stop_reasons[i])
continue;
 
-   spin_unlock_irqrestore(>queue_stop_reason_lock, flags);
+   spin_unlock_irqrestore(>queue_stop_reason_lock, *flags);
list_for_each_entry_rcu(sdata, >interfaces, list) {
int ac;
 
@@ -329,13 +330,22 @@ void ieee80211_wake_txqs(unsigned long data)
__ieee80211_wake_txqs(sdata, ac);
}
}
-   spin_lock_irqsave(>queue_stop_reason_lock, flags);
+   spin_lock_irqsave(>queue_stop_reason_lock, *flags);
}
 
-   spin_unlock_irqrestore(>queue_stop_reason_lock, flags);
rcu_read_unlock();
 }
 
+void ieee80211_wake_txqs(unsigned long data)
+{
+   struct ieee80211_local *local = (struct ieee80211_local *)data;
+   unsigned long flags;
+
+   spin_lock_irqsave(>queue_stop_reason_lock, flags);
+   _ieee80211_wake_txqs(local, );
+   spin_unlock_irqrestore(>queue_stop_reason_lock, flags);
+}
+
 void ieee80211_propagate_queue_wake(struct ieee80211_local *local, int queue)
 {
struct ieee80211_sub_if_data *sdata;
@@ -371,7 +381,8 @@ void ieee80211_propagate_queue_wake(struct ieee80211_local 
*local, int queue)
 
 static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue,
   enum queue_stop_reason reason,
-  bool refcounted)
+  bool refcounted,
+  unsigned long *flags)
 {
struct ieee80211_local *local = hw_to_local(hw);
 
@@ -405,8 +416,19 @@ static void __ieee80211_wake_queue(struct ieee80211_hw 
*hw, int queue,
} else
tasklet_schedule(>tx_pending_tasklet);
 
-   if (local->ops->wake_tx_queue)
-   tasklet_schedule(>wake_txqs_tasklet);
+   /*
+* Calling _ieee80211_wake_txqs here can be a problem because it may
+* release queue_stop_reason_lock which has been taken by
+* __ieee80211_wake_queue's caller. It is certainly not very nice to
+* release someone's lock, but it is fine because all the callers of
+* __ieee80211_wake_queue call it right before releasing the lock.
+*/
+   if (local->ops->wake_tx_queue) {
+   if (reason == IEEE80211_QUEUE_STOP_REASON_DRIVER)
+   

[PATCH] mac80211: ignore NullFunc frames in the duplicate detection

2018-12-03 Thread Emmanuel Grumbach
NullFunc packets should never be duplicate just like
QoS-NullFunc packets.

We saw a client that enters / exits power save with
NullFunc frames (and not with QoS-NullFunc) despite the
fact that the association supports HT.
This specific client also re-uses a non-zero sequence number
for different NullFunc frames.
At some point, the client had to send a retransmission of
the NullFunc frame and we dropped it, leading to a
misalignment in the power save state.
Fix this by never consider a NullFunc frame as duplicate,
just like we do for QoS NullFunc frames.

This fixes https://bugzilla.kernel.org/show_bug.cgi?id=201449

CC: 
Signed-off-by: Emmanuel Grumbach 
---
 net/mac80211/rx.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 3bd3b57..2c6515a 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1403,6 +1403,7 @@ ieee80211_rx_h_check_dup(struct ieee80211_rx_data *rx)
return RX_CONTINUE;
 
if (ieee80211_is_ctl(hdr->frame_control) ||
+   ieee80211_is_nullfunc(hdr->frame_control) ||
ieee80211_is_qos_nullfunc(hdr->frame_control) ||
is_multicast_ether_addr(hdr->addr1))
return RX_CONTINUE;
-- 
2.7.4



Re: [RFC 0/5] add XDP support to mt76x2e/mt76x0e drivers

2018-12-03 Thread Johannes Berg
Hi Toke, all,

Sorry I wasn't around for the discussion, I've been travelling and sick.

I'm picking this as an arbitrary point in the discussion to reply to,
hope you don't feel bad about that.

>> [A-MPDU reordering]
> In principle, all of this could be done. But we need to think carefully
> about what things it really makes sense to offload to XDP. In the
> general case, we will end up re-implementing all of mac80211 in eBPF,
> which is obviously not ideal.

Agree with this, completely. Mind you, it's not even simple to do that,
because each kind of hardware behaves differently. See below.

> For crypto in particular, I wonder if there is much of a speedup to be
> had if the crypto is in software anyway. Wouldn't that dominate the
> processing time?

Yeah, I'd also think the cost of skb allocation is dwarfed by the cost
of doing the crypto, but not really sure, maybe you have a fast special
AES instruction? :)


Anyway, here are my thoughts after reading most of the thread and having
discussed it with Lorenzo a while back and today:

1) I'm going to restrict most of the discussion to mac80211, but there
   are interesting cases outside of it as well. Much of the same
   arguments apply, though it means *more* feature combinatorial
   explosion to be able to handle everything.

2) We don't yet have it (but it's been suggested for years and we might
   also get it on Intel hardware eventually), but if we have TX and/or
   RX 802.3/802.11 frame conversion offload then I think we have no
   argument - XDP applies pure and simple as is in each direction you
   have offloads for, unless you do something really stupid in HW like
   still having to do reorder buffer or PN checking based on RX frame
   metadata. I hope nobody does that, but then I suppose you could do it
   before the XDP hooks w/o allocating SKBs.

3) TX from XDP (i.e. X -> wifi) could be implemented in mac80211, but is
   subject to some rather iffy details, for example:
   a) mac80211 may need more headroom than the input has, do we have to
  copy the whole data? depending on xdp_mem_type I think we may need
  that, rather than being able to make an skb with frag pages and
  extra headroom? We don't know it was just a single page and I
  guess we can't ref that page anyway, but maybe we could meddle
  with the SKB frag data somehow to avoid that.
   b) mac80211 may need to software encrypt - copy the whole data
   c) lifetime issues - we need to call xdp_return_frame(), which I
  guess we can tie to the skb we'd create anyway [2]
   (and IMHO we need to allocate an skb anyway, due to TXQs like Toke
mentioned and much other possible software handling)

4) XDP during RX - well, that's _mostly_ what this thread has been
   about, but really I think it's a can of worms. Consider:
   a) drivers may or may not do SW decryption
   b) drivers may or may not do PN checking - so your XDP program might
  end up having to do that or risk security/replay bugs!
  (which, btw, you can only do after reordering so see below)
   c) drivers may or may not do A-MSDU deaggregation, do you[1] really
  want to handle that in XDP? You could argue outer code should walk
  over the subframes, but then dropping becomes hard - and this
  really should only happen after a) and b)
  Oh, and IIRC there are cases that use A-MSDUs for single frames
  just to encapsulate different MAC addresses.
  Speaking of which, you have to validate the inner MAC addresses
  (but it's not a trivial comparison) or risk security bugs again.
   d) drivers may or may not do A-MPDU reordering (this was discussed
  earlier in the thread), which means even if you drop a frame you
  haven't just affected that connection but potentially stalled
  everything until the reorder buffer times out (~100ms), or we need
  a way for mac80211 to insert a fake skb into the reorder buffer at
  that spot (but then you allocate an skb again and high-speed
  traffic where you'd care most is always in an A-MPDU session)
   e) speaking of which, Intel's device has hardware assist things for
  reordering, but not fully offloaded reordering, so you might end
  up with hardware-specific ways of doing this in XDP?
   f) Some data frames are used internally in the stack, e.g. for TDLS.
   g) data frames may also affect the powersave state of a station, so
  if you have e.g. ath9k and the station sends a frame to wake up,
  but you decide you XDP_DROP it, the powersave state will get
  messed up, unless ... special handling (either mac80211 or the
  bpf program) again. Also, U-APSD.
   h) There are also simple things like QoS/non-QoS that add to the
  combinatorial explosion of things you have to handle
   i) data frames could be sent by anyone, not just STAs connected to
  your network, so I guess you'd have to filter that and mac80211
  would have to expose a station table lookup helper or 

Re: mac80211_hwsim : unsigned int for signal in netlink info frames

2018-12-03 Thread Johannes Berg
On Mon, 2018-11-26 at 17:07 +0100, Benjamin Beichler wrote:
> I'm working on my code base and I was surprised by the fact, that the
> type of the received signal strength for frames received via Netlink is
> u32, but the actual struct ieee80211_rx_status.signal uses an s8 for signal.
> 
> I actually refer to this line:
> https://elixir.bootlin.com/linux/v4.20-rc4/source/drivers/net/wireless/mac80211_hwsim.c#L3250

I guess this should use nla_get_s32 now, but I think that didn't exist
before and it also doesn't really matter since if you have a negative
value in a u32 it still works just fine as long as userspace and
kernelspace agree on the 2's complement representation :-)

> As we use the signal measurement in dBm (see
> https://elixir.bootlin.com/linux/v4.20-rc4/source/drivers/net/wireless/mac80211_hwsim.c#L2764),
> negative dBm values are totally reasonable as received signal strength.
> Moreover, I don't really know, whether mac80211 or respectively minstrel
> can do reasonable work with positive values.

Indeed. Make it negative.

> On the other hand this line
> https://elixir.bootlin.com/linux/v4.20-rc4/source/drivers/net/wireless/mac80211_hwsim.c#L1276
> inconsistently uses a negative value in the case of not using
> netlink/wmediumd, which is a decent value.

Sure, it should be negative.

> I think it is not possible to easily switch to another type (e.g. s32 or
> even s8) for the netlink attribute without breaking things, but somebody
> might correct me.

Well, u32 and s32 are really identical in netlink anyway, they're just 4
bytes long integers. So there's no "switching" if we now write
"nla_get_s32" in the code.

What we might want to do is use a policy now that says it must be a
sensible value like -200 to -10 or something, but it doesn't really
matter.

> Any suggestions?

Just put a negative integer there in your userspace.

(u32)-50 == 0xffce

signal = nla_get_u32(...) = 0xffce
-> signal will end up with -50

Nothing to see here, move along ;-)

johannes



Re: Issue with STBC capability and forcing radio to 1x1 mode.

2018-12-03 Thread Johannes Berg
On Wed, 2018-11-28 at 14:13 -0800, Ben Greear wrote:
> Hello,
> 
> I notice some weird things while debugging an issue on a 4.16+ kernel with 
> ath10k
> radio.
> 
> It seems that the 'iw phy info' does not remove the TX-STBC info
> when changing the antenna mask _until_ some vdev is brought up.
> 
> This makes it difficult to properly create hostapd config files.
> 
That's not anything iw can do, must be the driver.

johannes



[PATCH 2/2] mt76: dma: add rx buffer recycle support

2018-12-03 Thread Lorenzo Bianconi
Add support for recycling rx buffers if they are not forwarded
to network stack instead of reallocate them from scratch

Signed-off-by: Lorenzo Bianconi 
---
 drivers/net/wireless/mediatek/mt76/dma.c  | 60 +--
 drivers/net/wireless/mediatek/mt76/mt76.h |  3 ++
 2 files changed, 60 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/dma.c 
b/drivers/net/wireless/mediatek/mt76/dma.c
index 1db163c40dcf..eceadfa3f980 100644
--- a/drivers/net/wireless/mediatek/mt76/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/dma.c
@@ -39,6 +39,15 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue 
*q)
if (!q->entry)
return -ENOMEM;
 
+   /* allocate recycle buffer ring */
+   if (q == >q_rx[MT_RXQ_MCU] ||
+   q == >q_rx[MT_RXQ_MAIN]) {
+   size = q->ndesc * sizeof(*q->recycle);
+   q->recycle = devm_kzalloc(dev->dev, size, GFP_KERNEL);
+   if (!q->recycle)
+   return -ENOMEM;
+   }
+
/* clear descriptors */
for (i = 0; i < q->ndesc; i++)
q->desc[i].ctrl = cpu_to_le32(MT_DMA_CTL_DMA_DONE);
@@ -317,6 +326,49 @@ int mt76_dma_tx_queue_skb(struct mt76_dev *dev, struct 
mt76_queue *q,
 }
 EXPORT_SYMBOL_GPL(mt76_dma_tx_queue_skb);
 
+/* caller must hold mt76_queue spinlock */
+static u8 *mt76_dma_get_free_buf(struct mt76_queue *q, bool flush)
+{
+   if (q->recycle[q->rhead] || flush) {
+   u8 *buff = q->recycle[q->rhead];
+
+   q->recycle[q->rhead] = NULL;
+   q->rhead = (q->rhead + 1) % q->ndesc;
+   return buff;
+   }
+
+   return page_frag_alloc(>rx_page, q->buf_size, GFP_ATOMIC);
+}
+
+static void
+mt76_dma_set_recycle_buf(struct mt76_queue *q, u8 *data)
+{
+   spin_lock_bh(>lock);
+   if (!q->recycle[q->rtail]) {
+   q->recycle[q->rtail] = data;
+   q->rtail = (q->rtail + 1) % q->ndesc;
+   } else {
+   skb_free_frag(data);
+   }
+   spin_unlock_bh(>lock);
+}
+
+static void
+mt76_dma_free_recycle_ring(struct mt76_queue *q)
+{
+   u8 *buf;
+
+   spin_lock_bh(>lock);
+   while (true) {
+   buf = mt76_dma_get_free_buf(q, true);
+   if (!buf)
+   break;
+
+   skb_free_frag(buf);
+   }
+   spin_unlock_bh(>lock);
+}
+
 static int
 mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q)
 {
@@ -332,7 +384,7 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q)
while (q->queued < q->ndesc - 1) {
struct mt76_queue_buf qbuf;
 
-   buf = page_frag_alloc(>rx_page, q->buf_size, GFP_ATOMIC);
+   buf = mt76_dma_get_free_buf(q, false);
if (!buf)
break;
 
@@ -373,6 +425,8 @@ mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue 
*q)
} while (1);
spin_unlock_bh(>lock);
 
+   mt76_dma_free_recycle_ring(q);
+
if (!q->rx_page.va)
return;
 
@@ -438,7 +492,7 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue 
*q, int budget)
dev_kfree_skb(q->rx_head);
q->rx_head = NULL;
 
-   skb_free_frag(data);
+   mt76_dma_set_recycle_buf(q, data);
continue;
}
 
@@ -449,7 +503,7 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue 
*q, int budget)
 
skb = build_skb(data, q->buf_size);
if (!skb) {
-   skb_free_frag(data);
+   mt76_dma_set_recycle_buf(q, data);
continue;
}
skb_reserve(skb, q->buf_offset);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h 
b/drivers/net/wireless/mediatek/mt76/mt76.h
index 5cd508a68609..95546c744494 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -114,6 +114,9 @@ struct mt76_queue {
spinlock_t lock;
struct mt76_queue_entry *entry;
struct mt76_desc *desc;
+   /* recycle ring */
+   u16 rhead, rtail;
+   u8 **recycle;
 
struct list_head swq;
int swq_queued;
-- 
2.19.2



[PATCH 0/2] add rx buffer recycle support to mt76x2e/mt76x0e drivers

2018-12-03 Thread Lorenzo Bianconi
Add the capability to recycle rx buffers if they are not consumed by networking
stack.
This series is based on 'mt76: add size check for additional rx fragments' 
series:
https://patchwork.kernel.org/patch/10709453/

Lorenzo Bianconi (2):
  mt76: dma: do not build skb if reported len does not fit in buf_size
  mt76: dma: add rx buffer recycle support

 drivers/net/wireless/mediatek/mt76/dma.c  | 75 +++
 drivers/net/wireless/mediatek/mt76/mt76.h |  3 +
 2 files changed, 67 insertions(+), 11 deletions(-)

-- 
2.19.2



[PATCH 1/2] mt76: dma: do not build skb if reported len does not fit in buf_size

2018-12-03 Thread Lorenzo Bianconi
Precompute data length in order to avoid to allocate the related
skb data structure if reported length does not fit in queue buf_size

Signed-off-by: Lorenzo Bianconi 
---
 drivers/net/wireless/mediatek/mt76/dma.c | 15 +++
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/dma.c 
b/drivers/net/wireless/mediatek/mt76/dma.c
index b7fd2e110663..1db163c40dcf 100644
--- a/drivers/net/wireless/mediatek/mt76/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/dma.c
@@ -417,10 +417,9 @@ mt76_add_fragment(struct mt76_dev *dev, struct mt76_queue 
*q, void *data,
 static int
 mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
 {
+   int len, data_len, done = 0;
struct sk_buff *skb;
unsigned char *data;
-   int len;
-   int done = 0;
bool more;
 
while (done < budget) {
@@ -430,7 +429,12 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct 
mt76_queue *q, int budget)
if (!data)
break;
 
-   if (q->buf_size < len + q->buf_offset) {
+   if (q->rx_head)
+   data_len = q->buf_size;
+   else
+   data_len = SKB_WITH_OVERHEAD(q->buf_size);
+
+   if (data_len < len + q->buf_offset) {
dev_kfree_skb(q->rx_head);
q->rx_head = NULL;
 
@@ -448,12 +452,7 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct 
mt76_queue *q, int budget)
skb_free_frag(data);
continue;
}
-
skb_reserve(skb, q->buf_offset);
-   if (skb->tail + len > skb->end) {
-   dev_kfree_skb(skb);
-   continue;
-   }
 
if (q == >q_rx[MT_RXQ_MCU]) {
u32 *rxfce = (u32 *) skb->cb;
-- 
2.19.2



[PATCH 1/3] mt76: add size check for additional rx fragments

2018-12-03 Thread Felix Fietkau
So far the code only validates the buffer size of the first skb.
Extend this check to cover additional fragments as well, in case the size
is corrupted during a DMA reset.

Signed-off-by: Felix Fietkau 
---
 drivers/net/wireless/mediatek/mt76/dma.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/net/wireless/mediatek/mt76/dma.c 
b/drivers/net/wireless/mediatek/mt76/dma.c
index e2ba26378575..710a77fccf63 100644
--- a/drivers/net/wireless/mediatek/mt76/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/dma.c
@@ -430,6 +430,14 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct 
mt76_queue *q, int budget)
if (!data)
break;
 
+   if (q->buf_size < len + q->buf_offset) {
+   dev_kfree_skb(q->rx_head);
+   q->rx_head = NULL;
+
+   skb_free_frag(data);
+   continue;
+   }
+
if (q->rx_head) {
mt76_add_fragment(dev, q, data, len, more);
continue;
-- 
2.17.0



[PATCH 2/3] mt76: throttle transmission of buffered multicast packets

2018-12-03 Thread Felix Fietkau
Avoids drowning out regular transmissions

Signed-off-by: Felix Fietkau 
---
 drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
index 66315410aebe..6974acc75e2b 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
@@ -121,9 +121,10 @@ static void mt76x02_pre_tbtt_tasklet(unsigned long arg)
ieee80211_iterate_active_interfaces_atomic(mt76_hw(dev),
IEEE80211_IFACE_ITER_RESUME_ALL,
mt76x02_add_buffered_bc, );
-   } while (nframes != skb_queue_len());
+   } while (nframes != skb_queue_len() &&
+skb_queue_len() < 8);
 
-   if (!nframes)
+   if (!skb_queue_len())
return;
 
for (i = 0; i < ARRAY_SIZE(data.tail); i++) {
-- 
2.17.0



[PATCH 3/3] mt76: request tx status for powersave released EOSP packet

2018-12-03 Thread Felix Fietkau
Allows mac80211 to keep track of the service period

Signed-off-by: Felix Fietkau 
---
 drivers/net/wireless/mediatek/mt76/tx.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mediatek/mt76/tx.c 
b/drivers/net/wireless/mediatek/mt76/tx.c
index f4093dc0e174..06178bdafbac 100644
--- a/drivers/net/wireless/mediatek/mt76/tx.c
+++ b/drivers/net/wireless/mediatek/mt76/tx.c
@@ -330,7 +330,8 @@ mt76_queue_ps_skb(struct mt76_dev *dev, struct 
ieee80211_sta *sta,
 
info->control.flags |= IEEE80211_TX_CTRL_PS_RESPONSE;
if (last)
-   info->flags |= IEEE80211_TX_STATUS_EOSP;
+   info->flags |= IEEE80211_TX_STATUS_EOSP |
+  IEEE80211_TX_CTL_REQ_TX_STATUS;
 
mt76_skb_set_moredata(skb, !last);
dev->queue_ops->tx_queue_skb(dev, hwq, skb, wcid, sta);
-- 
2.17.0



[PATCH v2 05/15] iwlwifi: don't define OTP_LOW_IMAGE_SIZE per family, but per size

2018-12-03 Thread Luca Coelho
From: Luca Coelho 

Using OTP_LOW_IMAGE_SIZE_FAMILY_8000/9000/22000 only obfuscates the
actual values, since these 3 are the same.  Redefine the values per
size so it's easier to understand and compare the different
configurations.

Signed-off-by: Luca Coelho 
---

In v2: fix erroneously commented out line

drivers/net/wireless/intel/iwlwifi/cfg/1000.c   | 2 +-
 drivers/net/wireless/intel/iwlwifi/cfg/2000.c   | 4 ++--
 drivers/net/wireless/intel/iwlwifi/cfg/22000.c  | 4 ++--
 drivers/net/wireless/intel/iwlwifi/cfg/6000.c   | 6 +++---
 drivers/net/wireless/intel/iwlwifi/cfg/7000.c   | 2 +-
 drivers/net/wireless/intel/iwlwifi/cfg/8000.c   | 2 +-
 drivers/net/wireless/intel/iwlwifi/cfg/9000.c   | 2 +-
 drivers/net/wireless/intel/iwlwifi/iwl-config.h | 8 +++-
 8 files changed, 14 insertions(+), 16 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/1000.c 
b/drivers/net/wireless/intel/iwlwifi/cfg/1000.c
index 76b5ddb20248..1ff388b593ad 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/1000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/1000.c
@@ -48,7 +48,7 @@
 static const struct iwl_base_params iwl1000_base_params = {
.num_of_queues = IWLAGN_NUM_QUEUES,
.max_tfd_queue_size = 256,
-   .eeprom_size = OTP_LOW_IMAGE_SIZE,
+   .eeprom_size = OTP_LOW_IMAGE_SIZE_2K,
.pll_cfg = true,
.max_ll_items = OTP_MAX_LL_ITEMS_1000,
.shadow_ram_support = false,
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/2000.c 
b/drivers/net/wireless/intel/iwlwifi/cfg/2000.c
index e7e45846dd07..a6ec7ad39dcb 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/2000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/2000.c
@@ -57,7 +57,7 @@
 #define IWL135_MODULE_FIRMWARE(api) IWL135_FW_PRE __stringify(api) ".ucode"
 
 static const struct iwl_base_params iwl2000_base_params = {
-   .eeprom_size = OTP_LOW_IMAGE_SIZE,
+   .eeprom_size = OTP_LOW_IMAGE_SIZE_2K,
.num_of_queues = IWLAGN_NUM_QUEUES,
.max_tfd_queue_size = 256,
.max_ll_items = OTP_MAX_LL_ITEMS_2x00,
@@ -71,7 +71,7 @@ static const struct iwl_base_params iwl2000_base_params = {
 
 
 static const struct iwl_base_params iwl2030_base_params = {
-   .eeprom_size = OTP_LOW_IMAGE_SIZE,
+   .eeprom_size = OTP_LOW_IMAGE_SIZE_2K,
.num_of_queues = IWLAGN_NUM_QUEUES,
.max_tfd_queue_size = 256,
.max_ll_items = OTP_MAX_LL_ITEMS_2x00,
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c 
b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
index 8b2339165bca..2d395a4a5375 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
@@ -109,7 +109,7 @@
 #define NVM_HW_SECTION_NUM_FAMILY_2200010
 
 static const struct iwl_base_params iwl_22000_base_params = {
-   .eeprom_size = OTP_LOW_IMAGE_SIZE_FAMILY_22000,
+   .eeprom_size = OTP_LOW_IMAGE_SIZE_32K,
.num_of_queues = 512,
.max_tfd_queue_size = 256,
.shadow_ram_support = true,
@@ -121,7 +121,7 @@ static const struct iwl_base_params iwl_22000_base_params = 
{
 };
 
 static const struct iwl_base_params iwl_22560_base_params = {
-   .eeprom_size = OTP_LOW_IMAGE_SIZE_FAMILY_22000,
+   .eeprom_size = OTP_LOW_IMAGE_SIZE_32K,
.num_of_queues = 512,
.max_tfd_queue_size = 65536,
.shadow_ram_support = true,
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/6000.c 
b/drivers/net/wireless/intel/iwlwifi/cfg/6000.c
index 30e62a7c9d52..fbb18d066cd0 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/6000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/6000.c
@@ -66,7 +66,7 @@
 #define IWL6030_MODULE_FIRMWARE(api) IWL6030_FW_PRE __stringify(api) ".ucode"
 
 static const struct iwl_base_params iwl6000_base_params = {
-   .eeprom_size = OTP_LOW_IMAGE_SIZE,
+   .eeprom_size = OTP_LOW_IMAGE_SIZE_2K,
.num_of_queues = IWLAGN_NUM_QUEUES,
.max_tfd_queue_size = 256,
.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
@@ -79,7 +79,7 @@ static const struct iwl_base_params iwl6000_base_params = {
 };
 
 static const struct iwl_base_params iwl6050_base_params = {
-   .eeprom_size = OTP_LOW_IMAGE_SIZE,
+   .eeprom_size = OTP_LOW_IMAGE_SIZE_2K,
.num_of_queues = IWLAGN_NUM_QUEUES,
.max_tfd_queue_size = 256,
.max_ll_items = OTP_MAX_LL_ITEMS_6x50,
@@ -92,7 +92,7 @@ static const struct iwl_base_params iwl6050_base_params = {
 };
 
 static const struct iwl_base_params iwl6000_g2_base_params = {
-   .eeprom_size = OTP_LOW_IMAGE_SIZE,
+   .eeprom_size = OTP_LOW_IMAGE_SIZE_2K,
.num_of_queues = IWLAGN_NUM_QUEUES,
.max_tfd_queue_size = 256,
.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/7000.c 
b/drivers/net/wireless/intel/iwlwifi/cfg/7000.c
index c973bfaa3414..38d5db50b1ed 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/7000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/7000.c
@@ -116,7 +116,7 @@
 

Re: [PATCH 05/15] iwlwifi: don't define OTP_LOW_IMAGE_SIZE per family, but per size

2018-12-03 Thread Luciano Coelho
On Thu, 2018-11-29 at 12:01 +0200, Kalle Valo wrote:
> Luca Coelho  writes:
> 
> > From: Luca Coelho 
> > 
> > Using OTP_LOW_IMAGE_SIZE_FAMILY_8000/9000/22000 only obfuscates the
> > actual values, since these 3 are the same.  Redefine the values per
> > size so it's easier to understand and compare the different
> > configurations.
> > 
> > Signed-off-by: Luca Coelho 
> 
> [...]
> 
> > --- a/drivers/net/wireless/intel/iwlwifi/cfg/1000.c
> > +++ b/drivers/net/wireless/intel/iwlwifi/cfg/1000.c
> > @@ -48,7 +48,7 @@
> >  static const struct iwl_base_params iwl1000_base_params = {
> > .num_of_queues = IWLAGN_NUM_QUEUES,
> > .max_tfd_queue_size = 256,
> > -   .eeprom_size = OTP_LOW_IMAGE_SIZE,
> > +   /* .eeprom_size = OTP_LOW_IMAGE_SIZE_2K, */
> 
> Why this is commented out?

Nice catch! I have no idea what happened here, this was never commented
out in our internal tree... I'll send v2.

--
Luca.



[PATCH] nl80211/cfg80211: Add support to send tx frames at specified rate

2018-12-03 Thread vamsi krishna
NL80211_CMD_FRAME is used to send frames from userspace. Add support to
transmit the frames at a rate specified by userspace when needed.
The drivers shall indicate the support to send frames at rate specified
by userspace by setting %NL80211_EXT_FEATURE_CMD_FRAME_TXRATE flag in
wiphy capabilities. The userspace can specify the rate within
%NL80211_ATTR_RATE_INFO attribute while sending %NL80211_CMD_FRAME.

NL80211_ATTR_RATE_INFO is a nested attribute and encapsulates the
attributes defined in  nl80211_rate_info.

Signed-off-by: vamsi krishna 

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index c032375..dbf58c6 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2629,6 +2629,11 @@ struct cfg80211_update_ft_ies_params {
  * @dont_wait_for_ack: tells the low level not to wait for an ack
  * @n_csa_offsets: length of csa_offsets array
  * @csa_offsets: array of all the csa offsets in the frame
+ * @txrate: Tx rate at which this frame shall be transmitted on-air.
+ * txrate->legacy shall be used to determine 11abg rate only when none of
+ * RATE_INFO_FLAGS_MCS, RATE_INFO_FLAGS_VHT_MCS and RATE_INFO_FLAGS_HE_MCS
+ * flags in txrate->flags.
+ * @txrate_specified: Indicates whether any valid tx rate specified @txrate.
  */
 struct cfg80211_mgmt_tx_params {
struct ieee80211_channel *chan;
@@ -2640,6 +2645,8 @@ struct cfg80211_mgmt_tx_params {
bool dont_wait_for_ack;
int n_csa_offsets;
const u16 *csa_offsets;
+   struct rate_info txrate;
+   bool txrate_specified;
 };
 
 /**
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 0d4dd14..b731868 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -646,6 +646,11 @@
  * %NL80211_ATTR_CSA_C_OFFSETS_TX is an array of offsets to CSA
  * counters which will be updated to the current value. This attribute
  * is used during CSA period.
+ * Optionally the rate at which this frame shall be transmitted can be
+ * specified using %NL80211_ATTR_RATE_INFO if the driver indicates the
+ * support by setting %NL80211_EXT_FEATURE_CMD_FRAME_TXRATE feature flag.
+ * NL80211_RATE_INFO_BITRATE* shall not be populated within
+ * %NL80211_ATTR_RATE_INFO unless one of the 11abg rates is specified.
  * @NL80211_CMD_FRAME_WAIT_CANCEL: When an off-channel TX was requested, this
  * command may be used with the corresponding cookie to cancel the wait
  * time if it is known that it is no longer necessary.
@@ -2270,6 +2275,12 @@ enum nl80211_commands {
  * or bssid attribute will have higher precedence than the thresholds
  * mentioned in this attribute while checking rssi.
  *
+ * @NL80211_ATTR_RATE_INFO: Specifies either tx rate at which a packet shall be
+ * transmitted or rx rate at which a packet has been received. Nested
+ * attribute containing info as possible, see  nl80211_rate_info.
+ * Will be used with %NL80211_CMD_FRAME to specify the phy rate at which
+ * the frame associated with this command shall be transmitted over the
+ * air.
  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -2717,6 +2728,8 @@ enum nl80211_attrs {
 
NL80211_ATTR_SCHED_SCAN_MIN_RSSI,
 
+   NL80211_ATTR_RATE_INFO,
+
/* add attributes here, update the policy in nl80211.c */
 
__NL80211_ATTR_AFTER_LAST,
@@ -2930,7 +2943,9 @@ enum nl80211_he_ru_alloc {
  * enum nl80211_rate_info - bitrate information
  *
  * These attribute types are used with %NL80211_STA_INFO_TXRATE
- * when getting information about the bitrate of a station.
+ * when getting information about the bitrate of a station and with
+ * %NL80211_CMD_FRAME to specify the phy rate at which the frame shall
+ * be transmitted.
  * There are 2 attributes for bitrate, a legacy one that represents
  * a 16-bit value, and new one that represents a 32-bit value.
  * If the rate value fits into 16 bit, both attributes are reported
@@ -5278,6 +5293,10 @@ enum nl80211_feature_flags {
  * @NL80211_EXT_FEATURE_SCHED_SCAN_BAND_SPECIFIC_RSSI_THOLD: The driver 
supports
  * filtering scan results with band specific rssi thresholds that are
  * specified within %NL80211_ATTR_SCHED_SCAN_MIN_RSSI.
+ * @NL80211_EXT_FEATURE_CMD_FRAME_TXRATE: The driver supports sending frames
+ * at rate specified by userspace with %NL80211_CMD_FRAME. The tx rate
+ * shall be specified within %NL80211_ATTR_RATE_INFO nested attribute
+ * with %NL80211_CMD_FRAME command.
  *
  * @NUM_NL80211_EXT_FEATURES: number of extended features.
  * @MAX_NL80211_EXT_FEATURES: highest extended feature index.
@@ -5319,6 +5338,7 @@ enum nl80211_ext_feature_index {
NL80211_EXT_FEATURE_CAN_REPLACE_PTK0,
NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER,
NL80211_EXT_FEATURE_SCHED_SCAN_BAND_SPECIFIC_RSSI_THOLD,
+   

Price Inquiry 03-12-2018

2018-12-03 Thread Daniel Murray
Hi,friend,
 
This is Daniel Murray and i am from Sinara Group Co.Ltd in Russia.
We are glad to know about your company from the web and we are interested in 
your products.
Could you kindly send us your Latest catalog and price list for our trial order.
 
Best Regards,
 
Daniel Murray
Purchasing Manager




[PATCH 28/29] staging: wilc1000: avoid extra buffer copy while connect cfg ops

2018-12-02 Thread Ajay.Kathat
From: Ajay Singh 

Refactor the code to avoid the use of an extra buffer to store the
connection related parameter. No need to call cfg80211_disconnected in
case of failure to send the wid command to firmware, an error status is
directly returned in cfg80211 connect callback.

Signed-off-by: Ajay Singh 
---
 drivers/staging/wilc1000/host_interface.c | 129 +++---
 drivers/staging/wilc1000/host_interface.h |   2 +
 drivers/staging/wilc1000/wilc_wfi_cfgoperations.c |   2 +
 3 files changed, 21 insertions(+), 112 deletions(-)

diff --git a/drivers/staging/wilc1000/host_interface.c 
b/drivers/staging/wilc1000/host_interface.c
index 783c99b..f50728c 100644
--- a/drivers/staging/wilc1000/host_interface.c
+++ b/drivers/staging/wilc1000/host_interface.c
@@ -25,20 +25,6 @@ struct scan_attr {
struct hidden_network hidden_network;
 };
 
-struct connect_attr {
-   u8 *bssid;
-   u8 *ssid;
-   size_t ssid_len;
-   u8 *ies;
-   size_t ies_len;
-   u8 security;
-   wilc_connect_result result;
-   void *arg;
-   enum authtype auth_type;
-   u8 ch;
-   void *params;
-};
-
 struct rcvd_async_info {
u8 *buffer;
u32 len;
@@ -99,7 +85,6 @@ struct wilc_gtk_key {
 
 union message_body {
struct scan_attr scan_info;
-   struct connect_attr con_info;
struct rcvd_net_info net_info;
struct rcvd_async_info async_info;
struct set_multicast multicast_info;
@@ -362,54 +347,15 @@ static void handle_scan(struct work_struct *work)
kfree(msg);
 }
 
-static int wilc_send_connect_wid(struct wilc_vif *vif,
-struct connect_attr *conn_attr)
+static int wilc_send_connect_wid(struct wilc_vif *vif)
 {
int result = 0;
struct wid wid_list[8];
u32 wid_cnt = 0, dummyval = 0;
u8 *cur_byte = NULL;
-   struct join_bss_param *bss_param = conn_attr->params;
struct host_if_drv *hif_drv = vif->hif_drv;
-
-   if (conn_attr->bssid) {
-   hif_drv->usr_conn_req.bssid = kmemdup(conn_attr->bssid, 6,
- GFP_KERNEL);
-   if (!hif_drv->usr_conn_req.bssid) {
-   result = -ENOMEM;
-   goto error;
-   }
-   }
-
-   hif_drv->usr_conn_req.ssid_len = conn_attr->ssid_len;
-   if (conn_attr->ssid) {
-   hif_drv->usr_conn_req.ssid = kmalloc(conn_attr->ssid_len + 1,
-GFP_KERNEL);
-   if (!hif_drv->usr_conn_req.ssid) {
-   result = -ENOMEM;
-   goto error;
-   }
-   memcpy(hif_drv->usr_conn_req.ssid,
-  conn_attr->ssid,
-  conn_attr->ssid_len);
-   hif_drv->usr_conn_req.ssid[conn_attr->ssid_len] = '\0';
-   }
-
-   hif_drv->usr_conn_req.ies_len = conn_attr->ies_len;
-   if (conn_attr->ies) {
-   hif_drv->usr_conn_req.ies = kmemdup(conn_attr->ies,
-   conn_attr->ies_len,
-   GFP_KERNEL);
-   if (!hif_drv->usr_conn_req.ies) {
-   result = -ENOMEM;
-   goto error;
-   }
-   }
-
-   hif_drv->usr_conn_req.security = conn_attr->security;
-   hif_drv->usr_conn_req.auth_type = conn_attr->auth_type;
-   hif_drv->usr_conn_req.conn_result = conn_attr->result;
-   hif_drv->usr_conn_req.arg = conn_attr->arg;
+   struct user_conn_req *conn_attr = _drv->usr_conn_req;
+   struct join_bss_param *bss_param = hif_drv->usr_conn_req.param;
 
wid_list[wid_cnt].id = WID_SUCCESS_FRAME_COUNT;
wid_list[wid_cnt].type = WID_INT;
@@ -431,20 +377,20 @@ static int wilc_send_connect_wid(struct wilc_vif *vif,
 
wid_list[wid_cnt].id = WID_INFO_ELEMENT_ASSOCIATE;
wid_list[wid_cnt].type = WID_BIN_DATA;
-   wid_list[wid_cnt].val = hif_drv->usr_conn_req.ies;
-   wid_list[wid_cnt].size = hif_drv->usr_conn_req.ies_len;
+   wid_list[wid_cnt].val = conn_attr->ies;
+   wid_list[wid_cnt].size = conn_attr->ies_len;
wid_cnt++;
 
wid_list[wid_cnt].id = WID_11I_MODE;
wid_list[wid_cnt].type = WID_CHAR;
wid_list[wid_cnt].size = sizeof(char);
-   wid_list[wid_cnt].val = (s8 *)_drv->usr_conn_req.security;
+   wid_list[wid_cnt].val = (s8 *)_attr->security;
wid_cnt++;
 
wid_list[wid_cnt].id = WID_AUTH_TYPE;
wid_list[wid_cnt].type = WID_CHAR;
wid_list[wid_cnt].size = sizeof(char);
-   wid_list[wid_cnt].val = (s8 *)_drv->usr_conn_req.auth_type;
+   wid_list[wid_cnt].val = (s8 *)_attr->auth_type;
wid_cnt++;
 
wid_list[wid_cnt].id = WID_JOIN_REQ_EXTENDED;
@@ -494,7 +440,7 @@ static int wilc_send_connect_wid(struct wilc_vif *vif,

[PATCH 27/29] staging: wilc1000: handle connect ops callback from cfg80211 context

2018-12-02 Thread Ajay.Kathat
From: Ajay Singh 

Refactor the connect related cfg callback to be called from cfg80211
context. No need to post connect command internally in case scan is in
progress instead simply return the error status in connect ops callback.

Signed-off-by: Ajay Singh 
---
 drivers/staging/wilc1000/host_interface.c | 104 +-
 1 file changed, 44 insertions(+), 60 deletions(-)

diff --git a/drivers/staging/wilc1000/host_interface.c 
b/drivers/staging/wilc1000/host_interface.c
index 6a908ea..783c99b 100644
--- a/drivers/staging/wilc1000/host_interface.c
+++ b/drivers/staging/wilc1000/host_interface.c
@@ -362,34 +362,16 @@ static void handle_scan(struct work_struct *work)
kfree(msg);
 }
 
-static void handle_connect(struct work_struct *work)
+static int wilc_send_connect_wid(struct wilc_vif *vif,
+struct connect_attr *conn_attr)
 {
-   struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
-   struct wilc_vif *vif = msg->vif;
-   struct connect_attr *conn_attr = >body.con_info;
int result = 0;
struct wid wid_list[8];
u32 wid_cnt = 0, dummyval = 0;
u8 *cur_byte = NULL;
-   struct join_bss_param *bss_param;
+   struct join_bss_param *bss_param = conn_attr->params;
struct host_if_drv *hif_drv = vif->hif_drv;
 
-   if (msg->vif->hif_drv->usr_scan_req.scan_result) {
-   result = wilc_enqueue_work(msg);
-   if (result)
-   goto error;
-
-   usleep_range(2 * 1000, 2 * 1000);
-   return;
-   }
-
-   bss_param = conn_attr->params;
-   if (!bss_param) {
-   netdev_err(vif->ndev, "Required BSSID not found\n");
-   result = -ENOENT;
-   goto error;
-   }
-
if (conn_attr->bssid) {
hif_drv->usr_conn_req.bssid = kmemdup(conn_attr->bssid, 6,
  GFP_KERNEL);
@@ -490,8 +472,8 @@ static void handle_connect(struct work_struct *work)
netdev_err(vif->ndev, "Channel out of range\n");
*(cur_byte++) = 0xFF;
}
-   *(cur_byte++)  = (bss_param->cap_info) & 0xFF;
-   *(cur_byte++)  = ((bss_param->cap_info) >> 8) & 0xFF;
+   put_unaligned_le16(bss_param->cap_info, cur_byte);
+   cur_byte += 2;
 
if (conn_attr->bssid)
memcpy(cur_byte, conn_attr->bssid, 6);
@@ -501,8 +483,8 @@ static void handle_connect(struct work_struct *work)
memcpy(cur_byte, conn_attr->bssid, 6);
cur_byte += 6;
 
-   *(cur_byte++)  = (bss_param->beacon_period) & 0xFF;
-   *(cur_byte++)  = ((bss_param->beacon_period) >> 8) & 0xFF;
+   put_unaligned_le16(bss_param->beacon_period, cur_byte);
+   cur_byte += 2;
*(cur_byte++)  =  bss_param->dtim_period;
 
memcpy(cur_byte, bss_param->supp_rates, MAX_RATES_SUPPORTED + 1);
@@ -533,10 +515,8 @@ static void handle_connect(struct work_struct *work)
*(cur_byte++) = bss_param->noa_enabled;
 
if (bss_param->noa_enabled) {
-   *(cur_byte++) = (bss_param->tsf) & 0xFF;
-   *(cur_byte++) = ((bss_param->tsf) >> 8) & 0xFF;
-   *(cur_byte++) = ((bss_param->tsf) >> 16) & 0xFF;
-   *(cur_byte++) = ((bss_param->tsf) >> 24) & 0xFF;
+   put_unaligned_le32(bss_param->tsf, cur_byte);
+   cur_byte += 4;
 
*(cur_byte++) = bss_param->opp_enabled;
*(cur_byte++) = bss_param->idx;
@@ -616,8 +596,10 @@ static void handle_connect(struct work_struct *work)
kfree(conn_attr->ies);
conn_attr->ies = NULL;
 
+   kfree(conn_attr);
kfree(cur_byte);
-   kfree(msg);
+
+   return result;
 }
 
 static void handle_connect_timeout(struct work_struct *work)
@@ -1926,8 +1908,8 @@ int wilc_set_join_req(struct wilc_vif *vif, u8 *bssid, 
const u8 *ssid,
  u8 channel, void *join_params)
 {
int result;
-   struct host_if_msg *msg;
struct host_if_drv *hif_drv = vif->hif_drv;
+   struct connect_attr *con_info;
 
if (!hif_drv || !connect_result) {
netdev_err(vif->ndev,
@@ -1941,50 +1923,51 @@ int wilc_set_join_req(struct wilc_vif *vif, u8 *bssid, 
const u8 *ssid,
return -EFAULT;
}
 
-   msg = wilc_alloc_work(vif, handle_connect, false);
-   if (IS_ERR(msg))
-   return PTR_ERR(msg);
+   if (hif_drv->usr_scan_req.scan_result) {
+   netdev_err(vif->ndev, "%s: Scan in progress\n", __func__);
+   return -EBUSY;
+   }
+
+   con_info = kzalloc(sizeof(*con_info), GFP_KERNEL);
+   if (!con_info)
+   return -ENOMEM;
 
-   msg->body.con_info.security = security;
-   msg->body.con_info.auth_type = auth_type;
-   msg->body.con_info.ch = channel;
-   msg->body.con_info.result = connect_result;
-   

[PATCH 29/29] staging: wilc1000: handle scan operation callback from cfg80211 context

2018-12-02 Thread Ajay.Kathat
From: Ajay Singh 

Refactor code to handle scan operation callback from cfg80211 context.
No need to maintain 'scan_attr' struct as the wid command is directly
sent to firmware from cfg80211 context.

Signed-off-by: Ajay Singh 
---
 drivers/staging/wilc1000/host_interface.c | 143 --
 drivers/staging/wilc1000/wilc_wfi_cfgoperations.c |  13 +-
 2 files changed, 33 insertions(+), 123 deletions(-)

diff --git a/drivers/staging/wilc1000/host_interface.c 
b/drivers/staging/wilc1000/host_interface.c
index f50728c..b8603f2 100644
--- a/drivers/staging/wilc1000/host_interface.c
+++ b/drivers/staging/wilc1000/host_interface.c
@@ -13,18 +13,6 @@
 
 #define REAL_JOIN_REQ  0
 
-struct scan_attr {
-   u8 src;
-   u8 type;
-   u8 *ch_freq_list;
-   u8 ch_list_len;
-   u8 *ies;
-   size_t ies_len;
-   wilc_scan_result result;
-   void *arg;
-   struct hidden_network hidden_network;
-};
-
 struct rcvd_async_info {
u8 *buffer;
u32 len;
@@ -84,7 +72,6 @@ struct wilc_gtk_key {
 } __packed;
 
 union message_body {
-   struct scan_attr scan_info;
struct rcvd_net_info net_info;
struct rcvd_async_info async_info;
struct set_multicast multicast_info;
@@ -230,11 +217,11 @@ static int handle_scan_done(struct wilc_vif *vif, enum 
scan_event evt)
return result;
 }
 
-static void handle_scan(struct work_struct *work)
+int wilc_scan(struct wilc_vif *vif, u8 scan_source, u8 scan_type,
+ u8 *ch_freq_list, u8 ch_list_len, const u8 *ies,
+ size_t ies_len, wilc_scan_result scan_result, void *user_arg,
+ struct hidden_network *hidden_net)
 {
-   struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
-   struct wilc_vif *vif = msg->vif;
-   struct scan_attr *scan_info = >body.scan_info;
int result = 0;
struct wid wid_list[5];
u32 index = 0;
@@ -243,10 +230,6 @@ static void handle_scan(struct work_struct *work)
u8 valuesize = 0;
u8 *hdn_ntwk_wid_val = NULL;
struct host_if_drv *hif_drv = vif->hif_drv;
-   struct hidden_network *hidden_net = _info->hidden_network;
-
-   hif_drv->usr_scan_req.scan_result = scan_info->result;
-   hif_drv->usr_scan_req.arg = scan_info->arg;
 
if (hif_drv->hif_state >= HOST_IF_SCANNING &&
hif_drv->hif_state < HOST_IF_CONNECTED) {
@@ -288,63 +271,55 @@ static void handle_scan(struct work_struct *work)
 
wid_list[index].id = WID_INFO_ELEMENT_PROBE;
wid_list[index].type = WID_BIN_DATA;
-   wid_list[index].val = scan_info->ies;
-   wid_list[index].size = scan_info->ies_len;
+   wid_list[index].val = (s8 *)ies;
+   wid_list[index].size = ies_len;
index++;
 
wid_list[index].id = WID_SCAN_TYPE;
wid_list[index].type = WID_CHAR;
wid_list[index].size = sizeof(char);
-   wid_list[index].val = (s8 *)_info->type;
+   wid_list[index].val = (s8 *)_type;
index++;
 
wid_list[index].id = WID_SCAN_CHANNEL_LIST;
wid_list[index].type = WID_BIN_DATA;
 
-   if (scan_info->ch_freq_list &&
-   scan_info->ch_list_len > 0) {
-   int i;
-
-   for (i = 0; i < scan_info->ch_list_len; i++) {
-   if (scan_info->ch_freq_list[i] > 0)
-   scan_info->ch_freq_list[i] -= 1;
+   if (ch_freq_list && ch_list_len > 0) {
+   for (i = 0; i < ch_list_len; i++) {
+   if (ch_freq_list[i] > 0)
+   ch_freq_list[i] -= 1;
}
}
 
-   wid_list[index].val = scan_info->ch_freq_list;
-   wid_list[index].size = scan_info->ch_list_len;
+   wid_list[index].val = ch_freq_list;
+   wid_list[index].size = ch_list_len;
index++;
 
wid_list[index].id = WID_START_SCAN_REQ;
wid_list[index].type = WID_CHAR;
wid_list[index].size = sizeof(char);
-   wid_list[index].val = (s8 *)_info->src;
+   wid_list[index].val = (s8 *)_source;
index++;
 
result = wilc_send_config_pkt(vif, WILC_SET_CFG, wid_list,
  index,
  wilc_get_vif_idx(vif));
-
-   if (result)
-   netdev_err(vif->ndev, "Failed to send scan parameters\n");
-
-error:
if (result) {
-   del_timer(_drv->scan_timer);
-   handle_scan_done(vif, SCAN_EVENT_ABORTED);
+   netdev_err(vif->ndev, "Failed to send scan parameters\n");
+   goto error;
}
 
-   kfree(scan_info->ch_freq_list);
-   scan_info->ch_freq_list = NULL;
-
-   kfree(scan_info->ies);
-   scan_info->ies = NULL;
-   kfree(scan_info->hidden_network.net_info);
-   scan_info->hidden_network.net_info = NULL;
+   hif_drv->usr_scan_req.scan_result = scan_result;
+   

[PATCH 26/29] staging: wilc1000: avoid deferred handling of cfg80211 disconnect callback

2018-12-02 Thread Ajay.Kathat
From: Ajay Singh 

Refactor disconnect operation callback to handle from the cfg80211
context. The reason code is not required to pass as parameter to the
function, so remove it.

Signed-off-by: Ajay Singh 
---
 drivers/staging/wilc1000/host_interface.c | 39 +++
 drivers/staging/wilc1000/host_interface.h |  2 +-
 drivers/staging/wilc1000/wilc_wfi_cfgoperations.c |  2 +-
 3 files changed, 6 insertions(+), 37 deletions(-)

diff --git a/drivers/staging/wilc1000/host_interface.c 
b/drivers/staging/wilc1000/host_interface.c
index 7ab46ef..6a908ea 100644
--- a/drivers/staging/wilc1000/host_interface.c
+++ b/drivers/staging/wilc1000/host_interface.c
@@ -1241,10 +1241,8 @@ static void handle_rcvd_gnrl_async_info(struct 
work_struct *work)
kfree(msg);
 }
 
-static void handle_disconnect(struct work_struct *work)
+int wilc_disconnect(struct wilc_vif *vif)
 {
-   struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
-   struct wilc_vif *vif = msg->vif;
struct wid wid;
struct host_if_drv *hif_drv = vif->hif_drv;
struct disconnect_info disconn_info;
@@ -1263,10 +1261,9 @@ static void handle_disconnect(struct work_struct *work)
 
result = wilc_send_config_pkt(vif, WILC_SET_CFG, , 1,
  wilc_get_vif_idx(vif));
-
if (result) {
netdev_err(vif->ndev, "Failed to send dissconect\n");
-   goto out;
+   return result;
}
 
memset(_info, 0, sizeof(struct disconnect_info));
@@ -1307,10 +1304,7 @@ static void handle_disconnect(struct work_struct *work)
kfree(conn_req->ies);
conn_req->ies = NULL;
 
-out:
-
-   complete(>work_comp);
-   /* free 'msg' in caller after receiving completion */
+   return 0;
 }
 
 void wilc_resolve_disconnect_aberration(struct wilc_vif *vif)
@@ -1319,7 +1313,7 @@ void wilc_resolve_disconnect_aberration(struct wilc_vif 
*vif)
return;
if (vif->hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP ||
vif->hif_drv->hif_state == HOST_IF_CONNECTING)
-   wilc_disconnect(vif, 1);
+   wilc_disconnect(vif);
 }
 
 int wilc_get_statistics(struct wilc_vif *vif, struct rf_info *stats)
@@ -2012,31 +2006,6 @@ int wilc_set_join_req(struct wilc_vif *vif, u8 *bssid, 
const u8 *ssid,
return result;
 }
 
-int wilc_disconnect(struct wilc_vif *vif, u16 reason_code)
-{
-   int result;
-   struct host_if_msg *msg;
-   struct host_if_drv *hif_drv = vif->hif_drv;
-
-   if (!hif_drv) {
-   netdev_err(vif->ndev, "%s: hif driver is NULL", __func__);
-   return -EFAULT;
-   }
-
-   msg = wilc_alloc_work(vif, handle_disconnect, true);
-   if (IS_ERR(msg))
-   return PTR_ERR(msg);
-
-   result = wilc_enqueue_work(msg);
-   if (result)
-   netdev_err(vif->ndev, "%s: enqueue work failed\n", __func__);
-   else
-   wait_for_completion(>work_comp);
-
-   kfree(msg);
-   return result;
-}
-
 int wilc_set_mac_chnl_num(struct wilc_vif *vif, u8 channel)
 {
struct wid wid;
diff --git a/drivers/staging/wilc1000/host_interface.h 
b/drivers/staging/wilc1000/host_interface.h
index 20af5c4..ac4bdfe 100644
--- a/drivers/staging/wilc1000/host_interface.h
+++ b/drivers/staging/wilc1000/host_interface.h
@@ -264,7 +264,7 @@ int wilc_set_join_req(struct wilc_vif *vif, u8 *bssid, 
const u8 *ssid,
  wilc_connect_result connect_result, void *user_arg,
  u8 security, enum authtype auth_type,
  u8 channel, void *join_params);
-int wilc_disconnect(struct wilc_vif *vif, u16 reason_code);
+int wilc_disconnect(struct wilc_vif *vif);
 int wilc_set_mac_chnl_num(struct wilc_vif *vif, u8 channel);
 int wilc_get_rssi(struct wilc_vif *vif, s8 *rssi_level);
 int wilc_scan(struct wilc_vif *vif, u8 scan_source, u8 scan_type,
diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c 
b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
index 045e365..7cc985e 100644
--- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
+++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
@@ -760,7 +760,7 @@ static int disconnect(struct wiphy *wiphy, struct 
net_device *dev,
priv->p2p.is_wilc_ie = false;
wfi_drv->p2p_timeout = 0;
 
-   ret = wilc_disconnect(vif, reason_code);
+   ret = wilc_disconnect(vif);
if (ret != 0) {
netdev_err(priv->dev, "Error in disconnecting\n");
ret = -EINVAL;
-- 
2.7.4



[PATCH 25/29] staging: wilc1000: handle get_station() ops callback in cfg80211 context

2018-12-02 Thread Ajay.Kathat
From: Ajay Singh 

Refactor code to handle the get_station() callback from cfg80211
context. Provided different API's to fetch the station statistics
information in sync or async call. From cfg80211 get_station() ops
callback calls the sync version of API.

Signed-off-by: Ajay Singh 
---
 drivers/staging/wilc1000/host_interface.c | 38 +++
 drivers/staging/wilc1000/host_interface.h |  3 +-
 drivers/staging/wilc1000/wilc_wfi_cfgoperations.c |  2 +-
 3 files changed, 21 insertions(+), 22 deletions(-)

diff --git a/drivers/staging/wilc1000/host_interface.c 
b/drivers/staging/wilc1000/host_interface.c
index 4762925..7ab46ef 100644
--- a/drivers/staging/wilc1000/host_interface.c
+++ b/drivers/staging/wilc1000/host_interface.c
@@ -1322,13 +1322,10 @@ void wilc_resolve_disconnect_aberration(struct wilc_vif 
*vif)
wilc_disconnect(vif, 1);
 }
 
-static void handle_get_statistics(struct work_struct *work)
+int wilc_get_statistics(struct wilc_vif *vif, struct rf_info *stats)
 {
-   struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
-   struct wilc_vif *vif = msg->vif;
struct wid wid_list[5];
u32 wid_cnt = 0, result;
-   struct rf_info *stats = (struct rf_info *)msg->body.data;
 
wid_list[wid_cnt].id = WID_LINKSPEED;
wid_list[wid_cnt].type = WID_CHAR;
@@ -1364,8 +1361,10 @@ static void handle_get_statistics(struct work_struct 
*work)
  wid_cnt,
  wilc_get_vif_idx(vif));
 
-   if (result)
+   if (result) {
netdev_err(vif->ndev, "Failed to send scan parameters\n");
+   return result;
+   }
 
if (stats->link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH &&
stats->link_speed != DEFAULT_LINK_SPEED)
@@ -1373,11 +1372,18 @@ static void handle_get_statistics(struct work_struct 
*work)
else if (stats->link_speed != DEFAULT_LINK_SPEED)
wilc_enable_tcp_ack_filter(vif, false);
 
-   /* free 'msg' for async command, for sync caller will free it */
-   if (msg->is_sync)
-   complete(>work_comp);
-   else
-   kfree(msg);
+   return result;
+}
+
+static void handle_get_statistics(struct work_struct *work)
+{
+   struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
+   struct wilc_vif *vif = msg->vif;
+   struct rf_info *stats = (struct rf_info *)msg->body.data;
+
+   wilc_get_statistics(vif, stats);
+
+   kfree(msg);
 }
 
 static void wilc_hif_pack_sta_param(u8 *cur_byte, const u8 *mac,
@@ -2149,13 +2155,12 @@ int wilc_get_rssi(struct wilc_vif *vif, s8 *rssi_level)
return result;
 }
 
-int
-wilc_get_statistics(struct wilc_vif *vif, struct rf_info *stats, bool is_sync)
+int wilc_get_stats_async(struct wilc_vif *vif, struct rf_info *stats)
 {
int result;
struct host_if_msg *msg;
 
-   msg = wilc_alloc_work(vif, handle_get_statistics, is_sync);
+   msg = wilc_alloc_work(vif, handle_get_statistics, false);
if (IS_ERR(msg))
return PTR_ERR(msg);
 
@@ -2168,11 +2173,6 @@ wilc_get_statistics(struct wilc_vif *vif, struct rf_info 
*stats, bool is_sync)
return result;
}
 
-   if (is_sync) {
-   wait_for_completion(>work_comp);
-   kfree(msg);
-   }
-
return result;
 }
 
@@ -2297,7 +2297,7 @@ static void get_periodic_rssi(struct timer_list *t)
}
 
if (vif->hif_drv->hif_state == HOST_IF_CONNECTED)
-   wilc_get_statistics(vif, >periodic_stat, false);
+   wilc_get_stats_async(vif, >periodic_stat);
 
mod_timer(>periodic_rssi, jiffies + msecs_to_jiffies(5000));
 }
diff --git a/drivers/staging/wilc1000/host_interface.h 
b/drivers/staging/wilc1000/host_interface.h
index 953f0ea..20af5c4 100644
--- a/drivers/staging/wilc1000/host_interface.h
+++ b/drivers/staging/wilc1000/host_interface.h
@@ -297,8 +297,7 @@ void wilc_frame_register(struct wilc_vif *vif, u16 
frame_type, bool reg);
 int wilc_set_wfi_drv_handler(struct wilc_vif *vif, int index, u8 mode,
 u8 ifc_id);
 int wilc_set_operation_mode(struct wilc_vif *vif, u32 mode);
-int wilc_get_statistics(struct wilc_vif *vif, struct rf_info *stats,
-   bool is_sync);
+int wilc_get_statistics(struct wilc_vif *vif, struct rf_info *stats);
 void wilc_resolve_disconnect_aberration(struct wilc_vif *vif);
 int wilc_get_vif_idx(struct wilc_vif *vif);
 int wilc_set_tx_power(struct wilc_vif *vif, u8 tx_power);
diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c 
b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
index 4c9444e..045e365 100644
--- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
+++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
@@ -1039,7 +1039,7 @@ static int get_station(struct wiphy *wiphy, struct 
net_device *dev,
} 

[PATCH 21/29] staging: wilc1000: delete the unused code after code refactor

2018-12-02 Thread Ajay.Kathat
From: Ajay Singh 

After code refactor some of the macro and variables are not required any
more, so deleted the unused code.

Signed-off-by: Ajay Singh 
---
 drivers/staging/wilc1000/host_interface.c | 31 ---
 drivers/staging/wilc1000/host_interface.h | 27 ---
 2 files changed, 58 deletions(-)

diff --git a/drivers/staging/wilc1000/host_interface.c 
b/drivers/staging/wilc1000/host_interface.c
index 596a321..71395d8 100644
--- a/drivers/staging/wilc1000/host_interface.c
+++ b/drivers/staging/wilc1000/host_interface.c
@@ -13,30 +13,6 @@
 
 #define REAL_JOIN_REQ  0
 
-struct host_if_wpa_attr {
-   u8 *key;
-   const u8 *mac_addr;
-   u8 *seq;
-   u8 seq_len;
-   u8 index;
-   u8 key_len;
-   u8 mode;
-};
-
-struct host_if_wep_attr {
-   u8 *key;
-   u8 key_len;
-   u8 index;
-   u8 mode;
-   enum authtype auth_type;
-};
-
-union host_if_key_attr {
-   struct host_if_wep_attr wep;
-   struct host_if_wpa_attr wpa;
-   struct host_if_pmkid_attr pmkid;
-};
-
 struct scan_attr {
u8 src;
u8 type;
@@ -121,20 +97,13 @@ struct wilc_gtk_key {
u8 key[0];
 } __packed;
 
-struct set_ip_addr {
-   u8 *ip_addr;
-   u8 idx;
-};
-
 union message_body {
struct scan_attr scan_info;
struct connect_attr con_info;
struct rcvd_net_info net_info;
struct rcvd_async_info async_info;
-   struct set_ip_addr ip_info;
struct set_multicast multicast_info;
struct get_mac_addr get_mac_info;
-   struct ba_session_info session_info;
struct remain_ch remain_on_ch;
char *data;
 };
diff --git a/drivers/staging/wilc1000/host_interface.h 
b/drivers/staging/wilc1000/host_interface.h
index 477372b..d2f29ea 100644
--- a/drivers/staging/wilc1000/host_interface.h
+++ b/drivers/staging/wilc1000/host_interface.h
@@ -17,13 +17,6 @@ enum {
WILC_CLIENT_MODE = 0x4
 };
 
-enum {
-   WILC_ADD_KEY = 0x1,
-   WILC_REMOVE_KEY = 0x2,
-   WILC_DEFAULT_KEY = 0x4,
-   WILC_ADD_KEY_AP = 0x8
-};
-
 #define WILC_MAX_NUM_STA   9
 #define MAX_NUM_SCANNED_NETWORKS   100
 #define MAX_NUM_SCANNED_NETWORKS_SHADOW130
@@ -31,16 +24,10 @@ enum {
 
 #define TX_MIC_KEY_LEN 8
 #define RX_MIC_KEY_LEN 8
-#define PTK_KEY_LEN16
 
-#define RX_MIC_KEY_MSG_LEN 48
-#define PTK_KEY_MSG_LEN39
-
-#define PMKSA_KEY_LEN  22
 #define WILC_MAX_NUM_PMKIDS16
 #define WILC_ADD_STA_LENGTH40
 #define WILC_NUM_CONCURRENT_IFC2
-#define WILC_DRV_HANDLER_SIZE  5
 
 #define NUM_RSSI5
 
@@ -160,13 +147,6 @@ enum conn_event {
CONN_DISCONN_EVENT_FORCE_32BIT  = 0x
 };
 
-enum KEY_TYPE {
-   WILC_KEY_TYPE_WEP,
-   WILC_KEY_TYPE_WPA_RX_GTK,
-   WILC_KEY_TYPE_WPA_PTK,
-   WILC_KEY_TYPE_PMKSA,
-};
-
 typedef void (*wilc_scan_result)(enum scan_event, struct network_info *,
 void *, void *);
 
@@ -218,13 +198,6 @@ struct get_mac_addr {
u8 *mac_addr;
 };
 
-struct ba_session_info {
-   u8 bssid[ETH_ALEN];
-   u8 tid;
-   u16 buf_size;
-   u16 time_out;
-};
-
 struct remain_ch {
u16 ch;
u32 duration;
-- 
2.7.4



[PATCH 23/29] staging: wilc1000: use correct 'struct remain_ch' variable in scan complete

2018-12-02 Thread Ajay.Kathat
From: Ajay Singh 

Use the correct reference to remain_ch variable in scan complete.
Passing 'msg->body.remain_on_ch' to handle_remain_on_chan is not
correct. So used the correct reference used to store roc related
information during the scan.

Signed-off-by: Ajay Singh 
---
 drivers/staging/wilc1000/host_interface.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/staging/wilc1000/host_interface.c 
b/drivers/staging/wilc1000/host_interface.c
index dc02561..9139e0e 100644
--- a/drivers/staging/wilc1000/host_interface.c
+++ b/drivers/staging/wilc1000/host_interface.c
@@ -1613,7 +1613,8 @@ static void handle_scan_complete(struct work_struct *work)
handle_scan_done(msg->vif, SCAN_EVENT_DONE);
 
if (msg->vif->hif_drv->remain_on_ch_pending)
-   handle_remain_on_chan(msg->vif, >body.remain_on_ch);
+   handle_remain_on_chan(msg->vif,
+ >vif->hif_drv->remain_on_ch);
kfree(msg);
 }
 
-- 
2.7.4



[PATCH 17/29] staging: wilc1000: refactor wilc_set_operation_mode() to avoid deferred handling

2018-12-02 Thread Ajay.Kathat
From: Ajay Singh 

Avoid handling of WID_CURRENT_CHANNEL wid command in deferred approach.
Instead of posting the wid to work queue now handle directly from the
caller context. Use structure to fill in the firmware specific format.

Signed-off-by: Ajay Singh 
---
 drivers/staging/wilc1000/host_interface.c | 49 ++-
 drivers/staging/wilc1000/host_interface.h |  4 ---
 2 files changed, 16 insertions(+), 37 deletions(-)

diff --git a/drivers/staging/wilc1000/host_interface.c 
b/drivers/staging/wilc1000/host_interface.c
index 1910f9a..312c01e 100644
--- a/drivers/staging/wilc1000/host_interface.c
+++ b/drivers/staging/wilc1000/host_interface.c
@@ -85,6 +85,10 @@ struct del_all_sta {
u8 mac[WILC_MAX_NUM_STA][ETH_ALEN];
 };
 
+struct wilc_op_mode {
+   __le32 mode;
+};
+
 struct wilc_reg_frame {
bool reg;
u8 reg_id;
@@ -111,7 +115,6 @@ union message_body {
struct set_ip_addr ip_info;
struct drv_handler drv;
struct set_multicast multicast_info;
-   struct op_mode mode;
struct get_mac_addr get_mac_info;
struct ba_session_info session_info;
struct remain_ch remain_on_ch;
@@ -261,28 +264,6 @@ static void handle_set_wfi_drv_handler(struct work_struct 
*work)
kfree(msg);
 }
 
-static void handle_set_operation_mode(struct work_struct *work)
-{
-   struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
-   struct wilc_vif *vif = msg->vif;
-   struct op_mode *hif_op_mode = >body.mode;
-   int ret;
-   struct wid wid;
-
-   wid.id = WID_SET_OPERATION_MODE;
-   wid.type = WID_INT;
-   wid.val = (s8 *)_op_mode->mode;
-   wid.size = sizeof(u32);
-
-   ret = wilc_send_config_pkt(vif, WILC_SET_CFG, , 1,
-  wilc_get_vif_idx(vif));
-
-   if (ret)
-   netdev_err(vif->ndev, "Failed to set operation mode\n");
-
-   kfree(msg);
-}
-
 static void handle_get_mac_address(struct work_struct *work)
 {
struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
@@ -2550,19 +2531,21 @@ int wilc_set_wfi_drv_handler(struct wilc_vif *vif, int 
index, u8 mode,
 
 int wilc_set_operation_mode(struct wilc_vif *vif, u32 mode)
 {
+   struct wid wid;
+   struct wilc_op_mode op_mode;
int result;
-   struct host_if_msg *msg;
 
-   msg  = wilc_alloc_work(vif, handle_set_operation_mode, false);
-   if (IS_ERR(msg))
-   return PTR_ERR(msg);
+   wid.id = WID_SET_OPERATION_MODE;
+   wid.type = WID_INT;
+   wid.size = sizeof(op_mode);
+   wid.val = (u8 *)_mode;
 
-   msg->body.mode.mode = mode;
-   result = wilc_enqueue_work(msg);
-   if (result) {
-   netdev_err(vif->ndev, "%s: enqueue work failed\n", __func__);
-   kfree(msg);
-   }
+   op_mode.mode = cpu_to_le32(mode);
+
+   result = wilc_send_config_pkt(vif, WILC_SET_CFG, , 1,
+ wilc_get_vif_idx(vif));
+   if (result)
+   netdev_err(vif->ndev, "Failed to set operation mode\n");
 
return result;
 }
diff --git a/drivers/staging/wilc1000/host_interface.h 
b/drivers/staging/wilc1000/host_interface.h
index 10d5627..e958357 100644
--- a/drivers/staging/wilc1000/host_interface.h
+++ b/drivers/staging/wilc1000/host_interface.h
@@ -220,10 +220,6 @@ struct drv_handler {
u8 name;
 };
 
-struct op_mode {
-   u32 mode;
-};
-
 struct get_mac_addr {
u8 *mac_addr;
 };
-- 
2.7.4



[PATCH 22/29] staging: wilc1000: refactor wilc_get_mac_address() to avoid deferred handling

2018-12-02 Thread Ajay.Kathat
From: Ajay Singh 

Avoid handling of WID_MAC_ADDR wid command in deferred approach. Instead
of posting the wid to workqueue now handle directly from the caller
context.

Signed-off-by: Ajay Singh 
---
 drivers/staging/wilc1000/host_interface.c | 43 ++-
 drivers/staging/wilc1000/host_interface.h |  4 ---
 2 files changed, 8 insertions(+), 39 deletions(-)

diff --git a/drivers/staging/wilc1000/host_interface.c 
b/drivers/staging/wilc1000/host_interface.c
index 71395d8..dc02561 100644
--- a/drivers/staging/wilc1000/host_interface.c
+++ b/drivers/staging/wilc1000/host_interface.c
@@ -103,7 +103,6 @@ union message_body {
struct rcvd_net_info net_info;
struct rcvd_async_info async_info;
struct set_multicast multicast_info;
-   struct get_mac_addr get_mac_info;
struct remain_ch remain_on_ch;
char *data;
 };
@@ -208,28 +207,6 @@ static struct wilc_vif *wilc_get_vif_from_idx(struct wilc 
*wilc, int idx)
return wilc->vif[index];
 }
 
-static void handle_get_mac_address(struct work_struct *work)
-{
-   struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
-   struct wilc_vif *vif = msg->vif;
-   struct get_mac_addr *get_mac_addr = >body.get_mac_info;
-   int ret;
-   struct wid wid;
-
-   wid.id = WID_MAC_ADDR;
-   wid.type = WID_STR;
-   wid.val = get_mac_addr->mac_addr;
-   wid.size = ETH_ALEN;
-
-   ret = wilc_send_config_pkt(vif, WILC_GET_CFG, , 1,
-  wilc_get_vif_idx(vif));
-
-   if (ret)
-   netdev_err(vif->ndev, "Failed to get mac address\n");
-   complete(>work_comp);
-   /* free 'msg' data later, in caller */
-}
-
 static int handle_scan_done(struct wilc_vif *vif, enum scan_event evt)
 {
int result = 0;
@@ -1934,21 +1911,17 @@ int wilc_set_pmkid_info(struct wilc_vif *vif, struct 
wilc_pmkid_attr *pmkid)
 int wilc_get_mac_address(struct wilc_vif *vif, u8 *mac_addr)
 {
int result;
-   struct host_if_msg *msg;
-
-   msg = wilc_alloc_work(vif, handle_get_mac_address, true);
-   if (IS_ERR(msg))
-   return PTR_ERR(msg);
+   struct wid wid;
 
-   msg->body.get_mac_info.mac_addr = mac_addr;
+   wid.id = WID_MAC_ADDR;
+   wid.type = WID_STR;
+   wid.size = ETH_ALEN;
+   wid.val = mac_addr;
 
-   result = wilc_enqueue_work(msg);
+   result = wilc_send_config_pkt(vif, WILC_GET_CFG, , 1,
+ wilc_get_vif_idx(vif));
if (result)
-   netdev_err(vif->ndev, "%s: enqueue work failed\n", __func__);
-   else
-   wait_for_completion(>work_comp);
-
-   kfree(msg);
+   netdev_err(vif->ndev, "Failed to get mac address\n");
 
return result;
 }
diff --git a/drivers/staging/wilc1000/host_interface.h 
b/drivers/staging/wilc1000/host_interface.h
index d2f29ea..953f0ea 100644
--- a/drivers/staging/wilc1000/host_interface.h
+++ b/drivers/staging/wilc1000/host_interface.h
@@ -194,10 +194,6 @@ struct user_conn_req {
void *arg;
 };
 
-struct get_mac_addr {
-   u8 *mac_addr;
-};
-
 struct remain_ch {
u16 ch;
u32 duration;
-- 
2.7.4



[PATCH 19/29] staging: wilc1000: refactor wilc_get_inactive_time() to avoid deferred handling

2018-12-02 Thread Ajay.Kathat
From: Ajay Singh 

Avoid handling of inactive time related wid command in deferred manner.
Instead of posting the wid to workqueue now handle directly from the
caller context.

Signed-off-by: Ajay Singh 
---
 drivers/staging/wilc1000/host_interface.c | 91 ---
 1 file changed, 23 insertions(+), 68 deletions(-)

diff --git a/drivers/staging/wilc1000/host_interface.c 
b/drivers/staging/wilc1000/host_interface.c
index ab770d8..e3dc9b6 100644
--- a/drivers/staging/wilc1000/host_interface.c
+++ b/drivers/staging/wilc1000/host_interface.c
@@ -105,18 +105,12 @@ struct set_ip_addr {
u8 idx;
 };
 
-struct sta_inactive_t {
-   u32 inactive_time;
-   u8 mac[6];
-};
-
 union message_body {
struct scan_attr scan_info;
struct connect_attr con_info;
struct rcvd_net_info net_info;
struct rcvd_async_info async_info;
struct key_attr key_info;
-   struct sta_inactive_t mac_info;
struct set_ip_addr ip_info;
struct set_multicast multicast_info;
struct get_mac_addr get_mac_info;
@@ -1678,48 +1672,6 @@ static void handle_get_statistics(struct work_struct 
*work)
kfree(msg);
 }
 
-static void handle_get_inactive_time(struct work_struct *work)
-{
-   struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
-   struct wilc_vif *vif = msg->vif;
-   struct sta_inactive_t *hif_sta_inactive = >body.mac_info;
-   int result;
-   struct wid wid;
-
-   wid.id = WID_SET_STA_MAC_INACTIVE_TIME;
-   wid.type = WID_STR;
-   wid.size = ETH_ALEN;
-   wid.val = kmalloc(wid.size, GFP_KERNEL);
-   if (!wid.val)
-   goto out;
-
-   ether_addr_copy(wid.val, hif_sta_inactive->mac);
-
-   result = wilc_send_config_pkt(vif, WILC_SET_CFG, , 1,
- wilc_get_vif_idx(vif));
-   kfree(wid.val);
-
-   if (result) {
-   netdev_err(vif->ndev, "Failed to set inactive mac\n");
-   goto out;
-   }
-
-   wid.id = WID_GET_INACTIVE_TIME;
-   wid.type = WID_INT;
-   wid.val = (s8 *)_sta_inactive->inactive_time;
-   wid.size = sizeof(u32);
-
-   result = wilc_send_config_pkt(vif, WILC_GET_CFG, , 1,
- wilc_get_vif_idx(vif));
-
-   if (result)
-   netdev_err(vif->ndev, "Failed to get inactive time\n");
-
-out:
-   /* free 'msg' data in caller */
-   complete(>work_comp);
-}
-
 static void wilc_hif_pack_sta_param(u8 *cur_byte, const u8 *mac,
struct station_parameters *params)
 {
@@ -2508,32 +2460,35 @@ int wilc_set_operation_mode(struct wilc_vif *vif, u32 
mode)
return result;
 }
 
-s32 wilc_get_inactive_time(struct wilc_vif *vif, const u8 *mac,
-  u32 *out_val)
+s32 wilc_get_inactive_time(struct wilc_vif *vif, const u8 *mac, u32 *out_val)
 {
+   struct wid wid;
s32 result;
-   struct host_if_msg *msg;
-   struct host_if_drv *hif_drv = vif->hif_drv;
-
-   if (!hif_drv) {
-   netdev_err(vif->ndev, "%s: hif driver is NULL", __func__);
-   return -EFAULT;
-   }
 
-   msg = wilc_alloc_work(vif, handle_get_inactive_time, true);
-   if (IS_ERR(msg))
-   return PTR_ERR(msg);
+   wid.id = WID_SET_STA_MAC_INACTIVE_TIME;
+   wid.type = WID_STR;
+   wid.size = ETH_ALEN;
+   wid.val = kzalloc(wid.size, GFP_KERNEL);
+   if (!wid.val)
+   return -ENOMEM;
 
-   memcpy(msg->body.mac_info.mac, mac, ETH_ALEN);
+   ether_addr_copy(wid.val, mac);
+   result = wilc_send_config_pkt(vif, WILC_SET_CFG, , 1,
+ wilc_get_vif_idx(vif));
+   kfree(wid.val);
+   if (result) {
+   netdev_err(vif->ndev, "Failed to set inactive mac\n");
+   return result;
+   }
 
-   result = wilc_enqueue_work(msg);
+   wid.id = WID_GET_INACTIVE_TIME;
+   wid.type = WID_INT;
+   wid.val = (s8 *)out_val;
+   wid.size = sizeof(u32);
+   result = wilc_send_config_pkt(vif, WILC_GET_CFG, , 1,
+ wilc_get_vif_idx(vif));
if (result)
-   netdev_err(vif->ndev, "%s: enqueue work failed\n", __func__);
-   else
-   wait_for_completion(>work_comp);
-
-   *out_val = msg->body.mac_info.inactive_time;
-   kfree(msg);
+   netdev_err(vif->ndev, "Failed to get inactive time\n");
 
return result;
 }
-- 
2.7.4



[PATCH 15/29] staging: wilc1000: refactor wilc_hif_set_cfg() to avoid deferred handling

2018-12-02 Thread Ajay.Kathat
From: Ajay Singh 

Avoid handling configuration params wid command in deferred approach.
Instead of posting to workqueue now handle directly from the caller
context. Reduce the size of wid array from 32 to 4 as maximum only 4 wid
used at a time.

Signed-off-by: Ajay Singh 
---
 drivers/staging/wilc1000/host_interface.c | 95 +++
 1 file changed, 32 insertions(+), 63 deletions(-)

diff --git a/drivers/staging/wilc1000/host_interface.c 
b/drivers/staging/wilc1000/host_interface.c
index f6bd76c..6b1c9e3 100644
--- a/drivers/staging/wilc1000/host_interface.c
+++ b/drivers/staging/wilc1000/host_interface.c
@@ -107,7 +107,6 @@ union message_body {
struct rcvd_net_info net_info;
struct rcvd_async_info async_info;
struct key_attr key_info;
-   struct cfg_param_attr cfg_info;
struct sta_inactive_t mac_info;
struct set_ip_addr ip_info;
struct drv_handler drv;
@@ -306,53 +305,6 @@ static void handle_get_mac_address(struct work_struct 
*work)
/* free 'msg' data later, in caller */
 }
 
-static void handle_cfg_param(struct work_struct *work)
-{
-   struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
-   struct wilc_vif *vif = msg->vif;
-   struct cfg_param_attr *param = >body.cfg_info;
-   int ret;
-   struct wid wid_list[32];
-   int i = 0;
-
-   if (param->flag & WILC_CFG_PARAM_RETRY_SHORT) {
-   wid_list[i].id = WID_SHORT_RETRY_LIMIT;
-   wid_list[i].val = (s8 *)>short_retry_limit;
-   wid_list[i].type = WID_SHORT;
-   wid_list[i].size = sizeof(u16);
-   i++;
-   }
-   if (param->flag & WILC_CFG_PARAM_RETRY_LONG) {
-   wid_list[i].id = WID_LONG_RETRY_LIMIT;
-   wid_list[i].val = (s8 *)>long_retry_limit;
-   wid_list[i].type = WID_SHORT;
-   wid_list[i].size = sizeof(u16);
-   i++;
-   }
-   if (param->flag & WILC_CFG_PARAM_FRAG_THRESHOLD) {
-   wid_list[i].id = WID_FRAG_THRESHOLD;
-   wid_list[i].val = (s8 *)>frag_threshold;
-   wid_list[i].type = WID_SHORT;
-   wid_list[i].size = sizeof(u16);
-   i++;
-   }
-   if (param->flag & WILC_CFG_PARAM_RTS_THRESHOLD) {
-   wid_list[i].id = WID_RTS_THRESHOLD;
-   wid_list[i].val = (s8 *)>rts_threshold;
-   wid_list[i].type = WID_SHORT;
-   wid_list[i].size = sizeof(u16);
-   i++;
-   }
-
-   ret = wilc_send_config_pkt(vif, WILC_SET_CFG, wid_list,
-  i, wilc_get_vif_idx(vif));
-
-   if (ret)
-   netdev_err(vif->ndev, "Error in setting CFG params\n");
-
-   kfree(msg);
-}
-
 static int handle_scan_done(struct wilc_vif *vif, enum scan_event evt)
 {
int result = 0;
@@ -2797,26 +2749,43 @@ int wilc_scan(struct wilc_vif *vif, u8 scan_source, u8 
scan_type,
return result;
 }
 
-int wilc_hif_set_cfg(struct wilc_vif *vif,
-struct cfg_param_attr *cfg_param)
+int wilc_hif_set_cfg(struct wilc_vif *vif, struct cfg_param_attr *param)
 {
-   struct host_if_msg *msg;
-   struct host_if_drv *hif_drv = vif->hif_drv;
+   struct wid wid_list[4];
+   int i = 0;
int result;
 
-   if (!hif_drv) {
-   netdev_err(vif->ndev, "%s: hif driver is NULL", __func__);
-   return -EFAULT;
+   if (param->flag & WILC_CFG_PARAM_RETRY_SHORT) {
+   wid_list[i].id = WID_SHORT_RETRY_LIMIT;
+   wid_list[i].val = (s8 *)>short_retry_limit;
+   wid_list[i].type = WID_SHORT;
+   wid_list[i].size = sizeof(u16);
+   i++;
+   }
+   if (param->flag & WILC_CFG_PARAM_RETRY_LONG) {
+   wid_list[i].id = WID_LONG_RETRY_LIMIT;
+   wid_list[i].val = (s8 *)>long_retry_limit;
+   wid_list[i].type = WID_SHORT;
+   wid_list[i].size = sizeof(u16);
+   i++;
+   }
+   if (param->flag & WILC_CFG_PARAM_FRAG_THRESHOLD) {
+   wid_list[i].id = WID_FRAG_THRESHOLD;
+   wid_list[i].val = (s8 *)>frag_threshold;
+   wid_list[i].type = WID_SHORT;
+   wid_list[i].size = sizeof(u16);
+   i++;
+   }
+   if (param->flag & WILC_CFG_PARAM_RTS_THRESHOLD) {
+   wid_list[i].id = WID_RTS_THRESHOLD;
+   wid_list[i].val = (s8 *)>rts_threshold;
+   wid_list[i].type = WID_SHORT;
+   wid_list[i].size = sizeof(u16);
+   i++;
}
 
-   msg = wilc_alloc_work(vif, handle_cfg_param, false);
-   if (IS_ERR(msg))
-   return PTR_ERR(msg);
-
-   msg->body.cfg_info = *cfg_param;
-   result = wilc_enqueue_work(msg);
-   if (result)
-   kfree(msg);
+   result = wilc_send_config_pkt(vif, WILC_SET_CFG, wid_list,
+   

[PATCH 16/29] staging: wilc1000: handle station dump cfg ops from cfg80211 context

2018-12-02 Thread Ajay.Kathat
From: Ajay Singh 

Refactor code to handle dump_station() callback from cfg80211 context.
Instead of deferring issue of wid command now send it directly from cfg
context. Also making use of wilc_get_rssi() error status in case there
is a failure to post the wid command to the firmware.

Signed-off-by: Ajay Singh 
---
 drivers/staging/wilc1000/host_interface.c | 51 ---
 drivers/staging/wilc1000/wilc_wfi_cfgoperations.c |  5 ++-
 2 files changed, 13 insertions(+), 43 deletions(-)

diff --git a/drivers/staging/wilc1000/host_interface.c 
b/drivers/staging/wilc1000/host_interface.c
index 6b1c9e3..1910f9a 100644
--- a/drivers/staging/wilc1000/host_interface.c
+++ b/drivers/staging/wilc1000/host_interface.c
@@ -1678,27 +1678,6 @@ void wilc_resolve_disconnect_aberration(struct wilc_vif 
*vif)
wilc_disconnect(vif, 1);
 }
 
-static void handle_get_rssi(struct work_struct *work)
-{
-   struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
-   struct wilc_vif *vif = msg->vif;
-   int result;
-   struct wid wid;
-
-   wid.id = WID_RSSI;
-   wid.type = WID_CHAR;
-   wid.val = msg->body.data;
-   wid.size = sizeof(char);
-
-   result = wilc_send_config_pkt(vif, WILC_GET_CFG, , 1,
- wilc_get_vif_idx(vif));
-   if (result)
-   netdev_err(vif->ndev, "Failed to get RSSI value\n");
-
-   complete(>work_comp);
-   /* free 'msg' data in caller */
-}
-
 static void handle_get_statistics(struct work_struct *work)
 {
struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
@@ -2620,34 +2599,22 @@ s32 wilc_get_inactive_time(struct wilc_vif *vif, const 
u8 *mac,
 
 int wilc_get_rssi(struct wilc_vif *vif, s8 *rssi_level)
 {
+   struct wid wid;
int result;
-   struct host_if_msg *msg;
 
if (!rssi_level) {
netdev_err(vif->ndev, "%s: RSSI level is NULL\n", __func__);
return -EFAULT;
}
 
-   msg = wilc_alloc_work(vif, handle_get_rssi, true);
-   if (IS_ERR(msg))
-   return PTR_ERR(msg);
-
-   msg->body.data = kzalloc(sizeof(s8), GFP_KERNEL);
-   if (!msg->body.data) {
-   kfree(msg);
-   return -ENOMEM;
-   }
-
-   result = wilc_enqueue_work(msg);
-   if (result) {
-   netdev_err(vif->ndev, "%s: enqueue work failed\n", __func__);
-   } else {
-   wait_for_completion(>work_comp);
-   *rssi_level = *msg->body.data;
-   }
-
-   kfree(msg->body.data);
-   kfree(msg);
+   wid.id = WID_RSSI;
+   wid.type = WID_CHAR;
+   wid.size = sizeof(char);
+   wid.val = rssi_level;
+   result = wilc_send_config_pkt(vif, WILC_GET_CFG, , 1,
+ wilc_get_vif_idx(vif));
+   if (result)
+   netdev_err(vif->ndev, "Failed to get RSSI value\n");
 
return result;
 }
diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c 
b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
index 18370ef..4802ce9 100644
--- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
+++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
@@ -1659,13 +1659,16 @@ static int dump_station(struct wiphy *wiphy, struct 
net_device *dev,
 {
struct wilc_priv *priv = wiphy_priv(wiphy);
struct wilc_vif *vif = netdev_priv(priv->dev);
+   int ret;
 
if (idx != 0)
return -ENOENT;
 
sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL);
 
-   wilc_get_rssi(vif, >signal);
+   ret = wilc_get_rssi(vif, >signal);
+   if (ret)
+   return ret;
 
memcpy(mac, priv->associated_bss, ETH_ALEN);
return 0;
-- 
2.7.4



[PATCH 18/29] staging: wilc1000: refactor wilc_set_wfi_drv_handler() to avoid deferred handling

2018-12-02 Thread Ajay.Kathat
From: Ajay Singh 

Avoid handling of WID_SET_DRV_HANDLER wid command in deferred approach.
Instead of posting the wid to work queue now handle directly from the
caller context. Remove 'is_sync' parameter from the API as it's not
required anymore.

Signed-off-by: Ajay Singh 
---
 drivers/staging/wilc1000/host_interface.c | 82 ++-
 drivers/staging/wilc1000/host_interface.h |  8 +--
 drivers/staging/wilc1000/linux_wlan.c |  3 +-
 drivers/staging/wilc1000/wilc_wfi_cfgoperations.c |  2 +-
 4 files changed, 23 insertions(+), 72 deletions(-)

diff --git a/drivers/staging/wilc1000/host_interface.c 
b/drivers/staging/wilc1000/host_interface.c
index 312c01e..ab770d8 100644
--- a/drivers/staging/wilc1000/host_interface.c
+++ b/drivers/staging/wilc1000/host_interface.c
@@ -95,6 +95,11 @@ struct wilc_reg_frame {
__le32 frame_type;
 } __packed;
 
+struct wilc_drv_handler {
+   __le32 handler;
+   u8 mode;
+} __packed;
+
 struct set_ip_addr {
u8 *ip_addr;
u8 idx;
@@ -113,7 +118,6 @@ union message_body {
struct key_attr key_info;
struct sta_inactive_t mac_info;
struct set_ip_addr ip_info;
-   struct drv_handler drv;
struct set_multicast multicast_info;
struct get_mac_addr get_mac_info;
struct ba_session_info session_info;
@@ -221,49 +225,6 @@ static struct wilc_vif *wilc_get_vif_from_idx(struct wilc 
*wilc, int idx)
return wilc->vif[index];
 }
 
-static void handle_set_wfi_drv_handler(struct work_struct *work)
-{
-   struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
-   struct wilc_vif *vif = msg->vif;
-   struct drv_handler *hif_drv_handler = >body.drv;
-   int ret;
-   struct wid wid;
-   u8 *currbyte, *buffer;
-   struct host_if_drv *hif_drv;
-
-   if (!vif->hif_drv || !hif_drv_handler)
-   goto free_msg;
-
-   hif_drv = vif->hif_drv;
-
-   buffer = kzalloc(WILC_DRV_HANDLER_SIZE, GFP_KERNEL);
-   if (!buffer)
-   goto free_msg;
-
-   currbyte = buffer;
-   put_unaligned_le32(hif_drv->driver_handler_id, currbyte);
-   currbyte += 4;
-   *currbyte = (hif_drv_handler->name | (hif_drv_handler->mode << 1));
-
-   wid.id = WID_SET_DRV_HANDLER;
-   wid.type = WID_STR;
-   wid.val = (s8 *)buffer;
-   wid.size = WILC_DRV_HANDLER_SIZE;
-
-   ret = wilc_send_config_pkt(vif, WILC_SET_CFG, , 1,
-  hif_drv->driver_handler_id);
-   if (ret)
-   netdev_err(vif->ndev, "Failed to set driver handler\n");
-
-   kfree(buffer);
-
-free_msg:
-   if (msg->is_sync)
-   complete(>work_comp);
-
-   kfree(msg);
-}
-
 static void handle_get_mac_address(struct work_struct *work)
 {
struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
@@ -2503,28 +2464,25 @@ int wilc_set_mac_chnl_num(struct wilc_vif *vif, u8 
channel)
 }
 
 int wilc_set_wfi_drv_handler(struct wilc_vif *vif, int index, u8 mode,
-u8 ifc_id, bool is_sync)
+u8 ifc_id)
 {
+   struct wid wid;
+   struct host_if_drv *hif_drv = vif->hif_drv;
int result;
-   struct host_if_msg *msg;
-
-   msg = wilc_alloc_work(vif, handle_set_wfi_drv_handler, is_sync);
-   if (IS_ERR(msg))
-   return PTR_ERR(msg);
+   struct wilc_drv_handler drv;
 
-   msg->body.drv.handler = index;
-   msg->body.drv.mode = mode;
-   msg->body.drv.name = ifc_id;
+   wid.id = WID_SET_DRV_HANDLER;
+   wid.type = WID_STR;
+   wid.size = sizeof(drv);
+   wid.val = (u8 *)
 
-   result = wilc_enqueue_work(msg);
-   if (result) {
-   netdev_err(vif->ndev, "%s: enqueue work failed\n", __func__);
-   kfree(msg);
-   return result;
-   }
+   drv.handler = cpu_to_le32(index);
+   drv.mode = (ifc_id | (mode << 1));
 
-   if (is_sync)
-   wait_for_completion(>work_comp);
+   result = wilc_send_config_pkt(vif, WILC_SET_CFG, , 1,
+ hif_drv->driver_handler_id);
+   if (result)
+   netdev_err(vif->ndev, "Failed to set driver handler\n");
 
return result;
 }
@@ -2814,7 +2772,7 @@ int wilc_deinit(struct wilc_vif *vif)
del_timer_sync(>periodic_rssi);
del_timer_sync(_drv->remain_on_ch_timer);
 
-   wilc_set_wfi_drv_handler(vif, 0, 0, 0, true);
+   wilc_set_wfi_drv_handler(vif, 0, 0, 0);
 
if (hif_drv->usr_scan_req.scan_result) {
hif_drv->usr_scan_req.scan_result(SCAN_EVENT_ABORTED, NULL,
diff --git a/drivers/staging/wilc1000/host_interface.h 
b/drivers/staging/wilc1000/host_interface.h
index e958357..7748f65 100644
--- a/drivers/staging/wilc1000/host_interface.h
+++ b/drivers/staging/wilc1000/host_interface.h
@@ -214,12 +214,6 @@ struct user_conn_req {
void *arg;
 };
 

[PATCH 20/29] staging: wilc1000: handle key related cfg operation from cfg80211 context

2018-12-02 Thread Ajay.Kathat
From: Ajay Singh 

Refactor add/delete key operation to handle directly from cfg80211
context. Also, avoid an extra copy of the information in hif layer and
directly fill the buffer in firmware format.

Signed-off-by: Ajay Singh 
---
 drivers/staging/wilc1000/host_interface.c | 691 ++
 drivers/staging/wilc1000/host_interface.h |  13 +-
 drivers/staging/wilc1000/wilc_wfi_cfgoperations.c |   4 +-
 drivers/staging/wilc1000/wilc_wfi_netdevice.h |   2 +-
 4 files changed, 204 insertions(+), 506 deletions(-)

diff --git a/drivers/staging/wilc1000/host_interface.c 
b/drivers/staging/wilc1000/host_interface.c
index e3dc9b6..596a321 100644
--- a/drivers/staging/wilc1000/host_interface.c
+++ b/drivers/staging/wilc1000/host_interface.c
@@ -37,12 +37,6 @@ union host_if_key_attr {
struct host_if_pmkid_attr pmkid;
 };
 
-struct key_attr {
-   enum KEY_TYPE type;
-   u8 action;
-   union host_if_key_attr attr;
-};
-
 struct scan_attr {
u8 src;
u8 type;
@@ -100,6 +94,33 @@ struct wilc_drv_handler {
u8 mode;
 } __packed;
 
+struct wilc_wep_key {
+   u8 index;
+   u8 key_len;
+   u8 key[0];
+} __packed;
+
+struct wilc_sta_wpa_ptk {
+   u8 mac_addr[ETH_ALEN];
+   u8 key_len;
+   u8 key[0];
+} __packed;
+
+struct wilc_ap_wpa_ptk {
+   u8 mac_addr[ETH_ALEN];
+   u8 index;
+   u8 key_len;
+   u8 key[0];
+} __packed;
+
+struct wilc_gtk_key {
+   u8 mac_addr[ETH_ALEN];
+   u8 rsc[8];
+   u8 index;
+   u8 key_len;
+   u8 key[0];
+} __packed;
+
 struct set_ip_addr {
u8 *ip_addr;
u8 idx;
@@ -110,7 +131,6 @@ union message_body {
struct connect_attr con_info;
struct rcvd_net_info net_info;
struct rcvd_async_info async_info;
-   struct key_attr key_info;
struct set_ip_addr ip_info;
struct set_multicast multicast_info;
struct get_mac_addr get_mac_info;
@@ -1275,264 +1295,6 @@ static void handle_rcvd_gnrl_async_info(struct 
work_struct *work)
kfree(msg);
 }
 
-static int wilc_pmksa_key_copy(struct wilc_vif *vif, struct key_attr *hif_key)
-{
-   int i;
-   int ret;
-   struct wid wid;
-   u8 *key_buf;
-
-   key_buf = kmalloc((hif_key->attr.pmkid.numpmkid * PMKSA_KEY_LEN) + 1,
- GFP_KERNEL);
-   if (!key_buf)
-   return -ENOMEM;
-
-   key_buf[0] = hif_key->attr.pmkid.numpmkid;
-
-   for (i = 0; i < hif_key->attr.pmkid.numpmkid; i++) {
-   memcpy(key_buf + ((PMKSA_KEY_LEN * i) + 1),
-  hif_key->attr.pmkid.pmkidlist[i].bssid, ETH_ALEN);
-   memcpy(key_buf + ((PMKSA_KEY_LEN * i) + ETH_ALEN + 1),
-  hif_key->attr.pmkid.pmkidlist[i].pmkid, WLAN_PMKID_LEN);
-   }
-
-   wid.id = WID_PMKID_INFO;
-   wid.type = WID_STR;
-   wid.val = (s8 *)key_buf;
-   wid.size = (hif_key->attr.pmkid.numpmkid * PMKSA_KEY_LEN) + 1;
-
-   ret = wilc_send_config_pkt(vif, WILC_SET_CFG, , 1,
-  wilc_get_vif_idx(vif));
-
-   kfree(key_buf);
-
-   return ret;
-}
-
-static void handle_key(struct work_struct *work)
-{
-   struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
-   struct wilc_vif *vif = msg->vif;
-   struct key_attr *hif_key = >body.key_info;
-   int result = 0;
-   struct wid wid;
-   struct wid wid_list[5];
-   u8 *key_buf;
-   struct host_if_drv *hif_drv = vif->hif_drv;
-
-   switch (hif_key->type) {
-   case WILC_KEY_TYPE_WEP:
-
-   if (hif_key->action & WILC_ADD_KEY_AP) {
-   wid_list[0].id = WID_11I_MODE;
-   wid_list[0].type = WID_CHAR;
-   wid_list[0].size = sizeof(char);
-   wid_list[0].val = (s8 *)_key->attr.wep.mode;
-
-   wid_list[1].id = WID_AUTH_TYPE;
-   wid_list[1].type = WID_CHAR;
-   wid_list[1].size = sizeof(char);
-   wid_list[1].val = (s8 *)_key->attr.wep.auth_type;
-
-   key_buf = kmalloc(hif_key->attr.wep.key_len + 2,
- GFP_KERNEL);
-   if (!key_buf) {
-   result = -ENOMEM;
-   goto out_wep;
-   }
-
-   key_buf[0] = hif_key->attr.wep.index;
-   key_buf[1] = hif_key->attr.wep.key_len;
-
-   memcpy(_buf[2], hif_key->attr.wep.key,
-  hif_key->attr.wep.key_len);
-
-   wid_list[2].id = WID_WEP_KEY_VALUE;
-   wid_list[2].type = WID_STR;
-   wid_list[2].size = hif_key->attr.wep.key_len + 2;
-   wid_list[2].val = (s8 *)key_buf;
-
-   result = wilc_send_config_pkt(vif, 

[PATCH 24/29] staging: wilc1000: handle remain on channel cfg ops from cfg80211 context

2018-12-02 Thread Ajay.Kathat
From: Ajay Singh 

Refactor wilc_remain_on_channel() to handle remain_on_channel callback
from cfg80211 context.

Signed-off-by: Ajay Singh 
---
 drivers/staging/wilc1000/host_interface.c | 36 ++-
 1 file changed, 11 insertions(+), 25 deletions(-)

diff --git a/drivers/staging/wilc1000/host_interface.c 
b/drivers/staging/wilc1000/host_interface.c
index 9139e0e..4762925 100644
--- a/drivers/staging/wilc1000/host_interface.c
+++ b/drivers/staging/wilc1000/host_interface.c
@@ -1592,14 +1592,6 @@ static void handle_scan_timer(struct work_struct *work)
kfree(msg);
 }
 
-static void handle_remain_on_chan_work(struct work_struct *work)
-{
-   struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
-
-   handle_remain_on_chan(msg->vif, >body.remain_on_ch);
-   kfree(msg);
-}
-
 static void handle_scan_complete(struct work_struct *work)
 {
struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
@@ -2527,25 +2519,19 @@ int wilc_remain_on_channel(struct wilc_vif *vif, u32 
session_id,
   wilc_remain_on_chan_ready ready,
   void *user_arg)
 {
+   struct remain_ch roc;
int result;
-   struct host_if_msg *msg;
-
-   msg = wilc_alloc_work(vif, handle_remain_on_chan_work, false);
-   if (IS_ERR(msg))
-   return PTR_ERR(msg);
 
-   msg->body.remain_on_ch.ch = chan;
-   msg->body.remain_on_ch.expired = expired;
-   msg->body.remain_on_ch.ready = ready;
-   msg->body.remain_on_ch.arg = user_arg;
-   msg->body.remain_on_ch.duration = duration;
-   msg->body.remain_on_ch.id = session_id;
-
-   result = wilc_enqueue_work(msg);
-   if (result) {
-   netdev_err(vif->ndev, "%s: enqueue work failed\n", __func__);
-   kfree(msg);
-   }
+   roc.ch = chan;
+   roc.expired = expired;
+   roc.ready = ready;
+   roc.arg = user_arg;
+   roc.duration = duration;
+   roc.id = session_id;
+   result = handle_remain_on_chan(vif, );
+   if (result)
+   netdev_err(vif->ndev, "%s: failed to set remain on channel\n",
+  __func__);
 
return result;
 }
-- 
2.7.4



[PATCH 10/29] staging: wilc1000: use is_zero_ether_addr() API to check mac address

2018-12-02 Thread Ajay.Kathat
From: Ajay Singh 

Use is_zero_ether_addr() API to check if mac address value is zero.

Signed-off-by: Ajay Singh 
---
 drivers/staging/wilc1000/host_interface.c | 3 +--
 drivers/staging/wilc1000/linux_wlan.c | 3 +--
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/staging/wilc1000/host_interface.c 
b/drivers/staging/wilc1000/host_interface.c
index 8ce56a3..310138d 100644
--- a/drivers/staging/wilc1000/host_interface.c
+++ b/drivers/staging/wilc1000/host_interface.c
@@ -3400,13 +3400,12 @@ int wilc_del_allstation(struct wilc_vif *vif, u8 
mac_addr[][ETH_ALEN])
struct wid wid;
int result;
int i;
-   u8 zero_addr[ETH_ALEN] = {0};
u8 assoc_sta = 0;
struct del_all_sta del_sta;
 
memset(_sta, 0x0, sizeof(del_sta));
for (i = 0; i < WILC_MAX_NUM_STA; i++) {
-   if (memcmp(mac_addr[i], zero_addr, ETH_ALEN)) {
+   if (!is_zero_ether_addr(mac_addr[i])) {
assoc_sta++;
ether_addr_copy(del_sta.mac[i], mac_addr[i]);
}
diff --git a/drivers/staging/wilc1000/linux_wlan.c 
b/drivers/staging/wilc1000/linux_wlan.c
index e246d18..142816a 100644
--- a/drivers/staging/wilc1000/linux_wlan.c
+++ b/drivers/staging/wilc1000/linux_wlan.c
@@ -205,11 +205,10 @@ void wilc_wlan_set_bssid(struct net_device *wilc_netdev, 
u8 *bssid, u8 mode)
 int wilc_wlan_get_num_conn_ifcs(struct wilc *wilc)
 {
u8 i = 0;
-   u8 null_bssid[6] = {0};
u8 ret_val = 0;
 
for (i = 0; i < wilc->vif_num; i++)
-   if (memcmp(wilc->vif[i]->bssid, null_bssid, 6))
+   if (!is_zero_ether_addr(wilc->vif[i]->bssid))
ret_val++;
 
return ret_val;
-- 
2.7.4



[PATCH 08/29] staging: wilc1000: use void return for wilc_hif_pack_sta_param()

2018-12-02 Thread Ajay.Kathat
From: Ajay Singh 

Change the return type from u32 to void for wilc_hif_pack_sta_param() as
its value is not used. Also remove the use of extra pointer as it's not
required now.

Signed-off-by: Ajay Singh 
---
 drivers/staging/wilc1000/host_interface.c | 14 --
 1 file changed, 4 insertions(+), 10 deletions(-)

diff --git a/drivers/staging/wilc1000/host_interface.c 
b/drivers/staging/wilc1000/host_interface.c
index fedcff8..40477ca 100644
--- a/drivers/staging/wilc1000/host_interface.c
+++ b/drivers/staging/wilc1000/host_interface.c
@@ -1960,12 +1960,9 @@ static void handle_del_beacon(struct work_struct *work)
kfree(msg);
 }
 
-static u32 wilc_hif_pack_sta_param(u8 *buff, const u8 *mac,
-  struct station_parameters *params)
+static void wilc_hif_pack_sta_param(u8 *cur_byte, const u8 *mac,
+   struct station_parameters *params)
 {
-   u8 *cur_byte;
-
-   cur_byte = buff;
ether_addr_copy(cur_byte, mac);
cur_byte += ETH_ALEN;
 
@@ -1990,9 +1987,6 @@ static u32 wilc_hif_pack_sta_param(u8 *buff, const u8 
*mac,
put_unaligned_le16(params->sta_flags_mask, cur_byte);
cur_byte += 2;
put_unaligned_le16(params->sta_flags_set, cur_byte);
-   cur_byte += 2;
-
-   return cur_byte - buff;
 }
 
 static void handle_del_all_sta(struct work_struct *work)
@@ -3440,7 +3434,7 @@ int wilc_add_station(struct wilc_vif *vif, const u8 *mac,
return -ENOMEM;
 
cur_byte = wid.val;
-   cur_byte += wilc_hif_pack_sta_param(cur_byte, mac, params);
+   wilc_hif_pack_sta_param(cur_byte, mac, params);
 
result = wilc_send_config_pkt(vif, WILC_SET_CFG, , 1,
  wilc_get_vif_idx(vif));
@@ -3532,7 +3526,7 @@ int wilc_edit_station(struct wilc_vif *vif, const u8 *mac,
return -ENOMEM;
 
cur_byte = wid.val;
-   cur_byte += wilc_hif_pack_sta_param(cur_byte, mac, params);
+   wilc_hif_pack_sta_param(cur_byte, mac, params);
 
result = wilc_send_config_pkt(vif, WILC_SET_CFG, , 1,
  wilc_get_vif_idx(vif));
-- 
2.7.4



[PATCH 13/29] staging: wilc1000: handle mgmt_frame_register ops from cfg82011 context

2018-12-02 Thread Ajay.Kathat
From: Ajay Singh 

Avoid handling of mgmt_frame_register operation callback in a deferred
manner. Now set the wid command to firmware directly from caller
context.

Signed-off-by: Ajay Singh 
---
 drivers/staging/wilc1000/host_interface.c | 70 ++-
 drivers/staging/wilc1000/host_interface.h |  6 ---
 2 files changed, 22 insertions(+), 54 deletions(-)

diff --git a/drivers/staging/wilc1000/host_interface.c 
b/drivers/staging/wilc1000/host_interface.c
index 97b84d2..4d1fa4a 100644
--- a/drivers/staging/wilc1000/host_interface.c
+++ b/drivers/staging/wilc1000/host_interface.c
@@ -89,6 +89,12 @@ struct del_all_sta {
u8 mac[WILC_MAX_NUM_STA][ETH_ALEN];
 };
 
+struct wilc_reg_frame {
+   bool reg;
+   u8 reg_id;
+   __le32 frame_type;
+} __packed;
+
 struct set_ip_addr {
u8 *ip_addr;
u8 idx;
@@ -115,7 +121,6 @@ union message_body {
struct get_mac_addr get_mac_info;
struct ba_session_info session_info;
struct remain_ch remain_on_ch;
-   struct reg_frame reg_frame;
char *data;
 };
 
@@ -1963,39 +1968,6 @@ static int handle_remain_on_chan(struct wilc_vif *vif,
return result;
 }
 
-static void handle_register_frame(struct work_struct *work)
-{
-   struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
-   struct wilc_vif *vif = msg->vif;
-   struct reg_frame *hif_reg_frame = >body.reg_frame;
-   int result;
-   struct wid wid;
-   u8 *cur_byte;
-
-   wid.id = WID_REGISTER_FRAME;
-   wid.type = WID_STR;
-   wid.val = kmalloc(sizeof(u16) + 2, GFP_KERNEL);
-   if (!wid.val)
-   goto out;
-
-   cur_byte = wid.val;
-
-   *cur_byte++ = hif_reg_frame->reg;
-   *cur_byte++ = hif_reg_frame->reg_id;
-   memcpy(cur_byte, _reg_frame->frame_type, sizeof(u16));
-
-   wid.size = sizeof(u16) + 2;
-
-   result = wilc_send_config_pkt(vif, WILC_SET_CFG, , 1,
- wilc_get_vif_idx(vif));
-   kfree(wid.val);
-   if (result)
-   netdev_err(vif->ndev, "Failed to frame register\n");
-
-out:
-   kfree(msg);
-}
-
 static void handle_listen_state_expired(struct work_struct *work)
 {
struct host_if_msg *msg = container_of(work, struct host_if_msg, work);
@@ -3162,33 +3134,35 @@ int wilc_listen_state_expired(struct wilc_vif *vif, u32 
session_id)
 
 void wilc_frame_register(struct wilc_vif *vif, u16 frame_type, bool reg)
 {
+   struct wid wid;
int result;
-   struct host_if_msg *msg;
+   struct wilc_reg_frame reg_frame;
 
-   msg = wilc_alloc_work(vif, handle_register_frame, false);
-   if (IS_ERR(msg))
-   return;
+   wid.id = WID_REGISTER_FRAME;
+   wid.type = WID_STR;
+   wid.size = sizeof(reg_frame);
+   wid.val = (u8 *)_frame;
+
+   memset(_frame, 0x0, sizeof(reg_frame));
+   reg_frame.reg = reg;
 
switch (frame_type) {
case IEEE80211_STYPE_ACTION:
-   msg->body.reg_frame.reg_id = WILC_FW_ACTION_FRM_IDX;
+   reg_frame.reg_id = WILC_FW_ACTION_FRM_IDX;
break;
 
case IEEE80211_STYPE_PROBE_REQ:
-   msg->body.reg_frame.reg_id = WILC_FW_PROBE_REQ_IDX;
+   reg_frame.reg_id = WILC_FW_PROBE_REQ_IDX;
break;
 
default:
break;
}
-   msg->body.reg_frame.frame_type = frame_type;
-   msg->body.reg_frame.reg = reg;
-
-   result = wilc_enqueue_work(msg);
-   if (result) {
-   netdev_err(vif->ndev, "%s: enqueue work failed\n", __func__);
-   kfree(msg);
-   }
+   reg_frame.frame_type = cpu_to_le16(frame_type);
+   result = wilc_send_config_pkt(vif, WILC_SET_CFG, , 1,
+ wilc_get_vif_idx(vif));
+   if (result)
+   netdev_err(vif->ndev, "Failed to frame register\n");
 }
 
 int wilc_add_beacon(struct wilc_vif *vif, u32 interval, u32 dtim_period,
diff --git a/drivers/staging/wilc1000/host_interface.h 
b/drivers/staging/wilc1000/host_interface.h
index 647a1af..10d5627 100644
--- a/drivers/staging/wilc1000/host_interface.h
+++ b/drivers/staging/wilc1000/host_interface.h
@@ -244,12 +244,6 @@ struct remain_ch {
u32 id;
 };
 
-struct reg_frame {
-   bool reg;
-   u16 frame_type;
-   u8 reg_id;
-};
-
 struct wilc;
 struct host_if_drv {
struct user_scan_req usr_scan_req;
-- 
2.7.4



[PATCH 02/29] staging: wilc1000: make use of put_unaligned_le32 in handle_set_wfi_drv_handler()

2018-12-02 Thread Ajay.Kathat
From: Ajay Singh 

Make use of put_unaligned_le32() function to pack the wid command buffer
for firmware.

Signed-off-by: Ajay Singh 
---
 drivers/staging/wilc1000/host_interface.c | 10 ++
 drivers/staging/wilc1000/host_interface.h |  1 -
 2 files changed, 2 insertions(+), 9 deletions(-)

diff --git a/drivers/staging/wilc1000/host_interface.c 
b/drivers/staging/wilc1000/host_interface.c
index 3f3b013..e179a8e 100644
--- a/drivers/staging/wilc1000/host_interface.c
+++ b/drivers/staging/wilc1000/host_interface.c
@@ -289,14 +289,8 @@ static void handle_set_wfi_drv_handler(struct work_struct 
*work)
goto free_msg;
 
currbyte = buffer;
-   *currbyte = hif_drv->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++;
+   put_unaligned_le32(hif_drv->driver_handler_id, currbyte);
+   currbyte += 4;
*currbyte = (hif_drv_handler->name | (hif_drv_handler->mode << 1));
 
wid.id = WID_SET_DRV_HANDLER;
diff --git a/drivers/staging/wilc1000/host_interface.h 
b/drivers/staging/wilc1000/host_interface.h
index 8279345..7a71cb6 100644
--- a/drivers/staging/wilc1000/host_interface.h
+++ b/drivers/staging/wilc1000/host_interface.h
@@ -41,7 +41,6 @@ enum {
 #define WILC_ADD_STA_LENGTH40
 #define WILC_NUM_CONCURRENT_IFC2
 #define WILC_DRV_HANDLER_SIZE  5
-#define DRV_HANDLER_MASK   0x00FF
 
 #define NUM_RSSI5
 
-- 
2.7.4



  1   2   3   4   5   6   7   8   9   10   >