qcacmn: Handle RTPM counter for opt wifi dp
Inorder to keep the PCIe link up during optional wifi dp transfer the hif_force_wake_request() is called during filter addition. This increments the rtpm_get counter. Now if Wifi is disconnected before releasing the filters, the corresponding hif_force_wake_release() call is not made. This causes a mismatch in RTPM GET and PUT calls and triggers an assert during hdd_wlan_stop_modules(). This change adds a cleanup call to release the force wake and reduce the rtpm_put counter to prevent the assert. Change-Id: Idd778275a015922376cf7eb0a7c3d92e75881fe8 CRs-Fixed: 3441186
This commit is contained in:

committed by
Madan Koyyalamudi

parent
2bea262d35
commit
42381bb34d
@@ -1354,6 +1354,36 @@ void dp_rx_alt_ipa_uc_detach(struct dp_soc *soc, struct dp_pdev *pdev)
|
|||||||
{ }
|
{ }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dp_ipa_opt_wifi_dp_cleanup() - Cleanup ipa opt wifi dp filter setup
|
||||||
|
* @soc: data path instance
|
||||||
|
* @pdev: core txrx pdev context
|
||||||
|
*
|
||||||
|
* This function will cleanup filter setup for optional wifi dp.
|
||||||
|
*
|
||||||
|
* Return: none
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef IPA_OPT_WIFI_DP
|
||||||
|
static void dp_ipa_opt_wifi_dp_cleanup(struct dp_soc *soc, struct dp_pdev *pdev)
|
||||||
|
{
|
||||||
|
struct hal_soc *hal_soc = (struct hal_soc *)soc->hal_soc;
|
||||||
|
struct hif_softc *hif = (struct hif_softc *)(hal_soc->hif_handle);
|
||||||
|
int count = qdf_atomic_read(&hif->opt_wifi_dp_rtpm_cnt);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = count; i > 0; i--) {
|
||||||
|
dp_info("opt_dp: cleanup call pcie link down");
|
||||||
|
dp_ipa_pcie_link_down((struct cdp_soc_t *)soc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static inline
|
||||||
|
void dp_opt_wifi_dp(struct dp_soc *soc, struct dp_pdev *pdev)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int dp_ipa_uc_detach(struct dp_soc *soc, struct dp_pdev *pdev)
|
int dp_ipa_uc_detach(struct dp_soc *soc, struct dp_pdev *pdev)
|
||||||
{
|
{
|
||||||
if (!wlan_cfg_is_ipa_enabled(soc->wlan_cfg_ctx))
|
if (!wlan_cfg_is_ipa_enabled(soc->wlan_cfg_ctx))
|
||||||
@@ -1371,6 +1401,8 @@ int dp_ipa_uc_detach(struct dp_soc *soc, struct dp_pdev *pdev)
|
|||||||
/* Cleanup 2nd RX pipe resources */
|
/* Cleanup 2nd RX pipe resources */
|
||||||
dp_rx_alt_ipa_uc_detach(soc, pdev);
|
dp_rx_alt_ipa_uc_detach(soc, pdev);
|
||||||
|
|
||||||
|
dp_ipa_opt_wifi_dp_cleanup(soc, pdev);
|
||||||
|
|
||||||
return QDF_STATUS_SUCCESS; /* success */
|
return QDF_STATUS_SUCCESS; /* success */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -347,6 +347,9 @@ struct hif_softc {
|
|||||||
#endif /*defined(HIF_CONFIG_SLUB_DEBUG_ON) || defined(HIF_CE_DEBUG_DATA_BUF)*/
|
#endif /*defined(HIF_CONFIG_SLUB_DEBUG_ON) || defined(HIF_CE_DEBUG_DATA_BUF)*/
|
||||||
#ifdef IPA_OFFLOAD
|
#ifdef IPA_OFFLOAD
|
||||||
qdf_shared_mem_t *ipa_ce_ring;
|
qdf_shared_mem_t *ipa_ce_ring;
|
||||||
|
#endif
|
||||||
|
#ifdef IPA_OPT_WIFI_DP
|
||||||
|
qdf_atomic_t opt_wifi_dp_rtpm_cnt;
|
||||||
#endif
|
#endif
|
||||||
struct hif_cfg ini_cfg;
|
struct hif_cfg ini_cfg;
|
||||||
#ifdef HIF_CE_LOG_INFO
|
#ifdef HIF_CE_LOG_INFO
|
||||||
|
@@ -4290,11 +4290,36 @@ void hif_allow_link_low_power_states(struct hif_opaque_softc *hif)
|
|||||||
#ifdef IPA_OPT_WIFI_DP
|
#ifdef IPA_OPT_WIFI_DP
|
||||||
int hif_prevent_l1(struct hif_opaque_softc *hif)
|
int hif_prevent_l1(struct hif_opaque_softc *hif)
|
||||||
{
|
{
|
||||||
return hif_force_wake_request(hif);
|
struct hif_softc *hif_softc = (struct hif_softc *)hif;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
status = hif_force_wake_request(hif);
|
||||||
|
if (status) {
|
||||||
|
hif_err("Force wake request error");
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
qdf_atomic_inc(&hif_softc->opt_wifi_dp_rtpm_cnt);
|
||||||
|
hif_info("opt_dp: pcie link up count %d",
|
||||||
|
qdf_atomic_read(&hif_softc->opt_wifi_dp_rtpm_cnt));
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
void hif_allow_l1(struct hif_opaque_softc *hif)
|
void hif_allow_l1(struct hif_opaque_softc *hif)
|
||||||
{
|
{
|
||||||
hif_force_wake_release(hif);
|
struct hif_softc *hif_softc = (struct hif_softc *)hif;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
if (qdf_atomic_read(&hif_softc->opt_wifi_dp_rtpm_cnt) > 0) {
|
||||||
|
status = hif_force_wake_release(hif);
|
||||||
|
if (status) {
|
||||||
|
hif_err("Force wake release error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
qdf_atomic_dec(&hif_softc->opt_wifi_dp_rtpm_cnt);
|
||||||
|
hif_info("opt_dp: pcie link down count %d",
|
||||||
|
qdf_atomic_read(&hif_softc->opt_wifi_dp_rtpm_cnt));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -4892,7 +4892,25 @@ int wlan_ipa_wdi_opt_dpath_flt_rsrv_cb(
|
|||||||
{
|
{
|
||||||
struct wifi_dp_flt_setup *dp_flt_params = NULL;
|
struct wifi_dp_flt_setup *dp_flt_params = NULL;
|
||||||
struct wlan_ipa_priv *ipa_obj = (struct wlan_ipa_priv *)ipa_ctx;
|
struct wlan_ipa_priv *ipa_obj = (struct wlan_ipa_priv *)ipa_ctx;
|
||||||
int i;
|
int i, pdev_id, param_val;
|
||||||
|
struct wlan_objmgr_pdev *pdev;
|
||||||
|
int response = 0;
|
||||||
|
|
||||||
|
pdev = ipa_obj->pdev;
|
||||||
|
pdev_id = ipa_obj->dp_pdev_id;
|
||||||
|
/* Disable Low power features before filter reservation */
|
||||||
|
ipa_info("opt_dp: Disable low power features to reserve filter");
|
||||||
|
param_val = 0;
|
||||||
|
response = cdp_ipa_opt_dp_enable_disable_low_power_mode(pdev, pdev_id,
|
||||||
|
param_val);
|
||||||
|
if (response) {
|
||||||
|
ipa_err("Low power feature disable failed. status %d",
|
||||||
|
response);
|
||||||
|
return QDF_STATUS_FILT_REQ_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
response = cdp_ipa_pcie_link_up(ipa_obj->dp_soc);
|
||||||
|
ipa_info("opt_dp: Pcie link up status %d", response);
|
||||||
|
|
||||||
ipa_info("opt_dp: Send filter reserve req");
|
ipa_info("opt_dp: Send filter reserve req");
|
||||||
dp_flt_params = &(ipa_obj->dp_cce_super_rule_flt_param);
|
dp_flt_params = &(ipa_obj->dp_cce_super_rule_flt_param);
|
||||||
@@ -4912,11 +4930,10 @@ int wlan_ipa_wdi_opt_dpath_flt_add_cb(
|
|||||||
struct ipa_wdi_opt_dpath_flt_add_cb_params *ipa_flt =
|
struct ipa_wdi_opt_dpath_flt_add_cb_params *ipa_flt =
|
||||||
(struct ipa_wdi_opt_dpath_flt_add_cb_params *)(in_out);
|
(struct ipa_wdi_opt_dpath_flt_add_cb_params *)(in_out);
|
||||||
struct wlan_ipa_priv *ipa_obj = (struct wlan_ipa_priv *)ipa_ctx;
|
struct wlan_ipa_priv *ipa_obj = (struct wlan_ipa_priv *)ipa_ctx;
|
||||||
int i, j, flt, param_val, pdev_id;
|
int i, j, flt, response = 0;
|
||||||
uint8_t num_flts;
|
uint8_t num_flts;
|
||||||
uint32_t src_ip_addr, dst_ip_addr;
|
uint32_t src_ip_addr, dst_ip_addr;
|
||||||
uint32_t *host_ipv6;
|
uint32_t *host_ipv6;
|
||||||
int response = 0;
|
|
||||||
struct wlan_objmgr_pdev *pdev;
|
struct wlan_objmgr_pdev *pdev;
|
||||||
struct wlan_objmgr_psoc *psoc;
|
struct wlan_objmgr_psoc *psoc;
|
||||||
struct wifi_dp_flt_setup *dp_flt_param = NULL;
|
struct wifi_dp_flt_setup *dp_flt_param = NULL;
|
||||||
@@ -4924,9 +4941,7 @@ int wlan_ipa_wdi_opt_dpath_flt_add_cb(
|
|||||||
|
|
||||||
pdev = ipa_obj->pdev;
|
pdev = ipa_obj->pdev;
|
||||||
psoc = wlan_pdev_get_psoc(pdev);
|
psoc = wlan_pdev_get_psoc(pdev);
|
||||||
pdev_id = ipa_obj->dp_pdev_id;
|
|
||||||
num_flts = ipa_flt->num_tuples;
|
num_flts = ipa_flt->num_tuples;
|
||||||
|
|
||||||
htc_handle = lmac_get_htc_hdl(psoc);
|
htc_handle = lmac_get_htc_hdl(psoc);
|
||||||
if (!htc_handle) {
|
if (!htc_handle) {
|
||||||
ipa_err("HTC Handle is null");
|
ipa_err("HTC Handle is null");
|
||||||
@@ -4940,19 +4955,6 @@ int wlan_ipa_wdi_opt_dpath_flt_add_cb(
|
|||||||
return QDF_STATUS_FILT_REQ_ERROR;
|
return QDF_STATUS_FILT_REQ_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Disable Low power features before filter addition */
|
|
||||||
ipa_info("opt_dp: Disable low power features to add filter param");
|
|
||||||
param_val = 0;
|
|
||||||
response = cdp_ipa_opt_dp_enable_disable_low_power_mode(pdev, pdev_id,
|
|
||||||
param_val);
|
|
||||||
if (response) {
|
|
||||||
ipa_err("Low power feature disable failed. status %d",
|
|
||||||
response);
|
|
||||||
return QDF_STATUS_FILT_REQ_ERROR;
|
|
||||||
}
|
|
||||||
response = cdp_ipa_pcie_link_up(ipa_obj->dp_soc);
|
|
||||||
ipa_info("opt_dp: Pcie link up status %d", response);
|
|
||||||
|
|
||||||
for (flt = 0; flt < num_flts; flt++) {
|
for (flt = 0; flt < num_flts; flt++) {
|
||||||
for (i = 0; i < IPA_WDI_MAX_FILTER; i++)
|
for (i = 0; i < IPA_WDI_MAX_FILTER; i++)
|
||||||
if (!dp_flt_param->flt_addr_params[i].ipa_flt_in_use)
|
if (!dp_flt_param->flt_addr_params[i].ipa_flt_in_use)
|
||||||
@@ -5063,14 +5065,12 @@ int wlan_ipa_wdi_opt_dpath_flt_rem_cb(
|
|||||||
struct wlan_ipa_priv *ipa_obj = (struct wlan_ipa_priv *)ipa_ctx;
|
struct wlan_ipa_priv *ipa_obj = (struct wlan_ipa_priv *)ipa_ctx;
|
||||||
struct wlan_objmgr_pdev *pdev;
|
struct wlan_objmgr_pdev *pdev;
|
||||||
struct wlan_objmgr_psoc *psoc;
|
struct wlan_objmgr_psoc *psoc;
|
||||||
int pdev_id;
|
|
||||||
uint8_t num_flts;
|
uint8_t num_flts;
|
||||||
uint32_t i, j, response = 0, param_val = 0;
|
uint32_t i, j, response = 0;
|
||||||
void *htc_handle;
|
void *htc_handle;
|
||||||
|
|
||||||
pdev = ipa_obj->pdev;
|
pdev = ipa_obj->pdev;
|
||||||
psoc = wlan_pdev_get_psoc(pdev);
|
psoc = wlan_pdev_get_psoc(pdev);
|
||||||
pdev_id = ipa_obj->dp_pdev_id;
|
|
||||||
num_flts = rem_flt->num_tuples;
|
num_flts = rem_flt->num_tuples;
|
||||||
|
|
||||||
htc_handle = lmac_get_htc_hdl(psoc);
|
htc_handle = lmac_get_htc_hdl(psoc);
|
||||||
@@ -5078,18 +5078,6 @@ int wlan_ipa_wdi_opt_dpath_flt_rem_cb(
|
|||||||
ipa_err("HTC Handle is null");
|
ipa_err("HTC Handle is null");
|
||||||
return QDF_STATUS_FILT_REQ_ERROR;
|
return QDF_STATUS_FILT_REQ_ERROR;
|
||||||
}
|
}
|
||||||
/* Enable Low power features before filter deletion */
|
|
||||||
ipa_info("opt_dp: Enable low power features to delete filter param");
|
|
||||||
param_val = 1;
|
|
||||||
response = cdp_ipa_opt_dp_enable_disable_low_power_mode(pdev, pdev_id,
|
|
||||||
param_val);
|
|
||||||
if (response) {
|
|
||||||
ipa_err("Low power feature enable failed. status %d", response);
|
|
||||||
return QDF_STATUS_FILT_REQ_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
response = cdp_ipa_pcie_link_up(ipa_obj->dp_soc);
|
|
||||||
ipa_info("opt_dp: Vote for PCIe link up");
|
|
||||||
|
|
||||||
dp_flt_params = &(ipa_obj->dp_cce_super_rule_flt_param);
|
dp_flt_params = &(ipa_obj->dp_cce_super_rule_flt_param);
|
||||||
for (i = 0; i < num_flts; i++) {
|
for (i = 0; i < num_flts; i++) {
|
||||||
@@ -5146,8 +5134,25 @@ int wlan_ipa_wdi_opt_dpath_flt_rsrv_rel_cb(void *ipa_ctx)
|
|||||||
{
|
{
|
||||||
struct wifi_dp_flt_setup *dp_flt_params = NULL;
|
struct wifi_dp_flt_setup *dp_flt_params = NULL;
|
||||||
struct wlan_ipa_priv *ipa_obj = (struct wlan_ipa_priv *)ipa_ctx;
|
struct wlan_ipa_priv *ipa_obj = (struct wlan_ipa_priv *)ipa_ctx;
|
||||||
int i;
|
int i, param_val = 0;
|
||||||
|
struct wlan_objmgr_pdev *pdev;
|
||||||
|
int pdev_id;
|
||||||
|
int response = 0;
|
||||||
|
|
||||||
|
pdev = ipa_obj->pdev;
|
||||||
|
pdev_id = ipa_obj->dp_pdev_id;
|
||||||
|
/* Enable Low power features before filter release */
|
||||||
|
ipa_info("opt_dp: Enable low power features to release filter");
|
||||||
|
param_val = 1;
|
||||||
|
response = cdp_ipa_opt_dp_enable_disable_low_power_mode(pdev, pdev_id,
|
||||||
|
param_val);
|
||||||
|
if (response) {
|
||||||
|
ipa_err("Low power feature enable failed. status %d", response);
|
||||||
|
return QDF_STATUS_FILT_REQ_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
response = cdp_ipa_pcie_link_down(ipa_obj->dp_soc);
|
||||||
|
ipa_info("opt_dp: Vote for PCIe link down");
|
||||||
dp_flt_params = &(ipa_obj->dp_cce_super_rule_flt_param);
|
dp_flt_params = &(ipa_obj->dp_cce_super_rule_flt_param);
|
||||||
for (i = 0; i < IPA_WDI_MAX_FILTER; i++)
|
for (i = 0; i < IPA_WDI_MAX_FILTER; i++)
|
||||||
dp_flt_params->flt_addr_params[i].valid = 0;
|
dp_flt_params->flt_addr_params[i].valid = 0;
|
||||||
|
Reference in New Issue
Block a user