From e8c54f97df7b0d8b0a1e19369a15d2f91bb2ee1b Mon Sep 17 00:00:00 2001 From: Rajasekaran Kalidoss Date: Wed, 13 Jan 2021 12:17:36 +0530 Subject: [PATCH] qcacld-3.0: Add support to get TWT target capabilities Add support to get the following TWT target capabilities 1) Nudge 2) all twt and 3) statistics Change-Id: If74e99b0ff920481bcabb0300129b9067082d113 CRs-Fixed: 2854927 --- .../dispatcher/inc/wlan_mlme_public_struct.h | 10 +- .../dispatcher/inc/wlan_mlme_twt_ucfg_api.h | 101 ++++++++++++++++++ .../dispatcher/src/wlan_mlme_twt_ucfg_api.c | 84 +++++++++++++++ core/hdd/src/wlan_hdd_twt.c | 71 ++++++++++++ core/wma/inc/wma_tgt_cfg.h | 5 +- core/wma/inc/wma_twt.h | 18 +++- core/wma/src/wma_main.c | 2 + core/wma/src/wma_twt.c | 12 +++ 8 files changed, 299 insertions(+), 4 deletions(-) diff --git a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h index 491b07d43fb9..e7dbdeb6ee66 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h @@ -1344,10 +1344,13 @@ struct wlan_mlme_acs { /* * struct wlan_mlme_cfg_twt - All twt related cfg items * @is_twt_enabled: global twt configuration - * @bcast_requestor_tgt_cap: Broadcast requestor target capability - * @bcast_responder_tgt_cap: Broadcast responder target capability * @is_bcast_responder_enabled: bcast responder enable/disable * @is_bcast_requestor_enabled: bcast requestor enable/disable + * @bcast_requestor_tgt_cap: Broadcast requestor target capability + * @bcast_responder_tgt_cap: Broadcast responder target capability + * @is_twt_nudge_tgt_cap_enabled: support for nudge request enable/disable + * @is_all_twt_tgt_cap_enabled: support for all twt enable/disable + * @is_twt_statistics_tgt_cap_enabled: support for twt statistics * @twt_congestion_timeout: congestion timeout value */ struct wlan_mlme_cfg_twt { @@ -1356,6 +1359,9 @@ struct wlan_mlme_cfg_twt { bool is_bcast_requestor_enabled; bool bcast_requestor_tgt_cap; bool bcast_responder_tgt_cap; + bool is_twt_nudge_tgt_cap_enabled; + bool is_all_twt_tgt_cap_enabled; + bool is_twt_statistics_tgt_cap_enabled; uint32_t twt_congestion_timeout; }; diff --git a/components/mlme/dispatcher/inc/wlan_mlme_twt_ucfg_api.h b/components/mlme/dispatcher/inc/wlan_mlme_twt_ucfg_api.h index b63bac3517e5..1bc7283a7f7c 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_twt_ucfg_api.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_twt_ucfg_api.h @@ -314,6 +314,68 @@ QDF_STATUS ucfg_mlme_init_twt_context(struct wlan_objmgr_psoc *psoc, { return mlme_init_twt_context(psoc, peer_mac, dialog_id); } + +/** + * ucfg_mlme_set_twt_nudge_tgt_cap() - Set TWT nudge target capability. + * @psoc: Pointer to global psoc object + * @val: Value to set + * + * Return: QDF_STATUS + */ +QDF_STATUS +ucfg_mlme_set_twt_nudge_tgt_cap(struct wlan_objmgr_psoc *psoc, bool val); + +/** + * ucfg_mlme_get_twt_nudge_tgt_cap() - Get TWT Nudge target capability + * @psoc: Pointer to global psoc object + * @val: Value to set + * + * Return: QDF_STATUS + */ +QDF_STATUS +ucfg_mlme_get_twt_nudge_tgt_cap(struct wlan_objmgr_psoc *psoc, bool *val); + +/** + * ucfg_mlme_set_twt_all_twt_tgt_cap() - Set TWT all dialog support target + * @psoc: Pointer to global psoc object + * @val: Value to set + * + * Return: QDF_STATUS + */ +QDF_STATUS +ucfg_mlme_set_twt_all_twt_tgt_cap(struct wlan_objmgr_psoc *psoc, bool val); + +/** + * ucfg_mlme_get_twt_all_twt_tgt_cap() - Get TWT all dialog support target + * capability + * @psoc: Pointer to global psoc object + * @val: Value to set + * + * Return: QDF_STATUS + */ +QDF_STATUS +ucfg_mlme_get_twt_all_twt_tgt_cap(struct wlan_objmgr_psoc *psoc, bool *val); + +/** + * ucfg_mlme_set_twt_statistics_tgt_cap() - Set TWT statistics target + * capability + * @psoc: Pointer to global psoc object + * @val: Value to set + * + * Return: QDF_STATUS + */ +QDF_STATUS +ucfg_mlme_set_twt_statistics_tgt_cap(struct wlan_objmgr_psoc *psoc, bool val); + +/** + * ucfg_mlme_get_twt_statistics_tgt_cap() - Get TWT statistics target capability + * @psoc: Pointer to global psoc object + * @val: Value to set + * + * Return: QDF_STATUS + */ +QDF_STATUS +ucfg_mlme_get_twt_statistics_tgt_cap(struct wlan_objmgr_psoc *psoc, bool *val); #else static inline QDF_STATUS ucfg_mlme_get_twt_requestor(struct wlan_objmgr_psoc *psoc, @@ -479,5 +541,44 @@ QDF_STATUS ucfg_mlme_init_twt_context(struct wlan_objmgr_psoc *psoc, { return QDF_STATUS_E_NOSUPPORT; } + +static inline QDF_STATUS +ucfg_mlme_get_twt_nudge_tgt_cap(struct wlan_objmgr_psoc *psoc, bool *val) +{ + *val = false; + return QDF_STATUS_E_NOSUPPORT; +} + +static inline QDF_STATUS +ucfg_mlme_get_twt_all_twt_tgt_cap(struct wlan_objmgr_psoc *psoc, bool *val) +{ + *val = false; + return QDF_STATUS_E_NOSUPPORT; +} + +static inline QDF_STATUS +ucfg_mlme_get_twt_statistics_tgt_cap(struct wlan_objmgr_psoc *psoc, bool *val) +{ + *val = false; + return QDF_STATUS_E_NOSUPPORT; +} + +static inline QDF_STATUS +ucfg_mlme_set_twt_nudge_tgt_cap(struct wlan_objmgr_psoc *psoc, bool val) +{ + return QDF_STATUS_E_NOSUPPORT; +} + +static inline QDF_STATUS +ucfg_mlme_set_twt_all_twt_tgt_cap(struct wlan_objmgr_psoc *psoc, bool val) +{ + return QDF_STATUS_E_NOSUPPORT; +} + +static inline QDF_STATUS +ucfg_mlme_set_twt_statistics_tgt_cap(struct wlan_objmgr_psoc *psoc, bool val) +{ + return QDF_STATUS_E_NOSUPPORT; +} #endif /* defined(WLAN_SUPPORT_TWT) && defined(WLAN_FEATURE_11AX) */ #endif /* _WLAN_MLME_TWT_UCFG_API_H_ */ diff --git a/components/mlme/dispatcher/src/wlan_mlme_twt_ucfg_api.c b/components/mlme/dispatcher/src/wlan_mlme_twt_ucfg_api.c index 8ba4734fc2fd..28a629e8380d 100644 --- a/components/mlme/dispatcher/src/wlan_mlme_twt_ucfg_api.c +++ b/components/mlme/dispatcher/src/wlan_mlme_twt_ucfg_api.c @@ -267,4 +267,88 @@ ucfg_mlme_set_twt_bcast_responder_tgt_cap(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } + +QDF_STATUS +ucfg_mlme_set_twt_nudge_tgt_cap(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_twt_nudge_tgt_cap_enabled = val; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +ucfg_mlme_get_twt_nudge_tgt_cap(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; + + *val = mlme_obj->cfg.twt_cfg.is_twt_nudge_tgt_cap_enabled; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +ucfg_mlme_set_twt_all_twt_tgt_cap(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_all_twt_tgt_cap_enabled = val; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +ucfg_mlme_get_twt_all_twt_tgt_cap(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; + + *val = mlme_obj->cfg.twt_cfg.is_all_twt_tgt_cap_enabled; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +ucfg_mlme_set_twt_statistics_tgt_cap(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_twt_statistics_tgt_cap_enabled = val; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +ucfg_mlme_get_twt_statistics_tgt_cap(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; + + *val = mlme_obj->cfg.twt_cfg.is_twt_statistics_tgt_cap_enabled; + + return QDF_STATUS_SUCCESS; +} #endif diff --git a/core/hdd/src/wlan_hdd_twt.c b/core/hdd/src/wlan_hdd_twt.c index 557bff3acd09..6c161e3ec18c 100644 --- a/core/hdd/src/wlan_hdd_twt.c +++ b/core/hdd/src/wlan_hdd_twt.c @@ -48,6 +48,7 @@ #define TWT_SETUP_WAKE_INTVL_EXP_MAX 31 #define TWT_WAKE_DURATION_MULTIPLICATION_FACTOR 256 #define TWT_MAX_NEXT_TWT_SIZE 3 +#define TWT_ALL_SESSIONS_DIALOG_ID 255 /** * struct twt_nudge_dialog_comp_ev_priv - private struct for twt nudge dialog @@ -394,6 +395,31 @@ int hdd_test_config_twt_terminate_session(struct hdd_adapter *adapter, return ret_val; } +static +QDF_STATUS hdd_twt_check_all_twt_support(struct wlan_objmgr_psoc *psoc, + uint32_t dialog_id) +{ + bool is_all_twt_tgt_cap_enabled = false; + QDF_STATUS status; + + /* Cap check is check NOT required if id is for a single session*/ + if (dialog_id != TWT_ALL_SESSIONS_DIALOG_ID) + return QDF_STATUS_SUCCESS; + + status = ucfg_mlme_get_twt_all_twt_tgt_cap( + psoc, + &is_all_twt_tgt_cap_enabled); + if (QDF_IS_STATUS_ERROR(status)) + return QDF_STATUS_E_INVAL; + + if (!is_all_twt_tgt_cap_enabled) { + hdd_debug("All TWT sessions not supported by target"); + return QDF_STATUS_E_NOSUPPORT; + } + + return QDF_STATUS_SUCCESS; +} + /** * hdd_twt_get_params_resp_len() - Calculates the length * of twt get_params nl response @@ -1492,6 +1518,7 @@ static int hdd_twt_terminate_session(struct hdd_adapter *adapter, struct hdd_station_ctx *hdd_sta_ctx = NULL; struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX + 1]; struct wmi_twt_del_dialog_param params = {0}; + QDF_STATUS status; int id; int ret; @@ -1528,6 +1555,13 @@ static int hdd_twt_terminate_session(struct hdd_adapter *adapter, hdd_debug("TWT_TERMINATE_FLOW_ID not specified. set to zero"); } + status = hdd_twt_check_all_twt_support(adapter->hdd_ctx->psoc, + params.dialog_id); + if (QDF_IS_STATUS_ERROR(status)) { + hdd_debug("All TWT sessions not supported by target"); + return -EINVAL; + } + if (!ucfg_mlme_is_twt_setup_done(adapter->hdd_ctx->psoc, &hdd_sta_ctx->conn_info.bssid, params.dialog_id)) { @@ -1764,6 +1798,7 @@ static int hdd_twt_pause_session(struct hdd_adapter *adapter, struct hdd_station_ctx *hdd_sta_ctx; struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX + 1]; struct wmi_twt_pause_dialog_cmd_param params = {0}; + QDF_STATUS status; int id; int ret; @@ -1799,6 +1834,13 @@ static int hdd_twt_pause_session(struct hdd_adapter *adapter, hdd_debug("TWT: FLOW_ID not specified. set to zero"); } + status = hdd_twt_check_all_twt_support(adapter->hdd_ctx->psoc, + params.dialog_id); + if (QDF_IS_STATUS_ERROR(status)) { + hdd_debug("All TWT sessions not supported by target"); + return -EINVAL; + } + if (!ucfg_mlme_is_twt_setup_done(adapter->hdd_ctx->psoc, &hdd_sta_ctx->conn_info.bssid, params.dialog_id)) { @@ -1911,8 +1953,10 @@ static int hdd_twt_nudge_session(struct hdd_adapter *adapter, struct hdd_station_ctx *hdd_sta_ctx; struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_MAX + 1]; struct wmi_twt_nudge_dialog_cmd_param params = {0}; + QDF_STATUS status; int id; int ret; + bool is_nudge_tgt_cap_enabled; if (adapter->device_mode != QDF_STA_MODE && adapter->device_mode != QDF_P2P_CLIENT_MODE) { @@ -1927,6 +1971,13 @@ static int hdd_twt_nudge_session(struct hdd_adapter *adapter, return -EINVAL; } + ucfg_mlme_get_twt_nudge_tgt_cap(adapter->hdd_ctx->psoc, + &is_nudge_tgt_cap_enabled); + if (!is_nudge_tgt_cap_enabled) { + hdd_debug("Nudge not supported by target"); + return -EINVAL; + } + params.vdev_id = adapter->vdev_id; ret = wlan_cfg80211_nla_parse_nested(tb, @@ -1950,6 +2001,13 @@ static int hdd_twt_nudge_session(struct hdd_adapter *adapter, } params.dialog_id = nla_get_u8(tb[id]); + status = hdd_twt_check_all_twt_support(adapter->hdd_ctx->psoc, + params.dialog_id); + if (QDF_IS_STATUS_ERROR(status)) { + hdd_debug("All TWT sessions not supported by target"); + return -EINVAL; + } + id = QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_WAKE_TIME; if (!tb[id]) { hdd_debug("TWT: WAKE_TIME not specified."); @@ -2266,6 +2324,7 @@ static int hdd_twt_resume_session(struct hdd_adapter *adapter, struct hdd_station_ctx *hdd_sta_ctx; struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TWT_RESUME_MAX + 1]; struct wmi_twt_resume_dialog_cmd_param params = {0}; + QDF_STATUS status; int id, id2; int ret; @@ -2300,6 +2359,13 @@ static int hdd_twt_resume_session(struct hdd_adapter *adapter, hdd_debug("TWT_RESUME_FLOW_ID not specified. set to zero"); } + status = hdd_twt_check_all_twt_support(adapter->hdd_ctx->psoc, + params.dialog_id); + if (QDF_IS_STATUS_ERROR(status)) { + hdd_debug("All TWT sessions not supported by target"); + return -EINVAL; + } + if (!ucfg_mlme_is_twt_setup_done(adapter->hdd_ctx->psoc, &hdd_sta_ctx->conn_info.bssid, params.dialog_id)) { @@ -2827,6 +2893,11 @@ void hdd_update_tgt_twt_cap(struct hdd_context *hdd_ctx, ucfg_mlme_set_twt_bcast_responder(hdd_ctx->psoc, QDF_MIN(cfg->twt_bcast_res_support, twt_res)); + ucfg_mlme_set_twt_nudge_tgt_cap(hdd_ctx->psoc, cfg->twt_nudge_enabled); + ucfg_mlme_set_twt_all_twt_tgt_cap(hdd_ctx->psoc, + cfg->all_twt_enabled); + ucfg_mlme_set_twt_statistics_tgt_cap(hdd_ctx->psoc, + cfg->twt_stats_enabled); } void hdd_send_twt_enable_cmd(struct hdd_context *hdd_ctx) diff --git a/core/wma/inc/wma_tgt_cfg.h b/core/wma/inc/wma_tgt_cfg.h index e251e8d093ec..4323d4796da8 100644 --- a/core/wma/inc/wma_tgt_cfg.h +++ b/core/wma/inc/wma_tgt_cfg.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2021 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 @@ -233,6 +233,9 @@ struct wma_tgt_cfg { #ifdef WLAN_SUPPORT_TWT bool twt_bcast_req_support; bool twt_bcast_res_support; + bool twt_nudge_enabled; + bool all_twt_enabled; + bool twt_stats_enabled; #endif }; #endif /* WMA_TGT_CFG_H */ diff --git a/core/wma/inc/wma_twt.h b/core/wma/inc/wma_twt.h index dfb97a3784a5..9166163ec28c 100644 --- a/core/wma/inc/wma_twt.h +++ b/core/wma/inc/wma_twt.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2019-2021 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 @@ -152,6 +152,18 @@ wma_twt_process_resume_dialog(t_wma_handle *wma_handle, */ void wma_update_bcast_twt_support(tp_wma_handle wh, struct wma_tgt_cfg *tgt_cfg); + +/** + * wma_update_twt_tgt_cap()- update the supported twt capabilities + * @wh: wma handle + * @tgt_cfg: target configuration to be updated + * + * Update support for twt capabilities based on service bit. + * + * Return: None + */ +void wma_update_twt_tgt_cap(tp_wma_handle wh, struct wma_tgt_cfg *tgt_cfg); + /** * wma_register_twt_events() - register for TWT wmi events * @wma_handle : wma handle @@ -230,6 +242,10 @@ static inline void wma_update_bcast_twt_support(tp_wma_handle wh, { } +static inline +void wma_update_twt_tgt_cap(tp_wma_handle wh, struct wma_tgt_cfg *tgt_cfg) +{ +} static inline void wma_register_twt_events(tp_wma_handle wma_handle) { } diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c index e96017720358..54411a6db3c9 100644 --- a/core/wma/src/wma_main.c +++ b/core/wma/src/wma_main.c @@ -4710,6 +4710,7 @@ static inline void wma_update_target_services(struct wmi_unified *wmi_handle, wmi_service_ll_stats_per_chan_rx_tx_time); wma_get_service_cap_club_get_sta_in_ll_stats_req(wmi_handle, cfg); + } /** @@ -5543,6 +5544,7 @@ static int wma_update_hdd_cfg(tp_wma_handle wma_handle) wma_update_hdd_cfg_ndp(wma_handle, &tgt_cfg); wma_update_nan_target_caps(wma_handle, &tgt_cfg); wma_update_bcast_twt_support(wma_handle, &tgt_cfg); + wma_update_twt_tgt_cap(wma_handle, &tgt_cfg); wma_update_restricted_80p80_bw_support(wma_handle, &tgt_cfg); /* Take the max of chains supported by FW, which will limit nss */ for (i = 0; i < tgt_hdl->info.total_mac_phy_cnt; i++) diff --git a/core/wma/src/wma_twt.c b/core/wma/src/wma_twt.c index 6382c2ad5f69..9cb4602ec166 100644 --- a/core/wma/src/wma_twt.c +++ b/core/wma/src/wma_twt.c @@ -622,6 +622,18 @@ void wma_update_bcast_twt_support(tp_wma_handle wh, tgt_cfg->twt_bcast_res_support = false; } +void wma_update_twt_tgt_cap(tp_wma_handle wh, struct wma_tgt_cfg *tgt_cfg) +{ + if (wmi_service_enabled(wh->wmi_handle, wmi_service_twt_nudge)) + tgt_cfg->twt_nudge_enabled = true; + + if (wmi_service_enabled(wh->wmi_handle, wmi_service_all_twt)) + tgt_cfg->all_twt_enabled = true; + + if (wmi_service_enabled(wh->wmi_handle, wmi_service_twt_statistics)) + tgt_cfg->twt_stats_enabled = true; +} + void wma_register_twt_events(tp_wma_handle wma_handle) { wmi_unified_register_event_handler(wma_handle->wmi_handle,