linux/drivers/net/wireless/ath/ath6kl/cfg80211.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2004-2011 Atheros Communications Inc.
   3 * Copyright (c) 2011-2012 Qualcomm Atheros, Inc.
   4 *
   5 * Permission to use, copy, modify, and/or distribute this software for any
   6 * purpose with or without fee is hereby granted, provided that the above
   7 * copyright notice and this permission notice appear in all copies.
   8 *
   9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  16 */
  17
  18#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  19
  20#include <linux/moduleparam.h>
  21#include <linux/inetdevice.h>
  22#include <linux/export.h>
  23
  24#include "core.h"
  25#include "cfg80211.h"
  26#include "debug.h"
  27#include "hif-ops.h"
  28#include "testmode.h"
  29
  30#define RATETAB_ENT(_rate, _rateid, _flags) {   \
  31        .bitrate    = (_rate),                  \
  32        .flags      = (_flags),                 \
  33        .hw_value   = (_rateid),                \
  34}
  35
  36#define CHAN2G(_channel, _freq, _flags) {   \
  37        .band           = NL80211_BAND_2GHZ,  \
  38        .hw_value       = (_channel),           \
  39        .center_freq    = (_freq),              \
  40        .flags          = (_flags),             \
  41        .max_antenna_gain   = 0,                \
  42        .max_power      = 30,                   \
  43}
  44
  45#define CHAN5G(_channel, _flags) {                  \
  46        .band           = NL80211_BAND_5GHZ,      \
  47        .hw_value       = (_channel),               \
  48        .center_freq    = 5000 + (5 * (_channel)),  \
  49        .flags          = (_flags),                 \
  50        .max_antenna_gain   = 0,                    \
  51        .max_power      = 30,                       \
  52}
  53
  54#define DEFAULT_BG_SCAN_PERIOD 60
  55
  56struct ath6kl_cfg80211_match_probe_ssid {
  57        struct cfg80211_ssid ssid;
  58        u8 flag;
  59};
  60
  61static struct ieee80211_rate ath6kl_rates[] = {
  62        RATETAB_ENT(10, 0x1, 0),
  63        RATETAB_ENT(20, 0x2, 0),
  64        RATETAB_ENT(55, 0x4, 0),
  65        RATETAB_ENT(110, 0x8, 0),
  66        RATETAB_ENT(60, 0x10, 0),
  67        RATETAB_ENT(90, 0x20, 0),
  68        RATETAB_ENT(120, 0x40, 0),
  69        RATETAB_ENT(180, 0x80, 0),
  70        RATETAB_ENT(240, 0x100, 0),
  71        RATETAB_ENT(360, 0x200, 0),
  72        RATETAB_ENT(480, 0x400, 0),
  73        RATETAB_ENT(540, 0x800, 0),
  74};
  75
  76#define ath6kl_a_rates     (ath6kl_rates + 4)
  77#define ath6kl_a_rates_size    8
  78#define ath6kl_g_rates     (ath6kl_rates + 0)
  79#define ath6kl_g_rates_size    12
  80
  81#define ath6kl_g_htcap IEEE80211_HT_CAP_SGI_20
  82#define ath6kl_a_htcap (IEEE80211_HT_CAP_SUP_WIDTH_20_40 | \
  83                        IEEE80211_HT_CAP_SGI_20          | \
  84                        IEEE80211_HT_CAP_SGI_40)
  85
  86static struct ieee80211_channel ath6kl_2ghz_channels[] = {
  87        CHAN2G(1, 2412, 0),
  88        CHAN2G(2, 2417, 0),
  89        CHAN2G(3, 2422, 0),
  90        CHAN2G(4, 2427, 0),
  91        CHAN2G(5, 2432, 0),
  92        CHAN2G(6, 2437, 0),
  93        CHAN2G(7, 2442, 0),
  94        CHAN2G(8, 2447, 0),
  95        CHAN2G(9, 2452, 0),
  96        CHAN2G(10, 2457, 0),
  97        CHAN2G(11, 2462, 0),
  98        CHAN2G(12, 2467, 0),
  99        CHAN2G(13, 2472, 0),
 100        CHAN2G(14, 2484, 0),
 101};
 102
 103static struct ieee80211_channel ath6kl_5ghz_a_channels[] = {
 104        CHAN5G(34, 0), CHAN5G(36, 0),
 105        CHAN5G(38, 0), CHAN5G(40, 0),
 106        CHAN5G(42, 0), CHAN5G(44, 0),
 107        CHAN5G(46, 0), CHAN5G(48, 0),
 108        CHAN5G(52, 0), CHAN5G(56, 0),
 109        CHAN5G(60, 0), CHAN5G(64, 0),
 110        CHAN5G(100, 0), CHAN5G(104, 0),
 111        CHAN5G(108, 0), CHAN5G(112, 0),
 112        CHAN5G(116, 0), CHAN5G(120, 0),
 113        CHAN5G(124, 0), CHAN5G(128, 0),
 114        CHAN5G(132, 0), CHAN5G(136, 0),
 115        CHAN5G(140, 0), CHAN5G(149, 0),
 116        CHAN5G(153, 0), CHAN5G(157, 0),
 117        CHAN5G(161, 0), CHAN5G(165, 0),
 118        CHAN5G(184, 0), CHAN5G(188, 0),
 119        CHAN5G(192, 0), CHAN5G(196, 0),
 120        CHAN5G(200, 0), CHAN5G(204, 0),
 121        CHAN5G(208, 0), CHAN5G(212, 0),
 122        CHAN5G(216, 0),
 123};
 124
 125static struct ieee80211_supported_band ath6kl_band_2ghz = {
 126        .n_channels = ARRAY_SIZE(ath6kl_2ghz_channels),
 127        .channels = ath6kl_2ghz_channels,
 128        .n_bitrates = ath6kl_g_rates_size,
 129        .bitrates = ath6kl_g_rates,
 130        .ht_cap.cap = ath6kl_g_htcap,
 131        .ht_cap.ht_supported = true,
 132};
 133
 134static struct ieee80211_supported_band ath6kl_band_5ghz = {
 135        .n_channels = ARRAY_SIZE(ath6kl_5ghz_a_channels),
 136        .channels = ath6kl_5ghz_a_channels,
 137        .n_bitrates = ath6kl_a_rates_size,
 138        .bitrates = ath6kl_a_rates,
 139        .ht_cap.cap = ath6kl_a_htcap,
 140        .ht_cap.ht_supported = true,
 141};
 142
 143#define CCKM_KRK_CIPHER_SUITE 0x004096ff /* use for KRK */
 144
 145/* returns true if scheduled scan was stopped */
 146static bool __ath6kl_cfg80211_sscan_stop(struct ath6kl_vif *vif)
 147{
 148        struct ath6kl *ar = vif->ar;
 149
 150        if (!test_and_clear_bit(SCHED_SCANNING, &vif->flags))
 151                return false;
 152
 153        del_timer_sync(&vif->sched_scan_timer);
 154
 155        if (ar->state == ATH6KL_STATE_RECOVERY)
 156                return true;
 157
 158        ath6kl_wmi_enable_sched_scan_cmd(ar->wmi, vif->fw_vif_idx, false);
 159
 160        return true;
 161}
 162
 163static void ath6kl_cfg80211_sscan_disable(struct ath6kl_vif *vif)
 164{
 165        struct ath6kl *ar = vif->ar;
 166        bool stopped;
 167
 168        stopped = __ath6kl_cfg80211_sscan_stop(vif);
 169
 170        if (!stopped)
 171                return;
 172
 173        cfg80211_sched_scan_stopped(ar->wiphy);
 174}
 175
 176static int ath6kl_set_wpa_version(struct ath6kl_vif *vif,
 177                                  enum nl80211_wpa_versions wpa_version)
 178{
 179        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: %u\n", __func__, wpa_version);
 180
 181        if (!wpa_version) {
 182                vif->auth_mode = NONE_AUTH;
 183        } else if (wpa_version & NL80211_WPA_VERSION_2) {
 184                vif->auth_mode = WPA2_AUTH;
 185        } else if (wpa_version & NL80211_WPA_VERSION_1) {
 186                vif->auth_mode = WPA_AUTH;
 187        } else {
 188                ath6kl_err("%s: %u not supported\n", __func__, wpa_version);
 189                return -ENOTSUPP;
 190        }
 191
 192        return 0;
 193}
 194
 195static int ath6kl_set_auth_type(struct ath6kl_vif *vif,
 196                                enum nl80211_auth_type auth_type)
 197{
 198        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: 0x%x\n", __func__, auth_type);
 199
 200        switch (auth_type) {
 201        case NL80211_AUTHTYPE_OPEN_SYSTEM:
 202                vif->dot11_auth_mode = OPEN_AUTH;
 203                break;
 204        case NL80211_AUTHTYPE_SHARED_KEY:
 205                vif->dot11_auth_mode = SHARED_AUTH;
 206                break;
 207        case NL80211_AUTHTYPE_NETWORK_EAP:
 208                vif->dot11_auth_mode = LEAP_AUTH;
 209                break;
 210
 211        case NL80211_AUTHTYPE_AUTOMATIC:
 212                vif->dot11_auth_mode = OPEN_AUTH | SHARED_AUTH;
 213                break;
 214
 215        default:
 216                ath6kl_err("%s: 0x%x not supported\n", __func__, auth_type);
 217                return -ENOTSUPP;
 218        }
 219
 220        return 0;
 221}
 222
 223static int ath6kl_set_cipher(struct ath6kl_vif *vif, u32 cipher, bool ucast)
 224{
 225        u8 *ar_cipher = ucast ? &vif->prwise_crypto : &vif->grp_crypto;
 226        u8 *ar_cipher_len = ucast ? &vif->prwise_crypto_len :
 227                &vif->grp_crypto_len;
 228
 229        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: cipher 0x%x, ucast %u\n",
 230                   __func__, cipher, ucast);
 231
 232        switch (cipher) {
 233        case 0:
 234                /* our own hack to use value 0 as no crypto used */
 235                *ar_cipher = NONE_CRYPT;
 236                *ar_cipher_len = 0;
 237                break;
 238        case WLAN_CIPHER_SUITE_WEP40:
 239                *ar_cipher = WEP_CRYPT;
 240                *ar_cipher_len = 5;
 241                break;
 242        case WLAN_CIPHER_SUITE_WEP104:
 243                *ar_cipher = WEP_CRYPT;
 244                *ar_cipher_len = 13;
 245                break;
 246        case WLAN_CIPHER_SUITE_TKIP:
 247                *ar_cipher = TKIP_CRYPT;
 248                *ar_cipher_len = 0;
 249                break;
 250        case WLAN_CIPHER_SUITE_CCMP:
 251                *ar_cipher = AES_CRYPT;
 252                *ar_cipher_len = 0;
 253                break;
 254        case WLAN_CIPHER_SUITE_SMS4:
 255                *ar_cipher = WAPI_CRYPT;
 256                *ar_cipher_len = 0;
 257                break;
 258        default:
 259                ath6kl_err("cipher 0x%x not supported\n", cipher);
 260                return -ENOTSUPP;
 261        }
 262
 263        return 0;
 264}
 265
 266static void ath6kl_set_key_mgmt(struct ath6kl_vif *vif, u32 key_mgmt)
 267{
 268        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: 0x%x\n", __func__, key_mgmt);
 269
 270        if (key_mgmt == WLAN_AKM_SUITE_PSK) {
 271                if (vif->auth_mode == WPA_AUTH)
 272                        vif->auth_mode = WPA_PSK_AUTH;
 273                else if (vif->auth_mode == WPA2_AUTH)
 274                        vif->auth_mode = WPA2_PSK_AUTH;
 275        } else if (key_mgmt == 0x00409600) {
 276                if (vif->auth_mode == WPA_AUTH)
 277                        vif->auth_mode = WPA_AUTH_CCKM;
 278                else if (vif->auth_mode == WPA2_AUTH)
 279                        vif->auth_mode = WPA2_AUTH_CCKM;
 280        } else if (key_mgmt != WLAN_AKM_SUITE_8021X) {
 281                vif->auth_mode = NONE_AUTH;
 282        }
 283}
 284
 285static bool ath6kl_cfg80211_ready(struct ath6kl_vif *vif)
 286{
 287        struct ath6kl *ar = vif->ar;
 288
 289        if (!test_bit(WMI_READY, &ar->flag)) {
 290                ath6kl_err("wmi is not ready\n");
 291                return false;
 292        }
 293
 294        if (!test_bit(WLAN_ENABLED, &vif->flags)) {
 295                ath6kl_err("wlan disabled\n");
 296                return false;
 297        }
 298
 299        return true;
 300}
 301
 302static bool ath6kl_is_wpa_ie(const u8 *pos)
 303{
 304        return pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
 305                pos[2] == 0x00 && pos[3] == 0x50 &&
 306                pos[4] == 0xf2 && pos[5] == 0x01;
 307}
 308
 309static bool ath6kl_is_rsn_ie(const u8 *pos)
 310{
 311        return pos[0] == WLAN_EID_RSN;
 312}
 313
 314static bool ath6kl_is_wps_ie(const u8 *pos)
 315{
 316        return (pos[0] == WLAN_EID_VENDOR_SPECIFIC &&
 317                pos[1] >= 4 &&
 318                pos[2] == 0x00 && pos[3] == 0x50 && pos[4] == 0xf2 &&
 319                pos[5] == 0x04);
 320}
 321
 322static int ath6kl_set_assoc_req_ies(struct ath6kl_vif *vif, const u8 *ies,
 323                                    size_t ies_len)
 324{
 325        struct ath6kl *ar = vif->ar;
 326        const u8 *pos;
 327        u8 *buf = NULL;
 328        size_t len = 0;
 329        int ret;
 330
 331        /*
 332         * Clear previously set flag
 333         */
 334
 335        ar->connect_ctrl_flags &= ~CONNECT_WPS_FLAG;
 336
 337        /*
 338         * Filter out RSN/WPA IE(s)
 339         */
 340
 341        if (ies && ies_len) {
 342                buf = kmalloc(ies_len, GFP_KERNEL);
 343                if (buf == NULL)
 344                        return -ENOMEM;
 345                pos = ies;
 346
 347                while (pos + 1 < ies + ies_len) {
 348                        if (pos + 2 + pos[1] > ies + ies_len)
 349                                break;
 350                        if (!(ath6kl_is_wpa_ie(pos) || ath6kl_is_rsn_ie(pos))) {
 351                                memcpy(buf + len, pos, 2 + pos[1]);
 352                                len += 2 + pos[1];
 353                        }
 354
 355                        if (ath6kl_is_wps_ie(pos))
 356                                ar->connect_ctrl_flags |= CONNECT_WPS_FLAG;
 357
 358                        pos += 2 + pos[1];
 359                }
 360        }
 361
 362        ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
 363                                       WMI_FRAME_ASSOC_REQ, buf, len);
 364        kfree(buf);
 365        return ret;
 366}
 367
 368static int ath6kl_nliftype_to_drv_iftype(enum nl80211_iftype type, u8 *nw_type)
 369{
 370        switch (type) {
 371        case NL80211_IFTYPE_STATION:
 372        case NL80211_IFTYPE_P2P_CLIENT:
 373                *nw_type = INFRA_NETWORK;
 374                break;
 375        case NL80211_IFTYPE_ADHOC:
 376                *nw_type = ADHOC_NETWORK;
 377                break;
 378        case NL80211_IFTYPE_AP:
 379        case NL80211_IFTYPE_P2P_GO:
 380                *nw_type = AP_NETWORK;
 381                break;
 382        default:
 383                ath6kl_err("invalid interface type %u\n", type);
 384                return -ENOTSUPP;
 385        }
 386
 387        return 0;
 388}
 389
 390static bool ath6kl_is_valid_iftype(struct ath6kl *ar, enum nl80211_iftype type,
 391                                   u8 *if_idx, u8 *nw_type)
 392{
 393        int i;
 394
 395        if (ath6kl_nliftype_to_drv_iftype(type, nw_type))
 396                return false;
 397
 398        if (ar->ibss_if_active || ((type == NL80211_IFTYPE_ADHOC) &&
 399                                   ar->num_vif))
 400                return false;
 401
 402        if (type == NL80211_IFTYPE_STATION ||
 403            type == NL80211_IFTYPE_AP || type == NL80211_IFTYPE_ADHOC) {
 404                for (i = 0; i < ar->vif_max; i++) {
 405                        if ((ar->avail_idx_map) & BIT(i)) {
 406                                *if_idx = i;
 407                                return true;
 408                        }
 409                }
 410        }
 411
 412        if (type == NL80211_IFTYPE_P2P_CLIENT ||
 413            type == NL80211_IFTYPE_P2P_GO) {
 414                for (i = ar->max_norm_iface; i < ar->vif_max; i++) {
 415                        if ((ar->avail_idx_map) & BIT(i)) {
 416                                *if_idx = i;
 417                                return true;
 418                        }
 419                }
 420        }
 421
 422        return false;
 423}
 424
 425static bool ath6kl_is_tx_pending(struct ath6kl *ar)
 426{
 427        return ar->tx_pending[ath6kl_wmi_get_control_ep(ar->wmi)] == 0;
 428}
 429
 430static void ath6kl_cfg80211_sta_bmiss_enhance(struct ath6kl_vif *vif,
 431                                              bool enable)
 432{
 433        int err;
 434
 435        if (WARN_ON(!test_bit(WMI_READY, &vif->ar->flag)))
 436                return;
 437
 438        if (vif->nw_type != INFRA_NETWORK)
 439                return;
 440
 441        if (!test_bit(ATH6KL_FW_CAPABILITY_BMISS_ENHANCE,
 442                      vif->ar->fw_capabilities))
 443                return;
 444
 445        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s fw bmiss enhance\n",
 446                   enable ? "enable" : "disable");
 447
 448        err = ath6kl_wmi_sta_bmiss_enhance_cmd(vif->ar->wmi,
 449                                               vif->fw_vif_idx, enable);
 450        if (err)
 451                ath6kl_err("failed to %s enhanced bmiss detection: %d\n",
 452                           enable ? "enable" : "disable", err);
 453}
 454
 455static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
 456                                   struct cfg80211_connect_params *sme)
 457{
 458        struct ath6kl *ar = ath6kl_priv(dev);
 459        struct ath6kl_vif *vif = netdev_priv(dev);
 460        int status;
 461        u8 nw_subtype = (ar->p2p) ? SUBTYPE_P2PDEV : SUBTYPE_NONE;
 462        u16 interval;
 463
 464        ath6kl_cfg80211_sscan_disable(vif);
 465
 466        vif->sme_state = SME_CONNECTING;
 467
 468        if (!ath6kl_cfg80211_ready(vif))
 469                return -EIO;
 470
 471        if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
 472                ath6kl_err("destroy in progress\n");
 473                return -EBUSY;
 474        }
 475
 476        if (test_bit(SKIP_SCAN, &ar->flag) &&
 477            ((sme->channel && sme->channel->center_freq == 0) ||
 478             (sme->bssid && is_zero_ether_addr(sme->bssid)))) {
 479                ath6kl_err("SkipScan: channel or bssid invalid\n");
 480                return -EINVAL;
 481        }
 482
 483        if (down_interruptible(&ar->sem)) {
 484                ath6kl_err("busy, couldn't get access\n");
 485                return -ERESTARTSYS;
 486        }
 487
 488        if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
 489                ath6kl_err("busy, destroy in progress\n");
 490                up(&ar->sem);
 491                return -EBUSY;
 492        }
 493
 494        if (ar->tx_pending[ath6kl_wmi_get_control_ep(ar->wmi)]) {
 495                /*
 496                 * sleep until the command queue drains
 497                 */
 498                wait_event_interruptible_timeout(ar->event_wq,
 499                                                 ath6kl_is_tx_pending(ar),
 500                                                 WMI_TIMEOUT);
 501                if (signal_pending(current)) {
 502                        ath6kl_err("cmd queue drain timeout\n");
 503                        up(&ar->sem);
 504                        return -EINTR;
 505                }
 506        }
 507
 508        status = ath6kl_set_assoc_req_ies(vif, sme->ie, sme->ie_len);
 509        if (status) {
 510                up(&ar->sem);
 511                return status;
 512        }
 513
 514        if (sme->ie == NULL || sme->ie_len == 0)
 515                ar->connect_ctrl_flags &= ~CONNECT_WPS_FLAG;
 516
 517        if (test_bit(CONNECTED, &vif->flags) &&
 518            vif->ssid_len == sme->ssid_len &&
 519            !memcmp(vif->ssid, sme->ssid, vif->ssid_len)) {
 520                vif->reconnect_flag = true;
 521                status = ath6kl_wmi_reconnect_cmd(ar->wmi, vif->fw_vif_idx,
 522                                                  vif->req_bssid,
 523                                                  vif->ch_hint);
 524
 525                up(&ar->sem);
 526                if (status) {
 527                        ath6kl_err("wmi_reconnect_cmd failed\n");
 528                        return -EIO;
 529                }
 530                return 0;
 531        } else if (vif->ssid_len == sme->ssid_len &&
 532                   !memcmp(vif->ssid, sme->ssid, vif->ssid_len)) {
 533                ath6kl_disconnect(vif);
 534        }
 535
 536        memset(vif->ssid, 0, sizeof(vif->ssid));
 537        vif->ssid_len = sme->ssid_len;
 538        memcpy(vif->ssid, sme->ssid, sme->ssid_len);
 539
 540        if (sme->channel)
 541                vif->ch_hint = sme->channel->center_freq;
 542
 543        memset(vif->req_bssid, 0, sizeof(vif->req_bssid));
 544        if (sme->bssid && !is_broadcast_ether_addr(sme->bssid))
 545                memcpy(vif->req_bssid, sme->bssid, sizeof(vif->req_bssid));
 546
 547        ath6kl_set_wpa_version(vif, sme->crypto.wpa_versions);
 548
 549        status = ath6kl_set_auth_type(vif, sme->auth_type);
 550        if (status) {
 551                up(&ar->sem);
 552                return status;
 553        }
 554
 555        if (sme->crypto.n_ciphers_pairwise)
 556                ath6kl_set_cipher(vif, sme->crypto.ciphers_pairwise[0], true);
 557        else
 558                ath6kl_set_cipher(vif, 0, true);
 559
 560        ath6kl_set_cipher(vif, sme->crypto.cipher_group, false);
 561
 562        if (sme->crypto.n_akm_suites)
 563                ath6kl_set_key_mgmt(vif, sme->crypto.akm_suites[0]);
 564
 565        if ((sme->key_len) &&
 566            (vif->auth_mode == NONE_AUTH) &&
 567            (vif->prwise_crypto == WEP_CRYPT)) {
 568                struct ath6kl_key *key = NULL;
 569
 570                if (sme->key_idx > WMI_MAX_KEY_INDEX) {
 571                        ath6kl_err("key index %d out of bounds\n",
 572                                   sme->key_idx);
 573                        up(&ar->sem);
 574                        return -ENOENT;
 575                }
 576
 577                key = &vif->keys[sme->key_idx];
 578                key->key_len = sme->key_len;
 579                memcpy(key->key, sme->key, key->key_len);
 580                key->cipher = vif->prwise_crypto;
 581                vif->def_txkey_index = sme->key_idx;
 582
 583                ath6kl_wmi_addkey_cmd(ar->wmi, vif->fw_vif_idx, sme->key_idx,
 584                                      vif->prwise_crypto,
 585                                      GROUP_USAGE | TX_USAGE,
 586                                      key->key_len,
 587                                      NULL, 0,
 588                                      key->key, KEY_OP_INIT_VAL, NULL,
 589                                      NO_SYNC_WMIFLAG);
 590        }
 591
 592        if (!ar->usr_bss_filter) {
 593                clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags);
 594                if (ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
 595                                             ALL_BSS_FILTER, 0) != 0) {
 596                        ath6kl_err("couldn't set bss filtering\n");
 597                        up(&ar->sem);
 598                        return -EIO;
 599                }
 600        }
 601
 602        vif->nw_type = vif->next_mode;
 603
 604        /* enable enhanced bmiss detection if applicable */
 605        ath6kl_cfg80211_sta_bmiss_enhance(vif, true);
 606
 607        if (vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT)
 608                nw_subtype = SUBTYPE_P2PCLIENT;
 609
 610        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
 611                   "%s: connect called with authmode %d dot11 auth %d"
 612                   " PW crypto %d PW crypto len %d GRP crypto %d"
 613                   " GRP crypto len %d channel hint %u\n",
 614                   __func__,
 615                   vif->auth_mode, vif->dot11_auth_mode, vif->prwise_crypto,
 616                   vif->prwise_crypto_len, vif->grp_crypto,
 617                   vif->grp_crypto_len, vif->ch_hint);
 618
 619        vif->reconnect_flag = 0;
 620
 621        if (vif->nw_type == INFRA_NETWORK) {
 622                interval = max_t(u16, vif->listen_intvl_t,
 623                                 ATH6KL_MAX_WOW_LISTEN_INTL);
 624                status = ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx,
 625                                                       interval,
 626                                                       0);
 627                if (status) {
 628                        ath6kl_err("couldn't set listen intervel\n");
 629                        up(&ar->sem);
 630                        return status;
 631                }
 632        }
 633
 634        status = ath6kl_wmi_connect_cmd(ar->wmi, vif->fw_vif_idx, vif->nw_type,
 635                                        vif->dot11_auth_mode, vif->auth_mode,
 636                                        vif->prwise_crypto,
 637                                        vif->prwise_crypto_len,
 638                                        vif->grp_crypto, vif->grp_crypto_len,
 639                                        vif->ssid_len, vif->ssid,
 640                                        vif->req_bssid, vif->ch_hint,
 641                                        ar->connect_ctrl_flags, nw_subtype);
 642
 643        if (sme->bg_scan_period == 0) {
 644                /* disable background scan if period is 0 */
 645                sme->bg_scan_period = 0xffff;
 646        } else if (sme->bg_scan_period == -1) {
 647                /* configure default value if not specified */
 648                sme->bg_scan_period = DEFAULT_BG_SCAN_PERIOD;
 649        }
 650
 651        ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx, 0, 0,
 652                                  sme->bg_scan_period, 0, 0, 0, 3, 0, 0, 0);
 653
 654        up(&ar->sem);
 655
 656        if (status == -EINVAL) {
 657                memset(vif->ssid, 0, sizeof(vif->ssid));
 658                vif->ssid_len = 0;
 659                ath6kl_err("invalid request\n");
 660                return -ENOENT;
 661        } else if (status) {
 662                ath6kl_err("ath6kl_wmi_connect_cmd failed\n");
 663                return -EIO;
 664        }
 665
 666        if ((!(ar->connect_ctrl_flags & CONNECT_DO_WPA_OFFLOAD)) &&
 667            ((vif->auth_mode == WPA_PSK_AUTH) ||
 668             (vif->auth_mode == WPA2_PSK_AUTH))) {
 669                mod_timer(&vif->disconnect_timer,
 670                          jiffies + msecs_to_jiffies(DISCON_TIMER_INTVAL));
 671        }
 672
 673        ar->connect_ctrl_flags &= ~CONNECT_DO_WPA_OFFLOAD;
 674        set_bit(CONNECT_PEND, &vif->flags);
 675
 676        return 0;
 677}
 678
 679static struct cfg80211_bss *
 680ath6kl_add_bss_if_needed(struct ath6kl_vif *vif,
 681                         enum network_type nw_type,
 682                         const u8 *bssid,
 683                         struct ieee80211_channel *chan,
 684                         const u8 *beacon_ie,
 685                         size_t beacon_ie_len)
 686{
 687        struct ath6kl *ar = vif->ar;
 688        struct cfg80211_bss *bss;
 689        u16 cap_val;
 690        enum ieee80211_bss_type bss_type;
 691        u8 *ie;
 692
 693        if (nw_type & ADHOC_NETWORK) {
 694                cap_val = WLAN_CAPABILITY_IBSS;
 695                bss_type = IEEE80211_BSS_TYPE_IBSS;
 696        } else {
 697                cap_val = WLAN_CAPABILITY_ESS;
 698                bss_type = IEEE80211_BSS_TYPE_ESS;
 699        }
 700
 701        bss = cfg80211_get_bss(ar->wiphy, chan, bssid,
 702                               vif->ssid, vif->ssid_len,
 703                               bss_type, IEEE80211_PRIVACY_ANY);
 704        if (bss == NULL) {
 705                /*
 706                 * Since cfg80211 may not yet know about the BSS,
 707                 * generate a partial entry until the first BSS info
 708                 * event becomes available.
 709                 *
 710                 * Prepend SSID element since it is not included in the Beacon
 711                 * IEs from the target.
 712                 */
 713                ie = kmalloc(2 + vif->ssid_len + beacon_ie_len, GFP_KERNEL);
 714                if (ie == NULL)
 715                        return NULL;
 716                ie[0] = WLAN_EID_SSID;
 717                ie[1] = vif->ssid_len;
 718                memcpy(ie + 2, vif->ssid, vif->ssid_len);
 719                memcpy(ie + 2 + vif->ssid_len, beacon_ie, beacon_ie_len);
 720                bss = cfg80211_inform_bss(ar->wiphy, chan,
 721                                          CFG80211_BSS_FTYPE_UNKNOWN,
 722                                          bssid, 0, cap_val, 100,
 723                                          ie, 2 + vif->ssid_len + beacon_ie_len,
 724                                          0, GFP_KERNEL);
 725                if (bss)
 726                        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
 727                                   "added bss %pM to cfg80211\n", bssid);
 728                kfree(ie);
 729        } else {
 730                ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "cfg80211 already has a bss\n");
 731        }
 732
 733        return bss;
 734}
 735
 736void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel,
 737                                   u8 *bssid, u16 listen_intvl,
 738                                   u16 beacon_intvl,
 739                                   enum network_type nw_type,
 740                                   u8 beacon_ie_len, u8 assoc_req_len,
 741                                   u8 assoc_resp_len, u8 *assoc_info)
 742{
 743        struct ieee80211_channel *chan;
 744        struct ath6kl *ar = vif->ar;
 745        struct cfg80211_bss *bss;
 746
 747        /* capinfo + listen interval */
 748        u8 assoc_req_ie_offset = sizeof(u16) + sizeof(u16);
 749
 750        /* capinfo + status code +  associd */
 751        u8 assoc_resp_ie_offset = sizeof(u16) + sizeof(u16) + sizeof(u16);
 752
 753        u8 *assoc_req_ie = assoc_info + beacon_ie_len + assoc_req_ie_offset;
 754        u8 *assoc_resp_ie = assoc_info + beacon_ie_len + assoc_req_len +
 755            assoc_resp_ie_offset;
 756
 757        assoc_req_len -= assoc_req_ie_offset;
 758        assoc_resp_len -= assoc_resp_ie_offset;
 759
 760        /*
 761         * Store Beacon interval here; DTIM period will be available only once
 762         * a Beacon frame from the AP is seen.
 763         */
 764        vif->assoc_bss_beacon_int = beacon_intvl;
 765        clear_bit(DTIM_PERIOD_AVAIL, &vif->flags);
 766
 767        if (nw_type & ADHOC_NETWORK) {
 768                if (vif->wdev.iftype != NL80211_IFTYPE_ADHOC) {
 769                        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
 770                                   "%s: ath6k not in ibss mode\n", __func__);
 771                        return;
 772                }
 773        }
 774
 775        if (nw_type & INFRA_NETWORK) {
 776                if (vif->wdev.iftype != NL80211_IFTYPE_STATION &&
 777                    vif->wdev.iftype != NL80211_IFTYPE_P2P_CLIENT) {
 778                        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
 779                                   "%s: ath6k not in station mode\n", __func__);
 780                        return;
 781                }
 782        }
 783
 784        chan = ieee80211_get_channel(ar->wiphy, (int) channel);
 785
 786        bss = ath6kl_add_bss_if_needed(vif, nw_type, bssid, chan,
 787                                       assoc_info, beacon_ie_len);
 788        if (!bss) {
 789                ath6kl_err("could not add cfg80211 bss entry\n");
 790                return;
 791        }
 792
 793        if (nw_type & ADHOC_NETWORK) {
 794                ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "ad-hoc %s selected\n",
 795                           nw_type & ADHOC_CREATOR ? "creator" : "joiner");
 796                cfg80211_ibss_joined(vif->ndev, bssid, chan, GFP_KERNEL);
 797                cfg80211_put_bss(ar->wiphy, bss);
 798                return;
 799        }
 800
 801        if (vif->sme_state == SME_CONNECTING) {
 802                /* inform connect result to cfg80211 */
 803                vif->sme_state = SME_CONNECTED;
 804                cfg80211_connect_result(vif->ndev, bssid,
 805                                        assoc_req_ie, assoc_req_len,
 806                                        assoc_resp_ie, assoc_resp_len,
 807                                        WLAN_STATUS_SUCCESS, GFP_KERNEL);
 808                cfg80211_put_bss(ar->wiphy, bss);
 809        } else if (vif->sme_state == SME_CONNECTED) {
 810                /* inform roam event to cfg80211 */
 811                cfg80211_roamed_bss(vif->ndev, bss, assoc_req_ie, assoc_req_len,
 812                                    assoc_resp_ie, assoc_resp_len, GFP_KERNEL);
 813        }
 814}
 815
 816static int ath6kl_cfg80211_disconnect(struct wiphy *wiphy,
 817                                      struct net_device *dev, u16 reason_code)
 818{
 819        struct ath6kl *ar = ath6kl_priv(dev);
 820        struct ath6kl_vif *vif = netdev_priv(dev);
 821
 822        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: reason=%u\n", __func__,
 823                   reason_code);
 824
 825        ath6kl_cfg80211_sscan_disable(vif);
 826
 827        if (!ath6kl_cfg80211_ready(vif))
 828                return -EIO;
 829
 830        if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
 831                ath6kl_err("busy, destroy in progress\n");
 832                return -EBUSY;
 833        }
 834
 835        if (down_interruptible(&ar->sem)) {
 836                ath6kl_err("busy, couldn't get access\n");
 837                return -ERESTARTSYS;
 838        }
 839
 840        vif->reconnect_flag = 0;
 841        ath6kl_disconnect(vif);
 842        memset(vif->ssid, 0, sizeof(vif->ssid));
 843        vif->ssid_len = 0;
 844
 845        if (!test_bit(SKIP_SCAN, &ar->flag))
 846                memset(vif->req_bssid, 0, sizeof(vif->req_bssid));
 847
 848        up(&ar->sem);
 849
 850        return 0;
 851}
 852
 853void ath6kl_cfg80211_disconnect_event(struct ath6kl_vif *vif, u8 reason,
 854                                      u8 *bssid, u8 assoc_resp_len,
 855                                      u8 *assoc_info, u16 proto_reason)
 856{
 857        struct ath6kl *ar = vif->ar;
 858
 859        if (vif->scan_req) {
 860                struct cfg80211_scan_info info = {
 861                        .aborted = true,
 862                };
 863
 864                cfg80211_scan_done(vif->scan_req, &info);
 865                vif->scan_req = NULL;
 866        }
 867
 868        if (vif->nw_type & ADHOC_NETWORK) {
 869                if (vif->wdev.iftype != NL80211_IFTYPE_ADHOC)
 870                        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
 871                                   "%s: ath6k not in ibss mode\n", __func__);
 872                return;
 873        }
 874
 875        if (vif->nw_type & INFRA_NETWORK) {
 876                if (vif->wdev.iftype != NL80211_IFTYPE_STATION &&
 877                    vif->wdev.iftype != NL80211_IFTYPE_P2P_CLIENT) {
 878                        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
 879                                   "%s: ath6k not in station mode\n", __func__);
 880                        return;
 881                }
 882        }
 883
 884        clear_bit(CONNECT_PEND, &vif->flags);
 885
 886        if (vif->sme_state == SME_CONNECTING) {
 887                cfg80211_connect_result(vif->ndev,
 888                                        bssid, NULL, 0,
 889                                        NULL, 0,
 890                                        WLAN_STATUS_UNSPECIFIED_FAILURE,
 891                                        GFP_KERNEL);
 892        } else if (vif->sme_state == SME_CONNECTED) {
 893                cfg80211_disconnected(vif->ndev, proto_reason,
 894                                      NULL, 0, false, GFP_KERNEL);
 895        }
 896
 897        vif->sme_state = SME_DISCONNECTED;
 898
 899        /*
 900         * Send a disconnect command to target when a disconnect event is
 901         * received with reason code other than 3 (DISCONNECT_CMD - disconnect
 902         * request from host) to make the firmware stop trying to connect even
 903         * after giving disconnect event. There will be one more disconnect
 904         * event for this disconnect command with reason code DISCONNECT_CMD
 905         * which won't be notified to cfg80211.
 906         */
 907        if (reason != DISCONNECT_CMD)
 908                ath6kl_wmi_disconnect_cmd(ar->wmi, vif->fw_vif_idx);
 909}
 910
 911static int ath6kl_set_probed_ssids(struct ath6kl *ar,
 912                                   struct ath6kl_vif *vif,
 913                                   struct cfg80211_ssid *ssids, int n_ssids,
 914                                   struct cfg80211_match_set *match_set,
 915                                   int n_match_ssid)
 916{
 917        u8 i, j, index_to_add, ssid_found = false;
 918        struct ath6kl_cfg80211_match_probe_ssid ssid_list[MAX_PROBED_SSIDS];
 919
 920        memset(ssid_list, 0, sizeof(ssid_list));
 921
 922        if (n_ssids > MAX_PROBED_SSIDS ||
 923            n_match_ssid > MAX_PROBED_SSIDS)
 924                return -EINVAL;
 925
 926        for (i = 0; i < n_ssids; i++) {
 927                memcpy(ssid_list[i].ssid.ssid,
 928                       ssids[i].ssid,
 929                       ssids[i].ssid_len);
 930                ssid_list[i].ssid.ssid_len = ssids[i].ssid_len;
 931
 932                if (ssids[i].ssid_len)
 933                        ssid_list[i].flag = SPECIFIC_SSID_FLAG;
 934                else
 935                        ssid_list[i].flag = ANY_SSID_FLAG;
 936
 937                if (n_match_ssid == 0)
 938                        ssid_list[i].flag |= MATCH_SSID_FLAG;
 939        }
 940
 941        index_to_add = i;
 942
 943        for (i = 0; i < n_match_ssid; i++) {
 944                ssid_found = false;
 945
 946                for (j = 0; j < n_ssids; j++) {
 947                        if ((match_set[i].ssid.ssid_len ==
 948                             ssid_list[j].ssid.ssid_len) &&
 949                            (!memcmp(ssid_list[j].ssid.ssid,
 950                                     match_set[i].ssid.ssid,
 951                                     match_set[i].ssid.ssid_len))) {
 952                                ssid_list[j].flag |= MATCH_SSID_FLAG;
 953                                ssid_found = true;
 954                                break;
 955                        }
 956                }
 957
 958                if (ssid_found)
 959                        continue;
 960
 961                if (index_to_add >= MAX_PROBED_SSIDS)
 962                        continue;
 963
 964                ssid_list[index_to_add].ssid.ssid_len =
 965                        match_set[i].ssid.ssid_len;
 966                memcpy(ssid_list[index_to_add].ssid.ssid,
 967                       match_set[i].ssid.ssid,
 968                       match_set[i].ssid.ssid_len);
 969                ssid_list[index_to_add].flag |= MATCH_SSID_FLAG;
 970                index_to_add++;
 971        }
 972
 973        for (i = 0; i < index_to_add; i++) {
 974                ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx, i,
 975                                          ssid_list[i].flag,
 976                                          ssid_list[i].ssid.ssid_len,
 977                                          ssid_list[i].ssid.ssid);
 978        }
 979
 980        /* Make sure no old entries are left behind */
 981        for (i = index_to_add; i < MAX_PROBED_SSIDS; i++) {
 982                ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx, i,
 983                                          DISABLE_SSID_FLAG, 0, NULL);
 984        }
 985
 986        return 0;
 987}
 988
 989static int ath6kl_cfg80211_scan(struct wiphy *wiphy,
 990                                struct cfg80211_scan_request *request)
 991{
 992        struct ath6kl_vif *vif = ath6kl_vif_from_wdev(request->wdev);
 993        struct ath6kl *ar = ath6kl_priv(vif->ndev);
 994        s8 n_channels = 0;
 995        u16 *channels = NULL;
 996        int ret = 0;
 997        u32 force_fg_scan = 0;
 998
 999        if (!ath6kl_cfg80211_ready(vif))
1000                return -EIO;
1001
1002        ath6kl_cfg80211_sscan_disable(vif);
1003
1004        if (!ar->usr_bss_filter) {
1005                clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags);
1006                ret = ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
1007                                               ALL_BSS_FILTER, 0);
1008                if (ret) {
1009                        ath6kl_err("couldn't set bss filtering\n");
1010                        return ret;
1011                }
1012        }
1013
1014        ret = ath6kl_set_probed_ssids(ar, vif, request->ssids,
1015                                      request->n_ssids, NULL, 0);
1016        if (ret < 0)
1017                return ret;
1018
1019        /* this also clears IE in fw if it's not set */
1020        ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
1021                                       WMI_FRAME_PROBE_REQ,
1022                                       request->ie, request->ie_len);
1023        if (ret) {
1024                ath6kl_err("failed to set Probe Request appie for scan\n");
1025                return ret;
1026        }
1027
1028        /*
1029         * Scan only the requested channels if the request specifies a set of
1030         * channels. If the list is longer than the target supports, do not
1031         * configure the list and instead, scan all available channels.
1032         */
1033        if (request->n_channels > 0 &&
1034            request->n_channels <= WMI_MAX_CHANNELS) {
1035                u8 i;
1036
1037                n_channels = request->n_channels;
1038
1039                channels = kzalloc(n_channels * sizeof(u16), GFP_KERNEL);
1040                if (channels == NULL) {
1041                        ath6kl_warn("failed to set scan channels, scan all channels");
1042                        n_channels = 0;
1043                }
1044
1045                for (i = 0; i < n_channels; i++)
1046                        channels[i] = request->channels[i]->center_freq;
1047        }
1048
1049        if (test_bit(CONNECTED, &vif->flags))
1050                force_fg_scan = 1;
1051
1052        vif->scan_req = request;
1053
1054        ret = ath6kl_wmi_beginscan_cmd(ar->wmi, vif->fw_vif_idx,
1055                                       WMI_LONG_SCAN, force_fg_scan,
1056                                       false, 0,
1057                                       ATH6KL_FG_SCAN_INTERVAL,
1058                                       n_channels, channels,
1059                                       request->no_cck,
1060                                       request->rates);
1061        if (ret) {
1062                ath6kl_err("failed to start scan: %d\n", ret);
1063                vif->scan_req = NULL;
1064        }
1065
1066        kfree(channels);
1067
1068        return ret;
1069}
1070
1071void ath6kl_cfg80211_scan_complete_event(struct ath6kl_vif *vif, bool aborted)
1072{
1073        struct ath6kl *ar = vif->ar;
1074        struct cfg80211_scan_info info = {
1075                .aborted = aborted,
1076        };
1077        int i;
1078
1079        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: status%s\n", __func__,
1080                   aborted ? " aborted" : "");
1081
1082        if (!vif->scan_req)
1083                return;
1084
1085        if (aborted)
1086                goto out;
1087
1088        if (vif->scan_req->n_ssids && vif->scan_req->ssids[0].ssid_len) {
1089                for (i = 0; i < vif->scan_req->n_ssids; i++) {
1090                        ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx,
1091                                                  i + 1, DISABLE_SSID_FLAG,
1092                                                  0, NULL);
1093                }
1094        }
1095
1096out:
1097        cfg80211_scan_done(vif->scan_req, &info);
1098        vif->scan_req = NULL;
1099}
1100
1101void ath6kl_cfg80211_ch_switch_notify(struct ath6kl_vif *vif, int freq,
1102                                      enum wmi_phy_mode mode)
1103{
1104        struct cfg80211_chan_def chandef;
1105
1106        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1107                   "channel switch notify nw_type %d freq %d mode %d\n",
1108                   vif->nw_type, freq, mode);
1109
1110        cfg80211_chandef_create(&chandef,
1111                                ieee80211_get_channel(vif->ar->wiphy, freq),
1112                                (mode == WMI_11G_HT20 &&
1113                                 ath6kl_band_2ghz.ht_cap.ht_supported) ?
1114                                        NL80211_CHAN_HT20 : NL80211_CHAN_NO_HT);
1115
1116        mutex_lock(&vif->wdev.mtx);
1117        cfg80211_ch_switch_notify(vif->ndev, &chandef);
1118        mutex_unlock(&vif->wdev.mtx);
1119}
1120
1121static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
1122                                   u8 key_index, bool pairwise,
1123                                   const u8 *mac_addr,
1124                                   struct key_params *params)
1125{
1126        struct ath6kl *ar = ath6kl_priv(ndev);
1127        struct ath6kl_vif *vif = netdev_priv(ndev);
1128        struct ath6kl_key *key = NULL;
1129        int seq_len;
1130        u8 key_usage;
1131        u8 key_type;
1132
1133        if (!ath6kl_cfg80211_ready(vif))
1134                return -EIO;
1135
1136        if (params->cipher == CCKM_KRK_CIPHER_SUITE) {
1137                if (params->key_len != WMI_KRK_LEN)
1138                        return -EINVAL;
1139                return ath6kl_wmi_add_krk_cmd(ar->wmi, vif->fw_vif_idx,
1140                                              params->key);
1141        }
1142
1143        if (key_index > WMI_MAX_KEY_INDEX) {
1144                ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1145                           "%s: key index %d out of bounds\n", __func__,
1146                           key_index);
1147                return -ENOENT;
1148        }
1149
1150        key = &vif->keys[key_index];
1151        memset(key, 0, sizeof(struct ath6kl_key));
1152
1153        if (pairwise)
1154                key_usage = PAIRWISE_USAGE;
1155        else
1156                key_usage = GROUP_USAGE;
1157
1158        seq_len = params->seq_len;
1159        if (params->cipher == WLAN_CIPHER_SUITE_SMS4 &&
1160            seq_len > ATH6KL_KEY_SEQ_LEN) {
1161                /* Only first half of the WPI PN is configured */
1162                seq_len = ATH6KL_KEY_SEQ_LEN;
1163        }
1164        if (params->key_len > WLAN_MAX_KEY_LEN ||
1165            seq_len > sizeof(key->seq))
1166                return -EINVAL;
1167
1168        key->key_len = params->key_len;
1169        memcpy(key->key, params->key, key->key_len);
1170        key->seq_len = seq_len;
1171        memcpy(key->seq, params->seq, key->seq_len);
1172        key->cipher = params->cipher;
1173
1174        switch (key->cipher) {
1175        case WLAN_CIPHER_SUITE_WEP40:
1176        case WLAN_CIPHER_SUITE_WEP104:
1177                key_type = WEP_CRYPT;
1178                break;
1179
1180        case WLAN_CIPHER_SUITE_TKIP:
1181                key_type = TKIP_CRYPT;
1182                break;
1183
1184        case WLAN_CIPHER_SUITE_CCMP:
1185                key_type = AES_CRYPT;
1186                break;
1187        case WLAN_CIPHER_SUITE_SMS4:
1188                key_type = WAPI_CRYPT;
1189                break;
1190
1191        default:
1192                return -ENOTSUPP;
1193        }
1194
1195        if (((vif->auth_mode == WPA_PSK_AUTH) ||
1196             (vif->auth_mode == WPA2_PSK_AUTH)) &&
1197            (key_usage & GROUP_USAGE))
1198                del_timer(&vif->disconnect_timer);
1199
1200        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1201                   "%s: index %d, key_len %d, key_type 0x%x, key_usage 0x%x, seq_len %d\n",
1202                   __func__, key_index, key->key_len, key_type,
1203                   key_usage, key->seq_len);
1204
1205        if (vif->nw_type == AP_NETWORK && !pairwise &&
1206            (key_type == TKIP_CRYPT || key_type == AES_CRYPT ||
1207             key_type == WAPI_CRYPT)) {
1208                ar->ap_mode_bkey.valid = true;
1209                ar->ap_mode_bkey.key_index = key_index;
1210                ar->ap_mode_bkey.key_type = key_type;
1211                ar->ap_mode_bkey.key_len = key->key_len;
1212                memcpy(ar->ap_mode_bkey.key, key->key, key->key_len);
1213                if (!test_bit(CONNECTED, &vif->flags)) {
1214                        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1215                                   "Delay initial group key configuration until AP mode has been started\n");
1216                        /*
1217                         * The key will be set in ath6kl_connect_ap_mode() once
1218                         * the connected event is received from the target.
1219                         */
1220                        return 0;
1221                }
1222        }
1223
1224        if (vif->next_mode == AP_NETWORK && key_type == WEP_CRYPT &&
1225            !test_bit(CONNECTED, &vif->flags)) {
1226                /*
1227                 * Store the key locally so that it can be re-configured after
1228                 * the AP mode has properly started
1229                 * (ath6kl_install_statioc_wep_keys).
1230                 */
1231                ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1232                           "Delay WEP key configuration until AP mode has been started\n");
1233                vif->wep_key_list[key_index].key_len = key->key_len;
1234                memcpy(vif->wep_key_list[key_index].key, key->key,
1235                       key->key_len);
1236                return 0;
1237        }
1238
1239        return ath6kl_wmi_addkey_cmd(ar->wmi, vif->fw_vif_idx, key_index,
1240                                     key_type, key_usage, key->key_len,
1241                                     key->seq, key->seq_len, key->key,
1242                                     KEY_OP_INIT_VAL,
1243                                     (u8 *) mac_addr, SYNC_BOTH_WMIFLAG);
1244}
1245
1246static int ath6kl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
1247                                   u8 key_index, bool pairwise,
1248                                   const u8 *mac_addr)
1249{
1250        struct ath6kl *ar = ath6kl_priv(ndev);
1251        struct ath6kl_vif *vif = netdev_priv(ndev);
1252
1253        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
1254
1255        if (!ath6kl_cfg80211_ready(vif))
1256                return -EIO;
1257
1258        if (key_index > WMI_MAX_KEY_INDEX) {
1259                ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1260                           "%s: key index %d out of bounds\n", __func__,
1261                           key_index);
1262                return -ENOENT;
1263        }
1264
1265        if (!vif->keys[key_index].key_len) {
1266                ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1267                           "%s: index %d is empty\n", __func__, key_index);
1268                return 0;
1269        }
1270
1271        vif->keys[key_index].key_len = 0;
1272
1273        return ath6kl_wmi_deletekey_cmd(ar->wmi, vif->fw_vif_idx, key_index);
1274}
1275
1276static int ath6kl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
1277                                   u8 key_index, bool pairwise,
1278                                   const u8 *mac_addr, void *cookie,
1279                                   void (*callback) (void *cookie,
1280                                                     struct key_params *))
1281{
1282        struct ath6kl_vif *vif = netdev_priv(ndev);
1283        struct ath6kl_key *key = NULL;
1284        struct key_params params;
1285
1286        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
1287
1288        if (!ath6kl_cfg80211_ready(vif))
1289                return -EIO;
1290
1291        if (key_index > WMI_MAX_KEY_INDEX) {
1292                ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1293                           "%s: key index %d out of bounds\n", __func__,
1294                           key_index);
1295                return -ENOENT;
1296        }
1297
1298        key = &vif->keys[key_index];
1299        memset(&params, 0, sizeof(params));
1300        params.cipher = key->cipher;
1301        params.key_len = key->key_len;
1302        params.seq_len = key->seq_len;
1303        params.seq = key->seq;
1304        params.key = key->key;
1305
1306        callback(cookie, &params);
1307
1308        return key->key_len ? 0 : -ENOENT;
1309}
1310
1311static int ath6kl_cfg80211_set_default_key(struct wiphy *wiphy,
1312                                           struct net_device *ndev,
1313                                           u8 key_index, bool unicast,
1314                                           bool multicast)
1315{
1316        struct ath6kl *ar = ath6kl_priv(ndev);
1317        struct ath6kl_vif *vif = netdev_priv(ndev);
1318        struct ath6kl_key *key = NULL;
1319        u8 key_usage;
1320        enum crypto_type key_type = NONE_CRYPT;
1321
1322        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
1323
1324        if (!ath6kl_cfg80211_ready(vif))
1325                return -EIO;
1326
1327        if (key_index > WMI_MAX_KEY_INDEX) {
1328                ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1329                           "%s: key index %d out of bounds\n",
1330                           __func__, key_index);
1331                return -ENOENT;
1332        }
1333
1334        if (!vif->keys[key_index].key_len) {
1335                ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: invalid key index %d\n",
1336                           __func__, key_index);
1337                return -EINVAL;
1338        }
1339
1340        vif->def_txkey_index = key_index;
1341        key = &vif->keys[vif->def_txkey_index];
1342        key_usage = GROUP_USAGE;
1343        if (vif->prwise_crypto == WEP_CRYPT)
1344                key_usage |= TX_USAGE;
1345        if (unicast)
1346                key_type = vif->prwise_crypto;
1347        if (multicast)
1348                key_type = vif->grp_crypto;
1349
1350        if (vif->next_mode == AP_NETWORK && !test_bit(CONNECTED, &vif->flags))
1351                return 0; /* Delay until AP mode has been started */
1352
1353        return ath6kl_wmi_addkey_cmd(ar->wmi, vif->fw_vif_idx,
1354                                     vif->def_txkey_index,
1355                                     key_type, key_usage,
1356                                     key->key_len, key->seq, key->seq_len,
1357                                     key->key,
1358                                     KEY_OP_INIT_VAL, NULL,
1359                                     SYNC_BOTH_WMIFLAG);
1360}
1361
1362void ath6kl_cfg80211_tkip_micerr_event(struct ath6kl_vif *vif, u8 keyid,
1363                                       bool ismcast)
1364{
1365        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1366                   "%s: keyid %d, ismcast %d\n", __func__, keyid, ismcast);
1367
1368        cfg80211_michael_mic_failure(vif->ndev, vif->bssid,
1369                                     (ismcast ? NL80211_KEYTYPE_GROUP :
1370                                      NL80211_KEYTYPE_PAIRWISE), keyid, NULL,
1371                                     GFP_KERNEL);
1372}
1373
1374static int ath6kl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1375{
1376        struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
1377        struct ath6kl_vif *vif;
1378        int ret;
1379
1380        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: changed 0x%x\n", __func__,
1381                   changed);
1382
1383        vif = ath6kl_vif_first(ar);
1384        if (!vif)
1385                return -EIO;
1386
1387        if (!ath6kl_cfg80211_ready(vif))
1388                return -EIO;
1389
1390        if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1391                ret = ath6kl_wmi_set_rts_cmd(ar->wmi, wiphy->rts_threshold);
1392                if (ret != 0) {
1393                        ath6kl_err("ath6kl_wmi_set_rts_cmd failed\n");
1394                        return -EIO;
1395                }
1396        }
1397
1398        return 0;
1399}
1400
1401static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy,
1402                                       struct wireless_dev *wdev,
1403                                       enum nl80211_tx_power_setting type,
1404                                       int mbm)
1405{
1406        struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
1407        struct ath6kl_vif *vif;
1408        int dbm = MBM_TO_DBM(mbm);
1409
1410        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type 0x%x, dbm %d\n", __func__,
1411                   type, dbm);
1412
1413        vif = ath6kl_vif_first(ar);
1414        if (!vif)
1415                return -EIO;
1416
1417        if (!ath6kl_cfg80211_ready(vif))
1418                return -EIO;
1419
1420        switch (type) {
1421        case NL80211_TX_POWER_AUTOMATIC:
1422                return 0;
1423        case NL80211_TX_POWER_LIMITED:
1424                ar->tx_pwr = dbm;
1425                break;
1426        default:
1427                ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type 0x%x not supported\n",
1428                           __func__, type);
1429                return -EOPNOTSUPP;
1430        }
1431
1432        ath6kl_wmi_set_tx_pwr_cmd(ar->wmi, vif->fw_vif_idx, dbm);
1433
1434        return 0;
1435}
1436
1437static int ath6kl_cfg80211_get_txpower(struct wiphy *wiphy,
1438                                       struct wireless_dev *wdev,
1439                                       int *dbm)
1440{
1441        struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
1442        struct ath6kl_vif *vif;
1443
1444        vif = ath6kl_vif_first(ar);
1445        if (!vif)
1446                return -EIO;
1447
1448        if (!ath6kl_cfg80211_ready(vif))
1449                return -EIO;
1450
1451        if (test_bit(CONNECTED, &vif->flags)) {
1452                ar->tx_pwr = 255;
1453
1454                if (ath6kl_wmi_get_tx_pwr_cmd(ar->wmi, vif->fw_vif_idx) != 0) {
1455                        ath6kl_err("ath6kl_wmi_get_tx_pwr_cmd failed\n");
1456                        return -EIO;
1457                }
1458
1459                wait_event_interruptible_timeout(ar->event_wq, ar->tx_pwr != 255,
1460                                                 5 * HZ);
1461
1462                if (signal_pending(current)) {
1463                        ath6kl_err("target did not respond\n");
1464                        return -EINTR;
1465                }
1466        }
1467
1468        *dbm = ar->tx_pwr;
1469        return 0;
1470}
1471
1472static int ath6kl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
1473                                          struct net_device *dev,
1474                                          bool pmgmt, int timeout)
1475{
1476        struct ath6kl *ar = ath6kl_priv(dev);
1477        struct wmi_power_mode_cmd mode;
1478        struct ath6kl_vif *vif = netdev_priv(dev);
1479
1480        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: pmgmt %d, timeout %d\n",
1481                   __func__, pmgmt, timeout);
1482
1483        if (!ath6kl_cfg80211_ready(vif))
1484                return -EIO;
1485
1486        if (pmgmt) {
1487                ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: rec power\n", __func__);
1488                mode.pwr_mode = REC_POWER;
1489        } else {
1490                ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: max perf\n", __func__);
1491                mode.pwr_mode = MAX_PERF_POWER;
1492        }
1493
1494        if (ath6kl_wmi_powermode_cmd(ar->wmi, vif->fw_vif_idx,
1495                                     mode.pwr_mode) != 0) {
1496                ath6kl_err("wmi_powermode_cmd failed\n");
1497                return -EIO;
1498        }
1499
1500        return 0;
1501}
1502
1503static struct wireless_dev *ath6kl_cfg80211_add_iface(struct wiphy *wiphy,
1504                                                      const char *name,
1505                                                      unsigned char name_assign_type,
1506                                                      enum nl80211_iftype type,
1507                                                      u32 *flags,
1508                                                      struct vif_params *params)
1509{
1510        struct ath6kl *ar = wiphy_priv(wiphy);
1511        struct wireless_dev *wdev;
1512        u8 if_idx, nw_type;
1513
1514        if (ar->num_vif == ar->vif_max) {
1515                ath6kl_err("Reached maximum number of supported vif\n");
1516                return ERR_PTR(-EINVAL);
1517        }
1518
1519        if (!ath6kl_is_valid_iftype(ar, type, &if_idx, &nw_type)) {
1520                ath6kl_err("Not a supported interface type\n");
1521                return ERR_PTR(-EINVAL);
1522        }
1523
1524        wdev = ath6kl_interface_add(ar, name, name_assign_type, type, if_idx, nw_type);
1525        if (!wdev)
1526                return ERR_PTR(-ENOMEM);
1527
1528        ar->num_vif++;
1529
1530        return wdev;
1531}
1532
1533static int ath6kl_cfg80211_del_iface(struct wiphy *wiphy,
1534                                     struct wireless_dev *wdev)
1535{
1536        struct ath6kl *ar = wiphy_priv(wiphy);
1537        struct ath6kl_vif *vif = netdev_priv(wdev->netdev);
1538
1539        spin_lock_bh(&ar->list_lock);
1540        list_del(&vif->list);
1541        spin_unlock_bh(&ar->list_lock);
1542
1543        ath6kl_cfg80211_vif_stop(vif, test_bit(WMI_READY, &ar->flag));
1544
1545        rtnl_lock();
1546        ath6kl_cfg80211_vif_cleanup(vif);
1547        rtnl_unlock();
1548
1549        return 0;
1550}
1551
1552static int ath6kl_cfg80211_change_iface(struct wiphy *wiphy,
1553                                        struct net_device *ndev,
1554                                        enum nl80211_iftype type, u32 *flags,
1555                                        struct vif_params *params)
1556{
1557        struct ath6kl_vif *vif = netdev_priv(ndev);
1558        int i;
1559
1560        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type %u\n", __func__, type);
1561
1562        /*
1563         * Don't bring up p2p on an interface which is not initialized
1564         * for p2p operation where fw does not have capability to switch
1565         * dynamically between non-p2p and p2p type interface.
1566         */
1567        if (!test_bit(ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX,
1568                      vif->ar->fw_capabilities) &&
1569            (type == NL80211_IFTYPE_P2P_CLIENT ||
1570             type == NL80211_IFTYPE_P2P_GO)) {
1571                if (vif->ar->vif_max == 1) {
1572                        if (vif->fw_vif_idx != 0)
1573                                return -EINVAL;
1574                        else
1575                                goto set_iface_type;
1576                }
1577
1578                for (i = vif->ar->max_norm_iface; i < vif->ar->vif_max; i++) {
1579                        if (i == vif->fw_vif_idx)
1580                                break;
1581                }
1582
1583                if (i == vif->ar->vif_max) {
1584                        ath6kl_err("Invalid interface to bring up P2P\n");
1585                        return -EINVAL;
1586                }
1587        }
1588
1589        /* need to clean up enhanced bmiss detection fw state */
1590        ath6kl_cfg80211_sta_bmiss_enhance(vif, false);
1591
1592set_iface_type:
1593        switch (type) {
1594        case NL80211_IFTYPE_STATION:
1595        case NL80211_IFTYPE_P2P_CLIENT:
1596                vif->next_mode = INFRA_NETWORK;
1597                break;
1598        case NL80211_IFTYPE_ADHOC:
1599                vif->next_mode = ADHOC_NETWORK;
1600                break;
1601        case NL80211_IFTYPE_AP:
1602        case NL80211_IFTYPE_P2P_GO:
1603                vif->next_mode = AP_NETWORK;
1604                break;
1605        default:
1606                ath6kl_err("invalid interface type %u\n", type);
1607                return -EOPNOTSUPP;
1608        }
1609
1610        vif->wdev.iftype = type;
1611
1612        return 0;
1613}
1614
1615static int ath6kl_cfg80211_join_ibss(struct wiphy *wiphy,
1616                                     struct net_device *dev,
1617                                     struct cfg80211_ibss_params *ibss_param)
1618{
1619        struct ath6kl *ar = ath6kl_priv(dev);
1620        struct ath6kl_vif *vif = netdev_priv(dev);
1621        int status;
1622
1623        if (!ath6kl_cfg80211_ready(vif))
1624                return -EIO;
1625
1626        vif->ssid_len = ibss_param->ssid_len;
1627        memcpy(vif->ssid, ibss_param->ssid, vif->ssid_len);
1628
1629        if (ibss_param->chandef.chan)
1630                vif->ch_hint = ibss_param->chandef.chan->center_freq;
1631
1632        if (ibss_param->channel_fixed) {
1633                /*
1634                 * TODO: channel_fixed: The channel should be fixed, do not
1635                 * search for IBSSs to join on other channels. Target
1636                 * firmware does not support this feature, needs to be
1637                 * updated.
1638                 */
1639                return -EOPNOTSUPP;
1640        }
1641
1642        memset(vif->req_bssid, 0, sizeof(vif->req_bssid));
1643        if (ibss_param->bssid && !is_broadcast_ether_addr(ibss_param->bssid))
1644                memcpy(vif->req_bssid, ibss_param->bssid,
1645                       sizeof(vif->req_bssid));
1646
1647        ath6kl_set_wpa_version(vif, 0);
1648
1649        status = ath6kl_set_auth_type(vif, NL80211_AUTHTYPE_OPEN_SYSTEM);
1650        if (status)
1651                return status;
1652
1653        if (ibss_param->privacy) {
1654                ath6kl_set_cipher(vif, WLAN_CIPHER_SUITE_WEP40, true);
1655                ath6kl_set_cipher(vif, WLAN_CIPHER_SUITE_WEP40, false);
1656        } else {
1657                ath6kl_set_cipher(vif, 0, true);
1658                ath6kl_set_cipher(vif, 0, false);
1659        }
1660
1661        vif->nw_type = vif->next_mode;
1662
1663        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1664                   "%s: connect called with authmode %d dot11 auth %d"
1665                   " PW crypto %d PW crypto len %d GRP crypto %d"
1666                   " GRP crypto len %d channel hint %u\n",
1667                   __func__,
1668                   vif->auth_mode, vif->dot11_auth_mode, vif->prwise_crypto,
1669                   vif->prwise_crypto_len, vif->grp_crypto,
1670                   vif->grp_crypto_len, vif->ch_hint);
1671
1672        status = ath6kl_wmi_connect_cmd(ar->wmi, vif->fw_vif_idx, vif->nw_type,
1673                                        vif->dot11_auth_mode, vif->auth_mode,
1674                                        vif->prwise_crypto,
1675                                        vif->prwise_crypto_len,
1676                                        vif->grp_crypto, vif->grp_crypto_len,
1677                                        vif->ssid_len, vif->ssid,
1678                                        vif->req_bssid, vif->ch_hint,
1679                                        ar->connect_ctrl_flags, SUBTYPE_NONE);
1680        set_bit(CONNECT_PEND, &vif->flags);
1681
1682        return 0;
1683}
1684
1685static int ath6kl_cfg80211_leave_ibss(struct wiphy *wiphy,
1686                                      struct net_device *dev)
1687{
1688        struct ath6kl_vif *vif = netdev_priv(dev);
1689
1690        if (!ath6kl_cfg80211_ready(vif))
1691                return -EIO;
1692
1693        ath6kl_disconnect(vif);
1694        memset(vif->ssid, 0, sizeof(vif->ssid));
1695        vif->ssid_len = 0;
1696
1697        return 0;
1698}
1699
1700static const u32 cipher_suites[] = {
1701        WLAN_CIPHER_SUITE_WEP40,
1702        WLAN_CIPHER_SUITE_WEP104,
1703        WLAN_CIPHER_SUITE_TKIP,
1704        WLAN_CIPHER_SUITE_CCMP,
1705        CCKM_KRK_CIPHER_SUITE,
1706        WLAN_CIPHER_SUITE_SMS4,
1707};
1708
1709static bool is_rate_legacy(s32 rate)
1710{
1711        static const s32 legacy[] = { 1000, 2000, 5500, 11000,
1712                6000, 9000, 12000, 18000, 24000,
1713                36000, 48000, 54000
1714        };
1715        u8 i;
1716
1717        for (i = 0; i < ARRAY_SIZE(legacy); i++)
1718                if (rate == legacy[i])
1719                        return true;
1720
1721        return false;
1722}
1723
1724static bool is_rate_ht20(s32 rate, u8 *mcs, bool *sgi)
1725{
1726        static const s32 ht20[] = { 6500, 13000, 19500, 26000, 39000,
1727                52000, 58500, 65000, 72200
1728        };
1729        u8 i;
1730
1731        for (i = 0; i < ARRAY_SIZE(ht20); i++) {
1732                if (rate == ht20[i]) {
1733                        if (i == ARRAY_SIZE(ht20) - 1)
1734                                /* last rate uses sgi */
1735                                *sgi = true;
1736                        else
1737                                *sgi = false;
1738
1739                        *mcs = i;
1740                        return true;
1741                }
1742        }
1743        return false;
1744}
1745
1746static bool is_rate_ht40(s32 rate, u8 *mcs, bool *sgi)
1747{
1748        static const s32 ht40[] = { 13500, 27000, 40500, 54000,
1749                81000, 108000, 121500, 135000,
1750                150000
1751        };
1752        u8 i;
1753
1754        for (i = 0; i < ARRAY_SIZE(ht40); i++) {
1755                if (rate == ht40[i]) {
1756                        if (i == ARRAY_SIZE(ht40) - 1)
1757                                /* last rate uses sgi */
1758                                *sgi = true;
1759                        else
1760                                *sgi = false;
1761
1762                        *mcs = i;
1763                        return true;
1764                }
1765        }
1766
1767        return false;
1768}
1769
1770static int ath6kl_get_station(struct wiphy *wiphy, struct net_device *dev,
1771                              const u8 *mac, struct station_info *sinfo)
1772{
1773        struct ath6kl *ar = ath6kl_priv(dev);
1774        struct ath6kl_vif *vif = netdev_priv(dev);
1775        long left;
1776        bool sgi;
1777        s32 rate;
1778        int ret;
1779        u8 mcs;
1780
1781        if (memcmp(mac, vif->bssid, ETH_ALEN) != 0)
1782                return -ENOENT;
1783
1784        if (down_interruptible(&ar->sem))
1785                return -EBUSY;
1786
1787        set_bit(STATS_UPDATE_PEND, &vif->flags);
1788
1789        ret = ath6kl_wmi_get_stats_cmd(ar->wmi, vif->fw_vif_idx);
1790
1791        if (ret != 0) {
1792                up(&ar->sem);
1793                return -EIO;
1794        }
1795
1796        left = wait_event_interruptible_timeout(ar->event_wq,
1797                                                !test_bit(STATS_UPDATE_PEND,
1798                                                          &vif->flags),
1799                                                WMI_TIMEOUT);
1800
1801        up(&ar->sem);
1802
1803        if (left == 0)
1804                return -ETIMEDOUT;
1805        else if (left < 0)
1806                return left;
1807
1808        if (vif->target_stats.rx_byte) {
1809                sinfo->rx_bytes = vif->target_stats.rx_byte;
1810                sinfo->filled |= BIT(NL80211_STA_INFO_RX_BYTES64);
1811                sinfo->rx_packets = vif->target_stats.rx_pkt;
1812                sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS);
1813        }
1814
1815        if (vif->target_stats.tx_byte) {
1816                sinfo->tx_bytes = vif->target_stats.tx_byte;
1817                sinfo->filled |= BIT(NL80211_STA_INFO_TX_BYTES64);
1818                sinfo->tx_packets = vif->target_stats.tx_pkt;
1819                sinfo->filled |= BIT(NL80211_STA_INFO_TX_PACKETS);
1820        }
1821
1822        sinfo->signal = vif->target_stats.cs_rssi;
1823        sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
1824
1825        rate = vif->target_stats.tx_ucast_rate;
1826
1827        if (is_rate_legacy(rate)) {
1828                sinfo->txrate.legacy = rate / 100;
1829        } else if (is_rate_ht20(rate, &mcs, &sgi)) {
1830                if (sgi) {
1831                        sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
1832                        sinfo->txrate.mcs = mcs - 1;
1833                } else {
1834                        sinfo->txrate.mcs = mcs;
1835                }
1836
1837                sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
1838                sinfo->txrate.bw = RATE_INFO_BW_20;
1839        } else if (is_rate_ht40(rate, &mcs, &sgi)) {
1840                if (sgi) {
1841                        sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
1842                        sinfo->txrate.mcs = mcs - 1;
1843                } else {
1844                        sinfo->txrate.mcs = mcs;
1845                }
1846
1847                sinfo->txrate.bw = RATE_INFO_BW_40;
1848                sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
1849        } else {
1850                ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1851                           "invalid rate from stats: %d\n", rate);
1852                ath6kl_debug_war(ar, ATH6KL_WAR_INVALID_RATE);
1853                return 0;
1854        }
1855
1856        sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
1857
1858        if (test_bit(CONNECTED, &vif->flags) &&
1859            test_bit(DTIM_PERIOD_AVAIL, &vif->flags) &&
1860            vif->nw_type == INFRA_NETWORK) {
1861                sinfo->filled |= BIT(NL80211_STA_INFO_BSS_PARAM);
1862                sinfo->bss_param.flags = 0;
1863                sinfo->bss_param.dtim_period = vif->assoc_bss_dtim_period;
1864                sinfo->bss_param.beacon_interval = vif->assoc_bss_beacon_int;
1865        }
1866
1867        return 0;
1868}
1869
1870static int ath6kl_set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1871                            struct cfg80211_pmksa *pmksa)
1872{
1873        struct ath6kl *ar = ath6kl_priv(netdev);
1874        struct ath6kl_vif *vif = netdev_priv(netdev);
1875
1876        return ath6kl_wmi_setpmkid_cmd(ar->wmi, vif->fw_vif_idx, pmksa->bssid,
1877                                       pmksa->pmkid, true);
1878}
1879
1880static int ath6kl_del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1881                            struct cfg80211_pmksa *pmksa)
1882{
1883        struct ath6kl *ar = ath6kl_priv(netdev);
1884        struct ath6kl_vif *vif = netdev_priv(netdev);
1885
1886        return ath6kl_wmi_setpmkid_cmd(ar->wmi, vif->fw_vif_idx, pmksa->bssid,
1887                                       pmksa->pmkid, false);
1888}
1889
1890static int ath6kl_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
1891{
1892        struct ath6kl *ar = ath6kl_priv(netdev);
1893        struct ath6kl_vif *vif = netdev_priv(netdev);
1894
1895        if (test_bit(CONNECTED, &vif->flags))
1896                return ath6kl_wmi_setpmkid_cmd(ar->wmi, vif->fw_vif_idx,
1897                                               vif->bssid, NULL, false);
1898        return 0;
1899}
1900
1901static int ath6kl_wow_usr(struct ath6kl *ar, struct ath6kl_vif *vif,
1902                          struct cfg80211_wowlan *wow, u32 *filter)
1903{
1904        int ret, pos;
1905        u8 mask[WOW_PATTERN_SIZE];
1906        u16 i;
1907
1908        /* Configure the patterns that we received from the user. */
1909        for (i = 0; i < wow->n_patterns; i++) {
1910                /*
1911                 * Convert given nl80211 specific mask value to equivalent
1912                 * driver specific mask value and send it to the chip along
1913                 * with patterns. For example, If the mask value defined in
1914                 * struct cfg80211_wowlan is 0xA (equivalent binary is 1010),
1915                 * then equivalent driver specific mask value is
1916                 * "0xFF 0x00 0xFF 0x00".
1917                 */
1918                memset(&mask, 0, sizeof(mask));
1919                for (pos = 0; pos < wow->patterns[i].pattern_len; pos++) {
1920                        if (wow->patterns[i].mask[pos / 8] & (0x1 << (pos % 8)))
1921                                mask[pos] = 0xFF;
1922                }
1923                /*
1924                 * Note: Pattern's offset is not passed as part of wowlan
1925                 * parameter from CFG layer. So it's always passed as ZERO
1926                 * to the firmware. It means, given WOW patterns are always
1927                 * matched from the first byte of received pkt in the firmware.
1928                 */
1929                ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
1930                                vif->fw_vif_idx, WOW_LIST_ID,
1931                                wow->patterns[i].pattern_len,
1932                                0 /* pattern offset */,
1933                                wow->patterns[i].pattern, mask);
1934                if (ret)
1935                        return ret;
1936        }
1937
1938        if (wow->disconnect)
1939                *filter |= WOW_FILTER_OPTION_NWK_DISASSOC;
1940
1941        if (wow->magic_pkt)
1942                *filter |= WOW_FILTER_OPTION_MAGIC_PACKET;
1943
1944        if (wow->gtk_rekey_failure)
1945                *filter |= WOW_FILTER_OPTION_GTK_ERROR;
1946
1947        if (wow->eap_identity_req)
1948                *filter |= WOW_FILTER_OPTION_EAP_REQ;
1949
1950        if (wow->four_way_handshake)
1951                *filter |= WOW_FILTER_OPTION_8021X_4WAYHS;
1952
1953        return 0;
1954}
1955
1956static int ath6kl_wow_ap(struct ath6kl *ar, struct ath6kl_vif *vif)
1957{
1958        static const u8 unicst_pattern[] = { 0x00, 0x00, 0x00,
1959                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1960                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1961                0x00, 0x08 };
1962        static const u8 unicst_mask[] = { 0x01, 0x00, 0x00,
1963                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1964                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1965                0x00, 0x7f };
1966        u8 unicst_offset = 0;
1967        static const u8 arp_pattern[] = { 0x08, 0x06 };
1968        static const u8 arp_mask[] = { 0xff, 0xff };
1969        u8 arp_offset = 20;
1970        static const u8 discvr_pattern[] = { 0xe0, 0x00, 0x00, 0xf8 };
1971        static const u8 discvr_mask[] = { 0xf0, 0x00, 0x00, 0xf8 };
1972        u8 discvr_offset = 38;
1973        static const u8 dhcp_pattern[] = { 0xff, 0xff, 0xff, 0xff,
1974                0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1975                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
1976                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1977                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1978                0x00, 0x00, 0x00, 0x00, 0x00, 0x43 /* port 67 */ };
1979        static const u8 dhcp_mask[] = { 0xff, 0xff, 0xff, 0xff,
1980                0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1981                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
1982                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1983                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1984                0x00, 0x00, 0x00, 0x00, 0xff, 0xff /* port 67 */ };
1985        u8 dhcp_offset = 0;
1986        int ret;
1987
1988        /* Setup unicast IP, EAPOL-like and ARP pkt pattern */
1989        ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
1990                        vif->fw_vif_idx, WOW_LIST_ID,
1991                        sizeof(unicst_pattern), unicst_offset,
1992                        unicst_pattern, unicst_mask);
1993        if (ret) {
1994                ath6kl_err("failed to add WOW unicast IP pattern\n");
1995                return ret;
1996        }
1997
1998        /* Setup all ARP pkt pattern */
1999        ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
2000                        vif->fw_vif_idx, WOW_LIST_ID,
2001                        sizeof(arp_pattern), arp_offset,
2002                        arp_pattern, arp_mask);
2003        if (ret) {
2004                ath6kl_err("failed to add WOW ARP pattern\n");
2005                return ret;
2006        }
2007
2008        /*
2009         * Setup multicast pattern for mDNS 224.0.0.251,
2010         * SSDP 239.255.255.250 and LLMNR  224.0.0.252
2011         */
2012        ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
2013                        vif->fw_vif_idx, WOW_LIST_ID,
2014                        sizeof(discvr_pattern), discvr_offset,
2015                        discvr_pattern, discvr_mask);
2016        if (ret) {
2017                ath6kl_err("failed to add WOW mDNS/SSDP/LLMNR pattern\n");
2018                return ret;
2019        }
2020
2021        /* Setup all DHCP broadcast pkt pattern */
2022        ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
2023                        vif->fw_vif_idx, WOW_LIST_ID,
2024                        sizeof(dhcp_pattern), dhcp_offset,
2025                        dhcp_pattern, dhcp_mask);
2026        if (ret) {
2027                ath6kl_err("failed to add WOW DHCP broadcast pattern\n");
2028                return ret;
2029        }
2030
2031        return 0;
2032}
2033
2034static int ath6kl_wow_sta(struct ath6kl *ar, struct ath6kl_vif *vif)
2035{
2036        struct net_device *ndev = vif->ndev;
2037        static const u8 discvr_pattern[] = { 0xe0, 0x00, 0x00, 0xf8 };
2038        static const u8 discvr_mask[] = { 0xf0, 0x00, 0x00, 0xf8 };
2039        u8 discvr_offset = 38;
2040        u8 mac_mask[ETH_ALEN];
2041        int ret;
2042
2043        /* Setup unicast pkt pattern */
2044        eth_broadcast_addr(mac_mask);
2045        ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
2046                                vif->fw_vif_idx, WOW_LIST_ID,
2047                                ETH_ALEN, 0, ndev->dev_addr,
2048                                mac_mask);
2049        if (ret) {
2050                ath6kl_err("failed to add WOW unicast pattern\n");
2051                return ret;
2052        }
2053
2054        /*
2055         * Setup multicast pattern for mDNS 224.0.0.251,
2056         * SSDP 239.255.255.250 and LLMNR 224.0.0.252
2057         */
2058        if ((ndev->flags & IFF_ALLMULTI) ||
2059            (ndev->flags & IFF_MULTICAST && netdev_mc_count(ndev) > 0)) {
2060                ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
2061                                vif->fw_vif_idx, WOW_LIST_ID,
2062                                sizeof(discvr_pattern), discvr_offset,
2063                                discvr_pattern, discvr_mask);
2064                if (ret) {
2065                        ath6kl_err("failed to add WOW mDNS/SSDP/LLMNR pattern\n");
2066                        return ret;
2067                }
2068        }
2069
2070        return 0;
2071}
2072
2073static int is_hsleep_mode_procsed(struct ath6kl_vif *vif)
2074{
2075        return test_bit(HOST_SLEEP_MODE_CMD_PROCESSED, &vif->flags);
2076}
2077
2078static bool is_ctrl_ep_empty(struct ath6kl *ar)
2079{
2080        return !ar->tx_pending[ar->ctrl_ep];
2081}
2082
2083static int ath6kl_cfg80211_host_sleep(struct ath6kl *ar, struct ath6kl_vif *vif)
2084{
2085        int ret, left;
2086
2087        clear_bit(HOST_SLEEP_MODE_CMD_PROCESSED, &vif->flags);
2088
2089        ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
2090                                                 ATH6KL_HOST_MODE_ASLEEP);
2091        if (ret)
2092                return ret;
2093
2094        left = wait_event_interruptible_timeout(ar->event_wq,
2095                                                is_hsleep_mode_procsed(vif),
2096                                                WMI_TIMEOUT);
2097        if (left == 0) {
2098                ath6kl_warn("timeout, didn't get host sleep cmd processed event\n");
2099                ret = -ETIMEDOUT;
2100        } else if (left < 0) {
2101                ath6kl_warn("error while waiting for host sleep cmd processed event %d\n",
2102                            left);
2103                ret = left;
2104        }
2105
2106        if (ar->tx_pending[ar->ctrl_ep]) {
2107                left = wait_event_interruptible_timeout(ar->event_wq,
2108                                                        is_ctrl_ep_empty(ar),
2109                                                        WMI_TIMEOUT);
2110                if (left == 0) {
2111                        ath6kl_warn("clear wmi ctrl data timeout\n");
2112                        ret = -ETIMEDOUT;
2113                } else if (left < 0) {
2114                        ath6kl_warn("clear wmi ctrl data failed: %d\n", left);
2115                        ret = left;
2116                }
2117        }
2118
2119        return ret;
2120}
2121
2122static int ath6kl_wow_suspend_vif(struct ath6kl_vif *vif,
2123                                  struct cfg80211_wowlan *wow, u32 *filter)
2124{
2125        struct ath6kl *ar = vif->ar;
2126        struct in_device *in_dev;
2127        struct in_ifaddr *ifa;
2128        int ret;
2129        u16 i, bmiss_time;
2130        __be32 ips[MAX_IP_ADDRS];
2131        u8 index = 0;
2132
2133        if (!test_bit(NETDEV_MCAST_ALL_ON, &vif->flags) &&
2134            test_bit(ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER,
2135                     ar->fw_capabilities)) {
2136                ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi,
2137                                                vif->fw_vif_idx, false);
2138                if (ret)
2139                        return ret;
2140        }
2141
2142        /* Clear existing WOW patterns */
2143        for (i = 0; i < WOW_MAX_FILTERS_PER_LIST; i++)
2144                ath6kl_wmi_del_wow_pattern_cmd(ar->wmi, vif->fw_vif_idx,
2145                                               WOW_LIST_ID, i);
2146
2147        /*
2148         * Skip the default WOW pattern configuration
2149         * if the driver receives any WOW patterns from
2150         * the user.
2151         */
2152        if (wow)
2153                ret = ath6kl_wow_usr(ar, vif, wow, filter);
2154        else if (vif->nw_type == AP_NETWORK)
2155                ret = ath6kl_wow_ap(ar, vif);
2156        else
2157                ret = ath6kl_wow_sta(ar, vif);
2158
2159        if (ret)
2160                return ret;
2161
2162        netif_stop_queue(vif->ndev);
2163
2164        if (vif->nw_type != AP_NETWORK) {
2165                ret = ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx,
2166                                                    ATH6KL_MAX_WOW_LISTEN_INTL,
2167                                                    0);
2168                if (ret)
2169                        return ret;
2170
2171                /* Set listen interval x 15 times as bmiss time */
2172                bmiss_time = ATH6KL_MAX_WOW_LISTEN_INTL * 15;
2173                if (bmiss_time > ATH6KL_MAX_BMISS_TIME)
2174                        bmiss_time = ATH6KL_MAX_BMISS_TIME;
2175
2176                ret = ath6kl_wmi_bmisstime_cmd(ar->wmi, vif->fw_vif_idx,
2177                                               bmiss_time, 0);
2178                if (ret)
2179                        return ret;
2180
2181                ret = ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx,
2182                                                0xFFFF, 0, 0xFFFF, 0, 0, 0,
2183                                                0, 0, 0, 0);
2184                if (ret)
2185                        return ret;
2186        }
2187
2188        /* Setup own IP addr for ARP agent. */
2189        in_dev = __in_dev_get_rtnl(vif->ndev);
2190        if (!in_dev)
2191                return 0;
2192
2193        ifa = in_dev->ifa_list;
2194        memset(&ips, 0, sizeof(ips));
2195
2196        /* Configure IP addr only if IP address count < MAX_IP_ADDRS */
2197        while (index < MAX_IP_ADDRS && ifa) {
2198                ips[index] = ifa->ifa_local;
2199                ifa = ifa->ifa_next;
2200                index++;
2201        }
2202
2203        if (ifa) {
2204                ath6kl_err("total IP addr count is exceeding fw limit\n");
2205                return -EINVAL;
2206        }
2207
2208        ret = ath6kl_wmi_set_ip_cmd(ar->wmi, vif->fw_vif_idx, ips[0], ips[1]);
2209        if (ret) {
2210                ath6kl_err("fail to setup ip for arp agent\n");
2211                return ret;
2212        }
2213
2214        return ret;
2215}
2216
2217static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
2218{
2219        struct ath6kl_vif *first_vif, *vif;
2220        int ret = 0;
2221        u32 filter = 0;
2222        bool connected = false;
2223
2224        /* enter / leave wow suspend on first vif always */
2225        first_vif = ath6kl_vif_first(ar);
2226        if (WARN_ON(!first_vif) ||
2227            !ath6kl_cfg80211_ready(first_vif))
2228                return -EIO;
2229
2230        if (wow && (wow->n_patterns > WOW_MAX_FILTERS_PER_LIST))
2231                return -EINVAL;
2232
2233        /* install filters for each connected vif */
2234        spin_lock_bh(&ar->list_lock);
2235        list_for_each_entry(vif, &ar->vif_list, list) {
2236                if (!test_bit(CONNECTED, &vif->flags) ||
2237                    !ath6kl_cfg80211_ready(vif))
2238                        continue;
2239                connected = true;
2240
2241                ret = ath6kl_wow_suspend_vif(vif, wow, &filter);
2242                if (ret)
2243                        break;
2244        }
2245        spin_unlock_bh(&ar->list_lock);
2246
2247        if (!connected)
2248                return -ENOTCONN;
2249        else if (ret)
2250                return ret;
2251
2252        ar->state = ATH6KL_STATE_SUSPENDING;
2253
2254        ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, first_vif->fw_vif_idx,
2255                                          ATH6KL_WOW_MODE_ENABLE,
2256                                          filter,
2257                                          WOW_HOST_REQ_DELAY);
2258        if (ret)
2259                return ret;
2260
2261        return ath6kl_cfg80211_host_sleep(ar, first_vif);
2262}
2263
2264static int ath6kl_wow_resume_vif(struct ath6kl_vif *vif)
2265{
2266        struct ath6kl *ar = vif->ar;
2267        int ret;
2268
2269        if (vif->nw_type != AP_NETWORK) {
2270                ret = ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx,
2271                                                0, 0, 0, 0, 0, 0, 3, 0, 0, 0);
2272                if (ret)
2273                        return ret;
2274
2275                ret = ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx,
2276                                                    vif->listen_intvl_t, 0);
2277                if (ret)
2278                        return ret;
2279
2280                ret = ath6kl_wmi_bmisstime_cmd(ar->wmi, vif->fw_vif_idx,
2281                                               vif->bmiss_time_t, 0);
2282                if (ret)
2283                        return ret;
2284        }
2285
2286        if (!test_bit(NETDEV_MCAST_ALL_OFF, &vif->flags) &&
2287            test_bit(ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER,
2288                     ar->fw_capabilities)) {
2289                ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi,
2290                                                  vif->fw_vif_idx, true);
2291                if (ret)
2292                        return ret;
2293        }
2294
2295        netif_wake_queue(vif->ndev);
2296
2297        return 0;
2298}
2299
2300static int ath6kl_wow_resume(struct ath6kl *ar)
2301{
2302        struct ath6kl_vif *vif;
2303        int ret;
2304
2305        vif = ath6kl_vif_first(ar);
2306        if (WARN_ON(!vif) ||
2307            !ath6kl_cfg80211_ready(vif))
2308                return -EIO;
2309
2310        ar->state = ATH6KL_STATE_RESUMING;
2311
2312        ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
2313                                                 ATH6KL_HOST_MODE_AWAKE);
2314        if (ret) {
2315                ath6kl_warn("Failed to configure host sleep mode for wow resume: %d\n",
2316                            ret);
2317                goto cleanup;
2318        }
2319
2320        spin_lock_bh(&ar->list_lock);
2321        list_for_each_entry(vif, &ar->vif_list, list) {
2322                if (!test_bit(CONNECTED, &vif->flags) ||
2323                    !ath6kl_cfg80211_ready(vif))
2324                        continue;
2325                ret = ath6kl_wow_resume_vif(vif);
2326                if (ret)
2327                        break;
2328        }
2329        spin_unlock_bh(&ar->list_lock);
2330
2331        if (ret)
2332                goto cleanup;
2333
2334        ar->state = ATH6KL_STATE_ON;
2335        return 0;
2336
2337cleanup:
2338        ar->state = ATH6KL_STATE_WOW;
2339        return ret;
2340}
2341
2342static int ath6kl_cfg80211_deepsleep_suspend(struct ath6kl *ar)
2343{
2344        struct ath6kl_vif *vif;
2345        int ret;
2346
2347        vif = ath6kl_vif_first(ar);
2348        if (!vif)
2349                return -EIO;
2350
2351        if (!test_bit(WMI_READY, &ar->flag)) {
2352                ath6kl_err("deepsleep failed as wmi is not ready\n");
2353                return -EIO;
2354        }
2355
2356        ath6kl_cfg80211_stop_all(ar);
2357
2358        /* Save the current power mode before enabling power save */
2359        ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode;
2360
2361        ret = ath6kl_wmi_powermode_cmd(ar->wmi, 0, REC_POWER);
2362        if (ret)
2363                return ret;
2364
2365        /* Disable WOW mode */
2366        ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, vif->fw_vif_idx,
2367                                          ATH6KL_WOW_MODE_DISABLE,
2368                                          0, 0);
2369        if (ret)
2370                return ret;
2371
2372        /* Flush all non control pkts in TX path */
2373        ath6kl_tx_data_cleanup(ar);
2374
2375        ret = ath6kl_cfg80211_host_sleep(ar, vif);
2376        if (ret)
2377                return ret;
2378
2379        return 0;
2380}
2381
2382static int ath6kl_cfg80211_deepsleep_resume(struct ath6kl *ar)
2383{
2384        struct ath6kl_vif *vif;
2385        int ret;
2386
2387        vif = ath6kl_vif_first(ar);
2388
2389        if (!vif)
2390                return -EIO;
2391
2392        if (ar->wmi->pwr_mode != ar->wmi->saved_pwr_mode) {
2393                ret = ath6kl_wmi_powermode_cmd(ar->wmi, 0,
2394                                               ar->wmi->saved_pwr_mode);
2395                if (ret)
2396                        return ret;
2397        }
2398
2399        ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
2400                                                 ATH6KL_HOST_MODE_AWAKE);
2401        if (ret)
2402                return ret;
2403
2404        ar->state = ATH6KL_STATE_ON;
2405
2406        /* Reset scan parameter to default values */
2407        ret = ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx,
2408                                        0, 0, 0, 0, 0, 0, 3, 0, 0, 0);
2409        if (ret)
2410                return ret;
2411
2412        return 0;
2413}
2414
2415int ath6kl_cfg80211_suspend(struct ath6kl *ar,
2416                            enum ath6kl_cfg_suspend_mode mode,
2417                            struct cfg80211_wowlan *wow)
2418{
2419        struct ath6kl_vif *vif;
2420        enum ath6kl_state prev_state;
2421        int ret;
2422
2423        switch (mode) {
2424        case ATH6KL_CFG_SUSPEND_WOW:
2425
2426                ath6kl_dbg(ATH6KL_DBG_SUSPEND, "wow mode suspend\n");
2427
2428                /* Flush all non control pkts in TX path */
2429                ath6kl_tx_data_cleanup(ar);
2430
2431                prev_state = ar->state;
2432
2433                ret = ath6kl_wow_suspend(ar, wow);
2434                if (ret) {
2435                        ar->state = prev_state;
2436                        return ret;
2437                }
2438
2439                ar->state = ATH6KL_STATE_WOW;
2440                break;
2441
2442        case ATH6KL_CFG_SUSPEND_DEEPSLEEP:
2443
2444                ath6kl_dbg(ATH6KL_DBG_SUSPEND, "deep sleep suspend\n");
2445
2446                ret = ath6kl_cfg80211_deepsleep_suspend(ar);
2447                if (ret) {
2448                        ath6kl_err("deepsleep suspend failed: %d\n", ret);
2449                        return ret;
2450                }
2451
2452                ar->state = ATH6KL_STATE_DEEPSLEEP;
2453
2454                break;
2455
2456        case ATH6KL_CFG_SUSPEND_CUTPOWER:
2457
2458                ath6kl_cfg80211_stop_all(ar);
2459
2460                if (ar->state == ATH6KL_STATE_OFF) {
2461                        ath6kl_dbg(ATH6KL_DBG_SUSPEND,
2462                                   "suspend hw off, no action for cutpower\n");
2463                        break;
2464                }
2465
2466                ath6kl_dbg(ATH6KL_DBG_SUSPEND, "suspend cutting power\n");
2467
2468                ret = ath6kl_init_hw_stop(ar);
2469                if (ret) {
2470                        ath6kl_warn("failed to stop hw during suspend: %d\n",
2471                                    ret);
2472                }
2473
2474                ar->state = ATH6KL_STATE_CUTPOWER;
2475
2476                break;
2477
2478        default:
2479                break;
2480        }
2481
2482        list_for_each_entry(vif, &ar->vif_list, list)
2483                ath6kl_cfg80211_scan_complete_event(vif, true);
2484
2485        return 0;
2486}
2487EXPORT_SYMBOL(ath6kl_cfg80211_suspend);
2488
2489int ath6kl_cfg80211_resume(struct ath6kl *ar)
2490{
2491        int ret;
2492
2493        switch (ar->state) {
2494        case  ATH6KL_STATE_WOW:
2495                ath6kl_dbg(ATH6KL_DBG_SUSPEND, "wow mode resume\n");
2496
2497                ret = ath6kl_wow_resume(ar);
2498                if (ret) {
2499                        ath6kl_warn("wow mode resume failed: %d\n", ret);
2500                        return ret;
2501                }
2502
2503                break;
2504
2505        case ATH6KL_STATE_DEEPSLEEP:
2506                ath6kl_dbg(ATH6KL_DBG_SUSPEND, "deep sleep resume\n");
2507
2508                ret = ath6kl_cfg80211_deepsleep_resume(ar);
2509                if (ret) {
2510                        ath6kl_warn("deep sleep resume failed: %d\n", ret);
2511                        return ret;
2512                }
2513                break;
2514
2515        case ATH6KL_STATE_CUTPOWER:
2516                ath6kl_dbg(ATH6KL_DBG_SUSPEND, "resume restoring power\n");
2517
2518                ret = ath6kl_init_hw_start(ar);
2519                if (ret) {
2520                        ath6kl_warn("Failed to boot hw in resume: %d\n", ret);
2521                        return ret;
2522                }
2523                break;
2524
2525        default:
2526                break;
2527        }
2528
2529        return 0;
2530}
2531EXPORT_SYMBOL(ath6kl_cfg80211_resume);
2532
2533#ifdef CONFIG_PM
2534
2535/* hif layer decides what suspend mode to use */
2536static int __ath6kl_cfg80211_suspend(struct wiphy *wiphy,
2537                                 struct cfg80211_wowlan *wow)
2538{
2539        struct ath6kl *ar = wiphy_priv(wiphy);
2540
2541        ath6kl_recovery_suspend(ar);
2542
2543        return ath6kl_hif_suspend(ar, wow);
2544}
2545
2546static int __ath6kl_cfg80211_resume(struct wiphy *wiphy)
2547{
2548        struct ath6kl *ar = wiphy_priv(wiphy);
2549        int err;
2550
2551        err = ath6kl_hif_resume(ar);
2552        if (err)
2553                return err;
2554
2555        ath6kl_recovery_resume(ar);
2556
2557        return 0;
2558}
2559
2560/*
2561 * FIXME: WOW suspend mode is selected if the host sdio controller supports
2562 * both sdio irq wake up and keep power. The target pulls sdio data line to
2563 * wake up the host when WOW pattern matches. This causes sdio irq handler
2564 * is being called in the host side which internally hits ath6kl's RX path.
2565 *
2566 * Since sdio interrupt is not disabled, RX path executes even before
2567 * the host executes the actual resume operation from PM module.
2568 *
2569 * In the current scenario, WOW resume should happen before start processing
2570 * any data from the target. So It's required to perform WOW resume in RX path.
2571 * Ideally we should perform WOW resume only in the actual platform
2572 * resume path. This area needs bit rework to avoid WOW resume in RX path.
2573 *
2574 * ath6kl_check_wow_status() is called from ath6kl_rx().
2575 */
2576void ath6kl_check_wow_status(struct ath6kl *ar)
2577{
2578        if (ar->state == ATH6KL_STATE_SUSPENDING)
2579                return;
2580
2581        if (ar->state == ATH6KL_STATE_WOW)
2582                ath6kl_cfg80211_resume(ar);
2583}
2584
2585#else
2586
2587void ath6kl_check_wow_status(struct ath6kl *ar)
2588{
2589}
2590#endif
2591
2592static int ath6kl_set_htcap(struct ath6kl_vif *vif, enum nl80211_band band,
2593                            bool ht_enable)
2594{
2595        struct ath6kl_htcap *htcap = &vif->htcap[band];
2596
2597        if (htcap->ht_enable == ht_enable)
2598                return 0;
2599
2600        if (ht_enable) {
2601                /* Set default ht capabilities */
2602                htcap->ht_enable = true;
2603                htcap->cap_info = (band == NL80211_BAND_2GHZ) ?
2604                                   ath6kl_g_htcap : ath6kl_a_htcap;
2605                htcap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K;
2606        } else /* Disable ht */
2607                memset(htcap, 0, sizeof(*htcap));
2608
2609        return ath6kl_wmi_set_htcap_cmd(vif->ar->wmi, vif->fw_vif_idx,
2610                                        band, htcap);
2611}
2612
2613static int ath6kl_restore_htcap(struct ath6kl_vif *vif)
2614{
2615        struct wiphy *wiphy = vif->ar->wiphy;
2616        int band, ret = 0;
2617
2618        for (band = 0; band < NUM_NL80211_BANDS; band++) {
2619                if (!wiphy->bands[band])
2620                        continue;
2621
2622                ret = ath6kl_set_htcap(vif, band,
2623                                wiphy->bands[band]->ht_cap.ht_supported);
2624                if (ret)
2625                        return ret;
2626        }
2627
2628        return ret;
2629}
2630
2631static bool ath6kl_is_p2p_ie(const u8 *pos)
2632{
2633        return pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
2634                pos[2] == 0x50 && pos[3] == 0x6f &&
2635                pos[4] == 0x9a && pos[5] == 0x09;
2636}
2637
2638static int ath6kl_set_ap_probe_resp_ies(struct ath6kl_vif *vif,
2639                                        const u8 *ies, size_t ies_len)
2640{
2641        struct ath6kl *ar = vif->ar;
2642        const u8 *pos;
2643        u8 *buf = NULL;
2644        size_t len = 0;
2645        int ret;
2646
2647        /*
2648         * Filter out P2P IE(s) since they will be included depending on
2649         * the Probe Request frame in ath6kl_send_go_probe_resp().
2650         */
2651
2652        if (ies && ies_len) {
2653                buf = kmalloc(ies_len, GFP_KERNEL);
2654                if (buf == NULL)
2655                        return -ENOMEM;
2656                pos = ies;
2657                while (pos + 1 < ies + ies_len) {
2658                        if (pos + 2 + pos[1] > ies + ies_len)
2659                                break;
2660                        if (!ath6kl_is_p2p_ie(pos)) {
2661                                memcpy(buf + len, pos, 2 + pos[1]);
2662                                len += 2 + pos[1];
2663                        }
2664                        pos += 2 + pos[1];
2665                }
2666        }
2667
2668        ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
2669                                       WMI_FRAME_PROBE_RESP, buf, len);
2670        kfree(buf);
2671        return ret;
2672}
2673
2674static int ath6kl_set_ies(struct ath6kl_vif *vif,
2675                          struct cfg80211_beacon_data *info)
2676{
2677        struct ath6kl *ar = vif->ar;
2678        int res;
2679
2680        /* this also clears IE in fw if it's not set */
2681        res = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
2682                                       WMI_FRAME_BEACON,
2683                                       info->beacon_ies,
2684                                       info->beacon_ies_len);
2685        if (res)
2686                return res;
2687
2688        /* this also clears IE in fw if it's not set */
2689        res = ath6kl_set_ap_probe_resp_ies(vif, info->proberesp_ies,
2690                                           info->proberesp_ies_len);
2691        if (res)
2692                return res;
2693
2694        /* this also clears IE in fw if it's not set */
2695        res = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
2696                                       WMI_FRAME_ASSOC_RESP,
2697                                       info->assocresp_ies,
2698                                       info->assocresp_ies_len);
2699        if (res)
2700                return res;
2701
2702        return 0;
2703}
2704
2705static int ath6kl_get_rsn_capab(struct cfg80211_beacon_data *beacon,
2706                                u8 *rsn_capab)
2707{
2708        const u8 *rsn_ie;
2709        size_t rsn_ie_len;
2710        u16 cnt;
2711
2712        if (!beacon->tail)
2713                return -EINVAL;
2714
2715        rsn_ie = cfg80211_find_ie(WLAN_EID_RSN, beacon->tail, beacon->tail_len);
2716        if (!rsn_ie)
2717                return -EINVAL;
2718
2719        rsn_ie_len = *(rsn_ie + 1);
2720        /* skip element id and length */
2721        rsn_ie += 2;
2722
2723        /* skip version */
2724        if (rsn_ie_len < 2)
2725                return -EINVAL;
2726        rsn_ie +=  2;
2727        rsn_ie_len -= 2;
2728
2729        /* skip group cipher suite */
2730        if (rsn_ie_len < 4)
2731                return 0;
2732        rsn_ie +=  4;
2733        rsn_ie_len -= 4;
2734
2735        /* skip pairwise cipher suite */
2736        if (rsn_ie_len < 2)
2737                return 0;
2738        cnt = get_unaligned_le16(rsn_ie);
2739        rsn_ie += (2 + cnt * 4);
2740        rsn_ie_len -= (2 + cnt * 4);
2741
2742        /* skip akm suite */
2743        if (rsn_ie_len < 2)
2744                return 0;
2745        cnt = get_unaligned_le16(rsn_ie);
2746        rsn_ie += (2 + cnt * 4);
2747        rsn_ie_len -= (2 + cnt * 4);
2748
2749        if (rsn_ie_len < 2)
2750                return 0;
2751
2752        memcpy(rsn_capab, rsn_ie, 2);
2753
2754        return 0;
2755}
2756
2757static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,
2758                           struct cfg80211_ap_settings *info)
2759{
2760        struct ath6kl *ar = ath6kl_priv(dev);
2761        struct ath6kl_vif *vif = netdev_priv(dev);
2762        struct ieee80211_mgmt *mgmt;
2763        bool hidden = false;
2764        u8 *ies;
2765        int ies_len;
2766        struct wmi_connect_cmd p;
2767        int res;
2768        int i, ret;
2769        u16 rsn_capab = 0;
2770        int inactivity_timeout = 0;
2771
2772        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s:\n", __func__);
2773
2774        if (!ath6kl_cfg80211_ready(vif))
2775                return -EIO;
2776
2777        if (vif->next_mode != AP_NETWORK)
2778                return -EOPNOTSUPP;
2779
2780        res = ath6kl_set_ies(vif, &info->beacon);
2781
2782        ar->ap_mode_bkey.valid = false;
2783
2784        ret = ath6kl_wmi_ap_set_beacon_intvl_cmd(ar->wmi, vif->fw_vif_idx,
2785                                                 info->beacon_interval);
2786
2787        if (ret)
2788                ath6kl_warn("Failed to set beacon interval: %d\n", ret);
2789
2790        ret = ath6kl_wmi_ap_set_dtim_cmd(ar->wmi, vif->fw_vif_idx,
2791                                         info->dtim_period);
2792
2793        /* ignore error, just print a warning and continue normally */
2794        if (ret)
2795                ath6kl_warn("Failed to set dtim_period in beacon: %d\n", ret);
2796
2797        if (info->beacon.head == NULL)
2798                return -EINVAL;
2799        mgmt = (struct ieee80211_mgmt *) info->beacon.head;
2800        ies = mgmt->u.beacon.variable;
2801        if (ies > info->beacon.head + info->beacon.head_len)
2802                return -EINVAL;
2803        ies_len = info->beacon.head + info->beacon.head_len - ies;
2804
2805        if (info->ssid == NULL)
2806                return -EINVAL;
2807        memcpy(vif->ssid, info->ssid, info->ssid_len);
2808        vif->ssid_len = info->ssid_len;
2809        if (info->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
2810                hidden = true;
2811
2812        res = ath6kl_wmi_ap_hidden_ssid(ar->wmi, vif->fw_vif_idx, hidden);
2813        if (res)
2814                return res;
2815
2816        ret = ath6kl_set_auth_type(vif, info->auth_type);
2817        if (ret)
2818                return ret;
2819
2820        memset(&p, 0, sizeof(p));
2821
2822        for (i = 0; i < info->crypto.n_akm_suites; i++) {
2823                switch (info->crypto.akm_suites[i]) {
2824                case WLAN_AKM_SUITE_8021X:
2825                        if (info->crypto.wpa_versions & NL80211_WPA_VERSION_1)
2826                                p.auth_mode |= WPA_AUTH;
2827                        if (info->crypto.wpa_versions & NL80211_WPA_VERSION_2)
2828                                p.auth_mode |= WPA2_AUTH;
2829                        break;
2830                case WLAN_AKM_SUITE_PSK:
2831                        if (info->crypto.wpa_versions & NL80211_WPA_VERSION_1)
2832                                p.auth_mode |= WPA_PSK_AUTH;
2833                        if (info->crypto.wpa_versions & NL80211_WPA_VERSION_2)
2834                                p.auth_mode |= WPA2_PSK_AUTH;
2835                        break;
2836                }
2837        }
2838        if (p.auth_mode == 0)
2839                p.auth_mode = NONE_AUTH;
2840        vif->auth_mode = p.auth_mode;
2841
2842        for (i = 0; i < info->crypto.n_ciphers_pairwise; i++) {
2843                switch (info->crypto.ciphers_pairwise[i]) {
2844                case WLAN_CIPHER_SUITE_WEP40:
2845                case WLAN_CIPHER_SUITE_WEP104:
2846                        p.prwise_crypto_type |= WEP_CRYPT;
2847                        break;
2848                case WLAN_CIPHER_SUITE_TKIP:
2849                        p.prwise_crypto_type |= TKIP_CRYPT;
2850                        break;
2851                case WLAN_CIPHER_SUITE_CCMP:
2852                        p.prwise_crypto_type |= AES_CRYPT;
2853                        break;
2854                case WLAN_CIPHER_SUITE_SMS4:
2855                        p.prwise_crypto_type |= WAPI_CRYPT;
2856                        break;
2857                }
2858        }
2859        if (p.prwise_crypto_type == 0) {
2860                p.prwise_crypto_type = NONE_CRYPT;
2861                ath6kl_set_cipher(vif, 0, true);
2862        } else if (info->crypto.n_ciphers_pairwise == 1) {
2863                ath6kl_set_cipher(vif, info->crypto.ciphers_pairwise[0], true);
2864        }
2865
2866        switch (info->crypto.cipher_group) {
2867        case WLAN_CIPHER_SUITE_WEP40:
2868        case WLAN_CIPHER_SUITE_WEP104:
2869                p.grp_crypto_type = WEP_CRYPT;
2870                break;
2871        case WLAN_CIPHER_SUITE_TKIP:
2872                p.grp_crypto_type = TKIP_CRYPT;
2873                break;
2874        case WLAN_CIPHER_SUITE_CCMP:
2875                p.grp_crypto_type = AES_CRYPT;
2876                break;
2877        case WLAN_CIPHER_SUITE_SMS4:
2878                p.grp_crypto_type = WAPI_CRYPT;
2879                break;
2880        default:
2881                p.grp_crypto_type = NONE_CRYPT;
2882                break;
2883        }
2884        ath6kl_set_cipher(vif, info->crypto.cipher_group, false);
2885
2886        p.nw_type = AP_NETWORK;
2887        vif->nw_type = vif->next_mode;
2888
2889        p.ssid_len = vif->ssid_len;
2890        memcpy(p.ssid, vif->ssid, vif->ssid_len);
2891        p.dot11_auth_mode = vif->dot11_auth_mode;
2892        p.ch = cpu_to_le16(info->chandef.chan->center_freq);
2893
2894        /* Enable uAPSD support by default */
2895        res = ath6kl_wmi_ap_set_apsd(ar->wmi, vif->fw_vif_idx, true);
2896        if (res < 0)
2897                return res;
2898
2899        if (vif->wdev.iftype == NL80211_IFTYPE_P2P_GO) {
2900                p.nw_subtype = SUBTYPE_P2PGO;
2901        } else {
2902                /*
2903                 * Due to firmware limitation, it is not possible to
2904                 * do P2P mgmt operations in AP mode
2905                 */
2906                p.nw_subtype = SUBTYPE_NONE;
2907        }
2908
2909        if (info->inactivity_timeout) {
2910                inactivity_timeout = info->inactivity_timeout;
2911
2912                if (test_bit(ATH6KL_FW_CAPABILITY_AP_INACTIVITY_MINS,
2913                             ar->fw_capabilities))
2914                        inactivity_timeout = DIV_ROUND_UP(inactivity_timeout,
2915                                                          60);
2916
2917                res = ath6kl_wmi_set_inact_period(ar->wmi, vif->fw_vif_idx,
2918                                                  inactivity_timeout);
2919                if (res < 0)
2920                        return res;
2921        }
2922
2923        if (ath6kl_set_htcap(vif, info->chandef.chan->band,
2924                             cfg80211_get_chandef_type(&info->chandef)
2925                                        != NL80211_CHAN_NO_HT))
2926                return -EIO;
2927
2928        /*
2929         * Get the PTKSA replay counter in the RSN IE. Supplicant
2930         * will use the RSN IE in M3 message and firmware has to
2931         * advertise the same in beacon/probe response. Send
2932         * the complete RSN IE capability field to firmware
2933         */
2934        if (!ath6kl_get_rsn_capab(&info->beacon, (u8 *) &rsn_capab) &&
2935            test_bit(ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE,
2936                     ar->fw_capabilities)) {
2937                res = ath6kl_wmi_set_ie_cmd(ar->wmi, vif->fw_vif_idx,
2938                                            WLAN_EID_RSN, WMI_RSN_IE_CAPB,
2939                                            (const u8 *) &rsn_capab,
2940                                            sizeof(rsn_capab));
2941                vif->rsn_capab = rsn_capab;
2942                if (res < 0)
2943                        return res;
2944        }
2945
2946        memcpy(&vif->profile, &p, sizeof(p));
2947        res = ath6kl_wmi_ap_profile_commit(ar->wmi, vif->fw_vif_idx, &p);
2948        if (res < 0)
2949                return res;
2950
2951        return 0;
2952}
2953
2954static int ath6kl_change_beacon(struct wiphy *wiphy, struct net_device *dev,
2955                                struct cfg80211_beacon_data *beacon)
2956{
2957        struct ath6kl_vif *vif = netdev_priv(dev);
2958
2959        if (!ath6kl_cfg80211_ready(vif))
2960                return -EIO;
2961
2962        if (vif->next_mode != AP_NETWORK)
2963                return -EOPNOTSUPP;
2964
2965        return ath6kl_set_ies(vif, beacon);
2966}
2967
2968static int ath6kl_stop_ap(struct wiphy *wiphy, struct net_device *dev)
2969{
2970        struct ath6kl *ar = ath6kl_priv(dev);
2971        struct ath6kl_vif *vif = netdev_priv(dev);
2972
2973        if (vif->nw_type != AP_NETWORK)
2974                return -EOPNOTSUPP;
2975        if (!test_bit(CONNECTED, &vif->flags))
2976                return -ENOTCONN;
2977
2978        ath6kl_wmi_disconnect_cmd(ar->wmi, vif->fw_vif_idx);
2979        clear_bit(CONNECTED, &vif->flags);
2980        netif_carrier_off(vif->ndev);
2981
2982        /* Restore ht setting in firmware */
2983        return ath6kl_restore_htcap(vif);
2984}
2985
2986static const u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
2987
2988static int ath6kl_del_station(struct wiphy *wiphy, struct net_device *dev,
2989                              struct station_del_parameters *params)
2990{
2991        struct ath6kl *ar = ath6kl_priv(dev);
2992        struct ath6kl_vif *vif = netdev_priv(dev);
2993        const u8 *addr = params->mac ? params->mac : bcast_addr;
2994
2995        return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx, WMI_AP_DEAUTH,
2996                                      addr, WLAN_REASON_PREV_AUTH_NOT_VALID);
2997}
2998
2999static int ath6kl_change_station(struct wiphy *wiphy, struct net_device *dev,
3000                                 const u8 *mac,
3001                                 struct station_parameters *params)
3002{
3003        struct ath6kl *ar = ath6kl_priv(dev);
3004        struct ath6kl_vif *vif = netdev_priv(dev);
3005        int err;
3006
3007        if (vif->nw_type != AP_NETWORK)
3008                return -EOPNOTSUPP;
3009
3010        err = cfg80211_check_station_change(wiphy, params,
3011                                            CFG80211_STA_AP_MLME_CLIENT);
3012        if (err)
3013                return err;
3014
3015        if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
3016                return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx,
3017                                              WMI_AP_MLME_AUTHORIZE, mac, 0);
3018        return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx,
3019                                      WMI_AP_MLME_UNAUTHORIZE, mac, 0);
3020}
3021
3022static int ath6kl_remain_on_channel(struct wiphy *wiphy,
3023                                    struct wireless_dev *wdev,
3024                                    struct ieee80211_channel *chan,
3025                                    unsigned int duration,
3026                                    u64 *cookie)
3027{
3028        struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev);
3029        struct ath6kl *ar = ath6kl_priv(vif->ndev);
3030        u32 id;
3031
3032        /* TODO: if already pending or ongoing remain-on-channel,
3033         * return -EBUSY */
3034        id = ++vif->last_roc_id;
3035        if (id == 0) {
3036                /* Do not use 0 as the cookie value */
3037                id = ++vif->last_roc_id;
3038        }
3039        *cookie = id;
3040
3041        return ath6kl_wmi_remain_on_chnl_cmd(ar->wmi, vif->fw_vif_idx,
3042                                             chan->center_freq, duration);
3043}
3044
3045static int ath6kl_cancel_remain_on_channel(struct wiphy *wiphy,
3046                                           struct wireless_dev *wdev,
3047                                           u64 cookie)
3048{
3049        struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev);
3050        struct ath6kl *ar = ath6kl_priv(vif->ndev);
3051
3052        if (cookie != vif->last_roc_id)
3053                return -ENOENT;
3054        vif->last_cancel_roc_id = cookie;
3055
3056        return ath6kl_wmi_cancel_remain_on_chnl_cmd(ar->wmi, vif->fw_vif_idx);
3057}
3058
3059static int ath6kl_send_go_probe_resp(struct ath6kl_vif *vif,
3060                                     const u8 *buf, size_t len,
3061                                     unsigned int freq)
3062{
3063        struct ath6kl *ar = vif->ar;
3064        const u8 *pos;
3065        u8 *p2p;
3066        int p2p_len;
3067        int ret;
3068        const struct ieee80211_mgmt *mgmt;
3069
3070        mgmt = (const struct ieee80211_mgmt *) buf;
3071
3072        /* Include P2P IE(s) from the frame generated in user space. */
3073
3074        p2p = kmalloc(len, GFP_KERNEL);
3075        if (p2p == NULL)
3076                return -ENOMEM;
3077        p2p_len = 0;
3078
3079        pos = mgmt->u.probe_resp.variable;
3080        while (pos + 1 < buf + len) {
3081                if (pos + 2 + pos[1] > buf + len)
3082                        break;
3083                if (ath6kl_is_p2p_ie(pos)) {
3084                        memcpy(p2p + p2p_len, pos, 2 + pos[1]);
3085                        p2p_len += 2 + pos[1];
3086                }
3087                pos += 2 + pos[1];
3088        }
3089
3090        ret = ath6kl_wmi_send_probe_response_cmd(ar->wmi, vif->fw_vif_idx, freq,
3091                                                 mgmt->da, p2p, p2p_len);
3092        kfree(p2p);
3093        return ret;
3094}
3095
3096static bool ath6kl_mgmt_powersave_ap(struct ath6kl_vif *vif,
3097                                     u32 id,
3098                                     u32 freq,
3099                                     u32 wait,
3100                                     const u8 *buf,
3101                                     size_t len,
3102                                     bool *more_data,
3103                                     bool no_cck)
3104{
3105        struct ieee80211_mgmt *mgmt;
3106        struct ath6kl_sta *conn;
3107        bool is_psq_empty = false;
3108        struct ath6kl_mgmt_buff *mgmt_buf;
3109        size_t mgmt_buf_size;
3110        struct ath6kl *ar = vif->ar;
3111
3112        mgmt = (struct ieee80211_mgmt *) buf;
3113        if (is_multicast_ether_addr(mgmt->da))
3114                return false;
3115
3116        conn = ath6kl_find_sta(vif, mgmt->da);
3117        if (!conn)
3118                return false;
3119
3120        if (conn->sta_flags & STA_PS_SLEEP) {
3121                if (!(conn->sta_flags & STA_PS_POLLED)) {
3122                        /* Queue the frames if the STA is sleeping */
3123                        mgmt_buf_size = len + sizeof(struct ath6kl_mgmt_buff);
3124                        mgmt_buf = kmalloc(mgmt_buf_size, GFP_KERNEL);
3125                        if (!mgmt_buf)
3126                                return false;
3127
3128                        INIT_LIST_HEAD(&mgmt_buf->list);
3129                        mgmt_buf->id = id;
3130                        mgmt_buf->freq = freq;
3131                        mgmt_buf->wait = wait;
3132                        mgmt_buf->len = len;
3133                        mgmt_buf->no_cck = no_cck;
3134                        memcpy(mgmt_buf->buf, buf, len);
3135                        spin_lock_bh(&conn->psq_lock);
3136                        is_psq_empty = skb_queue_empty(&conn->psq) &&
3137                                        (conn->mgmt_psq_len == 0);
3138                        list_add_tail(&mgmt_buf->list, &conn->mgmt_psq);
3139                        conn->mgmt_psq_len++;
3140                        spin_unlock_bh(&conn->psq_lock);
3141
3142                        /*
3143                         * If this is the first pkt getting queued
3144                         * for this STA, update the PVB for this
3145                         * STA.
3146                         */
3147                        if (is_psq_empty)
3148                                ath6kl_wmi_set_pvb_cmd(ar->wmi, vif->fw_vif_idx,
3149                                                       conn->aid, 1);
3150                        return true;
3151                }
3152
3153                /*
3154                 * This tx is because of a PsPoll.
3155                 * Determine if MoreData bit has to be set.
3156                 */
3157                spin_lock_bh(&conn->psq_lock);
3158                if (!skb_queue_empty(&conn->psq) || (conn->mgmt_psq_len != 0))
3159                        *more_data = true;
3160                spin_unlock_bh(&conn->psq_lock);
3161        }
3162
3163        return false;
3164}
3165
3166/* Check if SSID length is greater than DIRECT- */
3167static bool ath6kl_is_p2p_go_ssid(const u8 *buf, size_t len)
3168{
3169        const struct ieee80211_mgmt *mgmt;
3170        mgmt = (const struct ieee80211_mgmt *) buf;
3171
3172        /* variable[1] contains the SSID tag length */
3173        if (buf + len >= &mgmt->u.probe_resp.variable[1] &&
3174            (mgmt->u.probe_resp.variable[1] > P2P_WILDCARD_SSID_LEN)) {
3175                return true;
3176        }
3177
3178        return false;
3179}
3180
3181static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
3182                          struct cfg80211_mgmt_tx_params *params, u64 *cookie)
3183{
3184        struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev);
3185        struct ath6kl *ar = ath6kl_priv(vif->ndev);
3186        struct ieee80211_channel *chan = params->chan;
3187        const u8 *buf = params->buf;
3188        size_t len = params->len;
3189        unsigned int wait = params->wait;
3190        bool no_cck = params->no_cck;
3191        u32 id, freq;
3192        const struct ieee80211_mgmt *mgmt;
3193        bool more_data, queued;
3194
3195        /* default to the current channel, but use the one specified as argument
3196         * if any
3197         */
3198        freq = vif->ch_hint;
3199        if (chan)
3200                freq = chan->center_freq;
3201
3202        /* never send freq zero to the firmware */
3203        if (WARN_ON(freq == 0))
3204                return -EINVAL;
3205
3206        mgmt = (const struct ieee80211_mgmt *) buf;
3207        if (vif->nw_type == AP_NETWORK && test_bit(CONNECTED, &vif->flags) &&
3208            ieee80211_is_probe_resp(mgmt->frame_control) &&
3209            ath6kl_is_p2p_go_ssid(buf, len)) {
3210                /*
3211                 * Send Probe Response frame in GO mode using a separate WMI
3212                 * command to allow the target to fill in the generic IEs.
3213                 */
3214                *cookie = 0; /* TX status not supported */
3215                return ath6kl_send_go_probe_resp(vif, buf, len, freq);
3216        }
3217
3218        id = vif->send_action_id++;
3219        if (id == 0) {
3220                /*
3221                 * 0 is a reserved value in the WMI command and shall not be
3222                 * used for the command.
3223                 */
3224                id = vif->send_action_id++;
3225        }
3226
3227        *cookie = id;
3228
3229        /* AP mode Power saving processing */
3230        if (vif->nw_type == AP_NETWORK) {
3231                queued = ath6kl_mgmt_powersave_ap(vif, id, freq, wait, buf, len,
3232                                                  &more_data, no_cck);
3233                if (queued)
3234                        return 0;
3235        }
3236
3237        return ath6kl_wmi_send_mgmt_cmd(ar->wmi, vif->fw_vif_idx, id, freq,
3238                                        wait, buf, len, no_cck);
3239}
3240
3241static int ath6kl_get_antenna(struct wiphy *wiphy,
3242                              u32 *tx_ant, u32 *rx_ant)
3243{
3244        struct ath6kl *ar = wiphy_priv(wiphy);
3245        *tx_ant = ar->hw.tx_ant;
3246        *rx_ant = ar->hw.rx_ant;
3247        return 0;
3248}
3249
3250static void ath6kl_mgmt_frame_register(struct wiphy *wiphy,
3251                                       struct wireless_dev *wdev,
3252                                       u16 frame_type, bool reg)
3253{
3254        struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev);
3255
3256        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: frame_type=0x%x reg=%d\n",
3257                   __func__, frame_type, reg);
3258        if (frame_type == IEEE80211_STYPE_PROBE_REQ) {
3259                /*
3260                 * Note: This notification callback is not allowed to sleep, so
3261                 * we cannot send WMI_PROBE_REQ_REPORT_CMD here. Instead, we
3262                 * hardcode target to report Probe Request frames all the time.
3263                 */
3264                vif->probe_req_report = reg;
3265        }
3266}
3267
3268static 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
3356static int ath6kl_cfg80211_sscan_stop(struct wiphy *wiphy,
3357                                      struct net_device *dev)
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
3370static int ath6kl_cfg80211_set_bitrate(struct wiphy *wiphy,
3371                                       struct net_device *dev,
3372                                       const u8 *addr,
3373                                       const struct cfg80211_bitrate_mask *mask)
3374{
3375        struct ath6kl *ar = ath6kl_priv(dev);
3376        struct ath6kl_vif *vif = netdev_priv(dev);
3377
3378        return ath6kl_wmi_set_bitrate_mask(ar->wmi, vif->fw_vif_idx,
3379                                           mask);
3380}
3381
3382static int ath6kl_cfg80211_set_txe_config(struct wiphy *wiphy,
3383                                          struct net_device *dev,
3384                                          u32 rate, u32 pkts, u32 intvl)
3385{
3386        struct ath6kl *ar = ath6kl_priv(dev);
3387        struct ath6kl_vif *vif = netdev_priv(dev);
3388
3389        if (vif->nw_type != INFRA_NETWORK ||
3390            !test_bit(ATH6KL_FW_CAPABILITY_TX_ERR_NOTIFY, ar->fw_capabilities))
3391                return -EOPNOTSUPP;
3392
3393        if (vif->sme_state != SME_CONNECTED)
3394                return -ENOTCONN;
3395
3396        /* save this since the firmware won't report the interval */
3397        vif->txe_intvl = intvl;
3398
3399        return ath6kl_wmi_set_txe_notify(ar->wmi, vif->fw_vif_idx,
3400                                         rate, pkts, intvl);
3401}
3402
3403static const struct ieee80211_txrx_stypes
3404ath6kl_mgmt_stypes[NUM_NL80211_IFTYPES] = {
3405        [NL80211_IFTYPE_STATION] = {
3406                .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3407                BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
3408                .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3409                BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
3410        },
3411        [NL80211_IFTYPE_AP] = {
3412                .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3413                BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
3414                .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3415                BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
3416        },
3417        [NL80211_IFTYPE_P2P_CLIENT] = {
3418                .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3419                BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
3420                .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3421                BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
3422        },
3423        [NL80211_IFTYPE_P2P_GO] = {
3424                .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3425                BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
3426                .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3427                BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
3428        },
3429};
3430
3431static struct cfg80211_ops ath6kl_cfg80211_ops = {
3432        .add_virtual_intf = ath6kl_cfg80211_add_iface,
3433        .del_virtual_intf = ath6kl_cfg80211_del_iface,
3434        .change_virtual_intf = ath6kl_cfg80211_change_iface,
3435        .scan = ath6kl_cfg80211_scan,
3436        .connect = ath6kl_cfg80211_connect,
3437        .disconnect = ath6kl_cfg80211_disconnect,
3438        .add_key = ath6kl_cfg80211_add_key,
3439        .get_key = ath6kl_cfg80211_get_key,
3440        .del_key = ath6kl_cfg80211_del_key,
3441        .set_default_key = ath6kl_cfg80211_set_default_key,
3442        .set_wiphy_params = ath6kl_cfg80211_set_wiphy_params,
3443        .set_tx_power = ath6kl_cfg80211_set_txpower,
3444        .get_tx_power = ath6kl_cfg80211_get_txpower,
3445        .set_power_mgmt = ath6kl_cfg80211_set_power_mgmt,
3446        .join_ibss = ath6kl_cfg80211_join_ibss,
3447        .leave_ibss = ath6kl_cfg80211_leave_ibss,
3448        .get_station = ath6kl_get_station,
3449        .set_pmksa = ath6kl_set_pmksa,
3450        .del_pmksa = ath6kl_del_pmksa,
3451        .flush_pmksa = ath6kl_flush_pmksa,
3452        CFG80211_TESTMODE_CMD(ath6kl_tm_cmd)
3453#ifdef CONFIG_PM
3454        .suspend = __ath6kl_cfg80211_suspend,
3455        .resume = __ath6kl_cfg80211_resume,
3456#endif
3457        .start_ap = ath6kl_start_ap,
3458        .change_beacon = ath6kl_change_beacon,
3459        .stop_ap = ath6kl_stop_ap,
3460        .del_station = ath6kl_del_station,
3461        .change_station = ath6kl_change_station,
3462        .remain_on_channel = ath6kl_remain_on_channel,
3463        .cancel_remain_on_channel = ath6kl_cancel_remain_on_channel,
3464        .mgmt_tx = ath6kl_mgmt_tx,
3465        .mgmt_frame_register = ath6kl_mgmt_frame_register,
3466        .get_antenna = ath6kl_get_antenna,
3467        .sched_scan_start = ath6kl_cfg80211_sscan_start,
3468        .sched_scan_stop = ath6kl_cfg80211_sscan_stop,
3469        .set_bitrate_mask = ath6kl_cfg80211_set_bitrate,
3470        .set_cqm_txe_config = ath6kl_cfg80211_set_txe_config,
3471};
3472
3473void ath6kl_cfg80211_stop(struct ath6kl_vif *vif)
3474{
3475        ath6kl_cfg80211_sscan_disable(vif);
3476
3477        switch (vif->sme_state) {
3478        case SME_DISCONNECTED:
3479                break;
3480        case SME_CONNECTING:
3481                cfg80211_connect_result(vif->ndev, vif->bssid, NULL, 0,
3482                                        NULL, 0,
3483                                        WLAN_STATUS_UNSPECIFIED_FAILURE,
3484                                        GFP_KERNEL);
3485                break;
3486        case SME_CONNECTED:
3487                cfg80211_disconnected(vif->ndev, 0, NULL, 0, true, GFP_KERNEL);
3488                break;
3489        }
3490
3491        if (vif->ar->state != ATH6KL_STATE_RECOVERY &&
3492            (test_bit(CONNECTED, &vif->flags) ||
3493            test_bit(CONNECT_PEND, &vif->flags)))
3494                ath6kl_wmi_disconnect_cmd(vif->ar->wmi, vif->fw_vif_idx);
3495
3496        vif->sme_state = SME_DISCONNECTED;
3497        clear_bit(CONNECTED, &vif->flags);
3498        clear_bit(CONNECT_PEND, &vif->flags);
3499
3500        /* Stop netdev queues, needed during recovery */
3501        netif_stop_queue(vif->ndev);
3502        netif_carrier_off(vif->ndev);
3503
3504        /* disable scanning */
3505        if (vif->ar->state != ATH6KL_STATE_RECOVERY &&
3506            ath6kl_wmi_scanparams_cmd(vif->ar->wmi, vif->fw_vif_idx, 0xFFFF,
3507                                      0, 0, 0, 0, 0, 0, 0, 0, 0) != 0)
3508                ath6kl_warn("failed to disable scan during stop\n");
3509
3510        ath6kl_cfg80211_scan_complete_event(vif, true);
3511}
3512
3513void ath6kl_cfg80211_stop_all(struct ath6kl *ar)
3514{
3515        struct ath6kl_vif *vif;
3516
3517        vif = ath6kl_vif_first(ar);
3518        if (!vif && ar->state != ATH6KL_STATE_RECOVERY) {
3519                /* save the current power mode before enabling power save */
3520                ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode;
3521
3522                if (ath6kl_wmi_powermode_cmd(ar->wmi, 0, REC_POWER) != 0)
3523                        ath6kl_warn("ath6kl_deep_sleep_enable: wmi_powermode_cmd failed\n");
3524                return;
3525        }
3526
3527        /*
3528         * FIXME: we should take ar->list_lock to protect changes in the
3529         * vif_list, but that's not trivial to do as ath6kl_cfg80211_stop()
3530         * sleeps.
3531         */
3532        list_for_each_entry(vif, &ar->vif_list, list)
3533                ath6kl_cfg80211_stop(vif);
3534}
3535
3536static void ath6kl_cfg80211_reg_notify(struct wiphy *wiphy,
3537                                       struct regulatory_request *request)
3538{
3539        struct ath6kl *ar = wiphy_priv(wiphy);
3540        u32 rates[NUM_NL80211_BANDS];
3541        int ret, i;
3542
3543        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
3544                   "cfg reg_notify %c%c%s%s initiator %d hint_type %d\n",
3545                   request->alpha2[0], request->alpha2[1],
3546                   request->intersect ? " intersect" : "",
3547                   request->processed ? " processed" : "",
3548                   request->initiator, request->user_reg_hint_type);
3549
3550        if (request->user_reg_hint_type != NL80211_USER_REG_HINT_CELL_BASE)
3551                return;
3552
3553        ret = ath6kl_wmi_set_regdomain_cmd(ar->wmi, request->alpha2);
3554        if (ret) {
3555                ath6kl_err("failed to set regdomain: %d\n", ret);
3556                return;
3557        }
3558
3559        /*
3560         * Firmware will apply the regdomain change only after a scan is
3561         * issued and it will send a WMI_REGDOMAIN_EVENTID when it has been
3562         * changed.
3563         */
3564
3565        for (i = 0; i < NUM_NL80211_BANDS; i++)
3566                if (wiphy->bands[i])
3567                        rates[i] = (1 << wiphy->bands[i]->n_bitrates) - 1;
3568
3569
3570        ret = ath6kl_wmi_beginscan_cmd(ar->wmi, 0, WMI_LONG_SCAN, false,
3571                                       false, 0, ATH6KL_FG_SCAN_INTERVAL,
3572                                       0, NULL, false, rates);
3573        if (ret) {
3574                ath6kl_err("failed to start scan for a regdomain change: %d\n",
3575                           ret);
3576                return;
3577        }
3578}
3579
3580static int ath6kl_cfg80211_vif_init(struct ath6kl_vif *vif)
3581{
3582        vif->aggr_cntxt = aggr_init(vif);
3583        if (!vif->aggr_cntxt) {
3584                ath6kl_err("failed to initialize aggr\n");
3585                return -ENOMEM;
3586        }
3587
3588        setup_timer(&vif->disconnect_timer, disconnect_timer_handler,
3589                    (unsigned long) vif->ndev);
3590        setup_timer(&vif->sched_scan_timer, ath6kl_wmi_sscan_timer,
3591                    (unsigned long) vif);
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
3601void 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
3636void 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        unregister_netdevice(vif->ndev);
3654
3655        ar->num_vif--;
3656}
3657
3658static 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
3685static 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
3697static 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. */
3761static 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
3771static 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
3779struct 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
3787        ndev = alloc_netdev(sizeof(*vif), name, name_assign_type, ether_setup);
3788        if (!ndev)
3789                return NULL;
3790
3791        vif = netdev_priv(ndev);
3792        ndev->ieee80211_ptr = &vif->wdev;
3793        vif->wdev.wiphy = ar->wiphy;
3794        vif->ar = ar;
3795        vif->ndev = ndev;
3796        SET_NETDEV_DEV(ndev, wiphy_dev(vif->wdev.wiphy));
3797        vif->wdev.netdev = ndev;
3798        vif->wdev.iftype = type;
3799        vif->fw_vif_idx = fw_vif_idx;
3800        vif->nw_type = nw_type;
3801        vif->next_mode = nw_type;
3802        vif->listen_intvl_t = ATH6KL_DEFAULT_LISTEN_INTVAL;
3803        vif->bmiss_time_t = ATH6KL_DEFAULT_BMISS_TIME;
3804        vif->bg_scan_period = 0;
3805        vif->htcap[NL80211_BAND_2GHZ].ht_enable = true;
3806        vif->htcap[NL80211_BAND_5GHZ].ht_enable = true;
3807
3808        memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN);
3809        if (fw_vif_idx != 0) {
3810                ndev->dev_addr[0] = (ndev->dev_addr[0] ^ (1 << fw_vif_idx)) |
3811                                     0x2;
3812                if (test_bit(ATH6KL_FW_CAPABILITY_CUSTOM_MAC_ADDR,
3813                             ar->fw_capabilities))
3814                        ndev->dev_addr[4] ^= 0x80;
3815        }
3816
3817        init_netdev(ndev);
3818
3819        ath6kl_init_control_info(vif);
3820
3821        if (ath6kl_cfg80211_vif_init(vif))
3822                goto err;
3823
3824        netdev_set_default_ethtool_ops(ndev, &ath6kl_ethtool_ops);
3825
3826        if (register_netdevice(ndev))
3827                goto err;
3828
3829        ar->avail_idx_map &= ~BIT(fw_vif_idx);
3830        vif->sme_state = SME_DISCONNECTED;
3831        set_bit(WLAN_ENABLED, &vif->flags);
3832        ar->wlan_pwr_state = WLAN_POWER_STATE_ON;
3833
3834        if (type == NL80211_IFTYPE_ADHOC)
3835                ar->ibss_if_active = true;
3836
3837        spin_lock_bh(&ar->list_lock);
3838        list_add_tail(&vif->list, &ar->vif_list);
3839        spin_unlock_bh(&ar->list_lock);
3840
3841        return &vif->wdev;
3842
3843err:
3844        aggr_module_destroy(vif->aggr_cntxt);
3845        free_netdev(ndev);
3846        return NULL;
3847}
3848
3849#ifdef CONFIG_PM
3850static const struct wiphy_wowlan_support ath6kl_wowlan_support = {
3851        .flags = WIPHY_WOWLAN_MAGIC_PKT |
3852                 WIPHY_WOWLAN_DISCONNECT |
3853                 WIPHY_WOWLAN_GTK_REKEY_FAILURE  |
3854                 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
3855                 WIPHY_WOWLAN_EAP_IDENTITY_REQ   |
3856                 WIPHY_WOWLAN_4WAY_HANDSHAKE,
3857        .n_patterns = WOW_MAX_FILTERS_PER_LIST,
3858        .pattern_min_len = 1,
3859        .pattern_max_len = WOW_PATTERN_SIZE,
3860};
3861#endif
3862
3863int ath6kl_cfg80211_init(struct ath6kl *ar)
3864{
3865        struct wiphy *wiphy = ar->wiphy;
3866        bool band_2gig = false, band_5gig = false, ht = false;
3867        int ret;
3868
3869        wiphy->mgmt_stypes = ath6kl_mgmt_stypes;
3870
3871        wiphy->max_remain_on_channel_duration = 5000;
3872
3873        /* set device pointer for wiphy */
3874        set_wiphy_dev(wiphy, ar->dev);
3875
3876        wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
3877                                 BIT(NL80211_IFTYPE_ADHOC) |
3878                                 BIT(NL80211_IFTYPE_AP);
3879        if (ar->p2p) {
3880                wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_GO) |
3881                                          BIT(NL80211_IFTYPE_P2P_CLIENT);
3882        }
3883
3884        if (IS_ENABLED(CONFIG_ATH6KL_REGDOMAIN) &&
3885            test_bit(ATH6KL_FW_CAPABILITY_REGDOMAIN, ar->fw_capabilities)) {
3886                wiphy->reg_notifier = ath6kl_cfg80211_reg_notify;
3887                ar->wiphy->features |= NL80211_FEATURE_CELL_BASE_REG_HINTS;
3888        }
3889
3890        /* max num of ssids that can be probed during scanning */
3891        wiphy->max_scan_ssids = MAX_PROBED_SSIDS;
3892
3893        /* max num of ssids that can be matched after scan */
3894        if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN_MATCH_LIST,
3895                     ar->fw_capabilities))
3896                wiphy->max_match_sets = MAX_PROBED_SSIDS;
3897
3898        wiphy->max_scan_ie_len = 1000; /* FIX: what is correct limit? */
3899        switch (ar->hw.cap) {
3900        case WMI_11AN_CAP:
3901                ht = true;
3902        case WMI_11A_CAP:
3903                band_5gig = true;
3904                break;
3905        case WMI_11GN_CAP:
3906                ht = true;
3907        case WMI_11G_CAP:
3908                band_2gig = true;
3909                break;
3910        case WMI_11AGN_CAP:
3911                ht = true;
3912        case WMI_11AG_CAP:
3913                band_2gig = true;
3914                band_5gig = true;
3915                break;
3916        default:
3917                ath6kl_err("invalid phy capability!\n");
3918                return -EINVAL;
3919        }
3920
3921        /*
3922         * Even if the fw has HT support, advertise HT cap only when
3923         * the firmware has support to override RSN capability, otherwise
3924         * 4-way handshake would fail.
3925         */
3926        if (!(ht &&
3927              test_bit(ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE,
3928                       ar->fw_capabilities))) {
3929                ath6kl_band_2ghz.ht_cap.cap = 0;
3930                ath6kl_band_2ghz.ht_cap.ht_supported = false;
3931                ath6kl_band_5ghz.ht_cap.cap = 0;
3932                ath6kl_band_5ghz.ht_cap.ht_supported = false;
3933
3934                if (ht)
3935                        ath6kl_err("Firmware lacks RSN-CAP-OVERRIDE, so HT (802.11n) is disabled.");
3936        }
3937
3938        if (test_bit(ATH6KL_FW_CAPABILITY_64BIT_RATES,
3939                     ar->fw_capabilities)) {
3940                ath6kl_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3941                ath6kl_band_5ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3942                ath6kl_band_2ghz.ht_cap.mcs.rx_mask[1] = 0xff;
3943                ath6kl_band_5ghz.ht_cap.mcs.rx_mask[1] = 0xff;
3944                ar->hw.tx_ant = 0x3; /* mask, 2 antenna */
3945                ar->hw.rx_ant = 0x3;
3946        } else {
3947                ath6kl_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3948                ath6kl_band_5ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3949                ar->hw.tx_ant = 1;
3950                ar->hw.rx_ant = 1;
3951        }
3952
3953        wiphy->available_antennas_tx = ar->hw.tx_ant;
3954        wiphy->available_antennas_rx = ar->hw.rx_ant;
3955
3956        if (band_2gig)
3957                wiphy->bands[NL80211_BAND_2GHZ] = &ath6kl_band_2ghz;
3958        if (band_5gig)
3959                wiphy->bands[NL80211_BAND_5GHZ] = &ath6kl_band_5ghz;
3960
3961        wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
3962
3963        wiphy->cipher_suites = cipher_suites;
3964        wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
3965
3966#ifdef CONFIG_PM
3967        wiphy->wowlan = &ath6kl_wowlan_support;
3968#endif
3969
3970        wiphy->max_sched_scan_ssids = MAX_PROBED_SSIDS;
3971
3972        ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM |
3973                            WIPHY_FLAG_HAVE_AP_SME |
3974                            WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
3975                            WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
3976
3977        if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN_V2, ar->fw_capabilities))
3978                ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
3979
3980        if (test_bit(ATH6KL_FW_CAPABILITY_INACTIVITY_TIMEOUT,
3981                     ar->fw_capabilities))
3982                ar->wiphy->features |= NL80211_FEATURE_INACTIVITY_TIMER;
3983
3984        ar->wiphy->probe_resp_offload =
3985                NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
3986                NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
3987                NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P;
3988
3989        ret = wiphy_register(wiphy);
3990        if (ret < 0) {
3991                ath6kl_err("couldn't register wiphy device\n");
3992                return ret;
3993        }
3994
3995        ar->wiphy_registered = true;
3996
3997        return 0;
3998}
3999
4000void ath6kl_cfg80211_cleanup(struct ath6kl *ar)
4001{
4002        wiphy_unregister(ar->wiphy);
4003
4004        ar->wiphy_registered = false;
4005}
4006
4007struct ath6kl *ath6kl_cfg80211_create(void)
4008{
4009        struct ath6kl *ar;
4010        struct wiphy *wiphy;
4011
4012        /* create a new wiphy for use with cfg80211 */
4013        wiphy = wiphy_new(&ath6kl_cfg80211_ops, sizeof(struct ath6kl));
4014
4015        if (!wiphy) {
4016                ath6kl_err("couldn't allocate wiphy device\n");
4017                return NULL;
4018        }
4019
4020        ar = wiphy_priv(wiphy);
4021        ar->wiphy = wiphy;
4022
4023        return ar;
4024}
4025
4026/* Note: ar variable must not be accessed after calling this! */
4027void ath6kl_cfg80211_destroy(struct ath6kl *ar)
4028{
4029        int i;
4030
4031        for (i = 0; i < AP_MAX_NUM_STA; i++)
4032                kfree(ar->sta_list[i].aggr_conn);
4033
4034        wiphy_free(ar->wiphy);
4035}
4036
4037