aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHante Meuleman <meuleman@broadcom.com>2015-09-18 16:08:16 -0400
committerKalle Valo <kvalo@codeaurora.org>2015-09-29 03:56:03 -0400
commita2044d91d9d25a0e9e2abb43ca90cceee032f6ee (patch)
treecb360d4f6acad3c3a60655f8cf70b0938b80a7d2
parent8268c2011d255b547a9093977e728af5cf16d69e (diff)
brcmfmac: Fix race condition bug when deleting p2p interface.
When p2p device interface gets deleted by deinitialising discovery it will result in an event which removes the interface, but that is also done by delete p2p interface code. This results in race condition which sometimes results in lockup/crash. With this patch the delete device interface will wait for the event (with timeout) removing the possible race condition. Also on the stop device call from cfg80211 the deinitialisation of the discovery device should be avoided as it can result in a similar situation. Reviewed-by: Arend Van Spriel <arend@broadcom.com> Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com> Signed-off-by: Hante Meuleman <meuleman@broadcom.com> Signed-off-by: Arend van Spriel <arend@broadcom.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/p2p.c22
1 files changed, 14 insertions, 8 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
index 76e477109e6d..fda726c8e7ab 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
@@ -2241,6 +2241,7 @@ int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev)
2241 brcmf_dbg(TRACE, "delete P2P vif\n"); 2241 brcmf_dbg(TRACE, "delete P2P vif\n");
2242 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev); 2242 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
2243 2243
2244 brcmf_cfg80211_arm_vif_event(cfg, vif);
2244 switch (vif->wdev.iftype) { 2245 switch (vif->wdev.iftype) {
2245 case NL80211_IFTYPE_P2P_CLIENT: 2246 case NL80211_IFTYPE_P2P_CLIENT:
2246 if (test_bit(BRCMF_VIF_STATUS_DISCONNECTING, &vif->sme_state)) 2247 if (test_bit(BRCMF_VIF_STATUS_DISCONNECTING, &vif->sme_state))
@@ -2257,8 +2258,6 @@ int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev)
2257 return 0; 2258 return 0;
2258 brcmf_p2p_cancel_remain_on_channel(vif->ifp); 2259 brcmf_p2p_cancel_remain_on_channel(vif->ifp);
2259 brcmf_p2p_deinit_discovery(p2p); 2260 brcmf_p2p_deinit_discovery(p2p);
2260 brcmf_remove_interface(vif->ifp);
2261 return 0;
2262 default: 2261 default:
2263 return -ENOTSUPP; 2262 return -ENOTSUPP;
2264 } 2263 }
@@ -2270,10 +2269,11 @@ int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev)
2270 wait_for_completion_timeout(&cfg->vif_disabled, 2269 wait_for_completion_timeout(&cfg->vif_disabled,
2271 msecs_to_jiffies(500)); 2270 msecs_to_jiffies(500));
2272 2271
2273 brcmf_vif_clear_mgmt_ies(vif); 2272 err = 0;
2274 2273 if (vif->wdev.iftype != NL80211_IFTYPE_P2P_DEVICE) {
2275 brcmf_cfg80211_arm_vif_event(cfg, vif); 2274 brcmf_vif_clear_mgmt_ies(vif);
2276 err = brcmf_p2p_release_p2p_if(vif); 2275 err = brcmf_p2p_release_p2p_if(vif);
2276 }
2277 if (!err) { 2277 if (!err) {
2278 /* wait for firmware event */ 2278 /* wait for firmware event */
2279 err = brcmf_cfg80211_wait_vif_event_timeout(cfg, BRCMF_E_IF_DEL, 2279 err = brcmf_cfg80211_wait_vif_event_timeout(cfg, BRCMF_E_IF_DEL,
@@ -2283,8 +2283,12 @@ int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev)
2283 else 2283 else
2284 err = 0; 2284 err = 0;
2285 } 2285 }
2286 if (err)
2287 brcmf_remove_interface(vif->ifp);
2288
2286 brcmf_cfg80211_arm_vif_event(cfg, NULL); 2289 brcmf_cfg80211_arm_vif_event(cfg, NULL);
2287 p2p->bss_idx[P2PAPI_BSSCFG_CONNECTION].vif = NULL; 2290 if (vif->wdev.iftype != NL80211_IFTYPE_P2P_DEVICE)
2291 p2p->bss_idx[P2PAPI_BSSCFG_CONNECTION].vif = NULL;
2288 2292
2289 return err; 2293 return err;
2290} 2294}
@@ -2333,7 +2337,9 @@ void brcmf_p2p_stop_device(struct wiphy *wiphy, struct wireless_dev *wdev)
2333 */ 2337 */
2334 if (p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif == vif) { 2338 if (p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif == vif) {
2335 mutex_lock(&cfg->usr_sync); 2339 mutex_lock(&cfg->usr_sync);
2336 (void)brcmf_p2p_deinit_discovery(p2p); 2340 /* Set the discovery state to SCAN */
2341 (void)brcmf_p2p_set_discover_state(vif->ifp,
2342 WL_P2P_DISC_ST_SCAN, 0, 0);
2337 brcmf_abort_scanning(cfg); 2343 brcmf_abort_scanning(cfg);
2338 clear_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state); 2344 clear_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state);
2339 mutex_unlock(&cfg->usr_sync); 2345 mutex_unlock(&cfg->usr_sync);