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