diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath11k')
-rw-r--r-- | drivers/net/wireless/ath/ath11k/ahb.c | 56 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath11k/core.c | 103 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath11k/core.h | 10 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath11k/debug.h | 4 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath11k/debugfs_htt_stats.c | 88 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath11k/debugfs_htt_stats.h | 39 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath11k/dp_rx.c | 8 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath11k/hal.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath11k/hal_rx.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath11k/htc.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath11k/hw.h | 5 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath11k/mac.c | 128 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath11k/mac.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath11k/pci.c | 72 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath11k/pcic.c | 57 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath11k/pcic.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath11k/qmi.c | 6 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath11k/wmi.c | 47 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath11k/wmi.h | 25 |
19 files changed, 330 insertions, 330 deletions
diff --git a/drivers/net/wireless/ath/ath11k/ahb.c b/drivers/net/wireless/ath/ath11k/ahb.c index fa11807f48a9..c47414710138 100644 --- a/drivers/net/wireless/ath/ath11k/ahb.c +++ b/drivers/net/wireless/ath/ath11k/ahb.c @@ -140,8 +140,53 @@ ath11k_ahb_get_msi_irq_wcn6750(struct ath11k_base *ab, unsigned int vector) return ab->pci.msi.irqs[vector]; } +static inline u32 +ath11k_ahb_get_window_start_wcn6750(struct ath11k_base *ab, u32 offset) +{ + u32 window_start = 0; + + /* If offset lies within DP register range, use 1st window */ + if ((offset ^ HAL_SEQ_WCSS_UMAC_OFFSET) < ATH11K_PCI_WINDOW_RANGE_MASK) + window_start = ATH11K_PCI_WINDOW_START; + /* If offset lies within CE register range, use 2nd window */ + else if ((offset ^ HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab)) < + ATH11K_PCI_WINDOW_RANGE_MASK) + window_start = 2 * ATH11K_PCI_WINDOW_START; + + return window_start; +} + +static void +ath11k_ahb_window_write32_wcn6750(struct ath11k_base *ab, u32 offset, u32 value) +{ + u32 window_start; + + /* WCN6750 uses static window based register access*/ + window_start = ath11k_ahb_get_window_start_wcn6750(ab, offset); + + iowrite32(value, ab->mem + window_start + + (offset & ATH11K_PCI_WINDOW_RANGE_MASK)); +} + +static u32 ath11k_ahb_window_read32_wcn6750(struct ath11k_base *ab, u32 offset) +{ + u32 window_start; + u32 val; + + /* WCN6750 uses static window based register access */ + window_start = ath11k_ahb_get_window_start_wcn6750(ab, offset); + + val = ioread32(ab->mem + window_start + + (offset & ATH11K_PCI_WINDOW_RANGE_MASK)); + return val; +} + static const struct ath11k_pci_ops ath11k_ahb_pci_ops_wcn6750 = { + .wakeup = NULL, + .release = NULL, .get_msi_irq = ath11k_ahb_get_msi_irq_wcn6750, + .window_write32 = ath11k_ahb_window_write32_wcn6750, + .window_read32 = ath11k_ahb_window_read32_wcn6750, }; static inline u32 ath11k_ahb_read32(struct ath11k_base *ab, u32 offset) @@ -971,19 +1016,24 @@ static int ath11k_ahb_probe(struct platform_device *pdev) } ab->hif.ops = hif_ops; - ab->pci.ops = pci_ops; ab->pdev = pdev; ab->hw_rev = hw_rev; platform_set_drvdata(pdev, ab); - ret = ath11k_ahb_setup_resources(ab); - if (ret) + ret = ath11k_pcic_register_pci_ops(ab, pci_ops); + if (ret) { + ath11k_err(ab, "failed to register PCI ops: %d\n", ret); goto err_core_free; + } ret = ath11k_core_pre_init(ab); if (ret) goto err_core_free; + ret = ath11k_ahb_setup_resources(ab); + if (ret) + goto err_core_free; + ret = ath11k_ahb_fw_resources_init(ab); if (ret) goto err_core_free; diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index 1e98ff9ff288..c3e9e4f7bc24 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -54,9 +54,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .target_ce_count = 11, .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_ipq8074, .svc_to_ce_map_len = 21, - .rfkill_pin = 0, - .rfkill_cfg = 0, - .rfkill_on_level = 0, .single_pdev_only = false, .rxdma1_enable = true, .num_rxmda_per_pdev = 1, @@ -107,8 +104,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .fixed_mem_region = true, .static_window_map = false, .hybrid_bus_type = false, - .dp_window_idx = 0, - .ce_window_idx = 0, .fixed_fw_mem = false, .support_off_channel_tx = false, }, @@ -133,9 +128,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .target_ce_count = 11, .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_ipq6018, .svc_to_ce_map_len = 19, - .rfkill_pin = 0, - .rfkill_cfg = 0, - .rfkill_on_level = 0, .single_pdev_only = false, .rxdma1_enable = true, .num_rxmda_per_pdev = 1, @@ -183,8 +175,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .fixed_mem_region = true, .static_window_map = false, .hybrid_bus_type = false, - .dp_window_idx = 0, - .ce_window_idx = 0, .fixed_fw_mem = false, .support_off_channel_tx = false, }, @@ -209,9 +199,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .target_ce_count = 9, .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390, .svc_to_ce_map_len = 14, - .rfkill_pin = 48, - .rfkill_cfg = 0, - .rfkill_on_level = 1, .single_pdev_only = true, .rxdma1_enable = false, .num_rxmda_per_pdev = 2, @@ -258,8 +245,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .fixed_mem_region = false, .static_window_map = false, .hybrid_bus_type = false, - .dp_window_idx = 0, - .ce_window_idx = 0, .fixed_fw_mem = false, .support_off_channel_tx = true, }, @@ -284,9 +269,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .target_ce_count = 9, .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qcn9074, .svc_to_ce_map_len = 18, - .rfkill_pin = 0, - .rfkill_cfg = 0, - .rfkill_on_level = 0, .rxdma1_enable = true, .num_rxmda_per_pdev = 1, .rx_mac_buf_ring = false, @@ -333,8 +315,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .fixed_mem_region = false, .static_window_map = true, .hybrid_bus_type = false, - .dp_window_idx = 3, - .ce_window_idx = 2, .fixed_fw_mem = false, .support_off_channel_tx = false, }, @@ -359,9 +339,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .target_ce_count = 9, .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390, .svc_to_ce_map_len = 14, - .rfkill_pin = 0, - .rfkill_cfg = 0, - .rfkill_on_level = 0, .single_pdev_only = true, .rxdma1_enable = false, .num_rxmda_per_pdev = 2, @@ -408,8 +385,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .fixed_mem_region = false, .static_window_map = false, .hybrid_bus_type = false, - .dp_window_idx = 0, - .ce_window_idx = 0, .fixed_fw_mem = false, .support_off_channel_tx = true, }, @@ -434,9 +409,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .target_ce_count = 9, .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390, .svc_to_ce_map_len = 14, - .rfkill_pin = 0, - .rfkill_cfg = 0, - .rfkill_on_level = 0, .single_pdev_only = true, .rxdma1_enable = false, .num_rxmda_per_pdev = 2, @@ -482,8 +454,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .fixed_mem_region = false, .static_window_map = false, .hybrid_bus_type = false, - .dp_window_idx = 0, - .ce_window_idx = 0, .fixed_fw_mem = false, .support_off_channel_tx = true, }, @@ -508,9 +478,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .target_ce_count = 9, .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390, .svc_to_ce_map_len = 14, - .rfkill_pin = 0, - .rfkill_cfg = 0, - .rfkill_on_level = 0, .single_pdev_only = true, .rxdma1_enable = false, .num_rxmda_per_pdev = 1, @@ -556,8 +523,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .fixed_mem_region = false, .static_window_map = true, .hybrid_bus_type = true, - .dp_window_idx = 1, - .ce_window_idx = 2, .fixed_fw_mem = true, .support_off_channel_tx = false, }, @@ -1225,23 +1190,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 +1219,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); @@ -1402,27 +1367,6 @@ static int ath11k_core_start_firmware(struct ath11k_base *ab, return ret; } -static int ath11k_core_rfkill_config(struct ath11k_base *ab) -{ - struct ath11k *ar; - int ret = 0, i; - - if (!(ab->target_caps.sys_cap_info & WMI_SYS_CAP_INFO_RFKILL)) - return 0; - - for (i = 0; i < ab->num_radios; i++) { - ar = ab->pdevs[i].ar; - - ret = ath11k_mac_rfkill_config(ar); - if (ret && ret != -EOPNOTSUPP) { - ath11k_warn(ab, "failed to configure rfkill: %d", ret); - return ret; - } - } - - return ret; -} - int ath11k_core_qmi_firmware_ready(struct ath11k_base *ab) { int ret; @@ -1475,13 +1419,6 @@ int ath11k_core_qmi_firmware_ready(struct ath11k_base *ab) goto err_core_stop; } ath11k_hif_irq_enable(ab); - - ret = ath11k_core_rfkill_config(ab); - if (ret && ret != -EOPNOTSUPP) { - ath11k_err(ab, "failed to config rfkill: %d\n", ret); - goto err_core_stop; - } - mutex_unlock(&ab->core_lock); return 0; @@ -1550,7 +1487,6 @@ void ath11k_core_halt(struct ath11k *ar) cancel_delayed_work_sync(&ar->scan.timeout); cancel_work_sync(&ar->regd_update_work); cancel_work_sync(&ab->update_11d_work); - cancel_work_sync(&ab->rfkill_work); rcu_assign_pointer(ab->pdevs_active[ar->pdev_idx], NULL); synchronize_rcu(); @@ -1558,28 +1494,6 @@ void ath11k_core_halt(struct ath11k *ar) idr_init(&ar->txmgmt_idr); } -static void ath11k_rfkill_work(struct work_struct *work) -{ - struct ath11k_base *ab = container_of(work, struct ath11k_base, rfkill_work); - struct ath11k *ar; - bool rfkill_radio_on; - int i; - - spin_lock_bh(&ab->base_lock); - rfkill_radio_on = ab->rfkill_radio_on; - spin_unlock_bh(&ab->base_lock); - - for (i = 0; i < ab->num_radios; i++) { - ar = ab->pdevs[i].ar; - if (!ar) - continue; - - /* notify cfg80211 radio state change */ - ath11k_mac_rfkill_enable_radio(ar, rfkill_radio_on); - wiphy_rfkill_set_hw_state(ar->hw->wiphy, !rfkill_radio_on); - } -} - static void ath11k_update_11d(struct work_struct *work) { struct ath11k_base *ab = container_of(work, struct ath11k_base, update_11d_work); @@ -1891,7 +1805,6 @@ struct ath11k_base *ath11k_core_alloc(struct device *dev, size_t priv_size, init_waitqueue_head(&ab->qmi.cold_boot_waitq); INIT_WORK(&ab->restart_work, ath11k_core_restart); INIT_WORK(&ab->update_11d_work, ath11k_update_11d); - INIT_WORK(&ab->rfkill_work, ath11k_rfkill_work); INIT_WORK(&ab->reset_work, ath11k_core_reset); timer_setup(&ab->rx_replenish_retry, ath11k_ce_rx_replenish_retry, 0); init_completion(&ab->htc_suspend); diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h index 95bca0b078b1..afad8f55e433 100644 --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h @@ -14,6 +14,7 @@ #include <linux/dmi.h> #include <linux/ctype.h> #include <linux/rhashtable.h> +#include <linux/average.h> #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; @@ -578,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; @@ -927,10 +929,6 @@ struct ath11k_base { struct ath11k_dbring_cap *db_caps; u32 num_db_cap; - struct work_struct rfkill_work; - - /* true means radio is on */ - bool rfkill_radio_on; /* To synchronize 11d scan vdev id */ struct mutex vdev_id_11d_lock; diff --git a/drivers/net/wireless/ath/ath11k/debug.h b/drivers/net/wireless/ath/ath11k/debug.h index fbbd5fe02aa8..91545640c47b 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, }; diff --git a/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.c b/drivers/net/wireless/ath/ath11k/debugfs_htt_stats.c index 4484235bcda4..b3efca6bd7dd 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 <linux/vmalloc.h> @@ -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 dc210c54d131..5d722b51b125 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 == */ diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c index 049774cc158c..2148acf37071 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); @@ -2765,6 +2766,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/hal.c b/drivers/net/wireless/ath/ath11k/hal.c index 1dba7b9e0bda..bda71ab5a1f2 100644 --- a/drivers/net/wireless/ath/ath11k/hal.c +++ b/drivers/net/wireless/ath/ath11k/hal.c @@ -1165,7 +1165,7 @@ void ath11k_hal_srng_shadow_update_hp_tp(struct ath11k_base *ab, lockdep_assert_held(&srng->lock); /* check whether the ring is emptry. Update the shadow - * HP only when then ring isn't' empty. + * HP only when then ring isn't empty. */ if (srng->ring_dir == HAL_SRNG_DIR_SRC && *srng->u.src_ring.tp_addr != srng->u.src_ring.hp) diff --git a/drivers/net/wireless/ath/ath11k/hal_rx.c b/drivers/net/wireless/ath/ath11k/hal_rx.c index 4bb1fbaed0c9..7f39c6fb7408 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/htc.c b/drivers/net/wireless/ath/ath11k/htc.c index 069c29a4fac7..ca3aedc0252d 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); diff --git a/drivers/net/wireless/ath/ath11k/hw.h b/drivers/net/wireless/ath/ath11k/hw.h index 77dc5c851c9b..bb5ac940e470 100644 --- a/drivers/net/wireless/ath/ath11k/hw.h +++ b/drivers/net/wireless/ath/ath11k/hw.h @@ -153,9 +153,6 @@ struct ath11k_hw_params { u32 svc_to_ce_map_len; bool single_pdev_only; - u32 rfkill_pin; - u32 rfkill_cfg; - u32 rfkill_on_level; bool rxdma1_enable; int num_rxmda_per_pdev; @@ -201,8 +198,6 @@ struct ath11k_hw_params { bool fixed_mem_region; bool static_window_map; bool hybrid_bus_type; - u8 dp_window_idx; - u8 ce_window_idx; bool fixed_fw_mem; bool support_off_channel_tx; }; diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index ee1590b16eff..7e91e347c9ff 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -505,7 +505,7 @@ static int ath11k_mac_vif_chan(struct ieee80211_vif *vif, struct ieee80211_chanctx_conf *conf; rcu_read_lock(); - conf = rcu_dereference(vif->chanctx_conf); + conf = rcu_dereference(vif->bss_conf.chanctx_conf); if (!conf) { rcu_read_unlock(); return -ENOENT; @@ -1362,7 +1362,7 @@ static int ath11k_mac_setup_bcn_tmpl(struct ath11k_vif *arvif) if (arvif->vdev_type != WMI_VDEV_TYPE_AP) return 0; - bcn = ieee80211_beacon_get_template(hw, vif, &offs); + bcn = ieee80211_beacon_get_template(hw, vif, &offs, 0); if (!bcn) { ath11k_warn(ab, "failed to get beacon template from mac80211\n"); return -EPERM; @@ -1398,10 +1398,11 @@ 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) + if (!vif->bss_conf.color_change_active && !arvif->bcca_zero_sent) return; - if (vif->color_change_active && ieee80211_beacon_cntdwn_is_complete(vif)) { + if (vif->bss_conf.color_change_active && + ieee80211_beacon_cntdwn_is_complete(vif)) { arvif->bcca_zero_sent = true; ieee80211_color_change_finish(vif); return; @@ -1409,7 +1410,7 @@ void ath11k_mac_bcn_tx_event(struct ath11k_vif *arvif) arvif->bcca_zero_sent = false; - if (vif->color_change_active) + if (vif->bss_conf.color_change_active) ieee80211_beacon_update_cntdwn(vif); ath11k_mac_setup_bcn_tmpl(arvif); } @@ -1539,7 +1540,7 @@ static void ath11k_peer_assoc_h_basic(struct ath11k *ar, lockdep_assert_held(&ar->conf_mutex); if (vif->type == NL80211_IFTYPE_STATION) - aid = vif->bss_conf.aid; + aid = vif->cfg.aid; else aid = sta->aid; @@ -2749,7 +2750,7 @@ static void ath11k_bss_assoc(struct ieee80211_hw *hw, WARN_ON(arvif->is_up); - arvif->aid = bss_conf->aid; + arvif->aid = vif->cfg.aid; ether_addr_copy(arvif->bssid, bss_conf->bssid); ret = ath11k_wmi_vdev_up(ar, arvif->vdev_id, arvif->aid, arvif->bssid); @@ -2764,7 +2765,7 @@ static void ath11k_bss_assoc(struct ieee80211_hw *hw, ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac vdev %d up (associated) bssid %pM aid %d\n", - arvif->vdev_id, bss_conf->bssid, bss_conf->aid); + arvif->vdev_id, bss_conf->bssid, vif->cfg.aid); spin_lock_bh(&ar->ab->base_lock); @@ -3091,7 +3092,7 @@ static int ath11k_mac_config_obss_pd(struct ath11k *ar, static void ath11k_mac_op_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *info, - u32 changed) + u64 changed) { struct ath11k *ar = hw->priv; struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif); @@ -3185,9 +3186,10 @@ static void ath11k_mac_op_bss_info_changed(struct ieee80211_hw *hw, if (changed & BSS_CHANGED_SSID && vif->type == NL80211_IFTYPE_AP) { - arvif->u.ap.ssid_len = info->ssid_len; - if (info->ssid_len) - memcpy(arvif->u.ap.ssid, info->ssid, info->ssid_len); + arvif->u.ap.ssid_len = vif->cfg.ssid_len; + if (vif->cfg.ssid_len) + memcpy(arvif->u.ap.ssid, vif->cfg.ssid, + vif->cfg.ssid_len); arvif->u.ap.hidden_ssid = info->hidden_ssid; } @@ -3275,7 +3277,7 @@ static void ath11k_mac_op_bss_info_changed(struct ieee80211_hw *hw, } if (changed & BSS_CHANGED_ASSOC) { - if (info->assoc) + if (vif->cfg.assoc) ath11k_bss_assoc(hw, vif, info); else ath11k_bss_disassoc(hw, vif); @@ -3291,7 +3293,7 @@ static void ath11k_mac_op_bss_info_changed(struct ieee80211_hw *hw, if (changed & BSS_CHANGED_PS && ar->ab->hw_params.supports_sta_ps) { - arvif->ps = vif->bss_conf.ps; + arvif->ps = vif->cfg.ps; ret = ath11k_mac_config_ps(ar); if (ret) @@ -3406,14 +3408,15 @@ static void ath11k_mac_op_bss_info_changed(struct ieee80211_hw *hw, ath11k_mac_fils_discovery(arvif, info); if (changed & BSS_CHANGED_ARP_FILTER) { - ipv4_cnt = min(info->arp_addr_cnt, ATH11K_IPV4_MAX_COUNT); - memcpy(arvif->arp_ns_offload.ipv4_addr, info->arp_addr_list, + ipv4_cnt = min(vif->cfg.arp_addr_cnt, ATH11K_IPV4_MAX_COUNT); + memcpy(arvif->arp_ns_offload.ipv4_addr, + vif->cfg.arp_addr_list, ipv4_cnt * sizeof(u32)); memcpy(arvif->arp_ns_offload.mac_addr, vif->addr, ETH_ALEN); arvif->arp_ns_offload.ipv4_count = ipv4_cnt; ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac arp_addr_cnt %d vif->addr %pM, offload_addr %pI4\n", - info->arp_addr_cnt, + vif->cfg.arp_addr_cnt, vif->addr, arvif->arp_ns_offload.ipv4_addr); } @@ -4479,6 +4482,7 @@ static int ath11k_mac_station_add(struct ath11k *ar, } } + ewma_avg_rssi_init(&arsta->avg_rssi); return 0; free_tx_stats: @@ -4819,7 +4823,8 @@ exit: } static int ath11k_mac_op_conf_tx(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, u16 ac, + struct ieee80211_vif *vif, + unsigned int link_id, u16 ac, const struct ieee80211_tx_queue_params *params) { struct ath11k *ar = hw->priv; @@ -5606,63 +5611,6 @@ static int ath11k_mac_mgmt_tx(struct ath11k *ar, struct sk_buff *skb, return 0; } -int ath11k_mac_rfkill_config(struct ath11k *ar) -{ - struct ath11k_base *ab = ar->ab; - u32 param; - int ret; - - if (ab->hw_params.rfkill_pin == 0) - return -EOPNOTSUPP; - - ath11k_dbg(ab, ATH11K_DBG_MAC, - "mac rfkill_pin %d rfkill_cfg %d rfkill_on_level %d", - ab->hw_params.rfkill_pin, ab->hw_params.rfkill_cfg, - ab->hw_params.rfkill_on_level); - - param = FIELD_PREP(WMI_RFKILL_CFG_RADIO_LEVEL, - ab->hw_params.rfkill_on_level) | - FIELD_PREP(WMI_RFKILL_CFG_GPIO_PIN_NUM, - ab->hw_params.rfkill_pin) | - FIELD_PREP(WMI_RFKILL_CFG_PIN_AS_GPIO, - ab->hw_params.rfkill_cfg); - - ret = ath11k_wmi_pdev_set_param(ar, WMI_PDEV_PARAM_HW_RFKILL_CONFIG, - param, ar->pdev->pdev_id); - if (ret) { - ath11k_warn(ab, - "failed to set rfkill config 0x%x: %d\n", - param, ret); - return ret; - } - - return 0; -} - -int ath11k_mac_rfkill_enable_radio(struct ath11k *ar, bool enable) -{ - enum wmi_rfkill_enable_radio param; - int ret; - - if (enable) - param = WMI_RFKILL_ENABLE_RADIO_ON; - else - param = WMI_RFKILL_ENABLE_RADIO_OFF; - - ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac %d rfkill enable %d", - ar->pdev_idx, param); - - ret = ath11k_wmi_pdev_set_param(ar, WMI_PDEV_PARAM_RFKILL_ENABLE, - param, ar->pdev->pdev_id); - if (ret) { - ath11k_warn(ar->ab, "failed to set rfkill enable param %d: %d\n", - param, ret); - return ret; - } - - return 0; -} - static void ath11k_mac_op_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, struct sk_buff *skb) @@ -5917,7 +5865,6 @@ static void ath11k_mac_op_stop(struct ieee80211_hw *hw) cancel_delayed_work_sync(&ar->scan.timeout); cancel_work_sync(&ar->regd_update_work); cancel_work_sync(&ar->ab->update_11d_work); - cancel_work_sync(&ar->ab->rfkill_work); if (ar->state_11d == ATH11K_11D_PREPARING) { ar->state_11d = ATH11K_11D_IDLE; @@ -6848,7 +6795,7 @@ ath11k_mac_change_chanctx_cnt_iter(void *data, u8 *mac, { struct ath11k_mac_change_chanctx_arg *arg = data; - if (rcu_access_pointer(vif->chanctx_conf) != arg->ctx) + if (rcu_access_pointer(vif->bss_conf.chanctx_conf) != arg->ctx) return; arg->n_vifs++; @@ -6861,7 +6808,7 @@ ath11k_mac_change_chanctx_fill_iter(void *data, u8 *mac, struct ath11k_mac_change_chanctx_arg *arg = data; struct ieee80211_chanctx_conf *ctx; - ctx = rcu_access_pointer(vif->chanctx_conf); + ctx = rcu_access_pointer(vif->bss_conf.chanctx_conf); if (ctx != arg->ctx) return; @@ -7069,6 +7016,7 @@ static int ath11k_start_vdev_delay(struct ieee80211_hw *hw, static int ath11k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf, struct ieee80211_chanctx_conf *ctx) { struct ath11k *ar = hw->priv; @@ -7158,6 +7106,7 @@ out: static void ath11k_mac_op_unassign_vif_chanctx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf, struct ieee80211_chanctx_conf *ctx) { struct ath11k *ar = hw->priv; @@ -7799,6 +7748,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; @@ -7819,10 +7769,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) @@ -7832,7 +7783,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. @@ -8161,6 +8112,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) @@ -8297,11 +8252,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 +8269,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 +8281,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", diff --git a/drivers/net/wireless/ath/ath11k/mac.h b/drivers/net/wireless/ath/ath11k/mac.h index 57ebfc592b00..2a0d3afb0c99 100644 --- a/drivers/net/wireless/ath/ath11k/mac.h +++ b/drivers/net/wireless/ath/ath11k/mac.h @@ -148,8 +148,6 @@ u8 ath11k_mac_hw_rate_to_idx(const struct ieee80211_supported_band *sband, void __ath11k_mac_scan_finish(struct ath11k *ar); void ath11k_mac_scan_finish(struct ath11k *ar); -int ath11k_mac_rfkill_enable_radio(struct ath11k *ar, bool enable); -int ath11k_mac_rfkill_config(struct ath11k *ar); struct ath11k_vif *ath11k_mac_get_arvif(struct ath11k *ar, u32 vdev_id); struct ath11k_vif *ath11k_mac_get_arvif_by_vdev_id(struct ath11k_base *ab, diff --git a/drivers/net/wireless/ath/ath11k/pci.c b/drivers/net/wireless/ath/ath11k/pci.c index dedf1b88ddf6..5bd34a6273d9 100644 --- a/drivers/net/wireless/ath/ath11k/pci.c +++ b/drivers/net/wireless/ath/ath11k/pci.c @@ -50,6 +50,22 @@ static void ath11k_pci_bus_release(struct ath11k_base *ab) mhi_device_put(ab_pci->mhi_ctrl->mhi_dev); } +static u32 ath11k_pci_get_window_start(struct ath11k_base *ab, u32 offset) +{ + if (!ab->hw_params.static_window_map) + return ATH11K_PCI_WINDOW_START; + + if ((offset ^ HAL_SEQ_WCSS_UMAC_OFFSET) < ATH11K_PCI_WINDOW_RANGE_MASK) + /* if offset lies within DP register range, use 3rd window */ + return 3 * ATH11K_PCI_WINDOW_START; + else if ((offset ^ HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab)) < + ATH11K_PCI_WINDOW_RANGE_MASK) + /* if offset lies within CE register range, use 2nd window */ + return 2 * ATH11K_PCI_WINDOW_START; + else + return ATH11K_PCI_WINDOW_START; +} + static inline void ath11k_pci_select_window(struct ath11k_pci *ab_pci, u32 offset) { struct ath11k_base *ab = ab_pci->ab; @@ -70,26 +86,39 @@ static void ath11k_pci_window_write32(struct ath11k_base *ab, u32 offset, u32 value) { struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); - u32 window_start = ATH11K_PCI_WINDOW_START; + u32 window_start; + + window_start = ath11k_pci_get_window_start(ab, offset); - spin_lock_bh(&ab_pci->window_lock); - ath11k_pci_select_window(ab_pci, offset); - iowrite32(value, ab->mem + window_start + - (offset & ATH11K_PCI_WINDOW_RANGE_MASK)); - spin_unlock_bh(&ab_pci->window_lock); + if (window_start == ATH11K_PCI_WINDOW_START) { + spin_lock_bh(&ab_pci->window_lock); + ath11k_pci_select_window(ab_pci, offset); + iowrite32(value, ab->mem + window_start + + (offset & ATH11K_PCI_WINDOW_RANGE_MASK)); + spin_unlock_bh(&ab_pci->window_lock); + } else { + iowrite32(value, ab->mem + window_start + + (offset & ATH11K_PCI_WINDOW_RANGE_MASK)); + } } static u32 ath11k_pci_window_read32(struct ath11k_base *ab, u32 offset) { struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); - u32 window_start = ATH11K_PCI_WINDOW_START; - u32 val; + u32 window_start, val; - spin_lock_bh(&ab_pci->window_lock); - ath11k_pci_select_window(ab_pci, offset); - val = ioread32(ab->mem + window_start + - (offset & ATH11K_PCI_WINDOW_RANGE_MASK)); - spin_unlock_bh(&ab_pci->window_lock); + window_start = ath11k_pci_get_window_start(ab, offset); + + if (window_start == ATH11K_PCI_WINDOW_START) { + spin_lock_bh(&ab_pci->window_lock); + ath11k_pci_select_window(ab_pci, offset); + val = ioread32(ab->mem + window_start + + (offset & ATH11K_PCI_WINDOW_RANGE_MASK)); + spin_unlock_bh(&ab_pci->window_lock); + } else { + val = ioread32(ab->mem + window_start + + (offset & ATH11K_PCI_WINDOW_RANGE_MASK)); + } return val; } @@ -110,6 +139,8 @@ static const struct ath11k_pci_ops ath11k_pci_ops_qca6390 = { }; static const struct ath11k_pci_ops ath11k_pci_ops_qcn9074 = { + .wakeup = NULL, + .release = NULL, .get_msi_irq = ath11k_pci_get_msi_irq, .window_write32 = ath11k_pci_window_write32, .window_read32 = ath11k_pci_window_read32, @@ -697,6 +728,7 @@ static int ath11k_pci_probe(struct pci_dev *pdev, struct ath11k_base *ab; struct ath11k_pci *ab_pci; u32 soc_hw_version_major, soc_hw_version_minor, addr; + const struct ath11k_pci_ops *pci_ops; int ret; ab = ath11k_core_alloc(&pdev->dev, sizeof(*ab_pci), ATH11K_BUS_PCI); @@ -754,10 +786,10 @@ static int ath11k_pci_probe(struct pci_dev *pdev, goto err_pci_free_region; } - ab->pci.ops = &ath11k_pci_ops_qca6390; + pci_ops = &ath11k_pci_ops_qca6390; break; case QCN9074_DEVICE_ID: - ab->pci.ops = &ath11k_pci_ops_qcn9074; + pci_ops = &ath11k_pci_ops_qcn9074; ab->hw_rev = ATH11K_HW_QCN9074_HW10; break; case WCN6855_DEVICE_ID: @@ -787,7 +819,7 @@ unsupported_wcn6855_soc: goto err_pci_free_region; } - ab->pci.ops = &ath11k_pci_ops_qca6390; + pci_ops = &ath11k_pci_ops_qca6390; break; default: dev_err(&pdev->dev, "Unknown PCI device found: 0x%x\n", @@ -796,6 +828,12 @@ unsupported_wcn6855_soc: goto err_pci_free_region; } + ret = ath11k_pcic_register_pci_ops(ab, pci_ops); + if (ret) { + ath11k_err(ab, "failed to register PCI ops: %d\n", ret); + goto err_pci_free_region; + } + ret = ath11k_pcic_init_msi_config(ab); if (ret) { ath11k_err(ab, "failed to init msi config: %d\n", ret); @@ -920,7 +958,9 @@ qmi_fail: 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); } diff --git a/drivers/net/wireless/ath/ath11k/pcic.c b/drivers/net/wireless/ath/ath11k/pcic.c index cf12b98c480d..1adf20ebef27 100644 --- a/drivers/net/wireless/ath/ath11k/pcic.c +++ b/drivers/net/wireless/ath/ath11k/pcic.c @@ -140,23 +140,8 @@ int ath11k_pcic_init_msi_config(struct ath11k_base *ab) } EXPORT_SYMBOL(ath11k_pcic_init_msi_config); -static inline u32 ath11k_pcic_get_window_start(struct ath11k_base *ab, - u32 offset) -{ - u32 window_start = 0; - - if ((offset ^ HAL_SEQ_WCSS_UMAC_OFFSET) < ATH11K_PCI_WINDOW_RANGE_MASK) - window_start = ab->hw_params.dp_window_idx * ATH11K_PCI_WINDOW_START; - else if ((offset ^ HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab)) < - ATH11K_PCI_WINDOW_RANGE_MASK) - window_start = ab->hw_params.ce_window_idx * ATH11K_PCI_WINDOW_START; - - return window_start; -} - void ath11k_pcic_write32(struct ath11k_base *ab, u32 offset, u32 value) { - u32 window_start; int ret = 0; /* for offset beyond BAR + 4K - 32, may @@ -166,15 +151,10 @@ void ath11k_pcic_write32(struct ath11k_base *ab, u32 offset, u32 value) offset >= ATH11K_PCI_ACCESS_ALWAYS_OFF && ab->pci.ops->wakeup) ret = ab->pci.ops->wakeup(ab); - if (offset < ATH11K_PCI_WINDOW_START) { + if (offset < ATH11K_PCI_WINDOW_START) iowrite32(value, ab->mem + offset); - } else if (ab->hw_params.static_window_map) { - window_start = ath11k_pcic_get_window_start(ab, offset); - iowrite32(value, ab->mem + window_start + - (offset & ATH11K_PCI_WINDOW_RANGE_MASK)); - } else if (ab->pci.ops->window_write32) { + else ab->pci.ops->window_write32(ab, offset, value); - } if (test_bit(ATH11K_FLAG_DEVICE_INIT_DONE, &ab->dev_flags) && offset >= ATH11K_PCI_ACCESS_ALWAYS_OFF && ab->pci.ops->release && @@ -185,9 +165,8 @@ EXPORT_SYMBOL(ath11k_pcic_write32); u32 ath11k_pcic_read32(struct ath11k_base *ab, u32 offset) { - u32 val = 0; - u32 window_start; int ret = 0; + u32 val; /* for offset beyond BAR + 4K - 32, may * need to wakeup the device to access. @@ -196,15 +175,10 @@ u32 ath11k_pcic_read32(struct ath11k_base *ab, u32 offset) offset >= ATH11K_PCI_ACCESS_ALWAYS_OFF && ab->pci.ops->wakeup) ret = ab->pci.ops->wakeup(ab); - if (offset < ATH11K_PCI_WINDOW_START) { + if (offset < ATH11K_PCI_WINDOW_START) val = ioread32(ab->mem + offset); - } else if (ab->hw_params.static_window_map) { - window_start = ath11k_pcic_get_window_start(ab, offset); - val = ioread32(ab->mem + window_start + - (offset & ATH11K_PCI_WINDOW_RANGE_MASK)); - } else if (ab->pci.ops->window_read32) { + else val = ab->pci.ops->window_read32(ab, offset); - } if (test_bit(ATH11K_FLAG_DEVICE_INIT_DONE, &ab->dev_flags) && offset >= ATH11K_PCI_ACCESS_ALWAYS_OFF && ab->pci.ops->release && @@ -516,11 +490,6 @@ static irqreturn_t ath11k_pcic_ext_interrupt_handler(int irq, void *arg) static int ath11k_pcic_get_msi_irq(struct ath11k_base *ab, unsigned int vector) { - if (!ab->pci.ops->get_msi_irq) { - WARN_ONCE(1, "get_msi_irq pci op not defined"); - return -EOPNOTSUPP; - } - return ab->pci.ops->get_msi_irq(ab, vector); } @@ -746,3 +715,19 @@ int ath11k_pcic_map_service_to_pipe(struct ath11k_base *ab, u16 service_id, return 0; } EXPORT_SYMBOL(ath11k_pcic_map_service_to_pipe); + +int ath11k_pcic_register_pci_ops(struct ath11k_base *ab, + const struct ath11k_pci_ops *pci_ops) +{ + if (!pci_ops) + return 0; + + /* Return error if mandatory pci_ops callbacks are missing */ + if (!pci_ops->get_msi_irq || !pci_ops->window_write32 || + !pci_ops->window_read32) + return -EINVAL; + + ab->pci.ops = pci_ops; + return 0; +} +EXPORT_SYMBOL(ath11k_pcic_register_pci_ops); diff --git a/drivers/net/wireless/ath/ath11k/pcic.h b/drivers/net/wireless/ath/ath11k/pcic.h index c53d86289a8e..0afbb34510db 100644 --- a/drivers/net/wireless/ath/ath11k/pcic.h +++ b/drivers/net/wireless/ath/ath11k/pcic.h @@ -43,4 +43,6 @@ int ath11k_pcic_map_service_to_pipe(struct ath11k_base *ab, u16 service_id, void ath11k_pcic_ce_irqs_enable(struct ath11k_base *ab); void ath11k_pcic_ce_irq_disable_sync(struct ath11k_base *ab); int ath11k_pcic_init_msi_config(struct ath11k_base *ab); +int ath11k_pcic_register_pci_ops(struct ath11k_base *ab, + const struct ath11k_pci_ops *pci_ops); #endif diff --git a/drivers/net/wireless/ath/ath11k/qmi.c b/drivers/net/wireless/ath/ath11k/qmi.c index 61ead37a944a..00136601cb7d 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 7b1dc19c565e..88ee4f9d19da 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c @@ -129,8 +129,6 @@ static const struct wmi_tlv_policy wmi_tlv_policies[] = { = { .min_len = sizeof(struct wmi_peer_assoc_conf_event) }, [WMI_TAG_STATS_EVENT] = { .min_len = sizeof(struct wmi_stats_event) }, - [WMI_TAG_RFKILL_EVENT] = { - .min_len = sizeof(struct wmi_rfkill_state_change_ev) }, [WMI_TAG_PDEV_CTL_FAILSAFE_CHECK_EVENT] = { .min_len = sizeof(struct wmi_pdev_ctl_failsafe_chk_event) }, [WMI_TAG_HOST_SWFDA_EVENT] = { @@ -533,8 +531,6 @@ static int ath11k_pull_service_ready_tlv(struct ath11k_base *ab, cap->default_dbs_hw_mode_index = ev->default_dbs_hw_mode_index; cap->num_msdu_desc = ev->num_msdu_desc; - ath11k_dbg(ab, ATH11K_DBG_WMI, "wmi sys cap info 0x%x\n", cap->sys_cap_info); - return 0; } @@ -1700,7 +1696,7 @@ int ath11k_wmi_bcn_tmpl(struct ath11k *ar, u32 vdev_id, cmd->vdev_id = vdev_id; cmd->tim_ie_offset = offs->tim_offset; - if (vif->csa_active) { + if (vif->bss_conf.csa_active) { cmd->csa_switch_count_offset = offs->cntdwn_counter_offs[0]; cmd->ext_csa_switch_count_offset = offs->cntdwn_counter_offs[1]; } @@ -6564,7 +6560,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 @@ -7476,7 +7472,7 @@ ath11k_wmi_process_csa_switch_count_event(struct ath11k_base *ab, continue; } - if (arvif->is_up && arvif->vif->csa_active) + if (arvif->is_up && arvif->vif->bss_conf.csa_active) ieee80211_csa_finish(arvif->vif); } rcu_read_unlock(); @@ -7566,40 +7562,6 @@ exit: kfree(tb); } -static void ath11k_rfkill_state_change_event(struct ath11k_base *ab, - struct sk_buff *skb) -{ - const struct wmi_rfkill_state_change_ev *ev; - const void **tb; - 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_RFKILL_EVENT]; - if (!ev) { - kfree(tb); - return; - } - - ath11k_dbg(ab, ATH11K_DBG_MAC, - "wmi tlv rfkill state change gpio %d type %d radio_state %d\n", - ev->gpio_pin_num, - ev->int_type, - ev->radio_state); - - spin_lock_bh(&ab->base_lock); - ab->rfkill_radio_on = (ev->radio_state == WMI_RFKILL_RADIO_STATE_ON); - spin_unlock_bh(&ab->base_lock); - - queue_work(ab->workqueue, &ab->rfkill_work); - kfree(tb); -} - static void ath11k_wmi_pdev_temperature_event(struct ath11k_base *ab, struct sk_buff *skb) @@ -7995,9 +7957,6 @@ static void ath11k_wmi_tlv_op_rx(struct ath11k_base *ab, struct sk_buff *skb) case WMI_11D_NEW_COUNTRY_EVENTID: ath11k_reg_11d_new_cc_event(ab, skb); break; - case WMI_RFKILL_STATE_CHANGE_EVENTID: - ath11k_rfkill_state_change_event(ab, skb); - break; case WMI_DIAG_EVENTID: ath11k_wmi_diag_event(ab, skb); break; diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h index b1fad4707dc6..4da248ffa318 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.h +++ b/drivers/net/wireless/ath/ath11k/wmi.h @@ -5328,31 +5328,6 @@ struct target_resource_config { u32 twt_ap_sta_count; }; -enum wmi_sys_cap_info_flags { - WMI_SYS_CAP_INFO_RXTX_LED = BIT(0), - WMI_SYS_CAP_INFO_RFKILL = BIT(1), -}; - -#define WMI_RFKILL_CFG_GPIO_PIN_NUM GENMASK(5, 0) -#define WMI_RFKILL_CFG_RADIO_LEVEL BIT(6) -#define WMI_RFKILL_CFG_PIN_AS_GPIO GENMASK(10, 7) - -enum wmi_rfkill_enable_radio { - WMI_RFKILL_ENABLE_RADIO_ON = 0, - WMI_RFKILL_ENABLE_RADIO_OFF = 1, -}; - -enum wmi_rfkill_radio_state { - WMI_RFKILL_RADIO_STATE_OFF = 1, - WMI_RFKILL_RADIO_STATE_ON = 2, -}; - -struct wmi_rfkill_state_change_ev { - u32 gpio_pin_num; - u32 int_type; - u32 radio_state; -} __packed; - enum wmi_debug_log_param { WMI_DEBUG_LOG_PARAM_LOG_LEVEL = 0x1, WMI_DEBUG_LOG_PARAM_VDEV_ENABLE, |