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