wlan-ap-Telecominfraproject/feeds/wifi-ax/mac80211/patches/qca/015-add-raw-mode-support.patch
John Crispin 528a778e38 open-converged-wireless: Import 21.02 based uCentral tree
Signed-off-by: John Crispin <john@phrozen.org>
2021-03-25 12:19:47 +01:00

325 lines
11 KiB
Diff

From ac4ddc177cf0cfbb52678c7b5959a4985074e289 Mon Sep 17 00:00:00 2001
From: Manikanta Pubbisetty <mpubbise@codeaurora.org>
Date: Wed, 29 May 2019 21:09:28 +0530
Subject: [PATCH] ath11k: add raw mode support
Adding raw mode tx/rx support; also, adding support for
software crypto which depends on raw mode.
To enable raw mode tx/rx:
insmod ath11k.ko rawmode=1
To enable software crypto:
insmod ath11k.ko cryptmode=1
Signed-off-by: Manikanta Pubbisetty <mpubbise@codeaurora.org>
---
drivers/net/wireless/ath/ath11k/core.c | 23 ++++++++++++++++++++++
drivers/net/wireless/ath/ath11k/core.h | 7 +++++++
drivers/net/wireless/ath/ath11k/dp_rx.c | 9 +++++----
drivers/net/wireless/ath/ath11k/dp_tx.c | 34 +++++++++++++++++++++------------
drivers/net/wireless/ath/ath11k/mac.c | 20 +++++++++++++++++--
drivers/net/wireless/ath/ath11k/wmi.c | 4 ++++
6 files changed, 79 insertions(+), 18 deletions(-)
--- a/drivers/net/wireless/ath/ath11k/core.c
+++ b/drivers/net/wireless/ath/ath11k/core.c
@@ -14,9 +14,15 @@
#include "hif.h"
unsigned int ath11k_debug_mask;
+unsigned int rawmode;
+unsigned int cryptmode;
EXPORT_SYMBOL(ath11k_debug_mask);
module_param_named(debug_mask, ath11k_debug_mask, uint, 0644);
+module_param_named(rawmode, rawmode, uint, 0644);
+module_param_named(cryptmode, cryptmode, uint, 0644);
MODULE_PARM_DESC(debug_mask, "Debugging mask");
+MODULE_PARM_DESC(cryptmode, "crypto mode: 0-hardware, 1-software");
+MODULE_PARM_DESC(rawmode, "RAW mode TX: 0-disable, 1-enable");
static const struct ath11k_hw_params ath11k_hw_params[] = {
{
@@ -580,6 +586,23 @@ int ath11k_core_qmi_firmware_ready(struc
return ret;
}
+ switch (cryptmode) {
+ case ATH11K_CRYPT_MODE_SW:
+ set_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ab->dev_flags);
+ set_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags);
+ break;
+ case ATH11K_CRYPT_MODE_HW:
+ clear_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ab->dev_flags);
+ clear_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags);
+ break;
+ default:
+ ath11k_info(ab, "invalid cryptmode: %d\n", cryptmode);
+ return -EINVAL;
+ }
+
+ if (rawmode)
+ set_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags);
+
mutex_lock(&ab->core_lock);
ret = ath11k_core_start(ab, ATH11K_FIRMWARE_MODE_NORMAL);
if (ret) {
--- a/drivers/net/wireless/ath/ath11k/core.h
+++ b/drivers/net/wireless/ath/ath11k/core.h
@@ -55,6 +55,13 @@ enum wme_ac {
#define ATH11K_VHT_MCS_MAX 9
#define ATH11K_HE_MCS_MAX 11
+enum ath11k_crypt_mode {
+ /* Only use hardware crypto engine */
+ ATH11K_CRYPT_MODE_HW,
+ /* Only use software crypto */
+ ATH11K_CRYPT_MODE_SW,
+};
+
static inline enum wme_ac ath11k_tid_to_ac(u32 tid)
{
return (((tid == 0) || (tid == 3)) ? WME_AC_BE :
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
@@ -2136,8 +2136,6 @@ static void ath11k_dp_rx_h_mpdu(struct a
mcast = is_multicast_ether_addr(hdr->addr1);
fill_crypto_hdr = mcast;
- is_decrypted = ath11k_dp_rx_h_attn_is_decrypted(rx_desc);
-
spin_lock_bh(&ar->ab->base_lock);
peer = ath11k_peer_find_by_addr(ar->ab, hdr->addr2);
if (peer) {
@@ -2152,6 +2150,10 @@ static void ath11k_dp_rx_h_mpdu(struct a
err_bitmap = ath11k_dp_rx_h_attn_mpdu_err(rx_desc);
+ enctype = ath11k_dp_rx_h_mpdu_start_enctype(rx_desc);
+ if (enctype != HAL_ENCRYPT_TYPE_OPEN && !err_bitmap)
+ is_decrypted = ath11k_dp_rx_h_attn_is_decrypted(rx_desc);
+
/* Clear per-MPDU flags while leaving per-PPDU flags intact */
rx_status->flag &= ~(RX_FLAG_FAILED_FCS_CRC |
RX_FLAG_MMIC_ERROR |
@@ -2353,6 +2355,8 @@ static void ath11k_dp_rx_deliver_msdu(st
!!(status->flag & RX_FLAG_MMIC_ERROR),
!!(status->flag & RX_FLAG_AMSDU_MORE));
+ ath11k_dbg_dump(ar->ab, ATH11K_DBG_DP_RX, NULL, "dp rx msdu: ",
+ msdu->data, msdu->len);
/* TODO: trace rx packet */
ieee80211_rx_napi(ar->hw, NULL, msdu, napi);
--- a/drivers/net/wireless/ath/ath11k/dp_tx.c
+++ b/drivers/net/wireless/ath/ath11k/dp_tx.c
@@ -13,6 +13,10 @@ static enum hal_tcl_encap_type
ath11k_dp_tx_get_encap_type(struct ath11k_vif *arvif, struct sk_buff *skb)
{
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+ struct ath11k_base *ab = arvif->ar->ab;
+
+ if (test_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags))
+ return HAL_TCL_ENCAP_TYPE_RAW;
if (tx_info->control.flags & IEEE80211_TX_CTRL_HW_80211_ENCAP)
return HAL_TCL_ENCAP_TYPE_ETHERNET;
@@ -142,11 +146,17 @@ tcl_ring_sel:
ti.encap_type = ath11k_dp_tx_get_encap_type(arvif, skb);
ti.meta_data_flags = arvif->tcl_metadata;
- if (info->control.hw_key)
- ti.encrypt_type =
- ath11k_dp_tx_get_encrypt_type(info->control.hw_key->cipher);
- else
- ti.encrypt_type = HAL_ENCRYPT_TYPE_OPEN;
+ if (ti.encap_type == HAL_TCL_ENCAP_TYPE_RAW) {
+ if (info->control.hw_key) {
+ ti.encrypt_type =
+ ath11k_dp_tx_get_encrypt_type(info->control.hw_key->cipher);
+
+ if (ieee80211_has_protected(hdr->frame_control))
+ skb_put(skb, IEEE80211_CCMP_MIC_LEN);
+ } else {
+ ti.encrypt_type = HAL_ENCRYPT_TYPE_OPEN;
+ }
+ }
ti.addr_search_flags = arvif->hal_addr_search_flags;
ti.search_type = arvif->search_type;
@@ -156,7 +166,8 @@ tcl_ring_sel:
ti.bss_ast_hash = arvif->ast_hash;
ti.dscp_tid_tbl_idx = 0;
- if (skb->ip_summed == CHECKSUM_PARTIAL) {
+ if (skb->ip_summed == CHECKSUM_PARTIAL &&
+ ti.encap_type != HAL_TCL_ENCAP_TYPE_RAW) {
ti.flags0 |= FIELD_PREP(HAL_TCL_DATA_CMD_INFO1_IP4_CKSUM_EN, 1) |
FIELD_PREP(HAL_TCL_DATA_CMD_INFO1_UDP4_CKSUM_EN, 1) |
FIELD_PREP(HAL_TCL_DATA_CMD_INFO1_UDP6_CKSUM_EN, 1) |
@@ -176,10 +187,11 @@ tcl_ring_sel:
ath11k_dp_tx_encap_nwifi(skb);
break;
case HAL_TCL_ENCAP_TYPE_RAW:
- /* TODO: for CHECKSUM_PARTIAL case in raw mode, HW checksum offload
- * is not applicable, hence manual checksum calculation using
- * skb_checksum_help() is needed
- */
+ if (!test_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags)) {
+ ret = -EINVAL;
+ goto fail_remove_idr;
+ }
+ break;
case HAL_TCL_ENCAP_TYPE_ETHERNET:
/* no need to encap */
break;
@@ -235,6 +247,9 @@ tcl_ring_sel:
goto fail_unmap_dma;
}
+ ath11k_dbg_dump(ab, ATH11K_DBG_DP_TX, NULL, "dp tx msdu: ",
+ skb->data, skb->len);
+
ath11k_hal_tx_cmd_desc_setup(ab, hal_tcl_desc +
sizeof(struct hal_tlv_hdr), &ti);
@@ -352,7 +367,6 @@ ath11k_dp_tx_process_htt_tx_complete(str
wbm_status = FIELD_GET(HTT_TX_WBM_COMP_INFO0_STATUS,
status_desc->info0);
-
switch (wbm_status) {
case HAL_WBM_REL_HTT_TX_COMP_STATUS_OK:
case HAL_WBM_REL_HTT_TX_COMP_STATUS_DROP:
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -2380,6 +2380,9 @@ static int ath11k_install_key(struct ath
reinit_completion(&ar->install_key_done);
+ if (test_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags))
+ return 0;
+
if (cmd == DISABLE_KEY) {
/* TODO: Check if FW expects value other than NONE for del */
/* arg.key_cipher = WMI_CIPHER_NONE; */
@@ -2411,8 +2414,12 @@ static int ath11k_install_key(struct ath
return -EOPNOTSUPP;
}
+ if (test_bit(ATH11K_FLAG_RAW_MODE, &ar->ab->dev_flags))
+ key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
+
install:
ret = ath11k_wmi_vdev_install_key(arvif->ar, &arg);
+
if (ret)
return ret;
@@ -2484,6 +2491,9 @@ static int ath11k_mac_op_set_key(struct
key->cipher == WLAN_CIPHER_SUITE_BIP_CMAC_256)
return 1;
+ if (test_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags))
+ return 1;
+
if (key->keyidx > WMI_MAX_KEY_INDEX)
return -ENOSPC;
@@ -4442,6 +4452,9 @@ static int ath11k_mac_op_add_interface(s
else
param_value = ATH11K_HW_TXRX_NATIVE_WIFI;
+ if (test_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags))
+ param_value = ATH11K_HW_TXRX_RAW;
+
ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,
param_id, param_value);
if (ret) {
@@ -6179,8 +6192,10 @@ static int __ath11k_mac_register(struct
ath11k_reg_init(ar);
- /* advertise HW checksum offload capabilities */
- ar->hw->netdev_features = NETIF_F_HW_CSUM;
+ if (!test_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags)) {
+ ar->hw->netdev_features = NETIF_F_HW_CSUM;
+ ieee80211_hw_set(ar->hw, SW_CRYPTO_CONTROL);
+ }
ret = ieee80211_register_hw(ar->hw);
if (ret) {
--- a/drivers/net/wireless/ath/ath11k/wmi.c
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
@@ -864,6 +864,8 @@ int ath11k_wmi_vdev_start(struct ath11k
}
cmd->flags |= WMI_VDEV_START_LDPC_RX_ENABLED;
+ if (test_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags))
+ cmd->flags |= WMI_VDEV_START_HW_ENCRYPTION_DISABLED;
ptr = skb->data + sizeof(*cmd);
chan = ptr;
@@ -1684,7 +1686,8 @@ int ath11k_wmi_vdev_install_key(struct a
static inline void
ath11k_wmi_copy_peer_flags(struct wmi_peer_assoc_complete_cmd *cmd,
- struct peer_assoc_params *param)
+ struct peer_assoc_params *param,
+ bool hw_crypto_disabled)
{
cmd->peer_flags = 0;
@@ -1738,7 +1741,8 @@ ath11k_wmi_copy_peer_flags(struct wmi_pe
cmd->peer_flags |= WMI_PEER_AUTH;
if (param->need_ptk_4_way) {
cmd->peer_flags |= WMI_PEER_NEED_PTK_4_WAY;
- cmd->peer_flags &= ~WMI_PEER_AUTH;
+ if (!hw_crypto_disabled)
+ cmd->peer_flags &= ~WMI_PEER_AUTH;
}
if (param->need_gtk_2_way)
cmd->peer_flags |= WMI_PEER_NEED_GTK_2_WAY;
@@ -1805,7 +1809,8 @@ int ath11k_wmi_send_peer_assoc_cmd(struc
cmd->peer_new_assoc = param->peer_new_assoc;
cmd->peer_associd = param->peer_associd;
- ath11k_wmi_copy_peer_flags(cmd, param);
+ ath11k_wmi_copy_peer_flags(cmd, param,
+ test_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags));
ether_addr_copy(cmd->peer_macaddr.addr, param->peer_mac);
@@ -3368,6 +3373,10 @@ int ath11k_wmi_cmd_init(struct ath11k_ba
config.rx_timeout_pri[2] = TARGET_RX_TIMEOUT_LO_PRI;
config.rx_timeout_pri[3] = TARGET_RX_TIMEOUT_HI_PRI;
config.rx_decap_mode = TARGET_DECAP_MODE_NATIVE_WIFI;
+
+ if (test_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags))
+ config.rx_decap_mode = TARGET_DECAP_MODE_RAW;
+
config.scan_max_pending_req = TARGET_SCAN_MAX_PENDING_REQS;
config.bmiss_offload_max_vdev = TARGET_BMISS_OFFLOAD_MAX_VDEV;
config.roam_offload_max_vdev = TARGET_ROAM_OFFLOAD_MAX_VDEV;
--- a/drivers/net/wireless/ath/ath11k/debug.h
+++ b/drivers/net/wireless/ath/ath11k/debug.h
@@ -26,6 +26,8 @@ enum ath11k_debug_mask {
ATH11K_DBG_TESTMODE = 0x00000400,
ATH11k_DBG_HAL = 0x00000800,
ATH11K_DBG_PCI = 0x00001000,
+ ATH11K_DBG_DP_TX = 0x00002000,
+ ATH11K_DBG_DP_RX = 0x00004000,
ATH11K_DBG_ANY = 0xffffffff,
};
--- a/drivers/net/wireless/ath/ath11k/wmi.h
+++ b/drivers/net/wireless/ath/ath11k/wmi.h
@@ -2502,6 +2502,7 @@ struct wmi_vdev_down_cmd {
#define WMI_VDEV_START_HIDDEN_SSID BIT(0)
#define WMI_VDEV_START_PMF_ENABLED BIT(1)
#define WMI_VDEV_START_LDPC_RX_ENABLED BIT(3)
+#define WMI_VDEV_START_HW_ENCRYPTION_DISABLED BIT(4)
struct wmi_ssid {
u32 ssid_len;