On 9 June 2015 at 03:13, Liu CF/TW <cfliu.tw@xxxxxxxxx> wrote: > This change supports hardware crypto engine bypass by enabling raw > Rx/Tx encap mode. This enables use cases such as software crypto and raw > tx injection. This change introduces a new module param 'cryptmode'. > > cryptmode: > > 0: Use hardware crypto engine globally with native Wi-Fi mode TX/RX > encapsulation to the firmware. This is the default mode. > 1: Use sofware crypto engine globally with raw mode TX/RX encapsulation > to the firmware. > 2: Supports both hardware and software crypto with raw mode TX/RX > encapsulation to the firmware. By default hardware crypto engine is > used. To use software crypto in this mode, set the per ath10k_vif > 'nohwcrypt' flag value to True.* > *) The patch for setting vif specific 'nohwcrypt' flag when > cryptmode=2 would be a separate patch to mac80211. > > Possible use case examples: > > - Use software crypto engine in mac80211. (cryptmode=1) > > - Support inject raw unencrypted frame on monitor interface and use > hardware crypto to encrypt the injected Tx frames. (cryptmode=2) > > - Support receive raw hardware decrypted frame with encryption header > on monitor interface. (cryptmode=2) > > - Support hybrid local & split MAC mode to support tunneling protocols > such as CAPWAP: Use hardware crypto for BSS in local mode, > and bypass hardware crypto for BSS in split MAC mode. > (cryptmode=2, ath10k_vif nohwcrypt=0 for local mode, =1 for split MAC > mode) > > Testing: > > Used QCA988x hw 2.0 with firmware-4.bin_10.2.4.48 with > backports-20150424. > > All test case tested** with hostapd in both WPA2-PSK-TKIP (11g) and > WPA2-PSK-CCMP(11n/ac). Verified ping and http to google.com works. > > **) Need to skip ATH10K_FW_FEATURE_RAW_MODE_SUPPORT check in core.c to > test firmware. After all, none of the existing QCA official firmware > exports that firmware bit yet. > > Test Case cryptmode value tested > --------------------------------------------- ---------------------- > 1. ath10k hardware crypto can encrypt/decrypt 0: PASS > data frames when hostapd config the BSS in 1: Not applicable. > WPA2-PSK-TKIP and WPA2-PSK-CCMP modes. 2: PASS > > 2. mac80211 software crypto can encrypt/decrypt 0: Not applicable > data frames when hostapd config the BSS in 1: PASS > WPA2-PSK-TKIP and WPA2-PSK-CCMP modes. 2: PASS, when vif > nohwcrypt=1 > > 3. Monitor interface Tx: User application can 0: Not applicable > inject unencrypted raw Tx frames to monitor 1: PASS (mac80211) > interface for mac80211 or hardware to encrypt 2: PASS (hardware) > the frames. > > 4. Monitor interface Rx: mac80211 software crypto 0: Not applicable > engine can decrypt received TKIP/CCMP frames. 1: PASS > User application see decrypted frames. 2: PASS, when vif > nohwcrypt=1 > > 5. CAPWAP-like local and split MAC datapath 0: Not applicable > tunneling: Setup BSS1=Local MAC mode on wlan0, 1: Not applicable > BSS2=Split MAC mode on wlan0_monitor interface. 2: PASS > Test BSS1 data frames can be encrypted and > decrypted by ath10k hardware crypto engine > while BSS2 data frames can skip both hardware & > kernel mac80211 crypto engines via monitor > interface to the user application fot tunneling. I've finally got to run a few tests on your patch. I've tried qca988x with 10.2.4.48-2 (fw_feature hardcoded in driver). Here's a short summary of my findings: - cryptmode=1 can fix 4addr+802.1q VLAN tagging in both AP and STA modes (a problem recently reported by Cedric), - your patch as-is has AP WEP broken, see below - your patch as-is has TCP broken, see below - your patch as-is has performance really broken, see below - once patched it looks pretty solid. At the end of this email I'm attaching (most likely whitespace damaged) patch I've made on top of your patch for reviewing convenience. For testing/merging convenience here's a paste link: http://paste.ee/p/YMFrO Performance: cryptmode=1 ap=qca988x sta=killer1525 killer1525 -> qca988x 194.496 mbps [tcp1 ip4] killer1525 -> qca988x 238.309 mbps [tcp5 ip4] killer1525 -> qca988x 266.958 mbps [udp1 ip4] killer1525 -> qca988x 477.468 mbps [udp5 ip4] qca988x -> killer1525 301.378 mbps [tcp1 ip4] qca988x -> killer1525 297.949 mbps [tcp5 ip4] qca988x -> killer1525 331.351 mbps [udp1 ip4] qca988x -> killer1525 371.528 mbps [udp5 ip4] ap=killer1525 sta=qca988x qca988x -> killer1525 331.447 mbps [tcp1 ip4] qca988x -> killer1525 328.783 mbps [tcp5 ip4] qca988x -> killer1525 375.309 mbps [udp1 ip4] qca988x -> killer1525 403.379 mbps [udp5 ip4] killer1525 -> qca988x 203.689 mbps [tcp1 ip4] killer1525 -> qca988x 222.339 mbps [tcp5 ip4] killer1525 -> qca988x 264.199 mbps [udp1 ip4] killer1525 -> qca988x 479.371 mbps [udp5 ip4] vanilla ap=qca988x sta=killer1525 killer1525 -> qca988x 216.882 mbps [tcp1 ip4] killer1525 -> qca988x 265.066 mbps [tcp5 ip4] killer1525 -> qca988x 267.344 mbps [udp1 ip4] killer1525 -> qca988x 481.762 mbps [udp5 ip4] qca988x -> killer1525 209.34 mbps [tcp1 ip4] qca988x -> killer1525 231.009 mbps [tcp5 ip4] qca988x -> killer1525 385.807 mbps [udp1 ip4] qca988x -> killer1525 544.823 mbps [udp5 ip4] ap=killer1525 sta=qca988x qca988x -> killer1525 198.865 mbps [tcp1 ip4] qca988x -> killer1525 232.259 mbps [tcp5 ip4] qca988x -> killer1525 369.771 mbps [udp1 ip4] qca988x -> killer1525 529.127 mbps [udp5 ip4] killer1525 -> qca988x 210.846 mbps [tcp1 ip4] killer1525 -> qca988x 243.255 mbps [tcp5 ip4] killer1525 -> qca988x 261.926 mbps [udp1 ip4] killer1525 -> qca988x 485.102 mbps [udp5 ip4] Note: - only open network tested for RAW vs nwifi performance comparison - killer1525 (qca6174 hw2.2) is 2x2 device (hence max 866mbps) - used iperf - OTA, devices a few cm apart from each other, no shielding - tcpX/udpX, X - means number of threads used Overview: - relative Tx performance drop is seen but is within reasonable and expected threshold (A-MSDU must be disabled with RAW Tx) Connectivity: cryptmode=1 ap=iwl6205 sta1=qca988x crypto=open topology-1ap1sta OK ap=iwl6205 sta1=qca988x crypto=wep1 topology-1ap1sta OK ap=iwl6205 sta1=qca988x crypto=wpa topology-1ap1sta OK ap=iwl6205 sta1=qca988x crypto=wpa-ccmp topology-1ap1sta OK ap=qca988x sta1=iwl6205 crypto=open topology-1ap1sta OK ap=qca988x sta1=iwl6205 crypto=wep1 topology-1ap1sta OK ap=qca988x sta1=iwl6205 crypto=wpa topology-1ap1sta OK ap=qca988x sta1=iwl6205 crypto=wpa-ccmp topology-1ap1sta OK ap=iwl6205 sta1=qca988x crypto=open topology-1ap1sta2br OK ap=iwl6205 sta1=qca988x crypto=wep1 topology-1ap1sta2br OK ap=iwl6205 sta1=qca988x crypto=wpa topology-1ap1sta2br OK ap=iwl6205 sta1=qca988x crypto=wpa-ccmp topology-1ap1sta2br OK ap=qca988x sta1=iwl6205 crypto=open topology-1ap1sta2br OK ap=qca988x sta1=iwl6205 crypto=wep1 topology-1ap1sta2br OK ap=qca988x sta1=iwl6205 crypto=wpa topology-1ap1sta2br OK ap=qca988x sta1=iwl6205 crypto=wpa-ccmp topology-1ap1sta2br OK ap=iwl6205 sta1=qca988x crypto=open topology-1ap1sta2br1vlan OK ap=iwl6205 sta1=qca988x crypto=wep1 topology-1ap1sta2br1vlan OK ap=iwl6205 sta1=qca988x crypto=wpa topology-1ap1sta2br1vlan OK ap=iwl6205 sta1=qca988x crypto=wpa-ccmp topology-1ap1sta2br1vlan OK ap=qca988x sta1=iwl6205 crypto=open topology-1ap1sta2br1vlan OK ap=qca988x sta1=iwl6205 crypto=wep1 topology-1ap1sta2br1vlan OK ap=qca988x sta1=iwl6205 crypto=wpa topology-1ap1sta2br1vlan OK ap=qca988x sta1=iwl6205 crypto=wpa-ccmp topology-1ap1sta2br1vlan OK vanilla ap=iwl6205 sta1=qca988x crypto=open topology-1ap1sta OK ap=iwl6205 sta1=qca988x crypto=wep1 topology-1ap1sta OK ap=iwl6205 sta1=qca988x crypto=wpa topology-1ap1sta OK ap=iwl6205 sta1=qca988x crypto=wpa-ccmp topology-1ap1sta OK ap=qca988x sta1=iwl6205 crypto=open topology-1ap1sta OK ap=qca988x sta1=iwl6205 crypto=wep1 topology-1ap1sta OK ap=qca988x sta1=iwl6205 crypto=wpa topology-1ap1sta OK ap=qca988x sta1=iwl6205 crypto=wpa-ccmp topology-1ap1sta OK ap=iwl6205 sta1=qca988x crypto=open topology-1ap1sta2br OK ap=iwl6205 sta1=qca988x crypto=wep1 topology-1ap1sta2br OK ap=iwl6205 sta1=qca988x crypto=wpa topology-1ap1sta2br OK ap=iwl6205 sta1=qca988x crypto=wpa-ccmp topology-1ap1sta2br OK ap=qca988x sta1=iwl6205 crypto=open topology-1ap1sta2br OK ap=qca988x sta1=iwl6205 crypto=wep1 topology-1ap1sta2br FAIL* ap=qca988x sta1=iwl6205 crypto=wpa topology-1ap1sta2br OK ap=qca988x sta1=iwl6205 crypto=wpa-ccmp topology-1ap1sta2br OK ap=iwl6205 sta1=qca988x crypto=open topology-1ap1sta2br1vlan FAIL** ap=iwl6205 sta1=qca988x crypto=wep1 topology-1ap1sta2br1vlan FAIL** ap=iwl6205 sta1=qca988x crypto=wpa topology-1ap1sta2br1vlan FAIL** ap=iwl6205 sta1=qca988x crypto=wpa-ccmp topology-1ap1sta2br1vlan FAIL** ap=qca988x sta1=iwl6205 crypto=open topology-1ap1sta2br1vlan FAIL** ap=qca988x sta1=iwl6205 crypto=wep1 topology-1ap1sta2br1vlan FAIL** ap=qca988x sta1=iwl6205 crypto=wpa topology-1ap1sta2br1vlan FAIL** ap=qca988x sta1=iwl6205 crypto=wpa-ccmp topology-1ap1sta2br1vlan FAIL** * This is a known problem with AP with WEP and 4addr ** This is another known (recently reported) problem with 802.1q VLAN tagging and 4addr Note: - each test takes all possible endpoint pairs and pings - each pair-ping flushes arp table - ip6 is used Legend: 1ap1sta: [ap] ---- [sta] endpoints: ap, sta 1ap1sta2br: [veth0] [ap] ---- [sta] [veth2] | | | | [veth1] | \ [veth3] \ / \ / [br0] [br1] endpoints: veth0, veth2, br0, br1 note: STA works in 4addr mode, AP has wds_sta=1 1ap1sta2br1vlan: [veth0] [ap] ---- [sta] [veth2] | | | | [veth1] | \ [veth3] \ / \ / [br0] [br1] | | [vlan0_id2] [vlan1_id2] endpoints: vlan0_id2, vlan1_id2 note: STA works in 4addr mode, AP has wds_sta=1 [...] > static const struct ath10k_hw_params ath10k_hw_params_list[] = { > { > @@ -991,6 +994,34 @@ static int ath10k_core_init_firmware_features(struct ath10k *ar) > return -EINVAL; > } > > + ar->wmi.rx_decap_mode = __cpu_to_le32(ATH10K_HW_TXRX_NATIVE_WIFI); This is incorrect. rx_decap_mode is u32, not __le32. No need for the __cpu_to_le32() here. > + switch (ath10k_cryptmode_param) { > + case ATH10K_CRYPT_MODE_HW: > + clear_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags); > + clear_bit(ATH10K_FLAG_HW_CRYPTO_DISABLED, &ar->dev_flags); > + break; > + case ATH10K_CRYPT_MODE_SW: > + case ATH10K_CRYPT_MODE_HW_SW: > + if (!test_bit(ATH10K_FW_FEATURE_RAW_MODE_SUPPORT, > + ar->fw_features)) { > + ath10k_err(ar, "cryptmode > 0 requires raw mode support from firmware"); > + return -EINVAL; > + } > + > + set_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags); > + > + if (ath10k_cryptmode_param == ATH10K_CRYPT_MODE_SW) > + set_bit(ATH10K_FLAG_HW_CRYPTO_DISABLED, &ar->dev_flags); > + break; > + default: > + ath10k_info(ar, "invalid cryptmode: %d\n", > + ath10k_cryptmode_param); > + return -EINVAL; > + } > + > + if (test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) > + ar->wmi.rx_decap_mode = __cpu_to_le32(ATH10K_HW_TXRX_RAW); Ditto. This is u32, not __le32. [...] > @@ -197,12 +198,22 @@ static int ath10k_send_key(struct ath10k_vif *arvif, > return -EOPNOTSUPP; > } > > + if (test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) > + key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; > + > + 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; This causes 2 problems: a) Lots of these: [ 5406.702283] ath10k_pci 0000:00:06.0: failed to install key for vdev 0 peer 10:0b:a9:0d:c9:e0: -95 b) WEP in AP mode fails because: [ 5616.033102] ath10k_pci 0000:00:06.0: failed to install peer wep keys for vdev 0: -95 [ 5616.038512] ath10k_pci 0000:00:06.0: failed to associate station 10:0b:a9:0d:c9:e0 for vdev 0: -95 See my patch how I've dealt with it for now. Michał ---- commit 0fd8c42ad92a83c65450575e348c737917e8210a Author: Michal Kazior <michal.kazior@xxxxxxxxx> Date: Tue Jun 9 09:57:14 2015 +0200 ath10k: fix some RAW Tx encap mode cases A-MSDU must be disabled for RAW Tx encap mode to perform well when heavy traffic is applied. Also key handling was a bit buggy and was: - spamming dmesg with -95 warnings - prevented AP WEP from working As a solution return a 1 when using software crypto early in set_key(), and adjust all install_key() call sites to treat 1 as non-fatal retval. Signed-off-by: Michal Kazior <michal.kazior@xxxxxxxxx> diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index 0d5f157bc177..48b6bfc778b9 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c @@ -1021,9 +1021,24 @@ static int ath10k_core_init_firmware_features(struct ath10k *ar) return -EINVAL; } - if (test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) + ar->htt.max_num_amsdu = ATH10K_HTT_MAX_NUM_AMSDU_DEFAULT; + ar->htt.max_num_ampdu = ATH10K_HTT_MAX_NUM_AMPDU_DEFAULT; + + if (test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) { ar->wmi.rx_decap_mode = ATH10K_HW_TXRX_RAW; + /* Workaround: + * + * Firmware A-MSDU aggregation breaks with RAW Tx encap mode + * and causes enormous performance issues (malformed frames, + * etc). + * + * Disabling A-MSDU makes RAW mode stable with heavy traffic + * albeit a bit slower compared to regular operation. + */ + ar->htt.max_num_amsdu = 1; + } + /* 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 72bd19ee6f76..e473488639a9 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h @@ -393,9 +393,6 @@ struct ath10k_debug { u32 reg_addr; u32 nf_cal_period; - u8 htt_max_amsdu; - u8 htt_max_ampdu; - struct ath10k_fw_crash_data *fw_crash_data; }; diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c index 6ad92845de88..5b263e0dedf5 100644 --- a/drivers/net/wireless/ath/ath10k/debug.c +++ b/drivers/net/wireless/ath/ath10k/debug.c @@ -1358,11 +1358,8 @@ static ssize_t ath10k_read_htt_max_amsdu_ampdu(struct file *file, mutex_lock(&ar->conf_mutex); - if (ar->debug.htt_max_amsdu) - amsdu = ar->debug.htt_max_amsdu; - - if (ar->debug.htt_max_ampdu) - ampdu = ar->debug.htt_max_ampdu; + amsdu = ar->htt.max_num_amsdu; + ampdu = ar->htt.max_num_ampdu; mutex_unlock(&ar->conf_mutex); @@ -1397,8 +1394,8 @@ static ssize_t ath10k_write_htt_max_amsdu_ampdu(struct file *file, goto out; res = count; - ar->debug.htt_max_amsdu = amsdu; - ar->debug.htt_max_ampdu = ampdu; + ar->htt.max_num_amsdu = amsdu; + ar->htt.max_num_ampdu = ampdu; out: mutex_unlock(&ar->conf_mutex); @@ -1900,9 +1897,6 @@ void ath10k_debug_stop(struct ath10k *ar) if (ar->debug.htt_stats_mask != 0) cancel_delayed_work(&ar->debug.htt_stats_dwork); - ar->debug.htt_max_amsdu = 0; - ar->debug.htt_max_ampdu = 0; - ath10k_wmi_pdev_pktlog_disable(ar); } diff --git a/drivers/net/wireless/ath/ath10k/htt.c b/drivers/net/wireless/ath/ath10k/htt.c index 6da6ef26143a..a4e1a1b03413 100644 --- a/drivers/net/wireless/ath/ath10k/htt.c +++ b/drivers/net/wireless/ath/ath10k/htt.c @@ -205,8 +205,27 @@ int ath10k_htt_setup(struct ath10k_htt *htt) } status = ath10k_htt_verify_version(htt); - if (status) + if (status) { + ath10k_warn(ar, "failed to verify htt version: %d\n", + status); return status; + } - return ath10k_htt_send_rx_ring_cfg_ll(htt); + status = ath10k_htt_send_rx_ring_cfg_ll(htt); + if (status) { + ath10k_warn(ar, "failed to setup rx ring: %d\n", + status); + return status; + } + + status = ath10k_htt_h2t_aggr_cfg_msg(htt, + htt->max_num_ampdu, + htt->max_num_amsdu); + if (status) { + ath10k_warn(ar, "failed to setup amsdu/ampdu limit: %d\n", + status); + return status; + } + + return 0; } diff --git a/drivers/net/wireless/ath/ath10k/htt.h b/drivers/net/wireless/ath/ath10k/htt.h index 7e8a0d835663..58ca5337b4d1 100644 --- a/drivers/net/wireless/ath/ath10k/htt.h +++ b/drivers/net/wireless/ath/ath10k/htt.h @@ -1325,6 +1325,8 @@ struct ath10k_htt { u8 target_version_minor; struct completion target_version_received; enum ath10k_fw_htt_op_version op_version; + u8 max_num_amsdu; + u8 max_num_ampdu; const enum htt_t2h_msg_type *t2h_msg_types; u32 t2h_msg_types_max; @@ -1482,6 +1484,12 @@ struct htt_rx_desc { #define HTT_LOG2_MAX_CACHE_LINE_SIZE 7 /* 2^7 = 128 */ #define HTT_MAX_CACHE_LINE_SIZE_MASK ((1 << HTT_LOG2_MAX_CACHE_LINE_SIZE) - 1) +/* These values are default in most firmware revisions and apparently are a + * sweet spot performance wise. + */ +#define ATH10K_HTT_MAX_NUM_AMSDU_DEFAULT 3 +#define ATH10K_HTT_MAX_NUM_AMPDU_DEFAULT 64 + int ath10k_htt_connect(struct ath10k_htt *htt); int ath10k_htt_init(struct ath10k *ar); int ath10k_htt_setup(struct ath10k_htt *htt); diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index 5758e3d413ce..2a6267ee6978 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c @@ -2073,6 +2073,8 @@ void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb) break; case HTT_T2H_MSG_TYPE_CHAN_CHANGE: break; + case HTT_T2H_MSG_TYPE_AGGR_CONF: + break; default: ath10k_warn(ar, "htt event (%d) not handled\n", resp->hdr.msg_type); diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c index 7099e9181881..7c8156092e32 100644 --- a/drivers/net/wireless/ath/ath10k/htt_tx.c +++ b/drivers/net/wireless/ath/ath10k/htt_tx.c @@ -520,7 +520,8 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu) flags1 |= SM((u16)vdev_id, HTT_DATA_TX_DESC_FLAGS1_VDEV_ID); flags1 |= SM((u16)tid, HTT_DATA_TX_DESC_FLAGS1_EXT_TID); - if (msdu->ip_summed == CHECKSUM_PARTIAL) { + if (msdu->ip_summed == CHECKSUM_PARTIAL && + !test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) { flags1 |= HTT_DATA_TX_DESC_FLAGS1_CKSUM_L3_OFFLOAD; flags1 |= HTT_DATA_TX_DESC_FLAGS1_CKSUM_L4_OFFLOAD; } diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index b6685a863e70..ce15f3ccb38d 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -172,7 +172,6 @@ static int ath10k_send_key(struct ath10k_vif *arvif, .key_flags = flags, .macaddr = macaddr, }; - int ret; lockdep_assert_held(&arvif->ar->conf_mutex); @@ -201,19 +200,12 @@ static int ath10k_send_key(struct ath10k_vif *arvif, if (test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; - if (arvif->nohwcrypt) - cmd = DISABLE_KEY; - if (cmd == DISABLE_KEY) { arg.key_cipher = WMI_CIPHER_NONE; arg.key_data = NULL; } - ret = ath10k_wmi_vdev_install_key(arvif->ar, &arg); - - if (arvif->nohwcrypt && !ret) - return -EOPNOTSUPP; - return ret; + return ath10k_wmi_vdev_install_key(arvif->ar, &arg); } static int ath10k_install_key(struct ath10k_vif *arvif, @@ -229,6 +221,9 @@ static int ath10k_install_key(struct ath10k_vif *arvif, reinit_completion(&ar->install_key_done); + if (arvif->nohwcrypt) + return 1; + ret = ath10k_send_key(arvif, key, cmd, macaddr, flags); if (ret) return ret; @@ -267,7 +262,7 @@ static int ath10k_install_peer_wep_keys(struct ath10k_vif *arvif, ret = ath10k_install_key(arvif, arvif->wep_keys[i], SET_KEY, addr, flags); - if (ret) + if (ret < 0) return ret; flags = 0; @@ -275,7 +270,7 @@ static int ath10k_install_peer_wep_keys(struct ath10k_vif *arvif, ret = ath10k_install_key(arvif, arvif->wep_keys[i], SET_KEY, addr, flags); - if (ret) + if (ret < 0) return ret; spin_lock_bh(&ar->data_lock); @@ -333,10 +328,10 @@ static int ath10k_clear_peer_keys(struct ath10k_vif *arvif, /* key flags are not required to delete the key */ ret = ath10k_install_key(arvif, peer->keys[i], DISABLE_KEY, addr, flags); - if (ret && first_errno == 0) + if (ret < 0 && first_errno == 0) first_errno = ret; - if (ret) + if (ret < 0) ath10k_warn(ar, "failed to remove peer wep key %d: %d\n", i, ret); @@ -409,10 +404,10 @@ static int ath10k_clear_vdev_key(struct ath10k_vif *arvif, break; /* key flags are not required to delete the key */ ret = ath10k_install_key(arvif, key, DISABLE_KEY, addr, flags); - if (ret && first_errno == 0) + if (ret < 0 && first_errno == 0) first_errno = ret; - if (ret) + if (ret < 0) ath10k_warn(ar, "failed to remove key for %pM: %d\n", addr, ret); } @@ -4864,6 +4859,9 @@ static int ath10k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, if (key->cipher == WLAN_CIPHER_SUITE_AES_CMAC) return 1; + if (arvif->nohwcrypt) + return 1; + if (key->keyidx > WMI_MAX_KEY_INDEX) return -ENOSPC; @@ -4933,6 +4931,7 @@ static int ath10k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, ret = ath10k_install_key(arvif, key, cmd, peer_addr, flags); if (ret) { + WARN_ON(ret > 0); ath10k_warn(ar, "failed to install key for vdev %i peer %pM: %d\n", arvif->vdev_id, peer_addr, ret); goto exit; @@ -4948,13 +4947,16 @@ static int ath10k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, ret = ath10k_install_key(arvif, key, cmd, peer_addr, flags2); if (ret) { + WARN_ON(ret > 0); ath10k_warn(ar, "failed to install (ucast) key for vdev %i peer %pM: %d\n", arvif->vdev_id, peer_addr, ret); ret2 = ath10k_install_key(arvif, key, DISABLE_KEY, peer_addr, flags); - if (ret2) + if (ret2) { + WARN_ON(ret2 > 0); ath10k_warn(ar, "failed to disable (mcast) key for vdev %i peer %pM: %d\n", arvif->vdev_id, peer_addr, ret2); + } goto exit; } } @@ -7033,7 +7035,8 @@ int ath10k_mac_register(struct ath10k *ar) goto err_free; } - ar->hw->netdev_features = NETIF_F_HW_CSUM; + if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) + ar->hw->netdev_features = NETIF_F_HW_CSUM; if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED)) { /* Init ath dfs pattern detector */ -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html