aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/bcm4329/dhd.h3
-rw-r--r--drivers/net/wireless/bcm4329/dhd_cdc.c17
-rw-r--r--drivers/net/wireless/bcm4329/dhd_linux.c15
-rw-r--r--drivers/net/wireless/bcm4329/dhd_sdio.c3
4 files changed, 30 insertions, 8 deletions
diff --git a/drivers/net/wireless/bcm4329/dhd.h b/drivers/net/wireless/bcm4329/dhd.h
index 95b334f..0b2e9c2 100644
--- a/drivers/net/wireless/bcm4329/dhd.h
+++ b/drivers/net/wireless/bcm4329/dhd.h
@@ -144,7 +144,7 @@ typedef struct dhd_pub {
ulong rx_readahead_cnt; /* Number of packets where header read-ahead was used. */
ulong tx_realloc; /* Number of tx packets we had to realloc for headroom */
- ulong fc_packets; /* Number of flow control pkts recvd */
+ ulong fc_packets; /* Number of flow control pkts recvd */
/* Last error return */
int bcmerror;
@@ -156,6 +156,7 @@ typedef struct dhd_pub {
/* Suspend disable flag and "in suspend" flag */
int suspend_disable_flag; /* "1" to disable all extra powersaving during suspend */
int in_suspend; /* flag set to 1 when early suspend called */
+ int hang_was_sent; /* flag that message was send at least once */
#ifdef PNO_SUPPORT
int pno_enable; /* pno status : "1" is pno enable */
#endif /* PNO_SUPPORT */
diff --git a/drivers/net/wireless/bcm4329/dhd_cdc.c b/drivers/net/wireless/bcm4329/dhd_cdc.c
index 61f6a6f..4bec0b6 100644
--- a/drivers/net/wireless/bcm4329/dhd_cdc.c
+++ b/drivers/net/wireless/bcm4329/dhd_cdc.c
@@ -150,7 +150,8 @@ dhdcdc_query_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len)
memcpy(prot->buf, buf, len);
if ((ret = dhdcdc_msg(dhd)) < 0) {
- DHD_ERROR(("dhdcdc_query_ioctl: dhdcdc_msg failed w/status %d\n", ret));
+ if (!dhd->hang_was_sent)
+ DHD_ERROR(("dhdcdc_query_ioctl: dhdcdc_msg failed w/status %d\n", ret));
goto done;
}
@@ -205,6 +206,18 @@ dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len)
DHD_TRACE(("%s: Enter\n", __FUNCTION__));
DHD_CTL(("%s: cmd %d len %d\n", __FUNCTION__, cmd, len));
+ if (dhd->busstate == DHD_BUS_DOWN) {
+ DHD_ERROR(("%s : bus is down. we have nothing to do\n", __FUNCTION__));
+ return -EIO;
+ }
+
+ /* don't talk to the dongle if fw is about to be reloaded */
+ if (dhd->hang_was_sent) {
+ DHD_ERROR(("%s: HANG was sent up earlier. Not talking to the chip\n",
+ __FUNCTION__));
+ return -EIO;
+ }
+
memset(msg, 0, sizeof(cdc_ioctl_t));
msg->cmd = htol32(cmd);
@@ -251,7 +264,7 @@ dhd_prot_ioctl(dhd_pub_t *dhd, int ifidx, wl_ioctl_t * ioc, void * buf, int len)
dhd_prot_t *prot = dhd->prot;
int ret = -1;
- if (dhd->busstate == DHD_BUS_DOWN) {
+ if ((dhd->busstate == DHD_BUS_DOWN) || dhd->hang_was_sent) {
DHD_ERROR(("%s : bus is down. we have nothing to do\n", __FUNCTION__));
return ret;
}
diff --git a/drivers/net/wireless/bcm4329/dhd_linux.c b/drivers/net/wireless/bcm4329/dhd_linux.c
index 5c1384b..3ec1f3f 100644
--- a/drivers/net/wireless/bcm4329/dhd_linux.c
+++ b/drivers/net/wireless/bcm4329/dhd_linux.c
@@ -319,7 +319,6 @@ typedef struct dhd_info {
int wl_count;
int wl_packet;
- int hang_was_sent; /* flag that message was send at least once */
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25))
struct mutex wl_start_lock; /* mutex when START called to prevent any other Linux calls */
#endif
@@ -1778,6 +1777,14 @@ dhd_ioctl_entry(struct net_device *net, struct ifreq *ifr, int cmd)
dhd_os_wake_lock(&dhd->pub);
+ /* 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_os_wake_unlock(&dhd->pub);
+ return OSL_ERROR(BCME_DONGLE_DOWN);
+ }
+
ifidx = dhd_net2idx(dhd, net);
DHD_TRACE(("%s: ifidx %d, cmd 0x%04x\n", __FUNCTION__, ifidx, cmd));
@@ -1921,7 +1928,7 @@ dhd_stop(struct net_device *net)
#else
DHD_ERROR(("BYPASS %s:due to BRCM compilation : under investigation ...\n", __FUNCTION__));
#endif /* !defined(IGNORE_ETH0_DOWN) */
-
+ dhd->pub.hang_was_sent = 0;
OLD_MOD_DEC_USE_COUNT;
return 0;
}
@@ -3187,8 +3194,8 @@ int net_os_send_hang_message(struct net_device *dev)
int ret = 0;
if (dhd) {
- if (!dhd->hang_was_sent) {
- dhd->hang_was_sent = 1;
+ if (!dhd->pub.hang_was_sent) {
+ dhd->pub.hang_was_sent = 1;
ret = wl_iw_send_priv_event(dev, "HANG");
}
}
diff --git a/drivers/net/wireless/bcm4329/dhd_sdio.c b/drivers/net/wireless/bcm4329/dhd_sdio.c
index 1380dd3..e9093e8 100644
--- a/drivers/net/wireless/bcm4329/dhd_sdio.c
+++ b/drivers/net/wireless/bcm4329/dhd_sdio.c
@@ -1281,7 +1281,8 @@ dhd_bus_txctl(struct dhd_bus *bus, uchar *msg, uint msglen)
DHD_INFO(("%s: ctrl_frame_stat == FALSE\n", __FUNCTION__));
ret = 0;
} else {
- DHD_INFO(("%s: ctrl_frame_stat == TRUE\n", __FUNCTION__));
+ if (!bus->dhd->hang_was_sent)
+ DHD_ERROR(("%s: ctrl_frame_stat == TRUE\n", __FUNCTION__));
ret = -1;
}
}