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