[PATCH 5/5] ath11k: Handle MSI enablement during rmmod and SSR
Kalle Valo
kvalo at codeaurora.org
Sun Oct 10 23:47:50 PDT 2021
Jouni Malinen <jouni at codeaurora.org> writes:
> From: Baochen Qiang <bqiang at codeaurora.org>
>
> When doing "rmmod ath11k_pci", ath11k performs global SOC reset
> and MHI reset, where 0 address access is captured by IOMMU. See
> log below:
>
> ...
> [ 133.953860] ath11k_pci 0000:02:00.0: setting mhi state: DEINIT(1)
> [ 133.959714] ath11k_pci 0000:02:00.0: AMD-Vi: Event logged [IO_PAGE_FAULT domain=0x000a address=0x0 flags=0x0020]
> [ 133.973854] ath11k_pci 0000:02:00.0: MHISTATUS 0xff04
> [ 133.974095] ath11k_pci 0000:02:00.0: AMD-Vi: Event logged [IO_PAGE_FAULT domain=0x000a address=0x0 flags=0x0020]
> ...
>
> This issue is also observed in SSR process, cause a similar
> sequence as above is performed.
>
> Such an invalid access occurs because, during rmmod or SSR, MSI
> address is cleared but HW MSI functionality not disabled, thus HW
> target is able to raise an MSI transaction with 0 as MSI address.
>
> So it can be fixed by simply disabling MSI before reset. For SSR,
> since MSI functionality is still needed after target is brought
> back, we need to reenable it.
>
> Also change naming of some interfaces related.
>
> 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 at codeaurora.org>
> Signed-off-by: Jouni Malinen <jouni at codeaurora.org>
> ---
> drivers/net/wireless/ath/ath11k/pci.c | 27 ++++++++++++++++++++++-----
> 1 file changed, 22 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/ath11k/pci.c b/drivers/net/wireless/ath/ath11k/pci.c
> index 7b3bce0ba76e..1094b53465bc 100644
> --- a/drivers/net/wireless/ath/ath11k/pci.c
> +++ b/drivers/net/wireless/ath/ath11k/pci.c
> @@ -855,7 +855,18 @@ static void ath11k_pci_ce_irqs_enable(struct ath11k_base *ab)
> }
> }
>
> -static int ath11k_pci_enable_msi(struct ath11k_pci *ab_pci)
> +static void ath11k_pci_enable_msi(struct pci_dev *dev, bool enable)
> +{
> + u16 control;
> +
> + pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &control);
> + control &= ~PCI_MSI_FLAGS_ENABLE;
> + if (enable)
> + control |= PCI_MSI_FLAGS_ENABLE;
> + pci_write_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, control);
> +}
To make the function cleaner I renamed this to ath11k_pci_msi_config(),
added an else branch and changed it to take structh ath11k_pci. I also
added helpers ath11k_pci_msi_enable() and ath11k_pci_msi_disable().
--
https://patchwork.kernel.org/project/linux-wireless/list/
https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
More information about the ath11k
mailing list