From 7d64f70835ae2fa1df219e5196306bce57077123 Mon Sep 17 00:00:00 2001
From: Lin Ma <linm@broadcom.com>
Date: Wed, 3 Aug 2011 13:43:03 -0700
Subject: [PATCH 526/696] net: wireless: bcmdhd: Eliminate nested IOCTL call

Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
---
 drivers/net/wireless/bcmdhd/dhd_linux.c    |   24 ++++++++++++++++++++++++
 drivers/net/wireless/bcmdhd/wldev_common.c |   22 +++-------------------
 2 files changed, 27 insertions(+), 19 deletions(-)

diff --git a/drivers/net/wireless/bcmdhd/dhd_linux.c b/drivers/net/wireless/bcmdhd/dhd_linux.c
index 3035cf8..c345b18 100644
--- a/drivers/net/wireless/bcmdhd/dhd_linux.c
+++ b/drivers/net/wireless/bcmdhd/dhd_linux.c
@@ -4123,6 +4123,30 @@ int net_os_wake_unlock(struct net_device *dev)
 	return ret;
 }
 
+int dhd_ioctl_entry_local(struct net_device *net, wl_ioctl_t *ioc, int cmd)
+{
+	int ifidx;
+	int ret = 0;
+	dhd_info_t *dhd = NULL;
+
+	if (!net || !netdev_priv(net)) {
+		DHD_ERROR(("%s invalid parameter\n", __FUNCTION__));
+		return -EINVAL;
+	}
+
+	dhd = *(dhd_info_t **)netdev_priv(net);
+	ifidx = dhd_net2idx(dhd, net);
+	if (ifidx == DHD_BAD_IF) {
+		DHD_ERROR(("%s bad ifidx\n", __FUNCTION__));
+		return -ENODEV;
+	}
+
+	DHD_OS_WAKE_LOCK(&dhd->pub);
+	ret = dhd_wl_ioctl(&dhd->pub, ifidx, ioc, ioc->buf, ioc->len);
+	DHD_OS_WAKE_UNLOCK(&dhd->pub);
+
+	return ret;
+}
 
 #ifdef PROP_TXSTATUS
 extern int dhd_wlfc_interface_entry_update(void* state,	ewlfc_mac_entry_action_t action, uint8 ifid,
diff --git a/drivers/net/wireless/bcmdhd/wldev_common.c b/drivers/net/wireless/bcmdhd/wldev_common.c
index 429cd2c..b01e4a2 100644
--- a/drivers/net/wireless/bcmdhd/wldev_common.c
+++ b/drivers/net/wireless/bcmdhd/wldev_common.c
@@ -38,37 +38,21 @@
 #define htodchanspec(i) i
 #define dtohchanspec(i) i
 
+extern int dhd_ioctl_entry_local(struct net_device *net, wl_ioctl_t *ioc, int cmd);
+
 s32 wldev_ioctl(
 	struct net_device *dev, u32 cmd, void *arg, u32 len, u32 set)
 {
 	s32 ret = 0;
-	struct ifreq ifr;
 	struct wl_ioctl ioc;
-	mm_segment_t fs;
-	s32 err = 0;
-
-	if (!dev) {
-		DHD_ERROR(("%s: dev is null\n", __FUNCTION__));
-		return -EINVAL;
-	}
 
 	memset(&ioc, 0, sizeof(ioc));
 	ioc.cmd = cmd;
 	ioc.buf = arg;
 	ioc.len = len;
 	ioc.set = set;
-	strcpy(ifr.ifr_name, dev->name);
-	ifr.ifr_data = (caddr_t)&ioc;
-
-	fs = get_fs();
-	set_fs(get_ds());
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31)
-	err = dev->do_ioctl(dev, &ifr, SIOCDEVPRIVATE);
-#else
-	err = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, SIOCDEVPRIVATE);
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31) */
-	set_fs(fs);
 
+	ret = dhd_ioctl_entry_local(dev, &ioc, cmd);
 	return ret;
 }
 
-- 
1.7.1


