]> git.karo-electronics.de Git - mv-sheeva.git/blob - drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c
staging: brcm80211: further renaming in fullmac sources
[mv-sheeva.git] / drivers / staging / brcm80211 / brcmfmac / wl_cfg80211.c
1 /*
2  * Copyright (c) 2010 Broadcom Corporation
3  *
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.
7  *
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.
15  */
16
17 #include <linux/kernel.h>
18 #include <linux/if_arp.h>
19 #include <linux/sched.h>
20 #include <linux/kthread.h>
21 #include <linux/netdevice.h>
22 #include <linux/sched.h>
23 #include <linux/etherdevice.h>
24 #include <linux/wireless.h>
25 #include <linux/ieee80211.h>
26 #include <linux/mmc/sdio_func.h>
27 #include <linux/firmware.h>
28 #include <linux/uaccess.h>
29 #include <net/cfg80211.h>
30 #include <net/rtnetlink.h>
31
32 #include <brcmu_utils.h>
33 #include <defs.h>
34 #include <brcmu_wifi.h>
35 #include "dngl_stats.h"
36 #include "dhd.h"
37 #include "wl_cfg80211.h"
38
39 void brcmf_sdioh_set_host_pm_flags(int flag);
40
41 static struct sdio_func *cfg80211_sdio_func;
42 static struct wl_dev *wl_cfg80211_dev;
43 static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255};
44
45 u32 brcmf_dbg_level = WL_DBG_ERR;
46
47 #define WL_4329_FW_FILE "brcm/bcm4329-fullmac-4.bin"
48 #define WL_4329_NVRAM_FILE "brcm/bcm4329-fullmac-4.txt"
49
50 /*
51 ** cfg80211_ops api/callback list
52 */
53 static s32 wl_cfg80211_change_iface(struct wiphy *wiphy,
54                                       struct net_device *ndev,
55                                       enum nl80211_iftype type, u32 *flags,
56                                       struct vif_params *params);
57 static s32 __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
58                                 struct cfg80211_scan_request *request,
59                                 struct cfg80211_ssid *this_ssid);
60 static s32 wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
61                               struct cfg80211_scan_request *request);
62 static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed);
63 static s32 wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
64                                    struct cfg80211_ibss_params *params);
65 static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy,
66                                     struct net_device *dev);
67 static s32 wl_cfg80211_get_station(struct wiphy *wiphy,
68                                      struct net_device *dev, u8 *mac,
69                                      struct station_info *sinfo);
70 static s32 wl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
71                                         struct net_device *dev, bool enabled,
72                                         s32 timeout);
73 static s32 wl_cfg80211_set_bitrate_mask(struct wiphy *wiphy,
74                                           struct net_device *dev,
75                                           const u8 *addr,
76                                           const struct cfg80211_bitrate_mask
77                                           *mask);
78 static int wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
79                                struct cfg80211_connect_params *sme);
80 static s32 wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
81                                     u16 reason_code);
82 static s32 wl_cfg80211_set_tx_power(struct wiphy *wiphy,
83                                       enum nl80211_tx_power_setting type,
84                                       s32 dbm);
85 static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm);
86 static s32 wl_cfg80211_config_default_key(struct wiphy *wiphy,
87                                           struct net_device *dev, u8 key_idx,
88                                           bool unicast, bool multicast);
89 static s32 wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
90                                  u8 key_idx, bool pairwise, const u8 *mac_addr,
91                                  struct key_params *params);
92 static s32 wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
93                                  u8 key_idx, bool pairwise, const u8 *mac_addr);
94 static s32 wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
95                                  u8 key_idx, bool pairwise, const u8 *mac_addr,
96                                  void *cookie, void (*callback) (void *cookie,
97                                                                  struct
98                                                                  key_params *
99                                                                  params));
100 static s32 wl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
101                                                  struct net_device *dev,
102                                                  u8 key_idx);
103 static s32 wl_cfg80211_resume(struct wiphy *wiphy);
104 static s32 wl_cfg80211_suspend(struct wiphy *wiphy,
105                                  struct cfg80211_wowlan *wow);
106 static s32 wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
107                                    struct cfg80211_pmksa *pmksa);
108 static s32 wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
109                                    struct cfg80211_pmksa *pmksa);
110 static s32 wl_cfg80211_flush_pmksa(struct wiphy *wiphy,
111                                      struct net_device *dev);
112 /*
113 ** event & event Q handlers for cfg80211 interfaces
114 */
115 static s32 wl_create_event_handler(struct wl_priv *wl);
116 static void wl_destroy_event_handler(struct wl_priv *wl);
117 static s32 wl_event_handler(void *data);
118 static void wl_init_eq(struct wl_priv *wl);
119 static void wl_flush_eq(struct wl_priv *wl);
120 static void wl_lock_eq(struct wl_priv *wl);
121 static void wl_unlock_eq(struct wl_priv *wl);
122 static void wl_init_eq_lock(struct wl_priv *wl);
123 static void wl_init_eloop_handler(struct wl_event_loop *el);
124 static struct wl_event_q *wl_deq_event(struct wl_priv *wl);
125 static s32 wl_enq_event(struct wl_priv *wl, u32 type,
126                           const brcmf_event_msg_t *msg, void *data);
127 static void wl_put_event(struct wl_event_q *e);
128 static void wl_wakeup_event(struct wl_priv *wl);
129 static s32 wl_notify_connect_status(struct wl_priv *wl,
130                                       struct net_device *ndev,
131                                       const brcmf_event_msg_t *e, void *data);
132 static s32 wl_notify_roaming_status(struct wl_priv *wl,
133                                       struct net_device *ndev,
134                                       const brcmf_event_msg_t *e, void *data);
135 static s32 wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev,
136                                    const brcmf_event_msg_t *e, void *data);
137 static s32 wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
138                                  const brcmf_event_msg_t *e, void *data,
139                                 bool completed);
140 static s32 wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev,
141                                  const brcmf_event_msg_t *e, void *data);
142 static s32 wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev,
143                                   const brcmf_event_msg_t *e, void *data);
144
145 /*
146 ** register/deregister sdio function
147 */
148 struct sdio_func *wl_cfg80211_get_sdio_func(void);
149 static void wl_clear_sdio_func(void);
150
151 /*
152 ** ioctl utilites
153 */
154 static s32 wl_dev_bufvar_get(struct net_device *dev, s8 *name, s8 *buf,
155                                s32 buf_len);
156 static __used s32 wl_dev_bufvar_set(struct net_device *dev, s8 *name,
157                                       s8 *buf, s32 len);
158 static s32 wl_dev_intvar_set(struct net_device *dev, s8 *name, s32 val);
159 static s32 wl_dev_intvar_get(struct net_device *dev, s8 *name,
160                                s32 *retval);
161 static s32 wl_dev_ioctl(struct net_device *dev, u32 cmd, void *arg,
162                           u32 len);
163
164 /*
165 ** cfg80211 set_wiphy_params utilities
166 */
167 static s32 wl_set_frag(struct net_device *dev, u32 frag_threshold);
168 static s32 wl_set_rts(struct net_device *dev, u32 frag_threshold);
169 static s32 wl_set_retry(struct net_device *dev, u32 retry, bool l);
170
171 /*
172 ** wl profile utilities
173 */
174 static s32 wl_update_prof(struct wl_priv *wl, const brcmf_event_msg_t *e,
175                             void *data, s32 item);
176 static void *wl_read_prof(struct wl_priv *wl, s32 item);
177 static void wl_init_prof(struct wl_profile *prof);
178
179 /*
180 ** cfg80211 connect utilites
181 */
182 static s32 wl_set_wpa_version(struct net_device *dev,
183                         struct cfg80211_connect_params *sme);
184 static s32 wl_set_auth_type(struct net_device *dev,
185                         struct cfg80211_connect_params *sme);
186 static s32 wl_set_set_cipher(struct net_device *dev,
187                         struct cfg80211_connect_params *sme);
188 static s32 wl_set_key_mgmt(struct net_device *dev,
189                         struct cfg80211_connect_params *sme);
190 static s32 wl_set_set_sharedkey(struct net_device *dev,
191                         struct cfg80211_connect_params *sme);
192 static s32 wl_get_assoc_ies(struct wl_priv *wl);
193 static void wl_clear_assoc_ies(struct wl_priv *wl);
194 static void wl_ch_to_chanspec(int ch,
195         struct wl_join_params *join_params, size_t *join_params_size);
196
197 /*
198 ** information element utilities
199 */
200 static __used s32 wl_add_ie(struct wl_priv *wl, u8 t, u8 l, u8 *v);
201 static s32 wl_mode_to_nl80211_iftype(s32 mode);
202 static struct wireless_dev *wl_alloc_wdev(s32 sizeof_iface,
203                         struct device *dev);
204 static void wl_free_wdev(struct wl_priv *wl);
205 static s32 wl_inform_bss(struct wl_priv *wl);
206 static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi);
207 static s32 wl_update_bss_info(struct wl_priv *wl);
208 static s32 wl_add_keyext(struct wiphy *wiphy, struct net_device *dev,
209                         u8 key_idx, const u8 *mac_addr,
210                         struct key_params *params);
211
212 /*
213 ** key indianess swap utilities
214 */
215 static void swap_key_from_BE(struct wl_wsec_key *key);
216 static void swap_key_to_BE(struct wl_wsec_key *key);
217
218 /*
219 ** wl_priv memory init/deinit utilities
220 */
221 static s32 wl_init_priv_mem(struct wl_priv *wl);
222 static void wl_deinit_priv_mem(struct wl_priv *wl);
223
224 static void wl_delay(u32 ms);
225
226 /*
227 ** store/restore cfg80211 instance data
228 */
229 static void wl_set_drvdata(struct wl_dev *dev, void *data);
230 static void *wl_get_drvdata(struct wl_dev *dev);
231
232 /*
233 ** ibss mode utilities
234 */
235 static bool wl_is_ibssmode(struct wl_priv *wl);
236
237 /*
238 ** dongle up/down , default configuration utilities
239 */
240 static bool wl_is_linkdown(struct wl_priv *wl, const brcmf_event_msg_t *e);
241 static bool wl_is_linkup(struct wl_priv *wl, const brcmf_event_msg_t *e);
242 static bool wl_is_nonetwork(struct wl_priv *wl, const brcmf_event_msg_t *e);
243 static void wl_link_down(struct wl_priv *wl);
244 static s32 wl_dongle_mode(struct net_device *ndev, s32 iftype);
245 static s32 __wl_cfg80211_up(struct wl_priv *wl);
246 static s32 __wl_cfg80211_down(struct wl_priv *wl);
247 static s32 wl_dongle_probecap(struct wl_priv *wl);
248 static void wl_init_conf(struct wl_conf *conf);
249
250 /*
251 ** dongle configuration utilities
252 */
253 #ifndef EMBEDDED_PLATFORM
254 static s32 wl_dongle_mode(struct net_device *ndev, s32 iftype);
255 static s32 wl_dongle_country(struct net_device *ndev, u8 ccode);
256 static s32 wl_dongle_up(struct net_device *ndev, u32 up);
257 static s32 wl_dongle_power(struct net_device *ndev, u32 power_mode);
258 static s32 wl_dongle_glom(struct net_device *ndev, u32 glom,
259                             u32 dongle_align);
260 static s32 wl_dongle_offload(struct net_device *ndev, s32 arpoe,
261                                s32 arp_ol);
262 static s32 wl_pattern_atoh(s8 *src, s8 *dst);
263 static s32 wl_dongle_filter(struct net_device *ndev, u32 filter_mode);
264 static s32 wl_update_wiphybands(struct wl_priv *wl);
265 #endif                          /* !EMBEDDED_PLATFORM */
266
267 static s32 wl_dongle_eventmsg(struct net_device *ndev);
268 static s32 wl_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
269                                 s32 scan_unassoc_time, s32 scan_passive_time);
270 static s32 wl_config_dongle(struct wl_priv *wl, bool need_lock);
271 static s32 wl_dongle_roam(struct net_device *ndev, u32 roamvar,
272                             u32 bcn_timeout);
273
274 /*
275 ** iscan handler
276 */
277 static void wl_iscan_timer(unsigned long data);
278 static void wl_term_iscan(struct wl_priv *wl);
279 static s32 wl_init_iscan(struct wl_priv *wl);
280 static s32 wl_iscan_thread(void *data);
281 static s32 wl_dev_iovar_setbuf(struct net_device *dev, s8 *iovar,
282                                  void *param, s32 paramlen, void *bufptr,
283                                  s32 buflen);
284 static s32 wl_dev_iovar_getbuf(struct net_device *dev, s8 *iovar,
285                                  void *param, s32 paramlen, void *bufptr,
286                                  s32 buflen);
287 static s32 wl_run_iscan(struct wl_iscan_ctrl *iscan, struct wlc_ssid *ssid,
288                           u16 action);
289 static s32 wl_do_iscan(struct wl_priv *wl);
290 static s32 wl_wakeup_iscan(struct wl_iscan_ctrl *iscan);
291 static s32 wl_invoke_iscan(struct wl_priv *wl);
292 static s32 wl_get_iscan_results(struct wl_iscan_ctrl *iscan, u32 *status,
293                                   struct wl_scan_results **bss_list);
294 static void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted);
295 static void wl_init_iscan_eloop(struct wl_iscan_eloop *el);
296 static s32 wl_iscan_done(struct wl_priv *wl);
297 static s32 wl_iscan_pending(struct wl_priv *wl);
298 static s32 wl_iscan_inprogress(struct wl_priv *wl);
299 static s32 wl_iscan_aborted(struct wl_priv *wl);
300
301 /*
302 ** fw/nvram downloading handler
303 */
304 static void wl_init_fw(struct wl_fw_ctrl *fw);
305
306 /*
307 * find most significant bit set
308 */
309 static __used u32 wl_find_msb(u16 bit16);
310
311 /*
312 * update pmklist to dongle
313 */
314 static __used s32 wl_update_pmklist(struct net_device *dev,
315                                       struct wl_pmk_list *pmk_list, s32 err);
316
317 static void wl_set_mpc(struct net_device *ndev, int mpc);
318
319 /*
320 * debufs support
321 */
322 static int wl_debugfs_add_netdev_params(struct wl_priv *wl);
323 static void wl_debugfs_remove_netdev(struct wl_priv *wl);
324
325 #define WL_PRIV_GET()                                                   \
326         ({                                                              \
327         struct wl_iface *ci = wl_get_drvdata(wl_cfg80211_dev);          \
328         if (unlikely(!ci)) {                                            \
329                 WL_ERR("wl_cfg80211_dev is unavailable\n");             \
330                 BUG();                                                  \
331         }                                                               \
332         ci_to_wl(ci);                                                   \
333 })
334
335 #define CHECK_SYS_UP()                                                  \
336 do {                                                                    \
337         struct wl_priv *wl = wiphy_to_wl(wiphy);                        \
338         if (unlikely(!test_bit(WL_STATUS_READY, &wl->status))) {        \
339                 WL_INFO("device is not ready : status (%d)\n",          \
340                         (int)wl->status);                               \
341                 return -EIO;                                            \
342         }                                                               \
343 } while (0)
344
345 #define CHAN2G(_channel, _freq, _flags) {                       \
346         .band                   = IEEE80211_BAND_2GHZ,          \
347         .center_freq            = (_freq),                      \
348         .hw_value               = (_channel),                   \
349         .flags                  = (_flags),                     \
350         .max_antenna_gain       = 0,                            \
351         .max_power              = 30,                           \
352 }
353
354 #define CHAN5G(_channel, _flags) {                              \
355         .band                   = IEEE80211_BAND_5GHZ,          \
356         .center_freq            = 5000 + (5 * (_channel)),      \
357         .hw_value               = (_channel),                   \
358         .flags                  = (_flags),                     \
359         .max_antenna_gain       = 0,                            \
360         .max_power              = 30,                           \
361 }
362
363 #define RATE_TO_BASE100KBPS(rate)   (((rate) * 10) / 2)
364 #define RATETAB_ENT(_rateid, _flags) \
365         {                                                               \
366                 .bitrate        = RATE_TO_BASE100KBPS(_rateid),     \
367                 .hw_value       = (_rateid),                            \
368                 .flags          = (_flags),                             \
369         }
370
371 static struct ieee80211_rate __wl_rates[] = {
372         RATETAB_ENT(WLC_RATE_1M, 0),
373         RATETAB_ENT(WLC_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
374         RATETAB_ENT(WLC_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
375         RATETAB_ENT(WLC_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
376         RATETAB_ENT(WLC_RATE_6M, 0),
377         RATETAB_ENT(WLC_RATE_9M, 0),
378         RATETAB_ENT(WLC_RATE_12M, 0),
379         RATETAB_ENT(WLC_RATE_18M, 0),
380         RATETAB_ENT(WLC_RATE_24M, 0),
381         RATETAB_ENT(WLC_RATE_36M, 0),
382         RATETAB_ENT(WLC_RATE_48M, 0),
383         RATETAB_ENT(WLC_RATE_54M, 0),
384 };
385
386 #define wl_a_rates              (__wl_rates + 4)
387 #define wl_a_rates_size 8
388 #define wl_g_rates              (__wl_rates + 0)
389 #define wl_g_rates_size 12
390
391 static struct ieee80211_channel __wl_2ghz_channels[] = {
392         CHAN2G(1, 2412, 0),
393         CHAN2G(2, 2417, 0),
394         CHAN2G(3, 2422, 0),
395         CHAN2G(4, 2427, 0),
396         CHAN2G(5, 2432, 0),
397         CHAN2G(6, 2437, 0),
398         CHAN2G(7, 2442, 0),
399         CHAN2G(8, 2447, 0),
400         CHAN2G(9, 2452, 0),
401         CHAN2G(10, 2457, 0),
402         CHAN2G(11, 2462, 0),
403         CHAN2G(12, 2467, 0),
404         CHAN2G(13, 2472, 0),
405         CHAN2G(14, 2484, 0),
406 };
407
408 static struct ieee80211_channel __wl_5ghz_a_channels[] = {
409         CHAN5G(34, 0), CHAN5G(36, 0),
410         CHAN5G(38, 0), CHAN5G(40, 0),
411         CHAN5G(42, 0), CHAN5G(44, 0),
412         CHAN5G(46, 0), CHAN5G(48, 0),
413         CHAN5G(52, 0), CHAN5G(56, 0),
414         CHAN5G(60, 0), CHAN5G(64, 0),
415         CHAN5G(100, 0), CHAN5G(104, 0),
416         CHAN5G(108, 0), CHAN5G(112, 0),
417         CHAN5G(116, 0), CHAN5G(120, 0),
418         CHAN5G(124, 0), CHAN5G(128, 0),
419         CHAN5G(132, 0), CHAN5G(136, 0),
420         CHAN5G(140, 0), CHAN5G(149, 0),
421         CHAN5G(153, 0), CHAN5G(157, 0),
422         CHAN5G(161, 0), CHAN5G(165, 0),
423         CHAN5G(184, 0), CHAN5G(188, 0),
424         CHAN5G(192, 0), CHAN5G(196, 0),
425         CHAN5G(200, 0), CHAN5G(204, 0),
426         CHAN5G(208, 0), CHAN5G(212, 0),
427         CHAN5G(216, 0),
428 };
429
430 static struct ieee80211_channel __wl_5ghz_n_channels[] = {
431         CHAN5G(32, 0), CHAN5G(34, 0),
432         CHAN5G(36, 0), CHAN5G(38, 0),
433         CHAN5G(40, 0), CHAN5G(42, 0),
434         CHAN5G(44, 0), CHAN5G(46, 0),
435         CHAN5G(48, 0), CHAN5G(50, 0),
436         CHAN5G(52, 0), CHAN5G(54, 0),
437         CHAN5G(56, 0), CHAN5G(58, 0),
438         CHAN5G(60, 0), CHAN5G(62, 0),
439         CHAN5G(64, 0), CHAN5G(66, 0),
440         CHAN5G(68, 0), CHAN5G(70, 0),
441         CHAN5G(72, 0), CHAN5G(74, 0),
442         CHAN5G(76, 0), CHAN5G(78, 0),
443         CHAN5G(80, 0), CHAN5G(82, 0),
444         CHAN5G(84, 0), CHAN5G(86, 0),
445         CHAN5G(88, 0), CHAN5G(90, 0),
446         CHAN5G(92, 0), CHAN5G(94, 0),
447         CHAN5G(96, 0), CHAN5G(98, 0),
448         CHAN5G(100, 0), CHAN5G(102, 0),
449         CHAN5G(104, 0), CHAN5G(106, 0),
450         CHAN5G(108, 0), CHAN5G(110, 0),
451         CHAN5G(112, 0), CHAN5G(114, 0),
452         CHAN5G(116, 0), CHAN5G(118, 0),
453         CHAN5G(120, 0), CHAN5G(122, 0),
454         CHAN5G(124, 0), CHAN5G(126, 0),
455         CHAN5G(128, 0), CHAN5G(130, 0),
456         CHAN5G(132, 0), CHAN5G(134, 0),
457         CHAN5G(136, 0), CHAN5G(138, 0),
458         CHAN5G(140, 0), CHAN5G(142, 0),
459         CHAN5G(144, 0), CHAN5G(145, 0),
460         CHAN5G(146, 0), CHAN5G(147, 0),
461         CHAN5G(148, 0), CHAN5G(149, 0),
462         CHAN5G(150, 0), CHAN5G(151, 0),
463         CHAN5G(152, 0), CHAN5G(153, 0),
464         CHAN5G(154, 0), CHAN5G(155, 0),
465         CHAN5G(156, 0), CHAN5G(157, 0),
466         CHAN5G(158, 0), CHAN5G(159, 0),
467         CHAN5G(160, 0), CHAN5G(161, 0),
468         CHAN5G(162, 0), CHAN5G(163, 0),
469         CHAN5G(164, 0), CHAN5G(165, 0),
470         CHAN5G(166, 0), CHAN5G(168, 0),
471         CHAN5G(170, 0), CHAN5G(172, 0),
472         CHAN5G(174, 0), CHAN5G(176, 0),
473         CHAN5G(178, 0), CHAN5G(180, 0),
474         CHAN5G(182, 0), CHAN5G(184, 0),
475         CHAN5G(186, 0), CHAN5G(188, 0),
476         CHAN5G(190, 0), CHAN5G(192, 0),
477         CHAN5G(194, 0), CHAN5G(196, 0),
478         CHAN5G(198, 0), CHAN5G(200, 0),
479         CHAN5G(202, 0), CHAN5G(204, 0),
480         CHAN5G(206, 0), CHAN5G(208, 0),
481         CHAN5G(210, 0), CHAN5G(212, 0),
482         CHAN5G(214, 0), CHAN5G(216, 0),
483         CHAN5G(218, 0), CHAN5G(220, 0),
484         CHAN5G(222, 0), CHAN5G(224, 0),
485         CHAN5G(226, 0), CHAN5G(228, 0),
486 };
487
488 static struct ieee80211_supported_band __wl_band_2ghz = {
489         .band = IEEE80211_BAND_2GHZ,
490         .channels = __wl_2ghz_channels,
491         .n_channels = ARRAY_SIZE(__wl_2ghz_channels),
492         .bitrates = wl_g_rates,
493         .n_bitrates = wl_g_rates_size,
494 };
495
496 static struct ieee80211_supported_band __wl_band_5ghz_a = {
497         .band = IEEE80211_BAND_5GHZ,
498         .channels = __wl_5ghz_a_channels,
499         .n_channels = ARRAY_SIZE(__wl_5ghz_a_channels),
500         .bitrates = wl_a_rates,
501         .n_bitrates = wl_a_rates_size,
502 };
503
504 static struct ieee80211_supported_band __wl_band_5ghz_n = {
505         .band = IEEE80211_BAND_5GHZ,
506         .channels = __wl_5ghz_n_channels,
507         .n_channels = ARRAY_SIZE(__wl_5ghz_n_channels),
508         .bitrates = wl_a_rates,
509         .n_bitrates = wl_a_rates_size,
510 };
511
512 static const u32 __wl_cipher_suites[] = {
513         WLAN_CIPHER_SUITE_WEP40,
514         WLAN_CIPHER_SUITE_WEP104,
515         WLAN_CIPHER_SUITE_TKIP,
516         WLAN_CIPHER_SUITE_CCMP,
517         WLAN_CIPHER_SUITE_AES_CMAC,
518 };
519
520 static void swap_key_from_BE(struct wl_wsec_key *key)
521 {
522         key->index = cpu_to_le32(key->index);
523         key->len = cpu_to_le32(key->len);
524         key->algo = cpu_to_le32(key->algo);
525         key->flags = cpu_to_le32(key->flags);
526         key->rxiv.hi = cpu_to_le32(key->rxiv.hi);
527         key->rxiv.lo = cpu_to_le16(key->rxiv.lo);
528         key->iv_initialized = cpu_to_le32(key->iv_initialized);
529 }
530
531 static void swap_key_to_BE(struct wl_wsec_key *key)
532 {
533         key->index = le32_to_cpu(key->index);
534         key->len = le32_to_cpu(key->len);
535         key->algo = le32_to_cpu(key->algo);
536         key->flags = le32_to_cpu(key->flags);
537         key->rxiv.hi = le32_to_cpu(key->rxiv.hi);
538         key->rxiv.lo = le16_to_cpu(key->rxiv.lo);
539         key->iv_initialized = le32_to_cpu(key->iv_initialized);
540 }
541
542 static s32
543 wl_dev_ioctl(struct net_device *dev, u32 cmd, void *arg, u32 len)
544 {
545         struct ifreq ifr;
546         struct wl_ioctl ioc;
547         mm_segment_t fs;
548         s32 err = 0;
549
550         memset(&ioc, 0, sizeof(ioc));
551         ioc.cmd = cmd;
552         ioc.buf = arg;
553         ioc.len = len;
554         strcpy(ifr.ifr_name, dev->name);
555         ifr.ifr_data = (caddr_t)&ioc;
556
557         fs = get_fs();
558         set_fs(get_ds());
559         err = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, SIOCDEVPRIVATE);
560         set_fs(fs);
561
562         return err;
563 }
564
565 static s32
566 wl_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
567                          enum nl80211_iftype type, u32 *flags,
568                          struct vif_params *params)
569 {
570         struct wl_priv *wl = wiphy_to_wl(wiphy);
571         struct wireless_dev *wdev;
572         s32 infra = 0;
573         s32 err = 0;
574
575         WL_TRACE("Enter\n");
576         CHECK_SYS_UP();
577
578         switch (type) {
579         case NL80211_IFTYPE_MONITOR:
580         case NL80211_IFTYPE_WDS:
581                 WL_ERR("type (%d) : currently we do not support this type\n",
582                        type);
583                 return -EOPNOTSUPP;
584         case NL80211_IFTYPE_ADHOC:
585                 wl->conf->mode = WL_MODE_IBSS;
586                 infra = 0;
587                 break;
588         case NL80211_IFTYPE_STATION:
589                 wl->conf->mode = WL_MODE_BSS;
590                 infra = 1;
591                 break;
592         default:
593                 err = -EINVAL;
594                 goto done;
595         }
596
597         infra = cpu_to_le32(infra);
598         err = wl_dev_ioctl(ndev, BRCMF_C_SET_INFRA, &infra, sizeof(infra));
599         if (unlikely(err)) {
600                 WL_ERR("WLC_SET_INFRA error (%d)\n", err);
601                 err = -EAGAIN;
602         } else {
603                 wdev = ndev->ieee80211_ptr;
604                 wdev->iftype = type;
605         }
606
607         WL_INFO("IF Type = %s\n",
608                 (wl->conf->mode == WL_MODE_IBSS) ? "Adhoc" : "Infra");
609
610 done:
611         WL_TRACE("Exit\n");
612
613         return err;
614 }
615
616 static void wl_iscan_prep(struct wl_scan_params *params, struct wlc_ssid *ssid)
617 {
618         memcpy(params->bssid, ether_bcast, ETH_ALEN);
619         params->bss_type = DOT11_BSSTYPE_ANY;
620         params->scan_type = 0;
621         params->nprobes = -1;
622         params->active_time = -1;
623         params->passive_time = -1;
624         params->home_time = -1;
625         params->channel_num = 0;
626
627         params->nprobes = cpu_to_le32(params->nprobes);
628         params->active_time = cpu_to_le32(params->active_time);
629         params->passive_time = cpu_to_le32(params->passive_time);
630         params->home_time = cpu_to_le32(params->home_time);
631         if (ssid && ssid->SSID_len)
632                 memcpy(&params->ssid, ssid, sizeof(wlc_ssid_t));
633
634 }
635
636 static s32
637 wl_dev_iovar_setbuf(struct net_device *dev, s8 * iovar, void *param,
638                     s32 paramlen, void *bufptr, s32 buflen)
639 {
640         s32 iolen;
641
642         iolen = brcmu_mkiovar(iovar, param, paramlen, bufptr, buflen);
643         BUG_ON(!iolen);
644
645         return wl_dev_ioctl(dev, BRCMF_C_SET_VAR, bufptr, iolen);
646 }
647
648 static s32
649 wl_dev_iovar_getbuf(struct net_device *dev, s8 * iovar, void *param,
650                     s32 paramlen, void *bufptr, s32 buflen)
651 {
652         s32 iolen;
653
654         iolen = brcmu_mkiovar(iovar, param, paramlen, bufptr, buflen);
655         BUG_ON(!iolen);
656
657         return wl_dev_ioctl(dev, BRCMF_C_GET_VAR, bufptr, buflen);
658 }
659
660 static s32
661 wl_run_iscan(struct wl_iscan_ctrl *iscan, struct wlc_ssid *ssid, u16 action)
662 {
663         s32 params_size =
664             (WL_SCAN_PARAMS_FIXED_SIZE + offsetof(wl_iscan_params_t, params));
665         struct wl_iscan_params *params;
666         s32 err = 0;
667
668         if (ssid && ssid->SSID_len)
669                 params_size += sizeof(struct wlc_ssid);
670         params = kzalloc(params_size, GFP_KERNEL);
671         if (unlikely(!params))
672                 return -ENOMEM;
673         BUG_ON(params_size >= BRCMF_C_IOCTL_SMLEN);
674
675         wl_iscan_prep(&params->params, ssid);
676
677         params->version = cpu_to_le32(ISCAN_REQ_VERSION);
678         params->action = cpu_to_le16(action);
679         params->scan_duration = cpu_to_le16(0);
680
681         /* params_size += offsetof(wl_iscan_params_t, params); */
682         err = wl_dev_iovar_setbuf(iscan->dev, "iscan", params, params_size,
683                                 iscan->ioctl_buf, BRCMF_C_IOCTL_SMLEN);
684         if (unlikely(err)) {
685                 if (err == -EBUSY) {
686                         WL_INFO("system busy : iscan canceled\n");
687                 } else {
688                         WL_ERR("error (%d)\n", err);
689                 }
690         }
691         kfree(params);
692         return err;
693 }
694
695 static s32 wl_do_iscan(struct wl_priv *wl)
696 {
697         struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
698         struct net_device *ndev = wl_to_ndev(wl);
699         struct wlc_ssid ssid;
700         s32 passive_scan;
701         s32 err = 0;
702
703         /* Broadcast scan by default */
704         memset(&ssid, 0, sizeof(ssid));
705
706         iscan->state = WL_ISCAN_STATE_SCANING;
707
708         passive_scan = wl->active_scan ? 0 : 1;
709         err = wl_dev_ioctl(wl_to_ndev(wl), BRCMF_C_SET_PASSIVE_SCAN,
710                         &passive_scan, sizeof(passive_scan));
711         if (unlikely(err)) {
712                 WL_ERR("error (%d)\n", err);
713                 return err;
714         }
715         wl_set_mpc(ndev, 0);
716         wl->iscan_kickstart = true;
717         wl_run_iscan(iscan, &ssid, WL_SCAN_ACTION_START);
718         mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
719         iscan->timer_on = 1;
720
721         return err;
722 }
723
724 static s32
725 __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
726                    struct cfg80211_scan_request *request,
727                    struct cfg80211_ssid *this_ssid)
728 {
729         struct wl_priv *wl = ndev_to_wl(ndev);
730         struct cfg80211_ssid *ssids;
731         struct wl_scan_req *sr = wl_to_sr(wl);
732         s32 passive_scan;
733         bool iscan_req;
734         bool spec_scan;
735         s32 err = 0;
736
737         if (unlikely(test_bit(WL_STATUS_SCANNING, &wl->status))) {
738                 WL_ERR("Scanning already : status (%d)\n", (int)wl->status);
739                 return -EAGAIN;
740         }
741         if (unlikely(test_bit(WL_STATUS_SCAN_ABORTING, &wl->status))) {
742                 WL_ERR("Scanning being aborted : status (%d)\n",
743                        (int)wl->status);
744                 return -EAGAIN;
745         }
746         if (test_bit(WL_STATUS_CONNECTING, &wl->status)) {
747                 WL_ERR("Connecting : status (%d)\n",
748                        (int)wl->status);
749                 return -EAGAIN;
750         }
751
752         iscan_req = false;
753         spec_scan = false;
754         if (request) {
755                 /* scan bss */
756                 ssids = request->ssids;
757                 if (wl->iscan_on && (!ssids || !ssids->ssid_len))
758                         iscan_req = true;
759         } else {
760                 /* scan in ibss */
761                 /* we don't do iscan in ibss */
762                 ssids = this_ssid;
763         }
764
765         wl->scan_request = request;
766         set_bit(WL_STATUS_SCANNING, &wl->status);
767         if (iscan_req) {
768                 err = wl_do_iscan(wl);
769                 if (likely(!err))
770                         return err;
771                 else
772                         goto scan_out;
773         } else {
774                 WL_SCAN("ssid \"%s\", ssid_len (%d)\n",
775                        ssids->ssid, ssids->ssid_len);
776                 memset(&sr->ssid, 0, sizeof(sr->ssid));
777                 sr->ssid.SSID_len =
778                             min_t(u8, sizeof(sr->ssid.SSID), ssids->ssid_len);
779                 if (sr->ssid.SSID_len) {
780                         memcpy(sr->ssid.SSID, ssids->ssid, sr->ssid.SSID_len);
781                         sr->ssid.SSID_len = cpu_to_le32(sr->ssid.SSID_len);
782                         spec_scan = true;
783                 } else {
784                         WL_SCAN("Broadcast scan\n");
785                 }
786
787                 passive_scan = wl->active_scan ? 0 : 1;
788                 err = wl_dev_ioctl(ndev, BRCMF_C_SET_PASSIVE_SCAN,
789                                 &passive_scan, sizeof(passive_scan));
790                 if (unlikely(err)) {
791                         WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
792                         goto scan_out;
793                 }
794                 wl_set_mpc(ndev, 0);
795                 err = wl_dev_ioctl(ndev, BRCMF_C_SCAN, &sr->ssid,
796                                 sizeof(sr->ssid));
797                 if (err) {
798                         if (err == -EBUSY) {
799                                 WL_INFO("system busy : scan for \"%s\" canceled\n",
800                                         sr->ssid.SSID);
801                         } else {
802                                 WL_ERR("WLC_SCAN error (%d)\n", err);
803                         }
804                         wl_set_mpc(ndev, 1);
805                         goto scan_out;
806                 }
807         }
808
809         return 0;
810
811 scan_out:
812         clear_bit(WL_STATUS_SCANNING, &wl->status);
813         wl->scan_request = NULL;
814         return err;
815 }
816
817 static s32
818 wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
819                  struct cfg80211_scan_request *request)
820 {
821         s32 err = 0;
822
823         WL_TRACE("Enter\n");
824
825         CHECK_SYS_UP();
826
827         err = __wl_cfg80211_scan(wiphy, ndev, request, NULL);
828         if (unlikely(err))
829                 WL_ERR("scan error (%d)\n", err);
830
831         WL_TRACE("Exit\n");
832         return err;
833 }
834
835 static s32 wl_dev_intvar_set(struct net_device *dev, s8 *name, s32 val)
836 {
837         s8 buf[BRCMF_C_IOCTL_SMLEN];
838         u32 len;
839         s32 err = 0;
840
841         val = cpu_to_le32(val);
842         len = brcmu_mkiovar(name, (char *)(&val), sizeof(val), buf,
843                             sizeof(buf));
844         BUG_ON(!len);
845
846         err = wl_dev_ioctl(dev, BRCMF_C_SET_VAR, buf, len);
847         if (unlikely(err))
848                 WL_ERR("error (%d)\n", err);
849
850         return err;
851 }
852
853 static s32
854 wl_dev_intvar_get(struct net_device *dev, s8 *name, s32 *retval)
855 {
856         union {
857                 s8 buf[BRCMF_C_IOCTL_SMLEN];
858                 s32 val;
859         } var;
860         u32 len;
861         u32 data_null;
862         s32 err = 0;
863
864         len =
865             brcmu_mkiovar(name, (char *)(&data_null), 0, (char *)(&var),
866                         sizeof(var.buf));
867         BUG_ON(!len);
868         err = wl_dev_ioctl(dev, BRCMF_C_GET_VAR, &var, len);
869         if (unlikely(err))
870                 WL_ERR("error (%d)\n", err);
871
872         *retval = le32_to_cpu(var.val);
873
874         return err;
875 }
876
877 static s32 wl_set_rts(struct net_device *dev, u32 rts_threshold)
878 {
879         s32 err = 0;
880
881         err = wl_dev_intvar_set(dev, "rtsthresh", rts_threshold);
882         if (unlikely(err))
883                 WL_ERR("Error (%d)\n", err);
884
885         return err;
886 }
887
888 static s32 wl_set_frag(struct net_device *dev, u32 frag_threshold)
889 {
890         s32 err = 0;
891
892         err = wl_dev_intvar_set(dev, "fragthresh", frag_threshold);
893         if (unlikely(err))
894                 WL_ERR("Error (%d)\n", err);
895
896         return err;
897 }
898
899 static s32 wl_set_retry(struct net_device *dev, u32 retry, bool l)
900 {
901         s32 err = 0;
902         u32 cmd = (l ? WLC_SET_LRL : WLC_SET_SRL);
903
904         retry = cpu_to_le32(retry);
905         err = wl_dev_ioctl(dev, cmd, &retry, sizeof(retry));
906         if (unlikely(err)) {
907                 WL_ERR("cmd (%d) , error (%d)\n", cmd, err);
908                 return err;
909         }
910         return err;
911 }
912
913 static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
914 {
915         struct wl_priv *wl = wiphy_to_wl(wiphy);
916         struct net_device *ndev = wl_to_ndev(wl);
917         s32 err = 0;
918
919         WL_TRACE("Enter\n");
920         CHECK_SYS_UP();
921
922         if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
923             (wl->conf->rts_threshold != wiphy->rts_threshold)) {
924                 wl->conf->rts_threshold = wiphy->rts_threshold;
925                 err = wl_set_rts(ndev, wl->conf->rts_threshold);
926                 if (!err)
927                         goto done;
928         }
929         if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
930             (wl->conf->frag_threshold != wiphy->frag_threshold)) {
931                 wl->conf->frag_threshold = wiphy->frag_threshold;
932                 err = wl_set_frag(ndev, wl->conf->frag_threshold);
933                 if (!err)
934                         goto done;
935         }
936         if (changed & WIPHY_PARAM_RETRY_LONG
937             && (wl->conf->retry_long != wiphy->retry_long)) {
938                 wl->conf->retry_long = wiphy->retry_long;
939                 err = wl_set_retry(ndev, wl->conf->retry_long, true);
940                 if (!err)
941                         goto done;
942         }
943         if (changed & WIPHY_PARAM_RETRY_SHORT
944             && (wl->conf->retry_short != wiphy->retry_short)) {
945                 wl->conf->retry_short = wiphy->retry_short;
946                 err = wl_set_retry(ndev, wl->conf->retry_short, false);
947                 if (!err)
948                         goto done;
949         }
950
951 done:
952         WL_TRACE("Exit\n");
953         return err;
954 }
955
956 static s32
957 wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
958                       struct cfg80211_ibss_params *params)
959 {
960         struct wl_priv *wl = wiphy_to_wl(wiphy);
961         struct wl_join_params join_params;
962         size_t join_params_size = 0;
963         s32 err = 0;
964         s32 wsec = 0;
965         s32 bcnprd;
966
967         WL_TRACE("Enter\n");
968         CHECK_SYS_UP();
969
970         if (params->ssid)
971                 WL_CONN("SSID: %s\n", params->ssid);
972         else {
973                 WL_CONN("SSID: NULL, Not supported\n");
974                 return -EOPNOTSUPP;
975         }
976
977         set_bit(WL_STATUS_CONNECTING, &wl->status);
978
979         if (params->bssid)
980                 WL_CONN("BSSID: %02X %02X %02X %02X %02X %02X\n",
981                 params->bssid[0], params->bssid[1], params->bssid[2],
982                 params->bssid[3], params->bssid[4], params->bssid[5]);
983         else
984                 WL_CONN("No BSSID specified\n");
985
986         if (params->channel)
987                 WL_CONN("channel: %d\n", params->channel->center_freq);
988         else
989                 WL_CONN("no channel specified\n");
990
991         if (params->channel_fixed)
992                 WL_CONN("fixed channel required\n");
993         else
994                 WL_CONN("no fixed channel required\n");
995
996         if (params->ie && params->ie_len)
997                 WL_CONN("ie len: %d\n", params->ie_len);
998         else
999                 WL_CONN("no ie specified\n");
1000
1001         if (params->beacon_interval)
1002                 WL_CONN("beacon interval: %d\n", params->beacon_interval);
1003         else
1004                 WL_CONN("no beacon interval specified\n");
1005
1006         if (params->basic_rates)
1007                 WL_CONN("basic rates: %08X\n", params->basic_rates);
1008         else
1009                 WL_CONN("no basic rates specified\n");
1010
1011         if (params->privacy)
1012                 WL_CONN("privacy required\n");
1013         else
1014                 WL_CONN("no privacy required\n");
1015
1016         /* Configure Privacy for starter */
1017         if (params->privacy)
1018                 wsec |= WEP_ENABLED;
1019
1020         err = wl_dev_intvar_set(dev, "wsec", wsec);
1021         if (unlikely(err)) {
1022                 WL_ERR("wsec failed (%d)\n", err);
1023                 goto done;
1024         }
1025
1026         /* Configure Beacon Interval for starter */
1027         if (params->beacon_interval)
1028                 bcnprd = cpu_to_le32(params->beacon_interval);
1029         else
1030                 bcnprd = cpu_to_le32(100);
1031
1032         err = wl_dev_ioctl(dev, WLC_SET_BCNPRD, &bcnprd, sizeof(bcnprd));
1033         if (unlikely(err)) {
1034                 WL_ERR("WLC_SET_BCNPRD failed (%d)\n", err);
1035                 goto done;
1036         }
1037
1038         /* Configure required join parameter */
1039         memset(&join_params, 0, sizeof(wl_join_params_t));
1040
1041         /* SSID */
1042         join_params.ssid.SSID_len =
1043                         (params->ssid_len > 32) ? 32 : params->ssid_len;
1044         memcpy(join_params.ssid.SSID, params->ssid, join_params.ssid.SSID_len);
1045         join_params.ssid.SSID_len = cpu_to_le32(join_params.ssid.SSID_len);
1046         join_params_size = sizeof(join_params.ssid);
1047         wl_update_prof(wl, NULL, &join_params.ssid, WL_PROF_SSID);
1048
1049         /* BSSID */
1050         if (params->bssid) {
1051                 memcpy(join_params.params.bssid, params->bssid, ETH_ALEN);
1052                 join_params_size =
1053                         sizeof(join_params.ssid) + WL_ASSOC_PARAMS_FIXED_SIZE;
1054         } else {
1055                 memcpy(join_params.params.bssid, ether_bcast, ETH_ALEN);
1056         }
1057         wl_update_prof(wl, NULL, &join_params.params.bssid, WL_PROF_BSSID);
1058
1059         /* Channel */
1060         if (params->channel) {
1061                 u32 target_channel;
1062
1063                 wl->channel =
1064                         ieee80211_frequency_to_channel(
1065                                 params->channel->center_freq);
1066                 if (params->channel_fixed) {
1067                         /* adding chanspec */
1068                         wl_ch_to_chanspec(wl->channel,
1069                                 &join_params, &join_params_size);
1070                 }
1071
1072                 /* set channel for starter */
1073                 target_channel = cpu_to_le32(wl->channel);
1074                 err = wl_dev_ioctl(dev, WLC_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;
1079                 }
1080         } else
1081                 wl->channel = 0;
1082
1083         wl->ibss_starter = false;
1084
1085
1086         err = wl_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;
1091         }
1092
1093 done:
1094         if (err)
1095                 clear_bit(WL_STATUS_CONNECTING, &wl->status);
1096         WL_TRACE("Exit\n");
1097         return err;
1098 }
1099
1100 static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
1101 {
1102         struct wl_priv *wl = wiphy_to_wl(wiphy);
1103         s32 err = 0;
1104
1105         WL_TRACE("Enter\n");
1106         CHECK_SYS_UP();
1107
1108         wl_link_down(wl);
1109
1110         WL_TRACE("Exit\n");
1111
1112         return err;
1113 }
1114
1115 static s32
1116 wl_set_wpa_version(struct net_device *dev, struct cfg80211_connect_params *sme)
1117 {
1118         struct wl_priv *wl = ndev_to_wl(dev);
1119         struct wl_security *sec;
1120         s32 val = 0;
1121         s32 err = 0;
1122
1123         if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1124                 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
1125         else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1126                 val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
1127         else
1128                 val = WPA_AUTH_DISABLED;
1129         WL_CONN("setting wpa_auth to 0x%0x\n", val);
1130         err = wl_dev_intvar_set(dev, "wpa_auth", val);
1131         if (unlikely(err)) {
1132                 WL_ERR("set wpa_auth failed (%d)\n", err);
1133                 return err;
1134         }
1135         sec = wl_read_prof(wl, WL_PROF_SEC);
1136         sec->wpa_versions = sme->crypto.wpa_versions;
1137         return err;
1138 }
1139
1140 static s32
1141 wl_set_auth_type(struct net_device *dev, struct cfg80211_connect_params *sme)
1142 {
1143         struct wl_priv *wl = ndev_to_wl(dev);
1144         struct wl_security *sec;
1145         s32 val = 0;
1146         s32 err = 0;
1147
1148         switch (sme->auth_type) {
1149         case NL80211_AUTHTYPE_OPEN_SYSTEM:
1150                 val = 0;
1151                 WL_CONN("open system\n");
1152                 break;
1153         case NL80211_AUTHTYPE_SHARED_KEY:
1154                 val = 1;
1155                 WL_CONN("shared key\n");
1156                 break;
1157         case NL80211_AUTHTYPE_AUTOMATIC:
1158                 val = 2;
1159                 WL_CONN("automatic\n");
1160                 break;
1161         case NL80211_AUTHTYPE_NETWORK_EAP:
1162                 WL_CONN("network eap\n");
1163         default:
1164                 val = 2;
1165                 WL_ERR("invalid auth type (%d)\n", sme->auth_type);
1166                 break;
1167         }
1168
1169         err = wl_dev_intvar_set(dev, "auth", val);
1170         if (unlikely(err)) {
1171                 WL_ERR("set auth failed (%d)\n", err);
1172                 return err;
1173         }
1174         sec = wl_read_prof(wl, WL_PROF_SEC);
1175         sec->auth_type = sme->auth_type;
1176         return err;
1177 }
1178
1179 static s32
1180 wl_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme)
1181 {
1182         struct wl_priv *wl = ndev_to_wl(dev);
1183         struct wl_security *sec;
1184         s32 pval = 0;
1185         s32 gval = 0;
1186         s32 err = 0;
1187
1188         if (sme->crypto.n_ciphers_pairwise) {
1189                 switch (sme->crypto.ciphers_pairwise[0]) {
1190                 case WLAN_CIPHER_SUITE_WEP40:
1191                 case WLAN_CIPHER_SUITE_WEP104:
1192                         pval = WEP_ENABLED;
1193                         break;
1194                 case WLAN_CIPHER_SUITE_TKIP:
1195                         pval = TKIP_ENABLED;
1196                         break;
1197                 case WLAN_CIPHER_SUITE_CCMP:
1198                         pval = AES_ENABLED;
1199                         break;
1200                 case WLAN_CIPHER_SUITE_AES_CMAC:
1201                         pval = AES_ENABLED;
1202                         break;
1203                 default:
1204                         WL_ERR("invalid cipher pairwise (%d)\n",
1205                                sme->crypto.ciphers_pairwise[0]);
1206                         return -EINVAL;
1207                 }
1208         }
1209         if (sme->crypto.cipher_group) {
1210                 switch (sme->crypto.cipher_group) {
1211                 case WLAN_CIPHER_SUITE_WEP40:
1212                 case WLAN_CIPHER_SUITE_WEP104:
1213                         gval = WEP_ENABLED;
1214                         break;
1215                 case WLAN_CIPHER_SUITE_TKIP:
1216                         gval = TKIP_ENABLED;
1217                         break;
1218                 case WLAN_CIPHER_SUITE_CCMP:
1219                         gval = AES_ENABLED;
1220                         break;
1221                 case WLAN_CIPHER_SUITE_AES_CMAC:
1222                         gval = AES_ENABLED;
1223                         break;
1224                 default:
1225                         WL_ERR("invalid cipher group (%d)\n",
1226                                sme->crypto.cipher_group);
1227                         return -EINVAL;
1228                 }
1229         }
1230
1231         WL_CONN("pval (%d) gval (%d)\n", pval, gval);
1232         err = wl_dev_intvar_set(dev, "wsec", pval | gval);
1233         if (unlikely(err)) {
1234                 WL_ERR("error (%d)\n", err);
1235                 return err;
1236         }
1237
1238         sec = wl_read_prof(wl, WL_PROF_SEC);
1239         sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1240         sec->cipher_group = sme->crypto.cipher_group;
1241
1242         return err;
1243 }
1244
1245 static s32
1246 wl_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme)
1247 {
1248         struct wl_priv *wl = ndev_to_wl(dev);
1249         struct wl_security *sec;
1250         s32 val = 0;
1251         s32 err = 0;
1252
1253         if (sme->crypto.n_akm_suites) {
1254                 err = wl_dev_intvar_get(dev, "wpa_auth", &val);
1255                 if (unlikely(err)) {
1256                         WL_ERR("could not get wpa_auth (%d)\n", err);
1257                         return err;
1258                 }
1259                 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1260                         switch (sme->crypto.akm_suites[0]) {
1261                         case WLAN_AKM_SUITE_8021X:
1262                                 val = WPA_AUTH_UNSPECIFIED;
1263                                 break;
1264                         case WLAN_AKM_SUITE_PSK:
1265                                 val = WPA_AUTH_PSK;
1266                                 break;
1267                         default:
1268                                 WL_ERR("invalid cipher group (%d)\n",
1269                                        sme->crypto.cipher_group);
1270                                 return -EINVAL;
1271                         }
1272                 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1273                         switch (sme->crypto.akm_suites[0]) {
1274                         case WLAN_AKM_SUITE_8021X:
1275                                 val = WPA2_AUTH_UNSPECIFIED;
1276                                 break;
1277                         case WLAN_AKM_SUITE_PSK:
1278                                 val = WPA2_AUTH_PSK;
1279                                 break;
1280                         default:
1281                                 WL_ERR("invalid cipher group (%d)\n",
1282                                        sme->crypto.cipher_group);
1283                                 return -EINVAL;
1284                         }
1285                 }
1286
1287                 WL_CONN("setting wpa_auth to %d\n", val);
1288                 err = wl_dev_intvar_set(dev, "wpa_auth", val);
1289                 if (unlikely(err)) {
1290                         WL_ERR("could not set wpa_auth (%d)\n", err);
1291                         return err;
1292                 }
1293         }
1294         sec = wl_read_prof(wl, WL_PROF_SEC);
1295         sec->wpa_auth = sme->crypto.akm_suites[0];
1296
1297         return err;
1298 }
1299
1300 static s32
1301 wl_set_set_sharedkey(struct net_device *dev,
1302                      struct cfg80211_connect_params *sme)
1303 {
1304         struct wl_priv *wl = ndev_to_wl(dev);
1305         struct wl_security *sec;
1306         struct wl_wsec_key key;
1307         s32 val;
1308         s32 err = 0;
1309
1310         WL_CONN("key len (%d)\n", sme->key_len);
1311         if (sme->key_len) {
1312                 sec = wl_read_prof(wl, WL_PROF_SEC);
1313                 WL_CONN("wpa_versions 0x%x cipher_pairwise 0x%x\n",
1314                        sec->wpa_versions, sec->cipher_pairwise);
1315                 if (!
1316                     (sec->wpa_versions & (NL80211_WPA_VERSION_1 |
1317                                           NL80211_WPA_VERSION_2))
1318 && (sec->cipher_pairwise & (WLAN_CIPHER_SUITE_WEP40 |
1319                             WLAN_CIPHER_SUITE_WEP104))) {
1320                         memset(&key, 0, sizeof(key));
1321                         key.len = (u32) sme->key_len;
1322                         key.index = (u32) sme->key_idx;
1323                         if (unlikely(key.len > sizeof(key.data))) {
1324                                 WL_ERR("Too long key length (%u)\n", key.len);
1325                                 return -EINVAL;
1326                         }
1327                         memcpy(key.data, sme->key, key.len);
1328                         key.flags = WL_PRIMARY_KEY;
1329                         switch (sec->cipher_pairwise) {
1330                         case WLAN_CIPHER_SUITE_WEP40:
1331                                 key.algo = CRYPTO_ALGO_WEP1;
1332                                 break;
1333                         case WLAN_CIPHER_SUITE_WEP104:
1334                                 key.algo = CRYPTO_ALGO_WEP128;
1335                                 break;
1336                         default:
1337                                 WL_ERR("Invalid algorithm (%d)\n",
1338                                        sme->crypto.ciphers_pairwise[0]);
1339                                 return -EINVAL;
1340                         }
1341                         /* Set the new key/index */
1342                         WL_CONN("key length (%d) key index (%d) algo (%d)\n",
1343                                key.len, key.index, key.algo);
1344                         WL_CONN("key \"%s\"\n", key.data);
1345                         swap_key_from_BE(&key);
1346                         err = wl_dev_ioctl(dev, BRCMF_C_SET_KEY, &key,
1347                                         sizeof(key));
1348                         if (unlikely(err)) {
1349                                 WL_ERR("WLC_SET_KEY error (%d)\n", err);
1350                                 return err;
1351                         }
1352                         if (sec->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) {
1353                                 WL_CONN("set auth_type to shared key\n");
1354                                 val = 1;        /* shared key */
1355                                 err = wl_dev_intvar_set(dev, "auth", val);
1356                                 if (unlikely(err)) {
1357                                         WL_ERR("set auth failed (%d)\n", err);
1358                                         return err;
1359                                 }
1360                         }
1361                 }
1362         }
1363         return err;
1364 }
1365
1366 static s32
1367 wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
1368                     struct cfg80211_connect_params *sme)
1369 {
1370         struct wl_priv *wl = wiphy_to_wl(wiphy);
1371         struct ieee80211_channel *chan = sme->channel;
1372         struct wl_join_params join_params;
1373         size_t join_params_size;
1374
1375         s32 err = 0;
1376
1377         WL_TRACE("Enter\n");
1378         CHECK_SYS_UP();
1379
1380         if (unlikely(!sme->ssid)) {
1381                 WL_ERR("Invalid ssid\n");
1382                 return -EOPNOTSUPP;
1383         }
1384
1385         set_bit(WL_STATUS_CONNECTING, &wl->status);
1386
1387         if (chan) {
1388                 wl->channel =
1389                         ieee80211_frequency_to_channel(chan->center_freq);
1390                 WL_CONN("channel (%d), center_req (%d)\n",
1391                         wl->channel, chan->center_freq);
1392         } else
1393                 wl->channel = 0;
1394
1395         WL_INFO("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
1396
1397         err = wl_set_wpa_version(dev, sme);
1398         if (err) {
1399                 WL_ERR("wl_set_wpa_version failed (%d)\n", err);
1400                 goto done;
1401         }
1402
1403         err = wl_set_auth_type(dev, sme);
1404         if (err) {
1405                 WL_ERR("wl_set_auth_type failed (%d)\n", err);
1406                 goto done;
1407         }
1408
1409         err = wl_set_set_cipher(dev, sme);
1410         if (err) {
1411                 WL_ERR("wl_set_set_cipher failed (%d)\n", err);
1412                 goto done;
1413         }
1414
1415         err = wl_set_key_mgmt(dev, sme);
1416         if (err) {
1417                 WL_ERR("wl_set_key_mgmt failed (%d)\n", err);
1418                 goto done;
1419         }
1420
1421         err = wl_set_set_sharedkey(dev, sme);
1422         if (err) {
1423                 WL_ERR("wl_set_set_sharedkey failed (%d)\n", err);
1424                 goto done;
1425         }
1426
1427         wl_update_prof(wl, NULL, sme->bssid, WL_PROF_BSSID);
1428         /*
1429          **  Join with specific BSSID and cached SSID
1430          **  If SSID is zero join based on BSSID only
1431          */
1432         memset(&join_params, 0, sizeof(join_params));
1433         join_params_size = sizeof(join_params.ssid);
1434
1435         join_params.ssid.SSID_len = min(sizeof(join_params.ssid.SSID), sme->ssid_len);
1436         memcpy(&join_params.ssid.SSID, sme->ssid, join_params.ssid.SSID_len);
1437         join_params.ssid.SSID_len = cpu_to_le32(join_params.ssid.SSID_len);
1438         wl_update_prof(wl, NULL, &join_params.ssid, WL_PROF_SSID);
1439
1440         if (sme->bssid)
1441                 memcpy(join_params.params.bssid, sme->bssid, ETH_ALEN);
1442         else
1443                 memcpy(join_params.params.bssid, ether_bcast, ETH_ALEN);
1444
1445         if (join_params.ssid.SSID_len < IEEE80211_MAX_SSID_LEN) {
1446                 WL_CONN("ssid \"%s\", len (%d)\n",
1447                        join_params.ssid.SSID, join_params.ssid.SSID_len);
1448         }
1449
1450         wl_ch_to_chanspec(wl->channel, &join_params, &join_params_size);
1451         err = wl_dev_ioctl(dev, BRCMF_C_SET_SSID,
1452                            &join_params, join_params_size);
1453         if (err)
1454                 WL_ERR("WLC_SET_SSID failed (%d)\n", err);
1455
1456 done:
1457         if (err)
1458                 clear_bit(WL_STATUS_CONNECTING, &wl->status);
1459         WL_TRACE("Exit\n");
1460         return err;
1461 }
1462
1463 static s32
1464 wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
1465                        u16 reason_code)
1466 {
1467         struct wl_priv *wl = wiphy_to_wl(wiphy);
1468         scb_val_t scbval;
1469         s32 err = 0;
1470
1471         WL_TRACE("Enter. Reason code = %d\n", reason_code);
1472         CHECK_SYS_UP();
1473
1474         clear_bit(WL_STATUS_CONNECTED, &wl->status);
1475
1476         scbval.val = reason_code;
1477         memcpy(&scbval.ea, wl_read_prof(wl, WL_PROF_BSSID), ETH_ALEN);
1478         scbval.val = cpu_to_le32(scbval.val);
1479         err = wl_dev_ioctl(dev, BRCMF_C_DISASSOC, &scbval,
1480                         sizeof(scb_val_t));
1481         if (unlikely(err))
1482                 WL_ERR("error (%d)\n", err);
1483
1484         wl->link_up = false;
1485
1486         WL_TRACE("Exit\n");
1487         return err;
1488 }
1489
1490 static s32
1491 wl_cfg80211_set_tx_power(struct wiphy *wiphy,
1492                          enum nl80211_tx_power_setting type, s32 dbm)
1493 {
1494
1495         struct wl_priv *wl = wiphy_to_wl(wiphy);
1496         struct net_device *ndev = wl_to_ndev(wl);
1497         u16 txpwrmw;
1498         s32 err = 0;
1499         s32 disable = 0;
1500
1501         WL_TRACE("Enter\n");
1502         CHECK_SYS_UP();
1503
1504         switch (type) {
1505         case NL80211_TX_POWER_AUTOMATIC:
1506                 break;
1507         case NL80211_TX_POWER_LIMITED:
1508                 if (dbm < 0) {
1509                         WL_ERR("TX_POWER_LIMITED - dbm is negative\n");
1510                         err = -EINVAL;
1511                         goto done;
1512                 }
1513                 break;
1514         case NL80211_TX_POWER_FIXED:
1515                 if (dbm < 0) {
1516                         WL_ERR("TX_POWER_FIXED - dbm is negative\n");
1517                         err = -EINVAL;
1518                         goto done;
1519                 }
1520                 break;
1521         }
1522         /* Make sure radio is off or on as far as software is concerned */
1523         disable = WL_RADIO_SW_DISABLE << 16;
1524         disable = cpu_to_le32(disable);
1525         err = wl_dev_ioctl(ndev, BRCMF_C_SET_RADIO, &disable, sizeof(disable));
1526         if (unlikely(err))
1527                 WL_ERR("WLC_SET_RADIO error (%d)\n", err);
1528
1529         if (dbm > 0xffff)
1530                 txpwrmw = 0xffff;
1531         else
1532                 txpwrmw = (u16) dbm;
1533         err = wl_dev_intvar_set(ndev, "qtxpower",
1534                         (s32) (brcmu_mw_to_qdbm(txpwrmw)));
1535         if (unlikely(err))
1536                 WL_ERR("qtxpower error (%d)\n", err);
1537         wl->conf->tx_power = dbm;
1538
1539 done:
1540         WL_TRACE("Exit\n");
1541         return err;
1542 }
1543
1544 static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm)
1545 {
1546         struct wl_priv *wl = wiphy_to_wl(wiphy);
1547         struct net_device *ndev = wl_to_ndev(wl);
1548         s32 txpwrdbm;
1549         u8 result;
1550         s32 err = 0;
1551
1552         WL_TRACE("Enter\n");
1553         CHECK_SYS_UP();
1554
1555         err = wl_dev_intvar_get(ndev, "qtxpower", &txpwrdbm);
1556         if (unlikely(err)) {
1557                 WL_ERR("error (%d)\n", err);
1558                 goto done;
1559         }
1560
1561         result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
1562         *dbm = (s32) brcmu_qdbm_to_mw(result);
1563
1564 done:
1565         WL_TRACE("Exit\n");
1566         return err;
1567 }
1568
1569 static s32
1570 wl_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *dev,
1571                                u8 key_idx, bool unicast, bool multicast)
1572 {
1573         u32 index;
1574         s32 wsec;
1575         s32 err = 0;
1576
1577         WL_TRACE("Enter\n");
1578         WL_CONN("key index (%d)\n", key_idx);
1579         CHECK_SYS_UP();
1580
1581         err = wl_dev_ioctl(dev, BRCMF_C_GET_WSEC, &wsec, sizeof(wsec));
1582         if (unlikely(err)) {
1583                 WL_ERR("WLC_GET_WSEC error (%d)\n", err);
1584                 goto done;
1585         }
1586
1587         wsec = le32_to_cpu(wsec);
1588         if (wsec & WEP_ENABLED) {
1589                 /* Just select a new current key */
1590                 index = (u32) key_idx;
1591                 index = cpu_to_le32(index);
1592                 err = wl_dev_ioctl(dev, BRCMF_C_SET_KEY_PRIMARY, &index,
1593                                 sizeof(index));
1594                 if (unlikely(err))
1595                         WL_ERR("error (%d)\n", err);
1596         }
1597 done:
1598         WL_TRACE("Exit\n");
1599         return err;
1600 }
1601
1602 static s32
1603 wl_add_keyext(struct wiphy *wiphy, struct net_device *dev,
1604               u8 key_idx, const u8 *mac_addr, struct key_params *params)
1605 {
1606         struct wl_wsec_key key;
1607         s32 err = 0;
1608
1609         memset(&key, 0, sizeof(key));
1610         key.index = (u32) key_idx;
1611         /* Instead of bcast for ea address for default wep keys,
1612                  driver needs it to be Null */
1613         if (!is_multicast_ether_addr(mac_addr))
1614                 memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
1615         key.len = (u32) params->key_len;
1616         /* check for key index change */
1617         if (key.len == 0) {
1618                 /* key delete */
1619                 swap_key_from_BE(&key);
1620                 err = wl_dev_ioctl(dev, BRCMF_C_SET_KEY, &key, sizeof(key));
1621                 if (unlikely(err)) {
1622                         WL_ERR("key delete error (%d)\n", err);
1623                         return err;
1624                 }
1625         } else {
1626                 if (key.len > sizeof(key.data)) {
1627                         WL_ERR("Invalid key length (%d)\n", key.len);
1628                         return -EINVAL;
1629                 }
1630
1631                 WL_CONN("Setting the key index %d\n", key.index);
1632                 memcpy(key.data, params->key, key.len);
1633
1634                 if (params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1635                         u8 keybuf[8];
1636                         memcpy(keybuf, &key.data[24], sizeof(keybuf));
1637                         memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1638                         memcpy(&key.data[16], keybuf, sizeof(keybuf));
1639                 }
1640
1641                 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
1642                 if (params->seq && params->seq_len == 6) {
1643                         /* rx iv */
1644                         u8 *ivptr;
1645                         ivptr = (u8 *) params->seq;
1646                         key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
1647                             (ivptr[3] << 8) | ivptr[2];
1648                         key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
1649                         key.iv_initialized = true;
1650                 }
1651
1652                 switch (params->cipher) {
1653                 case WLAN_CIPHER_SUITE_WEP40:
1654                         key.algo = CRYPTO_ALGO_WEP1;
1655                         WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1656                         break;
1657                 case WLAN_CIPHER_SUITE_WEP104:
1658                         key.algo = CRYPTO_ALGO_WEP128;
1659                         WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1660                         break;
1661                 case WLAN_CIPHER_SUITE_TKIP:
1662                         key.algo = CRYPTO_ALGO_TKIP;
1663                         WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1664                         break;
1665                 case WLAN_CIPHER_SUITE_AES_CMAC:
1666                         key.algo = CRYPTO_ALGO_AES_CCM;
1667                         WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1668                         break;
1669                 case WLAN_CIPHER_SUITE_CCMP:
1670                         key.algo = CRYPTO_ALGO_AES_CCM;
1671                         WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
1672                         break;
1673                 default:
1674                         WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
1675                         return -EINVAL;
1676                 }
1677                 swap_key_from_BE(&key);
1678
1679                 brcmf_netdev_wait_pend8021x(dev);
1680                 err = wl_dev_ioctl(dev, BRCMF_C_SET_KEY, &key, sizeof(key));
1681                 if (unlikely(err)) {
1682                         WL_ERR("WLC_SET_KEY error (%d)\n", err);
1683                         return err;
1684                 }
1685         }
1686         return err;
1687 }
1688
1689 static s32
1690 wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
1691                     u8 key_idx, bool pairwise, const u8 *mac_addr,
1692                     struct key_params *params)
1693 {
1694         struct wl_wsec_key key;
1695         s32 val;
1696         s32 wsec;
1697         s32 err = 0;
1698         u8 keybuf[8];
1699
1700         WL_TRACE("Enter\n");
1701         WL_CONN("key index (%d)\n", key_idx);
1702         CHECK_SYS_UP();
1703
1704         if (mac_addr) {
1705                 WL_TRACE("Exit");
1706                 return wl_add_keyext(wiphy, dev, key_idx, mac_addr, params);
1707         }
1708         memset(&key, 0, sizeof(key));
1709
1710         key.len = (u32) params->key_len;
1711         key.index = (u32) key_idx;
1712
1713         if (unlikely(key.len > sizeof(key.data))) {
1714                 WL_ERR("Too long key length (%u)\n", key.len);
1715                 err = -EINVAL;
1716                 goto done;
1717         }
1718         memcpy(key.data, params->key, key.len);
1719
1720         key.flags = WL_PRIMARY_KEY;
1721         switch (params->cipher) {
1722         case WLAN_CIPHER_SUITE_WEP40:
1723                 key.algo = CRYPTO_ALGO_WEP1;
1724                 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1725                 break;
1726         case WLAN_CIPHER_SUITE_WEP104:
1727                 key.algo = CRYPTO_ALGO_WEP128;
1728                 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1729                 break;
1730         case WLAN_CIPHER_SUITE_TKIP:
1731                 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1732                 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1733                 memcpy(&key.data[16], keybuf, sizeof(keybuf));
1734                 key.algo = CRYPTO_ALGO_TKIP;
1735                 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1736                 break;
1737         case WLAN_CIPHER_SUITE_AES_CMAC:
1738                 key.algo = CRYPTO_ALGO_AES_CCM;
1739                 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1740                 break;
1741         case WLAN_CIPHER_SUITE_CCMP:
1742                 key.algo = CRYPTO_ALGO_AES_CCM;
1743                 WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
1744                 break;
1745         default:
1746                 WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
1747                 err = -EINVAL;
1748                 goto done;
1749         }
1750
1751         /* Set the new key/index */
1752         swap_key_from_BE(&key);
1753         err = wl_dev_ioctl(dev, BRCMF_C_SET_KEY, &key, sizeof(key));
1754         if (unlikely(err)) {
1755                 WL_ERR("WLC_SET_KEY error (%d)\n", err);
1756                 goto done;
1757         }
1758
1759         val = WEP_ENABLED;
1760         err = wl_dev_intvar_get(dev, "wsec", &wsec);
1761         if (unlikely(err)) {
1762                 WL_ERR("get wsec error (%d)\n", err);
1763                 goto done;
1764         }
1765         wsec &= ~(WEP_ENABLED);
1766         wsec |= val;
1767         err = wl_dev_intvar_set(dev, "wsec", wsec);
1768         if (unlikely(err)) {
1769                 WL_ERR("set wsec error (%d)\n", err);
1770                 goto done;
1771         }
1772
1773         val = 1;                /* assume shared key. otherwise 0 */
1774         val = cpu_to_le32(val);
1775         err = wl_dev_ioctl(dev, BRCMF_C_SET_AUTH, &val, sizeof(val));
1776         if (unlikely(err))
1777                 WL_ERR("WLC_SET_AUTH error (%d)\n", err);
1778 done:
1779         WL_TRACE("Exit\n");
1780         return err;
1781 }
1782
1783 static s32
1784 wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
1785                     u8 key_idx, bool pairwise, const u8 *mac_addr)
1786 {
1787         struct wl_wsec_key key;
1788         s32 err = 0;
1789         s32 val;
1790         s32 wsec;
1791
1792         WL_TRACE("Enter\n");
1793         CHECK_SYS_UP();
1794         memset(&key, 0, sizeof(key));
1795
1796         key.index = (u32) key_idx;
1797         key.flags = WL_PRIMARY_KEY;
1798         key.algo = CRYPTO_ALGO_OFF;
1799
1800         WL_CONN("key index (%d)\n", key_idx);
1801         /* Set the new key/index */
1802         swap_key_from_BE(&key);
1803         err = wl_dev_ioctl(dev, BRCMF_C_SET_KEY, &key, sizeof(key));
1804         if (unlikely(err)) {
1805                 if (err == -EINVAL) {
1806                         if (key.index >= DOT11_MAX_DEFAULT_KEYS)
1807                                 /* we ignore this key index in this case */
1808                                 WL_ERR("invalid key index (%d)\n", key_idx);
1809                 } else
1810                         WL_ERR("WLC_SET_KEY error (%d)\n", err);
1811
1812                 /* Ignore this error, may happen during DISASSOC */
1813                 err = -EAGAIN;
1814                 goto done;
1815         }
1816
1817         val = 0;
1818         err = wl_dev_intvar_get(dev, "wsec", &wsec);
1819         if (unlikely(err)) {
1820                 WL_ERR("get wsec error (%d)\n", err);
1821                 /* Ignore this error, may happen during DISASSOC */
1822                 err = -EAGAIN;
1823                 goto done;
1824         }
1825         wsec &= ~(WEP_ENABLED);
1826         wsec |= val;
1827         err = wl_dev_intvar_set(dev, "wsec", wsec);
1828         if (unlikely(err)) {
1829                 WL_ERR("set wsec error (%d)\n", err);
1830                 /* Ignore this error, may happen during DISASSOC */
1831                 err = -EAGAIN;
1832                 goto done;
1833         }
1834
1835         val = 0;                /* assume open key. otherwise 1 */
1836         val = cpu_to_le32(val);
1837         err = wl_dev_ioctl(dev, BRCMF_C_SET_AUTH, &val, sizeof(val));
1838         if (unlikely(err)) {
1839                 WL_ERR("WLC_SET_AUTH error (%d)\n", err);
1840                 /* Ignore this error, may happen during DISASSOC */
1841                 err = -EAGAIN;
1842         }
1843 done:
1844         WL_TRACE("Exit\n");
1845         return err;
1846 }
1847
1848 static s32
1849 wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
1850                     u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
1851                     void (*callback) (void *cookie, struct key_params * params))
1852 {
1853         struct key_params params;
1854         struct wl_wsec_key key;
1855         struct wl_priv *wl = wiphy_to_wl(wiphy);
1856         struct wl_security *sec;
1857         s32 wsec;
1858         s32 err = 0;
1859
1860         WL_TRACE("Enter\n");
1861         WL_CONN("key index (%d)\n", key_idx);
1862         CHECK_SYS_UP();
1863
1864         memset(&key, 0, sizeof(key));
1865         key.index = key_idx;
1866         swap_key_to_BE(&key);
1867         memset(&params, 0, sizeof(params));
1868         params.key_len = (u8) min_t(u8, WLAN_MAX_KEY_LEN, key.len);
1869         memcpy(params.key, key.data, params.key_len);
1870
1871         err = wl_dev_ioctl(dev, BRCMF_C_GET_WSEC, &wsec, sizeof(wsec));
1872         if (unlikely(err)) {
1873                 WL_ERR("WLC_GET_WSEC error (%d)\n", err);
1874                 /* Ignore this error, may happen during DISASSOC */
1875                 err = -EAGAIN;
1876                 goto done;
1877         }
1878         wsec = le32_to_cpu(wsec);
1879         switch (wsec) {
1880         case WEP_ENABLED:
1881                 sec = wl_read_prof(wl, WL_PROF_SEC);
1882                 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
1883                         params.cipher = WLAN_CIPHER_SUITE_WEP40;
1884                         WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1885                 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
1886                         params.cipher = WLAN_CIPHER_SUITE_WEP104;
1887                         WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1888                 }
1889                 break;
1890         case TKIP_ENABLED:
1891                 params.cipher = WLAN_CIPHER_SUITE_TKIP;
1892                 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1893                 break;
1894         case AES_ENABLED:
1895                 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
1896                 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1897                 break;
1898         default:
1899                 WL_ERR("Invalid algo (0x%x)\n", wsec);
1900                 err = -EINVAL;
1901                 goto done;
1902         }
1903         callback(cookie, &params);
1904
1905 done:
1906         WL_TRACE("Exit\n");
1907         return err;
1908 }
1909
1910 static s32
1911 wl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
1912                                     struct net_device *dev, u8 key_idx)
1913 {
1914         WL_INFO("Not supported\n");
1915
1916         CHECK_SYS_UP();
1917         return -EOPNOTSUPP;
1918 }
1919
1920 static s32
1921 wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
1922                         u8 *mac, struct station_info *sinfo)
1923 {
1924         struct wl_priv *wl = wiphy_to_wl(wiphy);
1925         scb_val_t scb_val;
1926         int rssi;
1927         s32 rate;
1928         s32 err = 0;
1929         u8 *bssid = wl_read_prof(wl, WL_PROF_BSSID);
1930
1931         WL_TRACE("Enter\n");
1932         CHECK_SYS_UP();
1933
1934         if (unlikely
1935             (memcmp(mac, bssid, ETH_ALEN))) {
1936                 WL_ERR("Wrong Mac address cfg_mac-%X:%X:%X:%X:%X:%X"
1937                         "wl_bssid-%X:%X:%X:%X:%X:%X\n",
1938                         mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
1939                         bssid[0], bssid[1], bssid[2], bssid[3],
1940                         bssid[4], bssid[5]);
1941                 err = -ENOENT;
1942                 goto done;
1943         }
1944
1945         /* Report the current tx rate */
1946         err = wl_dev_ioctl(dev, BRCMF_C_GET_RATE, &rate, sizeof(rate));
1947         if (err) {
1948                 WL_ERR("Could not get rate (%d)\n", err);
1949         } else {
1950                 rate = le32_to_cpu(rate);
1951                 sinfo->filled |= STATION_INFO_TX_BITRATE;
1952                 sinfo->txrate.legacy = rate * 5;
1953                 WL_CONN("Rate %d Mbps\n", rate / 2);
1954         }
1955
1956         if (test_bit(WL_STATUS_CONNECTED, &wl->status)) {
1957                 scb_val.val = 0;
1958                 err = wl_dev_ioctl(dev, BRCMF_C_GET_RSSI, &scb_val,
1959                                 sizeof(scb_val_t));
1960                 if (unlikely(err)) {
1961                         WL_ERR("Could not get rssi (%d)\n", err);
1962                 }
1963                 rssi = le32_to_cpu(scb_val.val);
1964                 sinfo->filled |= STATION_INFO_SIGNAL;
1965                 sinfo->signal = rssi;
1966                 WL_CONN("RSSI %d dBm\n", rssi);
1967         }
1968
1969 done:
1970         WL_TRACE("Exit\n");
1971         return err;
1972 }
1973
1974 static s32
1975 wl_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
1976                            bool enabled, s32 timeout)
1977 {
1978         s32 pm;
1979         s32 err = 0;
1980
1981         WL_TRACE("Enter\n");
1982         CHECK_SYS_UP();
1983
1984         pm = enabled ? PM_FAST : PM_OFF;
1985         pm = cpu_to_le32(pm);
1986         WL_INFO("power save %s\n", (pm ? "enabled" : "disabled"));
1987
1988         err = wl_dev_ioctl(dev, BRCMF_C_SET_PM, &pm, sizeof(pm));
1989         if (unlikely(err)) {
1990                 if (err == -ENODEV)
1991                         WL_ERR("net_device is not ready yet\n");
1992                 else
1993                         WL_ERR("error (%d)\n", err);
1994         }
1995         WL_TRACE("Exit\n");
1996         return err;
1997 }
1998
1999 static __used u32 wl_find_msb(u16 bit16)
2000 {
2001         u32 ret = 0;
2002
2003         if (bit16 & 0xff00) {
2004                 ret += 8;
2005                 bit16 >>= 8;
2006         }
2007
2008         if (bit16 & 0xf0) {
2009                 ret += 4;
2010                 bit16 >>= 4;
2011         }
2012
2013         if (bit16 & 0xc) {
2014                 ret += 2;
2015                 bit16 >>= 2;
2016         }
2017
2018         if (bit16 & 2)
2019                 ret += bit16 & 2;
2020         else if (bit16)
2021                 ret += bit16;
2022
2023         return ret;
2024 }
2025
2026 static s32
2027 wl_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev,
2028                              const u8 *addr,
2029                              const struct cfg80211_bitrate_mask *mask)
2030 {
2031         struct wl_rateset rateset;
2032         s32 rate;
2033         s32 val;
2034         s32 err_bg;
2035         s32 err_a;
2036         u32 legacy;
2037         s32 err = 0;
2038
2039         WL_TRACE("Enter\n");
2040         CHECK_SYS_UP();
2041
2042         /* addr param is always NULL. ignore it */
2043         /* Get current rateset */
2044         err = wl_dev_ioctl(dev, WLC_GET_CURR_RATESET, &rateset,
2045                         sizeof(rateset));
2046         if (unlikely(err)) {
2047                 WL_ERR("could not get current rateset (%d)\n", err);
2048                 goto done;
2049         }
2050
2051         rateset.count = le32_to_cpu(rateset.count);
2052
2053         legacy = wl_find_msb(mask->control[IEEE80211_BAND_2GHZ].legacy);
2054         if (!legacy)
2055                 legacy = wl_find_msb(mask->control[IEEE80211_BAND_5GHZ].legacy);
2056
2057         val = wl_g_rates[legacy - 1].bitrate * 100000;
2058
2059         if (val < rateset.count)
2060                 /* Select rate by rateset index */
2061                 rate = rateset.rates[val] & 0x7f;
2062         else
2063                 /* Specified rate in bps */
2064                 rate = val / 500000;
2065
2066         WL_CONN("rate %d mbps\n", rate / 2);
2067
2068         /*
2069          *
2070          *      Set rate override,
2071          *      Since the is a/b/g-blind, both a/bg_rate are enforced.
2072          */
2073         err_bg = wl_dev_intvar_set(dev, "bg_rate", rate);
2074         err_a = wl_dev_intvar_set(dev, "a_rate", rate);
2075         if (unlikely(err_bg && err_a)) {
2076                 WL_ERR("could not set fixed rate (%d) (%d)\n", err_bg, err_a);
2077                 err = err_bg | err_a;
2078         }
2079
2080 done:
2081         WL_TRACE("Exit\n");
2082         return err;
2083 }
2084
2085 static s32 wl_cfg80211_resume(struct wiphy *wiphy)
2086 {
2087         struct wl_priv *wl = wiphy_to_wl(wiphy);
2088         struct net_device *ndev = wl_to_ndev(wl);
2089
2090         /*
2091          * Check for WL_STATUS_READY before any function call which
2092          * could result is bus access. Don't block the resume for
2093          * any driver error conditions
2094          */
2095         WL_TRACE("Enter\n");
2096
2097 #if defined(CONFIG_PM_SLEEP)
2098         atomic_set(&brcmf_mmc_suspend, false);
2099 #endif  /*  defined(CONFIG_PM_SLEEP) */
2100
2101         if (test_bit(WL_STATUS_READY, &wl->status)) {
2102                 /* Turn on Watchdog timer */
2103                 brcmf_netdev_os_wd_timer(ndev, brcmf_watchdog_ms);
2104                 wl_invoke_iscan(wiphy_to_wl(wiphy));
2105         }
2106
2107         WL_TRACE("Exit\n");
2108         return 0;
2109 }
2110
2111 static s32 wl_cfg80211_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow)
2112 {
2113         struct wl_priv *wl = wiphy_to_wl(wiphy);
2114         struct net_device *ndev = wl_to_ndev(wl);
2115
2116         WL_TRACE("Enter\n");
2117
2118         /*
2119          * Check for WL_STATUS_READY before any function call which
2120          * could result is bus access. Don't block the suspend for
2121          * any driver error conditions
2122          */
2123
2124         /*
2125          * While going to suspend if associated with AP disassociate
2126          * from AP to save power while system is in suspended state
2127          */
2128         if ((test_bit(WL_STATUS_CONNECTED, &wl->status) ||
2129              test_bit(WL_STATUS_CONNECTING, &wl->status)) &&
2130              test_bit(WL_STATUS_READY, &wl->status)) {
2131                 WL_INFO("Disassociating from AP"
2132                         " while entering suspend state\n");
2133                 wl_link_down(wl);
2134
2135                 /*
2136                  * Make sure WPA_Supplicant receives all the event
2137                  * generated due to DISASSOC call to the fw to keep
2138                  * the state fw and WPA_Supplicant state consistent
2139                  */
2140                 rtnl_unlock();
2141                 wl_delay(500);
2142                 rtnl_lock();
2143         }
2144
2145         set_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
2146         if (test_bit(WL_STATUS_READY, &wl->status))
2147                 wl_term_iscan(wl);
2148
2149         if (wl->scan_request) {
2150                 /* Indidate scan abort to cfg80211 layer */
2151                 WL_INFO("Terminating scan in progress\n");
2152                 cfg80211_scan_done(wl->scan_request, true);
2153                 wl->scan_request = NULL;
2154         }
2155         clear_bit(WL_STATUS_SCANNING, &wl->status);
2156         clear_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
2157
2158         /* Inform SDIO stack not to switch off power to the chip */
2159         brcmf_sdioh_set_host_pm_flags(MMC_PM_KEEP_POWER);
2160
2161         /* Turn off watchdog timer */
2162         if (test_bit(WL_STATUS_READY, &wl->status)) {
2163                 WL_INFO("Terminate watchdog timer and enable MPC\n");
2164                 wl_set_mpc(ndev, 1);
2165                 brcmf_netdev_os_wd_timer(ndev, 0);
2166         }
2167
2168 #if defined(CONFIG_PM_SLEEP)
2169         atomic_set(&brcmf_mmc_suspend, true);
2170 #endif  /*  defined(CONFIG_PM_SLEEP) */
2171
2172         WL_TRACE("Exit\n");
2173
2174         return 0;
2175 }
2176
2177 static __used s32
2178 wl_update_pmklist(struct net_device *dev, struct wl_pmk_list *pmk_list,
2179                   s32 err)
2180 {
2181         int i, j;
2182
2183         WL_CONN("No of elements %d\n", pmk_list->pmkids.npmkid);
2184         for (i = 0; i < pmk_list->pmkids.npmkid; i++) {
2185                 WL_CONN("PMKID[%d]: %pM =\n", i,
2186                         &pmk_list->pmkids.pmkid[i].BSSID);
2187                 for (j = 0; j < WLAN_PMKID_LEN; j++)
2188                         WL_CONN("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]);
2189         }
2190
2191         if (likely(!err))
2192                 wl_dev_bufvar_set(dev, "pmkid_info", (char *)pmk_list,
2193                                         sizeof(*pmk_list));
2194
2195         return err;
2196 }
2197
2198 static s32
2199 wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
2200                       struct cfg80211_pmksa *pmksa)
2201 {
2202         struct wl_priv *wl = wiphy_to_wl(wiphy);
2203         s32 err = 0;
2204         int i;
2205
2206         WL_TRACE("Enter\n");
2207         CHECK_SYS_UP();
2208
2209         for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++)
2210                 if (!memcmp(pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID,
2211                             ETH_ALEN))
2212                         break;
2213         if (i < WL_NUM_PMKIDS_MAX) {
2214                 memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID, pmksa->bssid,
2215                        ETH_ALEN);
2216                 memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID, pmksa->pmkid,
2217                        WLAN_PMKID_LEN);
2218                 if (i == wl->pmk_list->pmkids.npmkid)
2219                         wl->pmk_list->pmkids.npmkid++;
2220         } else
2221                 err = -EINVAL;
2222
2223         WL_CONN("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2224                &wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid].BSSID);
2225         for (i = 0; i < WLAN_PMKID_LEN; i++)
2226                 WL_CONN("%02x\n",
2227                        wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid].
2228                        PMKID[i]);
2229
2230         err = wl_update_pmklist(dev, wl->pmk_list, err);
2231
2232         WL_TRACE("Exit\n");
2233         return err;
2234 }
2235
2236 static s32
2237 wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
2238                       struct cfg80211_pmksa *pmksa)
2239 {
2240         struct wl_priv *wl = wiphy_to_wl(wiphy);
2241         struct _pmkid_list pmkid;
2242         s32 err = 0;
2243         int i;
2244
2245         WL_TRACE("Enter\n");
2246         CHECK_SYS_UP();
2247         memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
2248         memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2249
2250         WL_CONN("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2251                &pmkid.pmkid[0].BSSID);
2252         for (i = 0; i < WLAN_PMKID_LEN; i++)
2253                 WL_CONN("%02x\n", pmkid.pmkid[0].PMKID[i]);
2254
2255         for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++)
2256                 if (!memcmp
2257                     (pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID,
2258                      ETH_ALEN))
2259                         break;
2260
2261         if ((wl->pmk_list->pmkids.npmkid > 0)
2262             && (i < wl->pmk_list->pmkids.npmkid)) {
2263                 memset(&wl->pmk_list->pmkids.pmkid[i], 0, sizeof(pmkid_t));
2264                 for (; i < (wl->pmk_list->pmkids.npmkid - 1); i++) {
2265                         memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID,
2266                                &wl->pmk_list->pmkids.pmkid[i + 1].BSSID,
2267                                ETH_ALEN);
2268                         memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID,
2269                                &wl->pmk_list->pmkids.pmkid[i + 1].PMKID,
2270                                WLAN_PMKID_LEN);
2271                 }
2272                 wl->pmk_list->pmkids.npmkid--;
2273         } else
2274                 err = -EINVAL;
2275
2276         err = wl_update_pmklist(dev, wl->pmk_list, err);
2277
2278         WL_TRACE("Exit\n");
2279         return err;
2280
2281 }
2282
2283 static s32
2284 wl_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
2285 {
2286         struct wl_priv *wl = wiphy_to_wl(wiphy);
2287         s32 err = 0;
2288
2289         WL_TRACE("Enter\n");
2290         CHECK_SYS_UP();
2291
2292         memset(wl->pmk_list, 0, sizeof(*wl->pmk_list));
2293         err = wl_update_pmklist(dev, wl->pmk_list, err);
2294
2295         WL_TRACE("Exit\n");
2296         return err;
2297
2298 }
2299
2300 static struct cfg80211_ops wl_cfg80211_ops = {
2301         .change_virtual_intf = wl_cfg80211_change_iface,
2302         .scan = wl_cfg80211_scan,
2303         .set_wiphy_params = wl_cfg80211_set_wiphy_params,
2304         .join_ibss = wl_cfg80211_join_ibss,
2305         .leave_ibss = wl_cfg80211_leave_ibss,
2306         .get_station = wl_cfg80211_get_station,
2307         .set_tx_power = wl_cfg80211_set_tx_power,
2308         .get_tx_power = wl_cfg80211_get_tx_power,
2309         .add_key = wl_cfg80211_add_key,
2310         .del_key = wl_cfg80211_del_key,
2311         .get_key = wl_cfg80211_get_key,
2312         .set_default_key = wl_cfg80211_config_default_key,
2313         .set_default_mgmt_key = wl_cfg80211_config_default_mgmt_key,
2314         .set_power_mgmt = wl_cfg80211_set_power_mgmt,
2315         .set_bitrate_mask = wl_cfg80211_set_bitrate_mask,
2316         .connect = wl_cfg80211_connect,
2317         .disconnect = wl_cfg80211_disconnect,
2318         .suspend = wl_cfg80211_suspend,
2319         .resume = wl_cfg80211_resume,
2320         .set_pmksa = wl_cfg80211_set_pmksa,
2321         .del_pmksa = wl_cfg80211_del_pmksa,
2322         .flush_pmksa = wl_cfg80211_flush_pmksa
2323 };
2324
2325 static s32 wl_mode_to_nl80211_iftype(s32 mode)
2326 {
2327         s32 err = 0;
2328
2329         switch (mode) {
2330         case WL_MODE_BSS:
2331                 return NL80211_IFTYPE_STATION;
2332         case WL_MODE_IBSS:
2333                 return NL80211_IFTYPE_ADHOC;
2334         default:
2335                 return NL80211_IFTYPE_UNSPECIFIED;
2336         }
2337
2338         return err;
2339 }
2340
2341 static struct wireless_dev *wl_alloc_wdev(s32 sizeof_iface,
2342                                           struct device *dev)
2343 {
2344         struct wireless_dev *wdev;
2345         s32 err = 0;
2346
2347         wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
2348         if (unlikely(!wdev)) {
2349                 WL_ERR("Could not allocate wireless device\n");
2350                 return ERR_PTR(-ENOMEM);
2351         }
2352         wdev->wiphy =
2353             wiphy_new(&wl_cfg80211_ops, sizeof(struct wl_priv) + sizeof_iface);
2354         if (unlikely(!wdev->wiphy)) {
2355                 WL_ERR("Couldn not allocate wiphy device\n");
2356                 err = -ENOMEM;
2357                 goto wiphy_new_out;
2358         }
2359         set_wiphy_dev(wdev->wiphy, dev);
2360         wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
2361         wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
2362         wdev->wiphy->interface_modes =
2363             BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
2364         wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
2365         wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a;    /* Set
2366                                                 * it as 11a by default.
2367                                                 * This will be updated with
2368                                                 * 11n phy tables in
2369                                                 * "ifconfig up"
2370                                                 * if phy has 11n capability
2371                                                 */
2372         wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2373         wdev->wiphy->cipher_suites = __wl_cipher_suites;
2374         wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
2375 #ifndef WL_POWERSAVE_DISABLED
2376         wdev->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;      /* enable power
2377                                                                  * save mode
2378                                                                  * by default
2379                                                                  */
2380 #else
2381         wdev->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
2382 #endif                          /* !WL_POWERSAVE_DISABLED */
2383         err = wiphy_register(wdev->wiphy);
2384         if (unlikely(err < 0)) {
2385                 WL_ERR("Couldn not register wiphy device (%d)\n", err);
2386                 goto wiphy_register_out;
2387         }
2388         return wdev;
2389
2390 wiphy_register_out:
2391         wiphy_free(wdev->wiphy);
2392
2393 wiphy_new_out:
2394         kfree(wdev);
2395
2396         return ERR_PTR(err);
2397 }
2398
2399 static void wl_free_wdev(struct wl_priv *wl)
2400 {
2401         struct wireless_dev *wdev = wl_to_wdev(wl);
2402
2403         if (unlikely(!wdev)) {
2404                 WL_ERR("wdev is invalid\n");
2405                 return;
2406         }
2407         wiphy_unregister(wdev->wiphy);
2408         wiphy_free(wdev->wiphy);
2409         kfree(wdev);
2410         wl_to_wdev(wl) = NULL;
2411 }
2412
2413 static s32 wl_inform_bss(struct wl_priv *wl)
2414 {
2415         struct wl_scan_results *bss_list;
2416         struct wl_bss_info *bi = NULL;  /* must be initialized */
2417         s32 err = 0;
2418         int i;
2419
2420         bss_list = wl->bss_list;
2421         if (unlikely(bss_list->version != WL_BSS_INFO_VERSION)) {
2422                 WL_ERR("Version %d != WL_BSS_INFO_VERSION\n",
2423                        bss_list->version);
2424                 return -EOPNOTSUPP;
2425         }
2426         WL_SCAN("scanned AP count (%d)\n", bss_list->count);
2427         bi = next_bss(bss_list, bi);
2428         for_each_bss(bss_list, bi, i) {
2429                 err = wl_inform_single_bss(wl, bi);
2430                 if (unlikely(err))
2431                         break;
2432         }
2433         return err;
2434 }
2435
2436
2437 static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi)
2438 {
2439         struct wiphy *wiphy = wl_to_wiphy(wl);
2440         struct ieee80211_channel *notify_channel;
2441         struct cfg80211_bss *bss;
2442         struct ieee80211_supported_band *band;
2443         s32 err = 0;
2444         u16 channel;
2445         u32 freq;
2446         u64 notify_timestamp;
2447         u16 notify_capability;
2448         u16 notify_interval;
2449         u8 *notify_ie;
2450         size_t notify_ielen;
2451         s32 notify_signal;
2452
2453         if (unlikely(le32_to_cpu(bi->length) > WL_BSS_INFO_MAX)) {
2454                 WL_ERR("Bss info is larger than buffer. Discarding\n");
2455                 return 0;
2456         }
2457
2458         channel = bi->ctl_ch ? bi->ctl_ch :
2459                                 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2460
2461         if (channel <= CH_MAX_2G_CHANNEL)
2462                 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2463         else
2464                 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2465
2466         freq = ieee80211_channel_to_frequency(channel, band->band);
2467         notify_channel = ieee80211_get_channel(wiphy, freq);
2468
2469         notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */
2470         notify_capability = le16_to_cpu(bi->capability);
2471         notify_interval = le16_to_cpu(bi->beacon_period);
2472         notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2473         notify_ielen = le16_to_cpu(bi->ie_length);
2474         notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2475
2476         WL_CONN("bssid: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
2477                         bi->BSSID[0], bi->BSSID[1], bi->BSSID[2],
2478                         bi->BSSID[3], bi->BSSID[4], bi->BSSID[5]);
2479         WL_CONN("Channel: %d(%d)\n", channel, freq);
2480         WL_CONN("Capability: %X\n", notify_capability);
2481         WL_CONN("Beacon interval: %d\n", notify_interval);
2482         WL_CONN("Signal: %d\n", notify_signal);
2483         WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp);
2484
2485         bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)bi->BSSID,
2486                 notify_timestamp, notify_capability, notify_interval, notify_ie,
2487                 notify_ielen, notify_signal, GFP_KERNEL);
2488
2489         if (unlikely(!bss)) {
2490                 WL_ERR("cfg80211_inform_bss_frame error\n");
2491                 return -EINVAL;
2492         }
2493
2494         return err;
2495 }
2496
2497 static s32
2498 wl_inform_ibss(struct wl_priv *wl, struct net_device *dev, const u8 *bssid)
2499 {
2500         struct wiphy *wiphy = wl_to_wiphy(wl);
2501         struct ieee80211_channel *notify_channel;
2502         struct wl_bss_info *bi = NULL;
2503         struct ieee80211_supported_band *band;
2504         u8 *buf = NULL;
2505         s32 err = 0;
2506         u16 channel;
2507         u32 freq;
2508         u64 notify_timestamp;
2509         u16 notify_capability;
2510         u16 notify_interval;
2511         u8 *notify_ie;
2512         size_t notify_ielen;
2513         s32 notify_signal;
2514
2515         WL_TRACE("Enter\n");
2516
2517         buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2518         if (buf == NULL) {
2519                 WL_ERR("kzalloc() failed\n");
2520                 err = -ENOMEM;
2521                 goto CleanUp;
2522         }
2523
2524         *(u32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
2525
2526         err = wl_dev_ioctl(dev, BRCMF_C_GET_BSS_INFO, buf, WL_BSS_INFO_MAX);
2527         if (unlikely(err)) {
2528                 WL_ERR("WLC_GET_BSS_INFO failed: %d\n", err);
2529                 goto CleanUp;
2530         }
2531
2532         bi = (wl_bss_info_t *)(buf + 4);
2533
2534         channel = bi->ctl_ch ? bi->ctl_ch :
2535                                 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2536
2537         if (channel <= CH_MAX_2G_CHANNEL)
2538                 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2539         else
2540                 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2541
2542         freq = ieee80211_channel_to_frequency(channel, band->band);
2543         notify_channel = ieee80211_get_channel(wiphy, freq);
2544
2545         notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */
2546         notify_capability = le16_to_cpu(bi->capability);
2547         notify_interval = le16_to_cpu(bi->beacon_period);
2548         notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2549         notify_ielen = le16_to_cpu(bi->ie_length);
2550         notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2551
2552         WL_CONN("channel: %d(%d)\n", channel, freq);
2553         WL_CONN("capability: %X\n", notify_capability);
2554         WL_CONN("beacon interval: %d\n", notify_interval);
2555         WL_CONN("signal: %d\n", notify_signal);
2556         WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp);
2557
2558         cfg80211_inform_bss(wiphy, notify_channel, bssid,
2559                 notify_timestamp, notify_capability, notify_interval,
2560                 notify_ie, notify_ielen, notify_signal, GFP_KERNEL);
2561
2562 CleanUp:
2563
2564         kfree(buf);
2565
2566         WL_TRACE("Exit\n");
2567
2568         return err;
2569 }
2570
2571 static bool wl_is_linkup(struct wl_priv *wl, const brcmf_event_msg_t *e)
2572 {
2573         u32 event = be32_to_cpu(e->event_type);
2574         u32 status = be32_to_cpu(e->status);
2575
2576         if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
2577                 WL_CONN("Processing set ssid\n");
2578                 wl->link_up = true;
2579                 return true;
2580         }
2581
2582         return false;
2583 }
2584
2585 static bool wl_is_linkdown(struct wl_priv *wl, const brcmf_event_msg_t *e)
2586 {
2587         u32 event = be32_to_cpu(e->event_type);
2588         u16 flags = be16_to_cpu(e->flags);
2589
2590         if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) {
2591                 WL_CONN("Processing link down\n");
2592                 return true;
2593         }
2594         return false;
2595 }
2596
2597 static bool wl_is_nonetwork(struct wl_priv *wl, const brcmf_event_msg_t *e)
2598 {
2599         u32 event = be32_to_cpu(e->event_type);
2600         u32 status = be32_to_cpu(e->status);
2601
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;
2607         }
2608
2609         if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
2610                 WL_CONN("Processing connecting & no network found\n");
2611                 return true;
2612         }
2613
2614         return false;
2615 }
2616
2617 static s32
2618 wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
2619                          const brcmf_event_msg_t *e, void *data)
2620 {
2621         s32 err = 0;
2622
2623         if (wl_is_linkup(wl, e)) {
2624                 WL_CONN("Linkup\n");
2625                 if (wl_is_ibssmode(wl)) {
2626                         wl_update_prof(wl, NULL, (void *)e->addr,
2627                                 WL_PROF_BSSID);
2628                         wl_inform_ibss(wl, ndev, e->addr);
2629                         cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
2630                         clear_bit(WL_STATUS_CONNECTING, &wl->status);
2631                         set_bit(WL_STATUS_CONNECTED, &wl->status);
2632                 } else
2633                         wl_bss_connect_done(wl, ndev, e, data, true);
2634         } else if (wl_is_linkdown(wl, e)) {
2635                 WL_CONN("Linkdown\n");
2636                 if (wl_is_ibssmode(wl)) {
2637                         clear_bit(WL_STATUS_CONNECTING, &wl->status);
2638                         if (test_and_clear_bit(WL_STATUS_CONNECTED,
2639                                 &wl->status))
2640                                 wl_link_down(wl);
2641                 } else {
2642                         wl_bss_connect_done(wl, ndev, e, data, false);
2643                         if (test_and_clear_bit(WL_STATUS_CONNECTED,
2644                                 &wl->status)) {
2645                                 cfg80211_disconnected(ndev, 0, NULL, 0,
2646                                         GFP_KERNEL);
2647                                 wl_link_down(wl);
2648                         }
2649                 }
2650                 wl_init_prof(wl->profile);
2651         } else if (wl_is_nonetwork(wl, e)) {
2652                 if (wl_is_ibssmode(wl))
2653                         clear_bit(WL_STATUS_CONNECTING, &wl->status);
2654                 else
2655                         wl_bss_connect_done(wl, ndev, e, data, false);
2656         }
2657
2658         return err;
2659 }
2660
2661 static s32
2662 wl_notify_roaming_status(struct wl_priv *wl, struct net_device *ndev,
2663                          const brcmf_event_msg_t *e, void *data)
2664 {
2665         s32 err = 0;
2666         u32 event = be32_to_cpu(e->event_type);
2667         u32 status = be32_to_cpu(e->status);
2668
2669         if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
2670                 if (test_bit(WL_STATUS_CONNECTED, &wl->status))
2671                         wl_bss_roaming_done(wl, ndev, e, data);
2672                 else
2673                         wl_bss_connect_done(wl, ndev, e, data, true);
2674         }
2675
2676         return err;
2677 }
2678
2679 static __used s32
2680 wl_dev_bufvar_set(struct net_device *dev, s8 *name, s8 *buf, s32 len)
2681 {
2682         struct wl_priv *wl = ndev_to_wl(dev);
2683         u32 buflen;
2684
2685         buflen = brcmu_mkiovar(name, buf, len, wl->ioctl_buf, WL_IOCTL_LEN_MAX);
2686         BUG_ON(!buflen);
2687
2688         return wl_dev_ioctl(dev, BRCMF_C_SET_VAR, wl->ioctl_buf, buflen);
2689 }
2690
2691 static s32
2692 wl_dev_bufvar_get(struct net_device *dev, s8 *name, s8 *buf,
2693                   s32 buf_len)
2694 {
2695         struct wl_priv *wl = ndev_to_wl(dev);
2696         u32 len;
2697         s32 err = 0;
2698
2699         len = brcmu_mkiovar(name, NULL, 0, wl->ioctl_buf, WL_IOCTL_LEN_MAX);
2700         BUG_ON(!len);
2701         err = wl_dev_ioctl(dev, BRCMF_C_GET_VAR, (void *)wl->ioctl_buf,
2702                         WL_IOCTL_LEN_MAX);
2703         if (unlikely(err)) {
2704                 WL_ERR("error (%d)\n", err);
2705                 return err;
2706         }
2707         memcpy(buf, wl->ioctl_buf, buf_len);
2708
2709         return err;
2710 }
2711
2712 static s32 wl_get_assoc_ies(struct wl_priv *wl)
2713 {
2714         struct net_device *ndev = wl_to_ndev(wl);
2715         struct wl_assoc_ielen *assoc_info;
2716         struct wl_connect_info *conn_info = wl_to_conn(wl);
2717         u32 req_len;
2718         u32 resp_len;
2719         s32 err = 0;
2720
2721         wl_clear_assoc_ies(wl);
2722
2723         err = wl_dev_bufvar_get(ndev, "assoc_info", wl->extra_buf,
2724                                 WL_ASSOC_INFO_MAX);
2725         if (unlikely(err)) {
2726                 WL_ERR("could not get assoc info (%d)\n", err);
2727                 return err;
2728         }
2729         assoc_info = (struct wl_assoc_ielen *)wl->extra_buf;
2730         req_len = assoc_info->req_len;
2731         resp_len = assoc_info->resp_len;
2732         if (req_len) {
2733                 err = wl_dev_bufvar_get(ndev, "assoc_req_ies", wl->extra_buf,
2734                                         WL_ASSOC_INFO_MAX);
2735                 if (unlikely(err)) {
2736                         WL_ERR("could not get assoc req (%d)\n", err);
2737                         return err;
2738                 }
2739                 conn_info->req_ie_len = req_len;
2740                 conn_info->req_ie =
2741                     kmemdup(wl->extra_buf, conn_info->req_ie_len, GFP_KERNEL);
2742         } else {
2743                 conn_info->req_ie_len = 0;
2744                 conn_info->req_ie = NULL;
2745         }
2746         if (resp_len) {
2747                 err = wl_dev_bufvar_get(ndev, "assoc_resp_ies", wl->extra_buf,
2748                                         WL_ASSOC_INFO_MAX);
2749                 if (unlikely(err)) {
2750                         WL_ERR("could not get assoc resp (%d)\n", err);
2751                         return err;
2752                 }
2753                 conn_info->resp_ie_len = resp_len;
2754                 conn_info->resp_ie =
2755                     kmemdup(wl->extra_buf, conn_info->resp_ie_len, GFP_KERNEL);
2756         } else {
2757                 conn_info->resp_ie_len = 0;
2758                 conn_info->resp_ie = NULL;
2759         }
2760         WL_CONN("req len (%d) resp len (%d)\n",
2761                conn_info->req_ie_len, conn_info->resp_ie_len);
2762
2763         return err;
2764 }
2765
2766 static void wl_clear_assoc_ies(struct wl_priv *wl)
2767 {
2768         struct wl_connect_info *conn_info = wl_to_conn(wl);
2769
2770         kfree(conn_info->req_ie);
2771         conn_info->req_ie = NULL;
2772         conn_info->req_ie_len = 0;
2773         kfree(conn_info->resp_ie);
2774         conn_info->resp_ie = NULL;
2775         conn_info->resp_ie_len = 0;
2776 }
2777
2778
2779 static void wl_ch_to_chanspec(int ch, struct wl_join_params *join_params,
2780         size_t *join_params_size)
2781 {
2782         chanspec_t chanspec = 0;
2783
2784         if (ch != 0) {
2785                 join_params->params.chanspec_num = 1;
2786                 join_params->params.chanspec_list[0] = ch;
2787
2788                 if (join_params->params.chanspec_list[0] <= CH_MAX_2G_CHANNEL)
2789                         chanspec |= WL_CHANSPEC_BAND_2G;
2790                 else
2791                         chanspec |= WL_CHANSPEC_BAND_5G;
2792
2793                 chanspec |= WL_CHANSPEC_BW_20;
2794                 chanspec |= WL_CHANSPEC_CTL_SB_NONE;
2795
2796                 *join_params_size += WL_ASSOC_PARAMS_FIXED_SIZE +
2797                         join_params->params.chanspec_num * sizeof(chanspec_t);
2798
2799                 join_params->params.chanspec_list[0] &= WL_CHANSPEC_CHAN_MASK;
2800                 join_params->params.chanspec_list[0] |= chanspec;
2801                 join_params->params.chanspec_list[0] =
2802                 cpu_to_le16(join_params->params.chanspec_list[0]);
2803
2804                 join_params->params.chanspec_num =
2805                         cpu_to_le32(join_params->params.chanspec_num);
2806
2807                 WL_CONN("join_params->params.chanspec_list[0]= %#X,"
2808                         "channel %d, chanspec %#X\n",
2809                        join_params->params.chanspec_list[0], ch, chanspec);
2810         }
2811 }
2812
2813 static s32 wl_update_bss_info(struct wl_priv *wl)
2814 {
2815         struct wl_bss_info *bi;
2816         struct wlc_ssid *ssid;
2817         struct brcmu_tlv *tim;
2818         u16 beacon_interval;
2819         u8 dtim_period;
2820         size_t ie_len;
2821         u8 *ie;
2822         s32 err = 0;
2823
2824         WL_TRACE("Enter\n");
2825         if (wl_is_ibssmode(wl))
2826                 return err;
2827
2828         ssid = (struct wlc_ssid *)wl_read_prof(wl, WL_PROF_SSID);
2829
2830         *(u32 *)wl->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
2831         err = wl_dev_ioctl(wl_to_ndev(wl), BRCMF_C_GET_BSS_INFO,
2832                         wl->extra_buf, WL_EXTRA_BUF_MAX);
2833         if (unlikely(err)) {
2834                 WL_ERR("Could not get bss info %d\n", err);
2835                 goto update_bss_info_out;
2836         }
2837
2838         bi = (struct wl_bss_info *)(wl->extra_buf + 4);
2839         err = wl_inform_single_bss(wl, bi);
2840         if (unlikely(err))
2841                 goto update_bss_info_out;
2842
2843         ie = ((u8 *)bi) + bi->ie_offset;
2844         ie_len = bi->ie_length;
2845         beacon_interval = cpu_to_le16(bi->beacon_period);
2846
2847         tim = brcmu_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
2848         if (tim)
2849                 dtim_period = tim->data[1];
2850         else {
2851                 /*
2852                 * active scan was done so we could not get dtim
2853                 * information out of probe response.
2854                 * so we speficially query dtim information to dongle.
2855                 */
2856                 u32 var;
2857                 err = wl_dev_intvar_get(wl_to_ndev(wl), "dtim_assoc", &var);
2858                 if (unlikely(err)) {
2859                         WL_ERR("wl dtim_assoc failed (%d)\n", err);
2860                         goto update_bss_info_out;
2861                 }
2862                 dtim_period = (u8)var;
2863         }
2864
2865         wl_update_prof(wl, NULL, &beacon_interval, WL_PROF_BEACONINT);
2866         wl_update_prof(wl, NULL, &dtim_period, WL_PROF_DTIMPERIOD);
2867
2868 update_bss_info_out:
2869         WL_TRACE("Exit");
2870         return err;
2871 }
2872
2873 static s32
2874 wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev,
2875                     const brcmf_event_msg_t *e, void *data)
2876 {
2877         struct wl_connect_info *conn_info = wl_to_conn(wl);
2878         s32 err = 0;
2879
2880         WL_TRACE("Enter\n");
2881
2882         wl_get_assoc_ies(wl);
2883         wl_update_prof(wl, NULL, &e->addr, WL_PROF_BSSID);
2884         wl_update_bss_info(wl);
2885
2886         cfg80211_roamed(ndev, NULL,
2887                         (u8 *)wl_read_prof(wl, WL_PROF_BSSID),
2888                         conn_info->req_ie, conn_info->req_ie_len,
2889                         conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
2890         WL_CONN("Report roaming result\n");
2891
2892         set_bit(WL_STATUS_CONNECTED, &wl->status);
2893         WL_TRACE("Exit\n");
2894         return err;
2895 }
2896
2897 static s32
2898 wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
2899                     const brcmf_event_msg_t *e, void *data, bool completed)
2900 {
2901         struct wl_connect_info *conn_info = wl_to_conn(wl);
2902         s32 err = 0;
2903
2904         WL_TRACE("Enter\n");
2905
2906         if (test_and_clear_bit(WL_STATUS_CONNECTING, &wl->status)) {
2907                 if (completed) {
2908                         wl_get_assoc_ies(wl);
2909                         wl_update_prof(wl, NULL, &e->addr, WL_PROF_BSSID);
2910                         wl_update_bss_info(wl);
2911                 }
2912                 cfg80211_connect_result(ndev,
2913                                         (u8 *)wl_read_prof(wl, WL_PROF_BSSID),
2914                                         conn_info->req_ie,
2915                                         conn_info->req_ie_len,
2916                                         conn_info->resp_ie,
2917                                         conn_info->resp_ie_len,
2918                                         completed ? WLAN_STATUS_SUCCESS : WLAN_STATUS_AUTH_TIMEOUT,
2919                                         GFP_KERNEL);
2920                 if (completed)
2921                         set_bit(WL_STATUS_CONNECTED, &wl->status);
2922                 WL_CONN("Report connect result - connection %s\n",
2923                                 completed ? "succeeded" : "failed");
2924         }
2925         WL_TRACE("Exit\n");
2926         return err;
2927 }
2928
2929 static s32
2930 wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev,
2931                      const brcmf_event_msg_t *e, void *data)
2932 {
2933         u16 flags = be16_to_cpu(e->flags);
2934         enum nl80211_key_type key_type;
2935
2936         rtnl_lock();
2937         if (flags & BRCMF_EVENT_MSG_GROUP)
2938                 key_type = NL80211_KEYTYPE_GROUP;
2939         else
2940                 key_type = NL80211_KEYTYPE_PAIRWISE;
2941
2942         cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1,
2943                                      NULL, GFP_KERNEL);
2944         rtnl_unlock();
2945
2946         return 0;
2947 }
2948
2949 static s32
2950 wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev,
2951                       const brcmf_event_msg_t *e, void *data)
2952 {
2953         struct channel_info channel_inform;
2954         struct wl_scan_results *bss_list;
2955         u32 len = WL_SCAN_BUF_MAX;
2956         s32 err = 0;
2957         bool scan_abort = false;
2958
2959         WL_TRACE("Enter\n");
2960
2961         if (wl->iscan_on && wl->iscan_kickstart) {
2962                 WL_TRACE("Exit\n");
2963                 return wl_wakeup_iscan(wl_to_iscan(wl));
2964         }
2965
2966         if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING, &wl->status))) {
2967                 WL_ERR("Scan complete while device not scanning\n");
2968                 scan_abort = true;
2969                 err = -EINVAL;
2970                 goto scan_done_out;
2971         }
2972
2973         err = wl_dev_ioctl(ndev, BRCMF_C_GET_CHANNEL, &channel_inform,
2974                         sizeof(channel_inform));
2975         if (unlikely(err)) {
2976                 WL_ERR("scan busy (%d)\n", err);
2977                 scan_abort = true;
2978                 goto scan_done_out;
2979         }
2980         channel_inform.scan_channel = le32_to_cpu(channel_inform.scan_channel);
2981         if (unlikely(channel_inform.scan_channel)) {
2982
2983                 WL_CONN("channel_inform.scan_channel (%d)\n",
2984                        channel_inform.scan_channel);
2985         }
2986         wl->bss_list = wl->scan_results;
2987         bss_list = wl->bss_list;
2988         memset(bss_list, 0, len);
2989         bss_list->buflen = cpu_to_le32(len);
2990
2991         err = wl_dev_ioctl(ndev, BRCMF_C_SCAN_RESULTS, bss_list, len);
2992         if (unlikely(err)) {
2993                 WL_ERR("%s Scan_results error (%d)\n", ndev->name, err);
2994                 err = -EINVAL;
2995                 scan_abort = true;
2996                 goto scan_done_out;
2997         }
2998         bss_list->buflen = le32_to_cpu(bss_list->buflen);
2999         bss_list->version = le32_to_cpu(bss_list->version);
3000         bss_list->count = le32_to_cpu(bss_list->count);
3001
3002         err = wl_inform_bss(wl);
3003         if (err) {
3004                 scan_abort = true;
3005                 goto scan_done_out;
3006         }
3007
3008 scan_done_out:
3009         if (wl->scan_request) {
3010                 WL_SCAN("calling cfg80211_scan_done\n");
3011                 cfg80211_scan_done(wl->scan_request, scan_abort);
3012                 wl_set_mpc(ndev, 1);
3013                 wl->scan_request = NULL;
3014         }
3015
3016         WL_TRACE("Exit\n");
3017
3018         return err;
3019 }
3020
3021 static void wl_init_conf(struct wl_conf *conf)
3022 {
3023         conf->mode = (u32)-1;
3024         conf->frag_threshold = (u32)-1;
3025         conf->rts_threshold = (u32)-1;
3026         conf->retry_short = (u32)-1;
3027         conf->retry_long = (u32)-1;
3028         conf->tx_power = -1;
3029 }
3030
3031 static void wl_init_prof(struct wl_profile *prof)
3032 {
3033         memset(prof, 0, sizeof(*prof));
3034 }
3035
3036 static void wl_init_eloop_handler(struct wl_event_loop *el)
3037 {
3038         memset(el, 0, sizeof(*el));
3039         el->handler[BRCMF_E_SCAN_COMPLETE] = wl_notify_scan_status;
3040         el->handler[BRCMF_E_LINK] = wl_notify_connect_status;
3041         el->handler[BRCMF_E_ROAM] = wl_notify_roaming_status;
3042         el->handler[BRCMF_E_MIC_ERROR] = wl_notify_mic_status;
3043         el->handler[BRCMF_E_SET_SSID] = wl_notify_connect_status;
3044 }
3045
3046 static s32 wl_init_priv_mem(struct wl_priv *wl)
3047 {
3048         wl->scan_results = kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
3049         if (unlikely(!wl->scan_results)) {
3050                 WL_ERR("Scan results alloc failed\n");
3051                 goto init_priv_mem_out;
3052         }
3053         wl->conf = kzalloc(sizeof(*wl->conf), GFP_KERNEL);
3054         if (unlikely(!wl->conf)) {
3055                 WL_ERR("wl_conf alloc failed\n");
3056                 goto init_priv_mem_out;
3057         }
3058         wl->profile = kzalloc(sizeof(*wl->profile), GFP_KERNEL);
3059         if (unlikely(!wl->profile)) {
3060                 WL_ERR("wl_profile alloc failed\n");
3061                 goto init_priv_mem_out;
3062         }
3063         wl->bss_info = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
3064         if (unlikely(!wl->bss_info)) {
3065                 WL_ERR("Bss information alloc failed\n");
3066                 goto init_priv_mem_out;
3067         }
3068         wl->scan_req_int = kzalloc(sizeof(*wl->scan_req_int), GFP_KERNEL);
3069         if (unlikely(!wl->scan_req_int)) {
3070                 WL_ERR("Scan req alloc failed\n");
3071                 goto init_priv_mem_out;
3072         }
3073         wl->ioctl_buf = kzalloc(WL_IOCTL_LEN_MAX, GFP_KERNEL);
3074         if (unlikely(!wl->ioctl_buf)) {
3075                 WL_ERR("Ioctl buf alloc failed\n");
3076                 goto init_priv_mem_out;
3077         }
3078         wl->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
3079         if (unlikely(!wl->extra_buf)) {
3080                 WL_ERR("Extra buf alloc failed\n");
3081                 goto init_priv_mem_out;
3082         }
3083         wl->iscan = kzalloc(sizeof(*wl->iscan), GFP_KERNEL);
3084         if (unlikely(!wl->iscan)) {
3085                 WL_ERR("Iscan buf alloc failed\n");
3086                 goto init_priv_mem_out;
3087         }
3088         wl->fw = kzalloc(sizeof(*wl->fw), GFP_KERNEL);
3089         if (unlikely(!wl->fw)) {
3090                 WL_ERR("fw object alloc failed\n");
3091                 goto init_priv_mem_out;
3092         }
3093         wl->pmk_list = kzalloc(sizeof(*wl->pmk_list), GFP_KERNEL);
3094         if (unlikely(!wl->pmk_list)) {
3095                 WL_ERR("pmk list alloc failed\n");
3096                 goto init_priv_mem_out;
3097         }
3098
3099         return 0;
3100
3101 init_priv_mem_out:
3102         wl_deinit_priv_mem(wl);
3103
3104         return -ENOMEM;
3105 }
3106
3107 static void wl_deinit_priv_mem(struct wl_priv *wl)
3108 {
3109         kfree(wl->scan_results);
3110         wl->scan_results = NULL;
3111         kfree(wl->bss_info);
3112         wl->bss_info = NULL;
3113         kfree(wl->conf);
3114         wl->conf = NULL;
3115         kfree(wl->profile);
3116         wl->profile = NULL;
3117         kfree(wl->scan_req_int);
3118         wl->scan_req_int = NULL;
3119         kfree(wl->ioctl_buf);
3120         wl->ioctl_buf = NULL;
3121         kfree(wl->extra_buf);
3122         wl->extra_buf = NULL;
3123         kfree(wl->iscan);
3124         wl->iscan = NULL;
3125         kfree(wl->fw);
3126         wl->fw = NULL;
3127         kfree(wl->pmk_list);
3128         wl->pmk_list = NULL;
3129 }
3130
3131 static s32 wl_create_event_handler(struct wl_priv *wl)
3132 {
3133         sema_init(&wl->event_sync, 0);
3134         wl->event_tsk = kthread_run(wl_event_handler, wl, "wl_event_handler");
3135         if (IS_ERR(wl->event_tsk)) {
3136                 wl->event_tsk = NULL;
3137                 WL_ERR("failed to create event thread\n");
3138                 return -ENOMEM;
3139         }
3140         return 0;
3141 }
3142
3143 static void wl_destroy_event_handler(struct wl_priv *wl)
3144 {
3145         if (wl->event_tsk) {
3146                 send_sig(SIGTERM, wl->event_tsk, 1);
3147                 kthread_stop(wl->event_tsk);
3148                 wl->event_tsk = NULL;
3149         }
3150 }
3151
3152 static void wl_term_iscan(struct wl_priv *wl)
3153 {
3154         struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
3155
3156         if (wl->iscan_on && iscan->tsk) {
3157                 iscan->state = WL_ISCAN_STATE_IDLE;
3158                 send_sig(SIGTERM, iscan->tsk, 1);
3159                 kthread_stop(iscan->tsk);
3160                 iscan->tsk = NULL;
3161         }
3162 }
3163
3164 static void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted)
3165 {
3166         struct wl_priv *wl = iscan_to_wl(iscan);
3167         struct net_device *ndev = wl_to_ndev(wl);
3168
3169         if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING, &wl->status))) {
3170                 WL_ERR("Scan complete while device not scanning\n");
3171                 return;
3172         }
3173         if (likely(wl->scan_request)) {
3174                 WL_SCAN("ISCAN Completed scan: %s\n",
3175                                 aborted ? "Aborted" : "Done");
3176                 cfg80211_scan_done(wl->scan_request, aborted);
3177                 wl_set_mpc(ndev, 1);
3178                 wl->scan_request = NULL;
3179         }
3180         wl->iscan_kickstart = false;
3181 }
3182
3183 static s32 wl_wakeup_iscan(struct wl_iscan_ctrl *iscan)
3184 {
3185         if (likely(iscan->state != WL_ISCAN_STATE_IDLE)) {
3186                 WL_SCAN("wake up iscan\n");
3187                 up(&iscan->sync);
3188                 return 0;
3189         }
3190
3191         return -EIO;
3192 }
3193
3194 static s32
3195 wl_get_iscan_results(struct wl_iscan_ctrl *iscan, u32 *status,
3196                      struct wl_scan_results **bss_list)
3197 {
3198         struct wl_iscan_results list;
3199         struct wl_scan_results *results;
3200         struct wl_iscan_results *list_buf;
3201         s32 err = 0;
3202
3203         memset(iscan->scan_buf, 0, WL_ISCAN_BUF_MAX);
3204         list_buf = (struct wl_iscan_results *)iscan->scan_buf;
3205         results = &list_buf->results;
3206         results->buflen = WL_ISCAN_RESULTS_FIXED_SIZE;
3207         results->version = 0;
3208         results->count = 0;
3209
3210         memset(&list, 0, sizeof(list));
3211         list.results.buflen = cpu_to_le32(WL_ISCAN_BUF_MAX);
3212         err = wl_dev_iovar_getbuf(iscan->dev, "iscanresults", &list,
3213                                 WL_ISCAN_RESULTS_FIXED_SIZE, iscan->scan_buf,
3214                                 WL_ISCAN_BUF_MAX);
3215         if (unlikely(err)) {
3216                 WL_ERR("error (%d)\n", err);
3217                 return err;
3218         }
3219         results->buflen = le32_to_cpu(results->buflen);
3220         results->version = le32_to_cpu(results->version);
3221         results->count = le32_to_cpu(results->count);
3222         WL_SCAN("results->count = %d\n", results->count);
3223         WL_SCAN("results->buflen = %d\n", results->buflen);
3224         *status = le32_to_cpu(list_buf->status);
3225         *bss_list = results;
3226
3227         return err;
3228 }
3229
3230 static s32 wl_iscan_done(struct wl_priv *wl)
3231 {
3232         struct wl_iscan_ctrl *iscan = wl->iscan;
3233         s32 err = 0;
3234
3235         iscan->state = WL_ISCAN_STATE_IDLE;
3236         rtnl_lock();
3237         wl_inform_bss(wl);
3238         wl_notify_iscan_complete(iscan, false);
3239         rtnl_unlock();
3240
3241         return err;
3242 }
3243
3244 static s32 wl_iscan_pending(struct wl_priv *wl)
3245 {
3246         struct wl_iscan_ctrl *iscan = wl->iscan;
3247         s32 err = 0;
3248
3249         /* Reschedule the timer */
3250         mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
3251         iscan->timer_on = 1;
3252
3253         return err;
3254 }
3255
3256 static s32 wl_iscan_inprogress(struct wl_priv *wl)
3257 {
3258         struct wl_iscan_ctrl *iscan = wl->iscan;
3259         s32 err = 0;
3260
3261         rtnl_lock();
3262         wl_inform_bss(wl);
3263         wl_run_iscan(iscan, NULL, WL_SCAN_ACTION_CONTINUE);
3264         rtnl_unlock();
3265         /* Reschedule the timer */
3266         mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
3267         iscan->timer_on = 1;
3268
3269         return err;
3270 }
3271
3272 static s32 wl_iscan_aborted(struct wl_priv *wl)
3273 {
3274         struct wl_iscan_ctrl *iscan = wl->iscan;
3275         s32 err = 0;
3276
3277         iscan->state = WL_ISCAN_STATE_IDLE;
3278         rtnl_lock();
3279         wl_notify_iscan_complete(iscan, true);
3280         rtnl_unlock();
3281
3282         return err;
3283 }
3284
3285 static s32 wl_iscan_thread(void *data)
3286 {
3287         struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1 };
3288         struct wl_iscan_ctrl *iscan = (struct wl_iscan_ctrl *)data;
3289         struct wl_priv *wl = iscan_to_wl(iscan);
3290         struct wl_iscan_eloop *el = &iscan->el;
3291         u32 status;
3292         int err = 0;
3293
3294         sched_setscheduler(current, SCHED_FIFO, &param);
3295         allow_signal(SIGTERM);
3296         status = WL_SCAN_RESULTS_PARTIAL;
3297         while (likely(!down_interruptible(&iscan->sync))) {
3298                 if (kthread_should_stop())
3299                         break;
3300                 if (iscan->timer_on) {
3301                         del_timer_sync(&iscan->timer);
3302                         iscan->timer_on = 0;
3303                 }
3304                 rtnl_lock();
3305                 err = wl_get_iscan_results(iscan, &status, &wl->bss_list);
3306                 if (unlikely(err)) {
3307                         status = WL_SCAN_RESULTS_ABORTED;
3308                         WL_ERR("Abort iscan\n");
3309                 }
3310                 rtnl_unlock();
3311                 el->handler[status] (wl);
3312         }
3313         if (iscan->timer_on) {
3314                 del_timer_sync(&iscan->timer);
3315                 iscan->timer_on = 0;
3316         }
3317         WL_SCAN("ISCAN thread terminated\n");
3318
3319         return 0;
3320 }
3321
3322 static void wl_iscan_timer(unsigned long data)
3323 {
3324         struct wl_iscan_ctrl *iscan = (struct wl_iscan_ctrl *)data;
3325
3326         if (iscan) {
3327                 iscan->timer_on = 0;
3328                 WL_SCAN("timer expired\n");
3329                 wl_wakeup_iscan(iscan);
3330         }
3331 }
3332
3333 static s32 wl_invoke_iscan(struct wl_priv *wl)
3334 {
3335         struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
3336         int err = 0;
3337
3338         if (wl->iscan_on && !iscan->tsk) {
3339                 iscan->state = WL_ISCAN_STATE_IDLE;
3340                 sema_init(&iscan->sync, 0);
3341                 iscan->tsk = kthread_run(wl_iscan_thread, iscan, "wl_iscan");
3342                 if (IS_ERR(iscan->tsk)) {
3343                         WL_ERR("Could not create iscan thread\n");
3344                         iscan->tsk = NULL;
3345                         return -ENOMEM;
3346                 }
3347         }
3348
3349         return err;
3350 }
3351
3352 static void wl_init_iscan_eloop(struct wl_iscan_eloop *el)
3353 {
3354         memset(el, 0, sizeof(*el));
3355         el->handler[WL_SCAN_RESULTS_SUCCESS] = wl_iscan_done;
3356         el->handler[WL_SCAN_RESULTS_PARTIAL] = wl_iscan_inprogress;
3357         el->handler[WL_SCAN_RESULTS_PENDING] = wl_iscan_pending;
3358         el->handler[WL_SCAN_RESULTS_ABORTED] = wl_iscan_aborted;
3359         el->handler[WL_SCAN_RESULTS_NO_MEM] = wl_iscan_aborted;
3360 }
3361
3362 static s32 wl_init_iscan(struct wl_priv *wl)
3363 {
3364         struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
3365         int err = 0;
3366
3367         if (wl->iscan_on) {
3368                 iscan->dev = wl_to_ndev(wl);
3369                 iscan->state = WL_ISCAN_STATE_IDLE;
3370                 wl_init_iscan_eloop(&iscan->el);
3371                 iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS;
3372                 init_timer(&iscan->timer);
3373                 iscan->timer.data = (unsigned long) iscan;
3374                 iscan->timer.function = wl_iscan_timer;
3375                 sema_init(&iscan->sync, 0);
3376                 iscan->tsk = kthread_run(wl_iscan_thread, iscan, "wl_iscan");
3377                 if (IS_ERR(iscan->tsk)) {
3378                         WL_ERR("Could not create iscan thread\n");
3379                         iscan->tsk = NULL;
3380                         return -ENOMEM;
3381                 }
3382                 iscan->data = wl;
3383         }
3384
3385         return err;
3386 }
3387
3388 static void wl_init_fw(struct wl_fw_ctrl *fw)
3389 {
3390         fw->status = 0;         /* init fw loading status.
3391                                  0 means nothing was loaded yet */
3392 }
3393
3394 static s32 wl_init_priv(struct wl_priv *wl)
3395 {
3396         struct wiphy *wiphy = wl_to_wiphy(wl);
3397         s32 err = 0;
3398
3399         wl->scan_request = NULL;
3400         wl->pwr_save = !!(wiphy->flags & WIPHY_FLAG_PS_ON_BY_DEFAULT);
3401         wl->iscan_on = true;    /* iscan on & off switch.
3402                                  we enable iscan per default */
3403         wl->roam_on = false;    /* roam on & off switch.
3404                                  we enable roam per default */
3405
3406         wl->iscan_kickstart = false;
3407         wl->active_scan = true; /* we do active scan for
3408                                  specific scan per default */
3409         wl->dongle_up = false;  /* dongle is not up yet */
3410         wl_init_eq(wl);
3411         err = wl_init_priv_mem(wl);
3412         if (unlikely(err))
3413                 return err;
3414         if (unlikely(wl_create_event_handler(wl)))
3415                 return -ENOMEM;
3416         wl_init_eloop_handler(&wl->el);
3417         mutex_init(&wl->usr_sync);
3418         err = wl_init_iscan(wl);
3419         if (unlikely(err))
3420                 return err;
3421         wl_init_fw(wl->fw);
3422         wl_init_conf(wl->conf);
3423         wl_init_prof(wl->profile);
3424         wl_link_down(wl);
3425
3426         return err;
3427 }
3428
3429 static void wl_deinit_priv(struct wl_priv *wl)
3430 {
3431         wl_destroy_event_handler(wl);
3432         wl->dongle_up = false;  /* dongle down */
3433         wl_flush_eq(wl);
3434         wl_link_down(wl);
3435         wl_term_iscan(wl);
3436         wl_deinit_priv_mem(wl);
3437 }
3438
3439 s32 wl_cfg80211_attach(struct net_device *ndev, void *data)
3440 {
3441         struct wireless_dev *wdev;
3442         struct wl_priv *wl;
3443         struct wl_iface *ci;
3444         s32 err = 0;
3445
3446         if (unlikely(!ndev)) {
3447                 WL_ERR("ndev is invalid\n");
3448                 return -ENODEV;
3449         }
3450         wl_cfg80211_dev = kzalloc(sizeof(struct wl_dev), GFP_KERNEL);
3451         if (unlikely(!wl_cfg80211_dev)) {
3452                 WL_ERR("wl_cfg80211_dev is invalid\n");
3453                 return -ENOMEM;
3454         }
3455         WL_INFO("func %p\n", wl_cfg80211_get_sdio_func());
3456         wdev = wl_alloc_wdev(sizeof(struct wl_iface), &wl_cfg80211_get_sdio_func()->dev);
3457         if (IS_ERR(wdev))
3458                 return -ENOMEM;
3459
3460         wdev->iftype = wl_mode_to_nl80211_iftype(WL_MODE_BSS);
3461         wl = wdev_to_wl(wdev);
3462         wl->wdev = wdev;
3463         wl->pub = data;
3464         ci = (struct wl_iface *)wl_to_ci(wl);
3465         ci->wl = wl;
3466         ndev->ieee80211_ptr = wdev;
3467         SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
3468         wdev->netdev = ndev;
3469         err = wl_init_priv(wl);
3470         if (unlikely(err)) {
3471                 WL_ERR("Failed to init iwm_priv (%d)\n", err);
3472                 goto cfg80211_attach_out;
3473         }
3474         wl_set_drvdata(wl_cfg80211_dev, ci);
3475
3476         return err;
3477
3478 cfg80211_attach_out:
3479         wl_free_wdev(wl);
3480         return err;
3481 }
3482
3483 void wl_cfg80211_detach(void)
3484 {
3485         struct wl_priv *wl;
3486
3487         wl = WL_PRIV_GET();
3488
3489         wl_deinit_priv(wl);
3490         wl_free_wdev(wl);
3491         wl_set_drvdata(wl_cfg80211_dev, NULL);
3492         kfree(wl_cfg80211_dev);
3493         wl_cfg80211_dev = NULL;
3494         wl_clear_sdio_func();
3495 }
3496
3497 static void wl_wakeup_event(struct wl_priv *wl)
3498 {
3499         up(&wl->event_sync);
3500 }
3501
3502 static s32 wl_event_handler(void *data)
3503 {
3504         struct wl_priv *wl = (struct wl_priv *)data;
3505         struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1 };
3506         struct wl_event_q *e;
3507
3508         sched_setscheduler(current, SCHED_FIFO, &param);
3509         allow_signal(SIGTERM);
3510         while (likely(!down_interruptible(&wl->event_sync))) {
3511                 if (kthread_should_stop())
3512                         break;
3513                 e = wl_deq_event(wl);
3514                 if (unlikely(!e)) {
3515                         WL_ERR("event queue empty...\n");
3516                         BUG();
3517                 }
3518                 WL_INFO("event type (%d)\n", e->etype);
3519                 if (wl->el.handler[e->etype]) {
3520                         wl->el.handler[e->etype] (wl, wl_to_ndev(wl), &e->emsg,
3521                                                   e->edata);
3522                 } else {
3523                         WL_INFO("Unknown Event (%d): ignoring\n", e->etype);
3524                 }
3525                 wl_put_event(e);
3526         }
3527         WL_INFO("was terminated\n");
3528         return 0;
3529 }
3530
3531 void
3532 wl_cfg80211_event(struct net_device *ndev,
3533                   const brcmf_event_msg_t *e, void *data)
3534 {
3535         u32 event_type = be32_to_cpu(e->event_type);
3536         struct wl_priv *wl = ndev_to_wl(ndev);
3537
3538         if (likely(!wl_enq_event(wl, event_type, e, data)))
3539                 wl_wakeup_event(wl);
3540 }
3541
3542 static void wl_init_eq(struct wl_priv *wl)
3543 {
3544         wl_init_eq_lock(wl);
3545         INIT_LIST_HEAD(&wl->eq_list);
3546 }
3547
3548 static void wl_flush_eq(struct wl_priv *wl)
3549 {
3550         struct wl_event_q *e;
3551
3552         wl_lock_eq(wl);
3553         while (!list_empty(&wl->eq_list)) {
3554                 e = list_first_entry(&wl->eq_list, struct wl_event_q, eq_list);
3555                 list_del(&e->eq_list);
3556                 kfree(e);
3557         }
3558         wl_unlock_eq(wl);
3559 }
3560
3561 /*
3562 * retrieve first queued event from head
3563 */
3564
3565 static struct wl_event_q *wl_deq_event(struct wl_priv *wl)
3566 {
3567         struct wl_event_q *e = NULL;
3568
3569         wl_lock_eq(wl);
3570         if (likely(!list_empty(&wl->eq_list))) {
3571                 e = list_first_entry(&wl->eq_list, struct wl_event_q, eq_list);
3572                 list_del(&e->eq_list);
3573         }
3574         wl_unlock_eq(wl);
3575
3576         return e;
3577 }
3578
3579 /*
3580 ** push event to tail of the queue
3581 */
3582
3583 static s32
3584 wl_enq_event(struct wl_priv *wl, u32 event, const brcmf_event_msg_t *msg,
3585              void *data)
3586 {
3587         struct wl_event_q *e;
3588         s32 err = 0;
3589
3590         e = kzalloc(sizeof(struct wl_event_q), GFP_KERNEL);
3591         if (unlikely(!e)) {
3592                 WL_ERR("event alloc failed\n");
3593                 return -ENOMEM;
3594         }
3595
3596         e->etype = event;
3597         memcpy(&e->emsg, msg, sizeof(brcmf_event_msg_t));
3598         if (data) {
3599         }
3600         wl_lock_eq(wl);
3601         list_add_tail(&e->eq_list, &wl->eq_list);
3602         wl_unlock_eq(wl);
3603
3604         return err;
3605 }
3606
3607 static void wl_put_event(struct wl_event_q *e)
3608 {
3609         kfree(e);
3610 }
3611
3612 void wl_cfg80211_sdio_func(void *func)
3613 {
3614         cfg80211_sdio_func = (struct sdio_func *)func;
3615 }
3616
3617 static void wl_clear_sdio_func(void)
3618 {
3619         cfg80211_sdio_func = NULL;
3620 }
3621
3622 struct sdio_func *wl_cfg80211_get_sdio_func(void)
3623 {
3624         return cfg80211_sdio_func;
3625 }
3626
3627 static s32 wl_dongle_mode(struct net_device *ndev, s32 iftype)
3628 {
3629         s32 infra = 0;
3630         s32 err = 0;
3631
3632         switch (iftype) {
3633         case NL80211_IFTYPE_MONITOR:
3634         case NL80211_IFTYPE_WDS:
3635                 WL_ERR("type (%d) : currently we do not support this mode\n",
3636                        iftype);
3637                 err = -EINVAL;
3638                 return err;
3639         case NL80211_IFTYPE_ADHOC:
3640                 infra = 0;
3641                 break;
3642         case NL80211_IFTYPE_STATION:
3643                 infra = 1;
3644                 break;
3645         default:
3646                 err = -EINVAL;
3647                 WL_ERR("invalid type (%d)\n", iftype);
3648                 return err;
3649         }
3650         infra = cpu_to_le32(infra);
3651         err = wl_dev_ioctl(ndev, BRCMF_C_SET_INFRA, &infra, sizeof(infra));
3652         if (unlikely(err)) {
3653                 WL_ERR("WLC_SET_INFRA error (%d)\n", err);
3654                 return err;
3655         }
3656
3657         return 0;
3658 }
3659
3660 #ifndef EMBEDDED_PLATFORM
3661 static s32 wl_dongle_country(struct net_device *ndev, u8 ccode)
3662 {
3663
3664         s32 err = 0;
3665
3666         return err;
3667 }
3668
3669 static s32 wl_dongle_up(struct net_device *ndev, u32 up)
3670 {
3671         s32 err = 0;
3672
3673         err = wl_dev_ioctl(ndev, BRCMF_C_UP, &up, sizeof(up));
3674         if (unlikely(err)) {
3675                 WL_ERR("WLC_UP error (%d)\n", err);
3676         }
3677         return err;
3678 }
3679
3680 static s32 wl_dongle_power(struct net_device *ndev, u32 power_mode)
3681 {
3682         s32 err = 0;
3683
3684         err = wl_dev_ioctl(ndev, BRCMF_C_SET_PM,
3685                            &power_mode, sizeof(power_mode));
3686         if (unlikely(err)) {
3687                 WL_ERR("WLC_SET_PM error (%d)\n", err);
3688         }
3689         return err;
3690 }
3691
3692 static s32
3693 wl_dongle_glom(struct net_device *ndev, u32 glom, u32 dongle_align)
3694 {
3695         s8 iovbuf[WL_EVENTING_MASK_LEN + 12];   /*  Room for "event_msgs" +
3696                                                  '\0' + bitvec  */
3697         s32 err = 0;
3698
3699         /* Match Host and Dongle rx alignment */
3700         brcmu_mkiovar("bus:txglomalign", (char *)&dongle_align, 4, iovbuf,
3701                     sizeof(iovbuf));
3702         err = wl_dev_ioctl(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
3703         if (unlikely(err)) {
3704                 WL_ERR("txglomalign error (%d)\n", err);
3705                 goto dongle_glom_out;
3706         }
3707         /* disable glom option per default */
3708         brcmu_mkiovar("bus:txglom", (char *)&glom, 4, iovbuf, sizeof(iovbuf));
3709         err = wl_dev_ioctl(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
3710         if (unlikely(err)) {
3711                 WL_ERR("txglom error (%d)\n", err);
3712                 goto dongle_glom_out;
3713         }
3714 dongle_glom_out:
3715         return err;
3716 }
3717
3718 static s32
3719 wl_dongle_offload(struct net_device *ndev, s32 arpoe, s32 arp_ol)
3720 {
3721         s8 iovbuf[WL_EVENTING_MASK_LEN + 12];   /*  Room for "event_msgs" +
3722                                                          '\0' + bitvec  */
3723         s32 err = 0;
3724
3725         /* Set ARP offload */
3726         brcmu_mkiovar("arpoe", (char *)&arpoe, 4, iovbuf, sizeof(iovbuf));
3727         err = wl_dev_ioctl(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
3728         if (err) {
3729                 if (err == -EOPNOTSUPP)
3730                         WL_INFO("arpoe is not supported\n");
3731                 else
3732                         WL_ERR("arpoe error (%d)\n", err);
3733
3734                 goto dongle_offload_out;
3735         }
3736         brcmu_mkiovar("arp_ol", (char *)&arp_ol, 4, iovbuf, sizeof(iovbuf));
3737         err = wl_dev_ioctl(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
3738         if (err) {
3739                 if (err == -EOPNOTSUPP)
3740                         WL_INFO("arp_ol is not supported\n");
3741                 else
3742                         WL_ERR("arp_ol error (%d)\n", err);
3743
3744                 goto dongle_offload_out;
3745         }
3746
3747 dongle_offload_out:
3748         return err;
3749 }
3750
3751 static s32 wl_pattern_atoh(s8 *src, s8 *dst)
3752 {
3753         int i;
3754         if (strncmp(src, "0x", 2) != 0 && strncmp(src, "0X", 2) != 0) {
3755                 WL_ERR("Mask invalid format. Needs to start with 0x\n");
3756                 return -1;
3757         }
3758         src = src + 2;          /* Skip past 0x */
3759         if (strlen(src) % 2 != 0) {
3760                 WL_ERR("Mask invalid format. Needs to be of even length\n");
3761                 return -1;
3762         }
3763         for (i = 0; *src != '\0'; i++) {
3764                 char num[3];
3765                 strncpy(num, src, 2);
3766                 num[2] = '\0';
3767                 dst[i] = (u8) simple_strtoul(num, NULL, 16);
3768                 src += 2;
3769         }
3770         return i;
3771 }
3772
3773 static s32 wl_dongle_filter(struct net_device *ndev, u32 filter_mode)
3774 {
3775         s8 iovbuf[WL_EVENTING_MASK_LEN + 12];   /*  Room for "event_msgs" +
3776                                                          '\0' + bitvec  */
3777         const s8 *str;
3778         struct wl_pkt_filter pkt_filter;
3779         struct wl_pkt_filter *pkt_filterp;
3780         s32 buf_len;
3781         s32 str_len;
3782         u32 mask_size;
3783         u32 pattern_size;
3784         s8 buf[256];
3785         s32 err = 0;
3786
3787 /* add a default packet filter pattern */
3788         str = "pkt_filter_add";
3789         str_len = strlen(str);
3790         strncpy(buf, str, str_len);
3791         buf[str_len] = '\0';
3792         buf_len = str_len + 1;
3793
3794         pkt_filterp = (struct wl_pkt_filter *)(buf + str_len + 1);
3795
3796         /* Parse packet filter id. */
3797         pkt_filter.id = cpu_to_le32(100);
3798
3799         /* Parse filter polarity. */
3800         pkt_filter.negate_match = cpu_to_le32(0);
3801
3802         /* Parse filter type. */
3803         pkt_filter.type = cpu_to_le32(0);
3804
3805         /* Parse pattern filter offset. */
3806         pkt_filter.u.pattern.offset = cpu_to_le32(0);
3807
3808         /* Parse pattern filter mask. */
3809         mask_size = cpu_to_le32(wl_pattern_atoh("0xff",
3810                                                 (char *)pkt_filterp->u.pattern.
3811                                                 mask_and_pattern));
3812
3813         /* Parse pattern filter pattern. */
3814         pattern_size = cpu_to_le32(wl_pattern_atoh("0x00",
3815                                                    (char *)&pkt_filterp->u.
3816                                                    pattern.
3817                                                    mask_and_pattern
3818                                                    [mask_size]));
3819
3820         if (mask_size != pattern_size) {
3821                 WL_ERR("Mask and pattern not the same size\n");
3822                 err = -EINVAL;
3823                 goto dongle_filter_out;
3824         }
3825
3826         pkt_filter.u.pattern.size_bytes = mask_size;
3827         buf_len += WL_PKT_FILTER_FIXED_LEN;
3828         buf_len += (WL_PKT_FILTER_PATTERN_FIXED_LEN + 2 * mask_size);
3829
3830         /* Keep-alive attributes are set in local
3831          * variable (keep_alive_pkt), and
3832          * then memcpy'ed into buffer (keep_alive_pktp) since there is no
3833          * guarantee that the buffer is properly aligned.
3834          */
3835         memcpy((char *)pkt_filterp, &pkt_filter,
3836                WL_PKT_FILTER_FIXED_LEN + WL_PKT_FILTER_PATTERN_FIXED_LEN);
3837
3838         err = wl_dev_ioctl(ndev, BRCMF_C_SET_VAR, buf, buf_len);
3839         if (err) {
3840                 if (err == -EOPNOTSUPP) {
3841                         WL_INFO("filter not supported\n");
3842                 } else {
3843                         WL_ERR("filter (%d)\n", err);
3844                 }
3845                 goto dongle_filter_out;
3846         }
3847
3848         /* set mode to allow pattern */
3849         brcmu_mkiovar("pkt_filter_mode", (char *)&filter_mode, 4, iovbuf,
3850                     sizeof(iovbuf));
3851         err = wl_dev_ioctl(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
3852         if (err) {
3853                 if (err == -EOPNOTSUPP) {
3854                         WL_INFO("filter_mode not supported\n");
3855                 } else {
3856                         WL_ERR("filter_mode (%d)\n", err);
3857                 }
3858                 goto dongle_filter_out;
3859         }
3860
3861 dongle_filter_out:
3862         return err;
3863 }
3864 #endif                          /* !EMBEDDED_PLATFORM */
3865
3866 static s32 wl_dongle_eventmsg(struct net_device *ndev)
3867 {
3868         s8 iovbuf[WL_EVENTING_MASK_LEN + 12];   /*  Room for "event_msgs" +
3869                                                  '\0' + bitvec  */
3870         s8 eventmask[WL_EVENTING_MASK_LEN];
3871         s32 err = 0;
3872
3873         WL_TRACE("Enter\n");
3874
3875         /* Setup event_msgs */
3876         brcmu_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf,
3877                     sizeof(iovbuf));
3878         err = wl_dev_ioctl(ndev, BRCMF_C_GET_VAR, iovbuf, sizeof(iovbuf));
3879         if (unlikely(err)) {
3880                 WL_ERR("Get event_msgs error (%d)\n", err);
3881                 goto dongle_eventmsg_out;
3882         }
3883         memcpy(eventmask, iovbuf, WL_EVENTING_MASK_LEN);
3884
3885         setbit(eventmask, BRCMF_E_SET_SSID);
3886         setbit(eventmask, BRCMF_E_ROAM);
3887         setbit(eventmask, BRCMF_E_PRUNE);
3888         setbit(eventmask, BRCMF_E_AUTH);
3889         setbit(eventmask, BRCMF_E_REASSOC);
3890         setbit(eventmask, BRCMF_E_REASSOC_IND);
3891         setbit(eventmask, BRCMF_E_DEAUTH_IND);
3892         setbit(eventmask, BRCMF_E_DISASSOC_IND);
3893         setbit(eventmask, BRCMF_E_DISASSOC);
3894         setbit(eventmask, BRCMF_E_JOIN);
3895         setbit(eventmask, BRCMF_E_ASSOC_IND);
3896         setbit(eventmask, BRCMF_E_PSK_SUP);
3897         setbit(eventmask, BRCMF_E_LINK);
3898         setbit(eventmask, BRCMF_E_NDIS_LINK);
3899         setbit(eventmask, BRCMF_E_MIC_ERROR);
3900         setbit(eventmask, BRCMF_E_PMKID_CACHE);
3901         setbit(eventmask, BRCMF_E_TXFAIL);
3902         setbit(eventmask, BRCMF_E_JOIN_START);
3903         setbit(eventmask, BRCMF_E_SCAN_COMPLETE);
3904
3905         brcmu_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf,
3906                     sizeof(iovbuf));
3907         err = wl_dev_ioctl(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
3908         if (unlikely(err)) {
3909                 WL_ERR("Set event_msgs error (%d)\n", err);
3910                 goto dongle_eventmsg_out;
3911         }
3912
3913 dongle_eventmsg_out:
3914         WL_TRACE("Exit\n");
3915         return err;
3916 }
3917
3918 static s32
3919 wl_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
3920 {
3921         s8 iovbuf[32];
3922         s32 roamtrigger[2];
3923         s32 roam_delta[2];
3924         s32 err = 0;
3925
3926         /*
3927          * Setup timeout if Beacons are lost and roam is
3928          * off to report link down
3929          */
3930         if (roamvar) {
3931                 brcmu_mkiovar("bcn_timeout", (char *)&bcn_timeout,
3932                         sizeof(bcn_timeout), iovbuf, sizeof(iovbuf));
3933                 err = wl_dev_ioctl(ndev, BRCMF_C_SET_VAR,
3934                                    iovbuf, sizeof(iovbuf));
3935                 if (unlikely(err)) {
3936                         WL_ERR("bcn_timeout error (%d)\n", err);
3937                         goto dongle_rom_out;
3938                 }
3939         }
3940
3941         /*
3942          * Enable/Disable built-in roaming to allow supplicant
3943          * to take care of roaming
3944          */
3945         WL_INFO("Internal Roaming = %s\n", roamvar ? "Off" : "On");
3946         brcmu_mkiovar("roam_off", (char *)&roamvar,
3947                                 sizeof(roamvar), iovbuf, sizeof(iovbuf));
3948         err = wl_dev_ioctl(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
3949         if (unlikely(err)) {
3950                 WL_ERR("roam_off error (%d)\n", err);
3951                 goto dongle_rom_out;
3952         }
3953
3954         roamtrigger[0] = WL_ROAM_TRIGGER_LEVEL;
3955         roamtrigger[1] = WLC_BAND_ALL;
3956         err = wl_dev_ioctl(ndev, BRCMF_C_SET_ROAM_TRIGGER,
3957                         (void *)roamtrigger, sizeof(roamtrigger));
3958         if (unlikely(err)) {
3959                 WL_ERR("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
3960                 goto dongle_rom_out;
3961         }
3962
3963         roam_delta[0] = WL_ROAM_DELTA;
3964         roam_delta[1] = WLC_BAND_ALL;
3965         err = wl_dev_ioctl(ndev, BRCMF_C_SET_ROAM_DELTA,
3966                                 (void *)roam_delta, sizeof(roam_delta));
3967         if (unlikely(err)) {
3968                 WL_ERR("WLC_SET_ROAM_DELTA error (%d)\n", err);
3969                 goto dongle_rom_out;
3970         }
3971
3972 dongle_rom_out:
3973         return err;
3974 }
3975
3976 static s32
3977 wl_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
3978                 s32 scan_unassoc_time, s32 scan_passive_time)
3979 {
3980         s32 err = 0;
3981
3982         err = wl_dev_ioctl(ndev, BRCMF_C_SET_SCAN_CHANNEL_TIME,
3983                            &scan_assoc_time, sizeof(scan_assoc_time));
3984         if (err) {
3985                 if (err == -EOPNOTSUPP)
3986                         WL_INFO("Scan assoc time is not supported\n");
3987                 else
3988                         WL_ERR("Scan assoc time error (%d)\n", err);
3989                 goto dongle_scantime_out;
3990         }
3991         err = wl_dev_ioctl(ndev, BRCMF_C_SET_SCAN_UNASSOC_TIME,
3992                            &scan_unassoc_time, sizeof(scan_unassoc_time));
3993         if (err) {
3994                 if (err == -EOPNOTSUPP)
3995                         WL_INFO("Scan unassoc time is not supported\n");
3996                 else
3997                         WL_ERR("Scan unassoc time error (%d)\n", err);
3998                 goto dongle_scantime_out;
3999         }
4000
4001         err = wl_dev_ioctl(ndev, BRCMF_C_SET_SCAN_PASSIVE_TIME,
4002                            &scan_passive_time, sizeof(scan_passive_time));
4003         if (err) {
4004                 if (err == -EOPNOTSUPP)
4005                         WL_INFO("Scan passive time is not supported\n");
4006                 else
4007                         WL_ERR("Scan passive time error (%d)\n", err);
4008                 goto dongle_scantime_out;
4009         }
4010
4011 dongle_scantime_out:
4012         return err;
4013 }
4014
4015 s32 wl_config_dongle(struct wl_priv *wl, bool need_lock)
4016 {
4017         struct net_device *ndev;
4018         struct wireless_dev *wdev;
4019         s32 err = 0;
4020
4021         if (wl->dongle_up)
4022                 return err;
4023
4024         ndev = wl_to_ndev(wl);
4025         wdev = ndev->ieee80211_ptr;
4026         if (need_lock)
4027                 rtnl_lock();
4028
4029 #ifndef EMBEDDED_PLATFORM
4030         err = wl_dongle_up(ndev, 0);
4031         if (unlikely(err))
4032                 goto default_conf_out;
4033         err = wl_dongle_country(ndev, 0);
4034         if (unlikely(err))
4035                 goto default_conf_out;
4036         err = wl_dongle_power(ndev, PM_FAST);
4037         if (unlikely(err))
4038                 goto default_conf_out;
4039         err = wl_dongle_glom(ndev, 0, BRCMF_SDALIGN);
4040         if (unlikely(err))
4041                 goto default_conf_out;
4042
4043         wl_dongle_offload(ndev, 1, 0xf);
4044         wl_dongle_filter(ndev, 1);
4045 #endif /* !EMBEDDED_PLATFORM */
4046
4047         wl_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME,
4048                         WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
4049
4050         err = wl_dongle_eventmsg(ndev);
4051         if (unlikely(err))
4052                 goto default_conf_out;
4053         err = wl_dongle_roam(ndev, (wl->roam_on ? 0 : 1), WL_BEACON_TIMEOUT);
4054         if (unlikely(err))
4055                 goto default_conf_out;
4056         err = wl_dongle_mode(ndev, wdev->iftype);
4057         if (unlikely(err && err != -EINPROGRESS))
4058                 goto default_conf_out;
4059         err = wl_dongle_probecap(wl);
4060         if (unlikely(err))
4061                 goto default_conf_out;
4062
4063         /* -EINPROGRESS: Call commit handler */
4064
4065 default_conf_out:
4066         if (need_lock)
4067                 rtnl_unlock();
4068
4069         wl->dongle_up = true;
4070
4071         return err;
4072
4073 }
4074
4075 static s32 wl_update_wiphybands(struct wl_priv *wl)
4076 {
4077         struct wiphy *wiphy;
4078         s32 phy_list;
4079         s8 phy;
4080         s32 err = 0;
4081
4082         err = wl_dev_ioctl(wl_to_ndev(wl), WLC_GET_PHYLIST, &phy_list,
4083                         sizeof(phy_list));
4084         if (unlikely(err)) {
4085                 WL_ERR("error (%d)\n", err);
4086                 return err;
4087         }
4088
4089         phy = ((char *)&phy_list)[1];
4090         WL_INFO("%c phy\n", phy);
4091         if (phy == 'n' || phy == 'a') {
4092                 wiphy = wl_to_wiphy(wl);
4093                 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
4094         }
4095
4096         return err;
4097 }
4098
4099 static s32 __wl_cfg80211_up(struct wl_priv *wl)
4100 {
4101         s32 err = 0;
4102
4103         set_bit(WL_STATUS_READY, &wl->status);
4104
4105         wl_debugfs_add_netdev_params(wl);
4106
4107         err = wl_config_dongle(wl, false);
4108         if (unlikely(err))
4109                 return err;
4110
4111         wl_invoke_iscan(wl);
4112
4113         return err;
4114 }
4115
4116 static s32 __wl_cfg80211_down(struct wl_priv *wl)
4117 {
4118         /*
4119          * While going down, if associated with AP disassociate
4120          * from AP to save power
4121          */
4122         if ((test_bit(WL_STATUS_CONNECTED, &wl->status) ||
4123              test_bit(WL_STATUS_CONNECTING, &wl->status)) &&
4124              test_bit(WL_STATUS_READY, &wl->status)) {
4125                 WL_INFO("Disassociating from AP");
4126                 wl_link_down(wl);
4127
4128                 /* Make sure WPA_Supplicant receives all the event
4129                    generated due to DISASSOC call to the fw to keep
4130                    the state fw and WPA_Supplicant state consistent
4131                  */
4132                 rtnl_unlock();
4133                 wl_delay(500);
4134                 rtnl_lock();
4135         }
4136
4137         set_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
4138         wl_term_iscan(wl);
4139         if (wl->scan_request) {
4140                 cfg80211_scan_done(wl->scan_request, true);
4141                 /* May need to perform this to cover rmmod */
4142                 /* wl_set_mpc(wl_to_ndev(wl), 1); */
4143                 wl->scan_request = NULL;
4144         }
4145         clear_bit(WL_STATUS_READY, &wl->status);
4146         clear_bit(WL_STATUS_SCANNING, &wl->status);
4147         clear_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
4148
4149         wl_debugfs_remove_netdev(wl);
4150
4151         return 0;
4152 }
4153
4154 s32 wl_cfg80211_up(void)
4155 {
4156         struct wl_priv *wl;
4157         s32 err = 0;
4158
4159         wl = WL_PRIV_GET();
4160         mutex_lock(&wl->usr_sync);
4161         err = __wl_cfg80211_up(wl);
4162         mutex_unlock(&wl->usr_sync);
4163
4164         return err;
4165 }
4166
4167 s32 wl_cfg80211_down(void)
4168 {
4169         struct wl_priv *wl;
4170         s32 err = 0;
4171
4172         wl = WL_PRIV_GET();
4173         mutex_lock(&wl->usr_sync);
4174         err = __wl_cfg80211_down(wl);
4175         mutex_unlock(&wl->usr_sync);
4176
4177         return err;
4178 }
4179
4180 static s32 wl_dongle_probecap(struct wl_priv *wl)
4181 {
4182         return wl_update_wiphybands(wl);
4183 }
4184
4185 static void *wl_read_prof(struct wl_priv *wl, s32 item)
4186 {
4187         switch (item) {
4188         case WL_PROF_SEC:
4189                 return &wl->profile->sec;
4190         case WL_PROF_BSSID:
4191                 return &wl->profile->bssid;
4192         case WL_PROF_SSID:
4193                 return &wl->profile->ssid;
4194         }
4195         WL_ERR("invalid item (%d)\n", item);
4196         return NULL;
4197 }
4198
4199 static s32
4200 wl_update_prof(struct wl_priv *wl, const brcmf_event_msg_t *e, void *data,
4201                s32 item)
4202 {
4203         s32 err = 0;
4204         struct wlc_ssid *ssid;
4205
4206         switch (item) {
4207         case WL_PROF_SSID:
4208                 ssid = (wlc_ssid_t *) data;
4209                 memset(wl->profile->ssid.SSID, 0,
4210                        sizeof(wl->profile->ssid.SSID));
4211                 memcpy(wl->profile->ssid.SSID, ssid->SSID, ssid->SSID_len);
4212                 wl->profile->ssid.SSID_len = ssid->SSID_len;
4213                 break;
4214         case WL_PROF_BSSID:
4215                 if (data)
4216                         memcpy(wl->profile->bssid, data, ETH_ALEN);
4217                 else
4218                         memset(wl->profile->bssid, 0, ETH_ALEN);
4219                 break;
4220         case WL_PROF_SEC:
4221                 memcpy(&wl->profile->sec, data, sizeof(wl->profile->sec));
4222                 break;
4223         case WL_PROF_BEACONINT:
4224                 wl->profile->beacon_interval = *(u16 *)data;
4225                 break;
4226         case WL_PROF_DTIMPERIOD:
4227                 wl->profile->dtim_period = *(u8 *)data;
4228                 break;
4229         default:
4230                 WL_ERR("unsupported item (%d)\n", item);
4231                 err = -EOPNOTSUPP;
4232                 break;
4233         }
4234
4235         return err;
4236 }
4237
4238 static bool wl_is_ibssmode(struct wl_priv *wl)
4239 {
4240         return wl->conf->mode == WL_MODE_IBSS;
4241 }
4242
4243 static __used s32 wl_add_ie(struct wl_priv *wl, u8 t, u8 l, u8 *v)
4244 {
4245         struct wl_ie *ie = wl_to_ie(wl);
4246         s32 err = 0;
4247
4248         if (unlikely(ie->offset + l + 2 > WL_TLV_INFO_MAX)) {
4249                 WL_ERR("ei crosses buffer boundary\n");
4250                 return -ENOSPC;
4251         }
4252         ie->buf[ie->offset] = t;
4253         ie->buf[ie->offset + 1] = l;
4254         memcpy(&ie->buf[ie->offset + 2], v, l);
4255         ie->offset += l + 2;
4256
4257         return err;
4258 }
4259
4260 static void wl_link_down(struct wl_priv *wl)
4261 {
4262         struct net_device *dev = NULL;
4263         s32 err = 0;
4264
4265         WL_TRACE("Enter\n");
4266
4267         if (wl->link_up) {
4268                 dev = wl_to_ndev(wl);
4269                 WL_INFO("Call WLC_DISASSOC to stop excess roaming\n ");
4270                 err = wl_dev_ioctl(dev, BRCMF_C_DISASSOC, NULL, 0);
4271                 if (unlikely(err))
4272                         WL_ERR("WLC_DISASSOC failed (%d)\n", err);
4273                 wl->link_up = false;
4274         }
4275         WL_TRACE("Exit\n");
4276 }
4277
4278 static void wl_lock_eq(struct wl_priv *wl)
4279 {
4280         spin_lock_irq(&wl->eq_lock);
4281 }
4282
4283 static void wl_unlock_eq(struct wl_priv *wl)
4284 {
4285         spin_unlock_irq(&wl->eq_lock);
4286 }
4287
4288 static void wl_init_eq_lock(struct wl_priv *wl)
4289 {
4290         spin_lock_init(&wl->eq_lock);
4291 }
4292
4293 static void wl_delay(u32 ms)
4294 {
4295         if (ms < 1000 / HZ) {
4296                 cond_resched();
4297                 mdelay(ms);
4298         } else {
4299                 msleep(ms);
4300         }
4301 }
4302
4303 static void wl_set_drvdata(struct wl_dev *dev, void *data)
4304 {
4305         dev->driver_data = data;
4306 }
4307
4308 static void *wl_get_drvdata(struct wl_dev *dev)
4309 {
4310         void *data = NULL;
4311
4312         if (dev)
4313                 data = dev->driver_data;
4314         return data;
4315 }
4316
4317 s32 wl_cfg80211_read_fw(s8 *buf, u32 size)
4318 {
4319         const struct firmware *fw_entry;
4320         struct wl_priv *wl;
4321
4322         wl = WL_PRIV_GET();
4323
4324         fw_entry = wl->fw->fw_entry;
4325
4326         if (fw_entry->size < wl->fw->ptr + size)
4327                 size = fw_entry->size - wl->fw->ptr;
4328
4329         memcpy(buf, &fw_entry->data[wl->fw->ptr], size);
4330         wl->fw->ptr += size;
4331         return size;
4332 }
4333
4334 void wl_cfg80211_release_fw(void)
4335 {
4336         struct wl_priv *wl;
4337
4338         wl = WL_PRIV_GET();
4339         release_firmware(wl->fw->fw_entry);
4340         wl->fw->ptr = 0;
4341 }
4342
4343 void *wl_cfg80211_request_fw(s8 *file_name)
4344 {
4345         struct wl_priv *wl;
4346         const struct firmware *fw_entry = NULL;
4347         s32 err = 0;
4348
4349         WL_INFO("file name : \"%s\"\n", file_name);
4350         wl = WL_PRIV_GET();
4351
4352         if (!test_bit(WL_FW_LOADING_DONE, &wl->fw->status)) {
4353                 err = request_firmware(&wl->fw->fw_entry, file_name,
4354                                 &wl_cfg80211_get_sdio_func()->dev);
4355                 if (unlikely(err)) {
4356                         WL_ERR("Could not download fw (%d)\n", err);
4357                         goto req_fw_out;
4358                 }
4359                 set_bit(WL_FW_LOADING_DONE, &wl->fw->status);
4360                 fw_entry = wl->fw->fw_entry;
4361                 if (fw_entry) {
4362                         WL_INFO("fw size (%zd), data (%p)\n",
4363                                fw_entry->size, fw_entry->data);
4364                 }
4365         } else if (!test_bit(WL_NVRAM_LOADING_DONE, &wl->fw->status)) {
4366                 err = request_firmware(&wl->fw->fw_entry, file_name,
4367                                 &wl_cfg80211_get_sdio_func()->dev);
4368                 if (unlikely(err)) {
4369                         WL_ERR("Could not download nvram (%d)\n", err);
4370                         goto req_fw_out;
4371                 }
4372                 set_bit(WL_NVRAM_LOADING_DONE, &wl->fw->status);
4373                 fw_entry = wl->fw->fw_entry;
4374                 if (fw_entry) {
4375                         WL_INFO("nvram size (%zd), data (%p)\n",
4376                                fw_entry->size, fw_entry->data);
4377                 }
4378         } else {
4379                 WL_INFO("Downloading already done. Nothing to do more\n");
4380                 err = -EPERM;
4381         }
4382
4383 req_fw_out:
4384         if (unlikely(err)) {
4385                 return NULL;
4386         }
4387         wl->fw->ptr = 0;
4388         return (void *)fw_entry->data;
4389 }
4390
4391 s8 *wl_cfg80211_get_fwname(void)
4392 {
4393         struct wl_priv *wl;
4394
4395         wl = WL_PRIV_GET();
4396         strcpy(wl->fw->fw_name, WL_4329_FW_FILE);
4397         return wl->fw->fw_name;
4398 }
4399
4400 s8 *wl_cfg80211_get_nvramname(void)
4401 {
4402         struct wl_priv *wl;
4403
4404         wl = WL_PRIV_GET();
4405         strcpy(wl->fw->nvram_name, WL_4329_NVRAM_FILE);
4406         return wl->fw->nvram_name;
4407 }
4408
4409 static void wl_set_mpc(struct net_device *ndev, int mpc)
4410 {
4411         s32 err = 0;
4412         struct wl_priv *wl = ndev_to_wl(ndev);
4413
4414         if (test_bit(WL_STATUS_READY, &wl->status)) {
4415                 err = wl_dev_intvar_set(ndev, "mpc", mpc);
4416                 if (unlikely(err)) {
4417                         WL_ERR("fail to set mpc\n");
4418                         return;
4419                 }
4420                 WL_INFO("MPC : %d\n", mpc);
4421         }
4422 }
4423
4424 static int wl_debugfs_add_netdev_params(struct wl_priv *wl)
4425 {
4426         char buf[10+IFNAMSIZ];
4427         struct dentry *fd;
4428         s32 err = 0;
4429
4430         sprintf(buf, "netdev:%s", wl_to_ndev(wl)->name);
4431         wl->debugfsdir = debugfs_create_dir(buf, wl_to_wiphy(wl)->debugfsdir);
4432
4433         fd = debugfs_create_u16("beacon_int", S_IRUGO, wl->debugfsdir,
4434                 (u16 *)&wl->profile->beacon_interval);
4435         if (!fd) {
4436                 err = -ENOMEM;
4437                 goto err_out;
4438         }
4439
4440         fd = debugfs_create_u8("dtim_period", S_IRUGO, wl->debugfsdir,
4441                 (u8 *)&wl->profile->dtim_period);
4442         if (!fd) {
4443                 err = -ENOMEM;
4444                 goto err_out;
4445         }
4446
4447 err_out:
4448         return err;
4449 }
4450
4451 static void wl_debugfs_remove_netdev(struct wl_priv *wl)
4452 {
4453         debugfs_remove_recursive(wl->debugfsdir);
4454         wl->debugfsdir = NULL;
4455 }