Re: [v5 7/8] rsi: add module parameter operating mode

2018-01-31 Thread Kalle Valo
Amitkumar Karwar  writes:

> From: Prameela Rani Garnepudi 
>
> Operating mode determines the support for other protocols.
> This is made as module parameter for better usage.
>
> Signed-off-by: Prameela Rani Garnepudi 
> Signed-off-by: Siva Rebbagondla 
> Signed-off-by: Amitkumar Karwar 

[...]

> +/* Default operating mode is wlan STA + BT */
> +static u16 dev_oper_mode = DEV_OPMODE_STA_BT_DUAL;
> +module_param(dev_oper_mode, ushort, 0444);
> +MODULE_PARM_DESC(dev_oper_mode,
> +  "1[Wi-Fi], 4[BT], 8[BT LE], 5[Wi-Fi STA + BT classic]\n"
> +  "9[Wi-Fi STA + BT LE], 13[Wi-Fi STA + BT classic + BT LE]\n"
> +  "6[AP + BT classic], 14[AP + BT classic + BT LE]");

I really wish that we have nl80211 interface for configuring btcoex. We
have been talking about that for years but nobody has implemented it :(

-- 
Kalle Valo


Re: [v5 6/8] rsi: handle BT traffic in driver

2018-01-31 Thread Kalle Valo
Amitkumar Karwar  writes:

> From: Siva Rebbagondla 
>
> BT frames are passed through coex and hal modules to BUS.
> After firmware is loaded, based on the operating mode CARD
> READY frame comes for each protocol. When BT card ready is
> received, BT attach is called.
> Protocol operations are exchanged between the modules
> at initialization time.
>
> Signed-off-by: Siva Rebbagondla 
> Signed-off-by: Prameela Rani Garnepudi 
> Signed-off-by: Amitkumar Karwar 
> ---
> v5: Same as v3, v4
> v3: bt_ops need not be present structure g_proto_ops. It is removed.
> v2: WLAN module depends on BT module. Updated in Kconfig
> ---
>  drivers/net/wireless/rsi/Kconfig|  2 +-
>  drivers/net/wireless/rsi/rsi_91x_coex.c |  4 ++-
>  drivers/net/wireless/rsi/rsi_91x_core.c | 16 
>  drivers/net/wireless/rsi/rsi_91x_hal.c  | 39 
> +
>  drivers/net/wireless/rsi/rsi_91x_main.c | 31 +++
>  drivers/net/wireless/rsi/rsi_91x_sdio_ops.c |  1 +
>  drivers/net/wireless/rsi/rsi_common.h   |  1 +
>  drivers/net/wireless/rsi/rsi_hal.h  | 10 
>  drivers/net/wireless/rsi/rsi_main.h |  3 +++
>  9 files changed, 100 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/net/wireless/rsi/Kconfig 
> b/drivers/net/wireless/rsi/Kconfig
> index 7c5e4ca..ad72c80 100644
> --- a/drivers/net/wireless/rsi/Kconfig
> +++ b/drivers/net/wireless/rsi/Kconfig
> @@ -13,7 +13,7 @@ if WLAN_VENDOR_RSI
>  
>  config RSI_91X
>   tristate "Redpine Signals Inc 91x WLAN driver support"
> - depends on MAC80211
> + depends on MAC80211 && BT_RSI

I think this is evil, now the wlan driver cannot be enabled unless the
bluetooth driver is enabled. And if I'm understanding correctly it won't
even show up in the menuconfig. A much nicer approach would be that
btcoex is just disabled in the wlan driver if BT_RSI is disabled.

-- 
Kalle Valo


Re: [v5 4/8] rsi: add coex support

2018-01-31 Thread Kalle Valo
Amitkumar Karwar  writes:

> From: Prameela Rani Garnepudi 
>
> With BT support, driver has to handle two streams of data
> (i.e. wlan and BT). Actual coex implementation is in firmware.
> Coex module just schedule the packets to firmware by taking them
> from the corresponding paths.
>
> Structures for module and protocol operations are introduced for
> this purpose. Protocol operations structure is global structure
> which can be shared among different modules. Initialization of
> coex and operating mode values is moved to rsi_91x_init().
>
> Signed-off-by: Prameela Rani Garnepudi 
> Signed-off-by: Siva Rebbagondla 
> Signed-off-by: Amitkumar Karwar 

[...]

> +static void rsi_coex_sched_tx_pkts(struct rsi_coex_ctrl_block *coex_cb)
> +{
> + enum rsi_coex_queues coex_q;
> + struct sk_buff *skb;
> +
> + while (1) {
> + coex_q = rsi_coex_determine_coex_q(coex_cb);
> + rsi_dbg(INFO_ZONE, "queue = %d\n", coex_q);
> +
> + if (coex_q == RSI_COEX_Q_INVALID) {
> + rsi_dbg(DATA_TX_ZONE, "No more pkt\n");
> + break;
> + }
> +
> + if (coex_q == RSI_COEX_Q_BT)
> + skb = skb_dequeue(_cb->coex_tx_qs[RSI_COEX_Q_BT]);
> + }
> +}

Neverending loops are dangerous in kernel. Can you put a limit so that
if there's a bug the loop will not run forever?

-- 
Kalle Valo


Re: [v5 5/8] Bluetooth: btrsi: add new rsi bluetooth driver

2018-01-31 Thread Kalle Valo
Marcel Holtmann  writes:

>> Redpine bluetooth driver is a thin driver which depends on
>> 'rsi_91x' driver for transmitting and receiving packets
>> to/from device. It creates hci interface when attach() is
>> called from 'rsi_91x' module.
>> 
>> Signed-off-by: Prameela Rani Garnepudi 
>> Signed-off-by: Siva Rebbagondla 
>> Signed-off-by: Amitkumar Karwar 

[...]

>> +module_init(rsi_91x_bt_module_init);
>> +module_exit(rsi_91x_bt_module_exit);
>> +MODULE_AUTHOR("Redpine Signals Inc");
>> +MODULE_DESCRIPTION("RSI BT driver");
>> +MODULE_SUPPORTED_DEVICE("RSI-BT");
>> +MODULE_LICENSE("Dual BSD/GPL”);
>
> Acked-by: Marcel Holtmann 
> Reviewed-by: Marcel Holtmann 

So how should we handle the logistics, should all these go via
wireless-drivers-next tree or what's the plan?

-- 
Kalle Valo


Re: [v5 4/8] rsi: add coex support

2018-01-31 Thread Kalle Valo
Amitkumar Karwar  writes:

> From: Prameela Rani Garnepudi 
>
> With BT support, driver has to handle two streams of data
> (i.e. wlan and BT). Actual coex implementation is in firmware.
> Coex module just schedule the packets to firmware by taking them
> from the corresponding paths.
>
> Structures for module and protocol operations are introduced for
> this purpose. Protocol operations structure is global structure
> which can be shared among different modules. Initialization of
> coex and operating mode values is moved to rsi_91x_init().
>
> Signed-off-by: Prameela Rani Garnepudi 
> Signed-off-by: Siva Rebbagondla 
> Signed-off-by: Amitkumar Karwar 

[...]

> @@ -270,6 +271,7 @@ struct rsi_common {
>   u8 obm_ant_sel_val;
>   int tx_power;
>   u8 ant_in_use;
> + struct semaphore tx_bus_lock;

Do you really need to use semaphore? I think nowadays the preference is
to use something other than semaphores.

Also calling it tx_bus_lock is IMHO misleading, tx_bus_sema would be
nicer.

-- 
Kalle Valo


Re: [v5 3/8] rsi: add header file rsi_header

2018-01-31 Thread Kalle Valo
Amitkumar Karwar  writes:

> From: Prameela Rani Garnepudi 
>
> The common parameters used by wlan and bt modules are added
> to a new header file "rsi_header.h" defined in '/include/linux'
>
> Signed-off-by: Prameela Rani Garnepudi 
> Signed-off-by: Siva Rebbagondla 
> Signed-off-by: Amitkumar Karwar 

[...]

> diff --git a/include/linux/rsi_header.h b/include/linux/rsi_header.h
> new file mode 100644
> index 000..16a447b
> --- /dev/null
> +++ b/include/linux/rsi_header.h
> @@ -0,0 +1,34 @@
> +/**
> + * Copyright (c) 2017 Redpine Signals Inc.
> + *
> + * Permission to use, copy, modify, and/or distribute this software for any
> + * purpose with or without fee is hereby granted, provided that the above
> + * copyright notice and this permission notice appear in all copies.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> + */
> +
> +#ifndef __RSI_HEADER_H__
> +#define __RSI_HEADER_H__
> +
> +/* HAL queue information */
> +#define RSI_COEX_Q   0x0
> +#define RSI_BT_Q 0x2
> +#define RSI_WLAN_Q  0x3
> +#define RSI_WIFI_MGMT_Q 0x4
> +#define RSI_WIFI_DATA_Q 0x5
> +#define RSI_BT_MGMT_Q0x6
> +#define RSI_BT_DATA_Q0x7
> +
> +enum rsi_host_intf {
> + RSI_HOST_INTF_SDIO = 0,
> + RSI_HOST_INTF_USB
> +};
> +
> +#endif

The name of the header "rsi_header.h" looks odd. The ".h" prefix already
tells that it's a header file, no need to repeat that in the filename.
But also calling it "rsi.h" feels a bit weird, it's not really very
specific. Would "rsi_91x.h" (from rsi_91x.ko) be any better?

Also I'm not sure about the location (include/linux), is that really the
correct place to have a header file shared by a wireless and bluetooth
driver? Anyone know? Or would include/net be better?

-- 
Kalle Valo


Re: rtl8821ae keep alive not set, connection lost

2018-01-31 Thread James Cameron
On Wed, Jan 31, 2018 at 11:06:12AM -0600, Larry Finger wrote:
> On 09/12/2017 05:09 PM, James Cameron wrote:
> >Summary: 40b368af4b75 ("rtlwifi: Fix alignment issues") breaks
> >rtl8821ae keep alive, causing "Connection to AP lost" and deauth,
> >but why?
> >
> >Wireless connection is lost after a few seconds or minutes, on
> >every OLPC NL3 laptop with rtl8821ae, with any stable kernel after
> >4.10.1, and any kernel with 40b368af4b75.
> >
> >dmesg contains
> >
> >   wlp2s0: Connection to AP 2c:b0:5d:a6:86:eb lost
> >
> >iw event shows
> >
> >   wlp2s0: del station 2c:b0:5d:a6:86:eb
> >   wlp2s0 (phy #0): deauth 74:c6:3b:09:b5:0d -> 2c:b0:5d:a6:86:eb reason 4: 
> > Disassociated due to inactivity
> >   wlp2s0 (phy #0): disconnected (local request)
> >
> >Workaround is to bounce the link, then reconnect;
> >
> >   ip link set wlp2s0 down
> >   ip link set wlp2s0 up
> >   iw dev wlp2s0 connect qz
> >
> >A nearby monitor host captures a deauthentication packet sent by
> >the device.
> >
> >Bisection showed cause is 40b368af4b75 ("rtlwifi: Fix alignment
> >issues") which changes the width of DBI register read.
> >
> >On the face of it, 40b368af4b75 looks correct, especially compared
> >against same function in rtl8723be.
> >
> >I've no idea why reverting fixes the problem.  I'm hoping someone
> >here might speculate and suggest ways to test.
> >
> >As keep alive is set through this path, my guess is that keep alive
> >is not being set in the device.  Or perhaps reading 16-bits
> >perturbs another register.  Is there a way to test?
> >
> >http://dev.laptop.org/~quozl/z/1drtGD.txt dmesg of 4.13
> >
> >http://dev.laptop.org/~quozl/z/1drt7c.txt dmesg with 4.13 and
> >revert of 40b368af4b75
> 
> James,
> 
> I'm afraid we are needing to revisit this problem again. Changing
> that 8-bit read to a 16-bit version causes an unaligned memory
> reference in AARCH64, thus we will need to re-revert. To prevent
> problems on systems such as yours, PK plans to turn off ASPM
> capability and backdoor in certain platforms that will be listed in
> a quirks table. Please report the output of 'dmidecode -t system'
> for you affected system(s).

Thanks for letting me know.

We made three production runs, and I'm waiting to get a hold of the
dmidecode for two of them.  This may take some weeks; we have to find
stock and ship it, or we have to ask our contract manufacturer (CM) if
they have kept data or units.

I've dmidecode for one production run.

http://dev.laptop.org/~quozl/z/1eh7JF.txt (my unit nl3-e)

I've dmidecode for prototypes, but they have clearly been programmed
badly.  We did not ask our CM for Windows compatibility, so they may
have had no step to verify the data.  We also went through several
iterations to get serial numbers assigned, so the data I have does not
have good provenance.

http://dev.laptop.org/~quozl/z/1eh7EE.txt (my unit nl3-c)
http://dev.laptop.org/~quozl/z/1eh7EV.txt (my unit nl3-d)
http://dev.laptop.org/~quozl/z/1eh7He.txt (my unit nl3-a)
http://dev.laptop.org/~quozl/z/1eh8DR.txt (my unit nl3-b)

> We hope you will be able to test any proposed patches.

Yes, can do.

I've just tested v4.15.

However, I'm concerned about your plan to use quirks;

1.  turning off ASPM may decrease run time on battery, which if it is
significant, across several thousand laptops will yield generator fuel
or solar budget failure; can the power impact be quantified?

2.  why not keep ASPM enabled, and use 8-bit when quirked, or on
x86_64, or when not AARCH64?

3.  why not find the underlying problem; PK is in the same company as
the device firmware engineers, so it should be possible for them to
find out why 16-bit access causes the device firmware to hang?  We
drew a blank trying to reach firmware engineers through our CM and
module maker; perhaps we were not large or noisy enough.

4.  it's not just me; there are others who have reported similar
problems, so won't re-reverting affect them?  They haven't engaged in
the process as thoroughly, and may not be in the quirks table.  You
also reproduced the problem with different hardware.

> Thanks,
> 
> Larry

-- 
James Cameron
http://quozl.netrek.org/


Re: [v5 1/8] rsi: add rx control block to handle rx packets in USB

2018-01-31 Thread Kalle Valo
Amitkumar Karwar  writes:

> From: Prameela Rani Garnepudi 
>
> Rx bluetooth endpoint shall be added in further patches. Rx control
> block is introduced here to handle Rx packets properly. Separate
> function is written to initialize the RX control blocks.
>
> Signed-off-by: Prameela Rani Garnepudi 
> Signed-off-by: Siva Rebbagondla 
> Signed-off-by: Amitkumar Karwar 

[...]

> +static int rsi_usb_init_rx(struct rsi_hw *adapter)
> +{
> + struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)adapter->rsi_dev;
> + struct rx_usb_ctrl_block *rx_cb;
> + u8 idx;
> +
> + for (idx = 0; idx < MAX_RX_URBS; idx++) {
> + rx_cb = >rx_cb[idx];
> +
> + rx_cb->rx_buffer = kzalloc(RSI_USB_BUF_SIZE * 2,
> +GFP_KERNEL | GFP_DMA);

Do you really need GFP_DMA? From the documentation:

 "GFP_DMA exists for historical reasons and should be avoided where
  possible."

-- 
Kalle Valo


QCA9531 Question

2018-01-31 Thread David Hutchison
Hello,

I have two Atheros AP147 QCA9531 SoC, the radio is connected to the
WMAC. I am running OpenWRT Trunk on them and for some reason the TX/RX
is incredibly low.

The first AP147 is low powered, No xPA Bias and only has 20dB of
output power. Ath9k appears to run correctly, meaning I can bring up
station/AP. However when I scan, it see's nothing. When I bring up an
AP, the AP doesn't transmit.

The second AP147 has an xPA Bias level of 13. This time I can scan on
a station interface but everything it see's is incredibly low. The TX
Power is also very very low. With the xPA, this is supposed to run at
26 dB.

Is there a register a register that I can toggle to enable the QCA9531
internal PA/LNA? It's like ath9k is not enabling the internal PA/LNA
correctly.

The odd thing is, I have other QCA9531 boards ( Mikrotik based ) and
they run fine on OpenWRT Trunk. I'm not sure what the difference is...

Any insight would be much appreciated.

I posted some details on the LEDE forum:
https://forum.lede-project.org/t/ap147-010-qca9531-wmac-tx-power-issue/11126/2

-- Davey


Re: [RFC v3 0/6] EAPoL over NL80211

2018-01-31 Thread Denis Kenzior

Hi Johannes,

On 01/31/2018 04:00 PM, Johannes Berg wrote:

Looks pretty good! Some comments over in separate emails.

Maybe you should consider reordering:

[1/6] keep
[2/6] keep
[3/6] introduce TX (now patch 5)
[4/6] introduce RX (now patch 3)
   modify this to require TX from the driver in order to be able to
   set the new flag
[5/6] add TX to mac80211
[6/6] add RX to mac80211 and set the flag

Ok, you don't really have to do that, since you only set the flag in
the last patch anyway, but that'd make it better to add the check that
requires TX, so you don't have to do that in the TX patch and modify
the RX portion again.


Err, Johannes Berg presents: Fun with Flags ;) So I re-read this about 
half a dozen times and I think I figured out what you wanted.  It seems 
you mean different flags in 4/6 and 6/6.  I reordered V4 with my 
interpretation.  Doesn't quite look like the above, but hopefully I 
groked what you wanted correctly.


I didn't put in the extra owner check on the tx operation since it 
wasn't clear whether you wanted that or not.


Thanks for the review.

Regards,
-Denis


[RFC v4 6/6] mac80211: Send control port frames over nl80211

2018-01-31 Thread Denis Kenzior
If userspace requested control port frames to go over 80211, then do so.
The control packets are intercepted just prior to delivery of the packet
to the underlying network device.

Pre-authentication type frames (protocol: 0x88c7) are also forwarded
over nl80211.

Signed-off-by: Denis Kenzior 
---
 net/mac80211/cfg.c |  2 ++
 net/mac80211/ieee80211_i.h |  1 +
 net/mac80211/main.c|  2 ++
 net/mac80211/mlme.c|  2 ++
 net/mac80211/rx.c  | 33 -
 5 files changed, 35 insertions(+), 5 deletions(-)

diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index fb3cf38d674f..71cb45e517b0 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -925,6 +925,7 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct 
net_device *dev,
 */
sdata->control_port_protocol = params->crypto.control_port_ethertype;
sdata->control_port_no_encrypt = params->crypto.control_port_no_encrypt;
+   sdata->control_port_over_nl80211 = false;
sdata->encrypt_headroom = ieee80211_cs_headroom(sdata->local,
>crypto,
sdata->vif.type);
@@ -934,6 +935,7 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct 
net_device *dev,
params->crypto.control_port_ethertype;
vlan->control_port_no_encrypt =
params->crypto.control_port_no_encrypt;
+   vlan->control_port_over_nl80211 = false;
vlan->encrypt_headroom =
ieee80211_cs_headroom(sdata->local,
  >crypto,
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index c78f30555b6d..c71d2eded1f2 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -899,6 +899,7 @@ struct ieee80211_sub_if_data {
u16 sequence_number;
__be16 control_port_protocol;
bool control_port_no_encrypt;
+   bool control_port_over_nl80211;
int encrypt_headroom;
 
atomic_t num_tx_queued;
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 0785d04a80bc..e5a51267c75d 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -554,6 +554,8 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t 
priv_data_len,
   NL80211_FEATURE_USERSPACE_MPM |
   NL80211_FEATURE_FULL_AP_CLIENT_STATE;
wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_FILS_STA);
+   wiphy_ext_feature_set(wiphy,
+ NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211);
 
if (!ops->hw_scan)
wiphy->features |= NL80211_FEATURE_LOW_PRIORITY_SCAN |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 39b660b9a908..fc71a906939b 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -4830,6 +4830,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data 
*sdata,
 
sdata->control_port_protocol = req->crypto.control_port_ethertype;
sdata->control_port_no_encrypt = req->crypto.control_port_no_encrypt;
+   sdata->control_port_over_nl80211 =
+   req->crypto.control_port_over_nl80211;
sdata->encrypt_headroom = ieee80211_cs_headroom(local, >crypto,
sdata->vif.type);
 
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index e755f93ad735..c152fc318c11 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -2243,6 +2243,32 @@ static bool ieee80211_frame_allowed(struct 
ieee80211_rx_data *rx, __le16 fc)
return true;
 }
 
+static void ieee80211_deliver_skb_to_local_stack(struct sk_buff *skb,
+struct ieee80211_rx_data *rx)
+{
+   struct ieee80211_sub_if_data *sdata = rx->sdata;
+   struct net_device *dev = sdata->dev;
+
+   if (unlikely((skb->protocol == sdata->control_port_protocol ||
+ skb->protocol == cpu_to_be16(ETH_P_PREAUTH)) &&
+sdata->control_port_over_nl80211)) {
+   struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
+   bool noencrypt = status->flag & RX_FLAG_DECRYPTED;
+   struct ethhdr *ehdr = eth_hdr(skb);
+
+   cfg80211_rx_control_port(dev, skb->data, skb->len,
+ehdr->h_source,
+be16_to_cpu(skb->protocol), noencrypt);
+   dev_kfree_skb(skb);
+   } else {
+   /* deliver to local stack */
+   if (rx->napi)
+   napi_gro_receive(rx->napi, skb);
+   else
+   netif_receive_skb(skb);
+   }
+}
+
 /*
  * requires that rx->skb is a frame with ethernet header
  */
@@ -2327,13 +2353,10 @@ ieee80211_deliver_skb(struct ieee80211_rx_data 

[RFC v4 3/6] nl80211: Implement TX of control port frames

2018-01-31 Thread Denis Kenzior
This commit implements the TX side of NL80211_CMD_CONTROL_PORT_FRAME.
Userspace provides the raw EAPoL frame using NL80211_ATTR_FRAME.
Userspace should also provide the destination address and the protocol
type to use when sending the frame.  This is used to implement TX of
Pre-authentication frames.  If CONTROL_PORT_ETHERTYPE_NO_ENCRYPT is
specified, then the driver will be asked not to encrypt the outgoing
frame.

A new EXT_FEATURE flag is introduced so that nl80211 code can check
whether a given wiphy has capability to pass EAPoL frames over NL80211.

Signed-off-by: Denis Kenzior 
---
 include/net/cfg80211.h   |  9 +++
 include/uapi/linux/nl80211.h |  3 +++
 net/wireless/nl80211.c   | 63 +++-
 net/wireless/rdev-ops.h  | 15 +++
 net/wireless/trace.h | 26 ++
 5 files changed, 115 insertions(+), 1 deletion(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index f3102c6745fd..e1686421fdd7 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2958,6 +2958,9 @@ struct cfg80211_external_auth_params {
  *
  * @external_auth: indicates result of offloaded authentication processing from
  * user space
+ *
+ * @tx_control_port: TX a control port frame (EAPoL).  The noencrypt parameter
+ * tells the driver that the frame should not be encrypted.
  */
 struct cfg80211_ops {
int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
@@ -3253,6 +3256,12 @@ struct cfg80211_ops {
   const u8 *aa);
int (*external_auth)(struct wiphy *wiphy, struct net_device *dev,
 struct cfg80211_external_auth_params *params);
+
+   int (*tx_control_port)(struct wiphy *wiphy,
+  struct net_device *dev,
+  const u8 *buf, size_t len,
+  const u8 *dest, const __be16 proto,
+  const bool noencrypt);
 };
 
 /*
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 31fc88cb0a2c..5842b3954cfd 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -5009,6 +5009,8 @@ enum nl80211_feature_flags {
  * @NL80211_EXT_FEATURE_LOW_SPAN_SCAN: Driver supports low span scan.
  * @NL80211_EXT_FEATURE_LOW_POWER_SCAN: Driver supports low power scan.
  * @NL80211_EXT_FEATURE_HIGH_ACCURACY_SCAN: Driver supports high accuracy scan.
+ * @NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211: Driver supports sending and
+ * receiving control port frames over NL80211 instead of the netdevice.
  *
  * @NUM_NL80211_EXT_FEATURES: number of extended features.
  * @MAX_NL80211_EXT_FEATURES: highest extended feature index.
@@ -5039,6 +5041,7 @@ enum nl80211_ext_feature_index {
NL80211_EXT_FEATURE_LOW_SPAN_SCAN,
NL80211_EXT_FEATURE_LOW_POWER_SCAN,
NL80211_EXT_FEATURE_HIGH_ACCURACY_SCAN,
+   NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211,
 
/* add new features before the definition below */
NUM_NL80211_EXT_FEATURES,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index bffbd2cd2fc3..645c072cc4a3 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -12515,6 +12515,60 @@ static int nl80211_external_auth(struct sk_buff *skb, 
struct genl_info *info)
return rdev_external_auth(rdev, dev, );
 }
 
+static int nl80211_tx_control_port(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;
+   const u8 *buf;
+   size_t len;
+   u8 *dest;
+   u16 proto;
+   bool noencrypt;
+   int err;
+
+   if (!wiphy_ext_feature_isset(>wiphy,
+
NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211))
+   return -EOPNOTSUPP;
+
+   if (!rdev->ops->tx_control_port)
+   return -EOPNOTSUPP;
+
+   if (!info->attrs[NL80211_ATTR_FRAME] ||
+   !info->attrs[NL80211_ATTR_MAC] ||
+   !info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE])
+   return -EINVAL;
+
+   wdev_lock(wdev);
+
+   switch (wdev->iftype) {
+   case NL80211_IFTYPE_STATION:
+   if (wdev->current_bss)
+   break;
+   err = -ENOTCONN;
+   goto out;
+   default:
+   err = -EOPNOTSUPP;
+   goto out;
+   }
+
+   wdev_unlock(wdev);
+
+   buf = nla_data(info->attrs[NL80211_ATTR_FRAME]);
+   len = nla_len(info->attrs[NL80211_ATTR_FRAME]);
+   dest = nla_data(info->attrs[NL80211_ATTR_MAC]);
+   proto = nla_get_u16(info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]);
+   noencrypt =
+   nla_get_flag(info->attrs[NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT]);
+
+   

[RFC v4 4/6] nl80211: Add CONTROL_PORT_OVER_NL80211 attribute

2018-01-31 Thread Denis Kenzior
Signed-off-by: Denis Kenzior 
---
 include/net/cfg80211.h   |  3 +++
 include/uapi/linux/nl80211.h | 14 +-
 net/wireless/nl80211.c   | 13 +
 3 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index e1686421fdd7..ccc501cc6ffc 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -646,6 +646,8 @@ struct survey_info {
  * allowed through even on unauthorized ports
  * @control_port_no_encrypt: TRUE to prevent encryption of control port
  * protocol frames.
+ * @control_port_over_nl80211: TRUE if userspace expects to exchange control
+ * port frames over NL80211 instead of the network interface.
  * @wep_keys: static WEP keys, if not NULL points to an array of
  * CFG80211_MAX_WEP_KEYS WEP keys
  * @wep_tx_key: key index (0..3) of the default TX static WEP key
@@ -661,6 +663,7 @@ struct cfg80211_crypto_settings {
bool control_port;
__be16 control_port_ethertype;
bool control_port_no_encrypt;
+   bool control_port_over_nl80211;
struct key_params *wep_keys;
int wep_tx_key;
const u8 *psk;
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 5842b3954cfd..d6016afbfdd7 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -542,7 +542,8 @@
  * IEs in %NL80211_ATTR_IE, %NL80211_ATTR_AUTH_TYPE, %NL80211_ATTR_USE_MFP,
  * %NL80211_ATTR_MAC, %NL80211_ATTR_WIPHY_FREQ, %NL80211_ATTR_CONTROL_PORT,
  * %NL80211_ATTR_CONTROL_PORT_ETHERTYPE,
- * %NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT, %NL80211_ATTR_MAC_HINT, and
+ * %NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT,
+ * %NL80211_ATTR_CONTROL_PORT_OVER_NL80211, %NL80211_ATTR_MAC_HINT, and
  * %NL80211_ATTR_WIPHY_FREQ_HINT.
  * If included, %NL80211_ATTR_MAC and %NL80211_ATTR_WIPHY_FREQ are
  * restrictions on BSS selection, i.e., they effectively prevent roaming
@@ -1488,6 +1489,15 @@ enum nl80211_commands {
  * @NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT: When included along with
  * %NL80211_ATTR_CONTROL_PORT_ETHERTYPE, indicates that the custom
  * ethertype frames used for key negotiation must not be encrypted.
+ * @NL80211_ATTR_CONTROL_PORT_OVER_NL80211: A flag indicating whether control
+ * port frames (e.g. of type given in %NL80211_ATTR_CONTROL_PORT_ETHERTYPE)
+ * will be sent directly to the network interface or sent via the NL80211
+ * socket.  If this attribute is missing, then legacy behavior of sending
+ * control port frames directly to the network interface is used.  If the
+ * flag is included, then control port frames are sent over NL80211 instead
+ * using %CMD_CONTROL_PORT_FRAME.  If control port routing over NL80211 is
+ * to be used then userspace must also use the %NL80211_ATTR_SOCKET_OWNER
+ * flag.
  *
  * @NL80211_ATTR_TESTDATA: Testmode data blob, passed through to the driver.
  * We recommend using nested, driver-specific attributes within this.
@@ -2640,6 +2650,8 @@ enum nl80211_attrs {
 
NL80211_ATTR_NSS,
 
+   NL80211_ATTR_CONTROL_PORT_OVER_NL80211,
+
/* add attributes here, update the policy in nl80211.c */
 
__NL80211_ATTR_AFTER_LAST,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 645c072cc4a3..fbc6c3ddb5f9 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -286,6 +286,7 @@ static const struct nla_policy 
nl80211_policy[NUM_NL80211_ATTR] = {
[NL80211_ATTR_CONTROL_PORT] = { .type = NLA_FLAG },
[NL80211_ATTR_CONTROL_PORT_ETHERTYPE] = { .type = NLA_U16 },
[NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT] = { .type = NLA_FLAG },
+   [NL80211_ATTR_CONTROL_PORT_OVER_NL80211] = { .type = NLA_FLAG },
[NL80211_ATTR_PRIVACY] = { .type = NLA_FLAG },
[NL80211_ATTR_CIPHER_SUITE_GROUP] = { .type = NLA_U32 },
[NL80211_ATTR_WPA_VERSIONS] = { .type = NLA_U32 },
@@ -8225,6 +8226,18 @@ static int nl80211_crypto_settings(struct 
cfg80211_registered_device *rdev,
} else
settings->control_port_ethertype = cpu_to_be16(ETH_P_PAE);
 
+   if (info->attrs[NL80211_ATTR_CONTROL_PORT_OVER_NL80211]) {
+   if (!info->attrs[NL80211_ATTR_SOCKET_OWNER])
+   return -EINVAL;
+
+   if (!rdev->ops->tx_control_port ||
+   !wiphy_ext_feature_isset(>wiphy,
+
NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211))
+   return -EOPNOTSUPP;
+
+   settings->control_port_over_nl80211 = true;
+   }
+
if (info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]) {
void *data;
int len, i;
-- 
2.13.5



[RFC v4 1/6] uapi: Add 802.11 Preauthentication to if_ether

2018-01-31 Thread Denis Kenzior
This adds 0x88c7 protocol type to if_ether.

Signed-off-by: Denis Kenzior 
---
 include/uapi/linux/if_ether.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/uapi/linux/if_ether.h b/include/uapi/linux/if_ether.h
index f8cb5760ea4f..54585906e50a 100644
--- a/include/uapi/linux/if_ether.h
+++ b/include/uapi/linux/if_ether.h
@@ -89,6 +89,7 @@
 #define ETH_P_AOE  0x88A2  /* ATA over Ethernet*/
 #define ETH_P_8021AD   0x88A8  /* 802.1ad Service VLAN */
 #define ETH_P_802_EX1  0x88B5  /* 802.1 Local Experimental 1.  */
+#define ETH_P_PREAUTH  0x88C7  /* 802.11 Preauthentication */
 #define ETH_P_TIPC 0x88CA  /* TIPC */
 #define ETH_P_MACSEC   0x88E5  /* 802.1ae MACsec */
 #define ETH_P_8021AH   0x88E7  /* 802.1ah Backbone Service Tag */
-- 
2.13.5



[RFC v4 5/6] mac80211: Add support for tx_control_port

2018-01-31 Thread Denis Kenzior
Signed-off-by: Denis Kenzior 
---
 net/mac80211/cfg.c |  1 +
 net/mac80211/ieee80211_i.h |  3 +++
 net/mac80211/tx.c  | 46 ++
 3 files changed, 50 insertions(+)

diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 46028e12e216..fb3cf38d674f 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -3785,4 +3785,5 @@ const struct cfg80211_ops mac80211_config_ops = {
.add_nan_func = ieee80211_add_nan_func,
.del_nan_func = ieee80211_del_nan_func,
.set_multicast_to_unicast = ieee80211_set_multicast_to_unicast,
+   .tx_control_port = ieee80211_tx_control_port,
 };
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 26900025de2f..c78f30555b6d 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1734,6 +1734,9 @@ void ieee80211_check_fast_xmit(struct sta_info *sta);
 void ieee80211_check_fast_xmit_all(struct ieee80211_local *local);
 void ieee80211_check_fast_xmit_iface(struct ieee80211_sub_if_data *sdata);
 void ieee80211_clear_fast_xmit(struct sta_info *sta);
+int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev,
+ const u8 *buf, size_t len,
+ const u8 *dest, __be16 proto, bool unencrypted);
 
 /* HT */
 void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata,
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 25904af38839..99934bc3cd83 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -4754,3 +4754,49 @@ void __ieee80211_tx_skb_tid_band(struct 
ieee80211_sub_if_data *sdata,
ieee80211_xmit(sdata, NULL, skb);
local_bh_enable();
 }
+
+int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev,
+ const u8 *buf, size_t len,
+ const u8 *dest, __be16 proto, bool unencrypted)
+{
+   struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+   struct ieee80211_local *local = sdata->local;
+   struct sk_buff *skb;
+   struct ethhdr *ehdr;
+   u32 flags;
+
+   /* Only accept CONTROL_PORT_PROTOCOL configured in CONNECT/ASSOCIATE
+* or Pre-Authentication
+*/
+   if (proto != sdata->control_port_protocol &&
+   proto != cpu_to_be16(ETH_P_PREAUTH))
+   return -EINVAL;
+
+   if (unencrypted)
+   flags = IEEE80211_TX_INTFL_DONT_ENCRYPT;
+   else
+   flags = 0;
+
+   skb = dev_alloc_skb(local->hw.extra_tx_headroom +
+   sizeof(struct ethhdr) + len);
+   if (!skb)
+   return -ENOMEM;
+
+   skb_reserve(skb, local->hw.extra_tx_headroom + sizeof(struct ethhdr));
+
+   skb_put_data(skb, buf, len);
+
+   ehdr = skb_push(skb, sizeof(struct ethhdr));
+   memcpy(ehdr->h_dest, dest, ETH_ALEN);
+   memcpy(ehdr->h_source, sdata->vif.addr, ETH_ALEN);
+   ehdr->h_proto = proto;
+
+   skb->dev = dev;
+   skb->protocol = htons(ETH_P_802_3);
+   skb_reset_network_header(skb);
+   skb_reset_mac_header(skb);
+
+   __ieee80211_subif_start_xmit(skb, skb->dev, flags);
+
+   return 0;
+}
-- 
2.13.5



[RFC v4 2/6] nl80211: Add CMD_CONTROL_PORT_FRAME API

2018-01-31 Thread Denis Kenzior
This commit also adds cfg80211_rx_control_port function.  This is used
to generate a CMD_CONTROL_PORT_FRAME event out to userspace.  The
conn_owner_nlportid is used as the unicast destination.  This means that
userspace must specify NL80211_ATTR_SOCKET_OWNER flag if control port
over nl80211 routing is requested in NL80211_CMD_CONNECT or
NL80211_CMD_ASSOCIATE

Signed-off-by: Denis Kenzior 
---
 include/net/cfg80211.h   | 22 +
 include/uapi/linux/nl80211.h | 13 ++
 net/wireless/nl80211.c   | 58 
 net/wireless/trace.h | 21 
 4 files changed, 114 insertions(+)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 7d49cd0cf92d..f3102c6745fd 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -5690,6 +5690,28 @@ void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, 
u64 cookie,
 
 
 /**
+ * cfg80211_rx_control_port - notification about a received control port frame
+ * @dev: The device the frame matched to
+ * @buf: control port frame
+ * @len: length of the frame data
+ * @addr: The peer from which the frame was received
+ * @proto: frame protocol, typically PAE or Pre-authentication
+ * @unencrypted: Whether the frame was received unencrypted
+ *
+ * This function is used to inform userspace about a received control port
+ * frame.  It should only be used if userspace indicated it wants to receive
+ * control port frames over NL80211.
+ *
+ * The frame is the data portion of the 802.3 or 802.11 data frame with all
+ * network layer headers removed (e.g. the raw EAPoL frame).
+ *
+ * Return: %true if the frame was passed to userspace
+ */
+bool cfg80211_rx_control_port(struct net_device *dev,
+ const u8 *buf, size_t len,
+ const u8 *addr, u16 proto, bool unencrypted);
+
+/**
  * cfg80211_cqm_rssi_notify - connection quality monitoring rssi event
  * @dev: network device
  * @rssi_event: the triggered RSSI event
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index ca3d5a613fc0..31fc88cb0a2c 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -990,6 +990,17 @@
  * _CMD_CONNECT or _CMD_ROAM. If the 4 way handshake failed
  * _CMD_DISCONNECT should be indicated instead.
  *
+ * @NL80211_CMD_CONTROL_PORT_FRAME: Control Port (e.g. PAE) frame TX request
+ * and RX notification.  This command is used both as a request to transmit
+ * a control port frame and as a notification that a control port frame
+ * has been received. %NL80211_ATTR_FRAME is used to specify the
+ * frame contents.  The frame is the raw EAPoL data, without ethernet or
+ * 802.11 headers.
+ * When used as an event indication %NL80211_ATTR_CONTROL_PORT_ETHERTYPE,
+ * %NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT and %NL80211_ATTR_MAC are added
+ * indicating the protocol type of the received frame; whether the frame
+ * was received unencrypted and the MAC address of the peer respectively.
+ *
  * @NL80211_CMD_RELOAD_REGDB: Request that the regdb firmware file is reloaded.
  *
  * @NL80211_CMD_EXTERNAL_AUTH: This interface is exclusively defined for host
@@ -1228,6 +1239,8 @@ enum nl80211_commands {
 
NL80211_CMD_STA_OPMODE_CHANGED,
 
+   NL80211_CMD_CONTROL_PORT_FRAME,
+
/* 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 cc6ec5bab676..bffbd2cd2fc3 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -14549,6 +14549,64 @@ void cfg80211_mgmt_tx_status(struct wireless_dev 
*wdev, u64 cookie,
 }
 EXPORT_SYMBOL(cfg80211_mgmt_tx_status);
 
+static int __nl80211_rx_control_port(struct net_device *dev,
+const u8 *buf, size_t len,
+const u8 *addr, u16 proto,
+bool unencrypted, gfp_t gfp)
+{
+   struct wireless_dev *wdev = dev->ieee80211_ptr;
+   struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
+   struct sk_buff *msg;
+   void *hdr;
+   u32 nlportid = READ_ONCE(wdev->conn_owner_nlportid);
+
+   if (!nlportid)
+   return -ENOENT;
+
+   msg = nlmsg_new(100 + len, gfp);
+   if (!msg)
+   return -ENOMEM;
+
+   hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CONTROL_PORT_FRAME);
+   if (!hdr) {
+   nlmsg_free(msg);
+   return -ENOMEM;
+   }
+
+   if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
+   nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
+   nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
+ NL80211_ATTR_PAD) ||
+   nla_put(msg, NL80211_ATTR_FRAME, len, buf) ||
+   nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
+  

[RFC v4 0/6] EAPoL over NL80211

2018-01-31 Thread Denis Kenzior
This patchset adds support for running 802.11 authentication mechanisms (e.g.
802.1X, 4-Way Handshake, etc) over NL80211 instead of putting them onto the
network device.  This has the advantage of fixing several long-standing race
conditions that result from userspace operating on multiple transports in order
to manage a 802.11 connection (e.g. NL80211 and wireless netdev, wlan0, etc).

For example, userspace would sometimes see 4-Way handshake packets before
NL80211 signaled that the connection has been established.  Leading to ugly
hacks or having the STA wait for retransmissions from the AP.

This also provides a way to mitigate a particularly nasty race condition where
the encryption key could be set prior to the 4-way handshake packet 4/4 being
sent.  This would result in the packet being sent encrypted and discarded by
the peer.  The mitigation strategy for this race is for userspace to explicitly
tell the kernel that a particular EAPoL packet should not be encrypted.

To make this possible this patchset introduces a new NL80211 command and several
new attributes.  A userspace that is capable of processing EAPoL packets over
NL80211 includes a new NL80211_ATTR_CONTROL_PORT_OVER_NL80211 attribute in its
NL80211_CMD_ASSOCIATE or NL80211_CMD_CONNECT requests being sent to the kernel.
The previously added NL80211_ATTR_SOCKET_OWNER attribute must also be included.
The latter is used by the kernel to send NL80211_CMD_CONTROL_PORT_FRAME
notifications back to userspace via a netlink unicast.  If the
NL80211_ATTR_CONTROL_PORT_OVER_NL80211 attribute is not specified, then legacy
behavior is kept and control port packets continue to flow over the network
interface.

If control port over nl80211 transport is requested, then control port packets
are intercepted just prior to being handed to the network device and sent over
netlink via the NL80211_CMD_CONTROL_PORT_FRAME notification.
NL80211_ATTR_CONTROL_PORT_ETHERTYPE and NL80211_ATTR_MAC are included to
specify the control port frame protocol and source address respectively.  If
the control port frame was received unencrypted then
NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT flag is also included.  NL80211_ATTR_FRAME
attribute contains the raw control port frame with all transport layer headers
stripped (e.g. this would be the raw EAPoL frame).

Userspace can reply to control port frames either via legacy methods (by sending
frames to the network device) or via NL80211_CMD_CONTROL_PORT_FRAME request.
Userspace would included NL80211_ATTR_FRAME with the raw control port frame as
well as NL80211_Attr_MAC and NL80211_ATTR_CONTROL_PORT_ETHERTYPE attributes to
specify the destination address and protocol respectively.  This allows
Pre-Authentication (protocol 0x88c7) frames to be sent via this mechanism as
well.  Finally, NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT flag can be included to
tell the driver to send the frame unencrypted, e.g. for 4-Way handshake 4/4
frames.

The proposed patchset has been tested in a mac80211_hwsim based environment with
hostapd and iwd.

ChangeLog

v4

- Reordered the patches to make sure that: when CONTROL_PORT_OVER_NL80211 is
provided by userspace, nl80211 checks that both EXT_FEATURE bit is set and
the tx_control_port is present in rdev ops.
- Fixed up various issues Johannes found in his review

v3

- Added ETH_P_PREAUTH to if_ether.h
- Moved NL80211 feature bit from wiphy features to ext features
- Addressed various comments from Johannes

v2

- Added WIPHY_FLAG_CONTROL_PORT_OVER_NL80211 flag.  This is a capability flag
used by the drivers, e.g. that the driver supports control port over nl80211
capability.  This capability is now checked when CONTROL_PORT_OVER_NL80211 is
requested.

- mac80211 rx path now forwards Pre-Authentication frames over NL80211 as well,
if requested.  Tweaked the signature of cfg80211_rx_control_port.

- TX path reworked completely.  tx_control_port method has been introduced to
cfg80211_ops.  An implementation of tx_control_port for mac80211 was added.

Denis Kenzior (6):
  uapi: Add 802.11 Preauthentication to if_ether
  nl80211: Add CMD_CONTROL_PORT_FRAME API
  nl80211: Implement TX of control port frames
  nl80211: Add CONTROL_PORT_OVER_NL80211 attribute
  mac80211: Add support for tx_control_port
  mac80211: Send control port frames over nl80211

 include/net/cfg80211.h|  34 +++
 include/uapi/linux/if_ether.h |   1 +
 include/uapi/linux/nl80211.h  |  30 +-
 net/mac80211/cfg.c|   3 +
 net/mac80211/ieee80211_i.h|   4 ++
 net/mac80211/main.c   |   2 +
 net/mac80211/mlme.c   |   2 +
 net/mac80211/rx.c |  33 +--
 net/mac80211/tx.c |  46 +++
 net/wireless/nl80211.c| 134 +-
 net/wireless/rdev-ops.h   |  15 +
 net/wireless/trace.h  |  47 +++
 12 files changed, 344 insertions(+), 7 deletions(-)

-- 
2.13.5



lockdep warning in mac80211/tx.c, 4.13.16+ kernel, ath9k related

2018-01-31 Thread Ben Greear

Hello,

This first splat comes from this code:

static ieee80211_tx_result debug_noinline
ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
{
struct ieee80211_key *key;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;

if (unlikely(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT))
tx->key = NULL;
else if (tx->sta &&
### line 605 ### (key = 
rcu_dereference(tx->sta->ptk[tx->sta->ptk_idx])))
tx->key = key;
else if (ieee80211_is_group_privacy_action(tx->skb) &&
(key = rcu_dereference(tx->sdata->default_multicast_key)))
tx->key = key;
else if (ieee80211_is_mgmt(hdr->frame_control) &&
 is_multicast_ether_addr(hdr->addr1) &&
 ieee80211_is_robust_mgmt_frame(tx->skb) &&
 (key = rcu_dereference(tx->sdata->default_mgmt_key)))
tx->key = key;
else if (is_multicast_ether_addr(hdr->addr1) &&
 (key = rcu_dereference(tx->sdata->default_multicast_key)))
tx->key = key;
else if (!is_multicast_ether_addr(hdr->addr1) &&
### line 619 ### (key = 
rcu_dereference(tx->sdata->default_unicast_key)))
tx->key = key;
else
tx->key = NULL;

This ath9k has some local modifications, including removal of the airtime 
fairness logic
that was breaking my test case very quickly, so could be my fault of course.

Full tree is here:

https://github.com/greearb/linux-ct-4.13


Any idea why this might be complaining?

Test case is to bring up 200 virtual stations on each of 6 radios and then 
randomly
restart the stations and/or APs they are connected to.  I'm trying to shake out
stability bugs and such...


 30917 Jan 31 15:21:01 2u-6n kernel: =
 30918 Jan 31 15:21:01 2u-6n kernel: WARNING: suspicious RCU usage
 30919 Jan 31 15:21:01 2u-6n kernel: 4.13.16+ #2 Tainted: GW  O
 30920 Jan 31 15:21:01 2u-6n kernel: -
 30921 Jan 31 15:21:01 2u-6n kernel: 
/home/greearb/git/linux-4.13.dev.y/net/mac80211/tx.c:605 suspicious 
rcu_dereference_check() usage!
 30922 Jan 31 15:21:01 2u-6n kernel:
 30923   other info that might help us debug this:
 30924 Jan 31 15:21:01 2u-6n kernel:
 30925   rcu_scheduler_active = 2, debug_locks = 1
 30926 Jan 31 15:21:01 2u-6n kernel: 5 locks held by ip/19628:
 30927 Jan 31 15:21:01 2u-6n kernel:  #0:  (rtnl_mutex){+.+.+.}, at: 
[] rtnetlink_rcv+0x16/0x30
 30928 Jan 31 15:21:01 2u-6n kernel:  #1:  (>mtx){+.+.+.}, at: 
[] cfg80211_leave+0x1d/0x40 [cfg80211]
 30929 Jan 31 15:21:01 2u-6n kernel:  #2:  (>sta_mtx){+.+.+.}, at: 
[] __sta_info_flush+0x7c/0x170 [mac80211]
 30930 Jan 31 15:21:01 2u-6n kernel:  #3:  (&(>axq_lock)->rlock){+.-...}, at: 
[] ath_tx_node_cleanup+0x66/0x160 [ath9k]
 30931 Jan 31 15:21:01 2u-6n kernel:  #4:  (&(>lock)->rlock){+.-...}, at: 
[] ieee80211_tx_dequeue+0x45/0xca0 [mac80211]
 30932 Jan 31 15:21:01 2u-6n kernel:
 30933   stack backtrace:
 30934 Jan 31 15:21:01 2u-6n kernel: CPU: 1 PID: 19628 Comm: ip Tainted: G  
  W  O4.13.16+ #2
 30935 Jan 31 15:21:01 2u-6n kernel: Hardware name: Iron_Systems,Inc 
CS-CAD-2U-A02/X10SRL-F, BIOS 2.0b 05/02/2017
 30936 Jan 31 15:21:01 2u-6n kernel: Call Trace:
 30937 Jan 31 15:21:01 2u-6n kernel:  dump_stack+0x85/0xc7
 30938 Jan 31 15:21:01 2u-6n kernel:  lockdep_rcu_suspicious+0xc5/0x100
 30939 Jan 31 15:21:01 2u-6n kernel:  ieee80211_tx_h_select_key+0x1c9/0x4e0 
[mac80211]
 30940 Jan 31 15:21:01 2u-6n kernel:  ieee80211_tx_dequeue+0x376/0xca0 
[mac80211]
 30941 Jan 31 15:21:01 2u-6n kernel:  ath_tid_dequeue+0x9c/0x110 [ath9k]
 30942 Jan 31 15:21:01 2u-6n kernel:  ath_tx_node_cleanup+0xa4/0x160 [ath9k]
 30943 Jan 31 15:21:01 2u-6n kernel:  ath9k_sta_state+0x6b/0x1e0 [ath9k]
 30944 Jan 31 15:21:01 2u-6n kernel:  drv_sta_state+0xad/0xa80 [mac80211]
 30945 Jan 31 15:21:01 2u-6n kernel:  __sta_info_destroy_part2+0x178/0x1d0 
[mac80211]
 30946 Jan 31 15:21:01 2u-6n kernel:  __sta_info_flush+0xef/0x170 [mac80211]
 30947 Jan 31 15:21:01 2u-6n kernel:  ieee80211_set_disassoc+0xc6/0x400 
[mac80211]
 30948 Jan 31 15:21:01 2u-6n kernel:  ieee80211_mgd_deauth+0x2f6/0x830 
[mac80211]
 30949 Jan 31 15:21:01 2u-6n kernel:  ieee80211_deauth+0x13/0x20 [mac80211]
 30950 Jan 31 15:21:01 2u-6n kernel:  cfg80211_mlme_deauth+0x16b/0x3e0 
[cfg80211]
 30951 Jan 31 15:21:01 2u-6n kernel:  cfg80211_mlme_down+0x6d/0xa0 [cfg80211]
 30952 Jan 31 15:21:01 2u-6n kernel:  cfg80211_disconnect+0x2f4/0x3f0 [cfg80211]
 30953 Jan 31 15:21:01 2u-6n kernel:  ? kfree+0x24d/0x2b0
 30954 Jan 31 15:21:01 2u-6n kernel:  __cfg80211_leave+0x134/0x190 [cfg80211]
 30955 Jan 31 15:21:01 2u-6n kernel:  cfg80211_leave+0x28/0x40 [cfg80211]
 30956 Jan 31 15:21:01 2u-6n kernel:  

[PATCH] mt76x2: remove warnings in mt76x2_mac_write_txwi()

2018-01-31 Thread Lorenzo Bianconi
Fix following sparse warnings in mt76x2_mac_write_txwi:
- drivers/net/wireless/mediatek/mt76/mt76x2_mac.c:201:26: warning:
  incorrect type in assignment (different base types)
- drivers/net/wireless/mediatek/mt76/mt76x2_mac.c:201:26: expected
  restricted __le32 [usertype] iv
- drivers/net/wireless/mediatek/mt76/mt76x2_mac.c:201:26: got unsigned
  int [unsigned] [usertype] 
- drivers/net/wireless/mediatek/mt76/mt76x2_mac.c:202:27: warning:
  incorrect type in assignment (different base types)
- drivers/net/wireless/mediatek/mt76/mt76x2_mac.c:202:27: expected
  restricted __le32 [usertype] eiv
- drivers/net/wireless/mediatek/mt76/mt76x2_mac.c:202:27: got unsigned
  int [unsigned] [usertype] 

Fixes: 23405236460b ("mt76: fix transmission of encrypted management
frames")
Signed-off-by: Lorenzo Bianconi 
---
 drivers/net/wireless/mediatek/mt76/mt76x2_mac.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c 
b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c
index 6c30b5eaa9ca..279cd8717806 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c
@@ -198,8 +198,8 @@ void mt76x2_mac_write_txwi(struct mt76x2_dev *dev, struct 
mt76x2_txwi *txwi,
ccmp_pn[5] = pn >> 24;
ccmp_pn[6] = pn >> 32;
ccmp_pn[7] = pn >> 40;
-   txwi->iv = *((u32 *) _pn[0]);
-   txwi->eiv = *((u32 *) _pn[1]);
+   txwi->iv = *((__le32 *)_pn[0]);
+   txwi->eiv = *((__le32 *)_pn[1]);
}
 
spin_lock_bh(>mt76.lock);
-- 
2.14.3



Re: [PATCH 3/6] nl80211: Add CMD_CONTROL_PORT_FRAME API

2018-01-31 Thread Johannes Berg
On Wed, 2018-01-31 at 16:01 -0600, Denis Kenzior wrote:
> Hi Johannes,
> 
> > > + * @NL80211_CMD_CONTROL_PORT_FRAME: Control Port (e.g. PAE) frame TX 
> > > request
> > > + *   and RX notification.  This command is used both as a request to 
> > > transmit
> > > + *   a control port frame and as a notification that a control port 
> > > frame
> > > + *   has been received. %NL80211_ATTR_FRAME is used to specify the
> > > + *   frame contents.  The frame is the raw EAPoL data, without 
> > > ethernet or
> > > + *   802.11 headers.
> > 
> > Never mind, so it's without Ethernet header. Is that really desirable
> > though? I mean, it could be that the Ethernet address even matters (not
> > sure) and it'd probably be easier to handle in (existing) userspace
> > where Ethernet frames are expected now?
> 
> I also include the from address inside the NL80211 message as ATTR_MAC. 
> The protocol as well.  I wrote the docs first and never updated the 
> little details afterwards.  Will fix.

Good point, I could've seen that.

Still not sure it makes a big difference, but I guess it doesn't really
matter that much (though in a sense it'd be easier to take Ethernet
header apart than putting it back together - but even that can be done
in place in the message buffer)

> > > + nla_put_failure:
> > > + genlmsg_cancel(msg, hdr);
> > 
> > nit: there's no point in cancelling if you free it (immediately).
> 
> Just following some existing code, but will fix.

Yeah I just never got around to cleaning up that antipattern ... I'll
make an spatch.

johannes


Re: [PATCH 3/6] nl80211: Add CMD_CONTROL_PORT_FRAME API

2018-01-31 Thread Denis Kenzior

Hi Johannes,


+ * @NL80211_CMD_CONTROL_PORT_FRAME: Control Port (e.g. PAE) frame TX request
+ * and RX notification.  This command is used both as a request to transmit
+ * a control port frame and as a notification that a control port frame
+ * has been received. %NL80211_ATTR_FRAME is used to specify the
+ * frame contents.  The frame is the raw EAPoL data, without ethernet or
+ * 802.11 headers.


Never mind, so it's without Ethernet header. Is that really desirable
though? I mean, it could be that the Ethernet address even matters (not
sure) and it'd probably be easier to handle in (existing) userspace
where Ethernet frames are expected now?


I also include the from address inside the NL80211 message as ATTR_MAC. 
The protocol as well.  I wrote the docs first and never updated the 
little details afterwards.  Will fix.





+ nla_put_failure:
+   genlmsg_cancel(msg, hdr);


nit: there's no point in cancelling if you free it (immediately).


Just following some existing code, but will fix.




+bool cfg80211_rx_control_port(struct net_device *dev,
+ const u8 *buf, size_t len,
+ const u8 *addr, u16 proto, bool unencrypted)
+{
+   bool ret;
+
+   trace_cfg80211_rx_control_port(dev, buf, len, addr, proto, unencrypted);
+   ret = __nl80211_rx_control_port(dev, buf, len, addr, proto,
+   unencrypted, GFP_ATOMIC);
+   trace_cfg80211_return_bool(ret);


this seems wrong - you return -ERROR from __nl80211_rx_control_port()
so you need either to pass that on as an integer to the caller, or put
an == 0 here or something?

"Return: %true if the frame was passed to userspace"



Yep, will fix.

Regards,
-Denis



Re: [PATCH 5/6] nl80211: Implement TX of control port frames

2018-01-31 Thread Johannes Berg
On Wed, 2018-01-31 at 15:58 -0600, Denis Kenzior wrote:

> > Actually, then again, that's awkward because doing events and commands
> > on the same socket doesn't mix all _that_ well. Perhaps we just need to
> > fix that problem in libnl or something and be done with it ...
> > 
> 
> There are no issues on our side..

I guess you don't use libnl then :-) It doesn't exactly make it easy to
receive events while waiting for an ACK.

johannes


Re: [RFC v3 0/6] EAPoL over NL80211

2018-01-31 Thread Johannes Berg
Looks pretty good! Some comments over in separate emails.

Maybe you should consider reordering:

[1/6] keep
[2/6] keep
[3/6] introduce TX (now patch 5)
[4/6] introduce RX (now patch 3)
  modify this to require TX from the driver in order to be able to
  set the new flag
[5/6] add TX to mac80211
[6/6] add RX to mac80211 and set the flag

Ok, you don't really have to do that, since you only set the flag in
the last patch anyway, but that'd make it better to add the check that
requires TX, so you don't have to do that in the TX patch and modify
the RX portion again.

johannes



Re: [PATCH 5/6] nl80211: Implement TX of control port frames

2018-01-31 Thread Denis Kenzior

Hi Johannes,

On 01/31/2018 03:53 PM, Johannes Berg wrote:



+static int nl80211_tx_control_port(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;
+   const u8 *buf;
+   size_t len;
+   u8 *dest;
+   u16 proto;
+   bool noencrypt;
+   int err;
+
+   if (!wiphy_ext_feature_isset(>wiphy,
+
NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211))
+   return -EOPNOTSUPP;
+
+   if (!rdev->ops->tx_control_port)
+   return -EOPNOTSUPP;


I wonder if maybe we should accept this command only from the socket
owner? Is there a use case for something else?


Yes I thought about adding such a check as I think it wouldn't make 
sense to accept control port frames from any other application besides 
the socket owner.  However the socket owner stuff was a bit 
controversial, so I left it out.


I would support adding this check...



Actually, then again, that's awkward because doing events and commands
on the same socket doesn't mix all _that_ well. Perhaps we just need to
fix that problem in libnl or something and be done with it ...


There are no issues on our side..

Regards,
-Denis


Re: [PATCH 5/6] nl80211: Implement TX of control port frames

2018-01-31 Thread Johannes Berg

> +static int nl80211_tx_control_port(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;
> + const u8 *buf;
> + size_t len;
> + u8 *dest;
> + u16 proto;
> + bool noencrypt;
> + int err;
> +
> + if (!wiphy_ext_feature_isset(>wiphy,
> +  
> NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211))
> + return -EOPNOTSUPP;
> +
> + if (!rdev->ops->tx_control_port)
> + return -EOPNOTSUPP;

I wonder if maybe we should accept this command only from the socket
owner? Is there a use case for something else?

Actually, then again, that's awkward because doing events and commands
on the same socket doesn't mix all _that_ well. Perhaps we just need to
fix that problem in libnl or something and be done with it ...

johannes


Re: [PATCH 5/6] nl80211: Implement TX of control port frames

2018-01-31 Thread Johannes Berg
On Wed, 2018-01-31 at 15:33 -0600, Denis Kenzior wrote:
> 
> + return rdev_tx_control_port(rdev, dev, buf, len,
> + dest, cpu_to_be16(proto), noencrypt);

You're passing __be16 here

> +++ b/net/wireless/rdev-ops.h
> @@ -714,6 +714,21 @@ static inline int rdev_mgmt_tx(struct 
> cfg80211_registered_device *rdev,
>   return ret;
>  }
>  
> +static inline int rdev_tx_control_port(struct cfg80211_registered_device 
> *rdev,
> +struct net_device *dev,
> +const void *buf, size_t len,
> +const u8 *dest, u16 proto,
> +const bool noencrypt)

but have u16 here - doesn't that make sparse unhappy?

Should also declare the API as __be16.

johannes


Re: [PATCH 4/6] mac80211: Send control port frames over nl80211

2018-01-31 Thread Johannes Berg
On Wed, 2018-01-31 at 15:33 -0600, Denis Kenzior wrote:
> 
> + if (!cfg80211_rx_control_port(dev, skb->data, skb->len,
> +   ehdr->h_source,
> +   be16_to_cpu(skb->protocol),
> +   noencrypt))
> + dev_kfree_skb(skb);

Err, you should free it unconditionally, no? You don't do anything with
the skb afterwards, since you can't get into the else branch and
deliver it to the netdev now, so afaict it'd be leaked if not freed?

Which explains why you didn't notice the error in the previous patch,
it was making this code correct by freeing it all the time (never
hitting an error, presumably, and even if you wouldn't notice the small
leaks)

johannes


Re: [PATCH 3/6] nl80211: Add CMD_CONTROL_PORT_FRAME API

2018-01-31 Thread Johannes Berg
On Wed, 2018-01-31 at 15:33 -0600, Denis Kenzior wrote:
> 
>  /**
> + * cfg80211_rx_control_port - inform userspace about a received control port
> + * frame, e.g. EAPoL.  This is used if userspace has specified it wants to
> + * receive control port frames over NL80211.

nitpick - the short description must fit on a single line, you can have
a longer description separately (after the arguments, I'd probably even
put it after the return)

> + * @dev: The device the frame matched to
> + * @buf: control port frame
> + * @len: length of the frame data

You should document what exactly is in this frame data?

Should it be with the ethernet header removed? It would seem easier if
it's with the ethernet header included, but then why do you need the
proto argument?

> + * @NL80211_CMD_CONTROL_PORT_FRAME: Control Port (e.g. PAE) frame TX request
> + *   and RX notification.  This command is used both as a request to transmit
> + *   a control port frame and as a notification that a control port frame
> + *   has been received. %NL80211_ATTR_FRAME is used to specify the
> + *   frame contents.  The frame is the raw EAPoL data, without ethernet or
> + *   802.11 headers.

Never mind, so it's without Ethernet header. Is that really desirable
though? I mean, it could be that the Ethernet address even matters (not
sure) and it'd probably be easier to handle in (existing) userspace
where Ethernet frames are expected now?

> + nla_put_failure:
> + genlmsg_cancel(msg, hdr);

nit: there's no point in cancelling if you free it (immediately).

> +bool cfg80211_rx_control_port(struct net_device *dev,
> +   const u8 *buf, size_t len,
> +   const u8 *addr, u16 proto, bool unencrypted)
> +{
> + bool ret;
> +
> + trace_cfg80211_rx_control_port(dev, buf, len, addr, proto, unencrypted);
> + ret = __nl80211_rx_control_port(dev, buf, len, addr, proto,
> + unencrypted, GFP_ATOMIC);
> + trace_cfg80211_return_bool(ret);

this seems wrong - you return -ERROR from __nl80211_rx_control_port()
so you need either to pass that on as an integer to the caller, or put
an == 0 here or something?

"Return: %true if the frame was passed to userspace"

johannes


[PATCH 5/6] nl80211: Implement TX of control port frames

2018-01-31 Thread Denis Kenzior
This commit implements the TX side of NL80211_CMD_CONTROL_PORT_FRAME.
Userspace provides the raw EAPoL frame using NL80211_ATTR_FRAME.
Userspace should also provide the destination address and the protocol
type to use when sending the frame.  This is used to implement TX of
Pre-authentication frames.  If CONTROL_PORT_ETHERTYPE_NO_ENCRYPT is
specified, then the driver will be asked not to encrypt the outgoing
frame.

Signed-off-by: Denis Kenzior 
---
 include/net/cfg80211.h  |  9 +++
 net/wireless/nl80211.c  | 63 -
 net/wireless/rdev-ops.h | 15 
 net/wireless/trace.h| 25 
 4 files changed, 111 insertions(+), 1 deletion(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 60a38543b830..dc6d37b40574 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2961,6 +2961,9 @@ struct cfg80211_external_auth_params {
  *
  * @external_auth: indicates result of offloaded authentication processing from
  * user space
+ *
+ * @tx_control_port: TX a control port frame (EAPoL).  The noencrypt parameter
+ * tells the driver that the frame should not be encrypted.
  */
 struct cfg80211_ops {
int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
@@ -3256,6 +3259,12 @@ struct cfg80211_ops {
   const u8 *aa);
int (*external_auth)(struct wiphy *wiphy, struct net_device *dev,
 struct cfg80211_external_auth_params *params);
+
+   int (*tx_control_port)(struct wiphy *wiphy,
+  struct net_device *dev,
+  const u8 *buf, size_t len,
+  const u8 *dest, const u16 proto,
+  const bool noencrypt);
 };
 
 /*
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 840dada2cca3..ed5752a99951 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -12527,6 +12527,60 @@ static int nl80211_external_auth(struct sk_buff *skb, 
struct genl_info *info)
return rdev_external_auth(rdev, dev, );
 }
 
+static int nl80211_tx_control_port(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;
+   const u8 *buf;
+   size_t len;
+   u8 *dest;
+   u16 proto;
+   bool noencrypt;
+   int err;
+
+   if (!wiphy_ext_feature_isset(>wiphy,
+
NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211))
+   return -EOPNOTSUPP;
+
+   if (!rdev->ops->tx_control_port)
+   return -EOPNOTSUPP;
+
+   if (!info->attrs[NL80211_ATTR_FRAME] ||
+   !info->attrs[NL80211_ATTR_MAC] ||
+   !info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE])
+   return -EINVAL;
+
+   wdev_lock(wdev);
+
+   switch (wdev->iftype) {
+   case NL80211_IFTYPE_STATION:
+   if (wdev->current_bss)
+   break;
+   err = -ENOTCONN;
+   goto out;
+   default:
+   err = -EOPNOTSUPP;
+   goto out;
+   }
+
+   wdev_unlock(wdev);
+
+   buf = nla_data(info->attrs[NL80211_ATTR_FRAME]);
+   len = nla_len(info->attrs[NL80211_ATTR_FRAME]);
+   dest = nla_data(info->attrs[NL80211_ATTR_MAC]);
+   proto = nla_get_u16(info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]);
+   noencrypt =
+   nla_get_flag(info->attrs[NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT]);
+
+   return rdev_tx_control_port(rdev, dev, buf, len,
+   dest, cpu_to_be16(proto), noencrypt);
+
+ out:
+   wdev_unlock(wdev);
+   return err;
+}
+
 #define NL80211_FLAG_NEED_WIPHY0x01
 #define NL80211_FLAG_NEED_NETDEV   0x02
 #define NL80211_FLAG_NEED_RTNL 0x04
@@ -13430,7 +13484,14 @@ static const struct genl_ops nl80211_ops[] = {
.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
  NL80211_FLAG_NEED_RTNL,
},
-
+   {
+   .cmd = NL80211_CMD_CONTROL_PORT_FRAME,
+   .doit = nl80211_tx_control_port,
+   .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 = {
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
index 84f23ae015fc..ced82e2350f4 100644
--- a/net/wireless/rdev-ops.h
+++ b/net/wireless/rdev-ops.h
@@ -714,6 +714,21 @@ static inline int rdev_mgmt_tx(struct 
cfg80211_registered_device *rdev,
return ret;
 }
 
+static inline int rdev_tx_control_port(struct 

[PATCH 4/6] mac80211: Send control port frames over nl80211

2018-01-31 Thread Denis Kenzior
If userspace requested control port frames to go over 80211, then do so.
The control packets are intercepted just prior to delivery of the packet
to the underlying network device.

Pre-authentication type frames (protocol: 0x88c7) are also forwarded
over nl80211.

Signed-off-by: Denis Kenzior 
---
 net/mac80211/cfg.c |  2 ++
 net/mac80211/ieee80211_i.h |  1 +
 net/mac80211/mlme.c|  2 ++
 net/mac80211/rx.c  | 34 +-
 4 files changed, 34 insertions(+), 5 deletions(-)

diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 46028e12e216..f53bfb27295f 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -925,6 +925,7 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct 
net_device *dev,
 */
sdata->control_port_protocol = params->crypto.control_port_ethertype;
sdata->control_port_no_encrypt = params->crypto.control_port_no_encrypt;
+   sdata->control_port_over_nl80211 = false;
sdata->encrypt_headroom = ieee80211_cs_headroom(sdata->local,
>crypto,
sdata->vif.type);
@@ -934,6 +935,7 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct 
net_device *dev,
params->crypto.control_port_ethertype;
vlan->control_port_no_encrypt =
params->crypto.control_port_no_encrypt;
+   vlan->control_port_over_nl80211 = false;
vlan->encrypt_headroom =
ieee80211_cs_headroom(sdata->local,
  >crypto,
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 26900025de2f..6f91aea6a4cb 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -899,6 +899,7 @@ struct ieee80211_sub_if_data {
u16 sequence_number;
__be16 control_port_protocol;
bool control_port_no_encrypt;
+   bool control_port_over_nl80211;
int encrypt_headroom;
 
atomic_t num_tx_queued;
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 39b660b9a908..fc71a906939b 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -4830,6 +4830,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data 
*sdata,
 
sdata->control_port_protocol = req->crypto.control_port_ethertype;
sdata->control_port_no_encrypt = req->crypto.control_port_no_encrypt;
+   sdata->control_port_over_nl80211 =
+   req->crypto.control_port_over_nl80211;
sdata->encrypt_headroom = ieee80211_cs_headroom(local, >crypto,
sdata->vif.type);
 
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index e755f93ad735..c3abf9e44079 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -2243,6 +2243,33 @@ static bool ieee80211_frame_allowed(struct 
ieee80211_rx_data *rx, __le16 fc)
return true;
 }
 
+static void ieee80211_deliver_skb_to_local_stack(struct sk_buff *skb,
+struct ieee80211_rx_data *rx)
+{
+   struct ieee80211_sub_if_data *sdata = rx->sdata;
+   struct net_device *dev = sdata->dev;
+
+   if (unlikely((skb->protocol == sdata->control_port_protocol ||
+ skb->protocol == cpu_to_be16(ETH_P_PREAUTH)) &&
+sdata->control_port_over_nl80211)) {
+   struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
+   bool noencrypt = status->flag & RX_FLAG_DECRYPTED;
+   struct ethhdr *ehdr = eth_hdr(skb);
+
+   if (!cfg80211_rx_control_port(dev, skb->data, skb->len,
+ ehdr->h_source,
+ be16_to_cpu(skb->protocol),
+ noencrypt))
+   dev_kfree_skb(skb);
+   } else {
+   /* deliver to local stack */
+   if (rx->napi)
+   napi_gro_receive(rx->napi, skb);
+   else
+   netif_receive_skb(skb);
+   }
+}
+
 /*
  * requires that rx->skb is a frame with ethernet header
  */
@@ -2327,13 +2354,10 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx)
 #endif
 
if (skb) {
-   /* deliver to local stack */
skb->protocol = eth_type_trans(skb, dev);
memset(skb->cb, 0, sizeof(skb->cb));
-   if (rx->napi)
-   napi_gro_receive(rx->napi, skb);
-   else
-   netif_receive_skb(skb);
+
+   ieee80211_deliver_skb_to_local_stack(skb, rx);
}
 
if (xmit_skb) {
-- 
2.13.5



[PATCH 3/6] nl80211: Add CMD_CONTROL_PORT_FRAME API

2018-01-31 Thread Denis Kenzior
This commit also adds cfg80211_rx_control_port function.  This is used
to generate a CMD_CONTROL_PORT_FRAME event out to userspace.  The
conn_owner_nlportid is used as the unicast destination.  This means that
userspace must specify NL80211_ATTR_SOCKET_OWNER flag if control port
over nl80211 routing is requested in NL80211_CMD_CONNECT or
NL80211_CMD_ASSOCIATE

Signed-off-by: Denis Kenzior 
---
 include/net/cfg80211.h   | 17 +
 include/uapi/linux/nl80211.h | 15 +++
 net/wireless/nl80211.c   | 59 
 net/wireless/trace.h | 21 
 4 files changed, 112 insertions(+)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index fb369947aefb..60a38543b830 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -5693,6 +5693,23 @@ void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, 
u64 cookie,
 
 
 /**
+ * cfg80211_rx_control_port - inform userspace about a received control port
+ * frame, e.g. EAPoL.  This is used if userspace has specified it wants to
+ * receive control port frames over NL80211.
+ * @dev: The device the frame matched to
+ * @buf: control port frame
+ * @len: length of the frame data
+ * @addr: The peer from which the frame was received
+ * @proto: frame protocol, typically PAE or Pre-authentication
+ * @unencrypted: Whether the frame was received unencrypted
+ *
+ * Return: %true if the frame was passed to userspace
+ */
+bool cfg80211_rx_control_port(struct net_device *dev,
+ const u8 *buf, size_t len,
+ const u8 *addr, u16 proto, bool unencrypted);
+
+/**
  * cfg80211_cqm_rssi_notify - connection quality monitoring rssi event
  * @dev: network device
  * @rssi_event: the triggered RSSI event
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 20b35ba6721f..3a9d4364d383 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -991,6 +991,17 @@
  * _CMD_CONNECT or _CMD_ROAM. If the 4 way handshake failed
  * _CMD_DISCONNECT should be indicated instead.
  *
+ * @NL80211_CMD_CONTROL_PORT_FRAME: Control Port (e.g. PAE) frame TX request
+ * and RX notification.  This command is used both as a request to transmit
+ * a control port frame and as a notification that a control port frame
+ * has been received. %NL80211_ATTR_FRAME is used to specify the
+ * frame contents.  The frame is the raw EAPoL data, without ethernet or
+ * 802.11 headers.
+ * When used as an event indication %NL80211_ATTR_CONTROL_PORT_ETHERTYPE,
+ * %NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT and %NL80211_ATTR_MAC are added
+ * indicating the protocol type of the received frame; whether the frame
+ * was received unencrypted and the MAC address of the peer respectively.
+ *
  * @NL80211_CMD_RELOAD_REGDB: Request that the regdb firmware file is reloaded.
  *
  * @NL80211_CMD_EXTERNAL_AUTH: This interface is exclusively defined for host
@@ -1229,6 +1240,8 @@ enum nl80211_commands {
 
NL80211_CMD_STA_OPMODE_CHANGED,
 
+   NL80211_CMD_CONTROL_PORT_FRAME,
+
/* add new commands above here */
 
/* used to define NL80211_CMD_MAX below */
@@ -1476,6 +1489,8 @@ enum nl80211_commands {
  * @NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT: When included along with
  * %NL80211_ATTR_CONTROL_PORT_ETHERTYPE, indicates that the custom
  * ethertype frames used for key negotiation must not be encrypted.
+ * When included in %NL80211_CMD_CONTROL_PORT_FRAME it means that the
+ * control port frame was received unencrypted.
  * @NL80211_ATTR_CONTROL_PORT_OVER_NL80211: A flag indicating whether control
  * port frames (e.g. of type given in %NL80211_ATTR_CONTROL_PORT_ETHERTYPE)
  * will be sent directly to the network interface or sent via the NL80211
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 0c389044a4d3..840dada2cca3 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -14561,6 +14561,65 @@ void cfg80211_mgmt_tx_status(struct wireless_dev 
*wdev, u64 cookie,
 }
 EXPORT_SYMBOL(cfg80211_mgmt_tx_status);
 
+static int __nl80211_rx_control_port(struct net_device *dev,
+const u8 *buf, size_t len,
+const u8 *addr, u16 proto,
+bool unencrypted, gfp_t gfp)
+{
+   struct wireless_dev *wdev = dev->ieee80211_ptr;
+   struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
+   struct sk_buff *msg;
+   void *hdr;
+   u32 nlportid = READ_ONCE(wdev->conn_owner_nlportid);
+
+   if (!nlportid)
+   return -ENOENT;
+
+   msg = nlmsg_new(100 + len, gfp);
+   if (!msg)
+   return -ENOMEM;
+
+   hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CONTROL_PORT_FRAME);
+   if (!hdr) {
+   nlmsg_free(msg);
+   return 

[PATCH 2/6] nl80211: Add CONTROL_PORT_OVER_NL80211 attribute

2018-01-31 Thread Denis Kenzior
Signed-off-by: Denis Kenzior 
---
 include/net/cfg80211.h   |  3 +++
 include/uapi/linux/nl80211.h | 17 -
 net/wireless/nl80211.c   | 12 
 3 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 7d49cd0cf92d..fb369947aefb 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -646,6 +646,8 @@ struct survey_info {
  * allowed through even on unauthorized ports
  * @control_port_no_encrypt: TRUE to prevent encryption of control port
  * protocol frames.
+ * @control_port_over_nl80211: TRUE if userspace expects to exchange control
+ * port frames over NL80211 instead of the network interface.
  * @wep_keys: static WEP keys, if not NULL points to an array of
  * CFG80211_MAX_WEP_KEYS WEP keys
  * @wep_tx_key: key index (0..3) of the default TX static WEP key
@@ -661,6 +663,7 @@ struct cfg80211_crypto_settings {
bool control_port;
__be16 control_port_ethertype;
bool control_port_no_encrypt;
+   bool control_port_over_nl80211;
struct key_params *wep_keys;
int wep_tx_key;
const u8 *psk;
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index ca3d5a613fc0..20b35ba6721f 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -542,7 +542,8 @@
  * IEs in %NL80211_ATTR_IE, %NL80211_ATTR_AUTH_TYPE, %NL80211_ATTR_USE_MFP,
  * %NL80211_ATTR_MAC, %NL80211_ATTR_WIPHY_FREQ, %NL80211_ATTR_CONTROL_PORT,
  * %NL80211_ATTR_CONTROL_PORT_ETHERTYPE,
- * %NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT, %NL80211_ATTR_MAC_HINT, and
+ * %NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT,
+ * %NL80211_ATTR_CONTROL_PORT_OVER_NL80211, %NL80211_ATTR_MAC_HINT, and
  * %NL80211_ATTR_WIPHY_FREQ_HINT.
  * If included, %NL80211_ATTR_MAC and %NL80211_ATTR_WIPHY_FREQ are
  * restrictions on BSS selection, i.e., they effectively prevent roaming
@@ -1475,6 +1476,15 @@ enum nl80211_commands {
  * @NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT: When included along with
  * %NL80211_ATTR_CONTROL_PORT_ETHERTYPE, indicates that the custom
  * ethertype frames used for key negotiation must not be encrypted.
+ * @NL80211_ATTR_CONTROL_PORT_OVER_NL80211: A flag indicating whether control
+ * port frames (e.g. of type given in %NL80211_ATTR_CONTROL_PORT_ETHERTYPE)
+ * will be sent directly to the network interface or sent via the NL80211
+ * socket.  If this attribute is missing, then legacy behavior of sending
+ * control port frames directly to the network interface is used.  If the
+ * flag is included, then control port frames are sent over NL80211 instead
+ * using %CMD_CONTROL_PORT_FRAME.  If control port routing over NL80211 is
+ * to be used then userspace must also use the %NL80211_ATTR_SOCKET_OWNER
+ * flag.
  *
  * @NL80211_ATTR_TESTDATA: Testmode data blob, passed through to the driver.
  * We recommend using nested, driver-specific attributes within this.
@@ -2627,6 +2637,8 @@ enum nl80211_attrs {
 
NL80211_ATTR_NSS,
 
+   NL80211_ATTR_CONTROL_PORT_OVER_NL80211,
+
/* add attributes here, update the policy in nl80211.c */
 
__NL80211_ATTR_AFTER_LAST,
@@ -4996,6 +5008,8 @@ enum nl80211_feature_flags {
  * @NL80211_EXT_FEATURE_LOW_SPAN_SCAN: Driver supports low span scan.
  * @NL80211_EXT_FEATURE_LOW_POWER_SCAN: Driver supports low power scan.
  * @NL80211_EXT_FEATURE_HIGH_ACCURACY_SCAN: Driver supports high accuracy scan.
+ * @NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211: Driver supports sending and
+ * receiving control port frames over NL80211 instead of the netdevice.
  *
  * @NUM_NL80211_EXT_FEATURES: number of extended features.
  * @MAX_NL80211_EXT_FEATURES: highest extended feature index.
@@ -5026,6 +5040,7 @@ enum nl80211_ext_feature_index {
NL80211_EXT_FEATURE_LOW_SPAN_SCAN,
NL80211_EXT_FEATURE_LOW_POWER_SCAN,
NL80211_EXT_FEATURE_HIGH_ACCURACY_SCAN,
+   NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211,
 
/* add new features before the definition below */
NUM_NL80211_EXT_FEATURES,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index cc6ec5bab676..0c389044a4d3 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -286,6 +286,7 @@ static const struct nla_policy 
nl80211_policy[NUM_NL80211_ATTR] = {
[NL80211_ATTR_CONTROL_PORT] = { .type = NLA_FLAG },
[NL80211_ATTR_CONTROL_PORT_ETHERTYPE] = { .type = NLA_U16 },
[NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT] = { .type = NLA_FLAG },
+   [NL80211_ATTR_CONTROL_PORT_OVER_NL80211] = { .type = NLA_FLAG },
[NL80211_ATTR_PRIVACY] = { .type = NLA_FLAG },
[NL80211_ATTR_CIPHER_SUITE_GROUP] = { .type = NLA_U32 },
[NL80211_ATTR_WPA_VERSIONS] = { .type = NLA_U32 },
@@ -8225,6 +8226,17 @@ static int nl80211_crypto_settings(struct 
cfg80211_registered_device *rdev,
} 

[PATCH 6/6] mac80211: Add support for tx_control_port

2018-01-31 Thread Denis Kenzior
Signed-off-by: Denis Kenzior 
---
 net/mac80211/cfg.c |  1 +
 net/mac80211/ieee80211_i.h |  3 +++
 net/mac80211/main.c|  2 ++
 net/mac80211/tx.c  | 46 ++
 4 files changed, 52 insertions(+)

diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index f53bfb27295f..71cb45e517b0 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -3787,4 +3787,5 @@ const struct cfg80211_ops mac80211_config_ops = {
.add_nan_func = ieee80211_add_nan_func,
.del_nan_func = ieee80211_del_nan_func,
.set_multicast_to_unicast = ieee80211_set_multicast_to_unicast,
+   .tx_control_port = ieee80211_tx_control_port,
 };
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 6f91aea6a4cb..be444305ef06 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1735,6 +1735,9 @@ void ieee80211_check_fast_xmit(struct sta_info *sta);
 void ieee80211_check_fast_xmit_all(struct ieee80211_local *local);
 void ieee80211_check_fast_xmit_iface(struct ieee80211_sub_if_data *sdata);
 void ieee80211_clear_fast_xmit(struct sta_info *sta);
+int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev,
+ const u8 *buf, size_t len,
+ const u8 *dest, u16 proto, bool unencrypted);
 
 /* HT */
 void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata,
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 0785d04a80bc..e5a51267c75d 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -554,6 +554,8 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t 
priv_data_len,
   NL80211_FEATURE_USERSPACE_MPM |
   NL80211_FEATURE_FULL_AP_CLIENT_STATE;
wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_FILS_STA);
+   wiphy_ext_feature_set(wiphy,
+ NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211);
 
if (!ops->hw_scan)
wiphy->features |= NL80211_FEATURE_LOW_PRIORITY_SCAN |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 25904af38839..031b27fa752c 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -4754,3 +4754,49 @@ void __ieee80211_tx_skb_tid_band(struct 
ieee80211_sub_if_data *sdata,
ieee80211_xmit(sdata, NULL, skb);
local_bh_enable();
 }
+
+int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev,
+ const u8 *buf, size_t len,
+ const u8 *dest, u16 proto, bool unencrypted)
+{
+   struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+   struct ieee80211_local *local = sdata->local;
+   struct sk_buff *skb;
+   struct ethhdr *ehdr;
+   u32 flags;
+
+   /* Only accept CONTROL_PORT_PROTOCOL configured in CONNECT/ASSOCIATE
+* or Pre-Authentication
+*/
+   if (proto != sdata->control_port_protocol &&
+   proto != cpu_to_be16(ETH_P_PREAUTH))
+   return -EINVAL;
+
+   if (unencrypted)
+   flags = IEEE80211_TX_INTFL_DONT_ENCRYPT;
+   else
+   flags = 0;
+
+   skb = dev_alloc_skb(local->hw.extra_tx_headroom +
+   sizeof(struct ethhdr) + len);
+   if (!skb)
+   return -ENOMEM;
+
+   skb_reserve(skb, local->hw.extra_tx_headroom + sizeof(struct ethhdr));
+
+   skb_put_data(skb, buf, len);
+
+   ehdr = skb_push(skb, sizeof(struct ethhdr));
+   memcpy(ehdr->h_dest, dest, ETH_ALEN);
+   memcpy(ehdr->h_source, sdata->vif.addr, ETH_ALEN);
+   ehdr->h_proto = proto;
+
+   skb->dev = dev;
+   skb->protocol = htons(ETH_P_802_3);
+   skb_reset_network_header(skb);
+   skb_reset_mac_header(skb);
+
+   __ieee80211_subif_start_xmit(skb, skb->dev, flags);
+
+   return 0;
+}
-- 
2.13.5



[PATCH 1/6] uapi: Add 802.11 Preauthentication to if_ether

2018-01-31 Thread Denis Kenzior
This adds 0x88c7 protocol type to if_ether.

Signed-off-by: Denis Kenzior 
---
 include/uapi/linux/if_ether.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/uapi/linux/if_ether.h b/include/uapi/linux/if_ether.h
index f8cb5760ea4f..54585906e50a 100644
--- a/include/uapi/linux/if_ether.h
+++ b/include/uapi/linux/if_ether.h
@@ -89,6 +89,7 @@
 #define ETH_P_AOE  0x88A2  /* ATA over Ethernet*/
 #define ETH_P_8021AD   0x88A8  /* 802.1ad Service VLAN */
 #define ETH_P_802_EX1  0x88B5  /* 802.1 Local Experimental 1.  */
+#define ETH_P_PREAUTH  0x88C7  /* 802.11 Preauthentication */
 #define ETH_P_TIPC 0x88CA  /* TIPC */
 #define ETH_P_MACSEC   0x88E5  /* 802.1ae MACsec */
 #define ETH_P_8021AH   0x88E7  /* 802.1ah Backbone Service Tag */
-- 
2.13.5



[RFC v3 0/6] EAPoL over NL80211

2018-01-31 Thread Denis Kenzior
This patchset adds support for running 802.11 authentication mechanisms (e.g.
802.1X, 4-Way Handshake, etc) over NL80211 instead of putting them onto the
network device.  This has the advantage of fixing several long-standing race
conditions that result from userspace operating on multiple transports in order
to manage a 802.11 connection (e.g. NL80211 and wireless netdev, wlan0, etc).

For example, userspace would sometimes see 4-Way handshake packets before
NL80211 signaled that the connection has been established.  Leading to ugly
hacks or having the STA wait for retransmissions from the AP.

This also provides a way to mitigate a particularly nasty race condition where
the encryption key could be set prior to the 4-way handshake packet 4/4 being
sent.  This would result in the packet being sent encrypted and discarded by
the peer.  The mitigation strategy for this race is for userspace to explicitly
tell the kernel that a particular EAPoL packet should not be encrypted.

To make this possible this patchset introduces a new NL80211 command and several
new attributes.  A userspace that is capable of processing EAPoL packets over
NL80211 includes a new NL80211_ATTR_CONTROL_PORT_OVER_NL80211 attribute in its
NL80211_CMD_ASSOCIATE or NL80211_CMD_CONNECT requests being sent to the kernel.
The previously added NL80211_ATTR_SOCKET_OWNER attribute must also be included.
The latter is used by the kernel to send NL80211_CMD_CONTROL_PORT_FRAME
notifications back to userspace via a netlink unicast.  If the
NL80211_ATTR_CONTROL_PORT_OVER_NL80211 attribute is not specified, then legacy
behavior is kept and control port packets continue to flow over the network
interface.

If control port over nl80211 transport is requested, then control port packets
are intercepted just prior to being handed to the network device and sent over
netlink via the NL80211_CMD_CONTROL_PORT_FRAME notification.
NL80211_ATTR_CONTROL_PORT_ETHERTYPE and NL80211_ATTR_MAC are included to
specify the control port frame protocol and source address respectively.  If
the control port frame was received unencrypted then
NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT flag is also included.  NL80211_ATTR_FRAME
attribute contains the raw control port frame with all transport layer headers
stripped (e.g. this would be the raw EAPoL frame).

Userspace can reply to control port frames either via legacy methods (by sending
frames to the network device) or via NL80211_CMD_CONTROL_PORT_FRAME request.
Userspace would included NL80211_ATTR_FRAME with the raw control port frame as
well as NL80211_Attr_MAC and NL80211_ATTR_CONTROL_PORT_ETHERTYPE attributes to
specify the destination address and protocol respectively.  This allows
Pre-Authentication (protocol 0x88c7) frames to be sent via this mechanism as
well.  Finally, NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT flag can be included to
tell the driver to send the frame unencrypted, e.g. for 4-Way handshake 4/4
frames.

The proposed patchset has been tested in a mac80211_hwsim based environment with
hostapd and iwd.

ChangeLog

v3

- Added ETH_P_PREAUTH to if_ether.h
- Moved NL80211 feature bit from wiphy features to ext features
- Addressed various comments from Johannes

v2

- Added WIPHY_FLAG_CONTROL_PORT_OVER_NL80211 flag.  This is a capability flag
used by the drivers, e.g. that the driver supports control port over nl80211
capability.  This capability is now checked when CONTROL_PORT_OVER_NL80211 is
requested.

- mac80211 rx path now forwards Pre-Authentication frames over NL80211 as well,
if requested.  Tweaked the signature of cfg80211_rx_control_port.

- TX path reworked completely.  tx_control_port method has been introduced to
cfg80211_ops.  An implementation of tx_control_port for mac80211 was added.

Denis Kenzior (6):
  uapi: Add 802.11 Preauthentication to if_ether
  nl80211: Add CONTROL_PORT_OVER_NL80211 attribute
  nl80211: Add CMD_CONTROL_PORT_FRAME API
  mac80211: Send control port frames over nl80211
  nl80211: Implement TX of control port frames
  mac80211: Add support for tx_control_port

 include/net/cfg80211.h|  29 +
 include/uapi/linux/if_ether.h |   1 +
 include/uapi/linux/nl80211.h  |  32 +-
 net/mac80211/cfg.c|   3 +
 net/mac80211/ieee80211_i.h|   4 ++
 net/mac80211/main.c   |   2 +
 net/mac80211/mlme.c   |   2 +
 net/mac80211/rx.c |  34 +--
 net/mac80211/tx.c |  46 +++
 net/wireless/nl80211.c| 134 +-
 net/wireless/rdev-ops.h   |  15 +
 net/wireless/trace.h  |  46 +++
 12 files changed, 341 insertions(+), 7 deletions(-)

-- 
2.13.5



Re: [PATCH] brcmfmac: detect & reject faked packet generated by a firmware

2018-01-31 Thread Arend van Spriel

On 1/31/2018 5:14 PM, Hante Meuleman wrote:

It is an 802.2 frame, more specifically a LLC XID frames. So why it exists?
And more over, why would we crash as an result? Decoding info can be found
here:

https://www.cisco.com/c/en/us/support/docs/ibm-technologies/logical-link-control-llc/12247-45.html#con3

The frame was likely sent by the stack from remote site PC, should be
possible to capture with tcpdump.

I've seen these frames before, but don’t know what they are for. The frame
appears to be correctly encoded. The ethertype, is not a type, but a len
field. The only protocol with such a short len allowed is llc, see also


Could it be related to the fact that the interface is put in a bridge 
and hence the device is put in promiscuous mode? Anyway, I did not read 
anything about a firmware crash. Just that clients could not associate.


Regards,
Arend


Re: [PATCH] brcmfmac: detect & reject faked packet generated by a firmware

2018-01-31 Thread Rafał Miłecki

On 2018-01-30 12:30, Arend van Spriel wrote:

On 1/30/2018 10:09 AM, Rafał Miłecki wrote:

From: Rafał Miłecki 

When using 4366b1 and 4366c0 chipsets with more recent firmwares
1) 10.10 (TOB) (r663589)
2) 10.10.122.20 (r683106)
respectively, it is impossible to use brcmfmac with interface in AP
mode. With the AP interface bridged and multicast used, no STA will be
able to associate; the STA will be immediately disassociated when
attempting to associate.

Debugging revealed this to be caused by a "faked" packet (generated by
firmware), that is passed to the networking subsystem and then back to
the firmware. Fortunately this packet is easily identified and can be
detected and ignored as a workaround for misbehaving firmware.

Signed-off-by: Rafał Miłecki 
---
  .../wireless/broadcom/brcm80211/brcmfmac/core.c| 46 
++

  1 file changed, 46 insertions(+)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c

index 930e423f83a8..a98ba9bbc7fe 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
@@ -323,8 +323,54 @@ void brcmf_txflowblock_if(struct brcmf_if *ifp,
spin_unlock_irqrestore(>netif_stop_lock, flags);
  }

+/**
+ * brcmf_is_valid_skb - validates skb received from the hardware
+ *
+ * @skb: skb to check
+ *
+ * Sometimes firmware/hardware can generate broken packets that 
aren't real or
+ * valid and their skb-s shouldn't be passed up to the networking 
subsystem.

+ *
+ * Firmwares for 43602a1, 4366b1 and 4366c0 are known to *generate* a 
faked 6 B
+ * packet whenever a STA associates. The purpose of this fake packet 
remains
+ * unknown but it is clearly not data coming from a station. As such 
it

+ * shouldn't be passed to the networking subsystem.
+ *
+ * Normally such a packet would simply be ignored, but this is not 
the case with
+ * more recent 4366b1 and 4366c0 firmwares. These firmwares seem to 
explicitly
+ * check for this packet and will reject (disassociate) the station, 
making it
+ * impossible to connect to the AP at all. This can happen when using 
a bridged
+ * interface with multicasting. Such a scenario apparently isn't 
tested (or

+ * supported) by Broadcom's internal team.
+ */
+static bool brcmf_is_valid_skb(struct sk_buff *skb)
+{
+   const u8 fw_faked_packet[6] __aligned(2) = {
+   0x00, 0x01, 0xaf, 0x81, 0x01, 0x00,
+   };
+#if !defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
+   const u16 *a = (const u16 *)skb->data;
+   const u16 *b = (const u16 *)fw_faked_packet;
+#endif
+
+   if (skb->len != 6)
+   return true;
+
+#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
+	return !!(((*(const u32 *)skb->data) ^ (*(const u32 
*)fw_faked_packet)) |
+		  ((*(const u16 *)(skb->data + 4)) ^ (*(const u16 
*)(fw_faked_packet + 4;

+#else
+   return !!((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2]));
+#endif
+}


The code above does look very much like ether_addr_equal(). Why not
use that instead of reinventing it.


You're right about ether_addr_equal(), I wasn't sure if that is
acceptable to use it for comparing any 6 bytes data.

I know it'd work, it's just not what it was designed for.

Kalle?



  void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb)
  {
+   if (!brcmf_is_valid_skb(skb)) {
+   brcmu_pkt_buf_free_skb(skb);


Maybe we should add a driver stat for this although I better have a
look into the root cause of this.


It seems there are following stats fields we can use:
1) rx_errors
2) rx_dropped
3) rx_length_errors
4) rx_over_errors
5) rx_crc_errors
6) rx_frame_errors
7) rx_fifo_errors
8) rx_missed_errors

Which one do you think may fit this case the best?


Re: rtl8821ae keep alive not set, connection lost

2018-01-31 Thread Larry Finger

On 09/12/2017 05:09 PM, James Cameron wrote:

Summary: 40b368af4b75 ("rtlwifi: Fix alignment issues") breaks
rtl8821ae keep alive, causing "Connection to AP lost" and deauth, but
why?

Wireless connection is lost after a few seconds or minutes, on every
OLPC NL3 laptop with rtl8821ae, with any stable kernel after 4.10.1,
and any kernel with 40b368af4b75.

dmesg contains

   wlp2s0: Connection to AP 2c:b0:5d:a6:86:eb lost

iw event shows

   wlp2s0: del station 2c:b0:5d:a6:86:eb
   wlp2s0 (phy #0): deauth 74:c6:3b:09:b5:0d -> 2c:b0:5d:a6:86:eb reason 4: 
Disassociated due to inactivity
   wlp2s0 (phy #0): disconnected (local request)

Workaround is to bounce the link, then reconnect;

   ip link set wlp2s0 down
   ip link set wlp2s0 up
   iw dev wlp2s0 connect qz

A nearby monitor host captures a deauthentication packet sent by the
device.

Bisection showed cause is 40b368af4b75 ("rtlwifi: Fix alignment
issues") which changes the width of DBI register read.

On the face of it, 40b368af4b75 looks correct, especially compared
against same function in rtl8723be.

I've no idea why reverting fixes the problem.  I'm hoping someone here
might speculate and suggest ways to test.

As keep alive is set through this path, my guess is that keep alive is
not being set in the device.  Or perhaps reading 16-bits perturbs
another register.  Is there a way to test?

http://dev.laptop.org/~quozl/z/1drtGD.txt dmesg of 4.13

http://dev.laptop.org/~quozl/z/1drt7c.txt dmesg with 4.13 and revert
of 40b368af4b75


James,

I'm afraid we are needing to revisit this problem again. Changing that 8-bit 
read to a 16-bit version causes an unaligned memory reference in AARCH64, thus 
we will need to re-revert. To prevent problems on systems such as yours, PK 
plans to turn off ASPM capability and backdoor in certain platforms that will be 
listed in a quirks table. Please report the output of 'dmidecode -t system' for 
you affected system(s).


We hope you will be able to test any proposed patches.

Thanks,

Larry




RE: [PATCH] brcmfmac: detect & reject faked packet generated by a firmware

2018-01-31 Thread Hante Meuleman
It is an 802.2 frame, more specifically a LLC XID frames. So why it exists?
And more over, why would we crash as an result? Decoding info can be found
here:

https://www.cisco.com/c/en/us/support/docs/ibm-technologies/logical-link-control-llc/12247-45.html#con3

The frame was likely sent by the stack from remote site PC, should be
possible to capture with tcpdump.

I've seen these frames before, but don’t know what they are for. The frame
appears to be correctly encoded. The ethertype, is not a type, but a len
field. The only protocol with such a short len allowed is llc, see also

https://www.savvius.com/networking-glossary/ethernet/frame_formats/

So it is 802.2 (also known as LLC)

Regads,
Hante



-Original Message-
From: Arend van Spriel [mailto:arend.vanspr...@broadcom.com]
Sent: Wednesday, January 31, 2018 3:20 PM
To: Rafał Miłecki
Cc: Rafał Miłecki; Kalle Valo; Franky Lin; Hante Meuleman; Chi-Hsien Lin;
Wright Feng; Pieter-Paul Giesberts; linux-wireless@vger.kernel.org;
brcm80211-dev-list@broadcom.com; brcm80211-dev-l...@cypress.com
Subject: Re: [PATCH] brcmfmac: detect & reject faked packet generated by a
firmware

On 1/31/2018 2:14 PM, Rafał Miłecki wrote:
> On 2018-01-30 12:47, Arend van Spriel wrote:
>> On 1/30/2018 10:09 AM, Rafał Miłecki wrote:
>>> From: Rafał Miłecki 
>>>
>>> When using 4366b1 and 4366c0 chipsets with more recent firmwares
>>> 1) 10.10 (TOB) (r663589)
>>> 2) 10.10.122.20 (r683106)
>>> respectively, it is impossible to use brcmfmac with interface in AP
>>> mode. With the AP interface bridged and multicast used, no STA will
>>> be able to associate; the STA will be immediately disassociated when
>>> attempting to associate.
>>>
>>> Debugging revealed this to be caused by a "faked" packet (generated
>>> by firmware), that is passed to the networking subsystem and then
>>> back to the firmware. Fortunately this packet is easily identified
>>> and can be detected and ignored as a workaround for misbehaving
>>> firmware.
>>
>> I am actually wondering what this packet is. Have you checked in
>> brcmf_msgbuf_process_rx_complete(). I am curious what buflen is there
>> and what eth_type_trans() will do to the packet, ie. what protocol.
>> As everything should be 802.3 we could/should add a length check of
>> 14 bytes.
>
> Did you find anything?

I was going to say no, but below I see I misinterpreted your commit message
and thought we were getting 6 bytes from firmware, but it is 6 bytes +
ETH_HLEN.

> I got some debugging info, hopefully this is what you expected

and more ... :-)

> [  144.356648] brcmfmac: [brcmf_msgbuf_process_rx_complete] msg.msgtype:
> 0x12
> [  144.363559] brcmfmac: [brcmf_msgbuf_process_rx_complete] msg.ifidx:
> 0x00
> [  144.370374] brcmfmac: [brcmf_msgbuf_process_rx_complete] msg.flags:
> 0x80
> [  144.377179] brcmfmac: [brcmf_msgbuf_process_rx_complete] msg.rsvd0:
> 0x00
> [  144.383986] brcmfmac: [brcmf_msgbuf_process_rx_complete]
> msg.request_id: 0x0041
> [  144.391661] brcmfmac: [brcmf_msgbuf_process_rx_complete]
> compl_hdr.status:   0x
> [  144.399156] brcmfmac: [brcmf_msgbuf_process_rx_complete]
> compl_hdr.flow_ring_id: 0x
> [  144.407179] brcmfmac: [brcmf_msgbuf_process_rx_complete]
> metadata_len:   0x
> [  144.414334] brcmfmac: [brcmf_msgbuf_process_rx_complete] data_len:
> 0x0014
> [  144.421227] brcmfmac: [brcmf_msgbuf_process_rx_complete] data_offset:
> 0x
> [  144.428288] brcmfmac: [brcmf_msgbuf_process_rx_complete] flags:
> 0x0001
> [  144.434918] brcmfmac: [brcmf_msgbuf_process_rx_complete] rx_status_0:
> 0x
> [  144.442334] brcmfmac: [brcmf_msgbuf_process_rx_complete] rx_status_1:
> 0x
> [  144.449750] brcmfmac: [brcmf_msgbuf_process_rx_complete] rsvd0:
> 0x0001
> [  144.456724] brcmfmac: [brcmf_msgbuf_process_rx_complete] skb->data:
> ff ff ff ff  ff ff ec 10  7b 5f ?? ??  00 06 00 01  af 81 01
> 00 [  144.467883] brcmfmac: [brcmf_msgbuf_process_rx_complete]
> skb->protocol:  0x0400

Not sure what protocol that is. Can not find it in if_ether.h. Will look in
our firmware repo for it.

Thanks,
Arend

> (just masked 2 bytes of my MAC)
>
>
> diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
> b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
> index 1bd4b96..08cdcaf 100644
> --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
> +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
> @@ -1172,7 +1172,43 @@ brcmf_msgbuf_process_rx_complete(struct
> brcmf_msgbuf *msgbuf, void *buf)
>   return;
>   }
>
> +if (skb->len == ETH_HLEN + 6) {
> +uint8_t *data;
> +int i;
> +
> +pr_info("[%s] msg.msgtype:\t0x%02x\n", __func__,
> rx_complete->msg.msgtype);
> +pr_info("[%s] msg.ifidx:\t\t0x%02x\n", __func__,
> rx_complete->msg.ifidx);
> +pr_info("[%s] msg.flags:\t\t0x%02x\n", 

Re: [PATCH] wireless: zd1211rw: remove redundant assignment of pointer 'q'

2018-01-31 Thread Dan Carpenter
On Wed, Jan 31, 2018 at 02:58:57PM +0200, Andy Shevchenko wrote:
> On Tue, Jan 30, 2018 at 8:25 PM, Colin King  wrote:
> > From: Colin Ian King 
> >
> > Pointer q is initialized and then almost immediately afterwards being
> > re-assigned the same value. Remove the second redundant assignment.
> >
> 
> Don't you see strange that in the same context of the patch two users
> of q are present?
> 
> How did you test this?
> 

The patch is obviously correct, I don't understand the question.

regards,
dan carpenter




Re: ath9k will not tx packets sometimes.

2018-01-31 Thread Sebastian Gottschall

Am 31.01.2018 um 14:46 schrieb Toke Høiland-Jørgensen:

Sebastian Gottschall  writes:


Am 31.01.2018 um 12:50 schrieb Toke Høiland-Jørgensen:

Sebastian Gottschall  writes:


Am 30.01.2018 um 19:55 schrieb Toke Høiland-Jørgensen:

Ben Greear  writes:


I'm actually working on reworking that whole scheduler logic, and move
some of it into mac80211. Could you test this (WiP) patch and see if
that has the same problem?

It had some serious conflicts in ath10k, due to my local changes, so
I did not actually test this.

Can send you a version without the ath10k changes tomorrow if you'd like
to test - but will try to reproduce myself as well...


But, a revert of the atf patches (a6e56d749 and 63fefa050) appear to
have resolved the issue. I'll test more with these reverted, and maybe
will have time to work more on actually fixing upstream code next time
I move to a newer kernel (and/or after your pending changes get in).

Ah, that narrows it down some. Well, that is the code I'm hacking on
currently anyway, so let's see if we can't get it fixed as part of that
series :)

i have some addition information for you maybe. in the same timeframe i
noticed a increased memory usage for ath9k devices.
maybe that helps. so i hit memory boundaries on embedded devices with
dual interfaces and just 32 mb  ram now which wasnt the case before
is this patch worth to try from my side?

This is probably because of the added queue space. Which is sort of by
design. In 3ff23cd5654b9c8f4d567caa73439b4c39fbeaae we lowered the
default limit for non-VHT devices to 4MB. But if you have several PHYs
on a very memory constrained device you could still run out I guess.

`echo fq_memory_limit 2097152 > /sys/kernel/debug/ieee80211/phy0/aqm`
would limit it to 2MB for that phy...

what if i tried that already? :-)

Hmm, then it's maybe a bug? Changing the limit makes no difference at
all? Does your build include 0bfe649fbb133? What are values of the

maybe it makes a change but i run into oom after a while as well

counters in /sys/kernel/debug/ieee80211/phy0/aqm ?
i will check the current state in the next days. havent checked it over 
the last 2 months on the affected device




-Toke



--
Mit freundlichen Grüssen / Regards

Sebastian Gottschall / CTO

NewMedia-NET GmbH - DD-WRT
Firmensitz:  Stubenwaldallee 21a, 64625 Bensheim
Registergericht: Amtsgericht Darmstadt, HRB 25473
Geschäftsführer: Peter Steinhäuser, Christian Scheele
http://www.dd-wrt.com
email: s.gottsch...@dd-wrt.com
Tel.: +496251-582650 / Fax: +496251-5826565



Re: [PATCH v4 2/3] mac80211_hwsim: add nl_err_msg in hwsim_new_radio in netlink case

2018-01-31 Thread Benjamin Beichler
Am 31.01.2018 um 13:05 schrieb Johannes Berg:
> On Tue, 2018-01-30 at 10:47 +0100, Benjamin Beichler wrote:
>
>> It should not be triggered because of already existing macs, I added it
>> for somehow completeness, but you can leave it out.
> Sure.
>
>> After having again a look on it, there could be an -ENOMEM on
>> rhashtable_insert. Maybe it's better to explicitly catch only -EEXIST
>> and print for the rest an generic error. Do you agree ?
> Nah, that's unlikely enough ... and you get -ENOMEM back in userspace
> too.
>
> That said, good thing I looked at this - you forgot a set of braces :-)
Damn ... but fortunately you saw it. As you already accepted it, I don't
need to send new patches :-D

> johannes
>
thanks for your efforts!

Benjamin


-- 
M.Sc. Benjamin Beichler

Universität Rostock, Fakultät für Informatik und Elektrotechnik
Institut für Angewandte Mikroelektronik und Datentechnik

University of Rostock, Department of CS and EE
Institute of Applied Microelectronics and CE

Richard-Wagner-Straße 31
18119 Rostock
Deutschland/Germany

phone: +49 (0) 381 498 - 7278
email: benjamin.beich...@uni-rostock.de
www: http://www.imd.uni-rostock.de/




smime.p7s
Description: S/MIME Cryptographic Signature


Re: [PATCH] brcmfmac: detect & reject faked packet generated by a firmware

2018-01-31 Thread Arend van Spriel

On 1/31/2018 2:14 PM, Rafał Miłecki wrote:

On 2018-01-30 12:47, Arend van Spriel wrote:

On 1/30/2018 10:09 AM, Rafał Miłecki wrote:

From: Rafał Miłecki 

When using 4366b1 and 4366c0 chipsets with more recent firmwares
1) 10.10 (TOB) (r663589)
2) 10.10.122.20 (r683106)
respectively, it is impossible to use brcmfmac with interface in AP
mode. With the AP interface bridged and multicast used, no STA will be
able to associate; the STA will be immediately disassociated when
attempting to associate.

Debugging revealed this to be caused by a "faked" packet (generated by
firmware), that is passed to the networking subsystem and then back to
the firmware. Fortunately this packet is easily identified and can be
detected and ignored as a workaround for misbehaving firmware.


I am actually wondering what this packet is. Have you checked in
brcmf_msgbuf_process_rx_complete(). I am curious what buflen is there
and what eth_type_trans() will do to the packet, ie. what protocol. As
everything should be 802.3 we could/should add a length check of 14
bytes.


Did you find anything?


I was going to say no, but below I see I misinterpreted your commit 
message and thought we were getting 6 bytes from firmware, but it is 6 
bytes + ETH_HLEN.



I got some debugging info, hopefully this is what you expected


and more ... :-)


[  144.356648] brcmfmac: [brcmf_msgbuf_process_rx_complete] msg.msgtype:
0x12
[  144.363559] brcmfmac: [brcmf_msgbuf_process_rx_complete] msg.ifidx:
0x00
[  144.370374] brcmfmac: [brcmf_msgbuf_process_rx_complete] msg.flags:
0x80
[  144.377179] brcmfmac: [brcmf_msgbuf_process_rx_complete] msg.rsvd0:
0x00
[  144.383986] brcmfmac: [brcmf_msgbuf_process_rx_complete]
msg.request_id: 0x0041
[  144.391661] brcmfmac: [brcmf_msgbuf_process_rx_complete]
compl_hdr.status:   0x
[  144.399156] brcmfmac: [brcmf_msgbuf_process_rx_complete]
compl_hdr.flow_ring_id: 0x
[  144.407179] brcmfmac: [brcmf_msgbuf_process_rx_complete]
metadata_len:   0x
[  144.414334] brcmfmac: [brcmf_msgbuf_process_rx_complete] data_len:
0x0014
[  144.421227] brcmfmac: [brcmf_msgbuf_process_rx_complete] data_offset:
0x
[  144.428288] brcmfmac: [brcmf_msgbuf_process_rx_complete] flags:
0x0001
[  144.434918] brcmfmac: [brcmf_msgbuf_process_rx_complete] rx_status_0:
0x
[  144.442334] brcmfmac: [brcmf_msgbuf_process_rx_complete] rx_status_1:
0x
[  144.449750] brcmfmac: [brcmf_msgbuf_process_rx_complete] rsvd0:
0x0001
[  144.456724] brcmfmac: [brcmf_msgbuf_process_rx_complete] skb->data:
ff ff ff ff  ff ff ec 10  7b 5f ?? ??  00 06 00 01  af 81 01 00
[  144.467883] brcmfmac: [brcmf_msgbuf_process_rx_complete]
skb->protocol:  0x0400


Not sure what protocol that is. Can not find it in if_ether.h. Will look 
in our firmware repo for it.


Thanks,
Arend


(just masked 2 bytes of my MAC)


diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
index 1bd4b96..08cdcaf 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
@@ -1172,7 +1172,43 @@ brcmf_msgbuf_process_rx_complete(struct
brcmf_msgbuf *msgbuf, void *buf)
  return;
  }

+if (skb->len == ETH_HLEN + 6) {
+uint8_t *data;
+int i;
+
+pr_info("[%s] msg.msgtype:\t0x%02x\n", __func__,
rx_complete->msg.msgtype);
+pr_info("[%s] msg.ifidx:\t\t0x%02x\n", __func__,
rx_complete->msg.ifidx);
+pr_info("[%s] msg.flags:\t\t0x%02x\n", __func__,
rx_complete->msg.flags);
+pr_info("[%s] msg.rsvd0:\t\t0x%02x\n", __func__,
rx_complete->msg.rsvd0);
+pr_info("[%s] msg.request_id:\t0x%08x\n", __func__,
le32_to_cpu(rx_complete->msg.request_id));
+
+pr_info("[%s] compl_hdr.status:\t0x%04x\n", __func__,
le16_to_cpu(rx_complete->compl_hdr.status));
+pr_info("[%s] compl_hdr.flow_ring_id:\t0x%04x\n", __func__,
le16_to_cpu(rx_complete->compl_hdr.flow_ring_id));
+
+pr_info("[%s] metadata_len:\t0x%04x\n", __func__,
le16_to_cpu(rx_complete->metadata_len));
+pr_info("[%s] data_len:\t\t0x%04x\n", __func__,
le16_to_cpu(rx_complete->data_len));
+pr_info("[%s] data_offset:\t0x%04x\n", __func__,
le16_to_cpu(rx_complete->data_offset));
+pr_info("[%s] flags:\t\t0x%04x\n", __func__,
le16_to_cpu(rx_complete->flags));
+pr_info("[%s] rx_status_0:\t0x%08x\n", __func__,
le32_to_cpu(rx_complete->rx_status_0));
+pr_info("[%s] rx_status_1:\t0x%08x\n", __func__,
le32_to_cpu(rx_complete->rx_status_1));
+pr_info("[%s] rsvd0:\t\t0x%08x\n", __func__,
le32_to_cpu(rx_complete->rsvd0));
+
+data = skb->data;
+pr_info("[%s] skb->data:\t\t", __func__);
+for (i = 0; i < 32 && i < skb->len; i++) {
+pr_cont("%02x ", data[i]);
+if (i % 4 == 3)
+

Re: [PATCH] brcmfmac: detect & reject faked packet generated by a firmware

2018-01-31 Thread Arend van Spriel

On 1/31/2018 2:11 PM, Rafał Miłecki wrote:

  void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb)
  {
+if (!brcmf_is_valid_skb(skb)) {
+brcmu_pkt_buf_free_skb(skb);


Maybe we should add a driver stat for this although I better have a
look into the root cause of this.


It seems there are following stats fields we can use:
1) rx_errors
2) rx_dropped
3) rx_length_errors
4) rx_over_errors
5) rx_crc_errors
6) rx_frame_errors
7) rx_fifo_errors
8) rx_missed_errors

Which one do you think may fit this case the best?


Those are actually netdev stats, right? Not sure I want to have those, 
but if any I would say 3) fits best.


Regards,
Arend


Re: [PATCH] brcmfmac: detect & reject faked packet generated by a firmware

2018-01-31 Thread Rafał Miłecki

On 2018-01-30 12:47, Arend van Spriel wrote:

On 1/30/2018 10:09 AM, Rafał Miłecki wrote:

From: Rafał Miłecki 

When using 4366b1 and 4366c0 chipsets with more recent firmwares
1) 10.10 (TOB) (r663589)
2) 10.10.122.20 (r683106)
respectively, it is impossible to use brcmfmac with interface in AP
mode. With the AP interface bridged and multicast used, no STA will be
able to associate; the STA will be immediately disassociated when
attempting to associate.

Debugging revealed this to be caused by a "faked" packet (generated by
firmware), that is passed to the networking subsystem and then back to
the firmware. Fortunately this packet is easily identified and can be
detected and ignored as a workaround for misbehaving firmware.


I am actually wondering what this packet is. Have you checked in
brcmf_msgbuf_process_rx_complete(). I am curious what buflen is there
and what eth_type_trans() will do to the packet, ie. what protocol. As
everything should be 802.3 we could/should add a length check of 14
bytes.


Did you find anything?

I got some debugging info, hopefully this is what you expected

[  144.356648] brcmfmac: [brcmf_msgbuf_process_rx_complete] msg.msgtype: 
   0x12
[  144.363559] brcmfmac: [brcmf_msgbuf_process_rx_complete] msg.ifidx:   
   0x00
[  144.370374] brcmfmac: [brcmf_msgbuf_process_rx_complete] msg.flags:   
   0x80
[  144.377179] brcmfmac: [brcmf_msgbuf_process_rx_complete] msg.rsvd0:   
   0x00
[  144.383986] brcmfmac: [brcmf_msgbuf_process_rx_complete] 
msg.request_id: 0x0041
[  144.391661] brcmfmac: [brcmf_msgbuf_process_rx_complete] 
compl_hdr.status:   0x
[  144.399156] brcmfmac: [brcmf_msgbuf_process_rx_complete] 
compl_hdr.flow_ring_id: 0x
[  144.407179] brcmfmac: [brcmf_msgbuf_process_rx_complete] 
metadata_len:   0x
[  144.414334] brcmfmac: [brcmf_msgbuf_process_rx_complete] data_len:
   0x0014
[  144.421227] brcmfmac: [brcmf_msgbuf_process_rx_complete] data_offset: 
   0x
[  144.428288] brcmfmac: [brcmf_msgbuf_process_rx_complete] flags:   
   0x0001
[  144.434918] brcmfmac: [brcmf_msgbuf_process_rx_complete] rx_status_0: 
   0x
[  144.442334] brcmfmac: [brcmf_msgbuf_process_rx_complete] rx_status_1: 
   0x
[  144.449750] brcmfmac: [brcmf_msgbuf_process_rx_complete] rsvd0:   
   0x0001
[  144.456724] brcmfmac: [brcmf_msgbuf_process_rx_complete] skb->data:   
   ff ff ff ff  ff ff ec 10  7b 5f ?? ??  00 06 00 01  af 81 01 00
[  144.467883] brcmfmac: [brcmf_msgbuf_process_rx_complete] 
skb->protocol:  0x0400


(just masked 2 bytes of my MAC)


diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c 
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c

index 1bd4b96..08cdcaf 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
@@ -1172,7 +1172,43 @@ brcmf_msgbuf_process_rx_complete(struct 
brcmf_msgbuf *msgbuf, void *buf)

return;
}

+   if (skb->len == ETH_HLEN + 6) {
+   uint8_t *data;
+   int i;
+
+		pr_info("[%s] msg.msgtype:\t0x%02x\n", __func__, 
rx_complete->msg.msgtype);
+		pr_info("[%s] msg.ifidx:\t\t0x%02x\n", __func__, 
rx_complete->msg.ifidx);
+		pr_info("[%s] msg.flags:\t\t0x%02x\n", __func__, 
rx_complete->msg.flags);
+		pr_info("[%s] msg.rsvd0:\t\t0x%02x\n", __func__, 
rx_complete->msg.rsvd0);
+		pr_info("[%s] msg.request_id:\t0x%08x\n", __func__, 
le32_to_cpu(rx_complete->msg.request_id));

+
+		pr_info("[%s] compl_hdr.status:\t0x%04x\n", __func__, 
le16_to_cpu(rx_complete->compl_hdr.status));
+		pr_info("[%s] compl_hdr.flow_ring_id:\t0x%04x\n", __func__, 
le16_to_cpu(rx_complete->compl_hdr.flow_ring_id));

+
+		pr_info("[%s] metadata_len:\t0x%04x\n", __func__, 
le16_to_cpu(rx_complete->metadata_len));
+		pr_info("[%s] data_len:\t\t0x%04x\n", __func__, 
le16_to_cpu(rx_complete->data_len));
+		pr_info("[%s] data_offset:\t0x%04x\n", __func__, 
le16_to_cpu(rx_complete->data_offset));
+		pr_info("[%s] flags:\t\t0x%04x\n", __func__, 
le16_to_cpu(rx_complete->flags));
+		pr_info("[%s] rx_status_0:\t0x%08x\n", __func__, 
le32_to_cpu(rx_complete->rx_status_0));
+		pr_info("[%s] rx_status_1:\t0x%08x\n", __func__, 
le32_to_cpu(rx_complete->rx_status_1));
+		pr_info("[%s] rsvd0:\t\t0x%08x\n", __func__, 
le32_to_cpu(rx_complete->rsvd0));

+
+   data = skb->data;
+   pr_info("[%s] skb->data:\t\t", __func__);
+   for (i = 0; i < 32 && i < skb->len; i++) {
+   pr_cont("%02x ", data[i]);
+   if (i % 4 == 3)
+   pr_cont(" ");
+   }
+   pr_cont("\n");
+   }
+
skb->protocol = eth_type_trans(skb, ifp->ndev);
+
+   if (skb->len == 6) {
+   pr_info("[%s] skb->protocol:\t0x%04x\n", __func__, 
skb->protocol);
+   }
+
brcmf_netif_rx(ifp, skb);

Re: ath9k will not tx packets sometimes.

2018-01-31 Thread Toke Høiland-Jørgensen
Sebastian Gottschall  writes:

> Am 31.01.2018 um 12:50 schrieb Toke Høiland-Jørgensen:
>> Sebastian Gottschall  writes:
>>
>>> Am 30.01.2018 um 19:55 schrieb Toke Høiland-Jørgensen:
 Ben Greear  writes:

>> I'm actually working on reworking that whole scheduler logic, and move
>> some of it into mac80211. Could you test this (WiP) patch and see if
>> that has the same problem?
> It had some serious conflicts in ath10k, due to my local changes, so
> I did not actually test this.
 Can send you a version without the ath10k changes tomorrow if you'd like
 to test - but will try to reproduce myself as well...

> But, a revert of the atf patches (a6e56d749 and 63fefa050) appear to
> have resolved the issue. I'll test more with these reverted, and maybe
> will have time to work more on actually fixing upstream code next time
> I move to a newer kernel (and/or after your pending changes get in).
 Ah, that narrows it down some. Well, that is the code I'm hacking on
 currently anyway, so let's see if we can't get it fixed as part of that
 series :)
>>> i have some addition information for you maybe. in the same timeframe i
>>> noticed a increased memory usage for ath9k devices.
>>> maybe that helps. so i hit memory boundaries on embedded devices with
>>> dual interfaces and just 32 mb  ram now which wasnt the case before
>>> is this patch worth to try from my side?
>> This is probably because of the added queue space. Which is sort of by
>> design. In 3ff23cd5654b9c8f4d567caa73439b4c39fbeaae we lowered the
>> default limit for non-VHT devices to 4MB. But if you have several PHYs
>> on a very memory constrained device you could still run out I guess.
>>
>> `echo fq_memory_limit 2097152 > /sys/kernel/debug/ieee80211/phy0/aqm`
>> would limit it to 2MB for that phy...
> what if i tried that already? :-)

Hmm, then it's maybe a bug? Changing the limit makes no difference at
all? Does your build include 0bfe649fbb133? What are values of the
counters in /sys/kernel/debug/ieee80211/phy0/aqm ?

-Toke


Re: ath9k will not tx packets sometimes.

2018-01-31 Thread Sebastian Gottschall

Am 31.01.2018 um 12:50 schrieb Toke Høiland-Jørgensen:

Sebastian Gottschall  writes:


Am 30.01.2018 um 19:55 schrieb Toke Høiland-Jørgensen:

Ben Greear  writes:


I'm actually working on reworking that whole scheduler logic, and move
some of it into mac80211. Could you test this (WiP) patch and see if
that has the same problem?

It had some serious conflicts in ath10k, due to my local changes, so
I did not actually test this.

Can send you a version without the ath10k changes tomorrow if you'd like
to test - but will try to reproduce myself as well...


But, a revert of the atf patches (a6e56d749 and 63fefa050) appear to
have resolved the issue. I'll test more with these reverted, and maybe
will have time to work more on actually fixing upstream code next time
I move to a newer kernel (and/or after your pending changes get in).

Ah, that narrows it down some. Well, that is the code I'm hacking on
currently anyway, so let's see if we can't get it fixed as part of that
series :)

i have some addition information for you maybe. in the same timeframe i
noticed a increased memory usage for ath9k devices.
maybe that helps. so i hit memory boundaries on embedded devices with
dual interfaces and just 32 mb  ram now which wasnt the case before
is this patch worth to try from my side?

This is probably because of the added queue space. Which is sort of by
design. In 3ff23cd5654b9c8f4d567caa73439b4c39fbeaae we lowered the
default limit for non-VHT devices to 4MB. But if you have several PHYs
on a very memory constrained device you could still run out I guess.

`echo fq_memory_limit 2097152 > /sys/kernel/debug/ieee80211/phy0/aqm`
would limit it to 2MB for that phy...

what if i tried that already? :-)

Sebastian


-Toke



--
Mit freundlichen Grüssen / Regards

Sebastian Gottschall / CTO

NewMedia-NET GmbH - DD-WRT
Firmensitz:  Stubenwaldallee 21a, 64625 Bensheim
Registergericht: Amtsgericht Darmstadt, HRB 25473
Geschäftsführer: Peter Steinhäuser, Christian Scheele
http://www.dd-wrt.com
email: s.gottsch...@dd-wrt.com
Tel.: +496251-582650 / Fax: +496251-5826565



Re: [PATCH] wireless: zd1211rw: remove redundant assignment of pointer 'q'

2018-01-31 Thread Andy Shevchenko
On Tue, Jan 30, 2018 at 8:25 PM, Colin King  wrote:
> From: Colin Ian King 
>
> Pointer q is initialized and then almost immediately afterwards being
> re-assigned the same value. Remove the second redundant assignment.
>

Don't you see strange that in the same context of the patch two users
of q are present?

How did you test this?

> Cleans up clang warning:
> drivers/net/wireless/zydas/zd1211rw/zd_mac.c:503:23: warning: Value
> stored to 'q' during its initialization is never read

> -   q = >ack_wait_queue;
> spin_lock_irqsave(>lock, flags);
>
> skb_queue_walk(q, skb) {



-- 
With Best Regards,
Andy Shevchenko


Re: [PATCH v4 2/3] mac80211_hwsim: add nl_err_msg in hwsim_new_radio in netlink case

2018-01-31 Thread Johannes Berg
On Tue, 2018-01-30 at 10:47 +0100, Benjamin Beichler wrote:

> It should not be triggered because of already existing macs, I added it
> for somehow completeness, but you can leave it out.

Sure.

> After having again a look on it, there could be an -ENOMEM on
> rhashtable_insert. Maybe it's better to explicitly catch only -EEXIST
> and print for the rest an generic error. Do you agree ?

Nah, that's unlikely enough ... and you get -ENOMEM back in userspace
too.

That said, good thing I looked at this - you forgot a set of braces :-)

johannes


[PATCH] ath10k: Add sta rx packet stats per tid

2018-01-31 Thread Vasanthakumar Thiagarajan
Added per tid sta counters for the following

- Total number MSDUs received from firmware
- Number of MSDUs received with errors like decryption, crc, mic ,etc.
- Number of MSDUs dropped in the driver
- A-MPDU/A-MSDU subframe stats
- Number of MSDUS passed to mac80211

All stats other than A-MPDU stats are only for received data frames.
A-MPDU stats might have stats for management frames when monitor
interface is active where management frames are notified both in wmi
and HTT interfaces.

These per tid stats can be enabled with tid bitmask through a debugfs
like below

 echo  > /sys/kernel/debug/ieee80211/phyX/ath10k/sta_tid_stats_mask

 tid 16 (tid_bitmask 0x1) is used for non-qos data/management frames

The stats are read from
/sys/kernel/debug/ieee80211/phyX/netdev\:wlanX/stations//dump_tid_stats

Sample output:

 To enable rx stats for tid 0, 5 and 6,

 echo 0x0061 > /sys/kernel/debug/ieee80211/phy0/ath10k/sta_tid_stats_mask

cat 
/sys/kernel/debug/ieee80211/phy0/netdev\:wlan15/stations/8c\:fd\:f0\:0a\:8e\:df/dump_tid_stats

Driver Rx pkt stats per tid, ([tid] count)
--
MSDUs from FW   [00] 2567[05] 3178[06] 1089
MSDUs unchained [00] 0   [05] 0   [06] 0
MSDUs locally dropped:chained   [00] 0   [05] 0   [06] 0
MSDUs locally dropped:filtered  [00] 0   [05] 0   [06] 0
MSDUs queued for mac80211   [00] 2567[05] 3178[06] 1089
MSDUs with error:fcs_err[00] 0   [05] 0   [06] 2
MSDUs with error:tkip_err   [00] 0   [05] 0   [06] 0
MSDUs with error:crypt_err  [00] 0   [05] 0   [06] 0
MSDUs with error:peer_idx_inval [00] 0   [05] 0   [06] 0

A-MPDU num subframes upto 10[00] 2567[05] 3178[06] 1087
A-MPDU num subframes 11-20  [00] 0   [05] 0   [06] 0
A-MPDU num subframes 21-30  [00] 0   [05] 0   [06] 0
A-MPDU num subframes 31-40  [00] 0   [05] 0   [06] 0
A-MPDU num subframes 41-50  [00] 0   [05] 0   [06] 0
A-MPDU num subframes 51-60  [00] 0   [05] 0   [06] 0
A-MPDU num subframes >60[00] 0   [05] 0   [06] 0

A-MSDU num subframes 1  [00] 2567[05] 3178[06] 1089
A-MSDU num subframes 2  [00] 0   [05] 0   [06] 0
A-MSDU num subframes 3  [00] 0   [05] 0   [06] 0
A-MSDU num subframes 4  [00] 0   [05] 0   [06] 0
A-MSDU num subframes >4 [00] 0   [05] 0   [06] 0

Signed-off-by: Vasanthakumar Thiagarajan 
---
 drivers/net/wireless/ath/ath10k/core.h|  45 
 drivers/net/wireless/ath/ath10k/debug.c   |  48 +
 drivers/net/wireless/ath/ath10k/debug.h   |  31 +++
 drivers/net/wireless/ath/ath10k/debugfs_sta.c | 286 ++
 drivers/net/wireless/ath/ath10k/htt_rx.c  |  71 ++-
 5 files changed, 471 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.h 
b/drivers/net/wireless/ath/ath10k/core.h
index fe6b30356d3b..c624b96f8b84 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -1,6 +1,7 @@
 /*
  * Copyright (c) 2005-2011 Atheros Communications Inc.
  * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -354,6 +355,45 @@ struct ath10k_txq {
unsigned long num_push_allowed;
 };
 
+enum ath10k_pkt_rx_err {
+   ATH10K_PKT_RX_ERR_FCS,
+   ATH10K_PKT_RX_ERR_TKIP,
+   ATH10K_PKT_RX_ERR_CRYPT,
+   ATH10K_PKT_RX_ERR_PEER_IDX_INVAL,
+   ATH10K_PKT_RX_ERR_MAX,
+};
+
+enum ath10k_ampdu_subfrm_num {
+   ATH10K_AMPDU_SUBFRM_NUM_10,
+   ATH10K_AMPDU_SUBFRM_NUM_20,
+   ATH10K_AMPDU_SUBFRM_NUM_30,
+   ATH10K_AMPDU_SUBFRM_NUM_40,
+   ATH10K_AMPDU_SUBFRM_NUM_50,
+   ATH10K_AMPDU_SUBFRM_NUM_60,
+   ATH10K_AMPDU_SUBFRM_NUM_MORE,
+   ATH10K_AMPDU_SUBFRM_NUM_MAX,
+};
+
+enum ath10k_amsdu_subfrm_num {
+   ATH10K_AMSDU_SUBFRM_NUM_1,
+   ATH10K_AMSDU_SUBFRM_NUM_2,
+   ATH10K_AMSDU_SUBFRM_NUM_3,
+   ATH10K_AMSDU_SUBFRM_NUM_4,
+   ATH10K_AMSDU_SUBFRM_NUM_MORE,
+   ATH10K_AMSDU_SUBFRM_NUM_MAX,
+};
+
+struct ath10k_sta_tid_stats {
+   unsigned long int rx_pkt_from_fw;
+   unsigned long int rx_pkt_unchained;
+   unsigned long int rx_pkt_drop_chained;
+   unsigned long int rx_pkt_drop_filter;
+   unsigned long int rx_pkt_err[ATH10K_PKT_RX_ERR_MAX];
+   unsigned long int rx_pkt_queued_for_mac;
+   unsigned long int rx_pkt_ampdu[ATH10K_AMPDU_SUBFRM_NUM_MAX];
+  

Re: ath9k will not tx packets sometimes.

2018-01-31 Thread Toke Høiland-Jørgensen
Sebastian Gottschall  writes:

> Am 30.01.2018 um 19:55 schrieb Toke Høiland-Jørgensen:
>> Ben Greear  writes:
>>
 I'm actually working on reworking that whole scheduler logic, and move
 some of it into mac80211. Could you test this (WiP) patch and see if
 that has the same problem?
>>> It had some serious conflicts in ath10k, due to my local changes, so
>>> I did not actually test this.
>> Can send you a version without the ath10k changes tomorrow if you'd like
>> to test - but will try to reproduce myself as well...
>>
>>> But, a revert of the atf patches (a6e56d749 and 63fefa050) appear to
>>> have resolved the issue. I'll test more with these reverted, and maybe
>>> will have time to work more on actually fixing upstream code next time
>>> I move to a newer kernel (and/or after your pending changes get in).
>> Ah, that narrows it down some. Well, that is the code I'm hacking on
>> currently anyway, so let's see if we can't get it fixed as part of that
>> series :)
> i have some addition information for you maybe. in the same timeframe i 
> noticed a increased memory usage for ath9k devices.
> maybe that helps. so i hit memory boundaries on embedded devices with 
> dual interfaces and just 32 mb  ram now which wasnt the case before
> is this patch worth to try from my side?

This is probably because of the added queue space. Which is sort of by
design. In 3ff23cd5654b9c8f4d567caa73439b4c39fbeaae we lowered the
default limit for non-VHT devices to 4MB. But if you have several PHYs
on a very memory constrained device you could still run out I guess.

`echo fq_memory_limit 2097152 > /sys/kernel/debug/ieee80211/phy0/aqm`
would limit it to 2MB for that phy...

-Toke


[PATCHv3 2/2] mac80211: Add support to notify ht/vht opmode modification.

2018-01-31 Thread Tamizh chelvam
This will add support to send an event to a userspace application
whenever station advertise its ht/vht opmode modification through
an action frame.

Signed-off-by: Tamizh chelvam 
---
v3:
  * Initialized the sta_opmode_info structure variable before using

 net/mac80211/rx.c  | 14 ++
 net/mac80211/vht.c |  9 +
 2 files changed, 23 insertions(+)

diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index fd58061..e755f93 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -2848,6 +2848,7 @@ static void ieee80211_process_sa_query_req(struct 
ieee80211_sub_if_data *sdata,
case WLAN_HT_ACTION_SMPS: {
struct ieee80211_supported_band *sband;
enum ieee80211_smps_mode smps_mode;
+   struct sta_opmode_info sta_opmode = {};
 
/* convert to HT capability */
switch (mgmt->u.action.u.ht_smps.smps_control) {
@@ -2868,17 +2869,24 @@ static void ieee80211_process_sa_query_req(struct 
ieee80211_sub_if_data *sdata,
if (rx->sta->sta.smps_mode == smps_mode)
goto handled;
rx->sta->sta.smps_mode = smps_mode;
+   sta_opmode.smps_mode = smps_mode;
+   sta_opmode.changed = STA_OPMODE_SMPS_MODE_CHANGED;
 
sband = rx->local->hw.wiphy->bands[status->band];
 
rate_control_rate_update(local, sband, rx->sta,
 IEEE80211_RC_SMPS_CHANGED);
+   cfg80211_sta_opmode_change_notify(sdata->dev,
+ rx->sta->addr,
+ _opmode,
+ GFP_KERNEL);
goto handled;
}
case WLAN_HT_ACTION_NOTIFY_CHANWIDTH: {
struct ieee80211_supported_band *sband;
u8 chanwidth = mgmt->u.action.u.ht_notify_cw.chanwidth;
enum ieee80211_sta_rx_bandwidth max_bw, new_bw;
+   struct sta_opmode_info sta_opmode = {};
 
/* If it doesn't support 40 MHz it can't change ... */
if (!(rx->sta->sta.ht_cap.cap &
@@ -2899,9 +2907,15 @@ static void ieee80211_process_sa_query_req(struct 
ieee80211_sub_if_data *sdata,
 
rx->sta->sta.bandwidth = new_bw;
sband = rx->local->hw.wiphy->bands[status->band];
+   sta_opmode.bw = new_bw;
+   sta_opmode.changed = STA_OPMODE_MAX_BW_CHANGED;
 
rate_control_rate_update(local, sband, rx->sta,
 IEEE80211_RC_BW_CHANGED);
+   cfg80211_sta_opmode_change_notify(sdata->dev,
+ rx->sta->addr,
+ _opmode,
+ GFP_KERNEL);
goto handled;
}
default:
diff --git a/net/mac80211/vht.c b/net/mac80211/vht.c
index b9276ac..5714dee 100644
--- a/net/mac80211/vht.c
+++ b/net/mac80211/vht.c
@@ -447,6 +447,7 @@ u32 __ieee80211_vht_handle_opmode(struct 
ieee80211_sub_if_data *sdata,
  enum nl80211_band band)
 {
enum ieee80211_sta_rx_bandwidth new_bw;
+   struct sta_opmode_info sta_opmode = {};
u32 changed = 0;
u8 nss;
 
@@ -460,7 +461,9 @@ u32 __ieee80211_vht_handle_opmode(struct 
ieee80211_sub_if_data *sdata,
 
if (sta->sta.rx_nss != nss) {
sta->sta.rx_nss = nss;
+   sta_opmode.rx_nss = nss;
changed |= IEEE80211_RC_NSS_CHANGED;
+   sta_opmode.changed |= STA_OPMODE_N_SS_CHANGED;
}
 
switch (opmode & IEEE80211_OPMODE_NOTIF_CHANWIDTH_MASK) {
@@ -481,9 +484,15 @@ u32 __ieee80211_vht_handle_opmode(struct 
ieee80211_sub_if_data *sdata,
new_bw = ieee80211_sta_cur_vht_bw(sta);
if (new_bw != sta->sta.bandwidth) {
sta->sta.bandwidth = new_bw;
+   sta_opmode.bw = new_bw;
changed |= IEEE80211_RC_BW_CHANGED;
+   sta_opmode.changed |= STA_OPMODE_MAX_BW_CHANGED;
}
 
+   if (sta_opmode.changed)
+   cfg80211_sta_opmode_change_notify(sdata->dev, sta->addr,
+ _opmode, GFP_KERNEL);
+
return changed;
 }
 
-- 
1.9.1



[PATCHv3 1/2] cfg80211: Add support to notify station's opmode change to userspace

2018-01-31 Thread Tamizh chelvam
ht/vht action frames will be sent to AP from station to notify
change of its ht/vht opmode(max bandwidth, smps mode or nss) modified
values. Currently these valuse used by driver/firmware for rate control
algorithm. This patch introduces NL80211_CMD_STA_OPMODE_CHANGED
command to notify those modified/current supported values(max bandwidth,
smps mode, max nss) to userspace application. This will be useful for the
application like steering, which closely monitoring station's capability
changes. Since the application has taken these values during station
association.

Signed-off-by: Tamizh chelvam 
---
v3:
  * Initialized the sta_opmode_info structure variable before using
v2:
  * Addressed Johannes's comments

 include/net/cfg80211.h   | 43 ++
 include/uapi/linux/nl80211.h | 12 ++
 net/wireless/nl80211.c   | 55 
 3 files changed, 110 insertions(+)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 81174f9..81caf86 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -3517,6 +3517,35 @@ enum wiphy_vendor_command_flags {
 };
 
 /**
+ * enum wiphy_opmode_flag - Station's ht/vht operation mode information flags
+ *
+ * @STA_OPMODE_MAX_BW_CHANGED: Max Bandwidth changed
+ * @STA_OPMODE_SMPS_MODE_CHANGED: SMPS mode changed
+ * @STA_OPMODE_N_SS_CHANGED: max N_SS (number of spatial streams) changed
+ *
+ */
+enum wiphy_opmode_flag {
+   STA_OPMODE_MAX_BW_CHANGED   = BIT(0),
+   STA_OPMODE_SMPS_MODE_CHANGED= BIT(1),
+   STA_OPMODE_N_SS_CHANGED = BIT(2),
+};
+
+/**
+ * struct sta_opmode_info - Station's ht/vht operation mode information
+ * @changed: contains value from  wiphy_opmode_flag
+ * @smps_mode: New SMPS mode of a station
+ * @bw: new max bandwidth value of a station
+ * @rx_nss: new rx_nss value of a station
+ */
+
+struct sta_opmode_info {
+   u32 changed;
+   u8 smps_mode;
+   u8 bw;
+   u8 rx_nss;
+};
+
+/**
  * struct wiphy_vendor_command - vendor command definition
  * @info: vendor command identifying information, as used in nl80211
  * @flags: flags, see  wiphy_vendor_command_flags
@@ -5685,6 +5714,20 @@ void cfg80211_radar_event(struct wiphy *wiphy,
  struct cfg80211_chan_def *chandef, gfp_t gfp);
 
 /**
+ * cfg80211_sta_opmode_change_notify - STA's ht/vht operation mode change event
+ * @dev: network device
+ * @mac: MAC address of a station which opmode got modified
+ * @sta_opmode: station's current opmode value
+ * @gfp: context flags
+ *
+ * Driver should call this function when station's opmode modified via action
+ * frame.
+ */
+void cfg80211_sta_opmode_change_notify(struct net_device *dev, const u8 *mac,
+  struct sta_opmode_info *sta_opmode,
+  gfp_t gfp);
+
+/**
  * cfg80211_cac_event - Channel availability check (CAC) event
  * @netdev: network device
  * @chandef: chandef for the current channel
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index c587a61..b3b449f 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -992,6 +992,11 @@
  *
  * @NL80211_CMD_RELOAD_REGDB: Request that the regdb firmware file is reloaded.
  *
+ * @NL80211_CMD_STA_OPMODE_CHANGED: An event that notify station's
+ * ht opmode or vht opmode changes using any of _ATTR_SMPS_MODE,
+ * _ATTR_CHANNEL_WIDTH,_ATTR_NSS attributes with its
+ * address(specified in _ATTR_MAC).
+ *
  * @NL80211_CMD_MAX: highest used command number
  * @__NL80211_CMD_AFTER_LAST: internal use
  */
@@ -1198,6 +1203,8 @@ enum nl80211_commands {
 
NL80211_CMD_RELOAD_REGDB,
 
+   NL80211_CMD_STA_OPMODE_CHANGED,
+
/* add new commands above here */
 
/* used to define NL80211_CMD_MAX below */
@@ -2153,6 +2160,9 @@ enum nl80211_commands {
  * @NL80211_ATTR_PMKR0_NAME: PMK-R0 Name for offloaded FT.
  * @NL80211_ATTR_PORT_AUTHORIZED: (reserved)
  *
+ * @NL80211_ATTR_NSS: Station's New/updated  RX_NSS value notified using this
+ * u8 attribute. This is used with %NL80211_CMD_STA_OPMODE_CHANGED.
+ *
  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -2579,6 +2589,8 @@ enum nl80211_attrs {
NL80211_ATTR_PMKR0_NAME,
NL80211_ATTR_PORT_AUTHORIZED,
 
+   NL80211_ATTR_NSS,
+
/* add attributes here, update the policy in nl80211.c */
 
__NL80211_ATTR_AFTER_LAST,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index ab0c687..733259f 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -14887,6 +14887,61 @@ void cfg80211_ch_switch_started_notify(struct 
net_device *dev,
nlmsg_free(msg);
 }
 
+void cfg80211_sta_opmode_change_notify(struct net_device *dev, const u8 *mac,
+   

RE: [PATCH v3 2/3] cfg80211/nl80211: Optional authentication offload to userspace

2018-01-31 Thread Srinivas Dasari
On Tue, Jan 30, 2018 at 1:23 PM, Johannes Berg  
wrote:
> On Thu, 2018-01-25 at 17:13 +0200, Jouni Malinen wrote:
>>
>> + if (nla_get_flag(info->attrs[NL80211_ATTR_EXTERNAL_AUTH_SUPPORT]))
>> + connect.flags |= CONNECT_REQ_EXTERNAL_AUTH_SUPPORT;
>
> It seems like here we should check for connection owner, no?
>
> If you say yes, I can edit that in.

I guess you are referring  netlink socket owner. 
Yes , we do agree with you and Thanks a lot for adding this check.

Regards,
Srinivas.