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:
Namita Nair
2023-03-20 18:36:08 -07:00
committed by Madan Koyyalamudi
parent 2bea262d35
commit 42381bb34d
4 changed files with 101 additions and 36 deletions

View File

@@ -1354,6 +1354,36 @@ void dp_rx_alt_ipa_uc_detach(struct dp_soc *soc, struct dp_pdev *pdev)
{ }
#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)
{
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 */
dp_rx_alt_ipa_uc_detach(soc, pdev);
dp_ipa_opt_wifi_dp_cleanup(soc, pdev);
return QDF_STATUS_SUCCESS; /* success */
}

View File

@@ -347,6 +347,9 @@ struct hif_softc {
#endif /*defined(HIF_CONFIG_SLUB_DEBUG_ON) || defined(HIF_CE_DEBUG_DATA_BUF)*/
#ifdef IPA_OFFLOAD
qdf_shared_mem_t *ipa_ce_ring;
#endif
#ifdef IPA_OPT_WIFI_DP
qdf_atomic_t opt_wifi_dp_rtpm_cnt;
#endif
struct hif_cfg ini_cfg;
#ifdef HIF_CE_LOG_INFO

View File

@@ -4290,11 +4290,36 @@ void hif_allow_link_low_power_states(struct hif_opaque_softc *hif)
#ifdef IPA_OPT_WIFI_DP
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)
{
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

View File

@@ -4892,7 +4892,25 @@ int wlan_ipa_wdi_opt_dpath_flt_rsrv_cb(
{
struct wifi_dp_flt_setup *dp_flt_params = NULL;
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");
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 *)(in_out);
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;
uint32_t src_ip_addr, dst_ip_addr;
uint32_t *host_ipv6;
int response = 0;
struct wlan_objmgr_pdev *pdev;
struct wlan_objmgr_psoc *psoc;
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;
psoc = wlan_pdev_get_psoc(pdev);
pdev_id = ipa_obj->dp_pdev_id;
num_flts = ipa_flt->num_tuples;
htc_handle = lmac_get_htc_hdl(psoc);
if (!htc_handle) {
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;
}
/* 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 (i = 0; i < IPA_WDI_MAX_FILTER; i++)
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_objmgr_pdev *pdev;
struct wlan_objmgr_psoc *psoc;
int pdev_id;
uint8_t num_flts;
uint32_t i, j, response = 0, param_val = 0;
uint32_t i, j, response = 0;
void *htc_handle;
pdev = ipa_obj->pdev;
psoc = wlan_pdev_get_psoc(pdev);
pdev_id = ipa_obj->dp_pdev_id;
num_flts = rem_flt->num_tuples;
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");
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);
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 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);
for (i = 0; i < IPA_WDI_MAX_FILTER; i++)
dp_flt_params->flt_addr_params[i].valid = 0;