aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/bcmdhd
diff options
context:
space:
mode:
authorDmitry Shmidt <dimitrysh@google.com>2012-06-14 10:59:25 -0700
committerDmitry Shmidt <dimitrysh@google.com>2012-06-19 10:38:10 -0700
commit2749b2ea4f335eba5fa5fe399a8fc07b808ba5e9 (patch)
treefcec659e94f6437e472f3a99ac498f8bc49909fc /drivers/net/wireless/bcmdhd
parentcb786ee756155411b65212d4ee76050a382ac674 (diff)
downloadkernel_samsung_crespo-2749b2ea4f335eba5fa5fe399a8fc07b808ba5e9.zip
kernel_samsung_crespo-2749b2ea4f335eba5fa5fe399a8fc07b808ba5e9.tar.gz
kernel_samsung_crespo-2749b2ea4f335eba5fa5fe399a8fc07b808ba5e9.tar.bz2
net: wireless: bcmdhd: Reload FW in case of constant scan failure
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
Diffstat (limited to 'drivers/net/wireless/bcmdhd')
-rw-r--r--drivers/net/wireless/bcmdhd/dhd.h1
-rw-r--r--drivers/net/wireless/bcmdhd/dhd_linux.c1
-rw-r--r--drivers/net/wireless/bcmdhd/wl_cfg80211.c10
-rw-r--r--drivers/net/wireless/bcmdhd/wl_cfg80211.h1
4 files changed, 12 insertions, 1 deletions
diff --git a/drivers/net/wireless/bcmdhd/dhd.h b/drivers/net/wireless/bcmdhd/dhd.h
index 3b4dc7a..3ffbf0b 100644
--- a/drivers/net/wireless/bcmdhd/dhd.h
+++ b/drivers/net/wireless/bcmdhd/dhd.h
@@ -431,6 +431,7 @@ extern void dhd_os_sdunlock_sndup_rxq(dhd_pub_t * pub);
extern void dhd_os_sdlock_eventq(dhd_pub_t * pub);
extern void dhd_os_sdunlock_eventq(dhd_pub_t * pub);
extern bool dhd_os_check_hang(dhd_pub_t *dhdp, int ifidx, int ret);
+extern int net_os_send_hang_message(struct net_device *dev);
#ifdef PNO_SUPPORT
extern int dhd_pno_enable(dhd_pub_t *dhd, int pfn_enabled);
diff --git a/drivers/net/wireless/bcmdhd/dhd_linux.c b/drivers/net/wireless/bcmdhd/dhd_linux.c
index d8c1c1b..a600b58 100644
--- a/drivers/net/wireless/bcmdhd/dhd_linux.c
+++ b/drivers/net/wireless/bcmdhd/dhd_linux.c
@@ -298,7 +298,6 @@ char nvram_path[MOD_PARAM_PATHLEN];
int op_mode = 0;
module_param(op_mode, int, 0644);
extern int wl_control_wl_start(struct net_device *dev);
-extern int net_os_send_hang_message(struct net_device *dev);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
struct semaphore dhd_registration_sem;
#define DHD_REGISTRATION_TIMEOUT 12000 /* msec : allowed time to finished dhd registration */
diff --git a/drivers/net/wireless/bcmdhd/wl_cfg80211.c b/drivers/net/wireless/bcmdhd/wl_cfg80211.c
index cccc4d1..d6bf8fa 100644
--- a/drivers/net/wireless/bcmdhd/wl_cfg80211.c
+++ b/drivers/net/wireless/bcmdhd/wl_cfg80211.c
@@ -72,6 +72,7 @@ u32 wl_dbg_level = WL_DBG_ERR;
#define WL_SCAN_ACTIVE_TIME 40
#define WL_SCAN_PASSIVE_TIME 130
#define WL_FRAME_LEN 300
+#define WL_SCAN_BUSY_MAX 8
#define DNGL_FUNC(func, parameters) func parameters;
#define COEX_DHCP
@@ -1738,6 +1739,13 @@ wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
err = __wl_cfg80211_scan(wiphy, ndev, request, NULL);
if (unlikely(err)) {
WL_ERR(("scan error (%d)\n", err));
+ if (err == BCME_BUSY) {
+ wl->scan_busy_count++;
+ if (wl->scan_busy_count > WL_SCAN_BUSY_MAX) {
+ wl->scan_busy_count = 0;
+ net_os_send_hang_message(ndev);
+ }
+ }
return err;
}
@@ -6005,6 +6013,7 @@ static void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted)
unsigned long flags;
WL_DBG(("Enter \n"));
+ wl->scan_busy_count = 0;
if (!wl_get_drv_status(wl, SCANNING, ndev)) {
wl_clr_drv_status(wl, SCANNING, ndev);
WL_ERR(("Scan complete while device not scanning\n"));
@@ -6259,6 +6268,7 @@ static s32 wl_notify_escan_complete(struct wl_priv *wl,
WL_DBG(("Enter \n"));
+ wl->scan_busy_count = 0;
if (wl->scan_request) {
if (wl->scan_request->dev == wl->p2p_net)
dev = wl_to_prmry_ndev(wl);
diff --git a/drivers/net/wireless/bcmdhd/wl_cfg80211.h b/drivers/net/wireless/bcmdhd/wl_cfg80211.h
index 37c8e58..49bed70 100644
--- a/drivers/net/wireless/bcmdhd/wl_cfg80211.h
+++ b/drivers/net/wireless/bcmdhd/wl_cfg80211.h
@@ -456,6 +456,7 @@ struct wl_priv {
bool sched_scan_running; /* scheduled scan req status */
u16 hostapd_chan; /* remember chan requested by framework for hostapd */
u16 deauth_reason; /* Place holder to save deauth/disassoc reasons */
+ u16 scan_busy_count;
};
static inline struct wl_bss_info *next_bss(struct wl_scan_results *list, struct wl_bss_info *bss)