From bde7c6fb4deeeba7f1f9ae4b916ded23ba0f8214 Mon Sep 17 00:00:00 2001 From: Yue Ma Date: Thu, 1 Feb 2018 12:25:47 -0800 Subject: [PATCH] cnss2: Support collecting firmware dump during driver load When firmware crashes during WLAN host driver loads, collects firmware dump and proceeds with SSR as normal cases. Change-Id: If2ac7da3c2db4b4116949d092ad53299f23c87e0 Signed-off-by: Yue Ma --- drivers/net/wireless/cnss2/main.c | 24 +++++++++++++++--------- drivers/net/wireless/cnss2/pci.c | 4 ++++ include/net/cnss2.h | 1 + 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/cnss2/main.c b/drivers/net/wireless/cnss2/main.c index bcea74ad6685..dcaf3203f197 100644 --- a/drivers/net/wireless/cnss2/main.c +++ b/drivers/net/wireless/cnss2/main.c @@ -571,7 +571,8 @@ static int cnss_driver_call_probe(struct cnss_plat_data *plat_priv) goto out; } - if (test_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state)) { + if (test_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state) && + test_bit(CNSS_DRIVER_PROBED, &plat_priv->driver_state)) { ret = plat_priv->driver_ops->reinit(pci_priv->pci_dev, pci_priv->pci_device_id); if (ret) { @@ -588,6 +589,7 @@ static int cnss_driver_call_probe(struct cnss_plat_data *plat_priv) ret); goto out; } + clear_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state); clear_bit(CNSS_DRIVER_LOADING, &plat_priv->driver_state); set_bit(CNSS_DRIVER_PROBED, &plat_priv->driver_state); } @@ -614,7 +616,8 @@ static int cnss_driver_call_remove(struct cnss_plat_data *plat_priv) return -EINVAL; } - if (test_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state)) { + if (test_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state) && + test_bit(CNSS_DRIVER_PROBED, &plat_priv->driver_state)) { plat_priv->driver_ops->shutdown(pci_priv->pci_dev); } else if (test_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state)) { plat_priv->driver_ops->remove(pci_priv->pci_dev); @@ -652,7 +655,9 @@ static int cnss_fw_ready_hdlr(struct cnss_plat_data *plat_priv) complete(&plat_priv->power_up_complete); } - if (ret) + if (ret && test_bit(CNSS_DEV_ERR_NOTIFY, &plat_priv->driver_state)) + goto out; + else if (ret) goto shutdown; return 0; @@ -662,6 +667,10 @@ shutdown: cnss_suspend_pci_link(plat_priv->bus_priv); cnss_power_off_device(plat_priv); + clear_bit(CNSS_FW_READY, &plat_priv->driver_state); + clear_bit(CNSS_FW_MEM_READY, &plat_priv->driver_state); + +out: return ret; } @@ -1179,8 +1188,10 @@ static void cnss_qca6290_crash_shutdown(struct cnss_plat_data *plat_priv) if (test_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state) || test_bit(CNSS_DRIVER_LOADING, &plat_priv->driver_state) || - test_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state)) + test_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state)) { + cnss_pr_dbg("Ignore crash shutdown\n"); return; + } ret = cnss_pci_set_mhi_state(pci_priv, CNSS_MHI_RDDM_KERNEL_PANIC); if (ret) { @@ -1538,11 +1549,6 @@ static int cnss_driver_recovery_hdlr(struct cnss_plat_data *plat_priv, if (!test_bit(CNSS_FW_READY, &plat_priv->driver_state)) { set_bit(CNSS_FW_BOOT_RECOVERY, &plat_priv->driver_state); - } else if (test_bit(CNSS_DRIVER_LOADING, - &plat_priv->driver_state)) { - cnss_pr_err("Driver probe is in progress, ignore recovery\n"); - ret = -EINVAL; - goto out; } break; } diff --git a/drivers/net/wireless/cnss2/pci.c b/drivers/net/wireless/cnss2/pci.c index 39deddd4db07..0f145babeb71 100644 --- a/drivers/net/wireless/cnss2/pci.c +++ b/drivers/net/wireless/cnss2/pci.c @@ -1185,6 +1185,10 @@ static void cnss_mhi_notify_status(enum MHI_CB_REASON reason, void *priv) cnss_pr_dbg("MHI status cb is called with reason %d\n", reason); + if (plat_priv->driver_ops && plat_priv->driver_ops->update_status) + plat_priv->driver_ops->update_status(pci_priv->pci_dev, + CNSS_FW_DOWN); + set_bit(CNSS_DEV_ERR_NOTIFY, &plat_priv->driver_state); del_timer(&plat_priv->fw_boot_timer); diff --git a/include/net/cnss2.h b/include/net/cnss2.h index 053114979a87..f80d87533a99 100644 --- a/include/net/cnss2.h +++ b/include/net/cnss2.h @@ -88,6 +88,7 @@ enum cnss_driver_status { CNSS_INITIALIZED, CNSS_LOAD_UNLOAD, CNSS_RECOVERY, + CNSS_FW_DOWN, }; struct cnss_ce_tgt_pipe_cfg {