net: wireless: bcmdhd: Add 'wlan_ctrl_wake' wakelock
authorDmitry Shmidt <dimitrysh@google.com>
Wed, 21 Mar 2012 19:35:56 +0000 (12:35 -0700)
committerDmitry Shmidt <dimitrysh@google.com>
Tue, 27 Mar 2012 20:52:11 +0000 (13:52 -0700)
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
drivers/net/wireless/bcmdhd/dhd.h
drivers/net/wireless/bcmdhd/dhd_linux.c

index 3e37e991456cf61953adb6c091acb4783c091601..01c6c316871ff421d3afa5992092e5d35af35e43 100644 (file)
@@ -213,9 +213,6 @@ typedef struct dhd_pub {
  *  see target dhd-cdc-sdmmc-panda-cfg80211-icsmr1-gpl-debug in Makefile
  */
 
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_HAS_WAKELOCK)
-       struct wake_lock        wakelock[WAKE_LOCK_MAX];
-#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined (CONFIG_HAS_WAKELOCK) */
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1
        struct mutex    wl_start_stop_lock; /* lock/unlock for Android start/stop */
        struct mutex    wl_softap_lock;          /* lock/unlock for any SoftAP/STA settings */
@@ -297,7 +294,8 @@ void dhd_os_spin_unlock(dhd_pub_t *pub, unsigned long flags);
 extern int dhd_os_wake_lock(dhd_pub_t *pub);
 extern int dhd_os_wake_unlock(dhd_pub_t *pub);
 extern int dhd_os_wake_lock_timeout(dhd_pub_t *pub);
-extern int dhd_os_wake_lock_timeout_enable(dhd_pub_t *pub, int val);
+extern int dhd_os_wake_lock_rx_timeout_enable(dhd_pub_t *pub, int val);
+extern int dhd_os_wake_lock_ctrl_timeout_enable(dhd_pub_t *pub, int val);
 
 inline static void MUTEX_LOCK_SOFTAP_SET_INIT(dhd_pub_t * dhdp)
 {
@@ -323,7 +321,8 @@ inline static void MUTEX_UNLOCK_SOFTAP_SET(dhd_pub_t * dhdp)
 #define DHD_OS_WAKE_LOCK(pub)                  dhd_os_wake_lock(pub)
 #define DHD_OS_WAKE_UNLOCK(pub)                dhd_os_wake_unlock(pub)
 #define DHD_OS_WAKE_LOCK_TIMEOUT(pub)          dhd_os_wake_lock_timeout(pub)
-#define DHD_OS_WAKE_LOCK_TIMEOUT_ENABLE(pub, val)      dhd_os_wake_lock_timeout_enable(pub, val)
+#define DHD_OS_WAKE_LOCK_RX_TIMEOUT_ENABLE(pub, val)   dhd_os_wake_lock_rx_timeout_enable(pub, val)
+#define DHD_OS_WAKE_LOCK_CTRL_TIMEOUT_ENABLE(pub, val) dhd_os_wake_lock_ctrl_timeout_enable(pub, val)
 
 #define DHD_PACKET_TIMEOUT_MS  1000
 #define DHD_EVENT_TIMEOUT_MS   1500
index ad30958cb7c3e615e721817f72596780d43678cb..a88ef0e121e9c4e49cdd76a94f6cfc784de67197 100644 (file)
@@ -251,6 +251,7 @@ typedef struct dhd_info {
 #if defined(CONFIG_HAS_WAKELOCK) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
        struct wake_lock wl_wifi;   /* Wifi wakelock */
        struct wake_lock wl_rxwake; /* Wifi rx wakelock */
+       struct wake_lock wl_ctrlwake; /* Wifi ctrl wakelock */
 #endif
 
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25))
@@ -262,7 +263,8 @@ typedef struct dhd_info {
 #endif
        spinlock_t wakelock_spinlock;
        int wakelock_counter;
-       int wakelock_timeout_enable;
+       int wakelock_rx_timeout_enable;
+       int wakelock_ctrl_timeout_enable;
 
        /* Thread to issue ioctl for multicast */
        bool set_macaddress;
@@ -1405,7 +1407,8 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt, uint8 chan)
        int i;
        dhd_if_t *ifp;
        wl_event_msg_t event;
-       int tout = DHD_PACKET_TIMEOUT_MS;
+       int tout_rx = 0;
+       int tout_ctrl = 0;
 
        DHD_TRACE(("%s: Enter\n", __FUNCTION__));
 
@@ -1507,12 +1510,15 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt, uint8 chan)
                        &data);
 
                        wl_event_to_host_order(&event);
-                       tout = DHD_EVENT_TIMEOUT_MS;
+                       if (!tout_ctrl)
+                               tout_ctrl = DHD_PACKET_TIMEOUT_MS;
                        if (event.event_type == WLC_E_BTA_HCI_EVENT) {
                                dhd_bta_doevt(dhdp, data, event.datalen);
                        } else if (event.event_type == WLC_E_PFN_NET_FOUND) {
-                               tout *= 2;
+                               tout_ctrl *= 2;
                        }
+               } else {
+                       tout_rx = DHD_PACKET_TIMEOUT_MS;
                }
 
                ASSERT(ifidx < DHD_MAX_IFS && dhd->iflist[ifidx]);
@@ -1545,7 +1551,8 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt, uint8 chan)
 #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) */
                }
        }
-       DHD_OS_WAKE_LOCK_TIMEOUT_ENABLE(dhdp, tout);
+       DHD_OS_WAKE_LOCK_RX_TIMEOUT_ENABLE(dhdp, tout_rx);
+       DHD_OS_WAKE_LOCK_CTRL_TIMEOUT_ENABLE(dhdp, tout_ctrl);
 }
 
 void
@@ -2044,7 +2051,7 @@ dhd_ioctl_entry(struct net_device *net, struct ifreq *ifr, int cmd)
        /* send to dongle only if we are not waiting for reload already */
        if (dhd->pub.hang_was_sent) {
                DHD_ERROR(("%s: HANG was sent up earlier\n", __FUNCTION__));
-               DHD_OS_WAKE_LOCK_TIMEOUT_ENABLE(&dhd->pub, DHD_EVENT_TIMEOUT_MS);
+               DHD_OS_WAKE_LOCK_CTRL_TIMEOUT_ENABLE(&dhd->pub, DHD_EVENT_TIMEOUT_MS);
                DHD_OS_WAKE_UNLOCK(&dhd->pub);
                return OSL_ERROR(BCME_DONGLE_DOWN);
        }
@@ -2650,10 +2657,12 @@ dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen)
        /* Initialize Wakelock stuff */
        spin_lock_init(&dhd->wakelock_spinlock);
        dhd->wakelock_counter = 0;
-       dhd->wakelock_timeout_enable = 0;
+       dhd->wakelock_rx_timeout_enable = 0;
+       dhd->wakelock_ctrl_timeout_enable = 0;
 #ifdef CONFIG_HAS_WAKELOCK
        wake_lock_init(&dhd->wl_wifi, WAKE_LOCK_SUSPEND, "wlan_wake");
        wake_lock_init(&dhd->wl_rxwake, WAKE_LOCK_SUSPEND, "wlan_rx_wake");
+       wake_lock_init(&dhd->wl_ctrlwake, WAKE_LOCK_SUSPEND, "wlan_ctrl_wake");
 #endif
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25))
        mutex_init(&dhd->dhd_net_if_mutex);
@@ -3694,6 +3703,7 @@ void dhd_detach(dhd_pub_t *dhdp)
 #ifdef CONFIG_HAS_WAKELOCK
                wake_lock_destroy(&dhd->wl_wifi);
                wake_lock_destroy(&dhd->wl_rxwake);
+               wake_lock_destroy(&dhd->wl_ctrlwake);
 #endif
        }
 }
@@ -4590,13 +4600,18 @@ int dhd_os_wake_lock_timeout(dhd_pub_t *pub)
 
        if (dhd) {
                spin_lock_irqsave(&dhd->wakelock_spinlock, flags);
-               ret = dhd->wakelock_timeout_enable;
+               ret = dhd->wakelock_rx_timeout_enable > dhd->wakelock_ctrl_timeout_enable ?
+                       dhd->wakelock_rx_timeout_enable : dhd->wakelock_ctrl_timeout_enable;
 #ifdef CONFIG_HAS_WAKELOCK
-               if (dhd->wakelock_timeout_enable)
+               if (dhd->wakelock_rx_timeout_enable)
                        wake_lock_timeout(&dhd->wl_rxwake,
-                               msecs_to_jiffies(dhd->wakelock_timeout_enable));
+                               msecs_to_jiffies(dhd->wakelock_rx_timeout_enable));
+               if (dhd->wakelock_ctrl_timeout_enable)
+                       wake_lock_timeout(&dhd->wl_ctrlwake,
+                               msecs_to_jiffies(dhd->wakelock_ctrl_timeout_enable));
 #endif
-               dhd->wakelock_timeout_enable = 0;
+               dhd->wakelock_rx_timeout_enable = 0;
+               dhd->wakelock_ctrl_timeout_enable = 0;
                spin_unlock_irqrestore(&dhd->wakelock_spinlock, flags);
        }
        return ret;
@@ -4612,27 +4627,51 @@ int net_os_wake_lock_timeout(struct net_device *dev)
        return ret;
 }
 
-int dhd_os_wake_lock_timeout_enable(dhd_pub_t *pub, int val)
+int dhd_os_wake_lock_rx_timeout_enable(dhd_pub_t *pub, int val)
+{
+       dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+       unsigned long flags;
+
+       if (dhd) {
+               spin_lock_irqsave(&dhd->wakelock_spinlock, flags);
+               if (val > dhd->wakelock_rx_timeout_enable)
+                       dhd->wakelock_rx_timeout_enable = val;
+               spin_unlock_irqrestore(&dhd->wakelock_spinlock, flags);
+       }
+       return 0;
+}
+
+int dhd_os_wake_lock_ctrl_timeout_enable(dhd_pub_t *pub, int val)
 {
        dhd_info_t *dhd = (dhd_info_t *)(pub->info);
        unsigned long flags;
 
        if (dhd) {
                spin_lock_irqsave(&dhd->wakelock_spinlock, flags);
-               if (val > dhd->wakelock_timeout_enable)
-                       dhd->wakelock_timeout_enable = val;
+               if (val > dhd->wakelock_ctrl_timeout_enable)
+                       dhd->wakelock_ctrl_timeout_enable = val;
                spin_unlock_irqrestore(&dhd->wakelock_spinlock, flags);
        }
        return 0;
 }
 
-int net_os_wake_lock_timeout_enable(struct net_device *dev, int val)
+int net_os_wake_lock_rx_timeout_enable(struct net_device *dev, int val)
+{
+       dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+       int ret = 0;
+
+       if (dhd)
+               ret = dhd_os_wake_lock_rx_timeout_enable(&dhd->pub, val);
+       return ret;
+}
+
+int net_os_wake_lock_ctrl_timeout_enable(struct net_device *dev, int val)
 {
        dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
        int ret = 0;
 
        if (dhd)
-               ret = dhd_os_wake_lock_timeout_enable(&dhd->pub, val);
+               ret = dhd_os_wake_lock_ctrl_timeout_enable(&dhd->pub, val);
        return ret;
 }