summaryrefslogtreecommitdiffstats
path: root/bcm4329/src/dhd/sys
diff options
context:
space:
mode:
Diffstat (limited to 'bcm4329/src/dhd/sys')
-rw-r--r--bcm4329/src/dhd/sys/dhd.h54
-rw-r--r--bcm4329/src/dhd/sys/dhd_bus.h2
-rw-r--r--bcm4329/src/dhd/sys/dhd_cdc.c7
-rw-r--r--bcm4329/src/dhd/sys/dhd_common.c31
-rw-r--r--bcm4329/src/dhd/sys/dhd_custom_gpio.c24
-rw-r--r--bcm4329/src/dhd/sys/dhd_dbg.h2
-rw-r--r--bcm4329/src/dhd/sys/dhd_linux.c410
-rw-r--r--bcm4329/src/dhd/sys/dhd_linux_sched.c2
-rw-r--r--bcm4329/src/dhd/sys/dhd_proto.h2
-rw-r--r--bcm4329/src/dhd/sys/dhd_sdio.c15
10 files changed, 313 insertions, 236 deletions
diff --git a/bcm4329/src/dhd/sys/dhd.h b/bcm4329/src/dhd/sys/dhd.h
index faf016f..8aa33b3 100644
--- a/bcm4329/src/dhd/sys/dhd.h
+++ b/bcm4329/src/dhd/sys/dhd.h
@@ -24,7 +24,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: dhd.h,v 1.32.4.7.2.4.14.29 2010/02/23 06:58:21 Exp $
+ * $Id: dhd.h,v 1.32.4.7.2.4.14.27 2010/01/19 06:42:55 Exp $
*/
/****************
@@ -46,9 +46,7 @@
#include <linux/ethtool.h>
#include <asm/uaccess.h>
#include <asm/unaligned.h>
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_HAS_WAKELOCK)
-#include <linux/wakelock.h>
-#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined (CONFIG_HAS_WAKELOCK) */
+
/* The kernel threading is sdio-specific */
#else /* LINUX */
#define ENOMEM 1
@@ -149,9 +147,6 @@ typedef struct dhd_pub {
int dongle_error;
uint8 country_code[WLC_CNTRY_BUF_SZ];
-#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) */
} dhd_pub_t;
#if defined(NDIS60)
@@ -171,7 +166,7 @@ WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(wdf_device_info_t, dhd_get_wdf_device_info)
#define _DHD_PM_RESUME_WAIT(a, b) do {\
int retry = 0; \
while (dhd_mmc_suspend && retry++ != b) { \
- wait_event_timeout(a, FALSE, HZ/100); \
+ wait_event_interruptible_timeout(a, FALSE, HZ/100); \
} \
} while (0)
#define DHD_PM_RESUME_WAIT(a) _DHD_PM_RESUME_WAIT(a, 30)
@@ -183,7 +178,7 @@ WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(wdf_device_info_t, dhd_get_wdf_device_info)
#define SPINWAIT_SLEEP(a, exp, us) do { \
uint countdown = (us) + 9; \
while ((exp) && (countdown >= 10)) { \
- wait_event_timeout(a, FALSE, HZ/100); \
+ wait_event_interruptible_timeout(a, FALSE, HZ/100); \
countdown -= 10; \
} \
} while (0)
@@ -208,41 +203,11 @@ WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(wdf_device_info_t, dhd_get_wdf_device_info)
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) */
#define DHD_IF_VIF 0x01 /* Virtual IF (Hidden from user) */
-inline static void WAKE_LOCK_INIT(dhd_pub_t * dhdp, int index, char * y)
-{
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_HAS_WAKELOCK)
- wake_lock_init(&dhdp->wakelock[index], WAKE_LOCK_SUSPEND, y);
-#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined (CONFIG_HAS_WAKELOCK) */
-}
-
-inline static void WAKE_LOCK(dhd_pub_t * dhdp, int index)
-{
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_HAS_WAKELOCK)
- wake_lock(&dhdp->wakelock[index]);
-#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined (CONFIG_HAS_WAKELOCK) */
-}
-
-inline static void WAKE_UNLOCK(dhd_pub_t * dhdp, int index)
-{
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_HAS_WAKELOCK)
- wake_unlock(&dhdp->wakelock[index]);
-#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined (CONFIG_HAS_WAKELOCK) */
-}
-
-inline static void WAKE_LOCK_TIMEOUT(dhd_pub_t * dhdp, int index, long time)
-{
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_HAS_WAKELOCK)
- wake_lock_timeout(&dhdp->wakelock[index], time);
-#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined (CONFIG_HAS_WAKELOCK) */
-}
-
-inline static void WAKE_LOCK_DESTROY(dhd_pub_t * dhdp, int index)
-{
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_HAS_WAKELOCK)
- wake_lock_destroy(&dhdp->wakelock[index]);
-#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined (CONFIG_HAS_WAKELOCK) */
-}
-
+/* Wakelock Functions */
+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);
typedef struct dhd_if_event {
uint8 ifidx;
@@ -358,7 +323,6 @@ extern int dhd_bus_devreset(dhd_pub_t *dhdp, uint8 flag);
extern uint dhd_bus_status(dhd_pub_t *dhdp);
extern int dhd_bus_start(dhd_pub_t *dhdp);
-extern void print_buf(void *pbuf, int len, int bytes_per_line);
typedef enum cust_gpio_modes {
diff --git a/bcm4329/src/dhd/sys/dhd_bus.h b/bcm4329/src/dhd/sys/dhd_bus.h
index 7156543..93392f9 100644
--- a/bcm4329/src/dhd/sys/dhd_bus.h
+++ b/bcm4329/src/dhd/sys/dhd_bus.h
@@ -4,7 +4,7 @@
* Provides type definitions and function prototypes used to link the
* DHD OS, bus, and protocol modules.
*
- * Copyright (C) 1999-2010, Broadcom Corporation
+ * Copyright (C) 1999-2009, Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
diff --git a/bcm4329/src/dhd/sys/dhd_cdc.c b/bcm4329/src/dhd/sys/dhd_cdc.c
index 77da0ea..43b21c3 100644
--- a/bcm4329/src/dhd/sys/dhd_cdc.c
+++ b/bcm4329/src/dhd/sys/dhd_cdc.c
@@ -73,9 +73,12 @@ dhdcdc_msg(dhd_pub_t *dhd)
{
dhd_prot_t *prot = dhd->prot;
int len = ltoh32(prot->msg.len) + sizeof(cdc_ioctl_t);
+ int ret;
DHD_TRACE(("%s: Enter\n", __FUNCTION__));
+ dhd_os_wake_lock(dhd);
+
/* NOTE : cdc->msg.len holds the desired length of the buffer to be
* returned. Only up to CDC_MAX_MSG_SIZE of this buffer area
* is actually sent to the dongle
@@ -84,7 +87,9 @@ dhdcdc_msg(dhd_pub_t *dhd)
len = CDC_MAX_MSG_SIZE;
/* Send request */
- return dhd_bus_txctl(dhd->bus, (uchar*)&prot->msg, len);
+ ret = dhd_bus_txctl(dhd->bus, (uchar*)&prot->msg, len);
+ dhd_os_wake_unlock(dhd);
+ return ret;
}
static int
diff --git a/bcm4329/src/dhd/sys/dhd_common.c b/bcm4329/src/dhd/sys/dhd_common.c
index ae0c3fb..9dc7113 100644
--- a/bcm4329/src/dhd/sys/dhd_common.c
+++ b/bcm4329/src/dhd/sys/dhd_common.c
@@ -101,8 +101,16 @@ dhd_common_init(void)
* first time that the driver is initialized vs subsequent initializations.
*/
dhd_msg_level = DHD_ERROR_VAL;
+#ifdef CONFIG_BCM4329_FW_PATH
+ strncpy(fw_path, CONFIG_BCM4329_FW_PATH, MOD_PARAM_PATHLEN-1);
+#else
fw_path[0] = '\0';
+#endif
+#ifdef CONFIG_BCM4329_NVRAM_PATH
+ strncpy(nv_path, CONFIG_BCM4329_NVRAM_PATH, MOD_PARAM_PATHLEN-1);
+#else
nv_path[0] = '\0';
+#endif
}
static int
@@ -189,7 +197,6 @@ dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, uint32 actionid, const ch
dhd_msg_level = int_val;
break;
-
case IOV_GVAL(IOV_BCMERRORSTR):
strncpy((char *)arg, bcmerrorstr(dhd_pub->bcmerror), BCME_STRLEN);
((char *)arg)[BCME_STRLEN - 1] = 0x00;
@@ -886,25 +893,3 @@ wl_event_to_host_order(wl_event_msg_t *evt)
evt->datalen = ntoh32(evt->datalen);
evt->version = ntoh16(evt->version);
}
-
-void print_buf(void *pbuf, int len, int bytes_per_line)
-{
- int i, j = 0;
- unsigned char *buf = pbuf;
-
- if (bytes_per_line == 0) {
- bytes_per_line = len;
- }
-
- for (i = 0; i < len; i++) {
- printf("%2.2x", *buf++);
- j++;
- if (j == bytes_per_line) {
- printf("\n");
- j = 0;
- } else {
- printf(":");
- }
- }
- printf("\n");
-}
diff --git a/bcm4329/src/dhd/sys/dhd_custom_gpio.c b/bcm4329/src/dhd/sys/dhd_custom_gpio.c
index cb67ae2..2dc6e42 100644
--- a/bcm4329/src/dhd/sys/dhd_custom_gpio.c
+++ b/bcm4329/src/dhd/sys/dhd_custom_gpio.c
@@ -42,6 +42,7 @@
extern void bcm_wlan_power_off(int);
extern void bcm_wlan_power_on(int);
#endif /* CUSTOMER_HW */
+
#ifdef CUSTOMER_HW2
int wifi_set_carddetect(int on);
int wifi_set_power(int on, unsigned long msec);
@@ -54,10 +55,6 @@ int wifi_get_irq_number(unsigned long *irq_flags_ptr);
extern int sdioh_mmc_irq(int irq);
#endif /* (BCMLXSDMMC) */
-#ifdef CUSTOMER_HW3
-#include <mach/gpio.h>
-#endif
-
/* Customer specific Host GPIO defintion */
static int dhd_oob_gpio_num = -1; /* GG 19 */
@@ -66,12 +63,10 @@ MODULE_PARM_DESC(dhd_oob_gpio_num, "DHD oob gpio number");
int dhd_customer_oob_irq_map(unsigned long *irq_flags_ptr)
{
- int host_oob_irq = 0;
-
+ int host_oob_irq;
#ifdef CUSTOMER_HW2
host_oob_irq = wifi_get_irq_number(irq_flags_ptr);
-
-#else /* for NOT CUSTOMER_HW2 */
+#else
#if defined(CUSTOM_OOB_GPIO_NUM)
if (dhd_oob_gpio_num < 0) {
dhd_oob_gpio_num = CUSTOM_OOB_GPIO_NUM;
@@ -80,22 +75,15 @@ int dhd_customer_oob_irq_map(unsigned long *irq_flags_ptr)
*irq_flags_ptr = IRQF_TRIGGER_FALLING;
if (dhd_oob_gpio_num < 0) {
WL_ERROR(("%s: ERROR customer specific Host GPIO is NOT defined \n",
- __FUNCTION__));
+ __FUNCTION__));
return (dhd_oob_gpio_num);
}
WL_ERROR(("%s: customer specific Host GPIO number is (%d)\n",
__FUNCTION__, dhd_oob_gpio_num));
-#if defined CUSTOMER_HW
- host_oob_irq = MSM_GPIO_TO_INT(dhd_oob_gpio_num);
-#elif defined CUSTOMER_HW3
- gpio_request(dhd_oob_gpio_num, "oob irq");
- host_oob_irq = gpio_to_irq(dhd_oob_gpio_num);
- gpio_direction_input(dhd_oob_gpio_num);
-#endif /* CUSTOMER_HW */
-#endif /* CUSTOMER_HW2 */
-
+ host_oob_irq = sdioh_mmc_irq(dhd_oob_gpio_num);
+#endif
return (host_oob_irq);
}
#endif /* defined(OOB_INTR_ONLY) */
diff --git a/bcm4329/src/dhd/sys/dhd_dbg.h b/bcm4329/src/dhd/sys/dhd_dbg.h
index 852f3c2..e6d18f7 100644
--- a/bcm4329/src/dhd/sys/dhd_dbg.h
+++ b/bcm4329/src/dhd/sys/dhd_dbg.h
@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: dhd_dbg.h,v 1.5.6.2.4.2.14.6 2010/02/23 05:36:53 Exp $
+ * $Id: dhd_dbg.h,v 1.5.6.2.4.2.14.4 2009/12/11 01:13:49 Exp $
*/
#ifndef _dhd_dbg_
diff --git a/bcm4329/src/dhd/sys/dhd_linux.c b/bcm4329/src/dhd/sys/dhd_linux.c
index 38a1a11..ef529e7 100644
--- a/bcm4329/src/dhd/sys/dhd_linux.c
+++ b/bcm4329/src/dhd/sys/dhd_linux.c
@@ -22,7 +22,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: dhd_linux.c,v 1.65.4.9.2.12.2.60.4.1 2010/03/16 03:29:40 Exp $
+ * $Id: dhd_linux.c,v 1.65.4.9.2.12.2.60 2010/02/23 00:18:36 Exp $
*/
#ifdef CONFIG_WIFI_CONTROL_FUNC
@@ -57,6 +57,11 @@
#include <dhd_bus.h>
#include <dhd_proto.h>
#include <dhd_dbg.h>
+#include <wl_iw.h>
+#ifdef CONFIG_HAS_WAKELOCK
+#include <linux/wakelock.h>
+#endif
+#include <linux/freezer.h>
#if defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC)
#include <linux/wifi_tiwlan.h>
@@ -110,12 +115,13 @@ int wifi_set_reset(int on, unsigned long msec)
mdelay(msec);
return 0;
}
+
static int wifi_probe(struct platform_device *pdev)
{
struct wifi_platform_data *wifi_ctrl =
(struct wifi_platform_data *)(pdev->dev.platform_data);
- printk("## %s\n", __FUNCTION__);
+ DHD_TRACE(("## %s\n", __FUNCTION__));
wifi_irqres = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "bcm4329_wlan_irq");
wifi_control_data = wifi_ctrl;
@@ -131,7 +137,7 @@ static int wifi_remove(struct platform_device *pdev)
struct wifi_platform_data *wifi_ctrl =
(struct wifi_platform_data *)(pdev->dev.platform_data);
- printk("## %s\n", __FUNCTION__);
+ DHD_TRACE(("## %s\n", __FUNCTION__));
wifi_control_data = wifi_ctrl;
wifi_set_carddetect(0); /* CardDetect (1->0) */
@@ -148,7 +154,7 @@ static int wifi_suspend(struct platform_device *pdev, pm_message_t state)
static int wifi_resume(struct platform_device *pdev)
{
DHD_TRACE(("##> %s\n", __FUNCTION__));
- return 0;
+ return 0;
}
static struct platform_driver wifi_device = {
@@ -248,6 +254,15 @@ typedef struct dhd_info {
struct semaphore dpc_sem;
struct completion dpc_exited;
+ /* Wakelocks */
+#ifdef CONFIG_HAS_WAKELOCK
+ struct wake_lock wl_wifi; /* Wifi wakelock */
+ struct wake_lock wl_rxwake; /* Wifi rx wakelock */
+#endif
+ spinlock_t wl_lock;
+ int wl_count;
+ int wl_packet;
+
/* Thread to issue ioctl for multicast */
long sysioc_pid;
struct semaphore sysioc_sem;
@@ -271,7 +286,6 @@ char nvram_path[MOD_PARAM_PATHLEN];
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && 1
struct semaphore dhd_registration_sem;
-#define DHD_REGISTRATION_TIMEOUT 8000 /* msec : allowed time to finished dhd registration */
#endif
/* load firmware and/or nvram values from the filesystem */
module_param_string(firmware_path, firmware_path, MOD_PARAM_PATHLEN, 0);
@@ -759,7 +773,7 @@ dhd_op_if(dhd_if_t *ifp)
break;
case WLC_E_IF_DEL:
if (ifp->net != NULL) {
- DHD_TRACE(("\n%s: got 'WLC_E_IF_DEL' state\n", __FUNCTION__));
+ DHD_TRACE(("\n%s: got 'WLC_E_IF_DEL' state\n", __FUNCTION__));
netif_stop_queue(ifp->net);
unregister_netdev(ifp->net);
ret = DHD_DEL_IF; /* Make sure the free_netdev() is called */
@@ -771,23 +785,17 @@ dhd_op_if(dhd_if_t *ifp)
break;
}
-
if (ret < 0) {
-
if (ifp->net) {
-
free_netdev(ifp->net);
}
-
dhd->iflist[ifp->idx] = NULL;
MFREE(dhd->pub.osh, ifp, sizeof(*ifp));
-
#ifdef SOFTAP
if (ifp->net == ap_net_dev)
- ap_net_dev = NULL; /* NULL SOFTAP global wl0.1 as well */
+ ap_net_dev = NULL; /* NULL SOFTAP global as well */
#endif /* SOFTAP */
}
-
}
static int
@@ -796,9 +804,12 @@ _dhd_sysioc_thread(void *data)
dhd_info_t *dhd = (dhd_info_t *)data;
int i;
+ set_freezable();
+
DAEMONIZE("dhd_sysioc");
while (down_interruptible(&dhd->sysioc_sem) == 0) {
+ dhd_os_wake_lock(&dhd->pub);
for (i = 0; i < DHD_MAX_IFS; i++) {
if (dhd->iflist[i]) {
if (dhd->iflist[i]->state)
@@ -813,6 +824,7 @@ _dhd_sysioc_thread(void *data)
}
}
}
+ dhd_os_wake_unlock(&dhd->pub);
}
complete_and_exit(&dhd->sysioc_exited, 0);
}
@@ -886,7 +898,6 @@ dhd_sendpkt(dhd_pub_t *dhdp, int ifidx, void *pktbuf)
#ifdef BCMDBUS
ret = dbus_send_pkt(dhdp->dbus, pktbuf, NULL /* pktinfo */);
#else
- WAKE_LOCK_TIMEOUT(dhdp, WAKE_LOCK_TMOUT, 25);
ret = dhd_bus_txdata(dhdp->bus, pktbuf);
#endif /* BCMDBUS */
@@ -906,6 +917,7 @@ dhd_start_xmit(struct sk_buff *skb, struct net_device *net)
/* Reject if down */
if (!dhd->pub.up || (dhd->pub.busstate == DHD_BUS_DOWN)) {
DHD_ERROR(("%s: xmit rejected due to dhd bus down status \n", __FUNCTION__));
+ netif_stop_queue(net);
return -ENODEV;
}
@@ -1066,6 +1078,7 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt)
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) */
}
}
+ dhd_os_wake_lock_timeout_enable(dhdp);
}
void
@@ -1132,7 +1145,6 @@ static int
dhd_watchdog_thread(void *data)
{
dhd_info_t *dhd = (dhd_info_t *)data;
- WAKE_LOCK_INIT(&dhd->pub, WAKE_LOCK_WATCHDOG, "dhd_watchdog_thread");
/* This thread doesn't need any user-level access,
* so get rid of all our resources
@@ -1146,17 +1158,17 @@ dhd_watchdog_thread(void *data)
}
#endif /* DHD_SCHED */
+ set_freezable();
+
DAEMONIZE("dhd_watchdog");
/* Run until signal received */
while (1) {
if (down_interruptible (&dhd->watchdog_sem) == 0) {
- if (dhd->pub.dongle_reset == FALSE) {
- WAKE_LOCK(&dhd->pub, WAKE_LOCK_WATCHDOG);
- /* Call the bus module watchdog */
- dhd_bus_watchdog(&dhd->pub);
- WAKE_UNLOCK(&dhd->pub, WAKE_LOCK_WATCHDOG);
- }
+ dhd_os_wake_lock(&dhd->pub);
+ /* Call the bus module watchdog */
+ dhd_bus_watchdog(&dhd->pub);
+
/* Count the tick for reference */
dhd->pub.tickcnt++;
@@ -1164,12 +1176,12 @@ dhd_watchdog_thread(void *data)
if (dhd->wd_timer_valid) {
mod_timer(&dhd->timer, jiffies + dhd_watchdog_ms * HZ / 1000);
}
+ dhd_os_wake_unlock(&dhd->pub);
}
else
break;
}
- WAKE_LOCK_DESTROY(&dhd->pub, WAKE_LOCK_WATCHDOG);
complete_and_exit(&dhd->watchdog_exited, 0);
}
@@ -1190,8 +1202,12 @@ dhd_watchdog(ulong data)
dhd->pub.tickcnt++;
/* Reschedule the watchdog */
+#if defined(CONTINUOUS_WATCHDOG)
+ mod_timer(&dhd->timer, jiffies + dhd_watchdog_ms * HZ / 1000);
+#else
if (dhd->wd_timer_valid)
mod_timer(&dhd->timer, jiffies + dhd_watchdog_ms * HZ / 1000);
+#endif /* defined(CONTINUOUS_WATCHDOG) */
}
static int
@@ -1199,7 +1215,6 @@ dhd_dpc_thread(void *data)
{
dhd_info_t *dhd = (dhd_info_t *)data;
- WAKE_LOCK_INIT(&dhd->pub, WAKE_LOCK_DPC, "dhd_dpc_thread");
/* This thread doesn't need any user-level access,
* so get rid of all our resources
*/
@@ -1212,6 +1227,8 @@ dhd_dpc_thread(void *data)
}
#endif /* DHD_SCHED */
+ set_freezable();
+
DAEMONIZE("dhd_dpc");
/* Run until signal received */
@@ -1219,22 +1236,21 @@ dhd_dpc_thread(void *data)
if (down_interruptible(&dhd->dpc_sem) == 0) {
/* Call bus dpc unless it indicated down (then clean stop) */
if (dhd->pub.busstate != DHD_BUS_DOWN) {
- WAKE_LOCK(&dhd->pub, WAKE_LOCK_DPC);
if (dhd_bus_dpc(dhd->pub.bus)) {
up(&dhd->dpc_sem);
- WAKE_LOCK_TIMEOUT(&dhd->pub, WAKE_LOCK_TMOUT, 25);
}
- WAKE_UNLOCK(&dhd->pub, WAKE_LOCK_DPC);
+ else {
+ dhd_os_wake_unlock(&dhd->pub);
+ }
} else {
dhd_bus_stop(dhd->pub.bus, TRUE);
+ dhd_os_wake_unlock(&dhd->pub);
}
}
else
break;
}
- WAKE_LOCK_DESTROY(&dhd->pub, WAKE_LOCK_DPC);
-
complete_and_exit(&dhd->dpc_exited, 0);
}
@@ -1259,6 +1275,7 @@ dhd_sched_dpc(dhd_pub_t *dhdp)
{
dhd_info_t *dhd = (dhd_info_t *)dhdp->info;
+ dhd_os_wake_lock(dhdp);
if (dhd->dpc_pid >= 0) {
up(&dhd->dpc_sem);
return;
@@ -1575,13 +1592,9 @@ dhd_ioctl_entry(struct net_device *net, struct ifreq *ifr, int cmd)
if (is_set_key_cmd) {
dhd_wait_pend8021x(net);
}
- WAKE_LOCK_INIT(&dhd->pub, WAKE_LOCK_IOCTL, "dhd_ioctl_entry");
- WAKE_LOCK(&dhd->pub, WAKE_LOCK_IOCTL);
bcmerror = dhd_prot_ioctl(&dhd->pub, ifidx, (wl_ioctl_t *)&ioc, buf, buflen);
- WAKE_UNLOCK(&dhd->pub, WAKE_LOCK_IOCTL);
- WAKE_LOCK_DESTROY(&dhd->pub, WAKE_LOCK_IOCTL);
done:
if (!bcmerror && buf && ioc.buf) {
if (copy_to_user(ioc.buf, buf, buflen))
@@ -1626,6 +1639,8 @@ dhd_open(struct net_device *net)
#endif
int ifidx;
+ wl_control_wl_start(net); /* start if needed */
+
ifidx = dhd_net2idx(dhd, net);
DHD_TRACE(("%s: ifidx %d\n", __FUNCTION__, ifidx));
@@ -1772,11 +1787,12 @@ dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen)
if (dhd_add_if(dhd, 0, (void *)net, net->name, NULL, 0, 0) == DHD_BAD_IF)
goto fail;
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31))
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 31))
net->open = NULL;
#else
net->netdev_ops = NULL;
#endif
+
init_MUTEX(&dhd->proto_sem);
/* Initialize other structure content */
init_waitqueue_head(&dhd->ioctl_resp_wait);
@@ -1786,6 +1802,15 @@ dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen)
spin_lock_init(&dhd->sdlock);
spin_lock_init(&dhd->txqlock);
+ /* Initialize Wakelock stuff */
+ spin_lock_init(&dhd->wl_lock);
+ dhd->wl_count = 0;
+ dhd->wl_packet = 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");
+#endif
+
/* Link to info module */
dhd->pub.info = dhd;
@@ -1859,9 +1884,6 @@ dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen)
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP)
register_pm_notifier(&dhd_sleep_pm_notifier);
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) */
- /* Init lock suspend to prevent kernel going to suspend */
- WAKE_LOCK_INIT(&dhd->pub, WAKE_LOCK_TMOUT, "dhd_wake_lock");
- WAKE_LOCK_INIT(&dhd->pub, WAKE_LOCK_LINK_DOWN_TMOUT, "dhd_wake_lock_link_dw_event");
#ifdef CONFIG_HAS_EARLYSUSPEND
dhd->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 20;
@@ -1894,19 +1916,12 @@ dhd_bus_start(dhd_pub_t *dhdp)
/* try to download image and nvram to the dongle */
if (dhd->pub.busstate == DHD_BUS_DOWN) {
- WAKE_LOCK_INIT(dhdp, WAKE_LOCK_DOWNLOAD, "dhd_bus_start");
- WAKE_LOCK(dhdp, WAKE_LOCK_DOWNLOAD);
if (!(dhd_bus_download_firmware(dhd->pub.bus, dhd->pub.osh,
fw_path, nv_path))) {
DHD_ERROR(("%s: dhdsdio_probe_download failed. firmware = %s nvram = %s\n",
__FUNCTION__, fw_path, nv_path));
- WAKE_UNLOCK(dhdp, WAKE_LOCK_DOWNLOAD);
- WAKE_LOCK_DESTROY(dhdp, WAKE_LOCK_DOWNLOAD);
return -1;
}
-
- WAKE_UNLOCK(dhdp, WAKE_LOCK_DOWNLOAD);
- WAKE_LOCK_DESTROY(dhdp, WAKE_LOCK_DOWNLOAD);
}
/* Start the watchdog timer */
@@ -1921,7 +1936,7 @@ dhd_bus_start(dhd_pub_t *dhdp)
#if defined(OOB_INTR_ONLY)
/* Host registration for OOB interrupt */
if (bcmsdh_register_oob_intr(dhdp)) {
- del_timer(&dhd->timer);
+ del_timer_sync(&dhd->timer);
dhd->wd_timer_valid = FALSE;
DHD_ERROR(("%s Host failed to resgister for OOB\n", __FUNCTION__));
return -ENODEV;
@@ -1933,7 +1948,7 @@ dhd_bus_start(dhd_pub_t *dhdp)
/* If bus is not ready, can't come up */
if (dhd->pub.busstate != DHD_BUS_DATA) {
- del_timer(&dhd->timer);
+ del_timer_sync(&dhd->timer);
dhd->wd_timer_valid = FALSE;
DHD_ERROR(("%s failed bus is not ready\n", __FUNCTION__));
return -ENODEV;
@@ -1970,7 +1985,7 @@ dhd_iovar(dhd_pub_t *pub, int ifidx, char *name, char *cmd_buf, uint cmd_len, in
return ret;
}
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31))
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 31))
static struct net_device_ops dhd_ops_pri = {
.ndo_open = dhd_open,
.ndo_stop = dhd_stop,
@@ -1978,7 +1993,7 @@ static struct net_device_ops dhd_ops_pri = {
.ndo_do_ioctl = dhd_ioctl_entry,
.ndo_start_xmit = dhd_start_xmit,
.ndo_set_mac_address = dhd_set_mac_address,
- .ndo_set_multicast_list = dhd_set_multicast_list
+ .ndo_set_multicast_list = dhd_set_multicast_list,
};
static struct net_device_ops dhd_ops_virt = {
@@ -1986,9 +2001,10 @@ static struct net_device_ops dhd_ops_virt = {
.ndo_do_ioctl = dhd_ioctl_entry,
.ndo_start_xmit = dhd_start_xmit,
.ndo_set_mac_address = dhd_set_mac_address,
- .ndo_set_multicast_list = dhd_set_multicast_list
+ .ndo_set_multicast_list = dhd_set_multicast_list,
};
-#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)) */
+#endif
+
int
dhd_net_attach(dhd_pub_t *dhdp, int ifidx)
{
@@ -1999,11 +2015,10 @@ dhd_net_attach(dhd_pub_t *dhdp, int ifidx)
DHD_TRACE(("%s: ifidx %d\n", __FUNCTION__, ifidx));
ASSERT(dhd && dhd->iflist[ifidx]);
-
net = dhd->iflist[ifidx]->net;
- ASSERT(net);
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31))
+ ASSERT(net);
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 31))
ASSERT(!net->open);
net->get_stats = dhd_get_stats;
net->do_ioctl = dhd_ioctl_entry;
@@ -2021,7 +2036,7 @@ dhd_net_attach(dhd_pub_t *dhdp, int ifidx)
/*
* device functions for the primary interface only
*/
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31))
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 31))
net->open = dhd_open;
net->stop = dhd_stop;
#else
@@ -2047,7 +2062,6 @@ dhd_net_attach(dhd_pub_t *dhdp, int ifidx)
#endif /* WIRELESS_EXT > 12 */
#endif /* CONFIG_WIRELESS_EXT */
-
dhd->pub.rxsz = net->mtu + net->hard_header_len + dhd->pub.hdrlen;
memcpy(net->dev_addr, temp_addr, ETHER_ADDR_LEN);
@@ -2062,13 +2076,13 @@ dhd_net_attach(dhd_pub_t *dhdp, int ifidx)
dhd->pub.mac.octet[3], dhd->pub.mac.octet[4], dhd->pub.mac.octet[5]);
wl_iw_iscan_set_scan_broadcast_prep(net, 1);
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && 1
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
up(&dhd_registration_sem);
#endif
return 0;
fail:
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31)
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 31))
net->open = NULL;
#else
net->netdev_ops = NULL;
@@ -2096,7 +2110,7 @@ dhd_bus_detach(dhd_pub_t *dhdp)
#endif /* defined(OOB_INTR_ONLY) */
/* Clear the watchdog timer */
- del_timer(&dhd->timer);
+ del_timer_sync(&dhd->timer);
dhd->wd_timer_valid = FALSE;
}
}
@@ -2118,6 +2132,14 @@ dhd_detach(dhd_pub_t *dhdp)
#if defined(CONFIG_HAS_EARLYSUSPEND)
unregister_early_suspend(&dhd->early_suspend);
#endif /* defined(CONFIG_HAS_EARLYSUSPEND) */
+#ifdef CONFIG_WIRELESS_EXT
+ /* Attach and link in the iw */
+ wl_iw_detach();
+#endif
+ if (dhd->sysioc_pid >= 0) {
+ KILL_PROC(dhd->sysioc_pid, SIGTERM);
+ wait_for_completion(&dhd->sysioc_exited);
+ }
for (i = 1; i < DHD_MAX_IFS; i++)
if (dhd->iflist[i])
@@ -2125,7 +2147,7 @@ dhd_detach(dhd_pub_t *dhdp)
ifp = dhd->iflist[0];
ASSERT(ifp);
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31))
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 31))
if (ifp->net->open) {
#else
if (ifp->net->netdev_ops == &dhd_ops_pri) {
@@ -2134,61 +2156,39 @@ dhd_detach(dhd_pub_t *dhdp)
unregister_netdev(ifp->net);
}
+ if (dhd->watchdog_pid >= 0)
+ {
+ KILL_PROC(dhd->watchdog_pid, SIGTERM);
+ wait_for_completion(&dhd->watchdog_exited);
+ }
- if (dhd->watchdog_pid >= 0)
- {
- KILL_PROC(dhd->watchdog_pid, SIGTERM);
- wait_for_completion(&dhd->watchdog_exited);
- }
-
- if (dhd->dpc_pid >= 0)
- {
- KILL_PROC(dhd->dpc_pid, SIGTERM);
- wait_for_completion(&dhd->dpc_exited);
- }
- else
- tasklet_kill(&dhd->tasklet);
-
- if (dhd->sysioc_pid >= 0) {
- KILL_PROC(dhd->sysioc_pid, SIGTERM);
- wait_for_completion(&dhd->sysioc_exited);
- }
-
- dhd_bus_detach(dhdp);
+ if (dhd->dpc_pid >= 0)
+ {
+ KILL_PROC(dhd->dpc_pid, SIGTERM);
+ wait_for_completion(&dhd->dpc_exited);
+ }
+ else
+ tasklet_kill(&dhd->tasklet);
- if (dhdp->prot)
- dhd_prot_detach(dhdp);
+ dhd_bus_detach(dhdp);
-#ifdef CONFIG_WIRELESS_EXT
- /* Attach and link in the iw */
- wl_iw_detach();
-#endif
+ if (dhdp->prot)
+ dhd_prot_detach(dhdp);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP)
- unregister_pm_notifier(&dhd_sleep_pm_notifier);
+ unregister_pm_notifier(&dhd_sleep_pm_notifier);
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) */
- WAKE_LOCK_DESTROY(dhdp, WAKE_LOCK_TMOUT);
- WAKE_LOCK_DESTROY(dhdp, WAKE_LOCK_LINK_DOWN_TMOUT);
- free_netdev(ifp->net);
- MFREE(dhd->pub.osh, ifp, sizeof(*ifp));
- MFREE(dhd->pub.osh, dhd, sizeof(*dhd));
- }
-}
-}
-static void __exit
-dhd_module_cleanup(void)
-{
- DHD_TRACE(("%s: Enter\n", __FUNCTION__));
-
- dhd_bus_unregister();
-#if defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC)
- wifi_del_dev();
+ free_netdev(ifp->net);
+#ifdef CONFIG_HAS_WAKELOCK
+ wake_lock_destroy(&dhd->wl_wifi);
+ wake_lock_destroy(&dhd->wl_rxwake);
#endif
- /* Call customer gpio to turn off power with WL_REG_ON signal */
- dhd_customer_gpio_wlan_ctrl(WLAN_POWER_OFF);
+ MFREE(dhd->pub.osh, ifp, sizeof(*ifp));
+ MFREE(dhd->pub.osh, dhd, sizeof(*dhd));
+ }
+ }
}
-
static int __init
dhd_module_init(void)
{
@@ -2209,6 +2209,7 @@ dhd_module_init(void)
DHD_ERROR(("Invalid module parameters.\n"));
return -EINVAL;
} while (0);
+
/* Call customer gpio to turn on power with WL_REG_ON signal */
dhd_customer_gpio_wlan_ctrl(WLAN_POWER_ON);
@@ -2218,19 +2219,18 @@ dhd_module_init(void)
error = wifi_add_dev();
if (error) {
DHD_ERROR(("%s: platform_driver_register failed\n", __FUNCTION__));
- goto faild;
+ goto fail_0;
}
/* Waiting callback after platform_driver_register is done or exit with error */
- if (down_timeout(&wifi_control_sem, msecs_to_jiffies(1000)) != 0) {
- printk("%s: platform_driver_register timeout\n", __FUNCTION__);
- /* renove device */
- wifi_del_dev();
- goto faild;
+ if (down_timeout(&wifi_control_sem, msecs_to_jiffies(5000)) != 0) {
+ error = -EINVAL;
+ DHD_ERROR(("%s: platform_driver_register timeout\n", __FUNCTION__));
+ goto fail_1;
}
#endif /* #if defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC) */
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && 1
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
sema_init(&dhd_registration_sem, 0);
#endif
@@ -2240,28 +2240,51 @@ dhd_module_init(void)
printf("\n%s\n", dhd_version);
else {
DHD_ERROR(("%s: sdio_register_driver failed\n", __FUNCTION__));
- goto faild;
+ goto fail_1;
}
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && 1
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
/*
* Wait till MMC sdio_register_driver callback called and made driver attach.
* It's needed to make sync up exit from dhd insmod and
* Kernel MMC sdio device callback registration
*/
- if (down_timeout(&dhd_registration_sem, msecs_to_jiffies(DHD_REGISTRATION_TIMEOUT)) != 0) {
+ if (down_timeout(&dhd_registration_sem, msecs_to_jiffies(10000)) != 0) {
error = -EINVAL;
DHD_ERROR(("%s: sdio_register_driver timeout\n", __FUNCTION__));
- dhd_bus_unregister();
+ goto fail_2;
}
#endif
return error;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
+fail_2:
+ dhd_bus_unregister();
+#endif
+fail_1:
+#if defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC)
+ wifi_del_dev();
+fail_0:
+#endif /* defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC) */
+
+ /* Call customer gpio to turn off power with WL_REG_ON signal */
+ dhd_customer_gpio_wlan_ctrl(WLAN_POWER_OFF);
+
+ return error;
+}
+
+static void __exit
+dhd_module_cleanup(void)
+{
+ DHD_TRACE(("%s: Enter\n", __FUNCTION__));
-faild:
- /* turn off power and exit */
+ dhd_bus_unregister();
+#if defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC)
+ wifi_del_dev();
+#endif
+ /* Call customer gpio to turn off power with WL_REG_ON signal */
dhd_customer_gpio_wlan_ctrl(WLAN_POWER_OFF);
- return -EINVAL;
}
+
module_init(dhd_module_init);
module_exit(dhd_module_cleanup);
@@ -2348,34 +2371,22 @@ void
dhd_os_wd_timer(void *bus, uint wdtick)
{
dhd_pub_t *pub = bus;
- static uint save_dhd_watchdog_ms = 0;
dhd_info_t *dhd = (dhd_info_t *)pub->info;
+ static uint save_dhd_watchdog_ms = 0;
/* Totally stop the timer */
if (!wdtick && dhd->wd_timer_valid == TRUE) {
- del_timer(&dhd->timer);
+ del_timer_sync(&dhd->timer);
dhd->wd_timer_valid = FALSE;
save_dhd_watchdog_ms = wdtick;
return;
}
if (wdtick) {
- dhd_watchdog_ms = (uint) wdtick;
- if (save_dhd_watchdog_ms != dhd_watchdog_ms) {
-
- if (dhd->wd_timer_valid == TRUE)
- /* Stop timer and restart at new value */
- del_timer(&dhd->timer);
-
- /* Create timer again when watchdog period is
- dynamically changed or in the first instance
- */
- dhd->timer.expires = jiffies + dhd_watchdog_ms * HZ / 1000;
- add_timer(&dhd->timer);
- }else {
- /* Re arm the timer, at last watchdog period */
- mod_timer(&dhd->timer, jiffies + dhd_watchdog_ms * HZ / 1000);
- }
+ dhd_watchdog_ms = (uint)wdtick;
+
+ /* Re arm the timer, at last watchdog period */
+ mod_timer(&dhd->timer, jiffies + dhd_watchdog_ms * HZ / 1000);
dhd->wd_timer_valid = TRUE;
save_dhd_watchdog_ms = wdtick;
@@ -2434,7 +2445,7 @@ dhd_os_sdlock(dhd_pub_t *pub)
if (dhd->threads_only)
down(&dhd->sdsem);
else
- spin_lock_bh(&dhd->sdlock);
+ spin_lock_bh(&dhd->sdlock);
}
void
@@ -2447,7 +2458,7 @@ dhd_os_sdunlock(dhd_pub_t *pub)
if (dhd->threads_only)
up(&dhd->sdsem);
else
- spin_unlock_bh(&dhd->sdlock);
+ spin_unlock_bh(&dhd->sdlock);
}
void
@@ -2560,7 +2571,7 @@ dhd_sendup_event(dhd_pub_t *dhdp, wl_event_msg_t *event, void *data)
void dhd_wait_for_event(dhd_pub_t *dhd, bool *lockvar)
{
-#if 1 && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0))
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0))
struct dhd_info *dhdinfo = dhd->info;
dhd_os_sdunlock(dhd);
wait_event_interruptible_timeout(dhdinfo->ctrl_wait, (*lockvar == FALSE), HZ * 2);
@@ -2571,13 +2582,14 @@ void dhd_wait_for_event(dhd_pub_t *dhd, bool *lockvar)
void dhd_wait_event_wakeup(dhd_pub_t *dhd)
{
-#if 1 && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0))
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0))
struct dhd_info *dhdinfo = dhd->info;
if (waitqueue_active(&dhdinfo->ctrl_wait))
wake_up_interruptible(&dhdinfo->ctrl_wait);
#endif
return;
}
+
int
dhd_dev_reset(struct net_device *dev, uint8 flag)
{
@@ -2592,6 +2604,7 @@ dhd_dev_reset(struct net_device *dev, uint8 flag)
/* Turning on watchdog back */
if (!flag)
dhd_os_wd_timer(&dhd->pub, dhd_watchdog_ms);
+
DHD_ERROR(("%s: WLAN OFF DONE\n", __FUNCTION__));
return 1;
@@ -2632,3 +2645,120 @@ dhd_wait_pend8021x(struct net_device *dev)
}
return pend;
}
+
+int dhd_os_wake_lock_timeout(dhd_pub_t *pub)
+{
+ dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+ unsigned long flags;
+ int ret = 0;
+
+ if (dhd) {
+ spin_lock_irqsave(&dhd->wl_lock, flags);
+ ret = dhd->wl_packet;
+#ifdef CONFIG_HAS_WAKELOCK
+ if (dhd->wl_packet)
+ wake_lock_timeout(&dhd->wl_rxwake, HZ);
+#endif
+ dhd->wl_packet = 0;
+ spin_unlock_irqrestore(&dhd->wl_lock, flags);
+ }
+ /* printk("%s: %d\n", __FUNCTION__, ret); */
+ return ret;
+}
+
+int net_os_wake_lock_timeout(struct net_device *dev)
+{
+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+ int ret = 0;
+
+ if (dhd)
+ ret = dhd_os_wake_lock_timeout(&dhd->pub);
+ return ret;
+}
+
+int dhd_os_wake_lock_timeout_enable(dhd_pub_t *pub)
+{
+ dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+ unsigned long flags;
+
+ if (dhd) {
+ spin_lock_irqsave(&dhd->wl_lock, flags);
+ dhd->wl_packet = 1;
+ spin_unlock_irqrestore(&dhd->wl_lock, flags);
+ }
+ /* printk("%s\n",__func__); */
+ return 0;
+}
+
+int net_os_wake_lock_timeout_enable(struct net_device *dev)
+{
+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+ int ret = 0;
+
+ if (dhd)
+ ret = dhd_os_wake_lock_timeout_enable(&dhd->pub);
+ return ret;
+}
+
+int dhd_os_wake_lock(dhd_pub_t *pub)
+{
+ dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+ unsigned long flags;
+ int ret = 0;
+
+ if (dhd) {
+ spin_lock_irqsave(&dhd->wl_lock, flags);
+#ifdef CONFIG_HAS_WAKELOCK
+ if (!dhd->wl_count)
+ wake_lock(&dhd->wl_wifi);
+#endif
+ dhd->wl_count++;
+ ret = dhd->wl_count;
+ spin_unlock_irqrestore(&dhd->wl_lock, flags);
+ }
+ /* printk("%s: %d\n", __FUNCTION__, ret); */
+ return ret;
+}
+
+int net_os_wake_lock(struct net_device *dev)
+{
+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+ int ret = 0;
+
+ if (dhd)
+ ret = dhd_os_wake_lock(&dhd->pub);
+ return ret;
+}
+
+int dhd_os_wake_unlock(dhd_pub_t *pub)
+{
+ dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+ unsigned long flags;
+ int ret = 0;
+
+ dhd_os_wake_lock_timeout(pub);
+ if (dhd) {
+ spin_lock_irqsave(&dhd->wl_lock, flags);
+ if (dhd->wl_count) {
+ dhd->wl_count--;
+#ifdef CONFIG_HAS_WAKELOCK
+ if (!dhd->wl_count)
+ wake_unlock(&dhd->wl_wifi);
+#endif
+ ret = dhd->wl_count;
+ }
+ spin_unlock_irqrestore(&dhd->wl_lock, flags);
+ }
+ /* printk("%s: %d\n", __FUNCTION__, ret); */
+ return ret;
+}
+
+int net_os_wake_unlock(struct net_device *dev)
+{
+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+ int ret = 0;
+
+ if (dhd)
+ ret = dhd_os_wake_unlock(&dhd->pub);
+ return ret;
+}
diff --git a/bcm4329/src/dhd/sys/dhd_linux_sched.c b/bcm4329/src/dhd/sys/dhd_linux_sched.c
index 480b416..3189123 100644
--- a/bcm4329/src/dhd/sys/dhd_linux_sched.c
+++ b/bcm4329/src/dhd/sys/dhd_linux_sched.c
@@ -1,7 +1,7 @@
/*
* Expose some of the kernel scheduler routines
*
- * Copyright (C) 1999-2010, Broadcom Corporation
+ * Copyright (C) 1999-2009, Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
diff --git a/bcm4329/src/dhd/sys/dhd_proto.h b/bcm4329/src/dhd/sys/dhd_proto.h
index 79584d6..1e2401a 100644
--- a/bcm4329/src/dhd/sys/dhd_proto.h
+++ b/bcm4329/src/dhd/sys/dhd_proto.h
@@ -4,7 +4,7 @@
* Provides type definitions and function prototypes used to link the
* DHD OS, bus, and protocol modules.
*
- * Copyright (C) 1999-2010, Broadcom Corporation
+ * Copyright (C) 1999-2009, Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
diff --git a/bcm4329/src/dhd/sys/dhd_sdio.c b/bcm4329/src/dhd/sys/dhd_sdio.c
index b006623..e571671 100644
--- a/bcm4329/src/dhd/sys/dhd_sdio.c
+++ b/bcm4329/src/dhd/sys/dhd_sdio.c
@@ -689,9 +689,10 @@ dhdsdio_clkctl(dhd_bus_t *bus, uint target, bool pendok)
/* Early exit if we're already there */
if (bus->clkstate == target) {
- if (target == CLK_AVAIL)
+ if (target == CLK_AVAIL) {
dhd_os_wd_timer(bus->dhd, dhd_watchdog_ms);
bus->activity = TRUE;
+ }
return BCME_OK;
}
@@ -3751,7 +3752,7 @@ dhdsdio_dpc(dhd_bus_t *bus)
if (err) {
DHD_ERROR(("%s: error reading DEVCTL: %d\n", __FUNCTION__, err));
bus->dhd->busstate = DHD_BUS_DOWN;
- }else
+ } else
ASSERT(devctl & SBSDIO_DEVCTL_CA_INT_ONLY);
#endif /* DHD_DEBUG */
@@ -4009,13 +4010,14 @@ dhdsdio_isr(void *arg)
#if defined(SDIO_ISR_THREAD)
DHD_TRACE(("Calling dhdsdio_dpc() from %s\n", __FUNCTION__));
+ dhd_os_wake_lock(bus->dhd);
while (dhdsdio_dpc(bus));
+ dhd_os_wake_unlock(bus->dhd);
#else
bus->dpc_sched = TRUE;
dhd_sched_dpc(bus->dhd);
#endif
-
}
#ifdef SDTEST
@@ -4526,12 +4528,15 @@ dhdsdio_probe(uint16 venid, uint16 devid, uint16 bus_no, uint16 slot,
/* if firmware path present try to download and bring up bus */
if ((ret = dhd_bus_start(bus->dhd)) != 0) {
+#if 1
DHD_ERROR(("%s: failed\n", __FUNCTION__));
goto fail;
+#else
if (ret == BCME_NOTUP) {
DHD_ERROR(("%s: dongle is not responding\n", __FUNCTION__));
goto fail;
}
+#endif
}
/* Ok, have the per-port tell the stack we're open for business */
if (dhd_net_attach(bus->dhd, 0) != 0) {
@@ -4832,7 +4837,6 @@ dhd_bus_download_firmware(struct dhd_bus *bus, osl_t *osh,
ret = dhdsdio_download_firmware(bus, osh, bus->sdh);
-
return ret;
}
@@ -4842,12 +4846,13 @@ dhdsdio_download_firmware(struct dhd_bus *bus, osl_t *osh, void *sdh)
bool ret;
/* Download the firmware */
+ dhd_os_wake_lock(bus->dhd);
dhdsdio_clkctl(bus, CLK_AVAIL, FALSE);
ret = _dhdsdio_download_firmware(bus) == 0;
dhdsdio_clkctl(bus, CLK_SDONLY, FALSE);
-
+ dhd_os_wake_unlock(bus->dhd);
return ret;
}