aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorArend van Spriel <arend@broadcom.com>2013-05-27 15:09:57 -0400
committerJohn W. Linville <linville@tuxdriver.com>2013-05-28 13:43:09 -0400
commitcbb371da233eb2b4c200010a5372579b880b4ae6 (patch)
tree11941df709d5c888ab9f90fcb9599557e9f7a61d /drivers/net
parent9390ace916b2fd866c1762b1cd16c276d8c8c890 (diff)
brcmfmac: use struct net_device::destructor to remove interfaces
Upon deleting a P2P_CLIENT/GO interface the vif and consequently the wdev is freed before the net_device is actually being unregistered but cfg80211 still needs to access the wdev. Using destructor field to free the net_device and vif. 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')
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c6
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/p2p.c23
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c1
3 files changed, 25 insertions, 5 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
index f04e3555dca3..b98f2235978e 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
@@ -653,6 +653,7 @@ int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked)
653 653
654 brcmf_dbg(INFO, "%s: Broadcom Dongle Host Driver\n", ndev->name); 654 brcmf_dbg(INFO, "%s: Broadcom Dongle Host Driver\n", ndev->name);
655 655
656 ndev->destructor = free_netdev;
656 return 0; 657 return 0;
657 658
658fail: 659fail:
@@ -793,6 +794,7 @@ void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx)
793 struct brcmf_if *ifp; 794 struct brcmf_if *ifp;
794 795
795 ifp = drvr->iflist[bssidx]; 796 ifp = drvr->iflist[bssidx];
797 drvr->iflist[bssidx] = NULL;
796 if (!ifp) { 798 if (!ifp) {
797 brcmf_err("Null interface, idx=%d\n", bssidx); 799 brcmf_err("Null interface, idx=%d\n", bssidx);
798 return; 800 return;
@@ -813,15 +815,13 @@ void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx)
813 cancel_work_sync(&ifp->setmacaddr_work); 815 cancel_work_sync(&ifp->setmacaddr_work);
814 cancel_work_sync(&ifp->multicast_work); 816 cancel_work_sync(&ifp->multicast_work);
815 } 817 }
816 818 /* unregister will take care of freeing it */
817 unregister_netdev(ifp->ndev); 819 unregister_netdev(ifp->ndev);
818 if (bssidx == 0) 820 if (bssidx == 0)
819 brcmf_cfg80211_detach(drvr->config); 821 brcmf_cfg80211_detach(drvr->config);
820 free_netdev(ifp->ndev);
821 } else { 822 } else {
822 kfree(ifp); 823 kfree(ifp);
823 } 824 }
824 drvr->iflist[bssidx] = NULL;
825} 825}
826 826
827int brcmf_attach(uint bus_hdrlen, struct device *dev) 827int brcmf_attach(uint bus_hdrlen, struct device *dev)
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
index 167b7afdf0d8..79555f006d53 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
@@ -2240,6 +2240,25 @@ static void brcmf_p2p_delete_p2pdev(struct brcmf_cfg80211_info *cfg,
2240} 2240}
2241 2241
2242/** 2242/**
2243 * brcmf_p2p_free_p2p_if() - free up net device related data.
2244 *
2245 * @ndev: net device that needs to be freed.
2246 */
2247static void brcmf_p2p_free_p2p_if(struct net_device *ndev)
2248{
2249 struct brcmf_cfg80211_info *cfg;
2250 struct brcmf_cfg80211_vif *vif;
2251 struct brcmf_if *ifp;
2252
2253 ifp = netdev_priv(ndev);
2254 cfg = ifp->drvr->config;
2255 vif = ifp->vif;
2256
2257 brcmf_free_vif(cfg, vif);
2258 free_netdev(ifp->ndev);
2259}
2260
2261/**
2243 * brcmf_p2p_add_vif() - create a new P2P virtual interface. 2262 * brcmf_p2p_add_vif() - create a new P2P virtual interface.
2244 * 2263 *
2245 * @wiphy: wiphy device of new interface. 2264 * @wiphy: wiphy device of new interface.
@@ -2316,6 +2335,9 @@ struct wireless_dev *brcmf_p2p_add_vif(struct wiphy *wiphy, const char *name,
2316 brcmf_err("Registering netdevice failed\n"); 2335 brcmf_err("Registering netdevice failed\n");
2317 goto fail; 2336 goto fail;
2318 } 2337 }
2338 /* override destructor */
2339 ifp->ndev->destructor = brcmf_p2p_free_p2p_if;
2340
2319 cfg->p2p.bss_idx[P2PAPI_BSSCFG_CONNECTION].vif = vif; 2341 cfg->p2p.bss_idx[P2PAPI_BSSCFG_CONNECTION].vif = vif;
2320 /* Disable firmware roaming for P2P interface */ 2342 /* Disable firmware roaming for P2P interface */
2321 brcmf_fil_iovar_int_set(ifp, "roam_off", 1); 2343 brcmf_fil_iovar_int_set(ifp, "roam_off", 1);
@@ -2391,7 +2413,6 @@ int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev)
2391 err = 0; 2413 err = 0;
2392 } 2414 }
2393 brcmf_cfg80211_arm_vif_event(cfg, NULL); 2415 brcmf_cfg80211_arm_vif_event(cfg, NULL);
2394 brcmf_free_vif(cfg, vif);
2395 p2p->bss_idx[P2PAPI_BSSCFG_CONNECTION].vif = NULL; 2416 p2p->bss_idx[P2PAPI_BSSCFG_CONNECTION].vif = NULL;
2396 2417
2397 return err; 2418 return err;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index f8c86b58a6d1..656ce8765863 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -4678,7 +4678,6 @@ static s32 brcmf_notify_vif_event(struct brcmf_if *ifp,
4678 return 0; 4678 return 0;
4679 4679
4680 case BRCMF_E_IF_DEL: 4680 case BRCMF_E_IF_DEL:
4681 ifp->vif = NULL;
4682 mutex_unlock(&event->vif_event_lock); 4681 mutex_unlock(&event->vif_event_lock);
4683 /* event may not be upon user request */ 4682 /* event may not be upon user request */
4684 if (brcmf_cfg80211_vif_event_armed(cfg)) 4683 if (brcmf_cfg80211_vif_event_armed(cfg))