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