From 73bfed8cd6a48b684823bcb894a219ebfde83c8d Mon Sep 17 00:00:00 2001 From: Jyoti Kumari Date: Mon, 3 May 2021 15:31:05 +0530 Subject: [PATCH] qcacld-3.0: Handle SAP TWT concurrency scenario TWT is allowed only in DBS/Standalone case and not in SCC/MCC. Handle TWT if any session request comes in SCC/MCC or DBS case as per below: 1. If TWT session request comes on standalone SAP then peer client will initiate the session and not from userspace (SAP DUT) a. Send twt responder enable command and b. Send twt requestor disable command to firmware 2. If session request comes on standalone STA then a. Send twt requestor enable command and b. Send twt responder disable command to firmware 3. If two vdevs are up and SCC/MCC exist a. Send beacon template with twt responder disable command to SAP vdev b. Send twt requestor disable command to STA vdev 4. If two vdevs are up in case of DBS a. Send requestor enable command for STA vdev b. Send beacon template with responder enable command for SAP vdev 5. If 3 port concurrency comes then a. Send requestor disable command to STA vdev and b. Send beacon template with responder disable command to SAP vdev Change-Id: I65994702bb72d5006bd66b2ef57a0704a67410f7 CRs-Fixed: 2938961 --- .../policy_mgr/inc/wlan_policy_mgr_api.h | 10 ++ .../src/wlan_policy_mgr_get_set_utils.c | 52 ++++++ core/hdd/inc/wlan_hdd_main.h | 4 + core/hdd/inc/wlan_hdd_twt.h | 84 ++++++++++ core/hdd/src/wlan_hdd_assoc.c | 5 + core/hdd/src/wlan_hdd_hostapd.c | 2 + core/hdd/src/wlan_hdd_main.c | 32 +++- core/hdd/src/wlan_hdd_twt.c | 156 ++++++++++++++++++ .../src/sys/legacy/src/utils/src/parser_api.c | 31 +++- core/sme/inc/sme_api.h | 16 +- core/sme/src/common/sme_api.c | 14 ++ 11 files changed, 393 insertions(+), 13 deletions(-) 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 3f99bacf2494..2151d6f2d697 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 @@ -2326,6 +2326,16 @@ void policy_mgr_hw_mode_transition_cb(uint32_t old_hw_mode_index, struct policy_mgr_vdev_mac_map *vdev_mac_map, struct wlan_objmgr_psoc *context); +/** + * policy_mgr_current_concurrency_is_scc() - To check the current + * concurrency combination if it is doing SCC + * @psoc: PSOC object information + * This routine is called to check if it is doing SCC + * + * Return: True - SCC, False - Otherwise + */ +bool policy_mgr_current_concurrency_is_scc(struct wlan_objmgr_psoc *psoc); + /** * policy_mgr_current_concurrency_is_mcc() - To check the current * concurrency combination if it is doing MCC diff --git a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c index e3cc251c3a51..efde1ae38709 100644 --- a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c +++ b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c @@ -1609,6 +1609,58 @@ bool policy_mgr_is_scc_with_this_vdev_id(struct wlan_objmgr_psoc *psoc, return false; } +bool policy_mgr_current_concurrency_is_scc(struct wlan_objmgr_psoc *psoc) +{ + uint32_t num_connections = 0; + bool is_scc = false; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return is_scc; + } + + num_connections = policy_mgr_get_connection_count(psoc); + + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + switch (num_connections) { + case 1: + break; + case 2: + if (pm_conc_connection_list[0].freq == + pm_conc_connection_list[1].freq && + pm_conc_connection_list[0].mac == + pm_conc_connection_list[1].mac) { + is_scc = true; + } + break; + case 3: + if (policy_mgr_is_current_hwmode_dbs(psoc) && + (pm_conc_connection_list[0].freq == + pm_conc_connection_list[1].freq || + pm_conc_connection_list[0].freq == + pm_conc_connection_list[2].freq || + pm_conc_connection_list[1].freq == + pm_conc_connection_list[2].freq)) { + is_scc = true; + } else if ((pm_conc_connection_list[0].freq == + pm_conc_connection_list[1].freq) && + (pm_conc_connection_list[0].freq == + pm_conc_connection_list[2].freq)) { + is_scc = true; + } + break; + default: + policy_mgr_debug("unexpected num_connections value %d", + num_connections); + break; + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + + return is_scc; +} + bool policy_mgr_current_concurrency_is_mcc(struct wlan_objmgr_psoc *psoc) { uint32_t num_connections = 0; diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index 83f5d747e7dc..b9aec6230314 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -1850,6 +1850,7 @@ struct hdd_adapter_ops_history { * @multi_client_thermal_mitigation: Multi client thermal mitigation by fw * @disconnect_for_sta_mon_conc: disconnect if sta monitor intf concurrency * @is_dual_mac_cfg_updated: indicate whether dual mac cfg has been updated + * @twt_en_dis_work: work to send twt enable/disable cmd on MCC/SCC concurrency */ struct hdd_context { struct wlan_objmgr_psoc *psoc; @@ -2198,6 +2199,9 @@ struct hdd_context { qdf_event_t regulatory_update_event; qdf_mutex_t regulatory_status_lock; bool is_fw_dbg_log_levels_configured; +#ifdef WLAN_SUPPORT_TWT + qdf_work_t twt_en_dis_work; +#endif }; /** diff --git a/core/hdd/inc/wlan_hdd_twt.h b/core/hdd/inc/wlan_hdd_twt.h index ba009970bcd0..857a87dd399f 100644 --- a/core/hdd/inc/wlan_hdd_twt.h +++ b/core/hdd/inc/wlan_hdd_twt.h @@ -102,6 +102,14 @@ enum twt_status { TWT_CLOSED, }; +/** + * struct twt_conc_arg: TWT concurrency args + * @ hdd_ctx: pointer to hdd context + */ +struct twt_conc_arg { + struct hdd_context *hdd_ctx; +}; + /** * wlan_hdd_cfg80211_wifi_twt_config() - Wifi twt configuration * vendor command @@ -236,6 +244,56 @@ void hdd_send_twt_role_disable_cmd(struct hdd_context *hdd_ctx, */ void hdd_send_twt_del_all_sessions_to_userspace(struct hdd_adapter *adapter); +/** + * hdd_twt_concurrency_update_on_scc_mcc() - Send TWT disable command to fw if + * SCC/MCC exists in two vdevs + * @pdev: pdev pointer + * @object: object pointer + * @arg: arg pointer + * + * Return: None + */ +void hdd_twt_concurrency_update_on_scc_mcc(struct wlan_objmgr_pdev *pdev, + void *object, void *arg); + +/** + * hdd_twt_concurrency_update_on_dbs() - Send TWT enable command to fw if DBS + * exists in two vdevs + * @pdev: pdev pointer + * @object: object pointer + * @arg: arg pointer + * + * Return: None + */ +void hdd_twt_concurrency_update_on_dbs(struct wlan_objmgr_pdev *pdev, + void *object, void *arg); + +/** + * __hdd_twt_update_work_handler() - TWT work handler to send TWT enable/disable + * command to fw + * @hdd_ctx: HDD context pointer + * + * Return: None + */ +void __hdd_twt_update_work_handler(struct hdd_context *hdd_ctx); + +/** + * hdd_twt_update_work_handler() - Wrapper function + * @data: data pointer + * + * Return: None + */ +void hdd_twt_update_work_handler(void *data); + +/** + * wlan_twt_concurrency_update() - Handles twt concurrency in case of SCC/MCC + * or DBS + * @hdd_ctx: hdd context pointer + * + * Return: None + */ +void wlan_twt_concurrency_update(struct hdd_context *hdd_ctx); + #define FEATURE_VENDOR_SUBCMD_WIFI_CONFIG_TWT \ { \ .info.vendor_id = QCA_NL80211_VENDOR_ID, \ @@ -311,6 +369,32 @@ static inline void hdd_send_twt_del_all_sessions_to_userspace(struct hdd_adapter *adapter) { } + +static inline +void hdd_twt_concurrency_update_on_scc_mcc(struct wlan_objmgr_pdev *pdev, + void *object, void *arg) +{ +} + +static inline +void hdd_twt_concurrency_update_on_dbs(struct wlan_objmgr_pdev *pdev, + void *object, void *arg) +{ +} + +static inline +void __hdd_twt_update_work_handler(struct hdd_context *hdd_ctx) +{ +} + +static inline void hdd_twt_update_work_handler(void *data) +{ +} + +static inline void wlan_twt_concurrency_update(struct hdd_context *hdd_ctx) +{ +} + #define FEATURE_VENDOR_SUBCMD_WIFI_CONFIG_TWT #endif diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c index 106fa49a4157..2f9293c48a23 100644 --- a/core/hdd/src/wlan_hdd_assoc.c +++ b/core/hdd/src/wlan_hdd_assoc.c @@ -2069,6 +2069,8 @@ static QDF_STATUS hdd_dis_connect_handler(struct hdd_adapter *adapter, */ sta_ctx->hdd_reassoc_scenario = false; + wlan_twt_concurrency_update(hdd_ctx); + vdev = hdd_objmgr_get_vdev(adapter); if (vdev) { ucfg_if_mgr_deliver_event(vdev, @@ -3417,6 +3419,8 @@ hdd_association_completion_handler(struct hdd_adapter *adapter, WLAN_ALL_SESSIONS_DIALOG_ID); } + wlan_twt_concurrency_update(hdd_ctx); + /* * Following code will be cleaned once the interface manager * module is enabled. @@ -3668,6 +3672,7 @@ hdd_association_completion_handler(struct hdd_adapter *adapter, qdf_mem_zero(connect_complete, sizeof(*connect_complete)); + wlan_twt_concurrency_update(hdd_ctx); connect_complete->status = QDF_STATUS_E_FAILURE; ucfg_if_mgr_deliver_event(adapter->vdev, WLAN_IF_MGR_EV_CONNECT_COMPLETE, diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c index d74d56542767..971083f47dd4 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/core/hdd/src/wlan_hdd_hostapd.c @@ -5897,6 +5897,7 @@ error: wlansap_reset_sap_config_add_ie(config, eUPDATE_IE_ALL); free: + wlan_twt_concurrency_update(hdd_ctx); if (deliver_start_evt) { status = ucfg_if_mgr_deliver_event( adapter->vdev, @@ -6054,6 +6055,7 @@ static int __wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy, adapter->vdev_id); hdd_green_ap_start_state_mc(hdd_ctx, adapter->device_mode, false); + wlan_twt_concurrency_update(hdd_ctx); status = ucfg_if_mgr_deliver_event(adapter->vdev, WLAN_IF_MGR_EV_AP_STOP_BSS_COMPLETE, NULL); diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 370d20628bab..97c7a00cfbe0 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -2228,12 +2228,15 @@ static void hdd_extract_fw_version_info(struct hdd_context *hdd_ctx) #if defined(CONFIG_BAND_6GHZ) && (defined(CFG80211_6GHZ_BAND_SUPPORTED) || \ (KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE)) static void -hdd_update_wiphy_he_caps_6ghz(struct hdd_context *hdd_ctx) +hdd_update_wiphy_he_caps_6ghz(struct hdd_context *hdd_ctx, + tDot11fIEhe_cap *he_cap_cfg) { struct ieee80211_supported_band *band_6g = hdd_ctx->wiphy->bands[HDD_NL80211_BAND_6GHZ]; uint8_t *phy_info = hdd_ctx->iftype_data_6g->he_cap.he_cap_elem.phy_cap_info; + uint8_t *mac_info_6g = + hdd_ctx->iftype_data_6g->he_cap.he_cap_elem.mac_cap_info; uint8_t max_fw_bw = sme_get_vht_ch_width(); if (!band_6g || !phy_info) { @@ -2256,11 +2259,18 @@ hdd_update_wiphy_he_caps_6ghz(struct hdd_context *hdd_ctx) phy_info[0] |= IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G; + if (he_cap_cfg->twt_request) + mac_info_6g[0] |= IEEE80211_HE_MAC_CAP0_TWT_REQ; + + if (he_cap_cfg->twt_responder) + mac_info_6g[0] |= IEEE80211_HE_MAC_CAP0_TWT_RES; + band_6g->iftype_data = hdd_ctx->iftype_data_6g; } #else static inline void -hdd_update_wiphy_he_caps_6ghz(struct hdd_context *hdd_ctx) +hdd_update_wiphy_he_caps_6ghz(struct hdd_context *hdd_ctx, + tDot11fIEhe_cap *he_cap_cfg) { } #endif @@ -2279,6 +2289,10 @@ static void hdd_update_wiphy_he_cap(struct hdd_context *hdd_ctx) uint32_t channel_bonding_mode_2g; uint8_t *phy_info_2g = hdd_ctx->iftype_data_2g->he_cap.he_cap_elem.phy_cap_info; + uint8_t *mac_info_2g = + hdd_ctx->iftype_data_2g->he_cap.he_cap_elem.mac_cap_info; + uint8_t *mac_info_5g = + hdd_ctx->iftype_data_5g->he_cap.he_cap_elem.mac_cap_info; status = ucfg_mlme_cfg_get_he_caps(hdd_ctx->psoc, &he_cap_cfg); @@ -2297,6 +2311,12 @@ static void hdd_update_wiphy_he_cap(struct hdd_context *hdd_ctx) if (channel_bonding_mode_2g) phy_info_2g[0] |= IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G; + + if (he_cap_cfg.twt_request) + mac_info_2g[0] |= IEEE80211_HE_MAC_CAP0_TWT_REQ; + + if (he_cap_cfg.twt_responder) + mac_info_2g[0] |= IEEE80211_HE_MAC_CAP0_TWT_RES; } if (band_5g) { hdd_ctx->iftype_data_5g->types_mask = @@ -2313,9 +2333,15 @@ static void hdd_update_wiphy_he_cap(struct hdd_context *hdd_ctx) if (max_fw_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_80_PLUS_80MHZ) phy_info_5g[0] |= IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G; + + if (he_cap_cfg.twt_request) + mac_info_5g[0] |= IEEE80211_HE_MAC_CAP0_TWT_REQ; + + if (he_cap_cfg.twt_responder) + mac_info_5g[0] |= IEEE80211_HE_MAC_CAP0_TWT_RES; } - hdd_update_wiphy_he_caps_6ghz(hdd_ctx); + hdd_update_wiphy_he_caps_6ghz(hdd_ctx, &he_cap_cfg); } #else static void hdd_update_wiphy_he_cap(struct hdd_context *hdd_ctx) diff --git a/core/hdd/src/wlan_hdd_twt.c b/core/hdd/src/wlan_hdd_twt.c index ca81637f938a..745c76f4ecb4 100644 --- a/core/hdd/src/wlan_hdd_twt.c +++ b/core/hdd/src/wlan_hdd_twt.c @@ -3862,6 +3862,157 @@ void hdd_send_twt_role_disable_cmd(struct hdd_context *hdd_ctx, } } +void hdd_twt_concurrency_update_on_scc_mcc(struct wlan_objmgr_pdev *pdev, + void *object, void *arg) +{ + struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)object; + struct twt_conc_arg *twt_arg = arg; + QDF_STATUS status = QDF_STATUS_SUCCESS; + + if (vdev->vdev_mlme.vdev_opmode == QDF_SAP_MODE && + vdev->vdev_mlme.mlme_state == WLAN_VDEV_S_UP) { + hdd_debug("Concurrency exist on SAP vdev"); + status = hdd_send_twt_responder_disable_cmd(twt_arg->hdd_ctx); + if (QDF_IS_STATUS_ERROR(status)) { + hdd_err("TWT responder disable cmd to firmware failed"); + return; + } + sme_twt_update_beacon_template(twt_arg->hdd_ctx->mac_handle); + } + + if (vdev->vdev_mlme.vdev_opmode == QDF_STA_MODE && + vdev->vdev_mlme.mlme_state == WLAN_VDEV_S_UP) { + hdd_debug("Concurrency exist on STA vdev"); + status = hdd_send_twt_requestor_disable_cmd(twt_arg->hdd_ctx); + if (QDF_IS_STATUS_ERROR(status)) { + hdd_err("TWT requestor disable cmd to firmware failed"); + return; + } + } +} + +void hdd_twt_concurrency_update_on_dbs(struct wlan_objmgr_pdev *pdev, + void *object, void *arg) +{ + struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)object; + struct twt_conc_arg *twt_arg = arg; + QDF_STATUS status = QDF_STATUS_SUCCESS; + + if (vdev->vdev_mlme.vdev_opmode == QDF_SAP_MODE && + vdev->vdev_mlme.mlme_state == WLAN_VDEV_S_UP) { + hdd_debug("SAP vdev exist"); + status = hdd_send_twt_responder_enable_cmd(twt_arg->hdd_ctx); + if (QDF_IS_STATUS_ERROR(status)) { + hdd_err("TWT responder enable cmd to firmware failed"); + return; + } + sme_twt_update_beacon_template(twt_arg->hdd_ctx->mac_handle); + } + + if (vdev->vdev_mlme.vdev_opmode == QDF_STA_MODE && + vdev->vdev_mlme.mlme_state == WLAN_VDEV_S_UP) { + hdd_debug("STA vdev exist"); + status = hdd_send_twt_requestor_enable_cmd(twt_arg->hdd_ctx); + if (QDF_IS_STATUS_ERROR(status)) { + hdd_err("TWT requestor enable cmd to firmware failed"); + return; + } + } +} + +void __hdd_twt_update_work_handler(struct hdd_context *hdd_ctx) +{ + struct twt_conc_arg twt_arg; + uint32_t num_connections = 0, sap_count = 0, sta_count = 0; + int ret; + QDF_STATUS status = QDF_STATUS_SUCCESS; + + ret = wlan_hdd_validate_context(hdd_ctx); + if (ret) { + hdd_err("Invalid HDD context"); + return; + } + num_connections = policy_mgr_get_connection_count(hdd_ctx->psoc); + sta_count = policy_mgr_mode_specific_connection_count(hdd_ctx->psoc, + PM_STA_MODE, + NULL); + sap_count = policy_mgr_mode_specific_connection_count(hdd_ctx->psoc, + PM_SAP_MODE, + NULL); + twt_arg.hdd_ctx = hdd_ctx; + + hdd_debug("Total connection %d, sta_count %d, sap_count %d", + num_connections, sta_count, sap_count); + switch (num_connections) { + case 1: + if (sta_count == 1) { + hdd_send_twt_requestor_enable_cmd(hdd_ctx); + } else if (sap_count == 1) { + hdd_send_twt_responder_enable_cmd(hdd_ctx); + sme_twt_update_beacon_template(hdd_ctx->mac_handle); + } + break; + case 2: + if (policy_mgr_current_concurrency_is_scc(hdd_ctx->psoc) || + policy_mgr_current_concurrency_is_mcc(hdd_ctx->psoc)) { + status = wlan_objmgr_pdev_iterate_obj_list( + hdd_ctx->pdev, + WLAN_VDEV_OP, + hdd_twt_concurrency_update_on_scc_mcc, + &twt_arg, 0, + WLAN_HDD_ID_OBJ_MGR); + if (QDF_IS_STATUS_ERROR(status)) { + hdd_err("SAP not in SCC/MCC concurrency"); + return; + } + } else if (policy_mgr_is_current_hwmode_dbs(hdd_ctx->psoc)) { + status = wlan_objmgr_pdev_iterate_obj_list( + hdd_ctx->pdev, + WLAN_VDEV_OP, + hdd_twt_concurrency_update_on_dbs, + &twt_arg, 0, + WLAN_HDD_ID_OBJ_MGR); + if (QDF_IS_STATUS_ERROR(status)) { + hdd_err("SAP not in DBS case"); + return; + } + } + break; + case 3: + status = wlan_objmgr_pdev_iterate_obj_list( + hdd_ctx->pdev, + WLAN_VDEV_OP, + hdd_twt_concurrency_update_on_scc_mcc, + &twt_arg, 0, + WLAN_HDD_ID_OBJ_MGR); + break; + default: + hdd_err("Unexpected number of connection"); + break; + } +} + +void hdd_twt_update_work_handler(void *data) +{ + struct hdd_context *hdd_ctx = (struct hdd_context *)data; + struct osif_psoc_sync *psoc_sync; + int ret; + + ret = osif_psoc_sync_op_start(wiphy_dev(hdd_ctx->wiphy), &psoc_sync); + if (ret) + return; + + __hdd_twt_update_work_handler(hdd_ctx); + + osif_psoc_sync_op_stop(psoc_sync); +} + +void wlan_twt_concurrency_update(struct hdd_context *hdd_ctx) +{ + qdf_flush_work(&hdd_ctx->twt_en_dis_work); + qdf_sched_work(0, &hdd_ctx->twt_en_dis_work); +} + void wlan_hdd_twt_init(struct hdd_context *hdd_ctx) { QDF_STATUS status; @@ -3900,12 +4051,17 @@ void wlan_hdd_twt_init(struct hdd_context *hdd_ctx) } hdd_send_twt_requestor_enable_cmd(hdd_ctx); + qdf_create_work(0, &hdd_ctx->twt_en_dis_work, + hdd_twt_update_work_handler, hdd_ctx); } void wlan_hdd_twt_deinit(struct hdd_context *hdd_ctx) { QDF_STATUS status; + qdf_flush_work(&hdd_ctx->twt_en_dis_work); + qdf_destroy_work(NULL, &hdd_ctx->twt_en_dis_work); + status = qdf_event_destroy(&hdd_ctx->twt_disable_comp_evt); if (QDF_IS_STATUS_ERROR(status)) hdd_err("Failed to destroy twt_disable_comp_evt"); diff --git a/core/mac/src/sys/legacy/src/utils/src/parser_api.c b/core/mac/src/sys/legacy/src/utils/src/parser_api.c index 5bb7c5bff2ef..c58827243203 100644 --- a/core/mac/src/sys/legacy/src/utils/src/parser_api.c +++ b/core/mac/src/sys/legacy/src/utils/src/parser_api.c @@ -6296,9 +6296,9 @@ populate_dot11f_timing_advert_frame(struct mac_context *mac_ctx, #ifdef WLAN_FEATURE_11AX #ifdef WLAN_SUPPORT_TWT static void -populate_dot11f_broadcast_twt_he_cap(struct mac_context *mac, - struct pe_session *session, - tDot11fIEhe_cap *he_cap) +populate_dot11f_twt_he_cap(struct mac_context *mac, + struct pe_session *session, + tDot11fIEhe_cap *he_cap) { bool bcast_requestor = mac->mlme_cfg->twt_cfg.is_bcast_requestor_enabled; @@ -6306,6 +6306,17 @@ populate_dot11f_broadcast_twt_he_cap(struct mac_context *mac, mac->mlme_cfg->twt_cfg.is_bcast_responder_enabled; he_cap->broadcast_twt = 0; + if (session->opmode == QDF_STA_MODE && + !(mac->mlme_cfg->twt_cfg.req_flag)) { + /* Set twt_request as 0 if any SCC/MCC concurrency exist */ + he_cap->twt_request = 0; + return; + } else if (session->opmode == QDF_SAP_MODE && + !(mac->mlme_cfg->twt_cfg.res_flag)) { + /** Set twt_responder as 0 if any SCC/MCC concurrency exist */ + he_cap->twt_responder = 0; + return; + } if (session->opmode == QDF_STA_MODE) { he_cap->broadcast_twt = bcast_requestor; @@ -6315,9 +6326,9 @@ populate_dot11f_broadcast_twt_he_cap(struct mac_context *mac, } #else static inline void -populate_dot11f_broadcast_twt_he_cap(struct mac_context *mac_ctx, - struct pe_session *session, - tDot11fIEhe_cap *he_cap) +populate_dot11f_twt_he_cap(struct mac_context *mac_ctx, + struct pe_session *session, + tDot11fIEhe_cap *he_cap) { he_cap->broadcast_twt = 0; } @@ -6365,7 +6376,7 @@ QDF_STATUS populate_dot11f_he_caps(struct mac_context *mac_ctx, struct pe_sessio } else { he_cap->ppet.ppe_threshold.num_ppe_th = 0; } - populate_dot11f_broadcast_twt_he_cap(mac_ctx, session, he_cap); + populate_dot11f_twt_he_cap(mac_ctx, session, he_cap); return QDF_STATUS_SUCCESS; } @@ -6494,11 +6505,13 @@ QDF_STATUS populate_dot11f_twt_extended_caps(struct mac_context *mac_ctx, if (pe_session->opmode == QDF_STA_MODE) p_ext_cap->twt_requestor_support = - mac_ctx->mlme_cfg->he_caps.dot11_he_cap.twt_request; + mac_ctx->mlme_cfg->he_caps.dot11_he_cap.twt_request && + mac_ctx->mlme_cfg->twt_cfg.req_flag; if (pe_session->opmode == QDF_SAP_MODE) p_ext_cap->twt_responder_support = - mac_ctx->mlme_cfg->he_caps.dot11_he_cap.twt_responder; + mac_ctx->mlme_cfg->he_caps.dot11_he_cap.twt_responder && + mac_ctx->mlme_cfg->twt_cfg.res_flag; dot11f->num_bytes = lim_compute_ext_cap_ie_length(dot11f); diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h index 73c7b12d9e2c..e4be3dc5d35b 100644 --- a/core/sme/inc/sme_api.h +++ b/core/sme/inc/sme_api.h @@ -3758,8 +3758,16 @@ sme_nudge_dialog_cmd(mac_handle_t mac_handle, QDF_STATUS sme_resume_dialog_cmd(mac_handle_t mac_handle, struct wmi_twt_resume_dialog_cmd_param *twt_params); -#else +/** + * sme_twt_update_beacon_template() - API to send beacon update to fw + * @mac: Global MAC pointer + * + * Return: None + */ +void sme_twt_update_beacon_template(mac_handle_t mac_handle); + +#else static inline QDF_STATUS sme_test_config_twt_setup(struct wmi_twt_add_dialog_param *params) { @@ -3771,6 +3779,12 @@ sme_test_config_twt_terminate(struct wmi_twt_del_dialog_param *params) { return QDF_STATUS_E_FAILURE; } + +static inline void +sme_twt_update_beacon_template(mac_handle_t mac_handle) +{ +} + #endif /** diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index e86af82d6a7b..e14110b1af3e 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -2718,6 +2718,20 @@ sme_process_twt_notify_event(struct mac_context *mac, if (callback) callback(mac->psoc, notify_event); } + +/** + * sme_twt_update_beacon_template() - API to send beacon update to fw + * @mac: Global MAC pointer + * + * Return: None + */ +void sme_twt_update_beacon_template(mac_handle_t mac_handle) +{ + struct mac_context *mac = MAC_CONTEXT(mac_handle); + + csr_update_beacon(mac); +} + #else static void sme_process_twt_add_dialog_event(struct mac_context *mac,