ath10k-firmware: remove dependency on kmod-ath10k so that it can be selected instead
[15.05/openwrt.git] / package / kernel / mac80211 / patches / 370-0009-brcmfmac-Deleting-of-p2p-device-is-leaking-memory.patch
1 From: Hante Meuleman <meuleman@broadcom.com>
2 Date: Fri, 18 Sep 2015 22:08:12 +0200
3 Subject: [PATCH] brcmfmac: Deleting of p2p device is leaking memory.
4
5 When a p2p device gets deleted, the memory for the vif is not being
6 released. This is solved by reorganizing the cleanup path and
7 properly freeing the memory.
8
9 Reviewed-by: Arend Van Spriel <arend@broadcom.com>
10 Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
11 Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
12 Signed-off-by: Arend van Spriel <arend@broadcom.com>
13 Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
14 ---
15
16 --- a/drivers/net/wireless/brcm80211/brcmfmac/core.c
17 +++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c
18 @@ -887,6 +887,16 @@ static void brcmf_del_if(struct brcmf_pu
19                         cancel_work_sync(&ifp->multicast_work);
20                 }
21                 brcmf_net_detach(ifp->ndev);
22 +       } else {
23 +               /* Only p2p device interfaces which get dynamically created
24 +                * end up here. In this case the p2p module should be informed
25 +                * about the removal of the interface within the firmware. If
26 +                * not then p2p commands towards the firmware will cause some
27 +                * serious troublesome side effects. The p2p module will clean
28 +                * up the ifp if needed.
29 +                */
30 +               brcmf_p2p_ifp_removed(ifp);
31 +               kfree(ifp);
32         }
33  }
34  
35 @@ -894,7 +904,8 @@ void brcmf_remove_interface(struct brcmf
36  {
37         if (!ifp || WARN_ON(ifp->drvr->iflist[ifp->bssidx] != ifp))
38                 return;
39 -
40 +       brcmf_dbg(TRACE, "Enter, bssidx=%d, ifidx=%d\n", ifp->bssidx,
41 +                 ifp->ifidx);
42         brcmf_fws_del_interface(ifp);
43         brcmf_del_if(ifp->drvr, ifp->bssidx);
44  }
45 --- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
46 +++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
47 @@ -2131,20 +2131,6 @@ fail:
48  }
49  
50  /**
51 - * brcmf_p2p_delete_p2pdev() - delete P2P_DEVICE virtual interface.
52 - *
53 - * @vif: virtual interface object to delete.
54 - */
55 -static void brcmf_p2p_delete_p2pdev(struct brcmf_p2p_info *p2p,
56 -                                   struct brcmf_cfg80211_vif *vif)
57 -{
58 -       cfg80211_unregister_wdev(&vif->wdev);
59 -       p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL;
60 -       brcmf_remove_interface(vif->ifp);
61 -       brcmf_free_vif(vif);
62 -}
63 -
64 -/**
65   * brcmf_p2p_add_vif() - create a new P2P virtual interface.
66   *
67   * @wiphy: wiphy device of new interface.
68 @@ -2264,9 +2250,11 @@ int brcmf_p2p_del_vif(struct wiphy *wiph
69                 break;
70  
71         case NL80211_IFTYPE_P2P_DEVICE:
72 +               if (!p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
73 +                       return 0;
74                 brcmf_p2p_cancel_remain_on_channel(vif->ifp);
75                 brcmf_p2p_deinit_discovery(p2p);
76 -               brcmf_p2p_delete_p2pdev(p2p, vif);
77 +               brcmf_remove_interface(vif->ifp);
78                 return 0;
79         default:
80                 return -ENOTSUPP;
81 @@ -2298,6 +2286,21 @@ int brcmf_p2p_del_vif(struct wiphy *wiph
82         return err;
83  }
84  
85 +void brcmf_p2p_ifp_removed(struct brcmf_if *ifp)
86 +{
87 +       struct brcmf_cfg80211_info *cfg;
88 +       struct brcmf_cfg80211_vif *vif;
89 +
90 +       brcmf_dbg(INFO, "P2P: device interface removed\n");
91 +       vif = ifp->vif;
92 +       cfg = wdev_to_cfg(&vif->wdev);
93 +       cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL;
94 +       rtnl_lock();
95 +       cfg80211_unregister_wdev(&vif->wdev);
96 +       rtnl_unlock();
97 +       brcmf_free_vif(vif);
98 +}
99 +
100  int brcmf_p2p_start_device(struct wiphy *wiphy, struct wireless_dev *wdev)
101  {
102         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
103 @@ -2422,10 +2425,7 @@ void brcmf_p2p_detach(struct brcmf_p2p_i
104         if (vif != NULL) {
105                 brcmf_p2p_cancel_remain_on_channel(vif->ifp);
106                 brcmf_p2p_deinit_discovery(p2p);
107 -               /* remove discovery interface */
108 -               rtnl_lock();
109 -               brcmf_p2p_delete_p2pdev(p2p, vif);
110 -               rtnl_unlock();
111 +               brcmf_remove_interface(vif->ifp);
112         }
113         /* just set it all to zero */
114         memset(p2p, 0, sizeof(*p2p));
115 --- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.h
116 +++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.h
117 @@ -156,6 +156,7 @@ struct wireless_dev *brcmf_p2p_add_vif(s
118  int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev);
119  int brcmf_p2p_ifchange(struct brcmf_cfg80211_info *cfg,
120                        enum brcmf_fil_p2p_if_types if_type);
121 +void brcmf_p2p_ifp_removed(struct brcmf_if *ifp);
122  int brcmf_p2p_start_device(struct wiphy *wiphy, struct wireless_dev *wdev);
123  void brcmf_p2p_stop_device(struct wiphy *wiphy, struct wireless_dev *wdev);
124  int brcmf_p2p_scan_prep(struct wiphy *wiphy,