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
This commit is contained in:
Rajasekaran Kalidoss 2021-01-13 12:17:36 +05:30 • committed by snandini
commit e8c54f97df
8 changed files with 299 additions and 4 deletions

View file

@ -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;
};

View file

@ -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_ */

View file

@ -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

View file

@ -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)

View file

@ -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 */

View file

@ -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)
{
}

View file

@ -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++)

View file

@ -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,