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