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 < ar->vif_max; 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 < ar->vif_max; 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);
435 ar->connect_ctrl_flags &= ~CONNECT_WPS_FLAG;
437 if (test_bit(CONNECTED, &vif->flags) &&
438 vif->ssid_len == sme->ssid_len &&
439 !memcmp(vif->ssid, sme->ssid, vif->ssid_len)) {
440 vif->reconnect_flag = true;
441 status = ath6kl_wmi_reconnect_cmd(ar->wmi, vif->fw_vif_idx,
447 ath6kl_err("wmi_reconnect_cmd failed\n");
451 } else if (vif->ssid_len == sme->ssid_len &&
452 !memcmp(vif->ssid, sme->ssid, vif->ssid_len)) {
453 ath6kl_disconnect(vif);
456 memset(vif->ssid, 0, sizeof(vif->ssid));
457 vif->ssid_len = sme->ssid_len;
458 memcpy(vif->ssid, sme->ssid, sme->ssid_len);
461 vif->ch_hint = sme->channel->center_freq;
463 memset(vif->req_bssid, 0, sizeof(vif->req_bssid));
464 if (sme->bssid && !is_broadcast_ether_addr(sme->bssid))
465 memcpy(vif->req_bssid, sme->bssid, sizeof(vif->req_bssid));
467 ath6kl_set_wpa_version(vif, sme->crypto.wpa_versions);
469 status = ath6kl_set_auth_type(vif, sme->auth_type);
475 if (sme->crypto.n_ciphers_pairwise)
476 ath6kl_set_cipher(vif, sme->crypto.ciphers_pairwise[0], true);
478 ath6kl_set_cipher(vif, 0, true);
480 ath6kl_set_cipher(vif, sme->crypto.cipher_group, false);
482 if (sme->crypto.n_akm_suites)
483 ath6kl_set_key_mgmt(vif, sme->crypto.akm_suites[0]);
485 if ((sme->key_len) &&
486 (vif->auth_mode == NONE_AUTH) &&
487 (vif->prwise_crypto == WEP_CRYPT)) {
488 struct ath6kl_key *key = NULL;
490 if (sme->key_idx < WMI_MIN_KEY_INDEX ||
491 sme->key_idx > WMI_MAX_KEY_INDEX) {
492 ath6kl_err("key index %d out of bounds\n",
498 key = &vif->keys[sme->key_idx];
499 key->key_len = sme->key_len;
500 memcpy(key->key, sme->key, key->key_len);
501 key->cipher = vif->prwise_crypto;
502 vif->def_txkey_index = sme->key_idx;
504 ath6kl_wmi_addkey_cmd(ar->wmi, vif->fw_vif_idx, sme->key_idx,
506 GROUP_USAGE | TX_USAGE,
509 key->key, KEY_OP_INIT_VAL, NULL,
513 if (!ar->usr_bss_filter) {
514 clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags);
515 if (ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
516 ALL_BSS_FILTER, 0) != 0) {
517 ath6kl_err("couldn't set bss filtering\n");
523 vif->nw_type = vif->next_mode;
525 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
526 "%s: connect called with authmode %d dot11 auth %d"
527 " PW crypto %d PW crypto len %d GRP crypto %d"
528 " GRP crypto len %d channel hint %u\n",
530 vif->auth_mode, vif->dot11_auth_mode, vif->prwise_crypto,
531 vif->prwise_crypto_len, vif->grp_crypto,
532 vif->grp_crypto_len, vif->ch_hint);
534 vif->reconnect_flag = 0;
535 status = ath6kl_wmi_connect_cmd(ar->wmi, vif->fw_vif_idx, vif->nw_type,
536 vif->dot11_auth_mode, vif->auth_mode,
538 vif->prwise_crypto_len,
539 vif->grp_crypto, vif->grp_crypto_len,
540 vif->ssid_len, vif->ssid,
541 vif->req_bssid, vif->ch_hint,
542 ar->connect_ctrl_flags);
546 if (status == -EINVAL) {
547 memset(vif->ssid, 0, sizeof(vif->ssid));
549 ath6kl_err("invalid request\n");
552 ath6kl_err("ath6kl_wmi_connect_cmd failed\n");
556 if ((!(ar->connect_ctrl_flags & CONNECT_DO_WPA_OFFLOAD)) &&
557 ((vif->auth_mode == WPA_PSK_AUTH)
558 || (vif->auth_mode == WPA2_PSK_AUTH))) {
559 mod_timer(&vif->disconnect_timer,
560 jiffies + msecs_to_jiffies(DISCON_TIMER_INTVAL));
563 ar->connect_ctrl_flags &= ~CONNECT_DO_WPA_OFFLOAD;
564 set_bit(CONNECT_PEND, &vif->flags);
569 static int ath6kl_add_bss_if_needed(struct ath6kl_vif *vif,
570 enum network_type nw_type,
572 struct ieee80211_channel *chan,
573 const u8 *beacon_ie, size_t beacon_ie_len)
575 struct ath6kl *ar = vif->ar;
576 struct cfg80211_bss *bss;
577 u16 cap_mask, cap_val;
580 if (nw_type & ADHOC_NETWORK) {
581 cap_mask = WLAN_CAPABILITY_IBSS;
582 cap_val = WLAN_CAPABILITY_IBSS;
584 cap_mask = WLAN_CAPABILITY_ESS;
585 cap_val = WLAN_CAPABILITY_ESS;
588 bss = cfg80211_get_bss(ar->wiphy, chan, bssid,
589 vif->ssid, vif->ssid_len,
593 * Since cfg80211 may not yet know about the BSS,
594 * generate a partial entry until the first BSS info
595 * event becomes available.
597 * Prepend SSID element since it is not included in the Beacon
598 * IEs from the target.
600 ie = kmalloc(2 + vif->ssid_len + beacon_ie_len, GFP_KERNEL);
603 ie[0] = WLAN_EID_SSID;
604 ie[1] = vif->ssid_len;
605 memcpy(ie + 2, vif->ssid, vif->ssid_len);
606 memcpy(ie + 2 + vif->ssid_len, beacon_ie, beacon_ie_len);
607 bss = cfg80211_inform_bss(ar->wiphy, chan,
608 bssid, 0, cap_val, 100,
609 ie, 2 + vif->ssid_len + beacon_ie_len,
612 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "added bss %pM to "
613 "cfg80211\n", bssid);
616 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "cfg80211 already has a bss "
622 cfg80211_put_bss(bss);
627 void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel,
628 u8 *bssid, u16 listen_intvl,
630 enum network_type nw_type,
631 u8 beacon_ie_len, u8 assoc_req_len,
632 u8 assoc_resp_len, u8 *assoc_info)
634 struct ieee80211_channel *chan;
635 struct ath6kl *ar = vif->ar;
637 /* capinfo + listen interval */
638 u8 assoc_req_ie_offset = sizeof(u16) + sizeof(u16);
640 /* capinfo + status code + associd */
641 u8 assoc_resp_ie_offset = sizeof(u16) + sizeof(u16) + sizeof(u16);
643 u8 *assoc_req_ie = assoc_info + beacon_ie_len + assoc_req_ie_offset;
644 u8 *assoc_resp_ie = assoc_info + beacon_ie_len + assoc_req_len +
645 assoc_resp_ie_offset;
647 assoc_req_len -= assoc_req_ie_offset;
648 assoc_resp_len -= assoc_resp_ie_offset;
651 * Store Beacon interval here; DTIM period will be available only once
652 * a Beacon frame from the AP is seen.
654 vif->assoc_bss_beacon_int = beacon_intvl;
655 clear_bit(DTIM_PERIOD_AVAIL, &vif->flags);
657 if (nw_type & ADHOC_NETWORK) {
658 if (vif->wdev.iftype != NL80211_IFTYPE_ADHOC) {
659 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
660 "%s: ath6k not in ibss mode\n", __func__);
665 if (nw_type & INFRA_NETWORK) {
666 if (vif->wdev.iftype != NL80211_IFTYPE_STATION &&
667 vif->wdev.iftype != NL80211_IFTYPE_P2P_CLIENT) {
668 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
669 "%s: ath6k not in station mode\n", __func__);
674 chan = ieee80211_get_channel(ar->wiphy, (int) channel);
676 if (ath6kl_add_bss_if_needed(vif, nw_type, bssid, chan, assoc_info,
677 beacon_ie_len) < 0) {
678 ath6kl_err("could not add cfg80211 bss entry\n");
682 if (nw_type & ADHOC_NETWORK) {
683 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "ad-hoc %s selected\n",
684 nw_type & ADHOC_CREATOR ? "creator" : "joiner");
685 cfg80211_ibss_joined(vif->ndev, bssid, GFP_KERNEL);
689 if (vif->sme_state == SME_CONNECTING) {
690 /* inform connect result to cfg80211 */
691 vif->sme_state = SME_CONNECTED;
692 cfg80211_connect_result(vif->ndev, bssid,
693 assoc_req_ie, assoc_req_len,
694 assoc_resp_ie, assoc_resp_len,
695 WLAN_STATUS_SUCCESS, GFP_KERNEL);
696 } else if (vif->sme_state == SME_CONNECTED) {
697 /* inform roam event to cfg80211 */
698 cfg80211_roamed(vif->ndev, chan, bssid,
699 assoc_req_ie, assoc_req_len,
700 assoc_resp_ie, assoc_resp_len, GFP_KERNEL);
704 static int ath6kl_cfg80211_disconnect(struct wiphy *wiphy,
705 struct net_device *dev, u16 reason_code)
707 struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(dev);
708 struct ath6kl_vif *vif = netdev_priv(dev);
710 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: reason=%u\n", __func__,
713 if (!ath6kl_cfg80211_ready(vif))
716 if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
717 ath6kl_err("busy, destroy in progress\n");
721 if (down_interruptible(&ar->sem)) {
722 ath6kl_err("busy, couldn't get access\n");
726 vif->reconnect_flag = 0;
727 ath6kl_disconnect(vif);
728 memset(vif->ssid, 0, sizeof(vif->ssid));
731 if (!test_bit(SKIP_SCAN, &ar->flag))
732 memset(vif->req_bssid, 0, sizeof(vif->req_bssid));
736 vif->sme_state = SME_DISCONNECTED;
741 void ath6kl_cfg80211_disconnect_event(struct ath6kl_vif *vif, u8 reason,
742 u8 *bssid, u8 assoc_resp_len,
743 u8 *assoc_info, u16 proto_reason)
745 struct ath6kl *ar = vif->ar;
748 cfg80211_scan_done(vif->scan_req, true);
749 vif->scan_req = NULL;
752 if (vif->nw_type & ADHOC_NETWORK) {
753 if (vif->wdev.iftype != NL80211_IFTYPE_ADHOC) {
754 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
755 "%s: ath6k not in ibss mode\n", __func__);
758 memset(bssid, 0, ETH_ALEN);
759 cfg80211_ibss_joined(vif->ndev, bssid, GFP_KERNEL);
763 if (vif->nw_type & INFRA_NETWORK) {
764 if (vif->wdev.iftype != NL80211_IFTYPE_STATION &&
765 vif->wdev.iftype != NL80211_IFTYPE_P2P_CLIENT) {
766 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
767 "%s: ath6k not in station mode\n", __func__);
773 * Send a disconnect command to target when a disconnect event is
774 * received with reason code other than 3 (DISCONNECT_CMD - disconnect
775 * request from host) to make the firmware stop trying to connect even
776 * after giving disconnect event. There will be one more disconnect
777 * event for this disconnect command with reason code DISCONNECT_CMD
778 * which will be notified to cfg80211.
781 if (reason != DISCONNECT_CMD) {
782 ath6kl_wmi_disconnect_cmd(ar->wmi, vif->fw_vif_idx);
786 clear_bit(CONNECT_PEND, &vif->flags);
788 if (vif->sme_state == SME_CONNECTING) {
789 cfg80211_connect_result(vif->ndev,
792 WLAN_STATUS_UNSPECIFIED_FAILURE,
794 } else if (vif->sme_state == SME_CONNECTED) {
795 cfg80211_disconnected(vif->ndev, reason,
796 NULL, 0, GFP_KERNEL);
799 vif->sme_state = SME_DISCONNECTED;
802 static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
803 struct cfg80211_scan_request *request)
805 struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
806 struct ath6kl_vif *vif = netdev_priv(ndev);
808 u16 *channels = NULL;
810 u32 force_fg_scan = 0;
812 if (!ath6kl_cfg80211_ready(vif))
815 if (!ar->usr_bss_filter) {
816 clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags);
817 ret = ath6kl_wmi_bssfilter_cmd(
818 ar->wmi, vif->fw_vif_idx,
819 (test_bit(CONNECTED, &vif->flags) ?
820 ALL_BUT_BSS_FILTER : ALL_BSS_FILTER), 0);
822 ath6kl_err("couldn't set bss filtering\n");
827 if (request->n_ssids && request->ssids[0].ssid_len) {
830 if (request->n_ssids > (MAX_PROBED_SSID_INDEX - 1))
831 request->n_ssids = MAX_PROBED_SSID_INDEX - 1;
833 for (i = 0; i < request->n_ssids; i++)
834 ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx,
835 i + 1, SPECIFIC_SSID_FLAG,
836 request->ssids[i].ssid_len,
837 request->ssids[i].ssid);
841 ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
843 request->ie, request->ie_len);
845 ath6kl_err("failed to set Probe Request appie for "
852 * Scan only the requested channels if the request specifies a set of
853 * channels. If the list is longer than the target supports, do not
854 * configure the list and instead, scan all available channels.
856 if (request->n_channels > 0 &&
857 request->n_channels <= WMI_MAX_CHANNELS) {
860 n_channels = request->n_channels;
862 channels = kzalloc(n_channels * sizeof(u16), GFP_KERNEL);
863 if (channels == NULL) {
864 ath6kl_warn("failed to set scan channels, "
865 "scan all channels");
869 for (i = 0; i < n_channels; i++)
870 channels[i] = request->channels[i]->center_freq;
873 if (test_bit(CONNECTED, &vif->flags))
876 ret = ath6kl_wmi_startscan_cmd(ar->wmi, vif->fw_vif_idx, WMI_LONG_SCAN,
877 force_fg_scan, false, 0, 0, n_channels,
880 ath6kl_err("wmi_startscan_cmd failed\n");
882 vif->scan_req = request;
889 void ath6kl_cfg80211_scan_complete_event(struct ath6kl_vif *vif, bool aborted)
891 struct ath6kl *ar = vif->ar;
894 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: status%s\n", __func__,
895 aborted ? " aborted" : "");
903 if (vif->scan_req->n_ssids && vif->scan_req->ssids[0].ssid_len) {
904 for (i = 0; i < vif->scan_req->n_ssids; i++) {
905 ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx,
906 i + 1, DISABLE_SSID_FLAG,
912 cfg80211_scan_done(vif->scan_req, aborted);
913 vif->scan_req = NULL;
916 static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
917 u8 key_index, bool pairwise,
919 struct key_params *params)
921 struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
922 struct ath6kl_vif *vif = netdev_priv(ndev);
923 struct ath6kl_key *key = NULL;
927 if (!ath6kl_cfg80211_ready(vif))
930 if (params->cipher == CCKM_KRK_CIPHER_SUITE) {
931 if (params->key_len != WMI_KRK_LEN)
933 return ath6kl_wmi_add_krk_cmd(ar->wmi, vif->fw_vif_idx,
937 if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
938 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
939 "%s: key index %d out of bounds\n", __func__,
944 key = &vif->keys[key_index];
945 memset(key, 0, sizeof(struct ath6kl_key));
948 key_usage = PAIRWISE_USAGE;
950 key_usage = GROUP_USAGE;
953 int seq_len = params->seq_len;
954 if (params->cipher == WLAN_CIPHER_SUITE_SMS4 &&
955 seq_len > ATH6KL_KEY_SEQ_LEN) {
956 /* Only first half of the WPI PN is configured */
957 seq_len = ATH6KL_KEY_SEQ_LEN;
959 if (params->key_len > WLAN_MAX_KEY_LEN ||
960 seq_len > sizeof(key->seq))
963 key->key_len = params->key_len;
964 memcpy(key->key, params->key, key->key_len);
965 key->seq_len = seq_len;
966 memcpy(key->seq, params->seq, key->seq_len);
967 key->cipher = params->cipher;
970 switch (key->cipher) {
971 case WLAN_CIPHER_SUITE_WEP40:
972 case WLAN_CIPHER_SUITE_WEP104:
973 key_type = WEP_CRYPT;
976 case WLAN_CIPHER_SUITE_TKIP:
977 key_type = TKIP_CRYPT;
980 case WLAN_CIPHER_SUITE_CCMP:
981 key_type = AES_CRYPT;
983 case WLAN_CIPHER_SUITE_SMS4:
984 key_type = WAPI_CRYPT;
991 if (((vif->auth_mode == WPA_PSK_AUTH)
992 || (vif->auth_mode == WPA2_PSK_AUTH))
993 && (key_usage & GROUP_USAGE))
994 del_timer(&vif->disconnect_timer);
996 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
997 "%s: index %d, key_len %d, key_type 0x%x, key_usage 0x%x, seq_len %d\n",
998 __func__, key_index, key->key_len, key_type,
999 key_usage, key->seq_len);
1001 if (vif->nw_type == AP_NETWORK && !pairwise &&
1002 (key_type == TKIP_CRYPT || key_type == AES_CRYPT) && params) {
1003 ar->ap_mode_bkey.valid = true;
1004 ar->ap_mode_bkey.key_index = key_index;
1005 ar->ap_mode_bkey.key_type = key_type;
1006 ar->ap_mode_bkey.key_len = key->key_len;
1007 memcpy(ar->ap_mode_bkey.key, key->key, key->key_len);
1008 if (!test_bit(CONNECTED, &vif->flags)) {
1009 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delay initial group "
1010 "key configuration until AP mode has been "
1013 * The key will be set in ath6kl_connect_ap_mode() once
1014 * the connected event is received from the target.
1020 if (vif->next_mode == AP_NETWORK && key_type == WEP_CRYPT &&
1021 !test_bit(CONNECTED, &vif->flags)) {
1023 * Store the key locally so that it can be re-configured after
1024 * the AP mode has properly started
1025 * (ath6kl_install_statioc_wep_keys).
1027 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delay WEP key configuration "
1028 "until AP mode has been started\n");
1029 vif->wep_key_list[key_index].key_len = key->key_len;
1030 memcpy(vif->wep_key_list[key_index].key, key->key,
1035 return ath6kl_wmi_addkey_cmd(ar->wmi, vif->fw_vif_idx, key_index,
1036 key_type, key_usage, key->key_len,
1037 key->seq, key->seq_len, key->key,
1039 (u8 *) mac_addr, SYNC_BOTH_WMIFLAG);
1042 static int ath6kl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
1043 u8 key_index, bool pairwise,
1046 struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
1047 struct ath6kl_vif *vif = netdev_priv(ndev);
1049 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
1051 if (!ath6kl_cfg80211_ready(vif))
1054 if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
1055 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1056 "%s: key index %d out of bounds\n", __func__,
1061 if (!vif->keys[key_index].key_len) {
1062 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1063 "%s: index %d is empty\n", __func__, key_index);
1067 vif->keys[key_index].key_len = 0;
1069 return ath6kl_wmi_deletekey_cmd(ar->wmi, vif->fw_vif_idx, key_index);
1072 static int ath6kl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
1073 u8 key_index, bool pairwise,
1074 const u8 *mac_addr, void *cookie,
1075 void (*callback) (void *cookie,
1076 struct key_params *))
1078 struct ath6kl_vif *vif = netdev_priv(ndev);
1079 struct ath6kl_key *key = NULL;
1080 struct key_params params;
1082 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
1084 if (!ath6kl_cfg80211_ready(vif))
1087 if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
1088 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1089 "%s: key index %d out of bounds\n", __func__,
1094 key = &vif->keys[key_index];
1095 memset(¶ms, 0, sizeof(params));
1096 params.cipher = key->cipher;
1097 params.key_len = key->key_len;
1098 params.seq_len = key->seq_len;
1099 params.seq = key->seq;
1100 params.key = key->key;
1102 callback(cookie, ¶ms);
1104 return key->key_len ? 0 : -ENOENT;
1107 static int ath6kl_cfg80211_set_default_key(struct wiphy *wiphy,
1108 struct net_device *ndev,
1109 u8 key_index, bool unicast,
1112 struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
1113 struct ath6kl_vif *vif = netdev_priv(ndev);
1114 struct ath6kl_key *key = NULL;
1116 enum crypto_type key_type = NONE_CRYPT;
1118 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
1120 if (!ath6kl_cfg80211_ready(vif))
1123 if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
1124 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1125 "%s: key index %d out of bounds\n",
1126 __func__, key_index);
1130 if (!vif->keys[key_index].key_len) {
1131 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: invalid key index %d\n",
1132 __func__, key_index);
1136 vif->def_txkey_index = key_index;
1137 key = &vif->keys[vif->def_txkey_index];
1138 key_usage = GROUP_USAGE;
1139 if (vif->prwise_crypto == WEP_CRYPT)
1140 key_usage |= TX_USAGE;
1142 key_type = vif->prwise_crypto;
1144 key_type = vif->grp_crypto;
1146 if (vif->next_mode == AP_NETWORK && !test_bit(CONNECTED, &vif->flags))
1147 return 0; /* Delay until AP mode has been started */
1149 return ath6kl_wmi_addkey_cmd(ar->wmi, vif->fw_vif_idx,
1150 vif->def_txkey_index,
1151 key_type, key_usage,
1152 key->key_len, key->seq, key->seq_len,
1154 KEY_OP_INIT_VAL, NULL,
1158 void ath6kl_cfg80211_tkip_micerr_event(struct ath6kl_vif *vif, u8 keyid,
1161 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1162 "%s: keyid %d, ismcast %d\n", __func__, keyid, ismcast);
1164 cfg80211_michael_mic_failure(vif->ndev, vif->bssid,
1165 (ismcast ? NL80211_KEYTYPE_GROUP :
1166 NL80211_KEYTYPE_PAIRWISE), keyid, NULL,
1170 static int ath6kl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1172 struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
1173 struct ath6kl_vif *vif;
1176 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: changed 0x%x\n", __func__,
1179 vif = ath6kl_vif_first(ar);
1183 if (!ath6kl_cfg80211_ready(vif))
1186 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1187 ret = ath6kl_wmi_set_rts_cmd(ar->wmi, wiphy->rts_threshold);
1189 ath6kl_err("ath6kl_wmi_set_rts_cmd failed\n");
1198 * The type nl80211_tx_power_setting replaces the following
1199 * data type from 2.6.36 onwards
1201 static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy,
1202 enum nl80211_tx_power_setting type,
1205 struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
1206 struct ath6kl_vif *vif;
1209 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type 0x%x, dbm %d\n", __func__,
1212 vif = ath6kl_vif_first(ar);
1216 if (!ath6kl_cfg80211_ready(vif))
1220 case NL80211_TX_POWER_AUTOMATIC:
1222 case NL80211_TX_POWER_LIMITED:
1223 ar->tx_pwr = ath6kl_dbm = dbm;
1226 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type 0x%x not supported\n",
1231 ath6kl_wmi_set_tx_pwr_cmd(ar->wmi, vif->fw_vif_idx, ath6kl_dbm);
1236 static int ath6kl_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
1238 struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
1239 struct ath6kl_vif *vif;
1241 vif = ath6kl_vif_first(ar);
1245 if (!ath6kl_cfg80211_ready(vif))
1248 if (test_bit(CONNECTED, &vif->flags)) {
1251 if (ath6kl_wmi_get_tx_pwr_cmd(ar->wmi, vif->fw_vif_idx) != 0) {
1252 ath6kl_err("ath6kl_wmi_get_tx_pwr_cmd failed\n");
1256 wait_event_interruptible_timeout(ar->event_wq, ar->tx_pwr != 0,
1259 if (signal_pending(current)) {
1260 ath6kl_err("target did not respond\n");
1269 static int ath6kl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
1270 struct net_device *dev,
1271 bool pmgmt, int timeout)
1273 struct ath6kl *ar = ath6kl_priv(dev);
1274 struct wmi_power_mode_cmd mode;
1275 struct ath6kl_vif *vif = netdev_priv(dev);
1277 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: pmgmt %d, timeout %d\n",
1278 __func__, pmgmt, timeout);
1280 if (!ath6kl_cfg80211_ready(vif))
1284 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: max perf\n", __func__);
1285 mode.pwr_mode = REC_POWER;
1287 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: rec power\n", __func__);
1288 mode.pwr_mode = MAX_PERF_POWER;
1291 if (ath6kl_wmi_powermode_cmd(ar->wmi, vif->fw_vif_idx,
1292 mode.pwr_mode) != 0) {
1293 ath6kl_err("wmi_powermode_cmd failed\n");
1300 static struct net_device *ath6kl_cfg80211_add_iface(struct wiphy *wiphy,
1302 enum nl80211_iftype type,
1304 struct vif_params *params)
1306 struct ath6kl *ar = wiphy_priv(wiphy);
1307 struct net_device *ndev;
1310 if (ar->num_vif == ar->vif_max) {
1311 ath6kl_err("Reached maximum number of supported vif\n");
1312 return ERR_PTR(-EINVAL);
1315 if (!ath6kl_is_valid_iftype(ar, type, &if_idx, &nw_type)) {
1316 ath6kl_err("Not a supported interface type\n");
1317 return ERR_PTR(-EINVAL);
1320 ndev = ath6kl_interface_add(ar, name, type, if_idx, nw_type);
1322 return ERR_PTR(-ENOMEM);
1329 static int ath6kl_cfg80211_del_iface(struct wiphy *wiphy,
1330 struct net_device *ndev)
1332 struct ath6kl *ar = wiphy_priv(wiphy);
1333 struct ath6kl_vif *vif = netdev_priv(ndev);
1335 spin_lock_bh(&ar->list_lock);
1336 list_del(&vif->list);
1337 spin_unlock_bh(&ar->list_lock);
1339 ath6kl_cleanup_vif(vif, test_bit(WMI_READY, &ar->flag));
1341 ath6kl_deinit_if_data(vif);
1346 static int ath6kl_cfg80211_change_iface(struct wiphy *wiphy,
1347 struct net_device *ndev,
1348 enum nl80211_iftype type, u32 *flags,
1349 struct vif_params *params)
1351 struct ath6kl_vif *vif = netdev_priv(ndev);
1353 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type %u\n", __func__, type);
1356 case NL80211_IFTYPE_STATION:
1357 vif->next_mode = INFRA_NETWORK;
1359 case NL80211_IFTYPE_ADHOC:
1360 vif->next_mode = ADHOC_NETWORK;
1362 case NL80211_IFTYPE_AP:
1363 vif->next_mode = AP_NETWORK;
1365 case NL80211_IFTYPE_P2P_CLIENT:
1366 vif->next_mode = INFRA_NETWORK;
1368 case NL80211_IFTYPE_P2P_GO:
1369 vif->next_mode = AP_NETWORK;
1372 ath6kl_err("invalid interface type %u\n", type);
1376 vif->wdev.iftype = type;
1381 static int ath6kl_cfg80211_join_ibss(struct wiphy *wiphy,
1382 struct net_device *dev,
1383 struct cfg80211_ibss_params *ibss_param)
1385 struct ath6kl *ar = ath6kl_priv(dev);
1386 struct ath6kl_vif *vif = netdev_priv(dev);
1389 if (!ath6kl_cfg80211_ready(vif))
1392 vif->ssid_len = ibss_param->ssid_len;
1393 memcpy(vif->ssid, ibss_param->ssid, vif->ssid_len);
1395 if (ibss_param->channel)
1396 vif->ch_hint = ibss_param->channel->center_freq;
1398 if (ibss_param->channel_fixed) {
1400 * TODO: channel_fixed: The channel should be fixed, do not
1401 * search for IBSSs to join on other channels. Target
1402 * firmware does not support this feature, needs to be
1408 memset(vif->req_bssid, 0, sizeof(vif->req_bssid));
1409 if (ibss_param->bssid && !is_broadcast_ether_addr(ibss_param->bssid))
1410 memcpy(vif->req_bssid, ibss_param->bssid,
1411 sizeof(vif->req_bssid));
1413 ath6kl_set_wpa_version(vif, 0);
1415 status = ath6kl_set_auth_type(vif, NL80211_AUTHTYPE_OPEN_SYSTEM);
1419 if (ibss_param->privacy) {
1420 ath6kl_set_cipher(vif, WLAN_CIPHER_SUITE_WEP40, true);
1421 ath6kl_set_cipher(vif, WLAN_CIPHER_SUITE_WEP40, false);
1423 ath6kl_set_cipher(vif, 0, true);
1424 ath6kl_set_cipher(vif, 0, false);
1427 vif->nw_type = vif->next_mode;
1429 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1430 "%s: connect called with authmode %d dot11 auth %d"
1431 " PW crypto %d PW crypto len %d GRP crypto %d"
1432 " GRP crypto len %d channel hint %u\n",
1434 vif->auth_mode, vif->dot11_auth_mode, vif->prwise_crypto,
1435 vif->prwise_crypto_len, vif->grp_crypto,
1436 vif->grp_crypto_len, vif->ch_hint);
1438 status = ath6kl_wmi_connect_cmd(ar->wmi, vif->fw_vif_idx, vif->nw_type,
1439 vif->dot11_auth_mode, vif->auth_mode,
1441 vif->prwise_crypto_len,
1442 vif->grp_crypto, vif->grp_crypto_len,
1443 vif->ssid_len, vif->ssid,
1444 vif->req_bssid, vif->ch_hint,
1445 ar->connect_ctrl_flags);
1446 set_bit(CONNECT_PEND, &vif->flags);
1451 static int ath6kl_cfg80211_leave_ibss(struct wiphy *wiphy,
1452 struct net_device *dev)
1454 struct ath6kl_vif *vif = netdev_priv(dev);
1456 if (!ath6kl_cfg80211_ready(vif))
1459 ath6kl_disconnect(vif);
1460 memset(vif->ssid, 0, sizeof(vif->ssid));
1466 static const u32 cipher_suites[] = {
1467 WLAN_CIPHER_SUITE_WEP40,
1468 WLAN_CIPHER_SUITE_WEP104,
1469 WLAN_CIPHER_SUITE_TKIP,
1470 WLAN_CIPHER_SUITE_CCMP,
1471 CCKM_KRK_CIPHER_SUITE,
1472 WLAN_CIPHER_SUITE_SMS4,
1475 static bool is_rate_legacy(s32 rate)
1477 static const s32 legacy[] = { 1000, 2000, 5500, 11000,
1478 6000, 9000, 12000, 18000, 24000,
1483 for (i = 0; i < ARRAY_SIZE(legacy); i++)
1484 if (rate == legacy[i])
1490 static bool is_rate_ht20(s32 rate, u8 *mcs, bool *sgi)
1492 static const s32 ht20[] = { 6500, 13000, 19500, 26000, 39000,
1493 52000, 58500, 65000, 72200
1497 for (i = 0; i < ARRAY_SIZE(ht20); i++) {
1498 if (rate == ht20[i]) {
1499 if (i == ARRAY_SIZE(ht20) - 1)
1500 /* last rate uses sgi */
1512 static bool is_rate_ht40(s32 rate, u8 *mcs, bool *sgi)
1514 static const s32 ht40[] = { 13500, 27000, 40500, 54000,
1515 81000, 108000, 121500, 135000,
1520 for (i = 0; i < ARRAY_SIZE(ht40); i++) {
1521 if (rate == ht40[i]) {
1522 if (i == ARRAY_SIZE(ht40) - 1)
1523 /* last rate uses sgi */
1536 static int ath6kl_get_station(struct wiphy *wiphy, struct net_device *dev,
1537 u8 *mac, struct station_info *sinfo)
1539 struct ath6kl *ar = ath6kl_priv(dev);
1540 struct ath6kl_vif *vif = netdev_priv(dev);
1547 if (memcmp(mac, vif->bssid, ETH_ALEN) != 0)
1550 if (down_interruptible(&ar->sem))
1553 set_bit(STATS_UPDATE_PEND, &vif->flags);
1555 ret = ath6kl_wmi_get_stats_cmd(ar->wmi, vif->fw_vif_idx);
1562 left = wait_event_interruptible_timeout(ar->event_wq,
1563 !test_bit(STATS_UPDATE_PEND,
1574 if (vif->target_stats.rx_byte) {
1575 sinfo->rx_bytes = vif->target_stats.rx_byte;
1576 sinfo->filled |= STATION_INFO_RX_BYTES;
1577 sinfo->rx_packets = vif->target_stats.rx_pkt;
1578 sinfo->filled |= STATION_INFO_RX_PACKETS;
1581 if (vif->target_stats.tx_byte) {
1582 sinfo->tx_bytes = vif->target_stats.tx_byte;
1583 sinfo->filled |= STATION_INFO_TX_BYTES;
1584 sinfo->tx_packets = vif->target_stats.tx_pkt;
1585 sinfo->filled |= STATION_INFO_TX_PACKETS;
1588 sinfo->signal = vif->target_stats.cs_rssi;
1589 sinfo->filled |= STATION_INFO_SIGNAL;
1591 rate = vif->target_stats.tx_ucast_rate;
1593 if (is_rate_legacy(rate)) {
1594 sinfo->txrate.legacy = rate / 100;
1595 } else if (is_rate_ht20(rate, &mcs, &sgi)) {
1597 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
1598 sinfo->txrate.mcs = mcs - 1;
1600 sinfo->txrate.mcs = mcs;
1603 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
1604 } else if (is_rate_ht40(rate, &mcs, &sgi)) {
1606 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
1607 sinfo->txrate.mcs = mcs - 1;
1609 sinfo->txrate.mcs = mcs;
1612 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
1613 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
1615 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1616 "invalid rate from stats: %d\n", rate);
1617 ath6kl_debug_war(ar, ATH6KL_WAR_INVALID_RATE);
1621 sinfo->filled |= STATION_INFO_TX_BITRATE;
1623 if (test_bit(CONNECTED, &vif->flags) &&
1624 test_bit(DTIM_PERIOD_AVAIL, &vif->flags) &&
1625 vif->nw_type == INFRA_NETWORK) {
1626 sinfo->filled |= STATION_INFO_BSS_PARAM;
1627 sinfo->bss_param.flags = 0;
1628 sinfo->bss_param.dtim_period = vif->assoc_bss_dtim_period;
1629 sinfo->bss_param.beacon_interval = vif->assoc_bss_beacon_int;
1635 static int ath6kl_set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1636 struct cfg80211_pmksa *pmksa)
1638 struct ath6kl *ar = ath6kl_priv(netdev);
1639 struct ath6kl_vif *vif = netdev_priv(netdev);
1641 return ath6kl_wmi_setpmkid_cmd(ar->wmi, vif->fw_vif_idx, pmksa->bssid,
1642 pmksa->pmkid, true);
1645 static int ath6kl_del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1646 struct cfg80211_pmksa *pmksa)
1648 struct ath6kl *ar = ath6kl_priv(netdev);
1649 struct ath6kl_vif *vif = netdev_priv(netdev);
1651 return ath6kl_wmi_setpmkid_cmd(ar->wmi, vif->fw_vif_idx, pmksa->bssid,
1652 pmksa->pmkid, false);
1655 static int ath6kl_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
1657 struct ath6kl *ar = ath6kl_priv(netdev);
1658 struct ath6kl_vif *vif = netdev_priv(netdev);
1660 if (test_bit(CONNECTED, &vif->flags))
1661 return ath6kl_wmi_setpmkid_cmd(ar->wmi, vif->fw_vif_idx,
1662 vif->bssid, NULL, false);
1666 static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
1668 struct ath6kl_vif *vif;
1672 u8 mask[WOW_MASK_SIZE];
1674 vif = ath6kl_vif_first(ar);
1678 if (!ath6kl_cfg80211_ready(vif))
1681 if (!test_bit(CONNECTED, &vif->flags))
1684 /* Clear existing WOW patterns */
1685 for (i = 0; i < WOW_MAX_FILTERS_PER_LIST; i++)
1686 ath6kl_wmi_del_wow_pattern_cmd(ar->wmi, vif->fw_vif_idx,
1688 /* Configure new WOW patterns */
1689 for (i = 0; i < wow->n_patterns; i++) {
1692 * Convert given nl80211 specific mask value to equivalent
1693 * driver specific mask value and send it to the chip along
1694 * with patterns. For example, If the mask value defined in
1695 * struct cfg80211_wowlan is 0xA (equivalent binary is 1010),
1696 * then equivalent driver specific mask value is
1697 * "0xFF 0x00 0xFF 0x00".
1699 memset(&mask, 0, sizeof(mask));
1700 for (pos = 0; pos < wow->patterns[i].pattern_len; pos++) {
1701 if (wow->patterns[i].mask[pos / 8] & (0x1 << (pos % 8)))
1705 * Note: Pattern's offset is not passed as part of wowlan
1706 * parameter from CFG layer. So it's always passed as ZERO
1707 * to the firmware. It means, given WOW patterns are always
1708 * matched from the first byte of received pkt in the firmware.
1710 ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
1711 vif->fw_vif_idx, WOW_LIST_ID,
1712 wow->patterns[i].pattern_len,
1713 0 /* pattern offset */,
1714 wow->patterns[i].pattern, mask);
1719 if (wow->disconnect)
1720 filter |= WOW_FILTER_OPTION_NWK_DISASSOC;
1723 filter |= WOW_FILTER_OPTION_MAGIC_PACKET;
1725 if (wow->gtk_rekey_failure)
1726 filter |= WOW_FILTER_OPTION_GTK_ERROR;
1728 if (wow->eap_identity_req)
1729 filter |= WOW_FILTER_OPTION_EAP_REQ;
1731 if (wow->four_way_handshake)
1732 filter |= WOW_FILTER_OPTION_8021X_4WAYHS;
1734 ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, vif->fw_vif_idx,
1735 ATH6KL_WOW_MODE_ENABLE,
1737 WOW_HOST_REQ_DELAY);
1741 ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
1742 ATH6KL_HOST_MODE_ASLEEP);
1746 if (ar->tx_pending[ar->ctrl_ep]) {
1747 left = wait_event_interruptible_timeout(ar->event_wq,
1748 ar->tx_pending[ar->ctrl_ep] == 0, WMI_TIMEOUT);
1750 ath6kl_warn("clear wmi ctrl data timeout\n");
1752 } else if (left < 0) {
1753 ath6kl_warn("clear wmi ctrl data failed: %d\n", left);
1761 static int ath6kl_wow_resume(struct ath6kl *ar)
1763 struct ath6kl_vif *vif;
1766 vif = ath6kl_vif_first(ar);
1770 ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
1771 ATH6KL_HOST_MODE_AWAKE);
1775 int ath6kl_cfg80211_suspend(struct ath6kl *ar,
1776 enum ath6kl_cfg_suspend_mode mode,
1777 struct cfg80211_wowlan *wow)
1782 case ATH6KL_CFG_SUSPEND_WOW:
1784 ath6kl_dbg(ATH6KL_DBG_SUSPEND, "wow mode suspend\n");
1786 /* Flush all non control pkts in TX path */
1787 ath6kl_tx_data_cleanup(ar);
1789 ret = ath6kl_wow_suspend(ar, wow);
1791 ath6kl_err("wow suspend failed: %d\n", ret);
1794 ar->state = ATH6KL_STATE_WOW;
1797 case ATH6KL_CFG_SUSPEND_DEEPSLEEP:
1799 ath6kl_cfg80211_stop(ar);
1801 /* save the current power mode before enabling power save */
1802 ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode;
1804 ret = ath6kl_wmi_powermode_cmd(ar->wmi, 0, REC_POWER);
1806 ath6kl_warn("wmi powermode command failed during suspend: %d\n",
1810 ar->state = ATH6KL_STATE_DEEPSLEEP;
1814 case ATH6KL_CFG_SUSPEND_CUTPOWER:
1816 ath6kl_cfg80211_stop(ar);
1818 if (ar->state == ATH6KL_STATE_OFF) {
1819 ath6kl_dbg(ATH6KL_DBG_SUSPEND,
1820 "suspend hw off, no action for cutpower\n");
1824 ath6kl_dbg(ATH6KL_DBG_SUSPEND, "suspend cutting power\n");
1826 ret = ath6kl_init_hw_stop(ar);
1828 ath6kl_warn("failed to stop hw during suspend: %d\n",
1832 ar->state = ATH6KL_STATE_CUTPOWER;
1843 int ath6kl_cfg80211_resume(struct ath6kl *ar)
1847 switch (ar->state) {
1848 case ATH6KL_STATE_WOW:
1849 ath6kl_dbg(ATH6KL_DBG_SUSPEND, "wow mode resume\n");
1851 ret = ath6kl_wow_resume(ar);
1853 ath6kl_warn("wow mode resume failed: %d\n", ret);
1857 ar->state = ATH6KL_STATE_ON;
1860 case ATH6KL_STATE_DEEPSLEEP:
1861 if (ar->wmi->pwr_mode != ar->wmi->saved_pwr_mode) {
1862 ret = ath6kl_wmi_powermode_cmd(ar->wmi, 0,
1863 ar->wmi->saved_pwr_mode);
1865 ath6kl_warn("wmi powermode command failed during resume: %d\n",
1870 ar->state = ATH6KL_STATE_ON;
1874 case ATH6KL_STATE_CUTPOWER:
1875 ath6kl_dbg(ATH6KL_DBG_SUSPEND, "resume restoring power\n");
1877 ret = ath6kl_init_hw_start(ar);
1879 ath6kl_warn("Failed to boot hw in resume: %d\n", ret);
1893 /* hif layer decides what suspend mode to use */
1894 static int __ath6kl_cfg80211_suspend(struct wiphy *wiphy,
1895 struct cfg80211_wowlan *wow)
1897 struct ath6kl *ar = wiphy_priv(wiphy);
1899 return ath6kl_hif_suspend(ar, wow);
1902 static int __ath6kl_cfg80211_resume(struct wiphy *wiphy)
1904 struct ath6kl *ar = wiphy_priv(wiphy);
1906 return ath6kl_hif_resume(ar);
1910 * FIXME: WOW suspend mode is selected if the host sdio controller supports
1911 * both sdio irq wake up and keep power. The target pulls sdio data line to
1912 * wake up the host when WOW pattern matches. This causes sdio irq handler
1913 * is being called in the host side which internally hits ath6kl's RX path.
1915 * Since sdio interrupt is not disabled, RX path executes even before
1916 * the host executes the actual resume operation from PM module.
1918 * In the current scenario, WOW resume should happen before start processing
1919 * any data from the target. So It's required to perform WOW resume in RX path.
1920 * Ideally we should perform WOW resume only in the actual platform
1921 * resume path. This area needs bit rework to avoid WOW resume in RX path.
1923 * ath6kl_check_wow_status() is called from ath6kl_rx().
1925 void ath6kl_check_wow_status(struct ath6kl *ar)
1927 if (ar->state == ATH6KL_STATE_WOW)
1928 ath6kl_cfg80211_resume(ar);
1933 void ath6kl_check_wow_status(struct ath6kl *ar)
1938 static int ath6kl_set_channel(struct wiphy *wiphy, struct net_device *dev,
1939 struct ieee80211_channel *chan,
1940 enum nl80211_channel_type channel_type)
1942 struct ath6kl_vif *vif = netdev_priv(dev);
1944 if (!ath6kl_cfg80211_ready(vif))
1947 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: center_freq=%u hw_value=%u\n",
1948 __func__, chan->center_freq, chan->hw_value);
1949 vif->next_chan = chan->center_freq;
1954 static bool ath6kl_is_p2p_ie(const u8 *pos)
1956 return pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
1957 pos[2] == 0x50 && pos[3] == 0x6f &&
1958 pos[4] == 0x9a && pos[5] == 0x09;
1961 static int ath6kl_set_ap_probe_resp_ies(struct ath6kl_vif *vif,
1962 const u8 *ies, size_t ies_len)
1964 struct ath6kl *ar = vif->ar;
1971 * Filter out P2P IE(s) since they will be included depending on
1972 * the Probe Request frame in ath6kl_send_go_probe_resp().
1975 if (ies && ies_len) {
1976 buf = kmalloc(ies_len, GFP_KERNEL);
1980 while (pos + 1 < ies + ies_len) {
1981 if (pos + 2 + pos[1] > ies + ies_len)
1983 if (!ath6kl_is_p2p_ie(pos)) {
1984 memcpy(buf + len, pos, 2 + pos[1]);
1991 ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
1992 WMI_FRAME_PROBE_RESP, buf, len);
1997 static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev,
1998 struct beacon_parameters *info, bool add)
2000 struct ath6kl *ar = ath6kl_priv(dev);
2001 struct ath6kl_vif *vif = netdev_priv(dev);
2002 struct ieee80211_mgmt *mgmt;
2005 struct wmi_connect_cmd p;
2009 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: add=%d\n", __func__, add);
2011 if (!ath6kl_cfg80211_ready(vif))
2014 if (vif->next_mode != AP_NETWORK)
2017 if (info->beacon_ies) {
2018 res = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
2021 info->beacon_ies_len);
2025 if (info->proberesp_ies) {
2026 res = ath6kl_set_ap_probe_resp_ies(vif, info->proberesp_ies,
2027 info->proberesp_ies_len);
2031 if (info->assocresp_ies) {
2032 res = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
2033 WMI_FRAME_ASSOC_RESP,
2034 info->assocresp_ies,
2035 info->assocresp_ies_len);
2043 ar->ap_mode_bkey.valid = false;
2050 if (info->head == NULL)
2052 mgmt = (struct ieee80211_mgmt *) info->head;
2053 ies = mgmt->u.beacon.variable;
2054 if (ies > info->head + info->head_len)
2056 ies_len = info->head + info->head_len - ies;
2058 if (info->ssid == NULL)
2060 memcpy(vif->ssid, info->ssid, info->ssid_len);
2061 vif->ssid_len = info->ssid_len;
2062 if (info->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
2063 return -EOPNOTSUPP; /* TODO */
2065 ret = ath6kl_set_auth_type(vif, info->auth_type);
2069 memset(&p, 0, sizeof(p));
2071 for (i = 0; i < info->crypto.n_akm_suites; i++) {
2072 switch (info->crypto.akm_suites[i]) {
2073 case WLAN_AKM_SUITE_8021X:
2074 if (info->crypto.wpa_versions & NL80211_WPA_VERSION_1)
2075 p.auth_mode |= WPA_AUTH;
2076 if (info->crypto.wpa_versions & NL80211_WPA_VERSION_2)
2077 p.auth_mode |= WPA2_AUTH;
2079 case WLAN_AKM_SUITE_PSK:
2080 if (info->crypto.wpa_versions & NL80211_WPA_VERSION_1)
2081 p.auth_mode |= WPA_PSK_AUTH;
2082 if (info->crypto.wpa_versions & NL80211_WPA_VERSION_2)
2083 p.auth_mode |= WPA2_PSK_AUTH;
2087 if (p.auth_mode == 0)
2088 p.auth_mode = NONE_AUTH;
2089 vif->auth_mode = p.auth_mode;
2091 for (i = 0; i < info->crypto.n_ciphers_pairwise; i++) {
2092 switch (info->crypto.ciphers_pairwise[i]) {
2093 case WLAN_CIPHER_SUITE_WEP40:
2094 case WLAN_CIPHER_SUITE_WEP104:
2095 p.prwise_crypto_type |= WEP_CRYPT;
2097 case WLAN_CIPHER_SUITE_TKIP:
2098 p.prwise_crypto_type |= TKIP_CRYPT;
2100 case WLAN_CIPHER_SUITE_CCMP:
2101 p.prwise_crypto_type |= AES_CRYPT;
2103 case WLAN_CIPHER_SUITE_SMS4:
2104 p.prwise_crypto_type |= WAPI_CRYPT;
2108 if (p.prwise_crypto_type == 0) {
2109 p.prwise_crypto_type = NONE_CRYPT;
2110 ath6kl_set_cipher(vif, 0, true);
2111 } else if (info->crypto.n_ciphers_pairwise == 1)
2112 ath6kl_set_cipher(vif, info->crypto.ciphers_pairwise[0], true);
2114 switch (info->crypto.cipher_group) {
2115 case WLAN_CIPHER_SUITE_WEP40:
2116 case WLAN_CIPHER_SUITE_WEP104:
2117 p.grp_crypto_type = WEP_CRYPT;
2119 case WLAN_CIPHER_SUITE_TKIP:
2120 p.grp_crypto_type = TKIP_CRYPT;
2122 case WLAN_CIPHER_SUITE_CCMP:
2123 p.grp_crypto_type = AES_CRYPT;
2125 case WLAN_CIPHER_SUITE_SMS4:
2126 p.grp_crypto_type = WAPI_CRYPT;
2129 p.grp_crypto_type = NONE_CRYPT;
2132 ath6kl_set_cipher(vif, info->crypto.cipher_group, false);
2134 p.nw_type = AP_NETWORK;
2135 vif->nw_type = vif->next_mode;
2137 p.ssid_len = vif->ssid_len;
2138 memcpy(p.ssid, vif->ssid, vif->ssid_len);
2139 p.dot11_auth_mode = vif->dot11_auth_mode;
2140 p.ch = cpu_to_le16(vif->next_chan);
2142 res = ath6kl_wmi_ap_profile_commit(ar->wmi, vif->fw_vif_idx, &p);
2149 static int ath6kl_add_beacon(struct wiphy *wiphy, struct net_device *dev,
2150 struct beacon_parameters *info)
2152 return ath6kl_ap_beacon(wiphy, dev, info, true);
2155 static int ath6kl_set_beacon(struct wiphy *wiphy, struct net_device *dev,
2156 struct beacon_parameters *info)
2158 return ath6kl_ap_beacon(wiphy, dev, info, false);
2161 static int ath6kl_del_beacon(struct wiphy *wiphy, struct net_device *dev)
2163 struct ath6kl *ar = ath6kl_priv(dev);
2164 struct ath6kl_vif *vif = netdev_priv(dev);
2166 if (vif->nw_type != AP_NETWORK)
2168 if (!test_bit(CONNECTED, &vif->flags))
2171 ath6kl_wmi_disconnect_cmd(ar->wmi, vif->fw_vif_idx);
2172 clear_bit(CONNECTED, &vif->flags);
2177 static int ath6kl_change_station(struct wiphy *wiphy, struct net_device *dev,
2178 u8 *mac, struct station_parameters *params)
2180 struct ath6kl *ar = ath6kl_priv(dev);
2181 struct ath6kl_vif *vif = netdev_priv(dev);
2183 if (vif->nw_type != AP_NETWORK)
2186 /* Use this only for authorizing/unauthorizing a station */
2187 if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)))
2190 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
2191 return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx,
2192 WMI_AP_MLME_AUTHORIZE, mac, 0);
2193 return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx,
2194 WMI_AP_MLME_UNAUTHORIZE, mac, 0);
2197 static int ath6kl_remain_on_channel(struct wiphy *wiphy,
2198 struct net_device *dev,
2199 struct ieee80211_channel *chan,
2200 enum nl80211_channel_type channel_type,
2201 unsigned int duration,
2204 struct ath6kl *ar = ath6kl_priv(dev);
2205 struct ath6kl_vif *vif = netdev_priv(dev);
2208 /* TODO: if already pending or ongoing remain-on-channel,
2210 id = ++vif->last_roc_id;
2212 /* Do not use 0 as the cookie value */
2213 id = ++vif->last_roc_id;
2217 return ath6kl_wmi_remain_on_chnl_cmd(ar->wmi, vif->fw_vif_idx,
2218 chan->center_freq, duration);
2221 static int ath6kl_cancel_remain_on_channel(struct wiphy *wiphy,
2222 struct net_device *dev,
2225 struct ath6kl *ar = ath6kl_priv(dev);
2226 struct ath6kl_vif *vif = netdev_priv(dev);
2228 if (cookie != vif->last_roc_id)
2230 vif->last_cancel_roc_id = cookie;
2232 return ath6kl_wmi_cancel_remain_on_chnl_cmd(ar->wmi, vif->fw_vif_idx);
2235 static int ath6kl_send_go_probe_resp(struct ath6kl_vif *vif,
2236 const u8 *buf, size_t len,
2239 struct ath6kl *ar = vif->ar;
2244 const struct ieee80211_mgmt *mgmt;
2246 mgmt = (const struct ieee80211_mgmt *) buf;
2248 /* Include P2P IE(s) from the frame generated in user space. */
2250 p2p = kmalloc(len, GFP_KERNEL);
2255 pos = mgmt->u.probe_resp.variable;
2256 while (pos + 1 < buf + len) {
2257 if (pos + 2 + pos[1] > buf + len)
2259 if (ath6kl_is_p2p_ie(pos)) {
2260 memcpy(p2p + p2p_len, pos, 2 + pos[1]);
2261 p2p_len += 2 + pos[1];
2266 ret = ath6kl_wmi_send_probe_response_cmd(ar->wmi, vif->fw_vif_idx, freq,
2267 mgmt->da, p2p, p2p_len);
2272 static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
2273 struct ieee80211_channel *chan, bool offchan,
2274 enum nl80211_channel_type channel_type,
2275 bool channel_type_valid, unsigned int wait,
2276 const u8 *buf, size_t len, bool no_cck,
2277 bool dont_wait_for_ack, u64 *cookie)
2279 struct ath6kl *ar = ath6kl_priv(dev);
2280 struct ath6kl_vif *vif = netdev_priv(dev);
2282 const struct ieee80211_mgmt *mgmt;
2284 mgmt = (const struct ieee80211_mgmt *) buf;
2285 if (buf + len >= mgmt->u.probe_resp.variable &&
2286 vif->nw_type == AP_NETWORK && test_bit(CONNECTED, &vif->flags) &&
2287 ieee80211_is_probe_resp(mgmt->frame_control)) {
2289 * Send Probe Response frame in AP mode using a separate WMI
2290 * command to allow the target to fill in the generic IEs.
2292 *cookie = 0; /* TX status not supported */
2293 return ath6kl_send_go_probe_resp(vif, buf, len,
2297 id = vif->send_action_id++;
2300 * 0 is a reserved value in the WMI command and shall not be
2301 * used for the command.
2303 id = vif->send_action_id++;
2307 return ath6kl_wmi_send_action_cmd(ar->wmi, vif->fw_vif_idx, id,
2308 chan->center_freq, wait,
2312 static void ath6kl_mgmt_frame_register(struct wiphy *wiphy,
2313 struct net_device *dev,
2314 u16 frame_type, bool reg)
2316 struct ath6kl_vif *vif = netdev_priv(dev);
2318 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: frame_type=0x%x reg=%d\n",
2319 __func__, frame_type, reg);
2320 if (frame_type == IEEE80211_STYPE_PROBE_REQ) {
2322 * Note: This notification callback is not allowed to sleep, so
2323 * we cannot send WMI_PROBE_REQ_REPORT_CMD here. Instead, we
2324 * hardcode target to report Probe Request frames all the time.
2326 vif->probe_req_report = reg;
2330 static const struct ieee80211_txrx_stypes
2331 ath6kl_mgmt_stypes[NUM_NL80211_IFTYPES] = {
2332 [NL80211_IFTYPE_STATION] = {
2333 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
2334 BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
2335 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
2336 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
2338 [NL80211_IFTYPE_P2P_CLIENT] = {
2339 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
2340 BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
2341 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
2342 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
2344 [NL80211_IFTYPE_P2P_GO] = {
2345 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
2346 BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
2347 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
2348 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
2352 static struct cfg80211_ops ath6kl_cfg80211_ops = {
2353 .add_virtual_intf = ath6kl_cfg80211_add_iface,
2354 .del_virtual_intf = ath6kl_cfg80211_del_iface,
2355 .change_virtual_intf = ath6kl_cfg80211_change_iface,
2356 .scan = ath6kl_cfg80211_scan,
2357 .connect = ath6kl_cfg80211_connect,
2358 .disconnect = ath6kl_cfg80211_disconnect,
2359 .add_key = ath6kl_cfg80211_add_key,
2360 .get_key = ath6kl_cfg80211_get_key,
2361 .del_key = ath6kl_cfg80211_del_key,
2362 .set_default_key = ath6kl_cfg80211_set_default_key,
2363 .set_wiphy_params = ath6kl_cfg80211_set_wiphy_params,
2364 .set_tx_power = ath6kl_cfg80211_set_txpower,
2365 .get_tx_power = ath6kl_cfg80211_get_txpower,
2366 .set_power_mgmt = ath6kl_cfg80211_set_power_mgmt,
2367 .join_ibss = ath6kl_cfg80211_join_ibss,
2368 .leave_ibss = ath6kl_cfg80211_leave_ibss,
2369 .get_station = ath6kl_get_station,
2370 .set_pmksa = ath6kl_set_pmksa,
2371 .del_pmksa = ath6kl_del_pmksa,
2372 .flush_pmksa = ath6kl_flush_pmksa,
2373 CFG80211_TESTMODE_CMD(ath6kl_tm_cmd)
2375 .suspend = __ath6kl_cfg80211_suspend,
2376 .resume = __ath6kl_cfg80211_resume,
2378 .set_channel = ath6kl_set_channel,
2379 .add_beacon = ath6kl_add_beacon,
2380 .set_beacon = ath6kl_set_beacon,
2381 .del_beacon = ath6kl_del_beacon,
2382 .change_station = ath6kl_change_station,
2383 .remain_on_channel = ath6kl_remain_on_channel,
2384 .cancel_remain_on_channel = ath6kl_cancel_remain_on_channel,
2385 .mgmt_tx = ath6kl_mgmt_tx,
2386 .mgmt_frame_register = ath6kl_mgmt_frame_register,
2389 void ath6kl_cfg80211_stop(struct ath6kl *ar)
2391 struct ath6kl_vif *vif;
2393 /* FIXME: for multi vif */
2394 vif = ath6kl_vif_first(ar);
2396 /* save the current power mode before enabling power save */
2397 ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode;
2399 if (ath6kl_wmi_powermode_cmd(ar->wmi, 0, REC_POWER) != 0)
2400 ath6kl_warn("ath6kl_deep_sleep_enable: "
2401 "wmi_powermode_cmd failed\n");
2405 switch (vif->sme_state) {
2406 case SME_CONNECTING:
2407 cfg80211_connect_result(vif->ndev, vif->bssid, NULL, 0,
2409 WLAN_STATUS_UNSPECIFIED_FAILURE,
2415 * FIXME: oddly enough smeState is in DISCONNECTED during
2416 * suspend, why? Need to send disconnected event in that
2419 cfg80211_disconnected(vif->ndev, 0, NULL, 0, GFP_KERNEL);
2423 if (test_bit(CONNECTED, &vif->flags) ||
2424 test_bit(CONNECT_PEND, &vif->flags))
2425 ath6kl_wmi_disconnect_cmd(ar->wmi, vif->fw_vif_idx);
2427 vif->sme_state = SME_DISCONNECTED;
2428 clear_bit(CONNECTED, &vif->flags);
2429 clear_bit(CONNECT_PEND, &vif->flags);
2431 /* disable scanning */
2432 if (ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx, 0xFFFF, 0, 0,
2433 0, 0, 0, 0, 0, 0, 0) != 0)
2434 printk(KERN_WARNING "ath6kl: failed to disable scan "
2435 "during suspend\n");
2437 ath6kl_cfg80211_scan_complete_event(vif, true);
2440 struct ath6kl *ath6kl_core_alloc(struct device *dev)
2443 struct wiphy *wiphy;
2446 /* create a new wiphy for use with cfg80211 */
2447 wiphy = wiphy_new(&ath6kl_cfg80211_ops, sizeof(struct ath6kl));
2450 ath6kl_err("couldn't allocate wiphy device\n");
2454 ar = wiphy_priv(wiphy);
2455 if (!multi_norm_if_support)
2456 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);