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