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

Commit 07abf74b authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "net: cnss: add subsystem restart support for dual WiFi"

parents 789fd424 d4205a2f
Loading
Loading
Loading
Loading
+121 −0
Original line number Diff line number Diff line
@@ -18,10 +18,131 @@
#include <linux/pm_wakeup.h>
#include <linux/sched.h>
#include <linux/suspend.h>
#include <linux/mutex.h>
#include <linux/rwsem.h>
#include <net/cnss.h>
#include <net/cfg80211.h>

static DEFINE_MUTEX(unsafe_channel_list_lock);
static DEFINE_MUTEX(dfs_nol_info_lock);

static struct cnss_unsafe_channel_list {
	u16 unsafe_ch_count;
	u16 unsafe_ch_list[CNSS_MAX_CH_NUM];
} unsafe_channel_list;

static struct cnss_dfs_nol_info {
	void *dfs_nol_info;
	u16 dfs_nol_info_len;
} dfs_nol_info;

int cnss_set_wlan_unsafe_channel(u16 *unsafe_ch_list, u16 ch_count)
{
	struct cnss_unsafe_channel_list *unsafe_list;

	mutex_lock(&unsafe_channel_list_lock);
	if ((!unsafe_ch_list) || (!ch_count) || (ch_count > CNSS_MAX_CH_NUM)) {
		mutex_unlock(&unsafe_channel_list_lock);
		return -EINVAL;
	}

	unsafe_list = &unsafe_channel_list;
	unsafe_channel_list.unsafe_ch_count = ch_count;

	memcpy(
		(char *)unsafe_list->unsafe_ch_list,
		(char *)unsafe_ch_list, ch_count * sizeof(u16));
	mutex_unlock(&unsafe_channel_list_lock);

	return 0;
}
EXPORT_SYMBOL(cnss_set_wlan_unsafe_channel);

int cnss_get_wlan_unsafe_channel(
			u16 *unsafe_ch_list,
			u16 *ch_count, u16 buf_len)
{
	struct cnss_unsafe_channel_list *unsafe_list;

	mutex_lock(&unsafe_channel_list_lock);
	if (!unsafe_ch_list || !ch_count) {
		mutex_unlock(&unsafe_channel_list_lock);
		return -EINVAL;
	}

	unsafe_list = &unsafe_channel_list;
	if (buf_len < (unsafe_list->unsafe_ch_count * sizeof(u16))) {
		mutex_unlock(&unsafe_channel_list_lock);
		return -ENOMEM;
	}

	*ch_count = unsafe_list->unsafe_ch_count;
	memcpy(
		(char *)unsafe_ch_list,
		(char *)unsafe_list->unsafe_ch_list,
		unsafe_list->unsafe_ch_count * sizeof(u16));
	mutex_unlock(&unsafe_channel_list_lock);

	return 0;
}
EXPORT_SYMBOL(cnss_get_wlan_unsafe_channel);

int cnss_wlan_set_dfs_nol(const void *info, u16 info_len)
{
	void *temp;
	struct cnss_dfs_nol_info *dfs_info;

	mutex_lock(&dfs_nol_info_lock);
	if (!info || !info_len) {
		mutex_unlock(&dfs_nol_info_lock);
		return -EINVAL;
	}

	temp = kmalloc(info_len, GFP_KERNEL);
	if (!temp) {
		mutex_unlock(&dfs_nol_info_lock);
		return -ENOMEM;
	}

	memcpy(temp, info, info_len);
	dfs_info = &dfs_nol_info;
	kfree(dfs_info->dfs_nol_info);

	dfs_info->dfs_nol_info = temp;
	dfs_info->dfs_nol_info_len = info_len;
	mutex_unlock(&dfs_nol_info_lock);

	return 0;
}
EXPORT_SYMBOL(cnss_wlan_set_dfs_nol);

int cnss_wlan_get_dfs_nol(void *info, u16 info_len)
{
	int len;
	struct cnss_dfs_nol_info *dfs_info;

	mutex_lock(&dfs_nol_info_lock);
	if (!info || !info_len) {
		mutex_unlock(&dfs_nol_info_lock);
		return -EINVAL;
	}

	dfs_info = &dfs_nol_info;

	if (dfs_info->dfs_nol_info == NULL || dfs_info->dfs_nol_info_len == 0) {
		mutex_unlock(&dfs_nol_info_lock);
		return -ENOENT;
	}

	len = min(info_len, dfs_info->dfs_nol_info_len);

	memcpy(info, dfs_info->dfs_nol_info, len);
	mutex_unlock(&dfs_nol_info_lock);

	return len;
}
EXPORT_SYMBOL(cnss_wlan_get_dfs_nol);

void cnss_init_work(struct work_struct *work, work_func_t func)
{
	INIT_WORK(work, func);
+120 −92
Original line number Diff line number Diff line
@@ -236,8 +236,6 @@ static struct cnss_data {
	void *ramdump_addr;
	phys_addr_t ramdump_phys;
	struct msm_dump_data dump_data;
	u16 unsafe_ch_count;
	u16 unsafe_ch_list[CNSS_MAX_CH_NUM];
	struct cnss_wlan_driver *driver;
	struct pci_dev *pdev;
	const struct pci_device_id *id;
@@ -252,7 +250,6 @@ static struct cnss_data {
	bool notify_modem_status;
	struct pci_saved_state *saved_state;
	u16 revision_id;
	u16 dfs_nol_info_len;
	bool recovery_in_progress;
	bool fw_available;
	struct codeswap_codeseg_info *cnss_seg_info;
@@ -272,7 +269,6 @@ static struct cnss_data {
	struct wakeup_source ws;
	uint32_t recovery_count;
	enum cnss_driver_status driver_status;
	void *dfs_nol_info;
#ifdef CONFIG_CNSS_SECURE_FW
	void *fw_mem;
#endif
@@ -1756,12 +1752,12 @@ static ssize_t fw_image_setup_store(struct device *dev,
static DEVICE_ATTR(fw_image_setup, S_IRUSR | S_IWUSR,
	fw_image_setup_show, fw_image_setup_store);

void recovery_work_handler(struct work_struct *recovery)
void cnss_pci_recovery_work_handler(struct work_struct *recovery)
{
	cnss_device_self_recovery();
}

DECLARE_WORK(recovery_work, recovery_work_handler);
DECLARE_WORK(recovery_work, cnss_pci_recovery_work_handler);

void cnss_schedule_recovery_work(void)
{
@@ -2167,90 +2163,6 @@ cut_power:
}
EXPORT_SYMBOL(cnss_wlan_unregister_driver);

int cnss_set_wlan_unsafe_channel(u16 *unsafe_ch_list, u16 ch_count)
{
	if (!penv)
		return -ENODEV;

	if ((!unsafe_ch_list) || (ch_count > CNSS_MAX_CH_NUM))
		return -EINVAL;

	penv->unsafe_ch_count = ch_count;

	if (ch_count != 0)
		memcpy((char *)penv->unsafe_ch_list, (char *)unsafe_ch_list,
			ch_count * sizeof(u16));

	return 0;
}
EXPORT_SYMBOL(cnss_set_wlan_unsafe_channel);

int cnss_get_wlan_unsafe_channel(u16 *unsafe_ch_list,
					u16 *ch_count, u16 buf_len)
{
	if (!penv)
		return -ENODEV;

	if (!unsafe_ch_list || !ch_count)
		return -EINVAL;

	if (buf_len < (penv->unsafe_ch_count * sizeof(u16)))
		return -ENOMEM;

	*ch_count = penv->unsafe_ch_count;
	memcpy((char *)unsafe_ch_list, (char *)penv->unsafe_ch_list,
			penv->unsafe_ch_count * sizeof(u16));

	return 0;
}
EXPORT_SYMBOL(cnss_get_wlan_unsafe_channel);

int cnss_wlan_set_dfs_nol(const void *info, u16 info_len)
{
	void *temp;

	if (!penv)
		return -ENODEV;

	if (!info || !info_len)
		return -EINVAL;

	temp = kmalloc(info_len, GFP_KERNEL);
	if (!temp)
		return -ENOMEM;

	memcpy(temp, info, info_len);

	kfree(penv->dfs_nol_info);

	penv->dfs_nol_info = temp;
	penv->dfs_nol_info_len = info_len;

	return 0;
}
EXPORT_SYMBOL(cnss_wlan_set_dfs_nol);

int cnss_wlan_get_dfs_nol(void *info, u16 info_len)
{
	int len;

	if (!penv)
		return -ENODEV;

	if (!info || !info_len)
		return -EINVAL;

	if (penv->dfs_nol_info == NULL || penv->dfs_nol_info_len == 0)
		return -ENOENT;

	len = min(info_len, penv->dfs_nol_info_len);

	memcpy(info, penv->dfs_nol_info, len);

	return len;
}
EXPORT_SYMBOL(cnss_wlan_get_dfs_nol);

#ifdef CONFIG_PCI_MSM
int cnss_wlan_pm_control(bool vote)
{
@@ -2277,6 +2189,32 @@ void cnss_release_pm_sem(void)
}
EXPORT_SYMBOL(cnss_release_pm_sem);

void cnss_pci_schedule_recovery_work(void)
{
	schedule_work(&recovery_work);
}
EXPORT_SYMBOL(cnss_pci_schedule_recovery_work);

void *cnss_pci_get_virt_ramdump_mem(unsigned long *size)
{
	if (!penv || !penv->pldev)
		return NULL;

	*size = penv->ramdump_size;

	return penv->ramdump_addr;
}
EXPORT_SYMBOL(cnss_pci_get_virt_ramdump_mem);

void cnss_pci_device_crashed(void)
{
	if (penv && penv->subsys) {
		subsys_set_crash_status(penv->subsys, true);
		subsystem_restart_dev(penv->subsys);
	}
}
EXPORT_SYMBOL(cnss_pci_device_crashed);

int cnss_get_ramdump_mem(unsigned long *address, unsigned long *size)
{
	if (!penv || !penv->pldev)
@@ -2452,6 +2390,32 @@ err_wlan_vreg_on:
	return ret;
}

void cnss_pci_device_self_recovery(void)
{
	if (!penv)
		return;

	if (penv->recovery_in_progress) {
		pr_err("cnss: Recovery already in progress\n");
		return;
	}

	if (penv->driver_status == CNSS_LOAD_UNLOAD) {
		pr_err("cnss: load unload in progress\n");
		return;
	}

	penv->recovery_count++;
	penv->recovery_in_progress = true;
	cnss_pm_wake_lock(&penv->ws);
	cnss_shutdown(NULL, false);
	msleep(WLAN_RECOVERY_DELAY);
	cnss_powerup(NULL);
	cnss_pm_wake_lock_release(&penv->ws);
	penv->recovery_in_progress = false;
}
EXPORT_SYMBOL(cnss_pci_device_self_recovery);

static int cnss_ramdump(int enable, const struct subsys_desc *subsys)
{
	struct ramdump_segment segment;
@@ -2805,8 +2769,6 @@ static int cnss_remove(struct platform_device *pdev)

	cnss_pm_wake_lock_destroy(&penv->ws);

	kfree(penv->dfs_nol_info);

	if (penv->bus_client)
		msm_bus_scale_unregister_client(penv->bus_client);

@@ -2900,6 +2862,72 @@ void cnss_remove_pm_qos(void)
}
EXPORT_SYMBOL(cnss_remove_pm_qos);

void cnss_pci_request_pm_qos_type(int latency_type, u32 qos_val)
{
	if (!penv) {
		pr_err("%s: penv is NULL\n", __func__);
		return;
	}

	pm_qos_add_request(&penv->qos_request, latency_type, qos_val);
}
EXPORT_SYMBOL(cnss_pci_request_pm_qos_type);

void cnss_pci_request_pm_qos(u32 qos_val)
{
	if (!penv) {
		pr_err("%s: penv is NULL\n", __func__);
		return;
	}

	pm_qos_add_request(&penv->qos_request, PM_QOS_CPU_DMA_LATENCY, qos_val);
}
EXPORT_SYMBOL(cnss_pci_request_pm_qos);

void cnss_pci_remove_pm_qos(void)
{
	if (!penv) {
		pr_err("%s: penv is NULL\n", __func__);
		return;
	}

	pm_qos_remove_request(&penv->qos_request);
}
EXPORT_SYMBOL(cnss_pci_remove_pm_qos);

int cnss_pci_request_bus_bandwidth(int bandwidth)
{
	int ret = 0;

	if (!penv)
		return -ENODEV;

	if (!penv->bus_client)
		return -ENOSYS;

	switch (bandwidth) {
	case CNSS_BUS_WIDTH_NONE:
	case CNSS_BUS_WIDTH_LOW:
	case CNSS_BUS_WIDTH_MEDIUM:
	case CNSS_BUS_WIDTH_HIGH:
		ret = msm_bus_scale_client_update_request(
				penv->bus_client, bandwidth);
		if (!ret) {
			penv->current_bandwidth_vote = bandwidth;
		} else {
			pr_err("%s: could not set bus bandwidth %d, ret = %d\n",
			       __func__, bandwidth, ret);
		}
		break;

	default:
		pr_err("%s: Invalid request %d", __func__, bandwidth);
		ret = -EINVAL;
	}
	return ret;
}
EXPORT_SYMBOL(cnss_pci_request_bus_bandwidth);

int cnss_request_bus_bandwidth(int bandwidth)
{
	int ret = 0;
+72 −107
Original line number Diff line number Diff line
@@ -45,16 +45,6 @@
#define CNSS_DUMP_MAGIC_VER_V2	0x42445953
#define CNSS_DUMP_NAME		"CNSS_WLAN"

struct cnss_unsafe_channel_list {
	u16 unsafe_ch_count;
	u16 unsafe_ch_list[CNSS_MAX_CH_NUM];
};

struct cnss_dfs_nol_info {
	void *dfs_nol_info;
	u16 dfs_nol_info_len;
};

struct cnss_sdio_regulator {
	struct regulator *wlan_io;
	struct regulator *wlan_xtal;
@@ -84,8 +74,6 @@ struct cnss_ssr_info {
static struct cnss_sdio_data {
	struct cnss_sdio_regulator regulator;
	struct platform_device *pdev;
	struct cnss_dfs_nol_info dfs_info;
	struct cnss_unsafe_channel_list unsafe_list;
	struct cnss_sdio_info cnss_sdio_info;
	struct cnss_ssr_info ssr_info;
	struct pm_qos_request qos_request;
@@ -137,13 +125,7 @@ static const struct sdio_device_id ar6k_id_table[] = {
};
MODULE_DEVICE_TABLE(sdio, ar6k_id_table);

int cnss_request_bus_bandwidth(int bandwidth)
{
	return 0;
}
EXPORT_SYMBOL(cnss_request_bus_bandwidth);

void cnss_request_pm_qos_type(int latency_type, u32 qos_val)
void cnss_sdio_request_pm_qos_type(int latency_type, u32 qos_val)
{
	if (!cnss_pdata)
		return;
@@ -151,9 +133,15 @@ void cnss_request_pm_qos_type(int latency_type, u32 qos_val)
	pr_debug("%s: PM QoS value: %d\n", __func__, qos_val);
	pm_qos_add_request(&cnss_pdata->qos_request, latency_type, qos_val);
}
EXPORT_SYMBOL(cnss_request_pm_qos_type);
EXPORT_SYMBOL(cnss_sdio_request_pm_qos_type);

void cnss_request_pm_qos(u32 qos_val)
int cnss_sdio_request_bus_bandwidth(int bandwidth)
{
	return 0;
}
EXPORT_SYMBOL(cnss_sdio_request_bus_bandwidth);

void cnss_sdio_request_pm_qos(u32 qos_val)
{
	if (!cnss_pdata)
		return;
@@ -163,9 +151,9 @@ void cnss_request_pm_qos(u32 qos_val)
		&cnss_pdata->qos_request,
		PM_QOS_CPU_DMA_LATENCY, qos_val);
}
EXPORT_SYMBOL(cnss_request_pm_qos);
EXPORT_SYMBOL(cnss_sdio_request_pm_qos);

void cnss_remove_pm_qos(void)
void cnss_sdio_remove_pm_qos(void)
{
	if (!cnss_pdata)
		return;
@@ -173,103 +161,45 @@ void cnss_remove_pm_qos(void)
	pm_qos_remove_request(&cnss_pdata->qos_request);
	pr_debug("%s: PM QoS removed\n", __func__);
}
EXPORT_SYMBOL(cnss_remove_pm_qos);
EXPORT_SYMBOL(cnss_sdio_remove_pm_qos);

int cnss_set_wlan_unsafe_channel(u16 *unsafe_ch_list, u16 ch_count)
int cnss_request_bus_bandwidth(int bandwidth)
{
	struct cnss_unsafe_channel_list *unsafe_list;

	if (!cnss_pdata)
		return -ENODEV;

	if ((!unsafe_ch_list) || (!ch_count) || (ch_count > CNSS_MAX_CH_NUM))
		return -EINVAL;

	unsafe_list = &cnss_pdata->unsafe_list;
	unsafe_list->unsafe_ch_count = ch_count;

	memcpy(
		(char *)unsafe_list->unsafe_ch_list,
		(char *)unsafe_ch_list, ch_count * sizeof(u16));

	return 0;
}
EXPORT_SYMBOL(cnss_set_wlan_unsafe_channel);
EXPORT_SYMBOL(cnss_request_bus_bandwidth);

int cnss_get_wlan_unsafe_channel(
	u16 *unsafe_ch_list, u16 *ch_count, u16 buf_len)
void cnss_request_pm_qos_type(int latency_type, u32 qos_val)
{
	struct cnss_unsafe_channel_list *unsafe_list;

	if (!cnss_pdata)
		return -ENODEV;

	if (!unsafe_ch_list || !ch_count)
		return -EINVAL;

	unsafe_list = &cnss_pdata->unsafe_list;

	if (buf_len < (unsafe_list->unsafe_ch_count * sizeof(u16)))
		return -ENOMEM;

	*ch_count = unsafe_list->unsafe_ch_count;
	memcpy(
		(char *)unsafe_ch_list, (char *)unsafe_list->unsafe_ch_list,
		unsafe_list->unsafe_ch_count * sizeof(u16));
		return;

	return 0;
	pr_debug("%s: PM QoS value: %d\n", __func__, qos_val);
	pm_qos_add_request(&cnss_pdata->qos_request, latency_type, qos_val);
}
EXPORT_SYMBOL(cnss_get_wlan_unsafe_channel);
EXPORT_SYMBOL(cnss_request_pm_qos_type);

int cnss_wlan_set_dfs_nol(const void *info, u16 info_len)
void cnss_request_pm_qos(u32 qos_val)
{
	void *temp;
	struct cnss_dfs_nol_info *dfs_info;

	if (!cnss_pdata)
		return -ENODEV;

	if (!info || !info_len)
		return -EINVAL;

	temp = kmalloc(info_len, GFP_KERNEL);
	if (!temp)
		return -ENOMEM;

	memcpy(temp, info, info_len);
	dfs_info = &cnss_pdata->dfs_info;
	kfree(dfs_info->dfs_nol_info);

	dfs_info->dfs_nol_info = temp;
	dfs_info->dfs_nol_info_len = info_len;
		return;

	return 0;
	pr_debug("%s: PM QoS value: %d\n", __func__, qos_val);
	pm_qos_add_request(
		&cnss_pdata->qos_request,
		PM_QOS_CPU_DMA_LATENCY, qos_val);
}
EXPORT_SYMBOL(cnss_wlan_set_dfs_nol);
EXPORT_SYMBOL(cnss_request_pm_qos);

int cnss_wlan_get_dfs_nol(void *info, u16 info_len)
void cnss_remove_pm_qos(void)
{
	int len;
	struct cnss_dfs_nol_info *dfs_info;

	if (!cnss_pdata)
		return -ENODEV;

	if (!info || !info_len)
		return -EINVAL;

	dfs_info = &cnss_pdata->dfs_info;

	if (dfs_info->dfs_nol_info == NULL || dfs_info->dfs_nol_info_len == 0)
		return -ENOENT;

	len = min(info_len, dfs_info->dfs_nol_info_len);

	memcpy(info, dfs_info->dfs_nol_info, len);
		return;

	return len;
	pm_qos_remove_request(&cnss_pdata->qos_request);
	pr_debug("%s: PM QoS removed\n", __func__);
}
EXPORT_SYMBOL(cnss_wlan_get_dfs_nol);
EXPORT_SYMBOL(cnss_remove_pm_qos);

static int cnss_sdio_shutdown(const struct subsys_desc *subsys, bool force_stop)
{
@@ -537,6 +467,39 @@ static void cnss_ramdump_cleanup(void)
	ssr_info->ramdump_dev = NULL;
}

void *cnss_sdio_get_virt_ramdump_mem(unsigned long *size)
{
	if (!cnss_pdata || !cnss_pdata->pdev)
		return NULL;

	*size = cnss_pdata->ssr_info.ramdump_size;

	return cnss_pdata->ssr_info.ramdump_addr;
}
EXPORT_SYMBOL(cnss_sdio_get_virt_ramdump_mem);

void cnss_sdio_device_self_recovery(void)
{
	cnss_sdio_shutdown(NULL, false);
	msleep(WLAN_RECOVERY_DELAY);
	cnss_sdio_powerup(NULL);
}
EXPORT_SYMBOL(cnss_sdio_device_self_recovery);

void cnss_sdio_device_crashed(void)
{
	struct cnss_ssr_info *ssr_info;

	if (!cnss_pdata)
		return;
	ssr_info = &cnss_pdata->ssr_info;
	if (ssr_info->subsys) {
		subsys_set_crash_status(ssr_info->subsys, true);
		subsystem_restart_dev(ssr_info->subsys);
	}
}
EXPORT_SYMBOL(cnss_sdio_device_crashed);

int cnss_get_ramdump_mem(unsigned long *address, unsigned long *size)
{
	struct cnss_ssr_info *ssr_info;
@@ -571,12 +534,18 @@ void cnss_device_self_recovery(void)
}
EXPORT_SYMBOL(cnss_device_self_recovery);

static void recovery_work_handler(struct work_struct *recovery)
static void cnss_sdio_recovery_work_handler(struct work_struct *recovery)
{
	cnss_device_self_recovery();
}

DECLARE_WORK(recovery_work, recovery_work_handler);
DECLARE_WORK(recovery_work, cnss_sdio_recovery_work_handler);

void cnss_sdio_schedule_recovery_work(void)
{
	schedule_work(&recovery_work);
}
EXPORT_SYMBOL(cnss_sdio_schedule_recovery_work);

void cnss_schedule_recovery_work(void)
{
@@ -1074,15 +1043,11 @@ err_wlan_enable_regulator:

static int cnss_sdio_remove(struct platform_device *pdev)
{
	struct cnss_dfs_nol_info *dfs_info;

	if (!cnss_pdata)
		return -ENODEV;

	cnss_sdio_wlan_exit();

	dfs_info = &cnss_pdata->dfs_info;
	kfree(dfs_info->dfs_nol_info);
	cnss_subsys_exit();
	cnss_ramdump_cleanup();
	cnss_sdio_release_resource();
+24 −0
Original line number Diff line number Diff line
@@ -122,6 +122,8 @@ extern void cnss_wlan_unregister_driver(struct cnss_wlan_driver *driver);
extern int cnss_get_fw_files(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);
extern int cnss_pci_request_bus_bandwidth(int bandwidth);
extern int cnss_sdio_request_bus_bandwidth(int bandwidth);
extern int cnss_request_bus_bandwidth(int bandwidth);

extern int cnss_get_sha_hash(const u8 *data, u32 data_len,
@@ -140,6 +142,15 @@ extern void cnss_release_pm_sem(void);
extern void cnss_request_pm_qos_type(int latency_type, u32 qos_val);
extern void cnss_request_pm_qos(u32 qos_val);
extern void cnss_remove_pm_qos(void);

extern void cnss_pci_request_pm_qos_type(int latency_type, u32 qos_val);
extern void cnss_pci_request_pm_qos(u32 qos_val);
extern void cnss_pci_remove_pm_qos(void);

extern void cnss_sdio_request_pm_qos_type(int latency_type, u32 qos_val);
extern void cnss_sdio_request_pm_qos(u32 qos_val);
extern void cnss_sdio_remove_pm_qos(void);

extern int cnss_get_platform_cap(struct cnss_platform_cap *cap);
extern void cnss_set_driver_status(enum cnss_driver_status driver_status);

@@ -184,11 +195,24 @@ extern int cnss_get_wlan_unsafe_channel(u16 *unsafe_ch_list,
		u16 *ch_count, u16 buf_len);
extern int cnss_wlan_set_dfs_nol(const void *info, u16 info_len);
extern int cnss_wlan_get_dfs_nol(void *info, u16 info_len);

extern void cnss_device_crashed(void);
extern void cnss_sdio_device_crashed(void);
extern void cnss_pci_device_crashed(void);

extern void cnss_device_self_recovery(void);
extern void cnss_pci_device_self_recovery(void);
extern void cnss_sdio_device_self_recovery(void);

extern int cnss_get_ramdump_mem(unsigned long *address, unsigned long *size);

extern void *cnss_get_virt_ramdump_mem(unsigned long *size);
extern void *cnss_pci_get_virt_ramdump_mem(unsigned long *size);
extern void *cnss_sdio_get_virt_ramdump_mem(unsigned long *size);

extern void cnss_schedule_recovery_work(void);
extern void cnss_sdio_schedule_recovery_work(void);
extern void cnss_pci_schedule_recovery_work(void);

enum {
	CNSS_RESET_SOC = 0,