123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384 |
- From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
- Date: Wed, 29 Jun 2016 21:54:27 +0200
- Subject: [PATCH] brcmfmac: support removing AP interfaces with
- "interface_remove"
- MIME-Version: 1.0
- Content-Type: text/plain; charset=UTF-8
- Content-Transfer-Encoding: 8bit
- New firmwares (e.g. 10.10.69.36 for BCM4366) support "interface_remove"
- for removing interfaces. Try to use this method on cfg80211 request. In
- case of older firmwares (e.g. 7.35.177.56 for BCM43602 as I tested) this
- will just result in firmware rejecting command and this won't change any
- behavior.
- Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
- Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
- ---
- --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
- +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
- @@ -785,12 +785,48 @@ s32 brcmf_notify_escan_complete(struct b
- return err;
- }
-
- +static int brcmf_cfg80211_del_ap_iface(struct wiphy *wiphy,
- + struct wireless_dev *wdev)
- +{
- + struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
- + struct net_device *ndev = wdev->netdev;
- + struct brcmf_if *ifp = netdev_priv(ndev);
- + int ret;
- + int err;
- +
- + brcmf_cfg80211_arm_vif_event(cfg, ifp->vif);
- +
- + err = brcmf_fil_bsscfg_data_set(ifp, "interface_remove", NULL, 0);
- + if (err) {
- + brcmf_err("interface_remove failed %d\n", err);
- + goto err_unarm;
- + }
- +
- + /* wait for firmware event */
- + ret = brcmf_cfg80211_wait_vif_event(cfg, BRCMF_E_IF_DEL,
- + BRCMF_VIF_EVENT_TIMEOUT);
- + if (!ret) {
- + brcmf_err("timeout occurred\n");
- + err = -EIO;
- + goto err_unarm;
- + }
- +
- + brcmf_remove_interface(ifp, true);
- +
- +err_unarm:
- + brcmf_cfg80211_arm_vif_event(cfg, NULL);
- + return err;
- +}
- +
- static
- int brcmf_cfg80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev)
- {
- struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
- struct net_device *ndev = wdev->netdev;
-
- + if (ndev && ndev == cfg_to_ndev(cfg))
- + return -ENOTSUPP;
- +
- /* vif event pending in firmware */
- if (brcmf_cfg80211_vif_event_armed(cfg))
- return -EBUSY;
- @@ -807,12 +843,13 @@ int brcmf_cfg80211_del_iface(struct wiph
- switch (wdev->iftype) {
- case NL80211_IFTYPE_ADHOC:
- case NL80211_IFTYPE_STATION:
- - case NL80211_IFTYPE_AP:
- case NL80211_IFTYPE_AP_VLAN:
- case NL80211_IFTYPE_WDS:
- case NL80211_IFTYPE_MONITOR:
- case NL80211_IFTYPE_MESH_POINT:
- return -EOPNOTSUPP;
- + case NL80211_IFTYPE_AP:
- + return brcmf_cfg80211_del_ap_iface(wiphy, wdev);
- case NL80211_IFTYPE_P2P_CLIENT:
- case NL80211_IFTYPE_P2P_GO:
- case NL80211_IFTYPE_P2P_DEVICE:
|