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.
23 static unsigned int ath6kl_p2p;
24 static unsigned int multi_norm_if_support;
26 module_param(ath6kl_p2p, uint, 0644);
27 module_param(multi_norm_if_support, 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 static int ath6kl_set_wpa_version(struct ath6kl_vif *vif,
129 enum nl80211_wpa_versions wpa_version)
131 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: %u\n", __func__, wpa_version);
134 vif->auth_mode = NONE_AUTH;
135 } else if (wpa_version & NL80211_WPA_VERSION_2) {
136 vif->auth_mode = WPA2_AUTH;
137 } else if (wpa_version & NL80211_WPA_VERSION_1) {
138 vif->auth_mode = WPA_AUTH;
140 ath6kl_err("%s: %u not supported\n", __func__, wpa_version);
147 static int ath6kl_set_auth_type(struct ath6kl_vif *vif,
148 enum nl80211_auth_type auth_type)
150 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: 0x%x\n", __func__, auth_type);
153 case NL80211_AUTHTYPE_OPEN_SYSTEM:
154 vif->dot11_auth_mode = OPEN_AUTH;
156 case NL80211_AUTHTYPE_SHARED_KEY:
157 vif->dot11_auth_mode = SHARED_AUTH;
159 case NL80211_AUTHTYPE_NETWORK_EAP:
160 vif->dot11_auth_mode = LEAP_AUTH;
163 case NL80211_AUTHTYPE_AUTOMATIC:
164 vif->dot11_auth_mode = OPEN_AUTH | SHARED_AUTH;
168 ath6kl_err("%s: 0x%x not spported\n", __func__, auth_type);
175 static int ath6kl_set_cipher(struct ath6kl_vif *vif, u32 cipher, bool ucast)
177 u8 *ar_cipher = ucast ? &vif->prwise_crypto : &vif->grp_crypto;
178 u8 *ar_cipher_len = ucast ? &vif->prwise_crypto_len :
179 &vif->grp_crypto_len;
181 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: cipher 0x%x, ucast %u\n",
182 __func__, cipher, ucast);
186 /* our own hack to use value 0 as no crypto used */
187 *ar_cipher = NONE_CRYPT;
190 case WLAN_CIPHER_SUITE_WEP40:
191 *ar_cipher = WEP_CRYPT;
194 case WLAN_CIPHER_SUITE_WEP104:
195 *ar_cipher = WEP_CRYPT;
198 case WLAN_CIPHER_SUITE_TKIP:
199 *ar_cipher = TKIP_CRYPT;
202 case WLAN_CIPHER_SUITE_CCMP:
203 *ar_cipher = AES_CRYPT;
206 case WLAN_CIPHER_SUITE_SMS4:
207 *ar_cipher = WAPI_CRYPT;
211 ath6kl_err("cipher 0x%x not supported\n", cipher);
218 static void ath6kl_set_key_mgmt(struct ath6kl_vif *vif, u32 key_mgmt)
220 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: 0x%x\n", __func__, key_mgmt);
222 if (key_mgmt == WLAN_AKM_SUITE_PSK) {
223 if (vif->auth_mode == WPA_AUTH)
224 vif->auth_mode = WPA_PSK_AUTH;
225 else if (vif->auth_mode == WPA2_AUTH)
226 vif->auth_mode = WPA2_PSK_AUTH;
227 } else if (key_mgmt == 0x00409600) {
228 if (vif->auth_mode == WPA_AUTH)
229 vif->auth_mode = WPA_AUTH_CCKM;
230 else if (vif->auth_mode == WPA2_AUTH)
231 vif->auth_mode = WPA2_AUTH_CCKM;
232 } else if (key_mgmt != WLAN_AKM_SUITE_8021X) {
233 vif->auth_mode = NONE_AUTH;
237 static bool ath6kl_cfg80211_ready(struct ath6kl_vif *vif)
239 struct ath6kl *ar = vif->ar;
241 if (!test_bit(WMI_READY, &ar->flag)) {
242 ath6kl_err("wmi is not ready\n");
246 if (!test_bit(WLAN_ENABLED, &vif->flags)) {
247 ath6kl_err("wlan disabled\n");
254 static bool ath6kl_is_wpa_ie(const u8 *pos)
256 return pos[0] == WLAN_EID_WPA && pos[1] >= 4 &&
257 pos[2] == 0x00 && pos[3] == 0x50 &&
258 pos[4] == 0xf2 && pos[5] == 0x01;
261 static bool ath6kl_is_rsn_ie(const u8 *pos)
263 return pos[0] == WLAN_EID_RSN;
266 static bool ath6kl_is_wps_ie(const u8 *pos)
268 return (pos[0] == WLAN_EID_VENDOR_SPECIFIC &&
270 pos[2] == 0x00 && pos[3] == 0x50 && pos[4] == 0xf2 &&
274 static int ath6kl_set_assoc_req_ies(struct ath6kl_vif *vif, const u8 *ies,
277 struct ath6kl *ar = vif->ar;
284 * Clear previously set flag
287 ar->connect_ctrl_flags &= ~CONNECT_WPS_FLAG;
290 * Filter out RSN/WPA IE(s)
293 if (ies && ies_len) {
294 buf = kmalloc(ies_len, GFP_KERNEL);
299 while (pos + 1 < ies + ies_len) {
300 if (pos + 2 + pos[1] > ies + ies_len)
302 if (!(ath6kl_is_wpa_ie(pos) || ath6kl_is_rsn_ie(pos))) {
303 memcpy(buf + len, pos, 2 + pos[1]);
307 if (ath6kl_is_wps_ie(pos))
308 ar->connect_ctrl_flags |= CONNECT_WPS_FLAG;
314 ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
315 WMI_FRAME_ASSOC_REQ, buf, len);
320 static int ath6kl_nliftype_to_drv_iftype(enum nl80211_iftype type, u8 *nw_type)
323 case NL80211_IFTYPE_STATION:
324 *nw_type = INFRA_NETWORK;
326 case NL80211_IFTYPE_ADHOC:
327 *nw_type = ADHOC_NETWORK;
329 case NL80211_IFTYPE_AP:
330 *nw_type = AP_NETWORK;
332 case NL80211_IFTYPE_P2P_CLIENT:
333 *nw_type = INFRA_NETWORK;
335 case NL80211_IFTYPE_P2P_GO:
336 *nw_type = AP_NETWORK;
339 ath6kl_err("invalid interface type %u\n", type);
346 static bool ath6kl_is_valid_iftype(struct ath6kl *ar, enum nl80211_iftype type,
347 u8 *if_idx, u8 *nw_type)
351 if (ath6kl_nliftype_to_drv_iftype(type, nw_type))
354 if (ar->ibss_if_active || ((type == NL80211_IFTYPE_ADHOC) &&
358 if (type == NL80211_IFTYPE_STATION ||
359 type == NL80211_IFTYPE_AP || type == NL80211_IFTYPE_ADHOC) {
360 for (i = 0; i < MAX_NUM_VIF; i++) {
361 if ((ar->avail_idx_map >> i) & BIT(0)) {
368 if (type == NL80211_IFTYPE_P2P_CLIENT ||
369 type == NL80211_IFTYPE_P2P_GO) {
370 for (i = ar->max_norm_iface; i < MAX_NUM_VIF; i++) {
371 if ((ar->avail_idx_map >> i) & BIT(0)) {
381 static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
382 struct cfg80211_connect_params *sme)
384 struct ath6kl *ar = ath6kl_priv(dev);
385 struct ath6kl_vif *vif = netdev_priv(dev);
388 vif->sme_state = SME_CONNECTING;
390 if (!ath6kl_cfg80211_ready(vif))
393 if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
394 ath6kl_err("destroy in progress\n");
398 if (test_bit(SKIP_SCAN, &ar->flag) &&
399 ((sme->channel && sme->channel->center_freq == 0) ||
400 (sme->bssid && is_zero_ether_addr(sme->bssid)))) {
401 ath6kl_err("SkipScan: channel or bssid invalid\n");
405 if (down_interruptible(&ar->sem)) {
406 ath6kl_err("busy, couldn't get access\n");
410 if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
411 ath6kl_err("busy, destroy in progress\n");
416 if (ar->tx_pending[ath6kl_wmi_get_control_ep(ar->wmi)]) {
418 * sleep until the command queue drains
420 wait_event_interruptible_timeout(ar->event_wq,
421 ar->tx_pending[ath6kl_wmi_get_control_ep(ar->wmi)] == 0,
423 if (signal_pending(current)) {
424 ath6kl_err("cmd queue drain timeout\n");
430 if (sme->ie && (sme->ie_len > 0)) {
431 status = ath6kl_set_assoc_req_ies(vif, sme->ie, sme->ie_len);
436 if (test_bit(CONNECTED, &vif->flags) &&
437 vif->ssid_len == sme->ssid_len &&
438 !memcmp(vif->ssid, sme->ssid, vif->ssid_len)) {
439 vif->reconnect_flag = true;
440 status = ath6kl_wmi_reconnect_cmd(ar->wmi, vif->fw_vif_idx,
446 ath6kl_err("wmi_reconnect_cmd failed\n");
450 } else if (vif->ssid_len == sme->ssid_len &&
451 !memcmp(vif->ssid, sme->ssid, vif->ssid_len)) {
452 ath6kl_disconnect(vif);
455 memset(vif->ssid, 0, sizeof(vif->ssid));
456 vif->ssid_len = sme->ssid_len;
457 memcpy(vif->ssid, sme->ssid, sme->ssid_len);
460 vif->ch_hint = sme->channel->center_freq;
462 memset(vif->req_bssid, 0, sizeof(vif->req_bssid));
463 if (sme->bssid && !is_broadcast_ether_addr(sme->bssid))
464 memcpy(vif->req_bssid, sme->bssid, sizeof(vif->req_bssid));
466 ath6kl_set_wpa_version(vif, sme->crypto.wpa_versions);
468 status = ath6kl_set_auth_type(vif, sme->auth_type);
474 if (sme->crypto.n_ciphers_pairwise)
475 ath6kl_set_cipher(vif, sme->crypto.ciphers_pairwise[0], true);
477 ath6kl_set_cipher(vif, 0, true);
479 ath6kl_set_cipher(vif, sme->crypto.cipher_group, false);
481 if (sme->crypto.n_akm_suites)
482 ath6kl_set_key_mgmt(vif, sme->crypto.akm_suites[0]);
484 if ((sme->key_len) &&
485 (vif->auth_mode == NONE_AUTH) &&
486 (vif->prwise_crypto == WEP_CRYPT)) {
487 struct ath6kl_key *key = NULL;
489 if (sme->key_idx < WMI_MIN_KEY_INDEX ||
490 sme->key_idx > WMI_MAX_KEY_INDEX) {
491 ath6kl_err("key index %d out of bounds\n",
497 key = &vif->keys[sme->key_idx];
498 key->key_len = sme->key_len;
499 memcpy(key->key, sme->key, key->key_len);
500 key->cipher = vif->prwise_crypto;
501 vif->def_txkey_index = sme->key_idx;
503 ath6kl_wmi_addkey_cmd(ar->wmi, vif->fw_vif_idx, sme->key_idx,
505 GROUP_USAGE | TX_USAGE,
508 key->key, KEY_OP_INIT_VAL, NULL,
512 if (!ar->usr_bss_filter) {
513 clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags);
514 if (ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
515 ALL_BSS_FILTER, 0) != 0) {
516 ath6kl_err("couldn't set bss filtering\n");
522 vif->nw_type = vif->next_mode;
524 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
525 "%s: connect called with authmode %d dot11 auth %d"
526 " PW crypto %d PW crypto len %d GRP crypto %d"
527 " GRP crypto len %d channel hint %u\n",
529 vif->auth_mode, vif->dot11_auth_mode, vif->prwise_crypto,
530 vif->prwise_crypto_len, vif->grp_crypto,
531 vif->grp_crypto_len, vif->ch_hint);
533 vif->reconnect_flag = 0;
534 status = ath6kl_wmi_connect_cmd(ar->wmi, vif->fw_vif_idx, vif->nw_type,
535 vif->dot11_auth_mode, vif->auth_mode,
537 vif->prwise_crypto_len,
538 vif->grp_crypto, vif->grp_crypto_len,
539 vif->ssid_len, vif->ssid,
540 vif->req_bssid, vif->ch_hint,
541 ar->connect_ctrl_flags);
545 if (status == -EINVAL) {
546 memset(vif->ssid, 0, sizeof(vif->ssid));
548 ath6kl_err("invalid request\n");
551 ath6kl_err("ath6kl_wmi_connect_cmd failed\n");
555 if ((!(ar->connect_ctrl_flags & CONNECT_DO_WPA_OFFLOAD)) &&
556 ((vif->auth_mode == WPA_PSK_AUTH)
557 || (vif->auth_mode == WPA2_PSK_AUTH))) {
558 mod_timer(&vif->disconnect_timer,
559 jiffies + msecs_to_jiffies(DISCON_TIMER_INTVAL));
562 ar->connect_ctrl_flags &= ~CONNECT_DO_WPA_OFFLOAD;
563 set_bit(CONNECT_PEND, &vif->flags);
568 static int ath6kl_add_bss_if_needed(struct ath6kl_vif *vif,
569 enum network_type nw_type,
571 struct ieee80211_channel *chan,
572 const u8 *beacon_ie, size_t beacon_ie_len)
574 struct ath6kl *ar = vif->ar;
575 struct cfg80211_bss *bss;
576 u16 cap_mask, cap_val;
579 if (nw_type & ADHOC_NETWORK) {
580 cap_mask = WLAN_CAPABILITY_IBSS;
581 cap_val = WLAN_CAPABILITY_IBSS;
583 cap_mask = WLAN_CAPABILITY_ESS;
584 cap_val = WLAN_CAPABILITY_ESS;
587 bss = cfg80211_get_bss(ar->wiphy, chan, bssid,
588 vif->ssid, vif->ssid_len,
592 * Since cfg80211 may not yet know about the BSS,
593 * generate a partial entry until the first BSS info
594 * event becomes available.
596 * Prepend SSID element since it is not included in the Beacon
597 * IEs from the target.
599 ie = kmalloc(2 + vif->ssid_len + beacon_ie_len, GFP_KERNEL);
602 ie[0] = WLAN_EID_SSID;
603 ie[1] = vif->ssid_len;
604 memcpy(ie + 2, vif->ssid, vif->ssid_len);
605 memcpy(ie + 2 + vif->ssid_len, beacon_ie, beacon_ie_len);
606 bss = cfg80211_inform_bss(ar->wiphy, chan,
607 bssid, 0, cap_val, 100,
608 ie, 2 + vif->ssid_len + beacon_ie_len,
611 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "added bss %pM to "
612 "cfg80211\n", bssid);
615 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "cfg80211 already has a bss "
621 cfg80211_put_bss(bss);
626 void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel,
627 u8 *bssid, u16 listen_intvl,
629 enum network_type nw_type,
630 u8 beacon_ie_len, u8 assoc_req_len,
631 u8 assoc_resp_len, u8 *assoc_info)
633 struct ieee80211_channel *chan;
634 struct ath6kl *ar = vif->ar;
636 /* capinfo + listen interval */
637 u8 assoc_req_ie_offset = sizeof(u16) + sizeof(u16);
639 /* capinfo + status code + associd */
640 u8 assoc_resp_ie_offset = sizeof(u16) + sizeof(u16) + sizeof(u16);
642 u8 *assoc_req_ie = assoc_info + beacon_ie_len + assoc_req_ie_offset;
643 u8 *assoc_resp_ie = assoc_info + beacon_ie_len + assoc_req_len +
644 assoc_resp_ie_offset;
646 assoc_req_len -= assoc_req_ie_offset;
647 assoc_resp_len -= assoc_resp_ie_offset;
650 * Store Beacon interval here; DTIM period will be available only once
651 * a Beacon frame from the AP is seen.
653 vif->assoc_bss_beacon_int = beacon_intvl;
654 clear_bit(DTIM_PERIOD_AVAIL, &vif->flags);
656 if (nw_type & ADHOC_NETWORK) {
657 if (vif->wdev.iftype != NL80211_IFTYPE_ADHOC) {
658 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
659 "%s: ath6k not in ibss mode\n", __func__);
664 if (nw_type & INFRA_NETWORK) {
665 if (vif->wdev.iftype != NL80211_IFTYPE_STATION &&
666 vif->wdev.iftype != NL80211_IFTYPE_P2P_CLIENT) {
667 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
668 "%s: ath6k not in station mode\n", __func__);
673 chan = ieee80211_get_channel(ar->wiphy, (int) channel);
675 if (ath6kl_add_bss_if_needed(vif, nw_type, bssid, chan, assoc_info,
676 beacon_ie_len) < 0) {
677 ath6kl_err("could not add cfg80211 bss entry\n");
681 if (nw_type & ADHOC_NETWORK) {
682 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "ad-hoc %s selected\n",
683 nw_type & ADHOC_CREATOR ? "creator" : "joiner");
684 cfg80211_ibss_joined(vif->ndev, bssid, GFP_KERNEL);
688 if (vif->sme_state == SME_CONNECTING) {
689 /* inform connect result to cfg80211 */
690 vif->sme_state = SME_CONNECTED;
691 cfg80211_connect_result(vif->ndev, bssid,
692 assoc_req_ie, assoc_req_len,
693 assoc_resp_ie, assoc_resp_len,
694 WLAN_STATUS_SUCCESS, GFP_KERNEL);
695 } else if (vif->sme_state == SME_CONNECTED) {
696 /* inform roam event to cfg80211 */
697 cfg80211_roamed(vif->ndev, chan, bssid,
698 assoc_req_ie, assoc_req_len,
699 assoc_resp_ie, assoc_resp_len, GFP_KERNEL);
703 static int ath6kl_cfg80211_disconnect(struct wiphy *wiphy,
704 struct net_device *dev, u16 reason_code)
706 struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(dev);
707 struct ath6kl_vif *vif = netdev_priv(dev);
709 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: reason=%u\n", __func__,
712 if (!ath6kl_cfg80211_ready(vif))
715 if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
716 ath6kl_err("busy, destroy in progress\n");
720 if (down_interruptible(&ar->sem)) {
721 ath6kl_err("busy, couldn't get access\n");
725 vif->reconnect_flag = 0;
726 ath6kl_disconnect(vif);
727 memset(vif->ssid, 0, sizeof(vif->ssid));
730 if (!test_bit(SKIP_SCAN, &ar->flag))
731 memset(vif->req_bssid, 0, sizeof(vif->req_bssid));
735 vif->sme_state = SME_DISCONNECTED;
740 void ath6kl_cfg80211_disconnect_event(struct ath6kl_vif *vif, u8 reason,
741 u8 *bssid, u8 assoc_resp_len,
742 u8 *assoc_info, u16 proto_reason)
744 struct ath6kl *ar = vif->ar;
747 cfg80211_scan_done(vif->scan_req, true);
748 vif->scan_req = NULL;
751 if (vif->nw_type & ADHOC_NETWORK) {
752 if (vif->wdev.iftype != NL80211_IFTYPE_ADHOC) {
753 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
754 "%s: ath6k not in ibss mode\n", __func__);
757 memset(bssid, 0, ETH_ALEN);
758 cfg80211_ibss_joined(vif->ndev, bssid, GFP_KERNEL);
762 if (vif->nw_type & INFRA_NETWORK) {
763 if (vif->wdev.iftype != NL80211_IFTYPE_STATION &&
764 vif->wdev.iftype != NL80211_IFTYPE_P2P_CLIENT) {
765 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
766 "%s: ath6k not in station mode\n", __func__);
772 * Send a disconnect command to target when a disconnect event is
773 * received with reason code other than 3 (DISCONNECT_CMD - disconnect
774 * request from host) to make the firmware stop trying to connect even
775 * after giving disconnect event. There will be one more disconnect
776 * event for this disconnect command with reason code DISCONNECT_CMD
777 * which will be notified to cfg80211.
780 if (reason != DISCONNECT_CMD) {
781 ath6kl_wmi_disconnect_cmd(ar->wmi, vif->fw_vif_idx);
785 clear_bit(CONNECT_PEND, &vif->flags);
787 if (vif->sme_state == SME_CONNECTING) {
788 cfg80211_connect_result(vif->ndev,
791 WLAN_STATUS_UNSPECIFIED_FAILURE,
793 } else if (vif->sme_state == SME_CONNECTED) {
794 cfg80211_disconnected(vif->ndev, reason,
795 NULL, 0, GFP_KERNEL);
798 vif->sme_state = SME_DISCONNECTED;
801 static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
802 struct cfg80211_scan_request *request)
804 struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
805 struct ath6kl_vif *vif = netdev_priv(ndev);
807 u16 *channels = NULL;
809 u32 force_fg_scan = 0;
811 if (!ath6kl_cfg80211_ready(vif))
814 if (!ar->usr_bss_filter) {
815 clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags);
816 ret = ath6kl_wmi_bssfilter_cmd(
817 ar->wmi, vif->fw_vif_idx,
818 (test_bit(CONNECTED, &vif->flags) ?
819 ALL_BUT_BSS_FILTER : ALL_BSS_FILTER), 0);
821 ath6kl_err("couldn't set bss filtering\n");
826 if (request->n_ssids && request->ssids[0].ssid_len) {
829 if (request->n_ssids > (MAX_PROBED_SSID_INDEX - 1))
830 request->n_ssids = MAX_PROBED_SSID_INDEX - 1;
832 for (i = 0; i < request->n_ssids; i++)
833 ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx,
834 i + 1, SPECIFIC_SSID_FLAG,
835 request->ssids[i].ssid_len,
836 request->ssids[i].ssid);
840 ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
842 request->ie, request->ie_len);
844 ath6kl_err("failed to set Probe Request appie for "
851 * Scan only the requested channels if the request specifies a set of
852 * channels. If the list is longer than the target supports, do not
853 * configure the list and instead, scan all available channels.
855 if (request->n_channels > 0 &&
856 request->n_channels <= WMI_MAX_CHANNELS) {
859 n_channels = request->n_channels;
861 channels = kzalloc(n_channels * sizeof(u16), GFP_KERNEL);
862 if (channels == NULL) {
863 ath6kl_warn("failed to set scan channels, "
864 "scan all channels");
868 for (i = 0; i < n_channels; i++)
869 channels[i] = request->channels[i]->center_freq;
872 if (test_bit(CONNECTED, &vif->flags))
875 ret = ath6kl_wmi_startscan_cmd(ar->wmi, vif->fw_vif_idx, WMI_LONG_SCAN,
876 force_fg_scan, false, 0, 0, n_channels,
879 ath6kl_err("wmi_startscan_cmd failed\n");
881 vif->scan_req = request;
888 void ath6kl_cfg80211_scan_complete_event(struct ath6kl_vif *vif, bool aborted)
890 struct ath6kl *ar = vif->ar;
893 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: status%s\n", __func__,
894 aborted ? " aborted" : "");
902 if (vif->scan_req->n_ssids && vif->scan_req->ssids[0].ssid_len) {
903 for (i = 0; i < vif->scan_req->n_ssids; i++) {
904 ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx,
905 i + 1, DISABLE_SSID_FLAG,
911 cfg80211_scan_done(vif->scan_req, aborted);
912 vif->scan_req = NULL;
915 static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
916 u8 key_index, bool pairwise,
918 struct key_params *params)
920 struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
921 struct ath6kl_vif *vif = netdev_priv(ndev);
922 struct ath6kl_key *key = NULL;
926 if (!ath6kl_cfg80211_ready(vif))
929 if (params->cipher == CCKM_KRK_CIPHER_SUITE) {
930 if (params->key_len != WMI_KRK_LEN)
932 return ath6kl_wmi_add_krk_cmd(ar->wmi, vif->fw_vif_idx,
936 if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
937 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
938 "%s: key index %d out of bounds\n", __func__,
943 key = &vif->keys[key_index];
944 memset(key, 0, sizeof(struct ath6kl_key));
947 key_usage = PAIRWISE_USAGE;
949 key_usage = GROUP_USAGE;
952 int seq_len = params->seq_len;
953 if (params->cipher == WLAN_CIPHER_SUITE_SMS4 &&
954 seq_len > ATH6KL_KEY_SEQ_LEN) {
955 /* Only first half of the WPI PN is configured */
956 seq_len = ATH6KL_KEY_SEQ_LEN;
958 if (params->key_len > WLAN_MAX_KEY_LEN ||
959 seq_len > sizeof(key->seq))
962 key->key_len = params->key_len;
963 memcpy(key->key, params->key, key->key_len);
964 key->seq_len = seq_len;
965 memcpy(key->seq, params->seq, key->seq_len);
966 key->cipher = params->cipher;
969 switch (key->cipher) {
970 case WLAN_CIPHER_SUITE_WEP40:
971 case WLAN_CIPHER_SUITE_WEP104:
972 key_type = WEP_CRYPT;
975 case WLAN_CIPHER_SUITE_TKIP:
976 key_type = TKIP_CRYPT;
979 case WLAN_CIPHER_SUITE_CCMP:
980 key_type = AES_CRYPT;
982 case WLAN_CIPHER_SUITE_SMS4:
983 key_type = WAPI_CRYPT;
990 if (((vif->auth_mode == WPA_PSK_AUTH)
991 || (vif->auth_mode == WPA2_PSK_AUTH))
992 && (key_usage & GROUP_USAGE))
993 del_timer(&vif->disconnect_timer);
995 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
996 "%s: index %d, key_len %d, key_type 0x%x, key_usage 0x%x, seq_len %d\n",
997 __func__, key_index, key->key_len, key_type,
998 key_usage, key->seq_len);
1000 if (vif->nw_type == AP_NETWORK && !pairwise &&
1001 (key_type == TKIP_CRYPT || key_type == AES_CRYPT) && params) {
1002 ar->ap_mode_bkey.valid = true;
1003 ar->ap_mode_bkey.key_index = key_index;
1004 ar->ap_mode_bkey.key_type = key_type;
1005 ar->ap_mode_bkey.key_len = key->key_len;
1006 memcpy(ar->ap_mode_bkey.key, key->key, key->key_len);
1007 if (!test_bit(CONNECTED, &vif->flags)) {
1008 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delay initial group "
1009 "key configuration until AP mode has been "
1012 * The key will be set in ath6kl_connect_ap_mode() once
1013 * the connected event is received from the target.
1019 if (vif->next_mode == AP_NETWORK && key_type == WEP_CRYPT &&
1020 !test_bit(CONNECTED, &vif->flags)) {
1022 * Store the key locally so that it can be re-configured after
1023 * the AP mode has properly started
1024 * (ath6kl_install_statioc_wep_keys).
1026 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delay WEP key configuration "
1027 "until AP mode has been started\n");
1028 vif->wep_key_list[key_index].key_len = key->key_len;
1029 memcpy(vif->wep_key_list[key_index].key, key->key,
1034 return ath6kl_wmi_addkey_cmd(ar->wmi, vif->fw_vif_idx, key_index,
1035 key_type, key_usage, key->key_len,
1036 key->seq, key->seq_len, key->key,
1038 (u8 *) mac_addr, SYNC_BOTH_WMIFLAG);
1041 static int ath6kl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
1042 u8 key_index, bool pairwise,
1045 struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
1046 struct ath6kl_vif *vif = netdev_priv(ndev);
1048 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
1050 if (!ath6kl_cfg80211_ready(vif))
1053 if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
1054 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1055 "%s: key index %d out of bounds\n", __func__,
1060 if (!vif->keys[key_index].key_len) {
1061 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1062 "%s: index %d is empty\n", __func__, key_index);
1066 vif->keys[key_index].key_len = 0;
1068 return ath6kl_wmi_deletekey_cmd(ar->wmi, vif->fw_vif_idx, key_index);
1071 static int ath6kl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
1072 u8 key_index, bool pairwise,
1073 const u8 *mac_addr, void *cookie,
1074 void (*callback) (void *cookie,
1075 struct key_params *))
1077 struct ath6kl_vif *vif = netdev_priv(ndev);
1078 struct ath6kl_key *key = NULL;
1079 struct key_params params;
1081 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
1083 if (!ath6kl_cfg80211_ready(vif))
1086 if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
1087 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1088 "%s: key index %d out of bounds\n", __func__,
1093 key = &vif->keys[key_index];
1094 memset(¶ms, 0, sizeof(params));
1095 params.cipher = key->cipher;
1096 params.key_len = key->key_len;
1097 params.seq_len = key->seq_len;
1098 params.seq = key->seq;
1099 params.key = key->key;
1101 callback(cookie, ¶ms);
1103 return key->key_len ? 0 : -ENOENT;
1106 static int ath6kl_cfg80211_set_default_key(struct wiphy *wiphy,
1107 struct net_device *ndev,
1108 u8 key_index, bool unicast,
1111 struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
1112 struct ath6kl_vif *vif = netdev_priv(ndev);
1113 struct ath6kl_key *key = NULL;
1115 enum crypto_type key_type = NONE_CRYPT;
1117 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
1119 if (!ath6kl_cfg80211_ready(vif))
1122 if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
1123 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1124 "%s: key index %d out of bounds\n",
1125 __func__, key_index);
1129 if (!vif->keys[key_index].key_len) {
1130 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: invalid key index %d\n",
1131 __func__, key_index);
1135 vif->def_txkey_index = key_index;
1136 key = &vif->keys[vif->def_txkey_index];
1137 key_usage = GROUP_USAGE;
1138 if (vif->prwise_crypto == WEP_CRYPT)
1139 key_usage |= TX_USAGE;
1141 key_type = vif->prwise_crypto;
1143 key_type = vif->grp_crypto;
1145 if (vif->next_mode == AP_NETWORK && !test_bit(CONNECTED, &vif->flags))
1146 return 0; /* Delay until AP mode has been started */
1148 return ath6kl_wmi_addkey_cmd(ar->wmi, vif->fw_vif_idx,
1149 vif->def_txkey_index,
1150 key_type, key_usage,
1151 key->key_len, key->seq, key->seq_len,
1153 KEY_OP_INIT_VAL, NULL,
1157 void ath6kl_cfg80211_tkip_micerr_event(struct ath6kl_vif *vif, u8 keyid,
1160 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1161 "%s: keyid %d, ismcast %d\n", __func__, keyid, ismcast);
1163 cfg80211_michael_mic_failure(vif->ndev, vif->bssid,
1164 (ismcast ? NL80211_KEYTYPE_GROUP :
1165 NL80211_KEYTYPE_PAIRWISE), keyid, NULL,
1169 static int ath6kl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1171 struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
1172 struct ath6kl_vif *vif;
1175 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: changed 0x%x\n", __func__,
1178 vif = ath6kl_vif_first(ar);
1182 if (!ath6kl_cfg80211_ready(vif))
1185 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1186 ret = ath6kl_wmi_set_rts_cmd(ar->wmi, wiphy->rts_threshold);
1188 ath6kl_err("ath6kl_wmi_set_rts_cmd failed\n");
1197 * The type nl80211_tx_power_setting replaces the following
1198 * data type from 2.6.36 onwards
1200 static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy,
1201 enum nl80211_tx_power_setting type,
1204 struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
1205 struct ath6kl_vif *vif;
1208 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type 0x%x, dbm %d\n", __func__,
1211 vif = ath6kl_vif_first(ar);
1215 if (!ath6kl_cfg80211_ready(vif))
1219 case NL80211_TX_POWER_AUTOMATIC:
1221 case NL80211_TX_POWER_LIMITED:
1222 ar->tx_pwr = ath6kl_dbm = dbm;
1225 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type 0x%x not supported\n",
1230 ath6kl_wmi_set_tx_pwr_cmd(ar->wmi, vif->fw_vif_idx, ath6kl_dbm);
1235 static int ath6kl_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
1237 struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
1238 struct ath6kl_vif *vif;
1240 vif = ath6kl_vif_first(ar);
1244 if (!ath6kl_cfg80211_ready(vif))
1247 if (test_bit(CONNECTED, &vif->flags)) {
1250 if (ath6kl_wmi_get_tx_pwr_cmd(ar->wmi, vif->fw_vif_idx) != 0) {
1251 ath6kl_err("ath6kl_wmi_get_tx_pwr_cmd failed\n");
1255 wait_event_interruptible_timeout(ar->event_wq, ar->tx_pwr != 0,
1258 if (signal_pending(current)) {
1259 ath6kl_err("target did not respond\n");
1268 static int ath6kl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
1269 struct net_device *dev,
1270 bool pmgmt, int timeout)
1272 struct ath6kl *ar = ath6kl_priv(dev);
1273 struct wmi_power_mode_cmd mode;
1274 struct ath6kl_vif *vif = netdev_priv(dev);
1276 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: pmgmt %d, timeout %d\n",
1277 __func__, pmgmt, timeout);
1279 if (!ath6kl_cfg80211_ready(vif))
1283 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: max perf\n", __func__);
1284 mode.pwr_mode = REC_POWER;
1286 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: rec power\n", __func__);
1287 mode.pwr_mode = MAX_PERF_POWER;
1290 if (ath6kl_wmi_powermode_cmd(ar->wmi, vif->fw_vif_idx,
1291 mode.pwr_mode) != 0) {
1292 ath6kl_err("wmi_powermode_cmd failed\n");
1299 static struct net_device *ath6kl_cfg80211_add_iface(struct wiphy *wiphy,
1301 enum nl80211_iftype type,
1303 struct vif_params *params)
1305 struct ath6kl *ar = wiphy_priv(wiphy);
1306 struct net_device *ndev;
1309 if (ar->num_vif == MAX_NUM_VIF) {
1310 ath6kl_err("Reached maximum number of supported vif\n");
1311 return ERR_PTR(-EINVAL);
1314 if (!ath6kl_is_valid_iftype(ar, type, &if_idx, &nw_type)) {
1315 ath6kl_err("Not a supported interface type\n");
1316 return ERR_PTR(-EINVAL);
1319 ndev = ath6kl_interface_add(ar, name, type, if_idx, nw_type);
1321 return ERR_PTR(-ENOMEM);
1328 static int ath6kl_cfg80211_del_iface(struct wiphy *wiphy,
1329 struct net_device *ndev)
1331 struct ath6kl *ar = wiphy_priv(wiphy);
1332 struct ath6kl_vif *vif = netdev_priv(ndev);
1334 spin_lock_bh(&ar->list_lock);
1335 list_del(&vif->list);
1336 spin_unlock_bh(&ar->list_lock);
1338 ath6kl_cleanup_vif(vif, test_bit(WMI_READY, &ar->flag));
1340 ath6kl_deinit_if_data(vif);
1345 static int ath6kl_cfg80211_change_iface(struct wiphy *wiphy,
1346 struct net_device *ndev,
1347 enum nl80211_iftype type, u32 *flags,
1348 struct vif_params *params)
1350 struct ath6kl_vif *vif = netdev_priv(ndev);
1352 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type %u\n", __func__, type);
1354 if (!ath6kl_cfg80211_ready(vif))
1358 case NL80211_IFTYPE_STATION:
1359 vif->next_mode = INFRA_NETWORK;
1361 case NL80211_IFTYPE_ADHOC:
1362 vif->next_mode = ADHOC_NETWORK;
1364 case NL80211_IFTYPE_AP:
1365 vif->next_mode = AP_NETWORK;
1367 case NL80211_IFTYPE_P2P_CLIENT:
1368 vif->next_mode = INFRA_NETWORK;
1370 case NL80211_IFTYPE_P2P_GO:
1371 vif->next_mode = AP_NETWORK;
1374 ath6kl_err("invalid interface type %u\n", type);
1378 vif->wdev.iftype = type;
1383 static int ath6kl_cfg80211_join_ibss(struct wiphy *wiphy,
1384 struct net_device *dev,
1385 struct cfg80211_ibss_params *ibss_param)
1387 struct ath6kl *ar = ath6kl_priv(dev);
1388 struct ath6kl_vif *vif = netdev_priv(dev);
1391 if (!ath6kl_cfg80211_ready(vif))
1394 vif->ssid_len = ibss_param->ssid_len;
1395 memcpy(vif->ssid, ibss_param->ssid, vif->ssid_len);
1397 if (ibss_param->channel)
1398 vif->ch_hint = ibss_param->channel->center_freq;
1400 if (ibss_param->channel_fixed) {
1402 * TODO: channel_fixed: The channel should be fixed, do not
1403 * search for IBSSs to join on other channels. Target
1404 * firmware does not support this feature, needs to be
1410 memset(vif->req_bssid, 0, sizeof(vif->req_bssid));
1411 if (ibss_param->bssid && !is_broadcast_ether_addr(ibss_param->bssid))
1412 memcpy(vif->req_bssid, ibss_param->bssid,
1413 sizeof(vif->req_bssid));
1415 ath6kl_set_wpa_version(vif, 0);
1417 status = ath6kl_set_auth_type(vif, NL80211_AUTHTYPE_OPEN_SYSTEM);
1421 if (ibss_param->privacy) {
1422 ath6kl_set_cipher(vif, WLAN_CIPHER_SUITE_WEP40, true);
1423 ath6kl_set_cipher(vif, WLAN_CIPHER_SUITE_WEP40, false);
1425 ath6kl_set_cipher(vif, 0, true);
1426 ath6kl_set_cipher(vif, 0, false);
1429 vif->nw_type = vif->next_mode;
1431 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1432 "%s: connect called with authmode %d dot11 auth %d"
1433 " PW crypto %d PW crypto len %d GRP crypto %d"
1434 " GRP crypto len %d channel hint %u\n",
1436 vif->auth_mode, vif->dot11_auth_mode, vif->prwise_crypto,
1437 vif->prwise_crypto_len, vif->grp_crypto,
1438 vif->grp_crypto_len, vif->ch_hint);
1440 status = ath6kl_wmi_connect_cmd(ar->wmi, vif->fw_vif_idx, vif->nw_type,
1441 vif->dot11_auth_mode, vif->auth_mode,
1443 vif->prwise_crypto_len,
1444 vif->grp_crypto, vif->grp_crypto_len,
1445 vif->ssid_len, vif->ssid,
1446 vif->req_bssid, vif->ch_hint,
1447 ar->connect_ctrl_flags);
1448 set_bit(CONNECT_PEND, &vif->flags);
1453 static int ath6kl_cfg80211_leave_ibss(struct wiphy *wiphy,
1454 struct net_device *dev)
1456 struct ath6kl_vif *vif = netdev_priv(dev);
1458 if (!ath6kl_cfg80211_ready(vif))
1461 ath6kl_disconnect(vif);
1462 memset(vif->ssid, 0, sizeof(vif->ssid));
1468 static const u32 cipher_suites[] = {
1469 WLAN_CIPHER_SUITE_WEP40,
1470 WLAN_CIPHER_SUITE_WEP104,
1471 WLAN_CIPHER_SUITE_TKIP,
1472 WLAN_CIPHER_SUITE_CCMP,
1473 CCKM_KRK_CIPHER_SUITE,
1474 WLAN_CIPHER_SUITE_SMS4,
1477 static bool is_rate_legacy(s32 rate)
1479 static const s32 legacy[] = { 1000, 2000, 5500, 11000,
1480 6000, 9000, 12000, 18000, 24000,
1485 for (i = 0; i < ARRAY_SIZE(legacy); i++)
1486 if (rate == legacy[i])
1492 static bool is_rate_ht20(s32 rate, u8 *mcs, bool *sgi)
1494 static const s32 ht20[] = { 6500, 13000, 19500, 26000, 39000,
1495 52000, 58500, 65000, 72200
1499 for (i = 0; i < ARRAY_SIZE(ht20); i++) {
1500 if (rate == ht20[i]) {
1501 if (i == ARRAY_SIZE(ht20) - 1)
1502 /* last rate uses sgi */
1514 static bool is_rate_ht40(s32 rate, u8 *mcs, bool *sgi)
1516 static const s32 ht40[] = { 13500, 27000, 40500, 54000,
1517 81000, 108000, 121500, 135000,
1522 for (i = 0; i < ARRAY_SIZE(ht40); i++) {
1523 if (rate == ht40[i]) {
1524 if (i == ARRAY_SIZE(ht40) - 1)
1525 /* last rate uses sgi */
1538 static int ath6kl_get_station(struct wiphy *wiphy, struct net_device *dev,
1539 u8 *mac, struct station_info *sinfo)
1541 struct ath6kl *ar = ath6kl_priv(dev);
1542 struct ath6kl_vif *vif = netdev_priv(dev);
1549 if (memcmp(mac, vif->bssid, ETH_ALEN) != 0)
1552 if (down_interruptible(&ar->sem))
1555 set_bit(STATS_UPDATE_PEND, &vif->flags);
1557 ret = ath6kl_wmi_get_stats_cmd(ar->wmi, vif->fw_vif_idx);
1564 left = wait_event_interruptible_timeout(ar->event_wq,
1565 !test_bit(STATS_UPDATE_PEND,
1576 if (vif->target_stats.rx_byte) {
1577 sinfo->rx_bytes = vif->target_stats.rx_byte;
1578 sinfo->filled |= STATION_INFO_RX_BYTES;
1579 sinfo->rx_packets = vif->target_stats.rx_pkt;
1580 sinfo->filled |= STATION_INFO_RX_PACKETS;
1583 if (vif->target_stats.tx_byte) {
1584 sinfo->tx_bytes = vif->target_stats.tx_byte;
1585 sinfo->filled |= STATION_INFO_TX_BYTES;
1586 sinfo->tx_packets = vif->target_stats.tx_pkt;
1587 sinfo->filled |= STATION_INFO_TX_PACKETS;
1590 sinfo->signal = vif->target_stats.cs_rssi;
1591 sinfo->filled |= STATION_INFO_SIGNAL;
1593 rate = vif->target_stats.tx_ucast_rate;
1595 if (is_rate_legacy(rate)) {
1596 sinfo->txrate.legacy = rate / 100;
1597 } else if (is_rate_ht20(rate, &mcs, &sgi)) {
1599 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
1600 sinfo->txrate.mcs = mcs - 1;
1602 sinfo->txrate.mcs = mcs;
1605 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
1606 } else if (is_rate_ht40(rate, &mcs, &sgi)) {
1608 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
1609 sinfo->txrate.mcs = mcs - 1;
1611 sinfo->txrate.mcs = mcs;
1614 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
1615 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
1617 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1618 "invalid rate from stats: %d\n", rate);
1619 ath6kl_debug_war(ar, ATH6KL_WAR_INVALID_RATE);
1623 sinfo->filled |= STATION_INFO_TX_BITRATE;
1625 if (test_bit(CONNECTED, &vif->flags) &&
1626 test_bit(DTIM_PERIOD_AVAIL, &vif->flags) &&
1627 vif->nw_type == INFRA_NETWORK) {
1628 sinfo->filled |= STATION_INFO_BSS_PARAM;
1629 sinfo->bss_param.flags = 0;
1630 sinfo->bss_param.dtim_period = vif->assoc_bss_dtim_period;
1631 sinfo->bss_param.beacon_interval = vif->assoc_bss_beacon_int;
1637 static int ath6kl_set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1638 struct cfg80211_pmksa *pmksa)
1640 struct ath6kl *ar = ath6kl_priv(netdev);
1641 struct ath6kl_vif *vif = netdev_priv(netdev);
1643 return ath6kl_wmi_setpmkid_cmd(ar->wmi, vif->fw_vif_idx, pmksa->bssid,
1644 pmksa->pmkid, true);
1647 static int ath6kl_del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1648 struct cfg80211_pmksa *pmksa)
1650 struct ath6kl *ar = ath6kl_priv(netdev);
1651 struct ath6kl_vif *vif = netdev_priv(netdev);
1653 return ath6kl_wmi_setpmkid_cmd(ar->wmi, vif->fw_vif_idx, pmksa->bssid,
1654 pmksa->pmkid, false);
1657 static int ath6kl_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
1659 struct ath6kl *ar = ath6kl_priv(netdev);
1660 struct ath6kl_vif *vif = netdev_priv(netdev);
1662 if (test_bit(CONNECTED, &vif->flags))
1663 return ath6kl_wmi_setpmkid_cmd(ar->wmi, vif->fw_vif_idx,
1664 vif->bssid, NULL, false);
1668 static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
1670 struct ath6kl_vif *vif;
1674 u8 mask[WOW_MASK_SIZE];
1676 vif = ath6kl_vif_first(ar);
1680 if (!ath6kl_cfg80211_ready(vif))
1683 if (!test_bit(CONNECTED, &vif->flags))
1686 /* Clear existing WOW patterns */
1687 for (i = 0; i < WOW_MAX_FILTERS_PER_LIST; i++)
1688 ath6kl_wmi_del_wow_pattern_cmd(ar->wmi, vif->fw_vif_idx,
1690 /* Configure new WOW patterns */
1691 for (i = 0; i < wow->n_patterns; i++) {
1694 * Convert given nl80211 specific mask value to equivalent
1695 * driver specific mask value and send it to the chip along
1696 * with patterns. For example, If the mask value defined in
1697 * struct cfg80211_wowlan is 0xA (equivalent binary is 1010),
1698 * then equivalent driver specific mask value is
1699 * "0xFF 0x00 0xFF 0x00".
1701 memset(&mask, 0, sizeof(mask));
1702 for (pos = 0; pos < wow->patterns[i].pattern_len; pos++) {
1703 if (wow->patterns[i].mask[pos / 8] & (0x1 << (pos % 8)))
1707 * Note: Pattern's offset is not passed as part of wowlan
1708 * parameter from CFG layer. So it's always passed as ZERO
1709 * to the firmware. It means, given WOW patterns are always
1710 * matched from the first byte of received pkt in the firmware.
1712 ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
1713 vif->fw_vif_idx, WOW_LIST_ID,
1714 wow->patterns[i].pattern_len,
1715 0 /* pattern offset */,
1716 wow->patterns[i].pattern, mask);
1721 if (wow->disconnect)
1722 filter |= WOW_FILTER_OPTION_NWK_DISASSOC;
1725 filter |= WOW_FILTER_OPTION_MAGIC_PACKET;
1727 if (wow->gtk_rekey_failure)
1728 filter |= WOW_FILTER_OPTION_GTK_ERROR;
1730 if (wow->eap_identity_req)
1731 filter |= WOW_FILTER_OPTION_EAP_REQ;
1733 if (wow->four_way_handshake)
1734 filter |= WOW_FILTER_OPTION_8021X_4WAYHS;
1736 ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, vif->fw_vif_idx,
1737 ATH6KL_WOW_MODE_ENABLE,
1739 WOW_HOST_REQ_DELAY);
1743 ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
1744 ATH6KL_HOST_MODE_ASLEEP);
1748 if (ar->tx_pending[ar->ctrl_ep]) {
1749 left = wait_event_interruptible_timeout(ar->event_wq,
1750 ar->tx_pending[ar->ctrl_ep] == 0, WMI_TIMEOUT);
1752 ath6kl_warn("clear wmi ctrl data timeout\n");
1754 } else if (left < 0) {
1755 ath6kl_warn("clear wmi ctrl data failed: %d\n", left);
1763 static int ath6kl_wow_resume(struct ath6kl *ar)
1765 struct ath6kl_vif *vif;
1768 vif = ath6kl_vif_first(ar);
1772 ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
1773 ATH6KL_HOST_MODE_AWAKE);
1777 int ath6kl_cfg80211_suspend(struct ath6kl *ar,
1778 enum ath6kl_cfg_suspend_mode mode,
1779 struct cfg80211_wowlan *wow)
1784 case ATH6KL_CFG_SUSPEND_WOW:
1786 ath6kl_dbg(ATH6KL_DBG_SUSPEND, "wow mode suspend\n");
1788 /* Flush all non control pkts in TX path */
1789 ath6kl_tx_data_cleanup(ar);
1791 ret = ath6kl_wow_suspend(ar, wow);
1793 ath6kl_err("wow suspend failed: %d\n", ret);
1796 ar->state = ATH6KL_STATE_WOW;
1799 case ATH6KL_CFG_SUSPEND_DEEPSLEEP:
1801 ath6kl_cfg80211_stop(ar);
1803 /* save the current power mode before enabling power save */
1804 ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode;
1806 ret = ath6kl_wmi_powermode_cmd(ar->wmi, 0, REC_POWER);
1808 ath6kl_warn("wmi powermode command failed during suspend: %d\n",
1812 ar->state = ATH6KL_STATE_DEEPSLEEP;
1816 case ATH6KL_CFG_SUSPEND_CUTPOWER:
1818 ath6kl_cfg80211_stop(ar);
1820 if (ar->state == ATH6KL_STATE_OFF) {
1821 ath6kl_dbg(ATH6KL_DBG_SUSPEND,
1822 "suspend hw off, no action for cutpower\n");
1826 ath6kl_dbg(ATH6KL_DBG_SUSPEND, "suspend cutting power\n");
1828 ret = ath6kl_init_hw_stop(ar);
1830 ath6kl_warn("failed to stop hw during suspend: %d\n",
1834 ar->state = ATH6KL_STATE_CUTPOWER;
1845 int ath6kl_cfg80211_resume(struct ath6kl *ar)
1849 switch (ar->state) {
1850 case ATH6KL_STATE_WOW:
1851 ath6kl_dbg(ATH6KL_DBG_SUSPEND, "wow mode resume\n");
1853 ret = ath6kl_wow_resume(ar);
1855 ath6kl_warn("wow mode resume failed: %d\n", ret);
1859 ar->state = ATH6KL_STATE_ON;
1862 case ATH6KL_STATE_DEEPSLEEP:
1863 if (ar->wmi->pwr_mode != ar->wmi->saved_pwr_mode) {
1864 ret = ath6kl_wmi_powermode_cmd(ar->wmi, 0,
1865 ar->wmi->saved_pwr_mode);
1867 ath6kl_warn("wmi powermode command failed during resume: %d\n",
1872 ar->state = ATH6KL_STATE_ON;
1876 case ATH6KL_STATE_CUTPOWER:
1877 ath6kl_dbg(ATH6KL_DBG_SUSPEND, "resume restoring power\n");
1879 ret = ath6kl_init_hw_start(ar);
1881 ath6kl_warn("Failed to boot hw in resume: %d\n", ret);
1895 /* hif layer decides what suspend mode to use */
1896 static int __ath6kl_cfg80211_suspend(struct wiphy *wiphy,
1897 struct cfg80211_wowlan *wow)
1899 struct ath6kl *ar = wiphy_priv(wiphy);
1901 return ath6kl_hif_suspend(ar, wow);
1904 static int __ath6kl_cfg80211_resume(struct wiphy *wiphy)
1906 struct ath6kl *ar = wiphy_priv(wiphy);
1908 return ath6kl_hif_resume(ar);
1912 * FIXME: WOW suspend mode is selected if the host sdio controller supports
1913 * both sdio irq wake up and keep power. The target pulls sdio data line to
1914 * wake up the host when WOW pattern matches. This causes sdio irq handler
1915 * is being called in the host side which internally hits ath6kl's RX path.
1917 * Since sdio interrupt is not disabled, RX path executes even before
1918 * the host executes the actual resume operation from PM module.
1920 * In the current scenario, WOW resume should happen before start processing
1921 * any data from the target. So It's required to perform WOW resume in RX path.
1922 * Ideally we should perform WOW resume only in the actual platform
1923 * resume path. This area needs bit rework to avoid WOW resume in RX path.
1925 * ath6kl_check_wow_status() is called from ath6kl_rx().
1927 void ath6kl_check_wow_status(struct ath6kl *ar)
1929 if (ar->state == ATH6KL_STATE_WOW)
1930 ath6kl_cfg80211_resume(ar);
1935 void ath6kl_check_wow_status(struct ath6kl *ar)
1940 static int ath6kl_set_channel(struct wiphy *wiphy, struct net_device *dev,
1941 struct ieee80211_channel *chan,
1942 enum nl80211_channel_type channel_type)
1944 struct ath6kl_vif *vif = netdev_priv(dev);
1946 if (!ath6kl_cfg80211_ready(vif))
1949 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: center_freq=%u hw_value=%u\n",
1950 __func__, chan->center_freq, chan->hw_value);
1951 vif->next_chan = chan->center_freq;
1956 static bool ath6kl_is_p2p_ie(const u8 *pos)
1958 return pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
1959 pos[2] == 0x50 && pos[3] == 0x6f &&
1960 pos[4] == 0x9a && pos[5] == 0x09;
1963 static int ath6kl_set_ap_probe_resp_ies(struct ath6kl_vif *vif,
1964 const u8 *ies, size_t ies_len)
1966 struct ath6kl *ar = vif->ar;
1973 * Filter out P2P IE(s) since they will be included depending on
1974 * the Probe Request frame in ath6kl_send_go_probe_resp().
1977 if (ies && ies_len) {
1978 buf = kmalloc(ies_len, GFP_KERNEL);
1982 while (pos + 1 < ies + ies_len) {
1983 if (pos + 2 + pos[1] > ies + ies_len)
1985 if (!ath6kl_is_p2p_ie(pos)) {
1986 memcpy(buf + len, pos, 2 + pos[1]);
1993 ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
1994 WMI_FRAME_PROBE_RESP, buf, len);
1999 static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev,
2000 struct beacon_parameters *info, bool add)
2002 struct ath6kl *ar = ath6kl_priv(dev);
2003 struct ath6kl_vif *vif = netdev_priv(dev);
2004 struct ieee80211_mgmt *mgmt;
2007 struct wmi_connect_cmd p;
2011 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: add=%d\n", __func__, add);
2013 if (!ath6kl_cfg80211_ready(vif))
2016 if (vif->next_mode != AP_NETWORK)
2019 if (info->beacon_ies) {
2020 res = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
2023 info->beacon_ies_len);
2027 if (info->proberesp_ies) {
2028 res = ath6kl_set_ap_probe_resp_ies(vif, info->proberesp_ies,
2029 info->proberesp_ies_len);
2033 if (info->assocresp_ies) {
2034 res = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
2035 WMI_FRAME_ASSOC_RESP,
2036 info->assocresp_ies,
2037 info->assocresp_ies_len);
2045 ar->ap_mode_bkey.valid = false;
2052 if (info->head == NULL)
2054 mgmt = (struct ieee80211_mgmt *) info->head;
2055 ies = mgmt->u.beacon.variable;
2056 if (ies > info->head + info->head_len)
2058 ies_len = info->head + info->head_len - ies;
2060 if (info->ssid == NULL)
2062 memcpy(vif->ssid, info->ssid, info->ssid_len);
2063 vif->ssid_len = info->ssid_len;
2064 if (info->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
2065 return -EOPNOTSUPP; /* TODO */
2067 ret = ath6kl_set_auth_type(vif, info->auth_type);
2071 memset(&p, 0, sizeof(p));
2073 for (i = 0; i < info->crypto.n_akm_suites; i++) {
2074 switch (info->crypto.akm_suites[i]) {
2075 case WLAN_AKM_SUITE_8021X:
2076 if (info->crypto.wpa_versions & NL80211_WPA_VERSION_1)
2077 p.auth_mode |= WPA_AUTH;
2078 if (info->crypto.wpa_versions & NL80211_WPA_VERSION_2)
2079 p.auth_mode |= WPA2_AUTH;
2081 case WLAN_AKM_SUITE_PSK:
2082 if (info->crypto.wpa_versions & NL80211_WPA_VERSION_1)
2083 p.auth_mode |= WPA_PSK_AUTH;
2084 if (info->crypto.wpa_versions & NL80211_WPA_VERSION_2)
2085 p.auth_mode |= WPA2_PSK_AUTH;
2089 if (p.auth_mode == 0)
2090 p.auth_mode = NONE_AUTH;
2091 vif->auth_mode = p.auth_mode;
2093 for (i = 0; i < info->crypto.n_ciphers_pairwise; i++) {
2094 switch (info->crypto.ciphers_pairwise[i]) {
2095 case WLAN_CIPHER_SUITE_WEP40:
2096 case WLAN_CIPHER_SUITE_WEP104:
2097 p.prwise_crypto_type |= WEP_CRYPT;
2099 case WLAN_CIPHER_SUITE_TKIP:
2100 p.prwise_crypto_type |= TKIP_CRYPT;
2102 case WLAN_CIPHER_SUITE_CCMP:
2103 p.prwise_crypto_type |= AES_CRYPT;
2105 case WLAN_CIPHER_SUITE_SMS4:
2106 p.prwise_crypto_type |= WAPI_CRYPT;
2110 if (p.prwise_crypto_type == 0) {
2111 p.prwise_crypto_type = NONE_CRYPT;
2112 ath6kl_set_cipher(vif, 0, true);
2113 } else if (info->crypto.n_ciphers_pairwise == 1)
2114 ath6kl_set_cipher(vif, info->crypto.ciphers_pairwise[0], true);
2116 switch (info->crypto.cipher_group) {
2117 case WLAN_CIPHER_SUITE_WEP40:
2118 case WLAN_CIPHER_SUITE_WEP104:
2119 p.grp_crypto_type = WEP_CRYPT;
2121 case WLAN_CIPHER_SUITE_TKIP:
2122 p.grp_crypto_type = TKIP_CRYPT;
2124 case WLAN_CIPHER_SUITE_CCMP:
2125 p.grp_crypto_type = AES_CRYPT;
2127 case WLAN_CIPHER_SUITE_SMS4:
2128 p.grp_crypto_type = WAPI_CRYPT;
2131 p.grp_crypto_type = NONE_CRYPT;
2134 ath6kl_set_cipher(vif, info->crypto.cipher_group, false);
2136 p.nw_type = AP_NETWORK;
2137 vif->nw_type = vif->next_mode;
2139 p.ssid_len = vif->ssid_len;
2140 memcpy(p.ssid, vif->ssid, vif->ssid_len);
2141 p.dot11_auth_mode = vif->dot11_auth_mode;
2142 p.ch = cpu_to_le16(vif->next_chan);
2144 res = ath6kl_wmi_ap_profile_commit(ar->wmi, vif->fw_vif_idx, &p);
2151 static int ath6kl_add_beacon(struct wiphy *wiphy, struct net_device *dev,
2152 struct beacon_parameters *info)
2154 return ath6kl_ap_beacon(wiphy, dev, info, true);
2157 static int ath6kl_set_beacon(struct wiphy *wiphy, struct net_device *dev,
2158 struct beacon_parameters *info)
2160 return ath6kl_ap_beacon(wiphy, dev, info, false);
2163 static int ath6kl_del_beacon(struct wiphy *wiphy, struct net_device *dev)
2165 struct ath6kl *ar = ath6kl_priv(dev);
2166 struct ath6kl_vif *vif = netdev_priv(dev);
2168 if (vif->nw_type != AP_NETWORK)
2170 if (!test_bit(CONNECTED, &vif->flags))
2173 ath6kl_wmi_disconnect_cmd(ar->wmi, vif->fw_vif_idx);
2174 clear_bit(CONNECTED, &vif->flags);
2179 static int ath6kl_change_station(struct wiphy *wiphy, struct net_device *dev,
2180 u8 *mac, struct station_parameters *params)
2182 struct ath6kl *ar = ath6kl_priv(dev);
2183 struct ath6kl_vif *vif = netdev_priv(dev);
2185 if (vif->nw_type != AP_NETWORK)
2188 /* Use this only for authorizing/unauthorizing a station */
2189 if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)))
2192 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
2193 return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx,
2194 WMI_AP_MLME_AUTHORIZE, mac, 0);
2195 return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx,
2196 WMI_AP_MLME_UNAUTHORIZE, mac, 0);
2199 static int ath6kl_remain_on_channel(struct wiphy *wiphy,
2200 struct net_device *dev,
2201 struct ieee80211_channel *chan,
2202 enum nl80211_channel_type channel_type,
2203 unsigned int duration,
2206 struct ath6kl *ar = ath6kl_priv(dev);
2207 struct ath6kl_vif *vif = netdev_priv(dev);
2210 /* TODO: if already pending or ongoing remain-on-channel,
2212 id = ++vif->last_roc_id;
2214 /* Do not use 0 as the cookie value */
2215 id = ++vif->last_roc_id;
2219 return ath6kl_wmi_remain_on_chnl_cmd(ar->wmi, vif->fw_vif_idx,
2220 chan->center_freq, duration);
2223 static int ath6kl_cancel_remain_on_channel(struct wiphy *wiphy,
2224 struct net_device *dev,
2227 struct ath6kl *ar = ath6kl_priv(dev);
2228 struct ath6kl_vif *vif = netdev_priv(dev);
2230 if (cookie != vif->last_roc_id)
2232 vif->last_cancel_roc_id = cookie;
2234 return ath6kl_wmi_cancel_remain_on_chnl_cmd(ar->wmi, vif->fw_vif_idx);
2237 static int ath6kl_send_go_probe_resp(struct ath6kl_vif *vif,
2238 const u8 *buf, size_t len,
2241 struct ath6kl *ar = vif->ar;
2246 const struct ieee80211_mgmt *mgmt;
2248 mgmt = (const struct ieee80211_mgmt *) buf;
2250 /* Include P2P IE(s) from the frame generated in user space. */
2252 p2p = kmalloc(len, GFP_KERNEL);
2257 pos = mgmt->u.probe_resp.variable;
2258 while (pos + 1 < buf + len) {
2259 if (pos + 2 + pos[1] > buf + len)
2261 if (ath6kl_is_p2p_ie(pos)) {
2262 memcpy(p2p + p2p_len, pos, 2 + pos[1]);
2263 p2p_len += 2 + pos[1];
2268 ret = ath6kl_wmi_send_probe_response_cmd(ar->wmi, vif->fw_vif_idx, freq,
2269 mgmt->da, p2p, p2p_len);
2274 static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
2275 struct ieee80211_channel *chan, bool offchan,
2276 enum nl80211_channel_type channel_type,
2277 bool channel_type_valid, unsigned int wait,
2278 const u8 *buf, size_t len, bool no_cck,
2279 bool dont_wait_for_ack, u64 *cookie)
2281 struct ath6kl *ar = ath6kl_priv(dev);
2282 struct ath6kl_vif *vif = netdev_priv(dev);
2284 const struct ieee80211_mgmt *mgmt;
2286 mgmt = (const struct ieee80211_mgmt *) buf;
2287 if (buf + len >= mgmt->u.probe_resp.variable &&
2288 vif->nw_type == AP_NETWORK && test_bit(CONNECTED, &vif->flags) &&
2289 ieee80211_is_probe_resp(mgmt->frame_control)) {
2291 * Send Probe Response frame in AP mode using a separate WMI
2292 * command to allow the target to fill in the generic IEs.
2294 *cookie = 0; /* TX status not supported */
2295 return ath6kl_send_go_probe_resp(vif, buf, len,
2299 id = vif->send_action_id++;
2302 * 0 is a reserved value in the WMI command and shall not be
2303 * used for the command.
2305 id = vif->send_action_id++;
2309 return ath6kl_wmi_send_action_cmd(ar->wmi, vif->fw_vif_idx, id,
2310 chan->center_freq, wait,
2314 static void ath6kl_mgmt_frame_register(struct wiphy *wiphy,
2315 struct net_device *dev,
2316 u16 frame_type, bool reg)
2318 struct ath6kl_vif *vif = netdev_priv(dev);
2320 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: frame_type=0x%x reg=%d\n",
2321 __func__, frame_type, reg);
2322 if (frame_type == IEEE80211_STYPE_PROBE_REQ) {
2324 * Note: This notification callback is not allowed to sleep, so
2325 * we cannot send WMI_PROBE_REQ_REPORT_CMD here. Instead, we
2326 * hardcode target to report Probe Request frames all the time.
2328 vif->probe_req_report = reg;
2332 static const struct ieee80211_txrx_stypes
2333 ath6kl_mgmt_stypes[NUM_NL80211_IFTYPES] = {
2334 [NL80211_IFTYPE_STATION] = {
2335 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
2336 BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
2337 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
2338 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
2340 [NL80211_IFTYPE_P2P_CLIENT] = {
2341 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
2342 BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
2343 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
2344 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
2346 [NL80211_IFTYPE_P2P_GO] = {
2347 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
2348 BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
2349 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
2350 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
2354 static struct cfg80211_ops ath6kl_cfg80211_ops = {
2355 .add_virtual_intf = ath6kl_cfg80211_add_iface,
2356 .del_virtual_intf = ath6kl_cfg80211_del_iface,
2357 .change_virtual_intf = ath6kl_cfg80211_change_iface,
2358 .scan = ath6kl_cfg80211_scan,
2359 .connect = ath6kl_cfg80211_connect,
2360 .disconnect = ath6kl_cfg80211_disconnect,
2361 .add_key = ath6kl_cfg80211_add_key,
2362 .get_key = ath6kl_cfg80211_get_key,
2363 .del_key = ath6kl_cfg80211_del_key,
2364 .set_default_key = ath6kl_cfg80211_set_default_key,
2365 .set_wiphy_params = ath6kl_cfg80211_set_wiphy_params,
2366 .set_tx_power = ath6kl_cfg80211_set_txpower,
2367 .get_tx_power = ath6kl_cfg80211_get_txpower,
2368 .set_power_mgmt = ath6kl_cfg80211_set_power_mgmt,
2369 .join_ibss = ath6kl_cfg80211_join_ibss,
2370 .leave_ibss = ath6kl_cfg80211_leave_ibss,
2371 .get_station = ath6kl_get_station,
2372 .set_pmksa = ath6kl_set_pmksa,
2373 .del_pmksa = ath6kl_del_pmksa,
2374 .flush_pmksa = ath6kl_flush_pmksa,
2375 CFG80211_TESTMODE_CMD(ath6kl_tm_cmd)
2377 .suspend = __ath6kl_cfg80211_suspend,
2378 .resume = __ath6kl_cfg80211_resume,
2380 .set_channel = ath6kl_set_channel,
2381 .add_beacon = ath6kl_add_beacon,
2382 .set_beacon = ath6kl_set_beacon,
2383 .del_beacon = ath6kl_del_beacon,
2384 .change_station = ath6kl_change_station,
2385 .remain_on_channel = ath6kl_remain_on_channel,
2386 .cancel_remain_on_channel = ath6kl_cancel_remain_on_channel,
2387 .mgmt_tx = ath6kl_mgmt_tx,
2388 .mgmt_frame_register = ath6kl_mgmt_frame_register,
2391 void ath6kl_cfg80211_stop(struct ath6kl *ar)
2393 struct ath6kl_vif *vif;
2395 /* FIXME: for multi vif */
2396 vif = ath6kl_vif_first(ar);
2398 /* save the current power mode before enabling power save */
2399 ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode;
2401 if (ath6kl_wmi_powermode_cmd(ar->wmi, 0, REC_POWER) != 0)
2402 ath6kl_warn("ath6kl_deep_sleep_enable: "
2403 "wmi_powermode_cmd failed\n");
2407 switch (vif->sme_state) {
2408 case SME_CONNECTING:
2409 cfg80211_connect_result(vif->ndev, vif->bssid, NULL, 0,
2411 WLAN_STATUS_UNSPECIFIED_FAILURE,
2417 * FIXME: oddly enough smeState is in DISCONNECTED during
2418 * suspend, why? Need to send disconnected event in that
2421 cfg80211_disconnected(vif->ndev, 0, NULL, 0, GFP_KERNEL);
2425 if (test_bit(CONNECTED, &vif->flags) ||
2426 test_bit(CONNECT_PEND, &vif->flags))
2427 ath6kl_wmi_disconnect_cmd(ar->wmi, vif->fw_vif_idx);
2429 vif->sme_state = SME_DISCONNECTED;
2430 clear_bit(CONNECTED, &vif->flags);
2431 clear_bit(CONNECT_PEND, &vif->flags);
2433 /* disable scanning */
2434 if (ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx, 0xFFFF, 0, 0,
2435 0, 0, 0, 0, 0, 0, 0) != 0)
2436 printk(KERN_WARNING "ath6kl: failed to disable scan "
2437 "during suspend\n");
2439 ath6kl_cfg80211_scan_complete_event(vif, true);
2442 struct ath6kl *ath6kl_core_alloc(struct device *dev)
2445 struct wiphy *wiphy;
2448 /* create a new wiphy for use with cfg80211 */
2449 wiphy = wiphy_new(&ath6kl_cfg80211_ops, sizeof(struct ath6kl));
2452 ath6kl_err("couldn't allocate wiphy device\n");
2456 ar = wiphy_priv(wiphy);
2457 if (!multi_norm_if_support)
2458 ar->p2p = !!ath6kl_p2p;
2462 if (multi_norm_if_support)
2463 ar->max_norm_iface = 2;
2465 ar->max_norm_iface = 1;
2467 /* FIXME: Remove this once the multivif support is enabled */
2468 ar->max_norm_iface = 1;
2470 spin_lock_init(&ar->lock);
2471 spin_lock_init(&ar->mcastpsq_lock);
2472 spin_lock_init(&ar->list_lock);
2474 init_waitqueue_head(&ar->event_wq);
2475 sema_init(&ar->sem, 1);
2477 INIT_LIST_HEAD(&ar->amsdu_rx_buffer_queue);
2478 INIT_LIST_HEAD(&ar->vif_list);
2480 clear_bit(WMI_ENABLED, &ar->flag);
2481 clear_bit(SKIP_SCAN, &ar->flag);
2482 clear_bit(DESTROY_IN_PROGRESS, &ar->flag);
2484 ar->listen_intvl_t = A_DEFAULT_LISTEN_INTERVAL;
2485 ar->listen_intvl_b = 0;
2489 memset(&ar->sc_params, 0, sizeof(ar->sc_params));
2490 ar->sc_params.short_scan_ratio = WMI_SHORTSCANRATIO_DEFAULT;
2491 ar->sc_params.scan_ctrl_flags = DEFAULT_SCAN_CTRL_FLAGS;
2492 ar->lrssi_roam_threshold = DEF_LRSSI_ROAM_THRESHOLD;
2494 ar->state = ATH6KL_STATE_OFF;
2496 memset((u8 *)ar->sta_list, 0,
2497 AP_MAX_NUM_STA * sizeof(struct ath6kl_sta));
2499 /* Init the PS queues */
2500 for (ctr = 0; ctr < AP_MAX_NUM_STA; ctr++) {
2501 spin_lock_init(&ar->sta_list[ctr].psq_lock);
2502 skb_queue_head_init(&ar->sta_list[ctr].psq);
2505 skb_queue_head_init(&ar->mcastpsq);
2507 memcpy(ar->ap_country_code, DEF_AP_COUNTRY_CODE, 3);
2512 int ath6kl_register_ieee80211_hw(struct ath6kl *ar)
2514 struct wiphy *wiphy = ar->wiphy;
2517 wiphy->mgmt_stypes = ath6kl_mgmt_stypes;
2519 wiphy->max_remain_on_channel_duration = 5000;
2521 /* set device pointer for wiphy */
2522 set_wiphy_dev(wiphy, ar->dev);
2524 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
2525 BIT(NL80211_IFTYPE_ADHOC) |
2526 BIT(NL80211_IFTYPE_AP);
2528 wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_GO) |
2529 BIT(NL80211_IFTYPE_P2P_CLIENT);
2532 /* max num of ssids that can be probed during scanning */
2533 wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX;
2534 wiphy->max_scan_ie_len = 1000; /* FIX: what is correct limit? */
2535 wiphy->bands[IEEE80211_BAND_2GHZ] = &ath6kl_band_2ghz;
2536 wiphy->bands[IEEE80211_BAND_5GHZ] = &ath6kl_band_5ghz;
2537 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2539 wiphy->cipher_suites = cipher_suites;
2540 wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
2542 wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
2543 WIPHY_WOWLAN_DISCONNECT |
2544 WIPHY_WOWLAN_GTK_REKEY_FAILURE |
2545 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
2546 WIPHY_WOWLAN_EAP_IDENTITY_REQ |
2547 WIPHY_WOWLAN_4WAY_HANDSHAKE;
2548 wiphy->wowlan.n_patterns = WOW_MAX_FILTERS_PER_LIST;
2549 wiphy->wowlan.pattern_min_len = 1;
2550 wiphy->wowlan.pattern_max_len = WOW_PATTERN_SIZE;
2552 ret = wiphy_register(wiphy);
2554 ath6kl_err("couldn't register wiphy device\n");
2561 static int ath6kl_init_if_data(struct ath6kl_vif *vif)
2563 vif->aggr_cntxt = aggr_init(vif->ndev);
2564 if (!vif->aggr_cntxt) {
2565 ath6kl_err("failed to initialize aggr\n");
2569 setup_timer(&vif->disconnect_timer, disconnect_timer_handler,
2570 (unsigned long) vif->ndev);
2571 set_bit(WMM_ENABLED, &vif->flags);
2572 spin_lock_init(&vif->if_lock);
2577 void ath6kl_deinit_if_data(struct ath6kl_vif *vif)
2579 struct ath6kl *ar = vif->ar;
2581 aggr_module_destroy(vif->aggr_cntxt);
2583 ar->avail_idx_map |= BIT(vif->fw_vif_idx);
2585 if (vif->nw_type == ADHOC_NETWORK)
2586 ar->ibss_if_active = false;
2588 unregister_netdevice(vif->ndev);
2593 struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name,
2594 enum nl80211_iftype type, u8 fw_vif_idx,
2597 struct net_device *ndev;
2598 struct ath6kl_vif *vif;
2600 ndev = alloc_netdev(sizeof(*vif), name, ether_setup);
2604 vif = netdev_priv(ndev);
2605 ndev->ieee80211_ptr = &vif->wdev;
2606 vif->wdev.wiphy = ar->wiphy;
2609 SET_NETDEV_DEV(ndev, wiphy_dev(vif->wdev.wiphy));
2610 vif->wdev.netdev = ndev;
2611 vif->wdev.iftype = type;
2612 vif->fw_vif_idx = fw_vif_idx;
2613 vif->nw_type = vif->next_mode = nw_type;
2615 memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN);
2616 if (fw_vif_idx != 0)
2617 ndev->dev_addr[0] = (ndev->dev_addr[0] ^ (1 << fw_vif_idx)) |
2622 ath6kl_init_control_info(vif);
2624 /* TODO: Pass interface specific pointer instead of ar */
2625 if (ath6kl_init_if_data(vif))
2628 if (register_netdevice(ndev))
2631 ar->avail_idx_map &= ~BIT(fw_vif_idx);
2632 vif->sme_state = SME_DISCONNECTED;
2633 set_bit(WLAN_ENABLED, &vif->flags);
2634 ar->wlan_pwr_state = WLAN_POWER_STATE_ON;
2635 set_bit(NETDEV_REGISTERED, &vif->flags);
2637 if (type == NL80211_IFTYPE_ADHOC)
2638 ar->ibss_if_active = true;
2640 spin_lock_bh(&ar->list_lock);
2641 list_add_tail(&vif->list, &ar->vif_list);
2642 spin_unlock_bh(&ar->list_lock);
2647 aggr_module_destroy(vif->aggr_cntxt);
2652 void ath6kl_deinit_ieee80211_hw(struct ath6kl *ar)
2654 wiphy_unregister(ar->wiphy);
2655 wiphy_free(ar->wiphy);