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