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