From 0a4c0b455783f67ba5cb84b352f9b4e821b77326 Mon Sep 17 00:00:00 2001 From: Bhaumik Bhatt Date: Fri, 24 Jul 2020 12:23:51 -0700 Subject: [PATCH 1/2] cnss2: print message for abrupt device reset to PBL At times, the device can abruptly reset due to power rail or other related issues which can manifest as a linkdown on the host. As linkdown recovery mechanism is put in place, it would be helpful to understand why a set of ramdumps was not collected in these abrupt reset cases. Hence, it is wise to add a print message to check whether the device has reset to PBL and make the users aware. Change-Id: I545a5b87461b05ea436e383fddd2a8d037a8389d Signed-off-by: Bhaumik Bhatt --- drivers/net/wireless/cnss2/pci.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/wireless/cnss2/pci.c b/drivers/net/wireless/cnss2/pci.c index 57ceee858961..e7c6ba369380 100644 --- a/drivers/net/wireless/cnss2/pci.c +++ b/drivers/net/wireless/cnss2/pci.c @@ -4300,12 +4300,18 @@ static void cnss_dev_rddm_timeout_hdlr(struct timer_list *t) { struct cnss_pci_data *pci_priv = from_timer(pci_priv, t, dev_rddm_timer); + struct mhi_controller *mhi_ctrl = pci_priv->mhi_ctrl; if (!pci_priv) return; cnss_fatal_err("Timeout waiting for RDDM notification\n"); + if (mhi_get_exec_env(mhi_ctrl) == MHI_EE_PBL) + cnss_pr_err("Unable to collect ramdumps due to abrupt reset\n"); + + mhi_debug_reg_dump(mhi_ctrl); + cnss_schedule_recovery(&pci_priv->pci_dev->dev, CNSS_REASON_TIMEOUT); } From 2cf1df2b58b545780baee47ccf6de6f045377eaa Mon Sep 17 00:00:00 2001 From: Yue Ma Date: Tue, 11 Aug 2020 15:10:59 -0700 Subject: [PATCH 2/2] cnss2: Notify MSM PCIe bus driver when detect link down There are cases that CNSS driver or WLAN host driver detects PCIe link not accessible but link down interrupt is not triggered. In order to handle these cases, instead of starting recovery directly, notify MSM PCIe bus which can assert PCIe PERST GPIO and then handle the link down callback from it as normal link down. Change-Id: I9af8b3ae33d9c094a412c39962f5c1883c34a12a Signed-off-by: Yue Ma --- drivers/net/wireless/cnss2/pci.c | 66 +++++++++++++++----------------- 1 file changed, 31 insertions(+), 35 deletions(-) diff --git a/drivers/net/wireless/cnss2/pci.c b/drivers/net/wireless/cnss2/pci.c index e7c6ba369380..f2d980fe0571 100644 --- a/drivers/net/wireless/cnss2/pci.c +++ b/drivers/net/wireless/cnss2/pci.c @@ -912,19 +912,12 @@ void cnss_pci_allow_l1(struct device *dev) } EXPORT_SYMBOL(cnss_pci_allow_l1); -int cnss_pci_link_down(struct device *dev) +static void cnss_pci_handle_linkdown(struct cnss_pci_data *pci_priv) { + struct cnss_plat_data *plat_priv = pci_priv->plat_priv; + struct pci_dev *pci_dev = pci_priv->pci_dev; unsigned long flags; - struct pci_dev *pci_dev = to_pci_dev(dev); - struct cnss_pci_data *pci_priv = cnss_get_pci_priv(pci_dev); - struct cnss_plat_data *plat_priv; - if (!pci_priv) { - cnss_pr_err("pci_priv is NULL\n"); - return -EINVAL; - } - - plat_priv = pci_priv->plat_priv; if (test_bit(ENABLE_PCI_LINK_DOWN_PANIC, &plat_priv->ctrl_params.quirks)) panic("cnss: PCI link is down\n"); @@ -933,17 +926,40 @@ int cnss_pci_link_down(struct device *dev) if (pci_priv->pci_link_down_ind) { cnss_pr_dbg("PCI link down recovery is in progress, ignore\n"); spin_unlock_irqrestore(&pci_link_down_lock, flags); - return -EINVAL; + return; } pci_priv->pci_link_down_ind = true; spin_unlock_irqrestore(&pci_link_down_lock, flags); reinit_completion(&pci_priv->wake_event); - cnss_pr_err("PCI link down is detected, schedule recovery\n"); - cnss_schedule_recovery(dev, CNSS_REASON_LINK_DOWN); + if (pci_dev->device == QCA6174_DEVICE_ID) + disable_irq(pci_dev->irq); - return 0; + cnss_fatal_err("PCI link down, schedule recovery\n"); + cnss_schedule_recovery(&pci_dev->dev, CNSS_REASON_LINK_DOWN); +} + +int cnss_pci_link_down(struct device *dev) +{ + struct pci_dev *pci_dev = to_pci_dev(dev); + struct cnss_pci_data *pci_priv = cnss_get_pci_priv(pci_dev); + int ret; + + if (!pci_priv) { + cnss_pr_err("pci_priv is NULL\n"); + return -EINVAL; + } + + cnss_pr_err("PCI link down is detected by drivers\n"); + + ret = msm_pcie_pm_control(MSM_PCIE_HANDLE_LINKDOWN, + pci_dev->bus->number, pci_dev, NULL, + PM_OPTIONS_DEFAULT); + if (ret) + cnss_pci_handle_linkdown(pci_priv); + + return ret; } EXPORT_SYMBOL(cnss_pci_link_down); @@ -2400,10 +2416,8 @@ static bool cnss_pci_is_drv_supported(struct cnss_pci_data *pci_priv) static void cnss_pci_event_cb(struct msm_pcie_notify *notify) { - unsigned long flags; struct pci_dev *pci_dev; struct cnss_pci_data *pci_priv; - struct cnss_plat_data *plat_priv; if (!notify) return; @@ -2416,27 +2430,9 @@ static void cnss_pci_event_cb(struct msm_pcie_notify *notify) if (!pci_priv) return; - plat_priv = pci_priv->plat_priv; switch (notify->event) { case MSM_PCIE_EVENT_LINKDOWN: - if (test_bit(ENABLE_PCI_LINK_DOWN_PANIC, - &plat_priv->ctrl_params.quirks)) - panic("cnss: PCI link is down\n"); - - spin_lock_irqsave(&pci_link_down_lock, flags); - if (pci_priv->pci_link_down_ind) { - cnss_pr_dbg("PCI link down recovery is in progress, ignore\n"); - spin_unlock_irqrestore(&pci_link_down_lock, flags); - return; - } - pci_priv->pci_link_down_ind = true; - spin_unlock_irqrestore(&pci_link_down_lock, flags); - - reinit_completion(&pci_priv->wake_event); - cnss_fatal_err("PCI link down, schedule recovery\n"); - if (pci_dev->device == QCA6174_DEVICE_ID) - disable_irq(pci_dev->irq); - cnss_schedule_recovery(&pci_dev->dev, CNSS_REASON_LINK_DOWN); + cnss_pci_handle_linkdown(pci_priv); break; case MSM_PCIE_EVENT_WAKEUP: complete(&pci_priv->wake_event);