Add channal get and android wifi dormancy mechanism to bcm4329.(V2.00)
author高伟龙 <gwl@rock-chips.com>
Sat, 8 Oct 2011 02:28:13 +0000 (10:28 +0800)
committer高伟龙 <gwl@rock-chips.com>
Sat, 8 Oct 2011 02:28:13 +0000 (10:28 +0800)
drivers/net/wireless/bcm4329/dhd_linux.c
drivers/net/wireless/bcm4329/include/wifi_version.h [new file with mode: 0644]
drivers/net/wireless/bcm4329/wl_iw.c

index 622e2a9eb0b26047fa0f5d4842251d1509264e8f..d9af222f7c29710ea5bb195d6aba73c386c3f1d0 100644 (file)
@@ -47,6 +47,7 @@
 #include <asm/uaccess.h>
 #include <asm/unaligned.h>
 
+#include <wifi_version.h>
 #include <epivers.h>
 #include <bcmutils.h>
 #include <bcmendian.h>
@@ -69,6 +70,9 @@ struct semaphore wifi_control_sem;
 
 struct dhd_bus *g_bus;
 
+extern void bcm4329_power_save_exit(void);
+extern void bcm4329_power_save_init(void);
+
 static struct wifi_platform_data *wifi_control_data = NULL;
 static struct resource *wifi_irqres = NULL;
 
@@ -2528,6 +2532,7 @@ rockchip_wifi_exit_module(void)
 #endif
        /* Call customer gpio to turn off power with WL_REG_ON signal */
        dhd_customer_gpio_wlan_ctrl(WLAN_POWER_OFF);
+       bcm4329_power_save_exit();
 }
 
 int
@@ -2537,6 +2542,7 @@ rockchip_wifi_init_module(void)
 
        DHD_TRACE(("%s: Enter\n", __FUNCTION__));
 
+       printk("BCM4329 Wi-Fi driver (Powered by Rockchip,Ver %s) init.\n", BCM4329_DRV_VERSION);
        /* Sanity check on the module parameters */
        do {
                /* Both watchdog and DPC as tasklets are ok */
@@ -2595,6 +2601,8 @@ rockchip_wifi_init_module(void)
                goto fail_2;
        }
 #endif
+       bcm4329_power_save_init();
+
        return error;
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
 fail_2:
@@ -2616,7 +2624,7 @@ fail_0:
 //module_exit(dhd_module_cleanup);
 int mv88w8686_if_sdio_init_module(void)
 {
-       return rockchip_wifi_init_module();
+       return rockchip_wifi_init_module();
 }
 
 void mv88w8686_if_sdio_exit_module(void)
diff --git a/drivers/net/wireless/bcm4329/include/wifi_version.h b/drivers/net/wireless/bcm4329/include/wifi_version.h
new file mode 100644 (file)
index 0000000..e650326
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef WIFI_VERSION_H
+#define WIFI_VERSION_H
+
+/*
+ * Broadcom BCM4329 driver version.
+ */
+#define BCM4329_DRV_VERSION "2.00"
+
+#endif /* WIFI_BCM4329_VERSION_H */
index 8460804c945ad46b346ef981a895c1cf52bc9440..146dffd529764dab9e4257b9d633146e12cc6ca6 100644 (file)
@@ -57,7 +57,7 @@ typedef const struct si_pub  si_t;
 #define WL_TRACE_COEX(x)
 
 #include <wl_iw.h>
-
+#include <linux/wakelock.h>
 
 
 #ifndef IW_ENCODE_ALG_SM4
@@ -684,6 +684,33 @@ exit:
        return error;
 }
 
+static int
+wl_iw_get_country(
+        struct net_device *dev,
+        struct iw_request_info *info,
+        union iwreq_data *wrqu,
+        char *extra
+)
+{
+       char *ccode;
+       int current_channels;
+       
+       WL_TRACE(("%s\n", __FUNCTION__));
+
+       ccode = dhd_bus_country_get(dev);
+       if(ccode){
+               if(0 == strcmp(ccode, "Q2"))
+                       current_channels = 11;
+               else if(0 == strcmp(ccode, "EU"))
+                       current_channels = 13;
+               else if(0 == strcmp(ccode, "JP"))
+                       current_channels = 14;
+       }
+       sprintf(extra, "Scan-Channels = %d", current_channels);
+       printk("Get Channels return %d,(country code = %s)\n",current_channels, ccode); 
+       return 0;
+}
+
 #ifdef CUSTOMER_HW2
 static int
 wl_iw_set_power_mode(
@@ -7045,6 +7072,30 @@ int wl_iw_process_private_ascii_cmd(
 }
 #endif
 
+#define BCM4329_WAKELOCK_NAME "bcm4329_wifi_wakelock"
+
+static struct wake_lock bcm4329_suspend_lock;
+
+int bcm4329_wakelock_init = 0;
+
+void bcm4329_power_save_init(void)
+{
+        wake_lock_init(&bcm4329_suspend_lock, WAKE_LOCK_SUSPEND, BCM4329_WAKELOCK_NAME);
+        wake_lock(&bcm4329_suspend_lock);
+        
+       bcm4329_wakelock_init = 2;
+}
+
+void bcm4329_power_save_exit(void)
+{
+        bcm4329_wakelock_init = 0;
+        msleep(100);
+        
+       if (bcm4329_wakelock_init == 2)
+                wake_unlock(&bcm4329_suspend_lock);
+        wake_lock_destroy(&bcm4329_suspend_lock);
+}
+
 static int wl_iw_set_priv(
        struct net_device *dev,
        struct iw_request_info *info,
@@ -7070,6 +7121,11 @@ static int wl_iw_set_priv(
        
        if (dwrq->length && extra) {
                if (strnicmp(extra, "START", strlen("START")) == 0) {
+                       if (bcm4329_wakelock_init == 1)
+                        {
+                                wake_lock(&bcm4329_suspend_lock);
+                                bcm4329_wakelock_init = 2;
+                        }
                        wl_iw_control_wl_on(dev, info);
                        WL_TRACE(("%s, Received regular START command\n", __FUNCTION__));
                }
@@ -7101,8 +7157,16 @@ static int wl_iw_set_priv(
                        ret = wl_iw_get_macaddr(dev, info, (union iwreq_data *)dwrq, extra);
                else if (strnicmp(extra, "COUNTRY", strlen("COUNTRY")) == 0)
                        ret = wl_iw_set_country(dev, info, (union iwreq_data *)dwrq, extra);
-               else if (strnicmp(extra, "STOP", strlen("STOP")) == 0)
+               else if (strnicmp(extra, "SCAN-CHANNELS", strlen("SCAN-CHANNELS")) == 0)
+                       ret = wl_iw_get_country(dev, info, (union iwreq_data *)dwrq, extra);
+               else if (strnicmp(extra, "STOP", strlen("STOP")) == 0){
                        ret = wl_iw_control_wl_off(dev, info);
+                       if (bcm4329_wakelock_init == 2)
+                        {
+                                wake_unlock(&bcm4329_suspend_lock);
+                                bcm4329_wakelock_init = 1;
+                        }
+               }
                else if (strnicmp(extra, BAND_GET_CMD, strlen(BAND_GET_CMD)) == 0)
                        ret = wl_iw_get_band(dev, info, (union iwreq_data *)dwrq, extra);
                else if (strnicmp(extra, BAND_SET_CMD, strlen(BAND_SET_CMD)) == 0)