staging: brcm80211: remove brcmf_find_msb() function
[linux-2.6/kvm.git] / drivers / staging / brcm80211 / brcmfmac / wl_cfg80211.c
blob4f7b0816af7b6fed4775dbec0e6a60771adf8d13
1 /*
2 * Copyright (c) 2010 Broadcom Corporation
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 #include <linux/kernel.h>
18 #include <linux/if_arp.h>
19 #include <linux/sched.h>
20 #include <linux/kthread.h>
21 #include <linux/netdevice.h>
22 #include <linux/sched.h>
23 #include <linux/bitops.h>
24 #include <linux/etherdevice.h>
25 #include <linux/ieee80211.h>
26 #include <linux/mmc/sdio_func.h>
27 #include <linux/uaccess.h>
28 #include <net/cfg80211.h>
29 #include <net/rtnetlink.h>
31 #include <brcmu_utils.h>
32 #include <defs.h>
33 #include <brcmu_wifi.h>
34 #include "dhd.h"
35 #include "wl_cfg80211.h"
37 static struct sdio_func *cfg80211_sdio_func;
38 static struct brcmf_cfg80211_dev *cfg80211_dev;
39 static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255};
41 u32 brcmf_dbg_level = WL_DBG_ERR;
44 ** cfg80211_ops api/callback list
46 static s32 brcmf_cfg80211_change_iface(struct wiphy *wiphy,
47 struct net_device *ndev,
48 enum nl80211_iftype type, u32 *flags,
49 struct vif_params *params);
50 static s32 __brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
51 struct cfg80211_scan_request *request,
52 struct cfg80211_ssid *this_ssid);
53 static s32 brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
54 struct cfg80211_scan_request *request);
55 static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed);
56 static s32 brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
57 struct cfg80211_ibss_params *params);
58 static s32 brcmf_cfg80211_leave_ibss(struct wiphy *wiphy,
59 struct net_device *dev);
60 static s32 brcmf_cfg80211_get_station(struct wiphy *wiphy,
61 struct net_device *dev, u8 *mac,
62 struct station_info *sinfo);
63 static s32 brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy,
64 struct net_device *dev, bool enabled,
65 s32 timeout);
66 static s32 brcmf_cfg80211_set_bitrate_mask(struct wiphy *wiphy,
67 struct net_device *dev,
68 const u8 *addr,
69 const struct cfg80211_bitrate_mask
70 *mask);
71 static int brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
72 struct cfg80211_connect_params *sme);
73 static s32 brcmf_cfg80211_disconnect(struct wiphy *wiphy,
74 struct net_device *dev,
75 u16 reason_code);
76 static s32 brcmf_cfg80211_set_tx_power(struct wiphy *wiphy,
77 enum nl80211_tx_power_setting type,
78 s32 dbm);
79 static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm);
80 static s32 brcmf_cfg80211_config_default_key(struct wiphy *wiphy,
81 struct net_device *dev, u8 key_idx,
82 bool unicast, bool multicast);
83 static s32 brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
84 u8 key_idx, bool pairwise, const u8 *mac_addr,
85 struct key_params *params);
86 static s32 brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
87 u8 key_idx, bool pairwise, const u8 *mac_addr);
88 static s32 brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
89 u8 key_idx, bool pairwise, const u8 *mac_addr,
90 void *cookie, void (*callback) (void *cookie,
91 struct
92 key_params *
93 params));
94 static s32 brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
95 struct net_device *dev,
96 u8 key_idx);
97 static s32 brcmf_cfg80211_resume(struct wiphy *wiphy);
98 static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
99 struct cfg80211_wowlan *wow);
100 static s32 brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
101 struct cfg80211_pmksa *pmksa);
102 static s32 brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
103 struct cfg80211_pmksa *pmksa);
104 static s32 brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy,
105 struct net_device *dev);
107 ** event & event Q handlers for cfg80211 interfaces
109 static s32 brcmf_create_event_handler(struct brcmf_cfg80211_priv *cfg_priv);
110 static void brcmf_destroy_event_handler(struct brcmf_cfg80211_priv *cfg_priv);
111 static s32 brcmf_event_handler(void *data);
112 static void brcmf_init_eq(struct brcmf_cfg80211_priv *cfg_priv);
113 static void brcmf_flush_eq(struct brcmf_cfg80211_priv *cfg_priv);
114 static void brcmf_lock_eq(struct brcmf_cfg80211_priv *cfg_priv);
115 static void brcmf_unlock_eq(struct brcmf_cfg80211_priv *cfg_priv);
116 static void brcmf_init_eq_lock(struct brcmf_cfg80211_priv *cfg_priv);
117 static void brcmf_init_eloop_handler(struct brcmf_cfg80211_event_loop *el);
118 static struct brcmf_cfg80211_event_q *
119 brcmf_deq_event(struct brcmf_cfg80211_priv *cfg_priv);
120 static s32 brcmf_enq_event(struct brcmf_cfg80211_priv *cfg_priv, u32 type,
121 const struct brcmf_event_msg *msg);
122 static void brcmf_put_event(struct brcmf_cfg80211_event_q *e);
123 static void brcmf_wakeup_event(struct brcmf_cfg80211_priv *cfg_priv);
124 static s32 brcmf_notify_connect_status(struct brcmf_cfg80211_priv *cfg_priv,
125 struct net_device *ndev,
126 const struct brcmf_event_msg *e,
127 void *data);
128 static s32 brcmf_notify_roaming_status(struct brcmf_cfg80211_priv *cfg_priv,
129 struct net_device *ndev,
130 const struct brcmf_event_msg *e,
131 void *data);
132 static s32 brcmf_notify_scan_status(struct brcmf_cfg80211_priv *cfg_priv,
133 struct net_device *ndev,
134 const struct brcmf_event_msg *e,
135 void *data);
136 static s32 brcmf_bss_connect_done(struct brcmf_cfg80211_priv *cfg_priv,
137 struct net_device *ndev,
138 const struct brcmf_event_msg *e,
139 bool completed);
140 static s32 brcmf_bss_roaming_done(struct brcmf_cfg80211_priv *cfg_priv,
141 struct net_device *ndev,
142 const struct brcmf_event_msg *e);
143 static s32 brcmf_notify_mic_status(struct brcmf_cfg80211_priv *cfg_priv,
144 struct net_device *ndev,
145 const struct brcmf_event_msg *e, void *data);
148 ** register/deregister sdio function
150 static void brcmf_clear_sdio_func(void);
153 ** ioctl utilites
155 static s32 brcmf_dev_bufvar_get(struct net_device *dev, s8 *name, s8 *buf,
156 s32 buf_len);
157 static __used s32 brcmf_dev_bufvar_set(struct net_device *dev, s8 *name,
158 s8 *buf, s32 len);
159 static s32 brcmf_dev_intvar_set(struct net_device *dev, s8 *name, s32 val);
160 static s32 brcmf_dev_intvar_get(struct net_device *dev, s8 *name,
161 s32 *retval);
162 static s32 brcmf_dev_ioctl(struct net_device *dev, u32 cmd, void *arg,
163 u32 len);
166 ** cfg80211 set_wiphy_params utilities
168 static s32 brcmf_set_frag(struct net_device *dev, u32 frag_threshold);
169 static s32 brcmf_set_rts(struct net_device *dev, u32 frag_threshold);
170 static s32 brcmf_set_retry(struct net_device *dev, u32 retry, bool l);
173 ** wl profile utilities
175 static s32 brcmf_update_prof(struct brcmf_cfg80211_priv *cfg_priv,
176 const struct brcmf_event_msg *e,
177 void *data, s32 item);
178 static void *brcmf_read_prof(struct brcmf_cfg80211_priv *cfg_priv, s32 item);
179 static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof);
182 ** cfg80211 connect utilites
184 static s32 brcmf_set_wpa_version(struct net_device *dev,
185 struct cfg80211_connect_params *sme);
186 static s32 brcmf_set_auth_type(struct net_device *dev,
187 struct cfg80211_connect_params *sme);
188 static s32 brcmf_set_set_cipher(struct net_device *dev,
189 struct cfg80211_connect_params *sme);
190 static s32 brcmf_set_key_mgmt(struct net_device *dev,
191 struct cfg80211_connect_params *sme);
192 static s32 brcmf_set_set_sharedkey(struct net_device *dev,
193 struct cfg80211_connect_params *sme);
194 static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv);
195 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv);
196 static void brcmf_ch_to_chanspec(int ch,
197 struct brcmf_join_params *join_params, size_t *join_params_size);
200 ** information element utilities
202 static __used s32 brcmf_add_ie(struct brcmf_cfg80211_priv *cfg_priv,
203 u8 t, u8 l, u8 *v);
204 static s32 brcmf_mode_to_nl80211_iftype(s32 mode);
205 static struct wireless_dev *brcmf_alloc_wdev(s32 sizeof_iface,
206 struct device *dev);
207 static void brcmf_free_wdev(struct brcmf_cfg80211_priv *cfg_priv);
208 static s32 brcmf_inform_bss(struct brcmf_cfg80211_priv *cfg_priv);
209 static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv,
210 struct brcmf_bss_info *bi);
211 static s32 brcmf_update_bss_info(struct brcmf_cfg80211_priv *cfg_priv);
212 static s32 brcmf_add_keyext(struct wiphy *wiphy, struct net_device *dev,
213 u8 key_idx, const u8 *mac_addr,
214 struct key_params *params);
217 ** key indianess swap utilities
219 static void convert_key_from_CPU(struct brcmf_wsec_key *key);
220 static void convert_key_to_CPU(struct brcmf_wsec_key *key);
223 ** brcmf_cfg80211_priv memory init/deinit utilities
225 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_priv *cfg_priv);
226 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_priv *cfg_priv);
228 static void brcmf_delay(u32 ms);
231 ** store/restore cfg80211 instance data
233 static void brcmf_set_drvdata(struct brcmf_cfg80211_dev *dev, void *data);
234 static void *brcmf_get_drvdata(struct brcmf_cfg80211_dev *dev);
237 ** ibss mode utilities
239 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_priv *cfg_priv);
242 ** dongle up/down , default configuration utilities
244 static bool brcmf_is_linkdown(struct brcmf_cfg80211_priv *cfg_priv,
245 const struct brcmf_event_msg *e);
246 static bool brcmf_is_linkup(struct brcmf_cfg80211_priv *cfg_priv,
247 const struct brcmf_event_msg *e);
248 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_priv *cfg_priv,
249 const struct brcmf_event_msg *e);
250 static void brcmf_link_down(struct brcmf_cfg80211_priv *cfg_priv);
251 static s32 brcmf_dongle_mode(struct net_device *ndev, s32 iftype);
252 static s32 __brcmf_cfg80211_up(struct brcmf_cfg80211_priv *cfg_priv);
253 static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_priv *cfg_priv);
254 static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_priv *cfg_priv);
255 static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf);
258 ** dongle configuration utilities
260 static s32 brcmf_dongle_eventmsg(struct net_device *ndev);
261 static s32 brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
262 s32 scan_unassoc_time, s32 scan_passive_time);
263 static s32 brcmf_config_dongle(struct brcmf_cfg80211_priv *cfg_priv,
264 bool need_lock);
265 static s32 brcmf_dongle_roam(struct net_device *ndev, u32 roamvar,
266 u32 bcn_timeout);
269 ** iscan handler
271 static void brcmf_iscan_timer(unsigned long data);
272 static void brcmf_term_iscan(struct brcmf_cfg80211_priv *cfg_priv);
273 static s32 brcmf_init_iscan(struct brcmf_cfg80211_priv *cfg_priv);
274 static s32 brcmf_iscan_thread(void *data);
275 static s32 brcmf_dev_iovar_setbuf(struct net_device *dev, s8 *iovar,
276 void *param, s32 paramlen, void *bufptr,
277 s32 buflen);
278 static s32 brcmf_dev_iovar_getbuf(struct net_device *dev, s8 *iovar,
279 void *param, s32 paramlen, void *bufptr,
280 s32 buflen);
281 static s32 brcmf_run_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan,
282 struct brcmf_ssid *ssid, u16 action);
283 static s32 brcmf_do_iscan(struct brcmf_cfg80211_priv *cfg_priv);
284 static s32 brcmf_wakeup_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan);
285 static s32 brcmf_invoke_iscan(struct brcmf_cfg80211_priv *cfg_priv);
286 static s32 brcmf_get_iscan_results(struct brcmf_cfg80211_iscan_ctrl *iscan,
287 u32 *status,
288 struct brcmf_scan_results **bss_list);
289 static void brcmf_notify_iscan_complete(struct brcmf_cfg80211_iscan_ctrl *iscan,
290 bool aborted);
291 static void brcmf_init_iscan_eloop(struct brcmf_cfg80211_iscan_eloop *el);
292 static s32 brcmf_iscan_done(struct brcmf_cfg80211_priv *cfg_priv);
293 static s32 brcmf_iscan_pending(struct brcmf_cfg80211_priv *cfg_priv);
294 static s32 brcmf_iscan_inprogress(struct brcmf_cfg80211_priv *cfg_priv);
295 static s32 brcmf_iscan_aborted(struct brcmf_cfg80211_priv *cfg_priv);
298 * update pmklist to dongle
300 static __used s32 brcmf_update_pmklist(struct net_device *dev,
301 struct brcmf_cfg80211_pmk_list *pmk_list,
302 s32 err);
304 static void brcmf_set_mpc(struct net_device *ndev, int mpc);
307 * debufs support
309 static int
310 brcmf_debugfs_add_netdev_params(struct brcmf_cfg80211_priv *cfg_priv);
311 static void brcmf_debugfs_remove_netdev(struct brcmf_cfg80211_priv *cfg_priv);
313 #define WL_PRIV_GET() \
314 ({ \
315 struct brcmf_cfg80211_iface *ci = brcmf_get_drvdata(cfg80211_dev); \
316 if (unlikely(!ci)) { \
317 WL_ERR("wl_cfg80211_dev is unavailable\n"); \
318 BUG(); \
320 ci->cfg_priv; \
323 #define CHECK_SYS_UP() \
324 do { \
325 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); \
326 if (unlikely(!test_bit(WL_STATUS_READY, &cfg_priv->status))) { \
327 WL_INFO("device is not ready : status (%d)\n", \
328 (int)cfg_priv->status); \
329 return -EIO; \
331 } while (0)
333 #define CHAN2G(_channel, _freq, _flags) { \
334 .band = IEEE80211_BAND_2GHZ, \
335 .center_freq = (_freq), \
336 .hw_value = (_channel), \
337 .flags = (_flags), \
338 .max_antenna_gain = 0, \
339 .max_power = 30, \
342 #define CHAN5G(_channel, _flags) { \
343 .band = IEEE80211_BAND_5GHZ, \
344 .center_freq = 5000 + (5 * (_channel)), \
345 .hw_value = (_channel), \
346 .flags = (_flags), \
347 .max_antenna_gain = 0, \
348 .max_power = 30, \
351 #define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
352 #define RATETAB_ENT(_rateid, _flags) \
354 .bitrate = RATE_TO_BASE100KBPS(_rateid), \
355 .hw_value = (_rateid), \
356 .flags = (_flags), \
359 static struct ieee80211_rate __wl_rates[] = {
360 RATETAB_ENT(BRCM_RATE_1M, 0),
361 RATETAB_ENT(BRCM_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
362 RATETAB_ENT(BRCM_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
363 RATETAB_ENT(BRCM_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
364 RATETAB_ENT(BRCM_RATE_6M, 0),
365 RATETAB_ENT(BRCM_RATE_9M, 0),
366 RATETAB_ENT(BRCM_RATE_12M, 0),
367 RATETAB_ENT(BRCM_RATE_18M, 0),
368 RATETAB_ENT(BRCM_RATE_24M, 0),
369 RATETAB_ENT(BRCM_RATE_36M, 0),
370 RATETAB_ENT(BRCM_RATE_48M, 0),
371 RATETAB_ENT(BRCM_RATE_54M, 0),
374 #define wl_a_rates (__wl_rates + 4)
375 #define wl_a_rates_size 8
376 #define wl_g_rates (__wl_rates + 0)
377 #define wl_g_rates_size 12
379 static struct ieee80211_channel __wl_2ghz_channels[] = {
380 CHAN2G(1, 2412, 0),
381 CHAN2G(2, 2417, 0),
382 CHAN2G(3, 2422, 0),
383 CHAN2G(4, 2427, 0),
384 CHAN2G(5, 2432, 0),
385 CHAN2G(6, 2437, 0),
386 CHAN2G(7, 2442, 0),
387 CHAN2G(8, 2447, 0),
388 CHAN2G(9, 2452, 0),
389 CHAN2G(10, 2457, 0),
390 CHAN2G(11, 2462, 0),
391 CHAN2G(12, 2467, 0),
392 CHAN2G(13, 2472, 0),
393 CHAN2G(14, 2484, 0),
396 static struct ieee80211_channel __wl_5ghz_a_channels[] = {
397 CHAN5G(34, 0), CHAN5G(36, 0),
398 CHAN5G(38, 0), CHAN5G(40, 0),
399 CHAN5G(42, 0), CHAN5G(44, 0),
400 CHAN5G(46, 0), CHAN5G(48, 0),
401 CHAN5G(52, 0), CHAN5G(56, 0),
402 CHAN5G(60, 0), CHAN5G(64, 0),
403 CHAN5G(100, 0), CHAN5G(104, 0),
404 CHAN5G(108, 0), CHAN5G(112, 0),
405 CHAN5G(116, 0), CHAN5G(120, 0),
406 CHAN5G(124, 0), CHAN5G(128, 0),
407 CHAN5G(132, 0), CHAN5G(136, 0),
408 CHAN5G(140, 0), CHAN5G(149, 0),
409 CHAN5G(153, 0), CHAN5G(157, 0),
410 CHAN5G(161, 0), CHAN5G(165, 0),
411 CHAN5G(184, 0), CHAN5G(188, 0),
412 CHAN5G(192, 0), CHAN5G(196, 0),
413 CHAN5G(200, 0), CHAN5G(204, 0),
414 CHAN5G(208, 0), CHAN5G(212, 0),
415 CHAN5G(216, 0),
418 static struct ieee80211_channel __wl_5ghz_n_channels[] = {
419 CHAN5G(32, 0), CHAN5G(34, 0),
420 CHAN5G(36, 0), CHAN5G(38, 0),
421 CHAN5G(40, 0), CHAN5G(42, 0),
422 CHAN5G(44, 0), CHAN5G(46, 0),
423 CHAN5G(48, 0), CHAN5G(50, 0),
424 CHAN5G(52, 0), CHAN5G(54, 0),
425 CHAN5G(56, 0), CHAN5G(58, 0),
426 CHAN5G(60, 0), CHAN5G(62, 0),
427 CHAN5G(64, 0), CHAN5G(66, 0),
428 CHAN5G(68, 0), CHAN5G(70, 0),
429 CHAN5G(72, 0), CHAN5G(74, 0),
430 CHAN5G(76, 0), CHAN5G(78, 0),
431 CHAN5G(80, 0), CHAN5G(82, 0),
432 CHAN5G(84, 0), CHAN5G(86, 0),
433 CHAN5G(88, 0), CHAN5G(90, 0),
434 CHAN5G(92, 0), CHAN5G(94, 0),
435 CHAN5G(96, 0), CHAN5G(98, 0),
436 CHAN5G(100, 0), CHAN5G(102, 0),
437 CHAN5G(104, 0), CHAN5G(106, 0),
438 CHAN5G(108, 0), CHAN5G(110, 0),
439 CHAN5G(112, 0), CHAN5G(114, 0),
440 CHAN5G(116, 0), CHAN5G(118, 0),
441 CHAN5G(120, 0), CHAN5G(122, 0),
442 CHAN5G(124, 0), CHAN5G(126, 0),
443 CHAN5G(128, 0), CHAN5G(130, 0),
444 CHAN5G(132, 0), CHAN5G(134, 0),
445 CHAN5G(136, 0), CHAN5G(138, 0),
446 CHAN5G(140, 0), CHAN5G(142, 0),
447 CHAN5G(144, 0), CHAN5G(145, 0),
448 CHAN5G(146, 0), CHAN5G(147, 0),
449 CHAN5G(148, 0), CHAN5G(149, 0),
450 CHAN5G(150, 0), CHAN5G(151, 0),
451 CHAN5G(152, 0), CHAN5G(153, 0),
452 CHAN5G(154, 0), CHAN5G(155, 0),
453 CHAN5G(156, 0), CHAN5G(157, 0),
454 CHAN5G(158, 0), CHAN5G(159, 0),
455 CHAN5G(160, 0), CHAN5G(161, 0),
456 CHAN5G(162, 0), CHAN5G(163, 0),
457 CHAN5G(164, 0), CHAN5G(165, 0),
458 CHAN5G(166, 0), CHAN5G(168, 0),
459 CHAN5G(170, 0), CHAN5G(172, 0),
460 CHAN5G(174, 0), CHAN5G(176, 0),
461 CHAN5G(178, 0), CHAN5G(180, 0),
462 CHAN5G(182, 0), CHAN5G(184, 0),
463 CHAN5G(186, 0), CHAN5G(188, 0),
464 CHAN5G(190, 0), CHAN5G(192, 0),
465 CHAN5G(194, 0), CHAN5G(196, 0),
466 CHAN5G(198, 0), CHAN5G(200, 0),
467 CHAN5G(202, 0), CHAN5G(204, 0),
468 CHAN5G(206, 0), CHAN5G(208, 0),
469 CHAN5G(210, 0), CHAN5G(212, 0),
470 CHAN5G(214, 0), CHAN5G(216, 0),
471 CHAN5G(218, 0), CHAN5G(220, 0),
472 CHAN5G(222, 0), CHAN5G(224, 0),
473 CHAN5G(226, 0), CHAN5G(228, 0),
476 static struct ieee80211_supported_band __wl_band_2ghz = {
477 .band = IEEE80211_BAND_2GHZ,
478 .channels = __wl_2ghz_channels,
479 .n_channels = ARRAY_SIZE(__wl_2ghz_channels),
480 .bitrates = wl_g_rates,
481 .n_bitrates = wl_g_rates_size,
484 static struct ieee80211_supported_band __wl_band_5ghz_a = {
485 .band = IEEE80211_BAND_5GHZ,
486 .channels = __wl_5ghz_a_channels,
487 .n_channels = ARRAY_SIZE(__wl_5ghz_a_channels),
488 .bitrates = wl_a_rates,
489 .n_bitrates = wl_a_rates_size,
492 static struct ieee80211_supported_band __wl_band_5ghz_n = {
493 .band = IEEE80211_BAND_5GHZ,
494 .channels = __wl_5ghz_n_channels,
495 .n_channels = ARRAY_SIZE(__wl_5ghz_n_channels),
496 .bitrates = wl_a_rates,
497 .n_bitrates = wl_a_rates_size,
500 static const u32 __wl_cipher_suites[] = {
501 WLAN_CIPHER_SUITE_WEP40,
502 WLAN_CIPHER_SUITE_WEP104,
503 WLAN_CIPHER_SUITE_TKIP,
504 WLAN_CIPHER_SUITE_CCMP,
505 WLAN_CIPHER_SUITE_AES_CMAC,
508 static void convert_key_from_CPU(struct brcmf_wsec_key *key)
510 key->index = cpu_to_le32(key->index);
511 key->len = cpu_to_le32(key->len);
512 key->algo = cpu_to_le32(key->algo);
513 key->flags = cpu_to_le32(key->flags);
514 key->rxiv.hi = cpu_to_le32(key->rxiv.hi);
515 key->rxiv.lo = cpu_to_le16(key->rxiv.lo);
516 key->iv_initialized = cpu_to_le32(key->iv_initialized);
519 static void convert_key_to_CPU(struct brcmf_wsec_key *key)
521 key->index = le32_to_cpu(key->index);
522 key->len = le32_to_cpu(key->len);
523 key->algo = le32_to_cpu(key->algo);
524 key->flags = le32_to_cpu(key->flags);
525 key->rxiv.hi = le32_to_cpu(key->rxiv.hi);
526 key->rxiv.lo = le16_to_cpu(key->rxiv.lo);
527 key->iv_initialized = le32_to_cpu(key->iv_initialized);
530 static s32
531 brcmf_dev_ioctl(struct net_device *dev, u32 cmd, void *arg, u32 len)
533 struct ifreq ifr;
534 struct brcmf_ioctl ioc;
535 mm_segment_t fs;
536 s32 err = 0;
538 memset(&ioc, 0, sizeof(ioc));
539 ioc.cmd = cmd;
540 ioc.buf = arg;
541 ioc.len = len;
542 strcpy(ifr.ifr_name, dev->name);
543 ifr.ifr_data = (caddr_t)&ioc;
545 fs = get_fs();
546 set_fs(get_ds());
547 err = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, SIOCDEVPRIVATE);
548 set_fs(fs);
550 return err;
553 static s32
554 brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
555 enum nl80211_iftype type, u32 *flags,
556 struct vif_params *params)
558 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
559 struct wireless_dev *wdev;
560 s32 infra = 0;
561 s32 err = 0;
563 WL_TRACE("Enter\n");
564 CHECK_SYS_UP();
566 switch (type) {
567 case NL80211_IFTYPE_MONITOR:
568 case NL80211_IFTYPE_WDS:
569 WL_ERR("type (%d) : currently we do not support this type\n",
570 type);
571 return -EOPNOTSUPP;
572 case NL80211_IFTYPE_ADHOC:
573 cfg_priv->conf->mode = WL_MODE_IBSS;
574 infra = 0;
575 break;
576 case NL80211_IFTYPE_STATION:
577 cfg_priv->conf->mode = WL_MODE_BSS;
578 infra = 1;
579 break;
580 default:
581 err = -EINVAL;
582 goto done;
585 infra = cpu_to_le32(infra);
586 err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_INFRA, &infra, sizeof(infra));
587 if (unlikely(err)) {
588 WL_ERR("WLC_SET_INFRA error (%d)\n", err);
589 err = -EAGAIN;
590 } else {
591 wdev = ndev->ieee80211_ptr;
592 wdev->iftype = type;
595 WL_INFO("IF Type = %s\n",
596 (cfg_priv->conf->mode == WL_MODE_IBSS) ? "Adhoc" : "Infra");
598 done:
599 WL_TRACE("Exit\n");
601 return err;
604 static void wl_iscan_prep(struct brcmf_scan_params *params,
605 struct brcmf_ssid *ssid)
607 memcpy(params->bssid, ether_bcast, ETH_ALEN);
608 params->bss_type = DOT11_BSSTYPE_ANY;
609 params->scan_type = 0;
610 params->nprobes = -1;
611 params->active_time = -1;
612 params->passive_time = -1;
613 params->home_time = -1;
614 params->channel_num = 0;
616 params->nprobes = cpu_to_le32(params->nprobes);
617 params->active_time = cpu_to_le32(params->active_time);
618 params->passive_time = cpu_to_le32(params->passive_time);
619 params->home_time = cpu_to_le32(params->home_time);
620 if (ssid && ssid->SSID_len)
621 memcpy(&params->ssid, ssid, sizeof(struct brcmf_ssid));
625 static s32
626 brcmf_dev_iovar_setbuf(struct net_device *dev, s8 * iovar, void *param,
627 s32 paramlen, void *bufptr, s32 buflen)
629 s32 iolen;
631 iolen = brcmu_mkiovar(iovar, param, paramlen, bufptr, buflen);
632 BUG_ON(!iolen);
634 return brcmf_dev_ioctl(dev, BRCMF_C_SET_VAR, bufptr, iolen);
637 static s32
638 brcmf_dev_iovar_getbuf(struct net_device *dev, s8 * iovar, void *param,
639 s32 paramlen, void *bufptr, s32 buflen)
641 s32 iolen;
643 iolen = brcmu_mkiovar(iovar, param, paramlen, bufptr, buflen);
644 BUG_ON(!iolen);
646 return brcmf_dev_ioctl(dev, BRCMF_C_GET_VAR, bufptr, buflen);
649 static s32
650 brcmf_run_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan,
651 struct brcmf_ssid *ssid, u16 action)
653 s32 params_size = (BRCMF_SCAN_PARAMS_FIXED_SIZE +
654 offsetof(struct brcmf_iscan_params, params));
655 struct brcmf_iscan_params *params;
656 s32 err = 0;
658 if (ssid && ssid->SSID_len)
659 params_size += sizeof(struct brcmf_ssid);
660 params = kzalloc(params_size, GFP_KERNEL);
661 if (unlikely(!params))
662 return -ENOMEM;
663 BUG_ON(params_size >= BRCMF_C_IOCTL_SMLEN);
665 wl_iscan_prep(&params->params, ssid);
667 params->version = cpu_to_le32(BRCMF_ISCAN_REQ_VERSION);
668 params->action = cpu_to_le16(action);
669 params->scan_duration = cpu_to_le16(0);
671 /* params_size += offsetof(struct brcmf_iscan_params, params); */
672 err = brcmf_dev_iovar_setbuf(iscan->dev, "iscan", params, params_size,
673 iscan->ioctl_buf, BRCMF_C_IOCTL_SMLEN);
674 if (unlikely(err)) {
675 if (err == -EBUSY)
676 WL_INFO("system busy : iscan canceled\n");
677 else
678 WL_ERR("error (%d)\n", err);
681 kfree(params);
682 return err;
685 static s32 brcmf_do_iscan(struct brcmf_cfg80211_priv *cfg_priv)
687 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
688 struct net_device *ndev = cfg_to_ndev(cfg_priv);
689 struct brcmf_ssid ssid;
690 s32 passive_scan;
691 s32 err = 0;
693 /* Broadcast scan by default */
694 memset(&ssid, 0, sizeof(ssid));
696 iscan->state = WL_ISCAN_STATE_SCANING;
698 passive_scan = cfg_priv->active_scan ? 0 : 1;
699 err = brcmf_dev_ioctl(cfg_to_ndev(cfg_priv), BRCMF_C_SET_PASSIVE_SCAN,
700 &passive_scan, sizeof(passive_scan));
701 if (unlikely(err)) {
702 WL_ERR("error (%d)\n", err);
703 return err;
705 brcmf_set_mpc(ndev, 0);
706 cfg_priv->iscan_kickstart = true;
707 err = brcmf_run_iscan(iscan, &ssid, BRCMF_SCAN_ACTION_START);
708 if (err) {
709 brcmf_set_mpc(ndev, 1);
710 cfg_priv->iscan_kickstart = false;
711 return err;
713 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
714 iscan->timer_on = 1;
715 return err;
718 static s32
719 __brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
720 struct cfg80211_scan_request *request,
721 struct cfg80211_ssid *this_ssid)
723 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
724 struct cfg80211_ssid *ssids;
725 struct brcmf_cfg80211_scan_req *sr = cfg_priv->scan_req_int;
726 s32 passive_scan;
727 bool iscan_req;
728 bool spec_scan;
729 s32 err = 0;
731 if (unlikely(test_bit(WL_STATUS_SCANNING, &cfg_priv->status))) {
732 WL_ERR("Scanning already : status (%lu)\n", cfg_priv->status);
733 return -EAGAIN;
735 if (unlikely(test_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status))) {
736 WL_ERR("Scanning being aborted : status (%lu)\n",
737 cfg_priv->status);
738 return -EAGAIN;
740 if (test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) {
741 WL_ERR("Connecting : status (%lu)\n",
742 cfg_priv->status);
743 return -EAGAIN;
746 iscan_req = false;
747 spec_scan = false;
748 if (request) {
749 /* scan bss */
750 ssids = request->ssids;
751 if (cfg_priv->iscan_on && (!ssids || !ssids->ssid_len))
752 iscan_req = true;
753 } else {
754 /* scan in ibss */
755 /* we don't do iscan in ibss */
756 ssids = this_ssid;
759 cfg_priv->scan_request = request;
760 set_bit(WL_STATUS_SCANNING, &cfg_priv->status);
761 if (iscan_req) {
762 err = brcmf_do_iscan(cfg_priv);
763 if (likely(!err))
764 return err;
765 else
766 goto scan_out;
767 } else {
768 WL_SCAN("ssid \"%s\", ssid_len (%d)\n",
769 ssids->ssid, ssids->ssid_len);
770 memset(&sr->ssid, 0, sizeof(sr->ssid));
771 sr->ssid.SSID_len =
772 min_t(u8, sizeof(sr->ssid.SSID), ssids->ssid_len);
773 if (sr->ssid.SSID_len) {
774 memcpy(sr->ssid.SSID, ssids->ssid, sr->ssid.SSID_len);
775 sr->ssid.SSID_len = cpu_to_le32(sr->ssid.SSID_len);
776 spec_scan = true;
777 } else {
778 WL_SCAN("Broadcast scan\n");
781 passive_scan = cfg_priv->active_scan ? 0 : 1;
782 err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_PASSIVE_SCAN,
783 &passive_scan, sizeof(passive_scan));
784 if (unlikely(err)) {
785 WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
786 goto scan_out;
788 brcmf_set_mpc(ndev, 0);
789 err = brcmf_dev_ioctl(ndev, BRCMF_C_SCAN, &sr->ssid,
790 sizeof(sr->ssid));
791 if (err) {
792 if (err == -EBUSY)
793 WL_INFO("system busy : scan for \"%s\" "
794 "canceled\n", sr->ssid.SSID);
795 else
796 WL_ERR("WLC_SCAN error (%d)\n", err);
798 brcmf_set_mpc(ndev, 1);
799 goto scan_out;
803 return 0;
805 scan_out:
806 clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
807 cfg_priv->scan_request = NULL;
808 return err;
811 static s32
812 brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
813 struct cfg80211_scan_request *request)
815 s32 err = 0;
817 WL_TRACE("Enter\n");
819 CHECK_SYS_UP();
821 err = __brcmf_cfg80211_scan(wiphy, ndev, request, NULL);
822 if (unlikely(err))
823 WL_ERR("scan error (%d)\n", err);
825 WL_TRACE("Exit\n");
826 return err;
829 static s32 brcmf_dev_intvar_set(struct net_device *dev, s8 *name, s32 val)
831 s8 buf[BRCMF_C_IOCTL_SMLEN];
832 u32 len;
833 s32 err = 0;
835 val = cpu_to_le32(val);
836 len = brcmu_mkiovar(name, (char *)(&val), sizeof(val), buf,
837 sizeof(buf));
838 BUG_ON(!len);
840 err = brcmf_dev_ioctl(dev, BRCMF_C_SET_VAR, buf, len);
841 if (unlikely(err))
842 WL_ERR("error (%d)\n", err);
844 return err;
847 static s32
848 brcmf_dev_intvar_get(struct net_device *dev, s8 *name, s32 *retval)
850 union {
851 s8 buf[BRCMF_C_IOCTL_SMLEN];
852 s32 val;
853 } var;
854 u32 len;
855 u32 data_null;
856 s32 err = 0;
858 len =
859 brcmu_mkiovar(name, (char *)(&data_null), 0, (char *)(&var),
860 sizeof(var.buf));
861 BUG_ON(!len);
862 err = brcmf_dev_ioctl(dev, BRCMF_C_GET_VAR, &var, len);
863 if (unlikely(err))
864 WL_ERR("error (%d)\n", err);
866 *retval = le32_to_cpu(var.val);
868 return err;
871 static s32 brcmf_set_rts(struct net_device *dev, u32 rts_threshold)
873 s32 err = 0;
875 err = brcmf_dev_intvar_set(dev, "rtsthresh", rts_threshold);
876 if (unlikely(err))
877 WL_ERR("Error (%d)\n", err);
879 return err;
882 static s32 brcmf_set_frag(struct net_device *dev, u32 frag_threshold)
884 s32 err = 0;
886 err = brcmf_dev_intvar_set(dev, "fragthresh", frag_threshold);
887 if (unlikely(err))
888 WL_ERR("Error (%d)\n", err);
890 return err;
893 static s32 brcmf_set_retry(struct net_device *dev, u32 retry, bool l)
895 s32 err = 0;
896 u32 cmd = (l ? BRCM_SET_LRL : BRCM_SET_SRL);
898 retry = cpu_to_le32(retry);
899 err = brcmf_dev_ioctl(dev, cmd, &retry, sizeof(retry));
900 if (unlikely(err)) {
901 WL_ERR("cmd (%d) , error (%d)\n", cmd, err);
902 return err;
904 return err;
907 static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
909 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
910 struct net_device *ndev = cfg_to_ndev(cfg_priv);
911 s32 err = 0;
913 WL_TRACE("Enter\n");
914 CHECK_SYS_UP();
916 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
917 (cfg_priv->conf->rts_threshold != wiphy->rts_threshold)) {
918 cfg_priv->conf->rts_threshold = wiphy->rts_threshold;
919 err = brcmf_set_rts(ndev, cfg_priv->conf->rts_threshold);
920 if (!err)
921 goto done;
923 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
924 (cfg_priv->conf->frag_threshold != wiphy->frag_threshold)) {
925 cfg_priv->conf->frag_threshold = wiphy->frag_threshold;
926 err = brcmf_set_frag(ndev, cfg_priv->conf->frag_threshold);
927 if (!err)
928 goto done;
930 if (changed & WIPHY_PARAM_RETRY_LONG
931 && (cfg_priv->conf->retry_long != wiphy->retry_long)) {
932 cfg_priv->conf->retry_long = wiphy->retry_long;
933 err = brcmf_set_retry(ndev, cfg_priv->conf->retry_long, true);
934 if (!err)
935 goto done;
937 if (changed & WIPHY_PARAM_RETRY_SHORT
938 && (cfg_priv->conf->retry_short != wiphy->retry_short)) {
939 cfg_priv->conf->retry_short = wiphy->retry_short;
940 err = brcmf_set_retry(ndev, cfg_priv->conf->retry_short, false);
941 if (!err)
942 goto done;
945 done:
946 WL_TRACE("Exit\n");
947 return err;
950 static s32
951 brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
952 struct cfg80211_ibss_params *params)
954 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
955 struct brcmf_join_params join_params;
956 size_t join_params_size = 0;
957 s32 err = 0;
958 s32 wsec = 0;
959 s32 bcnprd;
961 WL_TRACE("Enter\n");
962 CHECK_SYS_UP();
964 if (params->ssid)
965 WL_CONN("SSID: %s\n", params->ssid);
966 else {
967 WL_CONN("SSID: NULL, Not supported\n");
968 return -EOPNOTSUPP;
971 set_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
973 if (params->bssid)
974 WL_CONN("BSSID: %02X %02X %02X %02X %02X %02X\n",
975 params->bssid[0], params->bssid[1], params->bssid[2],
976 params->bssid[3], params->bssid[4], params->bssid[5]);
977 else
978 WL_CONN("No BSSID specified\n");
980 if (params->channel)
981 WL_CONN("channel: %d\n", params->channel->center_freq);
982 else
983 WL_CONN("no channel specified\n");
985 if (params->channel_fixed)
986 WL_CONN("fixed channel required\n");
987 else
988 WL_CONN("no fixed channel required\n");
990 if (params->ie && params->ie_len)
991 WL_CONN("ie len: %d\n", params->ie_len);
992 else
993 WL_CONN("no ie specified\n");
995 if (params->beacon_interval)
996 WL_CONN("beacon interval: %d\n", params->beacon_interval);
997 else
998 WL_CONN("no beacon interval specified\n");
1000 if (params->basic_rates)
1001 WL_CONN("basic rates: %08X\n", params->basic_rates);
1002 else
1003 WL_CONN("no basic rates specified\n");
1005 if (params->privacy)
1006 WL_CONN("privacy required\n");
1007 else
1008 WL_CONN("no privacy required\n");
1010 /* Configure Privacy for starter */
1011 if (params->privacy)
1012 wsec |= WEP_ENABLED;
1014 err = brcmf_dev_intvar_set(dev, "wsec", wsec);
1015 if (unlikely(err)) {
1016 WL_ERR("wsec failed (%d)\n", err);
1017 goto done;
1020 /* Configure Beacon Interval for starter */
1021 if (params->beacon_interval)
1022 bcnprd = cpu_to_le32(params->beacon_interval);
1023 else
1024 bcnprd = cpu_to_le32(100);
1026 err = brcmf_dev_ioctl(dev, BRCM_SET_BCNPRD, &bcnprd, sizeof(bcnprd));
1027 if (unlikely(err)) {
1028 WL_ERR("WLC_SET_BCNPRD failed (%d)\n", err);
1029 goto done;
1032 /* Configure required join parameter */
1033 memset(&join_params, 0, sizeof(struct brcmf_join_params));
1035 /* SSID */
1036 join_params.ssid.SSID_len =
1037 (params->ssid_len > 32) ? 32 : params->ssid_len;
1038 memcpy(join_params.ssid.SSID, params->ssid, join_params.ssid.SSID_len);
1039 join_params.ssid.SSID_len = cpu_to_le32(join_params.ssid.SSID_len);
1040 join_params_size = sizeof(join_params.ssid);
1041 brcmf_update_prof(cfg_priv, NULL, &join_params.ssid, WL_PROF_SSID);
1043 /* BSSID */
1044 if (params->bssid) {
1045 memcpy(join_params.params.bssid, params->bssid, ETH_ALEN);
1046 join_params_size = sizeof(join_params.ssid) +
1047 BRCMF_ASSOC_PARAMS_FIXED_SIZE;
1048 } else {
1049 memcpy(join_params.params.bssid, ether_bcast, ETH_ALEN);
1052 brcmf_update_prof(cfg_priv, NULL,
1053 &join_params.params.bssid, WL_PROF_BSSID);
1055 /* Channel */
1056 if (params->channel) {
1057 u32 target_channel;
1059 cfg_priv->channel =
1060 ieee80211_frequency_to_channel(
1061 params->channel->center_freq);
1062 if (params->channel_fixed) {
1063 /* adding chanspec */
1064 brcmf_ch_to_chanspec(cfg_priv->channel,
1065 &join_params, &join_params_size);
1068 /* set channel for starter */
1069 target_channel = cpu_to_le32(cfg_priv->channel);
1070 err = brcmf_dev_ioctl(dev, BRCM_SET_CHANNEL,
1071 &target_channel, sizeof(target_channel));
1072 if (unlikely(err)) {
1073 WL_ERR("WLC_SET_CHANNEL failed (%d)\n", err);
1074 goto done;
1076 } else
1077 cfg_priv->channel = 0;
1079 cfg_priv->ibss_starter = false;
1082 err = brcmf_dev_ioctl(dev, BRCMF_C_SET_SSID,
1083 &join_params, join_params_size);
1084 if (unlikely(err)) {
1085 WL_ERR("WLC_SET_SSID failed (%d)\n", err);
1086 goto done;
1089 done:
1090 if (err)
1091 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
1092 WL_TRACE("Exit\n");
1093 return err;
1096 static s32
1097 brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
1099 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1100 s32 err = 0;
1102 WL_TRACE("Enter\n");
1103 CHECK_SYS_UP();
1105 brcmf_link_down(cfg_priv);
1107 WL_TRACE("Exit\n");
1109 return err;
1112 static s32 brcmf_set_wpa_version(struct net_device *dev,
1113 struct cfg80211_connect_params *sme)
1115 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(dev);
1116 struct brcmf_cfg80211_security *sec;
1117 s32 val = 0;
1118 s32 err = 0;
1120 if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1121 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
1122 else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1123 val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
1124 else
1125 val = WPA_AUTH_DISABLED;
1126 WL_CONN("setting wpa_auth to 0x%0x\n", val);
1127 err = brcmf_dev_intvar_set(dev, "wpa_auth", val);
1128 if (unlikely(err)) {
1129 WL_ERR("set wpa_auth failed (%d)\n", err);
1130 return err;
1132 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1133 sec->wpa_versions = sme->crypto.wpa_versions;
1134 return err;
1137 static s32
1138 brcmf_set_auth_type(struct net_device *dev, struct cfg80211_connect_params *sme)
1140 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(dev);
1141 struct brcmf_cfg80211_security *sec;
1142 s32 val = 0;
1143 s32 err = 0;
1145 switch (sme->auth_type) {
1146 case NL80211_AUTHTYPE_OPEN_SYSTEM:
1147 val = 0;
1148 WL_CONN("open system\n");
1149 break;
1150 case NL80211_AUTHTYPE_SHARED_KEY:
1151 val = 1;
1152 WL_CONN("shared key\n");
1153 break;
1154 case NL80211_AUTHTYPE_AUTOMATIC:
1155 val = 2;
1156 WL_CONN("automatic\n");
1157 break;
1158 case NL80211_AUTHTYPE_NETWORK_EAP:
1159 WL_CONN("network eap\n");
1160 default:
1161 val = 2;
1162 WL_ERR("invalid auth type (%d)\n", sme->auth_type);
1163 break;
1166 err = brcmf_dev_intvar_set(dev, "auth", val);
1167 if (unlikely(err)) {
1168 WL_ERR("set auth failed (%d)\n", err);
1169 return err;
1171 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1172 sec->auth_type = sme->auth_type;
1173 return err;
1176 static s32
1177 brcmf_set_set_cipher(struct net_device *dev,
1178 struct cfg80211_connect_params *sme)
1180 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(dev);
1181 struct brcmf_cfg80211_security *sec;
1182 s32 pval = 0;
1183 s32 gval = 0;
1184 s32 err = 0;
1186 if (sme->crypto.n_ciphers_pairwise) {
1187 switch (sme->crypto.ciphers_pairwise[0]) {
1188 case WLAN_CIPHER_SUITE_WEP40:
1189 case WLAN_CIPHER_SUITE_WEP104:
1190 pval = WEP_ENABLED;
1191 break;
1192 case WLAN_CIPHER_SUITE_TKIP:
1193 pval = TKIP_ENABLED;
1194 break;
1195 case WLAN_CIPHER_SUITE_CCMP:
1196 pval = AES_ENABLED;
1197 break;
1198 case WLAN_CIPHER_SUITE_AES_CMAC:
1199 pval = AES_ENABLED;
1200 break;
1201 default:
1202 WL_ERR("invalid cipher pairwise (%d)\n",
1203 sme->crypto.ciphers_pairwise[0]);
1204 return -EINVAL;
1207 if (sme->crypto.cipher_group) {
1208 switch (sme->crypto.cipher_group) {
1209 case WLAN_CIPHER_SUITE_WEP40:
1210 case WLAN_CIPHER_SUITE_WEP104:
1211 gval = WEP_ENABLED;
1212 break;
1213 case WLAN_CIPHER_SUITE_TKIP:
1214 gval = TKIP_ENABLED;
1215 break;
1216 case WLAN_CIPHER_SUITE_CCMP:
1217 gval = AES_ENABLED;
1218 break;
1219 case WLAN_CIPHER_SUITE_AES_CMAC:
1220 gval = AES_ENABLED;
1221 break;
1222 default:
1223 WL_ERR("invalid cipher group (%d)\n",
1224 sme->crypto.cipher_group);
1225 return -EINVAL;
1229 WL_CONN("pval (%d) gval (%d)\n", pval, gval);
1230 err = brcmf_dev_intvar_set(dev, "wsec", pval | gval);
1231 if (unlikely(err)) {
1232 WL_ERR("error (%d)\n", err);
1233 return err;
1236 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1237 sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1238 sec->cipher_group = sme->crypto.cipher_group;
1240 return err;
1243 static s32
1244 brcmf_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme)
1246 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(dev);
1247 struct brcmf_cfg80211_security *sec;
1248 s32 val = 0;
1249 s32 err = 0;
1251 if (sme->crypto.n_akm_suites) {
1252 err = brcmf_dev_intvar_get(dev, "wpa_auth", &val);
1253 if (unlikely(err)) {
1254 WL_ERR("could not get wpa_auth (%d)\n", err);
1255 return err;
1257 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1258 switch (sme->crypto.akm_suites[0]) {
1259 case WLAN_AKM_SUITE_8021X:
1260 val = WPA_AUTH_UNSPECIFIED;
1261 break;
1262 case WLAN_AKM_SUITE_PSK:
1263 val = WPA_AUTH_PSK;
1264 break;
1265 default:
1266 WL_ERR("invalid cipher group (%d)\n",
1267 sme->crypto.cipher_group);
1268 return -EINVAL;
1270 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1271 switch (sme->crypto.akm_suites[0]) {
1272 case WLAN_AKM_SUITE_8021X:
1273 val = WPA2_AUTH_UNSPECIFIED;
1274 break;
1275 case WLAN_AKM_SUITE_PSK:
1276 val = WPA2_AUTH_PSK;
1277 break;
1278 default:
1279 WL_ERR("invalid cipher group (%d)\n",
1280 sme->crypto.cipher_group);
1281 return -EINVAL;
1285 WL_CONN("setting wpa_auth to %d\n", val);
1286 err = brcmf_dev_intvar_set(dev, "wpa_auth", val);
1287 if (unlikely(err)) {
1288 WL_ERR("could not set wpa_auth (%d)\n", err);
1289 return err;
1292 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1293 sec->wpa_auth = sme->crypto.akm_suites[0];
1295 return err;
1298 static s32
1299 brcmf_set_set_sharedkey(struct net_device *dev,
1300 struct cfg80211_connect_params *sme)
1302 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(dev);
1303 struct brcmf_cfg80211_security *sec;
1304 struct brcmf_wsec_key key;
1305 s32 val;
1306 s32 err = 0;
1308 WL_CONN("key len (%d)\n", sme->key_len);
1309 if (sme->key_len) {
1310 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1311 WL_CONN("wpa_versions 0x%x cipher_pairwise 0x%x\n",
1312 sec->wpa_versions, sec->cipher_pairwise);
1313 if (!
1314 (sec->wpa_versions & (NL80211_WPA_VERSION_1 |
1315 NL80211_WPA_VERSION_2))
1316 && (sec->cipher_pairwise & (WLAN_CIPHER_SUITE_WEP40 |
1317 WLAN_CIPHER_SUITE_WEP104))) {
1318 memset(&key, 0, sizeof(key));
1319 key.len = (u32) sme->key_len;
1320 key.index = (u32) sme->key_idx;
1321 if (unlikely(key.len > sizeof(key.data))) {
1322 WL_ERR("Too long key length (%u)\n", key.len);
1323 return -EINVAL;
1325 memcpy(key.data, sme->key, key.len);
1326 key.flags = BRCMF_PRIMARY_KEY;
1327 switch (sec->cipher_pairwise) {
1328 case WLAN_CIPHER_SUITE_WEP40:
1329 key.algo = CRYPTO_ALGO_WEP1;
1330 break;
1331 case WLAN_CIPHER_SUITE_WEP104:
1332 key.algo = CRYPTO_ALGO_WEP128;
1333 break;
1334 default:
1335 WL_ERR("Invalid algorithm (%d)\n",
1336 sme->crypto.ciphers_pairwise[0]);
1337 return -EINVAL;
1339 /* Set the new key/index */
1340 WL_CONN("key length (%d) key index (%d) algo (%d)\n",
1341 key.len, key.index, key.algo);
1342 WL_CONN("key \"%s\"\n", key.data);
1343 convert_key_from_CPU(&key);
1344 err = brcmf_dev_ioctl(dev, BRCMF_C_SET_KEY, &key,
1345 sizeof(key));
1346 if (unlikely(err)) {
1347 WL_ERR("WLC_SET_KEY error (%d)\n", err);
1348 return err;
1350 if (sec->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) {
1351 WL_CONN("set auth_type to shared key\n");
1352 val = 1; /* shared key */
1353 err = brcmf_dev_intvar_set(dev, "auth", val);
1354 if (unlikely(err)) {
1355 WL_ERR("set auth failed (%d)\n", err);
1356 return err;
1361 return err;
1364 static s32
1365 brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
1366 struct cfg80211_connect_params *sme)
1368 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1369 struct ieee80211_channel *chan = sme->channel;
1370 struct brcmf_join_params join_params;
1371 size_t join_params_size;
1373 s32 err = 0;
1375 WL_TRACE("Enter\n");
1376 CHECK_SYS_UP();
1378 if (unlikely(!sme->ssid)) {
1379 WL_ERR("Invalid ssid\n");
1380 return -EOPNOTSUPP;
1383 set_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
1385 if (chan) {
1386 cfg_priv->channel =
1387 ieee80211_frequency_to_channel(chan->center_freq);
1388 WL_CONN("channel (%d), center_req (%d)\n",
1389 cfg_priv->channel, chan->center_freq);
1390 } else
1391 cfg_priv->channel = 0;
1393 WL_INFO("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
1395 err = brcmf_set_wpa_version(dev, sme);
1396 if (err) {
1397 WL_ERR("wl_set_wpa_version failed (%d)\n", err);
1398 goto done;
1401 err = brcmf_set_auth_type(dev, sme);
1402 if (err) {
1403 WL_ERR("wl_set_auth_type failed (%d)\n", err);
1404 goto done;
1407 err = brcmf_set_set_cipher(dev, sme);
1408 if (err) {
1409 WL_ERR("wl_set_set_cipher failed (%d)\n", err);
1410 goto done;
1413 err = brcmf_set_key_mgmt(dev, sme);
1414 if (err) {
1415 WL_ERR("wl_set_key_mgmt failed (%d)\n", err);
1416 goto done;
1419 err = brcmf_set_set_sharedkey(dev, sme);
1420 if (err) {
1421 WL_ERR("wl_set_set_sharedkey failed (%d)\n", err);
1422 goto done;
1425 memset(&join_params, 0, sizeof(join_params));
1426 join_params_size = sizeof(join_params.ssid);
1428 join_params.ssid.SSID_len =
1429 min(sizeof(join_params.ssid.SSID), sme->ssid_len);
1430 memcpy(&join_params.ssid.SSID, sme->ssid, join_params.ssid.SSID_len);
1431 join_params.ssid.SSID_len = cpu_to_le32(join_params.ssid.SSID_len);
1432 brcmf_update_prof(cfg_priv, NULL, &join_params.ssid, WL_PROF_SSID);
1434 memcpy(join_params.params.bssid, ether_bcast, ETH_ALEN);
1436 if (join_params.ssid.SSID_len < IEEE80211_MAX_SSID_LEN)
1437 WL_CONN("ssid \"%s\", len (%d)\n",
1438 join_params.ssid.SSID, join_params.ssid.SSID_len);
1440 brcmf_ch_to_chanspec(cfg_priv->channel,
1441 &join_params, &join_params_size);
1442 err = brcmf_dev_ioctl(dev, BRCMF_C_SET_SSID,
1443 &join_params, join_params_size);
1444 if (err)
1445 WL_ERR("WLC_SET_SSID failed (%d)\n", err);
1447 done:
1448 if (err)
1449 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
1450 WL_TRACE("Exit\n");
1451 return err;
1454 static s32
1455 brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
1456 u16 reason_code)
1458 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1459 struct brcmf_scb_val scbval;
1460 s32 err = 0;
1462 WL_TRACE("Enter. Reason code = %d\n", reason_code);
1463 CHECK_SYS_UP();
1465 clear_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
1467 scbval.val = reason_code;
1468 memcpy(&scbval.ea, brcmf_read_prof(cfg_priv, WL_PROF_BSSID), ETH_ALEN);
1469 scbval.val = cpu_to_le32(scbval.val);
1470 err = brcmf_dev_ioctl(dev, BRCMF_C_DISASSOC, &scbval,
1471 sizeof(struct brcmf_scb_val));
1472 if (unlikely(err))
1473 WL_ERR("error (%d)\n", err);
1475 cfg_priv->link_up = false;
1477 WL_TRACE("Exit\n");
1478 return err;
1481 static s32
1482 brcmf_cfg80211_set_tx_power(struct wiphy *wiphy,
1483 enum nl80211_tx_power_setting type, s32 dbm)
1486 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1487 struct net_device *ndev = cfg_to_ndev(cfg_priv);
1488 u16 txpwrmw;
1489 s32 err = 0;
1490 s32 disable = 0;
1492 WL_TRACE("Enter\n");
1493 CHECK_SYS_UP();
1495 switch (type) {
1496 case NL80211_TX_POWER_AUTOMATIC:
1497 break;
1498 case NL80211_TX_POWER_LIMITED:
1499 if (dbm < 0) {
1500 WL_ERR("TX_POWER_LIMITED - dbm is negative\n");
1501 err = -EINVAL;
1502 goto done;
1504 break;
1505 case NL80211_TX_POWER_FIXED:
1506 if (dbm < 0) {
1507 WL_ERR("TX_POWER_FIXED - dbm is negative\n");
1508 err = -EINVAL;
1509 goto done;
1511 break;
1513 /* Make sure radio is off or on as far as software is concerned */
1514 disable = WL_RADIO_SW_DISABLE << 16;
1515 disable = cpu_to_le32(disable);
1516 err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_RADIO, &disable,
1517 sizeof(disable));
1518 if (unlikely(err))
1519 WL_ERR("WLC_SET_RADIO error (%d)\n", err);
1521 if (dbm > 0xffff)
1522 txpwrmw = 0xffff;
1523 else
1524 txpwrmw = (u16) dbm;
1525 err = brcmf_dev_intvar_set(ndev, "qtxpower",
1526 (s32) (brcmu_mw_to_qdbm(txpwrmw)));
1527 if (unlikely(err))
1528 WL_ERR("qtxpower error (%d)\n", err);
1529 cfg_priv->conf->tx_power = dbm;
1531 done:
1532 WL_TRACE("Exit\n");
1533 return err;
1536 static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm)
1538 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1539 struct net_device *ndev = cfg_to_ndev(cfg_priv);
1540 s32 txpwrdbm;
1541 u8 result;
1542 s32 err = 0;
1544 WL_TRACE("Enter\n");
1545 CHECK_SYS_UP();
1547 err = brcmf_dev_intvar_get(ndev, "qtxpower", &txpwrdbm);
1548 if (unlikely(err)) {
1549 WL_ERR("error (%d)\n", err);
1550 goto done;
1553 result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
1554 *dbm = (s32) brcmu_qdbm_to_mw(result);
1556 done:
1557 WL_TRACE("Exit\n");
1558 return err;
1561 static s32
1562 brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *dev,
1563 u8 key_idx, bool unicast, bool multicast)
1565 u32 index;
1566 s32 wsec;
1567 s32 err = 0;
1569 WL_TRACE("Enter\n");
1570 WL_CONN("key index (%d)\n", key_idx);
1571 CHECK_SYS_UP();
1573 err = brcmf_dev_ioctl(dev, BRCMF_C_GET_WSEC, &wsec, sizeof(wsec));
1574 if (unlikely(err)) {
1575 WL_ERR("WLC_GET_WSEC error (%d)\n", err);
1576 goto done;
1579 wsec = le32_to_cpu(wsec);
1580 if (wsec & WEP_ENABLED) {
1581 /* Just select a new current key */
1582 index = (u32) key_idx;
1583 index = cpu_to_le32(index);
1584 err = brcmf_dev_ioctl(dev, BRCMF_C_SET_KEY_PRIMARY, &index,
1585 sizeof(index));
1586 if (unlikely(err))
1587 WL_ERR("error (%d)\n", err);
1589 done:
1590 WL_TRACE("Exit\n");
1591 return err;
1594 static s32
1595 brcmf_add_keyext(struct wiphy *wiphy, struct net_device *dev,
1596 u8 key_idx, const u8 *mac_addr, struct key_params *params)
1598 struct brcmf_wsec_key key;
1599 s32 err = 0;
1601 memset(&key, 0, sizeof(key));
1602 key.index = (u32) key_idx;
1603 /* Instead of bcast for ea address for default wep keys,
1604 driver needs it to be Null */
1605 if (!is_multicast_ether_addr(mac_addr))
1606 memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
1607 key.len = (u32) params->key_len;
1608 /* check for key index change */
1609 if (key.len == 0) {
1610 /* key delete */
1611 convert_key_from_CPU(&key);
1612 err = brcmf_dev_ioctl(dev, BRCMF_C_SET_KEY, &key, sizeof(key));
1613 if (unlikely(err)) {
1614 WL_ERR("key delete error (%d)\n", err);
1615 return err;
1617 } else {
1618 if (key.len > sizeof(key.data)) {
1619 WL_ERR("Invalid key length (%d)\n", key.len);
1620 return -EINVAL;
1623 WL_CONN("Setting the key index %d\n", key.index);
1624 memcpy(key.data, params->key, key.len);
1626 if (params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1627 u8 keybuf[8];
1628 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1629 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1630 memcpy(&key.data[16], keybuf, sizeof(keybuf));
1633 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
1634 if (params->seq && params->seq_len == 6) {
1635 /* rx iv */
1636 u8 *ivptr;
1637 ivptr = (u8 *) params->seq;
1638 key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
1639 (ivptr[3] << 8) | ivptr[2];
1640 key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
1641 key.iv_initialized = true;
1644 switch (params->cipher) {
1645 case WLAN_CIPHER_SUITE_WEP40:
1646 key.algo = CRYPTO_ALGO_WEP1;
1647 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1648 break;
1649 case WLAN_CIPHER_SUITE_WEP104:
1650 key.algo = CRYPTO_ALGO_WEP128;
1651 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1652 break;
1653 case WLAN_CIPHER_SUITE_TKIP:
1654 key.algo = CRYPTO_ALGO_TKIP;
1655 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1656 break;
1657 case WLAN_CIPHER_SUITE_AES_CMAC:
1658 key.algo = CRYPTO_ALGO_AES_CCM;
1659 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1660 break;
1661 case WLAN_CIPHER_SUITE_CCMP:
1662 key.algo = CRYPTO_ALGO_AES_CCM;
1663 WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
1664 break;
1665 default:
1666 WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
1667 return -EINVAL;
1669 convert_key_from_CPU(&key);
1671 brcmf_netdev_wait_pend8021x(dev);
1672 err = brcmf_dev_ioctl(dev, BRCMF_C_SET_KEY, &key, sizeof(key));
1673 if (unlikely(err)) {
1674 WL_ERR("WLC_SET_KEY error (%d)\n", err);
1675 return err;
1678 return err;
1681 static s32
1682 brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
1683 u8 key_idx, bool pairwise, const u8 *mac_addr,
1684 struct key_params *params)
1686 struct brcmf_wsec_key key;
1687 s32 val;
1688 s32 wsec;
1689 s32 err = 0;
1690 u8 keybuf[8];
1692 WL_TRACE("Enter\n");
1693 WL_CONN("key index (%d)\n", key_idx);
1694 CHECK_SYS_UP();
1696 if (mac_addr) {
1697 WL_TRACE("Exit");
1698 return brcmf_add_keyext(wiphy, dev, key_idx, mac_addr, params);
1700 memset(&key, 0, sizeof(key));
1702 key.len = (u32) params->key_len;
1703 key.index = (u32) key_idx;
1705 if (unlikely(key.len > sizeof(key.data))) {
1706 WL_ERR("Too long key length (%u)\n", key.len);
1707 err = -EINVAL;
1708 goto done;
1710 memcpy(key.data, params->key, key.len);
1712 key.flags = BRCMF_PRIMARY_KEY;
1713 switch (params->cipher) {
1714 case WLAN_CIPHER_SUITE_WEP40:
1715 key.algo = CRYPTO_ALGO_WEP1;
1716 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1717 break;
1718 case WLAN_CIPHER_SUITE_WEP104:
1719 key.algo = CRYPTO_ALGO_WEP128;
1720 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1721 break;
1722 case WLAN_CIPHER_SUITE_TKIP:
1723 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1724 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1725 memcpy(&key.data[16], keybuf, sizeof(keybuf));
1726 key.algo = CRYPTO_ALGO_TKIP;
1727 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1728 break;
1729 case WLAN_CIPHER_SUITE_AES_CMAC:
1730 key.algo = CRYPTO_ALGO_AES_CCM;
1731 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1732 break;
1733 case WLAN_CIPHER_SUITE_CCMP:
1734 key.algo = CRYPTO_ALGO_AES_CCM;
1735 WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
1736 break;
1737 default:
1738 WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
1739 err = -EINVAL;
1740 goto done;
1743 /* Set the new key/index */
1744 convert_key_from_CPU(&key);
1745 err = brcmf_dev_ioctl(dev, BRCMF_C_SET_KEY, &key, sizeof(key));
1746 if (unlikely(err)) {
1747 WL_ERR("WLC_SET_KEY error (%d)\n", err);
1748 goto done;
1751 val = WEP_ENABLED;
1752 err = brcmf_dev_intvar_get(dev, "wsec", &wsec);
1753 if (unlikely(err)) {
1754 WL_ERR("get wsec error (%d)\n", err);
1755 goto done;
1757 wsec &= ~(WEP_ENABLED);
1758 wsec |= val;
1759 err = brcmf_dev_intvar_set(dev, "wsec", wsec);
1760 if (unlikely(err)) {
1761 WL_ERR("set wsec error (%d)\n", err);
1762 goto done;
1765 val = 1; /* assume shared key. otherwise 0 */
1766 val = cpu_to_le32(val);
1767 err = brcmf_dev_ioctl(dev, BRCMF_C_SET_AUTH, &val, sizeof(val));
1768 if (unlikely(err))
1769 WL_ERR("WLC_SET_AUTH error (%d)\n", err);
1770 done:
1771 WL_TRACE("Exit\n");
1772 return err;
1775 static s32
1776 brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
1777 u8 key_idx, bool pairwise, const u8 *mac_addr)
1779 struct brcmf_wsec_key key;
1780 s32 err = 0;
1781 s32 val;
1782 s32 wsec;
1784 WL_TRACE("Enter\n");
1785 CHECK_SYS_UP();
1786 memset(&key, 0, sizeof(key));
1788 key.index = (u32) key_idx;
1789 key.flags = BRCMF_PRIMARY_KEY;
1790 key.algo = CRYPTO_ALGO_OFF;
1792 WL_CONN("key index (%d)\n", key_idx);
1793 /* Set the new key/index */
1794 convert_key_from_CPU(&key);
1795 err = brcmf_dev_ioctl(dev, BRCMF_C_SET_KEY, &key, sizeof(key));
1796 if (unlikely(err)) {
1797 if (err == -EINVAL) {
1798 if (key.index >= DOT11_MAX_DEFAULT_KEYS)
1799 /* we ignore this key index in this case */
1800 WL_ERR("invalid key index (%d)\n", key_idx);
1801 } else
1802 WL_ERR("WLC_SET_KEY error (%d)\n", err);
1804 /* Ignore this error, may happen during DISASSOC */
1805 err = -EAGAIN;
1806 goto done;
1809 val = 0;
1810 err = brcmf_dev_intvar_get(dev, "wsec", &wsec);
1811 if (unlikely(err)) {
1812 WL_ERR("get wsec error (%d)\n", err);
1813 /* Ignore this error, may happen during DISASSOC */
1814 err = -EAGAIN;
1815 goto done;
1817 wsec &= ~(WEP_ENABLED);
1818 wsec |= val;
1819 err = brcmf_dev_intvar_set(dev, "wsec", wsec);
1820 if (unlikely(err)) {
1821 WL_ERR("set wsec error (%d)\n", err);
1822 /* Ignore this error, may happen during DISASSOC */
1823 err = -EAGAIN;
1824 goto done;
1827 val = 0; /* assume open key. otherwise 1 */
1828 val = cpu_to_le32(val);
1829 err = brcmf_dev_ioctl(dev, BRCMF_C_SET_AUTH, &val, sizeof(val));
1830 if (unlikely(err)) {
1831 WL_ERR("WLC_SET_AUTH error (%d)\n", err);
1832 /* Ignore this error, may happen during DISASSOC */
1833 err = -EAGAIN;
1835 done:
1836 WL_TRACE("Exit\n");
1837 return err;
1840 static s32
1841 brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
1842 u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
1843 void (*callback) (void *cookie, struct key_params * params))
1845 struct key_params params;
1846 struct brcmf_wsec_key key;
1847 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1848 struct brcmf_cfg80211_security *sec;
1849 s32 wsec;
1850 s32 err = 0;
1852 WL_TRACE("Enter\n");
1853 WL_CONN("key index (%d)\n", key_idx);
1854 CHECK_SYS_UP();
1856 memset(&key, 0, sizeof(key));
1857 key.index = key_idx;
1858 convert_key_to_CPU(&key);
1859 memset(&params, 0, sizeof(params));
1860 params.key_len = (u8) min_t(u8, WLAN_MAX_KEY_LEN, key.len);
1861 memcpy(params.key, key.data, params.key_len);
1863 err = brcmf_dev_ioctl(dev, BRCMF_C_GET_WSEC, &wsec, sizeof(wsec));
1864 if (unlikely(err)) {
1865 WL_ERR("WLC_GET_WSEC error (%d)\n", err);
1866 /* Ignore this error, may happen during DISASSOC */
1867 err = -EAGAIN;
1868 goto done;
1870 wsec = le32_to_cpu(wsec);
1871 switch (wsec) {
1872 case WEP_ENABLED:
1873 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1874 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
1875 params.cipher = WLAN_CIPHER_SUITE_WEP40;
1876 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1877 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
1878 params.cipher = WLAN_CIPHER_SUITE_WEP104;
1879 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1881 break;
1882 case TKIP_ENABLED:
1883 params.cipher = WLAN_CIPHER_SUITE_TKIP;
1884 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1885 break;
1886 case AES_ENABLED:
1887 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
1888 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1889 break;
1890 default:
1891 WL_ERR("Invalid algo (0x%x)\n", wsec);
1892 err = -EINVAL;
1893 goto done;
1895 callback(cookie, &params);
1897 done:
1898 WL_TRACE("Exit\n");
1899 return err;
1902 static s32
1903 brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
1904 struct net_device *dev, u8 key_idx)
1906 WL_INFO("Not supported\n");
1908 CHECK_SYS_UP();
1909 return -EOPNOTSUPP;
1912 static s32
1913 brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
1914 u8 *mac, struct station_info *sinfo)
1916 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1917 struct brcmf_scb_val scb_val;
1918 int rssi;
1919 s32 rate;
1920 s32 err = 0;
1921 u8 *bssid = brcmf_read_prof(cfg_priv, WL_PROF_BSSID);
1923 WL_TRACE("Enter\n");
1924 CHECK_SYS_UP();
1926 if (unlikely
1927 (memcmp(mac, bssid, ETH_ALEN))) {
1928 WL_ERR("Wrong Mac address cfg_mac-%X:%X:%X:%X:%X:%X"
1929 "wl_bssid-%X:%X:%X:%X:%X:%X\n",
1930 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
1931 bssid[0], bssid[1], bssid[2], bssid[3],
1932 bssid[4], bssid[5]);
1933 err = -ENOENT;
1934 goto done;
1937 /* Report the current tx rate */
1938 err = brcmf_dev_ioctl(dev, BRCMF_C_GET_RATE, &rate, sizeof(rate));
1939 if (err) {
1940 WL_ERR("Could not get rate (%d)\n", err);
1941 } else {
1942 rate = le32_to_cpu(rate);
1943 sinfo->filled |= STATION_INFO_TX_BITRATE;
1944 sinfo->txrate.legacy = rate * 5;
1945 WL_CONN("Rate %d Mbps\n", rate / 2);
1948 if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status)) {
1949 scb_val.val = 0;
1950 err = brcmf_dev_ioctl(dev, BRCMF_C_GET_RSSI, &scb_val,
1951 sizeof(struct brcmf_scb_val));
1952 if (unlikely(err))
1953 WL_ERR("Could not get rssi (%d)\n", err);
1955 rssi = le32_to_cpu(scb_val.val);
1956 sinfo->filled |= STATION_INFO_SIGNAL;
1957 sinfo->signal = rssi;
1958 WL_CONN("RSSI %d dBm\n", rssi);
1961 done:
1962 WL_TRACE("Exit\n");
1963 return err;
1966 static s32
1967 brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
1968 bool enabled, s32 timeout)
1970 s32 pm;
1971 s32 err = 0;
1972 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1974 WL_TRACE("Enter\n");
1977 * Powersave enable/disable request is coming from the
1978 * cfg80211 even before the interface is up. In that
1979 * scenario, driver will be storing the power save
1980 * preference in cfg_priv struct to apply this to
1981 * FW later while initializing the dongle
1983 cfg_priv->pwr_save = enabled;
1984 if (!test_bit(WL_STATUS_READY, &cfg_priv->status)) {
1986 WL_INFO("Device is not ready,"
1987 "storing the value in cfg_priv struct\n");
1988 goto done;
1991 pm = enabled ? PM_FAST : PM_OFF;
1992 pm = cpu_to_le32(pm);
1993 WL_INFO("power save %s\n", (pm ? "enabled" : "disabled"));
1995 err = brcmf_dev_ioctl(dev, BRCMF_C_SET_PM, &pm, sizeof(pm));
1996 if (unlikely(err)) {
1997 if (err == -ENODEV)
1998 WL_ERR("net_device is not ready yet\n");
1999 else
2000 WL_ERR("error (%d)\n", err);
2002 done:
2003 WL_TRACE("Exit\n");
2004 return err;
2007 static s32
2008 brcmf_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev,
2009 const u8 *addr,
2010 const struct cfg80211_bitrate_mask *mask)
2012 struct brcm_rateset rateset;
2013 s32 rate;
2014 s32 val;
2015 s32 err_bg;
2016 s32 err_a;
2017 u32 legacy;
2018 s32 err = 0;
2020 WL_TRACE("Enter\n");
2021 CHECK_SYS_UP();
2023 /* addr param is always NULL. ignore it */
2024 /* Get current rateset */
2025 err = brcmf_dev_ioctl(dev, BRCM_GET_CURR_RATESET, &rateset,
2026 sizeof(rateset));
2027 if (unlikely(err)) {
2028 WL_ERR("could not get current rateset (%d)\n", err);
2029 goto done;
2032 rateset.count = le32_to_cpu(rateset.count);
2034 legacy = ffs(mask->control[IEEE80211_BAND_2GHZ].legacy & 0xFFFF);
2035 if (!legacy)
2036 legacy = ffs(mask->control[IEEE80211_BAND_5GHZ].legacy &
2037 0xFFFF);
2039 val = wl_g_rates[legacy - 1].bitrate * 100000;
2041 if (val < rateset.count)
2042 /* Select rate by rateset index */
2043 rate = rateset.rates[val] & 0x7f;
2044 else
2045 /* Specified rate in bps */
2046 rate = val / 500000;
2048 WL_CONN("rate %d mbps\n", rate / 2);
2052 * Set rate override,
2053 * Since the is a/b/g-blind, both a/bg_rate are enforced.
2055 err_bg = brcmf_dev_intvar_set(dev, "bg_rate", rate);
2056 err_a = brcmf_dev_intvar_set(dev, "a_rate", rate);
2057 if (unlikely(err_bg && err_a)) {
2058 WL_ERR("could not set fixed rate (%d) (%d)\n", err_bg, err_a);
2059 err = err_bg | err_a;
2062 done:
2063 WL_TRACE("Exit\n");
2064 return err;
2067 static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
2069 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2072 * Check for WL_STATUS_READY before any function call which
2073 * could result is bus access. Don't block the resume for
2074 * any driver error conditions
2076 WL_TRACE("Enter\n");
2078 if (test_bit(WL_STATUS_READY, &cfg_priv->status))
2079 brcmf_invoke_iscan(wiphy_to_cfg(wiphy));
2081 WL_TRACE("Exit\n");
2082 return 0;
2085 static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
2086 struct cfg80211_wowlan *wow)
2088 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2089 struct net_device *ndev = cfg_to_ndev(cfg_priv);
2091 WL_TRACE("Enter\n");
2094 * Check for WL_STATUS_READY before any function call which
2095 * could result is bus access. Don't block the suspend for
2096 * any driver error conditions
2100 * While going to suspend if associated with AP disassociate
2101 * from AP to save power while system is in suspended state
2103 if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) ||
2104 test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) &&
2105 test_bit(WL_STATUS_READY, &cfg_priv->status)) {
2106 WL_INFO("Disassociating from AP"
2107 " while entering suspend state\n");
2108 brcmf_link_down(cfg_priv);
2111 * Make sure WPA_Supplicant receives all the event
2112 * generated due to DISASSOC call to the fw to keep
2113 * the state fw and WPA_Supplicant state consistent
2115 rtnl_unlock();
2116 brcmf_delay(500);
2117 rtnl_lock();
2120 set_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
2121 if (test_bit(WL_STATUS_READY, &cfg_priv->status))
2122 brcmf_term_iscan(cfg_priv);
2124 if (cfg_priv->scan_request) {
2125 /* Indidate scan abort to cfg80211 layer */
2126 WL_INFO("Terminating scan in progress\n");
2127 cfg80211_scan_done(cfg_priv->scan_request, true);
2128 cfg_priv->scan_request = NULL;
2130 clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
2131 clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
2133 /* Turn off watchdog timer */
2134 if (test_bit(WL_STATUS_READY, &cfg_priv->status)) {
2135 WL_INFO("Enable MPC\n");
2136 brcmf_set_mpc(ndev, 1);
2139 WL_TRACE("Exit\n");
2141 return 0;
2144 static __used s32
2145 brcmf_update_pmklist(struct net_device *dev,
2146 struct brcmf_cfg80211_pmk_list *pmk_list, s32 err)
2148 int i, j;
2150 WL_CONN("No of elements %d\n", pmk_list->pmkids.npmkid);
2151 for (i = 0; i < pmk_list->pmkids.npmkid; i++) {
2152 WL_CONN("PMKID[%d]: %pM =\n", i,
2153 &pmk_list->pmkids.pmkid[i].BSSID);
2154 for (j = 0; j < WLAN_PMKID_LEN; j++)
2155 WL_CONN("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]);
2158 if (likely(!err))
2159 brcmf_dev_bufvar_set(dev, "pmkid_info", (char *)pmk_list,
2160 sizeof(*pmk_list));
2162 return err;
2165 static s32
2166 brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
2167 struct cfg80211_pmksa *pmksa)
2169 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2170 struct pmkid_list *pmkids = &cfg_priv->pmk_list->pmkids;
2171 s32 err = 0;
2172 int i;
2174 WL_TRACE("Enter\n");
2175 CHECK_SYS_UP();
2177 for (i = 0; i < pmkids->npmkid; i++)
2178 if (!memcmp(pmksa->bssid, pmkids->pmkid[i].BSSID, ETH_ALEN))
2179 break;
2180 if (i < WL_NUM_PMKIDS_MAX) {
2181 memcpy(pmkids->pmkid[i].BSSID, pmksa->bssid, ETH_ALEN);
2182 memcpy(pmkids->pmkid[i].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2183 if (i == pmkids->npmkid)
2184 pmkids->npmkid++;
2185 } else
2186 err = -EINVAL;
2188 WL_CONN("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2189 pmkids->pmkid[pmkids->npmkid].BSSID);
2190 for (i = 0; i < WLAN_PMKID_LEN; i++)
2191 WL_CONN("%02x\n", pmkids->pmkid[pmkids->npmkid].PMKID[i]);
2193 err = brcmf_update_pmklist(dev, cfg_priv->pmk_list, err);
2195 WL_TRACE("Exit\n");
2196 return err;
2199 static s32
2200 brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
2201 struct cfg80211_pmksa *pmksa)
2203 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2204 struct pmkid_list pmkid;
2205 s32 err = 0;
2206 int i;
2208 WL_TRACE("Enter\n");
2209 CHECK_SYS_UP();
2210 memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
2211 memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2213 WL_CONN("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2214 &pmkid.pmkid[0].BSSID);
2215 for (i = 0; i < WLAN_PMKID_LEN; i++)
2216 WL_CONN("%02x\n", pmkid.pmkid[0].PMKID[i]);
2218 for (i = 0; i < cfg_priv->pmk_list->pmkids.npmkid; i++)
2219 if (!memcmp
2220 (pmksa->bssid, &cfg_priv->pmk_list->pmkids.pmkid[i].BSSID,
2221 ETH_ALEN))
2222 break;
2224 if ((cfg_priv->pmk_list->pmkids.npmkid > 0)
2225 && (i < cfg_priv->pmk_list->pmkids.npmkid)) {
2226 memset(&cfg_priv->pmk_list->pmkids.pmkid[i], 0,
2227 sizeof(struct pmkid));
2228 for (; i < (cfg_priv->pmk_list->pmkids.npmkid - 1); i++) {
2229 memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].BSSID,
2230 &cfg_priv->pmk_list->pmkids.pmkid[i + 1].BSSID,
2231 ETH_ALEN);
2232 memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].PMKID,
2233 &cfg_priv->pmk_list->pmkids.pmkid[i + 1].PMKID,
2234 WLAN_PMKID_LEN);
2236 cfg_priv->pmk_list->pmkids.npmkid--;
2237 } else
2238 err = -EINVAL;
2240 err = brcmf_update_pmklist(dev, cfg_priv->pmk_list, err);
2242 WL_TRACE("Exit\n");
2243 return err;
2247 static s32
2248 brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
2250 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2251 s32 err = 0;
2253 WL_TRACE("Enter\n");
2254 CHECK_SYS_UP();
2256 memset(cfg_priv->pmk_list, 0, sizeof(*cfg_priv->pmk_list));
2257 err = brcmf_update_pmklist(dev, cfg_priv->pmk_list, err);
2259 WL_TRACE("Exit\n");
2260 return err;
2264 static struct cfg80211_ops wl_cfg80211_ops = {
2265 .change_virtual_intf = brcmf_cfg80211_change_iface,
2266 .scan = brcmf_cfg80211_scan,
2267 .set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
2268 .join_ibss = brcmf_cfg80211_join_ibss,
2269 .leave_ibss = brcmf_cfg80211_leave_ibss,
2270 .get_station = brcmf_cfg80211_get_station,
2271 .set_tx_power = brcmf_cfg80211_set_tx_power,
2272 .get_tx_power = brcmf_cfg80211_get_tx_power,
2273 .add_key = brcmf_cfg80211_add_key,
2274 .del_key = brcmf_cfg80211_del_key,
2275 .get_key = brcmf_cfg80211_get_key,
2276 .set_default_key = brcmf_cfg80211_config_default_key,
2277 .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
2278 .set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
2279 .set_bitrate_mask = brcmf_cfg80211_set_bitrate_mask,
2280 .connect = brcmf_cfg80211_connect,
2281 .disconnect = brcmf_cfg80211_disconnect,
2282 .suspend = brcmf_cfg80211_suspend,
2283 .resume = brcmf_cfg80211_resume,
2284 .set_pmksa = brcmf_cfg80211_set_pmksa,
2285 .del_pmksa = brcmf_cfg80211_del_pmksa,
2286 .flush_pmksa = brcmf_cfg80211_flush_pmksa
2289 static s32 brcmf_mode_to_nl80211_iftype(s32 mode)
2291 s32 err = 0;
2293 switch (mode) {
2294 case WL_MODE_BSS:
2295 return NL80211_IFTYPE_STATION;
2296 case WL_MODE_IBSS:
2297 return NL80211_IFTYPE_ADHOC;
2298 default:
2299 return NL80211_IFTYPE_UNSPECIFIED;
2302 return err;
2305 static struct wireless_dev *brcmf_alloc_wdev(s32 sizeof_iface,
2306 struct device *dev)
2308 struct wireless_dev *wdev;
2309 s32 err = 0;
2311 wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
2312 if (unlikely(!wdev)) {
2313 WL_ERR("Could not allocate wireless device\n");
2314 return ERR_PTR(-ENOMEM);
2316 wdev->wiphy =
2317 wiphy_new(&wl_cfg80211_ops,
2318 sizeof(struct brcmf_cfg80211_priv) + sizeof_iface);
2319 if (unlikely(!wdev->wiphy)) {
2320 WL_ERR("Couldn not allocate wiphy device\n");
2321 err = -ENOMEM;
2322 goto wiphy_new_out;
2324 set_wiphy_dev(wdev->wiphy, dev);
2325 wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
2326 wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
2327 wdev->wiphy->interface_modes =
2328 BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
2329 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
2330 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a; /* Set
2331 * it as 11a by default.
2332 * This will be updated with
2333 * 11n phy tables in
2334 * "ifconfig up"
2335 * if phy has 11n capability
2337 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2338 wdev->wiphy->cipher_suites = __wl_cipher_suites;
2339 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
2340 #ifndef WL_POWERSAVE_DISABLED
2341 wdev->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; /* enable power
2342 * save mode
2343 * by default
2345 #else
2346 wdev->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
2347 #endif /* !WL_POWERSAVE_DISABLED */
2348 err = wiphy_register(wdev->wiphy);
2349 if (unlikely(err < 0)) {
2350 WL_ERR("Couldn not register wiphy device (%d)\n", err);
2351 goto wiphy_register_out;
2353 return wdev;
2355 wiphy_register_out:
2356 wiphy_free(wdev->wiphy);
2358 wiphy_new_out:
2359 kfree(wdev);
2361 return ERR_PTR(err);
2364 static void brcmf_free_wdev(struct brcmf_cfg80211_priv *cfg_priv)
2366 struct wireless_dev *wdev = cfg_to_wdev(cfg_priv);
2368 if (unlikely(!wdev)) {
2369 WL_ERR("wdev is invalid\n");
2370 return;
2372 wiphy_unregister(wdev->wiphy);
2373 wiphy_free(wdev->wiphy);
2374 kfree(wdev);
2375 cfg_to_wdev(cfg_priv) = NULL;
2378 static s32 brcmf_inform_bss(struct brcmf_cfg80211_priv *cfg_priv)
2380 struct brcmf_scan_results *bss_list;
2381 struct brcmf_bss_info *bi = NULL; /* must be initialized */
2382 s32 err = 0;
2383 int i;
2385 bss_list = cfg_priv->bss_list;
2386 if (unlikely(bss_list->version != BRCMF_BSS_INFO_VERSION)) {
2387 WL_ERR("Version %d != WL_BSS_INFO_VERSION\n",
2388 bss_list->version);
2389 return -EOPNOTSUPP;
2391 WL_SCAN("scanned AP count (%d)\n", bss_list->count);
2392 bi = next_bss(bss_list, bi);
2393 for_each_bss(bss_list, bi, i) {
2394 err = brcmf_inform_single_bss(cfg_priv, bi);
2395 if (unlikely(err))
2396 break;
2398 return err;
2402 static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv,
2403 struct brcmf_bss_info *bi)
2405 struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
2406 struct ieee80211_channel *notify_channel;
2407 struct cfg80211_bss *bss;
2408 struct ieee80211_supported_band *band;
2409 s32 err = 0;
2410 u16 channel;
2411 u32 freq;
2412 u64 notify_timestamp;
2413 u16 notify_capability;
2414 u16 notify_interval;
2415 u8 *notify_ie;
2416 size_t notify_ielen;
2417 s32 notify_signal;
2419 if (unlikely(le32_to_cpu(bi->length) > WL_BSS_INFO_MAX)) {
2420 WL_ERR("Bss info is larger than buffer. Discarding\n");
2421 return 0;
2424 channel = bi->ctl_ch ? bi->ctl_ch :
2425 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2427 if (channel <= CH_MAX_2G_CHANNEL)
2428 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2429 else
2430 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2432 freq = ieee80211_channel_to_frequency(channel, band->band);
2433 notify_channel = ieee80211_get_channel(wiphy, freq);
2435 notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */
2436 notify_capability = le16_to_cpu(bi->capability);
2437 notify_interval = le16_to_cpu(bi->beacon_period);
2438 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2439 notify_ielen = le16_to_cpu(bi->ie_length);
2440 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2442 WL_CONN("bssid: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
2443 bi->BSSID[0], bi->BSSID[1], bi->BSSID[2],
2444 bi->BSSID[3], bi->BSSID[4], bi->BSSID[5]);
2445 WL_CONN("Channel: %d(%d)\n", channel, freq);
2446 WL_CONN("Capability: %X\n", notify_capability);
2447 WL_CONN("Beacon interval: %d\n", notify_interval);
2448 WL_CONN("Signal: %d\n", notify_signal);
2449 WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp);
2451 bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)bi->BSSID,
2452 notify_timestamp, notify_capability, notify_interval, notify_ie,
2453 notify_ielen, notify_signal, GFP_KERNEL);
2455 if (unlikely(!bss)) {
2456 WL_ERR("cfg80211_inform_bss_frame error\n");
2457 return -EINVAL;
2460 return err;
2463 static s32 wl_inform_ibss(struct brcmf_cfg80211_priv *cfg_priv,
2464 struct net_device *dev, const u8 *bssid)
2466 struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
2467 struct ieee80211_channel *notify_channel;
2468 struct brcmf_bss_info *bi = NULL;
2469 struct ieee80211_supported_band *band;
2470 u8 *buf = NULL;
2471 s32 err = 0;
2472 u16 channel;
2473 u32 freq;
2474 u64 notify_timestamp;
2475 u16 notify_capability;
2476 u16 notify_interval;
2477 u8 *notify_ie;
2478 size_t notify_ielen;
2479 s32 notify_signal;
2481 WL_TRACE("Enter\n");
2483 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2484 if (buf == NULL) {
2485 WL_ERR("kzalloc() failed\n");
2486 err = -ENOMEM;
2487 goto CleanUp;
2490 *(u32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
2492 err = brcmf_dev_ioctl(dev, BRCMF_C_GET_BSS_INFO, buf, WL_BSS_INFO_MAX);
2493 if (unlikely(err)) {
2494 WL_ERR("WLC_GET_BSS_INFO failed: %d\n", err);
2495 goto CleanUp;
2498 bi = (struct brcmf_bss_info *)(buf + 4);
2500 channel = bi->ctl_ch ? bi->ctl_ch :
2501 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2503 if (channel <= CH_MAX_2G_CHANNEL)
2504 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2505 else
2506 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2508 freq = ieee80211_channel_to_frequency(channel, band->band);
2509 notify_channel = ieee80211_get_channel(wiphy, freq);
2511 notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */
2512 notify_capability = le16_to_cpu(bi->capability);
2513 notify_interval = le16_to_cpu(bi->beacon_period);
2514 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2515 notify_ielen = le16_to_cpu(bi->ie_length);
2516 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2518 WL_CONN("channel: %d(%d)\n", channel, freq);
2519 WL_CONN("capability: %X\n", notify_capability);
2520 WL_CONN("beacon interval: %d\n", notify_interval);
2521 WL_CONN("signal: %d\n", notify_signal);
2522 WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp);
2524 cfg80211_inform_bss(wiphy, notify_channel, bssid,
2525 notify_timestamp, notify_capability, notify_interval,
2526 notify_ie, notify_ielen, notify_signal, GFP_KERNEL);
2528 CleanUp:
2530 kfree(buf);
2532 WL_TRACE("Exit\n");
2534 return err;
2537 static bool brcmf_is_linkup(struct brcmf_cfg80211_priv *cfg_priv,
2538 const struct brcmf_event_msg *e)
2540 u32 event = be32_to_cpu(e->event_type);
2541 u32 status = be32_to_cpu(e->status);
2543 if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
2544 WL_CONN("Processing set ssid\n");
2545 cfg_priv->link_up = true;
2546 return true;
2549 return false;
2552 static bool brcmf_is_linkdown(struct brcmf_cfg80211_priv *cfg_priv,
2553 const struct brcmf_event_msg *e)
2555 u32 event = be32_to_cpu(e->event_type);
2556 u16 flags = be16_to_cpu(e->flags);
2558 if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) {
2559 WL_CONN("Processing link down\n");
2560 return true;
2562 return false;
2565 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_priv *cfg_priv,
2566 const struct brcmf_event_msg *e)
2568 u32 event = be32_to_cpu(e->event_type);
2569 u32 status = be32_to_cpu(e->status);
2571 if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
2572 WL_CONN("Processing Link %s & no network found\n",
2573 be16_to_cpu(e->flags) & BRCMF_EVENT_MSG_LINK ?
2574 "up" : "down");
2575 return true;
2578 if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
2579 WL_CONN("Processing connecting & no network found\n");
2580 return true;
2583 return false;
2586 static s32
2587 brcmf_notify_connect_status(struct brcmf_cfg80211_priv *cfg_priv,
2588 struct net_device *ndev,
2589 const struct brcmf_event_msg *e, void *data)
2591 s32 err = 0;
2593 if (brcmf_is_linkup(cfg_priv, e)) {
2594 WL_CONN("Linkup\n");
2595 if (brcmf_is_ibssmode(cfg_priv)) {
2596 brcmf_update_prof(cfg_priv, NULL, (void *)e->addr,
2597 WL_PROF_BSSID);
2598 wl_inform_ibss(cfg_priv, ndev, e->addr);
2599 cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
2600 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
2601 set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
2602 } else
2603 brcmf_bss_connect_done(cfg_priv, ndev, e, true);
2604 } else if (brcmf_is_linkdown(cfg_priv, e)) {
2605 WL_CONN("Linkdown\n");
2606 if (brcmf_is_ibssmode(cfg_priv)) {
2607 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
2608 if (test_and_clear_bit(WL_STATUS_CONNECTED,
2609 &cfg_priv->status))
2610 brcmf_link_down(cfg_priv);
2611 } else {
2612 brcmf_bss_connect_done(cfg_priv, ndev, e, false);
2613 if (test_and_clear_bit(WL_STATUS_CONNECTED,
2614 &cfg_priv->status)) {
2615 cfg80211_disconnected(ndev, 0, NULL, 0,
2616 GFP_KERNEL);
2617 brcmf_link_down(cfg_priv);
2620 brcmf_init_prof(cfg_priv->profile);
2621 } else if (brcmf_is_nonetwork(cfg_priv, e)) {
2622 if (brcmf_is_ibssmode(cfg_priv))
2623 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
2624 else
2625 brcmf_bss_connect_done(cfg_priv, ndev, e, false);
2628 return err;
2631 static s32
2632 brcmf_notify_roaming_status(struct brcmf_cfg80211_priv *cfg_priv,
2633 struct net_device *ndev,
2634 const struct brcmf_event_msg *e, void *data)
2636 s32 err = 0;
2637 u32 event = be32_to_cpu(e->event_type);
2638 u32 status = be32_to_cpu(e->status);
2640 if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
2641 if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status))
2642 brcmf_bss_roaming_done(cfg_priv, ndev, e);
2643 else
2644 brcmf_bss_connect_done(cfg_priv, ndev, e, true);
2647 return err;
2650 static __used s32
2651 brcmf_dev_bufvar_set(struct net_device *dev, s8 *name, s8 *buf, s32 len)
2653 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(dev);
2654 u32 buflen;
2656 buflen = brcmu_mkiovar(name, buf, len, cfg_priv->ioctl_buf,
2657 WL_IOCTL_LEN_MAX);
2658 BUG_ON(!buflen);
2660 return brcmf_dev_ioctl(dev, BRCMF_C_SET_VAR, cfg_priv->ioctl_buf,
2661 buflen);
2664 static s32
2665 brcmf_dev_bufvar_get(struct net_device *dev, s8 *name, s8 *buf,
2666 s32 buf_len)
2668 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(dev);
2669 u32 len;
2670 s32 err = 0;
2672 len = brcmu_mkiovar(name, NULL, 0, cfg_priv->ioctl_buf,
2673 WL_IOCTL_LEN_MAX);
2674 BUG_ON(!len);
2675 err = brcmf_dev_ioctl(dev, BRCMF_C_GET_VAR, (void *)cfg_priv->ioctl_buf,
2676 WL_IOCTL_LEN_MAX);
2677 if (unlikely(err)) {
2678 WL_ERR("error (%d)\n", err);
2679 return err;
2681 memcpy(buf, cfg_priv->ioctl_buf, buf_len);
2683 return err;
2686 static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
2688 struct net_device *ndev = cfg_to_ndev(cfg_priv);
2689 struct brcmf_cfg80211_assoc_ielen *assoc_info;
2690 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2691 u32 req_len;
2692 u32 resp_len;
2693 s32 err = 0;
2695 brcmf_clear_assoc_ies(cfg_priv);
2697 err = brcmf_dev_bufvar_get(ndev, "assoc_info", cfg_priv->extra_buf,
2698 WL_ASSOC_INFO_MAX);
2699 if (unlikely(err)) {
2700 WL_ERR("could not get assoc info (%d)\n", err);
2701 return err;
2703 assoc_info = (struct brcmf_cfg80211_assoc_ielen *)cfg_priv->extra_buf;
2704 req_len = assoc_info->req_len;
2705 resp_len = assoc_info->resp_len;
2706 if (req_len) {
2707 err = brcmf_dev_bufvar_get(ndev, "assoc_req_ies",
2708 cfg_priv->extra_buf,
2709 WL_ASSOC_INFO_MAX);
2710 if (unlikely(err)) {
2711 WL_ERR("could not get assoc req (%d)\n", err);
2712 return err;
2714 conn_info->req_ie_len = req_len;
2715 conn_info->req_ie =
2716 kmemdup(cfg_priv->extra_buf, conn_info->req_ie_len,
2717 GFP_KERNEL);
2718 } else {
2719 conn_info->req_ie_len = 0;
2720 conn_info->req_ie = NULL;
2722 if (resp_len) {
2723 err = brcmf_dev_bufvar_get(ndev, "assoc_resp_ies",
2724 cfg_priv->extra_buf,
2725 WL_ASSOC_INFO_MAX);
2726 if (unlikely(err)) {
2727 WL_ERR("could not get assoc resp (%d)\n", err);
2728 return err;
2730 conn_info->resp_ie_len = resp_len;
2731 conn_info->resp_ie =
2732 kmemdup(cfg_priv->extra_buf, conn_info->resp_ie_len,
2733 GFP_KERNEL);
2734 } else {
2735 conn_info->resp_ie_len = 0;
2736 conn_info->resp_ie = NULL;
2738 WL_CONN("req len (%d) resp len (%d)\n",
2739 conn_info->req_ie_len, conn_info->resp_ie_len);
2741 return err;
2744 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
2746 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2748 kfree(conn_info->req_ie);
2749 conn_info->req_ie = NULL;
2750 conn_info->req_ie_len = 0;
2751 kfree(conn_info->resp_ie);
2752 conn_info->resp_ie = NULL;
2753 conn_info->resp_ie_len = 0;
2757 static void brcmf_ch_to_chanspec(int ch, struct brcmf_join_params *join_params,
2758 size_t *join_params_size)
2760 u16 chanspec = 0;
2762 if (ch != 0) {
2763 join_params->params.chanspec_num = 1;
2764 join_params->params.chanspec_list[0] = ch;
2766 if (join_params->params.chanspec_list[0] <= CH_MAX_2G_CHANNEL)
2767 chanspec |= WL_CHANSPEC_BAND_2G;
2768 else
2769 chanspec |= WL_CHANSPEC_BAND_5G;
2771 chanspec |= WL_CHANSPEC_BW_20;
2772 chanspec |= WL_CHANSPEC_CTL_SB_NONE;
2774 *join_params_size += BRCMF_ASSOC_PARAMS_FIXED_SIZE +
2775 join_params->params.chanspec_num * sizeof(u16);
2777 join_params->params.chanspec_list[0] &= WL_CHANSPEC_CHAN_MASK;
2778 join_params->params.chanspec_list[0] |= chanspec;
2779 join_params->params.chanspec_list[0] =
2780 cpu_to_le16(join_params->params.chanspec_list[0]);
2782 join_params->params.chanspec_num =
2783 cpu_to_le32(join_params->params.chanspec_num);
2785 WL_CONN("join_params->params.chanspec_list[0]= %#X,"
2786 "channel %d, chanspec %#X\n",
2787 join_params->params.chanspec_list[0], ch, chanspec);
2791 static s32 brcmf_update_bss_info(struct brcmf_cfg80211_priv *cfg_priv)
2793 struct brcmf_bss_info *bi;
2794 struct brcmf_ssid *ssid;
2795 struct brcmu_tlv *tim;
2796 u16 beacon_interval;
2797 u8 dtim_period;
2798 size_t ie_len;
2799 u8 *ie;
2800 s32 err = 0;
2802 WL_TRACE("Enter\n");
2803 if (brcmf_is_ibssmode(cfg_priv))
2804 return err;
2806 ssid = (struct brcmf_ssid *)brcmf_read_prof(cfg_priv, WL_PROF_SSID);
2808 *(u32 *)cfg_priv->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
2809 err = brcmf_dev_ioctl(cfg_to_ndev(cfg_priv), BRCMF_C_GET_BSS_INFO,
2810 cfg_priv->extra_buf, WL_EXTRA_BUF_MAX);
2811 if (unlikely(err)) {
2812 WL_ERR("Could not get bss info %d\n", err);
2813 goto update_bss_info_out;
2816 bi = (struct brcmf_bss_info *)(cfg_priv->extra_buf + 4);
2817 err = brcmf_inform_single_bss(cfg_priv, bi);
2818 if (unlikely(err))
2819 goto update_bss_info_out;
2821 ie = ((u8 *)bi) + bi->ie_offset;
2822 ie_len = bi->ie_length;
2823 beacon_interval = cpu_to_le16(bi->beacon_period);
2825 tim = brcmu_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
2826 if (tim)
2827 dtim_period = tim->data[1];
2828 else {
2830 * active scan was done so we could not get dtim
2831 * information out of probe response.
2832 * so we speficially query dtim information to dongle.
2834 u32 var;
2835 err = brcmf_dev_intvar_get(cfg_to_ndev(cfg_priv),
2836 "dtim_assoc", &var);
2837 if (unlikely(err)) {
2838 WL_ERR("wl dtim_assoc failed (%d)\n", err);
2839 goto update_bss_info_out;
2841 dtim_period = (u8)var;
2844 brcmf_update_prof(cfg_priv, NULL, &beacon_interval, WL_PROF_BEACONINT);
2845 brcmf_update_prof(cfg_priv, NULL, &dtim_period, WL_PROF_DTIMPERIOD);
2847 update_bss_info_out:
2848 WL_TRACE("Exit");
2849 return err;
2852 static s32
2853 brcmf_bss_roaming_done(struct brcmf_cfg80211_priv *cfg_priv,
2854 struct net_device *ndev,
2855 const struct brcmf_event_msg *e)
2857 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2858 struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
2859 struct brcmf_channel_info channel;
2860 struct ieee80211_channel *notify_channel;
2861 struct ieee80211_supported_band *band;
2862 u32 freq;
2863 s32 err = 0;
2865 WL_TRACE("Enter\n");
2867 brcmf_get_assoc_ies(cfg_priv);
2868 brcmf_update_prof(cfg_priv, NULL, &e->addr, WL_PROF_BSSID);
2869 brcmf_update_bss_info(cfg_priv);
2871 brcmf_dev_ioctl(ndev, BRCMF_C_GET_CHANNEL, &channel, sizeof(channel));
2873 channel.target_channel = le32_to_cpu(channel.target_channel);
2874 WL_CONN("Roamed to channel %d\n", channel.target_channel);
2876 if (channel.target_channel <= CH_MAX_2G_CHANNEL)
2877 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2878 else
2879 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2881 freq = ieee80211_channel_to_frequency(channel.target_channel,
2882 band->band);
2883 notify_channel = ieee80211_get_channel(wiphy, freq);
2885 cfg80211_roamed(ndev, notify_channel,
2886 (u8 *)brcmf_read_prof(cfg_priv, WL_PROF_BSSID),
2887 conn_info->req_ie, conn_info->req_ie_len,
2888 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
2889 WL_CONN("Report roaming result\n");
2891 set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
2892 WL_TRACE("Exit\n");
2893 return err;
2896 static s32
2897 brcmf_bss_connect_done(struct brcmf_cfg80211_priv *cfg_priv,
2898 struct net_device *ndev, const struct brcmf_event_msg *e,
2899 bool completed)
2901 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2902 s32 err = 0;
2904 WL_TRACE("Enter\n");
2906 if (test_and_clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) {
2907 if (completed) {
2908 brcmf_get_assoc_ies(cfg_priv);
2909 brcmf_update_prof(cfg_priv, NULL, &e->addr,
2910 WL_PROF_BSSID);
2911 brcmf_update_bss_info(cfg_priv);
2913 cfg80211_connect_result(ndev,
2914 (u8 *)brcmf_read_prof(cfg_priv,
2915 WL_PROF_BSSID),
2916 conn_info->req_ie,
2917 conn_info->req_ie_len,
2918 conn_info->resp_ie,
2919 conn_info->resp_ie_len,
2920 completed ? WLAN_STATUS_SUCCESS :
2921 WLAN_STATUS_AUTH_TIMEOUT,
2922 GFP_KERNEL);
2923 if (completed)
2924 set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
2925 WL_CONN("Report connect result - connection %s\n",
2926 completed ? "succeeded" : "failed");
2928 WL_TRACE("Exit\n");
2929 return err;
2932 static s32
2933 brcmf_notify_mic_status(struct brcmf_cfg80211_priv *cfg_priv,
2934 struct net_device *ndev,
2935 const struct brcmf_event_msg *e, void *data)
2937 u16 flags = be16_to_cpu(e->flags);
2938 enum nl80211_key_type key_type;
2940 rtnl_lock();
2941 if (flags & BRCMF_EVENT_MSG_GROUP)
2942 key_type = NL80211_KEYTYPE_GROUP;
2943 else
2944 key_type = NL80211_KEYTYPE_PAIRWISE;
2946 cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1,
2947 NULL, GFP_KERNEL);
2948 rtnl_unlock();
2950 return 0;
2953 static s32
2954 brcmf_notify_scan_status(struct brcmf_cfg80211_priv *cfg_priv,
2955 struct net_device *ndev,
2956 const struct brcmf_event_msg *e, void *data)
2958 struct brcmf_channel_info channel_inform;
2959 struct brcmf_scan_results *bss_list;
2960 u32 len = WL_SCAN_BUF_MAX;
2961 s32 err = 0;
2962 bool scan_abort = false;
2964 WL_TRACE("Enter\n");
2966 if (cfg_priv->iscan_on && cfg_priv->iscan_kickstart) {
2967 WL_TRACE("Exit\n");
2968 return brcmf_wakeup_iscan(cfg_to_iscan(cfg_priv));
2971 if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING,
2972 &cfg_priv->status))) {
2973 WL_ERR("Scan complete while device not scanning\n");
2974 scan_abort = true;
2975 err = -EINVAL;
2976 goto scan_done_out;
2979 err = brcmf_dev_ioctl(ndev, BRCMF_C_GET_CHANNEL, &channel_inform,
2980 sizeof(channel_inform));
2981 if (unlikely(err)) {
2982 WL_ERR("scan busy (%d)\n", err);
2983 scan_abort = true;
2984 goto scan_done_out;
2986 channel_inform.scan_channel = le32_to_cpu(channel_inform.scan_channel);
2987 if (unlikely(channel_inform.scan_channel)) {
2989 WL_CONN("channel_inform.scan_channel (%d)\n",
2990 channel_inform.scan_channel);
2992 cfg_priv->bss_list = cfg_priv->scan_results;
2993 bss_list = cfg_priv->bss_list;
2994 memset(bss_list, 0, len);
2995 bss_list->buflen = cpu_to_le32(len);
2997 err = brcmf_dev_ioctl(ndev, BRCMF_C_SCAN_RESULTS, bss_list, len);
2998 if (unlikely(err)) {
2999 WL_ERR("%s Scan_results error (%d)\n", ndev->name, err);
3000 err = -EINVAL;
3001 scan_abort = true;
3002 goto scan_done_out;
3004 bss_list->buflen = le32_to_cpu(bss_list->buflen);
3005 bss_list->version = le32_to_cpu(bss_list->version);
3006 bss_list->count = le32_to_cpu(bss_list->count);
3008 err = brcmf_inform_bss(cfg_priv);
3009 if (err) {
3010 scan_abort = true;
3011 goto scan_done_out;
3014 scan_done_out:
3015 if (cfg_priv->scan_request) {
3016 WL_SCAN("calling cfg80211_scan_done\n");
3017 cfg80211_scan_done(cfg_priv->scan_request, scan_abort);
3018 brcmf_set_mpc(ndev, 1);
3019 cfg_priv->scan_request = NULL;
3022 WL_TRACE("Exit\n");
3024 return err;
3027 static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
3029 conf->mode = (u32)-1;
3030 conf->frag_threshold = (u32)-1;
3031 conf->rts_threshold = (u32)-1;
3032 conf->retry_short = (u32)-1;
3033 conf->retry_long = (u32)-1;
3034 conf->tx_power = -1;
3037 static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof)
3039 memset(prof, 0, sizeof(*prof));
3042 static void brcmf_init_eloop_handler(struct brcmf_cfg80211_event_loop *el)
3044 memset(el, 0, sizeof(*el));
3045 el->handler[BRCMF_E_SCAN_COMPLETE] = brcmf_notify_scan_status;
3046 el->handler[BRCMF_E_LINK] = brcmf_notify_connect_status;
3047 el->handler[BRCMF_E_ROAM] = brcmf_notify_roaming_status;
3048 el->handler[BRCMF_E_MIC_ERROR] = brcmf_notify_mic_status;
3049 el->handler[BRCMF_E_SET_SSID] = brcmf_notify_connect_status;
3052 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
3054 cfg_priv->scan_results = kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
3055 if (unlikely(!cfg_priv->scan_results)) {
3056 WL_ERR("Scan results alloc failed\n");
3057 goto init_priv_mem_out;
3059 cfg_priv->conf = kzalloc(sizeof(*cfg_priv->conf), GFP_KERNEL);
3060 if (unlikely(!cfg_priv->conf)) {
3061 WL_ERR("wl_conf alloc failed\n");
3062 goto init_priv_mem_out;
3064 cfg_priv->profile = kzalloc(sizeof(*cfg_priv->profile), GFP_KERNEL);
3065 if (unlikely(!cfg_priv->profile)) {
3066 WL_ERR("wl_profile alloc failed\n");
3067 goto init_priv_mem_out;
3069 cfg_priv->bss_info = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
3070 if (unlikely(!cfg_priv->bss_info)) {
3071 WL_ERR("Bss information alloc failed\n");
3072 goto init_priv_mem_out;
3074 cfg_priv->scan_req_int = kzalloc(sizeof(*cfg_priv->scan_req_int),
3075 GFP_KERNEL);
3076 if (unlikely(!cfg_priv->scan_req_int)) {
3077 WL_ERR("Scan req alloc failed\n");
3078 goto init_priv_mem_out;
3080 cfg_priv->ioctl_buf = kzalloc(WL_IOCTL_LEN_MAX, GFP_KERNEL);
3081 if (unlikely(!cfg_priv->ioctl_buf)) {
3082 WL_ERR("Ioctl buf alloc failed\n");
3083 goto init_priv_mem_out;
3085 cfg_priv->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
3086 if (unlikely(!cfg_priv->extra_buf)) {
3087 WL_ERR("Extra buf alloc failed\n");
3088 goto init_priv_mem_out;
3090 cfg_priv->iscan = kzalloc(sizeof(*cfg_priv->iscan), GFP_KERNEL);
3091 if (unlikely(!cfg_priv->iscan)) {
3092 WL_ERR("Iscan buf alloc failed\n");
3093 goto init_priv_mem_out;
3095 cfg_priv->pmk_list = kzalloc(sizeof(*cfg_priv->pmk_list), GFP_KERNEL);
3096 if (unlikely(!cfg_priv->pmk_list)) {
3097 WL_ERR("pmk list alloc failed\n");
3098 goto init_priv_mem_out;
3101 return 0;
3103 init_priv_mem_out:
3104 brcmf_deinit_priv_mem(cfg_priv);
3106 return -ENOMEM;
3109 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
3111 kfree(cfg_priv->scan_results);
3112 cfg_priv->scan_results = NULL;
3113 kfree(cfg_priv->bss_info);
3114 cfg_priv->bss_info = NULL;
3115 kfree(cfg_priv->conf);
3116 cfg_priv->conf = NULL;
3117 kfree(cfg_priv->profile);
3118 cfg_priv->profile = NULL;
3119 kfree(cfg_priv->scan_req_int);
3120 cfg_priv->scan_req_int = NULL;
3121 kfree(cfg_priv->ioctl_buf);
3122 cfg_priv->ioctl_buf = NULL;
3123 kfree(cfg_priv->extra_buf);
3124 cfg_priv->extra_buf = NULL;
3125 kfree(cfg_priv->iscan);
3126 cfg_priv->iscan = NULL;
3127 kfree(cfg_priv->pmk_list);
3128 cfg_priv->pmk_list = NULL;
3131 static s32 brcmf_create_event_handler(struct brcmf_cfg80211_priv *cfg_priv)
3133 init_waitqueue_head(&cfg_priv->event_waitq);
3134 cfg_priv->event_tsk = kthread_run(brcmf_event_handler, cfg_priv,
3135 "wl_event_handler");
3136 if (IS_ERR(cfg_priv->event_tsk)) {
3137 cfg_priv->event_tsk = NULL;
3138 WL_ERR("failed to create event thread\n");
3139 return -ENOMEM;
3141 return 0;
3144 static void brcmf_destroy_event_handler(struct brcmf_cfg80211_priv *cfg_priv)
3146 if (cfg_priv->event_tsk) {
3147 send_sig(SIGTERM, cfg_priv->event_tsk, 1);
3148 kthread_stop(cfg_priv->event_tsk);
3149 cfg_priv->event_tsk = NULL;
3153 static void brcmf_term_iscan(struct brcmf_cfg80211_priv *cfg_priv)
3155 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
3156 struct brcmf_ssid ssid;
3158 if (cfg_priv->iscan_on && iscan->tsk) {
3159 iscan->state = WL_ISCAN_STATE_IDLE;
3160 send_sig(SIGTERM, iscan->tsk, 1);
3163 * The iscan task may want to acquire the rtnl_lock
3164 * so release it here upon stopping the task.
3166 rtnl_unlock();
3167 kthread_stop(iscan->tsk);
3168 rtnl_lock();
3169 iscan->tsk = NULL;
3171 /* Abort iscan running in FW */
3172 memset(&ssid, 0, sizeof(ssid));
3173 brcmf_run_iscan(iscan, &ssid, WL_SCAN_ACTION_ABORT);
3177 static void brcmf_notify_iscan_complete(struct brcmf_cfg80211_iscan_ctrl *iscan,
3178 bool aborted)
3180 struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan);
3181 struct net_device *ndev = cfg_to_ndev(cfg_priv);
3183 if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING,
3184 &cfg_priv->status))) {
3185 WL_ERR("Scan complete while device not scanning\n");
3186 return;
3188 if (likely(cfg_priv->scan_request)) {
3189 WL_SCAN("ISCAN Completed scan: %s\n",
3190 aborted ? "Aborted" : "Done");
3191 cfg80211_scan_done(cfg_priv->scan_request, aborted);
3192 brcmf_set_mpc(ndev, 1);
3193 cfg_priv->scan_request = NULL;
3195 cfg_priv->iscan_kickstart = false;
3198 static s32 brcmf_wakeup_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan)
3200 if (likely(iscan->state != WL_ISCAN_STATE_IDLE)) {
3201 WL_SCAN("wake up iscan\n");
3202 wake_up(&iscan->waitq);
3203 return 0;
3206 return -EIO;
3209 static s32
3210 brcmf_get_iscan_results(struct brcmf_cfg80211_iscan_ctrl *iscan, u32 *status,
3211 struct brcmf_scan_results **bss_list)
3213 struct brcmf_iscan_results list;
3214 struct brcmf_scan_results *results;
3215 struct brcmf_iscan_results *list_buf;
3216 s32 err = 0;
3218 memset(iscan->scan_buf, 0, WL_ISCAN_BUF_MAX);
3219 list_buf = (struct brcmf_iscan_results *)iscan->scan_buf;
3220 results = &list_buf->results;
3221 results->buflen = BRCMF_ISCAN_RESULTS_FIXED_SIZE;
3222 results->version = 0;
3223 results->count = 0;
3225 memset(&list, 0, sizeof(list));
3226 list.results.buflen = cpu_to_le32(WL_ISCAN_BUF_MAX);
3227 err = brcmf_dev_iovar_getbuf(iscan->dev, "iscanresults", &list,
3228 BRCMF_ISCAN_RESULTS_FIXED_SIZE, iscan->scan_buf,
3229 WL_ISCAN_BUF_MAX);
3230 if (unlikely(err)) {
3231 WL_ERR("error (%d)\n", err);
3232 return err;
3234 results->buflen = le32_to_cpu(results->buflen);
3235 results->version = le32_to_cpu(results->version);
3236 results->count = le32_to_cpu(results->count);
3237 WL_SCAN("results->count = %d\n", results->count);
3238 WL_SCAN("results->buflen = %d\n", results->buflen);
3239 *status = le32_to_cpu(list_buf->status);
3240 WL_SCAN("status = %d\n", *status);
3241 *bss_list = results;
3243 return err;
3246 static s32 brcmf_iscan_done(struct brcmf_cfg80211_priv *cfg_priv)
3248 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
3249 s32 err = 0;
3251 iscan->state = WL_ISCAN_STATE_IDLE;
3252 rtnl_lock();
3253 brcmf_inform_bss(cfg_priv);
3254 brcmf_notify_iscan_complete(iscan, false);
3255 rtnl_unlock();
3257 return err;
3260 static s32 brcmf_iscan_pending(struct brcmf_cfg80211_priv *cfg_priv)
3262 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
3263 s32 err = 0;
3265 /* Reschedule the timer */
3266 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
3267 iscan->timer_on = 1;
3269 return err;
3272 static s32 brcmf_iscan_inprogress(struct brcmf_cfg80211_priv *cfg_priv)
3274 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
3275 s32 err = 0;
3277 rtnl_lock();
3278 brcmf_inform_bss(cfg_priv);
3279 brcmf_run_iscan(iscan, NULL, BRCMF_SCAN_ACTION_CONTINUE);
3280 rtnl_unlock();
3281 /* Reschedule the timer */
3282 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
3283 iscan->timer_on = 1;
3285 return err;
3288 static s32 brcmf_iscan_aborted(struct brcmf_cfg80211_priv *cfg_priv)
3290 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
3291 s32 err = 0;
3293 iscan->state = WL_ISCAN_STATE_IDLE;
3294 rtnl_lock();
3295 brcmf_notify_iscan_complete(iscan, true);
3296 rtnl_unlock();
3298 return err;
3301 static s32 brcmf_iscan_thread(void *data)
3303 struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1 };
3304 struct brcmf_cfg80211_iscan_ctrl *iscan =
3305 (struct brcmf_cfg80211_iscan_ctrl *)data;
3306 struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan);
3307 struct brcmf_cfg80211_iscan_eloop *el = &iscan->el;
3308 DECLARE_WAITQUEUE(wait, current);
3309 u32 status;
3310 int err = 0;
3312 sched_setscheduler(current, SCHED_FIFO, &param);
3313 allow_signal(SIGTERM);
3314 status = BRCMF_SCAN_RESULTS_PARTIAL;
3315 add_wait_queue(&iscan->waitq, &wait);
3316 while (1) {
3317 prepare_to_wait(&iscan->waitq, &wait, TASK_INTERRUPTIBLE);
3319 schedule();
3321 if (kthread_should_stop())
3322 break;
3323 if (iscan->timer_on) {
3324 del_timer_sync(&iscan->timer);
3325 iscan->timer_on = 0;
3327 rtnl_lock();
3328 err = brcmf_get_iscan_results(iscan, &status,
3329 &cfg_priv->bss_list);
3330 if (unlikely(err)) {
3331 status = BRCMF_SCAN_RESULTS_ABORTED;
3332 WL_ERR("Abort iscan\n");
3334 rtnl_unlock();
3335 el->handler[status](cfg_priv);
3337 finish_wait(&iscan->waitq, &wait);
3338 if (iscan->timer_on) {
3339 del_timer_sync(&iscan->timer);
3340 iscan->timer_on = 0;
3342 WL_SCAN("ISCAN thread terminated\n");
3344 return 0;
3347 static void brcmf_iscan_timer(unsigned long data)
3349 struct brcmf_cfg80211_iscan_ctrl *iscan =
3350 (struct brcmf_cfg80211_iscan_ctrl *)data;
3352 if (iscan) {
3353 iscan->timer_on = 0;
3354 WL_SCAN("timer expired\n");
3355 brcmf_wakeup_iscan(iscan);
3359 static s32 brcmf_invoke_iscan(struct brcmf_cfg80211_priv *cfg_priv)
3361 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
3363 if (cfg_priv->iscan_on && !iscan->tsk) {
3364 iscan->state = WL_ISCAN_STATE_IDLE;
3365 init_waitqueue_head(&iscan->waitq);
3366 iscan->tsk = kthread_run(brcmf_iscan_thread, iscan, "wl_iscan");
3367 if (IS_ERR(iscan->tsk)) {
3368 WL_ERR("Could not create iscan thread\n");
3369 iscan->tsk = NULL;
3370 return -ENOMEM;
3374 return 0;
3377 static void brcmf_init_iscan_eloop(struct brcmf_cfg80211_iscan_eloop *el)
3379 memset(el, 0, sizeof(*el));
3380 el->handler[BRCMF_SCAN_RESULTS_SUCCESS] = brcmf_iscan_done;
3381 el->handler[BRCMF_SCAN_RESULTS_PARTIAL] = brcmf_iscan_inprogress;
3382 el->handler[BRCMF_SCAN_RESULTS_PENDING] = brcmf_iscan_pending;
3383 el->handler[BRCMF_SCAN_RESULTS_ABORTED] = brcmf_iscan_aborted;
3384 el->handler[BRCMF_SCAN_RESULTS_NO_MEM] = brcmf_iscan_aborted;
3387 static s32 brcmf_init_iscan(struct brcmf_cfg80211_priv *cfg_priv)
3389 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
3390 int err = 0;
3392 if (cfg_priv->iscan_on) {
3393 iscan->dev = cfg_to_ndev(cfg_priv);
3394 brcmf_init_iscan_eloop(&iscan->el);
3395 iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS;
3396 init_timer(&iscan->timer);
3397 iscan->timer.data = (unsigned long) iscan;
3398 iscan->timer.function = brcmf_iscan_timer;
3399 err = brcmf_invoke_iscan(cfg_priv);
3400 if (!err)
3401 iscan->data = cfg_priv;
3404 return err;
3407 static s32 wl_init_priv(struct brcmf_cfg80211_priv *cfg_priv)
3409 s32 err = 0;
3411 cfg_priv->scan_request = NULL;
3412 #ifndef WL_POWERSAVE_DISABLED
3413 cfg_priv->pwr_save = true;
3414 #endif /* WL_POWERSAVE_DISABLED */
3415 cfg_priv->iscan_on = true; /* iscan on & off switch.
3416 we enable iscan per default */
3417 cfg_priv->roam_on = true; /* roam on & off switch.
3418 we enable roam per default */
3420 cfg_priv->iscan_kickstart = false;
3421 cfg_priv->active_scan = true; /* we do active scan for
3422 specific scan per default */
3423 cfg_priv->dongle_up = false; /* dongle is not up yet */
3424 brcmf_init_eq(cfg_priv);
3425 err = brcmf_init_priv_mem(cfg_priv);
3426 if (unlikely(err))
3427 return err;
3428 if (unlikely(brcmf_create_event_handler(cfg_priv)))
3429 return -ENOMEM;
3430 brcmf_init_eloop_handler(&cfg_priv->el);
3431 mutex_init(&cfg_priv->usr_sync);
3432 err = brcmf_init_iscan(cfg_priv);
3433 if (unlikely(err))
3434 return err;
3435 brcmf_init_conf(cfg_priv->conf);
3436 brcmf_init_prof(cfg_priv->profile);
3437 brcmf_link_down(cfg_priv);
3439 return err;
3442 static void wl_deinit_priv(struct brcmf_cfg80211_priv *cfg_priv)
3444 brcmf_destroy_event_handler(cfg_priv);
3445 cfg_priv->dongle_up = false; /* dongle down */
3446 brcmf_flush_eq(cfg_priv);
3447 brcmf_link_down(cfg_priv);
3448 brcmf_term_iscan(cfg_priv);
3449 brcmf_deinit_priv_mem(cfg_priv);
3452 s32 brcmf_cfg80211_attach(struct net_device *ndev, void *data)
3454 struct wireless_dev *wdev;
3455 struct brcmf_cfg80211_priv *cfg_priv;
3456 struct brcmf_cfg80211_iface *ci;
3457 s32 err = 0;
3459 if (unlikely(!ndev)) {
3460 WL_ERR("ndev is invalid\n");
3461 return -ENODEV;
3463 cfg80211_dev = kzalloc(sizeof(struct brcmf_cfg80211_dev), GFP_KERNEL);
3464 if (unlikely(!cfg80211_dev)) {
3465 WL_ERR("wl_cfg80211_dev is invalid\n");
3466 return -ENOMEM;
3468 WL_INFO("func %p\n", brcmf_cfg80211_get_sdio_func());
3469 wdev = brcmf_alloc_wdev(sizeof(struct brcmf_cfg80211_iface),
3470 &brcmf_cfg80211_get_sdio_func()->dev);
3471 if (IS_ERR(wdev))
3472 return -ENOMEM;
3474 wdev->iftype = brcmf_mode_to_nl80211_iftype(WL_MODE_BSS);
3475 cfg_priv = wdev_to_cfg(wdev);
3476 cfg_priv->wdev = wdev;
3477 cfg_priv->pub = data;
3478 ci = (struct brcmf_cfg80211_iface *)&cfg_priv->ci;
3479 ci->cfg_priv = cfg_priv;
3480 ndev->ieee80211_ptr = wdev;
3481 SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
3482 wdev->netdev = ndev;
3483 err = wl_init_priv(cfg_priv);
3484 if (unlikely(err)) {
3485 WL_ERR("Failed to init iwm_priv (%d)\n", err);
3486 goto cfg80211_attach_out;
3488 brcmf_set_drvdata(cfg80211_dev, ci);
3490 return err;
3492 cfg80211_attach_out:
3493 brcmf_free_wdev(cfg_priv);
3494 return err;
3497 void brcmf_cfg80211_detach(void)
3499 struct brcmf_cfg80211_priv *cfg_priv;
3501 cfg_priv = WL_PRIV_GET();
3503 wl_deinit_priv(cfg_priv);
3504 brcmf_free_wdev(cfg_priv);
3505 brcmf_set_drvdata(cfg80211_dev, NULL);
3506 kfree(cfg80211_dev);
3507 cfg80211_dev = NULL;
3508 brcmf_clear_sdio_func();
3511 static void brcmf_wakeup_event(struct brcmf_cfg80211_priv *cfg_priv)
3513 wake_up(&cfg_priv->event_waitq);
3516 static s32 brcmf_event_handler(void *data)
3518 struct brcmf_cfg80211_priv *cfg_priv =
3519 (struct brcmf_cfg80211_priv *)data;
3520 struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1 };
3521 struct brcmf_cfg80211_event_q *e;
3522 DECLARE_WAITQUEUE(wait, current);
3524 sched_setscheduler(current, SCHED_FIFO, &param);
3525 allow_signal(SIGTERM);
3526 add_wait_queue(&cfg_priv->event_waitq, &wait);
3527 while (1) {
3528 prepare_to_wait(&cfg_priv->event_waitq, &wait,
3529 TASK_INTERRUPTIBLE);
3531 schedule();
3533 if (kthread_should_stop())
3534 break;
3536 e = brcmf_deq_event(cfg_priv);
3537 if (unlikely(!e)) {
3538 WL_ERR("event queue empty...\n");
3539 continue;
3542 do {
3543 WL_INFO("event type (%d)\n", e->etype);
3544 if (cfg_priv->el.handler[e->etype])
3545 cfg_priv->el.handler[e->etype](cfg_priv,
3546 cfg_to_ndev(cfg_priv),
3547 &e->emsg, e->edata);
3548 else
3549 WL_INFO("Unknown Event (%d): ignoring\n",
3550 e->etype);
3551 brcmf_put_event(e);
3552 } while ((e = brcmf_deq_event(cfg_priv)));
3554 finish_wait(&cfg_priv->event_waitq, &wait);
3555 WL_INFO("was terminated\n");
3556 return 0;
3559 void
3560 brcmf_cfg80211_event(struct net_device *ndev,
3561 const struct brcmf_event_msg *e, void *data)
3563 u32 event_type = be32_to_cpu(e->event_type);
3564 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
3566 if (likely(!brcmf_enq_event(cfg_priv, event_type, e)))
3567 brcmf_wakeup_event(cfg_priv);
3570 static void brcmf_init_eq(struct brcmf_cfg80211_priv *cfg_priv)
3572 brcmf_init_eq_lock(cfg_priv);
3573 INIT_LIST_HEAD(&cfg_priv->eq_list);
3576 static void brcmf_flush_eq(struct brcmf_cfg80211_priv *cfg_priv)
3578 struct brcmf_cfg80211_event_q *e;
3580 brcmf_lock_eq(cfg_priv);
3581 while (!list_empty(&cfg_priv->eq_list)) {
3582 e = list_first_entry(&cfg_priv->eq_list,
3583 struct brcmf_cfg80211_event_q, eq_list);
3584 list_del(&e->eq_list);
3585 kfree(e);
3587 brcmf_unlock_eq(cfg_priv);
3591 * retrieve first queued event from head
3594 static struct brcmf_cfg80211_event_q *brcmf_deq_event(
3595 struct brcmf_cfg80211_priv *cfg_priv)
3597 struct brcmf_cfg80211_event_q *e = NULL;
3599 brcmf_lock_eq(cfg_priv);
3600 if (likely(!list_empty(&cfg_priv->eq_list))) {
3601 e = list_first_entry(&cfg_priv->eq_list,
3602 struct brcmf_cfg80211_event_q, eq_list);
3603 list_del(&e->eq_list);
3605 brcmf_unlock_eq(cfg_priv);
3607 return e;
3611 ** push event to tail of the queue
3614 static s32
3615 brcmf_enq_event(struct brcmf_cfg80211_priv *cfg_priv, u32 event,
3616 const struct brcmf_event_msg *msg)
3618 struct brcmf_cfg80211_event_q *e;
3619 s32 err = 0;
3621 e = kzalloc(sizeof(struct brcmf_cfg80211_event_q), GFP_KERNEL);
3622 if (unlikely(!e)) {
3623 WL_ERR("event alloc failed\n");
3624 return -ENOMEM;
3627 e->etype = event;
3628 memcpy(&e->emsg, msg, sizeof(struct brcmf_event_msg));
3630 brcmf_lock_eq(cfg_priv);
3631 list_add_tail(&e->eq_list, &cfg_priv->eq_list);
3632 brcmf_unlock_eq(cfg_priv);
3634 return err;
3637 static void brcmf_put_event(struct brcmf_cfg80211_event_q *e)
3639 kfree(e);
3642 void brcmf_cfg80211_sdio_func(void *func)
3644 cfg80211_sdio_func = (struct sdio_func *)func;
3647 static void brcmf_clear_sdio_func(void)
3649 cfg80211_sdio_func = NULL;
3652 struct sdio_func *brcmf_cfg80211_get_sdio_func(void)
3654 return cfg80211_sdio_func;
3657 static s32 brcmf_dongle_mode(struct net_device *ndev, s32 iftype)
3659 s32 infra = 0;
3660 s32 err = 0;
3662 switch (iftype) {
3663 case NL80211_IFTYPE_MONITOR:
3664 case NL80211_IFTYPE_WDS:
3665 WL_ERR("type (%d) : currently we do not support this mode\n",
3666 iftype);
3667 err = -EINVAL;
3668 return err;
3669 case NL80211_IFTYPE_ADHOC:
3670 infra = 0;
3671 break;
3672 case NL80211_IFTYPE_STATION:
3673 infra = 1;
3674 break;
3675 default:
3676 err = -EINVAL;
3677 WL_ERR("invalid type (%d)\n", iftype);
3678 return err;
3680 infra = cpu_to_le32(infra);
3681 err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_INFRA, &infra, sizeof(infra));
3682 if (unlikely(err)) {
3683 WL_ERR("WLC_SET_INFRA error (%d)\n", err);
3684 return err;
3687 return 0;
3690 static s32 brcmf_dongle_eventmsg(struct net_device *ndev)
3692 /* Room for "event_msgs" + '\0' + bitvec */
3693 s8 iovbuf[BRCMF_EVENTING_MASK_LEN + 12];
3694 s8 eventmask[BRCMF_EVENTING_MASK_LEN];
3695 s32 err = 0;
3697 WL_TRACE("Enter\n");
3699 /* Setup event_msgs */
3700 brcmu_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN, iovbuf,
3701 sizeof(iovbuf));
3702 err = brcmf_dev_ioctl(ndev, BRCMF_C_GET_VAR, iovbuf, sizeof(iovbuf));
3703 if (unlikely(err)) {
3704 WL_ERR("Get event_msgs error (%d)\n", err);
3705 goto dongle_eventmsg_out;
3707 memcpy(eventmask, iovbuf, BRCMF_EVENTING_MASK_LEN);
3709 setbit(eventmask, BRCMF_E_SET_SSID);
3710 setbit(eventmask, BRCMF_E_ROAM);
3711 setbit(eventmask, BRCMF_E_PRUNE);
3712 setbit(eventmask, BRCMF_E_AUTH);
3713 setbit(eventmask, BRCMF_E_REASSOC);
3714 setbit(eventmask, BRCMF_E_REASSOC_IND);
3715 setbit(eventmask, BRCMF_E_DEAUTH_IND);
3716 setbit(eventmask, BRCMF_E_DISASSOC_IND);
3717 setbit(eventmask, BRCMF_E_DISASSOC);
3718 setbit(eventmask, BRCMF_E_JOIN);
3719 setbit(eventmask, BRCMF_E_ASSOC_IND);
3720 setbit(eventmask, BRCMF_E_PSK_SUP);
3721 setbit(eventmask, BRCMF_E_LINK);
3722 setbit(eventmask, BRCMF_E_NDIS_LINK);
3723 setbit(eventmask, BRCMF_E_MIC_ERROR);
3724 setbit(eventmask, BRCMF_E_PMKID_CACHE);
3725 setbit(eventmask, BRCMF_E_TXFAIL);
3726 setbit(eventmask, BRCMF_E_JOIN_START);
3727 setbit(eventmask, BRCMF_E_SCAN_COMPLETE);
3729 brcmu_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN, iovbuf,
3730 sizeof(iovbuf));
3731 err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
3732 if (unlikely(err)) {
3733 WL_ERR("Set event_msgs error (%d)\n", err);
3734 goto dongle_eventmsg_out;
3737 dongle_eventmsg_out:
3738 WL_TRACE("Exit\n");
3739 return err;
3742 static s32
3743 brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
3745 s8 iovbuf[32];
3746 s32 roamtrigger[2];
3747 s32 roam_delta[2];
3748 s32 err = 0;
3751 * Setup timeout if Beacons are lost and roam is
3752 * off to report link down
3754 if (roamvar) {
3755 brcmu_mkiovar("bcn_timeout", (char *)&bcn_timeout,
3756 sizeof(bcn_timeout), iovbuf, sizeof(iovbuf));
3757 err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_VAR,
3758 iovbuf, sizeof(iovbuf));
3759 if (unlikely(err)) {
3760 WL_ERR("bcn_timeout error (%d)\n", err);
3761 goto dongle_rom_out;
3766 * Enable/Disable built-in roaming to allow supplicant
3767 * to take care of roaming
3769 WL_INFO("Internal Roaming = %s\n", roamvar ? "Off" : "On");
3770 brcmu_mkiovar("roam_off", (char *)&roamvar,
3771 sizeof(roamvar), iovbuf, sizeof(iovbuf));
3772 err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
3773 if (unlikely(err)) {
3774 WL_ERR("roam_off error (%d)\n", err);
3775 goto dongle_rom_out;
3778 roamtrigger[0] = WL_ROAM_TRIGGER_LEVEL;
3779 roamtrigger[1] = BRCM_BAND_ALL;
3780 err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_ROAM_TRIGGER,
3781 (void *)roamtrigger, sizeof(roamtrigger));
3782 if (unlikely(err)) {
3783 WL_ERR("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
3784 goto dongle_rom_out;
3787 roam_delta[0] = WL_ROAM_DELTA;
3788 roam_delta[1] = BRCM_BAND_ALL;
3789 err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_ROAM_DELTA,
3790 (void *)roam_delta, sizeof(roam_delta));
3791 if (unlikely(err)) {
3792 WL_ERR("WLC_SET_ROAM_DELTA error (%d)\n", err);
3793 goto dongle_rom_out;
3796 dongle_rom_out:
3797 return err;
3800 static s32
3801 brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
3802 s32 scan_unassoc_time, s32 scan_passive_time)
3804 s32 err = 0;
3806 err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_SCAN_CHANNEL_TIME,
3807 &scan_assoc_time, sizeof(scan_assoc_time));
3808 if (err) {
3809 if (err == -EOPNOTSUPP)
3810 WL_INFO("Scan assoc time is not supported\n");
3811 else
3812 WL_ERR("Scan assoc time error (%d)\n", err);
3813 goto dongle_scantime_out;
3815 err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_SCAN_UNASSOC_TIME,
3816 &scan_unassoc_time, sizeof(scan_unassoc_time));
3817 if (err) {
3818 if (err == -EOPNOTSUPP)
3819 WL_INFO("Scan unassoc time is not supported\n");
3820 else
3821 WL_ERR("Scan unassoc time error (%d)\n", err);
3822 goto dongle_scantime_out;
3825 err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_SCAN_PASSIVE_TIME,
3826 &scan_passive_time, sizeof(scan_passive_time));
3827 if (err) {
3828 if (err == -EOPNOTSUPP)
3829 WL_INFO("Scan passive time is not supported\n");
3830 else
3831 WL_ERR("Scan passive time error (%d)\n", err);
3832 goto dongle_scantime_out;
3835 dongle_scantime_out:
3836 return err;
3839 s32 brcmf_config_dongle(struct brcmf_cfg80211_priv *cfg_priv, bool need_lock)
3841 struct net_device *ndev;
3842 struct wireless_dev *wdev;
3843 s32 power_mode;
3844 s32 err = 0;
3846 if (cfg_priv->dongle_up)
3847 return err;
3849 ndev = cfg_to_ndev(cfg_priv);
3850 wdev = ndev->ieee80211_ptr;
3851 if (need_lock)
3852 rtnl_lock();
3854 brcmf_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME,
3855 WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
3857 err = brcmf_dongle_eventmsg(ndev);
3858 if (unlikely(err))
3859 goto default_conf_out;
3861 power_mode = cfg_priv->pwr_save ? PM_FAST : PM_OFF;
3862 power_mode = cpu_to_le32(power_mode);
3863 err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_PM,
3864 &power_mode, sizeof(power_mode));
3865 if (err)
3866 goto default_conf_out;
3867 WL_INFO("power save set to %s\n",
3868 (power_mode ? "enabled" : "disabled"));
3870 err = brcmf_dongle_roam(ndev, (cfg_priv->roam_on ? 0 : 1),
3871 WL_BEACON_TIMEOUT);
3872 if (unlikely(err))
3873 goto default_conf_out;
3874 err = brcmf_dongle_mode(ndev, wdev->iftype);
3875 if (unlikely(err && err != -EINPROGRESS))
3876 goto default_conf_out;
3877 err = brcmf_dongle_probecap(cfg_priv);
3878 if (unlikely(err))
3879 goto default_conf_out;
3881 /* -EINPROGRESS: Call commit handler */
3883 default_conf_out:
3884 if (need_lock)
3885 rtnl_unlock();
3887 cfg_priv->dongle_up = true;
3889 return err;
3893 static s32 wl_update_wiphybands(struct brcmf_cfg80211_priv *cfg_priv)
3895 struct wiphy *wiphy;
3896 s32 phy_list;
3897 s8 phy;
3898 s32 err = 0;
3900 err = brcmf_dev_ioctl(cfg_to_ndev(cfg_priv), BRCM_GET_PHYLIST,
3901 &phy_list, sizeof(phy_list));
3902 if (unlikely(err)) {
3903 WL_ERR("error (%d)\n", err);
3904 return err;
3907 phy = ((char *)&phy_list)[1];
3908 WL_INFO("%c phy\n", phy);
3909 if (phy == 'n' || phy == 'a') {
3910 wiphy = cfg_to_wiphy(cfg_priv);
3911 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
3914 return err;
3917 static s32 __brcmf_cfg80211_up(struct brcmf_cfg80211_priv *cfg_priv)
3919 s32 err = 0;
3921 set_bit(WL_STATUS_READY, &cfg_priv->status);
3923 brcmf_debugfs_add_netdev_params(cfg_priv);
3925 err = brcmf_config_dongle(cfg_priv, false);
3926 if (unlikely(err))
3927 return err;
3929 brcmf_invoke_iscan(cfg_priv);
3931 return err;
3934 static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_priv *cfg_priv)
3937 * While going down, if associated with AP disassociate
3938 * from AP to save power
3940 if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) ||
3941 test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) &&
3942 test_bit(WL_STATUS_READY, &cfg_priv->status)) {
3943 WL_INFO("Disassociating from AP");
3944 brcmf_link_down(cfg_priv);
3946 /* Make sure WPA_Supplicant receives all the event
3947 generated due to DISASSOC call to the fw to keep
3948 the state fw and WPA_Supplicant state consistent
3950 rtnl_unlock();
3951 brcmf_delay(500);
3952 rtnl_lock();
3955 set_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
3956 brcmf_term_iscan(cfg_priv);
3957 if (cfg_priv->scan_request) {
3958 cfg80211_scan_done(cfg_priv->scan_request, true);
3959 /* May need to perform this to cover rmmod */
3960 /* wl_set_mpc(cfg_to_ndev(wl), 1); */
3961 cfg_priv->scan_request = NULL;
3963 clear_bit(WL_STATUS_READY, &cfg_priv->status);
3964 clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
3965 clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
3967 brcmf_debugfs_remove_netdev(cfg_priv);
3969 return 0;
3972 s32 brcmf_cfg80211_up(void)
3974 struct brcmf_cfg80211_priv *cfg_priv;
3975 s32 err = 0;
3977 cfg_priv = WL_PRIV_GET();
3978 mutex_lock(&cfg_priv->usr_sync);
3979 err = __brcmf_cfg80211_up(cfg_priv);
3980 mutex_unlock(&cfg_priv->usr_sync);
3982 return err;
3985 s32 brcmf_cfg80211_down(void)
3987 struct brcmf_cfg80211_priv *cfg_priv;
3988 s32 err = 0;
3990 cfg_priv = WL_PRIV_GET();
3991 mutex_lock(&cfg_priv->usr_sync);
3992 err = __brcmf_cfg80211_down(cfg_priv);
3993 mutex_unlock(&cfg_priv->usr_sync);
3995 return err;
3998 static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_priv *cfg_priv)
4000 return wl_update_wiphybands(cfg_priv);
4003 static void *brcmf_read_prof(struct brcmf_cfg80211_priv *cfg_priv, s32 item)
4005 switch (item) {
4006 case WL_PROF_SEC:
4007 return &cfg_priv->profile->sec;
4008 case WL_PROF_BSSID:
4009 return &cfg_priv->profile->bssid;
4010 case WL_PROF_SSID:
4011 return &cfg_priv->profile->ssid;
4013 WL_ERR("invalid item (%d)\n", item);
4014 return NULL;
4017 static s32
4018 brcmf_update_prof(struct brcmf_cfg80211_priv *cfg_priv,
4019 const struct brcmf_event_msg *e, void *data, s32 item)
4021 s32 err = 0;
4022 struct brcmf_ssid *ssid;
4024 switch (item) {
4025 case WL_PROF_SSID:
4026 ssid = (struct brcmf_ssid *) data;
4027 memset(cfg_priv->profile->ssid.SSID, 0,
4028 sizeof(cfg_priv->profile->ssid.SSID));
4029 memcpy(cfg_priv->profile->ssid.SSID,
4030 ssid->SSID, ssid->SSID_len);
4031 cfg_priv->profile->ssid.SSID_len = ssid->SSID_len;
4032 break;
4033 case WL_PROF_BSSID:
4034 if (data)
4035 memcpy(cfg_priv->profile->bssid, data, ETH_ALEN);
4036 else
4037 memset(cfg_priv->profile->bssid, 0, ETH_ALEN);
4038 break;
4039 case WL_PROF_SEC:
4040 memcpy(&cfg_priv->profile->sec, data,
4041 sizeof(cfg_priv->profile->sec));
4042 break;
4043 case WL_PROF_BEACONINT:
4044 cfg_priv->profile->beacon_interval = *(u16 *)data;
4045 break;
4046 case WL_PROF_DTIMPERIOD:
4047 cfg_priv->profile->dtim_period = *(u8 *)data;
4048 break;
4049 default:
4050 WL_ERR("unsupported item (%d)\n", item);
4051 err = -EOPNOTSUPP;
4052 break;
4055 return err;
4058 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_priv *cfg_priv)
4060 return cfg_priv->conf->mode == WL_MODE_IBSS;
4063 static __used s32 brcmf_add_ie(struct brcmf_cfg80211_priv *cfg_priv,
4064 u8 t, u8 l, u8 *v)
4066 struct brcmf_cfg80211_ie *ie = &cfg_priv->ie;
4067 s32 err = 0;
4069 if (unlikely(ie->offset + l + 2 > WL_TLV_INFO_MAX)) {
4070 WL_ERR("ei crosses buffer boundary\n");
4071 return -ENOSPC;
4073 ie->buf[ie->offset] = t;
4074 ie->buf[ie->offset + 1] = l;
4075 memcpy(&ie->buf[ie->offset + 2], v, l);
4076 ie->offset += l + 2;
4078 return err;
4081 static void brcmf_link_down(struct brcmf_cfg80211_priv *cfg_priv)
4083 struct net_device *dev = NULL;
4084 s32 err = 0;
4086 WL_TRACE("Enter\n");
4088 if (cfg_priv->link_up) {
4089 dev = cfg_to_ndev(cfg_priv);
4090 WL_INFO("Call WLC_DISASSOC to stop excess roaming\n ");
4091 err = brcmf_dev_ioctl(dev, BRCMF_C_DISASSOC, NULL, 0);
4092 if (unlikely(err))
4093 WL_ERR("WLC_DISASSOC failed (%d)\n", err);
4094 cfg_priv->link_up = false;
4096 WL_TRACE("Exit\n");
4099 static void brcmf_lock_eq(struct brcmf_cfg80211_priv *cfg_priv)
4101 spin_lock_irq(&cfg_priv->eq_lock);
4104 static void brcmf_unlock_eq(struct brcmf_cfg80211_priv *cfg_priv)
4106 spin_unlock_irq(&cfg_priv->eq_lock);
4109 static void brcmf_init_eq_lock(struct brcmf_cfg80211_priv *cfg_priv)
4111 spin_lock_init(&cfg_priv->eq_lock);
4114 static void brcmf_delay(u32 ms)
4116 if (ms < 1000 / HZ) {
4117 cond_resched();
4118 mdelay(ms);
4119 } else {
4120 msleep(ms);
4124 static void brcmf_set_drvdata(struct brcmf_cfg80211_dev *dev, void *data)
4126 dev->driver_data = data;
4129 static void *brcmf_get_drvdata(struct brcmf_cfg80211_dev *dev)
4131 void *data = NULL;
4133 if (dev)
4134 data = dev->driver_data;
4135 return data;
4138 static void brcmf_set_mpc(struct net_device *ndev, int mpc)
4140 s32 err = 0;
4141 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
4143 if (test_bit(WL_STATUS_READY, &cfg_priv->status)) {
4144 err = brcmf_dev_intvar_set(ndev, "mpc", mpc);
4145 if (unlikely(err)) {
4146 WL_ERR("fail to set mpc\n");
4147 return;
4149 WL_INFO("MPC : %d\n", mpc);
4153 static int brcmf_debugfs_add_netdev_params(struct brcmf_cfg80211_priv *cfg_priv)
4155 char buf[10+IFNAMSIZ];
4156 struct dentry *fd;
4157 s32 err = 0;
4159 sprintf(buf, "netdev:%s", cfg_to_ndev(cfg_priv)->name);
4160 cfg_priv->debugfsdir = debugfs_create_dir(buf,
4161 cfg_to_wiphy(cfg_priv)->debugfsdir);
4163 fd = debugfs_create_u16("beacon_int", S_IRUGO, cfg_priv->debugfsdir,
4164 (u16 *)&cfg_priv->profile->beacon_interval);
4165 if (!fd) {
4166 err = -ENOMEM;
4167 goto err_out;
4170 fd = debugfs_create_u8("dtim_period", S_IRUGO, cfg_priv->debugfsdir,
4171 (u8 *)&cfg_priv->profile->dtim_period);
4172 if (!fd) {
4173 err = -ENOMEM;
4174 goto err_out;
4177 err_out:
4178 return err;
4181 static void brcmf_debugfs_remove_netdev(struct brcmf_cfg80211_priv *cfg_priv)
4183 debugfs_remove_recursive(cfg_priv->debugfsdir);
4184 cfg_priv->debugfsdir = NULL;