Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cbb371da authored by Arend van Spriel's avatar Arend van Spriel Committed by John W. Linville
Browse files

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: default avatarHante Meuleman <meuleman@broadcom.com>
Signed-off-by: default avatarArend van Spriel <arend@broadcom.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 9390ace9
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -653,6 +653,7 @@ int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked)

	brcmf_dbg(INFO, "%s: Broadcom Dongle Host Driver\n", ndev->name);

	ndev->destructor = free_netdev;
	return 0;

fail:
@@ -793,6 +794,7 @@ void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx)
	struct brcmf_if *ifp;

	ifp = drvr->iflist[bssidx];
	drvr->iflist[bssidx] = NULL;
	if (!ifp) {
		brcmf_err("Null interface, idx=%d\n", bssidx);
		return;
@@ -813,15 +815,13 @@ void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx)
			cancel_work_sync(&ifp->setmacaddr_work);
			cancel_work_sync(&ifp->multicast_work);
		}

		/* unregister will take care of freeing it */
		unregister_netdev(ifp->ndev);
		if (bssidx == 0)
			brcmf_cfg80211_detach(drvr->config);
		free_netdev(ifp->ndev);
	} else {
		kfree(ifp);
	}
	drvr->iflist[bssidx] = NULL;
}

int brcmf_attach(uint bus_hdrlen, struct device *dev)
+22 −1
Original line number Diff line number Diff line
@@ -2239,6 +2239,25 @@ static void brcmf_p2p_delete_p2pdev(struct brcmf_cfg80211_info *cfg,
	brcmf_free_vif(cfg, vif);
}

/**
 * brcmf_p2p_free_p2p_if() - free up net device related data.
 *
 * @ndev: net device that needs to be freed.
 */
static void brcmf_p2p_free_p2p_if(struct net_device *ndev)
{
	struct brcmf_cfg80211_info *cfg;
	struct brcmf_cfg80211_vif *vif;
	struct brcmf_if *ifp;

	ifp = netdev_priv(ndev);
	cfg = ifp->drvr->config;
	vif = ifp->vif;

	brcmf_free_vif(cfg, vif);
	free_netdev(ifp->ndev);
}

/**
 * brcmf_p2p_add_vif() - create a new P2P virtual interface.
 *
@@ -2316,6 +2335,9 @@ struct wireless_dev *brcmf_p2p_add_vif(struct wiphy *wiphy, const char *name,
		brcmf_err("Registering netdevice failed\n");
		goto fail;
	}
	/* override destructor */
	ifp->ndev->destructor = brcmf_p2p_free_p2p_if;

	cfg->p2p.bss_idx[P2PAPI_BSSCFG_CONNECTION].vif = vif;
	/* Disable firmware roaming for P2P interface  */
	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)
			err = 0;
	}
	brcmf_cfg80211_arm_vif_event(cfg, NULL);
	brcmf_free_vif(cfg, vif);
	p2p->bss_idx[P2PAPI_BSSCFG_CONNECTION].vif = NULL;

	return err;
+0 −1
Original line number Diff line number Diff line
@@ -4678,7 +4678,6 @@ static s32 brcmf_notify_vif_event(struct brcmf_if *ifp,
		return 0;

	case BRCMF_E_IF_DEL:
		ifp->vif = NULL;
		mutex_unlock(&event->vif_event_lock);
		/* event may not be upon user request */
		if (brcmf_cfg80211_vif_event_armed(cfg))