diff mbox

ath10k/mac80211: add rawtxrx, nohwcrypt module param for raw tx injection, sw crypto support.

Message ID CAG5N3qG7090vB6XoUaQSHvQw7GpE+gXvJAbKrv7def3nV0OFJw@mail.gmail.com (mailing list archive)
State Changes Requested
Headers show

Commit Message

Liu CF/TW May 6, 2015, 1:06 a.m. UTC
- ath10k:   add rawtxrx param for 10.2+ firmware to support sw, hw crypto
             engine and raw Tx injection.
 - mac80211: Add IEEE80211_KEY_FLAG_RESERVE_TAILROOM support for TKIP and
             CCMP required by ath10k and add per BSS(vif) based sw_crypto
             control.

This change enables the raw Tx/Rx feature in ath10k 10.2+ firmware with a
module parameter 'rawtxrx'. With rawtxrx=1, the ath10k hardware crypto
engine could be optionally skipped to support use cases such as enabling
mac80211 sw crypto engine, user level crypto engine, raw Tx frame
injection.

ath10k hw supports hw encryption in both native wifi and raw encap mode.
SW may choose to skip hw crypto engine on per Tx frame or per STA
descriptor basis. This change implements per BSS based sw_crypto control
policy by adding the NL80211_ATTR_SW_CRYPTO attribute to nl80211.

This change also implements the classic 'nohwcrypt' module param in
ath9k/5k to globally disable the hardware engine. When sw crypto or raw
tx injection is used, 'rawtxrx=1' module param is required.

- ath10k_core module parameters:

  rawtxrx:   When set to 1, hw uses raw Tx encap (per frame), and raw Rx
                  decap (global, pdev setting) on datapath.

  nohwcrypt: When set to 1, disables HW crypto engine globally.

- mac80211 change:

  Support IEEE80211_KEY_FLAG_RESERVE_TAILROOM. Required for sw crypto
  to work for ath10k.

  Introduce NL80211_ATTR_SW_CRYPTO attribute as a per BSS parameter to
  selectively choose sw or hw crypto engine when BSS is created.

Testing: used QCA988x hw 2.0 with 10.2 firmware.

ath10k    ath10k     nl80211
rawtxrx   nohwcrypt  SW_CRYPTO
param     param      attribute    Testing Status
-------   ---------  ---------    ---------------------------------
   0          0           -         HW CCMP/TKIP tested ok.
   0          1           -         Not supported by ath10k hw.
   1          0           -         HW CCMP/TKIP tested ok.
   1          0           0         BSS 1 tested HW CCMP/TKIP ok.
   1          0           1         BSS 2 can bypass HW engine.
                                    - mac80211 SW crypto tested ok.
                                    - raw Tx frame injection tested ok.
   1          1           -         HW crypto globally disabled.
                                    - mac80211 SW crypto tested ok.
                                    - raw Tx frame injection tested ok.

Signed-off-by: David Liu <cfliu.tw@gmail.com>
---
 drivers/net/wireless/ath/ath10k/core.c   | 12 +++++++
 drivers/net/wireless/ath/ath10k/core.h   |  5 +++
 drivers/net/wireless/ath/ath10k/htt_rx.c |  3 +-
 drivers/net/wireless/ath/ath10k/htt_tx.c |  3 ++
 drivers/net/wireless/ath/ath10k/hw.h     |  2 +-
 drivers/net/wireless/ath/ath10k/mac.c    | 56 +++++++++++++++++++++++++++++---
 drivers/net/wireless/ath/ath10k/wmi.c    |  6 ++--
 include/net/cfg80211.h                   |  4 +++
 include/net/mac80211.h                   |  3 ++
 include/uapi/linux/nl80211.h             |  5 +++
 net/mac80211/cfg.c                       |  7 ++++
 net/mac80211/wpa.c                       | 24 +++++++++++---
 net/wireless/nl80211.c                   |  5 +++
 net/wireless/trace.h                     |  7 ++--
 14 files changed, 125 insertions(+), 17 deletions(-)

Comments

Kalle Valo May 8, 2015, 11:54 a.m. UTC | #1
Hi David,

"Liu CF/TW" <cfliu.tw@gmail.com> writes:

>  - ath10k:   add rawtxrx param for 10.2+ firmware to support sw, hw crypto
>              engine and raw Tx injection.
>  - mac80211: Add IEEE80211_KEY_FLAG_RESERVE_TAILROOM support for TKIP and
>              CCMP required by ath10k and add per BSS(vif) based sw_crypto
>              control.

This patch has few major problems. First of all, ath10k and mac80211
changes should be in separate patches. Secondly the patch is whitespace
damaged, I recommend using git-send-email to avoid that.

And there's just too much feature changes in one patch, it's usually
better to split the features into separate patches. For example, you
could first add a simple raw mode support to ath10k (ie. the bare
minimum needed to get the feature) and then adding more advanced
features per patch.

> This change enables the raw Tx/Rx feature in ath10k 10.2+ firmware with a
> module parameter 'rawtxrx'. With rawtxrx=1, the ath10k hardware crypto
> engine could be optionally skipped to support use cases such as enabling
> mac80211 sw crypto engine, user level crypto engine, raw Tx frame
> injection.

Lots of people, especially in Qualcomm, seem to call this feature as
"raw mode". Would it be more descriptive to name the module paramer as
'rawmode'?

> Testing: used QCA988x hw 2.0 with 10.2 firmware.
>
> ath10k    ath10k     nl80211
> rawtxrx   nohwcrypt  SW_CRYPTO
> param     param      attribute    Testing Status
> -------   ---------  ---------    ---------------------------------
>    0          0           -         HW CCMP/TKIP tested ok.
>    0          1           -         Not supported by ath10k hw.
>    1          0           -         HW CCMP/TKIP tested ok.
>    1          0           0         BSS 1 tested HW CCMP/TKIP ok.
>    1          0           1         BSS 2 can bypass HW engine.
>                                     - mac80211 SW crypto tested ok.
>                                     - raw Tx frame injection tested ok.
>    1          1           -         HW crypto globally disabled.
>                                     - mac80211 SW crypto tested ok.
>                                     - raw Tx frame injection tested ok.

I wonder does it make any sense to have nohwcrypt parameter? Especially
if ath10k doesn't support case rawtxrx=0 and nohwcrypt=1. One
possibility I came up is to have multiple values for rawtxrx, for
example is rawtxrx=1 means HW crypt enabled and rawtxrx=2 HW crypt
disabled. Ideas welcome.

> --- a/drivers/net/wireless/ath/ath10k/core.c
> +++ b/drivers/net/wireless/ath/ath10k/core.c
> @@ -31,16 +31,22 @@
>  #include "wmi-ops.h"
>
>  unsigned int ath10k_debug_mask;
> +bool ath10k_modparam_nohwcrypt;
> +bool ath10k_modparam_rawtxrx;

Instead of making these public I would prefer to set a flag in struct
ath10k, for example dev_flags.

> ath10k_core_init_firmware_features(struct ath10k *ar)
>   return -EINVAL;
>   }
>
> + if ((ath10k_modparam_rawtxrx || ath10k_modparam_nohwcrypt) &&
> +    !test_bit(ATH10K_FW_FEATURE_WMI_10_2, ar->fw_features)) {
> + ath10k_err(ar, "rawtxrx mode supported only in 10.2+ firmware");
> + return -EINVAL;
> + }

I think we should add a flag to enum ath10k_fw_features and check for
that.

> diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
> index 241220c..cdfa8a8 100644
> --- a/include/uapi/linux/nl80211.h
> +++ b/include/uapi/linux/nl80211.h
> @@ -1761,6 +1761,9 @@ enum nl80211_commands {
>   * @NL80211_ATTR_REG_INDOOR: flag attribute, if set indicates that the device
>   *      is operating in an indoor environment.
>   *
> + * @NL80211_ATTR_SW_CRYPTO: use software crypto instead of hardware crypto for
> + * the BSS.
> + *
>   * @NUM_NL80211_ATTR: total number of nl80211_attrs available
>   * @NL80211_ATTR_MAX: highest attribute number currently defined
>   * @__NL80211_ATTR_AFTER_LAST: internal use
> @@ -2130,6 +2133,8 @@ enum nl80211_attrs {
>
>   NL80211_ATTR_REG_INDOOR,
>
> + NL80211_ATTR_SW_CRYPTO,

Like I said above, nl80211/cfg80211/mac80211 changes need to be in
separate patches. And I suspect that the changes of getting this
accepted is low. Maybe a debugfs is a better choise?
Ben Greear May 8, 2015, 4:28 p.m. UTC | #2
On 05/08/2015 04:54 AM, Kalle Valo wrote:
> Hi David,
> 
> "Liu CF/TW" <cfliu.tw@gmail.com> writes:
> 
>>  - ath10k:   add rawtxrx param for 10.2+ firmware to support sw, hw crypto
>>              engine and raw Tx injection.
>>  - mac80211: Add IEEE80211_KEY_FLAG_RESERVE_TAILROOM support for TKIP and
>>              CCMP required by ath10k and add per BSS(vif) based sw_crypto
>>              control.
> 
> This patch has few major problems. First of all, ath10k and mac80211
> changes should be in separate patches. Secondly the patch is whitespace
> damaged, I recommend using git-send-email to avoid that.
> 
> And there's just too much feature changes in one patch, it's usually
> better to split the features into separate patches. For example, you
> could first add a simple raw mode support to ath10k (ie. the bare
> minimum needed to get the feature) and then adding more advanced
> features per patch.
> 
>> This change enables the raw Tx/Rx feature in ath10k 10.2+ firmware with a
>> module parameter 'rawtxrx'. With rawtxrx=1, the ath10k hardware crypto
>> engine could be optionally skipped to support use cases such as enabling
>> mac80211 sw crypto engine, user level crypto engine, raw Tx frame
>> injection.
> 
> Lots of people, especially in Qualcomm, seem to call this feature as
> "raw mode". Would it be more descriptive to name the module paramer as
> 'rawmode'?
> 
>> Testing: used QCA988x hw 2.0 with 10.2 firmware.
>>
>> ath10k    ath10k     nl80211
>> rawtxrx   nohwcrypt  SW_CRYPTO
>> param     param      attribute    Testing Status
>> -------   ---------  ---------    ---------------------------------
>>    0          0           -         HW CCMP/TKIP tested ok.
>>    0          1           -         Not supported by ath10k hw.
>>    1          0           -         HW CCMP/TKIP tested ok.
>>    1          0           0         BSS 1 tested HW CCMP/TKIP ok.
>>    1          0           1         BSS 2 can bypass HW engine.
>>                                     - mac80211 SW crypto tested ok.
>>                                     - raw Tx frame injection tested ok.
>>    1          1           -         HW crypto globally disabled.
>>                                     - mac80211 SW crypto tested ok.
>>                                     - raw Tx frame injection tested ok.
> 
> I wonder does it make any sense to have nohwcrypt parameter? Especially
> if ath10k doesn't support case rawtxrx=0 and nohwcrypt=1. One
> possibility I came up is to have multiple values for rawtxrx, for
> example is rawtxrx=1 means HW crypt enabled and rawtxrx=2 HW crypt
> disabled. Ideas welcome.


In my CT firmware, I end up using native tx and raw rx to enable rx-sw-crypt.

(I could not figure out how to do raw-tx with encrypted frames, though since
 10.2 FW can do it, I guess it must be possible...)

Maybe we could have a way to specify both rx and rx mode independently of
each other to support that use case as well?

Maybe:


txmode=x;  // 0 == native, 1 == raw (and maybe support other tx modes in the future as desired)
rxmode=x;  // 0 == native, 1 == raw
nohwcrypt=x; // 0 == standard hw crypt, 0x1 == rx-sw-crypt, 0x2 == tx-sw-crypt, 0x3 == tx/rx-sw-crypt

If any limits are placed, please do use feature flags instead of firmware version comparisons
..that way I might can support at least some of this in CT firmware.

Thanks,
Ben
Liu CF/TW May 8, 2015, 5:35 p.m. UTC | #3
Hi Kalle/Ben,

Comments inlined.

On Fri, May 8, 2015 at 9:28 AM, Ben Greear <greearb@candelatech.com> wrote:
> On 05/08/2015 04:54 AM, Kalle Valo wrote:
>> Hi David,
>>
>> "Liu CF/TW" <cfliu.tw@gmail.com> writes:
>>
>>>  - ath10k:   add rawtxrx param for 10.2+ firmware to support sw, hw crypto
>>>              engine and raw Tx injection.
>>>  - mac80211: Add IEEE80211_KEY_FLAG_RESERVE_TAILROOM support for TKIP and
>>>              CCMP required by ath10k and add per BSS(vif) based sw_crypto
>>>              control.
>>
>> This patch has few major problems. First of all, ath10k and mac80211
>> changes should be in separate patches. Secondly the patch is whitespace
>> damaged, I recommend using git-send-email to avoid that.

Thanks. Would split the patch into multiple changes.

>>
>> And there's just too much feature changes in one patch, it's usually
>> better to split the features into separate patches. For example, you
>> could first add a simple raw mode support to ath10k (ie. the bare
>> minimum needed to get the feature) and then adding more advanced
>> features per patch.
>>
>>> This change enables the raw Tx/Rx feature in ath10k 10.2+ firmware with a
>>> module parameter 'rawtxrx'. With rawtxrx=1, the ath10k hardware crypto
>>> engine could be optionally skipped to support use cases such as enabling
>>> mac80211 sw crypto engine, user level crypto engine, raw Tx frame
>>> injection.
>>
>> Lots of people, especially in Qualcomm, seem to call this feature as
>> "raw mode". Would it be more descriptive to name the module paramer as
>> 'rawmode'?

Sounds good. Will use rawmode instead.

>>
>>> Testing: used QCA988x hw 2.0 with 10.2 firmware.
>>>
>>> ath10k    ath10k     nl80211
>>> rawtxrx   nohwcrypt  SW_CRYPTO
>>> param     param      attribute    Testing Status
>>> -------   ---------  ---------    ---------------------------------
>>>    0          0           -         HW CCMP/TKIP tested ok.
>>>    0          1           -         Not supported by ath10k hw.
>>>    1          0           -         HW CCMP/TKIP tested ok.
>>>    1          0           0         BSS 1 tested HW CCMP/TKIP ok.
>>>    1          0           1         BSS 2 can bypass HW engine.
>>>                                     - mac80211 SW crypto tested ok.
>>>                                     - raw Tx frame injection tested ok.
>>>    1          1           -         HW crypto globally disabled.
>>>                                     - mac80211 SW crypto tested ok.
>>>                                     - raw Tx frame injection tested ok.
>>
>> I wonder does it make any sense to have nohwcrypt parameter? Especially
>> if ath10k doesn't support case rawtxrx=0 and nohwcrypt=1. One
>> possibility I came up is to have multiple values for rawtxrx, for
>> example is rawtxrx=1 means HW crypt enabled and rawtxrx=2 HW crypt
>> disabled. Ideas welcome.
>
>

Indeed. I picked nohwcrypt because it seems to be the convention in
previous Atheros drivers for this feature.
In this case, I will drop nohwcrypt and do as you suggested.

rawmode = 0: Raw mode disabled. Use the default native WiFi mode. In
this mode, only HW crypto is supported.
rawmode = 1: Use Raw rx decap + raw tx encap mode. Supports both SW
and HW crypto.
rawmode = 2: Same as 1, but with HW crypto engine globally disabled.

When rawmode = 1, I want a further per BSS control to make some BSS
use HW crypto and some BSS bypass HW crypto.
For those BSS that have HW crypto bypassed, their data frames may come
from either the normal wlan interfaces (therefore mac80211 sw crypto
used), or from monitor interfaces (therefore Tx injected frames
already encrypted + Rx frames still encrypted)


> In my CT firmware, I end up using native tx and raw rx to enable rx-sw-crypt.
>
> (I could not figure out how to do raw-tx with encrypted frames, though since
>  10.2 FW can do it, I guess it must be possible...)
>
> Maybe we could have a way to specify both rx and rx mode independently of
> each other to support that use case as well?
>
> Maybe:
>
>
> txmode=x;  // 0 == native, 1 == raw (and maybe support other tx modes in the future as desired)
> rxmode=x;  // 0 == native, 1 == raw
> nohwcrypt=x; // 0 == standard hw crypt, 0x1 == rx-sw-crypt, 0x2 == tx-sw-crypt, 0x3 == tx/rx-sw-crypt
>
> If any limits are placed, please do use feature flags instead of firmware version comparisons
> ..that way I might can support at least some of this in CT firmware.
>
> Thanks,
> Ben
>


I'd assume it's more desirable to have sw crypto supported using the
same encapsulation mode for both rx/tx, right? Did you see use cases
that only rx-sw-crypt or only tx-sw-crypt is needed? I prefer Kalle's
suggestion to use only 1 flag instead of 3.

FYI, in my case, I got Tx & Rx working in raw mode for both SW & HW crypto.
- With FW 10.2, for (injected) encrypted Tx frames from monitor
interface, there isn't much SW needs to do. Mianly set
ATH10K_HW_TXRX_RAW + HTT_DATA_TX_DESC_FLAGS0_NO_ENCRYPT on the HTT Tx
descriptor is sufficient.
I found setting raw Tx encap mode on VDEV actually isn't really
necessary. Per frame control anyway is finer grained control than per
VDEV.

Thanks,
David
>
> --
> Ben Greear <greearb@candelatech.com>
> Candela Technologies Inc  http://www.candelatech.com
>
Ben Greear May 8, 2015, 5:52 p.m. UTC | #4
On 05/08/2015 10:35 AM, Liu CF/TW wrote:

>> In my CT firmware, I end up using native tx and raw rx to enable rx-sw-crypt.
>>
>> (I could not figure out how to do raw-tx with encrypted frames, though since
>>  10.2 FW can do it, I guess it must be possible...)
>>
>> Maybe we could have a way to specify both rx and rx mode independently of
>> each other to support that use case as well?
>>
>> Maybe:
>>
>>
>> txmode=x;  // 0 == native, 1 == raw (and maybe support other tx modes in the future as desired)
>> rxmode=x;  // 0 == native, 1 == raw
>> nohwcrypt=x; // 0 == standard hw crypt, 0x1 == rx-sw-crypt, 0x2 == tx-sw-crypt, 0x3 == tx/rx-sw-crypt
>>
>> If any limits are placed, please do use feature flags instead of firmware version comparisons
>> ..that way I might can support at least some of this in CT firmware.
>>
>> Thanks,
>> Ben
>>
> 
> 
> I'd assume it's more desirable to have sw crypto supported using the
> same encapsulation mode for both rx/tx, right? Did you see use cases
> that only rx-sw-crypt or only tx-sw-crypt is needed? I prefer Kalle's
> suggestion to use only 1 flag instead of 3.

My own need for sw-crypt is to work around firmware/hardware limitations
that will not allow two station vdevs to be connected to same AP using
encryption (because peer is same for both vdevs, and the key hash collides).

In this case, I can still use hardware tx encryption, I just need to
disable the rx-decryption.  I do this by passing a flag to my
firmware to purposefully mis-configure the rx-decrypt logic so that it
can never find the peer entry when receiving frames.  I also enable raw
rx mode, which lets these un-decrypted frames be received as raw frames.

I still use native tx mode.

The nice thing about this is that I still get CPU offload for tx encryption.

I am glad you have found a way to make 10.2 do full sw-tx-crypt as well,
but at least in my case, that may not be something I want to use for
most scenarios.


> FYI, in my case, I got Tx & Rx working in raw mode for both SW & HW crypto.
> - With FW 10.2, for (injected) encrypted Tx frames from monitor
> interface, there isn't much SW needs to do. Mianly set
> ATH10K_HW_TXRX_RAW + HTT_DATA_TX_DESC_FLAGS0_NO_ENCRYPT on the HTT Tx
> descriptor is sufficient.
> I found setting raw Tx encap mode on VDEV actually isn't really
> necessary. Per frame control anyway is finer grained control than per
> VDEV.

I think there must be fixes in the 10.2 firmware that are not in stock 10.1
and not in my modified 10.1 that allows this to work.  I was never able to get
my 10.1 based firmware to do a raw tx of an already-encrypted frame.  Stock
10.1 firmware has the same limitation as far as I know.

Thanks,
Ben
Kalle Valo May 11, 2015, 12:12 p.m. UTC | #5
"Liu CF/TW" <cfliu.tw@gmail.com> writes:

>>> I wonder does it make any sense to have nohwcrypt parameter? Especially
>>> if ath10k doesn't support case rawtxrx=0 and nohwcrypt=1. One
>>> possibility I came up is to have multiple values for rawtxrx, for
>>> example is rawtxrx=1 means HW crypt enabled and rawtxrx=2 HW crypt
>>> disabled. Ideas welcome.
>
> Indeed. I picked nohwcrypt because it seems to be the convention in
> previous Atheros drivers for this feature.

Yeah, but I don't think we need to follow that in ath10k. Especially not
until we get SW encryption working in all cases.

> In this case, I will drop nohwcrypt and do as you suggested.
>
> rawmode = 0: Raw mode disabled. Use the default native WiFi mode. In
> this mode, only HW crypto is supported.
> rawmode = 1: Use Raw rx decap + raw tx encap mode. Supports both SW
> and HW crypto.
> rawmode = 2: Same as 1, but with HW crypto engine globally disabled.

I would guess that HW crypto globally disabled (value 2 above) will be
more popular, right? So would it make sense to reverse the values and
use value 1 for that?

> When rawmode = 1, I want a further per BSS control to make some BSS
> use HW crypto and some BSS bypass HW crypto.
> For those BSS that have HW crypto bypassed, their data frames may come
> from either the normal wlan interfaces (therefore mac80211 sw crypto
> used), or from monitor interfaces (therefore Tx injected frames
> already encrypted + Rx frames still encrypted)

Ok, we need to think how to configure this. Maybe a debugfs interface?
Kalle Valo May 11, 2015, 12:24 p.m. UTC | #6
Ben Greear <greearb@candelatech.com> writes:

> Maybe we could have a way to specify both rx and rx mode independently of
> each other to support that use case as well?
>
> Maybe:
>
> txmode=x;  // 0 == native, 1 == raw (and maybe support other tx modes in the future as desired)
> rxmode=x;  // 0 == native, 1 == raw
> nohwcrypt=x; // 0 == standard hw crypt, 0x1 == rx-sw-crypt, 0x2 == tx-sw-crypt, 0x3 == tx/rx-sw-crypt

This looks overly complicated and hard to maintain for a very special
use case, not really excited about this.
Ben Greear May 11, 2015, 4:17 p.m. UTC | #7
On 05/11/2015 05:12 AM, Kalle Valo wrote:
> "Liu CF/TW" <cfliu.tw@gmail.com> writes:
> 
>>>> I wonder does it make any sense to have nohwcrypt parameter? Especially
>>>> if ath10k doesn't support case rawtxrx=0 and nohwcrypt=1. One
>>>> possibility I came up is to have multiple values for rawtxrx, for
>>>> example is rawtxrx=1 means HW crypt enabled and rawtxrx=2 HW crypt
>>>> disabled. Ideas welcome.
>>
>> Indeed. I picked nohwcrypt because it seems to be the convention in
>> previous Atheros drivers for this feature.
> 
> Yeah, but I don't think we need to follow that in ath10k. Especially not
> until we get SW encryption working in all cases.

What do you mean 'all cases'?  Many upstream firmware builds will just
crash if you try raw tx, regardless of any encryption options.


>> In this case, I will drop nohwcrypt and do as you suggested.
>>
>> rawmode = 0: Raw mode disabled. Use the default native WiFi mode. In
>> this mode, only HW crypto is supported.
>> rawmode = 1: Use Raw rx decap + raw tx encap mode. Supports both SW
>> and HW crypto.
>> rawmode = 2: Same as 1, but with HW crypto engine globally disabled.
> 
> I would guess that HW crypto globally disabled (value 2 above) will be
> more popular, right? So would it make sense to reverse the values and
> use value 1 for that?

You are combining multiple different (but related) things into a single
enum.  Maybe make it a bitfield instead so that new combinations can be
added later w/out making such a mess in the code?


>> When rawmode = 1, I want a further per BSS control to make some BSS
>> use HW crypto and some BSS bypass HW crypto.
>> For those BSS that have HW crypto bypassed, their data frames may come
>> from either the normal wlan interfaces (therefore mac80211 sw crypto
>> used), or from monitor interfaces (therefore Tx injected frames
>> already encrypted + Rx frames still encrypted)
> 
> Ok, we need to think how to configure this. Maybe a debugfs interface?

I'm curious the order of operations...seems like you will have to create
and start using the BSS before you get access to it in debugfs?  Or are you
going to create a table of mac-addresses or something like that?

Thanks,
Ben
Liu CF/TW May 12, 2015, 10:44 p.m. UTC | #8
I am going to propose just one single module parameter control: enc_mode

- enc_mode = 0: Use HW crypto (default),

  Driver behavior:
     - ath10k driver uses native WiFi mode for both Tx/Rx.
     - ath10k driver configures key to HW.
     Given HW key descriptor is configured, mac80211 would offload Tx
encryption to HW and only do Rx decryption (by mac80211) if HW failed
to do it.

  Use case:
      - The only mode current driver supports to date.
      - The CT firmware special use case should fall into this
category where firmware overrides the ath10k driver setting to force
Rx fallback to SW decryption (in mac80211).
         (From Ben's description, I believe CT FW overrides the global
Rx decap mode=raw mode  + mangle the HW Rx descriptor to skip HW
decryption)

- enc_mode = 1: Use SW crypto.

  Driver behavior:
     - ath10k driver uses raw encap mode for both Tx/Rx
     - ath10k driver doesn't configure actual key to HW but program
CLEAR key context to bypass HW.
     This is the classic nohwcrypt=1 mode. Only SW crypto is enabled globally.
  Use case:
     - NEW: Full SW crypto on both Tx/Rx.
     - NEW: raw injected Tx frame. If encryption required, would use
mac80211 SW crypto.

- enc_mode = 2: Supports both HW and SW crypto simultaneously.

  Driver behavior:
     - ath10k driver uses raw encap mode for both Tx/Rx
     - ath10k driver configures key to HW only if the per BSS config
enables it (either via debugfs or nl80211 attribute, TBD)
       If HW key is configured, use HW crypto. Otherwise, use SW crypto.

  Use case:
    - NEW: raw injected Tx frame. If encryption is required, could
support both SW or HW crypto (by the per BSS config)
    - NEW: some BSS could use HW crypto with no performance hit while
some BSS could bypass HW crypto (ex: CAPWAP like split-MAC encrypted
frames)

Ben, in this case, as long as enc_mode == 0, your FW should continue
to work. I will add a new FW feature TX_RAW_ENCAP_SUPPORTED, and fail
at module load time if enc_mode !=0 and FW doesn't support it. Would
this address your concerns?

David.


On Mon, May 11, 2015 at 9:17 AM, Ben Greear <greearb@candelatech.com> wrote:
> On 05/11/2015 05:12 AM, Kalle Valo wrote:
>> "Liu CF/TW" <cfliu.tw@gmail.com> writes:
>>
>>>>> I wonder does it make any sense to have nohwcrypt parameter? Especially
>>>>> if ath10k doesn't support case rawtxrx=0 and nohwcrypt=1. One
>>>>> possibility I came up is to have multiple values for rawtxrx, for
>>>>> example is rawtxrx=1 means HW crypt enabled and rawtxrx=2 HW crypt
>>>>> disabled. Ideas welcome.
>>>
>>> Indeed. I picked nohwcrypt because it seems to be the convention in
>>> previous Atheros drivers for this feature.
>>
>> Yeah, but I don't think we need to follow that in ath10k. Especially not
>> until we get SW encryption working in all cases.
>
> What do you mean 'all cases'?  Many upstream firmware builds will just
> crash if you try raw tx, regardless of any encryption options.
>
>
>>> In this case, I will drop nohwcrypt and do as you suggested.
>>>
>>> rawmode = 0: Raw mode disabled. Use the default native WiFi mode. In
>>> this mode, only HW crypto is supported.
>>> rawmode = 1: Use Raw rx decap + raw tx encap mode. Supports both SW
>>> and HW crypto.
>>> rawmode = 2: Same as 1, but with HW crypto engine globally disabled.
>>
>> I would guess that HW crypto globally disabled (value 2 above) will be
>> more popular, right? So would it make sense to reverse the values and
>> use value 1 for that?
>
> You are combining multiple different (but related) things into a single
> enum.  Maybe make it a bitfield instead so that new combinations can be
> added later w/out making such a mess in the code?
>
>
>>> When rawmode = 1, I want a further per BSS control to make some BSS
>>> use HW crypto and some BSS bypass HW crypto.
>>> For those BSS that have HW crypto bypassed, their data frames may come
>>> from either the normal wlan interfaces (therefore mac80211 sw crypto
>>> used), or from monitor interfaces (therefore Tx injected frames
>>> already encrypted + Rx frames still encrypted)
>>
>> Ok, we need to think how to configure this. Maybe a debugfs interface?
>
> I'm curious the order of operations...seems like you will have to create
> and start using the BSS before you get access to it in debugfs?  Or are you
> going to create a table of mac-addresses or something like that?
>
> Thanks,
> Ben
>
>
> --
> Ben Greear <greearb@candelatech.com>
> Candela Technologies Inc  http://www.candelatech.com
>
Liu CF/TW May 12, 2015, 11:01 p.m. UTC | #9
On Tue, May 12, 2015 at 3:44 PM, Liu CF/TW <cfliu.tw@gmail.com> wrote:
> I am going to propose just one single module parameter control: enc_mode
>
> - enc_mode = 0: Use HW crypto (default),
>
>   Driver behavior:
>      - ath10k driver uses native WiFi mode for both Tx/Rx.
>      - ath10k driver configures key to HW.
>      Given HW key descriptor is configured, mac80211 would offload Tx
> encryption to HW and only do Rx decryption (by mac80211) if HW failed
> to do it.
>

Recap. Should be: "Given HW key descriptor is configured, Tx
encryption and Rx decryption would be both done by HW."

Note: Due to HW limitation, SW crypto can't be done in native WiFi mode.
Transmit already encrypted frames requires raw mode.
Bypass encrypted frame for SW for decryption in native Wifi mode is
possible, but requires reinserting QoS header on per frame basis which
is tedious.

>   Use case:
>       - The only mode current driver supports to date.
>       - The CT firmware special use case should fall into this
> category where firmware overrides the ath10k driver setting to force
> Rx fallback to SW decryption (in mac80211).
>          (From Ben's description, I believe CT FW overrides the global
> Rx decap mode=raw mode  + mangle the HW Rx descriptor to skip HW
> decryption)
>
> - enc_mode = 1: Use SW crypto.
>
>   Driver behavior:
>      - ath10k driver uses raw encap mode for both Tx/Rx
>      - ath10k driver doesn't configure actual key to HW but program
> CLEAR key context to bypass HW.
>      This is the classic nohwcrypt=1 mode. Only SW crypto is enabled globally.
>   Use case:
>      - NEW: Full SW crypto on both Tx/Rx.
>      - NEW: raw injected Tx frame. If encryption required, would use
> mac80211 SW crypto.
>
> - enc_mode = 2: Supports both HW and SW crypto simultaneously.
>
>   Driver behavior:
>      - ath10k driver uses raw encap mode for both Tx/Rx
>      - ath10k driver configures key to HW only if the per BSS config
> enables it (either via debugfs or nl80211 attribute, TBD)
>        If HW key is configured, use HW crypto. Otherwise, use SW crypto.
>
>   Use case:
>     - NEW: raw injected Tx frame. If encryption is required, could
> support both SW or HW crypto (by the per BSS config)
>     - NEW: some BSS could use HW crypto with no performance hit while
> some BSS could bypass HW crypto (ex: CAPWAP like split-MAC encrypted
> frames)
>
> Ben, in this case, as long as enc_mode == 0, your FW should continue
> to work. I will add a new FW feature TX_RAW_ENCAP_SUPPORTED, and fail
> at module load time if enc_mode !=0 and FW doesn't support it. Would
> this address your concerns?
>
> David.
>
>
Kalle Valo May 14, 2015, 3:12 p.m. UTC | #10
"Liu CF/TW" <cfliu.tw@gmail.com> writes:

> I am going to propose just one single module parameter control: enc_mode
>
> - enc_mode = 0: Use HW crypto (default),
>
>   Driver behavior:
>      - ath10k driver uses native WiFi mode for both Tx/Rx.
>      - ath10k driver configures key to HW.
>      Given HW key descriptor is configured, mac80211 would offload Tx
> encryption to HW and only do Rx decryption (by mac80211) if HW failed
> to do it.

But isn't the point here to use 802.11 frames ("raw mode")? Then why
name the module paramater as enc_mode? I think that's confusing.

And to me enc_mode doesn't tell much, my first thought was "encoding
mode". Wouldn't cryptmode tell more to the user?
Liu CF/TW May 14, 2015, 7:35 p.m. UTC | #11
On Thu, May 14, 2015 at 8:12 AM, Kalle Valo <kvalo@qca.qualcomm.com> wrote:
> "Liu CF/TW" <cfliu.tw@gmail.com> writes:
>
>> I am going to propose just one single module parameter control: enc_mode
>>
>> - enc_mode = 0: Use HW crypto (default),
>>
>>   Driver behavior:
>>      - ath10k driver uses native WiFi mode for both Tx/Rx.
>>      - ath10k driver configures key to HW.
>>      Given HW key descriptor is configured, mac80211 would offload Tx
>> encryption to HW and only do Rx decryption (by mac80211) if HW failed
>> to do it.
>
> But isn't the point here to use 802.11 frames ("raw mode")? Then why
> name the module paramater as enc_mode? I think that's confusing.
>
> And to me enc_mode doesn't tell much, my first thought was "encoding
> mode". Wouldn't cryptmode tell more to the user?
>
>

Thanks for the suggestion. Yes, crypt_mode is better. I didn't mean
"enc({ap, oding})_mode" but "enc(ryption)_mode"

IMO, the new use cases enabled by the change are sw crypto support and
raw Tx frame injection (to bypass hw crypto if already encrypted).
Therefore I suggest use "crypt_mode" as module param so it's clear one
only needs to set it if sw crypto is desired.

"raw_mode" itself as a module param doesn't mean much to user, it
doesn't say what new use cases are supported. After all, both native
wifi and raw mode supports HW crypto.

In Ben's use case, driver that loads CT firmware can continue to run
without setting anything (default crypt_mode=0 means use HW crypto)
and FW continues its magic to enable Rx SW crypto fallback.  At some
point when CT firmware implements the FW feature
TX_RAW_ENCAP_SUPPORTED, all the crypt_modes=0,1,2 also works there.

Does this make sense?
David

> --
> Kalle Valo
Ben Greear May 14, 2015, 9:16 p.m. UTC | #12
On 05/14/2015 12:35 PM, Liu CF/TW wrote:
> On Thu, May 14, 2015 at 8:12 AM, Kalle Valo <kvalo@qca.qualcomm.com> wrote:
>> "Liu CF/TW" <cfliu.tw@gmail.com> writes:
>>
>>> I am going to propose just one single module parameter control: enc_mode
>>>
>>> - enc_mode = 0: Use HW crypto (default),
>>>
>>>    Driver behavior:
>>>       - ath10k driver uses native WiFi mode for both Tx/Rx.
>>>       - ath10k driver configures key to HW.
>>>       Given HW key descriptor is configured, mac80211 would offload Tx
>>> encryption to HW and only do Rx decryption (by mac80211) if HW failed
>>> to do it.
>>
>> But isn't the point here to use 802.11 frames ("raw mode")? Then why
>> name the module paramater as enc_mode? I think that's confusing.
>>
>> And to me enc_mode doesn't tell much, my first thought was "encoding
>> mode". Wouldn't cryptmode tell more to the user?
>>
>>
>
> Thanks for the suggestion. Yes, crypt_mode is better. I didn't mean
> "enc({ap, oding})_mode" but "enc(ryption)_mode"
>
> IMO, the new use cases enabled by the change are sw crypto support and
> raw Tx frame injection (to bypass hw crypto if already encrypted).
> Therefore I suggest use "crypt_mode" as module param so it's clear one
> only needs to set it if sw crypto is desired.
>
> "raw_mode" itself as a module param doesn't mean much to user, it
> doesn't say what new use cases are supported. After all, both native
> wifi and raw mode supports HW crypto.
>
> In Ben's use case, driver that loads CT firmware can continue to run
> without setting anything (default crypt_mode=0 means use HW crypto)
> and FW continues its magic to enable Rx SW crypto fallback.  At some
> point when CT firmware implements the FW feature
> TX_RAW_ENCAP_SUPPORTED, all the crypt_modes=0,1,2 also works there.

This fine for me.  I'll just keep using my patch that enables nohwcrypt
module option to enable my own rx-sw-crypt feature.  If I ever
get raw-tx working for encrypted packets I'll set that flag in
my firmware as you suggest.

Thanks,
Ben
diff mbox

Patch

diff --git a/drivers/net/wireless/ath/ath10k/core.c
b/drivers/net/wireless/ath/ath10k/core.c
index bcccae1..d31597d 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -31,16 +31,22 @@ 
 #include "wmi-ops.h"

 unsigned int ath10k_debug_mask;
+bool ath10k_modparam_nohwcrypt;
+bool ath10k_modparam_rawtxrx;
 static bool uart_print;
 static bool skip_otp;

 module_param_named(debug_mask, ath10k_debug_mask, uint, 0644);
+module_param_named(nohwcrypt, ath10k_modparam_nohwcrypt, bool, 0644);
+module_param_named(rawtxrx, ath10k_modparam_rawtxrx, bool, 0644);
 module_param(uart_print, bool, 0644);
 module_param(skip_otp, bool, 0644);

 MODULE_PARM_DESC(debug_mask, "Debugging mask");
 MODULE_PARM_DESC(uart_print, "Uart target debugging");
 MODULE_PARM_DESC(skip_otp, "Skip otp failure for calibration in testmode");
+MODULE_PARM_DESC(nohwcrypt, "Disable hw crypto globally");
+MODULE_PARM_DESC(rxwtxrx, "Use raw encap/decap mode");

 static const struct ath10k_hw_params ath10k_hw_params_list[] = {
  {
@@ -990,6 +996,12 @@  static int
ath10k_core_init_firmware_features(struct ath10k *ar)
  return -EINVAL;
  }

+ if ((ath10k_modparam_rawtxrx || ath10k_modparam_nohwcrypt) &&
+    !test_bit(ATH10K_FW_FEATURE_WMI_10_2, ar->fw_features)) {
+ ath10k_err(ar, "rawtxrx mode supported only in 10.2+ firmware");
+ return -EINVAL;
+ }
+
  /* Backwards compatibility for firmwares without
  * ATH10K_FW_IE_WMI_OP_VERSION.
  */
diff --git a/drivers/net/wireless/ath/ath10k/core.h
b/drivers/net/wireless/ath/ath10k/core.h
index 827b3d7..1e7a5ca 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -66,6 +66,9 @@ 

 struct ath10k;

+extern bool ath10k_modparam_nohwcrypt;
+extern bool ath10k_modparam_rawtxrx;
+
 enum ath10k_bus {
  ATH10K_BUS_PCI,
 };
@@ -91,6 +94,7 @@  struct ath10k_skb_cb {
  u8 tid;
  u16 freq;
  bool is_offchan;
+ bool nohwcrypt;
  struct ath10k_htt_txbuf *txbuf;
  u32 txbuf_paddr;
  } __packed htt;
@@ -349,6 +353,7 @@  struct ath10k_vif {
  } u;

  bool use_cts_prot;
+ bool nohwcrypt;
  int num_legacy_stations;
  int txpower;
  struct wmi_wmm_params_all_arg wmm_params;
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c
b/drivers/net/wireless/ath/ath10k/htt_rx.c
index b26e32f..29ec1ec 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -1012,8 +1012,7 @@  static void ath10k_htt_rx_h_undecap_raw(struct ath10k *ar,

  /* In most cases this will be true for sniffed frames. It makes sense
  * to deliver them as-is without stripping the crypto param. This would
- * also make sense for software based decryption (which is not
- * implemented in ath10k).
+ * also make sense for software based decryption.
  *
  * If there's no error then the frame is decrypted. At least that is
  * the case for frames that come in via fragmented rx indication.
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c
b/drivers/net/wireless/ath/ath10k/htt_tx.c
index a60ef7d..18446d9 100644
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
@@ -508,6 +508,9 @@  int ath10k_htt_tx(struct ath10k_htt *htt, struct
sk_buff *msdu)
  prefetch_len);
  skb_cb->htt.txbuf->htc_hdr.flags = 0;

+ if (skb_cb->htt.nohwcrypt)
+ flags0 |= HTT_DATA_TX_DESC_FLAGS0_NO_ENCRYPT;
+
  if (!skb_cb->is_protected)
  flags0 |= HTT_DATA_TX_DESC_FLAGS0_NO_ENCRYPT;

diff --git a/drivers/net/wireless/ath/ath10k/hw.h
b/drivers/net/wireless/ath/ath10k/hw.h
index 89e09cb..3d3bb9e 100644
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -293,7 +293,7 @@  enum ath10k_hw_rate_cck {
 #define TARGET_10X_RX_SKIP_DEFRAG_TIMEOUT_DUP_DETECTION_CHECK 1
 #define TARGET_10X_VOW_CONFIG 0
 #define TARGET_10X_NUM_MSDU_DESC (1024 + 400)
-#define TARGET_10X_MAX_FRAG_ENTRIES 0
+#define TARGET_10X_MAX_FRAG_ENTRIES 10

 /* 10.2 parameters */
 #define TARGET_10_2_DMA_BURST_SIZE 1
diff --git a/drivers/net/wireless/ath/ath10k/mac.c
b/drivers/net/wireless/ath/ath10k/mac.c
index 425dbe2..8f34e79 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -172,6 +172,7 @@  static int ath10k_send_key(struct ath10k_vif *arvif,
  .key_flags = flags,
  .macaddr = macaddr,
  };
+ int ret;

  lockdep_assert_held(&arvif->ar->conf_mutex);

@@ -184,6 +185,9 @@  static int ath10k_send_key(struct ath10k_vif *arvif,
  arg.key_cipher = WMI_CIPHER_TKIP;
  arg.key_txmic_len = 8;
  arg.key_rxmic_len = 8;
+ if (ath10k_modparam_rawtxrx)
+ key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
+
  break;
  case WLAN_CIPHER_SUITE_WEP40:
  case WLAN_CIPHER_SUITE_WEP104:
@@ -197,12 +201,24 @@  static int ath10k_send_key(struct ath10k_vif *arvif,
  return -EOPNOTSUPP;
  }

+ if (ath10k_modparam_rawtxrx) {
+ key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
+ key->flags |= IEEE80211_KEY_FLAG_RESERVE_TAILROOM;
+ }
+
+ if (arvif->nohwcrypt)
+ cmd = DISABLE_KEY;
+
  if (cmd == DISABLE_KEY) {
  arg.key_cipher = WMI_CIPHER_NONE;
  arg.key_data = NULL;
  }

- return ath10k_wmi_vdev_install_key(arvif->ar, &arg);
+ ret = ath10k_wmi_vdev_install_key(arvif->ar, &arg);
+
+ if (arvif->nohwcrypt && !ret)
+ return -EOPNOTSUPP;
+ return ret;
 }

 static int ath10k_install_key(struct ath10k_vif *arvif,
@@ -3192,9 +3208,24 @@  ath10k_tx_h_get_txmode(struct ath10k *ar,
struct ieee80211_vif *vif,
  if (ieee80211_is_data_present(fc) && sta && sta->tdls)
  return ATH10K_HW_TXRX_ETHERNET;

+ if (ath10k_modparam_rawtxrx)
+ return ATH10K_HW_TXRX_RAW;
+
  return ATH10K_HW_TXRX_NATIVE_WIFI;
 }

+static bool ath10k_tx_h_use_hwcrypto(struct ieee80211_vif *vif,
+     struct sk_buff *skb) {
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ const u32 mask = IEEE80211_TX_INTFL_DONT_ENCRYPT |
+ IEEE80211_TX_CTL_INJECTED;
+ if ((info->flags & mask) == mask)
+ return false;
+ if (vif)
+ return !ath10k_vif_to_arvif(vif)->nohwcrypt;
+ return true;
+}
+
 /* HTT Tx uses Native Wifi tx mode which expects 802.11 frames without QoS
  * Control in the header.
  */
@@ -3640,6 +3671,7 @@  static void ath10k_tx(struct ieee80211_hw *hw,
  ATH10K_SKB_CB(skb)->htt.is_offchan = false;
  ATH10K_SKB_CB(skb)->htt.freq = 0;
  ATH10K_SKB_CB(skb)->htt.tid = ath10k_tx_h_get_tid(hdr);
+ ATH10K_SKB_CB(skb)->htt.nohwcrypt = !ath10k_tx_h_use_hwcrypto(vif, skb);
  ATH10K_SKB_CB(skb)->vdev_id = ath10k_tx_h_get_vdev_id(ar, vif);
  ATH10K_SKB_CB(skb)->txmode = ath10k_tx_h_get_txmode(ar, vif, sta, skb);
  ATH10K_SKB_CB(skb)->is_protected = ieee80211_has_protected(fc);
@@ -3655,9 +3687,8 @@  static void ath10k_tx(struct ieee80211_hw *hw,
  ath10k_tx_h_8023(skb);
  break;
  case ATH10K_HW_TXRX_RAW:
- /* FIXME: Packet injection isn't implemented. It should be
- * doable with firmware 10.2 on qca988x.
- */
+ if (ath10k_modparam_rawtxrx)
+ break;
  WARN_ON_ONCE(1);
  ieee80211_free_txskb(hw, skb);
  return;
@@ -4154,6 +4185,7 @@  static int ath10k_add_interface(struct ieee80211_hw *hw,
  int bit;
  int i;
  u32 vdev_param;
+ u32 param_value;

  vif->driver_flags |= IEEE80211_VIF_SUPPORTS_UAPSD;

@@ -4257,6 +4289,14 @@  static int ath10k_add_interface(struct ieee80211_hw *hw,
  }
  }

+ if (ath10k_modparam_nohwcrypt || vif->sw_crypto)
+ arvif->nohwcrypt = true;
+
+ if (arvif->nohwcrypt && !ath10k_modparam_rawtxrx) {
+ ath10k_warn(ar, "rawtxrx module param needed for sw crypto\n");
+ goto err;
+ }
+
  ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev create %d (add interface)
type %d subtype %d bcnmode %s\n",
    arvif->vdev_id, arvif->vdev_type, arvif->vdev_subtype,
    arvif->beacon_buf ? "single-buf" : "per-skb");
@@ -4285,8 +4325,14 @@  static int ath10k_add_interface(struct ieee80211_hw *hw,
  arvif->def_wep_key_idx = -1;

  vdev_param = ar->wmi.vdev_param->tx_encap_type;
+ if (ath10k_modparam_rawtxrx)
+ param_value = ATH10K_HW_TXRX_RAW;
+ else
+ param_value = ATH10K_HW_TXRX_NATIVE_WIFI;
+
  ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
- ATH10K_HW_TXRX_NATIVE_WIFI);
+ param_value);
+
  /* 10.X firmware does not support this VDEV parameter. Do not warn */
  if (ret && ret != -EOPNOTSUPP) {
  ath10k_warn(ar, "failed to set vdev %i TX encapsulation: %d\n",
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c
b/drivers/net/wireless/ath/ath10k/wmi.c
index ebaa096..d7e557b 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -507,7 +507,7 @@  static struct wmi_vdev_param_map wmi_10x_vdev_param_map = {
  .txbf = WMI_VDEV_PARAM_UNSUPPORTED,
  .packet_powersave = WMI_VDEV_PARAM_UNSUPPORTED,
  .drop_unencry = WMI_VDEV_PARAM_UNSUPPORTED,
- .tx_encap_type = WMI_VDEV_PARAM_UNSUPPORTED,
+ .tx_encap_type = WMI_10X_VDEV_PARAM_TX_ENCAP_TYPE,
  .ap_detect_out_of_sync_sleeping_sta_time_secs =
  WMI_10X_VDEV_PARAM_AP_DETECT_OUT_OF_SYNC_SLEEPING_STA_TIME_SECS,
 };
@@ -3891,7 +3891,9 @@  static struct sk_buff
*ath10k_wmi_10_2_op_gen_init(struct ath10k *ar)
  config.rx_timeout_pri_vi = __cpu_to_le32(TARGET_10X_RX_TIMEOUT_LO_PRI);
  config.rx_timeout_pri_be = __cpu_to_le32(TARGET_10X_RX_TIMEOUT_LO_PRI);
  config.rx_timeout_pri_bk = __cpu_to_le32(TARGET_10X_RX_TIMEOUT_HI_PRI);
- config.rx_decap_mode = __cpu_to_le32(TARGET_10X_RX_DECAP_MODE);
+ config.rx_decap_mode = __cpu_to_le32(ATH10K_HW_TXRX_NATIVE_WIFI);
+ if (ath10k_modparam_rawtxrx)
+ config.rx_decap_mode = __cpu_to_le32(ATH10K_HW_TXRX_RAW);

  config.scan_max_pending_reqs =
  __cpu_to_le32(TARGET_10X_SCAN_MAX_PENDING_REQS);
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index f8d6813..b41c71c 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -711,6 +711,7 @@  struct cfg80211_acl_data {
  * @p2p_opp_ps: P2P opportunistic PS
  * @acl: ACL configuration used by the drivers which has support for
  * MAC address based access control
+ * @sw_crypto: use software crypto engine.*
  */
 struct cfg80211_ap_settings {
  struct cfg80211_chan_def chandef;
@@ -729,6 +730,7 @@  struct cfg80211_ap_settings {
  u8 p2p_ctwindow;
  bool p2p_opp_ps;
  const struct cfg80211_acl_data *acl;
+ int sw_crypto;
 };

 /**
@@ -1210,6 +1212,7 @@  struct mpath_info {
  * @ap_isolate: do not forward packets between connected stations
  * @ht_opmode: HT Operation mode
  * (u16 = opmode, -1 = do not change)
+ * @sw_crypto: Use software crypto instead of hardware.
  * @p2p_ctwindow: P2P CT Window (-1 = no change)
  * @p2p_opp_ps: P2P opportunistic PS (-1 = no change)
  */
@@ -1221,6 +1224,7 @@  struct bss_parameters {
  u8 basic_rates_len;
  int ap_isolate;
  int ht_opmode;
+ int sw_crypto;
  s8 p2p_ctwindow, p2p_opp_ps;
 };

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 3314298..5f45d02 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -1344,6 +1344,8 @@  enum ieee80211_vif_flags {
  * @csa_active: marks whether a channel switch is going on. Internally it is
  * write-protected by sdata_lock and local->mtx so holding either is fine
  * for read access.
+ * @sw_crypto: indicates frames on the BSS should be encrypted by software
+ * and bypass hardware crypto engine.
  * @driver_flags: flags/capabilities the driver has for this interface,
  * these need to be set (or cleared) when the interface is added
  * or, if supported by the driver, the interface type is changed
@@ -1368,6 +1370,7 @@  struct ieee80211_vif {
  u8 addr[ETH_ALEN];
  bool p2p;
  bool csa_active;
+ bool sw_crypto;

  u8 cab_queue;
  u8 hw_queue[IEEE80211_NUM_ACS];
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 241220c..cdfa8a8 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -1761,6 +1761,9 @@  enum nl80211_commands {
  * @NL80211_ATTR_REG_INDOOR: flag attribute, if set indicates that the device
  *      is operating in an indoor environment.
  *
+ * @NL80211_ATTR_SW_CRYPTO: use software crypto instead of hardware crypto for
+ * the BSS.
+ *
  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -2130,6 +2133,8 @@  enum nl80211_attrs {

  NL80211_ATTR_REG_INDOOR,

+ NL80211_ATTR_SW_CRYPTO,
+
  /* add attributes here, update the policy in nl80211.c */

  __NL80211_ATTR_AFTER_LAST,
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 72a0178..a50c9226 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1889,6 +1889,13 @@  static int ieee80211_change_bss(struct wiphy *wiphy,
  sdata->flags &= ~IEEE80211_SDATA_DONT_BRIDGE_PACKETS;
  }

+ if (params->sw_crypto >= 0) {
+ if (params->sw_crypto)
+ sdata->vif.sw_crypto = true;
+ else
+ sdata->vif.sw_crypto = false;
+ }
+
  if (params->ht_opmode >= 0) {
  sdata->vif.bss_conf.ht_operation_mode =
  (u16) params->ht_opmode;
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index 9d63d93..b56f31a 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -192,7 +192,9 @@  static int tkip_encrypt_skb(struct
ieee80211_tx_data *tx, struct sk_buff *skb)

  if (info->control.hw_key &&
     !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV) &&
-    !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)) {
+    !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE) &&
+    !(info->control.hw_key->flags &
+      IEEE80211_KEY_FLAG_RESERVE_TAILROOM)) {
  /* hwaccel - with no need for software-generated IV */
  return 0;
  }
@@ -200,7 +202,8 @@  static int tkip_encrypt_skb(struct
ieee80211_tx_data *tx, struct sk_buff *skb)
  hdrlen = ieee80211_hdrlen(hdr->frame_control);
  len = skb->len - hdrlen;

- if (info->control.hw_key)
+ if (info->control.hw_key && !(info->control.hw_key->flags &
+      IEEE80211_KEY_FLAG_RESERVE_TAILROOM))
  tail = 0;
  else
  tail = IEEE80211_TKIP_ICV_LEN;
@@ -227,8 +230,12 @@  static int tkip_encrypt_skb(struct
ieee80211_tx_data *tx, struct sk_buff *skb)
  spin_unlock(&key->u.tkip.txlock);

  /* hwaccel - with software IV */
- if (info->control.hw_key)
+ if (info->control.hw_key) {
+ if (info->control.hw_key->flags &
+    IEEE80211_KEY_FLAG_RESERVE_TAILROOM)
+ skb_put(skb, tail);
  return 0;
+ }

  /* Add room for ICV */
  skb_put(skb, IEEE80211_TKIP_ICV_LEN);
@@ -411,6 +418,8 @@  static int ccmp_encrypt_skb(struct
ieee80211_tx_data *tx, struct sk_buff *skb,
  if (info->control.hw_key &&
     !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV) &&
     !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE) &&
+    !(info->control.hw_key->flags &
+       IEEE80211_KEY_FLAG_RESERVE_TAILROOM) &&
     !((info->control.hw_key->flags &
        IEEE80211_KEY_FLAG_GENERATE_IV_MGMT) &&
       ieee80211_is_mgmt(hdr->frame_control))) {
@@ -424,7 +433,8 @@  static int ccmp_encrypt_skb(struct
ieee80211_tx_data *tx, struct sk_buff *skb,
  hdrlen = ieee80211_hdrlen(hdr->frame_control);
  len = skb->len - hdrlen;

- if (info->control.hw_key)
+ if (info->control.hw_key && !(info->control.hw_key->flags &
+      IEEE80211_KEY_FLAG_RESERVE_TAILROOM))
  tail = 0;
  else
  tail = mic_len;
@@ -456,8 +466,12 @@  static int ccmp_encrypt_skb(struct
ieee80211_tx_data *tx, struct sk_buff *skb,
  ccmp_pn2hdr(pos, pn, key->conf.keyidx);

  /* hwaccel - with software CCMP header */
- if (info->control.hw_key)
+ if (info->control.hw_key) {
+ if (info->control.hw_key->flags &
+    IEEE80211_KEY_FLAG_RESERVE_TAILROOM)
+ skb_put(skb, tail);
  return 0;
+ }

  pos += IEEE80211_CCMP_HDR_LEN;
  ccmp_special_blocks(skb, pn, b_0, aad);
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 8a33bba..c2dea0e 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -4851,6 +4851,7 @@  static int nl80211_set_bss(struct sk_buff *skb,
struct genl_info *info)
  params.use_short_preamble = -1;
  params.use_short_slot_time = -1;
  params.ap_isolate = -1;
+ params.sw_crypto = -1;
  params.ht_opmode = -1;
  params.p2p_ctwindow = -1;
  params.p2p_opp_ps = -1;
@@ -4901,6 +4902,10 @@  static int nl80211_set_bss(struct sk_buff *skb,
struct genl_info *info)
     !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_OPPPS))
  return -EINVAL;
  }
+ if (info->attrs[NL80211_ATTR_SW_CRYPTO]) {
+ params.sw_crypto =
+    !!nla_get_u8(info->attrs[NL80211_ATTR_SW_CRYPTO]);
+ }

  if (!rdev->ops->change_bss)
  return -EOPNOTSUPP;
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index af3617c..c411a20 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -986,6 +986,7 @@  TRACE_EVENT(rdev_change_bss,
  __field(int, use_short_preamble)
  __field(int, use_short_slot_time)
  __field(int, ap_isolate)
+ __field(int, sw_crypto)
  __field(int, ht_opmode)
  ),
  TP_fast_assign(
@@ -995,14 +996,16 @@  TRACE_EVENT(rdev_change_bss,
  __entry->use_short_preamble = params->use_short_preamble;
  __entry->use_short_slot_time = params->use_short_slot_time;
  __entry->ap_isolate = params->ap_isolate;
+ __entry->sw_crypto = params->sw_crypto;
  __entry->ht_opmode = params->ht_opmode;
  ),
  TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", use cts prot: %d, "
   "use short preamble: %d, use short slot time: %d, "
-  "ap isolate: %d, ht opmode: %d",
+  "ap isolate: %d, sw_crypto: %d, ht opmode: %d",
   WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->use_cts_prot,
   __entry->use_short_preamble, __entry->use_short_slot_time,
-  __entry->ap_isolate, __entry->ht_opmode)
+  __entry->ap_isolate, __entry->sw_crypto,
+  __entry->ht_opmode)
 );

 TRACE_EVENT(rdev_set_txq_params,