mac80211: backport brcmfmac changes from 2016-07-08
[openwrt/staging/chunkeey.git] / package / kernel / mac80211 / patches / 319-0006-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ł Miłecki <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 @@ -785,12 +785,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 @@ -807,12 +843,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: