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>
25 static unsigned int ath6kl_p2p
;
27 module_param(ath6kl_p2p
, uint
, 0644);
29 #define RATETAB_ENT(_rate, _rateid, _flags) { \
32 .hw_value = (_rateid), \
35 #define CHAN2G(_channel, _freq, _flags) { \
36 .band = IEEE80211_BAND_2GHZ, \
37 .hw_value = (_channel), \
38 .center_freq = (_freq), \
40 .max_antenna_gain = 0, \
44 #define CHAN5G(_channel, _flags) { \
45 .band = IEEE80211_BAND_5GHZ, \
46 .hw_value = (_channel), \
47 .center_freq = 5000 + (5 * (_channel)), \
49 .max_antenna_gain = 0, \
53 static struct ieee80211_rate ath6kl_rates
[] = {
54 RATETAB_ENT(10, 0x1, 0),
55 RATETAB_ENT(20, 0x2, 0),
56 RATETAB_ENT(55, 0x4, 0),
57 RATETAB_ENT(110, 0x8, 0),
58 RATETAB_ENT(60, 0x10, 0),
59 RATETAB_ENT(90, 0x20, 0),
60 RATETAB_ENT(120, 0x40, 0),
61 RATETAB_ENT(180, 0x80, 0),
62 RATETAB_ENT(240, 0x100, 0),
63 RATETAB_ENT(360, 0x200, 0),
64 RATETAB_ENT(480, 0x400, 0),
65 RATETAB_ENT(540, 0x800, 0),
68 #define ath6kl_a_rates (ath6kl_rates + 4)
69 #define ath6kl_a_rates_size 8
70 #define ath6kl_g_rates (ath6kl_rates + 0)
71 #define ath6kl_g_rates_size 12
73 static struct ieee80211_channel ath6kl_2ghz_channels
[] = {
90 static struct ieee80211_channel ath6kl_5ghz_a_channels
[] = {
91 CHAN5G(34, 0), CHAN5G(36, 0),
92 CHAN5G(38, 0), CHAN5G(40, 0),
93 CHAN5G(42, 0), CHAN5G(44, 0),
94 CHAN5G(46, 0), CHAN5G(48, 0),
95 CHAN5G(52, 0), CHAN5G(56, 0),
96 CHAN5G(60, 0), CHAN5G(64, 0),
97 CHAN5G(100, 0), CHAN5G(104, 0),
98 CHAN5G(108, 0), CHAN5G(112, 0),
99 CHAN5G(116, 0), CHAN5G(120, 0),
100 CHAN5G(124, 0), CHAN5G(128, 0),
101 CHAN5G(132, 0), CHAN5G(136, 0),
102 CHAN5G(140, 0), CHAN5G(149, 0),
103 CHAN5G(153, 0), CHAN5G(157, 0),
104 CHAN5G(161, 0), CHAN5G(165, 0),
105 CHAN5G(184, 0), CHAN5G(188, 0),
106 CHAN5G(192, 0), CHAN5G(196, 0),
107 CHAN5G(200, 0), CHAN5G(204, 0),
108 CHAN5G(208, 0), CHAN5G(212, 0),
112 static struct ieee80211_supported_band ath6kl_band_2ghz
= {
113 .n_channels
= ARRAY_SIZE(ath6kl_2ghz_channels
),
114 .channels
= ath6kl_2ghz_channels
,
115 .n_bitrates
= ath6kl_g_rates_size
,
116 .bitrates
= ath6kl_g_rates
,
119 static struct ieee80211_supported_band ath6kl_band_5ghz
= {
120 .n_channels
= ARRAY_SIZE(ath6kl_5ghz_a_channels
),
121 .channels
= ath6kl_5ghz_a_channels
,
122 .n_bitrates
= ath6kl_a_rates_size
,
123 .bitrates
= ath6kl_a_rates
,
126 #define CCKM_KRK_CIPHER_SUITE 0x004096ff /* use for KRK */
128 /* returns true if scheduled scan was stopped */
129 static bool __ath6kl_cfg80211_sscan_stop(struct ath6kl_vif
*vif
)
131 struct ath6kl
*ar
= vif
->ar
;
133 if (ar
->state
!= ATH6KL_STATE_SCHED_SCAN
)
136 del_timer_sync(&vif
->sched_scan_timer
);
138 ath6kl_wmi_set_host_sleep_mode_cmd(ar
->wmi
, vif
->fw_vif_idx
,
139 ATH6KL_HOST_MODE_AWAKE
);
141 ar
->state
= ATH6KL_STATE_ON
;
146 static void ath6kl_cfg80211_sscan_disable(struct ath6kl_vif
*vif
)
148 struct ath6kl
*ar
= vif
->ar
;
151 stopped
= __ath6kl_cfg80211_sscan_stop(vif
);
156 cfg80211_sched_scan_stopped(ar
->wiphy
);
159 static int ath6kl_set_wpa_version(struct ath6kl_vif
*vif
,
160 enum nl80211_wpa_versions wpa_version
)
162 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "%s: %u\n", __func__
, wpa_version
);
165 vif
->auth_mode
= NONE_AUTH
;
166 } else if (wpa_version
& NL80211_WPA_VERSION_2
) {
167 vif
->auth_mode
= WPA2_AUTH
;
168 } else if (wpa_version
& NL80211_WPA_VERSION_1
) {
169 vif
->auth_mode
= WPA_AUTH
;
171 ath6kl_err("%s: %u not supported\n", __func__
, wpa_version
);
178 static int ath6kl_set_auth_type(struct ath6kl_vif
*vif
,
179 enum nl80211_auth_type auth_type
)
181 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "%s: 0x%x\n", __func__
, auth_type
);
184 case NL80211_AUTHTYPE_OPEN_SYSTEM
:
185 vif
->dot11_auth_mode
= OPEN_AUTH
;
187 case NL80211_AUTHTYPE_SHARED_KEY
:
188 vif
->dot11_auth_mode
= SHARED_AUTH
;
190 case NL80211_AUTHTYPE_NETWORK_EAP
:
191 vif
->dot11_auth_mode
= LEAP_AUTH
;
194 case NL80211_AUTHTYPE_AUTOMATIC
:
195 vif
->dot11_auth_mode
= OPEN_AUTH
| SHARED_AUTH
;
199 ath6kl_err("%s: 0x%x not spported\n", __func__
, auth_type
);
206 static int ath6kl_set_cipher(struct ath6kl_vif
*vif
, u32 cipher
, bool ucast
)
208 u8
*ar_cipher
= ucast
? &vif
->prwise_crypto
: &vif
->grp_crypto
;
209 u8
*ar_cipher_len
= ucast
? &vif
->prwise_crypto_len
:
210 &vif
->grp_crypto_len
;
212 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "%s: cipher 0x%x, ucast %u\n",
213 __func__
, cipher
, ucast
);
217 /* our own hack to use value 0 as no crypto used */
218 *ar_cipher
= NONE_CRYPT
;
221 case WLAN_CIPHER_SUITE_WEP40
:
222 *ar_cipher
= WEP_CRYPT
;
225 case WLAN_CIPHER_SUITE_WEP104
:
226 *ar_cipher
= WEP_CRYPT
;
229 case WLAN_CIPHER_SUITE_TKIP
:
230 *ar_cipher
= TKIP_CRYPT
;
233 case WLAN_CIPHER_SUITE_CCMP
:
234 *ar_cipher
= AES_CRYPT
;
237 case WLAN_CIPHER_SUITE_SMS4
:
238 *ar_cipher
= WAPI_CRYPT
;
242 ath6kl_err("cipher 0x%x not supported\n", cipher
);
249 static void ath6kl_set_key_mgmt(struct ath6kl_vif
*vif
, u32 key_mgmt
)
251 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "%s: 0x%x\n", __func__
, key_mgmt
);
253 if (key_mgmt
== WLAN_AKM_SUITE_PSK
) {
254 if (vif
->auth_mode
== WPA_AUTH
)
255 vif
->auth_mode
= WPA_PSK_AUTH
;
256 else if (vif
->auth_mode
== WPA2_AUTH
)
257 vif
->auth_mode
= WPA2_PSK_AUTH
;
258 } else if (key_mgmt
== 0x00409600) {
259 if (vif
->auth_mode
== WPA_AUTH
)
260 vif
->auth_mode
= WPA_AUTH_CCKM
;
261 else if (vif
->auth_mode
== WPA2_AUTH
)
262 vif
->auth_mode
= WPA2_AUTH_CCKM
;
263 } else if (key_mgmt
!= WLAN_AKM_SUITE_8021X
) {
264 vif
->auth_mode
= NONE_AUTH
;
268 static bool ath6kl_cfg80211_ready(struct ath6kl_vif
*vif
)
270 struct ath6kl
*ar
= vif
->ar
;
272 if (!test_bit(WMI_READY
, &ar
->flag
)) {
273 ath6kl_err("wmi is not ready\n");
277 if (!test_bit(WLAN_ENABLED
, &vif
->flags
)) {
278 ath6kl_err("wlan disabled\n");
285 static bool ath6kl_is_wpa_ie(const u8
*pos
)
287 return pos
[0] == WLAN_EID_WPA
&& pos
[1] >= 4 &&
288 pos
[2] == 0x00 && pos
[3] == 0x50 &&
289 pos
[4] == 0xf2 && pos
[5] == 0x01;
292 static bool ath6kl_is_rsn_ie(const u8
*pos
)
294 return pos
[0] == WLAN_EID_RSN
;
297 static bool ath6kl_is_wps_ie(const u8
*pos
)
299 return (pos
[0] == WLAN_EID_VENDOR_SPECIFIC
&&
301 pos
[2] == 0x00 && pos
[3] == 0x50 && pos
[4] == 0xf2 &&
305 static int ath6kl_set_assoc_req_ies(struct ath6kl_vif
*vif
, const u8
*ies
,
308 struct ath6kl
*ar
= vif
->ar
;
315 * Clear previously set flag
318 ar
->connect_ctrl_flags
&= ~CONNECT_WPS_FLAG
;
321 * Filter out RSN/WPA IE(s)
324 if (ies
&& ies_len
) {
325 buf
= kmalloc(ies_len
, GFP_KERNEL
);
330 while (pos
+ 1 < ies
+ ies_len
) {
331 if (pos
+ 2 + pos
[1] > ies
+ ies_len
)
333 if (!(ath6kl_is_wpa_ie(pos
) || ath6kl_is_rsn_ie(pos
))) {
334 memcpy(buf
+ len
, pos
, 2 + pos
[1]);
338 if (ath6kl_is_wps_ie(pos
))
339 ar
->connect_ctrl_flags
|= CONNECT_WPS_FLAG
;
345 ret
= ath6kl_wmi_set_appie_cmd(ar
->wmi
, vif
->fw_vif_idx
,
346 WMI_FRAME_ASSOC_REQ
, buf
, len
);
351 static int ath6kl_nliftype_to_drv_iftype(enum nl80211_iftype type
, u8
*nw_type
)
354 case NL80211_IFTYPE_STATION
:
355 *nw_type
= INFRA_NETWORK
;
357 case NL80211_IFTYPE_ADHOC
:
358 *nw_type
= ADHOC_NETWORK
;
360 case NL80211_IFTYPE_AP
:
361 *nw_type
= AP_NETWORK
;
363 case NL80211_IFTYPE_P2P_CLIENT
:
364 *nw_type
= INFRA_NETWORK
;
366 case NL80211_IFTYPE_P2P_GO
:
367 *nw_type
= AP_NETWORK
;
370 ath6kl_err("invalid interface type %u\n", type
);
377 static bool ath6kl_is_valid_iftype(struct ath6kl
*ar
, enum nl80211_iftype type
,
378 u8
*if_idx
, u8
*nw_type
)
382 if (ath6kl_nliftype_to_drv_iftype(type
, nw_type
))
385 if (ar
->ibss_if_active
|| ((type
== NL80211_IFTYPE_ADHOC
) &&
389 if (type
== NL80211_IFTYPE_STATION
||
390 type
== NL80211_IFTYPE_AP
|| type
== NL80211_IFTYPE_ADHOC
) {
391 for (i
= 0; i
< ar
->vif_max
; i
++) {
392 if ((ar
->avail_idx_map
>> i
) & BIT(0)) {
399 if (type
== NL80211_IFTYPE_P2P_CLIENT
||
400 type
== NL80211_IFTYPE_P2P_GO
) {
401 for (i
= ar
->max_norm_iface
; i
< ar
->vif_max
; i
++) {
402 if ((ar
->avail_idx_map
>> i
) & BIT(0)) {
412 static int ath6kl_cfg80211_connect(struct wiphy
*wiphy
, struct net_device
*dev
,
413 struct cfg80211_connect_params
*sme
)
415 struct ath6kl
*ar
= ath6kl_priv(dev
);
416 struct ath6kl_vif
*vif
= netdev_priv(dev
);
418 u8 nw_subtype
= (ar
->p2p
) ? SUBTYPE_P2PDEV
: SUBTYPE_NONE
;
420 ath6kl_cfg80211_sscan_disable(vif
);
422 vif
->sme_state
= SME_CONNECTING
;
424 if (!ath6kl_cfg80211_ready(vif
))
427 if (test_bit(DESTROY_IN_PROGRESS
, &ar
->flag
)) {
428 ath6kl_err("destroy in progress\n");
432 if (test_bit(SKIP_SCAN
, &ar
->flag
) &&
433 ((sme
->channel
&& sme
->channel
->center_freq
== 0) ||
434 (sme
->bssid
&& is_zero_ether_addr(sme
->bssid
)))) {
435 ath6kl_err("SkipScan: channel or bssid invalid\n");
439 if (down_interruptible(&ar
->sem
)) {
440 ath6kl_err("busy, couldn't get access\n");
444 if (test_bit(DESTROY_IN_PROGRESS
, &ar
->flag
)) {
445 ath6kl_err("busy, destroy in progress\n");
450 if (ar
->tx_pending
[ath6kl_wmi_get_control_ep(ar
->wmi
)]) {
452 * sleep until the command queue drains
454 wait_event_interruptible_timeout(ar
->event_wq
,
455 ar
->tx_pending
[ath6kl_wmi_get_control_ep(ar
->wmi
)] == 0,
457 if (signal_pending(current
)) {
458 ath6kl_err("cmd queue drain timeout\n");
464 status
= ath6kl_set_assoc_req_ies(vif
, sme
->ie
, sme
->ie_len
);
470 if (sme
->ie
== NULL
|| sme
->ie_len
== 0)
471 ar
->connect_ctrl_flags
&= ~CONNECT_WPS_FLAG
;
473 if (test_bit(CONNECTED
, &vif
->flags
) &&
474 vif
->ssid_len
== sme
->ssid_len
&&
475 !memcmp(vif
->ssid
, sme
->ssid
, vif
->ssid_len
)) {
476 vif
->reconnect_flag
= true;
477 status
= ath6kl_wmi_reconnect_cmd(ar
->wmi
, vif
->fw_vif_idx
,
483 ath6kl_err("wmi_reconnect_cmd failed\n");
487 } else if (vif
->ssid_len
== sme
->ssid_len
&&
488 !memcmp(vif
->ssid
, sme
->ssid
, vif
->ssid_len
)) {
489 ath6kl_disconnect(vif
);
492 memset(vif
->ssid
, 0, sizeof(vif
->ssid
));
493 vif
->ssid_len
= sme
->ssid_len
;
494 memcpy(vif
->ssid
, sme
->ssid
, sme
->ssid_len
);
497 vif
->ch_hint
= sme
->channel
->center_freq
;
499 memset(vif
->req_bssid
, 0, sizeof(vif
->req_bssid
));
500 if (sme
->bssid
&& !is_broadcast_ether_addr(sme
->bssid
))
501 memcpy(vif
->req_bssid
, sme
->bssid
, sizeof(vif
->req_bssid
));
503 ath6kl_set_wpa_version(vif
, sme
->crypto
.wpa_versions
);
505 status
= ath6kl_set_auth_type(vif
, sme
->auth_type
);
511 if (sme
->crypto
.n_ciphers_pairwise
)
512 ath6kl_set_cipher(vif
, sme
->crypto
.ciphers_pairwise
[0], true);
514 ath6kl_set_cipher(vif
, 0, true);
516 ath6kl_set_cipher(vif
, sme
->crypto
.cipher_group
, false);
518 if (sme
->crypto
.n_akm_suites
)
519 ath6kl_set_key_mgmt(vif
, sme
->crypto
.akm_suites
[0]);
521 if ((sme
->key_len
) &&
522 (vif
->auth_mode
== NONE_AUTH
) &&
523 (vif
->prwise_crypto
== WEP_CRYPT
)) {
524 struct ath6kl_key
*key
= NULL
;
526 if (sme
->key_idx
< WMI_MIN_KEY_INDEX
||
527 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
;
989 if (!ath6kl_cfg80211_ready(vif
))
992 if (params
->cipher
== CCKM_KRK_CIPHER_SUITE
) {
993 if (params
->key_len
!= WMI_KRK_LEN
)
995 return ath6kl_wmi_add_krk_cmd(ar
->wmi
, vif
->fw_vif_idx
,
999 if (key_index
< WMI_MIN_KEY_INDEX
|| key_index
> WMI_MAX_KEY_INDEX
) {
1000 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
,
1001 "%s: key index %d out of bounds\n", __func__
,
1006 key
= &vif
->keys
[key_index
];
1007 memset(key
, 0, sizeof(struct ath6kl_key
));
1010 key_usage
= PAIRWISE_USAGE
;
1012 key_usage
= GROUP_USAGE
;
1015 int 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
;
1032 switch (key
->cipher
) {
1033 case WLAN_CIPHER_SUITE_WEP40
:
1034 case WLAN_CIPHER_SUITE_WEP104
:
1035 key_type
= WEP_CRYPT
;
1038 case WLAN_CIPHER_SUITE_TKIP
:
1039 key_type
= TKIP_CRYPT
;
1042 case WLAN_CIPHER_SUITE_CCMP
:
1043 key_type
= AES_CRYPT
;
1045 case WLAN_CIPHER_SUITE_SMS4
:
1046 key_type
= WAPI_CRYPT
;
1053 if (((vif
->auth_mode
== WPA_PSK_AUTH
)
1054 || (vif
->auth_mode
== WPA2_PSK_AUTH
))
1055 && (key_usage
& GROUP_USAGE
))
1056 del_timer(&vif
->disconnect_timer
);
1058 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
,
1059 "%s: index %d, key_len %d, key_type 0x%x, key_usage 0x%x, seq_len %d\n",
1060 __func__
, key_index
, key
->key_len
, key_type
,
1061 key_usage
, key
->seq_len
);
1063 if (vif
->nw_type
== AP_NETWORK
&& !pairwise
&&
1064 (key_type
== TKIP_CRYPT
|| key_type
== AES_CRYPT
||
1065 key_type
== WAPI_CRYPT
) && params
) {
1066 ar
->ap_mode_bkey
.valid
= true;
1067 ar
->ap_mode_bkey
.key_index
= key_index
;
1068 ar
->ap_mode_bkey
.key_type
= key_type
;
1069 ar
->ap_mode_bkey
.key_len
= key
->key_len
;
1070 memcpy(ar
->ap_mode_bkey
.key
, key
->key
, key
->key_len
);
1071 if (!test_bit(CONNECTED
, &vif
->flags
)) {
1072 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "Delay initial group "
1073 "key configuration until AP mode has been "
1076 * The key will be set in ath6kl_connect_ap_mode() once
1077 * the connected event is received from the target.
1083 if (vif
->next_mode
== AP_NETWORK
&& key_type
== WEP_CRYPT
&&
1084 !test_bit(CONNECTED
, &vif
->flags
)) {
1086 * Store the key locally so that it can be re-configured after
1087 * the AP mode has properly started
1088 * (ath6kl_install_statioc_wep_keys).
1090 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "Delay WEP key configuration "
1091 "until AP mode has been started\n");
1092 vif
->wep_key_list
[key_index
].key_len
= key
->key_len
;
1093 memcpy(vif
->wep_key_list
[key_index
].key
, key
->key
,
1098 return ath6kl_wmi_addkey_cmd(ar
->wmi
, vif
->fw_vif_idx
, key_index
,
1099 key_type
, key_usage
, key
->key_len
,
1100 key
->seq
, key
->seq_len
, key
->key
,
1102 (u8
*) mac_addr
, SYNC_BOTH_WMIFLAG
);
1105 static int ath6kl_cfg80211_del_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
1106 u8 key_index
, bool pairwise
,
1109 struct ath6kl
*ar
= ath6kl_priv(ndev
);
1110 struct ath6kl_vif
*vif
= netdev_priv(ndev
);
1112 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "%s: index %d\n", __func__
, key_index
);
1114 if (!ath6kl_cfg80211_ready(vif
))
1117 if (key_index
< WMI_MIN_KEY_INDEX
|| key_index
> WMI_MAX_KEY_INDEX
) {
1118 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
,
1119 "%s: key index %d out of bounds\n", __func__
,
1124 if (!vif
->keys
[key_index
].key_len
) {
1125 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
,
1126 "%s: index %d is empty\n", __func__
, key_index
);
1130 vif
->keys
[key_index
].key_len
= 0;
1132 return ath6kl_wmi_deletekey_cmd(ar
->wmi
, vif
->fw_vif_idx
, key_index
);
1135 static int ath6kl_cfg80211_get_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
1136 u8 key_index
, bool pairwise
,
1137 const u8
*mac_addr
, void *cookie
,
1138 void (*callback
) (void *cookie
,
1139 struct key_params
*))
1141 struct ath6kl_vif
*vif
= netdev_priv(ndev
);
1142 struct ath6kl_key
*key
= NULL
;
1143 struct key_params params
;
1145 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "%s: index %d\n", __func__
, key_index
);
1147 if (!ath6kl_cfg80211_ready(vif
))
1150 if (key_index
< WMI_MIN_KEY_INDEX
|| key_index
> WMI_MAX_KEY_INDEX
) {
1151 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
,
1152 "%s: key index %d out of bounds\n", __func__
,
1157 key
= &vif
->keys
[key_index
];
1158 memset(¶ms
, 0, sizeof(params
));
1159 params
.cipher
= key
->cipher
;
1160 params
.key_len
= key
->key_len
;
1161 params
.seq_len
= key
->seq_len
;
1162 params
.seq
= key
->seq
;
1163 params
.key
= key
->key
;
1165 callback(cookie
, ¶ms
);
1167 return key
->key_len
? 0 : -ENOENT
;
1170 static int ath6kl_cfg80211_set_default_key(struct wiphy
*wiphy
,
1171 struct net_device
*ndev
,
1172 u8 key_index
, bool unicast
,
1175 struct ath6kl
*ar
= ath6kl_priv(ndev
);
1176 struct ath6kl_vif
*vif
= netdev_priv(ndev
);
1177 struct ath6kl_key
*key
= NULL
;
1179 enum crypto_type key_type
= NONE_CRYPT
;
1181 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "%s: index %d\n", __func__
, key_index
);
1183 if (!ath6kl_cfg80211_ready(vif
))
1186 if (key_index
< WMI_MIN_KEY_INDEX
|| key_index
> WMI_MAX_KEY_INDEX
) {
1187 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
,
1188 "%s: key index %d out of bounds\n",
1189 __func__
, key_index
);
1193 if (!vif
->keys
[key_index
].key_len
) {
1194 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "%s: invalid key index %d\n",
1195 __func__
, key_index
);
1199 vif
->def_txkey_index
= key_index
;
1200 key
= &vif
->keys
[vif
->def_txkey_index
];
1201 key_usage
= GROUP_USAGE
;
1202 if (vif
->prwise_crypto
== WEP_CRYPT
)
1203 key_usage
|= TX_USAGE
;
1205 key_type
= vif
->prwise_crypto
;
1207 key_type
= vif
->grp_crypto
;
1209 if (vif
->next_mode
== AP_NETWORK
&& !test_bit(CONNECTED
, &vif
->flags
))
1210 return 0; /* Delay until AP mode has been started */
1212 return ath6kl_wmi_addkey_cmd(ar
->wmi
, vif
->fw_vif_idx
,
1213 vif
->def_txkey_index
,
1214 key_type
, key_usage
,
1215 key
->key_len
, key
->seq
, key
->seq_len
,
1217 KEY_OP_INIT_VAL
, NULL
,
1221 void ath6kl_cfg80211_tkip_micerr_event(struct ath6kl_vif
*vif
, u8 keyid
,
1224 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
,
1225 "%s: keyid %d, ismcast %d\n", __func__
, keyid
, ismcast
);
1227 cfg80211_michael_mic_failure(vif
->ndev
, vif
->bssid
,
1228 (ismcast
? NL80211_KEYTYPE_GROUP
:
1229 NL80211_KEYTYPE_PAIRWISE
), keyid
, NULL
,
1233 static int ath6kl_cfg80211_set_wiphy_params(struct wiphy
*wiphy
, u32 changed
)
1235 struct ath6kl
*ar
= (struct ath6kl
*)wiphy_priv(wiphy
);
1236 struct ath6kl_vif
*vif
;
1239 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "%s: changed 0x%x\n", __func__
,
1242 vif
= ath6kl_vif_first(ar
);
1246 if (!ath6kl_cfg80211_ready(vif
))
1249 if (changed
& WIPHY_PARAM_RTS_THRESHOLD
) {
1250 ret
= ath6kl_wmi_set_rts_cmd(ar
->wmi
, wiphy
->rts_threshold
);
1252 ath6kl_err("ath6kl_wmi_set_rts_cmd failed\n");
1261 * The type nl80211_tx_power_setting replaces the following
1262 * data type from 2.6.36 onwards
1264 static int ath6kl_cfg80211_set_txpower(struct wiphy
*wiphy
,
1265 enum nl80211_tx_power_setting type
,
1268 struct ath6kl
*ar
= (struct ath6kl
*)wiphy_priv(wiphy
);
1269 struct ath6kl_vif
*vif
;
1271 int dbm
= MBM_TO_DBM(mbm
);
1273 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "%s: type 0x%x, dbm %d\n", __func__
,
1276 vif
= ath6kl_vif_first(ar
);
1280 if (!ath6kl_cfg80211_ready(vif
))
1284 case NL80211_TX_POWER_AUTOMATIC
:
1286 case NL80211_TX_POWER_LIMITED
:
1287 ar
->tx_pwr
= ath6kl_dbm
= dbm
;
1290 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "%s: type 0x%x not supported\n",
1295 ath6kl_wmi_set_tx_pwr_cmd(ar
->wmi
, vif
->fw_vif_idx
, ath6kl_dbm
);
1300 static int ath6kl_cfg80211_get_txpower(struct wiphy
*wiphy
, int *dbm
)
1302 struct ath6kl
*ar
= (struct ath6kl
*)wiphy_priv(wiphy
);
1303 struct ath6kl_vif
*vif
;
1305 vif
= ath6kl_vif_first(ar
);
1309 if (!ath6kl_cfg80211_ready(vif
))
1312 if (test_bit(CONNECTED
, &vif
->flags
)) {
1315 if (ath6kl_wmi_get_tx_pwr_cmd(ar
->wmi
, vif
->fw_vif_idx
) != 0) {
1316 ath6kl_err("ath6kl_wmi_get_tx_pwr_cmd failed\n");
1320 wait_event_interruptible_timeout(ar
->event_wq
, ar
->tx_pwr
!= 0,
1323 if (signal_pending(current
)) {
1324 ath6kl_err("target did not respond\n");
1333 static int ath6kl_cfg80211_set_power_mgmt(struct wiphy
*wiphy
,
1334 struct net_device
*dev
,
1335 bool pmgmt
, int timeout
)
1337 struct ath6kl
*ar
= ath6kl_priv(dev
);
1338 struct wmi_power_mode_cmd mode
;
1339 struct ath6kl_vif
*vif
= netdev_priv(dev
);
1341 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "%s: pmgmt %d, timeout %d\n",
1342 __func__
, pmgmt
, timeout
);
1344 if (!ath6kl_cfg80211_ready(vif
))
1348 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "%s: max perf\n", __func__
);
1349 mode
.pwr_mode
= REC_POWER
;
1351 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "%s: rec power\n", __func__
);
1352 mode
.pwr_mode
= MAX_PERF_POWER
;
1355 if (ath6kl_wmi_powermode_cmd(ar
->wmi
, vif
->fw_vif_idx
,
1356 mode
.pwr_mode
) != 0) {
1357 ath6kl_err("wmi_powermode_cmd failed\n");
1364 static struct net_device
*ath6kl_cfg80211_add_iface(struct wiphy
*wiphy
,
1366 enum nl80211_iftype type
,
1368 struct vif_params
*params
)
1370 struct ath6kl
*ar
= wiphy_priv(wiphy
);
1371 struct net_device
*ndev
;
1374 if (ar
->num_vif
== ar
->vif_max
) {
1375 ath6kl_err("Reached maximum number of supported vif\n");
1376 return ERR_PTR(-EINVAL
);
1379 if (!ath6kl_is_valid_iftype(ar
, type
, &if_idx
, &nw_type
)) {
1380 ath6kl_err("Not a supported interface type\n");
1381 return ERR_PTR(-EINVAL
);
1384 ndev
= ath6kl_interface_add(ar
, name
, type
, if_idx
, nw_type
);
1386 return ERR_PTR(-ENOMEM
);
1393 static int ath6kl_cfg80211_del_iface(struct wiphy
*wiphy
,
1394 struct net_device
*ndev
)
1396 struct ath6kl
*ar
= wiphy_priv(wiphy
);
1397 struct ath6kl_vif
*vif
= netdev_priv(ndev
);
1399 spin_lock_bh(&ar
->list_lock
);
1400 list_del(&vif
->list
);
1401 spin_unlock_bh(&ar
->list_lock
);
1403 ath6kl_cleanup_vif(vif
, test_bit(WMI_READY
, &ar
->flag
));
1405 ath6kl_deinit_if_data(vif
);
1410 static int ath6kl_cfg80211_change_iface(struct wiphy
*wiphy
,
1411 struct net_device
*ndev
,
1412 enum nl80211_iftype type
, u32
*flags
,
1413 struct vif_params
*params
)
1415 struct ath6kl_vif
*vif
= netdev_priv(ndev
);
1417 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "%s: type %u\n", __func__
, type
);
1420 case NL80211_IFTYPE_STATION
:
1421 vif
->next_mode
= INFRA_NETWORK
;
1423 case NL80211_IFTYPE_ADHOC
:
1424 vif
->next_mode
= ADHOC_NETWORK
;
1426 case NL80211_IFTYPE_AP
:
1427 vif
->next_mode
= AP_NETWORK
;
1429 case NL80211_IFTYPE_P2P_CLIENT
:
1430 vif
->next_mode
= INFRA_NETWORK
;
1432 case NL80211_IFTYPE_P2P_GO
:
1433 vif
->next_mode
= AP_NETWORK
;
1436 ath6kl_err("invalid interface type %u\n", type
);
1440 vif
->wdev
.iftype
= type
;
1445 static int ath6kl_cfg80211_join_ibss(struct wiphy
*wiphy
,
1446 struct net_device
*dev
,
1447 struct cfg80211_ibss_params
*ibss_param
)
1449 struct ath6kl
*ar
= ath6kl_priv(dev
);
1450 struct ath6kl_vif
*vif
= netdev_priv(dev
);
1453 if (!ath6kl_cfg80211_ready(vif
))
1456 vif
->ssid_len
= ibss_param
->ssid_len
;
1457 memcpy(vif
->ssid
, ibss_param
->ssid
, vif
->ssid_len
);
1459 if (ibss_param
->channel
)
1460 vif
->ch_hint
= ibss_param
->channel
->center_freq
;
1462 if (ibss_param
->channel_fixed
) {
1464 * TODO: channel_fixed: The channel should be fixed, do not
1465 * search for IBSSs to join on other channels. Target
1466 * firmware does not support this feature, needs to be
1472 memset(vif
->req_bssid
, 0, sizeof(vif
->req_bssid
));
1473 if (ibss_param
->bssid
&& !is_broadcast_ether_addr(ibss_param
->bssid
))
1474 memcpy(vif
->req_bssid
, ibss_param
->bssid
,
1475 sizeof(vif
->req_bssid
));
1477 ath6kl_set_wpa_version(vif
, 0);
1479 status
= ath6kl_set_auth_type(vif
, NL80211_AUTHTYPE_OPEN_SYSTEM
);
1483 if (ibss_param
->privacy
) {
1484 ath6kl_set_cipher(vif
, WLAN_CIPHER_SUITE_WEP40
, true);
1485 ath6kl_set_cipher(vif
, WLAN_CIPHER_SUITE_WEP40
, false);
1487 ath6kl_set_cipher(vif
, 0, true);
1488 ath6kl_set_cipher(vif
, 0, false);
1491 vif
->nw_type
= vif
->next_mode
;
1493 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
,
1494 "%s: connect called with authmode %d dot11 auth %d"
1495 " PW crypto %d PW crypto len %d GRP crypto %d"
1496 " GRP crypto len %d channel hint %u\n",
1498 vif
->auth_mode
, vif
->dot11_auth_mode
, vif
->prwise_crypto
,
1499 vif
->prwise_crypto_len
, vif
->grp_crypto
,
1500 vif
->grp_crypto_len
, vif
->ch_hint
);
1502 status
= ath6kl_wmi_connect_cmd(ar
->wmi
, vif
->fw_vif_idx
, vif
->nw_type
,
1503 vif
->dot11_auth_mode
, vif
->auth_mode
,
1505 vif
->prwise_crypto_len
,
1506 vif
->grp_crypto
, vif
->grp_crypto_len
,
1507 vif
->ssid_len
, vif
->ssid
,
1508 vif
->req_bssid
, vif
->ch_hint
,
1509 ar
->connect_ctrl_flags
, SUBTYPE_NONE
);
1510 set_bit(CONNECT_PEND
, &vif
->flags
);
1515 static int ath6kl_cfg80211_leave_ibss(struct wiphy
*wiphy
,
1516 struct net_device
*dev
)
1518 struct ath6kl_vif
*vif
= netdev_priv(dev
);
1520 if (!ath6kl_cfg80211_ready(vif
))
1523 ath6kl_disconnect(vif
);
1524 memset(vif
->ssid
, 0, sizeof(vif
->ssid
));
1530 static const u32 cipher_suites
[] = {
1531 WLAN_CIPHER_SUITE_WEP40
,
1532 WLAN_CIPHER_SUITE_WEP104
,
1533 WLAN_CIPHER_SUITE_TKIP
,
1534 WLAN_CIPHER_SUITE_CCMP
,
1535 CCKM_KRK_CIPHER_SUITE
,
1536 WLAN_CIPHER_SUITE_SMS4
,
1539 static bool is_rate_legacy(s32 rate
)
1541 static const s32 legacy
[] = { 1000, 2000, 5500, 11000,
1542 6000, 9000, 12000, 18000, 24000,
1547 for (i
= 0; i
< ARRAY_SIZE(legacy
); i
++)
1548 if (rate
== legacy
[i
])
1554 static bool is_rate_ht20(s32 rate
, u8
*mcs
, bool *sgi
)
1556 static const s32 ht20
[] = { 6500, 13000, 19500, 26000, 39000,
1557 52000, 58500, 65000, 72200
1561 for (i
= 0; i
< ARRAY_SIZE(ht20
); i
++) {
1562 if (rate
== ht20
[i
]) {
1563 if (i
== ARRAY_SIZE(ht20
) - 1)
1564 /* last rate uses sgi */
1576 static bool is_rate_ht40(s32 rate
, u8
*mcs
, bool *sgi
)
1578 static const s32 ht40
[] = { 13500, 27000, 40500, 54000,
1579 81000, 108000, 121500, 135000,
1584 for (i
= 0; i
< ARRAY_SIZE(ht40
); i
++) {
1585 if (rate
== ht40
[i
]) {
1586 if (i
== ARRAY_SIZE(ht40
) - 1)
1587 /* last rate uses sgi */
1600 static int ath6kl_get_station(struct wiphy
*wiphy
, struct net_device
*dev
,
1601 u8
*mac
, struct station_info
*sinfo
)
1603 struct ath6kl
*ar
= ath6kl_priv(dev
);
1604 struct ath6kl_vif
*vif
= netdev_priv(dev
);
1611 if (memcmp(mac
, vif
->bssid
, ETH_ALEN
) != 0)
1614 if (down_interruptible(&ar
->sem
))
1617 set_bit(STATS_UPDATE_PEND
, &vif
->flags
);
1619 ret
= ath6kl_wmi_get_stats_cmd(ar
->wmi
, vif
->fw_vif_idx
);
1626 left
= wait_event_interruptible_timeout(ar
->event_wq
,
1627 !test_bit(STATS_UPDATE_PEND
,
1638 if (vif
->target_stats
.rx_byte
) {
1639 sinfo
->rx_bytes
= vif
->target_stats
.rx_byte
;
1640 sinfo
->filled
|= STATION_INFO_RX_BYTES
;
1641 sinfo
->rx_packets
= vif
->target_stats
.rx_pkt
;
1642 sinfo
->filled
|= STATION_INFO_RX_PACKETS
;
1645 if (vif
->target_stats
.tx_byte
) {
1646 sinfo
->tx_bytes
= vif
->target_stats
.tx_byte
;
1647 sinfo
->filled
|= STATION_INFO_TX_BYTES
;
1648 sinfo
->tx_packets
= vif
->target_stats
.tx_pkt
;
1649 sinfo
->filled
|= STATION_INFO_TX_PACKETS
;
1652 sinfo
->signal
= vif
->target_stats
.cs_rssi
;
1653 sinfo
->filled
|= STATION_INFO_SIGNAL
;
1655 rate
= vif
->target_stats
.tx_ucast_rate
;
1657 if (is_rate_legacy(rate
)) {
1658 sinfo
->txrate
.legacy
= rate
/ 100;
1659 } else if (is_rate_ht20(rate
, &mcs
, &sgi
)) {
1661 sinfo
->txrate
.flags
|= RATE_INFO_FLAGS_SHORT_GI
;
1662 sinfo
->txrate
.mcs
= mcs
- 1;
1664 sinfo
->txrate
.mcs
= mcs
;
1667 sinfo
->txrate
.flags
|= RATE_INFO_FLAGS_MCS
;
1668 } else if (is_rate_ht40(rate
, &mcs
, &sgi
)) {
1670 sinfo
->txrate
.flags
|= RATE_INFO_FLAGS_SHORT_GI
;
1671 sinfo
->txrate
.mcs
= mcs
- 1;
1673 sinfo
->txrate
.mcs
= mcs
;
1676 sinfo
->txrate
.flags
|= RATE_INFO_FLAGS_40_MHZ_WIDTH
;
1677 sinfo
->txrate
.flags
|= RATE_INFO_FLAGS_MCS
;
1679 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
,
1680 "invalid rate from stats: %d\n", rate
);
1681 ath6kl_debug_war(ar
, ATH6KL_WAR_INVALID_RATE
);
1685 sinfo
->filled
|= STATION_INFO_TX_BITRATE
;
1687 if (test_bit(CONNECTED
, &vif
->flags
) &&
1688 test_bit(DTIM_PERIOD_AVAIL
, &vif
->flags
) &&
1689 vif
->nw_type
== INFRA_NETWORK
) {
1690 sinfo
->filled
|= STATION_INFO_BSS_PARAM
;
1691 sinfo
->bss_param
.flags
= 0;
1692 sinfo
->bss_param
.dtim_period
= vif
->assoc_bss_dtim_period
;
1693 sinfo
->bss_param
.beacon_interval
= vif
->assoc_bss_beacon_int
;
1699 static int ath6kl_set_pmksa(struct wiphy
*wiphy
, struct net_device
*netdev
,
1700 struct cfg80211_pmksa
*pmksa
)
1702 struct ath6kl
*ar
= ath6kl_priv(netdev
);
1703 struct ath6kl_vif
*vif
= netdev_priv(netdev
);
1705 return ath6kl_wmi_setpmkid_cmd(ar
->wmi
, vif
->fw_vif_idx
, pmksa
->bssid
,
1706 pmksa
->pmkid
, true);
1709 static int ath6kl_del_pmksa(struct wiphy
*wiphy
, struct net_device
*netdev
,
1710 struct cfg80211_pmksa
*pmksa
)
1712 struct ath6kl
*ar
= ath6kl_priv(netdev
);
1713 struct ath6kl_vif
*vif
= netdev_priv(netdev
);
1715 return ath6kl_wmi_setpmkid_cmd(ar
->wmi
, vif
->fw_vif_idx
, pmksa
->bssid
,
1716 pmksa
->pmkid
, false);
1719 static int ath6kl_flush_pmksa(struct wiphy
*wiphy
, struct net_device
*netdev
)
1721 struct ath6kl
*ar
= ath6kl_priv(netdev
);
1722 struct ath6kl_vif
*vif
= netdev_priv(netdev
);
1724 if (test_bit(CONNECTED
, &vif
->flags
))
1725 return ath6kl_wmi_setpmkid_cmd(ar
->wmi
, vif
->fw_vif_idx
,
1726 vif
->bssid
, NULL
, false);
1730 static int ath6kl_wow_suspend(struct ath6kl
*ar
, struct cfg80211_wowlan
*wow
)
1732 struct ath6kl_vif
*vif
;
1736 u8 mask
[WOW_MASK_SIZE
];
1738 vif
= ath6kl_vif_first(ar
);
1742 if (!ath6kl_cfg80211_ready(vif
))
1745 if (!test_bit(CONNECTED
, &vif
->flags
))
1748 /* Clear existing WOW patterns */
1749 for (i
= 0; i
< WOW_MAX_FILTERS_PER_LIST
; i
++)
1750 ath6kl_wmi_del_wow_pattern_cmd(ar
->wmi
, vif
->fw_vif_idx
,
1752 /* Configure new WOW patterns */
1753 for (i
= 0; i
< wow
->n_patterns
; i
++) {
1756 * Convert given nl80211 specific mask value to equivalent
1757 * driver specific mask value and send it to the chip along
1758 * with patterns. For example, If the mask value defined in
1759 * struct cfg80211_wowlan is 0xA (equivalent binary is 1010),
1760 * then equivalent driver specific mask value is
1761 * "0xFF 0x00 0xFF 0x00".
1763 memset(&mask
, 0, sizeof(mask
));
1764 for (pos
= 0; pos
< wow
->patterns
[i
].pattern_len
; pos
++) {
1765 if (wow
->patterns
[i
].mask
[pos
/ 8] & (0x1 << (pos
% 8)))
1769 * Note: Pattern's offset is not passed as part of wowlan
1770 * parameter from CFG layer. So it's always passed as ZERO
1771 * to the firmware. It means, given WOW patterns are always
1772 * matched from the first byte of received pkt in the firmware.
1774 ret
= ath6kl_wmi_add_wow_pattern_cmd(ar
->wmi
,
1775 vif
->fw_vif_idx
, WOW_LIST_ID
,
1776 wow
->patterns
[i
].pattern_len
,
1777 0 /* pattern offset */,
1778 wow
->patterns
[i
].pattern
, mask
);
1783 if (wow
->disconnect
)
1784 filter
|= WOW_FILTER_OPTION_NWK_DISASSOC
;
1787 filter
|= WOW_FILTER_OPTION_MAGIC_PACKET
;
1789 if (wow
->gtk_rekey_failure
)
1790 filter
|= WOW_FILTER_OPTION_GTK_ERROR
;
1792 if (wow
->eap_identity_req
)
1793 filter
|= WOW_FILTER_OPTION_EAP_REQ
;
1795 if (wow
->four_way_handshake
)
1796 filter
|= WOW_FILTER_OPTION_8021X_4WAYHS
;
1798 ret
= ath6kl_wmi_set_wow_mode_cmd(ar
->wmi
, vif
->fw_vif_idx
,
1799 ATH6KL_WOW_MODE_ENABLE
,
1801 WOW_HOST_REQ_DELAY
);
1805 ret
= ath6kl_wmi_set_host_sleep_mode_cmd(ar
->wmi
, vif
->fw_vif_idx
,
1806 ATH6KL_HOST_MODE_ASLEEP
);
1810 if (ar
->tx_pending
[ar
->ctrl_ep
]) {
1811 left
= wait_event_interruptible_timeout(ar
->event_wq
,
1812 ar
->tx_pending
[ar
->ctrl_ep
] == 0, WMI_TIMEOUT
);
1814 ath6kl_warn("clear wmi ctrl data timeout\n");
1816 } else if (left
< 0) {
1817 ath6kl_warn("clear wmi ctrl data failed: %d\n", left
);
1825 static int ath6kl_wow_resume(struct ath6kl
*ar
)
1827 struct ath6kl_vif
*vif
;
1830 vif
= ath6kl_vif_first(ar
);
1834 ret
= ath6kl_wmi_set_host_sleep_mode_cmd(ar
->wmi
, vif
->fw_vif_idx
,
1835 ATH6KL_HOST_MODE_AWAKE
);
1839 int ath6kl_cfg80211_suspend(struct ath6kl
*ar
,
1840 enum ath6kl_cfg_suspend_mode mode
,
1841 struct cfg80211_wowlan
*wow
)
1846 case ATH6KL_CFG_SUSPEND_WOW
:
1848 ath6kl_dbg(ATH6KL_DBG_SUSPEND
, "wow mode suspend\n");
1850 /* Flush all non control pkts in TX path */
1851 ath6kl_tx_data_cleanup(ar
);
1853 ret
= ath6kl_wow_suspend(ar
, wow
);
1855 ath6kl_err("wow suspend failed: %d\n", ret
);
1858 ar
->state
= ATH6KL_STATE_WOW
;
1861 case ATH6KL_CFG_SUSPEND_DEEPSLEEP
:
1863 ath6kl_cfg80211_stop_all(ar
);
1865 /* save the current power mode before enabling power save */
1866 ar
->wmi
->saved_pwr_mode
= ar
->wmi
->pwr_mode
;
1868 ret
= ath6kl_wmi_powermode_cmd(ar
->wmi
, 0, REC_POWER
);
1870 ath6kl_warn("wmi powermode command failed during suspend: %d\n",
1874 ar
->state
= ATH6KL_STATE_DEEPSLEEP
;
1878 case ATH6KL_CFG_SUSPEND_CUTPOWER
:
1880 ath6kl_cfg80211_stop_all(ar
);
1882 if (ar
->state
== ATH6KL_STATE_OFF
) {
1883 ath6kl_dbg(ATH6KL_DBG_SUSPEND
,
1884 "suspend hw off, no action for cutpower\n");
1888 ath6kl_dbg(ATH6KL_DBG_SUSPEND
, "suspend cutting power\n");
1890 ret
= ath6kl_init_hw_stop(ar
);
1892 ath6kl_warn("failed to stop hw during suspend: %d\n",
1896 ar
->state
= ATH6KL_STATE_CUTPOWER
;
1900 case ATH6KL_CFG_SUSPEND_SCHED_SCAN
:
1902 * Nothing needed for schedule scan, firmware is already in
1903 * wow mode and sleeping most of the time.
1914 int ath6kl_cfg80211_resume(struct ath6kl
*ar
)
1918 switch (ar
->state
) {
1919 case ATH6KL_STATE_WOW
:
1920 ath6kl_dbg(ATH6KL_DBG_SUSPEND
, "wow mode resume\n");
1922 ret
= ath6kl_wow_resume(ar
);
1924 ath6kl_warn("wow mode resume failed: %d\n", ret
);
1928 ar
->state
= ATH6KL_STATE_ON
;
1931 case ATH6KL_STATE_DEEPSLEEP
:
1932 if (ar
->wmi
->pwr_mode
!= ar
->wmi
->saved_pwr_mode
) {
1933 ret
= ath6kl_wmi_powermode_cmd(ar
->wmi
, 0,
1934 ar
->wmi
->saved_pwr_mode
);
1936 ath6kl_warn("wmi powermode command failed during resume: %d\n",
1941 ar
->state
= ATH6KL_STATE_ON
;
1945 case ATH6KL_STATE_CUTPOWER
:
1946 ath6kl_dbg(ATH6KL_DBG_SUSPEND
, "resume restoring power\n");
1948 ret
= ath6kl_init_hw_start(ar
);
1950 ath6kl_warn("Failed to boot hw in resume: %d\n", ret
);
1955 case ATH6KL_STATE_SCHED_SCAN
:
1967 /* hif layer decides what suspend mode to use */
1968 static int __ath6kl_cfg80211_suspend(struct wiphy
*wiphy
,
1969 struct cfg80211_wowlan
*wow
)
1971 struct ath6kl
*ar
= wiphy_priv(wiphy
);
1973 return ath6kl_hif_suspend(ar
, wow
);
1976 static int __ath6kl_cfg80211_resume(struct wiphy
*wiphy
)
1978 struct ath6kl
*ar
= wiphy_priv(wiphy
);
1980 return ath6kl_hif_resume(ar
);
1984 * FIXME: WOW suspend mode is selected if the host sdio controller supports
1985 * both sdio irq wake up and keep power. The target pulls sdio data line to
1986 * wake up the host when WOW pattern matches. This causes sdio irq handler
1987 * is being called in the host side which internally hits ath6kl's RX path.
1989 * Since sdio interrupt is not disabled, RX path executes even before
1990 * the host executes the actual resume operation from PM module.
1992 * In the current scenario, WOW resume should happen before start processing
1993 * any data from the target. So It's required to perform WOW resume in RX path.
1994 * Ideally we should perform WOW resume only in the actual platform
1995 * resume path. This area needs bit rework to avoid WOW resume in RX path.
1997 * ath6kl_check_wow_status() is called from ath6kl_rx().
1999 void ath6kl_check_wow_status(struct ath6kl
*ar
)
2001 if (ar
->state
== ATH6KL_STATE_WOW
)
2002 ath6kl_cfg80211_resume(ar
);
2007 void ath6kl_check_wow_status(struct ath6kl
*ar
)
2012 static int ath6kl_set_channel(struct wiphy
*wiphy
, struct net_device
*dev
,
2013 struct ieee80211_channel
*chan
,
2014 enum nl80211_channel_type channel_type
)
2016 struct ath6kl_vif
*vif
= netdev_priv(dev
);
2018 if (!ath6kl_cfg80211_ready(vif
))
2021 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "%s: center_freq=%u hw_value=%u\n",
2022 __func__
, chan
->center_freq
, chan
->hw_value
);
2023 vif
->next_chan
= chan
->center_freq
;
2028 static bool ath6kl_is_p2p_ie(const u8
*pos
)
2030 return pos
[0] == WLAN_EID_VENDOR_SPECIFIC
&& pos
[1] >= 4 &&
2031 pos
[2] == 0x50 && pos
[3] == 0x6f &&
2032 pos
[4] == 0x9a && pos
[5] == 0x09;
2035 static int ath6kl_set_ap_probe_resp_ies(struct ath6kl_vif
*vif
,
2036 const u8
*ies
, size_t ies_len
)
2038 struct ath6kl
*ar
= vif
->ar
;
2045 * Filter out P2P IE(s) since they will be included depending on
2046 * the Probe Request frame in ath6kl_send_go_probe_resp().
2049 if (ies
&& ies_len
) {
2050 buf
= kmalloc(ies_len
, GFP_KERNEL
);
2054 while (pos
+ 1 < ies
+ ies_len
) {
2055 if (pos
+ 2 + pos
[1] > ies
+ ies_len
)
2057 if (!ath6kl_is_p2p_ie(pos
)) {
2058 memcpy(buf
+ len
, pos
, 2 + pos
[1]);
2065 ret
= ath6kl_wmi_set_appie_cmd(ar
->wmi
, vif
->fw_vif_idx
,
2066 WMI_FRAME_PROBE_RESP
, buf
, len
);
2071 static int ath6kl_ap_beacon(struct wiphy
*wiphy
, struct net_device
*dev
,
2072 struct beacon_parameters
*info
, bool add
)
2074 struct ath6kl
*ar
= ath6kl_priv(dev
);
2075 struct ath6kl_vif
*vif
= netdev_priv(dev
);
2076 struct ieee80211_mgmt
*mgmt
;
2079 struct wmi_connect_cmd p
;
2083 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "%s: add=%d\n", __func__
, add
);
2085 if (!ath6kl_cfg80211_ready(vif
))
2088 if (vif
->next_mode
!= AP_NETWORK
)
2091 if (info
->beacon_ies
) {
2092 res
= ath6kl_wmi_set_appie_cmd(ar
->wmi
, vif
->fw_vif_idx
,
2095 info
->beacon_ies_len
);
2099 if (info
->proberesp_ies
) {
2100 res
= ath6kl_set_ap_probe_resp_ies(vif
, info
->proberesp_ies
,
2101 info
->proberesp_ies_len
);
2105 if (info
->assocresp_ies
) {
2106 res
= ath6kl_wmi_set_appie_cmd(ar
->wmi
, vif
->fw_vif_idx
,
2107 WMI_FRAME_ASSOC_RESP
,
2108 info
->assocresp_ies
,
2109 info
->assocresp_ies_len
);
2117 ar
->ap_mode_bkey
.valid
= false;
2124 if (info
->head
== NULL
)
2126 mgmt
= (struct ieee80211_mgmt
*) info
->head
;
2127 ies
= mgmt
->u
.beacon
.variable
;
2128 if (ies
> info
->head
+ info
->head_len
)
2130 ies_len
= info
->head
+ info
->head_len
- ies
;
2132 if (info
->ssid
== NULL
)
2134 memcpy(vif
->ssid
, info
->ssid
, info
->ssid_len
);
2135 vif
->ssid_len
= info
->ssid_len
;
2136 if (info
->hidden_ssid
!= NL80211_HIDDEN_SSID_NOT_IN_USE
)
2137 return -EOPNOTSUPP
; /* TODO */
2139 ret
= ath6kl_set_auth_type(vif
, info
->auth_type
);
2143 memset(&p
, 0, sizeof(p
));
2145 for (i
= 0; i
< info
->crypto
.n_akm_suites
; i
++) {
2146 switch (info
->crypto
.akm_suites
[i
]) {
2147 case WLAN_AKM_SUITE_8021X
:
2148 if (info
->crypto
.wpa_versions
& NL80211_WPA_VERSION_1
)
2149 p
.auth_mode
|= WPA_AUTH
;
2150 if (info
->crypto
.wpa_versions
& NL80211_WPA_VERSION_2
)
2151 p
.auth_mode
|= WPA2_AUTH
;
2153 case WLAN_AKM_SUITE_PSK
:
2154 if (info
->crypto
.wpa_versions
& NL80211_WPA_VERSION_1
)
2155 p
.auth_mode
|= WPA_PSK_AUTH
;
2156 if (info
->crypto
.wpa_versions
& NL80211_WPA_VERSION_2
)
2157 p
.auth_mode
|= WPA2_PSK_AUTH
;
2161 if (p
.auth_mode
== 0)
2162 p
.auth_mode
= NONE_AUTH
;
2163 vif
->auth_mode
= p
.auth_mode
;
2165 for (i
= 0; i
< info
->crypto
.n_ciphers_pairwise
; i
++) {
2166 switch (info
->crypto
.ciphers_pairwise
[i
]) {
2167 case WLAN_CIPHER_SUITE_WEP40
:
2168 case WLAN_CIPHER_SUITE_WEP104
:
2169 p
.prwise_crypto_type
|= WEP_CRYPT
;
2171 case WLAN_CIPHER_SUITE_TKIP
:
2172 p
.prwise_crypto_type
|= TKIP_CRYPT
;
2174 case WLAN_CIPHER_SUITE_CCMP
:
2175 p
.prwise_crypto_type
|= AES_CRYPT
;
2177 case WLAN_CIPHER_SUITE_SMS4
:
2178 p
.prwise_crypto_type
|= WAPI_CRYPT
;
2182 if (p
.prwise_crypto_type
== 0) {
2183 p
.prwise_crypto_type
= NONE_CRYPT
;
2184 ath6kl_set_cipher(vif
, 0, true);
2185 } else if (info
->crypto
.n_ciphers_pairwise
== 1)
2186 ath6kl_set_cipher(vif
, info
->crypto
.ciphers_pairwise
[0], true);
2188 switch (info
->crypto
.cipher_group
) {
2189 case WLAN_CIPHER_SUITE_WEP40
:
2190 case WLAN_CIPHER_SUITE_WEP104
:
2191 p
.grp_crypto_type
= WEP_CRYPT
;
2193 case WLAN_CIPHER_SUITE_TKIP
:
2194 p
.grp_crypto_type
= TKIP_CRYPT
;
2196 case WLAN_CIPHER_SUITE_CCMP
:
2197 p
.grp_crypto_type
= AES_CRYPT
;
2199 case WLAN_CIPHER_SUITE_SMS4
:
2200 p
.grp_crypto_type
= WAPI_CRYPT
;
2203 p
.grp_crypto_type
= NONE_CRYPT
;
2206 ath6kl_set_cipher(vif
, info
->crypto
.cipher_group
, false);
2208 p
.nw_type
= AP_NETWORK
;
2209 vif
->nw_type
= vif
->next_mode
;
2211 p
.ssid_len
= vif
->ssid_len
;
2212 memcpy(p
.ssid
, vif
->ssid
, vif
->ssid_len
);
2213 p
.dot11_auth_mode
= vif
->dot11_auth_mode
;
2214 p
.ch
= cpu_to_le16(vif
->next_chan
);
2216 if (vif
->wdev
.iftype
== NL80211_IFTYPE_P2P_GO
) {
2217 p
.nw_subtype
= SUBTYPE_P2PGO
;
2220 * Due to firmware limitation, it is not possible to
2221 * do P2P mgmt operations in AP mode
2223 p
.nw_subtype
= SUBTYPE_NONE
;
2226 res
= ath6kl_wmi_ap_profile_commit(ar
->wmi
, vif
->fw_vif_idx
, &p
);
2233 static int ath6kl_add_beacon(struct wiphy
*wiphy
, struct net_device
*dev
,
2234 struct beacon_parameters
*info
)
2236 return ath6kl_ap_beacon(wiphy
, dev
, info
, true);
2239 static int ath6kl_set_beacon(struct wiphy
*wiphy
, struct net_device
*dev
,
2240 struct beacon_parameters
*info
)
2242 return ath6kl_ap_beacon(wiphy
, dev
, info
, false);
2245 static int ath6kl_del_beacon(struct wiphy
*wiphy
, struct net_device
*dev
)
2247 struct ath6kl
*ar
= ath6kl_priv(dev
);
2248 struct ath6kl_vif
*vif
= netdev_priv(dev
);
2250 if (vif
->nw_type
!= AP_NETWORK
)
2252 if (!test_bit(CONNECTED
, &vif
->flags
))
2255 ath6kl_wmi_disconnect_cmd(ar
->wmi
, vif
->fw_vif_idx
);
2256 clear_bit(CONNECTED
, &vif
->flags
);
2261 static int ath6kl_change_station(struct wiphy
*wiphy
, struct net_device
*dev
,
2262 u8
*mac
, struct station_parameters
*params
)
2264 struct ath6kl
*ar
= ath6kl_priv(dev
);
2265 struct ath6kl_vif
*vif
= netdev_priv(dev
);
2267 if (vif
->nw_type
!= AP_NETWORK
)
2270 /* Use this only for authorizing/unauthorizing a station */
2271 if (!(params
->sta_flags_mask
& BIT(NL80211_STA_FLAG_AUTHORIZED
)))
2274 if (params
->sta_flags_set
& BIT(NL80211_STA_FLAG_AUTHORIZED
))
2275 return ath6kl_wmi_ap_set_mlme(ar
->wmi
, vif
->fw_vif_idx
,
2276 WMI_AP_MLME_AUTHORIZE
, mac
, 0);
2277 return ath6kl_wmi_ap_set_mlme(ar
->wmi
, vif
->fw_vif_idx
,
2278 WMI_AP_MLME_UNAUTHORIZE
, mac
, 0);
2281 static int ath6kl_remain_on_channel(struct wiphy
*wiphy
,
2282 struct net_device
*dev
,
2283 struct ieee80211_channel
*chan
,
2284 enum nl80211_channel_type channel_type
,
2285 unsigned int duration
,
2288 struct ath6kl
*ar
= ath6kl_priv(dev
);
2289 struct ath6kl_vif
*vif
= netdev_priv(dev
);
2292 /* TODO: if already pending or ongoing remain-on-channel,
2294 id
= ++vif
->last_roc_id
;
2296 /* Do not use 0 as the cookie value */
2297 id
= ++vif
->last_roc_id
;
2301 return ath6kl_wmi_remain_on_chnl_cmd(ar
->wmi
, vif
->fw_vif_idx
,
2302 chan
->center_freq
, duration
);
2305 static int ath6kl_cancel_remain_on_channel(struct wiphy
*wiphy
,
2306 struct net_device
*dev
,
2309 struct ath6kl
*ar
= ath6kl_priv(dev
);
2310 struct ath6kl_vif
*vif
= netdev_priv(dev
);
2312 if (cookie
!= vif
->last_roc_id
)
2314 vif
->last_cancel_roc_id
= cookie
;
2316 return ath6kl_wmi_cancel_remain_on_chnl_cmd(ar
->wmi
, vif
->fw_vif_idx
);
2319 static int ath6kl_send_go_probe_resp(struct ath6kl_vif
*vif
,
2320 const u8
*buf
, size_t len
,
2323 struct ath6kl
*ar
= vif
->ar
;
2328 const struct ieee80211_mgmt
*mgmt
;
2330 mgmt
= (const struct ieee80211_mgmt
*) buf
;
2332 /* Include P2P IE(s) from the frame generated in user space. */
2334 p2p
= kmalloc(len
, GFP_KERNEL
);
2339 pos
= mgmt
->u
.probe_resp
.variable
;
2340 while (pos
+ 1 < buf
+ len
) {
2341 if (pos
+ 2 + pos
[1] > buf
+ len
)
2343 if (ath6kl_is_p2p_ie(pos
)) {
2344 memcpy(p2p
+ p2p_len
, pos
, 2 + pos
[1]);
2345 p2p_len
+= 2 + pos
[1];
2350 ret
= ath6kl_wmi_send_probe_response_cmd(ar
->wmi
, vif
->fw_vif_idx
, freq
,
2351 mgmt
->da
, p2p
, p2p_len
);
2356 static int ath6kl_mgmt_tx(struct wiphy
*wiphy
, struct net_device
*dev
,
2357 struct ieee80211_channel
*chan
, bool offchan
,
2358 enum nl80211_channel_type channel_type
,
2359 bool channel_type_valid
, unsigned int wait
,
2360 const u8
*buf
, size_t len
, bool no_cck
,
2361 bool dont_wait_for_ack
, u64
*cookie
)
2363 struct ath6kl
*ar
= ath6kl_priv(dev
);
2364 struct ath6kl_vif
*vif
= netdev_priv(dev
);
2366 const struct ieee80211_mgmt
*mgmt
;
2368 mgmt
= (const struct ieee80211_mgmt
*) buf
;
2369 if (buf
+ len
>= mgmt
->u
.probe_resp
.variable
&&
2370 vif
->nw_type
== AP_NETWORK
&& test_bit(CONNECTED
, &vif
->flags
) &&
2371 ieee80211_is_probe_resp(mgmt
->frame_control
)) {
2373 * Send Probe Response frame in AP mode using a separate WMI
2374 * command to allow the target to fill in the generic IEs.
2376 *cookie
= 0; /* TX status not supported */
2377 return ath6kl_send_go_probe_resp(vif
, buf
, len
,
2381 id
= vif
->send_action_id
++;
2384 * 0 is a reserved value in the WMI command and shall not be
2385 * used for the command.
2387 id
= vif
->send_action_id
++;
2392 if (test_bit(ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX
,
2393 ar
->fw_capabilities
)) {
2395 * If capable of doing P2P mgmt operations using
2396 * station interface, send additional information like
2397 * supported rates to advertise and xmit rates for
2400 return ath6kl_wmi_send_mgmt_cmd(ar
->wmi
, vif
->fw_vif_idx
, id
,
2401 chan
->center_freq
, wait
,
2404 return ath6kl_wmi_send_action_cmd(ar
->wmi
, vif
->fw_vif_idx
, id
,
2405 chan
->center_freq
, wait
,
2410 static void ath6kl_mgmt_frame_register(struct wiphy
*wiphy
,
2411 struct net_device
*dev
,
2412 u16 frame_type
, bool reg
)
2414 struct ath6kl_vif
*vif
= netdev_priv(dev
);
2416 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG
, "%s: frame_type=0x%x reg=%d\n",
2417 __func__
, frame_type
, reg
);
2418 if (frame_type
== IEEE80211_STYPE_PROBE_REQ
) {
2420 * Note: This notification callback is not allowed to sleep, so
2421 * we cannot send WMI_PROBE_REQ_REPORT_CMD here. Instead, we
2422 * hardcode target to report Probe Request frames all the time.
2424 vif
->probe_req_report
= reg
;
2428 static int ath6kl_cfg80211_sscan_start(struct wiphy
*wiphy
,
2429 struct net_device
*dev
,
2430 struct cfg80211_sched_scan_request
*request
)
2432 struct ath6kl
*ar
= ath6kl_priv(dev
);
2433 struct ath6kl_vif
*vif
= netdev_priv(dev
);
2438 if (ar
->state
!= ATH6KL_STATE_ON
)
2441 if (vif
->sme_state
!= SME_DISCONNECTED
)
2444 for (i
= 0; i
< ar
->wiphy
->max_sched_scan_ssids
; i
++) {
2445 ath6kl_wmi_probedssid_cmd(ar
->wmi
, vif
->fw_vif_idx
,
2446 i
, DISABLE_SSID_FLAG
,
2450 /* fw uses seconds, also make sure that it's >0 */
2451 interval
= max_t(u16
, 1, request
->interval
/ 1000);
2453 ath6kl_wmi_scanparams_cmd(ar
->wmi
, vif
->fw_vif_idx
,
2455 10, 0, 0, 0, 3, 0, 0, 0);
2457 if (request
->n_ssids
&& request
->ssids
[0].ssid_len
) {
2458 for (i
= 0; i
< request
->n_ssids
; i
++) {
2459 ath6kl_wmi_probedssid_cmd(ar
->wmi
, vif
->fw_vif_idx
,
2460 i
, SPECIFIC_SSID_FLAG
,
2461 request
->ssids
[i
].ssid_len
,
2462 request
->ssids
[i
].ssid
);
2466 ret
= ath6kl_wmi_set_wow_mode_cmd(ar
->wmi
, vif
->fw_vif_idx
,
2467 ATH6KL_WOW_MODE_ENABLE
,
2469 WOW_HOST_REQ_DELAY
);
2471 ath6kl_warn("Failed to enable wow with ssid filter: %d\n", ret
);
2475 /* this also clears IE in fw if it's not set */
2476 ret
= ath6kl_wmi_set_appie_cmd(ar
->wmi
, vif
->fw_vif_idx
,
2477 WMI_FRAME_PROBE_REQ
,
2478 request
->ie
, request
->ie_len
);
2480 ath6kl_warn("Failed to set probe request IE for scheduled scan: %d",
2485 ret
= ath6kl_wmi_set_host_sleep_mode_cmd(ar
->wmi
, vif
->fw_vif_idx
,
2486 ATH6KL_HOST_MODE_ASLEEP
);
2488 ath6kl_warn("Failed to enable host sleep mode for sched scan: %d\n",
2493 ar
->state
= ATH6KL_STATE_SCHED_SCAN
;
2498 static int ath6kl_cfg80211_sscan_stop(struct wiphy
*wiphy
,
2499 struct net_device
*dev
)
2501 struct ath6kl_vif
*vif
= netdev_priv(dev
);
2504 stopped
= __ath6kl_cfg80211_sscan_stop(vif
);
2512 static const struct ieee80211_txrx_stypes
2513 ath6kl_mgmt_stypes
[NUM_NL80211_IFTYPES
] = {
2514 [NL80211_IFTYPE_STATION
] = {
2515 .tx
= BIT(IEEE80211_STYPE_ACTION
>> 4) |
2516 BIT(IEEE80211_STYPE_PROBE_RESP
>> 4),
2517 .rx
= BIT(IEEE80211_STYPE_ACTION
>> 4) |
2518 BIT(IEEE80211_STYPE_PROBE_REQ
>> 4)
2520 [NL80211_IFTYPE_P2P_CLIENT
] = {
2521 .tx
= BIT(IEEE80211_STYPE_ACTION
>> 4) |
2522 BIT(IEEE80211_STYPE_PROBE_RESP
>> 4),
2523 .rx
= BIT(IEEE80211_STYPE_ACTION
>> 4) |
2524 BIT(IEEE80211_STYPE_PROBE_REQ
>> 4)
2526 [NL80211_IFTYPE_P2P_GO
] = {
2527 .tx
= BIT(IEEE80211_STYPE_ACTION
>> 4) |
2528 BIT(IEEE80211_STYPE_PROBE_RESP
>> 4),
2529 .rx
= BIT(IEEE80211_STYPE_ACTION
>> 4) |
2530 BIT(IEEE80211_STYPE_PROBE_REQ
>> 4)
2534 static struct cfg80211_ops ath6kl_cfg80211_ops
= {
2535 .add_virtual_intf
= ath6kl_cfg80211_add_iface
,
2536 .del_virtual_intf
= ath6kl_cfg80211_del_iface
,
2537 .change_virtual_intf
= ath6kl_cfg80211_change_iface
,
2538 .scan
= ath6kl_cfg80211_scan
,
2539 .connect
= ath6kl_cfg80211_connect
,
2540 .disconnect
= ath6kl_cfg80211_disconnect
,
2541 .add_key
= ath6kl_cfg80211_add_key
,
2542 .get_key
= ath6kl_cfg80211_get_key
,
2543 .del_key
= ath6kl_cfg80211_del_key
,
2544 .set_default_key
= ath6kl_cfg80211_set_default_key
,
2545 .set_wiphy_params
= ath6kl_cfg80211_set_wiphy_params
,
2546 .set_tx_power
= ath6kl_cfg80211_set_txpower
,
2547 .get_tx_power
= ath6kl_cfg80211_get_txpower
,
2548 .set_power_mgmt
= ath6kl_cfg80211_set_power_mgmt
,
2549 .join_ibss
= ath6kl_cfg80211_join_ibss
,
2550 .leave_ibss
= ath6kl_cfg80211_leave_ibss
,
2551 .get_station
= ath6kl_get_station
,
2552 .set_pmksa
= ath6kl_set_pmksa
,
2553 .del_pmksa
= ath6kl_del_pmksa
,
2554 .flush_pmksa
= ath6kl_flush_pmksa
,
2555 CFG80211_TESTMODE_CMD(ath6kl_tm_cmd
)
2557 .suspend
= __ath6kl_cfg80211_suspend
,
2558 .resume
= __ath6kl_cfg80211_resume
,
2560 .set_channel
= ath6kl_set_channel
,
2561 .add_beacon
= ath6kl_add_beacon
,
2562 .set_beacon
= ath6kl_set_beacon
,
2563 .del_beacon
= ath6kl_del_beacon
,
2564 .change_station
= ath6kl_change_station
,
2565 .remain_on_channel
= ath6kl_remain_on_channel
,
2566 .cancel_remain_on_channel
= ath6kl_cancel_remain_on_channel
,
2567 .mgmt_tx
= ath6kl_mgmt_tx
,
2568 .mgmt_frame_register
= ath6kl_mgmt_frame_register
,
2569 .sched_scan_start
= ath6kl_cfg80211_sscan_start
,
2570 .sched_scan_stop
= ath6kl_cfg80211_sscan_stop
,
2573 void ath6kl_cfg80211_stop(struct ath6kl_vif
*vif
)
2575 ath6kl_cfg80211_sscan_disable(vif
);
2577 switch (vif
->sme_state
) {
2578 case SME_DISCONNECTED
:
2580 case SME_CONNECTING
:
2581 cfg80211_connect_result(vif
->ndev
, vif
->bssid
, NULL
, 0,
2583 WLAN_STATUS_UNSPECIFIED_FAILURE
,
2587 cfg80211_disconnected(vif
->ndev
, 0, NULL
, 0, GFP_KERNEL
);
2591 if (test_bit(CONNECTED
, &vif
->flags
) ||
2592 test_bit(CONNECT_PEND
, &vif
->flags
))
2593 ath6kl_wmi_disconnect_cmd(vif
->ar
->wmi
, vif
->fw_vif_idx
);
2595 vif
->sme_state
= SME_DISCONNECTED
;
2596 clear_bit(CONNECTED
, &vif
->flags
);
2597 clear_bit(CONNECT_PEND
, &vif
->flags
);
2599 /* disable scanning */
2600 if (ath6kl_wmi_scanparams_cmd(vif
->ar
->wmi
, vif
->fw_vif_idx
, 0xFFFF,
2601 0, 0, 0, 0, 0, 0, 0, 0, 0) != 0)
2602 ath6kl_warn("failed to disable scan during stop\n");
2604 ath6kl_cfg80211_scan_complete_event(vif
, true);
2607 void ath6kl_cfg80211_stop_all(struct ath6kl
*ar
)
2609 struct ath6kl_vif
*vif
;
2611 vif
= ath6kl_vif_first(ar
);
2613 /* save the current power mode before enabling power save */
2614 ar
->wmi
->saved_pwr_mode
= ar
->wmi
->pwr_mode
;
2616 if (ath6kl_wmi_powermode_cmd(ar
->wmi
, 0, REC_POWER
) != 0)
2617 ath6kl_warn("ath6kl_deep_sleep_enable: "
2618 "wmi_powermode_cmd failed\n");
2623 * FIXME: we should take ar->list_lock to protect changes in the
2624 * vif_list, but that's not trivial to do as ath6kl_cfg80211_stop()
2627 list_for_each_entry(vif
, &ar
->vif_list
, list
)
2628 ath6kl_cfg80211_stop(vif
);
2631 struct ath6kl
*ath6kl_core_alloc(struct device
*dev
)
2634 struct wiphy
*wiphy
;
2637 /* create a new wiphy for use with cfg80211 */
2638 wiphy
= wiphy_new(&ath6kl_cfg80211_ops
, sizeof(struct ath6kl
));
2641 ath6kl_err("couldn't allocate wiphy device\n");
2645 ar
= wiphy_priv(wiphy
);
2646 ar
->p2p
= !!ath6kl_p2p
;
2652 ar
->max_norm_iface
= 1;
2654 spin_lock_init(&ar
->lock
);
2655 spin_lock_init(&ar
->mcastpsq_lock
);
2656 spin_lock_init(&ar
->list_lock
);
2658 init_waitqueue_head(&ar
->event_wq
);
2659 sema_init(&ar
->sem
, 1);
2661 INIT_LIST_HEAD(&ar
->amsdu_rx_buffer_queue
);
2662 INIT_LIST_HEAD(&ar
->vif_list
);
2664 clear_bit(WMI_ENABLED
, &ar
->flag
);
2665 clear_bit(SKIP_SCAN
, &ar
->flag
);
2666 clear_bit(DESTROY_IN_PROGRESS
, &ar
->flag
);
2668 ar
->listen_intvl_t
= A_DEFAULT_LISTEN_INTERVAL
;
2669 ar
->listen_intvl_b
= 0;
2673 ar
->lrssi_roam_threshold
= DEF_LRSSI_ROAM_THRESHOLD
;
2675 ar
->state
= ATH6KL_STATE_OFF
;
2677 memset((u8
*)ar
->sta_list
, 0,
2678 AP_MAX_NUM_STA
* sizeof(struct ath6kl_sta
));
2680 /* Init the PS queues */
2681 for (ctr
= 0; ctr
< AP_MAX_NUM_STA
; ctr
++) {
2682 spin_lock_init(&ar
->sta_list
[ctr
].psq_lock
);
2683 skb_queue_head_init(&ar
->sta_list
[ctr
].psq
);
2686 skb_queue_head_init(&ar
->mcastpsq
);
2688 memcpy(ar
->ap_country_code
, DEF_AP_COUNTRY_CODE
, 3);
2693 int ath6kl_register_ieee80211_hw(struct ath6kl
*ar
)
2695 struct wiphy
*wiphy
= ar
->wiphy
;
2698 wiphy
->mgmt_stypes
= ath6kl_mgmt_stypes
;
2700 wiphy
->max_remain_on_channel_duration
= 5000;
2702 /* set device pointer for wiphy */
2703 set_wiphy_dev(wiphy
, ar
->dev
);
2705 wiphy
->interface_modes
= BIT(NL80211_IFTYPE_STATION
) |
2706 BIT(NL80211_IFTYPE_ADHOC
) |
2707 BIT(NL80211_IFTYPE_AP
);
2709 wiphy
->interface_modes
|= BIT(NL80211_IFTYPE_P2P_GO
) |
2710 BIT(NL80211_IFTYPE_P2P_CLIENT
);
2713 /* max num of ssids that can be probed during scanning */
2714 wiphy
->max_scan_ssids
= MAX_PROBED_SSID_INDEX
;
2715 wiphy
->max_scan_ie_len
= 1000; /* FIX: what is correct limit? */
2716 wiphy
->bands
[IEEE80211_BAND_2GHZ
] = &ath6kl_band_2ghz
;
2717 wiphy
->bands
[IEEE80211_BAND_5GHZ
] = &ath6kl_band_5ghz
;
2718 wiphy
->signal_type
= CFG80211_SIGNAL_TYPE_MBM
;
2720 wiphy
->cipher_suites
= cipher_suites
;
2721 wiphy
->n_cipher_suites
= ARRAY_SIZE(cipher_suites
);
2723 wiphy
->wowlan
.flags
= WIPHY_WOWLAN_MAGIC_PKT
|
2724 WIPHY_WOWLAN_DISCONNECT
|
2725 WIPHY_WOWLAN_GTK_REKEY_FAILURE
|
2726 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY
|
2727 WIPHY_WOWLAN_EAP_IDENTITY_REQ
|
2728 WIPHY_WOWLAN_4WAY_HANDSHAKE
;
2729 wiphy
->wowlan
.n_patterns
= WOW_MAX_FILTERS_PER_LIST
;
2730 wiphy
->wowlan
.pattern_min_len
= 1;
2731 wiphy
->wowlan
.pattern_max_len
= WOW_PATTERN_SIZE
;
2733 wiphy
->max_sched_scan_ssids
= 10;
2735 ret
= wiphy_register(wiphy
);
2737 ath6kl_err("couldn't register wiphy device\n");
2744 static int ath6kl_init_if_data(struct ath6kl_vif
*vif
)
2746 vif
->aggr_cntxt
= aggr_init(vif
->ndev
);
2747 if (!vif
->aggr_cntxt
) {
2748 ath6kl_err("failed to initialize aggr\n");
2752 setup_timer(&vif
->disconnect_timer
, disconnect_timer_handler
,
2753 (unsigned long) vif
->ndev
);
2754 setup_timer(&vif
->sched_scan_timer
, ath6kl_wmi_sscan_timer
,
2755 (unsigned long) vif
);
2757 set_bit(WMM_ENABLED
, &vif
->flags
);
2758 spin_lock_init(&vif
->if_lock
);
2763 void ath6kl_deinit_if_data(struct ath6kl_vif
*vif
)
2765 struct ath6kl
*ar
= vif
->ar
;
2767 aggr_module_destroy(vif
->aggr_cntxt
);
2769 ar
->avail_idx_map
|= BIT(vif
->fw_vif_idx
);
2771 if (vif
->nw_type
== ADHOC_NETWORK
)
2772 ar
->ibss_if_active
= false;
2774 unregister_netdevice(vif
->ndev
);
2779 struct net_device
*ath6kl_interface_add(struct ath6kl
*ar
, char *name
,
2780 enum nl80211_iftype type
, u8 fw_vif_idx
,
2783 struct net_device
*ndev
;
2784 struct ath6kl_vif
*vif
;
2786 ndev
= alloc_netdev(sizeof(*vif
), name
, ether_setup
);
2790 vif
= netdev_priv(ndev
);
2791 ndev
->ieee80211_ptr
= &vif
->wdev
;
2792 vif
->wdev
.wiphy
= ar
->wiphy
;
2795 SET_NETDEV_DEV(ndev
, wiphy_dev(vif
->wdev
.wiphy
));
2796 vif
->wdev
.netdev
= ndev
;
2797 vif
->wdev
.iftype
= type
;
2798 vif
->fw_vif_idx
= fw_vif_idx
;
2799 vif
->nw_type
= vif
->next_mode
= nw_type
;
2801 memcpy(ndev
->dev_addr
, ar
->mac_addr
, ETH_ALEN
);
2802 if (fw_vif_idx
!= 0)
2803 ndev
->dev_addr
[0] = (ndev
->dev_addr
[0] ^ (1 << fw_vif_idx
)) |
2808 ath6kl_init_control_info(vif
);
2810 /* TODO: Pass interface specific pointer instead of ar */
2811 if (ath6kl_init_if_data(vif
))
2814 if (register_netdevice(ndev
))
2817 ar
->avail_idx_map
&= ~BIT(fw_vif_idx
);
2818 vif
->sme_state
= SME_DISCONNECTED
;
2819 set_bit(WLAN_ENABLED
, &vif
->flags
);
2820 ar
->wlan_pwr_state
= WLAN_POWER_STATE_ON
;
2821 set_bit(NETDEV_REGISTERED
, &vif
->flags
);
2823 if (type
== NL80211_IFTYPE_ADHOC
)
2824 ar
->ibss_if_active
= true;
2826 spin_lock_bh(&ar
->list_lock
);
2827 list_add_tail(&vif
->list
, &ar
->vif_list
);
2828 spin_unlock_bh(&ar
->list_lock
);
2833 aggr_module_destroy(vif
->aggr_cntxt
);
2838 void ath6kl_deinit_ieee80211_hw(struct ath6kl
*ar
)
2840 wiphy_unregister(ar
->wiphy
);
2841 wiphy_free(ar
->wiphy
);