summaryrefslogtreecommitdiffstats
path: root/libwifi_hal
diff options
context:
space:
mode:
authorChristopher Wiley <wiley@google.com>2016-06-16 16:31:01 -0700
committerChristopher Wiley <wiley@google.com>2016-06-17 11:50:59 -0700
commita591506fbf1445877fc2f97bca1e00b51ccc3a85 (patch)
treeb06882f46a46c89b8320d6b4e4b5eb89eacbad6c /libwifi_hal
parent6579c9dc1d5ebc056ba7dcc6c23aa25732227124 (diff)
downloadandroid_frameworks_opt_net_wifi-a591506fbf1445877fc2f97bca1e00b51ccc3a85.tar.gz
android_frameworks_opt_net_wifi-a591506fbf1445877fc2f97bca1e00b51ccc3a85.tar.bz2
android_frameworks_opt_net_wifi-a591506fbf1445877fc2f97bca1e00b51ccc3a85.zip
Move device dependent functionality to libwifi-hal
Bug: 29418968 Change-Id: I0fa3047972c57af7128ce6384b62960f6f017d93 Test: wifi works/unittests pass on bullhead
Diffstat (limited to 'libwifi_hal')
-rw-r--r--libwifi_hal/Android.mk61
-rw-r--r--libwifi_hal/include/hardware_legacy/wifi.h64
-rw-r--r--libwifi_hal/wifi_hal_common.cpp240
3 files changed, 357 insertions, 8 deletions
diff --git a/libwifi_hal/Android.mk b/libwifi_hal/Android.mk
index e83c25e47..879ad8711 100644
--- a/libwifi_hal/Android.mk
+++ b/libwifi_hal/Android.mk
@@ -15,12 +15,7 @@
LOCAL_PATH := $(call my-dir)
ifneq ($(TARGET_BUILD_PDK), true)
-# A fallback "vendor" HAL library.
-# Don't link this, link libwifi-hal.
-# ============================================================
-include $(CLEAR_VARS)
-LOCAL_MODULE := libwifi-hal-fallback
-LOCAL_CFLAGS := \
+wifi_hal_cflags := \
-Wall \
-Werror \
-Wextra \
@@ -30,6 +25,53 @@ LOCAL_CFLAGS := \
-Wshadow \
-Wunused-variable \
-Wwrite-strings
+ifdef WIFI_DRIVER_MODULE_PATH
+wifi_hal_cflags += -DWIFI_DRIVER_MODULE_PATH=\"$(WIFI_DRIVER_MODULE_PATH)\"
+endif
+ifdef WIFI_DRIVER_MODULE_ARG
+wifi_hal_cflags += -DWIFI_DRIVER_MODULE_ARG=\"$(WIFI_DRIVER_MODULE_ARG)\"
+endif
+ifdef WIFI_DRIVER_MODULE_NAME
+wifi_hal_cflags += -DWIFI_DRIVER_MODULE_NAME=\"$(WIFI_DRIVER_MODULE_NAME)\"
+endif
+ifdef WIFI_DRIVER_FW_PATH_STA
+wifi_hal_cflags += -DWIFI_DRIVER_FW_PATH_STA=\"$(WIFI_DRIVER_FW_PATH_STA)\"
+endif
+ifdef WIFI_DRIVER_FW_PATH_AP
+wifi_hal_cflags += -DWIFI_DRIVER_FW_PATH_AP=\"$(WIFI_DRIVER_FW_PATH_AP)\"
+endif
+ifdef WIFI_DRIVER_FW_PATH_P2P
+wifi_hal_cflags += -DWIFI_DRIVER_FW_PATH_P2P=\"$(WIFI_DRIVER_FW_PATH_P2P)\"
+endif
+ifdef WIFI_DRIVER_FW_PATH_PARAM
+wifi_hal_cflags += -DWIFI_DRIVER_FW_PATH_PARAM=\"$(WIFI_DRIVER_FW_PATH_PARAM)\"
+endif
+
+ifdef WIFI_DRIVER_STATE_CTRL_PARAM
+wifi_hal_cflags += -DWIFI_DRIVER_STATE_CTRL_PARAM=\"$(WIFI_DRIVER_STATE_CTRL_PARAM)\"
+endif
+ifdef WIFI_DRIVER_STATE_ON
+wifi_hal_cflags += -DWIFI_DRIVER_STATE_ON=\"$(WIFI_DRIVER_STATE_ON)\"
+endif
+ifdef WIFI_DRIVER_STATE_OFF
+wifi_hal_cflags += -DWIFI_DRIVER_STATE_OFF=\"$(WIFI_DRIVER_STATE_OFF)\"
+endif
+
+# Common code shared between the HALs.
+# ============================================================
+include $(CLEAR_VARS)
+LOCAL_MODULE := libwifi-hal-common
+LOCAL_CFLAGS := $(wifi_hal_cflags)
+LOCAL_SRC_FILES := wifi_hal_common.cpp
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
+include $(BUILD_STATIC_LIBRARY)
+
+# A fallback "vendor" HAL library.
+# Don't link this, link libwifi-hal.
+# ============================================================
+include $(CLEAR_VARS)
+LOCAL_MODULE := libwifi-hal-fallback
+LOCAL_CFLAGS := $(wifi_hal_cflags)
LOCAL_SRC_FILES := wifi_hal_fallback.cpp
LOCAL_C_INCLUDES := $(call include-path-for, libhardware_legacy)
include $(BUILD_STATIC_LIBRARY)
@@ -54,12 +96,15 @@ endif
# ============================================================
include $(CLEAR_VARS)
LOCAL_MODULE := libwifi-hal
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(call include-path-for, libhardware_legacy)
+LOCAL_EXPORT_C_INCLUDE_DIRS := \
+ $(LOCAL_PATH)/include \
+ $(call include-path-for, libhardware_legacy)
LOCAL_SHARED_LIBRARIES := \
+ libcutils \
liblog \
libnl \
libutils
-LOCAL_WHOLE_STATIC_LIBRARIES := $(LIB_WIFI_HAL)
+LOCAL_WHOLE_STATIC_LIBRARIES := $(LIB_WIFI_HAL) libwifi-hal-common
include $(BUILD_SHARED_LIBRARY)
endif
diff --git a/libwifi_hal/include/hardware_legacy/wifi.h b/libwifi_hal/include/hardware_legacy/wifi.h
new file mode 100644
index 000000000..defff0a19
--- /dev/null
+++ b/libwifi_hal/include/hardware_legacy/wifi.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef HARDWARE_LEGACY_WIFI_H
+#define HARDWARE_LEGACY_WIFI_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+/**
+ * Load the Wi-Fi driver.
+ *
+ * @return 0 on success, < 0 on failure.
+ */
+int wifi_load_driver();
+
+/**
+ * Unload the Wi-Fi driver.
+ *
+ * @return 0 on success, < 0 on failure.
+ */
+int wifi_unload_driver();
+
+/**
+ * Check if the Wi-Fi driver is loaded.
+ * Check if the Wi-Fi driver is loaded.
+
+ * @return 0 on success, < 0 on failure.
+ */
+int is_wifi_driver_loaded();
+
+/**
+ * Return the path to requested firmware
+ */
+#define WIFI_GET_FW_PATH_STA 0
+#define WIFI_GET_FW_PATH_AP 1
+#define WIFI_GET_FW_PATH_P2P 2
+const char *wifi_get_fw_path(int fw_type);
+
+/**
+ * Change the path to firmware for the wlan driver
+ */
+int wifi_change_fw_path(const char *fwpath);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* HARDWARE_LEGACY_WIFI_H */
diff --git a/libwifi_hal/wifi_hal_common.cpp b/libwifi_hal/wifi_hal_common.cpp
new file mode 100644
index 000000000..54c38e135
--- /dev/null
+++ b/libwifi_hal/wifi_hal_common.cpp
@@ -0,0 +1,240 @@
+/*
+ * Copyright 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "hardware_legacy/wifi.h"
+
+#define LOG_TAG "WifiHalCommon"
+
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <cutils/log.h>
+#include <cutils/misc.h>
+#include <cutils/properties.h>
+
+extern int init_module(void *, unsigned long, const char *);
+extern int delete_module(const char *, unsigned int);
+
+#ifndef WIFI_DRIVER_FW_PATH_STA
+#define WIFI_DRIVER_FW_PATH_STA NULL
+#endif
+#ifndef WIFI_DRIVER_FW_PATH_AP
+#define WIFI_DRIVER_FW_PATH_AP NULL
+#endif
+#ifndef WIFI_DRIVER_FW_PATH_P2P
+#define WIFI_DRIVER_FW_PATH_P2P NULL
+#endif
+#ifndef WIFI_DRIVER_FW_PATH_PARAM
+#define WIFI_DRIVER_FW_PATH_PARAM "/sys/module/wlan/parameters/fwpath"
+#endif
+
+#ifndef WIFI_DRIVER_MODULE_ARG
+#define WIFI_DRIVER_MODULE_ARG ""
+#endif
+
+static const char DRIVER_PROP_NAME[] = "wlan.driver.status";
+#ifdef WIFI_DRIVER_MODULE_PATH
+static const char DRIVER_MODULE_NAME[] = WIFI_DRIVER_MODULE_NAME;
+static const char DRIVER_MODULE_TAG[] = WIFI_DRIVER_MODULE_NAME " ";
+static const char DRIVER_MODULE_PATH[] = WIFI_DRIVER_MODULE_PATH;
+static const char DRIVER_MODULE_ARG[] = WIFI_DRIVER_MODULE_ARG;
+static const char MODULE_FILE[] = "/proc/modules";
+#endif
+
+static int insmod(const char *filename, const char *args)
+{
+ void *module;
+ unsigned int size;
+ int ret;
+
+ module = load_file(filename, &size);
+ if (!module)
+ return -1;
+
+ ret = init_module(module, size, args);
+
+ free(module);
+
+ return ret;
+}
+
+static int rmmod(const char *modname)
+{
+ int ret = -1;
+ int maxtry = 10;
+
+ while (maxtry-- > 0) {
+ ret = delete_module(modname, O_NONBLOCK | O_EXCL);
+ if (ret < 0 && errno == EAGAIN)
+ usleep(500000);
+ else
+ break;
+ }
+
+ if (ret != 0)
+ ALOGD("Unable to unload driver module \"%s\": %s\n",
+ modname, strerror(errno));
+ return ret;
+}
+
+#ifdef WIFI_DRIVER_STATE_CTRL_PARAM
+int wifi_change_driver_state(const char *state)
+{
+ int len;
+ int fd;
+ int ret = 0;
+
+ if (!state)
+ return -1;
+ fd = TEMP_FAILURE_RETRY(open(WIFI_DRIVER_STATE_CTRL_PARAM, O_WRONLY));
+ if (fd < 0) {
+ ALOGE("Failed to open driver state control param (%s)", strerror(errno));
+ return -1;
+ }
+ len = strlen(state) + 1;
+ if (TEMP_FAILURE_RETRY(write(fd, state, len)) != len) {
+ ALOGE("Failed to write driver state control param (%s)", strerror(errno));
+ ret = -1;
+ }
+ close(fd);
+ return ret;
+}
+#endif
+
+int is_wifi_driver_loaded() {
+ char driver_status[PROPERTY_VALUE_MAX];
+#ifdef WIFI_DRIVER_MODULE_PATH
+ FILE *proc;
+ char line[sizeof(DRIVER_MODULE_TAG)+10];
+#endif
+
+ if (!property_get(DRIVER_PROP_NAME, driver_status, NULL)
+ || strcmp(driver_status, "ok") != 0) {
+ return 0; /* driver not loaded */
+ }
+#ifdef WIFI_DRIVER_MODULE_PATH
+ /*
+ * If the property says the driver is loaded, check to
+ * make sure that the property setting isn't just left
+ * over from a previous manual shutdown or a runtime
+ * crash.
+ */
+ if ((proc = fopen(MODULE_FILE, "r")) == NULL) {
+ ALOGW("Could not open %s: %s", MODULE_FILE, strerror(errno));
+ property_set(DRIVER_PROP_NAME, "unloaded");
+ return 0;
+ }
+ while ((fgets(line, sizeof(line), proc)) != NULL) {
+ if (strncmp(line, DRIVER_MODULE_TAG, strlen(DRIVER_MODULE_TAG)) == 0) {
+ fclose(proc);
+ return 1;
+ }
+ }
+ fclose(proc);
+ property_set(DRIVER_PROP_NAME, "unloaded");
+ return 0;
+#else
+ return 1;
+#endif
+}
+
+int wifi_load_driver()
+{
+#ifdef WIFI_DRIVER_MODULE_PATH
+ if (is_wifi_driver_loaded()) {
+ return 0;
+ }
+
+ if (insmod(DRIVER_MODULE_PATH, DRIVER_MODULE_ARG) < 0)
+ return -1;
+
+#elif defined WIFI_DRIVER_STATE_CTRL_PARAM
+ if (is_wifi_driver_loaded()) {
+ return 0;
+ }
+
+ if (wifi_change_driver_state(WIFI_DRIVER_STATE_ON) < 0)
+ return -1;
+#endif
+ property_set(DRIVER_PROP_NAME, "ok");
+ return 0;
+}
+
+int wifi_unload_driver()
+{
+ usleep(200000); /* allow to finish interface down */
+#ifdef WIFI_DRIVER_MODULE_PATH
+ if (rmmod(DRIVER_MODULE_NAME) == 0) {
+ int count = 20; /* wait at most 10 seconds for completion */
+ while (count-- > 0) {
+ if (!is_wifi_driver_loaded())
+ break;
+ usleep(500000);
+ }
+ usleep(500000); /* allow card removal */
+ if (count) {
+ return 0;
+ }
+ return -1;
+ } else
+ return -1;
+#else
+#ifdef WIFI_DRIVER_STATE_CTRL_PARAM
+ if (is_wifi_driver_loaded()) {
+ if (wifi_change_driver_state(WIFI_DRIVER_STATE_OFF) < 0)
+ return -1;
+ }
+#endif
+ property_set(DRIVER_PROP_NAME, "unloaded");
+ return 0;
+#endif
+}
+
+const char *wifi_get_fw_path(int fw_type)
+{
+ switch (fw_type) {
+ case WIFI_GET_FW_PATH_STA:
+ return WIFI_DRIVER_FW_PATH_STA;
+ case WIFI_GET_FW_PATH_AP:
+ return WIFI_DRIVER_FW_PATH_AP;
+ case WIFI_GET_FW_PATH_P2P:
+ return WIFI_DRIVER_FW_PATH_P2P;
+ }
+ return NULL;
+}
+
+int wifi_change_fw_path(const char *fwpath)
+{
+ int len;
+ int fd;
+ int ret = 0;
+
+ if (!fwpath)
+ return ret;
+ fd = TEMP_FAILURE_RETRY(open(WIFI_DRIVER_FW_PATH_PARAM, O_WRONLY));
+ if (fd < 0) {
+ ALOGE("Failed to open wlan fw path param (%s)", strerror(errno));
+ return -1;
+ }
+ len = strlen(fwpath) + 1;
+ if (TEMP_FAILURE_RETRY(write(fd, fwpath, len)) != len) {
+ ALOGE("Failed to write wlan fw path param (%s)", strerror(errno));
+ ret = -1;
+ }
+ close(fd);
+ return ret;
+}