mac80211: brcmfmac: fix getting/setting TX power
[15.05/openwrt.git] / package / kernel / mac80211 / patches / 370-0013-brcmfmac-Fix-race-condition-bug-when-deleting-p2p-in.patch
1 From: Hante Meuleman <meuleman@broadcom.com>
2 Date: Fri, 18 Sep 2015 22:08:16 +0200
3 Subject: [PATCH] brcmfmac: Fix race condition bug when deleting p2p interface.
4
5 When p2p device interface gets deleted by deinitialising discovery
6 it will result in an event which removes the interface, but that is
7 also done by delete p2p interface code. This results in race
8 condition which sometimes results in lockup/crash. With this patch
9 the delete device interface will wait for the event (with timeout)
10 removing the possible race condition. Also on the stop device call
11 from cfg80211 the deinitialisation of the discovery device should
12 be avoided as it can result in a similar situation.
13
14 Reviewed-by: Arend Van Spriel <arend@broadcom.com>
15 Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
16 Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
17 Signed-off-by: Arend van Spriel <arend@broadcom.com>
18 Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
19 ---
20
21 --- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
22 +++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
23 @@ -2238,6 +2238,7 @@ int brcmf_p2p_del_vif(struct wiphy *wiph
24         brcmf_dbg(TRACE, "delete P2P vif\n");
25         vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
26  
27 +       brcmf_cfg80211_arm_vif_event(cfg, vif);
28         switch (vif->wdev.iftype) {
29         case NL80211_IFTYPE_P2P_CLIENT:
30                 if (test_bit(BRCMF_VIF_STATUS_DISCONNECTING, &vif->sme_state))
31 @@ -2254,8 +2255,6 @@ int brcmf_p2p_del_vif(struct wiphy *wiph
32                         return 0;
33                 brcmf_p2p_cancel_remain_on_channel(vif->ifp);
34                 brcmf_p2p_deinit_discovery(p2p);
35 -               brcmf_remove_interface(vif->ifp);
36 -               return 0;
37         default:
38                 return -ENOTSUPP;
39         }
40 @@ -2267,10 +2266,11 @@ int brcmf_p2p_del_vif(struct wiphy *wiph
41                 wait_for_completion_timeout(&cfg->vif_disabled,
42                                             msecs_to_jiffies(500));
43  
44 -       brcmf_vif_clear_mgmt_ies(vif);
45 -
46 -       brcmf_cfg80211_arm_vif_event(cfg, vif);
47 -       err = brcmf_p2p_release_p2p_if(vif);
48 +       err = 0;
49 +       if (vif->wdev.iftype != NL80211_IFTYPE_P2P_DEVICE) {
50 +               brcmf_vif_clear_mgmt_ies(vif);
51 +               err = brcmf_p2p_release_p2p_if(vif);
52 +       }
53         if (!err) {
54                 /* wait for firmware event */
55                 err = brcmf_cfg80211_wait_vif_event_timeout(cfg, BRCMF_E_IF_DEL,
56 @@ -2280,8 +2280,12 @@ int brcmf_p2p_del_vif(struct wiphy *wiph
57                 else
58                         err = 0;
59         }
60 +       if (err)
61 +               brcmf_remove_interface(vif->ifp);
62 +
63         brcmf_cfg80211_arm_vif_event(cfg, NULL);
64 -       p2p->bss_idx[P2PAPI_BSSCFG_CONNECTION].vif = NULL;
65 +       if (vif->wdev.iftype != NL80211_IFTYPE_P2P_DEVICE)
66 +               p2p->bss_idx[P2PAPI_BSSCFG_CONNECTION].vif = NULL;
67  
68         return err;
69  }
70 @@ -2330,7 +2334,9 @@ void brcmf_p2p_stop_device(struct wiphy
71          */
72         if (p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif == vif) {
73                 mutex_lock(&cfg->usr_sync);
74 -               (void)brcmf_p2p_deinit_discovery(p2p);
75 +               /* Set the discovery state to SCAN */
76 +               (void)brcmf_p2p_set_discover_state(vif->ifp,
77 +                                                  WL_P2P_DISC_ST_SCAN, 0, 0);
78                 brcmf_abort_scanning(cfg);
79                 clear_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state);
80                 mutex_unlock(&cfg->usr_sync);