diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c index 969a1231800e43a06ed96cd36602355cdb910016..8be07c653b2d0b4e14ef71b4ba090543b61331a5 100644 --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c @@ -1227,11 +1227,15 @@ static void ath10k_pci_irq_enable(struct ath10k *ar) static int ath10k_pci_hif_start(struct ath10k *ar) { + struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot hif start\n"); ath10k_pci_irq_enable(ar); ath10k_pci_rx_post(ar); + pcie_capability_write_word(ar_pci->pdev, PCI_EXP_LNKCTL, + ar_pci->link_ctl); + return 0; } @@ -1981,6 +1985,7 @@ static int ath10k_pci_chip_reset(struct ath10k *ar) static int ath10k_pci_hif_power_up(struct ath10k *ar) { + struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); int ret; ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot hif power up\n"); @@ -1991,6 +1996,11 @@ static int ath10k_pci_hif_power_up(struct ath10k *ar) return ret; } + pcie_capability_read_word(ar_pci->pdev, PCI_EXP_LNKCTL, + &ar_pci->link_ctl); + pcie_capability_write_word(ar_pci->pdev, PCI_EXP_LNKCTL, + ar_pci->link_ctl & ~PCI_EXP_LNKCTL_ASPMC); + /* * Bring the target up cleanly. * @@ -2502,7 +2512,6 @@ static int ath10k_pci_claim(struct ath10k *ar) { struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct pci_dev *pdev = ar_pci->pdev; - u32 lcr_val; int ret; pci_set_drvdata(pdev, ar); @@ -2536,10 +2545,6 @@ static int ath10k_pci_claim(struct ath10k *ar) pci_set_master(pdev); - /* Workaround: Disable ASPM */ - pci_read_config_dword(pdev, 0x80, &lcr_val); - pci_write_config_dword(pdev, 0x80, (lcr_val & 0xffffff00)); - /* Arrange for access to Target SoC registers. */ ar_pci->mem = pci_iomap(pdev, BAR_NUM, 0); if (!ar_pci->mem) { diff --git a/drivers/net/wireless/ath/ath10k/pci.h b/drivers/net/wireless/ath/ath10k/pci.h index bddf54320160d91c8f21fd9982c54e123e3d3881..ee2173d6125755da92ae6fa8645e2bb849835fe4 100644 --- a/drivers/net/wireless/ath/ath10k/pci.h +++ b/drivers/net/wireless/ath/ath10k/pci.h @@ -185,6 +185,12 @@ struct ath10k_pci { /* Map CE id to ce_state */ struct ath10k_ce_pipe ce_states[CE_COUNT_MAX]; struct timer_list rx_post_retry; + + /* Due to HW quirks it is recommended to disable ASPM during device + * bootup. To do that the original PCI-E Link Control is stored before + * device bootup is executed and re-programmed later. + */ + u16 link_ctl; }; static inline struct ath10k_pci *ath10k_pci_priv(struct ath10k *ar)