Files
wlan-ap/feeds/ipq807x/mac80211/patches/015-add-raw-mode-support.patch
John Crispin 3affbc1cad QualComm/AX: add Hawkeye and Cypress support
This series is based on
* 2020-07-10 ipq6018-ilq-11-0_qca_oem-034672b0676c37b1f4519e5720e18e95fe6236ef

Add support for
* qsdk kernel/v4.4
* qsdk ethernet subsystem
* v5.7 ath11k backport + QualComm staging patches (wlan_ap_1.0)
* ath11k-firmware
* hostapd/iw/...

Feature support
* full boot, system detection
* sysupgrade to nand
* HE support via latest hostapd
* driver support for usb, crypto, hwmon, cpufreq, ...

Missing
* NSS/HW flow offloading - FW blob is not redistributable

Using the qsdk v4.4 is an intermediate solution while the vanilla is being
tested. Vanilla kernel is almost on feature par. Work has already started
to upstream the ethernet and switch drivers. Once complete the target will
be fully upstream.

Signed-off-by: John Crispin <john@phrozen.org>
2020-07-23 18:54:03 +02:00

278 lines
9.1 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,8 +14,14 @@
#include "debug.h"
unsigned int ath11k_debug_mask;
+unsigned int rawmode;
+unsigned int cryptmode;
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 = {
.name = "ipq8074",
@@ -547,6 +553,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
@@ -53,6 +53,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
@@ -2040,8 +2040,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) {
@@ -2056,6 +2054,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 |
@@ -2253,6 +2255,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
@@ -16,7 +16,11 @@ ath11k_txq_tcl_ring_map[ATH11K_HW_MAX_QU
static enum hal_tcl_encap_type
ath11k_dp_tx_get_encap_type(struct ath11k_vif *arvif, struct sk_buff *skb)
{
- /* TODO: Determine encap type based on vif_type and configuration */
+ struct ath11k_base *ab = arvif->ar->ab;
+
+ if (test_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags))
+ return HAL_TCL_ENCAP_TYPE_RAW;
+
return HAL_TCL_ENCAP_TYPE_NATIVE_WIFI;
}
@@ -110,11 +114,17 @@ int ath11k_dp_tx(struct ath11k *ar, stru
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;
@@ -124,7 +134,8 @@ int ath11k_dp_tx(struct ath11k *ar, stru
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) |
@@ -144,10 +155,11 @@ int ath11k_dp_tx(struct ath11k *ar, stru
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:
case HAL_TCL_ENCAP_TYPE_802_3:
/* TODO: Take care of other encap modes as well */
@@ -186,6 +198,9 @@ int ath11k_dp_tx(struct ath11k *ar, stru
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);
@@ -300,7 +315,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
@@ -2258,6 +2258,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; */
@@ -2289,8 +2292,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;
@@ -2362,6 +2369,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;
@@ -4220,6 +4230,10 @@ static int ath11k_mac_op_add_interface(s
param_id = WMI_VDEV_PARAM_TX_ENCAP_TYPE;
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) {
@@ -5855,8 +5869,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
@@ -3229,6 +3229,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
@@ -25,6 +25,8 @@ enum ath11k_debug_mask {
ATH11K_DBG_REG = 0x00000200,
ATH11K_DBG_TESTMODE = 0x00000400,
ATH11k_DBG_HAL = 0x00000800,
+ ATH11K_DBG_DP_TX = 0x00001000,
+ ATH11K_DBG_DP_RX = 0x00002000,
ATH11K_DBG_ANY = 0xffffffff,
};