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: 538241 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: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: 538240 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: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: 538239 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: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: 538238 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)