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