From 7e315ca4af8f44763e296fce55c07498438de0fb Mon Sep 17 00:00:00 2001 From: abhinav kumar Date: Wed, 7 Apr 2021 18:05:44 +0530 Subject: [PATCH] qcacld-3.0: Set time quota for 2 MCC vdevs/adapters If STA + STA connected in MCC, FW should distribute the duty cycle between primary and secondary connection in 70:30 ratio. Quota for the 2nd role is calculated as 100 - quota of first mode. Change-Id: I36ab9a9717da1e1f0ff0e0e11a18681c97ed6c58 CRs-Fixed: 2927460 --- .../mlme/dispatcher/inc/wlan_mlme_api.h | 31 +++++ .../mlme/dispatcher/inc/wlan_mlme_ucfg_api.h | 36 ++++++ .../mlme/dispatcher/src/wlan_mlme_api.c | 116 ++++++++++++++++++ core/hdd/inc/wlan_hdd_main.h | 8 +- core/hdd/src/wlan_hdd_cfg80211.c | 39 +++++- core/hdd/src/wlan_hdd_main.c | 4 +- core/hdd/src/wlan_hdd_p2p.c | 3 +- core/sme/src/csr/csr_api_roam.c | 29 ++++- 8 files changed, 255 insertions(+), 11 deletions(-) diff --git a/components/mlme/dispatcher/inc/wlan_mlme_api.h b/components/mlme/dispatcher/inc/wlan_mlme_api.h index 91b2386b12..b7a410e0a1 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_api.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_api.h @@ -280,6 +280,16 @@ QDF_STATUS wlan_mlme_set_band_capability(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_set_dual_sta_policy(struct wlan_objmgr_psoc *psoc, uint8_t dual_sta_config); +/** + * wlan_mlme_get_dual_sta_policy() - Get the dual sta policy + * @psoc: pointer to psoc object + * @dual_sta_config: Value to be set from the caller + * + * Return: QDF Status + */ +QDF_STATUS wlan_mlme_get_dual_sta_policy(struct wlan_objmgr_psoc *psoc, + uint8_t *dual_sta_config); + /** * wlan_mlme_get_prevent_link_down() - Get the prevent link down config * @psoc: pointer to psoc object @@ -1067,6 +1077,27 @@ QDF_STATUS wlan_mlme_set_fils_enabled_info(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_mlme_set_primary_interface(struct wlan_objmgr_psoc *psoc, uint8_t value); +/** + * wlan_mlme_set_default_primary_iface() - Set the default primary iface id + * for driver + * @psoc: pointer to psoc object + * + * Return: QDF Status + */ +QDF_STATUS wlan_mlme_set_default_primary_iface(struct wlan_objmgr_psoc *psoc); + +/** + * wlan_mlme_get_mcc_duty_cycle_percentage() - Get primary STA iface duty + * cycle percentage + * @psoc: pointer to psoc object + * @value: value that needs to be set from the caller + * + * API to get the MCC duty cycle for primary and secondary STA's + * + * Return: primary iface quota on success + */ +int wlan_mlme_get_mcc_duty_cycle_percentage(struct wlan_objmgr_pdev *pdev); + /** * wlan_mlme_get_tl_delayed_trgr_frm_int() - Get delay interval(in ms) * of UAPSD auto trigger diff --git a/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h b/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h index 97bdfacc51..818ea793c5 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h @@ -270,6 +270,20 @@ QDF_STATUS ucfg_mlme_set_dual_sta_policy(struct wlan_objmgr_psoc *psoc, return wlan_mlme_set_dual_sta_policy(psoc, dual_sta_config); } +/** + * ucfg_mlme_get_dual_sta_policy() - Get the Concurrent STA policy value + * @psoc: pointer to psoc object + * @dual_sta_config: Pointer to the variable from caller + * + * Return: QDF Status + */ +static inline +QDF_STATUS ucfg_mlme_get_dual_sta_policy(struct wlan_objmgr_psoc *psoc, + uint8_t *dual_sta_config) +{ + return wlan_mlme_get_dual_sta_policy(psoc, dual_sta_config); +} + /** * ucfg_mlme_get_prevent_link_down() - Get the prevent link down config * @psoc: pointer to psoc object @@ -1980,6 +1994,28 @@ QDF_STATUS ucfg_mlme_set_primary_interface(struct wlan_objmgr_psoc *psoc, return wlan_mlme_set_primary_interface(psoc, value); } +/** + * ucfg_mlme_get_mcc_duty_cycle_percentage() - Get primary STA iface MCC + * duty-cycle + * + * @psoc: pointer to psoc object + * @value: value that needs to be set from the caller + * + * primary and secondary STA iface MCC duty-cycle value in below format + * ****************************************************** + * |bit 31-24 | bit 23-16 | bits 15-8 |bits 7-0 | + * | Unused | Quota for | chan. # for |chan. # for| + * | | 1st chan | 1st chan. |2nd chan. | + * ***************************************************** + * + * Return: primary iface MCC duty-cycle value + */ +static inline +int ucfg_mlme_get_mcc_duty_cycle_percentage(struct wlan_objmgr_pdev *pdev) +{ + return wlan_mlme_get_mcc_duty_cycle_percentage(pdev); +} + /** * ucfg_mlme_set_enable_bcast_probe_rsp() - Set enable bcast probe resp info * @psoc: pointer to psoc object diff --git a/components/mlme/dispatcher/src/wlan_mlme_api.c b/components/mlme/dispatcher/src/wlan_mlme_api.c index 34ca729a95..d988894727 100644 --- a/components/mlme/dispatcher/src/wlan_mlme_api.c +++ b/components/mlme/dispatcher/src/wlan_mlme_api.c @@ -30,6 +30,9 @@ #include "wlan_utility.h" #include "wlan_policy_mgr_ucfg.h" +/* quota in milliseconds */ +#define MCC_DUTY_CYCLE 70 + QDF_STATUS wlan_mlme_get_cfg_str(uint8_t *dst, struct mlme_cfg_str *cfg_str, qdf_size_t *len) { @@ -245,6 +248,22 @@ QDF_STATUS wlan_mlme_set_dual_sta_policy(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } +QDF_STATUS wlan_mlme_get_dual_sta_policy(struct wlan_objmgr_psoc *psoc, + uint8_t *dual_sta_config) + +{ + struct wlan_mlme_psoc_ext_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_ext_obj(psoc); + if (!mlme_obj) + return QDF_STATUS_E_FAILURE; + + *dual_sta_config = + mlme_obj->cfg.gen.dual_sta_policy.concurrent_sta_policy; + + return QDF_STATUS_SUCCESS; +} + QDF_STATUS wlan_mlme_get_prevent_link_down(struct wlan_objmgr_psoc *psoc, bool *prevent_link_down) { @@ -2420,9 +2439,106 @@ QDF_STATUS wlan_mlme_set_primary_interface(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_E_FAILURE; mlme_obj->cfg.gen.dual_sta_policy.primary_vdev_id = value; + mlme_debug("Set primary iface to :%d", value); + return QDF_STATUS_SUCCESS; } +int wlan_mlme_get_mcc_duty_cycle_percentage(struct wlan_objmgr_pdev *pdev) +{ + struct wlan_objmgr_psoc *psoc = NULL; + struct wlan_mlme_psoc_ext_obj *mlme_obj; + uint32_t op_ch_freq_list[MAX_NUMBER_OF_CONC_CONNECTIONS]; + uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS]; + uint32_t i, operating_channel, quota_value = MCC_DUTY_CYCLE; + struct dual_sta_policy *dual_sta_policy; + uint32_t count, primary_sta_freq = 0, secondary_sta_freq = 0; + + psoc = wlan_pdev_get_psoc(pdev); + if (!psoc) + return -EINVAL; + + mlme_obj = mlme_get_psoc_ext_obj(psoc); + if (!mlme_obj) + return -EINVAL; + dual_sta_policy = &mlme_obj->cfg.gen.dual_sta_policy; + + if (dual_sta_policy->primary_vdev_id == WLAN_INVALID_VDEV_ID || + (dual_sta_policy->concurrent_sta_policy == + QCA_WLAN_CONCURRENT_STA_POLICY_UNBIASED)) { + mlme_debug("Invalid primary vdev id or policy is unbaised :%d", + dual_sta_policy->concurrent_sta_policy); + return -EINVAL; + } + + count = policy_mgr_get_mode_specific_conn_info(psoc, op_ch_freq_list, + vdev_id_list, + PM_STA_MODE); + + /* Proceed only in case of STA+STA */ + if (count != 2) { + mlme_debug("STA+STA concurrency is not present"); + return -EINVAL; + } + + for (i = 0; i < count; i++) { + if (vdev_id_list[i] == dual_sta_policy->primary_vdev_id) { + primary_sta_freq = op_ch_freq_list[i]; + mlme_debug("primary sta vdev:%d at inxex:%d, freq:%d", + i, vdev_id_list[i], op_ch_freq_list[i]); + } else { + secondary_sta_freq = op_ch_freq_list[i]; + mlme_debug("secondary sta vdev:%d at inxex:%d, freq:%d", + i, vdev_id_list[i], op_ch_freq_list[i]); + } + } + + if (!primary_sta_freq || !secondary_sta_freq) { + mlme_debug("Invalid primary or secondary sta freq"); + return -EINVAL; + } + + operating_channel = wlan_freq_to_chan(primary_sta_freq); + + /* + * The channel numbers for both adapters and the time + * quota for the 1st adapter, i.e., one specified in cmd + * are formatted as a bit vector + * ****************************************************** + * |bit 31-24 | bit 23-16 | bits 15-8 |bits 7-0 | + * | Unused | Quota for | chan. # for |chan. # for| + * | | 1st chan | 1st chan. |2nd chan. | + * ****************************************************** + */ + mlme_debug("First connection channel No.:%d and quota:%dms", + operating_channel, quota_value); + /* Move the time quota for first channel to bits 15-8 */ + quota_value = quota_value << 8; + /* + * Store the channel number of 1st channel at bits 7-0 + * of the bit vector + */ + quota_value |= operating_channel; + /* Second STA Connection */ + operating_channel = wlan_freq_to_chan(secondary_sta_freq); + if (!operating_channel) + mlme_debug("Secondary adapter op channel is invalid"); + /* + * Now move the time quota and channel number of the + * 1st adapter to bits 23-16 and bits 15-8 of the bit + * vector, respectively. + */ + quota_value = quota_value << 8; + /* + * Set the channel number for 2nd MCC vdev at bits + * 7-0 of set_value + */ + quota_value |= operating_channel; + mlme_debug("quota value:%x", quota_value); + + return quota_value; +} + QDF_STATUS wlan_mlme_set_enable_bcast_probe_rsp(struct wlan_objmgr_psoc *psoc, bool value) { diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index 9492d25720..5d315d4357 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -4146,15 +4146,15 @@ static inline void hdd_send_peer_status_ind_to_app( #endif /* WIFI_POS_CONVERGENCE */ /** - * wlan_hdd_send_p2p_quota()- Send P2P Quota value to FW + * wlan_hdd_send_mcc_vdev_quota()- Send mcc vdev quota value to FW * @adapter: Adapter data - * @sval: P2P quota value + * @sval: mcc vdev quota value * - * Send P2P quota value to FW + * Send mcc vdev quota value value to FW * * Return: 0 success else failure */ -int wlan_hdd_send_p2p_quota(struct hdd_adapter *adapter, int sval); +int wlan_hdd_send_mcc_vdev_quota(struct hdd_adapter *adapter, int sval); /** * wlan_hdd_send_p2p_quota()- Send MCC latency to FW diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 5bfc27aa35..094fbfea38 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -8633,7 +8633,9 @@ static int hdd_set_primary_interface(struct hdd_adapter *adapter, struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); bool is_set_primary_iface; QDF_STATUS status; - uint8_t primary_vdev_id; + uint8_t primary_vdev_id, dual_sta_policy; + int set_value; + uint32_t count; /* ignore unless in STA mode */ if (adapter->device_mode != QDF_STA_MODE) @@ -8651,6 +8653,41 @@ static int hdd_set_primary_interface(struct hdd_adapter *adapter, return -EINVAL; } + /* + * send duty cycle percentage to FW only if STA + STA + * concurrency is in MCC. + */ + count = policy_mgr_mode_specific_connection_count(hdd_ctx->psoc, + PM_STA_MODE, NULL); + if (count != 2 && + !policy_mgr_current_concurrency_is_mcc(hdd_ctx->psoc)) { + hdd_debug("STA + STA concurrency is in MCC not present"); + return -EINVAL; + } + + status = ucfg_mlme_get_dual_sta_policy(hdd_ctx->psoc, &dual_sta_policy); + if (QDF_IS_STATUS_ERROR(status)) { + hdd_err("could not get dual sta policy, %d", status); + return -EINVAL; + } + + if (is_set_primary_iface && dual_sta_policy == + QCA_WLAN_CONCURRENT_STA_POLICY_PREFER_PRIMARY) { + set_value = + ucfg_mlme_get_mcc_duty_cycle_percentage(hdd_ctx->pdev); + if (set_value < 0) { + hdd_err("Invalid mcc duty cycle"); + return -EINVAL; + } + + if (QDF_IS_STATUS_ERROR(sme_set_mas(false))) { + hdd_err("Failed to disable mcc_adaptive_scheduler"); + return -EINVAL; + } + + wlan_hdd_send_mcc_vdev_quota(adapter, set_value); + } + return 0; } diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 6a8a7f8401..c80e2e0689 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -18629,13 +18629,13 @@ bool hdd_set_connection_in_progress(bool value) return status; } -int wlan_hdd_send_p2p_quota(struct hdd_adapter *adapter, int set_value) +int wlan_hdd_send_mcc_vdev_quota(struct hdd_adapter *adapter, int set_value) { if (!adapter) { hdd_err("Invalid adapter"); return -EINVAL; } - hdd_info("Send MCC P2P QUOTA to WMA: %d", set_value); + hdd_info("send mcc vdev quota to fw: %d", set_value); sme_cli_set_command(adapter->vdev_id, WMA_VDEV_MCC_SET_TIME_QUOTA, set_value, VDEV_CMD); diff --git a/core/hdd/src/wlan_hdd_p2p.c b/core/hdd/src/wlan_hdd_p2p.c index e60f566a0b..26516cdeca 100644 --- a/core/hdd/src/wlan_hdd_p2p.c +++ b/core/hdd/src/wlan_hdd_p2p.c @@ -1445,8 +1445,7 @@ int wlan_hdd_set_mcc_p2p_quota(struct hdd_adapter *adapter, set_value = set_second_connection_operating_channel( hdd_ctx, set_value, adapter->vdev_id); - - ret = wlan_hdd_send_p2p_quota(adapter, set_value); + ret = wlan_hdd_send_mcc_vdev_quota(adapter, set_value); } else { hdd_info("MCC is not active. Exit w/o setting latency"); } diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index 490b174f5e..3828c9cb8b 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -12689,9 +12689,11 @@ cm_csr_connect_done_ind(struct wlan_objmgr_vdev *vdev, { struct mac_context *mac_ctx; uint8_t vdev_id = wlan_vdev_get_id(vdev); - int32_t ucast_cipher; + int32_t ucast_cipher, count; struct set_context_rsp install_key_rsp; - int32_t rsn_cap; + int32_t rsn_cap, set_value; + struct wlan_mlme_psoc_ext_obj *mlme_obj; + struct dual_sta_policy *dual_sta_policy; /* * This API is to update legacy struct and should be removed once @@ -12702,6 +12704,10 @@ cm_csr_connect_done_ind(struct wlan_objmgr_vdev *vdev, if (!mac_ctx) return QDF_STATUS_E_INVAL; + mlme_obj = mlme_get_psoc_ext_obj(mac_ctx->psoc); + if (!mlme_obj) + return QDF_STATUS_E_INVAL; + if (QDF_IS_STATUS_ERROR(rsp->connect_status)) { cm_csr_set_idle(vdev_id); sme_qos_update_hand_off(vdev_id, false); @@ -12712,6 +12718,25 @@ cm_csr_connect_done_ind(struct wlan_objmgr_vdev *vdev, return QDF_STATUS_SUCCESS; } + dual_sta_policy = &mlme_obj->cfg.gen.dual_sta_policy; + count = policy_mgr_mode_specific_connection_count(mac_ctx->psoc, + PM_STA_MODE, NULL); + /* + * send duty cycle percentage to FW only if STA + STA + * concurrency is in MCC. + */ + if (dual_sta_policy->primary_vdev_id != WLAN_UMAC_VDEV_ID_MAX && + dual_sta_policy->concurrent_sta_policy == + QCA_WLAN_CONCURRENT_STA_POLICY_PREFER_PRIMARY && count == 2 && + policy_mgr_current_concurrency_is_mcc(mac_ctx->psoc)) { + if (QDF_IS_STATUS_ERROR(sme_set_mas(false))) + sme_err("Failed to disable mcc_adaptive_scheduler"); + set_value = + wlan_mlme_get_mcc_duty_cycle_percentage(mac_ctx->pdev); + sme_cli_set_command(vdev_id, WMA_VDEV_MCC_SET_TIME_QUOTA, + set_value, VDEV_CMD); + } + /* * For open mode authentication, send dummy install key response to * send OBSS scan and QOS event.