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