Re: [PATCH v10] Add device-specific reset for Qualcomm devices

From: Baochen Qiang

Date: Mon Jun 29 2026 - 05:45:50 EST




On 6/25/2026 9:03 PM, Manivannan Sadhasivam wrote:
> On Wed, Jun 24, 2026 at 03:47:12PM +0800, Baochen Qiang wrote:
>>
>>
>> On 6/24/2026 2:31 AM, Jose Ignacio Tornos Martinez wrote:
>>> Some Qualcomm PCIe devices (WCN6855/WCN7850 WiFi cards, SDX62/SDX65 modems)
>>> lack working reset methods for VFIO passthrough scenarios. These devices
>>> have no FLR capability, advertise NoSoftRst+ (blocking PM reset), and have
>>> broken bus reset.
>>>
>>> The problem manifests in VFIO passthrough scenarios:
>>>
>>> - WCN6855 (17cb:1103) and WCN7850 (17cb:1107) WiFi devices:
>>> Normal VM operation works fine, including clean shutdown/reboot.
>>> However, when the VM terminates uncleanly (crash, force-off), VFIO
>>> attempts to reset the device before it can be assigned to another VM.
>>> Without a working reset method, the device remains in an undefined state,
>>> preventing reuse.
>>>
>>> - SDX62/SDX65 (17cb:0308) 5G modems: Never successfully initialize even
>>> on first VM assignment without proper reset capability.
>>>
>>> Add device-specific reset methods using BAR-space hardware reset registers
>>> that exist in these devices:
>>>
>>> - WCN6855/WCN7850 WiFi devices use SoC global reset via BAR0 (sequence from
>>> ath11k/ath12k driver: ath11k_pci_soc_global_reset(), ath11k_pci_sw_reset(),
>>> ath11k_mhi_set_mhictrl_reset()):
>>> - Write/clear reset bit at offset 0x3008
>>> - Wait for PCIe link recovery (up to 5 seconds)
>>> - Clear MHI controller SYSERR status at offset 0x38
>>>
>>> - SDX62/SDX65 modem devices use MHI SoC reset via BAR0 (sequence from MHI
>>> driver: mhi_soc_reset(), mhi_pci_reset_prepare()):
>>> - Write reset request to offset 0xb0
>>> - Wait 2 seconds for reset completion
>>>
>>> These are true hardware reset mechanisms (not power management or firmware
>>> error recovery), providing proper device reset for VFIO scenarios.
>>>
>>> Testing was performed on desktop platforms with M.2 WiFi and modem cards
>>> using M.2-to-PCIe adapters, including extensive force-reset cycling to
>>> verify stability.
>>>
>>> Signed-off-by: Jose Ignacio Tornos Martinez <jtornosm@xxxxxxxxxx>
>>> ---
>>> v10:
>>> - Complete redesign based on maintainer feedback (Manivannan Sadhasivam,
>>> Alex Williamson): use actual hardware reset registers from
>>> device drivers instead of D3hot power cycling
>>> v9: https://lore.kernel.org/all/20260612142638.1243895-1-jtornosm@xxxxxxxxxx/
>>>
>>> drivers/pci/quirks.c | 118 +++++++++++++++++++++++++++++++++++++++++++
>>> 1 file changed, 118 insertions(+)
>>>
>>> diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
>>> index 431c021d7414..8ad3f214e520 100644
>>> --- a/drivers/pci/quirks.c
>>> +++ b/drivers/pci/quirks.c
>>> @@ -4240,6 +4240,121 @@ static int reset_hinic_vf_dev(struct pci_dev *pdev, bool probe)
>>> return 0;
>>> }
>>>
>>> +#define QUALCOMM_WIFI_PCIE_SOC_GLOBAL_RESET 0x3008
>>> +#define QUALCOMM_WIFI_PCIE_SOC_GLOBAL_RESET_V BIT(0)
>>> +#define QUALCOMM_WIFI_MHISTATUS 0x48
>>> +#define QUALCOMM_WIFI_MHICTRL 0x38
>>> +#define QUALCOMM_WIFI_MHICTRL_RESET_MASK 0x2
>>> +
>>> +/*
>>> + * Qualcomm WiFi device-specific reset using SoC global reset via BAR0
>>> + * registers.
>>> + */
>>> +static int reset_qualcomm_wifi(struct pci_dev *pdev, bool probe)
>>> +{
>>> + bool link_recovered = false;
>>> + unsigned long timeout;
>>> + void __iomem *bar;
>>> + u32 val;
>>> + u16 cmd;
>>> +
>>> + if (probe)
>>> + return 0;
>>> +
>>> + if (pdev->current_state != PCI_D0)
>>> + return -EINVAL;
>>> +
>>> + pci_read_config_word(pdev, PCI_COMMAND, &cmd);
>>> + pci_write_config_word(pdev, PCI_COMMAND, cmd | PCI_COMMAND_MEMORY);
>>> +
>>> + bar = pci_iomap(pdev, 0, 0);
>>> + if (!bar) {
>>> + pci_write_config_word(pdev, PCI_COMMAND, cmd);
>>> + return -ENODEV;
>>> + }
>>> +
>>> + val = ioread32(bar + QUALCOMM_WIFI_PCIE_SOC_GLOBAL_RESET);
>>
>> QUALCOMM_WIFI_PCIE_SOC_GLOBAL_RESET is beyond the first 4K bar area hence requires MHI
>> wakeup before accessing, see [1]. the wakeup callback for WCN6855 is
>> ath11k_pci_bus_wake_up() which calls mhi_device_get_sync(). Not sure how this can be done
>> here. Maybe Mani can provide some hints?
>>
>
> I don't think the device needs to be waken up before
> QUALCOMM_WIFI_PCIE_SOC_GLOBAL_RESET. ath11k driver wakes up the device for
> accessing the MHI interface I believe. Since this callback is not touching MHI,
> there is no need to wakeup the device, AFAIK.

MHI register space is constitute with 3 segments, with mhi offset always being 0, bhi
offset 0x100 and bhie offset 0x224 (the latter two offsets are for WCN7850, but I think
also apply to other devices). That said the whole MHI register space does not go beyond
the first 4K region, hence wakeup is not for accessing MHI interface.

>
> - Mani
>