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.
17 #include <linux/moduleparam.h>
18 #include <linux/inetdevice.h>
26 static unsigned int ath6kl_p2p
;
28 module_param(ath6kl_p2p
, uint
, 0644);
30 #define RATETAB_ENT(_rate, _rateid, _flags) { \
33 .hw_value = (_rateid), \
36 #define CHAN2G(_channel, _freq, _flags) { \
37 .band = IEEE80211_BAND_2GHZ, \
38 .hw_value = (_channel), \
39 .center_freq = (_freq), \
41 .max_antenna_gain = 0, \
45 #define CHAN5G(_channel, _flags) { \
46 .band = IEEE80211_BAND_5GHZ, \
47 .hw_value = (_channel), \
48 .center_freq = 5000 + (5 * (_channel)), \
50 .max_antenna_gain = 0, \
54 static struct ieee80211_rate ath6kl_rates
[] = {
55 RATETAB_ENT(10, 0x1, 0),
56 RATETAB_ENT(20, 0x2, 0),
57 RATETAB_ENT(55, 0x4, 0),
58 RATETAB_ENT(110, 0x8, 0),
59 RATETAB_ENT(60, 0x10, 0),
60 RATETAB_ENT(90, 0x20, 0),
61 RATETAB_ENT(120, 0x40, 0),
62 RATETAB_ENT(180, 0x80, 0),
63 RATETAB_ENT(240, 0x100, 0),
64 RATETAB_ENT(360, 0x200, 0),
65 RATETAB_ENT(480, 0x400, 0),
66 RATETAB_ENT(540, 0x800, 0),
69 #define ath6kl_a_rates (ath6kl_rates + 4)
70 #define ath6kl_a_rates_size 8
71 #define ath6kl_g_rates (ath6kl_rates + 0)
72 #define ath6kl_g_rates_size 12
74 static struct ieee80211_channel ath6kl_2ghz_channels
[] = {
91 static struct ieee80211_channel ath6kl_5ghz_a_channels
[] = {
92 CHAN5G(34, 0), CHAN5G(36, 0),
93 CHAN5G(38, 0), CHAN5G(40, 0),
94 CHAN5G(42, 0), CHAN5G(44, 0),
95 CHAN5G(46, 0), CHAN5G(48, 0),
96 CHAN5G(52, 0), CHAN5G(56, 0),
97 CHAN5G(60, 0), CHAN5G(64, 0),
98 CHAN5G(100, 0), CHAN5G(104, 0),
99 CHAN5G(108, 0), CHAN5G(112, 0),
100 CHAN5G(116, 0), CHAN5G(120, 0),
101 CHAN5G(124, 0), CHAN5G(128, 0),
102 CHAN5G(132, 0), CHAN5G(136, 0),
103 CHAN5G(140, 0), CHAN5G(149, 0),
104 CHAN5G(153, 0), CHAN5G(157, 0),
105 CHAN5G(161, 0), CHAN5G(165, 0),
106 CHAN5G(184, 0), CHAN5G(188, 0),
107 CHAN5G(192, 0), CHAN5G(196, 0),
108 CHAN5G(200, 0), CHAN5G(204, 0),
109 CHAN5G(208, 0), CHAN5G(212, 0),
113 static struct ieee80211_supported_band ath6kl_band_2ghz
= {
114 .n_channels
= ARRAY_SIZE(ath6kl_2ghz_channels
),
115 .channels
= ath6kl_2ghz_channels
,
116 .n_bitrates
= ath6kl_g_rates_size
,
117 .bitrates
= ath6kl_g_rates
,
120 static struct ieee80211_supported_band ath6kl_band_5ghz
= {
121 .n_channels
= ARRAY_SIZE(ath6kl_5ghz_a_channels
),
122 .channels
= ath6kl_5ghz_a_channels
,
123 .n_bitrates
= ath6kl_a_rates_size
,
124 .bitrates
= ath6kl_a_rates
,
127 #define CCKM_KRK_CIPHER_SUITE 0x004096ff /* use for KRK */
129 /* returns true if scheduled scan was stopped */
130 static bool __ath6kl_cfg80211_sscan_stop(struct ath6kl_vif
*vif
)
132 struct ath6kl
*ar
= vif
->ar
;
134 if (ar
->state
!= ATH6KL_STATE_SCHED_SCAN
)
137 del_timer_sync(&vif
->sched_scan_timer
);
139 ath6kl_wmi_set_host_sleep_mode_cmd(ar
->wmi
, vif
->fw_vif_idx
,
140 ATH6KL_HOST_MODE_AWAKE
);
142 ar
->state
= ATH6KL_STATE_ON
;
147 static void ath6kl_cfg80211_sscan_disable(struct ath6kl_vif
*vif
)
149 struct ath6kl
*ar
= vif
->ar
;
152 stopped
= __ath6kl_cfg80211_sscan_stop(vif
);
157 cfg80211_sched_scan_stopped(ar
->wiphy
);
160 static int ath6kl_set_wpa_version(struct ath6kl_vif
*vif
,
161 enum nl80211_wpa_versions wpa_version
)
163 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "%s: %u\n", __func__
, wpa_version
);
166 vif
->auth_mode
= NONE_AUTH
;
167 } else if (wpa_version
& NL80211_WPA_VERSION_2
) {
168 vif
->auth_mode
= WPA2_AUTH
;
169 } else if (wpa_version
& NL80211_WPA_VERSION_1
) {
170 vif
->auth_mode
= WPA_AUTH
;
172 ath6kl_err("%s: %u not supported\n", __func__
, wpa_version
);
179 static int ath6kl_set_auth_type(struct ath6kl_vif
*vif
,
180 enum nl80211_auth_type auth_type
)
182 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "%s: 0x%x\n", __func__
, auth_type
);
185 case NL80211_AUTHTYPE_OPEN_SYSTEM
:
186 vif
->dot11_auth_mode
= OPEN_AUTH
;
188 case NL80211_AUTHTYPE_SHARED_KEY
:
189 vif
->dot11_auth_mode
= SHARED_AUTH
;
191 case NL80211_AUTHTYPE_NETWORK_EAP
:
192 vif
->dot11_auth_mode
= LEAP_AUTH
;
195 case NL80211_AUTHTYPE_AUTOMATIC
:
196 vif
->dot11_auth_mode
= OPEN_AUTH
| SHARED_AUTH
;
200 ath6kl_err("%s: 0x%x not spported\n", __func__
, auth_type
);
207 static int ath6kl_set_cipher(struct ath6kl_vif
*vif
, u32 cipher
, bool ucast
)
209 u8
*ar_cipher
= ucast
? &vif
->prwise_crypto
: &vif
->grp_crypto
;
210 u8
*ar_cipher_len
= ucast
? &vif
->prwise_crypto_len
:
211 &vif
->grp_crypto_len
;
213 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "%s: cipher 0x%x, ucast %u\n",
214 __func__
, cipher
, ucast
);
218 /* our own hack to use value 0 as no crypto used */
219 *ar_cipher
= NONE_CRYPT
;
222 case WLAN_CIPHER_SUITE_WEP40
:
223 *ar_cipher
= WEP_CRYPT
;
226 case WLAN_CIPHER_SUITE_WEP104
:
227 *ar_cipher
= WEP_CRYPT
;
230 case WLAN_CIPHER_SUITE_TKIP
:
231 *ar_cipher
= TKIP_CRYPT
;
234 case WLAN_CIPHER_SUITE_CCMP
:
235 *ar_cipher
= AES_CRYPT
;
238 case WLAN_CIPHER_SUITE_SMS4
:
239 *ar_cipher
= WAPI_CRYPT
;
243 ath6kl_err("cipher 0x%x not supported\n", cipher
);
250 static void ath6kl_set_key_mgmt(struct ath6kl_vif
*vif
, u32 key_mgmt
)
252 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "%s: 0x%x\n", __func__
, key_mgmt
);
254 if (key_mgmt
== WLAN_AKM_SUITE_PSK
) {
255 if (vif
->auth_mode
== WPA_AUTH
)
256 vif
->auth_mode
= WPA_PSK_AUTH
;
257 else if (vif
->auth_mode
== WPA2_AUTH
)
258 vif
->auth_mode
= WPA2_PSK_AUTH
;
259 } else if (key_mgmt
== 0x00409600) {
260 if (vif
->auth_mode
== WPA_AUTH
)
261 vif
->auth_mode
= WPA_AUTH_CCKM
;
262 else if (vif
->auth_mode
== WPA2_AUTH
)
263 vif
->auth_mode
= WPA2_AUTH_CCKM
;
264 } else if (key_mgmt
!= WLAN_AKM_SUITE_8021X
) {
265 vif
->auth_mode
= NONE_AUTH
;
269 static bool ath6kl_cfg80211_ready(struct ath6kl_vif
*vif
)
271 struct ath6kl
*ar
= vif
->ar
;
273 if (!test_bit(WMI_READY
, &ar
->flag
)) {
274 ath6kl_err("wmi is not ready\n");
278 if (!test_bit(WLAN_ENABLED
, &vif
->flags
)) {
279 ath6kl_err("wlan disabled\n");
286 static bool ath6kl_is_wpa_ie(const u8
*pos
)
288 return pos
[0] == WLAN_EID_WPA
&& pos
[1] >= 4 &&
289 pos
[2] == 0x00 && pos
[3] == 0x50 &&
290 pos
[4] == 0xf2 && pos
[5] == 0x01;
293 static bool ath6kl_is_rsn_ie(const u8
*pos
)
295 return pos
[0] == WLAN_EID_RSN
;
298 static bool ath6kl_is_wps_ie(const u8
*pos
)
300 return (pos
[0] == WLAN_EID_VENDOR_SPECIFIC
&&
302 pos
[2] == 0x00 && pos
[3] == 0x50 && pos
[4] == 0xf2 &&
306 static int ath6kl_set_assoc_req_ies(struct ath6kl_vif
*vif
, const u8
*ies
,
309 struct ath6kl
*ar
= vif
->ar
;
316 * Clear previously set flag
319 ar
->connect_ctrl_flags
&= ~CONNECT_WPS_FLAG
;
322 * Filter out RSN/WPA IE(s)
325 if (ies
&& ies_len
) {
326 buf
= kmalloc(ies_len
, GFP_KERNEL
);
331 while (pos
+ 1 < ies
+ ies_len
) {
332 if (pos
+ 2 + pos
[1] > ies
+ ies_len
)
334 if (!(ath6kl_is_wpa_ie(pos
) || ath6kl_is_rsn_ie(pos
))) {
335 memcpy(buf
+ len
, pos
, 2 + pos
[1]);
339 if (ath6kl_is_wps_ie(pos
))
340 ar
->connect_ctrl_flags
|= CONNECT_WPS_FLAG
;
346 ret
= ath6kl_wmi_set_appie_cmd(ar
->wmi
, vif
->fw_vif_idx
,
347 WMI_FRAME_ASSOC_REQ
, buf
, len
);
352 static int ath6kl_nliftype_to_drv_iftype(enum nl80211_iftype type
, u8
*nw_type
)
355 case NL80211_IFTYPE_STATION
:
356 *nw_type
= INFRA_NETWORK
;
358 case NL80211_IFTYPE_ADHOC
:
359 *nw_type
= ADHOC_NETWORK
;
361 case NL80211_IFTYPE_AP
:
362 *nw_type
= AP_NETWORK
;
364 case NL80211_IFTYPE_P2P_CLIENT
:
365 *nw_type
= INFRA_NETWORK
;
367 case NL80211_IFTYPE_P2P_GO
:
368 *nw_type
= AP_NETWORK
;
371 ath6kl_err("invalid interface type %u\n", type
);
378 static bool ath6kl_is_valid_iftype(struct ath6kl
*ar
, enum nl80211_iftype type
,
379 u8
*if_idx
, u8
*nw_type
)
383 if (ath6kl_nliftype_to_drv_iftype(type
, nw_type
))
386 if (ar
->ibss_if_active
|| ((type
== NL80211_IFTYPE_ADHOC
) &&
390 if (type
== NL80211_IFTYPE_STATION
||
391 type
== NL80211_IFTYPE_AP
|| type
== NL80211_IFTYPE_ADHOC
) {
392 for (i
= 0; i
< ar
->vif_max
; i
++) {
393 if ((ar
->avail_idx_map
>> i
) & BIT(0)) {
400 if (type
== NL80211_IFTYPE_P2P_CLIENT
||
401 type
== NL80211_IFTYPE_P2P_GO
) {
402 for (i
= ar
->max_norm_iface
; i
< ar
->vif_max
; i
++) {
403 if ((ar
->avail_idx_map
>> i
) & BIT(0)) {
413 static int ath6kl_cfg80211_connect(struct wiphy
*wiphy
, struct net_device
*dev
,
414 struct cfg80211_connect_params
*sme
)
416 struct ath6kl
*ar
= ath6kl_priv(dev
);
417 struct ath6kl_vif
*vif
= netdev_priv(dev
);
419 u8 nw_subtype
= (ar
->p2p
) ? SUBTYPE_P2PDEV
: SUBTYPE_NONE
;
421 ath6kl_cfg80211_sscan_disable(vif
);
423 vif
->sme_state
= SME_CONNECTING
;
425 if (!ath6kl_cfg80211_ready(vif
))
428 if (test_bit(DESTROY_IN_PROGRESS
, &ar
->flag
)) {
429 ath6kl_err("destroy in progress\n");
433 if (test_bit(SKIP_SCAN
, &ar
->flag
) &&
434 ((sme
->channel
&& sme
->channel
->center_freq
== 0) ||
435 (sme
->bssid
&& is_zero_ether_addr(sme
->bssid
)))) {
436 ath6kl_err("SkipScan: channel or bssid invalid\n");
440 if (down_interruptible(&ar
->sem
)) {
441 ath6kl_err("busy, couldn't get access\n");
445 if (test_bit(DESTROY_IN_PROGRESS
, &ar
->flag
)) {
446 ath6kl_err("busy, destroy in progress\n");
451 if (ar
->tx_pending
[ath6kl_wmi_get_control_ep(ar
->wmi
)]) {
453 * sleep until the command queue drains
455 wait_event_interruptible_timeout(ar
->event_wq
,
456 ar
->tx_pending
[ath6kl_wmi_get_control_ep(ar
->wmi
)] == 0,
458 if (signal_pending(current
)) {
459 ath6kl_err("cmd queue drain timeout\n");
465 status
= ath6kl_set_assoc_req_ies(vif
, sme
->ie
, sme
->ie_len
);
471 if (sme
->ie
== NULL
|| sme
->ie_len
== 0)
472 ar
->connect_ctrl_flags
&= ~CONNECT_WPS_FLAG
;
474 if (test_bit(CONNECTED
, &vif
->flags
) &&
475 vif
->ssid_len
== sme
->ssid_len
&&
476 !memcmp(vif
->ssid
, sme
->ssid
, vif
->ssid_len
)) {
477 vif
->reconnect_flag
= true;
478 status
= ath6kl_wmi_reconnect_cmd(ar
->wmi
, vif
->fw_vif_idx
,
484 ath6kl_err("wmi_reconnect_cmd failed\n");
488 } else if (vif
->ssid_len
== sme
->ssid_len
&&
489 !memcmp(vif
->ssid
, sme
->ssid
, vif
->ssid_len
)) {
490 ath6kl_disconnect(vif
);
493 memset(vif
->ssid
, 0, sizeof(vif
->ssid
));
494 vif
->ssid_len
= sme
->ssid_len
;
495 memcpy(vif
->ssid
, sme
->ssid
, sme
->ssid_len
);
498 vif
->ch_hint
= sme
->channel
->center_freq
;
500 memset(vif
->req_bssid
, 0, sizeof(vif
->req_bssid
));
501 if (sme
->bssid
&& !is_broadcast_ether_addr(sme
->bssid
))
502 memcpy(vif
->req_bssid
, sme
->bssid
, sizeof(vif
->req_bssid
));
504 ath6kl_set_wpa_version(vif
, sme
->crypto
.wpa_versions
);
506 status
= ath6kl_set_auth_type(vif
, sme
->auth_type
);
512 if (sme
->crypto
.n_ciphers_pairwise
)
513 ath6kl_set_cipher(vif
, sme
->crypto
.ciphers_pairwise
[0], true);
515 ath6kl_set_cipher(vif
, 0, true);
517 ath6kl_set_cipher(vif
, sme
->crypto
.cipher_group
, false);
519 if (sme
->crypto
.n_akm_suites
)
520 ath6kl_set_key_mgmt(vif
, sme
->crypto
.akm_suites
[0]);
522 if ((sme
->key_len
) &&
523 (vif
->auth_mode
== NONE_AUTH
) &&
524 (vif
->prwise_crypto
== WEP_CRYPT
)) {
525 struct ath6kl_key
*key
= NULL
;
527 if (sme
->key_idx
> WMI_MAX_KEY_INDEX
) {
528 ath6kl_err("key index %d out of bounds\n",
534 key
= &vif
->keys
[sme
->key_idx
];
535 key
->key_len
= sme
->key_len
;
536 memcpy(key
->key
, sme
->key
, key
->key_len
);
537 key
->cipher
= vif
->prwise_crypto
;
538 vif
->def_txkey_index
= sme
->key_idx
;
540 ath6kl_wmi_addkey_cmd(ar
->wmi
, vif
->fw_vif_idx
, sme
->key_idx
,
542 GROUP_USAGE
| TX_USAGE
,
545 key
->key
, KEY_OP_INIT_VAL
, NULL
,
549 if (!ar
->usr_bss_filter
) {
550 clear_bit(CLEAR_BSSFILTER_ON_BEACON
, &vif
->flags
);
551 if (ath6kl_wmi_bssfilter_cmd(ar
->wmi
, vif
->fw_vif_idx
,
552 ALL_BSS_FILTER
, 0) != 0) {
553 ath6kl_err("couldn't set bss filtering\n");
559 vif
->nw_type
= vif
->next_mode
;
561 if (vif
->wdev
.iftype
== NL80211_IFTYPE_P2P_CLIENT
)
562 nw_subtype
= SUBTYPE_P2PCLIENT
;
564 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
,
565 "%s: connect called with authmode %d dot11 auth %d"
566 " PW crypto %d PW crypto len %d GRP crypto %d"
567 " GRP crypto len %d channel hint %u\n",
569 vif
->auth_mode
, vif
->dot11_auth_mode
, vif
->prwise_crypto
,
570 vif
->prwise_crypto_len
, vif
->grp_crypto
,
571 vif
->grp_crypto_len
, vif
->ch_hint
);
573 vif
->reconnect_flag
= 0;
574 status
= ath6kl_wmi_connect_cmd(ar
->wmi
, vif
->fw_vif_idx
, vif
->nw_type
,
575 vif
->dot11_auth_mode
, vif
->auth_mode
,
577 vif
->prwise_crypto_len
,
578 vif
->grp_crypto
, vif
->grp_crypto_len
,
579 vif
->ssid_len
, vif
->ssid
,
580 vif
->req_bssid
, vif
->ch_hint
,
581 ar
->connect_ctrl_flags
, nw_subtype
);
585 if (status
== -EINVAL
) {
586 memset(vif
->ssid
, 0, sizeof(vif
->ssid
));
588 ath6kl_err("invalid request\n");
591 ath6kl_err("ath6kl_wmi_connect_cmd failed\n");
595 if ((!(ar
->connect_ctrl_flags
& CONNECT_DO_WPA_OFFLOAD
)) &&
596 ((vif
->auth_mode
== WPA_PSK_AUTH
)
597 || (vif
->auth_mode
== WPA2_PSK_AUTH
))) {
598 mod_timer(&vif
->disconnect_timer
,
599 jiffies
+ msecs_to_jiffies(DISCON_TIMER_INTVAL
));
602 ar
->connect_ctrl_flags
&= ~CONNECT_DO_WPA_OFFLOAD
;
603 set_bit(CONNECT_PEND
, &vif
->flags
);
608 static struct cfg80211_bss
*
609 ath6kl_add_bss_if_needed(struct ath6kl_vif
*vif
,
610 enum network_type nw_type
,
612 struct ieee80211_channel
*chan
,
614 size_t beacon_ie_len
)
616 struct ath6kl
*ar
= vif
->ar
;
617 struct cfg80211_bss
*bss
;
618 u16 cap_mask
, cap_val
;
621 if (nw_type
& ADHOC_NETWORK
) {
622 cap_mask
= WLAN_CAPABILITY_IBSS
;
623 cap_val
= WLAN_CAPABILITY_IBSS
;
625 cap_mask
= WLAN_CAPABILITY_ESS
;
626 cap_val
= WLAN_CAPABILITY_ESS
;
629 bss
= cfg80211_get_bss(ar
->wiphy
, chan
, bssid
,
630 vif
->ssid
, vif
->ssid_len
,
634 * Since cfg80211 may not yet know about the BSS,
635 * generate a partial entry until the first BSS info
636 * event becomes available.
638 * Prepend SSID element since it is not included in the Beacon
639 * IEs from the target.
641 ie
= kmalloc(2 + vif
->ssid_len
+ beacon_ie_len
, GFP_KERNEL
);
644 ie
[0] = WLAN_EID_SSID
;
645 ie
[1] = vif
->ssid_len
;
646 memcpy(ie
+ 2, vif
->ssid
, vif
->ssid_len
);
647 memcpy(ie
+ 2 + vif
->ssid_len
, beacon_ie
, beacon_ie_len
);
648 bss
= cfg80211_inform_bss(ar
->wiphy
, chan
,
649 bssid
, 0, cap_val
, 100,
650 ie
, 2 + vif
->ssid_len
+ beacon_ie_len
,
653 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "added bss %pM to "
654 "cfg80211\n", bssid
);
657 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "cfg80211 already has a bss\n");
662 void ath6kl_cfg80211_connect_event(struct ath6kl_vif
*vif
, u16 channel
,
663 u8
*bssid
, u16 listen_intvl
,
665 enum network_type nw_type
,
666 u8 beacon_ie_len
, u8 assoc_req_len
,
667 u8 assoc_resp_len
, u8
*assoc_info
)
669 struct ieee80211_channel
*chan
;
670 struct ath6kl
*ar
= vif
->ar
;
671 struct cfg80211_bss
*bss
;
673 /* capinfo + listen interval */
674 u8 assoc_req_ie_offset
= sizeof(u16
) + sizeof(u16
);
676 /* capinfo + status code + associd */
677 u8 assoc_resp_ie_offset
= sizeof(u16
) + sizeof(u16
) + sizeof(u16
);
679 u8
*assoc_req_ie
= assoc_info
+ beacon_ie_len
+ assoc_req_ie_offset
;
680 u8
*assoc_resp_ie
= assoc_info
+ beacon_ie_len
+ assoc_req_len
+
681 assoc_resp_ie_offset
;
683 assoc_req_len
-= assoc_req_ie_offset
;
684 assoc_resp_len
-= assoc_resp_ie_offset
;
687 * Store Beacon interval here; DTIM period will be available only once
688 * a Beacon frame from the AP is seen.
690 vif
->assoc_bss_beacon_int
= beacon_intvl
;
691 clear_bit(DTIM_PERIOD_AVAIL
, &vif
->flags
);
693 if (nw_type
& ADHOC_NETWORK
) {
694 if (vif
->wdev
.iftype
!= NL80211_IFTYPE_ADHOC
) {
695 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
,
696 "%s: ath6k not in ibss mode\n", __func__
);
701 if (nw_type
& INFRA_NETWORK
) {
702 if (vif
->wdev
.iftype
!= NL80211_IFTYPE_STATION
&&
703 vif
->wdev
.iftype
!= NL80211_IFTYPE_P2P_CLIENT
) {
704 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
,
705 "%s: ath6k not in station mode\n", __func__
);
710 chan
= ieee80211_get_channel(ar
->wiphy
, (int) channel
);
712 bss
= ath6kl_add_bss_if_needed(vif
, nw_type
, bssid
, chan
,
713 assoc_info
, beacon_ie_len
);
715 ath6kl_err("could not add cfg80211 bss entry\n");
719 if (nw_type
& ADHOC_NETWORK
) {
720 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "ad-hoc %s selected\n",
721 nw_type
& ADHOC_CREATOR
? "creator" : "joiner");
722 cfg80211_ibss_joined(vif
->ndev
, bssid
, GFP_KERNEL
);
723 cfg80211_put_bss(bss
);
727 if (vif
->sme_state
== SME_CONNECTING
) {
728 /* inform connect result to cfg80211 */
729 vif
->sme_state
= SME_CONNECTED
;
730 cfg80211_connect_result(vif
->ndev
, bssid
,
731 assoc_req_ie
, assoc_req_len
,
732 assoc_resp_ie
, assoc_resp_len
,
733 WLAN_STATUS_SUCCESS
, GFP_KERNEL
);
734 cfg80211_put_bss(bss
);
735 } else if (vif
->sme_state
== SME_CONNECTED
) {
736 /* inform roam event to cfg80211 */
737 cfg80211_roamed_bss(vif
->ndev
, bss
, assoc_req_ie
, assoc_req_len
,
738 assoc_resp_ie
, assoc_resp_len
, GFP_KERNEL
);
742 static int ath6kl_cfg80211_disconnect(struct wiphy
*wiphy
,
743 struct net_device
*dev
, u16 reason_code
)
745 struct ath6kl
*ar
= ath6kl_priv(dev
);
746 struct ath6kl_vif
*vif
= netdev_priv(dev
);
748 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "%s: reason=%u\n", __func__
,
751 ath6kl_cfg80211_sscan_disable(vif
);
753 if (!ath6kl_cfg80211_ready(vif
))
756 if (test_bit(DESTROY_IN_PROGRESS
, &ar
->flag
)) {
757 ath6kl_err("busy, destroy in progress\n");
761 if (down_interruptible(&ar
->sem
)) {
762 ath6kl_err("busy, couldn't get access\n");
766 vif
->reconnect_flag
= 0;
767 ath6kl_disconnect(vif
);
768 memset(vif
->ssid
, 0, sizeof(vif
->ssid
));
771 if (!test_bit(SKIP_SCAN
, &ar
->flag
))
772 memset(vif
->req_bssid
, 0, sizeof(vif
->req_bssid
));
776 vif
->sme_state
= SME_DISCONNECTED
;
781 void ath6kl_cfg80211_disconnect_event(struct ath6kl_vif
*vif
, u8 reason
,
782 u8
*bssid
, u8 assoc_resp_len
,
783 u8
*assoc_info
, u16 proto_reason
)
785 struct ath6kl
*ar
= vif
->ar
;
788 cfg80211_scan_done(vif
->scan_req
, true);
789 vif
->scan_req
= NULL
;
792 if (vif
->nw_type
& ADHOC_NETWORK
) {
793 if (vif
->wdev
.iftype
!= NL80211_IFTYPE_ADHOC
) {
794 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
,
795 "%s: ath6k not in ibss mode\n", __func__
);
798 memset(bssid
, 0, ETH_ALEN
);
799 cfg80211_ibss_joined(vif
->ndev
, bssid
, GFP_KERNEL
);
803 if (vif
->nw_type
& INFRA_NETWORK
) {
804 if (vif
->wdev
.iftype
!= NL80211_IFTYPE_STATION
&&
805 vif
->wdev
.iftype
!= NL80211_IFTYPE_P2P_CLIENT
) {
806 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
,
807 "%s: ath6k not in station mode\n", __func__
);
813 * Send a disconnect command to target when a disconnect event is
814 * received with reason code other than 3 (DISCONNECT_CMD - disconnect
815 * request from host) to make the firmware stop trying to connect even
816 * after giving disconnect event. There will be one more disconnect
817 * event for this disconnect command with reason code DISCONNECT_CMD
818 * which will be notified to cfg80211.
821 if (reason
!= DISCONNECT_CMD
) {
822 ath6kl_wmi_disconnect_cmd(ar
->wmi
, vif
->fw_vif_idx
);
826 clear_bit(CONNECT_PEND
, &vif
->flags
);
828 if (vif
->sme_state
== SME_CONNECTING
) {
829 cfg80211_connect_result(vif
->ndev
,
832 WLAN_STATUS_UNSPECIFIED_FAILURE
,
834 } else if (vif
->sme_state
== SME_CONNECTED
) {
835 cfg80211_disconnected(vif
->ndev
, reason
,
836 NULL
, 0, GFP_KERNEL
);
839 vif
->sme_state
= SME_DISCONNECTED
;
842 static int ath6kl_cfg80211_scan(struct wiphy
*wiphy
, struct net_device
*ndev
,
843 struct cfg80211_scan_request
*request
)
845 struct ath6kl
*ar
= ath6kl_priv(ndev
);
846 struct ath6kl_vif
*vif
= netdev_priv(ndev
);
848 u16
*channels
= NULL
;
850 u32 force_fg_scan
= 0;
852 if (!ath6kl_cfg80211_ready(vif
))
855 ath6kl_cfg80211_sscan_disable(vif
);
857 if (!ar
->usr_bss_filter
) {
858 clear_bit(CLEAR_BSSFILTER_ON_BEACON
, &vif
->flags
);
859 ret
= ath6kl_wmi_bssfilter_cmd(
860 ar
->wmi
, vif
->fw_vif_idx
,
861 (test_bit(CONNECTED
, &vif
->flags
) ?
862 ALL_BUT_BSS_FILTER
: ALL_BSS_FILTER
), 0);
864 ath6kl_err("couldn't set bss filtering\n");
869 if (request
->n_ssids
&& request
->ssids
[0].ssid_len
) {
872 if (request
->n_ssids
> (MAX_PROBED_SSID_INDEX
- 1))
873 request
->n_ssids
= MAX_PROBED_SSID_INDEX
- 1;
875 for (i
= 0; i
< request
->n_ssids
; i
++)
876 ath6kl_wmi_probedssid_cmd(ar
->wmi
, vif
->fw_vif_idx
,
877 i
+ 1, SPECIFIC_SSID_FLAG
,
878 request
->ssids
[i
].ssid_len
,
879 request
->ssids
[i
].ssid
);
883 * FIXME: we should clear the IE in fw if it's not set so just
884 * remove the check altogether
887 ret
= ath6kl_wmi_set_appie_cmd(ar
->wmi
, vif
->fw_vif_idx
,
889 request
->ie
, request
->ie_len
);
891 ath6kl_err("failed to set Probe Request appie for "
898 * Scan only the requested channels if the request specifies a set of
899 * channels. If the list is longer than the target supports, do not
900 * configure the list and instead, scan all available channels.
902 if (request
->n_channels
> 0 &&
903 request
->n_channels
<= WMI_MAX_CHANNELS
) {
906 n_channels
= request
->n_channels
;
908 channels
= kzalloc(n_channels
* sizeof(u16
), GFP_KERNEL
);
909 if (channels
== NULL
) {
910 ath6kl_warn("failed to set scan channels, "
911 "scan all channels");
915 for (i
= 0; i
< n_channels
; i
++)
916 channels
[i
] = request
->channels
[i
]->center_freq
;
919 if (test_bit(CONNECTED
, &vif
->flags
))
922 if (test_bit(ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX
,
923 ar
->fw_capabilities
)) {
925 * If capable of doing P2P mgmt operations using
926 * station interface, send additional information like
927 * supported rates to advertise and xmit rates for
930 ret
= ath6kl_wmi_beginscan_cmd(ar
->wmi
, vif
->fw_vif_idx
,
931 WMI_LONG_SCAN
, force_fg_scan
,
932 false, 0, 0, n_channels
,
933 channels
, request
->no_cck
,
936 ret
= ath6kl_wmi_startscan_cmd(ar
->wmi
, vif
->fw_vif_idx
,
937 WMI_LONG_SCAN
, force_fg_scan
,
938 false, 0, 0, n_channels
,
942 ath6kl_err("wmi_startscan_cmd failed\n");
944 vif
->scan_req
= request
;
951 void ath6kl_cfg80211_scan_complete_event(struct ath6kl_vif
*vif
, bool aborted
)
953 struct ath6kl
*ar
= vif
->ar
;
956 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "%s: status%s\n", __func__
,
957 aborted
? " aborted" : "");
965 if (vif
->scan_req
->n_ssids
&& vif
->scan_req
->ssids
[0].ssid_len
) {
966 for (i
= 0; i
< vif
->scan_req
->n_ssids
; i
++) {
967 ath6kl_wmi_probedssid_cmd(ar
->wmi
, vif
->fw_vif_idx
,
968 i
+ 1, DISABLE_SSID_FLAG
,
974 cfg80211_scan_done(vif
->scan_req
, aborted
);
975 vif
->scan_req
= NULL
;
978 static int ath6kl_cfg80211_add_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
979 u8 key_index
, bool pairwise
,
981 struct key_params
*params
)
983 struct ath6kl
*ar
= ath6kl_priv(ndev
);
984 struct ath6kl_vif
*vif
= netdev_priv(ndev
);
985 struct ath6kl_key
*key
= NULL
;
990 if (!ath6kl_cfg80211_ready(vif
))
993 if (params
->cipher
== CCKM_KRK_CIPHER_SUITE
) {
994 if (params
->key_len
!= WMI_KRK_LEN
)
996 return ath6kl_wmi_add_krk_cmd(ar
->wmi
, vif
->fw_vif_idx
,
1000 if (key_index
> WMI_MAX_KEY_INDEX
) {
1001 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
,
1002 "%s: key index %d out of bounds\n", __func__
,
1007 key
= &vif
->keys
[key_index
];
1008 memset(key
, 0, sizeof(struct ath6kl_key
));
1011 key_usage
= PAIRWISE_USAGE
;
1013 key_usage
= GROUP_USAGE
;
1015 seq_len
= params
->seq_len
;
1016 if (params
->cipher
== WLAN_CIPHER_SUITE_SMS4
&&
1017 seq_len
> ATH6KL_KEY_SEQ_LEN
) {
1018 /* Only first half of the WPI PN is configured */
1019 seq_len
= ATH6KL_KEY_SEQ_LEN
;
1021 if (params
->key_len
> WLAN_MAX_KEY_LEN
||
1022 seq_len
> sizeof(key
->seq
))
1025 key
->key_len
= params
->key_len
;
1026 memcpy(key
->key
, params
->key
, key
->key_len
);
1027 key
->seq_len
= seq_len
;
1028 memcpy(key
->seq
, params
->seq
, key
->seq_len
);
1029 key
->cipher
= params
->cipher
;
1031 switch (key
->cipher
) {
1032 case WLAN_CIPHER_SUITE_WEP40
:
1033 case WLAN_CIPHER_SUITE_WEP104
:
1034 key_type
= WEP_CRYPT
;
1037 case WLAN_CIPHER_SUITE_TKIP
:
1038 key_type
= TKIP_CRYPT
;
1041 case WLAN_CIPHER_SUITE_CCMP
:
1042 key_type
= AES_CRYPT
;
1044 case WLAN_CIPHER_SUITE_SMS4
:
1045 key_type
= WAPI_CRYPT
;
1052 if (((vif
->auth_mode
== WPA_PSK_AUTH
)
1053 || (vif
->auth_mode
== WPA2_PSK_AUTH
))
1054 && (key_usage
& GROUP_USAGE
))
1055 del_timer(&vif
->disconnect_timer
);
1057 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
,
1058 "%s: index %d, key_len %d, key_type 0x%x, key_usage 0x%x, seq_len %d\n",
1059 __func__
, key_index
, key
->key_len
, key_type
,
1060 key_usage
, key
->seq_len
);
1062 if (vif
->nw_type
== AP_NETWORK
&& !pairwise
&&
1063 (key_type
== TKIP_CRYPT
|| key_type
== AES_CRYPT
||
1064 key_type
== WAPI_CRYPT
) && params
) {
1065 ar
->ap_mode_bkey
.valid
= true;
1066 ar
->ap_mode_bkey
.key_index
= key_index
;
1067 ar
->ap_mode_bkey
.key_type
= key_type
;
1068 ar
->ap_mode_bkey
.key_len
= key
->key_len
;
1069 memcpy(ar
->ap_mode_bkey
.key
, key
->key
, key
->key_len
);
1070 if (!test_bit(CONNECTED
, &vif
->flags
)) {
1071 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "Delay initial group "
1072 "key configuration until AP mode has been "
1075 * The key will be set in ath6kl_connect_ap_mode() once
1076 * the connected event is received from the target.
1082 if (vif
->next_mode
== AP_NETWORK
&& key_type
== WEP_CRYPT
&&
1083 !test_bit(CONNECTED
, &vif
->flags
)) {
1085 * Store the key locally so that it can be re-configured after
1086 * the AP mode has properly started
1087 * (ath6kl_install_statioc_wep_keys).
1089 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "Delay WEP key configuration "
1090 "until AP mode has been started\n");
1091 vif
->wep_key_list
[key_index
].key_len
= key
->key_len
;
1092 memcpy(vif
->wep_key_list
[key_index
].key
, key
->key
,
1097 return ath6kl_wmi_addkey_cmd(ar
->wmi
, vif
->fw_vif_idx
, key_index
,
1098 key_type
, key_usage
, key
->key_len
,
1099 key
->seq
, key
->seq_len
, key
->key
,
1101 (u8
*) mac_addr
, SYNC_BOTH_WMIFLAG
);
1104 static int ath6kl_cfg80211_del_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
1105 u8 key_index
, bool pairwise
,
1108 struct ath6kl
*ar
= ath6kl_priv(ndev
);
1109 struct ath6kl_vif
*vif
= netdev_priv(ndev
);
1111 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "%s: index %d\n", __func__
, key_index
);
1113 if (!ath6kl_cfg80211_ready(vif
))
1116 if (key_index
> WMI_MAX_KEY_INDEX
) {
1117 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
,
1118 "%s: key index %d out of bounds\n", __func__
,
1123 if (!vif
->keys
[key_index
].key_len
) {
1124 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
,
1125 "%s: index %d is empty\n", __func__
, key_index
);
1129 vif
->keys
[key_index
].key_len
= 0;
1131 return ath6kl_wmi_deletekey_cmd(ar
->wmi
, vif
->fw_vif_idx
, key_index
);
1134 static int ath6kl_cfg80211_get_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
1135 u8 key_index
, bool pairwise
,
1136 const u8
*mac_addr
, void *cookie
,
1137 void (*callback
) (void *cookie
,
1138 struct key_params
*))
1140 struct ath6kl_vif
*vif
= netdev_priv(ndev
);
1141 struct ath6kl_key
*key
= NULL
;
1142 struct key_params params
;
1144 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "%s: index %d\n", __func__
, key_index
);
1146 if (!ath6kl_cfg80211_ready(vif
))
1149 if (key_index
> WMI_MAX_KEY_INDEX
) {
1150 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
,
1151 "%s: key index %d out of bounds\n", __func__
,
1156 key
= &vif
->keys
[key_index
];
1157 memset(¶ms
, 0, sizeof(params
));
1158 params
.cipher
= key
->cipher
;
1159 params
.key_len
= key
->key_len
;
1160 params
.seq_len
= key
->seq_len
;
1161 params
.seq
= key
->seq
;
1162 params
.key
= key
->key
;
1164 callback(cookie
, ¶ms
);
1166 return key
->key_len
? 0 : -ENOENT
;
1169 static int ath6kl_cfg80211_set_default_key(struct wiphy
*wiphy
,
1170 struct net_device
*ndev
,
1171 u8 key_index
, bool unicast
,
1174 struct ath6kl
*ar
= ath6kl_priv(ndev
);
1175 struct ath6kl_vif
*vif
= netdev_priv(ndev
);
1176 struct ath6kl_key
*key
= NULL
;
1178 enum crypto_type key_type
= NONE_CRYPT
;
1180 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "%s: index %d\n", __func__
, key_index
);
1182 if (!ath6kl_cfg80211_ready(vif
))
1185 if (key_index
> WMI_MAX_KEY_INDEX
) {
1186 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
,
1187 "%s: key index %d out of bounds\n",
1188 __func__
, key_index
);
1192 if (!vif
->keys
[key_index
].key_len
) {
1193 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "%s: invalid key index %d\n",
1194 __func__
, key_index
);
1198 vif
->def_txkey_index
= key_index
;
1199 key
= &vif
->keys
[vif
->def_txkey_index
];
1200 key_usage
= GROUP_USAGE
;
1201 if (vif
->prwise_crypto
== WEP_CRYPT
)
1202 key_usage
|= TX_USAGE
;
1204 key_type
= vif
->prwise_crypto
;
1206 key_type
= vif
->grp_crypto
;
1208 if (vif
->next_mode
== AP_NETWORK
&& !test_bit(CONNECTED
, &vif
->flags
))
1209 return 0; /* Delay until AP mode has been started */
1211 return ath6kl_wmi_addkey_cmd(ar
->wmi
, vif
->fw_vif_idx
,
1212 vif
->def_txkey_index
,
1213 key_type
, key_usage
,
1214 key
->key_len
, key
->seq
, key
->seq_len
,
1216 KEY_OP_INIT_VAL
, NULL
,
1220 void ath6kl_cfg80211_tkip_micerr_event(struct ath6kl_vif
*vif
, u8 keyid
,
1223 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
,
1224 "%s: keyid %d, ismcast %d\n", __func__
, keyid
, ismcast
);
1226 cfg80211_michael_mic_failure(vif
->ndev
, vif
->bssid
,
1227 (ismcast
? NL80211_KEYTYPE_GROUP
:
1228 NL80211_KEYTYPE_PAIRWISE
), keyid
, NULL
,
1232 static int ath6kl_cfg80211_set_wiphy_params(struct wiphy
*wiphy
, u32 changed
)
1234 struct ath6kl
*ar
= (struct ath6kl
*)wiphy_priv(wiphy
);
1235 struct ath6kl_vif
*vif
;
1238 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "%s: changed 0x%x\n", __func__
,
1241 vif
= ath6kl_vif_first(ar
);
1245 if (!ath6kl_cfg80211_ready(vif
))
1248 if (changed
& WIPHY_PARAM_RTS_THRESHOLD
) {
1249 ret
= ath6kl_wmi_set_rts_cmd(ar
->wmi
, wiphy
->rts_threshold
);
1251 ath6kl_err("ath6kl_wmi_set_rts_cmd failed\n");
1260 * The type nl80211_tx_power_setting replaces the following
1261 * data type from 2.6.36 onwards
1263 static int ath6kl_cfg80211_set_txpower(struct wiphy
*wiphy
,
1264 enum nl80211_tx_power_setting type
,
1267 struct ath6kl
*ar
= (struct ath6kl
*)wiphy_priv(wiphy
);
1268 struct ath6kl_vif
*vif
;
1270 int dbm
= MBM_TO_DBM(mbm
);
1272 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "%s: type 0x%x, dbm %d\n", __func__
,
1275 vif
= ath6kl_vif_first(ar
);
1279 if (!ath6kl_cfg80211_ready(vif
))
1283 case NL80211_TX_POWER_AUTOMATIC
:
1285 case NL80211_TX_POWER_LIMITED
:
1286 ar
->tx_pwr
= ath6kl_dbm
= dbm
;
1289 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "%s: type 0x%x not supported\n",
1294 ath6kl_wmi_set_tx_pwr_cmd(ar
->wmi
, vif
->fw_vif_idx
, ath6kl_dbm
);
1299 static int ath6kl_cfg80211_get_txpower(struct wiphy
*wiphy
, int *dbm
)
1301 struct ath6kl
*ar
= (struct ath6kl
*)wiphy_priv(wiphy
);
1302 struct ath6kl_vif
*vif
;
1304 vif
= ath6kl_vif_first(ar
);
1308 if (!ath6kl_cfg80211_ready(vif
))
1311 if (test_bit(CONNECTED
, &vif
->flags
)) {
1314 if (ath6kl_wmi_get_tx_pwr_cmd(ar
->wmi
, vif
->fw_vif_idx
) != 0) {
1315 ath6kl_err("ath6kl_wmi_get_tx_pwr_cmd failed\n");
1319 wait_event_interruptible_timeout(ar
->event_wq
, ar
->tx_pwr
!= 0,
1322 if (signal_pending(current
)) {
1323 ath6kl_err("target did not respond\n");
1332 static int ath6kl_cfg80211_set_power_mgmt(struct wiphy
*wiphy
,
1333 struct net_device
*dev
,
1334 bool pmgmt
, int timeout
)
1336 struct ath6kl
*ar
= ath6kl_priv(dev
);
1337 struct wmi_power_mode_cmd mode
;
1338 struct ath6kl_vif
*vif
= netdev_priv(dev
);
1340 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "%s: pmgmt %d, timeout %d\n",
1341 __func__
, pmgmt
, timeout
);
1343 if (!ath6kl_cfg80211_ready(vif
))
1347 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "%s: max perf\n", __func__
);
1348 mode
.pwr_mode
= REC_POWER
;
1350 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "%s: rec power\n", __func__
);
1351 mode
.pwr_mode
= MAX_PERF_POWER
;
1354 if (ath6kl_wmi_powermode_cmd(ar
->wmi
, vif
->fw_vif_idx
,
1355 mode
.pwr_mode
) != 0) {
1356 ath6kl_err("wmi_powermode_cmd failed\n");
1363 static struct net_device
*ath6kl_cfg80211_add_iface(struct wiphy
*wiphy
,
1365 enum nl80211_iftype type
,
1367 struct vif_params
*params
)
1369 struct ath6kl
*ar
= wiphy_priv(wiphy
);
1370 struct net_device
*ndev
;
1373 if (ar
->num_vif
== ar
->vif_max
) {
1374 ath6kl_err("Reached maximum number of supported vif\n");
1375 return ERR_PTR(-EINVAL
);
1378 if (!ath6kl_is_valid_iftype(ar
, type
, &if_idx
, &nw_type
)) {
1379 ath6kl_err("Not a supported interface type\n");
1380 return ERR_PTR(-EINVAL
);
1383 ndev
= ath6kl_interface_add(ar
, name
, type
, if_idx
, nw_type
);
1385 return ERR_PTR(-ENOMEM
);
1392 static int ath6kl_cfg80211_del_iface(struct wiphy
*wiphy
,
1393 struct net_device
*ndev
)
1395 struct ath6kl
*ar
= wiphy_priv(wiphy
);
1396 struct ath6kl_vif
*vif
= netdev_priv(ndev
);
1398 spin_lock_bh(&ar
->list_lock
);
1399 list_del(&vif
->list
);
1400 spin_unlock_bh(&ar
->list_lock
);
1402 ath6kl_cleanup_vif(vif
, test_bit(WMI_READY
, &ar
->flag
));
1404 ath6kl_cfg80211_vif_cleanup(vif
);
1409 static int ath6kl_cfg80211_change_iface(struct wiphy
*wiphy
,
1410 struct net_device
*ndev
,
1411 enum nl80211_iftype type
, u32
*flags
,
1412 struct vif_params
*params
)
1414 struct ath6kl_vif
*vif
= netdev_priv(ndev
);
1416 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "%s: type %u\n", __func__
, type
);
1419 case NL80211_IFTYPE_STATION
:
1420 vif
->next_mode
= INFRA_NETWORK
;
1422 case NL80211_IFTYPE_ADHOC
:
1423 vif
->next_mode
= ADHOC_NETWORK
;
1425 case NL80211_IFTYPE_AP
:
1426 vif
->next_mode
= AP_NETWORK
;
1428 case NL80211_IFTYPE_P2P_CLIENT
:
1429 vif
->next_mode
= INFRA_NETWORK
;
1431 case NL80211_IFTYPE_P2P_GO
:
1432 vif
->next_mode
= AP_NETWORK
;
1435 ath6kl_err("invalid interface type %u\n", type
);
1439 vif
->wdev
.iftype
= type
;
1444 static int ath6kl_cfg80211_join_ibss(struct wiphy
*wiphy
,
1445 struct net_device
*dev
,
1446 struct cfg80211_ibss_params
*ibss_param
)
1448 struct ath6kl
*ar
= ath6kl_priv(dev
);
1449 struct ath6kl_vif
*vif
= netdev_priv(dev
);
1452 if (!ath6kl_cfg80211_ready(vif
))
1455 vif
->ssid_len
= ibss_param
->ssid_len
;
1456 memcpy(vif
->ssid
, ibss_param
->ssid
, vif
->ssid_len
);
1458 if (ibss_param
->channel
)
1459 vif
->ch_hint
= ibss_param
->channel
->center_freq
;
1461 if (ibss_param
->channel_fixed
) {
1463 * TODO: channel_fixed: The channel should be fixed, do not
1464 * search for IBSSs to join on other channels. Target
1465 * firmware does not support this feature, needs to be
1471 memset(vif
->req_bssid
, 0, sizeof(vif
->req_bssid
));
1472 if (ibss_param
->bssid
&& !is_broadcast_ether_addr(ibss_param
->bssid
))
1473 memcpy(vif
->req_bssid
, ibss_param
->bssid
,
1474 sizeof(vif
->req_bssid
));
1476 ath6kl_set_wpa_version(vif
, 0);
1478 status
= ath6kl_set_auth_type(vif
, NL80211_AUTHTYPE_OPEN_SYSTEM
);
1482 if (ibss_param
->privacy
) {
1483 ath6kl_set_cipher(vif
, WLAN_CIPHER_SUITE_WEP40
, true);
1484 ath6kl_set_cipher(vif
, WLAN_CIPHER_SUITE_WEP40
, false);
1486 ath6kl_set_cipher(vif
, 0, true);
1487 ath6kl_set_cipher(vif
, 0, false);
1490 vif
->nw_type
= vif
->next_mode
;
1492 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
,
1493 "%s: connect called with authmode %d dot11 auth %d"
1494 " PW crypto %d PW crypto len %d GRP crypto %d"
1495 " GRP crypto len %d channel hint %u\n",
1497 vif
->auth_mode
, vif
->dot11_auth_mode
, vif
->prwise_crypto
,
1498 vif
->prwise_crypto_len
, vif
->grp_crypto
,
1499 vif
->grp_crypto_len
, vif
->ch_hint
);
1501 status
= ath6kl_wmi_connect_cmd(ar
->wmi
, vif
->fw_vif_idx
, vif
->nw_type
,
1502 vif
->dot11_auth_mode
, vif
->auth_mode
,
1504 vif
->prwise_crypto_len
,
1505 vif
->grp_crypto
, vif
->grp_crypto_len
,
1506 vif
->ssid_len
, vif
->ssid
,
1507 vif
->req_bssid
, vif
->ch_hint
,
1508 ar
->connect_ctrl_flags
, SUBTYPE_NONE
);
1509 set_bit(CONNECT_PEND
, &vif
->flags
);
1514 static int ath6kl_cfg80211_leave_ibss(struct wiphy
*wiphy
,
1515 struct net_device
*dev
)
1517 struct ath6kl_vif
*vif
= netdev_priv(dev
);
1519 if (!ath6kl_cfg80211_ready(vif
))
1522 ath6kl_disconnect(vif
);
1523 memset(vif
->ssid
, 0, sizeof(vif
->ssid
));
1529 static const u32 cipher_suites
[] = {
1530 WLAN_CIPHER_SUITE_WEP40
,
1531 WLAN_CIPHER_SUITE_WEP104
,
1532 WLAN_CIPHER_SUITE_TKIP
,
1533 WLAN_CIPHER_SUITE_CCMP
,
1534 CCKM_KRK_CIPHER_SUITE
,
1535 WLAN_CIPHER_SUITE_SMS4
,
1538 static bool is_rate_legacy(s32 rate
)
1540 static const s32 legacy
[] = { 1000, 2000, 5500, 11000,
1541 6000, 9000, 12000, 18000, 24000,
1546 for (i
= 0; i
< ARRAY_SIZE(legacy
); i
++)
1547 if (rate
== legacy
[i
])
1553 static bool is_rate_ht20(s32 rate
, u8
*mcs
, bool *sgi
)
1555 static const s32 ht20
[] = { 6500, 13000, 19500, 26000, 39000,
1556 52000, 58500, 65000, 72200
1560 for (i
= 0; i
< ARRAY_SIZE(ht20
); i
++) {
1561 if (rate
== ht20
[i
]) {
1562 if (i
== ARRAY_SIZE(ht20
) - 1)
1563 /* last rate uses sgi */
1575 static bool is_rate_ht40(s32 rate
, u8
*mcs
, bool *sgi
)
1577 static const s32 ht40
[] = { 13500, 27000, 40500, 54000,
1578 81000, 108000, 121500, 135000,
1583 for (i
= 0; i
< ARRAY_SIZE(ht40
); i
++) {
1584 if (rate
== ht40
[i
]) {
1585 if (i
== ARRAY_SIZE(ht40
) - 1)
1586 /* last rate uses sgi */
1599 static int ath6kl_get_station(struct wiphy
*wiphy
, struct net_device
*dev
,
1600 u8
*mac
, struct station_info
*sinfo
)
1602 struct ath6kl
*ar
= ath6kl_priv(dev
);
1603 struct ath6kl_vif
*vif
= netdev_priv(dev
);
1610 if (memcmp(mac
, vif
->bssid
, ETH_ALEN
) != 0)
1613 if (down_interruptible(&ar
->sem
))
1616 set_bit(STATS_UPDATE_PEND
, &vif
->flags
);
1618 ret
= ath6kl_wmi_get_stats_cmd(ar
->wmi
, vif
->fw_vif_idx
);
1625 left
= wait_event_interruptible_timeout(ar
->event_wq
,
1626 !test_bit(STATS_UPDATE_PEND
,
1637 if (vif
->target_stats
.rx_byte
) {
1638 sinfo
->rx_bytes
= vif
->target_stats
.rx_byte
;
1639 sinfo
->filled
|= STATION_INFO_RX_BYTES
;
1640 sinfo
->rx_packets
= vif
->target_stats
.rx_pkt
;
1641 sinfo
->filled
|= STATION_INFO_RX_PACKETS
;
1644 if (vif
->target_stats
.tx_byte
) {
1645 sinfo
->tx_bytes
= vif
->target_stats
.tx_byte
;
1646 sinfo
->filled
|= STATION_INFO_TX_BYTES
;
1647 sinfo
->tx_packets
= vif
->target_stats
.tx_pkt
;
1648 sinfo
->filled
|= STATION_INFO_TX_PACKETS
;
1651 sinfo
->signal
= vif
->target_stats
.cs_rssi
;
1652 sinfo
->filled
|= STATION_INFO_SIGNAL
;
1654 rate
= vif
->target_stats
.tx_ucast_rate
;
1656 if (is_rate_legacy(rate
)) {
1657 sinfo
->txrate
.legacy
= rate
/ 100;
1658 } else if (is_rate_ht20(rate
, &mcs
, &sgi
)) {
1660 sinfo
->txrate
.flags
|= RATE_INFO_FLAGS_SHORT_GI
;
1661 sinfo
->txrate
.mcs
= mcs
- 1;
1663 sinfo
->txrate
.mcs
= mcs
;
1666 sinfo
->txrate
.flags
|= RATE_INFO_FLAGS_MCS
;
1667 } else if (is_rate_ht40(rate
, &mcs
, &sgi
)) {
1669 sinfo
->txrate
.flags
|= RATE_INFO_FLAGS_SHORT_GI
;
1670 sinfo
->txrate
.mcs
= mcs
- 1;
1672 sinfo
->txrate
.mcs
= mcs
;
1675 sinfo
->txrate
.flags
|= RATE_INFO_FLAGS_40_MHZ_WIDTH
;
1676 sinfo
->txrate
.flags
|= RATE_INFO_FLAGS_MCS
;
1678 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
,
1679 "invalid rate from stats: %d\n", rate
);
1680 ath6kl_debug_war(ar
, ATH6KL_WAR_INVALID_RATE
);
1684 sinfo
->filled
|= STATION_INFO_TX_BITRATE
;
1686 if (test_bit(CONNECTED
, &vif
->flags
) &&
1687 test_bit(DTIM_PERIOD_AVAIL
, &vif
->flags
) &&
1688 vif
->nw_type
== INFRA_NETWORK
) {
1689 sinfo
->filled
|= STATION_INFO_BSS_PARAM
;
1690 sinfo
->bss_param
.flags
= 0;
1691 sinfo
->bss_param
.dtim_period
= vif
->assoc_bss_dtim_period
;
1692 sinfo
->bss_param
.beacon_interval
= vif
->assoc_bss_beacon_int
;
1698 static int ath6kl_set_pmksa(struct wiphy
*wiphy
, struct net_device
*netdev
,
1699 struct cfg80211_pmksa
*pmksa
)
1701 struct ath6kl
*ar
= ath6kl_priv(netdev
);
1702 struct ath6kl_vif
*vif
= netdev_priv(netdev
);
1704 return ath6kl_wmi_setpmkid_cmd(ar
->wmi
, vif
->fw_vif_idx
, pmksa
->bssid
,
1705 pmksa
->pmkid
, true);
1708 static int ath6kl_del_pmksa(struct wiphy
*wiphy
, struct net_device
*netdev
,
1709 struct cfg80211_pmksa
*pmksa
)
1711 struct ath6kl
*ar
= ath6kl_priv(netdev
);
1712 struct ath6kl_vif
*vif
= netdev_priv(netdev
);
1714 return ath6kl_wmi_setpmkid_cmd(ar
->wmi
, vif
->fw_vif_idx
, pmksa
->bssid
,
1715 pmksa
->pmkid
, false);
1718 static int ath6kl_flush_pmksa(struct wiphy
*wiphy
, struct net_device
*netdev
)
1720 struct ath6kl
*ar
= ath6kl_priv(netdev
);
1721 struct ath6kl_vif
*vif
= netdev_priv(netdev
);
1723 if (test_bit(CONNECTED
, &vif
->flags
))
1724 return ath6kl_wmi_setpmkid_cmd(ar
->wmi
, vif
->fw_vif_idx
,
1725 vif
->bssid
, NULL
, false);
1729 static int ath6kl_wow_suspend(struct ath6kl
*ar
, struct cfg80211_wowlan
*wow
)
1731 struct in_device
*in_dev
;
1732 struct in_ifaddr
*ifa
;
1733 struct ath6kl_vif
*vif
;
1737 u8 mask
[WOW_MASK_SIZE
], index
= 0;
1738 __be32 ips
[MAX_IP_ADDRS
];
1740 vif
= ath6kl_vif_first(ar
);
1744 if (!ath6kl_cfg80211_ready(vif
))
1747 if (!test_bit(CONNECTED
, &vif
->flags
))
1750 /* Clear existing WOW patterns */
1751 for (i
= 0; i
< WOW_MAX_FILTERS_PER_LIST
; i
++)
1752 ath6kl_wmi_del_wow_pattern_cmd(ar
->wmi
, vif
->fw_vif_idx
,
1754 /* Configure new WOW patterns */
1755 for (i
= 0; i
< wow
->n_patterns
; i
++) {
1758 * Convert given nl80211 specific mask value to equivalent
1759 * driver specific mask value and send it to the chip along
1760 * with patterns. For example, If the mask value defined in
1761 * struct cfg80211_wowlan is 0xA (equivalent binary is 1010),
1762 * then equivalent driver specific mask value is
1763 * "0xFF 0x00 0xFF 0x00".
1765 memset(&mask
, 0, sizeof(mask
));
1766 for (pos
= 0; pos
< wow
->patterns
[i
].pattern_len
; pos
++) {
1767 if (wow
->patterns
[i
].mask
[pos
/ 8] & (0x1 << (pos
% 8)))
1771 * Note: Pattern's offset is not passed as part of wowlan
1772 * parameter from CFG layer. So it's always passed as ZERO
1773 * to the firmware. It means, given WOW patterns are always
1774 * matched from the first byte of received pkt in the firmware.
1776 ret
= ath6kl_wmi_add_wow_pattern_cmd(ar
->wmi
,
1777 vif
->fw_vif_idx
, WOW_LIST_ID
,
1778 wow
->patterns
[i
].pattern_len
,
1779 0 /* pattern offset */,
1780 wow
->patterns
[i
].pattern
, mask
);
1785 /* Setup own IP addr for ARP agent. */
1786 in_dev
= __in_dev_get_rtnl(vif
->ndev
);
1790 ifa
= in_dev
->ifa_list
;
1791 memset(&ips
, 0, sizeof(ips
));
1793 /* Configure IP addr only if IP address count < MAX_IP_ADDRS */
1794 while (index
< MAX_IP_ADDRS
&& ifa
) {
1795 ips
[index
] = ifa
->ifa_local
;
1796 ifa
= ifa
->ifa_next
;
1801 ath6kl_err("total IP addr count is exceeding fw limit\n");
1805 ret
= ath6kl_wmi_set_ip_cmd(ar
->wmi
, vif
->fw_vif_idx
, ips
[0], ips
[1]);
1807 ath6kl_err("fail to setup ip for arp agent\n");
1812 if (wow
->disconnect
)
1813 filter
|= WOW_FILTER_OPTION_NWK_DISASSOC
;
1816 filter
|= WOW_FILTER_OPTION_MAGIC_PACKET
;
1818 if (wow
->gtk_rekey_failure
)
1819 filter
|= WOW_FILTER_OPTION_GTK_ERROR
;
1821 if (wow
->eap_identity_req
)
1822 filter
|= WOW_FILTER_OPTION_EAP_REQ
;
1824 if (wow
->four_way_handshake
)
1825 filter
|= WOW_FILTER_OPTION_8021X_4WAYHS
;
1827 ret
= ath6kl_wmi_set_wow_mode_cmd(ar
->wmi
, vif
->fw_vif_idx
,
1828 ATH6KL_WOW_MODE_ENABLE
,
1830 WOW_HOST_REQ_DELAY
);
1834 ret
= ath6kl_wmi_set_host_sleep_mode_cmd(ar
->wmi
, vif
->fw_vif_idx
,
1835 ATH6KL_HOST_MODE_ASLEEP
);
1839 if (ar
->tx_pending
[ar
->ctrl_ep
]) {
1840 left
= wait_event_interruptible_timeout(ar
->event_wq
,
1841 ar
->tx_pending
[ar
->ctrl_ep
] == 0, WMI_TIMEOUT
);
1843 ath6kl_warn("clear wmi ctrl data timeout\n");
1845 } else if (left
< 0) {
1846 ath6kl_warn("clear wmi ctrl data failed: %d\n", left
);
1854 static int ath6kl_wow_resume(struct ath6kl
*ar
)
1856 struct ath6kl_vif
*vif
;
1859 vif
= ath6kl_vif_first(ar
);
1863 ret
= ath6kl_wmi_set_host_sleep_mode_cmd(ar
->wmi
, vif
->fw_vif_idx
,
1864 ATH6KL_HOST_MODE_AWAKE
);
1868 int ath6kl_cfg80211_suspend(struct ath6kl
*ar
,
1869 enum ath6kl_cfg_suspend_mode mode
,
1870 struct cfg80211_wowlan
*wow
)
1875 case ATH6KL_CFG_SUSPEND_WOW
:
1877 ath6kl_dbg(ATH6KL_DBG_SUSPEND
, "wow mode suspend\n");
1879 /* Flush all non control pkts in TX path */
1880 ath6kl_tx_data_cleanup(ar
);
1882 ret
= ath6kl_wow_suspend(ar
, wow
);
1884 ath6kl_err("wow suspend failed: %d\n", ret
);
1887 ar
->state
= ATH6KL_STATE_WOW
;
1890 case ATH6KL_CFG_SUSPEND_DEEPSLEEP
:
1892 ath6kl_cfg80211_stop_all(ar
);
1894 /* save the current power mode before enabling power save */
1895 ar
->wmi
->saved_pwr_mode
= ar
->wmi
->pwr_mode
;
1897 ret
= ath6kl_wmi_powermode_cmd(ar
->wmi
, 0, REC_POWER
);
1899 ath6kl_warn("wmi powermode command failed during suspend: %d\n",
1903 ar
->state
= ATH6KL_STATE_DEEPSLEEP
;
1907 case ATH6KL_CFG_SUSPEND_CUTPOWER
:
1909 ath6kl_cfg80211_stop_all(ar
);
1911 if (ar
->state
== ATH6KL_STATE_OFF
) {
1912 ath6kl_dbg(ATH6KL_DBG_SUSPEND
,
1913 "suspend hw off, no action for cutpower\n");
1917 ath6kl_dbg(ATH6KL_DBG_SUSPEND
, "suspend cutting power\n");
1919 ret
= ath6kl_init_hw_stop(ar
);
1921 ath6kl_warn("failed to stop hw during suspend: %d\n",
1925 ar
->state
= ATH6KL_STATE_CUTPOWER
;
1929 case ATH6KL_CFG_SUSPEND_SCHED_SCAN
:
1931 * Nothing needed for schedule scan, firmware is already in
1932 * wow mode and sleeping most of the time.
1943 int ath6kl_cfg80211_resume(struct ath6kl
*ar
)
1947 switch (ar
->state
) {
1948 case ATH6KL_STATE_WOW
:
1949 ath6kl_dbg(ATH6KL_DBG_SUSPEND
, "wow mode resume\n");
1951 ret
= ath6kl_wow_resume(ar
);
1953 ath6kl_warn("wow mode resume failed: %d\n", ret
);
1957 ar
->state
= ATH6KL_STATE_ON
;
1960 case ATH6KL_STATE_DEEPSLEEP
:
1961 if (ar
->wmi
->pwr_mode
!= ar
->wmi
->saved_pwr_mode
) {
1962 ret
= ath6kl_wmi_powermode_cmd(ar
->wmi
, 0,
1963 ar
->wmi
->saved_pwr_mode
);
1965 ath6kl_warn("wmi powermode command failed during resume: %d\n",
1970 ar
->state
= ATH6KL_STATE_ON
;
1974 case ATH6KL_STATE_CUTPOWER
:
1975 ath6kl_dbg(ATH6KL_DBG_SUSPEND
, "resume restoring power\n");
1977 ret
= ath6kl_init_hw_start(ar
);
1979 ath6kl_warn("Failed to boot hw in resume: %d\n", ret
);
1984 case ATH6KL_STATE_SCHED_SCAN
:
1996 /* hif layer decides what suspend mode to use */
1997 static int __ath6kl_cfg80211_suspend(struct wiphy
*wiphy
,
1998 struct cfg80211_wowlan
*wow
)
2000 struct ath6kl
*ar
= wiphy_priv(wiphy
);
2002 return ath6kl_hif_suspend(ar
, wow
);
2005 static int __ath6kl_cfg80211_resume(struct wiphy
*wiphy
)
2007 struct ath6kl
*ar
= wiphy_priv(wiphy
);
2009 return ath6kl_hif_resume(ar
);
2013 * FIXME: WOW suspend mode is selected if the host sdio controller supports
2014 * both sdio irq wake up and keep power. The target pulls sdio data line to
2015 * wake up the host when WOW pattern matches. This causes sdio irq handler
2016 * is being called in the host side which internally hits ath6kl's RX path.
2018 * Since sdio interrupt is not disabled, RX path executes even before
2019 * the host executes the actual resume operation from PM module.
2021 * In the current scenario, WOW resume should happen before start processing
2022 * any data from the target. So It's required to perform WOW resume in RX path.
2023 * Ideally we should perform WOW resume only in the actual platform
2024 * resume path. This area needs bit rework to avoid WOW resume in RX path.
2026 * ath6kl_check_wow_status() is called from ath6kl_rx().
2028 void ath6kl_check_wow_status(struct ath6kl
*ar
)
2030 if (ar
->state
== ATH6KL_STATE_WOW
)
2031 ath6kl_cfg80211_resume(ar
);
2036 void ath6kl_check_wow_status(struct ath6kl
*ar
)
2041 static int ath6kl_set_channel(struct wiphy
*wiphy
, struct net_device
*dev
,
2042 struct ieee80211_channel
*chan
,
2043 enum nl80211_channel_type channel_type
)
2045 struct ath6kl_vif
*vif
;
2048 * 'dev' could be NULL if a channel change is required for the hardware
2049 * device itself, instead of a particular VIF.
2051 * FIXME: To be handled properly when monitor mode is supported.
2056 vif
= netdev_priv(dev
);
2058 if (!ath6kl_cfg80211_ready(vif
))
2061 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "%s: center_freq=%u hw_value=%u\n",
2062 __func__
, chan
->center_freq
, chan
->hw_value
);
2063 vif
->next_chan
= chan
->center_freq
;
2068 static bool ath6kl_is_p2p_ie(const u8
*pos
)
2070 return pos
[0] == WLAN_EID_VENDOR_SPECIFIC
&& pos
[1] >= 4 &&
2071 pos
[2] == 0x50 && pos
[3] == 0x6f &&
2072 pos
[4] == 0x9a && pos
[5] == 0x09;
2075 static int ath6kl_set_ap_probe_resp_ies(struct ath6kl_vif
*vif
,
2076 const u8
*ies
, size_t ies_len
)
2078 struct ath6kl
*ar
= vif
->ar
;
2085 * Filter out P2P IE(s) since they will be included depending on
2086 * the Probe Request frame in ath6kl_send_go_probe_resp().
2089 if (ies
&& ies_len
) {
2090 buf
= kmalloc(ies_len
, GFP_KERNEL
);
2094 while (pos
+ 1 < ies
+ ies_len
) {
2095 if (pos
+ 2 + pos
[1] > ies
+ ies_len
)
2097 if (!ath6kl_is_p2p_ie(pos
)) {
2098 memcpy(buf
+ len
, pos
, 2 + pos
[1]);
2105 ret
= ath6kl_wmi_set_appie_cmd(ar
->wmi
, vif
->fw_vif_idx
,
2106 WMI_FRAME_PROBE_RESP
, buf
, len
);
2111 static int ath6kl_ap_beacon(struct wiphy
*wiphy
, struct net_device
*dev
,
2112 struct beacon_parameters
*info
, bool add
)
2114 struct ath6kl
*ar
= ath6kl_priv(dev
);
2115 struct ath6kl_vif
*vif
= netdev_priv(dev
);
2116 struct ieee80211_mgmt
*mgmt
;
2119 struct wmi_connect_cmd p
;
2123 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "%s: add=%d\n", __func__
, add
);
2125 if (!ath6kl_cfg80211_ready(vif
))
2128 if (vif
->next_mode
!= AP_NETWORK
)
2131 if (info
->beacon_ies
) {
2132 res
= ath6kl_wmi_set_appie_cmd(ar
->wmi
, vif
->fw_vif_idx
,
2135 info
->beacon_ies_len
);
2139 if (info
->proberesp_ies
) {
2140 res
= ath6kl_set_ap_probe_resp_ies(vif
, info
->proberesp_ies
,
2141 info
->proberesp_ies_len
);
2145 if (info
->assocresp_ies
) {
2146 res
= ath6kl_wmi_set_appie_cmd(ar
->wmi
, vif
->fw_vif_idx
,
2147 WMI_FRAME_ASSOC_RESP
,
2148 info
->assocresp_ies
,
2149 info
->assocresp_ies_len
);
2157 ar
->ap_mode_bkey
.valid
= false;
2164 if (info
->head
== NULL
)
2166 mgmt
= (struct ieee80211_mgmt
*) info
->head
;
2167 ies
= mgmt
->u
.beacon
.variable
;
2168 if (ies
> info
->head
+ info
->head_len
)
2170 ies_len
= info
->head
+ info
->head_len
- ies
;
2172 if (info
->ssid
== NULL
)
2174 memcpy(vif
->ssid
, info
->ssid
, info
->ssid_len
);
2175 vif
->ssid_len
= info
->ssid_len
;
2176 if (info
->hidden_ssid
!= NL80211_HIDDEN_SSID_NOT_IN_USE
)
2177 return -EOPNOTSUPP
; /* TODO */
2179 ret
= ath6kl_set_auth_type(vif
, info
->auth_type
);
2183 memset(&p
, 0, sizeof(p
));
2185 for (i
= 0; i
< info
->crypto
.n_akm_suites
; i
++) {
2186 switch (info
->crypto
.akm_suites
[i
]) {
2187 case WLAN_AKM_SUITE_8021X
:
2188 if (info
->crypto
.wpa_versions
& NL80211_WPA_VERSION_1
)
2189 p
.auth_mode
|= WPA_AUTH
;
2190 if (info
->crypto
.wpa_versions
& NL80211_WPA_VERSION_2
)
2191 p
.auth_mode
|= WPA2_AUTH
;
2193 case WLAN_AKM_SUITE_PSK
:
2194 if (info
->crypto
.wpa_versions
& NL80211_WPA_VERSION_1
)
2195 p
.auth_mode
|= WPA_PSK_AUTH
;
2196 if (info
->crypto
.wpa_versions
& NL80211_WPA_VERSION_2
)
2197 p
.auth_mode
|= WPA2_PSK_AUTH
;
2201 if (p
.auth_mode
== 0)
2202 p
.auth_mode
= NONE_AUTH
;
2203 vif
->auth_mode
= p
.auth_mode
;
2205 for (i
= 0; i
< info
->crypto
.n_ciphers_pairwise
; i
++) {
2206 switch (info
->crypto
.ciphers_pairwise
[i
]) {
2207 case WLAN_CIPHER_SUITE_WEP40
:
2208 case WLAN_CIPHER_SUITE_WEP104
:
2209 p
.prwise_crypto_type
|= WEP_CRYPT
;
2211 case WLAN_CIPHER_SUITE_TKIP
:
2212 p
.prwise_crypto_type
|= TKIP_CRYPT
;
2214 case WLAN_CIPHER_SUITE_CCMP
:
2215 p
.prwise_crypto_type
|= AES_CRYPT
;
2217 case WLAN_CIPHER_SUITE_SMS4
:
2218 p
.prwise_crypto_type
|= WAPI_CRYPT
;
2222 if (p
.prwise_crypto_type
== 0) {
2223 p
.prwise_crypto_type
= NONE_CRYPT
;
2224 ath6kl_set_cipher(vif
, 0, true);
2225 } else if (info
->crypto
.n_ciphers_pairwise
== 1)
2226 ath6kl_set_cipher(vif
, info
->crypto
.ciphers_pairwise
[0], true);
2228 switch (info
->crypto
.cipher_group
) {
2229 case WLAN_CIPHER_SUITE_WEP40
:
2230 case WLAN_CIPHER_SUITE_WEP104
:
2231 p
.grp_crypto_type
= WEP_CRYPT
;
2233 case WLAN_CIPHER_SUITE_TKIP
:
2234 p
.grp_crypto_type
= TKIP_CRYPT
;
2236 case WLAN_CIPHER_SUITE_CCMP
:
2237 p
.grp_crypto_type
= AES_CRYPT
;
2239 case WLAN_CIPHER_SUITE_SMS4
:
2240 p
.grp_crypto_type
= WAPI_CRYPT
;
2243 p
.grp_crypto_type
= NONE_CRYPT
;
2246 ath6kl_set_cipher(vif
, info
->crypto
.cipher_group
, false);
2248 p
.nw_type
= AP_NETWORK
;
2249 vif
->nw_type
= vif
->next_mode
;
2251 p
.ssid_len
= vif
->ssid_len
;
2252 memcpy(p
.ssid
, vif
->ssid
, vif
->ssid_len
);
2253 p
.dot11_auth_mode
= vif
->dot11_auth_mode
;
2254 p
.ch
= cpu_to_le16(vif
->next_chan
);
2256 /* Enable uAPSD support by default */
2257 res
= ath6kl_wmi_ap_set_apsd(ar
->wmi
, vif
->fw_vif_idx
, true);
2261 if (vif
->wdev
.iftype
== NL80211_IFTYPE_P2P_GO
) {
2262 p
.nw_subtype
= SUBTYPE_P2PGO
;
2265 * Due to firmware limitation, it is not possible to
2266 * do P2P mgmt operations in AP mode
2268 p
.nw_subtype
= SUBTYPE_NONE
;
2271 res
= ath6kl_wmi_ap_profile_commit(ar
->wmi
, vif
->fw_vif_idx
, &p
);
2278 static int ath6kl_add_beacon(struct wiphy
*wiphy
, struct net_device
*dev
,
2279 struct beacon_parameters
*info
)
2281 return ath6kl_ap_beacon(wiphy
, dev
, info
, true);
2284 static int ath6kl_set_beacon(struct wiphy
*wiphy
, struct net_device
*dev
,
2285 struct beacon_parameters
*info
)
2287 return ath6kl_ap_beacon(wiphy
, dev
, info
, false);
2290 static int ath6kl_del_beacon(struct wiphy
*wiphy
, struct net_device
*dev
)
2292 struct ath6kl
*ar
= ath6kl_priv(dev
);
2293 struct ath6kl_vif
*vif
= netdev_priv(dev
);
2295 if (vif
->nw_type
!= AP_NETWORK
)
2297 if (!test_bit(CONNECTED
, &vif
->flags
))
2300 ath6kl_wmi_disconnect_cmd(ar
->wmi
, vif
->fw_vif_idx
);
2301 clear_bit(CONNECTED
, &vif
->flags
);
2306 static const u8 bcast_addr
[ETH_ALEN
] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
2308 static int ath6kl_del_station(struct wiphy
*wiphy
, struct net_device
*dev
,
2311 struct ath6kl
*ar
= ath6kl_priv(dev
);
2312 struct ath6kl_vif
*vif
= netdev_priv(dev
);
2313 const u8
*addr
= mac
? mac
: bcast_addr
;
2315 return ath6kl_wmi_ap_set_mlme(ar
->wmi
, vif
->fw_vif_idx
, WMI_AP_DEAUTH
,
2316 addr
, WLAN_REASON_PREV_AUTH_NOT_VALID
);
2319 static int ath6kl_change_station(struct wiphy
*wiphy
, struct net_device
*dev
,
2320 u8
*mac
, struct station_parameters
*params
)
2322 struct ath6kl
*ar
= ath6kl_priv(dev
);
2323 struct ath6kl_vif
*vif
= netdev_priv(dev
);
2325 if (vif
->nw_type
!= AP_NETWORK
)
2328 /* Use this only for authorizing/unauthorizing a station */
2329 if (!(params
->sta_flags_mask
& BIT(NL80211_STA_FLAG_AUTHORIZED
)))
2332 if (params
->sta_flags_set
& BIT(NL80211_STA_FLAG_AUTHORIZED
))
2333 return ath6kl_wmi_ap_set_mlme(ar
->wmi
, vif
->fw_vif_idx
,
2334 WMI_AP_MLME_AUTHORIZE
, mac
, 0);
2335 return ath6kl_wmi_ap_set_mlme(ar
->wmi
, vif
->fw_vif_idx
,
2336 WMI_AP_MLME_UNAUTHORIZE
, mac
, 0);
2339 static int ath6kl_remain_on_channel(struct wiphy
*wiphy
,
2340 struct net_device
*dev
,
2341 struct ieee80211_channel
*chan
,
2342 enum nl80211_channel_type channel_type
,
2343 unsigned int duration
,
2346 struct ath6kl
*ar
= ath6kl_priv(dev
);
2347 struct ath6kl_vif
*vif
= netdev_priv(dev
);
2350 /* TODO: if already pending or ongoing remain-on-channel,
2352 id
= ++vif
->last_roc_id
;
2354 /* Do not use 0 as the cookie value */
2355 id
= ++vif
->last_roc_id
;
2359 return ath6kl_wmi_remain_on_chnl_cmd(ar
->wmi
, vif
->fw_vif_idx
,
2360 chan
->center_freq
, duration
);
2363 static int ath6kl_cancel_remain_on_channel(struct wiphy
*wiphy
,
2364 struct net_device
*dev
,
2367 struct ath6kl
*ar
= ath6kl_priv(dev
);
2368 struct ath6kl_vif
*vif
= netdev_priv(dev
);
2370 if (cookie
!= vif
->last_roc_id
)
2372 vif
->last_cancel_roc_id
= cookie
;
2374 return ath6kl_wmi_cancel_remain_on_chnl_cmd(ar
->wmi
, vif
->fw_vif_idx
);
2377 static int ath6kl_send_go_probe_resp(struct ath6kl_vif
*vif
,
2378 const u8
*buf
, size_t len
,
2381 struct ath6kl
*ar
= vif
->ar
;
2386 const struct ieee80211_mgmt
*mgmt
;
2388 mgmt
= (const struct ieee80211_mgmt
*) buf
;
2390 /* Include P2P IE(s) from the frame generated in user space. */
2392 p2p
= kmalloc(len
, GFP_KERNEL
);
2397 pos
= mgmt
->u
.probe_resp
.variable
;
2398 while (pos
+ 1 < buf
+ len
) {
2399 if (pos
+ 2 + pos
[1] > buf
+ len
)
2401 if (ath6kl_is_p2p_ie(pos
)) {
2402 memcpy(p2p
+ p2p_len
, pos
, 2 + pos
[1]);
2403 p2p_len
+= 2 + pos
[1];
2408 ret
= ath6kl_wmi_send_probe_response_cmd(ar
->wmi
, vif
->fw_vif_idx
, freq
,
2409 mgmt
->da
, p2p
, p2p_len
);
2414 static int ath6kl_mgmt_tx(struct wiphy
*wiphy
, struct net_device
*dev
,
2415 struct ieee80211_channel
*chan
, bool offchan
,
2416 enum nl80211_channel_type channel_type
,
2417 bool channel_type_valid
, unsigned int wait
,
2418 const u8
*buf
, size_t len
, bool no_cck
,
2419 bool dont_wait_for_ack
, u64
*cookie
)
2421 struct ath6kl
*ar
= ath6kl_priv(dev
);
2422 struct ath6kl_vif
*vif
= netdev_priv(dev
);
2424 const struct ieee80211_mgmt
*mgmt
;
2426 mgmt
= (const struct ieee80211_mgmt
*) buf
;
2427 if (buf
+ len
>= mgmt
->u
.probe_resp
.variable
&&
2428 vif
->nw_type
== AP_NETWORK
&& test_bit(CONNECTED
, &vif
->flags
) &&
2429 ieee80211_is_probe_resp(mgmt
->frame_control
)) {
2431 * Send Probe Response frame in AP mode using a separate WMI
2432 * command to allow the target to fill in the generic IEs.
2434 *cookie
= 0; /* TX status not supported */
2435 return ath6kl_send_go_probe_resp(vif
, buf
, len
,
2439 id
= vif
->send_action_id
++;
2442 * 0 is a reserved value in the WMI command and shall not be
2443 * used for the command.
2445 id
= vif
->send_action_id
++;
2450 if (test_bit(ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX
,
2451 ar
->fw_capabilities
)) {
2453 * If capable of doing P2P mgmt operations using
2454 * station interface, send additional information like
2455 * supported rates to advertise and xmit rates for
2458 return ath6kl_wmi_send_mgmt_cmd(ar
->wmi
, vif
->fw_vif_idx
, id
,
2459 chan
->center_freq
, wait
,
2462 return ath6kl_wmi_send_action_cmd(ar
->wmi
, vif
->fw_vif_idx
, id
,
2463 chan
->center_freq
, wait
,
2468 static void ath6kl_mgmt_frame_register(struct wiphy
*wiphy
,
2469 struct net_device
*dev
,
2470 u16 frame_type
, bool reg
)
2472 struct ath6kl_vif
*vif
= netdev_priv(dev
);
2474 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "%s: frame_type=0x%x reg=%d\n",
2475 __func__
, frame_type
, reg
);
2476 if (frame_type
== IEEE80211_STYPE_PROBE_REQ
) {
2478 * Note: This notification callback is not allowed to sleep, so
2479 * we cannot send WMI_PROBE_REQ_REPORT_CMD here. Instead, we
2480 * hardcode target to report Probe Request frames all the time.
2482 vif
->probe_req_report
= reg
;
2486 static int ath6kl_cfg80211_sscan_start(struct wiphy
*wiphy
,
2487 struct net_device
*dev
,
2488 struct cfg80211_sched_scan_request
*request
)
2490 struct ath6kl
*ar
= ath6kl_priv(dev
);
2491 struct ath6kl_vif
*vif
= netdev_priv(dev
);
2496 if (ar
->state
!= ATH6KL_STATE_ON
)
2499 if (vif
->sme_state
!= SME_DISCONNECTED
)
2502 for (i
= 0; i
< ar
->wiphy
->max_sched_scan_ssids
; i
++) {
2503 ath6kl_wmi_probedssid_cmd(ar
->wmi
, vif
->fw_vif_idx
,
2504 i
, DISABLE_SSID_FLAG
,
2508 /* fw uses seconds, also make sure that it's >0 */
2509 interval
= max_t(u16
, 1, request
->interval
/ 1000);
2511 ath6kl_wmi_scanparams_cmd(ar
->wmi
, vif
->fw_vif_idx
,
2513 10, 0, 0, 0, 3, 0, 0, 0);
2515 if (request
->n_ssids
&& request
->ssids
[0].ssid_len
) {
2516 for (i
= 0; i
< request
->n_ssids
; i
++) {
2517 ath6kl_wmi_probedssid_cmd(ar
->wmi
, vif
->fw_vif_idx
,
2518 i
, SPECIFIC_SSID_FLAG
,
2519 request
->ssids
[i
].ssid_len
,
2520 request
->ssids
[i
].ssid
);
2524 ret
= ath6kl_wmi_set_wow_mode_cmd(ar
->wmi
, vif
->fw_vif_idx
,
2525 ATH6KL_WOW_MODE_ENABLE
,
2527 WOW_HOST_REQ_DELAY
);
2529 ath6kl_warn("Failed to enable wow with ssid filter: %d\n", ret
);
2533 /* this also clears IE in fw if it's not set */
2534 ret
= ath6kl_wmi_set_appie_cmd(ar
->wmi
, vif
->fw_vif_idx
,
2535 WMI_FRAME_PROBE_REQ
,
2536 request
->ie
, request
->ie_len
);
2538 ath6kl_warn("Failed to set probe request IE for scheduled scan: %d",
2543 ret
= ath6kl_wmi_set_host_sleep_mode_cmd(ar
->wmi
, vif
->fw_vif_idx
,
2544 ATH6KL_HOST_MODE_ASLEEP
);
2546 ath6kl_warn("Failed to enable host sleep mode for sched scan: %d\n",
2551 ar
->state
= ATH6KL_STATE_SCHED_SCAN
;
2556 static int ath6kl_cfg80211_sscan_stop(struct wiphy
*wiphy
,
2557 struct net_device
*dev
)
2559 struct ath6kl_vif
*vif
= netdev_priv(dev
);
2562 stopped
= __ath6kl_cfg80211_sscan_stop(vif
);
2570 static const struct ieee80211_txrx_stypes
2571 ath6kl_mgmt_stypes
[NUM_NL80211_IFTYPES
] = {
2572 [NL80211_IFTYPE_STATION
] = {
2573 .tx
= BIT(IEEE80211_STYPE_ACTION
>> 4) |
2574 BIT(IEEE80211_STYPE_PROBE_RESP
>> 4),
2575 .rx
= BIT(IEEE80211_STYPE_ACTION
>> 4) |
2576 BIT(IEEE80211_STYPE_PROBE_REQ
>> 4)
2578 [NL80211_IFTYPE_AP
] = {
2579 .tx
= BIT(IEEE80211_STYPE_ACTION
>> 4) |
2580 BIT(IEEE80211_STYPE_PROBE_RESP
>> 4),
2581 .rx
= BIT(IEEE80211_STYPE_ACTION
>> 4) |
2582 BIT(IEEE80211_STYPE_PROBE_REQ
>> 4)
2584 [NL80211_IFTYPE_P2P_CLIENT
] = {
2585 .tx
= BIT(IEEE80211_STYPE_ACTION
>> 4) |
2586 BIT(IEEE80211_STYPE_PROBE_RESP
>> 4),
2587 .rx
= BIT(IEEE80211_STYPE_ACTION
>> 4) |
2588 BIT(IEEE80211_STYPE_PROBE_REQ
>> 4)
2590 [NL80211_IFTYPE_P2P_GO
] = {
2591 .tx
= BIT(IEEE80211_STYPE_ACTION
>> 4) |
2592 BIT(IEEE80211_STYPE_PROBE_RESP
>> 4),
2593 .rx
= BIT(IEEE80211_STYPE_ACTION
>> 4) |
2594 BIT(IEEE80211_STYPE_PROBE_REQ
>> 4)
2598 static struct cfg80211_ops ath6kl_cfg80211_ops
= {
2599 .add_virtual_intf
= ath6kl_cfg80211_add_iface
,
2600 .del_virtual_intf
= ath6kl_cfg80211_del_iface
,
2601 .change_virtual_intf
= ath6kl_cfg80211_change_iface
,
2602 .scan
= ath6kl_cfg80211_scan
,
2603 .connect
= ath6kl_cfg80211_connect
,
2604 .disconnect
= ath6kl_cfg80211_disconnect
,
2605 .add_key
= ath6kl_cfg80211_add_key
,
2606 .get_key
= ath6kl_cfg80211_get_key
,
2607 .del_key
= ath6kl_cfg80211_del_key
,
2608 .set_default_key
= ath6kl_cfg80211_set_default_key
,
2609 .set_wiphy_params
= ath6kl_cfg80211_set_wiphy_params
,
2610 .set_tx_power
= ath6kl_cfg80211_set_txpower
,
2611 .get_tx_power
= ath6kl_cfg80211_get_txpower
,
2612 .set_power_mgmt
= ath6kl_cfg80211_set_power_mgmt
,
2613 .join_ibss
= ath6kl_cfg80211_join_ibss
,
2614 .leave_ibss
= ath6kl_cfg80211_leave_ibss
,
2615 .get_station
= ath6kl_get_station
,
2616 .set_pmksa
= ath6kl_set_pmksa
,
2617 .del_pmksa
= ath6kl_del_pmksa
,
2618 .flush_pmksa
= ath6kl_flush_pmksa
,
2619 CFG80211_TESTMODE_CMD(ath6kl_tm_cmd
)
2621 .suspend
= __ath6kl_cfg80211_suspend
,
2622 .resume
= __ath6kl_cfg80211_resume
,
2624 .set_channel
= ath6kl_set_channel
,
2625 .add_beacon
= ath6kl_add_beacon
,
2626 .set_beacon
= ath6kl_set_beacon
,
2627 .del_beacon
= ath6kl_del_beacon
,
2628 .del_station
= ath6kl_del_station
,
2629 .change_station
= ath6kl_change_station
,
2630 .remain_on_channel
= ath6kl_remain_on_channel
,
2631 .cancel_remain_on_channel
= ath6kl_cancel_remain_on_channel
,
2632 .mgmt_tx
= ath6kl_mgmt_tx
,
2633 .mgmt_frame_register
= ath6kl_mgmt_frame_register
,
2634 .sched_scan_start
= ath6kl_cfg80211_sscan_start
,
2635 .sched_scan_stop
= ath6kl_cfg80211_sscan_stop
,
2638 void ath6kl_cfg80211_stop(struct ath6kl_vif
*vif
)
2640 ath6kl_cfg80211_sscan_disable(vif
);
2642 switch (vif
->sme_state
) {
2643 case SME_DISCONNECTED
:
2645 case SME_CONNECTING
:
2646 cfg80211_connect_result(vif
->ndev
, vif
->bssid
, NULL
, 0,
2648 WLAN_STATUS_UNSPECIFIED_FAILURE
,
2652 cfg80211_disconnected(vif
->ndev
, 0, NULL
, 0, GFP_KERNEL
);
2656 if (test_bit(CONNECTED
, &vif
->flags
) ||
2657 test_bit(CONNECT_PEND
, &vif
->flags
))
2658 ath6kl_wmi_disconnect_cmd(vif
->ar
->wmi
, vif
->fw_vif_idx
);
2660 vif
->sme_state
= SME_DISCONNECTED
;
2661 clear_bit(CONNECTED
, &vif
->flags
);
2662 clear_bit(CONNECT_PEND
, &vif
->flags
);
2664 /* disable scanning */
2665 if (ath6kl_wmi_scanparams_cmd(vif
->ar
->wmi
, vif
->fw_vif_idx
, 0xFFFF,
2666 0, 0, 0, 0, 0, 0, 0, 0, 0) != 0)
2667 ath6kl_warn("failed to disable scan during stop\n");
2669 ath6kl_cfg80211_scan_complete_event(vif
, true);
2672 void ath6kl_cfg80211_stop_all(struct ath6kl
*ar
)
2674 struct ath6kl_vif
*vif
;
2676 vif
= ath6kl_vif_first(ar
);
2678 /* save the current power mode before enabling power save */
2679 ar
->wmi
->saved_pwr_mode
= ar
->wmi
->pwr_mode
;
2681 if (ath6kl_wmi_powermode_cmd(ar
->wmi
, 0, REC_POWER
) != 0)
2682 ath6kl_warn("ath6kl_deep_sleep_enable: "
2683 "wmi_powermode_cmd failed\n");
2688 * FIXME: we should take ar->list_lock to protect changes in the
2689 * vif_list, but that's not trivial to do as ath6kl_cfg80211_stop()
2692 list_for_each_entry(vif
, &ar
->vif_list
, list
)
2693 ath6kl_cfg80211_stop(vif
);
2696 struct ath6kl
*ath6kl_core_alloc(struct device
*dev
)
2699 struct wiphy
*wiphy
;
2702 /* create a new wiphy for use with cfg80211 */
2703 wiphy
= wiphy_new(&ath6kl_cfg80211_ops
, sizeof(struct ath6kl
));
2706 ath6kl_err("couldn't allocate wiphy device\n");
2710 ar
= wiphy_priv(wiphy
);
2711 ar
->p2p
= !!ath6kl_p2p
;
2717 ar
->max_norm_iface
= 1;
2719 spin_lock_init(&ar
->lock
);
2720 spin_lock_init(&ar
->mcastpsq_lock
);
2721 spin_lock_init(&ar
->list_lock
);
2723 init_waitqueue_head(&ar
->event_wq
);
2724 sema_init(&ar
->sem
, 1);
2726 INIT_LIST_HEAD(&ar
->amsdu_rx_buffer_queue
);
2727 INIT_LIST_HEAD(&ar
->vif_list
);
2729 clear_bit(WMI_ENABLED
, &ar
->flag
);
2730 clear_bit(SKIP_SCAN
, &ar
->flag
);
2731 clear_bit(DESTROY_IN_PROGRESS
, &ar
->flag
);
2733 ar
->listen_intvl_b
= A_DEFAULT_LISTEN_INTERVAL
;
2737 ar
->lrssi_roam_threshold
= DEF_LRSSI_ROAM_THRESHOLD
;
2739 ar
->state
= ATH6KL_STATE_OFF
;
2741 memset((u8
*)ar
->sta_list
, 0,
2742 AP_MAX_NUM_STA
* sizeof(struct ath6kl_sta
));
2744 /* Init the PS queues */
2745 for (ctr
= 0; ctr
< AP_MAX_NUM_STA
; ctr
++) {
2746 spin_lock_init(&ar
->sta_list
[ctr
].psq_lock
);
2747 skb_queue_head_init(&ar
->sta_list
[ctr
].psq
);
2748 skb_queue_head_init(&ar
->sta_list
[ctr
].apsdq
);
2751 skb_queue_head_init(&ar
->mcastpsq
);
2753 memcpy(ar
->ap_country_code
, DEF_AP_COUNTRY_CODE
, 3);
2758 static int ath6kl_cfg80211_vif_init(struct ath6kl_vif
*vif
)
2760 vif
->aggr_cntxt
= aggr_init(vif
->ndev
);
2761 if (!vif
->aggr_cntxt
) {
2762 ath6kl_err("failed to initialize aggr\n");
2766 setup_timer(&vif
->disconnect_timer
, disconnect_timer_handler
,
2767 (unsigned long) vif
->ndev
);
2768 setup_timer(&vif
->sched_scan_timer
, ath6kl_wmi_sscan_timer
,
2769 (unsigned long) vif
);
2771 set_bit(WMM_ENABLED
, &vif
->flags
);
2772 spin_lock_init(&vif
->if_lock
);
2774 INIT_LIST_HEAD(&vif
->mc_filter
);
2779 void ath6kl_cfg80211_vif_cleanup(struct ath6kl_vif
*vif
)
2781 struct ath6kl
*ar
= vif
->ar
;
2782 struct ath6kl_mc_filter
*mc_filter
, *tmp
;
2784 aggr_module_destroy(vif
->aggr_cntxt
);
2786 ar
->avail_idx_map
|= BIT(vif
->fw_vif_idx
);
2788 if (vif
->nw_type
== ADHOC_NETWORK
)
2789 ar
->ibss_if_active
= false;
2791 list_for_each_entry_safe(mc_filter
, tmp
, &vif
->mc_filter
, list
) {
2792 list_del(&mc_filter
->list
);
2796 unregister_netdevice(vif
->ndev
);
2801 struct net_device
*ath6kl_interface_add(struct ath6kl
*ar
, char *name
,
2802 enum nl80211_iftype type
, u8 fw_vif_idx
,
2805 struct net_device
*ndev
;
2806 struct ath6kl_vif
*vif
;
2808 ndev
= alloc_netdev(sizeof(*vif
), name
, ether_setup
);
2812 vif
= netdev_priv(ndev
);
2813 ndev
->ieee80211_ptr
= &vif
->wdev
;
2814 vif
->wdev
.wiphy
= ar
->wiphy
;
2817 SET_NETDEV_DEV(ndev
, wiphy_dev(vif
->wdev
.wiphy
));
2818 vif
->wdev
.netdev
= ndev
;
2819 vif
->wdev
.iftype
= type
;
2820 vif
->fw_vif_idx
= fw_vif_idx
;
2821 vif
->nw_type
= vif
->next_mode
= nw_type
;
2823 memcpy(ndev
->dev_addr
, ar
->mac_addr
, ETH_ALEN
);
2824 if (fw_vif_idx
!= 0)
2825 ndev
->dev_addr
[0] = (ndev
->dev_addr
[0] ^ (1 << fw_vif_idx
)) |
2830 ath6kl_init_control_info(vif
);
2832 if (ath6kl_cfg80211_vif_init(vif
))
2835 if (register_netdevice(ndev
))
2838 ar
->avail_idx_map
&= ~BIT(fw_vif_idx
);
2839 vif
->sme_state
= SME_DISCONNECTED
;
2840 set_bit(WLAN_ENABLED
, &vif
->flags
);
2841 ar
->wlan_pwr_state
= WLAN_POWER_STATE_ON
;
2842 set_bit(NETDEV_REGISTERED
, &vif
->flags
);
2844 if (type
== NL80211_IFTYPE_ADHOC
)
2845 ar
->ibss_if_active
= true;
2847 spin_lock_bh(&ar
->list_lock
);
2848 list_add_tail(&vif
->list
, &ar
->vif_list
);
2849 spin_unlock_bh(&ar
->list_lock
);
2854 aggr_module_destroy(vif
->aggr_cntxt
);
2859 int ath6kl_cfg80211_init(struct ath6kl
*ar
)
2861 struct wiphy
*wiphy
= ar
->wiphy
;
2864 wiphy
->mgmt_stypes
= ath6kl_mgmt_stypes
;
2866 wiphy
->max_remain_on_channel_duration
= 5000;
2868 /* set device pointer for wiphy */
2869 set_wiphy_dev(wiphy
, ar
->dev
);
2871 wiphy
->interface_modes
= BIT(NL80211_IFTYPE_STATION
) |
2872 BIT(NL80211_IFTYPE_ADHOC
) |
2873 BIT(NL80211_IFTYPE_AP
);
2875 wiphy
->interface_modes
|= BIT(NL80211_IFTYPE_P2P_GO
) |
2876 BIT(NL80211_IFTYPE_P2P_CLIENT
);
2879 /* max num of ssids that can be probed during scanning */
2880 wiphy
->max_scan_ssids
= MAX_PROBED_SSID_INDEX
;
2881 wiphy
->max_scan_ie_len
= 1000; /* FIX: what is correct limit? */
2882 wiphy
->bands
[IEEE80211_BAND_2GHZ
] = &ath6kl_band_2ghz
;
2883 wiphy
->bands
[IEEE80211_BAND_5GHZ
] = &ath6kl_band_5ghz
;
2884 wiphy
->signal_type
= CFG80211_SIGNAL_TYPE_MBM
;
2886 wiphy
->cipher_suites
= cipher_suites
;
2887 wiphy
->n_cipher_suites
= ARRAY_SIZE(cipher_suites
);
2889 wiphy
->wowlan
.flags
= WIPHY_WOWLAN_MAGIC_PKT
|
2890 WIPHY_WOWLAN_DISCONNECT
|
2891 WIPHY_WOWLAN_GTK_REKEY_FAILURE
|
2892 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY
|
2893 WIPHY_WOWLAN_EAP_IDENTITY_REQ
|
2894 WIPHY_WOWLAN_4WAY_HANDSHAKE
;
2895 wiphy
->wowlan
.n_patterns
= WOW_MAX_FILTERS_PER_LIST
;
2896 wiphy
->wowlan
.pattern_min_len
= 1;
2897 wiphy
->wowlan
.pattern_max_len
= WOW_PATTERN_SIZE
;
2899 wiphy
->max_sched_scan_ssids
= 10;
2901 ret
= wiphy_register(wiphy
);
2903 ath6kl_err("couldn't register wiphy device\n");
2910 void ath6kl_cfg80211_cleanup(struct ath6kl
*ar
)
2912 wiphy_unregister(ar
->wiphy
);
2915 * FIXME: should be removed as we remove wiphy in
2916 * ath6kl_core_free(). Most likely this causes a use after free.
2918 wiphy_free(ar
->wiphy
);