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