mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-12-18 09:51:26 +00:00
325 lines
11 KiB
Diff
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;
|