summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSrinivas Ramachandran <srinivasra@nvidia.com>2018-12-05 20:35:22 -0500
committermobile promotions <svcmobile_promotions@nvidia.com>2018-12-18 01:56:35 -0500
commit8438dbee00b82b2fc571b3cba8fceee6364b4e23 (patch)
tree8882b5fc43cfcff3afd631d93ee4c306494ebc47
parenta593bd245b972ff2aef63668a9f842deadaed7c4 (diff)
net: wireless: bcmdhd: Reset wifi after consecutive scan timeouts
Issue: Sometimes consecutive scan requests result in back to back timeouts rather than providing scan results. The root cause of issue is not yet known. DUT cannot connect to any AP due to this issue. Fix: As a WAR, reset wifi by passing driver hang event to android framework. This will recover wifi from the bad state in some cases. Bug 2439038 Change-Id: I3acb64ccc8e7f0bf063ee579c5e64d97dd77a51b Signed-off-by: Srinivas Ramachandran <srinivasra@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1966519 (cherry picked from commit d468a4c8b971a72bfcb7c11633b185c2ee61f8ce) Reviewed-on: https://git-master.nvidia.com/r/1972629 GVS: Gerrit_Virtual_Submit Reviewed-by: Ashutosh Jha <ajha@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
-rw-r--r--drivers/net/wireless/bcmdhd/wl_cfg80211.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/drivers/net/wireless/bcmdhd/wl_cfg80211.c b/drivers/net/wireless/bcmdhd/wl_cfg80211.c
index 7b0138f23..be66977d1 100644
--- a/drivers/net/wireless/bcmdhd/wl_cfg80211.c
+++ b/drivers/net/wireless/bcmdhd/wl_cfg80211.c
@@ -10311,6 +10311,8 @@ wl_notify_pfn_status(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
10311} 10311}
10312#endif /* PNO_SUPPORT */ 10312#endif /* PNO_SUPPORT */
10313 10313
10314#define MAX_NUM_SCAN_TIMEOUTS 3
10315atomic_t num_scan_timeout = ATOMIC_INIT(0);
10314static s32 10316static s32
10315wl_notify_scan_status(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev, 10317wl_notify_scan_status(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
10316 const wl_event_msg_t *e, void *data) 10318 const wl_event_msg_t *e, void *data)
@@ -10367,6 +10369,7 @@ wl_notify_scan_status(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
10367 10369
10368scan_done_out: 10370scan_done_out:
10369 del_timer_sync(&cfg->scan_timeout); 10371 del_timer_sync(&cfg->scan_timeout);
10372 atomic_set(&num_scan_timeout, 0);
10370 spin_lock_irqsave(&cfg->cfgdrv_lock, flags); 10373 spin_lock_irqsave(&cfg->cfgdrv_lock, flags);
10371 if (cfg->scan_request) { 10374 if (cfg->scan_request) {
10372#ifdef CONFIG_BCMDHD_CUSTOM_SYSFS_TEGRA 10375#ifdef CONFIG_BCMDHD_CUSTOM_SYSFS_TEGRA
@@ -11090,6 +11093,11 @@ static void wl_scan_timeout(unsigned long data)
11090{ 11093{
11091 wl_event_msg_t msg; 11094 wl_event_msg_t msg;
11092 struct bcm_cfg80211 *cfg = (struct bcm_cfg80211 *)data; 11095 struct bcm_cfg80211 *cfg = (struct bcm_cfg80211 *)data;
11096 struct wireless_dev *wdev;
11097 struct net_device *ndev;
11098 u32 connected;
11099 ndev = bcmcfg_to_prmry_ndev(cfg);
11100 connected = wl_get_drv_status(cfg, CONNECTED, ndev);
11093 11101
11094 if (!(cfg->scan_request)) { 11102 if (!(cfg->scan_request)) {
11095 WL_ERR(("timer expired but no scan request\n")); 11103 WL_ERR(("timer expired but no scan request\n"));
@@ -11101,6 +11109,23 @@ static void wl_scan_timeout(unsigned long data)
11101 msg.status = hton32(WLC_E_STATUS_TIMEOUT); 11109 msg.status = hton32(WLC_E_STATUS_TIMEOUT);
11102 msg.reason = 0xFFFFFFFF; 11110 msg.reason = 0xFFFFFFFF;
11103 wl_cfg80211_event(bcmcfg_to_prmry_ndev(cfg), &msg, NULL); 11111 wl_cfg80211_event(bcmcfg_to_prmry_ndev(cfg), &msg, NULL);
11112
11113 WL_DBG(("%s: Increment scan timeout count\n", __func__));
11114 if (!connected) {
11115 atomic_inc(&num_scan_timeout);
11116 }
11117
11118 if (atomic_read(&num_scan_timeout) >= MAX_NUM_SCAN_TIMEOUTS) {
11119 atomic_set(&num_scan_timeout, 0);
11120 if (cfg) {
11121 wdev = (struct wireless_dev *) cfg->wdev;
11122 if (wdev) {
11123 WL_ERR(("%s: Consecutive scan timeout, reset wifi to recover\n",
11124 __func__));
11125 wl_cfg80211_hang(wdev->netdev, WLAN_REASON_UNSPECIFIED);
11126 }
11127 }
11128 }
11104} 11129}
11105 11130
11106static s32 11131static s32
@@ -11282,8 +11307,10 @@ static s32 wl_notify_escan_complete(struct bcm_cfg80211 *cfg,
11282 } 11307 }
11283 if (fw_abort && !in_atomic()) 11308 if (fw_abort && !in_atomic())
11284 wl_cfg80211_scan_abort(cfg); 11309 wl_cfg80211_scan_abort(cfg);
11285 if (timer_pending(&cfg->scan_timeout)) 11310 if (timer_pending(&cfg->scan_timeout)) {
11286 del_timer_sync(&cfg->scan_timeout); 11311 del_timer_sync(&cfg->scan_timeout);
11312 atomic_set(&num_scan_timeout, 0);
11313 }
11287#if defined(ESCAN_RESULT_PATCH) 11314#if defined(ESCAN_RESULT_PATCH)
11288 if (likely(cfg->scan_request)) { 11315 if (likely(cfg->scan_request)) {
11289 cfg->bss_list = wl_escan_get_buf(cfg, aborted); 11316 cfg->bss_list = wl_escan_get_buf(cfg, aborted);
@@ -11305,6 +11332,8 @@ static s32 wl_notify_escan_complete(struct bcm_cfg80211 *cfg,
11305 } 11332 }
11306#endif /* WL_SCHED_SCAN */ 11333#endif /* WL_SCHED_SCAN */
11307 if (likely(cfg->scan_request)) { 11334 if (likely(cfg->scan_request)) {
11335 WL_DBG(("%s: Scan complete, reset scan timeout count\n", __func__));
11336 atomic_set(&num_scan_timeout, 0);
11308#ifdef CONFIG_BCMDHD_CUSTOM_SYSFS_TEGRA 11337#ifdef CONFIG_BCMDHD_CUSTOM_SYSFS_TEGRA
11309 TEGRA_SCAN_DONE(cfg->scan_request, aborted) 11338 TEGRA_SCAN_DONE(cfg->scan_request, aborted)
11310#endif 11339#endif