2 * Copyright (c) 2004-2011 Atheros Communications Inc.
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.
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
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 #define RATETAB_ENT(_rate, _rateid, _flags) { \
24 .hw_value = (_rateid), \
27 #define CHAN2G(_channel, _freq, _flags) { \
28 .band = IEEE80211_BAND_2GHZ, \
29 .hw_value = (_channel), \
30 .center_freq = (_freq), \
32 .max_antenna_gain = 0, \
36 #define CHAN5G(_channel, _flags) { \
37 .band = IEEE80211_BAND_5GHZ, \
38 .hw_value = (_channel), \
39 .center_freq = 5000 + (5 * (_channel)), \
41 .max_antenna_gain = 0, \
45 static struct ieee80211_rate ath6kl_rates
[] = {
46 RATETAB_ENT(10, 0x1, 0),
47 RATETAB_ENT(20, 0x2, 0),
48 RATETAB_ENT(55, 0x4, 0),
49 RATETAB_ENT(110, 0x8, 0),
50 RATETAB_ENT(60, 0x10, 0),
51 RATETAB_ENT(90, 0x20, 0),
52 RATETAB_ENT(120, 0x40, 0),
53 RATETAB_ENT(180, 0x80, 0),
54 RATETAB_ENT(240, 0x100, 0),
55 RATETAB_ENT(360, 0x200, 0),
56 RATETAB_ENT(480, 0x400, 0),
57 RATETAB_ENT(540, 0x800, 0),
60 #define ath6kl_a_rates (ath6kl_rates + 4)
61 #define ath6kl_a_rates_size 8
62 #define ath6kl_g_rates (ath6kl_rates + 0)
63 #define ath6kl_g_rates_size 12
65 static struct ieee80211_channel ath6kl_2ghz_channels
[] = {
82 static struct ieee80211_channel ath6kl_5ghz_a_channels
[] = {
83 CHAN5G(34, 0), CHAN5G(36, 0),
84 CHAN5G(38, 0), CHAN5G(40, 0),
85 CHAN5G(42, 0), CHAN5G(44, 0),
86 CHAN5G(46, 0), CHAN5G(48, 0),
87 CHAN5G(52, 0), CHAN5G(56, 0),
88 CHAN5G(60, 0), CHAN5G(64, 0),
89 CHAN5G(100, 0), CHAN5G(104, 0),
90 CHAN5G(108, 0), CHAN5G(112, 0),
91 CHAN5G(116, 0), CHAN5G(120, 0),
92 CHAN5G(124, 0), CHAN5G(128, 0),
93 CHAN5G(132, 0), CHAN5G(136, 0),
94 CHAN5G(140, 0), CHAN5G(149, 0),
95 CHAN5G(153, 0), CHAN5G(157, 0),
96 CHAN5G(161, 0), CHAN5G(165, 0),
97 CHAN5G(184, 0), CHAN5G(188, 0),
98 CHAN5G(192, 0), CHAN5G(196, 0),
99 CHAN5G(200, 0), CHAN5G(204, 0),
100 CHAN5G(208, 0), CHAN5G(212, 0),
104 static struct ieee80211_supported_band ath6kl_band_2ghz
= {
105 .n_channels
= ARRAY_SIZE(ath6kl_2ghz_channels
),
106 .channels
= ath6kl_2ghz_channels
,
107 .n_bitrates
= ath6kl_g_rates_size
,
108 .bitrates
= ath6kl_g_rates
,
111 static struct ieee80211_supported_band ath6kl_band_5ghz
= {
112 .n_channels
= ARRAY_SIZE(ath6kl_5ghz_a_channels
),
113 .channels
= ath6kl_5ghz_a_channels
,
114 .n_bitrates
= ath6kl_a_rates_size
,
115 .bitrates
= ath6kl_a_rates
,
118 static int ath6kl_set_wpa_version(struct ath6kl
*ar
,
119 enum nl80211_wpa_versions wpa_version
)
121 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "%s: %u\n", __func__
, wpa_version
);
124 ar
->auth_mode
= NONE_AUTH
;
125 } else if (wpa_version
& NL80211_WPA_VERSION_2
) {
126 ar
->auth_mode
= WPA2_AUTH
;
127 } else if (wpa_version
& NL80211_WPA_VERSION_1
) {
128 ar
->auth_mode
= WPA_AUTH
;
130 ath6kl_err("%s: %u not supported\n", __func__
, wpa_version
);
137 static int ath6kl_set_auth_type(struct ath6kl
*ar
,
138 enum nl80211_auth_type auth_type
)
141 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "%s: 0x%x\n", __func__
, auth_type
);
144 case NL80211_AUTHTYPE_OPEN_SYSTEM
:
145 ar
->dot11_auth_mode
= OPEN_AUTH
;
147 case NL80211_AUTHTYPE_SHARED_KEY
:
148 ar
->dot11_auth_mode
= SHARED_AUTH
;
150 case NL80211_AUTHTYPE_NETWORK_EAP
:
151 ar
->dot11_auth_mode
= LEAP_AUTH
;
154 case NL80211_AUTHTYPE_AUTOMATIC
:
155 ar
->dot11_auth_mode
= OPEN_AUTH
;
156 ar
->auto_auth_stage
= AUTH_OPEN_IN_PROGRESS
;
160 ath6kl_err("%s: 0x%x not spported\n", __func__
, auth_type
);
167 static int ath6kl_set_cipher(struct ath6kl
*ar
, u32 cipher
, bool ucast
)
169 u8
*ar_cipher
= ucast
? &ar
->prwise_crypto
: &ar
->grp_crypto
;
170 u8
*ar_cipher_len
= ucast
? &ar
->prwise_crypto_len
: &ar
->grp_crpto_len
;
172 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "%s: cipher 0x%x, ucast %u\n",
173 __func__
, cipher
, ucast
);
177 /* our own hack to use value 0 as no crypto used */
178 *ar_cipher
= NONE_CRYPT
;
181 case WLAN_CIPHER_SUITE_WEP40
:
182 *ar_cipher
= WEP_CRYPT
;
185 case WLAN_CIPHER_SUITE_WEP104
:
186 *ar_cipher
= WEP_CRYPT
;
189 case WLAN_CIPHER_SUITE_TKIP
:
190 *ar_cipher
= TKIP_CRYPT
;
193 case WLAN_CIPHER_SUITE_CCMP
:
194 *ar_cipher
= AES_CRYPT
;
198 ath6kl_err("cipher 0x%x not supported\n", cipher
);
205 static void ath6kl_set_key_mgmt(struct ath6kl
*ar
, u32 key_mgmt
)
207 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "%s: 0x%x\n", __func__
, key_mgmt
);
209 if (key_mgmt
== WLAN_AKM_SUITE_PSK
) {
210 if (ar
->auth_mode
== WPA_AUTH
)
211 ar
->auth_mode
= WPA_PSK_AUTH
;
212 else if (ar
->auth_mode
== WPA2_AUTH
)
213 ar
->auth_mode
= WPA2_PSK_AUTH
;
214 } else if (key_mgmt
!= WLAN_AKM_SUITE_8021X
) {
215 ar
->auth_mode
= NONE_AUTH
;
219 static bool ath6kl_cfg80211_ready(struct ath6kl
*ar
)
221 if (!test_bit(WMI_READY
, &ar
->flag
)) {
222 ath6kl_err("wmi is not ready\n");
226 if (!test_bit(WLAN_ENABLED
, &ar
->flag
)) {
227 ath6kl_err("wlan disabled\n");
234 static int ath6kl_cfg80211_connect(struct wiphy
*wiphy
, struct net_device
*dev
,
235 struct cfg80211_connect_params
*sme
)
237 struct ath6kl
*ar
= ath6kl_priv(dev
);
240 ar
->sme_state
= SME_CONNECTING
;
242 if (!ath6kl_cfg80211_ready(ar
))
245 if (test_bit(DESTROY_IN_PROGRESS
, &ar
->flag
)) {
246 ath6kl_err("destroy in progress\n");
250 if (test_bit(SKIP_SCAN
, &ar
->flag
) &&
251 ((sme
->channel
&& sme
->channel
->center_freq
== 0) ||
252 (sme
->bssid
&& is_zero_ether_addr(sme
->bssid
)))) {
253 ath6kl_err("SkipScan: channel or bssid invalid\n");
257 if (down_interruptible(&ar
->sem
)) {
258 ath6kl_err("busy, couldn't get access\n");
262 if (test_bit(DESTROY_IN_PROGRESS
, &ar
->flag
)) {
263 ath6kl_err("busy, destroy in progress\n");
268 if (ar
->tx_pending
[ath6kl_wmi_get_control_ep(ar
->wmi
)]) {
270 * sleep until the command queue drains
272 wait_event_interruptible_timeout(ar
->event_wq
,
273 ar
->tx_pending
[ath6kl_wmi_get_control_ep(ar
->wmi
)] == 0,
275 if (signal_pending(current
)) {
276 ath6kl_err("cmd queue drain timeout\n");
282 if (test_bit(CONNECTED
, &ar
->flag
) &&
283 ar
->ssid_len
== sme
->ssid_len
&&
284 !memcmp(ar
->ssid
, sme
->ssid
, ar
->ssid_len
)) {
285 ar
->reconnect_flag
= true;
286 status
= ath6kl_wmi_reconnect_cmd(ar
->wmi
, ar
->req_bssid
,
291 ath6kl_err("wmi_reconnect_cmd failed\n");
295 } else if (ar
->ssid_len
== sme
->ssid_len
&&
296 !memcmp(ar
->ssid
, sme
->ssid
, ar
->ssid_len
)) {
297 ath6kl_disconnect(ar
);
300 memset(ar
->ssid
, 0, sizeof(ar
->ssid
));
301 ar
->ssid_len
= sme
->ssid_len
;
302 memcpy(ar
->ssid
, sme
->ssid
, sme
->ssid_len
);
305 ar
->ch_hint
= sme
->channel
->center_freq
;
307 memset(ar
->req_bssid
, 0, sizeof(ar
->req_bssid
));
308 if (sme
->bssid
&& !is_broadcast_ether_addr(sme
->bssid
))
309 memcpy(ar
->req_bssid
, sme
->bssid
, sizeof(ar
->req_bssid
));
311 ath6kl_set_wpa_version(ar
, sme
->crypto
.wpa_versions
);
313 status
= ath6kl_set_auth_type(ar
, sme
->auth_type
);
319 if (sme
->crypto
.n_ciphers_pairwise
)
320 ath6kl_set_cipher(ar
, sme
->crypto
.ciphers_pairwise
[0], true);
322 ath6kl_set_cipher(ar
, 0, true);
324 ath6kl_set_cipher(ar
, sme
->crypto
.cipher_group
, false);
326 if (sme
->crypto
.n_akm_suites
)
327 ath6kl_set_key_mgmt(ar
, sme
->crypto
.akm_suites
[0]);
329 if ((sme
->key_len
) &&
330 (ar
->auth_mode
== NONE_AUTH
) && (ar
->prwise_crypto
== WEP_CRYPT
)) {
331 struct ath6kl_key
*key
= NULL
;
333 if (sme
->key_idx
< WMI_MIN_KEY_INDEX
||
334 sme
->key_idx
> WMI_MAX_KEY_INDEX
) {
335 ath6kl_err("key index %d out of bounds\n",
341 key
= &ar
->keys
[sme
->key_idx
];
342 key
->key_len
= sme
->key_len
;
343 memcpy(key
->key
, sme
->key
, key
->key_len
);
344 key
->cipher
= ar
->prwise_crypto
;
345 ar
->def_txkey_index
= sme
->key_idx
;
347 ath6kl_wmi_addkey_cmd(ar
->wmi
, sme
->key_idx
,
349 GROUP_USAGE
| TX_USAGE
,
352 key
->key
, KEY_OP_INIT_VAL
, NULL
,
356 if (!ar
->usr_bss_filter
) {
357 if (ath6kl_wmi_bssfilter_cmd(ar
->wmi
, ALL_BSS_FILTER
, 0) != 0) {
358 ath6kl_err("couldn't set bss filtering\n");
364 ar
->nw_type
= ar
->next_mode
;
366 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
,
367 "%s: connect called with authmode %d dot11 auth %d"
368 " PW crypto %d PW crypto len %d GRP crypto %d"
369 " GRP crypto len %d channel hint %u\n",
371 ar
->auth_mode
, ar
->dot11_auth_mode
, ar
->prwise_crypto
,
372 ar
->prwise_crypto_len
, ar
->grp_crypto
,
373 ar
->grp_crpto_len
, ar
->ch_hint
);
375 ar
->reconnect_flag
= 0;
376 status
= ath6kl_wmi_connect_cmd(ar
->wmi
, ar
->nw_type
,
377 ar
->dot11_auth_mode
, ar
->auth_mode
,
379 ar
->prwise_crypto_len
,
380 ar
->grp_crypto
, ar
->grp_crpto_len
,
381 ar
->ssid_len
, ar
->ssid
,
382 ar
->req_bssid
, ar
->ch_hint
,
383 ar
->connect_ctrl_flags
);
387 if (status
== -EINVAL
) {
388 memset(ar
->ssid
, 0, sizeof(ar
->ssid
));
390 ath6kl_err("invalid request\n");
393 ath6kl_err("ath6kl_wmi_connect_cmd failed\n");
397 if ((!(ar
->connect_ctrl_flags
& CONNECT_DO_WPA_OFFLOAD
)) &&
398 ((ar
->auth_mode
== WPA_PSK_AUTH
)
399 || (ar
->auth_mode
== WPA2_PSK_AUTH
))) {
400 mod_timer(&ar
->disconnect_timer
,
401 jiffies
+ msecs_to_jiffies(DISCON_TIMER_INTVAL
));
404 ar
->connect_ctrl_flags
&= ~CONNECT_DO_WPA_OFFLOAD
;
405 set_bit(CONNECT_PEND
, &ar
->flag
);
410 void ath6kl_cfg80211_connect_event(struct ath6kl
*ar
, u16 channel
,
411 u8
*bssid
, u16 listen_intvl
,
413 enum network_type nw_type
,
414 u8 beacon_ie_len
, u8 assoc_req_len
,
415 u8 assoc_resp_len
, u8
*assoc_info
)
419 struct cfg80211_bss
*bss
= NULL
;
420 struct ieee80211_mgmt
*mgmt
= NULL
;
421 struct ieee80211_channel
*ibss_ch
= NULL
;
422 s32 signal
= 50 * 100;
424 unsigned char ie_buf
[256];
425 unsigned char *ptr_ie_buf
= ie_buf
;
426 unsigned char *ieeemgmtbuf
= NULL
;
427 u8 source_mac
[ETH_ALEN
];
431 /* capinfo + listen interval */
432 u8 assoc_req_ie_offset
= sizeof(u16
) + sizeof(u16
);
434 /* capinfo + status code + associd */
435 u8 assoc_resp_ie_offset
= sizeof(u16
) + sizeof(u16
) + sizeof(u16
);
437 u8
*assoc_req_ie
= assoc_info
+ beacon_ie_len
+ assoc_req_ie_offset
;
438 u8
*assoc_resp_ie
= assoc_info
+ beacon_ie_len
+ assoc_req_len
+
439 assoc_resp_ie_offset
;
441 assoc_req_len
-= assoc_req_ie_offset
;
442 assoc_resp_len
-= assoc_resp_ie_offset
;
444 ar
->auto_auth_stage
= AUTH_IDLE
;
446 if (nw_type
& ADHOC_NETWORK
) {
447 if (ar
->wdev
->iftype
!= NL80211_IFTYPE_ADHOC
) {
448 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
,
449 "%s: ath6k not in ibss mode\n", __func__
);
454 if (nw_type
& INFRA_NETWORK
) {
455 if (ar
->wdev
->iftype
!= NL80211_IFTYPE_STATION
) {
456 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
,
457 "%s: ath6k not in station mode\n", __func__
);
462 if (nw_type
& ADHOC_NETWORK
) {
463 capa_mask
= WLAN_CAPABILITY_IBSS
;
464 capa_val
= WLAN_CAPABILITY_IBSS
;
466 capa_mask
= WLAN_CAPABILITY_ESS
;
467 capa_val
= WLAN_CAPABILITY_ESS
;
470 /* Before informing the join/connect event, make sure that
471 * bss entry is present in scan list, if it not present
472 * construct and insert into scan list, otherwise that
473 * event will be dropped on the way by cfg80211, due to
474 * this keys will not be plumbed in case of WEP and
475 * application will not be aware of join/connect status. */
476 bss
= cfg80211_get_bss(ar
->wdev
->wiphy
, NULL
, bssid
,
477 ar
->wdev
->ssid
, ar
->wdev
->ssid_len
,
478 capa_mask
, capa_val
);
481 * Earlier we were updating the cfg about bss by making a beacon frame
482 * only if the entry for bss is not there. This can have some issue if
483 * ROAM event is generated and a heavy traffic is ongoing. The ROAM
484 * event is handled through a work queue and by the time it really gets
485 * handled, BSS would have been aged out. So it is better to update the
486 * cfg about BSS irrespective of its entry being present right now or
490 if (nw_type
& ADHOC_NETWORK
) {
491 /* construct 802.11 mgmt beacon */
493 *ptr_ie_buf
++ = WLAN_EID_SSID
;
494 *ptr_ie_buf
++ = ar
->ssid_len
;
495 memcpy(ptr_ie_buf
, ar
->ssid
, ar
->ssid_len
);
496 ptr_ie_buf
+= ar
->ssid_len
;
498 *ptr_ie_buf
++ = WLAN_EID_IBSS_PARAMS
;
499 *ptr_ie_buf
++ = 2; /* length */
500 *ptr_ie_buf
++ = 0; /* ATIM window */
501 *ptr_ie_buf
++ = 0; /* ATIM window */
503 /* TODO: update ibss params and include supported rates,
504 * DS param set, extened support rates, wmm. */
506 ie_buf_len
= ptr_ie_buf
- ie_buf
;
509 capability
|= WLAN_CAPABILITY_IBSS
;
511 if (ar
->prwise_crypto
== WEP_CRYPT
)
512 capability
|= WLAN_CAPABILITY_PRIVACY
;
514 memcpy(source_mac
, ar
->net_dev
->dev_addr
, ETH_ALEN
);
517 capability
= *(u16
*) (&assoc_info
[beacon_ie_len
]);
518 memcpy(source_mac
, bssid
, ETH_ALEN
);
519 ptr_ie_buf
= assoc_req_ie
;
520 ie_buf_len
= assoc_req_len
;
523 size
= offsetof(struct ieee80211_mgmt
, u
)
524 + sizeof(mgmt
->u
.beacon
)
527 ieeemgmtbuf
= kzalloc(size
, GFP_ATOMIC
);
529 ath6kl_err("ieee mgmt buf alloc error\n");
530 cfg80211_put_bss(bss
);
534 mgmt
= (struct ieee80211_mgmt
*)ieeemgmtbuf
;
535 mgmt
->frame_control
= cpu_to_le16(IEEE80211_FTYPE_MGMT
|
536 IEEE80211_STYPE_BEACON
);
537 memset(mgmt
->da
, 0xff, ETH_ALEN
); /* broadcast addr */
538 memcpy(mgmt
->sa
, source_mac
, ETH_ALEN
);
539 memcpy(mgmt
->bssid
, bssid
, ETH_ALEN
);
540 mgmt
->u
.beacon
.beacon_int
= cpu_to_le16(beacon_intvl
);
541 mgmt
->u
.beacon
.capab_info
= cpu_to_le16(capability
);
542 memcpy(mgmt
->u
.beacon
.variable
, ptr_ie_buf
, ie_buf_len
);
544 ibss_ch
= ieee80211_get_channel(ar
->wdev
->wiphy
, (int)channel
);
546 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
,
547 "%s: inform bss with bssid %pM channel %d beacon_intvl %d capability 0x%x\n",
548 __func__
, mgmt
->bssid
, ibss_ch
->hw_value
,
549 beacon_intvl
, capability
);
551 bss
= cfg80211_inform_bss_frame(ar
->wdev
->wiphy
,
553 size
, signal
, GFP_KERNEL
);
555 cfg80211_put_bss(bss
);
557 if (nw_type
& ADHOC_NETWORK
) {
558 cfg80211_ibss_joined(ar
->net_dev
, bssid
, GFP_KERNEL
);
562 if (ar
->sme_state
== SME_CONNECTING
) {
563 /* inform connect result to cfg80211 */
564 ar
->sme_state
= SME_CONNECTED
;
565 cfg80211_connect_result(ar
->net_dev
, bssid
,
566 assoc_req_ie
, assoc_req_len
,
567 assoc_resp_ie
, assoc_resp_len
,
568 WLAN_STATUS_SUCCESS
, GFP_KERNEL
);
569 } else if (ar
->sme_state
== SME_CONNECTED
) {
570 /* inform roam event to cfg80211 */
571 cfg80211_roamed(ar
->net_dev
, ibss_ch
, bssid
,
572 assoc_req_ie
, assoc_req_len
,
573 assoc_resp_ie
, assoc_resp_len
, GFP_KERNEL
);
577 static int ath6kl_cfg80211_disconnect(struct wiphy
*wiphy
,
578 struct net_device
*dev
, u16 reason_code
)
580 struct ath6kl
*ar
= (struct ath6kl
*)ath6kl_priv(dev
);
582 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "%s: reason=%u\n", __func__
,
585 if (!ath6kl_cfg80211_ready(ar
))
588 if (test_bit(DESTROY_IN_PROGRESS
, &ar
->flag
)) {
589 ath6kl_err("busy, destroy in progress\n");
593 if (down_interruptible(&ar
->sem
)) {
594 ath6kl_err("busy, couldn't get access\n");
598 ar
->reconnect_flag
= 0;
599 ath6kl_disconnect(ar
);
600 memset(ar
->ssid
, 0, sizeof(ar
->ssid
));
603 if (!test_bit(SKIP_SCAN
, &ar
->flag
))
604 memset(ar
->req_bssid
, 0, sizeof(ar
->req_bssid
));
611 void ath6kl_cfg80211_disconnect_event(struct ath6kl
*ar
, u8 reason
,
612 u8
*bssid
, u8 assoc_resp_len
,
613 u8
*assoc_info
, u16 proto_reason
)
615 struct ath6kl_key
*key
= NULL
;
619 cfg80211_scan_done(ar
->scan_req
, true);
623 if (ar
->nw_type
& ADHOC_NETWORK
) {
624 if (ar
->wdev
->iftype
!= NL80211_IFTYPE_ADHOC
) {
625 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
,
626 "%s: ath6k not in ibss mode\n", __func__
);
629 memset(bssid
, 0, ETH_ALEN
);
630 cfg80211_ibss_joined(ar
->net_dev
, bssid
, GFP_KERNEL
);
634 if (ar
->nw_type
& INFRA_NETWORK
) {
635 if (ar
->wdev
->iftype
!= NL80211_IFTYPE_STATION
) {
636 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
,
637 "%s: ath6k not in station mode\n", __func__
);
642 if (!test_bit(CONNECT_PEND
, &ar
->flag
)) {
643 if (reason
!= DISCONNECT_CMD
)
644 ath6kl_wmi_disconnect_cmd(ar
->wmi
);
649 if (reason
== NO_NETWORK_AVAIL
) {
650 /* connect cmd failed */
651 ath6kl_wmi_disconnect_cmd(ar
->wmi
);
655 if (reason
!= DISCONNECT_CMD
)
658 if (!ar
->auto_auth_stage
) {
659 clear_bit(CONNECT_PEND
, &ar
->flag
);
661 if (ar
->sme_state
== SME_CONNECTING
) {
662 cfg80211_connect_result(ar
->net_dev
,
665 WLAN_STATUS_UNSPECIFIED_FAILURE
,
668 cfg80211_disconnected(ar
->net_dev
, reason
,
669 NULL
, 0, GFP_KERNEL
);
672 ar
->sme_state
= SME_DISCONNECTED
;
676 if (ar
->dot11_auth_mode
!= OPEN_AUTH
)
680 * If the current auth algorithm is open, try shared and
681 * make autoAuthStage idle. We do not make it leap for now
684 key
= &ar
->keys
[ar
->def_txkey_index
];
685 if (down_interruptible(&ar
->sem
)) {
686 ath6kl_err("busy, couldn't get access\n");
690 ar
->dot11_auth_mode
= SHARED_AUTH
;
691 ar
->auto_auth_stage
= AUTH_IDLE
;
693 ath6kl_wmi_addkey_cmd(ar
->wmi
,
696 GROUP_USAGE
| TX_USAGE
,
699 KEY_OP_INIT_VAL
, NULL
,
702 status
= ath6kl_wmi_connect_cmd(ar
->wmi
,
707 ar
->prwise_crypto_len
,
714 ar
->connect_ctrl_flags
);
718 static inline bool is_ch_11a(u16 ch
)
720 return (!((ch
>= 2412) && (ch
<= 2484)));
723 /* struct ath6kl_node_table::nt_nodelock is locked when calling this */
724 void ath6kl_cfg80211_scan_node(struct wiphy
*wiphy
, struct bss
*ni
)
727 unsigned char *ieeemgmtbuf
= NULL
;
728 struct ieee80211_mgmt
*mgmt
;
729 struct ieee80211_channel
*channel
;
730 struct ieee80211_supported_band
*band
;
731 struct ath6kl_common_ie
*cie
;
737 if (is_ch_11a(cie
->ie_chan
))
738 band
= wiphy
->bands
[IEEE80211_BAND_5GHZ
]; /* 11a */
739 else if ((cie
->ie_erp
) || (cie
->ie_xrates
))
740 band
= wiphy
->bands
[IEEE80211_BAND_2GHZ
]; /* 11g */
742 band
= wiphy
->bands
[IEEE80211_BAND_2GHZ
]; /* 11b */
744 size
= ni
->ni_framelen
+ offsetof(struct ieee80211_mgmt
, u
);
745 ieeemgmtbuf
= kmalloc(size
, GFP_ATOMIC
);
747 ath6kl_err("ieee mgmt buf alloc error\n");
752 * TODO: Update target to include 802.11 mac header while sending
753 * bss info. Target removes 802.11 mac header while sending the bss
754 * info to host, cfg80211 needs it, for time being just filling the
755 * da, sa and bssid fields alone.
757 mgmt
= (struct ieee80211_mgmt
*)ieeemgmtbuf
;
758 memset(mgmt
->da
, 0xff, ETH_ALEN
); /*broadcast addr */
759 memcpy(mgmt
->sa
, ni
->ni_macaddr
, ETH_ALEN
);
760 memcpy(mgmt
->bssid
, ni
->ni_macaddr
, ETH_ALEN
);
761 memcpy(ieeemgmtbuf
+ offsetof(struct ieee80211_mgmt
, u
),
762 ni
->ni_buf
, ni
->ni_framelen
);
765 channel
= ieee80211_get_channel(wiphy
, freq
);
766 signal
= ni
->ni_snr
* 100;
768 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
,
769 "%s: bssid %pM ch %d freq %d size %d\n", __func__
,
770 mgmt
->bssid
, channel
->hw_value
, freq
, size
);
771 cfg80211_inform_bss_frame(wiphy
, channel
, mgmt
,
772 size
, signal
, GFP_ATOMIC
);
777 static int ath6kl_cfg80211_scan(struct wiphy
*wiphy
, struct net_device
*ndev
,
778 struct cfg80211_scan_request
*request
)
780 struct ath6kl
*ar
= (struct ath6kl
*)ath6kl_priv(ndev
);
783 if (!ath6kl_cfg80211_ready(ar
))
786 if (!ar
->usr_bss_filter
) {
787 if (ath6kl_wmi_bssfilter_cmd(ar
->wmi
,
788 (test_bit(CONNECTED
, &ar
->flag
) ?
790 ALL_BSS_FILTER
), 0) != 0) {
791 ath6kl_err("couldn't set bss filtering\n");
796 if (request
->n_ssids
&& request
->ssids
[0].ssid_len
) {
799 if (request
->n_ssids
> (MAX_PROBED_SSID_INDEX
- 1))
800 request
->n_ssids
= MAX_PROBED_SSID_INDEX
- 1;
802 for (i
= 0; i
< request
->n_ssids
; i
++)
803 ath6kl_wmi_probedssid_cmd(ar
->wmi
, i
+ 1,
805 request
->ssids
[i
].ssid_len
,
806 request
->ssids
[i
].ssid
);
809 if (ath6kl_wmi_startscan_cmd(ar
->wmi
, WMI_LONG_SCAN
, 0,
810 false, 0, 0, 0, NULL
) != 0) {
811 ath6kl_err("wmi_startscan_cmd failed\n");
815 ar
->scan_req
= request
;
820 void ath6kl_cfg80211_scan_complete_event(struct ath6kl
*ar
, int status
)
824 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "%s: status %d\n", __func__
, status
);
829 if ((status
== -ECANCELED
) || (status
== -EBUSY
)) {
830 cfg80211_scan_done(ar
->scan_req
, true);
834 /* Translate data to cfg80211 mgmt format */
835 wlan_iterate_nodes(&ar
->scan_table
, ar
->wdev
->wiphy
);
837 cfg80211_scan_done(ar
->scan_req
, false);
839 if (ar
->scan_req
->n_ssids
&& ar
->scan_req
->ssids
[0].ssid_len
) {
840 for (i
= 0; i
< ar
->scan_req
->n_ssids
; i
++) {
841 ath6kl_wmi_probedssid_cmd(ar
->wmi
, i
+ 1,
851 static int ath6kl_cfg80211_add_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
852 u8 key_index
, bool pairwise
,
854 struct key_params
*params
)
856 struct ath6kl
*ar
= (struct ath6kl
*)ath6kl_priv(ndev
);
857 struct ath6kl_key
*key
= NULL
;
862 if (!ath6kl_cfg80211_ready(ar
))
865 if (key_index
< WMI_MIN_KEY_INDEX
|| key_index
> WMI_MAX_KEY_INDEX
) {
866 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
,
867 "%s: key index %d out of bounds\n", __func__
,
872 key
= &ar
->keys
[key_index
];
873 memset(key
, 0, sizeof(struct ath6kl_key
));
876 key_usage
= PAIRWISE_USAGE
;
878 key_usage
= GROUP_USAGE
;
881 if (params
->key_len
> WLAN_MAX_KEY_LEN
||
882 params
->seq_len
> sizeof(key
->seq
))
885 key
->key_len
= params
->key_len
;
886 memcpy(key
->key
, params
->key
, key
->key_len
);
887 key
->seq_len
= params
->seq_len
;
888 memcpy(key
->seq
, params
->seq
, key
->seq_len
);
889 key
->cipher
= params
->cipher
;
892 switch (key
->cipher
) {
893 case WLAN_CIPHER_SUITE_WEP40
:
894 case WLAN_CIPHER_SUITE_WEP104
:
895 key_type
= WEP_CRYPT
;
898 case WLAN_CIPHER_SUITE_TKIP
:
899 key_type
= TKIP_CRYPT
;
902 case WLAN_CIPHER_SUITE_CCMP
:
903 key_type
= AES_CRYPT
;
910 if (((ar
->auth_mode
== WPA_PSK_AUTH
)
911 || (ar
->auth_mode
== WPA2_PSK_AUTH
))
912 && (key_usage
& GROUP_USAGE
))
913 del_timer(&ar
->disconnect_timer
);
915 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
,
916 "%s: index %d, key_len %d, key_type 0x%x, key_usage 0x%x, seq_len %d\n",
917 __func__
, key_index
, key
->key_len
, key_type
,
918 key_usage
, key
->seq_len
);
920 ar
->def_txkey_index
= key_index
;
921 status
= ath6kl_wmi_addkey_cmd(ar
->wmi
, ar
->def_txkey_index
,
922 key_type
, key_usage
, key
->key_len
,
923 key
->seq
, key
->key
, KEY_OP_INIT_VAL
,
924 (u8
*) mac_addr
, SYNC_BOTH_WMIFLAG
);
932 static int ath6kl_cfg80211_del_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
933 u8 key_index
, bool pairwise
,
936 struct ath6kl
*ar
= (struct ath6kl
*)ath6kl_priv(ndev
);
938 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "%s: index %d\n", __func__
, key_index
);
940 if (!ath6kl_cfg80211_ready(ar
))
943 if (key_index
< WMI_MIN_KEY_INDEX
|| key_index
> WMI_MAX_KEY_INDEX
) {
944 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
,
945 "%s: key index %d out of bounds\n", __func__
,
950 if (!ar
->keys
[key_index
].key_len
) {
951 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
,
952 "%s: index %d is empty\n", __func__
, key_index
);
956 ar
->keys
[key_index
].key_len
= 0;
958 return ath6kl_wmi_deletekey_cmd(ar
->wmi
, key_index
);
961 static int ath6kl_cfg80211_get_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
962 u8 key_index
, bool pairwise
,
963 const u8
*mac_addr
, void *cookie
,
964 void (*callback
) (void *cookie
,
965 struct key_params
*))
967 struct ath6kl
*ar
= (struct ath6kl
*)ath6kl_priv(ndev
);
968 struct ath6kl_key
*key
= NULL
;
969 struct key_params params
;
971 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "%s: index %d\n", __func__
, key_index
);
973 if (!ath6kl_cfg80211_ready(ar
))
976 if (key_index
< WMI_MIN_KEY_INDEX
|| key_index
> WMI_MAX_KEY_INDEX
) {
977 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
,
978 "%s: key index %d out of bounds\n", __func__
,
983 key
= &ar
->keys
[key_index
];
984 memset(¶ms
, 0, sizeof(params
));
985 params
.cipher
= key
->cipher
;
986 params
.key_len
= key
->key_len
;
987 params
.seq_len
= key
->seq_len
;
988 params
.seq
= key
->seq
;
989 params
.key
= key
->key
;
991 callback(cookie
, ¶ms
);
993 return key
->key_len
? 0 : -ENOENT
;
996 static int ath6kl_cfg80211_set_default_key(struct wiphy
*wiphy
,
997 struct net_device
*ndev
,
998 u8 key_index
, bool unicast
,
1001 struct ath6kl
*ar
= (struct ath6kl
*)ath6kl_priv(ndev
);
1002 struct ath6kl_key
*key
= NULL
;
1006 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "%s: index %d\n", __func__
, key_index
);
1008 if (!ath6kl_cfg80211_ready(ar
))
1011 if (key_index
< WMI_MIN_KEY_INDEX
|| key_index
> WMI_MAX_KEY_INDEX
) {
1012 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
,
1013 "%s: key index %d out of bounds\n",
1014 __func__
, key_index
);
1018 if (!ar
->keys
[key_index
].key_len
) {
1019 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "%s: invalid key index %d\n",
1020 __func__
, key_index
);
1024 ar
->def_txkey_index
= key_index
;
1025 key
= &ar
->keys
[ar
->def_txkey_index
];
1026 key_usage
= GROUP_USAGE
;
1027 if (ar
->prwise_crypto
== WEP_CRYPT
)
1028 key_usage
|= TX_USAGE
;
1030 status
= ath6kl_wmi_addkey_cmd(ar
->wmi
, ar
->def_txkey_index
,
1031 ar
->prwise_crypto
, key_usage
,
1032 key
->key_len
, key
->seq
, key
->key
,
1033 KEY_OP_INIT_VAL
, NULL
,
1041 void ath6kl_cfg80211_tkip_micerr_event(struct ath6kl
*ar
, u8 keyid
,
1044 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
,
1045 "%s: keyid %d, ismcast %d\n", __func__
, keyid
, ismcast
);
1047 cfg80211_michael_mic_failure(ar
->net_dev
, ar
->bssid
,
1048 (ismcast
? NL80211_KEYTYPE_GROUP
:
1049 NL80211_KEYTYPE_PAIRWISE
), keyid
, NULL
,
1053 static int ath6kl_cfg80211_set_wiphy_params(struct wiphy
*wiphy
, u32 changed
)
1055 struct ath6kl
*ar
= (struct ath6kl
*)wiphy_priv(wiphy
);
1058 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "%s: changed 0x%x\n", __func__
,
1061 if (!ath6kl_cfg80211_ready(ar
))
1064 if (changed
& WIPHY_PARAM_RTS_THRESHOLD
) {
1065 ret
= ath6kl_wmi_set_rts_cmd(ar
->wmi
, wiphy
->rts_threshold
);
1067 ath6kl_err("ath6kl_wmi_set_rts_cmd failed\n");
1076 * The type nl80211_tx_power_setting replaces the following
1077 * data type from 2.6.36 onwards
1079 static int ath6kl_cfg80211_set_txpower(struct wiphy
*wiphy
,
1080 enum nl80211_tx_power_setting type
,
1083 struct ath6kl
*ar
= (struct ath6kl
*)wiphy_priv(wiphy
);
1086 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "%s: type 0x%x, dbm %d\n", __func__
,
1089 if (!ath6kl_cfg80211_ready(ar
))
1093 case NL80211_TX_POWER_AUTOMATIC
:
1095 case NL80211_TX_POWER_LIMITED
:
1096 ar
->tx_pwr
= ath6kl_dbm
= dbm
;
1099 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "%s: type 0x%x not supported\n",
1104 ath6kl_wmi_set_tx_pwr_cmd(ar
->wmi
, ath6kl_dbm
);
1109 static int ath6kl_cfg80211_get_txpower(struct wiphy
*wiphy
, int *dbm
)
1111 struct ath6kl
*ar
= (struct ath6kl
*)wiphy_priv(wiphy
);
1113 if (!ath6kl_cfg80211_ready(ar
))
1116 if (test_bit(CONNECTED
, &ar
->flag
)) {
1119 if (ath6kl_wmi_get_tx_pwr_cmd(ar
->wmi
) != 0) {
1120 ath6kl_err("ath6kl_wmi_get_tx_pwr_cmd failed\n");
1124 wait_event_interruptible_timeout(ar
->event_wq
, ar
->tx_pwr
!= 0,
1127 if (signal_pending(current
)) {
1128 ath6kl_err("target did not respond\n");
1137 static int ath6kl_cfg80211_set_power_mgmt(struct wiphy
*wiphy
,
1138 struct net_device
*dev
,
1139 bool pmgmt
, int timeout
)
1141 struct ath6kl
*ar
= ath6kl_priv(dev
);
1142 struct wmi_power_mode_cmd mode
;
1144 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "%s: pmgmt %d, timeout %d\n",
1145 __func__
, pmgmt
, timeout
);
1147 if (!ath6kl_cfg80211_ready(ar
))
1151 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "%s: max perf\n", __func__
);
1152 mode
.pwr_mode
= REC_POWER
;
1154 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "%s: rec power\n", __func__
);
1155 mode
.pwr_mode
= MAX_PERF_POWER
;
1158 if (ath6kl_wmi_powermode_cmd(ar
->wmi
, mode
.pwr_mode
) != 0) {
1159 ath6kl_err("wmi_powermode_cmd failed\n");
1166 static int ath6kl_cfg80211_change_iface(struct wiphy
*wiphy
,
1167 struct net_device
*ndev
,
1168 enum nl80211_iftype type
, u32
*flags
,
1169 struct vif_params
*params
)
1171 struct ath6kl
*ar
= ath6kl_priv(ndev
);
1172 struct wireless_dev
*wdev
= ar
->wdev
;
1174 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "%s: type %u\n", __func__
, type
);
1176 if (!ath6kl_cfg80211_ready(ar
))
1180 case NL80211_IFTYPE_STATION
:
1181 ar
->next_mode
= INFRA_NETWORK
;
1183 case NL80211_IFTYPE_ADHOC
:
1184 ar
->next_mode
= ADHOC_NETWORK
;
1187 ath6kl_err("invalid interface type %u\n", type
);
1191 wdev
->iftype
= type
;
1196 static int ath6kl_cfg80211_join_ibss(struct wiphy
*wiphy
,
1197 struct net_device
*dev
,
1198 struct cfg80211_ibss_params
*ibss_param
)
1200 struct ath6kl
*ar
= ath6kl_priv(dev
);
1203 if (!ath6kl_cfg80211_ready(ar
))
1206 ar
->ssid_len
= ibss_param
->ssid_len
;
1207 memcpy(ar
->ssid
, ibss_param
->ssid
, ar
->ssid_len
);
1209 if (ibss_param
->channel
)
1210 ar
->ch_hint
= ibss_param
->channel
->center_freq
;
1212 if (ibss_param
->channel_fixed
) {
1214 * TODO: channel_fixed: The channel should be fixed, do not
1215 * search for IBSSs to join on other channels. Target
1216 * firmware does not support this feature, needs to be
1222 memset(ar
->req_bssid
, 0, sizeof(ar
->req_bssid
));
1223 if (ibss_param
->bssid
&& !is_broadcast_ether_addr(ibss_param
->bssid
))
1224 memcpy(ar
->req_bssid
, ibss_param
->bssid
, sizeof(ar
->req_bssid
));
1226 ath6kl_set_wpa_version(ar
, 0);
1228 status
= ath6kl_set_auth_type(ar
, NL80211_AUTHTYPE_OPEN_SYSTEM
);
1232 if (ibss_param
->privacy
) {
1233 ath6kl_set_cipher(ar
, WLAN_CIPHER_SUITE_WEP40
, true);
1234 ath6kl_set_cipher(ar
, WLAN_CIPHER_SUITE_WEP40
, false);
1236 ath6kl_set_cipher(ar
, 0, true);
1237 ath6kl_set_cipher(ar
, 0, false);
1240 ar
->nw_type
= ar
->next_mode
;
1242 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
,
1243 "%s: connect called with authmode %d dot11 auth %d"
1244 " PW crypto %d PW crypto len %d GRP crypto %d"
1245 " GRP crypto len %d channel hint %u\n",
1247 ar
->auth_mode
, ar
->dot11_auth_mode
, ar
->prwise_crypto
,
1248 ar
->prwise_crypto_len
, ar
->grp_crypto
,
1249 ar
->grp_crpto_len
, ar
->ch_hint
);
1251 status
= ath6kl_wmi_connect_cmd(ar
->wmi
, ar
->nw_type
,
1252 ar
->dot11_auth_mode
, ar
->auth_mode
,
1254 ar
->prwise_crypto_len
,
1255 ar
->grp_crypto
, ar
->grp_crpto_len
,
1256 ar
->ssid_len
, ar
->ssid
,
1257 ar
->req_bssid
, ar
->ch_hint
,
1258 ar
->connect_ctrl_flags
);
1259 set_bit(CONNECT_PEND
, &ar
->flag
);
1264 static int ath6kl_cfg80211_leave_ibss(struct wiphy
*wiphy
,
1265 struct net_device
*dev
)
1267 struct ath6kl
*ar
= (struct ath6kl
*)ath6kl_priv(dev
);
1269 if (!ath6kl_cfg80211_ready(ar
))
1272 ath6kl_disconnect(ar
);
1273 memset(ar
->ssid
, 0, sizeof(ar
->ssid
));
1279 static const u32 cipher_suites
[] = {
1280 WLAN_CIPHER_SUITE_WEP40
,
1281 WLAN_CIPHER_SUITE_WEP104
,
1282 WLAN_CIPHER_SUITE_TKIP
,
1283 WLAN_CIPHER_SUITE_CCMP
,
1286 static bool is_rate_legacy(s32 rate
)
1288 static const s32 legacy
[] = { 1000, 2000, 5500, 11000,
1289 6000, 9000, 12000, 18000, 24000,
1294 for (i
= 0; i
< ARRAY_SIZE(legacy
); i
++)
1295 if (rate
== legacy
[i
])
1301 static bool is_rate_ht20(s32 rate
, u8
*mcs
, bool *sgi
)
1303 static const s32 ht20
[] = { 6500, 13000, 19500, 26000, 39000,
1304 52000, 58500, 65000, 72200
1308 for (i
= 0; i
< ARRAY_SIZE(ht20
); i
++) {
1309 if (rate
== ht20
[i
]) {
1310 if (i
== ARRAY_SIZE(ht20
) - 1)
1311 /* last rate uses sgi */
1323 static bool is_rate_ht40(s32 rate
, u8
*mcs
, bool *sgi
)
1325 static const s32 ht40
[] = { 13500, 27000, 40500, 54000,
1326 81000, 108000, 121500, 135000,
1331 for (i
= 0; i
< ARRAY_SIZE(ht40
); i
++) {
1332 if (rate
== ht40
[i
]) {
1333 if (i
== ARRAY_SIZE(ht40
) - 1)
1334 /* last rate uses sgi */
1347 static int ath6kl_get_station(struct wiphy
*wiphy
, struct net_device
*dev
,
1348 u8
*mac
, struct station_info
*sinfo
)
1350 struct ath6kl
*ar
= ath6kl_priv(dev
);
1357 if (memcmp(mac
, ar
->bssid
, ETH_ALEN
) != 0)
1360 if (down_interruptible(&ar
->sem
))
1363 set_bit(STATS_UPDATE_PEND
, &ar
->flag
);
1365 ret
= ath6kl_wmi_get_stats_cmd(ar
->wmi
);
1372 left
= wait_event_interruptible_timeout(ar
->event_wq
,
1373 !test_bit(STATS_UPDATE_PEND
,
1384 if (ar
->target_stats
.rx_byte
) {
1385 sinfo
->rx_bytes
= ar
->target_stats
.rx_byte
;
1386 sinfo
->filled
|= STATION_INFO_RX_BYTES
;
1387 sinfo
->rx_packets
= ar
->target_stats
.rx_pkt
;
1388 sinfo
->filled
|= STATION_INFO_RX_PACKETS
;
1391 if (ar
->target_stats
.tx_byte
) {
1392 sinfo
->tx_bytes
= ar
->target_stats
.tx_byte
;
1393 sinfo
->filled
|= STATION_INFO_TX_BYTES
;
1394 sinfo
->tx_packets
= ar
->target_stats
.tx_pkt
;
1395 sinfo
->filled
|= STATION_INFO_TX_PACKETS
;
1398 sinfo
->signal
= ar
->target_stats
.cs_rssi
;
1399 sinfo
->filled
|= STATION_INFO_SIGNAL
;
1401 rate
= ar
->target_stats
.tx_ucast_rate
;
1403 if (is_rate_legacy(rate
)) {
1404 sinfo
->txrate
.legacy
= rate
/ 100;
1405 } else if (is_rate_ht20(rate
, &mcs
, &sgi
)) {
1407 sinfo
->txrate
.flags
|= RATE_INFO_FLAGS_SHORT_GI
;
1408 sinfo
->txrate
.mcs
= mcs
- 1;
1410 sinfo
->txrate
.mcs
= mcs
;
1413 sinfo
->txrate
.flags
|= RATE_INFO_FLAGS_MCS
;
1414 } else if (is_rate_ht40(rate
, &mcs
, &sgi
)) {
1416 sinfo
->txrate
.flags
|= RATE_INFO_FLAGS_SHORT_GI
;
1417 sinfo
->txrate
.mcs
= mcs
- 1;
1419 sinfo
->txrate
.mcs
= mcs
;
1422 sinfo
->txrate
.flags
|= RATE_INFO_FLAGS_40_MHZ_WIDTH
;
1423 sinfo
->txrate
.flags
|= RATE_INFO_FLAGS_MCS
;
1425 ath6kl_warn("invalid rate: %d\n", rate
);
1429 sinfo
->filled
|= STATION_INFO_TX_BITRATE
;
1434 static int ath6kl_set_pmksa(struct wiphy
*wiphy
, struct net_device
*netdev
,
1435 struct cfg80211_pmksa
*pmksa
)
1437 struct ath6kl
*ar
= ath6kl_priv(netdev
);
1438 return ath6kl_wmi_setpmkid_cmd(ar
->wmi
, pmksa
->bssid
,
1439 pmksa
->pmkid
, true);
1442 static int ath6kl_del_pmksa(struct wiphy
*wiphy
, struct net_device
*netdev
,
1443 struct cfg80211_pmksa
*pmksa
)
1445 struct ath6kl
*ar
= ath6kl_priv(netdev
);
1446 return ath6kl_wmi_setpmkid_cmd(ar
->wmi
, pmksa
->bssid
,
1447 pmksa
->pmkid
, false);
1450 static int ath6kl_flush_pmksa(struct wiphy
*wiphy
, struct net_device
*netdev
)
1452 struct ath6kl
*ar
= ath6kl_priv(netdev
);
1453 if (test_bit(CONNECTED
, &ar
->flag
))
1454 return ath6kl_wmi_setpmkid_cmd(ar
->wmi
, ar
->bssid
, NULL
, false);
1458 static struct cfg80211_ops ath6kl_cfg80211_ops
= {
1459 .change_virtual_intf
= ath6kl_cfg80211_change_iface
,
1460 .scan
= ath6kl_cfg80211_scan
,
1461 .connect
= ath6kl_cfg80211_connect
,
1462 .disconnect
= ath6kl_cfg80211_disconnect
,
1463 .add_key
= ath6kl_cfg80211_add_key
,
1464 .get_key
= ath6kl_cfg80211_get_key
,
1465 .del_key
= ath6kl_cfg80211_del_key
,
1466 .set_default_key
= ath6kl_cfg80211_set_default_key
,
1467 .set_wiphy_params
= ath6kl_cfg80211_set_wiphy_params
,
1468 .set_tx_power
= ath6kl_cfg80211_set_txpower
,
1469 .get_tx_power
= ath6kl_cfg80211_get_txpower
,
1470 .set_power_mgmt
= ath6kl_cfg80211_set_power_mgmt
,
1471 .join_ibss
= ath6kl_cfg80211_join_ibss
,
1472 .leave_ibss
= ath6kl_cfg80211_leave_ibss
,
1473 .get_station
= ath6kl_get_station
,
1474 .set_pmksa
= ath6kl_set_pmksa
,
1475 .del_pmksa
= ath6kl_del_pmksa
,
1476 .flush_pmksa
= ath6kl_flush_pmksa
,
1479 struct wireless_dev
*ath6kl_cfg80211_init(struct device
*dev
)
1482 struct wireless_dev
*wdev
;
1484 wdev
= kzalloc(sizeof(struct wireless_dev
), GFP_KERNEL
);
1486 ath6kl_err("couldn't allocate wireless device\n");
1490 /* create a new wiphy for use with cfg80211 */
1491 wdev
->wiphy
= wiphy_new(&ath6kl_cfg80211_ops
, sizeof(struct ath6kl
));
1493 ath6kl_err("couldn't allocate wiphy device\n");
1498 /* set device pointer for wiphy */
1499 set_wiphy_dev(wdev
->wiphy
, dev
);
1501 wdev
->wiphy
->interface_modes
= BIT(NL80211_IFTYPE_STATION
) |
1502 BIT(NL80211_IFTYPE_ADHOC
);
1503 /* max num of ssids that can be probed during scanning */
1504 wdev
->wiphy
->max_scan_ssids
= MAX_PROBED_SSID_INDEX
;
1505 wdev
->wiphy
->bands
[IEEE80211_BAND_2GHZ
] = &ath6kl_band_2ghz
;
1506 wdev
->wiphy
->bands
[IEEE80211_BAND_5GHZ
] = &ath6kl_band_5ghz
;
1507 wdev
->wiphy
->signal_type
= CFG80211_SIGNAL_TYPE_MBM
;
1509 wdev
->wiphy
->cipher_suites
= cipher_suites
;
1510 wdev
->wiphy
->n_cipher_suites
= ARRAY_SIZE(cipher_suites
);
1512 ret
= wiphy_register(wdev
->wiphy
);
1514 ath6kl_err("couldn't register wiphy device\n");
1515 wiphy_free(wdev
->wiphy
);
1523 void ath6kl_cfg80211_deinit(struct ath6kl
*ar
)
1525 struct wireless_dev
*wdev
= ar
->wdev
;
1528 cfg80211_scan_done(ar
->scan_req
, true);
1529 ar
->scan_req
= NULL
;
1535 wiphy_unregister(wdev
->wiphy
);
1536 wiphy_free(wdev
->wiphy
);