diff options
Diffstat (limited to 'qcwcn/wifi_hal/wificonfig.cpp')
-rw-r--r-- | qcwcn/wifi_hal/wificonfig.cpp | 117 |
1 files changed, 114 insertions, 3 deletions
diff --git a/qcwcn/wifi_hal/wificonfig.cpp b/qcwcn/wifi_hal/wificonfig.cpp index 9d1fef2..a2f0fb3 100644 --- a/qcwcn/wifi_hal/wificonfig.cpp +++ b/qcwcn/wifi_hal/wificonfig.cpp @@ -84,7 +84,7 @@ wifi_error wifi_extended_dtim_config_set(wifi_request_id id, } ret = wifiConfigCommand->put_u32( - QCA_WLAN_VENDOR_ATTR_WIFI_CONFIG_DYNAMIC_DTIM, extended_dtim); + QCA_WLAN_VENDOR_ATTR_CONFIG_DYNAMIC_DTIM, extended_dtim); if (ret != WIFI_SUCCESS) { ALOGE("wifi_extended_dtim_config_set(): failed to put vendor data. " "Error:%d", ret); @@ -105,6 +105,14 @@ cleanup: return ret; } +int check_feature(enum qca_wlan_vendor_features feature, features_info *info) +{ + size_t idx = feature / 8; + + return (idx < info->flags_len) && + (info->flags[idx] & BIT(feature % 8)); +} + /* Set the country code to driver. */ wifi_error wifi_set_country_code(wifi_interface_handle iface, const char* country_code) @@ -113,6 +121,7 @@ wifi_error wifi_set_country_code(wifi_interface_handle iface, wifi_error ret; WiFiConfigCommand *wifiConfigCommand; wifi_handle wifiHandle = getWifiHandle(iface); + hal_info *info = getHalInfo(wifiHandle); ALOGV("%s: %s", __FUNCTION__, country_code); @@ -144,6 +153,18 @@ wifi_error wifi_set_country_code(wifi_interface_handle iface, goto cleanup; } + if (check_feature(QCA_WLAN_VENDOR_FEATURE_SELF_MANAGED_REGULATORY, + &info->driver_supported_features)) { + ret = wifiConfigCommand->put_u32(NL80211_ATTR_USER_REG_HINT_TYPE, + NL80211_USER_REG_HINT_CELL_BASE); + if (ret != WIFI_SUCCESS) { + ALOGE("wifi_set_country_code: put reg hint type failed. Error:%d", + ret); + goto cleanup; + } + } + + /* Send the NL msg. */ wifiConfigCommand->waitForRsp(false); ret = wifiConfigCommand->requestEvent(); @@ -205,7 +226,7 @@ wifi_error wifi_set_beacon_wifi_iface_stats_averaging_factor( } if (wifiConfigCommand->put_u32( - QCA_WLAN_VENDOR_ATTR_WIFI_CONFIG_STATS_AVG_FACTOR, factor)) { + QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR, factor)) { ALOGE("wifi_set_beacon_wifi_iface_stats_averaging_factor(): failed to " "put vendor data. Error:%d", ret); goto cleanup; @@ -271,7 +292,7 @@ wifi_error wifi_set_guard_time(wifi_request_id id, } if (wifiConfigCommand->put_u32( - QCA_WLAN_VENDOR_ATTR_WIFI_CONFIG_GUARD_TIME, guard_time)) { + QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME, guard_time)) { ALOGE("wifi_set_guard_time: failed to add vendor data."); goto cleanup; } @@ -337,6 +358,7 @@ wifi_error wifi_select_tx_power_scenario(wifi_interface_handle handle, switch (scenario) { case WIFI_POWER_SCENARIO_VOICE_CALL: case WIFI_POWER_SCENARIO_ON_HEAD_CELL_OFF: + case WIFI_POWER_SCENARIO_ON_BODY_BT: bdf_file = QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF0; break; @@ -435,6 +457,95 @@ cleanup: return ret; } +wifi_error wifi_set_latency_mode(wifi_interface_handle handle, + wifi_latency_mode mode) { + wifi_error ret; + WiFiConfigCommand *wifiConfigCommand; + struct nlattr *nlData; + u32 latency_mode; + interface_info *ifaceInfo = getIfaceInfo(handle); + wifi_handle wifiHandle = getWifiHandle(handle); + hal_info *info = getHalInfo(wifiHandle); + + ALOGV("%s : latency mode:%d", __FUNCTION__, mode); + + /* Check Supported low-latency capability */ + if (!(info->supported_feature_set & WIFI_FEATURE_SET_LATENCY_MODE)) { + ALOGE("%s: Set latency mode feature not supported %x", __FUNCTION__, + info->supported_feature_set); + return WIFI_ERROR_NOT_SUPPORTED; + } + + wifiConfigCommand = new WiFiConfigCommand( + wifiHandle, + 1, + OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION); + if (wifiConfigCommand == NULL) { + ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + /* Create the NL message. */ + ret = wifiConfigCommand->create(); + if (ret != WIFI_SUCCESS) { + ALOGE("wifi_set_latency_mode: 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 != WIFI_SUCCESS) { + ALOGE("wifi_set_latency_mode: 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) { + ret = WIFI_ERROR_UNKNOWN; + ALOGE("wifi_set_latency_mode: failed attr_start for VENDOR_DATA. " + "Error:%d", ret); + goto cleanup; + } + + switch(mode) { + case WIFI_LATENCY_MODE_NORMAL: + latency_mode = QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_NORMAL; + break; + + case WIFI_LATENCY_MODE_LOW: + latency_mode = QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_LOW; + break; + + default: + ALOGE("wifi_set_latency_mode: Invalid mode: %d", mode); + ret = WIFI_ERROR_UNKNOWN; + goto cleanup; + } + + if (wifiConfigCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL, + latency_mode)) { + ALOGE("wifi_set_latency_mode: failed to put latency mode"); + ret = WIFI_ERROR_UNKNOWN; + goto cleanup; + } + wifiConfigCommand->attr_end(nlData); + + /* Send the NL msg. */ + wifiConfigCommand->waitForRsp(false); + ret = wifiConfigCommand->requestEvent(); + if (ret != WIFI_SUCCESS) { + ALOGE("wifi_set_latency_mode: requestEvent Error:%d", ret); + goto cleanup; + } + +cleanup: + delete wifiConfigCommand; + return ret; +} + WiFiConfigCommand::WiFiConfigCommand(wifi_handle handle, int id, u32 vendor_id, u32 subcmd) |