OSDN Git Service

net: wireless: bcmdhd: Reload FW in case of constant scan failure
authorDmitry Shmidt <dimitrysh@google.com>
Thu, 14 Jun 2012 17:59:25 +0000 (10:59 -0700)
committerDmitry Shmidt <dimitrysh@google.com>
Tue, 19 Jun 2012 17:38:10 +0000 (10:38 -0700)
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
drivers/net/wireless/bcmdhd/dhd.h
drivers/net/wireless/bcmdhd/dhd_linux.c
drivers/net/wireless/bcmdhd/wl_cfg80211.c
drivers/net/wireless/bcmdhd/wl_cfg80211.h

index 3b4dc7a..3ffbf0b 100644 (file)
@@ -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);
index d8c1c1b..a600b58 100644 (file)
@@ -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 */
index cccc4d1..d6bf8fa 100644 (file)
@@ -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);
index 37c8e58..49bed70 100644 (file)
@@ -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)