42adff61b9db8726f3a831c1eb2e801a2cd6f4f2
[oweals/openwrt.git] /
1 From 856d5a011c86b59f6564be4508912fb1d866adfc Mon Sep 17 00:00:00 2001
2 From: Arend Van Spriel <arend.vanspriel@broadcom.com>
3 Date: Thu, 22 Mar 2018 21:28:23 +0100
4 Subject: [PATCH] brcmfmac: allocate struct brcmf_pub instance using
5  wiphy_new()
6
7 Rework the driver so the wiphy instance holds the main driver information
8 in its private buffer. Previously it held struct brcmf_cfg80211_info
9 instance so a bit of reorg was needed. This was done so that the wiphy
10 name or its parent device can be shown in debug output.
11
12 Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
13 Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
14 Reviewed-by: Franky Lin <franky.lin@broadcom.com>
15 Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
16 Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
17 ---
18  .../wireless/broadcom/brcm80211/brcmfmac/btcoex.c  |  2 +-
19  .../broadcom/brcm80211/brcmfmac/cfg80211.c         | 86 ++++++++++------------
20  .../broadcom/brcm80211/brcmfmac/cfg80211.h         | 17 +++--
21  .../wireless/broadcom/brcm80211/brcmfmac/common.c  |  2 +
22  .../wireless/broadcom/brcm80211/brcmfmac/core.c    | 27 +++++--
23  .../wireless/broadcom/brcm80211/brcmfmac/core.h    |  1 +
24  .../net/wireless/broadcom/brcm80211/brcmfmac/p2p.c |  2 +-
25  7 files changed, 76 insertions(+), 61 deletions(-)
26
27 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/btcoex.c
28 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/btcoex.c
29 @@ -462,7 +462,7 @@ static void brcmf_btcoex_dhcp_end(struct
30  int brcmf_btcoex_set_mode(struct brcmf_cfg80211_vif *vif,
31                           enum brcmf_btcoex_mode mode, u16 duration)
32  {
33 -       struct brcmf_cfg80211_info *cfg = wiphy_priv(vif->wdev.wiphy);
34 +       struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(vif->wdev.wiphy);
35         struct brcmf_btcoex_info *btci = cfg->btcoex;
36         struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0);
37  
38 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
39 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
40 @@ -753,7 +753,7 @@ s32 brcmf_notify_escan_complete(struct b
41  static int brcmf_cfg80211_del_ap_iface(struct wiphy *wiphy,
42                                        struct wireless_dev *wdev)
43  {
44 -       struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
45 +       struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
46         struct net_device *ndev = wdev->netdev;
47         struct brcmf_if *ifp = netdev_priv(ndev);
48         int ret;
49 @@ -786,7 +786,7 @@ err_unarm:
50  static
51  int brcmf_cfg80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev)
52  {
53 -       struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
54 +       struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
55         struct net_device *ndev = wdev->netdev;
56  
57         if (ndev && ndev == cfg_to_ndev(cfg))
58 @@ -831,7 +831,7 @@ brcmf_cfg80211_change_iface(struct wiphy
59                          enum nl80211_iftype type,
60                          struct vif_params *params)
61  {
62 -       struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
63 +       struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
64         struct brcmf_if *ifp = netdev_priv(ndev);
65         struct brcmf_cfg80211_vif *vif = ifp->vif;
66         s32 infra = 0;
67 @@ -2127,17 +2127,15 @@ static s32
68  brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
69                             s32 *dbm)
70  {
71 -       struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
72 -       struct net_device *ndev = cfg_to_ndev(cfg);
73 -       struct brcmf_if *ifp = netdev_priv(ndev);
74 +       struct brcmf_cfg80211_vif *vif = wdev_to_vif(wdev);
75         s32 qdbm = 0;
76         s32 err;
77  
78         brcmf_dbg(TRACE, "Enter\n");
79 -       if (!check_vif_up(ifp->vif))
80 +       if (!check_vif_up(vif))
81                 return -EIO;
82  
83 -       err = brcmf_fil_iovar_int_get(ifp, "qtxpower", &qdbm);
84 +       err = brcmf_fil_iovar_int_get(vif->ifp, "qtxpower", &qdbm);
85         if (err) {
86                 brcmf_err("error (%d)\n", err);
87                 goto done;
88 @@ -3359,7 +3357,7 @@ brcmf_cfg80211_sched_scan_start(struct w
89                                 struct cfg80211_sched_scan_request *req)
90  {
91         struct brcmf_if *ifp = netdev_priv(ndev);
92 -       struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
93 +       struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
94  
95         brcmf_dbg(SCAN, "Enter: n_match_sets=%d n_ssids=%d\n",
96                   req->n_match_sets, req->n_ssids);
97 @@ -5191,6 +5189,12 @@ static struct cfg80211_ops brcmf_cfg8021
98         .del_pmk = brcmf_cfg80211_del_pmk,
99  };
100  
101 +struct cfg80211_ops *brcmf_cfg80211_get_ops(void)
102 +{
103 +       return kmemdup(&brcmf_cfg80211_ops, sizeof(brcmf_cfg80211_ops),
104 +                      GFP_KERNEL);
105 +}
106 +
107  struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
108                                            enum nl80211_iftype type)
109  {
110 @@ -5898,7 +5902,7 @@ static void brcmf_update_bw40_channel_fl
111  static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg,
112                                     u32 bw_cap[])
113  {
114 -       struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
115 +       struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0);
116         struct ieee80211_supported_band *band;
117         struct ieee80211_channel *channel;
118         struct wiphy *wiphy;
119 @@ -6013,7 +6017,7 @@ fail_pbuf:
120  
121  static int brcmf_enable_bw40_2g(struct brcmf_cfg80211_info *cfg)
122  {
123 -       struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
124 +       struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0);
125         struct ieee80211_supported_band *band;
126         struct brcmf_fil_bwcap_le band_bwcap;
127         struct brcmf_chanspec_list *list;
128 @@ -6198,10 +6202,10 @@ static void brcmf_update_vht_cap(struct
129         }
130  }
131  
132 -static int brcmf_setup_wiphybands(struct wiphy *wiphy)
133 +static int brcmf_setup_wiphybands(struct brcmf_cfg80211_info *cfg)
134  {
135 -       struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
136 -       struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
137 +       struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0);
138 +       struct wiphy *wiphy;
139         u32 nmode = 0;
140         u32 vhtmode = 0;
141         u32 bw_cap[2] = { WLC_BW_20MHZ_BIT, WLC_BW_20MHZ_BIT };
142 @@ -6795,8 +6799,8 @@ static s32 brcmf_translate_country_code(
143  static void brcmf_cfg80211_reg_notifier(struct wiphy *wiphy,
144                                         struct regulatory_request *req)
145  {
146 -       struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
147 -       struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
148 +       struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
149 +       struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0);
150         struct brcmf_fil_country_le ccreq;
151         s32 err;
152         int i;
153 @@ -6831,7 +6835,7 @@ static void brcmf_cfg80211_reg_notifier(
154                 brcmf_err("Firmware rejected country setting\n");
155                 return;
156         }
157 -       brcmf_setup_wiphybands(wiphy);
158 +       brcmf_setup_wiphybands(cfg);
159  }
160  
161  static void brcmf_free_wiphy(struct wiphy *wiphy)
162 @@ -6858,17 +6862,15 @@ static void brcmf_free_wiphy(struct wiph
163         if (wiphy->wowlan != &brcmf_wowlan_support)
164                 kfree(wiphy->wowlan);
165  #endif
166 -       wiphy_free(wiphy);
167  }
168  
169  struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
170 -                                                 struct device *busdev,
171 +                                                 struct cfg80211_ops *ops,
172                                                   bool p2pdev_forced)
173  {
174 +       struct wiphy *wiphy = drvr->wiphy;
175         struct net_device *ndev = brcmf_get_ifp(drvr, 0)->ndev;
176         struct brcmf_cfg80211_info *cfg;
177 -       struct wiphy *wiphy;
178 -       struct cfg80211_ops *ops;
179         struct brcmf_cfg80211_vif *vif;
180         struct brcmf_if *ifp;
181         s32 err = 0;
182 @@ -6880,26 +6882,13 @@ struct brcmf_cfg80211_info *brcmf_cfg802
183                 return NULL;
184         }
185  
186 -       ops = kmemdup(&brcmf_cfg80211_ops, sizeof(*ops), GFP_KERNEL);
187 -       if (!ops)
188 -               return NULL;
189 -
190 -       ifp = netdev_priv(ndev);
191 -#ifdef CONFIG_PM
192 -       if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_GTK))
193 -               ops->set_rekey_data = brcmf_cfg80211_set_rekey_data;
194 -#endif
195 -       wiphy = wiphy_new(ops, sizeof(struct brcmf_cfg80211_info));
196 -       if (!wiphy) {
197 +       cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
198 +       if (!cfg) {
199                 brcmf_err("Could not allocate wiphy device\n");
200 -               goto ops_out;
201 +               return NULL;
202         }
203 -       memcpy(wiphy->perm_addr, drvr->mac, ETH_ALEN);
204 -       set_wiphy_dev(wiphy, busdev);
205  
206 -       cfg = wiphy_priv(wiphy);
207         cfg->wiphy = wiphy;
208 -       cfg->ops = ops;
209         cfg->pub = drvr;
210         init_vif_event(&cfg->vif_event);
211         INIT_LIST_HEAD(&cfg->vif_list);
212 @@ -6908,6 +6897,7 @@ struct brcmf_cfg80211_info *brcmf_cfg802
213         if (IS_ERR(vif))
214                 goto wiphy_out;
215  
216 +       ifp = netdev_priv(ndev);
217         vif->ifp = ifp;
218         vif->wdev.netdev = ndev;
219         ndev->ieee80211_ptr = &vif->wdev;
220 @@ -6934,6 +6924,11 @@ struct brcmf_cfg80211_info *brcmf_cfg802
221         if (err < 0)
222                 goto priv_out;
223  
224 +       /* regulatory notifer below needs access to cfg so
225 +        * assign it now.
226 +        */
227 +       drvr->config = cfg;
228 +
229         brcmf_dbg(INFO, "Registering custom regulatory\n");
230         wiphy->reg_notifier = brcmf_cfg80211_reg_notifier;
231         wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
232 @@ -6947,13 +6942,17 @@ struct brcmf_cfg80211_info *brcmf_cfg802
233                 cap = &wiphy->bands[NL80211_BAND_2GHZ]->ht_cap.cap;
234                 *cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
235         }
236 +#ifdef CONFIG_PM
237 +       if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_GTK))
238 +               ops->set_rekey_data = brcmf_cfg80211_set_rekey_data;
239 +#endif
240         err = wiphy_register(wiphy);
241         if (err < 0) {
242                 brcmf_err("Could not register wiphy device (%d)\n", err);
243                 goto priv_out;
244         }
245  
246 -       err = brcmf_setup_wiphybands(wiphy);
247 +       err = brcmf_setup_wiphybands(cfg);
248         if (err) {
249                 brcmf_err("Setting wiphy bands failed (%d)\n", err);
250                 goto wiphy_unreg_out;
251 @@ -6970,12 +6969,7 @@ struct brcmf_cfg80211_info *brcmf_cfg802
252                 else
253                         *cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
254         }
255 -       /* p2p might require that "if-events" get processed by fweh. So
256 -        * activate the already registered event handlers now and activate
257 -        * the rest when initialization has completed. drvr->config needs to
258 -        * be assigned before activating events.
259 -        */
260 -       drvr->config = cfg;
261 +
262         err = brcmf_fweh_activate_events(ifp);
263         if (err) {
264                 brcmf_err("FWEH activation failed (%d)\n", err);
265 @@ -7043,8 +7037,7 @@ priv_out:
266         ifp->vif = NULL;
267  wiphy_out:
268         brcmf_free_wiphy(wiphy);
269 -ops_out:
270 -       kfree(ops);
271 +       kfree(cfg);
272         return NULL;
273  }
274  
275 @@ -7059,4 +7052,5 @@ void brcmf_cfg80211_detach(struct brcmf_
276         kfree(cfg->ops);
277         wl_deinit_priv(cfg);
278         brcmf_free_wiphy(cfg->wiphy);
279 +       kfree(cfg);
280  }
281 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
282 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
283 @@ -355,20 +355,24 @@ static inline struct wiphy *cfg_to_wiphy
284  
285  static inline struct brcmf_cfg80211_info *wiphy_to_cfg(struct wiphy *w)
286  {
287 -       return (struct brcmf_cfg80211_info *)(wiphy_priv(w));
288 +       struct brcmf_pub *drvr = wiphy_priv(w);
289 +       return drvr->config;
290  }
291  
292  static inline struct brcmf_cfg80211_info *wdev_to_cfg(struct wireless_dev *wd)
293  {
294 -       return (struct brcmf_cfg80211_info *)(wdev_priv(wd));
295 +       return wiphy_to_cfg(wd->wiphy);
296 +}
297 +
298 +static inline struct brcmf_cfg80211_vif *wdev_to_vif(struct wireless_dev *wdev)
299 +{
300 +       return container_of(wdev, struct brcmf_cfg80211_vif, wdev);
301  }
302  
303  static inline
304  struct net_device *cfg_to_ndev(struct brcmf_cfg80211_info *cfg)
305  {
306 -       struct brcmf_cfg80211_vif *vif;
307 -       vif = list_first_entry(&cfg->vif_list, struct brcmf_cfg80211_vif, list);
308 -       return vif->wdev.netdev;
309 +       return brcmf_get_ifp(cfg->pub, 0)->ndev;
310  }
311  
312  static inline struct brcmf_cfg80211_info *ndev_to_cfg(struct net_device *ndev)
313 @@ -395,11 +399,12 @@ brcmf_cfg80211_connect_info *cfg_to_conn
314  }
315  
316  struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
317 -                                                 struct device *busdev,
318 +                                                 struct cfg80211_ops *ops,
319                                                   bool p2pdev_forced);
320  void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg);
321  s32 brcmf_cfg80211_up(struct net_device *ndev);
322  s32 brcmf_cfg80211_down(struct net_device *ndev);
323 +struct cfg80211_ops *brcmf_cfg80211_get_ops(void);
324  enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp);
325  
326  struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
327 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
328 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
329 @@ -252,6 +252,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_i
330                 brcmf_err("Retreiving cur_etheraddr failed, %d\n", err);
331                 goto done;
332         }
333 +       memcpy(ifp->drvr->wiphy->perm_addr, ifp->drvr->mac, ETH_ALEN);
334         memcpy(ifp->drvr->mac, ifp->mac_addr, sizeof(ifp->drvr->mac));
335  
336         bus = ifp->drvr->bus_if;
337 @@ -279,6 +280,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_i
338                 ri->chippkg = le32_to_cpu(revinfo.chippkg);
339                 ri->nvramrev = le32_to_cpu(revinfo.nvramrev);
340  
341 +               /* use revinfo if not known yet */
342                 if (!bus->chip) {
343                         bus->chip = le32_to_cpu(revinfo.chipnum);
344                         bus->chiprev = le32_to_cpu(revinfo.chiprev);
345 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
346 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
347 @@ -1021,7 +1021,7 @@ static int brcmf_revinfo_read(struct seq
348         return 0;
349  }
350  
351 -static int brcmf_bus_started(struct brcmf_pub *drvr)
352 +static int brcmf_bus_started(struct brcmf_pub *drvr, struct cfg80211_ops *ops)
353  {
354         int ret = -1;
355         struct brcmf_bus *bus_if = drvr->bus_if;
356 @@ -1060,7 +1060,7 @@ static int brcmf_bus_started(struct brcm
357  
358         brcmf_proto_add_if(drvr, ifp);
359  
360 -       drvr->config = brcmf_cfg80211_attach(drvr, bus_if->dev,
361 +       drvr->config = brcmf_cfg80211_attach(drvr, ops,
362                                              drvr->settings->p2p_enable);
363         if (drvr->config == NULL) {
364                 ret = -ENOMEM;
365 @@ -1115,17 +1115,26 @@ fail:
366  
367  int brcmf_attach(struct device *dev, struct brcmf_mp_device *settings)
368  {
369 +       struct wiphy *wiphy;
370 +       struct cfg80211_ops *ops;
371         struct brcmf_pub *drvr = NULL;
372         int ret = 0;
373         int i;
374  
375         brcmf_dbg(TRACE, "Enter\n");
376  
377 -       /* Allocate primary brcmf_info */
378 -       drvr = kzalloc(sizeof(*drvr), GFP_ATOMIC);
379 -       if (!drvr)
380 +       ops = brcmf_cfg80211_get_ops();
381 +       if (!ops)
382                 return -ENOMEM;
383  
384 +       wiphy = wiphy_new(ops, sizeof(*drvr));
385 +       if (!wiphy)
386 +               return -ENOMEM;
387 +
388 +       set_wiphy_dev(wiphy, dev);
389 +       drvr = wiphy_priv(wiphy);
390 +       drvr->wiphy = wiphy;
391 +
392         for (i = 0; i < ARRAY_SIZE(drvr->if2bss); i++)
393                 drvr->if2bss[i] = BRCMF_BSSIDX_INVALID;
394  
395 @@ -1154,15 +1163,18 @@ int brcmf_attach(struct device *dev, str
396         /* attach firmware event handler */
397         brcmf_fweh_attach(drvr);
398  
399 -       ret = brcmf_bus_started(drvr);
400 +       ret = brcmf_bus_started(drvr, ops);
401         if (ret != 0) {
402                 brcmf_err("dongle is not responding: err=%d\n", ret);
403                 goto fail;
404         }
405 +
406 +       drvr->config->ops = ops;
407         return 0;
408  
409  fail:
410         brcmf_detach(dev);
411 +       kfree(ops);
412  
413         return ret;
414  }
415 @@ -1220,6 +1232,7 @@ void brcmf_detach(struct device *dev)
416                 brcmf_remove_interface(drvr->iflist[i], false);
417  
418         brcmf_cfg80211_detach(drvr->config);
419 +       drvr->config = NULL;
420  
421         brcmf_bus_stop(drvr->bus_if);
422  
423 @@ -1227,7 +1240,7 @@ void brcmf_detach(struct device *dev)
424  
425         brcmf_debug_detach(drvr);
426         bus_if->drvr = NULL;
427 -       kfree(drvr);
428 +       wiphy_free(drvr->wiphy);
429  }
430  
431  s32 brcmf_iovar_data_set(struct device *dev, char *name, void *data, u32 len)
432 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
433 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
434 @@ -107,6 +107,7 @@ struct brcmf_pub {
435         /* Linkage ponters */
436         struct brcmf_bus *bus_if;
437         struct brcmf_proto *proto;
438 +       struct wiphy *wiphy;
439         struct brcmf_cfg80211_info *config;
440  
441         /* Internal brcmf items */
442 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
443 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
444 @@ -2229,7 +2229,7 @@ fail:
445   */
446  int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev)
447  {
448 -       struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
449 +       struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
450         struct brcmf_p2p_info *p2p = &cfg->p2p;
451         struct brcmf_cfg80211_vif *vif;
452         enum nl80211_iftype iftype;