blob: bab50919a3e45a148086fce7d0f8733161ec0b66 [file] [log] [blame]
/*
* Copyright (c) 2017 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
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/**
* DOC : wlan_hdd_he.c
*
* WLAN Host Device Driver file for 802.11ax (High Efficiency) support.
*
*/
#include "wlan_hdd_main.h"
#include "wlan_hdd_he.h"
/**
* hdd_he_wni_cfg_to_string() - return string conversion of HE WNI CFG
* @cfg_id: Config ID.
*
* This utility function helps log string conversion of WNI config ID.
*
* Return: string conversion of the HE WNI config ID, if match found;
* "Invalid" otherwise.
*/
static const char *hdd_he_wni_cfg_to_string(uint16_t cfg_id)
{
switch (cfg_id) {
default:
return "Invalid";
CASE_RETURN_STRING(WNI_CFG_HE_CONTROL);
CASE_RETURN_STRING(WNI_CFG_HE_TWT_REQUESTOR);
CASE_RETURN_STRING(WNI_CFG_HE_TWT_RESPONDER);
CASE_RETURN_STRING(WNI_CFG_HE_FRAGMENTATION);
CASE_RETURN_STRING(WNI_CFG_HE_MAX_FRAG_MSDU);
CASE_RETURN_STRING(WNI_CFG_HE_MIN_FRAG_SIZE);
CASE_RETURN_STRING(WNI_CFG_HE_TRIG_PAD);
CASE_RETURN_STRING(WNI_CFG_HE_MTID_AGGR);
CASE_RETURN_STRING(WNI_CFG_HE_LINK_ADAPTATION);
CASE_RETURN_STRING(WNI_CFG_HE_ALL_ACK);
CASE_RETURN_STRING(WNI_CFG_HE_UL_MU_RSP_SCHEDULING);
CASE_RETURN_STRING(WNI_CFG_HE_BUFFER_STATUS_RPT);
CASE_RETURN_STRING(WNI_CFG_HE_BCAST_TWT);
CASE_RETURN_STRING(WNI_CFG_HE_BA_32BIT);
CASE_RETURN_STRING(WNI_CFG_HE_MU_CASCADING);
CASE_RETURN_STRING(WNI_CFG_HE_MULTI_TID);
CASE_RETURN_STRING(WNI_CFG_HE_DL_MU_BA);
CASE_RETURN_STRING(WNI_CFG_HE_OMI);
CASE_RETURN_STRING(WNI_CFG_HE_OFDMA_RA);
CASE_RETURN_STRING(WNI_CFG_HE_MAX_AMPDU_LEN);
CASE_RETURN_STRING(WNI_CFG_HE_AMSDU_FRAG);
CASE_RETURN_STRING(WNI_CFG_HE_FLEX_TWT_SCHED);
CASE_RETURN_STRING(WNI_CFG_HE_RX_CTRL);
CASE_RETURN_STRING(WNI_CFG_HE_BSRP_AMPDU_AGGR);
CASE_RETURN_STRING(WNI_CFG_HE_QTP);
CASE_RETURN_STRING(WNI_CFG_HE_A_BQR);
CASE_RETURN_STRING(WNI_CFG_HE_DUAL_BAND);
CASE_RETURN_STRING(WNI_CFG_HE_CHAN_WIDTH);
CASE_RETURN_STRING(WNI_CFG_HE_RX_PREAM_PUNC);
CASE_RETURN_STRING(WNI_CFG_HE_CLASS_OF_DEVICE);
CASE_RETURN_STRING(WNI_CFG_HE_LDPC);
CASE_RETURN_STRING(WNI_CFG_HE_LTF_PPDU);
CASE_RETURN_STRING(WNI_CFG_HE_LTF_NDP);
CASE_RETURN_STRING(WNI_CFG_HE_STBC);
CASE_RETURN_STRING(WNI_CFG_HE_DOPPLER);
CASE_RETURN_STRING(WNI_CFG_HE_UL_MUMIMO);
CASE_RETURN_STRING(WNI_CFG_HE_DCM_TX);
CASE_RETURN_STRING(WNI_CFG_HE_DCM_RX);
CASE_RETURN_STRING(WNI_CFG_HE_MU_PPDU);
CASE_RETURN_STRING(WNI_CFG_HE_SU_BEAMFORMER);
CASE_RETURN_STRING(WNI_CFG_HE_SU_BEAMFORMEE);
CASE_RETURN_STRING(WNI_CFG_HE_MU_BEAMFORMER);
CASE_RETURN_STRING(WNI_CFG_HE_BFEE_STS_LT80);
CASE_RETURN_STRING(WNI_CFG_HE_NSTS_TOT_LT80);
CASE_RETURN_STRING(WNI_CFG_HE_BFEE_STS_GT80);
CASE_RETURN_STRING(WNI_CFG_HE_NSTS_TOT_GT80);
CASE_RETURN_STRING(WNI_CFG_HE_NUM_SOUND_LT80);
CASE_RETURN_STRING(WNI_CFG_HE_NUM_SOUND_GT80);
CASE_RETURN_STRING(WNI_CFG_HE_SU_FEED_TONE16);
CASE_RETURN_STRING(WNI_CFG_HE_MU_FEED_TONE16);
CASE_RETURN_STRING(WNI_CFG_HE_CODEBOOK_SU);
CASE_RETURN_STRING(WNI_CFG_HE_CODEBOOK_MU);
CASE_RETURN_STRING(WNI_CFG_HE_BFRM_FEED);
CASE_RETURN_STRING(WNI_CFG_HE_ER_SU_PPDU);
CASE_RETURN_STRING(WNI_CFG_HE_DL_PART_BW);
CASE_RETURN_STRING(WNI_CFG_HE_PPET_PRESENT);
CASE_RETURN_STRING(WNI_CFG_HE_SRP);
CASE_RETURN_STRING(WNI_CFG_HE_POWER_BOOST);
CASE_RETURN_STRING(WNI_CFG_HE_4x_LTF_GI);
CASE_RETURN_STRING(WNI_CFG_HE_NSS);
CASE_RETURN_STRING(WNI_CFG_HE_MCS);
CASE_RETURN_STRING(WNI_CFG_HE_PPET);
}
}
/**
* hdd_he_set_wni_cfg() - Update WNI CFG
* @hdd_ctx: HDD context
* @cfg_id: CFG to be udpated
* @new_value: Value to be updated
*
* Update WNI CFG with the value passed.
*
* Return: None
*/
static void hdd_he_set_wni_cfg(struct hdd_context_s *hdd_ctx,
uint16_t cfg_id, uint32_t new_value)
{
QDF_STATUS status;
status = sme_cfg_set_int(hdd_ctx->hHal, cfg_id, new_value);
if (QDF_IS_STATUS_ERROR(status))
hdd_err("could not set %s", hdd_he_wni_cfg_to_string(cfg_id));
}
/**
* hdd_update_tgt_he_cap() - Update HE related capabilities
* @hdd_ctx: HDD context
* @he_cap: Target HE capabilities
*
* This function updaates WNI CFG with Target capabilities received as part of
* Default values present in WNI CFG are the values supported by FW/HW.
* INI should be introduced if user control is required to control the value.
*
* Return: None
*/
void hdd_update_tgt_he_cap(struct hdd_context_s *hdd_ctx,
struct wma_tgt_cfg *cfg)
{
uint32_t ppet_size = sizeof(tDot11fIEppe_threshold);
QDF_STATUS status;
tDot11fIEvendor_he_cap *he_cap = &cfg->he_cap;
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_CONTROL, he_cap->htc_he);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_TWT_REQUESTOR,
he_cap->twt_request);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_TWT_RESPONDER,
he_cap->twt_responder);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_FRAGMENTATION,
he_cap->fragmentation);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_MAX_FRAG_MSDU,
he_cap->max_num_frag_msdu);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_MIN_FRAG_SIZE,
he_cap->min_frag_size);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_TRIG_PAD,
he_cap->trigger_frm_mac_pad);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_MTID_AGGR,
he_cap->multi_tid_aggr);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_LINK_ADAPTATION,
he_cap->he_link_adaptation);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_ALL_ACK, he_cap->all_ack);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_UL_MU_RSP_SCHEDULING,
he_cap->ul_mu_rsp_sched);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_BUFFER_STATUS_RPT,
he_cap->a_bsr);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_BCAST_TWT,
he_cap->broadcast_twt);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_BA_32BIT,
he_cap->ba_32bit_bitmap);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_MU_CASCADING,
he_cap->mu_cascade);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_MULTI_TID,
he_cap->ack_enabled_multitid);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_DL_MU_BA, he_cap->dl_mu_ba);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_OMI, he_cap->omi_a_ctrl);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_OFDMA_RA, he_cap->ofdma_ra);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_MAX_AMPDU_LEN,
he_cap->max_ampdu_len);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_AMSDU_FRAG, he_cap->amsdu_frag);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_FLEX_TWT_SCHED,
he_cap->flex_twt_sched);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_RX_CTRL, he_cap->rx_ctrl_frame);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_BSRP_AMPDU_AGGR,
he_cap->bsrp_ampdu_aggr);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_QTP, he_cap->qtp);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_A_BQR, he_cap->a_bqr);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_DUAL_BAND, he_cap->dual_band);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_CHAN_WIDTH, he_cap->chan_width);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_RX_PREAM_PUNC,
he_cap->rx_pream_puncturing);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_CLASS_OF_DEVICE,
he_cap->device_class);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_LDPC, he_cap->ldpc_coding);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_LTF_PPDU,
he_cap->he_ltf_gi_ppdu);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_LTF_NDP, he_cap->he_ltf_gi_ndp);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_STBC, he_cap->stbc);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_DOPPLER, he_cap->doppler);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_UL_MUMIMO, he_cap->ul_mu);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_DCM_TX, he_cap->dcm_enc_tx);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_DCM_RX, he_cap->dcm_enc_rx);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_MU_PPDU, he_cap->ul_he_mu);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_SU_BEAMFORMER,
he_cap->su_beamformer);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_SU_BEAMFORMEE,
he_cap->su_beamformee);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_MU_BEAMFORMER,
he_cap->mu_beamformer);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_BFEE_STS_LT80,
he_cap->bfee_sts_lt_80);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_NSTS_TOT_LT80,
he_cap->nsts_tol_lt_80);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_BFEE_STS_GT80,
he_cap->bfee_sta_gt_80);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_NSTS_TOT_GT80,
he_cap->nsts_tot_gt_80);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_NUM_SOUND_LT80,
he_cap->num_sounding_lt_80);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_NUM_SOUND_GT80,
he_cap->num_sounding_gt_80);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_SU_FEED_TONE16,
he_cap->su_feedback_tone16);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_MU_FEED_TONE16,
he_cap->mu_feedback_tone16);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_CODEBOOK_SU,
he_cap->codebook_su);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_CODEBOOK_MU,
he_cap->codebook_mu);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_BFRM_FEED,
he_cap->beamforming_feedback);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_ER_SU_PPDU,
he_cap->he_er_su_ppdu);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_DL_PART_BW,
he_cap->dl_mu_mimo_part_bw);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_PPET_PRESENT,
he_cap->ppet_present);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_SRP, he_cap->srp);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_POWER_BOOST,
he_cap->power_boost);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_4x_LTF_GI, he_cap->he_ltf_gi_4x);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_NSS, he_cap->nss_supported);
hdd_he_set_wni_cfg(hdd_ctx, WNI_CFG_HE_MCS, he_cap->mcs_supported);
/* PPET can not be configured by user - Set values from FW */
status = sme_cfg_set_str(hdd_ctx->hHal, WNI_CFG_HE_PPET,
(void *)&he_cap->ppe_threshold, ppet_size);
if (status == QDF_STATUS_E_FAILURE)
hdd_alert("could not set HE PPET");
}