qcacld-3.0: Add support to process twt qca vendor command

Add support to process twt qca vendor command.

Change-Id: I2691ce7d1cc50798d99104389fe2213791ebdf78
CRs-Fixed: 2328891
This commit is contained in:
Arif Hussain 2019-03-14 17:06:56 -07:00 • committed by nshrivas
commit 1f58cbbf36
5 changed files with 292 additions and 2 deletions

View file

@ -59,6 +59,7 @@
#include "wlan_hdd_wmm.h"
#include "wma_types.h"
#include "wma.h"
#include "wma_twt.h"
#include "wlan_hdd_misc.h"
#include "wlan_hdd_nan.h"
#include "wlan_logging_sock_svc.h"
@ -5301,6 +5302,20 @@ wlan_hdd_wifi_config_policy[QCA_WLAN_VENDOR_ATTR_CONFIG_MAX + 1] = {
};
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_U8 },
[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_REQ_TYPE] = {.type = NLA_U8 },
[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TRIGGER] = {.type = NLA_U8 },
[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE] = {.type = NLA_U8 },
[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_PROTECTION] = {.type = NLA_U8 },
[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_attr_he_omi_tx_policy [QCA_WLAN_VENDOR_ATTR_HE_OMI_MAX + 1] = {
[QCA_WLAN_VENDOR_ATTR_HE_OMI_RX_NSS] = {.type = NLA_U8 },
@ -5367,6 +5382,12 @@ wlan_hdd_wifi_test_config_policy[
= {.type = NLA_U8},
[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_2G_VHT] = {
.type = NLA_U8},
[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_SETUP] = {
.type = NLA_NESTED},
[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_TERMINATE] = {
.type = NLA_NESTED},
[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TWT_REQ_SUPPORT] = {
.type = NLA_U8},
};
/**
@ -7178,6 +7199,163 @@ __wlan_hdd_cfg80211_set_wifi_test_config(struct wiphy *wiphy,
adapter->vdev_id, cfg_val);
}
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);
uint32_t wake_intvl_exp = 0, result = 0;
struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX + 1];
struct nlattr *twt_session;
int tmp, rc;
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;
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("Invalid twt ATTR");
goto send_err;
}
cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_EXP;
if (tb2[cmd_id])
wake_intvl_exp = nla_get_u8(tb2[cmd_id]);
cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST;
if (tb2[cmd_id])
params.flag_bcast = nla_get_u8(tb2[cmd_id]);
cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_REQ_TYPE;
if (tb2[cmd_id])
params.twt_cmd = nla_get_u8(tb2[cmd_id]);
cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TRIGGER;
if (tb2[cmd_id])
params.flag_trigger = nla_get_u8(tb2[cmd_id]);
cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE;
if (tb2[cmd_id])
params.flag_flow_type = nla_get_u8(tb2[cmd_id]);
cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_PROTECTION;
if (tb2[cmd_id])
params.flag_protection =
nla_get_u8(tb2[cmd_id]);
cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME;
if (tb2[cmd_id])
params.sp_offset_us = nla_get_u32(tb2[cmd_id]);
cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_DURATION;
if (tb2[cmd_id])
params.wake_dura_us =
256 * nla_get_u32(tb2[cmd_id]);
cmd_id =
QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_MANTISSA;
if (tb2[cmd_id])
params.wake_intvl_mantis =
nla_get_u32(tb2[cmd_id]);
if (wake_intvl_exp) {
if (((sizeof(UINT_MAX) / 8) - 2) <
(wake_intvl_exp - 1)) {
hdd_err("Invalid wake_intvl_exp %d",
wake_intvl_exp);
goto send_err;
}
result = 2 << (wake_intvl_exp - 1);
if (result >
(UINT_MAX / params.wake_intvl_mantis)) {
hdd_err("Invalid exp %d mantissa %d",
wake_intvl_exp,
params.wake_intvl_mantis);
goto send_err;
}
params.wake_intvl_us =
params.wake_intvl_mantis * result;
} else {
params.wake_intvl_us = params.wake_intvl_mantis;
}
if (params.wake_dura_us > 0xFFFF) {
hdd_err("Invalid wake_dura_us %d",
params.wake_dura_us);
goto send_err;
}
hdd_debug("twt: vdev %d, intvl_us %d, mantis %d",
params.vdev_id, params.wake_intvl_us,
params.wake_intvl_mantis);
hdd_debug("twt: dura %d, offset %d, cmd %d",
params.wake_dura_us, params.sp_offset_us,
params.twt_cmd);
hdd_debug("twt: bcast %d, trigger %d, type %d, prot %d",
params.flag_bcast, params.flag_trigger,
params.flag_flow_type,
params.flag_protection);
ret_val = qdf_status_to_os_return(
wma_twt_process_add_dialog(&params));
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};
struct hdd_station_ctx *hdd_sta_ctx =
WLAN_HDD_GET_STATION_CTX_PTR(adapter);
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(
wma_twt_process_del_dialog(&params));
if (ret_val)
goto send_err;
}
cmd_id = QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TWT_REQ_SUPPORT;
if (tb[cmd_id]) {
cfg_val = nla_get_u8(tb[cmd_id]);
hdd_debug("twt_request: val %d", cfg_val);
ret_val = sme_update_he_twt_req_support(hdd_ctx->mac_handle,
adapter->vdev_id,
cfg_val);
}
if (update_sme_cfg)
sme_update_config(mac_handle, sme_config);

View file

@ -2829,6 +2829,17 @@ int sme_update_he_frag_supp(mac_handle_t mac_handle, uint8_t session_id,
*/
int sme_update_he_ldpc_supp(mac_handle_t mac_handle, uint8_t session_id,
uint16_t he_ldpc);
/**
* sme_update_he_twt_req_support() - Sets twt request capability
* @mac_handle: Opaque handle to the global MAC context
* @session_id: SME session id
* @value: set value
*
* Return: 0 on success else err code
*/
int sme_update_he_twt_req_support(mac_handle_t mac_handle, uint8_t session_id,
uint8_t cfg_val);
#else
static inline void sme_update_tgt_he_cap(mac_handle_t mac_handle,
struct wma_tgt_cfg *cfg,
@ -2952,6 +2963,14 @@ static inline void sme_set_he_tx_bf_cbf_rates(uint8_t session_id)
static inline void sme_config_su_ppdu_queue(uint8_t session_id, bool enable)
{
}
static inline int sme_update_he_twt_req_support(mac_handle_t mac_handle,
uint8_t session_id,
uint8_t cfg_val)
{
return 0;
}
#endif
/**

View file

@ -11743,6 +11743,25 @@ int sme_update_he_ldpc_supp(mac_handle_t mac_handle, uint8_t session_id,
return 0;
}
int sme_update_he_twt_req_support(mac_handle_t mac_handle, uint8_t session_id,
uint8_t cfg_val)
{
struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
struct csr_roam_session *session;
session = CSR_GET_SESSION(mac_ctx, session_id);
if (!session) {
sme_err("No session for id %d", session_id);
return -EINVAL;
}
mac_ctx->mlme_cfg->he_caps.dot11_he_cap.twt_request = cfg_val;
csr_update_session_he_cap(mac_ctx, session);
return 0;
}
#endif
/**

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018 The Linux Foundation. All rights reserved.
* Copyright (c) 2019 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
@ -20,6 +20,7 @@
#define __WMA_TWT_H
#include "wma.h"
#include "wmi_unified_twt_param.h"
#ifdef WLAN_SUPPORT_TWT
/**
@ -40,6 +41,23 @@ void wma_send_twt_enable_cmd(uint32_t pdev_id, uint32_t congestion_timeout);
*/
void wma_set_twt_peer_caps(tpAddStaParams params,
struct peer_assoc_params *cmd);
/**
* wma_twt_process_add_dialog() - Process twt add dialog command
* @params: add dialog configuration param
*
* Return: QDF_STATUS
*/
QDF_STATUS wma_twt_process_add_dialog(struct wmi_twt_add_dialog_param *params);
/**
* wma_twt_process_del_dialog() - Process del dialog command
* @params: del dialog configuration param
*
* Return: QDF_STATUS
*/
QDF_STATUS wma_twt_process_del_dialog(struct wmi_twt_del_dialog_param *params);
#else
static inline void wma_send_twt_enable_cmd(uint32_t pdev_id,
uint32_t congestion_timeout)
@ -51,6 +69,22 @@ static inline void wma_set_twt_peer_caps(tpAddStaParams params,
struct peer_assoc_params *cmd)
{
}
static inline QDF_STATUS wma_twt_process_add_dialog(
struct wmi_twt_add_dialog_param *params)
{
WMA_LOGD(FL("TWT not supported as WLAN_SUPPORT_TWT is disabled"));
return QDF_STATUS_E_INVAL;
}
static inline QDF_STATUS wma_twt_process_del_dialog(
struct wmi_twt_del_dialog_param *params)
{
WMA_LOGD(FL("TWT not supported as WLAN_SUPPORT_TWT is disabled"));
return QDF_STATUS_E_INVAL;
}
#endif
#endif /* __WMA_HE_H */

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018 The Linux Foundation. All rights reserved.
* Copyright (c) 2019 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
@ -88,3 +88,43 @@ void wma_set_twt_peer_caps(tpAddStaParams params, struct peer_assoc_params *cmd)
cmd->peer_flags |= WMI_PEER_TWT_RESP;
}
QDF_STATUS wma_twt_process_add_dialog(
struct wmi_twt_add_dialog_param *params)
{
t_wma_handle *wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
wmi_unified_t wmi_handle;
if (!wma_handle) {
WMA_LOGE("Invalid WMA context, twt add dialog failed");
return QDF_STATUS_E_INVAL;
}
wmi_handle = (wmi_unified_t)wma_handle->wmi_handle;
if (!wmi_handle) {
WMA_LOGE("Invalid wmi handle, twt add dialog failed");
return QDF_STATUS_E_INVAL;
}
return wmi_unified_twt_add_dialog_cmd(wmi_handle, params);
}
QDF_STATUS wma_twt_process_del_dialog(
struct wmi_twt_del_dialog_param *params)
{
t_wma_handle *wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
wmi_unified_t wmi_handle;
if (!wma_handle) {
WMA_LOGE("Invalid WMA context, twt del dialog failed");
return QDF_STATUS_E_INVAL;
}
wmi_handle = (wmi_unified_t)wma_handle->wmi_handle;
if (!wmi_handle) {
WMA_LOGE("Invalid wmi handle, twt del dialog failed");
return QDF_STATUS_E_INVAL;
}
return wmi_unified_twt_del_dialog_cmd(wmi_handle, params);
}