From 7f386462b4b0981a9816a8cafaabd516c44502ae Mon Sep 17 00:00:00 2001 From: Dmitry Shmidt Date: Wed, 21 Mar 2012 12:35:56 -0700 Subject: [PATCH] net: wireless: bcmdhd: Add 'wlan_ctrl_wake' wakelock Signed-off-by: Dmitry Shmidt --- drivers/net/wireless/bcmdhd/dhd.h | 9 ++-- drivers/net/wireless/bcmdhd/dhd_linux.c | 71 +++++++++++++++++++------ 2 files changed, 59 insertions(+), 21 deletions(-) diff --git a/drivers/net/wireless/bcmdhd/dhd.h b/drivers/net/wireless/bcmdhd/dhd.h index 3e37e991456c..01c6c316871f 100644 --- a/drivers/net/wireless/bcmdhd/dhd.h +++ b/drivers/net/wireless/bcmdhd/dhd.h @@ -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 diff --git a/drivers/net/wireless/bcmdhd/dhd_linux.c b/drivers/net/wireless/bcmdhd/dhd_linux.c index ad30958cb7c3..a88ef0e121e9 100644 --- a/drivers/net/wireless/bcmdhd/dhd_linux.c +++ b/drivers/net/wireless/bcmdhd/dhd_linux.c @@ -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; } -- 2.34.1