net: wireless: bcm4329: Prohibit FW access in case of FW crash

Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
This commit is contained in:
Dmitry Shmidt
2011-10-26 13:57:26 -07:00
parent 019c9a9d40
commit d5b9284a58
4 changed files with 30 additions and 8 deletions

View File

@@ -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 */

View File

@@ -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;
}

View File

@@ -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");
}
}

View File

@@ -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;
}
}