6f400088b10a68c18ff813f3dbb9194ff9780c8e
[openwrt/staging/pepe2k.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 @@ -464,7 +464,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 @@ -783,7 +783,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 @@ -816,7 +816,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 @@ -861,7 +861,7 @@ brcmf_cfg80211_change_iface(struct wiphy
59 enum nl80211_iftype type, u32 *flags,
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 @@ -2175,17 +2175,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 @@ -3398,7 +3396,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 @@ -5192,6 +5190,12 @@ static struct cfg80211_ops brcmf_cfg8021
98 .update_connect_params = brcmf_cfg80211_update_conn_params,
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 @@ -5866,7 +5870,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 @@ -5981,7 +5985,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 @@ -6166,10 +6170,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 @@ -6764,8 +6768,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 @@ -6800,7 +6804,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 @@ -6827,17 +6831,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 @@ -6849,26 +6851,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 @@ -6877,6 +6866,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 @@ -6903,6 +6893,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 @@ -6916,13 +6911,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 @@ -6939,12 +6938,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 @@ -7004,8 +6998,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 @@ -7016,7 +7009,8 @@ void brcmf_cfg80211_detach(struct brcmf_
276
277 brcmf_btcoex_detach(cfg);
278 wiphy_unregister(cfg->wiphy);
279 - kfree(cfg->ops);
280 + kfree(cfg->pub->cfg80211_ops);
281 wl_deinit_priv(cfg);
282 brcmf_free_wiphy(cfg->wiphy);
283 + kfree(cfg);
284 }
285 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
286 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
287 @@ -290,7 +290,7 @@ struct brcmf_cfg80211_wowl {
288 */
289 struct brcmf_cfg80211_info {
290 struct wiphy *wiphy;
291 - struct cfg80211_ops *ops;
292 +// struct cfg80211_ops *ops; /* OpenWrt keeps it in the struct brcmf_pub */
293 struct brcmf_cfg80211_conf *conf;
294 struct brcmf_p2p_info p2p;
295 struct brcmf_btcoex_info *btcoex;
296 @@ -342,20 +342,24 @@ static inline struct wiphy *cfg_to_wiphy
297
298 static inline struct brcmf_cfg80211_info *wiphy_to_cfg(struct wiphy *w)
299 {
300 - return (struct brcmf_cfg80211_info *)(wiphy_priv(w));
301 + struct brcmf_pub *drvr = wiphy_priv(w);
302 + return drvr->config;
303 }
304
305 static inline struct brcmf_cfg80211_info *wdev_to_cfg(struct wireless_dev *wd)
306 {
307 - return (struct brcmf_cfg80211_info *)(wdev_priv(wd));
308 + return wiphy_to_cfg(wd->wiphy);
309 +}
310 +
311 +static inline struct brcmf_cfg80211_vif *wdev_to_vif(struct wireless_dev *wdev)
312 +{
313 + return container_of(wdev, struct brcmf_cfg80211_vif, wdev);
314 }
315
316 static inline
317 struct net_device *cfg_to_ndev(struct brcmf_cfg80211_info *cfg)
318 {
319 - struct brcmf_cfg80211_vif *vif;
320 - vif = list_first_entry(&cfg->vif_list, struct brcmf_cfg80211_vif, list);
321 - return vif->wdev.netdev;
322 + return brcmf_get_ifp(cfg->pub, 0)->ndev;
323 }
324
325 static inline struct brcmf_cfg80211_info *ndev_to_cfg(struct net_device *ndev)
326 @@ -382,11 +386,12 @@ brcmf_cfg80211_connect_info *cfg_to_conn
327 }
328
329 struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
330 - struct device *busdev,
331 + struct cfg80211_ops *ops,
332 bool p2pdev_forced);
333 void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg);
334 s32 brcmf_cfg80211_up(struct net_device *ndev);
335 s32 brcmf_cfg80211_down(struct net_device *ndev);
336 +struct cfg80211_ops *brcmf_cfg80211_get_ops(void);
337 enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp);
338
339 struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
340 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
341 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
342 @@ -124,6 +124,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_i
343 brcmf_err("Retreiving cur_etheraddr failed, %d\n", err);
344 goto done;
345 }
346 + memcpy(ifp->drvr->wiphy->perm_addr, ifp->drvr->mac, ETH_ALEN);
347 memcpy(ifp->drvr->mac, ifp->mac_addr, sizeof(ifp->drvr->mac));
348
349 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_REVINFO,
350 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
351 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
352 @@ -1036,7 +1036,7 @@ int brcmf_bus_started(struct device *dev
353
354 brcmf_fws_add_interface(ifp);
355
356 - drvr->config = brcmf_cfg80211_attach(drvr, bus_if->dev,
357 + drvr->config = brcmf_cfg80211_attach(drvr, drvr->cfg80211_ops,
358 drvr->settings->p2p_enable);
359 if (drvr->config == NULL) {
360 ret = -ENOMEM;
361 @@ -1095,17 +1095,26 @@ fail:
362
363 int brcmf_attach(struct device *dev, struct brcmf_mp_device *settings)
364 {
365 + struct wiphy *wiphy;
366 + struct cfg80211_ops *ops;
367 struct brcmf_pub *drvr = NULL;
368 int ret = 0;
369 int i;
370
371 brcmf_dbg(TRACE, "Enter\n");
372
373 - /* Allocate primary brcmf_info */
374 - drvr = kzalloc(sizeof(*drvr), GFP_ATOMIC);
375 - if (!drvr)
376 + ops = brcmf_cfg80211_get_ops();
377 + if (!ops)
378 return -ENOMEM;
379
380 + wiphy = wiphy_new(ops, sizeof(*drvr));
381 + if (!wiphy)
382 + return -ENOMEM;
383 +
384 + set_wiphy_dev(wiphy, dev);
385 + drvr = wiphy_priv(wiphy);
386 + drvr->wiphy = wiphy;
387 +
388 for (i = 0; i < ARRAY_SIZE(drvr->if2bss); i++)
389 drvr->if2bss[i] = BRCMF_BSSIDX_INVALID;
390
391 @@ -1134,10 +1143,12 @@ int brcmf_attach(struct device *dev, str
392 /* attach firmware event handler */
393 brcmf_fweh_attach(drvr);
394
395 + drvr->cfg80211_ops = ops;
396 return ret;
397
398 fail:
399 brcmf_detach(dev);
400 + kfree(ops);
401
402 return ret;
403 }
404 @@ -1195,6 +1206,7 @@ void brcmf_detach(struct device *dev)
405 brcmf_remove_interface(drvr->iflist[i], false);
406
407 brcmf_cfg80211_detach(drvr->config);
408 + drvr->config = NULL;
409
410 brcmf_fws_deinit(drvr);
411
412 @@ -1204,7 +1216,7 @@ void brcmf_detach(struct device *dev)
413
414 brcmf_debug_detach(drvr);
415 bus_if->drvr = NULL;
416 - kfree(drvr);
417 + wiphy_free(drvr->wiphy);
418 }
419
420 s32 brcmf_iovar_data_set(struct device *dev, char *name, void *data, u32 len)
421 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
422 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
423 @@ -108,6 +108,7 @@ struct brcmf_pub {
424 /* Linkage ponters */
425 struct brcmf_bus *bus_if;
426 struct brcmf_proto *proto;
427 + struct wiphy *wiphy;
428 struct brcmf_cfg80211_info *config;
429
430 /* Internal brcmf items */
431 @@ -143,6 +144,9 @@ struct brcmf_pub {
432 struct notifier_block inetaddr_notifier;
433 struct notifier_block inet6addr_notifier;
434 struct brcmf_mp_device *settings;
435 +
436 + /* Pointer needed by OpenWrt due to backporting some fixes */
437 + void *cfg80211_ops;
438 };
439
440 /* forward declarations */
441 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
442 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
443 @@ -2236,7 +2236,7 @@ fail:
444 */
445 int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev)
446 {
447 - struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
448 + struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
449 struct brcmf_p2p_info *p2p = &cfg->p2p;
450 struct brcmf_cfg80211_vif *vif;
451 enum nl80211_iftype iftype;