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