From patchwork Thu Jan 27 05:33:22 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manikanta Pubbisetty X-Patchwork-Id: 12726291 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A7F33C433EF for ; Thu, 27 Jan 2022 05:33:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236223AbiA0Fdq (ORCPT ); Thu, 27 Jan 2022 00:33:46 -0500 Received: from alexa-out.qualcomm.com ([129.46.98.28]:50885 "EHLO alexa-out.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233121AbiA0Fdp (ORCPT ); Thu, 27 Jan 2022 00:33:45 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1643261625; x=1674797625; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version; bh=2h0dYAYmdlN5eRAPm8zpvihUYGff15A2BFWGba7H+ac=; b=ElrkjwTzlQTw3CSw3Zp0gu8hkjJs46AsJMvWdSW4uPynZNPJ12eFupdQ HPwvWDIKASRcVUHN+cts7dGej/Sdqc4znX12Cjjp2QYztTBl56RCwC381 0TwN7eYIooDXcQaWxxilLsfsN1lGzQ2w5ohU8z/O1/DU9PvgYamGxBYHZ A=; Received: from ironmsg-lv-alpha.qualcomm.com ([10.47.202.13]) by alexa-out.qualcomm.com with ESMTP; 26 Jan 2022 21:33:45 -0800 X-QCInternal: smtphost Received: from nasanex01c.na.qualcomm.com ([10.47.97.222]) by ironmsg-lv-alpha.qualcomm.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Jan 2022 21:33:44 -0800 Received: from nalasex01a.na.qualcomm.com (10.47.209.196) by nasanex01c.na.qualcomm.com (10.47.97.222) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.922.19; Wed, 26 Jan 2022 21:33:44 -0800 Received: from mpubbise-linux.qualcomm.com (10.80.80.8) by nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.922.19; Wed, 26 Jan 2022 21:33:42 -0800 From: Manikanta Pubbisetty To: CC: , Manikanta Pubbisetty Subject: [PATCH RFC 1/8] ath11k: Enable low power mode when WLAN is not active Date: Thu, 27 Jan 2022 11:03:22 +0530 Message-ID: <1643261609-13500-2-git-send-email-quic_mpubbise@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1643261609-13500-1-git-send-email-quic_mpubbise@quicinc.com> References: <1643261609-13500-1-git-send-email-quic_mpubbise@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To nalasex01a.na.qualcomm.com (10.47.209.196) Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org Currently, WLAN chip is powered once during driver probe and is kept ON (powered) always even when WLAN is not active; keeping the chip powered ON all the time will consume extra power which is not desirable on a battery operated device. Same is the case with non-WoW suspend, chip will not be put into low power mode when the system is suspended resulting in higher battery drain. As per the recommendation, sending a PDEV suspend WMI command followed by a QMI MODE OFF command will cease all WLAN activity and put the device in low power mode. Put the chip in low power mode when there are no active WLAN interfaces and during non-WoW suspend to conserve power. The logic is being applied only for WCN6750 not impacting other supported chips. Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.1.0.1-00573-QCAMSLSWPLZ-1 Signed-off-by: Manikanta Pubbisetty --- drivers/net/wireless/ath/ath11k/core.c | 141 ++++++++++++++++++++++++------ drivers/net/wireless/ath/ath11k/core.h | 5 +- drivers/net/wireless/ath/ath11k/hw.h | 3 +- drivers/net/wireless/ath/ath11k/mac.c | 27 +++++- drivers/net/wireless/ath/ath11k/thermal.c | 12 +++ 5 files changed, 159 insertions(+), 29 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index 86373d6..acb8861 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. - * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -97,6 +97,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .alloc_cacheable_memory = true, .supports_rssi_stats = false, .fw_wmi_diag_event = false, + .non_wow_suspend = false, }, { .hw_rev = ATH11K_HW_IPQ6018_HW10, @@ -160,6 +161,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .alloc_cacheable_memory = true, .supports_rssi_stats = false, .fw_wmi_diag_event = false, + .non_wow_suspend = false, }, { .name = "qca6390 hw2.0", @@ -222,6 +224,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .alloc_cacheable_memory = false, .supports_rssi_stats = true, .fw_wmi_diag_event = true, + .non_wow_suspend = false, }, { .name = "qcn9074 hw1.0", @@ -284,6 +287,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .alloc_cacheable_memory = true, .supports_rssi_stats = false, .fw_wmi_diag_event = false, + .non_wow_suspend = false, }, { .name = "wcn6855 hw2.0", @@ -346,6 +350,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .alloc_cacheable_memory = false, .supports_rssi_stats = true, .fw_wmi_diag_event = true, + .non_wow_suspend = false, }, { .name = "wcn6855 hw2.1", @@ -407,6 +412,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .alloc_cacheable_memory = false, .supports_rssi_stats = true, .fw_wmi_diag_event = true, + .non_wow_suspend = false, }, { .name = "wcn6750 hw1.0", @@ -468,6 +474,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .alloc_cacheable_memory = false, .supports_rssi_stats = true, .fw_wmi_diag_event = false, + .non_wow_suspend = true, }, }; @@ -931,7 +938,6 @@ static int ath11k_core_soc_create(struct ath11k_base *ab) static void ath11k_core_soc_destroy(struct ath11k_base *ab) { ath11k_debugfs_soc_destroy(ab); - ath11k_dp_free(ab); ath11k_reg_free(ab); ath11k_qmi_deinit_service(ab); } @@ -987,11 +993,10 @@ static int ath11k_core_pdev_create(struct ath11k_base *ab) static void ath11k_core_pdev_destroy(struct ath11k_base *ab) { - ath11k_spectral_deinit(ab); ath11k_thermal_unregister(ab); ath11k_mac_unregister(ab); - ath11k_hif_irq_disable(ab); - ath11k_dp_pdev_free(ab); + if (!test_bit(ATH11K_FLAG_DEVICE_STOPPED, &ab->dev_flags)) + ath11k_core_stop_device(ab); ath11k_debugfs_pdev_destroy(ab); } @@ -1205,6 +1210,9 @@ int ath11k_core_qmi_firmware_ready(struct ath11k_base *ab) mutex_unlock(&ab->core_lock); + if (!test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags)) + ath11k_core_stop_device(ab); + return 0; err_core_stop: @@ -1221,10 +1229,7 @@ int ath11k_core_qmi_firmware_ready(struct ath11k_base *ab) static int ath11k_core_reconfigure_on_crash(struct ath11k_base *ab) { - int ret; - mutex_lock(&ab->core_lock); - ath11k_thermal_unregister(ab); ath11k_hif_irq_disable(ab); ath11k_dp_pdev_free(ab); ath11k_spectral_deinit(ab); @@ -1234,27 +1239,11 @@ static int ath11k_core_reconfigure_on_crash(struct ath11k_base *ab) mutex_unlock(&ab->core_lock); ath11k_dp_free(ab); - ath11k_hal_srng_deinit(ab); + set_bit(ATH11K_FLAG_DEVICE_STOPPED, &ab->dev_flags); ab->free_vdev_map = (1LL << (ab->num_radios * TARGET_NUM_VDEVS(ab))) - 1; - ret = ath11k_hal_srng_init(ab); - if (ret) - return ret; - - clear_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags); - - ret = ath11k_core_qmi_firmware_ready(ab); - if (ret) - goto err_hal_srng_deinit; - - clear_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags); - return 0; - -err_hal_srng_deinit: - ath11k_hal_srng_deinit(ab); - return ret; } void ath11k_core_halt(struct ath11k *ar) @@ -1465,7 +1454,6 @@ void ath11k_core_deinit(struct ath11k_base *ab) mutex_lock(&ab->core_lock); ath11k_core_pdev_destroy(ab); - ath11k_core_stop(ab); mutex_unlock(&ab->core_lock); @@ -1527,5 +1515,106 @@ struct ath11k_base *ath11k_core_alloc(struct device *dev, size_t priv_size, } EXPORT_SYMBOL(ath11k_core_alloc); +static int ath11k_core_suspend_target(struct ath11k_base *ab, u32 suspend_opt) +{ + struct ath11k *ar; + struct ath11k_pdev *pdev; + unsigned long time_left; + int ret; + int i; + + for (i = 0; i < ab->num_radios; i++) { + pdev = &ab->pdevs[i]; + ar = pdev->ar; + + reinit_completion(&ab->htc_suspend); + + ret = ath11k_wmi_pdev_suspend(ar, suspend_opt, pdev->pdev_id); + if (ret) { + ath11k_warn(ab, "could not suspend target (%d)\n", ret); + return ret; + } + + time_left = wait_for_completion_timeout(&ab->htc_suspend, 3 * HZ); + + if (!time_left) { + ath11k_warn(ab, "suspend timed out - target pause event never came\n"); + return -ETIMEDOUT; + } + } + + return 0; +} + +void ath11k_core_stop_device(struct ath11k_base *ab) +{ + if (!ab->hw_params.non_wow_suspend && + !test_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags)) + return; + + ath11k_core_suspend_target(ab, WMI_PDEV_SUSPEND_AND_DISABLE_INTR); + + ath11k_hif_irq_disable(ab); + ath11k_core_stop(ab); + ath11k_spectral_deinit(ab); + ath11k_dp_pdev_free(ab); + ath11k_dp_free(ab); + + set_bit(ATH11K_FLAG_DEVICE_STOPPED, &ab->dev_flags); +} + +int ath11k_core_start_device(struct ath11k_base *ab) +{ + int i; + int ret; + struct ath11k_pdev *pdev; + struct ath11k *ar; + + if (!ab->hw_params.non_wow_suspend && + !test_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags)) + return 0; + + for (i = 0; i < ab->num_radios; i++) { + pdev = &ab->pdevs[i]; + ar = pdev->ar; + if (!ar) + continue; + + if (ar->state == ATH11K_STATE_ON) + break; + } + + if (i == ab->num_radios || + test_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags)) { + if (!test_bit(ATH11K_FLAG_DEVICE_STOPPED, &ab->dev_flags)) + return -EAGAIN; + + ath11k_hal_srng_deinit(ab); + + ret = ath11k_hal_srng_init(ab); + if (ret) { + ath11k_err(ab, "failed to allocate ce pipes: %d\n", ret); + return ret; + } + + clear_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags); + + ret = ath11k_core_qmi_firmware_ready(ab); + if (ret) { + ath11k_err(ab, "failed to init core: %d\n", ret); + goto err_hal_srng_deinit; + } + + clear_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags); + clear_bit(ATH11K_FLAG_DEVICE_STOPPED, &ab->dev_flags); + } + + return 0; + +err_hal_srng_deinit: + ath11k_hal_srng_deinit(ab); + return ret; +} + MODULE_DESCRIPTION("Core module for Qualcomm Atheros 802.11ax wireless LAN cards."); MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h index 76f5aef..758f271 100644 --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. - * Copyright (c) 2021, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef ATH11K_CORE_H @@ -208,6 +208,7 @@ enum ath11k_dev_flags { ATH11K_FLAG_FIXED_MEM_RGN, ATH11K_FLAG_DEVICE_INIT_DONE, ATH11K_FLAG_MULTI_MSI_VECTORS, + ATH11K_FLAG_DEVICE_STOPPED, }; enum ath11k_monitor_flags { @@ -1025,6 +1026,8 @@ int ath11k_core_check_dt(struct ath11k_base *ath11k); void ath11k_core_halt(struct ath11k *ar); int ath11k_core_resume(struct ath11k_base *ab); int ath11k_core_suspend(struct ath11k_base *ab); +void ath11k_core_stop_device(struct ath11k_base *ab); +int ath11k_core_start_device(struct ath11k_base *ab); const struct firmware *ath11k_core_firmware_request(struct ath11k_base *ab, const char *filename); diff --git a/drivers/net/wireless/ath/ath11k/hw.h b/drivers/net/wireless/ath/ath11k/hw.h index a220c9a..a38745e 100644 --- a/drivers/net/wireless/ath/ath11k/hw.h +++ b/drivers/net/wireless/ath/ath11k/hw.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. - * Copyright (c) 2021, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef ATH11K_HW_H @@ -192,6 +192,7 @@ struct ath11k_hw_params { bool alloc_cacheable_memory; bool supports_rssi_stats; bool fw_wmi_diag_event; + bool non_wow_suspend; }; struct ath11k_hw_ops { diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index ac6a192..2402405 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. - * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -5726,6 +5726,14 @@ static int ath11k_mac_op_start(struct ieee80211_hw *hw) int ret; ath11k_mac_drain_tx(ar); + + ret = ath11k_core_start_device(ab); + if (ret) { + if (ret != -EAGAIN) + ath11k_err(ab, "failed to start device : %d\n", ret); + return ret; + } + mutex_lock(&ar->conf_mutex); switch (ar->state) { @@ -5847,8 +5855,11 @@ static int ath11k_mac_op_start(struct ieee80211_hw *hw) static void ath11k_mac_op_stop(struct ieee80211_hw *hw) { struct ath11k *ar = hw->priv; + struct ath11k_base *ab = ar->ab; + struct ath11k_pdev *pdev; struct htt_ppdu_stats_info *ppdu_stats, *tmp; int ret; + int i; ath11k_mac_drain_tx(ar); @@ -5879,6 +5890,20 @@ static void ath11k_mac_op_stop(struct ieee80211_hw *hw) synchronize_rcu(); atomic_set(&ar->num_pending_mgmt_tx, 0); + + for (i = 0; i < ab->num_radios; i++) { + pdev = &ab->pdevs[i]; + ar = pdev->ar; + if (!ar || ar->state == ATH11K_STATE_OFF) + continue; + break; + } + + /* All PDEVs on the SoC are down, time to power down + * the device. + */ + if (i == ab->num_radios) + ath11k_core_stop_device(ab); } static void diff --git a/drivers/net/wireless/ath/ath11k/thermal.c b/drivers/net/wireless/ath/ath11k/thermal.c index c96b26f..acb3b45 100644 --- a/drivers/net/wireless/ath/ath11k/thermal.c +++ b/drivers/net/wireless/ath/ath11k/thermal.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -69,6 +70,11 @@ static ssize_t ath11k_thermal_show_temp(struct device *dev, mutex_lock(&ar->conf_mutex); + if (test_bit(ATH11K_FLAG_CRASH_FLUSH, &ar->ab->dev_flags)) { + ret = -ESHUTDOWN; + goto out; + } + /* Can't get temperature when the card is off */ if (ar->state != ATH11K_STATE_ON) { ret = -ENETDOWN; @@ -131,6 +137,9 @@ int ath11k_thermal_set_throttling(struct ath11k *ar, u32 throttle_state) lockdep_assert_held(&ar->conf_mutex); + if (test_bit(ATH11K_FLAG_CRASH_FLUSH, &ar->ab->dev_flags)) + return 0; + if (ar->state != ATH11K_STATE_ON) return 0; @@ -162,6 +171,9 @@ int ath11k_thermal_register(struct ath11k_base *sc) struct ath11k_pdev *pdev; int i, ret; + if (test_bit(ATH11K_FLAG_REGISTERED, &sc->dev_flags)) + return 0; + for (i = 0; i < sc->num_radios; i++) { pdev = &sc->pdevs[i]; ar = pdev->ar; From patchwork Thu Jan 27 05:33:23 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manikanta Pubbisetty X-Patchwork-Id: 12726292 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id BE4B0C433F5 for ; Thu, 27 Jan 2022 05:33:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236262AbiA0Fdr (ORCPT ); Thu, 27 Jan 2022 00:33:47 -0500 Received: from alexa-out-sd-02.qualcomm.com ([199.106.114.39]:2542 "EHLO alexa-out-sd-02.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233121AbiA0Fdr (ORCPT ); Thu, 27 Jan 2022 00:33:47 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1643261627; x=1674797627; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version; bh=ab7NghZ+xnLjogVj6QomxLHLTctgOwl/jJKhlfXHZdA=; b=dZkXhHqXIWvZpeFQGczqm07GVpNsSF+d/zVbEFSXIUxmU7BH+tg2Tw2g XfC1XZCl49qn9RYRenpSJwyZ4uVvJKz6U70DlhIY67tRbH4c/tL4WhKLd 9Bl+6MpBdBT3LJfiW6uMY9HyPSr08QKirQE6OoI8pWt2mSWfQW1v54oza E=; Received: from unknown (HELO ironmsg02-sd.qualcomm.com) ([10.53.140.142]) by alexa-out-sd-02.qualcomm.com with ESMTP; 26 Jan 2022 21:33:47 -0800 X-QCInternal: smtphost Received: from nasanex01c.na.qualcomm.com ([10.47.97.222]) by ironmsg02-sd.qualcomm.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Jan 2022 21:33:47 -0800 Received: from nalasex01a.na.qualcomm.com (10.47.209.196) by nasanex01c.na.qualcomm.com (10.47.97.222) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.922.19; Wed, 26 Jan 2022 21:33:46 -0800 Received: from mpubbise-linux.qualcomm.com (10.80.80.8) by nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.922.19; Wed, 26 Jan 2022 21:33:44 -0800 From: Manikanta Pubbisetty To: CC: , Manikanta Pubbisetty Subject: [PATCH RFC 2/8] ath11k: Register shutdown handler for WCN6750 Date: Thu, 27 Jan 2022 11:03:23 +0530 Message-ID: <1643261609-13500-3-git-send-email-quic_mpubbise@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1643261609-13500-1-git-send-email-quic_mpubbise@quicinc.com> References: <1643261609-13500-1-git-send-email-quic_mpubbise@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To nalasex01a.na.qualcomm.com (10.47.209.196) Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org When the system shuts down, SMMU driver will be stopped and will not assist in IOVA translation. SMMU driver expects all of its consumers to shutdown before shutting down itself. WCN6750 being one of the consumer should not perform DMA activity after SMMU shutdown which will otherwise result in a SMMU fault. SMMU driver will call the shutdown() callback of all its consumer devices and the consumers shall stop further DMA activity after the invocation of their respective shutdown() callback. Register the shutdown() callback to the platform core for WCN6750. Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.1.0.1-00573-QCAMSLSWPLZ-1 Signed-off-by: Manikanta Pubbisetty --- drivers/net/wireless/ath/ath11k/ahb.c | 36 ++++++++++++++++++++++++++++++++++- drivers/net/wireless/ath/ath11k/qmi.c | 3 +-- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/ahb.c b/drivers/net/wireless/ath/ath11k/ahb.c index 7cb13a0..97ee8c4 100644 --- a/drivers/net/wireless/ath/ath11k/ahb.c +++ b/drivers/net/wireless/ath/ath11k/ahb.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. - * Copyright (c) 2021, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -1069,6 +1069,7 @@ static int ath11k_ahb_remove(struct platform_device *pdev) set_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags); cancel_work_sync(&ab->restart_work); + cancel_work_sync(&ab->qmi.event_work); ath11k_core_deinit(ab); qmi_fail: @@ -1082,6 +1083,38 @@ static int ath11k_ahb_remove(struct platform_device *pdev) return 0; } +static void ath11k_ahb_shutdown(struct platform_device *pdev) +{ + struct ath11k_base *ab = platform_get_drvdata(pdev); + unsigned long left; + + reinit_completion(&ab->driver_recovery); + + if (test_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags)) { + left = wait_for_completion_timeout(&ab->driver_recovery, + ATH11K_AHB_RECOVERY_TIMEOUT); + if (!left) + ath11k_warn(ab, "failed to receive recovery response completion\n"); + } + + set_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags); + cancel_work_sync(&ab->restart_work); + cancel_work_sync(&ab->qmi.event_work); + + if (!(test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags))) + goto free_resources; + + ath11k_core_deinit(ab); + +free_resources: + ath11k_ahb_free_irq(ab); + ath11k_hal_srng_deinit(ab); + ath11k_ahb_fw_resource_deinit(ab); + ath11k_ce_free_pipes(ab); + ath11k_core_free(ab); + platform_set_drvdata(pdev, NULL); +} + static struct platform_driver ath11k_ahb_driver = { .driver = { .name = "ath11k", @@ -1089,6 +1122,7 @@ static struct platform_driver ath11k_ahb_driver = { }, .probe = ath11k_ahb_probe, .remove = ath11k_ahb_remove, + .shutdown = ath11k_ahb_shutdown, }; static int ath11k_ahb_init(void) diff --git a/drivers/net/wireless/ath/ath11k/qmi.c b/drivers/net/wireless/ath/ath11k/qmi.c index 4745ff9..f50c273 100644 --- a/drivers/net/wireless/ath/ath11k/qmi.c +++ b/drivers/net/wireless/ath/ath11k/qmi.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. - * Copyright (c) 2021, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -3185,7 +3185,6 @@ int ath11k_qmi_init_service(struct ath11k_base *ab) void ath11k_qmi_deinit_service(struct ath11k_base *ab) { qmi_handle_release(&ab->qmi.handle); - cancel_work_sync(&ab->qmi.event_work); destroy_workqueue(ab->qmi.event_wq); ath11k_qmi_m3_free(ab); ath11k_qmi_free_target_mem_chunk(ab); From patchwork Thu Jan 27 05:33:24 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manikanta Pubbisetty X-Patchwork-Id: 12726293 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1B914C433F5 for ; Thu, 27 Jan 2022 05:33:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236267AbiA0Fdu (ORCPT ); Thu, 27 Jan 2022 00:33:50 -0500 Received: from alexa-out-sd-01.qualcomm.com ([199.106.114.38]:53591 "EHLO alexa-out-sd-01.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236258AbiA0Fdt (ORCPT ); Thu, 27 Jan 2022 00:33:49 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1643261629; x=1674797629; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version; bh=rjD71jbAoUNdvtwGxcW18e13EHw0v0VdRbA8C0IeJJs=; b=tq2mEXges5zOWNoIEZrmrwmqiXv79KYBnYLhOauds2qt9fJO8MhPOL7p U9aDK3G/gMGgKPGUrSGUap1yGwUU8DaFQo2GVZZJZXk9jVOrFVydGg5V8 0p3alkmNGQEDd3M+NYplWZQA/bJV7UgQ7B9uWTYLljd5fxUWyXOyr7Lwp Y=; Received: from unknown (HELO ironmsg04-sd.qualcomm.com) ([10.53.140.144]) by alexa-out-sd-01.qualcomm.com with ESMTP; 26 Jan 2022 21:33:49 -0800 X-QCInternal: smtphost Received: from nasanex01c.na.qualcomm.com ([10.47.97.222]) by ironmsg04-sd.qualcomm.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Jan 2022 21:33:49 -0800 Received: from nalasex01a.na.qualcomm.com (10.47.209.196) by nasanex01c.na.qualcomm.com (10.47.97.222) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.922.19; Wed, 26 Jan 2022 21:33:49 -0800 Received: from mpubbise-linux.qualcomm.com (10.80.80.8) by nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.922.19; Wed, 26 Jan 2022 21:33:47 -0800 From: Manikanta Pubbisetty To: CC: , Manikanta Pubbisetty Subject: [PATCH RFC 3/8] ath11k: Cold boot calibration support on WCN6750 Date: Thu, 27 Jan 2022 11:03:24 +0530 Message-ID: <1643261609-13500-4-git-send-email-quic_mpubbise@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1643261609-13500-1-git-send-email-quic_mpubbise@quicinc.com> References: <1643261609-13500-1-git-send-email-quic_mpubbise@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To nalasex01a.na.qualcomm.com (10.47.209.196) Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org Add cold boot calibration support on WCN6750. Unlike other chipsets where firmware (FW) is restarted after cold boot caliration is completed, it is recommended not to restart the firmware for WCN6750. Also, QMI message IDs for some of the QMI messages were incorrectly defined in the original implementation, these has to be corrected for enabling cold boot support on WCN6750. These corrections are applicable for all chipsets and will not impact them. QMI message flow for WCN6750 with cold boot support: FW_INIT_DONE to HOST -> CALIBRATION Mode to FW -> CAL_DONE to Host -> FW_READY to Host -> MODE_ON to FW QMI message flow for other chipsets with cold boot support: FW_INIT_DONE to Host -> CALIBRATION Mode to FW -> CAL_DONE to Host -> Trigger FW restart -> FW_INIT_DONE to HOST -> MODE_ON to FW QMI message flow for chipsets without cold boot support: FW_INIT_DONE to Host -> MODE_ON to FW Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.1.0.1-00573-QCAMSLSWPLZ-1 Signed-off-by: Manikanta Pubbisetty --- drivers/net/wireless/ath/ath11k/ahb.c | 3 ++- drivers/net/wireless/ath/ath11k/core.c | 9 ++++++- drivers/net/wireless/ath/ath11k/hw.h | 1 + drivers/net/wireless/ath/ath11k/qmi.c | 44 +++++++++++++++++++++++++++++++++- drivers/net/wireless/ath/ath11k/qmi.h | 12 +++++++--- 5 files changed, 63 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/ahb.c b/drivers/net/wireless/ath/ath11k/ahb.c index 97ee8c4..4301f62 100644 --- a/drivers/net/wireless/ath/ath11k/ahb.c +++ b/drivers/net/wireless/ath/ath11k/ahb.c @@ -378,7 +378,8 @@ static int ath11k_ahb_fwreset_from_cold_boot(struct ath11k_base *ab) int timeout; if (ath11k_cold_boot_cal == 0 || ab->qmi.cal_done || - ab->hw_params.cold_boot_calib == 0) + ab->hw_params.cold_boot_calib == 0 || + ab->hw_params.cold_boot_fw_restart == 0) return 0; ath11k_dbg(ab, ATH11K_DBG_AHB, "wait for cold boot done\n"); diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index acb8861..643f655 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -83,6 +83,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .idle_ps = false, .supports_sta_ps = false, .cold_boot_calib = true, + .cold_boot_fw_restart = true, .fw_mem_mode = 0, .num_vdevs = 16 + 1, .num_peers = 512, @@ -147,6 +148,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .idle_ps = false, .supports_sta_ps = false, .cold_boot_calib = true, + .cold_boot_fw_restart = true, .fw_mem_mode = 0, .num_vdevs = 16 + 1, .num_peers = 512, @@ -210,6 +212,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .idle_ps = true, .supports_sta_ps = true, .cold_boot_calib = false, + .cold_boot_fw_restart = false, .fw_mem_mode = 0, .num_vdevs = 16 + 1, .num_peers = 512, @@ -273,6 +276,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .idle_ps = false, .supports_sta_ps = false, .cold_boot_calib = false, + .cold_boot_fw_restart = false, .fw_mem_mode = 2, .num_vdevs = 8, .num_peers = 128, @@ -336,6 +340,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .idle_ps = true, .supports_sta_ps = true, .cold_boot_calib = false, + .cold_boot_fw_restart = false, .fw_mem_mode = 0, .num_vdevs = 16 + 1, .num_peers = 512, @@ -398,6 +403,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .idle_ps = true, .supports_sta_ps = true, .cold_boot_calib = false, + .cold_boot_fw_restart = false, .fw_mem_mode = 0, .num_vdevs = 16 + 1, .num_peers = 512, @@ -459,7 +465,8 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .supports_shadow_regs = true, .idle_ps = true, .supports_sta_ps = true, - .cold_boot_calib = false, + .cold_boot_calib = true, + .cold_boot_fw_restart = false, .fw_mem_mode = 0, .num_vdevs = 16 + 1, .num_peers = 512, diff --git a/drivers/net/wireless/ath/ath11k/hw.h b/drivers/net/wireless/ath/ath11k/hw.h index a38745e..ed4b72b 100644 --- a/drivers/net/wireless/ath/ath11k/hw.h +++ b/drivers/net/wireless/ath/ath11k/hw.h @@ -193,6 +193,7 @@ struct ath11k_hw_params { bool supports_rssi_stats; bool fw_wmi_diag_event; bool non_wow_suspend; + bool cold_boot_fw_restart; }; struct ath11k_hw_ops { diff --git a/drivers/net/wireless/ath/ath11k/qmi.c b/drivers/net/wireless/ath/ath11k/qmi.c index f50c273..1f9b751d 100644 --- a/drivers/net/wireless/ath/ath11k/qmi.c +++ b/drivers/net/wireless/ath/ath11k/qmi.c @@ -1693,6 +1693,13 @@ static struct qmi_elem_info qmi_wlanfw_wlan_ini_resp_msg_v01_ei[] = { }, }; +static struct qmi_elem_info qmi_wlfw_fw_init_done_ind_msg_v01_ei[] = { + { + .data_type = QMI_EOTI, + .array_type = NO_ARRAY, + }, +}; + static int ath11k_qmi_host_cap_send(struct ath11k_base *ab) { struct qmi_wlanfw_host_cap_req_msg_v01 req; @@ -2999,6 +3006,19 @@ static void ath11k_qmi_msg_cold_boot_cal_done_cb(struct qmi_handle *qmi_hdl, ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi cold boot calibration done\n"); } +static void ath11k_qmi_msg_fw_init_done_cb(struct qmi_handle *qmi_hdl, + struct sockaddr_qrtr *sq, + struct qmi_txn *txn, + const void *decoded) +{ + struct ath11k_qmi *qmi = container_of(qmi_hdl, + struct ath11k_qmi, handle); + struct ath11k_base *ab = qmi->ab; + + ath11k_qmi_driver_event_post(qmi, ATH11K_QMI_EVENT_FW_INIT_DONE, NULL); + ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi firmware init done\n"); +} + static const struct qmi_msg_handler ath11k_qmi_msg_handlers[] = { { .type = QMI_INDICATION, @@ -3029,6 +3049,14 @@ static const struct qmi_msg_handler ath11k_qmi_msg_handlers[] = { sizeof(struct qmi_wlanfw_fw_cold_cal_done_ind_msg_v01), .fn = ath11k_qmi_msg_cold_boot_cal_done_cb, }, + { + .type = QMI_INDICATION, + .msg_id = QMI_WLFW_FW_INIT_DONE_IND_V01, + .ei = qmi_wlfw_fw_init_done_ind_msg_v01_ei, + .decoded_size = + sizeof(struct qmi_wlfw_fw_init_done_ind_msg_v01), + .fn = ath11k_qmi_msg_fw_init_done_cb, + }, }; static int ath11k_qmi_ops_new_server(struct qmi_handle *qmi_hdl, @@ -3111,7 +3139,7 @@ static void ath11k_qmi_driver_event_work(struct work_struct *work) if (ret < 0) set_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags); break; - case ATH11K_QMI_EVENT_FW_READY: + case ATH11K_QMI_EVENT_FW_INIT_DONE: clear_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags); if (test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags)) { ath11k_hal_dump_srng_stats(ab); @@ -3131,6 +3159,20 @@ static void ath11k_qmi_driver_event_work(struct work_struct *work) } break; + case ATH11K_QMI_EVENT_FW_READY: + /* For targets requiring a FW restart upon cold + * boot completion, there is no need to process + * FW ready; such targets will receive FW init + * done message after FW restart. + */ + if (!ab->hw_params.cold_boot_fw_restart) { + clear_bit(ATH11K_FLAG_CRASH_FLUSH, + &ab->dev_flags); + clear_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags); + ath11k_core_qmi_firmware_ready(ab); + set_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags); + } + break; case ATH11K_QMI_EVENT_COLD_BOOT_CAL_DONE: break; default: diff --git a/drivers/net/wireless/ath/ath11k/qmi.h b/drivers/net/wireless/ath/ath11k/qmi.h index 593d81ed..f3cea7d 100644 --- a/drivers/net/wireless/ath/ath11k/qmi.h +++ b/drivers/net/wireless/ath/ath11k/qmi.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. - * Copyright (c) 2021, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef ATH11K_QMI_H @@ -31,8 +31,9 @@ #define QMI_WLFW_REQUEST_MEM_IND_V01 0x0035 #define QMI_WLFW_FW_MEM_READY_IND_V01 0x0037 -#define QMI_WLFW_COLD_BOOT_CAL_DONE_IND_V01 0x0021 -#define QMI_WLFW_FW_READY_IND_V01 0x0038 +#define QMI_WLFW_COLD_BOOT_CAL_DONE_IND_V01 0x003E +#define QMI_WLFW_FW_READY_IND_V01 0x0021 +#define QMI_WLFW_FW_INIT_DONE_IND_V01 0x0038 #define QMI_WLANFW_MAX_DATA_SIZE_V01 6144 #define ATH11K_FIRMWARE_MODE_OFF 4 @@ -69,6 +70,7 @@ enum ath11k_qmi_event_type { ATH11K_QMI_EVENT_FORCE_FW_ASSERT, ATH11K_QMI_EVENT_POWER_UP, ATH11K_QMI_EVENT_POWER_DOWN, + ATH11K_QMI_EVENT_FW_INIT_DONE, ATH11K_QMI_EVENT_MAX, }; @@ -289,6 +291,10 @@ struct qmi_wlanfw_fw_cold_cal_done_ind_msg_v01 { char placeholder; }; +struct qmi_wlfw_fw_init_done_ind_msg_v01 { + char placeholder; +}; + #define QMI_WLANFW_CAP_REQ_MSG_V01_MAX_LEN 0 #define QMI_WLANFW_CAP_RESP_MSG_V01_MAX_LEN 235 #define QMI_WLANFW_CAP_REQ_V01 0x0024 From patchwork Thu Jan 27 05:33:25 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manikanta Pubbisetty X-Patchwork-Id: 12726294 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B29F7C433FE for ; Thu, 27 Jan 2022 05:33:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236258AbiA0Fdw (ORCPT ); Thu, 27 Jan 2022 00:33:52 -0500 Received: from alexa-out.qualcomm.com ([129.46.98.28]:39341 "EHLO alexa-out.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233121AbiA0Fdv (ORCPT ); Thu, 27 Jan 2022 00:33:51 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1643261631; x=1674797631; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version; bh=0LNGn4Augm8ykglUCzO1NAeXrbYBC//4ak+/9v2H5R8=; b=nheW+XyduqWt8bhChMuvpHMQo1RnDL5gRgSm+D8zqmEiy7kWYhgDW2sJ XPK5BbDWO3bdsLttR5uLsSYUB4N4OxUWPIAPIq3dhk2m4uxO9HhxjvWYG o78SVgE+rX4F6C7Ajz19JLGGxkeh7WUmFTJ2SN8QlzODorumg7Mevnftv E=; Received: from ironmsg09-lv.qualcomm.com ([10.47.202.153]) by alexa-out.qualcomm.com with ESMTP; 26 Jan 2022 21:33:51 -0800 X-QCInternal: smtphost Received: from nasanex01c.na.qualcomm.com ([10.47.97.222]) by ironmsg09-lv.qualcomm.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Jan 2022 21:33:51 -0800 Received: from nalasex01a.na.qualcomm.com (10.47.209.196) by nasanex01c.na.qualcomm.com (10.47.97.222) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.922.19; Wed, 26 Jan 2022 21:33:51 -0800 Received: from mpubbise-linux.qualcomm.com (10.80.80.8) by nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.922.19; Wed, 26 Jan 2022 21:33:49 -0800 From: Manikanta Pubbisetty To: CC: , Manikanta Pubbisetty Subject: [PATCH RFC 4/8] ath11k: Cap NSS of HE peer to radio supported NSS Date: Thu, 27 Jan 2022 11:03:25 +0530 Message-ID: <1643261609-13500-5-git-send-email-quic_mpubbise@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1643261609-13500-1-git-send-email-quic_mpubbise@quicinc.com> References: <1643261609-13500-1-git-send-email-quic_mpubbise@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To nalasex01a.na.qualcomm.com (10.47.209.196) Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org Cap NSS of HE peer to radio supported NSS during assoc, this is needed as the WCN6750 FW expects peer NSS to be <= radio supported NSS, this will fix the FW assert because of peer NSS being greater than max NSS supported by the radio. Since we are capping the NSS to the NSS that radio supports, this change should not impact other supported hardware. Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.1.0.1-00573-QCAMSLSWPLZ-1 Signed-off-by: Manikanta Pubbisetty --- drivers/net/wireless/ath/ath11k/mac.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index 2402405..55cdee9 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -2274,6 +2274,7 @@ static void ath11k_peer_assoc_h_he(struct ath11k *ar, max_nss = i + 1; } arg->peer_nss = min(sta->rx_nss, max_nss); + arg->peer_nss = min_t(u32, arg->peer_nss, ar->num_rx_chains); if (arg->peer_phymode == MODE_11AX_HE160 || arg->peer_phymode == MODE_11AX_HE80_80) { From patchwork Thu Jan 27 05:33:26 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manikanta Pubbisetty X-Patchwork-Id: 12726295 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 660BDC433F5 for ; Thu, 27 Jan 2022 05:33:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236272AbiA0Fdy (ORCPT ); Thu, 27 Jan 2022 00:33:54 -0500 Received: from alexa-out-sd-01.qualcomm.com ([199.106.114.38]:53591 "EHLO alexa-out-sd-01.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233121AbiA0Fdx (ORCPT ); Thu, 27 Jan 2022 00:33:53 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1643261633; x=1674797633; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version; bh=r71iHHJZT83gDisJ2i6sLgN1YHMGs5Z8too8sVzWT2M=; b=wKrHJqeLUkgq2UYBtZaXkPorRyv+YeBX/KftTAQ7gU0m+NTsAbLqE49f zBQc5oQ7D68CeVWcXOxtiWm66RPg3NHJoGpqLSJDd6QFIwX0pln+EhHcY JgEcUKc3PthlgtylXgJdhrUnJUgiHeM+sndfIKXCcoGcjGgNqKTt58e5A I=; Received: from unknown (HELO ironmsg03-sd.qualcomm.com) ([10.53.140.143]) by alexa-out-sd-01.qualcomm.com with ESMTP; 26 Jan 2022 21:33:53 -0800 X-QCInternal: smtphost Received: from nasanex01c.na.qualcomm.com ([10.47.97.222]) by ironmsg03-sd.qualcomm.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Jan 2022 21:33:53 -0800 Received: from nalasex01a.na.qualcomm.com (10.47.209.196) by nasanex01c.na.qualcomm.com (10.47.97.222) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.922.19; Wed, 26 Jan 2022 21:33:53 -0800 Received: from mpubbise-linux.qualcomm.com (10.80.80.8) by nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.922.19; Wed, 26 Jan 2022 21:33:51 -0800 From: Manikanta Pubbisetty To: CC: , Manikanta Pubbisetty Subject: [PATCH RFC 5/8] ath11k: Enable threaded NAPI on WCN6750 Date: Thu, 27 Jan 2022 11:03:26 +0530 Message-ID: <1643261609-13500-6-git-send-email-quic_mpubbise@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1643261609-13500-1-git-send-email-quic_mpubbise@quicinc.com> References: <1643261609-13500-1-git-send-email-quic_mpubbise@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To nalasex01a.na.qualcomm.com (10.47.209.196) Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org Enable threaded NAPI on WCN6750; Unlike traditional NAPI poll which runs in softirq context and on the core which scheduled the NAPI, threaded NAPI makes use of kernel threads which are under direct control of the scheduler and helps in balancing the NAPI processing load across multiple CPUs, this helps in improving throughput. In the case of WCN6750, enabling threaded NAPI has improved 160Mhz RX throughput by nearly 400Mbps. Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.1.0.1-00573-QCAMSLSWPLZ-1 Signed-off-by: Manikanta Pubbisetty --- drivers/net/wireless/ath/ath11k/ahb.c | 2 ++ drivers/net/wireless/ath/ath11k/core.c | 7 +++++++ drivers/net/wireless/ath/ath11k/hw.h | 1 + drivers/net/wireless/ath/ath11k/pci_cmn.c | 4 +++- 4 files changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath11k/ahb.c b/drivers/net/wireless/ath/ath11k/ahb.c index 4301f62..fd3bb43 100644 --- a/drivers/net/wireless/ath/ath11k/ahb.c +++ b/drivers/net/wireless/ath/ath11k/ahb.c @@ -331,6 +331,8 @@ static void ath11k_ahb_ext_irq_enable(struct ath11k_base *ab) struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i]; if (!irq_grp->napi_enabled) { + if (ab->hw_params.threaded_napi) + dev_set_threaded(&irq_grp->napi_ndev, true); napi_enable(&irq_grp->napi); irq_grp->napi_enabled = true; } diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index 643f655..161bddf 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -99,6 +99,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .supports_rssi_stats = false, .fw_wmi_diag_event = false, .non_wow_suspend = false, + .threaded_napi = false, }, { .hw_rev = ATH11K_HW_IPQ6018_HW10, @@ -164,6 +165,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .supports_rssi_stats = false, .fw_wmi_diag_event = false, .non_wow_suspend = false, + .threaded_napi = false, }, { .name = "qca6390 hw2.0", @@ -228,6 +230,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .supports_rssi_stats = true, .fw_wmi_diag_event = true, .non_wow_suspend = false, + .threaded_napi = false, }, { .name = "qcn9074 hw1.0", @@ -292,6 +295,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .supports_rssi_stats = false, .fw_wmi_diag_event = false, .non_wow_suspend = false, + .threaded_napi = false, }, { .name = "wcn6855 hw2.0", @@ -356,6 +360,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .supports_rssi_stats = true, .fw_wmi_diag_event = true, .non_wow_suspend = false, + .threaded_napi = false, }, { .name = "wcn6855 hw2.1", @@ -419,6 +424,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .supports_rssi_stats = true, .fw_wmi_diag_event = true, .non_wow_suspend = false, + .threaded_napi = false, }, { .name = "wcn6750 hw1.0", @@ -482,6 +488,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .supports_rssi_stats = true, .fw_wmi_diag_event = false, .non_wow_suspend = true, + .threaded_napi = true, }, }; diff --git a/drivers/net/wireless/ath/ath11k/hw.h b/drivers/net/wireless/ath/ath11k/hw.h index ed4b72b..d33b9b7 100644 --- a/drivers/net/wireless/ath/ath11k/hw.h +++ b/drivers/net/wireless/ath/ath11k/hw.h @@ -194,6 +194,7 @@ struct ath11k_hw_params { bool fw_wmi_diag_event; bool non_wow_suspend; bool cold_boot_fw_restart; + bool threaded_napi; }; struct ath11k_hw_ops { diff --git a/drivers/net/wireless/ath/ath11k/pci_cmn.c b/drivers/net/wireless/ath/ath11k/pci_cmn.c index 047fcd7..6550f7c 100644 --- a/drivers/net/wireless/ath/ath11k/pci_cmn.c +++ b/drivers/net/wireless/ath/ath11k/pci_cmn.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved. */ #include "core.h" @@ -425,6 +425,8 @@ void ath11k_pci_ext_irq_enable(struct ath11k_base *ab) struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i]; if (!irq_grp->napi_enabled) { + if (ab->hw_params.threaded_napi) + dev_set_threaded(&irq_grp->napi_ndev, true); napi_enable(&irq_grp->napi); irq_grp->napi_enabled = true; } From patchwork Thu Jan 27 05:33:27 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manikanta Pubbisetty X-Patchwork-Id: 12726296 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4B100C433FE for ; Thu, 27 Jan 2022 05:33:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236283AbiA0Fd4 (ORCPT ); Thu, 27 Jan 2022 00:33:56 -0500 Received: from alexa-out-sd-02.qualcomm.com ([199.106.114.39]:2556 "EHLO alexa-out-sd-02.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236273AbiA0Fdz (ORCPT ); Thu, 27 Jan 2022 00:33:55 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1643261635; x=1674797635; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version; bh=grINu50fIJpu2V6gAsNBKv5IVQeesGIUlU5chOhbTic=; b=XKnsj9yFEr20wDZCN1LL/j8PEio/e+3koNTjlZmfcPwavh+xZenAmmmt 3COXczbKhierD43OIS/wiCR1uCnf4O4SBjJrHo9p7e/NQ30vaHbEZqpoD Gybwl43eleKhvJ2bDk7cEmN3djS6ftH2ZeOef5kEzw2wMh5nRiJmIKMPL 4=; Received: from unknown (HELO ironmsg-SD-alpha.qualcomm.com) ([10.53.140.30]) by alexa-out-sd-02.qualcomm.com with ESMTP; 26 Jan 2022 21:33:55 -0800 X-QCInternal: smtphost Received: from nasanex01c.na.qualcomm.com ([10.47.97.222]) by ironmsg-SD-alpha.qualcomm.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Jan 2022 21:33:55 -0800 Received: from nalasex01a.na.qualcomm.com (10.47.209.196) by nasanex01c.na.qualcomm.com (10.47.97.222) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.922.19; Wed, 26 Jan 2022 21:33:55 -0800 Received: from mpubbise-linux.qualcomm.com (10.80.80.8) by nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.922.19; Wed, 26 Jan 2022 21:33:53 -0800 From: Manikanta Pubbisetty To: CC: , Manikanta Pubbisetty Subject: [PATCH RFC 6/8] ath11k: Increase TCL data ring size Date: Thu, 27 Jan 2022 11:03:27 +0530 Message-ID: <1643261609-13500-7-git-send-email-quic_mpubbise@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1643261609-13500-1-git-send-email-quic_mpubbise@quicinc.com> References: <1643261609-13500-1-git-send-email-quic_mpubbise@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To nalasex01a.na.qualcomm.com (10.47.209.196) Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org Increase TCL data ring size from 512 to 2048, this is needed to meet 160Mhz TX throughput on WCN6750. As the ring size is increased, there will be a slight increase in memory used but should not impact the functioning of any hardware. Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.1.0.1-00573-QCAMSLSWPLZ-1 Signed-off-by: Manikanta Pubbisetty --- drivers/net/wireless/ath/ath11k/dp.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath11k/dp.h b/drivers/net/wireless/ath/ath11k/dp.h index 409d6cc..9a30367 100644 --- a/drivers/net/wireless/ath/ath11k/dp.h +++ b/drivers/net/wireless/ath/ath11k/dp.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 ATH11K_DP_H @@ -199,7 +200,7 @@ struct ath11k_pdev_dp { #define DP_IDLE_SCATTER_BUFS_MAX 16 #define DP_WBM_RELEASE_RING_SIZE 64 -#define DP_TCL_DATA_RING_SIZE 512 +#define DP_TCL_DATA_RING_SIZE 2048 #define DP_TX_COMP_RING_SIZE 32768 #define DP_TX_IDR_SIZE DP_TX_COMP_RING_SIZE #define DP_TCL_CMD_RING_SIZE 32 From patchwork Thu Jan 27 05:33:28 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manikanta Pubbisetty X-Patchwork-Id: 12726297 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D1165C433F5 for ; Thu, 27 Jan 2022 05:33:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236274AbiA0Fd7 (ORCPT ); Thu, 27 Jan 2022 00:33:59 -0500 Received: from alexa-out-sd-02.qualcomm.com ([199.106.114.39]:2556 "EHLO alexa-out-sd-02.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236275AbiA0Fd6 (ORCPT ); Thu, 27 Jan 2022 00:33:58 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1643261638; x=1674797638; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version; bh=A9qrRu+Dmdhu4SUyoeKXbRdopzhAN13BrqLccQXocaE=; b=WsAF+ZUSGwLaqniMtHCZQ09oL/rFWpQdcUkiji/QUahVlmmxztvYlIbq qgcX26/Od7dDPOkWWZUg1GlsKpV3BpDTGlGo/ezbSCqhZGi87N34gPG9Z mTnt2PDSys4NHDyBHWZbdH6LGgDt7dw+HO9S21wn53IsFZbGcuWC1SlG5 E=; Received: from unknown (HELO ironmsg-SD-alpha.qualcomm.com) ([10.53.140.30]) by alexa-out-sd-02.qualcomm.com with ESMTP; 26 Jan 2022 21:33:58 -0800 X-QCInternal: smtphost Received: from nasanex01c.na.qualcomm.com ([10.47.97.222]) by ironmsg-SD-alpha.qualcomm.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Jan 2022 21:33:58 -0800 Received: from nalasex01a.na.qualcomm.com (10.47.209.196) by nasanex01c.na.qualcomm.com (10.47.97.222) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.922.19; Wed, 26 Jan 2022 21:33:58 -0800 Received: from mpubbise-linux.qualcomm.com (10.80.80.8) by nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.922.19; Wed, 26 Jan 2022 21:33:55 -0800 From: Manikanta Pubbisetty To: CC: , Manikanta Pubbisetty Subject: [PATCH RFC 7/8] ath11k: Add multi TX ring support for WCN6750 Date: Thu, 27 Jan 2022 11:03:28 +0530 Message-ID: <1643261609-13500-8-git-send-email-quic_mpubbise@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1643261609-13500-1-git-send-email-quic_mpubbise@quicinc.com> References: <1643261609-13500-1-git-send-email-quic_mpubbise@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To nalasex01a.na.qualcomm.com (10.47.209.196) Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org Currently in the case of WCN6750, only one TCL ring is enabled for TX, all TX activity happens only on one ring, this is limiting the TX throughput in 160Mhz case, enabling mutliple TCL rings on WCN6750 has shown an improvement of nearly 300 Mbps in the case of TCP TX, therefore add the support of multi TX ring for WCN6750. Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.1.0.1-00573-QCAMSLSWPLZ-1 Signed-off-by: Manikanta Pubbisetty --- drivers/net/wireless/ath/ath11k/core.c | 11 ++- drivers/net/wireless/ath/ath11k/dp.c | 23 ++++--- drivers/net/wireless/ath/ath11k/dp.h | 2 + drivers/net/wireless/ath/ath11k/dp_tx.c | 14 ++-- drivers/net/wireless/ath/ath11k/hal.c | 4 +- drivers/net/wireless/ath/ath11k/hal.h | 4 +- drivers/net/wireless/ath/ath11k/hal_tx.c | 4 +- drivers/net/wireless/ath/ath11k/hal_tx.h | 2 + drivers/net/wireless/ath/ath11k/hw.c | 113 +++++++++++++++++++++++++++++-- drivers/net/wireless/ath/ath11k/hw.h | 12 ++++ 10 files changed, 160 insertions(+), 29 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index 161bddf..fa507a27 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -100,6 +100,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .fw_wmi_diag_event = false, .non_wow_suspend = false, .threaded_napi = false, + .tcl_wbm_map = ath11k_hw_tcl_wbm_ring_map_ipq8074, }, { .hw_rev = ATH11K_HW_IPQ6018_HW10, @@ -166,6 +167,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .fw_wmi_diag_event = false, .non_wow_suspend = false, .threaded_napi = false, + .tcl_wbm_map = ath11k_hw_tcl_wbm_ring_map_ipq8074, }, { .name = "qca6390 hw2.0", @@ -231,6 +233,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .fw_wmi_diag_event = true, .non_wow_suspend = false, .threaded_napi = false, + .tcl_wbm_map = ath11k_hw_tcl_wbm_ring_map_ipq8074, }, { .name = "qcn9074 hw1.0", @@ -296,6 +299,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .fw_wmi_diag_event = false, .non_wow_suspend = false, .threaded_napi = false, + .tcl_wbm_map = ath11k_hw_tcl_wbm_ring_map_ipq8074, }, { .name = "wcn6855 hw2.0", @@ -361,6 +365,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .fw_wmi_diag_event = true, .non_wow_suspend = false, .threaded_napi = false, + .tcl_wbm_map = ath11k_hw_tcl_wbm_ring_map_ipq8074, }, { .name = "wcn6855 hw2.1", @@ -425,6 +430,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .fw_wmi_diag_event = true, .non_wow_suspend = false, .threaded_napi = false, + .tcl_wbm_map = ath11k_hw_tcl_wbm_ring_map_ipq8074, }, { .name = "wcn6750 hw1.0", @@ -437,7 +443,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .max_radios = 1, .bdf_addr = 0x4B0C0000, .hw_ops = &wcn6750_ops, - .ring_mask = &ath11k_hw_ring_mask_qca6390, + .ring_mask = &ath11k_hw_ring_mask_wcn6750, .internal_sleep_clock = false, .regs = &wcn6750_regs, .qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_WCN6750, @@ -481,7 +487,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .supports_regdb = true, .fix_l1ss = true, .credit_flow = true, - .max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390, + .max_tx_ring = DP_TCL_NUM_RING_MAX, .hal_params = &ath11k_hw_hal_params_qca6390, .supports_dynamic_smps_6ghz = false, .alloc_cacheable_memory = false, @@ -489,6 +495,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .fw_wmi_diag_event = false, .non_wow_suspend = true, .threaded_napi = true, + .tcl_wbm_map = ath11k_hw_tcl_wbm_ring_map_wcn6750, }, }; diff --git a/drivers/net/wireless/ath/ath11k/dp.c b/drivers/net/wireless/ath/ath11k/dp.c index 8b790ce..c44b081 100644 --- a/drivers/net/wireless/ath/ath11k/dp.c +++ b/drivers/net/wireless/ath/ath11k/dp.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 @@ -131,13 +132,11 @@ static int ath11k_dp_srng_calculate_msi_group(struct ath11k_base *ab, switch (type) { case HAL_WBM2SW_RELEASE: - if (ring_num < 3) { - grp_mask = &ab->hw_params.ring_mask->tx[0]; - } else if (ring_num == 3) { + if (ring_num == DP_RX_RELEASE_RING_NUM) { grp_mask = &ab->hw_params.ring_mask->rx_wbm_rel[0]; ring_num = 0; } else { - return -ENOENT; + grp_mask = &ab->hw_params.ring_mask->tx[0]; } break; case HAL_REO_EXCEPTION: @@ -371,6 +370,7 @@ static int ath11k_dp_srng_common_setup(struct ath11k_base *ab) struct ath11k_dp *dp = &ab->dp; struct hal_srng *srng; int i, ret; + u8 tcl_num, wbm_num; ret = ath11k_dp_srng_setup(ab, &dp->wbm_desc_rel_ring, HAL_SW2WBM_RELEASE, 0, 0, @@ -396,8 +396,11 @@ static int ath11k_dp_srng_common_setup(struct ath11k_base *ab) } for (i = 0; i < ab->hw_params.max_tx_ring; i++) { + tcl_num = ab->hw_params.tcl_wbm_map[i].tcl_ring_num; + wbm_num = ab->hw_params.tcl_wbm_map[i].wbm_ring_num; + ret = ath11k_dp_srng_setup(ab, &dp->tx_ring[i].tcl_data_ring, - HAL_TCL_DATA, i, 0, + HAL_TCL_DATA, tcl_num, 0, DP_TCL_DATA_RING_SIZE); if (ret) { ath11k_warn(ab, "failed to set up tcl_data ring (%d) :%d\n", @@ -406,7 +409,7 @@ static int ath11k_dp_srng_common_setup(struct ath11k_base *ab) } ret = ath11k_dp_srng_setup(ab, &dp->tx_ring[i].tcl_comp_ring, - HAL_WBM2SW_RELEASE, i, 0, + HAL_WBM2SW_RELEASE, wbm_num, 0, DP_TX_COMP_RING_SIZE); if (ret) { ath11k_warn(ab, "failed to set up tcl_comp ring (%d) :%d\n", @@ -431,7 +434,7 @@ static int ath11k_dp_srng_common_setup(struct ath11k_base *ab) } ret = ath11k_dp_srng_setup(ab, &dp->rx_rel_ring, HAL_WBM2SW_RELEASE, - 3, 0, DP_RX_RELEASE_RING_SIZE); + DP_RX_RELEASE_RING_NUM, 0, DP_RX_RELEASE_RING_SIZE); if (ret) { ath11k_warn(ab, "failed to set up rx_rel ring :%d\n", ret); goto err; @@ -774,8 +777,10 @@ int ath11k_dp_service_srng(struct ath11k_base *ab, int i, j; int tot_work_done = 0; - if (ab->hw_params.ring_mask->tx[grp_id]) { - i = __fls(ab->hw_params.ring_mask->tx[grp_id]); + for (i = 0; i < ab->hw_params.max_tx_ring; i++) { + if (!(BIT(ab->hw_params.tcl_wbm_map[i].wbm_ring_num) & + ab->hw_params.ring_mask->tx[grp_id])) + continue; ath11k_dp_tx_completion_handler(ab, i); } diff --git a/drivers/net/wireless/ath/ath11k/dp.h b/drivers/net/wireless/ath/ath11k/dp.h index 9a30367..946510f 100644 --- a/drivers/net/wireless/ath/ath11k/dp.h +++ b/drivers/net/wireless/ath/ath11k/dp.h @@ -220,6 +220,8 @@ struct ath11k_pdev_dp { #define DP_RXDMA_MONITOR_DST_RING_SIZE 2048 #define DP_RXDMA_MONITOR_DESC_RING_SIZE 4096 +#define DP_RX_RELEASE_RING_NUM 3 + #define DP_RX_BUFFER_SIZE 2048 #define DP_RX_BUFFER_SIZE_LITE 1024 #define DP_RX_BUFFER_ALIGN_SIZE 128 diff --git a/drivers/net/wireless/ath/ath11k/dp_tx.c b/drivers/net/wireless/ath/ath11k/dp_tx.c index 91d6244..770bdc5 100644 --- a/drivers/net/wireless/ath/ath11k/dp_tx.c +++ b/drivers/net/wireless/ath/ath11k/dp_tx.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 "core.h" @@ -93,7 +94,8 @@ int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif, u8 pool_id; u8 hal_ring_id; int ret; - u8 ring_selector = 0, ring_map = 0; + u32 ring_selector = 0; + u8 ring_map = 0; bool tcl_ring_retry; if (unlikely(test_bit(ATH11K_FLAG_CRASH_FLUSH, &ar->ab->dev_flags))) @@ -105,19 +107,13 @@ int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif, pool_id = skb_get_queue_mapping(skb) & (ATH11K_HW_MAX_QUEUES - 1); - /* Let the default ring selection be based on current processor - * number, where one of the 3 tcl rings are selected based on - * the smp_processor_id(). In case that ring - * is full/busy, we resort to other available rings. - * If all rings are full, we drop the packet. - * //TODO Add throttling logic when all rings are full - */ - ring_selector = smp_processor_id(); + ring_selector = ab->hw_params.hw_ops->get_ring_selector(skb); tcl_ring_sel: tcl_ring_retry = false; ti.ring_id = ring_selector % ab->hw_params.max_tx_ring; + ti.rbm_id = ab->hw_params.tcl_wbm_map[ti.ring_id].rbm_id; ring_map |= BIT(ti.ring_id); diff --git a/drivers/net/wireless/ath/ath11k/hal.c b/drivers/net/wireless/ath/ath11k/hal.c index 9a6340d..92038c5 100644 --- a/drivers/net/wireless/ath/ath11k/hal.c +++ b/drivers/net/wireless/ath/ath11k/hal.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. - * Copyright (c) 2021, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved. */ #include #include "hal_tx.h" @@ -126,7 +126,7 @@ static const struct hal_srng_config hw_srng_config_template[] = { }, { /* WBM2SW_RELEASE */ .start_ring_id = HAL_SRNG_RING_ID_WBM2SW0_RELEASE, - .max_rings = 4, + .max_rings = 5, .entry_size = sizeof(struct hal_wbm_release_ring) >> 2, .lmac_ring = false, .ring_dir = HAL_SRNG_DIR_DST, diff --git a/drivers/net/wireless/ath/ath11k/hal.h b/drivers/net/wireless/ath/ath11k/hal.h index 347d456..f1b6336 100644 --- a/drivers/net/wireless/ath/ath11k/hal.h +++ b/drivers/net/wireless/ath/ath11k/hal.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. - * Copyright (c) 2021, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef ATH11K_HAL_H @@ -389,6 +389,7 @@ enum hal_srng_ring_id { HAL_SRNG_RING_ID_WBM2SW1_RELEASE, HAL_SRNG_RING_ID_WBM2SW2_RELEASE, HAL_SRNG_RING_ID_WBM2SW3_RELEASE, + HAL_SRNG_RING_ID_WBM2SW4_RELEASE, HAL_SRNG_RING_ID_UMAC_ID_END = 127, HAL_SRNG_RING_ID_LMAC1_ID_START, @@ -678,6 +679,7 @@ enum hal_rx_buf_return_buf_manager { HAL_RX_BUF_RBM_SW1_BM, HAL_RX_BUF_RBM_SW2_BM, HAL_RX_BUF_RBM_SW3_BM, + HAL_RX_BUF_RBM_SW4_BM, }; #define HAL_SRNG_DESC_LOOP_CNT 0xf0000000 diff --git a/drivers/net/wireless/ath/ath11k/hal_tx.c b/drivers/net/wireless/ath/ath11k/hal_tx.c index c8929de..d1b0e36 100644 --- a/drivers/net/wireless/ath/ath11k/hal_tx.c +++ b/drivers/net/wireless/ath/ath11k/hal_tx.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 "hal_desc.h" @@ -44,8 +45,7 @@ void ath11k_hal_tx_cmd_desc_setup(struct ath11k_base *ab, void *cmd, FIELD_PREP(BUFFER_ADDR_INFO1_ADDR, ((uint64_t)ti->paddr >> HAL_ADDR_MSB_REG_SHIFT)); tcl_cmd->buf_addr_info.info1 |= - FIELD_PREP(BUFFER_ADDR_INFO1_RET_BUF_MGR, - (ti->ring_id + HAL_RX_BUF_RBM_SW0_BM)) | + FIELD_PREP(BUFFER_ADDR_INFO1_RET_BUF_MGR, ti->rbm_id) | FIELD_PREP(BUFFER_ADDR_INFO1_SW_COOKIE, ti->desc_id); tcl_cmd->info0 = diff --git a/drivers/net/wireless/ath/ath11k/hal_tx.h b/drivers/net/wireless/ath/ath11k/hal_tx.h index 36f4f6f..c5e8836 100644 --- a/drivers/net/wireless/ath/ath11k/hal_tx.h +++ b/drivers/net/wireless/ath/ath11k/hal_tx.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 ATH11K_HAL_TX_H @@ -35,6 +36,7 @@ struct hal_tx_info { u8 lmac_id; u8 dscp_tid_tbl_idx; bool enable_mesh; + u8 rbm_id; }; /* TODO: Check if the actual desc macros can be used instead */ diff --git a/drivers/net/wireless/ath/ath11k/hw.c b/drivers/net/wireless/ath/ath11k/hw.c index c19f9101..4d3c433 100644 --- a/drivers/net/wireless/ath/ath11k/hw.c +++ b/drivers/net/wireless/ath/ath11k/hw.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved. - * Copyright (c) 2021, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -814,6 +814,30 @@ static u16 ath11k_hw_wcn6855_mpdu_info_get_peerid(u8 *tlv_data) return peer_id; } +static u32 ath11k_hw_ipq8074_get_tcl_ring_selector(struct sk_buff *skb) +{ + /* Let the default ring selection be based on current processor + * number, where one of the 3 tcl rings are selected based on + * the smp_processor_id(). In case that ring + * is full/busy, we resort to other available rings. + * If all rings are full, we drop the packet. + * //TODO Add throttling logic when all rings are full + */ + return smp_processor_id(); +} + +static u32 ath11k_hw_wcn6750_get_tcl_ring_selector(struct sk_buff *skb) +{ + /* Select the TCL ring based on the flow hash of the SKB, + * since applications pumping the traffic can be scheduled + * on multiple CPUs, there is a chance that packets of the + * same flow could end on different TCL rings, this could + * sometimes results in an out of order arrival of the + * packets at the receiver. + */ + return skb_get_hash(skb); +} + const struct ath11k_hw_ops ipq8074_ops = { .get_hw_mac_from_pdev_id = ath11k_hw_ipq8074_mac_from_pdev_id, .wmi_init_config = ath11k_init_wmi_config_ipq8074, @@ -851,6 +875,7 @@ const struct ath11k_hw_ops ipq8074_ops = { .mpdu_info_get_peerid = ath11k_hw_ipq8074_mpdu_info_get_peerid, .rx_desc_mac_addr2_valid = ath11k_hw_ipq8074_rx_desc_mac_addr2_valid, .rx_desc_mpdu_start_addr2 = ath11k_hw_ipq8074_rx_desc_mpdu_start_addr2, + .get_ring_selector = ath11k_hw_ipq8074_get_tcl_ring_selector, }; const struct ath11k_hw_ops ipq6018_ops = { @@ -890,6 +915,7 @@ const struct ath11k_hw_ops ipq6018_ops = { .mpdu_info_get_peerid = ath11k_hw_ipq8074_mpdu_info_get_peerid, .rx_desc_mac_addr2_valid = ath11k_hw_ipq8074_rx_desc_mac_addr2_valid, .rx_desc_mpdu_start_addr2 = ath11k_hw_ipq8074_rx_desc_mpdu_start_addr2, + .get_ring_selector = ath11k_hw_ipq8074_get_tcl_ring_selector, }; const struct ath11k_hw_ops qca6390_ops = { @@ -929,6 +955,7 @@ const struct ath11k_hw_ops qca6390_ops = { .mpdu_info_get_peerid = ath11k_hw_ipq8074_mpdu_info_get_peerid, .rx_desc_mac_addr2_valid = ath11k_hw_ipq8074_rx_desc_mac_addr2_valid, .rx_desc_mpdu_start_addr2 = ath11k_hw_ipq8074_rx_desc_mpdu_start_addr2, + .get_ring_selector = ath11k_hw_ipq8074_get_tcl_ring_selector, }; const struct ath11k_hw_ops qcn9074_ops = { @@ -968,6 +995,7 @@ const struct ath11k_hw_ops qcn9074_ops = { .mpdu_info_get_peerid = ath11k_hw_ipq8074_mpdu_info_get_peerid, .rx_desc_mac_addr2_valid = ath11k_hw_ipq9074_rx_desc_mac_addr2_valid, .rx_desc_mpdu_start_addr2 = ath11k_hw_ipq9074_rx_desc_mpdu_start_addr2, + .get_ring_selector = ath11k_hw_ipq8074_get_tcl_ring_selector, }; const struct ath11k_hw_ops wcn6855_ops = { @@ -1006,6 +1034,7 @@ const struct ath11k_hw_ops wcn6855_ops = { .mpdu_info_get_peerid = ath11k_hw_wcn6855_mpdu_info_get_peerid, .rx_desc_mac_addr2_valid = ath11k_hw_wcn6855_rx_desc_mac_addr2_valid, .rx_desc_mpdu_start_addr2 = ath11k_hw_wcn6855_rx_desc_mpdu_start_addr2, + .get_ring_selector = ath11k_hw_ipq8074_get_tcl_ring_selector, }; const struct ath11k_hw_ops wcn6750_ops = { @@ -1044,11 +1073,14 @@ const struct ath11k_hw_ops wcn6750_ops = { .mpdu_info_get_peerid = ath11k_hw_ipq8074_mpdu_info_get_peerid, .rx_desc_mac_addr2_valid = ath11k_hw_ipq9074_rx_desc_mac_addr2_valid, .rx_desc_mpdu_start_addr2 = ath11k_hw_ipq9074_rx_desc_mpdu_start_addr2, + .get_ring_selector = ath11k_hw_wcn6750_get_tcl_ring_selector, }; -#define ATH11K_TX_RING_MASK_0 0x1 -#define ATH11K_TX_RING_MASK_1 0x2 -#define ATH11K_TX_RING_MASK_2 0x4 +#define ATH11K_TX_RING_MASK_0 BIT(0) +#define ATH11K_TX_RING_MASK_1 BIT(1) +#define ATH11K_TX_RING_MASK_2 BIT(2) +#define ATH11K_TX_RING_MASK_3 BIT(3) +#define ATH11K_TX_RING_MASK_4 BIT(4) #define ATH11K_RX_RING_MASK_0 0x1 #define ATH11K_RX_RING_MASK_1 0x2 @@ -1895,6 +1927,43 @@ const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_qcn9074 = { }, }; +const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_wcn6750 = { + .tx = { + ATH11K_TX_RING_MASK_0, + 0, + ATH11K_TX_RING_MASK_2, + 0, + ATH11K_TX_RING_MASK_4, + }, + .rx_mon_status = { + 0, 0, 0, 0, 0, 0, + ATH11K_RX_MON_STATUS_RING_MASK_0, + }, + .rx = { + 0, 0, 0, 0, 0, 0, 0, + ATH11K_RX_RING_MASK_0, + ATH11K_RX_RING_MASK_1, + ATH11K_RX_RING_MASK_2, + ATH11K_RX_RING_MASK_3, + }, + .rx_err = { + 0, ATH11K_RX_ERR_RING_MASK_0, + }, + .rx_wbm_rel = { + 0, ATH11K_RX_WBM_REL_RING_MASK_0, + }, + .reo_status = { + 0, ATH11K_REO_STATUS_RING_MASK_0, + }, + .rxdma2host = { + ATH11K_RXDMA2HOST_RING_MASK_0, + ATH11K_RXDMA2HOST_RING_MASK_1, + ATH11K_RXDMA2HOST_RING_MASK_2, + }, + .host2rxdma = { + }, +}; + const struct ath11k_hw_regs ipq8074_regs = { /* SW2TCL(x) R0 ring configuration address */ .hal_tcl1_ring_base_lsb = 0x00000510, @@ -2318,3 +2387,39 @@ const struct ath11k_hw_hal_params ath11k_hw_hal_params_ipq8074 = { const struct ath11k_hw_hal_params ath11k_hw_hal_params_qca6390 = { .rx_buf_rbm = HAL_RX_BUF_RBM_SW1_BM, }; + +const struct ath11k_hw_tcl_wbm_ring_map ath11k_hw_tcl_wbm_ring_map_ipq8074[] = { + { + .tcl_ring_num = 0, + .wbm_ring_num = 0, + .rbm_id = HAL_RX_BUF_RBM_SW0_BM, + }, + { + .tcl_ring_num = 1, + .wbm_ring_num = 1, + .rbm_id = HAL_RX_BUF_RBM_SW1_BM, + }, + { + .tcl_ring_num = 2, + .wbm_ring_num = 2, + .rbm_id = HAL_RX_BUF_RBM_SW2_BM, + }, +}; + +const struct ath11k_hw_tcl_wbm_ring_map ath11k_hw_tcl_wbm_ring_map_wcn6750[] = { + { + .tcl_ring_num = 0, + .wbm_ring_num = 0, + .rbm_id = HAL_RX_BUF_RBM_SW0_BM, + }, + { + .tcl_ring_num = 1, + .wbm_ring_num = 4, + .rbm_id = HAL_RX_BUF_RBM_SW4_BM, + }, + { + .tcl_ring_num = 2, + .wbm_ring_num = 2, + .rbm_id = HAL_RX_BUF_RBM_SW2_BM, + }, +}; diff --git a/drivers/net/wireless/ath/ath11k/hw.h b/drivers/net/wireless/ath/ath11k/hw.h index d33b9b7..f7c6ad5 100644 --- a/drivers/net/wireless/ath/ath11k/hw.h +++ b/drivers/net/wireless/ath/ath11k/hw.h @@ -126,6 +126,12 @@ struct ath11k_hw_hal_params { enum hal_rx_buf_return_buf_manager rx_buf_rbm; }; +struct ath11k_hw_tcl_wbm_ring_map { + u8 tcl_ring_num; + u8 wbm_ring_num; + u8 rbm_id; +}; + struct ath11k_hw_params { const char *name; u16 hw_rev; @@ -195,6 +201,7 @@ struct ath11k_hw_params { bool non_wow_suspend; bool cold_boot_fw_restart; bool threaded_napi; + const struct ath11k_hw_tcl_wbm_ring_map *tcl_wbm_map; }; struct ath11k_hw_ops { @@ -237,6 +244,7 @@ struct ath11k_hw_ops { u16 (*mpdu_info_get_peerid)(u8 *tlv_data); bool (*rx_desc_mac_addr2_valid)(struct hal_rx_desc *desc); u8* (*rx_desc_mpdu_start_addr2)(struct hal_rx_desc *desc); + u32 (*get_ring_selector)(struct sk_buff *skb); }; extern const struct ath11k_hw_ops ipq8074_ops; @@ -249,10 +257,14 @@ extern const struct ath11k_hw_ops wcn6750_ops; extern const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_ipq8074; extern const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_qca6390; extern const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_qcn9074; +extern const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_wcn6750; extern const struct ath11k_hw_hal_params ath11k_hw_hal_params_ipq8074; extern const struct ath11k_hw_hal_params ath11k_hw_hal_params_qca6390; +extern const struct ath11k_hw_tcl_wbm_ring_map ath11k_hw_tcl_wbm_ring_map_ipq8074[]; +extern const struct ath11k_hw_tcl_wbm_ring_map ath11k_hw_tcl_wbm_ring_map_wcn6750[]; + static inline int ath11k_hw_get_mac_from_pdev_id(struct ath11k_hw_params *hw, int pdev_idx) From patchwork Thu Jan 27 05:33:29 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manikanta Pubbisetty X-Patchwork-Id: 12726298 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9CE02C433F5 for ; Thu, 27 Jan 2022 05:34:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236287AbiA0FeC (ORCPT ); Thu, 27 Jan 2022 00:34:02 -0500 Received: from alexa-out-sd-02.qualcomm.com ([199.106.114.39]:2556 "EHLO alexa-out-sd-02.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236295AbiA0FeA (ORCPT ); Thu, 27 Jan 2022 00:34:00 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1643261640; x=1674797640; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version; bh=C9hybfjz3O5SrsNPjxfvX3x7M20YzPYpPTsIwWwHwLQ=; b=Agh0k5NqoIcoKScBYBc4JG0TeYY1oD9v/i3Y2DIG5aMYSDaCiOIja7vM 9oPwzrmY7elpym+iVg6xbBpNGMcIL+z67qssKuT5WSDo3QSLVerupReaI Jv7M2wxMMDUfjSyEMiBCvlPR+IRbDmdsD6VLwW/DwrSyOUmd7FyRP9CKo o=; Received: from unknown (HELO ironmsg-SD-alpha.qualcomm.com) ([10.53.140.30]) by alexa-out-sd-02.qualcomm.com with ESMTP; 26 Jan 2022 21:34:00 -0800 X-QCInternal: smtphost Received: from nasanex01c.na.qualcomm.com ([10.47.97.222]) by ironmsg-SD-alpha.qualcomm.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Jan 2022 21:34:00 -0800 Received: from nalasex01a.na.qualcomm.com (10.47.209.196) by nasanex01c.na.qualcomm.com (10.47.97.222) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.922.19; Wed, 26 Jan 2022 21:34:00 -0800 Received: from mpubbise-linux.qualcomm.com (10.80.80.8) by nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.922.19; Wed, 26 Jan 2022 21:33:57 -0800 From: Manikanta Pubbisetty To: CC: , Manikanta Pubbisetty Subject: [PATCH RFC 8/8] ath11k: Add Coredump support of MSA region for WCN6750 Date: Thu, 27 Jan 2022 11:03:29 +0530 Message-ID: <1643261609-13500-9-git-send-email-quic_mpubbise@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1643261609-13500-1-git-send-email-quic_mpubbise@quicinc.com> References: <1643261609-13500-1-git-send-email-quic_mpubbise@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To nalasex01a.na.qualcomm.com (10.47.209.196) Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org In the context of WCN6750, MSA is a 12MB reserved memory region entirely used by WCN6750 firmware for it's operation. This memory carries useful information required to debug firmware/hardware issues. Therefore add coredump support to dump MSA region during FW assert for WCN6750. Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.1.0.1-00573-QCAMSLSWPLZ-1 Signed-off-by: Manikanta Pubbisetty --- drivers/net/wireless/ath/ath11k/Kconfig | 1 + drivers/net/wireless/ath/ath11k/Makefile | 1 + drivers/net/wireless/ath/ath11k/ahb.c | 85 ++++++++++++++++++++++++++++- drivers/net/wireless/ath/ath11k/ahb.h | 8 ++- drivers/net/wireless/ath/ath11k/coredump.c | 87 ++++++++++++++++++++++++++++++ drivers/net/wireless/ath/ath11k/coredump.h | 71 ++++++++++++++++++++++++ 6 files changed, 251 insertions(+), 2 deletions(-) create mode 100644 drivers/net/wireless/ath/ath11k/coredump.c create mode 100644 drivers/net/wireless/ath/ath11k/coredump.h diff --git a/drivers/net/wireless/ath/ath11k/Kconfig b/drivers/net/wireless/ath/ath11k/Kconfig index ad5cc6c..96074f5 100644 --- a/drivers/net/wireless/ath/ath11k/Kconfig +++ b/drivers/net/wireless/ath/ath11k/Kconfig @@ -5,6 +5,7 @@ config ATH11K depends on CRYPTO_MICHAEL_MIC select ATH_COMMON select QCOM_QMI_HELPERS + select WANT_DEV_COREDUMP help This module adds support for Qualcomm Technologies 802.11ax family of chipsets. diff --git a/drivers/net/wireless/ath/ath11k/Makefile b/drivers/net/wireless/ath/ath11k/Makefile index e3ea6a2..ec3c394 100644 --- a/drivers/net/wireless/ath/ath11k/Makefile +++ b/drivers/net/wireless/ath/ath11k/Makefile @@ -24,6 +24,7 @@ ath11k-$(CONFIG_NL80211_TESTMODE) += testmode.o ath11k-$(CONFIG_ATH11K_TRACING) += trace.o ath11k-$(CONFIG_THERMAL) += thermal.o ath11k-$(CONFIG_ATH11K_SPECTRAL) += spectral.o +ath11k-$(CONFIG_DEV_COREDUMP) += coredump.o obj-$(CONFIG_ATH11K_AHB) += ath11k_ahb.o ath11k_ahb-y += ahb.o pci_cmn.o diff --git a/drivers/net/wireless/ath/ath11k/ahb.c b/drivers/net/wireless/ath/ath11k/ahb.c index fd3bb43..83b1da8 100644 --- a/drivers/net/wireless/ath/ath11k/ahb.c +++ b/drivers/net/wireless/ath/ath11k/ahb.c @@ -15,7 +15,9 @@ #include "debug.h" #include "hif.h" #include +#include #include "pci_cmn.h" +#include "coredump.h" static const struct of_device_id ath11k_ahb_of_match[] = { /* TODO: Should we change the compatible string to something similar @@ -777,6 +779,74 @@ static int ath11k_ahb_setup_resources(struct ath11k_base *ab) return 0; } +static void ath11k_ahb_coredump_msa(struct ath11k_base *ab) +{ + struct ath11k_ahb *ab_ahb = ath11k_ahb_priv(ab); + struct ath11k_msa_dump msa_data; + + msa_data.paddr = ab_ahb->fw.msa_paddr; + msa_data.vaddr = ab_ahb->fw.msa_vaddr; + msa_data.size = ab_ahb->fw.msa_size; + + ath11k_coredump_msa(ab, &msa_data); +} + +static int ath11k_ahb_ssr_notifier(struct notifier_block *nb, + unsigned long action, void *data) +{ + struct ath11k_ahb *ab_ahb = container_of(nb, struct ath11k_ahb, nb); + struct ath11k_base *ab = ab_ahb->ab; + struct qcom_ssr_notify_data *notify_data = data; + + switch (action) { + case QCOM_SSR_BEFORE_POWERUP: + break; + case QCOM_SSR_AFTER_POWERUP: + break; + case QCOM_SSR_BEFORE_SHUTDOWN: + if (notify_data->crashed) + ath11k_ahb_coredump_msa(ab); + break; + case QCOM_SSR_AFTER_SHUTDOWN: + break; + default: + ath11k_err(ab, "received unrecognized event %lu\n", action); + break; + } + + return NOTIFY_OK; +} + +static int ath11k_ahb_register_ssr_notifier(struct ath11k_base *ab) +{ + struct ath11k_ahb *ab_ahb = ath11k_ahb_priv(ab); + void *notifier; + int ret; + + ab_ahb->nb.notifier_call = ath11k_ahb_ssr_notifier; + + notifier = qcom_register_ssr_notifier("wpss", &ab_ahb->nb); + if (IS_ERR(notifier)) { + ret = PTR_ERR(notifier); + ath11k_err(ab, "failed to initialize SSR notifier: %d\n", ret); + return ret; + } + + ab_ahb->notifier = notifier; + + return 0; +} + +static void ath11k_ahb_unregister_ssr_notifier(struct ath11k_base *ab) +{ + struct ath11k_ahb *ab_ahb = ath11k_ahb_priv(ab); + int ret; + + ret = qcom_unregister_ssr_notifier(ab_ahb->notifier, &ab_ahb->nb); + if (ret) + ath11k_err(ab, "error %d unregistering notifier\n", ret); +} + static int ath11k_ahb_setup_msa_resources(struct ath11k_base *ab) { struct ath11k_ahb *ab_ahb = ath11k_ahb_priv(ab); @@ -798,6 +868,14 @@ static int ath11k_ahb_setup_msa_resources(struct ath11k_base *ab) ab_ahb->fw.msa_paddr = r.start; ab_ahb->fw.msa_size = resource_size(&r); + ab_ahb->fw.msa_vaddr = devm_memremap(dev, ab_ahb->fw.msa_paddr, + ab_ahb->fw.msa_size, + MEMREMAP_WT); + if (IS_ERR(ab_ahb->fw.msa_vaddr)) { + dev_err(dev, "failed to map memory region: %pa\n", + &r.start); + return PTR_ERR(ab_ahb->fw.msa_vaddr); + } node = of_parse_phandle(dev->of_node, "memory-region", 1); if (!node) @@ -813,7 +891,7 @@ static int ath11k_ahb_setup_msa_resources(struct ath11k_base *ab) ab_ahb->fw.ce_paddr = r.start; ab_ahb->fw.ce_size = resource_size(&r); - return 0; + return ath11k_ahb_register_ssr_notifier(ab); } static int ath11k_ahb_fw_resources_init(struct ath11k_base *ab) @@ -917,6 +995,8 @@ static int ath11k_ahb_fw_resource_deinit(struct ath11k_base *ab) if (ab_ahb->fw.use_tz) return 0; + ath11k_ahb_unregister_ssr_notifier(ab); + iommu = ab_ahb->fw.iommu_domain; unmapped_size = iommu_unmap(iommu, ab_ahb->fw.msa_paddr, ab_ahb->fw.msa_size); @@ -940,6 +1020,7 @@ static int ath11k_ahb_fw_resource_deinit(struct ath11k_base *ab) static int ath11k_ahb_probe(struct platform_device *pdev) { struct ath11k_base *ab; + struct ath11k_ahb *ab_ahb; const struct of_device_id *of_id; const struct ath11k_bus_params *bus_params; const struct ath11k_hif_ops *hif_ops; @@ -986,6 +1067,8 @@ static int ath11k_ahb_probe(struct platform_device *pdev) ab->pdev = pdev; ab->hw_rev = hw_rev; platform_set_drvdata(pdev, ab); + ab_ahb = ath11k_ahb_priv(ab); + ab_ahb->ab = ab; ret = ath11k_ahb_setup_resources(ab); if (ret) diff --git a/drivers/net/wireless/ath/ath11k/ahb.h b/drivers/net/wireless/ath/ath11k/ahb.h index 4c7872d..efb72eb 100644 --- a/drivers/net/wireless/ath/ath11k/ahb.h +++ b/drivers/net/wireless/ath/ath11k/ahb.h @@ -1,11 +1,12 @@ /* SPDX-License-Identifier: BSD-3-Clause-Clear */ /* * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. - * Copyright (c) 2021, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef ATH11K_AHB_H #define ATH11K_AHB_H +#include #include "core.h" #define ATH11K_AHB_RECOVERY_TIMEOUT (3 * HZ) @@ -13,15 +14,20 @@ struct ath11k_base; struct ath11k_ahb { struct rproc *tgt_rproc; + struct ath11k_base *ab; struct { struct device *dev; struct iommu_domain *iommu_domain; dma_addr_t msa_paddr; u32 msa_size; + void *msa_vaddr; dma_addr_t ce_paddr; u32 ce_size; bool use_tz; } fw; + + struct notifier_block nb; + void *notifier; }; static inline struct ath11k_ahb *ath11k_ahb_priv(struct ath11k_base *ab) diff --git a/drivers/net/wireless/ath/ath11k/coredump.c b/drivers/net/wireless/ath/ath11k/coredump.c new file mode 100644 index 0000000..247ac26 --- /dev/null +++ b/drivers/net/wireless/ath/ath11k/coredump.c @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: BSD-3-Clause-Clear +/* + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include "core.h" +#include "coredump.h" +#include "debug.h" + +static void ath11k_coredump_update_hdr(struct ath11k_base *ab, + struct ath11k_dump_file_data *file_data, + size_t header_size) +{ + struct timespec64 timestamp; + + strscpy(file_data->df_magic, "ATH11K-FW-DUMP", + sizeof(file_data->df_magic)); + file_data->len = cpu_to_le32(header_size); + file_data->version = cpu_to_le32(ATH11K_FW_CRASH_DUMP_VERSION); + guid_gen(&file_data->guid); + ktime_get_real_ts64(×tamp); + file_data->tv_sec = cpu_to_le64(timestamp.tv_sec); + file_data->tv_nsec = cpu_to_le64(timestamp.tv_nsec); +} + +void ath11k_coredump_msa(struct ath11k_base *ab, + struct ath11k_msa_dump *msa_data) +{ + struct ath11k_dump_segment *segment; + struct ath11k_dump_file_data *file_data; + size_t header_size; + int ret; + u8 *buf, *dump; + + segment = vzalloc(sizeof(*segment)); + if (!segment) + return; + + header_size = sizeof(struct ath11k_dump_file_data); + header_size += sizeof(*segment); + header_size = PAGE_ALIGN(header_size); + buf = vzalloc(header_size); + if (!buf) { + vfree(segment); + return; + } + + file_data = (struct ath11k_dump_file_data *)buf; + + ath11k_coredump_update_hdr(ab, file_data, header_size); + + file_data->num_seg = cpu_to_le32(1); + file_data->seg_size = cpu_to_le32(sizeof(*segment)); + + /* copy segment details to file */ + buf += offsetof(struct ath11k_dump_file_data, seg); + file_data->seg = (struct ath11k_dump_segment *)buf; + + segment->addr = msa_data->paddr; + segment->vaddr = msa_data->vaddr; + segment->len = msa_data->size; + segment->type = ATH11K_FW_MSA_DUMP_DATA; + + memcpy(file_data->seg, segment, sizeof(*segment)); + + dump = vzalloc(header_size + segment->len); + if (!dump) { + ret = -ENOMEM; + ath11k_err(ab, "failed to allocate memory for msa dump %d\n", ret); + goto err_alloc_fail; + } + + memcpy(dump, (void *)file_data, header_size); + memcpy(dump + header_size, segment->vaddr, segment->len); + + dev_coredumpv(ab->dev, dump, header_size + segment->len, + GFP_KERNEL); +err_alloc_fail: + vfree(file_data); + vfree(segment); +} +EXPORT_SYMBOL(ath11k_coredump_msa); diff --git a/drivers/net/wireless/ath/ath11k/coredump.h b/drivers/net/wireless/ath/ath11k/coredump.h new file mode 100644 index 0000000..ad7ecf2 --- /dev/null +++ b/drivers/net/wireless/ath/ath11k/coredump.h @@ -0,0 +1,71 @@ +/* SPDX-License-Identifier: BSD-3-Clause-Clear + * + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef _COREDUMP_H_ +#define _COREDUMP_H_ + +#define ATH11K_FW_CRASH_DUMP_VERSION 1 + +enum ath11k_fw_crash_dump_type { + ATH11K_FW_MSA_DUMP_DATA, + ATH11K_FW_CRASH_DUMP_MAX, +}; + +struct ath11k_dump_segment { + unsigned long addr; + u32 *vaddr; + unsigned int len; + unsigned int type; +}; + +struct ath11k_dump_file_data { + /* "ATH11K-FW-DUMP" */ + char df_magic[16]; + __le32 len; + /* file dump version */ + __le32 version; + /* pci device id */ + __le32 chip_id; + guid_t guid; + /* time-of-day stamp */ + __le64 tv_sec; + /* time-of-day stamp, nano-seconds */ + __le64 tv_nsec; + /* room for growth w/out changing binary format */ + u8 unused[8]; + /* number of segments */ + __le32 num_seg; + /* ath11k_dump_segment struct size */ + __le32 seg_size; + + struct ath11k_dump_segment *seg; + /* struct ath11k_dump_segment + more */ + + u8 data[]; +} __packed; + +struct ath11k_coredump_state { + struct ath11k_dump_file_data *header; + struct ath11k_dump_segment *segments; + u32 num_seg; +}; + +struct ath11k_msa_dump { + u64 paddr; + u32 *vaddr; + u64 size; +}; + +#ifdef CONFIG_DEV_COREDUMP +void ath11k_coredump_msa(struct ath11k_base *ab, + struct ath11k_msa_dump *msa_data); +#else +static inline void +ath11k_coredump_msa(struct ath11k_base *ab, + struct ath11k_msa_dump *msa_data) +{ +} +#endif /* CONFIG_DEV_COREDUMP */ +#endif /* _COREDUMP_H_ */