summaryrefslogtreecommitdiffstats
path: root/libwifi_hal/wifi_hal_common.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libwifi_hal/wifi_hal_common.cpp')
-rw-r--r--libwifi_hal/wifi_hal_common.cpp59
1 files changed, 59 insertions, 0 deletions
diff --git a/libwifi_hal/wifi_hal_common.cpp b/libwifi_hal/wifi_hal_common.cpp
index 413daf7da..49bb9d1af 100644
--- a/libwifi_hal/wifi_hal_common.cpp
+++ b/libwifi_hal/wifi_hal_common.cpp
@@ -42,6 +42,12 @@ extern "C" int delete_module(const char *, unsigned int);
#define WIFI_DRIVER_MODULE_ARG ""
#endif
+#ifdef WIFI_DRIVER_OPERSTATE_PATH
+#include <sys/stat.h>
+#define OPERSTATE_UP "up"
+#define OPERSTATE_DOWN "down"
+#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;
@@ -93,8 +99,20 @@ int wifi_change_driver_state(const char *state) {
int len;
int fd;
int ret = 0;
+ int count = 5; /* wait at most 1 second for completion */
if (!state) return -1;
+
+ do {
+ if (access(WIFI_DRIVER_STATE_CTRL_PARAM, W_OK) == 0)
+ break;
+ usleep(200000);
+ } while (--count > 0);
+ if (count == 0) {
+ PLOG(ERROR) << "Failed to access driver state control param " << strerror(errno) << ", " << errno;
+ return -1;
+ }
+
fd = TEMP_FAILURE_RETRY(open(WIFI_DRIVER_STATE_CTRL_PARAM, O_WRONLY));
if (fd < 0) {
PLOG(ERROR) << "Failed to open driver state control param";
@@ -147,6 +165,40 @@ int is_wifi_driver_loaded() {
#endif
}
+#ifdef WIFI_DRIVER_OPERSTATE_PATH
+int is_wifi_driver_ready() {
+ struct stat sbuf;
+ FILE *fstate;
+ char operstate[8];
+ int open_count = 25, read_count = 25;
+ while (open_count-- >= 0) {
+ if (stat(WIFI_DRIVER_OPERSTATE_PATH, &sbuf) == 0) {
+ if ((fstate = fopen(WIFI_DRIVER_OPERSTATE_PATH, "r")) == NULL) {
+ usleep(500000);
+ } else {
+ break;
+ }
+ } else {
+ usleep(500000);
+ }
+ }
+ if (fstate != NULL) {
+ while (read_count-- >= 0) {
+ fgets(operstate, sizeof(operstate), fstate);
+ if (strncmp(operstate, OPERSTATE_UP, strlen(OPERSTATE_UP)) == 0 ||
+ strncmp(operstate, OPERSTATE_DOWN, strlen(OPERSTATE_DOWN)) == 0) {
+ PLOG(INFO) << "Wifi driver is ready";
+ return 1;
+ }
+ PLOG(WARNING) << "Waiting for Wifi driver to get ready. (" << read_count << ")";
+ usleep(500000);
+ }
+ fclose(fstate);
+ }
+ return 0;
+}
+#endif
+
int wifi_load_driver() {
#ifdef WIFI_DRIVER_MODULE_PATH
if (is_wifi_driver_loaded()) {
@@ -163,6 +215,13 @@ int wifi_load_driver() {
if (wifi_change_driver_state(WIFI_DRIVER_STATE_ON) < 0) return -1;
#endif
+
+#ifdef WIFI_DRIVER_OPERSTATE_PATH
+ if (!is_wifi_driver_ready()) {
+ PLOG(ERROR) << "Wifi driver didn't get ready in time, giving up!";
+ return -1;
+ }
+#endif
property_set(DRIVER_PROP_NAME, "ok");
return 0;
}