[PATCH 17/26][SRU][U/OEM-5.10] UBUNTU: SAUCE: ath11k: disable ASPM L0sLs before downloading firmware

You-Sheng Yang vicamo.yang at canonical.com
Fri Dec 4 15:20:03 UTC 2020


From: Carl Huang <cjhuang at codeaurora.org>

BugLink: https://bugs.launchpad.net/bugs/1879633

Sometimes target doesn't switch to amss state as device enters
L1ss state, so disable L0sL1s during firmware downloading.
Driver recovers the ASPM to default value in start callback
or powerdown callback.

Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1

Signed-off-by: Carl Huang <cjhuang at codeaurora.org>
Signed-off-by: Kalle Valo <kvalo at codeaurora.org>
(cherry picked from commit 8bd374e3305359ca0be9fe88e8a1edc1abd537eb
https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git)
Signed-off-by: You-Sheng Yang <vicamo.yang at canonical.com>
---
 drivers/net/wireless/ath/ath11k/pci.c | 17 +++++++++++++++++
 drivers/net/wireless/ath/ath11k/pci.h |  2 ++
 2 files changed, 19 insertions(+)

diff --git a/drivers/net/wireless/ath/ath11k/pci.c b/drivers/net/wireless/ath/ath11k/pci.c
index c058c6e9db43..7e39fe157df3 100644
--- a/drivers/net/wireless/ath/ath11k/pci.c
+++ b/drivers/net/wireless/ath/ath11k/pci.c
@@ -998,6 +998,11 @@ static int ath11k_pci_power_up(struct ath11k_base *ab)
 	clear_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags);
 	ath11k_pci_sw_reset(ab_pci->ab, true);
 
+	/* disable L0sL1, write 0x40 to link_ctrl */
+	pci_read_config_byte(ab_pci->pdev, 0x80, &ab_pci->aspm);
+	pci_write_config_byte(ab_pci->pdev, 0x80, ab_pci->aspm & 0xfc);
+	ab_pci->restore_aspm = true;
+
 	ret = ath11k_mhi_start(ab_pci);
 	if (ret) {
 		ath11k_err(ab, "failed to start mhi: %d\n", ret);
@@ -1011,6 +1016,12 @@ static void ath11k_pci_power_down(struct ath11k_base *ab)
 {
 	struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);
 
+	/* recover aspm */
+	if (ab_pci->restore_aspm) {
+		pci_write_config_byte(ab_pci->pdev, 0x80, ab_pci->aspm);
+		ab_pci->restore_aspm = false;
+	}
+
 	ath11k_pci_force_wake(ab_pci->ab);
 	ath11k_mhi_stop(ab_pci);
 	clear_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags);
@@ -1073,6 +1084,12 @@ static int ath11k_pci_start(struct ath11k_base *ab)
 
 	set_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags);
 
+	/* recover aspm */
+	if (ab_pci->restore_aspm) {
+		pci_write_config_byte(ab_pci->pdev, 0x80, ab_pci->aspm);
+		ab_pci->restore_aspm = false;
+	}
+
 	ath11k_pci_ce_irqs_enable(ab);
 	ath11k_ce_rx_post_buf(ab);
 
diff --git a/drivers/net/wireless/ath/ath11k/pci.h b/drivers/net/wireless/ath/ath11k/pci.h
index 2125cdfaa334..edf6d2e6f088 100644
--- a/drivers/net/wireless/ath/ath11k/pci.h
+++ b/drivers/net/wireless/ath/ath11k/pci.h
@@ -82,6 +82,8 @@ struct ath11k_pci {
 
 	/* enum ath11k_pci_flags */
 	unsigned long flags;
+	u8 aspm;
+	bool restore_aspm;
 };
 
 static inline struct ath11k_pci *ath11k_pci_priv(struct ath11k_base *ab)
-- 
2.29.2




More information about the kernel-team mailing list