diff options
| author | Kabilan Kannan <kabilank@codeaurora.org> | 2016-12-02 18:49:38 -0800 |
|---|---|---|
| committer | qcabuildsw <qcabuildsw@localhost> | 2016-12-16 16:08:03 -0800 |
| commit | fac8ed2ccc96fc69aff225f8f7a2bd20a0db9dfc (patch) | |
| tree | c39e8a09c8068261fb6511913d85364eebfc214c | |
| parent | adc3b1872a97d0832be2f55bcfa2efe13c301884 (diff) | |
qcacld-3.0: Add SAR power limit configuration
There is a regulatory requirement for Specific Absorption
Rate (SAR) whereby the phone transmit power is reduced
when it is determined that the phone is in close
proximity to the body.
Implement a vendor command interface to set SAR power
limits dynamically.
Change-Id: I137ce9bde2fa05e363d5af17e155dc739d862c5f
CRs-Fixed: 1098102
| -rw-r--r-- | core/hdd/src/wlan_hdd_cfg80211.c | 279 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_cfg80211.h | 125 | ||||
| -rw-r--r-- | core/sme/inc/sme_api.h | 10 | ||||
| -rw-r--r-- | core/sme/src/common/sme_api.c | 15 | ||||
| -rw-r--r-- | core/wma/inc/wma_api.h | 12 | ||||
| -rw-r--r-- | core/wma/src/wma_features.c | 24 |
6 files changed, 462 insertions, 3 deletions
diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index f995def1716e..2228dba875fe 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -7932,6 +7932,276 @@ static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy, return ret; } +/** + * wlan_hdd_cfg80211_sar_convert_limit_set() - Convert limit set value + * @nl80211_value: Vendor command attribute value + * @wmi_value: Pointer to return converted WMI return value + * + * Convert NL80211 vendor command value for SAR limit set to WMI value + * Return: 0 on success, -1 on invalid value + */ +static int wlan_hdd_cfg80211_sar_convert_limit_set(u32 nl80211_value, + u32 *wmi_value) +{ + int ret = 0; + + switch (nl80211_value) { + case QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_NONE: + *wmi_value = WMI_SAR_FEATURE_OFF; + break; + case QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF0: + *wmi_value = WMI_SAR_FEATURE_ON_SET_0; + break; + case QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF1: + *wmi_value = WMI_SAR_FEATURE_ON_SET_1; + break; + case QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF2: + *wmi_value = WMI_SAR_FEATURE_ON_SET_2; + break; + case QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF3: + *wmi_value = WMI_SAR_FEATURE_ON_SET_3; + break; + case QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF4: + *wmi_value = WMI_SAR_FEATURE_ON_SET_4; + break; + case QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_USER: + *wmi_value = WMI_SAR_FEATURE_ON_USER_DEFINED; + break; + default: + ret = -1; + } + return ret; +} + +/** + * wlan_hdd_cfg80211_sar_convert_band() - Convert WLAN band value + * @nl80211_value: Vendor command attribute value + * @wmi_value: Pointer to return converted WMI return value + * + * Convert NL80211 vendor command value for SAR BAND to WMI value + * Return: 0 on success, -1 on invalid value + */ +static int wlan_hdd_cfg80211_sar_convert_band(u32 nl80211_value, u32 *wmi_value) +{ + int ret = 0; + + switch (nl80211_value) { + case NL80211_BAND_2GHZ: + *wmi_value = WMI_SAR_2G_ID; + break; + case NL80211_BAND_5GHZ: + *wmi_value = WMI_SAR_5G_ID; + break; + default: + ret = -1; + } + return ret; +} + +/** + * wlan_hdd_cfg80211_sar_convert_modulation() - Convert WLAN modulation value + * @nl80211_value: Vendor command attribute value + * @wmi_value: Pointer to return converted WMI return value + * + * Convert NL80211 vendor command value for SAR Modulation to WMI value + * Return: 0 on success, -1 on invalid value + */ +static int wlan_hdd_cfg80211_sar_convert_modulation(u32 nl80211_value, + u32 *wmi_value) +{ + int ret = 0; + + switch (nl80211_value) { + case QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_MODULATION_CCK: + *wmi_value = WMI_SAR_MOD_CCK; + break; + case QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_MODULATION_OFDM: + *wmi_value = WMI_SAR_MOD_OFDM; + break; + default: + ret = -1; + } + return ret; +} + + +/** + * __wlan_hdd_set_sar_power_limits() - Set SAR power limits + * @wiphy: Pointer to wireless phy + * @wdev: Pointer to wireless device + * @data: Pointer to data + * @data_len: Length of @data + * + * This function is used to setup Specific Absorption Rate limit specs. + * + * Return: 0 on success, negative errno on failure + */ +static int __wlan_hdd_set_sar_power_limits(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len) +{ + hdd_context_t *hdd_ctx = wiphy_priv(wiphy); + struct nlattr *sar_spec[QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_MAX + 1], + *tb[QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_MAX + 1], + *sar_spec_list; + struct sar_limit_cmd_params sar_limit_cmd = {0}; + int ret = -EINVAL, i = 0, rem = 0; + + ENTER(); + + if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { + hdd_err("Command not allowed in FTM mode"); + return -EPERM; + } + + if (wlan_hdd_validate_context(hdd_ctx)) + return -EINVAL; + + if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_MAX, + data, data_len, NULL)) { + hdd_err("Invalid SAR attributes"); + return -EINVAL; + } + + /* Vendor command manadates all SAR Specs in single call */ + sar_limit_cmd.commit_limits = 1; + sar_limit_cmd.sar_enable = WMI_SAR_FEATURE_NO_CHANGE; + if (tb[QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SAR_ENABLE]) { + if (wlan_hdd_cfg80211_sar_convert_limit_set(nla_get_u32( + tb[QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SAR_ENABLE]), + &sar_limit_cmd.sar_enable) < 0) { + hdd_err("Invalid SAR Enable attr"); + goto fail; + } + } + hdd_info("attr sar sar_enable %d", sar_limit_cmd.sar_enable); + + if (tb[QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_NUM_SPECS]) { + sar_limit_cmd.num_limit_rows = nla_get_u32( + tb[QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_NUM_SPECS]); + hdd_info("attr sar num_limit_rows %d", + sar_limit_cmd.num_limit_rows); + } + if (sar_limit_cmd.num_limit_rows > MAX_SAR_LIMIT_ROWS_SUPPORTED) { + hdd_err("SAR Spec list exceed supported size"); + goto fail; + } + if (sar_limit_cmd.num_limit_rows == 0) + goto send_sar_limits; + sar_limit_cmd.sar_limit_row_list = qdf_mem_malloc(sizeof( + struct sar_limit_cmd_row) * + sar_limit_cmd.num_limit_rows); + if (!sar_limit_cmd.sar_limit_row_list) { + ret = -ENOMEM; + goto fail; + } + if (!tb[QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC]) { + hdd_err("Invalid SAR SPECs list"); + goto fail; + } + + nla_for_each_nested(sar_spec_list, + tb[QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC], rem) { + if (i == sar_limit_cmd.num_limit_rows) { + hdd_warn("SAR Cmd has excess SPECs in list"); + break; + } + + if (nla_parse(sar_spec, QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_MAX, + nla_data(sar_spec_list), nla_len(sar_spec_list), + NULL)) { + hdd_err("nla_parse failed for SAR Spec list"); + goto fail; + } + sar_limit_cmd.sar_limit_row_list[i].validity_bitmap = 0; + if (sar_spec[ + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_POWER_LIMIT]) { + sar_limit_cmd.sar_limit_row_list[i].limit_value = + nla_get_u32(sar_spec[ + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_POWER_LIMIT]); + } else { + hdd_err("SAR Spec does not have power limit value"); + goto fail; + } + + if (sar_spec[QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_BAND]) { + if (wlan_hdd_cfg80211_sar_convert_band(nla_get_u32( + sar_spec[QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_BAND]), + &sar_limit_cmd.sar_limit_row_list[i].band_id) + < 0) { + hdd_err("Invalid SAR Band attr"); + goto fail; + } + sar_limit_cmd.sar_limit_row_list[i].validity_bitmap |= + WMI_SAR_BAND_ID_VALID_MASK; + } + if (sar_spec[QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_CHAIN]) { + sar_limit_cmd.sar_limit_row_list[i].chain_id = + nla_get_u32(sar_spec[ + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_CHAIN]); + sar_limit_cmd.sar_limit_row_list[i].validity_bitmap |= + WMI_SAR_CHAIN_ID_VALID_MASK; + } + if (sar_spec[QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_MODULATION]) { + if (wlan_hdd_cfg80211_sar_convert_modulation(nla_get_u32( + sar_spec[QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_MODULATION]), + &sar_limit_cmd.sar_limit_row_list[i].mod_id) + < 0) { + hdd_err("Invalid SAR Modulation attr"); + goto fail; + } + sar_limit_cmd.sar_limit_row_list[i].validity_bitmap |= + WMI_SAR_MOD_ID_VALID_MASK; + } + hdd_info("Spec_ID: %d, Band: %d Chain: %d Mod: %d POW_Limit: %d Validity_Bitmap: %d", + i, sar_limit_cmd.sar_limit_row_list[i].band_id, + sar_limit_cmd.sar_limit_row_list[i].chain_id, + sar_limit_cmd.sar_limit_row_list[i].mod_id, + sar_limit_cmd.sar_limit_row_list[i].limit_value, + sar_limit_cmd.sar_limit_row_list[i].validity_bitmap); + i++; + } + + if (i < sar_limit_cmd.num_limit_rows) { + hdd_warn("SAR Cmd has less SPECs in list"); + sar_limit_cmd.num_limit_rows = i; + } + +send_sar_limits: + if (sme_set_sar_power_limits(hdd_ctx->hHal, &sar_limit_cmd) == + QDF_STATUS_SUCCESS) + ret = 0; +fail: + qdf_mem_free(sar_limit_cmd.sar_limit_row_list); + return ret; +} + +/** + * wlan_hdd_cfg80211_set_sar_power_limits() - Set SAR power limits + * @wiphy: Pointer to wireless phy + * @wdev: Pointer to wireless device + * @data: Pointer to data + * @data_len: Length of @data + * + * Wrapper function of __wlan_hdd_cfg80211_set_sar_power_limits() + * + * Return: 0 on success, negative errno on failure + */ +static int wlan_hdd_cfg80211_set_sar_power_limits(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + int ret; + + cds_ssr_protect(__func__); + ret = __wlan_hdd_set_sar_power_limits(wiphy, wdev, data, + data_len); + cds_ssr_unprotect(__func__); + + return ret; +} + static const struct nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] = { [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = {.type = NLA_U32}, @@ -8647,8 +8917,15 @@ const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] = { WIPHY_VENDOR_CMD_NEED_NETDEV | WIPHY_VENDOR_CMD_NEED_RUNNING, .doit = wlan_hdd_cfg80211_configure_tdls_mode - } + }, #endif + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_SAR_LIMITS, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = wlan_hdd_cfg80211_set_sar_power_limits + }, }; /** diff --git a/core/hdd/src/wlan_hdd_cfg80211.h b/core/hdd/src/wlan_hdd_cfg80211.h index a85133831842..b02a32527232 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.h +++ b/core/hdd/src/wlan_hdd_cfg80211.h @@ -298,6 +298,10 @@ typedef enum { * @QCA_NL80211_VENDOR_SUBCMD_CONFIGURE_TDLS: Configure the TDLS behavior * in the host driver. The different TDLS configurations are defined * by the attributes in enum qca_wlan_vendor_attr_tdls_configuration. + * @QCA_NL80211_VENDOR_SUBCMD_SET_SAR_LIMITS:Set the Specific Absorption Rate + * (SAR) power limits. A critical regulation for FCC compliance, OEMs + * require methods to set SAR limits on TX power of WLAN/WWAN. + * enum qca_vendor_attr_sar_limits attributes are used with this command. */ enum qca_nl80211_vendor_subcmds { @@ -444,6 +448,9 @@ enum qca_nl80211_vendor_subcmds { /* Configure the TDLS mode from user space */ QCA_NL80211_VENDOR_SUBCMD_CONFIGURE_TDLS = 143, + + /* Set Specific Absorption Rate(SAR) Power Limits */ + QCA_NL80211_VENDOR_SUBCMD_SET_SAR_LIMITS = 146, }; /** @@ -3148,6 +3155,124 @@ enum qca_wlan_vendor_tdls_trigger_mode { QCA_WLAN_VENDOR_TDLS_TRIGGER_MODE_EXTERNAL = 1 << 2, }; +/** + * enum qca_vendor_attr_sar_limits_selections - Source of SAR power limits + * @QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF0: Select SAR profile #0 + * that is hard-coded in the Board Data File (BDF). + * @QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF1: Select SAR profile #1 + * that is hard-coded in the Board Data File (BDF). + * @QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF2: Select SAR profile #2 + * that is hard-coded in the Board Data File (BDF). + * @QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF3: Select SAR profile #3 + * that is hard-coded in the Board Data File (BDF). + * @QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF4: Select SAR profile #4 + * that is hard-coded in the Board Data File (BDF). + * @QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_NONE: Do not select any + * source of SAR power limits, thereby disabling the SAR power + * limit feature. + * @QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_USER: Select the SAR power + * limits configured by %QCA_NL80211_VENDOR_SUBCMD_SET_SAR. + * + * This enumerates the valid set of values that may be supplied for + * attribute %QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT in an instance of + * the %QCA_NL80211_VENDOR_SUBCMD_SET_SAR_LIMITS vendor command. + */ +enum qca_vendor_attr_sar_limits_selections { + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF0 = 0, + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF1 = 1, + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF2 = 2, + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF3 = 3, + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF4 = 4, + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_NONE = 5, + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_USER = 6, +}; + +/** + * enum qca_vendor_attr_sar_limits_spec_modulations - + * SAR limits specification modulation + * @QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_MODULATION_CCK - + * CCK modulation + * @QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_MODULATION_OFDM - + * OFDM modulation + * + * This enumerates the valid set of values that may be supplied for + * attribute %QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_MODULATION in an + * instance of attribute %QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC in an + * instance of the %QCA_NL80211_VENDOR_SUBCMD_SET_SAR_LIMITS vendor + * command. + */ +enum qca_vendor_attr_sar_limits_spec_modulations { + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_MODULATION_CCK = 0, + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_MODULATION_OFDM = 1, +}; + +/** + * enum qca_vendor_attr_sar_limits - Attributes for SAR power limits + * + * @QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SAR_ENABLE: Optional (u32) value to + * select which SAR power limit table should be used. Valid + * values are enumerated in enum + * %qca_vendor_attr_sar_limits_selections. The existing SAR + * power limit selection is unchanged if this attribute is not + * present. + * + * @QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_NUM_SPECS: Optional (u32) value + * which specifies the number of SAR power limit specifications + * which will follow. + * + * @QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC: Nested array of SAR power + * limit specifications. The number of specifications is + * specified by @QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_NUM_SPECS. Each + * specification contains a set of + * QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_* attributes. A + * specification is uniquely identified by the attributes + * %QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_BAND, + * %QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_CHAIN, and + * %QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_MODULATION and always + * contains as a payload the attribute + * %QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_POWER_LIMIT. + * + * @QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_BAND: Optional (u32) value to + * indicate for which band this specification applies. Valid + * values are enumerated in enum %nl80211_band (although not all + * bands may be supported by a given device). If the attribute is + * not supplied then the specification will be applied to all + * supported bands. + * + * @QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_CHAIN: Optional (u32) value + * to indicate for which antenna chain this specification + * applies, i.e. 1 for chain 1, 2 for chain 2, etc. If the + * attribute is not supplied then the specification will be + * applied to all chains. + * + * @QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_MODULATION: Optional (u32) + * value to indicate for which modulation scheme this + * specification applies. Valid values are enumerated in enum + * %qca_vendor_attr_sar_limits_spec_modulations. If the attribute + * is not supplied then the specification will be applied to all + * modulation schemes. + * + * @QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_POWER_LIMIT: Required (u32) + * value to specify the actual power limit value in steps of 0.5 + * dbm. + * + * These attributes are used with %QCA_NL80211_VENDOR_SUBCMD_SET_SAR_LIMITS. + */ +enum qca_vendor_attr_sar_limits { + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SAR_ENABLE = 1, + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_NUM_SPECS = 2, + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC = 3, + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_BAND = 4, + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_CHAIN = 5, + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_MODULATION = 6, + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_POWER_LIMIT = 7, + + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_MAX = + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_AFTER_LAST - 1 +}; + struct cfg80211_bss *wlan_hdd_cfg80211_update_bss_db(hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo); diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h index 121d5de9e537..1b8bdf4367f0 100644 --- a/core/sme/inc/sme_api.h +++ b/core/sme/inc/sme_api.h @@ -1364,7 +1364,15 @@ QDF_STATUS sme_power_debug_stats_req(tHalHandle hal, void (*callback_fn) (struct power_stats_response *response, void *context), void *power_stats_context); #endif - +/** + * sme_set_sar_power_limits() - set sar limits + * @hal: HAL handle + * @sar_limit_cmd: struct to send sar limit cmd. + * + * Return: QDF_STATUS enumeration. + */ +QDF_STATUS sme_set_sar_power_limits(tHalHandle hal, + struct sar_limit_cmd_params *sar_limit_cmd); void sme_set_cc_src(tHalHandle hal_handle, enum country_src); diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index d746f633bc0f..ae67f667b5de 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -16856,6 +16856,21 @@ QDF_STATUS sme_set_default_scan_ie(tHalHandle hal, uint16_t session_id, return status; } +QDF_STATUS sme_set_sar_power_limits(tHalHandle hal, + struct sar_limit_cmd_params *sar_limit_cmd) +{ + void *wma_handle; + + 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"); + return QDF_STATUS_E_FAILURE; + } + + return wma_set_sar_limit(wma_handle, sar_limit_cmd); +} + #ifdef WLAN_FEATURE_DISA /** * sme_encrypt_decrypt_msg() - handles encrypt/decrypt mesaage diff --git a/core/wma/inc/wma_api.h b/core/wma/inc/wma_api.h index d6ca6d14e875..3b2e17495c35 100644 --- a/core/wma/inc/wma_api.h +++ b/core/wma/inc/wma_api.h @@ -325,7 +325,17 @@ QDF_STATUS wma_set_cts2self_for_p2p_go(void *wma_handle, uint32_t cts2self_for_p2p_go); QDF_STATUS wma_set_tx_rx_aggregation_size (struct sir_set_tx_rx_aggregation_size *tx_rx_aggregation_size); - +/** + * wma_set_sar_limit() - set sar limits in the target + * @handle: wma handle + * @sar_limit_cmd_params: sar limit cmd params + * + * This function sends WMI command to set SAR limits. + * + * Return: QDF_STATUS enumeration + */ +QDF_STATUS wma_set_sar_limit(WMA_HANDLE handle, + struct sar_limit_cmd_params *sar_limit_params); /** * wma_set_qpower_config() - update qpower config in wma * @vdev_id: the Id of the vdev to configure diff --git a/core/wma/src/wma_features.c b/core/wma/src/wma_features.c index 5e63eb4d574a..231e757a4af6 100644 --- a/core/wma/src/wma_features.c +++ b/core/wma/src/wma_features.c @@ -8326,6 +8326,30 @@ QDF_STATUS wma_enable_disable_caevent_ind(tp_wma_handle wma, uint8_t val) return QDF_STATUS_SUCCESS; } +QDF_STATUS wma_set_sar_limit(WMA_HANDLE handle, + struct sar_limit_cmd_params *sar_limit_params) +{ + int ret; + tp_wma_handle wma = (tp_wma_handle) handle; + + if (!wma || !wma->wmi_handle) { + WMA_LOGE("%s: WMA is closed, can not issue set sar limit msg", + __func__); + return QDF_STATUS_E_INVAL; + } + + if (sar_limit_params == NULL) { + WMA_LOGE("%s: set sar limit ptr NULL", + __func__); + return QDF_STATUS_E_INVAL; + } + + ret = wmi_unified_send_sar_limit_cmd(wma->wmi_handle, + sar_limit_params); + + return ret; +} + #ifdef WLAN_FEATURE_DISA /** * wma_encrypt_decrypt_msg() - |
