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