staging: brcm80211: remove checkpatch warnings 'suspect code indent'
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / staging / brcm80211 / brcmfmac / wl_cfg80211.c
blob12c6ee35456e242f4203d9f175acb0c82c664e6b
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/etherdevice.h>
24 #include <linux/wireless.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 "dngl_stats.h"
35 #include "dhd.h"
36 #include "wl_cfg80211.h"
38 static struct sdio_func *cfg80211_sdio_func;
39 static struct brcmf_cfg80211_dev *cfg80211_dev;
40 static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255};
42 u32 brcmf_dbg_level = WL_DBG_ERR;
45 ** cfg80211_ops api/callback list
47 static s32 brcmf_cfg80211_change_iface(struct wiphy *wiphy,
48 struct net_device *ndev,
49 enum nl80211_iftype type, u32 *flags,
50 struct vif_params *params);
51 static s32 __brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
52 struct cfg80211_scan_request *request,
53 struct cfg80211_ssid *this_ssid);
54 static s32 brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
55 struct cfg80211_scan_request *request);
56 static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed);
57 static s32 brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
58 struct cfg80211_ibss_params *params);
59 static s32 brcmf_cfg80211_leave_ibss(struct wiphy *wiphy,
60 struct net_device *dev);
61 static s32 brcmf_cfg80211_get_station(struct wiphy *wiphy,
62 struct net_device *dev, u8 *mac,
63 struct station_info *sinfo);
64 static s32 brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy,
65 struct net_device *dev, bool enabled,
66 s32 timeout);
67 static s32 brcmf_cfg80211_set_bitrate_mask(struct wiphy *wiphy,
68 struct net_device *dev,
69 const u8 *addr,
70 const struct cfg80211_bitrate_mask
71 *mask);
72 static int brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
73 struct cfg80211_connect_params *sme);
74 static s32 brcmf_cfg80211_disconnect(struct wiphy *wiphy,
75 struct net_device *dev,
76 u16 reason_code);
77 static s32 brcmf_cfg80211_set_tx_power(struct wiphy *wiphy,
78 enum nl80211_tx_power_setting type,
79 s32 dbm);
80 static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm);
81 static s32 brcmf_cfg80211_config_default_key(struct wiphy *wiphy,
82 struct net_device *dev, u8 key_idx,
83 bool unicast, bool multicast);
84 static s32 brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
85 u8 key_idx, bool pairwise, const u8 *mac_addr,
86 struct key_params *params);
87 static s32 brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
88 u8 key_idx, bool pairwise, const u8 *mac_addr);
89 static s32 brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
90 u8 key_idx, bool pairwise, const u8 *mac_addr,
91 void *cookie, void (*callback) (void *cookie,
92 struct
93 key_params *
94 params));
95 static s32 brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
96 struct net_device *dev,
97 u8 key_idx);
98 static s32 brcmf_cfg80211_resume(struct wiphy *wiphy);
99 static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
100 struct cfg80211_wowlan *wow);
101 static s32 brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
102 struct cfg80211_pmksa *pmksa);
103 static s32 brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
104 struct cfg80211_pmksa *pmksa);
105 static s32 brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy,
106 struct net_device *dev);
108 ** event & event Q handlers for cfg80211 interfaces
110 static s32 brcmf_create_event_handler(struct brcmf_cfg80211_priv *cfg_priv);
111 static void brcmf_destroy_event_handler(struct brcmf_cfg80211_priv *cfg_priv);
112 static s32 brcmf_event_handler(void *data);
113 static void brcmf_init_eq(struct brcmf_cfg80211_priv *cfg_priv);
114 static void brcmf_flush_eq(struct brcmf_cfg80211_priv *cfg_priv);
115 static void brcmf_lock_eq(struct brcmf_cfg80211_priv *cfg_priv);
116 static void brcmf_unlock_eq(struct brcmf_cfg80211_priv *cfg_priv);
117 static void brcmf_init_eq_lock(struct brcmf_cfg80211_priv *cfg_priv);
118 static void brcmf_init_eloop_handler(struct brcmf_cfg80211_event_loop *el);
119 static struct brcmf_cfg80211_event_q *
120 brcmf_deq_event(struct brcmf_cfg80211_priv *cfg_priv);
121 static s32 brcmf_enq_event(struct brcmf_cfg80211_priv *cfg_priv, u32 type,
122 const struct brcmf_event_msg *msg, void *data);
123 static void brcmf_put_event(struct brcmf_cfg80211_event_q *e);
124 static void brcmf_wakeup_event(struct brcmf_cfg80211_priv *cfg_priv);
125 static s32 brcmf_notify_connect_status(struct brcmf_cfg80211_priv *cfg_priv,
126 struct net_device *ndev,
127 const struct brcmf_event_msg *e,
128 void *data);
129 static s32 brcmf_notify_roaming_status(struct brcmf_cfg80211_priv *cfg_priv,
130 struct net_device *ndev,
131 const struct brcmf_event_msg *e,
132 void *data);
133 static s32 brcmf_notify_scan_status(struct brcmf_cfg80211_priv *cfg_priv,
134 struct net_device *ndev,
135 const struct brcmf_event_msg *e,
136 void *data);
137 static s32 brcmf_bss_connect_done(struct brcmf_cfg80211_priv *cfg_priv,
138 struct net_device *ndev,
139 const struct brcmf_event_msg *e, void *data,
140 bool completed);
141 static s32 brcmf_bss_roaming_done(struct brcmf_cfg80211_priv *cfg_priv,
142 struct net_device *ndev,
143 const struct brcmf_event_msg *e, void *data);
144 static s32 brcmf_notify_mic_status(struct brcmf_cfg80211_priv *cfg_priv,
145 struct net_device *ndev,
146 const struct brcmf_event_msg *e, void *data);
149 ** register/deregister sdio function
151 static void brcmf_clear_sdio_func(void);
154 ** ioctl utilites
156 static s32 brcmf_dev_bufvar_get(struct net_device *dev, s8 *name, s8 *buf,
157 s32 buf_len);
158 static __used s32 brcmf_dev_bufvar_set(struct net_device *dev, s8 *name,
159 s8 *buf, s32 len);
160 static s32 brcmf_dev_intvar_set(struct net_device *dev, s8 *name, s32 val);
161 static s32 brcmf_dev_intvar_get(struct net_device *dev, s8 *name,
162 s32 *retval);
163 static s32 brcmf_dev_ioctl(struct net_device *dev, u32 cmd, void *arg,
164 u32 len);
167 ** cfg80211 set_wiphy_params utilities
169 static s32 brcmf_set_frag(struct net_device *dev, u32 frag_threshold);
170 static s32 brcmf_set_rts(struct net_device *dev, u32 frag_threshold);
171 static s32 brcmf_set_retry(struct net_device *dev, u32 retry, bool l);
174 ** wl profile utilities
176 static s32 brcmf_update_prof(struct brcmf_cfg80211_priv *cfg_priv,
177 const struct brcmf_event_msg *e,
178 void *data, s32 item);
179 static void *brcmf_read_prof(struct brcmf_cfg80211_priv *cfg_priv, s32 item);
180 static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof);
183 ** cfg80211 connect utilites
185 static s32 brcmf_set_wpa_version(struct net_device *dev,
186 struct cfg80211_connect_params *sme);
187 static s32 brcmf_set_auth_type(struct net_device *dev,
188 struct cfg80211_connect_params *sme);
189 static s32 brcmf_set_set_cipher(struct net_device *dev,
190 struct cfg80211_connect_params *sme);
191 static s32 brcmf_set_key_mgmt(struct net_device *dev,
192 struct cfg80211_connect_params *sme);
193 static s32 brcmf_set_set_sharedkey(struct net_device *dev,
194 struct cfg80211_connect_params *sme);
195 static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv);
196 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv);
197 static void brcmf_ch_to_chanspec(int ch,
198 struct brcmf_join_params *join_params, size_t *join_params_size);
201 ** information element utilities
203 static __used s32 brcmf_add_ie(struct brcmf_cfg80211_priv *cfg_priv,
204 u8 t, u8 l, u8 *v);
205 static s32 brcmf_mode_to_nl80211_iftype(s32 mode);
206 static struct wireless_dev *brcmf_alloc_wdev(s32 sizeof_iface,
207 struct device *dev);
208 static void brcmf_free_wdev(struct brcmf_cfg80211_priv *cfg_priv);
209 static s32 brcmf_inform_bss(struct brcmf_cfg80211_priv *cfg_priv);
210 static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv,
211 struct brcmf_bss_info *bi);
212 static s32 brcmf_update_bss_info(struct brcmf_cfg80211_priv *cfg_priv);
213 static s32 brcmf_add_keyext(struct wiphy *wiphy, struct net_device *dev,
214 u8 key_idx, const u8 *mac_addr,
215 struct key_params *params);
218 ** key indianess swap utilities
220 static void swap_key_from_BE(struct brcmf_wsec_key *key);
221 static void swap_key_to_BE(struct brcmf_wsec_key *key);
224 ** brcmf_cfg80211_priv memory init/deinit utilities
226 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_priv *cfg_priv);
227 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_priv *cfg_priv);
229 static void brcmf_delay(u32 ms);
232 ** store/restore cfg80211 instance data
234 static void brcmf_set_drvdata(struct brcmf_cfg80211_dev *dev, void *data);
235 static void *brcmf_get_drvdata(struct brcmf_cfg80211_dev *dev);
238 ** ibss mode utilities
240 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_priv *cfg_priv);
243 ** dongle up/down , default configuration utilities
245 static bool brcmf_is_linkdown(struct brcmf_cfg80211_priv *cfg_priv,
246 const struct brcmf_event_msg *e);
247 static bool brcmf_is_linkup(struct brcmf_cfg80211_priv *cfg_priv,
248 const struct brcmf_event_msg *e);
249 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_priv *cfg_priv,
250 const struct brcmf_event_msg *e);
251 static void brcmf_link_down(struct brcmf_cfg80211_priv *cfg_priv);
252 static s32 brcmf_dongle_mode(struct net_device *ndev, s32 iftype);
253 static s32 __brcmf_cfg80211_up(struct brcmf_cfg80211_priv *cfg_priv);
254 static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_priv *cfg_priv);
255 static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_priv *cfg_priv);
256 static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf);
259 ** dongle configuration utilities
261 static s32 brcmf_dongle_eventmsg(struct net_device *ndev);
262 static s32 brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
263 s32 scan_unassoc_time, s32 scan_passive_time);
264 static s32 brcmf_config_dongle(struct brcmf_cfg80211_priv *cfg_priv,
265 bool need_lock);
266 static s32 brcmf_dongle_roam(struct net_device *ndev, u32 roamvar,
267 u32 bcn_timeout);
270 ** iscan handler
272 static void brcmf_iscan_timer(unsigned long data);
273 static void brcmf_term_iscan(struct brcmf_cfg80211_priv *cfg_priv);
274 static s32 brcmf_init_iscan(struct brcmf_cfg80211_priv *cfg_priv);
275 static s32 brcmf_iscan_thread(void *data);
276 static s32 brcmf_dev_iovar_setbuf(struct net_device *dev, s8 *iovar,
277 void *param, s32 paramlen, void *bufptr,
278 s32 buflen);
279 static s32 brcmf_dev_iovar_getbuf(struct net_device *dev, s8 *iovar,
280 void *param, s32 paramlen, void *bufptr,
281 s32 buflen);
282 static s32 brcmf_run_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan,
283 struct brcmf_ssid *ssid, u16 action);
284 static s32 brcmf_do_iscan(struct brcmf_cfg80211_priv *cfg_priv);
285 static s32 brcmf_wakeup_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan);
286 static s32 brcmf_invoke_iscan(struct brcmf_cfg80211_priv *cfg_priv);
287 static s32 brcmf_get_iscan_results(struct brcmf_cfg80211_iscan_ctrl *iscan,
288 u32 *status,
289 struct brcmf_scan_results **bss_list);
290 static void brcmf_notify_iscan_complete(struct brcmf_cfg80211_iscan_ctrl *iscan,
291 bool aborted);
292 static void brcmf_init_iscan_eloop(struct brcmf_cfg80211_iscan_eloop *el);
293 static s32 brcmf_iscan_done(struct brcmf_cfg80211_priv *cfg_priv);
294 static s32 brcmf_iscan_pending(struct brcmf_cfg80211_priv *cfg_priv);
295 static s32 brcmf_iscan_inprogress(struct brcmf_cfg80211_priv *cfg_priv);
296 static s32 brcmf_iscan_aborted(struct brcmf_cfg80211_priv *cfg_priv);
299 * find most significant bit set
301 static __used u32 brcmf_find_msb(u16 bit16);
304 * update pmklist to dongle
306 static __used s32 brcmf_update_pmklist(struct net_device *dev,
307 struct brcmf_cfg80211_pmk_list *pmk_list,
308 s32 err);
310 static void brcmf_set_mpc(struct net_device *ndev, int mpc);
313 * debufs support
315 static int
316 brcmf_debugfs_add_netdev_params(struct brcmf_cfg80211_priv *cfg_priv);
317 static void brcmf_debugfs_remove_netdev(struct brcmf_cfg80211_priv *cfg_priv);
319 #define WL_PRIV_GET() \
320 ({ \
321 struct brcmf_cfg80211_iface *ci = brcmf_get_drvdata(cfg80211_dev); \
322 if (unlikely(!ci)) { \
323 WL_ERR("wl_cfg80211_dev is unavailable\n"); \
324 BUG(); \
326 ci->cfg_priv; \
329 #define CHECK_SYS_UP() \
330 do { \
331 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); \
332 if (unlikely(!test_bit(WL_STATUS_READY, &cfg_priv->status))) { \
333 WL_INFO("device is not ready : status (%d)\n", \
334 (int)cfg_priv->status); \
335 return -EIO; \
337 } while (0)
339 #define CHAN2G(_channel, _freq, _flags) { \
340 .band = IEEE80211_BAND_2GHZ, \
341 .center_freq = (_freq), \
342 .hw_value = (_channel), \
343 .flags = (_flags), \
344 .max_antenna_gain = 0, \
345 .max_power = 30, \
348 #define CHAN5G(_channel, _flags) { \
349 .band = IEEE80211_BAND_5GHZ, \
350 .center_freq = 5000 + (5 * (_channel)), \
351 .hw_value = (_channel), \
352 .flags = (_flags), \
353 .max_antenna_gain = 0, \
354 .max_power = 30, \
357 #define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
358 #define RATETAB_ENT(_rateid, _flags) \
360 .bitrate = RATE_TO_BASE100KBPS(_rateid), \
361 .hw_value = (_rateid), \
362 .flags = (_flags), \
365 static struct ieee80211_rate __wl_rates[] = {
366 RATETAB_ENT(WLC_RATE_1M, 0),
367 RATETAB_ENT(WLC_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
368 RATETAB_ENT(WLC_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
369 RATETAB_ENT(WLC_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
370 RATETAB_ENT(WLC_RATE_6M, 0),
371 RATETAB_ENT(WLC_RATE_9M, 0),
372 RATETAB_ENT(WLC_RATE_12M, 0),
373 RATETAB_ENT(WLC_RATE_18M, 0),
374 RATETAB_ENT(WLC_RATE_24M, 0),
375 RATETAB_ENT(WLC_RATE_36M, 0),
376 RATETAB_ENT(WLC_RATE_48M, 0),
377 RATETAB_ENT(WLC_RATE_54M, 0),
380 #define wl_a_rates (__wl_rates + 4)
381 #define wl_a_rates_size 8
382 #define wl_g_rates (__wl_rates + 0)
383 #define wl_g_rates_size 12
385 static struct ieee80211_channel __wl_2ghz_channels[] = {
386 CHAN2G(1, 2412, 0),
387 CHAN2G(2, 2417, 0),
388 CHAN2G(3, 2422, 0),
389 CHAN2G(4, 2427, 0),
390 CHAN2G(5, 2432, 0),
391 CHAN2G(6, 2437, 0),
392 CHAN2G(7, 2442, 0),
393 CHAN2G(8, 2447, 0),
394 CHAN2G(9, 2452, 0),
395 CHAN2G(10, 2457, 0),
396 CHAN2G(11, 2462, 0),
397 CHAN2G(12, 2467, 0),
398 CHAN2G(13, 2472, 0),
399 CHAN2G(14, 2484, 0),
402 static struct ieee80211_channel __wl_5ghz_a_channels[] = {
403 CHAN5G(34, 0), CHAN5G(36, 0),
404 CHAN5G(38, 0), CHAN5G(40, 0),
405 CHAN5G(42, 0), CHAN5G(44, 0),
406 CHAN5G(46, 0), CHAN5G(48, 0),
407 CHAN5G(52, 0), CHAN5G(56, 0),
408 CHAN5G(60, 0), CHAN5G(64, 0),
409 CHAN5G(100, 0), CHAN5G(104, 0),
410 CHAN5G(108, 0), CHAN5G(112, 0),
411 CHAN5G(116, 0), CHAN5G(120, 0),
412 CHAN5G(124, 0), CHAN5G(128, 0),
413 CHAN5G(132, 0), CHAN5G(136, 0),
414 CHAN5G(140, 0), CHAN5G(149, 0),
415 CHAN5G(153, 0), CHAN5G(157, 0),
416 CHAN5G(161, 0), CHAN5G(165, 0),
417 CHAN5G(184, 0), CHAN5G(188, 0),
418 CHAN5G(192, 0), CHAN5G(196, 0),
419 CHAN5G(200, 0), CHAN5G(204, 0),
420 CHAN5G(208, 0), CHAN5G(212, 0),
421 CHAN5G(216, 0),
424 static struct ieee80211_channel __wl_5ghz_n_channels[] = {
425 CHAN5G(32, 0), CHAN5G(34, 0),
426 CHAN5G(36, 0), CHAN5G(38, 0),
427 CHAN5G(40, 0), CHAN5G(42, 0),
428 CHAN5G(44, 0), CHAN5G(46, 0),
429 CHAN5G(48, 0), CHAN5G(50, 0),
430 CHAN5G(52, 0), CHAN5G(54, 0),
431 CHAN5G(56, 0), CHAN5G(58, 0),
432 CHAN5G(60, 0), CHAN5G(62, 0),
433 CHAN5G(64, 0), CHAN5G(66, 0),
434 CHAN5G(68, 0), CHAN5G(70, 0),
435 CHAN5G(72, 0), CHAN5G(74, 0),
436 CHAN5G(76, 0), CHAN5G(78, 0),
437 CHAN5G(80, 0), CHAN5G(82, 0),
438 CHAN5G(84, 0), CHAN5G(86, 0),
439 CHAN5G(88, 0), CHAN5G(90, 0),
440 CHAN5G(92, 0), CHAN5G(94, 0),
441 CHAN5G(96, 0), CHAN5G(98, 0),
442 CHAN5G(100, 0), CHAN5G(102, 0),
443 CHAN5G(104, 0), CHAN5G(106, 0),
444 CHAN5G(108, 0), CHAN5G(110, 0),
445 CHAN5G(112, 0), CHAN5G(114, 0),
446 CHAN5G(116, 0), CHAN5G(118, 0),
447 CHAN5G(120, 0), CHAN5G(122, 0),
448 CHAN5G(124, 0), CHAN5G(126, 0),
449 CHAN5G(128, 0), CHAN5G(130, 0),
450 CHAN5G(132, 0), CHAN5G(134, 0),
451 CHAN5G(136, 0), CHAN5G(138, 0),
452 CHAN5G(140, 0), CHAN5G(142, 0),
453 CHAN5G(144, 0), CHAN5G(145, 0),
454 CHAN5G(146, 0), CHAN5G(147, 0),
455 CHAN5G(148, 0), CHAN5G(149, 0),
456 CHAN5G(150, 0), CHAN5G(151, 0),
457 CHAN5G(152, 0), CHAN5G(153, 0),
458 CHAN5G(154, 0), CHAN5G(155, 0),
459 CHAN5G(156, 0), CHAN5G(157, 0),
460 CHAN5G(158, 0), CHAN5G(159, 0),
461 CHAN5G(160, 0), CHAN5G(161, 0),
462 CHAN5G(162, 0), CHAN5G(163, 0),
463 CHAN5G(164, 0), CHAN5G(165, 0),
464 CHAN5G(166, 0), CHAN5G(168, 0),
465 CHAN5G(170, 0), CHAN5G(172, 0),
466 CHAN5G(174, 0), CHAN5G(176, 0),
467 CHAN5G(178, 0), CHAN5G(180, 0),
468 CHAN5G(182, 0), CHAN5G(184, 0),
469 CHAN5G(186, 0), CHAN5G(188, 0),
470 CHAN5G(190, 0), CHAN5G(192, 0),
471 CHAN5G(194, 0), CHAN5G(196, 0),
472 CHAN5G(198, 0), CHAN5G(200, 0),
473 CHAN5G(202, 0), CHAN5G(204, 0),
474 CHAN5G(206, 0), CHAN5G(208, 0),
475 CHAN5G(210, 0), CHAN5G(212, 0),
476 CHAN5G(214, 0), CHAN5G(216, 0),
477 CHAN5G(218, 0), CHAN5G(220, 0),
478 CHAN5G(222, 0), CHAN5G(224, 0),
479 CHAN5G(226, 0), CHAN5G(228, 0),
482 static struct ieee80211_supported_band __wl_band_2ghz = {
483 .band = IEEE80211_BAND_2GHZ,
484 .channels = __wl_2ghz_channels,
485 .n_channels = ARRAY_SIZE(__wl_2ghz_channels),
486 .bitrates = wl_g_rates,
487 .n_bitrates = wl_g_rates_size,
490 static struct ieee80211_supported_band __wl_band_5ghz_a = {
491 .band = IEEE80211_BAND_5GHZ,
492 .channels = __wl_5ghz_a_channels,
493 .n_channels = ARRAY_SIZE(__wl_5ghz_a_channels),
494 .bitrates = wl_a_rates,
495 .n_bitrates = wl_a_rates_size,
498 static struct ieee80211_supported_band __wl_band_5ghz_n = {
499 .band = IEEE80211_BAND_5GHZ,
500 .channels = __wl_5ghz_n_channels,
501 .n_channels = ARRAY_SIZE(__wl_5ghz_n_channels),
502 .bitrates = wl_a_rates,
503 .n_bitrates = wl_a_rates_size,
506 static const u32 __wl_cipher_suites[] = {
507 WLAN_CIPHER_SUITE_WEP40,
508 WLAN_CIPHER_SUITE_WEP104,
509 WLAN_CIPHER_SUITE_TKIP,
510 WLAN_CIPHER_SUITE_CCMP,
511 WLAN_CIPHER_SUITE_AES_CMAC,
514 static void swap_key_from_BE(struct brcmf_wsec_key *key)
516 key->index = cpu_to_le32(key->index);
517 key->len = cpu_to_le32(key->len);
518 key->algo = cpu_to_le32(key->algo);
519 key->flags = cpu_to_le32(key->flags);
520 key->rxiv.hi = cpu_to_le32(key->rxiv.hi);
521 key->rxiv.lo = cpu_to_le16(key->rxiv.lo);
522 key->iv_initialized = cpu_to_le32(key->iv_initialized);
525 static void swap_key_to_BE(struct brcmf_wsec_key *key)
527 key->index = le32_to_cpu(key->index);
528 key->len = le32_to_cpu(key->len);
529 key->algo = le32_to_cpu(key->algo);
530 key->flags = le32_to_cpu(key->flags);
531 key->rxiv.hi = le32_to_cpu(key->rxiv.hi);
532 key->rxiv.lo = le16_to_cpu(key->rxiv.lo);
533 key->iv_initialized = le32_to_cpu(key->iv_initialized);
536 static s32
537 brcmf_dev_ioctl(struct net_device *dev, u32 cmd, void *arg, u32 len)
539 struct ifreq ifr;
540 struct brcmf_ioctl ioc;
541 mm_segment_t fs;
542 s32 err = 0;
544 memset(&ioc, 0, sizeof(ioc));
545 ioc.cmd = cmd;
546 ioc.buf = arg;
547 ioc.len = len;
548 strcpy(ifr.ifr_name, dev->name);
549 ifr.ifr_data = (caddr_t)&ioc;
551 fs = get_fs();
552 set_fs(get_ds());
553 err = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, SIOCDEVPRIVATE);
554 set_fs(fs);
556 return err;
559 static s32
560 brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
561 enum nl80211_iftype type, u32 *flags,
562 struct vif_params *params)
564 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
565 struct wireless_dev *wdev;
566 s32 infra = 0;
567 s32 err = 0;
569 WL_TRACE("Enter\n");
570 CHECK_SYS_UP();
572 switch (type) {
573 case NL80211_IFTYPE_MONITOR:
574 case NL80211_IFTYPE_WDS:
575 WL_ERR("type (%d) : currently we do not support this type\n",
576 type);
577 return -EOPNOTSUPP;
578 case NL80211_IFTYPE_ADHOC:
579 cfg_priv->conf->mode = WL_MODE_IBSS;
580 infra = 0;
581 break;
582 case NL80211_IFTYPE_STATION:
583 cfg_priv->conf->mode = WL_MODE_BSS;
584 infra = 1;
585 break;
586 default:
587 err = -EINVAL;
588 goto done;
591 infra = cpu_to_le32(infra);
592 err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_INFRA, &infra, sizeof(infra));
593 if (unlikely(err)) {
594 WL_ERR("WLC_SET_INFRA error (%d)\n", err);
595 err = -EAGAIN;
596 } else {
597 wdev = ndev->ieee80211_ptr;
598 wdev->iftype = type;
601 WL_INFO("IF Type = %s\n",
602 (cfg_priv->conf->mode == WL_MODE_IBSS) ? "Adhoc" : "Infra");
604 done:
605 WL_TRACE("Exit\n");
607 return err;
610 static void wl_iscan_prep(struct brcmf_scan_params *params,
611 struct brcmf_ssid *ssid)
613 memcpy(params->bssid, ether_bcast, ETH_ALEN);
614 params->bss_type = DOT11_BSSTYPE_ANY;
615 params->scan_type = 0;
616 params->nprobes = -1;
617 params->active_time = -1;
618 params->passive_time = -1;
619 params->home_time = -1;
620 params->channel_num = 0;
622 params->nprobes = cpu_to_le32(params->nprobes);
623 params->active_time = cpu_to_le32(params->active_time);
624 params->passive_time = cpu_to_le32(params->passive_time);
625 params->home_time = cpu_to_le32(params->home_time);
626 if (ssid && ssid->SSID_len)
627 memcpy(&params->ssid, ssid, sizeof(struct brcmf_ssid));
631 static s32
632 brcmf_dev_iovar_setbuf(struct net_device *dev, s8 * iovar, void *param,
633 s32 paramlen, void *bufptr, s32 buflen)
635 s32 iolen;
637 iolen = brcmu_mkiovar(iovar, param, paramlen, bufptr, buflen);
638 BUG_ON(!iolen);
640 return brcmf_dev_ioctl(dev, BRCMF_C_SET_VAR, bufptr, iolen);
643 static s32
644 brcmf_dev_iovar_getbuf(struct net_device *dev, s8 * iovar, void *param,
645 s32 paramlen, void *bufptr, s32 buflen)
647 s32 iolen;
649 iolen = brcmu_mkiovar(iovar, param, paramlen, bufptr, buflen);
650 BUG_ON(!iolen);
652 return brcmf_dev_ioctl(dev, BRCMF_C_GET_VAR, bufptr, buflen);
655 static s32
656 brcmf_run_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan,
657 struct brcmf_ssid *ssid, u16 action)
659 s32 params_size = (BRCMF_SCAN_PARAMS_FIXED_SIZE +
660 offsetof(struct brcmf_iscan_params, params));
661 struct brcmf_iscan_params *params;
662 s32 err = 0;
664 if (ssid && ssid->SSID_len)
665 params_size += sizeof(struct brcmf_ssid);
666 params = kzalloc(params_size, GFP_KERNEL);
667 if (unlikely(!params))
668 return -ENOMEM;
669 BUG_ON(params_size >= BRCMF_C_IOCTL_SMLEN);
671 wl_iscan_prep(&params->params, ssid);
673 params->version = cpu_to_le32(BRCMF_ISCAN_REQ_VERSION);
674 params->action = cpu_to_le16(action);
675 params->scan_duration = cpu_to_le16(0);
677 /* params_size += offsetof(struct brcmf_iscan_params, params); */
678 err = brcmf_dev_iovar_setbuf(iscan->dev, "iscan", params, params_size,
679 iscan->ioctl_buf, BRCMF_C_IOCTL_SMLEN);
680 if (unlikely(err)) {
681 if (err == -EBUSY) {
682 WL_INFO("system busy : iscan canceled\n");
683 } else {
684 WL_ERR("error (%d)\n", err);
687 kfree(params);
688 return err;
691 static s32 brcmf_do_iscan(struct brcmf_cfg80211_priv *cfg_priv)
693 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
694 struct net_device *ndev = cfg_to_ndev(cfg_priv);
695 struct brcmf_ssid ssid;
696 s32 passive_scan;
697 s32 err = 0;
699 /* Broadcast scan by default */
700 memset(&ssid, 0, sizeof(ssid));
702 iscan->state = WL_ISCAN_STATE_SCANING;
704 passive_scan = cfg_priv->active_scan ? 0 : 1;
705 err = brcmf_dev_ioctl(cfg_to_ndev(cfg_priv), BRCMF_C_SET_PASSIVE_SCAN,
706 &passive_scan, sizeof(passive_scan));
707 if (unlikely(err)) {
708 WL_ERR("error (%d)\n", err);
709 return err;
711 brcmf_set_mpc(ndev, 0);
712 cfg_priv->iscan_kickstart = true;
713 brcmf_run_iscan(iscan, &ssid, BRCMF_SCAN_ACTION_START);
714 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
715 iscan->timer_on = 1;
717 return err;
720 static s32
721 __brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
722 struct cfg80211_scan_request *request,
723 struct cfg80211_ssid *this_ssid)
725 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
726 struct cfg80211_ssid *ssids;
727 struct brcmf_cfg80211_scan_req *sr = cfg_priv->scan_req_int;
728 s32 passive_scan;
729 bool iscan_req;
730 bool spec_scan;
731 s32 err = 0;
733 if (unlikely(test_bit(WL_STATUS_SCANNING, &cfg_priv->status))) {
734 WL_ERR("Scanning already : status (%lu)\n", cfg_priv->status);
735 return -EAGAIN;
737 if (unlikely(test_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status))) {
738 WL_ERR("Scanning being aborted : status (%lu)\n",
739 cfg_priv->status);
740 return -EAGAIN;
742 if (test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) {
743 WL_ERR("Connecting : status (%lu)\n",
744 cfg_priv->status);
745 return -EAGAIN;
748 iscan_req = false;
749 spec_scan = false;
750 if (request) {
751 /* scan bss */
752 ssids = request->ssids;
753 if (cfg_priv->iscan_on && (!ssids || !ssids->ssid_len))
754 iscan_req = true;
755 } else {
756 /* scan in ibss */
757 /* we don't do iscan in ibss */
758 ssids = this_ssid;
761 cfg_priv->scan_request = request;
762 set_bit(WL_STATUS_SCANNING, &cfg_priv->status);
763 if (iscan_req) {
764 err = brcmf_do_iscan(cfg_priv);
765 if (likely(!err))
766 return err;
767 else
768 goto scan_out;
769 } else {
770 WL_SCAN("ssid \"%s\", ssid_len (%d)\n",
771 ssids->ssid, ssids->ssid_len);
772 memset(&sr->ssid, 0, sizeof(sr->ssid));
773 sr->ssid.SSID_len =
774 min_t(u8, sizeof(sr->ssid.SSID), ssids->ssid_len);
775 if (sr->ssid.SSID_len) {
776 memcpy(sr->ssid.SSID, ssids->ssid, sr->ssid.SSID_len);
777 sr->ssid.SSID_len = cpu_to_le32(sr->ssid.SSID_len);
778 spec_scan = true;
779 } else {
780 WL_SCAN("Broadcast scan\n");
783 passive_scan = cfg_priv->active_scan ? 0 : 1;
784 err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_PASSIVE_SCAN,
785 &passive_scan, sizeof(passive_scan));
786 if (unlikely(err)) {
787 WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
788 goto scan_out;
790 brcmf_set_mpc(ndev, 0);
791 err = brcmf_dev_ioctl(ndev, BRCMF_C_SCAN, &sr->ssid,
792 sizeof(sr->ssid));
793 if (err) {
794 if (err == -EBUSY) {
795 WL_INFO("system busy : scan for \"%s\" canceled\n",
796 sr->ssid.SSID);
797 } else {
798 WL_ERR("WLC_SCAN error (%d)\n", err);
800 brcmf_set_mpc(ndev, 1);
801 goto scan_out;
805 return 0;
807 scan_out:
808 clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
809 cfg_priv->scan_request = NULL;
810 return err;
813 static s32
814 brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
815 struct cfg80211_scan_request *request)
817 s32 err = 0;
819 WL_TRACE("Enter\n");
821 CHECK_SYS_UP();
823 err = __brcmf_cfg80211_scan(wiphy, ndev, request, NULL);
824 if (unlikely(err))
825 WL_ERR("scan error (%d)\n", err);
827 WL_TRACE("Exit\n");
828 return err;
831 static s32 brcmf_dev_intvar_set(struct net_device *dev, s8 *name, s32 val)
833 s8 buf[BRCMF_C_IOCTL_SMLEN];
834 u32 len;
835 s32 err = 0;
837 val = cpu_to_le32(val);
838 len = brcmu_mkiovar(name, (char *)(&val), sizeof(val), buf,
839 sizeof(buf));
840 BUG_ON(!len);
842 err = brcmf_dev_ioctl(dev, BRCMF_C_SET_VAR, buf, len);
843 if (unlikely(err))
844 WL_ERR("error (%d)\n", err);
846 return err;
849 static s32
850 brcmf_dev_intvar_get(struct net_device *dev, s8 *name, s32 *retval)
852 union {
853 s8 buf[BRCMF_C_IOCTL_SMLEN];
854 s32 val;
855 } var;
856 u32 len;
857 u32 data_null;
858 s32 err = 0;
860 len =
861 brcmu_mkiovar(name, (char *)(&data_null), 0, (char *)(&var),
862 sizeof(var.buf));
863 BUG_ON(!len);
864 err = brcmf_dev_ioctl(dev, BRCMF_C_GET_VAR, &var, len);
865 if (unlikely(err))
866 WL_ERR("error (%d)\n", err);
868 *retval = le32_to_cpu(var.val);
870 return err;
873 static s32 brcmf_set_rts(struct net_device *dev, u32 rts_threshold)
875 s32 err = 0;
877 err = brcmf_dev_intvar_set(dev, "rtsthresh", rts_threshold);
878 if (unlikely(err))
879 WL_ERR("Error (%d)\n", err);
881 return err;
884 static s32 brcmf_set_frag(struct net_device *dev, u32 frag_threshold)
886 s32 err = 0;
888 err = brcmf_dev_intvar_set(dev, "fragthresh", frag_threshold);
889 if (unlikely(err))
890 WL_ERR("Error (%d)\n", err);
892 return err;
895 static s32 brcmf_set_retry(struct net_device *dev, u32 retry, bool l)
897 s32 err = 0;
898 u32 cmd = (l ? WLC_SET_LRL : WLC_SET_SRL);
900 retry = cpu_to_le32(retry);
901 err = brcmf_dev_ioctl(dev, cmd, &retry, sizeof(retry));
902 if (unlikely(err)) {
903 WL_ERR("cmd (%d) , error (%d)\n", cmd, err);
904 return err;
906 return err;
909 static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
911 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
912 struct net_device *ndev = cfg_to_ndev(cfg_priv);
913 s32 err = 0;
915 WL_TRACE("Enter\n");
916 CHECK_SYS_UP();
918 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
919 (cfg_priv->conf->rts_threshold != wiphy->rts_threshold)) {
920 cfg_priv->conf->rts_threshold = wiphy->rts_threshold;
921 err = brcmf_set_rts(ndev, cfg_priv->conf->rts_threshold);
922 if (!err)
923 goto done;
925 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
926 (cfg_priv->conf->frag_threshold != wiphy->frag_threshold)) {
927 cfg_priv->conf->frag_threshold = wiphy->frag_threshold;
928 err = brcmf_set_frag(ndev, cfg_priv->conf->frag_threshold);
929 if (!err)
930 goto done;
932 if (changed & WIPHY_PARAM_RETRY_LONG
933 && (cfg_priv->conf->retry_long != wiphy->retry_long)) {
934 cfg_priv->conf->retry_long = wiphy->retry_long;
935 err = brcmf_set_retry(ndev, cfg_priv->conf->retry_long, true);
936 if (!err)
937 goto done;
939 if (changed & WIPHY_PARAM_RETRY_SHORT
940 && (cfg_priv->conf->retry_short != wiphy->retry_short)) {
941 cfg_priv->conf->retry_short = wiphy->retry_short;
942 err = brcmf_set_retry(ndev, cfg_priv->conf->retry_short, false);
943 if (!err)
944 goto done;
947 done:
948 WL_TRACE("Exit\n");
949 return err;
952 static s32
953 brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
954 struct cfg80211_ibss_params *params)
956 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
957 struct brcmf_join_params join_params;
958 size_t join_params_size = 0;
959 s32 err = 0;
960 s32 wsec = 0;
961 s32 bcnprd;
963 WL_TRACE("Enter\n");
964 CHECK_SYS_UP();
966 if (params->ssid)
967 WL_CONN("SSID: %s\n", params->ssid);
968 else {
969 WL_CONN("SSID: NULL, Not supported\n");
970 return -EOPNOTSUPP;
973 set_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
975 if (params->bssid)
976 WL_CONN("BSSID: %02X %02X %02X %02X %02X %02X\n",
977 params->bssid[0], params->bssid[1], params->bssid[2],
978 params->bssid[3], params->bssid[4], params->bssid[5]);
979 else
980 WL_CONN("No BSSID specified\n");
982 if (params->channel)
983 WL_CONN("channel: %d\n", params->channel->center_freq);
984 else
985 WL_CONN("no channel specified\n");
987 if (params->channel_fixed)
988 WL_CONN("fixed channel required\n");
989 else
990 WL_CONN("no fixed channel required\n");
992 if (params->ie && params->ie_len)
993 WL_CONN("ie len: %d\n", params->ie_len);
994 else
995 WL_CONN("no ie specified\n");
997 if (params->beacon_interval)
998 WL_CONN("beacon interval: %d\n", params->beacon_interval);
999 else
1000 WL_CONN("no beacon interval specified\n");
1002 if (params->basic_rates)
1003 WL_CONN("basic rates: %08X\n", params->basic_rates);
1004 else
1005 WL_CONN("no basic rates specified\n");
1007 if (params->privacy)
1008 WL_CONN("privacy required\n");
1009 else
1010 WL_CONN("no privacy required\n");
1012 /* Configure Privacy for starter */
1013 if (params->privacy)
1014 wsec |= WEP_ENABLED;
1016 err = brcmf_dev_intvar_set(dev, "wsec", wsec);
1017 if (unlikely(err)) {
1018 WL_ERR("wsec failed (%d)\n", err);
1019 goto done;
1022 /* Configure Beacon Interval for starter */
1023 if (params->beacon_interval)
1024 bcnprd = cpu_to_le32(params->beacon_interval);
1025 else
1026 bcnprd = cpu_to_le32(100);
1028 err = brcmf_dev_ioctl(dev, WLC_SET_BCNPRD, &bcnprd, sizeof(bcnprd));
1029 if (unlikely(err)) {
1030 WL_ERR("WLC_SET_BCNPRD failed (%d)\n", err);
1031 goto done;
1034 /* Configure required join parameter */
1035 memset(&join_params, 0, sizeof(struct brcmf_join_params));
1037 /* SSID */
1038 join_params.ssid.SSID_len =
1039 (params->ssid_len > 32) ? 32 : params->ssid_len;
1040 memcpy(join_params.ssid.SSID, params->ssid, join_params.ssid.SSID_len);
1041 join_params.ssid.SSID_len = cpu_to_le32(join_params.ssid.SSID_len);
1042 join_params_size = sizeof(join_params.ssid);
1043 brcmf_update_prof(cfg_priv, NULL, &join_params.ssid, WL_PROF_SSID);
1045 /* BSSID */
1046 if (params->bssid) {
1047 memcpy(join_params.params.bssid, params->bssid, ETH_ALEN);
1048 join_params_size = sizeof(join_params.ssid) +
1049 BRCMF_ASSOC_PARAMS_FIXED_SIZE;
1050 } else {
1051 memcpy(join_params.params.bssid, ether_bcast, ETH_ALEN);
1053 brcmf_update_prof(cfg_priv, NULL,
1054 &join_params.params.bssid, WL_PROF_BSSID);
1056 /* Channel */
1057 if (params->channel) {
1058 u32 target_channel;
1060 cfg_priv->channel =
1061 ieee80211_frequency_to_channel(
1062 params->channel->center_freq);
1063 if (params->channel_fixed) {
1064 /* adding chanspec */
1065 brcmf_ch_to_chanspec(cfg_priv->channel,
1066 &join_params, &join_params_size);
1069 /* set channel for starter */
1070 target_channel = cpu_to_le32(cfg_priv->channel);
1071 err = brcmf_dev_ioctl(dev, WLC_SET_CHANNEL,
1072 &target_channel, sizeof(target_channel));
1073 if (unlikely(err)) {
1074 WL_ERR("WLC_SET_CHANNEL failed (%d)\n", err);
1075 goto done;
1077 } else
1078 cfg_priv->channel = 0;
1080 cfg_priv->ibss_starter = false;
1083 err = brcmf_dev_ioctl(dev, BRCMF_C_SET_SSID,
1084 &join_params, join_params_size);
1085 if (unlikely(err)) {
1086 WL_ERR("WLC_SET_SSID failed (%d)\n", err);
1087 goto done;
1090 done:
1091 if (err)
1092 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
1093 WL_TRACE("Exit\n");
1094 return err;
1097 static s32 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
1113 brcmf_set_wpa_version(struct net_device *dev, 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, struct cfg80211_connect_params *sme)
1179 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(dev);
1180 struct brcmf_cfg80211_security *sec;
1181 s32 pval = 0;
1182 s32 gval = 0;
1183 s32 err = 0;
1185 if (sme->crypto.n_ciphers_pairwise) {
1186 switch (sme->crypto.ciphers_pairwise[0]) {
1187 case WLAN_CIPHER_SUITE_WEP40:
1188 case WLAN_CIPHER_SUITE_WEP104:
1189 pval = WEP_ENABLED;
1190 break;
1191 case WLAN_CIPHER_SUITE_TKIP:
1192 pval = TKIP_ENABLED;
1193 break;
1194 case WLAN_CIPHER_SUITE_CCMP:
1195 pval = AES_ENABLED;
1196 break;
1197 case WLAN_CIPHER_SUITE_AES_CMAC:
1198 pval = AES_ENABLED;
1199 break;
1200 default:
1201 WL_ERR("invalid cipher pairwise (%d)\n",
1202 sme->crypto.ciphers_pairwise[0]);
1203 return -EINVAL;
1206 if (sme->crypto.cipher_group) {
1207 switch (sme->crypto.cipher_group) {
1208 case WLAN_CIPHER_SUITE_WEP40:
1209 case WLAN_CIPHER_SUITE_WEP104:
1210 gval = WEP_ENABLED;
1211 break;
1212 case WLAN_CIPHER_SUITE_TKIP:
1213 gval = TKIP_ENABLED;
1214 break;
1215 case WLAN_CIPHER_SUITE_CCMP:
1216 gval = AES_ENABLED;
1217 break;
1218 case WLAN_CIPHER_SUITE_AES_CMAC:
1219 gval = AES_ENABLED;
1220 break;
1221 default:
1222 WL_ERR("invalid cipher group (%d)\n",
1223 sme->crypto.cipher_group);
1224 return -EINVAL;
1228 WL_CONN("pval (%d) gval (%d)\n", pval, gval);
1229 err = brcmf_dev_intvar_set(dev, "wsec", pval | gval);
1230 if (unlikely(err)) {
1231 WL_ERR("error (%d)\n", err);
1232 return err;
1235 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1236 sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1237 sec->cipher_group = sme->crypto.cipher_group;
1239 return err;
1242 static s32
1243 brcmf_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme)
1245 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(dev);
1246 struct brcmf_cfg80211_security *sec;
1247 s32 val = 0;
1248 s32 err = 0;
1250 if (sme->crypto.n_akm_suites) {
1251 err = brcmf_dev_intvar_get(dev, "wpa_auth", &val);
1252 if (unlikely(err)) {
1253 WL_ERR("could not get wpa_auth (%d)\n", err);
1254 return err;
1256 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1257 switch (sme->crypto.akm_suites[0]) {
1258 case WLAN_AKM_SUITE_8021X:
1259 val = WPA_AUTH_UNSPECIFIED;
1260 break;
1261 case WLAN_AKM_SUITE_PSK:
1262 val = WPA_AUTH_PSK;
1263 break;
1264 default:
1265 WL_ERR("invalid cipher group (%d)\n",
1266 sme->crypto.cipher_group);
1267 return -EINVAL;
1269 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1270 switch (sme->crypto.akm_suites[0]) {
1271 case WLAN_AKM_SUITE_8021X:
1272 val = WPA2_AUTH_UNSPECIFIED;
1273 break;
1274 case WLAN_AKM_SUITE_PSK:
1275 val = WPA2_AUTH_PSK;
1276 break;
1277 default:
1278 WL_ERR("invalid cipher group (%d)\n",
1279 sme->crypto.cipher_group);
1280 return -EINVAL;
1284 WL_CONN("setting wpa_auth to %d\n", val);
1285 err = brcmf_dev_intvar_set(dev, "wpa_auth", val);
1286 if (unlikely(err)) {
1287 WL_ERR("could not set wpa_auth (%d)\n", err);
1288 return err;
1291 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1292 sec->wpa_auth = sme->crypto.akm_suites[0];
1294 return err;
1297 static s32
1298 brcmf_set_set_sharedkey(struct net_device *dev,
1299 struct cfg80211_connect_params *sme)
1301 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(dev);
1302 struct brcmf_cfg80211_security *sec;
1303 struct brcmf_wsec_key key;
1304 s32 val;
1305 s32 err = 0;
1307 WL_CONN("key len (%d)\n", sme->key_len);
1308 if (sme->key_len) {
1309 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1310 WL_CONN("wpa_versions 0x%x cipher_pairwise 0x%x\n",
1311 sec->wpa_versions, sec->cipher_pairwise);
1312 if (!
1313 (sec->wpa_versions & (NL80211_WPA_VERSION_1 |
1314 NL80211_WPA_VERSION_2))
1315 && (sec->cipher_pairwise & (WLAN_CIPHER_SUITE_WEP40 |
1316 WLAN_CIPHER_SUITE_WEP104))) {
1317 memset(&key, 0, sizeof(key));
1318 key.len = (u32) sme->key_len;
1319 key.index = (u32) sme->key_idx;
1320 if (unlikely(key.len > sizeof(key.data))) {
1321 WL_ERR("Too long key length (%u)\n", key.len);
1322 return -EINVAL;
1324 memcpy(key.data, sme->key, key.len);
1325 key.flags = BRCMF_PRIMARY_KEY;
1326 switch (sec->cipher_pairwise) {
1327 case WLAN_CIPHER_SUITE_WEP40:
1328 key.algo = CRYPTO_ALGO_WEP1;
1329 break;
1330 case WLAN_CIPHER_SUITE_WEP104:
1331 key.algo = CRYPTO_ALGO_WEP128;
1332 break;
1333 default:
1334 WL_ERR("Invalid algorithm (%d)\n",
1335 sme->crypto.ciphers_pairwise[0]);
1336 return -EINVAL;
1338 /* Set the new key/index */
1339 WL_CONN("key length (%d) key index (%d) algo (%d)\n",
1340 key.len, key.index, key.algo);
1341 WL_CONN("key \"%s\"\n", key.data);
1342 swap_key_from_BE(&key);
1343 err = brcmf_dev_ioctl(dev, BRCMF_C_SET_KEY, &key,
1344 sizeof(key));
1345 if (unlikely(err)) {
1346 WL_ERR("WLC_SET_KEY error (%d)\n", err);
1347 return err;
1349 if (sec->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) {
1350 WL_CONN("set auth_type to shared key\n");
1351 val = 1; /* shared key */
1352 err = brcmf_dev_intvar_set(dev, "auth", val);
1353 if (unlikely(err)) {
1354 WL_ERR("set auth failed (%d)\n", err);
1355 return err;
1360 return err;
1363 static s32
1364 brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
1365 struct cfg80211_connect_params *sme)
1367 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1368 struct ieee80211_channel *chan = sme->channel;
1369 struct brcmf_join_params join_params;
1370 size_t join_params_size;
1372 s32 err = 0;
1374 WL_TRACE("Enter\n");
1375 CHECK_SYS_UP();
1377 if (unlikely(!sme->ssid)) {
1378 WL_ERR("Invalid ssid\n");
1379 return -EOPNOTSUPP;
1382 set_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
1384 if (chan) {
1385 cfg_priv->channel =
1386 ieee80211_frequency_to_channel(chan->center_freq);
1387 WL_CONN("channel (%d), center_req (%d)\n",
1388 cfg_priv->channel, chan->center_freq);
1389 } else
1390 cfg_priv->channel = 0;
1392 WL_INFO("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
1394 err = brcmf_set_wpa_version(dev, sme);
1395 if (err) {
1396 WL_ERR("wl_set_wpa_version failed (%d)\n", err);
1397 goto done;
1400 err = brcmf_set_auth_type(dev, sme);
1401 if (err) {
1402 WL_ERR("wl_set_auth_type failed (%d)\n", err);
1403 goto done;
1406 err = brcmf_set_set_cipher(dev, sme);
1407 if (err) {
1408 WL_ERR("wl_set_set_cipher failed (%d)\n", err);
1409 goto done;
1412 err = brcmf_set_key_mgmt(dev, sme);
1413 if (err) {
1414 WL_ERR("wl_set_key_mgmt failed (%d)\n", err);
1415 goto done;
1418 err = brcmf_set_set_sharedkey(dev, sme);
1419 if (err) {
1420 WL_ERR("wl_set_set_sharedkey failed (%d)\n", err);
1421 goto done;
1424 brcmf_update_prof(cfg_priv, NULL, sme->bssid, WL_PROF_BSSID);
1426 ** Join with specific BSSID and cached SSID
1427 ** If SSID is zero join based on BSSID only
1429 memset(&join_params, 0, sizeof(join_params));
1430 join_params_size = sizeof(join_params.ssid);
1432 join_params.ssid.SSID_len = min(sizeof(join_params.ssid.SSID), sme->ssid_len);
1433 memcpy(&join_params.ssid.SSID, sme->ssid, join_params.ssid.SSID_len);
1434 join_params.ssid.SSID_len = cpu_to_le32(join_params.ssid.SSID_len);
1435 brcmf_update_prof(cfg_priv, NULL, &join_params.ssid, WL_PROF_SSID);
1437 if (sme->bssid)
1438 memcpy(join_params.params.bssid, sme->bssid, ETH_ALEN);
1439 else
1440 memcpy(join_params.params.bssid, ether_bcast, ETH_ALEN);
1442 if (join_params.ssid.SSID_len < IEEE80211_MAX_SSID_LEN) {
1443 WL_CONN("ssid \"%s\", len (%d)\n",
1444 join_params.ssid.SSID, join_params.ssid.SSID_len);
1447 brcmf_ch_to_chanspec(cfg_priv->channel,
1448 &join_params, &join_params_size);
1449 err = brcmf_dev_ioctl(dev, BRCMF_C_SET_SSID,
1450 &join_params, join_params_size);
1451 if (err)
1452 WL_ERR("WLC_SET_SSID failed (%d)\n", err);
1454 done:
1455 if (err)
1456 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
1457 WL_TRACE("Exit\n");
1458 return err;
1461 static s32
1462 brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
1463 u16 reason_code)
1465 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1466 struct brcmf_scb_val scbval;
1467 s32 err = 0;
1469 WL_TRACE("Enter. Reason code = %d\n", reason_code);
1470 CHECK_SYS_UP();
1472 clear_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
1474 scbval.val = reason_code;
1475 memcpy(&scbval.ea, brcmf_read_prof(cfg_priv, WL_PROF_BSSID), ETH_ALEN);
1476 scbval.val = cpu_to_le32(scbval.val);
1477 err = brcmf_dev_ioctl(dev, BRCMF_C_DISASSOC, &scbval,
1478 sizeof(struct brcmf_scb_val));
1479 if (unlikely(err))
1480 WL_ERR("error (%d)\n", err);
1482 cfg_priv->link_up = false;
1484 WL_TRACE("Exit\n");
1485 return err;
1488 static s32
1489 brcmf_cfg80211_set_tx_power(struct wiphy *wiphy,
1490 enum nl80211_tx_power_setting type, s32 dbm)
1493 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1494 struct net_device *ndev = cfg_to_ndev(cfg_priv);
1495 u16 txpwrmw;
1496 s32 err = 0;
1497 s32 disable = 0;
1499 WL_TRACE("Enter\n");
1500 CHECK_SYS_UP();
1502 switch (type) {
1503 case NL80211_TX_POWER_AUTOMATIC:
1504 break;
1505 case NL80211_TX_POWER_LIMITED:
1506 if (dbm < 0) {
1507 WL_ERR("TX_POWER_LIMITED - dbm is negative\n");
1508 err = -EINVAL;
1509 goto done;
1511 break;
1512 case NL80211_TX_POWER_FIXED:
1513 if (dbm < 0) {
1514 WL_ERR("TX_POWER_FIXED - dbm is negative\n");
1515 err = -EINVAL;
1516 goto done;
1518 break;
1520 /* Make sure radio is off or on as far as software is concerned */
1521 disable = WL_RADIO_SW_DISABLE << 16;
1522 disable = cpu_to_le32(disable);
1523 err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_RADIO, &disable, sizeof(disable));
1524 if (unlikely(err))
1525 WL_ERR("WLC_SET_RADIO error (%d)\n", err);
1527 if (dbm > 0xffff)
1528 txpwrmw = 0xffff;
1529 else
1530 txpwrmw = (u16) dbm;
1531 err = brcmf_dev_intvar_set(ndev, "qtxpower",
1532 (s32) (brcmu_mw_to_qdbm(txpwrmw)));
1533 if (unlikely(err))
1534 WL_ERR("qtxpower error (%d)\n", err);
1535 cfg_priv->conf->tx_power = dbm;
1537 done:
1538 WL_TRACE("Exit\n");
1539 return err;
1542 static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm)
1544 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1545 struct net_device *ndev = cfg_to_ndev(cfg_priv);
1546 s32 txpwrdbm;
1547 u8 result;
1548 s32 err = 0;
1550 WL_TRACE("Enter\n");
1551 CHECK_SYS_UP();
1553 err = brcmf_dev_intvar_get(ndev, "qtxpower", &txpwrdbm);
1554 if (unlikely(err)) {
1555 WL_ERR("error (%d)\n", err);
1556 goto done;
1559 result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
1560 *dbm = (s32) brcmu_qdbm_to_mw(result);
1562 done:
1563 WL_TRACE("Exit\n");
1564 return err;
1567 static s32
1568 brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *dev,
1569 u8 key_idx, bool unicast, bool multicast)
1571 u32 index;
1572 s32 wsec;
1573 s32 err = 0;
1575 WL_TRACE("Enter\n");
1576 WL_CONN("key index (%d)\n", key_idx);
1577 CHECK_SYS_UP();
1579 err = brcmf_dev_ioctl(dev, BRCMF_C_GET_WSEC, &wsec, sizeof(wsec));
1580 if (unlikely(err)) {
1581 WL_ERR("WLC_GET_WSEC error (%d)\n", err);
1582 goto done;
1585 wsec = le32_to_cpu(wsec);
1586 if (wsec & WEP_ENABLED) {
1587 /* Just select a new current key */
1588 index = (u32) key_idx;
1589 index = cpu_to_le32(index);
1590 err = brcmf_dev_ioctl(dev, BRCMF_C_SET_KEY_PRIMARY, &index,
1591 sizeof(index));
1592 if (unlikely(err))
1593 WL_ERR("error (%d)\n", err);
1595 done:
1596 WL_TRACE("Exit\n");
1597 return err;
1600 static s32
1601 brcmf_add_keyext(struct wiphy *wiphy, struct net_device *dev,
1602 u8 key_idx, const u8 *mac_addr, struct key_params *params)
1604 struct brcmf_wsec_key key;
1605 s32 err = 0;
1607 memset(&key, 0, sizeof(key));
1608 key.index = (u32) key_idx;
1609 /* Instead of bcast for ea address for default wep keys,
1610 driver needs it to be Null */
1611 if (!is_multicast_ether_addr(mac_addr))
1612 memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
1613 key.len = (u32) params->key_len;
1614 /* check for key index change */
1615 if (key.len == 0) {
1616 /* key delete */
1617 swap_key_from_BE(&key);
1618 err = brcmf_dev_ioctl(dev, BRCMF_C_SET_KEY, &key, sizeof(key));
1619 if (unlikely(err)) {
1620 WL_ERR("key delete error (%d)\n", err);
1621 return err;
1623 } else {
1624 if (key.len > sizeof(key.data)) {
1625 WL_ERR("Invalid key length (%d)\n", key.len);
1626 return -EINVAL;
1629 WL_CONN("Setting the key index %d\n", key.index);
1630 memcpy(key.data, params->key, key.len);
1632 if (params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1633 u8 keybuf[8];
1634 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1635 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1636 memcpy(&key.data[16], keybuf, sizeof(keybuf));
1639 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
1640 if (params->seq && params->seq_len == 6) {
1641 /* rx iv */
1642 u8 *ivptr;
1643 ivptr = (u8 *) params->seq;
1644 key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
1645 (ivptr[3] << 8) | ivptr[2];
1646 key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
1647 key.iv_initialized = true;
1650 switch (params->cipher) {
1651 case WLAN_CIPHER_SUITE_WEP40:
1652 key.algo = CRYPTO_ALGO_WEP1;
1653 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1654 break;
1655 case WLAN_CIPHER_SUITE_WEP104:
1656 key.algo = CRYPTO_ALGO_WEP128;
1657 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1658 break;
1659 case WLAN_CIPHER_SUITE_TKIP:
1660 key.algo = CRYPTO_ALGO_TKIP;
1661 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1662 break;
1663 case WLAN_CIPHER_SUITE_AES_CMAC:
1664 key.algo = CRYPTO_ALGO_AES_CCM;
1665 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1666 break;
1667 case WLAN_CIPHER_SUITE_CCMP:
1668 key.algo = CRYPTO_ALGO_AES_CCM;
1669 WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
1670 break;
1671 default:
1672 WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
1673 return -EINVAL;
1675 swap_key_from_BE(&key);
1677 brcmf_netdev_wait_pend8021x(dev);
1678 err = brcmf_dev_ioctl(dev, BRCMF_C_SET_KEY, &key, sizeof(key));
1679 if (unlikely(err)) {
1680 WL_ERR("WLC_SET_KEY error (%d)\n", err);
1681 return err;
1684 return err;
1687 static s32
1688 brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
1689 u8 key_idx, bool pairwise, const u8 *mac_addr,
1690 struct key_params *params)
1692 struct brcmf_wsec_key key;
1693 s32 val;
1694 s32 wsec;
1695 s32 err = 0;
1696 u8 keybuf[8];
1698 WL_TRACE("Enter\n");
1699 WL_CONN("key index (%d)\n", key_idx);
1700 CHECK_SYS_UP();
1702 if (mac_addr) {
1703 WL_TRACE("Exit");
1704 return brcmf_add_keyext(wiphy, dev, key_idx, mac_addr, params);
1706 memset(&key, 0, sizeof(key));
1708 key.len = (u32) params->key_len;
1709 key.index = (u32) key_idx;
1711 if (unlikely(key.len > sizeof(key.data))) {
1712 WL_ERR("Too long key length (%u)\n", key.len);
1713 err = -EINVAL;
1714 goto done;
1716 memcpy(key.data, params->key, key.len);
1718 key.flags = BRCMF_PRIMARY_KEY;
1719 switch (params->cipher) {
1720 case WLAN_CIPHER_SUITE_WEP40:
1721 key.algo = CRYPTO_ALGO_WEP1;
1722 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1723 break;
1724 case WLAN_CIPHER_SUITE_WEP104:
1725 key.algo = CRYPTO_ALGO_WEP128;
1726 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1727 break;
1728 case WLAN_CIPHER_SUITE_TKIP:
1729 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1730 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1731 memcpy(&key.data[16], keybuf, sizeof(keybuf));
1732 key.algo = CRYPTO_ALGO_TKIP;
1733 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1734 break;
1735 case WLAN_CIPHER_SUITE_AES_CMAC:
1736 key.algo = CRYPTO_ALGO_AES_CCM;
1737 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1738 break;
1739 case WLAN_CIPHER_SUITE_CCMP:
1740 key.algo = CRYPTO_ALGO_AES_CCM;
1741 WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
1742 break;
1743 default:
1744 WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
1745 err = -EINVAL;
1746 goto done;
1749 /* Set the new key/index */
1750 swap_key_from_BE(&key);
1751 err = brcmf_dev_ioctl(dev, BRCMF_C_SET_KEY, &key, sizeof(key));
1752 if (unlikely(err)) {
1753 WL_ERR("WLC_SET_KEY error (%d)\n", err);
1754 goto done;
1757 val = WEP_ENABLED;
1758 err = brcmf_dev_intvar_get(dev, "wsec", &wsec);
1759 if (unlikely(err)) {
1760 WL_ERR("get wsec error (%d)\n", err);
1761 goto done;
1763 wsec &= ~(WEP_ENABLED);
1764 wsec |= val;
1765 err = brcmf_dev_intvar_set(dev, "wsec", wsec);
1766 if (unlikely(err)) {
1767 WL_ERR("set wsec error (%d)\n", err);
1768 goto done;
1771 val = 1; /* assume shared key. otherwise 0 */
1772 val = cpu_to_le32(val);
1773 err = brcmf_dev_ioctl(dev, BRCMF_C_SET_AUTH, &val, sizeof(val));
1774 if (unlikely(err))
1775 WL_ERR("WLC_SET_AUTH error (%d)\n", err);
1776 done:
1777 WL_TRACE("Exit\n");
1778 return err;
1781 static s32
1782 brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
1783 u8 key_idx, bool pairwise, const u8 *mac_addr)
1785 struct brcmf_wsec_key key;
1786 s32 err = 0;
1787 s32 val;
1788 s32 wsec;
1790 WL_TRACE("Enter\n");
1791 CHECK_SYS_UP();
1792 memset(&key, 0, sizeof(key));
1794 key.index = (u32) key_idx;
1795 key.flags = BRCMF_PRIMARY_KEY;
1796 key.algo = CRYPTO_ALGO_OFF;
1798 WL_CONN("key index (%d)\n", key_idx);
1799 /* Set the new key/index */
1800 swap_key_from_BE(&key);
1801 err = brcmf_dev_ioctl(dev, BRCMF_C_SET_KEY, &key, sizeof(key));
1802 if (unlikely(err)) {
1803 if (err == -EINVAL) {
1804 if (key.index >= DOT11_MAX_DEFAULT_KEYS)
1805 /* we ignore this key index in this case */
1806 WL_ERR("invalid key index (%d)\n", key_idx);
1807 } else
1808 WL_ERR("WLC_SET_KEY error (%d)\n", err);
1810 /* Ignore this error, may happen during DISASSOC */
1811 err = -EAGAIN;
1812 goto done;
1815 val = 0;
1816 err = brcmf_dev_intvar_get(dev, "wsec", &wsec);
1817 if (unlikely(err)) {
1818 WL_ERR("get wsec error (%d)\n", err);
1819 /* Ignore this error, may happen during DISASSOC */
1820 err = -EAGAIN;
1821 goto done;
1823 wsec &= ~(WEP_ENABLED);
1824 wsec |= val;
1825 err = brcmf_dev_intvar_set(dev, "wsec", wsec);
1826 if (unlikely(err)) {
1827 WL_ERR("set wsec error (%d)\n", err);
1828 /* Ignore this error, may happen during DISASSOC */
1829 err = -EAGAIN;
1830 goto done;
1833 val = 0; /* assume open key. otherwise 1 */
1834 val = cpu_to_le32(val);
1835 err = brcmf_dev_ioctl(dev, BRCMF_C_SET_AUTH, &val, sizeof(val));
1836 if (unlikely(err)) {
1837 WL_ERR("WLC_SET_AUTH error (%d)\n", err);
1838 /* Ignore this error, may happen during DISASSOC */
1839 err = -EAGAIN;
1841 done:
1842 WL_TRACE("Exit\n");
1843 return err;
1846 static s32
1847 brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
1848 u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
1849 void (*callback) (void *cookie, struct key_params * params))
1851 struct key_params params;
1852 struct brcmf_wsec_key key;
1853 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1854 struct brcmf_cfg80211_security *sec;
1855 s32 wsec;
1856 s32 err = 0;
1858 WL_TRACE("Enter\n");
1859 WL_CONN("key index (%d)\n", key_idx);
1860 CHECK_SYS_UP();
1862 memset(&key, 0, sizeof(key));
1863 key.index = key_idx;
1864 swap_key_to_BE(&key);
1865 memset(&params, 0, sizeof(params));
1866 params.key_len = (u8) min_t(u8, WLAN_MAX_KEY_LEN, key.len);
1867 memcpy(params.key, key.data, params.key_len);
1869 err = brcmf_dev_ioctl(dev, BRCMF_C_GET_WSEC, &wsec, sizeof(wsec));
1870 if (unlikely(err)) {
1871 WL_ERR("WLC_GET_WSEC error (%d)\n", err);
1872 /* Ignore this error, may happen during DISASSOC */
1873 err = -EAGAIN;
1874 goto done;
1876 wsec = le32_to_cpu(wsec);
1877 switch (wsec) {
1878 case WEP_ENABLED:
1879 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1880 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
1881 params.cipher = WLAN_CIPHER_SUITE_WEP40;
1882 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1883 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
1884 params.cipher = WLAN_CIPHER_SUITE_WEP104;
1885 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1887 break;
1888 case TKIP_ENABLED:
1889 params.cipher = WLAN_CIPHER_SUITE_TKIP;
1890 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1891 break;
1892 case AES_ENABLED:
1893 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
1894 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1895 break;
1896 default:
1897 WL_ERR("Invalid algo (0x%x)\n", wsec);
1898 err = -EINVAL;
1899 goto done;
1901 callback(cookie, &params);
1903 done:
1904 WL_TRACE("Exit\n");
1905 return err;
1908 static s32
1909 brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
1910 struct net_device *dev, u8 key_idx)
1912 WL_INFO("Not supported\n");
1914 CHECK_SYS_UP();
1915 return -EOPNOTSUPP;
1918 static s32
1919 brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
1920 u8 *mac, struct station_info *sinfo)
1922 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1923 struct brcmf_scb_val scb_val;
1924 int rssi;
1925 s32 rate;
1926 s32 err = 0;
1927 u8 *bssid = brcmf_read_prof(cfg_priv, WL_PROF_BSSID);
1929 WL_TRACE("Enter\n");
1930 CHECK_SYS_UP();
1932 if (unlikely
1933 (memcmp(mac, bssid, ETH_ALEN))) {
1934 WL_ERR("Wrong Mac address cfg_mac-%X:%X:%X:%X:%X:%X"
1935 "wl_bssid-%X:%X:%X:%X:%X:%X\n",
1936 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
1937 bssid[0], bssid[1], bssid[2], bssid[3],
1938 bssid[4], bssid[5]);
1939 err = -ENOENT;
1940 goto done;
1943 /* Report the current tx rate */
1944 err = brcmf_dev_ioctl(dev, BRCMF_C_GET_RATE, &rate, sizeof(rate));
1945 if (err) {
1946 WL_ERR("Could not get rate (%d)\n", err);
1947 } else {
1948 rate = le32_to_cpu(rate);
1949 sinfo->filled |= STATION_INFO_TX_BITRATE;
1950 sinfo->txrate.legacy = rate * 5;
1951 WL_CONN("Rate %d Mbps\n", rate / 2);
1954 if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status)) {
1955 scb_val.val = 0;
1956 err = brcmf_dev_ioctl(dev, BRCMF_C_GET_RSSI, &scb_val,
1957 sizeof(struct brcmf_scb_val));
1958 if (unlikely(err)) {
1959 WL_ERR("Could not get rssi (%d)\n", err);
1961 rssi = le32_to_cpu(scb_val.val);
1962 sinfo->filled |= STATION_INFO_SIGNAL;
1963 sinfo->signal = rssi;
1964 WL_CONN("RSSI %d dBm\n", rssi);
1967 done:
1968 WL_TRACE("Exit\n");
1969 return err;
1972 static s32
1973 brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
1974 bool enabled, s32 timeout)
1976 s32 pm;
1977 s32 err = 0;
1979 WL_TRACE("Enter\n");
1980 CHECK_SYS_UP();
1982 pm = enabled ? PM_FAST : PM_OFF;
1983 pm = cpu_to_le32(pm);
1984 WL_INFO("power save %s\n", (pm ? "enabled" : "disabled"));
1986 err = brcmf_dev_ioctl(dev, BRCMF_C_SET_PM, &pm, sizeof(pm));
1987 if (unlikely(err)) {
1988 if (err == -ENODEV)
1989 WL_ERR("net_device is not ready yet\n");
1990 else
1991 WL_ERR("error (%d)\n", err);
1993 WL_TRACE("Exit\n");
1994 return err;
1997 static __used u32 brcmf_find_msb(u16 bit16)
1999 u32 ret = 0;
2001 if (bit16 & 0xff00) {
2002 ret += 8;
2003 bit16 >>= 8;
2006 if (bit16 & 0xf0) {
2007 ret += 4;
2008 bit16 >>= 4;
2011 if (bit16 & 0xc) {
2012 ret += 2;
2013 bit16 >>= 2;
2016 if (bit16 & 2)
2017 ret += bit16 & 2;
2018 else if (bit16)
2019 ret += bit16;
2021 return ret;
2024 static s32
2025 brcmf_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev,
2026 const u8 *addr,
2027 const struct cfg80211_bitrate_mask *mask)
2029 struct wl_rateset rateset;
2030 s32 rate;
2031 s32 val;
2032 s32 err_bg;
2033 s32 err_a;
2034 u32 legacy;
2035 s32 err = 0;
2037 WL_TRACE("Enter\n");
2038 CHECK_SYS_UP();
2040 /* addr param is always NULL. ignore it */
2041 /* Get current rateset */
2042 err = brcmf_dev_ioctl(dev, WLC_GET_CURR_RATESET, &rateset,
2043 sizeof(rateset));
2044 if (unlikely(err)) {
2045 WL_ERR("could not get current rateset (%d)\n", err);
2046 goto done;
2049 rateset.count = le32_to_cpu(rateset.count);
2051 legacy = brcmf_find_msb(mask->control[IEEE80211_BAND_2GHZ].legacy);
2052 if (!legacy)
2053 legacy = brcmf_find_msb(mask->control[IEEE80211_BAND_5GHZ].legacy);
2055 val = wl_g_rates[legacy - 1].bitrate * 100000;
2057 if (val < rateset.count)
2058 /* Select rate by rateset index */
2059 rate = rateset.rates[val] & 0x7f;
2060 else
2061 /* Specified rate in bps */
2062 rate = val / 500000;
2064 WL_CONN("rate %d mbps\n", rate / 2);
2068 * Set rate override,
2069 * Since the is a/b/g-blind, both a/bg_rate are enforced.
2071 err_bg = brcmf_dev_intvar_set(dev, "bg_rate", rate);
2072 err_a = brcmf_dev_intvar_set(dev, "a_rate", rate);
2073 if (unlikely(err_bg && err_a)) {
2074 WL_ERR("could not set fixed rate (%d) (%d)\n", err_bg, err_a);
2075 err = err_bg | err_a;
2078 done:
2079 WL_TRACE("Exit\n");
2080 return err;
2083 static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
2085 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2088 * Check for WL_STATUS_READY before any function call which
2089 * could result is bus access. Don't block the resume for
2090 * any driver error conditions
2092 WL_TRACE("Enter\n");
2094 #if defined(CONFIG_PM_SLEEP)
2095 atomic_set(&brcmf_mmc_suspend, false);
2096 #endif /* defined(CONFIG_PM_SLEEP) */
2098 if (test_bit(WL_STATUS_READY, &cfg_priv->status))
2099 brcmf_invoke_iscan(wiphy_to_cfg(wiphy));
2101 WL_TRACE("Exit\n");
2102 return 0;
2105 static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
2106 struct cfg80211_wowlan *wow)
2108 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2109 struct net_device *ndev = cfg_to_ndev(cfg_priv);
2111 WL_TRACE("Enter\n");
2114 * Check for WL_STATUS_READY before any function call which
2115 * could result is bus access. Don't block the suspend for
2116 * any driver error conditions
2120 * While going to suspend if associated with AP disassociate
2121 * from AP to save power while system is in suspended state
2123 if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) ||
2124 test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) &&
2125 test_bit(WL_STATUS_READY, &cfg_priv->status)) {
2126 WL_INFO("Disassociating from AP"
2127 " while entering suspend state\n");
2128 brcmf_link_down(cfg_priv);
2131 * Make sure WPA_Supplicant receives all the event
2132 * generated due to DISASSOC call to the fw to keep
2133 * the state fw and WPA_Supplicant state consistent
2135 rtnl_unlock();
2136 brcmf_delay(500);
2137 rtnl_lock();
2140 set_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
2141 if (test_bit(WL_STATUS_READY, &cfg_priv->status))
2142 brcmf_term_iscan(cfg_priv);
2144 if (cfg_priv->scan_request) {
2145 /* Indidate scan abort to cfg80211 layer */
2146 WL_INFO("Terminating scan in progress\n");
2147 cfg80211_scan_done(cfg_priv->scan_request, true);
2148 cfg_priv->scan_request = NULL;
2150 clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
2151 clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
2153 /* Turn off watchdog timer */
2154 if (test_bit(WL_STATUS_READY, &cfg_priv->status)) {
2155 WL_INFO("Enable MPC\n");
2156 brcmf_set_mpc(ndev, 1);
2159 #if defined(CONFIG_PM_SLEEP)
2160 atomic_set(&brcmf_mmc_suspend, true);
2161 #endif /* defined(CONFIG_PM_SLEEP) */
2163 WL_TRACE("Exit\n");
2165 return 0;
2168 static __used s32
2169 brcmf_update_pmklist(struct net_device *dev,
2170 struct brcmf_cfg80211_pmk_list *pmk_list, s32 err)
2172 int i, j;
2174 WL_CONN("No of elements %d\n", pmk_list->pmkids.npmkid);
2175 for (i = 0; i < pmk_list->pmkids.npmkid; i++) {
2176 WL_CONN("PMKID[%d]: %pM =\n", i,
2177 &pmk_list->pmkids.pmkid[i].BSSID);
2178 for (j = 0; j < WLAN_PMKID_LEN; j++)
2179 WL_CONN("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]);
2182 if (likely(!err))
2183 brcmf_dev_bufvar_set(dev, "pmkid_info", (char *)pmk_list,
2184 sizeof(*pmk_list));
2186 return err;
2189 static s32
2190 brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
2191 struct cfg80211_pmksa *pmksa)
2193 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2194 struct _pmkid_list *pmkids = &cfg_priv->pmk_list->pmkids;
2195 s32 err = 0;
2196 int i;
2198 WL_TRACE("Enter\n");
2199 CHECK_SYS_UP();
2201 for (i = 0; i < pmkids->npmkid; i++)
2202 if (!memcmp(pmksa->bssid, pmkids->pmkid[i].BSSID, ETH_ALEN))
2203 break;
2204 if (i < WL_NUM_PMKIDS_MAX) {
2205 memcpy(pmkids->pmkid[i].BSSID, pmksa->bssid, ETH_ALEN);
2206 memcpy(pmkids->pmkid[i].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2207 if (i == pmkids->npmkid)
2208 pmkids->npmkid++;
2209 } else
2210 err = -EINVAL;
2212 WL_CONN("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2213 pmkids->pmkid[pmkids->npmkid].BSSID);
2214 for (i = 0; i < WLAN_PMKID_LEN; i++)
2215 WL_CONN("%02x\n", pmkids->pmkid[pmkids->npmkid].PMKID[i]);
2217 err = brcmf_update_pmklist(dev, cfg_priv->pmk_list, err);
2219 WL_TRACE("Exit\n");
2220 return err;
2223 static s32
2224 brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
2225 struct cfg80211_pmksa *pmksa)
2227 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2228 struct _pmkid_list pmkid;
2229 s32 err = 0;
2230 int i;
2232 WL_TRACE("Enter\n");
2233 CHECK_SYS_UP();
2234 memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
2235 memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2237 WL_CONN("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2238 &pmkid.pmkid[0].BSSID);
2239 for (i = 0; i < WLAN_PMKID_LEN; i++)
2240 WL_CONN("%02x\n", pmkid.pmkid[0].PMKID[i]);
2242 for (i = 0; i < cfg_priv->pmk_list->pmkids.npmkid; i++)
2243 if (!memcmp
2244 (pmksa->bssid, &cfg_priv->pmk_list->pmkids.pmkid[i].BSSID,
2245 ETH_ALEN))
2246 break;
2248 if ((cfg_priv->pmk_list->pmkids.npmkid > 0)
2249 && (i < cfg_priv->pmk_list->pmkids.npmkid)) {
2250 memset(&cfg_priv->pmk_list->pmkids.pmkid[i], 0,
2251 sizeof(pmkid_t));
2252 for (; i < (cfg_priv->pmk_list->pmkids.npmkid - 1); i++) {
2253 memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].BSSID,
2254 &cfg_priv->pmk_list->pmkids.pmkid[i + 1].BSSID,
2255 ETH_ALEN);
2256 memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].PMKID,
2257 &cfg_priv->pmk_list->pmkids.pmkid[i + 1].PMKID,
2258 WLAN_PMKID_LEN);
2260 cfg_priv->pmk_list->pmkids.npmkid--;
2261 } else
2262 err = -EINVAL;
2264 err = brcmf_update_pmklist(dev, cfg_priv->pmk_list, err);
2266 WL_TRACE("Exit\n");
2267 return err;
2271 static s32
2272 brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
2274 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2275 s32 err = 0;
2277 WL_TRACE("Enter\n");
2278 CHECK_SYS_UP();
2280 memset(cfg_priv->pmk_list, 0, sizeof(*cfg_priv->pmk_list));
2281 err = brcmf_update_pmklist(dev, cfg_priv->pmk_list, err);
2283 WL_TRACE("Exit\n");
2284 return err;
2288 static struct cfg80211_ops wl_cfg80211_ops = {
2289 .change_virtual_intf = brcmf_cfg80211_change_iface,
2290 .scan = brcmf_cfg80211_scan,
2291 .set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
2292 .join_ibss = brcmf_cfg80211_join_ibss,
2293 .leave_ibss = brcmf_cfg80211_leave_ibss,
2294 .get_station = brcmf_cfg80211_get_station,
2295 .set_tx_power = brcmf_cfg80211_set_tx_power,
2296 .get_tx_power = brcmf_cfg80211_get_tx_power,
2297 .add_key = brcmf_cfg80211_add_key,
2298 .del_key = brcmf_cfg80211_del_key,
2299 .get_key = brcmf_cfg80211_get_key,
2300 .set_default_key = brcmf_cfg80211_config_default_key,
2301 .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
2302 .set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
2303 .set_bitrate_mask = brcmf_cfg80211_set_bitrate_mask,
2304 .connect = brcmf_cfg80211_connect,
2305 .disconnect = brcmf_cfg80211_disconnect,
2306 .suspend = brcmf_cfg80211_suspend,
2307 .resume = brcmf_cfg80211_resume,
2308 .set_pmksa = brcmf_cfg80211_set_pmksa,
2309 .del_pmksa = brcmf_cfg80211_del_pmksa,
2310 .flush_pmksa = brcmf_cfg80211_flush_pmksa
2313 static s32 brcmf_mode_to_nl80211_iftype(s32 mode)
2315 s32 err = 0;
2317 switch (mode) {
2318 case WL_MODE_BSS:
2319 return NL80211_IFTYPE_STATION;
2320 case WL_MODE_IBSS:
2321 return NL80211_IFTYPE_ADHOC;
2322 default:
2323 return NL80211_IFTYPE_UNSPECIFIED;
2326 return err;
2329 static struct wireless_dev *brcmf_alloc_wdev(s32 sizeof_iface,
2330 struct device *dev)
2332 struct wireless_dev *wdev;
2333 s32 err = 0;
2335 wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
2336 if (unlikely(!wdev)) {
2337 WL_ERR("Could not allocate wireless device\n");
2338 return ERR_PTR(-ENOMEM);
2340 wdev->wiphy =
2341 wiphy_new(&wl_cfg80211_ops,
2342 sizeof(struct brcmf_cfg80211_priv) + sizeof_iface);
2343 if (unlikely(!wdev->wiphy)) {
2344 WL_ERR("Couldn not allocate wiphy device\n");
2345 err = -ENOMEM;
2346 goto wiphy_new_out;
2348 set_wiphy_dev(wdev->wiphy, dev);
2349 wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
2350 wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
2351 wdev->wiphy->interface_modes =
2352 BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
2353 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
2354 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a; /* Set
2355 * it as 11a by default.
2356 * This will be updated with
2357 * 11n phy tables in
2358 * "ifconfig up"
2359 * if phy has 11n capability
2361 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2362 wdev->wiphy->cipher_suites = __wl_cipher_suites;
2363 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
2364 #ifndef WL_POWERSAVE_DISABLED
2365 wdev->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; /* enable power
2366 * save mode
2367 * by default
2369 #else
2370 wdev->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
2371 #endif /* !WL_POWERSAVE_DISABLED */
2372 err = wiphy_register(wdev->wiphy);
2373 if (unlikely(err < 0)) {
2374 WL_ERR("Couldn not register wiphy device (%d)\n", err);
2375 goto wiphy_register_out;
2377 return wdev;
2379 wiphy_register_out:
2380 wiphy_free(wdev->wiphy);
2382 wiphy_new_out:
2383 kfree(wdev);
2385 return ERR_PTR(err);
2388 static void brcmf_free_wdev(struct brcmf_cfg80211_priv *cfg_priv)
2390 struct wireless_dev *wdev = cfg_to_wdev(cfg_priv);
2392 if (unlikely(!wdev)) {
2393 WL_ERR("wdev is invalid\n");
2394 return;
2396 wiphy_unregister(wdev->wiphy);
2397 wiphy_free(wdev->wiphy);
2398 kfree(wdev);
2399 cfg_to_wdev(cfg_priv) = NULL;
2402 static s32 brcmf_inform_bss(struct brcmf_cfg80211_priv *cfg_priv)
2404 struct brcmf_scan_results *bss_list;
2405 struct brcmf_bss_info *bi = NULL; /* must be initialized */
2406 s32 err = 0;
2407 int i;
2409 bss_list = cfg_priv->bss_list;
2410 if (unlikely(bss_list->version != BRCMF_BSS_INFO_VERSION)) {
2411 WL_ERR("Version %d != WL_BSS_INFO_VERSION\n",
2412 bss_list->version);
2413 return -EOPNOTSUPP;
2415 WL_SCAN("scanned AP count (%d)\n", bss_list->count);
2416 bi = next_bss(bss_list, bi);
2417 for_each_bss(bss_list, bi, i) {
2418 err = brcmf_inform_single_bss(cfg_priv, bi);
2419 if (unlikely(err))
2420 break;
2422 return err;
2426 static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv,
2427 struct brcmf_bss_info *bi)
2429 struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
2430 struct ieee80211_channel *notify_channel;
2431 struct cfg80211_bss *bss;
2432 struct ieee80211_supported_band *band;
2433 s32 err = 0;
2434 u16 channel;
2435 u32 freq;
2436 u64 notify_timestamp;
2437 u16 notify_capability;
2438 u16 notify_interval;
2439 u8 *notify_ie;
2440 size_t notify_ielen;
2441 s32 notify_signal;
2443 if (unlikely(le32_to_cpu(bi->length) > WL_BSS_INFO_MAX)) {
2444 WL_ERR("Bss info is larger than buffer. Discarding\n");
2445 return 0;
2448 channel = bi->ctl_ch ? bi->ctl_ch :
2449 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2451 if (channel <= CH_MAX_2G_CHANNEL)
2452 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2453 else
2454 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2456 freq = ieee80211_channel_to_frequency(channel, band->band);
2457 notify_channel = ieee80211_get_channel(wiphy, freq);
2459 notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */
2460 notify_capability = le16_to_cpu(bi->capability);
2461 notify_interval = le16_to_cpu(bi->beacon_period);
2462 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2463 notify_ielen = le16_to_cpu(bi->ie_length);
2464 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2466 WL_CONN("bssid: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
2467 bi->BSSID[0], bi->BSSID[1], bi->BSSID[2],
2468 bi->BSSID[3], bi->BSSID[4], bi->BSSID[5]);
2469 WL_CONN("Channel: %d(%d)\n", channel, freq);
2470 WL_CONN("Capability: %X\n", notify_capability);
2471 WL_CONN("Beacon interval: %d\n", notify_interval);
2472 WL_CONN("Signal: %d\n", notify_signal);
2473 WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp);
2475 bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)bi->BSSID,
2476 notify_timestamp, notify_capability, notify_interval, notify_ie,
2477 notify_ielen, notify_signal, GFP_KERNEL);
2479 if (unlikely(!bss)) {
2480 WL_ERR("cfg80211_inform_bss_frame error\n");
2481 return -EINVAL;
2484 return err;
2487 static s32 wl_inform_ibss(struct brcmf_cfg80211_priv *cfg_priv,
2488 struct net_device *dev, const u8 *bssid)
2490 struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
2491 struct ieee80211_channel *notify_channel;
2492 struct brcmf_bss_info *bi = NULL;
2493 struct ieee80211_supported_band *band;
2494 u8 *buf = NULL;
2495 s32 err = 0;
2496 u16 channel;
2497 u32 freq;
2498 u64 notify_timestamp;
2499 u16 notify_capability;
2500 u16 notify_interval;
2501 u8 *notify_ie;
2502 size_t notify_ielen;
2503 s32 notify_signal;
2505 WL_TRACE("Enter\n");
2507 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2508 if (buf == NULL) {
2509 WL_ERR("kzalloc() failed\n");
2510 err = -ENOMEM;
2511 goto CleanUp;
2514 *(u32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
2516 err = brcmf_dev_ioctl(dev, BRCMF_C_GET_BSS_INFO, buf, WL_BSS_INFO_MAX);
2517 if (unlikely(err)) {
2518 WL_ERR("WLC_GET_BSS_INFO failed: %d\n", err);
2519 goto CleanUp;
2522 bi = (struct brcmf_bss_info *)(buf + 4);
2524 channel = bi->ctl_ch ? bi->ctl_ch :
2525 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2527 if (channel <= CH_MAX_2G_CHANNEL)
2528 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2529 else
2530 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2532 freq = ieee80211_channel_to_frequency(channel, band->band);
2533 notify_channel = ieee80211_get_channel(wiphy, freq);
2535 notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */
2536 notify_capability = le16_to_cpu(bi->capability);
2537 notify_interval = le16_to_cpu(bi->beacon_period);
2538 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2539 notify_ielen = le16_to_cpu(bi->ie_length);
2540 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2542 WL_CONN("channel: %d(%d)\n", channel, freq);
2543 WL_CONN("capability: %X\n", notify_capability);
2544 WL_CONN("beacon interval: %d\n", notify_interval);
2545 WL_CONN("signal: %d\n", notify_signal);
2546 WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp);
2548 cfg80211_inform_bss(wiphy, notify_channel, bssid,
2549 notify_timestamp, notify_capability, notify_interval,
2550 notify_ie, notify_ielen, notify_signal, GFP_KERNEL);
2552 CleanUp:
2554 kfree(buf);
2556 WL_TRACE("Exit\n");
2558 return err;
2561 static bool brcmf_is_linkup(struct brcmf_cfg80211_priv *cfg_priv,
2562 const struct brcmf_event_msg *e)
2564 u32 event = be32_to_cpu(e->event_type);
2565 u32 status = be32_to_cpu(e->status);
2567 if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
2568 WL_CONN("Processing set ssid\n");
2569 cfg_priv->link_up = true;
2570 return true;
2573 return false;
2576 static bool brcmf_is_linkdown(struct brcmf_cfg80211_priv *cfg_priv,
2577 const struct brcmf_event_msg *e)
2579 u32 event = be32_to_cpu(e->event_type);
2580 u16 flags = be16_to_cpu(e->flags);
2582 if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) {
2583 WL_CONN("Processing link down\n");
2584 return true;
2586 return false;
2589 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_priv *cfg_priv,
2590 const struct brcmf_event_msg *e)
2592 u32 event = be32_to_cpu(e->event_type);
2593 u32 status = be32_to_cpu(e->status);
2595 if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
2596 WL_CONN("Processing Link %s & no network found\n",
2597 be16_to_cpu(e->flags) & BRCMF_EVENT_MSG_LINK ?
2598 "up" : "down");
2599 return true;
2602 if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
2603 WL_CONN("Processing connecting & no network found\n");
2604 return true;
2607 return false;
2610 static s32
2611 brcmf_notify_connect_status(struct brcmf_cfg80211_priv *cfg_priv,
2612 struct net_device *ndev,
2613 const struct brcmf_event_msg *e, void *data)
2615 s32 err = 0;
2617 if (brcmf_is_linkup(cfg_priv, e)) {
2618 WL_CONN("Linkup\n");
2619 if (brcmf_is_ibssmode(cfg_priv)) {
2620 brcmf_update_prof(cfg_priv, NULL, (void *)e->addr,
2621 WL_PROF_BSSID);
2622 wl_inform_ibss(cfg_priv, ndev, e->addr);
2623 cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
2624 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
2625 set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
2626 } else
2627 brcmf_bss_connect_done(cfg_priv, ndev, e, data, true);
2628 } else if (brcmf_is_linkdown(cfg_priv, e)) {
2629 WL_CONN("Linkdown\n");
2630 if (brcmf_is_ibssmode(cfg_priv)) {
2631 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
2632 if (test_and_clear_bit(WL_STATUS_CONNECTED,
2633 &cfg_priv->status))
2634 brcmf_link_down(cfg_priv);
2635 } else {
2636 brcmf_bss_connect_done(cfg_priv, ndev, e, data, false);
2637 if (test_and_clear_bit(WL_STATUS_CONNECTED,
2638 &cfg_priv->status)) {
2639 cfg80211_disconnected(ndev, 0, NULL, 0,
2640 GFP_KERNEL);
2641 brcmf_link_down(cfg_priv);
2644 brcmf_init_prof(cfg_priv->profile);
2645 } else if (brcmf_is_nonetwork(cfg_priv, e)) {
2646 if (brcmf_is_ibssmode(cfg_priv))
2647 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
2648 else
2649 brcmf_bss_connect_done(cfg_priv, ndev, e, data, false);
2652 return err;
2655 static s32
2656 brcmf_notify_roaming_status(struct brcmf_cfg80211_priv *cfg_priv,
2657 struct net_device *ndev,
2658 const struct brcmf_event_msg *e, void *data)
2660 s32 err = 0;
2661 u32 event = be32_to_cpu(e->event_type);
2662 u32 status = be32_to_cpu(e->status);
2664 if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
2665 if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status))
2666 brcmf_bss_roaming_done(cfg_priv, ndev, e, data);
2667 else
2668 brcmf_bss_connect_done(cfg_priv, ndev, e, data, true);
2671 return err;
2674 static __used s32
2675 brcmf_dev_bufvar_set(struct net_device *dev, s8 *name, s8 *buf, s32 len)
2677 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(dev);
2678 u32 buflen;
2680 buflen = brcmu_mkiovar(name, buf, len, cfg_priv->ioctl_buf,
2681 WL_IOCTL_LEN_MAX);
2682 BUG_ON(!buflen);
2684 return brcmf_dev_ioctl(dev, BRCMF_C_SET_VAR, cfg_priv->ioctl_buf,
2685 buflen);
2688 static s32
2689 brcmf_dev_bufvar_get(struct net_device *dev, s8 *name, s8 *buf,
2690 s32 buf_len)
2692 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(dev);
2693 u32 len;
2694 s32 err = 0;
2696 len = brcmu_mkiovar(name, NULL, 0, cfg_priv->ioctl_buf,
2697 WL_IOCTL_LEN_MAX);
2698 BUG_ON(!len);
2699 err = brcmf_dev_ioctl(dev, BRCMF_C_GET_VAR, (void *)cfg_priv->ioctl_buf,
2700 WL_IOCTL_LEN_MAX);
2701 if (unlikely(err)) {
2702 WL_ERR("error (%d)\n", err);
2703 return err;
2705 memcpy(buf, cfg_priv->ioctl_buf, buf_len);
2707 return err;
2710 static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
2712 struct net_device *ndev = cfg_to_ndev(cfg_priv);
2713 struct brcmf_cfg80211_assoc_ielen *assoc_info;
2714 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2715 u32 req_len;
2716 u32 resp_len;
2717 s32 err = 0;
2719 brcmf_clear_assoc_ies(cfg_priv);
2721 err = brcmf_dev_bufvar_get(ndev, "assoc_info", cfg_priv->extra_buf,
2722 WL_ASSOC_INFO_MAX);
2723 if (unlikely(err)) {
2724 WL_ERR("could not get assoc info (%d)\n", err);
2725 return err;
2727 assoc_info = (struct brcmf_cfg80211_assoc_ielen *)cfg_priv->extra_buf;
2728 req_len = assoc_info->req_len;
2729 resp_len = assoc_info->resp_len;
2730 if (req_len) {
2731 err = brcmf_dev_bufvar_get(ndev, "assoc_req_ies",
2732 cfg_priv->extra_buf,
2733 WL_ASSOC_INFO_MAX);
2734 if (unlikely(err)) {
2735 WL_ERR("could not get assoc req (%d)\n", err);
2736 return err;
2738 conn_info->req_ie_len = req_len;
2739 conn_info->req_ie =
2740 kmemdup(cfg_priv->extra_buf, conn_info->req_ie_len,
2741 GFP_KERNEL);
2742 } else {
2743 conn_info->req_ie_len = 0;
2744 conn_info->req_ie = NULL;
2746 if (resp_len) {
2747 err = brcmf_dev_bufvar_get(ndev, "assoc_resp_ies",
2748 cfg_priv->extra_buf,
2749 WL_ASSOC_INFO_MAX);
2750 if (unlikely(err)) {
2751 WL_ERR("could not get assoc resp (%d)\n", err);
2752 return err;
2754 conn_info->resp_ie_len = resp_len;
2755 conn_info->resp_ie =
2756 kmemdup(cfg_priv->extra_buf, conn_info->resp_ie_len,
2757 GFP_KERNEL);
2758 } else {
2759 conn_info->resp_ie_len = 0;
2760 conn_info->resp_ie = NULL;
2762 WL_CONN("req len (%d) resp len (%d)\n",
2763 conn_info->req_ie_len, conn_info->resp_ie_len);
2765 return err;
2768 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
2770 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2772 kfree(conn_info->req_ie);
2773 conn_info->req_ie = NULL;
2774 conn_info->req_ie_len = 0;
2775 kfree(conn_info->resp_ie);
2776 conn_info->resp_ie = NULL;
2777 conn_info->resp_ie_len = 0;
2781 static void brcmf_ch_to_chanspec(int ch, struct brcmf_join_params *join_params,
2782 size_t *join_params_size)
2784 chanspec_t chanspec = 0;
2786 if (ch != 0) {
2787 join_params->params.chanspec_num = 1;
2788 join_params->params.chanspec_list[0] = ch;
2790 if (join_params->params.chanspec_list[0] <= CH_MAX_2G_CHANNEL)
2791 chanspec |= WL_CHANSPEC_BAND_2G;
2792 else
2793 chanspec |= WL_CHANSPEC_BAND_5G;
2795 chanspec |= WL_CHANSPEC_BW_20;
2796 chanspec |= WL_CHANSPEC_CTL_SB_NONE;
2798 *join_params_size += BRCMF_ASSOC_PARAMS_FIXED_SIZE +
2799 join_params->params.chanspec_num * sizeof(chanspec_t);
2801 join_params->params.chanspec_list[0] &= WL_CHANSPEC_CHAN_MASK;
2802 join_params->params.chanspec_list[0] |= chanspec;
2803 join_params->params.chanspec_list[0] =
2804 cpu_to_le16(join_params->params.chanspec_list[0]);
2806 join_params->params.chanspec_num =
2807 cpu_to_le32(join_params->params.chanspec_num);
2809 WL_CONN("join_params->params.chanspec_list[0]= %#X,"
2810 "channel %d, chanspec %#X\n",
2811 join_params->params.chanspec_list[0], ch, chanspec);
2815 static s32 brcmf_update_bss_info(struct brcmf_cfg80211_priv *cfg_priv)
2817 struct brcmf_bss_info *bi;
2818 struct brcmf_ssid *ssid;
2819 struct brcmu_tlv *tim;
2820 u16 beacon_interval;
2821 u8 dtim_period;
2822 size_t ie_len;
2823 u8 *ie;
2824 s32 err = 0;
2826 WL_TRACE("Enter\n");
2827 if (brcmf_is_ibssmode(cfg_priv))
2828 return err;
2830 ssid = (struct brcmf_ssid *)brcmf_read_prof(cfg_priv, WL_PROF_SSID);
2832 *(u32 *)cfg_priv->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
2833 err = brcmf_dev_ioctl(cfg_to_ndev(cfg_priv), BRCMF_C_GET_BSS_INFO,
2834 cfg_priv->extra_buf, WL_EXTRA_BUF_MAX);
2835 if (unlikely(err)) {
2836 WL_ERR("Could not get bss info %d\n", err);
2837 goto update_bss_info_out;
2840 bi = (struct brcmf_bss_info *)(cfg_priv->extra_buf + 4);
2841 err = brcmf_inform_single_bss(cfg_priv, bi);
2842 if (unlikely(err))
2843 goto update_bss_info_out;
2845 ie = ((u8 *)bi) + bi->ie_offset;
2846 ie_len = bi->ie_length;
2847 beacon_interval = cpu_to_le16(bi->beacon_period);
2849 tim = brcmu_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
2850 if (tim)
2851 dtim_period = tim->data[1];
2852 else {
2854 * active scan was done so we could not get dtim
2855 * information out of probe response.
2856 * so we speficially query dtim information to dongle.
2858 u32 var;
2859 err = brcmf_dev_intvar_get(cfg_to_ndev(cfg_priv),
2860 "dtim_assoc", &var);
2861 if (unlikely(err)) {
2862 WL_ERR("wl dtim_assoc failed (%d)\n", err);
2863 goto update_bss_info_out;
2865 dtim_period = (u8)var;
2868 brcmf_update_prof(cfg_priv, NULL, &beacon_interval, WL_PROF_BEACONINT);
2869 brcmf_update_prof(cfg_priv, NULL, &dtim_period, WL_PROF_DTIMPERIOD);
2871 update_bss_info_out:
2872 WL_TRACE("Exit");
2873 return err;
2876 static s32
2877 brcmf_bss_roaming_done(struct brcmf_cfg80211_priv *cfg_priv,
2878 struct net_device *ndev,
2879 const struct brcmf_event_msg *e, void *data)
2881 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2882 s32 err = 0;
2884 WL_TRACE("Enter\n");
2886 brcmf_get_assoc_ies(cfg_priv);
2887 brcmf_update_prof(cfg_priv, NULL, &e->addr, WL_PROF_BSSID);
2888 brcmf_update_bss_info(cfg_priv);
2890 cfg80211_roamed(ndev, NULL,
2891 (u8 *)brcmf_read_prof(cfg_priv, WL_PROF_BSSID),
2892 conn_info->req_ie, conn_info->req_ie_len,
2893 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
2894 WL_CONN("Report roaming result\n");
2896 set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
2897 WL_TRACE("Exit\n");
2898 return err;
2901 static s32
2902 brcmf_bss_connect_done(struct brcmf_cfg80211_priv *cfg_priv,
2903 struct net_device *ndev, const struct brcmf_event_msg *e,
2904 void *data, bool completed)
2906 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2907 s32 err = 0;
2909 WL_TRACE("Enter\n");
2911 if (test_and_clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) {
2912 if (completed) {
2913 brcmf_get_assoc_ies(cfg_priv);
2914 brcmf_update_prof(cfg_priv, NULL, &e->addr,
2915 WL_PROF_BSSID);
2916 brcmf_update_bss_info(cfg_priv);
2918 cfg80211_connect_result(ndev,
2919 (u8 *)brcmf_read_prof(cfg_priv,
2920 WL_PROF_BSSID),
2921 conn_info->req_ie,
2922 conn_info->req_ie_len,
2923 conn_info->resp_ie,
2924 conn_info->resp_ie_len,
2925 completed ? WLAN_STATUS_SUCCESS :
2926 WLAN_STATUS_AUTH_TIMEOUT,
2927 GFP_KERNEL);
2928 if (completed)
2929 set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
2930 WL_CONN("Report connect result - connection %s\n",
2931 completed ? "succeeded" : "failed");
2933 WL_TRACE("Exit\n");
2934 return err;
2937 static s32
2938 brcmf_notify_mic_status(struct brcmf_cfg80211_priv *cfg_priv,
2939 struct net_device *ndev,
2940 const struct brcmf_event_msg *e, void *data)
2942 u16 flags = be16_to_cpu(e->flags);
2943 enum nl80211_key_type key_type;
2945 rtnl_lock();
2946 if (flags & BRCMF_EVENT_MSG_GROUP)
2947 key_type = NL80211_KEYTYPE_GROUP;
2948 else
2949 key_type = NL80211_KEYTYPE_PAIRWISE;
2951 cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1,
2952 NULL, GFP_KERNEL);
2953 rtnl_unlock();
2955 return 0;
2958 static s32
2959 brcmf_notify_scan_status(struct brcmf_cfg80211_priv *cfg_priv,
2960 struct net_device *ndev,
2961 const struct brcmf_event_msg *e, void *data)
2963 struct brcmf_channel_info channel_inform;
2964 struct brcmf_scan_results *bss_list;
2965 u32 len = WL_SCAN_BUF_MAX;
2966 s32 err = 0;
2967 bool scan_abort = false;
2969 WL_TRACE("Enter\n");
2971 if (cfg_priv->iscan_on && cfg_priv->iscan_kickstart) {
2972 WL_TRACE("Exit\n");
2973 return brcmf_wakeup_iscan(cfg_to_iscan(cfg_priv));
2976 if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING,
2977 &cfg_priv->status))) {
2978 WL_ERR("Scan complete while device not scanning\n");
2979 scan_abort = true;
2980 err = -EINVAL;
2981 goto scan_done_out;
2984 err = brcmf_dev_ioctl(ndev, BRCMF_C_GET_CHANNEL, &channel_inform,
2985 sizeof(channel_inform));
2986 if (unlikely(err)) {
2987 WL_ERR("scan busy (%d)\n", err);
2988 scan_abort = true;
2989 goto scan_done_out;
2991 channel_inform.scan_channel = le32_to_cpu(channel_inform.scan_channel);
2992 if (unlikely(channel_inform.scan_channel)) {
2994 WL_CONN("channel_inform.scan_channel (%d)\n",
2995 channel_inform.scan_channel);
2997 cfg_priv->bss_list = cfg_priv->scan_results;
2998 bss_list = cfg_priv->bss_list;
2999 memset(bss_list, 0, len);
3000 bss_list->buflen = cpu_to_le32(len);
3002 err = brcmf_dev_ioctl(ndev, BRCMF_C_SCAN_RESULTS, bss_list, len);
3003 if (unlikely(err)) {
3004 WL_ERR("%s Scan_results error (%d)\n", ndev->name, err);
3005 err = -EINVAL;
3006 scan_abort = true;
3007 goto scan_done_out;
3009 bss_list->buflen = le32_to_cpu(bss_list->buflen);
3010 bss_list->version = le32_to_cpu(bss_list->version);
3011 bss_list->count = le32_to_cpu(bss_list->count);
3013 err = brcmf_inform_bss(cfg_priv);
3014 if (err) {
3015 scan_abort = true;
3016 goto scan_done_out;
3019 scan_done_out:
3020 if (cfg_priv->scan_request) {
3021 WL_SCAN("calling cfg80211_scan_done\n");
3022 cfg80211_scan_done(cfg_priv->scan_request, scan_abort);
3023 brcmf_set_mpc(ndev, 1);
3024 cfg_priv->scan_request = NULL;
3027 WL_TRACE("Exit\n");
3029 return err;
3032 static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
3034 conf->mode = (u32)-1;
3035 conf->frag_threshold = (u32)-1;
3036 conf->rts_threshold = (u32)-1;
3037 conf->retry_short = (u32)-1;
3038 conf->retry_long = (u32)-1;
3039 conf->tx_power = -1;
3042 static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof)
3044 memset(prof, 0, sizeof(*prof));
3047 static void brcmf_init_eloop_handler(struct brcmf_cfg80211_event_loop *el)
3049 memset(el, 0, sizeof(*el));
3050 el->handler[BRCMF_E_SCAN_COMPLETE] = brcmf_notify_scan_status;
3051 el->handler[BRCMF_E_LINK] = brcmf_notify_connect_status;
3052 el->handler[BRCMF_E_ROAM] = brcmf_notify_roaming_status;
3053 el->handler[BRCMF_E_MIC_ERROR] = brcmf_notify_mic_status;
3054 el->handler[BRCMF_E_SET_SSID] = brcmf_notify_connect_status;
3057 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
3059 cfg_priv->scan_results = kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
3060 if (unlikely(!cfg_priv->scan_results)) {
3061 WL_ERR("Scan results alloc failed\n");
3062 goto init_priv_mem_out;
3064 cfg_priv->conf = kzalloc(sizeof(*cfg_priv->conf), GFP_KERNEL);
3065 if (unlikely(!cfg_priv->conf)) {
3066 WL_ERR("wl_conf alloc failed\n");
3067 goto init_priv_mem_out;
3069 cfg_priv->profile = kzalloc(sizeof(*cfg_priv->profile), GFP_KERNEL);
3070 if (unlikely(!cfg_priv->profile)) {
3071 WL_ERR("wl_profile alloc failed\n");
3072 goto init_priv_mem_out;
3074 cfg_priv->bss_info = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
3075 if (unlikely(!cfg_priv->bss_info)) {
3076 WL_ERR("Bss information alloc failed\n");
3077 goto init_priv_mem_out;
3079 cfg_priv->scan_req_int = kzalloc(sizeof(*cfg_priv->scan_req_int),
3080 GFP_KERNEL);
3081 if (unlikely(!cfg_priv->scan_req_int)) {
3082 WL_ERR("Scan req alloc failed\n");
3083 goto init_priv_mem_out;
3085 cfg_priv->ioctl_buf = kzalloc(WL_IOCTL_LEN_MAX, GFP_KERNEL);
3086 if (unlikely(!cfg_priv->ioctl_buf)) {
3087 WL_ERR("Ioctl buf alloc failed\n");
3088 goto init_priv_mem_out;
3090 cfg_priv->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
3091 if (unlikely(!cfg_priv->extra_buf)) {
3092 WL_ERR("Extra buf alloc failed\n");
3093 goto init_priv_mem_out;
3095 cfg_priv->iscan = kzalloc(sizeof(*cfg_priv->iscan), GFP_KERNEL);
3096 if (unlikely(!cfg_priv->iscan)) {
3097 WL_ERR("Iscan buf alloc failed\n");
3098 goto init_priv_mem_out;
3100 cfg_priv->pmk_list = kzalloc(sizeof(*cfg_priv->pmk_list), GFP_KERNEL);
3101 if (unlikely(!cfg_priv->pmk_list)) {
3102 WL_ERR("pmk list alloc failed\n");
3103 goto init_priv_mem_out;
3106 return 0;
3108 init_priv_mem_out:
3109 brcmf_deinit_priv_mem(cfg_priv);
3111 return -ENOMEM;
3114 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
3116 kfree(cfg_priv->scan_results);
3117 cfg_priv->scan_results = NULL;
3118 kfree(cfg_priv->bss_info);
3119 cfg_priv->bss_info = NULL;
3120 kfree(cfg_priv->conf);
3121 cfg_priv->conf = NULL;
3122 kfree(cfg_priv->profile);
3123 cfg_priv->profile = NULL;
3124 kfree(cfg_priv->scan_req_int);
3125 cfg_priv->scan_req_int = NULL;
3126 kfree(cfg_priv->ioctl_buf);
3127 cfg_priv->ioctl_buf = NULL;
3128 kfree(cfg_priv->extra_buf);
3129 cfg_priv->extra_buf = NULL;
3130 kfree(cfg_priv->iscan);
3131 cfg_priv->iscan = NULL;
3132 kfree(cfg_priv->pmk_list);
3133 cfg_priv->pmk_list = NULL;
3136 static s32 brcmf_create_event_handler(struct brcmf_cfg80211_priv *cfg_priv)
3138 sema_init(&cfg_priv->event_sync, 0);
3139 cfg_priv->event_tsk = kthread_run(brcmf_event_handler, cfg_priv,
3140 "wl_event_handler");
3141 if (IS_ERR(cfg_priv->event_tsk)) {
3142 cfg_priv->event_tsk = NULL;
3143 WL_ERR("failed to create event thread\n");
3144 return -ENOMEM;
3146 return 0;
3149 static void brcmf_destroy_event_handler(struct brcmf_cfg80211_priv *cfg_priv)
3151 if (cfg_priv->event_tsk) {
3152 send_sig(SIGTERM, cfg_priv->event_tsk, 1);
3153 kthread_stop(cfg_priv->event_tsk);
3154 cfg_priv->event_tsk = NULL;
3158 static void brcmf_term_iscan(struct brcmf_cfg80211_priv *cfg_priv)
3160 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
3162 if (cfg_priv->iscan_on && iscan->tsk) {
3163 iscan->state = WL_ISCAN_STATE_IDLE;
3164 send_sig(SIGTERM, iscan->tsk, 1);
3165 kthread_stop(iscan->tsk);
3166 iscan->tsk = NULL;
3170 static void brcmf_notify_iscan_complete(struct brcmf_cfg80211_iscan_ctrl *iscan,
3171 bool aborted)
3173 struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan);
3174 struct net_device *ndev = cfg_to_ndev(cfg_priv);
3176 if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING,
3177 &cfg_priv->status))) {
3178 WL_ERR("Scan complete while device not scanning\n");
3179 return;
3181 if (likely(cfg_priv->scan_request)) {
3182 WL_SCAN("ISCAN Completed scan: %s\n",
3183 aborted ? "Aborted" : "Done");
3184 cfg80211_scan_done(cfg_priv->scan_request, aborted);
3185 brcmf_set_mpc(ndev, 1);
3186 cfg_priv->scan_request = NULL;
3188 cfg_priv->iscan_kickstart = false;
3191 static s32 brcmf_wakeup_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan)
3193 if (likely(iscan->state != WL_ISCAN_STATE_IDLE)) {
3194 WL_SCAN("wake up iscan\n");
3195 up(&iscan->sync);
3196 return 0;
3199 return -EIO;
3202 static s32
3203 brcmf_get_iscan_results(struct brcmf_cfg80211_iscan_ctrl *iscan, u32 *status,
3204 struct brcmf_scan_results **bss_list)
3206 struct brcmf_iscan_results list;
3207 struct brcmf_scan_results *results;
3208 struct brcmf_iscan_results *list_buf;
3209 s32 err = 0;
3211 memset(iscan->scan_buf, 0, WL_ISCAN_BUF_MAX);
3212 list_buf = (struct brcmf_iscan_results *)iscan->scan_buf;
3213 results = &list_buf->results;
3214 results->buflen = BRCMF_ISCAN_RESULTS_FIXED_SIZE;
3215 results->version = 0;
3216 results->count = 0;
3218 memset(&list, 0, sizeof(list));
3219 list.results.buflen = cpu_to_le32(WL_ISCAN_BUF_MAX);
3220 err = brcmf_dev_iovar_getbuf(iscan->dev, "iscanresults", &list,
3221 BRCMF_ISCAN_RESULTS_FIXED_SIZE, iscan->scan_buf,
3222 WL_ISCAN_BUF_MAX);
3223 if (unlikely(err)) {
3224 WL_ERR("error (%d)\n", err);
3225 return err;
3227 results->buflen = le32_to_cpu(results->buflen);
3228 results->version = le32_to_cpu(results->version);
3229 results->count = le32_to_cpu(results->count);
3230 WL_SCAN("results->count = %d\n", results->count);
3231 WL_SCAN("results->buflen = %d\n", results->buflen);
3232 *status = le32_to_cpu(list_buf->status);
3233 *bss_list = results;
3235 return err;
3238 static s32 brcmf_iscan_done(struct brcmf_cfg80211_priv *cfg_priv)
3240 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
3241 s32 err = 0;
3243 iscan->state = WL_ISCAN_STATE_IDLE;
3244 rtnl_lock();
3245 brcmf_inform_bss(cfg_priv);
3246 brcmf_notify_iscan_complete(iscan, false);
3247 rtnl_unlock();
3249 return err;
3252 static s32 brcmf_iscan_pending(struct brcmf_cfg80211_priv *cfg_priv)
3254 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
3255 s32 err = 0;
3257 /* Reschedule the timer */
3258 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
3259 iscan->timer_on = 1;
3261 return err;
3264 static s32 brcmf_iscan_inprogress(struct brcmf_cfg80211_priv *cfg_priv)
3266 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
3267 s32 err = 0;
3269 rtnl_lock();
3270 brcmf_inform_bss(cfg_priv);
3271 brcmf_run_iscan(iscan, NULL, BRCMF_SCAN_ACTION_CONTINUE);
3272 rtnl_unlock();
3273 /* Reschedule the timer */
3274 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
3275 iscan->timer_on = 1;
3277 return err;
3280 static s32 brcmf_iscan_aborted(struct brcmf_cfg80211_priv *cfg_priv)
3282 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
3283 s32 err = 0;
3285 iscan->state = WL_ISCAN_STATE_IDLE;
3286 rtnl_lock();
3287 brcmf_notify_iscan_complete(iscan, true);
3288 rtnl_unlock();
3290 return err;
3293 static s32 brcmf_iscan_thread(void *data)
3295 struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1 };
3296 struct brcmf_cfg80211_iscan_ctrl *iscan =
3297 (struct brcmf_cfg80211_iscan_ctrl *)data;
3298 struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan);
3299 struct brcmf_cfg80211_iscan_eloop *el = &iscan->el;
3300 u32 status;
3301 int err = 0;
3303 sched_setscheduler(current, SCHED_FIFO, &param);
3304 allow_signal(SIGTERM);
3305 status = BRCMF_SCAN_RESULTS_PARTIAL;
3306 while (likely(!down_interruptible(&iscan->sync))) {
3307 if (kthread_should_stop())
3308 break;
3309 if (iscan->timer_on) {
3310 del_timer_sync(&iscan->timer);
3311 iscan->timer_on = 0;
3313 rtnl_lock();
3314 err = brcmf_get_iscan_results(iscan, &status,
3315 &cfg_priv->bss_list);
3316 if (unlikely(err)) {
3317 status = BRCMF_SCAN_RESULTS_ABORTED;
3318 WL_ERR("Abort iscan\n");
3320 rtnl_unlock();
3321 el->handler[status](cfg_priv);
3323 if (iscan->timer_on) {
3324 del_timer_sync(&iscan->timer);
3325 iscan->timer_on = 0;
3327 WL_SCAN("ISCAN thread terminated\n");
3329 return 0;
3332 static void brcmf_iscan_timer(unsigned long data)
3334 struct brcmf_cfg80211_iscan_ctrl *iscan =
3335 (struct brcmf_cfg80211_iscan_ctrl *)data;
3337 if (iscan) {
3338 iscan->timer_on = 0;
3339 WL_SCAN("timer expired\n");
3340 brcmf_wakeup_iscan(iscan);
3344 static s32 brcmf_invoke_iscan(struct brcmf_cfg80211_priv *cfg_priv)
3346 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
3347 int err = 0;
3349 if (cfg_priv->iscan_on && !iscan->tsk) {
3350 iscan->state = WL_ISCAN_STATE_IDLE;
3351 sema_init(&iscan->sync, 0);
3352 iscan->tsk = kthread_run(brcmf_iscan_thread, iscan, "wl_iscan");
3353 if (IS_ERR(iscan->tsk)) {
3354 WL_ERR("Could not create iscan thread\n");
3355 iscan->tsk = NULL;
3356 return -ENOMEM;
3360 return err;
3363 static void brcmf_init_iscan_eloop(struct brcmf_cfg80211_iscan_eloop *el)
3365 memset(el, 0, sizeof(*el));
3366 el->handler[BRCMF_SCAN_RESULTS_SUCCESS] = brcmf_iscan_done;
3367 el->handler[BRCMF_SCAN_RESULTS_PARTIAL] = brcmf_iscan_inprogress;
3368 el->handler[BRCMF_SCAN_RESULTS_PENDING] = brcmf_iscan_pending;
3369 el->handler[BRCMF_SCAN_RESULTS_ABORTED] = brcmf_iscan_aborted;
3370 el->handler[BRCMF_SCAN_RESULTS_NO_MEM] = brcmf_iscan_aborted;
3373 static s32 brcmf_init_iscan(struct brcmf_cfg80211_priv *cfg_priv)
3375 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
3376 int err = 0;
3378 if (cfg_priv->iscan_on) {
3379 iscan->dev = cfg_to_ndev(cfg_priv);
3380 iscan->state = WL_ISCAN_STATE_IDLE;
3381 brcmf_init_iscan_eloop(&iscan->el);
3382 iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS;
3383 init_timer(&iscan->timer);
3384 iscan->timer.data = (unsigned long) iscan;
3385 iscan->timer.function = brcmf_iscan_timer;
3386 sema_init(&iscan->sync, 0);
3387 iscan->tsk = kthread_run(brcmf_iscan_thread, iscan, "wl_iscan");
3388 if (IS_ERR(iscan->tsk)) {
3389 WL_ERR("Could not create iscan thread\n");
3390 iscan->tsk = NULL;
3391 return -ENOMEM;
3393 iscan->data = cfg_priv;
3396 return err;
3399 static s32 wl_init_priv(struct brcmf_cfg80211_priv *cfg_priv)
3401 struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
3402 s32 err = 0;
3404 cfg_priv->scan_request = NULL;
3405 cfg_priv->pwr_save = !!(wiphy->flags & WIPHY_FLAG_PS_ON_BY_DEFAULT);
3406 cfg_priv->iscan_on = true; /* iscan on & off switch.
3407 we enable iscan per default */
3408 cfg_priv->roam_on = false; /* roam on & off switch.
3409 we enable roam per default */
3411 cfg_priv->iscan_kickstart = false;
3412 cfg_priv->active_scan = true; /* we do active scan for
3413 specific scan per default */
3414 cfg_priv->dongle_up = false; /* dongle is not up yet */
3415 brcmf_init_eq(cfg_priv);
3416 err = brcmf_init_priv_mem(cfg_priv);
3417 if (unlikely(err))
3418 return err;
3419 if (unlikely(brcmf_create_event_handler(cfg_priv)))
3420 return -ENOMEM;
3421 brcmf_init_eloop_handler(&cfg_priv->el);
3422 mutex_init(&cfg_priv->usr_sync);
3423 err = brcmf_init_iscan(cfg_priv);
3424 if (unlikely(err))
3425 return err;
3426 brcmf_init_conf(cfg_priv->conf);
3427 brcmf_init_prof(cfg_priv->profile);
3428 brcmf_link_down(cfg_priv);
3430 return err;
3433 static void wl_deinit_priv(struct brcmf_cfg80211_priv *cfg_priv)
3435 brcmf_destroy_event_handler(cfg_priv);
3436 cfg_priv->dongle_up = false; /* dongle down */
3437 brcmf_flush_eq(cfg_priv);
3438 brcmf_link_down(cfg_priv);
3439 brcmf_term_iscan(cfg_priv);
3440 brcmf_deinit_priv_mem(cfg_priv);
3443 s32 brcmf_cfg80211_attach(struct net_device *ndev, void *data)
3445 struct wireless_dev *wdev;
3446 struct brcmf_cfg80211_priv *cfg_priv;
3447 struct brcmf_cfg80211_iface *ci;
3448 s32 err = 0;
3450 if (unlikely(!ndev)) {
3451 WL_ERR("ndev is invalid\n");
3452 return -ENODEV;
3454 cfg80211_dev = kzalloc(sizeof(struct brcmf_cfg80211_dev), GFP_KERNEL);
3455 if (unlikely(!cfg80211_dev)) {
3456 WL_ERR("wl_cfg80211_dev is invalid\n");
3457 return -ENOMEM;
3459 WL_INFO("func %p\n", brcmf_cfg80211_get_sdio_func());
3460 wdev = brcmf_alloc_wdev(sizeof(struct brcmf_cfg80211_iface),
3461 &brcmf_cfg80211_get_sdio_func()->dev);
3462 if (IS_ERR(wdev))
3463 return -ENOMEM;
3465 wdev->iftype = brcmf_mode_to_nl80211_iftype(WL_MODE_BSS);
3466 cfg_priv = wdev_to_cfg(wdev);
3467 cfg_priv->wdev = wdev;
3468 cfg_priv->pub = data;
3469 ci = (struct brcmf_cfg80211_iface *)&cfg_priv->ci;
3470 ci->cfg_priv = cfg_priv;
3471 ndev->ieee80211_ptr = wdev;
3472 SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
3473 wdev->netdev = ndev;
3474 err = wl_init_priv(cfg_priv);
3475 if (unlikely(err)) {
3476 WL_ERR("Failed to init iwm_priv (%d)\n", err);
3477 goto cfg80211_attach_out;
3479 brcmf_set_drvdata(cfg80211_dev, ci);
3481 return err;
3483 cfg80211_attach_out:
3484 brcmf_free_wdev(cfg_priv);
3485 return err;
3488 void brcmf_cfg80211_detach(void)
3490 struct brcmf_cfg80211_priv *cfg_priv;
3492 cfg_priv = WL_PRIV_GET();
3494 wl_deinit_priv(cfg_priv);
3495 brcmf_free_wdev(cfg_priv);
3496 brcmf_set_drvdata(cfg80211_dev, NULL);
3497 kfree(cfg80211_dev);
3498 cfg80211_dev = NULL;
3499 brcmf_clear_sdio_func();
3502 static void brcmf_wakeup_event(struct brcmf_cfg80211_priv *cfg_priv)
3504 up(&cfg_priv->event_sync);
3507 static s32 brcmf_event_handler(void *data)
3509 struct brcmf_cfg80211_priv *cfg_priv =
3510 (struct brcmf_cfg80211_priv *)data;
3511 struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1 };
3512 struct brcmf_cfg80211_event_q *e;
3514 sched_setscheduler(current, SCHED_FIFO, &param);
3515 allow_signal(SIGTERM);
3516 while (likely(!down_interruptible(&cfg_priv->event_sync))) {
3517 if (kthread_should_stop())
3518 break;
3519 e = brcmf_deq_event(cfg_priv);
3520 if (unlikely(!e)) {
3521 WL_ERR("event queue empty...\n");
3522 BUG();
3524 WL_INFO("event type (%d)\n", e->etype);
3525 if (cfg_priv->el.handler[e->etype]) {
3526 cfg_priv->el.handler[e->etype](cfg_priv,
3527 cfg_to_ndev(cfg_priv),
3528 &e->emsg, e->edata);
3529 } else {
3530 WL_INFO("Unknown Event (%d): ignoring\n", e->etype);
3532 brcmf_put_event(e);
3534 WL_INFO("was terminated\n");
3535 return 0;
3538 void
3539 brcmf_cfg80211_event(struct net_device *ndev,
3540 const struct brcmf_event_msg *e, void *data)
3542 u32 event_type = be32_to_cpu(e->event_type);
3543 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
3545 if (likely(!brcmf_enq_event(cfg_priv, event_type, e, data)))
3546 brcmf_wakeup_event(cfg_priv);
3549 static void brcmf_init_eq(struct brcmf_cfg80211_priv *cfg_priv)
3551 brcmf_init_eq_lock(cfg_priv);
3552 INIT_LIST_HEAD(&cfg_priv->eq_list);
3555 static void brcmf_flush_eq(struct brcmf_cfg80211_priv *cfg_priv)
3557 struct brcmf_cfg80211_event_q *e;
3559 brcmf_lock_eq(cfg_priv);
3560 while (!list_empty(&cfg_priv->eq_list)) {
3561 e = list_first_entry(&cfg_priv->eq_list,
3562 struct brcmf_cfg80211_event_q, eq_list);
3563 list_del(&e->eq_list);
3564 kfree(e);
3566 brcmf_unlock_eq(cfg_priv);
3570 * retrieve first queued event from head
3573 static struct brcmf_cfg80211_event_q *brcmf_deq_event(
3574 struct brcmf_cfg80211_priv *cfg_priv)
3576 struct brcmf_cfg80211_event_q *e = NULL;
3578 brcmf_lock_eq(cfg_priv);
3579 if (likely(!list_empty(&cfg_priv->eq_list))) {
3580 e = list_first_entry(&cfg_priv->eq_list,
3581 struct brcmf_cfg80211_event_q, eq_list);
3582 list_del(&e->eq_list);
3584 brcmf_unlock_eq(cfg_priv);
3586 return e;
3590 ** push event to tail of the queue
3593 static s32
3594 brcmf_enq_event(struct brcmf_cfg80211_priv *cfg_priv, u32 event,
3595 const struct brcmf_event_msg *msg, void *data)
3597 struct brcmf_cfg80211_event_q *e;
3598 s32 err = 0;
3600 e = kzalloc(sizeof(struct brcmf_cfg80211_event_q), GFP_KERNEL);
3601 if (unlikely(!e)) {
3602 WL_ERR("event alloc failed\n");
3603 return -ENOMEM;
3606 e->etype = event;
3607 memcpy(&e->emsg, msg, sizeof(struct brcmf_event_msg));
3609 brcmf_lock_eq(cfg_priv);
3610 list_add_tail(&e->eq_list, &cfg_priv->eq_list);
3611 brcmf_unlock_eq(cfg_priv);
3613 return err;
3616 static void brcmf_put_event(struct brcmf_cfg80211_event_q *e)
3618 kfree(e);
3621 void brcmf_cfg80211_sdio_func(void *func)
3623 cfg80211_sdio_func = (struct sdio_func *)func;
3626 static void brcmf_clear_sdio_func(void)
3628 cfg80211_sdio_func = NULL;
3631 struct sdio_func *brcmf_cfg80211_get_sdio_func(void)
3633 return cfg80211_sdio_func;
3636 static s32 brcmf_dongle_mode(struct net_device *ndev, s32 iftype)
3638 s32 infra = 0;
3639 s32 err = 0;
3641 switch (iftype) {
3642 case NL80211_IFTYPE_MONITOR:
3643 case NL80211_IFTYPE_WDS:
3644 WL_ERR("type (%d) : currently we do not support this mode\n",
3645 iftype);
3646 err = -EINVAL;
3647 return err;
3648 case NL80211_IFTYPE_ADHOC:
3649 infra = 0;
3650 break;
3651 case NL80211_IFTYPE_STATION:
3652 infra = 1;
3653 break;
3654 default:
3655 err = -EINVAL;
3656 WL_ERR("invalid type (%d)\n", iftype);
3657 return err;
3659 infra = cpu_to_le32(infra);
3660 err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_INFRA, &infra, sizeof(infra));
3661 if (unlikely(err)) {
3662 WL_ERR("WLC_SET_INFRA error (%d)\n", err);
3663 return err;
3666 return 0;
3669 static s32 brcmf_dongle_eventmsg(struct net_device *ndev)
3671 /* Room for "event_msgs" + '\0' + bitvec */
3672 s8 iovbuf[BRCMF_EVENTING_MASK_LEN + 12];
3673 s8 eventmask[BRCMF_EVENTING_MASK_LEN];
3674 s32 err = 0;
3676 WL_TRACE("Enter\n");
3678 /* Setup event_msgs */
3679 brcmu_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN, iovbuf,
3680 sizeof(iovbuf));
3681 err = brcmf_dev_ioctl(ndev, BRCMF_C_GET_VAR, iovbuf, sizeof(iovbuf));
3682 if (unlikely(err)) {
3683 WL_ERR("Get event_msgs error (%d)\n", err);
3684 goto dongle_eventmsg_out;
3686 memcpy(eventmask, iovbuf, BRCMF_EVENTING_MASK_LEN);
3688 setbit(eventmask, BRCMF_E_SET_SSID);
3689 setbit(eventmask, BRCMF_E_ROAM);
3690 setbit(eventmask, BRCMF_E_PRUNE);
3691 setbit(eventmask, BRCMF_E_AUTH);
3692 setbit(eventmask, BRCMF_E_REASSOC);
3693 setbit(eventmask, BRCMF_E_REASSOC_IND);
3694 setbit(eventmask, BRCMF_E_DEAUTH_IND);
3695 setbit(eventmask, BRCMF_E_DISASSOC_IND);
3696 setbit(eventmask, BRCMF_E_DISASSOC);
3697 setbit(eventmask, BRCMF_E_JOIN);
3698 setbit(eventmask, BRCMF_E_ASSOC_IND);
3699 setbit(eventmask, BRCMF_E_PSK_SUP);
3700 setbit(eventmask, BRCMF_E_LINK);
3701 setbit(eventmask, BRCMF_E_NDIS_LINK);
3702 setbit(eventmask, BRCMF_E_MIC_ERROR);
3703 setbit(eventmask, BRCMF_E_PMKID_CACHE);
3704 setbit(eventmask, BRCMF_E_TXFAIL);
3705 setbit(eventmask, BRCMF_E_JOIN_START);
3706 setbit(eventmask, BRCMF_E_SCAN_COMPLETE);
3708 brcmu_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN, iovbuf,
3709 sizeof(iovbuf));
3710 err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
3711 if (unlikely(err)) {
3712 WL_ERR("Set event_msgs error (%d)\n", err);
3713 goto dongle_eventmsg_out;
3716 dongle_eventmsg_out:
3717 WL_TRACE("Exit\n");
3718 return err;
3721 static s32
3722 brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
3724 s8 iovbuf[32];
3725 s32 roamtrigger[2];
3726 s32 roam_delta[2];
3727 s32 err = 0;
3730 * Setup timeout if Beacons are lost and roam is
3731 * off to report link down
3733 if (roamvar) {
3734 brcmu_mkiovar("bcn_timeout", (char *)&bcn_timeout,
3735 sizeof(bcn_timeout), iovbuf, sizeof(iovbuf));
3736 err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_VAR,
3737 iovbuf, sizeof(iovbuf));
3738 if (unlikely(err)) {
3739 WL_ERR("bcn_timeout error (%d)\n", err);
3740 goto dongle_rom_out;
3745 * Enable/Disable built-in roaming to allow supplicant
3746 * to take care of roaming
3748 WL_INFO("Internal Roaming = %s\n", roamvar ? "Off" : "On");
3749 brcmu_mkiovar("roam_off", (char *)&roamvar,
3750 sizeof(roamvar), iovbuf, sizeof(iovbuf));
3751 err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
3752 if (unlikely(err)) {
3753 WL_ERR("roam_off error (%d)\n", err);
3754 goto dongle_rom_out;
3757 roamtrigger[0] = WL_ROAM_TRIGGER_LEVEL;
3758 roamtrigger[1] = WLC_BAND_ALL;
3759 err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_ROAM_TRIGGER,
3760 (void *)roamtrigger, sizeof(roamtrigger));
3761 if (unlikely(err)) {
3762 WL_ERR("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
3763 goto dongle_rom_out;
3766 roam_delta[0] = WL_ROAM_DELTA;
3767 roam_delta[1] = WLC_BAND_ALL;
3768 err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_ROAM_DELTA,
3769 (void *)roam_delta, sizeof(roam_delta));
3770 if (unlikely(err)) {
3771 WL_ERR("WLC_SET_ROAM_DELTA error (%d)\n", err);
3772 goto dongle_rom_out;
3775 dongle_rom_out:
3776 return err;
3779 static s32
3780 brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
3781 s32 scan_unassoc_time, s32 scan_passive_time)
3783 s32 err = 0;
3785 err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_SCAN_CHANNEL_TIME,
3786 &scan_assoc_time, sizeof(scan_assoc_time));
3787 if (err) {
3788 if (err == -EOPNOTSUPP)
3789 WL_INFO("Scan assoc time is not supported\n");
3790 else
3791 WL_ERR("Scan assoc time error (%d)\n", err);
3792 goto dongle_scantime_out;
3794 err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_SCAN_UNASSOC_TIME,
3795 &scan_unassoc_time, sizeof(scan_unassoc_time));
3796 if (err) {
3797 if (err == -EOPNOTSUPP)
3798 WL_INFO("Scan unassoc time is not supported\n");
3799 else
3800 WL_ERR("Scan unassoc time error (%d)\n", err);
3801 goto dongle_scantime_out;
3804 err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_SCAN_PASSIVE_TIME,
3805 &scan_passive_time, sizeof(scan_passive_time));
3806 if (err) {
3807 if (err == -EOPNOTSUPP)
3808 WL_INFO("Scan passive time is not supported\n");
3809 else
3810 WL_ERR("Scan passive time error (%d)\n", err);
3811 goto dongle_scantime_out;
3814 dongle_scantime_out:
3815 return err;
3818 s32 brcmf_config_dongle(struct brcmf_cfg80211_priv *cfg_priv, bool need_lock)
3820 struct net_device *ndev;
3821 struct wireless_dev *wdev;
3822 s32 err = 0;
3824 if (cfg_priv->dongle_up)
3825 return err;
3827 ndev = cfg_to_ndev(cfg_priv);
3828 wdev = ndev->ieee80211_ptr;
3829 if (need_lock)
3830 rtnl_lock();
3832 brcmf_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME,
3833 WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
3835 err = brcmf_dongle_eventmsg(ndev);
3836 if (unlikely(err))
3837 goto default_conf_out;
3838 err = brcmf_dongle_roam(ndev, (cfg_priv->roam_on ? 0 : 1),
3839 WL_BEACON_TIMEOUT);
3840 if (unlikely(err))
3841 goto default_conf_out;
3842 err = brcmf_dongle_mode(ndev, wdev->iftype);
3843 if (unlikely(err && err != -EINPROGRESS))
3844 goto default_conf_out;
3845 err = brcmf_dongle_probecap(cfg_priv);
3846 if (unlikely(err))
3847 goto default_conf_out;
3849 /* -EINPROGRESS: Call commit handler */
3851 default_conf_out:
3852 if (need_lock)
3853 rtnl_unlock();
3855 cfg_priv->dongle_up = true;
3857 return err;
3861 static s32 wl_update_wiphybands(struct brcmf_cfg80211_priv *cfg_priv)
3863 struct wiphy *wiphy;
3864 s32 phy_list;
3865 s8 phy;
3866 s32 err = 0;
3868 err = brcmf_dev_ioctl(cfg_to_ndev(cfg_priv), WLC_GET_PHYLIST, &phy_list,
3869 sizeof(phy_list));
3870 if (unlikely(err)) {
3871 WL_ERR("error (%d)\n", err);
3872 return err;
3875 phy = ((char *)&phy_list)[1];
3876 WL_INFO("%c phy\n", phy);
3877 if (phy == 'n' || phy == 'a') {
3878 wiphy = cfg_to_wiphy(cfg_priv);
3879 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
3882 return err;
3885 static s32 __brcmf_cfg80211_up(struct brcmf_cfg80211_priv *cfg_priv)
3887 s32 err = 0;
3889 set_bit(WL_STATUS_READY, &cfg_priv->status);
3891 brcmf_debugfs_add_netdev_params(cfg_priv);
3893 err = brcmf_config_dongle(cfg_priv, false);
3894 if (unlikely(err))
3895 return err;
3897 brcmf_invoke_iscan(cfg_priv);
3899 return err;
3902 static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_priv *cfg_priv)
3905 * While going down, if associated with AP disassociate
3906 * from AP to save power
3908 if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) ||
3909 test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) &&
3910 test_bit(WL_STATUS_READY, &cfg_priv->status)) {
3911 WL_INFO("Disassociating from AP");
3912 brcmf_link_down(cfg_priv);
3914 /* Make sure WPA_Supplicant receives all the event
3915 generated due to DISASSOC call to the fw to keep
3916 the state fw and WPA_Supplicant state consistent
3918 rtnl_unlock();
3919 brcmf_delay(500);
3920 rtnl_lock();
3923 set_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
3924 brcmf_term_iscan(cfg_priv);
3925 if (cfg_priv->scan_request) {
3926 cfg80211_scan_done(cfg_priv->scan_request, true);
3927 /* May need to perform this to cover rmmod */
3928 /* wl_set_mpc(cfg_to_ndev(wl), 1); */
3929 cfg_priv->scan_request = NULL;
3931 clear_bit(WL_STATUS_READY, &cfg_priv->status);
3932 clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
3933 clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
3935 brcmf_debugfs_remove_netdev(cfg_priv);
3937 return 0;
3940 s32 brcmf_cfg80211_up(void)
3942 struct brcmf_cfg80211_priv *cfg_priv;
3943 s32 err = 0;
3945 cfg_priv = WL_PRIV_GET();
3946 mutex_lock(&cfg_priv->usr_sync);
3947 err = __brcmf_cfg80211_up(cfg_priv);
3948 mutex_unlock(&cfg_priv->usr_sync);
3950 return err;
3953 s32 brcmf_cfg80211_down(void)
3955 struct brcmf_cfg80211_priv *cfg_priv;
3956 s32 err = 0;
3958 cfg_priv = WL_PRIV_GET();
3959 mutex_lock(&cfg_priv->usr_sync);
3960 err = __brcmf_cfg80211_down(cfg_priv);
3961 mutex_unlock(&cfg_priv->usr_sync);
3963 return err;
3966 static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_priv *cfg_priv)
3968 return wl_update_wiphybands(cfg_priv);
3971 static void *brcmf_read_prof(struct brcmf_cfg80211_priv *cfg_priv, s32 item)
3973 switch (item) {
3974 case WL_PROF_SEC:
3975 return &cfg_priv->profile->sec;
3976 case WL_PROF_BSSID:
3977 return &cfg_priv->profile->bssid;
3978 case WL_PROF_SSID:
3979 return &cfg_priv->profile->ssid;
3981 WL_ERR("invalid item (%d)\n", item);
3982 return NULL;
3985 static s32
3986 brcmf_update_prof(struct brcmf_cfg80211_priv *cfg_priv,
3987 const struct brcmf_event_msg *e, void *data, s32 item)
3989 s32 err = 0;
3990 struct brcmf_ssid *ssid;
3992 switch (item) {
3993 case WL_PROF_SSID:
3994 ssid = (struct brcmf_ssid *) data;
3995 memset(cfg_priv->profile->ssid.SSID, 0,
3996 sizeof(cfg_priv->profile->ssid.SSID));
3997 memcpy(cfg_priv->profile->ssid.SSID,
3998 ssid->SSID, ssid->SSID_len);
3999 cfg_priv->profile->ssid.SSID_len = ssid->SSID_len;
4000 break;
4001 case WL_PROF_BSSID:
4002 if (data)
4003 memcpy(cfg_priv->profile->bssid, data, ETH_ALEN);
4004 else
4005 memset(cfg_priv->profile->bssid, 0, ETH_ALEN);
4006 break;
4007 case WL_PROF_SEC:
4008 memcpy(&cfg_priv->profile->sec, data,
4009 sizeof(cfg_priv->profile->sec));
4010 break;
4011 case WL_PROF_BEACONINT:
4012 cfg_priv->profile->beacon_interval = *(u16 *)data;
4013 break;
4014 case WL_PROF_DTIMPERIOD:
4015 cfg_priv->profile->dtim_period = *(u8 *)data;
4016 break;
4017 default:
4018 WL_ERR("unsupported item (%d)\n", item);
4019 err = -EOPNOTSUPP;
4020 break;
4023 return err;
4026 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_priv *cfg_priv)
4028 return cfg_priv->conf->mode == WL_MODE_IBSS;
4031 static __used s32 brcmf_add_ie(struct brcmf_cfg80211_priv *cfg_priv,
4032 u8 t, u8 l, u8 *v)
4034 struct brcmf_cfg80211_ie *ie = &cfg_priv->ie;
4035 s32 err = 0;
4037 if (unlikely(ie->offset + l + 2 > WL_TLV_INFO_MAX)) {
4038 WL_ERR("ei crosses buffer boundary\n");
4039 return -ENOSPC;
4041 ie->buf[ie->offset] = t;
4042 ie->buf[ie->offset + 1] = l;
4043 memcpy(&ie->buf[ie->offset + 2], v, l);
4044 ie->offset += l + 2;
4046 return err;
4049 static void brcmf_link_down(struct brcmf_cfg80211_priv *cfg_priv)
4051 struct net_device *dev = NULL;
4052 s32 err = 0;
4054 WL_TRACE("Enter\n");
4056 if (cfg_priv->link_up) {
4057 dev = cfg_to_ndev(cfg_priv);
4058 WL_INFO("Call WLC_DISASSOC to stop excess roaming\n ");
4059 err = brcmf_dev_ioctl(dev, BRCMF_C_DISASSOC, NULL, 0);
4060 if (unlikely(err))
4061 WL_ERR("WLC_DISASSOC failed (%d)\n", err);
4062 cfg_priv->link_up = false;
4064 WL_TRACE("Exit\n");
4067 static void brcmf_lock_eq(struct brcmf_cfg80211_priv *cfg_priv)
4069 spin_lock_irq(&cfg_priv->eq_lock);
4072 static void brcmf_unlock_eq(struct brcmf_cfg80211_priv *cfg_priv)
4074 spin_unlock_irq(&cfg_priv->eq_lock);
4077 static void brcmf_init_eq_lock(struct brcmf_cfg80211_priv *cfg_priv)
4079 spin_lock_init(&cfg_priv->eq_lock);
4082 static void brcmf_delay(u32 ms)
4084 if (ms < 1000 / HZ) {
4085 cond_resched();
4086 mdelay(ms);
4087 } else {
4088 msleep(ms);
4092 static void brcmf_set_drvdata(struct brcmf_cfg80211_dev *dev, void *data)
4094 dev->driver_data = data;
4097 static void *brcmf_get_drvdata(struct brcmf_cfg80211_dev *dev)
4099 void *data = NULL;
4101 if (dev)
4102 data = dev->driver_data;
4103 return data;
4106 static void brcmf_set_mpc(struct net_device *ndev, int mpc)
4108 s32 err = 0;
4109 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
4111 if (test_bit(WL_STATUS_READY, &cfg_priv->status)) {
4112 err = brcmf_dev_intvar_set(ndev, "mpc", mpc);
4113 if (unlikely(err)) {
4114 WL_ERR("fail to set mpc\n");
4115 return;
4117 WL_INFO("MPC : %d\n", mpc);
4121 static int brcmf_debugfs_add_netdev_params(struct brcmf_cfg80211_priv *cfg_priv)
4123 char buf[10+IFNAMSIZ];
4124 struct dentry *fd;
4125 s32 err = 0;
4127 sprintf(buf, "netdev:%s", cfg_to_ndev(cfg_priv)->name);
4128 cfg_priv->debugfsdir = debugfs_create_dir(buf,
4129 cfg_to_wiphy(cfg_priv)->debugfsdir);
4131 fd = debugfs_create_u16("beacon_int", S_IRUGO, cfg_priv->debugfsdir,
4132 (u16 *)&cfg_priv->profile->beacon_interval);
4133 if (!fd) {
4134 err = -ENOMEM;
4135 goto err_out;
4138 fd = debugfs_create_u8("dtim_period", S_IRUGO, cfg_priv->debugfsdir,
4139 (u8 *)&cfg_priv->profile->dtim_period);
4140 if (!fd) {
4141 err = -ENOMEM;
4142 goto err_out;
4145 err_out:
4146 return err;
4149 static void brcmf_debugfs_remove_netdev(struct brcmf_cfg80211_priv *cfg_priv)
4151 debugfs_remove_recursive(cfg_priv->debugfsdir);
4152 cfg_priv->debugfsdir = NULL;