diff --git a/core/hdd/inc/wlan_hdd_twt.h b/core/hdd/inc/wlan_hdd_twt.h index 7fef1ff4500b..cf1ef0f22e61 100644 --- a/core/hdd/inc/wlan_hdd_twt.h +++ b/core/hdd/inc/wlan_hdd_twt.h @@ -39,12 +39,8 @@ struct wmi_twt_del_dialog_param; struct wmi_twt_pause_dialog_cmd_param; struct wmi_twt_resume_dialog_cmd_param; -extern const struct nla_policy qca_wlan_vendor_twt_add_dialog_policy[ - QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX + 1]; - extern const struct nla_policy -wlan_hdd_wifi_twt_config_policy[ - QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_MAX + 1]; +wlan_hdd_wifi_twt_config_policy[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_MAX + 1]; #ifdef WLAN_SUPPORT_TWT /** @@ -142,6 +138,34 @@ void wlan_hdd_twt_init(struct hdd_context *hdd_ctx); */ void wlan_hdd_twt_deinit(struct hdd_context *hdd_ctx); +/** + * hdd_test_config_twt_setup_session() - Process TWT setup + * operation in the received test config vendor command and + * send it to firmare + * @adapter: adapter pointer + * @tb: nl attributes + * + * Handles QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_SETUP + * + * Return: 0 for Success and negative value for failure + */ +int hdd_test_config_twt_setup_session(struct hdd_adapter *adapter, + struct nlattr **tb); + +/** + * hdd_test_config_twt_terminate_session() - Process TWT terminate + * operation in the received test config vendor command and send + * it to firmare + * @adapter: adapter pointer + * @tb: nl attributes + * + * Handles QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_TERMINATE + * + * Return: 0 for Success and negative value for failure + */ +int hdd_test_config_twt_terminate_session(struct hdd_adapter *adapter, + struct nlattr **tb); + #define FEATURE_VENDOR_SUBCMD_WIFI_CONFIG_TWT \ { \ .info.vendor_id = QCA_NL80211_VENDOR_ID, \ @@ -155,16 +179,6 @@ void wlan_hdd_twt_deinit(struct hdd_context *hdd_ctx); QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_MAX) \ }, -/** - * hdd_twt_setup_req_type_to_cmd() - Converts twt setup request type to twt cmd - * @req_type: twt setup request type - * @twt_cmd: pointer to store twt command - * - * Return: QDF_STATUS_SUCCESS on success, else other qdf error values - */ -QDF_STATUS -hdd_twt_setup_req_type_to_cmd(u8 req_type, enum WMI_HOST_TWT_COMMAND *twt_cmd); - #else static inline void hdd_update_tgt_twt_cap(struct hdd_context *hdd_ctx, struct wma_tgt_cfg *cfg) @@ -188,12 +202,20 @@ static inline void wlan_hdd_twt_deinit(struct hdd_context *hdd_ctx) { } -enum WMI_HOST_TWT_COMMAND; -static inline QDF_STATUS -hdd_twt_setup_req_type_to_cmd(u8 req_type, enum WMI_HOST_TWT_COMMAND *twt_cmd) +static inline +int hdd_test_config_twt_setup_session(struct hdd_adapter *adapter, + struct nlattr **tb) { - return QDF_STATUS_E_INVAL; + return -EINVAL; } + +static inline +int hdd_test_config_twt_terminate_session(struct hdd_adapter *adapter, + struct nlattr **tb) +{ + return -EINVAL; +} + #define FEATURE_VENDOR_SUBCMD_WIFI_CONFIG_TWT #endif diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 96f4f5fc0be9..5ba0a4465d28 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -159,9 +159,6 @@ #include "wlan_reg_ucfg_api.h" #include "wlan_hdd_twt.h" -#define TWT_FLOW_TYPE_ANNOUNCED 0 -#define TWT_FLOW_TYPE_UNANNOUNCED 1 - #ifdef WLAN_FEATURE_INTERFACE_MGR #include "wlan_if_mgr_ucfg_api.h" #include "wlan_if_mgr_public_struct.h" @@ -771,21 +768,6 @@ static struct ieee80211_iface_combination static struct cfg80211_ops wlan_hdd_cfg80211_ops; -const struct nla_policy qca_wlan_vendor_twt_add_dialog_policy[ - QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX + 1] = { - [QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_EXP] = {.type = NLA_U8 }, - [QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST] = {.type = NLA_FLAG }, - [QCA_WLAN_VENDOR_ATTR_TWT_SETUP_REQ_TYPE] = {.type = NLA_U8 }, - [QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TRIGGER] = {.type = NLA_FLAG }, - [QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_ID] = {.type = NLA_U8 }, - [QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE] = {.type = NLA_U8 }, - [QCA_WLAN_VENDOR_ATTR_TWT_SETUP_PROTECTION] = {.type = NLA_FLAG }, - [QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME] = {.type = NLA_U32 }, - [QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_DURATION] = {.type = NLA_U32 }, - [QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_MANTISSA] = { - .type = NLA_U32 }, -}; - #ifdef WLAN_NL80211_TESTMODE enum wlan_hdd_tm_attr { WLAN_HDD_TM_ATTR_INVALID = 0, @@ -9430,125 +9412,6 @@ static void hdd_disable_runtime_pm_for_user(struct hdd_context *hdd_ctx) qdf_runtime_pm_prevent_suspend(&ctx->user); } -int hdd_twt_get_add_dialog_values(struct nlattr **tb, - struct wmi_twt_add_dialog_param *params) -{ - uint32_t wake_intvl_exp, result; - int cmd_id; - QDF_STATUS qdf_status; - - cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_ID; - if (tb[cmd_id]) { - params->dialog_id = nla_get_u8(tb[cmd_id]); - } else { - params->dialog_id = 0; - hdd_debug("TWT_SETUP_FLOW_ID not specified. set to zero"); - } - - cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_EXP; - if (!tb[cmd_id]) { - hdd_err_rl("TWT_SETUP_WAKE_INTVL_EXP is must"); - return -EINVAL; - } - wake_intvl_exp = nla_get_u8(tb[cmd_id]); - if (wake_intvl_exp > TWT_SETUP_WAKE_INTVL_EXP_MAX) { - hdd_err_rl("Invalid wake_intvl_exp %u > %u", - wake_intvl_exp, - TWT_SETUP_WAKE_INTVL_EXP_MAX); - return -EINVAL; - } - - cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST; - params->flag_bcast = nla_get_flag(tb[cmd_id]); - - cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_REQ_TYPE; - if (!tb[cmd_id]) { - hdd_err_rl("TWT_SETUP_REQ_TYPE is must"); - return -EINVAL; - } - qdf_status = hdd_twt_setup_req_type_to_cmd(nla_get_u8(tb[cmd_id]), - ¶ms->twt_cmd); - if (QDF_IS_STATUS_ERROR(qdf_status)) - return qdf_status_to_os_return(qdf_status); - - cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TRIGGER; - params->flag_trigger = nla_get_flag(tb[cmd_id]); - - cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE; - if (!tb[cmd_id]) { - hdd_err_rl("TWT_SETUP_FLOW_TYPE is must"); - return -EINVAL; - } - params->flag_flow_type = nla_get_u8(tb[cmd_id]); - if (params->flag_flow_type != TWT_FLOW_TYPE_ANNOUNCED && - params->flag_flow_type != TWT_FLOW_TYPE_UNANNOUNCED) - return -EINVAL; - - cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_PROTECTION; - params->flag_protection = nla_get_flag(tb[cmd_id]); - - cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME; - if (tb[cmd_id]) - params->sp_offset_us = nla_get_u32(tb[cmd_id]); - - cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_DURATION; - if (!tb[cmd_id]) { - hdd_err_rl("TWT_SETUP_WAKE_DURATION is must"); - return -EINVAL; - } - params->wake_dura_us = TWT_WAKE_DURATION_MULTIPLICATION_FACTOR * - nla_get_u32(tb[cmd_id]); - if (params->wake_dura_us > TWT_SETUP_WAKE_DURATION_MAX) { - hdd_err_rl("Invalid wake_dura_us %u", - params->wake_dura_us); - return -EINVAL; - } - - cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_MANTISSA; - if (!tb[cmd_id]) { - hdd_err_rl("SETUP_WAKE_INTVL_MANTISSA is must"); - return -EINVAL; - } - params->wake_intvl_mantis = nla_get_u32(tb[cmd_id]); - if (params->wake_intvl_mantis > - TWT_SETUP_WAKE_INTVL_MANTISSA_MAX) { - hdd_err_rl("Invalid wake_intvl_mantis %u", - params->wake_dura_us); - return -EINVAL; - } - - if (wake_intvl_exp && params->wake_intvl_mantis) { - result = 2 << (wake_intvl_exp - 1); - if (result > - (UINT_MAX / params->wake_intvl_mantis)) { - hdd_err_rl("Invalid exp %d mantissa %d", - wake_intvl_exp, - params->wake_intvl_mantis); - return -EINVAL; - } - params->wake_intvl_us = - params->wake_intvl_mantis * result; - } else { - params->wake_intvl_us = params->wake_intvl_mantis; - } - - hdd_debug("twt: dialog_id %d, vdev %d, wake intvl_us %d, mantis %d", - params->dialog_id, params->vdev_id, params->wake_intvl_us, - params->wake_intvl_mantis); - hdd_debug("twt: wake dura %d, sp_offset %d, cmd %d", - params->wake_dura_us, params->sp_offset_us, - params->twt_cmd); - hdd_debug("twt: bcast %d, trigger %d, flow_type %d, prot %d", - params->flag_bcast, params->flag_trigger, - params->flag_flow_type, - params->flag_protection); - hdd_debug("twt: peer mac_addr " - QDF_MAC_ADDR_FMT, - QDF_MAC_ADDR_REF(params->peer_macaddr)); - - return 0; -} - /** * __wlan_hdd_cfg80211_set_wifi_test_config() - Wifi test configuration * vendor command @@ -10027,84 +9890,13 @@ __wlan_hdd_cfg80211_set_wifi_test_config(struct wiphy *wiphy, } if (tb[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_SETUP]) { - struct wmi_twt_add_dialog_param params = {0}; - struct hdd_station_ctx *hdd_sta_ctx = - WLAN_HDD_GET_STATION_CTX_PTR(adapter); - struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX + 1]; - struct nlattr *twt_session; - int tmp, rc; - uint32_t congestion_timeout = 0; - - if ((adapter->device_mode != QDF_STA_MODE && - adapter->device_mode != QDF_P2P_CLIENT_MODE) || - hdd_sta_ctx->conn_info.conn_state != - eConnectionState_Associated) { - hdd_err_rl("Invalid state, vdev %d mode %d state %d", - adapter->vdev_id, adapter->device_mode, - hdd_sta_ctx->conn_info.conn_state); + ret_val = hdd_test_config_twt_setup_session(adapter, tb); + if (ret_val) goto send_err; - } - - qdf_mem_copy(params.peer_macaddr, - hdd_sta_ctx->conn_info.bssid.bytes, - QDF_MAC_ADDR_SIZE); - params.vdev_id = adapter->vdev_id; - params.dialog_id = 0; - - cmd_id = QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_SETUP; - nla_for_each_nested(twt_session, tb[cmd_id], tmp) { - rc = wlan_cfg80211_nla_parse( - tb2, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX, - nla_data(twt_session), - nla_len(twt_session), - qca_wlan_vendor_twt_add_dialog_policy); - if (rc) { - hdd_err_rl("Invalid twt ATTR"); - goto send_err; - } - - ret_val = hdd_twt_get_add_dialog_values(tb2, ¶ms); - if (ret_val) - goto send_err; - - ucfg_mlme_get_twt_congestion_timeout(hdd_ctx->psoc, - &congestion_timeout); - if (congestion_timeout) { - ret_val = qdf_status_to_os_return( - hdd_send_twt_disable_cmd(hdd_ctx)); - if (ret_val) { - hdd_err("Failed to disable TWT"); - goto send_err; - } - ucfg_mlme_set_twt_congestion_timeout( - hdd_ctx->psoc, 0); - hdd_send_twt_enable_cmd(hdd_ctx); - } - ret_val = qdf_status_to_os_return(sme_test_config_twt_setup(¶ms)); - if (ret_val) - goto send_err; - } } if (tb[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_TERMINATE]) { - struct wmi_twt_del_dialog_param params = {0}; - - if ((adapter->device_mode != QDF_STA_MODE && - adapter->device_mode != QDF_P2P_CLIENT_MODE) || - hdd_sta_ctx->conn_info.conn_state != - eConnectionState_Associated) { - hdd_err("Invalid state, vdev %d mode %d state %d", - adapter->vdev_id, adapter->device_mode, - hdd_sta_ctx->conn_info.conn_state); - goto send_err; - } - qdf_mem_copy(params.peer_macaddr, - hdd_sta_ctx->conn_info.bssid.bytes, - QDF_MAC_ADDR_SIZE); - params.vdev_id = adapter->vdev_id; - params.dialog_id = 0; - hdd_debug("twt_terminate: vdev_id %d", params.vdev_id); - ret_val = qdf_status_to_os_return(sme_test_config_twt_terminate(¶ms)); + ret_val = hdd_test_config_twt_terminate_session(adapter, tb); if (ret_val) goto send_err; } diff --git a/core/hdd/src/wlan_hdd_cfg80211.h b/core/hdd/src/wlan_hdd_cfg80211.h index 8f9234cf0699..6941f7bd2711 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.h +++ b/core/hdd/src/wlan_hdd_cfg80211.h @@ -875,16 +875,4 @@ static inline void hdd_send_update_owe_info_event(struct hdd_adapter *adapter, */ bool hdd_is_legacy_connection(struct hdd_adapter *adapter); -/** - * hdd_twt_get_add_dialog_values() - Get TWT add dialog parameter - * values from QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS - * @tb: nl attributes - * @params: wmi twt add dialog parameters - * - * Handles QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX - * - * Return: 0 or -EINVAL. - */ -int hdd_twt_get_add_dialog_values(struct nlattr **tb2, - struct wmi_twt_add_dialog_param *params); #endif diff --git a/core/hdd/src/wlan_hdd_twt.c b/core/hdd/src/wlan_hdd_twt.c index b86c711003ff..b0074026f9eb 100644 --- a/core/hdd/src/wlan_hdd_twt.c +++ b/core/hdd/src/wlan_hdd_twt.c @@ -41,6 +41,9 @@ #define TWT_PAUSE_COMPLETE_TIMEOUT 4000 #define TWT_RESUME_COMPLETE_TIMEOUT 4000 +#define TWT_FLOW_TYPE_ANNOUNCED 0 +#define TWT_FLOW_TYPE_UNANNOUNCED 1 + /** * struct twt_pause_dialog_comp_ev_priv - private struct for twt pause dialog * @pause_dialog_comp_ev_buf: buffer from TWT pause dialog complete_event @@ -85,6 +88,20 @@ struct twt_del_dialog_comp_ev_priv { struct wmi_twt_del_dialog_complete_event_param del_dialog_comp_ev_buf; }; +static const struct nla_policy +qca_wlan_vendor_twt_add_dialog_policy[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX + 1] = { + [QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_EXP] = {.type = NLA_U8 }, + [QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST] = {.type = NLA_FLAG }, + [QCA_WLAN_VENDOR_ATTR_TWT_SETUP_REQ_TYPE] = {.type = NLA_U8 }, + [QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TRIGGER] = {.type = NLA_FLAG }, + [QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_ID] = {.type = NLA_U8 }, + [QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE] = {.type = NLA_U8 }, + [QCA_WLAN_VENDOR_ATTR_TWT_SETUP_PROTECTION] = {.type = NLA_FLAG }, + [QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME] = {.type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_DURATION] = {.type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_MANTISSA] = {.type = NLA_U32 }, +}; + static const struct nla_policy qca_wlan_vendor_twt_resume_dialog_policy[QCA_WLAN_VENDOR_ATTR_TWT_RESUME_MAX + 1] = { [QCA_WLAN_VENDOR_ATTR_TWT_RESUME_FLOW_ID] = {.type = NLA_U8 }, @@ -102,7 +119,14 @@ wlan_hdd_wifi_twt_config_policy[ .type = NLA_NESTED}, }; -QDF_STATUS +/** + * hdd_twt_setup_req_type_to_cmd() - Converts twt setup request type to twt cmd + * @req_type: twt setup request type + * @twt_cmd: pointer to store twt command + * + * Return: QDF_STATUS_SUCCESS on success, else other qdf error values + */ +static QDF_STATUS hdd_twt_setup_req_type_to_cmd(u8 req_type, enum WMI_HOST_TWT_COMMAND *twt_cmd) { if (req_type == QCA_WLAN_VENDOR_TWT_SETUP_REQUEST) { @@ -118,6 +142,230 @@ hdd_twt_setup_req_type_to_cmd(u8 req_type, enum WMI_HOST_TWT_COMMAND *twt_cmd) return QDF_STATUS_SUCCESS; } +/** + * hdd_twt_get_add_dialog_values() - Get TWT add dialog parameter + * values from QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS + * @tb: nl attributes + * @params: wmi twt add dialog parameters + * + * Handles QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX + * + * Return: 0 or -EINVAL. + */ +static +int hdd_twt_get_add_dialog_values(struct nlattr **tb, + struct wmi_twt_add_dialog_param *params) +{ + uint32_t wake_intvl_exp, result; + int cmd_id; + QDF_STATUS qdf_status; + + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_ID; + if (tb[cmd_id]) { + params->dialog_id = nla_get_u8(tb[cmd_id]); + } else { + params->dialog_id = 0; + hdd_debug("TWT_SETUP_FLOW_ID not specified. set to zero"); + } + + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_EXP; + if (!tb[cmd_id]) { + hdd_err_rl("TWT_SETUP_WAKE_INTVL_EXP is must"); + return -EINVAL; + } + wake_intvl_exp = nla_get_u8(tb[cmd_id]); + if (wake_intvl_exp > TWT_SETUP_WAKE_INTVL_EXP_MAX) { + hdd_err_rl("Invalid wake_intvl_exp %u > %u", + wake_intvl_exp, + TWT_SETUP_WAKE_INTVL_EXP_MAX); + return -EINVAL; + } + + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST; + params->flag_bcast = nla_get_flag(tb[cmd_id]); + + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_REQ_TYPE; + if (!tb[cmd_id]) { + hdd_err_rl("TWT_SETUP_REQ_TYPE is must"); + return -EINVAL; + } + qdf_status = hdd_twt_setup_req_type_to_cmd(nla_get_u8(tb[cmd_id]), + ¶ms->twt_cmd); + if (QDF_IS_STATUS_ERROR(qdf_status)) + return qdf_status_to_os_return(qdf_status); + + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TRIGGER; + params->flag_trigger = nla_get_flag(tb[cmd_id]); + + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE; + if (!tb[cmd_id]) { + hdd_err_rl("TWT_SETUP_FLOW_TYPE is must"); + return -EINVAL; + } + params->flag_flow_type = nla_get_u8(tb[cmd_id]); + if (params->flag_flow_type != TWT_FLOW_TYPE_ANNOUNCED && + params->flag_flow_type != TWT_FLOW_TYPE_UNANNOUNCED) + return -EINVAL; + + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_PROTECTION; + params->flag_protection = nla_get_flag(tb[cmd_id]); + + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME; + if (tb[cmd_id]) + params->sp_offset_us = nla_get_u32(tb[cmd_id]); + + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_DURATION; + if (!tb[cmd_id]) { + hdd_err_rl("TWT_SETUP_WAKE_DURATION is must"); + return -EINVAL; + } + params->wake_dura_us = TWT_WAKE_DURATION_MULTIPLICATION_FACTOR * + nla_get_u32(tb[cmd_id]); + if (params->wake_dura_us > TWT_SETUP_WAKE_DURATION_MAX) { + hdd_err_rl("Invalid wake_dura_us %u", + params->wake_dura_us); + return -EINVAL; + } + + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_MANTISSA; + if (!tb[cmd_id]) { + hdd_err_rl("SETUP_WAKE_INTVL_MANTISSA is must"); + return -EINVAL; + } + params->wake_intvl_mantis = nla_get_u32(tb[cmd_id]); + if (params->wake_intvl_mantis > + TWT_SETUP_WAKE_INTVL_MANTISSA_MAX) { + hdd_err_rl("Invalid wake_intvl_mantis %u", + params->wake_dura_us); + return -EINVAL; + } + + if (wake_intvl_exp && params->wake_intvl_mantis) { + result = 2 << (wake_intvl_exp - 1); + if (result > + (UINT_MAX / params->wake_intvl_mantis)) { + hdd_err_rl("Invalid exp %d mantissa %d", + wake_intvl_exp, + params->wake_intvl_mantis); + return -EINVAL; + } + params->wake_intvl_us = + params->wake_intvl_mantis * result; + } else { + params->wake_intvl_us = params->wake_intvl_mantis; + } + + hdd_debug("twt: dialog_id %d, vdev %d, wake intvl_us %d, mantis %d", + params->dialog_id, params->vdev_id, params->wake_intvl_us, + params->wake_intvl_mantis); + hdd_debug("twt: wake dura %d, sp_offset %d, cmd %d", + params->wake_dura_us, params->sp_offset_us, + params->twt_cmd); + hdd_debug("twt: bcast %d, trigger %d, flow_type %d, prot %d", + params->flag_bcast, params->flag_trigger, + params->flag_flow_type, + params->flag_protection); + hdd_debug("twt: peer mac_addr " + QDF_MAC_ADDR_FMT, + QDF_MAC_ADDR_REF(params->peer_macaddr)); + + return 0; +} + +int hdd_test_config_twt_setup_session(struct hdd_adapter *adapter, + struct nlattr **tb) +{ + struct nlattr *twt_session; + int tmp, rc; + struct hdd_station_ctx *hdd_sta_ctx = NULL; + struct wmi_twt_add_dialog_param params = {0}; + struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX + 1]; + uint32_t congestion_timeout = 0; + int ret = 0; + int cmd_id; + + if (adapter->device_mode != QDF_STA_MODE && + adapter->device_mode != QDF_P2P_CLIENT_MODE) { + return -EOPNOTSUPP; + } + + hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); + if (hdd_sta_ctx->conn_info.conn_state != eConnectionState_Associated) { + hdd_err_rl("Invalid state, vdev %d mode %d state %d", + adapter->vdev_id, adapter->device_mode, + hdd_sta_ctx->conn_info.conn_state); + return -EINVAL; + } + + qdf_mem_copy(params.peer_macaddr, hdd_sta_ctx->conn_info.bssid.bytes, + QDF_MAC_ADDR_SIZE); + params.vdev_id = adapter->vdev_id; + + cmd_id = QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_SETUP; + nla_for_each_nested(twt_session, tb[cmd_id], tmp) { + rc = wlan_cfg80211_nla_parse(tb2, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX, + nla_data(twt_session), + nla_len(twt_session), + qca_wlan_vendor_twt_add_dialog_policy); + if (rc) { + hdd_err_rl("Invalid twt ATTR"); + return -EINVAL; + } + + ret = hdd_twt_get_add_dialog_values(tb2, ¶ms); + if (ret) + return ret; + + ucfg_mlme_get_twt_congestion_timeout(adapter->hdd_ctx->psoc, + &congestion_timeout); + if (congestion_timeout) { + ret = qdf_status_to_os_return( + hdd_send_twt_disable_cmd(adapter->hdd_ctx)); + if (ret) { + hdd_err("Failed to disable TWT"); + return ret; + } + ucfg_mlme_set_twt_congestion_timeout(adapter->hdd_ctx->psoc, 0); + hdd_send_twt_enable_cmd(adapter->hdd_ctx); + } + + ret = qdf_status_to_os_return(sme_test_config_twt_setup(¶ms)); + } + return ret; +} + +int hdd_test_config_twt_terminate_session(struct hdd_adapter *adapter, + struct nlattr **tb) +{ + struct hdd_station_ctx *hdd_sta_ctx = NULL; + struct wmi_twt_del_dialog_param params = {0}; + int ret_val; + + if (adapter->device_mode != QDF_STA_MODE && + adapter->device_mode != QDF_P2P_CLIENT_MODE) { + return -EOPNOTSUPP; + } + + hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); + if (hdd_sta_ctx->conn_info.conn_state != eConnectionState_Associated) { + hdd_err_rl("Invalid state, vdev %d mode %d state %d", + adapter->vdev_id, adapter->device_mode, + hdd_sta_ctx->conn_info.conn_state); + return -EINVAL; + } + + qdf_mem_copy(params.peer_macaddr, + hdd_sta_ctx->conn_info.bssid.bytes, + QDF_MAC_ADDR_SIZE); + params.vdev_id = adapter->vdev_id; + params.dialog_id = 0; + hdd_debug("twt_terminate: vdev_id %d", params.vdev_id); + + ret_val = qdf_status_to_os_return(sme_test_config_twt_terminate(¶ms)); + return ret_val; +} + /** * hdd_twt_get_params_resp_len() - Calculates the length * of twt get_params nl response diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index 62a55fa9ad90..b8cc305f6460 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -14485,7 +14485,7 @@ QDF_STATUS sme_test_config_twt_setup(struct wmi_twt_add_dialog_param *params) wma_handle = cds_get_context(QDF_MODULE_ID_WMA); if (!wma_handle) { QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, - "wma handle is NULL"); + "wma handle is NULL"); return QDF_STATUS_E_FAILURE; } @@ -14500,7 +14500,7 @@ sme_test_config_twt_terminate(struct wmi_twt_del_dialog_param *params) wma_handle = cds_get_context(QDF_MODULE_ID_WMA); if (!wma_handle) { QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, - "wma handle is NULL"); + "wma handle is NULL"); return QDF_STATUS_E_FAILURE; }