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