diff mbox series

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

Message ID 20201204152013.195139-18-vicamo.yang@canonical.com
State New
Headers show
Series UBUNTU: SAUCE: Support Killer 500s (QCA6390) WLAN/BT | expand

Commit Message

You-Sheng Yang Dec. 4, 2020, 3:20 p.m. UTC
From: Carl Huang <cjhuang@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@codeaurora.org>
Signed-off-by: Kalle Valo <kvalo@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@canonical.com>
---
 drivers/net/wireless/ath/ath11k/pci.c | 17 +++++++++++++++++
 drivers/net/wireless/ath/ath11k/pci.h |  2 ++
 2 files changed, 19 insertions(+)
diff mbox series

Patch

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)