net: cnss: add subsystem restart support for dual WiFi

Subsystem device add support for subsystem restart
recovery and ramdump device for cnss firmware dump
collection before the subsystem restart.

Refactor subsystem restart wrapper APIs to avoid the name
space collision in cnss platform driver compilation in dual
WiFi mode.

CRs-Fixed: 983677
Change-Id: Ib4a8d1a6d0ce8f1faa43ce0aa8312823b1ca3c15
Signed-off-by: Sarada Prasanna Garnayak <sgarna@codeaurora.org>
This commit is contained in:
Sarada Prasanna Garnayak 2016-02-27 21:03:12 +05:30 committed by David Keitel
parent b29bc2ad43
commit 9fc3913ed9
3 changed files with 108 additions and 4 deletions

View file

@ -1752,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)
{
@ -2189,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)
@ -2364,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;

View file

@ -467,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;
@ -501,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)
{

View file

@ -195,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,