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