Merge tag 'LA.UM.8.1.r1-14500-sm8150.0' of https://source.codeaurora.org/quic/la/platform/hardware/qcom/wlan into lineage-17.1

"LA.UM.8.1.r1-14500-sm8150.0"

Change-Id: I294edb29a68e8b5c1f4f727bb3eab2dd857d8579
diff --git a/Android.mk b/Android.mk
index 200eb36..8fb178a 100644
--- a/Android.mk
+++ b/Android.mk
@@ -1,4 +1,8 @@
+ifeq ($(call my-dir),$(call project-path-for,qcom-wlan))
+
 # TODO:  Find a better way to separate build configs for ADP vs non-ADP devices
 ifneq ($(BOARD_IS_AUTOMOTIVE),true)
 include $(call all-subdir-makefiles)
 endif
+
+endif
diff --git a/qcwcn/wifi_hal/Android.mk b/qcwcn/wifi_hal/Android.mk
index 12a8b78..16c075f 100644
--- a/qcwcn/wifi_hal/Android.mk
+++ b/qcwcn/wifi_hal/Android.mk
@@ -38,7 +38,7 @@
 include $(CLEAR_VARS)
 
 LOCAL_CFLAGS := -Wno-unused-parameter
-ifeq ($(TARGET_BUILD_VARIANT),userdebug)
+ifeq ($(TARGET_BUILD_VARIANT),eng)
 LOCAL_CFLAGS += "-DLOG_NDEBUG=0"
 endif
 
@@ -57,11 +57,8 @@
 	$(call include-path-for, libhardware_legacy)/hardware_legacy \
 	external/wpa_supplicant_8/src/drivers \
 	$(TARGET_OUT_HEADERS)/libwpa_client \
-	$(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include \
 	$(TARGET_OUT_HEADERS)/cld80211-lib
 
-LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
-
 LOCAL_SRC_FILES := \
 	list.cpp \
 	wifi_hal.cpp \
@@ -102,6 +99,7 @@
 endif
 
 LOCAL_HEADER_LIBRARIES := libcutils_headers libutils_headers libwifi-hal-ctrl_headers
+LOCAL_HEADER_LIBRARIES += generated_kernel_headers
 LOCAL_SANITIZE := cfi signed-integer-overflow unsigned-integer-overflow
 
 include $(BUILD_STATIC_LIBRARY)
@@ -129,11 +127,8 @@
 	$(call include-path-for, libhardware_legacy)/hardware_legacy \
 	external/wpa_supplicant_8/src/drivers \
 	$(TARGET_OUT_HEADERS)/libwpa_client \
-	$(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include \
 	$(TARGET_OUT_HEADERS)/cld80211-lib
 
-LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
-
 LOCAL_SRC_FILES := \
 	list.cpp \
 	wifi_hal.cpp \
@@ -177,5 +172,6 @@
 endif
 
 LOCAL_HEADER_LIBRARIES := libcutils_headers libutils_headers libwifi-hal-ctrl_headers
+LOCAL_HEADER_LIBRARIES += generated_kernel_headers
 LOCAL_SANITIZE := cfi integer_overflow
 include $(BUILD_SHARED_LIBRARY)
diff --git a/qcwcn/wifi_hal/common.cpp b/qcwcn/wifi_hal/common.cpp
index 3d72e76..4299abb 100644
--- a/qcwcn/wifi_hal/common.cpp
+++ b/qcwcn/wifi_hal/common.cpp
@@ -239,6 +239,7 @@
 lowi_cb_table_t *LowiWifiHalApi = NULL;
 /* LowiSupportedCapabilities read */
 u32 lowiSupportedCapabilities = 0;
+bool lowiUnsupported = false;
 
 int compareLowiVersion(u16 major, u16 minor, u16 micro)
 {
@@ -269,21 +270,27 @@
     *lowi_wifihal_api = NULL;
     *lowi_get_capa_supported = false;
 
+    if (lowiUnsupported) {
+        return WIFI_ERROR_NOT_SUPPORTED;
+    }
+
 #if __WORDSIZE == 64
     void* lowi_handle = dlopen("/vendor/lib64/liblowi_wifihal.so", RTLD_NOW);
 #else
     void* lowi_handle = dlopen("/vendor/lib/liblowi_wifihal.so", RTLD_NOW);
 #endif
     if (!lowi_handle) {
-        ALOGE("%s: NULL lowi_handle, err: %s", __FUNCTION__, dlerror());
-        return WIFI_ERROR_UNKNOWN;
+        ALOGV("%s: NULL lowi_handle, err: %s", __FUNCTION__, dlerror());
+        retVal = WIFI_ERROR_NOT_SUPPORTED;
+        goto cleanup;
     }
 
     lowiCbTable = (getCbTable_t*)dlsym(lowi_handle,
                                        "lowi_wifihal_get_cb_table");
     if (!lowiCbTable) {
         ALOGE("%s: NULL lowi callback table", __FUNCTION__);
-        return WIFI_ERROR_UNKNOWN;
+        retVal = WIFI_ERROR_NOT_SUPPORTED;
+        goto cleanup;
     }
 
     *lowi_wifihal_api = lowiCbTable();
@@ -344,6 +351,7 @@
 cleanup:
     if (retVal) {
         *lowi_wifihal_api = NULL;
+        lowiUnsupported = true;
     }
     return retVal;
 }
@@ -353,6 +361,10 @@
     int ret = WIFI_SUCCESS;
     bool lowi_get_capabilities_support = false;
 
+    if (lowiUnsupported) {
+        return NULL;
+    }
+
     if (LowiWifiHalApi == NULL) {
         ALOGV("%s: LowiWifiHalApi Null, Initialize Lowi",
               __FUNCTION__);
@@ -366,7 +378,7 @@
         /* Initialize LOWI if it isn't up already. */
         ret = LowiWifiHalApi->init();
         if (ret) {
-            ALOGE("%s: failed lowi initialization. "
+            ALOGW("%s: failed lowi initialization. "
                 "Returned error:%d. Exit.", __FUNCTION__, ret);
             goto cleanup;
         }
@@ -395,10 +407,12 @@
 
 cleanup:
     if (LowiWifiHalApi && LowiWifiHalApi->destroy) {
+        ALOGI("%s: Cleaning up Lowi due to failure. Return NULL", __FUNCTION__);
         ret = LowiWifiHalApi->destroy();
     }
     LowiWifiHalApi = NULL;
     lowiSupportedCapabilities = 0;
+    lowiUnsupported = true;
     return LowiWifiHalApi;
 }
 
diff --git a/qcwcn/wifi_hal/llstats.cpp b/qcwcn/wifi_hal/llstats.cpp
index e12b61f..ed8af1c 100644
--- a/qcwcn/wifi_hal/llstats.cpp
+++ b/qcwcn/wifi_hal/llstats.cpp
@@ -934,7 +934,7 @@
                 {
                     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS])
                     {
-                        ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS"
+                        ALOGD("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS"
                               " not found", __FUNCTION__);
                         return WIFI_ERROR_INVALID_ARGS;
                     }
@@ -945,7 +945,7 @@
                         QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS
                         ])
                     {
-                        ALOGE("%s:"
+                        ALOGD("%s:"
                             "QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS"
                             " not found", __FUNCTION__);
                         status = WIFI_ERROR_INVALID_ARGS;
diff --git a/qcwcn/wifi_hal/wifilogger_diag.cpp b/qcwcn/wifi_hal/wifilogger_diag.cpp
index a106364..3eb5b9c 100644
--- a/qcwcn/wifi_hal/wifilogger_diag.cpp
+++ b/qcwcn/wifi_hal/wifilogger_diag.cpp
@@ -2680,7 +2680,7 @@
         if (!info->cldctx) {
             if ((wnl->nlh.nlmsg_len <= sizeof(tAniNlHdr)) ||
                 (wnl->nlh.nlmsg_len < (sizeof(tAniNlHdr) + ntohs(wnl->clh.wmsg.length)))) {
-                ALOGE("Received UMAC message with insufficent length: %d",
+                ALOGV("Received UMAC message with insufficent length: %d",
                       wnl->nlh.nlmsg_len);
                 return WIFI_ERROR_UNKNOWN;
             }
diff --git a/wcnss-service/Android.mk b/wcnss-service/Android.mk
index a779b70..c1a9646 100644
--- a/wcnss-service/Android.mk
+++ b/wcnss-service/Android.mk
@@ -1,28 +1,77 @@
 ifneq (,$(filter arm aarch64 arm64, $(TARGET_ARCH)))
+
 LOCAL_PATH := $(call my-dir)
+
 include $(CLEAR_VARS)
+
 ifeq ($(PRODUCT_VENDOR_MOVE_ENABLED),true)
 LOCAL_VENDOR_MODULE := true
 endif
+
 LOCAL_MODULE := wcnss_service
 LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/common/inc/
 LOCAL_SRC_FILES := wcnss_service.c
+LOCAL_SHARED_LIBRARIES := libc libcutils libutils liblog
+
 ifeq ($(strip $(TARGET_USES_QCOM_WCNSS_QMI)),true)
-LOCAL_CFLAGS += -DWCNSS_QMI
+
+ifeq ($(TARGET_PROVIDES_WCNSS_QMI),true)
+LOCAL_CFLAGS += -DWCNSS_QMI_OSS
+LOCAL_SHARED_LIBRARIES += libdl
+else
+ifeq ($(TARGET_USES_WCNSS_MAC_ADDR_REV),true)
+LOCAL_CFLAGS += -DWCNSS_QMI_MAC_ADDR_REV
+endif
+ifneq ($(QCPATH),)
+LOCAL_CFLAGS += -DWCNSS_QMI -DMDM_DETECT
+LOCAL_SHARED_LIBRARIES += libwcnss_qmi
+else
+LOCAL_CFLAGS += -DWCNSS_QMI_OSS
+LOCAL_SHARED_LIBRARIES += libdl
+endif #QCPATH
+endif #TARGET_PROVIDES_WCNSS_QMI
+
+endif #TARGET_USES_QCOM_WCNSS_QMI
+
+ifneq ($(TARGET_DISABLE_WCNSS_CONFIG_COPY),true)
+LOCAL_CFLAGS += -DWCNSS_COPY_CONFIG
+endif
+
+LOCAL_MODULE_TAGS := optional
+LOCAL_CFLAGS += -Wall
+
+include $(BUILD_EXECUTABLE)
+
+ifneq ($(TARGET_PROVIDES_WCNSS_QMI),true)
+ifeq ($(strip $(TARGET_USES_QCOM_WCNSS_QMI)),true)
+ifneq ($(QCPATH),)
+include $(CLEAR_VARS)
+
+ifeq ($(PRODUCT_VENDOR_MOVE_ENABLED),true)
+LOCAL_VENDOR_MODULE := true
+endif
+
 LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/qmi-framework/inc
 LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/qmi/services
 LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/qmi/platform
 LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/qmi/inc
-LOCAL_SRC_FILES += wcnss_qmi_client.c
-endif #TARGET_USES_QCOM_WCNSS_QMI
 LOCAL_SHARED_LIBRARIES := libc libcutils libutils liblog
-ifeq ($(strip $(TARGET_USES_QCOM_WCNSS_QMI)),true)
 LOCAL_SHARED_LIBRARIES += libqmiservices libqmi_cci
 LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/libmdmdetect/inc
 LOCAL_SHARED_LIBRARIES += libmdmdetect
 LOCAL_HEADER_LIBRARIES += libril-qc-qmi-services-headers
-endif #TARGET_USES_QCOM_WCNSS_QMI
+LOCAL_CFLAGS += -DWCNSS_QMI
+LOCAL_SRC_FILES += wcnss_qmi_client.c
+
+LOCAL_MODULE := libwcnss_qmi
 LOCAL_MODULE_TAGS := optional
-LOCAL_CFLAGS += -Wall -Werror
-include $(BUILD_EXECUTABLE)
-endif
+
+LOCAL_CFLAGS += -Wall
+
+include $(BUILD_SHARED_LIBRARY)
+
+endif #QCPATH
+endif #TARGET_USES_QCOM_WCNSS_QMI
+endif #TARGET_PROVIDES_WCNSS_QMI
+
+endif #TARGET_ARCH == arm
diff --git a/wcnss-service/wcnss_service.c b/wcnss-service/wcnss_service.c
index c817be1..7d1add9 100644
--- a/wcnss-service/wcnss_service.c
+++ b/wcnss-service/wcnss_service.c
@@ -37,13 +37,19 @@
 #include <utime.h>
 #include <sys/stat.h>
 #include <sys/sendfile.h>
+#include <unistd.h>
 #define LOG_TAG "wcnss_service"
 #include <cutils/log.h>
 #include <cutils/properties.h>
 #ifdef WCNSS_QMI
 #include "wcnss_qmi_client.h"
+#ifdef MDM_DETECT
 #include "mdm_detect.h"
 #endif
+#endif
+#ifdef WCNSS_QMI_OSS
+#include <dlfcn.h>
+#endif
 
 #define SUCCESS 0
 #define FAILED -1
@@ -68,11 +74,12 @@
 #define WCNSS_FACT_FILE "/data/vendor/wifi/WCN_FACTORY"
 #define WCNSS_DEVICE    "/dev/wcnss_wlan"
 #define WCNSS_CTRL      "/dev/wcnss_ctrl"
+#ifdef WCNSS_COPY_CONFIG
 #define WLAN_INI_FILE_DEST   "/data/vendor/wifi/WCNSS_qcom_cfg.ini"
 #define WLAN_INI_FILE_SOURCE "/vendor/etc/wifi/WCNSS_qcom_cfg.ini"
+#endif
 #define WCNSS_HAS_CAL_DATA\
 		"/sys/module/wcnsscore/parameters/has_calibrated_data"
-#define WLAN_DRIVER_ATH_DEFAULT_VAL "0"
 
 #define ASCII_A		65
 #define ASCII_a		97
@@ -80,10 +87,14 @@
 #define HEXA_A		10
 #define HEX_BASE		16
 
-#ifdef WCNSS_QMI
+#if defined (WCNSS_QMI) || defined(WCNSS_QMI_OSS)
 #define WLAN_ADDR_SIZE   6
 unsigned char wlan_nv_mac_addr[WLAN_ADDR_SIZE];
+#ifdef WCNSS_QMI_MAC_ADDR_REV
+#define MAC_ADDR_ARRAY(a) (a)[5], (a)[4], (a)[3], (a)[2], (a)[1], (a)[0]
+#else
 #define MAC_ADDR_ARRAY(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
+#endif
 #define MAC_ADDRESS_STR "%02x:%02x:%02x:%02x:%02x:%02x"
 
 /* As we Want to write in 00:0a:f5:11:22:33 format in sysfs file
@@ -296,6 +307,7 @@
 	chdir("..");
 }
 
+#ifdef WCNSS_COPY_CONFIG
 void setup_wlan_config_file()
 {
 	int rfd;
@@ -366,6 +378,8 @@
 	property_set("vendor.wlan.driver.config", WLAN_INI_FILE_DEST);
 	return;
 }
+#endif
+
 unsigned int convert_string_to_hex(char* string)
 {
 	int idx;
@@ -389,17 +403,15 @@
 }
 
 
-#ifdef WCNSS_QMI
+#if defined(WCNSS_QMI) || defined(WCNSS_QMI_OSS)
 void setup_wcnss_parameters(int *cal, int nv_mac_addr)
 #else
 void setup_wcnss_parameters(int *cal)
 #endif
 {
 	char msg[WCNSS_MAX_CMD_LEN];
-	char serial[PROPERTY_VALUE_MAX];
 	int fd, rc, pos = 0;
 	struct stat st;
-	unsigned int serial_num = 0;
 
 	fd = open(WCNSS_CTRL, O_WRONLY);
 	if (fd < 0) {
@@ -407,37 +419,27 @@
 		return;
 	}
 
-	rc = property_get("ro.serialno", serial, "");
-	if (rc) {
-		serial_num = convert_string_to_hex(serial);
-		ALOGE("Serial Number is  %x", serial_num);
-
-		msg[pos++] = WCNSS_USR_SERIAL_NUM >> BYTE_1;
-		msg[pos++] = WCNSS_USR_SERIAL_NUM >> BYTE_0;
-		msg[pos++] = serial_num >> BYTE_3;
-		msg[pos++] = serial_num >> BYTE_2;
-		msg[pos++] = serial_num >> BYTE_1;
-		msg[pos++] = serial_num >> BYTE_0;
-
-		if (write(fd, msg, pos) < 0) {
-			ALOGE("Failed to write to %s : %s", WCNSS_CTRL,
-					strerror(errno));
-			goto fail;
-		}
-	}
-
-#ifdef WCNSS_QMI
+#if defined(WCNSS_QMI) || defined (WCNSS_QMI_OSS)
 	if (SUCCESS == nv_mac_addr)
 	{
 		pos = 0;
 		msg[pos++] = WCNSS_USR_WLAN_MAC_ADDR >> BYTE_1;
 		msg[pos++] = WCNSS_USR_WLAN_MAC_ADDR >> BYTE_0;
+#ifdef WCNSS_QMI_MAC_ADDR_REV
+		msg[pos++] = wlan_nv_mac_addr[5];
+		msg[pos++] = wlan_nv_mac_addr[4];
+		msg[pos++] = wlan_nv_mac_addr[3];
+		msg[pos++] = wlan_nv_mac_addr[2];
+		msg[pos++] = wlan_nv_mac_addr[1];
+		msg[pos++] = wlan_nv_mac_addr[0];
+#else
 		msg[pos++] = wlan_nv_mac_addr[0];
 		msg[pos++] = wlan_nv_mac_addr[1];
 		msg[pos++] = wlan_nv_mac_addr[2];
 		msg[pos++] = wlan_nv_mac_addr[3];
 		msg[pos++] = wlan_nv_mac_addr[4];
 		msg[pos++] = wlan_nv_mac_addr[5];
+#endif
 
 		ALOGI("WLAN MAC Addr:" MAC_ADDRESS_STR,
 			MAC_ADDR_ARRAY(wlan_nv_mac_addr));
@@ -493,12 +495,7 @@
 	return;
 }
 
-void setup_wlan_driver_ath_prop()
-{
-	property_set("vendor.wlan.driver.ath", WLAN_DRIVER_ATH_DEFAULT_VAL);
-}
-
-#ifdef WCNSS_QMI
+#ifdef MDM_DETECT
 int check_modem_compatability(struct dev_info *mdm_detect_info)
 {
 	char args[MODEM_BASEBAND_PROPERTY_SIZE] = {0};
@@ -717,23 +714,103 @@
 	}
 
 	ALOGI("dynamic nv replace sucessfully!\n");
-
 }
 
+#ifdef WCNSS_QMI_OSS
+static void *wcnss_qmi_handle = NULL;
+static int (*wcnss_init_qmi)(void) = NULL;
+static int (*wcnss_qmi_get_wlan_address)(unsigned char *) = NULL;
+static void (*wcnss_qmi_deinit)(void) = NULL;
+
+static int setup_wcnss_qmi(void)
+{
+	const char *error = NULL;
+
+	/* initialize the DMS client and request the wlan mac address */
+	wcnss_qmi_handle = dlopen("libwcnss_qmi.so", RTLD_NOW);
+	if (!wcnss_qmi_handle) {
+		ALOGE("Failed to open libwcnss_qmi.so: %s", dlerror());
+		goto dlopen_err;
+	}
+
+	dlerror();
+
+	wcnss_init_qmi = dlsym(wcnss_qmi_handle, "wcnss_init_qmi");
+	if ((error = dlerror()) != NULL) {
+		ALOGE("Failed to resolve function: %s: %s",
+				"wcnss_init_qmi", error);
+		goto dlsym_err;
+	}
+
+	dlerror();
+
+	wcnss_qmi_get_wlan_address = dlsym(wcnss_qmi_handle,
+			"wcnss_qmi_get_wlan_address");
+	if ((error = dlerror()) != NULL) {
+		ALOGE("Failed to resolve function: %s: %s",
+				"wcnss_qmi_get_wlan_address", error);
+		goto dlsym_err;
+	}
+
+	dlerror();
+
+	wcnss_qmi_deinit = dlsym(wcnss_qmi_handle, "wcnss_qmi_deinit");
+	if ((error = dlerror()) != NULL) {
+		ALOGE("Failed to resolve function: %s: %s",
+				"wcnss_qmi_deinit", error);
+		goto dlsym_err;
+	}
+
+	return SUCCESS;
+
+dlsym_err:
+	dlclose(wcnss_qmi_handle);
+dlopen_err:
+	return FAILED;
+}
+#endif
+
 int main(int argc, char *argv[])
 {
 	UNUSED(argc), UNUSED(argv);
 	int rc;
 	int fd_dev, ret_cal;
-#ifdef WCNSS_QMI
+#if defined(WCNSS_QMI) || defined(WCNSS_QMI_OSS)
 	int nv_mac_addr = FAILED;
+#ifdef MDM_DETECT
 	struct dev_info mdm_detect_info;
 	int nom = 0;
 #endif
+#endif
 
+#ifdef WCNSS_COPY_CONFIG
 	setup_wlan_config_file();
+#endif
 
+#ifdef WCNSS_QMI_OSS
+	/* dlopen WCNSS QMI lib */
+
+	rc = setup_wcnss_qmi();
+	if (rc == SUCCESS) {
+		if (SUCCESS == (*wcnss_init_qmi)()) {
+			rc = (*wcnss_qmi_get_wlan_address)(wlan_nv_mac_addr);
+			if (rc == SUCCESS) {
+				nv_mac_addr = SUCCESS;
+				ALOGE("WLAN MAC Addr:" MAC_ADDRESS_STR,
+						MAC_ADDR_ARRAY(wlan_nv_mac_addr));
+			} else
+				ALOGE("Failed to Get MAC addr from modem");
+
+			(*wcnss_qmi_deinit)();
+		}
+		else
+			ALOGE("Failed to Initialize wcnss QMI Interface");
+	} else {
+		ALOGE("Failed to Initialize wcnss QMI interface library");
+	}
+#endif
 #ifdef WCNSS_QMI
+#ifdef MDM_DETECT
 	/* Call ESOC API to get the number of modems.
 	   If the number of modems is not zero, only then proceed
 	   with the eap_proxy intialization.*/
@@ -755,6 +832,7 @@
 		ALOGE("wcnss_service: Target does not have external modem");
 		goto nomodem;
 	}
+#endif
 
 	/* initialize the DMS client and request the wlan mac address */
 
@@ -779,7 +857,7 @@
 
 	dynamic_nv_replace();
 
-#ifdef WCNSS_QMI
+#if defined(WCNSS_QMI) || defined(WCNSS_QMI_OSS)
 	setup_wcnss_parameters(&ret_cal, nv_mac_addr);
 #else
 	setup_wcnss_parameters(&ret_cal);
@@ -800,8 +878,6 @@
 			ALOGE("Cal data is successfully written to WCNSS");
 	}
 
-	setup_wlan_driver_ath_prop();
-
 	rc = wcnss_read_and_store_cal_data(fd_dev);
 	if (rc != SUCCESS)
 		ALOGE("Failed to read and save cal data %d", rc);
@@ -811,5 +887,9 @@
 
 	close(fd_dev);
 
+#ifdef WCNSS_QMI_OSS
+	dlclose(wcnss_qmi_handle);
+#endif
+
 	return rc;
 }