Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc
[pandora-kernel.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
20 #include <bcmutils.h>
21
22 #include <asm/uaccess.h>
23
24 #include <dngl_stats.h>
25 #include <dhd.h>
26 #include <dhdioctl.h>
27 #include <wlioctl.h>
28
29 #include <linux/kthread.h>
30 #include <linux/netdevice.h>
31 #include <linux/sched.h>
32 #include <linux/etherdevice.h>
33 #include <linux/wireless.h>
34 #include <linux/ieee80211.h>
35 #include <net/cfg80211.h>
36
37 #include <net/rtnetlink.h>
38 #include <linux/mmc/sdio_func.h>
39 #include <linux/firmware.h>
40 #include <wl_cfg80211.h>
41
42 void sdioh_sdio_set_host_pm_flags(int flag);
43
44 static struct sdio_func *cfg80211_sdio_func;
45 static struct wl_dev *wl_cfg80211_dev;
46 static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255};
47
48 u32 wl_dbg_level = WL_DBG_ERR;
49
50 #define WL_4329_FW_FILE "brcm/bcm4329-fullmac-4.bin"
51 #define WL_4329_NVRAM_FILE "brcm/bcm4329-fullmac-4.txt"
52
53 /*
54 ** cfg80211_ops api/callback list
55 */
56 static s32 wl_cfg80211_change_iface(struct wiphy *wiphy,
57                                       struct net_device *ndev,
58                                       enum nl80211_iftype type, u32 *flags,
59                                       struct vif_params *params);
60 static s32 __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
61                                 struct cfg80211_scan_request *request,
62                                 struct cfg80211_ssid *this_ssid);
63 static s32 wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
64                               struct cfg80211_scan_request *request);
65 static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed);
66 static s32 wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
67                                    struct cfg80211_ibss_params *params);
68 static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy,
69                                     struct net_device *dev);
70 static s32 wl_cfg80211_get_station(struct wiphy *wiphy,
71                                      struct net_device *dev, u8 *mac,
72                                      struct station_info *sinfo);
73 static s32 wl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
74                                         struct net_device *dev, bool enabled,
75                                         s32 timeout);
76 static s32 wl_cfg80211_set_bitrate_mask(struct wiphy *wiphy,
77                                           struct net_device *dev,
78                                           const u8 *addr,
79                                           const struct cfg80211_bitrate_mask
80                                           *mask);
81 static int wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
82                                struct cfg80211_connect_params *sme);
83 static s32 wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
84                                     u16 reason_code);
85 static s32 wl_cfg80211_set_tx_power(struct wiphy *wiphy,
86                                       enum nl80211_tx_power_setting type,
87                                       s32 dbm);
88 static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm);
89 static s32 wl_cfg80211_config_default_key(struct wiphy *wiphy,
90                                           struct net_device *dev, u8 key_idx,
91                                           bool unicast, bool multicast);
92 static s32 wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
93                                  u8 key_idx, bool pairwise, const u8 *mac_addr,
94                                  struct key_params *params);
95 static s32 wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
96                                  u8 key_idx, bool pairwise, const u8 *mac_addr);
97 static s32 wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
98                                  u8 key_idx, bool pairwise, const u8 *mac_addr,
99                                  void *cookie, void (*callback) (void *cookie,
100                                                                  struct
101                                                                  key_params *
102                                                                  params));
103 static s32 wl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
104                                                  struct net_device *dev,
105                                                  u8 key_idx);
106 static s32 wl_cfg80211_resume(struct wiphy *wiphy);
107 static s32 wl_cfg80211_suspend(struct wiphy *wiphy);
108 static s32 wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
109                                    struct cfg80211_pmksa *pmksa);
110 static s32 wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
111                                    struct cfg80211_pmksa *pmksa);
112 static s32 wl_cfg80211_flush_pmksa(struct wiphy *wiphy,
113                                      struct net_device *dev);
114 /*
115 ** event & event Q handlers for cfg80211 interfaces
116 */
117 static s32 wl_create_event_handler(struct wl_priv *wl);
118 static void wl_destroy_event_handler(struct wl_priv *wl);
119 static s32 wl_event_handler(void *data);
120 static void wl_init_eq(struct wl_priv *wl);
121 static void wl_flush_eq(struct wl_priv *wl);
122 static void wl_lock_eq(struct wl_priv *wl);
123 static void wl_unlock_eq(struct wl_priv *wl);
124 static void wl_init_eq_lock(struct wl_priv *wl);
125 static void wl_init_eloop_handler(struct wl_event_loop *el);
126 static struct wl_event_q *wl_deq_event(struct wl_priv *wl);
127 static s32 wl_enq_event(struct wl_priv *wl, u32 type,
128                           const wl_event_msg_t *msg, void *data);
129 static void wl_put_event(struct wl_event_q *e);
130 static void wl_wakeup_event(struct wl_priv *wl);
131 static s32 wl_notify_connect_status(struct wl_priv *wl,
132                                       struct net_device *ndev,
133                                       const wl_event_msg_t *e, void *data);
134 static s32 wl_notify_roaming_status(struct wl_priv *wl,
135                                       struct net_device *ndev,
136                                       const wl_event_msg_t *e, void *data);
137 static s32 wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev,
138                                    const wl_event_msg_t *e, void *data);
139 static s32 wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
140                                  const wl_event_msg_t *e, void *data,
141                                 bool completed);
142 static s32 wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev,
143                                  const wl_event_msg_t *e, void *data);
144 static s32 wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev,
145                                   const wl_event_msg_t *e, void *data);
146
147 /*
148 ** register/deregister sdio function
149 */
150 struct sdio_func *wl_cfg80211_get_sdio_func(void);
151 static void wl_clear_sdio_func(void);
152
153 /*
154 ** ioctl utilites
155 */
156 static s32 wl_dev_bufvar_get(struct net_device *dev, s8 *name, s8 *buf,
157                                s32 buf_len);
158 static __used s32 wl_dev_bufvar_set(struct net_device *dev, s8 *name,
159                                       s8 *buf, s32 len);
160 static s32 wl_dev_intvar_set(struct net_device *dev, s8 *name, s32 val);
161 static s32 wl_dev_intvar_get(struct net_device *dev, s8 *name,
162                                s32 *retval);
163 static s32 wl_dev_ioctl(struct net_device *dev, u32 cmd, void *arg,
164                           u32 len);
165
166 /*
167 ** cfg80211 set_wiphy_params utilities
168 */
169 static s32 wl_set_frag(struct net_device *dev, u32 frag_threshold);
170 static s32 wl_set_rts(struct net_device *dev, u32 frag_threshold);
171 static s32 wl_set_retry(struct net_device *dev, u32 retry, bool l);
172
173 /*
174 ** wl profile utilities
175 */
176 static s32 wl_update_prof(struct wl_priv *wl, const wl_event_msg_t *e,
177                             void *data, s32 item);
178 static void *wl_read_prof(struct wl_priv *wl, s32 item);
179 static void wl_init_prof(struct wl_profile *prof);
180
181 /*
182 ** cfg80211 connect utilites
183 */
184 static s32 wl_set_wpa_version(struct net_device *dev,
185                         struct cfg80211_connect_params *sme);
186 static s32 wl_set_auth_type(struct net_device *dev,
187                         struct cfg80211_connect_params *sme);
188 static s32 wl_set_set_cipher(struct net_device *dev,
189                         struct cfg80211_connect_params *sme);
190 static s32 wl_set_key_mgmt(struct net_device *dev,
191                         struct cfg80211_connect_params *sme);
192 static s32 wl_set_set_sharedkey(struct net_device *dev,
193                         struct cfg80211_connect_params *sme);
194 static s32 wl_get_assoc_ies(struct wl_priv *wl);
195 static void wl_clear_assoc_ies(struct wl_priv *wl);
196 static void wl_ch_to_chanspec(int ch,
197         struct wl_join_params *join_params, size_t *join_params_size);
198
199 /*
200 ** information element utilities
201 */
202 static __used s32 wl_add_ie(struct wl_priv *wl, u8 t, u8 l, u8 *v);
203 static s32 wl_mode_to_nl80211_iftype(s32 mode);
204 static struct wireless_dev *wl_alloc_wdev(s32 sizeof_iface,
205                         struct device *dev);
206 static void wl_free_wdev(struct wl_priv *wl);
207 static s32 wl_inform_bss(struct wl_priv *wl);
208 static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi);
209 static s32 wl_update_bss_info(struct wl_priv *wl);
210 static s32 wl_add_keyext(struct wiphy *wiphy, struct net_device *dev,
211                         u8 key_idx, const u8 *mac_addr,
212                         struct key_params *params);
213
214 /*
215 ** key indianess swap utilities
216 */
217 static void swap_key_from_BE(struct wl_wsec_key *key);
218 static void swap_key_to_BE(struct wl_wsec_key *key);
219
220 /*
221 ** wl_priv memory init/deinit utilities
222 */
223 static s32 wl_init_priv_mem(struct wl_priv *wl);
224 static void wl_deinit_priv_mem(struct wl_priv *wl);
225
226 static void wl_delay(u32 ms);
227
228 /*
229 ** store/restore cfg80211 instance data
230 */
231 static void wl_set_drvdata(struct wl_dev *dev, void *data);
232 static void *wl_get_drvdata(struct wl_dev *dev);
233
234 /*
235 ** ibss mode utilities
236 */
237 static bool wl_is_ibssmode(struct wl_priv *wl);
238
239 /*
240 ** dongle up/down , default configuration utilities
241 */
242 static bool wl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e);
243 static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e);
244 static bool wl_is_nonetwork(struct wl_priv *wl, const wl_event_msg_t *e);
245 static void wl_link_down(struct wl_priv *wl);
246 static s32 wl_dongle_mode(struct net_device *ndev, s32 iftype);
247 static s32 __wl_cfg80211_up(struct wl_priv *wl);
248 static s32 __wl_cfg80211_down(struct wl_priv *wl);
249 static s32 wl_dongle_probecap(struct wl_priv *wl);
250 static void wl_init_conf(struct wl_conf *conf);
251
252 /*
253 ** dongle configuration utilities
254 */
255 #ifndef EMBEDDED_PLATFORM
256 static s32 wl_dongle_mode(struct net_device *ndev, s32 iftype);
257 static s32 wl_dongle_country(struct net_device *ndev, u8 ccode);
258 static s32 wl_dongle_up(struct net_device *ndev, u32 up);
259 static s32 wl_dongle_power(struct net_device *ndev, u32 power_mode);
260 static s32 wl_dongle_glom(struct net_device *ndev, u32 glom,
261                             u32 dongle_align);
262 static s32 wl_dongle_offload(struct net_device *ndev, s32 arpoe,
263                                s32 arp_ol);
264 static s32 wl_pattern_atoh(s8 *src, s8 *dst);
265 static s32 wl_dongle_filter(struct net_device *ndev, u32 filter_mode);
266 static s32 wl_update_wiphybands(struct wl_priv *wl);
267 #endif                          /* !EMBEDDED_PLATFORM */
268
269 static s32 wl_dongle_eventmsg(struct net_device *ndev);
270 static s32 wl_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
271                                 s32 scan_unassoc_time, s32 scan_passive_time);
272 static s32 wl_config_dongle(struct wl_priv *wl, bool need_lock);
273 static s32 wl_dongle_roam(struct net_device *ndev, u32 roamvar,
274                             u32 bcn_timeout);
275
276 /*
277 ** iscan handler
278 */
279 static void wl_iscan_timer(unsigned long data);
280 static void wl_term_iscan(struct wl_priv *wl);
281 static s32 wl_init_iscan(struct wl_priv *wl);
282 static s32 wl_iscan_thread(void *data);
283 static s32 wl_dev_iovar_setbuf(struct net_device *dev, s8 *iovar,
284                                  void *param, s32 paramlen, void *bufptr,
285                                  s32 buflen);
286 static s32 wl_dev_iovar_getbuf(struct net_device *dev, s8 *iovar,
287                                  void *param, s32 paramlen, void *bufptr,
288                                  s32 buflen);
289 static s32 wl_run_iscan(struct wl_iscan_ctrl *iscan, struct wlc_ssid *ssid,
290                           u16 action);
291 static s32 wl_do_iscan(struct wl_priv *wl);
292 static s32 wl_wakeup_iscan(struct wl_iscan_ctrl *iscan);
293 static s32 wl_invoke_iscan(struct wl_priv *wl);
294 static s32 wl_get_iscan_results(struct wl_iscan_ctrl *iscan, u32 *status,
295                                   struct wl_scan_results **bss_list);
296 static void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted);
297 static void wl_init_iscan_eloop(struct wl_iscan_eloop *el);
298 static s32 wl_iscan_done(struct wl_priv *wl);
299 static s32 wl_iscan_pending(struct wl_priv *wl);
300 static s32 wl_iscan_inprogress(struct wl_priv *wl);
301 static s32 wl_iscan_aborted(struct wl_priv *wl);
302
303 /*
304 ** fw/nvram downloading handler
305 */
306 static void wl_init_fw(struct wl_fw_ctrl *fw);
307
308 /*
309 * find most significant bit set
310 */
311 static __used u32 wl_find_msb(u16 bit16);
312
313 /*
314 * update pmklist to dongle
315 */
316 static __used s32 wl_update_pmklist(struct net_device *dev,
317                                       struct wl_pmk_list *pmk_list, s32 err);
318
319 static void wl_set_mpc(struct net_device *ndev, int mpc);
320
321 /*
322 * debufs support
323 */
324 static int wl_debugfs_add_netdev_params(struct wl_priv *wl);
325 static void wl_debugfs_remove_netdev(struct wl_priv *wl);
326
327 #define WL_PRIV_GET()                                                   \
328         ({                                                              \
329         struct wl_iface *ci;                                            \
330         if (unlikely(!(wl_cfg80211_dev &&                               \
331                 (ci = wl_get_drvdata(wl_cfg80211_dev))))) {             \
332                 WL_ERR("wl_cfg80211_dev is unavailable\n");             \
333                 BUG();                                                  \
334         }                                                               \
335         ci_to_wl(ci);                                                   \
336 })
337
338 #define CHECK_SYS_UP()                                                  \
339 do {                                                                    \
340         struct wl_priv *wl = wiphy_to_wl(wiphy);                        \
341         if (unlikely(!test_bit(WL_STATUS_READY, &wl->status))) {        \
342                 WL_INFO("device is not ready : status (%d)\n",          \
343                         (int)wl->status);                               \
344                 return -EIO;                                            \
345         }                                                               \
346 } while (0)
347
348 extern int dhd_wait_pend8021x(struct net_device *dev);
349 #define CHAN2G(_channel, _freq, _flags) {                       \
350         .band                   = IEEE80211_BAND_2GHZ,          \
351         .center_freq            = (_freq),                      \
352         .hw_value               = (_channel),                   \
353         .flags                  = (_flags),                     \
354         .max_antenna_gain       = 0,                            \
355         .max_power              = 30,                           \
356 }
357
358 #define CHAN5G(_channel, _flags) {                              \
359         .band                   = IEEE80211_BAND_5GHZ,          \
360         .center_freq            = 5000 + (5 * (_channel)),      \
361         .hw_value               = (_channel),                   \
362         .flags                  = (_flags),                     \
363         .max_antenna_gain       = 0,                            \
364         .max_power              = 30,                           \
365 }
366
367 #define RATE_TO_BASE100KBPS(rate)   (((rate) * 10) / 2)
368 #define RATETAB_ENT(_rateid, _flags) \
369         {                                                               \
370                 .bitrate        = RATE_TO_BASE100KBPS(_rateid),     \
371                 .hw_value       = (_rateid),                            \
372                 .flags          = (_flags),                             \
373         }
374
375 static struct ieee80211_rate __wl_rates[] = {
376         RATETAB_ENT(WLC_RATE_1M, 0),
377         RATETAB_ENT(WLC_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
378         RATETAB_ENT(WLC_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
379         RATETAB_ENT(WLC_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
380         RATETAB_ENT(WLC_RATE_6M, 0),
381         RATETAB_ENT(WLC_RATE_9M, 0),
382         RATETAB_ENT(WLC_RATE_12M, 0),
383         RATETAB_ENT(WLC_RATE_18M, 0),
384         RATETAB_ENT(WLC_RATE_24M, 0),
385         RATETAB_ENT(WLC_RATE_36M, 0),
386         RATETAB_ENT(WLC_RATE_48M, 0),
387         RATETAB_ENT(WLC_RATE_54M, 0),
388 };
389
390 #define wl_a_rates              (__wl_rates + 4)
391 #define wl_a_rates_size 8
392 #define wl_g_rates              (__wl_rates + 0)
393 #define wl_g_rates_size 12
394
395 static struct ieee80211_channel __wl_2ghz_channels[] = {
396         CHAN2G(1, 2412, 0),
397         CHAN2G(2, 2417, 0),
398         CHAN2G(3, 2422, 0),
399         CHAN2G(4, 2427, 0),
400         CHAN2G(5, 2432, 0),
401         CHAN2G(6, 2437, 0),
402         CHAN2G(7, 2442, 0),
403         CHAN2G(8, 2447, 0),
404         CHAN2G(9, 2452, 0),
405         CHAN2G(10, 2457, 0),
406         CHAN2G(11, 2462, 0),
407         CHAN2G(12, 2467, 0),
408         CHAN2G(13, 2472, 0),
409         CHAN2G(14, 2484, 0),
410 };
411
412 static struct ieee80211_channel __wl_5ghz_a_channels[] = {
413         CHAN5G(34, 0), CHAN5G(36, 0),
414         CHAN5G(38, 0), CHAN5G(40, 0),
415         CHAN5G(42, 0), CHAN5G(44, 0),
416         CHAN5G(46, 0), CHAN5G(48, 0),
417         CHAN5G(52, 0), CHAN5G(56, 0),
418         CHAN5G(60, 0), CHAN5G(64, 0),
419         CHAN5G(100, 0), CHAN5G(104, 0),
420         CHAN5G(108, 0), CHAN5G(112, 0),
421         CHAN5G(116, 0), CHAN5G(120, 0),
422         CHAN5G(124, 0), CHAN5G(128, 0),
423         CHAN5G(132, 0), CHAN5G(136, 0),
424         CHAN5G(140, 0), CHAN5G(149, 0),
425         CHAN5G(153, 0), CHAN5G(157, 0),
426         CHAN5G(161, 0), CHAN5G(165, 0),
427         CHAN5G(184, 0), CHAN5G(188, 0),
428         CHAN5G(192, 0), CHAN5G(196, 0),
429         CHAN5G(200, 0), CHAN5G(204, 0),
430         CHAN5G(208, 0), CHAN5G(212, 0),
431         CHAN5G(216, 0),
432 };
433
434 static struct ieee80211_channel __wl_5ghz_n_channels[] = {
435         CHAN5G(32, 0), CHAN5G(34, 0),
436         CHAN5G(36, 0), CHAN5G(38, 0),
437         CHAN5G(40, 0), CHAN5G(42, 0),
438         CHAN5G(44, 0), CHAN5G(46, 0),
439         CHAN5G(48, 0), CHAN5G(50, 0),
440         CHAN5G(52, 0), CHAN5G(54, 0),
441         CHAN5G(56, 0), CHAN5G(58, 0),
442         CHAN5G(60, 0), CHAN5G(62, 0),
443         CHAN5G(64, 0), CHAN5G(66, 0),
444         CHAN5G(68, 0), CHAN5G(70, 0),
445         CHAN5G(72, 0), CHAN5G(74, 0),
446         CHAN5G(76, 0), CHAN5G(78, 0),
447         CHAN5G(80, 0), CHAN5G(82, 0),
448         CHAN5G(84, 0), CHAN5G(86, 0),
449         CHAN5G(88, 0), CHAN5G(90, 0),
450         CHAN5G(92, 0), CHAN5G(94, 0),
451         CHAN5G(96, 0), CHAN5G(98, 0),
452         CHAN5G(100, 0), CHAN5G(102, 0),
453         CHAN5G(104, 0), CHAN5G(106, 0),
454         CHAN5G(108, 0), CHAN5G(110, 0),
455         CHAN5G(112, 0), CHAN5G(114, 0),
456         CHAN5G(116, 0), CHAN5G(118, 0),
457         CHAN5G(120, 0), CHAN5G(122, 0),
458         CHAN5G(124, 0), CHAN5G(126, 0),
459         CHAN5G(128, 0), CHAN5G(130, 0),
460         CHAN5G(132, 0), CHAN5G(134, 0),
461         CHAN5G(136, 0), CHAN5G(138, 0),
462         CHAN5G(140, 0), CHAN5G(142, 0),
463         CHAN5G(144, 0), CHAN5G(145, 0),
464         CHAN5G(146, 0), CHAN5G(147, 0),
465         CHAN5G(148, 0), CHAN5G(149, 0),
466         CHAN5G(150, 0), CHAN5G(151, 0),
467         CHAN5G(152, 0), CHAN5G(153, 0),
468         CHAN5G(154, 0), CHAN5G(155, 0),
469         CHAN5G(156, 0), CHAN5G(157, 0),
470         CHAN5G(158, 0), CHAN5G(159, 0),
471         CHAN5G(160, 0), CHAN5G(161, 0),
472         CHAN5G(162, 0), CHAN5G(163, 0),
473         CHAN5G(164, 0), CHAN5G(165, 0),
474         CHAN5G(166, 0), CHAN5G(168, 0),
475         CHAN5G(170, 0), CHAN5G(172, 0),
476         CHAN5G(174, 0), CHAN5G(176, 0),
477         CHAN5G(178, 0), CHAN5G(180, 0),
478         CHAN5G(182, 0), CHAN5G(184, 0),
479         CHAN5G(186, 0), CHAN5G(188, 0),
480         CHAN5G(190, 0), CHAN5G(192, 0),
481         CHAN5G(194, 0), CHAN5G(196, 0),
482         CHAN5G(198, 0), CHAN5G(200, 0),
483         CHAN5G(202, 0), CHAN5G(204, 0),
484         CHAN5G(206, 0), CHAN5G(208, 0),
485         CHAN5G(210, 0), CHAN5G(212, 0),
486         CHAN5G(214, 0), CHAN5G(216, 0),
487         CHAN5G(218, 0), CHAN5G(220, 0),
488         CHAN5G(222, 0), CHAN5G(224, 0),
489         CHAN5G(226, 0), CHAN5G(228, 0),
490 };
491
492 static struct ieee80211_supported_band __wl_band_2ghz = {
493         .band = IEEE80211_BAND_2GHZ,
494         .channels = __wl_2ghz_channels,
495         .n_channels = ARRAY_SIZE(__wl_2ghz_channels),
496         .bitrates = wl_g_rates,
497         .n_bitrates = wl_g_rates_size,
498 };
499
500 static struct ieee80211_supported_band __wl_band_5ghz_a = {
501         .band = IEEE80211_BAND_5GHZ,
502         .channels = __wl_5ghz_a_channels,
503         .n_channels = ARRAY_SIZE(__wl_5ghz_a_channels),
504         .bitrates = wl_a_rates,
505         .n_bitrates = wl_a_rates_size,
506 };
507
508 static struct ieee80211_supported_band __wl_band_5ghz_n = {
509         .band = IEEE80211_BAND_5GHZ,
510         .channels = __wl_5ghz_n_channels,
511         .n_channels = ARRAY_SIZE(__wl_5ghz_n_channels),
512         .bitrates = wl_a_rates,
513         .n_bitrates = wl_a_rates_size,
514 };
515
516 static const u32 __wl_cipher_suites[] = {
517         WLAN_CIPHER_SUITE_WEP40,
518         WLAN_CIPHER_SUITE_WEP104,
519         WLAN_CIPHER_SUITE_TKIP,
520         WLAN_CIPHER_SUITE_CCMP,
521         WLAN_CIPHER_SUITE_AES_CMAC,
522 };
523
524 static void swap_key_from_BE(struct wl_wsec_key *key)
525 {
526         key->index = cpu_to_le32(key->index);
527         key->len = cpu_to_le32(key->len);
528         key->algo = cpu_to_le32(key->algo);
529         key->flags = cpu_to_le32(key->flags);
530         key->rxiv.hi = cpu_to_le32(key->rxiv.hi);
531         key->rxiv.lo = cpu_to_le16(key->rxiv.lo);
532         key->iv_initialized = cpu_to_le32(key->iv_initialized);
533 }
534
535 static void swap_key_to_BE(struct wl_wsec_key *key)
536 {
537         key->index = le32_to_cpu(key->index);
538         key->len = le32_to_cpu(key->len);
539         key->algo = le32_to_cpu(key->algo);
540         key->flags = le32_to_cpu(key->flags);
541         key->rxiv.hi = le32_to_cpu(key->rxiv.hi);
542         key->rxiv.lo = le16_to_cpu(key->rxiv.lo);
543         key->iv_initialized = le32_to_cpu(key->iv_initialized);
544 }
545
546 static s32
547 wl_dev_ioctl(struct net_device *dev, u32 cmd, void *arg, u32 len)
548 {
549         struct ifreq ifr;
550         struct wl_ioctl ioc;
551         mm_segment_t fs;
552         s32 err = 0;
553
554         memset(&ioc, 0, sizeof(ioc));
555         ioc.cmd = cmd;
556         ioc.buf = arg;
557         ioc.len = len;
558         strcpy(ifr.ifr_name, dev->name);
559         ifr.ifr_data = (caddr_t)&ioc;
560
561         fs = get_fs();
562         set_fs(get_ds());
563         err = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, SIOCDEVPRIVATE);
564         set_fs(fs);
565
566         return err;
567 }
568
569 static s32
570 wl_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
571                          enum nl80211_iftype type, u32 *flags,
572                          struct vif_params *params)
573 {
574         struct wl_priv *wl = wiphy_to_wl(wiphy);
575         struct wireless_dev *wdev;
576         s32 infra = 0;
577         s32 err = 0;
578
579         WL_TRACE("Enter\n");
580         CHECK_SYS_UP();
581
582         switch (type) {
583         case NL80211_IFTYPE_MONITOR:
584         case NL80211_IFTYPE_WDS:
585                 WL_ERR("type (%d) : currently we do not support this type\n",
586                        type);
587                 return -EOPNOTSUPP;
588         case NL80211_IFTYPE_ADHOC:
589                 wl->conf->mode = WL_MODE_IBSS;
590                 infra = 0;
591                 break;
592         case NL80211_IFTYPE_STATION:
593                 wl->conf->mode = WL_MODE_BSS;
594                 infra = 1;
595                 break;
596         default:
597                 err = -EINVAL;
598                 goto done;
599         }
600
601         infra = cpu_to_le32(infra);
602         err = wl_dev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(infra));
603         if (unlikely(err)) {
604                 WL_ERR("WLC_SET_INFRA error (%d)\n", err);
605                 err = -EAGAIN;
606         } else {
607                 wdev = ndev->ieee80211_ptr;
608                 wdev->iftype = type;
609         }
610
611         WL_INFO("IF Type = %s\n",
612                 (wl->conf->mode == WL_MODE_IBSS) ? "Adhoc" : "Infra");
613
614 done:
615         WL_TRACE("Exit\n");
616
617         return err;
618 }
619
620 static void wl_iscan_prep(struct wl_scan_params *params, struct wlc_ssid *ssid)
621 {
622         memcpy(params->bssid, ether_bcast, ETH_ALEN);
623         params->bss_type = DOT11_BSSTYPE_ANY;
624         params->scan_type = 0;
625         params->nprobes = -1;
626         params->active_time = -1;
627         params->passive_time = -1;
628         params->home_time = -1;
629         params->channel_num = 0;
630
631         params->nprobes = cpu_to_le32(params->nprobes);
632         params->active_time = cpu_to_le32(params->active_time);
633         params->passive_time = cpu_to_le32(params->passive_time);
634         params->home_time = cpu_to_le32(params->home_time);
635         if (ssid && ssid->SSID_len)
636                 memcpy(&params->ssid, ssid, sizeof(wlc_ssid_t));
637
638 }
639
640 static s32
641 wl_dev_iovar_setbuf(struct net_device *dev, s8 * iovar, void *param,
642                     s32 paramlen, void *bufptr, s32 buflen)
643 {
644         s32 iolen;
645
646         iolen = bcm_mkiovar(iovar, param, paramlen, bufptr, buflen);
647         BUG_ON(!iolen);
648
649         return wl_dev_ioctl(dev, WLC_SET_VAR, bufptr, iolen);
650 }
651
652 static s32
653 wl_dev_iovar_getbuf(struct net_device *dev, s8 * iovar, void *param,
654                     s32 paramlen, void *bufptr, s32 buflen)
655 {
656         s32 iolen;
657
658         iolen = bcm_mkiovar(iovar, param, paramlen, bufptr, buflen);
659         BUG_ON(!iolen);
660
661         return wl_dev_ioctl(dev, WLC_GET_VAR, bufptr, buflen);
662 }
663
664 static s32
665 wl_run_iscan(struct wl_iscan_ctrl *iscan, struct wlc_ssid *ssid, u16 action)
666 {
667         s32 params_size =
668             (WL_SCAN_PARAMS_FIXED_SIZE + offsetof(wl_iscan_params_t, params));
669         struct wl_iscan_params *params;
670         s32 err = 0;
671
672         if (ssid && ssid->SSID_len)
673                 params_size += sizeof(struct wlc_ssid);
674         params = kzalloc(params_size, GFP_KERNEL);
675         if (unlikely(!params))
676                 return -ENOMEM;
677         BUG_ON(params_size >= WLC_IOCTL_SMLEN);
678
679         wl_iscan_prep(&params->params, ssid);
680
681         params->version = cpu_to_le32(ISCAN_REQ_VERSION);
682         params->action = cpu_to_le16(action);
683         params->scan_duration = cpu_to_le16(0);
684
685         /* params_size += offsetof(wl_iscan_params_t, params); */
686         err = wl_dev_iovar_setbuf(iscan->dev, "iscan", params, params_size,
687                                 iscan->ioctl_buf, WLC_IOCTL_SMLEN);
688         if (unlikely(err)) {
689                 if (err == -EBUSY) {
690                         WL_INFO("system busy : iscan canceled\n");
691                 } else {
692                         WL_ERR("error (%d)\n", err);
693                 }
694         }
695         kfree(params);
696         return err;
697 }
698
699 static s32 wl_do_iscan(struct wl_priv *wl)
700 {
701         struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
702         struct net_device *ndev = wl_to_ndev(wl);
703         struct wlc_ssid ssid;
704         s32 passive_scan;
705         s32 err = 0;
706
707         /* Broadcast scan by default */
708         memset(&ssid, 0, sizeof(ssid));
709
710         iscan->state = WL_ISCAN_STATE_SCANING;
711
712         passive_scan = wl->active_scan ? 0 : 1;
713         err = wl_dev_ioctl(wl_to_ndev(wl), WLC_SET_PASSIVE_SCAN,
714                         &passive_scan, sizeof(passive_scan));
715         if (unlikely(err)) {
716                 WL_ERR("error (%d)\n", err);
717                 return err;
718         }
719         wl_set_mpc(ndev, 0);
720         wl->iscan_kickstart = true;
721         wl_run_iscan(iscan, &ssid, WL_SCAN_ACTION_START);
722         mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
723         iscan->timer_on = 1;
724
725         return err;
726 }
727
728 static s32
729 __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
730                    struct cfg80211_scan_request *request,
731                    struct cfg80211_ssid *this_ssid)
732 {
733         struct wl_priv *wl = ndev_to_wl(ndev);
734         struct cfg80211_ssid *ssids;
735         struct wl_scan_req *sr = wl_to_sr(wl);
736         s32 passive_scan;
737         bool iscan_req;
738         bool spec_scan;
739         s32 err = 0;
740
741         if (unlikely(test_bit(WL_STATUS_SCANNING, &wl->status))) {
742                 WL_ERR("Scanning already : status (%d)\n", (int)wl->status);
743                 return -EAGAIN;
744         }
745         if (unlikely(test_bit(WL_STATUS_SCAN_ABORTING, &wl->status))) {
746                 WL_ERR("Scanning being aborted : status (%d)\n",
747                        (int)wl->status);
748                 return -EAGAIN;
749         }
750         if (test_bit(WL_STATUS_CONNECTING, &wl->status)) {
751                 WL_ERR("Connecting : status (%d)\n",
752                        (int)wl->status);
753                 return -EAGAIN;
754         }
755
756         iscan_req = false;
757         spec_scan = false;
758         if (request) {
759                 /* scan bss */
760                 ssids = request->ssids;
761                 if (wl->iscan_on && (!ssids || !ssids->ssid_len))
762                         iscan_req = true;
763         } else {
764                 /* scan in ibss */
765                 /* we don't do iscan in ibss */
766                 ssids = this_ssid;
767         }
768
769         wl->scan_request = request;
770         set_bit(WL_STATUS_SCANNING, &wl->status);
771         if (iscan_req) {
772                 err = wl_do_iscan(wl);
773                 if (likely(!err))
774                         return err;
775                 else
776                         goto scan_out;
777         } else {
778                 WL_SCAN("ssid \"%s\", ssid_len (%d)\n",
779                        ssids->ssid, ssids->ssid_len);
780                 memset(&sr->ssid, 0, sizeof(sr->ssid));
781                 sr->ssid.SSID_len =
782                             min_t(u8, sizeof(sr->ssid.SSID), ssids->ssid_len);
783                 if (sr->ssid.SSID_len) {
784                         memcpy(sr->ssid.SSID, ssids->ssid, sr->ssid.SSID_len);
785                         sr->ssid.SSID_len = cpu_to_le32(sr->ssid.SSID_len);
786                         spec_scan = true;
787                 } else {
788                         WL_SCAN("Broadcast scan\n");
789                 }
790
791                 passive_scan = wl->active_scan ? 0 : 1;
792                 err = wl_dev_ioctl(ndev, WLC_SET_PASSIVE_SCAN,
793                                 &passive_scan, sizeof(passive_scan));
794                 if (unlikely(err)) {
795                         WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
796                         goto scan_out;
797                 }
798                 wl_set_mpc(ndev, 0);
799                 err = wl_dev_ioctl(ndev, WLC_SCAN, &sr->ssid,
800                                 sizeof(sr->ssid));
801                 if (err) {
802                         if (err == -EBUSY) {
803                                 WL_INFO("system busy : scan for \"%s\" canceled\n",
804                                         sr->ssid.SSID);
805                         } else {
806                                 WL_ERR("WLC_SCAN error (%d)\n", err);
807                         }
808                         wl_set_mpc(ndev, 1);
809                         goto scan_out;
810                 }
811         }
812
813         return 0;
814
815 scan_out:
816         clear_bit(WL_STATUS_SCANNING, &wl->status);
817         wl->scan_request = NULL;
818         return err;
819 }
820
821 static s32
822 wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
823                  struct cfg80211_scan_request *request)
824 {
825         s32 err = 0;
826
827         WL_TRACE("Enter\n");
828
829         CHECK_SYS_UP();
830
831         err = __wl_cfg80211_scan(wiphy, ndev, request, NULL);
832         if (unlikely(err))
833                 WL_ERR("scan error (%d)\n", err);
834
835         WL_TRACE("Exit\n");
836         return err;
837 }
838
839 static s32 wl_dev_intvar_set(struct net_device *dev, s8 *name, s32 val)
840 {
841         s8 buf[WLC_IOCTL_SMLEN];
842         u32 len;
843         s32 err = 0;
844
845         val = cpu_to_le32(val);
846         len = bcm_mkiovar(name, (char *)(&val), sizeof(val), buf, sizeof(buf));
847         BUG_ON(!len);
848
849         err = wl_dev_ioctl(dev, WLC_SET_VAR, buf, len);
850         if (unlikely(err))
851                 WL_ERR("error (%d)\n", err);
852
853         return err;
854 }
855
856 static s32
857 wl_dev_intvar_get(struct net_device *dev, s8 *name, s32 *retval)
858 {
859         union {
860                 s8 buf[WLC_IOCTL_SMLEN];
861                 s32 val;
862         } var;
863         u32 len;
864         u32 data_null;
865         s32 err = 0;
866
867         len =
868             bcm_mkiovar(name, (char *)(&data_null), 0, (char *)(&var),
869                         sizeof(var.buf));
870         BUG_ON(!len);
871         err = wl_dev_ioctl(dev, WLC_GET_VAR, &var, len);
872         if (unlikely(err))
873                 WL_ERR("error (%d)\n", err);
874
875         *retval = le32_to_cpu(var.val);
876
877         return err;
878 }
879
880 static s32 wl_set_rts(struct net_device *dev, u32 rts_threshold)
881 {
882         s32 err = 0;
883
884         err = wl_dev_intvar_set(dev, "rtsthresh", rts_threshold);
885         if (unlikely(err))
886                 WL_ERR("Error (%d)\n", err);
887
888         return err;
889 }
890
891 static s32 wl_set_frag(struct net_device *dev, u32 frag_threshold)
892 {
893         s32 err = 0;
894
895         err = wl_dev_intvar_set(dev, "fragthresh", frag_threshold);
896         if (unlikely(err))
897                 WL_ERR("Error (%d)\n", err);
898
899         return err;
900 }
901
902 static s32 wl_set_retry(struct net_device *dev, u32 retry, bool l)
903 {
904         s32 err = 0;
905         u32 cmd = (l ? WLC_SET_LRL : WLC_SET_SRL);
906
907         retry = cpu_to_le32(retry);
908         err = wl_dev_ioctl(dev, cmd, &retry, sizeof(retry));
909         if (unlikely(err)) {
910                 WL_ERR("cmd (%d) , error (%d)\n", cmd, err);
911                 return err;
912         }
913         return err;
914 }
915
916 static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
917 {
918         struct wl_priv *wl = wiphy_to_wl(wiphy);
919         struct net_device *ndev = wl_to_ndev(wl);
920         s32 err = 0;
921
922         WL_TRACE("Enter\n");
923         CHECK_SYS_UP();
924
925         if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
926             (wl->conf->rts_threshold != wiphy->rts_threshold)) {
927                 wl->conf->rts_threshold = wiphy->rts_threshold;
928                 err = wl_set_rts(ndev, wl->conf->rts_threshold);
929                 if (!err)
930                         goto done;
931         }
932         if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
933             (wl->conf->frag_threshold != wiphy->frag_threshold)) {
934                 wl->conf->frag_threshold = wiphy->frag_threshold;
935                 err = wl_set_frag(ndev, wl->conf->frag_threshold);
936                 if (!err)
937                         goto done;
938         }
939         if (changed & WIPHY_PARAM_RETRY_LONG
940             && (wl->conf->retry_long != wiphy->retry_long)) {
941                 wl->conf->retry_long = wiphy->retry_long;
942                 err = wl_set_retry(ndev, wl->conf->retry_long, true);
943                 if (!err)
944                         goto done;
945         }
946         if (changed & WIPHY_PARAM_RETRY_SHORT
947             && (wl->conf->retry_short != wiphy->retry_short)) {
948                 wl->conf->retry_short = wiphy->retry_short;
949                 err = wl_set_retry(ndev, wl->conf->retry_short, false);
950                 if (!err)
951                         goto done;
952         }
953
954 done:
955         WL_TRACE("Exit\n");
956         return err;
957 }
958
959 static s32
960 wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
961                       struct cfg80211_ibss_params *params)
962 {
963         struct wl_priv *wl = wiphy_to_wl(wiphy);
964         struct wl_join_params join_params;
965         size_t join_params_size = 0;
966         s32 err = 0;
967         s32 wsec = 0;
968         s32 bcnprd;
969
970         WL_TRACE("Enter\n");
971         CHECK_SYS_UP();
972
973         if (params->ssid)
974                 WL_CONN("SSID: %s\n", params->ssid);
975         else {
976                 WL_CONN("SSID: NULL, Not supported\n");
977                 return -EOPNOTSUPP;
978         }
979
980         if (params->bssid)
981                 WL_CONN("BSSID: %02X %02X %02X %02X %02X %02X\n",
982                 params->bssid[0], params->bssid[1], params->bssid[2],
983                 params->bssid[3], params->bssid[4], params->bssid[5]);
984         else
985                 WL_CONN("No BSSID specified\n");
986
987         if (params->channel)
988                 WL_CONN("channel: %d\n", params->channel->center_freq);
989         else
990                 WL_CONN("no channel specified\n");
991
992         if (params->channel_fixed)
993                 WL_CONN("fixed channel required\n");
994         else
995                 WL_CONN("no fixed channel required\n");
996
997         if (params->ie && params->ie_len)
998                 WL_CONN("ie len: %d\n", params->ie_len);
999         else
1000                 WL_CONN("no ie specified\n");
1001
1002         if (params->beacon_interval)
1003                 WL_CONN("beacon interval: %d\n", params->beacon_interval);
1004         else
1005                 WL_CONN("no beacon interval specified\n");
1006
1007         if (params->basic_rates)
1008                 WL_CONN("basic rates: %08X\n", params->basic_rates);
1009         else
1010                 WL_CONN("no basic rates specified\n");
1011
1012         if (params->privacy)
1013                 WL_CONN("privacy required\n");
1014         else
1015                 WL_CONN("no privacy required\n");
1016
1017         /* Configure Privacy for starter */
1018         if (params->privacy)
1019                 wsec |= WEP_ENABLED;
1020
1021         err = wl_dev_intvar_set(dev, "wsec", wsec);
1022         if (unlikely(err)) {
1023                 WL_ERR("wsec failed (%d)\n", err);
1024                 goto done;
1025         }
1026
1027         /* Configure Beacon Interval for starter */
1028         if (params->beacon_interval)
1029                 bcnprd = cpu_to_le32(params->beacon_interval);
1030         else
1031                 bcnprd = cpu_to_le32(100);
1032
1033         err = wl_dev_ioctl(dev, WLC_SET_BCNPRD, &bcnprd, sizeof(bcnprd));
1034         if (unlikely(err)) {
1035                 WL_ERR("WLC_SET_BCNPRD failed (%d)\n", err);
1036                 goto done;
1037         }
1038
1039         /* Configure required join parameter */
1040         memset(&join_params, 0, sizeof(wl_join_params_t));
1041
1042         /* SSID */
1043         join_params.ssid.SSID_len =
1044                         (params->ssid_len > 32) ? 32 : params->ssid_len;
1045         memcpy(join_params.ssid.SSID, params->ssid, join_params.ssid.SSID_len);
1046         join_params.ssid.SSID_len = cpu_to_le32(join_params.ssid.SSID_len);
1047         join_params_size = sizeof(join_params.ssid);
1048         wl_update_prof(wl, NULL, &join_params.ssid, WL_PROF_SSID);
1049
1050         /* BSSID */
1051         if (params->bssid) {
1052                 memcpy(join_params.params.bssid, params->bssid, ETH_ALEN);
1053                 join_params_size =
1054                         sizeof(join_params.ssid) + WL_ASSOC_PARAMS_FIXED_SIZE;
1055         } else {
1056                 memcpy(join_params.params.bssid, ether_bcast, ETH_ALEN);
1057         }
1058         wl_update_prof(wl, NULL, &join_params.params.bssid, WL_PROF_BSSID);
1059
1060         /* Channel */
1061         if (params->channel) {
1062                 u32 target_channel;
1063
1064                 wl->channel =
1065                         ieee80211_frequency_to_channel(
1066                                 params->channel->center_freq);
1067                 if (params->channel_fixed) {
1068                         /* adding chanspec */
1069                         wl_ch_to_chanspec(wl->channel,
1070                                 &join_params, &join_params_size);
1071                 }
1072
1073                 /* set channel for starter */
1074                 target_channel = cpu_to_le32(wl->channel);
1075                 err = wl_dev_ioctl(dev, WLC_SET_CHANNEL,
1076                         &target_channel, sizeof(target_channel));
1077                 if (unlikely(err)) {
1078                         WL_ERR("WLC_SET_CHANNEL failed (%d)\n", err);
1079                         goto done;
1080                 }
1081         } else
1082                 wl->channel = 0;
1083
1084         wl->ibss_starter = false;
1085
1086
1087         err = wl_dev_ioctl(dev, WLC_SET_SSID, &join_params, join_params_size);
1088         if (unlikely(err)) {
1089                 WL_ERR("WLC_SET_SSID failed (%d)\n", err);
1090                 goto done;
1091         }
1092
1093         set_bit(WL_STATUS_CONNECTING, &wl->status);
1094
1095 done:
1096         WL_TRACE("Exit\n");
1097         return err;
1098 }
1099
1100 static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
1101 {
1102         struct wl_priv *wl = wiphy_to_wl(wiphy);
1103         s32 err = 0;
1104
1105         WL_TRACE("Enter\n");
1106         CHECK_SYS_UP();
1107
1108         wl_link_down(wl);
1109
1110         WL_TRACE("Exit\n");
1111
1112         return err;
1113 }
1114
1115 static s32
1116 wl_set_wpa_version(struct net_device *dev, struct cfg80211_connect_params *sme)
1117 {
1118         struct wl_priv *wl = ndev_to_wl(dev);
1119         struct wl_security *sec;
1120         s32 val = 0;
1121         s32 err = 0;
1122
1123         if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1124                 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
1125         else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1126                 val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
1127         else
1128                 val = WPA_AUTH_DISABLED;
1129         WL_CONN("setting wpa_auth to 0x%0x\n", val);
1130         err = wl_dev_intvar_set(dev, "wpa_auth", val);
1131         if (unlikely(err)) {
1132                 WL_ERR("set wpa_auth failed (%d)\n", err);
1133                 return err;
1134         }
1135         sec = wl_read_prof(wl, WL_PROF_SEC);
1136         sec->wpa_versions = sme->crypto.wpa_versions;
1137         return err;
1138 }
1139
1140 static s32
1141 wl_set_auth_type(struct net_device *dev, struct cfg80211_connect_params *sme)
1142 {
1143         struct wl_priv *wl = ndev_to_wl(dev);
1144         struct wl_security *sec;
1145         s32 val = 0;
1146         s32 err = 0;
1147
1148         switch (sme->auth_type) {
1149         case NL80211_AUTHTYPE_OPEN_SYSTEM:
1150                 val = 0;
1151                 WL_CONN("open system\n");
1152                 break;
1153         case NL80211_AUTHTYPE_SHARED_KEY:
1154                 val = 1;
1155                 WL_CONN("shared key\n");
1156                 break;
1157         case NL80211_AUTHTYPE_AUTOMATIC:
1158                 val = 2;
1159                 WL_CONN("automatic\n");
1160                 break;
1161         case NL80211_AUTHTYPE_NETWORK_EAP:
1162                 WL_CONN("network eap\n");
1163         default:
1164                 val = 2;
1165                 WL_ERR("invalid auth type (%d)\n", sme->auth_type);
1166                 break;
1167         }
1168
1169         err = wl_dev_intvar_set(dev, "auth", val);
1170         if (unlikely(err)) {
1171                 WL_ERR("set auth failed (%d)\n", err);
1172                 return err;
1173         }
1174         sec = wl_read_prof(wl, WL_PROF_SEC);
1175         sec->auth_type = sme->auth_type;
1176         return err;
1177 }
1178
1179 static s32
1180 wl_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme)
1181 {
1182         struct wl_priv *wl = ndev_to_wl(dev);
1183         struct wl_security *sec;
1184         s32 pval = 0;
1185         s32 gval = 0;
1186         s32 err = 0;
1187
1188         if (sme->crypto.n_ciphers_pairwise) {
1189                 switch (sme->crypto.ciphers_pairwise[0]) {
1190                 case WLAN_CIPHER_SUITE_WEP40:
1191                 case WLAN_CIPHER_SUITE_WEP104:
1192                         pval = WEP_ENABLED;
1193                         break;
1194                 case WLAN_CIPHER_SUITE_TKIP:
1195                         pval = TKIP_ENABLED;
1196                         break;
1197                 case WLAN_CIPHER_SUITE_CCMP:
1198                         pval = AES_ENABLED;
1199                         break;
1200                 case WLAN_CIPHER_SUITE_AES_CMAC:
1201                         pval = AES_ENABLED;
1202                         break;
1203                 default:
1204                         WL_ERR("invalid cipher pairwise (%d)\n",
1205                                sme->crypto.ciphers_pairwise[0]);
1206                         return -EINVAL;
1207                 }
1208         }
1209         if (sme->crypto.cipher_group) {
1210                 switch (sme->crypto.cipher_group) {
1211                 case WLAN_CIPHER_SUITE_WEP40:
1212                 case WLAN_CIPHER_SUITE_WEP104:
1213                         gval = WEP_ENABLED;
1214                         break;
1215                 case WLAN_CIPHER_SUITE_TKIP:
1216                         gval = TKIP_ENABLED;
1217                         break;
1218                 case WLAN_CIPHER_SUITE_CCMP:
1219                         gval = AES_ENABLED;
1220                         break;
1221                 case WLAN_CIPHER_SUITE_AES_CMAC:
1222                         gval = AES_ENABLED;
1223                         break;
1224                 default:
1225                         WL_ERR("invalid cipher group (%d)\n",
1226                                sme->crypto.cipher_group);
1227                         return -EINVAL;
1228                 }
1229         }
1230
1231         WL_CONN("pval (%d) gval (%d)\n", pval, gval);
1232         err = wl_dev_intvar_set(dev, "wsec", pval | gval);
1233         if (unlikely(err)) {
1234                 WL_ERR("error (%d)\n", err);
1235                 return err;
1236         }
1237
1238         sec = wl_read_prof(wl, WL_PROF_SEC);
1239         sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1240         sec->cipher_group = sme->crypto.cipher_group;
1241
1242         return err;
1243 }
1244
1245 static s32
1246 wl_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme)
1247 {
1248         struct wl_priv *wl = ndev_to_wl(dev);
1249         struct wl_security *sec;
1250         s32 val = 0;
1251         s32 err = 0;
1252
1253         if (sme->crypto.n_akm_suites) {
1254                 err = wl_dev_intvar_get(dev, "wpa_auth", &val);
1255                 if (unlikely(err)) {
1256                         WL_ERR("could not get wpa_auth (%d)\n", err);
1257                         return err;
1258                 }
1259                 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1260                         switch (sme->crypto.akm_suites[0]) {
1261                         case WLAN_AKM_SUITE_8021X:
1262                                 val = WPA_AUTH_UNSPECIFIED;
1263                                 break;
1264                         case WLAN_AKM_SUITE_PSK:
1265                                 val = WPA_AUTH_PSK;
1266                                 break;
1267                         default:
1268                                 WL_ERR("invalid cipher group (%d)\n",
1269                                        sme->crypto.cipher_group);
1270                                 return -EINVAL;
1271                         }
1272                 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1273                         switch (sme->crypto.akm_suites[0]) {
1274                         case WLAN_AKM_SUITE_8021X:
1275                                 val = WPA2_AUTH_UNSPECIFIED;
1276                                 break;
1277                         case WLAN_AKM_SUITE_PSK:
1278                                 val = WPA2_AUTH_PSK;
1279                                 break;
1280                         default:
1281                                 WL_ERR("invalid cipher group (%d)\n",
1282                                        sme->crypto.cipher_group);
1283                                 return -EINVAL;
1284                         }
1285                 }
1286
1287                 WL_CONN("setting wpa_auth to %d\n", val);
1288                 err = wl_dev_intvar_set(dev, "wpa_auth", val);
1289                 if (unlikely(err)) {
1290                         WL_ERR("could not set wpa_auth (%d)\n", err);
1291                         return err;
1292                 }
1293         }
1294         sec = wl_read_prof(wl, WL_PROF_SEC);
1295         sec->wpa_auth = sme->crypto.akm_suites[0];
1296
1297         return err;
1298 }
1299
1300 static s32
1301 wl_set_set_sharedkey(struct net_device *dev,
1302                      struct cfg80211_connect_params *sme)
1303 {
1304         struct wl_priv *wl = ndev_to_wl(dev);
1305         struct wl_security *sec;
1306         struct wl_wsec_key key;
1307         s32 val;
1308         s32 err = 0;
1309
1310         WL_CONN("key len (%d)\n", sme->key_len);
1311         if (sme->key_len) {
1312                 sec = wl_read_prof(wl, WL_PROF_SEC);
1313                 WL_CONN("wpa_versions 0x%x cipher_pairwise 0x%x\n",
1314                        sec->wpa_versions, sec->cipher_pairwise);
1315                 if (!
1316                     (sec->wpa_versions & (NL80211_WPA_VERSION_1 |
1317                                           NL80211_WPA_VERSION_2))
1318 && (sec->cipher_pairwise & (WLAN_CIPHER_SUITE_WEP40 |
1319                             WLAN_CIPHER_SUITE_WEP104))) {
1320                         memset(&key, 0, sizeof(key));
1321                         key.len = (u32) sme->key_len;
1322                         key.index = (u32) sme->key_idx;
1323                         if (unlikely(key.len > sizeof(key.data))) {
1324                                 WL_ERR("Too long key length (%u)\n", key.len);
1325                                 return -EINVAL;
1326                         }
1327                         memcpy(key.data, sme->key, key.len);
1328                         key.flags = WL_PRIMARY_KEY;
1329                         switch (sec->cipher_pairwise) {
1330                         case WLAN_CIPHER_SUITE_WEP40:
1331                                 key.algo = CRYPTO_ALGO_WEP1;
1332                                 break;
1333                         case WLAN_CIPHER_SUITE_WEP104:
1334                                 key.algo = CRYPTO_ALGO_WEP128;
1335                                 break;
1336                         default:
1337                                 WL_ERR("Invalid algorithm (%d)\n",
1338                                        sme->crypto.ciphers_pairwise[0]);
1339                                 return -EINVAL;
1340                         }
1341                         /* Set the new key/index */
1342                         WL_CONN("key length (%d) key index (%d) algo (%d)\n",
1343                                key.len, key.index, key.algo);
1344                         WL_CONN("key \"%s\"\n", key.data);
1345                         swap_key_from_BE(&key);
1346                         err = wl_dev_ioctl(dev, WLC_SET_KEY, &key,
1347                                         sizeof(key));
1348                         if (unlikely(err)) {
1349                                 WL_ERR("WLC_SET_KEY error (%d)\n", err);
1350                                 return err;
1351                         }
1352                         if (sec->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) {
1353                                 WL_CONN("set auth_type to shared key\n");
1354                                 val = 1;        /* shared key */
1355                                 err = wl_dev_intvar_set(dev, "auth", val);
1356                                 if (unlikely(err)) {
1357                                         WL_ERR("set auth failed (%d)\n", err);
1358                                         return err;
1359                                 }
1360                         }
1361                 }
1362         }
1363         return err;
1364 }
1365
1366 static s32
1367 wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
1368                     struct cfg80211_connect_params *sme)
1369 {
1370         struct wl_priv *wl = wiphy_to_wl(wiphy);
1371         struct ieee80211_channel *chan = sme->channel;
1372         struct wl_join_params join_params;
1373         size_t join_params_size;
1374
1375         s32 err = 0;
1376
1377         WL_TRACE("Enter\n");
1378         CHECK_SYS_UP();
1379
1380         if (unlikely(!sme->ssid)) {
1381                 WL_ERR("Invalid ssid\n");
1382                 return -EOPNOTSUPP;
1383         }
1384
1385         if (chan) {
1386                 wl->channel =
1387                         ieee80211_frequency_to_channel(chan->center_freq);
1388                 WL_CONN("channel (%d), center_req (%d)\n",
1389                         wl->channel, chan->center_freq);
1390         } else
1391                 wl->channel = 0;
1392
1393         WL_INFO("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
1394
1395         err = wl_set_wpa_version(dev, sme);
1396         if (unlikely(err))
1397                 return err;
1398
1399         err = wl_set_auth_type(dev, sme);
1400         if (unlikely(err))
1401                 return err;
1402
1403         err = wl_set_set_cipher(dev, sme);
1404         if (unlikely(err))
1405                 return err;
1406
1407         err = wl_set_key_mgmt(dev, sme);
1408         if (unlikely(err))
1409                 return err;
1410
1411         err = wl_set_set_sharedkey(dev, sme);
1412         if (unlikely(err))
1413                 return err;
1414
1415         wl_update_prof(wl, NULL, sme->bssid, WL_PROF_BSSID);
1416         /*
1417          **  Join with specific BSSID and cached SSID
1418          **  If SSID is zero join based on BSSID only
1419          */
1420         memset(&join_params, 0, sizeof(join_params));
1421         join_params_size = sizeof(join_params.ssid);
1422
1423         join_params.ssid.SSID_len = min(sizeof(join_params.ssid.SSID), sme->ssid_len);
1424         memcpy(&join_params.ssid.SSID, sme->ssid, join_params.ssid.SSID_len);
1425         join_params.ssid.SSID_len = cpu_to_le32(join_params.ssid.SSID_len);
1426         wl_update_prof(wl, NULL, &join_params.ssid, WL_PROF_SSID);
1427
1428         if (sme->bssid)
1429                 memcpy(join_params.params.bssid, sme->bssid, ETH_ALEN);
1430         else
1431                 memcpy(join_params.params.bssid, ether_bcast, ETH_ALEN);
1432
1433         if (join_params.ssid.SSID_len < IEEE80211_MAX_SSID_LEN) {
1434                 WL_CONN("ssid \"%s\", len (%d)\n",
1435                        join_params.ssid.SSID, join_params.ssid.SSID_len);
1436         }
1437
1438         wl_ch_to_chanspec(wl->channel, &join_params, &join_params_size);
1439         err = wl_dev_ioctl(dev, WLC_SET_SSID, &join_params, join_params_size);
1440         if (unlikely(err)) {
1441                 WL_ERR("error (%d)\n", err);
1442                 return err;
1443         }
1444         set_bit(WL_STATUS_CONNECTING, &wl->status);
1445
1446         WL_TRACE("Exit\n");
1447         return err;
1448 }
1449
1450 static s32
1451 wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
1452                        u16 reason_code)
1453 {
1454         struct wl_priv *wl = wiphy_to_wl(wiphy);
1455         scb_val_t scbval;
1456         s32 err = 0;
1457
1458         WL_TRACE("Enter. Reason code = %d\n", reason_code);
1459         CHECK_SYS_UP();
1460
1461         clear_bit(WL_STATUS_CONNECTED, &wl->status);
1462
1463         scbval.val = reason_code;
1464         memcpy(&scbval.ea, wl_read_prof(wl, WL_PROF_BSSID), ETH_ALEN);
1465         scbval.val = cpu_to_le32(scbval.val);
1466         err = wl_dev_ioctl(dev, WLC_DISASSOC, &scbval,
1467                         sizeof(scb_val_t));
1468         if (unlikely(err))
1469                 WL_ERR("error (%d)\n", err);
1470
1471         wl->link_up = false;
1472
1473         WL_TRACE("Exit\n");
1474         return err;
1475 }
1476
1477 static s32
1478 wl_cfg80211_set_tx_power(struct wiphy *wiphy,
1479                          enum nl80211_tx_power_setting type, s32 dbm)
1480 {
1481
1482         struct wl_priv *wl = wiphy_to_wl(wiphy);
1483         struct net_device *ndev = wl_to_ndev(wl);
1484         u16 txpwrmw;
1485         s32 err = 0;
1486         s32 disable = 0;
1487
1488         WL_TRACE("Enter\n");
1489         CHECK_SYS_UP();
1490
1491         switch (type) {
1492         case NL80211_TX_POWER_AUTOMATIC:
1493                 break;
1494         case NL80211_TX_POWER_LIMITED:
1495                 if (dbm < 0) {
1496                         WL_ERR("TX_POWER_LIMITED - dbm is negative\n");
1497                         err = -EINVAL;
1498                         goto done;
1499                 }
1500                 break;
1501         case NL80211_TX_POWER_FIXED:
1502                 if (dbm < 0) {
1503                         WL_ERR("TX_POWER_FIXED - dbm is negative\n");
1504                         err = -EINVAL;
1505                         goto done;
1506                 }
1507                 break;
1508         }
1509         /* Make sure radio is off or on as far as software is concerned */
1510         disable = WL_RADIO_SW_DISABLE << 16;
1511         disable = cpu_to_le32(disable);
1512         err = wl_dev_ioctl(ndev, WLC_SET_RADIO, &disable, sizeof(disable));
1513         if (unlikely(err))
1514                 WL_ERR("WLC_SET_RADIO error (%d)\n", err);
1515
1516         if (dbm > 0xffff)
1517                 txpwrmw = 0xffff;
1518         else
1519                 txpwrmw = (u16) dbm;
1520         err = wl_dev_intvar_set(ndev, "qtxpower",
1521                         (s32) (bcm_mw_to_qdbm(txpwrmw)));
1522         if (unlikely(err))
1523                 WL_ERR("qtxpower error (%d)\n", err);
1524         wl->conf->tx_power = dbm;
1525
1526 done:
1527         WL_TRACE("Exit\n");
1528         return err;
1529 }
1530
1531 static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm)
1532 {
1533         struct wl_priv *wl = wiphy_to_wl(wiphy);
1534         struct net_device *ndev = wl_to_ndev(wl);
1535         s32 txpwrdbm;
1536         u8 result;
1537         s32 err = 0;
1538
1539         WL_TRACE("Enter\n");
1540         CHECK_SYS_UP();
1541
1542         err = wl_dev_intvar_get(ndev, "qtxpower", &txpwrdbm);
1543         if (unlikely(err)) {
1544                 WL_ERR("error (%d)\n", err);
1545                 goto done;
1546         }
1547
1548         result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
1549         *dbm = (s32) bcm_qdbm_to_mw(result);
1550
1551 done:
1552         WL_TRACE("Exit\n");
1553         return err;
1554 }
1555
1556 static s32
1557 wl_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *dev,
1558                                u8 key_idx, bool unicast, bool multicast)
1559 {
1560         u32 index;
1561         s32 wsec;
1562         s32 err = 0;
1563
1564         WL_TRACE("Enter\n");
1565         WL_CONN("key index (%d)\n", key_idx);
1566         CHECK_SYS_UP();
1567
1568         err = wl_dev_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec));
1569         if (unlikely(err)) {
1570                 WL_ERR("WLC_GET_WSEC error (%d)\n", err);
1571                 goto done;
1572         }
1573
1574         wsec = le32_to_cpu(wsec);
1575         if (wsec & WEP_ENABLED) {
1576                 /* Just select a new current key */
1577                 index = (u32) key_idx;
1578                 index = cpu_to_le32(index);
1579                 err = wl_dev_ioctl(dev, WLC_SET_KEY_PRIMARY, &index,
1580                                 sizeof(index));
1581                 if (unlikely(err))
1582                         WL_ERR("error (%d)\n", err);
1583         }
1584 done:
1585         WL_TRACE("Exit\n");
1586         return err;
1587 }
1588
1589 static s32
1590 wl_add_keyext(struct wiphy *wiphy, struct net_device *dev,
1591               u8 key_idx, const u8 *mac_addr, struct key_params *params)
1592 {
1593         struct wl_wsec_key key;
1594         s32 err = 0;
1595
1596         memset(&key, 0, sizeof(key));
1597         key.index = (u32) key_idx;
1598         /* Instead of bcast for ea address for default wep keys,
1599                  driver needs it to be Null */
1600         if (!is_multicast_ether_addr(mac_addr))
1601                 memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
1602         key.len = (u32) params->key_len;
1603         /* check for key index change */
1604         if (key.len == 0) {
1605                 /* key delete */
1606                 swap_key_from_BE(&key);
1607                 err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
1608                 if (unlikely(err)) {
1609                         WL_ERR("key delete error (%d)\n", err);
1610                         return err;
1611                 }
1612         } else {
1613                 if (key.len > sizeof(key.data)) {
1614                         WL_ERR("Invalid key length (%d)\n", key.len);
1615                         return -EINVAL;
1616                 }
1617
1618                 WL_CONN("Setting the key index %d\n", key.index);
1619                 memcpy(key.data, params->key, key.len);
1620
1621                 if (params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1622                         u8 keybuf[8];
1623                         memcpy(keybuf, &key.data[24], sizeof(keybuf));
1624                         memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1625                         memcpy(&key.data[16], keybuf, sizeof(keybuf));
1626                 }
1627
1628                 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
1629                 if (params->seq && params->seq_len == 6) {
1630                         /* rx iv */
1631                         u8 *ivptr;
1632                         ivptr = (u8 *) params->seq;
1633                         key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
1634                             (ivptr[3] << 8) | ivptr[2];
1635                         key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
1636                         key.iv_initialized = true;
1637                 }
1638
1639                 switch (params->cipher) {
1640                 case WLAN_CIPHER_SUITE_WEP40:
1641                         key.algo = CRYPTO_ALGO_WEP1;
1642                         WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1643                         break;
1644                 case WLAN_CIPHER_SUITE_WEP104:
1645                         key.algo = CRYPTO_ALGO_WEP128;
1646                         WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1647                         break;
1648                 case WLAN_CIPHER_SUITE_TKIP:
1649                         key.algo = CRYPTO_ALGO_TKIP;
1650                         WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1651                         break;
1652                 case WLAN_CIPHER_SUITE_AES_CMAC:
1653                         key.algo = CRYPTO_ALGO_AES_CCM;
1654                         WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1655                         break;
1656                 case WLAN_CIPHER_SUITE_CCMP:
1657                         key.algo = CRYPTO_ALGO_AES_CCM;
1658                         WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
1659                         break;
1660                 default:
1661                         WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
1662                         return -EINVAL;
1663                 }
1664                 swap_key_from_BE(&key);
1665
1666                 dhd_wait_pend8021x(dev);
1667                 err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
1668                 if (unlikely(err)) {
1669                         WL_ERR("WLC_SET_KEY error (%d)\n", err);
1670                         return err;
1671                 }
1672         }
1673         return err;
1674 }
1675
1676 static s32
1677 wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
1678                     u8 key_idx, bool pairwise, const u8 *mac_addr,
1679                     struct key_params *params)
1680 {
1681         struct wl_wsec_key key;
1682         s32 val;
1683         s32 wsec;
1684         s32 err = 0;
1685         u8 keybuf[8];
1686
1687         WL_TRACE("Enter\n");
1688         WL_CONN("key index (%d)\n", key_idx);
1689         CHECK_SYS_UP();
1690
1691         if (mac_addr) {
1692                 WL_TRACE("Exit");
1693                 return wl_add_keyext(wiphy, dev, key_idx, mac_addr, params);
1694         }
1695         memset(&key, 0, sizeof(key));
1696
1697         key.len = (u32) params->key_len;
1698         key.index = (u32) key_idx;
1699
1700         if (unlikely(key.len > sizeof(key.data))) {
1701                 WL_ERR("Too long key length (%u)\n", key.len);
1702                 err = -EINVAL;
1703                 goto done;
1704         }
1705         memcpy(key.data, params->key, key.len);
1706
1707         key.flags = WL_PRIMARY_KEY;
1708         switch (params->cipher) {
1709         case WLAN_CIPHER_SUITE_WEP40:
1710                 key.algo = CRYPTO_ALGO_WEP1;
1711                 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1712                 break;
1713         case WLAN_CIPHER_SUITE_WEP104:
1714                 key.algo = CRYPTO_ALGO_WEP128;
1715                 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1716                 break;
1717         case WLAN_CIPHER_SUITE_TKIP:
1718                 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1719                 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1720                 memcpy(&key.data[16], keybuf, sizeof(keybuf));
1721                 key.algo = CRYPTO_ALGO_TKIP;
1722                 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1723                 break;
1724         case WLAN_CIPHER_SUITE_AES_CMAC:
1725                 key.algo = CRYPTO_ALGO_AES_CCM;
1726                 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1727                 break;
1728         case WLAN_CIPHER_SUITE_CCMP:
1729                 key.algo = CRYPTO_ALGO_AES_CCM;
1730                 WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
1731                 break;
1732         default:
1733                 WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
1734                 err = -EINVAL;
1735                 goto done;
1736         }
1737
1738         /* Set the new key/index */
1739         swap_key_from_BE(&key);
1740         err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
1741         if (unlikely(err)) {
1742                 WL_ERR("WLC_SET_KEY error (%d)\n", err);
1743                 goto done;
1744         }
1745
1746         val = WEP_ENABLED;
1747         err = wl_dev_intvar_get(dev, "wsec", &wsec);
1748         if (unlikely(err)) {
1749                 WL_ERR("get wsec error (%d)\n", err);
1750                 goto done;
1751         }
1752         wsec &= ~(WEP_ENABLED);
1753         wsec |= val;
1754         err = wl_dev_intvar_set(dev, "wsec", wsec);
1755         if (unlikely(err)) {
1756                 WL_ERR("set wsec error (%d)\n", err);
1757                 goto done;
1758         }
1759
1760         val = 1;                /* assume shared key. otherwise 0 */
1761         val = cpu_to_le32(val);
1762         err = wl_dev_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val));
1763         if (unlikely(err))
1764                 WL_ERR("WLC_SET_AUTH error (%d)\n", err);
1765 done:
1766         WL_TRACE("Exit\n");
1767         return err;
1768 }
1769
1770 static s32
1771 wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
1772                     u8 key_idx, bool pairwise, const u8 *mac_addr)
1773 {
1774         struct wl_wsec_key key;
1775         s32 err = 0;
1776         s32 val;
1777         s32 wsec;
1778
1779         WL_TRACE("Enter\n");
1780         CHECK_SYS_UP();
1781         memset(&key, 0, sizeof(key));
1782
1783         key.index = (u32) key_idx;
1784         key.flags = WL_PRIMARY_KEY;
1785         key.algo = CRYPTO_ALGO_OFF;
1786
1787         WL_CONN("key index (%d)\n", key_idx);
1788         /* Set the new key/index */
1789         swap_key_from_BE(&key);
1790         err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
1791         if (unlikely(err)) {
1792                 if (err == -EINVAL) {
1793                         if (key.index >= DOT11_MAX_DEFAULT_KEYS)
1794                                 /* we ignore this key index in this case */
1795                                 WL_ERR("invalid key index (%d)\n", key_idx);
1796                 } else
1797                         WL_ERR("WLC_SET_KEY error (%d)\n", err);
1798
1799                 /* Ignore this error, may happen during DISASSOC */
1800                 err = -EAGAIN;
1801                 goto done;
1802         }
1803
1804         val = 0;
1805         err = wl_dev_intvar_get(dev, "wsec", &wsec);
1806         if (unlikely(err)) {
1807                 WL_ERR("get wsec error (%d)\n", err);
1808                 /* Ignore this error, may happen during DISASSOC */
1809                 err = -EAGAIN;
1810                 goto done;
1811         }
1812         wsec &= ~(WEP_ENABLED);
1813         wsec |= val;
1814         err = wl_dev_intvar_set(dev, "wsec", wsec);
1815         if (unlikely(err)) {
1816                 WL_ERR("set wsec error (%d)\n", err);
1817                 /* Ignore this error, may happen during DISASSOC */
1818                 err = -EAGAIN;
1819                 goto done;
1820         }
1821
1822         val = 0;                /* assume open key. otherwise 1 */
1823         val = cpu_to_le32(val);
1824         err = wl_dev_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val));
1825         if (unlikely(err)) {
1826                 WL_ERR("WLC_SET_AUTH error (%d)\n", err);
1827                 /* Ignore this error, may happen during DISASSOC */
1828                 err = -EAGAIN;
1829         }
1830 done:
1831         WL_TRACE("Exit\n");
1832         return err;
1833 }
1834
1835 static s32
1836 wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
1837                     u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
1838                     void (*callback) (void *cookie, struct key_params * params))
1839 {
1840         struct key_params params;
1841         struct wl_wsec_key key;
1842         struct wl_priv *wl = wiphy_to_wl(wiphy);
1843         struct wl_security *sec;
1844         s32 wsec;
1845         s32 err = 0;
1846
1847         WL_TRACE("Enter\n");
1848         WL_CONN("key index (%d)\n", key_idx);
1849         CHECK_SYS_UP();
1850
1851         memset(&key, 0, sizeof(key));
1852         key.index = key_idx;
1853         swap_key_to_BE(&key);
1854         memset(&params, 0, sizeof(params));
1855         params.key_len = (u8) min_t(u8, WLAN_MAX_KEY_LEN, key.len);
1856         memcpy(params.key, key.data, params.key_len);
1857
1858         err = wl_dev_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec));
1859         if (unlikely(err)) {
1860                 WL_ERR("WLC_GET_WSEC error (%d)\n", err);
1861                 /* Ignore this error, may happen during DISASSOC */
1862                 err = -EAGAIN;
1863                 goto done;
1864         }
1865         wsec = le32_to_cpu(wsec);
1866         switch (wsec) {
1867         case WEP_ENABLED:
1868                 sec = wl_read_prof(wl, WL_PROF_SEC);
1869                 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
1870                         params.cipher = WLAN_CIPHER_SUITE_WEP40;
1871                         WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1872                 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
1873                         params.cipher = WLAN_CIPHER_SUITE_WEP104;
1874                         WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1875                 }
1876                 break;
1877         case TKIP_ENABLED:
1878                 params.cipher = WLAN_CIPHER_SUITE_TKIP;
1879                 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1880                 break;
1881         case AES_ENABLED:
1882                 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
1883                 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1884                 break;
1885         default:
1886                 WL_ERR("Invalid algo (0x%x)\n", wsec);
1887                 err = -EINVAL;
1888                 goto done;
1889         }
1890         callback(cookie, &params);
1891
1892 done:
1893         WL_TRACE("Exit\n");
1894         return err;
1895 }
1896
1897 static s32
1898 wl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
1899                                     struct net_device *dev, u8 key_idx)
1900 {
1901         WL_INFO("Not supported\n");
1902
1903         CHECK_SYS_UP();
1904         return -EOPNOTSUPP;
1905 }
1906
1907 static s32
1908 wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
1909                         u8 *mac, struct station_info *sinfo)
1910 {
1911         struct wl_priv *wl = wiphy_to_wl(wiphy);
1912         scb_val_t scb_val;
1913         int rssi;
1914         s32 rate;
1915         s32 err = 0;
1916         u8 *bssid = wl_read_prof(wl, WL_PROF_BSSID);
1917
1918         WL_TRACE("Enter\n");
1919         CHECK_SYS_UP();
1920
1921         if (unlikely
1922             (memcmp(mac, bssid, ETH_ALEN))) {
1923                 WL_ERR("Wrong Mac address cfg_mac-%X:%X:%X:%X:%X:%X"
1924                         "wl_bssid-%X:%X:%X:%X:%X:%X\n",
1925                         mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
1926                         bssid[0], bssid[1], bssid[2], bssid[3],
1927                         bssid[4], bssid[5]);
1928                 err = -ENOENT;
1929                 goto done;
1930         }
1931
1932         /* Report the current tx rate */
1933         err = wl_dev_ioctl(dev, WLC_GET_RATE, &rate, sizeof(rate));
1934         if (err) {
1935                 WL_ERR("Could not get rate (%d)\n", err);
1936         } else {
1937                 rate = le32_to_cpu(rate);
1938                 sinfo->filled |= STATION_INFO_TX_BITRATE;
1939                 sinfo->txrate.legacy = rate * 5;
1940                 WL_CONN("Rate %d Mbps\n", rate / 2);
1941         }
1942
1943         if (test_bit(WL_STATUS_CONNECTED, &wl->status)) {
1944                 scb_val.val = 0;
1945                 err = wl_dev_ioctl(dev, WLC_GET_RSSI, &scb_val,
1946                                 sizeof(scb_val_t));
1947                 if (unlikely(err)) {
1948                         WL_ERR("Could not get rssi (%d)\n", err);
1949                 }
1950                 rssi = le32_to_cpu(scb_val.val);
1951                 sinfo->filled |= STATION_INFO_SIGNAL;
1952                 sinfo->signal = rssi;
1953                 WL_CONN("RSSI %d dBm\n", rssi);
1954         }
1955
1956 done:
1957         WL_TRACE("Exit\n");
1958         return err;
1959 }
1960
1961 static s32
1962 wl_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
1963                            bool enabled, s32 timeout)
1964 {
1965         s32 pm;
1966         s32 err = 0;
1967
1968         WL_TRACE("Enter\n");
1969         CHECK_SYS_UP();
1970
1971         pm = enabled ? PM_FAST : PM_OFF;
1972         pm = cpu_to_le32(pm);
1973         WL_INFO("power save %s\n", (pm ? "enabled" : "disabled"));
1974
1975         err = wl_dev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm));
1976         if (unlikely(err)) {
1977                 if (err == -ENODEV)
1978                         WL_ERR("net_device is not ready yet\n");
1979                 else
1980                         WL_ERR("error (%d)\n", err);
1981         }
1982         WL_TRACE("Exit\n");
1983         return err;
1984 }
1985
1986 static __used u32 wl_find_msb(u16 bit16)
1987 {
1988         u32 ret = 0;
1989
1990         if (bit16 & 0xff00) {
1991                 ret += 8;
1992                 bit16 >>= 8;
1993         }
1994
1995         if (bit16 & 0xf0) {
1996                 ret += 4;
1997                 bit16 >>= 4;
1998         }
1999
2000         if (bit16 & 0xc) {
2001                 ret += 2;
2002                 bit16 >>= 2;
2003         }
2004
2005         if (bit16 & 2)
2006                 ret += bit16 & 2;
2007         else if (bit16)
2008                 ret += bit16;
2009
2010         return ret;
2011 }
2012
2013 static s32
2014 wl_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev,
2015                              const u8 *addr,
2016                              const struct cfg80211_bitrate_mask *mask)
2017 {
2018         struct wl_rateset rateset;
2019         s32 rate;
2020         s32 val;
2021         s32 err_bg;
2022         s32 err_a;
2023         u32 legacy;
2024         s32 err = 0;
2025
2026         WL_TRACE("Enter\n");
2027         CHECK_SYS_UP();
2028
2029         /* addr param is always NULL. ignore it */
2030         /* Get current rateset */
2031         err = wl_dev_ioctl(dev, WLC_GET_CURR_RATESET, &rateset,
2032                         sizeof(rateset));
2033         if (unlikely(err)) {
2034                 WL_ERR("could not get current rateset (%d)\n", err);
2035                 goto done;
2036         }
2037
2038         rateset.count = le32_to_cpu(rateset.count);
2039
2040         legacy = wl_find_msb(mask->control[IEEE80211_BAND_2GHZ].legacy);
2041         if (!legacy)
2042                 legacy = wl_find_msb(mask->control[IEEE80211_BAND_5GHZ].legacy);
2043
2044         val = wl_g_rates[legacy - 1].bitrate * 100000;
2045
2046         if (val < rateset.count)
2047                 /* Select rate by rateset index */
2048                 rate = rateset.rates[val] & 0x7f;
2049         else
2050                 /* Specified rate in bps */
2051                 rate = val / 500000;
2052
2053         WL_CONN("rate %d mbps\n", rate / 2);
2054
2055         /*
2056          *
2057          *      Set rate override,
2058          *      Since the is a/b/g-blind, both a/bg_rate are enforced.
2059          */
2060         err_bg = wl_dev_intvar_set(dev, "bg_rate", rate);
2061         err_a = wl_dev_intvar_set(dev, "a_rate", rate);
2062         if (unlikely(err_bg && err_a)) {
2063                 WL_ERR("could not set fixed rate (%d) (%d)\n", err_bg, err_a);
2064                 err = err_bg | err_a;
2065         }
2066
2067 done:
2068         WL_TRACE("Exit\n");
2069         return err;
2070 }
2071
2072 static s32 wl_cfg80211_resume(struct wiphy *wiphy)
2073 {
2074         struct wl_priv *wl = wiphy_to_wl(wiphy);
2075         struct net_device *ndev = wl_to_ndev(wl);
2076
2077         /*
2078          * Check for WL_STATUS_READY before any function call which
2079          * could result is bus access. Don't block the resume for
2080          * any driver error conditions
2081          */
2082         WL_TRACE("Enter\n");
2083
2084 #if defined(CONFIG_PM_SLEEP)
2085         atomic_set(&dhd_mmc_suspend, false);
2086 #endif  /*  defined(CONFIG_PM_SLEEP) */
2087
2088         if (test_bit(WL_STATUS_READY, &wl->status)) {
2089                 /* Turn on Watchdog timer */
2090                 wl_os_wd_timer(ndev, dhd_watchdog_ms);
2091                 wl_invoke_iscan(wiphy_to_wl(wiphy));
2092         }
2093
2094         WL_TRACE("Exit\n");
2095         return 0;
2096 }
2097
2098 static s32 wl_cfg80211_suspend(struct wiphy *wiphy)
2099 {
2100         struct wl_priv *wl = wiphy_to_wl(wiphy);
2101         struct net_device *ndev = wl_to_ndev(wl);
2102
2103         WL_TRACE("Enter\n");
2104
2105         /*
2106          * Check for WL_STATUS_READY before any function call which
2107          * could result is bus access. Don't block the suspend for
2108          * any driver error conditions
2109          */
2110
2111         /*
2112          * While going to suspend if associated with AP disassociate
2113          * from AP to save power while system is in suspended state
2114          */
2115         if (test_bit(WL_STATUS_CONNECTED, &wl->status) &&
2116                 test_bit(WL_STATUS_READY, &wl->status)) {
2117                 WL_INFO("Disassociating from AP"
2118                         " while entering suspend state\n");
2119                 wl_link_down(wl);
2120
2121                 /*
2122                  * Make sure WPA_Supplicant receives all the event
2123                  * generated due to DISASSOC call to the fw to keep
2124                  * the state fw and WPA_Supplicant state consistent
2125                  */
2126                 rtnl_unlock();
2127                 wl_delay(500);
2128                 rtnl_lock();
2129         }
2130
2131         set_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
2132         if (test_bit(WL_STATUS_READY, &wl->status))
2133                 wl_term_iscan(wl);
2134
2135         if (wl->scan_request) {
2136                 /* Indidate scan abort to cfg80211 layer */
2137                 WL_INFO("Terminating scan in progress\n");
2138                 cfg80211_scan_done(wl->scan_request, true);
2139                 wl->scan_request = NULL;
2140         }
2141         clear_bit(WL_STATUS_SCANNING, &wl->status);
2142         clear_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
2143         clear_bit(WL_STATUS_CONNECTING, &wl->status);
2144         clear_bit(WL_STATUS_CONNECTED, &wl->status);
2145
2146         /* Inform SDIO stack not to switch off power to the chip */
2147         sdioh_sdio_set_host_pm_flags(MMC_PM_KEEP_POWER);
2148
2149         /* Turn off watchdog timer */
2150         if (test_bit(WL_STATUS_READY, &wl->status)) {
2151                 WL_INFO("Terminate watchdog timer and enable MPC\n");
2152                 wl_set_mpc(ndev, 1);
2153                 wl_os_wd_timer(ndev, 0);
2154         }
2155
2156 #if defined(CONFIG_PM_SLEEP)
2157         atomic_set(&dhd_mmc_suspend, true);
2158 #endif  /*  defined(CONFIG_PM_SLEEP) */
2159
2160         WL_TRACE("Exit\n");
2161
2162         return 0;
2163 }
2164
2165 static __used s32
2166 wl_update_pmklist(struct net_device *dev, struct wl_pmk_list *pmk_list,
2167                   s32 err)
2168 {
2169         int i, j;
2170
2171         WL_CONN("No of elements %d\n", pmk_list->pmkids.npmkid);
2172         for (i = 0; i < pmk_list->pmkids.npmkid; i++) {
2173                 WL_CONN("PMKID[%d]: %pM =\n", i,
2174                         &pmk_list->pmkids.pmkid[i].BSSID);
2175                 for (j = 0; j < WLAN_PMKID_LEN; j++)
2176                         WL_CONN("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]);
2177         }
2178
2179         if (likely(!err))
2180                 wl_dev_bufvar_set(dev, "pmkid_info", (char *)pmk_list,
2181                                         sizeof(*pmk_list));
2182
2183         return err;
2184 }
2185
2186 static s32
2187 wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
2188                       struct cfg80211_pmksa *pmksa)
2189 {
2190         struct wl_priv *wl = wiphy_to_wl(wiphy);
2191         s32 err = 0;
2192         int i;
2193
2194         WL_TRACE("Enter\n");
2195         CHECK_SYS_UP();
2196
2197         for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++)
2198                 if (!memcmp(pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID,
2199                             ETH_ALEN))
2200                         break;
2201         if (i < WL_NUM_PMKIDS_MAX) {
2202                 memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID, pmksa->bssid,
2203                        ETH_ALEN);
2204                 memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID, pmksa->pmkid,
2205                        WLAN_PMKID_LEN);
2206                 if (i == wl->pmk_list->pmkids.npmkid)
2207                         wl->pmk_list->pmkids.npmkid++;
2208         } else
2209                 err = -EINVAL;
2210
2211         WL_CONN("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2212                &wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid].BSSID);
2213         for (i = 0; i < WLAN_PMKID_LEN; i++)
2214                 WL_CONN("%02x\n",
2215                        wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid].
2216                        PMKID[i]);
2217
2218         err = wl_update_pmklist(dev, wl->pmk_list, err);
2219
2220         WL_TRACE("Exit\n");
2221         return err;
2222 }
2223
2224 static s32
2225 wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
2226                       struct cfg80211_pmksa *pmksa)
2227 {
2228         struct wl_priv *wl = wiphy_to_wl(wiphy);
2229         struct _pmkid_list pmkid;
2230         s32 err = 0;
2231         int i;
2232
2233         WL_TRACE("Enter\n");
2234         CHECK_SYS_UP();
2235         memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
2236         memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2237
2238         WL_CONN("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2239                &pmkid.pmkid[0].BSSID);
2240         for (i = 0; i < WLAN_PMKID_LEN; i++)
2241                 WL_CONN("%02x\n", pmkid.pmkid[0].PMKID[i]);
2242
2243         for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++)
2244                 if (!memcmp
2245                     (pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID,
2246                      ETH_ALEN))
2247                         break;
2248
2249         if ((wl->pmk_list->pmkids.npmkid > 0)
2250             && (i < wl->pmk_list->pmkids.npmkid)) {
2251                 memset(&wl->pmk_list->pmkids.pmkid[i], 0, sizeof(pmkid_t));
2252                 for (; i < (wl->pmk_list->pmkids.npmkid - 1); i++) {
2253                         memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID,
2254                                &wl->pmk_list->pmkids.pmkid[i + 1].BSSID,
2255                                ETH_ALEN);
2256                         memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID,
2257                                &wl->pmk_list->pmkids.pmkid[i + 1].PMKID,
2258                                WLAN_PMKID_LEN);
2259                 }
2260                 wl->pmk_list->pmkids.npmkid--;
2261         } else
2262                 err = -EINVAL;
2263
2264         err = wl_update_pmklist(dev, wl->pmk_list, err);
2265
2266         WL_TRACE("Exit\n");
2267         return err;
2268
2269 }
2270
2271 static s32
2272 wl_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
2273 {
2274         struct wl_priv *wl = wiphy_to_wl(wiphy);
2275         s32 err = 0;
2276
2277         WL_TRACE("Enter\n");
2278         CHECK_SYS_UP();
2279
2280         memset(wl->pmk_list, 0, sizeof(*wl->pmk_list));
2281         err = wl_update_pmklist(dev, wl->pmk_list, err);
2282
2283         WL_TRACE("Exit\n");
2284         return err;
2285
2286 }
2287
2288 static struct cfg80211_ops wl_cfg80211_ops = {
2289         .change_virtual_intf = wl_cfg80211_change_iface,
2290         .scan = wl_cfg80211_scan,
2291         .set_wiphy_params = wl_cfg80211_set_wiphy_params,
2292         .join_ibss = wl_cfg80211_join_ibss,
2293         .leave_ibss = wl_cfg80211_leave_ibss,
2294         .get_station = wl_cfg80211_get_station,
2295         .set_tx_power = wl_cfg80211_set_tx_power,
2296         .get_tx_power = wl_cfg80211_get_tx_power,
2297         .add_key = wl_cfg80211_add_key,
2298         .del_key = wl_cfg80211_del_key,
2299         .get_key = wl_cfg80211_get_key,
2300         .set_default_key = wl_cfg80211_config_default_key,
2301         .set_default_mgmt_key = wl_cfg80211_config_default_mgmt_key,
2302         .set_power_mgmt = wl_cfg80211_set_power_mgmt,
2303         .set_bitrate_mask = wl_cfg80211_set_bitrate_mask,
2304         .connect = wl_cfg80211_connect,
2305         .disconnect = wl_cfg80211_disconnect,
2306         .suspend = wl_cfg80211_suspend,
2307         .resume = wl_cfg80211_resume,
2308         .set_pmksa = wl_cfg80211_set_pmksa,
2309         .del_pmksa = wl_cfg80211_del_pmksa,
2310         .flush_pmksa = wl_cfg80211_flush_pmksa
2311 };
2312
2313 static s32 wl_mode_to_nl80211_iftype(s32 mode)
2314 {
2315         s32 err = 0;
2316
2317         switch (mode) {
2318         case WL_MODE_BSS:
2319                 return NL80211_IFTYPE_STATION;
2320         case WL_MODE_IBSS:
2321                 return NL80211_IFTYPE_ADHOC;
2322         default:
2323                 return NL80211_IFTYPE_UNSPECIFIED;
2324         }
2325
2326         return err;
2327 }
2328
2329 static struct wireless_dev *wl_alloc_wdev(s32 sizeof_iface,
2330                                           struct device *dev)
2331 {
2332         struct wireless_dev *wdev;
2333         s32 err = 0;
2334
2335         wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
2336         if (unlikely(!wdev)) {
2337                 WL_ERR("Could not allocate wireless device\n");
2338                 return ERR_PTR(-ENOMEM);
2339         }
2340         wdev->wiphy =
2341             wiphy_new(&wl_cfg80211_ops, sizeof(struct wl_priv) + sizeof_iface);
2342         if (unlikely(!wdev->wiphy)) {
2343                 WL_ERR("Couldn not allocate wiphy device\n");
2344                 err = -ENOMEM;
2345                 goto wiphy_new_out;
2346         }
2347         set_wiphy_dev(wdev->wiphy, dev);
2348         wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
2349         wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
2350         wdev->wiphy->interface_modes =
2351             BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
2352         wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
2353         wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a;    /* Set
2354                                                 * it as 11a by default.
2355                                                 * This will be updated with
2356                                                 * 11n phy tables in
2357                                                 * "ifconfig up"
2358                                                 * if phy has 11n capability
2359                                                 */
2360         wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2361         wdev->wiphy->cipher_suites = __wl_cipher_suites;
2362         wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
2363 #ifndef WL_POWERSAVE_DISABLED
2364         wdev->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;      /* enable power
2365                                                                  * save mode
2366                                                                  * by default
2367                                                                  */
2368 #else
2369         wdev->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
2370 #endif                          /* !WL_POWERSAVE_DISABLED */
2371         err = wiphy_register(wdev->wiphy);
2372         if (unlikely(err < 0)) {
2373                 WL_ERR("Couldn not register wiphy device (%d)\n", err);
2374                 goto wiphy_register_out;
2375         }
2376         return wdev;
2377
2378 wiphy_register_out:
2379         wiphy_free(wdev->wiphy);
2380
2381 wiphy_new_out:
2382         kfree(wdev);
2383
2384         return ERR_PTR(err);
2385 }
2386
2387 static void wl_free_wdev(struct wl_priv *wl)
2388 {
2389         struct wireless_dev *wdev = wl_to_wdev(wl);
2390
2391         if (unlikely(!wdev)) {
2392                 WL_ERR("wdev is invalid\n");
2393                 return;
2394         }
2395         wiphy_unregister(wdev->wiphy);
2396         wiphy_free(wdev->wiphy);
2397         kfree(wdev);
2398         wl_to_wdev(wl) = NULL;
2399 }
2400
2401 static s32 wl_inform_bss(struct wl_priv *wl)
2402 {
2403         struct wl_scan_results *bss_list;
2404         struct wl_bss_info *bi = NULL;  /* must be initialized */
2405         s32 err = 0;
2406         int i;
2407
2408         bss_list = wl->bss_list;
2409         if (unlikely(bss_list->version != WL_BSS_INFO_VERSION)) {
2410                 WL_ERR("Version %d != WL_BSS_INFO_VERSION\n",
2411                        bss_list->version);
2412                 return -EOPNOTSUPP;
2413         }
2414         WL_SCAN("scanned AP count (%d)\n", bss_list->count);
2415         bi = next_bss(bss_list, bi);
2416         for_each_bss(bss_list, bi, i) {
2417                 err = wl_inform_single_bss(wl, bi);
2418                 if (unlikely(err))
2419                         break;
2420         }
2421         return err;
2422 }
2423
2424
2425 static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi)
2426 {
2427         struct wiphy *wiphy = wl_to_wiphy(wl);
2428         struct ieee80211_channel *notify_channel;
2429         struct cfg80211_bss *bss;
2430         struct ieee80211_supported_band *band;
2431         s32 err = 0;
2432         u16 channel;
2433         u32 freq;
2434         u64 notify_timestamp;
2435         u16 notify_capability;
2436         u16 notify_interval;
2437         u8 *notify_ie;
2438         size_t notify_ielen;
2439         s32 notify_signal;
2440
2441         if (unlikely(le32_to_cpu(bi->length) > WL_BSS_INFO_MAX)) {
2442                 WL_ERR("Bss info is larger than buffer. Discarding\n");
2443                 return 0;
2444         }
2445
2446         channel = bi->ctl_ch ? bi->ctl_ch :
2447                                 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2448
2449         if (channel <= CH_MAX_2G_CHANNEL)
2450                 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2451         else
2452                 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2453
2454         freq = ieee80211_channel_to_frequency(channel, band->band);
2455         notify_channel = ieee80211_get_channel(wiphy, freq);
2456
2457         notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */
2458         notify_capability = le16_to_cpu(bi->capability);
2459         notify_interval = le16_to_cpu(bi->beacon_period);
2460         notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2461         notify_ielen = le16_to_cpu(bi->ie_length);
2462         notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2463
2464         WL_CONN("bssid: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
2465                         bi->BSSID[0], bi->BSSID[1], bi->BSSID[2],
2466                         bi->BSSID[3], bi->BSSID[4], bi->BSSID[5]);
2467         WL_CONN("Channel: %d(%d)\n", channel, freq);
2468         WL_CONN("Capability: %X\n", notify_capability);
2469         WL_CONN("Beacon interval: %d\n", notify_interval);
2470         WL_CONN("Signal: %d\n", notify_signal);
2471         WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp);
2472
2473         bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)bi->BSSID,
2474                 notify_timestamp, notify_capability, notify_interval, notify_ie,
2475                 notify_ielen, notify_signal, GFP_KERNEL);
2476
2477         if (unlikely(!bss)) {
2478                 WL_ERR("cfg80211_inform_bss_frame error\n");
2479                 return -EINVAL;
2480         }
2481
2482         return err;
2483 }
2484
2485 static s32
2486 wl_inform_ibss(struct wl_priv *wl, struct net_device *dev, const u8 *bssid)
2487 {
2488         struct wiphy *wiphy = wl_to_wiphy(wl);
2489         struct ieee80211_channel *notify_channel;
2490         struct wl_bss_info *bi = NULL;
2491         struct ieee80211_supported_band *band;
2492         u8 *buf = NULL;
2493         s32 err = 0;
2494         u16 channel;
2495         u32 freq;
2496         u64 notify_timestamp;
2497         u16 notify_capability;
2498         u16 notify_interval;
2499         u8 *notify_ie;
2500         size_t notify_ielen;
2501         s32 notify_signal;
2502
2503         WL_TRACE("Enter\n");
2504
2505         buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2506         if (buf == NULL) {
2507                 WL_ERR("kzalloc() failed\n");
2508                 err = -ENOMEM;
2509                 goto CleanUp;
2510         }
2511
2512         *(u32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
2513
2514         err = wl_dev_ioctl(dev, WLC_GET_BSS_INFO, buf, WL_BSS_INFO_MAX);
2515         if (unlikely(err)) {
2516                 WL_ERR("WLC_GET_BSS_INFO failed: %d\n", err);
2517                 goto CleanUp;
2518         }
2519
2520         bi = (wl_bss_info_t *)(buf + 4);
2521
2522         channel = bi->ctl_ch ? bi->ctl_ch :
2523                                 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2524
2525         if (channel <= CH_MAX_2G_CHANNEL)
2526                 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2527         else
2528                 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2529
2530         freq = ieee80211_channel_to_frequency(channel, band->band);
2531         notify_channel = ieee80211_get_channel(wiphy, freq);
2532
2533         notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */
2534         notify_capability = le16_to_cpu(bi->capability);
2535         notify_interval = le16_to_cpu(bi->beacon_period);
2536         notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2537         notify_ielen = le16_to_cpu(bi->ie_length);
2538         notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2539
2540         WL_CONN("channel: %d(%d)\n", channel, freq);
2541         WL_CONN("capability: %X\n", notify_capability);
2542         WL_CONN("beacon interval: %d\n", notify_interval);
2543         WL_CONN("signal: %d\n", notify_signal);
2544         WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp);
2545
2546         cfg80211_inform_bss(wiphy, notify_channel, bssid,
2547                 notify_timestamp, notify_capability, notify_interval,
2548                 notify_ie, notify_ielen, notify_signal, GFP_KERNEL);
2549
2550 CleanUp:
2551
2552         kfree(buf);
2553
2554         WL_TRACE("Exit\n");
2555
2556         return err;
2557 }
2558
2559 static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e)
2560 {
2561         u32 event = be32_to_cpu(e->event_type);
2562         u32 status = be32_to_cpu(e->status);
2563
2564         if (event == WLC_E_SET_SSID && status == WLC_E_STATUS_SUCCESS) {
2565                 WL_CONN("Processing set ssid\n");
2566                 wl->link_up = true;
2567                 return true;
2568         }
2569
2570         return false;
2571 }
2572
2573 static bool wl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e)
2574 {
2575         u32 event = be32_to_cpu(e->event_type);
2576         u16 flags = be16_to_cpu(e->flags);
2577
2578         if (event == WLC_E_LINK && (!(flags & WLC_EVENT_MSG_LINK))) {
2579                 WL_CONN("Processing link down\n");
2580                 return true;
2581         }
2582         return false;
2583 }
2584
2585 static bool wl_is_nonetwork(struct wl_priv *wl, const wl_event_msg_t *e)
2586 {
2587         u32 event = be32_to_cpu(e->event_type);
2588         u32 status = be32_to_cpu(e->status);
2589         u16 flags = be16_to_cpu(e->flags);
2590
2591         if (event == WLC_E_LINK && status == WLC_E_STATUS_NO_NETWORKS) {
2592                 WL_CONN("Processing Link %s & no network found\n",
2593                                 flags & WLC_EVENT_MSG_LINK ? "up" : "down");
2594                 return true;
2595         }
2596
2597         if (event == WLC_E_SET_SSID && status != WLC_E_STATUS_SUCCESS) {
2598                 WL_CONN("Processing connecting & no network found\n");
2599                 return true;
2600         }
2601
2602         return false;
2603 }
2604
2605 static s32
2606 wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
2607                          const wl_event_msg_t *e, void *data)
2608 {
2609         s32 err = 0;
2610
2611         if (wl_is_linkup(wl, e)) {
2612                 WL_CONN("Linkup\n");
2613                 if (wl_is_ibssmode(wl)) {
2614                         wl_update_prof(wl, NULL, (void *)e->addr,
2615                                 WL_PROF_BSSID);
2616                         wl_inform_ibss(wl, ndev, e->addr);
2617                         cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
2618                         clear_bit(WL_STATUS_CONNECTING, &wl->status);
2619                         set_bit(WL_STATUS_CONNECTED, &wl->status);
2620                 } else
2621                         wl_bss_connect_done(wl, ndev, e, data, true);
2622         } else if (wl_is_linkdown(wl, e)) {
2623                 WL_CONN("Linkdown\n");
2624                 if (wl_is_ibssmode(wl)) {
2625                         if (test_and_clear_bit(WL_STATUS_CONNECTED,
2626                                 &wl->status))
2627                                 wl_link_down(wl);
2628                 } else {
2629                         if (test_and_clear_bit(WL_STATUS_CONNECTED,
2630                                 &wl->status)) {
2631                                 cfg80211_disconnected(ndev, 0, NULL, 0,
2632                                         GFP_KERNEL);
2633                                 wl_link_down(wl);
2634                         }
2635                 }
2636                 wl_init_prof(wl->profile);
2637         } else if (wl_is_nonetwork(wl, e)) {
2638                 if (wl_is_ibssmode(wl))
2639                         clear_bit(WL_STATUS_CONNECTING, &wl->status);
2640                 else
2641                         wl_bss_connect_done(wl, ndev, e, data, false);
2642         }
2643
2644         return err;
2645 }
2646
2647 static s32
2648 wl_notify_roaming_status(struct wl_priv *wl, struct net_device *ndev,
2649                          const wl_event_msg_t *e, void *data)
2650 {
2651         s32 err = 0;
2652         u32 event = be32_to_cpu(e->event_type);
2653         u32 status = be32_to_cpu(e->status);
2654
2655         if (event == WLC_E_ROAM && status == WLC_E_STATUS_SUCCESS) {
2656                 if (test_bit(WL_STATUS_CONNECTED, &wl->status))
2657                         wl_bss_roaming_done(wl, ndev, e, data);
2658                 else
2659                         wl_bss_connect_done(wl, ndev, e, data, true);
2660         }
2661
2662         return err;
2663 }
2664
2665 static __used s32
2666 wl_dev_bufvar_set(struct net_device *dev, s8 *name, s8 *buf, s32 len)
2667 {
2668         struct wl_priv *wl = ndev_to_wl(dev);
2669         u32 buflen;
2670
2671         buflen = bcm_mkiovar(name, buf, len, wl->ioctl_buf, WL_IOCTL_LEN_MAX);
2672         BUG_ON(!buflen);
2673
2674         return wl_dev_ioctl(dev, WLC_SET_VAR, wl->ioctl_buf, buflen);
2675 }
2676
2677 static s32
2678 wl_dev_bufvar_get(struct net_device *dev, s8 *name, s8 *buf,
2679                   s32 buf_len)
2680 {
2681         struct wl_priv *wl = ndev_to_wl(dev);
2682         u32 len;
2683         s32 err = 0;
2684
2685         len = bcm_mkiovar(name, NULL, 0, wl->ioctl_buf, WL_IOCTL_LEN_MAX);
2686         BUG_ON(!len);
2687         err = wl_dev_ioctl(dev, WLC_GET_VAR, (void *)wl->ioctl_buf,
2688                         WL_IOCTL_LEN_MAX);
2689         if (unlikely(err)) {
2690                 WL_ERR("error (%d)\n", err);
2691                 return err;
2692         }
2693         memcpy(buf, wl->ioctl_buf, buf_len);
2694
2695         return err;
2696 }
2697
2698 static s32 wl_get_assoc_ies(struct wl_priv *wl)
2699 {
2700         struct net_device *ndev = wl_to_ndev(wl);
2701         struct wl_assoc_ielen *assoc_info;
2702         struct wl_connect_info *conn_info = wl_to_conn(wl);
2703         u32 req_len;
2704         u32 resp_len;
2705         s32 err = 0;
2706
2707         wl_clear_assoc_ies(wl);
2708
2709         err = wl_dev_bufvar_get(ndev, "assoc_info", wl->extra_buf,
2710                                 WL_ASSOC_INFO_MAX);
2711         if (unlikely(err)) {
2712                 WL_ERR("could not get assoc info (%d)\n", err);
2713                 return err;
2714         }
2715         assoc_info = (struct wl_assoc_ielen *)wl->extra_buf;
2716         req_len = assoc_info->req_len;
2717         resp_len = assoc_info->resp_len;
2718         if (req_len) {
2719                 err = wl_dev_bufvar_get(ndev, "assoc_req_ies", wl->extra_buf,
2720                                         WL_ASSOC_INFO_MAX);
2721                 if (unlikely(err)) {
2722                         WL_ERR("could not get assoc req (%d)\n", err);
2723                         return err;
2724                 }
2725                 conn_info->req_ie_len = req_len;
2726                 conn_info->req_ie =
2727                     kmemdup(wl->extra_buf, conn_info->req_ie_len, GFP_KERNEL);
2728         } else {
2729                 conn_info->req_ie_len = 0;
2730                 conn_info->req_ie = NULL;
2731         }
2732         if (resp_len) {
2733                 err = wl_dev_bufvar_get(ndev, "assoc_resp_ies", wl->extra_buf,
2734                                         WL_ASSOC_INFO_MAX);
2735                 if (unlikely(err)) {
2736                         WL_ERR("could not get assoc resp (%d)\n", err);
2737                         return err;
2738                 }
2739                 conn_info->resp_ie_len = resp_len;
2740                 conn_info->resp_ie =
2741                     kmemdup(wl->extra_buf, conn_info->resp_ie_len, GFP_KERNEL);
2742         } else {
2743                 conn_info->resp_ie_len = 0;
2744                 conn_info->resp_ie = NULL;
2745         }
2746         WL_CONN("req len (%d) resp len (%d)\n",
2747                conn_info->req_ie_len, conn_info->resp_ie_len);
2748
2749         return err;
2750 }
2751
2752 static void wl_clear_assoc_ies(struct wl_priv *wl)
2753 {
2754         struct wl_connect_info *conn_info = wl_to_conn(wl);
2755
2756         kfree(conn_info->req_ie);
2757         conn_info->req_ie = NULL;
2758         conn_info->req_ie_len = 0;
2759         kfree(conn_info->resp_ie);
2760         conn_info->resp_ie = NULL;
2761         conn_info->resp_ie_len = 0;
2762 }
2763
2764
2765 static void wl_ch_to_chanspec(int ch, struct wl_join_params *join_params,
2766         size_t *join_params_size)
2767 {
2768         chanspec_t chanspec = 0;
2769
2770         if (ch != 0) {
2771                 join_params->params.chanspec_num = 1;
2772                 join_params->params.chanspec_list[0] = ch;
2773
2774                 if (join_params->params.chanspec_list[0] <= CH_MAX_2G_CHANNEL)
2775                         chanspec |= WL_CHANSPEC_BAND_2G;
2776                 else
2777                         chanspec |= WL_CHANSPEC_BAND_5G;
2778
2779                 chanspec |= WL_CHANSPEC_BW_20;
2780                 chanspec |= WL_CHANSPEC_CTL_SB_NONE;
2781
2782                 *join_params_size += WL_ASSOC_PARAMS_FIXED_SIZE +
2783                         join_params->params.chanspec_num * sizeof(chanspec_t);
2784
2785                 join_params->params.chanspec_list[0] &= WL_CHANSPEC_CHAN_MASK;
2786                 join_params->params.chanspec_list[0] |= chanspec;
2787                 join_params->params.chanspec_list[0] =
2788                 cpu_to_le16(join_params->params.chanspec_list[0]);
2789
2790                 join_params->params.chanspec_num =
2791                         cpu_to_le32(join_params->params.chanspec_num);
2792
2793                 WL_CONN("join_params->params.chanspec_list[0]= %#X,"
2794                         "channel %d, chanspec %#X\n",
2795                        join_params->params.chanspec_list[0], ch, chanspec);
2796         }
2797 }
2798
2799 static s32 wl_update_bss_info(struct wl_priv *wl)
2800 {
2801         struct wl_bss_info *bi;
2802         struct wlc_ssid *ssid;
2803         struct bcm_tlv *tim;
2804         u16 beacon_interval;
2805         u8 dtim_period;
2806         size_t ie_len;
2807         u8 *ie;
2808         s32 err = 0;
2809
2810         WL_TRACE("Enter\n");
2811         if (wl_is_ibssmode(wl))
2812                 return err;
2813
2814         ssid = (struct wlc_ssid *)wl_read_prof(wl, WL_PROF_SSID);
2815
2816         *(u32 *)wl->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
2817         err = wl_dev_ioctl(wl_to_ndev(wl), WLC_GET_BSS_INFO,
2818                         wl->extra_buf, WL_EXTRA_BUF_MAX);
2819         if (unlikely(err)) {
2820                 WL_ERR("Could not get bss info %d\n", err);
2821                 goto update_bss_info_out;
2822         }
2823
2824         bi = (struct wl_bss_info *)(wl->extra_buf + 4);
2825         err = wl_inform_single_bss(wl, bi);
2826         if (unlikely(err))
2827                 goto update_bss_info_out;
2828
2829         ie = ((u8 *)bi) + bi->ie_offset;
2830         ie_len = bi->ie_length;
2831         beacon_interval = cpu_to_le16(bi->beacon_period);
2832
2833         tim = bcm_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
2834         if (tim)
2835                 dtim_period = tim->data[1];
2836         else {
2837                 /*
2838                 * active scan was done so we could not get dtim
2839                 * information out of probe response.
2840                 * so we speficially query dtim information to dongle.
2841                 */
2842                 u32 var;
2843                 err = wl_dev_intvar_get(wl_to_ndev(wl), "dtim_assoc", &var);
2844                 if (unlikely(err)) {
2845                         WL_ERR("wl dtim_assoc failed (%d)\n", err);
2846                         goto update_bss_info_out;
2847                 }
2848                 dtim_period = (u8)var;
2849         }
2850
2851         wl_update_prof(wl, NULL, &beacon_interval, WL_PROF_BEACONINT);
2852         wl_update_prof(wl, NULL, &dtim_period, WL_PROF_DTIMPERIOD);
2853
2854 update_bss_info_out:
2855         WL_TRACE("Exit");
2856         return err;
2857 }
2858
2859 static s32
2860 wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev,
2861                     const wl_event_msg_t *e, void *data)
2862 {
2863         struct wl_connect_info *conn_info = wl_to_conn(wl);
2864         s32 err = 0;
2865
2866         WL_TRACE("Enter\n");
2867
2868         wl_get_assoc_ies(wl);
2869         wl_update_prof(wl, NULL, &e->addr, WL_PROF_BSSID);
2870         wl_update_bss_info(wl);
2871
2872         cfg80211_roamed(ndev,
2873                         (u8 *)wl_read_prof(wl, WL_PROF_BSSID),
2874                         conn_info->req_ie, conn_info->req_ie_len,
2875                         conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
2876         WL_CONN("Report roaming result\n");
2877
2878         set_bit(WL_STATUS_CONNECTED, &wl->status);
2879         WL_TRACE("Exit\n");
2880         return err;
2881 }
2882
2883 static s32
2884 wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
2885                     const wl_event_msg_t *e, void *data, bool completed)
2886 {
2887         struct wl_connect_info *conn_info = wl_to_conn(wl);
2888         s32 err = 0;
2889
2890         WL_TRACE("Enter\n");
2891
2892         if (test_and_clear_bit(WL_STATUS_CONNECTING, &wl->status)) {
2893                 if (completed) {
2894                         wl_get_assoc_ies(wl);
2895                         wl_update_prof(wl, NULL, &e->addr, WL_PROF_BSSID);
2896                         wl_update_bss_info(wl);
2897                 }
2898                 cfg80211_connect_result(ndev,
2899                                         (u8 *)wl_read_prof(wl, WL_PROF_BSSID),
2900                                         conn_info->req_ie,
2901                                         conn_info->req_ie_len,
2902                                         conn_info->resp_ie,
2903                                         conn_info->resp_ie_len,
2904                                         completed ? WLAN_STATUS_SUCCESS : WLAN_STATUS_AUTH_TIMEOUT,
2905                                         GFP_KERNEL);
2906                 if (completed)
2907                         set_bit(WL_STATUS_CONNECTED, &wl->status);
2908                 WL_CONN("Report connect result - connection %s\n",
2909                                 completed ? "succeeded" : "failed");
2910         }
2911         WL_TRACE("Exit\n");
2912         return err;
2913 }
2914
2915 static s32
2916 wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev,
2917                      const wl_event_msg_t *e, void *data)
2918 {
2919         u16 flags = be16_to_cpu(e->flags);
2920         enum nl80211_key_type key_type;
2921
2922         rtnl_lock();
2923         if (flags & WLC_EVENT_MSG_GROUP)
2924                 key_type = NL80211_KEYTYPE_GROUP;
2925         else
2926