 72f6025d69
			
		
	
	72f6025d69
	
	
	
		
			
			It backports brcmfmac commits from kernel 4.17.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
(cherry picked from commit 3c8bb92655)
		
	
		
			
				
	
	
		
			453 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			453 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| From 856d5a011c86b59f6564be4508912fb1d866adfc Mon Sep 17 00:00:00 2001
 | |
| From: Arend Van Spriel <arend.vanspriel@broadcom.com>
 | |
| Date: Thu, 22 Mar 2018 21:28:23 +0100
 | |
| Subject: [PATCH] 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: Hante Meuleman <hante.meuleman@broadcom.com>
 | |
| Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
 | |
| Reviewed-by: Franky Lin <franky.lin@broadcom.com>
 | |
| Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
 | |
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
 | |
| ---
 | |
|  .../wireless/broadcom/brcm80211/brcmfmac/btcoex.c  |  2 +-
 | |
|  .../broadcom/brcm80211/brcmfmac/cfg80211.c         | 86 ++++++++++------------
 | |
|  .../broadcom/brcm80211/brcmfmac/cfg80211.h         | 17 +++--
 | |
|  .../wireless/broadcom/brcm80211/brcmfmac/common.c  |  2 +
 | |
|  .../wireless/broadcom/brcm80211/brcmfmac/core.c    | 27 +++++--
 | |
|  .../wireless/broadcom/brcm80211/brcmfmac/core.h    |  1 +
 | |
|  .../net/wireless/broadcom/brcm80211/brcmfmac/p2p.c |  2 +-
 | |
|  7 files changed, 76 insertions(+), 61 deletions(-)
 | |
| 
 | |
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/btcoex.c
 | |
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/btcoex.c
 | |
| @@ -462,7 +462,7 @@ static void brcmf_btcoex_dhcp_end(struct
 | |
|  int brcmf_btcoex_set_mode(struct brcmf_cfg80211_vif *vif,
 | |
|  			  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_if *ifp = brcmf_get_ifp(cfg->pub, 0);
 | |
|  
 | |
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
 | |
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
 | |
| @@ -753,7 +753,7 @@ s32 brcmf_notify_escan_complete(struct b
 | |
|  static int brcmf_cfg80211_del_ap_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 brcmf_if *ifp = netdev_priv(ndev);
 | |
|  	int ret;
 | |
| @@ -786,7 +786,7 @@ err_unarm:
 | |
|  static
 | |
|  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;
 | |
|  
 | |
|  	if (ndev && ndev == cfg_to_ndev(cfg))
 | |
| @@ -831,7 +831,7 @@ brcmf_cfg80211_change_iface(struct wiphy
 | |
|  			 enum nl80211_iftype type,
 | |
|  			 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_cfg80211_vif *vif = ifp->vif;
 | |
|  	s32 infra = 0;
 | |
| @@ -2127,17 +2127,15 @@ static s32
 | |
|  brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
 | |
|  			    s32 *dbm)
 | |
|  {
 | |
| -	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
 | |
| -	struct net_device *ndev = cfg_to_ndev(cfg);
 | |
| -	struct brcmf_if *ifp = netdev_priv(ndev);
 | |
| +	struct brcmf_cfg80211_vif *vif = wdev_to_vif(wdev);
 | |
|  	s32 qdbm = 0;
 | |
|  	s32 err;
 | |
|  
 | |
|  	brcmf_dbg(TRACE, "Enter\n");
 | |
| -	if (!check_vif_up(ifp->vif))
 | |
| +	if (!check_vif_up(vif))
 | |
|  		return -EIO;
 | |
|  
 | |
| -	err = brcmf_fil_iovar_int_get(ifp, "qtxpower", &qdbm);
 | |
| +	err = brcmf_fil_iovar_int_get(vif->ifp, "qtxpower", &qdbm);
 | |
|  	if (err) {
 | |
|  		brcmf_err("error (%d)\n", err);
 | |
|  		goto done;
 | |
| @@ -3359,7 +3357,7 @@ brcmf_cfg80211_sched_scan_start(struct w
 | |
|  				struct cfg80211_sched_scan_request *req)
 | |
|  {
 | |
|  	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",
 | |
|  		  req->n_match_sets, req->n_ssids);
 | |
| @@ -5191,6 +5189,12 @@ static struct cfg80211_ops brcmf_cfg8021
 | |
|  	.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,
 | |
|  					   enum nl80211_iftype type)
 | |
|  {
 | |
| @@ -5898,7 +5902,7 @@ static void brcmf_update_bw40_channel_fl
 | |
|  static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg,
 | |
|  				    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_channel *channel;
 | |
|  	struct wiphy *wiphy;
 | |
| @@ -6013,7 +6017,7 @@ fail_pbuf:
 | |
|  
 | |
|  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 brcmf_fil_bwcap_le band_bwcap;
 | |
|  	struct brcmf_chanspec_list *list;
 | |
| @@ -6198,10 +6202,10 @@ static void brcmf_update_vht_cap(struct
 | |
|  	}
 | |
|  }
 | |
|  
 | |
| -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 = netdev_priv(cfg_to_ndev(cfg));
 | |
| +	struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0);
 | |
| +	struct wiphy *wiphy;
 | |
|  	u32 nmode = 0;
 | |
|  	u32 vhtmode = 0;
 | |
|  	u32 bw_cap[2] = { WLC_BW_20MHZ_BIT, WLC_BW_20MHZ_BIT };
 | |
| @@ -6795,8 +6799,8 @@ static s32 brcmf_translate_country_code(
 | |
|  static void brcmf_cfg80211_reg_notifier(struct wiphy *wiphy,
 | |
|  					struct regulatory_request *req)
 | |
|  {
 | |
| -	struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
 | |
| -	struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
 | |
| +	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
 | |
| +	struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0);
 | |
|  	struct brcmf_fil_country_le ccreq;
 | |
|  	s32 err;
 | |
|  	int i;
 | |
| @@ -6831,7 +6835,7 @@ static void brcmf_cfg80211_reg_notifier(
 | |
|  		brcmf_err("Firmware rejected country setting\n");
 | |
|  		return;
 | |
|  	}
 | |
| -	brcmf_setup_wiphybands(wiphy);
 | |
| +	brcmf_setup_wiphybands(cfg);
 | |
|  }
 | |
|  
 | |
|  static void brcmf_free_wiphy(struct wiphy *wiphy)
 | |
| @@ -6858,17 +6862,15 @@ static void brcmf_free_wiphy(struct wiph
 | |
|  	if (wiphy->wowlan != &brcmf_wowlan_support)
 | |
|  		kfree(wiphy->wowlan);
 | |
|  #endif
 | |
| -	wiphy_free(wiphy);
 | |
|  }
 | |
|  
 | |
|  struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
 | |
| -						  struct device *busdev,
 | |
| +						  struct cfg80211_ops *ops,
 | |
|  						  bool p2pdev_forced)
 | |
|  {
 | |
| +	struct wiphy *wiphy = drvr->wiphy;
 | |
|  	struct net_device *ndev = brcmf_get_ifp(drvr, 0)->ndev;
 | |
|  	struct brcmf_cfg80211_info *cfg;
 | |
| -	struct wiphy *wiphy;
 | |
| -	struct cfg80211_ops *ops;
 | |
|  	struct brcmf_cfg80211_vif *vif;
 | |
|  	struct brcmf_if *ifp;
 | |
|  	s32 err = 0;
 | |
| @@ -6880,26 +6882,13 @@ struct brcmf_cfg80211_info *brcmf_cfg802
 | |
|  		return NULL;
 | |
|  	}
 | |
|  
 | |
| -	ops = kmemdup(&brcmf_cfg80211_ops, sizeof(*ops), GFP_KERNEL);
 | |
| -	if (!ops)
 | |
| -		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) {
 | |
| +	cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
 | |
| +	if (!cfg) {
 | |
|  		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->ops = ops;
 | |
|  	cfg->pub = drvr;
 | |
|  	init_vif_event(&cfg->vif_event);
 | |
|  	INIT_LIST_HEAD(&cfg->vif_list);
 | |
| @@ -6908,6 +6897,7 @@ struct brcmf_cfg80211_info *brcmf_cfg802
 | |
|  	if (IS_ERR(vif))
 | |
|  		goto wiphy_out;
 | |
|  
 | |
| +	ifp = netdev_priv(ndev);
 | |
|  	vif->ifp = ifp;
 | |
|  	vif->wdev.netdev = ndev;
 | |
|  	ndev->ieee80211_ptr = &vif->wdev;
 | |
| @@ -6934,6 +6924,11 @@ struct brcmf_cfg80211_info *brcmf_cfg802
 | |
|  	if (err < 0)
 | |
|  		goto priv_out;
 | |
|  
 | |
| +	/* regulatory notifer below needs access to cfg so
 | |
| +	 * assign it now.
 | |
| +	 */
 | |
| +	drvr->config = cfg;
 | |
| +
 | |
|  	brcmf_dbg(INFO, "Registering custom regulatory\n");
 | |
|  	wiphy->reg_notifier = brcmf_cfg80211_reg_notifier;
 | |
|  	wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
 | |
| @@ -6947,13 +6942,17 @@ struct brcmf_cfg80211_info *brcmf_cfg802
 | |
|  		cap = &wiphy->bands[NL80211_BAND_2GHZ]->ht_cap.cap;
 | |
|  		*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);
 | |
|  	if (err < 0) {
 | |
|  		brcmf_err("Could not register wiphy device (%d)\n", err);
 | |
|  		goto priv_out;
 | |
|  	}
 | |
|  
 | |
| -	err = brcmf_setup_wiphybands(wiphy);
 | |
| +	err = brcmf_setup_wiphybands(cfg);
 | |
|  	if (err) {
 | |
|  		brcmf_err("Setting wiphy bands failed (%d)\n", err);
 | |
|  		goto wiphy_unreg_out;
 | |
| @@ -6970,12 +6969,7 @@ struct brcmf_cfg80211_info *brcmf_cfg802
 | |
|  		else
 | |
|  			*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);
 | |
|  	if (err) {
 | |
|  		brcmf_err("FWEH activation failed (%d)\n", err);
 | |
| @@ -7043,8 +7037,7 @@ priv_out:
 | |
|  	ifp->vif = NULL;
 | |
|  wiphy_out:
 | |
|  	brcmf_free_wiphy(wiphy);
 | |
| -ops_out:
 | |
| -	kfree(ops);
 | |
| +	kfree(cfg);
 | |
|  	return NULL;
 | |
|  }
 | |
|  
 | |
| @@ -7059,4 +7052,5 @@ void brcmf_cfg80211_detach(struct brcmf_
 | |
|  	kfree(cfg->ops);
 | |
|  	wl_deinit_priv(cfg);
 | |
|  	brcmf_free_wiphy(cfg->wiphy);
 | |
| +	kfree(cfg);
 | |
|  }
 | |
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
 | |
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
 | |
| @@ -355,20 +355,24 @@ static inline struct wiphy *cfg_to_wiphy
 | |
|  
 | |
|  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)
 | |
|  {
 | |
| -	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
 | |
|  struct net_device *cfg_to_ndev(struct brcmf_cfg80211_info *cfg)
 | |
|  {
 | |
| -	struct brcmf_cfg80211_vif *vif;
 | |
| -	vif = list_first_entry(&cfg->vif_list, struct brcmf_cfg80211_vif, list);
 | |
| -	return vif->wdev.netdev;
 | |
| +	return brcmf_get_ifp(cfg->pub, 0)->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 *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
 | |
| -						  struct device *busdev,
 | |
| +						  struct cfg80211_ops *ops,
 | |
|  						  bool p2pdev_forced);
 | |
|  void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg);
 | |
|  s32 brcmf_cfg80211_up(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);
 | |
|  
 | |
|  struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
 | |
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
 | |
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
 | |
| @@ -252,6 +252,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_i
 | |
|  		brcmf_err("Retreiving cur_etheraddr failed, %d\n", err);
 | |
|  		goto done;
 | |
|  	}
 | |
| +	memcpy(ifp->drvr->wiphy->perm_addr, ifp->drvr->mac, ETH_ALEN);
 | |
|  	memcpy(ifp->drvr->mac, ifp->mac_addr, sizeof(ifp->drvr->mac));
 | |
|  
 | |
|  	bus = ifp->drvr->bus_if;
 | |
| @@ -279,6 +280,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_i
 | |
|  		ri->chippkg = le32_to_cpu(revinfo.chippkg);
 | |
|  		ri->nvramrev = le32_to_cpu(revinfo.nvramrev);
 | |
|  
 | |
| +		/* use revinfo if not known yet */
 | |
|  		if (!bus->chip) {
 | |
|  			bus->chip = le32_to_cpu(revinfo.chipnum);
 | |
|  			bus->chiprev = le32_to_cpu(revinfo.chiprev);
 | |
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
 | |
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
 | |
| @@ -1021,7 +1021,7 @@ static int brcmf_revinfo_read(struct seq
 | |
|  	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;
 | |
|  	struct brcmf_bus *bus_if = drvr->bus_if;
 | |
| @@ -1060,7 +1060,7 @@ static int brcmf_bus_started(struct brcm
 | |
|  
 | |
|  	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);
 | |
|  	if (drvr->config == NULL) {
 | |
|  		ret = -ENOMEM;
 | |
| @@ -1115,17 +1115,26 @@ fail:
 | |
|  
 | |
|  int brcmf_attach(struct device *dev, struct brcmf_mp_device *settings)
 | |
|  {
 | |
| +	struct wiphy *wiphy;
 | |
| +	struct cfg80211_ops *ops;
 | |
|  	struct brcmf_pub *drvr = NULL;
 | |
|  	int ret = 0;
 | |
|  	int i;
 | |
|  
 | |
|  	brcmf_dbg(TRACE, "Enter\n");
 | |
|  
 | |
| -	/* Allocate primary brcmf_info */
 | |
| -	drvr = kzalloc(sizeof(*drvr), GFP_ATOMIC);
 | |
| -	if (!drvr)
 | |
| +	ops = brcmf_cfg80211_get_ops();
 | |
| +	if (!ops)
 | |
|  		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++)
 | |
|  		drvr->if2bss[i] = BRCMF_BSSIDX_INVALID;
 | |
|  
 | |
| @@ -1154,15 +1163,18 @@ int brcmf_attach(struct device *dev, str
 | |
|  	/* attach firmware event handler */
 | |
|  	brcmf_fweh_attach(drvr);
 | |
|  
 | |
| -	ret = brcmf_bus_started(drvr);
 | |
| +	ret = brcmf_bus_started(drvr, ops);
 | |
|  	if (ret != 0) {
 | |
|  		brcmf_err("dongle is not responding: err=%d\n", ret);
 | |
|  		goto fail;
 | |
|  	}
 | |
| +
 | |
| +	drvr->config->ops = ops;
 | |
|  	return 0;
 | |
|  
 | |
|  fail:
 | |
|  	brcmf_detach(dev);
 | |
| +	kfree(ops);
 | |
|  
 | |
|  	return ret;
 | |
|  }
 | |
| @@ -1220,6 +1232,7 @@ void brcmf_detach(struct device *dev)
 | |
|  		brcmf_remove_interface(drvr->iflist[i], false);
 | |
|  
 | |
|  	brcmf_cfg80211_detach(drvr->config);
 | |
| +	drvr->config = NULL;
 | |
|  
 | |
|  	brcmf_bus_stop(drvr->bus_if);
 | |
|  
 | |
| @@ -1227,7 +1240,7 @@ void brcmf_detach(struct device *dev)
 | |
|  
 | |
|  	brcmf_debug_detach(drvr);
 | |
|  	bus_if->drvr = NULL;
 | |
| -	kfree(drvr);
 | |
| +	wiphy_free(drvr->wiphy);
 | |
|  }
 | |
|  
 | |
|  s32 brcmf_iovar_data_set(struct device *dev, char *name, void *data, u32 len)
 | |
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
 | |
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
 | |
| @@ -107,6 +107,7 @@ struct brcmf_pub {
 | |
|  	/* Linkage ponters */
 | |
|  	struct brcmf_bus *bus_if;
 | |
|  	struct brcmf_proto *proto;
 | |
| +	struct wiphy *wiphy;
 | |
|  	struct brcmf_cfg80211_info *config;
 | |
|  
 | |
|  	/* Internal brcmf items */
 | |
| --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
 | |
| +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
 | |
| @@ -2229,7 +2229,7 @@ fail:
 | |
|   */
 | |
|  int brcmf_p2p_del_vif(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 brcmf_p2p_info *p2p = &cfg->p2p;
 | |
|  	struct brcmf_cfg80211_vif *vif;
 | |
|  	enum nl80211_iftype iftype;
 |