diff --git a/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h b/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h index 3abe534273ff..e0de41b6597c 100644 --- a/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h +++ b/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h @@ -1186,6 +1186,7 @@ QDF_STATUS policy_mgr_check_n_start_opportunistic_timer( * @reason: Reason for connection update * @next_action: next action to happen at policy mgr after * HW mode change + * @action: action to be applied before hw mode change * * Sends the set hw mode request to FW * @@ -1233,7 +1234,7 @@ QDF_STATUS policy_mgr_pdev_set_hw_mode(struct wlan_objmgr_psoc *psoc, enum hw_mode_agile_dfs_capab dfs, enum hw_mode_sbs_capab sbs, enum policy_mgr_conn_update_reason reason, - uint8_t next_action); + uint8_t next_action, enum policy_mgr_conc_next_action action); /** * policy_mgr_pdev_set_hw_mode_cback() - callback invoked by @@ -1453,6 +1454,25 @@ QDF_STATUS policy_mgr_next_actions(struct wlan_objmgr_psoc *psoc, enum policy_mgr_conc_next_action action, enum policy_mgr_conn_update_reason reason); +/** + * policy_mgr_validate_dbs_switch() - Check DBS action valid or not + * @psoc: Pointer to psoc + * @action: action requested + * + * This routine will check the current hw mode with requested action. + * If we are already in the mode, the caller will do nothing. + * This will be called by policy_mgr_next_actions to check the action needed + * or not. + * + * return : QDF_STATUS_SUCCESS, action is allowed. + * QDF_STATUS_E_ALREADY, action is not needed. + * QDF_STATUS_E_FAILURE, error happens. + * QDF_STATUS_E_NOSUPPORT, the requested mode not supported. + */ +QDF_STATUS +policy_mgr_validate_dbs_switch(struct wlan_objmgr_psoc *psoc, + enum policy_mgr_conc_next_action action); + /** * policy_mgr_set_dual_mac_scan_config() - Set the dual MAC scan config * @psoc: PSOC object information diff --git a/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_public_struct.h b/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_public_struct.h index c8ba7f8e05f2..d7705e8ff093 100644 --- a/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_public_struct.h +++ b/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_public_struct.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -949,6 +949,7 @@ enum hw_mode_bandwidth { * enum set_hw_mode_status - Status of set HW mode command * @SET_HW_MODE_STATUS_OK: command successful * @SET_HW_MODE_STATUS_EINVAL: Requested invalid hw_mode + * @SET_HW_MODE_STATUS_ALREADY: Requested hw mode is already applied to FW. * @SET_HW_MODE_STATUS_ECANCELED: HW mode change cancelled * @SET_HW_MODE_STATUS_ENOTSUP: HW mode not supported * @SET_HW_MODE_STATUS_EHARDWARE: HW mode change prevented by hardware @@ -958,6 +959,7 @@ enum hw_mode_bandwidth { enum set_hw_mode_status { SET_HW_MODE_STATUS_OK, SET_HW_MODE_STATUS_EINVAL, + SET_HW_MODE_STATUS_ALREADY, SET_HW_MODE_STATUS_ECANCELED, SET_HW_MODE_STATUS_ENOTSUP, SET_HW_MODE_STATUS_EHARDWARE, @@ -1123,6 +1125,7 @@ struct policy_mgr_dual_mac_config { * @reason: Reason for HW mode change * @session_id: Session id * @next_action: next action to happen at policy mgr + * @action: current hw change action to be done * @context: psoc context */ struct policy_mgr_hw_mode { @@ -1131,6 +1134,7 @@ struct policy_mgr_hw_mode { enum policy_mgr_conn_update_reason reason; uint32_t session_id; uint8_t next_action; + enum policy_mgr_conc_next_action action; struct wlan_objmgr_psoc *context; }; diff --git a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c index bdac0e5b8940..3afcd60dcf42 100644 --- a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c +++ b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c @@ -131,7 +131,7 @@ QDF_STATUS policy_mgr_pdev_set_hw_mode(struct wlan_objmgr_psoc *psoc, enum hw_mode_agile_dfs_capab dfs, enum hw_mode_sbs_capab sbs, enum policy_mgr_conn_update_reason reason, - uint8_t next_action) + uint8_t next_action, enum policy_mgr_conc_next_action action) { int8_t hw_mode_index; struct policy_mgr_hw_mode msg; @@ -181,10 +181,11 @@ QDF_STATUS policy_mgr_pdev_set_hw_mode(struct wlan_objmgr_psoc *psoc, msg.reason = reason; msg.session_id = session_id; msg.next_action = next_action; + msg.action = action; msg.context = psoc; - policy_mgr_debug("set hw mode to sme: hw_mode_index: %d session:%d reason:%d", - msg.hw_mode_index, msg.session_id, msg.reason); + policy_mgr_debug("set hw mode to sme: hw_mode_index: %d session:%d reason:%d action %d", + msg.hw_mode_index, msg.session_id, msg.reason, action); status = pm_ctx->sme_cbacks.sme_pdev_set_hw_mode(msg); if (status != QDF_STATUS_SUCCESS) { @@ -932,29 +933,9 @@ policy_mgr_current_connections_update(struct wlan_objmgr_psoc *psoc, return status; } -/** - * policy_mgr_validate_dbs_switch() - Check DBS action valid or not - * @psoc: Pointer to psoc - * @session_id: vdev id - * @action: action requested - * @reason: reason of hw mode change - * - * This routine will check the current hw mode with requested action. - * If we are already in the mode, the caller will do nothing. - * This will be called by policy_mgr_next_actions to check the action needed - * or not. - * - * return : QDF_STATUS_SUCCESS, action is allowed. - * QDF_STATUS_E_ALREADY, action is not needed. - * QDF_STATUS_E_FAILURE, error happens. - * QDF_STATUS_E_NOSUPPORT, the requested mode not supported. - */ -static -QDF_STATUS policy_mgr_validate_dbs_switch( - struct wlan_objmgr_psoc *psoc, - uint32_t session_id, - enum policy_mgr_conc_next_action action, - enum policy_mgr_conn_update_reason reason) +QDF_STATUS +policy_mgr_validate_dbs_switch(struct wlan_objmgr_psoc *psoc, + enum policy_mgr_conc_next_action action) { QDF_STATUS status; struct policy_mgr_hw_mode_params hw_mode; @@ -1046,15 +1027,6 @@ QDF_STATUS policy_mgr_next_actions( return status; } - /* check for the current HW index to see if really need any action */ - status = policy_mgr_validate_dbs_switch(psoc, session_id, action, - reason); - if (!QDF_IS_STATUS_SUCCESS(status)) { - policy_mgr_err(" not take action %d reason %d session %d status %d", - action, reason, session_id, status); - return status; - } - switch (action) { case PM_DBS_DOWNGRADE: /* @@ -1077,7 +1049,7 @@ QDF_STATUS policy_mgr_next_actions( HW_MODE_DBS, HW_MODE_AGILE_DFS_NONE, HW_MODE_SBS_NONE, - reason, PM_NOP); + reason, PM_NOP, PM_DBS); break; case PM_SINGLE_MAC_UPGRADE: /* @@ -1091,7 +1063,8 @@ QDF_STATUS policy_mgr_next_actions( HW_MODE_DBS_NONE, HW_MODE_AGILE_DFS_NONE, HW_MODE_SBS_NONE, - reason, PM_UPGRADE); + reason, PM_UPGRADE, + PM_SINGLE_MAC_UPGRADE); break; case PM_SINGLE_MAC: status = policy_mgr_pdev_set_hw_mode(psoc, session_id, @@ -1102,7 +1075,7 @@ QDF_STATUS policy_mgr_next_actions( HW_MODE_DBS_NONE, HW_MODE_AGILE_DFS_NONE, HW_MODE_SBS_NONE, - reason, PM_NOP); + reason, PM_NOP, PM_SINGLE_MAC); break; case PM_DBS_UPGRADE: status = policy_mgr_pdev_set_hw_mode(psoc, session_id, @@ -1113,7 +1086,8 @@ QDF_STATUS policy_mgr_next_actions( HW_MODE_DBS, HW_MODE_AGILE_DFS_NONE, HW_MODE_SBS_NONE, - reason, PM_UPGRADE); + reason, PM_UPGRADE, + PM_DBS_UPGRADE); break; case PM_SBS_DOWNGRADE: status = policy_mgr_complete_action(psoc, POLICY_MGR_RX_NSS_1, @@ -1128,7 +1102,7 @@ QDF_STATUS policy_mgr_next_actions( HW_MODE_DBS, HW_MODE_AGILE_DFS_NONE, HW_MODE_SBS, - reason, PM_NOP); + reason, PM_NOP, PM_SBS); break; case PM_DOWNGRADE: /* @@ -1178,7 +1152,7 @@ QDF_STATUS policy_mgr_next_actions( HW_MODE_DBS, HW_MODE_AGILE_DFS_NONE, HW_MODE_SBS_NONE, - reason, next_action); + reason, next_action, PM_DBS1); break; case PM_DBS2: /* @@ -1200,7 +1174,7 @@ QDF_STATUS policy_mgr_next_actions( HW_MODE_DBS, HW_MODE_AGILE_DFS_NONE, HW_MODE_SBS_NONE, - reason, next_action); + reason, next_action, PM_DBS2); break; case PM_UPGRADE_5G: status = policy_mgr_nss_update( @@ -2483,10 +2457,15 @@ void policy_mgr_checkn_update_hw_mode_single_mac_mode( return; } - if (QDF_TIMER_STATE_RUNNING == - pm_ctx->dbs_opportunistic_timer.state) + if (QDF_TIMER_STATE_RUNNING == pm_ctx->dbs_opportunistic_timer.state) qdf_mc_timer_stop(&pm_ctx->dbs_opportunistic_timer); + if (policy_mgr_is_hw_dbs_required_for_band(psoc, HW_MODE_MAC_BAND_2G) && + (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq))) { + policy_mgr_debug("DBS required for new connection"); + return; + } + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) { if (pm_conc_connection_list[i].in_use) { @@ -2498,9 +2477,8 @@ void policy_mgr_checkn_update_hw_mode_single_mac_mode( } if (policy_mgr_is_hw_dbs_required_for_band( psoc, HW_MODE_MAC_BAND_2G) && - (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq) || WLAN_REG_IS_24GHZ_CH_FREQ( - pm_conc_connection_list[i].freq))) { + pm_conc_connection_list[i].freq)) { qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); policy_mgr_debug("DBS required"); return; diff --git a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_core.c b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_core.c index 57944ce2c324..24fd8e5771eb 100644 --- a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_core.c +++ b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_core.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -924,7 +924,7 @@ void policy_mgr_pdev_set_hw_mode_cb(uint32_t status, if (status != SET_HW_MODE_STATUS_OK) { policy_mgr_err("Set HW mode failed with status %d", status); - goto set_done_event; + goto next_action; } /* vdev mac map for NAN Discovery is expected in NAN Enable resp */ @@ -966,20 +966,22 @@ void policy_mgr_pdev_set_hw_mode_cb(uint32_t status, if (pm_ctx->mode_change_cb) pm_ctx->mode_change_cb(); - ret = policy_mgr_set_connection_update(context); - if (!QDF_IS_STATUS_SUCCESS(ret)) - policy_mgr_err("ERROR: set connection_update_done event failed"); /* Notify tdls */ if (pm_ctx->tdls_cbacks.tdls_notify_decrement_session) pm_ctx->tdls_cbacks.tdls_notify_decrement_session(pm_ctx->psoc); - if (PM_NOP != next_action) +next_action: + if (PM_NOP != next_action && (status == SET_HW_MODE_STATUS_ALREADY || + status == SET_HW_MODE_STATUS_OK)) policy_mgr_next_actions(context, session_id, next_action, reason); else policy_mgr_debug("No action needed right now"); set_done_event: + ret = policy_mgr_set_connection_update(context); + if (!QDF_IS_STATUS_SUCCESS(ret)) + policy_mgr_err("ERROR: set connection_update_done event failed"); ret = policy_mgr_set_opportunistic_update(context); if (!QDF_IS_STATUS_SUCCESS(ret)) policy_mgr_err("ERROR: set opportunistic_update event failed"); diff --git a/core/hdd/src/wlan_hdd_wext.c b/core/hdd/src/wlan_hdd_wext.c index 44018b93ec4e..7c0e12d08899 100644 --- a/core/hdd/src/wlan_hdd_wext.c +++ b/core/hdd/src/wlan_hdd_wext.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -7509,6 +7509,7 @@ hdd_policy_mgr_set_hw_mode_ut(struct hdd_context *hdd_ctx, enum hw_mode_bandwidth mac1_bw; enum hw_mode_mac_band_cap mac0_band_cap; enum hw_mode_dbs_capab dbs; + enum policy_mgr_conc_next_action action; switch (cmd) { case 0: @@ -7519,6 +7520,7 @@ hdd_policy_mgr_set_hw_mode_ut(struct hdd_context *hdd_ctx, mac1_bw = HW_MODE_BW_NONE; mac0_band_cap = HW_MODE_MAC_BAND_NONE; dbs = HW_MODE_DBS_NONE; + action = PM_SINGLE_MAC; break; case 1: hdd_debug("set hw mode for dual mac"); @@ -7528,6 +7530,7 @@ hdd_policy_mgr_set_hw_mode_ut(struct hdd_context *hdd_ctx, mac1_bw = HW_MODE_40_MHZ; mac0_band_cap = HW_MODE_MAC_BAND_NONE; dbs = HW_MODE_DBS; + action = PM_DBS; break; case 2: hdd_debug("set hw mode for 2x2 5g + 1x1 2g"); @@ -7537,6 +7540,7 @@ hdd_policy_mgr_set_hw_mode_ut(struct hdd_context *hdd_ctx, mac1_bw = HW_MODE_40_MHZ; mac0_band_cap = HW_MODE_MAC_BAND_5G; dbs = HW_MODE_DBS; + action = PM_DBS1; break; case 3: hdd_debug("set hw mode for 2x2 2g + 1x1 5g"); @@ -7546,6 +7550,7 @@ hdd_policy_mgr_set_hw_mode_ut(struct hdd_context *hdd_ctx, mac1_bw = HW_MODE_40_MHZ; mac0_band_cap = HW_MODE_MAC_BAND_2G; dbs = HW_MODE_DBS; + action = PM_DBS2; break; default: hdd_err("unknown cmd %d", cmd); @@ -7555,7 +7560,8 @@ hdd_policy_mgr_set_hw_mode_ut(struct hdd_context *hdd_ctx, mac0_ss, mac0_bw, mac1_ss, mac1_bw, mac0_band_cap, dbs, HW_MODE_AGILE_DFS_NONE, HW_MODE_SBS_NONE, - POLICY_MGR_UPDATE_REASON_UT, PM_NOP); + POLICY_MGR_UPDATE_REASON_UT, PM_NOP, + action); } static int iw_get_policy_manager_ut_ops(struct hdd_context *hdd_ctx, diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index 17f1719e1662..9844b763e601 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -199,7 +199,8 @@ static QDF_STATUS sme_process_set_hw_mode_resp(struct mac_context *mac, uint8_t * needs to be handled after the response of set hw * mode */ - if (param->status == SET_HW_MODE_STATUS_OK) { + if (param->status == SET_HW_MODE_STATUS_OK || + param->status == SET_HW_MODE_STATUS_ALREADY) { sme_debug("search for ssid success"); csr_scan_handle_search_for_ssid(mac, session_id); @@ -12332,6 +12333,7 @@ QDF_STATUS sme_pdev_set_hw_mode(struct policy_mgr_hw_mode msg) cmd->u.set_hw_mode_cmd.reason = msg.reason; cmd->u.set_hw_mode_cmd.session_id = msg.session_id; cmd->u.set_hw_mode_cmd.next_action = msg.next_action; + cmd->u.set_hw_mode_cmd.action = msg.action; cmd->u.set_hw_mode_cmd.context = msg.context; sme_debug("Queuing set hw mode to CSR, session: %d reason: %d", diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index 0314d819087a..43f70d0f3a2d 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -21223,6 +21223,9 @@ void csr_process_set_hw_mode(struct mac_context *mac, tSmeCmd *command) struct scheduler_msg msg = {0}; struct sir_set_hw_mode_resp *param; enum policy_mgr_hw_mode_change hw_mode; + enum policy_mgr_conc_next_action action; + enum set_hw_mode_status hw_mode_change_status = + SET_HW_MODE_STATUS_ECANCELED; /* Setting HW mode is for the entire system. * So, no need to check session @@ -21241,6 +21244,7 @@ void csr_process_set_hw_mode(struct mac_context *mac, tSmeCmd *command) */ goto fail; + action = command->u.set_hw_mode_cmd.action; /* For hidden SSID case, if there is any scan command pending * it needs to be cleared before issuing set HW mode */ @@ -21255,6 +21259,15 @@ void csr_process_set_hw_mode(struct mac_context *mac, tSmeCmd *command) } } + status = policy_mgr_validate_dbs_switch(mac->psoc, action); + + if (QDF_IS_STATUS_ERROR(status)) { + sme_err("Hw mode change not sent to FW status = %d", status); + if (status == QDF_STATUS_E_ALREADY) + hw_mode_change_status = SET_HW_MODE_STATUS_ALREADY; + goto fail; + } + hw_mode = policy_mgr_get_hw_mode_change_from_hw_mode_index( mac->psoc, command->u.set_hw_mode_cmd.hw_mode_index); @@ -21315,7 +21328,7 @@ fail: return; sme_err("Sending set HW fail response to SME"); - param->status = SET_HW_MODE_STATUS_ECANCELED; + param->status = hw_mode_change_status; param->cfgd_hw_mode_index = 0; param->num_vdev_mac_entries = 0; msg.type = eWNI_SME_SET_HW_MODE_RESP;