WiFi-HAL: Add support to configure thermal level am: fc600dab60

Change-Id: I54e3d6387ef8750175c1d08260dae1a2f2e8d5a2
diff --git a/qcwcn/wifi_hal/wifi_hal.cpp b/qcwcn/wifi_hal/wifi_hal.cpp
index 4199cef..86275de 100644
--- a/qcwcn/wifi_hal/wifi_hal.cpp
+++ b/qcwcn/wifi_hal/wifi_hal.cpp
@@ -572,6 +572,7 @@
     fn->wifi_reset_tx_power_scenario = wifi_reset_tx_power_scenario;
     fn->wifi_set_radio_mode_change_handler = wifi_set_radio_mode_change_handler;
     fn->wifi_set_latency_mode = wifi_set_latency_mode;
+    fn->wifi_set_thermal_mitigation_mode = wifi_set_thermal_mitigation_mode;
 
     return WIFI_SUCCESS;
 }
diff --git a/qcwcn/wifi_hal/wificonfig.cpp b/qcwcn/wifi_hal/wificonfig.cpp
index 169e7d4..1bf71c6 100644
--- a/qcwcn/wifi_hal/wificonfig.cpp
+++ b/qcwcn/wifi_hal/wificonfig.cpp
@@ -546,6 +546,105 @@
     return ret;
 }
 
+wifi_error wifi_set_thermal_mitigation_mode(wifi_handle handle,
+                                            wifi_thermal_mode mode,
+                                            u32 completion_window)
+{
+    wifi_error ret;
+    WiFiConfigCommand *wifiConfigCommand;
+    struct nlattr *nlData;
+    u32 qca_vendor_thermal_level;
+
+    wifiConfigCommand = new WiFiConfigCommand(
+                            handle,
+                            1,
+                            OUI_QCA,
+                            QCA_NL80211_VENDOR_SUBCMD_THERMAL_CMD);
+    if (wifiConfigCommand == NULL) {
+        ALOGE("%s: Error, Failed to create wifiConfigCommand", __FUNCTION__);
+        return WIFI_ERROR_UNKNOWN;
+    }
+
+    /* Create the NL message. */
+    ret = wifiConfigCommand->create();
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("Failed to create thermal vendor command, Error:%d", ret);
+        goto cleanup;
+    }
+
+    /* Set the interface Id of the message. */
+    ret = wifiConfigCommand->set_iface_id("wlan0");
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("%s: failed to set iface id. Error:%d",
+            __FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    nlData = wifiConfigCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
+    if (!nlData) {
+        ALOGE("%s: Failed in attr_start for VENDOR_DATA, Error:%d",
+              __FUNCTION__, ret);
+        goto cleanup;
+    }
+
+    if (wifiConfigCommand->put_u32(QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_VALUE,
+                             QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_SET_LEVEL)) {
+        ALOGE("Failed to put THERMAL_LEVEL command type");
+        goto cleanup;
+    }
+
+    switch(mode) {
+        case WIFI_MITIGATION_NONE:
+            qca_vendor_thermal_level = QCA_WLAN_VENDOR_THERMAL_LEVEL_NONE;
+            break;
+        case WIFI_MITIGATION_LIGHT:
+            qca_vendor_thermal_level = QCA_WLAN_VENDOR_THERMAL_LEVEL_LIGHT;
+            break;
+        case WIFI_MITIGATION_MODERATE:
+            qca_vendor_thermal_level = QCA_WLAN_VENDOR_THERMAL_LEVEL_MODERATE;
+            break;
+        case WIFI_MITIGATION_SEVERE:
+            qca_vendor_thermal_level = QCA_WLAN_VENDOR_THERMAL_LEVEL_SEVERE;
+            break;
+        case WIFI_MITIGATION_CRITICAL:
+            qca_vendor_thermal_level = QCA_WLAN_VENDOR_THERMAL_LEVEL_CRITICAL;
+            break;
+        case WIFI_MITIGATION_EMERGENCY:
+            qca_vendor_thermal_level = QCA_WLAN_VENDOR_THERMAL_LEVEL_EMERGENCY;
+            break;
+        default:
+            ALOGE("Unknown thermal mitigation level %d", mode);
+            ret = WIFI_ERROR_UNKNOWN;
+            goto cleanup;
+    }
+
+    if (wifiConfigCommand->put_u32(
+                             QCA_WLAN_VENDOR_ATTR_THERMAL_LEVEL,
+                             qca_vendor_thermal_level)) {
+        ALOGE("Failed to put thermal level");
+        goto cleanup;
+    }
+
+    if (wifiConfigCommand->put_u32(
+                             QCA_WLAN_VENDOR_ATTR_THERMAL_COMPLETION_WINDOW,
+                             completion_window)) {
+        ALOGE("Failed to put thermal completion window");
+        goto cleanup;
+    }
+    wifiConfigCommand->attr_end(nlData);
+
+    wifiConfigCommand->waitForRsp(false);
+    ret = wifiConfigCommand->requestEvent();
+    if (ret != WIFI_SUCCESS) {
+        ALOGE("Failed to set thermal level with Error: %d", ret);
+        goto cleanup;
+    }
+
+cleanup:
+    delete wifiConfigCommand;
+    return ret;
+}
+
 WiFiConfigCommand::WiFiConfigCommand(wifi_handle handle,
                                      int id, u32 vendor_id,
                                      u32 subcmd)