Loading drivers/net/wireless/cnss2/main.c +55 −0 Original line number Original line Diff line number Diff line Loading @@ -35,6 +35,7 @@ #define WLAN_RECOVERY_DELAY 1000 #define WLAN_RECOVERY_DELAY 1000 #define FILE_SYSTEM_READY 1 #define FILE_SYSTEM_READY 1 #define FW_READY_TIMEOUT 20000 #define FW_READY_TIMEOUT 20000 #define FW_ASSERT_TIMEOUT 5000 #define CNSS_EVENT_PENDING 2989 #define CNSS_EVENT_PENDING 2989 static struct cnss_plat_data *plat_env; static struct cnss_plat_data *plat_env; Loading Loading @@ -665,6 +666,8 @@ static char *cnss_driver_event_to_str(enum cnss_driver_event_type type) return "UNREGISTER_DRIVER"; return "UNREGISTER_DRIVER"; case CNSS_DRIVER_EVENT_RECOVERY: case CNSS_DRIVER_EVENT_RECOVERY: return "RECOVERY"; return "RECOVERY"; case CNSS_DRIVER_EVENT_FORCE_FW_ASSERT: return "FORCE_FW_ASSERT"; case CNSS_DRIVER_EVENT_MAX: case CNSS_DRIVER_EVENT_MAX: return "EVENT_MAX"; return "EVENT_MAX"; } } Loading Loading @@ -1545,6 +1548,55 @@ void cnss_schedule_recovery(struct device *dev, } } EXPORT_SYMBOL(cnss_schedule_recovery); EXPORT_SYMBOL(cnss_schedule_recovery); static int cnss_force_fw_assert_hdlr(struct cnss_plat_data *plat_priv) { struct cnss_pci_data *pci_priv = plat_priv->bus_priv; int ret; ret = cnss_pci_set_mhi_state(plat_priv->bus_priv, CNSS_MHI_TRIGGER_RDDM); if (ret) { cnss_pr_err("Failed to trigger RDDM, err = %d\n", ret); cnss_schedule_recovery(&pci_priv->pci_dev->dev, CNSS_REASON_DEFAULT); return 0; } if (!test_bit(CNSS_DEV_ERR_NOTIFY, &plat_priv->driver_state)) { mod_timer(&plat_priv->fw_boot_timer, jiffies + msecs_to_jiffies(FW_ASSERT_TIMEOUT)); } return 0; } int cnss_force_fw_assert(struct device *dev) { struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev); if (!plat_priv) { cnss_pr_err("plat_priv is NULL\n"); return -ENODEV; } if (plat_priv->device_id == QCA6174_DEVICE_ID) { cnss_pr_info("Forced FW assert is not supported\n"); return -EINVAL; } if (test_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state)) { cnss_pr_info("Recovery is already in progress, ignore forced FW assert\n"); return 0; } cnss_driver_event_post(plat_priv, CNSS_DRIVER_EVENT_FORCE_FW_ASSERT, false, NULL); return 0; } EXPORT_SYMBOL(cnss_force_fw_assert); void fw_boot_timeout(unsigned long data) void fw_boot_timeout(unsigned long data) { { struct cnss_plat_data *plat_priv = (struct cnss_plat_data *)data; struct cnss_plat_data *plat_priv = (struct cnss_plat_data *)data; Loading Loading @@ -1673,6 +1725,9 @@ static void cnss_driver_event_work(struct work_struct *work) ret = cnss_driver_recovery_hdlr(plat_priv, ret = cnss_driver_recovery_hdlr(plat_priv, event->data); event->data); break; break; case CNSS_DRIVER_EVENT_FORCE_FW_ASSERT: ret = cnss_force_fw_assert_hdlr(plat_priv); break; default: default: cnss_pr_err("Invalid driver event type: %d", cnss_pr_err("Invalid driver event type: %d", event->type); event->type); Loading drivers/net/wireless/cnss2/main.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -125,6 +125,7 @@ enum cnss_driver_event_type { CNSS_DRIVER_EVENT_REGISTER_DRIVER, CNSS_DRIVER_EVENT_REGISTER_DRIVER, CNSS_DRIVER_EVENT_UNREGISTER_DRIVER, CNSS_DRIVER_EVENT_UNREGISTER_DRIVER, CNSS_DRIVER_EVENT_RECOVERY, CNSS_DRIVER_EVENT_RECOVERY, CNSS_DRIVER_EVENT_FORCE_FW_ASSERT, CNSS_DRIVER_EVENT_MAX, CNSS_DRIVER_EVENT_MAX, }; }; Loading drivers/net/wireless/cnss2/pci.c +6 −0 Original line number Original line Diff line number Diff line Loading @@ -1032,6 +1032,8 @@ static char *cnss_mhi_state_to_str(enum cnss_mhi_state mhi_state) return "SUSPEND"; return "SUSPEND"; case CNSS_MHI_RESUME: case CNSS_MHI_RESUME: return "RESUME"; return "RESUME"; case CNSS_MHI_TRIGGER_RDDM: return "TRIGGER_RDDM"; case CNSS_MHI_RDDM: case CNSS_MHI_RDDM: return "RDDM"; return "RDDM"; case CNSS_MHI_RDDM_KERNEL_PANIC: case CNSS_MHI_RDDM_KERNEL_PANIC: Loading Loading @@ -1193,6 +1195,8 @@ static enum mhi_dev_ctrl cnss_to_mhi_dev_state(enum cnss_mhi_state state) return MHI_DEV_CTRL_SUSPEND; return MHI_DEV_CTRL_SUSPEND; case CNSS_MHI_RESUME: case CNSS_MHI_RESUME: return MHI_DEV_CTRL_RESUME; return MHI_DEV_CTRL_RESUME; case CNSS_MHI_TRIGGER_RDDM: return MHI_DEV_CTRL_TRIGGER_RDDM; case CNSS_MHI_RDDM: case CNSS_MHI_RDDM: return MHI_DEV_CTRL_RDDM; return MHI_DEV_CTRL_RDDM; case CNSS_MHI_RDDM_KERNEL_PANIC: case CNSS_MHI_RDDM_KERNEL_PANIC: Loading Loading @@ -1229,6 +1233,7 @@ static int cnss_pci_check_mhi_state_bit(struct cnss_pci_data *pci_priv, if (test_bit(CNSS_MHI_SUSPEND, &pci_priv->mhi_state)) if (test_bit(CNSS_MHI_SUSPEND, &pci_priv->mhi_state)) return 0; return 0; break; break; case CNSS_MHI_TRIGGER_RDDM: case CNSS_MHI_RDDM: case CNSS_MHI_RDDM: case CNSS_MHI_RDDM_KERNEL_PANIC: case CNSS_MHI_RDDM_KERNEL_PANIC: case CNSS_MHI_NOTIFY_LINK_ERROR: case CNSS_MHI_NOTIFY_LINK_ERROR: Loading Loading @@ -1267,6 +1272,7 @@ static void cnss_pci_set_mhi_state_bit(struct cnss_pci_data *pci_priv, case CNSS_MHI_RESUME: case CNSS_MHI_RESUME: clear_bit(CNSS_MHI_SUSPEND, &pci_priv->mhi_state); clear_bit(CNSS_MHI_SUSPEND, &pci_priv->mhi_state); break; break; case CNSS_MHI_TRIGGER_RDDM: case CNSS_MHI_RDDM: case CNSS_MHI_RDDM: case CNSS_MHI_RDDM_KERNEL_PANIC: case CNSS_MHI_RDDM_KERNEL_PANIC: case CNSS_MHI_NOTIFY_LINK_ERROR: case CNSS_MHI_NOTIFY_LINK_ERROR: Loading drivers/net/wireless/cnss2/pci.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -38,6 +38,7 @@ enum cnss_mhi_state { CNSS_MHI_RESUME, CNSS_MHI_RESUME, CNSS_MHI_POWER_OFF, CNSS_MHI_POWER_OFF, CNSS_MHI_POWER_ON, CNSS_MHI_POWER_ON, CNSS_MHI_TRIGGER_RDDM, CNSS_MHI_RDDM, CNSS_MHI_RDDM, CNSS_MHI_RDDM_KERNEL_PANIC, CNSS_MHI_RDDM_KERNEL_PANIC, CNSS_MHI_NOTIFY_LINK_ERROR, CNSS_MHI_NOTIFY_LINK_ERROR, Loading include/net/cnss2.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -145,6 +145,7 @@ extern void cnss_schedule_recovery(struct device *dev, enum cnss_recovery_reason reason); enum cnss_recovery_reason reason); extern int cnss_self_recovery(struct device *dev, extern int cnss_self_recovery(struct device *dev, enum cnss_recovery_reason reason); enum cnss_recovery_reason reason); extern int cnss_force_fw_assert(struct device *dev); extern void *cnss_get_virt_ramdump_mem(unsigned long *size); extern void *cnss_get_virt_ramdump_mem(unsigned long *size); extern int cnss_get_fw_files_for_target(struct cnss_fw_files *pfw_files, extern int cnss_get_fw_files_for_target(struct cnss_fw_files *pfw_files, u32 target_type, u32 target_version); u32 target_type, u32 target_version); Loading Loading
drivers/net/wireless/cnss2/main.c +55 −0 Original line number Original line Diff line number Diff line Loading @@ -35,6 +35,7 @@ #define WLAN_RECOVERY_DELAY 1000 #define WLAN_RECOVERY_DELAY 1000 #define FILE_SYSTEM_READY 1 #define FILE_SYSTEM_READY 1 #define FW_READY_TIMEOUT 20000 #define FW_READY_TIMEOUT 20000 #define FW_ASSERT_TIMEOUT 5000 #define CNSS_EVENT_PENDING 2989 #define CNSS_EVENT_PENDING 2989 static struct cnss_plat_data *plat_env; static struct cnss_plat_data *plat_env; Loading Loading @@ -665,6 +666,8 @@ static char *cnss_driver_event_to_str(enum cnss_driver_event_type type) return "UNREGISTER_DRIVER"; return "UNREGISTER_DRIVER"; case CNSS_DRIVER_EVENT_RECOVERY: case CNSS_DRIVER_EVENT_RECOVERY: return "RECOVERY"; return "RECOVERY"; case CNSS_DRIVER_EVENT_FORCE_FW_ASSERT: return "FORCE_FW_ASSERT"; case CNSS_DRIVER_EVENT_MAX: case CNSS_DRIVER_EVENT_MAX: return "EVENT_MAX"; return "EVENT_MAX"; } } Loading Loading @@ -1545,6 +1548,55 @@ void cnss_schedule_recovery(struct device *dev, } } EXPORT_SYMBOL(cnss_schedule_recovery); EXPORT_SYMBOL(cnss_schedule_recovery); static int cnss_force_fw_assert_hdlr(struct cnss_plat_data *plat_priv) { struct cnss_pci_data *pci_priv = plat_priv->bus_priv; int ret; ret = cnss_pci_set_mhi_state(plat_priv->bus_priv, CNSS_MHI_TRIGGER_RDDM); if (ret) { cnss_pr_err("Failed to trigger RDDM, err = %d\n", ret); cnss_schedule_recovery(&pci_priv->pci_dev->dev, CNSS_REASON_DEFAULT); return 0; } if (!test_bit(CNSS_DEV_ERR_NOTIFY, &plat_priv->driver_state)) { mod_timer(&plat_priv->fw_boot_timer, jiffies + msecs_to_jiffies(FW_ASSERT_TIMEOUT)); } return 0; } int cnss_force_fw_assert(struct device *dev) { struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev); if (!plat_priv) { cnss_pr_err("plat_priv is NULL\n"); return -ENODEV; } if (plat_priv->device_id == QCA6174_DEVICE_ID) { cnss_pr_info("Forced FW assert is not supported\n"); return -EINVAL; } if (test_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state)) { cnss_pr_info("Recovery is already in progress, ignore forced FW assert\n"); return 0; } cnss_driver_event_post(plat_priv, CNSS_DRIVER_EVENT_FORCE_FW_ASSERT, false, NULL); return 0; } EXPORT_SYMBOL(cnss_force_fw_assert); void fw_boot_timeout(unsigned long data) void fw_boot_timeout(unsigned long data) { { struct cnss_plat_data *plat_priv = (struct cnss_plat_data *)data; struct cnss_plat_data *plat_priv = (struct cnss_plat_data *)data; Loading Loading @@ -1673,6 +1725,9 @@ static void cnss_driver_event_work(struct work_struct *work) ret = cnss_driver_recovery_hdlr(plat_priv, ret = cnss_driver_recovery_hdlr(plat_priv, event->data); event->data); break; break; case CNSS_DRIVER_EVENT_FORCE_FW_ASSERT: ret = cnss_force_fw_assert_hdlr(plat_priv); break; default: default: cnss_pr_err("Invalid driver event type: %d", cnss_pr_err("Invalid driver event type: %d", event->type); event->type); Loading
drivers/net/wireless/cnss2/main.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -125,6 +125,7 @@ enum cnss_driver_event_type { CNSS_DRIVER_EVENT_REGISTER_DRIVER, CNSS_DRIVER_EVENT_REGISTER_DRIVER, CNSS_DRIVER_EVENT_UNREGISTER_DRIVER, CNSS_DRIVER_EVENT_UNREGISTER_DRIVER, CNSS_DRIVER_EVENT_RECOVERY, CNSS_DRIVER_EVENT_RECOVERY, CNSS_DRIVER_EVENT_FORCE_FW_ASSERT, CNSS_DRIVER_EVENT_MAX, CNSS_DRIVER_EVENT_MAX, }; }; Loading
drivers/net/wireless/cnss2/pci.c +6 −0 Original line number Original line Diff line number Diff line Loading @@ -1032,6 +1032,8 @@ static char *cnss_mhi_state_to_str(enum cnss_mhi_state mhi_state) return "SUSPEND"; return "SUSPEND"; case CNSS_MHI_RESUME: case CNSS_MHI_RESUME: return "RESUME"; return "RESUME"; case CNSS_MHI_TRIGGER_RDDM: return "TRIGGER_RDDM"; case CNSS_MHI_RDDM: case CNSS_MHI_RDDM: return "RDDM"; return "RDDM"; case CNSS_MHI_RDDM_KERNEL_PANIC: case CNSS_MHI_RDDM_KERNEL_PANIC: Loading Loading @@ -1193,6 +1195,8 @@ static enum mhi_dev_ctrl cnss_to_mhi_dev_state(enum cnss_mhi_state state) return MHI_DEV_CTRL_SUSPEND; return MHI_DEV_CTRL_SUSPEND; case CNSS_MHI_RESUME: case CNSS_MHI_RESUME: return MHI_DEV_CTRL_RESUME; return MHI_DEV_CTRL_RESUME; case CNSS_MHI_TRIGGER_RDDM: return MHI_DEV_CTRL_TRIGGER_RDDM; case CNSS_MHI_RDDM: case CNSS_MHI_RDDM: return MHI_DEV_CTRL_RDDM; return MHI_DEV_CTRL_RDDM; case CNSS_MHI_RDDM_KERNEL_PANIC: case CNSS_MHI_RDDM_KERNEL_PANIC: Loading Loading @@ -1229,6 +1233,7 @@ static int cnss_pci_check_mhi_state_bit(struct cnss_pci_data *pci_priv, if (test_bit(CNSS_MHI_SUSPEND, &pci_priv->mhi_state)) if (test_bit(CNSS_MHI_SUSPEND, &pci_priv->mhi_state)) return 0; return 0; break; break; case CNSS_MHI_TRIGGER_RDDM: case CNSS_MHI_RDDM: case CNSS_MHI_RDDM: case CNSS_MHI_RDDM_KERNEL_PANIC: case CNSS_MHI_RDDM_KERNEL_PANIC: case CNSS_MHI_NOTIFY_LINK_ERROR: case CNSS_MHI_NOTIFY_LINK_ERROR: Loading Loading @@ -1267,6 +1272,7 @@ static void cnss_pci_set_mhi_state_bit(struct cnss_pci_data *pci_priv, case CNSS_MHI_RESUME: case CNSS_MHI_RESUME: clear_bit(CNSS_MHI_SUSPEND, &pci_priv->mhi_state); clear_bit(CNSS_MHI_SUSPEND, &pci_priv->mhi_state); break; break; case CNSS_MHI_TRIGGER_RDDM: case CNSS_MHI_RDDM: case CNSS_MHI_RDDM: case CNSS_MHI_RDDM_KERNEL_PANIC: case CNSS_MHI_RDDM_KERNEL_PANIC: case CNSS_MHI_NOTIFY_LINK_ERROR: case CNSS_MHI_NOTIFY_LINK_ERROR: Loading
drivers/net/wireless/cnss2/pci.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -38,6 +38,7 @@ enum cnss_mhi_state { CNSS_MHI_RESUME, CNSS_MHI_RESUME, CNSS_MHI_POWER_OFF, CNSS_MHI_POWER_OFF, CNSS_MHI_POWER_ON, CNSS_MHI_POWER_ON, CNSS_MHI_TRIGGER_RDDM, CNSS_MHI_RDDM, CNSS_MHI_RDDM, CNSS_MHI_RDDM_KERNEL_PANIC, CNSS_MHI_RDDM_KERNEL_PANIC, CNSS_MHI_NOTIFY_LINK_ERROR, CNSS_MHI_NOTIFY_LINK_ERROR, Loading
include/net/cnss2.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -145,6 +145,7 @@ extern void cnss_schedule_recovery(struct device *dev, enum cnss_recovery_reason reason); enum cnss_recovery_reason reason); extern int cnss_self_recovery(struct device *dev, extern int cnss_self_recovery(struct device *dev, enum cnss_recovery_reason reason); enum cnss_recovery_reason reason); extern int cnss_force_fw_assert(struct device *dev); extern void *cnss_get_virt_ramdump_mem(unsigned long *size); extern void *cnss_get_virt_ramdump_mem(unsigned long *size); extern int cnss_get_fw_files_for_target(struct cnss_fw_files *pfw_files, extern int cnss_get_fw_files_for_target(struct cnss_fw_files *pfw_files, u32 target_type, u32 target_version); u32 target_type, u32 target_version); Loading