]> git.karo-electronics.de Git - mv-sheeva.git/blob - drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c
staging: brcm80211: brcmfmac: enable passive, active scan selection
[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 __used 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 passive_scan;
736         s32 err = 0;
737
738         /* Broadcast scan by default */
739         memset(&ssid, 0, sizeof(ssid));
740
741         iscan->state = WL_ISCAN_STATE_SCANING;
742
743         passive_scan = wl->active_scan ? 0 : 1;
744         err = wl_dev_ioctl(wl_to_ndev(wl), WLC_SET_PASSIVE_SCAN,
745                         &passive_scan, sizeof(passive_scan));
746         if (unlikely(err)) {
747                 WL_DBG(("error (%d)\n", err));
748                 return err;
749         }
750         wl_set_mpc(ndev, 0);
751         wl->iscan_kickstart = true;
752         wl_run_iscan(iscan, &ssid, WL_SCAN_ACTION_START);
753         mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
754         iscan->timer_on = 1;
755
756         return err;
757 }
758
759 static s32
760 __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
761                    struct cfg80211_scan_request *request,
762                    struct cfg80211_ssid *this_ssid)
763 {
764         struct wl_priv *wl = ndev_to_wl(ndev);
765         struct cfg80211_ssid *ssids;
766         struct wl_scan_req *sr = wl_to_sr(wl);
767         s32 passive_scan;
768         bool iscan_req;
769         bool spec_scan;
770         s32 err = 0;
771
772         if (unlikely(test_bit(WL_STATUS_SCANNING, &wl->status))) {
773                 WL_ERR(("Scanning already : status (%d)\n", (int)wl->status));
774                 return -EAGAIN;
775         }
776         if (unlikely(test_bit(WL_STATUS_SCAN_ABORTING, &wl->status))) {
777                 WL_ERR(("Scanning being aborted : status (%d)\n",
778                         (int)wl->status));
779                 return -EAGAIN;
780         }
781
782         iscan_req = false;
783         spec_scan = false;
784         if (request) {          /* scan bss */
785                 ssids = request->ssids;
786                 if (wl->iscan_on && (!ssids || !ssids->ssid_len)) {     /* for
787                                                          * specific scan,
788                                                          * ssids->ssid_len has
789                                                          * non-zero(ssid string)
790                                                          * length.
791                                                          * Otherwise this is 0.
792                                                          * we do not iscan for
793                                                          * specific scan request
794                                                          */
795                         iscan_req = true;
796                 }
797         } else {                /* scan in ibss */
798                 /* we don't do iscan in ibss */
799                 ssids = this_ssid;
800         }
801         wl->scan_request = request;
802         set_bit(WL_STATUS_SCANNING, &wl->status);
803         if (iscan_req) {
804                 err = wl_do_iscan(wl);
805                 if (likely(!err))
806                         return err;
807                 else
808                         goto scan_out;
809         } else {
810                 WL_DBG(("ssid \"%s\", ssid_len (%d)\n",
811                         ssids->ssid, ssids->ssid_len));
812                 memset(&sr->ssid, 0, sizeof(sr->ssid));
813                 sr->ssid.SSID_len =
814                             min_t(u8, sizeof(sr->ssid.SSID), ssids->ssid_len);
815                 if (sr->ssid.SSID_len) {
816                         memcpy(sr->ssid.SSID, ssids->ssid, sr->ssid.SSID_len);
817                         sr->ssid.SSID_len = htod32(sr->ssid.SSID_len);
818                         WL_DBG(("Specific scan ssid=\"%s\" len=%d\n",
819                                         sr->ssid.SSID, sr->ssid.SSID_len));
820                         spec_scan = true;
821                 } else {
822                         WL_DBG(("Broadcast scan\n"));
823                 }
824                 WL_DBG(("sr->ssid.SSID_len (%d)\n", sr->ssid.SSID_len));
825                 passive_scan = wl->active_scan ? 0 : 1;
826                 err = wl_dev_ioctl(ndev, WLC_SET_PASSIVE_SCAN,
827                                 &passive_scan, sizeof(passive_scan));
828                 if (unlikely(err)) {
829                         WL_ERR(("WLC_SET_PASSIVE_SCAN error (%d)\n", err));
830                         goto scan_out;
831                 }
832                 wl_set_mpc(ndev, 0);
833                 err = wl_dev_ioctl(ndev, WLC_SCAN, &sr->ssid,
834                                 sizeof(sr->ssid));
835                 if (err) {
836                         if (err == -EBUSY) {
837                                 WL_INFO(("system busy : scan for \"%s\" "
838                                         "canceled\n", sr->ssid.SSID));
839                         } else {
840                                 WL_ERR(("WLC_SCAN error (%d)\n", err));
841                         }
842                         wl_set_mpc(ndev, 1);
843                         goto scan_out;
844                 }
845         }
846
847         return 0;
848
849 scan_out:
850         clear_bit(WL_STATUS_SCANNING, &wl->status);
851         wl->scan_request = NULL;
852         return err;
853 }
854
855 static s32
856 wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
857                  struct cfg80211_scan_request *request)
858 {
859         s32 err = 0;
860
861         CHECK_SYS_UP();
862         err = __wl_cfg80211_scan(wiphy, ndev, request, NULL);
863         if (unlikely(err)) {
864                 WL_DBG(("scan error (%d)\n", err));
865                 return err;
866         }
867
868         return err;
869 }
870
871 static s32 wl_dev_intvar_set(struct net_device *dev, s8 *name, s32 val)
872 {
873         s8 buf[WLC_IOCTL_SMLEN];
874         u32 len;
875         s32 err = 0;
876
877         val = htod32(val);
878         len = bcm_mkiovar(name, (char *)(&val), sizeof(val), buf, sizeof(buf));
879         BUG_ON(unlikely(!len));
880
881         err = wl_dev_ioctl(dev, WLC_SET_VAR, buf, len);
882         if (unlikely(err)) {
883                 WL_ERR(("error (%d)\n", err));
884         }
885
886         return err;
887 }
888
889 static s32
890 wl_dev_intvar_get(struct net_device *dev, s8 *name, s32 *retval)
891 {
892         union {
893                 s8 buf[WLC_IOCTL_SMLEN];
894                 s32 val;
895         } var;
896         u32 len;
897         u32 data_null;
898         s32 err = 0;
899
900         len =
901             bcm_mkiovar(name, (char *)(&data_null), 0, (char *)(&var),
902                         sizeof(var.buf));
903         BUG_ON(unlikely(!len));
904         err = wl_dev_ioctl(dev, WLC_GET_VAR, &var, len);
905         if (unlikely(err)) {
906                 WL_ERR(("error (%d)\n", err));
907         }
908         *retval = dtoh32(var.val);
909
910         return err;
911 }
912
913 static s32 wl_set_rts(struct net_device *dev, u32 rts_threshold)
914 {
915         s32 err = 0;
916
917         err = wl_dev_intvar_set(dev, "rtsthresh", rts_threshold);
918         if (unlikely(err)) {
919                 WL_ERR(("Error (%d)\n", err));
920                 return err;
921         }
922         return err;
923 }
924
925 static s32 wl_set_frag(struct net_device *dev, u32 frag_threshold)
926 {
927         s32 err = 0;
928
929         err = wl_dev_intvar_set(dev, "fragthresh", frag_threshold);
930         if (unlikely(err)) {
931                 WL_ERR(("Error (%d)\n", err));
932                 return err;
933         }
934         return err;
935 }
936
937 static s32 wl_set_retry(struct net_device *dev, u32 retry, bool l)
938 {
939         s32 err = 0;
940         u32 cmd = (l ? WLC_SET_LRL : WLC_SET_SRL);
941
942         retry = htod32(retry);
943         err = wl_dev_ioctl(dev, cmd, &retry, sizeof(retry));
944         if (unlikely(err)) {
945                 WL_ERR(("cmd (%d) , error (%d)\n", cmd, err));
946                 return err;
947         }
948         return err;
949 }
950
951 static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
952 {
953         struct wl_priv *wl = wiphy_to_wl(wiphy);
954         struct net_device *ndev = wl_to_ndev(wl);
955         s32 err = 0;
956
957         CHECK_SYS_UP();
958         if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
959             (wl->conf->rts_threshold != wiphy->rts_threshold)) {
960                 wl->conf->rts_threshold = wiphy->rts_threshold;
961                 err = wl_set_rts(ndev, wl->conf->rts_threshold);
962                 if (!err)
963                         return err;
964         }
965         if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
966             (wl->conf->frag_threshold != wiphy->frag_threshold)) {
967                 wl->conf->frag_threshold = wiphy->frag_threshold;
968                 err = wl_set_frag(ndev, wl->conf->frag_threshold);
969                 if (!err)
970                         return err;
971         }
972         if (changed & WIPHY_PARAM_RETRY_LONG
973             && (wl->conf->retry_long != wiphy->retry_long)) {
974                 wl->conf->retry_long = wiphy->retry_long;
975                 err = wl_set_retry(ndev, wl->conf->retry_long, true);
976                 if (!err)
977                         return err;
978         }
979         if (changed & WIPHY_PARAM_RETRY_SHORT
980             && (wl->conf->retry_short != wiphy->retry_short)) {
981                 wl->conf->retry_short = wiphy->retry_short;
982                 err = wl_set_retry(ndev, wl->conf->retry_short, false);
983                 if (!err) {
984                         return err;
985                 }
986         }
987
988         return err;
989 }
990
991 static s32
992 wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
993                       struct cfg80211_ibss_params *params)
994 {
995         struct wl_priv *wl = wiphy_to_wl(wiphy);
996         struct cfg80211_bss *bss;
997         struct ieee80211_channel *chan;
998         struct wl_join_params join_params;
999         struct cfg80211_ssid ssid;
1000         s32 scan_retry = 0;
1001         s32 err = 0;
1002
1003         CHECK_SYS_UP();
1004         if (params->bssid) {
1005                 WL_ERR(("Invalid bssid\n"));
1006                 return -EOPNOTSUPP;
1007         }
1008         bss = cfg80211_get_ibss(wiphy, NULL, params->ssid, params->ssid_len);
1009         if (!bss) {
1010                 memcpy(ssid.ssid, params->ssid, params->ssid_len);
1011                 ssid.ssid_len = params->ssid_len;
1012                 do {
1013                         if (unlikely
1014                             (__wl_cfg80211_scan(wiphy, dev, NULL, &ssid) ==
1015                              -EBUSY)) {
1016                                 wl_delay(150);
1017                         } else {
1018                                 break;
1019                         }
1020                 } while (++scan_retry < WL_SCAN_RETRY_MAX);
1021                 rtnl_unlock();  /* to allow scan_inform to paropagate
1022                                          to cfg80211 plane */
1023                 schedule_timeout_interruptible(4 * HZ); /* wait 4 secons
1024                                                  till scan done.... */
1025                 rtnl_lock();
1026                 bss = cfg80211_get_ibss(wiphy, NULL,
1027                                         params->ssid, params->ssid_len);
1028         }
1029         if (bss) {
1030                 wl->ibss_starter = false;
1031                 WL_DBG(("Found IBSS\n"));
1032         } else {
1033                 wl->ibss_starter = true;
1034         }
1035         chan = params->channel;
1036         if (chan)
1037                 wl->channel = ieee80211_frequency_to_channel(chan->center_freq);
1038         /*
1039          ** Join with specific BSSID and cached SSID
1040          ** If SSID is zero join based on BSSID only
1041          */
1042         memset(&join_params, 0, sizeof(join_params));
1043         memcpy((void *)join_params.ssid.SSID, (void *)params->ssid,
1044                params->ssid_len);
1045         join_params.ssid.SSID_len = htod32(params->ssid_len);
1046         if (params->bssid)
1047                 memcpy(&join_params.params.bssid, params->bssid,
1048                        ETHER_ADDR_LEN);
1049         else
1050                 memset(&join_params.params.bssid, 0, ETHER_ADDR_LEN);
1051
1052         err = wl_dev_ioctl(dev, WLC_SET_SSID, &join_params,
1053                         sizeof(join_params));
1054         if (unlikely(err)) {
1055                 WL_ERR(("Error (%d)\n", err));
1056                 return err;
1057         }
1058         return err;
1059 }
1060
1061 static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
1062 {
1063         struct wl_priv *wl = wiphy_to_wl(wiphy);
1064         s32 err = 0;
1065
1066         CHECK_SYS_UP();
1067         wl_link_down(wl);
1068
1069         return err;
1070 }
1071
1072 static s32
1073 wl_set_wpa_version(struct net_device *dev, struct cfg80211_connect_params *sme)
1074 {
1075         struct wl_priv *wl = ndev_to_wl(dev);
1076         struct wl_security *sec;
1077         s32 val = 0;
1078         s32 err = 0;
1079
1080         if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1081                 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
1082         else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1083                 val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
1084         else
1085                 val = WPA_AUTH_DISABLED;
1086         WL_DBG(("setting wpa_auth to 0x%0x\n", val));
1087         err = wl_dev_intvar_set(dev, "wpa_auth", val);
1088         if (unlikely(err)) {
1089                 WL_ERR(("set wpa_auth failed (%d)\n", err));
1090                 return err;
1091         }
1092         sec = wl_read_prof(wl, WL_PROF_SEC);
1093         sec->wpa_versions = sme->crypto.wpa_versions;
1094         return err;
1095 }
1096
1097 static s32
1098 wl_set_auth_type(struct net_device *dev, struct cfg80211_connect_params *sme)
1099 {
1100         struct wl_priv *wl = ndev_to_wl(dev);
1101         struct wl_security *sec;
1102         s32 val = 0;
1103         s32 err = 0;
1104
1105         switch (sme->auth_type) {
1106         case NL80211_AUTHTYPE_OPEN_SYSTEM:
1107                 val = 0;
1108                 WL_DBG(("open system\n"));
1109                 break;
1110         case NL80211_AUTHTYPE_SHARED_KEY:
1111                 val = 1;
1112                 WL_DBG(("shared key\n"));
1113                 break;
1114         case NL80211_AUTHTYPE_AUTOMATIC:
1115                 val = 2;
1116                 WL_DBG(("automatic\n"));
1117                 break;
1118         case NL80211_AUTHTYPE_NETWORK_EAP:
1119                 WL_DBG(("network eap\n"));
1120         default:
1121                 val = 2;
1122                 WL_ERR(("invalid auth type (%d)\n", sme->auth_type));
1123                 break;
1124         }
1125
1126         err = wl_dev_intvar_set(dev, "auth", val);
1127         if (unlikely(err)) {
1128                 WL_ERR(("set auth failed (%d)\n", err));
1129                 return err;
1130         }
1131         sec = wl_read_prof(wl, WL_PROF_SEC);
1132         sec->auth_type = sme->auth_type;
1133         return err;
1134 }
1135
1136 static s32
1137 wl_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme)
1138 {
1139         struct wl_priv *wl = ndev_to_wl(dev);
1140         struct wl_security *sec;
1141         s32 pval = 0;
1142         s32 gval = 0;
1143         s32 err = 0;
1144
1145         if (sme->crypto.n_ciphers_pairwise) {
1146                 switch (sme->crypto.ciphers_pairwise[0]) {
1147                 case WLAN_CIPHER_SUITE_WEP40:
1148                 case WLAN_CIPHER_SUITE_WEP104:
1149                         pval = WEP_ENABLED;
1150                         break;
1151                 case WLAN_CIPHER_SUITE_TKIP:
1152                         pval = TKIP_ENABLED;
1153                         break;
1154                 case WLAN_CIPHER_SUITE_CCMP:
1155                         pval = AES_ENABLED;
1156                         break;
1157                 case WLAN_CIPHER_SUITE_AES_CMAC:
1158                         pval = AES_ENABLED;
1159                         break;
1160                 default:
1161                         WL_ERR(("invalid cipher pairwise (%d)\n",
1162                                 sme->crypto.ciphers_pairwise[0]));
1163                         return -EINVAL;
1164                 }
1165         }
1166         if (sme->crypto.cipher_group) {
1167                 switch (sme->crypto.cipher_group) {
1168                 case WLAN_CIPHER_SUITE_WEP40:
1169                 case WLAN_CIPHER_SUITE_WEP104:
1170                         gval = WEP_ENABLED;
1171                         break;
1172                 case WLAN_CIPHER_SUITE_TKIP:
1173                         gval = TKIP_ENABLED;
1174                         break;
1175                 case WLAN_CIPHER_SUITE_CCMP:
1176                         gval = AES_ENABLED;
1177                         break;
1178                 case WLAN_CIPHER_SUITE_AES_CMAC:
1179                         gval = AES_ENABLED;
1180                         break;
1181                 default:
1182                         WL_ERR(("invalid cipher group (%d)\n",
1183                                 sme->crypto.cipher_group));
1184                         return -EINVAL;
1185                 }
1186         }
1187
1188         WL_DBG(("pval (%d) gval (%d)\n", pval, gval));
1189         err = wl_dev_intvar_set(dev, "wsec", pval | gval);
1190         if (unlikely(err)) {
1191                 WL_ERR(("error (%d)\n", err));
1192                 return err;
1193         }
1194
1195         sec = wl_read_prof(wl, WL_PROF_SEC);
1196         sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1197         sec->cipher_group = sme->crypto.cipher_group;
1198
1199         return err;
1200 }
1201
1202 static s32
1203 wl_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme)
1204 {
1205         struct wl_priv *wl = ndev_to_wl(dev);
1206         struct wl_security *sec;
1207         s32 val = 0;
1208         s32 err = 0;
1209
1210         if (sme->crypto.n_akm_suites) {
1211                 err = wl_dev_intvar_get(dev, "wpa_auth", &val);
1212                 if (unlikely(err)) {
1213                         WL_ERR(("could not get wpa_auth (%d)\n", err));
1214                         return err;
1215                 }
1216                 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1217                         switch (sme->crypto.akm_suites[0]) {
1218                         case WLAN_AKM_SUITE_8021X:
1219                                 val = WPA_AUTH_UNSPECIFIED;
1220                                 break;
1221                         case WLAN_AKM_SUITE_PSK:
1222                                 val = WPA_AUTH_PSK;
1223                                 break;
1224                         default:
1225                                 WL_ERR(("invalid cipher group (%d)\n",
1226                                         sme->crypto.cipher_group));
1227                                 return -EINVAL;
1228                         }
1229                 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1230                         switch (sme->crypto.akm_suites[0]) {
1231                         case WLAN_AKM_SUITE_8021X:
1232                                 val = WPA2_AUTH_UNSPECIFIED;
1233                                 break;
1234                         case WLAN_AKM_SUITE_PSK:
1235                                 val = WPA2_AUTH_PSK;
1236                                 break;
1237                         default:
1238                                 WL_ERR(("invalid cipher group (%d)\n",
1239                                         sme->crypto.cipher_group));
1240                                 return -EINVAL;
1241                         }
1242                 }
1243
1244                 WL_DBG(("setting wpa_auth to %d\n", val));
1245                 err = wl_dev_intvar_set(dev, "wpa_auth", val);
1246                 if (unlikely(err)) {
1247                         WL_ERR(("could not set wpa_auth (%d)\n", err));
1248                         return err;
1249                 }
1250         }
1251         sec = wl_read_prof(wl, WL_PROF_SEC);
1252         sec->wpa_auth = sme->crypto.akm_suites[0];
1253
1254         return err;
1255 }
1256
1257 static s32
1258 wl_set_set_sharedkey(struct net_device *dev,
1259                      struct cfg80211_connect_params *sme)
1260 {
1261         struct wl_priv *wl = ndev_to_wl(dev);
1262         struct wl_security *sec;
1263         struct wl_wsec_key key;
1264         s32 val;
1265         s32 err = 0;
1266
1267         WL_DBG(("key len (%d)\n", sme->key_len));
1268         if (sme->key_len) {
1269                 sec = wl_read_prof(wl, WL_PROF_SEC);
1270                 WL_DBG(("wpa_versions 0x%x cipher_pairwise 0x%x\n",
1271                         sec->wpa_versions, sec->cipher_pairwise));
1272                 if (!
1273                     (sec->wpa_versions & (NL80211_WPA_VERSION_1 |
1274                                           NL80211_WPA_VERSION_2))
1275 && (sec->cipher_pairwise & (WLAN_CIPHER_SUITE_WEP40 |
1276                             WLAN_CIPHER_SUITE_WEP104))) {
1277                         memset(&key, 0, sizeof(key));
1278                         key.len = (u32) sme->key_len;
1279                         key.index = (u32) sme->key_idx;
1280                         if (unlikely(key.len > sizeof(key.data))) {
1281                                 WL_ERR(("Too long key length (%u)\n", key.len));
1282                                 return -EINVAL;
1283                         }
1284                         memcpy(key.data, sme->key, key.len);
1285                         key.flags = WL_PRIMARY_KEY;
1286                         switch (sec->cipher_pairwise) {
1287                         case WLAN_CIPHER_SUITE_WEP40:
1288                                 key.algo = CRYPTO_ALGO_WEP1;
1289                                 break;
1290                         case WLAN_CIPHER_SUITE_WEP104:
1291                                 key.algo = CRYPTO_ALGO_WEP128;
1292                                 break;
1293                         default:
1294                                 WL_ERR(("Invalid algorithm (%d)\n",
1295                                         sme->crypto.ciphers_pairwise[0]));
1296                                 return -EINVAL;
1297                         }
1298                         /* Set the new key/index */
1299                         WL_DBG(("key length (%d) key index (%d) algo (%d)\n",
1300                                 key.len, key.index, key.algo));
1301                         WL_DBG(("key \"%s\"\n", key.data));
1302                         swap_key_from_BE(&key);
1303                         err = wl_dev_ioctl(dev, WLC_SET_KEY, &key,
1304                                         sizeof(key));
1305                         if (unlikely(err)) {
1306                                 WL_ERR(("WLC_SET_KEY error (%d)\n", err));
1307                                 return err;
1308                         }
1309                         if (sec->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) {
1310                                 WL_DBG(("set auth_type to shared key\n"));
1311                                 val = 1;        /* shared key */
1312                                 err = wl_dev_intvar_set(dev, "auth", val);
1313                                 if (unlikely(err)) {
1314                                         WL_ERR(("set auth failed (%d)\n", err));
1315                                         return err;
1316                                 }
1317                         }
1318                 }
1319         }
1320         return err;
1321 }
1322
1323 static s32
1324 wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
1325                     struct cfg80211_connect_params *sme)
1326 {
1327         struct wl_priv *wl = wiphy_to_wl(wiphy);
1328         struct ieee80211_channel *chan = sme->channel;
1329         struct wl_join_params join_params;
1330         size_t join_params_size;
1331
1332         s32 err = 0;
1333
1334         CHECK_SYS_UP();
1335         if (unlikely(!sme->ssid)) {
1336                 WL_ERR(("Invalid ssid\n"));
1337                 return -EOPNOTSUPP;
1338         }
1339         if (chan) {
1340                 wl->channel = ieee80211_frequency_to_channel(chan->center_freq);
1341                 WL_DBG(("channel (%d), center_req (%d)\n", wl->channel,
1342                         chan->center_freq));
1343         }
1344         WL_DBG(("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len));
1345         err = wl_set_wpa_version(dev, sme);
1346         if (unlikely(err))
1347                 return err;
1348
1349         err = wl_set_auth_type(dev, sme);
1350         if (unlikely(err))
1351                 return err;
1352
1353         err = wl_set_set_cipher(dev, sme);
1354         if (unlikely(err))
1355                 return err;
1356
1357         err = wl_set_key_mgmt(dev, sme);
1358         if (unlikely(err))
1359                 return err;
1360
1361         err = wl_set_set_sharedkey(dev, sme);
1362         if (unlikely(err))
1363                 return err;
1364
1365         wl_update_prof(wl, NULL, sme->bssid, WL_PROF_BSSID);
1366         /*
1367          **  Join with specific BSSID and cached SSID
1368          **  If SSID is zero join based on BSSID only
1369          */
1370         memset(&join_params, 0, sizeof(join_params));
1371         join_params_size = sizeof(join_params.ssid);
1372
1373         join_params.ssid.SSID_len = min(sizeof(join_params.ssid.SSID), sme->ssid_len);
1374         memcpy(&join_params.ssid.SSID, sme->ssid, join_params.ssid.SSID_len);
1375         join_params.ssid.SSID_len = htod32(join_params.ssid.SSID_len);
1376         wl_update_prof(wl, NULL, &join_params.ssid, WL_PROF_SSID);
1377         memcpy(&join_params.params.bssid, &ether_bcast, ETHER_ADDR_LEN);
1378
1379         wl_ch_to_chanspec(wl->channel, &join_params, &join_params_size);
1380         WL_DBG(("join_param_size %d\n", join_params_size));
1381
1382         if (join_params.ssid.SSID_len < IEEE80211_MAX_SSID_LEN) {
1383                 WL_DBG(("ssid \"%s\", len (%d)\n", join_params.ssid.SSID,
1384                         join_params.ssid.SSID_len));
1385         }
1386         err = wl_dev_ioctl(dev, WLC_SET_SSID, &join_params, join_params_size);
1387         if (unlikely(err)) {
1388                 WL_ERR(("error (%d)\n", err));
1389                 return err;
1390         }
1391         set_bit(WL_STATUS_CONNECTING, &wl->status);
1392
1393         return err;
1394 }
1395
1396 static s32
1397 wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
1398                        u16 reason_code)
1399 {
1400         struct wl_priv *wl = wiphy_to_wl(wiphy);
1401         scb_val_t scbval;
1402         bool act = false;
1403         s32 err = 0;
1404
1405         WL_DBG(("Reason %d\n", reason_code));
1406         CHECK_SYS_UP();
1407         act = *(bool *) wl_read_prof(wl, WL_PROF_ACT);
1408         if (likely(act)) {
1409                 scbval.val = reason_code;
1410                 memcpy(&scbval.ea, &wl->bssid, ETHER_ADDR_LEN);
1411                 scbval.val = htod32(scbval.val);
1412                 err = wl_dev_ioctl(dev, WLC_DISASSOC, &scbval,
1413                                 sizeof(scb_val_t));
1414                 if (unlikely(err)) {
1415                         WL_ERR(("error (%d)\n", err));
1416                         return err;
1417                 }
1418         }
1419
1420         return err;
1421 }
1422
1423 static s32
1424 wl_cfg80211_set_tx_power(struct wiphy *wiphy,
1425                          enum nl80211_tx_power_setting type, s32 dbm)
1426 {
1427
1428         struct wl_priv *wl = wiphy_to_wl(wiphy);
1429         struct net_device *ndev = wl_to_ndev(wl);
1430         u16 txpwrmw;
1431         s32 err = 0;
1432         s32 disable = 0;
1433
1434         CHECK_SYS_UP();
1435         switch (type) {
1436         case NL80211_TX_POWER_AUTOMATIC:
1437                 break;
1438         case NL80211_TX_POWER_LIMITED:
1439                 if (dbm < 0) {
1440                         WL_ERR(("TX_POWER_LIMITTED - dbm is negative\n"));
1441                         return -EINVAL;
1442                 }
1443                 break;
1444         case NL80211_TX_POWER_FIXED:
1445                 if (dbm < 0) {
1446                         WL_ERR(("TX_POWER_FIXED - dbm is negative..\n"));
1447                         return -EINVAL;
1448                 }
1449                 break;
1450         }
1451         /* Make sure radio is off or on as far as software is concerned */
1452         disable = WL_RADIO_SW_DISABLE << 16;
1453         disable = htod32(disable);
1454         err = wl_dev_ioctl(ndev, WLC_SET_RADIO, &disable, sizeof(disable));
1455         if (unlikely(err)) {
1456                 WL_ERR(("WLC_SET_RADIO error (%d)\n", err));
1457                 return err;
1458         }
1459
1460         if (dbm > 0xffff)
1461                 txpwrmw = 0xffff;
1462         else
1463                 txpwrmw = (u16) dbm;
1464         err = wl_dev_intvar_set(ndev, "qtxpower",
1465                         (s32) (bcm_mw_to_qdbm(txpwrmw)));
1466         if (unlikely(err)) {
1467                 WL_ERR(("qtxpower error (%d)\n", err));
1468                 return err;
1469         }
1470         wl->conf->tx_power = dbm;
1471
1472         return err;
1473 }
1474
1475 static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm)
1476 {
1477         struct wl_priv *wl = wiphy_to_wl(wiphy);
1478         struct net_device *ndev = wl_to_ndev(wl);
1479         s32 txpwrdbm;
1480         u8 result;
1481         s32 err = 0;
1482
1483         CHECK_SYS_UP();
1484         err = wl_dev_intvar_get(ndev, "qtxpower", &txpwrdbm);
1485         if (unlikely(err)) {
1486                 WL_ERR(("error (%d)\n", err));
1487                 return err;
1488         }
1489         result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
1490         *dbm = (s32) bcm_qdbm_to_mw(result);
1491
1492         return err;
1493 }
1494
1495 static s32
1496 wl_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *dev,
1497                                u8 key_idx)
1498 {
1499         u32 index;
1500         s32 wsec;
1501         s32 err = 0;
1502
1503         WL_DBG(("key index (%d)\n", key_idx));
1504         CHECK_SYS_UP();
1505
1506         err = wl_dev_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec));
1507         if (unlikely(err)) {
1508                 WL_ERR(("WLC_GET_WSEC error (%d)\n", err));
1509                 return err;
1510         }
1511         wsec = dtoh32(wsec);
1512         if (wsec & WEP_ENABLED) {
1513                 /* Just select a new current key */
1514                 index = (u32) key_idx;
1515                 index = htod32(index);
1516                 err = wl_dev_ioctl(dev, WLC_SET_KEY_PRIMARY, &index,
1517                                 sizeof(index));
1518                 if (unlikely(err)) {
1519                         WL_ERR(("error (%d)\n", err));
1520                 }
1521         }
1522         return err;
1523 }
1524
1525 static s32
1526 wl_add_keyext(struct wiphy *wiphy, struct net_device *dev,
1527               u8 key_idx, const u8 *mac_addr, struct key_params *params)
1528 {
1529         struct wl_wsec_key key;
1530         s32 err = 0;
1531
1532         memset(&key, 0, sizeof(key));
1533         key.index = (u32) key_idx;
1534         /* Instead of bcast for ea address for default wep keys,
1535                  driver needs it to be Null */
1536         if (!ETHER_ISMULTI(mac_addr))
1537                 memcpy((char *)&key.ea, (void *)mac_addr, ETHER_ADDR_LEN);
1538         key.len = (u32) params->key_len;
1539         /* check for key index change */
1540         if (key.len == 0) {
1541                 /* key delete */
1542                 swap_key_from_BE(&key);
1543                 err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
1544                 if (unlikely(err)) {
1545                         WL_ERR(("key delete error (%d)\n", err));
1546                         return err;
1547                 }
1548         } else {
1549                 if (key.len > sizeof(key.data)) {
1550                         WL_ERR(("Invalid key length (%d)\n", key.len));
1551                         return -EINVAL;
1552                 }
1553
1554                 WL_DBG(("Setting the key index %d\n", key.index));
1555                 memcpy(key.data, params->key, key.len);
1556
1557                 if (params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1558                         u8 keybuf[8];
1559                         memcpy(keybuf, &key.data[24], sizeof(keybuf));
1560                         memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1561                         memcpy(&key.data[16], keybuf, sizeof(keybuf));
1562                 }
1563
1564                 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
1565                 if (params->seq && params->seq_len == 6) {
1566                         /* rx iv */
1567                         u8 *ivptr;
1568                         ivptr = (u8 *) params->seq;
1569                         key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
1570                             (ivptr[3] << 8) | ivptr[2];
1571                         key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
1572                         key.iv_initialized = true;
1573                 }
1574
1575                 switch (params->cipher) {
1576                 case WLAN_CIPHER_SUITE_WEP40:
1577                         key.algo = CRYPTO_ALGO_WEP1;
1578                         WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n"));
1579                         break;
1580                 case WLAN_CIPHER_SUITE_WEP104:
1581                         key.algo = CRYPTO_ALGO_WEP128;
1582                         WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n"));
1583                         break;
1584                 case WLAN_CIPHER_SUITE_TKIP:
1585                         key.algo = CRYPTO_ALGO_TKIP;
1586                         WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n"));
1587                         break;
1588                 case WLAN_CIPHER_SUITE_AES_CMAC:
1589                         key.algo = CRYPTO_ALGO_AES_CCM;
1590                         WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n"));
1591                         break;
1592                 case WLAN_CIPHER_SUITE_CCMP:
1593                         key.algo = CRYPTO_ALGO_AES_CCM;
1594                         WL_DBG(("WLAN_CIPHER_SUITE_CCMP\n"));
1595                         break;
1596                 default:
1597                         WL_ERR(("Invalid cipher (0x%x)\n", params->cipher));
1598                         return -EINVAL;
1599                 }
1600                 swap_key_from_BE(&key);
1601
1602                 dhd_wait_pend8021x(dev);
1603                 err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
1604                 if (unlikely(err)) {
1605                         WL_ERR(("WLC_SET_KEY error (%d)\n", err));
1606                         return err;
1607                 }
1608         }
1609         return err;
1610 }
1611
1612 static s32
1613 wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
1614                     u8 key_idx, const u8 *mac_addr,
1615                     struct key_params *params)
1616 {
1617         struct wl_wsec_key key;
1618         s32 val;
1619         s32 wsec;
1620         s32 err = 0;
1621
1622         WL_DBG(("key index (%d)\n", key_idx));
1623         CHECK_SYS_UP();
1624
1625         if (mac_addr)
1626                 return wl_add_keyext(wiphy, dev, key_idx, mac_addr, params);
1627         memset(&key, 0, sizeof(key));
1628
1629         key.len = (u32) params->key_len;
1630         key.index = (u32) key_idx;
1631
1632         if (unlikely(key.len > sizeof(key.data))) {
1633                 WL_ERR(("Too long key length (%u)\n", key.len));
1634                 return -EINVAL;
1635         }
1636         memcpy(key.data, params->key, key.len);
1637
1638         key.flags = WL_PRIMARY_KEY;
1639         switch (params->cipher) {
1640         case WLAN_CIPHER_SUITE_WEP40:
1641                 key.algo = CRYPTO_ALGO_WEP1;
1642                 WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n"));
1643                 break;
1644         case WLAN_CIPHER_SUITE_WEP104:
1645                 key.algo = CRYPTO_ALGO_WEP128;
1646                 WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n"));
1647                 break;
1648         case WLAN_CIPHER_SUITE_TKIP:
1649                 key.algo = CRYPTO_ALGO_TKIP;
1650                 WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n"));
1651                 break;
1652         case WLAN_CIPHER_SUITE_AES_CMAC:
1653                 key.algo = CRYPTO_ALGO_AES_CCM;
1654                 WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n"));
1655                 break;
1656         case WLAN_CIPHER_SUITE_CCMP:
1657                 key.algo = CRYPTO_ALGO_AES_CCM;
1658                 WL_DBG(("WLAN_CIPHER_SUITE_CCMP\n"));
1659                 break;
1660         default:
1661                 WL_ERR(("Invalid cipher (0x%x)\n", params->cipher));
1662                 return -EINVAL;
1663         }
1664
1665         /* Set the new key/index */
1666         swap_key_from_BE(&key);
1667         err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
1668         if (unlikely(err)) {
1669                 WL_ERR(("WLC_SET_KEY error (%d)\n", err));
1670                 return err;
1671         }
1672
1673         val = WEP_ENABLED;
1674         err = wl_dev_intvar_get(dev, "wsec", &wsec);
1675         if (unlikely(err)) {
1676                 WL_ERR(("get wsec error (%d)\n", err));
1677                 return err;
1678         }
1679         wsec &= ~(WEP_ENABLED);
1680         wsec |= val;
1681         err = wl_dev_intvar_set(dev, "wsec", wsec);
1682         if (unlikely(err)) {
1683                 WL_ERR(("set wsec error (%d)\n", err));
1684                 return err;
1685         }
1686
1687         val = 1;                /* assume shared key. otherwise 0 */
1688         val = htod32(val);
1689         err = wl_dev_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val));
1690         if (unlikely(err)) {
1691                 WL_ERR(("WLC_SET_AUTH error (%d)\n", err));
1692                 return err;
1693         }
1694         return err;
1695 }
1696
1697 static s32
1698 wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
1699                     u8 key_idx, const u8 *mac_addr)
1700 {
1701         struct wl_wsec_key key;
1702         s32 err = 0;
1703         s32 val;
1704         s32 wsec;
1705
1706         CHECK_SYS_UP();
1707         memset(&key, 0, sizeof(key));
1708
1709         key.index = (u32) key_idx;
1710         key.flags = WL_PRIMARY_KEY;
1711         key.algo = CRYPTO_ALGO_OFF;
1712
1713         WL_DBG(("key index (%d)\n", key_idx));
1714         /* Set the new key/index */
1715         swap_key_from_BE(&key);
1716         err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
1717         if (unlikely(err)) {
1718                 if (err == -EINVAL) {
1719                         if (key.index >= DOT11_MAX_DEFAULT_KEYS) {
1720                                 /* we ignore this key index in this case */
1721                                 WL_DBG(("invalid key index (%d)\n", key_idx));
1722                         }
1723                 } else {
1724                         WL_ERR(("WLC_SET_KEY error (%d)\n", err));
1725                 }
1726                 return err;
1727         }
1728
1729         val = 0;
1730         err = wl_dev_intvar_get(dev, "wsec", &wsec);
1731         if (unlikely(err)) {
1732                 WL_ERR(("get wsec error (%d)\n", err));
1733                 return err;
1734         }
1735         wsec &= ~(WEP_ENABLED);
1736         wsec |= val;
1737         err = wl_dev_intvar_set(dev, "wsec", wsec);
1738         if (unlikely(err)) {
1739                 WL_ERR(("set wsec error (%d)\n", err));
1740                 return err;
1741         }
1742
1743         val = 0;                /* assume open key. otherwise 1 */
1744         val = htod32(val);
1745         err = wl_dev_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val));
1746         if (unlikely(err)) {
1747                 WL_ERR(("WLC_SET_AUTH error (%d)\n", err));
1748                 return err;
1749         }
1750         return err;
1751 }
1752
1753 static s32
1754 wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
1755                     u8 key_idx, const u8 *mac_addr, void *cookie,
1756                     void (*callback) (void *cookie, struct key_params * params))
1757 {
1758         struct key_params params;
1759         struct wl_wsec_key key;
1760         struct wl_priv *wl = wiphy_to_wl(wiphy);
1761         struct wl_security *sec;
1762         s32 wsec;
1763         s32 err = 0;
1764
1765         WL_DBG(("key index (%d)\n", key_idx));
1766         CHECK_SYS_UP();
1767
1768         memset(&key, 0, sizeof(key));
1769         key.index = key_idx;
1770         swap_key_to_BE(&key);
1771         memset(&params, 0, sizeof(params));
1772         params.key_len = (u8) min_t(u8, DOT11_MAX_KEY_SIZE, key.len);
1773         memcpy(params.key, key.data, params.key_len);
1774
1775         err = wl_dev_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec));
1776         if (unlikely(err)) {
1777                 WL_ERR(("WLC_GET_WSEC error (%d)\n", err));
1778                 return err;
1779         }
1780         wsec = dtoh32(wsec);
1781         switch (wsec) {
1782         case WEP_ENABLED:
1783                 sec = wl_read_prof(wl, WL_PROF_SEC);
1784                 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
1785                         params.cipher = WLAN_CIPHER_SUITE_WEP40;
1786                         WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n"));
1787                 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
1788                         params.cipher = WLAN_CIPHER_SUITE_WEP104;
1789                         WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n"));
1790                 }
1791                 break;
1792         case TKIP_ENABLED:
1793                 params.cipher = WLAN_CIPHER_SUITE_TKIP;
1794                 WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n"));
1795                 break;
1796         case AES_ENABLED:
1797                 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
1798                 WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n"));
1799                 break;
1800         default:
1801                 WL_ERR(("Invalid algo (0x%x)\n", wsec));
1802                 return -EINVAL;
1803         }
1804
1805         callback(cookie, &params);
1806         return err;
1807 }
1808
1809 static s32
1810 wl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
1811                                     struct net_device *dev, u8 key_idx)
1812 {
1813         WL_INFO(("Not supported\n"));
1814         CHECK_SYS_UP();
1815         return -EOPNOTSUPP;
1816 }
1817
1818 static s32
1819 wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
1820                         u8 *mac, struct station_info *sinfo)
1821 {
1822         struct wl_priv *wl = wiphy_to_wl(wiphy);
1823         scb_val_t scb_val;
1824         int rssi;
1825         s32 rate;
1826         s32 err = 0;
1827
1828         CHECK_SYS_UP();
1829         if (unlikely
1830             (memcmp(mac, wl_read_prof(wl, WL_PROF_BSSID), ETHER_ADDR_LEN))) {
1831                 WL_ERR(("Wrong Mac address\n"));
1832                 return -ENOENT;
1833         }
1834
1835         /* Report the current tx rate */
1836         err = wl_dev_ioctl(dev, WLC_GET_RATE, &rate, sizeof(rate));
1837         if (err) {
1838                 WL_ERR(("Could not get rate (%d)\n", err));
1839         } else {
1840                 rate = dtoh32(rate);
1841                 sinfo->filled |= STATION_INFO_TX_BITRATE;
1842                 sinfo->txrate.legacy = rate * 5;
1843                 WL_DBG(("Rate %d Mbps\n", (rate / 2)));
1844         }
1845
1846         if (test_bit(WL_STATUS_CONNECTED, &wl->status)) {
1847                 scb_val.val = 0;
1848                 err = wl_dev_ioctl(dev, WLC_GET_RSSI, &scb_val,
1849                                 sizeof(scb_val_t));
1850                 if (unlikely(err)) {
1851                         WL_ERR(("Could not get rssi (%d)\n", err));
1852                         return err;
1853                 }
1854                 rssi = dtoh32(scb_val.val);
1855                 sinfo->filled |= STATION_INFO_SIGNAL;
1856                 sinfo->signal = rssi;
1857                 WL_DBG(("RSSI %d dBm\n", rssi));
1858         }
1859
1860         return err;
1861 }
1862
1863 static s32
1864 wl_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
1865                            bool enabled, s32 timeout)
1866 {
1867         s32 pm;
1868         s32 err = 0;
1869
1870         CHECK_SYS_UP();
1871         pm = enabled ? PM_FAST : PM_OFF;
1872         pm = htod32(pm);
1873         WL_DBG(("power save %s\n", (pm ? "enabled" : "disabled")));
1874         err = wl_dev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm));
1875         if (unlikely(err)) {
1876                 if (err == -ENODEV)
1877                         WL_DBG(("net_device is not ready yet\n"));
1878                 else
1879                         WL_ERR(("error (%d)\n", err));
1880                 return err;
1881         }
1882         return err;
1883 }
1884
1885 static __used u32 wl_find_msb(u16 bit16)
1886 {
1887         u32 ret = 0;
1888
1889         if (bit16 & 0xff00) {
1890                 ret += 8;
1891                 bit16 >>= 8;
1892         }
1893
1894         if (bit16 & 0xf0) {
1895                 ret += 4;
1896                 bit16 >>= 4;
1897         }
1898
1899         if (bit16 & 0xc) {
1900                 ret += 2;
1901                 bit16 >>= 2;
1902         }
1903
1904         if (bit16 & 2)
1905                 ret += bit16 & 2;
1906         else if (bit16)
1907                 ret += bit16;
1908
1909         return ret;
1910 }
1911
1912 static s32
1913 wl_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev,
1914                              const u8 *addr,
1915                              const struct cfg80211_bitrate_mask *mask)
1916 {
1917         struct wl_rateset rateset;
1918         s32 rate;
1919         s32 val;
1920         s32 err_bg;
1921         s32 err_a;
1922         u32 legacy;
1923         s32 err = 0;
1924
1925         CHECK_SYS_UP();
1926         /* addr param is always NULL. ignore it */
1927         /* Get current rateset */
1928         err = wl_dev_ioctl(dev, WLC_GET_CURR_RATESET, &rateset,
1929                         sizeof(rateset));
1930         if (unlikely(err)) {
1931                 WL_ERR(("could not get current rateset (%d)\n", err));
1932                 return err;
1933         }
1934
1935         rateset.count = dtoh32(rateset.count);
1936
1937         legacy = wl_find_msb(mask->control[IEEE80211_BAND_2GHZ].legacy);
1938         if (!legacy)
1939                 legacy = wl_find_msb(mask->control[IEEE80211_BAND_5GHZ].legacy);
1940
1941         val = wl_g_rates[legacy - 1].bitrate * 100000;
1942
1943         if (val < rateset.count) {
1944                 /* Select rate by rateset index */
1945                 rate = rateset.rates[val] & 0x7f;
1946         } else {
1947                 /* Specified rate in bps */
1948                 rate = val / 500000;
1949         }
1950
1951         WL_DBG(("rate %d mbps\n", (rate / 2)));
1952
1953         /*
1954          *
1955          *      Set rate override,
1956          *      Since the is a/b/g-blind, both a/bg_rate are enforced.
1957          */
1958         err_bg = wl_dev_intvar_set(dev, "bg_rate", rate);
1959         err_a = wl_dev_intvar_set(dev, "a_rate", rate);
1960         if (unlikely(err_bg && err_a)) {
1961                 WL_ERR(("could not set fixed rate (%d) (%d)\n", err_bg, err_a));
1962                 return err_bg | err_a;
1963         }
1964
1965         return err;
1966 }
1967
1968 static s32 wl_cfg80211_resume(struct wiphy *wiphy)
1969 {
1970         s32 err = 0;
1971
1972         CHECK_SYS_UP();
1973         wl_invoke_iscan(wiphy_to_wl(wiphy));
1974
1975         return err;
1976 }
1977
1978 static s32 wl_cfg80211_suspend(struct wiphy *wiphy)
1979 {
1980         struct wl_priv *wl = wiphy_to_wl(wiphy);
1981         struct net_device *ndev = wl_to_ndev(wl);
1982         s32 err = 0;
1983
1984         CHECK_SYS_UP();
1985
1986         set_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
1987         wl_term_iscan(wl);
1988         if (wl->scan_request) {
1989                 cfg80211_scan_done(wl->scan_request, true);     /* true means
1990                                                                  abort */
1991                 wl_set_mpc(ndev, 1);
1992                 wl->scan_request = NULL;
1993         }
1994         clear_bit(WL_STATUS_SCANNING, &wl->status);
1995         clear_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
1996
1997         return err;
1998 }
1999
2000 static __used s32
2001 wl_update_pmklist(struct net_device *dev, struct wl_pmk_list *pmk_list,
2002                   s32 err)
2003 {
2004         int i, j;
2005
2006         WL_DBG(("No of elements %d\n", pmk_list->pmkids.npmkid));
2007         for (i = 0; i < pmk_list->pmkids.npmkid; i++) {
2008                 WL_DBG(("PMKID[%d]: %pM =\n", i,
2009                         &pmk_list->pmkids.pmkid[i].BSSID));
2010                 for (j = 0; j < WPA2_PMKID_LEN; j++) {
2011                         WL_DBG(("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]));
2012                 }
2013         }
2014         if (likely(!err)) {
2015                 err = wl_dev_bufvar_set(dev, "pmkid_info", (char *)pmk_list,
2016                                         sizeof(*pmk_list));
2017         }
2018
2019         return err;
2020 }
2021
2022 static s32
2023 wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
2024                       struct cfg80211_pmksa *pmksa)
2025 {
2026         struct wl_priv *wl = wiphy_to_wl(wiphy);
2027         s32 err = 0;
2028         int i;
2029
2030         CHECK_SYS_UP();
2031         for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++)
2032                 if (!memcmp(pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID,
2033                             ETHER_ADDR_LEN))
2034                         break;
2035         if (i < WL_NUM_PMKIDS_MAX) {
2036                 memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID, pmksa->bssid,
2037                        ETHER_ADDR_LEN);
2038                 memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID, pmksa->pmkid,
2039                        WPA2_PMKID_LEN);
2040                 if (i == wl->pmk_list->pmkids.npmkid)
2041                         wl->pmk_list->pmkids.npmkid++;
2042         } else {
2043                 err = -EINVAL;
2044         }
2045         WL_DBG(("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2046                 &wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid].BSSID));
2047         for (i = 0; i < WPA2_PMKID_LEN; i++) {
2048                 WL_DBG(("%02x\n",
2049                         wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid].
2050                         PMKID[i]));
2051         }
2052
2053         err = wl_update_pmklist(dev, wl->pmk_list, err);
2054
2055         return err;
2056 }
2057
2058 static s32
2059 wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
2060                       struct cfg80211_pmksa *pmksa)
2061 {
2062         struct wl_priv *wl = wiphy_to_wl(wiphy);
2063         struct _pmkid_list pmkid;
2064         s32 err = 0;
2065         int i;
2066
2067         CHECK_SYS_UP();
2068         memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETHER_ADDR_LEN);
2069         memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WPA2_PMKID_LEN);
2070
2071         WL_DBG(("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2072                 &pmkid.pmkid[0].BSSID));
2073         for (i = 0; i < WPA2_PMKID_LEN; i++) {
2074                 WL_DBG(("%02x\n", pmkid.pmkid[0].PMKID[i]));
2075         }
2076
2077         for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++)
2078                 if (!memcmp
2079                     (pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID,
2080                      ETHER_ADDR_LEN))
2081                         break;
2082
2083         if ((wl->pmk_list->pmkids.npmkid > 0)
2084             && (i < wl->pmk_list->pmkids.npmkid)) {
2085                 memset(&wl->pmk_list->pmkids.pmkid[i], 0, sizeof(pmkid_t));
2086                 for (; i < (wl->pmk_list->pmkids.npmkid - 1); i++) {
2087                         memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID,
2088                                &wl->pmk_list->pmkids.pmkid[i + 1].BSSID,
2089                                ETHER_ADDR_LEN);
2090                         memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID,
2091                                &wl->pmk_list->pmkids.pmkid[i + 1].PMKID,
2092                                WPA2_PMKID_LEN);
2093                 }
2094                 wl->pmk_list->pmkids.npmkid--;
2095         } else {
2096                 err = -EINVAL;
2097         }
2098
2099         err = wl_update_pmklist(dev, wl->pmk_list, err);
2100
2101         return err;
2102
2103 }
2104
2105 static s32
2106 wl_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
2107 {
2108         struct wl_priv *wl = wiphy_to_wl(wiphy);
2109         s32 err = 0;
2110
2111         CHECK_SYS_UP();
2112         memset(wl->pmk_list, 0, sizeof(*wl->pmk_list));
2113         err = wl_update_pmklist(dev, wl->pmk_list, err);
2114         return err;
2115
2116 }
2117
2118 static struct cfg80211_ops wl_cfg80211_ops = {
2119         .change_virtual_intf = wl_cfg80211_change_iface,
2120         .scan = wl_cfg80211_scan,
2121         .set_wiphy_params = wl_cfg80211_set_wiphy_params,
2122         .join_ibss = wl_cfg80211_join_ibss,
2123         .leave_ibss = wl_cfg80211_leave_ibss,
2124         .get_station = wl_cfg80211_get_station,
2125         .set_tx_power = wl_cfg80211_set_tx_power,
2126         .get_tx_power = wl_cfg80211_get_tx_power,
2127         .add_key = wl_cfg80211_add_key,
2128         .del_key = wl_cfg80211_del_key,
2129         .get_key = wl_cfg80211_get_key,
2130         .set_default_key = wl_cfg80211_config_default_key,
2131         .set_default_mgmt_key = wl_cfg80211_config_default_mgmt_key,
2132         .set_power_mgmt = wl_cfg80211_set_power_mgmt,
2133         .set_bitrate_mask = wl_cfg80211_set_bitrate_mask,
2134         .connect = wl_cfg80211_connect,
2135         .disconnect = wl_cfg80211_disconnect,
2136         .suspend = wl_cfg80211_suspend,
2137         .resume = wl_cfg80211_resume,
2138         .set_pmksa = wl_cfg80211_set_pmksa,
2139         .del_pmksa = wl_cfg80211_del_pmksa,
2140         .flush_pmksa = wl_cfg80211_flush_pmksa
2141 };
2142
2143 static s32 wl_mode_to_nl80211_iftype(s32 mode)
2144 {
2145         s32 err = 0;
2146
2147         switch (mode) {
2148         case WL_MODE_BSS:
2149                 return NL80211_IFTYPE_STATION;
2150         case WL_MODE_IBSS:
2151                 return NL80211_IFTYPE_ADHOC;
2152         default:
2153                 return NL80211_IFTYPE_UNSPECIFIED;
2154         }
2155
2156         return err;
2157 }
2158
2159 static struct wireless_dev *wl_alloc_wdev(s32 sizeof_iface,
2160                                           struct device *dev)
2161 {
2162         struct wireless_dev *wdev;
2163         s32 err = 0;
2164
2165         wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
2166         if (unlikely(!wdev)) {
2167                 WL_ERR(("Could not allocate wireless device\n"));
2168                 return ERR_PTR(-ENOMEM);
2169         }
2170         wdev->wiphy =
2171             wiphy_new(&wl_cfg80211_ops, sizeof(struct wl_priv) + sizeof_iface);
2172         if (unlikely(!wdev->wiphy)) {
2173                 WL_ERR(("Couldn not allocate wiphy device\n"));
2174                 err = -ENOMEM;
2175                 goto wiphy_new_out;
2176         }
2177         set_wiphy_dev(wdev->wiphy, dev);
2178         wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
2179         wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
2180         wdev->wiphy->interface_modes =
2181             BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
2182         wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
2183         wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a;    /* Set
2184                                                 * it as 11a by default.
2185                                                 * This will be updated with
2186                                                 * 11n phy tables in
2187                                                 * "ifconfig up"
2188                                                 * if phy has 11n capability
2189                                                 */
2190         wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2191         wdev->wiphy->cipher_suites = __wl_cipher_suites;
2192         wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
2193 #ifndef WL_POWERSAVE_DISABLED
2194         wdev->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;      /* enable power
2195                                                                  * save mode
2196                                                                  * by default
2197                                                                  */
2198 #else
2199         wdev->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
2200 #endif                          /* !WL_POWERSAVE_DISABLED */
2201         err = wiphy_register(wdev->wiphy);
2202         if (unlikely(err < 0)) {
2203                 WL_ERR(("Couldn not register wiphy device (%d)\n", err));
2204                 goto wiphy_register_out;
2205         }
2206         return wdev;
2207
2208 wiphy_register_out:
2209         wiphy_free(wdev->wiphy);
2210
2211 wiphy_new_out:
2212         kfree(wdev);
2213
2214         return ERR_PTR(err);
2215 }
2216
2217 static void wl_free_wdev(struct wl_priv *wl)
2218 {
2219         struct wireless_dev *wdev = wl_to_wdev(wl);
2220
2221         if (unlikely(!wdev)) {
2222                 WL_ERR(("wdev is invalid\n"));
2223                 return;
2224         }
2225         wiphy_unregister(wdev->wiphy);
2226         wiphy_free(wdev->wiphy);
2227         kfree(wdev);
2228         wl_to_wdev(wl) = NULL;
2229 }
2230
2231 static s32 wl_inform_bss(struct wl_priv *wl)
2232 {
2233         struct wl_scan_results *bss_list;
2234         struct wl_bss_info *bi = NULL;  /* must be initialized */
2235         s32 err = 0;
2236         int i;
2237
2238         bss_list = wl->bss_list;
2239         if (unlikely(bss_list->version != WL_BSS_INFO_VERSION)) {
2240                 WL_ERR(("Version %d != WL_BSS_INFO_VERSION\n",
2241                         bss_list->version));
2242                 return -EOPNOTSUPP;
2243         }
2244         WL_DBG(("scanned AP count (%d)\n", bss_list->count));
2245         bi = next_bss(bss_list, bi);
2246         for_each_bss(bss_list, bi, i) {
2247                 err = wl_inform_single_bss(wl, bi);
2248                 if (unlikely(err))
2249                         break;
2250         }
2251         return err;
2252 }
2253
2254 static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi)
2255 {
2256         struct wiphy *wiphy = wl_to_wiphy(wl);
2257         struct ieee80211_mgmt *mgmt;
2258         struct ieee80211_channel *channel;
2259         struct ieee80211_supported_band *band;
2260         struct wl_cfg80211_bss_info *notif_bss_info;
2261         struct wl_scan_req *sr = wl_to_sr(wl);
2262         struct beacon_proberesp *beacon_proberesp;
2263         s32 mgmt_type;
2264         u32 signal;
2265         u32 freq;
2266         s32 err = 0;
2267
2268         if (unlikely(dtoh32(bi->length) > WL_BSS_INFO_MAX)) {
2269                 WL_DBG(("Beacon is larger than buffer. Discarding\n"));
2270                 return err;
2271         }
2272         notif_bss_info =
2273             kzalloc(sizeof(*notif_bss_info) + sizeof(*mgmt) - sizeof(u8) +
2274                     WL_BSS_INFO_MAX, GFP_KERNEL);
2275         if (unlikely(!notif_bss_info)) {
2276                 WL_ERR(("notif_bss_info alloc failed\n"));
2277                 return -ENOMEM;
2278         }
2279         mgmt = (struct ieee80211_mgmt *)notif_bss_info->frame_buf;
2280         notif_bss_info->channel =
2281                 bi->ctl_ch ? bi->ctl_ch : CHSPEC_CHANNEL(bi->chanspec);
2282
2283         if (notif_bss_info->channel <= CH_MAX_2G_CHANNEL)
2284                 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2285         else
2286                 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2287         notif_bss_info->rssi = bi->RSSI;
2288         memcpy(mgmt->bssid, &bi->BSSID, ETHER_ADDR_LEN);
2289         mgmt_type = wl->active_scan ?
2290                 IEEE80211_STYPE_PROBE_RESP : IEEE80211_STYPE_BEACON;
2291         if (!memcmp(bi->SSID, sr->ssid.SSID, bi->SSID_len)) {
2292                 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
2293                                                         mgmt_type);
2294         }
2295         beacon_proberesp = wl->active_scan ?
2296                 (struct beacon_proberesp *)&mgmt->u.probe_resp :
2297                 (struct beacon_proberesp *)&mgmt->u.beacon;
2298         beacon_proberesp->timestamp = 0;
2299         beacon_proberesp->beacon_int = cpu_to_le16(bi->beacon_period);
2300         beacon_proberesp->capab_info = cpu_to_le16(bi->capability);
2301         wl_rst_ie(wl);
2302         /*
2303         * wl_add_ie is not necessary because it can only add duplicated
2304         * SSID, rate information to frame_buf
2305         */
2306         /*
2307         * wl_add_ie(wl, WLAN_EID_SSID, bi->SSID_len, bi->SSID);
2308         * wl_add_ie(wl, WLAN_EID_SUPP_RATES, bi->rateset.count,
2309         * bi->rateset.rates);
2310         */
2311         wl_mrg_ie(wl, ((u8 *) bi) + bi->ie_offset, bi->ie_length);
2312         wl_cp_ie(wl, beacon_proberesp->variable, WL_BSS_INFO_MAX -
2313                  offsetof(struct wl_cfg80211_bss_info, frame_buf));
2314         notif_bss_info->frame_len =
2315             offsetof(struct ieee80211_mgmt,
2316                      u.beacon.variable) + wl_get_ielen(wl);
2317         freq = ieee80211_channel_to_frequency(notif_bss_info->channel);
2318         channel = ieee80211_get_channel(wiphy, freq);
2319
2320         WL_DBG(("SSID : \"%s\", rssi %d, channel %d, capability : 0x04%x, bssid %pM\n",
2321                 bi->SSID,
2322                 notif_bss_info->rssi, notif_bss_info->channel,
2323                 mgmt->u.beacon.capab_info, &bi->BSSID));
2324
2325         signal = notif_bss_info->rssi * 100;
2326         if (unlikely(!cfg80211_inform_bss_frame(wiphy, channel, mgmt,
2327                                                 le16_to_cpu
2328                                                 (notif_bss_info->frame_len),
2329                                                 signal, GFP_KERNEL))) {
2330                 WL_ERR(("cfg80211_inform_bss_frame error\n"));
2331                 kfree(notif_bss_info);
2332                 return -EINVAL;
2333         }
2334         kfree(notif_bss_info);
2335
2336         return err;
2337 }
2338
2339 static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e)
2340 {
2341         u32 event = ntoh32(e->event_type);
2342         u16 flags = ntoh16(e->flags);
2343
2344         if (event == WLC_E_LINK) {
2345                 if (flags & WLC_EVENT_MSG_LINK) {
2346                         if (wl_is_ibssmode(wl)) {
2347                                 if (wl_is_ibssstarter(wl)) {
2348                                 }
2349                         } else {
2350                                 return true;
2351                         }
2352                 }
2353         }
2354
2355         return false;
2356 }
2357
2358 static bool wl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e)
2359 {
2360         u32 event = ntoh32(e->event_type);
2361         u16 flags = ntoh16(e->flags);
2362
2363         if (event == WLC_E_DEAUTH_IND || event == WLC_E_DISASSOC_IND) {
2364                 return true;
2365         } else if (event == WLC_E_LINK) {
2366                 if (!(flags & WLC_EVENT_MSG_LINK))
2367                         return true;
2368         }
2369
2370         return false;
2371 }
2372
2373 static bool wl_is_nonetwork(struct wl_priv *wl, const wl_event_msg_t *e)
2374 {
2375         u32 event = ntoh32(e->event_type);
2376         u32 status = ntoh32(e->status);
2377
2378         if (event == WLC_E_SET_SSID || event == WLC_E_LINK) {
2379                 if (status == WLC_E_STATUS_NO_NETWORKS)
2380                         return true;
2381         }
2382
2383         return false;
2384 }
2385
2386 static s32
2387 wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
2388                          const wl_event_msg_t *e, void *data)
2389 {
2390         bool act;
2391         s32 err = 0;
2392
2393         if (wl_is_linkup(wl, e)) {
2394                 wl_link_up(wl);
2395                 if (wl_is_ibssmode(wl)) {
2396                         cfg80211_ibss_joined(ndev, (s8 *)&e->addr,
2397                                              GFP_KERNEL);
2398                         WL_DBG(("joined in IBSS network\n"));
2399                 } else {
2400                         wl_bss_connect_done(wl, ndev, e, data, true);
2401                         WL_DBG(("joined in BSS network \"%s\"\n",
2402                                 ((struct wlc_ssid *)
2403                                  wl_read_prof(wl, WL_PROF_SSID))->SSID));
2404                 }
2405                 act = true;
2406                 wl_update_prof(wl, e, &act, WL_PROF_ACT);
2407         } else if (wl_is_linkdown(wl, e)) {
2408                 cfg80211_disconnected(ndev, 0, NULL, 0, GFP_KERNEL);
2409                 clear_bit(WL_STATUS_CONNECTED, &wl->status);
2410                 wl_link_down(wl);
2411                 wl_init_prof(wl->profile);
2412         } else if (wl_is_nonetwork(wl, e)) {
2413                 wl_bss_connect_done(wl, ndev, e, data, false);
2414         }
2415
2416         return err;
2417 }
2418
2419 static s32
2420 wl_notify_roaming_status(struct wl_priv *wl, struct net_device *ndev,
2421                          const wl_event_msg_t *e, void *data)
2422 {
2423         bool act;
2424         s32 err = 0;
2425
2426         wl_bss_roaming_done(wl, ndev, e, data);
2427         act = true;
2428         wl_update_prof(wl, e, &act, WL_PROF_ACT);
2429
2430         return err;
2431 }
2432
2433 static __used s32
2434 wl_dev_bufvar_set(struct net_device *dev, s8 *name, s8 *buf, s32 len)
2435 {
2436         struct wl_priv *wl = ndev_to_wl(dev);
2437         u32 buflen;
2438
2439         buflen = bcm_mkiovar(name, buf, len, wl->ioctl_buf, WL_IOCTL_LEN_MAX);
2440         BUG_ON(unlikely(!buflen));
2441
2442         return wl_dev_ioctl(dev, WLC_SET_VAR, wl->ioctl_buf, buflen);
2443 }
2444
2445 static s32
2446 wl_dev_bufvar_get(struct net_device *dev, s8 *name, s8 *buf,
2447                   s32 buf_len)
2448 {
2449         struct wl_priv *wl = ndev_to_wl(dev);
2450         u32 len;
2451         s32 err = 0;
2452
2453         len = bcm_mkiovar(name, NULL, 0, wl->ioctl_buf, WL_IOCTL_LEN_MAX);
2454         BUG_ON(unlikely(!len));
2455         err = wl_dev_ioctl(dev, WLC_GET_VAR, (void *)wl->ioctl_buf,
2456                         WL_IOCTL_LEN_MAX);
2457         if (unlikely(err)) {
2458                 WL_ERR(("error (%d)\n", err));
2459                 return err;
2460         }
2461         memcpy(buf, wl->ioctl_buf, buf_len);
2462
2463         return err;
2464 }
2465
2466 static s32 wl_get_assoc_ies(struct wl_priv *wl)
2467 {
2468         struct net_device *ndev = wl_to_ndev(wl);
2469         struct wl_assoc_ielen *assoc_info;
2470         struct wl_connect_info *conn_info = wl_to_conn(wl);
2471         u32 req_len;
2472         u32 resp_len;
2473         s32 err = 0;
2474
2475         err = wl_dev_bufvar_get(ndev, "assoc_info", wl->extra_buf,
2476                                 WL_ASSOC_INFO_MAX);
2477         if (unlikely(err)) {
2478                 WL_ERR(("could not get assoc info (%d)\n", err));
2479                 return err;
2480         }
2481         assoc_info = (struct wl_assoc_ielen *)wl->extra_buf;
2482         req_len = assoc_info->req_len;
2483         resp_len = assoc_info->resp_len;
2484         if (req_len) {
2485                 err = wl_dev_bufvar_get(ndev, "assoc_req_ies", wl->extra_buf,
2486                                         WL_ASSOC_INFO_MAX);
2487                 if (unlikely(err)) {
2488                         WL_ERR(("could not get assoc req (%d)\n", err));
2489                         return err;
2490                 }
2491                 conn_info->req_ie_len = req_len;
2492                 conn_info->req_ie =
2493                     kmemdup(wl->extra_buf, conn_info->req_ie_len, GFP_KERNEL);
2494         } else {
2495                 conn_info->req_ie_len = 0;
2496                 conn_info->req_ie = NULL;
2497         }
2498         if (resp_len) {
2499                 err = wl_dev_bufvar_get(ndev, "assoc_resp_ies", wl->extra_buf,
2500                                         WL_ASSOC_INFO_MAX);
2501                 if (unlikely(err)) {
2502                         WL_ERR(("could not get assoc resp (%d)\n", err));
2503                         return err;
2504                 }
2505                 conn_info->resp_ie_len = resp_len;
2506                 conn_info->resp_ie =
2507                     kmemdup(wl->extra_buf, conn_info->resp_ie_len, GFP_KERNEL);
2508         } else {
2509                 conn_info->resp_ie_len = 0;
2510                 conn_info->resp_ie = NULL;
2511         }
2512         WL_DBG(("req len (%d) resp len (%d)\n", conn_info->req_ie_len,
2513                 conn_info->resp_ie_len));
2514
2515         return err;
2516 }
2517
2518 static void wl_ch_to_chanspec(int ch, struct wl_join_params *join_params,
2519         size_t *join_params_size)
2520 {
2521         chanspec_t chanspec = 0;
2522
2523         if (ch != 0) {
2524                 join_params->params.chanspec_num = 1;
2525                 join_params->params.chanspec_list[0] = ch;
2526
2527                 if (join_params->params.chanspec_list[0])
2528                         chanspec |= WL_CHANSPEC_BAND_2G;
2529                 else
2530                         chanspec |= WL_CHANSPEC_BAND_5G;
2531
2532                 chanspec |= WL_CHANSPEC_BW_20;
2533                 chanspec |= WL_CHANSPEC_CTL_SB_NONE;
2534
2535                 *join_params_size += WL_ASSOC_PARAMS_FIXED_SIZE +
2536                         join_params->params.chanspec_num * sizeof(chanspec_t);
2537
2538                 join_params->params.chanspec_list[0] &= WL_CHANSPEC_CHAN_MASK;
2539                 join_params->params.chanspec_list[0] |= chanspec;
2540                 join_params->params.chanspec_list[0] =
2541                 htodchanspec(join_params->params.chanspec_list[0]);
2542
2543                 join_params->params.chanspec_num =
2544                         htod32(join_params->params.chanspec_num);
2545
2546                 WL_DBG(("join_params->params.chanspec_list[0]= %#X, channel %d, chanspec %#X\n",
2547                         join_params->params.chanspec_list[0], ch, chanspec));
2548         }
2549 }
2550
2551 static s32 wl_update_bss_info(struct wl_priv *wl)
2552 {
2553         struct cfg80211_bss *bss;
2554         struct wl_bss_info *bi;
2555         struct wlc_ssid *ssid;
2556         s32 err = 0;
2557
2558         if (wl_is_ibssmode(wl))
2559                 return err;
2560
2561         ssid = (struct wlc_ssid *)wl_read_prof(wl, WL_PROF_SSID);
2562         bss =
2563             cfg80211_get_bss(wl_to_wiphy(wl), NULL, (s8 *)&wl->bssid,
2564                              ssid->SSID, ssid->SSID_len, WLAN_CAPABILITY_ESS,
2565                              WLAN_CAPABILITY_ESS);
2566
2567         rtnl_lock();
2568         if (unlikely(!bss)) {
2569                 WL_DBG(("Could not find the AP\n"));
2570                 *(u32 *) wl->extra_buf = htod32(WL_EXTRA_BUF_MAX);
2571                 err = wl_dev_ioctl(wl_to_ndev(wl), WLC_GET_BSS_INFO,
2572                                 wl->extra_buf, WL_EXTRA_BUF_MAX);
2573                 if (unlikely(err)) {
2574                         WL_ERR(("Could not get bss info %d\n", err));
2575                         goto update_bss_info_out;
2576                 }
2577                 bi = (struct wl_bss_info *)(wl->extra_buf + 4);
2578                 if (unlikely(memcmp(&bi->BSSID, &wl->bssid, ETHER_ADDR_LEN))) {
2579                         err = -EIO;
2580                         goto update_bss_info_out;
2581                 }
2582                 err = wl_inform_single_bss(wl, bi);
2583                 if (unlikely(err))
2584                         goto update_bss_info_out;
2585         } else {
2586                 WL_DBG(("Found the AP in the list - BSSID %pM\n", bss->bssid));
2587                 cfg80211_put_bss(bss);
2588         }
2589
2590 update_bss_info_out:
2591         rtnl_unlock();
2592         return err;
2593 }
2594
2595 static s32
2596 wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev,
2597                     const wl_event_msg_t *e, void *data)
2598 {
2599         struct wl_connect_info *conn_info = wl_to_conn(wl);
2600         s32 err = 0;
2601
2602         wl_get_assoc_ies(wl);
2603         memcpy(&wl->bssid, &e->addr, ETHER_ADDR_LEN);
2604         wl_update_bss_info(wl);
2605         cfg80211_roamed(ndev,
2606                         (u8 *)&wl->bssid,
2607                         conn_info->req_ie, conn_info->req_ie_len,
2608                         conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
2609         WL_DBG(("Report roaming result\n"));
2610
2611         set_bit(WL_STATUS_CONNECTED, &wl->status);
2612
2613         return err;
2614 }
2615
2616 static s32
2617 wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
2618                     const wl_event_msg_t *e, void *data, bool completed)
2619 {
2620         struct wl_connect_info *conn_info = wl_to_conn(wl);
2621         s32 err = 0;
2622
2623         wl_get_assoc_ies(wl);
2624         memcpy(&wl->bssid, &e->addr, ETHER_ADDR_LEN);
2625         wl_update_bss_info(wl);
2626         if (test_and_clear_bit(WL_STATUS_CONNECTING, &wl->status)) {
2627                 cfg80211_connect_result(ndev,
2628                                         (u8 *)&wl->bssid,
2629                                         conn_info->req_ie,
2630                                         conn_info->req_ie_len,
2631                                         conn_info->resp_ie,
2632                                         conn_info->resp_ie_len,
2633                                         completed ? WLAN_STATUS_SUCCESS : WLAN_STATUS_AUTH_TIMEOUT,
2634                                         GFP_KERNEL);
2635                 WL_DBG(("Report connect result - connection %s\n",
2636                         completed ? "succeeded" : "failed"));
2637         } else {
2638                 cfg80211_roamed(ndev,
2639                                 (u8 *)&wl->bssid,
2640                                 conn_info->req_ie, conn_info->req_ie_len,
2641                                 conn_info->resp_ie, conn_info->resp_ie_len,
2642                                 GFP_KERNEL);
2643                 WL_DBG(("Report roaming result\n"));
2644         }
2645         set_bit(WL_STATUS_CONNECTED, &wl->status);
2646
2647         return err;
2648 }
2649
2650 static s32
2651 wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev,
2652                      const wl_event_msg_t *e, void *data)
2653 {
2654         u16 flags = ntoh16(e->flags);
2655         enum nl80211_key_type key_type;
2656
2657         rtnl_lock();
2658         if (flags & WLC_EVENT_MSG_GROUP)
2659                 key_type = NL80211_KEYTYPE_GROUP;
2660         else
2661                 key_type = NL80211_KEYTYPE_PAIRWISE;
2662
2663         cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1,
2664                                      NULL, GFP_KERNEL);
2665         rtnl_unlock();
2666
2667         return 0;
2668 }
2669
2670 static s32
2671 wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev,
2672                       const wl_event_msg_t *e, void *data)
2673 {
2674         struct channel_info channel_inform;
2675         struct wl_scan_results *bss_list;
2676         u32 len = WL_SCAN_BUF_MAX;
2677         s32 err = 0;
2678
2679         if (wl->iscan_on && wl->iscan_kickstart)
2680                 return wl_wakeup_iscan(wl_to_iscan(wl));
2681
2682         if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING, &wl->status))) {
2683                 WL_ERR(("Scan complete while device not scanning\n"));
2684                 return -EINVAL;
2685         }
2686         if (unlikely(!wl->scan_request)) {
2687         }
2688         rtnl_lock();
2689         err = wl_dev_ioctl(ndev, WLC_GET_CHANNEL, &channel_inform,
2690                         sizeof(channel_inform));
2691         if (unlikely(err)) {
2692                 WL_ERR(("scan busy (%d)\n", err));
2693                 goto scan_done_out;
2694         }
2695         channel_inform.scan_channel = dtoh32(channel_inform.scan_channel);
2696         if (unlikely(channel_inform.scan_channel)) {
2697
2698                 WL_DBG(("channel_inform.scan_channel (%d)\n",
2699                         channel_inform.scan_channel));
2700         }
2701         wl->bss_list = wl->scan_results;
2702         bss_list = wl->bss_list;
2703         memset(bss_list, 0, len);
2704         bss_list->buflen = htod32(len);
2705         err = wl_dev_ioctl(ndev, WLC_SCAN_RESULTS, bss_list, len);
2706         if (unlikely(err)) {
2707                 WL_ERR(("%s Scan_results error (%d)\n", ndev->name, err));
2708                 err = -EINVAL;
2709                 goto scan_done_out;
2710         }
2711         bss_list->buflen = dtoh32(bss_list->buflen);
2712         bss_list->version = dtoh32(bss_list->version);
2713         bss_list->count = dtoh32(bss_list->count);
2714
2715         err = wl_inform_bss(wl);
2716         if (err)
2717                 goto scan_done_out;
2718
2719 scan_done_out:
2720         if (wl->scan_request) {
2721                 cfg80211_scan_done(wl->scan_request, false);
2722                 wl_set_mpc(ndev, 1);
2723                 wl->scan_request = NULL;
2724         }
2725         rtnl_unlock();
2726         return err;
2727 }
2728
2729 static void wl_init_conf(struct wl_conf *conf)
2730 {
2731         conf->mode = (u32)-1;
2732         conf->frag_threshold = (u32)-1;
2733         conf->rts_threshold = (u32)-1;
2734         conf->retry_short = (u32)-1;
2735         conf->retry_long = (u32)-1;
2736         conf->tx_power = -1;
2737 }
2738
2739 static void wl_init_prof(struct wl_profile *prof)
2740 {
2741         memset(prof, 0, sizeof(*prof));
2742 }
2743
2744 static void wl_init_eloop_handler(struct wl_event_loop *el)
2745 {
2746         memset(el, 0, sizeof(*el));
2747         el->handler[WLC_E_SCAN_COMPLETE] = wl_notify_scan_status;
2748         el->handler[WLC_E_JOIN] = wl_notify_connect_status;
2749         el->handler[WLC_E_LINK] = wl_notify_connect_status;
2750         el->handler[WLC_E_DEAUTH_IND] = wl_notify_connect_status;
2751         el->handler[WLC_E_DISASSOC_IND] = wl_notify_connect_status;
2752         el->handler[WLC_E_ASSOC_IND] = wl_notify_connect_status;
2753         el->handler[WLC_E_REASSOC_IND] = wl_notify_connect_status;
2754         el->handler[WLC_E_ROAM] = wl_notify_roaming_status;
2755         el->handler[WLC_E_MIC_ERROR] = wl_notify_mic_status;
2756         el->handler[WLC_E_SET_SSID] = wl_notify_connect_status;
2757 }
2758
2759 static s32 wl_init_priv_mem(struct wl_priv *wl)
2760 {
2761         wl->scan_results = (void *)kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
2762         if (unlikely(!wl->scan_results)) {
2763                 WL_ERR(("Scan results alloc failed\n"));
2764                 goto init_priv_mem_out;
2765         }
2766         wl->conf = (void *)kzalloc(sizeof(*wl->conf), GFP_KERNEL);
2767         if (unlikely(!wl->conf)) {
2768                 WL_ERR(("wl_conf alloc failed\n"));
2769                 goto init_priv_mem_out;
2770         }
2771         wl->profile = (void *)kzalloc(sizeof(*wl->profile), GFP_KERNEL);
2772         if (unlikely(!wl->profile)) {
2773                 WL_ERR(("wl_profile alloc failed\n"));
2774                 goto init_priv_mem_out;
2775         }
2776         wl->bss_info = (void *)kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2777         if (unlikely(!wl->bss_info)) {
2778                 WL_ERR(("Bss information alloc failed\n"));
2779                 goto init_priv_mem_out;
2780         }
2781         wl->scan_req_int =
2782             (void *)kzalloc(sizeof(*wl->scan_req_int), GFP_KERNEL);
2783         if (unlikely(!wl->scan_req_int)) {
2784                 WL_ERR(("Scan req alloc failed\n"));
2785                 goto init_priv_mem_out;
2786         }
2787         wl->ioctl_buf = (void *)kzalloc(WL_IOCTL_LEN_MAX, GFP_KERNEL);
2788         if (unlikely(!wl->ioctl_buf)) {
2789                 WL_ERR(("Ioctl buf alloc failed\n"));
2790                 goto init_priv_mem_out;
2791         }
2792         wl->extra_buf = (void *)kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
2793         if (unlikely(!wl->extra_buf)) {
2794                 WL_ERR(("Extra buf alloc failed\n"));
2795                 goto init_priv_mem_out;
2796         }
2797         wl->iscan = (void *)kzalloc(sizeof(*wl->iscan), GFP_KERNEL);
2798         if (unlikely(!wl->iscan)) {
2799                 WL_ERR(("Iscan buf alloc failed\n"));
2800                 goto init_priv_mem_out;
2801         }
2802         wl->fw = (void *)kzalloc(sizeof(*wl->fw), GFP_KERNEL);
2803         if (unlikely(!wl->fw)) {
2804                 WL_ERR(("fw object alloc failed\n"));
2805                 goto init_priv_mem_out;
2806         }
2807         wl->pmk_list = (void *)kzalloc(sizeof(*wl->pmk_list), GFP_KERNEL);
2808         if (unlikely(!wl->pmk_list)) {
2809                 WL_ERR(("pmk list alloc failed\n"));
2810                 goto init_priv_mem_out;
2811         }
2812
2813         return 0;
2814
2815 init_priv_mem_out:
2816         wl_deinit_priv_mem(wl);
2817
2818         return -ENOMEM;
2819 }
2820
2821 static void wl_deinit_priv_mem(struct wl_priv *wl)
2822 {
2823         kfree(wl->scan_results);
2824         wl->scan_results = NULL;
2825         kfree(wl->bss_info);
2826         wl->bss_info = NULL;
2827         kfree(wl->conf);
2828         wl->conf = NULL;
2829         kfree(wl->profile);
2830         wl->profile = NULL;
2831         kfree(wl->scan_req_int);
2832         wl->scan_req_int = NULL;
2833         kfree(wl->ioctl_buf);
2834         wl->ioctl_buf = NULL;
2835         kfree(wl->extra_buf);
2836         wl->extra_buf = NULL;
2837         kfree(wl->iscan);
2838         wl->iscan = NULL;
2839         kfree(wl->fw);
2840         wl->fw = NULL;
2841         kfree(wl->pmk_list);
2842         wl->pmk_list = NULL;
2843 }
2844
2845 static s32 wl_create_event_handler(struct wl_priv *wl)
2846 {
2847         sema_init(&wl->event_sync, 0);
2848         wl->event_tsk = kthread_run(wl_event_handler, wl, "wl_event_handler");
2849         if (IS_ERR(wl->event_tsk)) {
2850                 wl->event_tsk = NULL;
2851                 WL_ERR(("failed to create event thread\n"));
2852                 return -ENOMEM;
2853         }
2854         return 0;
2855 }
2856
2857 static void wl_destroy_event_handler(struct wl_priv *wl)
2858 {
2859         if (wl->event_tsk) {
2860                 send_sig(SIGTERM, wl->event_tsk, 1);
2861                 kthread_stop(wl->event_tsk);
2862                 wl->event_tsk = NULL;
2863         }
2864 }
2865
2866 static void wl_term_iscan(struct wl_priv *wl)
2867 {
2868         struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
2869
2870         if (wl->iscan_on && iscan->tsk) {
2871                 iscan->state = WL_ISCAN_STATE_IDLE;
2872                 send_sig(SIGTERM, iscan->tsk, 1);
2873                 kthread_stop(iscan->tsk);
2874                 iscan->tsk = NULL;
2875         }
2876 }
2877
2878 static void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted)
2879 {
2880         struct wl_priv *wl = iscan_to_wl(iscan);
2881         struct net_device *ndev = wl_to_ndev(wl);
2882
2883         if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING, &wl->status))) {
2884                 WL_ERR(("Scan complete while device not scanning\n"));
2885                 return;
2886         }
2887         if (likely(wl->scan_request)) {
2888                 cfg80211_scan_done(wl->scan_request, aborted);
2889                 wl_set_mpc(ndev, 1);
2890                 wl->scan_request = NULL;
2891         }
2892         wl->iscan_kickstart = false;
2893 }
2894
2895 static s32 wl_wakeup_iscan(struct wl_iscan_ctrl *iscan)
2896 {
2897         if (likely(iscan->state != WL_ISCAN_STATE_IDLE)) {
2898                 WL_DBG(("wake up iscan\n"));
2899                 up(&iscan->sync);
2900                 return 0;
2901         }
2902
2903         return -EIO;
2904 }
2905
2906 static s32
2907 wl_get_iscan_results(struct wl_iscan_ctrl *iscan, u32 *status,
2908                      struct wl_scan_results **bss_list)
2909 {
2910         struct wl_iscan_results list;
2911         struct wl_scan_results *results;
2912         struct wl_iscan_results *list_buf;
2913         s32 err = 0;
2914
2915         memset(iscan->scan_buf, 0, WL_ISCAN_BUF_MAX);
2916         list_buf = (struct wl_iscan_results *)iscan->scan_buf;
2917         results = &list_buf->results;
2918         results->buflen = WL_ISCAN_RESULTS_FIXED_SIZE;
2919         results->version = 0;
2920         results->count = 0;
2921
2922         memset(&list, 0, sizeof(list));
2923         list.results.buflen = htod32(WL_ISCAN_BUF_MAX);
2924         err = wl_dev_iovar_getbuf(iscan->dev, "iscanresults", &list,
2925                                 WL_ISCAN_RESULTS_FIXED_SIZE, iscan->scan_buf,
2926                                 WL_ISCAN_BUF_MAX);
2927         if (unlikely(err)) {
2928                 WL_ERR(("error (%d)\n", err));
2929                 return err;
2930         }
2931         results->buflen = dtoh32(results->buflen);
2932         results->version = dtoh32(results->version);
2933         results->count = dtoh32(results->count);
2934         WL_DBG(("results->count = %d\n", results->count));
2935         WL_DBG(("results->buflen = %d\n", results->buflen));
2936         *status = dtoh32(list_buf->status);
2937         *bss_list = results;
2938
2939         return err;
2940 }
2941
2942 static s32 wl_iscan_done(struct wl_priv *wl)
2943 {
2944         struct wl_iscan_ctrl *iscan = wl->iscan;
2945         s32 err = 0;
2946
2947         iscan->state = WL_ISCAN_STATE_IDLE;
2948         rtnl_lock();
2949         wl_inform_bss(wl);
2950         wl_notify_iscan_complete(iscan, false);
2951         rtnl_unlock();
2952
2953         return err;
2954 }
2955
2956 static s32 wl_iscan_pending(struct wl_priv *wl)
2957 {
2958         struct wl_iscan_ctrl *iscan = wl->iscan;
2959         s32 err = 0;
2960
2961         /* Reschedule the timer */
2962         mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
2963         iscan->timer_on = 1;
2964
2965         return err;
2966 }
2967
2968 static s32 wl_iscan_inprogress(struct wl_priv *wl)
2969 {
2970         struct wl_iscan_ctrl *iscan = wl->iscan;
2971         s32 err = 0;
2972
2973         rtnl_lock();
2974         wl_inform_bss(wl);
2975         wl_run_iscan(iscan, NULL, WL_SCAN_ACTION_CONTINUE);
2976         rtnl_unlock();
2977         /* Reschedule the timer */
2978         mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
2979         iscan->timer_on = 1;
2980
2981         return err;
2982 }
2983
2984 static s32 wl_iscan_aborted(struct wl_priv *wl)
2985 {
2986         struct wl_iscan_ctrl *iscan = wl->iscan;
2987         s32 err = 0;
2988
2989         iscan->state = WL_ISCAN_STATE_IDLE;
2990         rtnl_lock();
2991         wl_notify_iscan_complete(iscan, true);
2992         rtnl_unlock();
2993
2994         return err;
2995 }
2996
2997 static s32 wl_iscan_thread(void *data)
2998 {
2999         struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1 };
3000         struct wl_iscan_ctrl *iscan = (struct wl_iscan_ctrl *)data;
3001         struct wl_priv *wl = iscan_to_wl(iscan);
3002         struct wl_iscan_eloop *el = &iscan->el;
3003         u32 status;
3004         int err = 0;
3005
3006         sched_setscheduler(current, SCHED_FIFO, &param);
3007         allow_signal(SIGTERM);
3008         status = WL_SCAN_RESULTS_PARTIAL;
3009         while (likely(!down_interruptible(&iscan->sync))) {
3010                 if (kthread_should_stop())
3011                         break;
3012                 if (iscan->timer_on) {
3013                         del_timer_sync(&iscan->timer);
3014                         iscan->timer_on = 0;
3015                 }
3016                 rtnl_lock();
3017                 err = wl_get_iscan_results(iscan, &status, &wl->bss_list);
3018                 if (unlikely(err)) {
3019                         status = WL_SCAN_RESULTS_ABORTED;
3020                         WL_ERR(("Abort iscan\n"));
3021                 }
3022                 rtnl_unlock();
3023                 el->handler[status] (wl);
3024         }
3025         if (iscan->timer_on) {
3026                 del_timer_sync(&iscan->timer);
3027                 iscan->timer_on = 0;
3028         }
3029         WL_DBG(("%s was terminated\n", __func__));
3030
3031         return 0;
3032 }
3033
3034 static void wl_iscan_timer(unsigned long data)
3035 {
3036         struct wl_iscan_ctrl *iscan = (struct wl_iscan_ctrl *)data;
3037
3038         if (iscan) {
3039                 iscan->timer_on = 0;
3040                 WL_DBG(("timer expired\n"));
3041                 wl_wakeup_iscan(iscan);
3042         }
3043 }
3044
3045 static s32 wl_invoke_iscan(struct wl_priv *wl)
3046 {
3047         struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
3048         int err = 0;
3049
3050         if (wl->iscan_on && !iscan->tsk) {
3051                 iscan->state = WL_ISCAN_STATE_IDLE;
3052                 sema_init(&iscan->sync, 0);
3053                 iscan->tsk = kthread_run(wl_iscan_thread, iscan, "wl_iscan");
3054                 if (IS_ERR(iscan->tsk)) {
3055                         WL_ERR(("Could not create iscan thread\n"));
3056                         iscan->tsk = NULL;
3057                         return -ENOMEM;
3058                 }
3059         }
3060
3061         return err;
3062 }
3063
3064 static void wl_init_iscan_eloop(struct wl_iscan_eloop *el)
3065 {
3066         memset(el, 0, sizeof(*el));
3067         el->handler[WL_SCAN_RESULTS_SUCCESS] = wl_iscan_done;
3068         el->handler[WL_SCAN_RESULTS_PARTIAL] = wl_iscan_inprogress;
3069         el->handler[WL_SCAN_RESULTS_PENDING] = wl_iscan_pending;
3070         el->handler[WL_SCAN_RESULTS_ABORTED] = wl_iscan_aborted;
3071         el->handler[WL_SCAN_RESULTS_NO_MEM] = wl_iscan_aborted;
3072 }
3073
3074 static s32 wl_init_iscan(struct wl_priv *wl)
3075 {
3076         struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
3077         int err = 0;
3078
3079         if (wl->iscan_on) {
3080                 iscan->dev = wl_to_ndev(wl);
3081                 iscan->state = WL_ISCAN_STATE_IDLE;
3082                 wl_init_iscan_eloop(&iscan->el);
3083                 iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS;
3084                 init_timer(&iscan->timer);
3085                 iscan->timer.data = (unsigned long) iscan;
3086                 iscan->timer.function = wl_iscan_timer;
3087                 sema_init(&iscan->sync, 0);
3088                 iscan->tsk = kthread_run(wl_iscan_thread, iscan, "wl_iscan");
3089                 if (IS_ERR(iscan->tsk)) {
3090                         WL_ERR(("Could not create iscan thread\n"));
3091                         iscan->tsk = NULL;
3092                         return -ENOMEM;
3093                 }
3094                 iscan->data = wl;
3095         }
3096
3097         return err;
3098 }
3099
3100 static void wl_init_fw(struct wl_fw_ctrl *fw)
3101 {
3102         fw->status = 0;         /* init fw loading status.
3103                                  0 means nothing was loaded yet */
3104 }
3105
3106 static s32 wl_init_priv(struct wl_priv *wl)
3107 {
3108         struct wiphy *wiphy = wl_to_wiphy(wl);
3109         s32 err = 0;
3110
3111         wl->scan_request = NULL;
3112         wl->pwr_save = !!(wiphy->flags & WIPHY_FLAG_PS_ON_BY_DEFAULT);
3113         wl->iscan_on = true;    /* iscan on & off switch.
3114                                  we enable iscan per default */
3115         wl->roam_on = false;    /* roam on & off switch.
3116                                  we enable roam per default */
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 __used 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 }