aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
diff options
context:
space:
mode:
authorArend van Spriel <arend@broadcom.com>2013-02-08 15:53:41 +0100
committerJohn W. Linville <linville@tuxdriver.com>2013-02-08 14:51:38 -0500
commit5f4f9f114eef4907b6077d19dd5ad7d0a27e0f80 (patch)
tree1984c32c530311db1eed82680220f5ced7701c11 /drivers/net/wireless/brcm80211/brcmfmac/p2p.c
parentbrcmfmac: fix generation of the p2p related mac addresses (diff)
downloadlinux-dev-5f4f9f114eef4907b6077d19dd5ad7d0a27e0f80.tar.xz
linux-dev-5f4f9f114eef4907b6077d19dd5ad7d0a27e0f80.zip
brcmfmac: implement support for deleting virtual interfaces
Deletion of the virtual interface was not fully supported so adding it now. Tested using p2p_connect command in wpa_supplicant. Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com> Reviewed-by: Hante Meuleman <meuleman@broadcom.com> Signed-off-by: Arend van Spriel <arend@broadcom.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/brcm80211/brcmfmac/p2p.c')
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/p2p.c64
1 files changed, 52 insertions, 12 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
index cec4116379ea..fff5722d4c0b 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
@@ -827,6 +827,26 @@ static int brcmf_p2p_request_p2p_if(struct brcmf_if *ifp, u8 ea[ETH_ALEN],
return err;
}
+static int brcmf_p2p_disable_p2p_if(struct brcmf_cfg80211_vif *vif)
+{
+ struct brcmf_cfg80211_info *cfg = wdev_to_cfg(&vif->wdev);
+ struct net_device *pri_ndev = cfg_to_ndev(cfg);
+ struct brcmf_if *ifp = netdev_priv(pri_ndev);
+ u8 *addr = vif->wdev.netdev->dev_addr;
+
+ return brcmf_fil_iovar_data_set(ifp, "p2p_ifdis", addr, ETH_ALEN);
+}
+
+static int brcmf_p2p_release_p2p_if(struct brcmf_cfg80211_vif *vif)
+{
+ struct brcmf_cfg80211_info *cfg = wdev_to_cfg(&vif->wdev);
+ struct net_device *pri_ndev = cfg_to_ndev(cfg);
+ struct brcmf_if *ifp = netdev_priv(pri_ndev);
+ u8 *addr = vif->wdev.netdev->dev_addr;
+
+ return brcmf_fil_iovar_data_set(ifp, "p2p_ifdel", addr, ETH_ALEN);
+}
+
/**
* brcmf_p2p_add_vif() - create a new P2P virtual interface.
*
@@ -910,23 +930,43 @@ int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev)
{
struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
struct brcmf_cfg80211_vif *vif;
+ unsigned long jiffie_timeout = msecs_to_jiffies(1500);
+ bool wait_for_disable = false;
int err;
+ brcmf_dbg(TRACE, "delete P2P vif\n");
vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
- if (brcmf_cfg80211_vif_event_armed(cfg))
- return -EBUSY;
+ switch (vif->wdev.iftype) {
+ case NL80211_IFTYPE_P2P_CLIENT:
+ if (test_bit(BRCMF_VIF_STATUS_DISCONNECTING, &vif->sme_state))
+ wait_for_disable = true;
+ break;
+
+ case NL80211_IFTYPE_P2P_GO:
+ if (!brcmf_p2p_disable_p2p_if(vif))
+ wait_for_disable = true;
+ break;
+
+ case NL80211_IFTYPE_P2P_DEVICE:
+ default:
+ return -ENOTSUPP;
+ break;
+ }
+
+ if (wait_for_disable)
+ wait_for_completion_timeout(&cfg->vif_disabled, 500);
+
+ brcmf_vif_clear_mgmt_ies(vif);
brcmf_cfg80211_arm_vif_event(cfg, vif);
- /* wait for firmware event */
- err = brcmf_cfg80211_wait_vif_event_timeout(cfg, BRCMF_E_IF_DEL,
- msecs_to_jiffies(1500));
+ err = brcmf_p2p_release_p2p_if(vif);
+ if (!err)
+ /* wait for firmware event */
+ err = brcmf_cfg80211_wait_vif_event_timeout(cfg, BRCMF_E_IF_DEL,
+ jiffie_timeout);
brcmf_cfg80211_arm_vif_event(cfg, NULL);
- if (wdev->netdev)
- brcmf_dbg(INFO, "deleting vif \"%s\"\n", wdev->netdev->name);
- else
- brcmf_dbg(INFO, "deleting vif \"wdev-%u\"\n",
- wdev->identifier);
- brcmf_err("enter - not supported yet\n");
- return -EOPNOTSUPP;
+ brcmf_free_vif(vif);
+
+ return err;
}