2
* Linux-specific portion of Broadcom 802.11abg Networking Device Driver
5
* Copyright (C) 2013, Broadcom Corporation. All Rights Reserved.
7
* Permission to use, copy, modify, and/or distribute this software for any
8
* purpose with or without fee is hereby granted, provided that the above
9
* copyright notice and this permission notice appear in all copies.
11
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
14
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
16
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
17
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
* $Id: wl_cfg80211.c,v 1.1.6.4 2011-02-11 00:22:09 $
22
#if defined(USE_CFG80211)
29
#include <linux/kernel.h>
30
#include <linux/kthread.h>
31
#include <linux/netdevice.h>
32
#include <linux/ieee80211.h>
33
#include <net/cfg80211.h>
34
#include <linux/nl80211.h>
35
#include <net/rtnetlink.h>
37
#include <bcmendian.h>
39
#include <proto/802.11.h>
40
#include <wl_cfg80211_hybrid.h>
42
#define EVENT_TYPE(e) dtoh32((e)->event_type)
43
#define EVENT_FLAGS(e) dtoh16((e)->flags)
44
#define EVENT_STATUS(e) dtoh32((e)->status)
46
u32 wl_dbg_level = WL_DBG_ERR | WL_DBG_INFO;
48
static s32 wl_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
49
enum nl80211_iftype type, u32 *flags, struct vif_params *params);
50
static s32 wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
51
struct cfg80211_scan_request *request);
52
static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed);
53
static s32 wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
54
struct cfg80211_ibss_params *params);
55
static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev);
56
static s32 wl_cfg80211_get_station(struct wiphy *wiphy,
57
struct net_device *dev, u8 *mac, struct station_info *sinfo);
58
static s32 wl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
59
struct net_device *dev, bool enabled, s32 timeout);
60
static int wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
61
struct cfg80211_connect_params *sme);
62
static s32 wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code);
64
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)
65
static s32 wl_cfg80211_set_tx_power(struct wiphy *wiphy,
66
enum nl80211_tx_power_setting type, s32 dbm);
68
static s32 wl_cfg80211_set_tx_power(struct wiphy *wiphy,
69
enum tx_power_setting type, s32 dbm);
72
static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm);
74
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)
75
static s32 wl_cfg80211_config_default_key(struct wiphy *wiphy,
76
struct net_device *dev, u8 key_idx, bool unicast, bool multicast);
78
static s32 wl_cfg80211_config_default_key(struct wiphy *wiphy,
79
struct net_device *dev, u8 key_idx);
81
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)
82
static s32 wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
83
u8 key_idx, bool pairwise, const u8 *mac_addr, struct key_params *params);
84
static s32 wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
85
u8 key_idx, bool pairwise, const u8 *mac_addr);
86
static s32 wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
87
u8 key_idx, bool pairwise, const u8 *mac_addr,
88
void *cookie, void (*callback) (void *cookie, struct key_params *params));
90
static s32 wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
91
u8 key_idx, const u8 *mac_addr, struct key_params *params);
92
static s32 wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
93
u8 key_idx, const u8 *mac_addr);
94
static s32 wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
95
u8 key_idx, const u8 *mac_addr,
96
void *cookie, void (*callback) (void *cookie, struct key_params *params));
99
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)
100
static s32 wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
101
struct cfg80211_pmksa *pmksa);
102
static s32 wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
103
struct cfg80211_pmksa *pmksa);
104
static s32 wl_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev);
107
static s32 wl_create_event_handler(struct wl_cfg80211_priv *wl);
108
static void wl_destroy_event_handler(struct wl_cfg80211_priv *wl);
109
static s32 wl_event_handler(void *data);
110
static void wl_init_eq(struct wl_cfg80211_priv *wl);
111
static void wl_flush_eq(struct wl_cfg80211_priv *wl);
112
static void wl_lock_eq(struct wl_cfg80211_priv *wl);
113
static void wl_unlock_eq(struct wl_cfg80211_priv *wl);
114
static void wl_init_eq_lock(struct wl_cfg80211_priv *wl);
115
static void wl_init_eloop_handler(struct wl_cfg80211_event_loop *el);
116
static struct wl_cfg80211_event_q *wl_deq_event(struct wl_cfg80211_priv *wl);
117
static s32 wl_enq_event(struct wl_cfg80211_priv *wl, u32 type,
118
const wl_event_msg_t *msg, void *data);
119
static void wl_put_event(struct wl_cfg80211_event_q *e);
120
static void wl_wakeup_event(struct wl_cfg80211_priv *wl);
122
static s32 wl_notify_connect_status(struct wl_cfg80211_priv *wl, struct net_device *ndev,
123
const wl_event_msg_t *e, void *data);
124
static s32 wl_notify_roaming_status(struct wl_cfg80211_priv *wl, struct net_device *ndev,
125
const wl_event_msg_t *e, void *data);
126
static s32 wl_notify_scan_status(struct wl_cfg80211_priv *wl, struct net_device *ndev,
127
const wl_event_msg_t *e, void *data);
128
static s32 wl_bss_connect_done(struct wl_cfg80211_priv *wl, struct net_device *ndev,
129
const wl_event_msg_t *e, void *data, bool completed);
130
static s32 wl_bss_roaming_done(struct wl_cfg80211_priv *wl, struct net_device *ndev,
131
const wl_event_msg_t *e, void *data);
132
static s32 wl_notify_mic_status(struct wl_cfg80211_priv *wl, struct net_device *ndev,
133
const wl_event_msg_t *e, void *data);
135
static s32 wl_dev_bufvar_get(struct net_device *dev, s8 *name, s8 *buf, s32 buf_len);
136
static __used s32 wl_dev_bufvar_set(struct net_device *dev, s8 *name, s8 *buf, s32 len);
137
static s32 wl_dev_intvar_set(struct net_device *dev, s8 *name, s32 val);
138
static s32 wl_dev_intvar_get(struct net_device *dev, s8 *name, s32 *retval);
139
static s32 wl_dev_ioctl(struct net_device *dev, u32 cmd, void *arg, u32 len);
141
static s32 wl_set_frag(struct net_device *dev, u32 frag_threshold);
142
static s32 wl_set_rts(struct net_device *dev, u32 frag_threshold);
143
static s32 wl_set_retry(struct net_device *dev, u32 retry, bool l);
145
static void wl_init_prof(struct wl_cfg80211_profile *prof);
147
static s32 wl_set_wpa_version(struct net_device *dev, struct cfg80211_connect_params *sme);
148
static s32 wl_set_auth_type(struct net_device *dev, struct cfg80211_connect_params *sme);
149
static s32 wl_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme);
150
static s32 wl_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme);
151
static s32 wl_set_set_sharedkey(struct net_device *dev, struct cfg80211_connect_params *sme);
152
static s32 wl_get_assoc_ies(struct wl_cfg80211_priv *wl);
153
static void wl_ch_to_chanspec(struct ieee80211_channel *chan,
154
struct wl_join_params *join_params, size_t *join_params_size);
156
static void wl_rst_ie(struct wl_cfg80211_priv *wl);
157
static __used s32 wl_add_ie(struct wl_cfg80211_priv *wl, u8 t, u8 l, u8 *v);
158
static s32 wl_mrg_ie(struct wl_cfg80211_priv *wl, u8 *ie_stream, u16 ie_size);
159
static s32 wl_cp_ie(struct wl_cfg80211_priv *wl, u8 *dst, u16 dst_size);
160
static u32 wl_get_ielen(struct wl_cfg80211_priv *wl);
162
static s32 wl_mode_to_nl80211_iftype(s32 mode);
164
static s32 wl_alloc_wdev(struct device *dev, struct wireless_dev **rwdev);
165
static void wl_free_wdev(struct wl_cfg80211_priv *wl);
167
static s32 wl_inform_bss(struct wl_cfg80211_priv *wl, struct wl_scan_results *bss_list);
168
static s32 wl_inform_single_bss(struct wl_cfg80211_priv *wl, struct wl_bss_info *bi);
169
static s32 wl_update_bss_info(struct wl_cfg80211_priv *wl);
171
static void key_endian_to_device(struct wl_wsec_key *key);
172
static void key_endian_to_host(struct wl_wsec_key *key);
174
static s32 wl_init_priv_mem(struct wl_cfg80211_priv *wl);
175
static void wl_deinit_priv_mem(struct wl_cfg80211_priv *wl);
177
static bool wl_is_ibssmode(struct wl_cfg80211_priv *wl);
179
static void wl_link_up(struct wl_cfg80211_priv *wl);
180
static void wl_link_down(struct wl_cfg80211_priv *wl);
181
static s32 wl_set_mode(struct net_device *ndev, s32 iftype);
183
static void wl_init_conf(struct wl_cfg80211_conf *conf);
185
static s32 wl_update_wiphybands(struct wl_cfg80211_priv *wl);
187
static __used s32 wl_update_pmklist(struct net_device *dev,
188
struct wl_cfg80211_pmk_list *pmk_list, s32 err);
190
#if defined(WL_DBGMSG_ENABLE)
191
#define WL_DBG_ESTR_MAX 32
192
static s8 wl_dbg_estr[][WL_DBG_ESTR_MAX] = {
193
"SET_SSID", "JOIN", "START", "AUTH", "AUTH_IND",
194
"DEAUTH", "DEAUTH_IND", "ASSOC", "ASSOC_IND", "REASSOC",
195
"REASSOC_IND", "DISASSOC", "DISASSOC_IND", "QUIET_START", "QUIET_END",
196
"BEACON_RX", "LINK", "MIC_ERROR", "NDIS_LINK", "ROAM",
197
"TXFAIL", "PMKID_CACHE", "RETROGRADE_TSF", "PRUNE", "AUTOAUTH",
198
"EAPOL_MSG", "SCAN_COMPLETE", "ADDTS_IND", "DELTS_IND", "BCNSENT_IND",
199
"BCNRX_MSG", "BCNLOST_MSG", "ROAM_PREP", "PFN_NET_FOUND",
201
"RESET_COMPLETE", "JOIN_START", "ROAM_START", "ASSOC_START",
203
"RADIO", "PSM_WATCHDOG",
205
"SCAN_CONFIRM_IND", "PSK_SUP", "COUNTRY_CODE_CHANGED",
206
"EXCEEDED_MEDIUM_TIME", "ICV_ERROR",
207
"UNICAST_DECODE_ERROR", "MULTICAST_DECODE_ERROR", "TRACE",
209
"RSSI", "PFN_SCAN_COMPLETE", "ACTION_FRAME", "ACTION_FRAME_COMPLETE",
213
#define CHAN2G(_channel, _freq, _flags) { \
214
.band = IEEE80211_BAND_2GHZ, \
215
.center_freq = (_freq), \
216
.hw_value = (_channel), \
218
.max_antenna_gain = 0, \
222
#define CHAN5G(_channel, _flags) { \
223
.band = IEEE80211_BAND_5GHZ, \
224
.center_freq = 5000 + (5 * (_channel)), \
225
.hw_value = (_channel), \
227
.max_antenna_gain = 0, \
231
#define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
232
#define RATETAB_ENT(_rateid, _flags) \
234
.bitrate = RATE_TO_BASE100KBPS(_rateid), \
235
.hw_value = (_rateid), \
239
static struct ieee80211_rate __wl_rates[] = {
240
RATETAB_ENT(DOT11_RATE_1M, 0),
241
RATETAB_ENT(DOT11_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
242
RATETAB_ENT(DOT11_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
243
RATETAB_ENT(DOT11_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
244
RATETAB_ENT(DOT11_RATE_6M, 0),
245
RATETAB_ENT(DOT11_RATE_9M, 0),
246
RATETAB_ENT(DOT11_RATE_12M, 0),
247
RATETAB_ENT(DOT11_RATE_18M, 0),
248
RATETAB_ENT(DOT11_RATE_24M, 0),
249
RATETAB_ENT(DOT11_RATE_36M, 0),
250
RATETAB_ENT(DOT11_RATE_48M, 0),
251
RATETAB_ENT(DOT11_RATE_54M, 0),
254
#define wl_a_rates (__wl_rates + 4)
255
#define wl_a_rates_size 8
256
#define wl_g_rates (__wl_rates + 0)
257
#define wl_g_rates_size 12
259
static struct ieee80211_channel __wl_2ghz_channels[] = {
276
static struct ieee80211_channel __wl_5ghz_a_channels[] = {
277
CHAN5G(34, 0), CHAN5G(36, 0),
278
CHAN5G(38, 0), CHAN5G(40, 0),
279
CHAN5G(42, 0), CHAN5G(44, 0),
280
CHAN5G(46, 0), CHAN5G(48, 0),
281
CHAN5G(52, 0), CHAN5G(56, 0),
282
CHAN5G(60, 0), CHAN5G(64, 0),
283
CHAN5G(100, 0), CHAN5G(104, 0),
284
CHAN5G(108, 0), CHAN5G(112, 0),
285
CHAN5G(116, 0), CHAN5G(120, 0),
286
CHAN5G(124, 0), CHAN5G(128, 0),
287
CHAN5G(132, 0), CHAN5G(136, 0),
288
CHAN5G(140, 0), CHAN5G(149, 0),
289
CHAN5G(153, 0), CHAN5G(157, 0),
290
CHAN5G(161, 0), CHAN5G(165, 0),
291
CHAN5G(184, 0), CHAN5G(188, 0),
292
CHAN5G(192, 0), CHAN5G(196, 0),
293
CHAN5G(200, 0), CHAN5G(204, 0),
294
CHAN5G(208, 0), CHAN5G(212, 0),
298
static struct ieee80211_channel __wl_5ghz_n_channels[] = {
299
CHAN5G(32, 0), CHAN5G(34, 0),
300
CHAN5G(36, 0), CHAN5G(38, 0),
301
CHAN5G(40, 0), CHAN5G(42, 0),
302
CHAN5G(44, 0), CHAN5G(46, 0),
303
CHAN5G(48, 0), CHAN5G(50, 0),
304
CHAN5G(52, 0), CHAN5G(54, 0),
305
CHAN5G(56, 0), CHAN5G(58, 0),
306
CHAN5G(60, 0), CHAN5G(62, 0),
307
CHAN5G(64, 0), CHAN5G(66, 0),
308
CHAN5G(68, 0), CHAN5G(70, 0),
309
CHAN5G(72, 0), CHAN5G(74, 0),
310
CHAN5G(76, 0), CHAN5G(78, 0),
311
CHAN5G(80, 0), CHAN5G(82, 0),
312
CHAN5G(84, 0), CHAN5G(86, 0),
313
CHAN5G(88, 0), CHAN5G(90, 0),
314
CHAN5G(92, 0), CHAN5G(94, 0),
315
CHAN5G(96, 0), CHAN5G(98, 0),
316
CHAN5G(100, 0), CHAN5G(102, 0),
317
CHAN5G(104, 0), CHAN5G(106, 0),
318
CHAN5G(108, 0), CHAN5G(110, 0),
319
CHAN5G(112, 0), CHAN5G(114, 0),
320
CHAN5G(116, 0), CHAN5G(118, 0),
321
CHAN5G(120, 0), CHAN5G(122, 0),
322
CHAN5G(124, 0), CHAN5G(126, 0),
323
CHAN5G(128, 0), CHAN5G(130, 0),
324
CHAN5G(132, 0), CHAN5G(134, 0),
325
CHAN5G(136, 0), CHAN5G(138, 0),
326
CHAN5G(140, 0), CHAN5G(142, 0),
327
CHAN5G(144, 0), CHAN5G(145, 0),
328
CHAN5G(146, 0), CHAN5G(147, 0),
329
CHAN5G(148, 0), CHAN5G(149, 0),
330
CHAN5G(150, 0), CHAN5G(151, 0),
331
CHAN5G(152, 0), CHAN5G(153, 0),
332
CHAN5G(154, 0), CHAN5G(155, 0),
333
CHAN5G(156, 0), CHAN5G(157, 0),
334
CHAN5G(158, 0), CHAN5G(159, 0),
335
CHAN5G(160, 0), CHAN5G(161, 0),
336
CHAN5G(162, 0), CHAN5G(163, 0),
337
CHAN5G(164, 0), CHAN5G(165, 0),
338
CHAN5G(166, 0), CHAN5G(168, 0),
339
CHAN5G(170, 0), CHAN5G(172, 0),
340
CHAN5G(174, 0), CHAN5G(176, 0),
341
CHAN5G(178, 0), CHAN5G(180, 0),
342
CHAN5G(182, 0), CHAN5G(184, 0),
343
CHAN5G(186, 0), CHAN5G(188, 0),
344
CHAN5G(190, 0), CHAN5G(192, 0),
345
CHAN5G(194, 0), CHAN5G(196, 0),
346
CHAN5G(198, 0), CHAN5G(200, 0),
347
CHAN5G(202, 0), CHAN5G(204, 0),
348
CHAN5G(206, 0), CHAN5G(208, 0),
349
CHAN5G(210, 0), CHAN5G(212, 0),
350
CHAN5G(214, 0), CHAN5G(216, 0),
351
CHAN5G(218, 0), CHAN5G(220, 0),
352
CHAN5G(222, 0), CHAN5G(224, 0),
353
CHAN5G(226, 0), CHAN5G(228, 0),
356
static struct ieee80211_supported_band __wl_band_2ghz = {
357
.band = IEEE80211_BAND_2GHZ,
358
.channels = __wl_2ghz_channels,
359
.n_channels = ARRAY_SIZE(__wl_2ghz_channels),
360
.bitrates = wl_g_rates,
361
.n_bitrates = wl_g_rates_size,
364
static struct ieee80211_supported_band __wl_band_5ghz_a = {
365
.band = IEEE80211_BAND_5GHZ,
366
.channels = __wl_5ghz_a_channels,
367
.n_channels = ARRAY_SIZE(__wl_5ghz_a_channels),
368
.bitrates = wl_a_rates,
369
.n_bitrates = wl_a_rates_size,
372
static struct ieee80211_supported_band __wl_band_5ghz_n = {
373
.band = IEEE80211_BAND_5GHZ,
374
.channels = __wl_5ghz_n_channels,
375
.n_channels = ARRAY_SIZE(__wl_5ghz_n_channels),
376
.bitrates = wl_a_rates,
377
.n_bitrates = wl_a_rates_size,
380
static const u32 __wl_cipher_suites[] = {
381
WLAN_CIPHER_SUITE_WEP40,
382
WLAN_CIPHER_SUITE_WEP104,
383
WLAN_CIPHER_SUITE_TKIP,
384
WLAN_CIPHER_SUITE_CCMP,
385
WLAN_CIPHER_SUITE_AES_CMAC,
388
static void key_endian_to_device(struct wl_wsec_key *key)
390
key->index = htod32(key->index);
391
key->len = htod32(key->len);
392
key->algo = htod32(key->algo);
393
key->flags = htod32(key->flags);
394
key->rxiv.hi = htod32(key->rxiv.hi);
395
key->rxiv.lo = htod16(key->rxiv.lo);
396
key->iv_initialized = htod32(key->iv_initialized);
399
static void key_endian_to_host(struct wl_wsec_key *key)
401
key->index = dtoh32(key->index);
402
key->len = dtoh32(key->len);
403
key->algo = dtoh32(key->algo);
404
key->flags = dtoh32(key->flags);
405
key->rxiv.hi = dtoh32(key->rxiv.hi);
406
key->rxiv.lo = dtoh16(key->rxiv.lo);
407
key->iv_initialized = dtoh32(key->iv_initialized);
411
wl_dev_ioctl(struct net_device *dev, u32 cmd, void *arg, u32 len)
418
BUG_ON(len < sizeof(int));
420
memset(&ioc, 0, sizeof(ioc));
424
strcpy(ifr.ifr_name, dev->name);
425
ifr.ifr_data = (caddr_t)&ioc;
429
#if defined(WL_USE_NETDEV_OPS)
430
err = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, SIOCDEVPRIVATE);
432
err = dev->do_ioctl(dev, &ifr, SIOCDEVPRIVATE);
440
wl_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
441
enum nl80211_iftype type, u32 *flags,
442
struct vif_params *params)
444
struct wl_cfg80211_priv *wl = wiphy_to_wl(wiphy);
445
struct wireless_dev *wdev;
451
case NL80211_IFTYPE_MONITOR:
452
case NL80211_IFTYPE_WDS:
453
WL_ERR(("type (%d) : currently we do not support this type\n",
456
case NL80211_IFTYPE_ADHOC:
457
wl->conf->mode = WL_MODE_IBSS;
459
case NL80211_IFTYPE_STATION:
460
wl->conf->mode = WL_MODE_BSS;
466
infra = htod32(infra);
468
wdev = ndev->ieee80211_ptr;
470
WL_DBG(("%s : ap (%d), infra (%d)\n", ndev->name, ap, infra));
471
err = wl_dev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(infra));
473
WL_ERR(("WLC_SET_INFRA error (%d)\n", err));
476
err = wl_dev_ioctl(ndev, WLC_SET_AP, &ap, sizeof(ap));
478
WL_ERR(("WLC_SET_AP error (%d)\n", err));
486
wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
487
struct cfg80211_scan_request *request)
489
struct wl_cfg80211_priv *wl = ndev_to_wl(ndev);
490
struct cfg80211_ssid *ssids;
491
struct wl_cfg80211_scan_req *sr = wl_to_sr(wl);
496
ssids = request->ssids;
502
wl->scan_request = request;
504
memset(&sr->ssid, 0, sizeof(sr->ssid));
507
WL_DBG(("ssid \"%s\", ssid_len (%d)\n", ssids->ssid, ssids->ssid_len));
508
sr->ssid.SSID_len = min_t(u8, sizeof(sr->ssid.SSID), ssids->ssid_len);
511
if (sr->ssid.SSID_len) {
512
memcpy(sr->ssid.SSID, ssids->ssid, sr->ssid.SSID_len);
513
sr->ssid.SSID_len = htod32(sr->ssid.SSID_len);
514
WL_DBG(("Specific scan ssid=\"%s\" len=%d\n", sr->ssid.SSID, sr->ssid.SSID_len));
516
WL_DBG(("Broadcast scan\n"));
518
WL_DBG(("sr->ssid.SSID_len (%d)\n", sr->ssid.SSID_len));
519
passive_scan = wl->active_scan ? 0 : 1;
520
err = wl_dev_ioctl(ndev, WLC_SET_PASSIVE_SCAN, &passive_scan, sizeof(passive_scan));
522
WL_ERR(("WLC_SET_PASSIVE_SCAN error (%d)\n", err));
525
err = wl_dev_ioctl(ndev, WLC_SCAN, &sr->ssid, sizeof(sr->ssid));
528
WL_INF(("system busy : scan for \"%s\" "
529
"canceled\n", sr->ssid.SSID));
531
WL_ERR(("WLC_SCAN error (%d)\n", err));
539
wl->scan_request = NULL;
543
static s32 wl_dev_intvar_set(struct net_device *dev, s8 *name, s32 val)
545
s8 buf[WLC_IOCTL_SMLEN];
550
len = bcm_mkiovar(name, (char *)(&val), sizeof(val), buf, sizeof(buf));
553
err = wl_dev_ioctl(dev, WLC_SET_VAR, buf, len);
555
WL_ERR(("error (%d)\n", err));
562
wl_dev_intvar_get(struct net_device *dev, s8 *name, s32 *retval)
565
s8 buf[WLC_IOCTL_SMLEN];
572
len = bcm_mkiovar(name, (char *)(&data_null), 0, (char *)(&var), sizeof(var.buf));
574
err = wl_dev_ioctl(dev, WLC_GET_VAR, &var, len);
576
WL_ERR(("error (%d)\n", err));
578
*retval = dtoh32(var.val);
583
static s32 wl_set_rts(struct net_device *dev, u32 rts_threshold)
587
err = wl_dev_intvar_set(dev, "rtsthresh", rts_threshold);
589
WL_ERR(("Error (%d)\n", err));
595
static s32 wl_set_frag(struct net_device *dev, u32 frag_threshold)
599
err = wl_dev_intvar_set(dev, "fragthresh", frag_threshold);
601
WL_ERR(("Error (%d)\n", err));
607
static s32 wl_set_retry(struct net_device *dev, u32 retry, bool l)
610
u32 cmd = (l ? WLC_SET_LRL : WLC_SET_SRL);
612
retry = htod32(retry);
613
err = wl_dev_ioctl(dev, cmd, &retry, sizeof(retry));
615
WL_ERR(("cmd (%d) , error (%d)\n", cmd, err));
621
static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
623
struct wl_cfg80211_priv *wl = wiphy_to_wl(wiphy);
624
struct net_device *ndev = wl_to_ndev(wl);
627
if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
628
(wl->conf->rts_threshold != wiphy->rts_threshold)) {
629
wl->conf->rts_threshold = wiphy->rts_threshold;
630
err = wl_set_rts(ndev, wl->conf->rts_threshold);
634
if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
635
(wl->conf->frag_threshold != wiphy->frag_threshold)) {
636
wl->conf->frag_threshold = wiphy->frag_threshold;
637
err = wl_set_frag(ndev, wl->conf->frag_threshold);
641
if (changed & WIPHY_PARAM_RETRY_LONG && (wl->conf->retry_long != wiphy->retry_long)) {
642
wl->conf->retry_long = wiphy->retry_long;
643
err = wl_set_retry(ndev, wl->conf->retry_long, true);
647
if (changed & WIPHY_PARAM_RETRY_SHORT && (wl->conf->retry_short != wiphy->retry_short)) {
648
wl->conf->retry_short = wiphy->retry_short;
649
err = wl_set_retry(ndev, wl->conf->retry_short, false);
659
wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
660
struct cfg80211_ibss_params *params)
662
struct wl_join_params join_params;
663
size_t join_params_size;
670
WL_ERR(("Invalid bssid\n"));
674
if ((err = wl_dev_intvar_set(dev, "auth", 0))) {
677
if ((err = wl_dev_intvar_set(dev, "wpa_auth", WPA_AUTH_NONE))) {
680
if ((err = wl_dev_intvar_get(dev, "wsec", &val))) {
683
val &= ~(WEP_ENABLED | TKIP_ENABLED | AES_ENABLED);
684
if ((err = wl_dev_intvar_set(dev, "wsec", val))) {
688
memset(&join_params, 0, sizeof(join_params));
689
join_params_size = sizeof(join_params.ssid);
691
memcpy((void *)join_params.ssid.SSID, (void *)params->ssid, params->ssid_len);
692
join_params.ssid.SSID_len = htod32(params->ssid_len);
694
memcpy(&join_params.params.bssid, params->bssid, ETHER_ADDR_LEN);
696
memset(&join_params.params.bssid, 0, ETHER_ADDR_LEN);
698
wl_ch_to_chanspec(params->channel, &join_params, &join_params_size);
700
err = wl_dev_ioctl(dev, WLC_SET_SSID, &join_params, join_params_size);
702
WL_ERR(("Error (%d)\n", err));
708
static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
710
struct wl_cfg80211_priv *wl = wiphy_to_wl(wiphy);
721
wl_set_wpa_version(struct net_device *dev, struct cfg80211_connect_params *sme)
723
struct wl_cfg80211_priv *wl = ndev_to_wl(dev);
727
if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
728
val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
729
else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
730
val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
732
val = WPA_AUTH_DISABLED;
733
WL_DBG(("setting wpa_auth to 0x%0x\n", val));
734
err = wl_dev_intvar_set(dev, "wpa_auth", val);
736
WL_ERR(("set wpa_auth failed (%d)\n", err));
739
wl->profile->sec.wpa_versions = sme->crypto.wpa_versions;
744
wl_set_auth_type(struct net_device *dev, struct cfg80211_connect_params *sme)
746
struct wl_cfg80211_priv *wl = ndev_to_wl(dev);
750
switch (sme->auth_type) {
751
case NL80211_AUTHTYPE_OPEN_SYSTEM:
753
WL_DBG(("open system\n"));
755
case NL80211_AUTHTYPE_SHARED_KEY:
757
WL_DBG(("shared key\n"));
759
case NL80211_AUTHTYPE_AUTOMATIC:
761
WL_DBG(("automatic\n"));
763
case NL80211_AUTHTYPE_NETWORK_EAP:
764
WL_DBG(("network eap\n"));
767
WL_ERR(("invalid auth type (%d)\n", sme->auth_type));
771
err = wl_dev_intvar_set(dev, "auth", val);
773
WL_ERR(("set auth failed (%d)\n", err));
777
wl->profile->sec.auth_type = sme->auth_type;
782
wl_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme)
784
struct wl_cfg80211_priv *wl = ndev_to_wl(dev);
790
if (sme->crypto.n_ciphers_pairwise) {
791
switch (sme->crypto.ciphers_pairwise[0]) {
792
case WLAN_CIPHER_SUITE_WEP40:
793
case WLAN_CIPHER_SUITE_WEP104:
796
case WLAN_CIPHER_SUITE_TKIP:
799
case WLAN_CIPHER_SUITE_CCMP:
802
case WLAN_CIPHER_SUITE_AES_CMAC:
806
WL_ERR(("invalid cipher pairwise (%d)\n", sme->crypto.ciphers_pairwise[0]));
810
if (sme->crypto.cipher_group) {
811
switch (sme->crypto.cipher_group) {
812
case WLAN_CIPHER_SUITE_WEP40:
813
case WLAN_CIPHER_SUITE_WEP104:
816
case WLAN_CIPHER_SUITE_TKIP:
819
case WLAN_CIPHER_SUITE_CCMP:
822
case WLAN_CIPHER_SUITE_AES_CMAC:
826
WL_ERR(("invalid cipher group (%d)\n", sme->crypto.cipher_group));
831
if ((err = wl_dev_intvar_get(dev, "wsec", &val))) {
834
val &= ~(WEP_ENABLED | TKIP_ENABLED | AES_ENABLED);
836
WL_DBG(("set wsec to %d\n", val));
837
err = wl_dev_intvar_set(dev, "wsec", val);
839
WL_ERR(("error (%d)\n", err));
843
wl->profile->sec.cipher_pairwise = sme->crypto.ciphers_pairwise[0];
844
wl->profile->sec.cipher_group = sme->crypto.cipher_group;
850
wl_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme)
852
struct wl_cfg80211_priv *wl = ndev_to_wl(dev);
856
if (sme->crypto.n_akm_suites) {
857
err = wl_dev_intvar_get(dev, "wpa_auth", &val);
859
WL_ERR(("could not get wpa_auth (%d)\n", err));
862
if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
863
switch (sme->crypto.akm_suites[0]) {
864
case WLAN_AKM_SUITE_8021X:
865
val = WPA_AUTH_UNSPECIFIED;
867
case WLAN_AKM_SUITE_PSK:
871
WL_ERR(("invalid cipher group (%d)\n", sme->crypto.cipher_group));
874
} else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
875
switch (sme->crypto.akm_suites[0]) {
876
case WLAN_AKM_SUITE_8021X:
877
val = WPA2_AUTH_UNSPECIFIED;
879
case WLAN_AKM_SUITE_PSK:
883
WL_ERR(("invalid cipher group (%d)\n", sme->crypto.cipher_group));
888
WL_DBG(("setting wpa_auth to %d\n", val));
889
err = wl_dev_intvar_set(dev, "wpa_auth", val);
891
WL_ERR(("could not set wpa_auth (%d)\n", err));
896
wl->profile->sec.wpa_auth = sme->crypto.akm_suites[0];
902
wl_set_set_sharedkey(struct net_device *dev, struct cfg80211_connect_params *sme)
904
struct wl_cfg80211_priv *wl = ndev_to_wl(dev);
905
struct wl_cfg80211_security *sec;
906
struct wl_wsec_key key;
909
WL_DBG(("key len (%d)\n", sme->key_len));
911
sec = &wl->profile->sec;
912
WL_DBG(("wpa_versions 0x%x cipher_pairwise 0x%x\n",
913
sec->wpa_versions, sec->cipher_pairwise));
914
if (!(sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2)) &&
915
(sec->cipher_pairwise &
916
(WLAN_CIPHER_SUITE_WEP40 | WLAN_CIPHER_SUITE_WEP104))) {
917
memset(&key, 0, sizeof(key));
918
key.len = (u32) sme->key_len;
919
key.index = (u32) sme->key_idx;
920
if (key.len > sizeof(key.data)) {
921
WL_ERR(("Too long key length (%u)\n", key.len));
924
memcpy(key.data, sme->key, key.len);
925
key.flags = WL_PRIMARY_KEY;
926
switch (sec->cipher_pairwise) {
927
case WLAN_CIPHER_SUITE_WEP40:
928
key.algo = CRYPTO_ALGO_WEP1;
930
case WLAN_CIPHER_SUITE_WEP104:
931
key.algo = CRYPTO_ALGO_WEP128;
934
WL_ERR(("Invalid algorithm (%d)\n",
935
sme->crypto.ciphers_pairwise[0]));
939
WL_DBG(("key length (%d) key index (%d) algo (%d)\n", key.len,
940
key.index, key.algo));
941
WL_DBG(("key \"%s\"\n", key.data));
942
key_endian_to_device(&key);
943
err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
945
WL_ERR(("WLC_SET_KEY error (%d)\n", err));
954
wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
955
struct cfg80211_connect_params *sme)
957
struct wl_cfg80211_priv *wl = wiphy_to_wl(wiphy);
958
struct wl_join_params join_params;
959
size_t join_params_size;
964
WL_ERR(("Invalid ssid\n"));
968
WL_DBG(("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len));
970
err = wl_set_auth_type(dev, sme);
974
err = wl_set_wpa_version(dev, sme);
978
err = wl_set_set_cipher(dev, sme);
982
err = wl_set_key_mgmt(dev, sme);
986
err = wl_set_set_sharedkey(dev, sme);
991
wl_dev_bufvar_set(dev, "wsec_restrict", &valc, 1);
994
memcpy(wl->profile->bssid, sme->bssid, ETHER_ADDR_LEN);
997
memset(wl->profile->bssid, 0, ETHER_ADDR_LEN);
1000
memset(&join_params, 0, sizeof(join_params));
1001
join_params_size = sizeof(join_params.ssid);
1003
join_params.ssid.SSID_len = min(sizeof(join_params.ssid.SSID), sme->ssid_len);
1004
memcpy(&join_params.ssid.SSID, sme->ssid, join_params.ssid.SSID_len);
1005
join_params.ssid.SSID_len = htod32(join_params.ssid.SSID_len);
1006
memcpy(&join_params.params.bssid, ðer_bcast, ETHER_ADDR_LEN);
1008
memcpy(wl->profile->ssid.SSID, &join_params.ssid.SSID, join_params.ssid.SSID_len);
1009
wl->profile->ssid.SSID_len = join_params.ssid.SSID_len;
1011
wl_ch_to_chanspec(sme->channel, &join_params, &join_params_size);
1012
WL_DBG(("join_param_size %u\n", (unsigned int)join_params_size));
1014
if (join_params.ssid.SSID_len < IEEE80211_MAX_SSID_LEN) {
1015
WL_DBG(("ssid \"%s\", len (%d)\n", join_params.ssid.SSID,
1016
join_params.ssid.SSID_len));
1018
err = wl_dev_ioctl(dev, WLC_SET_SSID, &join_params, join_params_size);
1020
WL_ERR(("error (%d)\n", err));
1024
set_bit(WL_STATUS_CONNECTING, &wl->status);
1030
wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code)
1032
struct wl_cfg80211_priv *wl = wiphy_to_wl(wiphy);
1036
WL_DBG(("Reason %d\n", reason_code));
1038
if (wl->profile->active) {
1039
scbval.val = reason_code;
1040
memcpy(&scbval.ea, &wl->bssid, ETHER_ADDR_LEN);
1041
scbval.val = htod32(scbval.val);
1042
err = wl_dev_ioctl(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t));
1044
WL_ERR(("error (%d)\n", err));
1052
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)
1054
wl_cfg80211_set_tx_power(struct wiphy *wiphy, enum nl80211_tx_power_setting type, s32 dbm)
1056
#define NL80211_TX_POWER_AUTOMATIC TX_POWER_AUTOMATIC
1057
#define NL80211_TX_POWER_LIMITED TX_POWER_LIMITED
1058
#define NL80211_TX_POWER_FIXED TX_POWER_FIXED
1060
wl_cfg80211_set_tx_power(struct wiphy *wiphy, enum tx_power_setting type, s32 dbm)
1064
struct wl_cfg80211_priv *wl = wiphy_to_wl(wiphy);
1065
struct net_device *ndev = wl_to_ndev(wl);
1071
case NL80211_TX_POWER_AUTOMATIC:
1073
case NL80211_TX_POWER_LIMITED:
1075
WL_ERR(("TX_POWER_LIMITTED - dbm is negative\n"));
1079
case NL80211_TX_POWER_FIXED:
1081
WL_ERR(("TX_POWER_FIXED - dbm is negative..\n"));
1087
disable = WL_RADIO_SW_DISABLE << 16;
1088
disable = htod32(disable);
1089
err = wl_dev_ioctl(ndev, WLC_SET_RADIO, &disable, sizeof(disable));
1091
WL_ERR(("WLC_SET_RADIO error (%d)\n", err));
1098
txpwrmw = (u16) dbm;
1099
err = wl_dev_intvar_set(ndev, "qtxpower", (s32) (bcm_mw_to_qdbm(txpwrmw)));
1101
WL_ERR(("qtxpower error (%d)\n", err));
1104
wl->conf->tx_power = dbm;
1109
static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm)
1111
struct wl_cfg80211_priv *wl = wiphy_to_wl(wiphy);
1112
struct net_device *ndev = wl_to_ndev(wl);
1117
err = wl_dev_intvar_get(ndev, "qtxpower", &txpwrdbm);
1119
WL_ERR(("error (%d)\n", err));
1122
result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
1123
*dbm = (s32) bcm_qdbm_to_mw(result);
1128
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)
1130
wl_cfg80211_config_default_key(struct wiphy *wiphy,
1131
struct net_device *dev, u8 key_idx, bool unicast, bool multicast)
1134
wl_cfg80211_config_default_key(struct wiphy *wiphy,
1135
struct net_device *dev, u8 key_idx)
1141
WL_DBG(("key index (%d)\n", key_idx));
1143
index = (u32) key_idx;
1144
index = htod32(index);
1145
err = wl_dev_ioctl(dev, WLC_SET_KEY_PRIMARY, &index, sizeof(index));
1147
WL_DBG(("error (%d)\n", err));
1153
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)
1155
wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
1156
u8 key_idx, bool pairwise, const u8 *mac_addr, struct key_params *params)
1159
wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
1160
u8 key_idx, const u8 *mac_addr, struct key_params *params)
1163
struct wl_cfg80211_priv *wl = ndev_to_wl(dev);
1164
struct wl_wsec_key key;
1165
s32 secval, secnew = 0;
1168
WL_DBG(("key index %u len %u\n", (unsigned)key_idx, params->key_len));
1170
memset(&key, 0, sizeof(key));
1172
key.index = (u32) key_idx;
1174
switch (params->cipher) {
1175
case WLAN_CIPHER_SUITE_WEP40:
1176
key.algo = CRYPTO_ALGO_WEP1;
1177
secnew = WEP_ENABLED;
1178
WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n"));
1180
case WLAN_CIPHER_SUITE_WEP104:
1181
key.algo = CRYPTO_ALGO_WEP128;
1182
secnew = WEP_ENABLED;
1183
WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n"));
1185
case WLAN_CIPHER_SUITE_TKIP:
1186
key.algo = CRYPTO_ALGO_TKIP;
1187
secnew = TKIP_ENABLED;
1188
WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n"));
1190
case WLAN_CIPHER_SUITE_AES_CMAC:
1191
key.algo = CRYPTO_ALGO_AES_CCM;
1192
secnew = AES_ENABLED;
1193
WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n"));
1195
case WLAN_CIPHER_SUITE_CCMP:
1196
key.algo = CRYPTO_ALGO_AES_CCM;
1197
secnew = AES_ENABLED;
1198
WL_DBG(("WLAN_CIPHER_SUITE_CCMP\n"));
1201
WL_ERR(("Invalid cipher (0x%x)\n", params->cipher));
1206
if (!ETHER_ISMULTI(mac_addr)) {
1207
memcpy((char *)&key.ea, (void *)mac_addr, ETHER_ADDR_LEN);
1211
key.len = (u32) params->key_len;
1212
if (key.len > sizeof(key.data)) {
1213
WL_ERR(("Too long key length (%u)\n", key.len));
1216
memcpy(key.data, params->key, key.len);
1218
if (params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1220
memcpy(keybuf, &key.data[24], sizeof(keybuf));
1221
memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1222
memcpy(&key.data[16], keybuf, sizeof(keybuf));
1225
if (params->seq_len) {
1227
if (params->seq_len != 6) {
1228
WL_ERR(("seq_len %d is unexpected, check implementation.\n",
1231
ivptr = (u8 *) params->seq;
1232
key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) | (ivptr[3] << 8) | ivptr[2];
1233
key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
1234
key.iv_initialized = true;
1237
key_endian_to_device(&key);
1238
err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
1240
WL_ERR(("WLC_SET_KEY error (%d)\n", err));
1244
if ((err = wl_dev_intvar_get(dev, "wsec", &secval))) {
1247
if (secnew == WEP_ENABLED) {
1248
secval &= ~(TKIP_ENABLED | AES_ENABLED);
1251
secval &= ~(WEP_ENABLED);
1254
WL_DBG(("set wsec to %d\n", secval));
1255
err = wl_dev_intvar_set(dev, "wsec", secval);
1257
WL_ERR(("error (%d)\n", err));
1262
wl->profile->sec.cipher_pairwise = params->cipher;
1265
wl->profile->sec.cipher_group = params->cipher;
1271
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)
1273
wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
1274
u8 key_idx, bool pairwise, const u8 *mac_addr)
1277
wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
1278
u8 key_idx, const u8 *mac_addr)
1281
struct wl_wsec_key key;
1284
WL_DBG(("key index (%d)\n", key_idx));
1286
memset(&key, 0, sizeof(key));
1288
key.index = (u32) key_idx;
1291
if (!ETHER_ISMULTI(mac_addr)) {
1292
memcpy((char *)&key.ea, (void *)mac_addr, ETHER_ADDR_LEN);
1295
key.algo = CRYPTO_ALGO_OFF;
1297
key_endian_to_device(&key);
1298
err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
1300
if (err == -EINVAL) {
1301
if (key.index >= DOT11_MAX_DEFAULT_KEYS) {
1303
WL_DBG(("invalid key index (%d)\n", key_idx));
1306
WL_ERR(("WLC_SET_KEY error (%d)\n", err));
1314
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)
1316
wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
1317
u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
1318
void (*callback) (void *cookie, struct key_params * params))
1321
wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
1322
u8 key_idx, const u8 *mac_addr, void *cookie,
1323
void (*callback) (void *cookie, struct key_params * params))
1326
struct key_params params;
1327
struct wl_wsec_key key;
1328
struct wl_cfg80211_priv *wl = wiphy_to_wl(wiphy);
1329
struct wl_cfg80211_security *sec;
1333
WL_DBG(("key index (%d)\n", key_idx));
1335
memset(¶ms, 0, sizeof(params));
1337
memset(&key, 0, sizeof(key));
1338
key.index = key_idx;
1339
key_endian_to_device(&key);
1341
if ((err = wl_dev_ioctl(dev, WLC_GET_KEY, &key, sizeof(key)))) {
1344
key_endian_to_host(&key);
1346
params.key_len = (u8) min_t(u8, DOT11_MAX_KEY_SIZE, key.len);
1347
memcpy(params.key, key.data, params.key_len);
1349
if ((err = wl_dev_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec)))) {
1352
wsec = dtoh32(wsec);
1355
sec = &wl->profile->sec;
1356
if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
1357
params.cipher = WLAN_CIPHER_SUITE_WEP40;
1358
WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n"));
1359
} else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
1360
params.cipher = WLAN_CIPHER_SUITE_WEP104;
1361
WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n"));
1365
params.cipher = WLAN_CIPHER_SUITE_TKIP;
1366
WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n"));
1369
params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
1370
WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n"));
1373
WL_ERR(("Invalid algo (0x%x)\n", wsec));
1377
callback(cookie, ¶ms);
1382
wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
1383
u8 *mac, struct station_info *sinfo)
1385
struct wl_cfg80211_priv *wl = wiphy_to_wl(wiphy);
1391
if (memcmp(mac, wl->profile->bssid, ETHER_ADDR_LEN)) {
1392
WL_ERR(("Wrong Mac address\n"));
1396
err = wl_dev_ioctl(dev, WLC_GET_RATE, &rate, sizeof(rate));
1398
WL_DBG(("Could not get rate (%d)\n", err));
1400
rate = dtoh32(rate);
1401
sinfo->filled |= STATION_INFO_TX_BITRATE;
1402
sinfo->txrate.legacy = rate * 5;
1403
WL_DBG(("Rate %d Mbps\n", (rate / 2)));
1406
if (test_bit(WL_STATUS_CONNECTED, &wl->status)) {
1407
memset(&scb_val, 0, sizeof(scb_val));
1408
err = wl_dev_ioctl(dev, WLC_GET_RSSI, &scb_val, sizeof(scb_val_t));
1410
WL_DBG(("Could not get rssi (%d)\n", err));
1413
rssi = dtoh32(scb_val.val);
1414
sinfo->filled |= STATION_INFO_SIGNAL;
1415
sinfo->signal = rssi;
1416
WL_DBG(("RSSI %d dBm\n", rssi));
1423
wl_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
1424
bool enabled, s32 timeout)
1429
pm = enabled ? PM_FAST : PM_OFF;
1431
WL_DBG(("power save %s\n", (pm ? "enabled" : "disabled")));
1432
err = wl_dev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm));
1435
WL_DBG(("net_device is not ready yet\n"));
1437
WL_ERR(("error (%d)\n", err));
1444
wl_update_pmklist(struct net_device *dev, struct wl_cfg80211_pmk_list *pmk_list, s32 err)
1448
WL_DBG(("No of elements %d\n", pmk_list->pmkids.npmkid));
1449
for (i = 0; i < pmk_list->pmkids.npmkid; i++) {
1450
WL_DBG(("PMKID[%d]: %pM =\n", i,
1451
&pmk_list->pmkids.pmkid[i].BSSID));
1452
for (j = 0; j < WPA2_PMKID_LEN; j++) {
1453
WL_DBG(("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]));
1457
err = wl_dev_bufvar_set(dev, "pmkid_info", (char *)pmk_list, sizeof(*pmk_list));
1463
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)
1466
wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
1467
struct cfg80211_pmksa *pmksa)
1469
struct wl_cfg80211_priv *wl = wiphy_to_wl(wiphy);
1473
for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++)
1474
if (!memcmp(pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID, ETHER_ADDR_LEN))
1476
if (i < WL_NUM_PMKIDS_MAX) {
1477
memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID, pmksa->bssid, ETHER_ADDR_LEN);
1478
memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID, pmksa->pmkid, WPA2_PMKID_LEN);
1479
if (i == wl->pmk_list->pmkids.npmkid)
1480
wl->pmk_list->pmkids.npmkid++;
1484
WL_DBG(("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
1485
&wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid].BSSID));
1486
for (i = 0; i < WPA2_PMKID_LEN; i++) {
1488
wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid].PMKID[i]));
1491
err = wl_update_pmklist(dev, wl->pmk_list, err);
1497
wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
1498
struct cfg80211_pmksa *pmksa)
1500
struct wl_cfg80211_priv *wl = wiphy_to_wl(wiphy);
1501
struct _pmkid_list pmkid;
1505
memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETHER_ADDR_LEN);
1506
memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WPA2_PMKID_LEN);
1508
WL_DBG(("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
1509
&pmkid.pmkid[0].BSSID));
1510
for (i = 0; i < WPA2_PMKID_LEN; i++) {
1511
WL_DBG(("%02x\n", pmkid.pmkid[0].PMKID[i]));
1514
for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++)
1515
if (!memcmp(pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID, ETHER_ADDR_LEN))
1518
if ((wl->pmk_list->pmkids.npmkid > 0) && (i < wl->pmk_list->pmkids.npmkid)) {
1519
memset(&wl->pmk_list->pmkids.pmkid[i], 0, sizeof(pmkid_t));
1520
for (; i < (wl->pmk_list->pmkids.npmkid - 1); i++) {
1521
memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID,
1522
&wl->pmk_list->pmkids.pmkid[i + 1].BSSID, ETHER_ADDR_LEN);
1523
memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID,
1524
&wl->pmk_list->pmkids.pmkid[i + 1].PMKID, WPA2_PMKID_LEN);
1526
wl->pmk_list->pmkids.npmkid--;
1531
err = wl_update_pmklist(dev, wl->pmk_list, err);
1538
wl_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
1540
struct wl_cfg80211_priv *wl = wiphy_to_wl(wiphy);
1543
memset(wl->pmk_list, 0, sizeof(*wl->pmk_list));
1544
err = wl_update_pmklist(dev, wl->pmk_list, err);
1551
static struct cfg80211_ops wl_cfg80211_ops = {
1552
.change_virtual_intf = wl_cfg80211_change_iface,
1553
.scan = wl_cfg80211_scan,
1554
.set_wiphy_params = wl_cfg80211_set_wiphy_params,
1555
.join_ibss = wl_cfg80211_join_ibss,
1556
.leave_ibss = wl_cfg80211_leave_ibss,
1557
.get_station = wl_cfg80211_get_station,
1558
.set_tx_power = wl_cfg80211_set_tx_power,
1559
.get_tx_power = wl_cfg80211_get_tx_power,
1560
.add_key = wl_cfg80211_add_key,
1561
.del_key = wl_cfg80211_del_key,
1562
.get_key = wl_cfg80211_get_key,
1563
.set_default_key = wl_cfg80211_config_default_key,
1564
.set_power_mgmt = wl_cfg80211_set_power_mgmt,
1565
.connect = wl_cfg80211_connect,
1566
.disconnect = wl_cfg80211_disconnect,
1567
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)
1568
.set_pmksa = wl_cfg80211_set_pmksa,
1569
.del_pmksa = wl_cfg80211_del_pmksa,
1570
.flush_pmksa = wl_cfg80211_flush_pmksa
1574
static s32 wl_mode_to_nl80211_iftype(s32 mode)
1580
return NL80211_IFTYPE_STATION;
1582
return NL80211_IFTYPE_ADHOC;
1584
return NL80211_IFTYPE_UNSPECIFIED;
1590
static s32 wl_alloc_wdev(struct device *dev, struct wireless_dev **rwdev)
1592
struct wireless_dev *wdev;
1595
wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
1597
WL_ERR(("Could not allocate wireless device\n"));
1601
wdev->wiphy = wiphy_new(&wl_cfg80211_ops, sizeof(struct wl_cfg80211_priv));
1603
WL_ERR(("Couldn not allocate wiphy device\n"));
1607
set_wiphy_dev(wdev->wiphy, dev);
1608
wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
1609
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)
1610
wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
1612
wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
1613
wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
1614
wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a;
1615
wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
1616
wdev->wiphy->cipher_suites = __wl_cipher_suites;
1617
wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
1618
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)
1620
wdev->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
1622
err = wiphy_register(wdev->wiphy);
1624
WL_ERR(("Couldn not register wiphy device (%d)\n", err));
1625
goto wiphy_register_out;
1632
wiphy_free(wdev->wiphy);
1642
static void wl_free_wdev(struct wl_cfg80211_priv *wl)
1644
struct wireless_dev *wdev = wl_to_wdev(wl);
1647
WL_ERR(("wdev is invalid\n"));
1650
wiphy_unregister(wdev->wiphy);
1651
wiphy_free(wdev->wiphy);
1653
wl_to_wdev(wl) = NULL;
1656
static s32 wl_inform_bss(struct wl_cfg80211_priv *wl, struct wl_scan_results *bss_list)
1658
struct wl_bss_info *bi = NULL;
1662
if (bss_list->version != WL_BSS_INFO_VERSION) {
1663
WL_ERR(("Version %d != WL_BSS_INFO_VERSION\n", bss_list->version));
1666
WL_DBG(("scanned AP count (%d)\n", bss_list->count));
1667
bi = next_bss(bss_list, bi);
1668
for_each_bss(bss_list, bi, i) {
1669
err = wl_inform_single_bss(wl, bi);
1676
static s32 wl_inform_single_bss(struct wl_cfg80211_priv *wl, struct wl_bss_info *bi)
1678
struct wiphy *wiphy = wl_to_wiphy(wl);
1679
struct ieee80211_mgmt *mgmt;
1680
struct ieee80211_channel *channel;
1681
struct wl_cfg80211_bss_info *notif_bss_info;
1682
struct wl_cfg80211_scan_req *sr = wl_to_sr(wl);
1683
struct beacon_proberesp *beacon_proberesp;
1689
if (dtoh32(bi->length) > WL_BSS_INFO_MAX) {
1690
WL_DBG(("Beacon is larger than buffer. Discarding\n"));
1693
notif_bss_info = kzalloc(sizeof(*notif_bss_info) + sizeof(*mgmt) - sizeof(u8) +
1694
WL_BSS_INFO_MAX, GFP_KERNEL);
1695
if (!notif_bss_info) {
1696
WL_ERR(("notif_bss_info alloc failed\n"));
1699
mgmt = (struct ieee80211_mgmt *)notif_bss_info->frame_buf;
1700
notif_bss_info->channel = bi->ctl_ch ? bi->ctl_ch : CHSPEC_CHANNEL(bi->chanspec);
1702
notif_bss_info->rssi = bi->RSSI;
1703
memcpy(mgmt->bssid, &bi->BSSID, ETHER_ADDR_LEN);
1704
mgmt_type = wl->active_scan ? IEEE80211_STYPE_PROBE_RESP : IEEE80211_STYPE_BEACON;
1705
if (!memcmp(bi->SSID, sr->ssid.SSID, bi->SSID_len)) {
1706
mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | mgmt_type);
1708
beacon_proberesp = wl->active_scan ? (struct beacon_proberesp *)&mgmt->u.probe_resp :
1709
(struct beacon_proberesp *)&mgmt->u.beacon;
1710
beacon_proberesp->timestamp = 0;
1711
beacon_proberesp->beacon_int = cpu_to_le16(bi->beacon_period);
1712
beacon_proberesp->capab_info = cpu_to_le16(bi->capability);
1715
wl_mrg_ie(wl, ((u8 *) bi) + bi->ie_offset, bi->ie_length);
1716
wl_cp_ie(wl, beacon_proberesp->variable, WL_BSS_INFO_MAX -
1717
offsetof(struct wl_cfg80211_bss_info, frame_buf));
1718
notif_bss_info->frame_len = offsetof(struct ieee80211_mgmt, u.beacon.variable) +
1720
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)
1721
freq = ieee80211_channel_to_frequency(notif_bss_info->channel,
1722
(notif_bss_info->channel <= CH_MAX_2G_CHANNEL) ?
1723
IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ);
1725
freq = ieee80211_channel_to_frequency(notif_bss_info->channel);
1727
channel = ieee80211_get_channel(wiphy, freq);
1729
WL_DBG(("SSID : \"%s\", rssi %d, channel %d, capability : 0x04%x, bssid %pM\n",
1730
bi->SSID, notif_bss_info->rssi, notif_bss_info->channel,
1731
mgmt->u.beacon.capab_info, &bi->BSSID));
1733
signal = notif_bss_info->rssi * 100;
1734
if (!cfg80211_inform_bss_frame(wiphy, channel, mgmt,
1735
le16_to_cpu(notif_bss_info->frame_len), signal, GFP_KERNEL)) {
1736
WL_ERR(("cfg80211_inform_bss_frame error\n"));
1737
kfree(notif_bss_info);
1740
kfree(notif_bss_info);
1746
wl_notify_connect_status(struct wl_cfg80211_priv *wl, struct net_device *ndev,
1747
const wl_event_msg_t *e, void *data)
1750
u32 event = EVENT_TYPE(e);
1751
u16 flags = EVENT_FLAGS(e);
1752
u32 status = EVENT_STATUS(e);
1756
if (!wl_is_ibssmode(wl)) {
1757
if (event == WLC_E_LINK && (flags & WLC_EVENT_MSG_LINK)) {
1759
wl_bss_connect_done(wl, ndev, e, data, true);
1760
wl->profile->active = true;
1762
else if ((event == WLC_E_LINK && ~(flags & WLC_EVENT_MSG_LINK)) ||
1763
event == WLC_E_DEAUTH_IND || event == WLC_E_DISASSOC_IND) {
1764
cfg80211_disconnected(ndev, 0, NULL, 0, GFP_KERNEL);
1765
clear_bit(WL_STATUS_CONNECTED, &wl->status);
1767
wl_init_prof(wl->profile);
1769
else if (event == WLC_E_SET_SSID && status == WLC_E_STATUS_NO_NETWORKS) {
1770
wl_bss_connect_done(wl, ndev, e, data, false);
1773
WL_DBG(("no action (BSS mode)\n"));
1777
if (event == WLC_E_JOIN) {
1778
WL_DBG(("joined in IBSS network\n"));
1780
if (event == WLC_E_START) {
1781
WL_DBG(("started IBSS network\n"));
1783
if (event == WLC_E_JOIN || event == WLC_E_START) {
1785
wl_get_assoc_ies(wl);
1786
memcpy(&wl->bssid, &e->addr, ETHER_ADDR_LEN);
1787
wl_update_bss_info(wl);
1788
cfg80211_ibss_joined(ndev, (u8 *)&wl->bssid, GFP_KERNEL);
1789
set_bit(WL_STATUS_CONNECTED, &wl->status);
1790
wl->profile->active = true;
1792
else if ((event == WLC_E_LINK && ~(flags & WLC_EVENT_MSG_LINK)) ||
1793
event == WLC_E_DEAUTH_IND || event == WLC_E_DISASSOC_IND) {
1794
clear_bit(WL_STATUS_CONNECTED, &wl->status);
1796
wl_init_prof(wl->profile);
1798
else if (event == WLC_E_SET_SSID && status == WLC_E_STATUS_NO_NETWORKS) {
1799
WL_DBG(("no action - join fail (IBSS mode)\n"));
1802
WL_DBG(("no action (IBSS mode)\n"));
1810
wl_notify_roaming_status(struct wl_cfg80211_priv *wl, struct net_device *ndev,
1811
const wl_event_msg_t *e, void *data)
1814
u32 status = EVENT_STATUS(e);
1818
if (status == WLC_E_STATUS_SUCCESS) {
1819
err = wl_bss_roaming_done(wl, ndev, e, data);
1820
wl->profile->active = true;
1827
wl_dev_bufvar_set(struct net_device *dev, s8 *name, s8 *buf, s32 len)
1829
struct wl_cfg80211_priv *wl = ndev_to_wl(dev);
1832
buflen = bcm_mkiovar(name, buf, len, wl->ioctl_buf, WL_IOCTL_LEN_MAX);
1835
return wl_dev_ioctl(dev, WLC_SET_VAR, wl->ioctl_buf, buflen);
1839
wl_dev_bufvar_get(struct net_device *dev, s8 *name, s8 *buf, s32 buf_len)
1841
struct wl_cfg80211_priv *wl = ndev_to_wl(dev);
1845
len = bcm_mkiovar(name, NULL, 0, wl->ioctl_buf, WL_IOCTL_LEN_MAX);
1847
err = wl_dev_ioctl(dev, WLC_GET_VAR, (void *)wl->ioctl_buf, WL_IOCTL_LEN_MAX);
1849
WL_ERR(("error (%d)\n", err));
1852
memcpy(buf, wl->ioctl_buf, buf_len);
1857
static s32 wl_get_assoc_ies(struct wl_cfg80211_priv *wl)
1859
struct net_device *ndev = wl_to_ndev(wl);
1860
struct wl_cfg80211_assoc_ielen *assoc_info;
1861
struct wl_cfg80211_connect_info *conn_info = wl_to_conn(wl);
1866
err = wl_dev_bufvar_get(ndev, "assoc_info", wl->extra_buf, WL_ASSOC_INFO_MAX);
1868
WL_ERR(("could not get assoc info (%d)\n", err));
1871
assoc_info = (struct wl_cfg80211_assoc_ielen *)wl->extra_buf;
1872
req_len = assoc_info->req_len;
1873
resp_len = assoc_info->resp_len;
1875
err = wl_dev_bufvar_get(ndev, "assoc_req_ies", wl->extra_buf, WL_ASSOC_INFO_MAX);
1877
WL_ERR(("could not get assoc req (%d)\n", err));
1880
conn_info->req_ie_len = req_len;
1882
kmemdup(wl->extra_buf, conn_info->req_ie_len, GFP_KERNEL);
1884
conn_info->req_ie_len = 0;
1885
conn_info->req_ie = NULL;
1888
err = wl_dev_bufvar_get(ndev, "assoc_resp_ies", wl->extra_buf, WL_ASSOC_INFO_MAX);
1890
WL_ERR(("could not get assoc resp (%d)\n", err));
1893
conn_info->resp_ie_len = resp_len;
1894
conn_info->resp_ie =
1895
kmemdup(wl->extra_buf, conn_info->resp_ie_len, GFP_KERNEL);
1897
conn_info->resp_ie_len = 0;
1898
conn_info->resp_ie = NULL;
1900
WL_DBG(("req len (%d) resp len (%d)\n", conn_info->req_ie_len,
1901
conn_info->resp_ie_len));
1906
static void wl_ch_to_chanspec(struct ieee80211_channel *chan, struct wl_join_params *join_params,
1907
size_t *join_params_size)
1909
chanspec_t chanspec = 0;
1912
join_params->params.chanspec_num = 1;
1913
join_params->params.chanspec_list[0] =
1914
ieee80211_frequency_to_channel(chan->center_freq);
1916
if (chan->band == IEEE80211_BAND_2GHZ) {
1917
chanspec |= WL_CHANSPEC_BAND_2G;
1919
else if (chan->band == IEEE80211_BAND_5GHZ) {
1920
chanspec |= WL_CHANSPEC_BAND_5G;
1923
WL_ERR(("Unknown band\n"));
1927
chanspec |= WL_CHANSPEC_BW_20;
1929
*join_params_size += WL_ASSOC_PARAMS_FIXED_SIZE +
1930
join_params->params.chanspec_num * sizeof(chanspec_t);
1932
join_params->params.chanspec_list[0] &= WL_CHANSPEC_CHAN_MASK;
1933
join_params->params.chanspec_list[0] |= chanspec;
1934
join_params->params.chanspec_list[0] =
1935
htodchanspec(join_params->params.chanspec_list[0]);
1937
join_params->params.chanspec_num = htod32(join_params->params.chanspec_num);
1939
WL_DBG(("join_params->params.chanspec_list[0]= %#X, channel %d, chanspec %#X\n",
1940
join_params->params.chanspec_list[0],
1941
join_params->params.chanspec_list[0], chanspec));
1945
static s32 wl_update_bss_info(struct wl_cfg80211_priv *wl)
1947
struct cfg80211_bss *bss;
1948
struct wl_bss_info *bi;
1949
struct wlc_ssid *ssid;
1950
struct bcm_tlv *tim;
1956
ssid = &wl->profile->ssid;
1957
bss = cfg80211_get_bss(wl_to_wiphy(wl), NULL, (s8 *)&wl->bssid,
1958
ssid->SSID, ssid->SSID_len, WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
1962
WL_DBG(("Could not find the AP\n"));
1963
*(u32 *) wl->extra_buf = htod32(WL_EXTRA_BUF_MAX);
1964
err = wl_dev_ioctl(wl_to_ndev(wl), WLC_GET_BSS_INFO, wl->extra_buf,
1967
WL_ERR(("Could not get bss info %d\n", err));
1968
goto update_bss_info_out;
1970
bi = (struct wl_bss_info *)(wl->extra_buf + 4);
1971
if (memcmp(&bi->BSSID, &wl->bssid, ETHER_ADDR_LEN)) {
1973
goto update_bss_info_out;
1975
err = wl_inform_single_bss(wl, bi);
1977
goto update_bss_info_out;
1979
ie = ((u8 *)bi) + bi->ie_offset;
1980
ie_len = bi->ie_length;
1982
WL_DBG(("Found the AP in the list - BSSID %pM\n", bss->bssid));
1983
ie = bss->information_elements;
1984
ie_len = bss->len_information_elements;
1985
cfg80211_put_bss(bss);
1988
tim = bcm_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
1990
dtim_period = tim->data[1];
1993
err = wl_dev_ioctl(wl_to_ndev(wl), WLC_GET_DTIMPRD,
1994
&dtim_period, sizeof(dtim_period));
1996
WL_ERR(("WLC_GET_DTIMPRD error (%d)\n", err));
1997
goto update_bss_info_out;
2001
update_bss_info_out:
2007
wl_bss_roaming_done(struct wl_cfg80211_priv *wl, struct net_device *ndev,
2008
const wl_event_msg_t *e, void *data)
2010
struct wl_cfg80211_connect_info *conn_info = wl_to_conn(wl);
2013
wl_get_assoc_ies(wl);
2014
memcpy(&wl->bssid, &e->addr, ETHER_ADDR_LEN);
2015
wl_update_bss_info(wl);
2016
cfg80211_roamed(ndev,
2017
#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)
2021
conn_info->req_ie, conn_info->req_ie_len,
2022
conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
2023
WL_DBG(("Report roaming result\n"));
2025
set_bit(WL_STATUS_CONNECTED, &wl->status);
2031
wl_bss_connect_done(struct wl_cfg80211_priv *wl, struct net_device *ndev,
2032
const wl_event_msg_t *e, void *data, bool completed)
2034
struct wl_cfg80211_connect_info *conn_info = wl_to_conn(wl);
2037
wl_get_assoc_ies(wl);
2038
memcpy(&wl->bssid, &e->addr, ETHER_ADDR_LEN);
2039
wl_update_bss_info(wl);
2041
WL_DBG(("Reporting BSS network join result \"%s\"\n", wl->profile->ssid.SSID));
2042
if (test_and_clear_bit(WL_STATUS_CONNECTING, &wl->status)) {
2043
cfg80211_connect_result(ndev, (u8 *)&wl->bssid, conn_info->req_ie,
2044
conn_info->req_ie_len, conn_info->resp_ie, conn_info->resp_ie_len,
2045
completed ? WLAN_STATUS_SUCCESS : WLAN_STATUS_AUTH_TIMEOUT, GFP_KERNEL);
2046
WL_DBG(("connection %s\n", completed ? "succeeded" : "failed"));
2049
cfg80211_roamed(ndev,
2050
#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)
2053
(u8 *)&wl->bssid, conn_info->req_ie, conn_info->req_ie_len,
2054
conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
2055
WL_DBG(("roaming result\n"));
2057
set_bit(WL_STATUS_CONNECTED, &wl->status);
2063
wl_notify_mic_status(struct wl_cfg80211_priv *wl, struct net_device *ndev,
2064
const wl_event_msg_t *e, void *data)
2066
u16 flags = EVENT_FLAGS(e);
2067
enum nl80211_key_type key_type;
2072
if (flags & WLC_EVENT_MSG_GROUP)
2073
key_type = NL80211_KEYTYPE_GROUP;
2075
key_type = NL80211_KEYTYPE_PAIRWISE;
2077
cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1, NULL, GFP_KERNEL);
2084
wl_notify_scan_status(struct wl_cfg80211_priv *wl, struct net_device *ndev,
2085
const wl_event_msg_t *e, void *data)
2087
struct channel_info channel_inform;
2088
struct wl_scan_results *bss_list;
2095
err = wl_dev_ioctl(ndev, WLC_GET_CHANNEL, &channel_inform, sizeof(channel_inform));
2097
WL_ERR(("scan busy (%d)\n", err));
2100
channel_inform.scan_channel = dtoh32(channel_inform.scan_channel);
2101
if (channel_inform.scan_channel) {
2103
WL_DBG(("channel_inform.scan_channel (%d)\n", channel_inform.scan_channel));
2106
for (buflen = WL_SCAN_BUF_BASE; ; ) {
2107
bss_list = (struct wl_scan_results *) kmalloc(buflen, GFP_KERNEL);
2109
WL_ERR(("%s Out of memory for scan results, (%d)\n", ndev->name, err));
2112
memset(bss_list, 0, buflen);
2113
bss_list->buflen = htod32(buflen);
2114
err = wl_dev_ioctl(ndev, WLC_SCAN_RESULTS, bss_list, buflen);
2118
else if (err == -E2BIG) {
2123
WL_ERR(("%s Scan_results error (%d)\n", ndev->name, err));
2130
bss_list->buflen = dtoh32(bss_list->buflen);
2131
bss_list->version = dtoh32(bss_list->version);
2132
bss_list->count = dtoh32(bss_list->count);
2134
err = wl_inform_bss(wl, bss_list);
2138
if (wl->scan_request) {
2139
cfg80211_scan_done(wl->scan_request, false);
2140
wl->scan_request = NULL;
2146
static void wl_init_conf(struct wl_cfg80211_conf *conf)
2148
conf->mode = (u32)-1;
2149
conf->frag_threshold = (u32)-1;
2150
conf->rts_threshold = (u32)-1;
2151
conf->retry_short = (u32)-1;
2152
conf->retry_long = (u32)-1;
2153
conf->tx_power = -1;
2156
static void wl_init_prof(struct wl_cfg80211_profile *prof)
2158
memset(prof, 0, sizeof(*prof));
2161
static void wl_init_eloop_handler(struct wl_cfg80211_event_loop *el)
2163
memset(el, 0, sizeof(*el));
2164
el->handler[WLC_E_SCAN_COMPLETE] = wl_notify_scan_status;
2165
el->handler[WLC_E_JOIN] = wl_notify_connect_status;
2166
el->handler[WLC_E_START] = wl_notify_connect_status;
2167
el->handler[WLC_E_LINK] = wl_notify_connect_status;
2168
el->handler[WLC_E_NDIS_LINK] = wl_notify_connect_status;
2169
el->handler[WLC_E_SET_SSID] = wl_notify_connect_status;
2170
el->handler[WLC_E_DISASSOC_IND] = wl_notify_connect_status;
2171
el->handler[WLC_E_DEAUTH_IND] = wl_notify_connect_status;
2172
el->handler[WLC_E_ROAM] = wl_notify_roaming_status;
2173
el->handler[WLC_E_MIC_ERROR] = wl_notify_mic_status;
2176
static s32 wl_init_priv_mem(struct wl_cfg80211_priv *wl)
2178
wl->conf = (void *)kzalloc(sizeof(*wl->conf), GFP_KERNEL);
2180
WL_ERR(("wl_cfg80211_conf alloc failed\n"));
2181
goto init_priv_mem_out;
2183
wl->profile = (void *)kzalloc(sizeof(*wl->profile), GFP_KERNEL);
2185
WL_ERR(("wl_cfg80211_profile alloc failed\n"));
2186
goto init_priv_mem_out;
2188
wl->scan_req_int = (void *)kzalloc(sizeof(*wl->scan_req_int), GFP_KERNEL);
2189
if (!wl->scan_req_int) {
2190
WL_ERR(("Scan req alloc failed\n"));
2191
goto init_priv_mem_out;
2193
wl->ioctl_buf = (void *)kzalloc(WL_IOCTL_LEN_MAX, GFP_KERNEL);
2194
if (!wl->ioctl_buf) {
2195
WL_ERR(("Ioctl buf alloc failed\n"));
2196
goto init_priv_mem_out;
2198
wl->extra_buf = (void *)kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
2199
if (!wl->extra_buf) {
2200
WL_ERR(("Extra buf alloc failed\n"));
2201
goto init_priv_mem_out;
2204
wl->pmk_list = (void *)kzalloc(sizeof(*wl->pmk_list), GFP_KERNEL);
2205
if (!wl->pmk_list) {
2206
WL_ERR(("pmk list alloc failed\n"));
2207
goto init_priv_mem_out;
2213
wl_deinit_priv_mem(wl);
2218
static void wl_deinit_priv_mem(struct wl_cfg80211_priv *wl)
2224
kfree(wl->scan_req_int);
2225
wl->scan_req_int = NULL;
2226
kfree(wl->ioctl_buf);
2227
wl->ioctl_buf = NULL;
2228
kfree(wl->extra_buf);
2229
wl->extra_buf = NULL;
2230
kfree(wl->pmk_list);
2231
wl->pmk_list = NULL;
2234
static s32 wl_create_event_handler(struct wl_cfg80211_priv *wl)
2236
sema_init(&wl->event_sync, 0);
2237
wl->event_tsk = kthread_run(wl_event_handler, wl, "wl_event_handler");
2238
if (IS_ERR(wl->event_tsk)) {
2239
wl->event_tsk = NULL;
2240
WL_ERR(("failed to create event thread\n"));
2246
static void wl_destroy_event_handler(struct wl_cfg80211_priv *wl)
2248
if (wl->event_tsk) {
2249
send_sig(SIGTERM, wl->event_tsk, 1);
2250
kthread_stop(wl->event_tsk);
2251
wl->event_tsk = NULL;
2255
static s32 wl_init_cfg80211_priv(struct wl_cfg80211_priv *wl, struct wireless_dev *wdev)
2261
wl->scan_request = NULL;
2262
wl->active_scan = true;
2264
err = wl_init_priv_mem(wl);
2268
if (wl_create_event_handler(wl))
2271
wl_init_eloop_handler(&wl->el);
2276
wl_init_conf(wl->conf);
2277
wl_init_prof(wl->profile);
2283
static void wl_deinit_cfg80211_priv(struct wl_cfg80211_priv *wl)
2285
wl_destroy_event_handler(wl);
2288
wl_deinit_priv_mem(wl);
2291
s32 wl_cfg80211_attach(struct net_device *ndev, struct device *dev)
2293
struct wireless_dev *wdev;
2294
struct wl_cfg80211_priv *wl;
2298
WL_ERR(("ndev is invaild\n"));
2302
err = wl_alloc_wdev(dev, &wdev);
2307
wdev->iftype = wl_mode_to_nl80211_iftype(WL_MODE_BSS);
2308
wl = wdev_to_wl(wdev);
2309
ndev->ieee80211_ptr = wdev;
2310
SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
2311
wdev->netdev = ndev;
2312
err = wl_init_cfg80211_priv(wl, wdev);
2314
WL_ERR(("Failed to init iwm_priv (%d)\n", err));
2315
goto cfg80211_attach_out;
2319
WL_INF(("Registered CFG80211 phy\n"));
2323
cfg80211_attach_out:
2328
void wl_cfg80211_detach(struct net_device *ndev)
2330
struct wl_cfg80211_priv *wl = ndev_to_wl(ndev);
2332
wl_deinit_cfg80211_priv(wl);
2336
static void wl_wakeup_event(struct wl_cfg80211_priv *wl)
2338
up(&wl->event_sync);
2341
static s32 wl_event_handler(void *data)
2343
struct wl_cfg80211_priv *wl = (struct wl_cfg80211_priv *)data;
2344
struct wl_cfg80211_event_q *e;
2346
allow_signal(SIGTERM);
2347
while (!down_interruptible(&wl->event_sync)) {
2348
if (kthread_should_stop())
2350
e = wl_deq_event(wl);
2352
WL_ERR(("eqeue empty..\n"));
2355
WL_DBG(("event type (%d)\n", e->etype));
2356
if (wl->el.handler[e->etype]) {
2357
wl->el.handler[e->etype] (wl, wl_to_ndev(wl), &e->emsg, e->edata);
2359
WL_DBG(("Unknown Event (%d): ignoring\n", e->etype));
2363
WL_DBG(("%s was terminated\n", __func__));
2368
wl_cfg80211_event(struct net_device *ndev, const wl_event_msg_t * e, void *data)
2371
u32 event_type = EVENT_TYPE(e);
2373
struct wl_cfg80211_priv *wl = ndev_to_wl(ndev);
2374
#if defined(WL_DBGMSG_ENABLE)
2375
s8 *estr = (event_type <= sizeof(wl_dbg_estr) / WL_DBG_ESTR_MAX - 1) ?
2376
wl_dbg_estr[event_type] : (s8 *) "Unknown";
2377
WL_DBG(("event_type (%d):" "WLC_E_" "%s\n", event_type, estr));
2379
if (!wl_enq_event(wl, event_type, e, data))
2380
wl_wakeup_event(wl);
2383
static void wl_init_eq(struct wl_cfg80211_priv *wl)
2385
wl_init_eq_lock(wl);
2386
INIT_LIST_HEAD(&wl->eq_list);
2389
static void wl_flush_eq(struct wl_cfg80211_priv *wl)
2391
struct wl_cfg80211_event_q *e;
2394
while (!list_empty(&wl->eq_list)) {
2395
e = list_first_entry(&wl->eq_list, struct wl_cfg80211_event_q, eq_list);
2396
list_del(&e->eq_list);
2402
static struct wl_cfg80211_event_q *wl_deq_event(struct wl_cfg80211_priv *wl)
2404
struct wl_cfg80211_event_q *e = NULL;
2407
if (!list_empty(&wl->eq_list)) {
2408
e = list_first_entry(&wl->eq_list, struct wl_cfg80211_event_q, eq_list);
2409
list_del(&e->eq_list);
2417
wl_enq_event(struct wl_cfg80211_priv *wl, u32 event, const wl_event_msg_t *msg, void *data)
2419
struct wl_cfg80211_event_q *e;
2422
e = kzalloc(sizeof(struct wl_cfg80211_event_q), GFP_ATOMIC);
2424
WL_ERR(("event alloc failed\n"));
2429
memcpy(&e->emsg, msg, sizeof(wl_event_msg_t));
2433
spin_lock(&wl->eq_lock);
2434
list_add_tail(&e->eq_list, &wl->eq_list);
2435
spin_unlock(&wl->eq_lock);
2440
static void wl_put_event(struct wl_cfg80211_event_q *e)
2445
static s32 wl_set_mode(struct net_device *ndev, s32 iftype)
2452
case NL80211_IFTYPE_MONITOR:
2453
case NL80211_IFTYPE_WDS:
2454
WL_ERR(("type (%d) : currently we do not support this mode\n",
2458
case NL80211_IFTYPE_ADHOC:
2460
case NL80211_IFTYPE_STATION:
2465
WL_ERR(("invalid type (%d)\n", iftype));
2468
infra = htod32(infra);
2470
WL_DBG(("%s ap (%d), infra (%d)\n", ndev->name, ap, infra));
2471
err = wl_dev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(infra));
2473
WL_ERR(("WLC_SET_INFRA error (%d)\n", err));
2476
err = wl_dev_ioctl(ndev, WLC_SET_AP, &ap, sizeof(ap));
2478
WL_ERR(("WLC_SET_AP error (%d)\n", err));
2485
static s32 wl_update_wiphybands(struct wl_cfg80211_priv *wl)
2487
struct wiphy *wiphy;
2492
err = wl_dev_ioctl(wl_to_ndev(wl), WLC_GET_PHYLIST, &phy_list, sizeof(phy_list));
2494
WL_ERR(("error (%d)\n", err));
2498
phy = ((char *)&phy_list)[0];
2499
WL_DBG(("%c phy\n", phy));
2501
if (phy == 'n' || phy == 'a') {
2502
wiphy = wl_to_wiphy(wl);
2503
wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
2509
s32 wl_cfg80211_up(struct net_device *ndev)
2511
struct wl_cfg80211_priv *wl = ndev_to_wl(ndev);
2513
struct wireless_dev *wdev = ndev->ieee80211_ptr;
2515
wl_set_mode(ndev, wdev->iftype);
2517
err = wl_update_wiphybands(wl);
2522
s32 wl_cfg80211_down(struct net_device *ndev)
2524
struct wl_cfg80211_priv *wl = ndev_to_wl(ndev);
2527
if (wl->scan_request) {
2528
cfg80211_scan_done(wl->scan_request, true);
2529
wl->scan_request = NULL;
2535
static bool wl_is_ibssmode(struct wl_cfg80211_priv *wl)
2537
return wl->conf->mode == WL_MODE_IBSS;
2540
static void wl_rst_ie(struct wl_cfg80211_priv *wl)
2542
struct wl_cfg80211_ie *ie = wl_to_ie(wl);
2547
static __used s32 wl_add_ie(struct wl_cfg80211_priv *wl, u8 t, u8 l, u8 *v)
2549
struct wl_cfg80211_ie *ie = wl_to_ie(wl);
2552
if (ie->offset + l + 2 > WL_TLV_INFO_MAX) {
2553
WL_ERR(("ei crosses buffer boundary\n"));
2556
ie->buf[ie->offset] = t;
2557
ie->buf[ie->offset + 1] = l;
2558
memcpy(&ie->buf[ie->offset + 2], v, l);
2559
ie->offset += l + 2;
2564
static s32 wl_mrg_ie(struct wl_cfg80211_priv *wl, u8 *ie_stream, u16 ie_size)
2566
struct wl_cfg80211_ie *ie = wl_to_ie(wl);
2569
if (ie->offset + ie_size > WL_TLV_INFO_MAX) {
2570
WL_ERR(("ei_stream crosses buffer boundary\n"));
2573
memcpy(&ie->buf[ie->offset], ie_stream, ie_size);
2574
ie->offset += ie_size;
2579
static s32 wl_cp_ie(struct wl_cfg80211_priv *wl, u8 *dst, u16 dst_size)
2581
struct wl_cfg80211_ie *ie = wl_to_ie(wl);
2584
if (ie->offset > dst_size) {
2585
WL_ERR(("dst_size is not enough\n"));
2588
memcpy(dst, &ie->buf[0], ie->offset);
2593
static u32 wl_get_ielen(struct wl_cfg80211_priv *wl)
2595
struct wl_cfg80211_ie *ie = wl_to_ie(wl);
2600
static void wl_link_up(struct wl_cfg80211_priv *wl)
2605
static void wl_link_down(struct wl_cfg80211_priv *wl)
2607
struct wl_cfg80211_connect_info *conn_info = wl_to_conn(wl);
2611
kfree(conn_info->req_ie);
2612
conn_info->req_ie = NULL;
2613
conn_info->req_ie_len = 0;
2614
kfree(conn_info->resp_ie);
2615
conn_info->resp_ie = NULL;
2616
conn_info->resp_ie_len = 0;
2619
static void wl_lock_eq(struct wl_cfg80211_priv *wl)
2621
spin_lock_irq(&wl->eq_lock);
2624
static void wl_unlock_eq(struct wl_cfg80211_priv *wl)
2626
spin_unlock_irq(&wl->eq_lock);
2629
static void wl_init_eq_lock(struct wl_cfg80211_priv *wl)
2631
spin_lock_init(&wl->eq_lock);