qcacld-3.0: Add support for host initiated recovery

If platform has a mechanism to initiate target assert, trigger
that interface to force assert target. Certain integrated platforms
(where WLAN runs on it's own PD) provides a mechanism to initiate PDR
from host. That interface can be triggered when WLAN host detect
timeout scenarios.

CRs-Fixed: 1110243
Change-Id: I6a9408f47ca4245380dbf4177363c3c461ff948d
This commit is contained in:
Sameer Thalappil
2017-01-10 15:32:58 -08:00
committed by snandini
parent 2a519af313
commit ac5d26eb5e
4 changed files with 55 additions and 0 deletions

View File

@@ -1763,6 +1763,20 @@ void cds_trigger_recovery(bool skip_crash_inject)
qdf_runtime_pm_prevent_suspend(recovery_lock); qdf_runtime_pm_prevent_suspend(recovery_lock);
/*
* If force assert thru platform is available, trigger that interface.
* That should generate recovery by going thru the normal FW
* assert recovery model.
*/
if (!pld_force_assert_target(qdf_ctx->dev)) {
QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO_HIGH,
"Force assert triggered");
goto out;
}
QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO_HIGH,
"Force assert not available at platform");
if (!skip_crash_inject) { if (!skip_crash_inject) {
wma_crash_inject(wma_handle, RECOVERY_SIM_SELF_RECOVERY, 0); wma_crash_inject(wma_handle, RECOVERY_SIM_SELF_RECOVERY, 0);
@@ -1778,6 +1792,7 @@ void cds_trigger_recovery(bool skip_crash_inject)
cds_config_recovery_work(qdf_ctx); cds_config_recovery_work(qdf_ctx);
} }
out:
qdf_runtime_pm_allow_suspend(recovery_lock); qdf_runtime_pm_allow_suspend(recovery_lock);
qdf_runtime_lock_deinit(recovery_lock); qdf_runtime_lock_deinit(recovery_lock);
} }

View File

@@ -420,5 +420,6 @@ void pld_get_msi_address(struct device *dev, uint32_t *msi_addr_low,
unsigned int pld_socinfo_get_serial_number(struct device *dev); unsigned int pld_socinfo_get_serial_number(struct device *dev);
uint8_t *pld_get_wlan_mac_address(struct device *dev, uint32_t *num); uint8_t *pld_get_wlan_mac_address(struct device *dev, uint32_t *num);
int pld_is_qmi_disable(struct device *dev); int pld_is_qmi_disable(struct device *dev);
int pld_force_assert_target(struct device *dev);
#endif #endif

View File

@@ -1694,3 +1694,34 @@ int pld_is_qmi_disable(struct device *dev)
return ret; return ret;
} }
/**
* pld_force_assert_target() - Send a force assert to FW.
* This can use various sideband requests available at platform to
* initiate a FW assert.
* @dev: device
*
* Return: 0 if force assert of target was triggered successfully
* Non zero failure code for errors
*/
int pld_force_assert_target(struct device *dev)
{
int ret = 0;
enum pld_bus_type type = pld_get_bus_type(dev);
switch (type) {
case PLD_BUS_TYPE_SNOC:
ret = pld_snoc_force_assert_target(dev);
break;
case PLD_BUS_TYPE_PCIE:
case PLD_BUS_TYPE_SDIO:
ret = -EINVAL;
break;
default:
pr_err("Invalid device type %d\n", type);
ret = -EINVAL;
break;
}
return ret;
}

View File

@@ -146,6 +146,10 @@ static inline int pld_snoc_set_fw_log_mode(u8 fw_log_mode)
{ {
return 0; return 0;
} }
static inline int pld_snoc_force_assert_target(struct device *dev)
{
return 0;
}
#else #else
int pld_snoc_register_driver(void); int pld_snoc_register_driver(void);
void pld_snoc_unregister_driver(void); void pld_snoc_unregister_driver(void);
@@ -247,5 +251,9 @@ static inline int pld_snoc_set_fw_log_mode(u8 fw_log_mode)
{ {
return icnss_set_fw_log_mode(fw_log_mode); return icnss_set_fw_log_mode(fw_log_mode);
} }
static inline int pld_snoc_force_assert_target(struct device *dev)
{
return icnss_trigger_recovery(dev);
}
#endif #endif
#endif #endif