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