Loading drivers/net/wireless/cnss2/bus.c +15 −0 Original line number Diff line number Diff line Loading @@ -465,6 +465,21 @@ int cnss_bus_check_link_status(struct cnss_plat_data *plat_priv) } } int cnss_bus_recover_link_down(struct cnss_plat_data *plat_priv) { if (!plat_priv) return -ENODEV; switch (plat_priv->bus_type) { case CNSS_BUS_PCI: return cnss_pci_recover_link_down(plat_priv->bus_priv); default: cnss_pr_dbg("Unsupported bus type: %d\n", plat_priv->bus_type); return -EINVAL; } } int cnss_bus_debug_reg_read(struct cnss_plat_data *plat_priv, u32 offset, u32 *val) { Loading drivers/net/wireless/cnss2/bus.h +1 −0 Original line number Diff line number Diff line Loading @@ -52,6 +52,7 @@ int cnss_bus_update_status(struct cnss_plat_data *plat_priv, enum cnss_driver_status status); int cnss_bus_is_device_down(struct cnss_plat_data *plat_priv); int cnss_bus_check_link_status(struct cnss_plat_data *plat_priv); int cnss_bus_recover_link_down(struct cnss_plat_data *plat_priv); int cnss_bus_debug_reg_read(struct cnss_plat_data *plat_priv, u32 offset, u32 *val); int cnss_bus_debug_reg_write(struct cnss_plat_data *plat_priv, u32 offset, Loading drivers/net/wireless/cnss2/main.c +9 −1 Original line number Diff line number Diff line Loading @@ -742,7 +742,7 @@ int cnss_idle_shutdown(struct device *dev) reinit_completion(&plat_priv->recovery_complete); ret = wait_for_completion_timeout(&plat_priv->recovery_complete, RECOVERY_TIMEOUT); msecs_to_jiffies(RECOVERY_TIMEOUT)); if (!ret) { cnss_pr_err("Timeout waiting for recovery to complete\n"); CNSS_ASSERT(0); Loading Loading @@ -1071,6 +1071,14 @@ static int cnss_do_recovery(struct cnss_plat_data *plat_priv, if (test_bit(LINK_DOWN_SELF_RECOVERY, &plat_priv->ctrl_params.quirks)) goto self_recovery; if (!cnss_bus_recover_link_down(plat_priv)) { /* clear recovery bit here to avoid skipping * the recovery work for RDDM later */ clear_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state); return 0; } break; case CNSS_REASON_RDDM: cnss_bus_collect_dump_info(plat_priv, false); Loading drivers/net/wireless/cnss2/pci.c +51 −3 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ #define FW_ASSERT_TIMEOUT 5000 #define DEV_RDDM_TIMEOUT 5000 #define WAKE_EVENT_TIMEOUT 5000 #ifdef CONFIG_CNSS_EMULATION #define EMULATION_HW 1 Loading Loading @@ -775,6 +776,42 @@ int cnss_resume_pci_link(struct cnss_pci_data *pci_priv) return ret; } int cnss_pci_recover_link_down(struct cnss_pci_data *pci_priv) { int ret; switch (pci_priv->device_id) { case QCA6390_DEVICE_ID: case QCA6490_DEVICE_ID: break; default: return -EOPNOTSUPP; } /* Always wait here to avoid missing WAKE assert for RDDM * before link recovery */ msleep(WAKE_EVENT_TIMEOUT); ret = cnss_suspend_pci_link(pci_priv); if (ret) cnss_pr_err("Failed to suspend PCI link, err = %d\n", ret); ret = cnss_resume_pci_link(pci_priv); if (ret) { cnss_pr_err("Failed to resume PCI link, err = %d\n", ret); del_timer(&pci_priv->dev_rddm_timer); return ret; } mod_timer(&pci_priv->dev_rddm_timer, jiffies + msecs_to_jiffies(DEV_RDDM_TIMEOUT)); mhi_debug_reg_dump(pci_priv->mhi_ctrl); return 0; } int cnss_pci_prevent_l1(struct device *dev) { struct pci_dev *pci_dev = to_pci_dev(dev); Loading Loading @@ -849,6 +886,7 @@ int cnss_pci_link_down(struct device *dev) 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); Loading Loading @@ -2260,23 +2298,25 @@ static void cnss_pci_event_cb(struct msm_pcie_notify *notify) 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"); 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"); 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); cnss_fatal_err("PCI link down, schedule recovery!\n"); 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); break; case MSM_PCIE_EVENT_WAKEUP: complete(&pci_priv->wake_event); if (cnss_pci_get_monitor_wake_intr(pci_priv) && cnss_pci_get_auto_suspended(pci_priv)) { cnss_pci_set_monitor_wake_intr(pci_priv, false); Loading Loading @@ -4215,12 +4255,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); } Loading Loading @@ -4548,6 +4594,7 @@ static int cnss_pci_probe(struct pci_dev *pci_dev, cnss_pci_set_wlaon_pwr_ctrl(pci_priv, false, false, false); timer_setup(&pci_priv->dev_rddm_timer, cnss_dev_rddm_timeout_hdlr, 0); init_completion(&pci_priv->wake_event); INIT_DELAYED_WORK(&pci_priv->time_sync_work, cnss_pci_time_sync_work_hdlr); Loading Loading @@ -4611,6 +4658,7 @@ static void cnss_pci_remove(struct pci_dev *pci_dev) case QCA6490_DEVICE_ID: cnss_pci_unregister_mhi(pci_priv); cnss_pci_disable_msi(pci_priv); complete_all(&pci_priv->wake_event); del_timer(&pci_priv->dev_rddm_timer); break; default: Loading drivers/net/wireless/cnss2/pci.h +2 −0 Original line number Diff line number Diff line Loading @@ -77,6 +77,7 @@ struct cnss_pci_data { u8 drv_connected_last; u16 def_link_speed; u16 def_link_width; struct completion wake_event; u8 monitor_wake_intr; struct iommu_domain *iommu_domain; u8 smmu_s1_enable; Loading Loading @@ -165,6 +166,7 @@ static inline int cnss_pci_get_drv_connected(void *bus_priv) int cnss_pci_check_link_status(struct cnss_pci_data *pci_priv); int cnss_suspend_pci_link(struct cnss_pci_data *pci_priv); int cnss_resume_pci_link(struct cnss_pci_data *pci_priv); int cnss_pci_recover_link_down(struct cnss_pci_data *pci_priv); int cnss_pci_init(struct cnss_plat_data *plat_priv); void cnss_pci_deinit(struct cnss_plat_data *plat_priv); void cnss_pci_add_fw_prefix_name(struct cnss_pci_data *pci_priv, Loading Loading
drivers/net/wireless/cnss2/bus.c +15 −0 Original line number Diff line number Diff line Loading @@ -465,6 +465,21 @@ int cnss_bus_check_link_status(struct cnss_plat_data *plat_priv) } } int cnss_bus_recover_link_down(struct cnss_plat_data *plat_priv) { if (!plat_priv) return -ENODEV; switch (plat_priv->bus_type) { case CNSS_BUS_PCI: return cnss_pci_recover_link_down(plat_priv->bus_priv); default: cnss_pr_dbg("Unsupported bus type: %d\n", plat_priv->bus_type); return -EINVAL; } } int cnss_bus_debug_reg_read(struct cnss_plat_data *plat_priv, u32 offset, u32 *val) { Loading
drivers/net/wireless/cnss2/bus.h +1 −0 Original line number Diff line number Diff line Loading @@ -52,6 +52,7 @@ int cnss_bus_update_status(struct cnss_plat_data *plat_priv, enum cnss_driver_status status); int cnss_bus_is_device_down(struct cnss_plat_data *plat_priv); int cnss_bus_check_link_status(struct cnss_plat_data *plat_priv); int cnss_bus_recover_link_down(struct cnss_plat_data *plat_priv); int cnss_bus_debug_reg_read(struct cnss_plat_data *plat_priv, u32 offset, u32 *val); int cnss_bus_debug_reg_write(struct cnss_plat_data *plat_priv, u32 offset, Loading
drivers/net/wireless/cnss2/main.c +9 −1 Original line number Diff line number Diff line Loading @@ -742,7 +742,7 @@ int cnss_idle_shutdown(struct device *dev) reinit_completion(&plat_priv->recovery_complete); ret = wait_for_completion_timeout(&plat_priv->recovery_complete, RECOVERY_TIMEOUT); msecs_to_jiffies(RECOVERY_TIMEOUT)); if (!ret) { cnss_pr_err("Timeout waiting for recovery to complete\n"); CNSS_ASSERT(0); Loading Loading @@ -1071,6 +1071,14 @@ static int cnss_do_recovery(struct cnss_plat_data *plat_priv, if (test_bit(LINK_DOWN_SELF_RECOVERY, &plat_priv->ctrl_params.quirks)) goto self_recovery; if (!cnss_bus_recover_link_down(plat_priv)) { /* clear recovery bit here to avoid skipping * the recovery work for RDDM later */ clear_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state); return 0; } break; case CNSS_REASON_RDDM: cnss_bus_collect_dump_info(plat_priv, false); Loading
drivers/net/wireless/cnss2/pci.c +51 −3 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ #define FW_ASSERT_TIMEOUT 5000 #define DEV_RDDM_TIMEOUT 5000 #define WAKE_EVENT_TIMEOUT 5000 #ifdef CONFIG_CNSS_EMULATION #define EMULATION_HW 1 Loading Loading @@ -775,6 +776,42 @@ int cnss_resume_pci_link(struct cnss_pci_data *pci_priv) return ret; } int cnss_pci_recover_link_down(struct cnss_pci_data *pci_priv) { int ret; switch (pci_priv->device_id) { case QCA6390_DEVICE_ID: case QCA6490_DEVICE_ID: break; default: return -EOPNOTSUPP; } /* Always wait here to avoid missing WAKE assert for RDDM * before link recovery */ msleep(WAKE_EVENT_TIMEOUT); ret = cnss_suspend_pci_link(pci_priv); if (ret) cnss_pr_err("Failed to suspend PCI link, err = %d\n", ret); ret = cnss_resume_pci_link(pci_priv); if (ret) { cnss_pr_err("Failed to resume PCI link, err = %d\n", ret); del_timer(&pci_priv->dev_rddm_timer); return ret; } mod_timer(&pci_priv->dev_rddm_timer, jiffies + msecs_to_jiffies(DEV_RDDM_TIMEOUT)); mhi_debug_reg_dump(pci_priv->mhi_ctrl); return 0; } int cnss_pci_prevent_l1(struct device *dev) { struct pci_dev *pci_dev = to_pci_dev(dev); Loading Loading @@ -849,6 +886,7 @@ int cnss_pci_link_down(struct device *dev) 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); Loading Loading @@ -2260,23 +2298,25 @@ static void cnss_pci_event_cb(struct msm_pcie_notify *notify) 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"); 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"); 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); cnss_fatal_err("PCI link down, schedule recovery!\n"); 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); break; case MSM_PCIE_EVENT_WAKEUP: complete(&pci_priv->wake_event); if (cnss_pci_get_monitor_wake_intr(pci_priv) && cnss_pci_get_auto_suspended(pci_priv)) { cnss_pci_set_monitor_wake_intr(pci_priv, false); Loading Loading @@ -4215,12 +4255,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); } Loading Loading @@ -4548,6 +4594,7 @@ static int cnss_pci_probe(struct pci_dev *pci_dev, cnss_pci_set_wlaon_pwr_ctrl(pci_priv, false, false, false); timer_setup(&pci_priv->dev_rddm_timer, cnss_dev_rddm_timeout_hdlr, 0); init_completion(&pci_priv->wake_event); INIT_DELAYED_WORK(&pci_priv->time_sync_work, cnss_pci_time_sync_work_hdlr); Loading Loading @@ -4611,6 +4658,7 @@ static void cnss_pci_remove(struct pci_dev *pci_dev) case QCA6490_DEVICE_ID: cnss_pci_unregister_mhi(pci_priv); cnss_pci_disable_msi(pci_priv); complete_all(&pci_priv->wake_event); del_timer(&pci_priv->dev_rddm_timer); break; default: Loading
drivers/net/wireless/cnss2/pci.h +2 −0 Original line number Diff line number Diff line Loading @@ -77,6 +77,7 @@ struct cnss_pci_data { u8 drv_connected_last; u16 def_link_speed; u16 def_link_width; struct completion wake_event; u8 monitor_wake_intr; struct iommu_domain *iommu_domain; u8 smmu_s1_enable; Loading Loading @@ -165,6 +166,7 @@ static inline int cnss_pci_get_drv_connected(void *bus_priv) int cnss_pci_check_link_status(struct cnss_pci_data *pci_priv); int cnss_suspend_pci_link(struct cnss_pci_data *pci_priv); int cnss_resume_pci_link(struct cnss_pci_data *pci_priv); int cnss_pci_recover_link_down(struct cnss_pci_data *pci_priv); int cnss_pci_init(struct cnss_plat_data *plat_priv); void cnss_pci_deinit(struct cnss_plat_data *plat_priv); void cnss_pci_add_fw_prefix_name(struct cnss_pci_data *pci_priv, Loading