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

Commit 856d5a01 authored by Arend Van Spriel's avatar Arend Van Spriel Committed by Kalle Valo
Browse files

brcmfmac: allocate struct brcmf_pub instance using wiphy_new()



Rework the driver so the wiphy instance holds the main driver information
in its private buffer. Previously it held struct brcmf_cfg80211_info
instance so a bit of reorg was needed. This was done so that the wiphy
name or its parent device can be shown in debug output.

Reviewed-by: default avatarHante Meuleman <hante.meuleman@broadcom.com>
Reviewed-by: default avatarPieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
Reviewed-by: default avatarFranky Lin <franky.lin@broadcom.com>
Signed-off-by: default avatarArend van Spriel <arend.vanspriel@broadcom.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent c88cfa07
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -462,7 +462,7 @@ static void brcmf_btcoex_dhcp_end(struct brcmf_btcoex_info *btci)
int brcmf_btcoex_set_mode(struct brcmf_cfg80211_vif *vif,
int brcmf_btcoex_set_mode(struct brcmf_cfg80211_vif *vif,
			  enum brcmf_btcoex_mode mode, u16 duration)
			  enum brcmf_btcoex_mode mode, u16 duration)
{
{
	struct brcmf_cfg80211_info *cfg = wiphy_priv(vif->wdev.wiphy);
	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(vif->wdev.wiphy);
	struct brcmf_btcoex_info *btci = cfg->btcoex;
	struct brcmf_btcoex_info *btci = cfg->btcoex;
	struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0);
	struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0);


+40 −46
Original line number Original line Diff line number Diff line
@@ -753,7 +753,7 @@ s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
static int brcmf_cfg80211_del_ap_iface(struct wiphy *wiphy,
static int brcmf_cfg80211_del_ap_iface(struct wiphy *wiphy,
				       struct wireless_dev *wdev)
				       struct wireless_dev *wdev)
{
{
	struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
	struct net_device *ndev = wdev->netdev;
	struct net_device *ndev = wdev->netdev;
	struct brcmf_if *ifp = netdev_priv(ndev);
	struct brcmf_if *ifp = netdev_priv(ndev);
	int ret;
	int ret;
@@ -786,7 +786,7 @@ static int brcmf_cfg80211_del_ap_iface(struct wiphy *wiphy,
static
static
int brcmf_cfg80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev)
int brcmf_cfg80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev)
{
{
	struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
	struct net_device *ndev = wdev->netdev;
	struct net_device *ndev = wdev->netdev;


	if (ndev && ndev == cfg_to_ndev(cfg))
	if (ndev && ndev == cfg_to_ndev(cfg))
@@ -831,7 +831,7 @@ brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
			 enum nl80211_iftype type,
			 enum nl80211_iftype type,
			 struct vif_params *params)
			 struct vif_params *params)
{
{
	struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
	struct brcmf_if *ifp = netdev_priv(ndev);
	struct brcmf_if *ifp = netdev_priv(ndev);
	struct brcmf_cfg80211_vif *vif = ifp->vif;
	struct brcmf_cfg80211_vif *vif = ifp->vif;
	s32 infra = 0;
	s32 infra = 0;
@@ -2127,17 +2127,15 @@ static s32
brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
			    s32 *dbm)
			    s32 *dbm)
{
{
	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
	struct brcmf_cfg80211_vif *vif = wdev_to_vif(wdev);
	struct net_device *ndev = cfg_to_ndev(cfg);
	struct brcmf_if *ifp = netdev_priv(ndev);
	s32 qdbm = 0;
	s32 qdbm = 0;
	s32 err;
	s32 err;


	brcmf_dbg(TRACE, "Enter\n");
	brcmf_dbg(TRACE, "Enter\n");
	if (!check_vif_up(ifp->vif))
	if (!check_vif_up(vif))
		return -EIO;
		return -EIO;


	err = brcmf_fil_iovar_int_get(ifp, "qtxpower", &qdbm);
	err = brcmf_fil_iovar_int_get(vif->ifp, "qtxpower", &qdbm);
	if (err) {
	if (err) {
		brcmf_err("error (%d)\n", err);
		brcmf_err("error (%d)\n", err);
		goto done;
		goto done;
@@ -3358,7 +3356,7 @@ brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
				struct cfg80211_sched_scan_request *req)
				struct cfg80211_sched_scan_request *req)
{
{
	struct brcmf_if *ifp = netdev_priv(ndev);
	struct brcmf_if *ifp = netdev_priv(ndev);
	struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);


	brcmf_dbg(SCAN, "Enter: n_match_sets=%d n_ssids=%d\n",
	brcmf_dbg(SCAN, "Enter: n_match_sets=%d n_ssids=%d\n",
		  req->n_match_sets, req->n_ssids);
		  req->n_match_sets, req->n_ssids);
@@ -5190,6 +5188,12 @@ static struct cfg80211_ops brcmf_cfg80211_ops = {
	.del_pmk = brcmf_cfg80211_del_pmk,
	.del_pmk = brcmf_cfg80211_del_pmk,
};
};


struct cfg80211_ops *brcmf_cfg80211_get_ops(void)
{
	return kmemdup(&brcmf_cfg80211_ops, sizeof(brcmf_cfg80211_ops),
		       GFP_KERNEL);
}

struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
					   enum nl80211_iftype type)
					   enum nl80211_iftype type)
{
{
@@ -5897,7 +5901,7 @@ static void brcmf_update_bw40_channel_flag(struct ieee80211_channel *channel,
static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg,
static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg,
				    u32 bw_cap[])
				    u32 bw_cap[])
{
{
	struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
	struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0);
	struct ieee80211_supported_band *band;
	struct ieee80211_supported_band *band;
	struct ieee80211_channel *channel;
	struct ieee80211_channel *channel;
	struct wiphy *wiphy;
	struct wiphy *wiphy;
@@ -6012,7 +6016,7 @@ static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg,


static int brcmf_enable_bw40_2g(struct brcmf_cfg80211_info *cfg)
static int brcmf_enable_bw40_2g(struct brcmf_cfg80211_info *cfg)
{
{
	struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
	struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0);
	struct ieee80211_supported_band *band;
	struct ieee80211_supported_band *band;
	struct brcmf_fil_bwcap_le band_bwcap;
	struct brcmf_fil_bwcap_le band_bwcap;
	struct brcmf_chanspec_list *list;
	struct brcmf_chanspec_list *list;
@@ -6197,10 +6201,10 @@ static void brcmf_update_vht_cap(struct ieee80211_supported_band *band,
	}
	}
}
}


static int brcmf_setup_wiphybands(struct wiphy *wiphy)
static int brcmf_setup_wiphybands(struct brcmf_cfg80211_info *cfg)
{
{
	struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
	struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0);
	struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
	struct wiphy *wiphy;
	u32 nmode = 0;
	u32 nmode = 0;
	u32 vhtmode = 0;
	u32 vhtmode = 0;
	u32 bw_cap[2] = { WLC_BW_20MHZ_BIT, WLC_BW_20MHZ_BIT };
	u32 bw_cap[2] = { WLC_BW_20MHZ_BIT, WLC_BW_20MHZ_BIT };
@@ -6794,8 +6798,8 @@ static s32 brcmf_translate_country_code(struct brcmf_pub *drvr, char alpha2[2],
static void brcmf_cfg80211_reg_notifier(struct wiphy *wiphy,
static void brcmf_cfg80211_reg_notifier(struct wiphy *wiphy,
					struct regulatory_request *req)
					struct regulatory_request *req)
{
{
	struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
	struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
	struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0);
	struct brcmf_fil_country_le ccreq;
	struct brcmf_fil_country_le ccreq;
	s32 err;
	s32 err;
	int i;
	int i;
@@ -6830,7 +6834,7 @@ static void brcmf_cfg80211_reg_notifier(struct wiphy *wiphy,
		brcmf_err("Firmware rejected country setting\n");
		brcmf_err("Firmware rejected country setting\n");
		return;
		return;
	}
	}
	brcmf_setup_wiphybands(wiphy);
	brcmf_setup_wiphybands(cfg);
}
}


static void brcmf_free_wiphy(struct wiphy *wiphy)
static void brcmf_free_wiphy(struct wiphy *wiphy)
@@ -6857,17 +6861,15 @@ static void brcmf_free_wiphy(struct wiphy *wiphy)
	if (wiphy->wowlan != &brcmf_wowlan_support)
	if (wiphy->wowlan != &brcmf_wowlan_support)
		kfree(wiphy->wowlan);
		kfree(wiphy->wowlan);
#endif
#endif
	wiphy_free(wiphy);
}
}


struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
						  struct device *busdev,
						  struct cfg80211_ops *ops,
						  bool p2pdev_forced)
						  bool p2pdev_forced)
{
{
	struct wiphy *wiphy = drvr->wiphy;
	struct net_device *ndev = brcmf_get_ifp(drvr, 0)->ndev;
	struct net_device *ndev = brcmf_get_ifp(drvr, 0)->ndev;
	struct brcmf_cfg80211_info *cfg;
	struct brcmf_cfg80211_info *cfg;
	struct wiphy *wiphy;
	struct cfg80211_ops *ops;
	struct brcmf_cfg80211_vif *vif;
	struct brcmf_cfg80211_vif *vif;
	struct brcmf_if *ifp;
	struct brcmf_if *ifp;
	s32 err = 0;
	s32 err = 0;
@@ -6879,26 +6881,13 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
		return NULL;
		return NULL;
	}
	}


	ops = kmemdup(&brcmf_cfg80211_ops, sizeof(*ops), GFP_KERNEL);
	cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
	if (!ops)
	if (!cfg) {
		return NULL;

	ifp = netdev_priv(ndev);
#ifdef CONFIG_PM
	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_GTK))
		ops->set_rekey_data = brcmf_cfg80211_set_rekey_data;
#endif
	wiphy = wiphy_new(ops, sizeof(struct brcmf_cfg80211_info));
	if (!wiphy) {
		brcmf_err("Could not allocate wiphy device\n");
		brcmf_err("Could not allocate wiphy device\n");
		goto ops_out;
		return NULL;
	}
	}
	memcpy(wiphy->perm_addr, drvr->mac, ETH_ALEN);
	set_wiphy_dev(wiphy, busdev);


	cfg = wiphy_priv(wiphy);
	cfg->wiphy = wiphy;
	cfg->wiphy = wiphy;
	cfg->ops = ops;
	cfg->pub = drvr;
	cfg->pub = drvr;
	init_vif_event(&cfg->vif_event);
	init_vif_event(&cfg->vif_event);
	INIT_LIST_HEAD(&cfg->vif_list);
	INIT_LIST_HEAD(&cfg->vif_list);
@@ -6907,6 +6896,7 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
	if (IS_ERR(vif))
	if (IS_ERR(vif))
		goto wiphy_out;
		goto wiphy_out;


	ifp = netdev_priv(ndev);
	vif->ifp = ifp;
	vif->ifp = ifp;
	vif->wdev.netdev = ndev;
	vif->wdev.netdev = ndev;
	ndev->ieee80211_ptr = &vif->wdev;
	ndev->ieee80211_ptr = &vif->wdev;
@@ -6933,6 +6923,11 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
	if (err < 0)
	if (err < 0)
		goto priv_out;
		goto priv_out;


	/* regulatory notifer below needs access to cfg so
	 * assign it now.
	 */
	drvr->config = cfg;

	brcmf_dbg(INFO, "Registering custom regulatory\n");
	brcmf_dbg(INFO, "Registering custom regulatory\n");
	wiphy->reg_notifier = brcmf_cfg80211_reg_notifier;
	wiphy->reg_notifier = brcmf_cfg80211_reg_notifier;
	wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
	wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
@@ -6946,13 +6941,17 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
		cap = &wiphy->bands[NL80211_BAND_2GHZ]->ht_cap.cap;
		cap = &wiphy->bands[NL80211_BAND_2GHZ]->ht_cap.cap;
		*cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
		*cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
	}
	}
#ifdef CONFIG_PM
	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_GTK))
		ops->set_rekey_data = brcmf_cfg80211_set_rekey_data;
#endif
	err = wiphy_register(wiphy);
	err = wiphy_register(wiphy);
	if (err < 0) {
	if (err < 0) {
		brcmf_err("Could not register wiphy device (%d)\n", err);
		brcmf_err("Could not register wiphy device (%d)\n", err);
		goto priv_out;
		goto priv_out;
	}
	}


	err = brcmf_setup_wiphybands(wiphy);
	err = brcmf_setup_wiphybands(cfg);
	if (err) {
	if (err) {
		brcmf_err("Setting wiphy bands failed (%d)\n", err);
		brcmf_err("Setting wiphy bands failed (%d)\n", err);
		goto wiphy_unreg_out;
		goto wiphy_unreg_out;
@@ -6969,12 +6968,7 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
		else
		else
			*cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
			*cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
	}
	}
	/* p2p might require that "if-events" get processed by fweh. So

	 * activate the already registered event handlers now and activate
	 * the rest when initialization has completed. drvr->config needs to
	 * be assigned before activating events.
	 */
	drvr->config = cfg;
	err = brcmf_fweh_activate_events(ifp);
	err = brcmf_fweh_activate_events(ifp);
	if (err) {
	if (err) {
		brcmf_err("FWEH activation failed (%d)\n", err);
		brcmf_err("FWEH activation failed (%d)\n", err);
@@ -7042,8 +7036,7 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
	ifp->vif = NULL;
	ifp->vif = NULL;
wiphy_out:
wiphy_out:
	brcmf_free_wiphy(wiphy);
	brcmf_free_wiphy(wiphy);
ops_out:
	kfree(cfg);
	kfree(ops);
	return NULL;
	return NULL;
}
}


@@ -7058,4 +7051,5 @@ void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
	kfree(cfg->ops);
	kfree(cfg->ops);
	wl_deinit_priv(cfg);
	wl_deinit_priv(cfg);
	brcmf_free_wiphy(cfg->wiphy);
	brcmf_free_wiphy(cfg->wiphy);
	kfree(cfg);
}
}
+11 −6
Original line number Original line Diff line number Diff line
@@ -355,20 +355,24 @@ static inline struct wiphy *cfg_to_wiphy(struct brcmf_cfg80211_info *cfg)


static inline struct brcmf_cfg80211_info *wiphy_to_cfg(struct wiphy *w)
static inline struct brcmf_cfg80211_info *wiphy_to_cfg(struct wiphy *w)
{
{
	return (struct brcmf_cfg80211_info *)(wiphy_priv(w));
	struct brcmf_pub *drvr = wiphy_priv(w);
	return drvr->config;
}
}


static inline struct brcmf_cfg80211_info *wdev_to_cfg(struct wireless_dev *wd)
static inline struct brcmf_cfg80211_info *wdev_to_cfg(struct wireless_dev *wd)
{
{
	return (struct brcmf_cfg80211_info *)(wdev_priv(wd));
	return wiphy_to_cfg(wd->wiphy);
}

static inline struct brcmf_cfg80211_vif *wdev_to_vif(struct wireless_dev *wdev)
{
	return container_of(wdev, struct brcmf_cfg80211_vif, wdev);
}
}


static inline
static inline
struct net_device *cfg_to_ndev(struct brcmf_cfg80211_info *cfg)
struct net_device *cfg_to_ndev(struct brcmf_cfg80211_info *cfg)
{
{
	struct brcmf_cfg80211_vif *vif;
	return brcmf_get_ifp(cfg->pub, 0)->ndev;
	vif = list_first_entry(&cfg->vif_list, struct brcmf_cfg80211_vif, list);
	return vif->wdev.netdev;
}
}


static inline struct brcmf_cfg80211_info *ndev_to_cfg(struct net_device *ndev)
static inline struct brcmf_cfg80211_info *ndev_to_cfg(struct net_device *ndev)
@@ -395,11 +399,12 @@ brcmf_cfg80211_connect_info *cfg_to_conn(struct brcmf_cfg80211_info *cfg)
}
}


struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
						  struct device *busdev,
						  struct cfg80211_ops *ops,
						  bool p2pdev_forced);
						  bool p2pdev_forced);
void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg);
void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg);
s32 brcmf_cfg80211_up(struct net_device *ndev);
s32 brcmf_cfg80211_up(struct net_device *ndev);
s32 brcmf_cfg80211_down(struct net_device *ndev);
s32 brcmf_cfg80211_down(struct net_device *ndev);
struct cfg80211_ops *brcmf_cfg80211_get_ops(void);
enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp);
enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp);


struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
+2 −0
Original line number Original line Diff line number Diff line
@@ -248,6 +248,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
		brcmf_err("Retreiving cur_etheraddr failed, %d\n", err);
		brcmf_err("Retreiving cur_etheraddr failed, %d\n", err);
		goto done;
		goto done;
	}
	}
	memcpy(ifp->drvr->wiphy->perm_addr, ifp->drvr->mac, ETH_ALEN);
	memcpy(ifp->drvr->mac, ifp->mac_addr, sizeof(ifp->drvr->mac));
	memcpy(ifp->drvr->mac, ifp->mac_addr, sizeof(ifp->drvr->mac));


	bus = ifp->drvr->bus_if;
	bus = ifp->drvr->bus_if;
@@ -275,6 +276,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
		ri->chippkg = le32_to_cpu(revinfo.chippkg);
		ri->chippkg = le32_to_cpu(revinfo.chippkg);
		ri->nvramrev = le32_to_cpu(revinfo.nvramrev);
		ri->nvramrev = le32_to_cpu(revinfo.nvramrev);


		/* use revinfo if not known yet */
		if (!bus->chip) {
		if (!bus->chip) {
			bus->chip = le32_to_cpu(revinfo.chipnum);
			bus->chip = le32_to_cpu(revinfo.chipnum);
			bus->chiprev = le32_to_cpu(revinfo.chiprev);
			bus->chiprev = le32_to_cpu(revinfo.chiprev);
+20 −7
Original line number Original line Diff line number Diff line
@@ -943,7 +943,7 @@ static int brcmf_revinfo_read(struct seq_file *s, void *data)
	return 0;
	return 0;
}
}


static int brcmf_bus_started(struct brcmf_pub *drvr)
static int brcmf_bus_started(struct brcmf_pub *drvr, struct cfg80211_ops *ops)
{
{
	int ret = -1;
	int ret = -1;
	struct brcmf_bus *bus_if = drvr->bus_if;
	struct brcmf_bus *bus_if = drvr->bus_if;
@@ -982,7 +982,7 @@ static int brcmf_bus_started(struct brcmf_pub *drvr)


	brcmf_proto_add_if(drvr, ifp);
	brcmf_proto_add_if(drvr, ifp);


	drvr->config = brcmf_cfg80211_attach(drvr, bus_if->dev,
	drvr->config = brcmf_cfg80211_attach(drvr, ops,
					     drvr->settings->p2p_enable);
					     drvr->settings->p2p_enable);
	if (drvr->config == NULL) {
	if (drvr->config == NULL) {
		ret = -ENOMEM;
		ret = -ENOMEM;
@@ -1037,17 +1037,26 @@ static int brcmf_bus_started(struct brcmf_pub *drvr)


int brcmf_attach(struct device *dev, struct brcmf_mp_device *settings)
int brcmf_attach(struct device *dev, struct brcmf_mp_device *settings)
{
{
	struct wiphy *wiphy;
	struct cfg80211_ops *ops;
	struct brcmf_pub *drvr = NULL;
	struct brcmf_pub *drvr = NULL;
	int ret = 0;
	int ret = 0;
	int i;
	int i;


	brcmf_dbg(TRACE, "Enter\n");
	brcmf_dbg(TRACE, "Enter\n");


	/* Allocate primary brcmf_info */
	ops = brcmf_cfg80211_get_ops();
	drvr = kzalloc(sizeof(*drvr), GFP_ATOMIC);
	if (!ops)
	if (!drvr)
		return -ENOMEM;
		return -ENOMEM;


	wiphy = wiphy_new(ops, sizeof(*drvr));
	if (!wiphy)
		return -ENOMEM;

	set_wiphy_dev(wiphy, dev);
	drvr = wiphy_priv(wiphy);
	drvr->wiphy = wiphy;

	for (i = 0; i < ARRAY_SIZE(drvr->if2bss); i++)
	for (i = 0; i < ARRAY_SIZE(drvr->if2bss); i++)
		drvr->if2bss[i] = BRCMF_BSSIDX_INVALID;
		drvr->if2bss[i] = BRCMF_BSSIDX_INVALID;


@@ -1076,15 +1085,18 @@ int brcmf_attach(struct device *dev, struct brcmf_mp_device *settings)
	/* attach firmware event handler */
	/* attach firmware event handler */
	brcmf_fweh_attach(drvr);
	brcmf_fweh_attach(drvr);


	ret = brcmf_bus_started(drvr);
	ret = brcmf_bus_started(drvr, ops);
	if (ret != 0) {
	if (ret != 0) {
		brcmf_err("dongle is not responding: err=%d\n", ret);
		brcmf_err("dongle is not responding: err=%d\n", ret);
		goto fail;
		goto fail;
	}
	}

	drvr->config->ops = ops;
	return 0;
	return 0;


fail:
fail:
	brcmf_detach(dev);
	brcmf_detach(dev);
	kfree(ops);


	return ret;
	return ret;
}
}
@@ -1142,6 +1154,7 @@ void brcmf_detach(struct device *dev)
		brcmf_remove_interface(drvr->iflist[i], false);
		brcmf_remove_interface(drvr->iflist[i], false);


	brcmf_cfg80211_detach(drvr->config);
	brcmf_cfg80211_detach(drvr->config);
	drvr->config = NULL;


	brcmf_bus_stop(drvr->bus_if);
	brcmf_bus_stop(drvr->bus_if);


@@ -1149,7 +1162,7 @@ void brcmf_detach(struct device *dev)


	brcmf_debug_detach(drvr);
	brcmf_debug_detach(drvr);
	bus_if->drvr = NULL;
	bus_if->drvr = NULL;
	kfree(drvr);
	wiphy_free(drvr->wiphy);
}
}


s32 brcmf_iovar_data_set(struct device *dev, char *name, void *data, u32 len)
s32 brcmf_iovar_data_set(struct device *dev, char *name, void *data, u32 len)
Loading