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