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