staging: brcm80211: rename key endian conversion functions
[linux-2.6.git] / drivers / staging / brcm80211 / brcmfmac / wl_cfg80211.c
blob8b052b0fbb1fb69520510b6571b2d41a148ddc2d
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/ieee80211.h>
25 #include <linux/mmc/sdio_func.h>
26 #include <linux/uaccess.h>
27 #include <net/cfg80211.h>
28 #include <net/rtnetlink.h>
30 #include <brcmu_utils.h>
31 #include <defs.h>
32 #include <brcmu_wifi.h>
33 #include "dhd.h"
34 #include "wl_cfg80211.h"
36 static struct sdio_func *cfg80211_sdio_func;
37 static struct brcmf_cfg80211_dev *cfg80211_dev;
38 static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255};
40 u32 brcmf_dbg_level = WL_DBG_ERR;
43 ** cfg80211_ops api/callback list
45 static s32 brcmf_cfg80211_change_iface(struct wiphy *wiphy,
46 struct net_device *ndev,
47 enum nl80211_iftype type, u32 *flags,
48 struct vif_params *params);
49 static s32 __brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
50 struct cfg80211_scan_request *request,
51 struct cfg80211_ssid *this_ssid);
52 static s32 brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
53 struct cfg80211_scan_request *request);
54 static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed);
55 static s32 brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
56 struct cfg80211_ibss_params *params);
57 static s32 brcmf_cfg80211_leave_ibss(struct wiphy *wiphy,
58 struct net_device *dev);
59 static s32 brcmf_cfg80211_get_station(struct wiphy *wiphy,
60 struct net_device *dev, u8 *mac,
61 struct station_info *sinfo);
62 static s32 brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy,
63 struct net_device *dev, bool enabled,
64 s32 timeout);
65 static s32 brcmf_cfg80211_set_bitrate_mask(struct wiphy *wiphy,
66 struct net_device *dev,
67 const u8 *addr,
68 const struct cfg80211_bitrate_mask
69 *mask);
70 static int brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
71 struct cfg80211_connect_params *sme);
72 static s32 brcmf_cfg80211_disconnect(struct wiphy *wiphy,
73 struct net_device *dev,
74 u16 reason_code);
75 static s32 brcmf_cfg80211_set_tx_power(struct wiphy *wiphy,
76 enum nl80211_tx_power_setting type,
77 s32 dbm);
78 static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm);
79 static s32 brcmf_cfg80211_config_default_key(struct wiphy *wiphy,
80 struct net_device *dev, u8 key_idx,
81 bool unicast, bool multicast);
82 static s32 brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
83 u8 key_idx, bool pairwise, const u8 *mac_addr,
84 struct key_params *params);
85 static s32 brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
86 u8 key_idx, bool pairwise, const u8 *mac_addr);
87 static s32 brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
88 u8 key_idx, bool pairwise, const u8 *mac_addr,
89 void *cookie, void (*callback) (void *cookie,
90 struct
91 key_params *
92 params));
93 static s32 brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
94 struct net_device *dev,
95 u8 key_idx);
96 static s32 brcmf_cfg80211_resume(struct wiphy *wiphy);
97 static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
98 struct cfg80211_wowlan *wow);
99 static s32 brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
100 struct cfg80211_pmksa *pmksa);
101 static s32 brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
102 struct cfg80211_pmksa *pmksa);
103 static s32 brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy,
104 struct net_device *dev);
106 ** event & event Q handlers for cfg80211 interfaces
108 static s32 brcmf_create_event_handler(struct brcmf_cfg80211_priv *cfg_priv);
109 static void brcmf_destroy_event_handler(struct brcmf_cfg80211_priv *cfg_priv);
110 static s32 brcmf_event_handler(void *data);
111 static void brcmf_init_eq(struct brcmf_cfg80211_priv *cfg_priv);
112 static void brcmf_flush_eq(struct brcmf_cfg80211_priv *cfg_priv);
113 static void brcmf_lock_eq(struct brcmf_cfg80211_priv *cfg_priv);
114 static void brcmf_unlock_eq(struct brcmf_cfg80211_priv *cfg_priv);
115 static void brcmf_init_eq_lock(struct brcmf_cfg80211_priv *cfg_priv);
116 static void brcmf_init_eloop_handler(struct brcmf_cfg80211_event_loop *el);
117 static struct brcmf_cfg80211_event_q *
118 brcmf_deq_event(struct brcmf_cfg80211_priv *cfg_priv);
119 static s32 brcmf_enq_event(struct brcmf_cfg80211_priv *cfg_priv, u32 type,
120 const struct brcmf_event_msg *msg);
121 static void brcmf_put_event(struct brcmf_cfg80211_event_q *e);
122 static void brcmf_wakeup_event(struct brcmf_cfg80211_priv *cfg_priv);
123 static s32 brcmf_notify_connect_status(struct brcmf_cfg80211_priv *cfg_priv,
124 struct net_device *ndev,
125 const struct brcmf_event_msg *e,
126 void *data);
127 static s32 brcmf_notify_roaming_status(struct brcmf_cfg80211_priv *cfg_priv,
128 struct net_device *ndev,
129 const struct brcmf_event_msg *e,
130 void *data);
131 static s32 brcmf_notify_scan_status(struct brcmf_cfg80211_priv *cfg_priv,
132 struct net_device *ndev,
133 const struct brcmf_event_msg *e,
134 void *data);
135 static s32 brcmf_bss_connect_done(struct brcmf_cfg80211_priv *cfg_priv,
136 struct net_device *ndev,
137 const struct brcmf_event_msg *e,
138 bool completed);
139 static s32 brcmf_bss_roaming_done(struct brcmf_cfg80211_priv *cfg_priv,
140 struct net_device *ndev,
141 const struct brcmf_event_msg *e);
142 static s32 brcmf_notify_mic_status(struct brcmf_cfg80211_priv *cfg_priv,
143 struct net_device *ndev,
144 const struct brcmf_event_msg *e, void *data);
147 ** register/deregister sdio function
149 static void brcmf_clear_sdio_func(void);
152 ** ioctl utilites
154 static s32 brcmf_dev_bufvar_get(struct net_device *dev, s8 *name, s8 *buf,
155 s32 buf_len);
156 static __used s32 brcmf_dev_bufvar_set(struct net_device *dev, s8 *name,
157 s8 *buf, s32 len);
158 static s32 brcmf_dev_intvar_set(struct net_device *dev, s8 *name, s32 val);
159 static s32 brcmf_dev_intvar_get(struct net_device *dev, s8 *name,
160 s32 *retval);
161 static s32 brcmf_dev_ioctl(struct net_device *dev, u32 cmd, void *arg,
162 u32 len);
165 ** cfg80211 set_wiphy_params utilities
167 static s32 brcmf_set_frag(struct net_device *dev, u32 frag_threshold);
168 static s32 brcmf_set_rts(struct net_device *dev, u32 frag_threshold);
169 static s32 brcmf_set_retry(struct net_device *dev, u32 retry, bool l);
172 ** wl profile utilities
174 static s32 brcmf_update_prof(struct brcmf_cfg80211_priv *cfg_priv,
175 const struct brcmf_event_msg *e,
176 void *data, s32 item);
177 static void *brcmf_read_prof(struct brcmf_cfg80211_priv *cfg_priv, s32 item);
178 static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof);
181 ** cfg80211 connect utilites
183 static s32 brcmf_set_wpa_version(struct net_device *dev,
184 struct cfg80211_connect_params *sme);
185 static s32 brcmf_set_auth_type(struct net_device *dev,
186 struct cfg80211_connect_params *sme);
187 static s32 brcmf_set_set_cipher(struct net_device *dev,
188 struct cfg80211_connect_params *sme);
189 static s32 brcmf_set_key_mgmt(struct net_device *dev,
190 struct cfg80211_connect_params *sme);
191 static s32 brcmf_set_set_sharedkey(struct net_device *dev,
192 struct cfg80211_connect_params *sme);
193 static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv);
194 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv);
195 static void brcmf_ch_to_chanspec(int ch,
196 struct brcmf_join_params *join_params, size_t *join_params_size);
199 ** information element utilities
201 static __used s32 brcmf_add_ie(struct brcmf_cfg80211_priv *cfg_priv,
202 u8 t, u8 l, u8 *v);
203 static s32 brcmf_mode_to_nl80211_iftype(s32 mode);
204 static struct wireless_dev *brcmf_alloc_wdev(s32 sizeof_iface,
205 struct device *dev);
206 static void brcmf_free_wdev(struct brcmf_cfg80211_priv *cfg_priv);
207 static s32 brcmf_inform_bss(struct brcmf_cfg80211_priv *cfg_priv);
208 static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv,
209 struct brcmf_bss_info *bi);
210 static s32 brcmf_update_bss_info(struct brcmf_cfg80211_priv *cfg_priv);
211 static s32 brcmf_add_keyext(struct wiphy *wiphy, struct net_device *dev,
212 u8 key_idx, const u8 *mac_addr,
213 struct key_params *params);
216 ** key indianess swap utilities
218 static void convert_key_from_CPU(struct brcmf_wsec_key *key);
219 static void convert_key_to_CPU(struct brcmf_wsec_key *key);
222 ** brcmf_cfg80211_priv memory init/deinit utilities
224 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_priv *cfg_priv);
225 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_priv *cfg_priv);
227 static void brcmf_delay(u32 ms);
230 ** store/restore cfg80211 instance data
232 static void brcmf_set_drvdata(struct brcmf_cfg80211_dev *dev, void *data);
233 static void *brcmf_get_drvdata(struct brcmf_cfg80211_dev *dev);
236 ** ibss mode utilities
238 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_priv *cfg_priv);
241 ** dongle up/down , default configuration utilities
243 static bool brcmf_is_linkdown(struct brcmf_cfg80211_priv *cfg_priv,
244 const struct brcmf_event_msg *e);
245 static bool brcmf_is_linkup(struct brcmf_cfg80211_priv *cfg_priv,
246 const struct brcmf_event_msg *e);
247 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_priv *cfg_priv,
248 const struct brcmf_event_msg *e);
249 static void brcmf_link_down(struct brcmf_cfg80211_priv *cfg_priv);
250 static s32 brcmf_dongle_mode(struct net_device *ndev, s32 iftype);
251 static s32 __brcmf_cfg80211_up(struct brcmf_cfg80211_priv *cfg_priv);
252 static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_priv *cfg_priv);
253 static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_priv *cfg_priv);
254 static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf);
257 ** dongle configuration utilities
259 static s32 brcmf_dongle_eventmsg(struct net_device *ndev);
260 static s32 brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
261 s32 scan_unassoc_time, s32 scan_passive_time);
262 static s32 brcmf_config_dongle(struct brcmf_cfg80211_priv *cfg_priv,
263 bool need_lock);
264 static s32 brcmf_dongle_roam(struct net_device *ndev, u32 roamvar,
265 u32 bcn_timeout);
268 ** iscan handler
270 static void brcmf_iscan_timer(unsigned long data);
271 static void brcmf_term_iscan(struct brcmf_cfg80211_priv *cfg_priv);
272 static s32 brcmf_init_iscan(struct brcmf_cfg80211_priv *cfg_priv);
273 static s32 brcmf_iscan_thread(void *data);
274 static s32 brcmf_dev_iovar_setbuf(struct net_device *dev, s8 *iovar,
275 void *param, s32 paramlen, void *bufptr,
276 s32 buflen);
277 static s32 brcmf_dev_iovar_getbuf(struct net_device *dev, s8 *iovar,
278 void *param, s32 paramlen, void *bufptr,
279 s32 buflen);
280 static s32 brcmf_run_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan,
281 struct brcmf_ssid *ssid, u16 action);
282 static s32 brcmf_do_iscan(struct brcmf_cfg80211_priv *cfg_priv);
283 static s32 brcmf_wakeup_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan);
284 static s32 brcmf_invoke_iscan(struct brcmf_cfg80211_priv *cfg_priv);
285 static s32 brcmf_get_iscan_results(struct brcmf_cfg80211_iscan_ctrl *iscan,
286 u32 *status,
287 struct brcmf_scan_results **bss_list);
288 static void brcmf_notify_iscan_complete(struct brcmf_cfg80211_iscan_ctrl *iscan,
289 bool aborted);
290 static void brcmf_init_iscan_eloop(struct brcmf_cfg80211_iscan_eloop *el);
291 static s32 brcmf_iscan_done(struct brcmf_cfg80211_priv *cfg_priv);
292 static s32 brcmf_iscan_pending(struct brcmf_cfg80211_priv *cfg_priv);
293 static s32 brcmf_iscan_inprogress(struct brcmf_cfg80211_priv *cfg_priv);
294 static s32 brcmf_iscan_aborted(struct brcmf_cfg80211_priv *cfg_priv);
297 * find most significant bit set
299 static __used u32 brcmf_find_msb(u16 bit16);
302 * update pmklist to dongle
304 static __used s32 brcmf_update_pmklist(struct net_device *dev,
305 struct brcmf_cfg80211_pmk_list *pmk_list,
306 s32 err);
308 static void brcmf_set_mpc(struct net_device *ndev, int mpc);
311 * debufs support
313 static int
314 brcmf_debugfs_add_netdev_params(struct brcmf_cfg80211_priv *cfg_priv);
315 static void brcmf_debugfs_remove_netdev(struct brcmf_cfg80211_priv *cfg_priv);
317 #define WL_PRIV_GET() \
318 ({ \
319 struct brcmf_cfg80211_iface *ci = brcmf_get_drvdata(cfg80211_dev); \
320 if (unlikely(!ci)) { \
321 WL_ERR("wl_cfg80211_dev is unavailable\n"); \
322 BUG(); \
324 ci->cfg_priv; \
327 #define CHECK_SYS_UP() \
328 do { \
329 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); \
330 if (unlikely(!test_bit(WL_STATUS_READY, &cfg_priv->status))) { \
331 WL_INFO("device is not ready : status (%d)\n", \
332 (int)cfg_priv->status); \
333 return -EIO; \
335 } while (0)
337 #define CHAN2G(_channel, _freq, _flags) { \
338 .band = IEEE80211_BAND_2GHZ, \
339 .center_freq = (_freq), \
340 .hw_value = (_channel), \
341 .flags = (_flags), \
342 .max_antenna_gain = 0, \
343 .max_power = 30, \
346 #define CHAN5G(_channel, _flags) { \
347 .band = IEEE80211_BAND_5GHZ, \
348 .center_freq = 5000 + (5 * (_channel)), \
349 .hw_value = (_channel), \
350 .flags = (_flags), \
351 .max_antenna_gain = 0, \
352 .max_power = 30, \
355 #define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
356 #define RATETAB_ENT(_rateid, _flags) \
358 .bitrate = RATE_TO_BASE100KBPS(_rateid), \
359 .hw_value = (_rateid), \
360 .flags = (_flags), \
363 static struct ieee80211_rate __wl_rates[] = {
364 RATETAB_ENT(BRCM_RATE_1M, 0),
365 RATETAB_ENT(BRCM_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
366 RATETAB_ENT(BRCM_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
367 RATETAB_ENT(BRCM_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
368 RATETAB_ENT(BRCM_RATE_6M, 0),
369 RATETAB_ENT(BRCM_RATE_9M, 0),
370 RATETAB_ENT(BRCM_RATE_12M, 0),
371 RATETAB_ENT(BRCM_RATE_18M, 0),
372 RATETAB_ENT(BRCM_RATE_24M, 0),
373 RATETAB_ENT(BRCM_RATE_36M, 0),
374 RATETAB_ENT(BRCM_RATE_48M, 0),
375 RATETAB_ENT(BRCM_RATE_54M, 0),
378 #define wl_a_rates (__wl_rates + 4)
379 #define wl_a_rates_size 8
380 #define wl_g_rates (__wl_rates + 0)
381 #define wl_g_rates_size 12
383 static struct ieee80211_channel __wl_2ghz_channels[] = {
384 CHAN2G(1, 2412, 0),
385 CHAN2G(2, 2417, 0),
386 CHAN2G(3, 2422, 0),
387 CHAN2G(4, 2427, 0),
388 CHAN2G(5, 2432, 0),
389 CHAN2G(6, 2437, 0),
390 CHAN2G(7, 2442, 0),
391 CHAN2G(8, 2447, 0),
392 CHAN2G(9, 2452, 0),
393 CHAN2G(10, 2457, 0),
394 CHAN2G(11, 2462, 0),
395 CHAN2G(12, 2467, 0),
396 CHAN2G(13, 2472, 0),
397 CHAN2G(14, 2484, 0),
400 static struct ieee80211_channel __wl_5ghz_a_channels[] = {
401 CHAN5G(34, 0), CHAN5G(36, 0),
402 CHAN5G(38, 0), CHAN5G(40, 0),
403 CHAN5G(42, 0), CHAN5G(44, 0),
404 CHAN5G(46, 0), CHAN5G(48, 0),
405 CHAN5G(52, 0), CHAN5G(56, 0),
406 CHAN5G(60, 0), CHAN5G(64, 0),
407 CHAN5G(100, 0), CHAN5G(104, 0),
408 CHAN5G(108, 0), CHAN5G(112, 0),
409 CHAN5G(116, 0), CHAN5G(120, 0),
410 CHAN5G(124, 0), CHAN5G(128, 0),
411 CHAN5G(132, 0), CHAN5G(136, 0),
412 CHAN5G(140, 0), CHAN5G(149, 0),
413 CHAN5G(153, 0), CHAN5G(157, 0),
414 CHAN5G(161, 0), CHAN5G(165, 0),
415 CHAN5G(184, 0), CHAN5G(188, 0),
416 CHAN5G(192, 0), CHAN5G(196, 0),
417 CHAN5G(200, 0), CHAN5G(204, 0),
418 CHAN5G(208, 0), CHAN5G(212, 0),
419 CHAN5G(216, 0),
422 static struct ieee80211_channel __wl_5ghz_n_channels[] = {
423 CHAN5G(32, 0), CHAN5G(34, 0),
424 CHAN5G(36, 0), CHAN5G(38, 0),
425 CHAN5G(40, 0), CHAN5G(42, 0),
426 CHAN5G(44, 0), CHAN5G(46, 0),
427 CHAN5G(48, 0), CHAN5G(50, 0),
428 CHAN5G(52, 0), CHAN5G(54, 0),
429 CHAN5G(56, 0), CHAN5G(58, 0),
430 CHAN5G(60, 0), CHAN5G(62, 0),
431 CHAN5G(64, 0), CHAN5G(66, 0),
432 CHAN5G(68, 0), CHAN5G(70, 0),
433 CHAN5G(72, 0), CHAN5G(74, 0),
434 CHAN5G(76, 0), CHAN5G(78, 0),
435 CHAN5G(80, 0), CHAN5G(82, 0),
436 CHAN5G(84, 0), CHAN5G(86, 0),
437 CHAN5G(88, 0), CHAN5G(90, 0),
438 CHAN5G(92, 0), CHAN5G(94, 0),
439 CHAN5G(96, 0), CHAN5G(98, 0),
440 CHAN5G(100, 0), CHAN5G(102, 0),
441 CHAN5G(104, 0), CHAN5G(106, 0),
442 CHAN5G(108, 0), CHAN5G(110, 0),
443 CHAN5G(112, 0), CHAN5G(114, 0),
444 CHAN5G(116, 0), CHAN5G(118, 0),
445 CHAN5G(120, 0), CHAN5G(122, 0),
446 CHAN5G(124, 0), CHAN5G(126, 0),
447 CHAN5G(128, 0), CHAN5G(130, 0),
448 CHAN5G(132, 0), CHAN5G(134, 0),
449 CHAN5G(136, 0), CHAN5G(138, 0),
450 CHAN5G(140, 0), CHAN5G(142, 0),
451 CHAN5G(144, 0), CHAN5G(145, 0),
452 CHAN5G(146, 0), CHAN5G(147, 0),
453 CHAN5G(148, 0), CHAN5G(149, 0),
454 CHAN5G(150, 0), CHAN5G(151, 0),
455 CHAN5G(152, 0), CHAN5G(153, 0),
456 CHAN5G(154, 0), CHAN5G(155, 0),
457 CHAN5G(156, 0), CHAN5G(157, 0),
458 CHAN5G(158, 0), CHAN5G(159, 0),
459 CHAN5G(160, 0), CHAN5G(161, 0),
460 CHAN5G(162, 0), CHAN5G(163, 0),
461 CHAN5G(164, 0), CHAN5G(165, 0),
462 CHAN5G(166, 0), CHAN5G(168, 0),
463 CHAN5G(170, 0), CHAN5G(172, 0),
464 CHAN5G(174, 0), CHAN5G(176, 0),
465 CHAN5G(178, 0), CHAN5G(180, 0),
466 CHAN5G(182, 0), CHAN5G(184, 0),
467 CHAN5G(186, 0), CHAN5G(188, 0),
468 CHAN5G(190, 0), CHAN5G(192, 0),
469 CHAN5G(194, 0), CHAN5G(196, 0),
470 CHAN5G(198, 0), CHAN5G(200, 0),
471 CHAN5G(202, 0), CHAN5G(204, 0),
472 CHAN5G(206, 0), CHAN5G(208, 0),
473 CHAN5G(210, 0), CHAN5G(212, 0),
474 CHAN5G(214, 0), CHAN5G(216, 0),
475 CHAN5G(218, 0), CHAN5G(220, 0),
476 CHAN5G(222, 0), CHAN5G(224, 0),
477 CHAN5G(226, 0), CHAN5G(228, 0),
480 static struct ieee80211_supported_band __wl_band_2ghz = {
481 .band = IEEE80211_BAND_2GHZ,
482 .channels = __wl_2ghz_channels,
483 .n_channels = ARRAY_SIZE(__wl_2ghz_channels),
484 .bitrates = wl_g_rates,
485 .n_bitrates = wl_g_rates_size,
488 static struct ieee80211_supported_band __wl_band_5ghz_a = {
489 .band = IEEE80211_BAND_5GHZ,
490 .channels = __wl_5ghz_a_channels,
491 .n_channels = ARRAY_SIZE(__wl_5ghz_a_channels),
492 .bitrates = wl_a_rates,
493 .n_bitrates = wl_a_rates_size,
496 static struct ieee80211_supported_band __wl_band_5ghz_n = {
497 .band = IEEE80211_BAND_5GHZ,
498 .channels = __wl_5ghz_n_channels,
499 .n_channels = ARRAY_SIZE(__wl_5ghz_n_channels),
500 .bitrates = wl_a_rates,
501 .n_bitrates = wl_a_rates_size,
504 static const u32 __wl_cipher_suites[] = {
505 WLAN_CIPHER_SUITE_WEP40,
506 WLAN_CIPHER_SUITE_WEP104,
507 WLAN_CIPHER_SUITE_TKIP,
508 WLAN_CIPHER_SUITE_CCMP,
509 WLAN_CIPHER_SUITE_AES_CMAC,
512 static void convert_key_from_CPU(struct brcmf_wsec_key *key)
514 key->index = cpu_to_le32(key->index);
515 key->len = cpu_to_le32(key->len);
516 key->algo = cpu_to_le32(key->algo);
517 key->flags = cpu_to_le32(key->flags);
518 key->rxiv.hi = cpu_to_le32(key->rxiv.hi);
519 key->rxiv.lo = cpu_to_le16(key->rxiv.lo);
520 key->iv_initialized = cpu_to_le32(key->iv_initialized);
523 static void convert_key_to_CPU(struct brcmf_wsec_key *key)
525 key->index = le32_to_cpu(key->index);
526 key->len = le32_to_cpu(key->len);
527 key->algo = le32_to_cpu(key->algo);
528 key->flags = le32_to_cpu(key->flags);
529 key->rxiv.hi = le32_to_cpu(key->rxiv.hi);
530 key->rxiv.lo = le16_to_cpu(key->rxiv.lo);
531 key->iv_initialized = le32_to_cpu(key->iv_initialized);
534 static s32
535 brcmf_dev_ioctl(struct net_device *dev, u32 cmd, void *arg, u32 len)
537 struct ifreq ifr;
538 struct brcmf_ioctl ioc;
539 mm_segment_t fs;
540 s32 err = 0;
542 memset(&ioc, 0, sizeof(ioc));
543 ioc.cmd = cmd;
544 ioc.buf = arg;
545 ioc.len = len;
546 strcpy(ifr.ifr_name, dev->name);
547 ifr.ifr_data = (caddr_t)&ioc;
549 fs = get_fs();
550 set_fs(get_ds());
551 err = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, SIOCDEVPRIVATE);
552 set_fs(fs);
554 return err;
557 static s32
558 brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
559 enum nl80211_iftype type, u32 *flags,
560 struct vif_params *params)
562 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
563 struct wireless_dev *wdev;
564 s32 infra = 0;
565 s32 err = 0;
567 WL_TRACE("Enter\n");
568 CHECK_SYS_UP();
570 switch (type) {
571 case NL80211_IFTYPE_MONITOR:
572 case NL80211_IFTYPE_WDS:
573 WL_ERR("type (%d) : currently we do not support this type\n",
574 type);
575 return -EOPNOTSUPP;
576 case NL80211_IFTYPE_ADHOC:
577 cfg_priv->conf->mode = WL_MODE_IBSS;
578 infra = 0;
579 break;
580 case NL80211_IFTYPE_STATION:
581 cfg_priv->conf->mode = WL_MODE_BSS;
582 infra = 1;
583 break;
584 default:
585 err = -EINVAL;
586 goto done;
589 infra = cpu_to_le32(infra);
590 err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_INFRA, &infra, sizeof(infra));
591 if (unlikely(err)) {
592 WL_ERR("WLC_SET_INFRA error (%d)\n", err);
593 err = -EAGAIN;
594 } else {
595 wdev = ndev->ieee80211_ptr;
596 wdev->iftype = type;
599 WL_INFO("IF Type = %s\n",
600 (cfg_priv->conf->mode == WL_MODE_IBSS) ? "Adhoc" : "Infra");
602 done:
603 WL_TRACE("Exit\n");
605 return err;
608 static void wl_iscan_prep(struct brcmf_scan_params *params,
609 struct brcmf_ssid *ssid)
611 memcpy(params->bssid, ether_bcast, ETH_ALEN);
612 params->bss_type = DOT11_BSSTYPE_ANY;
613 params->scan_type = 0;
614 params->nprobes = -1;
615 params->active_time = -1;
616 params->passive_time = -1;
617 params->home_time = -1;
618 params->channel_num = 0;
620 params->nprobes = cpu_to_le32(params->nprobes);
621 params->active_time = cpu_to_le32(params->active_time);
622 params->passive_time = cpu_to_le32(params->passive_time);
623 params->home_time = cpu_to_le32(params->home_time);
624 if (ssid && ssid->SSID_len)
625 memcpy(&params->ssid, ssid, sizeof(struct brcmf_ssid));
629 static s32
630 brcmf_dev_iovar_setbuf(struct net_device *dev, s8 * iovar, void *param,
631 s32 paramlen, void *bufptr, s32 buflen)
633 s32 iolen;
635 iolen = brcmu_mkiovar(iovar, param, paramlen, bufptr, buflen);
636 BUG_ON(!iolen);
638 return brcmf_dev_ioctl(dev, BRCMF_C_SET_VAR, bufptr, iolen);
641 static s32
642 brcmf_dev_iovar_getbuf(struct net_device *dev, s8 * iovar, void *param,
643 s32 paramlen, void *bufptr, s32 buflen)
645 s32 iolen;
647 iolen = brcmu_mkiovar(iovar, param, paramlen, bufptr, buflen);
648 BUG_ON(!iolen);
650 return brcmf_dev_ioctl(dev, BRCMF_C_GET_VAR, bufptr, buflen);
653 static s32
654 brcmf_run_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan,
655 struct brcmf_ssid *ssid, u16 action)
657 s32 params_size = (BRCMF_SCAN_PARAMS_FIXED_SIZE +
658 offsetof(struct brcmf_iscan_params, params));
659 struct brcmf_iscan_params *params;
660 s32 err = 0;
662 if (ssid && ssid->SSID_len)
663 params_size += sizeof(struct brcmf_ssid);
664 params = kzalloc(params_size, GFP_KERNEL);
665 if (unlikely(!params))
666 return -ENOMEM;
667 BUG_ON(params_size >= BRCMF_C_IOCTL_SMLEN);
669 wl_iscan_prep(&params->params, ssid);
671 params->version = cpu_to_le32(BRCMF_ISCAN_REQ_VERSION);
672 params->action = cpu_to_le16(action);
673 params->scan_duration = cpu_to_le16(0);
675 /* params_size += offsetof(struct brcmf_iscan_params, params); */
676 err = brcmf_dev_iovar_setbuf(iscan->dev, "iscan", params, params_size,
677 iscan->ioctl_buf, BRCMF_C_IOCTL_SMLEN);
678 if (unlikely(err)) {
679 if (err == -EBUSY)
680 WL_INFO("system busy : iscan canceled\n");
681 else
682 WL_ERR("error (%d)\n", err);
685 kfree(params);
686 return err;
689 static s32 brcmf_do_iscan(struct brcmf_cfg80211_priv *cfg_priv)
691 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
692 struct net_device *ndev = cfg_to_ndev(cfg_priv);
693 struct brcmf_ssid ssid;
694 s32 passive_scan;
695 s32 err = 0;
697 /* Broadcast scan by default */
698 memset(&ssid, 0, sizeof(ssid));
700 iscan->state = WL_ISCAN_STATE_SCANING;
702 passive_scan = cfg_priv->active_scan ? 0 : 1;
703 err = brcmf_dev_ioctl(cfg_to_ndev(cfg_priv), BRCMF_C_SET_PASSIVE_SCAN,
704 &passive_scan, sizeof(passive_scan));
705 if (unlikely(err)) {
706 WL_ERR("error (%d)\n", err);
707 return err;
709 brcmf_set_mpc(ndev, 0);
710 cfg_priv->iscan_kickstart = true;
711 err = brcmf_run_iscan(iscan, &ssid, BRCMF_SCAN_ACTION_START);
712 if (err) {
713 brcmf_set_mpc(ndev, 1);
714 cfg_priv->iscan_kickstart = false;
715 return err;
717 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
718 iscan->timer_on = 1;
719 return err;
722 static s32
723 __brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
724 struct cfg80211_scan_request *request,
725 struct cfg80211_ssid *this_ssid)
727 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
728 struct cfg80211_ssid *ssids;
729 struct brcmf_cfg80211_scan_req *sr = cfg_priv->scan_req_int;
730 s32 passive_scan;
731 bool iscan_req;
732 bool spec_scan;
733 s32 err = 0;
735 if (unlikely(test_bit(WL_STATUS_SCANNING, &cfg_priv->status))) {
736 WL_ERR("Scanning already : status (%lu)\n", cfg_priv->status);
737 return -EAGAIN;
739 if (unlikely(test_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status))) {
740 WL_ERR("Scanning being aborted : status (%lu)\n",
741 cfg_priv->status);
742 return -EAGAIN;
744 if (test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) {
745 WL_ERR("Connecting : status (%lu)\n",
746 cfg_priv->status);
747 return -EAGAIN;
750 iscan_req = false;
751 spec_scan = false;
752 if (request) {
753 /* scan bss */
754 ssids = request->ssids;
755 if (cfg_priv->iscan_on && (!ssids || !ssids->ssid_len))
756 iscan_req = true;
757 } else {
758 /* scan in ibss */
759 /* we don't do iscan in ibss */
760 ssids = this_ssid;
763 cfg_priv->scan_request = request;
764 set_bit(WL_STATUS_SCANNING, &cfg_priv->status);
765 if (iscan_req) {
766 err = brcmf_do_iscan(cfg_priv);
767 if (likely(!err))
768 return err;
769 else
770 goto scan_out;
771 } else {
772 WL_SCAN("ssid \"%s\", ssid_len (%d)\n",
773 ssids->ssid, ssids->ssid_len);
774 memset(&sr->ssid, 0, sizeof(sr->ssid));
775 sr->ssid.SSID_len =
776 min_t(u8, sizeof(sr->ssid.SSID), ssids->ssid_len);
777 if (sr->ssid.SSID_len) {
778 memcpy(sr->ssid.SSID, ssids->ssid, sr->ssid.SSID_len);
779 sr->ssid.SSID_len = cpu_to_le32(sr->ssid.SSID_len);
780 spec_scan = true;
781 } else {
782 WL_SCAN("Broadcast scan\n");
785 passive_scan = cfg_priv->active_scan ? 0 : 1;
786 err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_PASSIVE_SCAN,
787 &passive_scan, sizeof(passive_scan));
788 if (unlikely(err)) {
789 WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
790 goto scan_out;
792 brcmf_set_mpc(ndev, 0);
793 err = brcmf_dev_ioctl(ndev, BRCMF_C_SCAN, &sr->ssid,
794 sizeof(sr->ssid));
795 if (err) {
796 if (err == -EBUSY)
797 WL_INFO("system busy : scan for \"%s\" "
798 "canceled\n", sr->ssid.SSID);
799 else
800 WL_ERR("WLC_SCAN error (%d)\n", err);
802 brcmf_set_mpc(ndev, 1);
803 goto scan_out;
807 return 0;
809 scan_out:
810 clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
811 cfg_priv->scan_request = NULL;
812 return err;
815 static s32
816 brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
817 struct cfg80211_scan_request *request)
819 s32 err = 0;
821 WL_TRACE("Enter\n");
823 CHECK_SYS_UP();
825 err = __brcmf_cfg80211_scan(wiphy, ndev, request, NULL);
826 if (unlikely(err))
827 WL_ERR("scan error (%d)\n", err);
829 WL_TRACE("Exit\n");
830 return err;
833 static s32 brcmf_dev_intvar_set(struct net_device *dev, s8 *name, s32 val)
835 s8 buf[BRCMF_C_IOCTL_SMLEN];
836 u32 len;
837 s32 err = 0;
839 val = cpu_to_le32(val);
840 len = brcmu_mkiovar(name, (char *)(&val), sizeof(val), buf,
841 sizeof(buf));
842 BUG_ON(!len);
844 err = brcmf_dev_ioctl(dev, BRCMF_C_SET_VAR, buf, len);
845 if (unlikely(err))
846 WL_ERR("error (%d)\n", err);
848 return err;
851 static s32
852 brcmf_dev_intvar_get(struct net_device *dev, s8 *name, s32 *retval)
854 union {
855 s8 buf[BRCMF_C_IOCTL_SMLEN];
856 s32 val;
857 } var;
858 u32 len;
859 u32 data_null;
860 s32 err = 0;
862 len =
863 brcmu_mkiovar(name, (char *)(&data_null), 0, (char *)(&var),
864 sizeof(var.buf));
865 BUG_ON(!len);
866 err = brcmf_dev_ioctl(dev, BRCMF_C_GET_VAR, &var, len);
867 if (unlikely(err))
868 WL_ERR("error (%d)\n", err);
870 *retval = le32_to_cpu(var.val);
872 return err;
875 static s32 brcmf_set_rts(struct net_device *dev, u32 rts_threshold)
877 s32 err = 0;
879 err = brcmf_dev_intvar_set(dev, "rtsthresh", rts_threshold);
880 if (unlikely(err))
881 WL_ERR("Error (%d)\n", err);
883 return err;
886 static s32 brcmf_set_frag(struct net_device *dev, u32 frag_threshold)
888 s32 err = 0;
890 err = brcmf_dev_intvar_set(dev, "fragthresh", frag_threshold);
891 if (unlikely(err))
892 WL_ERR("Error (%d)\n", err);
894 return err;
897 static s32 brcmf_set_retry(struct net_device *dev, u32 retry, bool l)
899 s32 err = 0;
900 u32 cmd = (l ? BRCM_SET_LRL : BRCM_SET_SRL);
902 retry = cpu_to_le32(retry);
903 err = brcmf_dev_ioctl(dev, cmd, &retry, sizeof(retry));
904 if (unlikely(err)) {
905 WL_ERR("cmd (%d) , error (%d)\n", cmd, err);
906 return err;
908 return err;
911 static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
913 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
914 struct net_device *ndev = cfg_to_ndev(cfg_priv);
915 s32 err = 0;
917 WL_TRACE("Enter\n");
918 CHECK_SYS_UP();
920 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
921 (cfg_priv->conf->rts_threshold != wiphy->rts_threshold)) {
922 cfg_priv->conf->rts_threshold = wiphy->rts_threshold;
923 err = brcmf_set_rts(ndev, cfg_priv->conf->rts_threshold);
924 if (!err)
925 goto done;
927 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
928 (cfg_priv->conf->frag_threshold != wiphy->frag_threshold)) {
929 cfg_priv->conf->frag_threshold = wiphy->frag_threshold;
930 err = brcmf_set_frag(ndev, cfg_priv->conf->frag_threshold);
931 if (!err)
932 goto done;
934 if (changed & WIPHY_PARAM_RETRY_LONG
935 && (cfg_priv->conf->retry_long != wiphy->retry_long)) {
936 cfg_priv->conf->retry_long = wiphy->retry_long;
937 err = brcmf_set_retry(ndev, cfg_priv->conf->retry_long, true);
938 if (!err)
939 goto done;
941 if (changed & WIPHY_PARAM_RETRY_SHORT
942 && (cfg_priv->conf->retry_short != wiphy->retry_short)) {
943 cfg_priv->conf->retry_short = wiphy->retry_short;
944 err = brcmf_set_retry(ndev, cfg_priv->conf->retry_short, false);
945 if (!err)
946 goto done;
949 done:
950 WL_TRACE("Exit\n");
951 return err;
954 static s32
955 brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
956 struct cfg80211_ibss_params *params)
958 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
959 struct brcmf_join_params join_params;
960 size_t join_params_size = 0;
961 s32 err = 0;
962 s32 wsec = 0;
963 s32 bcnprd;
965 WL_TRACE("Enter\n");
966 CHECK_SYS_UP();
968 if (params->ssid)
969 WL_CONN("SSID: %s\n", params->ssid);
970 else {
971 WL_CONN("SSID: NULL, Not supported\n");
972 return -EOPNOTSUPP;
975 set_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
977 if (params->bssid)
978 WL_CONN("BSSID: %02X %02X %02X %02X %02X %02X\n",
979 params->bssid[0], params->bssid[1], params->bssid[2],
980 params->bssid[3], params->bssid[4], params->bssid[5]);
981 else
982 WL_CONN("No BSSID specified\n");
984 if (params->channel)
985 WL_CONN("channel: %d\n", params->channel->center_freq);
986 else
987 WL_CONN("no channel specified\n");
989 if (params->channel_fixed)
990 WL_CONN("fixed channel required\n");
991 else
992 WL_CONN("no fixed channel required\n");
994 if (params->ie && params->ie_len)
995 WL_CONN("ie len: %d\n", params->ie_len);
996 else
997 WL_CONN("no ie specified\n");
999 if (params->beacon_interval)
1000 WL_CONN("beacon interval: %d\n", params->beacon_interval);
1001 else
1002 WL_CONN("no beacon interval specified\n");
1004 if (params->basic_rates)
1005 WL_CONN("basic rates: %08X\n", params->basic_rates);
1006 else
1007 WL_CONN("no basic rates specified\n");
1009 if (params->privacy)
1010 WL_CONN("privacy required\n");
1011 else
1012 WL_CONN("no privacy required\n");
1014 /* Configure Privacy for starter */
1015 if (params->privacy)
1016 wsec |= WEP_ENABLED;
1018 err = brcmf_dev_intvar_set(dev, "wsec", wsec);
1019 if (unlikely(err)) {
1020 WL_ERR("wsec failed (%d)\n", err);
1021 goto done;
1024 /* Configure Beacon Interval for starter */
1025 if (params->beacon_interval)
1026 bcnprd = cpu_to_le32(params->beacon_interval);
1027 else
1028 bcnprd = cpu_to_le32(100);
1030 err = brcmf_dev_ioctl(dev, BRCM_SET_BCNPRD, &bcnprd, sizeof(bcnprd));
1031 if (unlikely(err)) {
1032 WL_ERR("WLC_SET_BCNPRD failed (%d)\n", err);
1033 goto done;
1036 /* Configure required join parameter */
1037 memset(&join_params, 0, sizeof(struct brcmf_join_params));
1039 /* SSID */
1040 join_params.ssid.SSID_len =
1041 (params->ssid_len > 32) ? 32 : params->ssid_len;
1042 memcpy(join_params.ssid.SSID, params->ssid, join_params.ssid.SSID_len);
1043 join_params.ssid.SSID_len = cpu_to_le32(join_params.ssid.SSID_len);
1044 join_params_size = sizeof(join_params.ssid);
1045 brcmf_update_prof(cfg_priv, NULL, &join_params.ssid, WL_PROF_SSID);
1047 /* BSSID */
1048 if (params->bssid) {
1049 memcpy(join_params.params.bssid, params->bssid, ETH_ALEN);
1050 join_params_size = sizeof(join_params.ssid) +
1051 BRCMF_ASSOC_PARAMS_FIXED_SIZE;
1052 } else {
1053 memcpy(join_params.params.bssid, ether_bcast, ETH_ALEN);
1056 brcmf_update_prof(cfg_priv, NULL,
1057 &join_params.params.bssid, WL_PROF_BSSID);
1059 /* Channel */
1060 if (params->channel) {
1061 u32 target_channel;
1063 cfg_priv->channel =
1064 ieee80211_frequency_to_channel(
1065 params->channel->center_freq);
1066 if (params->channel_fixed) {
1067 /* adding chanspec */
1068 brcmf_ch_to_chanspec(cfg_priv->channel,
1069 &join_params, &join_params_size);
1072 /* set channel for starter */
1073 target_channel = cpu_to_le32(cfg_priv->channel);
1074 err = brcmf_dev_ioctl(dev, BRCM_SET_CHANNEL,
1075 &target_channel, sizeof(target_channel));
1076 if (unlikely(err)) {
1077 WL_ERR("WLC_SET_CHANNEL failed (%d)\n", err);
1078 goto done;
1080 } else
1081 cfg_priv->channel = 0;
1083 cfg_priv->ibss_starter = false;
1086 err = brcmf_dev_ioctl(dev, BRCMF_C_SET_SSID,
1087 &join_params, join_params_size);
1088 if (unlikely(err)) {
1089 WL_ERR("WLC_SET_SSID failed (%d)\n", err);
1090 goto done;
1093 done:
1094 if (err)
1095 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
1096 WL_TRACE("Exit\n");
1097 return err;
1100 static s32
1101 brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
1103 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1104 s32 err = 0;
1106 WL_TRACE("Enter\n");
1107 CHECK_SYS_UP();
1109 brcmf_link_down(cfg_priv);
1111 WL_TRACE("Exit\n");
1113 return err;
1116 static s32 brcmf_set_wpa_version(struct net_device *dev,
1117 struct cfg80211_connect_params *sme)
1119 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(dev);
1120 struct brcmf_cfg80211_security *sec;
1121 s32 val = 0;
1122 s32 err = 0;
1124 if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1125 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
1126 else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1127 val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
1128 else
1129 val = WPA_AUTH_DISABLED;
1130 WL_CONN("setting wpa_auth to 0x%0x\n", val);
1131 err = brcmf_dev_intvar_set(dev, "wpa_auth", val);
1132 if (unlikely(err)) {
1133 WL_ERR("set wpa_auth failed (%d)\n", err);
1134 return err;
1136 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1137 sec->wpa_versions = sme->crypto.wpa_versions;
1138 return err;
1141 static s32
1142 brcmf_set_auth_type(struct net_device *dev, struct cfg80211_connect_params *sme)
1144 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(dev);
1145 struct brcmf_cfg80211_security *sec;
1146 s32 val = 0;
1147 s32 err = 0;
1149 switch (sme->auth_type) {
1150 case NL80211_AUTHTYPE_OPEN_SYSTEM:
1151 val = 0;
1152 WL_CONN("open system\n");
1153 break;
1154 case NL80211_AUTHTYPE_SHARED_KEY:
1155 val = 1;
1156 WL_CONN("shared key\n");
1157 break;
1158 case NL80211_AUTHTYPE_AUTOMATIC:
1159 val = 2;
1160 WL_CONN("automatic\n");
1161 break;
1162 case NL80211_AUTHTYPE_NETWORK_EAP:
1163 WL_CONN("network eap\n");
1164 default:
1165 val = 2;
1166 WL_ERR("invalid auth type (%d)\n", sme->auth_type);
1167 break;
1170 err = brcmf_dev_intvar_set(dev, "auth", val);
1171 if (unlikely(err)) {
1172 WL_ERR("set auth failed (%d)\n", err);
1173 return err;
1175 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1176 sec->auth_type = sme->auth_type;
1177 return err;
1180 static s32
1181 brcmf_set_set_cipher(struct net_device *dev,
1182 struct cfg80211_connect_params *sme)
1184 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(dev);
1185 struct brcmf_cfg80211_security *sec;
1186 s32 pval = 0;
1187 s32 gval = 0;
1188 s32 err = 0;
1190 if (sme->crypto.n_ciphers_pairwise) {
1191 switch (sme->crypto.ciphers_pairwise[0]) {
1192 case WLAN_CIPHER_SUITE_WEP40:
1193 case WLAN_CIPHER_SUITE_WEP104:
1194 pval = WEP_ENABLED;
1195 break;
1196 case WLAN_CIPHER_SUITE_TKIP:
1197 pval = TKIP_ENABLED;
1198 break;
1199 case WLAN_CIPHER_SUITE_CCMP:
1200 pval = AES_ENABLED;
1201 break;
1202 case WLAN_CIPHER_SUITE_AES_CMAC:
1203 pval = AES_ENABLED;
1204 break;
1205 default:
1206 WL_ERR("invalid cipher pairwise (%d)\n",
1207 sme->crypto.ciphers_pairwise[0]);
1208 return -EINVAL;
1211 if (sme->crypto.cipher_group) {
1212 switch (sme->crypto.cipher_group) {
1213 case WLAN_CIPHER_SUITE_WEP40:
1214 case WLAN_CIPHER_SUITE_WEP104:
1215 gval = WEP_ENABLED;
1216 break;
1217 case WLAN_CIPHER_SUITE_TKIP:
1218 gval = TKIP_ENABLED;
1219 break;
1220 case WLAN_CIPHER_SUITE_CCMP:
1221 gval = AES_ENABLED;
1222 break;
1223 case WLAN_CIPHER_SUITE_AES_CMAC:
1224 gval = AES_ENABLED;
1225 break;
1226 default:
1227 WL_ERR("invalid cipher group (%d)\n",
1228 sme->crypto.cipher_group);
1229 return -EINVAL;
1233 WL_CONN("pval (%d) gval (%d)\n", pval, gval);
1234 err = brcmf_dev_intvar_set(dev, "wsec", pval | gval);
1235 if (unlikely(err)) {
1236 WL_ERR("error (%d)\n", err);
1237 return err;
1240 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1241 sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1242 sec->cipher_group = sme->crypto.cipher_group;
1244 return err;
1247 static s32
1248 brcmf_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme)
1250 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(dev);
1251 struct brcmf_cfg80211_security *sec;
1252 s32 val = 0;
1253 s32 err = 0;
1255 if (sme->crypto.n_akm_suites) {
1256 err = brcmf_dev_intvar_get(dev, "wpa_auth", &val);
1257 if (unlikely(err)) {
1258 WL_ERR("could not get wpa_auth (%d)\n", err);
1259 return err;
1261 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1262 switch (sme->crypto.akm_suites[0]) {
1263 case WLAN_AKM_SUITE_8021X:
1264 val = WPA_AUTH_UNSPECIFIED;
1265 break;
1266 case WLAN_AKM_SUITE_PSK:
1267 val = WPA_AUTH_PSK;
1268 break;
1269 default:
1270 WL_ERR("invalid cipher group (%d)\n",
1271 sme->crypto.cipher_group);
1272 return -EINVAL;
1274 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1275 switch (sme->crypto.akm_suites[0]) {
1276 case WLAN_AKM_SUITE_8021X:
1277 val = WPA2_AUTH_UNSPECIFIED;
1278 break;
1279 case WLAN_AKM_SUITE_PSK:
1280 val = WPA2_AUTH_PSK;
1281 break;
1282 default:
1283 WL_ERR("invalid cipher group (%d)\n",
1284 sme->crypto.cipher_group);
1285 return -EINVAL;
1289 WL_CONN("setting wpa_auth to %d\n", val);
1290 err = brcmf_dev_intvar_set(dev, "wpa_auth", val);
1291 if (unlikely(err)) {
1292 WL_ERR("could not set wpa_auth (%d)\n", err);
1293 return err;
1296 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1297 sec->wpa_auth = sme->crypto.akm_suites[0];
1299 return err;
1302 static s32
1303 brcmf_set_set_sharedkey(struct net_device *dev,
1304 struct cfg80211_connect_params *sme)
1306 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(dev);
1307 struct brcmf_cfg80211_security *sec;
1308 struct brcmf_wsec_key key;
1309 s32 val;
1310 s32 err = 0;
1312 WL_CONN("key len (%d)\n", sme->key_len);
1313 if (sme->key_len) {
1314 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1315 WL_CONN("wpa_versions 0x%x cipher_pairwise 0x%x\n",
1316 sec->wpa_versions, sec->cipher_pairwise);
1317 if (!
1318 (sec->wpa_versions & (NL80211_WPA_VERSION_1 |
1319 NL80211_WPA_VERSION_2))
1320 && (sec->cipher_pairwise & (WLAN_CIPHER_SUITE_WEP40 |
1321 WLAN_CIPHER_SUITE_WEP104))) {
1322 memset(&key, 0, sizeof(key));
1323 key.len = (u32) sme->key_len;
1324 key.index = (u32) sme->key_idx;
1325 if (unlikely(key.len > sizeof(key.data))) {
1326 WL_ERR("Too long key length (%u)\n", key.len);
1327 return -EINVAL;
1329 memcpy(key.data, sme->key, key.len);
1330 key.flags = BRCMF_PRIMARY_KEY;
1331 switch (sec->cipher_pairwise) {
1332 case WLAN_CIPHER_SUITE_WEP40:
1333 key.algo = CRYPTO_ALGO_WEP1;
1334 break;
1335 case WLAN_CIPHER_SUITE_WEP104:
1336 key.algo = CRYPTO_ALGO_WEP128;
1337 break;
1338 default:
1339 WL_ERR("Invalid algorithm (%d)\n",
1340 sme->crypto.ciphers_pairwise[0]);
1341 return -EINVAL;
1343 /* Set the new key/index */
1344 WL_CONN("key length (%d) key index (%d) algo (%d)\n",
1345 key.len, key.index, key.algo);
1346 WL_CONN("key \"%s\"\n", key.data);
1347 convert_key_from_CPU(&key);
1348 err = brcmf_dev_ioctl(dev, BRCMF_C_SET_KEY, &key,
1349 sizeof(key));
1350 if (unlikely(err)) {
1351 WL_ERR("WLC_SET_KEY error (%d)\n", err);
1352 return err;
1354 if (sec->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) {
1355 WL_CONN("set auth_type to shared key\n");
1356 val = 1; /* shared key */
1357 err = brcmf_dev_intvar_set(dev, "auth", val);
1358 if (unlikely(err)) {
1359 WL_ERR("set auth failed (%d)\n", err);
1360 return err;
1365 return err;
1368 static s32
1369 brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
1370 struct cfg80211_connect_params *sme)
1372 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1373 struct ieee80211_channel *chan = sme->channel;
1374 struct brcmf_join_params join_params;
1375 size_t join_params_size;
1377 s32 err = 0;
1379 WL_TRACE("Enter\n");
1380 CHECK_SYS_UP();
1382 if (unlikely(!sme->ssid)) {
1383 WL_ERR("Invalid ssid\n");
1384 return -EOPNOTSUPP;
1387 set_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
1389 if (chan) {
1390 cfg_priv->channel =
1391 ieee80211_frequency_to_channel(chan->center_freq);
1392 WL_CONN("channel (%d), center_req (%d)\n",
1393 cfg_priv->channel, chan->center_freq);
1394 } else
1395 cfg_priv->channel = 0;
1397 WL_INFO("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
1399 err = brcmf_set_wpa_version(dev, sme);
1400 if (err) {
1401 WL_ERR("wl_set_wpa_version failed (%d)\n", err);
1402 goto done;
1405 err = brcmf_set_auth_type(dev, sme);
1406 if (err) {
1407 WL_ERR("wl_set_auth_type failed (%d)\n", err);
1408 goto done;
1411 err = brcmf_set_set_cipher(dev, sme);
1412 if (err) {
1413 WL_ERR("wl_set_set_cipher failed (%d)\n", err);
1414 goto done;
1417 err = brcmf_set_key_mgmt(dev, sme);
1418 if (err) {
1419 WL_ERR("wl_set_key_mgmt failed (%d)\n", err);
1420 goto done;
1423 err = brcmf_set_set_sharedkey(dev, sme);
1424 if (err) {
1425 WL_ERR("wl_set_set_sharedkey failed (%d)\n", err);
1426 goto done;
1429 memset(&join_params, 0, sizeof(join_params));
1430 join_params_size = sizeof(join_params.ssid);
1432 join_params.ssid.SSID_len =
1433 min(sizeof(join_params.ssid.SSID), sme->ssid_len);
1434 memcpy(&join_params.ssid.SSID, sme->ssid, join_params.ssid.SSID_len);
1435 join_params.ssid.SSID_len = cpu_to_le32(join_params.ssid.SSID_len);
1436 brcmf_update_prof(cfg_priv, NULL, &join_params.ssid, WL_PROF_SSID);
1438 memcpy(join_params.params.bssid, ether_bcast, ETH_ALEN);
1440 if (join_params.ssid.SSID_len < IEEE80211_MAX_SSID_LEN)
1441 WL_CONN("ssid \"%s\", len (%d)\n",
1442 join_params.ssid.SSID, join_params.ssid.SSID_len);
1444 brcmf_ch_to_chanspec(cfg_priv->channel,
1445 &join_params, &join_params_size);
1446 err = brcmf_dev_ioctl(dev, BRCMF_C_SET_SSID,
1447 &join_params, join_params_size);
1448 if (err)
1449 WL_ERR("WLC_SET_SSID failed (%d)\n", err);
1451 done:
1452 if (err)
1453 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
1454 WL_TRACE("Exit\n");
1455 return err;
1458 static s32
1459 brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
1460 u16 reason_code)
1462 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1463 struct brcmf_scb_val scbval;
1464 s32 err = 0;
1466 WL_TRACE("Enter. Reason code = %d\n", reason_code);
1467 CHECK_SYS_UP();
1469 clear_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
1471 scbval.val = reason_code;
1472 memcpy(&scbval.ea, brcmf_read_prof(cfg_priv, WL_PROF_BSSID), ETH_ALEN);
1473 scbval.val = cpu_to_le32(scbval.val);
1474 err = brcmf_dev_ioctl(dev, BRCMF_C_DISASSOC, &scbval,
1475 sizeof(struct brcmf_scb_val));
1476 if (unlikely(err))
1477 WL_ERR("error (%d)\n", err);
1479 cfg_priv->link_up = false;
1481 WL_TRACE("Exit\n");
1482 return err;
1485 static s32
1486 brcmf_cfg80211_set_tx_power(struct wiphy *wiphy,
1487 enum nl80211_tx_power_setting type, s32 dbm)
1490 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1491 struct net_device *ndev = cfg_to_ndev(cfg_priv);
1492 u16 txpwrmw;
1493 s32 err = 0;
1494 s32 disable = 0;
1496 WL_TRACE("Enter\n");
1497 CHECK_SYS_UP();
1499 switch (type) {
1500 case NL80211_TX_POWER_AUTOMATIC:
1501 break;
1502 case NL80211_TX_POWER_LIMITED:
1503 if (dbm < 0) {
1504 WL_ERR("TX_POWER_LIMITED - dbm is negative\n");
1505 err = -EINVAL;
1506 goto done;
1508 break;
1509 case NL80211_TX_POWER_FIXED:
1510 if (dbm < 0) {
1511 WL_ERR("TX_POWER_FIXED - dbm is negative\n");
1512 err = -EINVAL;
1513 goto done;
1515 break;
1517 /* Make sure radio is off or on as far as software is concerned */
1518 disable = WL_RADIO_SW_DISABLE << 16;
1519 disable = cpu_to_le32(disable);
1520 err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_RADIO, &disable,
1521 sizeof(disable));
1522 if (unlikely(err))
1523 WL_ERR("WLC_SET_RADIO error (%d)\n", err);
1525 if (dbm > 0xffff)
1526 txpwrmw = 0xffff;
1527 else
1528 txpwrmw = (u16) dbm;
1529 err = brcmf_dev_intvar_set(ndev, "qtxpower",
1530 (s32) (brcmu_mw_to_qdbm(txpwrmw)));
1531 if (unlikely(err))
1532 WL_ERR("qtxpower error (%d)\n", err);
1533 cfg_priv->conf->tx_power = dbm;
1535 done:
1536 WL_TRACE("Exit\n");
1537 return err;
1540 static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm)
1542 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1543 struct net_device *ndev = cfg_to_ndev(cfg_priv);
1544 s32 txpwrdbm;
1545 u8 result;
1546 s32 err = 0;
1548 WL_TRACE("Enter\n");
1549 CHECK_SYS_UP();
1551 err = brcmf_dev_intvar_get(ndev, "qtxpower", &txpwrdbm);
1552 if (unlikely(err)) {
1553 WL_ERR("error (%d)\n", err);
1554 goto done;
1557 result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
1558 *dbm = (s32) brcmu_qdbm_to_mw(result);
1560 done:
1561 WL_TRACE("Exit\n");
1562 return err;
1565 static s32
1566 brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *dev,
1567 u8 key_idx, bool unicast, bool multicast)
1569 u32 index;
1570 s32 wsec;
1571 s32 err = 0;
1573 WL_TRACE("Enter\n");
1574 WL_CONN("key index (%d)\n", key_idx);
1575 CHECK_SYS_UP();
1577 err = brcmf_dev_ioctl(dev, BRCMF_C_GET_WSEC, &wsec, sizeof(wsec));
1578 if (unlikely(err)) {
1579 WL_ERR("WLC_GET_WSEC error (%d)\n", err);
1580 goto done;
1583 wsec = le32_to_cpu(wsec);
1584 if (wsec & WEP_ENABLED) {
1585 /* Just select a new current key */
1586 index = (u32) key_idx;
1587 index = cpu_to_le32(index);
1588 err = brcmf_dev_ioctl(dev, BRCMF_C_SET_KEY_PRIMARY, &index,
1589 sizeof(index));
1590 if (unlikely(err))
1591 WL_ERR("error (%d)\n", err);
1593 done:
1594 WL_TRACE("Exit\n");
1595 return err;
1598 static s32
1599 brcmf_add_keyext(struct wiphy *wiphy, struct net_device *dev,
1600 u8 key_idx, const u8 *mac_addr, struct key_params *params)
1602 struct brcmf_wsec_key key;
1603 s32 err = 0;
1605 memset(&key, 0, sizeof(key));
1606 key.index = (u32) key_idx;
1607 /* Instead of bcast for ea address for default wep keys,
1608 driver needs it to be Null */
1609 if (!is_multicast_ether_addr(mac_addr))
1610 memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
1611 key.len = (u32) params->key_len;
1612 /* check for key index change */
1613 if (key.len == 0) {
1614 /* key delete */
1615 convert_key_from_CPU(&key);
1616 err = brcmf_dev_ioctl(dev, BRCMF_C_SET_KEY, &key, sizeof(key));
1617 if (unlikely(err)) {
1618 WL_ERR("key delete error (%d)\n", err);
1619 return err;
1621 } else {
1622 if (key.len > sizeof(key.data)) {
1623 WL_ERR("Invalid key length (%d)\n", key.len);
1624 return -EINVAL;
1627 WL_CONN("Setting the key index %d\n", key.index);
1628 memcpy(key.data, params->key, key.len);
1630 if (params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1631 u8 keybuf[8];
1632 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1633 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1634 memcpy(&key.data[16], keybuf, sizeof(keybuf));
1637 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
1638 if (params->seq && params->seq_len == 6) {
1639 /* rx iv */
1640 u8 *ivptr;
1641 ivptr = (u8 *) params->seq;
1642 key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
1643 (ivptr[3] << 8) | ivptr[2];
1644 key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
1645 key.iv_initialized = true;
1648 switch (params->cipher) {
1649 case WLAN_CIPHER_SUITE_WEP40:
1650 key.algo = CRYPTO_ALGO_WEP1;
1651 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1652 break;
1653 case WLAN_CIPHER_SUITE_WEP104:
1654 key.algo = CRYPTO_ALGO_WEP128;
1655 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1656 break;
1657 case WLAN_CIPHER_SUITE_TKIP:
1658 key.algo = CRYPTO_ALGO_TKIP;
1659 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1660 break;
1661 case WLAN_CIPHER_SUITE_AES_CMAC:
1662 key.algo = CRYPTO_ALGO_AES_CCM;
1663 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1664 break;
1665 case WLAN_CIPHER_SUITE_CCMP:
1666 key.algo = CRYPTO_ALGO_AES_CCM;
1667 WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
1668 break;
1669 default:
1670 WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
1671 return -EINVAL;
1673 convert_key_from_CPU(&key);
1675 brcmf_netdev_wait_pend8021x(dev);
1676 err = brcmf_dev_ioctl(dev, BRCMF_C_SET_KEY, &key, sizeof(key));
1677 if (unlikely(err)) {
1678 WL_ERR("WLC_SET_KEY error (%d)\n", err);
1679 return err;
1682 return err;
1685 static s32
1686 brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
1687 u8 key_idx, bool pairwise, const u8 *mac_addr,
1688 struct key_params *params)
1690 struct brcmf_wsec_key key;
1691 s32 val;
1692 s32 wsec;
1693 s32 err = 0;
1694 u8 keybuf[8];
1696 WL_TRACE("Enter\n");
1697 WL_CONN("key index (%d)\n", key_idx);
1698 CHECK_SYS_UP();
1700 if (mac_addr) {
1701 WL_TRACE("Exit");
1702 return brcmf_add_keyext(wiphy, dev, key_idx, mac_addr, params);
1704 memset(&key, 0, sizeof(key));
1706 key.len = (u32) params->key_len;
1707 key.index = (u32) key_idx;
1709 if (unlikely(key.len > sizeof(key.data))) {
1710 WL_ERR("Too long key length (%u)\n", key.len);
1711 err = -EINVAL;
1712 goto done;
1714 memcpy(key.data, params->key, key.len);
1716 key.flags = BRCMF_PRIMARY_KEY;
1717 switch (params->cipher) {
1718 case WLAN_CIPHER_SUITE_WEP40:
1719 key.algo = CRYPTO_ALGO_WEP1;
1720 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1721 break;
1722 case WLAN_CIPHER_SUITE_WEP104:
1723 key.algo = CRYPTO_ALGO_WEP128;
1724 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1725 break;
1726 case WLAN_CIPHER_SUITE_TKIP:
1727 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1728 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1729 memcpy(&key.data[16], keybuf, sizeof(keybuf));
1730 key.algo = CRYPTO_ALGO_TKIP;
1731 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1732 break;
1733 case WLAN_CIPHER_SUITE_AES_CMAC:
1734 key.algo = CRYPTO_ALGO_AES_CCM;
1735 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1736 break;
1737 case WLAN_CIPHER_SUITE_CCMP:
1738 key.algo = CRYPTO_ALGO_AES_CCM;
1739 WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
1740 break;
1741 default:
1742 WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
1743 err = -EINVAL;
1744 goto done;
1747 /* Set the new key/index */
1748 convert_key_from_CPU(&key);
1749 err = brcmf_dev_ioctl(dev, BRCMF_C_SET_KEY, &key, sizeof(key));
1750 if (unlikely(err)) {
1751 WL_ERR("WLC_SET_KEY error (%d)\n", err);
1752 goto done;
1755 val = WEP_ENABLED;
1756 err = brcmf_dev_intvar_get(dev, "wsec", &wsec);
1757 if (unlikely(err)) {
1758 WL_ERR("get wsec error (%d)\n", err);
1759 goto done;
1761 wsec &= ~(WEP_ENABLED);
1762 wsec |= val;
1763 err = brcmf_dev_intvar_set(dev, "wsec", wsec);
1764 if (unlikely(err)) {
1765 WL_ERR("set wsec error (%d)\n", err);
1766 goto done;
1769 val = 1; /* assume shared key. otherwise 0 */
1770 val = cpu_to_le32(val);
1771 err = brcmf_dev_ioctl(dev, BRCMF_C_SET_AUTH, &val, sizeof(val));
1772 if (unlikely(err))
1773 WL_ERR("WLC_SET_AUTH error (%d)\n", err);
1774 done:
1775 WL_TRACE("Exit\n");
1776 return err;
1779 static s32
1780 brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
1781 u8 key_idx, bool pairwise, const u8 *mac_addr)
1783 struct brcmf_wsec_key key;
1784 s32 err = 0;
1785 s32 val;
1786 s32 wsec;
1788 WL_TRACE("Enter\n");
1789 CHECK_SYS_UP();
1790 memset(&key, 0, sizeof(key));
1792 key.index = (u32) key_idx;
1793 key.flags = BRCMF_PRIMARY_KEY;
1794 key.algo = CRYPTO_ALGO_OFF;
1796 WL_CONN("key index (%d)\n", key_idx);
1797 /* Set the new key/index */
1798 convert_key_from_CPU(&key);
1799 err = brcmf_dev_ioctl(dev, BRCMF_C_SET_KEY, &key, sizeof(key));
1800 if (unlikely(err)) {
1801 if (err == -EINVAL) {
1802 if (key.index >= DOT11_MAX_DEFAULT_KEYS)
1803 /* we ignore this key index in this case */
1804 WL_ERR("invalid key index (%d)\n", key_idx);
1805 } else
1806 WL_ERR("WLC_SET_KEY error (%d)\n", err);
1808 /* Ignore this error, may happen during DISASSOC */
1809 err = -EAGAIN;
1810 goto done;
1813 val = 0;
1814 err = brcmf_dev_intvar_get(dev, "wsec", &wsec);
1815 if (unlikely(err)) {
1816 WL_ERR("get wsec error (%d)\n", err);
1817 /* Ignore this error, may happen during DISASSOC */
1818 err = -EAGAIN;
1819 goto done;
1821 wsec &= ~(WEP_ENABLED);
1822 wsec |= val;
1823 err = brcmf_dev_intvar_set(dev, "wsec", wsec);
1824 if (unlikely(err)) {
1825 WL_ERR("set wsec error (%d)\n", err);
1826 /* Ignore this error, may happen during DISASSOC */
1827 err = -EAGAIN;
1828 goto done;
1831 val = 0; /* assume open key. otherwise 1 */
1832 val = cpu_to_le32(val);
1833 err = brcmf_dev_ioctl(dev, BRCMF_C_SET_AUTH, &val, sizeof(val));
1834 if (unlikely(err)) {
1835 WL_ERR("WLC_SET_AUTH error (%d)\n", err);
1836 /* Ignore this error, may happen during DISASSOC */
1837 err = -EAGAIN;
1839 done:
1840 WL_TRACE("Exit\n");
1841 return err;
1844 static s32
1845 brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
1846 u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
1847 void (*callback) (void *cookie, struct key_params * params))
1849 struct key_params params;
1850 struct brcmf_wsec_key key;
1851 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1852 struct brcmf_cfg80211_security *sec;
1853 s32 wsec;
1854 s32 err = 0;
1856 WL_TRACE("Enter\n");
1857 WL_CONN("key index (%d)\n", key_idx);
1858 CHECK_SYS_UP();
1860 memset(&key, 0, sizeof(key));
1861 key.index = key_idx;
1862 convert_key_to_CPU(&key);
1863 memset(&params, 0, sizeof(params));
1864 params.key_len = (u8) min_t(u8, WLAN_MAX_KEY_LEN, key.len);
1865 memcpy(params.key, key.data, params.key_len);
1867 err = brcmf_dev_ioctl(dev, BRCMF_C_GET_WSEC, &wsec, sizeof(wsec));
1868 if (unlikely(err)) {
1869 WL_ERR("WLC_GET_WSEC error (%d)\n", err);
1870 /* Ignore this error, may happen during DISASSOC */
1871 err = -EAGAIN;
1872 goto done;
1874 wsec = le32_to_cpu(wsec);
1875 switch (wsec) {
1876 case WEP_ENABLED:
1877 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1878 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
1879 params.cipher = WLAN_CIPHER_SUITE_WEP40;
1880 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1881 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
1882 params.cipher = WLAN_CIPHER_SUITE_WEP104;
1883 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1885 break;
1886 case TKIP_ENABLED:
1887 params.cipher = WLAN_CIPHER_SUITE_TKIP;
1888 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1889 break;
1890 case AES_ENABLED:
1891 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
1892 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1893 break;
1894 default:
1895 WL_ERR("Invalid algo (0x%x)\n", wsec);
1896 err = -EINVAL;
1897 goto done;
1899 callback(cookie, &params);
1901 done:
1902 WL_TRACE("Exit\n");
1903 return err;
1906 static s32
1907 brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
1908 struct net_device *dev, u8 key_idx)
1910 WL_INFO("Not supported\n");
1912 CHECK_SYS_UP();
1913 return -EOPNOTSUPP;
1916 static s32
1917 brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
1918 u8 *mac, struct station_info *sinfo)
1920 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1921 struct brcmf_scb_val scb_val;
1922 int rssi;
1923 s32 rate;
1924 s32 err = 0;
1925 u8 *bssid = brcmf_read_prof(cfg_priv, WL_PROF_BSSID);
1927 WL_TRACE("Enter\n");
1928 CHECK_SYS_UP();
1930 if (unlikely
1931 (memcmp(mac, bssid, ETH_ALEN))) {
1932 WL_ERR("Wrong Mac address cfg_mac-%X:%X:%X:%X:%X:%X"
1933 "wl_bssid-%X:%X:%X:%X:%X:%X\n",
1934 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
1935 bssid[0], bssid[1], bssid[2], bssid[3],
1936 bssid[4], bssid[5]);
1937 err = -ENOENT;
1938 goto done;
1941 /* Report the current tx rate */
1942 err = brcmf_dev_ioctl(dev, BRCMF_C_GET_RATE, &rate, sizeof(rate));
1943 if (err) {
1944 WL_ERR("Could not get rate (%d)\n", err);
1945 } else {
1946 rate = le32_to_cpu(rate);
1947 sinfo->filled |= STATION_INFO_TX_BITRATE;
1948 sinfo->txrate.legacy = rate * 5;
1949 WL_CONN("Rate %d Mbps\n", rate / 2);
1952 if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status)) {
1953 scb_val.val = 0;
1954 err = brcmf_dev_ioctl(dev, BRCMF_C_GET_RSSI, &scb_val,
1955 sizeof(struct brcmf_scb_val));
1956 if (unlikely(err))
1957 WL_ERR("Could not get rssi (%d)\n", err);
1959 rssi = le32_to_cpu(scb_val.val);
1960 sinfo->filled |= STATION_INFO_SIGNAL;
1961 sinfo->signal = rssi;
1962 WL_CONN("RSSI %d dBm\n", rssi);
1965 done:
1966 WL_TRACE("Exit\n");
1967 return err;
1970 static s32
1971 brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
1972 bool enabled, s32 timeout)
1974 s32 pm;
1975 s32 err = 0;
1976 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1978 WL_TRACE("Enter\n");
1981 * Powersave enable/disable request is coming from the
1982 * cfg80211 even before the interface is up. In that
1983 * scenario, driver will be storing the power save
1984 * preference in cfg_priv struct to apply this to
1985 * FW later while initializing the dongle
1987 cfg_priv->pwr_save = enabled;
1988 if (!test_bit(WL_STATUS_READY, &cfg_priv->status)) {
1990 WL_INFO("Device is not ready,"
1991 "storing the value in cfg_priv struct\n");
1992 goto done;
1995 pm = enabled ? PM_FAST : PM_OFF;
1996 pm = cpu_to_le32(pm);
1997 WL_INFO("power save %s\n", (pm ? "enabled" : "disabled"));
1999 err = brcmf_dev_ioctl(dev, BRCMF_C_SET_PM, &pm, sizeof(pm));
2000 if (unlikely(err)) {
2001 if (err == -ENODEV)
2002 WL_ERR("net_device is not ready yet\n");
2003 else
2004 WL_ERR("error (%d)\n", err);
2006 done:
2007 WL_TRACE("Exit\n");
2008 return err;
2011 static __used u32 brcmf_find_msb(u16 bit16)
2013 u32 ret = 0;
2015 if (bit16 & 0xff00) {
2016 ret += 8;
2017 bit16 >>= 8;
2020 if (bit16 & 0xf0) {
2021 ret += 4;
2022 bit16 >>= 4;
2025 if (bit16 & 0xc) {
2026 ret += 2;
2027 bit16 >>= 2;
2030 if (bit16 & 2)
2031 ret += bit16 & 2;
2032 else if (bit16)
2033 ret += bit16;
2035 return ret;
2038 static s32
2039 brcmf_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev,
2040 const u8 *addr,
2041 const struct cfg80211_bitrate_mask *mask)
2043 struct brcm_rateset rateset;
2044 s32 rate;
2045 s32 val;
2046 s32 err_bg;
2047 s32 err_a;
2048 u32 legacy;
2049 s32 err = 0;
2051 WL_TRACE("Enter\n");
2052 CHECK_SYS_UP();
2054 /* addr param is always NULL. ignore it */
2055 /* Get current rateset */
2056 err = brcmf_dev_ioctl(dev, BRCM_GET_CURR_RATESET, &rateset,
2057 sizeof(rateset));
2058 if (unlikely(err)) {
2059 WL_ERR("could not get current rateset (%d)\n", err);
2060 goto done;
2063 rateset.count = le32_to_cpu(rateset.count);
2065 legacy = brcmf_find_msb(mask->control[IEEE80211_BAND_2GHZ].legacy);
2066 if (!legacy)
2067 legacy = brcmf_find_msb(
2068 mask->control[IEEE80211_BAND_5GHZ].legacy);
2070 val = wl_g_rates[legacy - 1].bitrate * 100000;
2072 if (val < rateset.count)
2073 /* Select rate by rateset index */
2074 rate = rateset.rates[val] & 0x7f;
2075 else
2076 /* Specified rate in bps */
2077 rate = val / 500000;
2079 WL_CONN("rate %d mbps\n", rate / 2);
2083 * Set rate override,
2084 * Since the is a/b/g-blind, both a/bg_rate are enforced.
2086 err_bg = brcmf_dev_intvar_set(dev, "bg_rate", rate);
2087 err_a = brcmf_dev_intvar_set(dev, "a_rate", rate);
2088 if (unlikely(err_bg && err_a)) {
2089 WL_ERR("could not set fixed rate (%d) (%d)\n", err_bg, err_a);
2090 err = err_bg | err_a;
2093 done:
2094 WL_TRACE("Exit\n");
2095 return err;
2098 static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
2100 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2103 * Check for WL_STATUS_READY before any function call which
2104 * could result is bus access. Don't block the resume for
2105 * any driver error conditions
2107 WL_TRACE("Enter\n");
2109 if (test_bit(WL_STATUS_READY, &cfg_priv->status))
2110 brcmf_invoke_iscan(wiphy_to_cfg(wiphy));
2112 WL_TRACE("Exit\n");
2113 return 0;
2116 static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
2117 struct cfg80211_wowlan *wow)
2119 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2120 struct net_device *ndev = cfg_to_ndev(cfg_priv);
2122 WL_TRACE("Enter\n");
2125 * Check for WL_STATUS_READY before any function call which
2126 * could result is bus access. Don't block the suspend for
2127 * any driver error conditions
2131 * While going to suspend if associated with AP disassociate
2132 * from AP to save power while system is in suspended state
2134 if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) ||
2135 test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) &&
2136 test_bit(WL_STATUS_READY, &cfg_priv->status)) {
2137 WL_INFO("Disassociating from AP"
2138 " while entering suspend state\n");
2139 brcmf_link_down(cfg_priv);
2142 * Make sure WPA_Supplicant receives all the event
2143 * generated due to DISASSOC call to the fw to keep
2144 * the state fw and WPA_Supplicant state consistent
2146 rtnl_unlock();
2147 brcmf_delay(500);
2148 rtnl_lock();
2151 set_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
2152 if (test_bit(WL_STATUS_READY, &cfg_priv->status))
2153 brcmf_term_iscan(cfg_priv);
2155 if (cfg_priv->scan_request) {
2156 /* Indidate scan abort to cfg80211 layer */
2157 WL_INFO("Terminating scan in progress\n");
2158 cfg80211_scan_done(cfg_priv->scan_request, true);
2159 cfg_priv->scan_request = NULL;
2161 clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
2162 clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
2164 /* Turn off watchdog timer */
2165 if (test_bit(WL_STATUS_READY, &cfg_priv->status)) {
2166 WL_INFO("Enable MPC\n");
2167 brcmf_set_mpc(ndev, 1);
2170 WL_TRACE("Exit\n");
2172 return 0;
2175 static __used s32
2176 brcmf_update_pmklist(struct net_device *dev,
2177 struct brcmf_cfg80211_pmk_list *pmk_list, s32 err)
2179 int i, j;
2181 WL_CONN("No of elements %d\n", pmk_list->pmkids.npmkid);
2182 for (i = 0; i < pmk_list->pmkids.npmkid; i++) {
2183 WL_CONN("PMKID[%d]: %pM =\n", i,
2184 &pmk_list->pmkids.pmkid[i].BSSID);
2185 for (j = 0; j < WLAN_PMKID_LEN; j++)
2186 WL_CONN("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]);
2189 if (likely(!err))
2190 brcmf_dev_bufvar_set(dev, "pmkid_info", (char *)pmk_list,
2191 sizeof(*pmk_list));
2193 return err;
2196 static s32
2197 brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
2198 struct cfg80211_pmksa *pmksa)
2200 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2201 struct pmkid_list *pmkids = &cfg_priv->pmk_list->pmkids;
2202 s32 err = 0;
2203 int i;
2205 WL_TRACE("Enter\n");
2206 CHECK_SYS_UP();
2208 for (i = 0; i < pmkids->npmkid; i++)
2209 if (!memcmp(pmksa->bssid, pmkids->pmkid[i].BSSID, ETH_ALEN))
2210 break;
2211 if (i < WL_NUM_PMKIDS_MAX) {
2212 memcpy(pmkids->pmkid[i].BSSID, pmksa->bssid, ETH_ALEN);
2213 memcpy(pmkids->pmkid[i].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2214 if (i == pmkids->npmkid)
2215 pmkids->npmkid++;
2216 } else
2217 err = -EINVAL;
2219 WL_CONN("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2220 pmkids->pmkid[pmkids->npmkid].BSSID);
2221 for (i = 0; i < WLAN_PMKID_LEN; i++)
2222 WL_CONN("%02x\n", pmkids->pmkid[pmkids->npmkid].PMKID[i]);
2224 err = brcmf_update_pmklist(dev, cfg_priv->pmk_list, err);
2226 WL_TRACE("Exit\n");
2227 return err;
2230 static s32
2231 brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
2232 struct cfg80211_pmksa *pmksa)
2234 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2235 struct pmkid_list pmkid;
2236 s32 err = 0;
2237 int i;
2239 WL_TRACE("Enter\n");
2240 CHECK_SYS_UP();
2241 memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
2242 memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2244 WL_CONN("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2245 &pmkid.pmkid[0].BSSID);
2246 for (i = 0; i < WLAN_PMKID_LEN; i++)
2247 WL_CONN("%02x\n", pmkid.pmkid[0].PMKID[i]);
2249 for (i = 0; i < cfg_priv->pmk_list->pmkids.npmkid; i++)
2250 if (!memcmp
2251 (pmksa->bssid, &cfg_priv->pmk_list->pmkids.pmkid[i].BSSID,
2252 ETH_ALEN))
2253 break;
2255 if ((cfg_priv->pmk_list->pmkids.npmkid > 0)
2256 && (i < cfg_priv->pmk_list->pmkids.npmkid)) {
2257 memset(&cfg_priv->pmk_list->pmkids.pmkid[i], 0,
2258 sizeof(struct pmkid));
2259 for (; i < (cfg_priv->pmk_list->pmkids.npmkid - 1); i++) {
2260 memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].BSSID,
2261 &cfg_priv->pmk_list->pmkids.pmkid[i + 1].BSSID,
2262 ETH_ALEN);
2263 memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].PMKID,
2264 &cfg_priv->pmk_list->pmkids.pmkid[i + 1].PMKID,
2265 WLAN_PMKID_LEN);
2267 cfg_priv->pmk_list->pmkids.npmkid--;
2268 } else
2269 err = -EINVAL;
2271 err = brcmf_update_pmklist(dev, cfg_priv->pmk_list, err);
2273 WL_TRACE("Exit\n");
2274 return err;
2278 static s32
2279 brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
2281 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2282 s32 err = 0;
2284 WL_TRACE("Enter\n");
2285 CHECK_SYS_UP();
2287 memset(cfg_priv->pmk_list, 0, sizeof(*cfg_priv->pmk_list));
2288 err = brcmf_update_pmklist(dev, cfg_priv->pmk_list, err);
2290 WL_TRACE("Exit\n");
2291 return err;
2295 static struct cfg80211_ops wl_cfg80211_ops = {
2296 .change_virtual_intf = brcmf_cfg80211_change_iface,
2297 .scan = brcmf_cfg80211_scan,
2298 .set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
2299 .join_ibss = brcmf_cfg80211_join_ibss,
2300 .leave_ibss = brcmf_cfg80211_leave_ibss,
2301 .get_station = brcmf_cfg80211_get_station,
2302 .set_tx_power = brcmf_cfg80211_set_tx_power,
2303 .get_tx_power = brcmf_cfg80211_get_tx_power,
2304 .add_key = brcmf_cfg80211_add_key,
2305 .del_key = brcmf_cfg80211_del_key,
2306 .get_key = brcmf_cfg80211_get_key,
2307 .set_default_key = brcmf_cfg80211_config_default_key,
2308 .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
2309 .set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
2310 .set_bitrate_mask = brcmf_cfg80211_set_bitrate_mask,
2311 .connect = brcmf_cfg80211_connect,
2312 .disconnect = brcmf_cfg80211_disconnect,
2313 .suspend = brcmf_cfg80211_suspend,
2314 .resume = brcmf_cfg80211_resume,
2315 .set_pmksa = brcmf_cfg80211_set_pmksa,
2316 .del_pmksa = brcmf_cfg80211_del_pmksa,
2317 .flush_pmksa = brcmf_cfg80211_flush_pmksa
2320 static s32 brcmf_mode_to_nl80211_iftype(s32 mode)
2322 s32 err = 0;
2324 switch (mode) {
2325 case WL_MODE_BSS:
2326 return NL80211_IFTYPE_STATION;
2327 case WL_MODE_IBSS:
2328 return NL80211_IFTYPE_ADHOC;
2329 default:
2330 return NL80211_IFTYPE_UNSPECIFIED;
2333 return err;
2336 static struct wireless_dev *brcmf_alloc_wdev(s32 sizeof_iface,
2337 struct device *dev)
2339 struct wireless_dev *wdev;
2340 s32 err = 0;
2342 wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
2343 if (unlikely(!wdev)) {
2344 WL_ERR("Could not allocate wireless device\n");
2345 return ERR_PTR(-ENOMEM);
2347 wdev->wiphy =
2348 wiphy_new(&wl_cfg80211_ops,
2349 sizeof(struct brcmf_cfg80211_priv) + sizeof_iface);
2350 if (unlikely(!wdev->wiphy)) {
2351 WL_ERR("Couldn not allocate wiphy device\n");
2352 err = -ENOMEM;
2353 goto wiphy_new_out;
2355 set_wiphy_dev(wdev->wiphy, dev);
2356 wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
2357 wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
2358 wdev->wiphy->interface_modes =
2359 BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
2360 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
2361 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a; /* Set
2362 * it as 11a by default.
2363 * This will be updated with
2364 * 11n phy tables in
2365 * "ifconfig up"
2366 * if phy has 11n capability
2368 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2369 wdev->wiphy->cipher_suites = __wl_cipher_suites;
2370 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
2371 #ifndef WL_POWERSAVE_DISABLED
2372 wdev->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; /* enable power
2373 * save mode
2374 * by default
2376 #else
2377 wdev->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
2378 #endif /* !WL_POWERSAVE_DISABLED */
2379 err = wiphy_register(wdev->wiphy);
2380 if (unlikely(err < 0)) {
2381 WL_ERR("Couldn not register wiphy device (%d)\n", err);
2382 goto wiphy_register_out;
2384 return wdev;
2386 wiphy_register_out:
2387 wiphy_free(wdev->wiphy);
2389 wiphy_new_out:
2390 kfree(wdev);
2392 return ERR_PTR(err);
2395 static void brcmf_free_wdev(struct brcmf_cfg80211_priv *cfg_priv)
2397 struct wireless_dev *wdev = cfg_to_wdev(cfg_priv);
2399 if (unlikely(!wdev)) {
2400 WL_ERR("wdev is invalid\n");
2401 return;
2403 wiphy_unregister(wdev->wiphy);
2404 wiphy_free(wdev->wiphy);
2405 kfree(wdev);
2406 cfg_to_wdev(cfg_priv) = NULL;
2409 static s32 brcmf_inform_bss(struct brcmf_cfg80211_priv *cfg_priv)
2411 struct brcmf_scan_results *bss_list;
2412 struct brcmf_bss_info *bi = NULL; /* must be initialized */
2413 s32 err = 0;
2414 int i;
2416 bss_list = cfg_priv->bss_list;
2417 if (unlikely(bss_list->version != BRCMF_BSS_INFO_VERSION)) {
2418 WL_ERR("Version %d != WL_BSS_INFO_VERSION\n",
2419 bss_list->version);
2420 return -EOPNOTSUPP;
2422 WL_SCAN("scanned AP count (%d)\n", bss_list->count);
2423 bi = next_bss(bss_list, bi);
2424 for_each_bss(bss_list, bi, i) {
2425 err = brcmf_inform_single_bss(cfg_priv, bi);
2426 if (unlikely(err))
2427 break;
2429 return err;
2433 static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv,
2434 struct brcmf_bss_info *bi)
2436 struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
2437 struct ieee80211_channel *notify_channel;
2438 struct cfg80211_bss *bss;
2439 struct ieee80211_supported_band *band;
2440 s32 err = 0;
2441 u16 channel;
2442 u32 freq;
2443 u64 notify_timestamp;
2444 u16 notify_capability;
2445 u16 notify_interval;
2446 u8 *notify_ie;
2447 size_t notify_ielen;
2448 s32 notify_signal;
2450 if (unlikely(le32_to_cpu(bi->length) > WL_BSS_INFO_MAX)) {
2451 WL_ERR("Bss info is larger than buffer. Discarding\n");
2452 return 0;
2455 channel = bi->ctl_ch ? bi->ctl_ch :
2456 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2458 if (channel <= CH_MAX_2G_CHANNEL)
2459 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2460 else
2461 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2463 freq = ieee80211_channel_to_frequency(channel, band->band);
2464 notify_channel = ieee80211_get_channel(wiphy, freq);
2466 notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */
2467 notify_capability = le16_to_cpu(bi->capability);
2468 notify_interval = le16_to_cpu(bi->beacon_period);
2469 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2470 notify_ielen = le16_to_cpu(bi->ie_length);
2471 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2473 WL_CONN("bssid: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
2474 bi->BSSID[0], bi->BSSID[1], bi->BSSID[2],
2475 bi->BSSID[3], bi->BSSID[4], bi->BSSID[5]);
2476 WL_CONN("Channel: %d(%d)\n", channel, freq);
2477 WL_CONN("Capability: %X\n", notify_capability);
2478 WL_CONN("Beacon interval: %d\n", notify_interval);
2479 WL_CONN("Signal: %d\n", notify_signal);
2480 WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp);
2482 bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)bi->BSSID,
2483 notify_timestamp, notify_capability, notify_interval, notify_ie,
2484 notify_ielen, notify_signal, GFP_KERNEL);
2486 if (unlikely(!bss)) {
2487 WL_ERR("cfg80211_inform_bss_frame error\n");
2488 return -EINVAL;
2491 return err;
2494 static s32 wl_inform_ibss(struct brcmf_cfg80211_priv *cfg_priv,
2495 struct net_device *dev, const u8 *bssid)
2497 struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
2498 struct ieee80211_channel *notify_channel;
2499 struct brcmf_bss_info *bi = NULL;
2500 struct ieee80211_supported_band *band;
2501 u8 *buf = NULL;
2502 s32 err = 0;
2503 u16 channel;
2504 u32 freq;
2505 u64 notify_timestamp;
2506 u16 notify_capability;
2507 u16 notify_interval;
2508 u8 *notify_ie;
2509 size_t notify_ielen;
2510 s32 notify_signal;
2512 WL_TRACE("Enter\n");
2514 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2515 if (buf == NULL) {
2516 WL_ERR("kzalloc() failed\n");
2517 err = -ENOMEM;
2518 goto CleanUp;
2521 *(u32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
2523 err = brcmf_dev_ioctl(dev, BRCMF_C_GET_BSS_INFO, buf, WL_BSS_INFO_MAX);
2524 if (unlikely(err)) {
2525 WL_ERR("WLC_GET_BSS_INFO failed: %d\n", err);
2526 goto CleanUp;
2529 bi = (struct brcmf_bss_info *)(buf + 4);
2531 channel = bi->ctl_ch ? bi->ctl_ch :
2532 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2534 if (channel <= CH_MAX_2G_CHANNEL)
2535 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2536 else
2537 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2539 freq = ieee80211_channel_to_frequency(channel, band->band);
2540 notify_channel = ieee80211_get_channel(wiphy, freq);
2542 notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */
2543 notify_capability = le16_to_cpu(bi->capability);
2544 notify_interval = le16_to_cpu(bi->beacon_period);
2545 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2546 notify_ielen = le16_to_cpu(bi->ie_length);
2547 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2549 WL_CONN("channel: %d(%d)\n", channel, freq);
2550 WL_CONN("capability: %X\n", notify_capability);
2551 WL_CONN("beacon interval: %d\n", notify_interval);
2552 WL_CONN("signal: %d\n", notify_signal);
2553 WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp);
2555 cfg80211_inform_bss(wiphy, notify_channel, bssid,
2556 notify_timestamp, notify_capability, notify_interval,
2557 notify_ie, notify_ielen, notify_signal, GFP_KERNEL);
2559 CleanUp:
2561 kfree(buf);
2563 WL_TRACE("Exit\n");
2565 return err;
2568 static bool brcmf_is_linkup(struct brcmf_cfg80211_priv *cfg_priv,
2569 const struct brcmf_event_msg *e)
2571 u32 event = be32_to_cpu(e->event_type);
2572 u32 status = be32_to_cpu(e->status);
2574 if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
2575 WL_CONN("Processing set ssid\n");
2576 cfg_priv->link_up = true;
2577 return true;
2580 return false;
2583 static bool brcmf_is_linkdown(struct brcmf_cfg80211_priv *cfg_priv,
2584 const struct brcmf_event_msg *e)
2586 u32 event = be32_to_cpu(e->event_type);
2587 u16 flags = be16_to_cpu(e->flags);
2589 if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) {
2590 WL_CONN("Processing link down\n");
2591 return true;
2593 return false;
2596 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_priv *cfg_priv,
2597 const struct brcmf_event_msg *e)
2599 u32 event = be32_to_cpu(e->event_type);
2600 u32 status = be32_to_cpu(e->status);
2602 if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
2603 WL_CONN("Processing Link %s & no network found\n",
2604 be16_to_cpu(e->flags) & BRCMF_EVENT_MSG_LINK ?
2605 "up" : "down");
2606 return true;
2609 if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
2610 WL_CONN("Processing connecting & no network found\n");
2611 return true;
2614 return false;
2617 static s32
2618 brcmf_notify_connect_status(struct brcmf_cfg80211_priv *cfg_priv,
2619 struct net_device *ndev,
2620 const struct brcmf_event_msg *e, void *data)
2622 s32 err = 0;
2624 if (brcmf_is_linkup(cfg_priv, e)) {
2625 WL_CONN("Linkup\n");
2626 if (brcmf_is_ibssmode(cfg_priv)) {
2627 brcmf_update_prof(cfg_priv, NULL, (void *)e->addr,
2628 WL_PROF_BSSID);
2629 wl_inform_ibss(cfg_priv, ndev, e->addr);
2630 cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
2631 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
2632 set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
2633 } else
2634 brcmf_bss_connect_done(cfg_priv, ndev, e, true);
2635 } else if (brcmf_is_linkdown(cfg_priv, e)) {
2636 WL_CONN("Linkdown\n");
2637 if (brcmf_is_ibssmode(cfg_priv)) {
2638 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
2639 if (test_and_clear_bit(WL_STATUS_CONNECTED,
2640 &cfg_priv->status))
2641 brcmf_link_down(cfg_priv);
2642 } else {
2643 brcmf_bss_connect_done(cfg_priv, ndev, e, false);
2644 if (test_and_clear_bit(WL_STATUS_CONNECTED,
2645 &cfg_priv->status)) {
2646 cfg80211_disconnected(ndev, 0, NULL, 0,
2647 GFP_KERNEL);
2648 brcmf_link_down(cfg_priv);
2651 brcmf_init_prof(cfg_priv->profile);
2652 } else if (brcmf_is_nonetwork(cfg_priv, e)) {
2653 if (brcmf_is_ibssmode(cfg_priv))
2654 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
2655 else
2656 brcmf_bss_connect_done(cfg_priv, ndev, e, false);
2659 return err;
2662 static s32
2663 brcmf_notify_roaming_status(struct brcmf_cfg80211_priv *cfg_priv,
2664 struct net_device *ndev,
2665 const struct brcmf_event_msg *e, void *data)
2667 s32 err = 0;
2668 u32 event = be32_to_cpu(e->event_type);
2669 u32 status = be32_to_cpu(e->status);
2671 if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
2672 if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status))
2673 brcmf_bss_roaming_done(cfg_priv, ndev, e);
2674 else
2675 brcmf_bss_connect_done(cfg_priv, ndev, e, true);
2678 return err;
2681 static __used s32
2682 brcmf_dev_bufvar_set(struct net_device *dev, s8 *name, s8 *buf, s32 len)
2684 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(dev);
2685 u32 buflen;
2687 buflen = brcmu_mkiovar(name, buf, len, cfg_priv->ioctl_buf,
2688 WL_IOCTL_LEN_MAX);
2689 BUG_ON(!buflen);
2691 return brcmf_dev_ioctl(dev, BRCMF_C_SET_VAR, cfg_priv->ioctl_buf,
2692 buflen);
2695 static s32
2696 brcmf_dev_bufvar_get(struct net_device *dev, s8 *name, s8 *buf,
2697 s32 buf_len)
2699 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(dev);
2700 u32 len;
2701 s32 err = 0;
2703 len = brcmu_mkiovar(name, NULL, 0, cfg_priv->ioctl_buf,
2704 WL_IOCTL_LEN_MAX);
2705 BUG_ON(!len);
2706 err = brcmf_dev_ioctl(dev, BRCMF_C_GET_VAR, (void *)cfg_priv->ioctl_buf,
2707 WL_IOCTL_LEN_MAX);
2708 if (unlikely(err)) {
2709 WL_ERR("error (%d)\n", err);
2710 return err;
2712 memcpy(buf, cfg_priv->ioctl_buf, buf_len);
2714 return err;
2717 static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
2719 struct net_device *ndev = cfg_to_ndev(cfg_priv);
2720 struct brcmf_cfg80211_assoc_ielen *assoc_info;
2721 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2722 u32 req_len;
2723 u32 resp_len;
2724 s32 err = 0;
2726 brcmf_clear_assoc_ies(cfg_priv);
2728 err = brcmf_dev_bufvar_get(ndev, "assoc_info", cfg_priv->extra_buf,
2729 WL_ASSOC_INFO_MAX);
2730 if (unlikely(err)) {
2731 WL_ERR("could not get assoc info (%d)\n", err);
2732 return err;
2734 assoc_info = (struct brcmf_cfg80211_assoc_ielen *)cfg_priv->extra_buf;
2735 req_len = assoc_info->req_len;
2736 resp_len = assoc_info->resp_len;
2737 if (req_len) {
2738 err = brcmf_dev_bufvar_get(ndev, "assoc_req_ies",
2739 cfg_priv->extra_buf,
2740 WL_ASSOC_INFO_MAX);
2741 if (unlikely(err)) {
2742 WL_ERR("could not get assoc req (%d)\n", err);
2743 return err;
2745 conn_info->req_ie_len = req_len;
2746 conn_info->req_ie =
2747 kmemdup(cfg_priv->extra_buf, conn_info->req_ie_len,
2748 GFP_KERNEL);
2749 } else {
2750 conn_info->req_ie_len = 0;
2751 conn_info->req_ie = NULL;
2753 if (resp_len) {
2754 err = brcmf_dev_bufvar_get(ndev, "assoc_resp_ies",
2755 cfg_priv->extra_buf,
2756 WL_ASSOC_INFO_MAX);
2757 if (unlikely(err)) {
2758 WL_ERR("could not get assoc resp (%d)\n", err);
2759 return err;
2761 conn_info->resp_ie_len = resp_len;
2762 conn_info->resp_ie =
2763 kmemdup(cfg_priv->extra_buf, conn_info->resp_ie_len,
2764 GFP_KERNEL);
2765 } else {
2766 conn_info->resp_ie_len = 0;
2767 conn_info->resp_ie = NULL;
2769 WL_CONN("req len (%d) resp len (%d)\n",
2770 conn_info->req_ie_len, conn_info->resp_ie_len);
2772 return err;
2775 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
2777 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2779 kfree(conn_info->req_ie);
2780 conn_info->req_ie = NULL;
2781 conn_info->req_ie_len = 0;
2782 kfree(conn_info->resp_ie);
2783 conn_info->resp_ie = NULL;
2784 conn_info->resp_ie_len = 0;
2788 static void brcmf_ch_to_chanspec(int ch, struct brcmf_join_params *join_params,
2789 size_t *join_params_size)
2791 u16 chanspec = 0;
2793 if (ch != 0) {
2794 join_params->params.chanspec_num = 1;
2795 join_params->params.chanspec_list[0] = ch;
2797 if (join_params->params.chanspec_list[0] <= CH_MAX_2G_CHANNEL)
2798 chanspec |= WL_CHANSPEC_BAND_2G;
2799 else
2800 chanspec |= WL_CHANSPEC_BAND_5G;
2802 chanspec |= WL_CHANSPEC_BW_20;
2803 chanspec |= WL_CHANSPEC_CTL_SB_NONE;
2805 *join_params_size += BRCMF_ASSOC_PARAMS_FIXED_SIZE +
2806 join_params->params.chanspec_num * sizeof(u16);
2808 join_params->params.chanspec_list[0] &= WL_CHANSPEC_CHAN_MASK;
2809 join_params->params.chanspec_list[0] |= chanspec;
2810 join_params->params.chanspec_list[0] =
2811 cpu_to_le16(join_params->params.chanspec_list[0]);
2813 join_params->params.chanspec_num =
2814 cpu_to_le32(join_params->params.chanspec_num);
2816 WL_CONN("join_params->params.chanspec_list[0]= %#X,"
2817 "channel %d, chanspec %#X\n",
2818 join_params->params.chanspec_list[0], ch, chanspec);
2822 static s32 brcmf_update_bss_info(struct brcmf_cfg80211_priv *cfg_priv)
2824 struct brcmf_bss_info *bi;
2825 struct brcmf_ssid *ssid;
2826 struct brcmu_tlv *tim;
2827 u16 beacon_interval;
2828 u8 dtim_period;
2829 size_t ie_len;
2830 u8 *ie;
2831 s32 err = 0;
2833 WL_TRACE("Enter\n");
2834 if (brcmf_is_ibssmode(cfg_priv))
2835 return err;
2837 ssid = (struct brcmf_ssid *)brcmf_read_prof(cfg_priv, WL_PROF_SSID);
2839 *(u32 *)cfg_priv->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
2840 err = brcmf_dev_ioctl(cfg_to_ndev(cfg_priv), BRCMF_C_GET_BSS_INFO,
2841 cfg_priv->extra_buf, WL_EXTRA_BUF_MAX);
2842 if (unlikely(err)) {
2843 WL_ERR("Could not get bss info %d\n", err);
2844 goto update_bss_info_out;
2847 bi = (struct brcmf_bss_info *)(cfg_priv->extra_buf + 4);
2848 err = brcmf_inform_single_bss(cfg_priv, bi);
2849 if (unlikely(err))
2850 goto update_bss_info_out;
2852 ie = ((u8 *)bi) + bi->ie_offset;
2853 ie_len = bi->ie_length;
2854 beacon_interval = cpu_to_le16(bi->beacon_period);
2856 tim = brcmu_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
2857 if (tim)
2858 dtim_period = tim->data[1];
2859 else {
2861 * active scan was done so we could not get dtim
2862 * information out of probe response.
2863 * so we speficially query dtim information to dongle.
2865 u32 var;
2866 err = brcmf_dev_intvar_get(cfg_to_ndev(cfg_priv),
2867 "dtim_assoc", &var);
2868 if (unlikely(err)) {
2869 WL_ERR("wl dtim_assoc failed (%d)\n", err);
2870 goto update_bss_info_out;
2872 dtim_period = (u8)var;
2875 brcmf_update_prof(cfg_priv, NULL, &beacon_interval, WL_PROF_BEACONINT);
2876 brcmf_update_prof(cfg_priv, NULL, &dtim_period, WL_PROF_DTIMPERIOD);
2878 update_bss_info_out:
2879 WL_TRACE("Exit");
2880 return err;
2883 static s32
2884 brcmf_bss_roaming_done(struct brcmf_cfg80211_priv *cfg_priv,
2885 struct net_device *ndev,
2886 const struct brcmf_event_msg *e)
2888 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2889 struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
2890 struct brcmf_channel_info channel;
2891 struct ieee80211_channel *notify_channel;
2892 struct ieee80211_supported_band *band;
2893 u32 freq;
2894 s32 err = 0;
2896 WL_TRACE("Enter\n");
2898 brcmf_get_assoc_ies(cfg_priv);
2899 brcmf_update_prof(cfg_priv, NULL, &e->addr, WL_PROF_BSSID);
2900 brcmf_update_bss_info(cfg_priv);
2902 brcmf_dev_ioctl(ndev, BRCMF_C_GET_CHANNEL, &channel, sizeof(channel));
2904 channel.target_channel = le32_to_cpu(channel.target_channel);
2905 WL_CONN("Roamed to channel %d\n", channel.target_channel);
2907 if (channel.target_channel <= CH_MAX_2G_CHANNEL)
2908 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2909 else
2910 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2912 freq = ieee80211_channel_to_frequency(channel.target_channel,
2913 band->band);
2914 notify_channel = ieee80211_get_channel(wiphy, freq);
2916 cfg80211_roamed(ndev, notify_channel,
2917 (u8 *)brcmf_read_prof(cfg_priv, WL_PROF_BSSID),
2918 conn_info->req_ie, conn_info->req_ie_len,
2919 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
2920 WL_CONN("Report roaming result\n");
2922 set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
2923 WL_TRACE("Exit\n");
2924 return err;
2927 static s32
2928 brcmf_bss_connect_done(struct brcmf_cfg80211_priv *cfg_priv,
2929 struct net_device *ndev, const struct brcmf_event_msg *e,
2930 bool completed)
2932 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2933 s32 err = 0;
2935 WL_TRACE("Enter\n");
2937 if (test_and_clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) {
2938 if (completed) {
2939 brcmf_get_assoc_ies(cfg_priv);
2940 brcmf_update_prof(cfg_priv, NULL, &e->addr,
2941 WL_PROF_BSSID);
2942 brcmf_update_bss_info(cfg_priv);
2944 cfg80211_connect_result(ndev,
2945 (u8 *)brcmf_read_prof(cfg_priv,
2946 WL_PROF_BSSID),
2947 conn_info->req_ie,
2948 conn_info->req_ie_len,
2949 conn_info->resp_ie,
2950 conn_info->resp_ie_len,
2951 completed ? WLAN_STATUS_SUCCESS :
2952 WLAN_STATUS_AUTH_TIMEOUT,
2953 GFP_KERNEL);
2954 if (completed)
2955 set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
2956 WL_CONN("Report connect result - connection %s\n",
2957 completed ? "succeeded" : "failed");
2959 WL_TRACE("Exit\n");
2960 return err;
2963 static s32
2964 brcmf_notify_mic_status(struct brcmf_cfg80211_priv *cfg_priv,
2965 struct net_device *ndev,
2966 const struct brcmf_event_msg *e, void *data)
2968 u16 flags = be16_to_cpu(e->flags);
2969 enum nl80211_key_type key_type;
2971 rtnl_lock();
2972 if (flags & BRCMF_EVENT_MSG_GROUP)
2973 key_type = NL80211_KEYTYPE_GROUP;
2974 else
2975 key_type = NL80211_KEYTYPE_PAIRWISE;
2977 cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1,
2978 NULL, GFP_KERNEL);
2979 rtnl_unlock();
2981 return 0;
2984 static s32
2985 brcmf_notify_scan_status(struct brcmf_cfg80211_priv *cfg_priv,
2986 struct net_device *ndev,
2987 const struct brcmf_event_msg *e, void *data)
2989 struct brcmf_channel_info channel_inform;
2990 struct brcmf_scan_results *bss_list;
2991 u32 len = WL_SCAN_BUF_MAX;
2992 s32 err = 0;
2993 bool scan_abort = false;
2995 WL_TRACE("Enter\n");
2997 if (cfg_priv->iscan_on && cfg_priv->iscan_kickstart) {
2998 WL_TRACE("Exit\n");
2999 return brcmf_wakeup_iscan(cfg_to_iscan(cfg_priv));
3002 if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING,
3003 &cfg_priv->status))) {
3004 WL_ERR("Scan complete while device not scanning\n");
3005 scan_abort = true;
3006 err = -EINVAL;
3007 goto scan_done_out;
3010 err = brcmf_dev_ioctl(ndev, BRCMF_C_GET_CHANNEL, &channel_inform,
3011 sizeof(channel_inform));
3012 if (unlikely(err)) {
3013 WL_ERR("scan busy (%d)\n", err);
3014 scan_abort = true;
3015 goto scan_done_out;
3017 channel_inform.scan_channel = le32_to_cpu(channel_inform.scan_channel);
3018 if (unlikely(channel_inform.scan_channel)) {
3020 WL_CONN("channel_inform.scan_channel (%d)\n",
3021 channel_inform.scan_channel);
3023 cfg_priv->bss_list = cfg_priv->scan_results;
3024 bss_list = cfg_priv->bss_list;
3025 memset(bss_list, 0, len);
3026 bss_list->buflen = cpu_to_le32(len);
3028 err = brcmf_dev_ioctl(ndev, BRCMF_C_SCAN_RESULTS, bss_list, len);
3029 if (unlikely(err)) {
3030 WL_ERR("%s Scan_results error (%d)\n", ndev->name, err);
3031 err = -EINVAL;
3032 scan_abort = true;
3033 goto scan_done_out;
3035 bss_list->buflen = le32_to_cpu(bss_list->buflen);
3036 bss_list->version = le32_to_cpu(bss_list->version);
3037 bss_list->count = le32_to_cpu(bss_list->count);
3039 err = brcmf_inform_bss(cfg_priv);
3040 if (err) {
3041 scan_abort = true;
3042 goto scan_done_out;
3045 scan_done_out:
3046 if (cfg_priv->scan_request) {
3047 WL_SCAN("calling cfg80211_scan_done\n");
3048 cfg80211_scan_done(cfg_priv->scan_request, scan_abort);
3049 brcmf_set_mpc(ndev, 1);
3050 cfg_priv->scan_request = NULL;
3053 WL_TRACE("Exit\n");
3055 return err;
3058 static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
3060 conf->mode = (u32)-1;
3061 conf->frag_threshold = (u32)-1;
3062 conf->rts_threshold = (u32)-1;
3063 conf->retry_short = (u32)-1;
3064 conf->retry_long = (u32)-1;
3065 conf->tx_power = -1;
3068 static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof)
3070 memset(prof, 0, sizeof(*prof));
3073 static void brcmf_init_eloop_handler(struct brcmf_cfg80211_event_loop *el)
3075 memset(el, 0, sizeof(*el));
3076 el->handler[BRCMF_E_SCAN_COMPLETE] = brcmf_notify_scan_status;
3077 el->handler[BRCMF_E_LINK] = brcmf_notify_connect_status;
3078 el->handler[BRCMF_E_ROAM] = brcmf_notify_roaming_status;
3079 el->handler[BRCMF_E_MIC_ERROR] = brcmf_notify_mic_status;
3080 el->handler[BRCMF_E_SET_SSID] = brcmf_notify_connect_status;
3083 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
3085 cfg_priv->scan_results = kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
3086 if (unlikely(!cfg_priv->scan_results)) {
3087 WL_ERR("Scan results alloc failed\n");
3088 goto init_priv_mem_out;
3090 cfg_priv->conf = kzalloc(sizeof(*cfg_priv->conf), GFP_KERNEL);
3091 if (unlikely(!cfg_priv->conf)) {
3092 WL_ERR("wl_conf alloc failed\n");
3093 goto init_priv_mem_out;
3095 cfg_priv->profile = kzalloc(sizeof(*cfg_priv->profile), GFP_KERNEL);
3096 if (unlikely(!cfg_priv->profile)) {
3097 WL_ERR("wl_profile alloc failed\n");
3098 goto init_priv_mem_out;
3100 cfg_priv->bss_info = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
3101 if (unlikely(!cfg_priv->bss_info)) {
3102 WL_ERR("Bss information alloc failed\n");
3103 goto init_priv_mem_out;
3105 cfg_priv->scan_req_int = kzalloc(sizeof(*cfg_priv->scan_req_int),
3106 GFP_KERNEL);
3107 if (unlikely(!cfg_priv->scan_req_int)) {
3108 WL_ERR("Scan req alloc failed\n");
3109 goto init_priv_mem_out;
3111 cfg_priv->ioctl_buf = kzalloc(WL_IOCTL_LEN_MAX, GFP_KERNEL);
3112 if (unlikely(!cfg_priv->ioctl_buf)) {
3113 WL_ERR("Ioctl buf alloc failed\n");
3114 goto init_priv_mem_out;
3116 cfg_priv->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
3117 if (unlikely(!cfg_priv->extra_buf)) {
3118 WL_ERR("Extra buf alloc failed\n");
3119 goto init_priv_mem_out;
3121 cfg_priv->iscan = kzalloc(sizeof(*cfg_priv->iscan), GFP_KERNEL);
3122 if (unlikely(!cfg_priv->iscan)) {
3123 WL_ERR("Iscan buf alloc failed\n");
3124 goto init_priv_mem_out;
3126 cfg_priv->pmk_list = kzalloc(sizeof(*cfg_priv->pmk_list), GFP_KERNEL);
3127 if (unlikely(!cfg_priv->pmk_list)) {
3128 WL_ERR("pmk list alloc failed\n");
3129 goto init_priv_mem_out;
3132 return 0;
3134 init_priv_mem_out:
3135 brcmf_deinit_priv_mem(cfg_priv);
3137 return -ENOMEM;
3140 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
3142 kfree(cfg_priv->scan_results);
3143 cfg_priv->scan_results = NULL;
3144 kfree(cfg_priv->bss_info);
3145 cfg_priv->bss_info = NULL;
3146 kfree(cfg_priv->conf);
3147 cfg_priv->conf = NULL;
3148 kfree(cfg_priv->profile);
3149 cfg_priv->profile = NULL;
3150 kfree(cfg_priv->scan_req_int);
3151 cfg_priv->scan_req_int = NULL;
3152 kfree(cfg_priv->ioctl_buf);
3153 cfg_priv->ioctl_buf = NULL;
3154 kfree(cfg_priv->extra_buf);
3155 cfg_priv->extra_buf = NULL;
3156 kfree(cfg_priv->iscan);
3157 cfg_priv->iscan = NULL;
3158 kfree(cfg_priv->pmk_list);
3159 cfg_priv->pmk_list = NULL;
3162 static s32 brcmf_create_event_handler(struct brcmf_cfg80211_priv *cfg_priv)
3164 init_waitqueue_head(&cfg_priv->event_waitq);
3165 cfg_priv->event_tsk = kthread_run(brcmf_event_handler, cfg_priv,
3166 "wl_event_handler");
3167 if (IS_ERR(cfg_priv->event_tsk)) {
3168 cfg_priv->event_tsk = NULL;
3169 WL_ERR("failed to create event thread\n");
3170 return -ENOMEM;
3172 return 0;
3175 static void brcmf_destroy_event_handler(struct brcmf_cfg80211_priv *cfg_priv)
3177 if (cfg_priv->event_tsk) {
3178 send_sig(SIGTERM, cfg_priv->event_tsk, 1);
3179 kthread_stop(cfg_priv->event_tsk);
3180 cfg_priv->event_tsk = NULL;
3184 static void brcmf_term_iscan(struct brcmf_cfg80211_priv *cfg_priv)
3186 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
3187 struct brcmf_ssid ssid;
3189 if (cfg_priv->iscan_on && iscan->tsk) {
3190 iscan->state = WL_ISCAN_STATE_IDLE;
3191 send_sig(SIGTERM, iscan->tsk, 1);
3194 * The iscan task may want to acquire the rtnl_lock
3195 * so release it here upon stopping the task.
3197 rtnl_unlock();
3198 kthread_stop(iscan->tsk);
3199 rtnl_lock();
3200 iscan->tsk = NULL;
3202 /* Abort iscan running in FW */
3203 memset(&ssid, 0, sizeof(ssid));
3204 brcmf_run_iscan(iscan, &ssid, WL_SCAN_ACTION_ABORT);
3208 static void brcmf_notify_iscan_complete(struct brcmf_cfg80211_iscan_ctrl *iscan,
3209 bool aborted)
3211 struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan);
3212 struct net_device *ndev = cfg_to_ndev(cfg_priv);
3214 if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING,
3215 &cfg_priv->status))) {
3216 WL_ERR("Scan complete while device not scanning\n");
3217 return;
3219 if (likely(cfg_priv->scan_request)) {
3220 WL_SCAN("ISCAN Completed scan: %s\n",
3221 aborted ? "Aborted" : "Done");
3222 cfg80211_scan_done(cfg_priv->scan_request, aborted);
3223 brcmf_set_mpc(ndev, 1);
3224 cfg_priv->scan_request = NULL;
3226 cfg_priv->iscan_kickstart = false;
3229 static s32 brcmf_wakeup_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan)
3231 if (likely(iscan->state != WL_ISCAN_STATE_IDLE)) {
3232 WL_SCAN("wake up iscan\n");
3233 wake_up(&iscan->waitq);
3234 return 0;
3237 return -EIO;
3240 static s32
3241 brcmf_get_iscan_results(struct brcmf_cfg80211_iscan_ctrl *iscan, u32 *status,
3242 struct brcmf_scan_results **bss_list)
3244 struct brcmf_iscan_results list;
3245 struct brcmf_scan_results *results;
3246 struct brcmf_iscan_results *list_buf;
3247 s32 err = 0;
3249 memset(iscan->scan_buf, 0, WL_ISCAN_BUF_MAX);
3250 list_buf = (struct brcmf_iscan_results *)iscan->scan_buf;
3251 results = &list_buf->results;
3252 results->buflen = BRCMF_ISCAN_RESULTS_FIXED_SIZE;
3253 results->version = 0;
3254 results->count = 0;
3256 memset(&list, 0, sizeof(list));
3257 list.results.buflen = cpu_to_le32(WL_ISCAN_BUF_MAX);
3258 err = brcmf_dev_iovar_getbuf(iscan->dev, "iscanresults", &list,
3259 BRCMF_ISCAN_RESULTS_FIXED_SIZE, iscan->scan_buf,
3260 WL_ISCAN_BUF_MAX);
3261 if (unlikely(err)) {
3262 WL_ERR("error (%d)\n", err);
3263 return err;
3265 results->buflen = le32_to_cpu(results->buflen);
3266 results->version = le32_to_cpu(results->version);
3267 results->count = le32_to_cpu(results->count);
3268 WL_SCAN("results->count = %d\n", results->count);
3269 WL_SCAN("results->buflen = %d\n", results->buflen);
3270 *status = le32_to_cpu(list_buf->status);
3271 WL_SCAN("status = %d\n", *status);
3272 *bss_list = results;
3274 return err;
3277 static s32 brcmf_iscan_done(struct brcmf_cfg80211_priv *cfg_priv)
3279 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
3280 s32 err = 0;
3282 iscan->state = WL_ISCAN_STATE_IDLE;
3283 rtnl_lock();
3284 brcmf_inform_bss(cfg_priv);
3285 brcmf_notify_iscan_complete(iscan, false);
3286 rtnl_unlock();
3288 return err;
3291 static s32 brcmf_iscan_pending(struct brcmf_cfg80211_priv *cfg_priv)
3293 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
3294 s32 err = 0;
3296 /* Reschedule the timer */
3297 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
3298 iscan->timer_on = 1;
3300 return err;
3303 static s32 brcmf_iscan_inprogress(struct brcmf_cfg80211_priv *cfg_priv)
3305 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
3306 s32 err = 0;
3308 rtnl_lock();
3309 brcmf_inform_bss(cfg_priv);
3310 brcmf_run_iscan(iscan, NULL, BRCMF_SCAN_ACTION_CONTINUE);
3311 rtnl_unlock();
3312 /* Reschedule the timer */
3313 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
3314 iscan->timer_on = 1;
3316 return err;
3319 static s32 brcmf_iscan_aborted(struct brcmf_cfg80211_priv *cfg_priv)
3321 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
3322 s32 err = 0;
3324 iscan->state = WL_ISCAN_STATE_IDLE;
3325 rtnl_lock();
3326 brcmf_notify_iscan_complete(iscan, true);
3327 rtnl_unlock();
3329 return err;
3332 static s32 brcmf_iscan_thread(void *data)
3334 struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1 };
3335 struct brcmf_cfg80211_iscan_ctrl *iscan =
3336 (struct brcmf_cfg80211_iscan_ctrl *)data;
3337 struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan);
3338 struct brcmf_cfg80211_iscan_eloop *el = &iscan->el;
3339 DECLARE_WAITQUEUE(wait, current);
3340 u32 status;
3341 int err = 0;
3343 sched_setscheduler(current, SCHED_FIFO, &param);
3344 allow_signal(SIGTERM);
3345 status = BRCMF_SCAN_RESULTS_PARTIAL;
3346 add_wait_queue(&iscan->waitq, &wait);
3347 while (1) {
3348 prepare_to_wait(&iscan->waitq, &wait, TASK_INTERRUPTIBLE);
3350 schedule();
3352 if (kthread_should_stop())
3353 break;
3354 if (iscan->timer_on) {
3355 del_timer_sync(&iscan->timer);
3356 iscan->timer_on = 0;
3358 rtnl_lock();
3359 err = brcmf_get_iscan_results(iscan, &status,
3360 &cfg_priv->bss_list);
3361 if (unlikely(err)) {
3362 status = BRCMF_SCAN_RESULTS_ABORTED;
3363 WL_ERR("Abort iscan\n");
3365 rtnl_unlock();
3366 el->handler[status](cfg_priv);
3368 finish_wait(&iscan->waitq, &wait);
3369 if (iscan->timer_on) {
3370 del_timer_sync(&iscan->timer);
3371 iscan->timer_on = 0;
3373 WL_SCAN("ISCAN thread terminated\n");
3375 return 0;
3378 static void brcmf_iscan_timer(unsigned long data)
3380 struct brcmf_cfg80211_iscan_ctrl *iscan =
3381 (struct brcmf_cfg80211_iscan_ctrl *)data;
3383 if (iscan) {
3384 iscan->timer_on = 0;
3385 WL_SCAN("timer expired\n");
3386 brcmf_wakeup_iscan(iscan);
3390 static s32 brcmf_invoke_iscan(struct brcmf_cfg80211_priv *cfg_priv)
3392 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
3394 if (cfg_priv->iscan_on && !iscan->tsk) {
3395 iscan->state = WL_ISCAN_STATE_IDLE;
3396 init_waitqueue_head(&iscan->waitq);
3397 iscan->tsk = kthread_run(brcmf_iscan_thread, iscan, "wl_iscan");
3398 if (IS_ERR(iscan->tsk)) {
3399 WL_ERR("Could not create iscan thread\n");
3400 iscan->tsk = NULL;
3401 return -ENOMEM;
3405 return 0;
3408 static void brcmf_init_iscan_eloop(struct brcmf_cfg80211_iscan_eloop *el)
3410 memset(el, 0, sizeof(*el));
3411 el->handler[BRCMF_SCAN_RESULTS_SUCCESS] = brcmf_iscan_done;
3412 el->handler[BRCMF_SCAN_RESULTS_PARTIAL] = brcmf_iscan_inprogress;
3413 el->handler[BRCMF_SCAN_RESULTS_PENDING] = brcmf_iscan_pending;
3414 el->handler[BRCMF_SCAN_RESULTS_ABORTED] = brcmf_iscan_aborted;
3415 el->handler[BRCMF_SCAN_RESULTS_NO_MEM] = brcmf_iscan_aborted;
3418 static s32 brcmf_init_iscan(struct brcmf_cfg80211_priv *cfg_priv)
3420 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
3421 int err = 0;
3423 if (cfg_priv->iscan_on) {
3424 iscan->dev = cfg_to_ndev(cfg_priv);
3425 brcmf_init_iscan_eloop(&iscan->el);
3426 iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS;
3427 init_timer(&iscan->timer);
3428 iscan->timer.data = (unsigned long) iscan;
3429 iscan->timer.function = brcmf_iscan_timer;
3430 err = brcmf_invoke_iscan(cfg_priv);
3431 if (!err)
3432 iscan->data = cfg_priv;
3435 return err;
3438 static s32 wl_init_priv(struct brcmf_cfg80211_priv *cfg_priv)
3440 s32 err = 0;
3442 cfg_priv->scan_request = NULL;
3443 #ifndef WL_POWERSAVE_DISABLED
3444 cfg_priv->pwr_save = true;
3445 #endif /* WL_POWERSAVE_DISABLED */
3446 cfg_priv->iscan_on = true; /* iscan on & off switch.
3447 we enable iscan per default */
3448 cfg_priv->roam_on = true; /* roam on & off switch.
3449 we enable roam per default */
3451 cfg_priv->iscan_kickstart = false;
3452 cfg_priv->active_scan = true; /* we do active scan for
3453 specific scan per default */
3454 cfg_priv->dongle_up = false; /* dongle is not up yet */
3455 brcmf_init_eq(cfg_priv);
3456 err = brcmf_init_priv_mem(cfg_priv);
3457 if (unlikely(err))
3458 return err;
3459 if (unlikely(brcmf_create_event_handler(cfg_priv)))
3460 return -ENOMEM;
3461 brcmf_init_eloop_handler(&cfg_priv->el);
3462 mutex_init(&cfg_priv->usr_sync);
3463 err = brcmf_init_iscan(cfg_priv);
3464 if (unlikely(err))
3465 return err;
3466 brcmf_init_conf(cfg_priv->conf);
3467 brcmf_init_prof(cfg_priv->profile);
3468 brcmf_link_down(cfg_priv);
3470 return err;
3473 static void wl_deinit_priv(struct brcmf_cfg80211_priv *cfg_priv)
3475 brcmf_destroy_event_handler(cfg_priv);
3476 cfg_priv->dongle_up = false; /* dongle down */
3477 brcmf_flush_eq(cfg_priv);
3478 brcmf_link_down(cfg_priv);
3479 brcmf_term_iscan(cfg_priv);
3480 brcmf_deinit_priv_mem(cfg_priv);
3483 s32 brcmf_cfg80211_attach(struct net_device *ndev, void *data)
3485 struct wireless_dev *wdev;
3486 struct brcmf_cfg80211_priv *cfg_priv;
3487 struct brcmf_cfg80211_iface *ci;
3488 s32 err = 0;
3490 if (unlikely(!ndev)) {
3491 WL_ERR("ndev is invalid\n");
3492 return -ENODEV;
3494 cfg80211_dev = kzalloc(sizeof(struct brcmf_cfg80211_dev), GFP_KERNEL);
3495 if (unlikely(!cfg80211_dev)) {
3496 WL_ERR("wl_cfg80211_dev is invalid\n");
3497 return -ENOMEM;
3499 WL_INFO("func %p\n", brcmf_cfg80211_get_sdio_func());
3500 wdev = brcmf_alloc_wdev(sizeof(struct brcmf_cfg80211_iface),
3501 &brcmf_cfg80211_get_sdio_func()->dev);
3502 if (IS_ERR(wdev))
3503 return -ENOMEM;
3505 wdev->iftype = brcmf_mode_to_nl80211_iftype(WL_MODE_BSS);
3506 cfg_priv = wdev_to_cfg(wdev);
3507 cfg_priv->wdev = wdev;
3508 cfg_priv->pub = data;
3509 ci = (struct brcmf_cfg80211_iface *)&cfg_priv->ci;
3510 ci->cfg_priv = cfg_priv;
3511 ndev->ieee80211_ptr = wdev;
3512 SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
3513 wdev->netdev = ndev;
3514 err = wl_init_priv(cfg_priv);
3515 if (unlikely(err)) {
3516 WL_ERR("Failed to init iwm_priv (%d)\n", err);
3517 goto cfg80211_attach_out;
3519 brcmf_set_drvdata(cfg80211_dev, ci);
3521 return err;
3523 cfg80211_attach_out:
3524 brcmf_free_wdev(cfg_priv);
3525 return err;
3528 void brcmf_cfg80211_detach(void)
3530 struct brcmf_cfg80211_priv *cfg_priv;
3532 cfg_priv = WL_PRIV_GET();
3534 wl_deinit_priv(cfg_priv);
3535 brcmf_free_wdev(cfg_priv);
3536 brcmf_set_drvdata(cfg80211_dev, NULL);
3537 kfree(cfg80211_dev);
3538 cfg80211_dev = NULL;
3539 brcmf_clear_sdio_func();
3542 static void brcmf_wakeup_event(struct brcmf_cfg80211_priv *cfg_priv)
3544 wake_up(&cfg_priv->event_waitq);
3547 static s32 brcmf_event_handler(void *data)
3549 struct brcmf_cfg80211_priv *cfg_priv =
3550 (struct brcmf_cfg80211_priv *)data;
3551 struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1 };
3552 struct brcmf_cfg80211_event_q *e;
3553 DECLARE_WAITQUEUE(wait, current);
3555 sched_setscheduler(current, SCHED_FIFO, &param);
3556 allow_signal(SIGTERM);
3557 add_wait_queue(&cfg_priv->event_waitq, &wait);
3558 while (1) {
3559 prepare_to_wait(&cfg_priv->event_waitq, &wait,
3560 TASK_INTERRUPTIBLE);
3562 schedule();
3564 if (kthread_should_stop())
3565 break;
3567 e = brcmf_deq_event(cfg_priv);
3568 if (unlikely(!e)) {
3569 WL_ERR("event queue empty...\n");
3570 continue;
3573 do {
3574 WL_INFO("event type (%d)\n", e->etype);
3575 if (cfg_priv->el.handler[e->etype])
3576 cfg_priv->el.handler[e->etype](cfg_priv,
3577 cfg_to_ndev(cfg_priv),
3578 &e->emsg, e->edata);
3579 else
3580 WL_INFO("Unknown Event (%d): ignoring\n",
3581 e->etype);
3582 brcmf_put_event(e);
3583 } while ((e = brcmf_deq_event(cfg_priv)));
3585 finish_wait(&cfg_priv->event_waitq, &wait);
3586 WL_INFO("was terminated\n");
3587 return 0;
3590 void
3591 brcmf_cfg80211_event(struct net_device *ndev,
3592 const struct brcmf_event_msg *e, void *data)
3594 u32 event_type = be32_to_cpu(e->event_type);
3595 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
3597 if (likely(!brcmf_enq_event(cfg_priv, event_type, e)))
3598 brcmf_wakeup_event(cfg_priv);
3601 static void brcmf_init_eq(struct brcmf_cfg80211_priv *cfg_priv)
3603 brcmf_init_eq_lock(cfg_priv);
3604 INIT_LIST_HEAD(&cfg_priv->eq_list);
3607 static void brcmf_flush_eq(struct brcmf_cfg80211_priv *cfg_priv)
3609 struct brcmf_cfg80211_event_q *e;
3611 brcmf_lock_eq(cfg_priv);
3612 while (!list_empty(&cfg_priv->eq_list)) {
3613 e = list_first_entry(&cfg_priv->eq_list,
3614 struct brcmf_cfg80211_event_q, eq_list);
3615 list_del(&e->eq_list);
3616 kfree(e);
3618 brcmf_unlock_eq(cfg_priv);
3622 * retrieve first queued event from head
3625 static struct brcmf_cfg80211_event_q *brcmf_deq_event(
3626 struct brcmf_cfg80211_priv *cfg_priv)
3628 struct brcmf_cfg80211_event_q *e = NULL;
3630 brcmf_lock_eq(cfg_priv);
3631 if (likely(!list_empty(&cfg_priv->eq_list))) {
3632 e = list_first_entry(&cfg_priv->eq_list,
3633 struct brcmf_cfg80211_event_q, eq_list);
3634 list_del(&e->eq_list);
3636 brcmf_unlock_eq(cfg_priv);
3638 return e;
3642 ** push event to tail of the queue
3645 static s32
3646 brcmf_enq_event(struct brcmf_cfg80211_priv *cfg_priv, u32 event,
3647 const struct brcmf_event_msg *msg)
3649 struct brcmf_cfg80211_event_q *e;
3650 s32 err = 0;
3652 e = kzalloc(sizeof(struct brcmf_cfg80211_event_q), GFP_KERNEL);
3653 if (unlikely(!e)) {
3654 WL_ERR("event alloc failed\n");
3655 return -ENOMEM;
3658 e->etype = event;
3659 memcpy(&e->emsg, msg, sizeof(struct brcmf_event_msg));
3661 brcmf_lock_eq(cfg_priv);
3662 list_add_tail(&e->eq_list, &cfg_priv->eq_list);
3663 brcmf_unlock_eq(cfg_priv);
3665 return err;
3668 static void brcmf_put_event(struct brcmf_cfg80211_event_q *e)
3670 kfree(e);
3673 void brcmf_cfg80211_sdio_func(void *func)
3675 cfg80211_sdio_func = (struct sdio_func *)func;
3678 static void brcmf_clear_sdio_func(void)
3680 cfg80211_sdio_func = NULL;
3683 struct sdio_func *brcmf_cfg80211_get_sdio_func(void)
3685 return cfg80211_sdio_func;
3688 static s32 brcmf_dongle_mode(struct net_device *ndev, s32 iftype)
3690 s32 infra = 0;
3691 s32 err = 0;
3693 switch (iftype) {
3694 case NL80211_IFTYPE_MONITOR:
3695 case NL80211_IFTYPE_WDS:
3696 WL_ERR("type (%d) : currently we do not support this mode\n",
3697 iftype);
3698 err = -EINVAL;
3699 return err;
3700 case NL80211_IFTYPE_ADHOC:
3701 infra = 0;
3702 break;
3703 case NL80211_IFTYPE_STATION:
3704 infra = 1;
3705 break;
3706 default:
3707 err = -EINVAL;
3708 WL_ERR("invalid type (%d)\n", iftype);
3709 return err;
3711 infra = cpu_to_le32(infra);
3712 err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_INFRA, &infra, sizeof(infra));
3713 if (unlikely(err)) {
3714 WL_ERR("WLC_SET_INFRA error (%d)\n", err);
3715 return err;
3718 return 0;
3721 static s32 brcmf_dongle_eventmsg(struct net_device *ndev)
3723 /* Room for "event_msgs" + '\0' + bitvec */
3724 s8 iovbuf[BRCMF_EVENTING_MASK_LEN + 12];
3725 s8 eventmask[BRCMF_EVENTING_MASK_LEN];
3726 s32 err = 0;
3728 WL_TRACE("Enter\n");
3730 /* Setup event_msgs */
3731 brcmu_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN, iovbuf,
3732 sizeof(iovbuf));
3733 err = brcmf_dev_ioctl(ndev, BRCMF_C_GET_VAR, iovbuf, sizeof(iovbuf));
3734 if (unlikely(err)) {
3735 WL_ERR("Get event_msgs error (%d)\n", err);
3736 goto dongle_eventmsg_out;
3738 memcpy(eventmask, iovbuf, BRCMF_EVENTING_MASK_LEN);
3740 setbit(eventmask, BRCMF_E_SET_SSID);
3741 setbit(eventmask, BRCMF_E_ROAM);
3742 setbit(eventmask, BRCMF_E_PRUNE);
3743 setbit(eventmask, BRCMF_E_AUTH);
3744 setbit(eventmask, BRCMF_E_REASSOC);
3745 setbit(eventmask, BRCMF_E_REASSOC_IND);
3746 setbit(eventmask, BRCMF_E_DEAUTH_IND);
3747 setbit(eventmask, BRCMF_E_DISASSOC_IND);
3748 setbit(eventmask, BRCMF_E_DISASSOC);
3749 setbit(eventmask, BRCMF_E_JOIN);
3750 setbit(eventmask, BRCMF_E_ASSOC_IND);
3751 setbit(eventmask, BRCMF_E_PSK_SUP);
3752 setbit(eventmask, BRCMF_E_LINK);
3753 setbit(eventmask, BRCMF_E_NDIS_LINK);
3754 setbit(eventmask, BRCMF_E_MIC_ERROR);
3755 setbit(eventmask, BRCMF_E_PMKID_CACHE);
3756 setbit(eventmask, BRCMF_E_TXFAIL);
3757 setbit(eventmask, BRCMF_E_JOIN_START);
3758 setbit(eventmask, BRCMF_E_SCAN_COMPLETE);
3760 brcmu_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN, iovbuf,
3761 sizeof(iovbuf));
3762 err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
3763 if (unlikely(err)) {
3764 WL_ERR("Set event_msgs error (%d)\n", err);
3765 goto dongle_eventmsg_out;
3768 dongle_eventmsg_out:
3769 WL_TRACE("Exit\n");
3770 return err;
3773 static s32
3774 brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
3776 s8 iovbuf[32];
3777 s32 roamtrigger[2];
3778 s32 roam_delta[2];
3779 s32 err = 0;
3782 * Setup timeout if Beacons are lost and roam is
3783 * off to report link down
3785 if (roamvar) {
3786 brcmu_mkiovar("bcn_timeout", (char *)&bcn_timeout,
3787 sizeof(bcn_timeout), iovbuf, sizeof(iovbuf));
3788 err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_VAR,
3789 iovbuf, sizeof(iovbuf));
3790 if (unlikely(err)) {
3791 WL_ERR("bcn_timeout error (%d)\n", err);
3792 goto dongle_rom_out;
3797 * Enable/Disable built-in roaming to allow supplicant
3798 * to take care of roaming
3800 WL_INFO("Internal Roaming = %s\n", roamvar ? "Off" : "On");
3801 brcmu_mkiovar("roam_off", (char *)&roamvar,
3802 sizeof(roamvar), iovbuf, sizeof(iovbuf));
3803 err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
3804 if (unlikely(err)) {
3805 WL_ERR("roam_off error (%d)\n", err);
3806 goto dongle_rom_out;
3809 roamtrigger[0] = WL_ROAM_TRIGGER_LEVEL;
3810 roamtrigger[1] = BRCM_BAND_ALL;
3811 err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_ROAM_TRIGGER,
3812 (void *)roamtrigger, sizeof(roamtrigger));
3813 if (unlikely(err)) {
3814 WL_ERR("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
3815 goto dongle_rom_out;
3818 roam_delta[0] = WL_ROAM_DELTA;
3819 roam_delta[1] = BRCM_BAND_ALL;
3820 err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_ROAM_DELTA,
3821 (void *)roam_delta, sizeof(roam_delta));
3822 if (unlikely(err)) {
3823 WL_ERR("WLC_SET_ROAM_DELTA error (%d)\n", err);
3824 goto dongle_rom_out;
3827 dongle_rom_out:
3828 return err;
3831 static s32
3832 brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
3833 s32 scan_unassoc_time, s32 scan_passive_time)
3835 s32 err = 0;
3837 err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_SCAN_CHANNEL_TIME,
3838 &scan_assoc_time, sizeof(scan_assoc_time));
3839 if (err) {
3840 if (err == -EOPNOTSUPP)
3841 WL_INFO("Scan assoc time is not supported\n");
3842 else
3843 WL_ERR("Scan assoc time error (%d)\n", err);
3844 goto dongle_scantime_out;
3846 err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_SCAN_UNASSOC_TIME,
3847 &scan_unassoc_time, sizeof(scan_unassoc_time));
3848 if (err) {
3849 if (err == -EOPNOTSUPP)
3850 WL_INFO("Scan unassoc time is not supported\n");
3851 else
3852 WL_ERR("Scan unassoc time error (%d)\n", err);
3853 goto dongle_scantime_out;
3856 err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_SCAN_PASSIVE_TIME,
3857 &scan_passive_time, sizeof(scan_passive_time));
3858 if (err) {
3859 if (err == -EOPNOTSUPP)
3860 WL_INFO("Scan passive time is not supported\n");
3861 else
3862 WL_ERR("Scan passive time error (%d)\n", err);
3863 goto dongle_scantime_out;
3866 dongle_scantime_out:
3867 return err;
3870 s32 brcmf_config_dongle(struct brcmf_cfg80211_priv *cfg_priv, bool need_lock)
3872 struct net_device *ndev;
3873 struct wireless_dev *wdev;
3874 s32 power_mode;
3875 s32 err = 0;
3877 if (cfg_priv->dongle_up)
3878 return err;
3880 ndev = cfg_to_ndev(cfg_priv);
3881 wdev = ndev->ieee80211_ptr;
3882 if (need_lock)
3883 rtnl_lock();
3885 brcmf_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME,
3886 WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
3888 err = brcmf_dongle_eventmsg(ndev);
3889 if (unlikely(err))
3890 goto default_conf_out;
3892 power_mode = cfg_priv->pwr_save ? PM_FAST : PM_OFF;
3893 power_mode = cpu_to_le32(power_mode);
3894 err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_PM,
3895 &power_mode, sizeof(power_mode));
3896 if (err)
3897 goto default_conf_out;
3898 WL_INFO("power save set to %s\n",
3899 (power_mode ? "enabled" : "disabled"));
3901 err = brcmf_dongle_roam(ndev, (cfg_priv->roam_on ? 0 : 1),
3902 WL_BEACON_TIMEOUT);
3903 if (unlikely(err))
3904 goto default_conf_out;
3905 err = brcmf_dongle_mode(ndev, wdev->iftype);
3906 if (unlikely(err && err != -EINPROGRESS))
3907 goto default_conf_out;
3908 err = brcmf_dongle_probecap(cfg_priv);
3909 if (unlikely(err))
3910 goto default_conf_out;
3912 /* -EINPROGRESS: Call commit handler */
3914 default_conf_out:
3915 if (need_lock)
3916 rtnl_unlock();
3918 cfg_priv->dongle_up = true;
3920 return err;
3924 static s32 wl_update_wiphybands(struct brcmf_cfg80211_priv *cfg_priv)
3926 struct wiphy *wiphy;
3927 s32 phy_list;
3928 s8 phy;
3929 s32 err = 0;
3931 err = brcmf_dev_ioctl(cfg_to_ndev(cfg_priv), BRCM_GET_PHYLIST,
3932 &phy_list, sizeof(phy_list));
3933 if (unlikely(err)) {
3934 WL_ERR("error (%d)\n", err);
3935 return err;
3938 phy = ((char *)&phy_list)[1];
3939 WL_INFO("%c phy\n", phy);
3940 if (phy == 'n' || phy == 'a') {
3941 wiphy = cfg_to_wiphy(cfg_priv);
3942 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
3945 return err;
3948 static s32 __brcmf_cfg80211_up(struct brcmf_cfg80211_priv *cfg_priv)
3950 s32 err = 0;
3952 set_bit(WL_STATUS_READY, &cfg_priv->status);
3954 brcmf_debugfs_add_netdev_params(cfg_priv);
3956 err = brcmf_config_dongle(cfg_priv, false);
3957 if (unlikely(err))
3958 return err;
3960 brcmf_invoke_iscan(cfg_priv);
3962 return err;
3965 static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_priv *cfg_priv)
3968 * While going down, if associated with AP disassociate
3969 * from AP to save power
3971 if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) ||
3972 test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) &&
3973 test_bit(WL_STATUS_READY, &cfg_priv->status)) {
3974 WL_INFO("Disassociating from AP");
3975 brcmf_link_down(cfg_priv);
3977 /* Make sure WPA_Supplicant receives all the event
3978 generated due to DISASSOC call to the fw to keep
3979 the state fw and WPA_Supplicant state consistent
3981 rtnl_unlock();
3982 brcmf_delay(500);
3983 rtnl_lock();
3986 set_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
3987 brcmf_term_iscan(cfg_priv);
3988 if (cfg_priv->scan_request) {
3989 cfg80211_scan_done(cfg_priv->scan_request, true);
3990 /* May need to perform this to cover rmmod */
3991 /* wl_set_mpc(cfg_to_ndev(wl), 1); */
3992 cfg_priv->scan_request = NULL;
3994 clear_bit(WL_STATUS_READY, &cfg_priv->status);
3995 clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
3996 clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
3998 brcmf_debugfs_remove_netdev(cfg_priv);
4000 return 0;
4003 s32 brcmf_cfg80211_up(void)
4005 struct brcmf_cfg80211_priv *cfg_priv;
4006 s32 err = 0;
4008 cfg_priv = WL_PRIV_GET();
4009 mutex_lock(&cfg_priv->usr_sync);
4010 err = __brcmf_cfg80211_up(cfg_priv);
4011 mutex_unlock(&cfg_priv->usr_sync);
4013 return err;
4016 s32 brcmf_cfg80211_down(void)
4018 struct brcmf_cfg80211_priv *cfg_priv;
4019 s32 err = 0;
4021 cfg_priv = WL_PRIV_GET();
4022 mutex_lock(&cfg_priv->usr_sync);
4023 err = __brcmf_cfg80211_down(cfg_priv);
4024 mutex_unlock(&cfg_priv->usr_sync);
4026 return err;
4029 static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_priv *cfg_priv)
4031 return wl_update_wiphybands(cfg_priv);
4034 static void *brcmf_read_prof(struct brcmf_cfg80211_priv *cfg_priv, s32 item)
4036 switch (item) {
4037 case WL_PROF_SEC:
4038 return &cfg_priv->profile->sec;
4039 case WL_PROF_BSSID:
4040 return &cfg_priv->profile->bssid;
4041 case WL_PROF_SSID:
4042 return &cfg_priv->profile->ssid;
4044 WL_ERR("invalid item (%d)\n", item);
4045 return NULL;
4048 static s32
4049 brcmf_update_prof(struct brcmf_cfg80211_priv *cfg_priv,
4050 const struct brcmf_event_msg *e, void *data, s32 item)
4052 s32 err = 0;
4053 struct brcmf_ssid *ssid;
4055 switch (item) {
4056 case WL_PROF_SSID:
4057 ssid = (struct brcmf_ssid *) data;
4058 memset(cfg_priv->profile->ssid.SSID, 0,
4059 sizeof(cfg_priv->profile->ssid.SSID));
4060 memcpy(cfg_priv->profile->ssid.SSID,
4061 ssid->SSID, ssid->SSID_len);
4062 cfg_priv->profile->ssid.SSID_len = ssid->SSID_len;
4063 break;
4064 case WL_PROF_BSSID:
4065 if (data)
4066 memcpy(cfg_priv->profile->bssid, data, ETH_ALEN);
4067 else
4068 memset(cfg_priv->profile->bssid, 0, ETH_ALEN);
4069 break;
4070 case WL_PROF_SEC:
4071 memcpy(&cfg_priv->profile->sec, data,
4072 sizeof(cfg_priv->profile->sec));
4073 break;
4074 case WL_PROF_BEACONINT:
4075 cfg_priv->profile->beacon_interval = *(u16 *)data;
4076 break;
4077 case WL_PROF_DTIMPERIOD:
4078 cfg_priv->profile->dtim_period = *(u8 *)data;
4079 break;
4080 default:
4081 WL_ERR("unsupported item (%d)\n", item);
4082 err = -EOPNOTSUPP;
4083 break;
4086 return err;
4089 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_priv *cfg_priv)
4091 return cfg_priv->conf->mode == WL_MODE_IBSS;
4094 static __used s32 brcmf_add_ie(struct brcmf_cfg80211_priv *cfg_priv,
4095 u8 t, u8 l, u8 *v)
4097 struct brcmf_cfg80211_ie *ie = &cfg_priv->ie;
4098 s32 err = 0;
4100 if (unlikely(ie->offset + l + 2 > WL_TLV_INFO_MAX)) {
4101 WL_ERR("ei crosses buffer boundary\n");
4102 return -ENOSPC;
4104 ie->buf[ie->offset] = t;
4105 ie->buf[ie->offset + 1] = l;
4106 memcpy(&ie->buf[ie->offset + 2], v, l);
4107 ie->offset += l + 2;
4109 return err;
4112 static void brcmf_link_down(struct brcmf_cfg80211_priv *cfg_priv)
4114 struct net_device *dev = NULL;
4115 s32 err = 0;
4117 WL_TRACE("Enter\n");
4119 if (cfg_priv->link_up) {
4120 dev = cfg_to_ndev(cfg_priv);
4121 WL_INFO("Call WLC_DISASSOC to stop excess roaming\n ");
4122 err = brcmf_dev_ioctl(dev, BRCMF_C_DISASSOC, NULL, 0);
4123 if (unlikely(err))
4124 WL_ERR("WLC_DISASSOC failed (%d)\n", err);
4125 cfg_priv->link_up = false;
4127 WL_TRACE("Exit\n");
4130 static void brcmf_lock_eq(struct brcmf_cfg80211_priv *cfg_priv)
4132 spin_lock_irq(&cfg_priv->eq_lock);
4135 static void brcmf_unlock_eq(struct brcmf_cfg80211_priv *cfg_priv)
4137 spin_unlock_irq(&cfg_priv->eq_lock);
4140 static void brcmf_init_eq_lock(struct brcmf_cfg80211_priv *cfg_priv)
4142 spin_lock_init(&cfg_priv->eq_lock);
4145 static void brcmf_delay(u32 ms)
4147 if (ms < 1000 / HZ) {
4148 cond_resched();
4149 mdelay(ms);
4150 } else {
4151 msleep(ms);
4155 static void brcmf_set_drvdata(struct brcmf_cfg80211_dev *dev, void *data)
4157 dev->driver_data = data;
4160 static void *brcmf_get_drvdata(struct brcmf_cfg80211_dev *dev)
4162 void *data = NULL;
4164 if (dev)
4165 data = dev->driver_data;
4166 return data;
4169 static void brcmf_set_mpc(struct net_device *ndev, int mpc)
4171 s32 err = 0;
4172 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
4174 if (test_bit(WL_STATUS_READY, &cfg_priv->status)) {
4175 err = brcmf_dev_intvar_set(ndev, "mpc", mpc);
4176 if (unlikely(err)) {
4177 WL_ERR("fail to set mpc\n");
4178 return;
4180 WL_INFO("MPC : %d\n", mpc);
4184 static int brcmf_debugfs_add_netdev_params(struct brcmf_cfg80211_priv *cfg_priv)
4186 char buf[10+IFNAMSIZ];
4187 struct dentry *fd;
4188 s32 err = 0;
4190 sprintf(buf, "netdev:%s", cfg_to_ndev(cfg_priv)->name);
4191 cfg_priv->debugfsdir = debugfs_create_dir(buf,
4192 cfg_to_wiphy(cfg_priv)->debugfsdir);
4194 fd = debugfs_create_u16("beacon_int", S_IRUGO, cfg_priv->debugfsdir,
4195 (u16 *)&cfg_priv->profile->beacon_interval);
4196 if (!fd) {
4197 err = -ENOMEM;
4198 goto err_out;
4201 fd = debugfs_create_u8("dtim_period", S_IRUGO, cfg_priv->debugfsdir,
4202 (u8 *)&cfg_priv->profile->dtim_period);
4203 if (!fd) {
4204 err = -ENOMEM;
4205 goto err_out;
4208 err_out:
4209 return err;
4212 static void brcmf_debugfs_remove_netdev(struct brcmf_cfg80211_priv *cfg_priv)
4214 debugfs_remove_recursive(cfg_priv->debugfsdir);
4215 cfg_priv->debugfsdir = NULL;