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