diff --git a/mlme/core/src/wlan_mlme_main.c b/mlme/core/src/wlan_mlme_main.c index 4bf374ecd2..ff45c8f79c 100644 --- a/mlme/core/src/wlan_mlme_main.c +++ b/mlme/core/src/wlan_mlme_main.c @@ -438,21 +438,69 @@ static void mlme_init_ht_cap_in_cfg(struct wlan_objmgr_psoc *psoc, { union { uint16_t val_16; - struct mlme_ht_capabilities_info default_ht_cap_info; - } u; + struct mlme_ht_capabilities_info ht_cap_info; + } u1; - u.val_16 = (uint16_t)cfg_default(CFG_HT_CAP_INFO); + union { + uint16_t val_16; + struct mlme_ht_ext_cap_info ext_cap_info; + } u2; - u.default_ht_cap_info.adv_coding_cap = + union { + uint8_t val_8; + struct mlme_ht_info_field_1 info_field_1; + } u3; + + union { + uint16_t val_16; + struct mlme_ht_info_field_2 info_field_2; + } u4; + + union { + uint16_t val_16; + struct mlme_ht_info_field_3 info_field_3; + } u5; + + /* HT Capabilities - HT Caps Info Field */ + u1.val_16 = (uint16_t)cfg_default(CFG_HT_CAP_INFO); + u1.ht_cap_info.adv_coding_cap = cfg_get(psoc, CFG_RX_LDPC_ENABLE); - u.default_ht_cap_info.rx_stbc = cfg_get(psoc, CFG_RX_STBC_ENABLE); - u.default_ht_cap_info.tx_stbc = cfg_get(psoc, CFG_TX_STBC_ENABLE); - u.default_ht_cap_info.short_gi_20_mhz = + u1.ht_cap_info.rx_stbc = cfg_get(psoc, CFG_RX_STBC_ENABLE); + u1.ht_cap_info.tx_stbc = cfg_get(psoc, CFG_TX_STBC_ENABLE); + u1.ht_cap_info.short_gi_20_mhz = cfg_get(psoc, CFG_SHORT_GI_20MHZ); - u.default_ht_cap_info.short_gi_40_mhz = + u1.ht_cap_info.short_gi_40_mhz = cfg_get(psoc, CFG_SHORT_GI_40MHZ); + ht_caps->ht_cap_info = u1.ht_cap_info; - ht_caps->ht_cap_info = u.default_ht_cap_info; + /* HT Capapabilties - AMPDU Params */ + ht_caps->ampdu_params.max_rx_ampdu_factor = + cfg_get(psoc, CFG_MAX_RX_AMPDU_FACTOR); + ht_caps->ampdu_params.mpdu_density = + cfg_get(psoc, CFG_MPDU_DENSITY); + ht_caps->ampdu_params.reserved = 0; + + /* HT Capabilities - Extended Capabilities field */ + u2.val_16 = (uint16_t)cfg_default(CFG_EXT_HT_CAP_INFO); + ht_caps->ext_cap_info = u2.ext_cap_info; + + /* HT Operation - Information subset 1 of 3 */ + u3.val_8 = (uint8_t)cfg_default(CFG_HT_INFO_FIELD_1); + ht_caps->info_field_1 = u3.info_field_1; + + /* HT Operation - Information subset 2 of 3 */ + u4.val_16 = (uint16_t)cfg_default(CFG_HT_INFO_FIELD_2); + ht_caps->info_field_2 = u4.info_field_2; + + /* HT Operation - Information subset 3 of 3 */ + u5.val_16 = (uint16_t)cfg_default(CFG_HT_INFO_FIELD_3); + ht_caps->info_field_3 = u5.info_field_3; + + ht_caps->short_preamble = cfg_get(psoc, CFG_SHORT_PREAMBLE); + ht_caps->enable_ampdu_ps = cfg_get(psoc, CFG_ENABLE_AMPDUPS); + ht_caps->enable_smps = cfg_get(psoc, CFG_ENABLE_HT_SMPS); + ht_caps->smps = cfg_get(psoc, CFG_HT_SMPS_MODE); + ht_caps->max_num_amsdu = cfg_get(psoc, CFG_MAX_AMSDU_NUM); } static void mlme_init_qos_cfg(struct wlan_objmgr_psoc *psoc, diff --git a/mlme/dispatcher/inc/cfg_mlme_ht_caps.h b/mlme/dispatcher/inc/cfg_mlme_ht_caps.h index a8a1cdf6e6..f5680c37a6 100644 --- a/mlme/dispatcher/inc/cfg_mlme_ht_caps.h +++ b/mlme/dispatcher/inc/cfg_mlme_ht_caps.h @@ -173,6 +173,203 @@ CFG_VALUE_OR_DEFAULT, \ "HT cap info") +/* + * + * gShortPreamble - Set Short Preamble + * @Min: 0 + * @Max: 1 + * @Default: 1 + * + * This ini is used to set default short Preamble + * + * Related: None + * + * Supported Feature: STA + * + * Usage: Internal/External + * + * + */ +#define CFG_SHORT_PREAMBLE CFG_INI_BOOL( \ + "gShortPreamble", \ + 1, \ + "Short Preamble") + +#define CFG_HT_AMPDU_PARAMS CFG_UINT( \ + "ht_ampdu_params", \ + 0, \ + 255, \ + 0, \ + CFG_VALUE_OR_DEFAULT, \ + "HT AMPDU Params") + +#define CFG_EXT_HT_CAP_INFO CFG_UINT( \ + "ext_ht_cap_info", \ + 0, \ + 65535, \ + 1024, \ + CFG_VALUE_OR_DEFAULT, \ + "HT Ext Cap Info") + +#define CFG_HT_INFO_FIELD_1 CFG_UINT( \ + "ht_info_field_1", \ + 0, \ + 255, \ + 15, \ + CFG_VALUE_OR_DEFAULT, \ + "HT Info Field 1") + +#define CFG_HT_INFO_FIELD_2 CFG_UINT( \ + "ht_info_field_2", \ + 0, \ + 65535, \ + 0, \ + CFG_VALUE_OR_DEFAULT, \ + "HT Info Field 2") + +#define CFG_HT_INFO_FIELD_3 CFG_UINT( \ + "ht_info_field_3", \ + 0, \ + 65535, \ + 0, \ + CFG_VALUE_OR_DEFAULT, \ + "HT Info Field 3") + +/* + * + * gEnableHtSMPS - Enable the SM Power Save + * @Min: 0 + * @Max: 1 + * @Default: 0 + * + * This ini is used to enable SM Power Save + * + * Related: None + * + * Supported Feature: STA + * + * Usage: Internal/External + * + * + */ +#define CFG_ENABLE_HT_SMPS CFG_INI_BOOL( \ + "gEnableHtSMPS", \ + 0, \ + "Enable HT SM PowerSave") + +/* + * + * gHtSMPS - SMPS Mode + * @Min: 0 + * @Max: 3 + * @Default: 3 + * + * This ini is used to set default SM Power Save Antenna mode + * 0 - Static + * 1 - Dynamic + * 2 - Reserved/Invalid + * 3 - Disabled + * + * Related: None + * + * Supported Feature: STA + * + * Usage: Internal/External + * + * + */ +#define CFG_HT_SMPS_MODE CFG_INI_UINT( \ + "gHtSMPS", \ + 0, \ + 3, \ + 3, \ + CFG_VALUE_OR_DEFAULT, \ + "HT SM Power Save Config") + +/* + * + * gMaxAmsduNum - Max number of MSDU's in aggregate + * @Min: 0 + * @Max: 3 + * @Default: 1 + * gMaxAmsduNum is the number of MSDU's transmitted in the 11n aggregate + * frame. Setting it to a value larger than 1 enables transmit aggregation. + * It is a PHY parameter that applies to all vdev's in firmware. + * + * Supported Feature: 11n aggregation + * + * Usage: Internal + * + * + */ +#define CFG_MAX_AMSDU_NUM CFG_INI_UINT( \ + "gMaxAmsduNum", \ + 0, \ + 3, \ + 1, \ + CFG_VALUE_OR_DEFAULT, \ + "Max AMSDU Number") + +/* + * + * gMaxRxAmpduFactor - Provide the maximum ampdu factor. + * @Min: 0 + * @Max: 3 + * @Default: 3 + * + * This ini is used to set default maxampdu factor + * + * Related: None + * + * Supported Feature: STA + * + * Usage: Internal/External + * + * + */ +#define CFG_MAX_RX_AMPDU_FACTOR CFG_INI_UINT( \ + "gMaxRxAmpduFactor", \ + 0, \ + 3, \ + 3, \ + CFG_VALUE_OR_DEFAULT, \ + "Max Rx AMPDU Factor") + +/* + * + * ght_mpdu_density - Configuration option for HT MPDU density + * @Min: 0 + * @Max: 7 + * @Default: 7 + * + * This ini is used to set default MDPU Density + * + * Related: None + * + * Supported Feature: STA + * + * Usage: Internal/External + * + * As per (Table 8-125 802.11-2012) + * 0 for no restriction + * 1 for 1/4 micro sec + * 2 for 1/2 micro sec + * 3 for 1 micro sec + * 4 for 2 micro sec + * 5 for 4 micro sec + * 6 for 8 micro sec + * 7 for 16 micro sec + * + * + */ +#define CFG_MPDU_DENSITY CFG_INI_UINT( \ + "ght_mpdu_density", \ + 0, \ + 7, \ + 7, \ + CFG_VALUE_OR_DEFAULT, \ + "MPDU Density") + #define CFG_HT_CAPS_ALL \ CFG(CFG_HT_CAP_INFO) \ CFG(CFG_TX_LDPC_ENABLE) \ @@ -180,6 +377,17 @@ CFG(CFG_TX_STBC_ENABLE) \ CFG(CFG_RX_STBC_ENABLE) \ CFG(CFG_SHORT_GI_20MHZ) \ - CFG(CFG_SHORT_GI_40MHZ) + CFG(CFG_SHORT_GI_40MHZ) \ + CFG(CFG_SHORT_PREAMBLE) \ + CFG(CFG_HT_AMPDU_PARAMS) \ + CFG(CFG_EXT_HT_CAP_INFO) \ + CFG(CFG_HT_INFO_FIELD_1) \ + CFG(CFG_HT_INFO_FIELD_2) \ + CFG(CFG_HT_INFO_FIELD_3) \ + CFG(CFG_ENABLE_HT_SMPS) \ + CFG(CFG_HT_SMPS_MODE) \ + CFG(CFG_MAX_AMSDU_NUM) \ + CFG(CFG_MAX_RX_AMPDU_FACTOR) \ + CFG(CFG_MPDU_DENSITY) #endif /* __CFG_MLME_HT_CAPS_H */ diff --git a/mlme/dispatcher/inc/wlan_mlme_api.h b/mlme/dispatcher/inc/wlan_mlme_api.h index 39a3c9ae97..9a6d4e084e 100644 --- a/mlme/dispatcher/inc/wlan_mlme_api.h +++ b/mlme/dispatcher/inc/wlan_mlme_api.h @@ -177,6 +177,46 @@ QDF_STATUS wlan_mlme_set_ht_cap_info(struct wlan_objmgr_psoc *psoc, struct mlme_ht_capabilities_info ht_cap_info); +/** + * wlan_mlme_get_max_amsdu_num() - get the max amsdu num + * @psoc: pointer to psoc object + * @value: pointer to the value where the max_amsdu num is to be filled + * + * Return: QDF_STATUS + */ +QDF_STATUS wlan_mlme_get_max_amsdu_num(struct wlan_objmgr_psoc *psoc, + uint8_t *value); + +/** + * wlan_mlme_set_max_amsdu_num() - set the max amsdu num + * @psoc: pointer to psoc object + * @value: value to be set for max_amsdu_num + * + * Return: QDF_STATUS + */ +QDF_STATUS wlan_mlme_set_max_amsdu_num(struct wlan_objmgr_psoc *psoc, + uint8_t value); + +/** + * wlan_mlme_get_ht_mpdu_density() - get the ht mpdu density + * @psoc: pointer to psoc object + * @value: pointer to the value where the ht mpdu density is to be filled + * + * Return: QDF_STATUS + */ +QDF_STATUS wlan_mlme_get_ht_mpdu_density(struct wlan_objmgr_psoc *psoc, + uint8_t *value); + +/** + * wlan_mlme_set_ht_mpdu_density() - set the ht mpdu density + * @psoc: pointer to psoc object + * @value: value to be set for ht mpdu density + * + * Return: QDF_STATUS + */ +QDF_STATUS wlan_mlme_set_ht_mpdu_density(struct wlan_objmgr_psoc *psoc, + uint8_t value); + /** * wlan_mlme_get_band_capability() - Get the Band capability config * @psoc: pointer to psoc object diff --git a/mlme/dispatcher/inc/wlan_mlme_public_struct.h b/mlme/dispatcher/inc/wlan_mlme_public_struct.h index e3b4bd0cc6..40d800cf32 100644 --- a/mlme/dispatcher/inc/wlan_mlme_public_struct.h +++ b/mlme/dispatcher/inc/wlan_mlme_public_struct.h @@ -301,12 +301,161 @@ struct mlme_ht_capabilities_info { } qdf_packed; #endif +/** + * struct mlme_ht_param_info - HT AMPDU Parameters Info + * @reserved: reserved bits + * @mpdu_density: MPDU Density + * @max_rx_ampdu_factor: Max Rx AMPDU Factor + */ +#ifndef ANI_LITTLE_BIT_ENDIAN +struct mlme_ht_param_info { + uint8_t reserved:3; + uint8_t mpdu_density:3; + uint8_t max_rx_ampdu_factor:2; +} qdf_packed; +#else +struct mlme_ht_param_info { + uint8_t max_rx_ampdu_factor:2; + uint8_t mpdu_density:3; + uint8_t reserved:3; +#endif +} qdf_packed; + +/** + * struct mlme_ht_ext_cap_info - Extended HT Capabilities Info + * reserved_2: Reserved Bits + * mcs_feedback: MCS Feedback Capability + * reserved_1: Reserved Bits + * transition_time: Time needed for transition between 20Mhz and 40 Mhz + * pco: PCO (Phased Coexistence Operation) Support + */ +#ifndef ANI_LITTLE_BIT_ENDIAN +struct mlme_ht_ext_cap_info { + uint16_t reserved_2:6; + uint16_t mcs_feedback:2; + uint16_t reserved_1:5; + uint16_t transition_time:2; + uint16_t pco:1; +} qdf_packed; +#else +struct mlme_ht_ext_cap_info { + uint16_t pco:1; + uint16_t transition_time:2; + uint16_t reserved1:5; + uint16_t mcs_feedback:2; + uint16_t reserved2:6; +} qdf_packed; +#endif + +/** + * struct mlme_ht_info_field_1 - Additional HT IE Field1 + * @service_interval_granularity: Shortest Service Interval + * @controlled_access_only: Access Control for assoc requests + * @rifs_mode: Reduced Interframe Spacing mode + * @recommended_tx_width_set: Recommended Tx Channel Width + * @secondary_channel_offset: Secondary Channel Offset + */ +#ifndef ANI_LITTLE_BIT_ENDIAN +struct mlme_ht_info_field_1 { + uint8_t service_interval_granularity:3; + uint8_t controlled_access_only:1; + uint8_t rifs_mode:1; + uint8_t recommended_tx_width_set:1; + uint8_t secondary_channel_offset:2; +} qdf_packed; +#else +struct mlme_ht_info_field_1 { + uint8_t secondary_channel_offset:2; + uint8_t recommended_tx_width_set:1; + uint8_t rifs_mode:1; + uint8_t controlled_access_only:1; + uint8_t service_interval_granularity:3; +} qdf_packed; +#endif + +/* struct mlme_ht_info_field_2 - Additional HT IE Field2 + * @reserved: reserved bits + * @obss_non_ht_sta_present: Protection for non-HT STAs by Overlapping BSS + * @transmit_burst_limit: Transmit Burst Limit + * @non_gf_devices_present: Non Greenfield devices present + * @op_mode: Operation Mode + */ +#ifndef ANI_LITTLE_BIT_ENDIAN +struct mlme_ht_info_field_2 { + uint16_t reserved:11; + uint16_t obss_non_ht_sta_present:1; + uint16_t transmit_burst_limit:1; + uint16_t non_gf_devices_present:1; + uint16_t op_mode:2; +} qdf_packed; +#else +struct mlme_ht_info_field_2 { + uint16_t op_mode:2; + uint16_t nonGFDevicesPresent:1; + uint16_t transmit_burst_limit:1; + uint16_t obss_non_ht_sta_present:1; + uint16_t reserved:11; +} qdf_packed; +#endif + +/** + * struct mlme_ht_info_field_3 - Additional HT IE Field3 + * @reserved: reserved bits + * @pco_phase: PCO Phase + * @pco_active: PCO state + * @lsig_txop_protection_full_support: L-Sig TXOP Protection Full Support + * @secondary_beacon: Beacon ID + * @dual_cts_protection: Dual CTS protection Required + * @basic_stbc_mcs: Basic STBC MCS + */ +#ifndef ANI_LITTLE_BIT_ENDIAN +struct mlme_ht_info_field_3 { + uint16_t reserved:4; + uint16_t pco_phase:1; + uint16_t pco_active:1; + uint16_t lsig_txop_protection_full_support:1; + uint16_t secondary_beacon:1; + uint16_t dual_cts_protection:1; + uint16_t basic_stbc_mcs:7; +} qdf_packed; +#else +struct mlme_ht_info_field_3 { + uint16_t basic_stbc_mcs:7; + uint16_t dual_cts_protection:1; + uint16_t secondary_beacon:1; + uint16_t lsig_txop_protection_full_support:1; + uint16_t pco_active:1; + uint16_t pco_phase:1; + uint16_t reserved:4; +} qdf_packed; +#endif + /** * struct wlan_mlme_ht_caps - HT Capabilities related config items * @ht_cap_info: HT capabilities Info Structure + * @ampdu_params: AMPDU parameters + * @ext_cap_info: HT EXT capabilities info + * @info_field_1: HT Information Subset 1 + * @info_field_2: HT Information Subset 2 + * @info_field_3: HT Information Subset 3 + * @short_preamble: Short Preamble support + * @enable_ampdu_ps: Enable AMPDU Power Save + * @enable_smps: Enabled SM Power Save + * @smps : SM Power Save mode + * @max_num_amsdu: Max number of AMSDU */ struct wlan_mlme_ht_caps { struct mlme_ht_capabilities_info ht_cap_info; + struct mlme_ht_param_info ampdu_params; + struct mlme_ht_ext_cap_info ext_cap_info; + struct mlme_ht_info_field_1 info_field_1; + struct mlme_ht_info_field_2 info_field_2; + struct mlme_ht_info_field_3 info_field_3; + bool short_preamble; + bool enable_ampdu_ps; + bool enable_smps; + uint8_t smps; + uint8_t max_num_amsdu; }; /* diff --git a/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h b/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h index 1ad51b486d..fa2e8e5a16 100644 --- a/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h +++ b/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h @@ -149,6 +149,62 @@ QDF_STATUS ucfg_mlme_set_ht_cap_info(struct wlan_objmgr_psoc *psoc, return wlan_mlme_set_ht_cap_info(psoc, ht_cap_info); } +/** + * ucfg_mlme_get_max_amsdu_num() - get the max amsdu num + * @psoc: pointer to psoc object + * @value: pointer to the value where the max_amsdu num is to be filled + * + * Return: QDF_STATUS + */ +static inline +QDF_STATUS ucfg_mlme_get_max_amsdu_num(struct wlan_objmgr_psoc *psoc, + uint8_t *value) +{ + return wlan_mlme_get_max_amsdu_num(psoc, value); +} + +/** + * ucfg_mlme_set_max_amsdu_num() - set the max amsdu num + * @psoc: pointer to psoc object + * @value: value to be set for max_amsdu_num + * + * Return: QDF_STATUS + */ +static inline +QDF_STATUS ucfg_mlme_set_max_amsdu_num(struct wlan_objmgr_psoc *psoc, + uint8_t value) +{ + return wlan_mlme_set_max_amsdu_num(psoc, value); +} + +/** + * ucfg_mlme_get_ht_mpdu_density() - get the ht mpdu density + * @psoc: pointer to psoc object + * @value: pointer to the value where the ht mpdu density is to be filled + * + * Return: QDF_STATUS + */ +static inline +QDF_STATUS ucfg_mlme_get_ht_mpdu_density(struct wlan_objmgr_psoc *psoc, + uint8_t *value) +{ + return wlan_mlme_get_ht_mpdu_density(psoc, value); +} + +/** + * ucfg_mlme_set_ht_mpdu_density() - set the ht mpdu density + * @psoc: pointer to psoc object + * @value: value to be set for ht mpdu density + * + * Return: QDF_STATUS + */ +static inline +QDF_STATUS ucfg_mlme_set_ht_mpdu_density(struct wlan_objmgr_psoc *psoc, + uint8_t value) +{ + return wlan_mlme_set_ht_mpdu_density(psoc, value); +} + /** * ucfg_mlme_get_band_capability() - Get the Band capability config * @psoc: pointer to psoc object diff --git a/mlme/dispatcher/src/wlan_mlme_api.c b/mlme/dispatcher/src/wlan_mlme_api.c index bbd4375ab3..cd7fcdd255 100644 --- a/mlme/dispatcher/src/wlan_mlme_api.c +++ b/mlme/dispatcher/src/wlan_mlme_api.c @@ -90,6 +90,80 @@ QDF_STATUS wlan_mlme_set_ht_cap_info(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } +QDF_STATUS wlan_mlme_get_max_amsdu_num(struct wlan_objmgr_psoc *psoc, + uint8_t *value) +{ + struct wlan_mlme_psoc_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_obj(psoc); + if (!mlme_obj) { + mlme_err("Failed to get MLME Obj"); + return QDF_STATUS_E_FAILURE; + } + + *value = mlme_obj->cfg.ht_caps.max_num_amsdu; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS wlan_mlme_set_max_amsdu_num(struct wlan_objmgr_psoc *psoc, + uint8_t value) +{ + struct wlan_mlme_psoc_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_obj(psoc); + if (!mlme_obj) { + mlme_err("Failed to get MLME Obj"); + return QDF_STATUS_E_FAILURE; + } + + if (!cfg_in_range(CFG_MAX_AMSDU_NUM, value)) { + mlme_err("Error in setting Max AMSDU Num"); + return QDF_STATUS_E_INVAL; + } + + mlme_obj->cfg.ht_caps.max_num_amsdu = value; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS wlan_mlme_get_ht_mpdu_density(struct wlan_objmgr_psoc *psoc, + uint8_t *value) +{ + struct wlan_mlme_psoc_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_obj(psoc); + if (!mlme_obj) { + mlme_err("Failed to get MLME Obj"); + return QDF_STATUS_E_FAILURE; + } + + *value = (uint8_t)mlme_obj->cfg.ht_caps.ampdu_params.mpdu_density; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS wlan_mlme_set_ht_mpdu_density(struct wlan_objmgr_psoc *psoc, + uint8_t value) +{ + struct wlan_mlme_psoc_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_obj(psoc); + if (!mlme_obj) { + mlme_err("Failed to get MLME Obj"); + return QDF_STATUS_E_FAILURE; + } + + if (!cfg_in_range(CFG_MPDU_DENSITY, value)) { + mlme_err("Invalid value %d", value); + return QDF_STATUS_E_INVAL; + } + + mlme_obj->cfg.ht_caps.ampdu_params.mpdu_density = value; + + return QDF_STATUS_SUCCESS; +} + QDF_STATUS wlan_mlme_get_band_capability(struct wlan_objmgr_psoc *psoc, uint8_t *band_capability) {