From acd107d0a6e3f0a389be38a18e6a15e70d8ac659 Mon Sep 17 00:00:00 2001 From: Kiran Kumar Lokere Date: Wed, 9 Jan 2019 15:02:11 -0800 Subject: [PATCH] qcacld-3.0: Add support to configure HE +HTC support and OMI Tx Add support to configure HE +HTC support in HE caps and HE OM control transmission. Change-Id: Ic3ad5952198472ecda79471a37ff527dfdbcdbf0 CRs-Fixed: 2359376 --- core/hdd/src/wlan_hdd_cfg80211.c | 86 +++++++++++-- core/mac/inc/ani_global.h | 3 + core/sme/inc/sme_api.h | 82 +++++++++--- core/sme/src/common/sme_api.c | 208 ++++++++++++++++++++----------- 4 files changed, 277 insertions(+), 102 deletions(-) diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 3d57a0cdbeee..994e22066ab9 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -5297,6 +5297,14 @@ wlan_hdd_wifi_config_policy[QCA_WLAN_VENDOR_ATTR_CONFIG_MAX + 1] = { }; +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 }, + [QCA_WLAN_VENDOR_ATTR_HE_OMI_CH_BW] = {.type = NLA_U8 }, + [QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DISABLE] = {.type = NLA_U8 }, + [QCA_WLAN_VENDOR_ATTR_HE_OMI_TX_NSTS] = {.type = NLA_U8 }, +}; + static const struct nla_policy wlan_hdd_wifi_test_config_policy[ QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_MAX + 1] = { @@ -5344,6 +5352,10 @@ wlan_hdd_wifi_test_config_policy[ .type = NLA_FLAG}, [QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_SUPPDU] = { .type = NLA_U8}, + [QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_HTC_HE_SUPP] = { + .type = NLA_U8}, + [QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OMI_TX] = { + .type = NLA_NESTED}, [QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_ACTION_TX_TB_PPDU] = { .type = NLA_U8}, }; @@ -7039,19 +7051,62 @@ __wlan_hdd_cfg80211_set_wifi_test_config(struct wiphy *wiphy, cfg_val); } - cmd_id = QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_BW; + cmd_id = QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OMI_TX; if (tb[cmd_id]) { - cfg_val = nla_get_u8(tb[cmd_id]); - ret_val = sme_send_he_om_ctrl_bw_update(hdd_ctx->mac_handle, + struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_HE_OMI_MAX + 1]; + struct nlattr *curr_attr; + int tmp, rc; + nla_for_each_nested(curr_attr, tb[cmd_id], tmp) { + rc = wlan_cfg80211_nla_parse( + tb2, QCA_WLAN_VENDOR_ATTR_HE_OMI_MAX, + nla_data(curr_attr), + nla_len(curr_attr), + qca_wlan_vendor_attr_he_omi_tx_policy); + if (rc) { + hdd_err("Invalid ATTR"); + goto send_err; + } + cmd_id = QCA_WLAN_VENDOR_ATTR_HE_OMI_CH_BW; + if (tb2[cmd_id]) { + cfg_val = nla_get_u8(tb2[cmd_id]); + ret_val = sme_set_he_om_ctrl_param( + hdd_ctx->mac_handle, adapter->vdev_id, - cfg_val); - } - cmd_id = QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_NSS; - if (tb[cmd_id]) { - cfg_val = nla_get_u8(tb[cmd_id]); - ret_val = sme_send_he_om_ctrl_nss_update(hdd_ctx->mac_handle, - adapter->vdev_id, - cfg_val); + cmd_id, cfg_val); + } + cmd_id = QCA_WLAN_VENDOR_ATTR_HE_OMI_RX_NSS; + if (tb2[cmd_id]) { + cfg_val = nla_get_u8(tb2[cmd_id]); + ret_val = sme_set_he_om_ctrl_param( + hdd_ctx->mac_handle, + adapter->vdev_id, + cmd_id, cfg_val); + } + + cmd_id = QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DISABLE; + if (tb2[cmd_id]) { + cfg_val = nla_get_u8(tb2[cmd_id]); + ret_val = sme_set_he_om_ctrl_param( + hdd_ctx->mac_handle, + adapter->vdev_id, + cmd_id, cfg_val); + } + + cmd_id = QCA_WLAN_VENDOR_ATTR_HE_OMI_TX_NSTS; + if (tb2[cmd_id]) { + cfg_val = nla_get_u8(tb2[cmd_id]); + ret_val = sme_set_he_om_ctrl_param( + hdd_ctx->mac_handle, + adapter->vdev_id, + cmd_id, cfg_val); + } + } + if (ret_val) { + sme_reset_he_om_ctrl(hdd_ctx->mac_handle); + goto send_err; + } + ret_val = sme_send_he_om_ctrl_update(hdd_ctx->mac_handle, + adapter->vdev_id); } if (tb[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_CLEAR_HE_OM_CTRL_CONFIG]) @@ -7067,6 +7122,15 @@ __wlan_hdd_cfg80211_set_wifi_test_config(struct wiphy *wiphy, sme_config_su_ppdu_queue(adapter->vdev_id, false); } + cmd_id = QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_HTC_HE_SUPP; + if (tb[cmd_id]) { + cfg_val = nla_get_u8(tb[cmd_id]); + hdd_debug("Configure +HTC_HE support %d", cfg_val); + sme_update_he_htc_he_supp(hdd_ctx->mac_handle, + adapter->vdev_id, + (cfg_val ? true : false)); + } + cmd_id = QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_ACTION_TX_TB_PPDU; if (tb[cmd_id]) { cfg_val = nla_get_u8(tb[cmd_id]); diff --git a/core/mac/inc/ani_global.h b/core/mac/inc/ani_global.h index 682eab686f49..396c099eefa3 100644 --- a/core/mac/inc/ani_global.h +++ b/core/mac/inc/ani_global.h @@ -817,6 +817,9 @@ struct mac_context { uint8_t he_om_ctrl_cfg_bw; bool he_om_ctrl_cfg_nss_set; uint8_t he_om_ctrl_cfg_nss; + bool he_om_ctrl_cfg_ul_mu_dis; + bool he_om_ctrl_cfg_tx_nsts_set; + uint8_t he_om_ctrl_cfg_tx_nsts; #ifdef WLAN_FEATURE_11AX tDot11fIEhe_cap he_cap_2g; tDot11fIEhe_cap he_cap_5g; diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h index 2cf64de6114b..51feea26d115 100644 --- a/core/sme/inc/sme_api.h +++ b/core/sme/inc/sme_api.h @@ -42,6 +42,7 @@ #include "sir_types.h" #include "scheduler_api.h" #include "wlan_serialization_legacy_api.h" +#include /*-------------------------------------------------------------------------- Preprocessor definitions and constants @@ -2691,13 +2692,21 @@ int sme_update_he_trigger_frm_mac_pad(mac_handle_t mac_handle, int sme_update_he_om_ctrl_supp(mac_handle_t mac_handle, uint8_t session_id, uint8_t cfg_val); -#define NUM_OM_CTRL_UPDATE_CFG_PARAMS 7 -#define OM_CTRL_CMD_MAC_BITS31 1 -#define OM_CTRL_CMD_MAC_BITS47 2 -#define OM_CTRL_CMD_RX_NSS 3 -#define OM_CTRL_CMD_BW 4 -#define OM_CTRL_CMD_ULMU 5 -#define OM_CTRL_CMD_TX_NSS 6 +#define A_CTRL_ID_OMI 0x1 +struct omi_ctrl_tx { + uint32_t omi_in_vht:1; + uint32_t omi_in_he:1; + uint32_t a_ctrl_id:4; + uint32_t rx_nss:3; + uint32_t ch_bw:2; + uint32_t ul_mu_dis:1; + uint32_t tx_nsts:3; + uint32_t er_su_dis:1; + uint32_t dl_mu_mimo_resound:1; + uint32_t ul_mu_data_dis:1; + uint32_t reserved:14; +}; + int sme_send_he_om_ctrl_bw_update(mac_handle_t mac_handle, uint8_t session_id, uint8_t cfg_val); @@ -2716,6 +2725,29 @@ void sme_reset_he_om_ctrl(mac_handle_t mac_handle); */ int sme_config_action_tx_in_tb_ppdu(mac_handle_t mac_handle, uint8_t session_id, uint8_t cfg_val); + +/** + * sme_send_he_om_ctrl_update() - Send HE OM ctrl Tx cmd to FW + * @mac_handle: Pointer to mac handle + * @session_id: SME session id + * + * Return: 0 on success else err code + */ +int sme_send_he_om_ctrl_update(mac_handle_t mac_handle, uint8_t session_id); + +/** + * sme_set_he_om_ctrl_param() - Update HE OM control params for OMI Tx + * @mac_handle: Pointer to mac handle + * @session_id: SME session id + * @param: HE om control parameter + * @cfg_val: HE OM control parameter config value + * + * Return: 0 on success else err code + */ +int sme_set_he_om_ctrl_param(mac_handle_t mac_handle, uint8_t session_id, + enum qca_wlan_vendor_attr_he_omi_tx param, + uint8_t cfg_val); + /** * sme_set_usr_cfg_mu_edca() - sets the user cfg MU EDCA params flag * @mac_handle: Opaque handle to the global MAC context @@ -2733,6 +2765,17 @@ void sme_set_usr_cfg_mu_edca(mac_handle_t mac_handle, bool val); */ void sme_set_he_mu_edca_def_cfg(mac_handle_t mac_handle); +/** + * sme_update_he_htc_he_supp() - Update +HTC-HE support in HE capabilities + * @mac_handle: Pointer to mac handle + * @session_id: SME session id + * @cfg_val: config setting + * + * Return: 0 on success else err code + */ +int sme_update_he_htc_he_supp(mac_handle_t mac_handle, uint8_t session_id, + bool cfg_val); + /** * sme_update_mu_edca_params() - updates MU EDCA params values * @mac_handle: Opaque handle to the global MAC context @@ -2824,16 +2867,11 @@ static inline int sme_update_he_om_ctrl_supp(mac_handle_t mac_handle, return 0; } -static inline int sme_send_he_om_ctrl_bw_update(mac_handle_t mac_handle, - uint8_t session_id, - uint8_t cfg_val) -{ - return 0; -} -static inline int sme_send_he_om_ctrl_nss_update(mac_handle_t mac_handle, - uint8_t session_id, - uint8_t cfg_val) +static inline int +sme_set_he_om_ctrl_param(mac_handle_t mac_handle, uint8_t session_id, + enum qca_wlan_vendor_attr_he_omi_tx param, + uint8_t cfg_val) { return 0; } @@ -2849,6 +2887,18 @@ static inline int sme_config_action_tx_in_tb_ppdu(mac_handle_t mac_handle, return 0; } +static inline int sme_update_he_htc_he_supp(mac_handle_t mac_handle, + uint8_t session_id, + bool cfg_val) +{ + return 0; +} + +static inline int +sme_send_he_om_ctrl_update(mac_handle_t mac_handle, uint8_t session_id) +{ + return 0; +} static inline void sme_set_usr_cfg_mu_edca(mac_handle_t mac_handle, bool val) { } diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index fa236eb62a0f..a9d3723ba2ab 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -54,7 +54,6 @@ #include "ol_txrx.h" #include "wifi_pos_api.h" #include "net/cfg80211.h" -#include #include #include "wlan_mlme_public_struct.h" #include "wlan_mlme_main.h" @@ -11387,103 +11386,159 @@ int sme_update_he_om_ctrl_supp(mac_handle_t mac_handle, uint8_t session_id, return 0; } -int sme_send_he_om_ctrl_bw_update(mac_handle_t mac_handle, uint8_t session_id, - uint8_t cfg_val) +int sme_update_he_htc_he_supp(mac_handle_t mac_handle, uint8_t session_id, + bool cfg_val) { - uint32_t om_ctrl_cmd[NUM_OM_CTRL_UPDATE_CFG_PARAMS] = {0}; - QDF_STATUS status; + struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); - struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, session_id); + struct csr_roam_session *session; + + session = CSR_GET_SESSION(mac_ctx, session_id); if (!session) { - sme_err("Session does not exist, Session_id: %d", session_id); + sme_err("No session for id %d", session_id); return -EINVAL; } + + mac_ctx->mlme_cfg->he_caps.dot11_he_cap.htc_he = cfg_val; + csr_update_session_he_cap(mac_ctx, session); + + return 0; +} + +static QDF_STATUS +sme_validate_session_for_cap_update(struct mac_context *mac_ctx, + uint8_t session_id, + struct csr_roam_session *session) +{ + if (!session) { + sme_err("Session does not exist, Session_id: %d", session_id); + return QDF_STATUS_E_INVAL; + } if (!csr_is_conn_state_connected_infra(mac_ctx, session_id)) { sme_info("STA is not connected, Session_id: %d", session_id); + return QDF_STATUS_E_INVAL; + } + + return QDF_STATUS_SUCCESS; +} + +int sme_send_he_om_ctrl_update(mac_handle_t mac_handle, uint8_t session_id) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); + struct omi_ctrl_tx omi_data = {0}; + void *wma_handle; + struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, session_id); + uint32_t param_val = 0; + + wma_handle = cds_get_context(QDF_MODULE_ID_WMA); + if (!wma_handle) { + sme_err("wma handle is NULL"); + return -EIO; + } + + status = sme_validate_session_for_cap_update(mac_ctx, session_id, + session); + if (QDF_IS_STATUS_ERROR(status)) return -EINVAL; - } - if (cfg_val > session->connectedProfile.vht_channel_width) { - sme_info("OM ctrl BW %d is greater than connected BW %d", - cfg_val, session->connectedProfile.vht_channel_width); - return -EINVAL; - } - mac_ctx->he_om_ctrl_cfg_bw_set = true; - mac_ctx->he_om_ctrl_cfg_bw = cfg_val; - om_ctrl_cmd[0] = 1; - qdf_mem_copy((void *)&om_ctrl_cmd[OM_CTRL_CMD_MAC_BITS31], - (void *)session->connectedProfile.bssid.bytes, - sizeof(uint32_t)); - qdf_mem_copy((void *)&om_ctrl_cmd[OM_CTRL_CMD_MAC_BITS47], - (void *)&session->connectedProfile.bssid.bytes[4], - sizeof(uint16_t)); - if (mac_ctx->he_om_ctrl_cfg_nss_set) { - om_ctrl_cmd[OM_CTRL_CMD_RX_NSS] = - mac_ctx->he_om_ctrl_cfg_nss - 1; - om_ctrl_cmd[OM_CTRL_CMD_TX_NSS] = - mac_ctx->he_om_ctrl_cfg_nss - 1; - } else { - om_ctrl_cmd[OM_CTRL_CMD_RX_NSS] = session->nss - 1; - om_ctrl_cmd[OM_CTRL_CMD_TX_NSS] = session->nss - 1; - } - om_ctrl_cmd[OM_CTRL_CMD_BW] = cfg_val; - om_ctrl_cmd[OM_CTRL_CMD_ULMU] = 1; - status = wma_form_unit_test_cmd_and_send(session_id, 13, 7, - om_ctrl_cmd); + + omi_data.a_ctrl_id = A_CTRL_ID_OMI; + + if (mac_ctx->he_om_ctrl_cfg_nss_set) + omi_data.rx_nss = mac_ctx->he_om_ctrl_cfg_nss; + else + omi_data.rx_nss = session->nss - 1; + + if (mac_ctx->he_om_ctrl_cfg_tx_nsts_set) + omi_data.tx_nsts = mac_ctx->he_om_ctrl_cfg_tx_nsts; + else + omi_data.tx_nsts = session->nss - 1; + + if (mac_ctx->he_om_ctrl_cfg_bw_set) + omi_data.ch_bw = mac_ctx->he_om_ctrl_cfg_bw; + else + omi_data.ch_bw = session->connectedProfile.vht_channel_width; + + omi_data.ul_mu_dis = mac_ctx->he_om_ctrl_cfg_ul_mu_dis; + omi_data.omi_in_vht = 0x1; + omi_data.omi_in_he = 0x1; + + sme_info("OMI: BW %d TxNSTS %d RxNSS %d ULMU %d, OMI_VHT %d, OMI_HE %d", + omi_data.ch_bw, omi_data.tx_nsts, omi_data.rx_nss, + omi_data.ul_mu_dis, omi_data.omi_in_vht, omi_data.omi_in_he); + qdf_mem_copy(¶m_val, &omi_data, sizeof(omi_data)); + sme_debug("param val %08X, bssid:"MAC_ADDRESS_STR, param_val, + MAC_ADDR_ARRAY(session->connectedProfile.bssid.bytes)); + status = wma_set_peer_param(wma_handle, + session->connectedProfile.bssid.bytes, + WMI_PEER_PARAM_XMIT_OMI, + param_val, session_id); if (QDF_STATUS_SUCCESS != status) { - sme_err("send_unit_test_cmd returned %d", status); + sme_err("set_peer_param_cmd returned %d", status); return -EIO; } return 0; } -int sme_send_he_om_ctrl_nss_update(mac_handle_t mac_handle, uint8_t session_id, - uint8_t cfg_val) +int sme_set_he_om_ctrl_param(mac_handle_t mac_handle, uint8_t session_id, + enum qca_wlan_vendor_attr_he_omi_tx param, + uint8_t cfg_val) { - uint32_t om_ctrl_cmd[NUM_OM_CTRL_UPDATE_CFG_PARAMS] = {0}; QDF_STATUS status; struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); struct csr_roam_session *session = CSR_GET_SESSION(mac_ctx, session_id); - if (!session) { - sme_err("Session does not exist, Session_id: %d", session_id); + status = sme_validate_session_for_cap_update(mac_ctx, session_id, + session); + if (QDF_IS_STATUS_ERROR(status)) return -EINVAL; - } - if (!csr_is_conn_state_connected_infra(mac_ctx, session_id)) { - sme_info("STA not in connected state Session_id: %d", - session_id); - return -EINVAL; - } - if (cfg_val > session->nss) { - sme_info("OM ctrl Nss %d is greater than connected Nss %d", - cfg_val, session->nss); - return -EINVAL; - } - mac_ctx->he_om_ctrl_cfg_nss_set = true; - mac_ctx->he_om_ctrl_cfg_nss = cfg_val; - om_ctrl_cmd[0] = 1; - qdf_mem_copy((void *)&om_ctrl_cmd[OM_CTRL_CMD_MAC_BITS31], - (void *)session->connectedProfile.bssid.bytes, - sizeof(uint32_t)); - qdf_mem_copy((void *)&om_ctrl_cmd[OM_CTRL_CMD_MAC_BITS47], - (void *)&session->connectedProfile.bssid.bytes[4], - sizeof(uint16_t)); - if (mac_ctx->he_om_ctrl_cfg_bw_set) - om_ctrl_cmd[OM_CTRL_CMD_BW] = mac_ctx->he_om_ctrl_cfg_bw; - else - om_ctrl_cmd[OM_CTRL_CMD_BW] = - session->connectedProfile.vht_channel_width; - - om_ctrl_cmd[OM_CTRL_CMD_RX_NSS] = cfg_val - 1; - om_ctrl_cmd[OM_CTRL_CMD_TX_NSS] = cfg_val - 1; - om_ctrl_cmd[OM_CTRL_CMD_ULMU] = 1; - status = wma_form_unit_test_cmd_and_send(session_id, 13, 7, - om_ctrl_cmd); - if (QDF_STATUS_SUCCESS != status) { - sme_err("send_unit_test_cmd returned %d", status); - return -EIO; + switch(param) { + case QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DISABLE: + sme_debug("Set OM ctrl UL MU dis to %d", cfg_val); + mac_ctx->he_om_ctrl_cfg_ul_mu_dis = cfg_val; + break; + case QCA_WLAN_VENDOR_ATTR_HE_OMI_RX_NSS: + if ((cfg_val + 1) > session->nss) { + sme_debug("OMI Nss %d is > connected Nss %d", + cfg_val, session->nss); + mac_ctx->he_om_ctrl_cfg_nss_set = false; + return 0; + } + sme_debug("Set OM ctrl Rx Nss cfg to %d", cfg_val); + mac_ctx->he_om_ctrl_cfg_nss_set = true; + mac_ctx->he_om_ctrl_cfg_nss = cfg_val; + break; + case QCA_WLAN_VENDOR_ATTR_HE_OMI_CH_BW: + if (cfg_val > + session->connectedProfile.vht_channel_width) { + sme_info("OMI BW %d is > connected BW %d", + cfg_val, + session->connectedProfile. + vht_channel_width); + mac_ctx->he_om_ctrl_cfg_bw_set = false; + return 0; + } + sme_debug("Set OM ctrl BW cfg to %d", cfg_val); + mac_ctx->he_om_ctrl_cfg_bw_set = true; + mac_ctx->he_om_ctrl_cfg_bw = cfg_val; + break; + case QCA_WLAN_VENDOR_ATTR_HE_OMI_TX_NSTS: + if ((cfg_val + 1) > session->nss) { + sme_debug("OMI NSTS %d is > connected Nss %d", + cfg_val, session->nss); + mac_ctx->he_om_ctrl_cfg_tx_nsts_set = false; + return 0; + } + sme_debug("Set OM ctrl tx nsts cfg to %d", cfg_val); + mac_ctx->he_om_ctrl_cfg_tx_nsts_set = true; + mac_ctx->he_om_ctrl_cfg_tx_nsts = cfg_val; + break; + default: + sme_debug("Invalid OMI param %d", param); + return -EINVAL; } return 0; @@ -11497,6 +11552,9 @@ void sme_reset_he_om_ctrl(mac_handle_t mac_handle) mac_ctx->he_om_ctrl_cfg_nss_set = false; mac_ctx->he_om_ctrl_cfg_bw = 0; mac_ctx->he_om_ctrl_cfg_nss = 0; + mac_ctx->he_om_ctrl_cfg_ul_mu_dis = false; + mac_ctx->he_om_ctrl_cfg_tx_nsts_set = false; + mac_ctx->he_om_ctrl_cfg_tx_nsts = 0; } int sme_config_action_tx_in_tb_ppdu(mac_handle_t mac_handle, uint8_t session_id,