summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSubhani Shaik <subhanis@codeaurora.org>2017-06-30 16:50:50 +0530
committerRoshan Pius <rpius@google.com>2017-07-11 07:37:46 -0700
commit1906cf3d2905098937bba98222aa1a525452d391 (patch)
treea0c9f4ff60515f17f662d2fc25f19c1cb8cfa097
parent3b95b19e19743b7c2c055b10dfa9ffe5f089f90f (diff)
downloadandroid_hardware_qcom_wlan-1906cf3d2905098937bba98222aa1a525452d391.tar.gz
android_hardware_qcom_wlan-1906cf3d2905098937bba98222aa1a525452d391.tar.bz2
android_hardware_qcom_wlan-1906cf3d2905098937bba98222aa1a525452d391.zip
WiFi-HAL: Support to set tx_power_limits
Framework sends tx power limits to wifihal. Forward the same to WLAN driver with the help of nl80211 vendor command. Bug: 62437848 Test: Compiles Change-Id: I3073b98bacec33dc5ec544b8405330e820ed8bec (cherry-picked from 4735b5927aeb8ef7a4fa18a6f694be86478d3beb)
-rw-r--r--qcwcn/wifi_hal/wifi_hal.cpp2
-rw-r--r--qcwcn/wifi_hal/wificonfig.cpp140
2 files changed, 142 insertions, 0 deletions
diff --git a/qcwcn/wifi_hal/wifi_hal.cpp b/qcwcn/wifi_hal/wifi_hal.cpp
index 822d6bc..229a971 100644
--- a/qcwcn/wifi_hal/wifi_hal.cpp
+++ b/qcwcn/wifi_hal/wifi_hal.cpp
@@ -408,6 +408,8 @@ wifi_error init_wifi_vendor_hal_func_table(wifi_hal_fn *fn) {
fn->wifi_get_roaming_capabilities = wifi_get_roaming_capabilities;
fn->wifi_configure_roaming = wifi_configure_roaming;
fn->wifi_enable_firmware_roaming = wifi_enable_firmware_roaming;
+ fn->wifi_set_tx_power_limit = wifi_set_tx_power_limit;
+ fn->wifi_reset_tx_power_limit = wifi_reset_tx_power_limit;
return WIFI_SUCCESS;
}
diff --git a/qcwcn/wifi_hal/wificonfig.cpp b/qcwcn/wifi_hal/wificonfig.cpp
index 8a09488..c9d2ed8 100644
--- a/qcwcn/wifi_hal/wificonfig.cpp
+++ b/qcwcn/wifi_hal/wificonfig.cpp
@@ -286,6 +286,146 @@ cleanup:
return (wifi_error)ret;
}
+wifi_error wifi_set_tx_power_limit(wifi_interface_handle handle,
+ u32 tx_level_dbm)
+{
+ int ret = 0;
+ WiFiConfigCommand *wifiConfigCommand;
+ struct nlattr *nlData, *nlLimitSpec;
+ interface_info *ifaceInfo = getIfaceInfo(handle);
+ wifi_handle wifiHandle = getWifiHandle(handle);
+ u32 numSpecs = 1, j;
+
+ ALOGV("%s : tx power limit:%u", __FUNCTION__, tx_level_dbm);
+
+ wifiConfigCommand = new WiFiConfigCommand(
+ wifiHandle,
+ 1,
+ OUI_QCA,
+ QCA_NL80211_VENDOR_SUBCMD_SET_SAR_LIMITS);
+ if (wifiConfigCommand == NULL) {
+ ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__);
+ return WIFI_ERROR_UNKNOWN;
+ }
+
+ /* Create the NL message. */
+ ret = wifiConfigCommand->create();
+ if (ret < 0) {
+ ALOGE("wifi_set_tx_power_limit: failed to create NL msg. Error:%d", ret);
+ goto cleanup;
+ }
+
+ /* Set the interface Id of the message. */
+ ret = wifiConfigCommand->set_iface_id(ifaceInfo->name);
+ if (ret < 0) {
+ ALOGE("wifi_set_tx_power_limit: failed to set iface id. Error:%d", ret);
+ goto cleanup;
+ }
+
+ /* Add the vendor specific attributes for the NL command. */
+ nlData = wifiConfigCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+ if (!nlData) {
+ ALOGE("wifi_set_tx_power_limit: failed attr_start for VENDOR_DATA. "
+ "Error:%d", ret);
+ goto cleanup;
+ }
+
+ if (wifiConfigCommand->put_u32(
+ QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SAR_ENABLE,
+ QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_USER) ||
+ wifiConfigCommand->put_u32(
+ QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_NUM_SPECS, numSpecs)) {
+ ALOGE("failed to put SAR_ENABLE or NUM_SPECS");
+ goto cleanup;
+ }
+
+ nlLimitSpec =
+ wifiConfigCommand->attr_start(QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC);
+
+ /* Add NL attributes for SAR limit specs . */
+ for (j = 0; j < numSpecs; j++) {
+ struct nlattr *nl_sarSpec = wifiConfigCommand->attr_start(j);
+
+ if (wifiConfigCommand->put_u32(
+ QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_POWER_LIMIT, tx_level_dbm)) {
+ ALOGE("wifi_set_tx_power_limit: failed to add vendor data.");
+ goto cleanup;
+ }
+
+ wifiConfigCommand->attr_end(nl_sarSpec);
+ }
+ wifiConfigCommand->attr_end(nlLimitSpec);
+ wifiConfigCommand->attr_end(nlData);
+
+ ret = wifiConfigCommand->requestEvent();
+ if (ret != 0) {
+ ALOGE("wifi_set_tx_power_limit(): requestEvent Error:%d", ret);
+ goto cleanup;
+ }
+
+cleanup:
+ delete wifiConfigCommand;
+ return (wifi_error)ret;
+}
+
+wifi_error wifi_reset_tx_power_limit(wifi_interface_handle handle)
+{
+ int ret = 0;
+ WiFiConfigCommand *wifiConfigCommand;
+ struct nlattr *nlData;
+ interface_info *ifaceInfo = getIfaceInfo(handle);
+ wifi_handle wifiHandle = getWifiHandle(handle);
+
+ wifiConfigCommand = new WiFiConfigCommand(
+ wifiHandle,
+ 1,
+ OUI_QCA,
+ QCA_NL80211_VENDOR_SUBCMD_SET_SAR_LIMITS);
+ if (wifiConfigCommand == NULL) {
+ ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__);
+ return WIFI_ERROR_UNKNOWN;
+ }
+
+ /* Create the NL message. */
+ ret = wifiConfigCommand->create();
+ if (ret < 0) {
+ ALOGE("wifi_set_tx_power_limit: failed to create NL msg. Error:%d", ret);
+ goto cleanup;
+ }
+
+ /* Set the interface Id of the message. */
+ ret = wifiConfigCommand->set_iface_id(ifaceInfo->name);
+ if (ret < 0) {
+ ALOGE("wifi_set_tx_power_limit: failed to set iface id. Error:%d", ret);
+ goto cleanup;
+ }
+
+ /* Add the vendor specific attributes for the NL command. */
+ nlData = wifiConfigCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+ if (!nlData) {
+ ALOGE("wifi_set_tx_power_limit: failed attr_start for VENDOR_DATA. "
+ "Error:%d", ret);
+ goto cleanup;
+ }
+
+ if (wifiConfigCommand->put_u32(QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SAR_ENABLE,
+ QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_NONE)) {
+ ALOGE("failed to put SAR_ENABLE or NUM_SPECS");
+ goto cleanup;
+ }
+ wifiConfigCommand->attr_end(nlData);
+
+ ret = wifiConfigCommand->requestEvent();
+ if (ret != 0) {
+ ALOGE("wifi_set_tx_power_limit(): requestEvent Error:%d", ret);
+ goto cleanup;
+ }
+
+cleanup:
+ delete wifiConfigCommand;
+ return (wifi_error)ret;
+}
+
WiFiConfigCommand::WiFiConfigCommand(wifi_handle handle,
int id, u32 vendor_id,
u32 subcmd)