qcacld-3.0: Driver fails to report gDualMacFeatureDisable val to FW

If DBS is disabled from INI then driver just bails out
in wlan_hdd_update_dbs_scan_and_fw_mode_config() API and never report
it to FW. This creates a confusion when DBS is disable INI but our HW
is capable of doing DBS, i.e. driver thinks that DBS disabled
but FW thinks that DBS is enabled.

Provide a fix that driver should report exact INI setting to FW.
This issue got introduced as part of regression caused by:
Iec2ef7e77e91f332028904c319d24e1ed134306d

ROME platform doesn't support any DBS related commands in FW,
so if driver sends wmi command with dual_mac_config with all params
set to 0 then FW wouldn't respond back and driver would timeout on
waiting for response. This was the original issue for which
Iec2ef7e77e91f332028904c319d24e1ed134306d was added.

Make sure current solution doesn't break backward compatibility.
Add a check to make sure FW supports DBS to eliminate
ROME vs NON-ROME platform.

CRs-Fixed: 2361628
Change-Id: I8a3b795b20e82391ae5d5c86d1e7d814d103ce64
This commit is contained in:
Krunal Soni 2018-12-13 16:00:02 -08:00 committed by nshrivas
parent 325de9f293
commit e64b17e7f0
3 changed files with 81 additions and 48 deletions

View File

@ -2013,6 +2013,19 @@ QDF_STATUS policy_mgr_register_dp_cb(struct wlan_objmgr_psoc *psoc,
QDF_STATUS policy_mgr_register_wma_cb(struct wlan_objmgr_psoc *psoc,
struct policy_mgr_wma_cbacks *wma_cbacks);
/**
* policy_mgr_find_if_fw_supports_dbs() - to find if FW/HW supports DBS
* @psoc: PSOC object information
*
* This API checks if legacy service ready event contains DBS or no.
* This API doesn't check service ready extension which contains actual
* hw mode list that tells if all supported HW modes' caps.
*
* Return: true (if service ready indication supports DBS or no) else false
*
*/
bool policy_mgr_find_if_fw_supports_dbs(struct wlan_objmgr_psoc *psoc);
/**
* policy_mgr_is_dbs_enable() - Check if master DBS control is enabled
* @psoc: PSOC object information

View File

@ -810,11 +810,11 @@ int8_t policy_mgr_get_num_dbs_hw_modes(struct wlan_objmgr_psoc *psoc)
return pm_ctx->num_dbs_hw_modes;
}
bool policy_mgr_is_hw_dbs_capable(struct wlan_objmgr_psoc *psoc)
bool policy_mgr_find_if_fw_supports_dbs(struct wlan_objmgr_psoc *psoc)
{
uint32_t param, i, found = 0;
struct policy_mgr_psoc_priv_obj *pm_ctx;
struct wmi_unified *wmi_handle;
bool dbs_support;
pm_ctx = policy_mgr_get_context(psoc);
@ -822,30 +822,38 @@ bool policy_mgr_is_hw_dbs_capable(struct wlan_objmgr_psoc *psoc)
policy_mgr_err("Invalid Context");
return false;
}
if (!policy_mgr_is_dbs_enable(psoc)) {
policy_mgr_debug("DBS is disabled");
return false;
}
wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
if (!wmi_handle) {
policy_mgr_debug("Invalid WMI handle");
return false;
}
policy_mgr_debug("DBS service bit map: %d",
wmi_service_enabled(wmi_handle,
wmi_service_dual_band_simultaneous_support));
dbs_support =
wmi_service_enabled(wmi_handle,
wmi_service_dual_band_simultaneous_support);
policy_mgr_debug("is DBS supported by FW/HW: %s",
dbs_support ? "yes" : "no");
/* The agreement with FW is that: To know if the target is DBS
* capable, DBS needs to be supported both in the HW mode list
* and in the service ready event
*/
if (!(wmi_service_enabled(wmi_handle,
wmi_service_dual_band_simultaneous_support)))
if (!dbs_support)
return false;
return true;
}
static bool policy_mgr_find_if_hwlist_has_dbs(struct wlan_objmgr_psoc *psoc)
{
struct policy_mgr_psoc_priv_obj *pm_ctx;
uint32_t param, i, found = 0;
pm_ctx = policy_mgr_get_context(psoc);
if (!pm_ctx) {
policy_mgr_err("Invalid Context");
return false;
}
for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) {
param = pm_ctx->hw_mode.hw_mode_list[i];
policy_mgr_debug("HW param: %x", param);
@ -855,43 +863,23 @@ bool policy_mgr_is_hw_dbs_capable(struct wlan_objmgr_psoc *psoc)
break;
}
}
if (found)
return true;
return false;
}
bool policy_mgr_is_hw_sbs_capable(struct wlan_objmgr_psoc *psoc)
static bool policy_mgr_find_if_hwlist_has_sbs(struct wlan_objmgr_psoc *psoc)
{
uint32_t param, i, found = 0;
struct policy_mgr_psoc_priv_obj *pm_ctx;
struct wmi_unified *wmi_handle;
uint32_t param, i, found = 0;
pm_ctx = policy_mgr_get_context(psoc);
if (!pm_ctx) {
policy_mgr_err("Invalid Context");
return false;
}
wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
if (!wmi_handle) {
policy_mgr_debug("Invalid WMI handle");
return false;
}
policy_mgr_debug("DBS service bit map: %d",
wmi_service_enabled(wmi_handle,
wmi_service_dual_band_simultaneous_support));
/* The agreement with FW is that: To know if the target is SBS
* capable, SBS needs to be supported both in the HW mode list
* and DBS needs to be supported in the service ready event
*/
if (!(wmi_service_enabled(wmi_handle,
wmi_service_dual_band_simultaneous_support)))
return false;
for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) {
param = pm_ctx->hw_mode.hw_mode_list[i];
policy_mgr_debug("HW param: %x", param);
@ -901,13 +889,37 @@ bool policy_mgr_is_hw_sbs_capable(struct wlan_objmgr_psoc *psoc)
break;
}
}
if (found)
return true;
return false;
}
bool policy_mgr_is_hw_dbs_capable(struct wlan_objmgr_psoc *psoc)
{
if (!policy_mgr_is_dbs_enable(psoc)) {
policy_mgr_debug("DBS is disabled");
return false;
}
if (!policy_mgr_find_if_fw_supports_dbs(psoc)) {
policy_mgr_debug("HW mode list has no DBS");
return false;
}
return policy_mgr_find_if_hwlist_has_dbs(psoc);
}
bool policy_mgr_is_hw_sbs_capable(struct wlan_objmgr_psoc *psoc)
{
if (!policy_mgr_find_if_fw_supports_dbs(psoc)) {
policy_mgr_debug("HW mode list has no DBS");
return false;
}
return policy_mgr_find_if_hwlist_has_sbs(psoc);
}
QDF_STATUS policy_mgr_get_dbs_hw_modes(struct wlan_objmgr_psoc *psoc,
bool *one_by_one_dbs, bool *two_by_two_dbs)
{

View File

@ -2305,7 +2305,7 @@ wlan_hdd_update_dbs_scan_and_fw_mode_config(void)
{
struct policy_mgr_dual_mac_config cfg = {0};
QDF_STATUS status;
uint32_t channel_select_logic_conc = 0;
uint32_t chnl_sel_logic_conc = 0;
struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
uint8_t dual_mac_feature = DISABLE_DBS_CXN_AND_SCAN;
@ -2314,19 +2314,27 @@ wlan_hdd_update_dbs_scan_and_fw_mode_config(void)
return QDF_STATUS_E_FAILURE;
}
if (!policy_mgr_is_hw_dbs_capable(hdd_ctx->psoc))
/*
* ROME platform doesn't support any DBS related commands in FW,
* so if driver sends wmi command with dual_mac_config with all set to
* 0 then FW wouldn't respond back and driver would timeout on waiting
* for response. Check if FW supports DBS to eliminate ROME vs
* NON-ROME platform.
*/
if (!policy_mgr_find_if_fw_supports_dbs(hdd_ctx->psoc))
return QDF_STATUS_SUCCESS;
cfg.scan_config = 0;
cfg.fw_mode_config = 0;
cfg.set_dual_mac_cb = policy_mgr_soc_set_dual_mac_cfg_cb;
status =
ucfg_policy_mgr_get_chnl_select_plcy(hdd_ctx->psoc,
&channel_select_logic_conc);
if (status != QDF_STATUS_SUCCESS) {
hdd_err("ucfg_policy_mgr_get_chnl_select_plcy failed, use def");
return status;
if (policy_mgr_is_hw_dbs_capable(hdd_ctx->psoc)) {
status =
ucfg_policy_mgr_get_chnl_select_plcy(hdd_ctx->psoc,
&chnl_sel_logic_conc);
if (status != QDF_STATUS_SUCCESS) {
hdd_err("can't get chnl sel policy, use def");
return status;
}
}
status =
ucfg_policy_mgr_get_dual_mac_feature(hdd_ctx->psoc,
@ -2341,7 +2349,7 @@ wlan_hdd_update_dbs_scan_and_fw_mode_config(void)
hdd_ctx->psoc, &cfg.scan_config,
&cfg.fw_mode_config,
dual_mac_feature,
channel_select_logic_conc);
chnl_sel_logic_conc);
if (status != QDF_STATUS_SUCCESS) {
hdd_err("wma_get_updated_scan_and_fw_mode_config failed %d",