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