From fdb8fc34a6fbf8c7614f222cbe1176a0598f1941 Mon Sep 17 00:00:00 2001 From: Sriram R Date: Mon, 16 May 2022 13:25:59 +0300 Subject: [PATCH 01/22] ath11k: update missing MU-MIMO and OFDMA stats Update the missing MU-MIMO/OFDMA info in PDEV RX, trigger and schedule stats. i.e HTT stats type 10, 12 and 17 respectively. Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4-01209-QCAHKSWPL_SILICONZ-1 Signed-off-by: Sriram R Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/1652152236-12038-1-git-send-email-quic_srirrama@quicinc.com --- .../wireless/ath/ath11k/debugfs_htt_stats.c | 88 ++++++++++++++++++- .../wireless/ath/ath11k/debugfs_htt_stats.h | 39 ++++++++ 2 files changed, 126 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.c b/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.c index 4484235bcda41..b3efca6bd7ddb 100644 --- a/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.c +++ b/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -1403,6 +1404,8 @@ htt_print_tx_selfgen_ax_stats_tlv(const void *tag_buf, htt_stats_buf->ax_mu_mimo_brpoll_7); len += scnprintf(buf + len, buf_len - len, "ax_basic_trigger = %u\n", htt_stats_buf->ax_basic_trigger); + len += scnprintf(buf + len, buf_len - len, "ax_ulmumimo_trigger = %u\n", + htt_stats_buf->ax_ulmumimo_trigger); len += scnprintf(buf + len, buf_len - len, "ax_bsr_trigger = %u\n", htt_stats_buf->ax_bsr_trigger); len += scnprintf(buf + len, buf_len - len, "ax_mu_bar_trigger = %u\n", @@ -1485,6 +1488,8 @@ htt_print_tx_selfgen_ax_err_stats_tlv(const void *tag_buf, htt_stats_buf->ax_mu_mimo_brp7_err); len += scnprintf(buf + len, buf_len - len, "ax_basic_trigger_err = %u\n", htt_stats_buf->ax_basic_trigger_err); + len += scnprintf(buf + len, buf_len - len, "ax_ulmumimo_trigger_err = %u\n", + htt_stats_buf->ax_ulmumimo_trigger_err); len += scnprintf(buf + len, buf_len - len, "ax_bsr_trigger_err = %u\n", htt_stats_buf->ax_bsr_trigger_err); len += scnprintf(buf + len, buf_len - len, "ax_mu_bar_trigger_err = %u\n", @@ -1519,6 +1524,16 @@ htt_print_tx_pdev_mu_mimo_sch_stats_tlv(const void *tag_buf, len += scnprintf(buf + len, buf_len - len, "mu_mimo_ppdu_posted = %u\n\n", htt_stats_buf->mu_mimo_ppdu_posted); + for (i = 0; i < HTT_TX_PDEV_STATS_NUM_AC_MUMIMO_USER_STATS; i++) + len += scnprintf(buf + len, buf_len - len, + "ac_mu_mimo_sch_posted_per_group_index %u = %u\n", + i, htt_stats_buf->ac_mu_mimo_sch_posted_per_grp_sz[i]); + + for (i = 0; i < HTT_TX_PDEV_STATS_NUM_AX_MUMIMO_USER_STATS; i++) + len += scnprintf(buf + len, buf_len - len, + "ax_mu_mimo_sch_posted_per_group_index %u = %u\n", + i, htt_stats_buf->ax_mu_mimo_sch_posted_per_grp_sz[i]); + len += scnprintf(buf + len, buf_len - len, "11ac MU_MIMO SCH STATS:\n"); for (i = 0; i < HTT_TX_PDEV_STATS_NUM_AC_MUMIMO_USER_STATS; i++) @@ -1535,10 +1550,34 @@ htt_print_tx_pdev_mu_mimo_sch_stats_tlv(const void *tag_buf, len += scnprintf(buf + len, buf_len - len, "\n11ax OFDMA SCH STATS:\n"); - for (i = 0; i < HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS; i++) + for (i = 0; i < HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS; i++) { len += scnprintf(buf + len, buf_len - len, "ax_ofdma_sch_nusers_%u = %u\n", i, htt_stats_buf->ax_ofdma_sch_nusers[i]); + len += scnprintf(buf + len, buf_len - len, + "ax_ul_ofdma_basic_sch_nusers_%u = %u\n", + i, htt_stats_buf->ax_ul_ofdma_basic_sch_nusers[i]); + len += scnprintf(buf + len, buf_len - len, + "ax_ul_ofdma_bsr_sch_nusers_%u = %u\n", + i, htt_stats_buf->ax_ul_ofdma_bsr_sch_nusers[i]); + len += scnprintf(buf + len, buf_len - len, + "ax_ul_ofdma_sch_bar_nusers_%u = %u\n", + i, htt_stats_buf->ax_ul_ofdma_bar_sch_nusers[i]); + len += scnprintf(buf + len, buf_len - len, + "ax_ul_ofdma_brp_sch_nusers_%u = %u\n", + i, htt_stats_buf->ax_ul_ofdma_brp_sch_nusers[i]); + } + + len += scnprintf(buf + len, buf_len - len, "\n11ax UL MUMIO SCH STATS:\n"); + + for (i = 0; i < HTT_TX_PDEV_STATS_NUM_UL_MUMIMO_USER_STATS; i++) { + len += scnprintf(buf + len, buf_len - len, + "ax_ul_mumimo_basic_sch_nusers_%u = %u\n", + i, htt_stats_buf->ax_ul_mumimo_basic_sch_nusers[i]); + len += scnprintf(buf + len, buf_len - len, + "ax_ul_mumimo_brp_sch_nusers_%u = %u\n", + i, htt_stats_buf->ax_ul_mumimo_brp_sch_nusers[i]); + } if (len >= buf_len) buf[buf_len - 1] = 0; @@ -2933,6 +2972,21 @@ static inline void htt_print_rx_pdev_rate_stats_tlv(const void *tag_buf, len += scnprintf(buf + len, buf_len - len, "txbf = %u\n", htt_stats_buf->txbf); + len += scnprintf(buf + len, buf_len - len, "\nrx_su_ndpa = %u", + htt_stats_buf->rx_su_ndpa); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_11ax_su_txbf_mcs, + "rx_11ax_su_txbf_mcs", HTT_RX_PDEV_STATS_NUM_MCS_COUNTERS, + "\n"); + + len += scnprintf(buf + len, buf_len - len, "\nrx_mu_ndpa = %u", + htt_stats_buf->rx_mu_ndpa); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_11ax_mu_txbf_mcs, + "rx_11ax_mu_txbf_mcs", HTT_RX_PDEV_STATS_NUM_MCS_COUNTERS, + "\n"); + + len += scnprintf(buf + len, buf_len - len, "\nrx_br_poll = %u", + htt_stats_buf->rx_br_poll); + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_legacy_cck_rate, "rx_legacy_cck_rate", HTT_RX_PDEV_STATS_NUM_LEGACY_CCK_STATS, "\n"); @@ -2995,6 +3049,38 @@ static inline void htt_print_rx_pdev_rate_stats_tlv(const void *tag_buf, len += scnprintf(buf + len, buf_len - len, "\n"); } + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_ulofdma_non_data_nusers, + "rx_ulofdma_non_data_nusers", HTT_RX_PDEV_MAX_OFDMA_NUM_USER, + "\n"); + + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_ulofdma_data_nusers, + "rx_ulofdma_data_nusers", HTT_RX_PDEV_MAX_OFDMA_NUM_USER, + "\n"); + + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_11ax_dl_ofdma_mcs, + "rx_11ax_dl_ofdma_mcs", HTT_RX_PDEV_STATS_NUM_MCS_COUNTERS, + "\n"); + + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_11ax_dl_ofdma_ru, + "rx_11ax_dl_ofdma_ru", HTT_RX_PDEV_STATS_NUM_RU_SIZE_COUNTERS, + "\n"); + + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_ulmumimo_non_data_ppdu, + "rx_ulmumimo_non_data_ppdu", HTT_RX_PDEV_MAX_ULMUMIMO_NUM_USER, + "\n"); + + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_ulmumimo_data_ppdu, + "rx_ulmumimo_data_ppdu", HTT_RX_PDEV_MAX_ULMUMIMO_NUM_USER, + "\n"); + + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_ulmumimo_mpdu_ok, + "rx_ulmumimo_mpdu_ok", HTT_RX_PDEV_MAX_ULMUMIMO_NUM_USER, + "\n"); + + PRINT_ARRAY_TO_BUF(buf, len, htt_stats_buf->rx_ulmumimo_mpdu_fail, + "rx_ulmumimo_mpdu_fail", HTT_RX_PDEV_MAX_ULMUMIMO_NUM_USER, + "\n"); + len += scnprintf(buf + len, buf_len - len, "per_chain_rssi_pkt_type = %#x\n", htt_stats_buf->per_chain_rssi_pkt_type); diff --git a/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.h b/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.h index dc210c54d1310..5d722b51b1258 100644 --- a/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.h +++ b/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef DEBUG_HTT_STATS_H @@ -682,6 +683,7 @@ struct htt_tx_selfgen_ax_stats_tlv { u32 ax_bsr_trigger; u32 ax_mu_bar_trigger; u32 ax_mu_rts_trigger; + u32 ax_ulmumimo_trigger; }; struct htt_tx_selfgen_ac_err_stats_tlv { @@ -712,12 +714,14 @@ struct htt_tx_selfgen_ax_err_stats_tlv { u32 ax_bsr_trigger_err; u32 ax_mu_bar_trigger_err; u32 ax_mu_rts_trigger_err; + u32 ax_ulmumimo_trigger_err; }; /* == TX MU STATS == */ #define HTT_TX_PDEV_STATS_NUM_AC_MUMIMO_USER_STATS 4 #define HTT_TX_PDEV_STATS_NUM_AX_MUMIMO_USER_STATS 8 #define HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS 74 +#define HTT_TX_PDEV_STATS_NUM_UL_MUMIMO_USER_STATS 8 struct htt_tx_pdev_mu_mimo_sch_stats_tlv { /* mu-mimo sw sched cmd stats */ @@ -734,6 +738,24 @@ struct htt_tx_pdev_mu_mimo_sch_stats_tlv { u32 ac_mu_mimo_sch_nusers[HTT_TX_PDEV_STATS_NUM_AC_MUMIMO_USER_STATS]; u32 ax_mu_mimo_sch_nusers[HTT_TX_PDEV_STATS_NUM_AX_MUMIMO_USER_STATS]; u32 ax_ofdma_sch_nusers[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS]; + u32 ax_ul_ofdma_basic_sch_nusers[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS]; + u32 ax_ul_ofdma_bsr_sch_nusers[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS]; + u32 ax_ul_ofdma_bar_sch_nusers[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS]; + u32 ax_ul_ofdma_brp_sch_nusers[HTT_TX_PDEV_STATS_NUM_OFDMA_USER_STATS]; + + /* UL MU-MIMO */ + /* ax_ul_mumimo_basic_sch_nusers[i] is the number of basic triggers sent + * for (i+1) users + */ + u32 ax_ul_mumimo_basic_sch_nusers[HTT_TX_PDEV_STATS_NUM_UL_MUMIMO_USER_STATS]; + + /* ax_ul_mumimo_brp_sch_nusers[i] is the number of brp triggers sent + * for (i+1) users + */ + u32 ax_ul_mumimo_brp_sch_nusers[HTT_TX_PDEV_STATS_NUM_UL_MUMIMO_USER_STATS]; + + u32 ac_mu_mimo_sch_posted_per_grp_sz[HTT_TX_PDEV_STATS_NUM_AC_MUMIMO_USER_STATS]; + u32 ax_mu_mimo_sch_posted_per_grp_sz[HTT_TX_PDEV_STATS_NUM_AX_MUMIMO_USER_STATS]; }; struct htt_tx_pdev_mu_mimo_mpdu_stats_tlv { @@ -1297,6 +1319,8 @@ struct htt_tx_pdev_rate_stats_tlv { #define HTT_RX_PDEV_STATS_NUM_PREAMBLE_TYPES HTT_STATS_PREAM_COUNT #define HTT_RX_PDEV_MAX_OFDMA_NUM_USER 8 #define HTT_RX_PDEV_STATS_RXEVM_MAX_PILOTS_PER_NSS 16 +#define HTT_RX_PDEV_STATS_NUM_RU_SIZE_COUNTERS 6 +#define HTT_RX_PDEV_MAX_ULMUMIMO_NUM_USER 8 struct htt_rx_pdev_rate_stats_tlv { u32 mac_id__word; @@ -1375,6 +1399,21 @@ struct htt_rx_pdev_rate_stats_tlv { u32 per_chain_rssi_pkt_type; s8 rx_per_chain_rssi_in_dbm[HTT_RX_PDEV_STATS_NUM_SPATIAL_STREAMS] [HTT_RX_PDEV_STATS_NUM_BW_COUNTERS]; + + u32 rx_su_ndpa; + u32 rx_11ax_su_txbf_mcs[HTT_RX_PDEV_STATS_NUM_MCS_COUNTERS]; + u32 rx_mu_ndpa; + u32 rx_11ax_mu_txbf_mcs[HTT_RX_PDEV_STATS_NUM_MCS_COUNTERS]; + u32 rx_br_poll; + u32 rx_11ax_dl_ofdma_mcs[HTT_RX_PDEV_STATS_NUM_MCS_COUNTERS]; + u32 rx_11ax_dl_ofdma_ru[HTT_RX_PDEV_STATS_NUM_RU_SIZE_COUNTERS]; + + u32 rx_ulmumimo_non_data_ppdu[HTT_RX_PDEV_MAX_ULMUMIMO_NUM_USER]; + u32 rx_ulmumimo_data_ppdu[HTT_RX_PDEV_MAX_ULMUMIMO_NUM_USER]; + u32 rx_ulmumimo_mpdu_ok[HTT_RX_PDEV_MAX_ULMUMIMO_NUM_USER]; + u32 rx_ulmumimo_mpdu_fail[HTT_RX_PDEV_MAX_ULMUMIMO_NUM_USER]; + u32 rx_ulofdma_non_data_nusers[HTT_RX_PDEV_MAX_OFDMA_NUM_USER]; + u32 rx_ulofdma_data_nusers[HTT_RX_PDEV_MAX_OFDMA_NUM_USER]; }; /* == RX PDEV/SOC STATS == */ From 1ee6c5abebd3cacf2ac4378d0ed4f57fd4850421 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 18 May 2022 10:27:26 +0300 Subject: [PATCH 02/22] ath10k: do not enforce interrupt trigger type Interrupt line can be configured on different hardware in different way, even inverted. Therefore driver should not enforce specific trigger type - edge rising - but instead rely on Devicetree to configure it. All Qualcomm DTSI with WCN3990 define the interrupt type as level high, so the mismatch between DTSI and driver causes rebind issues: $ echo 18800000.wifi > /sys/bus/platform/drivers/ath10k_snoc/unbind $ echo 18800000.wifi > /sys/bus/platform/drivers/ath10k_snoc/bind [ 44.763114] irq: type mismatch, failed to map hwirq-446 for interrupt-controller@17a00000! [ 44.763130] ath10k_snoc 18800000.wifi: error -ENXIO: IRQ index 0 not found [ 44.763140] ath10k_snoc 18800000.wifi: failed to initialize resource: -6 Tested-on: WCN3990 hw1.0 SNOC WLAN.HL.3.2.0.c8-00009-QCAHLSWSC8180XMTPLZ-1 Tested-on: WCN3990 hw1.0 SNOC WLAN.HL.2.0-01387-QCAHLSWMTPLZ-1 Fixes: c963a683e701 ("ath10k: add resource init and deinit for WCN3990") Signed-off-by: Krzysztof Kozlowski Tested-by: Steev Klimaszewski Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220513151516.357549-1-krzysztof.kozlowski@linaro.org --- drivers/net/wireless/ath/ath10k/snoc.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/snoc.c b/drivers/net/wireless/ath/ath10k/snoc.c index 607e8164bf984..5576ad9fd1161 100644 --- a/drivers/net/wireless/ath/ath10k/snoc.c +++ b/drivers/net/wireless/ath/ath10k/snoc.c @@ -1249,13 +1249,12 @@ static void ath10k_snoc_init_napi(struct ath10k *ar) static int ath10k_snoc_request_irq(struct ath10k *ar) { struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); - int irqflags = IRQF_TRIGGER_RISING; int ret, id; for (id = 0; id < CE_COUNT_MAX; id++) { ret = request_irq(ar_snoc->ce_irqs[id].irq_line, - ath10k_snoc_per_engine_handler, - irqflags, ce_name[id], ar); + ath10k_snoc_per_engine_handler, 0, + ce_name[id], ar); if (ret) { ath10k_err(ar, "failed to register IRQ handler for CE %d: %d\n", From 2587d5198aa5adcbd8896aae4a2404dc13d48637 Mon Sep 17 00:00:00 2001 From: Sergey Ryazanov Date: Wed, 18 May 2022 10:27:26 +0300 Subject: [PATCH 03/22] ath10k: improve tx status reporting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We use ieee80211_tx_status() to report each completed tx frame. Internally, this function calls sta_info_get_by_addrs(), what has a couple of drawbacks: 1. additional station lookup causes a performance degradation; 2. mac80211 can not properly account Ethernet encapsulated frames due to the inability to properly determine the destination (station) MAC address since ieee80211_tx_status() assumes the frame has a 802.11 header. The latter is especially destructive if we want to use hardware frames encapsulation. To fix both of these issues, replace ieee80211_tx_status() with ieee80211_tx_status_ext() call and feed it station pointer from the tx queue associated with the transmitted frame. Tested-on: QCA9888 hw2.0 PCI 10.4-3.9.0.2-00131 Tested-on: QCA6174 hw3.2 PCI WLAN.RM.4.4.1-00157-QCARMSWPZ-1 Signed-off-by: Sergey Ryazanov Tested-by: Oldřich Jedlička # TP-Link Archer C7 v4 & v5 (QCA9563 + QCA9880) Tested-by: Edward Matijevic # TP-Link Archer C2600 (IPQ8064 + QCA9980 10.4.1.00030-1) Tested-by: Edward Matijevic # QCA9377 PCI in Sta mode Tested-by: Zhijun You # NETGEAR R7800 (QCA9984 10.4-3.9.0.2-00159) Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220516032519.29831-2-ryazanov.s.a@gmail.com --- drivers/net/wireless/ath/ath10k/txrx.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath10k/txrx.c b/drivers/net/wireless/ath/ath10k/txrx.c index 10123974c3da7..da3bc35e41aa0 100644 --- a/drivers/net/wireless/ath/ath10k/txrx.c +++ b/drivers/net/wireless/ath/ath10k/txrx.c @@ -43,6 +43,7 @@ static void ath10k_report_offchan_tx(struct ath10k *ar, struct sk_buff *skb) int ath10k_txrx_tx_unref(struct ath10k_htt *htt, const struct htt_tx_done *tx_done) { + struct ieee80211_tx_status status; struct ath10k *ar = htt->ar; struct device *dev = ar->dev; struct ieee80211_tx_info *info; @@ -128,7 +129,19 @@ int ath10k_txrx_tx_unref(struct ath10k_htt *htt, info->status.flags |= IEEE80211_TX_STATUS_ACK_SIGNAL_VALID; } - ieee80211_tx_status(htt->ar->hw, msdu); + memset(&status, 0, sizeof(status)); + status.skb = msdu; + status.info = info; + + rcu_read_lock(); + + if (txq) + status.sta = txq->sta; + + ieee80211_tx_status_ext(htt->ar->hw, &status); + + rcu_read_unlock(); + /* we do not own the msdu anymore */ return 0; From 70f119fb82af7f7417dc659faf02c91e1f853739 Mon Sep 17 00:00:00 2001 From: Sergey Ryazanov Date: Mon, 16 May 2022 13:26:00 +0300 Subject: [PATCH 04/22] ath10k: htt_tx: do not interpret Eth frames as WiFi The xmit path for the Ethernet encapsulated frames become more or less usable since d740d8fd2439 ("ath10k: unify tx mode and dispatch"). This change reorganize the xmit path in a manageable way to properly support various tx modes, but misses that the Ethernet encapsulated frame is a special case. We do not have an IEEE 802.11 header at the begining of them. But the HTT Tx handler still interprets first bytes of each frame as an IEEE 802.11 Frame Control field. Than this code was copied by e62ee5c381c5 ("ath10k: Add support for htt_data_tx_desc_64 descriptor") and a2097d6444c3 ("ath10k: htt: High latency TX support") to another handlers. In fact the issue in the high latency (HL) handler was introduced by 83ac260151e7 ("ath10k: add mic bytes for pmf management packet"). Ethernet encapsulated frame tx mode stay unused until 75d85fd9993c ("ath10k: introduce basic tdls functionality") started using it for TDLS frames to avoid key selection issue in some firmwares. Trying to interpret the begining of an Ethernet encapsulated frame as an IEEE 802.11 header was not hurt us noticeably since we need to meet two conditions: (1) xmit should be performed towards a TDLS peer, and (2) the TDLS peer should have a specific OUI part of its MAC address. Looks like that the rareness in TDLS communications of OUIs that can be interpreted as an 802.11 management frame saves users from facing this issue earlier. Improve Ethernet tx mode support in the HTT Tx handler by avoiding interpreting its first bytes as an IEEE 802.11 header. While at it, make the ieee80211_hdr variable local to the code block that is guarded by !is_eth check. In this way, we clarify in which cases a frame can be interpreted as IEEE 802.11, and saves us from similar issues in the future. Credits: this change as part of xmit encapsulation offloading support was originally made by QCA and then submitted for inclusion by John Crispin [1]. But the whole work was not accepted due to the lack of a part for 64-bits descriptors [2]. Zhijun You then pointed this out to me in a reply to my initial RFC patch series. And I made this slightly reworked version that covered all the HTT Tx handler variants. 1. https://lore.kernel.org/all/20191216092207.31032-1-john@phrozen.org/ 2. https://patchwork.kernel.org/project/linux-wireless/patch/20191216092207.31032-1-john@phrozen.org/ Reported-by: Zhijun You Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John Crispin Signed-off-by: Sergey Ryazanov Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220516032519.29831-3-ryazanov.s.a@gmail.com --- drivers/net/wireless/ath/ath10k/htt_tx.c | 61 ++++++++++++++---------- 1 file changed, 35 insertions(+), 26 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c index 9842a4b2f78f7..a19b0795c86d5 100644 --- a/drivers/net/wireless/ath/ath10k/htt_tx.c +++ b/drivers/net/wireless/ath/ath10k/htt_tx.c @@ -1275,7 +1275,6 @@ static int ath10k_htt_tx_hl(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txm struct ath10k *ar = htt->ar; int res, data_len; struct htt_cmd_hdr *cmd_hdr; - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data; struct htt_data_tx_desc *tx_desc; struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(msdu); struct sk_buff *tmp_skb; @@ -1286,11 +1285,15 @@ static int ath10k_htt_tx_hl(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txm u16 flags1 = 0; u16 msdu_id = 0; - if ((ieee80211_is_action(hdr->frame_control) || - ieee80211_is_deauth(hdr->frame_control) || - ieee80211_is_disassoc(hdr->frame_control)) && - ieee80211_has_protected(hdr->frame_control)) { - skb_put(msdu, IEEE80211_CCMP_MIC_LEN); + if (!is_eth) { + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data; + + if ((ieee80211_is_action(hdr->frame_control) || + ieee80211_is_deauth(hdr->frame_control) || + ieee80211_is_disassoc(hdr->frame_control)) && + ieee80211_has_protected(hdr->frame_control)) { + skb_put(msdu, IEEE80211_CCMP_MIC_LEN); + } } data_len = msdu->len; @@ -1387,7 +1390,6 @@ static int ath10k_htt_tx_32(struct ath10k_htt *htt, { struct ath10k *ar = htt->ar; struct device *dev = ar->dev; - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(msdu); struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(msdu); struct ath10k_hif_sg_item sg_items[2]; @@ -1419,15 +1421,19 @@ static int ath10k_htt_tx_32(struct ath10k_htt *htt, txbuf_paddr = htt->txbuf.paddr + (sizeof(struct ath10k_htt_txbuf_32) * msdu_id); - if ((ieee80211_is_action(hdr->frame_control) || - ieee80211_is_deauth(hdr->frame_control) || - ieee80211_is_disassoc(hdr->frame_control)) && - ieee80211_has_protected(hdr->frame_control)) { - skb_put(msdu, IEEE80211_CCMP_MIC_LEN); - } else if (!(skb_cb->flags & ATH10K_SKB_F_NO_HWCRYPT) && - txmode == ATH10K_HW_TXRX_RAW && - ieee80211_has_protected(hdr->frame_control)) { - skb_put(msdu, IEEE80211_CCMP_MIC_LEN); + if (!is_eth) { + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data; + + if ((ieee80211_is_action(hdr->frame_control) || + ieee80211_is_deauth(hdr->frame_control) || + ieee80211_is_disassoc(hdr->frame_control)) && + ieee80211_has_protected(hdr->frame_control)) { + skb_put(msdu, IEEE80211_CCMP_MIC_LEN); + } else if (!(skb_cb->flags & ATH10K_SKB_F_NO_HWCRYPT) && + txmode == ATH10K_HW_TXRX_RAW && + ieee80211_has_protected(hdr->frame_control)) { + skb_put(msdu, IEEE80211_CCMP_MIC_LEN); + } } skb_cb->paddr = dma_map_single(dev, msdu->data, msdu->len, @@ -1589,7 +1595,6 @@ static int ath10k_htt_tx_64(struct ath10k_htt *htt, { struct ath10k *ar = htt->ar; struct device *dev = ar->dev; - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(msdu); struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(msdu); struct ath10k_hif_sg_item sg_items[2]; @@ -1621,15 +1626,19 @@ static int ath10k_htt_tx_64(struct ath10k_htt *htt, txbuf_paddr = htt->txbuf.paddr + (sizeof(struct ath10k_htt_txbuf_64) * msdu_id); - if ((ieee80211_is_action(hdr->frame_control) || - ieee80211_is_deauth(hdr->frame_control) || - ieee80211_is_disassoc(hdr->frame_control)) && - ieee80211_has_protected(hdr->frame_control)) { - skb_put(msdu, IEEE80211_CCMP_MIC_LEN); - } else if (!(skb_cb->flags & ATH10K_SKB_F_NO_HWCRYPT) && - txmode == ATH10K_HW_TXRX_RAW && - ieee80211_has_protected(hdr->frame_control)) { - skb_put(msdu, IEEE80211_CCMP_MIC_LEN); + if (!is_eth) { + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data; + + if ((ieee80211_is_action(hdr->frame_control) || + ieee80211_is_deauth(hdr->frame_control) || + ieee80211_is_disassoc(hdr->frame_control)) && + ieee80211_has_protected(hdr->frame_control)) { + skb_put(msdu, IEEE80211_CCMP_MIC_LEN); + } else if (!(skb_cb->flags & ATH10K_SKB_F_NO_HWCRYPT) && + txmode == ATH10K_HW_TXRX_RAW && + ieee80211_has_protected(hdr->frame_control)) { + skb_put(msdu, IEEE80211_CCMP_MIC_LEN); + } } skb_cb->paddr = dma_map_single(dev, msdu->data, msdu->len, From a09740548275a74b897654b3aca5af589289b57a Mon Sep 17 00:00:00 2001 From: Sergey Ryazanov Date: Mon, 16 May 2022 13:26:00 +0300 Subject: [PATCH 05/22] ath10k: turn rawmode into frame_mode Turn boolean rawmode module param into integer frame_mode param that contains value from ath10k_hw_txrx_mode enum. As earlier the default param value is non-RAW (native Wi-Fi) encapsulation. The param name is selected to be consistent with the similar ath11k param. This is a preparation step for upcoming encapsulation offloading support. Signed-off-by: Sergey Ryazanov Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220516032519.29831-4-ryazanov.s.a@gmail.com --- drivers/net/wireless/ath/ath10k/core.c | 11 +++++++---- drivers/net/wireless/ath/ath10k/core.h | 1 + 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index 688177453b072..5654387acb4b3 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c @@ -33,9 +33,11 @@ EXPORT_SYMBOL(ath10k_debug_mask); static unsigned int ath10k_cryptmode_param; static bool uart_print; static bool skip_otp; -static bool rawmode; static bool fw_diag_log; +/* frame mode values are mapped as per enum ath10k_hw_txrx_mode */ +unsigned int ath10k_frame_mode = ATH10K_HW_TXRX_NATIVE_WIFI; + unsigned long ath10k_coredump_mask = BIT(ATH10K_FW_CRASH_DUMP_REGISTERS) | BIT(ATH10K_FW_CRASH_DUMP_CE_DATA); @@ -44,15 +46,16 @@ module_param_named(debug_mask, ath10k_debug_mask, uint, 0644); module_param_named(cryptmode, ath10k_cryptmode_param, uint, 0644); module_param(uart_print, bool, 0644); module_param(skip_otp, bool, 0644); -module_param(rawmode, bool, 0644); module_param(fw_diag_log, bool, 0644); +module_param_named(frame_mode, ath10k_frame_mode, uint, 0644); module_param_named(coredump_mask, ath10k_coredump_mask, ulong, 0444); MODULE_PARM_DESC(debug_mask, "Debugging mask"); MODULE_PARM_DESC(uart_print, "Uart target debugging"); MODULE_PARM_DESC(skip_otp, "Skip otp failure for calibration in testmode"); MODULE_PARM_DESC(cryptmode, "Crypto mode: 0-hardware, 1-software"); -MODULE_PARM_DESC(rawmode, "Use raw 802.11 frame datapath"); +MODULE_PARM_DESC(frame_mode, + "Datapath frame mode (0: raw, 1: native wifi (default))"); MODULE_PARM_DESC(coredump_mask, "Bitfield of what to include in firmware crash file"); MODULE_PARM_DESC(fw_diag_log, "Diag based fw log debugging"); @@ -2599,7 +2602,7 @@ static int ath10k_core_init_firmware_features(struct ath10k *ar) ar->htt.max_num_amsdu = ATH10K_HTT_MAX_NUM_AMSDU_DEFAULT; ar->htt.max_num_ampdu = ATH10K_HTT_MAX_NUM_AMPDU_DEFAULT; - if (rawmode) { + if (ath10k_frame_mode == ATH10K_HW_TXRX_RAW) { if (!test_bit(ATH10K_FW_FEATURE_RAW_MODE_SUPPORT, fw_file->fw_features)) { ath10k_err(ar, "rawmode = 1 requires support from firmware"); diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index 8bfabbcfdb143..d70d7d088a2bf 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h @@ -1314,6 +1314,7 @@ static inline bool ath10k_peer_stats_enabled(struct ath10k *ar) return false; } +extern unsigned int ath10k_frame_mode; extern unsigned long ath10k_coredump_mask; void ath10k_core_napi_sync_disable(struct ath10k *ar); From af6d8265c47e46881b80c6b073f53c8c4af52d28 Mon Sep 17 00:00:00 2001 From: Sergey Ryazanov Date: Mon, 16 May 2022 13:26:00 +0300 Subject: [PATCH 06/22] ath10k: add encapsulation offloading support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Frame encapsulation from Ethernet into the IEEE 802.11 frame format takes a considerable host CPU time on the xmit path. The firmware is able to do this operation for us, so enable encapsulation offloading for AP and Sta interface types to improve overall system performance. The driver is almost ready for encapsulation offloading support. There are only a few places where the driver assumes the frame format is IEEE 802.11 that need to be fixed. Encapsulation offloading is currently disabled by default and the driver utilizes mac80211 encapsulation support. To activate offloading, the frame_mode=2 parameter should be passed during module loading. On a QCA9563+QCA9888-based access point in bridged mode, encapsulation offloading increases TCP 16-streams DL throughput from 365 to 396 mbps (+8%) and UDP DL throughput from 436 to 483 mbps (+11%). Tested-on: QCA9888 hw2.0 PCI 10.4-3.9.0.2-00131 Tested-on: QCA6174 hw3.2 PCI WLAN.RM.4.4.1-00157-QCARMSWPZ-1 Signed-off-by: Sergey Ryazanov Tested-by: Oldřich Jedlička # TP-Link Archer C7 v4 & v5 (QCA9563 + QCA9880) Tested-by: Edward Matijevic # TP-Link Archer C2600 (IPQ8064 + QCA9980 10.4.1.00030-1) Tested-by: Edward Matijevic # QCA9377 PCI in Sta mode Tested-by: Zhijun You # NETGEAR R7800 (QCA9984 10.4-3.9.0.2-00159) Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220516032519.29831-5-ryazanov.s.a@gmail.com --- drivers/net/wireless/ath/ath10k/core.c | 2 +- drivers/net/wireless/ath/ath10k/mac.c | 67 +++++++++++++++++++++----- 2 files changed, 55 insertions(+), 14 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index 5654387acb4b3..276954b70d630 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c @@ -55,7 +55,7 @@ MODULE_PARM_DESC(uart_print, "Uart target debugging"); MODULE_PARM_DESC(skip_otp, "Skip otp failure for calibration in testmode"); MODULE_PARM_DESC(cryptmode, "Crypto mode: 0-hardware, 1-software"); MODULE_PARM_DESC(frame_mode, - "Datapath frame mode (0: raw, 1: native wifi (default))"); + "Datapath frame mode (0: raw, 1: native wifi (default), 2: ethernet)"); MODULE_PARM_DESC(coredump_mask, "Bitfield of what to include in firmware crash file"); MODULE_PARM_DESC(fw_diag_log, "Diag based fw log debugging"); diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 3570a5895ea8c..ebd5b9a8943e1 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -3713,6 +3713,9 @@ ath10k_mac_tx_h_get_txmode(struct ath10k *ar, const struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(skb); __le16 fc = hdr->frame_control; + if (IEEE80211_SKB_CB(skb)->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) + return ATH10K_HW_TXRX_ETHERNET; + if (!vif || vif->type == NL80211_IFTYPE_MONITOR) return ATH10K_HW_TXRX_RAW; @@ -3873,6 +3876,12 @@ static void ath10k_mac_tx_h_fill_cb(struct ath10k *ar, bool noack = false; cb->flags = 0; + + if (info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) { + cb->flags |= ATH10K_SKB_F_QOS; /* Assume data frames are QoS */ + goto finish_cb_fill; + } + if (!ath10k_tx_h_use_hwcrypto(vif, skb)) cb->flags |= ATH10K_SKB_F_NO_HWCRYPT; @@ -3911,6 +3920,7 @@ static void ath10k_mac_tx_h_fill_cb(struct ath10k *ar, cb->flags |= ATH10K_SKB_F_RAW_TX; } +finish_cb_fill: cb->vif = vif; cb->txq = txq; cb->airtime_est = airtime; @@ -4034,7 +4044,11 @@ static int ath10k_mac_tx(struct ath10k *ar, ath10k_tx_h_seq_no(vif, skb); break; case ATH10K_HW_TXRX_ETHERNET: - ath10k_tx_h_8023(skb); + /* Convert 802.11->802.3 header only if the frame was erlier + * encapsulated to 802.11 by mac80211. Otherwise pass it as is. + */ + if (!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP)) + ath10k_tx_h_8023(skb); break; case ATH10K_HW_TXRX_RAW: if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags) && @@ -4645,12 +4659,10 @@ static void ath10k_mac_op_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif = info->control.vif; struct ieee80211_sta *sta = control->sta; struct ieee80211_txq *txq = NULL; - struct ieee80211_hdr *hdr = (void *)skb->data; enum ath10k_hw_txrx_mode txmode; enum ath10k_mac_tx_path txpath; bool is_htt; bool is_mgmt; - bool is_presp; int ret; u16 airtime; @@ -4664,8 +4676,14 @@ static void ath10k_mac_op_tx(struct ieee80211_hw *hw, is_mgmt = (txpath == ATH10K_MAC_TX_HTT_MGMT); if (is_htt) { + bool is_presp = false; + spin_lock_bh(&ar->htt.tx_lock); - is_presp = ieee80211_is_probe_resp(hdr->frame_control); + if (!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP)) { + struct ieee80211_hdr *hdr = (void *)skb->data; + + is_presp = ieee80211_is_probe_resp(hdr->frame_control); + } ret = ath10k_htt_tx_inc_pending(htt); if (ret) { @@ -5465,6 +5483,30 @@ static int ath10k_mac_set_txbf_conf(struct ath10k_vif *arvif) ar->wmi.vdev_param->txbf, value); } +static void ath10k_update_vif_offload(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct ath10k_vif *arvif = (void *)vif->drv_priv; + struct ath10k *ar = hw->priv; + u32 vdev_param; + int ret; + + if (ath10k_frame_mode != ATH10K_HW_TXRX_ETHERNET || + ar->wmi.vdev_param->tx_encap_type == WMI_VDEV_PARAM_UNSUPPORTED || + (vif->type != NL80211_IFTYPE_STATION && + vif->type != NL80211_IFTYPE_AP)) + vif->offload_flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED; + + vdev_param = ar->wmi.vdev_param->tx_encap_type; + ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, + ATH10K_HW_TXRX_NATIVE_WIFI); + /* 10.X firmware does not support this VDEV parameter. Do not warn */ + if (ret && ret != -EOPNOTSUPP) { + ath10k_warn(ar, "failed to set vdev %i TX encapsulation: %d\n", + arvif->vdev_id, ret); + } +} + /* * TODO: * Figure out how to handle WMI_VDEV_SUBTYPE_P2P_DEVICE, @@ -5674,15 +5716,7 @@ static int ath10k_add_interface(struct ieee80211_hw *hw, arvif->def_wep_key_idx = -1; - vdev_param = ar->wmi.vdev_param->tx_encap_type; - ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, - ATH10K_HW_TXRX_NATIVE_WIFI); - /* 10.X firmware does not support this VDEV parameter. Do not warn */ - if (ret && ret != -EOPNOTSUPP) { - ath10k_warn(ar, "failed to set vdev %i TX encapsulation: %d\n", - arvif->vdev_id, ret); - goto err_vdev_delete; - } + ath10k_update_vif_offload(hw, vif); /* Configuring number of spatial stream for monitor interface is causing * target assert in qca9888 and qca6174. @@ -9375,6 +9409,7 @@ static const struct ieee80211_ops ath10k_ops = { .stop = ath10k_stop, .config = ath10k_config, .add_interface = ath10k_add_interface, + .update_vif_offload = ath10k_update_vif_offload, .remove_interface = ath10k_remove_interface, .configure_filter = ath10k_configure_filter, .bss_info_changed = ath10k_bss_info_changed, @@ -10044,6 +10079,12 @@ int ath10k_mac_register(struct ath10k *ar) if (test_bit(WMI_SERVICE_TDLS_UAPSD_BUFFER_STA, ar->wmi.svc_map)) ieee80211_hw_set(ar->hw, SUPPORTS_TDLS_BUFFER_STA); + if (ath10k_frame_mode == ATH10K_HW_TXRX_ETHERNET) { + if (ar->wmi.vdev_param->tx_encap_type != + WMI_VDEV_PARAM_UNSUPPORTED) + ieee80211_hw_set(ar->hw, SUPPORTS_TX_ENCAP_OFFLOAD); + } + ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH; ar->hw->wiphy->max_remain_on_channel_duration = 5000; From 75a7062e533e309a9ca0812c69f3ac3cefadb8b1 Mon Sep 17 00:00:00 2001 From: Maxime Bizon Date: Mon, 16 May 2022 17:23:43 +0200 Subject: [PATCH 07/22] ath10k: fix misreported tx bandwidth for 160Mhz Because of this missing switch case, 160Mhz transmit was reported as 20Mhz, leading to wrong airtime calculation and AQL limiting max throughput. Tested-on: QCA9984 hw2.0 PCI 10.4-3.10-00047 Signed-off-by: Maxime Bizon Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/cd2735a40da7f4fcc5323e3fca3775e7b5402ece.camel@freebox.fr --- drivers/net/wireless/ath/ath10k/htt_rx.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index 771252dd6d4ea..e8727c0b01717 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c @@ -3884,6 +3884,10 @@ ath10k_update_per_peer_tx_stats(struct ath10k *ar, arsta->tx_info.status.rates[0].flags |= IEEE80211_TX_RC_80_MHZ_WIDTH; break; + case RATE_INFO_BW_160: + arsta->tx_info.status.rates[0].flags |= + IEEE80211_TX_RC_160_MHZ_WIDTH; + break; } if (peer_stats->succ_pkts) { From 77bbbd5e0ed3b5998a353b0948584faa4f565f0e Mon Sep 17 00:00:00 2001 From: Baochen Qiang Date: Tue, 17 May 2022 08:48:44 +0800 Subject: [PATCH 08/22] ath11k: Fix warning on variable 'sar' dereference before check We are seeing below warning: warn: variable dereferenced before check 'sar' Fix it by moving ahead pointer check on 'sar'. Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3 Fixes: 652f69ed9c1b ("ath11k: Add support for SAR") Reported-by: kernel test robot Reported-by: Dan Carpenter Signed-off-by: Baochen Qiang Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220517004844.2412660-1-quic_bqiang@quicinc.com --- drivers/net/wireless/ath/ath11k/mac.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index ee1590b16eff7..7d574ad67e595 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -8297,11 +8297,15 @@ static int ath11k_mac_op_set_bios_sar_specs(struct ieee80211_hw *hw, const struct cfg80211_sar_specs *sar) { struct ath11k *ar = hw->priv; - const struct cfg80211_sar_sub_specs *sspec = sar->sub_specs; + const struct cfg80211_sar_sub_specs *sspec; int ret, index; u8 *sar_tbl; u32 i; + if (!sar || sar->type != NL80211_SAR_TYPE_POWER || + sar->num_sub_specs == 0) + return -EINVAL; + mutex_lock(&ar->conf_mutex); if (!test_bit(WMI_TLV_SERVICE_BIOS_SAR_SUPPORT, ar->ab->wmi_ab.svc_map) || @@ -8310,12 +8314,6 @@ static int ath11k_mac_op_set_bios_sar_specs(struct ieee80211_hw *hw, goto exit; } - if (!sar || sar->type != NL80211_SAR_TYPE_POWER || - sar->num_sub_specs == 0) { - ret = -EINVAL; - goto exit; - } - ret = ath11k_wmi_pdev_set_bios_geo_table_param(ar); if (ret) { ath11k_warn(ar->ab, "failed to set geo table: %d\n", ret); @@ -8328,6 +8326,7 @@ static int ath11k_mac_op_set_bios_sar_specs(struct ieee80211_hw *hw, goto exit; } + sspec = sar->sub_specs; for (i = 0; i < sar->num_sub_specs; i++) { if (sspec->freq_range_index >= (BIOS_SAR_TABLE_LEN >> 1)) { ath11k_warn(ar->ab, "Ignore bad frequency index %u, max allowed %u\n", From b380d2056ebb7f5af1195ad07a6ce96022d4c552 Mon Sep 17 00:00:00 2001 From: Guo Zhengkui Date: Tue, 17 May 2022 10:39:23 +0800 Subject: [PATCH 09/22] ath5k: replace ternary operator with min() Fix the following coccicheck warning: drivers/net/wireless/ath/ath5k/phy.c:3139:62-63: WARNING opportunity for min() Signed-off-by: Guo Zhengkui Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220517023923.76989-1-guozhengkui@vivo.com --- drivers/net/wireless/ath/ath5k/phy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index 00f9e347d414d..5797ef9c73d72 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c @@ -3136,7 +3136,7 @@ ath5k_combine_pwr_to_pdadc_curves(struct ath5k_hw *ah, pdadc_n = gain_boundaries[pdg] + pd_gain_overlap - pwr_min[pdg]; /* Limit it to be inside pwr range */ table_size = pwr_max[pdg] - pwr_min[pdg]; - max_idx = (pdadc_n < table_size) ? pdadc_n : table_size; + max_idx = min(pdadc_n, table_size); /* Fill pdadc_out table */ while (pdadc_0 < max_idx && pdadc_i < 128) From bebcfd2534a63ab7e7325f5337662bc84ca038b6 Mon Sep 17 00:00:00 2001 From: Manikanta Pubbisetty Date: Tue, 17 May 2022 11:22:41 +0530 Subject: [PATCH 10/22] ath11k: Init hw_params before setting up AHB resources As part of adding the support of WCN6750 to ath11k, bus_params were moved to hw_params and this regressed the initialization of WCN6750. By the time AHB resources are setup for WCN6750, hw_params will not be initialized and therefore initialization for WCN6750 will fail. This is applicable only for WCN6750, no other device is impacted. Fix this by moving the initialization of hw_params before setting up AHB resources. Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.1.0.1-00887-QCAMSLSWPLZ-1 Fixes: 00402f49d26f ("ath11k: Add support for WCN6750 device") Signed-off-by: Manikanta Pubbisetty Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220517055241.15885-1-quic_mpubbise@quicinc.com --- drivers/net/wireless/ath/ath11k/ahb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/ahb.c b/drivers/net/wireless/ath/ath11k/ahb.c index fa11807f48a94..d7d33d5cdfc50 100644 --- a/drivers/net/wireless/ath/ath11k/ahb.c +++ b/drivers/net/wireless/ath/ath11k/ahb.c @@ -976,11 +976,11 @@ static int ath11k_ahb_probe(struct platform_device *pdev) ab->hw_rev = hw_rev; platform_set_drvdata(pdev, ab); - ret = ath11k_ahb_setup_resources(ab); + ret = ath11k_core_pre_init(ab); if (ret) goto err_core_free; - ret = ath11k_core_pre_init(ab); + ret = ath11k_ahb_setup_resources(ab); if (ret) goto err_core_free; From 2be8afe05833c65017c8c56953f3640acfc42a40 Mon Sep 17 00:00:00 2001 From: Guo Zhengkui Date: Tue, 17 May 2022 10:41:06 +0800 Subject: [PATCH 11/22] ath9k: replace ternary operator with max() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix the following coccicheck warning: drivers/net/wireless/ath/ath9k/dfs.c:249:28-30: WARNING opportunity for max() Signed-off-by: Guo Zhengkui Acked-by: Toke Høiland-Jørgensen Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220517024106.77050-1-guozhengkui@vivo.com --- drivers/net/wireless/ath/ath9k/dfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/dfs.c b/drivers/net/wireless/ath/ath9k/dfs.c index acb9602aa464f..11349218bc21c 100644 --- a/drivers/net/wireless/ath/ath9k/dfs.c +++ b/drivers/net/wireless/ath/ath9k/dfs.c @@ -246,7 +246,7 @@ ath9k_postprocess_radar_event(struct ath_softc *sc, DFS_STAT_INC(sc, dc_phy_errors); /* when both are present use stronger one */ - rssi = (ard->rssi < ard->ext_rssi) ? ard->ext_rssi : ard->rssi; + rssi = max(ard->rssi, ard->ext_rssi); break; default: /* From d4ba1ff87b17e81686ada8f429300876f55f95ad Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Sun, 22 May 2022 15:33:16 +0300 Subject: [PATCH 12/22] ath11k: fix netdev open race Make sure to allocate resources needed before registering the device. This specifically avoids having a racing open() trigger a BUG_ON() in mod_timer() when ath11k_mac_op_start() is called before the mon_reap_timer as been set up. I did not see this issue with next-20220310, but I hit it on every probe with next-20220511. Perhaps some timing changed in between. Here's the backtrace: [ 51.346947] kernel BUG at kernel/time/timer.c:990! [ 51.346958] Internal error: Oops - BUG: 0 [#1] PREEMPT SMP ... [ 51.578225] Call trace: [ 51.583293] __mod_timer+0x298/0x390 [ 51.589518] mod_timer+0x14/0x20 [ 51.595368] ath11k_mac_op_start+0x41c/0x4a0 [ath11k] [ 51.603165] drv_start+0x38/0x60 [mac80211] [ 51.610110] ieee80211_do_open+0x29c/0x7d0 [mac80211] [ 51.617945] ieee80211_open+0x60/0xb0 [mac80211] [ 51.625311] __dev_open+0x100/0x1c0 [ 51.631420] __dev_change_flags+0x194/0x210 [ 51.638214] dev_change_flags+0x24/0x70 [ 51.644646] do_setlink+0x228/0xdb0 [ 51.650723] __rtnl_newlink+0x460/0x830 [ 51.657162] rtnl_newlink+0x4c/0x80 [ 51.663229] rtnetlink_rcv_msg+0x124/0x390 [ 51.669917] netlink_rcv_skb+0x58/0x130 [ 51.676314] rtnetlink_rcv+0x18/0x30 [ 51.682460] netlink_unicast+0x250/0x310 [ 51.688960] netlink_sendmsg+0x19c/0x3e0 [ 51.695458] ____sys_sendmsg+0x220/0x290 [ 51.701938] ___sys_sendmsg+0x7c/0xc0 [ 51.708148] __sys_sendmsg+0x68/0xd0 [ 51.714254] __arm64_sys_sendmsg+0x28/0x40 [ 51.720900] invoke_syscall+0x48/0x120 Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3 Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices") Fixes: 840c36fa727a ("ath11k: dp: stop rx pktlog before suspend") Signed-off-by: Johan Hovold Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220517103436.15867-1-johan+linaro@kernel.org --- drivers/net/wireless/ath/ath11k/core.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index 1e98ff9ff2888..c8e0bc9358386 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -1225,23 +1225,23 @@ static int ath11k_core_pdev_create(struct ath11k_base *ab) return ret; } - ret = ath11k_mac_register(ab); + ret = ath11k_dp_pdev_alloc(ab); if (ret) { - ath11k_err(ab, "failed register the radio with mac80211: %d\n", ret); + ath11k_err(ab, "failed to attach DP pdev: %d\n", ret); goto err_pdev_debug; } - ret = ath11k_dp_pdev_alloc(ab); + ret = ath11k_mac_register(ab); if (ret) { - ath11k_err(ab, "failed to attach DP pdev: %d\n", ret); - goto err_mac_unregister; + ath11k_err(ab, "failed register the radio with mac80211: %d\n", ret); + goto err_dp_pdev_free; } ret = ath11k_thermal_register(ab); if (ret) { ath11k_err(ab, "could not register thermal device: %d\n", ret); - goto err_dp_pdev_free; + goto err_mac_unregister; } ret = ath11k_spectral_init(ab); @@ -1254,10 +1254,10 @@ static int ath11k_core_pdev_create(struct ath11k_base *ab) err_thermal_unregister: ath11k_thermal_unregister(ab); -err_dp_pdev_free: - ath11k_dp_pdev_free(ab); err_mac_unregister: ath11k_mac_unregister(ab); +err_dp_pdev_free: + ath11k_dp_pdev_free(ab); err_pdev_debug: ath11k_debugfs_pdev_destroy(ab); From 9f855efd9a7b6b0539c694e9381fb67cf68b96c7 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 21 May 2022 13:10:24 +0200 Subject: [PATCH 13/22] ath6kl: fix typo in comment Spelling mistake (triple letters) in comment. Detected with the help of Coccinelle. Signed-off-by: Julia Lawall Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220521111145.81697-14-Julia.Lawall@inria.fr --- drivers/net/wireless/ath/ath6kl/wmi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h index 672014973cee5..0d99f754b7e7b 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.h +++ b/drivers/net/wireless/ath/ath6kl/wmi.h @@ -1278,7 +1278,7 @@ struct wmi_snr_threshold_params_cmd { /* "alpha" */ u8 weight; - /* lowest of uppper */ + /* lowest of upper */ u8 thresh_above1_val; u8 thresh_above2_val; From 3bd0c69653ac636eae8872aacdcd4156f772f928 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 23 May 2022 16:32:58 +0200 Subject: [PATCH 14/22] ath11k: fix IRQ affinity warning on shutdown Make sure to clear the IRQ affinity hint also on shutdown to avoid triggering a WARN_ON_ONCE() in __free_irq() when stopping MHI while using a single MSI vector. Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3 Fixes: e94b07493da3 ("ath11k: Set IRQ affinity to CPU0 in case of one MSI vector") Signed-off-by: Johan Hovold Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220523143258.24818-1-johan+linaro@kernel.org --- drivers/net/wireless/ath/ath11k/pci.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/ath/ath11k/pci.c b/drivers/net/wireless/ath/ath11k/pci.c index dedf1b88ddf6b..487a303b30779 100644 --- a/drivers/net/wireless/ath/ath11k/pci.c +++ b/drivers/net/wireless/ath/ath11k/pci.c @@ -920,7 +920,9 @@ static void ath11k_pci_remove(struct pci_dev *pdev) static void ath11k_pci_shutdown(struct pci_dev *pdev) { struct ath11k_base *ab = pci_get_drvdata(pdev); + struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); + ath11k_pci_set_irq_affinity_hint(ab_pci, NULL); ath11k_pci_power_down(ab); } From b205ce4c266cd66e6f954733ef6c94f06722e150 Mon Sep 17 00:00:00 2001 From: Thiraviyam Mariyappan Date: Thu, 19 May 2022 18:27:41 +0530 Subject: [PATCH 15/22] ath11k: support avg signal in station dump Currently mac80211 doesn't calculate average signal when RSS(Receive side scaling) is enabled from the driver, so average signal isn't printed in the station dump. To address this issue, calculate the average signal from RSSI within driver and display in the station dump. Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.5.0.1-01208-QCAHKSWPL_SILICONZ-1 Signed-off-by: Thiraviyam Mariyappan Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/1652965061-30457-1-git-send-email-quic_tmariyap@quicinc.com --- drivers/net/wireless/ath/ath11k/core.h | 4 ++++ drivers/net/wireless/ath/ath11k/dp_rx.c | 3 +++ drivers/net/wireless/ath/ath11k/mac.c | 5 +++++ 3 files changed, 12 insertions(+) diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h index 95bca0b078b16..ea31016437b06 100644 --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h @@ -14,6 +14,7 @@ #include #include #include +#include #include "qmi.h" #include "htc.h" #include "wmi.h" @@ -464,6 +465,8 @@ struct ath11k_per_ppdu_tx_stats { u32 retry_bytes; }; +DECLARE_EWMA(avg_rssi, 10, 8) + struct ath11k_sta { struct ath11k_vif *arvif; @@ -482,6 +485,7 @@ struct ath11k_sta { u64 rx_duration; u64 tx_duration; u8 rssi_comb; + struct ewma_avg_rssi avg_rssi; s8 rssi_beacon; s8 chain_signal[IEEE80211_MAX_CHAINS]; struct ath11k_htt_tx_stats *tx_stats; diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c index 049774cc158cc..e16beb96c37c3 100644 --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c @@ -2765,6 +2765,9 @@ static void ath11k_dp_rx_update_peer_stats(struct ath11k_sta *arsta, if (!rx_stats) return; + arsta->rssi_comb = ppdu_info->rssi_comb; + ewma_avg_rssi_add(&arsta->avg_rssi, ppdu_info->rssi_comb); + num_msdu = ppdu_info->tcp_msdu_count + ppdu_info->tcp_ack_msdu_count + ppdu_info->udp_msdu_count + ppdu_info->other_msdu_count; diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index 7d574ad67e595..f11956163822a 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -4479,6 +4479,7 @@ static int ath11k_mac_station_add(struct ath11k *ar, } } + ewma_avg_rssi_init(&arsta->avg_rssi); return 0; free_tx_stats: @@ -8161,6 +8162,10 @@ static void ath11k_mac_op_sta_statistics(struct ieee80211_hw *hw, sinfo->signal = db2dbm ? signal : signal + ATH11K_DEFAULT_NOISE_FLOOR; sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL); } + + sinfo->signal_avg = ewma_avg_rssi_read(&arsta->avg_rssi) + + ATH11K_DEFAULT_NOISE_FLOOR; + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG); } #if IS_ENABLED(CONFIG_IPV6) From 8723750e2753868591ba86a57b0041c5e38047ad Mon Sep 17 00:00:00 2001 From: Wen Gong Date: Wed, 25 May 2022 09:22:47 -0400 Subject: [PATCH 16/22] ath10k: fix regdomain info of iw reg set/get When wlan load, firmware report the reg code with 0x6C for QCA6174, it is world reg which checked by ath_is_world_regd(), then the reg will be save into reg_world_copy of ath_common in ath_regd_init(). Later the regulatory of ath_common is updated to another country code such as "US" in ath_reg_notifier_apply() by below call stack. After that, regulatory_hint() is called in ath10k_mac_register() and it lead "iw reg get" show two regdomain info as below. global country US: DFS-FCC (2400 - 2472 @ 40), (N/A, 30), (N/A) (5150 - 5250 @ 80), (N/A, 23), (N/A), AUTO-BW (5250 - 5350 @ 80), (N/A, 23), (0 ms), DFS, AUTO-BW (5470 - 5730 @ 160), (N/A, 23), (0 ms), DFS (5730 - 5850 @ 80), (N/A, 30), (N/A) (57240 - 71000 @ 2160), (N/A, 40), (N/A) phy#0 country US: DFS-FCC (2400 - 2472 @ 40), (N/A, 30), (N/A) (5150 - 5250 @ 80), (N/A, 23), (N/A), AUTO-BW (5250 - 5350 @ 80), (N/A, 23), (0 ms), DFS, AUTO-BW (5470 - 5730 @ 160), (N/A, 23), (0 ms), DFS (5730 - 5850 @ 80), (N/A, 30), (N/A) (57240 - 71000 @ 2160), (N/A, 40), (N/A) [ 4255.704975] Call Trace: [ 4255.704983] ath_reg_notifier_apply+0xa6/0xc5 [ath] [ 4255.704991] ath10k_reg_notifier+0x2f/0xd2 [ath10k_core] [ 4255.705010] wiphy_regulatory_register+0x5f/0x69 [cfg80211] [ 4255.705020] wiphy_register+0x459/0x8f0 [cfg80211] [ 4255.705042] ? ieee80211_register_hw+0x3a6/0x7d1 [mac80211] [ 4255.705049] ? __kmalloc+0xf4/0x218 [ 4255.705058] ? ieee80211_register_hw+0x3a6/0x7d1 [mac80211] [ 4255.705066] ? ath10k_mac_register+0x70/0xaab [ath10k_core] [ 4255.705075] ieee80211_register_hw+0x51a/0x7d1 [mac80211] [ 4255.705084] ath10k_mac_register+0x8b4/0xaab [ath10k_core] [ 4255.705094] ath10k_core_register_work+0xa5e/0xb45 [ath10k_core] [ 4255.705100] ? __schedule+0x61f/0x7d3 [ 4255.705105] process_one_work+0x1b7/0x392 [ 4255.705109] worker_thread+0x271/0x35d [ 4255.705112] ? pr_cont_work+0x58/0x58 [ 4255.705116] kthread+0x13f/0x147 [ 4255.705119] ? pr_cont_work+0x58/0x58 [ 4255.705123] ? kthread_destroy_worker+0x62/0x62 [ 4255.705126] ret_from_fork+0x22/0x40 At this moment, the two regdomain info is same, when run "iw reg set KR", the global regdomain info changed to KR, but the regdomain of phy#0 does not change again. It leads inconsistent values between global and phy#0 as below. global country KR: DFS-JP (2402 - 2482 @ 40), (N/A, 13), (N/A) (5170 - 5250 @ 80), (N/A, 20), (N/A), AUTO-BW (5250 - 5330 @ 80), (N/A, 20), (0 ms), DFS, AUTO-BW (5490 - 5710 @ 160), (N/A, 30), (0 ms), DFS (5735 - 5835 @ 80), (N/A, 30), (N/A) (57000 - 66000 @ 2160), (N/A, 43), (N/A) phy#0 country US: DFS-FCC (2400 - 2472 @ 40), (N/A, 30), (N/A) (5150 - 5250 @ 80), (N/A, 23), (N/A), AUTO-BW (5250 - 5350 @ 80), (N/A, 23), (0 ms), DFS, AUTO-BW (5470 - 5730 @ 160), (N/A, 23), (0 ms), DFS (5730 - 5850 @ 80), (N/A, 30), (N/A) (57240 - 71000 @ 2160), (N/A, 40), (N/A) The initial reg code is 0x6C which saved in reg_world_copy of ath_common, and the code US is updated from cfg80211 later, so ath10k should also check the initial reg code before regulatory_hint(). After this fix, regdomain info is same between "iw reg get" and "iw reg set xx", it does not have the regdomain info of phy#0 again. global country KR: DFS-JP (2402 - 2482 @ 40), (N/A, 13), (N/A) (5170 - 5250 @ 80), (N/A, 20), (N/A), AUTO-BW (5250 - 5330 @ 80), (N/A, 20), (0 ms), DFS, AUTO-BW (5490 - 5710 @ 160), (N/A, 30), (0 ms), DFS (5735 - 5835 @ 80), (N/A, 30), (N/A) (57000 - 66000 @ 2160), (N/A, 43), (N/A) This does not effect the channel list and power which ath10k used. When the country code for regulatory_hint() in ath10k_mac_register() is same with the global country code, then reg_set_rd_driver() of cfg80211 called from crda which return -EALREADY to set_regdom() and then update_all_wiphy_regulatory() will not be called while wlan load. When run "iw reg set xx", reg_get_regdomain() which used by function handle_channel() in net/wirelss/reg.c always use the regdomain returned by get_cfg80211_regdom() because the initiator of last regulatory_request is NL80211_REGDOM_SET_BY_USER, get_cfg80211_regdom() is the global regdomain, then all the ieee80211_channel info is updated in handle_channel() with the global regdomain. Tested-on: QCA6174 hw3.2 SDIO WLAN.RMH.4.4.1-00049 Tested-on: QCA9984 hw1.0 PCI 10.4-3.6-00104 Signed-off-by: Wen Gong Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220525132247.23459-1-quic_wgong@quicinc.com --- drivers/net/wireless/ath/ath10k/mac.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index ebd5b9a8943e1..a04e18250dae1 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -10270,7 +10270,8 @@ int ath10k_mac_register(struct ath10k *ar) ar->hw->wiphy->software_iftypes |= BIT(NL80211_IFTYPE_AP_VLAN); } - if (!ath_is_world_regd(&ar->ath_common.regulatory)) { + if (!ath_is_world_regd(&ar->ath_common.reg_world_copy) && + !ath_is_world_regd(&ar->ath_common.regulatory)) { ret = regulatory_hint(ar->hw->wiphy, ar->ath_common.regulatory.alpha2); if (ret) From e5646fe3b7ef739c392e59da7db6adf5e1fdef42 Mon Sep 17 00:00:00 2001 From: Christian 'Ansuel' Marangi Date: Sat, 28 May 2022 16:25:16 +0200 Subject: [PATCH 17/22] ath11k: fix missing skb drop on htc_tx_completion error On htc_tx_completion error the skb is not dropped. This is wrong since the completion_handler logic expect the skb to be consumed anyway even when an error is triggered. Not freeing the skb on error is a memory leak since the skb won't be freed anywere else. Correctly free the packet on eid >= ATH11K_HTC_EP_COUNT before returning. Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.5.0.1-01208-QCAHKSWPL_SILICONZ-1 Fixes: f951380a6022 ("ath11k: Disabling credit flow for WMI path") Signed-off-by: Christian 'Ansuel' Marangi Reviewed-by: Jeff Johnson Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220528142516.20819-2-ansuelsmth@gmail.com --- drivers/net/wireless/ath/ath11k/htc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath11k/htc.c b/drivers/net/wireless/ath/ath11k/htc.c index 069c29a4fac70..ca3aedc0252d5 100644 --- a/drivers/net/wireless/ath/ath11k/htc.c +++ b/drivers/net/wireless/ath/ath11k/htc.c @@ -258,8 +258,10 @@ void ath11k_htc_tx_completion_handler(struct ath11k_base *ab, u8 eid; eid = ATH11K_SKB_CB(skb)->eid; - if (eid >= ATH11K_HTC_EP_COUNT) + if (eid >= ATH11K_HTC_EP_COUNT) { + dev_kfree_skb_any(skb); return; + } ep = &htc->endpoint[eid]; spin_lock_bh(&htc->tx_lock); From 9331f7d3c54a263bede5055e106e40b28d0bd937 Mon Sep 17 00:00:00 2001 From: Manikanta Pubbisetty Date: Thu, 2 Jun 2022 17:26:21 +0530 Subject: [PATCH 18/22] ath11k: Fix incorrect debug_mask mappings Currently a couple of debug_mask entries are mapped to the same value, this could enable unintended driver logging. If enabling DP_TX logs was the intention, then this could also enable PCI logs flooding the dmesg buffer or vice versa. Fix this by correctly assigning the debug masks. Found during code review. Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.1.0.1-00887-QCAMSLSWPLZ-1 Fixes: aa2092a9bab3f ("ath11k: add raw mode and software crypto support") Signed-off-by: Manikanta Pubbisetty Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220602115621.15339-1-quic_mpubbise@quicinc.com --- drivers/net/wireless/ath/ath11k/debug.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/debug.h b/drivers/net/wireless/ath/ath11k/debug.h index fbbd5fe02aa83..91545640c47b2 100644 --- a/drivers/net/wireless/ath/ath11k/debug.h +++ b/drivers/net/wireless/ath/ath11k/debug.h @@ -23,8 +23,8 @@ enum ath11k_debug_mask { ATH11K_DBG_TESTMODE = 0x00000400, ATH11k_DBG_HAL = 0x00000800, ATH11K_DBG_PCI = 0x00001000, - ATH11K_DBG_DP_TX = 0x00001000, - ATH11K_DBG_DP_RX = 0x00002000, + ATH11K_DBG_DP_TX = 0x00002000, + ATH11K_DBG_DP_RX = 0x00004000, ATH11K_DBG_ANY = 0xffffffff, }; From 0ab52b2bd7be8fd49c8ade7703c1faa15359c6c5 Mon Sep 17 00:00:00 2001 From: Manikanta Pubbisetty Date: Thu, 2 Jun 2022 17:59:29 +0530 Subject: [PATCH 19/22] ath11k: Avoid REO CMD failed prints during firmware recovery Currently when firmware recovery is in progress, we do not queue REO commands to the firmware, instead -ESHUTDOWN will be returned to the caller leading to a failure print on the console. The REO command in the problem scenario is sent for all tids of a peer in which case we will have 16 failure prints on the console for a single peer. For an AP usecase, this count would be even higher in a worst case scenario. Since these commands are bound to fail during firmware recovery, it is better to avoid printing these failures and thereby avoid message flooding on the console. Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.1.0.1-00887-QCAMSLSWPLZ-1 Fixes: 8ee8d38ca472 ("ath11k: Fix crash during firmware recovery on reo cmd ring access") Signed-off-by: Manikanta Pubbisetty Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220602122929.18896-1-quic_mpubbise@quicinc.com --- drivers/net/wireless/ath/ath11k/dp_rx.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c index e16beb96c37c3..2148acf37071e 100644 --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c @@ -835,8 +835,9 @@ void ath11k_peer_rx_tid_delete(struct ath11k *ar, HAL_REO_CMD_UPDATE_RX_QUEUE, &cmd, ath11k_dp_rx_tid_del_func); if (ret) { - ath11k_err(ar->ab, "failed to send HAL_REO_CMD_UPDATE_RX_QUEUE cmd, tid %d (%d)\n", - tid, ret); + if (ret != -ESHUTDOWN) + ath11k_err(ar->ab, "failed to send HAL_REO_CMD_UPDATE_RX_QUEUE cmd, tid %d (%d)\n", + tid, ret); dma_unmap_single(ar->ab->dev, rx_tid->paddr, rx_tid->size, DMA_BIDIRECTIONAL); kfree(rx_tid->vaddr); From 4c1fc4f60a534728a34ed224281d17a33f2bf2bd Mon Sep 17 00:00:00 2001 From: Manikanta Pubbisetty Date: Thu, 2 Jun 2022 18:11:42 +0530 Subject: [PATCH 20/22] ath11k: Fix LDPC config in set_bitrate_mask hook Currently ar->ht_cap_info is not set anywhere in the code, this could result in LDPC config computed wrongly in the set_bitrate_mask() hook and eventually sending wrong config to the target. Fix this by checking the LDPC support from the band HT capabilities of the radio instead. Furthermore, it looks like firmwares running on the ath11k hardware do not set WMI_HT_CAP_LDPC for advertising the TX LDPC capability, WMI_HT_CAP_TX_LDPC is set instead and this should be checked for getting hardware's TX LDPC support. This is true for QCA6390, WCN6855 & WCN6750 hardware. Also, remove unused variables ht_cap_info & vht_cap_info from struct ath11k{}. Found this during code review. Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.1.0.1-00887-QCAMSLSWPLZ-1 Signed-off-by: Manikanta Pubbisetty Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220602124142.29909-1-quic_mpubbise@quicinc.com --- drivers/net/wireless/ath/ath11k/core.h | 2 -- drivers/net/wireless/ath/ath11k/mac.c | 4 +++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h index ea31016437b06..2bd5eb9df4d40 100644 --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h @@ -582,8 +582,6 @@ struct ath11k { struct ath11k_pdev_wmi *wmi; struct ath11k_pdev_dp dp; u8 mac_addr[ETH_ALEN]; - u32 ht_cap_info; - u32 vht_cap_info; struct ath11k_he ar_he; enum ath11k_state state; bool supports_6ghz; diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index f11956163822a..6b3d7a014847d 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -7800,6 +7800,7 @@ ath11k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw, { struct ath11k_vif *arvif = (void *)vif->drv_priv; struct cfg80211_chan_def def; + struct ath11k_pdev_cap *cap; struct ath11k *ar = arvif->ar; enum nl80211_band band; const u8 *ht_mcs_mask; @@ -7820,10 +7821,11 @@ ath11k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw, return -EPERM; band = def.chan->band; + cap = &ar->pdev->cap; ht_mcs_mask = mask->control[band].ht_mcs; vht_mcs_mask = mask->control[band].vht_mcs; he_mcs_mask = mask->control[band].he_mcs; - ldpc = !!(ar->ht_cap_info & WMI_HT_CAP_LDPC); + ldpc = !!(cap->band[band].ht_cap_info & WMI_HT_CAP_TX_LDPC); sgi = mask->control[band].gi; if (sgi == NL80211_TXRATE_FORCE_LGI) From 3926e0c12238a8053ed5a598b5b84c6cf2adacab Mon Sep 17 00:00:00 2001 From: Manikanta Pubbisetty Date: Thu, 2 Jun 2022 18:43:50 +0530 Subject: [PATCH 21/22] ath11k: Fix warnings reported by checkpatch Fix warnings reported by checkpatch tool. Below are the errors fixed, drivers/net/wireless/ath/ath11k/hal_rx.c:760: 'recevied' may be misspelled - perhaps 'received? drivers/net/wireless/ath/ath11k/qmi.c:2232: Prefer strscpy over strlcpy drivers/net/wireless/ath/ath11k/qmi.c:2238: Prefer strscpy over strlcpy drivers/net/wireless/ath/ath11k/qmi.c:2662: Prefer strscpy over strlcpy drivers/net/wireless/ath/ath11k/mac.c:7836: 'atleast' may be misspelled - perhaps 'at least'? drivers/net/wireless/ath/ath11k/wmi.c:6566: 'succeded' may be misspelled - perhaps 'succeeded'? Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.1.0.1-00887-QCAMSLSWPLZ-1 Signed-off-by: Manikanta Pubbisetty Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220602131350.29486-1-quic_mpubbise@quicinc.com --- drivers/net/wireless/ath/ath11k/hal_rx.c | 2 +- drivers/net/wireless/ath/ath11k/mac.c | 2 +- drivers/net/wireless/ath/ath11k/qmi.c | 6 +++--- drivers/net/wireless/ath/ath11k/wmi.c | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/hal_rx.c b/drivers/net/wireless/ath/ath11k/hal_rx.c index 4bb1fbaed0c9a..7f39c6fb7408c 100644 --- a/drivers/net/wireless/ath/ath11k/hal_rx.c +++ b/drivers/net/wireless/ath/ath11k/hal_rx.c @@ -757,7 +757,7 @@ void ath11k_hal_reo_qdesc_setup(void *vaddr, int tid, u32 ba_window_size, /* TODO: HW queue descriptors are currently allocated for max BA * window size for all QOS TIDs so that same descriptor can be used - * later when ADDBA request is recevied. This should be changed to + * later when ADDBA request is received. This should be changed to * allocate HW queue descriptors based on BA window size being * negotiated (0 for non BA cases), and reallocate when BA window * size changes and also send WMI message to FW to change the REO diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index 6b3d7a014847d..42d2e8cf81254 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -7835,7 +7835,7 @@ ath11k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw, he_ltf = mask->control[band].he_ltf; /* mac80211 doesn't support sending a fixed HT/VHT MCS alone, rather it - * requires passing atleast one of used basic rates along with them. + * requires passing at least one of used basic rates along with them. * Fixed rate setting across different preambles(legacy, HT, VHT) is * not supported by the FW. Hence use of FIXED_RATE vdev param is not * suitable for setting single HT/VHT rates. diff --git a/drivers/net/wireless/ath/ath11k/qmi.c b/drivers/net/wireless/ath/ath11k/qmi.c index 61ead37a944a8..00136601cb7db 100644 --- a/drivers/net/wireless/ath/ath11k/qmi.c +++ b/drivers/net/wireless/ath/ath11k/qmi.c @@ -2229,13 +2229,13 @@ static int ath11k_qmi_request_target_cap(struct ath11k_base *ab) if (resp.fw_version_info_valid) { ab->qmi.target.fw_version = resp.fw_version_info.fw_version; - strlcpy(ab->qmi.target.fw_build_timestamp, + strscpy(ab->qmi.target.fw_build_timestamp, resp.fw_version_info.fw_build_timestamp, sizeof(ab->qmi.target.fw_build_timestamp)); } if (resp.fw_build_id_valid) - strlcpy(ab->qmi.target.fw_build_id, resp.fw_build_id, + strscpy(ab->qmi.target.fw_build_id, resp.fw_build_id, sizeof(ab->qmi.target.fw_build_id)); if (resp.eeprom_read_timeout_valid) { @@ -2659,7 +2659,7 @@ static int ath11k_qmi_wlanfw_wlan_cfg_send(struct ath11k_base *ab) memset(&resp, 0, sizeof(resp)); req->host_version_valid = 1; - strlcpy(req->host_version, ATH11K_HOST_VERSION_STRING, + strscpy(req->host_version, ATH11K_HOST_VERSION_STRING, sizeof(req->host_version)); req->tgt_cfg_valid = 1; diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c index 84d1c70540132..f69918b9452a8 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c @@ -6563,7 +6563,7 @@ static int ath11k_reg_chan_list_event(struct ath11k_base *ab, struct sk_buff *sk fallback: /* Fallback to older reg (by sending previous country setting - * again if fw has succeded and we failed to process here. + * again if fw has succeeded and we failed to process here. * The Regdomain should be uniform across driver and fw. Since the * FW has processed the command and sent a success status, we expect * this function to succeed as well. If it doesn't, CTRY needs to be From cc2609eda6981d65b3b1c81e2807910d718b2b98 Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Mon, 6 Jun 2022 17:29:57 +0300 Subject: [PATCH 22/22] ath10k: fix recently introduced checkpatch warning I updated my checkpatch and saw new warnings: drivers/net/wireless/ath/ath10k/qmi.c:593: Prefer strscpy over strlcpy - see: https://lore.kernel.org/r/CAHk-=wgfRnXz0W3D37d01q3JFkr_i_uTL=V6A6G1oUZcprmknw@mail.gmail.com/ drivers/net/wireless/ath/ath10k/qmi.c:598: Prefer strscpy over strlcpy - see: https://lore.kernel.org/r/CAHk-=wgfRnXz0W3D37d01q3JFkr_i_uTL=V6A6G1oUZcprmknw@mail.gmail.com/ drivers/net/wireless/ath/ath10k/htt_rx.c:3565: Integer promotion: Using 'h' in '%04hx' is unnecessary Compile tested only. Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20220606142957.23721-1-kvalo@kernel.org --- drivers/net/wireless/ath/ath10k/htt_rx.c | 2 +- drivers/net/wireless/ath/ath10k/qmi.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index e8727c0b01717..b8461501221a7 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c @@ -3563,7 +3563,7 @@ static void ath10k_htt_rx_tx_mode_switch_ind(struct ath10k *ar, threshold = MS(info1, HTT_TX_MODE_SWITCH_IND_INFO1_THRESHOLD); ath10k_dbg(ar, ATH10K_DBG_HTT, - "htt rx tx mode switch ind info0 0x%04hx info1 0x%04x enable %d num records %zd mode %d threshold %u\n", + "htt rx tx mode switch ind info0 0x%04x info1 0x%04x enable %d num records %zd mode %d threshold %u\n", info0, info1, enable, num_records, mode, threshold); len += sizeof(resp->tx_mode_switch_ind.records[0]) * num_records; diff --git a/drivers/net/wireless/ath/ath10k/qmi.c b/drivers/net/wireless/ath/ath10k/qmi.c index 80fcb917fe4e1..d7e406916bc88 100644 --- a/drivers/net/wireless/ath/ath10k/qmi.c +++ b/drivers/net/wireless/ath/ath10k/qmi.c @@ -590,12 +590,12 @@ static int ath10k_qmi_cap_send_sync_msg(struct ath10k_qmi *qmi) if (resp->fw_version_info_valid) { qmi->fw_version = resp->fw_version_info.fw_version; - strlcpy(qmi->fw_build_timestamp, resp->fw_version_info.fw_build_timestamp, + strscpy(qmi->fw_build_timestamp, resp->fw_version_info.fw_build_timestamp, sizeof(qmi->fw_build_timestamp)); } if (resp->fw_build_id_valid) - strlcpy(qmi->fw_build_id, resp->fw_build_id, + strscpy(qmi->fw_build_id, resp->fw_build_id, MAX_BUILD_ID_LEN + 1); if (!test_bit(ATH10K_SNOC_FLAG_REGISTERED, &ar_snoc->flags)) {