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