Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0bcae799 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "cnss2: Add support to use new ramdump APIs"

parents f5de76fd 778ebcf7
Loading
Loading
Loading
Loading
+144 −0
Original line number Diff line number Diff line
@@ -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);
}
@@ -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)
@@ -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)
+5 −1
Original line number Diff line number Diff line
@@ -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
@@ -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);
+3 −50
Original line number Diff line number Diff line
@@ -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)
@@ -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);