mirror of
https://github.com/coolsnowwolf/lede.git
synced 2025-04-16 04:13:31 +00:00
mac80211: fix ath11k support for IPQ target
This commit is contained in:
parent
ba1f8c931c
commit
3530c1b73f
@ -12,6 +12,8 @@ PKG_CONFIG_DEPENDS += \
|
||||
CONFIG_ATH9K_TX99 \
|
||||
CONFIG_ATH10K_LEDS \
|
||||
CONFIG_ATH10K_THERMAL \
|
||||
CONFIG_ATH11K_MEM_PROFILE_512MB \
|
||||
CONFIG_ATH11K_MEM_PROFILE_1GB \
|
||||
CONFIG_ATH_USER_REGD
|
||||
|
||||
ifdef CONFIG_PACKAGE_MAC80211_DEBUGFS
|
||||
@ -54,6 +56,8 @@ config-$(CONFIG_ATH9K_TX99) += ATH9K_TX99
|
||||
config-$(CONFIG_ATH9K_UBNTHSR) += ATH9K_UBNTHSR
|
||||
config-$(CONFIG_ATH10K_LEDS) += ATH10K_LEDS
|
||||
config-$(CONFIG_ATH10K_THERMAL) += ATH10K_THERMAL
|
||||
config-$(CONFIG_ATH11K_MEM_PROFILE_512MB) += ATH11K_MEM_PROFILE_512MB
|
||||
config-$(CONFIG_ATH11K_MEM_PROFILE_1GB) += ATH11K_MEM_PROFILE_1GB
|
||||
|
||||
config-$(call config_package,ath9k-htc) += ATH9K_HTC
|
||||
config-$(call config_package,ath10k) += ATH10K ATH10K_PCI
|
||||
@ -284,7 +288,6 @@ define KernelPackage/ath10k/config
|
||||
|
||||
config ATH10K_THERMAL
|
||||
bool "Enable thermal sensors and throttling support"
|
||||
default y
|
||||
depends on PACKAGE_kmod-ath10k || PACKAGE_kmod-ath10k-smallbuffers
|
||||
|
||||
endef
|
||||
@ -300,9 +303,9 @@ define KernelPackage/ath11k
|
||||
TITLE:=Qualcomm 802.11ax wireless chipset support (common code)
|
||||
URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath11k
|
||||
DEPENDS+= +kmod-ath +@DRIVER_11N_SUPPORT +@DRIVER_11AC_SUPPORT +@DRIVER_11AX_SUPPORT \
|
||||
+kmod-crypto-michael-mic +ATH11K_THERMAL:kmod-hwmon-core +ATH11K_THERMAL:kmod-thermal
|
||||
+kmod-qcom-qmi-helpers +kmod-crypto-michael-mic +ATH11K_THERMAL:kmod-hwmon-core \
|
||||
+ATH11K_THERMAL:kmod-thermal
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath11k/ath11k.ko
|
||||
AUTOLOAD:=$(call AutoProbe,ath11k)
|
||||
endef
|
||||
|
||||
define KernelPackage/ath11k/description
|
||||
@ -317,13 +320,29 @@ define KernelPackage/ath11k/config
|
||||
depends on PACKAGE_kmod-ath11k
|
||||
default y if TARGET_ipq807x
|
||||
|
||||
if PACKAGE_kmod-ath11k
|
||||
|
||||
choice
|
||||
prompt "ath11k memory profile"
|
||||
default ATH11K_MEM_PROFILE_512MB
|
||||
help
|
||||
This allows selecting the ath11k memory size profile to be used.
|
||||
|
||||
config ATH11K_MEM_PROFILE_512MB
|
||||
bool "Use limits for the 512MB memory size"
|
||||
|
||||
config ATH11K_MEM_PROFILE_1GB
|
||||
bool "Use limits for the 1GB memory size"
|
||||
|
||||
endchoice
|
||||
endif
|
||||
endef
|
||||
|
||||
define KernelPackage/ath11k-ahb
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Qualcomm 802.11ax AHB wireless chipset support
|
||||
URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath11k
|
||||
DEPENDS+= @TARGET_ipq807x +kmod-ath11k
|
||||
DEPENDS+= @TARGET_ipq807x +kmod-ath11k +LINUX_5_15:kmod-qrtr-smd
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath11k/ath11k_ahb.ko
|
||||
AUTOLOAD:=$(call AutoProbe,ath11k_ahb)
|
||||
endef
|
||||
@ -337,7 +356,7 @@ define KernelPackage/ath11k-pci
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Qualcomm 802.11ax PCI wireless chipset support
|
||||
URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath11k
|
||||
DEPENDS+= @PCI_SUPPORT @TARGET_ipq807x +kmod-ath11k
|
||||
DEPENDS+= @PCI_SUPPORT +kmod-qrtr-mhi +kmod-ath11k
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath11k/ath11k_pci.ko
|
||||
AUTOLOAD:=$(call AutoProbe,ath11k_pci)
|
||||
endef
|
||||
|
@ -0,0 +1,151 @@
|
||||
From 34c67dc366419e06129dad0f32f521842bdff9bc Mon Sep 17 00:00:00 2001
|
||||
From: Sathishkumar Muruganandam <murugana@codeaurora.org>
|
||||
Date: Wed, 21 Jul 2021 00:31:46 +0300
|
||||
Subject: [PATCH 002/120] ath11k: fix 4-addr tx failure for AP and STA modes
|
||||
|
||||
Ath11k FW requires peer parameter WMI_PEER_USE_4ADDR to be set for
|
||||
4-addr peers allowing 4-address frame transmission to those peers.
|
||||
|
||||
Add ath11k driver callback for sta_set_4addr() to queue new workq
|
||||
set_4addr_wk only once based on new boolean, use_4addr_set.
|
||||
|
||||
sta_set_4addr() will be called during 4-addr STA association cases
|
||||
applicable for both AP and STA modes.
|
||||
|
||||
In ath11k_sta_set_4addr_wk(),
|
||||
|
||||
AP mode:
|
||||
WMI_PEER_USE_4ADDR will be set for the corresponding
|
||||
associated 4-addr STA(s)
|
||||
|
||||
STA mode:
|
||||
WMI_PEER_USE_4ADDR will be set for the AP to which the
|
||||
4-addr STA got associated.
|
||||
|
||||
Tested-on: IPQ8074 WLAN.HK.2.1.0.1-01238-QCAHKSWPL_SILICONZ-1
|
||||
|
||||
Signed-off-by: Sathishkumar Muruganandam <murugana@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20210720213147.90042-1-jouni@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/core.h | 3 ++
|
||||
drivers/net/wireless/ath/ath11k/mac.c | 48 ++++++++++++++++++++++++--
|
||||
2 files changed, 49 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/core.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/core.h
|
||||
@@ -362,6 +362,7 @@ struct ath11k_sta {
|
||||
enum hal_pn_type pn_type;
|
||||
|
||||
struct work_struct update_wk;
|
||||
+ struct work_struct set_4addr_wk;
|
||||
struct rate_info txrate;
|
||||
struct rate_info last_txrate;
|
||||
u64 rx_duration;
|
||||
@@ -374,6 +375,8 @@ struct ath11k_sta {
|
||||
/* protected by conf_mutex */
|
||||
bool aggr_mode;
|
||||
#endif
|
||||
+
|
||||
+ bool use_4addr_set;
|
||||
};
|
||||
|
||||
#define ATH11K_MIN_5G_FREQ 4150
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -3155,6 +3155,31 @@ static void ath11k_sta_rc_update_wk(stru
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
}
|
||||
|
||||
+static void ath11k_sta_set_4addr_wk(struct work_struct *wk)
|
||||
+{
|
||||
+ struct ath11k *ar;
|
||||
+ struct ath11k_vif *arvif;
|
||||
+ struct ath11k_sta *arsta;
|
||||
+ struct ieee80211_sta *sta;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ arsta = container_of(wk, struct ath11k_sta, set_4addr_wk);
|
||||
+ sta = container_of((void *)arsta, struct ieee80211_sta, drv_priv);
|
||||
+ arvif = arsta->arvif;
|
||||
+ ar = arvif->ar;
|
||||
+
|
||||
+ ath11k_dbg(ar->ab, ATH11K_DBG_MAC,
|
||||
+ "setting USE_4ADDR for peer %pM\n", sta->addr);
|
||||
+
|
||||
+ ret = ath11k_wmi_set_peer_param(ar, sta->addr,
|
||||
+ arvif->vdev_id,
|
||||
+ WMI_PEER_USE_4ADDR, 1);
|
||||
+
|
||||
+ if (ret)
|
||||
+ ath11k_warn(ar->ab, "failed to set peer %pM 4addr capability: %d\n",
|
||||
+ sta->addr, ret);
|
||||
+}
|
||||
+
|
||||
static int ath11k_mac_inc_num_stations(struct ath11k_vif *arvif,
|
||||
struct ieee80211_sta *sta)
|
||||
{
|
||||
@@ -3234,11 +3259,13 @@ static int ath11k_mac_station_add(struct
|
||||
}
|
||||
|
||||
if (ieee80211_vif_is_mesh(vif)) {
|
||||
+ ath11k_dbg(ab, ATH11K_DBG_MAC,
|
||||
+ "setting USE_4ADDR for mesh STA %pM\n", sta->addr);
|
||||
ret = ath11k_wmi_set_peer_param(ar, sta->addr,
|
||||
arvif->vdev_id,
|
||||
WMI_PEER_USE_4ADDR, 1);
|
||||
if (ret) {
|
||||
- ath11k_warn(ab, "failed to STA %pM 4addr capability: %d\n",
|
||||
+ ath11k_warn(ab, "failed to set mesh STA %pM 4addr capability: %d\n",
|
||||
sta->addr, ret);
|
||||
goto free_tx_stats;
|
||||
}
|
||||
@@ -3291,8 +3318,10 @@ static int ath11k_mac_op_sta_state(struc
|
||||
|
||||
/* cancel must be done outside the mutex to avoid deadlock */
|
||||
if ((old_state == IEEE80211_STA_NONE &&
|
||||
- new_state == IEEE80211_STA_NOTEXIST))
|
||||
+ new_state == IEEE80211_STA_NOTEXIST)) {
|
||||
cancel_work_sync(&arsta->update_wk);
|
||||
+ cancel_work_sync(&arsta->set_4addr_wk);
|
||||
+ }
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
|
||||
@@ -3301,6 +3330,7 @@ static int ath11k_mac_op_sta_state(struc
|
||||
memset(arsta, 0, sizeof(*arsta));
|
||||
arsta->arvif = arvif;
|
||||
INIT_WORK(&arsta->update_wk, ath11k_sta_rc_update_wk);
|
||||
+ INIT_WORK(&arsta->set_4addr_wk, ath11k_sta_set_4addr_wk);
|
||||
|
||||
ret = ath11k_mac_station_add(ar, vif, sta);
|
||||
if (ret)
|
||||
@@ -3395,6 +3425,19 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static void ath11k_mac_op_sta_set_4addr(struct ieee80211_hw *hw,
|
||||
+ struct ieee80211_vif *vif,
|
||||
+ struct ieee80211_sta *sta, bool enabled)
|
||||
+{
|
||||
+ struct ath11k *ar = hw->priv;
|
||||
+ struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
|
||||
+
|
||||
+ if (enabled && !arsta->use_4addr_set) {
|
||||
+ ieee80211_queue_work(ar->hw, &arsta->set_4addr_wk);
|
||||
+ arsta->use_4addr_set = true;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void ath11k_mac_op_sta_rc_update(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
@@ -6180,6 +6223,7 @@ static const struct ieee80211_ops ath11k
|
||||
.cancel_hw_scan = ath11k_mac_op_cancel_hw_scan,
|
||||
.set_key = ath11k_mac_op_set_key,
|
||||
.sta_state = ath11k_mac_op_sta_state,
|
||||
+ .sta_set_4addr = ath11k_mac_op_sta_set_4addr,
|
||||
.sta_set_txpwr = ath11k_mac_op_sta_set_txpwr,
|
||||
.sta_rc_update = ath11k_mac_op_sta_rc_update,
|
||||
.conf_tx = ath11k_mac_op_conf_tx,
|
@ -0,0 +1,123 @@
|
||||
From e20cfa3b62aeb1b5fc5ffa86a007af97f9954767 Mon Sep 17 00:00:00 2001
|
||||
From: Karthikeyan Periyasamy <periyasa@codeaurora.org>
|
||||
Date: Wed, 21 Jul 2021 00:31:47 +0300
|
||||
Subject: [PATCH 003/120] ath11k: fix 4addr multicast packet tx
|
||||
|
||||
In 4addr, AP wired backbone to STA wired backbone ping fails due to ARP
|
||||
request not getting answered. Here 4addr ARP multicast packet is sent in
|
||||
3addr, so that 4addr STA not honouring the 3addr ARP multicast packet.
|
||||
Fix this issue by sending out multicast packet in 4addr format, firmware
|
||||
expects peer meta flag instead of vdev meta flag in Tx descriptor.
|
||||
|
||||
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-01641-QCAHKSWPL_SILICONZ-1
|
||||
|
||||
Signed-off-by: Karthikeyan Periyasamy <periyasa@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20210720213147.90042-2-jouni@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/core.h | 1 +
|
||||
drivers/net/wireless/ath/ath11k/dp_tx.c | 12 ++++++++++--
|
||||
drivers/net/wireless/ath/ath11k/dp_tx.h | 2 +-
|
||||
drivers/net/wireless/ath/ath11k/mac.c | 6 +++++-
|
||||
drivers/net/wireless/ath/ath11k/peer.c | 11 +++++++++++
|
||||
5 files changed, 28 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/core.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/core.h
|
||||
@@ -377,6 +377,7 @@ struct ath11k_sta {
|
||||
#endif
|
||||
|
||||
bool use_4addr_set;
|
||||
+ u16 tcl_metadata;
|
||||
};
|
||||
|
||||
#define ATH11K_MIN_5G_FREQ 4150
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp_tx.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp_tx.c
|
||||
@@ -78,7 +78,7 @@ enum hal_encrypt_type ath11k_dp_tx_get_e
|
||||
}
|
||||
|
||||
int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif,
|
||||
- struct sk_buff *skb)
|
||||
+ struct ath11k_sta *arsta, struct sk_buff *skb)
|
||||
{
|
||||
struct ath11k_base *ab = ar->ab;
|
||||
struct ath11k_dp *dp = &ab->dp;
|
||||
@@ -145,7 +145,15 @@ tcl_ring_sel:
|
||||
FIELD_PREP(DP_TX_DESC_ID_MSDU_ID, ret) |
|
||||
FIELD_PREP(DP_TX_DESC_ID_POOL_ID, pool_id);
|
||||
ti.encap_type = ath11k_dp_tx_get_encap_type(arvif, skb);
|
||||
- ti.meta_data_flags = arvif->tcl_metadata;
|
||||
+
|
||||
+ if (ieee80211_has_a4(hdr->frame_control) &&
|
||||
+ is_multicast_ether_addr(hdr->addr3) && arsta &&
|
||||
+ arsta->use_4addr_set) {
|
||||
+ ti.meta_data_flags = arsta->tcl_metadata;
|
||||
+ ti.flags0 |= FIELD_PREP(HAL_TCL_DATA_CMD_INFO1_TO_FW, 1);
|
||||
+ } else {
|
||||
+ ti.meta_data_flags = arvif->tcl_metadata;
|
||||
+ }
|
||||
|
||||
if (ti.encap_type == HAL_TCL_ENCAP_TYPE_RAW) {
|
||||
if (skb_cb->flags & ATH11K_SKB_CIPHER_SET) {
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp_tx.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp_tx.h
|
||||
@@ -17,7 +17,7 @@ struct ath11k_dp_htt_wbm_tx_status {
|
||||
|
||||
int ath11k_dp_tx_htt_h2t_ver_req_msg(struct ath11k_base *ab);
|
||||
int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif,
|
||||
- struct sk_buff *skb);
|
||||
+ struct ath11k_sta *arsta, struct sk_buff *skb);
|
||||
void ath11k_dp_tx_completion_handler(struct ath11k_base *ab, int ring_id);
|
||||
int ath11k_dp_tx_send_reo_cmd(struct ath11k_base *ab, struct dp_rx_tid *rx_tid,
|
||||
enum hal_reo_cmd_type type,
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -4356,6 +4356,7 @@ static void ath11k_mac_op_tx(struct ieee
|
||||
struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
|
||||
struct ieee80211_key_conf *key = info->control.hw_key;
|
||||
+ struct ath11k_sta *arsta = NULL;
|
||||
u32 info_flags = info->flags;
|
||||
bool is_prb_rsp;
|
||||
int ret;
|
||||
@@ -4381,7 +4382,10 @@ static void ath11k_mac_op_tx(struct ieee
|
||||
return;
|
||||
}
|
||||
|
||||
- ret = ath11k_dp_tx(ar, arvif, skb);
|
||||
+ if (control->sta)
|
||||
+ arsta = (struct ath11k_sta *)control->sta->drv_priv;
|
||||
+
|
||||
+ ret = ath11k_dp_tx(ar, arvif, arsta, skb);
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab, "failed to transmit frame %d\n", ret);
|
||||
ieee80211_free_txskb(ar->hw, skb);
|
||||
--- a/drivers/net/wireless/ath/ath11k/peer.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/peer.c
|
||||
@@ -251,6 +251,7 @@ int ath11k_peer_create(struct ath11k *ar
|
||||
struct ieee80211_sta *sta, struct peer_create_params *param)
|
||||
{
|
||||
struct ath11k_peer *peer;
|
||||
+ struct ath11k_sta *arsta;
|
||||
int ret;
|
||||
|
||||
lockdep_assert_held(&ar->conf_mutex);
|
||||
@@ -319,6 +320,16 @@ int ath11k_peer_create(struct ath11k *ar
|
||||
peer->sec_type = HAL_ENCRYPT_TYPE_OPEN;
|
||||
peer->sec_type_grp = HAL_ENCRYPT_TYPE_OPEN;
|
||||
|
||||
+ if (sta) {
|
||||
+ arsta = (struct ath11k_sta *)sta->drv_priv;
|
||||
+ arsta->tcl_metadata |= FIELD_PREP(HTT_TCL_META_DATA_TYPE, 0) |
|
||||
+ FIELD_PREP(HTT_TCL_META_DATA_PEER_ID,
|
||||
+ peer->peer_id);
|
||||
+
|
||||
+ /* set HTT extension valid bit to 0 by default */
|
||||
+ arsta->tcl_metadata &= ~HTT_TCL_META_DATA_VALID_HTT;
|
||||
+ }
|
||||
+
|
||||
ar->num_peers++;
|
||||
|
||||
spin_unlock_bh(&ar->ab->base_lock);
|
@ -0,0 +1,42 @@
|
||||
From 7e9fb2418a4c092a363d23e97973c9624150e5b2 Mon Sep 17 00:00:00 2001
|
||||
From: Seevalamuthu Mariappan <seevalam@codeaurora.org>
|
||||
Date: Wed, 21 Jul 2021 00:49:20 +0300
|
||||
Subject: [PATCH 004/120] ath11k: Rename atf_config to flag1 in
|
||||
target_resource_config
|
||||
|
||||
The flag's purpose is not only meant for ATF configs. Rename atf_config
|
||||
to flag1, so it can be used for future purposes.
|
||||
|
||||
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.1.0.1-01228-QCAHKSWPL_SILICONZ-1
|
||||
|
||||
Signed-off-by: Seevalamuthu Mariappan <seevalam@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20210720214922.118078-1-jouni@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/wmi.c | 2 +-
|
||||
drivers/net/wireless/ath/ath11k/wmi.h | 2 +-
|
||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/wmi.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
|
||||
@@ -3496,7 +3496,7 @@ ath11k_wmi_copy_resource_config(struct w
|
||||
wmi_cfg->bpf_instruction_size = tg_cfg->bpf_instruction_size;
|
||||
wmi_cfg->max_bssid_rx_filters = tg_cfg->max_bssid_rx_filters;
|
||||
wmi_cfg->use_pdev_id = tg_cfg->use_pdev_id;
|
||||
- wmi_cfg->flag1 = tg_cfg->atf_config;
|
||||
+ wmi_cfg->flag1 = tg_cfg->flag1;
|
||||
wmi_cfg->peer_map_unmap_v2_support = tg_cfg->peer_map_unmap_v2_support;
|
||||
wmi_cfg->sched_params = tg_cfg->sched_params;
|
||||
wmi_cfg->twt_ap_pdev_count = tg_cfg->twt_ap_pdev_count;
|
||||
--- a/drivers/net/wireless/ath/ath11k/wmi.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/wmi.h
|
||||
@@ -5015,7 +5015,7 @@ struct target_resource_config {
|
||||
u32 vo_minfree;
|
||||
u32 rx_batchmode;
|
||||
u32 tt_support;
|
||||
- u32 atf_config;
|
||||
+ u32 flag1;
|
||||
u32 iphdr_pad_config;
|
||||
u32 qwrap_config:16,
|
||||
alloc_frag_desc_for_data_pkt:16;
|
@ -0,0 +1,51 @@
|
||||
From 9b4dd38b46cf24d8cb3ab433661cdc23a35160d0 Mon Sep 17 00:00:00 2001
|
||||
From: Seevalamuthu Mariappan <seevalam@codeaurora.org>
|
||||
Date: Wed, 21 Jul 2021 00:49:21 +0300
|
||||
Subject: [PATCH 005/120] ath11k: add support in survey dump with bss_chan_info
|
||||
|
||||
Survey dump statistics is not displaying channel rx and tx time because
|
||||
the service flag is not enabled. Enable the service flag "bss_chan_info"
|
||||
in wmi_resource_config to fetch and print the stats for the specific
|
||||
pdev.
|
||||
|
||||
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.1.0.1-01228-QCAHKSWPL_SILICONZ-1
|
||||
|
||||
Signed-off-by: Ritesh Singh <ritesi@codeaurora.org>
|
||||
Signed-off-by: Seevalamuthu Mariappan <seevalam@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20210720214922.118078-2-jouni@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/hw.c | 2 ++
|
||||
drivers/net/wireless/ath/ath11k/wmi.h | 2 ++
|
||||
2 files changed, 4 insertions(+)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/hw.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/hw.c
|
||||
@@ -97,6 +97,7 @@ static void ath11k_init_wmi_config_qca63
|
||||
config->num_multicast_filter_entries = 0x20;
|
||||
config->num_wow_filters = 0x16;
|
||||
config->num_keep_alive_pattern = 0;
|
||||
+ config->flag1 |= WMI_RSRC_CFG_FLAG1_BSS_CHANNEL_INFO_64;
|
||||
}
|
||||
|
||||
static void ath11k_hw_ipq8074_reo_setup(struct ath11k_base *ab)
|
||||
@@ -197,6 +198,7 @@ static void ath11k_init_wmi_config_ipq80
|
||||
config->peer_map_unmap_v2_support = 1;
|
||||
config->twt_ap_pdev_count = ab->num_radios;
|
||||
config->twt_ap_sta_count = 1000;
|
||||
+ config->flag1 |= WMI_RSRC_CFG_FLAG1_BSS_CHANNEL_INFO_64;
|
||||
}
|
||||
|
||||
static int ath11k_hw_mac_id_to_pdev_id_ipq8074(struct ath11k_hw_params *hw,
|
||||
--- a/drivers/net/wireless/ath/ath11k/wmi.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/wmi.h
|
||||
@@ -2244,6 +2244,8 @@ struct wmi_init_cmd {
|
||||
u32 num_host_mem_chunks;
|
||||
} __packed;
|
||||
|
||||
+#define WMI_RSRC_CFG_FLAG1_BSS_CHANNEL_INFO_64 BIT(5)
|
||||
+
|
||||
struct wmi_resource_config {
|
||||
u32 tlv_header;
|
||||
u32 num_vdevs;
|
@ -0,0 +1,65 @@
|
||||
From d37b4862312c980d1f6843d11a14ad4eda242c8d Mon Sep 17 00:00:00 2001
|
||||
From: Seevalamuthu Mariappan <seevalam@codeaurora.org>
|
||||
Date: Tue, 21 Sep 2021 16:39:29 +0300
|
||||
Subject: [PATCH 007/120] ath11k: move static function
|
||||
ath11k_mac_vdev_setup_sync to top
|
||||
|
||||
This is to prepare for monitor mode clean up.
|
||||
No functional changes are done.
|
||||
|
||||
Co-developed-by: Miles Hu <milehu@codeaurora.org>
|
||||
Signed-off-by: Miles Hu <milehu@codeaurora.org>
|
||||
Co-developed-by: Vasanthakumar Thiagarajan <vthiagar@codeaurora.org>
|
||||
Signed-off-by: Vasanthakumar Thiagarajan <vthiagar@codeaurora.org>
|
||||
Signed-off-by: Seevalamuthu Mariappan <seevalam@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20210721162053.46290-2-jouni@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/mac.c | 28 +++++++++++++--------------
|
||||
1 file changed, 14 insertions(+), 14 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -731,6 +731,20 @@ static int ath11k_monitor_vdev_up(struct
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static inline int ath11k_mac_vdev_setup_sync(struct ath11k *ar)
|
||||
+{
|
||||
+ lockdep_assert_held(&ar->conf_mutex);
|
||||
+
|
||||
+ if (test_bit(ATH11K_FLAG_CRASH_FLUSH, &ar->ab->dev_flags))
|
||||
+ return -ESHUTDOWN;
|
||||
+
|
||||
+ if (!wait_for_completion_timeout(&ar->vdev_setup_done,
|
||||
+ ATH11K_VDEV_SETUP_TIMEOUT_HZ))
|
||||
+ return -ETIMEDOUT;
|
||||
+
|
||||
+ return ar->last_wmi_vdev_start_status ? -EINVAL : 0;
|
||||
+}
|
||||
+
|
||||
static int ath11k_mac_op_config(struct ieee80211_hw *hw, u32 changed)
|
||||
{
|
||||
/* mac80211 requires this op to be present and that's why
|
||||
@@ -5165,20 +5179,6 @@ static void ath11k_mac_op_remove_chanctx
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
}
|
||||
|
||||
-static inline int ath11k_mac_vdev_setup_sync(struct ath11k *ar)
|
||||
-{
|
||||
- lockdep_assert_held(&ar->conf_mutex);
|
||||
-
|
||||
- if (test_bit(ATH11K_FLAG_CRASH_FLUSH, &ar->ab->dev_flags))
|
||||
- return -ESHUTDOWN;
|
||||
-
|
||||
- if (!wait_for_completion_timeout(&ar->vdev_setup_done,
|
||||
- ATH11K_VDEV_SETUP_TIMEOUT_HZ))
|
||||
- return -ETIMEDOUT;
|
||||
-
|
||||
- return ar->last_wmi_vdev_start_status ? -EINVAL : 0;
|
||||
-}
|
||||
-
|
||||
static int
|
||||
ath11k_mac_vdev_start_restart(struct ath11k_vif *arvif,
|
||||
const struct cfg80211_chan_def *chandef,
|
@ -0,0 +1,442 @@
|
||||
From 64e06b78a92744d43d3993ba623d2686d8f937e7 Mon Sep 17 00:00:00 2001
|
||||
From: Seevalamuthu Mariappan <seevalam@codeaurora.org>
|
||||
Date: Tue, 21 Sep 2021 16:39:29 +0300
|
||||
Subject: [PATCH 008/120] ath11k: add separate APIs for monitor mode
|
||||
|
||||
Add separate APIs for monitor_vdev_create/monitor_vdev_delete
|
||||
and monitor_vdev_start/monitor_vdev_stop.
|
||||
|
||||
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-01725-QCAHKSWPL_SILICONZ-1
|
||||
|
||||
Co-developed-by: Miles Hu <milehu@codeaurora.org>
|
||||
Signed-off-by: Miles Hu <milehu@codeaurora.org>
|
||||
Co-developed-by: Vasanthakumar Thiagarajan <vthiagar@codeaurora.org>
|
||||
Signed-off-by: Vasanthakumar Thiagarajan <vthiagar@codeaurora.org>
|
||||
Signed-off-by: Seevalamuthu Mariappan <seevalam@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20210721162053.46290-3-jouni@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/core.h | 5 +-
|
||||
drivers/net/wireless/ath/ath11k/mac.c | 371 ++++++++++++++++++++++++-
|
||||
2 files changed, 370 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/core.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/core.h
|
||||
@@ -194,6 +194,9 @@ enum ath11k_dev_flags {
|
||||
|
||||
enum ath11k_monitor_flags {
|
||||
ATH11K_FLAG_MONITOR_ENABLED,
|
||||
+ ATH11K_FLAG_MONITOR_CONF_ENABLED,
|
||||
+ ATH11K_FLAG_MONITOR_STARTED,
|
||||
+ ATH11K_FLAG_MONITOR_VDEV_CREATED,
|
||||
};
|
||||
|
||||
struct ath11k_vif {
|
||||
@@ -488,7 +491,6 @@ struct ath11k {
|
||||
u32 chan_tx_pwr;
|
||||
u32 num_stations;
|
||||
u32 max_num_stations;
|
||||
- bool monitor_present;
|
||||
/* To synchronize concurrent synchronous mac80211 callback operations,
|
||||
* concurrent debugfs configuration and concurrent FW statistics events.
|
||||
*/
|
||||
@@ -563,6 +565,7 @@ struct ath11k {
|
||||
struct ath11k_per_peer_tx_stats cached_stats;
|
||||
u32 last_ppdu_id;
|
||||
u32 cached_ppdu_id;
|
||||
+ int monitor_vdev_id;
|
||||
#ifdef CPTCFG_ATH11K_DEBUGFS
|
||||
struct ath11k_debug debug;
|
||||
#endif
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -745,14 +745,370 @@ static inline int ath11k_mac_vdev_setup_
|
||||
return ar->last_wmi_vdev_start_status ? -EINVAL : 0;
|
||||
}
|
||||
|
||||
-static int ath11k_mac_op_config(struct ieee80211_hw *hw, u32 changed)
|
||||
+static void
|
||||
+ath11k_mac_get_any_chandef_iter(struct ieee80211_hw *hw,
|
||||
+ struct ieee80211_chanctx_conf *conf,
|
||||
+ void *data)
|
||||
{
|
||||
- /* mac80211 requires this op to be present and that's why
|
||||
- * there's an empty function, this can be extended when
|
||||
- * required.
|
||||
- */
|
||||
+ struct cfg80211_chan_def **def = data;
|
||||
+
|
||||
+ *def = &conf->def;
|
||||
+}
|
||||
+
|
||||
+static int ath11k_mac_monitor_vdev_start(struct ath11k *ar, int vdev_id,
|
||||
+ struct cfg80211_chan_def *chandef)
|
||||
+{
|
||||
+ struct ieee80211_channel *channel;
|
||||
+ struct wmi_vdev_start_req_arg arg = {};
|
||||
+ int ret;
|
||||
+
|
||||
+ lockdep_assert_held(&ar->conf_mutex);
|
||||
+
|
||||
+ channel = chandef->chan;
|
||||
+
|
||||
+ arg.vdev_id = vdev_id;
|
||||
+ arg.channel.freq = channel->center_freq;
|
||||
+ arg.channel.band_center_freq1 = chandef->center_freq1;
|
||||
+ arg.channel.band_center_freq2 = chandef->center_freq2;
|
||||
+
|
||||
+ arg.channel.mode = ath11k_phymodes[chandef->chan->band][chandef->width];
|
||||
+ arg.channel.chan_radar = !!(channel->flags & IEEE80211_CHAN_RADAR);
|
||||
+
|
||||
+ arg.channel.min_power = 0;
|
||||
+ arg.channel.max_power = channel->max_power * 2;
|
||||
+ arg.channel.max_reg_power = channel->max_reg_power * 2;
|
||||
+ arg.channel.max_antenna_gain = channel->max_antenna_gain * 2;
|
||||
+
|
||||
+ arg.pref_tx_streams = ar->num_tx_chains;
|
||||
+ arg.pref_rx_streams = ar->num_rx_chains;
|
||||
+
|
||||
+ arg.channel.passive = !!(chandef->chan->flags & IEEE80211_CHAN_NO_IR);
|
||||
+
|
||||
+ reinit_completion(&ar->vdev_setup_done);
|
||||
+ reinit_completion(&ar->vdev_delete_done);
|
||||
+
|
||||
+ ret = ath11k_wmi_vdev_start(ar, &arg, false);
|
||||
+ if (ret) {
|
||||
+ ath11k_warn(ar->ab, "failed to request monitor vdev %i start: %d\n",
|
||||
+ vdev_id, ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = ath11k_mac_vdev_setup_sync(ar);
|
||||
+ if (ret) {
|
||||
+ ath11k_warn(ar->ab, "failed to synchronize setup for monitor vdev %i start: %d\n",
|
||||
+ vdev_id, ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = ath11k_wmi_vdev_up(ar, vdev_id, 0, ar->mac_addr);
|
||||
+ if (ret) {
|
||||
+ ath11k_warn(ar->ab, "failed to put up monitor vdev %i: %d\n",
|
||||
+ vdev_id, ret);
|
||||
+ goto vdev_stop;
|
||||
+ }
|
||||
+
|
||||
+ ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac monitor vdev %i started\n",
|
||||
+ vdev_id);
|
||||
|
||||
return 0;
|
||||
+
|
||||
+vdev_stop:
|
||||
+ reinit_completion(&ar->vdev_setup_done);
|
||||
+
|
||||
+ ret = ath11k_wmi_vdev_stop(ar, vdev_id);
|
||||
+ if (ret) {
|
||||
+ ath11k_warn(ar->ab, "failed to stop monitor vdev %i after start failure: %d\n",
|
||||
+ vdev_id, ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = ath11k_mac_vdev_setup_sync(ar);
|
||||
+ if (ret) {
|
||||
+ ath11k_warn(ar->ab, "failed to synchronize setup for vdev %i stop: %d\n",
|
||||
+ vdev_id, ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return -EIO;
|
||||
+}
|
||||
+
|
||||
+static int ath11k_mac_monitor_vdev_stop(struct ath11k *ar)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ lockdep_assert_held(&ar->conf_mutex);
|
||||
+
|
||||
+ reinit_completion(&ar->vdev_setup_done);
|
||||
+
|
||||
+ ret = ath11k_wmi_vdev_stop(ar, ar->monitor_vdev_id);
|
||||
+ if (ret) {
|
||||
+ ath11k_warn(ar->ab, "failed to request monitor vdev %i stop: %d\n",
|
||||
+ ar->monitor_vdev_id, ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = ath11k_mac_vdev_setup_sync(ar);
|
||||
+ if (ret) {
|
||||
+ ath11k_warn(ar->ab, "failed to synchronize monitor vdev %i stop: %d\n",
|
||||
+ ar->monitor_vdev_id, ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = ath11k_wmi_vdev_down(ar, ar->monitor_vdev_id);
|
||||
+ if (ret) {
|
||||
+ ath11k_warn(ar->ab, "failed to put down monitor vdev %i: %d\n",
|
||||
+ ar->monitor_vdev_id, ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac monitor vdev %i stopped\n",
|
||||
+ ar->monitor_vdev_id);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int ath11k_mac_monitor_vdev_create(struct ath11k *ar)
|
||||
+{
|
||||
+ struct ath11k_pdev *pdev = ar->pdev;
|
||||
+ struct vdev_create_params param = {};
|
||||
+ int bit, ret;
|
||||
+ u8 tmp_addr[6] = {0};
|
||||
+ u16 nss;
|
||||
+
|
||||
+ lockdep_assert_held(&ar->conf_mutex);
|
||||
+
|
||||
+ if (test_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags))
|
||||
+ return 0;
|
||||
+
|
||||
+ if (ar->ab->free_vdev_map == 0) {
|
||||
+ ath11k_warn(ar->ab, "failed to find free vdev id for monitor vdev\n");
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ bit = __ffs64(ar->ab->free_vdev_map);
|
||||
+
|
||||
+ ar->monitor_vdev_id = bit;
|
||||
+
|
||||
+ param.if_id = ar->monitor_vdev_id;
|
||||
+ param.type = WMI_VDEV_TYPE_MONITOR;
|
||||
+ param.subtype = WMI_VDEV_SUBTYPE_NONE;
|
||||
+ param.pdev_id = pdev->pdev_id;
|
||||
+
|
||||
+ if (pdev->cap.supported_bands & WMI_HOST_WLAN_2G_CAP) {
|
||||
+ param.chains[NL80211_BAND_2GHZ].tx = ar->num_tx_chains;
|
||||
+ param.chains[NL80211_BAND_2GHZ].rx = ar->num_rx_chains;
|
||||
+ }
|
||||
+ if (pdev->cap.supported_bands & WMI_HOST_WLAN_5G_CAP) {
|
||||
+ param.chains[NL80211_BAND_5GHZ].tx = ar->num_tx_chains;
|
||||
+ param.chains[NL80211_BAND_5GHZ].rx = ar->num_rx_chains;
|
||||
+ }
|
||||
+
|
||||
+ ret = ath11k_wmi_vdev_create(ar, tmp_addr, ¶m);
|
||||
+ if (ret) {
|
||||
+ ath11k_warn(ar->ab, "failed to request monitor vdev %i creation: %d\n",
|
||||
+ ar->monitor_vdev_id, ret);
|
||||
+ ar->monitor_vdev_id = -1;
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ nss = get_num_chains(ar->cfg_tx_chainmask) ? : 1;
|
||||
+ ret = ath11k_wmi_vdev_set_param_cmd(ar, ar->monitor_vdev_id,
|
||||
+ WMI_VDEV_PARAM_NSS, nss);
|
||||
+ if (ret) {
|
||||
+ ath11k_warn(ar->ab, "failed to set vdev %d chainmask 0x%x, nss %d :%d\n",
|
||||
+ ar->monitor_vdev_id, ar->cfg_tx_chainmask, nss, ret);
|
||||
+ goto err_vdev_del;
|
||||
+ }
|
||||
+
|
||||
+ ret = ath11k_mac_txpower_recalc(ar);
|
||||
+ if (ret) {
|
||||
+ ath11k_warn(ar->ab, "failed to recalc txpower for monitor vdev %d: %d\n",
|
||||
+ ar->monitor_vdev_id, ret);
|
||||
+ goto err_vdev_del;
|
||||
+ }
|
||||
+
|
||||
+ ar->allocated_vdev_map |= 1LL << ar->monitor_vdev_id;
|
||||
+ ar->ab->free_vdev_map &= ~(1LL << ar->monitor_vdev_id);
|
||||
+ ar->num_created_vdevs++;
|
||||
+ set_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags);
|
||||
+
|
||||
+ ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac monitor vdev %d created\n",
|
||||
+ ar->monitor_vdev_id);
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+err_vdev_del:
|
||||
+ ath11k_wmi_vdev_delete(ar, ar->monitor_vdev_id);
|
||||
+ ar->monitor_vdev_id = -1;
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int ath11k_mac_monitor_vdev_delete(struct ath11k *ar)
|
||||
+{
|
||||
+ int ret;
|
||||
+ unsigned long time_left;
|
||||
+
|
||||
+ lockdep_assert_held(&ar->conf_mutex);
|
||||
+
|
||||
+ if (!test_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags))
|
||||
+ return 0;
|
||||
+
|
||||
+ reinit_completion(&ar->vdev_delete_done);
|
||||
+
|
||||
+ ret = ath11k_wmi_vdev_delete(ar, ar->monitor_vdev_id);
|
||||
+ if (ret) {
|
||||
+ ath11k_warn(ar->ab, "failed to request wmi monitor vdev %i removal: %d\n",
|
||||
+ ar->monitor_vdev_id, ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ time_left = wait_for_completion_timeout(&ar->vdev_delete_done,
|
||||
+ ATH11K_VDEV_DELETE_TIMEOUT_HZ);
|
||||
+ if (time_left == 0) {
|
||||
+ ath11k_warn(ar->ab, "Timeout in receiving vdev delete response\n");
|
||||
+ } else {
|
||||
+ ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac monitor vdev %d deleted\n",
|
||||
+ ar->monitor_vdev_id);
|
||||
+
|
||||
+ ar->allocated_vdev_map &= ~(1LL << ar->monitor_vdev_id);
|
||||
+ ar->ab->free_vdev_map |= 1LL << (ar->monitor_vdev_id);
|
||||
+ ar->num_created_vdevs--;
|
||||
+ ar->monitor_vdev_id = -1;
|
||||
+ clear_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags);
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int ath11k_mac_monitor_start(struct ath11k *ar)
|
||||
+{
|
||||
+ struct cfg80211_chan_def *chandef = NULL;
|
||||
+ int ret;
|
||||
+
|
||||
+ lockdep_assert_held(&ar->conf_mutex);
|
||||
+
|
||||
+ if (test_bit(ATH11K_FLAG_MONITOR_STARTED, &ar->monitor_flags))
|
||||
+ return 0;
|
||||
+
|
||||
+ ieee80211_iter_chan_contexts_atomic(ar->hw,
|
||||
+ ath11k_mac_get_any_chandef_iter,
|
||||
+ &chandef);
|
||||
+ if (!chandef)
|
||||
+ return 0;
|
||||
+
|
||||
+ ret = ath11k_mac_monitor_vdev_start(ar, ar->monitor_vdev_id, chandef);
|
||||
+ if (ret) {
|
||||
+ ath11k_warn(ar->ab, "failed to start monitor vdev: %d\n", ret);
|
||||
+ ath11k_mac_monitor_vdev_delete(ar);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ set_bit(ATH11K_FLAG_MONITOR_STARTED, &ar->monitor_flags);
|
||||
+
|
||||
+ ar->num_started_vdevs++;
|
||||
+ ret = ath11k_dp_tx_htt_monitor_mode_ring_config(ar, false);
|
||||
+ if (ret) {
|
||||
+ ath11k_warn(ar->ab, "failed to configure htt monitor mode ring during start: %d",
|
||||
+ ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac monitor started\n");
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int ath11k_mac_monitor_stop(struct ath11k *ar)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ lockdep_assert_held(&ar->conf_mutex);
|
||||
+
|
||||
+ if (!test_bit(ATH11K_FLAG_MONITOR_STARTED, &ar->monitor_flags))
|
||||
+ return 0;
|
||||
+
|
||||
+ ret = ath11k_mac_monitor_vdev_stop(ar);
|
||||
+ if (ret) {
|
||||
+ ath11k_warn(ar->ab, "failed to stop monitor vdev: %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ clear_bit(ATH11K_FLAG_MONITOR_STARTED, &ar->monitor_flags);
|
||||
+ ar->num_started_vdevs--;
|
||||
+
|
||||
+ ret = ath11k_dp_tx_htt_monitor_mode_ring_config(ar, true);
|
||||
+ if (ret) {
|
||||
+ ath11k_warn(ar->ab, "failed to configure htt monitor mode ring during stop: %d",
|
||||
+ ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac monitor stopped ret %d\n", ret);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int ath11k_mac_op_config(struct ieee80211_hw *hw, u32 changed)
|
||||
+{
|
||||
+ struct ath11k *ar = hw->priv;
|
||||
+ struct ieee80211_conf *conf = &hw->conf;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ mutex_lock(&ar->conf_mutex);
|
||||
+
|
||||
+ if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
|
||||
+ if (conf->flags & IEEE80211_CONF_MONITOR) {
|
||||
+ set_bit(ATH11K_FLAG_MONITOR_CONF_ENABLED, &ar->monitor_flags);
|
||||
+
|
||||
+ if (test_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED,
|
||||
+ &ar->monitor_flags))
|
||||
+ goto out;
|
||||
+
|
||||
+ ret = ath11k_mac_monitor_vdev_create(ar);
|
||||
+ if (ret) {
|
||||
+ ath11k_warn(ar->ab, "failed to create monitor vdev: %d",
|
||||
+ ret);
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ ret = ath11k_mac_monitor_start(ar);
|
||||
+ if (ret) {
|
||||
+ ath11k_warn(ar->ab, "failed to start monitor: %d",
|
||||
+ ret);
|
||||
+ goto err_mon_del;
|
||||
+ }
|
||||
+ } else {
|
||||
+ clear_bit(ATH11K_FLAG_MONITOR_CONF_ENABLED, &ar->monitor_flags);
|
||||
+
|
||||
+ if (!test_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED,
|
||||
+ &ar->monitor_flags))
|
||||
+ goto out;
|
||||
+
|
||||
+ ret = ath11k_mac_monitor_stop(ar);
|
||||
+ if (ret) {
|
||||
+ ath11k_warn(ar->ab, "failed to stop monitor: %d",
|
||||
+ ret);
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ ret = ath11k_mac_monitor_vdev_delete(ar);
|
||||
+ if (ret) {
|
||||
+ ath11k_warn(ar->ab, "failed to delete monitor vdev: %d",
|
||||
+ ret);
|
||||
+ goto out;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+out:
|
||||
+ mutex_unlock(&ar->conf_mutex);
|
||||
+ return ret;
|
||||
+
|
||||
+err_mon_del:
|
||||
+ ath11k_mac_monitor_vdev_delete(ar);
|
||||
+ mutex_unlock(&ar->conf_mutex);
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
static int ath11k_mac_setup_bcn_tmpl(struct ath11k_vif *arvif)
|
||||
@@ -6771,7 +7127,12 @@ int ath11k_mac_allocate(struct ath11k_ba
|
||||
|
||||
INIT_WORK(&ar->wmi_mgmt_tx_work, ath11k_mgmt_over_wmi_tx_work);
|
||||
skb_queue_head_init(&ar->wmi_mgmt_tx_queue);
|
||||
+
|
||||
clear_bit(ATH11K_FLAG_MONITOR_ENABLED, &ar->monitor_flags);
|
||||
+ clear_bit(ATH11K_FLAG_MONITOR_STARTED, &ar->monitor_flags);
|
||||
+
|
||||
+ ar->monitor_vdev_id = -1;
|
||||
+ clear_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags);
|
||||
}
|
||||
|
||||
return 0;
|
@ -0,0 +1,370 @@
|
||||
From 689a5e6fff75229ac7c2af7a9c51dc2d3ca1882b Mon Sep 17 00:00:00 2001
|
||||
From: Seevalamuthu Mariappan <seevalam@codeaurora.org>
|
||||
Date: Tue, 21 Sep 2021 16:39:30 +0300
|
||||
Subject: [PATCH 009/120] ath11k: monitor mode clean up to use separate APIs
|
||||
|
||||
If monitor interface is enabled in co-exist mode, only local traffic are
|
||||
captured. It's caused by missing monitor vdev in co-exist mode. So,
|
||||
monitor mode clean up is done with separate Monitor APIs. For this,
|
||||
introduce flags monitor_started and monitor_vdev_created.
|
||||
|
||||
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-01725-QCAHKSWPL_SILICONZ-1
|
||||
|
||||
Co-developed-by: Miles Hu <milehu@codeaurora.org>
|
||||
Signed-off-by: Miles Hu <milehu@codeaurora.org>
|
||||
Co-developed-by: Vasanthakumar Thiagarajan <vthiagar@codeaurora.org>
|
||||
Signed-off-by: Vasanthakumar Thiagarajan <vthiagar@codeaurora.org>
|
||||
Signed-off-by: Seevalamuthu Mariappan <seevalam@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20210721162053.46290-4-jouni@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/core.h | 1 -
|
||||
drivers/net/wireless/ath/ath11k/dp_rx.c | 2 +-
|
||||
drivers/net/wireless/ath/ath11k/dp_tx.c | 8 +-
|
||||
drivers/net/wireless/ath/ath11k/mac.c | 150 ++++++++++++++++--------
|
||||
4 files changed, 110 insertions(+), 51 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/core.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/core.h
|
||||
@@ -193,7 +193,6 @@ enum ath11k_dev_flags {
|
||||
};
|
||||
|
||||
enum ath11k_monitor_flags {
|
||||
- ATH11K_FLAG_MONITOR_ENABLED,
|
||||
ATH11K_FLAG_MONITOR_CONF_ENABLED,
|
||||
ATH11K_FLAG_MONITOR_STARTED,
|
||||
ATH11K_FLAG_MONITOR_VDEV_CREATED,
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
|
||||
@@ -5032,7 +5032,7 @@ int ath11k_dp_rx_process_mon_rings(struc
|
||||
struct ath11k *ar = ath11k_ab_to_ar(ab, mac_id);
|
||||
int ret = 0;
|
||||
|
||||
- if (test_bit(ATH11K_FLAG_MONITOR_ENABLED, &ar->monitor_flags))
|
||||
+ if (test_bit(ATH11K_FLAG_MONITOR_STARTED, &ar->monitor_flags))
|
||||
ret = ath11k_dp_mon_process_rx(ab, mac_id, napi, budget);
|
||||
else
|
||||
ret = ath11k_dp_rx_process_mon_status(ab, mac_id, napi, budget);
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp_tx.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp_tx.c
|
||||
@@ -1076,12 +1076,16 @@ int ath11k_dp_tx_htt_monitor_mode_ring_c
|
||||
|
||||
for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
|
||||
ring_id = dp->rx_mon_status_refill_ring[i].refill_buf_ring.ring_id;
|
||||
- if (!reset)
|
||||
+ if (!reset) {
|
||||
tlv_filter.rx_filter =
|
||||
HTT_RX_MON_FILTER_TLV_FLAGS_MON_STATUS_RING;
|
||||
- else
|
||||
+ } else {
|
||||
tlv_filter = ath11k_mac_mon_status_filter_default;
|
||||
|
||||
+ if (ath11k_debugfs_is_extd_rx_stats_enabled(ar))
|
||||
+ tlv_filter.rx_filter = ath11k_debugfs_rx_filter(ar);
|
||||
+ }
|
||||
+
|
||||
ret = ath11k_dp_tx_htt_rx_filter_setup(ab, ring_id,
|
||||
dp->mac_id + i,
|
||||
HAL_RXDMA_MONITOR_STATUS,
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -715,22 +715,6 @@ void ath11k_mac_peer_cleanup_all(struct
|
||||
ar->num_stations = 0;
|
||||
}
|
||||
|
||||
-static int ath11k_monitor_vdev_up(struct ath11k *ar, int vdev_id)
|
||||
-{
|
||||
- int ret = 0;
|
||||
-
|
||||
- ret = ath11k_wmi_vdev_up(ar, vdev_id, 0, ar->mac_addr);
|
||||
- if (ret) {
|
||||
- ath11k_warn(ar->ab, "failed to put up monitor vdev %i: %d\n",
|
||||
- vdev_id, ret);
|
||||
- return ret;
|
||||
- }
|
||||
-
|
||||
- ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac monitor vdev %i started\n",
|
||||
- vdev_id);
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
static inline int ath11k_mac_vdev_setup_sync(struct ath11k *ar)
|
||||
{
|
||||
lockdep_assert_held(&ar->conf_mutex);
|
||||
@@ -2326,7 +2310,7 @@ static int ath11k_mac_config_obss_pd(str
|
||||
|
||||
/* Set and enable SRG/non-SRG OBSS PD Threshold */
|
||||
param_id = WMI_PDEV_PARAM_SET_CMD_OBSS_PD_THRESHOLD;
|
||||
- if (test_bit(ATH11K_FLAG_MONITOR_ENABLED, &ar->monitor_flags)) {
|
||||
+ if (test_bit(ATH11K_FLAG_MONITOR_STARTED, &ar->monitor_flags)) {
|
||||
ret = ath11k_wmi_pdev_set_param(ar, param_id, 0, pdev_id);
|
||||
if (ret)
|
||||
ath11k_warn(ar->ab,
|
||||
@@ -5100,8 +5084,8 @@ static int ath11k_mac_op_add_interface(s
|
||||
}
|
||||
|
||||
if (ar->num_created_vdevs > (TARGET_NUM_VDEVS - 1)) {
|
||||
- ath11k_warn(ab, "failed to create vdev, reached max vdev limit %d\n",
|
||||
- TARGET_NUM_VDEVS);
|
||||
+ ath11k_warn(ab, "failed to create vdev %u, reached max vdev limit %d\n",
|
||||
+ ar->num_created_vdevs, TARGET_NUM_VDEVS);
|
||||
ret = -EBUSY;
|
||||
goto err;
|
||||
}
|
||||
@@ -5141,6 +5125,7 @@ static int ath11k_mac_op_add_interface(s
|
||||
break;
|
||||
case NL80211_IFTYPE_MONITOR:
|
||||
arvif->vdev_type = WMI_VDEV_TYPE_MONITOR;
|
||||
+ ar->monitor_vdev_id = bit;
|
||||
break;
|
||||
default:
|
||||
WARN_ON(1);
|
||||
@@ -5242,6 +5227,9 @@ static int ath11k_mac_op_add_interface(s
|
||||
goto err_peer_del;
|
||||
}
|
||||
break;
|
||||
+ case WMI_VDEV_TYPE_MONITOR:
|
||||
+ set_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags);
|
||||
+ break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -5262,6 +5250,16 @@ static int ath11k_mac_op_add_interface(s
|
||||
|
||||
ath11k_dp_vdev_tx_attach(ar, arvif);
|
||||
|
||||
+ if (vif->type != NL80211_IFTYPE_MONITOR &&
|
||||
+ test_bit(ATH11K_FLAG_MONITOR_CONF_ENABLED, &ar->monitor_flags)) {
|
||||
+ ret = ath11k_mac_monitor_vdev_create(ar);
|
||||
+ if (ret) {
|
||||
+ ath11k_warn(ar->ab, "failed to create monitor vdev during add interface: %d",
|
||||
+ ret);
|
||||
+ goto err_peer_del;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
|
||||
return 0;
|
||||
@@ -5359,6 +5357,18 @@ static void ath11k_mac_op_remove_interfa
|
||||
ath11k_dbg(ab, ATH11K_DBG_MAC, "vdev %pM deleted, vdev_id %d\n",
|
||||
vif->addr, arvif->vdev_id);
|
||||
|
||||
+ if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) {
|
||||
+ clear_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags);
|
||||
+ ar->monitor_vdev_id = -1;
|
||||
+ } else if (test_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags) &&
|
||||
+ !test_bit(ATH11K_FLAG_MONITOR_STARTED, &ar->monitor_flags)) {
|
||||
+ ret = ath11k_mac_monitor_vdev_delete(ar);
|
||||
+ if (ret)
|
||||
+ /* continue even if there's an error */
|
||||
+ ath11k_warn(ar->ab, "failed to delete vdev monitor during remove interface: %d",
|
||||
+ ret);
|
||||
+ }
|
||||
+
|
||||
err_vdev_del:
|
||||
spin_lock_bh(&ar->data_lock);
|
||||
list_del(&arvif->list);
|
||||
@@ -5378,7 +5388,6 @@ err_vdev_del:
|
||||
|
||||
/* Recalc txpower for remaining vdev */
|
||||
ath11k_mac_txpower_recalc(ar);
|
||||
- clear_bit(ATH11K_FLAG_MONITOR_ENABLED, &ar->monitor_flags);
|
||||
|
||||
/* TODO: recal traffic pause state based on the available vdevs */
|
||||
|
||||
@@ -5401,8 +5410,6 @@ static void ath11k_mac_op_configure_filt
|
||||
u64 multicast)
|
||||
{
|
||||
struct ath11k *ar = hw->priv;
|
||||
- bool reset_flag = false;
|
||||
- int ret = 0;
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
|
||||
@@ -5410,23 +5417,6 @@ static void ath11k_mac_op_configure_filt
|
||||
*total_flags &= SUPPORTED_FILTERS;
|
||||
ar->filter_flags = *total_flags;
|
||||
|
||||
- /* For monitor mode */
|
||||
- reset_flag = !(ar->filter_flags & FIF_BCN_PRBRESP_PROMISC);
|
||||
-
|
||||
- ret = ath11k_dp_tx_htt_monitor_mode_ring_config(ar, reset_flag);
|
||||
- if (!ret) {
|
||||
- if (!reset_flag)
|
||||
- set_bit(ATH11K_FLAG_MONITOR_ENABLED, &ar->monitor_flags);
|
||||
- else
|
||||
- clear_bit(ATH11K_FLAG_MONITOR_ENABLED, &ar->monitor_flags);
|
||||
- } else {
|
||||
- ath11k_warn(ar->ab,
|
||||
- "fail to set monitor filter: %d\n", ret);
|
||||
- }
|
||||
- ath11k_dbg(ar->ab, ATH11K_DBG_MAC,
|
||||
- "changed_flags:0x%x, total_flags:0x%x, reset_flag:%d\n",
|
||||
- changed_flags, *total_flags, reset_flag);
|
||||
-
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
}
|
||||
|
||||
@@ -5617,7 +5607,9 @@ ath11k_mac_vdev_start_restart(struct ath
|
||||
return ret;
|
||||
}
|
||||
|
||||
- ar->num_started_vdevs++;
|
||||
+ if (!restart)
|
||||
+ ar->num_started_vdevs++;
|
||||
+
|
||||
ath11k_dbg(ab, ATH11K_DBG_MAC, "vdev %pM started, vdev_id %d\n",
|
||||
arvif->vif->addr, arvif->vdev_id);
|
||||
|
||||
@@ -5745,12 +5737,16 @@ ath11k_mac_update_vif_chan(struct ath11k
|
||||
struct ath11k_vif *arvif;
|
||||
int ret;
|
||||
int i;
|
||||
+ bool monitor_vif = false;
|
||||
|
||||
lockdep_assert_held(&ar->conf_mutex);
|
||||
|
||||
for (i = 0; i < n_vifs; i++) {
|
||||
arvif = (void *)vifs[i].vif->drv_priv;
|
||||
|
||||
+ if (vifs[i].vif->type == NL80211_IFTYPE_MONITOR)
|
||||
+ monitor_vif = true;
|
||||
+
|
||||
ath11k_dbg(ab, ATH11K_DBG_MAC,
|
||||
"mac chanctx switch vdev_id %i freq %u->%u width %d->%d\n",
|
||||
arvif->vdev_id,
|
||||
@@ -5771,6 +5767,8 @@ ath11k_mac_update_vif_chan(struct ath11k
|
||||
arvif->vdev_id, ret);
|
||||
continue;
|
||||
}
|
||||
+
|
||||
+ ar->num_started_vdevs--;
|
||||
}
|
||||
|
||||
/* All relevant vdevs are downed and associated channel resources
|
||||
@@ -5808,6 +5806,24 @@ ath11k_mac_update_vif_chan(struct ath11k
|
||||
continue;
|
||||
}
|
||||
}
|
||||
+
|
||||
+ /* Restart the internal monitor vdev on new channel */
|
||||
+ if (!monitor_vif &&
|
||||
+ test_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags)) {
|
||||
+ ret = ath11k_mac_monitor_stop(ar);
|
||||
+ if (ret) {
|
||||
+ ath11k_warn(ar->ab, "failed to stop monitor during vif channel update: %d",
|
||||
+ ret);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ ret = ath11k_mac_monitor_start(ar);
|
||||
+ if (ret) {
|
||||
+ ath11k_warn(ar->ab, "failed to start monitor during vif channel update: %d",
|
||||
+ ret);
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -5887,7 +5903,7 @@ static int ath11k_start_vdev_delay(struc
|
||||
}
|
||||
|
||||
if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) {
|
||||
- ret = ath11k_monitor_vdev_up(ar, arvif->vdev_id);
|
||||
+ ret = ath11k_wmi_vdev_up(ar, arvif->vdev_id, 0, ar->mac_addr);
|
||||
if (ret) {
|
||||
ath11k_warn(ab, "failed put monitor up: %d\n", ret);
|
||||
return ret;
|
||||
@@ -5947,6 +5963,18 @@ ath11k_mac_op_assign_vif_chanctx(struct
|
||||
}
|
||||
}
|
||||
|
||||
+ if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) {
|
||||
+ ret = ath11k_mac_monitor_start(ar);
|
||||
+ if (ret) {
|
||||
+ ath11k_warn(ar->ab, "failed to start monitor during vif channel context assignment: %d",
|
||||
+ ret);
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ arvif->is_started = true;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
ret = ath11k_mac_vdev_start(arvif, &ctx->def);
|
||||
if (ret) {
|
||||
ath11k_warn(ab, "failed to start vdev %i addr %pM on freq %d: %d\n",
|
||||
@@ -5954,14 +5982,19 @@ ath11k_mac_op_assign_vif_chanctx(struct
|
||||
ctx->def.chan->center_freq, ret);
|
||||
goto out;
|
||||
}
|
||||
- if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) {
|
||||
- ret = ath11k_monitor_vdev_up(ar, arvif->vdev_id);
|
||||
- if (ret)
|
||||
- goto out;
|
||||
- }
|
||||
|
||||
arvif->is_started = true;
|
||||
|
||||
+ if (arvif->vdev_type != WMI_VDEV_TYPE_MONITOR &&
|
||||
+ test_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags)) {
|
||||
+ ret = ath11k_mac_monitor_start(ar);
|
||||
+ if (ret) {
|
||||
+ ath11k_warn(ar->ab, "failed to start monitor during vif channel context assignment: %d",
|
||||
+ ret);
|
||||
+ goto out;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
/* TODO: Setup ps and cts/rts protection */
|
||||
|
||||
ret = 0;
|
||||
@@ -5995,6 +6028,20 @@ ath11k_mac_op_unassign_vif_chanctx(struc
|
||||
ath11k_peer_find_by_addr(ab, ar->mac_addr))
|
||||
ath11k_peer_delete(ar, arvif->vdev_id, ar->mac_addr);
|
||||
|
||||
+ if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) {
|
||||
+ ret = ath11k_mac_monitor_stop(ar);
|
||||
+ if (ret) {
|
||||
+ ath11k_warn(ar->ab, "failed to stop monitor during vif channel context unassignment: %d",
|
||||
+ ret);
|
||||
+ mutex_unlock(&ar->conf_mutex);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ arvif->is_started = false;
|
||||
+ mutex_unlock(&ar->conf_mutex);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
ret = ath11k_mac_vdev_stop(arvif);
|
||||
if (ret)
|
||||
ath11k_warn(ab, "failed to stop vdev %i: %d\n",
|
||||
@@ -6006,6 +6053,16 @@ ath11k_mac_op_unassign_vif_chanctx(struc
|
||||
arvif->vdev_type == WMI_VDEV_TYPE_MONITOR)
|
||||
ath11k_wmi_vdev_down(ar, arvif->vdev_id);
|
||||
|
||||
+ if (arvif->vdev_type != WMI_VDEV_TYPE_MONITOR &&
|
||||
+ ar->num_started_vdevs == 1 &&
|
||||
+ test_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags)) {
|
||||
+ ret = ath11k_mac_monitor_stop(ar);
|
||||
+ if (ret)
|
||||
+ /* continue even if there's an error */
|
||||
+ ath11k_warn(ar->ab, "failed to stop monitor during vif channel context unassignment: %d",
|
||||
+ ret);
|
||||
+ }
|
||||
+
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
}
|
||||
|
||||
@@ -7128,7 +7185,6 @@ int ath11k_mac_allocate(struct ath11k_ba
|
||||
INIT_WORK(&ar->wmi_mgmt_tx_work, ath11k_mgmt_over_wmi_tx_work);
|
||||
skb_queue_head_init(&ar->wmi_mgmt_tx_queue);
|
||||
|
||||
- clear_bit(ATH11K_FLAG_MONITOR_ENABLED, &ar->monitor_flags);
|
||||
clear_bit(ATH11K_FLAG_MONITOR_STARTED, &ar->monitor_flags);
|
||||
|
||||
ar->monitor_vdev_id = -1;
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,322 @@
|
||||
From f552d6fd2f27ce9430c74482c46272838e2de688 Mon Sep 17 00:00:00 2001
|
||||
From: P Praneesh <ppranees@codeaurora.org>
|
||||
Date: Fri, 24 Sep 2021 16:52:46 +0300
|
||||
Subject: [PATCH 011/120] ath11k: add support for 80P80 and 160 MHz bandwidth
|
||||
|
||||
For 160 MHz, nss_ratio_enabled flag is added to indicate firmware
|
||||
supports sending NSS ratio information from firmware as a part of
|
||||
service ready ext event. Extract this NSS ratio info from service
|
||||
ready ext event and save this information in ath11k_pdev_cap to
|
||||
calculate NSS ratio.
|
||||
|
||||
Current firmware configurations support two types of NSS ratio
|
||||
which is WMI_NSS_RATIO_1_NSS for QCN9074 and WMI_NSS_RATIO_1BY2_NSS
|
||||
for IPQ8074. Based on this two configuration, max supported
|
||||
NSS getting calculated.
|
||||
|
||||
Move ath11k_peer_assoc_h_phymode() before ath11k_peer_assoc_h_vht()
|
||||
to get arg->peer_phymode updated.
|
||||
|
||||
Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.4.0.1-00097-QCAHKSWPL_SILICONZ-1
|
||||
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-01467-QCAHKSWPL_SILICONZ-1
|
||||
|
||||
Co-developed-by: Ganesh Sesetti <gseset@codeaurora.org>
|
||||
Signed-off-by: Ganesh Sesetti <gseset@codeaurora.org>
|
||||
Co-developed-by: Sathishkumar Muruganandam <murugana@codeaurora.org>
|
||||
Signed-off-by: Sathishkumar Muruganandam <murugana@codeaurora.org>
|
||||
Signed-off-by: P Praneesh <ppranees@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20210721173615.75637-2-jouni@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/core.h | 2 +
|
||||
drivers/net/wireless/ath/ath11k/mac.c | 95 ++++++++++++++++++++++----
|
||||
drivers/net/wireless/ath/ath11k/mac.h | 3 +
|
||||
drivers/net/wireless/ath/ath11k/wmi.c | 20 +++++-
|
||||
drivers/net/wireless/ath/ath11k/wmi.h | 30 ++++++++
|
||||
5 files changed, 136 insertions(+), 14 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/core.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/core.h
|
||||
@@ -597,6 +597,8 @@ struct ath11k_pdev_cap {
|
||||
u32 tx_chain_mask_shift;
|
||||
u32 rx_chain_mask_shift;
|
||||
struct ath11k_band_cap band[NUM_NL80211_BANDS];
|
||||
+ bool nss_ratio_enabled;
|
||||
+ u8 nss_ratio_info;
|
||||
};
|
||||
|
||||
struct ath11k_pdev {
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -1581,6 +1581,34 @@ ath11k_peer_assoc_h_vht_limit(u16 tx_mcs
|
||||
return tx_mcs_set;
|
||||
}
|
||||
|
||||
+static u8 ath11k_get_nss_160mhz(struct ath11k *ar,
|
||||
+ u8 max_nss)
|
||||
+{
|
||||
+ u8 nss_ratio_info = ar->pdev->cap.nss_ratio_info;
|
||||
+ u8 max_sup_nss = 0;
|
||||
+
|
||||
+ switch (nss_ratio_info) {
|
||||
+ case WMI_NSS_RATIO_1BY2_NSS:
|
||||
+ max_sup_nss = max_nss >> 1;
|
||||
+ break;
|
||||
+ case WMI_NSS_RATIO_3BY4_NSS:
|
||||
+ ath11k_warn(ar->ab, "WMI_NSS_RATIO_3BY4_NSS not supported\n");
|
||||
+ break;
|
||||
+ case WMI_NSS_RATIO_1_NSS:
|
||||
+ max_sup_nss = max_nss;
|
||||
+ break;
|
||||
+ case WMI_NSS_RATIO_2_NSS:
|
||||
+ ath11k_warn(ar->ab, "WMI_NSS_RATIO_2_NSS not supported\n");
|
||||
+ break;
|
||||
+ default:
|
||||
+ ath11k_warn(ar->ab, "invalid nss ratio received from firmware: %d\n",
|
||||
+ nss_ratio_info);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return max_sup_nss;
|
||||
+}
|
||||
+
|
||||
static void ath11k_peer_assoc_h_vht(struct ath11k *ar,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
@@ -1595,6 +1623,7 @@ static void ath11k_peer_assoc_h_vht(stru
|
||||
u8 max_nss, vht_mcs;
|
||||
int i, vht_nss, nss_idx;
|
||||
bool user_rate_valid = true;
|
||||
+ u32 rx_nss, tx_nss, nss_160;
|
||||
|
||||
if (WARN_ON(ath11k_mac_vif_chan(vif, &def)))
|
||||
return;
|
||||
@@ -1687,10 +1716,29 @@ static void ath11k_peer_assoc_h_vht(stru
|
||||
/* TODO: Check */
|
||||
arg->tx_max_mcs_nss = 0xFF;
|
||||
|
||||
- ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac vht peer %pM max_mpdu %d flags 0x%x\n",
|
||||
- sta->addr, arg->peer_max_mpdu, arg->peer_flags);
|
||||
+ if (arg->peer_phymode == MODE_11AC_VHT160 ||
|
||||
+ arg->peer_phymode == MODE_11AC_VHT80_80) {
|
||||
+ tx_nss = ath11k_get_nss_160mhz(ar, max_nss);
|
||||
+ rx_nss = min(arg->peer_nss, tx_nss);
|
||||
+ arg->peer_bw_rxnss_override = ATH11K_BW_NSS_MAP_ENABLE;
|
||||
+
|
||||
+ if (!rx_nss) {
|
||||
+ ath11k_warn(ar->ab, "invalid max_nss\n");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (arg->peer_phymode == MODE_11AC_VHT160)
|
||||
+ nss_160 = FIELD_PREP(ATH11K_PEER_RX_NSS_160MHZ, rx_nss - 1);
|
||||
+ else
|
||||
+ nss_160 = FIELD_PREP(ATH11K_PEER_RX_NSS_80_80MHZ, rx_nss - 1);
|
||||
|
||||
- /* TODO: rxnss_override */
|
||||
+ arg->peer_bw_rxnss_override |= nss_160;
|
||||
+ }
|
||||
+
|
||||
+ ath11k_dbg(ar->ab, ATH11K_DBG_MAC,
|
||||
+ "mac vht peer %pM max_mpdu %d flags 0x%x nss_override 0x%x\n",
|
||||
+ sta->addr, arg->peer_max_mpdu, arg->peer_flags,
|
||||
+ arg->peer_bw_rxnss_override);
|
||||
}
|
||||
|
||||
static int ath11k_mac_get_max_he_mcs_map(u16 mcs_map, int nss)
|
||||
@@ -1774,6 +1822,7 @@ static void ath11k_peer_assoc_h_he(struc
|
||||
u16 he_tx_mcs = 0, v = 0;
|
||||
int i, he_nss, nss_idx;
|
||||
bool user_rate_valid = true;
|
||||
+ u32 rx_nss, tx_nss, nss_160;
|
||||
|
||||
if (WARN_ON(ath11k_mac_vif_chan(vif, &def)))
|
||||
return;
|
||||
@@ -1937,9 +1986,30 @@ static void ath11k_peer_assoc_h_he(struc
|
||||
}
|
||||
arg->peer_nss = min(sta->rx_nss, max_nss);
|
||||
|
||||
+ if (arg->peer_phymode == MODE_11AX_HE160 ||
|
||||
+ arg->peer_phymode == MODE_11AX_HE80_80) {
|
||||
+ tx_nss = ath11k_get_nss_160mhz(ar, max_nss);
|
||||
+ rx_nss = min(arg->peer_nss, tx_nss);
|
||||
+ arg->peer_bw_rxnss_override = ATH11K_BW_NSS_MAP_ENABLE;
|
||||
+
|
||||
+ if (!rx_nss) {
|
||||
+ ath11k_warn(ar->ab, "invalid max_nss\n");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (arg->peer_phymode == MODE_11AX_HE160)
|
||||
+ nss_160 = FIELD_PREP(ATH11K_PEER_RX_NSS_160MHZ, rx_nss - 1);
|
||||
+ else
|
||||
+ nss_160 = FIELD_PREP(ATH11K_PEER_RX_NSS_80_80MHZ, rx_nss - 1);
|
||||
+
|
||||
+ arg->peer_bw_rxnss_override |= nss_160;
|
||||
+ }
|
||||
+
|
||||
ath11k_dbg(ar->ab, ATH11K_DBG_MAC,
|
||||
- "mac he peer %pM nss %d mcs cnt %d\n",
|
||||
- sta->addr, arg->peer_nss, arg->peer_he_mcs_count);
|
||||
+ "mac he peer %pM nss %d mcs cnt %d nss_override 0x%x\n",
|
||||
+ sta->addr, arg->peer_nss,
|
||||
+ arg->peer_he_mcs_count,
|
||||
+ arg->peer_bw_rxnss_override);
|
||||
}
|
||||
|
||||
static void ath11k_peer_assoc_h_smps(struct ieee80211_sta *sta,
|
||||
@@ -2227,11 +2297,11 @@ static void ath11k_peer_assoc_prepare(st
|
||||
ath11k_peer_assoc_h_basic(ar, vif, sta, arg);
|
||||
ath11k_peer_assoc_h_crypto(ar, vif, sta, arg);
|
||||
ath11k_peer_assoc_h_rates(ar, vif, sta, arg);
|
||||
+ ath11k_peer_assoc_h_phymode(ar, vif, sta, arg);
|
||||
ath11k_peer_assoc_h_ht(ar, vif, sta, arg);
|
||||
ath11k_peer_assoc_h_vht(ar, vif, sta, arg);
|
||||
ath11k_peer_assoc_h_he(ar, vif, sta, arg);
|
||||
ath11k_peer_assoc_h_qos(ar, vif, sta, arg);
|
||||
- ath11k_peer_assoc_h_phymode(ar, vif, sta, arg);
|
||||
ath11k_peer_assoc_h_smps(sta, arg);
|
||||
|
||||
/* TODO: amsdu_disable req? */
|
||||
@@ -4427,11 +4497,6 @@ ath11k_create_vht_cap(struct ath11k *ar,
|
||||
|
||||
ath11k_set_vht_txbf_cap(ar, &vht_cap.cap);
|
||||
|
||||
- /* TODO: Enable back VHT160 mode once association issues are fixed */
|
||||
- /* Disabling VHT160 and VHT80+80 modes */
|
||||
- vht_cap.cap &= ~IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK;
|
||||
- vht_cap.cap &= ~IEEE80211_VHT_CAP_SHORT_GI_160;
|
||||
-
|
||||
rxmcs_map = 0;
|
||||
txmcs_map = 0;
|
||||
for (i = 0; i < 8; i++) {
|
||||
@@ -7345,7 +7410,9 @@ static int ath11k_mac_setup_iface_combin
|
||||
combinations[0].radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
|
||||
BIT(NL80211_CHAN_WIDTH_20) |
|
||||
BIT(NL80211_CHAN_WIDTH_40) |
|
||||
- BIT(NL80211_CHAN_WIDTH_80);
|
||||
+ BIT(NL80211_CHAN_WIDTH_80) |
|
||||
+ BIT(NL80211_CHAN_WIDTH_80P80) |
|
||||
+ BIT(NL80211_CHAN_WIDTH_160);
|
||||
|
||||
ar->hw->wiphy->iface_combinations = combinations;
|
||||
ar->hw->wiphy->n_iface_combinations = 1;
|
||||
@@ -7484,6 +7551,10 @@ static int __ath11k_mac_register(struct
|
||||
ieee80211_hw_set(ar->hw, SUPPORTS_TX_FRAG);
|
||||
ieee80211_hw_set(ar->hw, REPORTS_LOW_ACK);
|
||||
ieee80211_hw_set(ar->hw, SUPPORTS_TX_ENCAP_OFFLOAD);
|
||||
+
|
||||
+ if (cap->nss_ratio_enabled)
|
||||
+ ieee80211_hw_set(ar->hw, SUPPORTS_VHT_EXT_NSS_BW);
|
||||
+
|
||||
if (ht_cap & WMI_HT_CAP_ENABLED) {
|
||||
ieee80211_hw_set(ar->hw, AMPDU_AGGREGATION);
|
||||
ieee80211_hw_set(ar->hw, TX_AMPDU_SETUP_IN_HW);
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.h
|
||||
@@ -115,6 +115,9 @@ struct ath11k_generic_iter {
|
||||
#define WMI_MAX_SPATIAL_STREAM 3
|
||||
|
||||
#define ATH11K_CHAN_WIDTH_NUM 8
|
||||
+#define ATH11K_BW_NSS_MAP_ENABLE BIT(31)
|
||||
+#define ATH11K_PEER_RX_NSS_160MHZ GENMASK(2, 0)
|
||||
+#define ATH11K_PEER_RX_NSS_80_80MHZ GENMASK(5, 3)
|
||||
|
||||
#define ATH11K_OBSS_PD_MAX_THRESHOLD -82
|
||||
#define ATH11K_OBSS_PD_NON_SRG_MAX_THRESHOLD -62
|
||||
--- a/drivers/net/wireless/ath/ath11k/wmi.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
|
||||
@@ -360,6 +360,10 @@ ath11k_pull_mac_phy_cap_svc_ready_ext(st
|
||||
pdev_cap->he_mcs = mac_phy_caps->he_supp_mcs_5g;
|
||||
pdev_cap->tx_chain_mask = mac_phy_caps->tx_chain_mask_5g;
|
||||
pdev_cap->rx_chain_mask = mac_phy_caps->rx_chain_mask_5g;
|
||||
+ pdev_cap->nss_ratio_enabled =
|
||||
+ WMI_NSS_RATIO_ENABLE_DISABLE_GET(mac_phy_caps->nss_ratio);
|
||||
+ pdev_cap->nss_ratio_info =
|
||||
+ WMI_NSS_RATIO_INFO_GET(mac_phy_caps->nss_ratio);
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -783,14 +787,26 @@ int ath11k_wmi_vdev_down(struct ath11k *
|
||||
static void ath11k_wmi_put_wmi_channel(struct wmi_channel *chan,
|
||||
struct wmi_vdev_start_req_arg *arg)
|
||||
{
|
||||
+ u32 center_freq1 = arg->channel.band_center_freq1;
|
||||
+
|
||||
memset(chan, 0, sizeof(*chan));
|
||||
|
||||
chan->mhz = arg->channel.freq;
|
||||
chan->band_center_freq1 = arg->channel.band_center_freq1;
|
||||
- if (arg->channel.mode == MODE_11AC_VHT80_80)
|
||||
+
|
||||
+ if (arg->channel.mode == MODE_11AX_HE160) {
|
||||
+ if (arg->channel.freq > arg->channel.band_center_freq1)
|
||||
+ chan->band_center_freq1 = center_freq1 + 40;
|
||||
+ else
|
||||
+ chan->band_center_freq1 = center_freq1 - 40;
|
||||
+
|
||||
+ chan->band_center_freq2 = arg->channel.band_center_freq1;
|
||||
+
|
||||
+ } else if (arg->channel.mode == MODE_11AC_VHT80_80) {
|
||||
chan->band_center_freq2 = arg->channel.band_center_freq2;
|
||||
- else
|
||||
+ } else {
|
||||
chan->band_center_freq2 = 0;
|
||||
+ }
|
||||
|
||||
chan->info |= FIELD_PREP(WMI_CHAN_INFO_MODE, arg->channel.mode);
|
||||
if (arg->channel.passive)
|
||||
--- a/drivers/net/wireless/ath/ath11k/wmi.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/wmi.h
|
||||
@@ -2146,6 +2146,24 @@ enum wmi_direct_buffer_module {
|
||||
WMI_DIRECT_BUF_MAX
|
||||
};
|
||||
|
||||
+/* enum wmi_nss_ratio - NSS ratio received from FW during service ready ext
|
||||
+ * event
|
||||
+ * WMI_NSS_RATIO_1BY2_NSS -Max nss of 160MHz is equals to half of the max nss
|
||||
+ * of 80MHz
|
||||
+ * WMI_NSS_RATIO_3BY4_NSS - Max nss of 160MHz is equals to 3/4 of the max nss
|
||||
+ * of 80MHz
|
||||
+ * WMI_NSS_RATIO_1_NSS - Max nss of 160MHz is equals to the max nss of 80MHz
|
||||
+ * WMI_NSS_RATIO_2_NSS - Max nss of 160MHz is equals to two times the max
|
||||
+ * nss of 80MHz
|
||||
+ */
|
||||
+
|
||||
+enum wmi_nss_ratio {
|
||||
+ WMI_NSS_RATIO_1BY2_NSS = 0x0,
|
||||
+ WMI_NSS_RATIO_3BY4_NSS = 0x1,
|
||||
+ WMI_NSS_RATIO_1_NSS = 0x2,
|
||||
+ WMI_NSS_RATIO_2_NSS = 0x3,
|
||||
+};
|
||||
+
|
||||
struct wmi_host_pdev_band_to_mac {
|
||||
u32 pdev_id;
|
||||
u32 start_freq;
|
||||
@@ -2390,6 +2408,12 @@ struct wmi_hw_mode_capabilities {
|
||||
} __packed;
|
||||
|
||||
#define WMI_MAX_HECAP_PHY_SIZE (3)
|
||||
+#define WMI_NSS_RATIO_ENABLE_DISABLE_BITPOS BIT(0)
|
||||
+#define WMI_NSS_RATIO_ENABLE_DISABLE_GET(_val) \
|
||||
+ FIELD_GET(WMI_NSS_RATIO_ENABLE_DISABLE_BITPOS, _val)
|
||||
+#define WMI_NSS_RATIO_INFO_BITPOS GENMASK(4, 1)
|
||||
+#define WMI_NSS_RATIO_INFO_GET(_val) \
|
||||
+ FIELD_GET(WMI_NSS_RATIO_INFO_BITPOS, _val)
|
||||
|
||||
struct wmi_mac_phy_capabilities {
|
||||
u32 hw_mode_id;
|
||||
@@ -2423,6 +2447,12 @@ struct wmi_mac_phy_capabilities {
|
||||
u32 he_cap_info_2g_ext;
|
||||
u32 he_cap_info_5g_ext;
|
||||
u32 he_cap_info_internal;
|
||||
+ u32 wireless_modes;
|
||||
+ u32 low_2ghz_chan_freq;
|
||||
+ u32 high_2ghz_chan_freq;
|
||||
+ u32 low_5ghz_chan_freq;
|
||||
+ u32 high_5ghz_chan_freq;
|
||||
+ u32 nss_ratio;
|
||||
} __packed;
|
||||
|
||||
struct wmi_hal_reg_capabilities_ext {
|
@ -0,0 +1,165 @@
|
||||
From cc2ad7541486f1f755949c1ccd17e14a15bf1f4e Mon Sep 17 00:00:00 2001
|
||||
From: Karthikeyan Periyasamy <periyasa@codeaurora.org>
|
||||
Date: Fri, 24 Sep 2021 16:52:46 +0300
|
||||
Subject: [PATCH 012/120] ath11k: Refactor spectral FFT bin size
|
||||
|
||||
In IPQ8074, actual FFT bin size is two bytes but hardware reports it
|
||||
with extra pad size of two bytes for each FFT bin. So finally each FFT
|
||||
bin advertise as four bytes size in the collected data. This FFT pad is
|
||||
not advertised in IPQ6018 platform. To accommodate this different
|
||||
behavior across the platforms, introduce the hw param fft_pad_sz and use
|
||||
it in spectral process. Also group all the spectral params under the new
|
||||
structure in hw param structure for scalable in future.
|
||||
|
||||
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-01492-QCAHKSWPL_SILICONZ-1
|
||||
Tested-on: IPQ6018 hw1.0 AHB WLAN.HK.2.4.0.1-00330-QCAHKSWPL_SILICONZ-1
|
||||
|
||||
Signed-off-by: Karthikeyan Periyasamy <periyasa@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20210721180809.90960-2-jouni@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/core.c | 33 +++++++++++++++++++---
|
||||
drivers/net/wireless/ath/ath11k/hw.h | 6 +++-
|
||||
drivers/net/wireless/ath/ath11k/spectral.c | 13 ++++-----
|
||||
3 files changed, 40 insertions(+), 12 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/core.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/core.c
|
||||
@@ -59,7 +59,14 @@ static const struct ath11k_hw_params ath
|
||||
.vdev_start_delay = false,
|
||||
.htt_peer_map_v2 = true,
|
||||
.tcl_0_only = false,
|
||||
- .spectral_fft_sz = 2,
|
||||
+
|
||||
+ .spectral = {
|
||||
+ .fft_sz = 2,
|
||||
+ /* HW bug, expected BIN size is 2 bytes but HW report as 4 bytes.
|
||||
+ * so added pad size as 2 bytes to compensate the BIN size
|
||||
+ */
|
||||
+ .fft_pad_sz = 2,
|
||||
+ },
|
||||
|
||||
.interface_modes = BIT(NL80211_IFTYPE_STATION) |
|
||||
BIT(NL80211_IFTYPE_AP) |
|
||||
@@ -100,7 +107,11 @@ static const struct ath11k_hw_params ath
|
||||
.vdev_start_delay = false,
|
||||
.htt_peer_map_v2 = true,
|
||||
.tcl_0_only = false,
|
||||
- .spectral_fft_sz = 4,
|
||||
+
|
||||
+ .spectral = {
|
||||
+ .fft_sz = 4,
|
||||
+ .fft_pad_sz = 0,
|
||||
+ },
|
||||
|
||||
.interface_modes = BIT(NL80211_IFTYPE_STATION) |
|
||||
BIT(NL80211_IFTYPE_AP) |
|
||||
@@ -141,7 +152,11 @@ static const struct ath11k_hw_params ath
|
||||
.vdev_start_delay = true,
|
||||
.htt_peer_map_v2 = false,
|
||||
.tcl_0_only = true,
|
||||
- .spectral_fft_sz = 0,
|
||||
+
|
||||
+ .spectral = {
|
||||
+ .fft_sz = 0,
|
||||
+ .fft_pad_sz = 0,
|
||||
+ },
|
||||
|
||||
.interface_modes = BIT(NL80211_IFTYPE_STATION) |
|
||||
BIT(NL80211_IFTYPE_AP),
|
||||
@@ -180,6 +195,12 @@ static const struct ath11k_hw_params ath
|
||||
.vdev_start_delay = false,
|
||||
.htt_peer_map_v2 = true,
|
||||
.tcl_0_only = false,
|
||||
+
|
||||
+ .spectral = {
|
||||
+ .fft_sz = 0,
|
||||
+ .fft_pad_sz = 0,
|
||||
+ },
|
||||
+
|
||||
.interface_modes = BIT(NL80211_IFTYPE_STATION) |
|
||||
BIT(NL80211_IFTYPE_AP) |
|
||||
BIT(NL80211_IFTYPE_MESH_POINT),
|
||||
@@ -219,7 +240,11 @@ static const struct ath11k_hw_params ath
|
||||
.vdev_start_delay = true,
|
||||
.htt_peer_map_v2 = false,
|
||||
.tcl_0_only = true,
|
||||
- .spectral_fft_sz = 0,
|
||||
+
|
||||
+ .spectral = {
|
||||
+ .fft_sz = 0,
|
||||
+ .fft_pad_sz = 0,
|
||||
+ },
|
||||
|
||||
.interface_modes = BIT(NL80211_IFTYPE_STATION) |
|
||||
BIT(NL80211_IFTYPE_AP),
|
||||
--- a/drivers/net/wireless/ath/ath11k/hw.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/hw.h
|
||||
@@ -153,7 +153,11 @@ struct ath11k_hw_params {
|
||||
bool vdev_start_delay;
|
||||
bool htt_peer_map_v2;
|
||||
bool tcl_0_only;
|
||||
- u8 spectral_fft_sz;
|
||||
+
|
||||
+ struct {
|
||||
+ u8 fft_sz;
|
||||
+ u8 fft_pad_sz;
|
||||
+ } spectral;
|
||||
|
||||
u16 interface_modes;
|
||||
bool supports_monitor;
|
||||
--- a/drivers/net/wireless/ath/ath11k/spectral.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/spectral.c
|
||||
@@ -11,8 +11,6 @@
|
||||
#define ATH11K_SPECTRAL_EVENT_TIMEOUT_MS 1
|
||||
|
||||
#define ATH11K_SPECTRAL_DWORD_SIZE 4
|
||||
-/* HW bug, expected BIN size is 2 bytes but HW report as 4 bytes */
|
||||
-#define ATH11K_SPECTRAL_BIN_SIZE 4
|
||||
#define ATH11K_SPECTRAL_ATH11K_MIN_BINS 64
|
||||
#define ATH11K_SPECTRAL_ATH11K_MIN_IB_BINS 32
|
||||
#define ATH11K_SPECTRAL_ATH11K_MAX_IB_BINS 256
|
||||
@@ -585,12 +583,12 @@ int ath11k_spectral_process_fft(struct a
|
||||
struct spectral_tlv *tlv;
|
||||
int tlv_len, bin_len, num_bins;
|
||||
u16 length, freq;
|
||||
- u8 chan_width_mhz;
|
||||
+ u8 chan_width_mhz, bin_sz;
|
||||
int ret;
|
||||
|
||||
lockdep_assert_held(&ar->spectral.lock);
|
||||
|
||||
- if (!ab->hw_params.spectral_fft_sz) {
|
||||
+ if (!ab->hw_params.spectral.fft_sz) {
|
||||
ath11k_warn(ab, "invalid bin size type for hw rev %d\n",
|
||||
ab->hw_rev);
|
||||
return -EINVAL;
|
||||
@@ -608,7 +606,8 @@ int ath11k_spectral_process_fft(struct a
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
- num_bins = bin_len / ATH11K_SPECTRAL_BIN_SIZE;
|
||||
+ bin_sz = ab->hw_params.spectral.fft_sz + ab->hw_params.spectral.fft_pad_sz;
|
||||
+ num_bins = bin_len / bin_sz;
|
||||
/* Only In-band bins are useful to user for visualize */
|
||||
num_bins >>= 1;
|
||||
|
||||
@@ -658,7 +657,7 @@ int ath11k_spectral_process_fft(struct a
|
||||
fft_sample->freq2 = __cpu_to_be16(freq);
|
||||
|
||||
ath11k_spectral_parse_fft(fft_sample->data, fft_report->bins, num_bins,
|
||||
- ab->hw_params.spectral_fft_sz);
|
||||
+ ab->hw_params.spectral.fft_sz);
|
||||
|
||||
fft_sample->max_exp = ath11k_spectral_get_max_exp(fft_sample->max_index,
|
||||
search.peak_mag,
|
||||
@@ -966,7 +965,7 @@ int ath11k_spectral_init(struct ath11k_b
|
||||
ab->wmi_ab.svc_map))
|
||||
return 0;
|
||||
|
||||
- if (!ab->hw_params.spectral_fft_sz)
|
||||
+ if (!ab->hw_params.spectral.fft_sz)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < ab->num_radios; i++) {
|
@ -0,0 +1,168 @@
|
||||
From 1cae9c0009d35cec94ad8e1b06ebcb2d704626bf Mon Sep 17 00:00:00 2001
|
||||
From: Karthikeyan Periyasamy <periyasa@codeaurora.org>
|
||||
Date: Fri, 24 Sep 2021 16:52:46 +0300
|
||||
Subject: [PATCH 013/120] ath11k: Introduce spectral hw configurable param
|
||||
|
||||
Below parameters have been identified as configurable across the platforms.
|
||||
So to scale the spectral across the platforms, move these parameter
|
||||
into hw param.
|
||||
|
||||
1. Maximum FFT bins
|
||||
2. Summary report pad size
|
||||
3. FFT report header length
|
||||
|
||||
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-01492-QCAHKSWPL_SILICONZ-1
|
||||
Tested-on: IPQ6018 hw1.0 AHB WLAN.HK.2.4.0.1-00330-QCAHKSWPL_SILICONZ-1
|
||||
|
||||
Signed-off-by: Karthikeyan Periyasamy <periyasa@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20210721180809.90960-3-jouni@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/core.c | 12 +++++++++
|
||||
drivers/net/wireless/ath/ath11k/hw.h | 3 +++
|
||||
drivers/net/wireless/ath/ath11k/spectral.c | 29 +++++++++++-----------
|
||||
3 files changed, 30 insertions(+), 14 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/core.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/core.c
|
||||
@@ -66,6 +66,9 @@ static const struct ath11k_hw_params ath
|
||||
* so added pad size as 2 bytes to compensate the BIN size
|
||||
*/
|
||||
.fft_pad_sz = 2,
|
||||
+ .summary_pad_sz = 0,
|
||||
+ .fft_hdr_len = 16,
|
||||
+ .max_fft_bins = 512,
|
||||
},
|
||||
|
||||
.interface_modes = BIT(NL80211_IFTYPE_STATION) |
|
||||
@@ -111,6 +114,9 @@ static const struct ath11k_hw_params ath
|
||||
.spectral = {
|
||||
.fft_sz = 4,
|
||||
.fft_pad_sz = 0,
|
||||
+ .summary_pad_sz = 0,
|
||||
+ .fft_hdr_len = 16,
|
||||
+ .max_fft_bins = 512,
|
||||
},
|
||||
|
||||
.interface_modes = BIT(NL80211_IFTYPE_STATION) |
|
||||
@@ -156,6 +162,9 @@ static const struct ath11k_hw_params ath
|
||||
.spectral = {
|
||||
.fft_sz = 0,
|
||||
.fft_pad_sz = 0,
|
||||
+ .summary_pad_sz = 0,
|
||||
+ .fft_hdr_len = 0,
|
||||
+ .max_fft_bins = 0,
|
||||
},
|
||||
|
||||
.interface_modes = BIT(NL80211_IFTYPE_STATION) |
|
||||
@@ -244,6 +253,9 @@ static const struct ath11k_hw_params ath
|
||||
.spectral = {
|
||||
.fft_sz = 0,
|
||||
.fft_pad_sz = 0,
|
||||
+ .summary_pad_sz = 0,
|
||||
+ .fft_hdr_len = 0,
|
||||
+ .max_fft_bins = 0,
|
||||
},
|
||||
|
||||
.interface_modes = BIT(NL80211_IFTYPE_STATION) |
|
||||
--- a/drivers/net/wireless/ath/ath11k/hw.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/hw.h
|
||||
@@ -157,6 +157,9 @@ struct ath11k_hw_params {
|
||||
struct {
|
||||
u8 fft_sz;
|
||||
u8 fft_pad_sz;
|
||||
+ u8 summary_pad_sz;
|
||||
+ u8 fft_hdr_len;
|
||||
+ u16 max_fft_bins;
|
||||
} spectral;
|
||||
|
||||
u16 interface_modes;
|
||||
--- a/drivers/net/wireless/ath/ath11k/spectral.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/spectral.c
|
||||
@@ -11,20 +11,20 @@
|
||||
#define ATH11K_SPECTRAL_EVENT_TIMEOUT_MS 1
|
||||
|
||||
#define ATH11K_SPECTRAL_DWORD_SIZE 4
|
||||
-#define ATH11K_SPECTRAL_ATH11K_MIN_BINS 64
|
||||
-#define ATH11K_SPECTRAL_ATH11K_MIN_IB_BINS 32
|
||||
-#define ATH11K_SPECTRAL_ATH11K_MAX_IB_BINS 256
|
||||
+#define ATH11K_SPECTRAL_MIN_BINS 64
|
||||
+#define ATH11K_SPECTRAL_MIN_IB_BINS (ATH11K_SPECTRAL_MIN_BINS >> 1)
|
||||
+#define ATH11K_SPECTRAL_MAX_IB_BINS(x) ((x)->hw_params.spectral.max_fft_bins >> 1)
|
||||
|
||||
#define ATH11K_SPECTRAL_SCAN_COUNT_MAX 4095
|
||||
|
||||
/* Max channel computed by sum of 2g and 5g band channels */
|
||||
#define ATH11K_SPECTRAL_TOTAL_CHANNEL 41
|
||||
#define ATH11K_SPECTRAL_SAMPLES_PER_CHANNEL 70
|
||||
-#define ATH11K_SPECTRAL_PER_SAMPLE_SIZE (sizeof(struct fft_sample_ath11k) + \
|
||||
- ATH11K_SPECTRAL_ATH11K_MAX_IB_BINS)
|
||||
+#define ATH11K_SPECTRAL_PER_SAMPLE_SIZE(x) (sizeof(struct fft_sample_ath11k) + \
|
||||
+ ATH11K_SPECTRAL_MAX_IB_BINS(x))
|
||||
#define ATH11K_SPECTRAL_TOTAL_SAMPLE (ATH11K_SPECTRAL_TOTAL_CHANNEL * \
|
||||
ATH11K_SPECTRAL_SAMPLES_PER_CHANNEL)
|
||||
-#define ATH11K_SPECTRAL_SUB_BUFF_SIZE ATH11K_SPECTRAL_PER_SAMPLE_SIZE
|
||||
+#define ATH11K_SPECTRAL_SUB_BUFF_SIZE(x) ATH11K_SPECTRAL_PER_SAMPLE_SIZE(x)
|
||||
#define ATH11K_SPECTRAL_NUM_SUB_BUF ATH11K_SPECTRAL_TOTAL_SAMPLE
|
||||
|
||||
#define ATH11K_SPECTRAL_20MHZ 20
|
||||
@@ -446,8 +446,8 @@ static ssize_t ath11k_write_file_spectra
|
||||
if (kstrtoul(buf, 0, &val))
|
||||
return -EINVAL;
|
||||
|
||||
- if (val < ATH11K_SPECTRAL_ATH11K_MIN_BINS ||
|
||||
- val > SPECTRAL_ATH11K_MAX_NUM_BINS)
|
||||
+ if (val < ATH11K_SPECTRAL_MIN_BINS ||
|
||||
+ val > ar->ab->hw_params.spectral.max_fft_bins)
|
||||
return -EINVAL;
|
||||
|
||||
if (!is_power_of_2(val))
|
||||
@@ -598,7 +598,7 @@ int ath11k_spectral_process_fft(struct a
|
||||
tlv_len = FIELD_GET(SPECTRAL_TLV_HDR_LEN, __le32_to_cpu(tlv->header));
|
||||
/* convert Dword into bytes */
|
||||
tlv_len *= ATH11K_SPECTRAL_DWORD_SIZE;
|
||||
- bin_len = tlv_len - (sizeof(*fft_report) - sizeof(*tlv));
|
||||
+ bin_len = tlv_len - ab->hw_params.spectral.fft_hdr_len;
|
||||
|
||||
if (data_len < (bin_len + sizeof(*fft_report))) {
|
||||
ath11k_warn(ab, "mismatch in expected bin len %d and data len %d\n",
|
||||
@@ -611,8 +611,8 @@ int ath11k_spectral_process_fft(struct a
|
||||
/* Only In-band bins are useful to user for visualize */
|
||||
num_bins >>= 1;
|
||||
|
||||
- if (num_bins < ATH11K_SPECTRAL_ATH11K_MIN_IB_BINS ||
|
||||
- num_bins > ATH11K_SPECTRAL_ATH11K_MAX_IB_BINS ||
|
||||
+ if (num_bins < ATH11K_SPECTRAL_MIN_IB_BINS ||
|
||||
+ num_bins > ATH11K_SPECTRAL_MAX_IB_BINS(ab) ||
|
||||
!is_power_of_2(num_bins)) {
|
||||
ath11k_warn(ab, "Invalid num of bins %d\n", num_bins);
|
||||
return -EINVAL;
|
||||
@@ -693,7 +693,7 @@ static int ath11k_spectral_process_data(
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
- sample_sz = sizeof(*fft_sample) + ATH11K_SPECTRAL_ATH11K_MAX_IB_BINS;
|
||||
+ sample_sz = sizeof(*fft_sample) + ATH11K_SPECTRAL_MAX_IB_BINS(ab);
|
||||
fft_sample = kmalloc(sample_sz, GFP_ATOMIC);
|
||||
if (!fft_sample) {
|
||||
ret = -ENOBUFS;
|
||||
@@ -741,7 +741,8 @@ static int ath11k_spectral_process_data(
|
||||
* is 4 DWORD size (16 bytes).
|
||||
* Need to remove this workaround once HW bug fixed
|
||||
*/
|
||||
- tlv_len = sizeof(*summary) - sizeof(*tlv);
|
||||
+ tlv_len = sizeof(*summary) - sizeof(*tlv) +
|
||||
+ ab->hw_params.spectral.summary_pad_sz;
|
||||
|
||||
if (tlv_len < (sizeof(*summary) - sizeof(*tlv))) {
|
||||
ath11k_warn(ab, "failed to parse spectral summary at bytes %d tlv_len:%d\n",
|
||||
@@ -904,7 +905,7 @@ static inline int ath11k_spectral_debug_
|
||||
|
||||
ar->spectral.rfs_scan = relay_open("spectral_scan",
|
||||
ar->debug.debugfs_pdev,
|
||||
- ATH11K_SPECTRAL_SUB_BUFF_SIZE,
|
||||
+ ATH11K_SPECTRAL_SUB_BUFF_SIZE(ar->ab),
|
||||
ATH11K_SPECTRAL_NUM_SUB_BUF,
|
||||
&rfs_scan_cb, NULL);
|
||||
if (!ar->spectral.rfs_scan) {
|
@ -0,0 +1,33 @@
|
||||
From 6dfd20c8a6cd1fcf2c68d86c9d678f42535f6ade Mon Sep 17 00:00:00 2001
|
||||
From: Karthikeyan Periyasamy <periyasa@codeaurora.org>
|
||||
Date: Fri, 24 Sep 2021 16:52:46 +0300
|
||||
Subject: [PATCH 014/120] ath11k: Fix the spectral minimum FFT bin count
|
||||
|
||||
User was not able to configure the spectral with the FFT bin count 32.
|
||||
In all supported platforms, the expected minimum FFT bin count is 32 but
|
||||
it was wrongly defined as 64. This restrict the user to not configure
|
||||
down to the actually supported minimum FFT bin count. So update the
|
||||
minimum FFT bin count as 32.
|
||||
|
||||
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-01492-QCAHKSWPL_SILICONZ-1
|
||||
Tested-on: IPQ6018 hw1.0 AHB WLAN.HK.2.4.0.1-00330-QCAHKSWPL_SILICONZ-1
|
||||
|
||||
Signed-off-by: Karthikeyan Periyasamy <periyasa@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20210721180809.90960-4-jouni@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/spectral.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/spectral.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/spectral.c
|
||||
@@ -11,7 +11,7 @@
|
||||
#define ATH11K_SPECTRAL_EVENT_TIMEOUT_MS 1
|
||||
|
||||
#define ATH11K_SPECTRAL_DWORD_SIZE 4
|
||||
-#define ATH11K_SPECTRAL_MIN_BINS 64
|
||||
+#define ATH11K_SPECTRAL_MIN_BINS 32
|
||||
#define ATH11K_SPECTRAL_MIN_IB_BINS (ATH11K_SPECTRAL_MIN_BINS >> 1)
|
||||
#define ATH11K_SPECTRAL_MAX_IB_BINS(x) ((x)->hw_params.spectral.max_fft_bins >> 1)
|
||||
|
@ -0,0 +1,36 @@
|
||||
From b72e86c07e9881d249fbb7511060692f3fb6b687 Mon Sep 17 00:00:00 2001
|
||||
From: Karthikeyan Periyasamy <periyasa@codeaurora.org>
|
||||
Date: Fri, 24 Sep 2021 16:52:46 +0300
|
||||
Subject: [PATCH 015/120] ath11k: Add spectral scan support for QCN9074
|
||||
|
||||
Populate the below hw parameters as per the QCN9074 support
|
||||
1. FFT bin size as two bytes
|
||||
2. Maximum FFT bin count as 1024
|
||||
3. Summary report pad size as 16
|
||||
4. FFT report header length as 24
|
||||
|
||||
Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.4.0.1-01492-QCAHKSWPL_SILICONZ-1
|
||||
|
||||
Signed-off-by: Karthikeyan Periyasamy <periyasa@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20210721180809.90960-5-jouni@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/core.c | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/core.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/core.c
|
||||
@@ -206,8 +206,11 @@ static const struct ath11k_hw_params ath
|
||||
.tcl_0_only = false,
|
||||
|
||||
.spectral = {
|
||||
- .fft_sz = 0,
|
||||
+ .fft_sz = 2,
|
||||
.fft_pad_sz = 0,
|
||||
+ .summary_pad_sz = 16,
|
||||
+ .fft_hdr_len = 24,
|
||||
+ .max_fft_bins = 1024,
|
||||
},
|
||||
|
||||
.interface_modes = BIT(NL80211_IFTYPE_STATION) |
|
@ -0,0 +1,44 @@
|
||||
From eb19efed836a51ee30a602abe2dd21a97c47bbcc Mon Sep 17 00:00:00 2001
|
||||
From: Arnd Bergmann <arnd@arndb.de>
|
||||
Date: Fri, 24 Sep 2021 16:52:52 +0300
|
||||
Subject: [PATCH 016/120] ath11k: Wstringop-overread warning
|
||||
|
||||
gcc-11 with the kernel address sanitizer prints a warning for this
|
||||
driver:
|
||||
|
||||
In function 'ath11k_peer_assoc_h_vht',
|
||||
inlined from 'ath11k_peer_assoc_prepare' at drivers/net/wireless/ath/ath11k/mac.c:1632:2:
|
||||
drivers/net/wireless/ath/ath11k/mac.c:1164:13: error: 'ath11k_peer_assoc_h_vht_masked' reading 16 bytes from a region of size 4 [-Werror=stringop-overread]
|
||||
1164 | if (ath11k_peer_assoc_h_vht_masked(vht_mcs_mask))
|
||||
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
drivers/net/wireless/ath/ath11k/mac.c: In function 'ath11k_peer_assoc_prepare':
|
||||
drivers/net/wireless/ath/ath11k/mac.c:1164:13: note: referencing argument 1 of type 'const u16 *' {aka 'const short unsigned int *'}
|
||||
drivers/net/wireless/ath/ath11k/mac.c:969:1: note: in a call to function 'ath11k_peer_assoc_h_vht_masked'
|
||||
969 | ath11k_peer_assoc_h_vht_masked(const u16 vht_mcs_mask[NL80211_VHT_NSS_MAX])
|
||||
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
According to analysis from gcc developers, this is a glitch in the
|
||||
way gcc tracks the size of struct members. This should really get
|
||||
fixed in gcc, but it's also easy to work around this instance
|
||||
by changing the function prototype to no include the length of
|
||||
the array.
|
||||
|
||||
Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99673
|
||||
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20210322160253.4032422-5-arnd@kernel.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/mac.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -1401,7 +1401,7 @@ ath11k_peer_assoc_h_ht_masked(const u8 h
|
||||
}
|
||||
|
||||
static bool
|
||||
-ath11k_peer_assoc_h_vht_masked(const u16 vht_mcs_mask[NL80211_VHT_NSS_MAX])
|
||||
+ath11k_peer_assoc_h_vht_masked(const u16 vht_mcs_mask[])
|
||||
{
|
||||
int nss;
|
||||
|
@ -0,0 +1,114 @@
|
||||
From c72aa32d6d1c04fa83d4c0e6849e4e60d9d39ae4 Mon Sep 17 00:00:00 2001
|
||||
From: Anilkumar Kolli <akolli@codeaurora.org>
|
||||
Date: Tue, 28 Sep 2021 12:05:39 +0300
|
||||
Subject: [PATCH 017/120] ath11k: use hw_params to access board_size and
|
||||
cal_offset
|
||||
|
||||
Reuse board_size from hw_params, add cal_offset to hw params.
|
||||
This patch is clean up only, there is no change in functionality.
|
||||
|
||||
cal_size was unused, so remove that.
|
||||
|
||||
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-00009-QCAHKSWPL_SILICONZ-1
|
||||
Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.4.0.1-01838-QCAHKSWPL_SILICONZ-1
|
||||
|
||||
Signed-off-by: Anilkumar Kolli <akolli@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20210721201927.100369-2-jouni@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/core.c | 10 +++++-----
|
||||
drivers/net/wireless/ath/ath11k/hw.h | 2 +-
|
||||
drivers/net/wireless/ath/ath11k/qmi.c | 4 ++--
|
||||
drivers/net/wireless/ath/ath11k/qmi.h | 2 --
|
||||
4 files changed, 8 insertions(+), 10 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/core.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/core.c
|
||||
@@ -37,7 +37,7 @@ static const struct ath11k_hw_params ath
|
||||
.fw = {
|
||||
.dir = "IPQ8074/hw2.0",
|
||||
.board_size = 256 * 1024,
|
||||
- .cal_size = 256 * 1024,
|
||||
+ .cal_offset = 128 * 1024,
|
||||
},
|
||||
.max_radios = 3,
|
||||
.bdf_addr = 0x4B0C0000,
|
||||
@@ -88,7 +88,7 @@ static const struct ath11k_hw_params ath
|
||||
.fw = {
|
||||
.dir = "IPQ6018/hw1.0",
|
||||
.board_size = 256 * 1024,
|
||||
- .cal_size = 256 * 1024,
|
||||
+ .cal_offset = 128 * 1024,
|
||||
},
|
||||
.max_radios = 2,
|
||||
.bdf_addr = 0x4ABC0000,
|
||||
@@ -136,7 +136,7 @@ static const struct ath11k_hw_params ath
|
||||
.fw = {
|
||||
.dir = "QCA6390/hw2.0",
|
||||
.board_size = 256 * 1024,
|
||||
- .cal_size = 256 * 1024,
|
||||
+ .cal_offset = 128 * 1024,
|
||||
},
|
||||
.max_radios = 3,
|
||||
.bdf_addr = 0x4B0C0000,
|
||||
@@ -183,7 +183,7 @@ static const struct ath11k_hw_params ath
|
||||
.fw = {
|
||||
.dir = "QCN9074/hw1.0",
|
||||
.board_size = 256 * 1024,
|
||||
- .cal_size = 256 * 1024,
|
||||
+ .cal_offset = 128 * 1024,
|
||||
},
|
||||
.max_radios = 1,
|
||||
.single_pdev_only = false,
|
||||
@@ -230,7 +230,7 @@ static const struct ath11k_hw_params ath
|
||||
.fw = {
|
||||
.dir = "WCN6855/hw2.0",
|
||||
.board_size = 256 * 1024,
|
||||
- .cal_size = 256 * 1024,
|
||||
+ .cal_offset = 128 * 1024,
|
||||
},
|
||||
.max_radios = 3,
|
||||
.bdf_addr = 0x4B0C0000,
|
||||
--- a/drivers/net/wireless/ath/ath11k/hw.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/hw.h
|
||||
@@ -128,7 +128,7 @@ struct ath11k_hw_params {
|
||||
struct {
|
||||
const char *dir;
|
||||
size_t board_size;
|
||||
- size_t cal_size;
|
||||
+ size_t cal_offset;
|
||||
} fw;
|
||||
|
||||
const struct ath11k_hw_ops *hw_ops;
|
||||
--- a/drivers/net/wireless/ath/ath11k/qmi.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/qmi.c
|
||||
@@ -1953,7 +1953,7 @@ ath11k_qmi_prepare_bdf_download(struct a
|
||||
fw_size = min_t(u32, ab->hw_params.fw.board_size,
|
||||
fw_entry->size);
|
||||
|
||||
- memcpy_toio(bdf_addr + ATH11K_QMI_CALDATA_OFFSET,
|
||||
+ memcpy_toio(bdf_addr + ab->hw_params.fw.cal_offset,
|
||||
fw_entry->data, fw_size);
|
||||
|
||||
release_firmware(fw_entry);
|
||||
@@ -1979,7 +1979,7 @@ static int ath11k_qmi_load_bdf_fixed_add
|
||||
return -ENOMEM;
|
||||
memset(&resp, 0, sizeof(resp));
|
||||
|
||||
- bdf_addr = ioremap(ab->hw_params.bdf_addr, ATH11K_QMI_BDF_MAX_SIZE);
|
||||
+ bdf_addr = ioremap(ab->hw_params.bdf_addr, ab->hw_params.fw.board_size);
|
||||
if (!bdf_addr) {
|
||||
ath11k_warn(ab, "failed ioremap for board file\n");
|
||||
ret = -EIO;
|
||||
--- a/drivers/net/wireless/ath/ath11k/qmi.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/qmi.h
|
||||
@@ -13,8 +13,6 @@
|
||||
#define ATH11K_QMI_WLANFW_TIMEOUT_MS 5000
|
||||
#define ATH11K_QMI_MAX_BDF_FILE_NAME_SIZE 64
|
||||
#define ATH11K_QMI_CALDB_ADDRESS 0x4BA00000
|
||||
-#define ATH11K_QMI_BDF_MAX_SIZE (256 * 1024)
|
||||
-#define ATH11K_QMI_CALDATA_OFFSET (128 * 1024)
|
||||
#define ATH11K_QMI_WLANFW_MAX_BUILD_ID_LEN_V01 128
|
||||
#define ATH11K_QMI_WLFW_SERVICE_ID_V01 0x45
|
||||
#define ATH11K_QMI_WLFW_SERVICE_VERS_V01 0x01
|
@ -0,0 +1,357 @@
|
||||
From 336e7b53c82fc74d261024773a0fab43623a94fb Mon Sep 17 00:00:00 2001
|
||||
From: Anilkumar Kolli <akolli@codeaurora.org>
|
||||
Date: Tue, 28 Sep 2021 12:05:39 +0300
|
||||
Subject: [PATCH 018/120] ath11k: clean up BDF download functions
|
||||
|
||||
In current code, AHB/PCI uses two separate functions to download
|
||||
BDF file. Refactor code and make a common function to send QMI BDF
|
||||
download request for both AHB and PCI devices. This patch has no
|
||||
functional change.
|
||||
|
||||
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-00009-QCAHKSWPL_SILICONZ-1
|
||||
Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.4.0.1-01838-QCAHKSWPL_SILICONZ-1
|
||||
|
||||
Signed-off-by: Anilkumar Kolli <akolli@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20210721201927.100369-3-jouni@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/qmi.c | 248 +++++++++++---------------
|
||||
1 file changed, 101 insertions(+), 147 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/qmi.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/qmi.c
|
||||
@@ -1917,98 +1917,72 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static int
|
||||
-ath11k_qmi_prepare_bdf_download(struct ath11k_base *ab, int type,
|
||||
- struct qmi_wlanfw_bdf_download_req_msg_v01 *req,
|
||||
- void __iomem *bdf_addr)
|
||||
-{
|
||||
- const struct firmware *fw_entry;
|
||||
- struct ath11k_board_data bd;
|
||||
- u32 fw_size;
|
||||
- int ret;
|
||||
-
|
||||
- switch (type) {
|
||||
- case ATH11K_QMI_FILE_TYPE_BDF_GOLDEN:
|
||||
- memset(&bd, 0, sizeof(bd));
|
||||
-
|
||||
- ret = ath11k_core_fetch_bdf(ab, &bd);
|
||||
- if (ret) {
|
||||
- ath11k_warn(ab, "failed to load board file: %d\n", ret);
|
||||
- return ret;
|
||||
- }
|
||||
-
|
||||
- fw_size = min_t(u32, ab->hw_params.fw.board_size, bd.len);
|
||||
- memcpy_toio(bdf_addr, bd.data, fw_size);
|
||||
- ath11k_core_free_bdf(ab, &bd);
|
||||
- break;
|
||||
- case ATH11K_QMI_FILE_TYPE_CALDATA:
|
||||
- fw_entry = ath11k_core_firmware_request(ab, ATH11K_DEFAULT_CAL_FILE);
|
||||
- if (IS_ERR(fw_entry)) {
|
||||
- ret = PTR_ERR(fw_entry);
|
||||
- ath11k_warn(ab, "failed to load %s: %d\n",
|
||||
- ATH11K_DEFAULT_CAL_FILE, ret);
|
||||
- return ret;
|
||||
- }
|
||||
-
|
||||
- fw_size = min_t(u32, ab->hw_params.fw.board_size,
|
||||
- fw_entry->size);
|
||||
-
|
||||
- memcpy_toio(bdf_addr + ab->hw_params.fw.cal_offset,
|
||||
- fw_entry->data, fw_size);
|
||||
-
|
||||
- release_firmware(fw_entry);
|
||||
- break;
|
||||
- default:
|
||||
- return -EINVAL;
|
||||
- }
|
||||
-
|
||||
- req->total_size = fw_size;
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static int ath11k_qmi_load_bdf_fixed_addr(struct ath11k_base *ab)
|
||||
+static int ath11k_qmi_load_file_target_mem(struct ath11k_base *ab,
|
||||
+ const u8 *data, u32 len, u8 type)
|
||||
{
|
||||
struct qmi_wlanfw_bdf_download_req_msg_v01 *req;
|
||||
struct qmi_wlanfw_bdf_download_resp_msg_v01 resp;
|
||||
struct qmi_txn txn = {};
|
||||
+ const u8 *temp = data;
|
||||
void __iomem *bdf_addr = NULL;
|
||||
- int type, ret;
|
||||
+ int ret;
|
||||
+ u32 remaining = len;
|
||||
|
||||
req = kzalloc(sizeof(*req), GFP_KERNEL);
|
||||
if (!req)
|
||||
return -ENOMEM;
|
||||
+
|
||||
memset(&resp, 0, sizeof(resp));
|
||||
|
||||
- bdf_addr = ioremap(ab->hw_params.bdf_addr, ab->hw_params.fw.board_size);
|
||||
- if (!bdf_addr) {
|
||||
- ath11k_warn(ab, "failed ioremap for board file\n");
|
||||
- ret = -EIO;
|
||||
- goto out;
|
||||
+ if (ab->bus_params.fixed_bdf_addr) {
|
||||
+ bdf_addr = ioremap(ab->hw_params.bdf_addr, ab->hw_params.fw.board_size);
|
||||
+ if (!bdf_addr) {
|
||||
+ ath11k_warn(ab, "qmi ioremap error for bdf_addr\n");
|
||||
+ ret = -EIO;
|
||||
+ goto err_free_req;
|
||||
+ }
|
||||
}
|
||||
|
||||
- for (type = 0; type < ATH11K_QMI_MAX_FILE_TYPE; type++) {
|
||||
+ while (remaining) {
|
||||
req->valid = 1;
|
||||
req->file_id_valid = 1;
|
||||
req->file_id = ab->qmi.target.board_id;
|
||||
req->total_size_valid = 1;
|
||||
+ req->total_size = remaining;
|
||||
req->seg_id_valid = 1;
|
||||
- req->seg_id = type;
|
||||
- req->data_valid = 0;
|
||||
- req->data_len = ATH11K_QMI_MAX_BDF_FILE_NAME_SIZE;
|
||||
- req->bdf_type = 0;
|
||||
- req->bdf_type_valid = 0;
|
||||
+ req->data_valid = 1;
|
||||
+ req->bdf_type = type;
|
||||
+ req->bdf_type_valid = 1;
|
||||
req->end_valid = 1;
|
||||
- req->end = 1;
|
||||
+ req->end = 0;
|
||||
|
||||
- ret = ath11k_qmi_prepare_bdf_download(ab, type, req, bdf_addr);
|
||||
- if (ret < 0)
|
||||
- goto out_qmi_bdf;
|
||||
+ if (remaining > QMI_WLANFW_MAX_DATA_SIZE_V01) {
|
||||
+ req->data_len = QMI_WLANFW_MAX_DATA_SIZE_V01;
|
||||
+ } else {
|
||||
+ req->data_len = remaining;
|
||||
+ req->end = 1;
|
||||
+ }
|
||||
+
|
||||
+ if (ab->bus_params.fixed_bdf_addr) {
|
||||
+ req->data_valid = 0;
|
||||
+ req->end = 1;
|
||||
+ req->data_len = ATH11K_QMI_MAX_BDF_FILE_NAME_SIZE;
|
||||
+ } else {
|
||||
+ memcpy(req->data, temp, req->data_len);
|
||||
+ }
|
||||
+
|
||||
+ if (ab->bus_params.fixed_bdf_addr) {
|
||||
+ if (type == ATH11K_QMI_FILE_TYPE_CALDATA)
|
||||
+ bdf_addr += ab->hw_params.fw.cal_offset;
|
||||
+
|
||||
+ memcpy_toio(bdf_addr, temp, len);
|
||||
+ }
|
||||
|
||||
ret = qmi_txn_init(&ab->qmi.handle, &txn,
|
||||
qmi_wlanfw_bdf_download_resp_msg_v01_ei,
|
||||
&resp);
|
||||
if (ret < 0)
|
||||
- goto out_qmi_bdf;
|
||||
+ goto err_iounmap;
|
||||
|
||||
ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi bdf download req fixed addr type %d\n",
|
||||
type);
|
||||
@@ -2019,54 +1993,59 @@ static int ath11k_qmi_load_bdf_fixed_add
|
||||
qmi_wlanfw_bdf_download_req_msg_v01_ei, req);
|
||||
if (ret < 0) {
|
||||
qmi_txn_cancel(&txn);
|
||||
- goto out_qmi_bdf;
|
||||
+ goto err_iounmap;
|
||||
}
|
||||
|
||||
ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
|
||||
- if (ret < 0)
|
||||
- goto out_qmi_bdf;
|
||||
+ if (ret < 0) {
|
||||
+ ath11k_warn(ab, "failed to wait board file download request: %d\n",
|
||||
+ ret);
|
||||
+ goto err_iounmap;
|
||||
+ }
|
||||
|
||||
if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
|
||||
ath11k_warn(ab, "board file download request failed: %d %d\n",
|
||||
resp.resp.result, resp.resp.error);
|
||||
ret = -EINVAL;
|
||||
- goto out_qmi_bdf;
|
||||
+ goto err_iounmap;
|
||||
+ }
|
||||
+
|
||||
+ if (ab->bus_params.fixed_bdf_addr) {
|
||||
+ remaining = 0;
|
||||
+ } else {
|
||||
+ remaining -= req->data_len;
|
||||
+ temp += req->data_len;
|
||||
+ req->seg_id++;
|
||||
+ ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi bdf download request remaining %i\n",
|
||||
+ remaining);
|
||||
}
|
||||
}
|
||||
|
||||
-out_qmi_bdf:
|
||||
- iounmap(bdf_addr);
|
||||
-out:
|
||||
+err_iounmap:
|
||||
+ if (ab->bus_params.fixed_bdf_addr)
|
||||
+ iounmap(bdf_addr);
|
||||
+
|
||||
+err_free_req:
|
||||
kfree(req);
|
||||
+
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ath11k_qmi_load_bdf_qmi(struct ath11k_base *ab)
|
||||
{
|
||||
- struct qmi_wlanfw_bdf_download_req_msg_v01 *req;
|
||||
- struct qmi_wlanfw_bdf_download_resp_msg_v01 resp;
|
||||
+ char filename[ATH11K_QMI_MAX_BDF_FILE_NAME_SIZE];
|
||||
+ const struct firmware *fw_entry;
|
||||
struct ath11k_board_data bd;
|
||||
- unsigned int remaining;
|
||||
- struct qmi_txn txn = {};
|
||||
- int ret;
|
||||
- const u8 *temp;
|
||||
- int bdf_type;
|
||||
-
|
||||
- req = kzalloc(sizeof(*req), GFP_KERNEL);
|
||||
- if (!req)
|
||||
- return -ENOMEM;
|
||||
- memset(&resp, 0, sizeof(resp));
|
||||
+ u32 fw_size, file_type;
|
||||
+ int ret = 0, bdf_type;
|
||||
|
||||
memset(&bd, 0, sizeof(bd));
|
||||
ret = ath11k_core_fetch_bdf(ab, &bd);
|
||||
if (ret) {
|
||||
- ath11k_warn(ab, "failed to fetch board file: %d\n", ret);
|
||||
+ ath11k_warn(ab, "qmi failed to fetch board file: %d\n", ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
- temp = bd.data;
|
||||
- remaining = bd.len;
|
||||
-
|
||||
if (bd.len >= SELFMAG && memcmp(bd.data, ELFMAG, SELFMAG) == 0)
|
||||
bdf_type = ATH11K_QMI_BDF_TYPE_ELF;
|
||||
else
|
||||
@@ -2074,67 +2053,45 @@ static int ath11k_qmi_load_bdf_qmi(struc
|
||||
|
||||
ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi bdf_type %d\n", bdf_type);
|
||||
|
||||
- while (remaining) {
|
||||
- req->valid = 1;
|
||||
- req->file_id_valid = 1;
|
||||
- req->file_id = ab->qmi.target.board_id;
|
||||
- req->total_size_valid = 1;
|
||||
- req->total_size = bd.len;
|
||||
- req->seg_id_valid = 1;
|
||||
- req->data_valid = 1;
|
||||
- req->data_len = ATH11K_QMI_MAX_BDF_FILE_NAME_SIZE;
|
||||
- req->bdf_type = bdf_type;
|
||||
- req->bdf_type_valid = 1;
|
||||
- req->end_valid = 1;
|
||||
- req->end = 0;
|
||||
-
|
||||
- if (remaining > QMI_WLANFW_MAX_DATA_SIZE_V01) {
|
||||
- req->data_len = QMI_WLANFW_MAX_DATA_SIZE_V01;
|
||||
- } else {
|
||||
- req->data_len = remaining;
|
||||
- req->end = 1;
|
||||
- }
|
||||
-
|
||||
- memcpy(req->data, temp, req->data_len);
|
||||
-
|
||||
- ret = qmi_txn_init(&ab->qmi.handle, &txn,
|
||||
- qmi_wlanfw_bdf_download_resp_msg_v01_ei,
|
||||
- &resp);
|
||||
- if (ret < 0)
|
||||
- goto out_qmi_bdf;
|
||||
+ fw_size = bd.len;
|
||||
+ fw_size = min_t(u32, ab->hw_params.fw.board_size, bd.len);
|
||||
|
||||
- ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi bdf download request remaining %i\n",
|
||||
- remaining);
|
||||
+ ret = ath11k_qmi_load_file_target_mem(ab, bd.data, fw_size, bdf_type);
|
||||
+ if (ret < 0) {
|
||||
+ ath11k_warn(ab, "qmi failed to load bdf file\n");
|
||||
+ goto out;
|
||||
+ }
|
||||
|
||||
- ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
|
||||
- QMI_WLANFW_BDF_DOWNLOAD_REQ_V01,
|
||||
- QMI_WLANFW_BDF_DOWNLOAD_REQ_MSG_V01_MAX_LEN,
|
||||
- qmi_wlanfw_bdf_download_req_msg_v01_ei, req);
|
||||
- if (ret < 0) {
|
||||
- qmi_txn_cancel(&txn);
|
||||
- goto out_qmi_bdf;
|
||||
- }
|
||||
+ /* QCA6390 does not support cal data file, skip it */
|
||||
+ if (bdf_type == ATH11K_QMI_BDF_TYPE_ELF)
|
||||
+ goto out;
|
||||
|
||||
- ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
|
||||
- if (ret < 0)
|
||||
- goto out_qmi_bdf;
|
||||
+ file_type = ATH11K_QMI_FILE_TYPE_CALDATA;
|
||||
+ fw_entry = ath11k_core_firmware_request(ab, ATH11K_DEFAULT_CAL_FILE);
|
||||
+ if (IS_ERR(fw_entry)) {
|
||||
+ ret = PTR_ERR(fw_entry);
|
||||
+ ath11k_warn(ab,
|
||||
+ "qmi failed to load CAL data file:%s\n",
|
||||
+ filename);
|
||||
+ goto out;
|
||||
+ }
|
||||
|
||||
- if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
|
||||
- ath11k_warn(ab, "bdf download request failed: %d %d\n",
|
||||
- resp.resp.result, resp.resp.error);
|
||||
- ret = resp.resp.result;
|
||||
- goto out_qmi_bdf;
|
||||
- }
|
||||
- remaining -= req->data_len;
|
||||
- temp += req->data_len;
|
||||
- req->seg_id++;
|
||||
+ fw_size = min_t(u32, ab->hw_params.fw.board_size, fw_entry->size);
|
||||
+ ret = ath11k_qmi_load_file_target_mem(ab, fw_entry->data, fw_size, file_type);
|
||||
+ if (ret < 0) {
|
||||
+ ath11k_warn(ab, "qmi failed to load caldata\n");
|
||||
+ goto out_qmi_cal;
|
||||
}
|
||||
|
||||
-out_qmi_bdf:
|
||||
- ath11k_core_free_bdf(ab, &bd);
|
||||
+ ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi caldata downloaded: type: %u\n",
|
||||
+ file_type);
|
||||
|
||||
+out_qmi_cal:
|
||||
+ release_firmware(fw_entry);
|
||||
out:
|
||||
- kfree(req);
|
||||
+ ath11k_core_free_bdf(ab, &bd);
|
||||
+ ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi BDF download sequence completed\n");
|
||||
+
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -2519,10 +2476,7 @@ static int ath11k_qmi_event_load_bdf(str
|
||||
return ret;
|
||||
}
|
||||
|
||||
- if (ab->bus_params.fixed_bdf_addr)
|
||||
- ret = ath11k_qmi_load_bdf_fixed_addr(ab);
|
||||
- else
|
||||
- ret = ath11k_qmi_load_bdf_qmi(ab);
|
||||
+ ret = ath11k_qmi_load_bdf_qmi(ab);
|
||||
if (ret < 0) {
|
||||
ath11k_warn(ab, "failed to load board data file: %d\n", ret);
|
||||
return ret;
|
@ -0,0 +1,68 @@
|
||||
From e82dfe7b5608592c270cc69100cb4322069f949d Mon Sep 17 00:00:00 2001
|
||||
From: Anilkumar Kolli <akolli@codeaurora.org>
|
||||
Date: Tue, 28 Sep 2021 12:05:39 +0300
|
||||
Subject: [PATCH 019/120] ath11k: add caldata file for multiple radios
|
||||
|
||||
If multiple PCI cards are attached, each needs its own caldata file.
|
||||
|
||||
Added new Caldata file name,
|
||||
PCI Bus:
|
||||
cal-pci-0001:01:00.0.bin
|
||||
cal-pci-0000:01:00.0.bin
|
||||
AHB Bus:
|
||||
cal-ahb-c000000.wifi1.bin
|
||||
|
||||
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-00009-QCAHKSWPL_SILICONZ-1
|
||||
Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.4.0.1-01838-QCAHKSWPL_SILICONZ-1
|
||||
|
||||
Signed-off-by: Anilkumar Kolli <akolli@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20210721201927.100369-4-jouni@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/qmi.c | 13 +++++++++++--
|
||||
1 file changed, 11 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/qmi.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/qmi.c
|
||||
@@ -2033,6 +2033,7 @@ err_free_req:
|
||||
|
||||
static int ath11k_qmi_load_bdf_qmi(struct ath11k_base *ab)
|
||||
{
|
||||
+ struct device *dev = ab->dev;
|
||||
char filename[ATH11K_QMI_MAX_BDF_FILE_NAME_SIZE];
|
||||
const struct firmware *fw_entry;
|
||||
struct ath11k_board_data bd;
|
||||
@@ -2067,6 +2068,14 @@ static int ath11k_qmi_load_bdf_qmi(struc
|
||||
goto out;
|
||||
|
||||
file_type = ATH11K_QMI_FILE_TYPE_CALDATA;
|
||||
+
|
||||
+ /* cal-<bus>-<id>.bin */
|
||||
+ snprintf(filename, sizeof(filename), "cal-%s-%s.bin",
|
||||
+ ath11k_bus_str(ab->hif.bus), dev_name(dev));
|
||||
+ fw_entry = ath11k_core_firmware_request(ab, filename);
|
||||
+ if (!IS_ERR(fw_entry))
|
||||
+ goto success;
|
||||
+
|
||||
fw_entry = ath11k_core_firmware_request(ab, ATH11K_DEFAULT_CAL_FILE);
|
||||
if (IS_ERR(fw_entry)) {
|
||||
ret = PTR_ERR(fw_entry);
|
||||
@@ -2076,6 +2085,7 @@ static int ath11k_qmi_load_bdf_qmi(struc
|
||||
goto out;
|
||||
}
|
||||
|
||||
+success:
|
||||
fw_size = min_t(u32, ab->hw_params.fw.board_size, fw_entry->size);
|
||||
ret = ath11k_qmi_load_file_target_mem(ab, fw_entry->data, fw_size, file_type);
|
||||
if (ret < 0) {
|
||||
@@ -2083,8 +2093,7 @@ static int ath11k_qmi_load_bdf_qmi(struc
|
||||
goto out_qmi_cal;
|
||||
}
|
||||
|
||||
- ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi caldata downloaded: type: %u\n",
|
||||
- file_type);
|
||||
+ ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi caldata type: %u\n", file_type);
|
||||
|
||||
out_qmi_cal:
|
||||
release_firmware(fw_entry);
|
@ -0,0 +1,282 @@
|
||||
From 4ba3b05ebd0c3e98c7dd8c7ee03aed9d80299b79 Mon Sep 17 00:00:00 2001
|
||||
From: Anilkumar Kolli <akolli@codeaurora.org>
|
||||
Date: Tue, 28 Sep 2021 12:05:39 +0300
|
||||
Subject: [PATCH 020/120] ath11k: add caldata download support from EEPROM
|
||||
|
||||
Firmware updates EEPROM support capability in QMI FW caps, send QMI BDF
|
||||
download request message with file type EEPROM, to get caldata download
|
||||
from EEPROM. Firmware takes more time to update cal data from EEPROM, so
|
||||
increase QMI timeout.
|
||||
|
||||
Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.4.0.1-01838-QCAHKSWPL_SILICONZ-1
|
||||
|
||||
Signed-off-by: Anilkumar Kolli <akolli@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20210721201927.100369-5-jouni@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/qmi.c | 139 +++++++++++++++++++++-----
|
||||
drivers/net/wireless/ath/ath11k/qmi.h | 16 ++-
|
||||
2 files changed, 127 insertions(+), 28 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/qmi.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/qmi.c
|
||||
@@ -951,6 +951,78 @@ static struct qmi_elem_info qmi_wlanfw_c
|
||||
num_macs),
|
||||
},
|
||||
{
|
||||
+ .data_type = QMI_OPT_FLAG,
|
||||
+ .elem_len = 1,
|
||||
+ .elem_size = sizeof(u8),
|
||||
+ .array_type = NO_ARRAY,
|
||||
+ .tlv_type = 0x16,
|
||||
+ .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
|
||||
+ voltage_mv_valid),
|
||||
+ },
|
||||
+ {
|
||||
+ .data_type = QMI_UNSIGNED_4_BYTE,
|
||||
+ .elem_len = 1,
|
||||
+ .elem_size = sizeof(u32),
|
||||
+ .array_type = NO_ARRAY,
|
||||
+ .tlv_type = 0x16,
|
||||
+ .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
|
||||
+ voltage_mv),
|
||||
+ },
|
||||
+ {
|
||||
+ .data_type = QMI_OPT_FLAG,
|
||||
+ .elem_len = 1,
|
||||
+ .elem_size = sizeof(u8),
|
||||
+ .array_type = NO_ARRAY,
|
||||
+ .tlv_type = 0x17,
|
||||
+ .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
|
||||
+ time_freq_hz_valid),
|
||||
+ },
|
||||
+ {
|
||||
+ .data_type = QMI_UNSIGNED_4_BYTE,
|
||||
+ .elem_len = 1,
|
||||
+ .elem_size = sizeof(u32),
|
||||
+ .array_type = NO_ARRAY,
|
||||
+ .tlv_type = 0x17,
|
||||
+ .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
|
||||
+ time_freq_hz),
|
||||
+ },
|
||||
+ {
|
||||
+ .data_type = QMI_OPT_FLAG,
|
||||
+ .elem_len = 1,
|
||||
+ .elem_size = sizeof(u8),
|
||||
+ .array_type = NO_ARRAY,
|
||||
+ .tlv_type = 0x18,
|
||||
+ .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
|
||||
+ otp_version_valid),
|
||||
+ },
|
||||
+ {
|
||||
+ .data_type = QMI_UNSIGNED_4_BYTE,
|
||||
+ .elem_len = 1,
|
||||
+ .elem_size = sizeof(u32),
|
||||
+ .array_type = NO_ARRAY,
|
||||
+ .tlv_type = 0x18,
|
||||
+ .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
|
||||
+ otp_version),
|
||||
+ },
|
||||
+ {
|
||||
+ .data_type = QMI_OPT_FLAG,
|
||||
+ .elem_len = 1,
|
||||
+ .elem_size = sizeof(u8),
|
||||
+ .array_type = NO_ARRAY,
|
||||
+ .tlv_type = 0x19,
|
||||
+ .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
|
||||
+ eeprom_read_timeout_valid),
|
||||
+ },
|
||||
+ {
|
||||
+ .data_type = QMI_UNSIGNED_4_BYTE,
|
||||
+ .elem_len = 1,
|
||||
+ .elem_size = sizeof(u32),
|
||||
+ .array_type = NO_ARRAY,
|
||||
+ .tlv_type = 0x19,
|
||||
+ .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
|
||||
+ eeprom_read_timeout),
|
||||
+ },
|
||||
+ {
|
||||
.data_type = QMI_EOTI,
|
||||
.array_type = NO_ARRAY,
|
||||
.tlv_type = QMI_COMMON_TLV_TYPE,
|
||||
@@ -1846,8 +1918,8 @@ static int ath11k_qmi_request_target_cap
|
||||
memset(&req, 0, sizeof(req));
|
||||
memset(&resp, 0, sizeof(resp));
|
||||
|
||||
- ret = qmi_txn_init(&ab->qmi.handle, &txn,
|
||||
- qmi_wlanfw_cap_resp_msg_v01_ei, &resp);
|
||||
+ ret = qmi_txn_init(&ab->qmi.handle, &txn, qmi_wlanfw_cap_resp_msg_v01_ei,
|
||||
+ &resp);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
@@ -1900,6 +1972,12 @@ static int ath11k_qmi_request_target_cap
|
||||
strlcpy(ab->qmi.target.fw_build_id, resp.fw_build_id,
|
||||
sizeof(ab->qmi.target.fw_build_id));
|
||||
|
||||
+ if (resp.eeprom_read_timeout_valid) {
|
||||
+ ab->qmi.target.eeprom_caldata =
|
||||
+ resp.eeprom_read_timeout;
|
||||
+ ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi cal data supported from eeprom\n");
|
||||
+ }
|
||||
+
|
||||
ath11k_info(ab, "chip_id 0x%x chip_family 0x%x board_id 0x%x soc_id 0x%x\n",
|
||||
ab->qmi.target.chip_id, ab->qmi.target.chip_family,
|
||||
ab->qmi.target.board_id, ab->qmi.target.soc_id);
|
||||
@@ -1963,7 +2041,8 @@ static int ath11k_qmi_load_file_target_m
|
||||
req->end = 1;
|
||||
}
|
||||
|
||||
- if (ab->bus_params.fixed_bdf_addr) {
|
||||
+ if (ab->bus_params.fixed_bdf_addr ||
|
||||
+ type == ATH11K_QMI_FILE_TYPE_EEPROM) {
|
||||
req->data_valid = 0;
|
||||
req->end = 1;
|
||||
req->data_len = ATH11K_QMI_MAX_BDF_FILE_NAME_SIZE;
|
||||
@@ -2010,7 +2089,8 @@ static int ath11k_qmi_load_file_target_m
|
||||
goto err_iounmap;
|
||||
}
|
||||
|
||||
- if (ab->bus_params.fixed_bdf_addr) {
|
||||
+ if (ab->bus_params.fixed_bdf_addr ||
|
||||
+ type == ATH11K_QMI_FILE_TYPE_EEPROM) {
|
||||
remaining = 0;
|
||||
} else {
|
||||
remaining -= req->data_len;
|
||||
@@ -2039,6 +2119,7 @@ static int ath11k_qmi_load_bdf_qmi(struc
|
||||
struct ath11k_board_data bd;
|
||||
u32 fw_size, file_type;
|
||||
int ret = 0, bdf_type;
|
||||
+ const u8 *tmp;
|
||||
|
||||
memset(&bd, 0, sizeof(bd));
|
||||
ret = ath11k_core_fetch_bdf(ab, &bd);
|
||||
@@ -2063,31 +2144,38 @@ static int ath11k_qmi_load_bdf_qmi(struc
|
||||
goto out;
|
||||
}
|
||||
|
||||
- /* QCA6390 does not support cal data file, skip it */
|
||||
+ /* QCA6390 does not support cal data, skip it */
|
||||
if (bdf_type == ATH11K_QMI_BDF_TYPE_ELF)
|
||||
goto out;
|
||||
|
||||
- file_type = ATH11K_QMI_FILE_TYPE_CALDATA;
|
||||
+ if (ab->qmi.target.eeprom_caldata) {
|
||||
+ file_type = ATH11K_QMI_FILE_TYPE_EEPROM;
|
||||
+ tmp = filename;
|
||||
+ fw_size = ATH11K_QMI_MAX_BDF_FILE_NAME_SIZE;
|
||||
+ } else {
|
||||
+ file_type = ATH11K_QMI_FILE_TYPE_CALDATA;
|
||||
|
||||
- /* cal-<bus>-<id>.bin */
|
||||
- snprintf(filename, sizeof(filename), "cal-%s-%s.bin",
|
||||
- ath11k_bus_str(ab->hif.bus), dev_name(dev));
|
||||
- fw_entry = ath11k_core_firmware_request(ab, filename);
|
||||
- if (!IS_ERR(fw_entry))
|
||||
- goto success;
|
||||
-
|
||||
- fw_entry = ath11k_core_firmware_request(ab, ATH11K_DEFAULT_CAL_FILE);
|
||||
- if (IS_ERR(fw_entry)) {
|
||||
- ret = PTR_ERR(fw_entry);
|
||||
- ath11k_warn(ab,
|
||||
- "qmi failed to load CAL data file:%s\n",
|
||||
- filename);
|
||||
- goto out;
|
||||
+ /* cal-<bus>-<id>.bin */
|
||||
+ snprintf(filename, sizeof(filename), "cal-%s-%s.bin",
|
||||
+ ath11k_bus_str(ab->hif.bus), dev_name(dev));
|
||||
+ fw_entry = ath11k_core_firmware_request(ab, filename);
|
||||
+ if (!IS_ERR(fw_entry))
|
||||
+ goto success;
|
||||
+
|
||||
+ fw_entry = ath11k_core_firmware_request(ab, ATH11K_DEFAULT_CAL_FILE);
|
||||
+ if (IS_ERR(fw_entry)) {
|
||||
+ ret = PTR_ERR(fw_entry);
|
||||
+ ath11k_warn(ab,
|
||||
+ "qmi failed to load CAL data file:%s\n",
|
||||
+ filename);
|
||||
+ goto out;
|
||||
+ }
|
||||
+success:
|
||||
+ fw_size = min_t(u32, ab->hw_params.fw.board_size, fw_entry->size);
|
||||
+ tmp = fw_entry->data;
|
||||
}
|
||||
|
||||
-success:
|
||||
- fw_size = min_t(u32, ab->hw_params.fw.board_size, fw_entry->size);
|
||||
- ret = ath11k_qmi_load_file_target_mem(ab, fw_entry->data, fw_size, file_type);
|
||||
+ ret = ath11k_qmi_load_file_target_mem(ab, tmp, fw_size, file_type);
|
||||
if (ret < 0) {
|
||||
ath11k_warn(ab, "qmi failed to load caldata\n");
|
||||
goto out_qmi_cal;
|
||||
@@ -2096,7 +2184,8 @@ success:
|
||||
ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi caldata type: %u\n", file_type);
|
||||
|
||||
out_qmi_cal:
|
||||
- release_firmware(fw_entry);
|
||||
+ if (!ab->qmi.target.eeprom_caldata)
|
||||
+ release_firmware(fw_entry);
|
||||
out:
|
||||
ath11k_core_free_bdf(ab, &bd);
|
||||
ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi BDF download sequence completed\n");
|
||||
--- a/drivers/net/wireless/ath/ath11k/qmi.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/qmi.h
|
||||
@@ -10,7 +10,7 @@
|
||||
#include <linux/soc/qcom/qmi.h>
|
||||
|
||||
#define ATH11K_HOST_VERSION_STRING "WIN"
|
||||
-#define ATH11K_QMI_WLANFW_TIMEOUT_MS 5000
|
||||
+#define ATH11K_QMI_WLANFW_TIMEOUT_MS 10000
|
||||
#define ATH11K_QMI_MAX_BDF_FILE_NAME_SIZE 64
|
||||
#define ATH11K_QMI_CALDB_ADDRESS 0x4BA00000
|
||||
#define ATH11K_QMI_WLANFW_MAX_BUILD_ID_LEN_V01 128
|
||||
@@ -42,6 +42,7 @@ struct ath11k_base;
|
||||
enum ath11k_qmi_file_type {
|
||||
ATH11K_QMI_FILE_TYPE_BDF_GOLDEN,
|
||||
ATH11K_QMI_FILE_TYPE_CALDATA,
|
||||
+ ATH11K_QMI_FILE_TYPE_EEPROM,
|
||||
ATH11K_QMI_MAX_FILE_TYPE,
|
||||
};
|
||||
|
||||
@@ -102,6 +103,7 @@ struct target_info {
|
||||
u32 board_id;
|
||||
u32 soc_id;
|
||||
u32 fw_version;
|
||||
+ u32 eeprom_caldata;
|
||||
char fw_build_timestamp[ATH11K_QMI_WLANFW_MAX_TIMESTAMP_LEN_V01 + 1];
|
||||
char fw_build_id[ATH11K_QMI_WLANFW_MAX_BUILD_ID_LEN_V01 + 1];
|
||||
char bdf_ext[ATH11K_QMI_BDF_EXT_STR_LENGTH];
|
||||
@@ -133,7 +135,7 @@ struct ath11k_qmi {
|
||||
wait_queue_head_t cold_boot_waitq;
|
||||
};
|
||||
|
||||
-#define QMI_WLANFW_HOST_CAP_REQ_MSG_V01_MAX_LEN 189
|
||||
+#define QMI_WLANFW_HOST_CAP_REQ_MSG_V01_MAX_LEN 261
|
||||
#define QMI_WLANFW_HOST_CAP_REQ_V01 0x0034
|
||||
#define QMI_WLANFW_HOST_CAP_RESP_MSG_V01_MAX_LEN 7
|
||||
#define QMI_WLFW_HOST_CAP_RESP_V01 0x0034
|
||||
@@ -283,7 +285,7 @@ struct qmi_wlanfw_fw_cold_cal_done_ind_m
|
||||
};
|
||||
|
||||
#define QMI_WLANFW_CAP_REQ_MSG_V01_MAX_LEN 0
|
||||
-#define QMI_WLANFW_CAP_RESP_MSG_V01_MAX_LEN 207
|
||||
+#define QMI_WLANFW_CAP_RESP_MSG_V01_MAX_LEN 235
|
||||
#define QMI_WLANFW_CAP_REQ_V01 0x0024
|
||||
#define QMI_WLANFW_CAP_RESP_V01 0x0024
|
||||
|
||||
@@ -364,6 +366,14 @@ struct qmi_wlanfw_cap_resp_msg_v01 {
|
||||
char fw_build_id[ATH11K_QMI_WLANFW_MAX_BUILD_ID_LEN_V01 + 1];
|
||||
u8 num_macs_valid;
|
||||
u8 num_macs;
|
||||
+ u8 voltage_mv_valid;
|
||||
+ u32 voltage_mv;
|
||||
+ u8 time_freq_hz_valid;
|
||||
+ u32 time_freq_hz;
|
||||
+ u8 otp_version_valid;
|
||||
+ u32 otp_version;
|
||||
+ u8 eeprom_read_timeout_valid;
|
||||
+ u32 eeprom_read_timeout;
|
||||
};
|
||||
|
||||
struct qmi_wlanfw_cap_req_msg_v01 {
|
@ -0,0 +1,145 @@
|
||||
From b2549465cdeac3847487ce88b15ca47c37b60b88 Mon Sep 17 00:00:00 2001
|
||||
From: "Gustavo A. R. Silva" <gustavoars@kernel.org>
|
||||
Date: Tue, 28 Sep 2021 12:05:44 +0300
|
||||
Subject: [PATCH 021/120] ath11k: Replace one-element array with flexible-array
|
||||
member
|
||||
|
||||
There is a regular need in the kernel to provide a way to declare having a
|
||||
dynamically sized set of trailing elements in a structure. Kernel code
|
||||
should always use "flexible array members"[1] for these cases. The older
|
||||
style of one-element or zero-length arrays should no longer be used[2].
|
||||
|
||||
Refactor the code a bit according to the use of a flexible-array member in
|
||||
struct scan_chan_list_params instead of a one-element array, and use the
|
||||
struct_size() helper.
|
||||
|
||||
Also, save 25 (too many) bytes that were being allocated:
|
||||
|
||||
$ pahole -C channel_param drivers/net/wireless/ath/ath11k/reg.o
|
||||
struct channel_param {
|
||||
u8 chan_id; /* 0 1 */
|
||||
u8 pwr; /* 1 1 */
|
||||
u32 mhz; /* 2 4 */
|
||||
|
||||
/* Bitfield combined with next fields */
|
||||
|
||||
u32 half_rate:1; /* 4:16 4 */
|
||||
u32 quarter_rate:1; /* 4:17 4 */
|
||||
u32 dfs_set:1; /* 4:18 4 */
|
||||
u32 dfs_set_cfreq2:1; /* 4:19 4 */
|
||||
u32 is_chan_passive:1; /* 4:20 4 */
|
||||
u32 allow_ht:1; /* 4:21 4 */
|
||||
u32 allow_vht:1; /* 4:22 4 */
|
||||
u32 allow_he:1; /* 4:23 4 */
|
||||
u32 set_agile:1; /* 4:24 4 */
|
||||
u32 psc_channel:1; /* 4:25 4 */
|
||||
|
||||
/* XXX 6 bits hole, try to pack */
|
||||
|
||||
u32 phy_mode; /* 8 4 */
|
||||
u32 cfreq1; /* 12 4 */
|
||||
u32 cfreq2; /* 16 4 */
|
||||
char maxpower; /* 20 1 */
|
||||
char minpower; /* 21 1 */
|
||||
char maxregpower; /* 22 1 */
|
||||
u8 antennamax; /* 23 1 */
|
||||
u8 reg_class_id; /* 24 1 */
|
||||
|
||||
/* size: 25, cachelines: 1, members: 21 */
|
||||
/* sum members: 23 */
|
||||
/* sum bitfield members: 10 bits, bit holes: 1, sum bit holes: 6 bits */
|
||||
/* last cacheline: 25 bytes */
|
||||
} __attribute__((__packed__));
|
||||
|
||||
as previously, sizeof(struct scan_chan_list_params) was 32 bytes:
|
||||
|
||||
$ pahole -C scan_chan_list_params drivers/net/wireless/ath/ath11k/reg.o
|
||||
struct scan_chan_list_params {
|
||||
u32 pdev_id; /* 0 4 */
|
||||
u16 nallchans; /* 4 2 */
|
||||
struct channel_param ch_param[1]; /* 6 25 */
|
||||
|
||||
/* size: 32, cachelines: 1, members: 3 */
|
||||
/* padding: 1 */
|
||||
/* last cacheline: 32 bytes */
|
||||
};
|
||||
|
||||
and now with the flexible array transformation it is just 8 bytes:
|
||||
|
||||
$ pahole -C scan_chan_list_params drivers/net/wireless/ath/ath11k/reg.o
|
||||
struct scan_chan_list_params {
|
||||
u32 pdev_id; /* 0 4 */
|
||||
u16 nallchans; /* 4 2 */
|
||||
struct channel_param ch_param[]; /* 6 0 */
|
||||
|
||||
/* size: 8, cachelines: 1, members: 3 */
|
||||
/* padding: 2 */
|
||||
/* last cacheline: 8 bytes */
|
||||
};
|
||||
|
||||
This helps with the ongoing efforts to globally enable -Warray-bounds and
|
||||
get us closer to being able to tighten the FORTIFY_SOURCE routines on
|
||||
memcpy().
|
||||
|
||||
This issue was found with the help of Coccinelle and audited and fixed,
|
||||
manually.
|
||||
|
||||
[1] https://en.wikipedia.org/wiki/Flexible_array_member
|
||||
[2] https://www.kernel.org/doc/html/v5.10/process/deprecated.html#zero-length-and-one-element-arrays
|
||||
|
||||
Link: https://github.com/KSPP/linux/issues/79
|
||||
Link: https://github.com/KSPP/linux/issues/109
|
||||
Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20210823172159.GA25800@embeddedor
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/reg.c | 7 ++-----
|
||||
drivers/net/wireless/ath/ath11k/wmi.c | 2 +-
|
||||
drivers/net/wireless/ath/ath11k/wmi.h | 2 +-
|
||||
3 files changed, 4 insertions(+), 7 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/reg.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/reg.c
|
||||
@@ -97,7 +97,6 @@ int ath11k_reg_update_chan_list(struct a
|
||||
struct channel_param *ch;
|
||||
enum nl80211_band band;
|
||||
int num_channels = 0;
|
||||
- int params_len;
|
||||
int i, ret;
|
||||
|
||||
bands = hw->wiphy->bands;
|
||||
@@ -117,10 +116,8 @@ int ath11k_reg_update_chan_list(struct a
|
||||
if (WARN_ON(!num_channels))
|
||||
return -EINVAL;
|
||||
|
||||
- params_len = sizeof(struct scan_chan_list_params) +
|
||||
- num_channels * sizeof(struct channel_param);
|
||||
- params = kzalloc(params_len, GFP_KERNEL);
|
||||
-
|
||||
+ params = kzalloc(struct_size(params, ch_param, num_channels),
|
||||
+ GFP_KERNEL);
|
||||
if (!params)
|
||||
return -ENOMEM;
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/wmi.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
|
||||
@@ -2302,7 +2302,7 @@ int ath11k_wmi_send_scan_chan_list_cmd(s
|
||||
u16 num_send_chans, num_sends = 0, max_chan_limit = 0;
|
||||
u32 *reg1, *reg2;
|
||||
|
||||
- tchan_info = &chan_list->ch_param[0];
|
||||
+ tchan_info = chan_list->ch_param;
|
||||
while (chan_list->nallchans) {
|
||||
len = sizeof(*cmd) + TLV_HDR_SIZE;
|
||||
max_chan_limit = (wmi->wmi_ab->max_msg_len[ar->pdev_idx] - len) /
|
||||
--- a/drivers/net/wireless/ath/ath11k/wmi.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/wmi.h
|
||||
@@ -3659,7 +3659,7 @@ struct wmi_stop_scan_cmd {
|
||||
struct scan_chan_list_params {
|
||||
u32 pdev_id;
|
||||
u16 nallchans;
|
||||
- struct channel_param ch_param[1];
|
||||
+ struct channel_param ch_param[];
|
||||
};
|
||||
|
||||
struct wmi_scan_chan_list_cmd {
|
@ -0,0 +1,28 @@
|
||||
From b9b5948cdd7bc8d9fa31c78cbbb04382c815587f Mon Sep 17 00:00:00 2001
|
||||
From: Aaron Ma <aaron.ma@canonical.com>
|
||||
Date: Tue, 28 Sep 2021 12:05:43 +0300
|
||||
Subject: [PATCH 022/120] ath11k: qmi: avoid error messages when dma allocation
|
||||
fails
|
||||
|
||||
qmi tries to allocate a large contiguous dma memory at first,
|
||||
on the AMD Ryzen platform it fails, then retries with small slices.
|
||||
So set flag GFP_NOWARN to avoid flooding dmesg.
|
||||
|
||||
Signed-off-by: Aaron Ma <aaron.ma@canonical.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20210823063258.37747-1-aaron.ma@canonical.com
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/qmi.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/qmi.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/qmi.c
|
||||
@@ -1842,7 +1842,7 @@ static int ath11k_qmi_alloc_target_mem_c
|
||||
chunk->vaddr = dma_alloc_coherent(ab->dev,
|
||||
chunk->size,
|
||||
&chunk->paddr,
|
||||
- GFP_KERNEL);
|
||||
+ GFP_KERNEL | __GFP_NOWARN);
|
||||
if (!chunk->vaddr) {
|
||||
if (ab->qmi.mem_seg_count <= ATH11K_QMI_FW_MEM_REQ_SEGMENT_CNT) {
|
||||
ath11k_dbg(ab, ATH11K_DBG_QMI,
|
@ -0,0 +1,596 @@
|
||||
From 2167fa606c0f0e64b95a04f9bc42d9fd5360838a Mon Sep 17 00:00:00 2001
|
||||
From: Sriram R <srirrama@codeaurora.org>
|
||||
Date: Tue, 28 Sep 2021 12:05:40 +0300
|
||||
Subject: [PATCH 024/120] ath11k: Add support for RX decapsulation offload
|
||||
|
||||
Add support for rx decapsulation offload by advertising
|
||||
the support to mac80211 during registration. Also ensure
|
||||
the frames have the RX_FLAG_8023 flag set in decap offload
|
||||
frames before passing to mac80211.
|
||||
|
||||
Since the packets delivered to the driver are in 802.3 format, these
|
||||
can be sent to the network core with minimal processing in mac80211.
|
||||
This helps in releasing some CPU cycles in the host processor and
|
||||
thereby improving the performance.
|
||||
|
||||
Two exceptions are made before passing decap frames, one is
|
||||
for EAPOL packets since mac80211 8023 fast rx for the sta
|
||||
is set only after authorization, other case is for multicast
|
||||
packets to validate PN in mac80211. In both the cases the
|
||||
decap frames are converted to 80211 frame and sent to mac80211.
|
||||
|
||||
Ethernet decap can be enabled by using frame_mode modparam:
|
||||
|
||||
insmod ath11k frame_mode=2
|
||||
|
||||
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.5.0.1-00844-QCAHKSWPL_SILICONZ-1 v2
|
||||
|
||||
Co-developed-by: Manikanta Pubbisetty <mpubbise@codeaurora.org>
|
||||
Signed-off-by: Manikanta Pubbisetty <mpubbise@codeaurora.org>
|
||||
Signed-off-by: Sriram R <srirrama@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20210721204217.120572-1-jouni@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/core.h | 4 +
|
||||
drivers/net/wireless/ath/ath11k/dp_rx.c | 194 +++++++++++++--------
|
||||
drivers/net/wireless/ath/ath11k/hal_desc.h | 2 +
|
||||
drivers/net/wireless/ath/ath11k/hw.c | 43 +++++
|
||||
drivers/net/wireless/ath/ath11k/hw.h | 2 +
|
||||
drivers/net/wireless/ath/ath11k/mac.c | 25 ++-
|
||||
6 files changed, 198 insertions(+), 72 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/core.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/core.h
|
||||
@@ -93,6 +93,8 @@ struct ath11k_skb_rxcb {
|
||||
bool is_first_msdu;
|
||||
bool is_last_msdu;
|
||||
bool is_continuation;
|
||||
+ bool is_mcbc;
|
||||
+ bool is_eapol;
|
||||
struct hal_rx_desc *rx_desc;
|
||||
u8 err_rel_src;
|
||||
u8 err_code;
|
||||
@@ -100,6 +102,8 @@ struct ath11k_skb_rxcb {
|
||||
u8 unmapped;
|
||||
u8 is_frag;
|
||||
u8 tid;
|
||||
+ u16 peer_id;
|
||||
+ u16 seq_no;
|
||||
};
|
||||
|
||||
enum ath11k_hw_rev {
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
|
||||
@@ -270,6 +270,18 @@ static bool ath11k_dp_rx_h_attn_is_mcbc(
|
||||
__le32_to_cpu(attn->info1)));
|
||||
}
|
||||
|
||||
+static bool ath11k_dp_rxdesc_mac_addr2_valid(struct ath11k_base *ab,
|
||||
+ struct hal_rx_desc *desc)
|
||||
+{
|
||||
+ return ab->hw_params.hw_ops->rx_desc_mac_addr2_valid(desc);
|
||||
+}
|
||||
+
|
||||
+static u8 *ath11k_dp_rxdesc_mpdu_start_addr2(struct ath11k_base *ab,
|
||||
+ struct hal_rx_desc *desc)
|
||||
+{
|
||||
+ return ab->hw_params.hw_ops->rx_desc_mpdu_start_addr2(desc);
|
||||
+}
|
||||
+
|
||||
static void ath11k_dp_service_mon_ring(struct timer_list *t)
|
||||
{
|
||||
struct ath11k_base *ab = from_timer(ab, t, mon_reap_timer);
|
||||
@@ -2156,6 +2168,7 @@ static void ath11k_dp_rx_h_undecap(struc
|
||||
{
|
||||
u8 *first_hdr;
|
||||
u8 decap;
|
||||
+ struct ethhdr *ehdr;
|
||||
|
||||
first_hdr = ath11k_dp_rx_h_80211_hdr(ar->ab, rx_desc);
|
||||
decap = ath11k_dp_rx_h_msdu_start_decap_type(ar->ab, rx_desc);
|
||||
@@ -2170,9 +2183,22 @@ static void ath11k_dp_rx_h_undecap(struc
|
||||
decrypted);
|
||||
break;
|
||||
case DP_RX_DECAP_TYPE_ETHERNET2_DIX:
|
||||
- /* TODO undecap support for middle/last msdu's of amsdu */
|
||||
- ath11k_dp_rx_h_undecap_eth(ar, msdu, first_hdr,
|
||||
- enctype, status);
|
||||
+ ehdr = (struct ethhdr *)msdu->data;
|
||||
+
|
||||
+ /* mac80211 allows fast path only for authorized STA */
|
||||
+ if (ehdr->h_proto == cpu_to_be16(ETH_P_PAE)) {
|
||||
+ ATH11K_SKB_RXCB(msdu)->is_eapol = true;
|
||||
+ ath11k_dp_rx_h_undecap_eth(ar, msdu, first_hdr,
|
||||
+ enctype, status);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ /* PN for mcast packets will be validated in mac80211;
|
||||
+ * remove eth header and add 802.11 header.
|
||||
+ */
|
||||
+ if (ATH11K_SKB_RXCB(msdu)->is_mcbc && decrypted)
|
||||
+ ath11k_dp_rx_h_undecap_eth(ar, msdu, first_hdr,
|
||||
+ enctype, status);
|
||||
break;
|
||||
case DP_RX_DECAP_TYPE_8023:
|
||||
/* TODO: Handle undecap for these formats */
|
||||
@@ -2180,35 +2206,62 @@ static void ath11k_dp_rx_h_undecap(struc
|
||||
}
|
||||
}
|
||||
|
||||
+static struct ath11k_peer *
|
||||
+ath11k_dp_rx_h_find_peer(struct ath11k_base *ab, struct sk_buff *msdu)
|
||||
+{
|
||||
+ struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu);
|
||||
+ struct hal_rx_desc *rx_desc = rxcb->rx_desc;
|
||||
+ struct ath11k_peer *peer = NULL;
|
||||
+
|
||||
+ lockdep_assert_held(&ab->base_lock);
|
||||
+
|
||||
+ if (rxcb->peer_id)
|
||||
+ peer = ath11k_peer_find_by_id(ab, rxcb->peer_id);
|
||||
+
|
||||
+ if (peer)
|
||||
+ return peer;
|
||||
+
|
||||
+ if (!rx_desc || !(ath11k_dp_rxdesc_mac_addr2_valid(ab, rx_desc)))
|
||||
+ return NULL;
|
||||
+
|
||||
+ peer = ath11k_peer_find_by_addr(ab,
|
||||
+ ath11k_dp_rxdesc_mpdu_start_addr2(ab, rx_desc));
|
||||
+ return peer;
|
||||
+}
|
||||
+
|
||||
static void ath11k_dp_rx_h_mpdu(struct ath11k *ar,
|
||||
struct sk_buff *msdu,
|
||||
struct hal_rx_desc *rx_desc,
|
||||
struct ieee80211_rx_status *rx_status)
|
||||
{
|
||||
- bool fill_crypto_hdr, mcast;
|
||||
+ bool fill_crypto_hdr;
|
||||
enum hal_encrypt_type enctype;
|
||||
bool is_decrypted = false;
|
||||
+ struct ath11k_skb_rxcb *rxcb;
|
||||
struct ieee80211_hdr *hdr;
|
||||
struct ath11k_peer *peer;
|
||||
struct rx_attention *rx_attention;
|
||||
u32 err_bitmap;
|
||||
|
||||
- hdr = (struct ieee80211_hdr *)msdu->data;
|
||||
-
|
||||
/* PN for multicast packets will be checked in mac80211 */
|
||||
+ rxcb = ATH11K_SKB_RXCB(msdu);
|
||||
+ fill_crypto_hdr = ath11k_dp_rx_h_attn_is_mcbc(ar->ab, rx_desc);
|
||||
+ rxcb->is_mcbc = fill_crypto_hdr;
|
||||
|
||||
- mcast = is_multicast_ether_addr(hdr->addr1);
|
||||
- fill_crypto_hdr = mcast;
|
||||
+ if (rxcb->is_mcbc) {
|
||||
+ rxcb->peer_id = ath11k_dp_rx_h_mpdu_start_peer_id(ar->ab, rx_desc);
|
||||
+ rxcb->seq_no = ath11k_dp_rx_h_mpdu_start_seq_no(ar->ab, rx_desc);
|
||||
+ }
|
||||
|
||||
spin_lock_bh(&ar->ab->base_lock);
|
||||
- peer = ath11k_peer_find_by_addr(ar->ab, hdr->addr2);
|
||||
+ peer = ath11k_dp_rx_h_find_peer(ar->ab, msdu);
|
||||
if (peer) {
|
||||
- if (mcast)
|
||||
+ if (rxcb->is_mcbc)
|
||||
enctype = peer->sec_type_grp;
|
||||
else
|
||||
enctype = peer->sec_type;
|
||||
} else {
|
||||
- enctype = HAL_ENCRYPT_TYPE_OPEN;
|
||||
+ enctype = ath11k_dp_rx_h_mpdu_start_enctype(ar->ab, rx_desc);
|
||||
}
|
||||
spin_unlock_bh(&ar->ab->base_lock);
|
||||
|
||||
@@ -2247,8 +2300,11 @@ static void ath11k_dp_rx_h_mpdu(struct a
|
||||
if (!is_decrypted || fill_crypto_hdr)
|
||||
return;
|
||||
|
||||
- hdr = (void *)msdu->data;
|
||||
- hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_PROTECTED);
|
||||
+ if (ath11k_dp_rx_h_msdu_start_decap_type(ar->ab, rx_desc) !=
|
||||
+ DP_RX_DECAP_TYPE_ETHERNET2_DIX) {
|
||||
+ hdr = (void *)msdu->data;
|
||||
+ hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_PROTECTED);
|
||||
+ }
|
||||
}
|
||||
|
||||
static void ath11k_dp_rx_h_rate(struct ath11k *ar, struct hal_rx_desc *rx_desc,
|
||||
@@ -2365,51 +2421,49 @@ static void ath11k_dp_rx_h_ppdu(struct a
|
||||
ath11k_dp_rx_h_rate(ar, rx_desc, rx_status);
|
||||
}
|
||||
|
||||
-static char *ath11k_print_get_tid(struct ieee80211_hdr *hdr, char *out,
|
||||
- size_t size)
|
||||
-{
|
||||
- u8 *qc;
|
||||
- int tid;
|
||||
-
|
||||
- if (!ieee80211_is_data_qos(hdr->frame_control))
|
||||
- return "";
|
||||
-
|
||||
- qc = ieee80211_get_qos_ctl(hdr);
|
||||
- tid = *qc & IEEE80211_QOS_CTL_TID_MASK;
|
||||
- snprintf(out, size, "tid %d", tid);
|
||||
-
|
||||
- return out;
|
||||
-}
|
||||
-
|
||||
static void ath11k_dp_rx_deliver_msdu(struct ath11k *ar, struct napi_struct *napi,
|
||||
- struct sk_buff *msdu)
|
||||
+ struct sk_buff *msdu,
|
||||
+ struct ieee80211_rx_status *status)
|
||||
{
|
||||
static const struct ieee80211_radiotap_he known = {
|
||||
.data1 = cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_DATA_MCS_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA1_BW_RU_ALLOC_KNOWN),
|
||||
.data2 = cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_GI_KNOWN),
|
||||
};
|
||||
- struct ieee80211_rx_status *status;
|
||||
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data;
|
||||
+ struct ieee80211_rx_status *rx_status;
|
||||
struct ieee80211_radiotap_he *he = NULL;
|
||||
- char tid[32];
|
||||
-
|
||||
- status = IEEE80211_SKB_RXCB(msdu);
|
||||
- if (status->encoding == RX_ENC_HE) {
|
||||
+ struct ieee80211_sta *pubsta = NULL;
|
||||
+ struct ath11k_peer *peer;
|
||||
+ struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu);
|
||||
+ u8 decap = DP_RX_DECAP_TYPE_RAW;
|
||||
+ bool is_mcbc = rxcb->is_mcbc;
|
||||
+ bool is_eapol = rxcb->is_eapol;
|
||||
+
|
||||
+ if (status->encoding == RX_ENC_HE &&
|
||||
+ !(status->flag & RX_FLAG_RADIOTAP_HE) &&
|
||||
+ !(status->flag & RX_FLAG_SKIP_MONITOR)) {
|
||||
he = skb_push(msdu, sizeof(known));
|
||||
memcpy(he, &known, sizeof(known));
|
||||
status->flag |= RX_FLAG_RADIOTAP_HE;
|
||||
}
|
||||
|
||||
+ if (!(status->flag & RX_FLAG_ONLY_MONITOR))
|
||||
+ decap = ath11k_dp_rx_h_msdu_start_decap_type(ar->ab, rxcb->rx_desc);
|
||||
+
|
||||
+ spin_lock_bh(&ar->ab->base_lock);
|
||||
+ peer = ath11k_dp_rx_h_find_peer(ar->ab, msdu);
|
||||
+ if (peer && peer->sta)
|
||||
+ pubsta = peer->sta;
|
||||
+ spin_unlock_bh(&ar->ab->base_lock);
|
||||
+
|
||||
ath11k_dbg(ar->ab, ATH11K_DBG_DATA,
|
||||
- "rx skb %pK len %u peer %pM %s %s sn %u %s%s%s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %i mic-err %i amsdu-more %i\n",
|
||||
+ "rx skb %pK len %u peer %pM %d %s sn %u %s%s%s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %i mic-err %i amsdu-more %i\n",
|
||||
msdu,
|
||||
msdu->len,
|
||||
- ieee80211_get_SA(hdr),
|
||||
- ath11k_print_get_tid(hdr, tid, sizeof(tid)),
|
||||
- is_multicast_ether_addr(ieee80211_get_DA(hdr)) ?
|
||||
- "mcast" : "ucast",
|
||||
- (__le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4,
|
||||
+ peer ? peer->addr : NULL,
|
||||
+ rxcb->tid,
|
||||
+ is_mcbc ? "mcast" : "ucast",
|
||||
+ rxcb->seq_no,
|
||||
(status->encoding == RX_ENC_LEGACY) ? "legacy" : "",
|
||||
(status->encoding == RX_ENC_HT) ? "ht" : "",
|
||||
(status->encoding == RX_ENC_VHT) ? "vht" : "",
|
||||
@@ -2429,22 +2483,32 @@ static void ath11k_dp_rx_deliver_msdu(st
|
||||
ath11k_dbg_dump(ar->ab, ATH11K_DBG_DP_RX, NULL, "dp rx msdu: ",
|
||||
msdu->data, msdu->len);
|
||||
|
||||
+ rx_status = IEEE80211_SKB_RXCB(msdu);
|
||||
+ *rx_status = *status;
|
||||
+
|
||||
/* TODO: trace rx packet */
|
||||
|
||||
- ieee80211_rx_napi(ar->hw, NULL, msdu, napi);
|
||||
+ /* PN for multicast packets are not validate in HW,
|
||||
+ * so skip 802.3 rx path
|
||||
+ * Also, fast_rx expectes the STA to be authorized, hence
|
||||
+ * eapol packets are sent in slow path.
|
||||
+ */
|
||||
+ if (decap == DP_RX_DECAP_TYPE_ETHERNET2_DIX && !is_eapol &&
|
||||
+ !(is_mcbc && rx_status->flag & RX_FLAG_DECRYPTED))
|
||||
+ rx_status->flag |= RX_FLAG_8023;
|
||||
+
|
||||
+ ieee80211_rx_napi(ar->hw, pubsta, msdu, napi);
|
||||
}
|
||||
|
||||
static int ath11k_dp_rx_process_msdu(struct ath11k *ar,
|
||||
struct sk_buff *msdu,
|
||||
- struct sk_buff_head *msdu_list)
|
||||
+ struct sk_buff_head *msdu_list,
|
||||
+ struct ieee80211_rx_status *rx_status)
|
||||
{
|
||||
struct ath11k_base *ab = ar->ab;
|
||||
struct hal_rx_desc *rx_desc, *lrx_desc;
|
||||
struct rx_attention *rx_attention;
|
||||
- struct ieee80211_rx_status rx_status = {0};
|
||||
- struct ieee80211_rx_status *status;
|
||||
struct ath11k_skb_rxcb *rxcb;
|
||||
- struct ieee80211_hdr *hdr;
|
||||
struct sk_buff *last_buf;
|
||||
u8 l3_pad_bytes;
|
||||
u8 *hdr_status;
|
||||
@@ -2500,19 +2564,11 @@ static int ath11k_dp_rx_process_msdu(str
|
||||
}
|
||||
}
|
||||
|
||||
- hdr = (struct ieee80211_hdr *)msdu->data;
|
||||
-
|
||||
- /* Process only data frames */
|
||||
- if (!ieee80211_is_data(hdr->frame_control))
|
||||
- return -EINVAL;
|
||||
-
|
||||
- ath11k_dp_rx_h_ppdu(ar, rx_desc, &rx_status);
|
||||
- ath11k_dp_rx_h_mpdu(ar, msdu, rx_desc, &rx_status);
|
||||
+ ath11k_dp_rx_h_ppdu(ar, rx_desc, rx_status);
|
||||
+ ath11k_dp_rx_h_mpdu(ar, msdu, rx_desc, rx_status);
|
||||
|
||||
- rx_status.flag |= RX_FLAG_SKIP_MONITOR | RX_FLAG_DUP_VALIDATED;
|
||||
+ rx_status->flag |= RX_FLAG_SKIP_MONITOR | RX_FLAG_DUP_VALIDATED;
|
||||
|
||||
- status = IEEE80211_SKB_RXCB(msdu);
|
||||
- *status = rx_status;
|
||||
return 0;
|
||||
|
||||
free_out:
|
||||
@@ -2527,6 +2583,7 @@ static void ath11k_dp_rx_process_receive
|
||||
struct ath11k_skb_rxcb *rxcb;
|
||||
struct sk_buff *msdu;
|
||||
struct ath11k *ar;
|
||||
+ struct ieee80211_rx_status rx_status = {0};
|
||||
u8 mac_id;
|
||||
int ret;
|
||||
|
||||
@@ -2549,7 +2606,7 @@ static void ath11k_dp_rx_process_receive
|
||||
continue;
|
||||
}
|
||||
|
||||
- ret = ath11k_dp_rx_process_msdu(ar, msdu, msdu_list);
|
||||
+ ret = ath11k_dp_rx_process_msdu(ar, msdu, msdu_list, &rx_status);
|
||||
if (ret) {
|
||||
ath11k_dbg(ab, ATH11K_DBG_DATA,
|
||||
"Unable to process msdu %d", ret);
|
||||
@@ -2557,7 +2614,7 @@ static void ath11k_dp_rx_process_receive
|
||||
continue;
|
||||
}
|
||||
|
||||
- ath11k_dp_rx_deliver_msdu(ar, napi, msdu);
|
||||
+ ath11k_dp_rx_deliver_msdu(ar, napi, msdu, &rx_status);
|
||||
(*quota)--;
|
||||
}
|
||||
|
||||
@@ -2639,10 +2696,14 @@ try_again:
|
||||
RX_MSDU_DESC_INFO0_LAST_MSDU_IN_MPDU);
|
||||
rxcb->is_continuation = !!(desc.rx_msdu_info.info0 &
|
||||
RX_MSDU_DESC_INFO0_MSDU_CONTINUATION);
|
||||
- rxcb->mac_id = mac_id;
|
||||
+ rxcb->peer_id = FIELD_GET(RX_MPDU_DESC_META_DATA_PEER_ID,
|
||||
+ desc.rx_mpdu_info.meta_data);
|
||||
+ rxcb->seq_no = FIELD_GET(RX_MPDU_DESC_INFO0_SEQ_NUM,
|
||||
+ desc.rx_mpdu_info.info0);
|
||||
rxcb->tid = FIELD_GET(HAL_REO_DEST_RING_INFO0_RX_QUEUE_NUM,
|
||||
desc.info0);
|
||||
|
||||
+ rxcb->mac_id = mac_id;
|
||||
__skb_queue_tail(&msdu_list, msdu);
|
||||
|
||||
if (total_msdu_reaped >= quota && !rxcb->is_continuation) {
|
||||
@@ -3944,7 +4005,6 @@ static void ath11k_dp_rx_wbm_err(struct
|
||||
{
|
||||
struct ath11k_skb_rxcb *rxcb = ATH11K_SKB_RXCB(msdu);
|
||||
struct ieee80211_rx_status rxs = {0};
|
||||
- struct ieee80211_rx_status *status;
|
||||
bool drop = true;
|
||||
|
||||
switch (rxcb->err_rel_src) {
|
||||
@@ -3964,10 +4024,7 @@ static void ath11k_dp_rx_wbm_err(struct
|
||||
return;
|
||||
}
|
||||
|
||||
- status = IEEE80211_SKB_RXCB(msdu);
|
||||
- *status = rxs;
|
||||
-
|
||||
- ath11k_dp_rx_deliver_msdu(ar, napi, msdu);
|
||||
+ ath11k_dp_rx_deliver_msdu(ar, napi, msdu, &rxs);
|
||||
}
|
||||
|
||||
int ath11k_dp_rx_process_wbm_err(struct ath11k_base *ab,
|
||||
@@ -4851,7 +4908,7 @@ static int ath11k_dp_rx_mon_deliver(stru
|
||||
{
|
||||
struct ath11k_pdev_dp *dp = &ar->dp;
|
||||
struct sk_buff *mon_skb, *skb_next, *header;
|
||||
- struct ieee80211_rx_status *rxs = &dp->rx_status, *status;
|
||||
+ struct ieee80211_rx_status *rxs = &dp->rx_status;
|
||||
|
||||
mon_skb = ath11k_dp_rx_mon_merg_msdus(ar, mac_id, head_msdu,
|
||||
tail_msdu, rxs);
|
||||
@@ -4877,10 +4934,7 @@ static int ath11k_dp_rx_mon_deliver(stru
|
||||
}
|
||||
rxs->flag |= RX_FLAG_ONLY_MONITOR;
|
||||
|
||||
- status = IEEE80211_SKB_RXCB(mon_skb);
|
||||
- *status = *rxs;
|
||||
-
|
||||
- ath11k_dp_rx_deliver_msdu(ar, napi, mon_skb);
|
||||
+ ath11k_dp_rx_deliver_msdu(ar, napi, mon_skb, rxs);
|
||||
mon_skb = skb_next;
|
||||
} while (mon_skb);
|
||||
rxs->flag = 0;
|
||||
--- a/drivers/net/wireless/ath/ath11k/hal_desc.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/hal_desc.h
|
||||
@@ -496,6 +496,8 @@ struct hal_tlv_hdr {
|
||||
#define RX_MPDU_DESC_INFO0_DA_IDX_TIMEOUT BIT(29)
|
||||
#define RX_MPDU_DESC_INFO0_RAW_MPDU BIT(30)
|
||||
|
||||
+#define RX_MPDU_DESC_META_DATA_PEER_ID GENMASK(15, 0)
|
||||
+
|
||||
struct rx_mpdu_desc {
|
||||
u32 info0; /* %RX_MPDU_DESC_INFO */
|
||||
u32 meta_data;
|
||||
--- a/drivers/net/wireless/ath/ath11k/hw.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/hw.c
|
||||
@@ -374,6 +374,17 @@ static void ath11k_hw_ipq8074_rx_desc_se
|
||||
desc->u.ipq8074.msdu_start.info1 = __cpu_to_le32(info);
|
||||
}
|
||||
|
||||
+static bool ath11k_hw_ipq8074_rx_desc_mac_addr2_valid(struct hal_rx_desc *desc)
|
||||
+{
|
||||
+ return __le32_to_cpu(desc->u.ipq8074.mpdu_start.info1) &
|
||||
+ RX_MPDU_START_INFO1_MAC_ADDR2_VALID;
|
||||
+}
|
||||
+
|
||||
+static u8 *ath11k_hw_ipq8074_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc)
|
||||
+{
|
||||
+ return desc->u.ipq8074.mpdu_start.addr2;
|
||||
+}
|
||||
+
|
||||
static
|
||||
struct rx_attention *ath11k_hw_ipq8074_rx_desc_get_attention(struct hal_rx_desc *desc)
|
||||
{
|
||||
@@ -545,6 +556,17 @@ static u8 *ath11k_hw_qcn9074_rx_desc_get
|
||||
return &desc->u.qcn9074.msdu_payload[0];
|
||||
}
|
||||
|
||||
+static bool ath11k_hw_ipq9074_rx_desc_mac_addr2_valid(struct hal_rx_desc *desc)
|
||||
+{
|
||||
+ return __le32_to_cpu(desc->u.qcn9074.mpdu_start.info11) &
|
||||
+ RX_MPDU_START_INFO11_MAC_ADDR2_VALID;
|
||||
+}
|
||||
+
|
||||
+static u8 *ath11k_hw_ipq9074_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc)
|
||||
+{
|
||||
+ return desc->u.qcn9074.mpdu_start.addr2;
|
||||
+}
|
||||
+
|
||||
static bool ath11k_hw_wcn6855_rx_desc_get_first_msdu(struct hal_rx_desc *desc)
|
||||
{
|
||||
return !!FIELD_GET(RX_MSDU_END_INFO2_FIRST_MSDU_WCN6855,
|
||||
@@ -705,6 +727,17 @@ static u8 *ath11k_hw_wcn6855_rx_desc_get
|
||||
return &desc->u.wcn6855.msdu_payload[0];
|
||||
}
|
||||
|
||||
+static bool ath11k_hw_wcn6855_rx_desc_mac_addr2_valid(struct hal_rx_desc *desc)
|
||||
+{
|
||||
+ return __le32_to_cpu(desc->u.wcn6855.mpdu_start.info1) &
|
||||
+ RX_MPDU_START_INFO1_MAC_ADDR2_VALID;
|
||||
+}
|
||||
+
|
||||
+static u8 *ath11k_hw_wcn6855_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc)
|
||||
+{
|
||||
+ return desc->u.wcn6855.mpdu_start.addr2;
|
||||
+}
|
||||
+
|
||||
static void ath11k_hw_wcn6855_reo_setup(struct ath11k_base *ab)
|
||||
{
|
||||
u32 reo_base = HAL_SEQ_WCSS_UMAC_REO_REG;
|
||||
@@ -801,6 +834,8 @@ const struct ath11k_hw_ops ipq8074_ops =
|
||||
.rx_desc_get_msdu_payload = ath11k_hw_ipq8074_rx_desc_get_msdu_payload,
|
||||
.reo_setup = ath11k_hw_ipq8074_reo_setup,
|
||||
.mpdu_info_get_peerid = ath11k_hw_ipq8074_mpdu_info_get_peerid,
|
||||
+ .rx_desc_mac_addr2_valid = ath11k_hw_ipq8074_rx_desc_mac_addr2_valid,
|
||||
+ .rx_desc_mpdu_start_addr2 = ath11k_hw_ipq8074_rx_desc_mpdu_start_addr2,
|
||||
};
|
||||
|
||||
const struct ath11k_hw_ops ipq6018_ops = {
|
||||
@@ -837,6 +872,8 @@ const struct ath11k_hw_ops ipq6018_ops =
|
||||
.rx_desc_get_msdu_payload = ath11k_hw_ipq8074_rx_desc_get_msdu_payload,
|
||||
.reo_setup = ath11k_hw_ipq8074_reo_setup,
|
||||
.mpdu_info_get_peerid = ath11k_hw_ipq8074_mpdu_info_get_peerid,
|
||||
+ .rx_desc_mac_addr2_valid = ath11k_hw_ipq8074_rx_desc_mac_addr2_valid,
|
||||
+ .rx_desc_mpdu_start_addr2 = ath11k_hw_ipq8074_rx_desc_mpdu_start_addr2,
|
||||
};
|
||||
|
||||
const struct ath11k_hw_ops qca6390_ops = {
|
||||
@@ -873,6 +910,8 @@ const struct ath11k_hw_ops qca6390_ops =
|
||||
.rx_desc_get_msdu_payload = ath11k_hw_ipq8074_rx_desc_get_msdu_payload,
|
||||
.reo_setup = ath11k_hw_ipq8074_reo_setup,
|
||||
.mpdu_info_get_peerid = ath11k_hw_ipq8074_mpdu_info_get_peerid,
|
||||
+ .rx_desc_mac_addr2_valid = ath11k_hw_ipq8074_rx_desc_mac_addr2_valid,
|
||||
+ .rx_desc_mpdu_start_addr2 = ath11k_hw_ipq8074_rx_desc_mpdu_start_addr2,
|
||||
};
|
||||
|
||||
const struct ath11k_hw_ops qcn9074_ops = {
|
||||
@@ -909,6 +948,8 @@ const struct ath11k_hw_ops qcn9074_ops =
|
||||
.rx_desc_get_msdu_payload = ath11k_hw_qcn9074_rx_desc_get_msdu_payload,
|
||||
.reo_setup = ath11k_hw_ipq8074_reo_setup,
|
||||
.mpdu_info_get_peerid = ath11k_hw_ipq8074_mpdu_info_get_peerid,
|
||||
+ .rx_desc_mac_addr2_valid = ath11k_hw_ipq9074_rx_desc_mac_addr2_valid,
|
||||
+ .rx_desc_mpdu_start_addr2 = ath11k_hw_ipq9074_rx_desc_mpdu_start_addr2,
|
||||
};
|
||||
|
||||
const struct ath11k_hw_ops wcn6855_ops = {
|
||||
@@ -945,6 +986,8 @@ const struct ath11k_hw_ops wcn6855_ops =
|
||||
.rx_desc_get_msdu_payload = ath11k_hw_wcn6855_rx_desc_get_msdu_payload,
|
||||
.reo_setup = ath11k_hw_wcn6855_reo_setup,
|
||||
.mpdu_info_get_peerid = ath11k_hw_wcn6855_mpdu_info_get_peerid,
|
||||
+ .rx_desc_mac_addr2_valid = ath11k_hw_wcn6855_rx_desc_mac_addr2_valid,
|
||||
+ .rx_desc_mpdu_start_addr2 = ath11k_hw_wcn6855_rx_desc_mpdu_start_addr2,
|
||||
};
|
||||
|
||||
#define ATH11K_TX_RING_MASK_0 0x1
|
||||
--- a/drivers/net/wireless/ath/ath11k/hw.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/hw.h
|
||||
@@ -209,6 +209,8 @@ struct ath11k_hw_ops {
|
||||
u8 *(*rx_desc_get_msdu_payload)(struct hal_rx_desc *desc);
|
||||
void (*reo_setup)(struct ath11k_base *ab);
|
||||
u16 (*mpdu_info_get_peerid)(u8 *tlv_data);
|
||||
+ bool (*rx_desc_mac_addr2_valid)(struct hal_rx_desc *desc);
|
||||
+ u8* (*rx_desc_mpdu_start_addr2)(struct hal_rx_desc *desc);
|
||||
};
|
||||
|
||||
extern const struct ath11k_hw_ops ipq8074_ops;
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -5370,7 +5370,8 @@ static void ath11k_mac_op_update_vif_off
|
||||
if (ath11k_frame_mode != ATH11K_HW_TXRX_ETHERNET ||
|
||||
(vif->type != NL80211_IFTYPE_STATION &&
|
||||
vif->type != NL80211_IFTYPE_AP))
|
||||
- vif->offload_flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED;
|
||||
+ vif->offload_flags &= ~(IEEE80211_OFFLOAD_ENCAP_ENABLED |
|
||||
+ IEEE80211_OFFLOAD_DECAP_ENABLED);
|
||||
|
||||
if (vif->offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED)
|
||||
param_value = ATH11K_HW_TXRX_ETHERNET;
|
||||
@@ -5386,6 +5387,22 @@ static void ath11k_mac_op_update_vif_off
|
||||
arvif->vdev_id, ret);
|
||||
vif->offload_flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED;
|
||||
}
|
||||
+
|
||||
+ param_id = WMI_VDEV_PARAM_RX_DECAP_TYPE;
|
||||
+ if (vif->offload_flags & IEEE80211_OFFLOAD_DECAP_ENABLED)
|
||||
+ param_value = ATH11K_HW_TXRX_ETHERNET;
|
||||
+ else if (test_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags))
|
||||
+ param_value = ATH11K_HW_TXRX_RAW;
|
||||
+ else
|
||||
+ param_value = ATH11K_HW_TXRX_NATIVE_WIFI;
|
||||
+
|
||||
+ ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,
|
||||
+ param_id, param_value);
|
||||
+ if (ret) {
|
||||
+ ath11k_warn(ab, "failed to set vdev %d rx decap mode: %d\n",
|
||||
+ arvif->vdev_id, ret);
|
||||
+ vif->offload_flags &= ~IEEE80211_OFFLOAD_DECAP_ENABLED;
|
||||
+ }
|
||||
}
|
||||
|
||||
static int ath11k_mac_op_add_interface(struct ieee80211_hw *hw,
|
||||
@@ -7550,7 +7567,11 @@ static int __ath11k_mac_register(struct
|
||||
ieee80211_hw_set(ar->hw, QUEUE_CONTROL);
|
||||
ieee80211_hw_set(ar->hw, SUPPORTS_TX_FRAG);
|
||||
ieee80211_hw_set(ar->hw, REPORTS_LOW_ACK);
|
||||
- ieee80211_hw_set(ar->hw, SUPPORTS_TX_ENCAP_OFFLOAD);
|
||||
+
|
||||
+ if (ath11k_frame_mode == ATH11K_HW_TXRX_ETHERNET) {
|
||||
+ ieee80211_hw_set(ar->hw, SUPPORTS_TX_ENCAP_OFFLOAD);
|
||||
+ ieee80211_hw_set(ar->hw, SUPPORTS_RX_DECAP_OFFLOAD);
|
||||
+ }
|
||||
|
||||
if (cap->nss_ratio_enabled)
|
||||
ieee80211_hw_set(ar->hw, SUPPORTS_VHT_EXT_NSS_BW);
|
@ -0,0 +1,186 @@
|
||||
From ab18e3bc1c138f2b4358c6905a45afb7289d5086 Mon Sep 17 00:00:00 2001
|
||||
From: Anilkumar Kolli <akolli@codeaurora.org>
|
||||
Date: Tue, 28 Sep 2021 12:05:40 +0300
|
||||
Subject: [PATCH 025/120] ath11k: Fix pktlog lite rx events
|
||||
|
||||
Fix sending rx_buf_sz to ath11k_dp_tx_htt_rx_filter_setup()
|
||||
to enable pktlog full or lite mode. Depending on mode update the
|
||||
trace buffer with log type full/lite.
|
||||
|
||||
Pktlog lite is a lighter version of pktlog. This can be used to capture
|
||||
PPDU stats. These are useful for firmware performance debugging.
|
||||
|
||||
pktlog lite dumps are enabled using,
|
||||
echo "0x0 1" > ath11k/IPQ8074 hw2.0/mac0/pktlog_filter
|
||||
|
||||
Tested On: IPQ8074 hw2.0 AHB WLAN.HK.2.1.0.1-01233-QCAHKSWPL_SILICONZ-1 v2
|
||||
|
||||
Signed-off-by: Anilkumar Kolli <akolli@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20210721212029.142388-1-jouni@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/debugfs.c | 25 +++++++++++++++++++----
|
||||
drivers/net/wireless/ath/ath11k/dp.h | 1 +
|
||||
drivers/net/wireless/ath/ath11k/dp_rx.c | 16 ++++++++++++---
|
||||
drivers/net/wireless/ath/ath11k/trace.h | 11 ++++++----
|
||||
4 files changed, 42 insertions(+), 11 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/debugfs.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/debugfs.c
|
||||
@@ -902,7 +902,7 @@ static ssize_t ath11k_write_pktlog_filte
|
||||
struct htt_rx_ring_tlv_filter tlv_filter = {0};
|
||||
u32 rx_filter = 0, ring_id, filter, mode;
|
||||
u8 buf[128] = {0};
|
||||
- int i, ret;
|
||||
+ int i, ret, rx_buf_sz = 0;
|
||||
ssize_t rc;
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
@@ -940,6 +940,17 @@ static ssize_t ath11k_write_pktlog_filte
|
||||
}
|
||||
}
|
||||
|
||||
+ /* Clear rx filter set for monitor mode and rx status */
|
||||
+ for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
|
||||
+ ring_id = ar->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id;
|
||||
+ ret = ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, ar->dp.mac_id,
|
||||
+ HAL_RXDMA_MONITOR_STATUS,
|
||||
+ rx_buf_sz, &tlv_filter);
|
||||
+ if (ret) {
|
||||
+ ath11k_warn(ar->ab, "failed to set rx filter for monitor status ring\n");
|
||||
+ goto out;
|
||||
+ }
|
||||
+ }
|
||||
#define HTT_RX_FILTER_TLV_LITE_MODE \
|
||||
(HTT_RX_FILTER_TLV_FLAGS_PPDU_START | \
|
||||
HTT_RX_FILTER_TLV_FLAGS_PPDU_END | \
|
||||
@@ -955,6 +966,7 @@ static ssize_t ath11k_write_pktlog_filte
|
||||
HTT_RX_FILTER_TLV_FLAGS_MPDU_END |
|
||||
HTT_RX_FILTER_TLV_FLAGS_PACKET_HEADER |
|
||||
HTT_RX_FILTER_TLV_FLAGS_ATTENTION;
|
||||
+ rx_buf_sz = DP_RX_BUFFER_SIZE;
|
||||
} else if (mode == ATH11K_PKTLOG_MODE_LITE) {
|
||||
ret = ath11k_dp_tx_htt_h2t_ppdu_stats_req(ar,
|
||||
HTT_PPDU_STATS_TAG_PKTLOG);
|
||||
@@ -964,7 +976,12 @@ static ssize_t ath11k_write_pktlog_filte
|
||||
}
|
||||
|
||||
rx_filter = HTT_RX_FILTER_TLV_LITE_MODE;
|
||||
+ rx_buf_sz = DP_RX_BUFFER_SIZE_LITE;
|
||||
} else {
|
||||
+ rx_buf_sz = DP_RX_BUFFER_SIZE;
|
||||
+ tlv_filter = ath11k_mac_mon_status_filter_default;
|
||||
+ rx_filter = tlv_filter.rx_filter;
|
||||
+
|
||||
ret = ath11k_dp_tx_htt_h2t_ppdu_stats_req(ar,
|
||||
HTT_PPDU_STATS_TAG_DEFAULT);
|
||||
if (ret) {
|
||||
@@ -988,7 +1005,7 @@ static ssize_t ath11k_write_pktlog_filte
|
||||
ret = ath11k_dp_tx_htt_rx_filter_setup(ab, ring_id,
|
||||
ar->dp.mac_id + i,
|
||||
HAL_RXDMA_MONITOR_STATUS,
|
||||
- DP_RX_BUFFER_SIZE, &tlv_filter);
|
||||
+ rx_buf_sz, &tlv_filter);
|
||||
|
||||
if (ret) {
|
||||
ath11k_warn(ab, "failed to set rx filter for monitor status ring\n");
|
||||
@@ -996,8 +1013,8 @@ static ssize_t ath11k_write_pktlog_filte
|
||||
}
|
||||
}
|
||||
|
||||
- ath11k_dbg(ab, ATH11K_DBG_WMI, "pktlog filter %d mode %s\n",
|
||||
- filter, ((mode == ATH11K_PKTLOG_MODE_FULL) ? "full" : "lite"));
|
||||
+ ath11k_info(ab, "pktlog mode %s\n",
|
||||
+ ((mode == ATH11K_PKTLOG_MODE_FULL) ? "full" : "lite"));
|
||||
|
||||
ar->debug.pktlog_filter = filter;
|
||||
ar->debug.pktlog_mode = mode;
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp.h
|
||||
@@ -195,6 +195,7 @@ struct ath11k_pdev_dp {
|
||||
#define DP_RXDMA_MONITOR_DESC_RING_SIZE 4096
|
||||
|
||||
#define DP_RX_BUFFER_SIZE 2048
|
||||
+#define DP_RX_BUFFER_SIZE_LITE 1024
|
||||
#define DP_RX_BUFFER_ALIGN_SIZE 128
|
||||
|
||||
#define DP_RXDMA_BUF_COOKIE_BUF_ID GENMASK(17, 0)
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
|
||||
@@ -3033,6 +3033,8 @@ int ath11k_dp_rx_process_mon_status(stru
|
||||
struct ath11k_peer *peer;
|
||||
struct ath11k_sta *arsta;
|
||||
int num_buffs_reaped = 0;
|
||||
+ u32 rx_buf_sz;
|
||||
+ u16 log_type = 0;
|
||||
|
||||
__skb_queue_head_init(&skb_list);
|
||||
|
||||
@@ -3045,8 +3047,16 @@ int ath11k_dp_rx_process_mon_status(stru
|
||||
memset(&ppdu_info, 0, sizeof(ppdu_info));
|
||||
ppdu_info.peer_id = HAL_INVALID_PEERID;
|
||||
|
||||
- if (ath11k_debugfs_is_pktlog_rx_stats_enabled(ar))
|
||||
- trace_ath11k_htt_rxdesc(ar, skb->data, DP_RX_BUFFER_SIZE);
|
||||
+ if (ath11k_debugfs_is_pktlog_lite_mode_enabled(ar)) {
|
||||
+ log_type = ATH11K_PKTLOG_TYPE_LITE_RX;
|
||||
+ rx_buf_sz = DP_RX_BUFFER_SIZE_LITE;
|
||||
+ } else if (ath11k_debugfs_is_pktlog_rx_stats_enabled(ar)) {
|
||||
+ log_type = ATH11K_PKTLOG_TYPE_RX_STATBUF;
|
||||
+ rx_buf_sz = DP_RX_BUFFER_SIZE;
|
||||
+ }
|
||||
+
|
||||
+ if (log_type)
|
||||
+ trace_ath11k_htt_rxdesc(ar, skb->data, log_type, rx_buf_sz);
|
||||
|
||||
hal_status = ath11k_hal_rx_parse_mon_status(ab, &ppdu_info, skb);
|
||||
|
||||
@@ -3074,7 +3084,7 @@ int ath11k_dp_rx_process_mon_status(stru
|
||||
ath11k_dp_rx_update_peer_stats(arsta, &ppdu_info);
|
||||
|
||||
if (ath11k_debugfs_is_pktlog_peer_valid(ar, peer->addr))
|
||||
- trace_ath11k_htt_rxdesc(ar, skb->data, DP_RX_BUFFER_SIZE);
|
||||
+ trace_ath11k_htt_rxdesc(ar, skb->data, log_type, rx_buf_sz);
|
||||
|
||||
spin_unlock_bh(&ab->base_lock);
|
||||
rcu_read_unlock();
|
||||
--- a/drivers/net/wireless/ath/ath11k/trace.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/trace.h
|
||||
@@ -79,14 +79,15 @@ TRACE_EVENT(ath11k_htt_ppdu_stats,
|
||||
);
|
||||
|
||||
TRACE_EVENT(ath11k_htt_rxdesc,
|
||||
- TP_PROTO(struct ath11k *ar, const void *data, size_t len),
|
||||
+ TP_PROTO(struct ath11k *ar, const void *data, size_t log_type, size_t len),
|
||||
|
||||
- TP_ARGS(ar, data, len),
|
||||
+ TP_ARGS(ar, data, log_type, len),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__string(device, dev_name(ar->ab->dev))
|
||||
__string(driver, dev_driver_string(ar->ab->dev))
|
||||
__field(u16, len)
|
||||
+ __field(u16, log_type)
|
||||
__dynamic_array(u8, rxdesc, len)
|
||||
),
|
||||
|
||||
@@ -94,14 +95,16 @@ TRACE_EVENT(ath11k_htt_rxdesc,
|
||||
__assign_str(device, dev_name(ar->ab->dev));
|
||||
__assign_str(driver, dev_driver_string(ar->ab->dev));
|
||||
__entry->len = len;
|
||||
+ __entry->log_type = log_type;
|
||||
memcpy(__get_dynamic_array(rxdesc), data, len);
|
||||
),
|
||||
|
||||
TP_printk(
|
||||
- "%s %s rxdesc len %d",
|
||||
+ "%s %s rxdesc len %d type %d",
|
||||
__get_str(driver),
|
||||
__get_str(device),
|
||||
- __entry->len
|
||||
+ __entry->len,
|
||||
+ __entry->log_type
|
||||
)
|
||||
);
|
||||
|
@ -0,0 +1,250 @@
|
||||
From f394e4eae8e2c0579063e5473f1e321d22d3fe43 Mon Sep 17 00:00:00 2001
|
||||
From: Sriram R <srirrama@codeaurora.org>
|
||||
Date: Tue, 28 Sep 2021 12:05:40 +0300
|
||||
Subject: [PATCH 026/120] ath11k: Update pdev tx and rx firmware stats
|
||||
|
||||
Update the fields of pdev tx and tx firmware stats structure.
|
||||
Missing fields resulted in wrong fw stats to be displayed as below.
|
||||
|
||||
root@OpenWrt:/# cat /sys/kernel/debug/ath11k/
|
||||
ipq8074\ hw2.0/mac0/fw_stats/pdev_stats | grep Illegal
|
||||
Illegal rate phy errors 36839112
|
||||
|
||||
Note that this struct was missing its members from initial driver
|
||||
support and this change doesn't introduce/modify the structure for
|
||||
firmware changes.
|
||||
|
||||
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-01734-QCAHKSWPL_SILICONZ-1 v2
|
||||
|
||||
Signed-off-by: Sriram R <srirrama@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20210721212029.142388-2-jouni@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/core.h | 29 ++++++++++++++++++
|
||||
drivers/net/wireless/ath/ath11k/wmi.c | 41 ++++++++++++++++++++++++-
|
||||
drivers/net/wireless/ath/ath11k/wmi.h | 42 ++++++++++++++++++++++++++
|
||||
3 files changed, 111 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/core.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/core.h
|
||||
@@ -806,12 +806,15 @@ struct ath11k_fw_stats_pdev {
|
||||
s32 hw_reaped;
|
||||
/* Num underruns */
|
||||
s32 underrun;
|
||||
+ /* Num hw paused */
|
||||
+ u32 hw_paused;
|
||||
/* Num PPDUs cleaned up in TX abort */
|
||||
s32 tx_abort;
|
||||
/* Num MPDUs requeued by SW */
|
||||
s32 mpdus_requeued;
|
||||
/* excessive retries */
|
||||
u32 tx_ko;
|
||||
+ u32 tx_xretry;
|
||||
/* data hw rate code */
|
||||
u32 data_rc;
|
||||
/* Scheduler self triggers */
|
||||
@@ -832,6 +835,30 @@ struct ath11k_fw_stats_pdev {
|
||||
u32 phy_underrun;
|
||||
/* MPDU is more than txop limit */
|
||||
u32 txop_ovf;
|
||||
+ /* Num sequences posted */
|
||||
+ u32 seq_posted;
|
||||
+ /* Num sequences failed in queueing */
|
||||
+ u32 seq_failed_queueing;
|
||||
+ /* Num sequences completed */
|
||||
+ u32 seq_completed;
|
||||
+ /* Num sequences restarted */
|
||||
+ u32 seq_restarted;
|
||||
+ /* Num of MU sequences posted */
|
||||
+ u32 mu_seq_posted;
|
||||
+ /* Num MPDUs flushed by SW, HWPAUSED, SW TXABORT
|
||||
+ * (Reset,channel change)
|
||||
+ */
|
||||
+ s32 mpdus_sw_flush;
|
||||
+ /* Num MPDUs filtered by HW, all filter condition (TTL expired) */
|
||||
+ s32 mpdus_hw_filter;
|
||||
+ /* Num MPDUs truncated by PDG (TXOP, TBTT,
|
||||
+ * PPDU_duration based on rate, dyn_bw)
|
||||
+ */
|
||||
+ s32 mpdus_truncated;
|
||||
+ /* Num MPDUs that was tried but didn't receive ACK or BA */
|
||||
+ s32 mpdus_ack_failed;
|
||||
+ /* Num MPDUs that was dropped du to expiry. */
|
||||
+ s32 mpdus_expired;
|
||||
|
||||
/* PDEV RX stats */
|
||||
/* Cnts any change in ring routing mid-ppdu */
|
||||
@@ -857,6 +884,8 @@ struct ath11k_fw_stats_pdev {
|
||||
s32 phy_err_drop;
|
||||
/* Number of mpdu errors - FCS, MIC, ENC etc. */
|
||||
s32 mpdu_errs;
|
||||
+ /* Num overflow errors */
|
||||
+ s32 rx_ovfl_errs;
|
||||
};
|
||||
|
||||
struct ath11k_fw_stats_vdev {
|
||||
--- a/drivers/net/wireless/ath/ath11k/wmi.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
|
||||
@@ -5251,9 +5251,11 @@ ath11k_wmi_pull_pdev_stats_tx(const stru
|
||||
dst->hw_queued = src->hw_queued;
|
||||
dst->hw_reaped = src->hw_reaped;
|
||||
dst->underrun = src->underrun;
|
||||
+ dst->hw_paused = src->hw_paused;
|
||||
dst->tx_abort = src->tx_abort;
|
||||
dst->mpdus_requeued = src->mpdus_requeued;
|
||||
dst->tx_ko = src->tx_ko;
|
||||
+ dst->tx_xretry = src->tx_xretry;
|
||||
dst->data_rc = src->data_rc;
|
||||
dst->self_triggers = src->self_triggers;
|
||||
dst->sw_retry_failure = src->sw_retry_failure;
|
||||
@@ -5264,6 +5266,16 @@ ath11k_wmi_pull_pdev_stats_tx(const stru
|
||||
dst->stateless_tid_alloc_failure = src->stateless_tid_alloc_failure;
|
||||
dst->phy_underrun = src->phy_underrun;
|
||||
dst->txop_ovf = src->txop_ovf;
|
||||
+ dst->seq_posted = src->seq_posted;
|
||||
+ dst->seq_failed_queueing = src->seq_failed_queueing;
|
||||
+ dst->seq_completed = src->seq_completed;
|
||||
+ dst->seq_restarted = src->seq_restarted;
|
||||
+ dst->mu_seq_posted = src->mu_seq_posted;
|
||||
+ dst->mpdus_sw_flush = src->mpdus_sw_flush;
|
||||
+ dst->mpdus_hw_filter = src->mpdus_hw_filter;
|
||||
+ dst->mpdus_truncated = src->mpdus_truncated;
|
||||
+ dst->mpdus_ack_failed = src->mpdus_ack_failed;
|
||||
+ dst->mpdus_expired = src->mpdus_expired;
|
||||
}
|
||||
|
||||
static void ath11k_wmi_pull_pdev_stats_rx(const struct wmi_pdev_stats_rx *src,
|
||||
@@ -5283,6 +5295,7 @@ static void ath11k_wmi_pull_pdev_stats_r
|
||||
dst->phy_errs = src->phy_errs;
|
||||
dst->phy_err_drop = src->phy_err_drop;
|
||||
dst->mpdu_errs = src->mpdu_errs;
|
||||
+ dst->rx_ovfl_errs = src->rx_ovfl_errs;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -5520,11 +5533,15 @@ ath11k_wmi_fw_pdev_tx_stats_fill(const s
|
||||
len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
|
||||
"Num underruns", pdev->underrun);
|
||||
len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
|
||||
+ "Num HW Paused", pdev->hw_paused);
|
||||
+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
|
||||
"PPDUs cleaned", pdev->tx_abort);
|
||||
len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
|
||||
"MPDUs requeued", pdev->mpdus_requeued);
|
||||
len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
|
||||
- "Excessive retries", pdev->tx_ko);
|
||||
+ "PPDU OK", pdev->tx_ko);
|
||||
+ len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
|
||||
+ "Excessive retries", pdev->tx_xretry);
|
||||
len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
|
||||
"HW rate", pdev->data_rc);
|
||||
len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
|
||||
@@ -5548,6 +5565,26 @@ ath11k_wmi_fw_pdev_tx_stats_fill(const s
|
||||
"PHY underrun", pdev->phy_underrun);
|
||||
len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
|
||||
"MPDU is more than txop limit", pdev->txop_ovf);
|
||||
+ len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
|
||||
+ "Num sequences posted", pdev->seq_posted);
|
||||
+ len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
|
||||
+ "Num seq failed queueing ", pdev->seq_failed_queueing);
|
||||
+ len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
|
||||
+ "Num sequences completed ", pdev->seq_completed);
|
||||
+ len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
|
||||
+ "Num sequences restarted ", pdev->seq_restarted);
|
||||
+ len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
|
||||
+ "Num of MU sequences posted ", pdev->mu_seq_posted);
|
||||
+ len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
|
||||
+ "Num of MPDUS SW flushed ", pdev->mpdus_sw_flush);
|
||||
+ len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
|
||||
+ "Num of MPDUS HW filtered ", pdev->mpdus_hw_filter);
|
||||
+ len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
|
||||
+ "Num of MPDUS truncated ", pdev->mpdus_truncated);
|
||||
+ len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
|
||||
+ "Num of MPDUS ACK failed ", pdev->mpdus_ack_failed);
|
||||
+ len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
|
||||
+ "Num of MPDUS expired ", pdev->mpdus_expired);
|
||||
*length = len;
|
||||
}
|
||||
|
||||
@@ -5592,6 +5629,8 @@ ath11k_wmi_fw_pdev_rx_stats_fill(const s
|
||||
"PHY errors drops", pdev->phy_err_drop);
|
||||
len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
|
||||
"MPDU errors (FCS, MIC, ENC)", pdev->mpdu_errs);
|
||||
+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
|
||||
+ "Overflow errors", pdev->rx_ovfl_errs);
|
||||
*length = len;
|
||||
}
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/wmi.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/wmi.h
|
||||
@@ -4223,6 +4223,9 @@ struct wmi_pdev_stats_tx {
|
||||
/* Num underruns */
|
||||
s32 underrun;
|
||||
|
||||
+ /* Num hw paused */
|
||||
+ u32 hw_paused;
|
||||
+
|
||||
/* Num PPDUs cleaned up in TX abort */
|
||||
s32 tx_abort;
|
||||
|
||||
@@ -4232,6 +4235,8 @@ struct wmi_pdev_stats_tx {
|
||||
/* excessive retries */
|
||||
u32 tx_ko;
|
||||
|
||||
+ u32 tx_xretry;
|
||||
+
|
||||
/* data hw rate code */
|
||||
u32 data_rc;
|
||||
|
||||
@@ -4261,6 +4266,40 @@ struct wmi_pdev_stats_tx {
|
||||
|
||||
/* MPDU is more than txop limit */
|
||||
u32 txop_ovf;
|
||||
+
|
||||
+ /* Num sequences posted */
|
||||
+ u32 seq_posted;
|
||||
+
|
||||
+ /* Num sequences failed in queueing */
|
||||
+ u32 seq_failed_queueing;
|
||||
+
|
||||
+ /* Num sequences completed */
|
||||
+ u32 seq_completed;
|
||||
+
|
||||
+ /* Num sequences restarted */
|
||||
+ u32 seq_restarted;
|
||||
+
|
||||
+ /* Num of MU sequences posted */
|
||||
+ u32 mu_seq_posted;
|
||||
+
|
||||
+ /* Num MPDUs flushed by SW, HWPAUSED, SW TXABORT
|
||||
+ * (Reset,channel change)
|
||||
+ */
|
||||
+ s32 mpdus_sw_flush;
|
||||
+
|
||||
+ /* Num MPDUs filtered by HW, all filter condition (TTL expired) */
|
||||
+ s32 mpdus_hw_filter;
|
||||
+
|
||||
+ /* Num MPDUs truncated by PDG (TXOP, TBTT,
|
||||
+ * PPDU_duration based on rate, dyn_bw)
|
||||
+ */
|
||||
+ s32 mpdus_truncated;
|
||||
+
|
||||
+ /* Num MPDUs that was tried but didn't receive ACK or BA */
|
||||
+ s32 mpdus_ack_failed;
|
||||
+
|
||||
+ /* Num MPDUs that was dropped du to expiry. */
|
||||
+ s32 mpdus_expired;
|
||||
} __packed;
|
||||
|
||||
struct wmi_pdev_stats_rx {
|
||||
@@ -4295,6 +4334,9 @@ struct wmi_pdev_stats_rx {
|
||||
|
||||
/* Number of mpdu errors - FCS, MIC, ENC etc. */
|
||||
s32 mpdu_errs;
|
||||
+
|
||||
+ /* Num overflow errors */
|
||||
+ s32 rx_ovfl_errs;
|
||||
} __packed;
|
||||
|
||||
struct wmi_pdev_stats {
|
@ -0,0 +1,48 @@
|
||||
From 8717db7ee802b71fa3f2a79b265b1325bc61210c Mon Sep 17 00:00:00 2001
|
||||
From: Seevalamuthu Mariappan <seevalam@codeaurora.org>
|
||||
Date: Tue, 28 Sep 2021 12:05:40 +0300
|
||||
Subject: [PATCH 029/120] ath11k: Add vdev start flag to disable hardware
|
||||
encryption
|
||||
|
||||
Firmware blocks all data traffic until the key is plumbed. But, with
|
||||
software encryption mode, key is never plumbed to firmware. Due to this,
|
||||
a traffic failure in software encryption mode has been observed. Hence,
|
||||
firmware has introduced a flag to differentiate software encryption
|
||||
mode. This flag can be passed during vdev_start command.
|
||||
|
||||
Enable WMI_VDEV_START_HW_ENCRYPTION_DISABLED flag in vdev_start command
|
||||
to notify firmware to disable hardware encryption for a vdev. This is set
|
||||
if raw mode software encryption is enabled.
|
||||
|
||||
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-01421-QCAHKSWPL_SILICONZ-1
|
||||
|
||||
Signed-off-by: Seevalamuthu Mariappan <seevalam@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20210721212029.142388-5-jouni@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/wmi.c | 2 ++
|
||||
drivers/net/wireless/ath/ath11k/wmi.h | 1 +
|
||||
2 files changed, 3 insertions(+)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/wmi.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
|
||||
@@ -884,6 +884,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;
|
||||
--- a/drivers/net/wireless/ath/ath11k/wmi.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/wmi.h
|
||||
@@ -2577,6 +2577,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;
|
@ -0,0 +1,62 @@
|
||||
From 3c79cb4d63c0d58462d439efa0db328008354deb Mon Sep 17 00:00:00 2001
|
||||
From: Seevalamuthu Mariappan <seevalam@codeaurora.org>
|
||||
Date: Tue, 28 Sep 2021 12:05:40 +0300
|
||||
Subject: [PATCH 030/120] ath11k: Assign free_vdev_map value before
|
||||
ieee80211_register_hw
|
||||
|
||||
Firmware crash is seen randomly, because of sending wrong vdev_id
|
||||
in vdev_create command. This is due to free_vdev_map value being 0.
|
||||
free_vdev_map is getting assigned after ieee80211_register_hw. In
|
||||
some race conditions, add_interface api is getting called before
|
||||
assigning value to free_vdev_map. Fix this by assigning free_vdev_map
|
||||
before ieee80211_register_hw.
|
||||
|
||||
Also, moved ar->cc_freq_hz and ar->txmgmt_idr initialization before
|
||||
ieee80211_register_hw to avoid such race conditions.
|
||||
|
||||
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.5.0.1-00948-QCAHKSWPL_SILICONZ-1
|
||||
Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.4.0.1-01734-QCAHKSWPL_SILICONZ-1
|
||||
|
||||
Signed-off-by: Seevalamuthu Mariappan <seevalam@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20210721212029.142388-6-jouni@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/mac.c | 14 +++++++-------
|
||||
1 file changed, 7 insertions(+), 7 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -7701,6 +7701,10 @@ int ath11k_mac_register(struct ath11k_ba
|
||||
if (test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags))
|
||||
return 0;
|
||||
|
||||
+ /* Initialize channel counters frequency value in hertz */
|
||||
+ ab->cc_freq_hz = IPQ8074_CC_FREQ_HERTZ;
|
||||
+ ab->free_vdev_map = (1LL << (ab->num_radios * TARGET_NUM_VDEVS)) - 1;
|
||||
+
|
||||
for (i = 0; i < ab->num_radios; i++) {
|
||||
pdev = &ab->pdevs[i];
|
||||
ar = pdev->ar;
|
||||
@@ -7711,18 +7715,14 @@ int ath11k_mac_register(struct ath11k_ba
|
||||
ar->mac_addr[4] += i;
|
||||
}
|
||||
|
||||
+ idr_init(&ar->txmgmt_idr);
|
||||
+ spin_lock_init(&ar->txmgmt_idr_lock);
|
||||
+
|
||||
ret = __ath11k_mac_register(ar);
|
||||
if (ret)
|
||||
goto err_cleanup;
|
||||
-
|
||||
- idr_init(&ar->txmgmt_idr);
|
||||
- spin_lock_init(&ar->txmgmt_idr_lock);
|
||||
}
|
||||
|
||||
- /* Initialize channel counters frequency value in hertz */
|
||||
- ab->cc_freq_hz = IPQ8074_CC_FREQ_HERTZ;
|
||||
- ab->free_vdev_map = (1LL << (ab->num_radios * TARGET_NUM_VDEVS)) - 1;
|
||||
-
|
||||
return 0;
|
||||
|
||||
err_cleanup:
|
@ -0,0 +1,63 @@
|
||||
From 8ee8d38ca4727667e05a1dedf546162207bde9fa Mon Sep 17 00:00:00 2001
|
||||
From: Sriram R <srirrama@codeaurora.org>
|
||||
Date: Tue, 28 Sep 2021 12:05:40 +0300
|
||||
Subject: [PATCH 031/120] ath11k: Fix crash during firmware recovery on reo cmd
|
||||
ring access
|
||||
|
||||
In scenario when a peer is disassociating, there could be
|
||||
multiple places where a reo cmd ring is accessed, such as
|
||||
during aggregation teardown, tid queue cleanup, etc.
|
||||
|
||||
When this happens during firmware recovery where accessing of FW/HW
|
||||
resources/registers is not recommended, accessing reo cmd ring in
|
||||
this case could lead to crash or undefined behaviour.
|
||||
|
||||
Hence avoid this by checking for corresponding flag to avoid
|
||||
accessing reo cmd ring during firmware recovery.
|
||||
|
||||
Sample crash:
|
||||
|
||||
[ 3936.456050] Unhandled fault: imprecise external abort (0x1c06) at 0x54bb842a
|
||||
[ 3936.456411] WARN: Access Violation!!!, Run "cat /sys/kernel/debug/qcom_debug_logs/tz_log" for more details
|
||||
[ 3936.467997] pgd = b4474000
|
||||
[ 3936.477440] [54bb842a] *pgd=6fa61831, *pte=7f95d59f, *ppte=7f95de7e
|
||||
<snip>
|
||||
[ 3937.177436] [<8030ab10>] (_raw_spin_unlock_bh) from [<7f5e9eb8>] (ath11k_hal_reo_cmd_send+0x440/0x458 [ath11k])
|
||||
[ 3937.185730] [<7f5e9eb8>] (ath11k_hal_reo_cmd_send [ath11k]) from [<7f601c4c>] (ath11k_dp_tx_send_reo_cmd+0x2c/0xcc [ath11k])
|
||||
[ 3937.195524] [<7f601c4c>] (ath11k_dp_tx_send_reo_cmd [ath11k]) from [<7f602f10>] (ath11k_peer_rx_tid_reo_update+0x84/0xbc [ath11k])
|
||||
[ 3937.206984] [<7f602f10>] (ath11k_peer_rx_tid_reo_update [ath11k]) from [<7f605a9c>] (ath11k_dp_rx_ampdu_stop+0xa8/0x130 [ath11k])
|
||||
[ 3937.218532] [<7f605a9c>] (ath11k_dp_rx_ampdu_stop [ath11k]) from [<7f5f6730>] (ath11k_mac_op_ampdu_action+0x6c/0x98 [ath11k])
|
||||
[ 3937.230250] [<7f5f6730>] (ath11k_mac_op_ampdu_action [ath11k]) from [<c7b6e890>] (___ieee80211_stop_rx_ba_session+0x98/0x144 [mac80211])
|
||||
[ 3937.241499] [<c7b6e890>] (___ieee80211_stop_rx_ba_session [mac80211]) from [<c7b6cdd8>] (ieee80211_sta_tear_down_BA_sessions+0x4c/0xf4 [)
|
||||
[ 3937.253833] [<c7b6cdd8>] (ieee80211_sta_tear_down_BA_sessions [mac80211]) from [<c7b63460>] (ieee80211_sta_eosp+0x5b8/0x960 [mac80211])
|
||||
[ 3937.266764] [<c7b63460>] (ieee80211_sta_eosp [mac80211]) from [<c7b66da8>] (__sta_info_flush+0x9c/0x134 [mac80211])
|
||||
[ 3937.278826] [<c7b66da8>] (__sta_info_flush [mac80211]) from [<c7b7bd00>] (ieee80211_stop_ap+0x14c/0x28c [mac80211])
|
||||
[ 3937.289240] [<c7b7bd00>] (ieee80211_stop_ap [mac80211]) from [<7f509cf0>] (__cfg80211_stop_ap+0x4c/0xd8 [cfg80211])
|
||||
[ 3937.299629] [<7f509cf0>] (__cfg80211_stop_ap [cfg80211]) from [<7f4dddec>] (cfg80211_leave+0x24/0x30 [cfg80211])
|
||||
[ 3937.310041] [<7f4dddec>] (cfg80211_leave [cfg80211]) from [<7f4de03c>] (cfg80211_netdev_notifier_call+0x174/0x48c [cfg80211])
|
||||
[ 3937.320457] [<7f4de03c>] (cfg80211_netdev_notifier_call [cfg80211]) from [<80339928>] (notifier_call_chain+0x40/0x68)
|
||||
[ 3937.331636] [<80339928>] (notifier_call_chain) from [<803399a8>] (raw_notifier_call_chain+0x14/0x1c)
|
||||
[ 3937.342221] [<803399a8>] (raw_notifier_call_chain) from [<8073bb00>] (call_netdevice_notifiers+0xc/0x14)
|
||||
|
||||
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.1.0.1-01240-QCAHKSWPL_SILICONZ-1
|
||||
|
||||
Signed-off-by: Sriram R <srirrama@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20210721212029.142388-7-jouni@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/dp_tx.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp_tx.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp_tx.c
|
||||
@@ -622,6 +622,9 @@ int ath11k_dp_tx_send_reo_cmd(struct ath
|
||||
struct hal_srng *cmd_ring;
|
||||
int cmd_num;
|
||||
|
||||
+ if (test_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags))
|
||||
+ return -ESHUTDOWN;
|
||||
+
|
||||
cmd_ring = &ab->hal.srng_list[dp->reo_cmd_ring.ring_id];
|
||||
cmd_num = ath11k_hal_reo_cmd_send(ab, cmd_ring, type, cmd);
|
||||
|
@ -0,0 +1,44 @@
|
||||
From 79feedfea7793d91293ab72fac5fc66aae0c6a85 Mon Sep 17 00:00:00 2001
|
||||
From: Karthikeyan Periyasamy <periyasa@codeaurora.org>
|
||||
Date: Tue, 28 Sep 2021 12:05:41 +0300
|
||||
Subject: [PATCH 032/120] ath11k: Avoid "No VIF found" warning message
|
||||
|
||||
Facing below warning prints when we do wifi down in multiple VAPs scenario.
|
||||
|
||||
warning print:
|
||||
|
||||
ath11k c000000.wifi: No VIF found for vdev 2
|
||||
...
|
||||
ath11k c000000.wifi: No VIF found for vdev 0
|
||||
|
||||
In ath11k_mac_get_arvif_by_vdev_id(), we iterate all the radio to get the
|
||||
arvif for the requested vdev_id through ath11k_mac_get_arvif().
|
||||
ath11k_mac_get_arvif() throws a warning message if the given vdev_id is
|
||||
not found in the given radio. So to avoid the warning message, add
|
||||
the allocated_vdev_map cross check against the given vdev_id before using
|
||||
ath11k_mac_get_arvif() to ensure that vdev_id is allocated in the
|
||||
given radio.
|
||||
|
||||
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-01492-QCAHKSWPL_SILICONZ-1
|
||||
Tested-on: IPQ6018 hw1.0 AHB WLAN.HK.2.4.0.1-00330-QCAHKSWPL_SILICONZ-1
|
||||
|
||||
Signed-off-by: Karthikeyan Periyasamy <periyasa@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20210721212029.142388-8-jouni@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/mac.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -500,7 +500,8 @@ struct ath11k_vif *ath11k_mac_get_arvif_
|
||||
|
||||
for (i = 0; i < ab->num_radios; i++) {
|
||||
pdev = rcu_dereference(ab->pdevs_active[i]);
|
||||
- if (pdev && pdev->ar) {
|
||||
+ if (pdev && pdev->ar &&
|
||||
+ (pdev->ar->allocated_vdev_map & (1LL << vdev_id))) {
|
||||
arvif = ath11k_mac_get_arvif(pdev->ar, vdev_id);
|
||||
if (arvif)
|
||||
return arvif;
|
@ -0,0 +1,51 @@
|
||||
From 94a6df31dcf042f74db8209680d04546ce964ad5 Mon Sep 17 00:00:00 2001
|
||||
From: P Praneesh <ppranees@codeaurora.org>
|
||||
Date: Tue, 28 Sep 2021 12:05:41 +0300
|
||||
Subject: [PATCH 033/120] ath11k: Add wmi peer create conf event in
|
||||
wmi_tlv_event_id
|
||||
|
||||
When the driver sends a peer create cmd, the firmware responds with
|
||||
WMI_PEER_CREATE_CONF_EVENTID to confirm the firmware received
|
||||
WMI_PEER_CREATE_CMDID. Since the peer create conf event is not handled
|
||||
in ath11k_wmi_tlv_op_rx, we are getting unknown event id warning prints
|
||||
during peer creation.
|
||||
|
||||
Add WMI_PEER_CREATE_CONF_EVENTID in wmi_tlv_event_id and handle
|
||||
the same as unsupported event id under wmi logs.
|
||||
|
||||
warning prints:
|
||||
[ 4382.230817] ath11k_pci 0000:01:00.0: Unknown eventid: 0x601a
|
||||
|
||||
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-01695-QCAHKSWPL_SILICONZ-1
|
||||
|
||||
Signed-off-by: P Praneesh <ppranees@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20210721212029.142388-9-jouni@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/wmi.c | 1 +
|
||||
drivers/net/wireless/ath/ath11k/wmi.h | 3 +++
|
||||
2 files changed, 4 insertions(+)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/wmi.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
|
||||
@@ -7136,6 +7136,7 @@ static void ath11k_wmi_tlv_op_rx(struct
|
||||
case WMI_TWT_ENABLE_EVENTID:
|
||||
case WMI_TWT_DISABLE_EVENTID:
|
||||
case WMI_PDEV_DMA_RING_CFG_RSP_EVENTID:
|
||||
+ case WMI_PEER_CREATE_CONF_EVENTID:
|
||||
ath11k_dbg(ab, ATH11K_DBG_WMI,
|
||||
"ignoring unsupported event 0x%x\n", id);
|
||||
break;
|
||||
--- a/drivers/net/wireless/ath/ath11k/wmi.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/wmi.h
|
||||
@@ -663,6 +663,9 @@ enum wmi_tlv_event_id {
|
||||
WMI_PEER_RESERVED9_EVENTID,
|
||||
WMI_PEER_RESERVED10_EVENTID,
|
||||
WMI_PEER_OPER_MODE_CHANGE_EVENTID,
|
||||
+ WMI_PEER_TX_PN_RESPONSE_EVENTID,
|
||||
+ WMI_PEER_CFR_CAPTURE_EVENTID,
|
||||
+ WMI_PEER_CREATE_CONF_EVENTID,
|
||||
WMI_MGMT_RX_EVENTID = WMI_TLV_CMD(WMI_GRP_MGMT),
|
||||
WMI_HOST_SWBA_EVENTID,
|
||||
WMI_TBTTOFFSET_UPDATE_EVENTID,
|
@ -0,0 +1,43 @@
|
||||
From 4a9550f536cc9c62210f77d875f000e560fc64b1 Mon Sep 17 00:00:00 2001
|
||||
From: Pradeep Kumar Chitrapu <pradeepc@codeaurora.org>
|
||||
Date: Tue, 28 Sep 2021 14:00:43 +0300
|
||||
Subject: [PATCH 034/120] ath11k: add channel 2 into 6 GHz channel list
|
||||
|
||||
Add support for the 6 GHz channel 2 with center frequency 5935 MHz and
|
||||
operating class 136 per IEEE Std 802.11ax-2021, Table E-4.
|
||||
|
||||
Signed-off-by: Pradeep Kumar Chitrapu <pradeepc@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20210722102054.43419-1-jouni@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/core.h | 4 ++--
|
||||
drivers/net/wireless/ath/ath11k/mac.c | 3 +++
|
||||
2 files changed, 5 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/core.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/core.h
|
||||
@@ -387,9 +387,9 @@ struct ath11k_sta {
|
||||
};
|
||||
|
||||
#define ATH11K_MIN_5G_FREQ 4150
|
||||
-#define ATH11K_MIN_6G_FREQ 5945
|
||||
+#define ATH11K_MIN_6G_FREQ 5925
|
||||
#define ATH11K_MAX_6G_FREQ 7115
|
||||
-#define ATH11K_NUM_CHANS 100
|
||||
+#define ATH11K_NUM_CHANS 101
|
||||
#define ATH11K_MAX_5G_CHAN 173
|
||||
|
||||
enum ath11k_state {
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -150,6 +150,9 @@ static const struct ieee80211_channel at
|
||||
CHAN6G(225, 7075, 0),
|
||||
CHAN6G(229, 7095, 0),
|
||||
CHAN6G(233, 7115, 0),
|
||||
+
|
||||
+ /* new addition in IEEE Std 802.11ax-2021 */
|
||||
+ CHAN6G(2, 5935, 0),
|
||||
};
|
||||
|
||||
static struct ieee80211_rate ath11k_legacy_rates[] = {
|
@ -0,0 +1,35 @@
|
||||
From b6b142f644d2d88e2ceabe0aa4479e0a09ba1ea9 Mon Sep 17 00:00:00 2001
|
||||
From: Pradeep Kumar Chitrapu <pradeepc@codeaurora.org>
|
||||
Date: Tue, 28 Sep 2021 14:00:43 +0300
|
||||
Subject: [PATCH 036/120] ath11k: fix survey dump collection in 6 GHz
|
||||
|
||||
When ath11k receives survey request, choose the 6 GHz band when enabled.
|
||||
Without this, survey request does not include any 6 GHz band results,
|
||||
thereby causing auto channel selection to fail.
|
||||
|
||||
Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.4.0.1-01386-QCAHKSWPL_SILICONZ-1
|
||||
|
||||
Signed-off-by: Pradeep Kumar Chitrapu <pradeepc@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20210722102054.43419-3-jouni@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/mac.c | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -7172,7 +7172,13 @@ static int ath11k_mac_op_get_survey(stru
|
||||
|
||||
if (!sband)
|
||||
sband = hw->wiphy->bands[NL80211_BAND_5GHZ];
|
||||
+ if (sband && idx >= sband->n_channels) {
|
||||
+ idx -= sband->n_channels;
|
||||
+ sband = NULL;
|
||||
+ }
|
||||
|
||||
+ if (!sband)
|
||||
+ sband = hw->wiphy->bands[NL80211_BAND_6GHZ];
|
||||
if (!sband || idx >= sband->n_channels) {
|
||||
ret = -ENOENT;
|
||||
goto exit;
|
@ -0,0 +1,35 @@
|
||||
From 54f40f552afd5a07e635a52221ec4b0ce765c374 Mon Sep 17 00:00:00 2001
|
||||
From: Wen Gong <wgong@codeaurora.org>
|
||||
Date: Tue, 28 Sep 2021 14:00:43 +0300
|
||||
Subject: [PATCH 037/120] ath11k: re-enable ht_cap/vht_cap for 5G band for
|
||||
WCN6855
|
||||
|
||||
WCN6855 uses single_pdev_only, so it supports both the 5G and 6G bands
|
||||
in the same ath11k/pdev and it needs to enable ht_cap/vht_cap for the 5G
|
||||
band, otherwise it will downgrade to non-HT mode for the 5G band. Some
|
||||
chips like QCN9074 only support the 6G band, not the 5G band, and use
|
||||
the flag ar->supports_6ghz which is true to discard ht_cap/vht_cap.
|
||||
|
||||
Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1
|
||||
|
||||
Signed-off-by: Wen Gong <wgong@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20210804181217.88751-2-jouni@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/mac.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -4545,7 +4545,9 @@ static void ath11k_mac_setup_ht_vht_cap(
|
||||
rate_cap_rx_chainmask);
|
||||
}
|
||||
|
||||
- if (cap->supported_bands & WMI_HOST_WLAN_5G_CAP && !ar->supports_6ghz) {
|
||||
+ if (cap->supported_bands & WMI_HOST_WLAN_5G_CAP &&
|
||||
+ (ar->ab->hw_params.single_pdev_only ||
|
||||
+ !ar->supports_6ghz)) {
|
||||
band = &ar->mac.sbands[NL80211_BAND_5GHZ];
|
||||
ht_cap = cap->band[NL80211_BAND_5GHZ].ht_cap_info;
|
||||
if (ht_cap_info)
|
@ -0,0 +1,98 @@
|
||||
From 74bba5e5ba45d511a944082d76b64cc1849e4c2e Mon Sep 17 00:00:00 2001
|
||||
From: Wen Gong <wgong@codeaurora.org>
|
||||
Date: Tue, 28 Sep 2021 14:00:43 +0300
|
||||
Subject: [PATCH 038/120] ath11k: enable 6G channels for WCN6855
|
||||
|
||||
For some chips such as WCN6855, single_pdev_only is set in struct
|
||||
ath11k_hw_params which means ath11k calls ieee80211_register_hw() only
|
||||
once and create only one device interface, and that device interface
|
||||
supports all 2G/5G/6G channels.
|
||||
|
||||
ath11k_mac_setup_channels_rates() sets up the channels and it is called
|
||||
for each device interface. It is called only once for single_pdev_only,
|
||||
and then set up all channels for 2G/5G/6G. The logic of
|
||||
ath11k_mac_setup_channels_rates() is not suitable for single_pdev_only,
|
||||
it leads to all 6G channels being disabled for the device interface
|
||||
which is single_pdev_only such as WCN6855.
|
||||
|
||||
Add channel frequency checks for the 6G band and enable the 6G channels
|
||||
properly based on what is supported by the chip.
|
||||
|
||||
Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1
|
||||
|
||||
Signed-off-by: Wen Gong <wgong@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20210804181217.88751-3-jouni@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/mac.c | 25 ++++++++++++++++---------
|
||||
1 file changed, 16 insertions(+), 9 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -7312,7 +7312,7 @@ static int ath11k_mac_setup_channels_rat
|
||||
u32 supported_bands)
|
||||
{
|
||||
struct ieee80211_supported_band *band;
|
||||
- struct ath11k_hal_reg_capabilities_ext *reg_cap;
|
||||
+ struct ath11k_hal_reg_capabilities_ext *reg_cap, *temp_reg_cap;
|
||||
void *channels;
|
||||
u32 phy_id;
|
||||
|
||||
@@ -7322,6 +7322,7 @@ static int ath11k_mac_setup_channels_rat
|
||||
ATH11K_NUM_CHANS);
|
||||
|
||||
reg_cap = &ar->ab->hal_reg_cap[ar->pdev_idx];
|
||||
+ temp_reg_cap = reg_cap;
|
||||
|
||||
if (supported_bands & WMI_HOST_WLAN_2G_CAP) {
|
||||
channels = kmemdup(ath11k_2ghz_channels,
|
||||
@@ -7340,11 +7341,11 @@ static int ath11k_mac_setup_channels_rat
|
||||
|
||||
if (ar->ab->hw_params.single_pdev_only) {
|
||||
phy_id = ath11k_get_phy_id(ar, WMI_HOST_WLAN_2G_CAP);
|
||||
- reg_cap = &ar->ab->hal_reg_cap[phy_id];
|
||||
+ temp_reg_cap = &ar->ab->hal_reg_cap[phy_id];
|
||||
}
|
||||
ath11k_mac_update_ch_list(ar, band,
|
||||
- reg_cap->low_2ghz_chan,
|
||||
- reg_cap->high_2ghz_chan);
|
||||
+ temp_reg_cap->low_2ghz_chan,
|
||||
+ temp_reg_cap->high_2ghz_chan);
|
||||
}
|
||||
|
||||
if (supported_bands & WMI_HOST_WLAN_5G_CAP) {
|
||||
@@ -7364,9 +7365,15 @@ static int ath11k_mac_setup_channels_rat
|
||||
band->n_bitrates = ath11k_a_rates_size;
|
||||
band->bitrates = ath11k_a_rates;
|
||||
ar->hw->wiphy->bands[NL80211_BAND_6GHZ] = band;
|
||||
+
|
||||
+ if (ar->ab->hw_params.single_pdev_only) {
|
||||
+ phy_id = ath11k_get_phy_id(ar, WMI_HOST_WLAN_5G_CAP);
|
||||
+ temp_reg_cap = &ar->ab->hal_reg_cap[phy_id];
|
||||
+ }
|
||||
+
|
||||
ath11k_mac_update_ch_list(ar, band,
|
||||
- reg_cap->low_5ghz_chan,
|
||||
- reg_cap->high_5ghz_chan);
|
||||
+ temp_reg_cap->low_5ghz_chan,
|
||||
+ temp_reg_cap->high_5ghz_chan);
|
||||
}
|
||||
|
||||
if (reg_cap->low_5ghz_chan < ATH11K_MIN_6G_FREQ) {
|
||||
@@ -7389,12 +7396,12 @@ static int ath11k_mac_setup_channels_rat
|
||||
|
||||
if (ar->ab->hw_params.single_pdev_only) {
|
||||
phy_id = ath11k_get_phy_id(ar, WMI_HOST_WLAN_5G_CAP);
|
||||
- reg_cap = &ar->ab->hal_reg_cap[phy_id];
|
||||
+ temp_reg_cap = &ar->ab->hal_reg_cap[phy_id];
|
||||
}
|
||||
|
||||
ath11k_mac_update_ch_list(ar, band,
|
||||
- reg_cap->low_5ghz_chan,
|
||||
- reg_cap->high_5ghz_chan);
|
||||
+ temp_reg_cap->low_5ghz_chan,
|
||||
+ temp_reg_cap->high_5ghz_chan);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,54 @@
|
||||
From 0f17ae43823b237c73ff138bc067229f7c57e3a2 Mon Sep 17 00:00:00 2001
|
||||
From: Wen Gong <wgong@codeaurora.org>
|
||||
Date: Tue, 28 Sep 2021 14:00:43 +0300
|
||||
Subject: [PATCH 039/120] ath11k: copy cap info of 6G band under
|
||||
WMI_HOST_WLAN_5G_CAP for WCN6855
|
||||
|
||||
WCN6855 has 2 phys, one is 2G, another is 5G/6G, so it should copy the
|
||||
cap info of 6G band under the check of WMI_HOST_WLAN_5G_CAP as well as
|
||||
for the 5G band. Some chips like QCN9074 only have 6G, not have 2G and
|
||||
5G, and this 6G capability is also under WMI_HOST_WLAN_5G_CAP, so this
|
||||
change will not disturb it.
|
||||
|
||||
Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1
|
||||
|
||||
Signed-off-by: Wen Gong <wgong@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20210804181217.88751-4-jouni@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/wmi.c | 22 +++++++++++-----------
|
||||
1 file changed, 11 insertions(+), 11 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/wmi.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
|
||||
@@ -407,18 +407,18 @@ ath11k_pull_mac_phy_cap_svc_ready_ext(st
|
||||
sizeof(u32) * PSOC_HOST_MAX_PHY_SIZE);
|
||||
memcpy(&cap_band->he_ppet, &mac_phy_caps->he_ppet5g,
|
||||
sizeof(struct ath11k_ppe_threshold));
|
||||
- }
|
||||
|
||||
- cap_band = &pdev_cap->band[NL80211_BAND_6GHZ];
|
||||
- cap_band->max_bw_supported = mac_phy_caps->max_bw_supported_5g;
|
||||
- cap_band->ht_cap_info = mac_phy_caps->ht_cap_info_5g;
|
||||
- cap_band->he_cap_info[0] = mac_phy_caps->he_cap_info_5g;
|
||||
- cap_band->he_cap_info[1] = mac_phy_caps->he_cap_info_5g_ext;
|
||||
- cap_band->he_mcs = mac_phy_caps->he_supp_mcs_5g;
|
||||
- memcpy(cap_band->he_cap_phy_info, &mac_phy_caps->he_cap_phy_info_5g,
|
||||
- sizeof(u32) * PSOC_HOST_MAX_PHY_SIZE);
|
||||
- memcpy(&cap_band->he_ppet, &mac_phy_caps->he_ppet5g,
|
||||
- sizeof(struct ath11k_ppe_threshold));
|
||||
+ cap_band = &pdev_cap->band[NL80211_BAND_6GHZ];
|
||||
+ cap_band->max_bw_supported = mac_phy_caps->max_bw_supported_5g;
|
||||
+ cap_band->ht_cap_info = mac_phy_caps->ht_cap_info_5g;
|
||||
+ cap_band->he_cap_info[0] = mac_phy_caps->he_cap_info_5g;
|
||||
+ cap_band->he_cap_info[1] = mac_phy_caps->he_cap_info_5g_ext;
|
||||
+ cap_band->he_mcs = mac_phy_caps->he_supp_mcs_5g;
|
||||
+ memcpy(cap_band->he_cap_phy_info, &mac_phy_caps->he_cap_phy_info_5g,
|
||||
+ sizeof(u32) * PSOC_HOST_MAX_PHY_SIZE);
|
||||
+ memcpy(&cap_band->he_ppet, &mac_phy_caps->he_ppet5g,
|
||||
+ sizeof(struct ath11k_ppe_threshold));
|
||||
+ }
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
From cd18ed4cf8051ceb8590263f5914cb9bb58b0f25 Mon Sep 17 00:00:00 2001
|
||||
From: Baochen Qiang <bqiang@codeaurora.org>
|
||||
Date: Tue, 28 Sep 2021 14:00:43 +0300
|
||||
Subject: [PATCH 040/120] ath11k: Drop MSDU with length error in DP rx path
|
||||
|
||||
There are MSDUs whose length are invalid. For example,
|
||||
attackers may inject on purpose truncated A-MSDUs with
|
||||
invalid MSDU length.
|
||||
|
||||
Such MSDUs are marked with an err bit set in rx attention
|
||||
tlvs, so we can check and drop them.
|
||||
|
||||
Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1
|
||||
Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1
|
||||
|
||||
Signed-off-by: Baochen Qiang <bqiang@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20210913180246.193388-2-jouni@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/dp_rx.c | 18 ++++++++++++++++++
|
||||
1 file changed, 18 insertions(+)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
|
||||
@@ -142,6 +142,18 @@ static u32 ath11k_dp_rx_h_attn_mpdu_err(
|
||||
return errmap;
|
||||
}
|
||||
|
||||
+static bool ath11k_dp_rx_h_attn_msdu_len_err(struct ath11k_base *ab,
|
||||
+ struct hal_rx_desc *desc)
|
||||
+{
|
||||
+ struct rx_attention *rx_attention;
|
||||
+ u32 errmap;
|
||||
+
|
||||
+ rx_attention = ath11k_dp_rx_get_attention(ab, desc);
|
||||
+ errmap = ath11k_dp_rx_h_attn_mpdu_err(rx_attention);
|
||||
+
|
||||
+ return errmap & DP_RX_MPDU_ERR_MSDU_LEN;
|
||||
+}
|
||||
+
|
||||
static u16 ath11k_dp_rx_h_msdu_start_msdu_len(struct ath11k_base *ab,
|
||||
struct hal_rx_desc *desc)
|
||||
{
|
||||
@@ -2525,6 +2537,12 @@ static int ath11k_dp_rx_process_msdu(str
|
||||
}
|
||||
|
||||
rx_desc = (struct hal_rx_desc *)msdu->data;
|
||||
+ if (ath11k_dp_rx_h_attn_msdu_len_err(ab, rx_desc)) {
|
||||
+ ath11k_warn(ar->ab, "msdu len not valid\n");
|
||||
+ ret = -EIO;
|
||||
+ goto free_out;
|
||||
+ }
|
||||
+
|
||||
lrx_desc = (struct hal_rx_desc *)last_buf->data;
|
||||
rx_attention = ath11k_dp_rx_get_attention(ab, lrx_desc);
|
||||
if (!ath11k_dp_rx_h_attn_msdu_done(rx_attention)) {
|
@ -0,0 +1,46 @@
|
||||
From 8a0b899f169d6b6102918327d026922140194fff Mon Sep 17 00:00:00 2001
|
||||
From: Baochen Qiang <bqiang@codeaurora.org>
|
||||
Date: Tue, 28 Sep 2021 14:00:44 +0300
|
||||
Subject: [PATCH 041/120] ath11k: Fix inaccessible debug registers
|
||||
|
||||
Current code clears debug registers after SOC global reset performed
|
||||
in ath11k_pci_sw_reset. However at that time those registers are
|
||||
not accessible due to reset, thus they are actually not cleared at all.
|
||||
For WCN6855, it may cause target fail to initialize. This issue can be
|
||||
fixed by moving clear action ahead.
|
||||
|
||||
In addition, on some specific platforms, need to add delay to wait
|
||||
those registers to become accessible.
|
||||
|
||||
Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1
|
||||
|
||||
Signed-off-by: Baochen Qiang <bqiang@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20210913180246.193388-3-jouni@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/pci.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/pci.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/pci.c
|
||||
@@ -430,6 +430,8 @@ static void ath11k_pci_force_wake(struct
|
||||
|
||||
static void ath11k_pci_sw_reset(struct ath11k_base *ab, bool power_on)
|
||||
{
|
||||
+ mdelay(100);
|
||||
+
|
||||
if (power_on) {
|
||||
ath11k_pci_enable_ltssm(ab);
|
||||
ath11k_pci_clear_all_intrs(ab);
|
||||
@@ -439,9 +441,9 @@ static void ath11k_pci_sw_reset(struct a
|
||||
}
|
||||
|
||||
ath11k_mhi_clear_vector(ab);
|
||||
+ ath11k_pci_clear_dbg_registers(ab);
|
||||
ath11k_pci_soc_global_reset(ab);
|
||||
ath11k_mhi_set_mhictrl_reset(ab);
|
||||
- ath11k_pci_clear_dbg_registers(ab);
|
||||
}
|
||||
|
||||
int ath11k_pci_get_msi_irq(struct device *dev, unsigned int vector)
|
@ -0,0 +1,853 @@
|
||||
From 9e2e2d7a4dd490ff6e95e37611070d3b3a9cf58b Mon Sep 17 00:00:00 2001
|
||||
From: Seevalamuthu Mariappan <seevalam@codeaurora.org>
|
||||
Date: Tue, 28 Sep 2021 14:00:44 +0300
|
||||
Subject: [PATCH 043/120] ath11k: Rename macro ARRAY_TO_STRING to
|
||||
PRINT_ARRAY_TO_BUF
|
||||
|
||||
Renaming of macro is done to describe the macro functionality
|
||||
better as the macro functionality is modified in next patch-sets.
|
||||
No functional changes are done.
|
||||
|
||||
Signed-off-by: Seevalamuthu Mariappan <seevalam@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20210913223148.208026-2-jouni@codeaurora.org
|
||||
---
|
||||
.../wireless/ath/ath11k/debugfs_htt_stats.c | 378 +++++++++---------
|
||||
1 file changed, 189 insertions(+), 189 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.c
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
#define HTT_TLV_HDR_LEN 4
|
||||
|
||||
-#define ARRAY_TO_STRING(out, arr, len) \
|
||||
+#define PRINT_ARRAY_TO_BUF(out, arr, len) \
|
||||
do { \
|
||||
int index = 0; u8 i; \
|
||||
for (i = 0; i < len; i++) { \
|
||||
@@ -195,7 +195,7 @@ htt_print_tx_pdev_stats_urrn_tlv_v(const
|
||||
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_TX_PDEV_STATS_URRN_TLV_V:");
|
||||
|
||||
- ARRAY_TO_STRING(urrn_stats, htt_stats_buf->urrn_stats, num_elems);
|
||||
+ PRINT_ARRAY_TO_BUF(urrn_stats, htt_stats_buf->urrn_stats, num_elems);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "urrn_stats = %s\n", urrn_stats);
|
||||
|
||||
if (len >= buf_len)
|
||||
@@ -220,7 +220,7 @@ htt_print_tx_pdev_stats_flush_tlv_v(cons
|
||||
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_TX_PDEV_STATS_FLUSH_TLV_V:");
|
||||
|
||||
- ARRAY_TO_STRING(flush_errs, htt_stats_buf->flush_errs, num_elems);
|
||||
+ PRINT_ARRAY_TO_BUF(flush_errs, htt_stats_buf->flush_errs, num_elems);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "flush_errs = %s\n", flush_errs);
|
||||
|
||||
if (len >= buf_len)
|
||||
@@ -245,7 +245,7 @@ htt_print_tx_pdev_stats_sifs_tlv_v(const
|
||||
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_TX_PDEV_STATS_SIFS_TLV_V:");
|
||||
|
||||
- ARRAY_TO_STRING(sifs_status, htt_stats_buf->sifs_status, num_elems);
|
||||
+ PRINT_ARRAY_TO_BUF(sifs_status, htt_stats_buf->sifs_status, num_elems);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "sifs_status = %s\n",
|
||||
sifs_status);
|
||||
|
||||
@@ -271,7 +271,7 @@ htt_print_tx_pdev_stats_phy_err_tlv_v(co
|
||||
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_TX_PDEV_STATS_PHY_ERR_TLV_V:");
|
||||
|
||||
- ARRAY_TO_STRING(phy_errs, htt_stats_buf->phy_errs, num_elems);
|
||||
+ PRINT_ARRAY_TO_BUF(phy_errs, htt_stats_buf->phy_errs, num_elems);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "phy_errs = %s\n", phy_errs);
|
||||
|
||||
if (len >= buf_len)
|
||||
@@ -297,7 +297,7 @@ htt_print_tx_pdev_stats_sifs_hist_tlv_v(
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len,
|
||||
"HTT_TX_PDEV_STATS_SIFS_HIST_TLV_V:");
|
||||
|
||||
- ARRAY_TO_STRING(sifs_hist_status, htt_stats_buf->sifs_hist_status, num_elems);
|
||||
+ PRINT_ARRAY_TO_BUF(sifs_hist_status, htt_stats_buf->sifs_hist_status, num_elems);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "sifs_hist_status = %s\n",
|
||||
sifs_hist_status);
|
||||
|
||||
@@ -363,9 +363,9 @@ htt_print_tx_pdev_stats_tried_mpdu_cnt_h
|
||||
htt_stats_buf->hist_bin_size);
|
||||
|
||||
if (required_buffer_size < HTT_MAX_STRING_LEN) {
|
||||
- ARRAY_TO_STRING(tried_mpdu_cnt_hist,
|
||||
- htt_stats_buf->tried_mpdu_cnt_hist,
|
||||
- num_elements);
|
||||
+ PRINT_ARRAY_TO_BUF(tried_mpdu_cnt_hist,
|
||||
+ htt_stats_buf->tried_mpdu_cnt_hist,
|
||||
+ num_elements);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "tried_mpdu_cnt_hist = %s\n",
|
||||
tried_mpdu_cnt_hist);
|
||||
} else {
|
||||
@@ -667,9 +667,9 @@ static inline void htt_print_counter_tlv
|
||||
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_COUNTER_TLV:");
|
||||
|
||||
- ARRAY_TO_STRING(counter_name,
|
||||
- htt_stats_buf->counter_name,
|
||||
- HTT_MAX_COUNTER_NAME);
|
||||
+ PRINT_ARRAY_TO_BUF(counter_name,
|
||||
+ htt_stats_buf->counter_name,
|
||||
+ HTT_MAX_COUNTER_NAME);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "counter_name = %s ", counter_name);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "count = %u\n",
|
||||
htt_stats_buf->count);
|
||||
@@ -794,54 +794,54 @@ static inline void htt_print_tx_peer_rat
|
||||
htt_stats_buf->ack_rssi);
|
||||
|
||||
memset(str_buf, 0x0, HTT_MAX_STRING_LEN);
|
||||
- ARRAY_TO_STRING(str_buf, htt_stats_buf->tx_mcs,
|
||||
- HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS);
|
||||
+ PRINT_ARRAY_TO_BUF(str_buf, htt_stats_buf->tx_mcs,
|
||||
+ HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "tx_mcs = %s ", str_buf);
|
||||
|
||||
memset(str_buf, 0x0, HTT_MAX_STRING_LEN);
|
||||
- ARRAY_TO_STRING(str_buf, htt_stats_buf->tx_su_mcs,
|
||||
- HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS);
|
||||
+ PRINT_ARRAY_TO_BUF(str_buf, htt_stats_buf->tx_su_mcs,
|
||||
+ HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "tx_su_mcs = %s ", str_buf);
|
||||
|
||||
memset(str_buf, 0x0, HTT_MAX_STRING_LEN);
|
||||
- ARRAY_TO_STRING(str_buf, htt_stats_buf->tx_mu_mcs,
|
||||
- HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS);
|
||||
+ PRINT_ARRAY_TO_BUF(str_buf, htt_stats_buf->tx_mu_mcs,
|
||||
+ HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "tx_mu_mcs = %s ", str_buf);
|
||||
|
||||
memset(str_buf, 0x0, HTT_MAX_STRING_LEN);
|
||||
- ARRAY_TO_STRING(str_buf,
|
||||
- htt_stats_buf->tx_nss,
|
||||
- HTT_TX_PDEV_STATS_NUM_SPATIAL_STREAMS);
|
||||
+ PRINT_ARRAY_TO_BUF(str_buf,
|
||||
+ htt_stats_buf->tx_nss,
|
||||
+ HTT_TX_PDEV_STATS_NUM_SPATIAL_STREAMS);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "tx_nss = %s ", str_buf);
|
||||
|
||||
memset(str_buf, 0x0, HTT_MAX_STRING_LEN);
|
||||
- ARRAY_TO_STRING(str_buf,
|
||||
- htt_stats_buf->tx_bw,
|
||||
- HTT_TX_PDEV_STATS_NUM_BW_COUNTERS);
|
||||
+ PRINT_ARRAY_TO_BUF(str_buf,
|
||||
+ htt_stats_buf->tx_bw,
|
||||
+ HTT_TX_PDEV_STATS_NUM_BW_COUNTERS);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "tx_bw = %s ", str_buf);
|
||||
|
||||
memset(str_buf, 0x0, HTT_MAX_STRING_LEN);
|
||||
- ARRAY_TO_STRING(str_buf, htt_stats_buf->tx_stbc,
|
||||
- HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS);
|
||||
+ PRINT_ARRAY_TO_BUF(str_buf, htt_stats_buf->tx_stbc,
|
||||
+ HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "tx_stbc = %s ", str_buf);
|
||||
|
||||
memset(str_buf, 0x0, HTT_MAX_STRING_LEN);
|
||||
- ARRAY_TO_STRING(str_buf, htt_stats_buf->tx_pream,
|
||||
- HTT_TX_PDEV_STATS_NUM_PREAMBLE_TYPES);
|
||||
+ PRINT_ARRAY_TO_BUF(str_buf, htt_stats_buf->tx_pream,
|
||||
+ HTT_TX_PDEV_STATS_NUM_PREAMBLE_TYPES);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "tx_pream = %s ", str_buf);
|
||||
|
||||
for (j = 0; j < HTT_TX_PEER_STATS_NUM_GI_COUNTERS; j++) {
|
||||
- ARRAY_TO_STRING(tx_gi[j],
|
||||
- htt_stats_buf->tx_gi[j],
|
||||
- HTT_TX_PEER_STATS_NUM_MCS_COUNTERS);
|
||||
+ PRINT_ARRAY_TO_BUF(tx_gi[j],
|
||||
+ htt_stats_buf->tx_gi[j],
|
||||
+ HTT_TX_PEER_STATS_NUM_MCS_COUNTERS);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "tx_gi[%u] = %s ",
|
||||
- j, tx_gi[j]);
|
||||
+ j, tx_gi[j]);
|
||||
}
|
||||
|
||||
memset(str_buf, 0x0, HTT_MAX_STRING_LEN);
|
||||
- ARRAY_TO_STRING(str_buf,
|
||||
- htt_stats_buf->tx_dcm,
|
||||
- HTT_TX_PDEV_STATS_NUM_DCM_COUNTERS);
|
||||
+ PRINT_ARRAY_TO_BUF(str_buf,
|
||||
+ htt_stats_buf->tx_dcm,
|
||||
+ HTT_TX_PDEV_STATS_NUM_DCM_COUNTERS);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "tx_dcm = %s\n", str_buf);
|
||||
|
||||
if (len >= buf_len)
|
||||
@@ -895,47 +895,47 @@ static inline void htt_print_rx_peer_rat
|
||||
htt_stats_buf->rssi_comb);
|
||||
|
||||
memset(str_buf, 0x0, HTT_MAX_STRING_LEN);
|
||||
- ARRAY_TO_STRING(str_buf, htt_stats_buf->rx_mcs,
|
||||
- HTT_RX_PDEV_STATS_NUM_MCS_COUNTERS);
|
||||
+ PRINT_ARRAY_TO_BUF(str_buf, htt_stats_buf->rx_mcs,
|
||||
+ HTT_RX_PDEV_STATS_NUM_MCS_COUNTERS);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_mcs = %s ", str_buf);
|
||||
|
||||
memset(str_buf, 0x0, HTT_MAX_STRING_LEN);
|
||||
- ARRAY_TO_STRING(str_buf, htt_stats_buf->rx_nss,
|
||||
- HTT_RX_PDEV_STATS_NUM_SPATIAL_STREAMS);
|
||||
+ PRINT_ARRAY_TO_BUF(str_buf, htt_stats_buf->rx_nss,
|
||||
+ HTT_RX_PDEV_STATS_NUM_SPATIAL_STREAMS);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_nss = %s ", str_buf);
|
||||
|
||||
memset(str_buf, 0x0, HTT_MAX_STRING_LEN);
|
||||
- ARRAY_TO_STRING(str_buf, htt_stats_buf->rx_dcm,
|
||||
- HTT_RX_PDEV_STATS_NUM_DCM_COUNTERS);
|
||||
+ PRINT_ARRAY_TO_BUF(str_buf, htt_stats_buf->rx_dcm,
|
||||
+ HTT_RX_PDEV_STATS_NUM_DCM_COUNTERS);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_dcm = %s ", str_buf);
|
||||
|
||||
memset(str_buf, 0x0, HTT_MAX_STRING_LEN);
|
||||
- ARRAY_TO_STRING(str_buf, htt_stats_buf->rx_stbc,
|
||||
- HTT_RX_PDEV_STATS_NUM_MCS_COUNTERS);
|
||||
+ PRINT_ARRAY_TO_BUF(str_buf, htt_stats_buf->rx_stbc,
|
||||
+ HTT_RX_PDEV_STATS_NUM_MCS_COUNTERS);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_stbc = %s ", str_buf);
|
||||
|
||||
memset(str_buf, 0x0, HTT_MAX_STRING_LEN);
|
||||
- ARRAY_TO_STRING(str_buf, htt_stats_buf->rx_bw,
|
||||
- HTT_RX_PDEV_STATS_NUM_BW_COUNTERS);
|
||||
+ PRINT_ARRAY_TO_BUF(str_buf, htt_stats_buf->rx_bw,
|
||||
+ HTT_RX_PDEV_STATS_NUM_BW_COUNTERS);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_bw = %s ", str_buf);
|
||||
|
||||
for (j = 0; j < HTT_RX_PEER_STATS_NUM_SPATIAL_STREAMS; j++) {
|
||||
- ARRAY_TO_STRING(rssi_chain[j], htt_stats_buf->rssi_chain[j],
|
||||
- HTT_RX_PEER_STATS_NUM_BW_COUNTERS);
|
||||
+ PRINT_ARRAY_TO_BUF(rssi_chain[j], htt_stats_buf->rssi_chain[j],
|
||||
+ HTT_RX_PEER_STATS_NUM_BW_COUNTERS);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "rssi_chain[%u] = %s ",
|
||||
j, rssi_chain[j]);
|
||||
}
|
||||
|
||||
for (j = 0; j < HTT_RX_PEER_STATS_NUM_GI_COUNTERS; j++) {
|
||||
- ARRAY_TO_STRING(rx_gi[j], htt_stats_buf->rx_gi[j],
|
||||
- HTT_RX_PDEV_STATS_NUM_MCS_COUNTERS);
|
||||
+ PRINT_ARRAY_TO_BUF(rx_gi[j], htt_stats_buf->rx_gi[j],
|
||||
+ HTT_RX_PDEV_STATS_NUM_MCS_COUNTERS);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_gi[%u] = %s ",
|
||||
- j, rx_gi[j]);
|
||||
+ j, rx_gi[j]);
|
||||
}
|
||||
|
||||
memset(str_buf, 0x0, HTT_MAX_STRING_LEN);
|
||||
- ARRAY_TO_STRING(str_buf, htt_stats_buf->rx_pream,
|
||||
- HTT_RX_PDEV_STATS_NUM_PREAMBLE_TYPES);
|
||||
+ PRINT_ARRAY_TO_BUF(str_buf, htt_stats_buf->rx_pream,
|
||||
+ HTT_RX_PDEV_STATS_NUM_PREAMBLE_TYPES);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_pream = %s\n", str_buf);
|
||||
|
||||
if (len >= buf_len)
|
||||
@@ -1115,10 +1115,10 @@ htt_print_tx_hwq_difs_latency_stats_tlv_
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "hist_intvl = %u",
|
||||
htt_stats_buf->hist_intvl);
|
||||
|
||||
- ARRAY_TO_STRING(difs_latency_hist, htt_stats_buf->difs_latency_hist,
|
||||
- data_len);
|
||||
+ PRINT_ARRAY_TO_BUF(difs_latency_hist, htt_stats_buf->difs_latency_hist,
|
||||
+ data_len);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "difs_latency_hist = %s\n",
|
||||
- difs_latency_hist);
|
||||
+ difs_latency_hist);
|
||||
|
||||
if (len >= buf_len)
|
||||
buf[buf_len - 1] = 0;
|
||||
@@ -1145,7 +1145,7 @@ htt_print_tx_hwq_cmd_result_stats_tlv_v(
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len,
|
||||
"HTT_TX_HWQ_CMD_RESULT_STATS_TLV_V:");
|
||||
|
||||
- ARRAY_TO_STRING(cmd_result, htt_stats_buf->cmd_result, data_len);
|
||||
+ PRINT_ARRAY_TO_BUF(cmd_result, htt_stats_buf->cmd_result, data_len);
|
||||
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "cmd_result = %s\n", cmd_result);
|
||||
|
||||
@@ -1173,7 +1173,7 @@ htt_print_tx_hwq_cmd_stall_stats_tlv_v(c
|
||||
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_TX_HWQ_CMD_STALL_STATS_TLV_V:");
|
||||
|
||||
- ARRAY_TO_STRING(cmd_stall_status, htt_stats_buf->cmd_stall_status, num_elems);
|
||||
+ PRINT_ARRAY_TO_BUF(cmd_stall_status, htt_stats_buf->cmd_stall_status, num_elems);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "cmd_stall_status = %s\n",
|
||||
cmd_stall_status);
|
||||
|
||||
@@ -1202,7 +1202,7 @@ htt_print_tx_hwq_fes_result_stats_tlv_v(
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len,
|
||||
"HTT_TX_HWQ_FES_RESULT_STATS_TLV_V:");
|
||||
|
||||
- ARRAY_TO_STRING(fes_result, htt_stats_buf->fes_result, num_elems);
|
||||
+ PRINT_ARRAY_TO_BUF(fes_result, htt_stats_buf->fes_result, num_elems);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "fes_result = %s\n", fes_result);
|
||||
|
||||
if (len >= buf_len)
|
||||
@@ -1233,9 +1233,9 @@ htt_print_tx_hwq_tried_mpdu_cnt_hist_tlv
|
||||
htt_stats_buf->hist_bin_size);
|
||||
|
||||
if (required_buffer_size < HTT_MAX_STRING_LEN) {
|
||||
- ARRAY_TO_STRING(tried_mpdu_cnt_hist,
|
||||
- htt_stats_buf->tried_mpdu_cnt_hist,
|
||||
- num_elements);
|
||||
+ PRINT_ARRAY_TO_BUF(tried_mpdu_cnt_hist,
|
||||
+ htt_stats_buf->tried_mpdu_cnt_hist,
|
||||
+ num_elements);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len,
|
||||
"tried_mpdu_cnt_hist = %s\n",
|
||||
tried_mpdu_cnt_hist);
|
||||
@@ -1269,9 +1269,9 @@ htt_print_tx_hwq_txop_used_cnt_hist_tlv_
|
||||
"HTT_TX_HWQ_TXOP_USED_CNT_HIST_TLV_V:");
|
||||
|
||||
if (required_buffer_size < HTT_MAX_STRING_LEN) {
|
||||
- ARRAY_TO_STRING(txop_used_cnt_hist,
|
||||
- htt_stats_buf->txop_used_cnt_hist,
|
||||
- num_elements);
|
||||
+ PRINT_ARRAY_TO_BUF(txop_used_cnt_hist,
|
||||
+ htt_stats_buf->txop_used_cnt_hist,
|
||||
+ num_elements);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "txop_used_cnt_hist = %s\n",
|
||||
txop_used_cnt_hist);
|
||||
} else {
|
||||
@@ -1790,8 +1790,8 @@ htt_print_sched_txq_cmd_posted_tlv_v(con
|
||||
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_SCHED_TXQ_CMD_POSTED_TLV_V:");
|
||||
|
||||
- ARRAY_TO_STRING(sched_cmd_posted, htt_stats_buf->sched_cmd_posted,
|
||||
- num_elements);
|
||||
+ PRINT_ARRAY_TO_BUF(sched_cmd_posted, htt_stats_buf->sched_cmd_posted,
|
||||
+ num_elements);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "sched_cmd_posted = %s\n",
|
||||
sched_cmd_posted);
|
||||
|
||||
@@ -1817,8 +1817,8 @@ htt_print_sched_txq_cmd_reaped_tlv_v(con
|
||||
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_SCHED_TXQ_CMD_REAPED_TLV_V:");
|
||||
|
||||
- ARRAY_TO_STRING(sched_cmd_reaped, htt_stats_buf->sched_cmd_reaped,
|
||||
- num_elements);
|
||||
+ PRINT_ARRAY_TO_BUF(sched_cmd_reaped, htt_stats_buf->sched_cmd_reaped,
|
||||
+ num_elements);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "sched_cmd_reaped = %s\n",
|
||||
sched_cmd_reaped);
|
||||
|
||||
@@ -1847,8 +1847,8 @@ htt_print_sched_txq_sched_order_su_tlv_v
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len,
|
||||
"HTT_SCHED_TXQ_SCHED_ORDER_SU_TLV_V:");
|
||||
|
||||
- ARRAY_TO_STRING(sched_order_su, htt_stats_buf->sched_order_su,
|
||||
- sched_order_su_num_entries);
|
||||
+ PRINT_ARRAY_TO_BUF(sched_order_su, htt_stats_buf->sched_order_su,
|
||||
+ sched_order_su_num_entries);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "sched_order_su = %s\n",
|
||||
sched_order_su);
|
||||
|
||||
@@ -1876,8 +1876,8 @@ htt_print_sched_txq_sched_ineligibility_
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len,
|
||||
"HTT_SCHED_TXQ_SCHED_INELIGIBILITY_V:");
|
||||
|
||||
- ARRAY_TO_STRING(sched_ineligibility, htt_stats_buf->sched_ineligibility,
|
||||
- sched_ineligibility_num_entries);
|
||||
+ PRINT_ARRAY_TO_BUF(sched_ineligibility, htt_stats_buf->sched_ineligibility,
|
||||
+ sched_ineligibility_num_entries);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "sched_ineligibility = %s\n",
|
||||
sched_ineligibility);
|
||||
|
||||
@@ -1992,8 +1992,8 @@ htt_print_tx_tqm_gen_mpdu_stats_tlv_v(co
|
||||
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_TX_TQM_GEN_MPDU_STATS_TLV_V:");
|
||||
|
||||
- ARRAY_TO_STRING(gen_mpdu_end_reason, htt_stats_buf->gen_mpdu_end_reason,
|
||||
- num_elements);
|
||||
+ PRINT_ARRAY_TO_BUF(gen_mpdu_end_reason, htt_stats_buf->gen_mpdu_end_reason,
|
||||
+ num_elements);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "gen_mpdu_end_reason = %s\n",
|
||||
gen_mpdu_end_reason);
|
||||
|
||||
@@ -2020,8 +2020,8 @@ htt_print_tx_tqm_list_mpdu_stats_tlv_v(c
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len,
|
||||
"HTT_TX_TQM_LIST_MPDU_STATS_TLV_V:");
|
||||
|
||||
- ARRAY_TO_STRING(list_mpdu_end_reason, htt_stats_buf->list_mpdu_end_reason,
|
||||
- num_elems);
|
||||
+ PRINT_ARRAY_TO_BUF(list_mpdu_end_reason, htt_stats_buf->list_mpdu_end_reason,
|
||||
+ num_elems);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "list_mpdu_end_reason = %s\n",
|
||||
list_mpdu_end_reason);
|
||||
if (len >= buf_len)
|
||||
@@ -2047,8 +2047,8 @@ htt_print_tx_tqm_list_mpdu_cnt_tlv_v(con
|
||||
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_TX_TQM_LIST_MPDU_CNT_TLV_V:");
|
||||
|
||||
- ARRAY_TO_STRING(list_mpdu_cnt_hist, htt_stats_buf->list_mpdu_cnt_hist,
|
||||
- num_elems);
|
||||
+ PRINT_ARRAY_TO_BUF(list_mpdu_cnt_hist, htt_stats_buf->list_mpdu_cnt_hist,
|
||||
+ num_elems);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "list_mpdu_cnt_hist = %s\n",
|
||||
list_mpdu_cnt_hist);
|
||||
|
||||
@@ -2539,9 +2539,9 @@ htt_print_tx_de_fw2wbm_ring_full_hist_tl
|
||||
"HTT_TX_DE_FW2WBM_RING_FULL_HIST_TLV");
|
||||
|
||||
if (required_buffer_size < HTT_MAX_STRING_LEN) {
|
||||
- ARRAY_TO_STRING(fw2wbm_ring_full_hist,
|
||||
- htt_stats_buf->fw2wbm_ring_full_hist,
|
||||
- num_elements);
|
||||
+ PRINT_ARRAY_TO_BUF(fw2wbm_ring_full_hist,
|
||||
+ htt_stats_buf->fw2wbm_ring_full_hist,
|
||||
+ num_elements);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len,
|
||||
"fw2wbm_ring_full_hist = %s\n",
|
||||
fw2wbm_ring_full_hist);
|
||||
@@ -2634,13 +2634,13 @@ static inline void htt_print_ring_if_sta
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "cons_blockwait_count = %u",
|
||||
htt_stats_buf->cons_blockwait_count);
|
||||
|
||||
- ARRAY_TO_STRING(low_wm_hit_count, htt_stats_buf->low_wm_hit_count,
|
||||
- HTT_STATS_LOW_WM_BINS);
|
||||
+ PRINT_ARRAY_TO_BUF(low_wm_hit_count, htt_stats_buf->low_wm_hit_count,
|
||||
+ HTT_STATS_LOW_WM_BINS);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "low_wm_hit_count = %s ",
|
||||
low_wm_hit_count);
|
||||
|
||||
- ARRAY_TO_STRING(high_wm_hit_count, htt_stats_buf->high_wm_hit_count,
|
||||
- HTT_STATS_HIGH_WM_BINS);
|
||||
+ PRINT_ARRAY_TO_BUF(high_wm_hit_count, htt_stats_buf->high_wm_hit_count,
|
||||
+ HTT_STATS_HIGH_WM_BINS);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "high_wm_hit_count = %s\n",
|
||||
high_wm_hit_count);
|
||||
|
||||
@@ -2687,9 +2687,9 @@ static inline void htt_print_sfm_client_
|
||||
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_SFM_CLIENT_USER_TLV_V:");
|
||||
|
||||
- ARRAY_TO_STRING(dwords_used_by_user_n,
|
||||
- htt_stats_buf->dwords_used_by_user_n,
|
||||
- num_elems);
|
||||
+ PRINT_ARRAY_TO_BUF(dwords_used_by_user_n,
|
||||
+ htt_stats_buf->dwords_used_by_user_n,
|
||||
+ num_elems);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "dwords_used_by_user_n = %s\n",
|
||||
dwords_used_by_user_n);
|
||||
|
||||
@@ -2889,73 +2889,73 @@ static inline void htt_print_tx_pdev_rat
|
||||
htt_stats_buf->tx_legacy_ofdm_rate[7]);
|
||||
|
||||
memset(str_buf, 0x0, HTT_MAX_STRING_LEN);
|
||||
- ARRAY_TO_STRING(str_buf, htt_stats_buf->tx_mcs,
|
||||
- HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS);
|
||||
+ PRINT_ARRAY_TO_BUF(str_buf, htt_stats_buf->tx_mcs,
|
||||
+ HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "tx_mcs = %s ", str_buf);
|
||||
|
||||
memset(str_buf, 0x0, HTT_MAX_STRING_LEN);
|
||||
- ARRAY_TO_STRING(str_buf, htt_stats_buf->ac_mu_mimo_tx_mcs,
|
||||
- HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS);
|
||||
+ PRINT_ARRAY_TO_BUF(str_buf, htt_stats_buf->ac_mu_mimo_tx_mcs,
|
||||
+ HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "ac_mu_mimo_tx_mcs = %s ", str_buf);
|
||||
|
||||
memset(str_buf, 0x0, HTT_MAX_STRING_LEN);
|
||||
- ARRAY_TO_STRING(str_buf, htt_stats_buf->ax_mu_mimo_tx_mcs,
|
||||
- HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS);
|
||||
+ PRINT_ARRAY_TO_BUF(str_buf, htt_stats_buf->ax_mu_mimo_tx_mcs,
|
||||
+ HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "ax_mu_mimo_tx_mcs = %s ", str_buf);
|
||||
|
||||
memset(str_buf, 0x0, HTT_MAX_STRING_LEN);
|
||||
- ARRAY_TO_STRING(str_buf, htt_stats_buf->ofdma_tx_mcs,
|
||||
- HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS);
|
||||
+ PRINT_ARRAY_TO_BUF(str_buf, htt_stats_buf->ofdma_tx_mcs,
|
||||
+ HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "ofdma_tx_mcs = %s ", str_buf);
|
||||
|
||||
memset(str_buf, 0x0, HTT_MAX_STRING_LEN);
|
||||
- ARRAY_TO_STRING(str_buf, htt_stats_buf->tx_nss,
|
||||
- HTT_TX_PDEV_STATS_NUM_SPATIAL_STREAMS);
|
||||
+ PRINT_ARRAY_TO_BUF(str_buf, htt_stats_buf->tx_nss,
|
||||
+ HTT_TX_PDEV_STATS_NUM_SPATIAL_STREAMS);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "tx_nss = %s ", str_buf);
|
||||
|
||||
memset(str_buf, 0x0, HTT_MAX_STRING_LEN);
|
||||
- ARRAY_TO_STRING(str_buf, htt_stats_buf->ac_mu_mimo_tx_nss,
|
||||
- HTT_TX_PDEV_STATS_NUM_SPATIAL_STREAMS);
|
||||
+ PRINT_ARRAY_TO_BUF(str_buf, htt_stats_buf->ac_mu_mimo_tx_nss,
|
||||
+ HTT_TX_PDEV_STATS_NUM_SPATIAL_STREAMS);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "ac_mu_mimo_tx_nss = %s ", str_buf);
|
||||
|
||||
memset(str_buf, 0x0, HTT_MAX_STRING_LEN);
|
||||
- ARRAY_TO_STRING(str_buf, htt_stats_buf->ax_mu_mimo_tx_nss,
|
||||
- HTT_TX_PDEV_STATS_NUM_SPATIAL_STREAMS);
|
||||
+ PRINT_ARRAY_TO_BUF(str_buf, htt_stats_buf->ax_mu_mimo_tx_nss,
|
||||
+ HTT_TX_PDEV_STATS_NUM_SPATIAL_STREAMS);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "ax_mu_mimo_tx_nss = %s ", str_buf);
|
||||
|
||||
memset(str_buf, 0x0, HTT_MAX_STRING_LEN);
|
||||
- ARRAY_TO_STRING(str_buf, htt_stats_buf->ofdma_tx_nss,
|
||||
- HTT_TX_PDEV_STATS_NUM_SPATIAL_STREAMS);
|
||||
+ PRINT_ARRAY_TO_BUF(str_buf, htt_stats_buf->ofdma_tx_nss,
|
||||
+ HTT_TX_PDEV_STATS_NUM_SPATIAL_STREAMS);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "ofdma_tx_nss = %s ", str_buf);
|
||||
|
||||
memset(str_buf, 0x0, HTT_MAX_STRING_LEN);
|
||||
- ARRAY_TO_STRING(str_buf, htt_stats_buf->tx_bw,
|
||||
- HTT_TX_PDEV_STATS_NUM_BW_COUNTERS);
|
||||
+ PRINT_ARRAY_TO_BUF(str_buf, htt_stats_buf->tx_bw,
|
||||
+ HTT_TX_PDEV_STATS_NUM_BW_COUNTERS);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "tx_bw = %s ", str_buf);
|
||||
|
||||
memset(str_buf, 0x0, HTT_MAX_STRING_LEN);
|
||||
- ARRAY_TO_STRING(str_buf, htt_stats_buf->ac_mu_mimo_tx_bw,
|
||||
- HTT_TX_PDEV_STATS_NUM_BW_COUNTERS);
|
||||
+ PRINT_ARRAY_TO_BUF(str_buf, htt_stats_buf->ac_mu_mimo_tx_bw,
|
||||
+ HTT_TX_PDEV_STATS_NUM_BW_COUNTERS);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "ac_mu_mimo_tx_bw = %s ", str_buf);
|
||||
|
||||
memset(str_buf, 0x0, HTT_MAX_STRING_LEN);
|
||||
- ARRAY_TO_STRING(str_buf, htt_stats_buf->ax_mu_mimo_tx_bw,
|
||||
- HTT_TX_PDEV_STATS_NUM_BW_COUNTERS);
|
||||
+ PRINT_ARRAY_TO_BUF(str_buf, htt_stats_buf->ax_mu_mimo_tx_bw,
|
||||
+ HTT_TX_PDEV_STATS_NUM_BW_COUNTERS);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "ax_mu_mimo_tx_bw = %s ", str_buf);
|
||||
|
||||
memset(str_buf, 0x0, HTT_MAX_STRING_LEN);
|
||||
- ARRAY_TO_STRING(str_buf, htt_stats_buf->ofdma_tx_bw,
|
||||
- HTT_TX_PDEV_STATS_NUM_BW_COUNTERS);
|
||||
+ PRINT_ARRAY_TO_BUF(str_buf, htt_stats_buf->ofdma_tx_bw,
|
||||
+ HTT_TX_PDEV_STATS_NUM_BW_COUNTERS);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "ofdma_tx_bw = %s ", str_buf);
|
||||
|
||||
memset(str_buf, 0x0, HTT_MAX_STRING_LEN);
|
||||
- ARRAY_TO_STRING(str_buf, htt_stats_buf->tx_stbc,
|
||||
- HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS);
|
||||
+ PRINT_ARRAY_TO_BUF(str_buf, htt_stats_buf->tx_stbc,
|
||||
+ HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "tx_stbc = %s ", str_buf);
|
||||
|
||||
memset(str_buf, 0x0, HTT_MAX_STRING_LEN);
|
||||
- ARRAY_TO_STRING(str_buf, htt_stats_buf->tx_pream,
|
||||
- HTT_TX_PDEV_STATS_NUM_PREAMBLE_TYPES);
|
||||
+ PRINT_ARRAY_TO_BUF(str_buf, htt_stats_buf->tx_pream,
|
||||
+ HTT_TX_PDEV_STATS_NUM_PREAMBLE_TYPES);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "tx_pream = %s ", str_buf);
|
||||
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "HE LTF: 1x: %u, 2x: %u, 4x: %u",
|
||||
@@ -2965,16 +2965,16 @@ static inline void htt_print_tx_pdev_rat
|
||||
|
||||
/* SU GI Stats */
|
||||
for (j = 0; j < HTT_TX_PDEV_STATS_NUM_GI_COUNTERS; j++) {
|
||||
- ARRAY_TO_STRING(tx_gi[j], htt_stats_buf->tx_gi[j],
|
||||
- HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS);
|
||||
+ PRINT_ARRAY_TO_BUF(tx_gi[j], htt_stats_buf->tx_gi[j],
|
||||
+ HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "tx_gi[%u] = %s ",
|
||||
j, tx_gi[j]);
|
||||
}
|
||||
|
||||
/* AC MU-MIMO GI Stats */
|
||||
for (j = 0; j < HTT_TX_PDEV_STATS_NUM_GI_COUNTERS; j++) {
|
||||
- ARRAY_TO_STRING(tx_gi[j], htt_stats_buf->ac_mu_mimo_tx_gi[j],
|
||||
- HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS);
|
||||
+ PRINT_ARRAY_TO_BUF(tx_gi[j], htt_stats_buf->ac_mu_mimo_tx_gi[j],
|
||||
+ HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len,
|
||||
"ac_mu_mimo_tx_gi[%u] = %s ",
|
||||
j, tx_gi[j]);
|
||||
@@ -2982,8 +2982,8 @@ static inline void htt_print_tx_pdev_rat
|
||||
|
||||
/* AX MU-MIMO GI Stats */
|
||||
for (j = 0; j < HTT_TX_PDEV_STATS_NUM_GI_COUNTERS; j++) {
|
||||
- ARRAY_TO_STRING(tx_gi[j], htt_stats_buf->ax_mu_mimo_tx_gi[j],
|
||||
- HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS);
|
||||
+ PRINT_ARRAY_TO_BUF(tx_gi[j], htt_stats_buf->ax_mu_mimo_tx_gi[j],
|
||||
+ HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len,
|
||||
"ax_mu_mimo_tx_gi[%u] = %s ",
|
||||
j, tx_gi[j]);
|
||||
@@ -2991,15 +2991,15 @@ static inline void htt_print_tx_pdev_rat
|
||||
|
||||
/* DL OFDMA GI Stats */
|
||||
for (j = 0; j < HTT_TX_PDEV_STATS_NUM_GI_COUNTERS; j++) {
|
||||
- ARRAY_TO_STRING(tx_gi[j], htt_stats_buf->ofdma_tx_gi[j],
|
||||
- HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS);
|
||||
+ PRINT_ARRAY_TO_BUF(tx_gi[j], htt_stats_buf->ofdma_tx_gi[j],
|
||||
+ HTT_TX_PDEV_STATS_NUM_MCS_COUNTERS);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "ofdma_tx_gi[%u] = %s ",
|
||||
j, tx_gi[j]);
|
||||
}
|
||||
|
||||
memset(str_buf, 0x0, HTT_MAX_STRING_LEN);
|
||||
- ARRAY_TO_STRING(str_buf, htt_stats_buf->tx_dcm,
|
||||
- HTT_TX_PDEV_STATS_NUM_DCM_COUNTERS);
|
||||
+ PRINT_ARRAY_TO_BUF(str_buf, htt_stats_buf->tx_dcm,
|
||||
+ HTT_TX_PDEV_STATS_NUM_DCM_COUNTERS);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "tx_dcm = %s\n", str_buf);
|
||||
|
||||
if (len >= buf_len)
|
||||
@@ -3064,28 +3064,28 @@ static inline void htt_print_rx_pdev_rat
|
||||
htt_stats_buf->rssi_in_dbm);
|
||||
|
||||
memset(str_buf, 0x0, HTT_MAX_STRING_LEN);
|
||||
- ARRAY_TO_STRING(str_buf, htt_stats_buf->rx_mcs,
|
||||
- HTT_RX_PDEV_STATS_NUM_MCS_COUNTERS);
|
||||
+ PRINT_ARRAY_TO_BUF(str_buf, htt_stats_buf->rx_mcs,
|
||||
+ HTT_RX_PDEV_STATS_NUM_MCS_COUNTERS);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_mcs = %s ", str_buf);
|
||||
|
||||
memset(str_buf, 0x0, HTT_MAX_STRING_LEN);
|
||||
- ARRAY_TO_STRING(str_buf, htt_stats_buf->rx_nss,
|
||||
- HTT_RX_PDEV_STATS_NUM_SPATIAL_STREAMS);
|
||||
+ PRINT_ARRAY_TO_BUF(str_buf, htt_stats_buf->rx_nss,
|
||||
+ HTT_RX_PDEV_STATS_NUM_SPATIAL_STREAMS);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_nss = %s ", str_buf);
|
||||
|
||||
memset(str_buf, 0x0, HTT_MAX_STRING_LEN);
|
||||
- ARRAY_TO_STRING(str_buf, htt_stats_buf->rx_dcm,
|
||||
- HTT_RX_PDEV_STATS_NUM_DCM_COUNTERS);
|
||||
+ PRINT_ARRAY_TO_BUF(str_buf, htt_stats_buf->rx_dcm,
|
||||
+ HTT_RX_PDEV_STATS_NUM_DCM_COUNTERS);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_dcm = %s ", str_buf);
|
||||
|
||||
memset(str_buf, 0x0, HTT_MAX_STRING_LEN);
|
||||
- ARRAY_TO_STRING(str_buf, htt_stats_buf->rx_stbc,
|
||||
- HTT_RX_PDEV_STATS_NUM_MCS_COUNTERS);
|
||||
+ PRINT_ARRAY_TO_BUF(str_buf, htt_stats_buf->rx_stbc,
|
||||
+ HTT_RX_PDEV_STATS_NUM_MCS_COUNTERS);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_stbc = %s ", str_buf);
|
||||
|
||||
memset(str_buf, 0x0, HTT_MAX_STRING_LEN);
|
||||
- ARRAY_TO_STRING(str_buf, htt_stats_buf->rx_bw,
|
||||
- HTT_RX_PDEV_STATS_NUM_BW_COUNTERS);
|
||||
+ PRINT_ARRAY_TO_BUF(str_buf, htt_stats_buf->rx_bw,
|
||||
+ HTT_RX_PDEV_STATS_NUM_BW_COUNTERS);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_bw = %s ", str_buf);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_evm_nss_count = %u",
|
||||
htt_stats_buf->nss_count);
|
||||
@@ -3115,22 +3115,22 @@ static inline void htt_print_rx_pdev_rat
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "pilot_evm_dB_mean = %s ", str_buf);
|
||||
|
||||
for (j = 0; j < HTT_RX_PDEV_STATS_NUM_SPATIAL_STREAMS; j++) {
|
||||
- ARRAY_TO_STRING(rssi_chain[j], htt_stats_buf->rssi_chain[j],
|
||||
- HTT_RX_PDEV_STATS_NUM_BW_COUNTERS);
|
||||
+ PRINT_ARRAY_TO_BUF(rssi_chain[j], htt_stats_buf->rssi_chain[j],
|
||||
+ HTT_RX_PDEV_STATS_NUM_BW_COUNTERS);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "rssi_chain[%u] = %s ",
|
||||
j, rssi_chain[j]);
|
||||
}
|
||||
|
||||
for (j = 0; j < HTT_RX_PDEV_STATS_NUM_GI_COUNTERS; j++) {
|
||||
- ARRAY_TO_STRING(rx_gi[j], htt_stats_buf->rx_gi[j],
|
||||
- HTT_RX_PDEV_STATS_NUM_MCS_COUNTERS);
|
||||
+ PRINT_ARRAY_TO_BUF(rx_gi[j], htt_stats_buf->rx_gi[j],
|
||||
+ HTT_RX_PDEV_STATS_NUM_MCS_COUNTERS);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_gi[%u] = %s ",
|
||||
j, rx_gi[j]);
|
||||
}
|
||||
|
||||
memset(str_buf, 0x0, HTT_MAX_STRING_LEN);
|
||||
- ARRAY_TO_STRING(str_buf, htt_stats_buf->rx_pream,
|
||||
- HTT_RX_PDEV_STATS_NUM_PREAMBLE_TYPES);
|
||||
+ PRINT_ARRAY_TO_BUF(str_buf, htt_stats_buf->rx_pream,
|
||||
+ HTT_RX_PDEV_STATS_NUM_PREAMBLE_TYPES);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_pream = %s", str_buf);
|
||||
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_11ax_su_ext = %u",
|
||||
@@ -3145,14 +3145,14 @@ static inline void htt_print_rx_pdev_rat
|
||||
htt_stats_buf->txbf);
|
||||
|
||||
memset(str_buf, 0x0, HTT_MAX_STRING_LEN);
|
||||
- ARRAY_TO_STRING(str_buf, htt_stats_buf->rx_legacy_cck_rate,
|
||||
- HTT_RX_PDEV_STATS_NUM_LEGACY_CCK_STATS);
|
||||
+ PRINT_ARRAY_TO_BUF(str_buf, htt_stats_buf->rx_legacy_cck_rate,
|
||||
+ HTT_RX_PDEV_STATS_NUM_LEGACY_CCK_STATS);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_legacy_cck_rate = %s ",
|
||||
str_buf);
|
||||
|
||||
memset(str_buf, 0x0, HTT_MAX_STRING_LEN);
|
||||
- ARRAY_TO_STRING(str_buf, htt_stats_buf->rx_legacy_ofdm_rate,
|
||||
- HTT_RX_PDEV_STATS_NUM_LEGACY_OFDM_STATS);
|
||||
+ PRINT_ARRAY_TO_BUF(str_buf, htt_stats_buf->rx_legacy_ofdm_rate,
|
||||
+ HTT_RX_PDEV_STATS_NUM_LEGACY_OFDM_STATS);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_legacy_ofdm_rate = %s ",
|
||||
str_buf);
|
||||
|
||||
@@ -3164,25 +3164,25 @@ static inline void htt_print_rx_pdev_rat
|
||||
htt_stats_buf->rx_11ax_ul_ofdma);
|
||||
|
||||
memset(str_buf, 0x0, HTT_MAX_STRING_LEN);
|
||||
- ARRAY_TO_STRING(str_buf, htt_stats_buf->ul_ofdma_rx_mcs,
|
||||
- HTT_RX_PDEV_STATS_NUM_MCS_COUNTERS);
|
||||
+ PRINT_ARRAY_TO_BUF(str_buf, htt_stats_buf->ul_ofdma_rx_mcs,
|
||||
+ HTT_RX_PDEV_STATS_NUM_MCS_COUNTERS);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "ul_ofdma_rx_mcs = %s ", str_buf);
|
||||
|
||||
for (j = 0; j < HTT_RX_PDEV_STATS_NUM_GI_COUNTERS; j++) {
|
||||
- ARRAY_TO_STRING(rx_gi[j], htt_stats_buf->ul_ofdma_rx_gi[j],
|
||||
- HTT_RX_PDEV_STATS_NUM_MCS_COUNTERS);
|
||||
+ PRINT_ARRAY_TO_BUF(rx_gi[j], htt_stats_buf->ul_ofdma_rx_gi[j],
|
||||
+ HTT_RX_PDEV_STATS_NUM_MCS_COUNTERS);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "ul_ofdma_rx_gi[%u] = %s ",
|
||||
j, rx_gi[j]);
|
||||
}
|
||||
|
||||
memset(str_buf, 0x0, HTT_MAX_STRING_LEN);
|
||||
- ARRAY_TO_STRING(str_buf, htt_stats_buf->ul_ofdma_rx_nss,
|
||||
- HTT_RX_PDEV_STATS_NUM_SPATIAL_STREAMS);
|
||||
+ PRINT_ARRAY_TO_BUF(str_buf, htt_stats_buf->ul_ofdma_rx_nss,
|
||||
+ HTT_RX_PDEV_STATS_NUM_SPATIAL_STREAMS);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "ul_ofdma_rx_nss = %s ", str_buf);
|
||||
|
||||
memset(str_buf, 0x0, HTT_MAX_STRING_LEN);
|
||||
- ARRAY_TO_STRING(str_buf, htt_stats_buf->ul_ofdma_rx_bw,
|
||||
- HTT_RX_PDEV_STATS_NUM_BW_COUNTERS);
|
||||
+ PRINT_ARRAY_TO_BUF(str_buf, htt_stats_buf->ul_ofdma_rx_bw,
|
||||
+ HTT_RX_PDEV_STATS_NUM_BW_COUNTERS);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "ul_ofdma_rx_bw = %s ", str_buf);
|
||||
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "ul_ofdma_rx_stbc = %u",
|
||||
@@ -3191,25 +3191,25 @@ static inline void htt_print_rx_pdev_rat
|
||||
htt_stats_buf->ul_ofdma_rx_ldpc);
|
||||
|
||||
memset(str_buf, 0x0, HTT_MAX_STRING_LEN);
|
||||
- ARRAY_TO_STRING(str_buf, htt_stats_buf->rx_ulofdma_non_data_ppdu,
|
||||
- HTT_RX_PDEV_MAX_OFDMA_NUM_USER);
|
||||
+ PRINT_ARRAY_TO_BUF(str_buf, htt_stats_buf->rx_ulofdma_non_data_ppdu,
|
||||
+ HTT_RX_PDEV_MAX_OFDMA_NUM_USER);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_ulofdma_non_data_ppdu = %s ",
|
||||
str_buf);
|
||||
|
||||
memset(str_buf, 0x0, HTT_MAX_STRING_LEN);
|
||||
- ARRAY_TO_STRING(str_buf, htt_stats_buf->rx_ulofdma_data_ppdu,
|
||||
- HTT_RX_PDEV_MAX_OFDMA_NUM_USER);
|
||||
+ PRINT_ARRAY_TO_BUF(str_buf, htt_stats_buf->rx_ulofdma_data_ppdu,
|
||||
+ HTT_RX_PDEV_MAX_OFDMA_NUM_USER);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_ulofdma_data_ppdu = %s ",
|
||||
str_buf);
|
||||
|
||||
memset(str_buf, 0x0, HTT_MAX_STRING_LEN);
|
||||
- ARRAY_TO_STRING(str_buf, htt_stats_buf->rx_ulofdma_mpdu_ok,
|
||||
- HTT_RX_PDEV_MAX_OFDMA_NUM_USER);
|
||||
+ PRINT_ARRAY_TO_BUF(str_buf, htt_stats_buf->rx_ulofdma_mpdu_ok,
|
||||
+ HTT_RX_PDEV_MAX_OFDMA_NUM_USER);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_ulofdma_mpdu_ok = %s ", str_buf);
|
||||
|
||||
memset(str_buf, 0x0, HTT_MAX_STRING_LEN);
|
||||
- ARRAY_TO_STRING(str_buf, htt_stats_buf->rx_ulofdma_mpdu_fail,
|
||||
- HTT_RX_PDEV_MAX_OFDMA_NUM_USER);
|
||||
+ PRINT_ARRAY_TO_BUF(str_buf, htt_stats_buf->rx_ulofdma_mpdu_fail,
|
||||
+ HTT_RX_PDEV_MAX_OFDMA_NUM_USER);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "rx_ulofdma_mpdu_fail = %s",
|
||||
str_buf);
|
||||
|
||||
@@ -3320,9 +3320,9 @@ htt_print_rx_soc_fw_refill_ring_empty_tl
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len,
|
||||
"HTT_RX_SOC_FW_REFILL_RING_EMPTY_TLV_V:");
|
||||
|
||||
- ARRAY_TO_STRING(refill_ring_empty_cnt,
|
||||
- htt_stats_buf->refill_ring_empty_cnt,
|
||||
- num_elems);
|
||||
+ PRINT_ARRAY_TO_BUF(refill_ring_empty_cnt,
|
||||
+ htt_stats_buf->refill_ring_empty_cnt,
|
||||
+ num_elems);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "refill_ring_empty_cnt = %s\n",
|
||||
refill_ring_empty_cnt);
|
||||
|
||||
@@ -3350,9 +3350,9 @@ htt_print_rx_soc_fw_refill_ring_num_rxdm
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len,
|
||||
"HTT_RX_SOC_FW_REFILL_RING_NUM_RXDMA_ERR_TLV_V:");
|
||||
|
||||
- ARRAY_TO_STRING(rxdma_err_cnt,
|
||||
- htt_stats_buf->rxdma_err,
|
||||
- num_elems);
|
||||
+ PRINT_ARRAY_TO_BUF(rxdma_err_cnt,
|
||||
+ htt_stats_buf->rxdma_err,
|
||||
+ num_elems);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "rxdma_err = %s\n",
|
||||
rxdma_err_cnt);
|
||||
|
||||
@@ -3379,9 +3379,9 @@ htt_print_rx_soc_fw_refill_ring_num_reo_
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len,
|
||||
"HTT_RX_SOC_FW_REFILL_RING_NUM_REO_ERR_TLV_V:");
|
||||
|
||||
- ARRAY_TO_STRING(reo_err_cnt,
|
||||
- htt_stats_buf->reo_err,
|
||||
- num_elems);
|
||||
+ PRINT_ARRAY_TO_BUF(reo_err_cnt,
|
||||
+ htt_stats_buf->reo_err,
|
||||
+ num_elems);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "reo_err = %s\n",
|
||||
reo_err_cnt);
|
||||
|
||||
@@ -3447,9 +3447,9 @@ htt_print_rx_soc_fw_refill_ring_num_refi
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len,
|
||||
"HTT_RX_SOC_FW_REFILL_RING_NUM_REFILL_TLV_V:");
|
||||
|
||||
- ARRAY_TO_STRING(refill_ring_num_refill,
|
||||
- htt_stats_buf->refill_ring_num_refill,
|
||||
- num_elems);
|
||||
+ PRINT_ARRAY_TO_BUF(refill_ring_num_refill,
|
||||
+ htt_stats_buf->refill_ring_num_refill,
|
||||
+ num_elems);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "refill_ring_num_refill = %s\n",
|
||||
refill_ring_num_refill);
|
||||
|
||||
@@ -3491,15 +3491,15 @@ static inline void htt_print_rx_pdev_fw_
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "fw_ring_mpdu_ind = %u",
|
||||
htt_stats_buf->fw_ring_mpdu_ind);
|
||||
|
||||
- ARRAY_TO_STRING(fw_ring_mgmt_subtype,
|
||||
- htt_stats_buf->fw_ring_mgmt_subtype,
|
||||
- HTT_STATS_SUBTYPE_MAX);
|
||||
+ PRINT_ARRAY_TO_BUF(fw_ring_mgmt_subtype,
|
||||
+ htt_stats_buf->fw_ring_mgmt_subtype,
|
||||
+ HTT_STATS_SUBTYPE_MAX);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "fw_ring_mgmt_subtype = %s ",
|
||||
fw_ring_mgmt_subtype);
|
||||
|
||||
- ARRAY_TO_STRING(fw_ring_ctrl_subtype,
|
||||
- htt_stats_buf->fw_ring_ctrl_subtype,
|
||||
- HTT_STATS_SUBTYPE_MAX);
|
||||
+ PRINT_ARRAY_TO_BUF(fw_ring_ctrl_subtype,
|
||||
+ htt_stats_buf->fw_ring_ctrl_subtype,
|
||||
+ HTT_STATS_SUBTYPE_MAX);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "fw_ring_ctrl_subtype = %s ",
|
||||
fw_ring_ctrl_subtype);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "fw_ring_mcast_data_msdu = %u",
|
||||
@@ -3597,9 +3597,9 @@ htt_print_rx_pdev_fw_ring_mpdu_err_tlv_v
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len,
|
||||
"HTT_RX_PDEV_FW_RING_MPDU_ERR_TLV_V:");
|
||||
|
||||
- ARRAY_TO_STRING(fw_ring_mpdu_err,
|
||||
- htt_stats_buf->fw_ring_mpdu_err,
|
||||
- HTT_RX_STATS_RXDMA_MAX_ERR);
|
||||
+ PRINT_ARRAY_TO_BUF(fw_ring_mpdu_err,
|
||||
+ htt_stats_buf->fw_ring_mpdu_err,
|
||||
+ HTT_RX_STATS_RXDMA_MAX_ERR);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "fw_ring_mpdu_err = %s\n",
|
||||
fw_ring_mpdu_err);
|
||||
|
||||
@@ -3625,9 +3625,9 @@ htt_print_rx_pdev_fw_mpdu_drop_tlv_v(con
|
||||
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_RX_PDEV_FW_MPDU_DROP_TLV_V:");
|
||||
|
||||
- ARRAY_TO_STRING(fw_mpdu_drop,
|
||||
- htt_stats_buf->fw_mpdu_drop,
|
||||
- num_elems);
|
||||
+ PRINT_ARRAY_TO_BUF(fw_mpdu_drop,
|
||||
+ htt_stats_buf->fw_mpdu_drop,
|
||||
+ num_elems);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "fw_mpdu_drop = %s\n", fw_mpdu_drop);
|
||||
|
||||
if (len >= buf_len)
|
||||
@@ -3654,9 +3654,9 @@ htt_print_rx_pdev_fw_stats_phy_err_tlv(c
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "total_phy_err_nct = %u",
|
||||
htt_stats_buf->total_phy_err_cnt);
|
||||
|
||||
- ARRAY_TO_STRING(phy_errs,
|
||||
- htt_stats_buf->phy_err,
|
||||
- HTT_STATS_PHY_ERR_MAX);
|
||||
+ PRINT_ARRAY_TO_BUF(phy_errs,
|
||||
+ htt_stats_buf->phy_err,
|
||||
+ HTT_STATS_PHY_ERR_MAX);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "phy_errs = %s\n", phy_errs);
|
||||
|
||||
if (len >= buf_len)
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,683 @@
|
||||
From 6ed731829cf862dc1f73bbd063662d8a6c78a5b7 Mon Sep 17 00:00:00 2001
|
||||
From: Seevalamuthu Mariappan <seevalam@codeaurora.org>
|
||||
Date: Tue, 28 Sep 2021 14:00:45 +0300
|
||||
Subject: [PATCH 046/120] ath11k: Change masking and shifting in htt stats
|
||||
|
||||
In debugfs_htt_stats.c, masking and shifting is done to get
|
||||
stats values. Instead use GENMASK and FIELD_GET to improve
|
||||
code readability and maintenance.
|
||||
|
||||
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.5.0.1-01105-QCAHKSWPL_SILICONZ-1
|
||||
|
||||
Signed-off-by: Seevalamuthu Mariappan <seevalam@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20210913223148.208026-5-jouni@codeaurora.org
|
||||
---
|
||||
.../wireless/ath/ath11k/debugfs_htt_stats.c | 318 ++++++++++--------
|
||||
.../wireless/ath/ath11k/debugfs_htt_stats.h | 54 +++
|
||||
drivers/net/wireless/ath/ath11k/dp.h | 7 +
|
||||
3 files changed, 243 insertions(+), 136 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.c
|
||||
@@ -75,8 +75,8 @@ static inline void htt_print_tx_pdev_sta
|
||||
u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
|
||||
|
||||
len += scnprintf(buf + len, buf_len - len, "HTT_TX_PDEV_STATS_CMN_TLV:\n");
|
||||
- len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
|
||||
- htt_stats_buf->mac_id__word & 0xFF);
|
||||
+ len += scnprintf(buf + len, buf_len - len, "mac_id = %lu\n",
|
||||
+ FIELD_GET(HTT_STATS_MAC_ID, htt_stats_buf->mac_id__word));
|
||||
len += scnprintf(buf + len, buf_len - len, "hw_queued = %u\n",
|
||||
htt_stats_buf->hw_queued);
|
||||
len += scnprintf(buf + len, buf_len - len, "hw_reaped = %u\n",
|
||||
@@ -428,8 +428,8 @@ static inline void htt_print_hw_stats_pd
|
||||
u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
|
||||
|
||||
len += scnprintf(buf + len, buf_len - len, "HTT_HW_STATS_PDEV_ERRS_TLV:\n");
|
||||
- len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
|
||||
- htt_stats_buf->mac_id__word & 0xFF);
|
||||
+ len += scnprintf(buf + len, buf_len - len, "mac_id = %lu\n",
|
||||
+ FIELD_GET(HTT_STATS_MAC_ID, htt_stats_buf->mac_id__word));
|
||||
len += scnprintf(buf + len, buf_len - len, "tx_abort = %u\n",
|
||||
htt_stats_buf->tx_abort);
|
||||
len += scnprintf(buf + len, buf_len - len, "tx_abort_fail_count = %u\n",
|
||||
@@ -480,13 +480,15 @@ static inline void htt_print_msdu_flow_s
|
||||
htt_stats_buf->cur_msdu_count_in_flowq);
|
||||
len += scnprintf(buf + len, buf_len - len, "sw_peer_id = %u\n",
|
||||
htt_stats_buf->sw_peer_id);
|
||||
- len += scnprintf(buf + len, buf_len - len, "tx_flow_no = %u\n",
|
||||
- htt_stats_buf->tx_flow_no__tid_num__drop_rule & 0xFFFF);
|
||||
- len += scnprintf(buf + len, buf_len - len, "tid_num = %u\n",
|
||||
- (htt_stats_buf->tx_flow_no__tid_num__drop_rule & 0xF0000) >> 16);
|
||||
- len += scnprintf(buf + len, buf_len - len, "drop_rule = %u\n",
|
||||
- (htt_stats_buf->tx_flow_no__tid_num__drop_rule & 0x100000) >>
|
||||
- 20);
|
||||
+ len += scnprintf(buf + len, buf_len - len, "tx_flow_no = %lu\n",
|
||||
+ FIELD_GET(HTT_MSDU_FLOW_STATS_TX_FLOW_NO,
|
||||
+ htt_stats_buf->tx_flow_no__tid_num__drop_rule));
|
||||
+ len += scnprintf(buf + len, buf_len - len, "tid_num = %lu\n",
|
||||
+ FIELD_GET(HTT_MSDU_FLOW_STATS_TID_NUM,
|
||||
+ htt_stats_buf->tx_flow_no__tid_num__drop_rule));
|
||||
+ len += scnprintf(buf + len, buf_len - len, "drop_rule = %lu\n",
|
||||
+ FIELD_GET(HTT_MSDU_FLOW_STATS_DROP_RULE,
|
||||
+ htt_stats_buf->tx_flow_no__tid_num__drop_rule));
|
||||
len += scnprintf(buf + len, buf_len - len, "last_cycle_enqueue_count = %u\n",
|
||||
htt_stats_buf->last_cycle_enqueue_count);
|
||||
len += scnprintf(buf + len, buf_len - len, "last_cycle_dequeue_count = %u\n",
|
||||
@@ -516,15 +518,18 @@ static inline void htt_print_tx_tid_stat
|
||||
len += scnprintf(buf + len, buf_len - len, "HTT_TX_TID_STATS_TLV:\n");
|
||||
memcpy(tid_name, &(htt_stats_buf->tid_name[0]), MAX_HTT_TID_NAME);
|
||||
len += scnprintf(buf + len, buf_len - len, "tid_name = %s\n", tid_name);
|
||||
- len += scnprintf(buf + len, buf_len - len, "sw_peer_id = %u\n",
|
||||
- htt_stats_buf->sw_peer_id__tid_num & 0xFFFF);
|
||||
- len += scnprintf(buf + len, buf_len - len, "tid_num = %u\n",
|
||||
- (htt_stats_buf->sw_peer_id__tid_num & 0xFFFF0000) >> 16);
|
||||
- len += scnprintf(buf + len, buf_len - len, "num_sched_pending = %u\n",
|
||||
- htt_stats_buf->num_sched_pending__num_ppdu_in_hwq & 0xFF);
|
||||
- len += scnprintf(buf + len, buf_len - len, "num_ppdu_in_hwq = %u\n",
|
||||
- (htt_stats_buf->num_sched_pending__num_ppdu_in_hwq &
|
||||
- 0xFF00) >> 8);
|
||||
+ len += scnprintf(buf + len, buf_len - len, "sw_peer_id = %lu\n",
|
||||
+ FIELD_GET(HTT_TX_TID_STATS_SW_PEER_ID,
|
||||
+ htt_stats_buf->sw_peer_id__tid_num));
|
||||
+ len += scnprintf(buf + len, buf_len - len, "tid_num = %lu\n",
|
||||
+ FIELD_GET(HTT_TX_TID_STATS_TID_NUM,
|
||||
+ htt_stats_buf->sw_peer_id__tid_num));
|
||||
+ len += scnprintf(buf + len, buf_len - len, "num_sched_pending = %lu\n",
|
||||
+ FIELD_GET(HTT_TX_TID_STATS_NUM_SCHED_PENDING,
|
||||
+ htt_stats_buf->num_sched_pending__num_ppdu_in_hwq));
|
||||
+ len += scnprintf(buf + len, buf_len - len, "num_ppdu_in_hwq = %lu\n",
|
||||
+ FIELD_GET(HTT_TX_TID_STATS_NUM_PPDU_IN_HWQ,
|
||||
+ htt_stats_buf->num_sched_pending__num_ppdu_in_hwq));
|
||||
len += scnprintf(buf + len, buf_len - len, "tid_flags = 0x%x\n",
|
||||
htt_stats_buf->tid_flags);
|
||||
len += scnprintf(buf + len, buf_len - len, "hw_queued = %u\n",
|
||||
@@ -566,15 +571,18 @@ static inline void htt_print_tx_tid_stat
|
||||
len += scnprintf(buf + len, buf_len - len, "HTT_TX_TID_STATS_V1_TLV:\n");
|
||||
memcpy(tid_name, &(htt_stats_buf->tid_name[0]), MAX_HTT_TID_NAME);
|
||||
len += scnprintf(buf + len, buf_len - len, "tid_name = %s\n", tid_name);
|
||||
- len += scnprintf(buf + len, buf_len - len, "sw_peer_id = %u\n",
|
||||
- htt_stats_buf->sw_peer_id__tid_num & 0xFFFF);
|
||||
- len += scnprintf(buf + len, buf_len - len, "tid_num = %u\n",
|
||||
- (htt_stats_buf->sw_peer_id__tid_num & 0xFFFF0000) >> 16);
|
||||
- len += scnprintf(buf + len, buf_len - len, "num_sched_pending = %u\n",
|
||||
- htt_stats_buf->num_sched_pending__num_ppdu_in_hwq & 0xFF);
|
||||
- len += scnprintf(buf + len, buf_len - len, "num_ppdu_in_hwq = %u\n",
|
||||
- (htt_stats_buf->num_sched_pending__num_ppdu_in_hwq &
|
||||
- 0xFF00) >> 8);
|
||||
+ len += scnprintf(buf + len, buf_len - len, "sw_peer_id = %lu\n",
|
||||
+ FIELD_GET(HTT_TX_TID_STATS_V1_SW_PEER_ID,
|
||||
+ htt_stats_buf->sw_peer_id__tid_num));
|
||||
+ len += scnprintf(buf + len, buf_len - len, "tid_num = %lu\n",
|
||||
+ FIELD_GET(HTT_TX_TID_STATS_V1_TID_NUM,
|
||||
+ htt_stats_buf->sw_peer_id__tid_num));
|
||||
+ len += scnprintf(buf + len, buf_len - len, "num_sched_pending = %lu\n",
|
||||
+ FIELD_GET(HTT_TX_TID_STATS_V1_NUM_SCHED_PENDING,
|
||||
+ htt_stats_buf->num_sched_pending__num_ppdu_in_hwq));
|
||||
+ len += scnprintf(buf + len, buf_len - len, "num_ppdu_in_hwq = %lu\n",
|
||||
+ FIELD_GET(HTT_TX_TID_STATS_V1_NUM_PPDU_IN_HWQ,
|
||||
+ htt_stats_buf->num_sched_pending__num_ppdu_in_hwq));
|
||||
len += scnprintf(buf + len, buf_len - len, "tid_flags = 0x%x\n",
|
||||
htt_stats_buf->tid_flags);
|
||||
len += scnprintf(buf + len, buf_len - len, "max_qdepth_bytes = %u\n",
|
||||
@@ -618,10 +626,12 @@ static inline void htt_print_rx_tid_stat
|
||||
char tid_name[MAX_HTT_TID_NAME + 1] = {0};
|
||||
|
||||
len += scnprintf(buf + len, buf_len - len, "HTT_RX_TID_STATS_TLV:\n");
|
||||
- len += scnprintf(buf + len, buf_len - len, "sw_peer_id = %u\n",
|
||||
- htt_stats_buf->sw_peer_id__tid_num & 0xFFFF);
|
||||
- len += scnprintf(buf + len, buf_len - len, "tid_num = %u\n",
|
||||
- (htt_stats_buf->sw_peer_id__tid_num & 0xFFFF0000) >> 16);
|
||||
+ len += scnprintf(buf + len, buf_len - len, "sw_peer_id = %lu\n",
|
||||
+ FIELD_GET(HTT_RX_TID_STATS_SW_PEER_ID,
|
||||
+ htt_stats_buf->sw_peer_id__tid_num));
|
||||
+ len += scnprintf(buf + len, buf_len - len, "tid_num = %lu\n",
|
||||
+ FIELD_GET(HTT_RX_TID_STATS_TID_NUM,
|
||||
+ htt_stats_buf->sw_peer_id__tid_num));
|
||||
memcpy(tid_name, &(htt_stats_buf->tid_name[0]), MAX_HTT_TID_NAME);
|
||||
len += scnprintf(buf + len, buf_len - len, "tid_name = %s\n", tid_name);
|
||||
len += scnprintf(buf + len, buf_len - len, "dup_in_reorder = %u\n",
|
||||
@@ -724,20 +734,29 @@ static inline void htt_print_peer_detail
|
||||
htt_stats_buf->peer_type);
|
||||
len += scnprintf(buf + len, buf_len - len, "sw_peer_id = %u\n",
|
||||
htt_stats_buf->sw_peer_id);
|
||||
- len += scnprintf(buf + len, buf_len - len, "vdev_id = %u\n",
|
||||
- htt_stats_buf->vdev_pdev_ast_idx & 0xFF);
|
||||
- len += scnprintf(buf + len, buf_len - len, "pdev_id = %u\n",
|
||||
- (htt_stats_buf->vdev_pdev_ast_idx & 0xFF00) >> 8);
|
||||
- len += scnprintf(buf + len, buf_len - len, "ast_idx = %u\n",
|
||||
- (htt_stats_buf->vdev_pdev_ast_idx & 0xFFFF0000) >> 16);
|
||||
- len += scnprintf(buf + len, buf_len - len,
|
||||
- "mac_addr = %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
- htt_stats_buf->mac_addr.mac_addr_l32 & 0xFF,
|
||||
- (htt_stats_buf->mac_addr.mac_addr_l32 & 0xFF00) >> 8,
|
||||
- (htt_stats_buf->mac_addr.mac_addr_l32 & 0xFF0000) >> 16,
|
||||
- (htt_stats_buf->mac_addr.mac_addr_l32 & 0xFF000000) >> 24,
|
||||
- (htt_stats_buf->mac_addr.mac_addr_h16 & 0xFF),
|
||||
- (htt_stats_buf->mac_addr.mac_addr_h16 & 0xFF00) >> 8);
|
||||
+ len += scnprintf(buf + len, buf_len - len, "vdev_id = %lu\n",
|
||||
+ FIELD_GET(HTT_PEER_DETAILS_VDEV_ID,
|
||||
+ htt_stats_buf->vdev_pdev_ast_idx));
|
||||
+ len += scnprintf(buf + len, buf_len - len, "pdev_id = %lu\n",
|
||||
+ FIELD_GET(HTT_PEER_DETAILS_PDEV_ID,
|
||||
+ htt_stats_buf->vdev_pdev_ast_idx));
|
||||
+ len += scnprintf(buf + len, buf_len - len, "ast_idx = %lu\n",
|
||||
+ FIELD_GET(HTT_PEER_DETAILS_AST_IDX,
|
||||
+ htt_stats_buf->vdev_pdev_ast_idx));
|
||||
+ len += scnprintf(buf + len, buf_len - len,
|
||||
+ "mac_addr = %02lx:%02lx:%02lx:%02lx:%02lx:%02lx\n",
|
||||
+ FIELD_GET(HTT_MAC_ADDR_L32_0,
|
||||
+ htt_stats_buf->mac_addr.mac_addr_l32),
|
||||
+ FIELD_GET(HTT_MAC_ADDR_L32_1,
|
||||
+ htt_stats_buf->mac_addr.mac_addr_l32),
|
||||
+ FIELD_GET(HTT_MAC_ADDR_L32_2,
|
||||
+ htt_stats_buf->mac_addr.mac_addr_l32),
|
||||
+ FIELD_GET(HTT_MAC_ADDR_L32_3,
|
||||
+ htt_stats_buf->mac_addr.mac_addr_l32),
|
||||
+ FIELD_GET(HTT_MAC_ADDR_H16_0,
|
||||
+ htt_stats_buf->mac_addr.mac_addr_h16),
|
||||
+ FIELD_GET(HTT_MAC_ADDR_H16_1,
|
||||
+ htt_stats_buf->mac_addr.mac_addr_h16));
|
||||
len += scnprintf(buf + len, buf_len - len, "peer_flags = 0x%x\n",
|
||||
htt_stats_buf->peer_flags);
|
||||
len += scnprintf(buf + len, buf_len - len, "qpeer_flags = 0x%x\n\n",
|
||||
@@ -799,7 +818,6 @@ static inline void htt_print_tx_peer_rat
|
||||
buf[len] = 0;
|
||||
|
||||
stats_req->buf_len = len;
|
||||
-
|
||||
}
|
||||
|
||||
static inline void htt_print_rx_peer_rate_stats_tlv(const void *tag_buf,
|
||||
@@ -930,10 +948,12 @@ htt_print_tx_hwq_mu_mimo_cmn_stats_tlv(c
|
||||
u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
|
||||
|
||||
len += scnprintf(buf + len, buf_len - len, "HTT_TX_HWQ_MU_MIMO_CMN_STATS_TLV:\n");
|
||||
- len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
|
||||
- htt_stats_buf->mac_id__hwq_id__word & 0xFF);
|
||||
- len += scnprintf(buf + len, buf_len - len, "hwq_id = %u\n\n",
|
||||
- (htt_stats_buf->mac_id__hwq_id__word & 0xFF00) >> 8);
|
||||
+ len += scnprintf(buf + len, buf_len - len, "mac_id = %lu\n",
|
||||
+ FIELD_GET(HTT_TX_HWQ_STATS_MAC_ID,
|
||||
+ htt_stats_buf->mac_id__hwq_id__word));
|
||||
+ len += scnprintf(buf + len, buf_len - len, "hwq_id = %lu\n\n",
|
||||
+ FIELD_GET(HTT_TX_HWQ_STATS_HWQ_ID,
|
||||
+ htt_stats_buf->mac_id__hwq_id__word));
|
||||
|
||||
if (len >= buf_len)
|
||||
buf[buf_len - 1] = 0;
|
||||
@@ -953,10 +973,12 @@ htt_print_tx_hwq_stats_cmn_tlv(const voi
|
||||
|
||||
/* TODO: HKDBG */
|
||||
len += scnprintf(buf + len, buf_len - len, "HTT_TX_HWQ_STATS_CMN_TLV:\n");
|
||||
- len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
|
||||
- htt_stats_buf->mac_id__hwq_id__word & 0xFF);
|
||||
- len += scnprintf(buf + len, buf_len - len, "hwq_id = %u\n",
|
||||
- (htt_stats_buf->mac_id__hwq_id__word & 0xFF00) >> 8);
|
||||
+ len += scnprintf(buf + len, buf_len - len, "mac_id = %lu\n",
|
||||
+ FIELD_GET(HTT_TX_HWQ_STATS_MAC_ID,
|
||||
+ htt_stats_buf->mac_id__hwq_id__word));
|
||||
+ len += scnprintf(buf + len, buf_len - len, "hwq_id = %lu\n",
|
||||
+ FIELD_GET(HTT_TX_HWQ_STATS_HWQ_ID,
|
||||
+ htt_stats_buf->mac_id__hwq_id__word));
|
||||
len += scnprintf(buf + len, buf_len - len, "xretry = %u\n",
|
||||
htt_stats_buf->xretry);
|
||||
len += scnprintf(buf + len, buf_len - len, "underrun_cnt = %u\n",
|
||||
@@ -1281,8 +1303,8 @@ htt_print_tx_selfgen_cmn_stats_tlv(const
|
||||
u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
|
||||
|
||||
len += scnprintf(buf + len, buf_len - len, "HTT_TX_SELFGEN_CMN_STATS_TLV:\n");
|
||||
- len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
|
||||
- htt_stats_buf->mac_id__word & 0xFF);
|
||||
+ len += scnprintf(buf + len, buf_len - len, "mac_id = %lu\n",
|
||||
+ FIELD_GET(HTT_STATS_MAC_ID, htt_stats_buf->mac_id__word));
|
||||
len += scnprintf(buf + len, buf_len - len, "su_bar = %u\n",
|
||||
htt_stats_buf->su_bar);
|
||||
len += scnprintf(buf + len, buf_len - len, "rts = %u\n",
|
||||
@@ -1769,10 +1791,12 @@ htt_print_tx_pdev_stats_sched_per_txq_tl
|
||||
|
||||
len += scnprintf(buf + len, buf_len - len,
|
||||
"HTT_TX_PDEV_STATS_SCHED_PER_TXQ_TLV:\n");
|
||||
- len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
|
||||
- htt_stats_buf->mac_id__txq_id__word & 0xFF);
|
||||
- len += scnprintf(buf + len, buf_len - len, "txq_id = %u\n",
|
||||
- (htt_stats_buf->mac_id__txq_id__word & 0xFF00) >> 8);
|
||||
+ len += scnprintf(buf + len, buf_len - len, "mac_id = %lu\n",
|
||||
+ FIELD_GET(HTT_TX_PDEV_STATS_SCHED_PER_TXQ_MAC_ID,
|
||||
+ htt_stats_buf->mac_id__txq_id__word));
|
||||
+ len += scnprintf(buf + len, buf_len - len, "txq_id = %lu\n",
|
||||
+ FIELD_GET(HTT_TX_PDEV_STATS_SCHED_PER_TXQ_ID,
|
||||
+ htt_stats_buf->mac_id__txq_id__word));
|
||||
len += scnprintf(buf + len, buf_len - len, "sched_policy = %u\n",
|
||||
htt_stats_buf->sched_policy);
|
||||
len += scnprintf(buf + len, buf_len - len,
|
||||
@@ -1833,8 +1857,8 @@ static inline void htt_print_stats_tx_sc
|
||||
u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
|
||||
|
||||
len += scnprintf(buf + len, buf_len - len, "HTT_STATS_TX_SCHED_CMN_TLV:\n");
|
||||
- len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
|
||||
- htt_stats_buf->mac_id__word & 0xFF);
|
||||
+ len += scnprintf(buf + len, buf_len - len, "mac_id = %lu\n",
|
||||
+ FIELD_GET(HTT_STATS_MAC_ID, htt_stats_buf->mac_id__word));
|
||||
len += scnprintf(buf + len, buf_len - len, "current_timestamp = %u\n\n",
|
||||
htt_stats_buf->current_timestamp);
|
||||
|
||||
@@ -2011,8 +2035,8 @@ static inline void htt_print_tx_tqm_cmn_
|
||||
u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
|
||||
|
||||
len += scnprintf(buf + len, buf_len - len, "HTT_TX_TQM_CMN_STATS_TLV:\n");
|
||||
- len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
|
||||
- htt_stats_buf->mac_id__word & 0xFF);
|
||||
+ len += scnprintf(buf + len, buf_len - len, "mac_id = %lu\n",
|
||||
+ FIELD_GET(HTT_STATS_MAC_ID, htt_stats_buf->mac_id__word));
|
||||
len += scnprintf(buf + len, buf_len - len, "max_cmdq_id = %u\n",
|
||||
htt_stats_buf->max_cmdq_id);
|
||||
len += scnprintf(buf + len, buf_len - len, "list_mpdu_cnt_hist_intvl = %u\n",
|
||||
@@ -2069,10 +2093,12 @@ static inline void htt_print_tx_tqm_cmdq
|
||||
u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
|
||||
|
||||
len += scnprintf(buf + len, buf_len - len, "HTT_TX_TQM_CMDQ_STATUS_TLV:\n");
|
||||
- len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
|
||||
- htt_stats_buf->mac_id__cmdq_id__word & 0xFF);
|
||||
- len += scnprintf(buf + len, buf_len - len, "cmdq_id = %u\n\n",
|
||||
- (htt_stats_buf->mac_id__cmdq_id__word & 0xFF00) >> 8);
|
||||
+ len += scnprintf(buf + len, buf_len - len, "mac_id = %lu\n",
|
||||
+ FIELD_GET(HTT_TX_TQM_CMDQ_STATUS_MAC_ID,
|
||||
+ htt_stats_buf->mac_id__cmdq_id__word));
|
||||
+ len += scnprintf(buf + len, buf_len - len, "cmdq_id = %lu\n\n",
|
||||
+ FIELD_GET(HTT_TX_TQM_CMDQ_STATUS_CMDQ_ID,
|
||||
+ htt_stats_buf->mac_id__cmdq_id__word));
|
||||
len += scnprintf(buf + len, buf_len - len, "sync_cmd = %u\n",
|
||||
htt_stats_buf->sync_cmd);
|
||||
len += scnprintf(buf + len, buf_len - len, "write_cmd = %u\n",
|
||||
@@ -2417,8 +2443,8 @@ htt_print_tx_de_cmn_stats_tlv(const void
|
||||
u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
|
||||
|
||||
len += scnprintf(buf + len, buf_len - len, "HTT_TX_DE_CMN_STATS_TLV:\n");
|
||||
- len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
|
||||
- htt_stats_buf->mac_id__word & 0xFF);
|
||||
+ len += scnprintf(buf + len, buf_len - len, "mac_id = %lu\n",
|
||||
+ FIELD_GET(HTT_STATS_MAC_ID, htt_stats_buf->mac_id__word));
|
||||
len += scnprintf(buf + len, buf_len - len, "tcl2fw_entry_count = %u\n",
|
||||
htt_stats_buf->tcl2fw_entry_count);
|
||||
len += scnprintf(buf + len, buf_len - len, "not_to_fw = %u\n",
|
||||
@@ -2453,26 +2479,32 @@ static inline void htt_print_ring_if_sta
|
||||
htt_stats_buf->base_addr);
|
||||
len += scnprintf(buf + len, buf_len - len, "elem_size = %u\n",
|
||||
htt_stats_buf->elem_size);
|
||||
- len += scnprintf(buf + len, buf_len - len, "num_elems = %u\n",
|
||||
- htt_stats_buf->num_elems__prefetch_tail_idx & 0xFFFF);
|
||||
- len += scnprintf(buf + len, buf_len - len, "prefetch_tail_idx = %u\n",
|
||||
- (htt_stats_buf->num_elems__prefetch_tail_idx &
|
||||
- 0xFFFF0000) >> 16);
|
||||
- len += scnprintf(buf + len, buf_len - len, "head_idx = %u\n",
|
||||
- htt_stats_buf->head_idx__tail_idx & 0xFFFF);
|
||||
- len += scnprintf(buf + len, buf_len - len, "tail_idx = %u\n",
|
||||
- (htt_stats_buf->head_idx__tail_idx & 0xFFFF0000) >> 16);
|
||||
- len += scnprintf(buf + len, buf_len - len, "shadow_head_idx = %u\n",
|
||||
- htt_stats_buf->shadow_head_idx__shadow_tail_idx & 0xFFFF);
|
||||
- len += scnprintf(buf + len, buf_len - len, "shadow_tail_idx = %u\n",
|
||||
- (htt_stats_buf->shadow_head_idx__shadow_tail_idx &
|
||||
- 0xFFFF0000) >> 16);
|
||||
+ len += scnprintf(buf + len, buf_len - len, "num_elems = %lu\n",
|
||||
+ FIELD_GET(HTT_RING_IF_STATS_NUM_ELEMS,
|
||||
+ htt_stats_buf->num_elems__prefetch_tail_idx));
|
||||
+ len += scnprintf(buf + len, buf_len - len, "prefetch_tail_idx = %lu\n",
|
||||
+ FIELD_GET(HTT_RING_IF_STATS_PREFETCH_TAIL_INDEX,
|
||||
+ htt_stats_buf->num_elems__prefetch_tail_idx));
|
||||
+ len += scnprintf(buf + len, buf_len - len, "head_idx = %lu\n",
|
||||
+ FIELD_GET(HTT_RING_IF_STATS_HEAD_IDX,
|
||||
+ htt_stats_buf->head_idx__tail_idx));
|
||||
+ len += scnprintf(buf + len, buf_len - len, "tail_idx = %lu\n",
|
||||
+ FIELD_GET(HTT_RING_IF_STATS_TAIL_IDX,
|
||||
+ htt_stats_buf->head_idx__tail_idx));
|
||||
+ len += scnprintf(buf + len, buf_len - len, "shadow_head_idx = %lu\n",
|
||||
+ FIELD_GET(HTT_RING_IF_STATS_SHADOW_HEAD_IDX,
|
||||
+ htt_stats_buf->shadow_head_idx__shadow_tail_idx));
|
||||
+ len += scnprintf(buf + len, buf_len - len, "shadow_tail_idx = %lu\n",
|
||||
+ FIELD_GET(HTT_RING_IF_STATS_SHADOW_TAIL_IDX,
|
||||
+ htt_stats_buf->shadow_head_idx__shadow_tail_idx));
|
||||
len += scnprintf(buf + len, buf_len - len, "num_tail_incr = %u\n",
|
||||
htt_stats_buf->num_tail_incr);
|
||||
- len += scnprintf(buf + len, buf_len - len, "lwm_thresh = %u\n",
|
||||
- htt_stats_buf->lwm_thresh__hwm_thresh & 0xFFFF);
|
||||
- len += scnprintf(buf + len, buf_len - len, "hwm_thresh = %u\n",
|
||||
- (htt_stats_buf->lwm_thresh__hwm_thresh & 0xFFFF0000) >> 16);
|
||||
+ len += scnprintf(buf + len, buf_len - len, "lwm_thresh = %lu\n",
|
||||
+ FIELD_GET(HTT_RING_IF_STATS_LWM_THRESH,
|
||||
+ htt_stats_buf->lwm_thresh__hwm_thresh));
|
||||
+ len += scnprintf(buf + len, buf_len - len, "hwm_thresh = %lu\n",
|
||||
+ FIELD_GET(HTT_RING_IF_STATS_HWM_THRESH,
|
||||
+ htt_stats_buf->lwm_thresh__hwm_thresh));
|
||||
len += scnprintf(buf + len, buf_len - len, "overrun_hit_count = %u\n",
|
||||
htt_stats_buf->overrun_hit_count);
|
||||
len += scnprintf(buf + len, buf_len - len, "underrun_hit_count = %u\n",
|
||||
@@ -2504,8 +2536,8 @@ static inline void htt_print_ring_if_cmn
|
||||
u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
|
||||
|
||||
len += scnprintf(buf + len, buf_len - len, "HTT_RING_IF_CMN_TLV:\n");
|
||||
- len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
|
||||
- htt_stats_buf->mac_id__word & 0xFF);
|
||||
+ len += scnprintf(buf + len, buf_len - len, "mac_id = %lu\n",
|
||||
+ FIELD_GET(HTT_STATS_MAC_ID, htt_stats_buf->mac_id__word));
|
||||
len += scnprintf(buf + len, buf_len - len, "num_records = %u\n\n",
|
||||
htt_stats_buf->num_records);
|
||||
|
||||
@@ -2581,8 +2613,8 @@ static inline void htt_print_sfm_cmn_tlv
|
||||
u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
|
||||
|
||||
len += scnprintf(buf + len, buf_len - len, "HTT_SFM_CMN_TLV:\n");
|
||||
- len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
|
||||
- htt_stats_buf->mac_id__word & 0xFF);
|
||||
+ len += scnprintf(buf + len, buf_len - len, "mac_id = %lu\n",
|
||||
+ FIELD_GET(HTT_STATS_MAC_ID, htt_stats_buf->mac_id__word));
|
||||
len += scnprintf(buf + len, buf_len - len, "buf_total = %u\n",
|
||||
htt_stats_buf->buf_total);
|
||||
len += scnprintf(buf + len, buf_len - len, "mem_empty = %u\n",
|
||||
@@ -2609,14 +2641,18 @@ static inline void htt_print_sring_stats
|
||||
u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
|
||||
|
||||
len += scnprintf(buf + len, buf_len - len, "HTT_SRING_STATS_TLV:\n");
|
||||
- len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
|
||||
- htt_stats_buf->mac_id__ring_id__arena__ep & 0xFF);
|
||||
- len += scnprintf(buf + len, buf_len - len, "ring_id = %u\n",
|
||||
- (htt_stats_buf->mac_id__ring_id__arena__ep & 0xFF00) >> 8);
|
||||
- len += scnprintf(buf + len, buf_len - len, "arena = %u\n",
|
||||
- (htt_stats_buf->mac_id__ring_id__arena__ep & 0xFF0000) >> 16);
|
||||
- len += scnprintf(buf + len, buf_len - len, "ep = %u\n",
|
||||
- (htt_stats_buf->mac_id__ring_id__arena__ep & 0x1000000) >> 24);
|
||||
+ len += scnprintf(buf + len, buf_len - len, "mac_id = %lu\n",
|
||||
+ FIELD_GET(HTT_SRING_STATS_MAC_ID,
|
||||
+ htt_stats_buf->mac_id__ring_id__arena__ep));
|
||||
+ len += scnprintf(buf + len, buf_len - len, "ring_id = %lu\n",
|
||||
+ FIELD_GET(HTT_SRING_STATS_RING_ID,
|
||||
+ htt_stats_buf->mac_id__ring_id__arena__ep));
|
||||
+ len += scnprintf(buf + len, buf_len - len, "arena = %lu\n",
|
||||
+ FIELD_GET(HTT_SRING_STATS_ARENA,
|
||||
+ htt_stats_buf->mac_id__ring_id__arena__ep));
|
||||
+ len += scnprintf(buf + len, buf_len - len, "ep = %lu\n",
|
||||
+ FIELD_GET(HTT_SRING_STATS_EP,
|
||||
+ htt_stats_buf->mac_id__ring_id__arena__ep));
|
||||
len += scnprintf(buf + len, buf_len - len, "base_addr_lsb = 0x%x\n",
|
||||
htt_stats_buf->base_addr_lsb);
|
||||
len += scnprintf(buf + len, buf_len - len, "base_addr_msb = 0x%x\n",
|
||||
@@ -2625,25 +2661,30 @@ static inline void htt_print_sring_stats
|
||||
htt_stats_buf->ring_size);
|
||||
len += scnprintf(buf + len, buf_len - len, "elem_size = %u\n",
|
||||
htt_stats_buf->elem_size);
|
||||
- len += scnprintf(buf + len, buf_len - len, "num_avail_words = %u\n",
|
||||
- htt_stats_buf->num_avail_words__num_valid_words & 0xFFFF);
|
||||
- len += scnprintf(buf + len, buf_len - len, "num_valid_words = %u\n",
|
||||
- (htt_stats_buf->num_avail_words__num_valid_words &
|
||||
- 0xFFFF0000) >> 16);
|
||||
- len += scnprintf(buf + len, buf_len - len, "head_ptr = %u\n",
|
||||
- htt_stats_buf->head_ptr__tail_ptr & 0xFFFF);
|
||||
- len += scnprintf(buf + len, buf_len - len, "tail_ptr = %u\n",
|
||||
- (htt_stats_buf->head_ptr__tail_ptr & 0xFFFF0000) >> 16);
|
||||
- len += scnprintf(buf + len, buf_len - len, "consumer_empty = %u\n",
|
||||
- htt_stats_buf->consumer_empty__producer_full & 0xFFFF);
|
||||
- len += scnprintf(buf + len, buf_len - len, "producer_full = %u\n",
|
||||
- (htt_stats_buf->consumer_empty__producer_full &
|
||||
- 0xFFFF0000) >> 16);
|
||||
- len += scnprintf(buf + len, buf_len - len, "prefetch_count = %u\n",
|
||||
- htt_stats_buf->prefetch_count__internal_tail_ptr & 0xFFFF);
|
||||
- len += scnprintf(buf + len, buf_len - len, "internal_tail_ptr = %u\n\n",
|
||||
- (htt_stats_buf->prefetch_count__internal_tail_ptr &
|
||||
- 0xFFFF0000) >> 16);
|
||||
+ len += scnprintf(buf + len, buf_len - len, "num_avail_words = %lu\n",
|
||||
+ FIELD_GET(HTT_SRING_STATS_NUM_AVAIL_WORDS,
|
||||
+ htt_stats_buf->num_avail_words__num_valid_words));
|
||||
+ len += scnprintf(buf + len, buf_len - len, "num_valid_words = %lu\n",
|
||||
+ FIELD_GET(HTT_SRING_STATS_NUM_VALID_WORDS,
|
||||
+ htt_stats_buf->num_avail_words__num_valid_words));
|
||||
+ len += scnprintf(buf + len, buf_len - len, "head_ptr = %lu\n",
|
||||
+ FIELD_GET(HTT_SRING_STATS_HEAD_PTR,
|
||||
+ htt_stats_buf->head_ptr__tail_ptr));
|
||||
+ len += scnprintf(buf + len, buf_len - len, "tail_ptr = %lu\n",
|
||||
+ FIELD_GET(HTT_SRING_STATS_TAIL_PTR,
|
||||
+ htt_stats_buf->head_ptr__tail_ptr));
|
||||
+ len += scnprintf(buf + len, buf_len - len, "consumer_empty = %lu\n",
|
||||
+ FIELD_GET(HTT_SRING_STATS_CONSUMER_EMPTY,
|
||||
+ htt_stats_buf->consumer_empty__producer_full));
|
||||
+ len += scnprintf(buf + len, buf_len - len, "producer_full = %lu\n",
|
||||
+ FIELD_GET(HTT_SRING_STATS_PRODUCER_FULL,
|
||||
+ htt_stats_buf->consumer_empty__producer_full));
|
||||
+ len += scnprintf(buf + len, buf_len - len, "prefetch_count = %lu\n",
|
||||
+ FIELD_GET(HTT_SRING_STATS_PREFETCH_COUNT,
|
||||
+ htt_stats_buf->prefetch_count__internal_tail_ptr));
|
||||
+ len += scnprintf(buf + len, buf_len - len, "internal_tail_ptr = %lu\n\n",
|
||||
+ FIELD_GET(HTT_SRING_STATS_INTERNAL_TAIL_PTR,
|
||||
+ htt_stats_buf->prefetch_count__internal_tail_ptr));
|
||||
|
||||
if (len >= buf_len)
|
||||
buf[buf_len - 1] = 0;
|
||||
@@ -2683,8 +2724,8 @@ static inline void htt_print_tx_pdev_rat
|
||||
u8 j;
|
||||
|
||||
len += scnprintf(buf + len, buf_len - len, "HTT_TX_PDEV_RATE_STATS_TLV:\n");
|
||||
- len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
|
||||
- htt_stats_buf->mac_id__word & 0xFF);
|
||||
+ len += scnprintf(buf + len, buf_len - len, "mac_id = %lu\n",
|
||||
+ FIELD_GET(HTT_STATS_MAC_ID, htt_stats_buf->mac_id__word));
|
||||
len += scnprintf(buf + len, buf_len - len, "tx_ldpc = %u\n",
|
||||
htt_stats_buf->tx_ldpc);
|
||||
len += scnprintf(buf + len, buf_len - len, "ac_mu_mimo_tx_ldpc = %u\n",
|
||||
@@ -2809,8 +2850,8 @@ static inline void htt_print_rx_pdev_rat
|
||||
u8 i, j;
|
||||
|
||||
len += scnprintf(buf + len, buf_len - len, "HTT_RX_PDEV_RATE_STATS_TLV:\n");
|
||||
- len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
|
||||
- htt_stats_buf->mac_id__word & 0xFF);
|
||||
+ len += scnprintf(buf + len, buf_len - len, "mac_id = %lu\n",
|
||||
+ FIELD_GET(HTT_STATS_MAC_ID, htt_stats_buf->mac_id__word));
|
||||
len += scnprintf(buf + len, buf_len - len, "nsts = %u\n",
|
||||
htt_stats_buf->nsts);
|
||||
len += scnprintf(buf + len, buf_len - len, "rx_ldpc = %u\n",
|
||||
@@ -2844,7 +2885,6 @@ static inline void htt_print_rx_pdev_rat
|
||||
htt_stats_buf->pilot_count);
|
||||
|
||||
for (j = 0; j < HTT_RX_PDEV_STATS_NUM_SPATIAL_STREAMS; j++) {
|
||||
-
|
||||
len += scnprintf(buf + len, buf_len - len,
|
||||
"pilot_evm_db[%u] = ", j);
|
||||
for (i = 0; i < HTT_RX_PDEV_STATS_RXEVM_MAX_PILOTS_PER_NSS; i++)
|
||||
@@ -3173,8 +3213,8 @@ static inline void htt_print_rx_pdev_fw_
|
||||
u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
|
||||
|
||||
len += scnprintf(buf + len, buf_len - len, "HTT_RX_PDEV_FW_STATS_TLV:\n");
|
||||
- len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
|
||||
- htt_stats_buf->mac_id__word & 0xFF);
|
||||
+ len += scnprintf(buf + len, buf_len - len, "mac_id = %lu\n",
|
||||
+ FIELD_GET(HTT_STATS_MAC_ID, htt_stats_buf->mac_id__word));
|
||||
len += scnprintf(buf + len, buf_len - len, "ppdu_recvd = %u\n",
|
||||
htt_stats_buf->ppdu_recvd);
|
||||
len += scnprintf(buf + len, buf_len - len, "mpdu_cnt_fcs_ok = %u\n",
|
||||
@@ -3422,8 +3462,8 @@ static inline void htt_print_hw_stats_wh
|
||||
u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
|
||||
|
||||
len += scnprintf(buf + len, buf_len - len, "HTT_HW_STATS_WHAL_TX_TLV:\n");
|
||||
- len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n",
|
||||
- htt_stats_buf->mac_id__word & 0xFF);
|
||||
+ len += scnprintf(buf + len, buf_len - len, "mac_id = %lu\n",
|
||||
+ FIELD_GET(HTT_STATS_MAC_ID, htt_stats_buf->mac_id__word));
|
||||
len += scnprintf(buf + len, buf_len - len, "last_unpause_ppdu_id = %u\n",
|
||||
htt_stats_buf->last_unpause_ppdu_id);
|
||||
len += scnprintf(buf + len, buf_len - len, "hwsch_unpause_wait_tqm_write = %u\n",
|
||||
@@ -3492,13 +3532,19 @@ htt_print_pdev_stats_twt_session_tlv(con
|
||||
len += scnprintf(buf + len, buf_len - len, "vdev_id = %u\n",
|
||||
htt_stats_buf->vdev_id);
|
||||
len += scnprintf(buf + len, buf_len - len,
|
||||
- "peer_mac = %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
- htt_stats_buf->peer_mac.mac_addr_l32 & 0xFF,
|
||||
- (htt_stats_buf->peer_mac.mac_addr_l32 & 0xFF00) >> 8,
|
||||
- (htt_stats_buf->peer_mac.mac_addr_l32 & 0xFF0000) >> 16,
|
||||
- (htt_stats_buf->peer_mac.mac_addr_l32 & 0xFF000000) >> 24,
|
||||
- (htt_stats_buf->peer_mac.mac_addr_h16 & 0xFF),
|
||||
- (htt_stats_buf->peer_mac.mac_addr_h16 & 0xFF00) >> 8);
|
||||
+ "peer_mac = %02lx:%02lx:%02lx:%02lx:%02lx:%02lx\n",
|
||||
+ FIELD_GET(HTT_MAC_ADDR_L32_0,
|
||||
+ htt_stats_buf->peer_mac.mac_addr_l32),
|
||||
+ FIELD_GET(HTT_MAC_ADDR_L32_1,
|
||||
+ htt_stats_buf->peer_mac.mac_addr_l32),
|
||||
+ FIELD_GET(HTT_MAC_ADDR_L32_2,
|
||||
+ htt_stats_buf->peer_mac.mac_addr_l32),
|
||||
+ FIELD_GET(HTT_MAC_ADDR_L32_3,
|
||||
+ htt_stats_buf->peer_mac.mac_addr_l32),
|
||||
+ FIELD_GET(HTT_MAC_ADDR_H16_0,
|
||||
+ htt_stats_buf->peer_mac.mac_addr_h16),
|
||||
+ FIELD_GET(HTT_MAC_ADDR_H16_1,
|
||||
+ htt_stats_buf->peer_mac.mac_addr_h16));
|
||||
len += scnprintf(buf + len, buf_len - len, "flow_id_flags = %u\n",
|
||||
htt_stats_buf->flow_id_flags);
|
||||
len += scnprintf(buf + len, buf_len - len, "dialog_id = %u\n",
|
||||
--- a/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.h
|
||||
@@ -137,6 +137,8 @@ struct htt_stats_string_tlv {
|
||||
u32 data[0]; /* Can be variable length */
|
||||
} __packed;
|
||||
|
||||
+#define HTT_STATS_MAC_ID GENMASK(7, 0)
|
||||
+
|
||||
/* == TX PDEV STATS == */
|
||||
struct htt_tx_pdev_stats_cmn_tlv {
|
||||
u32 mac_id__word;
|
||||
@@ -290,6 +292,10 @@ struct htt_hw_stats_whal_tx_tlv {
|
||||
};
|
||||
|
||||
/* ============ PEER STATS ============ */
|
||||
+#define HTT_MSDU_FLOW_STATS_TX_FLOW_NO GENMASK(15, 0)
|
||||
+#define HTT_MSDU_FLOW_STATS_TID_NUM GENMASK(19, 16)
|
||||
+#define HTT_MSDU_FLOW_STATS_DROP_RULE BIT(20)
|
||||
+
|
||||
struct htt_msdu_flow_stats_tlv {
|
||||
u32 last_update_timestamp;
|
||||
u32 last_add_timestamp;
|
||||
@@ -306,6 +312,11 @@ struct htt_msdu_flow_stats_tlv {
|
||||
|
||||
#define MAX_HTT_TID_NAME 8
|
||||
|
||||
+#define HTT_TX_TID_STATS_SW_PEER_ID GENMASK(15, 0)
|
||||
+#define HTT_TX_TID_STATS_TID_NUM GENMASK(31, 16)
|
||||
+#define HTT_TX_TID_STATS_NUM_SCHED_PENDING GENMASK(7, 0)
|
||||
+#define HTT_TX_TID_STATS_NUM_PPDU_IN_HWQ GENMASK(15, 8)
|
||||
+
|
||||
/* Tidq stats */
|
||||
struct htt_tx_tid_stats_tlv {
|
||||
/* Stored as little endian */
|
||||
@@ -326,6 +337,11 @@ struct htt_tx_tid_stats_tlv {
|
||||
u32 tid_tx_airtime;
|
||||
};
|
||||
|
||||
+#define HTT_TX_TID_STATS_V1_SW_PEER_ID GENMASK(15, 0)
|
||||
+#define HTT_TX_TID_STATS_V1_TID_NUM GENMASK(31, 16)
|
||||
+#define HTT_TX_TID_STATS_V1_NUM_SCHED_PENDING GENMASK(7, 0)
|
||||
+#define HTT_TX_TID_STATS_V1_NUM_PPDU_IN_HWQ GENMASK(15, 8)
|
||||
+
|
||||
/* Tidq stats */
|
||||
struct htt_tx_tid_stats_v1_tlv {
|
||||
/* Stored as little endian */
|
||||
@@ -348,6 +364,9 @@ struct htt_tx_tid_stats_v1_tlv {
|
||||
u32 sendn_frms_allowed;
|
||||
};
|
||||
|
||||
+#define HTT_RX_TID_STATS_SW_PEER_ID GENMASK(15, 0)
|
||||
+#define HTT_RX_TID_STATS_TID_NUM GENMASK(31, 16)
|
||||
+
|
||||
struct htt_rx_tid_stats_tlv {
|
||||
u32 sw_peer_id__tid_num;
|
||||
u8 tid_name[MAX_HTT_TID_NAME];
|
||||
@@ -386,6 +405,10 @@ struct htt_peer_stats_cmn_tlv {
|
||||
u32 inactive_time;
|
||||
};
|
||||
|
||||
+#define HTT_PEER_DETAILS_VDEV_ID GENMASK(7, 0)
|
||||
+#define HTT_PEER_DETAILS_PDEV_ID GENMASK(15, 8)
|
||||
+#define HTT_PEER_DETAILS_AST_IDX GENMASK(31, 16)
|
||||
+
|
||||
struct htt_peer_details_tlv {
|
||||
u32 peer_type;
|
||||
u32 sw_peer_id;
|
||||
@@ -510,6 +533,9 @@ struct htt_tx_hwq_mu_mimo_mpdu_stats_tlv
|
||||
u32 mu_mimo_ampdu_underrun_usr;
|
||||
};
|
||||
|
||||
+#define HTT_TX_HWQ_STATS_MAC_ID GENMASK(7, 0)
|
||||
+#define HTT_TX_HWQ_STATS_HWQ_ID GENMASK(15, 8)
|
||||
+
|
||||
struct htt_tx_hwq_mu_mimo_cmn_stats_tlv {
|
||||
u32 mac_id__hwq_id__word;
|
||||
};
|
||||
@@ -789,6 +815,9 @@ struct htt_sched_txq_sched_ineligibility
|
||||
u32 sched_ineligibility[0];
|
||||
};
|
||||
|
||||
+#define HTT_TX_PDEV_STATS_SCHED_PER_TXQ_MAC_ID GENMASK(7, 0)
|
||||
+#define HTT_TX_PDEV_STATS_SCHED_PER_TXQ_ID GENMASK(15, 8)
|
||||
+
|
||||
struct htt_tx_pdev_stats_sched_per_txq_tlv {
|
||||
u32 mac_id__txq_id__word;
|
||||
u32 sched_policy;
|
||||
@@ -910,6 +939,9 @@ struct htt_tx_tqm_error_stats_tlv {
|
||||
};
|
||||
|
||||
/* == TQM CMDQ stats == */
|
||||
+#define HTT_TX_TQM_CMDQ_STATUS_MAC_ID GENMASK(7, 0)
|
||||
+#define HTT_TX_TQM_CMDQ_STATUS_CMDQ_ID GENMASK(15, 8)
|
||||
+
|
||||
struct htt_tx_tqm_cmdq_status_tlv {
|
||||
u32 mac_id__cmdq_id__word;
|
||||
u32 sync_cmd;
|
||||
@@ -1055,6 +1087,15 @@ struct htt_tx_de_cmn_stats_tlv {
|
||||
#define HTT_STATS_LOW_WM_BINS 5
|
||||
#define HTT_STATS_HIGH_WM_BINS 5
|
||||
|
||||
+#define HTT_RING_IF_STATS_NUM_ELEMS GENMASK(15, 0)
|
||||
+#define HTT_RING_IF_STATS_PREFETCH_TAIL_INDEX GENMASK(31, 16)
|
||||
+#define HTT_RING_IF_STATS_HEAD_IDX GENMASK(15, 0)
|
||||
+#define HTT_RING_IF_STATS_TAIL_IDX GENMASK(31, 16)
|
||||
+#define HTT_RING_IF_STATS_SHADOW_HEAD_IDX GENMASK(15, 0)
|
||||
+#define HTT_RING_IF_STATS_SHADOW_TAIL_IDX GENMASK(31, 16)
|
||||
+#define HTT_RING_IF_STATS_LWM_THRESH GENMASK(15, 0)
|
||||
+#define HTT_RING_IF_STATS_HWM_THRESH GENMASK(31, 16)
|
||||
+
|
||||
struct htt_ring_if_stats_tlv {
|
||||
u32 base_addr; /* DWORD aligned base memory address of the ring */
|
||||
u32 elem_size;
|
||||
@@ -1117,6 +1158,19 @@ struct htt_sfm_cmn_tlv {
|
||||
};
|
||||
|
||||
/* == SRNG STATS == */
|
||||
+#define HTT_SRING_STATS_MAC_ID GENMASK(7, 0)
|
||||
+#define HTT_SRING_STATS_RING_ID GENMASK(15, 8)
|
||||
+#define HTT_SRING_STATS_ARENA GENMASK(23, 16)
|
||||
+#define HTT_SRING_STATS_EP BIT(24)
|
||||
+#define HTT_SRING_STATS_NUM_AVAIL_WORDS GENMASK(15, 0)
|
||||
+#define HTT_SRING_STATS_NUM_VALID_WORDS GENMASK(31, 16)
|
||||
+#define HTT_SRING_STATS_HEAD_PTR GENMASK(15, 0)
|
||||
+#define HTT_SRING_STATS_TAIL_PTR GENMASK(31, 16)
|
||||
+#define HTT_SRING_STATS_CONSUMER_EMPTY GENMASK(15, 0)
|
||||
+#define HTT_SRING_STATS_PRODUCER_FULL GENMASK(31, 16)
|
||||
+#define HTT_SRING_STATS_PREFETCH_COUNT GENMASK(15, 0)
|
||||
+#define HTT_SRING_STATS_INTERNAL_TAIL_PTR GENMASK(31, 16)
|
||||
+
|
||||
struct htt_sring_stats_tlv {
|
||||
u32 mac_id__ring_id__arena__ep;
|
||||
u32 base_addr_lsb; /* DWORD aligned base memory address of the ring */
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp.h
|
||||
@@ -1593,6 +1593,13 @@ struct ath11k_htt_extd_stats_msg {
|
||||
u8 data[0];
|
||||
} __packed;
|
||||
|
||||
+#define HTT_MAC_ADDR_L32_0 GENMASK(7, 0)
|
||||
+#define HTT_MAC_ADDR_L32_1 GENMASK(15, 8)
|
||||
+#define HTT_MAC_ADDR_L32_2 GENMASK(23, 16)
|
||||
+#define HTT_MAC_ADDR_L32_3 GENMASK(31, 24)
|
||||
+#define HTT_MAC_ADDR_H16_0 GENMASK(7, 0)
|
||||
+#define HTT_MAC_ADDR_H16_1 GENMASK(15, 8)
|
||||
+
|
||||
struct htt_mac_addr {
|
||||
u32 mac_addr_l32;
|
||||
u32 mac_addr_h16;
|
@ -0,0 +1,677 @@
|
||||
From ac83b6034cfa3bec010c1e01d6e6b44673135afe Mon Sep 17 00:00:00 2001
|
||||
From: Venkateswara Naralasetty <vnaralas@codeaurora.org>
|
||||
Date: Tue, 28 Sep 2021 14:00:45 +0300
|
||||
Subject: [PATCH 047/120] ath11k: add HTT stats support for new stats
|
||||
|
||||
Add HTT stats support for,
|
||||
|
||||
29-ATH11K_DBG_HTT_EXT_STATS_PEER_CTRL_PATH_TXRX_STATS:
|
||||
Used to dump the control path txrx stats for each connected peer.
|
||||
Usage:
|
||||
echo 29 > /sys/kernel/debug/ieee80211/phyx/ath11k/htt_stats_type
|
||||
cat /sys/kernel/debug/ieee80211/phyx/netdev\:wlan0/stations/
|
||||
<sta mac>/htt_peer_stats.
|
||||
|
||||
31-ATH11K_DBG_HTT_EXT_STATS_PDEV_TX_RATE_TXBF_STATS:
|
||||
Used to dump the per pdev tx rate txbf stats.
|
||||
Usage:
|
||||
echo 31 > /sys/kernel/debug/ieee80211/phyx/ath11k/htt_stats_type
|
||||
cat /sys/kernel/debug/ieee80211/phyx/ath11k/htt_stats
|
||||
|
||||
32-ATH11k_DBG_HTT_EXT_STATS_TXBF_OFDMA:
|
||||
Used to dump the TXBF ofdma stats for all ofdma users.
|
||||
Usage:
|
||||
echo 32 > /sys/kernel/debug/ieee80211/phyx/ath11k/htt_stats_type
|
||||
cat /sys/kernel/debug/ieee80211/phyx/ath11k/htt_stats
|
||||
|
||||
37-ATH11K_DBG_HTT_EXT_PHY_COUNTERS_AND_PHY_STATS:
|
||||
Used to dump the mac and phy txrx counts and phy stats like per chain rssi
|
||||
and ANI level.
|
||||
Usage:
|
||||
echo 37 > /sys/kernel/debug/ieee80211/phyx/ath11k/htt_stats_type
|
||||
cat /sys/kernel/debug/ieee80211/phyx/ath11k/htt_stats
|
||||
|
||||
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.5.0.1-00486-QCAHKSWPL_SILICONZ-1
|
||||
|
||||
Signed-off-by: Venkateswara Naralasetty <vnaralas@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20210913223148.208026-6-jouni@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/debugfs.h | 4 +
|
||||
.../wireless/ath/ath11k/debugfs_htt_stats.c | 368 +++++++++++++++++-
|
||||
.../wireless/ath/ath11k/debugfs_htt_stats.h | 172 ++++++++
|
||||
drivers/net/wireless/ath/ath11k/debugfs_sta.c | 8 +-
|
||||
4 files changed, 548 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/debugfs.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/debugfs.h
|
||||
@@ -38,6 +38,10 @@ enum ath11k_dbg_htt_ext_stats_type {
|
||||
ATH11K_DBG_HTT_EXT_STATS_TX_SOUNDING_INFO = 22,
|
||||
ATH11K_DBG_HTT_EXT_STATS_PDEV_OBSS_PD_STATS = 23,
|
||||
ATH11K_DBG_HTT_EXT_STATS_RING_BACKPRESSURE_STATS = 24,
|
||||
+ ATH11K_DBG_HTT_EXT_STATS_PEER_CTRL_PATH_TXRX_STATS = 29,
|
||||
+ ATH11K_DBG_HTT_EXT_STATS_PDEV_TX_RATE_TXBF_STATS = 31,
|
||||
+ ATH11K_DBG_HTT_EXT_STATS_TXBF_OFDMA = 32,
|
||||
+ ATH11K_DBG_HTT_EXT_PHY_COUNTERS_AND_PHY_STATS = 37,
|
||||
|
||||
/* keep this last */
|
||||
ATH11K_DBG_HTT_NUM_EXT_STATS,
|
||||
--- a/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.c
|
||||
@@ -3639,6 +3639,334 @@ static inline void htt_print_backpressur
|
||||
}
|
||||
}
|
||||
|
||||
+static inline
|
||||
+void htt_print_pdev_tx_rate_txbf_stats_tlv(const void *tag_buf,
|
||||
+ struct debug_htt_stats_req *stats_req)
|
||||
+{
|
||||
+ const struct htt_pdev_txrate_txbf_stats_tlv *htt_stats_buf = tag_buf;
|
||||
+ u8 *buf = stats_req->buf;
|
||||
+ u32 len = stats_req->buf_len;
|
||||
+ u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
|
||||
+ int i;
|
||||
+
|
||||
+ len += scnprintf(buf + len, buf_len - len,
|
||||
+ "HTT_STATS_PDEV_TX_RATE_TXBF_STATS:\n");
|
||||
+
|
||||
+ len += scnprintf(buf + len, buf_len - len, "tx_ol_mcs = ");
|
||||
+ for (i = 0; i < HTT_TX_TXBF_RATE_STATS_NUM_MCS_COUNTERS; i++)
|
||||
+ len += scnprintf(buf + len, buf_len - len,
|
||||
+ "%d:%u,", i, htt_stats_buf->tx_su_ol_mcs[i]);
|
||||
+ len--;
|
||||
+
|
||||
+ len += scnprintf(buf + len, buf_len - len, "\ntx_ibf_mcs = ");
|
||||
+ for (i = 0; i < HTT_TX_TXBF_RATE_STATS_NUM_MCS_COUNTERS; i++)
|
||||
+ len += scnprintf(buf + len, buf_len - len,
|
||||
+ "%d:%u,", i, htt_stats_buf->tx_su_ibf_mcs[i]);
|
||||
+ len--;
|
||||
+
|
||||
+ len += scnprintf(buf + len, buf_len - len, "\ntx_txbf_mcs =");
|
||||
+ for (i = 0; i < HTT_TX_TXBF_RATE_STATS_NUM_MCS_COUNTERS; i++)
|
||||
+ len += scnprintf(buf + len, buf_len - len,
|
||||
+ "%d:%u,", i, htt_stats_buf->tx_su_txbf_mcs[i]);
|
||||
+ len--;
|
||||
+
|
||||
+ len += scnprintf(buf + len, buf_len - len, "\ntx_ol_nss = ");
|
||||
+ for (i = 0; i < HTT_TX_PDEV_STATS_NUM_SPATIAL_STREAMS; i++)
|
||||
+ len += scnprintf(buf + len, buf_len - len,
|
||||
+ "%d:%u,", i, htt_stats_buf->tx_su_ol_nss[i]);
|
||||
+ len--;
|
||||
+
|
||||
+ len += scnprintf(buf + len, buf_len - len, "\ntx_ibf_nss = ");
|
||||
+ for (i = 0; i < HTT_TX_PDEV_STATS_NUM_SPATIAL_STREAMS; i++)
|
||||
+ len += scnprintf(buf + len, buf_len - len,
|
||||
+ "%d:%u,", i, htt_stats_buf->tx_su_ibf_nss[i]);
|
||||
+ len--;
|
||||
+
|
||||
+ len += scnprintf(buf + len, buf_len - len, "\ntx_txbf_nss = ");
|
||||
+ for (i = 0; i < HTT_TX_PDEV_STATS_NUM_SPATIAL_STREAMS; i++)
|
||||
+ len += scnprintf(buf + len, buf_len - len,
|
||||
+ "%d:%u,", i, htt_stats_buf->tx_su_txbf_nss[i]);
|
||||
+ len--;
|
||||
+
|
||||
+ len += scnprintf(buf + len, buf_len - len, "\ntx_ol_bw = ");
|
||||
+ for (i = 0; i < HTT_TX_TXBF_RATE_STATS_NUM_BW_COUNTERS; i++)
|
||||
+ len += scnprintf(buf + len, buf_len - len,
|
||||
+ "%d:%u,", i, htt_stats_buf->tx_su_ol_bw[i]);
|
||||
+ len--;
|
||||
+
|
||||
+ len += scnprintf(buf + len, buf_len - len, "\ntx_ibf_bw = ");
|
||||
+ for (i = 0; i < HTT_TX_TXBF_RATE_STATS_NUM_BW_COUNTERS; i++)
|
||||
+ len += scnprintf(buf + len, buf_len - len,
|
||||
+ "%d:%u,", i, htt_stats_buf->tx_su_ibf_bw[i]);
|
||||
+ len--;
|
||||
+
|
||||
+ len += scnprintf(buf + len, buf_len - len, "\ntx_txbf_bw = ");
|
||||
+ for (i = 0; i < HTT_TX_TXBF_RATE_STATS_NUM_BW_COUNTERS; i++)
|
||||
+ len += scnprintf(buf + len, buf_len - len,
|
||||
+ "%d:%u,", i, htt_stats_buf->tx_su_txbf_bw[i]);
|
||||
+ len--;
|
||||
+
|
||||
+ len += scnprintf(buf + len, buf_len - len, "\n");
|
||||
+
|
||||
+ stats_req->buf_len = len;
|
||||
+}
|
||||
+
|
||||
+static inline
|
||||
+void htt_print_txbf_ofdma_ndpa_stats_tlv(const void *tag_buf,
|
||||
+ struct debug_htt_stats_req *stats_req)
|
||||
+{
|
||||
+ const struct htt_txbf_ofdma_ndpa_stats_tlv *htt_stats_buf = tag_buf;
|
||||
+ u8 *buf = stats_req->buf;
|
||||
+ u32 len = stats_req->buf_len;
|
||||
+ u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
|
||||
+ int i;
|
||||
+
|
||||
+ len += scnprintf(buf + len, buf_len - len,
|
||||
+ "HTT_TXBF_OFDMA_NDPA_STATS_TLV:\n");
|
||||
+
|
||||
+ for (i = 0; i < HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS; i++) {
|
||||
+ len += scnprintf(buf + len, buf_len - len,
|
||||
+ "ax_ofdma_ndpa_queued_user%d = %u\n",
|
||||
+ i, htt_stats_buf->ax_ofdma_ndpa_queued[i]);
|
||||
+ len += scnprintf(buf + len, buf_len - len,
|
||||
+ "ax_ofdma_ndpa_tried_user%d = %u\n",
|
||||
+ i, htt_stats_buf->ax_ofdma_ndpa_tried[i]);
|
||||
+ len += scnprintf(buf + len, buf_len - len,
|
||||
+ "ax_ofdma_ndpa_flushed_user%d = %u\n",
|
||||
+ i, htt_stats_buf->ax_ofdma_ndpa_flushed[i]);
|
||||
+ len += scnprintf(buf + len, buf_len - len,
|
||||
+ "ax_ofdma_ndpa_err_user%d = %u\n",
|
||||
+ i, htt_stats_buf->ax_ofdma_ndpa_err[i]);
|
||||
+ len += scnprintf(buf + len, buf_len - len, "\n");
|
||||
+ }
|
||||
+
|
||||
+ stats_req->buf_len = len;
|
||||
+}
|
||||
+
|
||||
+static inline
|
||||
+void htt_print_txbf_ofdma_ndp_stats_tlv(const void *tag_buf,
|
||||
+ struct debug_htt_stats_req *stats_req)
|
||||
+{
|
||||
+ const struct htt_txbf_ofdma_ndp_stats_tlv *htt_stats_buf = tag_buf;
|
||||
+ u8 *buf = stats_req->buf;
|
||||
+ u32 len = stats_req->buf_len;
|
||||
+ u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
|
||||
+ int i;
|
||||
+
|
||||
+ len += scnprintf(buf + len, buf_len - len,
|
||||
+ "HTT_TXBF_OFDMA_NDP_STATS_TLV:\n");
|
||||
+
|
||||
+ for (i = 0; i < HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS; i++) {
|
||||
+ len += scnprintf(buf + len, buf_len - len,
|
||||
+ "ax_ofdma_ndp_queued_user%d = %u\n",
|
||||
+ i, htt_stats_buf->ax_ofdma_ndp_queued[i]);
|
||||
+ len += scnprintf(buf + len, buf_len - len,
|
||||
+ "ax_ofdma_ndp_tried_user%d = %u\n",
|
||||
+ i, htt_stats_buf->ax_ofdma_ndp_tried[i]);
|
||||
+ len += scnprintf(buf + len, buf_len - len,
|
||||
+ "ax_ofdma_ndp_flushed_user%d = %u\n",
|
||||
+ i, htt_stats_buf->ax_ofdma_ndp_flushed[i]);
|
||||
+ len += scnprintf(buf + len, buf_len - len,
|
||||
+ "ax_ofdma_ndp_err_user%d = %u\n",
|
||||
+ i, htt_stats_buf->ax_ofdma_ndp_err[i]);
|
||||
+ len += scnprintf(buf + len, buf_len - len, "\n");
|
||||
+ }
|
||||
+
|
||||
+ stats_req->buf_len = len;
|
||||
+}
|
||||
+
|
||||
+static inline
|
||||
+void htt_print_txbf_ofdma_brp_stats_tlv(const void *tag_buf,
|
||||
+ struct debug_htt_stats_req *stats_req)
|
||||
+{
|
||||
+ const struct htt_txbf_ofdma_brp_stats_tlv *htt_stats_buf = tag_buf;
|
||||
+ u8 *buf = stats_req->buf;
|
||||
+ u32 len = stats_req->buf_len;
|
||||
+ u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
|
||||
+ int i;
|
||||
+
|
||||
+ len += scnprintf(buf + len, buf_len - len,
|
||||
+ "HTT_TXBF_OFDMA_BRP_STATS_TLV:\n");
|
||||
+
|
||||
+ for (i = 0; i < HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS; i++) {
|
||||
+ len += scnprintf(buf + len, buf_len - len,
|
||||
+ "ax_ofdma_brpoll_queued_user%d = %u\n",
|
||||
+ i, htt_stats_buf->ax_ofdma_brpoll_queued[i]);
|
||||
+ len += scnprintf(buf + len, buf_len - len,
|
||||
+ "ax_ofdma_brpoll_tried_user%d = %u\n",
|
||||
+ i, htt_stats_buf->ax_ofdma_brpoll_tried[i]);
|
||||
+ len += scnprintf(buf + len, buf_len - len,
|
||||
+ "ax_ofdma_brpoll_flushed_user%d = %u\n",
|
||||
+ i, htt_stats_buf->ax_ofdma_brpoll_flushed[i]);
|
||||
+ len += scnprintf(buf + len, buf_len - len,
|
||||
+ "ax_ofdma_brp_err_user%d = %u\n",
|
||||
+ i, htt_stats_buf->ax_ofdma_brp_err[i]);
|
||||
+ len += scnprintf(buf + len, buf_len - len,
|
||||
+ "ax_ofdma_brp_err_num_cbf_rcvd_user%d = %u\n",
|
||||
+ i, htt_stats_buf->ax_ofdma_brp_err_num_cbf_rcvd[i]);
|
||||
+ len += scnprintf(buf + len, buf_len - len, "\n");
|
||||
+ }
|
||||
+
|
||||
+ stats_req->buf_len = len;
|
||||
+}
|
||||
+
|
||||
+static inline
|
||||
+void htt_print_txbf_ofdma_steer_stats_tlv(const void *tag_buf,
|
||||
+ struct debug_htt_stats_req *stats_req)
|
||||
+{
|
||||
+ const struct htt_txbf_ofdma_steer_stats_tlv *htt_stats_buf = tag_buf;
|
||||
+ u8 *buf = stats_req->buf;
|
||||
+ u32 len = stats_req->buf_len;
|
||||
+ u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
|
||||
+ int i;
|
||||
+
|
||||
+ len += scnprintf(buf + len, buf_len - len,
|
||||
+ "HTT_TXBF_OFDMA_STEER_STATS_TLV:\n");
|
||||
+
|
||||
+ for (i = 0; i < HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS; i++) {
|
||||
+ len += scnprintf(buf + len, buf_len - len,
|
||||
+ "ax_ofdma_num_ppdu_steer_user%d = %u\n",
|
||||
+ i, htt_stats_buf->ax_ofdma_num_ppdu_steer[i]);
|
||||
+ len += scnprintf(buf + len, buf_len - len,
|
||||
+ "ax_ofdma_num_ppdu_ol_user%d = %u\n",
|
||||
+ i, htt_stats_buf->ax_ofdma_num_ppdu_ol[i]);
|
||||
+ len += scnprintf(buf + len, buf_len - len,
|
||||
+ "ax_ofdma_num_usrs_prefetch_user%d = %u\n",
|
||||
+ i, htt_stats_buf->ax_ofdma_num_usrs_prefetch[i]);
|
||||
+ len += scnprintf(buf + len, buf_len - len,
|
||||
+ "ax_ofdma_num_usrs_sound_user%d = %u\n",
|
||||
+ i, htt_stats_buf->ax_ofdma_num_usrs_sound[i]);
|
||||
+ len += scnprintf(buf + len, buf_len - len,
|
||||
+ "ax_ofdma_num_usrs_force_sound_user%d = %u\n",
|
||||
+ i, htt_stats_buf->ax_ofdma_num_usrs_force_sound[i]);
|
||||
+ len += scnprintf(buf + len, buf_len - len, "\n");
|
||||
+ }
|
||||
+
|
||||
+ stats_req->buf_len = len;
|
||||
+}
|
||||
+
|
||||
+static inline
|
||||
+void htt_print_phy_counters_tlv(const void *tag_buf,
|
||||
+ struct debug_htt_stats_req *stats_req)
|
||||
+{
|
||||
+ const struct htt_phy_counters_tlv *htt_stats_buf = tag_buf;
|
||||
+ u8 *buf = stats_req->buf;
|
||||
+ u32 len = stats_req->buf_len;
|
||||
+ u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
|
||||
+ int i;
|
||||
+
|
||||
+ len += scnprintf(buf + len, buf_len - len, "HTT_PHY_COUNTERS_TLV:\n");
|
||||
+ len += scnprintf(buf + len, buf_len - len, "rx_ofdma_timing_err_cnt = %u\n",
|
||||
+ htt_stats_buf->rx_ofdma_timing_err_cnt);
|
||||
+ len += scnprintf(buf + len, buf_len - len, "rx_cck_fail_cnt = %u\n",
|
||||
+ htt_stats_buf->rx_cck_fail_cnt);
|
||||
+ len += scnprintf(buf + len, buf_len - len, "mactx_abort_cnt = %u\n",
|
||||
+ htt_stats_buf->mactx_abort_cnt);
|
||||
+ len += scnprintf(buf + len, buf_len - len, "macrx_abort_cnt = %u\n",
|
||||
+ htt_stats_buf->macrx_abort_cnt);
|
||||
+ len += scnprintf(buf + len, buf_len - len, "phytx_abort_cnt = %u\n",
|
||||
+ htt_stats_buf->phytx_abort_cnt);
|
||||
+ len += scnprintf(buf + len, buf_len - len, "phyrx_abort_cnt = %u\n",
|
||||
+ htt_stats_buf->phyrx_abort_cnt);
|
||||
+ len += scnprintf(buf + len, buf_len - len, "phyrx_defer_abort_cnt = %u\n",
|
||||
+ htt_stats_buf->phyrx_defer_abort_cnt);
|
||||
+ len += scnprintf(buf + len, buf_len - len, "rx_gain_adj_lstf_event_cnt = %u\n",
|
||||
+ htt_stats_buf->rx_gain_adj_lstf_event_cnt);
|
||||
+ len += scnprintf(buf + len, buf_len - len, "rx_gain_adj_non_legacy_cnt = %u\n",
|
||||
+ htt_stats_buf->rx_gain_adj_non_legacy_cnt);
|
||||
+
|
||||
+ for (i = 0; i < HTT_MAX_RX_PKT_CNT; i++)
|
||||
+ len += scnprintf(buf + len, buf_len - len, "rx_pkt_cnt[%d] = %u\n",
|
||||
+ i, htt_stats_buf->rx_pkt_cnt[i]);
|
||||
+
|
||||
+ for (i = 0; i < HTT_MAX_RX_PKT_CRC_PASS_CNT; i++)
|
||||
+ len += scnprintf(buf + len, buf_len - len,
|
||||
+ "rx_pkt_crc_pass_cnt[%d] = %u\n",
|
||||
+ i, htt_stats_buf->rx_pkt_crc_pass_cnt[i]);
|
||||
+
|
||||
+ for (i = 0; i < HTT_MAX_PER_BLK_ERR_CNT; i++)
|
||||
+ len += scnprintf(buf + len, buf_len - len,
|
||||
+ "per_blk_err_cnt[%d] = %u\n",
|
||||
+ i, htt_stats_buf->per_blk_err_cnt[i]);
|
||||
+
|
||||
+ for (i = 0; i < HTT_MAX_RX_OTA_ERR_CNT; i++)
|
||||
+ len += scnprintf(buf + len, buf_len - len,
|
||||
+ "rx_ota_err_cnt[%d] = %u\n",
|
||||
+ i, htt_stats_buf->rx_ota_err_cnt[i]);
|
||||
+
|
||||
+ stats_req->buf_len = len;
|
||||
+}
|
||||
+
|
||||
+static inline
|
||||
+void htt_print_phy_stats_tlv(const void *tag_buf,
|
||||
+ struct debug_htt_stats_req *stats_req)
|
||||
+{
|
||||
+ const struct htt_phy_stats_tlv *htt_stats_buf = tag_buf;
|
||||
+ u8 *buf = stats_req->buf;
|
||||
+ u32 len = stats_req->buf_len;
|
||||
+ u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
|
||||
+ int i;
|
||||
+
|
||||
+ len += scnprintf(buf + len, buf_len - len, "HTT_PHY_STATS_TLV:\n");
|
||||
+
|
||||
+ for (i = 0; i < HTT_STATS_MAX_CHAINS; i++)
|
||||
+ len += scnprintf(buf + len, buf_len - len, "nf_chain[%d] = %d\n",
|
||||
+ i, htt_stats_buf->nf_chain[i]);
|
||||
+
|
||||
+ len += scnprintf(buf + len, buf_len - len, "false_radar_cnt = %u\n",
|
||||
+ htt_stats_buf->false_radar_cnt);
|
||||
+ len += scnprintf(buf + len, buf_len - len, "radar_cs_cnt = %u\n",
|
||||
+ htt_stats_buf->radar_cs_cnt);
|
||||
+ len += scnprintf(buf + len, buf_len - len, "ani_level = %d\n",
|
||||
+ htt_stats_buf->ani_level);
|
||||
+ len += scnprintf(buf + len, buf_len - len, "fw_run_time = %u\n",
|
||||
+ htt_stats_buf->fw_run_time);
|
||||
+
|
||||
+ stats_req->buf_len = len;
|
||||
+}
|
||||
+
|
||||
+static inline
|
||||
+void htt_print_peer_ctrl_path_txrx_stats_tlv(const void *tag_buf,
|
||||
+ struct debug_htt_stats_req *stats_req)
|
||||
+{
|
||||
+ const struct htt_peer_ctrl_path_txrx_stats_tlv *htt_stat_buf = tag_buf;
|
||||
+ u8 *buf = stats_req->buf;
|
||||
+ u32 len = stats_req->buf_len;
|
||||
+ u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
|
||||
+ int i;
|
||||
+ const char *mgmt_frm_type[ATH11K_STATS_MGMT_FRM_TYPE_MAX - 1] = {
|
||||
+ "assoc_req", "assoc_resp",
|
||||
+ "reassoc_req", "reassoc_resp",
|
||||
+ "probe_req", "probe_resp",
|
||||
+ "timing_advertisement", "reserved",
|
||||
+ "beacon", "atim", "disassoc",
|
||||
+ "auth", "deauth", "action", "action_no_ack"};
|
||||
+
|
||||
+ len += scnprintf(buf + len, buf_len - len,
|
||||
+ "HTT_STATS_PEER_CTRL_PATH_TXRX_STATS_TAG:\n");
|
||||
+ len += scnprintf(buf + len, buf_len - len,
|
||||
+ "peer_mac_addr = %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
+ htt_stat_buf->peer_mac_addr[0], htt_stat_buf->peer_mac_addr[1],
|
||||
+ htt_stat_buf->peer_mac_addr[2], htt_stat_buf->peer_mac_addr[3],
|
||||
+ htt_stat_buf->peer_mac_addr[4], htt_stat_buf->peer_mac_addr[5]);
|
||||
+
|
||||
+ len += scnprintf(buf + len, buf_len - len, "peer_tx_mgmt_subtype:\n");
|
||||
+ for (i = 0; i < ATH11K_STATS_MGMT_FRM_TYPE_MAX - 1; i++)
|
||||
+ len += scnprintf(buf + len, buf_len - len, "%s:%u\n",
|
||||
+ mgmt_frm_type[i],
|
||||
+ htt_stat_buf->peer_rx_mgmt_subtype[i]);
|
||||
+
|
||||
+ len += scnprintf(buf + len, buf_len - len, "peer_rx_mgmt_subtype:\n");
|
||||
+ for (i = 0; i < ATH11K_STATS_MGMT_FRM_TYPE_MAX - 1; i++)
|
||||
+ len += scnprintf(buf + len, buf_len - len, "%s:%u\n",
|
||||
+ mgmt_frm_type[i],
|
||||
+ htt_stat_buf->peer_rx_mgmt_subtype[i]);
|
||||
+
|
||||
+ len += scnprintf(buf + len, buf_len - len, "\n");
|
||||
+
|
||||
+ stats_req->buf_len = len;
|
||||
+}
|
||||
+
|
||||
static int ath11k_dbg_htt_ext_stats_parse(struct ath11k_base *ab,
|
||||
u16 tag, u16 len, const void *tag_buf,
|
||||
void *user_data)
|
||||
@@ -3990,6 +4318,30 @@ static int ath11k_dbg_htt_ext_stats_pars
|
||||
case HTT_STATS_RING_BACKPRESSURE_STATS_TAG:
|
||||
htt_print_backpressure_stats_tlv_v(tag_buf, user_data);
|
||||
break;
|
||||
+ case HTT_STATS_PDEV_TX_RATE_TXBF_STATS_TAG:
|
||||
+ htt_print_pdev_tx_rate_txbf_stats_tlv(tag_buf, stats_req);
|
||||
+ break;
|
||||
+ case HTT_STATS_TXBF_OFDMA_NDPA_STATS_TAG:
|
||||
+ htt_print_txbf_ofdma_ndpa_stats_tlv(tag_buf, stats_req);
|
||||
+ break;
|
||||
+ case HTT_STATS_TXBF_OFDMA_NDP_STATS_TAG:
|
||||
+ htt_print_txbf_ofdma_ndp_stats_tlv(tag_buf, stats_req);
|
||||
+ break;
|
||||
+ case HTT_STATS_TXBF_OFDMA_BRP_STATS_TAG:
|
||||
+ htt_print_txbf_ofdma_brp_stats_tlv(tag_buf, stats_req);
|
||||
+ break;
|
||||
+ case HTT_STATS_TXBF_OFDMA_STEER_STATS_TAG:
|
||||
+ htt_print_txbf_ofdma_steer_stats_tlv(tag_buf, stats_req);
|
||||
+ break;
|
||||
+ case HTT_STATS_PHY_COUNTERS_TAG:
|
||||
+ htt_print_phy_counters_tlv(tag_buf, stats_req);
|
||||
+ break;
|
||||
+ case HTT_STATS_PHY_STATS_TAG:
|
||||
+ htt_print_phy_stats_tlv(tag_buf, stats_req);
|
||||
+ break;
|
||||
+ case HTT_STATS_PEER_CTRL_PATH_TXRX_STATS_TAG:
|
||||
+ htt_print_peer_ctrl_path_txrx_stats_tlv(tag_buf, stats_req);
|
||||
+ break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -4077,8 +4429,7 @@ static ssize_t ath11k_write_htt_stats_ty
|
||||
if (type >= ATH11K_DBG_HTT_NUM_EXT_STATS)
|
||||
return -E2BIG;
|
||||
|
||||
- if (type == ATH11K_DBG_HTT_EXT_STATS_RESET ||
|
||||
- type == ATH11K_DBG_HTT_EXT_STATS_PEER_INFO)
|
||||
+ if (type == ATH11K_DBG_HTT_EXT_STATS_RESET)
|
||||
return -EPERM;
|
||||
|
||||
ar->debug.htt_stats.type = type;
|
||||
@@ -4139,6 +4490,15 @@ static int ath11k_prep_htt_stats_cfg_par
|
||||
case ATH11K_DBG_HTT_EXT_STATS_TX_SOUNDING_INFO:
|
||||
cfg_params->cfg0 = HTT_STAT_DEFAULT_CFG0_ACTIVE_VDEVS;
|
||||
break;
|
||||
+ case ATH11K_DBG_HTT_EXT_STATS_PEER_CTRL_PATH_TXRX_STATS:
|
||||
+ cfg_params->cfg0 = HTT_STAT_PEER_INFO_MAC_ADDR;
|
||||
+ cfg_params->cfg1 |= FIELD_PREP(GENMASK(7, 0), mac_addr[0]);
|
||||
+ cfg_params->cfg1 |= FIELD_PREP(GENMASK(15, 8), mac_addr[1]);
|
||||
+ cfg_params->cfg1 |= FIELD_PREP(GENMASK(23, 16), mac_addr[2]);
|
||||
+ cfg_params->cfg1 |= FIELD_PREP(GENMASK(31, 24), mac_addr[3]);
|
||||
+ cfg_params->cfg2 |= FIELD_PREP(GENMASK(7, 0), mac_addr[4]);
|
||||
+ cfg_params->cfg2 |= FIELD_PREP(GENMASK(15, 8), mac_addr[5]);
|
||||
+ break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -4196,7 +4556,9 @@ static int ath11k_open_htt_stats(struct
|
||||
u8 type = ar->debug.htt_stats.type;
|
||||
int ret;
|
||||
|
||||
- if (type == ATH11K_DBG_HTT_EXT_STATS_RESET)
|
||||
+ if (type == ATH11K_DBG_HTT_EXT_STATS_RESET ||
|
||||
+ type == ATH11K_DBG_HTT_EXT_STATS_PEER_INFO ||
|
||||
+ type == ATH11K_DBG_HTT_EXT_STATS_PEER_CTRL_PATH_TXRX_STATS)
|
||||
return -EPERM;
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
--- a/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.h
|
||||
@@ -102,6 +102,14 @@ enum htt_tlv_tag_t {
|
||||
HTT_STATS_PDEV_OBSS_PD_TAG = 88,
|
||||
HTT_STATS_HW_WAR_TAG = 89,
|
||||
HTT_STATS_RING_BACKPRESSURE_STATS_TAG = 90,
|
||||
+ HTT_STATS_PEER_CTRL_PATH_TXRX_STATS_TAG = 101,
|
||||
+ HTT_STATS_PDEV_TX_RATE_TXBF_STATS_TAG = 108,
|
||||
+ HTT_STATS_TXBF_OFDMA_NDPA_STATS_TAG = 113,
|
||||
+ HTT_STATS_TXBF_OFDMA_NDP_STATS_TAG = 114,
|
||||
+ HTT_STATS_TXBF_OFDMA_BRP_STATS_TAG = 115,
|
||||
+ HTT_STATS_TXBF_OFDMA_STEER_STATS_TAG = 116,
|
||||
+ HTT_STATS_PHY_COUNTERS_TAG = 121,
|
||||
+ HTT_STATS_PHY_STATS_TAG = 122,
|
||||
|
||||
HTT_STATS_MAX_TAG,
|
||||
};
|
||||
@@ -1750,6 +1758,170 @@ struct htt_ring_backpressure_stats_tlv {
|
||||
u32 backpressure_hist[5];
|
||||
};
|
||||
|
||||
+#define HTT_TX_TXBF_RATE_STATS_NUM_MCS_COUNTERS 14
|
||||
+#define HTT_TX_TXBF_RATE_STATS_NUM_BW_COUNTERS 5
|
||||
+#define HTT_TX_PDEV_STATS_NUM_SPATIAL_STREAMS 8
|
||||
+
|
||||
+struct htt_pdev_txrate_txbf_stats_tlv {
|
||||
+ /* SU TxBF TX MCS stats */
|
||||
+ u32 tx_su_txbf_mcs[HTT_TX_TXBF_RATE_STATS_NUM_MCS_COUNTERS];
|
||||
+ /* Implicit BF TX MCS stats */
|
||||
+ u32 tx_su_ibf_mcs[HTT_TX_TXBF_RATE_STATS_NUM_MCS_COUNTERS];
|
||||
+ /* Open loop TX MCS stats */
|
||||
+ u32 tx_su_ol_mcs[HTT_TX_TXBF_RATE_STATS_NUM_MCS_COUNTERS];
|
||||
+ /* SU TxBF TX NSS stats */
|
||||
+ u32 tx_su_txbf_nss[HTT_TX_PDEV_STATS_NUM_SPATIAL_STREAMS];
|
||||
+ /* Implicit BF TX NSS stats */
|
||||
+ u32 tx_su_ibf_nss[HTT_TX_PDEV_STATS_NUM_SPATIAL_STREAMS];
|
||||
+ /* Open loop TX NSS stats */
|
||||
+ u32 tx_su_ol_nss[HTT_TX_PDEV_STATS_NUM_SPATIAL_STREAMS];
|
||||
+ /* SU TxBF TX BW stats */
|
||||
+ u32 tx_su_txbf_bw[HTT_TX_TXBF_RATE_STATS_NUM_BW_COUNTERS];
|
||||
+ /* Implicit BF TX BW stats */
|
||||
+ u32 tx_su_ibf_bw[HTT_TX_TXBF_RATE_STATS_NUM_BW_COUNTERS];
|
||||
+ /* Open loop TX BW stats */
|
||||
+ u32 tx_su_ol_bw[HTT_TX_TXBF_RATE_STATS_NUM_BW_COUNTERS];
|
||||
+};
|
||||
+
|
||||
+struct htt_txbf_ofdma_ndpa_stats_tlv {
|
||||
+ /* 11AX HE OFDMA NDPA frame queued to the HW */
|
||||
+ u32 ax_ofdma_ndpa_queued[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS];
|
||||
+ /* 11AX HE OFDMA NDPA frame sent over the air */
|
||||
+ u32 ax_ofdma_ndpa_tried[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS];
|
||||
+ /* 11AX HE OFDMA NDPA frame flushed by HW */
|
||||
+ u32 ax_ofdma_ndpa_flushed[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS];
|
||||
+ /* 11AX HE OFDMA NDPA frame completed with error(s) */
|
||||
+ u32 ax_ofdma_ndpa_err[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS];
|
||||
+};
|
||||
+
|
||||
+struct htt_txbf_ofdma_ndp_stats_tlv {
|
||||
+ /* 11AX HE OFDMA NDP frame queued to the HW */
|
||||
+ u32 ax_ofdma_ndp_queued[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS];
|
||||
+ /* 11AX HE OFDMA NDPA frame sent over the air */
|
||||
+ u32 ax_ofdma_ndp_tried[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS];
|
||||
+ /* 11AX HE OFDMA NDPA frame flushed by HW */
|
||||
+ u32 ax_ofdma_ndp_flushed[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS];
|
||||
+ /* 11AX HE OFDMA NDPA frame completed with error(s) */
|
||||
+ u32 ax_ofdma_ndp_err[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS];
|
||||
+};
|
||||
+
|
||||
+struct htt_txbf_ofdma_brp_stats_tlv {
|
||||
+ /* 11AX HE OFDMA MU BRPOLL frame queued to the HW */
|
||||
+ u32 ax_ofdma_brpoll_queued[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS];
|
||||
+ /* 11AX HE OFDMA MU BRPOLL frame sent over the air */
|
||||
+ u32 ax_ofdma_brpoll_tried[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS];
|
||||
+ /* 11AX HE OFDMA MU BRPOLL frame flushed by HW */
|
||||
+ u32 ax_ofdma_brpoll_flushed[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS];
|
||||
+ /* 11AX HE OFDMA MU BRPOLL frame completed with error(s) */
|
||||
+ u32 ax_ofdma_brp_err[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS];
|
||||
+ /* Number of CBF(s) received when 11AX HE OFDMA MU BRPOLL frame
|
||||
+ * completed with error(s).
|
||||
+ */
|
||||
+ u32 ax_ofdma_brp_err_num_cbf_rcvd[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS + 1];
|
||||
+};
|
||||
+
|
||||
+struct htt_txbf_ofdma_steer_stats_tlv {
|
||||
+ /* 11AX HE OFDMA PPDUs that were sent over the air with steering (TXBF + OFDMA) */
|
||||
+ u32 ax_ofdma_num_ppdu_steer[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS];
|
||||
+ /* 11AX HE OFDMA PPDUs that were sent over the air in open loop */
|
||||
+ u32 ax_ofdma_num_ppdu_ol[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS];
|
||||
+ /* 11AX HE OFDMA number of users for which CBF prefetch was
|
||||
+ * initiated to PHY HW during TX.
|
||||
+ */
|
||||
+ u32 ax_ofdma_num_usrs_prefetch[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS];
|
||||
+ /* 11AX HE OFDMA number of users for which sounding was initiated during TX */
|
||||
+ u32 ax_ofdma_num_usrs_sound[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS];
|
||||
+ /* 11AX HE OFDMA number of users for which sounding was forced during TX */
|
||||
+ u32 ax_ofdma_num_usrs_force_sound[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS];
|
||||
+};
|
||||
+
|
||||
+#define HTT_MAX_RX_PKT_CNT 8
|
||||
+#define HTT_MAX_RX_PKT_CRC_PASS_CNT 8
|
||||
+#define HTT_MAX_PER_BLK_ERR_CNT 20
|
||||
+#define HTT_MAX_RX_OTA_ERR_CNT 14
|
||||
+#define HTT_STATS_MAX_CHAINS 8
|
||||
+#define ATH11K_STATS_MGMT_FRM_TYPE_MAX 16
|
||||
+
|
||||
+struct htt_phy_counters_tlv {
|
||||
+ /* number of RXTD OFDMA OTA error counts except power surge and drop */
|
||||
+ u32 rx_ofdma_timing_err_cnt;
|
||||
+ /* rx_cck_fail_cnt:
|
||||
+ * number of cck error counts due to rx reception failure because of
|
||||
+ * timing error in cck
|
||||
+ */
|
||||
+ u32 rx_cck_fail_cnt;
|
||||
+ /* number of times tx abort initiated by mac */
|
||||
+ u32 mactx_abort_cnt;
|
||||
+ /* number of times rx abort initiated by mac */
|
||||
+ u32 macrx_abort_cnt;
|
||||
+ /* number of times tx abort initiated by phy */
|
||||
+ u32 phytx_abort_cnt;
|
||||
+ /* number of times rx abort initiated by phy */
|
||||
+ u32 phyrx_abort_cnt;
|
||||
+ /* number of rx defered count initiated by phy */
|
||||
+ u32 phyrx_defer_abort_cnt;
|
||||
+ /* number of sizing events generated at LSTF */
|
||||
+ u32 rx_gain_adj_lstf_event_cnt;
|
||||
+ /* number of sizing events generated at non-legacy LTF */
|
||||
+ u32 rx_gain_adj_non_legacy_cnt;
|
||||
+ /* rx_pkt_cnt -
|
||||
+ * Received EOP (end-of-packet) count per packet type;
|
||||
+ * [0] = 11a; [1] = 11b; [2] = 11n; [3] = 11ac; [4] = 11ax; [5] = GF
|
||||
+ * [6-7]=RSVD
|
||||
+ */
|
||||
+ u32 rx_pkt_cnt[HTT_MAX_RX_PKT_CNT];
|
||||
+ /* rx_pkt_crc_pass_cnt -
|
||||
+ * Received EOP (end-of-packet) count per packet type;
|
||||
+ * [0] = 11a; [1] = 11b; [2] = 11n; [3] = 11ac; [4] = 11ax; [5] = GF
|
||||
+ * [6-7]=RSVD
|
||||
+ */
|
||||
+ u32 rx_pkt_crc_pass_cnt[HTT_MAX_RX_PKT_CRC_PASS_CNT];
|
||||
+ /* per_blk_err_cnt -
|
||||
+ * Error count per error source;
|
||||
+ * [0] = unknown; [1] = LSIG; [2] = HTSIG; [3] = VHTSIG; [4] = HESIG;
|
||||
+ * [5] = RXTD_OTA; [6] = RXTD_FATAL; [7] = DEMF; [8] = ROBE;
|
||||
+ * [9] = PMI; [10] = TXFD; [11] = TXTD; [12] = PHYRF
|
||||
+ * [13-19]=RSVD
|
||||
+ */
|
||||
+ u32 per_blk_err_cnt[HTT_MAX_PER_BLK_ERR_CNT];
|
||||
+ /* rx_ota_err_cnt -
|
||||
+ * RXTD OTA (over-the-air) error count per error reason;
|
||||
+ * [0] = voting fail; [1] = weak det fail; [2] = strong sig fail;
|
||||
+ * [3] = cck fail; [4] = power surge; [5] = power drop;
|
||||
+ * [6] = btcf timing timeout error; [7] = btcf packet detect error;
|
||||
+ * [8] = coarse timing timeout error
|
||||
+ * [9-13]=RSVD
|
||||
+ */
|
||||
+ u32 rx_ota_err_cnt[HTT_MAX_RX_OTA_ERR_CNT];
|
||||
+};
|
||||
+
|
||||
+struct htt_phy_stats_tlv {
|
||||
+ /* per chain hw noise floor values in dBm */
|
||||
+ s32 nf_chain[HTT_STATS_MAX_CHAINS];
|
||||
+ /* number of false radars detected */
|
||||
+ u32 false_radar_cnt;
|
||||
+ /* number of channel switches happened due to radar detection */
|
||||
+ u32 radar_cs_cnt;
|
||||
+ /* ani_level -
|
||||
+ * ANI level (noise interference) corresponds to the channel
|
||||
+ * the desense levels range from -5 to 15 in dB units,
|
||||
+ * higher values indicating more noise interference.
|
||||
+ */
|
||||
+ s32 ani_level;
|
||||
+ /* running time in minutes since FW boot */
|
||||
+ u32 fw_run_time;
|
||||
+};
|
||||
+
|
||||
+struct htt_peer_ctrl_path_txrx_stats_tlv {
|
||||
+ /* peer mac address */
|
||||
+ u8 peer_mac_addr[ETH_ALEN];
|
||||
+ u8 rsvd[2];
|
||||
+ /* Num of tx mgmt frames with subtype on peer level */
|
||||
+ u32 peer_tx_mgmt_subtype[ATH11K_STATS_MGMT_FRM_TYPE_MAX];
|
||||
+ /* Num of rx mgmt frames with subtype on peer level */
|
||||
+ u32 peer_rx_mgmt_subtype[ATH11K_STATS_MGMT_FRM_TYPE_MAX];
|
||||
+};
|
||||
+
|
||||
#ifdef CPTCFG_ATH11K_DEBUGFS
|
||||
|
||||
void ath11k_debugfs_htt_stats_init(struct ath11k *ar);
|
||||
--- a/drivers/net/wireless/ath/ath11k/debugfs_sta.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/debugfs_sta.c
|
||||
@@ -419,15 +419,21 @@ ath11k_dbg_sta_open_htt_peer_stats(struc
|
||||
struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv;
|
||||
struct ath11k *ar = arsta->arvif->ar;
|
||||
struct debug_htt_stats_req *stats_req;
|
||||
+ int type = ar->debug.htt_stats.type;
|
||||
int ret;
|
||||
|
||||
+ if ((type != ATH11K_DBG_HTT_EXT_STATS_PEER_INFO &&
|
||||
+ type != ATH11K_DBG_HTT_EXT_STATS_PEER_CTRL_PATH_TXRX_STATS) ||
|
||||
+ type == ATH11K_DBG_HTT_EXT_STATS_RESET)
|
||||
+ return -EPERM;
|
||||
+
|
||||
stats_req = vzalloc(sizeof(*stats_req) + ATH11K_HTT_STATS_BUF_SIZE);
|
||||
if (!stats_req)
|
||||
return -ENOMEM;
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
ar->debug.htt_stats.stats_req = stats_req;
|
||||
- stats_req->type = ATH11K_DBG_HTT_EXT_STATS_PEER_INFO;
|
||||
+ stats_req->type = type;
|
||||
memcpy(stats_req->peer_addr, sta->addr, ETH_ALEN);
|
||||
ret = ath11k_debugfs_htt_stats_req(ar);
|
||||
mutex_unlock(&ar->conf_mutex);
|
@ -0,0 +1,76 @@
|
||||
From c677d4b1bcc4f7330043d8f039f494557d720ed4 Mon Sep 17 00:00:00 2001
|
||||
From: Wen Gong <wgong@codeaurora.org>
|
||||
Date: Tue, 28 Sep 2021 14:00:45 +0300
|
||||
Subject: [PATCH 049/120] ath11k: indicate scan complete for scan canceled when
|
||||
scan running
|
||||
|
||||
ath11k prints "Received scan event for unknown vdev" when doing the
|
||||
following test:
|
||||
1. trigger scan
|
||||
2. wait 0.2 second
|
||||
3. iw reg set or 11d scan complete from firmware
|
||||
|
||||
Reason: When iw reg set or 11d scan complete, the new country code will
|
||||
be set to the firmware, and the new regdomain info indicated to ath11k,
|
||||
then the new channel list will be sent to the firmware. The firmware
|
||||
will cancel the current scan after receiving WMI_SCAN_CHAN_LIST_CMDID
|
||||
which is used for the new channel list, and the state of ath11k is
|
||||
ATH11K_SCAN_RUNNING, then ath11k_get_ar_on_scan_abort() returns NULL and
|
||||
ath11k_scan_event() returns at this point and does not indicate scan
|
||||
completion to mac80211.
|
||||
|
||||
Indicate scan completion to mac80211 and get rid of the "Received scan
|
||||
event for unknown vdev" print for the above case.
|
||||
|
||||
Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1
|
||||
|
||||
Signed-off-by: Wen Gong <wgong@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20210914164226.38843-2-jouni@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/wmi.c | 18 ++++++++++++------
|
||||
1 file changed, 12 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/wmi.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
|
||||
@@ -6289,8 +6289,9 @@ exit:
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
-static struct ath11k *ath11k_get_ar_on_scan_abort(struct ath11k_base *ab,
|
||||
- u32 vdev_id)
|
||||
+static struct ath11k *ath11k_get_ar_on_scan_state(struct ath11k_base *ab,
|
||||
+ u32 vdev_id,
|
||||
+ enum ath11k_scan_state state)
|
||||
{
|
||||
int i;
|
||||
struct ath11k_pdev *pdev;
|
||||
@@ -6302,7 +6303,7 @@ static struct ath11k *ath11k_get_ar_on_s
|
||||
ar = pdev->ar;
|
||||
|
||||
spin_lock_bh(&ar->data_lock);
|
||||
- if (ar->scan.state == ATH11K_SCAN_ABORTING &&
|
||||
+ if (ar->scan.state == state &&
|
||||
ar->scan.vdev_id == vdev_id) {
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
return ar;
|
||||
@@ -6332,10 +6333,15 @@ static void ath11k_scan_event(struct ath
|
||||
* aborting scan's vdev id matches this event info.
|
||||
*/
|
||||
if (scan_ev.event_type == WMI_SCAN_EVENT_COMPLETED &&
|
||||
- scan_ev.reason == WMI_SCAN_REASON_CANCELLED)
|
||||
- ar = ath11k_get_ar_on_scan_abort(ab, scan_ev.vdev_id);
|
||||
- else
|
||||
+ scan_ev.reason == WMI_SCAN_REASON_CANCELLED) {
|
||||
+ ar = ath11k_get_ar_on_scan_state(ab, scan_ev.vdev_id,
|
||||
+ ATH11K_SCAN_ABORTING);
|
||||
+ if (!ar)
|
||||
+ ar = ath11k_get_ar_on_scan_state(ab, scan_ev.vdev_id,
|
||||
+ ATH11K_SCAN_RUNNING);
|
||||
+ } else {
|
||||
ar = ath11k_mac_get_ar_by_vdev_id(ab, scan_ev.vdev_id);
|
||||
+ }
|
||||
|
||||
if (!ar) {
|
||||
ath11k_warn(ab, "Received scan event for unknown vdev");
|
@ -0,0 +1,71 @@
|
||||
From 62db14ea95b1017c53ebb8f724119ea4d90ecc07 Mon Sep 17 00:00:00 2001
|
||||
From: Wen Gong <wgong@codeaurora.org>
|
||||
Date: Tue, 28 Sep 2021 14:00:45 +0300
|
||||
Subject: [PATCH 050/120] ath11k: indicate to mac80211 scan complete with
|
||||
aborted flag for ATH11K_SCAN_STARTING state
|
||||
|
||||
Scan failure can not be recovered from when running a loop of the
|
||||
following steps:
|
||||
1. run scan: "iw wlan scan".
|
||||
2. run command: echo assert > /sys/kernel/debug/ath11k/qca6490\ hw2.0/simulate_fw_crash
|
||||
immediately after step 1.
|
||||
|
||||
result:
|
||||
scan failed and can not recover even when wlan recovery succeeds:
|
||||
command failed: Device or resource busy (-16)
|
||||
|
||||
reason:
|
||||
When scan arrives, WMI_START_SCAN_CMDID is sent to the firmware and
|
||||
function ath11k_mac_op_hw_scan() returns, then simulate_fw_crash arrives
|
||||
and the scan started event does not arrive, and then it starts to do
|
||||
recovery of wlan. __ath11k_mac_scan_finish() which is called from
|
||||
ath11k_core_halt() is one step of recovery, it will not call
|
||||
ieee80211_scan_completed() by logic currently because the scan state is
|
||||
ATH11K_SCAN_STARTING. Thus it leads the scan not being completed in
|
||||
mac80211, and leads all consecutive scans failing with -EBUSY in
|
||||
nl80211_trigger_scan even after wlan recovery success.
|
||||
|
||||
Indicate scan complete with aborted flag to mac80211 for
|
||||
ATH11K_SCAN_STARTING to allow recovery from scan failed with "Device or
|
||||
resource busy (-16)" after wlan recovery.
|
||||
|
||||
Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1
|
||||
|
||||
Signed-off-by: Wen Gong <wgong@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20210914164226.38843-3-jouni@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/mac.c | 15 +++++++++------
|
||||
1 file changed, 9 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -2982,18 +2982,21 @@ void __ath11k_mac_scan_finish(struct ath
|
||||
break;
|
||||
case ATH11K_SCAN_RUNNING:
|
||||
case ATH11K_SCAN_ABORTING:
|
||||
+ if (ar->scan.is_roc && ar->scan.roc_notify)
|
||||
+ ieee80211_remain_on_channel_expired(ar->hw);
|
||||
+ fallthrough;
|
||||
+ case ATH11K_SCAN_STARTING:
|
||||
if (!ar->scan.is_roc) {
|
||||
struct cfg80211_scan_info info = {
|
||||
- .aborted = (ar->scan.state ==
|
||||
- ATH11K_SCAN_ABORTING),
|
||||
+ .aborted = ((ar->scan.state ==
|
||||
+ ATH11K_SCAN_ABORTING) ||
|
||||
+ (ar->scan.state ==
|
||||
+ ATH11K_SCAN_STARTING)),
|
||||
};
|
||||
|
||||
ieee80211_scan_completed(ar->hw, &info);
|
||||
- } else if (ar->scan.roc_notify) {
|
||||
- ieee80211_remain_on_channel_expired(ar->hw);
|
||||
}
|
||||
- fallthrough;
|
||||
- case ATH11K_SCAN_STARTING:
|
||||
+
|
||||
ar->scan.state = ATH11K_SCAN_IDLE;
|
||||
ar->scan_channel = NULL;
|
||||
ar->scan.roc_freq = 0;
|
@ -0,0 +1,94 @@
|
||||
From c3a7d7eb4c9853bb457b792cef42ddd4a029a914 Mon Sep 17 00:00:00 2001
|
||||
From: Pradeep Kumar Chitrapu <pradeepc@codeaurora.org>
|
||||
Date: Tue, 28 Sep 2021 14:00:46 +0300
|
||||
Subject: [PATCH 051/120] ath11k: add 6 GHz params in peer assoc command
|
||||
|
||||
Currently A-MPDU aggregation parameters are not being configured
|
||||
during peer association for 6 GHz band. Hence, extract these
|
||||
parameters from station's capabilities received in association
|
||||
request and send to firmware. Without this, A-MPDU aggregation
|
||||
is not happening in 6 GHz band.
|
||||
|
||||
Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.4.0.1-01386-QCAHKSWPL_SILICONZ-1
|
||||
|
||||
Signed-off-by: Pradeep Kumar Chitrapu <pradeepc@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20210913175510.193005-2-jouni@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/mac.c | 50 ++++++++++++++++++++++++++-
|
||||
1 file changed, 49 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -2016,6 +2016,53 @@ static void ath11k_peer_assoc_h_he(struc
|
||||
arg->peer_bw_rxnss_override);
|
||||
}
|
||||
|
||||
+static void ath11k_peer_assoc_h_he_6ghz(struct ath11k *ar,
|
||||
+ struct ieee80211_vif *vif,
|
||||
+ struct ieee80211_sta *sta,
|
||||
+ struct peer_assoc_params *arg)
|
||||
+{
|
||||
+ const struct ieee80211_sta_he_cap *he_cap = &sta->he_cap;
|
||||
+ struct cfg80211_chan_def def;
|
||||
+ enum nl80211_band band;
|
||||
+ u8 ampdu_factor;
|
||||
+
|
||||
+ if (WARN_ON(ath11k_mac_vif_chan(vif, &def)))
|
||||
+ return;
|
||||
+
|
||||
+ band = def.chan->band;
|
||||
+
|
||||
+ if (!arg->he_flag || band != NL80211_BAND_6GHZ || !sta->he_6ghz_capa.capa)
|
||||
+ return;
|
||||
+
|
||||
+ if (sta->bandwidth == IEEE80211_STA_RX_BW_80)
|
||||
+ arg->bw_80 = true;
|
||||
+
|
||||
+ if (sta->bandwidth == IEEE80211_STA_RX_BW_160)
|
||||
+ arg->bw_160 = true;
|
||||
+
|
||||
+ arg->peer_he_caps_6ghz = le16_to_cpu(sta->he_6ghz_capa.capa);
|
||||
+ arg->peer_mpdu_density =
|
||||
+ ath11k_parse_mpdudensity(FIELD_GET(IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START,
|
||||
+ arg->peer_he_caps_6ghz));
|
||||
+
|
||||
+ /* From IEEE Std 802.11ax-2021 - Section 10.12.2: An HE STA shall be capable of
|
||||
+ * receiving A-MPDU where the A-MPDU pre-EOF padding length is up to the value
|
||||
+ * indicated by the Maximum A-MPDU Length Exponent Extension field in the HE
|
||||
+ * Capabilities element and the Maximum A-MPDU Length Exponent field in HE 6 GHz
|
||||
+ * Band Capabilities element in the 6 GHz band.
|
||||
+ *
|
||||
+ * Here, we are extracting the Max A-MPDU Exponent Extension from HE caps and
|
||||
+ * factor is the Maximum A-MPDU Length Exponent from HE 6 GHZ Band capability.
|
||||
+ */
|
||||
+ ampdu_factor = FIELD_GET(IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_MASK,
|
||||
+ he_cap->he_cap_elem.mac_cap_info[3]) +
|
||||
+ FIELD_GET(IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP,
|
||||
+ arg->peer_he_caps_6ghz);
|
||||
+
|
||||
+ arg->peer_max_mpdu = (1u << (IEEE80211_HE_6GHZ_MAX_AMPDU_FACTOR +
|
||||
+ ampdu_factor)) - 1;
|
||||
+}
|
||||
+
|
||||
static void ath11k_peer_assoc_h_smps(struct ieee80211_sta *sta,
|
||||
struct peer_assoc_params *arg)
|
||||
{
|
||||
@@ -2305,6 +2352,7 @@ static void ath11k_peer_assoc_prepare(st
|
||||
ath11k_peer_assoc_h_ht(ar, vif, sta, arg);
|
||||
ath11k_peer_assoc_h_vht(ar, vif, sta, arg);
|
||||
ath11k_peer_assoc_h_he(ar, vif, sta, arg);
|
||||
+ ath11k_peer_assoc_h_he_6ghz(ar, vif, sta, arg);
|
||||
ath11k_peer_assoc_h_qos(ar, vif, sta, arg);
|
||||
ath11k_peer_assoc_h_smps(sta, arg);
|
||||
|
||||
@@ -7598,7 +7646,7 @@ static int __ath11k_mac_register(struct
|
||||
if (cap->nss_ratio_enabled)
|
||||
ieee80211_hw_set(ar->hw, SUPPORTS_VHT_EXT_NSS_BW);
|
||||
|
||||
- if (ht_cap & WMI_HT_CAP_ENABLED) {
|
||||
+ if ((ht_cap & WMI_HT_CAP_ENABLED) || ar->supports_6ghz) {
|
||||
ieee80211_hw_set(ar->hw, AMPDU_AGGREGATION);
|
||||
ieee80211_hw_set(ar->hw, TX_AMPDU_SETUP_IN_HW);
|
||||
ieee80211_hw_set(ar->hw, SUPPORTS_REORDERING_BUFFER);
|
@ -0,0 +1,93 @@
|
||||
From 6f4d70308e5eb63c99702e93f7c0d8e55f360da2 Mon Sep 17 00:00:00 2001
|
||||
From: Pradeep Kumar Chitrapu <pradeepc@codeaurora.org>
|
||||
Date: Tue, 28 Sep 2021 14:00:46 +0300
|
||||
Subject: [PATCH 052/120] ath11k: support SMPS configuration for 6 GHz
|
||||
|
||||
Parse SMPS configuration from IEs and configure. Without this,
|
||||
SMPS is not enabled for 6 GHz band.
|
||||
|
||||
Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.4.0.1-01386-QCAHKSWPL_SILICONZ-1
|
||||
|
||||
Signed-off-by: Pradeep Kumar Chitrapu <pradeepc@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20210913175510.193005-3-jouni@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/mac.c | 31 ++++++++++++++++++---------
|
||||
1 file changed, 21 insertions(+), 10 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -2069,11 +2069,16 @@ static void ath11k_peer_assoc_h_smps(str
|
||||
const struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
|
||||
int smps;
|
||||
|
||||
- if (!ht_cap->ht_supported)
|
||||
+ if (!ht_cap->ht_supported && !sta->he_6ghz_capa.capa)
|
||||
return;
|
||||
|
||||
- smps = ht_cap->cap & IEEE80211_HT_CAP_SM_PS;
|
||||
- smps >>= IEEE80211_HT_CAP_SM_PS_SHIFT;
|
||||
+ if (ht_cap->ht_supported) {
|
||||
+ smps = ht_cap->cap & IEEE80211_HT_CAP_SM_PS;
|
||||
+ smps >>= IEEE80211_HT_CAP_SM_PS_SHIFT;
|
||||
+ } else {
|
||||
+ smps = FIELD_GET(IEEE80211_HE_6GHZ_CAP_SM_PS,
|
||||
+ le16_to_cpu(sta->he_6ghz_capa.capa));
|
||||
+ }
|
||||
|
||||
switch (smps) {
|
||||
case WLAN_HT_CAP_SM_PS_STATIC:
|
||||
@@ -2361,15 +2366,20 @@ static void ath11k_peer_assoc_prepare(st
|
||||
|
||||
static int ath11k_setup_peer_smps(struct ath11k *ar, struct ath11k_vif *arvif,
|
||||
const u8 *addr,
|
||||
- const struct ieee80211_sta_ht_cap *ht_cap)
|
||||
+ const struct ieee80211_sta_ht_cap *ht_cap,
|
||||
+ u16 he_6ghz_capa)
|
||||
{
|
||||
int smps;
|
||||
|
||||
- if (!ht_cap->ht_supported)
|
||||
+ if (!ht_cap->ht_supported && !he_6ghz_capa)
|
||||
return 0;
|
||||
|
||||
- smps = ht_cap->cap & IEEE80211_HT_CAP_SM_PS;
|
||||
- smps >>= IEEE80211_HT_CAP_SM_PS_SHIFT;
|
||||
+ if (ht_cap->ht_supported) {
|
||||
+ smps = ht_cap->cap & IEEE80211_HT_CAP_SM_PS;
|
||||
+ smps >>= IEEE80211_HT_CAP_SM_PS_SHIFT;
|
||||
+ } else {
|
||||
+ smps = FIELD_GET(IEEE80211_HE_6GHZ_CAP_SM_PS, he_6ghz_capa);
|
||||
+ }
|
||||
|
||||
if (smps >= ARRAY_SIZE(ath11k_smps_map))
|
||||
return -EINVAL;
|
||||
@@ -2422,7 +2432,8 @@ static void ath11k_bss_assoc(struct ieee
|
||||
}
|
||||
|
||||
ret = ath11k_setup_peer_smps(ar, arvif, bss_conf->bssid,
|
||||
- &ap_sta->ht_cap);
|
||||
+ &ap_sta->ht_cap,
|
||||
+ le16_to_cpu(ap_sta->he_6ghz_capa.capa));
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab, "failed to setup peer SMPS for vdev %d: %d\n",
|
||||
arvif->vdev_id, ret);
|
||||
@@ -3714,7 +3725,7 @@ static int ath11k_station_assoc(struct a
|
||||
return 0;
|
||||
|
||||
ret = ath11k_setup_peer_smps(ar, arvif, sta->addr,
|
||||
- &sta->ht_cap);
|
||||
+ &sta->ht_cap, le16_to_cpu(sta->he_6ghz_capa.capa));
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab, "failed to setup peer SMPS for vdev %d: %d\n",
|
||||
arvif->vdev_id, ret);
|
||||
@@ -7661,7 +7672,7 @@ static int __ath11k_mac_register(struct
|
||||
* for each band for a dual band capable radio. It will be tricky to
|
||||
* handle it when the ht capability different for each band.
|
||||
*/
|
||||
- if (ht_cap & WMI_HT_CAP_DYNAMIC_SMPS)
|
||||
+ if (ht_cap & WMI_HT_CAP_DYNAMIC_SMPS || ar->supports_6ghz)
|
||||
ar->hw->wiphy->features |= NL80211_FEATURE_DYNAMIC_SMPS;
|
||||
|
||||
ar->hw->wiphy->max_scan_ssids = WLAN_SCAN_PARAMS_MAX_SSID;
|
@ -0,0 +1,70 @@
|
||||
From 7210b4b77fe47697890d2d3b2ce57ac9f767bffc Mon Sep 17 00:00:00 2001
|
||||
From: Tim Gardner <tim.gardner@canonical.com>
|
||||
Date: Tue, 5 Oct 2021 16:55:54 +0300
|
||||
Subject: [PATCH 054/120] ath11k: Remove unused variable in
|
||||
ath11k_dp_rx_mon_merg_msdus()
|
||||
|
||||
Coverity complains that a constant variable guards dead code. In fact,
|
||||
mpdu_buf is set NULL and never updated.
|
||||
|
||||
4834err_merge_fail:
|
||||
null: At condition mpdu_buf, the value of mpdu_buf must be NULL.
|
||||
dead_error_condition: The condition mpdu_buf cannot be true.
|
||||
CID 92162 (#1 of 1): 'Constant' variable guards dead code (DEADCODE)
|
||||
dead_error_line: Execution cannot reach the expression decap_format !=
|
||||
DP_RX_DECAP_TYPE_RAW inside this statement: if (mpdu_buf && decap_forma....
|
||||
Local variable mpdu_buf is assigned only once, to a constant value, making it
|
||||
effectively constant throughout its scope. If this is not the intent, examine
|
||||
the logic to see if there is a missing assignment that would make mpdu_buf not
|
||||
remain constant.
|
||||
4835 if (mpdu_buf && decap_format != DP_RX_DECAP_TYPE_RAW) {
|
||||
|
||||
Fix this by removing mpdu_buf and unreachable code.
|
||||
|
||||
Cc: Kalle Valo <kvalo@codeaurora.org>
|
||||
Cc: "David S. Miller" <davem@davemloft.net>
|
||||
Cc: Jakub Kicinski <kuba@kernel.org>
|
||||
Cc: ath11k@lists.infradead.org
|
||||
Cc: linux-wireless@vger.kernel.org
|
||||
Cc: netdev@vger.kernel.org
|
||||
Cc: linux-kernel@vger.kernel.org
|
||||
Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20210927150743.19816-1-tim.gardner@canonical.com
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/dp_rx.c | 10 +---------
|
||||
1 file changed, 1 insertion(+), 9 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
|
||||
@@ -4828,7 +4828,7 @@ ath11k_dp_rx_mon_merg_msdus(struct ath11
|
||||
struct ieee80211_rx_status *rxs)
|
||||
{
|
||||
struct ath11k_base *ab = ar->ab;
|
||||
- struct sk_buff *msdu, *mpdu_buf, *prev_buf;
|
||||
+ struct sk_buff *msdu, *prev_buf;
|
||||
u32 wifi_hdr_len;
|
||||
struct hal_rx_desc *rx_desc;
|
||||
char *hdr_desc;
|
||||
@@ -4836,8 +4836,6 @@ ath11k_dp_rx_mon_merg_msdus(struct ath11
|
||||
struct ieee80211_hdr_3addr *wh;
|
||||
struct rx_attention *rx_attention;
|
||||
|
||||
- mpdu_buf = NULL;
|
||||
-
|
||||
if (!head_msdu)
|
||||
goto err_merge_fail;
|
||||
|
||||
@@ -4920,12 +4918,6 @@ ath11k_dp_rx_mon_merg_msdus(struct ath11
|
||||
return head_msdu;
|
||||
|
||||
err_merge_fail:
|
||||
- if (mpdu_buf && decap_format != DP_RX_DECAP_TYPE_RAW) {
|
||||
- ath11k_dbg(ab, ATH11K_DBG_DATA,
|
||||
- "err_merge_fail mpdu_buf %pK", mpdu_buf);
|
||||
- /* Free the head buffer */
|
||||
- dev_kfree_skb_any(mpdu_buf);
|
||||
- }
|
||||
return NULL;
|
||||
}
|
||||
|
@ -0,0 +1,26 @@
|
||||
From 567ec33a76c7d8e7fbd7a73c81dd16b9efc7ae6d Mon Sep 17 00:00:00 2001
|
||||
From: Colin Ian King <colin.king@canonical.com>
|
||||
Date: Wed, 6 Oct 2021 09:32:17 +0100
|
||||
Subject: [PATCH 055/120] ath11k: Fix spelling mistake "incompaitiblity" ->
|
||||
"incompatibility"
|
||||
|
||||
There is a spelling mistake in an ath11k_warn message. Fix it.
|
||||
|
||||
Signed-off-by: Colin Ian King <colin.king@canonical.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20211006083217.349596-1-colin.king@canonical.com
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/mac.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -7081,7 +7081,7 @@ ath11k_mac_op_set_bitrate_mask(struct ie
|
||||
|
||||
if (!ath11k_mac_validate_vht_he_fixed_rate_settings(ar, band, mask))
|
||||
ath11k_warn(ar->ab,
|
||||
- "could not update fixed rate settings to all peers due to mcs/nss incompaitiblity\n");
|
||||
+ "could not update fixed rate settings to all peers due to mcs/nss incompatibility\n");
|
||||
nss = min_t(u32, ar->num_tx_chains,
|
||||
max(max(ath11k_mac_max_ht_nss(ht_mcs_mask),
|
||||
ath11k_mac_max_vht_nss(vht_mcs_mask)),
|
@ -0,0 +1,56 @@
|
||||
From 16bdce2ada5a4c3c91b7c4e81780d2de50bd6ab5 Mon Sep 17 00:00:00 2001
|
||||
From: Kalle Valo <kvalo@codeaurora.org>
|
||||
Date: Fri, 8 Oct 2021 17:39:32 +0300
|
||||
Subject: [PATCH 056/120] ath11k: fix m68k and xtensa build failure in
|
||||
ath11k_peer_assoc_h_smps()
|
||||
|
||||
Stephen reported that ath11k was failing to build on m68k and xtensa:
|
||||
|
||||
In file included from <command-line>:0:0:
|
||||
In function 'ath11k_peer_assoc_h_smps',
|
||||
inlined from 'ath11k_peer_assoc_prepare' at drivers/net/wireless/ath/ath11k/mac.c:2362:2:
|
||||
include/linux/compiler_types.h:317:38: error: call to '__compiletime_assert_650' declared with attribute error: FIELD_GET: type of reg too small for mask
|
||||
_compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
|
||||
^
|
||||
include/linux/compiler_types.h:298:4: note: in definition of macro '__compiletime_assert'
|
||||
prefix ## suffix(); \
|
||||
^
|
||||
include/linux/compiler_types.h:317:2: note: in expansion of macro '_compiletime_assert'
|
||||
_compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
|
||||
^
|
||||
include/linux/build_bug.h:39:37: note: in expansion of macro 'compiletime_assert'
|
||||
#define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
|
||||
^
|
||||
include/linux/bitfield.h:52:3: note: in expansion of macro 'BUILD_BUG_ON_MSG'
|
||||
BUILD_BUG_ON_MSG((_mask) > (typeof(_reg))~0ull, \
|
||||
^
|
||||
include/linux/bitfield.h:108:3: note: in expansion of macro '__BF_FIELD_CHECK'
|
||||
__BF_FIELD_CHECK(_mask, _reg, 0U, "FIELD_GET: "); \
|
||||
^
|
||||
drivers/net/wireless/ath/ath11k/mac.c:2079:10: note: in expansion of macro 'FIELD_GET'
|
||||
smps = FIELD_GET(IEEE80211_HE_6GHZ_CAP_SM_PS,
|
||||
|
||||
Fix the issue by using le16_get_bits() to specify the size explicitly.
|
||||
|
||||
Fixes: 6f4d70308e5e ("ath11k: support SMPS configuration for 6 GHz")
|
||||
Reported-by: Stephen Rothwell <sfr@canb.auug.org.au>
|
||||
Tested-by: Geert Uytterhoeven <geert@linux-m68k.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/mac.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -2076,8 +2076,8 @@ static void ath11k_peer_assoc_h_smps(str
|
||||
smps = ht_cap->cap & IEEE80211_HT_CAP_SM_PS;
|
||||
smps >>= IEEE80211_HT_CAP_SM_PS_SHIFT;
|
||||
} else {
|
||||
- smps = FIELD_GET(IEEE80211_HE_6GHZ_CAP_SM_PS,
|
||||
- le16_to_cpu(sta->he_6ghz_capa.capa));
|
||||
+ smps = le16_get_bits(sta->he_6ghz_capa.capa,
|
||||
+ IEEE80211_HE_6GHZ_CAP_SM_PS);
|
||||
}
|
||||
|
||||
switch (smps) {
|
@ -0,0 +1,29 @@
|
||||
From 4f50bdfb4e5fc3d753c8cf94b94b43aaa2c49b95 Mon Sep 17 00:00:00 2001
|
||||
From: Colin Ian King <colin.king@canonical.com>
|
||||
Date: Thu, 7 Oct 2021 18:16:24 +0300
|
||||
Subject: [PATCH 057/120] ath11k: Remove redundant assignment to variable
|
||||
fw_size
|
||||
|
||||
Variable fw_size is being assigned a value that is never read and
|
||||
being re-assigned a new value in the next statement. The assignment
|
||||
is redundant and can be removed.
|
||||
|
||||
Addresses-Coverity: ("Unused value")
|
||||
Fixes: 336e7b53c82f ("ath11k: clean up BDF download functions")
|
||||
Signed-off-by: Colin Ian King <colin.king@canonical.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20211006105529.1011239-1-colin.king@canonical.com
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/qmi.c | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/qmi.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/qmi.c
|
||||
@@ -2135,7 +2135,6 @@ static int ath11k_qmi_load_bdf_qmi(struc
|
||||
|
||||
ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi bdf_type %d\n", bdf_type);
|
||||
|
||||
- fw_size = bd.len;
|
||||
fw_size = min_t(u32, ab->hw_params.fw.board_size, bd.len);
|
||||
|
||||
ret = ath11k_qmi_load_file_target_mem(ab, bd.data, fw_size, bdf_type);
|
@ -0,0 +1,40 @@
|
||||
From ec4363384c3f110561dc5ee2e59adee02dbd9f73 Mon Sep 17 00:00:00 2001
|
||||
From: "Gustavo A. R. Silva" <gustavoars@kernel.org>
|
||||
Date: Thu, 7 Oct 2021 18:16:24 +0300
|
||||
Subject: [PATCH 058/120] ath11k: Use kcalloc() instead of kzalloc()
|
||||
|
||||
Use 2-factor multiplication argument form kcalloc() instead
|
||||
of kzalloc().
|
||||
|
||||
Link: https://github.com/KSPP/linux/issues/162
|
||||
Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20211006181204.GA913553@embeddedor
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/wmi.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/wmi.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
|
||||
@@ -4065,8 +4065,8 @@ static int ath11k_wmi_tlv_mac_phy_caps_p
|
||||
|
||||
len = min_t(u16, len, sizeof(struct wmi_mac_phy_capabilities));
|
||||
if (!svc_rdy_ext->n_mac_phy_caps) {
|
||||
- svc_rdy_ext->mac_phy_caps = kzalloc((svc_rdy_ext->tot_phy_id) * len,
|
||||
- GFP_ATOMIC);
|
||||
+ svc_rdy_ext->mac_phy_caps = kcalloc(svc_rdy_ext->tot_phy_id,
|
||||
+ len, GFP_ATOMIC);
|
||||
if (!svc_rdy_ext->mac_phy_caps)
|
||||
return -ENOMEM;
|
||||
}
|
||||
@@ -4466,8 +4466,8 @@ static struct cur_reg_rule
|
||||
struct cur_reg_rule *reg_rule_ptr;
|
||||
u32 count;
|
||||
|
||||
- reg_rule_ptr = kzalloc((num_reg_rules * sizeof(*reg_rule_ptr)),
|
||||
- GFP_ATOMIC);
|
||||
+ reg_rule_ptr = kcalloc(num_reg_rules, sizeof(*reg_rule_ptr),
|
||||
+ GFP_ATOMIC);
|
||||
|
||||
if (!reg_rule_ptr)
|
||||
return NULL;
|
@ -0,0 +1,139 @@
|
||||
From 96527d527b271d950367ad13e3de8b0673545622 Mon Sep 17 00:00:00 2001
|
||||
From: Baochen Qiang <bqiang@codeaurora.org>
|
||||
Date: Mon, 11 Oct 2021 09:33:08 +0300
|
||||
Subject: [PATCH 059/120] ath11k: Handle MSI enablement during rmmod and SSR
|
||||
|
||||
When doing "rmmod ath11k_pci", ath11k performs global SOC reset
|
||||
and MHI reset, where 0 address access is captured by IOMMU. See
|
||||
log below:
|
||||
|
||||
...
|
||||
[ 133.953860] ath11k_pci 0000:02:00.0: setting mhi state: DEINIT(1)
|
||||
[ 133.959714] ath11k_pci 0000:02:00.0: AMD-Vi: Event logged [IO_PAGE_FAULT domain=0x000a address=0x0 flags=0x0020]
|
||||
[ 133.973854] ath11k_pci 0000:02:00.0: MHISTATUS 0xff04
|
||||
[ 133.974095] ath11k_pci 0000:02:00.0: AMD-Vi: Event logged [IO_PAGE_FAULT domain=0x000a address=0x0 flags=0x0020]
|
||||
...
|
||||
|
||||
This issue is also observed in SSR process, cause a similar
|
||||
sequence as above is performed.
|
||||
|
||||
Such an invalid access occurs because, during rmmod or SSR, MSI
|
||||
address is cleared but HW MSI functionality not disabled, thus HW
|
||||
target is able to raise an MSI transaction with 0 as MSI address.
|
||||
|
||||
So it can be fixed by simply disabling MSI before reset. For SSR,
|
||||
since MSI functionality is still needed after target is brought
|
||||
back, we need to reenable it.
|
||||
|
||||
Also change naming of some interfaces related.
|
||||
|
||||
Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1
|
||||
Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1
|
||||
|
||||
Signed-off-by: Baochen Qiang <bqiang@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20210913180246.193388-5-jouni@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/pci.c | 41 +++++++++++++++++++++++----
|
||||
1 file changed, 36 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/pci.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/pci.c
|
||||
@@ -855,7 +855,32 @@ static void ath11k_pci_ce_irqs_enable(st
|
||||
}
|
||||
}
|
||||
|
||||
-static int ath11k_pci_enable_msi(struct ath11k_pci *ab_pci)
|
||||
+static void ath11k_pci_msi_config(struct ath11k_pci *ab_pci, bool enable)
|
||||
+{
|
||||
+ struct pci_dev *dev = ab_pci->pdev;
|
||||
+ u16 control;
|
||||
+
|
||||
+ pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &control);
|
||||
+
|
||||
+ if (enable)
|
||||
+ control |= PCI_MSI_FLAGS_ENABLE;
|
||||
+ else
|
||||
+ control &= ~PCI_MSI_FLAGS_ENABLE;
|
||||
+
|
||||
+ pci_write_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, control);
|
||||
+}
|
||||
+
|
||||
+static void ath11k_pci_msi_enable(struct ath11k_pci *ab_pci)
|
||||
+{
|
||||
+ ath11k_pci_msi_config(ab_pci, true);
|
||||
+}
|
||||
+
|
||||
+static void ath11k_pci_msi_disable(struct ath11k_pci *ab_pci)
|
||||
+{
|
||||
+ ath11k_pci_msi_config(ab_pci, false);
|
||||
+}
|
||||
+
|
||||
+static int ath11k_pci_alloc_msi(struct ath11k_pci *ab_pci)
|
||||
{
|
||||
struct ath11k_base *ab = ab_pci->ab;
|
||||
const struct ath11k_msi_config *msi_config = ab_pci->msi_config;
|
||||
@@ -876,6 +901,7 @@ static int ath11k_pci_enable_msi(struct
|
||||
else
|
||||
return num_vectors;
|
||||
}
|
||||
+ ath11k_pci_msi_disable(ab_pci);
|
||||
|
||||
msi_desc = irq_get_msi_desc(ab_pci->pdev->irq);
|
||||
if (!msi_desc) {
|
||||
@@ -898,7 +924,7 @@ free_msi_vector:
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static void ath11k_pci_disable_msi(struct ath11k_pci *ab_pci)
|
||||
+static void ath11k_pci_free_msi(struct ath11k_pci *ab_pci)
|
||||
{
|
||||
pci_free_irq_vectors(ab_pci->pdev);
|
||||
}
|
||||
@@ -1019,6 +1045,8 @@ static int ath11k_pci_power_up(struct at
|
||||
*/
|
||||
ath11k_pci_aspm_disable(ab_pci);
|
||||
|
||||
+ ath11k_pci_msi_enable(ab_pci);
|
||||
+
|
||||
ret = ath11k_mhi_start(ab_pci);
|
||||
if (ret) {
|
||||
ath11k_err(ab, "failed to start mhi: %d\n", ret);
|
||||
@@ -1039,6 +1067,9 @@ static void ath11k_pci_power_down(struct
|
||||
ath11k_pci_aspm_restore(ab_pci);
|
||||
|
||||
ath11k_pci_force_wake(ab_pci->ab);
|
||||
+
|
||||
+ ath11k_pci_msi_disable(ab_pci);
|
||||
+
|
||||
ath11k_mhi_stop(ab_pci);
|
||||
clear_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags);
|
||||
ath11k_pci_sw_reset(ab_pci->ab, false);
|
||||
@@ -1263,7 +1294,7 @@ static int ath11k_pci_probe(struct pci_d
|
||||
goto err_pci_free_region;
|
||||
}
|
||||
|
||||
- ret = ath11k_pci_enable_msi(ab_pci);
|
||||
+ ret = ath11k_pci_alloc_msi(ab_pci);
|
||||
if (ret) {
|
||||
ath11k_err(ab, "failed to enable msi: %d\n", ret);
|
||||
goto err_pci_free_region;
|
||||
@@ -1317,7 +1348,7 @@ err_mhi_unregister:
|
||||
ath11k_mhi_unregister(ab_pci);
|
||||
|
||||
err_pci_disable_msi:
|
||||
- ath11k_pci_disable_msi(ab_pci);
|
||||
+ ath11k_pci_free_msi(ab_pci);
|
||||
|
||||
err_pci_free_region:
|
||||
ath11k_pci_free_region(ab_pci);
|
||||
@@ -1348,7 +1379,7 @@ qmi_fail:
|
||||
ath11k_mhi_unregister(ab_pci);
|
||||
|
||||
ath11k_pci_free_irq(ab);
|
||||
- ath11k_pci_disable_msi(ab_pci);
|
||||
+ ath11k_pci_free_msi(ab_pci);
|
||||
ath11k_pci_free_region(ab_pci);
|
||||
|
||||
ath11k_hal_srng_deinit(ab);
|
@ -0,0 +1,241 @@
|
||||
From 31582373a4a8e888b29ed759d28330a1995f2162 Mon Sep 17 00:00:00 2001
|
||||
From: Baochen Qiang <bqiang@codeaurora.org>
|
||||
Date: Mon, 11 Oct 2021 09:33:09 +0300
|
||||
Subject: [PATCH 060/120] ath11k: Change number of TCL rings to one for QCA6390
|
||||
|
||||
Some targets, QCA6390 for example, use only one TCL ring, it is better to
|
||||
initialize only one ring and leave others untouched for such targets.
|
||||
|
||||
This is a theoretical fix found during code review, no visible impact.
|
||||
|
||||
Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1
|
||||
|
||||
Signed-off-by: Baochen Qiang <bqiang@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20210914163726.38604-1-jouni@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/core.c | 10 +++++-----
|
||||
drivers/net/wireless/ath/ath11k/debugfs.c | 2 +-
|
||||
drivers/net/wireless/ath/ath11k/dp.c | 10 +++++-----
|
||||
drivers/net/wireless/ath/ath11k/dp.h | 1 +
|
||||
drivers/net/wireless/ath/ath11k/dp_tx.c | 13 +++++--------
|
||||
drivers/net/wireless/ath/ath11k/hw.h | 2 +-
|
||||
drivers/net/wireless/ath/ath11k/mac.c | 2 +-
|
||||
7 files changed, 19 insertions(+), 21 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/core.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/core.c
|
||||
@@ -58,7 +58,6 @@ static const struct ath11k_hw_params ath
|
||||
.rx_mac_buf_ring = false,
|
||||
.vdev_start_delay = false,
|
||||
.htt_peer_map_v2 = true,
|
||||
- .tcl_0_only = false,
|
||||
|
||||
.spectral = {
|
||||
.fft_sz = 2,
|
||||
@@ -81,6 +80,7 @@ static const struct ath11k_hw_params ath
|
||||
.supports_suspend = false,
|
||||
.hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074),
|
||||
.fix_l1ss = true,
|
||||
+ .max_tx_ring = DP_TCL_NUM_RING_MAX,
|
||||
},
|
||||
{
|
||||
.hw_rev = ATH11K_HW_IPQ6018_HW10,
|
||||
@@ -109,7 +109,6 @@ static const struct ath11k_hw_params ath
|
||||
.rx_mac_buf_ring = false,
|
||||
.vdev_start_delay = false,
|
||||
.htt_peer_map_v2 = true,
|
||||
- .tcl_0_only = false,
|
||||
|
||||
.spectral = {
|
||||
.fft_sz = 4,
|
||||
@@ -129,6 +128,7 @@ static const struct ath11k_hw_params ath
|
||||
.supports_suspend = false,
|
||||
.hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074),
|
||||
.fix_l1ss = true,
|
||||
+ .max_tx_ring = DP_TCL_NUM_RING_MAX,
|
||||
},
|
||||
{
|
||||
.name = "qca6390 hw2.0",
|
||||
@@ -157,7 +157,6 @@ static const struct ath11k_hw_params ath
|
||||
.rx_mac_buf_ring = true,
|
||||
.vdev_start_delay = true,
|
||||
.htt_peer_map_v2 = false,
|
||||
- .tcl_0_only = true,
|
||||
|
||||
.spectral = {
|
||||
.fft_sz = 0,
|
||||
@@ -176,6 +175,7 @@ static const struct ath11k_hw_params ath
|
||||
.supports_suspend = true,
|
||||
.hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074),
|
||||
.fix_l1ss = true,
|
||||
+ .max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390,
|
||||
},
|
||||
{
|
||||
.name = "qcn9074 hw1.0",
|
||||
@@ -203,7 +203,6 @@ static const struct ath11k_hw_params ath
|
||||
.rx_mac_buf_ring = false,
|
||||
.vdev_start_delay = false,
|
||||
.htt_peer_map_v2 = true,
|
||||
- .tcl_0_only = false,
|
||||
|
||||
.spectral = {
|
||||
.fft_sz = 2,
|
||||
@@ -223,6 +222,7 @@ static const struct ath11k_hw_params ath
|
||||
.supports_suspend = false,
|
||||
.hal_desc_sz = sizeof(struct hal_rx_desc_qcn9074),
|
||||
.fix_l1ss = true,
|
||||
+ .max_tx_ring = DP_TCL_NUM_RING_MAX,
|
||||
},
|
||||
{
|
||||
.name = "wcn6855 hw2.0",
|
||||
@@ -251,7 +251,6 @@ static const struct ath11k_hw_params ath
|
||||
.rx_mac_buf_ring = true,
|
||||
.vdev_start_delay = true,
|
||||
.htt_peer_map_v2 = false,
|
||||
- .tcl_0_only = true,
|
||||
|
||||
.spectral = {
|
||||
.fft_sz = 0,
|
||||
@@ -270,6 +269,7 @@ static const struct ath11k_hw_params ath
|
||||
.supports_suspend = true,
|
||||
.hal_desc_sz = sizeof(struct hal_rx_desc_wcn6855),
|
||||
.fix_l1ss = false,
|
||||
+ .max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390,
|
||||
},
|
||||
};
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/debugfs.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/debugfs.c
|
||||
@@ -806,7 +806,7 @@ static ssize_t ath11k_debugfs_dump_soc_d
|
||||
len += scnprintf(buf + len, size - len, "\nSOC TX STATS:\n");
|
||||
len += scnprintf(buf + len, size - len, "\nTCL Ring Full Failures:\n");
|
||||
|
||||
- for (i = 0; i < DP_TCL_NUM_RING_MAX; i++)
|
||||
+ for (i = 0; i < ab->hw_params.max_tx_ring; i++)
|
||||
len += scnprintf(buf + len, size - len, "ring%d: %u\n",
|
||||
i, soc_stats->tx_err.desc_na[i]);
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp.c
|
||||
@@ -311,7 +311,7 @@ void ath11k_dp_stop_shadow_timers(struct
|
||||
if (!ab->hw_params.supports_shadow_regs)
|
||||
return;
|
||||
|
||||
- for (i = 0; i < DP_TCL_NUM_RING_MAX; i++)
|
||||
+ for (i = 0; i < ab->hw_params.max_tx_ring; i++)
|
||||
ath11k_dp_shadow_stop_timer(ab, &ab->dp.tx_ring_timer[i]);
|
||||
|
||||
ath11k_dp_shadow_stop_timer(ab, &ab->dp.reo_cmd_timer);
|
||||
@@ -326,7 +326,7 @@ static void ath11k_dp_srng_common_cleanu
|
||||
ath11k_dp_srng_cleanup(ab, &dp->wbm_desc_rel_ring);
|
||||
ath11k_dp_srng_cleanup(ab, &dp->tcl_cmd_ring);
|
||||
ath11k_dp_srng_cleanup(ab, &dp->tcl_status_ring);
|
||||
- for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) {
|
||||
+ for (i = 0; i < ab->hw_params.max_tx_ring; i++) {
|
||||
ath11k_dp_srng_cleanup(ab, &dp->tx_ring[i].tcl_data_ring);
|
||||
ath11k_dp_srng_cleanup(ab, &dp->tx_ring[i].tcl_comp_ring);
|
||||
}
|
||||
@@ -366,7 +366,7 @@ static int ath11k_dp_srng_common_setup(s
|
||||
goto err;
|
||||
}
|
||||
|
||||
- for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) {
|
||||
+ for (i = 0; i < ab->hw_params.max_tx_ring; i++) {
|
||||
ret = ath11k_dp_srng_setup(ab, &dp->tx_ring[i].tcl_data_ring,
|
||||
HAL_TCL_DATA, i, 0,
|
||||
DP_TCL_DATA_RING_SIZE);
|
||||
@@ -996,7 +996,7 @@ void ath11k_dp_free(struct ath11k_base *
|
||||
|
||||
ath11k_dp_reo_cmd_list_cleanup(ab);
|
||||
|
||||
- for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) {
|
||||
+ for (i = 0; i < ab->hw_params.max_tx_ring; i++) {
|
||||
spin_lock_bh(&dp->tx_ring[i].tx_idr_lock);
|
||||
idr_for_each(&dp->tx_ring[i].txbuf_idr,
|
||||
ath11k_dp_tx_pending_cleanup, ab);
|
||||
@@ -1046,7 +1046,7 @@ int ath11k_dp_alloc(struct ath11k_base *
|
||||
|
||||
size = sizeof(struct hal_wbm_release_ring) * DP_TX_COMP_RING_SIZE;
|
||||
|
||||
- for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) {
|
||||
+ for (i = 0; i < ab->hw_params.max_tx_ring; i++) {
|
||||
idr_init(&dp->tx_ring[i].txbuf_idr);
|
||||
spin_lock_init(&dp->tx_ring[i].tx_idr_lock);
|
||||
dp->tx_ring[i].tcl_data_ring_id = i;
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp.h
|
||||
@@ -170,6 +170,7 @@ struct ath11k_pdev_dp {
|
||||
#define DP_BA_WIN_SZ_MAX 256
|
||||
|
||||
#define DP_TCL_NUM_RING_MAX 3
|
||||
+#define DP_TCL_NUM_RING_MAX_QCA6390 1
|
||||
|
||||
#define DP_IDLE_SCATTER_BUFS_MAX 16
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp_tx.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp_tx.c
|
||||
@@ -115,11 +115,8 @@ int ath11k_dp_tx(struct ath11k *ar, stru
|
||||
|
||||
tcl_ring_sel:
|
||||
tcl_ring_retry = false;
|
||||
- /* For some chip, it can only use tcl0 to tx */
|
||||
- if (ar->ab->hw_params.tcl_0_only)
|
||||
- ti.ring_id = 0;
|
||||
- else
|
||||
- ti.ring_id = ring_selector % DP_TCL_NUM_RING_MAX;
|
||||
+
|
||||
+ ti.ring_id = ring_selector % ab->hw_params.max_tx_ring;
|
||||
|
||||
ring_map |= BIT(ti.ring_id);
|
||||
|
||||
@@ -131,7 +128,7 @@ tcl_ring_sel:
|
||||
spin_unlock_bh(&tx_ring->tx_idr_lock);
|
||||
|
||||
if (ret < 0) {
|
||||
- if (ring_map == (BIT(DP_TCL_NUM_RING_MAX) - 1)) {
|
||||
+ if (ring_map == (BIT(ab->hw_params.max_tx_ring) - 1)) {
|
||||
atomic_inc(&ab->soc_stats.tx_err.misc_fail);
|
||||
return -ENOSPC;
|
||||
}
|
||||
@@ -248,8 +245,8 @@ tcl_ring_sel:
|
||||
* checking this ring earlier for each pkt tx.
|
||||
* Restart ring selection if some rings are not checked yet.
|
||||
*/
|
||||
- if (ring_map != (BIT(DP_TCL_NUM_RING_MAX) - 1) &&
|
||||
- !ar->ab->hw_params.tcl_0_only) {
|
||||
+ if (ring_map != (BIT(ab->hw_params.max_tx_ring) - 1) &&
|
||||
+ ab->hw_params.max_tx_ring > 1) {
|
||||
tcl_ring_retry = true;
|
||||
ring_selector++;
|
||||
}
|
||||
--- a/drivers/net/wireless/ath/ath11k/hw.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/hw.h
|
||||
@@ -152,7 +152,6 @@ struct ath11k_hw_params {
|
||||
bool rx_mac_buf_ring;
|
||||
bool vdev_start_delay;
|
||||
bool htt_peer_map_v2;
|
||||
- bool tcl_0_only;
|
||||
|
||||
struct {
|
||||
u8 fft_sz;
|
||||
@@ -170,6 +169,7 @@ struct ath11k_hw_params {
|
||||
bool supports_suspend;
|
||||
u32 hal_desc_sz;
|
||||
bool fix_l1ss;
|
||||
+ u8 max_tx_ring;
|
||||
};
|
||||
|
||||
struct ath11k_hw_ops {
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -5797,7 +5797,7 @@ err_vdev_del:
|
||||
idr_for_each(&ar->txmgmt_idr,
|
||||
ath11k_mac_vif_txmgmt_idr_remove, vif);
|
||||
|
||||
- for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) {
|
||||
+ for (i = 0; i < ab->hw_params.max_tx_ring; i++) {
|
||||
spin_lock_bh(&ab->dp.tx_ring[i].tx_idr_lock);
|
||||
idr_for_each(&ab->dp.tx_ring[i].txbuf_idr,
|
||||
ath11k_mac_vif_unref, vif);
|
@ -0,0 +1,33 @@
|
||||
From 8cd5c0847160aa9482d7f93ed63c4d72bad70cdf Mon Sep 17 00:00:00 2001
|
||||
From: Baochen Qiang <bqiang@codeaurora.org>
|
||||
Date: Mon, 11 Oct 2021 18:18:00 +0300
|
||||
Subject: [PATCH 061/120] ath11k: Identify DFS channel when sending scan
|
||||
channel list command
|
||||
|
||||
WMI_CHAN_INFO_DFS flag should be set when configuring a DFS channel
|
||||
included in scan channel list. Without it, firmware will not send a
|
||||
probe request frame which is needed in connection to an AP configured
|
||||
with hidden SSID/network_id. So fix this to allow probe request frames
|
||||
to be sent in cases where a beacon frame has been seen on the channel
|
||||
first.
|
||||
|
||||
Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1
|
||||
|
||||
Signed-off-by: Baochen Qiang <bqiang@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20211011054919.77071-1-bqiang@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/wmi.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/wmi.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
|
||||
@@ -2371,6 +2371,8 @@ int ath11k_wmi_send_scan_chan_list_cmd(s
|
||||
chan_info->info |= WMI_CHAN_INFO_QUARTER_RATE;
|
||||
if (tchan_info->psc_channel)
|
||||
chan_info->info |= WMI_CHAN_INFO_PSC;
|
||||
+ if (tchan_info->dfs_set)
|
||||
+ chan_info->info |= WMI_CHAN_INFO_DFS;
|
||||
|
||||
chan_info->info |= FIELD_PREP(WMI_CHAN_INFO_MODE,
|
||||
tchan_info->phy_mode);
|
@ -0,0 +1,299 @@
|
||||
From 734223d78428de3c7c7d7bc04daf258085780d90 Mon Sep 17 00:00:00 2001
|
||||
From: Baochen Qiang <bqiang@codeaurora.org>
|
||||
Date: Wed, 20 Oct 2021 11:59:06 +0300
|
||||
Subject: [PATCH 062/120] ath11k: change return buffer manager for QCA6390
|
||||
|
||||
QCA6390 firmware uses HAL_RX_BUF_RBM_SW1_BM, not HAL_RX_BUF_RBM_SW3_BM. This is
|
||||
needed to fix a case where an A-MSDU has an unexpected LLC/SNAP header in the
|
||||
first subframe (CVE-2020-24588).
|
||||
|
||||
Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1
|
||||
|
||||
Signed-off-by: Baochen Qiang <bqiang@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20210914163726.38604-2-jouni@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/core.c | 5 ++++
|
||||
drivers/net/wireless/ath/ath11k/dp.c | 4 +++-
|
||||
drivers/net/wireless/ath/ath11k/dp_rx.c | 29 +++++++++++++++---------
|
||||
drivers/net/wireless/ath/ath11k/hal_rx.c | 6 +++--
|
||||
drivers/net/wireless/ath/ath11k/hw.c | 11 ++++++++-
|
||||
drivers/net/wireless/ath/ath11k/hw.h | 9 ++++++++
|
||||
6 files changed, 49 insertions(+), 15 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/core.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/core.c
|
||||
@@ -81,6 +81,7 @@ static const struct ath11k_hw_params ath
|
||||
.hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074),
|
||||
.fix_l1ss = true,
|
||||
.max_tx_ring = DP_TCL_NUM_RING_MAX,
|
||||
+ .hal_params = &ath11k_hw_hal_params_ipq8074,
|
||||
},
|
||||
{
|
||||
.hw_rev = ATH11K_HW_IPQ6018_HW10,
|
||||
@@ -129,6 +130,7 @@ static const struct ath11k_hw_params ath
|
||||
.hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074),
|
||||
.fix_l1ss = true,
|
||||
.max_tx_ring = DP_TCL_NUM_RING_MAX,
|
||||
+ .hal_params = &ath11k_hw_hal_params_ipq8074,
|
||||
},
|
||||
{
|
||||
.name = "qca6390 hw2.0",
|
||||
@@ -176,6 +178,7 @@ static const struct ath11k_hw_params ath
|
||||
.hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074),
|
||||
.fix_l1ss = true,
|
||||
.max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390,
|
||||
+ .hal_params = &ath11k_hw_hal_params_qca6390,
|
||||
},
|
||||
{
|
||||
.name = "qcn9074 hw1.0",
|
||||
@@ -223,6 +226,7 @@ static const struct ath11k_hw_params ath
|
||||
.hal_desc_sz = sizeof(struct hal_rx_desc_qcn9074),
|
||||
.fix_l1ss = true,
|
||||
.max_tx_ring = DP_TCL_NUM_RING_MAX,
|
||||
+ .hal_params = &ath11k_hw_hal_params_ipq8074,
|
||||
},
|
||||
{
|
||||
.name = "wcn6855 hw2.0",
|
||||
@@ -270,6 +274,7 @@ static const struct ath11k_hw_params ath
|
||||
.hal_desc_sz = sizeof(struct hal_rx_desc_wcn6855),
|
||||
.fix_l1ss = false,
|
||||
.max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390,
|
||||
+ .hal_params = &ath11k_hw_hal_params_qca6390,
|
||||
},
|
||||
};
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp.c
|
||||
@@ -739,6 +739,7 @@ int ath11k_dp_service_srng(struct ath11k
|
||||
int budget)
|
||||
{
|
||||
struct napi_struct *napi = &irq_grp->napi;
|
||||
+ const struct ath11k_hw_hal_params *hal_params;
|
||||
int grp_id = irq_grp->grp_id;
|
||||
int work_done = 0;
|
||||
int i = 0, j;
|
||||
@@ -821,8 +822,9 @@ int ath11k_dp_service_srng(struct ath11k
|
||||
struct ath11k_pdev_dp *dp = &ar->dp;
|
||||
struct dp_rxdma_ring *rx_ring = &dp->rx_refill_buf_ring;
|
||||
|
||||
+ hal_params = ab->hw_params.hal_params;
|
||||
ath11k_dp_rxbufs_replenish(ab, id, rx_ring, 0,
|
||||
- HAL_RX_BUF_RBM_SW3_BM);
|
||||
+ hal_params->rx_buf_rbm);
|
||||
}
|
||||
}
|
||||
}
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
|
||||
@@ -499,7 +499,7 @@ static int ath11k_dp_rxdma_ring_buf_setu
|
||||
|
||||
rx_ring->bufs_max = num_entries;
|
||||
ath11k_dp_rxbufs_replenish(ar->ab, dp->mac_id, rx_ring, num_entries,
|
||||
- HAL_RX_BUF_RBM_SW3_BM);
|
||||
+ ar->ab->hw_params.hal_params->rx_buf_rbm);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2756,7 +2756,7 @@ try_again:
|
||||
rx_ring = &ar->dp.rx_refill_buf_ring;
|
||||
|
||||
ath11k_dp_rxbufs_replenish(ab, i, rx_ring, num_buffs_reaped[i],
|
||||
- HAL_RX_BUF_RBM_SW3_BM);
|
||||
+ ab->hw_params.hal_params->rx_buf_rbm);
|
||||
}
|
||||
|
||||
ath11k_dp_rx_process_received_packets(ab, napi, &msdu_list,
|
||||
@@ -2949,6 +2949,7 @@ static int ath11k_dp_rx_reap_mon_status_
|
||||
int *budget, struct sk_buff_head *skb_list)
|
||||
{
|
||||
struct ath11k *ar;
|
||||
+ const struct ath11k_hw_hal_params *hal_params;
|
||||
struct ath11k_pdev_dp *dp;
|
||||
struct dp_rxdma_ring *rx_ring;
|
||||
struct hal_srng *srng;
|
||||
@@ -3019,8 +3020,9 @@ move_next:
|
||||
&buf_id);
|
||||
|
||||
if (!skb) {
|
||||
+ hal_params = ab->hw_params.hal_params;
|
||||
ath11k_hal_rx_buf_addr_info_set(rx_mon_status_desc, 0, 0,
|
||||
- HAL_RX_BUF_RBM_SW3_BM);
|
||||
+ hal_params->rx_buf_rbm);
|
||||
num_buffs_reaped++;
|
||||
break;
|
||||
}
|
||||
@@ -3030,7 +3032,8 @@ move_next:
|
||||
FIELD_PREP(DP_RXDMA_BUF_COOKIE_BUF_ID, buf_id);
|
||||
|
||||
ath11k_hal_rx_buf_addr_info_set(rx_mon_status_desc, rxcb->paddr,
|
||||
- cookie, HAL_RX_BUF_RBM_SW3_BM);
|
||||
+ cookie,
|
||||
+ ab->hw_params.hal_params->rx_buf_rbm);
|
||||
ath11k_hal_srng_src_get_next_entry(ab, srng);
|
||||
num_buffs_reaped++;
|
||||
}
|
||||
@@ -3419,7 +3422,8 @@ static int ath11k_dp_rx_h_defrag_reo_rei
|
||||
cookie = FIELD_PREP(DP_RXDMA_BUF_COOKIE_PDEV_ID, dp->mac_id) |
|
||||
FIELD_PREP(DP_RXDMA_BUF_COOKIE_BUF_ID, buf_id);
|
||||
|
||||
- ath11k_hal_rx_buf_addr_info_set(msdu0, paddr, cookie, HAL_RX_BUF_RBM_SW3_BM);
|
||||
+ ath11k_hal_rx_buf_addr_info_set(msdu0, paddr, cookie,
|
||||
+ ab->hw_params.hal_params->rx_buf_rbm);
|
||||
|
||||
/* Fill mpdu details into reo entrace ring */
|
||||
srng = &ab->hal.srng_list[ab->dp.reo_reinject_ring.ring_id];
|
||||
@@ -3796,7 +3800,7 @@ int ath11k_dp_process_rx_err(struct ath1
|
||||
ath11k_hal_rx_msdu_link_info_get(link_desc_va, &num_msdus, msdu_cookies,
|
||||
&rbm);
|
||||
if (rbm != HAL_RX_BUF_RBM_WBM_IDLE_DESC_LIST &&
|
||||
- rbm != HAL_RX_BUF_RBM_SW3_BM) {
|
||||
+ rbm != ab->hw_params.hal_params->rx_buf_rbm) {
|
||||
ab->soc_stats.invalid_rbm++;
|
||||
ath11k_warn(ab, "invalid return buffer manager %d\n", rbm);
|
||||
ath11k_dp_rx_link_desc_return(ab, desc,
|
||||
@@ -3852,7 +3856,7 @@ exit:
|
||||
rx_ring = &ar->dp.rx_refill_buf_ring;
|
||||
|
||||
ath11k_dp_rxbufs_replenish(ab, i, rx_ring, n_bufs_reaped[i],
|
||||
- HAL_RX_BUF_RBM_SW3_BM);
|
||||
+ ab->hw_params.hal_params->rx_buf_rbm);
|
||||
}
|
||||
|
||||
return tot_n_bufs_reaped;
|
||||
@@ -4148,7 +4152,7 @@ int ath11k_dp_rx_process_wbm_err(struct
|
||||
rx_ring = &ar->dp.rx_refill_buf_ring;
|
||||
|
||||
ath11k_dp_rxbufs_replenish(ab, i, rx_ring, num_buffs_reaped[i],
|
||||
- HAL_RX_BUF_RBM_SW3_BM);
|
||||
+ ab->hw_params.hal_params->rx_buf_rbm);
|
||||
}
|
||||
|
||||
rcu_read_lock();
|
||||
@@ -4257,7 +4261,7 @@ int ath11k_dp_process_rxdma_err(struct a
|
||||
|
||||
if (num_buf_freed)
|
||||
ath11k_dp_rxbufs_replenish(ab, mac_id, rx_ring, num_buf_freed,
|
||||
- HAL_RX_BUF_RBM_SW3_BM);
|
||||
+ ab->hw_params.hal_params->rx_buf_rbm);
|
||||
|
||||
return budget - quota;
|
||||
}
|
||||
@@ -4976,6 +4980,7 @@ static void ath11k_dp_rx_mon_dest_proces
|
||||
{
|
||||
struct ath11k_pdev_dp *dp = &ar->dp;
|
||||
struct ath11k_mon_data *pmon = (struct ath11k_mon_data *)&dp->mon_data;
|
||||
+ const struct ath11k_hw_hal_params *hal_params;
|
||||
void *ring_entry;
|
||||
void *mon_dst_srng;
|
||||
u32 ppdu_id;
|
||||
@@ -5039,16 +5044,18 @@ static void ath11k_dp_rx_mon_dest_proces
|
||||
|
||||
if (rx_bufs_used) {
|
||||
rx_mon_stats->dest_ppdu_done++;
|
||||
+ hal_params = ar->ab->hw_params.hal_params;
|
||||
+
|
||||
if (ar->ab->hw_params.rxdma1_enable)
|
||||
ath11k_dp_rxbufs_replenish(ar->ab, dp->mac_id,
|
||||
&dp->rxdma_mon_buf_ring,
|
||||
rx_bufs_used,
|
||||
- HAL_RX_BUF_RBM_SW3_BM);
|
||||
+ hal_params->rx_buf_rbm);
|
||||
else
|
||||
ath11k_dp_rxbufs_replenish(ar->ab, dp->mac_id,
|
||||
&dp->rx_refill_buf_ring,
|
||||
rx_bufs_used,
|
||||
- HAL_RX_BUF_RBM_SW3_BM);
|
||||
+ hal_params->rx_buf_rbm);
|
||||
}
|
||||
}
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/hal_rx.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/hal_rx.c
|
||||
@@ -356,6 +356,7 @@ int ath11k_hal_wbm_desc_parse_err(struct
|
||||
struct hal_wbm_release_ring *wbm_desc = desc;
|
||||
enum hal_wbm_rel_desc_type type;
|
||||
enum hal_wbm_rel_src_module rel_src;
|
||||
+ enum hal_rx_buf_return_buf_manager ret_buf_mgr;
|
||||
|
||||
type = FIELD_GET(HAL_WBM_RELEASE_INFO0_DESC_TYPE,
|
||||
wbm_desc->info0);
|
||||
@@ -371,8 +372,9 @@ int ath11k_hal_wbm_desc_parse_err(struct
|
||||
rel_src != HAL_WBM_REL_SRC_MODULE_REO)
|
||||
return -EINVAL;
|
||||
|
||||
- if (FIELD_GET(BUFFER_ADDR_INFO1_RET_BUF_MGR,
|
||||
- wbm_desc->buf_addr_info.info1) != HAL_RX_BUF_RBM_SW3_BM) {
|
||||
+ ret_buf_mgr = FIELD_GET(BUFFER_ADDR_INFO1_RET_BUF_MGR,
|
||||
+ wbm_desc->buf_addr_info.info1);
|
||||
+ if (ret_buf_mgr != ab->hw_params.hal_params->rx_buf_rbm) {
|
||||
ab->soc_stats.invalid_rbm++;
|
||||
return -EINVAL;
|
||||
}
|
||||
--- a/drivers/net/wireless/ath/ath11k/hw.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/hw.c
|
||||
@@ -7,10 +7,11 @@
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/bitfield.h>
|
||||
|
||||
-#include "hw.h"
|
||||
#include "core.h"
|
||||
#include "ce.h"
|
||||
#include "hif.h"
|
||||
+#include "hal.h"
|
||||
+#include "hw.h"
|
||||
|
||||
/* Map from pdev index to hw mac index */
|
||||
static u8 ath11k_hw_ipq8074_mac_from_pdev_id(int pdev_idx)
|
||||
@@ -2124,3 +2125,11 @@ const struct ath11k_hw_regs wcn6855_regs
|
||||
.pcie_qserdes_sysclk_en_sel = 0x01e0c0ac,
|
||||
.pcie_pcs_osc_dtct_config_base = 0x01e0c628,
|
||||
};
|
||||
+
|
||||
+const struct ath11k_hw_hal_params ath11k_hw_hal_params_ipq8074 = {
|
||||
+ .rx_buf_rbm = HAL_RX_BUF_RBM_SW3_BM,
|
||||
+};
|
||||
+
|
||||
+const struct ath11k_hw_hal_params ath11k_hw_hal_params_qca6390 = {
|
||||
+ .rx_buf_rbm = HAL_RX_BUF_RBM_SW1_BM,
|
||||
+};
|
||||
--- a/drivers/net/wireless/ath/ath11k/hw.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/hw.h
|
||||
@@ -6,6 +6,7 @@
|
||||
#ifndef ATH11K_HW_H
|
||||
#define ATH11K_HW_H
|
||||
|
||||
+#include "hal.h"
|
||||
#include "wmi.h"
|
||||
|
||||
/* Target configuration defines */
|
||||
@@ -119,6 +120,10 @@ struct ath11k_hw_ring_mask {
|
||||
u8 host2rxdma[ATH11K_EXT_IRQ_GRP_NUM_MAX];
|
||||
};
|
||||
|
||||
+struct ath11k_hw_hal_params {
|
||||
+ enum hal_rx_buf_return_buf_manager rx_buf_rbm;
|
||||
+};
|
||||
+
|
||||
struct ath11k_hw_params {
|
||||
const char *name;
|
||||
u16 hw_rev;
|
||||
@@ -170,6 +175,7 @@ struct ath11k_hw_params {
|
||||
u32 hal_desc_sz;
|
||||
bool fix_l1ss;
|
||||
u8 max_tx_ring;
|
||||
+ const struct ath11k_hw_hal_params *hal_params;
|
||||
};
|
||||
|
||||
struct ath11k_hw_ops {
|
||||
@@ -223,6 +229,9 @@ extern const struct ath11k_hw_ring_mask
|
||||
extern const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_qca6390;
|
||||
extern const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_qcn9074;
|
||||
|
||||
+extern const struct ath11k_hw_hal_params ath11k_hw_hal_params_ipq8074;
|
||||
+extern const struct ath11k_hw_hal_params ath11k_hw_hal_params_qca6390;
|
||||
+
|
||||
static inline
|
||||
int ath11k_hw_get_mac_from_pdev_id(struct ath11k_hw_params *hw,
|
||||
int pdev_idx)
|
@ -0,0 +1,94 @@
|
||||
From 82c434c103408842a87404e873992b7698b6df2b Mon Sep 17 00:00:00 2001
|
||||
From: Wen Gong <wgong@codeaurora.org>
|
||||
Date: Thu, 28 Oct 2021 10:46:28 +0300
|
||||
Subject: [PATCH 063/120] ath11k: set correct NL80211_FEATURE_DYNAMIC_SMPS for
|
||||
WCN6855
|
||||
|
||||
Commit 6f4d70308e5e ("ath11k: support SMPS configuration for 6 GHz") changed
|
||||
"if (ht_cap & WMI_HT_CAP_DYNAMIC_SMPS)" to "if (ht_cap &
|
||||
WMI_HT_CAP_DYNAMIC_SMPS || ar->supports_6ghz)" which means
|
||||
NL80211_FEATURE_DYNAMIC_SMPS is enabled for all chips which support 6 GHz.
|
||||
However, WCN6855 supports 6 GHz but it does not support feature
|
||||
NL80211_FEATURE_DYNAMIC_SMPS, and this can lead to MU-MIMO test failures for
|
||||
WCN6855.
|
||||
|
||||
Disable NL80211_FEATURE_DYNAMIC_SMPS for WCN6855 since its ht_cap does not
|
||||
support WMI_HT_CAP_DYNAMIC_SMPS. Enable the feature only on QCN9074 as that's
|
||||
the only other device supporting 6 GHz band.
|
||||
|
||||
Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1
|
||||
|
||||
Signed-off-by: Wen Gong <wgong@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20210914163726.38604-3-jouni@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/core.c | 5 +++++
|
||||
drivers/net/wireless/ath/ath11k/hw.h | 1 +
|
||||
drivers/net/wireless/ath/ath11k/mac.c | 3 ++-
|
||||
3 files changed, 8 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/core.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/core.c
|
||||
@@ -82,6 +82,7 @@ static const struct ath11k_hw_params ath
|
||||
.fix_l1ss = true,
|
||||
.max_tx_ring = DP_TCL_NUM_RING_MAX,
|
||||
.hal_params = &ath11k_hw_hal_params_ipq8074,
|
||||
+ .supports_dynamic_smps_6ghz = false,
|
||||
},
|
||||
{
|
||||
.hw_rev = ATH11K_HW_IPQ6018_HW10,
|
||||
@@ -131,6 +132,7 @@ static const struct ath11k_hw_params ath
|
||||
.fix_l1ss = true,
|
||||
.max_tx_ring = DP_TCL_NUM_RING_MAX,
|
||||
.hal_params = &ath11k_hw_hal_params_ipq8074,
|
||||
+ .supports_dynamic_smps_6ghz = false,
|
||||
},
|
||||
{
|
||||
.name = "qca6390 hw2.0",
|
||||
@@ -179,6 +181,7 @@ static const struct ath11k_hw_params ath
|
||||
.fix_l1ss = true,
|
||||
.max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390,
|
||||
.hal_params = &ath11k_hw_hal_params_qca6390,
|
||||
+ .supports_dynamic_smps_6ghz = false,
|
||||
},
|
||||
{
|
||||
.name = "qcn9074 hw1.0",
|
||||
@@ -227,6 +230,7 @@ static const struct ath11k_hw_params ath
|
||||
.fix_l1ss = true,
|
||||
.max_tx_ring = DP_TCL_NUM_RING_MAX,
|
||||
.hal_params = &ath11k_hw_hal_params_ipq8074,
|
||||
+ .supports_dynamic_smps_6ghz = true,
|
||||
},
|
||||
{
|
||||
.name = "wcn6855 hw2.0",
|
||||
@@ -275,6 +279,7 @@ static const struct ath11k_hw_params ath
|
||||
.fix_l1ss = false,
|
||||
.max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390,
|
||||
.hal_params = &ath11k_hw_hal_params_qca6390,
|
||||
+ .supports_dynamic_smps_6ghz = false,
|
||||
},
|
||||
};
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/hw.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/hw.h
|
||||
@@ -176,6 +176,7 @@ struct ath11k_hw_params {
|
||||
bool fix_l1ss;
|
||||
u8 max_tx_ring;
|
||||
const struct ath11k_hw_hal_params *hal_params;
|
||||
+ bool supports_dynamic_smps_6ghz;
|
||||
};
|
||||
|
||||
struct ath11k_hw_ops {
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -7672,7 +7672,8 @@ static int __ath11k_mac_register(struct
|
||||
* for each band for a dual band capable radio. It will be tricky to
|
||||
* handle it when the ht capability different for each band.
|
||||
*/
|
||||
- if (ht_cap & WMI_HT_CAP_DYNAMIC_SMPS || ar->supports_6ghz)
|
||||
+ if (ht_cap & WMI_HT_CAP_DYNAMIC_SMPS ||
|
||||
+ (ar->supports_6ghz && ab->hw_params.supports_dynamic_smps_6ghz))
|
||||
ar->hw->wiphy->features |= NL80211_FEATURE_DYNAMIC_SMPS;
|
||||
|
||||
ar->hw->wiphy->max_scan_ssids = WLAN_SCAN_PARAMS_MAX_SSID;
|
@ -0,0 +1,73 @@
|
||||
From af3d89649bb69bd5be273cf6c001cd19c2604ca2 Mon Sep 17 00:00:00 2001
|
||||
From: Kalle Valo <kvalo@codeaurora.org>
|
||||
Date: Mon, 8 Nov 2021 14:38:25 +0200
|
||||
Subject: [PATCH 064/120] ath11k: convert ath11k_wmi_pdev_set_ps_mode() to use
|
||||
enum wmi_sta_ps_mode
|
||||
|
||||
It's more descriptive to use the actual enum used by the firmware instead of a
|
||||
boolean so change ath11k_wmi_pdev_set_ps_mode() to use a boolean.
|
||||
|
||||
Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1
|
||||
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20211108123826.8463-1-kvalo@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/mac.c | 3 ++-
|
||||
drivers/net/wireless/ath/ath11k/wmi.c | 7 ++++---
|
||||
drivers/net/wireless/ath/ath11k/wmi.h | 3 ++-
|
||||
3 files changed, 8 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -5638,7 +5638,8 @@ static int ath11k_mac_op_add_interface(s
|
||||
goto err_peer_del;
|
||||
}
|
||||
|
||||
- ret = ath11k_wmi_pdev_set_ps_mode(ar, arvif->vdev_id, false);
|
||||
+ ret = ath11k_wmi_pdev_set_ps_mode(ar, arvif->vdev_id,
|
||||
+ WMI_STA_PS_MODE_DISABLED);
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab, "failed to disable vdev %d ps mode: %d\n",
|
||||
arvif->vdev_id, ret);
|
||||
--- a/drivers/net/wireless/ath/ath11k/wmi.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
|
||||
@@ -1244,7 +1244,8 @@ int ath11k_wmi_pdev_set_param(struct ath
|
||||
return ret;
|
||||
}
|
||||
|
||||
-int ath11k_wmi_pdev_set_ps_mode(struct ath11k *ar, int vdev_id, u32 enable)
|
||||
+int ath11k_wmi_pdev_set_ps_mode(struct ath11k *ar, int vdev_id,
|
||||
+ enum wmi_sta_ps_mode psmode)
|
||||
{
|
||||
struct ath11k_pdev_wmi *wmi = ar->wmi;
|
||||
struct wmi_pdev_set_ps_mode_cmd *cmd;
|
||||
@@ -1259,7 +1260,7 @@ int ath11k_wmi_pdev_set_ps_mode(struct a
|
||||
cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_STA_POWERSAVE_MODE_CMD) |
|
||||
FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
|
||||
cmd->vdev_id = vdev_id;
|
||||
- cmd->sta_ps_mode = enable;
|
||||
+ cmd->sta_ps_mode = psmode;
|
||||
|
||||
ret = ath11k_wmi_cmd_send(wmi, skb, WMI_STA_POWERSAVE_MODE_CMDID);
|
||||
if (ret) {
|
||||
@@ -1269,7 +1270,7 @@ int ath11k_wmi_pdev_set_ps_mode(struct a
|
||||
|
||||
ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
|
||||
"WMI vdev set psmode %d vdev id %d\n",
|
||||
- enable, vdev_id);
|
||||
+ psmode, vdev_id);
|
||||
|
||||
return ret;
|
||||
}
|
||||
--- a/drivers/net/wireless/ath/ath11k/wmi.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/wmi.h
|
||||
@@ -5351,7 +5351,8 @@ int ath11k_wmi_set_peer_param(struct ath
|
||||
u32 vdev_id, u32 param_id, u32 param_val);
|
||||
int ath11k_wmi_pdev_set_param(struct ath11k *ar, u32 param_id,
|
||||
u32 param_value, u8 pdev_id);
|
||||
-int ath11k_wmi_pdev_set_ps_mode(struct ath11k *ar, int vdev_id, u32 enable);
|
||||
+int ath11k_wmi_pdev_set_ps_mode(struct ath11k *ar, int vdev_id,
|
||||
+ enum wmi_sta_ps_mode psmode);
|
||||
int ath11k_wmi_wait_for_unified_ready(struct ath11k_base *ab);
|
||||
int ath11k_wmi_cmd_init(struct ath11k_base *ab);
|
||||
int ath11k_wmi_wait_for_service_ready(struct ath11k_base *ab);
|
@ -0,0 +1,192 @@
|
||||
From b2beffa7d9a67b59b085616a27f1d10b1e80784f Mon Sep 17 00:00:00 2001
|
||||
From: Carl Huang <cjhuang@codeaurora.org>
|
||||
Date: Mon, 8 Nov 2021 14:38:26 +0200
|
||||
Subject: [PATCH 065/120] ath11k: enable 802.11 power save mode in station mode
|
||||
|
||||
To reduce power consumption enable 802.11 power save mode in station mode. This
|
||||
allows both radio and CPU to sleep more.
|
||||
|
||||
Only enable the mode on QCA6390 and WCN6855, it's unknown how other hardware
|
||||
families support this feature.
|
||||
|
||||
To test that power save mode is running run "iw dev wls1 set power_save off",
|
||||
check there is no NULL Data frame seen by a sniffer. And run "iw dev wls1 set power_save
|
||||
on" and check there is a NULL Data frame in sniffer.
|
||||
|
||||
Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1
|
||||
|
||||
Signed-off-by: Carl Huang <cjhuang@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20211108123826.8463-2-kvalo@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/core.c | 5 ++
|
||||
drivers/net/wireless/ath/ath11k/core.h | 1 +
|
||||
drivers/net/wireless/ath/ath11k/hw.h | 1 +
|
||||
drivers/net/wireless/ath/ath11k/mac.c | 87 ++++++++++++++++++++++++++
|
||||
4 files changed, 94 insertions(+)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/core.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/core.c
|
||||
@@ -76,6 +76,7 @@ static const struct ath11k_hw_params ath
|
||||
.supports_monitor = true,
|
||||
.supports_shadow_regs = false,
|
||||
.idle_ps = false,
|
||||
+ .supports_sta_ps = false,
|
||||
.cold_boot_calib = true,
|
||||
.supports_suspend = false,
|
||||
.hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074),
|
||||
@@ -126,6 +127,7 @@ static const struct ath11k_hw_params ath
|
||||
.supports_monitor = true,
|
||||
.supports_shadow_regs = false,
|
||||
.idle_ps = false,
|
||||
+ .supports_sta_ps = false,
|
||||
.cold_boot_calib = true,
|
||||
.supports_suspend = false,
|
||||
.hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074),
|
||||
@@ -175,6 +177,7 @@ static const struct ath11k_hw_params ath
|
||||
.supports_monitor = false,
|
||||
.supports_shadow_regs = true,
|
||||
.idle_ps = true,
|
||||
+ .supports_sta_ps = true,
|
||||
.cold_boot_calib = false,
|
||||
.supports_suspend = true,
|
||||
.hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074),
|
||||
@@ -224,6 +227,7 @@ static const struct ath11k_hw_params ath
|
||||
.supports_monitor = true,
|
||||
.supports_shadow_regs = false,
|
||||
.idle_ps = false,
|
||||
+ .supports_sta_ps = false,
|
||||
.cold_boot_calib = false,
|
||||
.supports_suspend = false,
|
||||
.hal_desc_sz = sizeof(struct hal_rx_desc_qcn9074),
|
||||
@@ -273,6 +277,7 @@ static const struct ath11k_hw_params ath
|
||||
.supports_monitor = false,
|
||||
.supports_shadow_regs = true,
|
||||
.idle_ps = true,
|
||||
+ .supports_sta_ps = true,
|
||||
.cold_boot_calib = false,
|
||||
.supports_suspend = true,
|
||||
.hal_desc_sz = sizeof(struct hal_rx_desc_wcn6855),
|
||||
--- a/drivers/net/wireless/ath/ath11k/core.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/core.h
|
||||
@@ -240,6 +240,7 @@ struct ath11k_vif {
|
||||
bool is_started;
|
||||
bool is_up;
|
||||
bool spectral_enabled;
|
||||
+ bool ps;
|
||||
u32 aid;
|
||||
u8 bssid[ETH_ALEN];
|
||||
struct cfg80211_bitrate_mask bitrate_mask;
|
||||
--- a/drivers/net/wireless/ath/ath11k/hw.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/hw.h
|
||||
@@ -170,6 +170,7 @@ struct ath11k_hw_params {
|
||||
bool supports_monitor;
|
||||
bool supports_shadow_regs;
|
||||
bool idle_ps;
|
||||
+ bool supports_sta_ps;
|
||||
bool cold_boot_calib;
|
||||
bool supports_suspend;
|
||||
u32 hal_desc_sz;
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -1049,6 +1049,83 @@ static int ath11k_mac_monitor_stop(struc
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int ath11k_mac_vif_setup_ps(struct ath11k_vif *arvif)
|
||||
+{
|
||||
+ struct ath11k *ar = arvif->ar;
|
||||
+ struct ieee80211_vif *vif = arvif->vif;
|
||||
+ struct ieee80211_conf *conf = &ar->hw->conf;
|
||||
+ enum wmi_sta_powersave_param param;
|
||||
+ enum wmi_sta_ps_mode psmode;
|
||||
+ int ret;
|
||||
+ int timeout;
|
||||
+ bool enable_ps;
|
||||
+
|
||||
+ lockdep_assert_held(&arvif->ar->conf_mutex);
|
||||
+
|
||||
+ if (arvif->vif->type != NL80211_IFTYPE_STATION)
|
||||
+ return 0;
|
||||
+
|
||||
+ enable_ps = arvif->ps;
|
||||
+
|
||||
+ if (!arvif->is_started) {
|
||||
+ /* mac80211 can update vif powersave state while disconnected.
|
||||
+ * Firmware doesn't behave nicely and consumes more power than
|
||||
+ * necessary if PS is disabled on a non-started vdev. Hence
|
||||
+ * force-enable PS for non-running vdevs.
|
||||
+ */
|
||||
+ psmode = WMI_STA_PS_MODE_ENABLED;
|
||||
+ } else if (enable_ps) {
|
||||
+ psmode = WMI_STA_PS_MODE_ENABLED;
|
||||
+ param = WMI_STA_PS_PARAM_INACTIVITY_TIME;
|
||||
+
|
||||
+ timeout = conf->dynamic_ps_timeout;
|
||||
+ if (timeout == 0) {
|
||||
+ /* firmware doesn't like 0 */
|
||||
+ timeout = ieee80211_tu_to_usec(vif->bss_conf.beacon_int) / 1000;
|
||||
+ }
|
||||
+
|
||||
+ ret = ath11k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param,
|
||||
+ timeout);
|
||||
+ if (ret) {
|
||||
+ ath11k_warn(ar->ab, "failed to set inactivity time for vdev %d: %i\n",
|
||||
+ arvif->vdev_id, ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+ } else {
|
||||
+ psmode = WMI_STA_PS_MODE_DISABLED;
|
||||
+ }
|
||||
+
|
||||
+ ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac vdev %d psmode %s\n",
|
||||
+ arvif->vdev_id, psmode ? "enable" : "disable");
|
||||
+
|
||||
+ ret = ath11k_wmi_pdev_set_ps_mode(ar, arvif->vdev_id, psmode);
|
||||
+ if (ret) {
|
||||
+ ath11k_warn(ar->ab, "failed to set sta power save mode %d for vdev %d: %d\n",
|
||||
+ psmode, arvif->vdev_id, ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int ath11k_mac_config_ps(struct ath11k *ar)
|
||||
+{
|
||||
+ struct ath11k_vif *arvif;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ lockdep_assert_held(&ar->conf_mutex);
|
||||
+
|
||||
+ list_for_each_entry(arvif, &ar->arvifs, list) {
|
||||
+ ret = ath11k_mac_vif_setup_ps(arvif);
|
||||
+ if (ret) {
|
||||
+ ath11k_warn(ar->ab, "failed to setup powersave: %d\n", ret);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static int ath11k_mac_op_config(struct ieee80211_hw *hw, u32 changed)
|
||||
{
|
||||
struct ath11k *ar = hw->priv;
|
||||
@@ -2942,6 +3019,16 @@ static void ath11k_mac_op_bss_info_chang
|
||||
ath11k_mac_txpower_recalc(ar);
|
||||
}
|
||||
|
||||
+ if (changed & BSS_CHANGED_PS &&
|
||||
+ ar->ab->hw_params.supports_sta_ps) {
|
||||
+ arvif->ps = vif->bss_conf.ps;
|
||||
+
|
||||
+ ret = ath11k_mac_config_ps(ar);
|
||||
+ if (ret)
|
||||
+ ath11k_warn(ar->ab, "failed to setup ps on vdev %i: %d\n",
|
||||
+ arvif->vdev_id, ret);
|
||||
+ }
|
||||
+
|
||||
if (changed & BSS_CHANGED_MCAST_RATE &&
|
||||
!ath11k_mac_vif_chan(arvif->vif, &def)) {
|
||||
band = def.chan->band;
|
@ -0,0 +1,57 @@
|
||||
From 16a2c3d5406f95ef6139de52669c60a39443f5f7 Mon Sep 17 00:00:00 2001
|
||||
From: Rameshkumar Sundaram <ramess@codeaurora.org>
|
||||
Date: Wed, 10 Nov 2021 17:10:48 +0200
|
||||
Subject: [PATCH 066/120] ath11k: Send PPDU_STATS_CFG with proper pdev mask to
|
||||
firmware
|
||||
|
||||
HTT_PPDU_STATS_CFG_PDEV_ID bit mask for target FW PPDU stats request message
|
||||
was set as bit 8 to 15. Bit 8 is reserved for soc stats and pdev id starts from
|
||||
bit 9. Hence change the bitmask as bit 9 to 15 and fill the proper pdev id in
|
||||
the request message.
|
||||
|
||||
In commit 701e48a43e15 ("ath11k: add packet log support for QCA6390"), both
|
||||
HTT_PPDU_STATS_CFG_PDEV_ID and pdev_mask were changed, but this pdev_mask
|
||||
calculation is not valid for platforms which has multiple pdevs with 1 rxdma
|
||||
per pdev, as this is writing same value(i.e. 2) for all pdevs. Hence fixed it
|
||||
to consider pdev_idx as well, to make it compatible for both single and multi
|
||||
pd cases.
|
||||
|
||||
Tested on: IPQ8074 hw2.0 AHB WLAN.HK.2.5.0.1-01092-QCAHKSWPL_SILICONZ-1
|
||||
Tested on: IPQ6018 hw1.0 WLAN.HK.2.5.0.1-01067-QCAHKSWPL_SILICONZ-1
|
||||
|
||||
Fixes: 701e48a43e15 ("ath11k: add packet log support for QCA6390")
|
||||
|
||||
Co-developed-by: Sathishkumar Muruganandam <murugana@codeaurora.org>
|
||||
Signed-off-by: Sathishkumar Muruganandam <murugana@codeaurora.org>
|
||||
Signed-off-by: Rameshkumar Sundaram <ramess@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20210721212029.142388-10-jouni@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/dp.h | 3 ++-
|
||||
drivers/net/wireless/ath/ath11k/dp_tx.c | 2 +-
|
||||
2 files changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp.h
|
||||
@@ -517,7 +517,8 @@ struct htt_ppdu_stats_cfg_cmd {
|
||||
} __packed;
|
||||
|
||||
#define HTT_PPDU_STATS_CFG_MSG_TYPE GENMASK(7, 0)
|
||||
-#define HTT_PPDU_STATS_CFG_PDEV_ID GENMASK(15, 8)
|
||||
+#define HTT_PPDU_STATS_CFG_SOC_STATS BIT(8)
|
||||
+#define HTT_PPDU_STATS_CFG_PDEV_ID GENMASK(15, 9)
|
||||
#define HTT_PPDU_STATS_CFG_TLV_TYPE_BITMASK GENMASK(31, 16)
|
||||
|
||||
enum htt_ppdu_stats_tag_type {
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp_tx.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp_tx.c
|
||||
@@ -903,7 +903,7 @@ int ath11k_dp_tx_htt_h2t_ppdu_stats_req(
|
||||
cmd->msg = FIELD_PREP(HTT_PPDU_STATS_CFG_MSG_TYPE,
|
||||
HTT_H2T_MSG_TYPE_PPDU_STATS_CFG);
|
||||
|
||||
- pdev_mask = 1 << (i + 1);
|
||||
+ pdev_mask = 1 << (ar->pdev_idx + i);
|
||||
cmd->msg |= FIELD_PREP(HTT_PPDU_STATS_CFG_PDEV_ID, pdev_mask);
|
||||
cmd->msg |= FIELD_PREP(HTT_PPDU_STATS_CFG_TLV_TYPE_BITMASK, mask);
|
||||
|
@ -0,0 +1,72 @@
|
||||
From c802b6d7815d7c3f556efea28d0b79ef57ebcfd4 Mon Sep 17 00:00:00 2001
|
||||
From: Rameshkumar Sundaram <quic_ramess@quicinc.com>
|
||||
Date: Mon, 25 Oct 2021 21:33:06 +0530
|
||||
Subject: [PATCH 067/120] ath11k: Clear auth flag only for actual association
|
||||
in security mode
|
||||
|
||||
AUTH flag is needed when peer assoc command is sent from host in
|
||||
security mode for non-assoc cases. Firmware will handle AUTH flag
|
||||
when client is associating as AUTH flag will be set after key exchange.
|
||||
For internally provided peer assoc commands from host, there won't be
|
||||
any key exchange, so AUTH flag is expected to be set in host.
|
||||
|
||||
Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.4.0.1-01838-QCAHKSWPL_SILICONZ-1
|
||||
|
||||
Co-developed-by: Lavanya Suresh <lavaks@codeaurora.org>
|
||||
Signed-off-by: Lavanya Suresh <lavaks@codeaurora.org>
|
||||
Signed-off-by: Rameshkumar Sundaram <quic_ramess@quicinc.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/1635177786-20854-1-git-send-email-quic_ramess@quicinc.com
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/mac.c | 3 +++
|
||||
drivers/net/wireless/ath/ath11k/wmi.c | 2 +-
|
||||
drivers/net/wireless/ath/ath11k/wmi.h | 1 +
|
||||
3 files changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -2495,6 +2495,7 @@ static void ath11k_bss_assoc(struct ieee
|
||||
|
||||
rcu_read_unlock();
|
||||
|
||||
+ peer_arg.is_assoc = true;
|
||||
ret = ath11k_wmi_send_peer_assoc_cmd(ar, &peer_arg);
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab, "failed to run peer assoc for %pM vdev %i: %d\n",
|
||||
@@ -3772,6 +3773,7 @@ static int ath11k_station_assoc(struct a
|
||||
|
||||
ath11k_peer_assoc_prepare(ar, vif, sta, &peer_arg, reassoc);
|
||||
|
||||
+ peer_arg.is_assoc = true;
|
||||
ret = ath11k_wmi_send_peer_assoc_cmd(ar, &peer_arg);
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab, "failed to run peer assoc for STA %pM vdev %i: %d\n",
|
||||
@@ -3983,6 +3985,7 @@ static void ath11k_sta_rc_update_wk(stru
|
||||
ath11k_peer_assoc_prepare(ar, arvif->vif, sta,
|
||||
&peer_arg, true);
|
||||
|
||||
+ peer_arg.is_assoc = false;
|
||||
err = ath11k_wmi_send_peer_assoc_cmd(ar, &peer_arg);
|
||||
if (err)
|
||||
ath11k_warn(ar->ab, "failed to run peer assoc for STA %pM vdev %i: %d\n",
|
||||
--- a/drivers/net/wireless/ath/ath11k/wmi.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
|
||||
@@ -1763,7 +1763,7 @@ 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;
|
||||
- if (!hw_crypto_disabled)
|
||||
+ if (!hw_crypto_disabled && param->is_assoc)
|
||||
cmd->peer_flags &= ~WMI_PEER_AUTH;
|
||||
}
|
||||
if (param->need_gtk_2_way)
|
||||
--- a/drivers/net/wireless/ath/ath11k/wmi.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/wmi.h
|
||||
@@ -3617,6 +3617,7 @@ struct peer_assoc_params {
|
||||
u32 peer_he_tx_mcs_set[WMI_HOST_MAX_HE_RATE_SET];
|
||||
bool twt_responder;
|
||||
bool twt_requester;
|
||||
+ bool is_assoc;
|
||||
struct ath11k_ppe_threshold peer_ppet;
|
||||
};
|
||||
|
@ -0,0 +1,114 @@
|
||||
From 85f36923be47b6990215ad444545a6a85133a0c6 Mon Sep 17 00:00:00 2001
|
||||
From: Karthikeyan Periyasamy <quic_periyasa@quicinc.com>
|
||||
Date: Fri, 12 Nov 2021 10:03:40 +0200
|
||||
Subject: [PATCH 068/120] ath11k: fix fw crash due to peer get authorized
|
||||
before key install
|
||||
|
||||
Firmware expects host to authorize the peer after the successful key
|
||||
install. But host authorize the peer before the key install, this trigger
|
||||
the firmware assert which leads to Q6 crash. To avoid this Q6 crash, host
|
||||
should authorize the peer after the key install. So introduce is_authorized
|
||||
in peer object to identify that peer is authorize or not. When
|
||||
IEEE80211_STA_CONTROL_PORT flag is unset, peer move to authorize state
|
||||
before the vdev up. When the same flag is set then peer move to authorize
|
||||
state after vdev up. So added authorise check in ath11k_bss_assoc() to
|
||||
handle the earlier state transition case. Also added the WMI authorize
|
||||
procedure in ath11k_mac_op_sta_state() to handle the non-earlier state
|
||||
transition case.
|
||||
|
||||
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-01492-QCAHKSWPL_SILICONZ-1
|
||||
|
||||
Signed-off-by: Karthikeyan Periyasamy <quic_periyasa@quicinc.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/1636554200-12345-1-git-send-email-quic_periyasa@quicinc.com
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/mac.c | 53 ++++++++++++++++++++++----
|
||||
drivers/net/wireless/ath/ath11k/peer.h | 1 +
|
||||
2 files changed, 47 insertions(+), 7 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -2474,6 +2474,8 @@ static void ath11k_bss_assoc(struct ieee
|
||||
struct ath11k_vif *arvif = (void *)vif->drv_priv;
|
||||
struct peer_assoc_params peer_arg;
|
||||
struct ieee80211_sta *ap_sta;
|
||||
+ struct ath11k_peer *peer;
|
||||
+ bool is_auth = false;
|
||||
int ret;
|
||||
|
||||
lockdep_assert_held(&ar->conf_mutex);
|
||||
@@ -2536,13 +2538,22 @@ static void ath11k_bss_assoc(struct ieee
|
||||
"mac vdev %d up (associated) bssid %pM aid %d\n",
|
||||
arvif->vdev_id, bss_conf->bssid, bss_conf->aid);
|
||||
|
||||
- /* Authorize BSS Peer */
|
||||
- ret = ath11k_wmi_set_peer_param(ar, arvif->bssid,
|
||||
- arvif->vdev_id,
|
||||
- WMI_PEER_AUTHORIZE,
|
||||
- 1);
|
||||
- if (ret)
|
||||
- ath11k_warn(ar->ab, "Unable to authorize BSS peer: %d\n", ret);
|
||||
+ spin_lock_bh(&ar->ab->base_lock);
|
||||
+
|
||||
+ peer = ath11k_peer_find(ar->ab, arvif->vdev_id, arvif->bssid);
|
||||
+ if (peer && peer->is_authorized)
|
||||
+ is_auth = true;
|
||||
+
|
||||
+ spin_unlock_bh(&ar->ab->base_lock);
|
||||
+
|
||||
+ if (is_auth) {
|
||||
+ ret = ath11k_wmi_set_peer_param(ar, arvif->bssid,
|
||||
+ arvif->vdev_id,
|
||||
+ WMI_PEER_AUTHORIZE,
|
||||
+ 1);
|
||||
+ if (ret)
|
||||
+ ath11k_warn(ar->ab, "Unable to authorize BSS peer: %d\n", ret);
|
||||
+ }
|
||||
|
||||
ret = ath11k_wmi_send_obss_spr_cmd(ar, arvif->vdev_id,
|
||||
&bss_conf->he_obss_pd);
|
||||
@@ -4221,6 +4232,34 @@ static int ath11k_mac_op_sta_state(struc
|
||||
ath11k_warn(ar->ab, "Failed to associate station: %pM\n",
|
||||
sta->addr);
|
||||
} else if (old_state == IEEE80211_STA_ASSOC &&
|
||||
+ new_state == IEEE80211_STA_AUTHORIZED) {
|
||||
+ spin_lock_bh(&ar->ab->base_lock);
|
||||
+
|
||||
+ peer = ath11k_peer_find(ar->ab, arvif->vdev_id, sta->addr);
|
||||
+ if (peer)
|
||||
+ peer->is_authorized = true;
|
||||
+
|
||||
+ spin_unlock_bh(&ar->ab->base_lock);
|
||||
+
|
||||
+ if (vif->type == NL80211_IFTYPE_STATION && arvif->is_up) {
|
||||
+ ret = ath11k_wmi_set_peer_param(ar, sta->addr,
|
||||
+ arvif->vdev_id,
|
||||
+ WMI_PEER_AUTHORIZE,
|
||||
+ 1);
|
||||
+ if (ret)
|
||||
+ ath11k_warn(ar->ab, "Unable to authorize peer %pM vdev %d: %d\n",
|
||||
+ sta->addr, arvif->vdev_id, ret);
|
||||
+ }
|
||||
+ } else if (old_state == IEEE80211_STA_AUTHORIZED &&
|
||||
+ new_state == IEEE80211_STA_ASSOC) {
|
||||
+ spin_lock_bh(&ar->ab->base_lock);
|
||||
+
|
||||
+ peer = ath11k_peer_find(ar->ab, arvif->vdev_id, sta->addr);
|
||||
+ if (peer)
|
||||
+ peer->is_authorized = false;
|
||||
+
|
||||
+ spin_unlock_bh(&ar->ab->base_lock);
|
||||
+ } else if (old_state == IEEE80211_STA_ASSOC &&
|
||||
new_state == IEEE80211_STA_AUTH &&
|
||||
(vif->type == NL80211_IFTYPE_AP ||
|
||||
vif->type == NL80211_IFTYPE_MESH_POINT ||
|
||||
--- a/drivers/net/wireless/ath/ath11k/peer.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/peer.h
|
||||
@@ -28,6 +28,7 @@ struct ath11k_peer {
|
||||
u8 ucast_keyidx;
|
||||
u16 sec_type;
|
||||
u16 sec_type_grp;
|
||||
+ bool is_authorized;
|
||||
};
|
||||
|
||||
void ath11k_peer_unmap_event(struct ath11k_base *ab, u16 peer_id);
|
@ -0,0 +1,60 @@
|
||||
From 4ea03443ecdac6920eb7aa3a9da2cd0b8cc6dfc8 Mon Sep 17 00:00:00 2001
|
||||
From: Karthikeyan Periyasamy <quic_periyasa@quicinc.com>
|
||||
Date: Wed, 10 Nov 2021 21:05:57 +0530
|
||||
Subject: [PATCH 069/120] ath11k: fix error routine when fallback of add
|
||||
interface fails
|
||||
|
||||
When there is an error in add interface process from
|
||||
ath11k_mac_set_kickout(), the code attempts to handle a
|
||||
fallback for add_interface. When this fallback succeeds, the
|
||||
driver returns zero rather than error code. This leads to
|
||||
success for the non created VAP. In cleanup, driver gets
|
||||
remove interface callback for the non created VAP and
|
||||
proceeds to self peer delete request which leads to FW assert.
|
||||
Since it was already deleted on the fallback of add interface,
|
||||
return the actual error code instead of fallback return code.
|
||||
|
||||
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.5.0.1-00729-QCAHKSWPL_SILICONZ-3 v2
|
||||
|
||||
Signed-off-by: Karthikeyan Periyasamy <quic_periyasa@quicinc.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/1636558557-2874-1-git-send-email-quic_periyasa@quicinc.com
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/mac.c | 14 +++++++-------
|
||||
1 file changed, 7 insertions(+), 7 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -5613,7 +5613,7 @@ static int ath11k_mac_op_add_interface(s
|
||||
u32 param_id, param_value;
|
||||
u16 nss;
|
||||
int i;
|
||||
- int ret;
|
||||
+ int ret, fbret;
|
||||
int bit;
|
||||
|
||||
vif->driver_flags |= IEEE80211_VIF_SUPPORTS_UAPSD;
|
||||
@@ -5816,17 +5816,17 @@ err_peer_del:
|
||||
if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
|
||||
reinit_completion(&ar->peer_delete_done);
|
||||
|
||||
- ret = ath11k_wmi_send_peer_delete_cmd(ar, vif->addr,
|
||||
- arvif->vdev_id);
|
||||
- if (ret) {
|
||||
+ fbret = ath11k_wmi_send_peer_delete_cmd(ar, vif->addr,
|
||||
+ arvif->vdev_id);
|
||||
+ if (fbret) {
|
||||
ath11k_warn(ar->ab, "failed to delete peer vdev_id %d addr %pM\n",
|
||||
arvif->vdev_id, vif->addr);
|
||||
goto err;
|
||||
}
|
||||
|
||||
- ret = ath11k_wait_for_peer_delete_done(ar, arvif->vdev_id,
|
||||
- vif->addr);
|
||||
- if (ret)
|
||||
+ fbret = ath11k_wait_for_peer_delete_done(ar, arvif->vdev_id,
|
||||
+ vif->addr);
|
||||
+ if (fbret)
|
||||
goto err;
|
||||
|
||||
ar->num_peers--;
|
@ -0,0 +1,57 @@
|
||||
From 4c375743c5fe1ef84d1dd7269dd12585957f403e Mon Sep 17 00:00:00 2001
|
||||
From: Karthikeyan Periyasamy <quic_periyasa@quicinc.com>
|
||||
Date: Wed, 10 Nov 2021 21:36:28 +0530
|
||||
Subject: [PATCH 070/120] ath11k: avoid unnecessary BH disable lock in STA
|
||||
kickout event
|
||||
|
||||
In STA kickout event processing, the peer object is protected
|
||||
under spin lock BH. Release this lock after picking up the vdev_id
|
||||
from the peer object instead after ieee80211_report_low_ack().
|
||||
This will minimize the lock hold period which will improve
|
||||
performance since base_lock is used across the data path.
|
||||
This was found in code review.
|
||||
|
||||
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.5.0.1-00729-QCAHKSWPL_SILICONZ-3 v2
|
||||
|
||||
Signed-off-by: Karthikeyan Periyasamy <quic_periyasa@quicinc.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/1636560388-24955-1-git-send-email-quic_periyasa@quicinc.com
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/wmi.c | 9 +++++++--
|
||||
1 file changed, 7 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/wmi.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
|
||||
@@ -6399,6 +6399,7 @@ static void ath11k_peer_sta_kickout_even
|
||||
struct ieee80211_sta *sta;
|
||||
struct ath11k_peer *peer;
|
||||
struct ath11k *ar;
|
||||
+ u32 vdev_id;
|
||||
|
||||
if (ath11k_pull_peer_sta_kickout_ev(ab, skb, &arg) != 0) {
|
||||
ath11k_warn(ab, "failed to extract peer sta kickout event");
|
||||
@@ -6414,10 +6415,15 @@ static void ath11k_peer_sta_kickout_even
|
||||
if (!peer) {
|
||||
ath11k_warn(ab, "peer not found %pM\n",
|
||||
arg.mac_addr);
|
||||
+ spin_unlock_bh(&ab->base_lock);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
- ar = ath11k_mac_get_ar_by_vdev_id(ab, peer->vdev_id);
|
||||
+ vdev_id = peer->vdev_id;
|
||||
+
|
||||
+ spin_unlock_bh(&ab->base_lock);
|
||||
+
|
||||
+ ar = ath11k_mac_get_ar_by_vdev_id(ab, vdev_id);
|
||||
if (!ar) {
|
||||
ath11k_warn(ab, "invalid vdev id in peer sta kickout ev %d",
|
||||
peer->vdev_id);
|
||||
@@ -6438,7 +6444,6 @@ static void ath11k_peer_sta_kickout_even
|
||||
ieee80211_report_low_ack(sta, 10);
|
||||
|
||||
exit:
|
||||
- spin_unlock_bh(&ab->base_lock);
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
@ -0,0 +1,74 @@
|
||||
From 31aeaf547d7e3b64ba5d5442dabc530bdb9e216e Mon Sep 17 00:00:00 2001
|
||||
From: Karthikeyan Periyasamy <quic_periyasa@quicinc.com>
|
||||
Date: Wed, 10 Nov 2021 21:51:30 +0530
|
||||
Subject: [PATCH 071/120] ath11k: fix DMA memory free in CE pipe cleanup
|
||||
|
||||
In CE pipe cleanup, DMA memory gets freed by the aligned address
|
||||
(base_addr_owner_space) which is wrong. It needs to be freed
|
||||
by the address (base_addr_owner_space_unaligned) returned by
|
||||
dma_alloc. So free the dma memory by the proper address.
|
||||
This was found in code review.
|
||||
|
||||
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.5.0.1-00729-QCAHKSWPL_SILICONZ-3 v2
|
||||
|
||||
Signed-off-by: Karthikeyan Periyasamy <quic_periyasa@quicinc.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/1636561290-18966-1-git-send-email-quic_periyasa@quicinc.com
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/ce.c | 16 ++++++++++------
|
||||
1 file changed, 10 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/ce.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/ce.c
|
||||
@@ -953,6 +953,7 @@ int ath11k_ce_init_pipes(struct ath11k_b
|
||||
void ath11k_ce_free_pipes(struct ath11k_base *ab)
|
||||
{
|
||||
struct ath11k_ce_pipe *pipe;
|
||||
+ struct ath11k_ce_ring *ce_ring;
|
||||
int desc_sz;
|
||||
int i;
|
||||
|
||||
@@ -964,22 +965,24 @@ void ath11k_ce_free_pipes(struct ath11k_
|
||||
|
||||
if (pipe->src_ring) {
|
||||
desc_sz = ath11k_hal_ce_get_desc_size(HAL_CE_DESC_SRC);
|
||||
+ ce_ring = pipe->src_ring;
|
||||
dma_free_coherent(ab->dev,
|
||||
pipe->src_ring->nentries * desc_sz +
|
||||
CE_DESC_RING_ALIGN,
|
||||
- pipe->src_ring->base_addr_owner_space,
|
||||
- pipe->src_ring->base_addr_ce_space);
|
||||
+ ce_ring->base_addr_owner_space_unaligned,
|
||||
+ ce_ring->base_addr_ce_space_unaligned);
|
||||
kfree(pipe->src_ring);
|
||||
pipe->src_ring = NULL;
|
||||
}
|
||||
|
||||
if (pipe->dest_ring) {
|
||||
desc_sz = ath11k_hal_ce_get_desc_size(HAL_CE_DESC_DST);
|
||||
+ ce_ring = pipe->dest_ring;
|
||||
dma_free_coherent(ab->dev,
|
||||
pipe->dest_ring->nentries * desc_sz +
|
||||
CE_DESC_RING_ALIGN,
|
||||
- pipe->dest_ring->base_addr_owner_space,
|
||||
- pipe->dest_ring->base_addr_ce_space);
|
||||
+ ce_ring->base_addr_owner_space_unaligned,
|
||||
+ ce_ring->base_addr_ce_space_unaligned);
|
||||
kfree(pipe->dest_ring);
|
||||
pipe->dest_ring = NULL;
|
||||
}
|
||||
@@ -987,11 +990,12 @@ void ath11k_ce_free_pipes(struct ath11k_
|
||||
if (pipe->status_ring) {
|
||||
desc_sz =
|
||||
ath11k_hal_ce_get_desc_size(HAL_CE_DESC_DST_STATUS);
|
||||
+ ce_ring = pipe->status_ring;
|
||||
dma_free_coherent(ab->dev,
|
||||
pipe->status_ring->nentries * desc_sz +
|
||||
CE_DESC_RING_ALIGN,
|
||||
- pipe->status_ring->base_addr_owner_space,
|
||||
- pipe->status_ring->base_addr_ce_space);
|
||||
+ ce_ring->base_addr_owner_space_unaligned,
|
||||
+ ce_ring->base_addr_ce_space_unaligned);
|
||||
kfree(pipe->status_ring);
|
||||
pipe->status_ring = NULL;
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
From 624e0a3170309eeb5b729f7a43c1ba3234325f02 Mon Sep 17 00:00:00 2001
|
||||
From: Seevalamuthu Mariappan <quic_seevalam@quicinc.com>
|
||||
Date: Thu, 11 Nov 2021 11:22:47 +0530
|
||||
Subject: [PATCH 072/120] ath11k: Fix 'unused-but-set-parameter' error
|
||||
|
||||
Below compilation error is reported when built with W=1,
|
||||
|
||||
drivers/net/wireless/ath/ath11k/mac.c:5408:22: error: parameter 'changed_flags' set but not used [-Werror,-Wunused-but-set-parameter]
|
||||
|
||||
changed_flags is set, but left unused. So, remove unnecessary set.
|
||||
Compile tested only.
|
||||
|
||||
Reported-by: kernel test robot <lkp@intel.com>
|
||||
Signed-off-by: Seevalamuthu Mariappan <quic_seevalam@quicinc.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/1636609967-5114-1-git-send-email-quic_seevalam@quicinc.com
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/mac.c | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -5961,7 +5961,6 @@ static void ath11k_mac_op_configure_filt
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
|
||||
- changed_flags &= SUPPORTED_FILTERS;
|
||||
*total_flags &= SUPPORTED_FILTERS;
|
||||
ar->filter_flags = *total_flags;
|
||||
|
@ -0,0 +1,65 @@
|
||||
From f187fe8e3bc65cc4d7b0916947e2d6cd65d9cd3a Mon Sep 17 00:00:00 2001
|
||||
From: Venkateswara Naralasetty <quic_vnaralas@quicinc.com>
|
||||
Date: Thu, 11 Nov 2021 20:50:02 +0530
|
||||
Subject: [PATCH 073/120] ath11k: fix firmware crash during channel switch
|
||||
|
||||
Currently the updated bandwidth for the peer will be configured
|
||||
to the firmware after channel switch from the sta_rc_update_wk.
|
||||
If the updated bandwidth is greater than the configured peer phymode
|
||||
during the peer assoc may result firmware assert.
|
||||
|
||||
For example, initially AP is in HE40 mode and the peer phymode is
|
||||
configured as MODE_11AX_HE40 during peer assoc. Now user change the
|
||||
channel width to HE80 then, the peer bandwidth will be updated as
|
||||
HE80 to the firmware.
|
||||
|
||||
This will trigger firmware assert due to peer bandwidth is greater than
|
||||
the peer phymode.
|
||||
|
||||
Fix this issue by sending peer assoc command before setting the updated
|
||||
peer bandwith to firmware.
|
||||
|
||||
Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.5.0.1-01100-QCAHKSWPL_SILICONZ-1
|
||||
|
||||
Signed-off-by: Venkateswara Naralasetty <quic_vnaralas@quicinc.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/1636644002-25446-1-git-send-email-quic_vnaralas@quicinc.com
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/mac.c | 26 +++++++++++++++++++++-----
|
||||
1 file changed, 21 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -3924,11 +3924,27 @@ static void ath11k_sta_rc_update_wk(stru
|
||||
ath11k_mac_max_he_nss(he_mcs_mask)));
|
||||
|
||||
if (changed & IEEE80211_RC_BW_CHANGED) {
|
||||
- err = ath11k_wmi_set_peer_param(ar, sta->addr, arvif->vdev_id,
|
||||
- WMI_PEER_CHWIDTH, bw);
|
||||
- if (err)
|
||||
- ath11k_warn(ar->ab, "failed to update STA %pM peer bw %d: %d\n",
|
||||
- sta->addr, bw, err);
|
||||
+ /* Send peer assoc command before set peer bandwidth param to
|
||||
+ * avoid the mismatch between the peer phymode and the peer
|
||||
+ * bandwidth.
|
||||
+ */
|
||||
+ ath11k_peer_assoc_prepare(ar, arvif->vif, sta, &peer_arg, true);
|
||||
+
|
||||
+ peer_arg.is_assoc = false;
|
||||
+ err = ath11k_wmi_send_peer_assoc_cmd(ar, &peer_arg);
|
||||
+ if (err) {
|
||||
+ ath11k_warn(ar->ab, "failed to send peer assoc for STA %pM vdev %i: %d\n",
|
||||
+ sta->addr, arvif->vdev_id, err);
|
||||
+ } else if (wait_for_completion_timeout(&ar->peer_assoc_done, 1 * HZ)) {
|
||||
+ err = ath11k_wmi_set_peer_param(ar, sta->addr, arvif->vdev_id,
|
||||
+ WMI_PEER_CHWIDTH, bw);
|
||||
+ if (err)
|
||||
+ ath11k_warn(ar->ab, "failed to update STA %pM peer bw %d: %d\n",
|
||||
+ sta->addr, bw, err);
|
||||
+ } else {
|
||||
+ ath11k_warn(ar->ab, "failed to get peer assoc conf event for %pM vdev %i\n",
|
||||
+ sta->addr, arvif->vdev_id);
|
||||
+ }
|
||||
}
|
||||
|
||||
if (changed & IEEE80211_RC_NSS_CHANGED) {
|
@ -0,0 +1,38 @@
|
||||
From 2c5545bfa29dd5305fa770959890a23ea39b5e69 Mon Sep 17 00:00:00 2001
|
||||
From: P Praneesh <ppranees@codeaurora.org>
|
||||
Date: Fri, 12 Nov 2021 11:01:18 +0200
|
||||
Subject: [PATCH 074/120] ath11k: disable unused CE8 interrupts for ipq8074
|
||||
|
||||
Host driver doesn't need to process CE8 interrupts (used
|
||||
by target independently)
|
||||
|
||||
The volume of interrupts is huge within short interval,
|
||||
CPU0 CPU1 CPU2 CPU3
|
||||
14022188 0 0 0 GIC 71 Edge ce8
|
||||
|
||||
Hence disabling unused CE8 interrupt will improve CPU usage.
|
||||
|
||||
Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.4.0.1.r2-00012-QCAHKSWPL_SILICONZ-1
|
||||
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-01695-QCAHKSWPL_SILICONZ-1
|
||||
|
||||
Co-developed-by: Sriram R <srirrama@codeaurora.org>
|
||||
Signed-off-by: Sriram R <srirrama@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: P Praneesh <ppranees@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/1630560820-21905-2-git-send-email-ppranees@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/ce.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/ce.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/ce.c
|
||||
@@ -77,7 +77,7 @@ const struct ce_attr ath11k_host_ce_conf
|
||||
|
||||
/* CE8: target autonomous hif_memcpy */
|
||||
{
|
||||
- .flags = CE_ATTR_FLAGS,
|
||||
+ .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR,
|
||||
.src_nentries = 0,
|
||||
.src_sz_max = 0,
|
||||
.dest_nentries = 0,
|
@ -0,0 +1,228 @@
|
||||
From 6452f0a3d5651bb7edfd9c709e78973aaa4d3bfc Mon Sep 17 00:00:00 2001
|
||||
From: P Praneesh <ppranees@codeaurora.org>
|
||||
Date: Fri, 12 Nov 2021 11:01:26 +0200
|
||||
Subject: [PATCH 075/120] ath11k: allocate dst ring descriptors from cacheable
|
||||
memory
|
||||
|
||||
tcl_data and reo_dst rings are currently being allocated using
|
||||
dma_allocate_coherent() which is non cacheable.
|
||||
|
||||
Allocating ring memory from cacheable memory area allows cached descriptor
|
||||
access and prefetch next descriptors to optimize CPU usage during
|
||||
descriptor processing on NAPI. Based on the hardware param we can enable
|
||||
or disable this feature for the corresponding platform.
|
||||
|
||||
Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.4.0.1.r2-00012-QCAHKSWPL_SILICONZ-1
|
||||
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-01695-QCAHKSWPL_SILICONZ-1
|
||||
|
||||
Co-developed-by: Pradeep Kumar Chitrapu <pradeepc@codeaurora.org>
|
||||
Signed-off-by: Pradeep Kumar Chitrapu <pradeepc@codeaurora.org>
|
||||
Co-developed-by: Sriram R <srirrama@codeaurora.org>
|
||||
Signed-off-by: Sriram R <srirrama@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: P Praneesh <ppranees@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/1630560820-21905-3-git-send-email-ppranees@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/core.c | 5 ++++
|
||||
drivers/net/wireless/ath/ath11k/dp.c | 38 ++++++++++++++++++++++----
|
||||
drivers/net/wireless/ath/ath11k/dp.h | 1 +
|
||||
drivers/net/wireless/ath/ath11k/hal.c | 28 +++++++++++++++++--
|
||||
drivers/net/wireless/ath/ath11k/hal.h | 1 +
|
||||
drivers/net/wireless/ath/ath11k/hw.h | 1 +
|
||||
6 files changed, 67 insertions(+), 7 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/core.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/core.c
|
||||
@@ -84,6 +84,7 @@ static const struct ath11k_hw_params ath
|
||||
.max_tx_ring = DP_TCL_NUM_RING_MAX,
|
||||
.hal_params = &ath11k_hw_hal_params_ipq8074,
|
||||
.supports_dynamic_smps_6ghz = false,
|
||||
+ .alloc_cacheable_memory = true,
|
||||
},
|
||||
{
|
||||
.hw_rev = ATH11K_HW_IPQ6018_HW10,
|
||||
@@ -135,6 +136,7 @@ static const struct ath11k_hw_params ath
|
||||
.max_tx_ring = DP_TCL_NUM_RING_MAX,
|
||||
.hal_params = &ath11k_hw_hal_params_ipq8074,
|
||||
.supports_dynamic_smps_6ghz = false,
|
||||
+ .alloc_cacheable_memory = true,
|
||||
},
|
||||
{
|
||||
.name = "qca6390 hw2.0",
|
||||
@@ -185,6 +187,7 @@ static const struct ath11k_hw_params ath
|
||||
.max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390,
|
||||
.hal_params = &ath11k_hw_hal_params_qca6390,
|
||||
.supports_dynamic_smps_6ghz = false,
|
||||
+ .alloc_cacheable_memory = false,
|
||||
},
|
||||
{
|
||||
.name = "qcn9074 hw1.0",
|
||||
@@ -235,6 +238,7 @@ static const struct ath11k_hw_params ath
|
||||
.max_tx_ring = DP_TCL_NUM_RING_MAX,
|
||||
.hal_params = &ath11k_hw_hal_params_ipq8074,
|
||||
.supports_dynamic_smps_6ghz = true,
|
||||
+ .alloc_cacheable_memory = true,
|
||||
},
|
||||
{
|
||||
.name = "wcn6855 hw2.0",
|
||||
@@ -285,6 +289,7 @@ static const struct ath11k_hw_params ath
|
||||
.max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390,
|
||||
.hal_params = &ath11k_hw_hal_params_qca6390,
|
||||
.supports_dynamic_smps_6ghz = false,
|
||||
+ .alloc_cacheable_memory = false,
|
||||
},
|
||||
};
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp.c
|
||||
@@ -101,8 +101,11 @@ void ath11k_dp_srng_cleanup(struct ath11
|
||||
if (!ring->vaddr_unaligned)
|
||||
return;
|
||||
|
||||
- dma_free_coherent(ab->dev, ring->size, ring->vaddr_unaligned,
|
||||
- ring->paddr_unaligned);
|
||||
+ if (ring->cached)
|
||||
+ kfree(ring->vaddr_unaligned);
|
||||
+ else
|
||||
+ dma_free_coherent(ab->dev, ring->size, ring->vaddr_unaligned,
|
||||
+ ring->paddr_unaligned);
|
||||
|
||||
ring->vaddr_unaligned = NULL;
|
||||
}
|
||||
@@ -222,6 +225,7 @@ int ath11k_dp_srng_setup(struct ath11k_b
|
||||
int entry_sz = ath11k_hal_srng_get_entrysize(ab, type);
|
||||
int max_entries = ath11k_hal_srng_get_max_entries(ab, type);
|
||||
int ret;
|
||||
+ bool cached = false;
|
||||
|
||||
if (max_entries < 0 || entry_sz < 0)
|
||||
return -EINVAL;
|
||||
@@ -230,9 +234,28 @@ int ath11k_dp_srng_setup(struct ath11k_b
|
||||
num_entries = max_entries;
|
||||
|
||||
ring->size = (num_entries * entry_sz) + HAL_RING_BASE_ALIGN - 1;
|
||||
- ring->vaddr_unaligned = dma_alloc_coherent(ab->dev, ring->size,
|
||||
- &ring->paddr_unaligned,
|
||||
- GFP_KERNEL);
|
||||
+
|
||||
+ if (ab->hw_params.alloc_cacheable_memory) {
|
||||
+ /* Allocate the reo dst and tx completion rings from cacheable memory */
|
||||
+ switch (type) {
|
||||
+ case HAL_REO_DST:
|
||||
+ cached = true;
|
||||
+ break;
|
||||
+ default:
|
||||
+ cached = false;
|
||||
+ }
|
||||
+
|
||||
+ if (cached) {
|
||||
+ ring->vaddr_unaligned = kzalloc(ring->size, GFP_KERNEL);
|
||||
+ ring->paddr_unaligned = virt_to_phys(ring->vaddr_unaligned);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (!cached)
|
||||
+ ring->vaddr_unaligned = dma_alloc_coherent(ab->dev, ring->size,
|
||||
+ &ring->paddr_unaligned,
|
||||
+ GFP_KERNEL);
|
||||
+
|
||||
if (!ring->vaddr_unaligned)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -292,6 +315,11 @@ int ath11k_dp_srng_setup(struct ath11k_b
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
+ if (cached) {
|
||||
+ params.flags |= HAL_SRNG_FLAGS_CACHED;
|
||||
+ ring->cached = 1;
|
||||
+ }
|
||||
+
|
||||
ret = ath11k_hal_srng_setup(ab, type, ring_num, mac_id, ¶ms);
|
||||
if (ret < 0) {
|
||||
ath11k_warn(ab, "failed to setup srng: %d ring_id %d\n",
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp.h
|
||||
@@ -64,6 +64,7 @@ struct dp_srng {
|
||||
dma_addr_t paddr;
|
||||
int size;
|
||||
u32 ring_id;
|
||||
+ u8 cached;
|
||||
};
|
||||
|
||||
struct dp_rxdma_ring {
|
||||
--- a/drivers/net/wireless/ath/ath11k/hal.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/hal.c
|
||||
@@ -627,6 +627,21 @@ u32 *ath11k_hal_srng_dst_peek(struct ath
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+static void ath11k_hal_srng_prefetch_desc(struct ath11k_base *ab,
|
||||
+ struct hal_srng *srng)
|
||||
+{
|
||||
+ u32 *desc;
|
||||
+
|
||||
+ /* prefetch only if desc is available */
|
||||
+ desc = ath11k_hal_srng_dst_peek(ab, srng);
|
||||
+ if (likely(desc)) {
|
||||
+ dma_sync_single_for_cpu(ab->dev, virt_to_phys(desc),
|
||||
+ (srng->entry_size * sizeof(u32)),
|
||||
+ DMA_FROM_DEVICE);
|
||||
+ prefetch(desc);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
u32 *ath11k_hal_srng_dst_get_next_entry(struct ath11k_base *ab,
|
||||
struct hal_srng *srng)
|
||||
{
|
||||
@@ -642,6 +657,10 @@ u32 *ath11k_hal_srng_dst_get_next_entry(
|
||||
srng->u.dst_ring.tp = (srng->u.dst_ring.tp + srng->entry_size) %
|
||||
srng->ring_size;
|
||||
|
||||
+ /* Try to prefetch the next descriptor in the ring */
|
||||
+ if (srng->flags & HAL_SRNG_FLAGS_CACHED)
|
||||
+ ath11k_hal_srng_prefetch_desc(ab, srng);
|
||||
+
|
||||
return desc;
|
||||
}
|
||||
|
||||
@@ -775,11 +794,16 @@ void ath11k_hal_srng_access_begin(struct
|
||||
{
|
||||
lockdep_assert_held(&srng->lock);
|
||||
|
||||
- if (srng->ring_dir == HAL_SRNG_DIR_SRC)
|
||||
+ if (srng->ring_dir == HAL_SRNG_DIR_SRC) {
|
||||
srng->u.src_ring.cached_tp =
|
||||
*(volatile u32 *)srng->u.src_ring.tp_addr;
|
||||
- else
|
||||
+ } else {
|
||||
srng->u.dst_ring.cached_hp = *srng->u.dst_ring.hp_addr;
|
||||
+
|
||||
+ /* Try to prefetch the next descriptor in the ring */
|
||||
+ if (srng->flags & HAL_SRNG_FLAGS_CACHED)
|
||||
+ ath11k_hal_srng_prefetch_desc(ab, srng);
|
||||
+ }
|
||||
}
|
||||
|
||||
/* Update cached ring head/tail pointers to HW. ath11k_hal_srng_access_begin()
|
||||
--- a/drivers/net/wireless/ath/ath11k/hal.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/hal.h
|
||||
@@ -513,6 +513,7 @@ enum hal_srng_dir {
|
||||
#define HAL_SRNG_FLAGS_DATA_TLV_SWAP 0x00000020
|
||||
#define HAL_SRNG_FLAGS_LOW_THRESH_INTR_EN 0x00010000
|
||||
#define HAL_SRNG_FLAGS_MSI_INTR 0x00020000
|
||||
+#define HAL_SRNG_FLAGS_CACHED 0x20000000
|
||||
#define HAL_SRNG_FLAGS_LMAC_RING 0x80000000
|
||||
|
||||
#define HAL_SRNG_TLV_HDR_TAG GENMASK(9, 1)
|
||||
--- a/drivers/net/wireless/ath/ath11k/hw.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/hw.h
|
||||
@@ -178,6 +178,7 @@ struct ath11k_hw_params {
|
||||
u8 max_tx_ring;
|
||||
const struct ath11k_hw_hal_params *hal_params;
|
||||
bool supports_dynamic_smps_6ghz;
|
||||
+ bool alloc_cacheable_memory;
|
||||
};
|
||||
|
||||
struct ath11k_hw_ops {
|
@ -0,0 +1,285 @@
|
||||
From 5e76fe03dbf9f9dbc4fd454283b02594226c0718 Mon Sep 17 00:00:00 2001
|
||||
From: P Praneesh <ppranees@codeaurora.org>
|
||||
Date: Fri, 12 Nov 2021 11:02:03 +0200
|
||||
Subject: [PATCH 076/120] ath11k: modify dp_rx desc access wrapper calls inline
|
||||
|
||||
In data path, to reduce the CPU cycles spending on descriptor access
|
||||
wrapper function, changed those functions as static inline.
|
||||
|
||||
Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.4.0.1.r2-00012-QCAHKSWPL_SILICONZ-1
|
||||
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-01695-QCAHKSWPL_SILICONZ-1
|
||||
|
||||
Co-developed-by: Sriram R <srirrama@codeaurora.org>
|
||||
Signed-off-by: Sriram R <srirrama@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: P Praneesh <ppranees@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/1630560820-21905-4-git-send-email-ppranees@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/dp_rx.c | 114 ++++++++++++------------
|
||||
1 file changed, 59 insertions(+), 55 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
|
||||
@@ -20,13 +20,15 @@
|
||||
|
||||
#define ATH11K_DP_RX_FRAGMENT_TIMEOUT_MS (2 * HZ)
|
||||
|
||||
-static u8 *ath11k_dp_rx_h_80211_hdr(struct ath11k_base *ab, struct hal_rx_desc *desc)
|
||||
+static inline
|
||||
+u8 *ath11k_dp_rx_h_80211_hdr(struct ath11k_base *ab, struct hal_rx_desc *desc)
|
||||
{
|
||||
return ab->hw_params.hw_ops->rx_desc_get_hdr_status(desc);
|
||||
}
|
||||
|
||||
-static enum hal_encrypt_type ath11k_dp_rx_h_mpdu_start_enctype(struct ath11k_base *ab,
|
||||
- struct hal_rx_desc *desc)
|
||||
+static inline
|
||||
+enum hal_encrypt_type ath11k_dp_rx_h_mpdu_start_enctype(struct ath11k_base *ab,
|
||||
+ struct hal_rx_desc *desc)
|
||||
{
|
||||
if (!ab->hw_params.hw_ops->rx_desc_encrypt_valid(desc))
|
||||
return HAL_ENCRYPT_TYPE_OPEN;
|
||||
@@ -34,32 +36,34 @@ static enum hal_encrypt_type ath11k_dp_r
|
||||
return ab->hw_params.hw_ops->rx_desc_get_encrypt_type(desc);
|
||||
}
|
||||
|
||||
-static u8 ath11k_dp_rx_h_msdu_start_decap_type(struct ath11k_base *ab,
|
||||
- struct hal_rx_desc *desc)
|
||||
+static inline u8 ath11k_dp_rx_h_msdu_start_decap_type(struct ath11k_base *ab,
|
||||
+ struct hal_rx_desc *desc)
|
||||
{
|
||||
return ab->hw_params.hw_ops->rx_desc_get_decap_type(desc);
|
||||
}
|
||||
|
||||
-static u8 ath11k_dp_rx_h_msdu_start_mesh_ctl_present(struct ath11k_base *ab,
|
||||
- struct hal_rx_desc *desc)
|
||||
+static inline
|
||||
+u8 ath11k_dp_rx_h_msdu_start_mesh_ctl_present(struct ath11k_base *ab,
|
||||
+ struct hal_rx_desc *desc)
|
||||
{
|
||||
return ab->hw_params.hw_ops->rx_desc_get_mesh_ctl(desc);
|
||||
}
|
||||
|
||||
-static bool ath11k_dp_rx_h_mpdu_start_seq_ctrl_valid(struct ath11k_base *ab,
|
||||
- struct hal_rx_desc *desc)
|
||||
+static inline
|
||||
+bool ath11k_dp_rx_h_mpdu_start_seq_ctrl_valid(struct ath11k_base *ab,
|
||||
+ struct hal_rx_desc *desc)
|
||||
{
|
||||
return ab->hw_params.hw_ops->rx_desc_get_mpdu_seq_ctl_vld(desc);
|
||||
}
|
||||
|
||||
-static bool ath11k_dp_rx_h_mpdu_start_fc_valid(struct ath11k_base *ab,
|
||||
- struct hal_rx_desc *desc)
|
||||
+static inline bool ath11k_dp_rx_h_mpdu_start_fc_valid(struct ath11k_base *ab,
|
||||
+ struct hal_rx_desc *desc)
|
||||
{
|
||||
return ab->hw_params.hw_ops->rx_desc_get_mpdu_fc_valid(desc);
|
||||
}
|
||||
|
||||
-static bool ath11k_dp_rx_h_mpdu_start_more_frags(struct ath11k_base *ab,
|
||||
- struct sk_buff *skb)
|
||||
+static inline bool ath11k_dp_rx_h_mpdu_start_more_frags(struct ath11k_base *ab,
|
||||
+ struct sk_buff *skb)
|
||||
{
|
||||
struct ieee80211_hdr *hdr;
|
||||
|
||||
@@ -67,8 +71,8 @@ static bool ath11k_dp_rx_h_mpdu_start_mo
|
||||
return ieee80211_has_morefrags(hdr->frame_control);
|
||||
}
|
||||
|
||||
-static u16 ath11k_dp_rx_h_mpdu_start_frag_no(struct ath11k_base *ab,
|
||||
- struct sk_buff *skb)
|
||||
+static inline u16 ath11k_dp_rx_h_mpdu_start_frag_no(struct ath11k_base *ab,
|
||||
+ struct sk_buff *skb)
|
||||
{
|
||||
struct ieee80211_hdr *hdr;
|
||||
|
||||
@@ -76,37 +80,37 @@ static u16 ath11k_dp_rx_h_mpdu_start_fra
|
||||
return le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG;
|
||||
}
|
||||
|
||||
-static u16 ath11k_dp_rx_h_mpdu_start_seq_no(struct ath11k_base *ab,
|
||||
- struct hal_rx_desc *desc)
|
||||
+static inline u16 ath11k_dp_rx_h_mpdu_start_seq_no(struct ath11k_base *ab,
|
||||
+ struct hal_rx_desc *desc)
|
||||
{
|
||||
return ab->hw_params.hw_ops->rx_desc_get_mpdu_start_seq_no(desc);
|
||||
}
|
||||
|
||||
-static void *ath11k_dp_rx_get_attention(struct ath11k_base *ab,
|
||||
- struct hal_rx_desc *desc)
|
||||
+static inline void *ath11k_dp_rx_get_attention(struct ath11k_base *ab,
|
||||
+ struct hal_rx_desc *desc)
|
||||
{
|
||||
return ab->hw_params.hw_ops->rx_desc_get_attention(desc);
|
||||
}
|
||||
|
||||
-static bool ath11k_dp_rx_h_attn_msdu_done(struct rx_attention *attn)
|
||||
+static inline bool ath11k_dp_rx_h_attn_msdu_done(struct rx_attention *attn)
|
||||
{
|
||||
return !!FIELD_GET(RX_ATTENTION_INFO2_MSDU_DONE,
|
||||
__le32_to_cpu(attn->info2));
|
||||
}
|
||||
|
||||
-static bool ath11k_dp_rx_h_attn_l4_cksum_fail(struct rx_attention *attn)
|
||||
+static inline bool ath11k_dp_rx_h_attn_l4_cksum_fail(struct rx_attention *attn)
|
||||
{
|
||||
return !!FIELD_GET(RX_ATTENTION_INFO1_TCP_UDP_CKSUM_FAIL,
|
||||
__le32_to_cpu(attn->info1));
|
||||
}
|
||||
|
||||
-static bool ath11k_dp_rx_h_attn_ip_cksum_fail(struct rx_attention *attn)
|
||||
+static inline bool ath11k_dp_rx_h_attn_ip_cksum_fail(struct rx_attention *attn)
|
||||
{
|
||||
return !!FIELD_GET(RX_ATTENTION_INFO1_IP_CKSUM_FAIL,
|
||||
__le32_to_cpu(attn->info1));
|
||||
}
|
||||
|
||||
-static bool ath11k_dp_rx_h_attn_is_decrypted(struct rx_attention *attn)
|
||||
+static inline bool ath11k_dp_rx_h_attn_is_decrypted(struct rx_attention *attn)
|
||||
{
|
||||
return (FIELD_GET(RX_ATTENTION_INFO2_DCRYPT_STATUS_CODE,
|
||||
__le32_to_cpu(attn->info2)) ==
|
||||
@@ -154,68 +158,68 @@ static bool ath11k_dp_rx_h_attn_msdu_len
|
||||
return errmap & DP_RX_MPDU_ERR_MSDU_LEN;
|
||||
}
|
||||
|
||||
-static u16 ath11k_dp_rx_h_msdu_start_msdu_len(struct ath11k_base *ab,
|
||||
- struct hal_rx_desc *desc)
|
||||
+static inline u16 ath11k_dp_rx_h_msdu_start_msdu_len(struct ath11k_base *ab,
|
||||
+ struct hal_rx_desc *desc)
|
||||
{
|
||||
return ab->hw_params.hw_ops->rx_desc_get_msdu_len(desc);
|
||||
}
|
||||
|
||||
-static u8 ath11k_dp_rx_h_msdu_start_sgi(struct ath11k_base *ab,
|
||||
- struct hal_rx_desc *desc)
|
||||
+static inline u8 ath11k_dp_rx_h_msdu_start_sgi(struct ath11k_base *ab,
|
||||
+ struct hal_rx_desc *desc)
|
||||
{
|
||||
return ab->hw_params.hw_ops->rx_desc_get_msdu_sgi(desc);
|
||||
}
|
||||
|
||||
-static u8 ath11k_dp_rx_h_msdu_start_rate_mcs(struct ath11k_base *ab,
|
||||
- struct hal_rx_desc *desc)
|
||||
+static inline u8 ath11k_dp_rx_h_msdu_start_rate_mcs(struct ath11k_base *ab,
|
||||
+ struct hal_rx_desc *desc)
|
||||
{
|
||||
return ab->hw_params.hw_ops->rx_desc_get_msdu_rate_mcs(desc);
|
||||
}
|
||||
|
||||
-static u8 ath11k_dp_rx_h_msdu_start_rx_bw(struct ath11k_base *ab,
|
||||
- struct hal_rx_desc *desc)
|
||||
+static inline u8 ath11k_dp_rx_h_msdu_start_rx_bw(struct ath11k_base *ab,
|
||||
+ struct hal_rx_desc *desc)
|
||||
{
|
||||
return ab->hw_params.hw_ops->rx_desc_get_msdu_rx_bw(desc);
|
||||
}
|
||||
|
||||
-static u32 ath11k_dp_rx_h_msdu_start_freq(struct ath11k_base *ab,
|
||||
- struct hal_rx_desc *desc)
|
||||
+static inline u32 ath11k_dp_rx_h_msdu_start_freq(struct ath11k_base *ab,
|
||||
+ struct hal_rx_desc *desc)
|
||||
{
|
||||
return ab->hw_params.hw_ops->rx_desc_get_msdu_freq(desc);
|
||||
}
|
||||
|
||||
-static u8 ath11k_dp_rx_h_msdu_start_pkt_type(struct ath11k_base *ab,
|
||||
- struct hal_rx_desc *desc)
|
||||
+static inline u8 ath11k_dp_rx_h_msdu_start_pkt_type(struct ath11k_base *ab,
|
||||
+ struct hal_rx_desc *desc)
|
||||
{
|
||||
return ab->hw_params.hw_ops->rx_desc_get_msdu_pkt_type(desc);
|
||||
}
|
||||
|
||||
-static u8 ath11k_dp_rx_h_msdu_start_nss(struct ath11k_base *ab,
|
||||
- struct hal_rx_desc *desc)
|
||||
+static inline u8 ath11k_dp_rx_h_msdu_start_nss(struct ath11k_base *ab,
|
||||
+ struct hal_rx_desc *desc)
|
||||
{
|
||||
return hweight8(ab->hw_params.hw_ops->rx_desc_get_msdu_nss(desc));
|
||||
}
|
||||
|
||||
-static u8 ath11k_dp_rx_h_mpdu_start_tid(struct ath11k_base *ab,
|
||||
- struct hal_rx_desc *desc)
|
||||
+static inline u8 ath11k_dp_rx_h_mpdu_start_tid(struct ath11k_base *ab,
|
||||
+ struct hal_rx_desc *desc)
|
||||
{
|
||||
return ab->hw_params.hw_ops->rx_desc_get_mpdu_tid(desc);
|
||||
}
|
||||
|
||||
-static u16 ath11k_dp_rx_h_mpdu_start_peer_id(struct ath11k_base *ab,
|
||||
- struct hal_rx_desc *desc)
|
||||
+static inline u16 ath11k_dp_rx_h_mpdu_start_peer_id(struct ath11k_base *ab,
|
||||
+ struct hal_rx_desc *desc)
|
||||
{
|
||||
return ab->hw_params.hw_ops->rx_desc_get_mpdu_peer_id(desc);
|
||||
}
|
||||
|
||||
-static u8 ath11k_dp_rx_h_msdu_end_l3pad(struct ath11k_base *ab,
|
||||
- struct hal_rx_desc *desc)
|
||||
+static inline u8 ath11k_dp_rx_h_msdu_end_l3pad(struct ath11k_base *ab,
|
||||
+ struct hal_rx_desc *desc)
|
||||
{
|
||||
return ab->hw_params.hw_ops->rx_desc_get_l3_pad_bytes(desc);
|
||||
}
|
||||
|
||||
-static bool ath11k_dp_rx_h_msdu_end_first_msdu(struct ath11k_base *ab,
|
||||
- struct hal_rx_desc *desc)
|
||||
+static inline bool ath11k_dp_rx_h_msdu_end_first_msdu(struct ath11k_base *ab,
|
||||
+ struct hal_rx_desc *desc)
|
||||
{
|
||||
return ab->hw_params.hw_ops->rx_desc_get_first_msdu(desc);
|
||||
}
|
||||
@@ -233,14 +237,14 @@ static void ath11k_dp_rx_desc_end_tlv_co
|
||||
ab->hw_params.hw_ops->rx_desc_copy_attn_end_tlv(fdesc, ldesc);
|
||||
}
|
||||
|
||||
-static u32 ath11k_dp_rxdesc_get_mpdulen_err(struct rx_attention *attn)
|
||||
+static inline u32 ath11k_dp_rxdesc_get_mpdulen_err(struct rx_attention *attn)
|
||||
{
|
||||
return FIELD_GET(RX_ATTENTION_INFO1_MPDU_LEN_ERR,
|
||||
__le32_to_cpu(attn->info1));
|
||||
}
|
||||
|
||||
-static u8 *ath11k_dp_rxdesc_get_80211hdr(struct ath11k_base *ab,
|
||||
- struct hal_rx_desc *rx_desc)
|
||||
+static inline u8 *ath11k_dp_rxdesc_get_80211hdr(struct ath11k_base *ab,
|
||||
+ struct hal_rx_desc *rx_desc)
|
||||
{
|
||||
u8 *rx_pkt_hdr;
|
||||
|
||||
@@ -249,8 +253,8 @@ static u8 *ath11k_dp_rxdesc_get_80211hdr
|
||||
return rx_pkt_hdr;
|
||||
}
|
||||
|
||||
-static bool ath11k_dp_rxdesc_mpdu_valid(struct ath11k_base *ab,
|
||||
- struct hal_rx_desc *rx_desc)
|
||||
+static inline bool ath11k_dp_rxdesc_mpdu_valid(struct ath11k_base *ab,
|
||||
+ struct hal_rx_desc *rx_desc)
|
||||
{
|
||||
u32 tlv_tag;
|
||||
|
||||
@@ -259,15 +263,15 @@ static bool ath11k_dp_rxdesc_mpdu_valid(
|
||||
return tlv_tag == HAL_RX_MPDU_START;
|
||||
}
|
||||
|
||||
-static u32 ath11k_dp_rxdesc_get_ppduid(struct ath11k_base *ab,
|
||||
- struct hal_rx_desc *rx_desc)
|
||||
+static inline u32 ath11k_dp_rxdesc_get_ppduid(struct ath11k_base *ab,
|
||||
+ struct hal_rx_desc *rx_desc)
|
||||
{
|
||||
return ab->hw_params.hw_ops->rx_desc_get_mpdu_ppdu_id(rx_desc);
|
||||
}
|
||||
|
||||
-static void ath11k_dp_rxdesc_set_msdu_len(struct ath11k_base *ab,
|
||||
- struct hal_rx_desc *desc,
|
||||
- u16 len)
|
||||
+static inline void ath11k_dp_rxdesc_set_msdu_len(struct ath11k_base *ab,
|
||||
+ struct hal_rx_desc *desc,
|
||||
+ u16 len)
|
||||
{
|
||||
ab->hw_params.hw_ops->rx_desc_set_msdu_len(desc, len);
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
From a1775e732eb90486519de3813b83a11b7fcee2d0 Mon Sep 17 00:00:00 2001
|
||||
From: P Praneesh <ppranees@codeaurora.org>
|
||||
Date: Fri, 12 Nov 2021 11:02:12 +0200
|
||||
Subject: [PATCH 077/120] ath11k: avoid additional access to
|
||||
ath11k_hal_srng_dst_num_free
|
||||
|
||||
In ath11k_dp_process_rx(), after processing rx_desc from
|
||||
ath11k_hal_srng_dst_get_next_entry(), ath11k_hal_srng_dst_num_free()
|
||||
is accessed everytime because of done flag is not set.
|
||||
|
||||
To avoid this additional access to ath11k_hal_srng_dst_num_free(),
|
||||
increment total_msdu_reaped only when continuation is not set and
|
||||
update done flag correspondingly.
|
||||
|
||||
Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.4.0.1.r2-00012-QCAHKSWPL_SILICONZ-1
|
||||
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-01695-QCAHKSWPL_SILICONZ-1
|
||||
|
||||
Co-developed-by: Sriram R <srirrama@codeaurora.org>
|
||||
Signed-off-by: Sriram R <srirrama@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: P Praneesh <ppranees@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/1630560820-21905-5-git-send-email-ppranees@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/dp_rx.c | 10 +++++++---
|
||||
1 file changed, 7 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
|
||||
@@ -2701,7 +2701,6 @@ try_again:
|
||||
DMA_FROM_DEVICE);
|
||||
|
||||
num_buffs_reaped[mac_id]++;
|
||||
- total_msdu_reaped++;
|
||||
|
||||
push_reason = FIELD_GET(HAL_REO_DEST_RING_INFO0_PUSH_REASON,
|
||||
desc.info0);
|
||||
@@ -2728,10 +2727,15 @@ try_again:
|
||||
rxcb->mac_id = mac_id;
|
||||
__skb_queue_tail(&msdu_list, msdu);
|
||||
|
||||
- if (total_msdu_reaped >= quota && !rxcb->is_continuation) {
|
||||
+ if (rxcb->is_continuation) {
|
||||
+ done = false;
|
||||
+ } else {
|
||||
+ total_msdu_reaped++;
|
||||
done = true;
|
||||
- break;
|
||||
}
|
||||
+
|
||||
+ if (total_msdu_reaped >= budget)
|
||||
+ break;
|
||||
}
|
||||
|
||||
/* Hw might have updated the head pointer after we cached it.
|
@ -0,0 +1,174 @@
|
||||
From c4d12cb37ea2e6c2b70880350d7bf1bbbd825c6c Mon Sep 17 00:00:00 2001
|
||||
From: P Praneesh <ppranees@codeaurora.org>
|
||||
Date: Fri, 12 Nov 2021 11:02:18 +0200
|
||||
Subject: [PATCH 078/120] ath11k: avoid active pdev check for each msdu
|
||||
|
||||
The Active Pdev and CAC check are done for each msdu in
|
||||
ath11k_dp_rx_process_received_packets which is a overhead.
|
||||
To avoid this overhead, collect all msdus in a per mac msdu
|
||||
list and pass to function.
|
||||
|
||||
Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.4.0.1.r2-00012-QCAHKSWPL_SILICONZ-1
|
||||
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-01695-QCAHKSWPL_SILICONZ-1
|
||||
|
||||
Co-developed-by: Sriram R <srirrama@codeaurora.org>
|
||||
Signed-off-by: Sriram R <srirrama@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: P Praneesh <ppranees@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/1630560820-21905-6-git-send-email-ppranees@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/dp_rx.c | 70 ++++++++++++-------------
|
||||
1 file changed, 34 insertions(+), 36 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
|
||||
@@ -2600,13 +2600,11 @@ free_out:
|
||||
static void ath11k_dp_rx_process_received_packets(struct ath11k_base *ab,
|
||||
struct napi_struct *napi,
|
||||
struct sk_buff_head *msdu_list,
|
||||
- int *quota, int ring_id)
|
||||
+ int *quota, int mac_id)
|
||||
{
|
||||
- struct ath11k_skb_rxcb *rxcb;
|
||||
struct sk_buff *msdu;
|
||||
struct ath11k *ar;
|
||||
struct ieee80211_rx_status rx_status = {0};
|
||||
- u8 mac_id;
|
||||
int ret;
|
||||
|
||||
if (skb_queue_empty(msdu_list))
|
||||
@@ -2614,20 +2612,20 @@ static void ath11k_dp_rx_process_receive
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
- while (*quota && (msdu = __skb_dequeue(msdu_list))) {
|
||||
- rxcb = ATH11K_SKB_RXCB(msdu);
|
||||
- mac_id = rxcb->mac_id;
|
||||
- ar = ab->pdevs[mac_id].ar;
|
||||
- if (!rcu_dereference(ab->pdevs_active[mac_id])) {
|
||||
- dev_kfree_skb_any(msdu);
|
||||
- continue;
|
||||
- }
|
||||
+ ar = ab->pdevs[mac_id].ar;
|
||||
+ if (!rcu_dereference(ab->pdevs_active[mac_id])) {
|
||||
+ __skb_queue_purge(msdu_list);
|
||||
+ rcu_read_unlock();
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
- if (test_bit(ATH11K_CAC_RUNNING, &ar->dev_flags)) {
|
||||
- dev_kfree_skb_any(msdu);
|
||||
- continue;
|
||||
- }
|
||||
+ if (test_bit(ATH11K_CAC_RUNNING, &ar->dev_flags)) {
|
||||
+ __skb_queue_purge(msdu_list);
|
||||
+ rcu_read_unlock();
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
+ while ((msdu = __skb_dequeue(msdu_list))) {
|
||||
ret = ath11k_dp_rx_process_msdu(ar, msdu, msdu_list, &rx_status);
|
||||
if (ret) {
|
||||
ath11k_dbg(ab, ATH11K_DBG_DATA,
|
||||
@@ -2649,7 +2647,7 @@ int ath11k_dp_process_rx(struct ath11k_b
|
||||
struct ath11k_dp *dp = &ab->dp;
|
||||
struct dp_rxdma_ring *rx_ring;
|
||||
int num_buffs_reaped[MAX_RADIOS] = {0};
|
||||
- struct sk_buff_head msdu_list;
|
||||
+ struct sk_buff_head msdu_list[MAX_RADIOS];
|
||||
struct ath11k_skb_rxcb *rxcb;
|
||||
int total_msdu_reaped = 0;
|
||||
struct hal_srng *srng;
|
||||
@@ -2658,10 +2656,13 @@ int ath11k_dp_process_rx(struct ath11k_b
|
||||
bool done = false;
|
||||
int buf_id, mac_id;
|
||||
struct ath11k *ar;
|
||||
- u32 *rx_desc;
|
||||
+ struct hal_reo_dest_ring *desc;
|
||||
+ enum hal_reo_dest_ring_push_reason push_reason;
|
||||
+ u32 cookie;
|
||||
int i;
|
||||
|
||||
- __skb_queue_head_init(&msdu_list);
|
||||
+ for (i = 0; i < MAX_RADIOS; i++)
|
||||
+ __skb_queue_head_init(&msdu_list[i]);
|
||||
|
||||
srng = &ab->hal.srng_list[dp->reo_dst_ring[ring_id].ring_id];
|
||||
|
||||
@@ -2670,13 +2671,11 @@ int ath11k_dp_process_rx(struct ath11k_b
|
||||
ath11k_hal_srng_access_begin(ab, srng);
|
||||
|
||||
try_again:
|
||||
- while ((rx_desc = ath11k_hal_srng_dst_get_next_entry(ab, srng))) {
|
||||
- struct hal_reo_dest_ring desc = *(struct hal_reo_dest_ring *)rx_desc;
|
||||
- enum hal_reo_dest_ring_push_reason push_reason;
|
||||
- u32 cookie;
|
||||
-
|
||||
+ while (likely(desc =
|
||||
+ (struct hal_reo_dest_ring *)ath11k_hal_srng_dst_get_next_entry(ab,
|
||||
+ srng))) {
|
||||
cookie = FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE,
|
||||
- desc.buf_addr_info.info1);
|
||||
+ desc->buf_addr_info.info1);
|
||||
buf_id = FIELD_GET(DP_RXDMA_BUF_COOKIE_BUF_ID,
|
||||
cookie);
|
||||
mac_id = FIELD_GET(DP_RXDMA_BUF_COOKIE_PDEV_ID, cookie);
|
||||
@@ -2703,7 +2702,7 @@ try_again:
|
||||
num_buffs_reaped[mac_id]++;
|
||||
|
||||
push_reason = FIELD_GET(HAL_REO_DEST_RING_INFO0_PUSH_REASON,
|
||||
- desc.info0);
|
||||
+ desc->info0);
|
||||
if (push_reason !=
|
||||
HAL_REO_DEST_RING_PUSH_REASON_ROUTING_INSTRUCTION) {
|
||||
dev_kfree_skb_any(msdu);
|
||||
@@ -2711,21 +2710,21 @@ try_again:
|
||||
continue;
|
||||
}
|
||||
|
||||
- rxcb->is_first_msdu = !!(desc.rx_msdu_info.info0 &
|
||||
+ rxcb->is_first_msdu = !!(desc->rx_msdu_info.info0 &
|
||||
RX_MSDU_DESC_INFO0_FIRST_MSDU_IN_MPDU);
|
||||
- rxcb->is_last_msdu = !!(desc.rx_msdu_info.info0 &
|
||||
+ rxcb->is_last_msdu = !!(desc->rx_msdu_info.info0 &
|
||||
RX_MSDU_DESC_INFO0_LAST_MSDU_IN_MPDU);
|
||||
- rxcb->is_continuation = !!(desc.rx_msdu_info.info0 &
|
||||
+ rxcb->is_continuation = !!(desc->rx_msdu_info.info0 &
|
||||
RX_MSDU_DESC_INFO0_MSDU_CONTINUATION);
|
||||
rxcb->peer_id = FIELD_GET(RX_MPDU_DESC_META_DATA_PEER_ID,
|
||||
- desc.rx_mpdu_info.meta_data);
|
||||
+ desc->rx_mpdu_info.meta_data);
|
||||
rxcb->seq_no = FIELD_GET(RX_MPDU_DESC_INFO0_SEQ_NUM,
|
||||
- desc.rx_mpdu_info.info0);
|
||||
+ desc->rx_mpdu_info.info0);
|
||||
rxcb->tid = FIELD_GET(HAL_REO_DEST_RING_INFO0_RX_QUEUE_NUM,
|
||||
- desc.info0);
|
||||
+ desc->info0);
|
||||
|
||||
rxcb->mac_id = mac_id;
|
||||
- __skb_queue_tail(&msdu_list, msdu);
|
||||
+ __skb_queue_tail(&msdu_list[mac_id], msdu);
|
||||
|
||||
if (rxcb->is_continuation) {
|
||||
done = false;
|
||||
@@ -2760,16 +2759,15 @@ try_again:
|
||||
if (!num_buffs_reaped[i])
|
||||
continue;
|
||||
|
||||
+ ath11k_dp_rx_process_received_packets(ab, napi, &msdu_list[i],
|
||||
+ "a, i);
|
||||
+
|
||||
ar = ab->pdevs[i].ar;
|
||||
rx_ring = &ar->dp.rx_refill_buf_ring;
|
||||
|
||||
ath11k_dp_rxbufs_replenish(ab, i, rx_ring, num_buffs_reaped[i],
|
||||
ab->hw_params.hal_params->rx_buf_rbm);
|
||||
}
|
||||
-
|
||||
- ath11k_dp_rx_process_received_packets(ab, napi, &msdu_list,
|
||||
- "a, ring_id);
|
||||
-
|
||||
exit:
|
||||
return budget - quota;
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
From db2ecf9f0567a8f1a96f23a392cc5a30eaec4369 Mon Sep 17 00:00:00 2001
|
||||
From: P Praneesh <ppranees@codeaurora.org>
|
||||
Date: Fri, 12 Nov 2021 11:02:24 +0200
|
||||
Subject: [PATCH 079/120] ath11k: remove usage quota while processing rx
|
||||
packets
|
||||
|
||||
The usage of quota variable inside ath11k_dp_rx_process_received_packets()
|
||||
is redundant. Since we would queue only max packets to the list before
|
||||
calling this function so it would never exceed quota. Hence removing
|
||||
usage of quota variable.
|
||||
|
||||
Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.4.0.1.r2-00012-QCAHKSWPL_SILICONZ-1
|
||||
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-01695-QCAHKSWPL_SILICONZ-1
|
||||
|
||||
Co-developed-by: Sriram R <srirrama@codeaurora.org>
|
||||
Signed-off-by: Sriram R <srirrama@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: P Praneesh <ppranees@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/1630560820-21905-7-git-send-email-ppranees@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/dp_rx.c | 9 +++------
|
||||
1 file changed, 3 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
|
||||
@@ -2600,7 +2600,7 @@ free_out:
|
||||
static void ath11k_dp_rx_process_received_packets(struct ath11k_base *ab,
|
||||
struct napi_struct *napi,
|
||||
struct sk_buff_head *msdu_list,
|
||||
- int *quota, int mac_id)
|
||||
+ int mac_id)
|
||||
{
|
||||
struct sk_buff *msdu;
|
||||
struct ath11k *ar;
|
||||
@@ -2635,7 +2635,6 @@ static void ath11k_dp_rx_process_receive
|
||||
}
|
||||
|
||||
ath11k_dp_rx_deliver_msdu(ar, napi, msdu, &rx_status);
|
||||
- (*quota)--;
|
||||
}
|
||||
|
||||
rcu_read_unlock();
|
||||
@@ -2652,7 +2651,6 @@ int ath11k_dp_process_rx(struct ath11k_b
|
||||
int total_msdu_reaped = 0;
|
||||
struct hal_srng *srng;
|
||||
struct sk_buff *msdu;
|
||||
- int quota = budget;
|
||||
bool done = false;
|
||||
int buf_id, mac_id;
|
||||
struct ath11k *ar;
|
||||
@@ -2759,8 +2757,7 @@ try_again:
|
||||
if (!num_buffs_reaped[i])
|
||||
continue;
|
||||
|
||||
- ath11k_dp_rx_process_received_packets(ab, napi, &msdu_list[i],
|
||||
- "a, i);
|
||||
+ ath11k_dp_rx_process_received_packets(ab, napi, &msdu_list[i], i);
|
||||
|
||||
ar = ab->pdevs[i].ar;
|
||||
rx_ring = &ar->dp.rx_refill_buf_ring;
|
||||
@@ -2769,7 +2766,7 @@ try_again:
|
||||
ab->hw_params.hal_params->rx_buf_rbm);
|
||||
}
|
||||
exit:
|
||||
- return budget - quota;
|
||||
+ return total_msdu_reaped;
|
||||
}
|
||||
|
||||
static void ath11k_dp_rx_update_peer_stats(struct ath11k_sta *arsta,
|
@ -0,0 +1,102 @@
|
||||
From 400588039a17a460292eb974ebba5811b8cbdb91 Mon Sep 17 00:00:00 2001
|
||||
From: P Praneesh <ppranees@codeaurora.org>
|
||||
Date: Fri, 12 Nov 2021 11:02:31 +0200
|
||||
Subject: [PATCH 080/120] ath11k: add branch predictors in process_rx
|
||||
|
||||
In datapath, add branch predictors where required in the process rx().
|
||||
This protects high value rx path without having performance overhead.
|
||||
Also while processing rx packets, the pointer that is returned by
|
||||
rcu_dereference() is not dereferenced. so it is preferable to use
|
||||
rcu_access_pointer() here.
|
||||
|
||||
Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.4.0.1.r2-00012-QCAHKSWPL_SILICONZ-1
|
||||
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-01695-QCAHKSWPL_SILICONZ-1
|
||||
|
||||
Co-developed-by: Sriram R <srirrama@codeaurora.org>
|
||||
Signed-off-by: Sriram R <srirrama@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: P Praneesh <ppranees@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/1630560820-21905-8-git-send-email-ppranees@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/dp_rx.c | 24 +++++++++---------------
|
||||
1 file changed, 9 insertions(+), 15 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
|
||||
@@ -2610,24 +2610,20 @@ static void ath11k_dp_rx_process_receive
|
||||
if (skb_queue_empty(msdu_list))
|
||||
return;
|
||||
|
||||
- rcu_read_lock();
|
||||
-
|
||||
- ar = ab->pdevs[mac_id].ar;
|
||||
- if (!rcu_dereference(ab->pdevs_active[mac_id])) {
|
||||
+ if (unlikely(!rcu_access_pointer(ab->pdevs_active[mac_id]))) {
|
||||
__skb_queue_purge(msdu_list);
|
||||
- rcu_read_unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
- if (test_bit(ATH11K_CAC_RUNNING, &ar->dev_flags)) {
|
||||
+ ar = ab->pdevs[mac_id].ar;
|
||||
+ if (unlikely(test_bit(ATH11K_CAC_RUNNING, &ar->dev_flags))) {
|
||||
__skb_queue_purge(msdu_list);
|
||||
- rcu_read_unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
while ((msdu = __skb_dequeue(msdu_list))) {
|
||||
ret = ath11k_dp_rx_process_msdu(ar, msdu, msdu_list, &rx_status);
|
||||
- if (ret) {
|
||||
+ if (unlikely(ret)) {
|
||||
ath11k_dbg(ab, ATH11K_DBG_DATA,
|
||||
"Unable to process msdu %d", ret);
|
||||
dev_kfree_skb_any(msdu);
|
||||
@@ -2636,8 +2632,6 @@ static void ath11k_dp_rx_process_receive
|
||||
|
||||
ath11k_dp_rx_deliver_msdu(ar, napi, msdu, &rx_status);
|
||||
}
|
||||
-
|
||||
- rcu_read_unlock();
|
||||
}
|
||||
|
||||
int ath11k_dp_process_rx(struct ath11k_base *ab, int ring_id,
|
||||
@@ -2682,7 +2676,7 @@ try_again:
|
||||
rx_ring = &ar->dp.rx_refill_buf_ring;
|
||||
spin_lock_bh(&rx_ring->idr_lock);
|
||||
msdu = idr_find(&rx_ring->bufs_idr, buf_id);
|
||||
- if (!msdu) {
|
||||
+ if (unlikely(!msdu)) {
|
||||
ath11k_warn(ab, "frame rx with invalid buf_id %d\n",
|
||||
buf_id);
|
||||
spin_unlock_bh(&rx_ring->idr_lock);
|
||||
@@ -2701,8 +2695,8 @@ try_again:
|
||||
|
||||
push_reason = FIELD_GET(HAL_REO_DEST_RING_INFO0_PUSH_REASON,
|
||||
desc->info0);
|
||||
- if (push_reason !=
|
||||
- HAL_REO_DEST_RING_PUSH_REASON_ROUTING_INSTRUCTION) {
|
||||
+ if (unlikely(push_reason !=
|
||||
+ HAL_REO_DEST_RING_PUSH_REASON_ROUTING_INSTRUCTION)) {
|
||||
dev_kfree_skb_any(msdu);
|
||||
ab->soc_stats.hal_reo_error[dp->reo_dst_ring[ring_id].ring_id]++;
|
||||
continue;
|
||||
@@ -2741,7 +2735,7 @@ try_again:
|
||||
* head pointer so that we can reap complete MPDU in the current
|
||||
* rx processing.
|
||||
*/
|
||||
- if (!done && ath11k_hal_srng_dst_num_free(ab, srng, true)) {
|
||||
+ if (unlikely(!done && ath11k_hal_srng_dst_num_free(ab, srng, true))) {
|
||||
ath11k_hal_srng_access_end(ab, srng);
|
||||
goto try_again;
|
||||
}
|
||||
@@ -2750,7 +2744,7 @@ try_again:
|
||||
|
||||
spin_unlock_bh(&srng->lock);
|
||||
|
||||
- if (!total_msdu_reaped)
|
||||
+ if (unlikely(!total_msdu_reaped))
|
||||
goto exit;
|
||||
|
||||
for (i = 0; i < ab->num_radios; i++) {
|
@ -0,0 +1,32 @@
|
||||
From d0e2523bfa9cb391fe966b0b6948c7e438981361 Mon Sep 17 00:00:00 2001
|
||||
From: P Praneesh <ppranees@codeaurora.org>
|
||||
Date: Fri, 12 Nov 2021 11:02:38 +0200
|
||||
Subject: [PATCH 081/120] ath11k: allocate HAL_WBM2SW_RELEASE ring from
|
||||
cacheable memory
|
||||
|
||||
Similar to REO destination ring, also allocate HAL_WBM2SW_RELEASE
|
||||
from cacheable memory so that descriptors could be prefetched during
|
||||
tx completion handling.
|
||||
|
||||
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-01734-QCAHKSWPL_SILICONZ-1 v2
|
||||
|
||||
Co-developed-by: Sriram R <srirrama@codeaurora.org>
|
||||
Signed-off-by: Sriram R <srirrama@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: P Praneesh <ppranees@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/1630560820-21905-9-git-send-email-ppranees@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/dp.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp.c
|
||||
@@ -239,6 +239,7 @@ int ath11k_dp_srng_setup(struct ath11k_b
|
||||
/* Allocate the reo dst and tx completion rings from cacheable memory */
|
||||
switch (type) {
|
||||
case HAL_REO_DST:
|
||||
+ case HAL_WBM2SW_RELEASE:
|
||||
cached = true;
|
||||
break;
|
||||
default:
|
@ -0,0 +1,36 @@
|
||||
From a8508bf7ced2e43f30b46333f09cbc79a1675616 Mon Sep 17 00:00:00 2001
|
||||
From: P Praneesh <ppranees@codeaurora.org>
|
||||
Date: Fri, 12 Nov 2021 11:02:45 +0200
|
||||
Subject: [PATCH 082/120] ath11k: remove mod operator in dst ring processing
|
||||
|
||||
Replace use of mod operator with a manual wrap around
|
||||
to avoid additional cost of using mod operation.
|
||||
|
||||
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-01734-QCAHKSWPL_SILICONZ-1 v2
|
||||
|
||||
Co-developed-by: Sriram R <srirrama@codeaurora.org>
|
||||
Signed-off-by: Sriram R <srirrama@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: P Praneesh <ppranees@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/1630560820-21905-10-git-send-email-ppranees@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/hal.c | 7 +++++--
|
||||
1 file changed, 5 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/hal.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/hal.c
|
||||
@@ -654,8 +654,11 @@ u32 *ath11k_hal_srng_dst_get_next_entry(
|
||||
|
||||
desc = srng->ring_base_vaddr + srng->u.dst_ring.tp;
|
||||
|
||||
- srng->u.dst_ring.tp = (srng->u.dst_ring.tp + srng->entry_size) %
|
||||
- srng->ring_size;
|
||||
+ srng->u.dst_ring.tp += srng->entry_size;
|
||||
+
|
||||
+ /* wrap around to start of ring*/
|
||||
+ if (srng->u.dst_ring.tp == srng->ring_size)
|
||||
+ srng->u.dst_ring.tp = 0;
|
||||
|
||||
/* Try to prefetch the next descriptor in the ring */
|
||||
if (srng->flags & HAL_SRNG_FLAGS_CACHED)
|
@ -0,0 +1,43 @@
|
||||
From cbfbed495d3289d5a0bc7c614cea639008086cfe Mon Sep 17 00:00:00 2001
|
||||
From: P Praneesh <ppranees@codeaurora.org>
|
||||
Date: Fri, 12 Nov 2021 11:05:58 +0200
|
||||
Subject: [PATCH 083/120] ath11k: avoid while loop in ring selection of tx
|
||||
completion interrupt
|
||||
|
||||
Currently while loop is used to find the tx completion ring number and
|
||||
it is not required since the tx ring mask and the group id can be combined
|
||||
to directly fetch the ring number. Hence remove the while loop
|
||||
and directly get the ring number from tx mask and group id.
|
||||
|
||||
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-01734-QCAHKSWPL_SILICONZ-1 v2
|
||||
|
||||
Co-developed-by: Sriram R <srirrama@codeaurora.org>
|
||||
Signed-off-by: Sriram R <srirrama@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: P Praneesh <ppranees@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/1630560820-21905-11-git-send-email-ppranees@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/dp.c | 9 ++++-----
|
||||
1 file changed, 4 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp.c
|
||||
@@ -771,13 +771,12 @@ int ath11k_dp_service_srng(struct ath11k
|
||||
const struct ath11k_hw_hal_params *hal_params;
|
||||
int grp_id = irq_grp->grp_id;
|
||||
int work_done = 0;
|
||||
- int i = 0, j;
|
||||
+ int i, j;
|
||||
int tot_work_done = 0;
|
||||
|
||||
- while (ab->hw_params.ring_mask->tx[grp_id] >> i) {
|
||||
- if (ab->hw_params.ring_mask->tx[grp_id] & BIT(i))
|
||||
- ath11k_dp_tx_completion_handler(ab, i);
|
||||
- i++;
|
||||
+ if (ab->hw_params.ring_mask->tx[grp_id]) {
|
||||
+ i = __fls(ab->hw_params.ring_mask->tx[grp_id]);
|
||||
+ ath11k_dp_tx_completion_handler(ab, i);
|
||||
}
|
||||
|
||||
if (ab->hw_params.ring_mask->rx_err[grp_id]) {
|
@ -0,0 +1,201 @@
|
||||
From bcef57ea400cc20a5389fa0e38d61063331558f8 Mon Sep 17 00:00:00 2001
|
||||
From: P Praneesh <ppranees@codeaurora.org>
|
||||
Date: Fri, 12 Nov 2021 11:06:04 +0200
|
||||
Subject: [PATCH 084/120] ath11k: add branch predictors in dp_tx path
|
||||
|
||||
Add branch prediction in dp_tx code path in tx and tx completion handlers.
|
||||
Also in ath11k_dp_tx_complete_msdu , the pointer that is returned by
|
||||
rcu_dereference() is not dereferenced. so it is preferable to use
|
||||
rcu_access_pointer() here.
|
||||
|
||||
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-01734-QCAHKSWPL_SILICONZ-1 v2
|
||||
|
||||
Co-developed-by: Sriram R <srirrama@codeaurora.org>
|
||||
Signed-off-by: Sriram R <srirrama@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: P Praneesh <ppranees@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/1630560820-21905-12-git-send-email-ppranees@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/dp_tx.c | 52 ++++++++++++-------------
|
||||
drivers/net/wireless/ath/ath11k/mac.c | 2 +-
|
||||
2 files changed, 25 insertions(+), 29 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp_tx.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp_tx.c
|
||||
@@ -95,11 +95,11 @@ int ath11k_dp_tx(struct ath11k *ar, stru
|
||||
u8 ring_selector = 0, ring_map = 0;
|
||||
bool tcl_ring_retry;
|
||||
|
||||
- if (test_bit(ATH11K_FLAG_CRASH_FLUSH, &ar->ab->dev_flags))
|
||||
+ if (unlikely(test_bit(ATH11K_FLAG_CRASH_FLUSH, &ar->ab->dev_flags)))
|
||||
return -ESHUTDOWN;
|
||||
|
||||
- if (!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) &&
|
||||
- !ieee80211_is_data(hdr->frame_control))
|
||||
+ if (unlikely(!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) &&
|
||||
+ !ieee80211_is_data(hdr->frame_control)))
|
||||
return -ENOTSUPP;
|
||||
|
||||
pool_id = skb_get_queue_mapping(skb) & (ATH11K_HW_MAX_QUEUES - 1);
|
||||
@@ -127,7 +127,7 @@ tcl_ring_sel:
|
||||
DP_TX_IDR_SIZE - 1, GFP_ATOMIC);
|
||||
spin_unlock_bh(&tx_ring->tx_idr_lock);
|
||||
|
||||
- if (ret < 0) {
|
||||
+ if (unlikely(ret < 0)) {
|
||||
if (ring_map == (BIT(ab->hw_params.max_tx_ring) - 1)) {
|
||||
atomic_inc(&ab->soc_stats.tx_err.misc_fail);
|
||||
return -ENOSPC;
|
||||
@@ -152,7 +152,7 @@ tcl_ring_sel:
|
||||
ti.meta_data_flags = arvif->tcl_metadata;
|
||||
}
|
||||
|
||||
- if (ti.encap_type == HAL_TCL_ENCAP_TYPE_RAW) {
|
||||
+ if (unlikely(ti.encap_type == HAL_TCL_ENCAP_TYPE_RAW)) {
|
||||
if (skb_cb->flags & ATH11K_SKB_CIPHER_SET) {
|
||||
ti.encrypt_type =
|
||||
ath11k_dp_tx_get_encrypt_type(skb_cb->cipher);
|
||||
@@ -173,8 +173,8 @@ tcl_ring_sel:
|
||||
ti.bss_ast_idx = arvif->ast_idx;
|
||||
ti.dscp_tid_tbl_idx = 0;
|
||||
|
||||
- if (skb->ip_summed == CHECKSUM_PARTIAL &&
|
||||
- ti.encap_type != HAL_TCL_ENCAP_TYPE_RAW) {
|
||||
+ if (likely(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) |
|
||||
@@ -211,7 +211,7 @@ tcl_ring_sel:
|
||||
}
|
||||
|
||||
ti.paddr = dma_map_single(ab->dev, skb->data, skb->len, DMA_TO_DEVICE);
|
||||
- if (dma_mapping_error(ab->dev, ti.paddr)) {
|
||||
+ if (unlikely(dma_mapping_error(ab->dev, ti.paddr))) {
|
||||
atomic_inc(&ab->soc_stats.tx_err.misc_fail);
|
||||
ath11k_warn(ab, "failed to DMA map data Tx buffer\n");
|
||||
ret = -ENOMEM;
|
||||
@@ -231,7 +231,7 @@ tcl_ring_sel:
|
||||
ath11k_hal_srng_access_begin(ab, tcl_ring);
|
||||
|
||||
hal_tcl_desc = (void *)ath11k_hal_srng_src_get_next_entry(ab, tcl_ring);
|
||||
- if (!hal_tcl_desc) {
|
||||
+ if (unlikely(!hal_tcl_desc)) {
|
||||
/* NOTE: It is highly unlikely we'll be running out of tcl_ring
|
||||
* desc because the desc is directly enqueued onto hw queue.
|
||||
*/
|
||||
@@ -245,7 +245,7 @@ tcl_ring_sel:
|
||||
* checking this ring earlier for each pkt tx.
|
||||
* Restart ring selection if some rings are not checked yet.
|
||||
*/
|
||||
- if (ring_map != (BIT(ab->hw_params.max_tx_ring) - 1) &&
|
||||
+ if (unlikely(ring_map != (BIT(ab->hw_params.max_tx_ring)) - 1) &&
|
||||
ab->hw_params.max_tx_ring > 1) {
|
||||
tcl_ring_retry = true;
|
||||
ring_selector++;
|
||||
@@ -327,7 +327,7 @@ ath11k_dp_tx_htt_tx_complete_buf(struct
|
||||
|
||||
spin_lock_bh(&tx_ring->tx_idr_lock);
|
||||
msdu = idr_find(&tx_ring->txbuf_idr, ts->msdu_id);
|
||||
- if (!msdu) {
|
||||
+ if (unlikely(!msdu)) {
|
||||
ath11k_warn(ab, "htt tx completion for unknown msdu_id %d\n",
|
||||
ts->msdu_id);
|
||||
spin_unlock_bh(&tx_ring->tx_idr_lock);
|
||||
@@ -435,16 +435,14 @@ static void ath11k_dp_tx_complete_msdu(s
|
||||
|
||||
dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE);
|
||||
|
||||
- rcu_read_lock();
|
||||
-
|
||||
- if (!rcu_dereference(ab->pdevs_active[ar->pdev_idx])) {
|
||||
+ if (unlikely(!rcu_access_pointer(ab->pdevs_active[ar->pdev_idx]))) {
|
||||
dev_kfree_skb_any(msdu);
|
||||
- goto exit;
|
||||
+ return;
|
||||
}
|
||||
|
||||
- if (!skb_cb->vif) {
|
||||
+ if (unlikely(!skb_cb->vif)) {
|
||||
dev_kfree_skb_any(msdu);
|
||||
- goto exit;
|
||||
+ return;
|
||||
}
|
||||
|
||||
info = IEEE80211_SKB_CB(msdu);
|
||||
@@ -465,7 +463,7 @@ static void ath11k_dp_tx_complete_msdu(s
|
||||
(info->flags & IEEE80211_TX_CTL_NO_ACK))
|
||||
info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED;
|
||||
|
||||
- if (ath11k_debugfs_is_extd_tx_stats_enabled(ar)) {
|
||||
+ if (unlikely(ath11k_debugfs_is_extd_tx_stats_enabled(ar))) {
|
||||
if (ts->flags & HAL_TX_STATUS_FLAGS_FIRST_MSDU) {
|
||||
if (ar->last_ppdu_id == 0) {
|
||||
ar->last_ppdu_id = ts->ppdu_id;
|
||||
@@ -494,9 +492,6 @@ static void ath11k_dp_tx_complete_msdu(s
|
||||
*/
|
||||
|
||||
ieee80211_tx_status(ar->hw, msdu);
|
||||
-
|
||||
-exit:
|
||||
- rcu_read_unlock();
|
||||
}
|
||||
|
||||
static inline void ath11k_dp_tx_status_parse(struct ath11k_base *ab,
|
||||
@@ -505,11 +500,11 @@ static inline void ath11k_dp_tx_status_p
|
||||
{
|
||||
ts->buf_rel_source =
|
||||
FIELD_GET(HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE, desc->info0);
|
||||
- if (ts->buf_rel_source != HAL_WBM_REL_SRC_MODULE_FW &&
|
||||
- ts->buf_rel_source != HAL_WBM_REL_SRC_MODULE_TQM)
|
||||
+ if (unlikely(ts->buf_rel_source != HAL_WBM_REL_SRC_MODULE_FW &&
|
||||
+ ts->buf_rel_source != HAL_WBM_REL_SRC_MODULE_TQM))
|
||||
return;
|
||||
|
||||
- if (ts->buf_rel_source == HAL_WBM_REL_SRC_MODULE_FW)
|
||||
+ if (unlikely(ts->buf_rel_source == HAL_WBM_REL_SRC_MODULE_FW))
|
||||
return;
|
||||
|
||||
ts->status = FIELD_GET(HAL_WBM_RELEASE_INFO0_TQM_RELEASE_REASON,
|
||||
@@ -556,8 +551,9 @@ void ath11k_dp_tx_completion_handler(str
|
||||
ATH11K_TX_COMPL_NEXT(tx_ring->tx_status_head);
|
||||
}
|
||||
|
||||
- if ((ath11k_hal_srng_dst_peek(ab, status_ring) != NULL) &&
|
||||
- (ATH11K_TX_COMPL_NEXT(tx_ring->tx_status_head) == tx_ring->tx_status_tail)) {
|
||||
+ if (unlikely((ath11k_hal_srng_dst_peek(ab, status_ring) != NULL) &&
|
||||
+ (ATH11K_TX_COMPL_NEXT(tx_ring->tx_status_head) ==
|
||||
+ tx_ring->tx_status_tail))) {
|
||||
/* TODO: Process pending tx_status messages when kfifo_is_full() */
|
||||
ath11k_warn(ab, "Unable to process some of the tx_status ring desc because status_fifo is full\n");
|
||||
}
|
||||
@@ -580,7 +576,7 @@ void ath11k_dp_tx_completion_handler(str
|
||||
mac_id = FIELD_GET(DP_TX_DESC_ID_MAC_ID, desc_id);
|
||||
msdu_id = FIELD_GET(DP_TX_DESC_ID_MSDU_ID, desc_id);
|
||||
|
||||
- if (ts.buf_rel_source == HAL_WBM_REL_SRC_MODULE_FW) {
|
||||
+ if (unlikely(ts.buf_rel_source == HAL_WBM_REL_SRC_MODULE_FW)) {
|
||||
ath11k_dp_tx_process_htt_tx_complete(ab,
|
||||
(void *)tx_status,
|
||||
mac_id, msdu_id,
|
||||
@@ -590,7 +586,7 @@ void ath11k_dp_tx_completion_handler(str
|
||||
|
||||
spin_lock_bh(&tx_ring->tx_idr_lock);
|
||||
msdu = idr_find(&tx_ring->txbuf_idr, msdu_id);
|
||||
- if (!msdu) {
|
||||
+ if (unlikely(!msdu)) {
|
||||
ath11k_warn(ab, "tx completion for unknown msdu_id %d\n",
|
||||
msdu_id);
|
||||
spin_unlock_bh(&tx_ring->tx_idr_lock);
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -5283,7 +5283,7 @@ static void ath11k_mac_op_tx(struct ieee
|
||||
arsta = (struct ath11k_sta *)control->sta->drv_priv;
|
||||
|
||||
ret = ath11k_dp_tx(ar, arvif, arsta, skb);
|
||||
- if (ret) {
|
||||
+ if (unlikely(ret)) {
|
||||
ath11k_warn(ar->ab, "failed to transmit frame %d\n", ret);
|
||||
ieee80211_free_txskb(ar->hw, skb);
|
||||
}
|
@ -0,0 +1,102 @@
|
||||
From be8867cb47652418e488170785bd9ffbadae3f1f Mon Sep 17 00:00:00 2001
|
||||
From: P Praneesh <ppranees@codeaurora.org>
|
||||
Date: Fri, 12 Nov 2021 11:06:11 +0200
|
||||
Subject: [PATCH 085/120] ath11k: avoid unnecessary lock contention in
|
||||
tx_completion path
|
||||
|
||||
Avoid unnecessary idr_find calls before the idr_remove calls. Because
|
||||
idr_remove gives the valid ptr if id is valid otherwise return NULL ptr.
|
||||
So removed the idr_find before idr_remove in tx completion path. Also no
|
||||
need to disable the bottom half preempt if it is already in the
|
||||
bottom half context, so modify the spin_lock_bh to spin_lock in the
|
||||
data tx completion path.
|
||||
|
||||
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-01734-QCAHKSWPL_SILICONZ-1 v2
|
||||
|
||||
Co-developed-by: Karthikeyan Periyasamy <periyasa@codeaurora.org>
|
||||
Signed-off-by: Karthikeyan Periyasamy <periyasa@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Signed-off-by: P Praneesh <ppranees@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/1630560820-21905-13-git-send-email-ppranees@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/dp_tx.c | 32 +++++++++++--------------
|
||||
1 file changed, 14 insertions(+), 18 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp_tx.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp_tx.c
|
||||
@@ -293,20 +293,18 @@ static void ath11k_dp_tx_free_txbuf(stru
|
||||
struct sk_buff *msdu;
|
||||
struct ath11k_skb_cb *skb_cb;
|
||||
|
||||
- spin_lock_bh(&tx_ring->tx_idr_lock);
|
||||
- msdu = idr_find(&tx_ring->txbuf_idr, msdu_id);
|
||||
- if (!msdu) {
|
||||
+ spin_lock(&tx_ring->tx_idr_lock);
|
||||
+ msdu = idr_remove(&tx_ring->txbuf_idr, msdu_id);
|
||||
+ spin_unlock(&tx_ring->tx_idr_lock);
|
||||
+
|
||||
+ if (unlikely(!msdu)) {
|
||||
ath11k_warn(ab, "tx completion for unknown msdu_id %d\n",
|
||||
msdu_id);
|
||||
- spin_unlock_bh(&tx_ring->tx_idr_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
skb_cb = ATH11K_SKB_CB(msdu);
|
||||
|
||||
- idr_remove(&tx_ring->txbuf_idr, msdu_id);
|
||||
- spin_unlock_bh(&tx_ring->tx_idr_lock);
|
||||
-
|
||||
dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE);
|
||||
dev_kfree_skb_any(msdu);
|
||||
|
||||
@@ -325,12 +323,13 @@ ath11k_dp_tx_htt_tx_complete_buf(struct
|
||||
struct ath11k_skb_cb *skb_cb;
|
||||
struct ath11k *ar;
|
||||
|
||||
- spin_lock_bh(&tx_ring->tx_idr_lock);
|
||||
- msdu = idr_find(&tx_ring->txbuf_idr, ts->msdu_id);
|
||||
+ spin_lock(&tx_ring->tx_idr_lock);
|
||||
+ msdu = idr_remove(&tx_ring->txbuf_idr, ts->msdu_id);
|
||||
+ spin_unlock(&tx_ring->tx_idr_lock);
|
||||
+
|
||||
if (unlikely(!msdu)) {
|
||||
ath11k_warn(ab, "htt tx completion for unknown msdu_id %d\n",
|
||||
ts->msdu_id);
|
||||
- spin_unlock_bh(&tx_ring->tx_idr_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -339,9 +338,6 @@ ath11k_dp_tx_htt_tx_complete_buf(struct
|
||||
|
||||
ar = skb_cb->ar;
|
||||
|
||||
- idr_remove(&tx_ring->txbuf_idr, ts->msdu_id);
|
||||
- spin_unlock_bh(&tx_ring->tx_idr_lock);
|
||||
-
|
||||
if (atomic_dec_and_test(&ar->dp.num_tx_pending))
|
||||
wake_up(&ar->dp.tx_empty_waitq);
|
||||
|
||||
@@ -584,16 +580,16 @@ void ath11k_dp_tx_completion_handler(str
|
||||
continue;
|
||||
}
|
||||
|
||||
- spin_lock_bh(&tx_ring->tx_idr_lock);
|
||||
- msdu = idr_find(&tx_ring->txbuf_idr, msdu_id);
|
||||
+ spin_lock(&tx_ring->tx_idr_lock);
|
||||
+ msdu = idr_remove(&tx_ring->txbuf_idr, msdu_id);
|
||||
if (unlikely(!msdu)) {
|
||||
ath11k_warn(ab, "tx completion for unknown msdu_id %d\n",
|
||||
msdu_id);
|
||||
- spin_unlock_bh(&tx_ring->tx_idr_lock);
|
||||
+ spin_unlock(&tx_ring->tx_idr_lock);
|
||||
continue;
|
||||
}
|
||||
- idr_remove(&tx_ring->txbuf_idr, msdu_id);
|
||||
- spin_unlock_bh(&tx_ring->tx_idr_lock);
|
||||
+
|
||||
+ spin_unlock(&tx_ring->tx_idr_lock);
|
||||
|
||||
ar = ab->pdevs[mac_id].ar;
|
||||
|
@ -0,0 +1,48 @@
|
||||
From 78406044bdd0cc8987bc082b76867c63ab1c6af8 Mon Sep 17 00:00:00 2001
|
||||
From: Wen Gong <wgong@codeaurora.org>
|
||||
Date: Wed, 13 Oct 2021 03:37:04 -0400
|
||||
Subject: [PATCH 086/120] ath11k: enable IEEE80211_VHT_EXT_NSS_BW_CAPABLE if
|
||||
NSS ratio enabled
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
When NSS ratio enabled reported by firmware, SUPPORTS_VHT_EXT_NSS_BW
|
||||
is set in ath11k, meanwhile IEEE80211_VHT_EXT_NSS_BW_CAPABLE also
|
||||
need to be set, otherwise it is invalid because spec in IEEE Std
|
||||
802.11™‐2020 as below.
|
||||
|
||||
Table 9-273-Supported VHT-MCS and NSS Set subfields, it has subfield
|
||||
VHT Extended NSS BW Capable, its definition is:
|
||||
Indicates whether the STA is capable of interpreting the Extended NSS
|
||||
BW Support subfield of the VHT Capabilities Information field.
|
||||
|
||||
dmesg have a message without this patch:
|
||||
|
||||
ieee80211 phy0: copying sband (band 1) due to VHT EXT NSS BW flag
|
||||
|
||||
It means mac80211 will set IEEE80211_VHT_EXT_NSS_BW_CAPABLE if ath11k not
|
||||
set it in ieee80211_register_hw(). So it is better to set it in ath11k.
|
||||
|
||||
Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1
|
||||
|
||||
Signed-off-by: Wen Gong <wgong@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20211013073704.15888-1-wgong@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/mac.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -4706,6 +4706,10 @@ ath11k_create_vht_cap(struct ath11k *ar,
|
||||
vht_cap.vht_supported = 1;
|
||||
vht_cap.cap = ar->pdev->cap.vht_cap;
|
||||
|
||||
+ if (ar->pdev->cap.nss_ratio_enabled)
|
||||
+ vht_cap.vht_mcs.tx_highest |=
|
||||
+ cpu_to_le16(IEEE80211_VHT_EXT_NSS_BW_CAPABLE);
|
||||
+
|
||||
ath11k_set_vht_txbf_cap(ar, &vht_cap.cap);
|
||||
|
||||
rxmcs_map = 0;
|
@ -0,0 +1,66 @@
|
||||
From 1d795645e1eef97fe5d409e3dd5747a942f00e08 Mon Sep 17 00:00:00 2001
|
||||
From: Wen Gong <wgong@codeaurora.org>
|
||||
Date: Mon, 11 Oct 2021 04:49:57 -0400
|
||||
Subject: [PATCH 087/120] ath11k: remove return for empty tx bitrate in
|
||||
mac_op_sta_statistics
|
||||
|
||||
Currently in ath11k_mac_op_sta_statistics() there is the following
|
||||
logic:
|
||||
|
||||
if (!arsta->txrate.legacy && !arsta->txrate.nss)
|
||||
return;
|
||||
|
||||
Unfortunately if this condition is true then the function returns without
|
||||
setting parameters that follow the txrate. To address this issue remove the
|
||||
return and instead invert the logic to set the txrate logic if
|
||||
(arsta->txrate.legacy || arsta->txrate.nss).
|
||||
|
||||
The same was done also in ath10k in commit 1cd6ba8ae33e ("ath10k: remove return
|
||||
for NL80211_STA_INFO_TX_BITRATE").
|
||||
|
||||
Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1
|
||||
|
||||
Signed-off-by: Wen Gong <wgong@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20211011084957.31024-1-wgong@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/mac.c | 29 +++++++++++++--------------
|
||||
1 file changed, 14 insertions(+), 15 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -7426,21 +7426,20 @@ static void ath11k_mac_op_sta_statistics
|
||||
sinfo->tx_duration = arsta->tx_duration;
|
||||
sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_DURATION);
|
||||
|
||||
- if (!arsta->txrate.legacy && !arsta->txrate.nss)
|
||||
- return;
|
||||
-
|
||||
- if (arsta->txrate.legacy) {
|
||||
- sinfo->txrate.legacy = arsta->txrate.legacy;
|
||||
- } else {
|
||||
- sinfo->txrate.mcs = arsta->txrate.mcs;
|
||||
- sinfo->txrate.nss = arsta->txrate.nss;
|
||||
- sinfo->txrate.bw = arsta->txrate.bw;
|
||||
- sinfo->txrate.he_gi = arsta->txrate.he_gi;
|
||||
- sinfo->txrate.he_dcm = arsta->txrate.he_dcm;
|
||||
- sinfo->txrate.he_ru_alloc = arsta->txrate.he_ru_alloc;
|
||||
+ if (arsta->txrate.legacy || arsta->txrate.nss) {
|
||||
+ if (arsta->txrate.legacy) {
|
||||
+ sinfo->txrate.legacy = arsta->txrate.legacy;
|
||||
+ } else {
|
||||
+ sinfo->txrate.mcs = arsta->txrate.mcs;
|
||||
+ sinfo->txrate.nss = arsta->txrate.nss;
|
||||
+ sinfo->txrate.bw = arsta->txrate.bw;
|
||||
+ sinfo->txrate.he_gi = arsta->txrate.he_gi;
|
||||
+ sinfo->txrate.he_dcm = arsta->txrate.he_dcm;
|
||||
+ sinfo->txrate.he_ru_alloc = arsta->txrate.he_ru_alloc;
|
||||
+ }
|
||||
+ sinfo->txrate.flags = arsta->txrate.flags;
|
||||
+ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
|
||||
}
|
||||
- sinfo->txrate.flags = arsta->txrate.flags;
|
||||
- sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
|
||||
|
||||
/* TODO: Use real NF instead of default one. */
|
||||
sinfo->signal = arsta->rssi_comb + ATH11K_DEFAULT_NOISE_FLOOR;
|
@ -0,0 +1,28 @@
|
||||
From c8f2d41bbff6794329d681d108a817366aed0ba7 Mon Sep 17 00:00:00 2001
|
||||
From: Wen Gong <quic_wgong@quicinc.com>
|
||||
Date: Mon, 25 Oct 2021 23:20:14 -0400
|
||||
Subject: [PATCH 088/120] ath11k: fix the value of msecs_to_jiffies in
|
||||
ath11k_debugfs_fw_stats_request
|
||||
|
||||
parameter of msecs_to_jiffies should be (3 * 1000) instead of (3 * HZ)
|
||||
|
||||
Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1
|
||||
|
||||
Signed-off-by: Wen Gong <quic_wgong@quicinc.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20211026032014.27010-1-quic_wgong@quicinc.com
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/debugfs.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/debugfs.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/debugfs.c
|
||||
@@ -195,7 +195,7 @@ static int ath11k_debugfs_fw_stats_reque
|
||||
* received 'update stats' event, we keep a 3 seconds timeout in case,
|
||||
* fw_stats_done is not marked yet
|
||||
*/
|
||||
- timeout = jiffies + msecs_to_jiffies(3 * HZ);
|
||||
+ timeout = jiffies + msecs_to_jiffies(3 * 1000);
|
||||
|
||||
ath11k_debugfs_fw_stats_reset(ar);
|
||||
|
@ -0,0 +1,89 @@
|
||||
From b4a0f54156ac7720de1750b6ea06657c91c52163 Mon Sep 17 00:00:00 2001
|
||||
From: Wen Gong <quic_wgong@quicinc.com>
|
||||
Date: Wed, 27 Oct 2021 05:38:25 -0400
|
||||
Subject: [PATCH 089/120] ath11k: move peer delete after vdev stop of station
|
||||
for QCA6390 and WCN6855
|
||||
|
||||
When station connect to AP, the wmi command sequence is:
|
||||
|
||||
peer_create->vdev_start->vdev_up
|
||||
|
||||
and sequence of station disconnect fo AP is:
|
||||
|
||||
peer_delete->vdev_down->vdev_stop
|
||||
|
||||
The sequence of disconnect is not opposite of connect, it caused firmware
|
||||
crash when it handle wmi vdev stop cmd when the AP is support TWT of
|
||||
802.11 ax, because firmware need access the bss peer for vdev stop cmd.
|
||||
|
||||
[ 390.438564] ath11k_pci 0000:05:00.0: wmi cmd send 0x6001 ret 0
|
||||
[ 390.438567] ath11k_pci 0000:05:00.0: WMI peer create vdev_id 0 peer_addr c4:04:15:3b:e0:39
|
||||
[ 390.472724] ath11k_pci 0000:05:00.0: mac vdev 0 start center_freq 2437 phymode 11ax-he20-2g
|
||||
[ 390.472731] ath11k_pci 0000:05:00.0: wmi cmd send 0x5003 ret 0
|
||||
[ 390.560849] ath11k_pci 0000:05:00.0: wmi cmd send 0x5005 ret 0
|
||||
[ 390.560850] ath11k_pci 0000:05:00.0: WMI mgmt vdev up id 0x0 assoc id 1 bssid c4:04:15:3b:e0:39
|
||||
|
||||
[ 399.432896] ath11k_pci 0000:05:00.0: WMI peer delete vdev_id 0 peer_addr c4:04:15:3b:e0:39
|
||||
[ 399.432902] ath11k_pci 0000:05:00.0: wmi cmd send 0x6002 ret 0
|
||||
[ 399.441380] ath11k_pci 0000:05:00.0: wmi cmd send 0x5007 ret 0
|
||||
[ 399.441381] ath11k_pci 0000:05:00.0: WMI vdev down id 0x0
|
||||
[ 399.454681] ath11k_pci 0000:05:00.0: wmi cmd send 0x5006 ret 0
|
||||
[ 399.454682] ath11k_pci 0000:05:00.0: WMI vdev stop id 0x0
|
||||
|
||||
The opposite sequence of disconnect should be:
|
||||
|
||||
vdev_down->vdev_stop->peer_delete
|
||||
|
||||
This patch change the sequence of disconnect for station as above
|
||||
opposite sequence for QCA6390, firmware not crash again with this patch.
|
||||
|
||||
Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1
|
||||
|
||||
Signed-off-by: Wen Gong <quic_wgong@quicinc.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20211027093825.12167-1-quic_wgong@quicinc.com
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/mac.c | 18 ++++++++++++++++++
|
||||
1 file changed, 18 insertions(+)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -4212,6 +4212,10 @@ static int ath11k_mac_op_sta_state(struc
|
||||
new_state == IEEE80211_STA_NOTEXIST)) {
|
||||
ath11k_dp_peer_cleanup(ar, arvif->vdev_id, sta->addr);
|
||||
|
||||
+ if (ar->ab->hw_params.vdev_start_delay &&
|
||||
+ vif->type == NL80211_IFTYPE_STATION)
|
||||
+ goto free;
|
||||
+
|
||||
ret = ath11k_peer_delete(ar, arvif->vdev_id, sta->addr);
|
||||
if (ret)
|
||||
ath11k_warn(ar->ab, "Failed to delete peer: %pM for VDEV: %d\n",
|
||||
@@ -4233,6 +4237,7 @@ static int ath11k_mac_op_sta_state(struc
|
||||
}
|
||||
spin_unlock_bh(&ar->ab->base_lock);
|
||||
|
||||
+free:
|
||||
kfree(arsta->tx_stats);
|
||||
arsta->tx_stats = NULL;
|
||||
|
||||
@@ -6617,6 +6622,19 @@ ath11k_mac_op_unassign_vif_chanctx(struc
|
||||
arvif->is_started = false;
|
||||
|
||||
if (ab->hw_params.vdev_start_delay &&
|
||||
+ arvif->vdev_type == WMI_VDEV_TYPE_STA) {
|
||||
+ ret = ath11k_peer_delete(ar, arvif->vdev_id, arvif->bssid);
|
||||
+ if (ret)
|
||||
+ ath11k_warn(ar->ab,
|
||||
+ "failed to delete peer %pM for vdev %d: %d\n",
|
||||
+ arvif->bssid, arvif->vdev_id, ret);
|
||||
+ else
|
||||
+ ath11k_dbg(ar->ab, ATH11K_DBG_MAC,
|
||||
+ "mac removed peer %pM vdev %d after vdev stop\n",
|
||||
+ arvif->bssid, arvif->vdev_id);
|
||||
+ }
|
||||
+
|
||||
+ if (ab->hw_params.vdev_start_delay &&
|
||||
arvif->vdev_type == WMI_VDEV_TYPE_MONITOR)
|
||||
ath11k_wmi_vdev_down(ar, arvif->vdev_id);
|
||||
|
@ -0,0 +1,73 @@
|
||||
From 787264893c69ed091a46335dfd0f50dabb457718 Mon Sep 17 00:00:00 2001
|
||||
From: P Praneesh <quic_ppranees@quicinc.com>
|
||||
Date: Mon, 25 Oct 2021 17:44:20 +0530
|
||||
Subject: [PATCH 090/120] ath11k: fix FCS_ERR flag in radio tap header
|
||||
|
||||
In radio tap header, BAD FCS flag is not updated properly because
|
||||
driver failed to update FCS_ERR flag in monitor mode.
|
||||
|
||||
In rx_desc, FCS_ERR information is available in rx_attention
|
||||
structure and presence of this field indicates corresponding frame
|
||||
failed FCS check.
|
||||
|
||||
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-01695-QCAHKSWPL_SILICONZ-1
|
||||
|
||||
Signed-off-by: P Praneesh <quic_ppranees@quicinc.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/1635164060-18423-1-git-send-email-quic_ppranees@quicinc.com
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/dp_rx.c | 14 ++++++++++++--
|
||||
1 file changed, 12 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
|
||||
@@ -4826,7 +4826,7 @@ static struct sk_buff *
|
||||
ath11k_dp_rx_mon_merg_msdus(struct ath11k *ar,
|
||||
u32 mac_id, struct sk_buff *head_msdu,
|
||||
struct sk_buff *last_msdu,
|
||||
- struct ieee80211_rx_status *rxs)
|
||||
+ struct ieee80211_rx_status *rxs, bool *fcs_err)
|
||||
{
|
||||
struct ath11k_base *ab = ar->ab;
|
||||
struct sk_buff *msdu, *prev_buf;
|
||||
@@ -4836,12 +4836,17 @@ ath11k_dp_rx_mon_merg_msdus(struct ath11
|
||||
u8 *dest, decap_format;
|
||||
struct ieee80211_hdr_3addr *wh;
|
||||
struct rx_attention *rx_attention;
|
||||
+ u32 err_bitmap;
|
||||
|
||||
if (!head_msdu)
|
||||
goto err_merge_fail;
|
||||
|
||||
rx_desc = (struct hal_rx_desc *)head_msdu->data;
|
||||
rx_attention = ath11k_dp_rx_get_attention(ab, rx_desc);
|
||||
+ err_bitmap = ath11k_dp_rx_h_attn_mpdu_err(rx_attention);
|
||||
+
|
||||
+ if (err_bitmap & DP_RX_MPDU_ERR_FCS)
|
||||
+ *fcs_err = true;
|
||||
|
||||
if (ath11k_dp_rxdesc_get_mpdulen_err(rx_attention))
|
||||
return NULL;
|
||||
@@ -4930,9 +4935,10 @@ static int ath11k_dp_rx_mon_deliver(stru
|
||||
struct ath11k_pdev_dp *dp = &ar->dp;
|
||||
struct sk_buff *mon_skb, *skb_next, *header;
|
||||
struct ieee80211_rx_status *rxs = &dp->rx_status;
|
||||
+ bool fcs_err = false;
|
||||
|
||||
mon_skb = ath11k_dp_rx_mon_merg_msdus(ar, mac_id, head_msdu,
|
||||
- tail_msdu, rxs);
|
||||
+ tail_msdu, rxs, &fcs_err);
|
||||
|
||||
if (!mon_skb)
|
||||
goto mon_deliver_fail;
|
||||
@@ -4940,6 +4946,10 @@ static int ath11k_dp_rx_mon_deliver(stru
|
||||
header = mon_skb;
|
||||
|
||||
rxs->flag = 0;
|
||||
+
|
||||
+ if (fcs_err)
|
||||
+ rxs->flag = RX_FLAG_FAILED_FCS_CRC;
|
||||
+
|
||||
do {
|
||||
skb_next = mon_skb->next;
|
||||
if (!skb_next)
|
@ -0,0 +1,64 @@
|
||||
From 9212c1b9e80a869e732769a4fe7f82d392b219be Mon Sep 17 00:00:00 2001
|
||||
From: P Praneesh <quic_ppranees@quicinc.com>
|
||||
Date: Mon, 25 Oct 2021 17:47:09 +0530
|
||||
Subject: [PATCH 091/120] ath11k: send proper txpower and maxregpower values to
|
||||
firmware
|
||||
|
||||
Set proper values for max_regpower, max_power, max_antenna_gain as it
|
||||
is because firmware will convert power values to 0.5dbm steps by
|
||||
multiplying it with 2.
|
||||
|
||||
If txpower is not set, it will lead to cca stuck resulting in latency
|
||||
issues for QCN9074.
|
||||
|
||||
Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.4.0.1-01386-QCAHKSWPL_SILICONZ-1
|
||||
|
||||
Co-developed-by: Lavanya Suresh <lavaks@codeaurora.org>
|
||||
Signed-off-by: Lavanya Suresh <lavaks@codeaurora.org>
|
||||
Signed-off-by: P Praneesh <quic_ppranees@quicinc.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/1635164229-22880-1-git-send-email-quic_ppranees@quicinc.com
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/mac.c | 12 ++++++------
|
||||
drivers/net/wireless/ath/ath11k/wmi.c | 2 ++
|
||||
2 files changed, 8 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -775,9 +775,9 @@ static int ath11k_mac_monitor_vdev_start
|
||||
arg.channel.chan_radar = !!(channel->flags & IEEE80211_CHAN_RADAR);
|
||||
|
||||
arg.channel.min_power = 0;
|
||||
- arg.channel.max_power = channel->max_power * 2;
|
||||
- arg.channel.max_reg_power = channel->max_reg_power * 2;
|
||||
- arg.channel.max_antenna_gain = channel->max_antenna_gain * 2;
|
||||
+ arg.channel.max_power = channel->max_power;
|
||||
+ arg.channel.max_reg_power = channel->max_reg_power;
|
||||
+ arg.channel.max_antenna_gain = channel->max_antenna_gain;
|
||||
|
||||
arg.pref_tx_streams = ar->num_tx_chains;
|
||||
arg.pref_rx_streams = ar->num_rx_chains;
|
||||
@@ -6123,9 +6123,9 @@ ath11k_mac_vdev_start_restart(struct ath
|
||||
ath11k_phymodes[chandef->chan->band][chandef->width];
|
||||
|
||||
arg.channel.min_power = 0;
|
||||
- arg.channel.max_power = chandef->chan->max_power * 2;
|
||||
- arg.channel.max_reg_power = chandef->chan->max_reg_power * 2;
|
||||
- arg.channel.max_antenna_gain = chandef->chan->max_antenna_gain * 2;
|
||||
+ arg.channel.max_power = chandef->chan->max_power;
|
||||
+ arg.channel.max_reg_power = chandef->chan->max_reg_power;
|
||||
+ arg.channel.max_antenna_gain = chandef->chan->max_antenna_gain;
|
||||
|
||||
arg.pref_tx_streams = ar->num_tx_chains;
|
||||
arg.pref_rx_streams = ar->num_rx_chains;
|
||||
--- a/drivers/net/wireless/ath/ath11k/wmi.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
|
||||
@@ -2387,6 +2387,8 @@ int ath11k_wmi_send_scan_chan_list_cmd(s
|
||||
tchan_info->reg_class_id);
|
||||
*reg2 |= FIELD_PREP(WMI_CHAN_REG_INFO2_ANT_MAX,
|
||||
tchan_info->antennamax);
|
||||
+ *reg2 |= FIELD_PREP(WMI_CHAN_REG_INFO2_MAX_TX_PWR,
|
||||
+ tchan_info->maxregpower);
|
||||
|
||||
ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
|
||||
"WMI chan scan list chan[%d] = %u, chan_info->info %8x\n",
|
@ -0,0 +1,44 @@
|
||||
From c0b0d2e87d91ce283c8766b4b3c2ec9ac90ebf96 Mon Sep 17 00:00:00 2001
|
||||
From: P Praneesh <quic_ppranees@quicinc.com>
|
||||
Date: Mon, 25 Oct 2021 18:54:42 +0530
|
||||
Subject: [PATCH 092/120] ath11k: Increment pending_mgmt_tx count before tx
|
||||
send invoke
|
||||
|
||||
There is a race condition whereby the tx completion handler can be invoked
|
||||
before the 'num_pending_mgmt_tx" count is incremented. If that occurs, we
|
||||
could get warning trace indicating that 'num_pending_mgmt_tx' is 0 (because
|
||||
it was not yet incremented). Ideally, this trace should be seen only if
|
||||
mgmt tx has not happened but tx completion is received, and it is not
|
||||
expected in this race condition.
|
||||
|
||||
Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.4.0.1-01386-QCAHKSWPL_SILICONZ-1
|
||||
|
||||
Co-developed-by: Lavanya Suresh <lavaks@codeaurora.org>
|
||||
Signed-off-by: Lavanya Suresh <lavaks@codeaurora.org>
|
||||
Signed-off-by: P Praneesh <quic_ppranees@quicinc.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/1635168282-8845-1-git-send-email-quic_ppranees@quicinc.com
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/mac.c | 6 ++++--
|
||||
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -5202,13 +5202,15 @@ static void ath11k_mgmt_over_wmi_tx_work
|
||||
arvif = ath11k_vif_to_arvif(skb_cb->vif);
|
||||
if (ar->allocated_vdev_map & (1LL << arvif->vdev_id) &&
|
||||
arvif->is_started) {
|
||||
+ atomic_inc(&ar->num_pending_mgmt_tx);
|
||||
ret = ath11k_mac_mgmt_tx_wmi(ar, arvif, skb);
|
||||
if (ret) {
|
||||
+ if (atomic_dec_if_positive(&ar->num_pending_mgmt_tx) < 0)
|
||||
+ WARN_ON_ONCE(1);
|
||||
+
|
||||
ath11k_warn(ar->ab, "failed to tx mgmt frame, vdev_id %d :%d\n",
|
||||
arvif->vdev_id, ret);
|
||||
ieee80211_free_txskb(ar->hw, skb);
|
||||
- } else {
|
||||
- atomic_inc(&ar->num_pending_mgmt_tx);
|
||||
}
|
||||
} else {
|
||||
ath11k_warn(ar->ab,
|
@ -0,0 +1,236 @@
|
||||
From 086c921a354089f209318501038d43c98d3f409f Mon Sep 17 00:00:00 2001
|
||||
From: Sven Eckelmann <sven@narfation.org>
|
||||
Date: Mon, 15 Nov 2021 11:29:55 +0200
|
||||
Subject: [PATCH 093/120] ath11k: Fix ETSI regd with weather radar overlap
|
||||
|
||||
Some ETSI countries have a small overlap in the wireless-regdb with an ETSI
|
||||
channel (5590-5650). A good example is Australia:
|
||||
|
||||
country AU: DFS-ETSI
|
||||
(2400 - 2483.5 @ 40), (36)
|
||||
(5150 - 5250 @ 80), (23), NO-OUTDOOR, AUTO-BW
|
||||
(5250 - 5350 @ 80), (20), NO-OUTDOOR, AUTO-BW, DFS
|
||||
(5470 - 5600 @ 80), (27), DFS
|
||||
(5650 - 5730 @ 80), (27), DFS
|
||||
(5730 - 5850 @ 80), (36)
|
||||
(57000 - 66000 @ 2160), (43), NO-OUTDOOR
|
||||
|
||||
If the firmware (or the BDF) is shipped with these rules then there is only
|
||||
a 10 MHz overlap with the weather radar:
|
||||
|
||||
* below: 5470 - 5590
|
||||
* weather radar: 5590 - 5600
|
||||
* above: (none for the rule "5470 - 5600 @ 80")
|
||||
|
||||
There are several wrong assumption in the ath11k code:
|
||||
|
||||
* there is always a valid range below the weather radar
|
||||
(actually: there could be no range below the weather radar range OR range
|
||||
could be smaller than 20 MHz)
|
||||
* intersected range in the weather radar range is valid
|
||||
(actually: the range could be smaller than 20 MHz)
|
||||
* range above weather radar is either empty or valid
|
||||
(actually: the range could be smaller than 20 MHz)
|
||||
|
||||
These wrong assumption will lead in this example to a rule
|
||||
|
||||
(5590 - 5600 @ 20), (N/A, 27), (600000 ms), DFS, AUTO-BW
|
||||
|
||||
which is invalid according to is_valid_reg_rule() because the freq_diff is
|
||||
only 10 MHz but the max_bandwidth is set to 20 MHz. Which results in a
|
||||
rejection like:
|
||||
|
||||
WARNING: at backports-20210222_001-4.4.60-b157d2276/net/wireless/reg.c:3984
|
||||
[...]
|
||||
Call trace:
|
||||
[<ffffffbffc3d2e50>] reg_get_max_bandwidth+0x300/0x3a8 [cfg80211]
|
||||
[<ffffffbffc3d3d0c>] regulatory_set_wiphy_regd_sync+0x3c/0x98 [cfg80211]
|
||||
[<ffffffbffc651598>] ath11k_regd_update+0x1a8/0x210 [ath11k]
|
||||
[<ffffffbffc652108>] ath11k_regd_update_work+0x18/0x20 [ath11k]
|
||||
[<ffffffc0000a93e0>] process_one_work+0x1f8/0x340
|
||||
[<ffffffc0000a9784>] worker_thread+0x25c/0x448
|
||||
[<ffffffc0000aedc8>] kthread+0xd0/0xd8
|
||||
[<ffffffc000085550>] ret_from_fork+0x10/0x40
|
||||
ath11k c000000.wifi: failed to perform regd update : -22
|
||||
Invalid regulatory domain detected
|
||||
|
||||
To avoid this, the algorithm has to be changed slightly. Instead of
|
||||
splitting a rule which overlaps with the weather radar range into 3 pieces
|
||||
and accepting the first two parts blindly, it must actually be checked for
|
||||
each piece whether it is a valid range. And only if it is valid, add it to
|
||||
the output array.
|
||||
|
||||
When these checks are in place, the processed rules for AU would end up as
|
||||
|
||||
country AU: DFS-ETSI
|
||||
(2400 - 2483 @ 40), (N/A, 36), (N/A)
|
||||
(5150 - 5250 @ 80), (6, 23), (N/A), NO-OUTDOOR, AUTO-BW
|
||||
(5250 - 5350 @ 80), (6, 20), (0 ms), NO-OUTDOOR, DFS, AUTO-BW
|
||||
(5470 - 5590 @ 80), (6, 27), (0 ms), DFS, AUTO-BW
|
||||
(5650 - 5730 @ 80), (6, 27), (0 ms), DFS, AUTO-BW
|
||||
(5730 - 5850 @ 80), (6, 36), (N/A), AUTO-BW
|
||||
|
||||
and will be accepted by the wireless regulatory code.
|
||||
|
||||
Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices")
|
||||
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20211112153116.1214421-1-sven@narfation.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/reg.c | 103 ++++++++++++++------------
|
||||
1 file changed, 56 insertions(+), 47 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/reg.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/reg.c
|
||||
@@ -456,6 +456,9 @@ ath11k_reg_adjust_bw(u16 start_freq, u16
|
||||
{
|
||||
u16 bw;
|
||||
|
||||
+ if (end_freq <= start_freq)
|
||||
+ return 0;
|
||||
+
|
||||
bw = end_freq - start_freq;
|
||||
bw = min_t(u16, bw, max_bw);
|
||||
|
||||
@@ -463,8 +466,10 @@ ath11k_reg_adjust_bw(u16 start_freq, u16
|
||||
bw = 80;
|
||||
else if (bw >= 40 && bw < 80)
|
||||
bw = 40;
|
||||
- else if (bw < 40)
|
||||
+ else if (bw >= 20 && bw < 40)
|
||||
bw = 20;
|
||||
+ else
|
||||
+ bw = 0;
|
||||
|
||||
return bw;
|
||||
}
|
||||
@@ -488,73 +493,77 @@ ath11k_reg_update_weather_radar_band(str
|
||||
struct cur_reg_rule *reg_rule,
|
||||
u8 *rule_idx, u32 flags, u16 max_bw)
|
||||
{
|
||||
+ u32 start_freq;
|
||||
u32 end_freq;
|
||||
u16 bw;
|
||||
u8 i;
|
||||
|
||||
i = *rule_idx;
|
||||
|
||||
+ /* there might be situations when even the input rule must be dropped */
|
||||
+ i--;
|
||||
+
|
||||
+ /* frequencies below weather radar */
|
||||
bw = ath11k_reg_adjust_bw(reg_rule->start_freq,
|
||||
ETSI_WEATHER_RADAR_BAND_LOW, max_bw);
|
||||
+ if (bw > 0) {
|
||||
+ i++;
|
||||
|
||||
- ath11k_reg_update_rule(regd->reg_rules + i, reg_rule->start_freq,
|
||||
- ETSI_WEATHER_RADAR_BAND_LOW, bw,
|
||||
- reg_rule->ant_gain, reg_rule->reg_power,
|
||||
- flags);
|
||||
-
|
||||
- ath11k_dbg(ab, ATH11K_DBG_REG,
|
||||
- "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d)\n",
|
||||
- i + 1, reg_rule->start_freq, ETSI_WEATHER_RADAR_BAND_LOW,
|
||||
- bw, reg_rule->ant_gain, reg_rule->reg_power,
|
||||
- regd->reg_rules[i].dfs_cac_ms,
|
||||
- flags);
|
||||
-
|
||||
- if (reg_rule->end_freq > ETSI_WEATHER_RADAR_BAND_HIGH)
|
||||
- end_freq = ETSI_WEATHER_RADAR_BAND_HIGH;
|
||||
- else
|
||||
- end_freq = reg_rule->end_freq;
|
||||
-
|
||||
- bw = ath11k_reg_adjust_bw(ETSI_WEATHER_RADAR_BAND_LOW, end_freq,
|
||||
- max_bw);
|
||||
-
|
||||
- i++;
|
||||
+ ath11k_reg_update_rule(regd->reg_rules + i,
|
||||
+ reg_rule->start_freq,
|
||||
+ ETSI_WEATHER_RADAR_BAND_LOW, bw,
|
||||
+ reg_rule->ant_gain, reg_rule->reg_power,
|
||||
+ flags);
|
||||
+
|
||||
+ ath11k_dbg(ab, ATH11K_DBG_REG,
|
||||
+ "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d)\n",
|
||||
+ i + 1, reg_rule->start_freq,
|
||||
+ ETSI_WEATHER_RADAR_BAND_LOW, bw, reg_rule->ant_gain,
|
||||
+ reg_rule->reg_power, regd->reg_rules[i].dfs_cac_ms,
|
||||
+ flags);
|
||||
+ }
|
||||
|
||||
- ath11k_reg_update_rule(regd->reg_rules + i,
|
||||
- ETSI_WEATHER_RADAR_BAND_LOW, end_freq, bw,
|
||||
- reg_rule->ant_gain, reg_rule->reg_power,
|
||||
- flags);
|
||||
-
|
||||
- regd->reg_rules[i].dfs_cac_ms = ETSI_WEATHER_RADAR_BAND_CAC_TIMEOUT;
|
||||
-
|
||||
- ath11k_dbg(ab, ATH11K_DBG_REG,
|
||||
- "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d)\n",
|
||||
- i + 1, ETSI_WEATHER_RADAR_BAND_LOW, end_freq,
|
||||
- bw, reg_rule->ant_gain, reg_rule->reg_power,
|
||||
- regd->reg_rules[i].dfs_cac_ms,
|
||||
- flags);
|
||||
-
|
||||
- if (end_freq == reg_rule->end_freq) {
|
||||
- regd->n_reg_rules--;
|
||||
- *rule_idx = i;
|
||||
- return;
|
||||
+ /* weather radar frequencies */
|
||||
+ start_freq = max_t(u32, reg_rule->start_freq,
|
||||
+ ETSI_WEATHER_RADAR_BAND_LOW);
|
||||
+ end_freq = min_t(u32, reg_rule->end_freq, ETSI_WEATHER_RADAR_BAND_HIGH);
|
||||
+
|
||||
+ bw = ath11k_reg_adjust_bw(start_freq, end_freq, max_bw);
|
||||
+ if (bw > 0) {
|
||||
+ i++;
|
||||
+
|
||||
+ ath11k_reg_update_rule(regd->reg_rules + i, start_freq,
|
||||
+ end_freq, bw, reg_rule->ant_gain,
|
||||
+ reg_rule->reg_power, flags);
|
||||
+
|
||||
+ regd->reg_rules[i].dfs_cac_ms = ETSI_WEATHER_RADAR_BAND_CAC_TIMEOUT;
|
||||
+
|
||||
+ ath11k_dbg(ab, ATH11K_DBG_REG,
|
||||
+ "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d)\n",
|
||||
+ i + 1, start_freq, end_freq, bw,
|
||||
+ reg_rule->ant_gain, reg_rule->reg_power,
|
||||
+ regd->reg_rules[i].dfs_cac_ms, flags);
|
||||
}
|
||||
|
||||
+ /* frequencies above weather radar */
|
||||
bw = ath11k_reg_adjust_bw(ETSI_WEATHER_RADAR_BAND_HIGH,
|
||||
reg_rule->end_freq, max_bw);
|
||||
+ if (bw > 0) {
|
||||
+ i++;
|
||||
|
||||
- i++;
|
||||
-
|
||||
- ath11k_reg_update_rule(regd->reg_rules + i, ETSI_WEATHER_RADAR_BAND_HIGH,
|
||||
- reg_rule->end_freq, bw,
|
||||
- reg_rule->ant_gain, reg_rule->reg_power,
|
||||
- flags);
|
||||
-
|
||||
- ath11k_dbg(ab, ATH11K_DBG_REG,
|
||||
- "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d)\n",
|
||||
- i + 1, ETSI_WEATHER_RADAR_BAND_HIGH, reg_rule->end_freq,
|
||||
- bw, reg_rule->ant_gain, reg_rule->reg_power,
|
||||
- regd->reg_rules[i].dfs_cac_ms,
|
||||
- flags);
|
||||
+ ath11k_reg_update_rule(regd->reg_rules + i,
|
||||
+ ETSI_WEATHER_RADAR_BAND_HIGH,
|
||||
+ reg_rule->end_freq, bw,
|
||||
+ reg_rule->ant_gain, reg_rule->reg_power,
|
||||
+ flags);
|
||||
+
|
||||
+ ath11k_dbg(ab, ATH11K_DBG_REG,
|
||||
+ "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d)\n",
|
||||
+ i + 1, ETSI_WEATHER_RADAR_BAND_HIGH,
|
||||
+ reg_rule->end_freq, bw, reg_rule->ant_gain,
|
||||
+ reg_rule->reg_power, regd->reg_rules[i].dfs_cac_ms,
|
||||
+ flags);
|
||||
+ }
|
||||
|
||||
*rule_idx = i;
|
||||
}
|
@ -0,0 +1,499 @@
|
||||
From f951380a6022440335f668f85296096ba13071ba Mon Sep 17 00:00:00 2001
|
||||
From: P Praneesh <quic_ppranees@quicinc.com>
|
||||
Date: Mon, 15 Nov 2021 11:50:52 +0200
|
||||
Subject: [PATCH 094/120] ath11k: Disabling credit flow for WMI path
|
||||
|
||||
Firmware credit flow control is enabled for WMI control services,
|
||||
which expects available tokens should be acquired before sending a
|
||||
command to the target. Also the token gets released when firmware
|
||||
receives the command.
|
||||
|
||||
This credit-based flow limits driver to send WMI command only
|
||||
when the token available which is causing WMI commands to timeout and
|
||||
return -EAGAIN, whereas firmware has enough capability to process the
|
||||
WMI command. To fix this Tx starvation issue, introduce the ability to
|
||||
disable the credit flow for the WMI path.
|
||||
|
||||
The driver sends WMI configuration for disabling credit flow to firmware
|
||||
by two ways.
|
||||
1. By using a global flag
|
||||
(HTC_MSG_SETUP_COMPLETE_EX_ID msg type flags)
|
||||
2. By using a local flag
|
||||
(ATH11K_HTC_CONN_FLAGS_DISABLE_CREDIT_FLOW_CTRL = 1 << 3)
|
||||
|
||||
Ath11k uses both these configurations to disable credit flow for the
|
||||
WMI path completely.
|
||||
|
||||
Also added a hw_param member for credit flow control by which we can
|
||||
enable or disable it based on per-target basis. Currently we are disabling
|
||||
credit flow for IPQ8074, IPQ6018, and QCN9074 as recommended by firmware.
|
||||
|
||||
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-01492-QCAHKSWPL_SILICONZ-1
|
||||
Tested-on: IPQ6018 hw1.0 AHB WLAN.HK.2.4.0.1-00330-QCAHKSWPL_SILICONZ-1
|
||||
|
||||
Co-developed-by: Pravas Kumar Panda <kumarpan@codeaurora.org>
|
||||
Signed-off-by: Pravas Kumar Panda <kumarpan@codeaurora.org>
|
||||
Signed-off-by: P Praneesh <quic_ppranees@quicinc.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/1635156494-20059-1-git-send-email-quic_ppranees@quicinc.com
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/ce.c | 37 +++++++++++---
|
||||
drivers/net/wireless/ath/ath11k/ce.h | 3 +-
|
||||
drivers/net/wireless/ath/ath11k/core.c | 5 ++
|
||||
drivers/net/wireless/ath/ath11k/htc.c | 71 +++++++++++++++++++-------
|
||||
drivers/net/wireless/ath/ath11k/htc.h | 9 ++--
|
||||
drivers/net/wireless/ath/ath11k/hw.h | 1 +
|
||||
drivers/net/wireless/ath/ath11k/wmi.c | 54 +++++++++++++++++---
|
||||
drivers/net/wireless/ath/ath11k/wmi.h | 1 +
|
||||
8 files changed, 146 insertions(+), 35 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/ce.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/ce.c
|
||||
@@ -14,6 +14,7 @@ const struct ce_attr ath11k_host_ce_conf
|
||||
.src_nentries = 16,
|
||||
.src_sz_max = 2048,
|
||||
.dest_nentries = 0,
|
||||
+ .send_cb = ath11k_htc_tx_completion_handler,
|
||||
},
|
||||
|
||||
/* CE1: target->host HTT + HTC control */
|
||||
@@ -40,6 +41,7 @@ const struct ce_attr ath11k_host_ce_conf
|
||||
.src_nentries = 32,
|
||||
.src_sz_max = 2048,
|
||||
.dest_nentries = 0,
|
||||
+ .send_cb = ath11k_htc_tx_completion_handler,
|
||||
},
|
||||
|
||||
/* CE4: host->target HTT */
|
||||
@@ -73,6 +75,7 @@ const struct ce_attr ath11k_host_ce_conf
|
||||
.src_nentries = 32,
|
||||
.src_sz_max = 2048,
|
||||
.dest_nentries = 0,
|
||||
+ .send_cb = ath11k_htc_tx_completion_handler,
|
||||
},
|
||||
|
||||
/* CE8: target autonomous hif_memcpy */
|
||||
@@ -89,6 +92,7 @@ const struct ce_attr ath11k_host_ce_conf
|
||||
.src_nentries = 32,
|
||||
.src_sz_max = 2048,
|
||||
.dest_nentries = 0,
|
||||
+ .send_cb = ath11k_htc_tx_completion_handler,
|
||||
},
|
||||
|
||||
/* CE10: target->host HTT */
|
||||
@@ -142,6 +146,7 @@ const struct ce_attr ath11k_host_ce_conf
|
||||
.src_nentries = 32,
|
||||
.src_sz_max = 2048,
|
||||
.dest_nentries = 0,
|
||||
+ .send_cb = ath11k_htc_tx_completion_handler,
|
||||
},
|
||||
|
||||
/* CE4: host->target HTT */
|
||||
@@ -175,6 +180,7 @@ const struct ce_attr ath11k_host_ce_conf
|
||||
.src_nentries = 32,
|
||||
.src_sz_max = 2048,
|
||||
.dest_nentries = 0,
|
||||
+ .send_cb = ath11k_htc_tx_completion_handler,
|
||||
},
|
||||
|
||||
/* CE8: target autonomous hif_memcpy */
|
||||
@@ -220,6 +226,7 @@ const struct ce_attr ath11k_host_ce_conf
|
||||
.src_nentries = 32,
|
||||
.src_sz_max = 2048,
|
||||
.dest_nentries = 0,
|
||||
+ .send_cb = ath11k_htc_tx_completion_handler,
|
||||
},
|
||||
|
||||
/* CE4: host->target HTT */
|
||||
@@ -489,18 +496,32 @@ err_unlock:
|
||||
return skb;
|
||||
}
|
||||
|
||||
-static void ath11k_ce_send_done_cb(struct ath11k_ce_pipe *pipe)
|
||||
+static void ath11k_ce_tx_process_cb(struct ath11k_ce_pipe *pipe)
|
||||
{
|
||||
struct ath11k_base *ab = pipe->ab;
|
||||
struct sk_buff *skb;
|
||||
+ struct sk_buff_head list;
|
||||
|
||||
+ __skb_queue_head_init(&list);
|
||||
while (!IS_ERR(skb = ath11k_ce_completed_send_next(pipe))) {
|
||||
if (!skb)
|
||||
continue;
|
||||
|
||||
dma_unmap_single(ab->dev, ATH11K_SKB_CB(skb)->paddr, skb->len,
|
||||
DMA_TO_DEVICE);
|
||||
- dev_kfree_skb_any(skb);
|
||||
+
|
||||
+ if ((!pipe->send_cb) || ab->hw_params.credit_flow) {
|
||||
+ dev_kfree_skb_any(skb);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ __skb_queue_tail(&list, skb);
|
||||
+ }
|
||||
+
|
||||
+ while ((skb = __skb_dequeue(&list))) {
|
||||
+ ath11k_dbg(ab, ATH11K_DBG_AHB, "tx ce pipe %d len %d\n",
|
||||
+ pipe->pipe_num, skb->len);
|
||||
+ pipe->send_cb(ab, skb);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -636,7 +657,7 @@ static int ath11k_ce_alloc_pipe(struct a
|
||||
pipe->attr_flags = attr->flags;
|
||||
|
||||
if (attr->src_nentries) {
|
||||
- pipe->send_cb = ath11k_ce_send_done_cb;
|
||||
+ pipe->send_cb = attr->send_cb;
|
||||
nentries = roundup_pow_of_two(attr->src_nentries);
|
||||
desc_sz = ath11k_hal_ce_get_desc_size(HAL_CE_DESC_SRC);
|
||||
ring = ath11k_ce_alloc_ring(ab, nentries, desc_sz);
|
||||
@@ -667,9 +688,10 @@ static int ath11k_ce_alloc_pipe(struct a
|
||||
void ath11k_ce_per_engine_service(struct ath11k_base *ab, u16 ce_id)
|
||||
{
|
||||
struct ath11k_ce_pipe *pipe = &ab->ce.ce_pipe[ce_id];
|
||||
+ const struct ce_attr *attr = &ab->hw_params.host_ce_config[ce_id];
|
||||
|
||||
- if (pipe->send_cb)
|
||||
- pipe->send_cb(pipe);
|
||||
+ if (attr->src_nentries)
|
||||
+ ath11k_ce_tx_process_cb(pipe);
|
||||
|
||||
if (pipe->recv_cb)
|
||||
ath11k_ce_recv_process_cb(pipe);
|
||||
@@ -678,9 +700,10 @@ void ath11k_ce_per_engine_service(struct
|
||||
void ath11k_ce_poll_send_completed(struct ath11k_base *ab, u8 pipe_id)
|
||||
{
|
||||
struct ath11k_ce_pipe *pipe = &ab->ce.ce_pipe[pipe_id];
|
||||
+ const struct ce_attr *attr = &ab->hw_params.host_ce_config[pipe_id];
|
||||
|
||||
- if ((pipe->attr_flags & CE_ATTR_DIS_INTR) && pipe->send_cb)
|
||||
- pipe->send_cb(pipe);
|
||||
+ if ((pipe->attr_flags & CE_ATTR_DIS_INTR) && attr->src_nentries)
|
||||
+ ath11k_ce_tx_process_cb(pipe);
|
||||
}
|
||||
EXPORT_SYMBOL(ath11k_ce_per_engine_service);
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/ce.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/ce.h
|
||||
@@ -101,6 +101,7 @@ struct ce_attr {
|
||||
unsigned int dest_nentries;
|
||||
|
||||
void (*recv_cb)(struct ath11k_base *, struct sk_buff *);
|
||||
+ void (*send_cb)(struct ath11k_base *, struct sk_buff *);
|
||||
};
|
||||
|
||||
#define CE_DESC_RING_ALIGN 8
|
||||
@@ -154,7 +155,7 @@ struct ath11k_ce_pipe {
|
||||
unsigned int buf_sz;
|
||||
unsigned int rx_buf_needed;
|
||||
|
||||
- void (*send_cb)(struct ath11k_ce_pipe *);
|
||||
+ void (*send_cb)(struct ath11k_base *, struct sk_buff *);
|
||||
void (*recv_cb)(struct ath11k_base *, struct sk_buff *);
|
||||
|
||||
struct tasklet_struct intr_tq;
|
||||
--- a/drivers/net/wireless/ath/ath11k/core.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/core.c
|
||||
@@ -81,6 +81,7 @@ static const struct ath11k_hw_params ath
|
||||
.supports_suspend = false,
|
||||
.hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074),
|
||||
.fix_l1ss = true,
|
||||
+ .credit_flow = false,
|
||||
.max_tx_ring = DP_TCL_NUM_RING_MAX,
|
||||
.hal_params = &ath11k_hw_hal_params_ipq8074,
|
||||
.supports_dynamic_smps_6ghz = false,
|
||||
@@ -133,6 +134,7 @@ static const struct ath11k_hw_params ath
|
||||
.supports_suspend = false,
|
||||
.hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074),
|
||||
.fix_l1ss = true,
|
||||
+ .credit_flow = false,
|
||||
.max_tx_ring = DP_TCL_NUM_RING_MAX,
|
||||
.hal_params = &ath11k_hw_hal_params_ipq8074,
|
||||
.supports_dynamic_smps_6ghz = false,
|
||||
@@ -184,6 +186,7 @@ static const struct ath11k_hw_params ath
|
||||
.supports_suspend = true,
|
||||
.hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074),
|
||||
.fix_l1ss = true,
|
||||
+ .credit_flow = true,
|
||||
.max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390,
|
||||
.hal_params = &ath11k_hw_hal_params_qca6390,
|
||||
.supports_dynamic_smps_6ghz = false,
|
||||
@@ -235,6 +238,7 @@ static const struct ath11k_hw_params ath
|
||||
.supports_suspend = false,
|
||||
.hal_desc_sz = sizeof(struct hal_rx_desc_qcn9074),
|
||||
.fix_l1ss = true,
|
||||
+ .credit_flow = false,
|
||||
.max_tx_ring = DP_TCL_NUM_RING_MAX,
|
||||
.hal_params = &ath11k_hw_hal_params_ipq8074,
|
||||
.supports_dynamic_smps_6ghz = true,
|
||||
@@ -286,6 +290,7 @@ static const struct ath11k_hw_params ath
|
||||
.supports_suspend = true,
|
||||
.hal_desc_sz = sizeof(struct hal_rx_desc_wcn6855),
|
||||
.fix_l1ss = false,
|
||||
+ .credit_flow = true,
|
||||
.max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390,
|
||||
.hal_params = &ath11k_hw_hal_params_qca6390,
|
||||
.supports_dynamic_smps_6ghz = false,
|
||||
--- a/drivers/net/wireless/ath/ath11k/htc.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/htc.c
|
||||
@@ -81,6 +81,8 @@ int ath11k_htc_send(struct ath11k_htc *h
|
||||
struct ath11k_base *ab = htc->ab;
|
||||
int credits = 0;
|
||||
int ret;
|
||||
+ bool credit_flow_enabled = (ab->hw_params.credit_flow &&
|
||||
+ ep->tx_credit_flow_enabled);
|
||||
|
||||
if (eid >= ATH11K_HTC_EP_COUNT) {
|
||||
ath11k_warn(ab, "Invalid endpoint id: %d\n", eid);
|
||||
@@ -89,7 +91,7 @@ int ath11k_htc_send(struct ath11k_htc *h
|
||||
|
||||
skb_push(skb, sizeof(struct ath11k_htc_hdr));
|
||||
|
||||
- if (ep->tx_credit_flow_enabled) {
|
||||
+ if (credit_flow_enabled) {
|
||||
credits = DIV_ROUND_UP(skb->len, htc->target_credit_size);
|
||||
spin_lock_bh(&htc->tx_lock);
|
||||
if (ep->tx_credits < credits) {
|
||||
@@ -126,7 +128,7 @@ int ath11k_htc_send(struct ath11k_htc *h
|
||||
err_unmap:
|
||||
dma_unmap_single(dev, skb_cb->paddr, skb->len, DMA_TO_DEVICE);
|
||||
err_credits:
|
||||
- if (ep->tx_credit_flow_enabled) {
|
||||
+ if (credit_flow_enabled) {
|
||||
spin_lock_bh(&htc->tx_lock);
|
||||
ep->tx_credits += credits;
|
||||
ath11k_dbg(ab, ATH11K_DBG_HTC,
|
||||
@@ -203,23 +205,25 @@ static int ath11k_htc_process_trailer(st
|
||||
break;
|
||||
}
|
||||
|
||||
- switch (record->hdr.id) {
|
||||
- case ATH11K_HTC_RECORD_CREDITS:
|
||||
- len = sizeof(struct ath11k_htc_credit_report);
|
||||
- if (record->hdr.len < len) {
|
||||
- ath11k_warn(ab, "Credit report too long\n");
|
||||
- status = -EINVAL;
|
||||
+ if (ab->hw_params.credit_flow) {
|
||||
+ switch (record->hdr.id) {
|
||||
+ case ATH11K_HTC_RECORD_CREDITS:
|
||||
+ len = sizeof(struct ath11k_htc_credit_report);
|
||||
+ if (record->hdr.len < len) {
|
||||
+ ath11k_warn(ab, "Credit report too long\n");
|
||||
+ status = -EINVAL;
|
||||
+ break;
|
||||
+ }
|
||||
+ ath11k_htc_process_credit_report(htc,
|
||||
+ record->credit_report,
|
||||
+ record->hdr.len,
|
||||
+ src_eid);
|
||||
+ break;
|
||||
+ default:
|
||||
+ ath11k_warn(ab, "Unhandled record: id:%d length:%d\n",
|
||||
+ record->hdr.id, record->hdr.len);
|
||||
break;
|
||||
}
|
||||
- ath11k_htc_process_credit_report(htc,
|
||||
- record->credit_report,
|
||||
- record->hdr.len,
|
||||
- src_eid);
|
||||
- break;
|
||||
- default:
|
||||
- ath11k_warn(ab, "Unhandled record: id:%d length:%d\n",
|
||||
- record->hdr.id, record->hdr.len);
|
||||
- break;
|
||||
}
|
||||
|
||||
if (status)
|
||||
@@ -245,6 +249,29 @@ static void ath11k_htc_suspend_complete(
|
||||
complete(&ab->htc_suspend);
|
||||
}
|
||||
|
||||
+void ath11k_htc_tx_completion_handler(struct ath11k_base *ab,
|
||||
+ struct sk_buff *skb)
|
||||
+{
|
||||
+ struct ath11k_htc *htc = &ab->htc;
|
||||
+ struct ath11k_htc_ep *ep;
|
||||
+ void (*ep_tx_complete)(struct ath11k_base *, struct sk_buff *);
|
||||
+ u8 eid;
|
||||
+
|
||||
+ eid = ATH11K_SKB_CB(skb)->eid;
|
||||
+ if (eid >= ATH11K_HTC_EP_COUNT)
|
||||
+ return;
|
||||
+
|
||||
+ ep = &htc->endpoint[eid];
|
||||
+ spin_lock_bh(&htc->tx_lock);
|
||||
+ ep_tx_complete = ep->ep_ops.ep_tx_complete;
|
||||
+ spin_unlock_bh(&htc->tx_lock);
|
||||
+ if (!ep_tx_complete) {
|
||||
+ dev_kfree_skb_any(skb);
|
||||
+ return;
|
||||
+ }
|
||||
+ ep_tx_complete(htc->ab, skb);
|
||||
+}
|
||||
+
|
||||
void ath11k_htc_rx_completion_handler(struct ath11k_base *ab,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
@@ -607,6 +634,11 @@ int ath11k_htc_connect_service(struct at
|
||||
disable_credit_flow_ctrl = true;
|
||||
}
|
||||
|
||||
+ if (!ab->hw_params.credit_flow) {
|
||||
+ flags |= ATH11K_HTC_CONN_FLAGS_DISABLE_CREDIT_FLOW_CTRL;
|
||||
+ disable_credit_flow_ctrl = true;
|
||||
+ }
|
||||
+
|
||||
req_msg->flags_len = FIELD_PREP(HTC_SVC_MSG_CONNECTIONFLAGS, flags);
|
||||
req_msg->msg_svc_id |= FIELD_PREP(HTC_SVC_MSG_SERVICE_ID,
|
||||
conn_req->service_id);
|
||||
@@ -732,7 +764,10 @@ int ath11k_htc_start(struct ath11k_htc *
|
||||
msg->msg_id = FIELD_PREP(HTC_MSG_MESSAGEID,
|
||||
ATH11K_HTC_MSG_SETUP_COMPLETE_EX_ID);
|
||||
|
||||
- ath11k_dbg(ab, ATH11K_DBG_HTC, "HTC is using TX credit flow control\n");
|
||||
+ if (ab->hw_params.credit_flow)
|
||||
+ ath11k_dbg(ab, ATH11K_DBG_HTC, "HTC is using TX credit flow control\n");
|
||||
+ else
|
||||
+ msg->flags |= ATH11K_GLOBAL_DISABLE_CREDIT_FLOW;
|
||||
|
||||
status = ath11k_htc_send(htc, ATH11K_HTC_EP_0, skb);
|
||||
if (status) {
|
||||
--- a/drivers/net/wireless/ath/ath11k/htc.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/htc.h
|
||||
@@ -83,8 +83,8 @@ enum ath11k_htc_conn_flags {
|
||||
ATH11K_HTC_CONN_FLAGS_THRESHOLD_LEVEL_ONE_HALF = 0x1,
|
||||
ATH11K_HTC_CONN_FLAGS_THRESHOLD_LEVEL_THREE_FOURTHS = 0x2,
|
||||
ATH11K_HTC_CONN_FLAGS_THRESHOLD_LEVEL_UNITY = 0x3,
|
||||
- ATH11K_HTC_CONN_FLAGS_REDUCE_CREDIT_DRIBBLE = 1 << 2,
|
||||
- ATH11K_HTC_CONN_FLAGS_DISABLE_CREDIT_FLOW_CTRL = 1 << 3
|
||||
+ ATH11K_HTC_CONN_FLAGS_REDUCE_CREDIT_DRIBBLE = 0x4,
|
||||
+ ATH11K_HTC_CONN_FLAGS_DISABLE_CREDIT_FLOW_CTRL = 0x8,
|
||||
};
|
||||
|
||||
enum ath11k_htc_conn_svc_status {
|
||||
@@ -116,6 +116,8 @@ struct ath11k_htc_conn_svc_resp {
|
||||
u32 svc_meta_pad;
|
||||
} __packed;
|
||||
|
||||
+#define ATH11K_GLOBAL_DISABLE_CREDIT_FLOW BIT(1)
|
||||
+
|
||||
struct ath11k_htc_setup_complete_extended {
|
||||
u32 msg_id;
|
||||
u32 flags;
|
||||
@@ -305,5 +307,6 @@ int ath11k_htc_send(struct ath11k_htc *h
|
||||
struct sk_buff *ath11k_htc_alloc_skb(struct ath11k_base *ar, int size);
|
||||
void ath11k_htc_rx_completion_handler(struct ath11k_base *ar,
|
||||
struct sk_buff *skb);
|
||||
-
|
||||
+void ath11k_htc_tx_completion_handler(struct ath11k_base *ab,
|
||||
+ struct sk_buff *skb);
|
||||
#endif
|
||||
--- a/drivers/net/wireless/ath/ath11k/hw.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/hw.h
|
||||
@@ -175,6 +175,7 @@ struct ath11k_hw_params {
|
||||
bool supports_suspend;
|
||||
u32 hal_desc_sz;
|
||||
bool fix_l1ss;
|
||||
+ bool credit_flow;
|
||||
u8 max_tx_ring;
|
||||
const struct ath11k_hw_hal_params *hal_params;
|
||||
bool supports_dynamic_smps_6ghz;
|
||||
--- a/drivers/net/wireless/ath/ath11k/wmi.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
|
||||
@@ -267,21 +267,39 @@ int ath11k_wmi_cmd_send(struct ath11k_pd
|
||||
{
|
||||
struct ath11k_wmi_base *wmi_sc = wmi->wmi_ab;
|
||||
int ret = -EOPNOTSUPP;
|
||||
+ struct ath11k_base *ab = wmi_sc->ab;
|
||||
|
||||
might_sleep();
|
||||
|
||||
- wait_event_timeout(wmi_sc->tx_credits_wq, ({
|
||||
- ret = ath11k_wmi_cmd_send_nowait(wmi, skb, cmd_id);
|
||||
+ if (ab->hw_params.credit_flow) {
|
||||
+ wait_event_timeout(wmi_sc->tx_credits_wq, ({
|
||||
+ ret = ath11k_wmi_cmd_send_nowait(wmi, skb, cmd_id);
|
||||
+
|
||||
+ if (ret && test_bit(ATH11K_FLAG_CRASH_FLUSH,
|
||||
+ &wmi_sc->ab->dev_flags))
|
||||
+ ret = -ESHUTDOWN;
|
||||
+
|
||||
+ (ret != -EAGAIN);
|
||||
+ }), WMI_SEND_TIMEOUT_HZ);
|
||||
+ } else {
|
||||
+ wait_event_timeout(wmi->tx_ce_desc_wq, ({
|
||||
+ ret = ath11k_wmi_cmd_send_nowait(wmi, skb, cmd_id);
|
||||
|
||||
- if (ret && test_bit(ATH11K_FLAG_CRASH_FLUSH, &wmi_sc->ab->dev_flags))
|
||||
- ret = -ESHUTDOWN;
|
||||
+ if (ret && test_bit(ATH11K_FLAG_CRASH_FLUSH,
|
||||
+ &wmi_sc->ab->dev_flags))
|
||||
+ ret = -ESHUTDOWN;
|
||||
|
||||
- (ret != -EAGAIN);
|
||||
- }), WMI_SEND_TIMEOUT_HZ);
|
||||
+ (ret != -ENOBUFS);
|
||||
+ }), WMI_SEND_TIMEOUT_HZ);
|
||||
+ }
|
||||
|
||||
if (ret == -EAGAIN)
|
||||
ath11k_warn(wmi_sc->ab, "wmi command %d timeout\n", cmd_id);
|
||||
|
||||
+ if (ret == -ENOBUFS)
|
||||
+ ath11k_warn(wmi_sc->ab, "ce desc not available for wmi command %d\n",
|
||||
+ cmd_id);
|
||||
+
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -5816,7 +5834,30 @@ static void ath11k_wmi_op_ep_tx_credits(
|
||||
static void ath11k_wmi_htc_tx_complete(struct ath11k_base *ab,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
+ struct ath11k_pdev_wmi *wmi = NULL;
|
||||
+ u32 i;
|
||||
+ u8 wmi_ep_count;
|
||||
+ u8 eid;
|
||||
+
|
||||
+ eid = ATH11K_SKB_CB(skb)->eid;
|
||||
dev_kfree_skb(skb);
|
||||
+
|
||||
+ if (eid >= ATH11K_HTC_EP_COUNT)
|
||||
+ return;
|
||||
+
|
||||
+ wmi_ep_count = ab->htc.wmi_ep_count;
|
||||
+ if (wmi_ep_count > ab->hw_params.max_radios)
|
||||
+ return;
|
||||
+
|
||||
+ for (i = 0; i < ab->htc.wmi_ep_count; i++) {
|
||||
+ if (ab->wmi_ab.wmi[i].eid == eid) {
|
||||
+ wmi = &ab->wmi_ab.wmi[i];
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (wmi)
|
||||
+ wake_up(&wmi->tx_ce_desc_wq);
|
||||
}
|
||||
|
||||
static bool ath11k_reg_is_world_alpha(char *alpha)
|
||||
@@ -7207,6 +7248,7 @@ static int ath11k_connect_pdev_htc_servi
|
||||
ab->wmi_ab.wmi_endpoint_id[pdev_idx] = conn_resp.eid;
|
||||
ab->wmi_ab.wmi[pdev_idx].eid = conn_resp.eid;
|
||||
ab->wmi_ab.max_msg_len[pdev_idx] = conn_resp.max_msg_len;
|
||||
+ init_waitqueue_head(&ab->wmi_ab.wmi[pdev_idx].tx_ce_desc_wq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
--- a/drivers/net/wireless/ath/ath11k/wmi.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/wmi.h
|
||||
@@ -2522,6 +2522,7 @@ struct ath11k_pdev_wmi {
|
||||
enum ath11k_htc_ep_id eid;
|
||||
const struct wmi_peer_flags_map *peer_flags;
|
||||
u32 rx_decap_mode;
|
||||
+ wait_queue_head_t tx_ce_desc_wq;
|
||||
};
|
||||
|
||||
struct vdev_create_params {
|
@ -0,0 +1,91 @@
|
||||
From bd77f6b1d7104cf6451399a7c67d08afecb9a7c7 Mon Sep 17 00:00:00 2001
|
||||
From: Rameshkumar Sundaram <quic_ramess@quicinc.com>
|
||||
Date: Tue, 2 Nov 2021 11:11:33 +0530
|
||||
Subject: [PATCH 095/120] ath11k: use cache line aligned buffers for dbring
|
||||
|
||||
The DMA buffers of dbring which is used for spectral/cfr
|
||||
starts at certain offset from original kmalloc() returned buffer.
|
||||
This is not cache line aligned.
|
||||
And also driver tries to access the data that is immediately before
|
||||
this offset address (i.e. buff->paddr) after doing dma map.
|
||||
This will cause cache line sharing issues and data corruption,
|
||||
if CPU happen to write back cache after HW has dma'ed the data.
|
||||
|
||||
Fix this by mapping a cache line aligned buffer to dma.
|
||||
|
||||
Tested on: IPQ8074 hw2.0 AHB WLAN.HK.2.5.0.1-01100-QCAHKSWPL_SILICONZ-1
|
||||
|
||||
Signed-off-by: Rameshkumar Sundaram <quic_ramess@quicinc.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/1635831693-15962-1-git-send-email-quic_ramess@quicinc.com
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/dbring.c | 16 ++++++++++++----
|
||||
drivers/net/wireless/ath/ath11k/dbring.h | 2 +-
|
||||
2 files changed, 13 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/dbring.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dbring.c
|
||||
@@ -87,17 +87,23 @@ static int ath11k_dbring_fill_bufs(struc
|
||||
req_entries = min(num_free, ring->bufs_max);
|
||||
num_remain = req_entries;
|
||||
align = ring->buf_align;
|
||||
- size = sizeof(*buff) + ring->buf_sz + align - 1;
|
||||
+ size = ring->buf_sz + align - 1;
|
||||
|
||||
while (num_remain > 0) {
|
||||
- buff = kzalloc(size, GFP_ATOMIC);
|
||||
+ buff = kzalloc(sizeof(*buff), GFP_ATOMIC);
|
||||
if (!buff)
|
||||
break;
|
||||
|
||||
+ buff->payload = kzalloc(size, GFP_ATOMIC);
|
||||
+ if (!buff->payload) {
|
||||
+ kfree(buff);
|
||||
+ break;
|
||||
+ }
|
||||
ret = ath11k_dbring_bufs_replenish(ar, ring, buff);
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab, "failed to replenish db ring num_remain %d req_ent %d\n",
|
||||
num_remain, req_entries);
|
||||
+ kfree(buff->payload);
|
||||
kfree(buff);
|
||||
break;
|
||||
}
|
||||
@@ -282,7 +288,7 @@ int ath11k_dbring_buffer_release_event(s
|
||||
|
||||
srng = &ab->hal.srng_list[ring->refill_srng.ring_id];
|
||||
num_entry = ev->fixed.num_buf_release_entry;
|
||||
- size = sizeof(*buff) + ring->buf_sz + ring->buf_align - 1;
|
||||
+ size = ring->buf_sz + ring->buf_align - 1;
|
||||
num_buff_reaped = 0;
|
||||
|
||||
spin_lock_bh(&srng->lock);
|
||||
@@ -319,7 +325,8 @@ int ath11k_dbring_buffer_release_event(s
|
||||
ring->handler(ar, &handler_data);
|
||||
}
|
||||
|
||||
- memset(buff, 0, size);
|
||||
+ buff->paddr = 0;
|
||||
+ memset(buff->payload, 0, size);
|
||||
ath11k_dbring_bufs_replenish(ar, ring, buff);
|
||||
}
|
||||
|
||||
@@ -346,6 +353,7 @@ void ath11k_dbring_buf_cleanup(struct at
|
||||
idr_remove(&ring->bufs_idr, buf_id);
|
||||
dma_unmap_single(ar->ab->dev, buff->paddr,
|
||||
ring->buf_sz, DMA_FROM_DEVICE);
|
||||
+ kfree(buff->payload);
|
||||
kfree(buff);
|
||||
}
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/dbring.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dbring.h
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
struct ath11k_dbring_element {
|
||||
dma_addr_t paddr;
|
||||
- u8 payload[0];
|
||||
+ u8 *payload;
|
||||
};
|
||||
|
||||
struct ath11k_dbring_data {
|
@ -0,0 +1,142 @@
|
||||
From 1ad6e4b00f29d017b196dda7ab96d1cfcbabd7d2 Mon Sep 17 00:00:00 2001
|
||||
From: Anilkumar Kolli <akolli@codeaurora.org>
|
||||
Date: Tue, 2 Nov 2021 18:22:38 +0530
|
||||
Subject: [PATCH 096/120] ath11k: Add missing qmi_txn_cancel()
|
||||
|
||||
Currently many functions do not follow this guidance when
|
||||
qmi_send_request() fails, therefore add missing
|
||||
qmi_txn_cancel() in the qmi_send_request() error path.
|
||||
|
||||
Also remove initialization on 'struct qmi_txn'
|
||||
since qmi_tx_init() performs all necessary initialization.
|
||||
|
||||
Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.4.0.1-01838-QCAHKSWPL_SILICONZ-1
|
||||
|
||||
Signed-off-by: Anilkumar Kolli <akolli@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/1635857558-21733-1-git-send-email-akolli@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/qmi.c | 21 ++++++++++++++-------
|
||||
1 file changed, 14 insertions(+), 7 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/qmi.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/qmi.c
|
||||
@@ -1586,7 +1586,7 @@ static int ath11k_qmi_host_cap_send(stru
|
||||
{
|
||||
struct qmi_wlanfw_host_cap_req_msg_v01 req;
|
||||
struct qmi_wlanfw_host_cap_resp_msg_v01 resp;
|
||||
- struct qmi_txn txn = {};
|
||||
+ struct qmi_txn txn;
|
||||
int ret = 0;
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
@@ -1640,6 +1640,7 @@ static int ath11k_qmi_host_cap_send(stru
|
||||
QMI_WLANFW_HOST_CAP_REQ_MSG_V01_MAX_LEN,
|
||||
qmi_wlanfw_host_cap_req_msg_v01_ei, &req);
|
||||
if (ret < 0) {
|
||||
+ qmi_txn_cancel(&txn);
|
||||
ath11k_warn(ab, "failed to send host capability request: %d\n", ret);
|
||||
goto out;
|
||||
}
|
||||
@@ -1705,6 +1706,7 @@ static int ath11k_qmi_fw_ind_register_se
|
||||
QMI_WLANFW_IND_REGISTER_REQ_MSG_V01_MAX_LEN,
|
||||
qmi_wlanfw_ind_register_req_msg_v01_ei, req);
|
||||
if (ret < 0) {
|
||||
+ qmi_txn_cancel(&txn);
|
||||
ath11k_warn(ab, "failed to send indication register request: %d\n",
|
||||
ret);
|
||||
goto out;
|
||||
@@ -1734,7 +1736,7 @@ static int ath11k_qmi_respond_fw_mem_req
|
||||
{
|
||||
struct qmi_wlanfw_respond_mem_req_msg_v01 *req;
|
||||
struct qmi_wlanfw_respond_mem_resp_msg_v01 resp;
|
||||
- struct qmi_txn txn = {};
|
||||
+ struct qmi_txn txn;
|
||||
int ret = 0, i;
|
||||
bool delayed;
|
||||
|
||||
@@ -1783,6 +1785,7 @@ static int ath11k_qmi_respond_fw_mem_req
|
||||
QMI_WLANFW_RESPOND_MEM_REQ_MSG_V01_MAX_LEN,
|
||||
qmi_wlanfw_respond_mem_req_msg_v01_ei, req);
|
||||
if (ret < 0) {
|
||||
+ qmi_txn_cancel(&txn);
|
||||
ath11k_warn(ab, "failed to respond qmi memory request: %d\n",
|
||||
ret);
|
||||
goto out;
|
||||
@@ -1911,7 +1914,7 @@ static int ath11k_qmi_request_target_cap
|
||||
{
|
||||
struct qmi_wlanfw_cap_req_msg_v01 req;
|
||||
struct qmi_wlanfw_cap_resp_msg_v01 resp;
|
||||
- struct qmi_txn txn = {};
|
||||
+ struct qmi_txn txn;
|
||||
int ret = 0;
|
||||
int r;
|
||||
|
||||
@@ -1930,6 +1933,7 @@ static int ath11k_qmi_request_target_cap
|
||||
QMI_WLANFW_CAP_REQ_MSG_V01_MAX_LEN,
|
||||
qmi_wlanfw_cap_req_msg_v01_ei, &req);
|
||||
if (ret < 0) {
|
||||
+ qmi_txn_cancel(&txn);
|
||||
ath11k_warn(ab, "failed to send qmi cap request: %d\n",
|
||||
ret);
|
||||
goto out;
|
||||
@@ -2000,7 +2004,7 @@ static int ath11k_qmi_load_file_target_m
|
||||
{
|
||||
struct qmi_wlanfw_bdf_download_req_msg_v01 *req;
|
||||
struct qmi_wlanfw_bdf_download_resp_msg_v01 resp;
|
||||
- struct qmi_txn txn = {};
|
||||
+ struct qmi_txn txn;
|
||||
const u8 *temp = data;
|
||||
void __iomem *bdf_addr = NULL;
|
||||
int ret;
|
||||
@@ -2245,7 +2249,7 @@ static int ath11k_qmi_wlanfw_m3_info_sen
|
||||
struct m3_mem_region *m3_mem = &ab->qmi.m3_mem;
|
||||
struct qmi_wlanfw_m3_info_req_msg_v01 req;
|
||||
struct qmi_wlanfw_m3_info_resp_msg_v01 resp;
|
||||
- struct qmi_txn txn = {};
|
||||
+ struct qmi_txn txn;
|
||||
int ret = 0;
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
@@ -2277,6 +2281,7 @@ static int ath11k_qmi_wlanfw_m3_info_sen
|
||||
QMI_WLANFW_M3_INFO_REQ_MSG_V01_MAX_MSG_LEN,
|
||||
qmi_wlanfw_m3_info_req_msg_v01_ei, &req);
|
||||
if (ret < 0) {
|
||||
+ qmi_txn_cancel(&txn);
|
||||
ath11k_warn(ab, "failed to send m3 information request: %d\n",
|
||||
ret);
|
||||
goto out;
|
||||
@@ -2303,7 +2308,7 @@ static int ath11k_qmi_wlanfw_mode_send(s
|
||||
{
|
||||
struct qmi_wlanfw_wlan_mode_req_msg_v01 req;
|
||||
struct qmi_wlanfw_wlan_mode_resp_msg_v01 resp;
|
||||
- struct qmi_txn txn = {};
|
||||
+ struct qmi_txn txn;
|
||||
int ret = 0;
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
@@ -2325,6 +2330,7 @@ static int ath11k_qmi_wlanfw_mode_send(s
|
||||
QMI_WLANFW_WLAN_MODE_REQ_MSG_V01_MAX_LEN,
|
||||
qmi_wlanfw_wlan_mode_req_msg_v01_ei, &req);
|
||||
if (ret < 0) {
|
||||
+ qmi_txn_cancel(&txn);
|
||||
ath11k_warn(ab, "failed to send wlan mode request (mode %d): %d\n",
|
||||
mode, ret);
|
||||
goto out;
|
||||
@@ -2358,7 +2364,7 @@ static int ath11k_qmi_wlanfw_wlan_cfg_se
|
||||
struct qmi_wlanfw_wlan_cfg_resp_msg_v01 resp;
|
||||
struct ce_pipe_config *ce_cfg;
|
||||
struct service_to_pipe *svc_cfg;
|
||||
- struct qmi_txn txn = {};
|
||||
+ struct qmi_txn txn;
|
||||
int ret = 0, pipe_num;
|
||||
|
||||
ce_cfg = (struct ce_pipe_config *)ab->qmi.ce_cfg.tgt_ce;
|
||||
@@ -2419,6 +2425,7 @@ static int ath11k_qmi_wlanfw_wlan_cfg_se
|
||||
QMI_WLANFW_WLAN_CFG_REQ_MSG_V01_MAX_LEN,
|
||||
qmi_wlanfw_wlan_cfg_req_msg_v01_ei, req);
|
||||
if (ret < 0) {
|
||||
+ qmi_txn_cancel(&txn);
|
||||
ath11k_warn(ab, "failed to send wlan config request: %d\n",
|
||||
ret);
|
||||
goto out;
|
@ -0,0 +1,309 @@
|
||||
From fb12305aff12e735e599c79514dde5dac40f5a59 Mon Sep 17 00:00:00 2001
|
||||
From: Venkateswara Naralasetty <quic_vnaralas@quicinc.com>
|
||||
Date: Tue, 9 Nov 2021 12:05:55 +0530
|
||||
Subject: [PATCH 097/120] ath11k: add trace log support
|
||||
|
||||
This change is to add trace log support for,
|
||||
* WMI events
|
||||
* WMI commands
|
||||
* ath11k_dbg messages
|
||||
* ath11k_dbg_dump messages
|
||||
* ath11k_log_info messages
|
||||
* ath11k_log_warn messages
|
||||
* ath11k_log_err messages
|
||||
|
||||
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.5.0.1-00652-QCAHKSWPL_SILICONZ-1
|
||||
|
||||
Signed-off-by: Venkateswara Naralasetty <quic_vnaralas@quicinc.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/1636439755-30419-1-git-send-email-quic_vnaralas@quicinc.com
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/debug.c | 12 +-
|
||||
drivers/net/wireless/ath/ath11k/debug.h | 3 +-
|
||||
drivers/net/wireless/ath/ath11k/trace.c | 1 +
|
||||
drivers/net/wireless/ath/ath11k/trace.h | 172 ++++++++++++++++++++++++
|
||||
drivers/net/wireless/ath/ath11k/wmi.c | 4 +
|
||||
5 files changed, 187 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/debug.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/debug.c
|
||||
@@ -17,7 +17,7 @@ void ath11k_info(struct ath11k_base *ab,
|
||||
va_start(args, fmt);
|
||||
vaf.va = &args;
|
||||
dev_info(ab->dev, "%pV", &vaf);
|
||||
- /* TODO: Trace the log */
|
||||
+ trace_ath11k_log_info(ab, &vaf);
|
||||
va_end(args);
|
||||
}
|
||||
EXPORT_SYMBOL(ath11k_info);
|
||||
@@ -32,7 +32,7 @@ void ath11k_err(struct ath11k_base *ab,
|
||||
va_start(args, fmt);
|
||||
vaf.va = &args;
|
||||
dev_err(ab->dev, "%pV", &vaf);
|
||||
- /* TODO: Trace the log */
|
||||
+ trace_ath11k_log_err(ab, &vaf);
|
||||
va_end(args);
|
||||
}
|
||||
EXPORT_SYMBOL(ath11k_err);
|
||||
@@ -47,7 +47,7 @@ void ath11k_warn(struct ath11k_base *ab,
|
||||
va_start(args, fmt);
|
||||
vaf.va = &args;
|
||||
dev_warn_ratelimited(ab->dev, "%pV", &vaf);
|
||||
- /* TODO: Trace the log */
|
||||
+ trace_ath11k_log_warn(ab, &vaf);
|
||||
va_end(args);
|
||||
}
|
||||
EXPORT_SYMBOL(ath11k_warn);
|
||||
@@ -68,7 +68,7 @@ void __ath11k_dbg(struct ath11k_base *ab
|
||||
if (ath11k_debug_mask & mask)
|
||||
dev_printk(KERN_DEBUG, ab->dev, "%pV", &vaf);
|
||||
|
||||
- /* TODO: trace log */
|
||||
+ trace_ath11k_log_dbg(ab, mask, &vaf);
|
||||
|
||||
va_end(args);
|
||||
}
|
||||
@@ -100,6 +100,10 @@ void ath11k_dbg_dump(struct ath11k_base
|
||||
dev_printk(KERN_DEBUG, ab->dev, "%s\n", linebuf);
|
||||
}
|
||||
}
|
||||
+
|
||||
+ /* tracing code doesn't like null strings */
|
||||
+ trace_ath11k_log_dbg_dump(ab, msg ? msg : "", prefix ? prefix : "",
|
||||
+ buf, len);
|
||||
}
|
||||
EXPORT_SYMBOL(ath11k_dbg_dump);
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/debug.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/debug.h
|
||||
@@ -60,7 +60,8 @@ static inline void ath11k_dbg_dump(struc
|
||||
|
||||
#define ath11k_dbg(ar, dbg_mask, fmt, ...) \
|
||||
do { \
|
||||
- if (ath11k_debug_mask & dbg_mask) \
|
||||
+ if ((ath11k_debug_mask & dbg_mask) || \
|
||||
+ trace_ath11k_log_dbg_enabled()) \
|
||||
__ath11k_dbg(ar, dbg_mask, fmt, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/trace.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/trace.c
|
||||
@@ -7,3 +7,4 @@
|
||||
|
||||
#define CREATE_TRACE_POINTS
|
||||
#include "trace.h"
|
||||
+EXPORT_SYMBOL(__tracepoint_ath11k_log_dbg);
|
||||
--- a/drivers/net/wireless/ath/ath11k/trace.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/trace.h
|
||||
@@ -14,12 +14,24 @@
|
||||
#if !defined(CPTCFG_ATH11K_TRACING)
|
||||
#undef TRACE_EVENT
|
||||
#define TRACE_EVENT(name, proto, ...) \
|
||||
+static inline void trace_ ## name(proto) {} \
|
||||
+static inline bool trace_##name##_enabled(void) \
|
||||
+{ \
|
||||
+ return false; \
|
||||
+}
|
||||
+
|
||||
+#undef DECLARE_EVENT_CLASS
|
||||
+#define DECLARE_EVENT_CLASS(...)
|
||||
+#undef DEFINE_EVENT
|
||||
+#define DEFINE_EVENT(evt_class, name, proto, ...) \
|
||||
static inline void trace_ ## name(proto) {}
|
||||
#endif /* !CPTCFG_ATH11K_TRACING || __CHECKER__ */
|
||||
|
||||
#undef TRACE_SYSTEM
|
||||
#define TRACE_SYSTEM ath11k
|
||||
|
||||
+#define ATH11K_MSG_MAX 400
|
||||
+
|
||||
TRACE_EVENT(ath11k_htt_pktlog,
|
||||
TP_PROTO(struct ath11k *ar, const void *buf, u16 buf_len,
|
||||
u32 pktlog_checksum),
|
||||
@@ -108,6 +120,166 @@ TRACE_EVENT(ath11k_htt_rxdesc,
|
||||
)
|
||||
);
|
||||
|
||||
+DECLARE_EVENT_CLASS(ath11k_log_event,
|
||||
+ TP_PROTO(struct ath11k_base *ab, struct va_format *vaf),
|
||||
+ TP_ARGS(ab, vaf),
|
||||
+ TP_STRUCT__entry(
|
||||
+ __string(device, dev_name(ab->dev))
|
||||
+ __string(driver, dev_driver_string(ab->dev))
|
||||
+ __dynamic_array(char, msg, ATH11K_MSG_MAX)
|
||||
+ ),
|
||||
+ TP_fast_assign(
|
||||
+ __assign_str(device, dev_name(ab->dev));
|
||||
+ __assign_str(driver, dev_driver_string(ab->dev));
|
||||
+ WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg),
|
||||
+ ATH11K_MSG_MAX,
|
||||
+ vaf->fmt,
|
||||
+ *vaf->va) >= ATH11K_MSG_MAX);
|
||||
+ ),
|
||||
+ TP_printk(
|
||||
+ "%s %s %s",
|
||||
+ __get_str(driver),
|
||||
+ __get_str(device),
|
||||
+ __get_str(msg)
|
||||
+ )
|
||||
+);
|
||||
+
|
||||
+DEFINE_EVENT(ath11k_log_event, ath11k_log_err,
|
||||
+ TP_PROTO(struct ath11k_base *ab, struct va_format *vaf),
|
||||
+ TP_ARGS(ab, vaf)
|
||||
+);
|
||||
+
|
||||
+DEFINE_EVENT(ath11k_log_event, ath11k_log_warn,
|
||||
+ TP_PROTO(struct ath11k_base *ab, struct va_format *vaf),
|
||||
+ TP_ARGS(ab, vaf)
|
||||
+);
|
||||
+
|
||||
+DEFINE_EVENT(ath11k_log_event, ath11k_log_info,
|
||||
+ TP_PROTO(struct ath11k_base *ab, struct va_format *vaf),
|
||||
+ TP_ARGS(ab, vaf)
|
||||
+);
|
||||
+
|
||||
+TRACE_EVENT(ath11k_wmi_cmd,
|
||||
+ TP_PROTO(struct ath11k_base *ab, int id, const void *buf, size_t buf_len),
|
||||
+
|
||||
+ TP_ARGS(ab, id, buf, buf_len),
|
||||
+
|
||||
+ TP_STRUCT__entry(
|
||||
+ __string(device, dev_name(ab->dev))
|
||||
+ __string(driver, dev_driver_string(ab->dev))
|
||||
+ __field(unsigned int, id)
|
||||
+ __field(size_t, buf_len)
|
||||
+ __dynamic_array(u8, buf, buf_len)
|
||||
+ ),
|
||||
+
|
||||
+ TP_fast_assign(
|
||||
+ __assign_str(device, dev_name(ab->dev));
|
||||
+ __assign_str(driver, dev_driver_string(ab->dev));
|
||||
+ __entry->id = id;
|
||||
+ __entry->buf_len = buf_len;
|
||||
+ memcpy(__get_dynamic_array(buf), buf, buf_len);
|
||||
+ ),
|
||||
+
|
||||
+ TP_printk(
|
||||
+ "%s %s id %d len %zu",
|
||||
+ __get_str(driver),
|
||||
+ __get_str(device),
|
||||
+ __entry->id,
|
||||
+ __entry->buf_len
|
||||
+ )
|
||||
+);
|
||||
+
|
||||
+TRACE_EVENT(ath11k_wmi_event,
|
||||
+ TP_PROTO(struct ath11k_base *ab, int id, const void *buf, size_t buf_len),
|
||||
+
|
||||
+ TP_ARGS(ab, id, buf, buf_len),
|
||||
+
|
||||
+ TP_STRUCT__entry(
|
||||
+ __string(device, dev_name(ab->dev))
|
||||
+ __string(driver, dev_driver_string(ab->dev))
|
||||
+ __field(unsigned int, id)
|
||||
+ __field(size_t, buf_len)
|
||||
+ __dynamic_array(u8, buf, buf_len)
|
||||
+ ),
|
||||
+
|
||||
+ TP_fast_assign(
|
||||
+ __assign_str(device, dev_name(ab->dev));
|
||||
+ __assign_str(driver, dev_driver_string(ab->dev));
|
||||
+ __entry->id = id;
|
||||
+ __entry->buf_len = buf_len;
|
||||
+ memcpy(__get_dynamic_array(buf), buf, buf_len);
|
||||
+ ),
|
||||
+
|
||||
+ TP_printk(
|
||||
+ "%s %s id %d len %zu",
|
||||
+ __get_str(driver),
|
||||
+ __get_str(device),
|
||||
+ __entry->id,
|
||||
+ __entry->buf_len
|
||||
+ )
|
||||
+);
|
||||
+
|
||||
+TRACE_EVENT(ath11k_log_dbg,
|
||||
+ TP_PROTO(struct ath11k_base *ab, unsigned int level, struct va_format *vaf),
|
||||
+
|
||||
+ TP_ARGS(ab, level, vaf),
|
||||
+
|
||||
+ TP_STRUCT__entry(
|
||||
+ __string(device, dev_name(ab->dev))
|
||||
+ __string(driver, dev_driver_string(ab->dev))
|
||||
+ __field(unsigned int, level)
|
||||
+ __dynamic_array(char, msg, ATH11K_MSG_MAX)
|
||||
+ ),
|
||||
+
|
||||
+ TP_fast_assign(
|
||||
+ __assign_str(device, dev_name(ab->dev));
|
||||
+ __assign_str(driver, dev_driver_string(ab->dev));
|
||||
+ __entry->level = level;
|
||||
+ WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg),
|
||||
+ ATH11K_MSG_MAX, vaf->fmt,
|
||||
+ *vaf->va) >= ATH11K_MSG_MAX);
|
||||
+ ),
|
||||
+
|
||||
+ TP_printk(
|
||||
+ "%s %s %s",
|
||||
+ __get_str(driver),
|
||||
+ __get_str(device),
|
||||
+ __get_str(msg)
|
||||
+ )
|
||||
+);
|
||||
+
|
||||
+TRACE_EVENT(ath11k_log_dbg_dump,
|
||||
+ TP_PROTO(struct ath11k_base *ab, const char *msg, const char *prefix,
|
||||
+ const void *buf, size_t buf_len),
|
||||
+
|
||||
+ TP_ARGS(ab, msg, prefix, buf, buf_len),
|
||||
+
|
||||
+ TP_STRUCT__entry(
|
||||
+ __string(device, dev_name(ab->dev))
|
||||
+ __string(driver, dev_driver_string(ab->dev))
|
||||
+ __string(msg, msg)
|
||||
+ __string(prefix, prefix)
|
||||
+ __field(size_t, buf_len)
|
||||
+ __dynamic_array(u8, buf, buf_len)
|
||||
+ ),
|
||||
+
|
||||
+ TP_fast_assign(
|
||||
+ __assign_str(device, dev_name(ab->dev));
|
||||
+ __assign_str(driver, dev_driver_string(ab->dev));
|
||||
+ __assign_str(msg, msg);
|
||||
+ __assign_str(prefix, prefix);
|
||||
+ __entry->buf_len = buf_len;
|
||||
+ memcpy(__get_dynamic_array(buf), buf, buf_len);
|
||||
+ ),
|
||||
+
|
||||
+ TP_printk(
|
||||
+ "%s %s %s/%s\n",
|
||||
+ __get_str(driver),
|
||||
+ __get_str(device),
|
||||
+ __get_str(prefix),
|
||||
+ __get_str(msg)
|
||||
+ )
|
||||
+);
|
||||
#endif /* _TRACE_H_ || TRACE_HEADER_MULTI_READ*/
|
||||
|
||||
/* we don't want to use include/trace/events */
|
||||
--- a/drivers/net/wireless/ath/ath11k/wmi.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
|
||||
@@ -249,6 +249,8 @@ static int ath11k_wmi_cmd_send_nowait(st
|
||||
cmd_hdr = (struct wmi_cmd_hdr *)skb->data;
|
||||
cmd_hdr->cmd_id = cmd;
|
||||
|
||||
+ trace_ath11k_wmi_cmd(ab, cmd_id, skb->data, skb->len);
|
||||
+
|
||||
memset(skb_cb, 0, sizeof(*skb_cb));
|
||||
ret = ath11k_htc_send(&ab->htc, wmi->eid, skb);
|
||||
|
||||
@@ -7103,6 +7105,8 @@ static void ath11k_wmi_tlv_op_rx(struct
|
||||
cmd_hdr = (struct wmi_cmd_hdr *)skb->data;
|
||||
id = FIELD_GET(WMI_CMD_HDR_CMD_ID, (cmd_hdr->cmd_id));
|
||||
|
||||
+ trace_ath11k_wmi_event(ab, id, skb->data, skb->len);
|
||||
+
|
||||
if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL)
|
||||
goto out;
|
||||
|
@ -0,0 +1,70 @@
|
||||
From 273703ebdb01b6c5f1aaf4b98fb57b177609055c Mon Sep 17 00:00:00 2001
|
||||
From: Baochen Qiang <bqiang@codeaurora.org>
|
||||
Date: Tue, 26 Oct 2021 09:16:05 +0800
|
||||
Subject: [PATCH 098/120] ath11k: Fix crash caused by uninitialized TX ring
|
||||
|
||||
Commit 31582373a4a8 ("ath11k: Change number of TCL rings to one for
|
||||
QCA6390") avoids initializing the other entries of dp->tx_ring cause
|
||||
the corresponding TX rings on QCA6390/WCN6855 are not used, but leaves
|
||||
those ring masks in ath11k_hw_ring_mask_qca6390.tx unchanged. Normally
|
||||
this is OK because we will only get interrupts from the first TX ring
|
||||
on these chips and thus only the first entry of dp->tx_ring is involved.
|
||||
|
||||
In case of one MSI vector, all DP rings share the same IRQ. For each
|
||||
interrupt, all rings have to be checked, which means the other entries
|
||||
of dp->tx_ring are involved. However since they are not initialized,
|
||||
system crashes.
|
||||
|
||||
Fix this issue by simply removing those ring masks.
|
||||
|
||||
crash stack:
|
||||
[ 102.907438] BUG: kernel NULL pointer dereference, address: 0000000000000028
|
||||
[ 102.907447] #PF: supervisor read access in kernel mode
|
||||
[ 102.907451] #PF: error_code(0x0000) - not-present page
|
||||
[ 102.907453] PGD 1081f0067 P4D 1081f0067 PUD 1081f1067 PMD 0
|
||||
[ 102.907460] Oops: 0000 [#1] SMP DEBUG_PAGEALLOC NOPTI
|
||||
[ 102.907465] CPU: 0 PID: 3511 Comm: apt-check Kdump: loaded Tainted: G E 5.15.0-rc4-wt-ath+ #20
|
||||
[ 102.907470] Hardware name: AMD Celadon-RN/Celadon-RN, BIOS RCD1005E 10/08/2020
|
||||
[ 102.907472] RIP: 0010:ath11k_dp_tx_completion_handler+0x201/0x830 [ath11k]
|
||||
[ 102.907497] Code: 3c 24 4e 8d ac 37 10 04 00 00 4a 8d bc 37 68 04 00 00 48 89 3c 24 48 63 c8 89 83 84 18 00 00 48 c1 e1 05 48 03 8b 78 18 00 00 <8b> 51 08 89 d6 83 e6 07 89 74 24 24 83 fe 03 74 04 85 f6 75 63 41
|
||||
[ 102.907501] RSP: 0000:ffff9b7340003e08 EFLAGS: 00010202
|
||||
[ 102.907505] RAX: 0000000000000001 RBX: ffff8e21530c0100 RCX: 0000000000000020
|
||||
[ 102.907508] RDX: 0000000000000000 RSI: 00000000fffffe00 RDI: ffff8e21530c1938
|
||||
[ 102.907511] RBP: ffff8e21530c0000 R08: 0000000000000001 R09: 0000000000000000
|
||||
[ 102.907513] R10: ffff8e2145534c10 R11: 0000000000000001 R12: ffff8e21530c2938
|
||||
[ 102.907515] R13: ffff8e21530c18e0 R14: 0000000000000100 R15: ffff8e21530c2978
|
||||
[ 102.907518] FS: 00007f5d4297e740(0000) GS:ffff8e243d600000(0000) knlGS:0000000000000000
|
||||
[ 102.907521] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
|
||||
[ 102.907524] CR2: 0000000000000028 CR3: 00000001034ea000 CR4: 0000000000350ef0
|
||||
[ 102.907527] Call Trace:
|
||||
[ 102.907531] <IRQ>
|
||||
[ 102.907537] ath11k_dp_service_srng+0x5c/0x2f0 [ath11k]
|
||||
[ 102.907556] ath11k_pci_ext_grp_napi_poll+0x21/0x70 [ath11k_pci]
|
||||
[ 102.907562] __napi_poll+0x2c/0x160
|
||||
[ 102.907570] net_rx_action+0x251/0x310
|
||||
[ 102.907576] __do_softirq+0x107/0x2fc
|
||||
[ 102.907585] irq_exit_rcu+0x74/0x90
|
||||
[ 102.907593] common_interrupt+0x83/0xa0
|
||||
[ 102.907600] </IRQ>
|
||||
[ 102.907601] asm_common_interrupt+0x1e/0x40
|
||||
|
||||
Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1
|
||||
|
||||
Signed-off-by: Baochen Qiang <bqiang@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20211026011605.58615-1-quic_bqiang@quicinc.com
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/hw.c | 2 --
|
||||
1 file changed, 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/hw.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/hw.c
|
||||
@@ -1061,8 +1061,6 @@ const struct ath11k_hw_ring_mask ath11k_
|
||||
const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_qca6390 = {
|
||||
.tx = {
|
||||
ATH11K_TX_RING_MASK_0,
|
||||
- ATH11K_TX_RING_MASK_1,
|
||||
- ATH11K_TX_RING_MASK_2,
|
||||
},
|
||||
.rx_mon_status = {
|
||||
0, 0, 0, 0,
|
@ -0,0 +1,130 @@
|
||||
From fc95d10ac41d75c14a81afcc8722333d8b2cf80f Mon Sep 17 00:00:00 2001
|
||||
From: Wen Gong <quic_wgong@quicinc.com>
|
||||
Date: Mon, 15 Nov 2021 11:29:55 +0200
|
||||
Subject: [PATCH 099/120] ath11k: add string type to search board data in
|
||||
board-2.bin for WCN6855
|
||||
|
||||
Currently ath11k only support string type with bus, chip id and board id
|
||||
such as "bus=ahb,qmi-chip-id=1,qmi-board-id=4" for ahb bus chip and
|
||||
"bus=pci,qmi-chip-id=0,qmi-board-id=255" for PCIe bus chip in
|
||||
board-2.bin. For WCN6855, it is not enough to distinguish all different
|
||||
chips.
|
||||
|
||||
This is to add a new string type which include bus, chip id, board id,
|
||||
vendor, device, subsystem-vendor and subsystem-device for WCN6855.
|
||||
|
||||
ath11k will first load board-2.bin and search in it for the board data
|
||||
with the above parameters, if matched one board data, then download it
|
||||
to firmware, if not matched any one, then ath11k will download the file
|
||||
board.bin to firmware.
|
||||
|
||||
Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1
|
||||
|
||||
Signed-off-by: Wen Gong <quic_wgong@quicinc.com>
|
||||
Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20211111065340.20187-1-quic_wgong@quicinc.com
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/core.c | 27 ++++++++++++++++++++------
|
||||
drivers/net/wireless/ath/ath11k/core.h | 13 +++++++++++++
|
||||
drivers/net/wireless/ath/ath11k/pci.c | 10 ++++++++++
|
||||
3 files changed, 44 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/core.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/core.c
|
||||
@@ -412,11 +412,26 @@ static int ath11k_core_create_board_name
|
||||
scnprintf(variant, sizeof(variant), ",variant=%s",
|
||||
ab->qmi.target.bdf_ext);
|
||||
|
||||
- scnprintf(name, name_len,
|
||||
- "bus=%s,qmi-chip-id=%d,qmi-board-id=%d%s",
|
||||
- ath11k_bus_str(ab->hif.bus),
|
||||
- ab->qmi.target.chip_id,
|
||||
- ab->qmi.target.board_id, variant);
|
||||
+ switch (ab->id.bdf_search) {
|
||||
+ case ATH11K_BDF_SEARCH_BUS_AND_BOARD:
|
||||
+ scnprintf(name, name_len,
|
||||
+ "bus=%s,vendor=%04x,device=%04x,subsystem-vendor=%04x,subsystem-device=%04x,qmi-chip-id=%d,qmi-board-id=%d%s",
|
||||
+ ath11k_bus_str(ab->hif.bus),
|
||||
+ ab->id.vendor, ab->id.device,
|
||||
+ ab->id.subsystem_vendor,
|
||||
+ ab->id.subsystem_device,
|
||||
+ ab->qmi.target.chip_id,
|
||||
+ ab->qmi.target.board_id,
|
||||
+ variant);
|
||||
+ break;
|
||||
+ default:
|
||||
+ scnprintf(name, name_len,
|
||||
+ "bus=%s,qmi-chip-id=%d,qmi-board-id=%d%s",
|
||||
+ ath11k_bus_str(ab->hif.bus),
|
||||
+ ab->qmi.target.chip_id,
|
||||
+ ab->qmi.target.board_id, variant);
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
ath11k_dbg(ab, ATH11K_DBG_BOOT, "boot using board name '%s'\n", name);
|
||||
|
||||
@@ -653,7 +668,7 @@ static int ath11k_core_fetch_board_data_
|
||||
return 0;
|
||||
}
|
||||
|
||||
-#define BOARD_NAME_SIZE 100
|
||||
+#define BOARD_NAME_SIZE 200
|
||||
int ath11k_core_fetch_bdf(struct ath11k_base *ab, struct ath11k_board_data *bd)
|
||||
{
|
||||
char boardname[BOARD_NAME_SIZE];
|
||||
--- a/drivers/net/wireless/ath/ath11k/core.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/core.h
|
||||
@@ -47,6 +47,11 @@ enum ath11k_supported_bw {
|
||||
ATH11K_BW_160 = 3,
|
||||
};
|
||||
|
||||
+enum ath11k_bdf_search {
|
||||
+ ATH11K_BDF_SEARCH_DEFAULT,
|
||||
+ ATH11K_BDF_SEARCH_BUS_AND_BOARD,
|
||||
+};
|
||||
+
|
||||
enum wme_ac {
|
||||
WME_AC_BE,
|
||||
WME_AC_BK,
|
||||
@@ -760,6 +765,14 @@ struct ath11k_base {
|
||||
|
||||
struct completion htc_suspend;
|
||||
|
||||
+ struct {
|
||||
+ enum ath11k_bdf_search bdf_search;
|
||||
+ u32 vendor;
|
||||
+ u32 device;
|
||||
+ u32 subsystem_vendor;
|
||||
+ u32 subsystem_device;
|
||||
+ } id;
|
||||
+
|
||||
/* must be last */
|
||||
u8 drv_priv[0] __aligned(sizeof(void *));
|
||||
};
|
||||
--- a/drivers/net/wireless/ath/ath11k/pci.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/pci.c
|
||||
@@ -1251,6 +1251,15 @@ static int ath11k_pci_probe(struct pci_d
|
||||
goto err_free_core;
|
||||
}
|
||||
|
||||
+ ath11k_dbg(ab, ATH11K_DBG_BOOT, "pci probe %04x:%04x %04x:%04x\n",
|
||||
+ pdev->vendor, pdev->device,
|
||||
+ pdev->subsystem_vendor, pdev->subsystem_device);
|
||||
+
|
||||
+ ab->id.vendor = pdev->vendor;
|
||||
+ ab->id.device = pdev->device;
|
||||
+ ab->id.subsystem_vendor = pdev->subsystem_vendor;
|
||||
+ ab->id.subsystem_device = pdev->subsystem_device;
|
||||
+
|
||||
switch (pci_dev->device) {
|
||||
case QCA6390_DEVICE_ID:
|
||||
ath11k_pci_read_hw_version(ab, &soc_hw_version_major,
|
||||
@@ -1273,6 +1282,7 @@ static int ath11k_pci_probe(struct pci_d
|
||||
ab->hw_rev = ATH11K_HW_QCN9074_HW10;
|
||||
break;
|
||||
case WCN6855_DEVICE_ID:
|
||||
+ ab->id.bdf_search = ATH11K_BDF_SEARCH_BUS_AND_BOARD;
|
||||
ath11k_pci_read_hw_version(ab, &soc_hw_version_major,
|
||||
&soc_hw_version_minor);
|
||||
switch (soc_hw_version_major) {
|
@ -0,0 +1,308 @@
|
||||
From 886433a984254c6d2c2074688dc8f48c40b1c070 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <john@phrozen.org>
|
||||
Date: Mon, 25 Oct 2021 21:40:54 +0530
|
||||
Subject: [PATCH 100/120] ath11k: add support for BSS color change
|
||||
|
||||
Whenever the MAC detects a color collision, or any of
|
||||
its associated stations detects one, the firmware will
|
||||
send out an event. Add the code to parse and handle
|
||||
this event and pass the data up to mac80211.
|
||||
|
||||
The firmware does not provide an offload feature such
|
||||
as the one used for CSA. The color change process is
|
||||
hence triggered via the beacon offload tx completion
|
||||
events sent out by firmware.
|
||||
|
||||
BSS color feature is enabled depending on service flag
|
||||
advertised by firmware, based on which color change
|
||||
functionality is invoked.
|
||||
|
||||
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.5.0.1-00680-QCAHKSWPL_SILICONZ-1
|
||||
|
||||
Signed-off-by: John Crispin <john@phrozen.org>
|
||||
Co-developed-by: Lavanya Suresh <lavaks@codeaurora.org>
|
||||
Signed-off-by: Lavanya Suresh <lavaks@codeaurora.org>
|
||||
Signed-off-by: Rameshkumar Sundaram <quic_ramess@quicinc.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/1635178254-17732-1-git-send-email-quic_ramess@quicinc.com
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/core.h | 2 +
|
||||
drivers/net/wireless/ath/ath11k/mac.c | 57 +++++++++++++++++--
|
||||
drivers/net/wireless/ath/ath11k/mac.h | 1 +
|
||||
drivers/net/wireless/ath/ath11k/wmi.c | 78 +++++++++++++++++++++++++-
|
||||
drivers/net/wireless/ath/ath11k/wmi.h | 15 +++++
|
||||
5 files changed, 147 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/core.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/core.h
|
||||
@@ -255,6 +255,8 @@ struct ath11k_vif {
|
||||
int txpower;
|
||||
bool rsnie_present;
|
||||
bool wpaie_present;
|
||||
+ bool bcca_zero_sent;
|
||||
+ bool do_not_send_tmpl;
|
||||
struct ieee80211_chanctx_conf chanctx;
|
||||
};
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -1231,6 +1231,26 @@ static int ath11k_mac_setup_bcn_tmpl(str
|
||||
return ret;
|
||||
}
|
||||
|
||||
+void ath11k_mac_bcn_tx_event(struct ath11k_vif *arvif)
|
||||
+{
|
||||
+ struct ieee80211_vif *vif = arvif->vif;
|
||||
+
|
||||
+ if (!vif->color_change_active && !arvif->bcca_zero_sent)
|
||||
+ return;
|
||||
+
|
||||
+ if (vif->color_change_active && ieee80211_beacon_cntdwn_is_complete(vif)) {
|
||||
+ arvif->bcca_zero_sent = true;
|
||||
+ ieee80211_color_change_finish(vif);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ arvif->bcca_zero_sent = false;
|
||||
+
|
||||
+ if (vif->color_change_active)
|
||||
+ ieee80211_beacon_update_cntdwn(vif);
|
||||
+ ath11k_mac_setup_bcn_tmpl(arvif);
|
||||
+}
|
||||
+
|
||||
static void ath11k_control_beaconing(struct ath11k_vif *arvif,
|
||||
struct ieee80211_bss_conf *info)
|
||||
{
|
||||
@@ -2894,10 +2914,17 @@ static void ath11k_mac_op_bss_info_chang
|
||||
"Set staggered beacon mode for VDEV: %d\n",
|
||||
arvif->vdev_id);
|
||||
|
||||
- ret = ath11k_mac_setup_bcn_tmpl(arvif);
|
||||
- if (ret)
|
||||
- ath11k_warn(ar->ab, "failed to update bcn template: %d\n",
|
||||
- ret);
|
||||
+ if (!arvif->do_not_send_tmpl || !arvif->bcca_zero_sent) {
|
||||
+ ret = ath11k_mac_setup_bcn_tmpl(arvif);
|
||||
+ if (ret)
|
||||
+ ath11k_warn(ar->ab, "failed to update bcn template: %d\n",
|
||||
+ ret);
|
||||
+ }
|
||||
+
|
||||
+ if (arvif->bcca_zero_sent)
|
||||
+ arvif->do_not_send_tmpl = true;
|
||||
+ else
|
||||
+ arvif->do_not_send_tmpl = false;
|
||||
}
|
||||
|
||||
if (changed & (BSS_CHANGED_BEACON_INFO | BSS_CHANGED_BEACON)) {
|
||||
@@ -3108,6 +3135,25 @@ static void ath11k_mac_op_bss_info_chang
|
||||
if (ret)
|
||||
ath11k_warn(ar->ab, "failed to set bss color collision on vdev %i: %d\n",
|
||||
arvif->vdev_id, ret);
|
||||
+
|
||||
+ param_id = WMI_VDEV_PARAM_BSS_COLOR;
|
||||
+ if (info->he_bss_color.enabled)
|
||||
+ param_value = info->he_bss_color.color <<
|
||||
+ IEEE80211_HE_OPERATION_BSS_COLOR_OFFSET;
|
||||
+ else
|
||||
+ param_value = IEEE80211_HE_OPERATION_BSS_COLOR_DISABLED;
|
||||
+
|
||||
+ ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,
|
||||
+ param_id,
|
||||
+ param_value);
|
||||
+ if (ret)
|
||||
+ ath11k_warn(ar->ab,
|
||||
+ "failed to set bss color param on vdev %i: %d\n",
|
||||
+ arvif->vdev_id, ret);
|
||||
+
|
||||
+ ath11k_dbg(ar->ab, ATH11K_DBG_MAC,
|
||||
+ "bss color param 0x%x set on vdev %i\n",
|
||||
+ param_value, arvif->vdev_id);
|
||||
} else if (vif->type == NL80211_IFTYPE_STATION) {
|
||||
ret = ath11k_wmi_send_bss_color_change_enable_cmd(ar,
|
||||
arvif->vdev_id,
|
||||
@@ -7872,6 +7918,9 @@ static int __ath11k_mac_register(struct
|
||||
|
||||
wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
|
||||
wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_STA_TX_PWR);
|
||||
+ if (test_bit(WMI_TLV_SERVICE_BSS_COLOR_OFFLOAD, ar->ab->wmi_ab.svc_map))
|
||||
+ wiphy_ext_feature_set(ar->hw->wiphy,
|
||||
+ NL80211_EXT_FEATURE_BSS_COLOR);
|
||||
|
||||
ar->hw->wiphy->cipher_suites = cipher_suites;
|
||||
ar->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.h
|
||||
@@ -155,4 +155,5 @@ enum ath11k_supported_bw ath11k_mac_mac8
|
||||
enum hal_encrypt_type ath11k_dp_tx_get_encrypt_type(u32 cipher);
|
||||
void ath11k_mac_handle_beacon(struct ath11k *ar, struct sk_buff *skb);
|
||||
void ath11k_mac_handle_beacon_miss(struct ath11k *ar, u32 vdev_id);
|
||||
+void ath11k_mac_bcn_tx_event(struct ath11k_vif *arvif);
|
||||
#endif
|
||||
--- a/drivers/net/wireless/ath/ath11k/wmi.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
|
||||
@@ -128,6 +128,8 @@ static const struct wmi_tlv_policy wmi_t
|
||||
.min_len = sizeof(struct wmi_probe_resp_tx_status_event) },
|
||||
[WMI_TAG_VDEV_DELETE_RESP_EVENT] = {
|
||||
.min_len = sizeof(struct wmi_vdev_delete_resp_event) },
|
||||
+ [WMI_TAG_OBSS_COLOR_COLLISION_EVT] = {
|
||||
+ .min_len = sizeof(struct wmi_obss_color_collision_event) },
|
||||
};
|
||||
|
||||
#define PRIMAP(_hw_mode_) \
|
||||
@@ -1633,6 +1635,15 @@ int ath11k_wmi_bcn_tmpl(struct ath11k *a
|
||||
void *ptr;
|
||||
int ret, len;
|
||||
size_t aligned_len = roundup(bcn->len, 4);
|
||||
+ struct ieee80211_vif *vif;
|
||||
+ struct ath11k_vif *arvif = ath11k_mac_get_arvif(ar, vdev_id);
|
||||
+
|
||||
+ if (!arvif) {
|
||||
+ ath11k_warn(ar->ab, "failed to find arvif with vdev id %d\n", vdev_id);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ vif = arvif->vif;
|
||||
|
||||
len = sizeof(*cmd) + sizeof(*bcn_prb_info) + TLV_HDR_SIZE + aligned_len;
|
||||
|
||||
@@ -1645,8 +1656,12 @@ int ath11k_wmi_bcn_tmpl(struct ath11k *a
|
||||
FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
|
||||
cmd->vdev_id = vdev_id;
|
||||
cmd->tim_ie_offset = offs->tim_offset;
|
||||
- cmd->csa_switch_count_offset = offs->cntdwn_counter_offs[0];
|
||||
- cmd->ext_csa_switch_count_offset = offs->cntdwn_counter_offs[1];
|
||||
+
|
||||
+ if (vif->csa_active) {
|
||||
+ cmd->csa_switch_count_offset = offs->cntdwn_counter_offs[0];
|
||||
+ cmd->ext_csa_switch_count_offset = offs->cntdwn_counter_offs[1];
|
||||
+ }
|
||||
+
|
||||
cmd->buf_len = bcn->len;
|
||||
|
||||
ptr = skb->data + sizeof(*cmd);
|
||||
@@ -3451,6 +3466,53 @@ int ath11k_wmi_fils_discovery(struct ath
|
||||
}
|
||||
|
||||
static void
|
||||
+ath11k_wmi_obss_color_collision_event(struct ath11k_base *ab, struct sk_buff *skb)
|
||||
+{
|
||||
+ const void **tb;
|
||||
+ const struct wmi_obss_color_collision_event *ev;
|
||||
+ struct ath11k_vif *arvif;
|
||||
+ int ret;
|
||||
+
|
||||
+ tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
|
||||
+ if (IS_ERR(tb)) {
|
||||
+ ret = PTR_ERR(tb);
|
||||
+ ath11k_warn(ab, "failed to parse tlv: %d\n", ret);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ ev = tb[WMI_TAG_OBSS_COLOR_COLLISION_EVT];
|
||||
+ if (!ev) {
|
||||
+ ath11k_warn(ab, "failed to fetch obss color collision ev");
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
+ arvif = ath11k_mac_get_arvif_by_vdev_id(ab, ev->vdev_id);
|
||||
+ if (!arvif) {
|
||||
+ ath11k_warn(ab, "failed to find arvif with vedv id %d in obss_color_collision_event\n",
|
||||
+ ev->vdev_id);
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
+ switch (ev->evt_type) {
|
||||
+ case WMI_BSS_COLOR_COLLISION_DETECTION:
|
||||
+ ieeee80211_obss_color_collision_notify(arvif->vif, ev->obss_color_bitmap);
|
||||
+ ath11k_dbg(ab, ATH11K_DBG_WMI,
|
||||
+ "OBSS color collision detected vdev:%d, event:%d, bitmap:%08llx\n",
|
||||
+ ev->vdev_id, ev->evt_type, ev->obss_color_bitmap);
|
||||
+ break;
|
||||
+ case WMI_BSS_COLOR_COLLISION_DISABLE:
|
||||
+ case WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY:
|
||||
+ case WMI_BSS_COLOR_FREE_SLOT_AVAILABLE:
|
||||
+ break;
|
||||
+ default:
|
||||
+ ath11k_warn(ab, "received unknown obss color collision detetction event\n");
|
||||
+ }
|
||||
+
|
||||
+exit:
|
||||
+ kfree(tb);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
ath11k_fill_band_to_mac_param(struct ath11k_base *soc,
|
||||
struct wmi_host_pdev_band_to_mac *band_to_mac)
|
||||
{
|
||||
@@ -6157,6 +6219,7 @@ static void ath11k_vdev_start_resp_event
|
||||
|
||||
static void ath11k_bcn_tx_status_event(struct ath11k_base *ab, struct sk_buff *skb)
|
||||
{
|
||||
+ struct ath11k_vif *arvif;
|
||||
u32 vdev_id, tx_status;
|
||||
|
||||
if (ath11k_pull_bcn_tx_status_ev(ab, skb->data, skb->len,
|
||||
@@ -6164,6 +6227,14 @@ static void ath11k_bcn_tx_status_event(s
|
||||
ath11k_warn(ab, "failed to extract bcn tx status");
|
||||
return;
|
||||
}
|
||||
+
|
||||
+ arvif = ath11k_mac_get_arvif_by_vdev_id(ab, vdev_id);
|
||||
+ if (!arvif) {
|
||||
+ ath11k_warn(ab, "invalid vdev id %d in bcn_tx_status",
|
||||
+ vdev_id);
|
||||
+ return;
|
||||
+ }
|
||||
+ ath11k_mac_bcn_tx_event(arvif);
|
||||
}
|
||||
|
||||
static void ath11k_vdev_stopped_event(struct ath11k_base *ab, struct sk_buff *skb)
|
||||
@@ -7191,6 +7262,9 @@ static void ath11k_wmi_tlv_op_rx(struct
|
||||
case WMI_OFFLOAD_PROB_RESP_TX_STATUS_EVENTID:
|
||||
ath11k_probe_resp_tx_status_event(ab, skb);
|
||||
break;
|
||||
+ case WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID:
|
||||
+ ath11k_wmi_obss_color_collision_event(ab, skb);
|
||||
+ break;
|
||||
/* add Unsupported events here */
|
||||
case WMI_TBTTOFFSET_EXT_UPDATE_EVENTID:
|
||||
case WMI_PEER_OPER_MODE_CHANGE_EVENTID:
|
||||
--- a/drivers/net/wireless/ath/ath11k/wmi.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/wmi.h
|
||||
@@ -774,6 +774,8 @@ enum wmi_tlv_event_id {
|
||||
WMI_MDNS_STATS_EVENTID = WMI_TLV_CMD(WMI_GRP_MDNS_OFL),
|
||||
WMI_SAP_OFL_ADD_STA_EVENTID = WMI_TLV_CMD(WMI_GRP_SAP_OFL),
|
||||
WMI_SAP_OFL_DEL_STA_EVENTID,
|
||||
+ WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID =
|
||||
+ WMI_EVT_GRP_START_ID(WMI_GRP_OBSS_OFL),
|
||||
WMI_OCB_SET_CONFIG_RESP_EVENTID = WMI_TLV_CMD(WMI_GRP_OCB),
|
||||
WMI_OCB_GET_TSF_TIMER_RESP_EVENTID,
|
||||
WMI_DCC_GET_STATS_RESP_EVENTID,
|
||||
@@ -4916,6 +4918,13 @@ struct wmi_pdev_obss_pd_bitmap_cmd {
|
||||
#define ATH11K_BSS_COLOR_COLLISION_DETECTION_STA_PERIOD_MS 10000
|
||||
#define ATH11K_BSS_COLOR_COLLISION_DETECTION_AP_PERIOD_MS 5000
|
||||
|
||||
+enum wmi_bss_color_collision {
|
||||
+ WMI_BSS_COLOR_COLLISION_DISABLE = 0,
|
||||
+ WMI_BSS_COLOR_COLLISION_DETECTION,
|
||||
+ WMI_BSS_COLOR_FREE_SLOT_TIMER_EXPIRY,
|
||||
+ WMI_BSS_COLOR_FREE_SLOT_AVAILABLE,
|
||||
+};
|
||||
+
|
||||
struct wmi_obss_color_collision_cfg_params_cmd {
|
||||
u32 tlv_header;
|
||||
u32 vdev_id;
|
||||
@@ -4933,6 +4942,12 @@ struct wmi_bss_color_change_enable_param
|
||||
u32 enable;
|
||||
} __packed;
|
||||
|
||||
+struct wmi_obss_color_collision_event {
|
||||
+ u32 vdev_id;
|
||||
+ u32 evt_type;
|
||||
+ u64 obss_color_bitmap;
|
||||
+} __packed;
|
||||
+
|
||||
#define ATH11K_IPV4_TH_SEED_SIZE 5
|
||||
#define ATH11K_IPV6_TH_SEED_SIZE 11
|
||||
|
@ -0,0 +1,52 @@
|
||||
From 436a4e88659842a7cf634d7cc088c8f2cc94ebf5 Mon Sep 17 00:00:00 2001
|
||||
From: Karthikeyan Kathirvel <kathirve@codeaurora.org>
|
||||
Date: Mon, 15 Nov 2021 11:04:40 +0100
|
||||
Subject: [PATCH 101/120] ath11k: clear the keys properly via DISABLE_KEY
|
||||
|
||||
DISABLE_KEY sets the key_len to 0, firmware will not delete the keys if
|
||||
key_len is 0. Changing from security mode to open mode will cause mcast
|
||||
to be still encrypted without vdev restart.
|
||||
|
||||
Set the proper key_len for DISABLE_KEY cmd to clear the keys in
|
||||
firmware.
|
||||
|
||||
Tested-on: IPQ6018 hw1.0 AHB WLAN.HK.2.5.0.1-01100-QCAHKSWPL_SILICONZ-1
|
||||
|
||||
Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices")
|
||||
Reported-by: Sven Eckelmann <sven@narfation.org>
|
||||
Signed-off-by: Karthikeyan Kathirvel <kathirve@codeaurora.org>
|
||||
[sven@narfation.org: split into separate patches, clean up commit message]
|
||||
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20211115100441.33771-1-sven@narfation.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/mac.c | 4 +---
|
||||
drivers/net/wireless/ath/ath11k/wmi.c | 3 ++-
|
||||
2 files changed, 3 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -3461,9 +3461,7 @@ static int ath11k_install_key(struct ath
|
||||
return 0;
|
||||
|
||||
if (cmd == DISABLE_KEY) {
|
||||
- /* TODO: Check if FW expects value other than NONE for del */
|
||||
- /* arg.key_cipher = WMI_CIPHER_NONE; */
|
||||
- arg.key_len = 0;
|
||||
+ arg.key_cipher = WMI_CIPHER_NONE;
|
||||
arg.key_data = NULL;
|
||||
goto install;
|
||||
}
|
||||
--- a/drivers/net/wireless/ath/ath11k/wmi.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
|
||||
@@ -1725,7 +1725,8 @@ int ath11k_wmi_vdev_install_key(struct a
|
||||
tlv = (struct wmi_tlv *)(skb->data + sizeof(*cmd));
|
||||
tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_BYTE) |
|
||||
FIELD_PREP(WMI_TLV_LEN, key_len_aligned);
|
||||
- memcpy(tlv->value, (u8 *)arg->key_data, key_len_aligned);
|
||||
+ if (arg->key_data)
|
||||
+ memcpy(tlv->value, (u8 *)arg->key_data, key_len_aligned);
|
||||
|
||||
ret = ath11k_wmi_cmd_send(wmi, skb, WMI_VDEV_INSTALL_KEY_CMDID);
|
||||
if (ret) {
|
@ -0,0 +1,49 @@
|
||||
From 64bc3aa02ae78b1fcb1b850e0eb1f0622002bfaa Mon Sep 17 00:00:00 2001
|
||||
From: Karthikeyan Kathirvel <kathirve@codeaurora.org>
|
||||
Date: Mon, 15 Nov 2021 11:04:41 +0100
|
||||
Subject: [PATCH 102/120] ath11k: reset RSN/WPA present state for open BSS
|
||||
|
||||
The ath11k driver is caching the information about RSN/WPA IE in the
|
||||
configured beacon template. The cached information is used during
|
||||
associations to figure out whether 4-way PKT/2-way GTK peer flags need to
|
||||
be set or not.
|
||||
|
||||
But the code never cleared the state when no such IE was found. This can
|
||||
for example happen when moving from an WPA/RSN to an open setup. The
|
||||
(seemingly connected) peer was then not able to communicate over the
|
||||
link because the firmware assumed a different (encryption enabled) state
|
||||
for the peer.
|
||||
|
||||
Tested-on: IPQ6018 hw1.0 AHB WLAN.HK.2.5.0.1-01100-QCAHKSWPL_SILICONZ-1
|
||||
|
||||
Fixes: 01e34233c645 ("ath11k: fix wmi peer flags in peer assoc command")
|
||||
Cc: Venkateswara Naralasetty <vnaralas@codeaurora.org>
|
||||
Reported-by: Sven Eckelmann <sven@narfation.org>
|
||||
Signed-off-by: Karthikeyan Kathirvel <kathirve@codeaurora.org>
|
||||
[sven@narfation.org: split into separate patches, clean up commit message]
|
||||
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20211115100441.33771-2-sven@narfation.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/mac.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -1214,11 +1214,15 @@ static int ath11k_mac_setup_bcn_tmpl(str
|
||||
|
||||
if (cfg80211_find_ie(WLAN_EID_RSN, ies, (skb_tail_pointer(bcn) - ies)))
|
||||
arvif->rsnie_present = true;
|
||||
+ else
|
||||
+ arvif->rsnie_present = false;
|
||||
|
||||
if (cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
|
||||
WLAN_OUI_TYPE_MICROSOFT_WPA,
|
||||
ies, (skb_tail_pointer(bcn) - ies)))
|
||||
arvif->wpaie_present = true;
|
||||
+ else
|
||||
+ arvif->wpaie_present = false;
|
||||
|
||||
ret = ath11k_wmi_bcn_tmpl(ar, arvif->vdev_id, &offs, bcn);
|
||||
|
@ -0,0 +1,137 @@
|
||||
From 081e2d6476e30399433b509684d5da4d1844e430 Mon Sep 17 00:00:00 2001
|
||||
From: Seevalamuthu Mariappan <quic_seevalam@quicinc.com>
|
||||
Date: Wed, 17 Nov 2021 09:39:41 +0200
|
||||
Subject: [PATCH 103/120] ath11k: add hw_param for wakeup_mhi
|
||||
|
||||
Wakeup mhi is needed before pci_read/write only for QCA6390 and WCN6855. Since
|
||||
wakeup & release mhi is enabled for all hardwares, below mhi assert is seen in
|
||||
QCN9074 when doing 'rmmod ath11k_pci':
|
||||
|
||||
Kernel panic - not syncing: dev_wake != 0
|
||||
CPU: 2 PID: 13535 Comm: procd Not tainted 4.4.60 #1
|
||||
Hardware name: Generic DT based system
|
||||
[<80316dac>] (unwind_backtrace) from [<80313700>] (show_stack+0x10/0x14)
|
||||
[<80313700>] (show_stack) from [<805135dc>] (dump_stack+0x7c/0x9c)
|
||||
[<805135dc>] (dump_stack) from [<8032136c>] (panic+0x84/0x1f8)
|
||||
[<8032136c>] (panic) from [<80549b24>] (mhi_pm_disable_transition+0x3b8/0x5b8)
|
||||
[<80549b24>] (mhi_pm_disable_transition) from [<80549ddc>] (mhi_power_down+0xb8/0x100)
|
||||
[<80549ddc>] (mhi_power_down) from [<7f5242b0>] (ath11k_mhi_op_status_cb+0x284/0x3ac [ath11k_pci])
|
||||
[E][__mhi_device_get_sync] Did not enter M0 state, cur_state:RESET pm_state:SHUTDOWN Process
|
||||
[E][__mhi_device_get_sync] Did not enter M0 state, cur_state:RESET pm_state:SHUTDOWN Process
|
||||
[E][__mhi_device_get_sync] Did not enter M0 state, cur_state:RESET pm_state:SHUTDOWN Process
|
||||
[<7f5242b0>] (ath11k_mhi_op_status_cb [ath11k_pci]) from [<7f524878>] (ath11k_mhi_stop+0x10/0x20 [ath11k_pci])
|
||||
[<7f524878>] (ath11k_mhi_stop [ath11k_pci]) from [<7f525b94>] (ath11k_pci_power_down+0x54/0x90 [ath11k_pci])
|
||||
[<7f525b94>] (ath11k_pci_power_down [ath11k_pci]) from [<8056b2a8>] (pci_device_shutdown+0x30/0x44)
|
||||
[<8056b2a8>] (pci_device_shutdown) from [<805cfa0c>] (device_shutdown+0x124/0x174)
|
||||
[<805cfa0c>] (device_shutdown) from [<8033aaa4>] (kernel_restart+0xc/0x50)
|
||||
[<8033aaa4>] (kernel_restart) from [<8033ada8>] (SyS_reboot+0x178/0x1ec)
|
||||
[<8033ada8>] (SyS_reboot) from [<80301b80>] (ret_fast_syscall+0x0/0x34)
|
||||
|
||||
Hence, disable wakeup/release mhi using hw_param for other hardwares.
|
||||
|
||||
Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.5.0.1-01060-QCAHKSWPL_SILICONZ-1
|
||||
|
||||
Fixes: a05bd8513335 ("ath11k: read and write registers below unwindowed address")
|
||||
Signed-off-by: Seevalamuthu Mariappan <quic_seevalam@quicinc.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/1636702019-26142-1-git-send-email-quic_seevalam@quicinc.com
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/core.c | 5 +++++
|
||||
drivers/net/wireless/ath/ath11k/hw.h | 1 +
|
||||
drivers/net/wireless/ath/ath11k/pci.c | 12 ++++++++----
|
||||
3 files changed, 14 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/core.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/core.c
|
||||
@@ -86,6 +86,7 @@ static const struct ath11k_hw_params ath
|
||||
.hal_params = &ath11k_hw_hal_params_ipq8074,
|
||||
.supports_dynamic_smps_6ghz = false,
|
||||
.alloc_cacheable_memory = true,
|
||||
+ .wakeup_mhi = false,
|
||||
},
|
||||
{
|
||||
.hw_rev = ATH11K_HW_IPQ6018_HW10,
|
||||
@@ -139,6 +140,7 @@ static const struct ath11k_hw_params ath
|
||||
.hal_params = &ath11k_hw_hal_params_ipq8074,
|
||||
.supports_dynamic_smps_6ghz = false,
|
||||
.alloc_cacheable_memory = true,
|
||||
+ .wakeup_mhi = false,
|
||||
},
|
||||
{
|
||||
.name = "qca6390 hw2.0",
|
||||
@@ -191,6 +193,7 @@ static const struct ath11k_hw_params ath
|
||||
.hal_params = &ath11k_hw_hal_params_qca6390,
|
||||
.supports_dynamic_smps_6ghz = false,
|
||||
.alloc_cacheable_memory = false,
|
||||
+ .wakeup_mhi = true,
|
||||
},
|
||||
{
|
||||
.name = "qcn9074 hw1.0",
|
||||
@@ -243,6 +246,7 @@ static const struct ath11k_hw_params ath
|
||||
.hal_params = &ath11k_hw_hal_params_ipq8074,
|
||||
.supports_dynamic_smps_6ghz = true,
|
||||
.alloc_cacheable_memory = true,
|
||||
+ .wakeup_mhi = false,
|
||||
},
|
||||
{
|
||||
.name = "wcn6855 hw2.0",
|
||||
@@ -295,6 +299,7 @@ static const struct ath11k_hw_params ath
|
||||
.hal_params = &ath11k_hw_hal_params_qca6390,
|
||||
.supports_dynamic_smps_6ghz = false,
|
||||
.alloc_cacheable_memory = false,
|
||||
+ .wakeup_mhi = true,
|
||||
},
|
||||
};
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/hw.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/hw.h
|
||||
@@ -180,6 +180,7 @@ struct ath11k_hw_params {
|
||||
const struct ath11k_hw_hal_params *hal_params;
|
||||
bool supports_dynamic_smps_6ghz;
|
||||
bool alloc_cacheable_memory;
|
||||
+ bool wakeup_mhi;
|
||||
};
|
||||
|
||||
struct ath11k_hw_ops {
|
||||
--- a/drivers/net/wireless/ath/ath11k/pci.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/pci.c
|
||||
@@ -182,7 +182,8 @@ void ath11k_pci_write32(struct ath11k_ba
|
||||
/* for offset beyond BAR + 4K - 32, may
|
||||
* need to wakeup MHI to access.
|
||||
*/
|
||||
- if (test_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags) &&
|
||||
+ if (ab->hw_params.wakeup_mhi &&
|
||||
+ test_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags) &&
|
||||
offset >= ACCESS_ALWAYS_OFF)
|
||||
mhi_device_get_sync(ab_pci->mhi_ctrl->mhi_dev);
|
||||
|
||||
@@ -206,7 +207,8 @@ void ath11k_pci_write32(struct ath11k_ba
|
||||
}
|
||||
}
|
||||
|
||||
- if (test_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags) &&
|
||||
+ if (ab->hw_params.wakeup_mhi &&
|
||||
+ test_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags) &&
|
||||
offset >= ACCESS_ALWAYS_OFF)
|
||||
mhi_device_put(ab_pci->mhi_ctrl->mhi_dev);
|
||||
}
|
||||
@@ -219,7 +221,8 @@ u32 ath11k_pci_read32(struct ath11k_base
|
||||
/* for offset beyond BAR + 4K - 32, may
|
||||
* need to wakeup MHI to access.
|
||||
*/
|
||||
- if (test_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags) &&
|
||||
+ if (ab->hw_params.wakeup_mhi &&
|
||||
+ test_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags) &&
|
||||
offset >= ACCESS_ALWAYS_OFF)
|
||||
mhi_device_get_sync(ab_pci->mhi_ctrl->mhi_dev);
|
||||
|
||||
@@ -243,7 +246,8 @@ u32 ath11k_pci_read32(struct ath11k_base
|
||||
}
|
||||
}
|
||||
|
||||
- if (test_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags) &&
|
||||
+ if (ab->hw_params.wakeup_mhi &&
|
||||
+ test_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags) &&
|
||||
offset >= ACCESS_ALWAYS_OFF)
|
||||
mhi_device_put(ab_pci->mhi_ctrl->mhi_dev);
|
||||
|
@ -0,0 +1,77 @@
|
||||
From 87b4072d7ef818e368b0f4162a1af2fb4727f51c Mon Sep 17 00:00:00 2001
|
||||
From: Carl Huang <cjhuang@codeaurora.org>
|
||||
Date: Fri, 19 Nov 2021 15:36:26 +0200
|
||||
Subject: [PATCH 104/120] ath11k: get msi_data again after request_irq is
|
||||
called
|
||||
|
||||
The reservation mode of interrupts in kernel assigns a dummy vector
|
||||
when the interrupt is allocated and assigns a real vector when the
|
||||
request_irq is called. The reservation mode helps to ease vector
|
||||
pressure when devices with a large amount of queues/interrupts
|
||||
are initialized, but only a minimal subset of those queues/interrupts
|
||||
is actually used.
|
||||
|
||||
So on reservation mode, the msi_data may change after request_irq
|
||||
is called, so ath11k reads msi_data again after request_irq is called,
|
||||
and then the correct msi_data is programmed into QCA6390 hardware
|
||||
components. Without this change, spurious interrupt occurs in case of
|
||||
one MSI vector. When VT-d in BIOS is enabled and ath11k can get 32 MSI
|
||||
vectors, ath11k always get the same msi_data before and after request_irq,
|
||||
that's why this change is only required when one MSI vector is to be
|
||||
supported.
|
||||
|
||||
Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1
|
||||
|
||||
Signed-off-by: Carl Huang <cjhuang@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20211026041636.5008-1-bqiang@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/pci.c | 30 +++++++++++++++++++++++++++
|
||||
1 file changed, 30 insertions(+)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/pci.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/pci.c
|
||||
@@ -933,6 +933,25 @@ static void ath11k_pci_free_msi(struct a
|
||||
pci_free_irq_vectors(ab_pci->pdev);
|
||||
}
|
||||
|
||||
+static int ath11k_pci_config_msi_data(struct ath11k_pci *ab_pci)
|
||||
+{
|
||||
+ struct msi_desc *msi_desc;
|
||||
+
|
||||
+ msi_desc = irq_get_msi_desc(ab_pci->pdev->irq);
|
||||
+ if (!msi_desc) {
|
||||
+ ath11k_err(ab_pci->ab, "msi_desc is NULL!\n");
|
||||
+ pci_free_irq_vectors(ab_pci->pdev);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ ab_pci->msi_ep_base_data = msi_desc->msg.data;
|
||||
+
|
||||
+ ath11k_dbg(ab_pci->ab, ATH11K_DBG_PCI, "pci after request_irq msi_ep_base_data %d\n",
|
||||
+ ab_pci->msi_ep_base_data);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int ath11k_pci_claim(struct ath11k_pci *ab_pci, struct pci_dev *pdev)
|
||||
{
|
||||
struct ath11k_base *ab = ab_pci->ab;
|
||||
@@ -1342,6 +1361,17 @@ static int ath11k_pci_probe(struct pci_d
|
||||
goto err_ce_free;
|
||||
}
|
||||
|
||||
+ /* kernel may allocate a dummy vector before request_irq and
|
||||
+ * then allocate a real vector when request_irq is called.
|
||||
+ * So get msi_data here again to avoid spurious interrupt
|
||||
+ * as msi_data will configured to srngs.
|
||||
+ */
|
||||
+ ret = ath11k_pci_config_msi_data(ab_pci);
|
||||
+ if (ret) {
|
||||
+ ath11k_err(ab, "failed to config msi_data: %d\n", ret);
|
||||
+ goto err_free_irq;
|
||||
+ }
|
||||
+
|
||||
ret = ath11k_core_init(ab);
|
||||
if (ret) {
|
||||
ath11k_err(ab, "failed to init core: %d\n", ret);
|
@ -0,0 +1,93 @@
|
||||
From 01279bcd01d965b6526d575e036841778d8e3c4e Mon Sep 17 00:00:00 2001
|
||||
From: Carl Huang <cjhuang@codeaurora.org>
|
||||
Date: Fri, 19 Nov 2021 15:36:26 +0200
|
||||
Subject: [PATCH 105/120] ath11k: add CE and ext IRQ flag to indicate
|
||||
irq_handler
|
||||
|
||||
This change adds two flags to indicate whether IRQ handler for CE
|
||||
and DP can be called. This is because in one MSI vector case,
|
||||
interrupt is not disabled in hif_stop and hif_irq_disable. Otherwise,
|
||||
MHI interrupt is disabled too.
|
||||
|
||||
Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1
|
||||
|
||||
Signed-off-by: Carl Huang <cjhuang@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Signed-off-by: Baochen Qiang <bqiang@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20211026041646.5060-1-bqiang@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/core.h | 2 ++
|
||||
drivers/net/wireless/ath/ath11k/pci.c | 16 ++++++++++++++++
|
||||
2 files changed, 18 insertions(+)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/core.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/core.h
|
||||
@@ -199,6 +199,8 @@ enum ath11k_dev_flags {
|
||||
ATH11K_FLAG_REGISTERED,
|
||||
ATH11K_FLAG_QMI_FAIL,
|
||||
ATH11K_FLAG_HTC_SUSPEND_COMPLETE,
|
||||
+ ATH11K_FLAG_CE_IRQ_ENABLED,
|
||||
+ ATH11K_FLAG_EXT_IRQ_ENABLED,
|
||||
};
|
||||
|
||||
enum ath11k_monitor_flags {
|
||||
--- a/drivers/net/wireless/ath/ath11k/pci.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/pci.c
|
||||
@@ -578,6 +578,8 @@ static void ath11k_pci_ce_irqs_disable(s
|
||||
{
|
||||
int i;
|
||||
|
||||
+ clear_bit(ATH11K_FLAG_CE_IRQ_ENABLED, &ab->dev_flags);
|
||||
+
|
||||
for (i = 0; i < ab->hw_params.ce_count; i++) {
|
||||
if (ath11k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR)
|
||||
continue;
|
||||
@@ -611,6 +613,10 @@ static void ath11k_pci_ce_tasklet(struct
|
||||
static irqreturn_t ath11k_pci_ce_interrupt_handler(int irq, void *arg)
|
||||
{
|
||||
struct ath11k_ce_pipe *ce_pipe = arg;
|
||||
+ struct ath11k_base *ab = ce_pipe->ab;
|
||||
+
|
||||
+ if (!test_bit(ATH11K_FLAG_CE_IRQ_ENABLED, &ab->dev_flags))
|
||||
+ return IRQ_HANDLED;
|
||||
|
||||
/* last interrupt received for this CE */
|
||||
ce_pipe->timestamp = jiffies;
|
||||
@@ -633,6 +639,8 @@ static void __ath11k_pci_ext_irq_disable
|
||||
{
|
||||
int i;
|
||||
|
||||
+ clear_bit(ATH11K_FLAG_EXT_IRQ_ENABLED, &sc->dev_flags);
|
||||
+
|
||||
for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) {
|
||||
struct ath11k_ext_irq_grp *irq_grp = &sc->ext_irq_grp[i];
|
||||
|
||||
@@ -655,6 +663,8 @@ static void ath11k_pci_ext_irq_enable(st
|
||||
{
|
||||
int i;
|
||||
|
||||
+ set_bit(ATH11K_FLAG_EXT_IRQ_ENABLED, &ab->dev_flags);
|
||||
+
|
||||
for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) {
|
||||
struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i];
|
||||
|
||||
@@ -706,6 +716,10 @@ static int ath11k_pci_ext_grp_napi_poll(
|
||||
static irqreturn_t ath11k_pci_ext_interrupt_handler(int irq, void *arg)
|
||||
{
|
||||
struct ath11k_ext_irq_grp *irq_grp = arg;
|
||||
+ struct ath11k_base *ab = irq_grp->ab;
|
||||
+
|
||||
+ if (!test_bit(ATH11K_FLAG_EXT_IRQ_ENABLED, &ab->dev_flags))
|
||||
+ return IRQ_HANDLED;
|
||||
|
||||
ath11k_dbg(irq_grp->ab, ATH11K_DBG_PCI, "ext irq:%d\n", irq);
|
||||
|
||||
@@ -852,6 +866,8 @@ static void ath11k_pci_ce_irqs_enable(st
|
||||
{
|
||||
int i;
|
||||
|
||||
+ set_bit(ATH11K_FLAG_CE_IRQ_ENABLED, &ab->dev_flags);
|
||||
+
|
||||
for (i = 0; i < ab->hw_params.ce_count; i++) {
|
||||
if (ath11k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR)
|
||||
continue;
|
@ -0,0 +1,50 @@
|
||||
From 4ab4693f327ad015c4637ae42dc53c8471aed9c8 Mon Sep 17 00:00:00 2001
|
||||
From: Carl Huang <cjhuang@codeaurora.org>
|
||||
Date: Fri, 19 Nov 2021 15:36:26 +0200
|
||||
Subject: [PATCH 106/120] ath11k: use ATH11K_PCI_IRQ_DP_OFFSET for DP IRQ
|
||||
|
||||
Like ATH11K_PCI_IRQ_CE0_OFFSET, define ATH11K_PCI_IRQ_DP_OFFSET for
|
||||
DP to save the IRQ instead of base_vector from MSI config.
|
||||
|
||||
Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1
|
||||
|
||||
Signed-off-by: Carl Huang <cjhuang@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Signed-off-by: Baochen Qiang <bqiang@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20211026041655.5112-1-bqiang@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/pci.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/pci.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/pci.c
|
||||
@@ -16,7 +16,8 @@
|
||||
#define ATH11K_PCI_BAR_NUM 0
|
||||
#define ATH11K_PCI_DMA_MASK 32
|
||||
|
||||
-#define ATH11K_PCI_IRQ_CE0_OFFSET 3
|
||||
+#define ATH11K_PCI_IRQ_CE0_OFFSET 3
|
||||
+#define ATH11K_PCI_IRQ_DP_OFFSET 14
|
||||
|
||||
#define WINDOW_ENABLE_BIT 0x40000000
|
||||
#define WINDOW_REG_ADDRESS 0x310c
|
||||
@@ -736,9 +737,8 @@ static irqreturn_t ath11k_pci_ext_interr
|
||||
static int ath11k_pci_ext_irq_config(struct ath11k_base *ab)
|
||||
{
|
||||
int i, j, ret, num_vectors = 0;
|
||||
- u32 user_base_data = 0, base_vector = 0, base_idx;
|
||||
+ u32 user_base_data = 0, base_vector = 0;
|
||||
|
||||
- base_idx = ATH11K_PCI_IRQ_CE0_OFFSET + CE_COUNT_MAX;
|
||||
ret = ath11k_pci_get_user_msi_assignment(ath11k_pci_priv(ab), "DP",
|
||||
&num_vectors,
|
||||
&user_base_data,
|
||||
@@ -768,7 +768,7 @@ static int ath11k_pci_ext_irq_config(str
|
||||
}
|
||||
|
||||
irq_grp->num_irq = num_irq;
|
||||
- irq_grp->irqs[0] = base_idx + i;
|
||||
+ irq_grp->irqs[0] = ATH11K_PCI_IRQ_DP_OFFSET + i;
|
||||
|
||||
for (j = 0; j < irq_grp->num_irq; j++) {
|
||||
int irq_idx = irq_grp->irqs[j];
|
@ -0,0 +1,173 @@
|
||||
From c41a6700b276ddf6ef93dcb43baca51ea0c4c7c1 Mon Sep 17 00:00:00 2001
|
||||
From: Carl Huang <cjhuang@codeaurora.org>
|
||||
Date: Fri, 19 Nov 2021 15:36:26 +0200
|
||||
Subject: [PATCH 107/120] ath11k: refactor multiple MSI vector implementation
|
||||
|
||||
This is to prepare for one MSI vector support. IRQ enable and disable
|
||||
of CE and DP are done only in case of multiple MSI vectors.
|
||||
|
||||
Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1
|
||||
|
||||
Signed-off-by: Carl Huang <cjhuang@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Signed-off-by: Baochen Qiang <bqiang@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20211026041705.5167-1-bqiang@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/pci.c | 48 ++++++++++++++++++++++-----
|
||||
drivers/net/wireless/ath/ath11k/pci.h | 3 ++
|
||||
2 files changed, 43 insertions(+), 8 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/pci.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/pci.c
|
||||
@@ -486,11 +486,11 @@ int ath11k_pci_get_user_msi_assignment(s
|
||||
for (idx = 0; idx < msi_config->total_users; idx++) {
|
||||
if (strcmp(user_name, msi_config->users[idx].name) == 0) {
|
||||
*num_vectors = msi_config->users[idx].num_vectors;
|
||||
- *user_base_data = msi_config->users[idx].base_vector
|
||||
- + ab_pci->msi_ep_base_data;
|
||||
- *base_vector = msi_config->users[idx].base_vector;
|
||||
+ *base_vector = msi_config->users[idx].base_vector;
|
||||
+ *user_base_data = *base_vector + ab_pci->msi_ep_base_data;
|
||||
|
||||
- ath11k_dbg(ab, ATH11K_DBG_PCI, "Assign MSI to user: %s, num_vectors: %d, user_base_data: %u, base_vector: %u\n",
|
||||
+ ath11k_dbg(ab, ATH11K_DBG_PCI,
|
||||
+ "Assign MSI to user: %s, num_vectors: %d, user_base_data: %u, base_vector: %u\n",
|
||||
user_name, *num_vectors, *user_base_data,
|
||||
*base_vector);
|
||||
|
||||
@@ -561,16 +561,30 @@ static void ath11k_pci_free_irq(struct a
|
||||
|
||||
static void ath11k_pci_ce_irq_enable(struct ath11k_base *ab, u16 ce_id)
|
||||
{
|
||||
+ struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);
|
||||
u32 irq_idx;
|
||||
|
||||
+ /* In case of one MSI vector, we handle irq enable/disable in a
|
||||
+ * uniform way since we only have one irq
|
||||
+ */
|
||||
+ if (!test_bit(ATH11K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags))
|
||||
+ return;
|
||||
+
|
||||
irq_idx = ATH11K_PCI_IRQ_CE0_OFFSET + ce_id;
|
||||
enable_irq(ab->irq_num[irq_idx]);
|
||||
}
|
||||
|
||||
static void ath11k_pci_ce_irq_disable(struct ath11k_base *ab, u16 ce_id)
|
||||
{
|
||||
+ struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);
|
||||
u32 irq_idx;
|
||||
|
||||
+ /* In case of one MSI vector, we handle irq enable/disable in a
|
||||
+ * uniform way since we only have one irq
|
||||
+ */
|
||||
+ if (!test_bit(ATH11K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags))
|
||||
+ return;
|
||||
+
|
||||
irq_idx = ATH11K_PCI_IRQ_CE0_OFFSET + ce_id;
|
||||
disable_irq_nosync(ab->irq_num[irq_idx]);
|
||||
}
|
||||
@@ -630,8 +644,15 @@ static irqreturn_t ath11k_pci_ce_interru
|
||||
|
||||
static void ath11k_pci_ext_grp_disable(struct ath11k_ext_irq_grp *irq_grp)
|
||||
{
|
||||
+ struct ath11k_pci *ab_pci = ath11k_pci_priv(irq_grp->ab);
|
||||
int i;
|
||||
|
||||
+ /* In case of one MSI vector, we handle irq enable/disable
|
||||
+ * in a uniform way since we only have one irq
|
||||
+ */
|
||||
+ if (!test_bit(ATH11K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags))
|
||||
+ return;
|
||||
+
|
||||
for (i = 0; i < irq_grp->num_irq; i++)
|
||||
disable_irq_nosync(irq_grp->ab->irq_num[irq_grp->irqs[i]]);
|
||||
}
|
||||
@@ -654,8 +675,15 @@ static void __ath11k_pci_ext_irq_disable
|
||||
|
||||
static void ath11k_pci_ext_grp_enable(struct ath11k_ext_irq_grp *irq_grp)
|
||||
{
|
||||
+ struct ath11k_pci *ab_pci = ath11k_pci_priv(irq_grp->ab);
|
||||
int i;
|
||||
|
||||
+ /* In case of one MSI vector, we handle irq enable/disable in a
|
||||
+ * uniform way since we only have one irq
|
||||
+ */
|
||||
+ if (!test_bit(ATH11K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags))
|
||||
+ return;
|
||||
+
|
||||
for (i = 0; i < irq_grp->num_irq; i++)
|
||||
enable_irq(irq_grp->ab->irq_num[irq_grp->irqs[i]]);
|
||||
}
|
||||
@@ -736,6 +764,7 @@ static irqreturn_t ath11k_pci_ext_interr
|
||||
|
||||
static int ath11k_pci_ext_irq_config(struct ath11k_base *ab)
|
||||
{
|
||||
+ struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);
|
||||
int i, j, ret, num_vectors = 0;
|
||||
u32 user_base_data = 0, base_vector = 0;
|
||||
|
||||
@@ -782,16 +811,15 @@ static int ath11k_pci_ext_irq_config(str
|
||||
|
||||
irq_set_status_flags(irq, IRQ_DISABLE_UNLAZY);
|
||||
ret = request_irq(irq, ath11k_pci_ext_interrupt_handler,
|
||||
- IRQF_SHARED,
|
||||
+ ab_pci->irq_flags,
|
||||
"DP_EXT_IRQ", irq_grp);
|
||||
if (ret) {
|
||||
ath11k_err(ab, "failed request irq %d: %d\n",
|
||||
vector, ret);
|
||||
return ret;
|
||||
}
|
||||
-
|
||||
- disable_irq_nosync(ab->irq_num[irq_idx]);
|
||||
}
|
||||
+ ath11k_pci_ext_grp_disable(irq_grp);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -799,6 +827,7 @@ static int ath11k_pci_ext_irq_config(str
|
||||
|
||||
static int ath11k_pci_config_irq(struct ath11k_base *ab)
|
||||
{
|
||||
+ struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);
|
||||
struct ath11k_ce_pipe *ce_pipe;
|
||||
u32 msi_data_start;
|
||||
u32 msi_data_count, msi_data_idx;
|
||||
@@ -826,7 +855,7 @@ static int ath11k_pci_config_irq(struct
|
||||
tasklet_setup(&ce_pipe->intr_tq, ath11k_pci_ce_tasklet);
|
||||
|
||||
ret = request_irq(irq, ath11k_pci_ce_interrupt_handler,
|
||||
- IRQF_SHARED, irq_name[irq_idx],
|
||||
+ ab_pci->irq_flags, irq_name[irq_idx],
|
||||
ce_pipe);
|
||||
if (ret) {
|
||||
ath11k_err(ab, "failed to request irq %d: %d\n",
|
||||
@@ -920,6 +949,9 @@ static int ath11k_pci_alloc_msi(struct a
|
||||
return -EINVAL;
|
||||
else
|
||||
return num_vectors;
|
||||
+ } else {
|
||||
+ set_bit(ATH11K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags);
|
||||
+ ab_pci->irq_flags = IRQF_SHARED;
|
||||
}
|
||||
ath11k_pci_msi_disable(ab_pci);
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/pci.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/pci.h
|
||||
@@ -68,6 +68,7 @@ enum ath11k_pci_flags {
|
||||
ATH11K_PCI_FLAG_INIT_DONE,
|
||||
ATH11K_PCI_FLAG_IS_MSI_64,
|
||||
ATH11K_PCI_ASPM_RESTORE,
|
||||
+ ATH11K_PCI_FLAG_MULTI_MSI_VECTORS,
|
||||
};
|
||||
|
||||
struct ath11k_pci {
|
||||
@@ -87,6 +88,8 @@ struct ath11k_pci {
|
||||
/* enum ath11k_pci_flags */
|
||||
unsigned long flags;
|
||||
u16 link_ctl;
|
||||
+
|
||||
+ unsigned long irq_flags;
|
||||
};
|
||||
|
||||
static inline struct ath11k_pci *ath11k_pci_priv(struct ath11k_base *ab)
|
@ -0,0 +1,195 @@
|
||||
From ac6e73483f7b4b5bde23b14fc3aaafc8341ae0c7 Mon Sep 17 00:00:00 2001
|
||||
From: Carl Huang <cjhuang@codeaurora.org>
|
||||
Date: Fri, 19 Nov 2021 15:36:26 +0200
|
||||
Subject: [PATCH 108/120] ath11k: add support one MSI vector
|
||||
|
||||
On some platforms it's not possible to allocate 32 MSI vectors for various
|
||||
reasons, be it kernel configuration, VT-d disabled, buggy BIOS etc. So
|
||||
ath11k was not able to use QCA6390 PCI devices on those platforms. Add
|
||||
support for one MSI vector to solve that.
|
||||
|
||||
In case of one MSI vector, interrupt migration needs to be disabled. This
|
||||
is because when interrupt migration happens, the msi_data may change.
|
||||
However, msi_data is already programmed to rings during initial phase and
|
||||
ath11k has no way to know that msi_data is changed during run time and
|
||||
reprogram again.
|
||||
|
||||
In case of one MSI vector, MHI subsystem should not use IRQF_NO_SUSPEND
|
||||
as QCA6390 doesn't set this flag too. Ath11k doesn't need to leave
|
||||
IRQ enabled in suspend state.
|
||||
|
||||
Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1
|
||||
|
||||
Signed-off-by: Carl Huang <cjhuang@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
Signed-off-by: Baochen Qiang <bqiang@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20211026041714.5219-1-bqiang@codeaurora.org
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/mhi.c | 14 ++++++--
|
||||
drivers/net/wireless/ath/ath11k/pci.c | 52 ++++++++++++++++++++-------
|
||||
2 files changed, 51 insertions(+), 15 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/mhi.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mhi.c
|
||||
@@ -248,6 +248,7 @@ static int ath11k_mhi_get_msi(struct ath
|
||||
u32 user_base_data, base_vector;
|
||||
int ret, num_vectors, i;
|
||||
int *irq;
|
||||
+ unsigned int msi_data;
|
||||
|
||||
ret = ath11k_pci_get_user_msi_assignment(ab_pci,
|
||||
"MHI", &num_vectors,
|
||||
@@ -262,9 +263,15 @@ static int ath11k_mhi_get_msi(struct ath
|
||||
if (!irq)
|
||||
return -ENOMEM;
|
||||
|
||||
- for (i = 0; i < num_vectors; i++)
|
||||
+ for (i = 0; i < num_vectors; i++) {
|
||||
+ msi_data = base_vector;
|
||||
+
|
||||
+ if (test_bit(ATH11K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags))
|
||||
+ msi_data += i;
|
||||
+
|
||||
irq[i] = ath11k_pci_get_msi_irq(ab->dev,
|
||||
- base_vector + i);
|
||||
+ msi_data);
|
||||
+ }
|
||||
|
||||
ab_pci->mhi_ctrl->irq = irq;
|
||||
ab_pci->mhi_ctrl->nr_irqs = num_vectors;
|
||||
@@ -341,6 +348,9 @@ int ath11k_mhi_register(struct ath11k_pc
|
||||
return ret;
|
||||
}
|
||||
|
||||
+ if (!test_bit(ATH11K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags))
|
||||
+ mhi_ctrl->irq_flags = IRQF_SHARED | IRQF_NOBALANCING;
|
||||
+
|
||||
mhi_ctrl->iova_start = 0;
|
||||
mhi_ctrl->iova_stop = 0xffffffff;
|
||||
mhi_ctrl->sbl_size = SZ_512K;
|
||||
--- a/drivers/net/wireless/ath/ath11k/pci.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/pci.c
|
||||
@@ -77,6 +77,17 @@ static const struct ath11k_msi_config at
|
||||
},
|
||||
};
|
||||
|
||||
+static const struct ath11k_msi_config msi_config_one_msi = {
|
||||
+ .total_vectors = 1,
|
||||
+ .total_users = 4,
|
||||
+ .users = (struct ath11k_msi_user[]) {
|
||||
+ { .name = "MHI", .num_vectors = 3, .base_vector = 0 },
|
||||
+ { .name = "CE", .num_vectors = 1, .base_vector = 0 },
|
||||
+ { .name = "WAKE", .num_vectors = 1, .base_vector = 0 },
|
||||
+ { .name = "DP", .num_vectors = 1, .base_vector = 0 },
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
static const char *irq_name[ATH11K_IRQ_NUM_MAX] = {
|
||||
"bhi",
|
||||
"mhi-er0",
|
||||
@@ -619,16 +630,18 @@ static void ath11k_pci_sync_ce_irqs(stru
|
||||
static void ath11k_pci_ce_tasklet(struct tasklet_struct *t)
|
||||
{
|
||||
struct ath11k_ce_pipe *ce_pipe = from_tasklet(ce_pipe, t, intr_tq);
|
||||
+ int irq_idx = ATH11K_PCI_IRQ_CE0_OFFSET + ce_pipe->pipe_num;
|
||||
|
||||
ath11k_ce_per_engine_service(ce_pipe->ab, ce_pipe->pipe_num);
|
||||
|
||||
- ath11k_pci_ce_irq_enable(ce_pipe->ab, ce_pipe->pipe_num);
|
||||
+ enable_irq(ce_pipe->ab->irq_num[irq_idx]);
|
||||
}
|
||||
|
||||
static irqreturn_t ath11k_pci_ce_interrupt_handler(int irq, void *arg)
|
||||
{
|
||||
struct ath11k_ce_pipe *ce_pipe = arg;
|
||||
struct ath11k_base *ab = ce_pipe->ab;
|
||||
+ int irq_idx = ATH11K_PCI_IRQ_CE0_OFFSET + ce_pipe->pipe_num;
|
||||
|
||||
if (!test_bit(ATH11K_FLAG_CE_IRQ_ENABLED, &ab->dev_flags))
|
||||
return IRQ_HANDLED;
|
||||
@@ -636,7 +649,8 @@ static irqreturn_t ath11k_pci_ce_interru
|
||||
/* last interrupt received for this CE */
|
||||
ce_pipe->timestamp = jiffies;
|
||||
|
||||
- ath11k_pci_ce_irq_disable(ce_pipe->ab, ce_pipe->pipe_num);
|
||||
+ disable_irq_nosync(ab->irq_num[irq_idx]);
|
||||
+
|
||||
tasklet_schedule(&ce_pipe->intr_tq);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
@@ -729,11 +743,13 @@ static int ath11k_pci_ext_grp_napi_poll(
|
||||
napi);
|
||||
struct ath11k_base *ab = irq_grp->ab;
|
||||
int work_done;
|
||||
+ int i;
|
||||
|
||||
work_done = ath11k_dp_service_srng(ab, irq_grp, budget);
|
||||
if (work_done < budget) {
|
||||
napi_complete_done(napi, work_done);
|
||||
- ath11k_pci_ext_grp_enable(irq_grp);
|
||||
+ for (i = 0; i < irq_grp->num_irq; i++)
|
||||
+ enable_irq(irq_grp->ab->irq_num[irq_grp->irqs[i]]);
|
||||
}
|
||||
|
||||
if (work_done > budget)
|
||||
@@ -746,6 +762,7 @@ static irqreturn_t ath11k_pci_ext_interr
|
||||
{
|
||||
struct ath11k_ext_irq_grp *irq_grp = arg;
|
||||
struct ath11k_base *ab = irq_grp->ab;
|
||||
+ int i;
|
||||
|
||||
if (!test_bit(ATH11K_FLAG_EXT_IRQ_ENABLED, &ab->dev_flags))
|
||||
return IRQ_HANDLED;
|
||||
@@ -755,7 +772,8 @@ static irqreturn_t ath11k_pci_ext_interr
|
||||
/* last interrupt received for this group */
|
||||
irq_grp->timestamp = jiffies;
|
||||
|
||||
- ath11k_pci_ext_grp_disable(irq_grp);
|
||||
+ for (i = 0; i < irq_grp->num_irq; i++)
|
||||
+ disable_irq_nosync(irq_grp->ab->irq_num[irq_grp->irqs[i]]);
|
||||
|
||||
napi_schedule(&irq_grp->napi);
|
||||
|
||||
@@ -941,18 +959,25 @@ static int ath11k_pci_alloc_msi(struct a
|
||||
msi_config->total_vectors,
|
||||
msi_config->total_vectors,
|
||||
PCI_IRQ_MSI);
|
||||
- if (num_vectors != msi_config->total_vectors) {
|
||||
- ath11k_err(ab, "failed to get %d MSI vectors, only %d available",
|
||||
- msi_config->total_vectors, num_vectors);
|
||||
-
|
||||
- if (num_vectors >= 0)
|
||||
- return -EINVAL;
|
||||
- else
|
||||
- return num_vectors;
|
||||
- } else {
|
||||
+ if (num_vectors == msi_config->total_vectors) {
|
||||
set_bit(ATH11K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags);
|
||||
ab_pci->irq_flags = IRQF_SHARED;
|
||||
+ } else {
|
||||
+ num_vectors = pci_alloc_irq_vectors(ab_pci->pdev,
|
||||
+ 1,
|
||||
+ 1,
|
||||
+ PCI_IRQ_MSI);
|
||||
+ if (num_vectors < 0) {
|
||||
+ ret = -EINVAL;
|
||||
+ goto reset_msi_config;
|
||||
+ }
|
||||
+ clear_bit(ATH11K_PCI_FLAG_MULTI_MSI_VECTORS, &ab_pci->flags);
|
||||
+ ab_pci->msi_config = &msi_config_one_msi;
|
||||
+ ab_pci->irq_flags = IRQF_SHARED | IRQF_NOBALANCING;
|
||||
+ ath11k_dbg(ab, ATH11K_DBG_PCI, "request MSI one vector\n");
|
||||
}
|
||||
+ ath11k_info(ab, "MSI vectors: %d\n", num_vectors);
|
||||
+
|
||||
ath11k_pci_msi_disable(ab_pci);
|
||||
|
||||
msi_desc = irq_get_msi_desc(ab_pci->pdev->irq);
|
||||
@@ -973,6 +998,7 @@ static int ath11k_pci_alloc_msi(struct a
|
||||
free_msi_vector:
|
||||
pci_free_irq_vectors(ab_pci->pdev);
|
||||
|
||||
+reset_msi_config:
|
||||
return ret;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user