net: wireless: rockchip_wlan: update for ap6xxx wifi driver
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rkwifi / bcmdhd / dhd_linux.c
old mode 100755 (executable)
new mode 100644 (file)
index 29c5a0e..9daa6e2
@@ -81,6 +81,9 @@
 #include <dhd_bus.h>
 #include <dhd_proto.h>
 #include <dhd_config.h>
 #include <dhd_bus.h>
 #include <dhd_proto.h>
 #include <dhd_config.h>
+#ifdef WL_ESCAN
+#include <wl_escan.h>
+#endif
 #include <dhd_dbg.h>
 #ifdef CONFIG_HAS_WAKELOCK
 #include <linux/wakelock.h>
 #include <dhd_dbg.h>
 #ifdef CONFIG_HAS_WAKELOCK
 #include <linux/wakelock.h>
@@ -5714,17 +5717,35 @@ dhd_ioctl_entry(struct net_device *net, struct ifreq *ifr, int cmd)
                        goto done;
                }
                ioc.cmd = compat_ioc.cmd;
                        goto done;
                }
                ioc.cmd = compat_ioc.cmd;
-               ioc.buf = compat_ptr(compat_ioc.buf);
-               ioc.len = compat_ioc.len;
-               ioc.set = compat_ioc.set;
-               ioc.used = compat_ioc.used;
-               ioc.needed = compat_ioc.needed;
-               /* To differentiate between wl and dhd read 4 more byes */
-               if ((copy_from_user(&ioc.driver, (char *)ifr->ifr_data + sizeof(compat_wl_ioctl_t),
-                       sizeof(uint)) != 0)) {
-                       ret = BCME_BADADDR;
-                       goto done;
-               }
+               if (ioc.cmd & WLC_SPEC_FLAG) {
+                       memset(&ioc, 0, sizeof(ioc));
+                       /* Copy the ioc control structure part of ioctl request */
+                       if (copy_from_user(&ioc, ifr->ifr_data, sizeof(wl_ioctl_t))) {
+                               ret = BCME_BADADDR;
+                               goto done;
+                       }
+                       ioc.cmd &= ~WLC_SPEC_FLAG; /* Clear the FLAG */
+
+                       /* To differentiate between wl and dhd read 4 more byes */
+                       if ((copy_from_user(&ioc.driver, (char *)ifr->ifr_data + sizeof(wl_ioctl_t),
+                               sizeof(uint)) != 0)) {
+                               ret = BCME_BADADDR;
+                               goto done;
+                       }
+
+               } else { /* ioc.cmd & WLC_SPEC_FLAG */
+                       ioc.buf = compat_ptr(compat_ioc.buf);
+                       ioc.len = compat_ioc.len;
+                       ioc.set = compat_ioc.set;
+                       ioc.used = compat_ioc.used;
+                       ioc.needed = compat_ioc.needed;
+                       /* To differentiate between wl and dhd read 4 more byes */
+                       if ((copy_from_user(&ioc.driver, (char *)ifr->ifr_data + sizeof(compat_wl_ioctl_t),
+                               sizeof(uint)) != 0)) {
+                               ret = BCME_BADADDR;
+                               goto done;
+                       }
+               } /* ioc.cmd & WLC_SPEC_FLAG */
        } else
 #endif /* CONFIG_COMPAT */
        {
        } else
 #endif /* CONFIG_COMPAT */
        {
@@ -5733,7 +5754,9 @@ dhd_ioctl_entry(struct net_device *net, struct ifreq *ifr, int cmd)
                        ret = BCME_BADADDR;
                        goto done;
                }
                        ret = BCME_BADADDR;
                        goto done;
                }
-
+#ifdef CONFIG_COMPAT
+               ioc.cmd &= ~WLC_SPEC_FLAG; /* make sure it was clear when it isn't a compat task*/
+#endif
                /* To differentiate between wl and dhd read 4 more byes */
                if ((copy_from_user(&ioc.driver, (char *)ifr->ifr_data + sizeof(wl_ioctl_t),
                        sizeof(uint)) != 0)) {
                /* To differentiate between wl and dhd read 4 more byes */
                if ((copy_from_user(&ioc.driver, (char *)ifr->ifr_data + sizeof(wl_ioctl_t),
                        sizeof(uint)) != 0)) {
@@ -7221,6 +7244,9 @@ dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen)
                }
                dhd_state |= DHD_ATTACH_STATE_WL_ATTACH;
        }
                }
                dhd_state |= DHD_ATTACH_STATE_WL_ATTACH;
        }
+#ifdef WL_ESCAN
+       wl_escan_attach(net, (void *)&dhd->pub);
+#endif
 #endif /* defined(WL_WIRELESS_EXT) */
 
 #ifdef SHOW_LOGTRACE
 #endif /* defined(WL_WIRELESS_EXT) */
 
 #ifdef SHOW_LOGTRACE
@@ -8792,6 +8818,9 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
 #ifdef WLTDLS
        setbit(eventmask, WLC_E_TDLS_PEER_EVENT);
 #endif /* WLTDLS */
 #ifdef WLTDLS
        setbit(eventmask, WLC_E_TDLS_PEER_EVENT);
 #endif /* WLTDLS */
+#ifdef WL_ESCAN
+       setbit(eventmask, WLC_E_ESCAN_RESULT);
+#endif
 #ifdef WL_CFG80211
        setbit(eventmask, WLC_E_ESCAN_RESULT);
        setbit(eventmask, WLC_E_AP_STARTED);
 #ifdef WL_CFG80211
        setbit(eventmask, WLC_E_ESCAN_RESULT);
        setbit(eventmask, WLC_E_AP_STARTED);
@@ -9663,6 +9692,9 @@ void dhd_detach(dhd_pub_t *dhdp)
                /* Detatch and unlink in the iw */
                wl_iw_detach();
        }
                /* Detatch and unlink in the iw */
                wl_iw_detach();
        }
+#ifdef WL_ESCAN
+       wl_escan_detach();
+#endif
 #endif /* defined(WL_WIRELESS_EXT) */
 
        /* delete all interfaces, start with virtual  */
 #endif /* defined(WL_WIRELESS_EXT) */
 
        /* delete all interfaces, start with virtual  */
@@ -9939,7 +9971,7 @@ dhd_module_cleanup(void)
        printf("%s: Exit\n", __FUNCTION__);
 }
 
        printf("%s: Exit\n", __FUNCTION__);
 }
 
-static void __exit
+static void
 dhd_module_exit(void)
 {
        dhd_buzzz_detach();
 dhd_module_exit(void)
 {
        dhd_buzzz_detach();
@@ -9947,11 +9979,11 @@ dhd_module_exit(void)
        unregister_reboot_notifier(&dhd_reboot_notifier);
 }
 
        unregister_reboot_notifier(&dhd_reboot_notifier);
 }
 
-static int __init
+static int
 dhd_module_init(void)
 {
        int err;
 dhd_module_init(void)
 {
        int err;
-       int retry = POWERUP_MAX_RETRY;
+       int retry = 0;
 
        printf("%s: in\n", __FUNCTION__);
 
 
        printf("%s: in\n", __FUNCTION__);
 
@@ -10010,7 +10042,37 @@ dhd_reboot_callback(struct notifier_block *this, unsigned long code, void *unuse
        return NOTIFY_DONE;
 }
 
        return NOTIFY_DONE;
 }
 
+static int wifi_init_thread(void *data)
+{
+       dhd_module_init();
+
+       return 0;
+}
 
 
+int rockchip_wifi_init_module_rkwifi(void)
+{
+       struct task_struct *kthread = NULL;
+
+       kthread = kthread_run(wifi_init_thread, NULL, "wifi_init_thread");
+       if (IS_ERR(kthread))
+               pr_err("create wifi_init_thread failed.\n");
+
+       return 0;
+}
+
+void rockchip_wifi_exit_module_rkwifi(void)
+{
+       dhd_module_exit();
+}
+
+#ifdef CONFIG_WIFI_LOAD_DRIVER_WHEN_KERNEL_BOOTUP
+late_initcall(rockchip_wifi_init_module_rkwifi);
+module_exit(rockchip_wifi_exit_module_rkwifi);
+#else
+module_init(rockchip_wifi_init_module_rkwifi);
+module_exit(rockchip_wifi_exit_module_rkwifi);
+#endif
+#if 0
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
 #if defined(CONFIG_DEFERRED_INITCALLS)
 #if defined(CONFIG_MACH_UNIVERSAL7420) || defined(CONFIG_SOC_EXYNOS8890) || \
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
 #if defined(CONFIG_DEFERRED_INITCALLS)
 #if defined(CONFIG_MACH_UNIVERSAL7420) || defined(CONFIG_SOC_EXYNOS8890) || \
@@ -10032,6 +10094,7 @@ module_init(dhd_module_init);
 
 module_exit(dhd_module_exit);
 
 
 module_exit(dhd_module_exit);
 
+#endif
 /*
  * OS specific functions required to implement DHD driver in OS independent way
  */
 /*
  * OS specific functions required to implement DHD driver in OS independent way
  */
@@ -12405,7 +12468,7 @@ bool dhd_os_check_hang(dhd_pub_t *dhdp, int ifidx, int ret)
        net = dhd_idx2net(dhdp, ifidx);
        if (!net) {
                DHD_ERROR(("%s : Invalid index : %d\n", __FUNCTION__, ifidx));
        net = dhd_idx2net(dhdp, ifidx);
        if (!net) {
                DHD_ERROR(("%s : Invalid index : %d\n", __FUNCTION__, ifidx));
-               return -EINVAL;
+               return FALSE;
        }
 
        return dhd_check_hang(net, dhdp, ret);
        }
 
        return dhd_check_hang(net, dhdp, ret);