macloader: Add support to set nvram calibration file.
authorAndreas Schneider <asn@cryptomilk.org>
Mon, 26 Jan 2015 21:56:30 +0000 (22:56 +0100)
committerNir Bruderman <nbruderman@gmail.com>
Mon, 16 Feb 2015 21:59:25 +0000 (21:59 +0000)
Change-Id: I0eb99ad6084eb8cd4452a91b13dd75384785f5a8
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit e283a09f99d0cbad2cf8b903ffe2da1c3e44663e)

macloader/Android.mk
macloader/macloader.c

index 722325fac1cc913b7a67954b69f55dd26093cdba..ee843becbc51bd534a815d9a6204d1459b3efe73 100644 (file)
@@ -3,6 +3,14 @@ ifeq ($(BOARD_HAVE_SAMSUNG_WIFI),true)
 LOCAL_PATH := $(call my-dir)
 include $(CLEAR_VARS)
 
+ifdef WIFI_DRIVER_NVRAM_PATH
+LOCAL_CFLAGS += -DWIFI_DRIVER_NVRAM_PATH=\"$(WIFI_DRIVER_NVRAM_PATH)\"
+endif
+
+ifdef WIFI_DRIVER_NVRAM_PATH_PARAM
+LOCAL_CFLAGS += -DWIFI_DRIVER_NVRAM_PATH_PARAM=\"$(WIFI_DRIVER_NVRAM_PATH_PARAM)\"
+endif
+
 LOCAL_SRC_FILES := \
     macloader.c
 
index 0e29e28038ab942caaf02f57433b29703f4231d2..a71afb0569dbbb79e0e8f693da4ba38dd4b1bf25 100644 (file)
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/types.h>
 #include <sys/stat.h>
+#include <fcntl.h>
 #include <unistd.h>
 #include <pwd.h>
 
 #include <cutils/log.h>
 
+#ifndef WIFI_DRIVER_NVRAM_PATH
+#define WIFI_DRIVER_NVRAM_PATH         NULL
+#endif
+
+#ifndef WIFI_DRIVER_NVRAM_PATH_PARAM
+#define WIFI_DRIVER_NVRAM_PATH_PARAM "/sys/module/wlan/parameters/nvram_path"
+#endif
+
 #define MACADDR_PATH "/efs/wifi/.mac.info"
 #define CID_PATH "/data/.cid.info"
 
@@ -41,6 +51,82 @@ enum Type {
     WISOL
 };
 
+static int wifi_change_nvram_calibration(const char *nvram_file,
+                                         const char *type)
+{
+    int len;
+    int fd = -1;
+    int ret = 0;
+    struct stat sb;
+    char nvram_str[1024] = { 0 };
+
+    if (nvram_file == NULL || type == NULL) {
+        return -1;
+    }
+
+    ret = stat(nvram_file, &sb);
+    if (ret != 0) {
+        ALOGE("Failed to check for NVRAM calibration file '%s' - error: %s",
+              nvram_file,
+              strerror(errno));
+        return -1;
+    }
+
+    ALOGD("Using NVRAM calibration file: %s\n", nvram_file);
+
+    fd = TEMP_FAILURE_RETRY(open(WIFI_DRIVER_NVRAM_PATH_PARAM, O_WRONLY));
+    if (fd < 0) {
+        ALOGE("Failed to open wifi nvram config path %s - error: %s",
+              WIFI_DRIVER_NVRAM_PATH_PARAM, strerror(errno));
+        return -1;
+    }
+
+    len = strlen(nvram_file) + 1;
+    if (TEMP_FAILURE_RETRY(write(fd, nvram_file, len)) != len) {
+        ALOGE("Failed to write to wifi config path %s - error: %s",
+              WIFI_DRIVER_NVRAM_PATH_PARAM, strerror(errno));
+        ret = -1;
+        goto out;
+    }
+
+    snprintf(nvram_str, sizeof(nvram_str), "%s_%s",
+             nvram_file, type);
+
+    ALOGD("Changing NVRAM calibration file for %s chipset\n", type);
+
+    ret = stat(nvram_str, &sb);
+    if (ret != 0) {
+        ALOGW("NVRAM calibration file '%s' doesn't exist", nvram_str);
+        /*
+         * We were able to write the default calibration file. So
+         * continue here without returning an error.
+         */
+        ret = 0;
+        goto out;
+    }
+
+    len = strlen(nvram_str) + 1;
+    if (TEMP_FAILURE_RETRY(write(fd, nvram_str, len)) != len) {
+        ALOGW("Failed to write to wifi config path %s - error: %s",
+              WIFI_DRIVER_NVRAM_PATH_PARAM, strerror(errno));
+        /*
+         * We were able to write the default calibration file. So
+         * continue here without returning an error.
+         */
+        ret = 0;
+        goto out;
+    }
+
+    ALOGD("NVRAM calibration file set to '%s'\n", nvram_str);
+
+    ret = 0;
+out:
+    if (fd != -1) {
+        close(fd);
+    }
+    return ret;
+}
+
 int main() {
     FILE* file;
     FILE* cidfile;
@@ -120,6 +206,7 @@ int main() {
     }
 
     if (type != NONE) {
+        const char *nvram_file;
         const char *type_str;
         struct passwd *pwd;
         int fd;
@@ -191,6 +278,14 @@ int main() {
                   CID_PATH, strerror(errno));
             return 1;
         }
+
+        nvram_file = WIFI_DRIVER_NVRAM_PATH;
+        if (nvram_file != NULL) {
+            ret = wifi_change_nvram_calibration(nvram_file, type_str);
+            if (ret != 0) {
+                return 1;
+            }
+        }
     } else {
         /* delete cid file if no specific type */
         ALOGD("Deleting file %s\n", CID_PATH);