net: wireless: bcmdhd: Fix FW hang recovery

- Reduce IOCTL responce timeout to 2 sec (from 20)
- Fix pending status in case of timeout
- Pass error code from dhd_is_associated() call
- Call cfg80211_disconnected() if no timeout detected

Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
This commit is contained in:
Dmitry Shmidt 2012-04-02 10:23:59 -07:00
parent 7d6c28c7cf
commit b071e4399f
6 changed files with 18 additions and 15 deletions

View File

@ -508,7 +508,7 @@ extern uint dhd_bus_status(dhd_pub_t *dhdp);
extern int dhd_bus_start(dhd_pub_t *dhdp);
extern int dhd_bus_membytes(dhd_pub_t *dhdp, bool set, uint32 address, uint8 *data, uint size);
extern void dhd_print_buf(void *pbuf, int len, int bytes_per_line);
extern bool dhd_is_associated(dhd_pub_t *dhd, void *bss_buf);
extern bool dhd_is_associated(dhd_pub_t *dhd, void *bss_buf, int *retval);
extern uint dhd_bus_chip_id(dhd_pub_t *dhdp);
#if defined(KEEP_ALIVE)

View File

@ -300,7 +300,7 @@ dhd_wl_ioctl(dhd_pub_t *dhd_pub, int ifindex, wl_ioctl_t *ioc, void *buf, int le
dhd_os_proto_block(dhd_pub);
ret = dhd_prot_ioctl(dhd_pub, ifindex, ioc, buf, len);
if (!ret)
if (ret)
dhd_os_check_hang(dhd_pub, ifindex, ret);
dhd_os_proto_unblock(dhd_pub);
@ -1724,10 +1724,10 @@ dhd_iscan_get_partial_result(void *dhdp, uint *scan_count)
/*
* returns = TRUE if associated, FALSE if not associated
*/
bool dhd_is_associated(dhd_pub_t *dhd, void *bss_buf)
bool dhd_is_associated(dhd_pub_t *dhd, void *bss_buf, int *retval)
{
char bssid[6], zbuf[6];
int ret = -1;
int ret;
bzero(bssid, 6);
bzero(zbuf, 6);
@ -1735,6 +1735,9 @@ bool dhd_is_associated(dhd_pub_t *dhd, void *bss_buf)
ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_BSSID, (char *)&bssid, ETHER_ADDR_LEN, FALSE, 0);
DHD_TRACE((" %s WLC_GET_BSSID ioctl res = %d\n", __FUNCTION__, ret));
if (retval)
*retval = ret;
if (ret == BCME_NOTASSOCIATED) {
DHD_TRACE(("%s: not associated! res:%d\n", __FUNCTION__, ret));
}
@ -1771,7 +1774,7 @@ dhd_get_dtim_skip(dhd_pub_t *dhd)
bcn_li_dtim = dhd->dtim_skip;
/* Check if associated */
if (dhd_is_associated(dhd, NULL) == FALSE) {
if (dhd_is_associated(dhd, NULL, NULL) == FALSE) {
DHD_TRACE(("%s NOT assoc ret %d\n", __FUNCTION__, ret));
goto exit;
}
@ -1884,7 +1887,7 @@ dhd_pno_enable(dhd_pub_t *dhd, int pfn_enabled)
memset(iovbuf, 0, sizeof(iovbuf));
#ifndef WL_SCHED_SCAN
if ((pfn_enabled) && (dhd_is_associated(dhd, NULL) == TRUE)) {
if ((pfn_enabled) && (dhd_is_associated(dhd, NULL, NULL) == TRUE)) {
DHD_ERROR(("%s pno is NOT enable : called in assoc mode , ignore\n", __FUNCTION__));
return ret;
}

View File

@ -29,8 +29,8 @@
#if defined(DHD_DEBUG)
#define DHD_ERROR(args) do {if ((dhd_msg_level & DHD_ERROR_VAL) && (net_ratelimit())) \
printf args;} while (0)
#define DHD_ERROR(args) do {if ((dhd_msg_level & DHD_ERROR_VAL) && (net_ratelimit())) \
printf args;} while (0)
#define DHD_TRACE(args) do {if (dhd_msg_level & DHD_TRACE_VAL) printf args;} while (0)
#define DHD_INFO(args) do {if (dhd_msg_level & DHD_INFO_VAL) printf args;} while (0)
#define DHD_DATA(args) do {if (dhd_msg_level & DHD_DATA_VAL) printf args;} while (0)

View File

@ -34,7 +34,7 @@
#include <wlioctl.h>
#ifndef IOCTL_RESP_TIMEOUT
#define IOCTL_RESP_TIMEOUT 20000 /* In milli second */
#define IOCTL_RESP_TIMEOUT 2000 /* In milli second */
#endif
/*

View File

@ -1455,7 +1455,7 @@ dhd_bus_rxctl(struct dhd_bus *bus, uchar *msg, uint msglen)
{
int timeleft;
uint rxlen = 0;
bool pending;
bool pending = FALSE;
DHD_TRACE(("%s: Enter\n", __FUNCTION__));

View File

@ -2844,11 +2844,11 @@ wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
#endif
} else if (wl_get_mode_by_netdev(wl, dev) == WL_MODE_BSS) {
u8 *curmacp = wl_read_prof(wl, dev, WL_PROF_BSSID);
err = -ENODEV;
if (!wl_get_drv_status(wl, CONNECTED, dev) ||
(dhd_is_associated(dhd, NULL) == FALSE)) {
(dhd_is_associated(dhd, NULL, &err) == FALSE)) {
WL_ERR(("NOT assoc\n"));
err = -ENODEV;
WL_ERR(("NOT assoc: %d\n", err));
goto get_station_err;
}
if (memcmp(mac, curmacp, ETHER_ADDR_LEN)) {
@ -2881,9 +2881,9 @@ wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
WL_DBG(("RSSI %d dBm\n", rssi));
get_station_err:
if (err) {
if (err && (err != -ETIMEDOUT) && (err != -EIO)) {
/* Disconnect due to zero BSSID or error to get RSSI */
WL_ERR(("force cfg80211_disconnected\n"));
WL_ERR(("force cfg80211_disconnected: %d\n", err));
wl_clr_drv_status(wl, CONNECTED, dev);
cfg80211_disconnected(dev, 0, NULL, 0, GFP_KERNEL);
wl_link_down(wl);