Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright (c) 2004-2011 Atheros Communications Inc.
0003  * Copyright (c) 2011-2012 Qualcomm Atheros, Inc.
0004  *
0005  * Permission to use, copy, modify, and/or distribute this software for any
0006  * purpose with or without fee is hereby granted, provided that the above
0007  * copyright notice and this permission notice appear in all copies.
0008  *
0009  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
0010  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
0011  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
0012  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
0013  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
0014  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
0015  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
0016  */
0017 
0018 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0019 
0020 #include <linux/moduleparam.h>
0021 #include <linux/inetdevice.h>
0022 #include <linux/export.h>
0023 #include <linux/sched/signal.h>
0024 
0025 #include "core.h"
0026 #include "cfg80211.h"
0027 #include "debug.h"
0028 #include "hif-ops.h"
0029 #include "testmode.h"
0030 
0031 #define RATETAB_ENT(_rate, _rateid, _flags) {   \
0032     .bitrate    = (_rate),                  \
0033     .flags      = (_flags),                 \
0034     .hw_value   = (_rateid),                \
0035 }
0036 
0037 #define CHAN2G(_channel, _freq, _flags) {   \
0038     .band           = NL80211_BAND_2GHZ,  \
0039     .hw_value       = (_channel),           \
0040     .center_freq    = (_freq),              \
0041     .flags          = (_flags),             \
0042     .max_antenna_gain   = 0,                \
0043     .max_power      = 30,                   \
0044 }
0045 
0046 #define CHAN5G(_channel, _flags) {          \
0047     .band           = NL80211_BAND_5GHZ,      \
0048     .hw_value       = (_channel),               \
0049     .center_freq    = 5000 + (5 * (_channel)),  \
0050     .flags          = (_flags),                 \
0051     .max_antenna_gain   = 0,                    \
0052     .max_power      = 30,                       \
0053 }
0054 
0055 #define DEFAULT_BG_SCAN_PERIOD 60
0056 
0057 struct ath6kl_cfg80211_match_probe_ssid {
0058     struct cfg80211_ssid ssid;
0059     u8 flag;
0060 };
0061 
0062 static struct ieee80211_rate ath6kl_rates[] = {
0063     RATETAB_ENT(10, 0x1, 0),
0064     RATETAB_ENT(20, 0x2, 0),
0065     RATETAB_ENT(55, 0x4, 0),
0066     RATETAB_ENT(110, 0x8, 0),
0067     RATETAB_ENT(60, 0x10, 0),
0068     RATETAB_ENT(90, 0x20, 0),
0069     RATETAB_ENT(120, 0x40, 0),
0070     RATETAB_ENT(180, 0x80, 0),
0071     RATETAB_ENT(240, 0x100, 0),
0072     RATETAB_ENT(360, 0x200, 0),
0073     RATETAB_ENT(480, 0x400, 0),
0074     RATETAB_ENT(540, 0x800, 0),
0075 };
0076 
0077 #define ath6kl_a_rates     (ath6kl_rates + 4)
0078 #define ath6kl_a_rates_size    8
0079 #define ath6kl_g_rates     (ath6kl_rates + 0)
0080 #define ath6kl_g_rates_size    12
0081 
0082 #define ath6kl_g_htcap IEEE80211_HT_CAP_SGI_20
0083 #define ath6kl_a_htcap (IEEE80211_HT_CAP_SUP_WIDTH_20_40 | \
0084             IEEE80211_HT_CAP_SGI_20      | \
0085             IEEE80211_HT_CAP_SGI_40)
0086 
0087 static struct ieee80211_channel ath6kl_2ghz_channels[] = {
0088     CHAN2G(1, 2412, 0),
0089     CHAN2G(2, 2417, 0),
0090     CHAN2G(3, 2422, 0),
0091     CHAN2G(4, 2427, 0),
0092     CHAN2G(5, 2432, 0),
0093     CHAN2G(6, 2437, 0),
0094     CHAN2G(7, 2442, 0),
0095     CHAN2G(8, 2447, 0),
0096     CHAN2G(9, 2452, 0),
0097     CHAN2G(10, 2457, 0),
0098     CHAN2G(11, 2462, 0),
0099     CHAN2G(12, 2467, 0),
0100     CHAN2G(13, 2472, 0),
0101     CHAN2G(14, 2484, 0),
0102 };
0103 
0104 static struct ieee80211_channel ath6kl_5ghz_a_channels[] = {
0105     CHAN5G(36, 0), CHAN5G(40, 0),
0106     CHAN5G(44, 0), CHAN5G(48, 0),
0107     CHAN5G(52, 0), CHAN5G(56, 0),
0108     CHAN5G(60, 0), CHAN5G(64, 0),
0109     CHAN5G(100, 0), CHAN5G(104, 0),
0110     CHAN5G(108, 0), CHAN5G(112, 0),
0111     CHAN5G(116, 0), CHAN5G(120, 0),
0112     CHAN5G(124, 0), CHAN5G(128, 0),
0113     CHAN5G(132, 0), CHAN5G(136, 0),
0114     CHAN5G(140, 0), CHAN5G(149, 0),
0115     CHAN5G(153, 0), CHAN5G(157, 0),
0116     CHAN5G(161, 0), CHAN5G(165, 0),
0117     CHAN5G(184, 0), CHAN5G(188, 0),
0118     CHAN5G(192, 0), CHAN5G(196, 0),
0119     CHAN5G(200, 0), CHAN5G(204, 0),
0120     CHAN5G(208, 0), CHAN5G(212, 0),
0121     CHAN5G(216, 0),
0122 };
0123 
0124 static struct ieee80211_supported_band ath6kl_band_2ghz = {
0125     .n_channels = ARRAY_SIZE(ath6kl_2ghz_channels),
0126     .channels = ath6kl_2ghz_channels,
0127     .n_bitrates = ath6kl_g_rates_size,
0128     .bitrates = ath6kl_g_rates,
0129     .ht_cap.cap = ath6kl_g_htcap,
0130     .ht_cap.ht_supported = true,
0131 };
0132 
0133 static struct ieee80211_supported_band ath6kl_band_5ghz = {
0134     .n_channels = ARRAY_SIZE(ath6kl_5ghz_a_channels),
0135     .channels = ath6kl_5ghz_a_channels,
0136     .n_bitrates = ath6kl_a_rates_size,
0137     .bitrates = ath6kl_a_rates,
0138     .ht_cap.cap = ath6kl_a_htcap,
0139     .ht_cap.ht_supported = true,
0140 };
0141 
0142 #define CCKM_KRK_CIPHER_SUITE 0x004096ff /* use for KRK */
0143 
0144 /* returns true if scheduled scan was stopped */
0145 static bool __ath6kl_cfg80211_sscan_stop(struct ath6kl_vif *vif)
0146 {
0147     struct ath6kl *ar = vif->ar;
0148 
0149     if (!test_and_clear_bit(SCHED_SCANNING, &vif->flags))
0150         return false;
0151 
0152     del_timer_sync(&vif->sched_scan_timer);
0153 
0154     if (ar->state == ATH6KL_STATE_RECOVERY)
0155         return true;
0156 
0157     ath6kl_wmi_enable_sched_scan_cmd(ar->wmi, vif->fw_vif_idx, false);
0158 
0159     return true;
0160 }
0161 
0162 static void ath6kl_cfg80211_sscan_disable(struct ath6kl_vif *vif)
0163 {
0164     struct ath6kl *ar = vif->ar;
0165     bool stopped;
0166 
0167     stopped = __ath6kl_cfg80211_sscan_stop(vif);
0168 
0169     if (!stopped)
0170         return;
0171 
0172     cfg80211_sched_scan_stopped(ar->wiphy, 0);
0173 }
0174 
0175 static int ath6kl_set_wpa_version(struct ath6kl_vif *vif,
0176                   enum nl80211_wpa_versions wpa_version)
0177 {
0178     ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: %u\n", __func__, wpa_version);
0179 
0180     if (!wpa_version) {
0181         vif->auth_mode = NONE_AUTH;
0182     } else if (wpa_version & NL80211_WPA_VERSION_2) {
0183         vif->auth_mode = WPA2_AUTH;
0184     } else if (wpa_version & NL80211_WPA_VERSION_1) {
0185         vif->auth_mode = WPA_AUTH;
0186     } else {
0187         ath6kl_err("%s: %u not supported\n", __func__, wpa_version);
0188         return -ENOTSUPP;
0189     }
0190 
0191     return 0;
0192 }
0193 
0194 static int ath6kl_set_auth_type(struct ath6kl_vif *vif,
0195                 enum nl80211_auth_type auth_type)
0196 {
0197     ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: 0x%x\n", __func__, auth_type);
0198 
0199     switch (auth_type) {
0200     case NL80211_AUTHTYPE_OPEN_SYSTEM:
0201         vif->dot11_auth_mode = OPEN_AUTH;
0202         break;
0203     case NL80211_AUTHTYPE_SHARED_KEY:
0204         vif->dot11_auth_mode = SHARED_AUTH;
0205         break;
0206     case NL80211_AUTHTYPE_NETWORK_EAP:
0207         vif->dot11_auth_mode = LEAP_AUTH;
0208         break;
0209 
0210     case NL80211_AUTHTYPE_AUTOMATIC:
0211         vif->dot11_auth_mode = OPEN_AUTH | SHARED_AUTH;
0212         break;
0213 
0214     default:
0215         ath6kl_err("%s: 0x%x not supported\n", __func__, auth_type);
0216         return -ENOTSUPP;
0217     }
0218 
0219     return 0;
0220 }
0221 
0222 static int ath6kl_set_cipher(struct ath6kl_vif *vif, u32 cipher, bool ucast)
0223 {
0224     u8 *ar_cipher = ucast ? &vif->prwise_crypto : &vif->grp_crypto;
0225     u8 *ar_cipher_len = ucast ? &vif->prwise_crypto_len :
0226         &vif->grp_crypto_len;
0227 
0228     ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: cipher 0x%x, ucast %u\n",
0229            __func__, cipher, ucast);
0230 
0231     switch (cipher) {
0232     case 0:
0233         /* our own hack to use value 0 as no crypto used */
0234         *ar_cipher = NONE_CRYPT;
0235         *ar_cipher_len = 0;
0236         break;
0237     case WLAN_CIPHER_SUITE_WEP40:
0238         *ar_cipher = WEP_CRYPT;
0239         *ar_cipher_len = 5;
0240         break;
0241     case WLAN_CIPHER_SUITE_WEP104:
0242         *ar_cipher = WEP_CRYPT;
0243         *ar_cipher_len = 13;
0244         break;
0245     case WLAN_CIPHER_SUITE_TKIP:
0246         *ar_cipher = TKIP_CRYPT;
0247         *ar_cipher_len = 0;
0248         break;
0249     case WLAN_CIPHER_SUITE_CCMP:
0250         *ar_cipher = AES_CRYPT;
0251         *ar_cipher_len = 0;
0252         break;
0253     case WLAN_CIPHER_SUITE_SMS4:
0254         *ar_cipher = WAPI_CRYPT;
0255         *ar_cipher_len = 0;
0256         break;
0257     default:
0258         ath6kl_err("cipher 0x%x not supported\n", cipher);
0259         return -ENOTSUPP;
0260     }
0261 
0262     return 0;
0263 }
0264 
0265 static void ath6kl_set_key_mgmt(struct ath6kl_vif *vif, u32 key_mgmt)
0266 {
0267     ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: 0x%x\n", __func__, key_mgmt);
0268 
0269     if (key_mgmt == WLAN_AKM_SUITE_PSK) {
0270         if (vif->auth_mode == WPA_AUTH)
0271             vif->auth_mode = WPA_PSK_AUTH;
0272         else if (vif->auth_mode == WPA2_AUTH)
0273             vif->auth_mode = WPA2_PSK_AUTH;
0274     } else if (key_mgmt == 0x00409600) {
0275         if (vif->auth_mode == WPA_AUTH)
0276             vif->auth_mode = WPA_AUTH_CCKM;
0277         else if (vif->auth_mode == WPA2_AUTH)
0278             vif->auth_mode = WPA2_AUTH_CCKM;
0279     } else if (key_mgmt != WLAN_AKM_SUITE_8021X) {
0280         vif->auth_mode = NONE_AUTH;
0281     }
0282 }
0283 
0284 static bool ath6kl_cfg80211_ready(struct ath6kl_vif *vif)
0285 {
0286     struct ath6kl *ar = vif->ar;
0287 
0288     if (!test_bit(WMI_READY, &ar->flag)) {
0289         ath6kl_err("wmi is not ready\n");
0290         return false;
0291     }
0292 
0293     if (!test_bit(WLAN_ENABLED, &vif->flags)) {
0294         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "wlan disabled\n");
0295         return false;
0296     }
0297 
0298     return true;
0299 }
0300 
0301 static bool ath6kl_is_wpa_ie(const u8 *pos)
0302 {
0303     return pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
0304         pos[2] == 0x00 && pos[3] == 0x50 &&
0305         pos[4] == 0xf2 && pos[5] == 0x01;
0306 }
0307 
0308 static bool ath6kl_is_rsn_ie(const u8 *pos)
0309 {
0310     return pos[0] == WLAN_EID_RSN;
0311 }
0312 
0313 static bool ath6kl_is_wps_ie(const u8 *pos)
0314 {
0315     return (pos[0] == WLAN_EID_VENDOR_SPECIFIC &&
0316         pos[1] >= 4 &&
0317         pos[2] == 0x00 && pos[3] == 0x50 && pos[4] == 0xf2 &&
0318         pos[5] == 0x04);
0319 }
0320 
0321 static int ath6kl_set_assoc_req_ies(struct ath6kl_vif *vif, const u8 *ies,
0322                     size_t ies_len)
0323 {
0324     struct ath6kl *ar = vif->ar;
0325     const u8 *pos;
0326     u8 *buf = NULL;
0327     size_t len = 0;
0328     int ret;
0329 
0330     /*
0331      * Clear previously set flag
0332      */
0333 
0334     ar->connect_ctrl_flags &= ~CONNECT_WPS_FLAG;
0335 
0336     /*
0337      * Filter out RSN/WPA IE(s)
0338      */
0339 
0340     if (ies && ies_len) {
0341         buf = kmalloc(ies_len, GFP_KERNEL);
0342         if (buf == NULL)
0343             return -ENOMEM;
0344         pos = ies;
0345 
0346         while (pos + 1 < ies + ies_len) {
0347             if (pos + 2 + pos[1] > ies + ies_len)
0348                 break;
0349             if (!(ath6kl_is_wpa_ie(pos) || ath6kl_is_rsn_ie(pos))) {
0350                 memcpy(buf + len, pos, 2 + pos[1]);
0351                 len += 2 + pos[1];
0352             }
0353 
0354             if (ath6kl_is_wps_ie(pos))
0355                 ar->connect_ctrl_flags |= CONNECT_WPS_FLAG;
0356 
0357             pos += 2 + pos[1];
0358         }
0359     }
0360 
0361     ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
0362                        WMI_FRAME_ASSOC_REQ, buf, len);
0363     kfree(buf);
0364     return ret;
0365 }
0366 
0367 static int ath6kl_nliftype_to_drv_iftype(enum nl80211_iftype type, u8 *nw_type)
0368 {
0369     switch (type) {
0370     case NL80211_IFTYPE_STATION:
0371     case NL80211_IFTYPE_P2P_CLIENT:
0372         *nw_type = INFRA_NETWORK;
0373         break;
0374     case NL80211_IFTYPE_ADHOC:
0375         *nw_type = ADHOC_NETWORK;
0376         break;
0377     case NL80211_IFTYPE_AP:
0378     case NL80211_IFTYPE_P2P_GO:
0379         *nw_type = AP_NETWORK;
0380         break;
0381     default:
0382         ath6kl_err("invalid interface type %u\n", type);
0383         return -ENOTSUPP;
0384     }
0385 
0386     return 0;
0387 }
0388 
0389 static bool ath6kl_is_valid_iftype(struct ath6kl *ar, enum nl80211_iftype type,
0390                    u8 *if_idx, u8 *nw_type)
0391 {
0392     int i;
0393 
0394     if (ath6kl_nliftype_to_drv_iftype(type, nw_type))
0395         return false;
0396 
0397     if (ar->ibss_if_active || ((type == NL80211_IFTYPE_ADHOC) &&
0398                    ar->num_vif))
0399         return false;
0400 
0401     if (type == NL80211_IFTYPE_STATION ||
0402         type == NL80211_IFTYPE_AP || type == NL80211_IFTYPE_ADHOC) {
0403         for (i = 0; i < ar->vif_max; i++) {
0404             if ((ar->avail_idx_map) & BIT(i)) {
0405                 *if_idx = i;
0406                 return true;
0407             }
0408         }
0409     }
0410 
0411     if (type == NL80211_IFTYPE_P2P_CLIENT ||
0412         type == NL80211_IFTYPE_P2P_GO) {
0413         for (i = ar->max_norm_iface; i < ar->vif_max; i++) {
0414             if ((ar->avail_idx_map) & BIT(i)) {
0415                 *if_idx = i;
0416                 return true;
0417             }
0418         }
0419     }
0420 
0421     return false;
0422 }
0423 
0424 static bool ath6kl_is_tx_pending(struct ath6kl *ar)
0425 {
0426     return ar->tx_pending[ath6kl_wmi_get_control_ep(ar->wmi)] == 0;
0427 }
0428 
0429 static void ath6kl_cfg80211_sta_bmiss_enhance(struct ath6kl_vif *vif,
0430                           bool enable)
0431 {
0432     int err;
0433 
0434     if (WARN_ON(!test_bit(WMI_READY, &vif->ar->flag)))
0435         return;
0436 
0437     if (vif->nw_type != INFRA_NETWORK)
0438         return;
0439 
0440     if (!test_bit(ATH6KL_FW_CAPABILITY_BMISS_ENHANCE,
0441               vif->ar->fw_capabilities))
0442         return;
0443 
0444     ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s fw bmiss enhance\n",
0445            enable ? "enable" : "disable");
0446 
0447     err = ath6kl_wmi_sta_bmiss_enhance_cmd(vif->ar->wmi,
0448                            vif->fw_vif_idx, enable);
0449     if (err)
0450         ath6kl_err("failed to %s enhanced bmiss detection: %d\n",
0451                enable ? "enable" : "disable", err);
0452 }
0453 
0454 static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
0455                    struct cfg80211_connect_params *sme)
0456 {
0457     struct ath6kl *ar = ath6kl_priv(dev);
0458     struct ath6kl_vif *vif = netdev_priv(dev);
0459     int status;
0460     u8 nw_subtype = (ar->p2p) ? SUBTYPE_P2PDEV : SUBTYPE_NONE;
0461     u16 interval;
0462 
0463     ath6kl_cfg80211_sscan_disable(vif);
0464 
0465     vif->sme_state = SME_CONNECTING;
0466 
0467     if (!ath6kl_cfg80211_ready(vif))
0468         return -EIO;
0469 
0470     if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
0471         ath6kl_err("destroy in progress\n");
0472         return -EBUSY;
0473     }
0474 
0475     if (test_bit(SKIP_SCAN, &ar->flag) &&
0476         ((sme->channel && sme->channel->center_freq == 0) ||
0477          (sme->bssid && is_zero_ether_addr(sme->bssid)))) {
0478         ath6kl_err("SkipScan: channel or bssid invalid\n");
0479         return -EINVAL;
0480     }
0481 
0482     if (down_interruptible(&ar->sem)) {
0483         ath6kl_err("busy, couldn't get access\n");
0484         return -ERESTARTSYS;
0485     }
0486 
0487     if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
0488         ath6kl_err("busy, destroy in progress\n");
0489         up(&ar->sem);
0490         return -EBUSY;
0491     }
0492 
0493     if (ar->tx_pending[ath6kl_wmi_get_control_ep(ar->wmi)]) {
0494         /*
0495          * sleep until the command queue drains
0496          */
0497         wait_event_interruptible_timeout(ar->event_wq,
0498                          ath6kl_is_tx_pending(ar),
0499                          WMI_TIMEOUT);
0500         if (signal_pending(current)) {
0501             ath6kl_err("cmd queue drain timeout\n");
0502             up(&ar->sem);
0503             return -EINTR;
0504         }
0505     }
0506 
0507     status = ath6kl_set_assoc_req_ies(vif, sme->ie, sme->ie_len);
0508     if (status) {
0509         up(&ar->sem);
0510         return status;
0511     }
0512 
0513     if (sme->ie == NULL || sme->ie_len == 0)
0514         ar->connect_ctrl_flags &= ~CONNECT_WPS_FLAG;
0515 
0516     if (test_bit(CONNECTED, &vif->flags) &&
0517         vif->ssid_len == sme->ssid_len &&
0518         !memcmp(vif->ssid, sme->ssid, vif->ssid_len)) {
0519         vif->reconnect_flag = true;
0520         status = ath6kl_wmi_reconnect_cmd(ar->wmi, vif->fw_vif_idx,
0521                           vif->req_bssid,
0522                           vif->ch_hint);
0523 
0524         up(&ar->sem);
0525         if (status) {
0526             ath6kl_err("wmi_reconnect_cmd failed\n");
0527             return -EIO;
0528         }
0529         return 0;
0530     } else if (vif->ssid_len == sme->ssid_len &&
0531            !memcmp(vif->ssid, sme->ssid, vif->ssid_len)) {
0532         ath6kl_disconnect(vif);
0533     }
0534 
0535     memset(vif->ssid, 0, sizeof(vif->ssid));
0536     vif->ssid_len = sme->ssid_len;
0537     memcpy(vif->ssid, sme->ssid, sme->ssid_len);
0538 
0539     if (sme->channel)
0540         vif->ch_hint = sme->channel->center_freq;
0541 
0542     memset(vif->req_bssid, 0, sizeof(vif->req_bssid));
0543     if (sme->bssid && !is_broadcast_ether_addr(sme->bssid))
0544         memcpy(vif->req_bssid, sme->bssid, sizeof(vif->req_bssid));
0545 
0546     ath6kl_set_wpa_version(vif, sme->crypto.wpa_versions);
0547 
0548     status = ath6kl_set_auth_type(vif, sme->auth_type);
0549     if (status) {
0550         up(&ar->sem);
0551         return status;
0552     }
0553 
0554     if (sme->crypto.n_ciphers_pairwise)
0555         ath6kl_set_cipher(vif, sme->crypto.ciphers_pairwise[0], true);
0556     else
0557         ath6kl_set_cipher(vif, 0, true);
0558 
0559     ath6kl_set_cipher(vif, sme->crypto.cipher_group, false);
0560 
0561     if (sme->crypto.n_akm_suites)
0562         ath6kl_set_key_mgmt(vif, sme->crypto.akm_suites[0]);
0563 
0564     if ((sme->key_len) &&
0565         (vif->auth_mode == NONE_AUTH) &&
0566         (vif->prwise_crypto == WEP_CRYPT)) {
0567         struct ath6kl_key *key = NULL;
0568 
0569         if (sme->key_idx > WMI_MAX_KEY_INDEX) {
0570             ath6kl_err("key index %d out of bounds\n",
0571                    sme->key_idx);
0572             up(&ar->sem);
0573             return -ENOENT;
0574         }
0575 
0576         key = &vif->keys[sme->key_idx];
0577         key->key_len = sme->key_len;
0578         memcpy(key->key, sme->key, key->key_len);
0579         key->cipher = vif->prwise_crypto;
0580         vif->def_txkey_index = sme->key_idx;
0581 
0582         ath6kl_wmi_addkey_cmd(ar->wmi, vif->fw_vif_idx, sme->key_idx,
0583                       vif->prwise_crypto,
0584                       GROUP_USAGE | TX_USAGE,
0585                       key->key_len,
0586                       NULL, 0,
0587                       key->key, KEY_OP_INIT_VAL, NULL,
0588                       NO_SYNC_WMIFLAG);
0589     }
0590 
0591     if (!ar->usr_bss_filter) {
0592         clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags);
0593         if (ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
0594                          ALL_BSS_FILTER, 0) != 0) {
0595             ath6kl_err("couldn't set bss filtering\n");
0596             up(&ar->sem);
0597             return -EIO;
0598         }
0599     }
0600 
0601     vif->nw_type = vif->next_mode;
0602 
0603     /* enable enhanced bmiss detection if applicable */
0604     ath6kl_cfg80211_sta_bmiss_enhance(vif, true);
0605 
0606     if (vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT)
0607         nw_subtype = SUBTYPE_P2PCLIENT;
0608 
0609     ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
0610            "%s: connect called with authmode %d dot11 auth %d"
0611            " PW crypto %d PW crypto len %d GRP crypto %d"
0612            " GRP crypto len %d channel hint %u\n",
0613            __func__,
0614            vif->auth_mode, vif->dot11_auth_mode, vif->prwise_crypto,
0615            vif->prwise_crypto_len, vif->grp_crypto,
0616            vif->grp_crypto_len, vif->ch_hint);
0617 
0618     vif->reconnect_flag = 0;
0619 
0620     if (vif->nw_type == INFRA_NETWORK) {
0621         interval = max_t(u16, vif->listen_intvl_t,
0622                  ATH6KL_MAX_WOW_LISTEN_INTL);
0623         status = ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx,
0624                                interval,
0625                                0);
0626         if (status) {
0627             ath6kl_err("couldn't set listen intervel\n");
0628             up(&ar->sem);
0629             return status;
0630         }
0631     }
0632 
0633     status = ath6kl_wmi_connect_cmd(ar->wmi, vif->fw_vif_idx, vif->nw_type,
0634                     vif->dot11_auth_mode, vif->auth_mode,
0635                     vif->prwise_crypto,
0636                     vif->prwise_crypto_len,
0637                     vif->grp_crypto, vif->grp_crypto_len,
0638                     vif->ssid_len, vif->ssid,
0639                     vif->req_bssid, vif->ch_hint,
0640                     ar->connect_ctrl_flags, nw_subtype);
0641 
0642     if (sme->bg_scan_period == 0) {
0643         /* disable background scan if period is 0 */
0644         sme->bg_scan_period = 0xffff;
0645     } else if (sme->bg_scan_period == -1) {
0646         /* configure default value if not specified */
0647         sme->bg_scan_period = DEFAULT_BG_SCAN_PERIOD;
0648     }
0649 
0650     ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx, 0, 0,
0651                   sme->bg_scan_period, 0, 0, 0, 3, 0, 0, 0);
0652 
0653     up(&ar->sem);
0654 
0655     if (status == -EINVAL) {
0656         memset(vif->ssid, 0, sizeof(vif->ssid));
0657         vif->ssid_len = 0;
0658         ath6kl_err("invalid request\n");
0659         return -ENOENT;
0660     } else if (status) {
0661         ath6kl_err("ath6kl_wmi_connect_cmd failed\n");
0662         return -EIO;
0663     }
0664 
0665     if ((!(ar->connect_ctrl_flags & CONNECT_DO_WPA_OFFLOAD)) &&
0666         ((vif->auth_mode == WPA_PSK_AUTH) ||
0667          (vif->auth_mode == WPA2_PSK_AUTH))) {
0668         mod_timer(&vif->disconnect_timer,
0669               jiffies + msecs_to_jiffies(DISCON_TIMER_INTVAL));
0670     }
0671 
0672     ar->connect_ctrl_flags &= ~CONNECT_DO_WPA_OFFLOAD;
0673     set_bit(CONNECT_PEND, &vif->flags);
0674 
0675     return 0;
0676 }
0677 
0678 static struct cfg80211_bss *
0679 ath6kl_add_bss_if_needed(struct ath6kl_vif *vif,
0680              enum network_type nw_type,
0681              const u8 *bssid,
0682              struct ieee80211_channel *chan,
0683              const u8 *beacon_ie,
0684              size_t beacon_ie_len)
0685 {
0686     struct ath6kl *ar = vif->ar;
0687     struct cfg80211_bss *bss;
0688     u16 cap_val;
0689     enum ieee80211_bss_type bss_type;
0690     u8 *ie;
0691 
0692     if (nw_type & ADHOC_NETWORK) {
0693         cap_val = WLAN_CAPABILITY_IBSS;
0694         bss_type = IEEE80211_BSS_TYPE_IBSS;
0695     } else {
0696         cap_val = WLAN_CAPABILITY_ESS;
0697         bss_type = IEEE80211_BSS_TYPE_ESS;
0698     }
0699 
0700     bss = cfg80211_get_bss(ar->wiphy, chan, bssid,
0701                    vif->ssid, vif->ssid_len,
0702                    bss_type, IEEE80211_PRIVACY_ANY);
0703     if (bss == NULL) {
0704         /*
0705          * Since cfg80211 may not yet know about the BSS,
0706          * generate a partial entry until the first BSS info
0707          * event becomes available.
0708          *
0709          * Prepend SSID element since it is not included in the Beacon
0710          * IEs from the target.
0711          */
0712         ie = kmalloc(2 + vif->ssid_len + beacon_ie_len, GFP_KERNEL);
0713         if (ie == NULL)
0714             return NULL;
0715         ie[0] = WLAN_EID_SSID;
0716         ie[1] = vif->ssid_len;
0717         memcpy(ie + 2, vif->ssid, vif->ssid_len);
0718         memcpy(ie + 2 + vif->ssid_len, beacon_ie, beacon_ie_len);
0719         bss = cfg80211_inform_bss(ar->wiphy, chan,
0720                       CFG80211_BSS_FTYPE_UNKNOWN,
0721                       bssid, 0, cap_val, 100,
0722                       ie, 2 + vif->ssid_len + beacon_ie_len,
0723                       0, GFP_KERNEL);
0724         if (bss)
0725             ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
0726                    "added bss %pM to cfg80211\n", bssid);
0727         kfree(ie);
0728     } else {
0729         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "cfg80211 already has a bss\n");
0730     }
0731 
0732     return bss;
0733 }
0734 
0735 void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel,
0736                    u8 *bssid, u16 listen_intvl,
0737                    u16 beacon_intvl,
0738                    enum network_type nw_type,
0739                    u8 beacon_ie_len, u8 assoc_req_len,
0740                    u8 assoc_resp_len, u8 *assoc_info)
0741 {
0742     struct ieee80211_channel *chan;
0743     struct ath6kl *ar = vif->ar;
0744     struct cfg80211_bss *bss;
0745 
0746     /* capinfo + listen interval */
0747     u8 assoc_req_ie_offset = sizeof(u16) + sizeof(u16);
0748 
0749     /* capinfo + status code +  associd */
0750     u8 assoc_resp_ie_offset = sizeof(u16) + sizeof(u16) + sizeof(u16);
0751 
0752     u8 *assoc_req_ie = assoc_info + beacon_ie_len + assoc_req_ie_offset;
0753     u8 *assoc_resp_ie = assoc_info + beacon_ie_len + assoc_req_len +
0754         assoc_resp_ie_offset;
0755 
0756     assoc_req_len -= assoc_req_ie_offset;
0757     assoc_resp_len -= assoc_resp_ie_offset;
0758 
0759     /*
0760      * Store Beacon interval here; DTIM period will be available only once
0761      * a Beacon frame from the AP is seen.
0762      */
0763     vif->assoc_bss_beacon_int = beacon_intvl;
0764     clear_bit(DTIM_PERIOD_AVAIL, &vif->flags);
0765 
0766     if (nw_type & ADHOC_NETWORK) {
0767         if (vif->wdev.iftype != NL80211_IFTYPE_ADHOC) {
0768             ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
0769                    "%s: ath6k not in ibss mode\n", __func__);
0770             return;
0771         }
0772     }
0773 
0774     if (nw_type & INFRA_NETWORK) {
0775         if (vif->wdev.iftype != NL80211_IFTYPE_STATION &&
0776             vif->wdev.iftype != NL80211_IFTYPE_P2P_CLIENT) {
0777             ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
0778                    "%s: ath6k not in station mode\n", __func__);
0779             return;
0780         }
0781     }
0782 
0783     chan = ieee80211_get_channel(ar->wiphy, (int) channel);
0784 
0785     bss = ath6kl_add_bss_if_needed(vif, nw_type, bssid, chan,
0786                        assoc_info, beacon_ie_len);
0787     if (!bss) {
0788         ath6kl_err("could not add cfg80211 bss entry\n");
0789         return;
0790     }
0791 
0792     if (nw_type & ADHOC_NETWORK) {
0793         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "ad-hoc %s selected\n",
0794                nw_type & ADHOC_CREATOR ? "creator" : "joiner");
0795         cfg80211_ibss_joined(vif->ndev, bssid, chan, GFP_KERNEL);
0796         cfg80211_put_bss(ar->wiphy, bss);
0797         return;
0798     }
0799 
0800     if (vif->sme_state == SME_CONNECTING) {
0801         /* inform connect result to cfg80211 */
0802         vif->sme_state = SME_CONNECTED;
0803         cfg80211_connect_result(vif->ndev, bssid,
0804                     assoc_req_ie, assoc_req_len,
0805                     assoc_resp_ie, assoc_resp_len,
0806                     WLAN_STATUS_SUCCESS, GFP_KERNEL);
0807         cfg80211_put_bss(ar->wiphy, bss);
0808     } else if (vif->sme_state == SME_CONNECTED) {
0809         struct cfg80211_roam_info roam_info = {
0810             .links[0].bss = bss,
0811             .req_ie = assoc_req_ie,
0812             .req_ie_len = assoc_req_len,
0813             .resp_ie = assoc_resp_ie,
0814             .resp_ie_len = assoc_resp_len,
0815         };
0816         /* inform roam event to cfg80211 */
0817         cfg80211_roamed(vif->ndev, &roam_info, GFP_KERNEL);
0818     }
0819 }
0820 
0821 static int ath6kl_cfg80211_disconnect(struct wiphy *wiphy,
0822                       struct net_device *dev, u16 reason_code)
0823 {
0824     struct ath6kl *ar = ath6kl_priv(dev);
0825     struct ath6kl_vif *vif = netdev_priv(dev);
0826 
0827     ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: reason=%u\n", __func__,
0828            reason_code);
0829 
0830     ath6kl_cfg80211_sscan_disable(vif);
0831 
0832     if (!ath6kl_cfg80211_ready(vif))
0833         return -EIO;
0834 
0835     if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
0836         ath6kl_err("busy, destroy in progress\n");
0837         return -EBUSY;
0838     }
0839 
0840     if (down_interruptible(&ar->sem)) {
0841         ath6kl_err("busy, couldn't get access\n");
0842         return -ERESTARTSYS;
0843     }
0844 
0845     vif->reconnect_flag = 0;
0846     ath6kl_disconnect(vif);
0847     memset(vif->ssid, 0, sizeof(vif->ssid));
0848     vif->ssid_len = 0;
0849 
0850     if (!test_bit(SKIP_SCAN, &ar->flag))
0851         memset(vif->req_bssid, 0, sizeof(vif->req_bssid));
0852 
0853     up(&ar->sem);
0854 
0855     return 0;
0856 }
0857 
0858 void ath6kl_cfg80211_disconnect_event(struct ath6kl_vif *vif, u8 reason,
0859                       u8 *bssid, u8 assoc_resp_len,
0860                       u8 *assoc_info, u16 proto_reason)
0861 {
0862     struct ath6kl *ar = vif->ar;
0863 
0864     if (vif->scan_req) {
0865         struct cfg80211_scan_info info = {
0866             .aborted = true,
0867         };
0868 
0869         cfg80211_scan_done(vif->scan_req, &info);
0870         vif->scan_req = NULL;
0871     }
0872 
0873     if (vif->nw_type & ADHOC_NETWORK) {
0874         if (vif->wdev.iftype != NL80211_IFTYPE_ADHOC)
0875             ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
0876                    "%s: ath6k not in ibss mode\n", __func__);
0877         return;
0878     }
0879 
0880     if (vif->nw_type & INFRA_NETWORK) {
0881         if (vif->wdev.iftype != NL80211_IFTYPE_STATION &&
0882             vif->wdev.iftype != NL80211_IFTYPE_P2P_CLIENT) {
0883             ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
0884                    "%s: ath6k not in station mode\n", __func__);
0885             return;
0886         }
0887     }
0888 
0889     clear_bit(CONNECT_PEND, &vif->flags);
0890 
0891     if (vif->sme_state == SME_CONNECTING) {
0892         cfg80211_connect_result(vif->ndev,
0893                     bssid, NULL, 0,
0894                     NULL, 0,
0895                     WLAN_STATUS_UNSPECIFIED_FAILURE,
0896                     GFP_KERNEL);
0897     } else if (vif->sme_state == SME_CONNECTED) {
0898         cfg80211_disconnected(vif->ndev, proto_reason,
0899                       NULL, 0, false, GFP_KERNEL);
0900     }
0901 
0902     vif->sme_state = SME_DISCONNECTED;
0903 
0904     /*
0905      * Send a disconnect command to target when a disconnect event is
0906      * received with reason code other than 3 (DISCONNECT_CMD - disconnect
0907      * request from host) to make the firmware stop trying to connect even
0908      * after giving disconnect event. There will be one more disconnect
0909      * event for this disconnect command with reason code DISCONNECT_CMD
0910      * which won't be notified to cfg80211.
0911      */
0912     if (reason != DISCONNECT_CMD)
0913         ath6kl_wmi_disconnect_cmd(ar->wmi, vif->fw_vif_idx);
0914 }
0915 
0916 static int ath6kl_set_probed_ssids(struct ath6kl *ar,
0917                    struct ath6kl_vif *vif,
0918                    struct cfg80211_ssid *ssids, int n_ssids,
0919                    struct cfg80211_match_set *match_set,
0920                    int n_match_ssid)
0921 {
0922     u8 i, j, index_to_add, ssid_found = false;
0923     struct ath6kl_cfg80211_match_probe_ssid ssid_list[MAX_PROBED_SSIDS];
0924 
0925     memset(ssid_list, 0, sizeof(ssid_list));
0926 
0927     if (n_ssids > MAX_PROBED_SSIDS ||
0928         n_match_ssid > MAX_PROBED_SSIDS)
0929         return -EINVAL;
0930 
0931     for (i = 0; i < n_ssids; i++) {
0932         memcpy(ssid_list[i].ssid.ssid,
0933                ssids[i].ssid,
0934                ssids[i].ssid_len);
0935         ssid_list[i].ssid.ssid_len = ssids[i].ssid_len;
0936 
0937         if (ssids[i].ssid_len)
0938             ssid_list[i].flag = SPECIFIC_SSID_FLAG;
0939         else
0940             ssid_list[i].flag = ANY_SSID_FLAG;
0941 
0942         if (ar->wiphy->max_match_sets != 0 && n_match_ssid == 0)
0943             ssid_list[i].flag |= MATCH_SSID_FLAG;
0944     }
0945 
0946     index_to_add = i;
0947 
0948     for (i = 0; i < n_match_ssid; i++) {
0949         ssid_found = false;
0950 
0951         for (j = 0; j < n_ssids; j++) {
0952             if ((match_set[i].ssid.ssid_len ==
0953                  ssid_list[j].ssid.ssid_len) &&
0954                 (!memcmp(ssid_list[j].ssid.ssid,
0955                      match_set[i].ssid.ssid,
0956                      match_set[i].ssid.ssid_len))) {
0957                 ssid_list[j].flag |= MATCH_SSID_FLAG;
0958                 ssid_found = true;
0959                 break;
0960             }
0961         }
0962 
0963         if (ssid_found)
0964             continue;
0965 
0966         if (index_to_add >= MAX_PROBED_SSIDS)
0967             continue;
0968 
0969         ssid_list[index_to_add].ssid.ssid_len =
0970             match_set[i].ssid.ssid_len;
0971         memcpy(ssid_list[index_to_add].ssid.ssid,
0972                match_set[i].ssid.ssid,
0973                match_set[i].ssid.ssid_len);
0974         ssid_list[index_to_add].flag |= MATCH_SSID_FLAG;
0975         index_to_add++;
0976     }
0977 
0978     for (i = 0; i < index_to_add; i++) {
0979         ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx, i,
0980                       ssid_list[i].flag,
0981                       ssid_list[i].ssid.ssid_len,
0982                       ssid_list[i].ssid.ssid);
0983     }
0984 
0985     /* Make sure no old entries are left behind */
0986     for (i = index_to_add; i < MAX_PROBED_SSIDS; i++) {
0987         ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx, i,
0988                       DISABLE_SSID_FLAG, 0, NULL);
0989     }
0990 
0991     return 0;
0992 }
0993 
0994 static int ath6kl_cfg80211_scan(struct wiphy *wiphy,
0995                 struct cfg80211_scan_request *request)
0996 {
0997     struct ath6kl_vif *vif = ath6kl_vif_from_wdev(request->wdev);
0998     struct ath6kl *ar = ath6kl_priv(vif->ndev);
0999     s8 n_channels = 0;
1000     u16 *channels = NULL;
1001     int ret = 0;
1002     u32 force_fg_scan = 0;
1003 
1004     if (!ath6kl_cfg80211_ready(vif))
1005         return -EIO;
1006 
1007     ath6kl_cfg80211_sscan_disable(vif);
1008 
1009     if (!ar->usr_bss_filter) {
1010         clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags);
1011         ret = ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
1012                            ALL_BSS_FILTER, 0);
1013         if (ret) {
1014             ath6kl_err("couldn't set bss filtering\n");
1015             return ret;
1016         }
1017     }
1018 
1019     ret = ath6kl_set_probed_ssids(ar, vif, request->ssids,
1020                       request->n_ssids, NULL, 0);
1021     if (ret < 0)
1022         return ret;
1023 
1024     /* this also clears IE in fw if it's not set */
1025     ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
1026                        WMI_FRAME_PROBE_REQ,
1027                        request->ie, request->ie_len);
1028     if (ret) {
1029         ath6kl_err("failed to set Probe Request appie for scan\n");
1030         return ret;
1031     }
1032 
1033     /*
1034      * Scan only the requested channels if the request specifies a set of
1035      * channels. If the list is longer than the target supports, do not
1036      * configure the list and instead, scan all available channels.
1037      */
1038     if (request->n_channels > 0 &&
1039         request->n_channels <= WMI_MAX_CHANNELS) {
1040         u8 i;
1041 
1042         n_channels = request->n_channels;
1043 
1044         channels = kcalloc(n_channels, sizeof(u16), GFP_KERNEL);
1045         if (channels == NULL) {
1046             ath6kl_warn("failed to set scan channels, scan all channels");
1047             n_channels = 0;
1048         }
1049 
1050         for (i = 0; i < n_channels; i++)
1051             channels[i] = request->channels[i]->center_freq;
1052     }
1053 
1054     if (test_bit(CONNECTED, &vif->flags))
1055         force_fg_scan = 1;
1056 
1057     vif->scan_req = request;
1058 
1059     ret = ath6kl_wmi_beginscan_cmd(ar->wmi, vif->fw_vif_idx,
1060                        WMI_LONG_SCAN, force_fg_scan,
1061                        false, 0,
1062                        ATH6KL_FG_SCAN_INTERVAL,
1063                        n_channels, channels,
1064                        request->no_cck,
1065                        request->rates);
1066     if (ret) {
1067         ath6kl_err("failed to start scan: %d\n", ret);
1068         vif->scan_req = NULL;
1069     }
1070 
1071     kfree(channels);
1072 
1073     return ret;
1074 }
1075 
1076 void ath6kl_cfg80211_scan_complete_event(struct ath6kl_vif *vif, bool aborted)
1077 {
1078     struct ath6kl *ar = vif->ar;
1079     struct cfg80211_scan_info info = {
1080         .aborted = aborted,
1081     };
1082     int i;
1083 
1084     ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: status%s\n", __func__,
1085            aborted ? " aborted" : "");
1086 
1087     if (!vif->scan_req)
1088         return;
1089 
1090     if (aborted)
1091         goto out;
1092 
1093     if (vif->scan_req->n_ssids && vif->scan_req->ssids[0].ssid_len) {
1094         for (i = 0; i < vif->scan_req->n_ssids; i++) {
1095             ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx,
1096                           i, DISABLE_SSID_FLAG,
1097                           0, NULL);
1098         }
1099     }
1100 
1101 out:
1102     cfg80211_scan_done(vif->scan_req, &info);
1103     vif->scan_req = NULL;
1104 }
1105 
1106 void ath6kl_cfg80211_ch_switch_notify(struct ath6kl_vif *vif, int freq,
1107                       enum wmi_phy_mode mode)
1108 {
1109     struct cfg80211_chan_def chandef;
1110 
1111     ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1112            "channel switch notify nw_type %d freq %d mode %d\n",
1113            vif->nw_type, freq, mode);
1114 
1115     cfg80211_chandef_create(&chandef,
1116                 ieee80211_get_channel(vif->ar->wiphy, freq),
1117                 (mode == WMI_11G_HT20 &&
1118                  ath6kl_band_2ghz.ht_cap.ht_supported) ?
1119                     NL80211_CHAN_HT20 : NL80211_CHAN_NO_HT);
1120 
1121     mutex_lock(&vif->wdev.mtx);
1122     cfg80211_ch_switch_notify(vif->ndev, &chandef, 0);
1123     mutex_unlock(&vif->wdev.mtx);
1124 }
1125 
1126 static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
1127                    u8 key_index, bool pairwise,
1128                    const u8 *mac_addr,
1129                    struct key_params *params)
1130 {
1131     struct ath6kl *ar = ath6kl_priv(ndev);
1132     struct ath6kl_vif *vif = netdev_priv(ndev);
1133     struct ath6kl_key *key = NULL;
1134     int seq_len;
1135     u8 key_usage;
1136     u8 key_type;
1137 
1138     if (!ath6kl_cfg80211_ready(vif))
1139         return -EIO;
1140 
1141     if (params->cipher == CCKM_KRK_CIPHER_SUITE) {
1142         if (params->key_len != WMI_KRK_LEN)
1143             return -EINVAL;
1144         return ath6kl_wmi_add_krk_cmd(ar->wmi, vif->fw_vif_idx,
1145                           params->key);
1146     }
1147 
1148     if (key_index > WMI_MAX_KEY_INDEX) {
1149         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1150                "%s: key index %d out of bounds\n", __func__,
1151                key_index);
1152         return -ENOENT;
1153     }
1154 
1155     key = &vif->keys[key_index];
1156     memset(key, 0, sizeof(struct ath6kl_key));
1157 
1158     if (pairwise)
1159         key_usage = PAIRWISE_USAGE;
1160     else
1161         key_usage = GROUP_USAGE;
1162 
1163     seq_len = params->seq_len;
1164     if (params->cipher == WLAN_CIPHER_SUITE_SMS4 &&
1165         seq_len > ATH6KL_KEY_SEQ_LEN) {
1166         /* Only first half of the WPI PN is configured */
1167         seq_len = ATH6KL_KEY_SEQ_LEN;
1168     }
1169     if (params->key_len > WLAN_MAX_KEY_LEN ||
1170         seq_len > sizeof(key->seq))
1171         return -EINVAL;
1172 
1173     key->key_len = params->key_len;
1174     memcpy(key->key, params->key, key->key_len);
1175     key->seq_len = seq_len;
1176     memcpy(key->seq, params->seq, key->seq_len);
1177     key->cipher = params->cipher;
1178 
1179     switch (key->cipher) {
1180     case WLAN_CIPHER_SUITE_WEP40:
1181     case WLAN_CIPHER_SUITE_WEP104:
1182         key_type = WEP_CRYPT;
1183         break;
1184 
1185     case WLAN_CIPHER_SUITE_TKIP:
1186         key_type = TKIP_CRYPT;
1187         break;
1188 
1189     case WLAN_CIPHER_SUITE_CCMP:
1190         key_type = AES_CRYPT;
1191         break;
1192     case WLAN_CIPHER_SUITE_SMS4:
1193         key_type = WAPI_CRYPT;
1194         break;
1195 
1196     default:
1197         return -ENOTSUPP;
1198     }
1199 
1200     if (((vif->auth_mode == WPA_PSK_AUTH) ||
1201          (vif->auth_mode == WPA2_PSK_AUTH)) &&
1202         (key_usage & GROUP_USAGE))
1203         del_timer(&vif->disconnect_timer);
1204 
1205     ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1206            "%s: index %d, key_len %d, key_type 0x%x, key_usage 0x%x, seq_len %d\n",
1207            __func__, key_index, key->key_len, key_type,
1208            key_usage, key->seq_len);
1209 
1210     if (vif->nw_type == AP_NETWORK && !pairwise &&
1211         (key_type == TKIP_CRYPT || key_type == AES_CRYPT ||
1212          key_type == WAPI_CRYPT)) {
1213         ar->ap_mode_bkey.valid = true;
1214         ar->ap_mode_bkey.key_index = key_index;
1215         ar->ap_mode_bkey.key_type = key_type;
1216         ar->ap_mode_bkey.key_len = key->key_len;
1217         memcpy(ar->ap_mode_bkey.key, key->key, key->key_len);
1218         if (!test_bit(CONNECTED, &vif->flags)) {
1219             ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1220                    "Delay initial group key configuration until AP mode has been started\n");
1221             /*
1222              * The key will be set in ath6kl_connect_ap_mode() once
1223              * the connected event is received from the target.
1224              */
1225             return 0;
1226         }
1227     }
1228 
1229     if (vif->next_mode == AP_NETWORK && key_type == WEP_CRYPT &&
1230         !test_bit(CONNECTED, &vif->flags)) {
1231         /*
1232          * Store the key locally so that it can be re-configured after
1233          * the AP mode has properly started
1234          * (ath6kl_install_statioc_wep_keys).
1235          */
1236         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1237                "Delay WEP key configuration until AP mode has been started\n");
1238         vif->wep_key_list[key_index].key_len = key->key_len;
1239         memcpy(vif->wep_key_list[key_index].key, key->key,
1240                key->key_len);
1241         return 0;
1242     }
1243 
1244     return ath6kl_wmi_addkey_cmd(ar->wmi, vif->fw_vif_idx, key_index,
1245                      key_type, key_usage, key->key_len,
1246                      key->seq, key->seq_len, key->key,
1247                      KEY_OP_INIT_VAL,
1248                      (u8 *) mac_addr, SYNC_BOTH_WMIFLAG);
1249 }
1250 
1251 static int ath6kl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
1252                    u8 key_index, bool pairwise,
1253                    const u8 *mac_addr)
1254 {
1255     struct ath6kl *ar = ath6kl_priv(ndev);
1256     struct ath6kl_vif *vif = netdev_priv(ndev);
1257 
1258     ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
1259 
1260     if (!ath6kl_cfg80211_ready(vif))
1261         return -EIO;
1262 
1263     if (key_index > WMI_MAX_KEY_INDEX) {
1264         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1265                "%s: key index %d out of bounds\n", __func__,
1266                key_index);
1267         return -ENOENT;
1268     }
1269 
1270     if (!vif->keys[key_index].key_len) {
1271         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1272                "%s: index %d is empty\n", __func__, key_index);
1273         return 0;
1274     }
1275 
1276     vif->keys[key_index].key_len = 0;
1277 
1278     return ath6kl_wmi_deletekey_cmd(ar->wmi, vif->fw_vif_idx, key_index);
1279 }
1280 
1281 static int ath6kl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
1282                    u8 key_index, bool pairwise,
1283                    const u8 *mac_addr, void *cookie,
1284                    void (*callback) (void *cookie,
1285                              struct key_params *))
1286 {
1287     struct ath6kl_vif *vif = netdev_priv(ndev);
1288     struct ath6kl_key *key = NULL;
1289     struct key_params params;
1290 
1291     ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
1292 
1293     if (!ath6kl_cfg80211_ready(vif))
1294         return -EIO;
1295 
1296     if (key_index > WMI_MAX_KEY_INDEX) {
1297         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1298                "%s: key index %d out of bounds\n", __func__,
1299                key_index);
1300         return -ENOENT;
1301     }
1302 
1303     key = &vif->keys[key_index];
1304     memset(&params, 0, sizeof(params));
1305     params.cipher = key->cipher;
1306     params.key_len = key->key_len;
1307     params.seq_len = key->seq_len;
1308     params.seq = key->seq;
1309     params.key = key->key;
1310 
1311     callback(cookie, &params);
1312 
1313     return key->key_len ? 0 : -ENOENT;
1314 }
1315 
1316 static int ath6kl_cfg80211_set_default_key(struct wiphy *wiphy,
1317                        struct net_device *ndev,
1318                        u8 key_index, bool unicast,
1319                        bool multicast)
1320 {
1321     struct ath6kl *ar = ath6kl_priv(ndev);
1322     struct ath6kl_vif *vif = netdev_priv(ndev);
1323     struct ath6kl_key *key = NULL;
1324     u8 key_usage;
1325     enum ath6kl_crypto_type key_type = NONE_CRYPT;
1326 
1327     ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
1328 
1329     if (!ath6kl_cfg80211_ready(vif))
1330         return -EIO;
1331 
1332     if (key_index > WMI_MAX_KEY_INDEX) {
1333         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1334                "%s: key index %d out of bounds\n",
1335                __func__, key_index);
1336         return -ENOENT;
1337     }
1338 
1339     if (!vif->keys[key_index].key_len) {
1340         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: invalid key index %d\n",
1341                __func__, key_index);
1342         return -EINVAL;
1343     }
1344 
1345     vif->def_txkey_index = key_index;
1346     key = &vif->keys[vif->def_txkey_index];
1347     key_usage = GROUP_USAGE;
1348     if (vif->prwise_crypto == WEP_CRYPT)
1349         key_usage |= TX_USAGE;
1350     if (unicast)
1351         key_type = vif->prwise_crypto;
1352     if (multicast)
1353         key_type = vif->grp_crypto;
1354 
1355     if (vif->next_mode == AP_NETWORK && !test_bit(CONNECTED, &vif->flags))
1356         return 0; /* Delay until AP mode has been started */
1357 
1358     return ath6kl_wmi_addkey_cmd(ar->wmi, vif->fw_vif_idx,
1359                      vif->def_txkey_index,
1360                      key_type, key_usage,
1361                      key->key_len, key->seq, key->seq_len,
1362                      key->key,
1363                      KEY_OP_INIT_VAL, NULL,
1364                      SYNC_BOTH_WMIFLAG);
1365 }
1366 
1367 void ath6kl_cfg80211_tkip_micerr_event(struct ath6kl_vif *vif, u8 keyid,
1368                        bool ismcast)
1369 {
1370     ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1371            "%s: keyid %d, ismcast %d\n", __func__, keyid, ismcast);
1372 
1373     cfg80211_michael_mic_failure(vif->ndev, vif->bssid,
1374                      (ismcast ? NL80211_KEYTYPE_GROUP :
1375                       NL80211_KEYTYPE_PAIRWISE), keyid, NULL,
1376                      GFP_KERNEL);
1377 }
1378 
1379 static int ath6kl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1380 {
1381     struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
1382     struct ath6kl_vif *vif;
1383     int ret;
1384 
1385     ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: changed 0x%x\n", __func__,
1386            changed);
1387 
1388     vif = ath6kl_vif_first(ar);
1389     if (!vif)
1390         return -EIO;
1391 
1392     if (!ath6kl_cfg80211_ready(vif))
1393         return -EIO;
1394 
1395     if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1396         ret = ath6kl_wmi_set_rts_cmd(ar->wmi, wiphy->rts_threshold);
1397         if (ret != 0) {
1398             ath6kl_err("ath6kl_wmi_set_rts_cmd failed\n");
1399             return -EIO;
1400         }
1401     }
1402 
1403     return 0;
1404 }
1405 
1406 static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy,
1407                        struct wireless_dev *wdev,
1408                        enum nl80211_tx_power_setting type,
1409                        int mbm)
1410 {
1411     struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
1412     struct ath6kl_vif *vif;
1413     int dbm = MBM_TO_DBM(mbm);
1414 
1415     ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type 0x%x, dbm %d\n", __func__,
1416            type, dbm);
1417 
1418     vif = ath6kl_vif_first(ar);
1419     if (!vif)
1420         return -EIO;
1421 
1422     if (!ath6kl_cfg80211_ready(vif))
1423         return -EIO;
1424 
1425     switch (type) {
1426     case NL80211_TX_POWER_AUTOMATIC:
1427         return 0;
1428     case NL80211_TX_POWER_LIMITED:
1429         ar->tx_pwr = dbm;
1430         break;
1431     default:
1432         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type 0x%x not supported\n",
1433                __func__, type);
1434         return -EOPNOTSUPP;
1435     }
1436 
1437     ath6kl_wmi_set_tx_pwr_cmd(ar->wmi, vif->fw_vif_idx, dbm);
1438 
1439     return 0;
1440 }
1441 
1442 static int ath6kl_cfg80211_get_txpower(struct wiphy *wiphy,
1443                        struct wireless_dev *wdev,
1444                        int *dbm)
1445 {
1446     struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
1447     struct ath6kl_vif *vif;
1448 
1449     vif = ath6kl_vif_first(ar);
1450     if (!vif)
1451         return -EIO;
1452 
1453     if (!ath6kl_cfg80211_ready(vif))
1454         return -EIO;
1455 
1456     if (test_bit(CONNECTED, &vif->flags)) {
1457         ar->tx_pwr = 255;
1458 
1459         if (ath6kl_wmi_get_tx_pwr_cmd(ar->wmi, vif->fw_vif_idx) != 0) {
1460             ath6kl_err("ath6kl_wmi_get_tx_pwr_cmd failed\n");
1461             return -EIO;
1462         }
1463 
1464         wait_event_interruptible_timeout(ar->event_wq, ar->tx_pwr != 255,
1465                          5 * HZ);
1466 
1467         if (signal_pending(current)) {
1468             ath6kl_err("target did not respond\n");
1469             return -EINTR;
1470         }
1471     }
1472 
1473     *dbm = ar->tx_pwr;
1474     return 0;
1475 }
1476 
1477 static int ath6kl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
1478                       struct net_device *dev,
1479                       bool pmgmt, int timeout)
1480 {
1481     struct ath6kl *ar = ath6kl_priv(dev);
1482     struct wmi_power_mode_cmd mode;
1483     struct ath6kl_vif *vif = netdev_priv(dev);
1484 
1485     ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: pmgmt %d, timeout %d\n",
1486            __func__, pmgmt, timeout);
1487 
1488     if (!ath6kl_cfg80211_ready(vif))
1489         return -EIO;
1490 
1491     if (pmgmt) {
1492         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: rec power\n", __func__);
1493         mode.pwr_mode = REC_POWER;
1494     } else {
1495         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: max perf\n", __func__);
1496         mode.pwr_mode = MAX_PERF_POWER;
1497     }
1498 
1499     if (ath6kl_wmi_powermode_cmd(ar->wmi, vif->fw_vif_idx,
1500                      mode.pwr_mode) != 0) {
1501         ath6kl_err("wmi_powermode_cmd failed\n");
1502         return -EIO;
1503     }
1504 
1505     return 0;
1506 }
1507 
1508 static struct wireless_dev *ath6kl_cfg80211_add_iface(struct wiphy *wiphy,
1509                               const char *name,
1510                               unsigned char name_assign_type,
1511                               enum nl80211_iftype type,
1512                               struct vif_params *params)
1513 {
1514     struct ath6kl *ar = wiphy_priv(wiphy);
1515     struct wireless_dev *wdev;
1516     u8 if_idx, nw_type;
1517 
1518     if (ar->num_vif == ar->vif_max) {
1519         ath6kl_err("Reached maximum number of supported vif\n");
1520         return ERR_PTR(-EINVAL);
1521     }
1522 
1523     if (!ath6kl_is_valid_iftype(ar, type, &if_idx, &nw_type)) {
1524         ath6kl_err("Not a supported interface type\n");
1525         return ERR_PTR(-EINVAL);
1526     }
1527 
1528     wdev = ath6kl_interface_add(ar, name, name_assign_type, type, if_idx, nw_type);
1529     if (!wdev)
1530         return ERR_PTR(-ENOMEM);
1531 
1532     ar->num_vif++;
1533 
1534     return wdev;
1535 }
1536 
1537 static int ath6kl_cfg80211_del_iface(struct wiphy *wiphy,
1538                      struct wireless_dev *wdev)
1539 {
1540     struct ath6kl *ar = wiphy_priv(wiphy);
1541     struct ath6kl_vif *vif = netdev_priv(wdev->netdev);
1542 
1543     spin_lock_bh(&ar->list_lock);
1544     list_del(&vif->list);
1545     spin_unlock_bh(&ar->list_lock);
1546 
1547     ath6kl_cfg80211_vif_stop(vif, test_bit(WMI_READY, &ar->flag));
1548 
1549     rtnl_lock();
1550     ath6kl_cfg80211_vif_cleanup(vif);
1551     rtnl_unlock();
1552 
1553     return 0;
1554 }
1555 
1556 static int ath6kl_cfg80211_change_iface(struct wiphy *wiphy,
1557                     struct net_device *ndev,
1558                     enum nl80211_iftype type,
1559                     struct vif_params *params)
1560 {
1561     struct ath6kl_vif *vif = netdev_priv(ndev);
1562     int i;
1563 
1564     ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type %u\n", __func__, type);
1565 
1566     /*
1567      * Don't bring up p2p on an interface which is not initialized
1568      * for p2p operation where fw does not have capability to switch
1569      * dynamically between non-p2p and p2p type interface.
1570      */
1571     if (!test_bit(ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX,
1572               vif->ar->fw_capabilities) &&
1573         (type == NL80211_IFTYPE_P2P_CLIENT ||
1574          type == NL80211_IFTYPE_P2P_GO)) {
1575         if (vif->ar->vif_max == 1) {
1576             if (vif->fw_vif_idx != 0)
1577                 return -EINVAL;
1578             else
1579                 goto set_iface_type;
1580         }
1581 
1582         for (i = vif->ar->max_norm_iface; i < vif->ar->vif_max; i++) {
1583             if (i == vif->fw_vif_idx)
1584                 break;
1585         }
1586 
1587         if (i == vif->ar->vif_max) {
1588             ath6kl_err("Invalid interface to bring up P2P\n");
1589             return -EINVAL;
1590         }
1591     }
1592 
1593     /* need to clean up enhanced bmiss detection fw state */
1594     ath6kl_cfg80211_sta_bmiss_enhance(vif, false);
1595 
1596 set_iface_type:
1597     switch (type) {
1598     case NL80211_IFTYPE_STATION:
1599     case NL80211_IFTYPE_P2P_CLIENT:
1600         vif->next_mode = INFRA_NETWORK;
1601         break;
1602     case NL80211_IFTYPE_ADHOC:
1603         vif->next_mode = ADHOC_NETWORK;
1604         break;
1605     case NL80211_IFTYPE_AP:
1606     case NL80211_IFTYPE_P2P_GO:
1607         vif->next_mode = AP_NETWORK;
1608         break;
1609     default:
1610         ath6kl_err("invalid interface type %u\n", type);
1611         return -EOPNOTSUPP;
1612     }
1613 
1614     vif->wdev.iftype = type;
1615 
1616     return 0;
1617 }
1618 
1619 static int ath6kl_cfg80211_join_ibss(struct wiphy *wiphy,
1620                      struct net_device *dev,
1621                      struct cfg80211_ibss_params *ibss_param)
1622 {
1623     struct ath6kl *ar = ath6kl_priv(dev);
1624     struct ath6kl_vif *vif = netdev_priv(dev);
1625     int status;
1626 
1627     if (!ath6kl_cfg80211_ready(vif))
1628         return -EIO;
1629 
1630     vif->ssid_len = ibss_param->ssid_len;
1631     memcpy(vif->ssid, ibss_param->ssid, vif->ssid_len);
1632 
1633     if (ibss_param->chandef.chan)
1634         vif->ch_hint = ibss_param->chandef.chan->center_freq;
1635 
1636     if (ibss_param->channel_fixed) {
1637         /*
1638          * TODO: channel_fixed: The channel should be fixed, do not
1639          * search for IBSSs to join on other channels. Target
1640          * firmware does not support this feature, needs to be
1641          * updated.
1642          */
1643         return -EOPNOTSUPP;
1644     }
1645 
1646     memset(vif->req_bssid, 0, sizeof(vif->req_bssid));
1647     if (ibss_param->bssid && !is_broadcast_ether_addr(ibss_param->bssid))
1648         memcpy(vif->req_bssid, ibss_param->bssid,
1649                sizeof(vif->req_bssid));
1650 
1651     ath6kl_set_wpa_version(vif, 0);
1652 
1653     status = ath6kl_set_auth_type(vif, NL80211_AUTHTYPE_OPEN_SYSTEM);
1654     if (status)
1655         return status;
1656 
1657     if (ibss_param->privacy) {
1658         ath6kl_set_cipher(vif, WLAN_CIPHER_SUITE_WEP40, true);
1659         ath6kl_set_cipher(vif, WLAN_CIPHER_SUITE_WEP40, false);
1660     } else {
1661         ath6kl_set_cipher(vif, 0, true);
1662         ath6kl_set_cipher(vif, 0, false);
1663     }
1664 
1665     vif->nw_type = vif->next_mode;
1666 
1667     ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1668            "%s: connect called with authmode %d dot11 auth %d"
1669            " PW crypto %d PW crypto len %d GRP crypto %d"
1670            " GRP crypto len %d channel hint %u\n",
1671            __func__,
1672            vif->auth_mode, vif->dot11_auth_mode, vif->prwise_crypto,
1673            vif->prwise_crypto_len, vif->grp_crypto,
1674            vif->grp_crypto_len, vif->ch_hint);
1675 
1676     status = ath6kl_wmi_connect_cmd(ar->wmi, vif->fw_vif_idx, vif->nw_type,
1677                     vif->dot11_auth_mode, vif->auth_mode,
1678                     vif->prwise_crypto,
1679                     vif->prwise_crypto_len,
1680                     vif->grp_crypto, vif->grp_crypto_len,
1681                     vif->ssid_len, vif->ssid,
1682                     vif->req_bssid, vif->ch_hint,
1683                     ar->connect_ctrl_flags, SUBTYPE_NONE);
1684     set_bit(CONNECT_PEND, &vif->flags);
1685 
1686     return 0;
1687 }
1688 
1689 static int ath6kl_cfg80211_leave_ibss(struct wiphy *wiphy,
1690                       struct net_device *dev)
1691 {
1692     struct ath6kl_vif *vif = netdev_priv(dev);
1693 
1694     if (!ath6kl_cfg80211_ready(vif))
1695         return -EIO;
1696 
1697     ath6kl_disconnect(vif);
1698     memset(vif->ssid, 0, sizeof(vif->ssid));
1699     vif->ssid_len = 0;
1700 
1701     return 0;
1702 }
1703 
1704 static const u32 cipher_suites[] = {
1705     WLAN_CIPHER_SUITE_WEP40,
1706     WLAN_CIPHER_SUITE_WEP104,
1707     WLAN_CIPHER_SUITE_TKIP,
1708     WLAN_CIPHER_SUITE_CCMP,
1709     CCKM_KRK_CIPHER_SUITE,
1710     WLAN_CIPHER_SUITE_SMS4,
1711 };
1712 
1713 static bool is_rate_legacy(s32 rate)
1714 {
1715     static const s32 legacy[] = { 1000, 2000, 5500, 11000,
1716         6000, 9000, 12000, 18000, 24000,
1717         36000, 48000, 54000
1718     };
1719     u8 i;
1720 
1721     for (i = 0; i < ARRAY_SIZE(legacy); i++)
1722         if (rate == legacy[i])
1723             return true;
1724 
1725     return false;
1726 }
1727 
1728 static bool is_rate_ht20(s32 rate, u8 *mcs, bool *sgi)
1729 {
1730     static const s32 ht20[] = { 6500, 13000, 19500, 26000, 39000,
1731         52000, 58500, 65000, 72200
1732     };
1733     u8 i;
1734 
1735     for (i = 0; i < ARRAY_SIZE(ht20); i++) {
1736         if (rate == ht20[i]) {
1737             if (i == ARRAY_SIZE(ht20) - 1)
1738                 /* last rate uses sgi */
1739                 *sgi = true;
1740             else
1741                 *sgi = false;
1742 
1743             *mcs = i;
1744             return true;
1745         }
1746     }
1747     return false;
1748 }
1749 
1750 static bool is_rate_ht40(s32 rate, u8 *mcs, bool *sgi)
1751 {
1752     static const s32 ht40[] = { 13500, 27000, 40500, 54000,
1753         81000, 108000, 121500, 135000,
1754         150000
1755     };
1756     u8 i;
1757 
1758     for (i = 0; i < ARRAY_SIZE(ht40); i++) {
1759         if (rate == ht40[i]) {
1760             if (i == ARRAY_SIZE(ht40) - 1)
1761                 /* last rate uses sgi */
1762                 *sgi = true;
1763             else
1764                 *sgi = false;
1765 
1766             *mcs = i;
1767             return true;
1768         }
1769     }
1770 
1771     return false;
1772 }
1773 
1774 static int ath6kl_get_station(struct wiphy *wiphy, struct net_device *dev,
1775                   const u8 *mac, struct station_info *sinfo)
1776 {
1777     struct ath6kl *ar = ath6kl_priv(dev);
1778     struct ath6kl_vif *vif = netdev_priv(dev);
1779     long left;
1780     bool sgi;
1781     s32 rate;
1782     int ret;
1783     u8 mcs;
1784 
1785     if (memcmp(mac, vif->bssid, ETH_ALEN) != 0)
1786         return -ENOENT;
1787 
1788     if (down_interruptible(&ar->sem))
1789         return -EBUSY;
1790 
1791     set_bit(STATS_UPDATE_PEND, &vif->flags);
1792 
1793     ret = ath6kl_wmi_get_stats_cmd(ar->wmi, vif->fw_vif_idx);
1794 
1795     if (ret != 0) {
1796         up(&ar->sem);
1797         return -EIO;
1798     }
1799 
1800     left = wait_event_interruptible_timeout(ar->event_wq,
1801                         !test_bit(STATS_UPDATE_PEND,
1802                               &vif->flags),
1803                         WMI_TIMEOUT);
1804 
1805     up(&ar->sem);
1806 
1807     if (left == 0)
1808         return -ETIMEDOUT;
1809     else if (left < 0)
1810         return left;
1811 
1812     if (vif->target_stats.rx_byte) {
1813         sinfo->rx_bytes = vif->target_stats.rx_byte;
1814         sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BYTES64);
1815         sinfo->rx_packets = vif->target_stats.rx_pkt;
1816         sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_PACKETS);
1817     }
1818 
1819     if (vif->target_stats.tx_byte) {
1820         sinfo->tx_bytes = vif->target_stats.tx_byte;
1821         sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BYTES64);
1822         sinfo->tx_packets = vif->target_stats.tx_pkt;
1823         sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_PACKETS);
1824     }
1825 
1826     sinfo->signal = vif->target_stats.cs_rssi;
1827     sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL);
1828 
1829     rate = vif->target_stats.tx_ucast_rate;
1830 
1831     if (is_rate_legacy(rate)) {
1832         sinfo->txrate.legacy = rate / 100;
1833     } else if (is_rate_ht20(rate, &mcs, &sgi)) {
1834         if (sgi) {
1835             sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
1836             sinfo->txrate.mcs = mcs - 1;
1837         } else {
1838             sinfo->txrate.mcs = mcs;
1839         }
1840 
1841         sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
1842         sinfo->txrate.bw = RATE_INFO_BW_20;
1843     } else if (is_rate_ht40(rate, &mcs, &sgi)) {
1844         if (sgi) {
1845             sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
1846             sinfo->txrate.mcs = mcs - 1;
1847         } else {
1848             sinfo->txrate.mcs = mcs;
1849         }
1850 
1851         sinfo->txrate.bw = RATE_INFO_BW_40;
1852         sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
1853     } else {
1854         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1855                "invalid rate from stats: %d\n", rate);
1856         ath6kl_debug_war(ar, ATH6KL_WAR_INVALID_RATE);
1857         return 0;
1858     }
1859 
1860     sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
1861 
1862     if (test_bit(CONNECTED, &vif->flags) &&
1863         test_bit(DTIM_PERIOD_AVAIL, &vif->flags) &&
1864         vif->nw_type == INFRA_NETWORK) {
1865         sinfo->filled |= BIT_ULL(NL80211_STA_INFO_BSS_PARAM);
1866         sinfo->bss_param.flags = 0;
1867         sinfo->bss_param.dtim_period = vif->assoc_bss_dtim_period;
1868         sinfo->bss_param.beacon_interval = vif->assoc_bss_beacon_int;
1869     }
1870 
1871     return 0;
1872 }
1873 
1874 static int ath6kl_set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1875                 struct cfg80211_pmksa *pmksa)
1876 {
1877     struct ath6kl *ar = ath6kl_priv(netdev);
1878     struct ath6kl_vif *vif = netdev_priv(netdev);
1879 
1880     return ath6kl_wmi_setpmkid_cmd(ar->wmi, vif->fw_vif_idx, pmksa->bssid,
1881                        pmksa->pmkid, true);
1882 }
1883 
1884 static int ath6kl_del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1885                 struct cfg80211_pmksa *pmksa)
1886 {
1887     struct ath6kl *ar = ath6kl_priv(netdev);
1888     struct ath6kl_vif *vif = netdev_priv(netdev);
1889 
1890     return ath6kl_wmi_setpmkid_cmd(ar->wmi, vif->fw_vif_idx, pmksa->bssid,
1891                        pmksa->pmkid, false);
1892 }
1893 
1894 static int ath6kl_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
1895 {
1896     struct ath6kl *ar = ath6kl_priv(netdev);
1897     struct ath6kl_vif *vif = netdev_priv(netdev);
1898 
1899     if (test_bit(CONNECTED, &vif->flags))
1900         return ath6kl_wmi_setpmkid_cmd(ar->wmi, vif->fw_vif_idx,
1901                            vif->bssid, NULL, false);
1902     return 0;
1903 }
1904 
1905 static int ath6kl_wow_usr(struct ath6kl *ar, struct ath6kl_vif *vif,
1906               struct cfg80211_wowlan *wow, u32 *filter)
1907 {
1908     int ret, pos;
1909     u8 mask[WOW_PATTERN_SIZE];
1910     u16 i;
1911 
1912     /* Configure the patterns that we received from the user. */
1913     for (i = 0; i < wow->n_patterns; i++) {
1914         /*
1915          * Convert given nl80211 specific mask value to equivalent
1916          * driver specific mask value and send it to the chip along
1917          * with patterns. For example, If the mask value defined in
1918          * struct cfg80211_wowlan is 0xA (equivalent binary is 1010),
1919          * then equivalent driver specific mask value is
1920          * "0xFF 0x00 0xFF 0x00".
1921          */
1922         memset(&mask, 0, sizeof(mask));
1923         for (pos = 0; pos < wow->patterns[i].pattern_len; pos++) {
1924             if (wow->patterns[i].mask[pos / 8] & (0x1 << (pos % 8)))
1925                 mask[pos] = 0xFF;
1926         }
1927         /*
1928          * Note: Pattern's offset is not passed as part of wowlan
1929          * parameter from CFG layer. So it's always passed as ZERO
1930          * to the firmware. It means, given WOW patterns are always
1931          * matched from the first byte of received pkt in the firmware.
1932          */
1933         ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
1934                 vif->fw_vif_idx, WOW_LIST_ID,
1935                 wow->patterns[i].pattern_len,
1936                 0 /* pattern offset */,
1937                 wow->patterns[i].pattern, mask);
1938         if (ret)
1939             return ret;
1940     }
1941 
1942     if (wow->disconnect)
1943         *filter |= WOW_FILTER_OPTION_NWK_DISASSOC;
1944 
1945     if (wow->magic_pkt)
1946         *filter |= WOW_FILTER_OPTION_MAGIC_PACKET;
1947 
1948     if (wow->gtk_rekey_failure)
1949         *filter |= WOW_FILTER_OPTION_GTK_ERROR;
1950 
1951     if (wow->eap_identity_req)
1952         *filter |= WOW_FILTER_OPTION_EAP_REQ;
1953 
1954     if (wow->four_way_handshake)
1955         *filter |= WOW_FILTER_OPTION_8021X_4WAYHS;
1956 
1957     return 0;
1958 }
1959 
1960 static int ath6kl_wow_ap(struct ath6kl *ar, struct ath6kl_vif *vif)
1961 {
1962     static const u8 unicst_pattern[] = { 0x00, 0x00, 0x00,
1963         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1964         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1965         0x00, 0x08 };
1966     static const u8 unicst_mask[] = { 0x01, 0x00, 0x00,
1967         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1968         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1969         0x00, 0x7f };
1970     u8 unicst_offset = 0;
1971     static const u8 arp_pattern[] = { 0x08, 0x06 };
1972     static const u8 arp_mask[] = { 0xff, 0xff };
1973     u8 arp_offset = 20;
1974     static const u8 discvr_pattern[] = { 0xe0, 0x00, 0x00, 0xf8 };
1975     static const u8 discvr_mask[] = { 0xf0, 0x00, 0x00, 0xf8 };
1976     u8 discvr_offset = 38;
1977     static const u8 dhcp_pattern[] = { 0xff, 0xff, 0xff, 0xff,
1978         0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1979         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
1980         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1981         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1982         0x00, 0x00, 0x00, 0x00, 0x00, 0x43 /* port 67 */ };
1983     static const u8 dhcp_mask[] = { 0xff, 0xff, 0xff, 0xff,
1984         0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1985         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
1986         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1987         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1988         0x00, 0x00, 0x00, 0x00, 0xff, 0xff /* port 67 */ };
1989     u8 dhcp_offset = 0;
1990     int ret;
1991 
1992     /* Setup unicast IP, EAPOL-like and ARP pkt pattern */
1993     ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
1994             vif->fw_vif_idx, WOW_LIST_ID,
1995             sizeof(unicst_pattern), unicst_offset,
1996             unicst_pattern, unicst_mask);
1997     if (ret) {
1998         ath6kl_err("failed to add WOW unicast IP pattern\n");
1999         return ret;
2000     }
2001 
2002     /* Setup all ARP pkt pattern */
2003     ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
2004             vif->fw_vif_idx, WOW_LIST_ID,
2005             sizeof(arp_pattern), arp_offset,
2006             arp_pattern, arp_mask);
2007     if (ret) {
2008         ath6kl_err("failed to add WOW ARP pattern\n");
2009         return ret;
2010     }
2011 
2012     /*
2013      * Setup multicast pattern for mDNS 224.0.0.251,
2014      * SSDP 239.255.255.250 and LLMNR  224.0.0.252
2015      */
2016     ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
2017             vif->fw_vif_idx, WOW_LIST_ID,
2018             sizeof(discvr_pattern), discvr_offset,
2019             discvr_pattern, discvr_mask);
2020     if (ret) {
2021         ath6kl_err("failed to add WOW mDNS/SSDP/LLMNR pattern\n");
2022         return ret;
2023     }
2024 
2025     /* Setup all DHCP broadcast pkt pattern */
2026     ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
2027             vif->fw_vif_idx, WOW_LIST_ID,
2028             sizeof(dhcp_pattern), dhcp_offset,
2029             dhcp_pattern, dhcp_mask);
2030     if (ret) {
2031         ath6kl_err("failed to add WOW DHCP broadcast pattern\n");
2032         return ret;
2033     }
2034 
2035     return 0;
2036 }
2037 
2038 static int ath6kl_wow_sta(struct ath6kl *ar, struct ath6kl_vif *vif)
2039 {
2040     struct net_device *ndev = vif->ndev;
2041     static const u8 discvr_pattern[] = { 0xe0, 0x00, 0x00, 0xf8 };
2042     static const u8 discvr_mask[] = { 0xf0, 0x00, 0x00, 0xf8 };
2043     u8 discvr_offset = 38;
2044     u8 mac_mask[ETH_ALEN];
2045     int ret;
2046 
2047     /* Setup unicast pkt pattern */
2048     eth_broadcast_addr(mac_mask);
2049     ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
2050                 vif->fw_vif_idx, WOW_LIST_ID,
2051                 ETH_ALEN, 0, ndev->dev_addr,
2052                 mac_mask);
2053     if (ret) {
2054         ath6kl_err("failed to add WOW unicast pattern\n");
2055         return ret;
2056     }
2057 
2058     /*
2059      * Setup multicast pattern for mDNS 224.0.0.251,
2060      * SSDP 239.255.255.250 and LLMNR 224.0.0.252
2061      */
2062     if ((ndev->flags & IFF_ALLMULTI) ||
2063         (ndev->flags & IFF_MULTICAST && netdev_mc_count(ndev) > 0)) {
2064         ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
2065                 vif->fw_vif_idx, WOW_LIST_ID,
2066                 sizeof(discvr_pattern), discvr_offset,
2067                 discvr_pattern, discvr_mask);
2068         if (ret) {
2069             ath6kl_err("failed to add WOW mDNS/SSDP/LLMNR pattern\n");
2070             return ret;
2071         }
2072     }
2073 
2074     return 0;
2075 }
2076 
2077 static int is_hsleep_mode_procsed(struct ath6kl_vif *vif)
2078 {
2079     return test_bit(HOST_SLEEP_MODE_CMD_PROCESSED, &vif->flags);
2080 }
2081 
2082 static bool is_ctrl_ep_empty(struct ath6kl *ar)
2083 {
2084     return !ar->tx_pending[ar->ctrl_ep];
2085 }
2086 
2087 static int ath6kl_cfg80211_host_sleep(struct ath6kl *ar, struct ath6kl_vif *vif)
2088 {
2089     int ret, left;
2090 
2091     clear_bit(HOST_SLEEP_MODE_CMD_PROCESSED, &vif->flags);
2092 
2093     ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
2094                          ATH6KL_HOST_MODE_ASLEEP);
2095     if (ret)
2096         return ret;
2097 
2098     left = wait_event_interruptible_timeout(ar->event_wq,
2099                         is_hsleep_mode_procsed(vif),
2100                         WMI_TIMEOUT);
2101     if (left == 0) {
2102         ath6kl_warn("timeout, didn't get host sleep cmd processed event\n");
2103         ret = -ETIMEDOUT;
2104     } else if (left < 0) {
2105         ath6kl_warn("error while waiting for host sleep cmd processed event %d\n",
2106                 left);
2107         ret = left;
2108     }
2109 
2110     if (ar->tx_pending[ar->ctrl_ep]) {
2111         left = wait_event_interruptible_timeout(ar->event_wq,
2112                             is_ctrl_ep_empty(ar),
2113                             WMI_TIMEOUT);
2114         if (left == 0) {
2115             ath6kl_warn("clear wmi ctrl data timeout\n");
2116             ret = -ETIMEDOUT;
2117         } else if (left < 0) {
2118             ath6kl_warn("clear wmi ctrl data failed: %d\n", left);
2119             ret = left;
2120         }
2121     }
2122 
2123     return ret;
2124 }
2125 
2126 static int ath6kl_wow_suspend_vif(struct ath6kl_vif *vif,
2127                   struct cfg80211_wowlan *wow, u32 *filter)
2128 {
2129     struct ath6kl *ar = vif->ar;
2130     struct in_device *in_dev;
2131     struct in_ifaddr *ifa;
2132     int ret;
2133     u16 i, bmiss_time;
2134     __be32 ips[MAX_IP_ADDRS];
2135     u8 index = 0;
2136 
2137     if (!test_bit(NETDEV_MCAST_ALL_ON, &vif->flags) &&
2138         test_bit(ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER,
2139              ar->fw_capabilities)) {
2140         ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi,
2141                         vif->fw_vif_idx, false);
2142         if (ret)
2143             return ret;
2144     }
2145 
2146     /* Clear existing WOW patterns */
2147     for (i = 0; i < WOW_MAX_FILTERS_PER_LIST; i++)
2148         ath6kl_wmi_del_wow_pattern_cmd(ar->wmi, vif->fw_vif_idx,
2149                            WOW_LIST_ID, i);
2150 
2151     /*
2152      * Skip the default WOW pattern configuration
2153      * if the driver receives any WOW patterns from
2154      * the user.
2155      */
2156     if (wow)
2157         ret = ath6kl_wow_usr(ar, vif, wow, filter);
2158     else if (vif->nw_type == AP_NETWORK)
2159         ret = ath6kl_wow_ap(ar, vif);
2160     else
2161         ret = ath6kl_wow_sta(ar, vif);
2162 
2163     if (ret)
2164         return ret;
2165 
2166     netif_stop_queue(vif->ndev);
2167 
2168     if (vif->nw_type != AP_NETWORK) {
2169         ret = ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx,
2170                             ATH6KL_MAX_WOW_LISTEN_INTL,
2171                             0);
2172         if (ret)
2173             return ret;
2174 
2175         /* Set listen interval x 15 times as bmiss time */
2176         bmiss_time = ATH6KL_MAX_WOW_LISTEN_INTL * 15;
2177         if (bmiss_time > ATH6KL_MAX_BMISS_TIME)
2178             bmiss_time = ATH6KL_MAX_BMISS_TIME;
2179 
2180         ret = ath6kl_wmi_bmisstime_cmd(ar->wmi, vif->fw_vif_idx,
2181                            bmiss_time, 0);
2182         if (ret)
2183             return ret;
2184 
2185         ret = ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx,
2186                         0xFFFF, 0, 0xFFFF, 0, 0, 0,
2187                         0, 0, 0, 0);
2188         if (ret)
2189             return ret;
2190     }
2191 
2192     /* Setup own IP addr for ARP agent. */
2193     in_dev = __in_dev_get_rtnl(vif->ndev);
2194     if (!in_dev)
2195         return 0;
2196 
2197     ifa = rtnl_dereference(in_dev->ifa_list);
2198     memset(&ips, 0, sizeof(ips));
2199 
2200     /* Configure IP addr only if IP address count < MAX_IP_ADDRS */
2201     while (index < MAX_IP_ADDRS && ifa) {
2202         ips[index] = ifa->ifa_local;
2203         ifa = rtnl_dereference(ifa->ifa_next);
2204         index++;
2205     }
2206 
2207     if (ifa) {
2208         ath6kl_err("total IP addr count is exceeding fw limit\n");
2209         return -EINVAL;
2210     }
2211 
2212     ret = ath6kl_wmi_set_ip_cmd(ar->wmi, vif->fw_vif_idx, ips[0], ips[1]);
2213     if (ret) {
2214         ath6kl_err("fail to setup ip for arp agent\n");
2215         return ret;
2216     }
2217 
2218     return ret;
2219 }
2220 
2221 static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
2222 {
2223     struct ath6kl_vif *first_vif, *vif;
2224     int ret = 0;
2225     u32 filter = 0;
2226     bool connected = false;
2227 
2228     /* enter / leave wow suspend on first vif always */
2229     first_vif = ath6kl_vif_first(ar);
2230     if (WARN_ON(!first_vif) ||
2231         !ath6kl_cfg80211_ready(first_vif))
2232         return -EIO;
2233 
2234     if (wow && (wow->n_patterns > WOW_MAX_FILTERS_PER_LIST))
2235         return -EINVAL;
2236 
2237     /* install filters for each connected vif */
2238     spin_lock_bh(&ar->list_lock);
2239     list_for_each_entry(vif, &ar->vif_list, list) {
2240         if (!test_bit(CONNECTED, &vif->flags) ||
2241             !ath6kl_cfg80211_ready(vif))
2242             continue;
2243         connected = true;
2244 
2245         ret = ath6kl_wow_suspend_vif(vif, wow, &filter);
2246         if (ret)
2247             break;
2248     }
2249     spin_unlock_bh(&ar->list_lock);
2250 
2251     if (!connected)
2252         return -ENOTCONN;
2253     else if (ret)
2254         return ret;
2255 
2256     ar->state = ATH6KL_STATE_SUSPENDING;
2257 
2258     ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, first_vif->fw_vif_idx,
2259                       ATH6KL_WOW_MODE_ENABLE,
2260                       filter,
2261                       WOW_HOST_REQ_DELAY);
2262     if (ret)
2263         return ret;
2264 
2265     return ath6kl_cfg80211_host_sleep(ar, first_vif);
2266 }
2267 
2268 static int ath6kl_wow_resume_vif(struct ath6kl_vif *vif)
2269 {
2270     struct ath6kl *ar = vif->ar;
2271     int ret;
2272 
2273     if (vif->nw_type != AP_NETWORK) {
2274         ret = ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx,
2275                         0, 0, 0, 0, 0, 0, 3, 0, 0, 0);
2276         if (ret)
2277             return ret;
2278 
2279         ret = ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx,
2280                             vif->listen_intvl_t, 0);
2281         if (ret)
2282             return ret;
2283 
2284         ret = ath6kl_wmi_bmisstime_cmd(ar->wmi, vif->fw_vif_idx,
2285                            vif->bmiss_time_t, 0);
2286         if (ret)
2287             return ret;
2288     }
2289 
2290     if (!test_bit(NETDEV_MCAST_ALL_OFF, &vif->flags) &&
2291         test_bit(ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER,
2292              ar->fw_capabilities)) {
2293         ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi,
2294                           vif->fw_vif_idx, true);
2295         if (ret)
2296             return ret;
2297     }
2298 
2299     netif_wake_queue(vif->ndev);
2300 
2301     return 0;
2302 }
2303 
2304 static int ath6kl_wow_resume(struct ath6kl *ar)
2305 {
2306     struct ath6kl_vif *vif;
2307     int ret;
2308 
2309     vif = ath6kl_vif_first(ar);
2310     if (WARN_ON(!vif) ||
2311         !ath6kl_cfg80211_ready(vif))
2312         return -EIO;
2313 
2314     ar->state = ATH6KL_STATE_RESUMING;
2315 
2316     ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
2317                          ATH6KL_HOST_MODE_AWAKE);
2318     if (ret) {
2319         ath6kl_warn("Failed to configure host sleep mode for wow resume: %d\n",
2320                 ret);
2321         goto cleanup;
2322     }
2323 
2324     spin_lock_bh(&ar->list_lock);
2325     list_for_each_entry(vif, &ar->vif_list, list) {
2326         if (!test_bit(CONNECTED, &vif->flags) ||
2327             !ath6kl_cfg80211_ready(vif))
2328             continue;
2329         ret = ath6kl_wow_resume_vif(vif);
2330         if (ret)
2331             break;
2332     }
2333     spin_unlock_bh(&ar->list_lock);
2334 
2335     if (ret)
2336         goto cleanup;
2337 
2338     ar->state = ATH6KL_STATE_ON;
2339     return 0;
2340 
2341 cleanup:
2342     ar->state = ATH6KL_STATE_WOW;
2343     return ret;
2344 }
2345 
2346 static int ath6kl_cfg80211_deepsleep_suspend(struct ath6kl *ar)
2347 {
2348     struct ath6kl_vif *vif;
2349     int ret;
2350 
2351     vif = ath6kl_vif_first(ar);
2352     if (!vif)
2353         return -EIO;
2354 
2355     if (!test_bit(WMI_READY, &ar->flag)) {
2356         ath6kl_err("deepsleep failed as wmi is not ready\n");
2357         return -EIO;
2358     }
2359 
2360     ath6kl_cfg80211_stop_all(ar);
2361 
2362     /* Save the current power mode before enabling power save */
2363     ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode;
2364 
2365     ret = ath6kl_wmi_powermode_cmd(ar->wmi, 0, REC_POWER);
2366     if (ret)
2367         return ret;
2368 
2369     /* Disable WOW mode */
2370     ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, vif->fw_vif_idx,
2371                       ATH6KL_WOW_MODE_DISABLE,
2372                       0, 0);
2373     if (ret)
2374         return ret;
2375 
2376     /* Flush all non control pkts in TX path */
2377     ath6kl_tx_data_cleanup(ar);
2378 
2379     ret = ath6kl_cfg80211_host_sleep(ar, vif);
2380     if (ret)
2381         return ret;
2382 
2383     return 0;
2384 }
2385 
2386 static int ath6kl_cfg80211_deepsleep_resume(struct ath6kl *ar)
2387 {
2388     struct ath6kl_vif *vif;
2389     int ret;
2390 
2391     vif = ath6kl_vif_first(ar);
2392 
2393     if (!vif)
2394         return -EIO;
2395 
2396     if (ar->wmi->pwr_mode != ar->wmi->saved_pwr_mode) {
2397         ret = ath6kl_wmi_powermode_cmd(ar->wmi, 0,
2398                            ar->wmi->saved_pwr_mode);
2399         if (ret)
2400             return ret;
2401     }
2402 
2403     ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
2404                          ATH6KL_HOST_MODE_AWAKE);
2405     if (ret)
2406         return ret;
2407 
2408     ar->state = ATH6KL_STATE_ON;
2409 
2410     /* Reset scan parameter to default values */
2411     ret = ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx,
2412                     0, 0, 0, 0, 0, 0, 3, 0, 0, 0);
2413     if (ret)
2414         return ret;
2415 
2416     return 0;
2417 }
2418 
2419 int ath6kl_cfg80211_suspend(struct ath6kl *ar,
2420                 enum ath6kl_cfg_suspend_mode mode,
2421                 struct cfg80211_wowlan *wow)
2422 {
2423     struct ath6kl_vif *vif;
2424     enum ath6kl_state prev_state;
2425     int ret;
2426 
2427     switch (mode) {
2428     case ATH6KL_CFG_SUSPEND_WOW:
2429 
2430         ath6kl_dbg(ATH6KL_DBG_SUSPEND, "wow mode suspend\n");
2431 
2432         /* Flush all non control pkts in TX path */
2433         ath6kl_tx_data_cleanup(ar);
2434 
2435         prev_state = ar->state;
2436 
2437         ret = ath6kl_wow_suspend(ar, wow);
2438         if (ret) {
2439             ar->state = prev_state;
2440             return ret;
2441         }
2442 
2443         ar->state = ATH6KL_STATE_WOW;
2444         break;
2445 
2446     case ATH6KL_CFG_SUSPEND_DEEPSLEEP:
2447 
2448         ath6kl_dbg(ATH6KL_DBG_SUSPEND, "deep sleep suspend\n");
2449 
2450         ret = ath6kl_cfg80211_deepsleep_suspend(ar);
2451         if (ret) {
2452             ath6kl_err("deepsleep suspend failed: %d\n", ret);
2453             return ret;
2454         }
2455 
2456         ar->state = ATH6KL_STATE_DEEPSLEEP;
2457 
2458         break;
2459 
2460     case ATH6KL_CFG_SUSPEND_CUTPOWER:
2461 
2462         ath6kl_cfg80211_stop_all(ar);
2463 
2464         if (ar->state == ATH6KL_STATE_OFF) {
2465             ath6kl_dbg(ATH6KL_DBG_SUSPEND,
2466                    "suspend hw off, no action for cutpower\n");
2467             break;
2468         }
2469 
2470         ath6kl_dbg(ATH6KL_DBG_SUSPEND, "suspend cutting power\n");
2471 
2472         ret = ath6kl_init_hw_stop(ar);
2473         if (ret) {
2474             ath6kl_warn("failed to stop hw during suspend: %d\n",
2475                     ret);
2476         }
2477 
2478         ar->state = ATH6KL_STATE_CUTPOWER;
2479 
2480         break;
2481 
2482     default:
2483         break;
2484     }
2485 
2486     list_for_each_entry(vif, &ar->vif_list, list)
2487         ath6kl_cfg80211_scan_complete_event(vif, true);
2488 
2489     return 0;
2490 }
2491 EXPORT_SYMBOL(ath6kl_cfg80211_suspend);
2492 
2493 int ath6kl_cfg80211_resume(struct ath6kl *ar)
2494 {
2495     int ret;
2496 
2497     switch (ar->state) {
2498     case  ATH6KL_STATE_WOW:
2499         ath6kl_dbg(ATH6KL_DBG_SUSPEND, "wow mode resume\n");
2500 
2501         ret = ath6kl_wow_resume(ar);
2502         if (ret) {
2503             ath6kl_warn("wow mode resume failed: %d\n", ret);
2504             return ret;
2505         }
2506 
2507         break;
2508 
2509     case ATH6KL_STATE_DEEPSLEEP:
2510         ath6kl_dbg(ATH6KL_DBG_SUSPEND, "deep sleep resume\n");
2511 
2512         ret = ath6kl_cfg80211_deepsleep_resume(ar);
2513         if (ret) {
2514             ath6kl_warn("deep sleep resume failed: %d\n", ret);
2515             return ret;
2516         }
2517         break;
2518 
2519     case ATH6KL_STATE_CUTPOWER:
2520         ath6kl_dbg(ATH6KL_DBG_SUSPEND, "resume restoring power\n");
2521 
2522         ret = ath6kl_init_hw_start(ar);
2523         if (ret) {
2524             ath6kl_warn("Failed to boot hw in resume: %d\n", ret);
2525             return ret;
2526         }
2527         break;
2528 
2529     default:
2530         break;
2531     }
2532 
2533     return 0;
2534 }
2535 EXPORT_SYMBOL(ath6kl_cfg80211_resume);
2536 
2537 #ifdef CONFIG_PM
2538 
2539 /* hif layer decides what suspend mode to use */
2540 static int __ath6kl_cfg80211_suspend(struct wiphy *wiphy,
2541                  struct cfg80211_wowlan *wow)
2542 {
2543     struct ath6kl *ar = wiphy_priv(wiphy);
2544 
2545     ath6kl_recovery_suspend(ar);
2546 
2547     return ath6kl_hif_suspend(ar, wow);
2548 }
2549 
2550 static int __ath6kl_cfg80211_resume(struct wiphy *wiphy)
2551 {
2552     struct ath6kl *ar = wiphy_priv(wiphy);
2553     int err;
2554 
2555     err = ath6kl_hif_resume(ar);
2556     if (err)
2557         return err;
2558 
2559     ath6kl_recovery_resume(ar);
2560 
2561     return 0;
2562 }
2563 
2564 /*
2565  * FIXME: WOW suspend mode is selected if the host sdio controller supports
2566  * both sdio irq wake up and keep power. The target pulls sdio data line to
2567  * wake up the host when WOW pattern matches. This causes sdio irq handler
2568  * is being called in the host side which internally hits ath6kl's RX path.
2569  *
2570  * Since sdio interrupt is not disabled, RX path executes even before
2571  * the host executes the actual resume operation from PM module.
2572  *
2573  * In the current scenario, WOW resume should happen before start processing
2574  * any data from the target. So It's required to perform WOW resume in RX path.
2575  * Ideally we should perform WOW resume only in the actual platform
2576  * resume path. This area needs bit rework to avoid WOW resume in RX path.
2577  *
2578  * ath6kl_check_wow_status() is called from ath6kl_rx().
2579  */
2580 void ath6kl_check_wow_status(struct ath6kl *ar)
2581 {
2582     if (ar->state == ATH6KL_STATE_SUSPENDING)
2583         return;
2584 
2585     if (ar->state == ATH6KL_STATE_WOW)
2586         ath6kl_cfg80211_resume(ar);
2587 }
2588 
2589 #else
2590 
2591 void ath6kl_check_wow_status(struct ath6kl *ar)
2592 {
2593 }
2594 #endif
2595 
2596 static int ath6kl_set_htcap(struct ath6kl_vif *vif, enum nl80211_band band,
2597                 bool ht_enable)
2598 {
2599     struct ath6kl_htcap *htcap = &vif->htcap[band];
2600 
2601     if (htcap->ht_enable == ht_enable)
2602         return 0;
2603 
2604     if (ht_enable) {
2605         /* Set default ht capabilities */
2606         htcap->ht_enable = true;
2607         htcap->cap_info = (band == NL80211_BAND_2GHZ) ?
2608                    ath6kl_g_htcap : ath6kl_a_htcap;
2609         htcap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K;
2610     } else /* Disable ht */
2611         memset(htcap, 0, sizeof(*htcap));
2612 
2613     return ath6kl_wmi_set_htcap_cmd(vif->ar->wmi, vif->fw_vif_idx,
2614                     band, htcap);
2615 }
2616 
2617 static int ath6kl_restore_htcap(struct ath6kl_vif *vif)
2618 {
2619     struct wiphy *wiphy = vif->ar->wiphy;
2620     int band, ret = 0;
2621 
2622     for (band = 0; band < NUM_NL80211_BANDS; band++) {
2623         if (!wiphy->bands[band])
2624             continue;
2625 
2626         ret = ath6kl_set_htcap(vif, band,
2627                 wiphy->bands[band]->ht_cap.ht_supported);
2628         if (ret)
2629             return ret;
2630     }
2631 
2632     return ret;
2633 }
2634 
2635 static bool ath6kl_is_p2p_ie(const u8 *pos)
2636 {
2637     return pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
2638         pos[2] == 0x50 && pos[3] == 0x6f &&
2639         pos[4] == 0x9a && pos[5] == 0x09;
2640 }
2641 
2642 static int ath6kl_set_ap_probe_resp_ies(struct ath6kl_vif *vif,
2643                     const u8 *ies, size_t ies_len)
2644 {
2645     struct ath6kl *ar = vif->ar;
2646     const u8 *pos;
2647     u8 *buf = NULL;
2648     size_t len = 0;
2649     int ret;
2650 
2651     /*
2652      * Filter out P2P IE(s) since they will be included depending on
2653      * the Probe Request frame in ath6kl_send_go_probe_resp().
2654      */
2655 
2656     if (ies && ies_len) {
2657         buf = kmalloc(ies_len, GFP_KERNEL);
2658         if (buf == NULL)
2659             return -ENOMEM;
2660         pos = ies;
2661         while (pos + 1 < ies + ies_len) {
2662             if (pos + 2 + pos[1] > ies + ies_len)
2663                 break;
2664             if (!ath6kl_is_p2p_ie(pos)) {
2665                 memcpy(buf + len, pos, 2 + pos[1]);
2666                 len += 2 + pos[1];
2667             }
2668             pos += 2 + pos[1];
2669         }
2670     }
2671 
2672     ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
2673                        WMI_FRAME_PROBE_RESP, buf, len);
2674     kfree(buf);
2675     return ret;
2676 }
2677 
2678 static int ath6kl_set_ies(struct ath6kl_vif *vif,
2679               struct cfg80211_beacon_data *info)
2680 {
2681     struct ath6kl *ar = vif->ar;
2682     int res;
2683 
2684     /* this also clears IE in fw if it's not set */
2685     res = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
2686                        WMI_FRAME_BEACON,
2687                        info->beacon_ies,
2688                        info->beacon_ies_len);
2689     if (res)
2690         return res;
2691 
2692     /* this also clears IE in fw if it's not set */
2693     res = ath6kl_set_ap_probe_resp_ies(vif, info->proberesp_ies,
2694                        info->proberesp_ies_len);
2695     if (res)
2696         return res;
2697 
2698     /* this also clears IE in fw if it's not set */
2699     res = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
2700                        WMI_FRAME_ASSOC_RESP,
2701                        info->assocresp_ies,
2702                        info->assocresp_ies_len);
2703     if (res)
2704         return res;
2705 
2706     return 0;
2707 }
2708 
2709 static int ath6kl_get_rsn_capab(struct cfg80211_beacon_data *beacon,
2710                 u8 *rsn_capab)
2711 {
2712     const u8 *rsn_ie;
2713     size_t rsn_ie_len;
2714     u16 cnt;
2715 
2716     if (!beacon->tail)
2717         return -EINVAL;
2718 
2719     rsn_ie = cfg80211_find_ie(WLAN_EID_RSN, beacon->tail, beacon->tail_len);
2720     if (!rsn_ie)
2721         return -EINVAL;
2722 
2723     rsn_ie_len = *(rsn_ie + 1);
2724     /* skip element id and length */
2725     rsn_ie += 2;
2726 
2727     /* skip version */
2728     if (rsn_ie_len < 2)
2729         return -EINVAL;
2730     rsn_ie +=  2;
2731     rsn_ie_len -= 2;
2732 
2733     /* skip group cipher suite */
2734     if (rsn_ie_len < 4)
2735         return 0;
2736     rsn_ie +=  4;
2737     rsn_ie_len -= 4;
2738 
2739     /* skip pairwise cipher suite */
2740     if (rsn_ie_len < 2)
2741         return 0;
2742     cnt = get_unaligned_le16(rsn_ie);
2743     rsn_ie += (2 + cnt * 4);
2744     rsn_ie_len -= (2 + cnt * 4);
2745 
2746     /* skip akm suite */
2747     if (rsn_ie_len < 2)
2748         return 0;
2749     cnt = get_unaligned_le16(rsn_ie);
2750     rsn_ie += (2 + cnt * 4);
2751     rsn_ie_len -= (2 + cnt * 4);
2752 
2753     if (rsn_ie_len < 2)
2754         return 0;
2755 
2756     memcpy(rsn_capab, rsn_ie, 2);
2757 
2758     return 0;
2759 }
2760 
2761 static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,
2762                struct cfg80211_ap_settings *info)
2763 {
2764     struct ath6kl *ar = ath6kl_priv(dev);
2765     struct ath6kl_vif *vif = netdev_priv(dev);
2766     struct ieee80211_mgmt *mgmt;
2767     bool hidden = false;
2768     u8 *ies;
2769     struct wmi_connect_cmd p;
2770     int res;
2771     int i, ret;
2772     u16 rsn_capab = 0;
2773     int inactivity_timeout = 0;
2774 
2775     ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s:\n", __func__);
2776 
2777     if (!ath6kl_cfg80211_ready(vif))
2778         return -EIO;
2779 
2780     if (vif->next_mode != AP_NETWORK)
2781         return -EOPNOTSUPP;
2782 
2783     res = ath6kl_set_ies(vif, &info->beacon);
2784 
2785     ar->ap_mode_bkey.valid = false;
2786 
2787     ret = ath6kl_wmi_ap_set_beacon_intvl_cmd(ar->wmi, vif->fw_vif_idx,
2788                          info->beacon_interval);
2789 
2790     if (ret)
2791         ath6kl_warn("Failed to set beacon interval: %d\n", ret);
2792 
2793     ret = ath6kl_wmi_ap_set_dtim_cmd(ar->wmi, vif->fw_vif_idx,
2794                      info->dtim_period);
2795 
2796     /* ignore error, just print a warning and continue normally */
2797     if (ret)
2798         ath6kl_warn("Failed to set dtim_period in beacon: %d\n", ret);
2799 
2800     if (info->beacon.head == NULL)
2801         return -EINVAL;
2802     mgmt = (struct ieee80211_mgmt *) info->beacon.head;
2803     ies = mgmt->u.beacon.variable;
2804     if (ies > info->beacon.head + info->beacon.head_len)
2805         return -EINVAL;
2806 
2807     if (info->ssid == NULL)
2808         return -EINVAL;
2809     memcpy(vif->ssid, info->ssid, info->ssid_len);
2810     vif->ssid_len = info->ssid_len;
2811     if (info->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
2812         hidden = true;
2813 
2814     res = ath6kl_wmi_ap_hidden_ssid(ar->wmi, vif->fw_vif_idx, hidden);
2815     if (res)
2816         return res;
2817 
2818     ret = ath6kl_set_auth_type(vif, info->auth_type);
2819     if (ret)
2820         return ret;
2821 
2822     memset(&p, 0, sizeof(p));
2823 
2824     for (i = 0; i < info->crypto.n_akm_suites; i++) {
2825         switch (info->crypto.akm_suites[i]) {
2826         case WLAN_AKM_SUITE_8021X:
2827             if (info->crypto.wpa_versions & NL80211_WPA_VERSION_1)
2828                 p.auth_mode |= WPA_AUTH;
2829             if (info->crypto.wpa_versions & NL80211_WPA_VERSION_2)
2830                 p.auth_mode |= WPA2_AUTH;
2831             break;
2832         case WLAN_AKM_SUITE_PSK:
2833             if (info->crypto.wpa_versions & NL80211_WPA_VERSION_1)
2834                 p.auth_mode |= WPA_PSK_AUTH;
2835             if (info->crypto.wpa_versions & NL80211_WPA_VERSION_2)
2836                 p.auth_mode |= WPA2_PSK_AUTH;
2837             break;
2838         }
2839     }
2840     if (p.auth_mode == 0)
2841         p.auth_mode = NONE_AUTH;
2842     vif->auth_mode = p.auth_mode;
2843 
2844     for (i = 0; i < info->crypto.n_ciphers_pairwise; i++) {
2845         switch (info->crypto.ciphers_pairwise[i]) {
2846         case WLAN_CIPHER_SUITE_WEP40:
2847         case WLAN_CIPHER_SUITE_WEP104:
2848             p.prwise_crypto_type |= WEP_CRYPT;
2849             break;
2850         case WLAN_CIPHER_SUITE_TKIP:
2851             p.prwise_crypto_type |= TKIP_CRYPT;
2852             break;
2853         case WLAN_CIPHER_SUITE_CCMP:
2854             p.prwise_crypto_type |= AES_CRYPT;
2855             break;
2856         case WLAN_CIPHER_SUITE_SMS4:
2857             p.prwise_crypto_type |= WAPI_CRYPT;
2858             break;
2859         }
2860     }
2861     if (p.prwise_crypto_type == 0) {
2862         p.prwise_crypto_type = NONE_CRYPT;
2863         ath6kl_set_cipher(vif, 0, true);
2864     } else if (info->crypto.n_ciphers_pairwise == 1) {
2865         ath6kl_set_cipher(vif, info->crypto.ciphers_pairwise[0], true);
2866     }
2867 
2868     switch (info->crypto.cipher_group) {
2869     case WLAN_CIPHER_SUITE_WEP40:
2870     case WLAN_CIPHER_SUITE_WEP104:
2871         p.grp_crypto_type = WEP_CRYPT;
2872         break;
2873     case WLAN_CIPHER_SUITE_TKIP:
2874         p.grp_crypto_type = TKIP_CRYPT;
2875         break;
2876     case WLAN_CIPHER_SUITE_CCMP:
2877         p.grp_crypto_type = AES_CRYPT;
2878         break;
2879     case WLAN_CIPHER_SUITE_SMS4:
2880         p.grp_crypto_type = WAPI_CRYPT;
2881         break;
2882     default:
2883         p.grp_crypto_type = NONE_CRYPT;
2884         break;
2885     }
2886     ath6kl_set_cipher(vif, info->crypto.cipher_group, false);
2887 
2888     p.nw_type = AP_NETWORK;
2889     vif->nw_type = vif->next_mode;
2890 
2891     p.ssid_len = vif->ssid_len;
2892     memcpy(p.ssid, vif->ssid, vif->ssid_len);
2893     p.dot11_auth_mode = vif->dot11_auth_mode;
2894     p.ch = cpu_to_le16(info->chandef.chan->center_freq);
2895 
2896     /* Enable uAPSD support by default */
2897     res = ath6kl_wmi_ap_set_apsd(ar->wmi, vif->fw_vif_idx, true);
2898     if (res < 0)
2899         return res;
2900 
2901     if (vif->wdev.iftype == NL80211_IFTYPE_P2P_GO) {
2902         p.nw_subtype = SUBTYPE_P2PGO;
2903     } else {
2904         /*
2905          * Due to firmware limitation, it is not possible to
2906          * do P2P mgmt operations in AP mode
2907          */
2908         p.nw_subtype = SUBTYPE_NONE;
2909     }
2910 
2911     if (info->inactivity_timeout) {
2912         inactivity_timeout = info->inactivity_timeout;
2913 
2914         if (test_bit(ATH6KL_FW_CAPABILITY_AP_INACTIVITY_MINS,
2915                  ar->fw_capabilities))
2916             inactivity_timeout = DIV_ROUND_UP(inactivity_timeout,
2917                               60);
2918 
2919         res = ath6kl_wmi_set_inact_period(ar->wmi, vif->fw_vif_idx,
2920                           inactivity_timeout);
2921         if (res < 0)
2922             return res;
2923     }
2924 
2925     if (ath6kl_set_htcap(vif, info->chandef.chan->band,
2926                  cfg80211_get_chandef_type(&info->chandef)
2927                     != NL80211_CHAN_NO_HT))
2928         return -EIO;
2929 
2930     /*
2931      * Get the PTKSA replay counter in the RSN IE. Supplicant
2932      * will use the RSN IE in M3 message and firmware has to
2933      * advertise the same in beacon/probe response. Send
2934      * the complete RSN IE capability field to firmware
2935      */
2936     if (!ath6kl_get_rsn_capab(&info->beacon, (u8 *) &rsn_capab) &&
2937         test_bit(ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE,
2938              ar->fw_capabilities)) {
2939         res = ath6kl_wmi_set_ie_cmd(ar->wmi, vif->fw_vif_idx,
2940                         WLAN_EID_RSN, WMI_RSN_IE_CAPB,
2941                         (const u8 *) &rsn_capab,
2942                         sizeof(rsn_capab));
2943         vif->rsn_capab = rsn_capab;
2944         if (res < 0)
2945             return res;
2946     }
2947 
2948     memcpy(&vif->profile, &p, sizeof(p));
2949     res = ath6kl_wmi_ap_profile_commit(ar->wmi, vif->fw_vif_idx, &p);
2950     if (res < 0)
2951         return res;
2952 
2953     return 0;
2954 }
2955 
2956 static int ath6kl_change_beacon(struct wiphy *wiphy, struct net_device *dev,
2957                 struct cfg80211_beacon_data *beacon)
2958 {
2959     struct ath6kl_vif *vif = netdev_priv(dev);
2960 
2961     if (!ath6kl_cfg80211_ready(vif))
2962         return -EIO;
2963 
2964     if (vif->next_mode != AP_NETWORK)
2965         return -EOPNOTSUPP;
2966 
2967     return ath6kl_set_ies(vif, beacon);
2968 }
2969 
2970 static int ath6kl_stop_ap(struct wiphy *wiphy, struct net_device *dev,
2971               unsigned int link_id)
2972 {
2973     struct ath6kl *ar = ath6kl_priv(dev);
2974     struct ath6kl_vif *vif = netdev_priv(dev);
2975 
2976     if (vif->nw_type != AP_NETWORK)
2977         return -EOPNOTSUPP;
2978     if (!test_bit(CONNECTED, &vif->flags))
2979         return -ENOTCONN;
2980 
2981     ath6kl_wmi_disconnect_cmd(ar->wmi, vif->fw_vif_idx);
2982     clear_bit(CONNECTED, &vif->flags);
2983     netif_carrier_off(vif->ndev);
2984 
2985     /* Restore ht setting in firmware */
2986     return ath6kl_restore_htcap(vif);
2987 }
2988 
2989 static const u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
2990 
2991 static int ath6kl_del_station(struct wiphy *wiphy, struct net_device *dev,
2992                   struct station_del_parameters *params)
2993 {
2994     struct ath6kl *ar = ath6kl_priv(dev);
2995     struct ath6kl_vif *vif = netdev_priv(dev);
2996     const u8 *addr = params->mac ? params->mac : bcast_addr;
2997 
2998     return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx, WMI_AP_DEAUTH,
2999                       addr, WLAN_REASON_PREV_AUTH_NOT_VALID);
3000 }
3001 
3002 static int ath6kl_change_station(struct wiphy *wiphy, struct net_device *dev,
3003                  const u8 *mac,
3004                  struct station_parameters *params)
3005 {
3006     struct ath6kl *ar = ath6kl_priv(dev);
3007     struct ath6kl_vif *vif = netdev_priv(dev);
3008     int err;
3009 
3010     if (vif->nw_type != AP_NETWORK)
3011         return -EOPNOTSUPP;
3012 
3013     err = cfg80211_check_station_change(wiphy, params,
3014                         CFG80211_STA_AP_MLME_CLIENT);
3015     if (err)
3016         return err;
3017 
3018     if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
3019         return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx,
3020                           WMI_AP_MLME_AUTHORIZE, mac, 0);
3021     return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx,
3022                       WMI_AP_MLME_UNAUTHORIZE, mac, 0);
3023 }
3024 
3025 static int ath6kl_remain_on_channel(struct wiphy *wiphy,
3026                     struct wireless_dev *wdev,
3027                     struct ieee80211_channel *chan,
3028                     unsigned int duration,
3029                     u64 *cookie)
3030 {
3031     struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev);
3032     struct ath6kl *ar = ath6kl_priv(vif->ndev);
3033     u32 id;
3034 
3035     /* TODO: if already pending or ongoing remain-on-channel,
3036      * return -EBUSY */
3037     id = ++vif->last_roc_id;
3038     if (id == 0) {
3039         /* Do not use 0 as the cookie value */
3040         id = ++vif->last_roc_id;
3041     }
3042     *cookie = id;
3043 
3044     return ath6kl_wmi_remain_on_chnl_cmd(ar->wmi, vif->fw_vif_idx,
3045                          chan->center_freq, duration);
3046 }
3047 
3048 static int ath6kl_cancel_remain_on_channel(struct wiphy *wiphy,
3049                        struct wireless_dev *wdev,
3050                        u64 cookie)
3051 {
3052     struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev);
3053     struct ath6kl *ar = ath6kl_priv(vif->ndev);
3054 
3055     if (cookie != vif->last_roc_id)
3056         return -ENOENT;
3057     vif->last_cancel_roc_id = cookie;
3058 
3059     return ath6kl_wmi_cancel_remain_on_chnl_cmd(ar->wmi, vif->fw_vif_idx);
3060 }
3061 
3062 static int ath6kl_send_go_probe_resp(struct ath6kl_vif *vif,
3063                      const u8 *buf, size_t len,
3064                      unsigned int freq)
3065 {
3066     struct ath6kl *ar = vif->ar;
3067     const u8 *pos;
3068     u8 *p2p;
3069     int p2p_len;
3070     int ret;
3071     const struct ieee80211_mgmt *mgmt;
3072 
3073     mgmt = (const struct ieee80211_mgmt *) buf;
3074 
3075     /* Include P2P IE(s) from the frame generated in user space. */
3076 
3077     p2p = kmalloc(len, GFP_KERNEL);
3078     if (p2p == NULL)
3079         return -ENOMEM;
3080     p2p_len = 0;
3081 
3082     pos = mgmt->u.probe_resp.variable;
3083     while (pos + 1 < buf + len) {
3084         if (pos + 2 + pos[1] > buf + len)
3085             break;
3086         if (ath6kl_is_p2p_ie(pos)) {
3087             memcpy(p2p + p2p_len, pos, 2 + pos[1]);
3088             p2p_len += 2 + pos[1];
3089         }
3090         pos += 2 + pos[1];
3091     }
3092 
3093     ret = ath6kl_wmi_send_probe_response_cmd(ar->wmi, vif->fw_vif_idx, freq,
3094                          mgmt->da, p2p, p2p_len);
3095     kfree(p2p);
3096     return ret;
3097 }
3098 
3099 static bool ath6kl_mgmt_powersave_ap(struct ath6kl_vif *vif,
3100                      u32 id,
3101                      u32 freq,
3102                      u32 wait,
3103                      const u8 *buf,
3104                      size_t len,
3105                      bool *more_data,
3106                      bool no_cck)
3107 {
3108     struct ieee80211_mgmt *mgmt;
3109     struct ath6kl_sta *conn;
3110     bool is_psq_empty = false;
3111     struct ath6kl_mgmt_buff *mgmt_buf;
3112     size_t mgmt_buf_size;
3113     struct ath6kl *ar = vif->ar;
3114 
3115     mgmt = (struct ieee80211_mgmt *) buf;
3116     if (is_multicast_ether_addr(mgmt->da))
3117         return false;
3118 
3119     conn = ath6kl_find_sta(vif, mgmt->da);
3120     if (!conn)
3121         return false;
3122 
3123     if (conn->sta_flags & STA_PS_SLEEP) {
3124         if (!(conn->sta_flags & STA_PS_POLLED)) {
3125             /* Queue the frames if the STA is sleeping */
3126             mgmt_buf_size = len + sizeof(struct ath6kl_mgmt_buff);
3127             mgmt_buf = kmalloc(mgmt_buf_size, GFP_KERNEL);
3128             if (!mgmt_buf)
3129                 return false;
3130 
3131             INIT_LIST_HEAD(&mgmt_buf->list);
3132             mgmt_buf->id = id;
3133             mgmt_buf->freq = freq;
3134             mgmt_buf->wait = wait;
3135             mgmt_buf->len = len;
3136             mgmt_buf->no_cck = no_cck;
3137             memcpy(mgmt_buf->buf, buf, len);
3138             spin_lock_bh(&conn->psq_lock);
3139             is_psq_empty = skb_queue_empty(&conn->psq) &&
3140                     (conn->mgmt_psq_len == 0);
3141             list_add_tail(&mgmt_buf->list, &conn->mgmt_psq);
3142             conn->mgmt_psq_len++;
3143             spin_unlock_bh(&conn->psq_lock);
3144 
3145             /*
3146              * If this is the first pkt getting queued
3147              * for this STA, update the PVB for this
3148              * STA.
3149              */
3150             if (is_psq_empty)
3151                 ath6kl_wmi_set_pvb_cmd(ar->wmi, vif->fw_vif_idx,
3152                                conn->aid, 1);
3153             return true;
3154         }
3155 
3156         /*
3157          * This tx is because of a PsPoll.
3158          * Determine if MoreData bit has to be set.
3159          */
3160         spin_lock_bh(&conn->psq_lock);
3161         if (!skb_queue_empty(&conn->psq) || (conn->mgmt_psq_len != 0))
3162             *more_data = true;
3163         spin_unlock_bh(&conn->psq_lock);
3164     }
3165 
3166     return false;
3167 }
3168 
3169 /* Check if SSID length is greater than DIRECT- */
3170 static bool ath6kl_is_p2p_go_ssid(const u8 *buf, size_t len)
3171 {
3172     const struct ieee80211_mgmt *mgmt;
3173     mgmt = (const struct ieee80211_mgmt *) buf;
3174 
3175     /* variable[1] contains the SSID tag length */
3176     if (buf + len >= &mgmt->u.probe_resp.variable[1] &&
3177         (mgmt->u.probe_resp.variable[1] > P2P_WILDCARD_SSID_LEN)) {
3178         return true;
3179     }
3180 
3181     return false;
3182 }
3183 
3184 static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
3185               struct cfg80211_mgmt_tx_params *params, u64 *cookie)
3186 {
3187     struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev);
3188     struct ath6kl *ar = ath6kl_priv(vif->ndev);
3189     struct ieee80211_channel *chan = params->chan;
3190     const u8 *buf = params->buf;
3191     size_t len = params->len;
3192     unsigned int wait = params->wait;
3193     bool no_cck = params->no_cck;
3194     u32 id, freq;
3195     const struct ieee80211_mgmt *mgmt;
3196     bool more_data, queued;
3197 
3198     /* default to the current channel, but use the one specified as argument
3199      * if any
3200      */
3201     freq = vif->ch_hint;
3202     if (chan)
3203         freq = chan->center_freq;
3204 
3205     /* never send freq zero to the firmware */
3206     if (WARN_ON(freq == 0))
3207         return -EINVAL;
3208 
3209     mgmt = (const struct ieee80211_mgmt *) buf;
3210     if (vif->nw_type == AP_NETWORK && test_bit(CONNECTED, &vif->flags) &&
3211         ieee80211_is_probe_resp(mgmt->frame_control) &&
3212         ath6kl_is_p2p_go_ssid(buf, len)) {
3213         /*
3214          * Send Probe Response frame in GO mode using a separate WMI
3215          * command to allow the target to fill in the generic IEs.
3216          */
3217         *cookie = 0; /* TX status not supported */
3218         return ath6kl_send_go_probe_resp(vif, buf, len, freq);
3219     }
3220 
3221     id = vif->send_action_id++;
3222     if (id == 0) {
3223         /*
3224          * 0 is a reserved value in the WMI command and shall not be
3225          * used for the command.
3226          */
3227         id = vif->send_action_id++;
3228     }
3229 
3230     *cookie = id;
3231 
3232     /* AP mode Power saving processing */
3233     if (vif->nw_type == AP_NETWORK) {
3234         queued = ath6kl_mgmt_powersave_ap(vif, id, freq, wait, buf, len,
3235                           &more_data, no_cck);
3236         if (queued)
3237             return 0;
3238     }
3239 
3240     return ath6kl_wmi_send_mgmt_cmd(ar->wmi, vif->fw_vif_idx, id, freq,
3241                     wait, buf, len, no_cck);
3242 }
3243 
3244 static int ath6kl_get_antenna(struct wiphy *wiphy,
3245                   u32 *tx_ant, u32 *rx_ant)
3246 {
3247     struct ath6kl *ar = wiphy_priv(wiphy);
3248     *tx_ant = ar->hw.tx_ant;
3249     *rx_ant = ar->hw.rx_ant;
3250     return 0;
3251 }
3252 
3253 static void ath6kl_update_mgmt_frame_registrations(struct wiphy *wiphy,
3254                            struct wireless_dev *wdev,
3255                            struct mgmt_frame_regs *upd)
3256 {
3257     struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev);
3258 
3259     /*
3260      * FIXME: send WMI_PROBE_REQ_REPORT_CMD here instead of hardcoding
3261      *    the reporting in the target all the time, this callback
3262      *    *is* allowed to sleep after all.
3263      */
3264     vif->probe_req_report =
3265         upd->interface_stypes & BIT(IEEE80211_STYPE_PROBE_REQ >> 4);
3266 }
3267 
3268 static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy,
3269             struct net_device *dev,
3270             struct cfg80211_sched_scan_request *request)
3271 {
3272     struct ath6kl *ar = ath6kl_priv(dev);
3273     struct ath6kl_vif *vif = netdev_priv(dev);
3274     u16 interval;
3275     int ret, rssi_thold;
3276     int n_match_sets = request->n_match_sets;
3277 
3278     /*
3279      * If there's a matchset w/o an SSID, then assume it's just for
3280      * the RSSI (nothing else is currently supported) and ignore it.
3281      * The device only supports a global RSSI filter that we set below.
3282      */
3283     if (n_match_sets == 1 && !request->match_sets[0].ssid.ssid_len)
3284         n_match_sets = 0;
3285 
3286     if (ar->state != ATH6KL_STATE_ON)
3287         return -EIO;
3288 
3289     if (vif->sme_state != SME_DISCONNECTED)
3290         return -EBUSY;
3291 
3292     ath6kl_cfg80211_scan_complete_event(vif, true);
3293 
3294     ret = ath6kl_set_probed_ssids(ar, vif, request->ssids,
3295                       request->n_ssids,
3296                       request->match_sets,
3297                       n_match_sets);
3298     if (ret < 0)
3299         return ret;
3300 
3301     if (!n_match_sets) {
3302         ret = ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
3303                            ALL_BSS_FILTER, 0);
3304         if (ret < 0)
3305             return ret;
3306     } else {
3307         ret = ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
3308                            MATCHED_SSID_FILTER, 0);
3309         if (ret < 0)
3310             return ret;
3311     }
3312 
3313     if (test_bit(ATH6KL_FW_CAPABILITY_RSSI_SCAN_THOLD,
3314              ar->fw_capabilities)) {
3315         if (request->min_rssi_thold <= NL80211_SCAN_RSSI_THOLD_OFF)
3316             rssi_thold = 0;
3317         else if (request->min_rssi_thold < -127)
3318             rssi_thold = -127;
3319         else
3320             rssi_thold = request->min_rssi_thold;
3321 
3322         ret = ath6kl_wmi_set_rssi_filter_cmd(ar->wmi, vif->fw_vif_idx,
3323                              rssi_thold);
3324         if (ret) {
3325             ath6kl_err("failed to set RSSI threshold for scan\n");
3326             return ret;
3327         }
3328     }
3329 
3330     /* fw uses seconds, also make sure that it's >0 */
3331     interval = max_t(u16, 1, request->scan_plans[0].interval);
3332 
3333     ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx,
3334                   interval, interval,
3335                   vif->bg_scan_period, 0, 0, 0, 3, 0, 0, 0);
3336 
3337     /* this also clears IE in fw if it's not set */
3338     ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
3339                        WMI_FRAME_PROBE_REQ,
3340                        request->ie, request->ie_len);
3341     if (ret) {
3342         ath6kl_warn("Failed to set probe request IE for scheduled scan: %d\n",
3343                 ret);
3344         return ret;
3345     }
3346 
3347     ret = ath6kl_wmi_enable_sched_scan_cmd(ar->wmi, vif->fw_vif_idx, true);
3348     if (ret)
3349         return ret;
3350 
3351     set_bit(SCHED_SCANNING, &vif->flags);
3352 
3353     return 0;
3354 }
3355 
3356 static int ath6kl_cfg80211_sscan_stop(struct wiphy *wiphy,
3357                       struct net_device *dev, u64 reqid)
3358 {
3359     struct ath6kl_vif *vif = netdev_priv(dev);
3360     bool stopped;
3361 
3362     stopped = __ath6kl_cfg80211_sscan_stop(vif);
3363 
3364     if (!stopped)
3365         return -EIO;
3366 
3367     return 0;
3368 }
3369 
3370 static int ath6kl_cfg80211_set_bitrate(struct wiphy *wiphy,
3371                        struct net_device *dev,
3372                        unsigned int link_id,
3373                        const u8 *addr,
3374                        const struct cfg80211_bitrate_mask *mask)
3375 {
3376     struct ath6kl *ar = ath6kl_priv(dev);
3377     struct ath6kl_vif *vif = netdev_priv(dev);
3378 
3379     return ath6kl_wmi_set_bitrate_mask(ar->wmi, vif->fw_vif_idx,
3380                        mask);
3381 }
3382 
3383 static int ath6kl_cfg80211_set_txe_config(struct wiphy *wiphy,
3384                       struct net_device *dev,
3385                       u32 rate, u32 pkts, u32 intvl)
3386 {
3387     struct ath6kl *ar = ath6kl_priv(dev);
3388     struct ath6kl_vif *vif = netdev_priv(dev);
3389 
3390     if (vif->nw_type != INFRA_NETWORK ||
3391         !test_bit(ATH6KL_FW_CAPABILITY_TX_ERR_NOTIFY, ar->fw_capabilities))
3392         return -EOPNOTSUPP;
3393 
3394     if (vif->sme_state != SME_CONNECTED)
3395         return -ENOTCONN;
3396 
3397     /* save this since the firmware won't report the interval */
3398     vif->txe_intvl = intvl;
3399 
3400     return ath6kl_wmi_set_txe_notify(ar->wmi, vif->fw_vif_idx,
3401                      rate, pkts, intvl);
3402 }
3403 
3404 static const struct ieee80211_txrx_stypes
3405 ath6kl_mgmt_stypes[NUM_NL80211_IFTYPES] = {
3406     [NL80211_IFTYPE_STATION] = {
3407         .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3408         BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
3409         .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3410         BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
3411     },
3412     [NL80211_IFTYPE_AP] = {
3413         .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3414         BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
3415         .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3416         BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
3417     },
3418     [NL80211_IFTYPE_P2P_CLIENT] = {
3419         .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3420         BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
3421         .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3422         BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
3423     },
3424     [NL80211_IFTYPE_P2P_GO] = {
3425         .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3426         BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
3427         .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3428         BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
3429     },
3430 };
3431 
3432 static struct cfg80211_ops ath6kl_cfg80211_ops = {
3433     .add_virtual_intf = ath6kl_cfg80211_add_iface,
3434     .del_virtual_intf = ath6kl_cfg80211_del_iface,
3435     .change_virtual_intf = ath6kl_cfg80211_change_iface,
3436     .scan = ath6kl_cfg80211_scan,
3437     .connect = ath6kl_cfg80211_connect,
3438     .disconnect = ath6kl_cfg80211_disconnect,
3439     .add_key = ath6kl_cfg80211_add_key,
3440     .get_key = ath6kl_cfg80211_get_key,
3441     .del_key = ath6kl_cfg80211_del_key,
3442     .set_default_key = ath6kl_cfg80211_set_default_key,
3443     .set_wiphy_params = ath6kl_cfg80211_set_wiphy_params,
3444     .set_tx_power = ath6kl_cfg80211_set_txpower,
3445     .get_tx_power = ath6kl_cfg80211_get_txpower,
3446     .set_power_mgmt = ath6kl_cfg80211_set_power_mgmt,
3447     .join_ibss = ath6kl_cfg80211_join_ibss,
3448     .leave_ibss = ath6kl_cfg80211_leave_ibss,
3449     .get_station = ath6kl_get_station,
3450     .set_pmksa = ath6kl_set_pmksa,
3451     .del_pmksa = ath6kl_del_pmksa,
3452     .flush_pmksa = ath6kl_flush_pmksa,
3453     CFG80211_TESTMODE_CMD(ath6kl_tm_cmd)
3454 #ifdef CONFIG_PM
3455     .suspend = __ath6kl_cfg80211_suspend,
3456     .resume = __ath6kl_cfg80211_resume,
3457 #endif
3458     .start_ap = ath6kl_start_ap,
3459     .change_beacon = ath6kl_change_beacon,
3460     .stop_ap = ath6kl_stop_ap,
3461     .del_station = ath6kl_del_station,
3462     .change_station = ath6kl_change_station,
3463     .remain_on_channel = ath6kl_remain_on_channel,
3464     .cancel_remain_on_channel = ath6kl_cancel_remain_on_channel,
3465     .mgmt_tx = ath6kl_mgmt_tx,
3466     .update_mgmt_frame_registrations =
3467         ath6kl_update_mgmt_frame_registrations,
3468     .get_antenna = ath6kl_get_antenna,
3469     .sched_scan_start = ath6kl_cfg80211_sscan_start,
3470     .sched_scan_stop = ath6kl_cfg80211_sscan_stop,
3471     .set_bitrate_mask = ath6kl_cfg80211_set_bitrate,
3472     .set_cqm_txe_config = ath6kl_cfg80211_set_txe_config,
3473 };
3474 
3475 void ath6kl_cfg80211_stop(struct ath6kl_vif *vif)
3476 {
3477     ath6kl_cfg80211_sscan_disable(vif);
3478 
3479     switch (vif->sme_state) {
3480     case SME_DISCONNECTED:
3481         break;
3482     case SME_CONNECTING:
3483         cfg80211_connect_result(vif->ndev, vif->bssid, NULL, 0,
3484                     NULL, 0,
3485                     WLAN_STATUS_UNSPECIFIED_FAILURE,
3486                     GFP_KERNEL);
3487         break;
3488     case SME_CONNECTED:
3489         cfg80211_disconnected(vif->ndev, 0, NULL, 0, true, GFP_KERNEL);
3490         break;
3491     }
3492 
3493     if (vif->ar->state != ATH6KL_STATE_RECOVERY &&
3494         (test_bit(CONNECTED, &vif->flags) ||
3495         test_bit(CONNECT_PEND, &vif->flags)))
3496         ath6kl_wmi_disconnect_cmd(vif->ar->wmi, vif->fw_vif_idx);
3497 
3498     vif->sme_state = SME_DISCONNECTED;
3499     clear_bit(CONNECTED, &vif->flags);
3500     clear_bit(CONNECT_PEND, &vif->flags);
3501 
3502     /* Stop netdev queues, needed during recovery */
3503     netif_stop_queue(vif->ndev);
3504     netif_carrier_off(vif->ndev);
3505 
3506     /* disable scanning */
3507     if (vif->ar->state != ATH6KL_STATE_RECOVERY &&
3508         ath6kl_wmi_scanparams_cmd(vif->ar->wmi, vif->fw_vif_idx, 0xFFFF,
3509                       0, 0, 0, 0, 0, 0, 0, 0, 0) != 0)
3510         ath6kl_warn("failed to disable scan during stop\n");
3511 
3512     ath6kl_cfg80211_scan_complete_event(vif, true);
3513 }
3514 
3515 void ath6kl_cfg80211_stop_all(struct ath6kl *ar)
3516 {
3517     struct ath6kl_vif *vif;
3518 
3519     vif = ath6kl_vif_first(ar);
3520     if (!vif && ar->state != ATH6KL_STATE_RECOVERY) {
3521         /* save the current power mode before enabling power save */
3522         ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode;
3523 
3524         if (ath6kl_wmi_powermode_cmd(ar->wmi, 0, REC_POWER) != 0)
3525             ath6kl_warn("ath6kl_deep_sleep_enable: wmi_powermode_cmd failed\n");
3526         return;
3527     }
3528 
3529     /*
3530      * FIXME: we should take ar->list_lock to protect changes in the
3531      * vif_list, but that's not trivial to do as ath6kl_cfg80211_stop()
3532      * sleeps.
3533      */
3534     list_for_each_entry(vif, &ar->vif_list, list)
3535         ath6kl_cfg80211_stop(vif);
3536 }
3537 
3538 static void ath6kl_cfg80211_reg_notify(struct wiphy *wiphy,
3539                        struct regulatory_request *request)
3540 {
3541     struct ath6kl *ar = wiphy_priv(wiphy);
3542     u32 rates[NUM_NL80211_BANDS];
3543     int ret, i;
3544 
3545     ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
3546            "cfg reg_notify %c%c%s%s initiator %d hint_type %d\n",
3547            request->alpha2[0], request->alpha2[1],
3548            request->intersect ? " intersect" : "",
3549            request->processed ? " processed" : "",
3550            request->initiator, request->user_reg_hint_type);
3551 
3552     if (request->user_reg_hint_type != NL80211_USER_REG_HINT_CELL_BASE)
3553         return;
3554 
3555     ret = ath6kl_wmi_set_regdomain_cmd(ar->wmi, request->alpha2);
3556     if (ret) {
3557         ath6kl_err("failed to set regdomain: %d\n", ret);
3558         return;
3559     }
3560 
3561     /*
3562      * Firmware will apply the regdomain change only after a scan is
3563      * issued and it will send a WMI_REGDOMAIN_EVENTID when it has been
3564      * changed.
3565      */
3566 
3567     for (i = 0; i < NUM_NL80211_BANDS; i++)
3568         if (wiphy->bands[i])
3569             rates[i] = (1 << wiphy->bands[i]->n_bitrates) - 1;
3570 
3571 
3572     ret = ath6kl_wmi_beginscan_cmd(ar->wmi, 0, WMI_LONG_SCAN, false,
3573                        false, 0, ATH6KL_FG_SCAN_INTERVAL,
3574                        0, NULL, false, rates);
3575     if (ret) {
3576         ath6kl_err("failed to start scan for a regdomain change: %d\n",
3577                ret);
3578         return;
3579     }
3580 }
3581 
3582 static int ath6kl_cfg80211_vif_init(struct ath6kl_vif *vif)
3583 {
3584     vif->aggr_cntxt = aggr_init(vif);
3585     if (!vif->aggr_cntxt) {
3586         ath6kl_err("failed to initialize aggr\n");
3587         return -ENOMEM;
3588     }
3589 
3590     timer_setup(&vif->disconnect_timer, disconnect_timer_handler, 0);
3591     timer_setup(&vif->sched_scan_timer, ath6kl_wmi_sscan_timer, 0);
3592 
3593     set_bit(WMM_ENABLED, &vif->flags);
3594     spin_lock_init(&vif->if_lock);
3595 
3596     INIT_LIST_HEAD(&vif->mc_filter);
3597 
3598     return 0;
3599 }
3600 
3601 void ath6kl_cfg80211_vif_stop(struct ath6kl_vif *vif, bool wmi_ready)
3602 {
3603     static u8 bcast_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
3604     bool discon_issued;
3605 
3606     netif_stop_queue(vif->ndev);
3607 
3608     clear_bit(WLAN_ENABLED, &vif->flags);
3609 
3610     if (wmi_ready) {
3611         discon_issued = test_bit(CONNECTED, &vif->flags) ||
3612                 test_bit(CONNECT_PEND, &vif->flags);
3613         ath6kl_disconnect(vif);
3614         del_timer(&vif->disconnect_timer);
3615 
3616         if (discon_issued)
3617             ath6kl_disconnect_event(vif, DISCONNECT_CMD,
3618                         (vif->nw_type & AP_NETWORK) ?
3619                         bcast_mac : vif->bssid,
3620                         0, NULL, 0);
3621     }
3622 
3623     if (vif->scan_req) {
3624         struct cfg80211_scan_info info = {
3625             .aborted = true,
3626         };
3627 
3628         cfg80211_scan_done(vif->scan_req, &info);
3629         vif->scan_req = NULL;
3630     }
3631 
3632     /* need to clean up enhanced bmiss detection fw state */
3633     ath6kl_cfg80211_sta_bmiss_enhance(vif, false);
3634 }
3635 
3636 void ath6kl_cfg80211_vif_cleanup(struct ath6kl_vif *vif)
3637 {
3638     struct ath6kl *ar = vif->ar;
3639     struct ath6kl_mc_filter *mc_filter, *tmp;
3640 
3641     aggr_module_destroy(vif->aggr_cntxt);
3642 
3643     ar->avail_idx_map |= BIT(vif->fw_vif_idx);
3644 
3645     if (vif->nw_type == ADHOC_NETWORK)
3646         ar->ibss_if_active = false;
3647 
3648     list_for_each_entry_safe(mc_filter, tmp, &vif->mc_filter, list) {
3649         list_del(&mc_filter->list);
3650         kfree(mc_filter);
3651     }
3652 
3653     cfg80211_unregister_netdevice(vif->ndev);
3654 
3655     ar->num_vif--;
3656 }
3657 
3658 static const char ath6kl_gstrings_sta_stats[][ETH_GSTRING_LEN] = {
3659     /* Common stats names used by many drivers. */
3660     "tx_pkts_nic", "tx_bytes_nic", "rx_pkts_nic", "rx_bytes_nic",
3661 
3662     /* TX stats. */
3663     "d_tx_ucast_pkts", "d_tx_bcast_pkts",
3664     "d_tx_ucast_bytes", "d_tx_bcast_bytes",
3665     "d_tx_rts_ok", "d_tx_error", "d_tx_fail",
3666     "d_tx_retry", "d_tx_multi_retry", "d_tx_rts_fail",
3667     "d_tx_tkip_counter_measures",
3668 
3669     /* RX Stats. */
3670     "d_rx_ucast_pkts", "d_rx_ucast_rate", "d_rx_bcast_pkts",
3671     "d_rx_ucast_bytes", "d_rx_bcast_bytes", "d_rx_frag_pkt",
3672     "d_rx_error", "d_rx_crc_err", "d_rx_keycache_miss",
3673     "d_rx_decrypt_crc_err", "d_rx_duplicate_frames",
3674     "d_rx_mic_err", "d_rx_tkip_format_err", "d_rx_ccmp_format_err",
3675     "d_rx_ccmp_replay_err",
3676 
3677     /* Misc stats. */
3678     "d_beacon_miss", "d_num_connects", "d_num_disconnects",
3679     "d_beacon_avg_rssi", "d_arp_received", "d_arp_matched",
3680     "d_arp_replied"
3681 };
3682 
3683 #define ATH6KL_STATS_LEN    ARRAY_SIZE(ath6kl_gstrings_sta_stats)
3684 
3685 static int ath6kl_get_sset_count(struct net_device *dev, int sset)
3686 {
3687     int rv = 0;
3688 
3689     if (sset == ETH_SS_STATS)
3690         rv += ATH6KL_STATS_LEN;
3691 
3692     if (rv == 0)
3693         return -EOPNOTSUPP;
3694     return rv;
3695 }
3696 
3697 static void ath6kl_get_stats(struct net_device *dev,
3698                 struct ethtool_stats *stats,
3699                 u64 *data)
3700 {
3701     struct ath6kl_vif *vif = netdev_priv(dev);
3702     struct ath6kl *ar = vif->ar;
3703     int i = 0;
3704     struct target_stats *tgt_stats;
3705 
3706     memset(data, 0, sizeof(u64) * ATH6KL_STATS_LEN);
3707 
3708     ath6kl_read_tgt_stats(ar, vif);
3709 
3710     tgt_stats = &vif->target_stats;
3711 
3712     data[i++] = tgt_stats->tx_ucast_pkt + tgt_stats->tx_bcast_pkt;
3713     data[i++] = tgt_stats->tx_ucast_byte + tgt_stats->tx_bcast_byte;
3714     data[i++] = tgt_stats->rx_ucast_pkt + tgt_stats->rx_bcast_pkt;
3715     data[i++] = tgt_stats->rx_ucast_byte + tgt_stats->rx_bcast_byte;
3716 
3717     data[i++] = tgt_stats->tx_ucast_pkt;
3718     data[i++] = tgt_stats->tx_bcast_pkt;
3719     data[i++] = tgt_stats->tx_ucast_byte;
3720     data[i++] = tgt_stats->tx_bcast_byte;
3721     data[i++] = tgt_stats->tx_rts_success_cnt;
3722     data[i++] = tgt_stats->tx_err;
3723     data[i++] = tgt_stats->tx_fail_cnt;
3724     data[i++] = tgt_stats->tx_retry_cnt;
3725     data[i++] = tgt_stats->tx_mult_retry_cnt;
3726     data[i++] = tgt_stats->tx_rts_fail_cnt;
3727     data[i++] = tgt_stats->tkip_cnter_measures_invoked;
3728 
3729     data[i++] = tgt_stats->rx_ucast_pkt;
3730     data[i++] = tgt_stats->rx_ucast_rate;
3731     data[i++] = tgt_stats->rx_bcast_pkt;
3732     data[i++] = tgt_stats->rx_ucast_byte;
3733     data[i++] = tgt_stats->rx_bcast_byte;
3734     data[i++] = tgt_stats->rx_frgment_pkt;
3735     data[i++] = tgt_stats->rx_err;
3736     data[i++] = tgt_stats->rx_crc_err;
3737     data[i++] = tgt_stats->rx_key_cache_miss;
3738     data[i++] = tgt_stats->rx_decrypt_err;
3739     data[i++] = tgt_stats->rx_dupl_frame;
3740     data[i++] = tgt_stats->tkip_local_mic_fail;
3741     data[i++] = tgt_stats->tkip_fmt_err;
3742     data[i++] = tgt_stats->ccmp_fmt_err;
3743     data[i++] = tgt_stats->ccmp_replays;
3744 
3745     data[i++] = tgt_stats->cs_bmiss_cnt;
3746     data[i++] = tgt_stats->cs_connect_cnt;
3747     data[i++] = tgt_stats->cs_discon_cnt;
3748     data[i++] = tgt_stats->cs_ave_beacon_rssi;
3749     data[i++] = tgt_stats->arp_received;
3750     data[i++] = tgt_stats->arp_matched;
3751     data[i++] = tgt_stats->arp_replied;
3752 
3753     if (i !=  ATH6KL_STATS_LEN) {
3754         WARN_ON_ONCE(1);
3755         ath6kl_err("ethtool stats error, i: %d  STATS_LEN: %d\n",
3756                i, (int)ATH6KL_STATS_LEN);
3757     }
3758 }
3759 
3760 /* These stats are per NIC, not really per vdev, so we just ignore dev. */
3761 static void ath6kl_get_strings(struct net_device *dev, u32 sset, u8 *data)
3762 {
3763     int sz_sta_stats = 0;
3764 
3765     if (sset == ETH_SS_STATS) {
3766         sz_sta_stats = sizeof(ath6kl_gstrings_sta_stats);
3767         memcpy(data, ath6kl_gstrings_sta_stats, sz_sta_stats);
3768     }
3769 }
3770 
3771 static const struct ethtool_ops ath6kl_ethtool_ops = {
3772     .get_drvinfo = cfg80211_get_drvinfo,
3773     .get_link = ethtool_op_get_link,
3774     .get_strings = ath6kl_get_strings,
3775     .get_ethtool_stats = ath6kl_get_stats,
3776     .get_sset_count = ath6kl_get_sset_count,
3777 };
3778 
3779 struct wireless_dev *ath6kl_interface_add(struct ath6kl *ar, const char *name,
3780                       unsigned char name_assign_type,
3781                       enum nl80211_iftype type,
3782                       u8 fw_vif_idx, u8 nw_type)
3783 {
3784     struct net_device *ndev;
3785     struct ath6kl_vif *vif;
3786     u8 addr[ETH_ALEN];
3787 
3788     ndev = alloc_netdev(sizeof(*vif), name, name_assign_type, ether_setup);
3789     if (!ndev)
3790         return NULL;
3791 
3792     vif = netdev_priv(ndev);
3793     ndev->ieee80211_ptr = &vif->wdev;
3794     vif->wdev.wiphy = ar->wiphy;
3795     vif->ar = ar;
3796     vif->ndev = ndev;
3797     SET_NETDEV_DEV(ndev, wiphy_dev(vif->wdev.wiphy));
3798     vif->wdev.netdev = ndev;
3799     vif->wdev.iftype = type;
3800     vif->fw_vif_idx = fw_vif_idx;
3801     vif->nw_type = nw_type;
3802     vif->next_mode = nw_type;
3803     vif->listen_intvl_t = ATH6KL_DEFAULT_LISTEN_INTVAL;
3804     vif->bmiss_time_t = ATH6KL_DEFAULT_BMISS_TIME;
3805     vif->bg_scan_period = 0;
3806     vif->htcap[NL80211_BAND_2GHZ].ht_enable = true;
3807     vif->htcap[NL80211_BAND_5GHZ].ht_enable = true;
3808 
3809     ether_addr_copy(addr, ar->mac_addr);
3810     if (fw_vif_idx != 0) {
3811         addr[0] = (addr[0] ^ (1 << fw_vif_idx)) | 0x2;
3812         if (test_bit(ATH6KL_FW_CAPABILITY_CUSTOM_MAC_ADDR,
3813                  ar->fw_capabilities))
3814             addr[4] ^= 0x80;
3815     }
3816     eth_hw_addr_set(ndev, addr);
3817 
3818     init_netdev(ndev);
3819 
3820     ath6kl_init_control_info(vif);
3821 
3822     if (ath6kl_cfg80211_vif_init(vif))
3823         goto err;
3824 
3825     netdev_set_default_ethtool_ops(ndev, &ath6kl_ethtool_ops);
3826 
3827     if (cfg80211_register_netdevice(ndev))
3828         goto err;
3829 
3830     ar->avail_idx_map &= ~BIT(fw_vif_idx);
3831     vif->sme_state = SME_DISCONNECTED;
3832     set_bit(WLAN_ENABLED, &vif->flags);
3833     ar->wlan_pwr_state = WLAN_POWER_STATE_ON;
3834 
3835     if (type == NL80211_IFTYPE_ADHOC)
3836         ar->ibss_if_active = true;
3837 
3838     spin_lock_bh(&ar->list_lock);
3839     list_add_tail(&vif->list, &ar->vif_list);
3840     spin_unlock_bh(&ar->list_lock);
3841 
3842     return &vif->wdev;
3843 
3844 err:
3845     aggr_module_destroy(vif->aggr_cntxt);
3846     free_netdev(ndev);
3847     return NULL;
3848 }
3849 
3850 #ifdef CONFIG_PM
3851 static const struct wiphy_wowlan_support ath6kl_wowlan_support = {
3852     .flags = WIPHY_WOWLAN_MAGIC_PKT |
3853          WIPHY_WOWLAN_DISCONNECT |
3854          WIPHY_WOWLAN_GTK_REKEY_FAILURE  |
3855          WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
3856          WIPHY_WOWLAN_EAP_IDENTITY_REQ   |
3857          WIPHY_WOWLAN_4WAY_HANDSHAKE,
3858     .n_patterns = WOW_MAX_FILTERS_PER_LIST,
3859     .pattern_min_len = 1,
3860     .pattern_max_len = WOW_PATTERN_SIZE,
3861 };
3862 #endif
3863 
3864 int ath6kl_cfg80211_init(struct ath6kl *ar)
3865 {
3866     struct wiphy *wiphy = ar->wiphy;
3867     bool band_2gig = false, band_5gig = false, ht = false;
3868     int ret;
3869 
3870     wiphy->mgmt_stypes = ath6kl_mgmt_stypes;
3871 
3872     wiphy->max_remain_on_channel_duration = 5000;
3873 
3874     /* set device pointer for wiphy */
3875     set_wiphy_dev(wiphy, ar->dev);
3876 
3877     wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
3878                  BIT(NL80211_IFTYPE_ADHOC) |
3879                  BIT(NL80211_IFTYPE_AP);
3880     if (ar->p2p) {
3881         wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_GO) |
3882                       BIT(NL80211_IFTYPE_P2P_CLIENT);
3883     }
3884 
3885     if (IS_ENABLED(CONFIG_ATH6KL_REGDOMAIN) &&
3886         test_bit(ATH6KL_FW_CAPABILITY_REGDOMAIN, ar->fw_capabilities)) {
3887         wiphy->reg_notifier = ath6kl_cfg80211_reg_notify;
3888         ar->wiphy->features |= NL80211_FEATURE_CELL_BASE_REG_HINTS;
3889     }
3890 
3891     /* max num of ssids that can be probed during scanning */
3892     wiphy->max_scan_ssids = MAX_PROBED_SSIDS;
3893 
3894     /* max num of ssids that can be matched after scan */
3895     if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN_MATCH_LIST,
3896              ar->fw_capabilities))
3897         wiphy->max_match_sets = MAX_PROBED_SSIDS;
3898 
3899     wiphy->max_scan_ie_len = 1000; /* FIX: what is correct limit? */
3900     switch (ar->hw.cap) {
3901     case WMI_11AN_CAP:
3902         ht = true;
3903         fallthrough;
3904     case WMI_11A_CAP:
3905         band_5gig = true;
3906         break;
3907     case WMI_11GN_CAP:
3908         ht = true;
3909         fallthrough;
3910     case WMI_11G_CAP:
3911         band_2gig = true;
3912         break;
3913     case WMI_11AGN_CAP:
3914         ht = true;
3915         fallthrough;
3916     case WMI_11AG_CAP:
3917         band_2gig = true;
3918         band_5gig = true;
3919         break;
3920     default:
3921         ath6kl_err("invalid phy capability!\n");
3922         return -EINVAL;
3923     }
3924 
3925     /*
3926      * Even if the fw has HT support, advertise HT cap only when
3927      * the firmware has support to override RSN capability, otherwise
3928      * 4-way handshake would fail.
3929      */
3930     if (!(ht &&
3931           test_bit(ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE,
3932                ar->fw_capabilities))) {
3933         ath6kl_band_2ghz.ht_cap.cap = 0;
3934         ath6kl_band_2ghz.ht_cap.ht_supported = false;
3935         ath6kl_band_5ghz.ht_cap.cap = 0;
3936         ath6kl_band_5ghz.ht_cap.ht_supported = false;
3937 
3938         if (ht)
3939             ath6kl_err("Firmware lacks RSN-CAP-OVERRIDE, so HT (802.11n) is disabled.");
3940     }
3941 
3942     if (test_bit(ATH6KL_FW_CAPABILITY_64BIT_RATES,
3943              ar->fw_capabilities)) {
3944         ath6kl_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3945         ath6kl_band_5ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3946         ath6kl_band_2ghz.ht_cap.mcs.rx_mask[1] = 0xff;
3947         ath6kl_band_5ghz.ht_cap.mcs.rx_mask[1] = 0xff;
3948         ar->hw.tx_ant = 0x3; /* mask, 2 antenna */
3949         ar->hw.rx_ant = 0x3;
3950     } else {
3951         ath6kl_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3952         ath6kl_band_5ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3953         ar->hw.tx_ant = 1;
3954         ar->hw.rx_ant = 1;
3955     }
3956 
3957     wiphy->available_antennas_tx = ar->hw.tx_ant;
3958     wiphy->available_antennas_rx = ar->hw.rx_ant;
3959 
3960     if (band_2gig)
3961         wiphy->bands[NL80211_BAND_2GHZ] = &ath6kl_band_2ghz;
3962     if (band_5gig)
3963         wiphy->bands[NL80211_BAND_5GHZ] = &ath6kl_band_5ghz;
3964 
3965     wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
3966 
3967     wiphy->cipher_suites = cipher_suites;
3968     wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
3969 
3970 #ifdef CONFIG_PM
3971     wiphy->wowlan = &ath6kl_wowlan_support;
3972 #endif
3973 
3974     wiphy->max_sched_scan_ssids = MAX_PROBED_SSIDS;
3975 
3976     ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM |
3977                 WIPHY_FLAG_HAVE_AP_SME |
3978                 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
3979                 WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
3980 
3981     if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN_V2, ar->fw_capabilities))
3982         ar->wiphy->max_sched_scan_reqs = 1;
3983 
3984     if (test_bit(ATH6KL_FW_CAPABILITY_INACTIVITY_TIMEOUT,
3985              ar->fw_capabilities))
3986         ar->wiphy->features |= NL80211_FEATURE_INACTIVITY_TIMER;
3987 
3988     ar->wiphy->probe_resp_offload =
3989         NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
3990         NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
3991         NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P;
3992 
3993     ret = wiphy_register(wiphy);
3994     if (ret < 0) {
3995         ath6kl_err("couldn't register wiphy device\n");
3996         return ret;
3997     }
3998 
3999     ar->wiphy_registered = true;
4000 
4001     return 0;
4002 }
4003 
4004 void ath6kl_cfg80211_cleanup(struct ath6kl *ar)
4005 {
4006     wiphy_unregister(ar->wiphy);
4007 
4008     ar->wiphy_registered = false;
4009 }
4010 
4011 struct ath6kl *ath6kl_cfg80211_create(void)
4012 {
4013     struct ath6kl *ar;
4014     struct wiphy *wiphy;
4015 
4016     /* create a new wiphy for use with cfg80211 */
4017     wiphy = wiphy_new(&ath6kl_cfg80211_ops, sizeof(struct ath6kl));
4018 
4019     if (!wiphy) {
4020         ath6kl_err("couldn't allocate wiphy device\n");
4021         return NULL;
4022     }
4023 
4024     ar = wiphy_priv(wiphy);
4025     ar->wiphy = wiphy;
4026 
4027     return ar;
4028 }
4029 
4030 /* Note: ar variable must not be accessed after calling this! */
4031 void ath6kl_cfg80211_destroy(struct ath6kl *ar)
4032 {
4033     int i;
4034 
4035     for (i = 0; i < AP_MAX_NUM_STA; i++)
4036         kfree(ar->sta_list[i].aggr_conn);
4037 
4038     wiphy_free(ar->wiphy);
4039 }
4040