From fec051ecaef6e48e0580e4d18a91c91a68e6052a Mon Sep 17 00:00:00 2001 From: Subrat Dash Date: Wed, 18 Nov 2020 17:07:09 +0530 Subject: [PATCH] qcacld-3.0: Add support to enable TWT roles There are cases where only a few TWT roles may be required to be enabled. For example TWT Requestor role alone or TWT Respondor role alone. Also, it could be unicast TWT only and disable broadcast TWT. Support broadcast TWT configuration in requestor and responder role by adding new INI. Extend the use of existing requestor and responder INIs to further enable requestor and responder roles itself. Change-Id: I3dfa196edfda9cafd01fa56c0bb6ce73e27b4144 CRs-Fixed: 2828718 --- components/mlme/core/src/wlan_mlme_main.c | 4 + components/mlme/dispatcher/inc/cfg_mlme_twt.h | 60 +++++- .../dispatcher/inc/wlan_mlme_public_struct.h | 4 + .../mlme/dispatcher/inc/wlan_mlme_ucfg_api.h | 149 +++++++++++++++ .../mlme/dispatcher/src/wlan_mlme_ucfg_api.c | 72 ++++++++ core/hdd/inc/wlan_hdd_twt.h | 38 ++++ core/hdd/src/wlan_hdd_p2p.c | 7 + core/hdd/src/wlan_hdd_twt.c | 174 ++++++++++++++++-- core/wma/inc/wma_tgt_cfg.h | 6 + core/wma/inc/wma_twt.h | 67 ++++++- core/wma/src/wma_main.c | 21 --- core/wma/src/wma_twt.c | 47 ++++- 12 files changed, 587 insertions(+), 62 deletions(-) diff --git a/components/mlme/core/src/wlan_mlme_main.c b/components/mlme/core/src/wlan_mlme_main.c index e695186546..d5d95402de 100644 --- a/components/mlme/core/src/wlan_mlme_main.c +++ b/components/mlme/core/src/wlan_mlme_main.c @@ -1193,11 +1193,15 @@ static void mlme_init_he_cap_in_cfg(struct wlan_objmgr_psoc *psoc, static void mlme_init_twt_cfg(struct wlan_objmgr_psoc *psoc, struct wlan_mlme_cfg_twt *twt_cfg) { + uint32_t bcast_conf = cfg_get(psoc, CFG_BCAST_TWT_REQ_RESP); + twt_cfg->is_twt_bcast_enabled = cfg_get(psoc, CFG_BCAST_TWT); twt_cfg->is_twt_enabled = cfg_get(psoc, CFG_ENABLE_TWT); twt_cfg->is_twt_responder_enabled = cfg_get(psoc, CFG_TWT_RESPONDER); twt_cfg->is_twt_requestor_enabled = cfg_get(psoc, CFG_TWT_REQUESTOR); twt_cfg->twt_congestion_timeout = cfg_get(psoc, CFG_TWT_CONGESTION_TIMEOUT); + twt_cfg->is_bcast_requestor_enabled = CFG_TWT_GET_BCAST_REQ(bcast_conf); + twt_cfg->is_bcast_responder_enabled = CFG_TWT_GET_BCAST_RES(bcast_conf); } #ifdef WLAN_FEATURE_SAE diff --git a/components/mlme/dispatcher/inc/cfg_mlme_twt.h b/components/mlme/dispatcher/inc/cfg_mlme_twt.h index 2bbaf6a94a..b19da46a71 100644 --- a/components/mlme/dispatcher/inc/cfg_mlme_twt.h +++ b/components/mlme/dispatcher/inc/cfg_mlme_twt.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2018, 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 @@ -28,7 +28,7 @@ * twt_requestor - twt requestor. * @Min: 0 * @Max: 1 - * @Default: 0 + * @Default: 1 * * This cfg is used to store twt requestor config. * @@ -42,14 +42,14 @@ */ #define CFG_TWT_REQUESTOR CFG_INI_BOOL( \ "twt_requestor", \ - 0, \ + 1, \ "TWT requestor") /* * * twt_responder - twt responder. * @Min: 0 * @Max: 1 - * @Default: 0 + * @Default: 1 * * This cfg is used to store twt responder config. * @@ -63,7 +63,7 @@ */ #define CFG_TWT_RESPONDER CFG_INI_BOOL( \ "twt_responder", \ - 0, \ + 1, \ "TWT responder") /* @@ -138,12 +138,58 @@ 100, \ CFG_VALUE_OR_DEFAULT, \ "twt congestion timeout") +/* + * + * twt_bcast_req_resp_config - To enable broadcast twt requestor and responder. + * @Min: 0 Disable the extended twt capability + * @Max: 3 + * @Default: 0 + * + * This cfg is used to configure the broadcast TWT requestor and responder. + * Bitmap for enabling the broadcast twt requestor and responder. + * BIT 0: Enable/Disable broadcast twt requestor. + * BIT 1: Enable/Disable broadcast twt responder. + * BIT 2-31: Reserved + * + * Related: CFG_ENABLE_TWT + * Related: CFG_TWT_RESPONDER + * Related: CFG_TWT_REQUESTOR + * + * Supported Feature: 11AX + * + * Usage: External + * + * + */ +/* defines to extract the requestor/responder capabilities from cfg */ +#define TWT_BCAST_REQ_INDEX 0 +#define TWT_BCAST_REQ_BITS 1 +#define TWT_BCAST_RES_INDEX 1 +#define TWT_BCAST_RES_BITS 1 + +#define CFG_BCAST_TWT_REQ_RESP CFG_INI_UINT( \ + "twt_bcast_req_resp_config", \ + 0, \ + 3, \ + 0, \ + CFG_VALUE_OR_DEFAULT, \ + "BROADCAST TWT CAPABILITY") + +#define CFG_TWT_GET_BCAST_REQ(_bcast_conf) \ + QDF_GET_BITS(_bcast_conf, \ + TWT_BCAST_REQ_INDEX, \ + TWT_BCAST_REQ_BITS) + +#define CFG_TWT_GET_BCAST_RES(_bcast_conf) \ + QDF_GET_BITS(_bcast_conf, \ + TWT_BCAST_RES_INDEX, \ + TWT_BCAST_RES_BITS) #define CFG_TWT_ALL \ CFG(CFG_BCAST_TWT) \ CFG(CFG_ENABLE_TWT) \ CFG(CFG_TWT_REQUESTOR) \ CFG(CFG_TWT_RESPONDER) \ - CFG(CFG_TWT_CONGESTION_TIMEOUT) - + CFG(CFG_TWT_CONGESTION_TIMEOUT) \ + CFG(CFG_BCAST_TWT_REQ_RESP) #endif /* __CFG_MLME_TWT_H */ diff --git a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h index cdb2acf75d..6b433dbf73 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h @@ -1396,6 +1396,8 @@ struct wlan_mlme_acs { * @is_twt_enabled: global twt configuration * @is_twt_responder_enabled: twt responder * @is_twt_requestor_enabled: twt requestor + * @is_bcast_responder_enabled: bcast responder enable/disable + * @is_bcast_requestor_enabled: bcast requestor enable/disable * @twt_congestion_timeout: congestion timeout value */ struct wlan_mlme_cfg_twt { @@ -1403,6 +1405,8 @@ struct wlan_mlme_cfg_twt { bool is_twt_enabled; bool is_twt_responder_enabled; bool is_twt_requestor_enabled; + bool is_bcast_responder_enabled; + bool is_bcast_requestor_enabled; uint32_t twt_congestion_timeout; }; diff --git a/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h b/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h index 06bb14cc87..9cd6a1fd8d 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h @@ -889,6 +889,7 @@ QDF_STATUS ucfg_mlme_set_pmkid_modes(struct wlan_objmgr_psoc *psoc, uint32_t val); +#ifdef WLAN_SUPPORT_TWT /** * ucfg_mlme_get_twt_requestor() - Get twt requestor * @psoc: pointer to psoc object @@ -999,6 +1000,154 @@ QDF_STATUS ucfg_mlme_set_enable_twt(struct wlan_objmgr_psoc *psoc, bool val); +/** + * ucfg_mlme_get_twt_bcast_requestor() - Get twt requestor enabled + * @psoc: pointer to psoc object + * @val: Pointer to the value which will be filled for the caller + * + * Return: QDF Status + */ +QDF_STATUS +ucfg_mlme_get_twt_bcast_requestor(struct wlan_objmgr_psoc *psoc, + bool *val); + +/** + * ucfg_mlme_set_twt_bcast_requestor() - Set Global twt bcast requestor support + * @psoc: pointer to psoc object + * @val: Value to be set to config + * + * Return: QDF Status + */ +QDF_STATUS +ucfg_mlme_set_twt_bcast_requestor(struct wlan_objmgr_psoc *psoc, + bool val); +/** + * ucfg_mlme_get_twt_bcast_responder() - Get twt responder enabled + * @psoc: pointer to psoc object + * @val: Pointer to the value which will be filled for the caller + * + * Return: QDF Status + */ +QDF_STATUS +ucfg_mlme_get_twt_bcast_responder(struct wlan_objmgr_psoc *psoc, + bool *val); + +/** + * ucfg_mlme_set_twt_bcast_responder() - Set Global twt bcast responder support + * @psoc: pointer to psoc object + * @val: Value to be set to config + * + * Return: QDF Status + */ +QDF_STATUS +ucfg_mlme_set_twt_bcast_responder(struct wlan_objmgr_psoc *psoc, + bool val); +#else +static inline QDF_STATUS +ucfg_mlme_get_twt_requestor(struct wlan_objmgr_psoc *psoc, + bool *val) +{ + *val = false; + return QDF_STATUS_E_NOSUPPORT; +} + +static inline QDF_STATUS +ucfg_mlme_set_twt_requestor(struct wlan_objmgr_psoc *psoc, + bool val) +{ + return QDF_STATUS_E_NOSUPPORT; +} + +static inline QDF_STATUS +ucfg_mlme_get_twt_responder(struct wlan_objmgr_psoc *psoc, + bool *val) +{ + *val = false; + return QDF_STATUS_E_NOSUPPORT; +} + +static inline QDF_STATUS +ucfg_mlme_set_twt_responder(struct wlan_objmgr_psoc *psoc, + bool val) +{ + return QDF_STATUS_E_NOSUPPORT; +} + +static inline QDF_STATUS +ucfg_mlme_get_bcast_twt(struct wlan_objmgr_psoc *psoc, + bool *val) +{ + *val = false; + return QDF_STATUS_E_NOSUPPORT; +} + +static inline QDF_STATUS +ucfg_mlme_set_bcast_twt(struct wlan_objmgr_psoc *psoc, + bool val) +{ + return QDF_STATUS_E_NOSUPPORT; +} + +static inline QDF_STATUS +ucfg_mlme_get_twt_congestion_timeout(struct wlan_objmgr_psoc *psoc, + uint32_t *val) +{ + *val = 0; + return QDF_STATUS_E_NOSUPPORT; +} + +static inline QDF_STATUS +ucfg_mlme_set_twt_congestion_timeout(struct wlan_objmgr_psoc *psoc, + uint32_t val) +{ + return QDF_STATUS_E_NOSUPPORT; +} + +static inline QDF_STATUS +ucfg_mlme_get_enable_twt(struct wlan_objmgr_psoc *psoc, + bool *val) +{ + *val = false; + return QDF_STATUS_E_NOSUPPORT; +} + +static inline QDF_STATUS +ucfg_mlme_set_enable_twt(struct wlan_objmgr_psoc *psoc, + bool val) +{ + return QDF_STATUS_E_NOSUPPORT; +} + +static inline QDF_STATUS +ucfg_mlme_get_twt_bcast_requestor(struct wlan_objmgr_psoc *psoc, + bool *val) +{ + *val = false; + return QDF_STATUS_E_NOSUPPORT; +} + +static inline QDF_STATUS +ucfg_mlme_set_twt_bcast_requestor(struct wlan_objmgr_psoc *psoc, + bool val) +{ + return QDF_STATUS_E_NOSUPPORT; +} + +static inline QDF_STATUS +ucfg_mlme_get_twt_bcast_responder(struct wlan_objmgr_psoc *psoc, + bool *val) +{ + *val = false; + return QDF_STATUS_E_NOSUPPORT; +} + +static inline QDF_STATUS +ucfg_mlme_set_twt_bcast_responder(struct wlan_objmgr_psoc *psoc, + bool val) +{ + return QDF_STATUS_E_NOSUPPORT; +} +#endif /** * ucfg_mlme_get_dot11p_mode() - Get the setting about 802.11p mode * @psoc: pointer to psoc object diff --git a/components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c b/components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c index 5ac49133d6..0ff011da25 100644 --- a/components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c +++ b/components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c @@ -508,6 +508,7 @@ ucfg_mlme_set_pmkid_modes(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } +#ifdef WLAN_SUPPORT_TWT QDF_STATUS ucfg_mlme_get_twt_requestor(struct wlan_objmgr_psoc *psoc, bool *val) @@ -668,6 +669,77 @@ ucfg_mlme_set_enable_twt(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } +QDF_STATUS +ucfg_mlme_get_twt_bcast_requestor(struct wlan_objmgr_psoc *psoc, + bool *val) +{ + struct wlan_mlme_psoc_ext_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_ext_obj(psoc); + if (!mlme_obj) { + uint32_t b_req_res; + + b_req_res = cfg_default(CFG_BCAST_TWT_REQ_RESP); + *val = CFG_TWT_GET_BCAST_REQ(b_req_res); + return QDF_STATUS_E_INVAL; + } + + *val = mlme_obj->cfg.twt_cfg.is_bcast_requestor_enabled; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +ucfg_mlme_get_twt_bcast_responder(struct wlan_objmgr_psoc *psoc, + bool *val) +{ + struct wlan_mlme_psoc_ext_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_ext_obj(psoc); + if (!mlme_obj) { + uint32_t b_req_res; + + b_req_res = cfg_default(CFG_BCAST_TWT_REQ_RESP); + *val = CFG_TWT_GET_BCAST_RES(b_req_res); + return QDF_STATUS_E_INVAL; + } + + *val = mlme_obj->cfg.twt_cfg.is_bcast_responder_enabled; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +ucfg_mlme_set_twt_bcast_requestor(struct wlan_objmgr_psoc *psoc, + bool val) +{ + struct wlan_mlme_psoc_ext_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_ext_obj(psoc); + if (!mlme_obj) + return QDF_STATUS_E_INVAL; + + mlme_obj->cfg.twt_cfg.is_bcast_requestor_enabled = val; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +ucfg_mlme_set_twt_bcast_responder(struct wlan_objmgr_psoc *psoc, + bool val) +{ + struct wlan_mlme_psoc_ext_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_ext_obj(psoc); + if (!mlme_obj) + return QDF_STATUS_E_INVAL; + + mlme_obj->cfg.twt_cfg.is_bcast_responder_enabled = val; + + return QDF_STATUS_SUCCESS; +} +#endif + QDF_STATUS ucfg_mlme_get_dot11p_mode(struct wlan_objmgr_psoc *psoc, enum dot11p_mode *out_mode) diff --git a/core/hdd/inc/wlan_hdd_twt.h b/core/hdd/inc/wlan_hdd_twt.h index cf1ef0f22e..60ee83353d 100644 --- a/core/hdd/inc/wlan_hdd_twt.h +++ b/core/hdd/inc/wlan_hdd_twt.h @@ -42,6 +42,29 @@ struct wmi_twt_resume_dialog_cmd_param; extern const struct nla_policy wlan_hdd_wifi_twt_config_policy[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_MAX + 1]; +/** + * enum twt_role - TWT role definitions + * @TWT_REQUESTOR: Individual/Bcast TWT requestor role + * @TWT_REQUESTOR_INDV: Individual TWT requestor role + * @TWT_REQUESTOR_BCAST: Broadcast TWT requestor role + * @TWT_RESPONDER: Individual/Bcast TWT responder role + * @TWT_RESPONDER_INDV: Individual TWT responder role + * @TWT_RESPONDER_BCAST: Broadcast TWT responder role + * @TWT_ROLE_ALL: All TWT roles + */ +enum twt_role { + TWT_REQUESTOR, + TWT_REQUESTOR_INDV, + /* Bcast alone cannot be enabled, but can be disabled */ + TWT_REQUESTOR_BCAST, + TWT_RESPONDER, + TWT_RESPONDER_INDV, + /* Bcast alone cannot be enabled, but can be disabled */ + TWT_RESPONDER_BCAST, + TWT_ROLE_ALL, + TWT_ROLE_MAX, +}; + #ifdef WLAN_SUPPORT_TWT /** * enum twt_status - TWT target state @@ -165,6 +188,16 @@ int hdd_test_config_twt_setup_session(struct hdd_adapter *adapter, */ int hdd_test_config_twt_terminate_session(struct hdd_adapter *adapter, struct nlattr **tb); +/** + * hdd_send_twt_role_disable_cmd() - Send a specific TWT role + * disable to firmware + * @hdd_ctx: hdd context pointer + * @role : TWT role to be disabled + * + * Return: None + */ +void hdd_send_twt_role_disable_cmd(struct hdd_context *hdd_ctx, + enum twt_role role); #define FEATURE_VENDOR_SUBCMD_WIFI_CONFIG_TWT \ { \ @@ -216,6 +249,11 @@ int hdd_test_config_twt_terminate_session(struct hdd_adapter *adapter, return -EINVAL; } +static inline +void hdd_send_twt_role_disable_cmd(struct hdd_context *hdd_ctx, + enum twt_role role) +{ +} #define FEATURE_VENDOR_SUBCMD_WIFI_CONFIG_TWT #endif diff --git a/core/hdd/src/wlan_hdd_p2p.c b/core/hdd/src/wlan_hdd_p2p.c index d0b98877c5..665c54bb25 100644 --- a/core/hdd/src/wlan_hdd_p2p.c +++ b/core/hdd/src/wlan_hdd_p2p.c @@ -905,6 +905,7 @@ static void hdd_clean_up_interface(struct hdd_context *hdd_ctx, hdd_stop_adapter(hdd_ctx, adapter); hdd_deinit_adapter(hdd_ctx, adapter, true); hdd_close_adapter(hdd_ctx, adapter, true); + hdd_send_twt_enable_cmd(hdd_ctx); } int __wlan_hdd_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev) @@ -1201,6 +1202,12 @@ int wlan_hdd_set_power_save(struct hdd_adapter *adapter, status = ucfg_p2p_set_ps(psoc, ps_config); hdd_debug("p2p set power save, status:%d", status); + /* P2P-GO-NOA and TWT do not go hand in hand */ + if (ps_config->duration) + hdd_send_twt_role_disable_cmd(hdd_ctx, TWT_RESPONDER); + else + hdd_send_twt_enable_cmd(hdd_ctx); + return qdf_status_to_os_return(status); } diff --git a/core/hdd/src/wlan_hdd_twt.c b/core/hdd/src/wlan_hdd_twt.c index 81b455d985..3bd57a76cd 100644 --- a/core/hdd/src/wlan_hdd_twt.c +++ b/core/hdd/src/wlan_hdd_twt.c @@ -33,6 +33,7 @@ #include "wma_twt.h" #include "osif_sync.h" #include "wlan_osif_request_manager.h" +#include "cfg_ucfg_api.h" #include #define TWT_SETUP_COMPLETE_TIMEOUT 4000 @@ -1998,51 +1999,134 @@ void hdd_update_tgt_twt_cap(struct hdd_context *hdd_ctx, struct wma_tgt_cfg *cfg) { struct wma_tgt_services *services = &cfg->services; - bool enable_twt = false; + bool twt_bcast_req; + bool twt_bcast_res; + bool enable_twt; + bool twt_req; + bool twt_res; ucfg_mlme_get_enable_twt(hdd_ctx->psoc, &enable_twt); - hdd_debug("TWT: enable_twt=%d, tgt Req=%d, Res=%d", - enable_twt, services->twt_requestor, - services->twt_responder); + + ucfg_mlme_get_twt_requestor(hdd_ctx->psoc, &twt_req); + + ucfg_mlme_get_twt_responder(hdd_ctx->psoc, &twt_res); + + ucfg_mlme_get_twt_bcast_requestor(hdd_ctx->psoc, + &twt_bcast_req); + + ucfg_mlme_get_twt_bcast_responder(hdd_ctx->psoc, + &twt_bcast_res); + + hdd_debug("ini: enable_twt=%d, bcast_req=%d, bcast_res=%d", + enable_twt, twt_bcast_req, twt_bcast_res); + hdd_debug("ini: twt_req=%d, twt_res=%d", twt_req, twt_res); + hdd_debug("svc: req=%d, res=%d, bcast_req=%d, bcast_res=%d", + services->twt_requestor, services->twt_responder, + cfg->twt_bcast_req_support, cfg->twt_bcast_res_support); ucfg_mlme_set_twt_requestor(hdd_ctx->psoc, QDF_MIN(services->twt_requestor, - enable_twt)); + (enable_twt && twt_req))); ucfg_mlme_set_twt_responder(hdd_ctx->psoc, QDF_MIN(services->twt_responder, - enable_twt)); + (enable_twt && twt_res))); + + twt_req = enable_twt && twt_bcast_req; + ucfg_mlme_set_twt_bcast_requestor(hdd_ctx->psoc, + QDF_MIN(cfg->twt_bcast_req_support, + twt_req)); + + twt_res = enable_twt && twt_bcast_res; + ucfg_mlme_set_twt_bcast_responder(hdd_ctx->psoc, + QDF_MIN(cfg->twt_bcast_res_support, + twt_res)); } void hdd_send_twt_enable_cmd(struct hdd_context *hdd_ctx) { uint8_t pdev_id = hdd_ctx->pdev->pdev_objmgr.wlan_pdev_id; - bool req_val = 0, resp_val = 0, bcast_val = 0; - uint32_t congestion_timeout = 0; + struct twt_enable_disable_conf twt_en_dis = {0}; + bool is_requestor_en; + bool is_responder_en; + bool twt_bcast_en; - ucfg_mlme_get_twt_requestor(hdd_ctx->psoc, &req_val); - ucfg_mlme_get_twt_responder(hdd_ctx->psoc, &resp_val); - ucfg_mlme_get_bcast_twt(hdd_ctx->psoc, &bcast_val); + /* Get MLME TWT config */ + ucfg_mlme_get_twt_requestor(hdd_ctx->psoc, &is_requestor_en); + ucfg_mlme_get_twt_responder(hdd_ctx->psoc, &is_responder_en); + ucfg_mlme_get_bcast_twt(hdd_ctx->psoc, &twt_en_dis.bcast_en); ucfg_mlme_get_twt_congestion_timeout(hdd_ctx->psoc, - &congestion_timeout); + &twt_en_dis.congestion_timeout); + hdd_debug("TWT mlme cfg:req: %d, res:%d, bcast:%d, cong:%d, pdev:%d", + is_requestor_en, is_responder_en, twt_en_dis.bcast_en, + twt_en_dis.congestion_timeout, pdev_id); - hdd_debug("TWT cfg req:%d, responder:%d, bcast:%d, pdev:%d, cong:%d", - req_val, resp_val, bcast_val, pdev_id, congestion_timeout); + /* The below code takes care of the following : + * If user wants to separately enable requestor and responder roles, + * and also the broadcast TWT capaibilities separately for each role. + * This is done by reusing the INI configuration to indicate the user + * preference and sending the command accordingly. + * Legacy targets did not provide this. Newer targets provide this. + * + * 1. The MLME config holds the intersection of fw cap and user config + * 2. This may result in two enable commands sent for legacy, but + * that's fine, since the firmware returns harmlessly for the + * second command. + * 3. The new two parameters in the enable command are ignored + * by legacy targets, and honored by new targets. + */ - if (req_val || resp_val || bcast_val) - wma_send_twt_enable_cmd(pdev_id, congestion_timeout, bcast_val); + /* If requestor configured, send requestor bcast/ucast config */ + if (is_requestor_en) { + twt_en_dis.role = WMI_TWT_ROLE_REQUESTOR; + twt_en_dis.ext_conf_present = true; + ucfg_mlme_get_twt_bcast_requestor(hdd_ctx->psoc, &twt_bcast_en); + if (twt_bcast_en) + twt_en_dis.oper = WMI_TWT_OPERATION_BROADCAST; + else + twt_en_dis.oper = WMI_TWT_OPERATION_INDIVIDUAL; + + wma_send_twt_enable_cmd(pdev_id, &twt_en_dis); + } + + /* If responder configured, send responder bcast/ucast config */ + if (is_responder_en) { + twt_en_dis.role = WMI_TWT_ROLE_RESPONDER; + twt_en_dis.ext_conf_present = true; + ucfg_mlme_get_twt_bcast_responder(hdd_ctx->psoc, &twt_bcast_en); + if (twt_bcast_en) + twt_en_dis.oper = WMI_TWT_OPERATION_BROADCAST; + else + twt_en_dis.oper = WMI_TWT_OPERATION_INDIVIDUAL; + + wma_send_twt_enable_cmd(pdev_id, &twt_en_dis); + } + + return; } QDF_STATUS hdd_send_twt_disable_cmd(struct hdd_context *hdd_ctx) { uint8_t pdev_id = hdd_ctx->pdev->pdev_objmgr.wlan_pdev_id; + struct twt_enable_disable_conf twt_en_dis = {0}; + QDF_STATUS status; hdd_debug("TWT disable cmd :pdev:%d", pdev_id); - wma_send_twt_disable_cmd(pdev_id); + /* One disable should be fine, with extended configuration + * set to false, and extended arguments will be ignored by target + */ + hdd_ctx->twt_state = TWT_DISABLE_REQUESTED; + twt_en_dis.ext_conf_present = false; + wma_send_twt_disable_cmd(pdev_id, &twt_en_dis); - return qdf_wait_single_event(&hdd_ctx->twt_disable_comp_evt, - TWT_DISABLE_COMPLETE_TIMEOUT); + status = qdf_wait_single_event(&hdd_ctx->twt_disable_comp_evt, + TWT_DISABLE_COMPLETE_TIMEOUT); + + if (!QDF_IS_STATUS_SUCCESS(status)) + hdd_warn("TWT Responder disable timedout"); + + return status; } /** @@ -2103,8 +2187,12 @@ hdd_twt_disable_comp_cb(hdd_handle_t hdd_handle) hdd_err("TWT: Invalid HDD Context"); return; } + prev_state = hdd_ctx->twt_state; - hdd_ctx->twt_state = TWT_DISABLED; + /* Do not change the state for role specific disables */ + if (hdd_ctx->twt_state == TWT_DISABLE_REQUESTED) { + hdd_ctx->twt_state = TWT_DISABLED; + } hdd_debug("TWT: State transitioned from %d to %d", prev_state, hdd_ctx->twt_state); @@ -2114,6 +2202,52 @@ hdd_twt_disable_comp_cb(hdd_handle_t hdd_handle) hdd_err("Failed to set twt_disable_comp_evt"); } +void hdd_send_twt_role_disable_cmd(struct hdd_context *hdd_ctx, + enum twt_role role) +{ + uint8_t pdev_id = hdd_ctx->pdev->pdev_objmgr.wlan_pdev_id; + struct twt_enable_disable_conf twt_en_dis = {0}; + QDF_STATUS status; + + hdd_debug("TWT disable cmd :pdev:%d : %d", pdev_id, role); + + if ((role == TWT_REQUESTOR) || (role == TWT_REQUESTOR_INDV)) { + twt_en_dis.ext_conf_present = true; + twt_en_dis.role = WMI_TWT_ROLE_REQUESTOR; + twt_en_dis.oper = WMI_TWT_OPERATION_INDIVIDUAL; + wma_send_twt_disable_cmd(pdev_id, &twt_en_dis); + } + + if (role == TWT_REQUESTOR_BCAST) { + twt_en_dis.ext_conf_present = true; + twt_en_dis.role = WMI_TWT_ROLE_REQUESTOR; + twt_en_dis.oper = WMI_TWT_OPERATION_BROADCAST; + wma_send_twt_disable_cmd(pdev_id, &twt_en_dis); + } + + if ((role == TWT_RESPONDER) || (role == TWT_RESPONDER_INDV)) { + twt_en_dis.ext_conf_present = true; + twt_en_dis.role = WMI_TWT_ROLE_RESPONDER; + twt_en_dis.oper = WMI_TWT_OPERATION_INDIVIDUAL; + wma_send_twt_disable_cmd(pdev_id, &twt_en_dis); + } + + if (role == TWT_RESPONDER_BCAST) { + twt_en_dis.ext_conf_present = true; + twt_en_dis.role = WMI_TWT_ROLE_RESPONDER; + twt_en_dis.oper = WMI_TWT_OPERATION_BROADCAST; + wma_send_twt_disable_cmd(pdev_id, &twt_en_dis); + } + + status = qdf_wait_single_event(&hdd_ctx->twt_disable_comp_evt, + TWT_DISABLE_COMPLETE_TIMEOUT); + + if (!QDF_IS_STATUS_SUCCESS(status)) { + hdd_warn("TWT request disable timedout"); + return; + } +} + void wlan_hdd_twt_init(struct hdd_context *hdd_ctx) { QDF_STATUS status; diff --git a/core/wma/inc/wma_tgt_cfg.h b/core/wma/inc/wma_tgt_cfg.h index 0548021d25..d9fd649c46 100644 --- a/core/wma/inc/wma_tgt_cfg.h +++ b/core/wma/inc/wma_tgt_cfg.h @@ -187,6 +187,8 @@ struct board_info { * @sar_version: Version of SAR supported by firmware * @bcast_twt_support: braodcast twt support * @restricted_80p80_bw_supp: Restricted 80+80MHz(165MHz BW) support + * @twt_bcast_req_support: twt bcast requestor support + * @twt_bcast_res_support: twt bcast responder support */ struct wma_tgt_cfg { uint32_t target_fw_version; @@ -230,5 +232,9 @@ struct wma_tgt_cfg { struct nan_tgt_caps nan_caps; bool bcast_twt_support; bool restricted_80p80_bw_supp; +#ifdef WLAN_SUPPORT_TWT + bool twt_bcast_req_support; + bool twt_bcast_res_support; +#endif }; #endif /* WMA_TGT_CFG_H */ diff --git a/core/wma/inc/wma_twt.h b/core/wma/inc/wma_twt.h index 58efd09e37..5c274737de 100644 --- a/core/wma/inc/wma_twt.h +++ b/core/wma/inc/wma_twt.h @@ -22,7 +22,22 @@ #include "wma.h" #include "wmi_unified_twt_param.h" -#ifdef WLAN_SUPPORT_TWT +/** + * struct twt_enable_disable_conf - TWT enable/disable configuration/parameters + * @congestion_timeout: Congestion timer value in ms for firmware controlled TWT + * @bcast_en: If bcast TWT enabled + * @ext_conf_present: If extended config is present + * @role: The configuration is for WMI_TWT_ROLE + * @oper: The configuration is for WMI_TWT_OPERATION + */ +struct twt_enable_disable_conf { + uint32_t congestion_timeout; + bool bcast_en; + bool ext_conf_present; + enum WMI_TWT_ROLE role; + enum WMI_TWT_OPERATION oper; +}; + /** * struct twt_add_dialog_complete_event - TWT add dialog complete event * @params: Fixed parameters for TWT add dialog complete event @@ -36,17 +51,16 @@ struct twt_add_dialog_complete_event { struct wmi_twt_add_dialog_additional_params additional_params; }; +#ifdef WLAN_SUPPORT_TWT /** * wma_send_twt_enable_cmd() - Send TWT Enable command to firmware * @pdev_id: pdev id - * @congestion_timeout: Timeout value for the TWT congestion timer - * @bcast_val: broadcast twt support + * @conf: Pointer to twt_enable_disable_conf * * Return: None */ void wma_send_twt_enable_cmd(uint32_t pdev_id, - uint32_t congestion_timeout, - bool bcast_val); + struct twt_enable_disable_conf *conf); /** * wma_set_twt_peer_caps() - Fill the peer TWT capabilities @@ -61,10 +75,12 @@ void wma_set_twt_peer_caps(tpAddStaParams params, /** * wma_send_twt_disable_cmd() - Send TWT disable command to firmware * @pdev_id: pdev id + * @conf: Pointer to twt_enable_disable_conf * * Return: None */ -void wma_send_twt_disable_cmd(uint32_t pdev_id); +void wma_send_twt_disable_cmd(uint32_t pdev_id, + struct twt_enable_disable_conf *conf); /** * wma_twt_process_add_dialog() - Process twt add dialog command @@ -113,15 +129,37 @@ QDF_STATUS wma_twt_process_resume_dialog(t_wma_handle *wma_handle, struct wmi_twt_resume_dialog_cmd_param *params); +/** + * wma_update_bcast_twt_support() - update bcost twt support + * @wh: wma handle + * @tgt_cfg: target configuration to be updated + * + * Update braodcast twt support based on service bit. + * + * Return: None + */ +void wma_update_bcast_twt_support(tp_wma_handle wh, + struct wma_tgt_cfg *tgt_cfg); +/** + * wma_register_twt_events() - register for TWT wmi events + * @wma_handle : wma handle + * + * Registers the wmi event handlers for TWT. + * + * Return: None + */ +void wma_register_twt_events(tp_wma_handle wma_handle); #else -static inline void wma_send_twt_enable_cmd(uint32_t pdev_id, - uint32_t congestion_timeout, - bool bcast_val) +static inline void +wma_send_twt_enable_cmd(uint32_t pdev_id, + struct twt_enable_disable_conf *conf) { wma_debug("TWT not supported as WLAN_SUPPORT_TWT is disabled"); } -static inline void wma_send_twt_disable_cmd(uint32_t pdev_id) +static inline void +wma_send_twt_disable_cmd(uint32_t pdev_id, + struct twt_enable_disable_conf *conf) { } @@ -165,6 +203,15 @@ wma_twt_process_resume_dialog(t_wma_handle *wma_handle, return QDF_STATUS_E_INVAL; } + +static inline void wma_update_bcast_twt_support(tp_wma_handle wh, + struct wma_tgt_cfg *tgt_cfg) +{ +} + +static inline void wma_register_twt_events(tp_wma_handle wma_handle) +{ +} #endif #endif /* __WMA_HE_H */ diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c index 1de6a7d960..9d03cdb770 100644 --- a/core/wma/src/wma_main.c +++ b/core/wma/src/wma_main.c @@ -3395,9 +3395,7 @@ QDF_STATUS wma_open(struct wlan_objmgr_psoc *psoc, wma_vdev_bss_color_collision_info_handler, WMA_RX_WORK_CTX); -#ifdef WLAN_SUPPORT_TWT wma_register_twt_events(wma_handle); -#endif wma_register_apf_events(wma_handle); wma_register_md_events(wma_handle); @@ -5171,25 +5169,6 @@ static void wma_update_obss_detection_support(tp_wma_handle wh, tgt_cfg->obss_detection_offloaded = false; } -/** - * wma_update_bcast_twt_support() - update bcost twt support - * @wh: wma handle - * @tgt_cfg: target configuration to be updated - * - * Update braodcast twt support based on service bit. - * - * Return: None - */ -static void wma_update_bcast_twt_support(tp_wma_handle wh, - struct wma_tgt_cfg *tgt_cfg) -{ - if (wmi_service_enabled(wh->wmi_handle, - wmi_service_bcast_twt_support)) - tgt_cfg->bcast_twt_support = true; - else - tgt_cfg->bcast_twt_support = false; -} - /** * wma_update_obss_color_collision_support() - update obss color collision * offload support diff --git a/core/wma/src/wma_twt.c b/core/wma/src/wma_twt.c index 2ceb0b142f..2d085cdb06 100644 --- a/core/wma/src/wma_twt.c +++ b/core/wma/src/wma_twt.c @@ -27,7 +27,7 @@ #include "wmi_unified_priv.h" void wma_send_twt_enable_cmd(uint32_t pdev_id, - uint32_t congestion_timeout, bool bcast_val) + struct twt_enable_disable_conf *conf) { t_wma_handle *wma = cds_get_context(QDF_MODULE_ID_WMA); struct wmi_twt_enable_param twt_enable_params = {0}; @@ -37,8 +37,11 @@ void wma_send_twt_enable_cmd(uint32_t pdev_id, return; twt_enable_params.pdev_id = pdev_id; - twt_enable_params.sta_cong_timer_ms = congestion_timeout; - twt_enable_params.b_twt_enable = bcast_val; + twt_enable_params.sta_cong_timer_ms = conf->congestion_timeout; + twt_enable_params.b_twt_enable = conf->bcast_en; + twt_enable_params.ext_conf_present = conf->ext_conf_present; + twt_enable_params.twt_role = conf->role; + twt_enable_params.twt_oper = conf->oper; ret = wmi_unified_twt_enable_cmd(wma->wmi_handle, &twt_enable_params); if (ret) @@ -87,7 +90,8 @@ int wma_twt_en_complete_event_handler(void *handle, return status; } -void wma_send_twt_disable_cmd(uint32_t pdev_id) +void wma_send_twt_disable_cmd(uint32_t pdev_id, + struct twt_enable_disable_conf *conf) { t_wma_handle *wma = cds_get_context(QDF_MODULE_ID_WMA); struct wmi_twt_disable_param twt_disable_params = {0}; @@ -97,6 +101,10 @@ void wma_send_twt_disable_cmd(uint32_t pdev_id) return; twt_disable_params.pdev_id = pdev_id; + twt_disable_params.ext_conf_present = conf->ext_conf_present; + twt_disable_params.twt_role = conf->role; + twt_disable_params.twt_oper = conf->oper; + ret = wmi_unified_twt_disable_cmd(wma->wmi_handle, &twt_disable_params); if (ret) @@ -433,6 +441,37 @@ int wma_twt_resume_dialog_complete_event_handler(void *handle, uint8_t *event, return status; } +/** + * wma_update_bcast_twt_support() - update bcost twt support + * @wh: wma handle + * @tgt_cfg: target configuration to be updated + * + * Update braodcast twt support based on service bit. + * + * Return: None + */ +void wma_update_bcast_twt_support(tp_wma_handle wh, + struct wma_tgt_cfg *tgt_cfg) +{ + if (wmi_service_enabled(wh->wmi_handle, + wmi_service_bcast_twt_support)) + tgt_cfg->bcast_twt_support = true; + else + tgt_cfg->bcast_twt_support = false; + + if (wmi_service_enabled(wh->wmi_handle, + wmi_service_twt_bcast_req_support)) + tgt_cfg->twt_bcast_req_support = true; + else + tgt_cfg->twt_bcast_req_support = false; + + if (wmi_service_enabled(wh->wmi_handle, + wmi_service_twt_bcast_resp_support)) + tgt_cfg->twt_bcast_res_support = true; + else + tgt_cfg->twt_bcast_res_support = false; +} + void wma_register_twt_events(tp_wma_handle wma_handle) { wmi_unified_register_event_handler(wma_handle->wmi_handle,