summaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorIlpo Järvinen <ilpo.jarvinen@linux.intel.com>2023-07-17 15:05:01 +0300
committerBjorn Helgaas <bhelgaas@google.com>2023-08-21 14:11:51 -0500
commitf5a7ac118faf6d4f794975947b3300717eae8fc5 (patch)
treeffcea0d2c73f16df731f94a6e96908f50b964236 /drivers/net
parent6c1b6bdb34aaf8f94f65a9cae1d63490320c11bc (diff)
downloadlinux-stable-f5a7ac118faf6d4f794975947b3300717eae8fc5.tar.gz
linux-stable-f5a7ac118faf6d4f794975947b3300717eae8fc5.tar.bz2
linux-stable-f5a7ac118faf6d4f794975947b3300717eae8fc5.zip
wifi: ath12k: Use RMW accessors for changing LNKCTL
Don't assume that only the driver would be accessing LNKCTL. ASPM policy changes can trigger write to LNKCTL outside of driver's control. Use RMW capability accessors which do proper locking to avoid losing concurrent updates to the register value. On restore, clear the ASPMC field properly. Suggested-by: Lukas Wunner <lukas@wunner.de> Fixes: d889913205cf ("wifi: ath12k: driver for Qualcomm Wi-Fi 7 devices") Link: https://lore.kernel.org/r/20230717120503.15276-10-ilpo.jarvinen@linux.intel.com Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Simon Horman <simon.horman@corigine.com> Acked-by: Kalle Valo <kvalo@kernel.org>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/ath/ath12k/pci.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/drivers/net/wireless/ath/ath12k/pci.c b/drivers/net/wireless/ath/ath12k/pci.c
index 5990a55801f0..e4f08a066ca1 100644
--- a/drivers/net/wireless/ath/ath12k/pci.c
+++ b/drivers/net/wireless/ath/ath12k/pci.c
@@ -794,8 +794,8 @@ static void ath12k_pci_aspm_disable(struct ath12k_pci *ab_pci)
u16_get_bits(ab_pci->link_ctl, PCI_EXP_LNKCTL_ASPM_L1));
/* disable L0s and L1 */
- pcie_capability_write_word(ab_pci->pdev, PCI_EXP_LNKCTL,
- ab_pci->link_ctl & ~PCI_EXP_LNKCTL_ASPMC);
+ pcie_capability_clear_word(ab_pci->pdev, PCI_EXP_LNKCTL,
+ PCI_EXP_LNKCTL_ASPMC);
set_bit(ATH12K_PCI_ASPM_RESTORE, &ab_pci->flags);
}
@@ -803,8 +803,10 @@ static void ath12k_pci_aspm_disable(struct ath12k_pci *ab_pci)
static void ath12k_pci_aspm_restore(struct ath12k_pci *ab_pci)
{
if (test_and_clear_bit(ATH12K_PCI_ASPM_RESTORE, &ab_pci->flags))
- pcie_capability_write_word(ab_pci->pdev, PCI_EXP_LNKCTL,
- ab_pci->link_ctl);
+ pcie_capability_clear_and_set_word(ab_pci->pdev, PCI_EXP_LNKCTL,
+ PCI_EXP_LNKCTL_ASPMC,
+ ab_pci->link_ctl &
+ PCI_EXP_LNKCTL_ASPMC);
}
static void ath12k_pci_kill_tasklets(struct ath12k_base *ab)