WiFi: Vendor HAL function to wait for driver ready

This commit adds a vendor hal function to wait for the driver to be
ready. This ensures the driver is ready for operation before framework
starts to use it.

Note: Broadcom mentioned that checking for the presence of
/sys/class/net/wlan0 may not guarantee that WiFi is fully
initialized, and we should check /sys/class/net/wlan0/flags
for IFF_UP instead.

However, this doesn't work. The /sys/class/net/wlan0/flags value
never moves beyond 0x1002 when WiFi is turned on, until after this
function (and its subsequent functions) is invoked.

Bug: 74120746
Change-Id: If8c624c4580d456abcb1437493783b3f114d5961
diff --git a/bcmdhd/wifi_hal/wifi_hal.cpp b/bcmdhd/wifi_hal/wifi_hal.cpp
index 511ff3f..81cad8a 100644
--- a/bcmdhd/wifi_hal/wifi_hal.cpp
+++ b/bcmdhd/wifi_hal/wifi_hal.cpp
@@ -60,6 +60,13 @@
 #define WIFI_HAL_CMD_SOCK_PORT       644
 #define WIFI_HAL_EVENT_SOCK_PORT     645
 
+/*
+ * Defines for wifi_wait_for_driver_ready()
+ * Specify durations between polls and max wait time
+ */
+#define POLL_DRIVER_DURATION_US (100000)
+#define POLL_DRIVER_MAX_TIME_MS (10000)
+
 static void internal_event_handler(wifi_handle handle, int events);
 static int internal_no_seq_check(nl_msg *msg, void *arg);
 static int internal_valid_message_handler(nl_msg *msg, void *arg);
@@ -151,6 +158,7 @@
         return WIFI_ERROR_UNKNOWN;
     }
     fn->wifi_initialize = wifi_initialize;
+    fn->wifi_wait_for_driver_ready = wifi_wait_for_driver_ready;
     fn->wifi_cleanup = wifi_cleanup;
     fn->wifi_event_loop = wifi_event_loop;
     fn->wifi_get_supported_feature_set = wifi_get_supported_feature_set;
@@ -306,6 +314,25 @@
     return WIFI_SUCCESS;
 }
 
+wifi_error wifi_wait_for_driver_ready(void)
+{
+    // This function will wait to make sure basic client netdev is created
+    // Function times out after 10 seconds
+    int count = (POLL_DRIVER_MAX_TIME_MS * 1000) / POLL_DRIVER_DURATION_US;
+    FILE *fd;
+
+    do {
+        if ((fd = fopen("/sys/class/net/wlan0", "r")) != NULL) {
+            fclose(fd);
+            return WIFI_SUCCESS;
+        }
+        usleep(POLL_DRIVER_DURATION_US);
+    } while(--count > 0);
+
+    ALOGE("Timed out waiting on Driver ready ... ");
+    return WIFI_ERROR_TIMED_OUT;
+}
+
 static int wifi_add_membership(wifi_handle handle, const char *group)
 {
     hal_info *info = getHalInfo(handle);