mac80211: brcmfmac: backport patches that were skipped previously #1
[15.05/openwrt.git] / package / kernel / mac80211 / patches / 351-0025-brcmfmac-support-removing-AP-interfaces-with-interfa.patch
1 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
2 Date: Wed, 29 Jun 2016 21:54:27 +0200
3 Subject: [PATCH] brcmfmac: support removing AP interfaces with
4  "interface_remove"
5 MIME-Version: 1.0
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
8
9 New firmwares (e.g. 10.10.69.36 for BCM4366) support "interface_remove"
10 for removing interfaces. Try to use this method on cfg80211 request. In
11 case of older firmwares (e.g. 7.35.177.56 for BCM43602 as I tested) this
12 will just result in firmware rejecting command and this won't change any
13 behavior.
14
15 Signed-off-by: RafaÅ\82 MiÅ\82ecki <zajec5@gmail.com>
16 Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
17 ---
18
19 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
20 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
21 @@ -771,12 +771,48 @@ s32 brcmf_notify_escan_complete(struct b
22         return err;
23  }
24  
25 +static int brcmf_cfg80211_del_ap_iface(struct wiphy *wiphy,
26 +                                      struct wireless_dev *wdev)
27 +{
28 +       struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
29 +       struct net_device *ndev = wdev->netdev;
30 +       struct brcmf_if *ifp = netdev_priv(ndev);
31 +       int ret;
32 +       int err;
33 +
34 +       brcmf_cfg80211_arm_vif_event(cfg, ifp->vif);
35 +
36 +       err = brcmf_fil_bsscfg_data_set(ifp, "interface_remove", NULL, 0);
37 +       if (err) {
38 +               brcmf_err("interface_remove failed %d\n", err);
39 +               goto err_unarm;
40 +       }
41 +
42 +       /* wait for firmware event */
43 +       ret = brcmf_cfg80211_wait_vif_event(cfg, BRCMF_E_IF_DEL,
44 +                                           BRCMF_VIF_EVENT_TIMEOUT);
45 +       if (!ret) {
46 +               brcmf_err("timeout occurred\n");
47 +               err = -EIO;
48 +               goto err_unarm;
49 +       }
50 +
51 +       brcmf_remove_interface(ifp, true);
52 +
53 +err_unarm:
54 +       brcmf_cfg80211_arm_vif_event(cfg, NULL);
55 +       return err;
56 +}
57 +
58  static
59  int brcmf_cfg80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev)
60  {
61         struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
62         struct net_device *ndev = wdev->netdev;
63  
64 +       if (ndev && ndev == cfg_to_ndev(cfg))
65 +               return -ENOTSUPP;
66 +
67         /* vif event pending in firmware */
68         if (brcmf_cfg80211_vif_event_armed(cfg))
69                 return -EBUSY;
70 @@ -793,12 +829,13 @@ int brcmf_cfg80211_del_iface(struct wiph
71         switch (wdev->iftype) {
72         case NL80211_IFTYPE_ADHOC:
73         case NL80211_IFTYPE_STATION:
74 -       case NL80211_IFTYPE_AP:
75         case NL80211_IFTYPE_AP_VLAN:
76         case NL80211_IFTYPE_WDS:
77         case NL80211_IFTYPE_MONITOR:
78         case NL80211_IFTYPE_MESH_POINT:
79                 return -EOPNOTSUPP;
80 +       case NL80211_IFTYPE_AP:
81 +               return brcmf_cfg80211_del_ap_iface(wiphy, wdev);
82         case NL80211_IFTYPE_P2P_CLIENT:
83         case NL80211_IFTYPE_P2P_GO:
84         case NL80211_IFTYPE_P2P_DEVICE: