Loading drivers/net/wireless/cnss2/main.c +144 −0 Original line number Diff line number Diff line Loading @@ -1001,6 +1001,7 @@ static void cnss_recovery_work_handler(struct work_struct *work) panic("subsys-restart: Resetting the SoC wlan crashed\n"); cnss_bus_dev_shutdown(plat_priv); cnss_bus_dev_ramdump(plat_priv); msleep(RECOVERY_DELAY_MS); cnss_bus_dev_powerup(plat_priv); } Loading Loading @@ -1752,6 +1753,69 @@ static void cnss_destroy_ramdump_device(struct cnss_plat_data *plat_priv, { destroy_ramdump_device(ramdump_dev); } int cnss_do_ramdump(struct cnss_plat_data *plat_priv) { struct cnss_ramdump_info *ramdump_info = &plat_priv->ramdump_info; struct ramdump_segment segment; memset(&segment, 0, sizeof(segment)); segment.v_address = ramdump_info->ramdump_va; segment.size = ramdump_info->ramdump_size; return do_ramdump(ramdump_info->ramdump_dev, &segment, 1); } int cnss_do_elf_ramdump(struct cnss_plat_data *plat_priv) { struct cnss_ramdump_info_v2 *info_v2 = &plat_priv->ramdump_info_v2; struct cnss_dump_data *dump_data = &info_v2->dump_data; struct cnss_dump_seg *dump_seg = info_v2->dump_data_vaddr; struct ramdump_segment *ramdump_segs, *s; struct cnss_dump_meta_info meta_info = {0}; int i, ret = 0; ramdump_segs = kcalloc(dump_data->nentries + 1, sizeof(*ramdump_segs), GFP_KERNEL); if (!ramdump_segs) return -ENOMEM; s = ramdump_segs + 1; for (i = 0; i < dump_data->nentries; i++) { if (dump_seg->type >= CNSS_FW_DUMP_TYPE_MAX) { cnss_pr_err("Unsupported dump type: %d", dump_seg->type); continue; } if (meta_info.entry[dump_seg->type].entry_start == 0) { meta_info.entry[dump_seg->type].type = dump_seg->type; meta_info.entry[dump_seg->type].entry_start = i + 1; } meta_info.entry[dump_seg->type].entry_num++; s->address = dump_seg->address; s->v_address = dump_seg->v_address; s->size = dump_seg->size; s++; dump_seg++; } meta_info.magic = CNSS_RAMDUMP_MAGIC; meta_info.version = CNSS_RAMDUMP_VERSION; meta_info.chipset = plat_priv->device_id; meta_info.total_entries = CNSS_FW_DUMP_TYPE_MAX; ramdump_segs->v_address = &meta_info; ramdump_segs->size = sizeof(meta_info); ret = do_elf_ramdump(info_v2->ramdump_dev, ramdump_segs, dump_data->nentries + 1); kfree(ramdump_segs); return ret; } #else static int cnss_panic_handler(struct notifier_block *nb, unsigned long action, void *data) Loading Loading @@ -1801,6 +1865,86 @@ static void cnss_destroy_ramdump_device(struct cnss_plat_data *plat_priv, void *ramdump_dev) { } #ifdef CONFIG_SUBSYSTEM_RAMDUMP int cnss_do_ramdump(struct cnss_plat_data *plat_priv) { struct cnss_ramdump_info *ramdump_info = &plat_priv->ramdump_info; struct qcom_dump_segment segment; struct list_head head; INIT_LIST_HEAD(&head); memset(&segment, 0, sizeof(segment)); segment.va = ramdump_info->ramdump_va; segment.size = ramdump_info->ramdump_size; list_add(&segment.node, &head); return do_dump(&head, ramdump_info->ramdump_dev); } int cnss_do_elf_ramdump(struct cnss_plat_data *plat_priv) { struct cnss_ramdump_info_v2 *info_v2 = &plat_priv->ramdump_info_v2; struct cnss_dump_data *dump_data = &info_v2->dump_data; struct cnss_dump_seg *dump_seg = info_v2->dump_data_vaddr; struct qcom_dump_segment *seg; struct cnss_dump_meta_info meta_info = {0}; struct list_head head; int i, ret = 0; INIT_LIST_HEAD(&head); for (i = 0; i < dump_data->nentries; i++) { if (dump_seg->type >= CNSS_FW_DUMP_TYPE_MAX) { cnss_pr_err("Unsupported dump type: %d", dump_seg->type); continue; } if (meta_info.entry[dump_seg->type].entry_start == 0) { meta_info.entry[dump_seg->type].type = dump_seg->type; meta_info.entry[dump_seg->type].entry_start = i + 1; } meta_info.entry[dump_seg->type].entry_num++; seg = kcalloc(1, sizeof(*seg), GFP_KERNEL); seg->da = dump_seg->address; seg->va = dump_seg->v_address; seg->size = dump_seg->size; list_add_tail(&seg->node, &head); dump_seg++; } meta_info.magic = CNSS_RAMDUMP_MAGIC; meta_info.version = CNSS_RAMDUMP_VERSION; meta_info.chipset = plat_priv->device_id; meta_info.total_entries = CNSS_FW_DUMP_TYPE_MAX; seg = kcalloc(1, sizeof(*seg), GFP_KERNEL); seg->va = &meta_info; seg->size = sizeof(meta_info); list_add(&seg->node, &head); ret = do_elf_dump(&head, info_v2->ramdump_dev); while (!list_empty(&head)) { seg = list_first_entry(&head, struct qcom_dump_segment, node); list_del(&seg->node); kfree(seg); } return ret; } #else int cnss_do_ramdump(struct cnss_plat_data *plat_priv) { return 0; } int cnss_do_elf_ramdump(struct cnss_plat_data *plat_priv) { return 0; } #endif /* CONFIG_SUBSYSTEM_RAMDUMP */ #endif /* CONFIG_MSM_SUBSYSTEM_RESTART */ static int cnss_init_dump_entry(struct cnss_plat_data *plat_priv) Loading drivers/net/wireless/cnss2/main.h +5 −1 Original line number Diff line number Diff line Loading @@ -11,8 +11,10 @@ #include <linux/pm_qos.h> #include <net/cnss2.h> #include <soc/qcom/memory_dump.h> #ifdef CONFIG_MSM_SUBSYSTEM_RESTART #if defined(CONFIG_MSM_SUBSYSTEM_RESTART) || defined(CONFIG_SUBSYSTEM_RAMDUMP) #include <soc/qcom/ramdump.h> #endif #ifdef CONFIG_MSM_SUBSYSTEM_RESTART #include <soc/qcom/subsystem_notif.h> #include <soc/qcom/subsystem_restart.h> #endif Loading Loading @@ -446,6 +448,8 @@ int cnss_register_subsys(struct cnss_plat_data *plat_priv); void cnss_unregister_subsys(struct cnss_plat_data *plat_priv); int cnss_register_ramdump(struct cnss_plat_data *plat_priv); void cnss_unregister_ramdump(struct cnss_plat_data *plat_priv); int cnss_do_ramdump(struct cnss_plat_data *plat_priv); int cnss_do_elf_ramdump(struct cnss_plat_data *plat_priv); void cnss_set_pin_connect_status(struct cnss_plat_data *plat_priv); int cnss_get_cpr_info(struct cnss_plat_data *plat_priv); int cnss_update_cpr_info(struct cnss_plat_data *plat_priv); Loading drivers/net/wireless/cnss2/pci.c +3 −50 Original line number Diff line number Diff line Loading @@ -1905,21 +1905,14 @@ static void cnss_qca6174_crash_shutdown(struct cnss_pci_data *pci_priv) static int cnss_qca6174_ramdump(struct cnss_pci_data *pci_priv) { int ret = 0; struct cnss_plat_data *plat_priv = pci_priv->plat_priv; struct cnss_ramdump_info *ramdump_info; struct ramdump_segment segment; ramdump_info = &plat_priv->ramdump_info; if (!ramdump_info->ramdump_size) return -EINVAL; memset(&segment, 0, sizeof(segment)); segment.v_address = ramdump_info->ramdump_va; segment.size = ramdump_info->ramdump_size; ret = do_ramdump(ramdump_info->ramdump_dev, &segment, 1); return ret; return cnss_do_ramdump(plat_priv); } static int cnss_qca6290_powerup(struct cnss_pci_data *pci_priv) Loading Loading @@ -2078,53 +2071,13 @@ static int cnss_qca6290_ramdump(struct cnss_pci_data *pci_priv) struct cnss_plat_data *plat_priv = pci_priv->plat_priv; struct cnss_ramdump_info_v2 *info_v2 = &plat_priv->ramdump_info_v2; struct cnss_dump_data *dump_data = &info_v2->dump_data; struct cnss_dump_seg *dump_seg = info_v2->dump_data_vaddr; struct ramdump_segment *ramdump_segs, *s; struct cnss_dump_meta_info meta_info = {0}; int i, ret = 0; int ret = 0; if (!info_v2->dump_data_valid || dump_data->nentries == 0) return 0; ramdump_segs = kcalloc(dump_data->nentries + 1, sizeof(*ramdump_segs), GFP_KERNEL); if (!ramdump_segs) return -ENOMEM; s = ramdump_segs + 1; for (i = 0; i < dump_data->nentries; i++) { if (dump_seg->type >= CNSS_FW_DUMP_TYPE_MAX) { cnss_pr_err("Unsupported dump type: %d", dump_seg->type); continue; } if (meta_info.entry[dump_seg->type].entry_start == 0) { meta_info.entry[dump_seg->type].type = dump_seg->type; meta_info.entry[dump_seg->type].entry_start = i + 1; } meta_info.entry[dump_seg->type].entry_num++; s->address = dump_seg->address; s->v_address = dump_seg->v_address; s->size = dump_seg->size; s++; dump_seg++; } meta_info.magic = CNSS_RAMDUMP_MAGIC; meta_info.version = CNSS_RAMDUMP_VERSION; meta_info.chipset = pci_priv->device_id; meta_info.total_entries = CNSS_FW_DUMP_TYPE_MAX; ramdump_segs->v_address = &meta_info; ramdump_segs->size = sizeof(meta_info); ret = do_elf_ramdump(info_v2->ramdump_dev, ramdump_segs, dump_data->nentries + 1); kfree(ramdump_segs); ret = cnss_do_elf_ramdump(plat_priv); cnss_pci_clear_dump_info(pci_priv); cnss_pci_deinit_mhi(pci_priv); Loading Loading
drivers/net/wireless/cnss2/main.c +144 −0 Original line number Diff line number Diff line Loading @@ -1001,6 +1001,7 @@ static void cnss_recovery_work_handler(struct work_struct *work) panic("subsys-restart: Resetting the SoC wlan crashed\n"); cnss_bus_dev_shutdown(plat_priv); cnss_bus_dev_ramdump(plat_priv); msleep(RECOVERY_DELAY_MS); cnss_bus_dev_powerup(plat_priv); } Loading Loading @@ -1752,6 +1753,69 @@ static void cnss_destroy_ramdump_device(struct cnss_plat_data *plat_priv, { destroy_ramdump_device(ramdump_dev); } int cnss_do_ramdump(struct cnss_plat_data *plat_priv) { struct cnss_ramdump_info *ramdump_info = &plat_priv->ramdump_info; struct ramdump_segment segment; memset(&segment, 0, sizeof(segment)); segment.v_address = ramdump_info->ramdump_va; segment.size = ramdump_info->ramdump_size; return do_ramdump(ramdump_info->ramdump_dev, &segment, 1); } int cnss_do_elf_ramdump(struct cnss_plat_data *plat_priv) { struct cnss_ramdump_info_v2 *info_v2 = &plat_priv->ramdump_info_v2; struct cnss_dump_data *dump_data = &info_v2->dump_data; struct cnss_dump_seg *dump_seg = info_v2->dump_data_vaddr; struct ramdump_segment *ramdump_segs, *s; struct cnss_dump_meta_info meta_info = {0}; int i, ret = 0; ramdump_segs = kcalloc(dump_data->nentries + 1, sizeof(*ramdump_segs), GFP_KERNEL); if (!ramdump_segs) return -ENOMEM; s = ramdump_segs + 1; for (i = 0; i < dump_data->nentries; i++) { if (dump_seg->type >= CNSS_FW_DUMP_TYPE_MAX) { cnss_pr_err("Unsupported dump type: %d", dump_seg->type); continue; } if (meta_info.entry[dump_seg->type].entry_start == 0) { meta_info.entry[dump_seg->type].type = dump_seg->type; meta_info.entry[dump_seg->type].entry_start = i + 1; } meta_info.entry[dump_seg->type].entry_num++; s->address = dump_seg->address; s->v_address = dump_seg->v_address; s->size = dump_seg->size; s++; dump_seg++; } meta_info.magic = CNSS_RAMDUMP_MAGIC; meta_info.version = CNSS_RAMDUMP_VERSION; meta_info.chipset = plat_priv->device_id; meta_info.total_entries = CNSS_FW_DUMP_TYPE_MAX; ramdump_segs->v_address = &meta_info; ramdump_segs->size = sizeof(meta_info); ret = do_elf_ramdump(info_v2->ramdump_dev, ramdump_segs, dump_data->nentries + 1); kfree(ramdump_segs); return ret; } #else static int cnss_panic_handler(struct notifier_block *nb, unsigned long action, void *data) Loading Loading @@ -1801,6 +1865,86 @@ static void cnss_destroy_ramdump_device(struct cnss_plat_data *plat_priv, void *ramdump_dev) { } #ifdef CONFIG_SUBSYSTEM_RAMDUMP int cnss_do_ramdump(struct cnss_plat_data *plat_priv) { struct cnss_ramdump_info *ramdump_info = &plat_priv->ramdump_info; struct qcom_dump_segment segment; struct list_head head; INIT_LIST_HEAD(&head); memset(&segment, 0, sizeof(segment)); segment.va = ramdump_info->ramdump_va; segment.size = ramdump_info->ramdump_size; list_add(&segment.node, &head); return do_dump(&head, ramdump_info->ramdump_dev); } int cnss_do_elf_ramdump(struct cnss_plat_data *plat_priv) { struct cnss_ramdump_info_v2 *info_v2 = &plat_priv->ramdump_info_v2; struct cnss_dump_data *dump_data = &info_v2->dump_data; struct cnss_dump_seg *dump_seg = info_v2->dump_data_vaddr; struct qcom_dump_segment *seg; struct cnss_dump_meta_info meta_info = {0}; struct list_head head; int i, ret = 0; INIT_LIST_HEAD(&head); for (i = 0; i < dump_data->nentries; i++) { if (dump_seg->type >= CNSS_FW_DUMP_TYPE_MAX) { cnss_pr_err("Unsupported dump type: %d", dump_seg->type); continue; } if (meta_info.entry[dump_seg->type].entry_start == 0) { meta_info.entry[dump_seg->type].type = dump_seg->type; meta_info.entry[dump_seg->type].entry_start = i + 1; } meta_info.entry[dump_seg->type].entry_num++; seg = kcalloc(1, sizeof(*seg), GFP_KERNEL); seg->da = dump_seg->address; seg->va = dump_seg->v_address; seg->size = dump_seg->size; list_add_tail(&seg->node, &head); dump_seg++; } meta_info.magic = CNSS_RAMDUMP_MAGIC; meta_info.version = CNSS_RAMDUMP_VERSION; meta_info.chipset = plat_priv->device_id; meta_info.total_entries = CNSS_FW_DUMP_TYPE_MAX; seg = kcalloc(1, sizeof(*seg), GFP_KERNEL); seg->va = &meta_info; seg->size = sizeof(meta_info); list_add(&seg->node, &head); ret = do_elf_dump(&head, info_v2->ramdump_dev); while (!list_empty(&head)) { seg = list_first_entry(&head, struct qcom_dump_segment, node); list_del(&seg->node); kfree(seg); } return ret; } #else int cnss_do_ramdump(struct cnss_plat_data *plat_priv) { return 0; } int cnss_do_elf_ramdump(struct cnss_plat_data *plat_priv) { return 0; } #endif /* CONFIG_SUBSYSTEM_RAMDUMP */ #endif /* CONFIG_MSM_SUBSYSTEM_RESTART */ static int cnss_init_dump_entry(struct cnss_plat_data *plat_priv) Loading
drivers/net/wireless/cnss2/main.h +5 −1 Original line number Diff line number Diff line Loading @@ -11,8 +11,10 @@ #include <linux/pm_qos.h> #include <net/cnss2.h> #include <soc/qcom/memory_dump.h> #ifdef CONFIG_MSM_SUBSYSTEM_RESTART #if defined(CONFIG_MSM_SUBSYSTEM_RESTART) || defined(CONFIG_SUBSYSTEM_RAMDUMP) #include <soc/qcom/ramdump.h> #endif #ifdef CONFIG_MSM_SUBSYSTEM_RESTART #include <soc/qcom/subsystem_notif.h> #include <soc/qcom/subsystem_restart.h> #endif Loading Loading @@ -446,6 +448,8 @@ int cnss_register_subsys(struct cnss_plat_data *plat_priv); void cnss_unregister_subsys(struct cnss_plat_data *plat_priv); int cnss_register_ramdump(struct cnss_plat_data *plat_priv); void cnss_unregister_ramdump(struct cnss_plat_data *plat_priv); int cnss_do_ramdump(struct cnss_plat_data *plat_priv); int cnss_do_elf_ramdump(struct cnss_plat_data *plat_priv); void cnss_set_pin_connect_status(struct cnss_plat_data *plat_priv); int cnss_get_cpr_info(struct cnss_plat_data *plat_priv); int cnss_update_cpr_info(struct cnss_plat_data *plat_priv); Loading
drivers/net/wireless/cnss2/pci.c +3 −50 Original line number Diff line number Diff line Loading @@ -1905,21 +1905,14 @@ static void cnss_qca6174_crash_shutdown(struct cnss_pci_data *pci_priv) static int cnss_qca6174_ramdump(struct cnss_pci_data *pci_priv) { int ret = 0; struct cnss_plat_data *plat_priv = pci_priv->plat_priv; struct cnss_ramdump_info *ramdump_info; struct ramdump_segment segment; ramdump_info = &plat_priv->ramdump_info; if (!ramdump_info->ramdump_size) return -EINVAL; memset(&segment, 0, sizeof(segment)); segment.v_address = ramdump_info->ramdump_va; segment.size = ramdump_info->ramdump_size; ret = do_ramdump(ramdump_info->ramdump_dev, &segment, 1); return ret; return cnss_do_ramdump(plat_priv); } static int cnss_qca6290_powerup(struct cnss_pci_data *pci_priv) Loading Loading @@ -2078,53 +2071,13 @@ static int cnss_qca6290_ramdump(struct cnss_pci_data *pci_priv) struct cnss_plat_data *plat_priv = pci_priv->plat_priv; struct cnss_ramdump_info_v2 *info_v2 = &plat_priv->ramdump_info_v2; struct cnss_dump_data *dump_data = &info_v2->dump_data; struct cnss_dump_seg *dump_seg = info_v2->dump_data_vaddr; struct ramdump_segment *ramdump_segs, *s; struct cnss_dump_meta_info meta_info = {0}; int i, ret = 0; int ret = 0; if (!info_v2->dump_data_valid || dump_data->nentries == 0) return 0; ramdump_segs = kcalloc(dump_data->nentries + 1, sizeof(*ramdump_segs), GFP_KERNEL); if (!ramdump_segs) return -ENOMEM; s = ramdump_segs + 1; for (i = 0; i < dump_data->nentries; i++) { if (dump_seg->type >= CNSS_FW_DUMP_TYPE_MAX) { cnss_pr_err("Unsupported dump type: %d", dump_seg->type); continue; } if (meta_info.entry[dump_seg->type].entry_start == 0) { meta_info.entry[dump_seg->type].type = dump_seg->type; meta_info.entry[dump_seg->type].entry_start = i + 1; } meta_info.entry[dump_seg->type].entry_num++; s->address = dump_seg->address; s->v_address = dump_seg->v_address; s->size = dump_seg->size; s++; dump_seg++; } meta_info.magic = CNSS_RAMDUMP_MAGIC; meta_info.version = CNSS_RAMDUMP_VERSION; meta_info.chipset = pci_priv->device_id; meta_info.total_entries = CNSS_FW_DUMP_TYPE_MAX; ramdump_segs->v_address = &meta_info; ramdump_segs->size = sizeof(meta_info); ret = do_elf_ramdump(info_v2->ramdump_dev, ramdump_segs, dump_data->nentries + 1); kfree(ramdump_segs); ret = cnss_do_elf_ramdump(plat_priv); cnss_pci_clear_dump_info(pci_priv); cnss_pci_deinit_mhi(pci_priv); Loading