[WCNCR00165271] misc: Support Android AOSP priv command
[Description]
Add priv command parsing format for wpa_supplicant w/o priv lib
Change-Id: Icc1d41f59059e50fce1cbe5451e1bb9967c393fa
Signed-off-by: Allan Wang <Allan.Wang@mediatek.com>
CR-Id: WCNCR00165271
Feature: misc
(cherry picked from commit cd0fbbe3f1ecbf8474d0401f58e278970d91d35c)
diff --git a/Makefile.ce b/Makefile.ce
index 5738d2e..c301ebb 100644
--- a/Makefile.ce
+++ b/Makefile.ce
@@ -136,6 +136,10 @@
# Define to enable Android wake_lock
CFG_ENABLE_WAKE_LOCK=0
+# For wpa_supplicant w/o MTK priv lib
+# y: enable, n: disable
+CFG_ANDROID_AOSP_PRIV_CMD=n
+
CFG_DEFAULT_DBG_LEVEL=0xF
CFG_TX_DIRECT_USB=1
@@ -229,6 +233,10 @@
PLATFORM_FLAGS += -DCFG_DRIVER_INF_NAME_CHANGE
endif
+ifeq ($(CFG_ANDROID_AOSP_PRIV_CMD), y)
+PLATFORM_FLAGS += -DCFG_ANDROID_AOSP_PRIV_CMD
+endif
+
ifneq ($(CFG_SUPPORT_SINGLE_SKU_LOCAL_DB),)
PLATFORM_FLAGS += -DCFG_SUPPORT_SINGLE_SKU_LOCAL_DB=$(CFG_SUPPORT_SINGLE_SKU_LOCAL_DB)
endif
diff --git a/Makefile.x86 b/Makefile.x86
index ad95c45..d279330 100644
--- a/Makefile.x86
+++ b/Makefile.x86
@@ -54,6 +54,10 @@
# Define to enable Android wake_lock
#CFG_ENABLE_WAKE_LOCK=0
+# For wpa_supplicant w/o MTK priv lib
+# y: enable, n: disable
+CFG_ANDROID_AOSP_PRIV_CMD=n
+
#CFG_DEFAULT_DBG_LEVEL=0xF
CFG_TX_DIRECT_USB=1
@@ -154,6 +158,10 @@
PLATFORM_FLAGS += -DCFG_CHIP_RESET_SUPPORT=$(CFG_CHIP_RESET_SUPPORT)
endif
+ifeq ($(CFG_ANDROID_AOSP_PRIV_CMD), y)
+PLATFORM_FLAGS += -DCFG_ANDROID_AOSP_PRIV_CMD
+endif
+
all: driver
driver:
diff --git a/os/linux/gl_init.c b/os/linux/gl_init.c
index 3ef9884..8ebd1b2 100644
--- a/os/linux/gl_init.c
+++ b/os/linux/gl_init.c
@@ -785,7 +785,11 @@
/* 0x8BE0 ~ 0x8BFF, private ioctl region */
ret = priv_support_ioctl(prDev, prIfReq, i4Cmd);
} else if (i4Cmd == SIOCDEVPRIVATE + 1) {
+#ifdef CFG_ANDROID_AOSP_PRIV_CMD
+ ret = android_private_support_driver_cmd(prDev, prIfReq, i4Cmd);
+#else
ret = priv_support_driver_cmd(prDev, prIfReq, i4Cmd);
+#endif /* CFG_ANDROID_AOSP_PRIV_CMD */
} else {
DBGLOG(INIT, WARN, "Unexpected ioctl command: 0x%04x\n", i4Cmd);
ret = -EOPNOTSUPP;
diff --git a/os/linux/gl_p2p.c b/os/linux/gl_p2p.c
index c021b55..c3e6f23 100644
--- a/os/linux/gl_p2p.c
+++ b/os/linux/gl_p2p.c
@@ -1645,6 +1645,10 @@
ret = priv_support_driver_cmd(prDev, prIfReq, i4Cmd);
else if (i4Cmd == SIOCGIWPRIV)
ret = mtk_p2p_wext_get_priv(prDev, &rIwReqInfo, &(prIwReq->u), NULL);
+#ifdef CFG_ANDROID_AOSP_PRIV_CMD
+ else if (i4Cmd == SIOCDEVPRIVATE + 1)
+ ret = android_private_support_driver_cmd(prDev, prIfReq, i4Cmd);
+#endif
else {
DBGLOG(INIT, WARN, "Unexpected ioctl command: 0x%04x\n", i4Cmd);
ret = -1;
diff --git a/os/linux/gl_wext_priv.c b/os/linux/gl_wext_priv.c
index d9a7080..10d9c8f 100644
--- a/os/linux/gl_wext_priv.c
+++ b/os/linux/gl_wext_priv.c
@@ -2398,6 +2398,13 @@
int total_len;
} priv_driver_cmd_t;
+#ifdef CFG_ANDROID_AOSP_PRIV_CMD
+struct android_wifi_priv_cmd {
+ char *buf;
+ int used_len;
+ int total_len;
+};
+#endif /* CFG_ANDROID_AOSP_PRIV_CMD */
int priv_driver_get_dbg_level(IN struct net_device *prNetDev, IN char *pcCommand, IN int i4TotalLen)
{
@@ -10036,7 +10043,13 @@
i4BytesWritten = (INT_32)u4Offset;
return i4BytesWritten;
+}
+static int priv_cmd_not_support(IN struct net_device *prNetDev, IN char *pcCommand, IN int i4TotalLen)
+{
+ DBGLOG(REQ, WARN, "not support priv command: %s\n", pcCommand);
+
+ return -EOPNOTSUPP;
}
static int priv_driver_set_maxrfgain(IN struct net_device *prNetDev, IN char *pcCommand, IN int i4TotalLen)
@@ -10447,7 +10460,6 @@
{
P_GLUE_INFO_T prGlueInfo = NULL;
INT_32 i4BytesWritten = 0;
- INT_32 i4CmdFound = 0;
if (g_u4HaltFlag) {
DBGLOG(REQ, WARN, "wlan is halt, skip priv_driver_cmds\n");
@@ -10458,8 +10470,6 @@
return -1;
prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
- if (i4CmdFound == 0) {
- i4CmdFound = 1;
if (strnicmp(pcCommand, CMD_RSSI, strlen(CMD_RSSI)) == 0) {
/* i4BytesWritten =
* wl_android_get_rssi(net, command, i4TotalLen);
@@ -10725,11 +10735,7 @@
i4BytesWritten = priv_driver_noise_histogram(prNetDev, pcCommand, i4TotalLen);
#endif
else
- i4CmdFound = 0;
- }
- /* i4CmdFound */
- if (i4CmdFound == 0)
- DBGLOG(REQ, INFO, "Unknown driver command %s - ignored\n", pcCommand);
+ i4BytesWritten = priv_cmd_not_support(prNetDev, pcCommand, i4TotalLen);
if (i4BytesWritten >= 0) {
if ((i4BytesWritten == 0) && (i4TotalLen > 0)) {
@@ -10835,3 +10841,54 @@
return ret;
} /* priv_support_driver_cmd */
+
+#ifdef CFG_ANDROID_AOSP_PRIV_CMD
+int android_private_support_driver_cmd(IN struct net_device *prNetDev,
+ IN OUT struct ifreq *prReq, IN int i4Cmd)
+{
+ struct android_wifi_priv_cmd priv_cmd;
+ char *command = NULL;
+ int ret = 0, bytes_written = 0;
+
+ if (!prReq->ifr_data)
+ return -EINVAL;
+
+ if (copy_from_user(&priv_cmd, prReq->ifr_data, sizeof(priv_cmd)))
+ return -EFAULT;
+
+ command = kzalloc(priv_cmd.total_len, GFP_KERNEL);
+ if (!command) {
+ DBGLOG(REQ, WARN, "%s, alloc mem failed\n", __func__);
+ return -ENOMEM;
+ }
+
+ if (copy_from_user(command, priv_cmd.buf, priv_cmd.total_len)) {
+ ret = -EFAULT;
+ goto FREE;
+ }
+
+ bytes_written = priv_driver_cmds(prNetDev, command, priv_cmd.total_len);
+
+ if (bytes_written >= 0) {
+ /* priv_cmd in but no response */
+ if ((bytes_written == 0) && (priv_cmd.total_len > 0))
+ command[0] = '\0';
+
+ if (bytes_written >= priv_cmd.total_len)
+ bytes_written = priv_cmd.total_len;
+ else
+ bytes_written++;
+
+ priv_cmd.used_len = bytes_written;
+
+ if (copy_to_user(priv_cmd.buf, command, bytes_written))
+ ret = -EFAULT;
+ } else
+ ret = bytes_written;
+
+FREE:
+ kfree(command);
+
+ return ret;
+}
+#endif /* CFG_ANDROID_AOSP_PRIV_CMD */
diff --git a/os/linux/include/gl_wext_priv.h b/os/linux/include/gl_wext_priv.h
index 7f305f7..9243a0f 100644
--- a/os/linux/include/gl_wext_priv.h
+++ b/os/linux/include/gl_wext_priv.h
@@ -318,6 +318,10 @@
int priv_support_driver_cmd(IN struct net_device *prDev, IN OUT struct ifreq *prReq, IN int i4Cmd);
+#ifdef CFG_ANDROID_AOSP_PRIV_CMD
+int android_private_support_driver_cmd(IN struct net_device *prDev, IN OUT struct ifreq *prReq, IN int i4Cmd);
+#endif /* CFG_ANDROID_AOSP_PRIV_CMD */
+
INT_32 priv_driver_cmds(IN struct net_device *prNetDev, IN PCHAR pcCommand, IN INT_32 i4TotalLen);
int priv_driver_set_cfg(IN struct net_device *prNetDev, IN char *pcCommand, IN int i4TotalLen);