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