From: Baochen Qiang <bqiang@xxxxxxxxxxxxxx> ath11k_pci_write32/read32 tries to wake up MHI before doing actual write/read work, which means each time a u32 is written/read, MHI wake up is performed. This is not necessary in case where we do a large amount of write/read, cause only one time of wake up is needed. So split each one into two parts, the first part does MHI get/put and the second one does actual write/read work. Also avoid the put operation if the previous get operation fails. Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1 Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1 Signed-off-by: Baochen Qiang <bqiang@xxxxxxxxxxxxxx> Signed-off-by: Jouni Malinen <jouni@xxxxxxxxxxxxxx> --- drivers/net/wireless/ath/ath11k/pci.c | 61 ++++++++++++++++++--------- 1 file changed, 42 insertions(+), 19 deletions(-) diff --git a/drivers/net/wireless/ath/ath11k/pci.c b/drivers/net/wireless/ath/ath11k/pci.c index 1094b53465bc..5c3ec3e7be89 100644 --- a/drivers/net/wireless/ath/ath11k/pci.c +++ b/drivers/net/wireless/ath/ath11k/pci.c @@ -174,18 +174,11 @@ static inline u32 ath11k_pci_get_window_start(struct ath11k_base *ab, return window_start; } -void ath11k_pci_write32(struct ath11k_base *ab, u32 offset, u32 value) +void ath11k_pci_do_write32(struct ath11k_base *ab, u32 offset, u32 value) { struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); u32 window_start; - /* for offset beyond BAR + 4K - 32, may - * need to wakeup MHI to access. - */ - if (test_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags) && - offset >= ACCESS_ALWAYS_OFF) - mhi_device_get_sync(ab_pci->mhi_ctrl->mhi_dev); - if (offset < WINDOW_START) { iowrite32(value, ab->mem + offset); } else { @@ -205,23 +198,33 @@ void ath11k_pci_write32(struct ath11k_base *ab, u32 offset, u32 value) (offset & WINDOW_RANGE_MASK)); } } - - if (test_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags) && - offset >= ACCESS_ALWAYS_OFF) - mhi_device_put(ab_pci->mhi_ctrl->mhi_dev); } -u32 ath11k_pci_read32(struct ath11k_base *ab, u32 offset) +void ath11k_pci_write32(struct ath11k_base *ab, u32 offset, u32 value) { struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); - u32 val, window_start; + bool wakeup_required; + int ret; /* for offset beyond BAR + 4K - 32, may * need to wakeup MHI to access. */ - if (test_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags) && - offset >= ACCESS_ALWAYS_OFF) - mhi_device_get_sync(ab_pci->mhi_ctrl->mhi_dev); + wakeup_required = test_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags) && + offset >= ACCESS_ALWAYS_OFF; + + if (wakeup_required) + ret = mhi_device_get_sync(ab_pci->mhi_ctrl->mhi_dev); + + ath11k_pci_do_write32(ab, offset, value); + + if (wakeup_required && !ret) + mhi_device_put(ab_pci->mhi_ctrl->mhi_dev); +} + +u32 ath11k_pci_do_read32(struct ath11k_base *ab, u32 offset) +{ + struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); + u32 val, window_start; if (offset < WINDOW_START) { val = ioread32(ab->mem + offset); @@ -243,8 +246,28 @@ u32 ath11k_pci_read32(struct ath11k_base *ab, u32 offset) } } - if (test_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags) && - offset >= ACCESS_ALWAYS_OFF) + return val; +} + +u32 ath11k_pci_read32(struct ath11k_base *ab, u32 offset) +{ + struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); + u32 val; + bool wakeup_required; + int ret; + + /* for offset beyond BAR + 4K - 32, may + * need to wakeup MHI to access. + */ + wakeup_required = test_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags) && + offset >= ACCESS_ALWAYS_OFF; + + if (wakeup_required) + ret = mhi_device_get_sync(ab_pci->mhi_ctrl->mhi_dev); + + val = ath11k_pci_do_read32(ab, offset); + + if (wakeup_required && !ret) mhi_device_put(ab_pci->mhi_ctrl->mhi_dev); return val; -- 2.25.1