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