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           = IEEE80211_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           = IEEE80211_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_mask, cap_val;
 690        u8 *ie;
 691
 692        if (nw_type & ADHOC_NETWORK) {
 693                cap_mask = WLAN_CAPABILITY_IBSS;
 694                cap_val = WLAN_CAPABILITY_IBSS;
 695        } else {
 696                cap_mask = WLAN_CAPABILITY_ESS;
 697                cap_val = WLAN_CAPABILITY_ESS;
 698        }
 699
 700        bss = cfg80211_get_bss(ar->wiphy, chan, bssid,
 701                               vif->ssid, vif->ssid_len,
 702                               cap_mask, cap_val);
 703        if (bss == NULL) {
 704                /*
 705                 * Since cfg80211 may not yet know about the BSS,
 706                 * generate a partial entry until the first BSS info
 707                 * event becomes available.
 708                 *
 709                 * Prepend SSID element since it is not included in the Beacon
 710                 * IEs from the target.
 711                 */
 712                ie = kmalloc(2 + vif->ssid_len + beacon_ie_len, GFP_KERNEL);
 713                if (ie == NULL)
 714                        return NULL;
 715                ie[0] = WLAN_EID_SSID;
 716                ie[1] = vif->ssid_len;
 717                memcpy(ie + 2, vif->ssid, vif->ssid_len);
 718                memcpy(ie + 2 + vif->ssid_len, beacon_ie, beacon_ie_len);
 719                bss = cfg80211_inform_bss(ar->wiphy, chan,
 720                                          bssid, 0, cap_val, 100,
 721                                          ie, 2 + vif->ssid_len + beacon_ie_len,
 722                                          0, GFP_KERNEL);
 723                if (bss)
 724                        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
 725                                   "added bss %pM to cfg80211\n", bssid);
 726                kfree(ie);
 727        } else {
 728                ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "cfg80211 already has a bss\n");
 729        }
 730
 731        return bss;
 732}
 733
 734void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel,
 735                                   u8 *bssid, u16 listen_intvl,
 736                                   u16 beacon_intvl,
 737                                   enum network_type nw_type,
 738                                   u8 beacon_ie_len, u8 assoc_req_len,
 739                                   u8 assoc_resp_len, u8 *assoc_info)
 740{
 741        struct ieee80211_channel *chan;
 742        struct ath6kl *ar = vif->ar;
 743        struct cfg80211_bss *bss;
 744
 745        /* capinfo + listen interval */
 746        u8 assoc_req_ie_offset = sizeof(u16) + sizeof(u16);
 747
 748        /* capinfo + status code +  associd */
 749        u8 assoc_resp_ie_offset = sizeof(u16) + sizeof(u16) + sizeof(u16);
 750
 751        u8 *assoc_req_ie = assoc_info + beacon_ie_len + assoc_req_ie_offset;
 752        u8 *assoc_resp_ie = assoc_info + beacon_ie_len + assoc_req_len +
 753            assoc_resp_ie_offset;
 754
 755        assoc_req_len -= assoc_req_ie_offset;
 756        assoc_resp_len -= assoc_resp_ie_offset;
 757
 758        /*
 759         * Store Beacon interval here; DTIM period will be available only once
 760         * a Beacon frame from the AP is seen.
 761         */
 762        vif->assoc_bss_beacon_int = beacon_intvl;
 763        clear_bit(DTIM_PERIOD_AVAIL, &vif->flags);
 764
 765        if (nw_type & ADHOC_NETWORK) {
 766                if (vif->wdev.iftype != NL80211_IFTYPE_ADHOC) {
 767                        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
 768                                   "%s: ath6k not in ibss mode\n", __func__);
 769                        return;
 770                }
 771        }
 772
 773        if (nw_type & INFRA_NETWORK) {
 774                if (vif->wdev.iftype != NL80211_IFTYPE_STATION &&
 775                    vif->wdev.iftype != NL80211_IFTYPE_P2P_CLIENT) {
 776                        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
 777                                   "%s: ath6k not in station mode\n", __func__);
 778                        return;
 779                }
 780        }
 781
 782        chan = ieee80211_get_channel(ar->wiphy, (int) channel);
 783
 784        bss = ath6kl_add_bss_if_needed(vif, nw_type, bssid, chan,
 785                                       assoc_info, beacon_ie_len);
 786        if (!bss) {
 787                ath6kl_err("could not add cfg80211 bss entry\n");
 788                return;
 789        }
 790
 791        if (nw_type & ADHOC_NETWORK) {
 792                ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "ad-hoc %s selected\n",
 793                           nw_type & ADHOC_CREATOR ? "creator" : "joiner");
 794                cfg80211_ibss_joined(vif->ndev, bssid, chan, GFP_KERNEL);
 795                cfg80211_put_bss(ar->wiphy, bss);
 796                return;
 797        }
 798
 799        if (vif->sme_state == SME_CONNECTING) {
 800                /* inform connect result to cfg80211 */
 801                vif->sme_state = SME_CONNECTED;
 802                cfg80211_connect_result(vif->ndev, bssid,
 803                                        assoc_req_ie, assoc_req_len,
 804                                        assoc_resp_ie, assoc_resp_len,
 805                                        WLAN_STATUS_SUCCESS, GFP_KERNEL);
 806                cfg80211_put_bss(ar->wiphy, bss);
 807        } else if (vif->sme_state == SME_CONNECTED) {
 808                /* inform roam event to cfg80211 */
 809                cfg80211_roamed_bss(vif->ndev, bss, assoc_req_ie, assoc_req_len,
 810                                    assoc_resp_ie, assoc_resp_len, GFP_KERNEL);
 811        }
 812}
 813
 814static int ath6kl_cfg80211_disconnect(struct wiphy *wiphy,
 815                                      struct net_device *dev, u16 reason_code)
 816{
 817        struct ath6kl *ar = ath6kl_priv(dev);
 818        struct ath6kl_vif *vif = netdev_priv(dev);
 819
 820        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: reason=%u\n", __func__,
 821                   reason_code);
 822
 823        ath6kl_cfg80211_sscan_disable(vif);
 824
 825        if (!ath6kl_cfg80211_ready(vif))
 826                return -EIO;
 827
 828        if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
 829                ath6kl_err("busy, destroy in progress\n");
 830                return -EBUSY;
 831        }
 832
 833        if (down_interruptible(&ar->sem)) {
 834                ath6kl_err("busy, couldn't get access\n");
 835                return -ERESTARTSYS;
 836        }
 837
 838        vif->reconnect_flag = 0;
 839        ath6kl_disconnect(vif);
 840        memset(vif->ssid, 0, sizeof(vif->ssid));
 841        vif->ssid_len = 0;
 842
 843        if (!test_bit(SKIP_SCAN, &ar->flag))
 844                memset(vif->req_bssid, 0, sizeof(vif->req_bssid));
 845
 846        up(&ar->sem);
 847
 848        vif->sme_state = SME_DISCONNECTED;
 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                cfg80211_scan_done(vif->scan_req, true);
 861                vif->scan_req = NULL;
 862        }
 863
 864        if (vif->nw_type & ADHOC_NETWORK) {
 865                if (vif->wdev.iftype != NL80211_IFTYPE_ADHOC)
 866                        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
 867                                   "%s: ath6k not in ibss mode\n", __func__);
 868                return;
 869        }
 870
 871        if (vif->nw_type & INFRA_NETWORK) {
 872                if (vif->wdev.iftype != NL80211_IFTYPE_STATION &&
 873                    vif->wdev.iftype != NL80211_IFTYPE_P2P_CLIENT) {
 874                        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
 875                                   "%s: ath6k not in station mode\n", __func__);
 876                        return;
 877                }
 878        }
 879
 880        clear_bit(CONNECT_PEND, &vif->flags);
 881
 882        if (vif->sme_state == SME_CONNECTING) {
 883                cfg80211_connect_result(vif->ndev,
 884                                        bssid, NULL, 0,
 885                                        NULL, 0,
 886                                        WLAN_STATUS_UNSPECIFIED_FAILURE,
 887                                        GFP_KERNEL);
 888        } else if (vif->sme_state == SME_CONNECTED) {
 889                cfg80211_disconnected(vif->ndev, proto_reason,
 890                                      NULL, 0, GFP_KERNEL);
 891        }
 892
 893        vif->sme_state = SME_DISCONNECTED;
 894
 895        /*
 896         * Send a disconnect command to target when a disconnect event is
 897         * received with reason code other than 3 (DISCONNECT_CMD - disconnect
 898         * request from host) to make the firmware stop trying to connect even
 899         * after giving disconnect event. There will be one more disconnect
 900         * event for this disconnect command with reason code DISCONNECT_CMD
 901         * which won't be notified to cfg80211.
 902         */
 903        if (reason != DISCONNECT_CMD)
 904                ath6kl_wmi_disconnect_cmd(ar->wmi, vif->fw_vif_idx);
 905}
 906
 907static int ath6kl_set_probed_ssids(struct ath6kl *ar,
 908                                   struct ath6kl_vif *vif,
 909                                   struct cfg80211_ssid *ssids, int n_ssids,
 910                                   struct cfg80211_match_set *match_set,
 911                                   int n_match_ssid)
 912{
 913        u8 i, j, index_to_add, ssid_found = false;
 914        struct ath6kl_cfg80211_match_probe_ssid ssid_list[MAX_PROBED_SSIDS];
 915
 916        memset(ssid_list, 0, sizeof(ssid_list));
 917
 918        if (n_ssids > MAX_PROBED_SSIDS ||
 919            n_match_ssid > MAX_PROBED_SSIDS)
 920                return -EINVAL;
 921
 922        for (i = 0; i < n_ssids; i++) {
 923                memcpy(ssid_list[i].ssid.ssid,
 924                       ssids[i].ssid,
 925                       ssids[i].ssid_len);
 926                ssid_list[i].ssid.ssid_len = ssids[i].ssid_len;
 927
 928                if (ssids[i].ssid_len)
 929                        ssid_list[i].flag = SPECIFIC_SSID_FLAG;
 930                else
 931                        ssid_list[i].flag = ANY_SSID_FLAG;
 932
 933                if (n_match_ssid == 0)
 934                        ssid_list[i].flag |= MATCH_SSID_FLAG;
 935        }
 936
 937        index_to_add = i;
 938
 939        for (i = 0; i < n_match_ssid; i++) {
 940                ssid_found = false;
 941
 942                for (j = 0; j < n_ssids; j++) {
 943                        if ((match_set[i].ssid.ssid_len ==
 944                             ssid_list[j].ssid.ssid_len) &&
 945                            (!memcmp(ssid_list[j].ssid.ssid,
 946                                     match_set[i].ssid.ssid,
 947                                     match_set[i].ssid.ssid_len))) {
 948                                ssid_list[j].flag |= MATCH_SSID_FLAG;
 949                                ssid_found = true;
 950                                break;
 951                        }
 952                }
 953
 954                if (ssid_found)
 955                        continue;
 956
 957                if (index_to_add >= MAX_PROBED_SSIDS)
 958                        continue;
 959
 960                ssid_list[index_to_add].ssid.ssid_len =
 961                        match_set[i].ssid.ssid_len;
 962                memcpy(ssid_list[index_to_add].ssid.ssid,
 963                       match_set[i].ssid.ssid,
 964                       match_set[i].ssid.ssid_len);
 965                ssid_list[index_to_add].flag |= MATCH_SSID_FLAG;
 966                index_to_add++;
 967        }
 968
 969        for (i = 0; i < index_to_add; i++) {
 970                ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx, i,
 971                                          ssid_list[i].flag,
 972                                          ssid_list[i].ssid.ssid_len,
 973                                          ssid_list[i].ssid.ssid);
 974        }
 975
 976        /* Make sure no old entries are left behind */
 977        for (i = index_to_add; i < MAX_PROBED_SSIDS; i++) {
 978                ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx, i,
 979                                          DISABLE_SSID_FLAG, 0, NULL);
 980        }
 981
 982        return 0;
 983}
 984
 985static int ath6kl_cfg80211_scan(struct wiphy *wiphy,
 986                                struct cfg80211_scan_request *request)
 987{
 988        struct ath6kl_vif *vif = ath6kl_vif_from_wdev(request->wdev);
 989        struct ath6kl *ar = ath6kl_priv(vif->ndev);
 990        s8 n_channels = 0;
 991        u16 *channels = NULL;
 992        int ret = 0;
 993        u32 force_fg_scan = 0;
 994
 995        if (!ath6kl_cfg80211_ready(vif))
 996                return -EIO;
 997
 998        ath6kl_cfg80211_sscan_disable(vif);
 999
1000        if (!ar->usr_bss_filter) {
1001                clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags);
1002                ret = ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
1003                                               ALL_BSS_FILTER, 0);
1004                if (ret) {
1005                        ath6kl_err("couldn't set bss filtering\n");
1006                        return ret;
1007                }
1008        }
1009
1010        ret = ath6kl_set_probed_ssids(ar, vif, request->ssids,
1011                                      request->n_ssids, NULL, 0);
1012        if (ret < 0)
1013                return ret;
1014
1015        /* this also clears IE in fw if it's not set */
1016        ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
1017                                       WMI_FRAME_PROBE_REQ,
1018                                       request->ie, request->ie_len);
1019        if (ret) {
1020                ath6kl_err("failed to set Probe Request appie for scan\n");
1021                return ret;
1022        }
1023
1024        /*
1025         * Scan only the requested channels if the request specifies a set of
1026         * channels. If the list is longer than the target supports, do not
1027         * configure the list and instead, scan all available channels.
1028         */
1029        if (request->n_channels > 0 &&
1030            request->n_channels <= WMI_MAX_CHANNELS) {
1031                u8 i;
1032
1033                n_channels = request->n_channels;
1034
1035                channels = kzalloc(n_channels * sizeof(u16), GFP_KERNEL);
1036                if (channels == NULL) {
1037                        ath6kl_warn("failed to set scan channels, scan all channels");
1038                        n_channels = 0;
1039                }
1040
1041                for (i = 0; i < n_channels; i++)
1042                        channels[i] = request->channels[i]->center_freq;
1043        }
1044
1045        if (test_bit(CONNECTED, &vif->flags))
1046                force_fg_scan = 1;
1047
1048        vif->scan_req = request;
1049
1050        ret = ath6kl_wmi_beginscan_cmd(ar->wmi, vif->fw_vif_idx,
1051                                       WMI_LONG_SCAN, force_fg_scan,
1052                                       false, 0,
1053                                       ATH6KL_FG_SCAN_INTERVAL,
1054                                       n_channels, channels,
1055                                       request->no_cck,
1056                                       request->rates);
1057        if (ret) {
1058                ath6kl_err("failed to start scan: %d\n", ret);
1059                vif->scan_req = NULL;
1060        }
1061
1062        kfree(channels);
1063
1064        return ret;
1065}
1066
1067void ath6kl_cfg80211_scan_complete_event(struct ath6kl_vif *vif, bool aborted)
1068{
1069        struct ath6kl *ar = vif->ar;
1070        int i;
1071
1072        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: status%s\n", __func__,
1073                   aborted ? " aborted" : "");
1074
1075        if (!vif->scan_req)
1076                return;
1077
1078        if (aborted)
1079                goto out;
1080
1081        if (vif->scan_req->n_ssids && vif->scan_req->ssids[0].ssid_len) {
1082                for (i = 0; i < vif->scan_req->n_ssids; i++) {
1083                        ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx,
1084                                                  i + 1, DISABLE_SSID_FLAG,
1085                                                  0, NULL);
1086                }
1087        }
1088
1089out:
1090        cfg80211_scan_done(vif->scan_req, aborted);
1091        vif->scan_req = NULL;
1092}
1093
1094void ath6kl_cfg80211_ch_switch_notify(struct ath6kl_vif *vif, int freq,
1095                                      enum wmi_phy_mode mode)
1096{
1097        struct cfg80211_chan_def chandef;
1098
1099        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1100                   "channel switch notify nw_type %d freq %d mode %d\n",
1101                   vif->nw_type, freq, mode);
1102
1103        cfg80211_chandef_create(&chandef,
1104                                ieee80211_get_channel(vif->ar->wiphy, freq),
1105                                (mode == WMI_11G_HT20) ?
1106                                        NL80211_CHAN_HT20 : NL80211_CHAN_NO_HT);
1107
1108        mutex_lock(&vif->wdev.mtx);
1109        cfg80211_ch_switch_notify(vif->ndev, &chandef);
1110        mutex_unlock(&vif->wdev.mtx);
1111}
1112
1113static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
1114                                   u8 key_index, bool pairwise,
1115                                   const u8 *mac_addr,
1116                                   struct key_params *params)
1117{
1118        struct ath6kl *ar = ath6kl_priv(ndev);
1119        struct ath6kl_vif *vif = netdev_priv(ndev);
1120        struct ath6kl_key *key = NULL;
1121        int seq_len;
1122        u8 key_usage;
1123        u8 key_type;
1124
1125        if (!ath6kl_cfg80211_ready(vif))
1126                return -EIO;
1127
1128        if (params->cipher == CCKM_KRK_CIPHER_SUITE) {
1129                if (params->key_len != WMI_KRK_LEN)
1130                        return -EINVAL;
1131                return ath6kl_wmi_add_krk_cmd(ar->wmi, vif->fw_vif_idx,
1132                                              params->key);
1133        }
1134
1135        if (key_index > WMI_MAX_KEY_INDEX) {
1136                ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1137                           "%s: key index %d out of bounds\n", __func__,
1138                           key_index);
1139                return -ENOENT;
1140        }
1141
1142        key = &vif->keys[key_index];
1143        memset(key, 0, sizeof(struct ath6kl_key));
1144
1145        if (pairwise)
1146                key_usage = PAIRWISE_USAGE;
1147        else
1148                key_usage = GROUP_USAGE;
1149
1150        seq_len = params->seq_len;
1151        if (params->cipher == WLAN_CIPHER_SUITE_SMS4 &&
1152            seq_len > ATH6KL_KEY_SEQ_LEN) {
1153                /* Only first half of the WPI PN is configured */
1154                seq_len = ATH6KL_KEY_SEQ_LEN;
1155        }
1156        if (params->key_len > WLAN_MAX_KEY_LEN ||
1157            seq_len > sizeof(key->seq))
1158                return -EINVAL;
1159
1160        key->key_len = params->key_len;
1161        memcpy(key->key, params->key, key->key_len);
1162        key->seq_len = seq_len;
1163        memcpy(key->seq, params->seq, key->seq_len);
1164        key->cipher = params->cipher;
1165
1166        switch (key->cipher) {
1167        case WLAN_CIPHER_SUITE_WEP40:
1168        case WLAN_CIPHER_SUITE_WEP104:
1169                key_type = WEP_CRYPT;
1170                break;
1171
1172        case WLAN_CIPHER_SUITE_TKIP:
1173                key_type = TKIP_CRYPT;
1174                break;
1175
1176        case WLAN_CIPHER_SUITE_CCMP:
1177                key_type = AES_CRYPT;
1178                break;
1179        case WLAN_CIPHER_SUITE_SMS4:
1180                key_type = WAPI_CRYPT;
1181                break;
1182
1183        default:
1184                return -ENOTSUPP;
1185        }
1186
1187        if (((vif->auth_mode == WPA_PSK_AUTH) ||
1188             (vif->auth_mode == WPA2_PSK_AUTH)) &&
1189            (key_usage & GROUP_USAGE))
1190                del_timer(&vif->disconnect_timer);
1191
1192        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1193                   "%s: index %d, key_len %d, key_type 0x%x, key_usage 0x%x, seq_len %d\n",
1194                   __func__, key_index, key->key_len, key_type,
1195                   key_usage, key->seq_len);
1196
1197        if (vif->nw_type == AP_NETWORK && !pairwise &&
1198            (key_type == TKIP_CRYPT || key_type == AES_CRYPT ||
1199             key_type == WAPI_CRYPT)) {
1200                ar->ap_mode_bkey.valid = true;
1201                ar->ap_mode_bkey.key_index = key_index;
1202                ar->ap_mode_bkey.key_type = key_type;
1203                ar->ap_mode_bkey.key_len = key->key_len;
1204                memcpy(ar->ap_mode_bkey.key, key->key, key->key_len);
1205                if (!test_bit(CONNECTED, &vif->flags)) {
1206                        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1207                                   "Delay initial group key configuration until AP mode has been started\n");
1208                        /*
1209                         * The key will be set in ath6kl_connect_ap_mode() once
1210                         * the connected event is received from the target.
1211                         */
1212                        return 0;
1213                }
1214        }
1215
1216        if (vif->next_mode == AP_NETWORK && key_type == WEP_CRYPT &&
1217            !test_bit(CONNECTED, &vif->flags)) {
1218                /*
1219                 * Store the key locally so that it can be re-configured after
1220                 * the AP mode has properly started
1221                 * (ath6kl_install_statioc_wep_keys).
1222                 */
1223                ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1224                           "Delay WEP key configuration until AP mode has been started\n");
1225                vif->wep_key_list[key_index].key_len = key->key_len;
1226                memcpy(vif->wep_key_list[key_index].key, key->key,
1227                       key->key_len);
1228                return 0;
1229        }
1230
1231        return ath6kl_wmi_addkey_cmd(ar->wmi, vif->fw_vif_idx, key_index,
1232                                     key_type, key_usage, key->key_len,
1233                                     key->seq, key->seq_len, key->key,
1234                                     KEY_OP_INIT_VAL,
1235                                     (u8 *) mac_addr, SYNC_BOTH_WMIFLAG);
1236}
1237
1238static int ath6kl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
1239                                   u8 key_index, bool pairwise,
1240                                   const u8 *mac_addr)
1241{
1242        struct ath6kl *ar = ath6kl_priv(ndev);
1243        struct ath6kl_vif *vif = netdev_priv(ndev);
1244
1245        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
1246
1247        if (!ath6kl_cfg80211_ready(vif))
1248                return -EIO;
1249
1250        if (key_index > WMI_MAX_KEY_INDEX) {
1251                ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1252                           "%s: key index %d out of bounds\n", __func__,
1253                           key_index);
1254                return -ENOENT;
1255        }
1256
1257        if (!vif->keys[key_index].key_len) {
1258                ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1259                           "%s: index %d is empty\n", __func__, key_index);
1260                return 0;
1261        }
1262
1263        vif->keys[key_index].key_len = 0;
1264
1265        return ath6kl_wmi_deletekey_cmd(ar->wmi, vif->fw_vif_idx, key_index);
1266}
1267
1268static int ath6kl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
1269                                   u8 key_index, bool pairwise,
1270                                   const u8 *mac_addr, void *cookie,
1271                                   void (*callback) (void *cookie,
1272                                                     struct key_params *))
1273{
1274        struct ath6kl_vif *vif = netdev_priv(ndev);
1275        struct ath6kl_key *key = NULL;
1276        struct key_params params;
1277
1278        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
1279
1280        if (!ath6kl_cfg80211_ready(vif))
1281                return -EIO;
1282
1283        if (key_index > WMI_MAX_KEY_INDEX) {
1284                ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1285                           "%s: key index %d out of bounds\n", __func__,
1286                           key_index);
1287                return -ENOENT;
1288        }
1289
1290        key = &vif->keys[key_index];
1291        memset(&params, 0, sizeof(params));
1292        params.cipher = key->cipher;
1293        params.key_len = key->key_len;
1294        params.seq_len = key->seq_len;
1295        params.seq = key->seq;
1296        params.key = key->key;
1297
1298        callback(cookie, &params);
1299
1300        return key->key_len ? 0 : -ENOENT;
1301}
1302
1303static int ath6kl_cfg80211_set_default_key(struct wiphy *wiphy,
1304                                           struct net_device *ndev,
1305                                           u8 key_index, bool unicast,
1306                                           bool multicast)
1307{
1308        struct ath6kl *ar = ath6kl_priv(ndev);
1309        struct ath6kl_vif *vif = netdev_priv(ndev);
1310        struct ath6kl_key *key = NULL;
1311        u8 key_usage;
1312        enum crypto_type key_type = NONE_CRYPT;
1313
1314        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
1315
1316        if (!ath6kl_cfg80211_ready(vif))
1317                return -EIO;
1318
1319        if (key_index > WMI_MAX_KEY_INDEX) {
1320                ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1321                           "%s: key index %d out of bounds\n",
1322                           __func__, key_index);
1323                return -ENOENT;
1324        }
1325
1326        if (!vif->keys[key_index].key_len) {
1327                ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: invalid key index %d\n",
1328                           __func__, key_index);
1329                return -EINVAL;
1330        }
1331
1332        vif->def_txkey_index = key_index;
1333        key = &vif->keys[vif->def_txkey_index];
1334        key_usage = GROUP_USAGE;
1335        if (vif->prwise_crypto == WEP_CRYPT)
1336                key_usage |= TX_USAGE;
1337        if (unicast)
1338                key_type = vif->prwise_crypto;
1339        if (multicast)
1340                key_type = vif->grp_crypto;
1341
1342        if (vif->next_mode == AP_NETWORK && !test_bit(CONNECTED, &vif->flags))
1343                return 0; /* Delay until AP mode has been started */
1344
1345        return ath6kl_wmi_addkey_cmd(ar->wmi, vif->fw_vif_idx,
1346                                     vif->def_txkey_index,
1347                                     key_type, key_usage,
1348                                     key->key_len, key->seq, key->seq_len,
1349                                     key->key,
1350                                     KEY_OP_INIT_VAL, NULL,
1351                                     SYNC_BOTH_WMIFLAG);
1352}
1353
1354void ath6kl_cfg80211_tkip_micerr_event(struct ath6kl_vif *vif, u8 keyid,
1355                                       bool ismcast)
1356{
1357        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1358                   "%s: keyid %d, ismcast %d\n", __func__, keyid, ismcast);
1359
1360        cfg80211_michael_mic_failure(vif->ndev, vif->bssid,
1361                                     (ismcast ? NL80211_KEYTYPE_GROUP :
1362                                      NL80211_KEYTYPE_PAIRWISE), keyid, NULL,
1363                                     GFP_KERNEL);
1364}
1365
1366static int ath6kl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1367{
1368        struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
1369        struct ath6kl_vif *vif;
1370        int ret;
1371
1372        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: changed 0x%x\n", __func__,
1373                   changed);
1374
1375        vif = ath6kl_vif_first(ar);
1376        if (!vif)
1377                return -EIO;
1378
1379        if (!ath6kl_cfg80211_ready(vif))
1380                return -EIO;
1381
1382        if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1383                ret = ath6kl_wmi_set_rts_cmd(ar->wmi, wiphy->rts_threshold);
1384                if (ret != 0) {
1385                        ath6kl_err("ath6kl_wmi_set_rts_cmd failed\n");
1386                        return -EIO;
1387                }
1388        }
1389
1390        return 0;
1391}
1392
1393static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy,
1394                                       struct wireless_dev *wdev,
1395                                       enum nl80211_tx_power_setting type,
1396                                       int mbm)
1397{
1398        struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
1399        struct ath6kl_vif *vif;
1400        int dbm = MBM_TO_DBM(mbm);
1401
1402        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type 0x%x, dbm %d\n", __func__,
1403                   type, dbm);
1404
1405        vif = ath6kl_vif_first(ar);
1406        if (!vif)
1407                return -EIO;
1408
1409        if (!ath6kl_cfg80211_ready(vif))
1410                return -EIO;
1411
1412        switch (type) {
1413        case NL80211_TX_POWER_AUTOMATIC:
1414                return 0;
1415        case NL80211_TX_POWER_LIMITED:
1416                ar->tx_pwr = dbm;
1417                break;
1418        default:
1419                ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type 0x%x not supported\n",
1420                           __func__, type);
1421                return -EOPNOTSUPP;
1422        }
1423
1424        ath6kl_wmi_set_tx_pwr_cmd(ar->wmi, vif->fw_vif_idx, dbm);
1425
1426        return 0;
1427}
1428
1429static int ath6kl_cfg80211_get_txpower(struct wiphy *wiphy,
1430                                       struct wireless_dev *wdev,
1431                                       int *dbm)
1432{
1433        struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
1434        struct ath6kl_vif *vif;
1435
1436        vif = ath6kl_vif_first(ar);
1437        if (!vif)
1438                return -EIO;
1439
1440        if (!ath6kl_cfg80211_ready(vif))
1441                return -EIO;
1442
1443        if (test_bit(CONNECTED, &vif->flags)) {
1444                ar->tx_pwr = 0;
1445
1446                if (ath6kl_wmi_get_tx_pwr_cmd(ar->wmi, vif->fw_vif_idx) != 0) {
1447                        ath6kl_err("ath6kl_wmi_get_tx_pwr_cmd failed\n");
1448                        return -EIO;
1449                }
1450
1451                wait_event_interruptible_timeout(ar->event_wq, ar->tx_pwr != 0,
1452                                                 5 * HZ);
1453
1454                if (signal_pending(current)) {
1455                        ath6kl_err("target did not respond\n");
1456                        return -EINTR;
1457                }
1458        }
1459
1460        *dbm = ar->tx_pwr;
1461        return 0;
1462}
1463
1464static int ath6kl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
1465                                          struct net_device *dev,
1466                                          bool pmgmt, int timeout)
1467{
1468        struct ath6kl *ar = ath6kl_priv(dev);
1469        struct wmi_power_mode_cmd mode;
1470        struct ath6kl_vif *vif = netdev_priv(dev);
1471
1472        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: pmgmt %d, timeout %d\n",
1473                   __func__, pmgmt, timeout);
1474
1475        if (!ath6kl_cfg80211_ready(vif))
1476                return -EIO;
1477
1478        if (pmgmt) {
1479                ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: rec power\n", __func__);
1480                mode.pwr_mode = REC_POWER;
1481        } else {
1482                ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: max perf\n", __func__);
1483                mode.pwr_mode = MAX_PERF_POWER;
1484        }
1485
1486        if (ath6kl_wmi_powermode_cmd(ar->wmi, vif->fw_vif_idx,
1487                                     mode.pwr_mode) != 0) {
1488                ath6kl_err("wmi_powermode_cmd failed\n");
1489                return -EIO;
1490        }
1491
1492        return 0;
1493}
1494
1495static struct wireless_dev *ath6kl_cfg80211_add_iface(struct wiphy *wiphy,
1496                                                      const char *name,
1497                                                      enum nl80211_iftype type,
1498                                                      u32 *flags,
1499                                                      struct vif_params *params)
1500{
1501        struct ath6kl *ar = wiphy_priv(wiphy);
1502        struct wireless_dev *wdev;
1503        u8 if_idx, nw_type;
1504
1505        if (ar->num_vif == ar->vif_max) {
1506                ath6kl_err("Reached maximum number of supported vif\n");
1507                return ERR_PTR(-EINVAL);
1508        }
1509
1510        if (!ath6kl_is_valid_iftype(ar, type, &if_idx, &nw_type)) {
1511                ath6kl_err("Not a supported interface type\n");
1512                return ERR_PTR(-EINVAL);
1513        }
1514
1515        wdev = ath6kl_interface_add(ar, name, type, if_idx, nw_type);
1516        if (!wdev)
1517                return ERR_PTR(-ENOMEM);
1518
1519        ar->num_vif++;
1520
1521        return wdev;
1522}
1523
1524static int ath6kl_cfg80211_del_iface(struct wiphy *wiphy,
1525                                     struct wireless_dev *wdev)
1526{
1527        struct ath6kl *ar = wiphy_priv(wiphy);
1528        struct ath6kl_vif *vif = netdev_priv(wdev->netdev);
1529
1530        spin_lock_bh(&ar->list_lock);
1531        list_del(&vif->list);
1532        spin_unlock_bh(&ar->list_lock);
1533
1534        ath6kl_cfg80211_vif_stop(vif, test_bit(WMI_READY, &ar->flag));
1535
1536        rtnl_lock();
1537        ath6kl_cfg80211_vif_cleanup(vif);
1538        rtnl_unlock();
1539
1540        return 0;
1541}
1542
1543static int ath6kl_cfg80211_change_iface(struct wiphy *wiphy,
1544                                        struct net_device *ndev,
1545                                        enum nl80211_iftype type, u32 *flags,
1546                                        struct vif_params *params)
1547{
1548        struct ath6kl_vif *vif = netdev_priv(ndev);
1549        int i;
1550
1551        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type %u\n", __func__, type);
1552
1553        /*
1554         * Don't bring up p2p on an interface which is not initialized
1555         * for p2p operation where fw does not have capability to switch
1556         * dynamically between non-p2p and p2p type interface.
1557         */
1558        if (!test_bit(ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX,
1559                      vif->ar->fw_capabilities) &&
1560            (type == NL80211_IFTYPE_P2P_CLIENT ||
1561             type == NL80211_IFTYPE_P2P_GO)) {
1562                if (vif->ar->vif_max == 1) {
1563                        if (vif->fw_vif_idx != 0)
1564                                return -EINVAL;
1565                        else
1566                                goto set_iface_type;
1567                }
1568
1569                for (i = vif->ar->max_norm_iface; i < vif->ar->vif_max; i++) {
1570                        if (i == vif->fw_vif_idx)
1571                                break;
1572                }
1573
1574                if (i == vif->ar->vif_max) {
1575                        ath6kl_err("Invalid interface to bring up P2P\n");
1576                        return -EINVAL;
1577                }
1578        }
1579
1580        /* need to clean up enhanced bmiss detection fw state */
1581        ath6kl_cfg80211_sta_bmiss_enhance(vif, false);
1582
1583set_iface_type:
1584        switch (type) {
1585        case NL80211_IFTYPE_STATION:
1586        case NL80211_IFTYPE_P2P_CLIENT:
1587                vif->next_mode = INFRA_NETWORK;
1588                break;
1589        case NL80211_IFTYPE_ADHOC:
1590                vif->next_mode = ADHOC_NETWORK;
1591                break;
1592        case NL80211_IFTYPE_AP:
1593        case NL80211_IFTYPE_P2P_GO:
1594                vif->next_mode = AP_NETWORK;
1595                break;
1596        default:
1597                ath6kl_err("invalid interface type %u\n", type);
1598                return -EOPNOTSUPP;
1599        }
1600
1601        vif->wdev.iftype = type;
1602
1603        return 0;
1604}
1605
1606static int ath6kl_cfg80211_join_ibss(struct wiphy *wiphy,
1607                                     struct net_device *dev,
1608                                     struct cfg80211_ibss_params *ibss_param)
1609{
1610        struct ath6kl *ar = ath6kl_priv(dev);
1611        struct ath6kl_vif *vif = netdev_priv(dev);
1612        int status;
1613
1614        if (!ath6kl_cfg80211_ready(vif))
1615                return -EIO;
1616
1617        vif->ssid_len = ibss_param->ssid_len;
1618        memcpy(vif->ssid, ibss_param->ssid, vif->ssid_len);
1619
1620        if (ibss_param->chandef.chan)
1621                vif->ch_hint = ibss_param->chandef.chan->center_freq;
1622
1623        if (ibss_param->channel_fixed) {
1624                /*
1625                 * TODO: channel_fixed: The channel should be fixed, do not
1626                 * search for IBSSs to join on other channels. Target
1627                 * firmware does not support this feature, needs to be
1628                 * updated.
1629                 */
1630                return -EOPNOTSUPP;
1631        }
1632
1633        memset(vif->req_bssid, 0, sizeof(vif->req_bssid));
1634        if (ibss_param->bssid && !is_broadcast_ether_addr(ibss_param->bssid))
1635                memcpy(vif->req_bssid, ibss_param->bssid,
1636                       sizeof(vif->req_bssid));
1637
1638        ath6kl_set_wpa_version(vif, 0);
1639
1640        status = ath6kl_set_auth_type(vif, NL80211_AUTHTYPE_OPEN_SYSTEM);
1641        if (status)
1642                return status;
1643
1644        if (ibss_param->privacy) {
1645                ath6kl_set_cipher(vif, WLAN_CIPHER_SUITE_WEP40, true);
1646                ath6kl_set_cipher(vif, WLAN_CIPHER_SUITE_WEP40, false);
1647        } else {
1648                ath6kl_set_cipher(vif, 0, true);
1649                ath6kl_set_cipher(vif, 0, false);
1650        }
1651
1652        vif->nw_type = vif->next_mode;
1653
1654        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1655                   "%s: connect called with authmode %d dot11 auth %d"
1656                   " PW crypto %d PW crypto len %d GRP crypto %d"
1657                   " GRP crypto len %d channel hint %u\n",
1658                   __func__,
1659                   vif->auth_mode, vif->dot11_auth_mode, vif->prwise_crypto,
1660                   vif->prwise_crypto_len, vif->grp_crypto,
1661                   vif->grp_crypto_len, vif->ch_hint);
1662
1663        status = ath6kl_wmi_connect_cmd(ar->wmi, vif->fw_vif_idx, vif->nw_type,
1664                                        vif->dot11_auth_mode, vif->auth_mode,
1665                                        vif->prwise_crypto,
1666                                        vif->prwise_crypto_len,
1667                                        vif->grp_crypto, vif->grp_crypto_len,
1668                                        vif->ssid_len, vif->ssid,
1669                                        vif->req_bssid, vif->ch_hint,
1670                                        ar->connect_ctrl_flags, SUBTYPE_NONE);
1671        set_bit(CONNECT_PEND, &vif->flags);
1672
1673        return 0;
1674}
1675
1676static int ath6kl_cfg80211_leave_ibss(struct wiphy *wiphy,
1677                                      struct net_device *dev)
1678{
1679        struct ath6kl_vif *vif = netdev_priv(dev);
1680
1681        if (!ath6kl_cfg80211_ready(vif))
1682                return -EIO;
1683
1684        ath6kl_disconnect(vif);
1685        memset(vif->ssid, 0, sizeof(vif->ssid));
1686        vif->ssid_len = 0;
1687
1688        return 0;
1689}
1690
1691static const u32 cipher_suites[] = {
1692        WLAN_CIPHER_SUITE_WEP40,
1693        WLAN_CIPHER_SUITE_WEP104,
1694        WLAN_CIPHER_SUITE_TKIP,
1695        WLAN_CIPHER_SUITE_CCMP,
1696        CCKM_KRK_CIPHER_SUITE,
1697        WLAN_CIPHER_SUITE_SMS4,
1698};
1699
1700static bool is_rate_legacy(s32 rate)
1701{
1702        static const s32 legacy[] = { 1000, 2000, 5500, 11000,
1703                6000, 9000, 12000, 18000, 24000,
1704                36000, 48000, 54000
1705        };
1706        u8 i;
1707
1708        for (i = 0; i < ARRAY_SIZE(legacy); i++)
1709                if (rate == legacy[i])
1710                        return true;
1711
1712        return false;
1713}
1714
1715static bool is_rate_ht20(s32 rate, u8 *mcs, bool *sgi)
1716{
1717        static const s32 ht20[] = { 6500, 13000, 19500, 26000, 39000,
1718                52000, 58500, 65000, 72200
1719        };
1720        u8 i;
1721
1722        for (i = 0; i < ARRAY_SIZE(ht20); i++) {
1723                if (rate == ht20[i]) {
1724                        if (i == ARRAY_SIZE(ht20) - 1)
1725                                /* last rate uses sgi */
1726                                *sgi = true;
1727                        else
1728                                *sgi = false;
1729
1730                        *mcs = i;
1731                        return true;
1732                }
1733        }
1734        return false;
1735}
1736
1737static bool is_rate_ht40(s32 rate, u8 *mcs, bool *sgi)
1738{
1739        static const s32 ht40[] = { 13500, 27000, 40500, 54000,
1740                81000, 108000, 121500, 135000,
1741                150000
1742        };
1743        u8 i;
1744
1745        for (i = 0; i < ARRAY_SIZE(ht40); i++) {
1746                if (rate == ht40[i]) {
1747                        if (i == ARRAY_SIZE(ht40) - 1)
1748                                /* last rate uses sgi */
1749                                *sgi = true;
1750                        else
1751                                *sgi = false;
1752
1753                        *mcs = i;
1754                        return true;
1755                }
1756        }
1757
1758        return false;
1759}
1760
1761static int ath6kl_get_station(struct wiphy *wiphy, struct net_device *dev,
1762                              const u8 *mac, struct station_info *sinfo)
1763{
1764        struct ath6kl *ar = ath6kl_priv(dev);
1765        struct ath6kl_vif *vif = netdev_priv(dev);
1766        long left;
1767        bool sgi;
1768        s32 rate;
1769        int ret;
1770        u8 mcs;
1771
1772        if (memcmp(mac, vif->bssid, ETH_ALEN) != 0)
1773                return -ENOENT;
1774
1775        if (down_interruptible(&ar->sem))
1776                return -EBUSY;
1777
1778        set_bit(STATS_UPDATE_PEND, &vif->flags);
1779
1780        ret = ath6kl_wmi_get_stats_cmd(ar->wmi, vif->fw_vif_idx);
1781
1782        if (ret != 0) {
1783                up(&ar->sem);
1784                return -EIO;
1785        }
1786
1787        left = wait_event_interruptible_timeout(ar->event_wq,
1788                                                !test_bit(STATS_UPDATE_PEND,
1789                                                          &vif->flags),
1790                                                WMI_TIMEOUT);
1791
1792        up(&ar->sem);
1793
1794        if (left == 0)
1795                return -ETIMEDOUT;
1796        else if (left < 0)
1797                return left;
1798
1799        if (vif->target_stats.rx_byte) {
1800                sinfo->rx_bytes = vif->target_stats.rx_byte;
1801                sinfo->filled |= STATION_INFO_RX_BYTES64;
1802                sinfo->rx_packets = vif->target_stats.rx_pkt;
1803                sinfo->filled |= STATION_INFO_RX_PACKETS;
1804        }
1805
1806        if (vif->target_stats.tx_byte) {
1807                sinfo->tx_bytes = vif->target_stats.tx_byte;
1808                sinfo->filled |= STATION_INFO_TX_BYTES64;
1809                sinfo->tx_packets = vif->target_stats.tx_pkt;
1810                sinfo->filled |= STATION_INFO_TX_PACKETS;
1811        }
1812
1813        sinfo->signal = vif->target_stats.cs_rssi;
1814        sinfo->filled |= STATION_INFO_SIGNAL;
1815
1816        rate = vif->target_stats.tx_ucast_rate;
1817
1818        if (is_rate_legacy(rate)) {
1819                sinfo->txrate.legacy = rate / 100;
1820        } else if (is_rate_ht20(rate, &mcs, &sgi)) {
1821                if (sgi) {
1822                        sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
1823                        sinfo->txrate.mcs = mcs - 1;
1824                } else {
1825                        sinfo->txrate.mcs = mcs;
1826                }
1827
1828                sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
1829        } else if (is_rate_ht40(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_40_MHZ_WIDTH;
1838                sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
1839        } else {
1840                ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1841                           "invalid rate from stats: %d\n", rate);
1842                ath6kl_debug_war(ar, ATH6KL_WAR_INVALID_RATE);
1843                return 0;
1844        }
1845
1846        sinfo->filled |= STATION_INFO_TX_BITRATE;
1847
1848        if (test_bit(CONNECTED, &vif->flags) &&
1849            test_bit(DTIM_PERIOD_AVAIL, &vif->flags) &&
1850            vif->nw_type == INFRA_NETWORK) {
1851                sinfo->filled |= STATION_INFO_BSS_PARAM;
1852                sinfo->bss_param.flags = 0;
1853                sinfo->bss_param.dtim_period = vif->assoc_bss_dtim_period;
1854                sinfo->bss_param.beacon_interval = vif->assoc_bss_beacon_int;
1855        }
1856
1857        return 0;
1858}
1859
1860static int ath6kl_set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1861                            struct cfg80211_pmksa *pmksa)
1862{
1863        struct ath6kl *ar = ath6kl_priv(netdev);
1864        struct ath6kl_vif *vif = netdev_priv(netdev);
1865
1866        return ath6kl_wmi_setpmkid_cmd(ar->wmi, vif->fw_vif_idx, pmksa->bssid,
1867                                       pmksa->pmkid, true);
1868}
1869
1870static int ath6kl_del_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, false);
1878}
1879
1880static int ath6kl_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
1881{
1882        struct ath6kl *ar = ath6kl_priv(netdev);
1883        struct ath6kl_vif *vif = netdev_priv(netdev);
1884
1885        if (test_bit(CONNECTED, &vif->flags))
1886                return ath6kl_wmi_setpmkid_cmd(ar->wmi, vif->fw_vif_idx,
1887                                               vif->bssid, NULL, false);
1888        return 0;
1889}
1890
1891static int ath6kl_wow_usr(struct ath6kl *ar, struct ath6kl_vif *vif,
1892                          struct cfg80211_wowlan *wow, u32 *filter)
1893{
1894        int ret, pos;
1895        u8 mask[WOW_PATTERN_SIZE];
1896        u16 i;
1897
1898        /* Configure the patterns that we received from the user. */
1899        for (i = 0; i < wow->n_patterns; i++) {
1900                /*
1901                 * Convert given nl80211 specific mask value to equivalent
1902                 * driver specific mask value and send it to the chip along
1903                 * with patterns. For example, If the mask value defined in
1904                 * struct cfg80211_wowlan is 0xA (equivalent binary is 1010),
1905                 * then equivalent driver specific mask value is
1906                 * "0xFF 0x00 0xFF 0x00".
1907                 */
1908                memset(&mask, 0, sizeof(mask));
1909                for (pos = 0; pos < wow->patterns[i].pattern_len; pos++) {
1910                        if (wow->patterns[i].mask[pos / 8] & (0x1 << (pos % 8)))
1911                                mask[pos] = 0xFF;
1912                }
1913                /*
1914                 * Note: Pattern's offset is not passed as part of wowlan
1915                 * parameter from CFG layer. So it's always passed as ZERO
1916                 * to the firmware. It means, given WOW patterns are always
1917                 * matched from the first byte of received pkt in the firmware.
1918                 */
1919                ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
1920                                vif->fw_vif_idx, WOW_LIST_ID,
1921                                wow->patterns[i].pattern_len,
1922                                0 /* pattern offset */,
1923                                wow->patterns[i].pattern, mask);
1924                if (ret)
1925                        return ret;
1926        }
1927
1928        if (wow->disconnect)
1929                *filter |= WOW_FILTER_OPTION_NWK_DISASSOC;
1930
1931        if (wow->magic_pkt)
1932                *filter |= WOW_FILTER_OPTION_MAGIC_PACKET;
1933
1934        if (wow->gtk_rekey_failure)
1935                *filter |= WOW_FILTER_OPTION_GTK_ERROR;
1936
1937        if (wow->eap_identity_req)
1938                *filter |= WOW_FILTER_OPTION_EAP_REQ;
1939
1940        if (wow->four_way_handshake)
1941                *filter |= WOW_FILTER_OPTION_8021X_4WAYHS;
1942
1943        return 0;
1944}
1945
1946static int ath6kl_wow_ap(struct ath6kl *ar, struct ath6kl_vif *vif)
1947{
1948        static const u8 unicst_pattern[] = { 0x00, 0x00, 0x00,
1949                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1950                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1951                0x00, 0x08 };
1952        static const u8 unicst_mask[] = { 0x01, 0x00, 0x00,
1953                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1954                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1955                0x00, 0x7f };
1956        u8 unicst_offset = 0;
1957        static const u8 arp_pattern[] = { 0x08, 0x06 };
1958        static const u8 arp_mask[] = { 0xff, 0xff };
1959        u8 arp_offset = 20;
1960        static const u8 discvr_pattern[] = { 0xe0, 0x00, 0x00, 0xf8 };
1961        static const u8 discvr_mask[] = { 0xf0, 0x00, 0x00, 0xf8 };
1962        u8 discvr_offset = 38;
1963        static const u8 dhcp_pattern[] = { 0xff, 0xff, 0xff, 0xff,
1964                0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1965                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
1966                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1967                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1968                0x00, 0x00, 0x00, 0x00, 0x00, 0x43 /* port 67 */ };
1969        static const u8 dhcp_mask[] = { 0xff, 0xff, 0xff, 0xff,
1970                0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1971                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
1972                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1973                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1974                0x00, 0x00, 0x00, 0x00, 0xff, 0xff /* port 67 */ };
1975        u8 dhcp_offset = 0;
1976        int ret;
1977
1978        /* Setup unicast IP, EAPOL-like and ARP pkt pattern */
1979        ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
1980                        vif->fw_vif_idx, WOW_LIST_ID,
1981                        sizeof(unicst_pattern), unicst_offset,
1982                        unicst_pattern, unicst_mask);
1983        if (ret) {
1984                ath6kl_err("failed to add WOW unicast IP pattern\n");
1985                return ret;
1986        }
1987
1988        /* Setup all ARP pkt pattern */
1989        ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
1990                        vif->fw_vif_idx, WOW_LIST_ID,
1991                        sizeof(arp_pattern), arp_offset,
1992                        arp_pattern, arp_mask);
1993        if (ret) {
1994                ath6kl_err("failed to add WOW ARP pattern\n");
1995                return ret;
1996        }
1997
1998        /*
1999         * Setup multicast pattern for mDNS 224.0.0.251,
2000         * SSDP 239.255.255.250 and LLMNR  224.0.0.252
2001         */
2002        ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
2003                        vif->fw_vif_idx, WOW_LIST_ID,
2004                        sizeof(discvr_pattern), discvr_offset,
2005                        discvr_pattern, discvr_mask);
2006        if (ret) {
2007                ath6kl_err("failed to add WOW mDNS/SSDP/LLMNR pattern\n");
2008                return ret;
2009        }
2010
2011        /* Setup all DHCP broadcast pkt pattern */
2012        ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
2013                        vif->fw_vif_idx, WOW_LIST_ID,
2014                        sizeof(dhcp_pattern), dhcp_offset,
2015                        dhcp_pattern, dhcp_mask);
2016        if (ret) {
2017                ath6kl_err("failed to add WOW DHCP broadcast pattern\n");
2018                return ret;
2019        }
2020
2021        return 0;
2022}
2023
2024static int ath6kl_wow_sta(struct ath6kl *ar, struct ath6kl_vif *vif)
2025{
2026        struct net_device *ndev = vif->ndev;
2027        static const u8 discvr_pattern[] = { 0xe0, 0x00, 0x00, 0xf8 };
2028        static const u8 discvr_mask[] = { 0xf0, 0x00, 0x00, 0xf8 };
2029        u8 discvr_offset = 38;
2030        u8 mac_mask[ETH_ALEN];
2031        int ret;
2032
2033        /* Setup unicast pkt pattern */
2034        memset(mac_mask, 0xff, ETH_ALEN);
2035        ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
2036                                vif->fw_vif_idx, WOW_LIST_ID,
2037                                ETH_ALEN, 0, ndev->dev_addr,
2038                                mac_mask);
2039        if (ret) {
2040                ath6kl_err("failed to add WOW unicast pattern\n");
2041                return ret;
2042        }
2043
2044        /*
2045         * Setup multicast pattern for mDNS 224.0.0.251,
2046         * SSDP 239.255.255.250 and LLMNR 224.0.0.252
2047         */
2048        if ((ndev->flags & IFF_ALLMULTI) ||
2049            (ndev->flags & IFF_MULTICAST && netdev_mc_count(ndev) > 0)) {
2050                ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
2051                                vif->fw_vif_idx, WOW_LIST_ID,
2052                                sizeof(discvr_pattern), discvr_offset,
2053                                discvr_pattern, discvr_mask);
2054                if (ret) {
2055                        ath6kl_err("failed to add WOW mDNS/SSDP/LLMNR pattern\n");
2056                        return ret;
2057                }
2058        }
2059
2060        return 0;
2061}
2062
2063static int is_hsleep_mode_procsed(struct ath6kl_vif *vif)
2064{
2065        return test_bit(HOST_SLEEP_MODE_CMD_PROCESSED, &vif->flags);
2066}
2067
2068static bool is_ctrl_ep_empty(struct ath6kl *ar)
2069{
2070        return !ar->tx_pending[ar->ctrl_ep];
2071}
2072
2073static int ath6kl_cfg80211_host_sleep(struct ath6kl *ar, struct ath6kl_vif *vif)
2074{
2075        int ret, left;
2076
2077        clear_bit(HOST_SLEEP_MODE_CMD_PROCESSED, &vif->flags);
2078
2079        ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
2080                                                 ATH6KL_HOST_MODE_ASLEEP);
2081        if (ret)
2082                return ret;
2083
2084        left = wait_event_interruptible_timeout(ar->event_wq,
2085                                                is_hsleep_mode_procsed(vif),
2086                                                WMI_TIMEOUT);
2087        if (left == 0) {
2088                ath6kl_warn("timeout, didn't get host sleep cmd processed event\n");
2089                ret = -ETIMEDOUT;
2090        } else if (left < 0) {
2091                ath6kl_warn("error while waiting for host sleep cmd processed event %d\n",
2092                            left);
2093                ret = left;
2094        }
2095
2096        if (ar->tx_pending[ar->ctrl_ep]) {
2097                left = wait_event_interruptible_timeout(ar->event_wq,
2098                                                        is_ctrl_ep_empty(ar),
2099                                                        WMI_TIMEOUT);
2100                if (left == 0) {
2101                        ath6kl_warn("clear wmi ctrl data timeout\n");
2102                        ret = -ETIMEDOUT;
2103                } else if (left < 0) {
2104                        ath6kl_warn("clear wmi ctrl data failed: %d\n", left);
2105                        ret = left;
2106                }
2107        }
2108
2109        return ret;
2110}
2111
2112static int ath6kl_wow_suspend_vif(struct ath6kl_vif *vif,
2113                                  struct cfg80211_wowlan *wow, u32 *filter)
2114{
2115        struct ath6kl *ar = vif->ar;
2116        struct in_device *in_dev;
2117        struct in_ifaddr *ifa;
2118        int ret;
2119        u16 i, bmiss_time;
2120        __be32 ips[MAX_IP_ADDRS];
2121        u8 index = 0;
2122
2123        if (!test_bit(NETDEV_MCAST_ALL_ON, &vif->flags) &&
2124            test_bit(ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER,
2125                     ar->fw_capabilities)) {
2126                ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi,
2127                                                vif->fw_vif_idx, false);
2128                if (ret)
2129                        return ret;
2130        }
2131
2132        /* Clear existing WOW patterns */
2133        for (i = 0; i < WOW_MAX_FILTERS_PER_LIST; i++)
2134                ath6kl_wmi_del_wow_pattern_cmd(ar->wmi, vif->fw_vif_idx,
2135                                               WOW_LIST_ID, i);
2136
2137        /*
2138         * Skip the default WOW pattern configuration
2139         * if the driver receives any WOW patterns from
2140         * the user.
2141         */
2142        if (wow)
2143                ret = ath6kl_wow_usr(ar, vif, wow, filter);
2144        else if (vif->nw_type == AP_NETWORK)
2145                ret = ath6kl_wow_ap(ar, vif);
2146        else
2147                ret = ath6kl_wow_sta(ar, vif);
2148
2149        if (ret)
2150                return ret;
2151
2152        netif_stop_queue(vif->ndev);
2153
2154        if (vif->nw_type != AP_NETWORK) {
2155                ret = ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx,
2156                                                    ATH6KL_MAX_WOW_LISTEN_INTL,
2157                                                    0);
2158                if (ret)
2159                        return ret;
2160
2161                /* Set listen interval x 15 times as bmiss time */
2162                bmiss_time = ATH6KL_MAX_WOW_LISTEN_INTL * 15;
2163                if (bmiss_time > ATH6KL_MAX_BMISS_TIME)
2164                        bmiss_time = ATH6KL_MAX_BMISS_TIME;
2165
2166                ret = ath6kl_wmi_bmisstime_cmd(ar->wmi, vif->fw_vif_idx,
2167                                               bmiss_time, 0);
2168                if (ret)
2169                        return ret;
2170
2171                ret = ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx,
2172                                                0xFFFF, 0, 0xFFFF, 0, 0, 0,
2173                                                0, 0, 0, 0);
2174                if (ret)
2175                        return ret;
2176        }
2177
2178        /* Setup own IP addr for ARP agent. */
2179        in_dev = __in_dev_get_rtnl(vif->ndev);
2180        if (!in_dev)
2181                return 0;
2182
2183        ifa = in_dev->ifa_list;
2184        memset(&ips, 0, sizeof(ips));
2185
2186        /* Configure IP addr only if IP address count < MAX_IP_ADDRS */
2187        while (index < MAX_IP_ADDRS && ifa) {
2188                ips[index] = ifa->ifa_local;
2189                ifa = ifa->ifa_next;
2190                index++;
2191        }
2192
2193        if (ifa) {
2194                ath6kl_err("total IP addr count is exceeding fw limit\n");
2195                return -EINVAL;
2196        }
2197
2198        ret = ath6kl_wmi_set_ip_cmd(ar->wmi, vif->fw_vif_idx, ips[0], ips[1]);
2199        if (ret) {
2200                ath6kl_err("fail to setup ip for arp agent\n");
2201                return ret;
2202        }
2203
2204        return ret;
2205}
2206
2207static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
2208{
2209        struct ath6kl_vif *first_vif, *vif;
2210        int ret = 0;
2211        u32 filter = 0;
2212        bool connected = false;
2213
2214        /* enter / leave wow suspend on first vif always */
2215        first_vif = ath6kl_vif_first(ar);
2216        if (WARN_ON(unlikely(!first_vif)) ||
2217            !ath6kl_cfg80211_ready(first_vif))
2218                return -EIO;
2219
2220        if (wow && (wow->n_patterns > WOW_MAX_FILTERS_PER_LIST))
2221                return -EINVAL;
2222
2223        /* install filters for each connected vif */
2224        spin_lock_bh(&ar->list_lock);
2225        list_for_each_entry(vif, &ar->vif_list, list) {
2226                if (!test_bit(CONNECTED, &vif->flags) ||
2227                    !ath6kl_cfg80211_ready(vif))
2228                        continue;
2229                connected = true;
2230
2231                ret = ath6kl_wow_suspend_vif(vif, wow, &filter);
2232                if (ret)
2233                        break;
2234        }
2235        spin_unlock_bh(&ar->list_lock);
2236
2237        if (!connected)
2238                return -ENOTCONN;
2239        else if (ret)
2240                return ret;
2241
2242        ar->state = ATH6KL_STATE_SUSPENDING;
2243
2244        ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, first_vif->fw_vif_idx,
2245                                          ATH6KL_WOW_MODE_ENABLE,
2246                                          filter,
2247                                          WOW_HOST_REQ_DELAY);
2248        if (ret)
2249                return ret;
2250
2251        return ath6kl_cfg80211_host_sleep(ar, first_vif);
2252}
2253
2254static int ath6kl_wow_resume_vif(struct ath6kl_vif *vif)
2255{
2256        struct ath6kl *ar = vif->ar;
2257        int ret;
2258
2259        if (vif->nw_type != AP_NETWORK) {
2260                ret = ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx,
2261                                                0, 0, 0, 0, 0, 0, 3, 0, 0, 0);
2262                if (ret)
2263                        return ret;
2264
2265                ret = ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx,
2266                                                    vif->listen_intvl_t, 0);
2267                if (ret)
2268                        return ret;
2269
2270                ret = ath6kl_wmi_bmisstime_cmd(ar->wmi, vif->fw_vif_idx,
2271                                               vif->bmiss_time_t, 0);
2272                if (ret)
2273                        return ret;
2274        }
2275
2276        if (!test_bit(NETDEV_MCAST_ALL_OFF, &vif->flags) &&
2277            test_bit(ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER,
2278                     ar->fw_capabilities)) {
2279                ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi,
2280                                                  vif->fw_vif_idx, true);
2281                if (ret)
2282                        return ret;
2283        }
2284
2285        netif_wake_queue(vif->ndev);
2286
2287        return 0;
2288}
2289
2290static int ath6kl_wow_resume(struct ath6kl *ar)
2291{
2292        struct ath6kl_vif *vif;
2293        int ret;
2294
2295        vif = ath6kl_vif_first(ar);
2296        if (WARN_ON(unlikely(!vif)) ||
2297            !ath6kl_cfg80211_ready(vif))
2298                return -EIO;
2299
2300        ar->state = ATH6KL_STATE_RESUMING;
2301
2302        ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
2303                                                 ATH6KL_HOST_MODE_AWAKE);
2304        if (ret) {
2305                ath6kl_warn("Failed to configure host sleep mode for wow resume: %d\n",
2306                            ret);
2307                goto cleanup;
2308        }
2309
2310        spin_lock_bh(&ar->list_lock);
2311        list_for_each_entry(vif, &ar->vif_list, list) {
2312                if (!test_bit(CONNECTED, &vif->flags) ||
2313                    !ath6kl_cfg80211_ready(vif))
2314                        continue;
2315                ret = ath6kl_wow_resume_vif(vif);
2316                if (ret)
2317                        break;
2318        }
2319        spin_unlock_bh(&ar->list_lock);
2320
2321        if (ret)
2322                goto cleanup;
2323
2324        ar->state = ATH6KL_STATE_ON;
2325        return 0;
2326
2327cleanup:
2328        ar->state = ATH6KL_STATE_WOW;
2329        return ret;
2330}
2331
2332static int ath6kl_cfg80211_deepsleep_suspend(struct ath6kl *ar)
2333{
2334        struct ath6kl_vif *vif;
2335        int ret;
2336
2337        vif = ath6kl_vif_first(ar);
2338        if (!vif)
2339                return -EIO;
2340
2341        if (!test_bit(WMI_READY, &ar->flag)) {
2342                ath6kl_err("deepsleep failed as wmi is not ready\n");
2343                return -EIO;
2344        }
2345
2346        ath6kl_cfg80211_stop_all(ar);
2347
2348        /* Save the current power mode before enabling power save */
2349        ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode;
2350
2351        ret = ath6kl_wmi_powermode_cmd(ar->wmi, 0, REC_POWER);
2352        if (ret)
2353                return ret;
2354
2355        /* Disable WOW mode */
2356        ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, vif->fw_vif_idx,
2357                                          ATH6KL_WOW_MODE_DISABLE,
2358                                          0, 0);
2359        if (ret)
2360                return ret;
2361
2362        /* Flush all non control pkts in TX path */
2363        ath6kl_tx_data_cleanup(ar);
2364
2365        ret = ath6kl_cfg80211_host_sleep(ar, vif);
2366        if (ret)
2367                return ret;
2368
2369        return 0;
2370}
2371
2372static int ath6kl_cfg80211_deepsleep_resume(struct ath6kl *ar)
2373{
2374        struct ath6kl_vif *vif;
2375        int ret;
2376
2377        vif = ath6kl_vif_first(ar);
2378
2379        if (!vif)
2380                return -EIO;
2381
2382        if (ar->wmi->pwr_mode != ar->wmi->saved_pwr_mode) {
2383                ret = ath6kl_wmi_powermode_cmd(ar->wmi, 0,
2384                                               ar->wmi->saved_pwr_mode);
2385                if (ret)
2386                        return ret;
2387        }
2388
2389        ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
2390                                                 ATH6KL_HOST_MODE_AWAKE);
2391        if (ret)
2392                return ret;
2393
2394        ar->state = ATH6KL_STATE_ON;
2395
2396        /* Reset scan parameter to default values */
2397        ret = ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx,
2398                                        0, 0, 0, 0, 0, 0, 3, 0, 0, 0);
2399        if (ret)
2400                return ret;
2401
2402        return 0;
2403}
2404
2405int ath6kl_cfg80211_suspend(struct ath6kl *ar,
2406                            enum ath6kl_cfg_suspend_mode mode,
2407                            struct cfg80211_wowlan *wow)
2408{
2409        struct ath6kl_vif *vif;
2410        enum ath6kl_state prev_state;
2411        int ret;
2412
2413        switch (mode) {
2414        case ATH6KL_CFG_SUSPEND_WOW:
2415
2416                ath6kl_dbg(ATH6KL_DBG_SUSPEND, "wow mode suspend\n");
2417
2418                /* Flush all non control pkts in TX path */
2419                ath6kl_tx_data_cleanup(ar);
2420
2421                prev_state = ar->state;
2422
2423                ret = ath6kl_wow_suspend(ar, wow);
2424                if (ret) {
2425                        ar->state = prev_state;
2426                        return ret;
2427                }
2428
2429                ar->state = ATH6KL_STATE_WOW;
2430                break;
2431
2432        case ATH6KL_CFG_SUSPEND_DEEPSLEEP:
2433
2434                ath6kl_dbg(ATH6KL_DBG_SUSPEND, "deep sleep suspend\n");
2435
2436                ret = ath6kl_cfg80211_deepsleep_suspend(ar);
2437                if (ret) {
2438                        ath6kl_err("deepsleep suspend failed: %d\n", ret);
2439                        return ret;
2440                }
2441
2442                ar->state = ATH6KL_STATE_DEEPSLEEP;
2443
2444                break;
2445
2446        case ATH6KL_CFG_SUSPEND_CUTPOWER:
2447
2448                ath6kl_cfg80211_stop_all(ar);
2449
2450                if (ar->state == ATH6KL_STATE_OFF) {
2451                        ath6kl_dbg(ATH6KL_DBG_SUSPEND,
2452                                   "suspend hw off, no action for cutpower\n");
2453                        break;
2454                }
2455
2456                ath6kl_dbg(ATH6KL_DBG_SUSPEND, "suspend cutting power\n");
2457
2458                ret = ath6kl_init_hw_stop(ar);
2459                if (ret) {
2460                        ath6kl_warn("failed to stop hw during suspend: %d\n",
2461                                    ret);
2462                }
2463
2464                ar->state = ATH6KL_STATE_CUTPOWER;
2465
2466                break;
2467
2468        default:
2469                break;
2470        }
2471
2472        list_for_each_entry(vif, &ar->vif_list, list)
2473                ath6kl_cfg80211_scan_complete_event(vif, true);
2474
2475        return 0;
2476}
2477EXPORT_SYMBOL(ath6kl_cfg80211_suspend);
2478
2479int ath6kl_cfg80211_resume(struct ath6kl *ar)
2480{
2481        int ret;
2482
2483        switch (ar->state) {
2484        case  ATH6KL_STATE_WOW:
2485                ath6kl_dbg(ATH6KL_DBG_SUSPEND, "wow mode resume\n");
2486
2487                ret = ath6kl_wow_resume(ar);
2488                if (ret) {
2489                        ath6kl_warn("wow mode resume failed: %d\n", ret);
2490                        return ret;
2491                }
2492
2493                break;
2494
2495        case ATH6KL_STATE_DEEPSLEEP:
2496                ath6kl_dbg(ATH6KL_DBG_SUSPEND, "deep sleep resume\n");
2497
2498                ret = ath6kl_cfg80211_deepsleep_resume(ar);
2499                if (ret) {
2500                        ath6kl_warn("deep sleep resume failed: %d\n", ret);
2501                        return ret;
2502                }
2503                break;
2504
2505        case ATH6KL_STATE_CUTPOWER:
2506                ath6kl_dbg(ATH6KL_DBG_SUSPEND, "resume restoring power\n");
2507
2508                ret = ath6kl_init_hw_start(ar);
2509                if (ret) {
2510                        ath6kl_warn("Failed to boot hw in resume: %d\n", ret);
2511                        return ret;
2512                }
2513                break;
2514
2515        default:
2516                break;
2517        }
2518
2519        return 0;
2520}
2521EXPORT_SYMBOL(ath6kl_cfg80211_resume);
2522
2523#ifdef CONFIG_PM
2524
2525/* hif layer decides what suspend mode to use */
2526static int __ath6kl_cfg80211_suspend(struct wiphy *wiphy,
2527                                 struct cfg80211_wowlan *wow)
2528{
2529        struct ath6kl *ar = wiphy_priv(wiphy);
2530
2531        ath6kl_recovery_suspend(ar);
2532
2533        return ath6kl_hif_suspend(ar, wow);
2534}
2535
2536static int __ath6kl_cfg80211_resume(struct wiphy *wiphy)
2537{
2538        struct ath6kl *ar = wiphy_priv(wiphy);
2539        int err;
2540
2541        err = ath6kl_hif_resume(ar);
2542        if (err)
2543                return err;
2544
2545        ath6kl_recovery_resume(ar);
2546
2547        return 0;
2548}
2549
2550/*
2551 * FIXME: WOW suspend mode is selected if the host sdio controller supports
2552 * both sdio irq wake up and keep power. The target pulls sdio data line to
2553 * wake up the host when WOW pattern matches. This causes sdio irq handler
2554 * is being called in the host side which internally hits ath6kl's RX path.
2555 *
2556 * Since sdio interrupt is not disabled, RX path executes even before
2557 * the host executes the actual resume operation from PM module.
2558 *
2559 * In the current scenario, WOW resume should happen before start processing
2560 * any data from the target. So It's required to perform WOW resume in RX path.
2561 * Ideally we should perform WOW resume only in the actual platform
2562 * resume path. This area needs bit rework to avoid WOW resume in RX path.
2563 *
2564 * ath6kl_check_wow_status() is called from ath6kl_rx().
2565 */
2566void ath6kl_check_wow_status(struct ath6kl *ar)
2567{
2568        if (ar->state == ATH6KL_STATE_SUSPENDING)
2569                return;
2570
2571        if (ar->state == ATH6KL_STATE_WOW)
2572                ath6kl_cfg80211_resume(ar);
2573}
2574
2575#else
2576
2577void ath6kl_check_wow_status(struct ath6kl *ar)
2578{
2579}
2580#endif
2581
2582static int ath6kl_set_htcap(struct ath6kl_vif *vif, enum ieee80211_band band,
2583                            bool ht_enable)
2584{
2585        struct ath6kl_htcap *htcap = &vif->htcap[band];
2586
2587        if (htcap->ht_enable == ht_enable)
2588                return 0;
2589
2590        if (ht_enable) {
2591                /* Set default ht capabilities */
2592                htcap->ht_enable = true;
2593                htcap->cap_info = (band == IEEE80211_BAND_2GHZ) ?
2594                                   ath6kl_g_htcap : ath6kl_a_htcap;
2595                htcap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K;
2596        } else /* Disable ht */
2597                memset(htcap, 0, sizeof(*htcap));
2598
2599        return ath6kl_wmi_set_htcap_cmd(vif->ar->wmi, vif->fw_vif_idx,
2600                                        band, htcap);
2601}
2602
2603static int ath6kl_restore_htcap(struct ath6kl_vif *vif)
2604{
2605        struct wiphy *wiphy = vif->ar->wiphy;
2606        int band, ret = 0;
2607
2608        for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
2609                if (!wiphy->bands[band])
2610                        continue;
2611
2612                ret = ath6kl_set_htcap(vif, band,
2613                                wiphy->bands[band]->ht_cap.ht_supported);
2614                if (ret)
2615                        return ret;
2616        }
2617
2618        return ret;
2619}
2620
2621static bool ath6kl_is_p2p_ie(const u8 *pos)
2622{
2623        return pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
2624                pos[2] == 0x50 && pos[3] == 0x6f &&
2625                pos[4] == 0x9a && pos[5] == 0x09;
2626}
2627
2628static int ath6kl_set_ap_probe_resp_ies(struct ath6kl_vif *vif,
2629                                        const u8 *ies, size_t ies_len)
2630{
2631        struct ath6kl *ar = vif->ar;
2632        const u8 *pos;
2633        u8 *buf = NULL;
2634        size_t len = 0;
2635        int ret;
2636
2637        /*
2638         * Filter out P2P IE(s) since they will be included depending on
2639         * the Probe Request frame in ath6kl_send_go_probe_resp().
2640         */
2641
2642        if (ies && ies_len) {
2643                buf = kmalloc(ies_len, GFP_KERNEL);
2644                if (buf == NULL)
2645                        return -ENOMEM;
2646                pos = ies;
2647                while (pos + 1 < ies + ies_len) {
2648                        if (pos + 2 + pos[1] > ies + ies_len)
2649                                break;
2650                        if (!ath6kl_is_p2p_ie(pos)) {
2651                                memcpy(buf + len, pos, 2 + pos[1]);
2652                                len += 2 + pos[1];
2653                        }
2654                        pos += 2 + pos[1];
2655                }
2656        }
2657
2658        ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
2659                                       WMI_FRAME_PROBE_RESP, buf, len);
2660        kfree(buf);
2661        return ret;
2662}
2663
2664static int ath6kl_set_ies(struct ath6kl_vif *vif,
2665                          struct cfg80211_beacon_data *info)
2666{
2667        struct ath6kl *ar = vif->ar;
2668        int res;
2669
2670        /* this also clears IE in fw if it's not set */
2671        res = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
2672                                       WMI_FRAME_BEACON,
2673                                       info->beacon_ies,
2674                                       info->beacon_ies_len);
2675        if (res)
2676                return res;
2677
2678        /* this also clears IE in fw if it's not set */
2679        res = ath6kl_set_ap_probe_resp_ies(vif, info->proberesp_ies,
2680                                           info->proberesp_ies_len);
2681        if (res)
2682                return res;
2683
2684        /* this also clears IE in fw if it's not set */
2685        res = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
2686                                       WMI_FRAME_ASSOC_RESP,
2687                                       info->assocresp_ies,
2688                                       info->assocresp_ies_len);
2689        if (res)
2690                return res;
2691
2692        return 0;
2693}
2694
2695static int ath6kl_get_rsn_capab(struct cfg80211_beacon_data *beacon,
2696                                u8 *rsn_capab)
2697{
2698        const u8 *rsn_ie;
2699        size_t rsn_ie_len;
2700        u16 cnt;
2701
2702        if (!beacon->tail)
2703                return -EINVAL;
2704
2705        rsn_ie = cfg80211_find_ie(WLAN_EID_RSN, beacon->tail, beacon->tail_len);
2706        if (!rsn_ie)
2707                return -EINVAL;
2708
2709        rsn_ie_len = *(rsn_ie + 1);
2710        /* skip element id and length */
2711        rsn_ie += 2;
2712
2713        /* skip version */
2714        if (rsn_ie_len < 2)
2715                return -EINVAL;
2716        rsn_ie +=  2;
2717        rsn_ie_len -= 2;
2718
2719        /* skip group cipher suite */
2720        if (rsn_ie_len < 4)
2721                return 0;
2722        rsn_ie +=  4;
2723        rsn_ie_len -= 4;
2724
2725        /* skip pairwise cipher suite */
2726        if (rsn_ie_len < 2)
2727                return 0;
2728        cnt = get_unaligned_le16(rsn_ie);
2729        rsn_ie += (2 + cnt * 4);
2730        rsn_ie_len -= (2 + cnt * 4);
2731
2732        /* skip akm suite */
2733        if (rsn_ie_len < 2)
2734                return 0;
2735        cnt = get_unaligned_le16(rsn_ie);
2736        rsn_ie += (2 + cnt * 4);
2737        rsn_ie_len -= (2 + cnt * 4);
2738
2739        if (rsn_ie_len < 2)
2740                return 0;
2741
2742        memcpy(rsn_capab, rsn_ie, 2);
2743
2744        return 0;
2745}
2746
2747static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,
2748                           struct cfg80211_ap_settings *info)
2749{
2750        struct ath6kl *ar = ath6kl_priv(dev);
2751        struct ath6kl_vif *vif = netdev_priv(dev);
2752        struct ieee80211_mgmt *mgmt;
2753        bool hidden = false;
2754        u8 *ies;
2755        int ies_len;
2756        struct wmi_connect_cmd p;
2757        int res;
2758        int i, ret;
2759        u16 rsn_capab = 0;
2760        int inactivity_timeout = 0;
2761
2762        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s:\n", __func__);
2763
2764        if (!ath6kl_cfg80211_ready(vif))
2765                return -EIO;
2766
2767        if (vif->next_mode != AP_NETWORK)
2768                return -EOPNOTSUPP;
2769
2770        res = ath6kl_set_ies(vif, &info->beacon);
2771
2772        ar->ap_mode_bkey.valid = false;
2773
2774        ret = ath6kl_wmi_ap_set_beacon_intvl_cmd(ar->wmi, vif->fw_vif_idx,
2775                                                 info->beacon_interval);
2776
2777        if (ret)
2778                ath6kl_warn("Failed to set beacon interval: %d\n", ret);
2779
2780        ret = ath6kl_wmi_ap_set_dtim_cmd(ar->wmi, vif->fw_vif_idx,
2781                                         info->dtim_period);
2782
2783        /* ignore error, just print a warning and continue normally */
2784        if (ret)
2785                ath6kl_warn("Failed to set dtim_period in beacon: %d\n", ret);
2786
2787        if (info->beacon.head == NULL)
2788                return -EINVAL;
2789        mgmt = (struct ieee80211_mgmt *) info->beacon.head;
2790        ies = mgmt->u.beacon.variable;
2791        if (ies > info->beacon.head + info->beacon.head_len)
2792                return -EINVAL;
2793        ies_len = info->beacon.head + info->beacon.head_len - ies;
2794
2795        if (info->ssid == NULL)
2796                return -EINVAL;
2797        memcpy(vif->ssid, info->ssid, info->ssid_len);
2798        vif->ssid_len = info->ssid_len;
2799        if (info->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
2800                hidden = true;
2801
2802        res = ath6kl_wmi_ap_hidden_ssid(ar->wmi, vif->fw_vif_idx, hidden);
2803        if (res)
2804                return res;
2805
2806        ret = ath6kl_set_auth_type(vif, info->auth_type);
2807        if (ret)
2808                return ret;
2809
2810        memset(&p, 0, sizeof(p));
2811
2812        for (i = 0; i < info->crypto.n_akm_suites; i++) {
2813                switch (info->crypto.akm_suites[i]) {
2814                case WLAN_AKM_SUITE_8021X:
2815                        if (info->crypto.wpa_versions & NL80211_WPA_VERSION_1)
2816                                p.auth_mode |= WPA_AUTH;
2817                        if (info->crypto.wpa_versions & NL80211_WPA_VERSION_2)
2818                                p.auth_mode |= WPA2_AUTH;
2819                        break;
2820                case WLAN_AKM_SUITE_PSK:
2821                        if (info->crypto.wpa_versions & NL80211_WPA_VERSION_1)
2822                                p.auth_mode |= WPA_PSK_AUTH;
2823                        if (info->crypto.wpa_versions & NL80211_WPA_VERSION_2)
2824                                p.auth_mode |= WPA2_PSK_AUTH;
2825                        break;
2826                }
2827        }
2828        if (p.auth_mode == 0)
2829                p.auth_mode = NONE_AUTH;
2830        vif->auth_mode = p.auth_mode;
2831
2832        for (i = 0; i < info->crypto.n_ciphers_pairwise; i++) {
2833                switch (info->crypto.ciphers_pairwise[i]) {
2834                case WLAN_CIPHER_SUITE_WEP40:
2835                case WLAN_CIPHER_SUITE_WEP104:
2836                        p.prwise_crypto_type |= WEP_CRYPT;
2837                        break;
2838                case WLAN_CIPHER_SUITE_TKIP:
2839                        p.prwise_crypto_type |= TKIP_CRYPT;
2840                        break;
2841                case WLAN_CIPHER_SUITE_CCMP:
2842                        p.prwise_crypto_type |= AES_CRYPT;
2843                        break;
2844                case WLAN_CIPHER_SUITE_SMS4:
2845                        p.prwise_crypto_type |= WAPI_CRYPT;
2846                        break;
2847                }
2848        }
2849        if (p.prwise_crypto_type == 0) {
2850                p.prwise_crypto_type = NONE_CRYPT;
2851                ath6kl_set_cipher(vif, 0, true);
2852        } else if (info->crypto.n_ciphers_pairwise == 1) {
2853                ath6kl_set_cipher(vif, info->crypto.ciphers_pairwise[0], true);
2854        }
2855
2856        switch (info->crypto.cipher_group) {
2857        case WLAN_CIPHER_SUITE_WEP40:
2858        case WLAN_CIPHER_SUITE_WEP104:
2859                p.grp_crypto_type = WEP_CRYPT;
2860                break;
2861        case WLAN_CIPHER_SUITE_TKIP:
2862                p.grp_crypto_type = TKIP_CRYPT;
2863                break;
2864        case WLAN_CIPHER_SUITE_CCMP:
2865                p.grp_crypto_type = AES_CRYPT;
2866                break;
2867        case WLAN_CIPHER_SUITE_SMS4:
2868                p.grp_crypto_type = WAPI_CRYPT;
2869                break;
2870        default:
2871                p.grp_crypto_type = NONE_CRYPT;
2872                break;
2873        }
2874        ath6kl_set_cipher(vif, info->crypto.cipher_group, false);
2875
2876        p.nw_type = AP_NETWORK;
2877        vif->nw_type = vif->next_mode;
2878
2879        p.ssid_len = vif->ssid_len;
2880        memcpy(p.ssid, vif->ssid, vif->ssid_len);
2881        p.dot11_auth_mode = vif->dot11_auth_mode;
2882        p.ch = cpu_to_le16(info->chandef.chan->center_freq);
2883
2884        /* Enable uAPSD support by default */
2885        res = ath6kl_wmi_ap_set_apsd(ar->wmi, vif->fw_vif_idx, true);
2886        if (res < 0)
2887                return res;
2888
2889        if (vif->wdev.iftype == NL80211_IFTYPE_P2P_GO) {
2890                p.nw_subtype = SUBTYPE_P2PGO;
2891        } else {
2892                /*
2893                 * Due to firmware limitation, it is not possible to
2894                 * do P2P mgmt operations in AP mode
2895                 */
2896                p.nw_subtype = SUBTYPE_NONE;
2897        }
2898
2899        if (info->inactivity_timeout) {
2900                inactivity_timeout = info->inactivity_timeout;
2901
2902                if (ar->hw.flags & ATH6KL_HW_AP_INACTIVITY_MINS)
2903                        inactivity_timeout = DIV_ROUND_UP(inactivity_timeout,
2904                                                          60);
2905
2906                res = ath6kl_wmi_set_inact_period(ar->wmi, vif->fw_vif_idx,
2907                                                  inactivity_timeout);
2908                if (res < 0)
2909                        return res;
2910        }
2911
2912        if (ath6kl_set_htcap(vif, info->chandef.chan->band,
2913                             cfg80211_get_chandef_type(&info->chandef)
2914                                        != NL80211_CHAN_NO_HT))
2915                return -EIO;
2916
2917        /*
2918         * Get the PTKSA replay counter in the RSN IE. Supplicant
2919         * will use the RSN IE in M3 message and firmware has to
2920         * advertise the same in beacon/probe response. Send
2921         * the complete RSN IE capability field to firmware
2922         */
2923        if (!ath6kl_get_rsn_capab(&info->beacon, (u8 *) &rsn_capab) &&
2924            test_bit(ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE,
2925                     ar->fw_capabilities)) {
2926                res = ath6kl_wmi_set_ie_cmd(ar->wmi, vif->fw_vif_idx,
2927                                            WLAN_EID_RSN, WMI_RSN_IE_CAPB,
2928                                            (const u8 *) &rsn_capab,
2929                                            sizeof(rsn_capab));
2930                vif->rsn_capab = rsn_capab;
2931                if (res < 0)
2932                        return res;
2933        }
2934
2935        memcpy(&vif->profile, &p, sizeof(p));
2936        res = ath6kl_wmi_ap_profile_commit(ar->wmi, vif->fw_vif_idx, &p);
2937        if (res < 0)
2938                return res;
2939
2940        return 0;
2941}
2942
2943static int ath6kl_change_beacon(struct wiphy *wiphy, struct net_device *dev,
2944                                struct cfg80211_beacon_data *beacon)
2945{
2946        struct ath6kl_vif *vif = netdev_priv(dev);
2947
2948        if (!ath6kl_cfg80211_ready(vif))
2949                return -EIO;
2950
2951        if (vif->next_mode != AP_NETWORK)
2952                return -EOPNOTSUPP;
2953
2954        return ath6kl_set_ies(vif, beacon);
2955}
2956
2957static int ath6kl_stop_ap(struct wiphy *wiphy, struct net_device *dev)
2958{
2959        struct ath6kl *ar = ath6kl_priv(dev);
2960        struct ath6kl_vif *vif = netdev_priv(dev);
2961
2962        if (vif->nw_type != AP_NETWORK)
2963                return -EOPNOTSUPP;
2964        if (!test_bit(CONNECTED, &vif->flags))
2965                return -ENOTCONN;
2966
2967        ath6kl_wmi_disconnect_cmd(ar->wmi, vif->fw_vif_idx);
2968        clear_bit(CONNECTED, &vif->flags);
2969
2970        /* Restore ht setting in firmware */
2971        return ath6kl_restore_htcap(vif);
2972}
2973
2974static const u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
2975
2976static int ath6kl_del_station(struct wiphy *wiphy, struct net_device *dev,
2977                              const u8 *mac)
2978{
2979        struct ath6kl *ar = ath6kl_priv(dev);
2980        struct ath6kl_vif *vif = netdev_priv(dev);
2981        const u8 *addr = mac ? mac : bcast_addr;
2982
2983        return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx, WMI_AP_DEAUTH,
2984                                      addr, WLAN_REASON_PREV_AUTH_NOT_VALID);
2985}
2986
2987static int ath6kl_change_station(struct wiphy *wiphy, struct net_device *dev,
2988                                 const u8 *mac,
2989                                 struct station_parameters *params)
2990{
2991        struct ath6kl *ar = ath6kl_priv(dev);
2992        struct ath6kl_vif *vif = netdev_priv(dev);
2993        int err;
2994
2995        if (vif->nw_type != AP_NETWORK)
2996                return -EOPNOTSUPP;
2997
2998        err = cfg80211_check_station_change(wiphy, params,
2999                                            CFG80211_STA_AP_MLME_CLIENT);
3000        if (err)
3001                return err;
3002
3003        if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
3004                return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx,
3005                                              WMI_AP_MLME_AUTHORIZE, mac, 0);
3006        return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx,
3007                                      WMI_AP_MLME_UNAUTHORIZE, mac, 0);
3008}
3009
3010static int ath6kl_remain_on_channel(struct wiphy *wiphy,
3011                                    struct wireless_dev *wdev,
3012                                    struct ieee80211_channel *chan,
3013                                    unsigned int duration,
3014                                    u64 *cookie)
3015{
3016        struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev);
3017        struct ath6kl *ar = ath6kl_priv(vif->ndev);
3018        u32 id;
3019
3020        /* TODO: if already pending or ongoing remain-on-channel,
3021         * return -EBUSY */
3022        id = ++vif->last_roc_id;
3023        if (id == 0) {
3024                /* Do not use 0 as the cookie value */
3025                id = ++vif->last_roc_id;
3026        }
3027        *cookie = id;
3028
3029        return ath6kl_wmi_remain_on_chnl_cmd(ar->wmi, vif->fw_vif_idx,
3030                                             chan->center_freq, duration);
3031}
3032
3033static int ath6kl_cancel_remain_on_channel(struct wiphy *wiphy,
3034                                           struct wireless_dev *wdev,
3035                                           u64 cookie)
3036{
3037        struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev);
3038        struct ath6kl *ar = ath6kl_priv(vif->ndev);
3039
3040        if (cookie != vif->last_roc_id)
3041                return -ENOENT;
3042        vif->last_cancel_roc_id = cookie;
3043
3044        return ath6kl_wmi_cancel_remain_on_chnl_cmd(ar->wmi, vif->fw_vif_idx);
3045}
3046
3047static int ath6kl_send_go_probe_resp(struct ath6kl_vif *vif,
3048                                     const u8 *buf, size_t len,
3049                                     unsigned int freq)
3050{
3051        struct ath6kl *ar = vif->ar;
3052        const u8 *pos;
3053        u8 *p2p;
3054        int p2p_len;
3055        int ret;
3056        const struct ieee80211_mgmt *mgmt;
3057
3058        mgmt = (const struct ieee80211_mgmt *) buf;
3059
3060        /* Include P2P IE(s) from the frame generated in user space. */
3061
3062        p2p = kmalloc(len, GFP_KERNEL);
3063        if (p2p == NULL)
3064                return -ENOMEM;
3065        p2p_len = 0;
3066
3067        pos = mgmt->u.probe_resp.variable;
3068        while (pos + 1 < buf + len) {
3069                if (pos + 2 + pos[1] > buf + len)
3070                        break;
3071                if (ath6kl_is_p2p_ie(pos)) {
3072                        memcpy(p2p + p2p_len, pos, 2 + pos[1]);
3073                        p2p_len += 2 + pos[1];
3074                }
3075                pos += 2 + pos[1];
3076        }
3077
3078        ret = ath6kl_wmi_send_probe_response_cmd(ar->wmi, vif->fw_vif_idx, freq,
3079                                                 mgmt->da, p2p, p2p_len);
3080        kfree(p2p);
3081        return ret;
3082}
3083
3084static bool ath6kl_mgmt_powersave_ap(struct ath6kl_vif *vif,
3085                                     u32 id,
3086                                     u32 freq,
3087                                     u32 wait,
3088                                     const u8 *buf,
3089                                     size_t len,
3090                                     bool *more_data,
3091                                     bool no_cck)
3092{
3093        struct ieee80211_mgmt *mgmt;
3094        struct ath6kl_sta *conn;
3095        bool is_psq_empty = false;
3096        struct ath6kl_mgmt_buff *mgmt_buf;
3097        size_t mgmt_buf_size;
3098        struct ath6kl *ar = vif->ar;
3099
3100        mgmt = (struct ieee80211_mgmt *) buf;
3101        if (is_multicast_ether_addr(mgmt->da))
3102                return false;
3103
3104        conn = ath6kl_find_sta(vif, mgmt->da);
3105        if (!conn)
3106                return false;
3107
3108        if (conn->sta_flags & STA_PS_SLEEP) {
3109                if (!(conn->sta_flags & STA_PS_POLLED)) {
3110                        /* Queue the frames if the STA is sleeping */
3111                        mgmt_buf_size = len + sizeof(struct ath6kl_mgmt_buff);
3112                        mgmt_buf = kmalloc(mgmt_buf_size, GFP_KERNEL);
3113                        if (!mgmt_buf)
3114                                return false;
3115
3116                        INIT_LIST_HEAD(&mgmt_buf->list);
3117                        mgmt_buf->id = id;
3118                        mgmt_buf->freq = freq;
3119                        mgmt_buf->wait = wait;
3120                        mgmt_buf->len = len;
3121                        mgmt_buf->no_cck = no_cck;
3122                        memcpy(mgmt_buf->buf, buf, len);
3123                        spin_lock_bh(&conn->psq_lock);
3124                        is_psq_empty = skb_queue_empty(&conn->psq) &&
3125                                        (conn->mgmt_psq_len == 0);
3126                        list_add_tail(&mgmt_buf->list, &conn->mgmt_psq);
3127                        conn->mgmt_psq_len++;
3128                        spin_unlock_bh(&conn->psq_lock);
3129
3130                        /*
3131                         * If this is the first pkt getting queued
3132                         * for this STA, update the PVB for this
3133                         * STA.
3134                         */
3135                        if (is_psq_empty)
3136                                ath6kl_wmi_set_pvb_cmd(ar->wmi, vif->fw_vif_idx,
3137                                                       conn->aid, 1);
3138                        return true;
3139                }
3140
3141                /*
3142                 * This tx is because of a PsPoll.
3143                 * Determine if MoreData bit has to be set.
3144                 */
3145                spin_lock_bh(&conn->psq_lock);
3146                if (!skb_queue_empty(&conn->psq) || (conn->mgmt_psq_len != 0))
3147                        *more_data = true;
3148                spin_unlock_bh(&conn->psq_lock);
3149        }
3150
3151        return false;
3152}
3153
3154/* Check if SSID length is greater than DIRECT- */
3155static bool ath6kl_is_p2p_go_ssid(const u8 *buf, size_t len)
3156{
3157        const struct ieee80211_mgmt *mgmt;
3158        mgmt = (const struct ieee80211_mgmt *) buf;
3159
3160        /* variable[1] contains the SSID tag length */
3161        if (buf + len >= &mgmt->u.probe_resp.variable[1] &&
3162            (mgmt->u.probe_resp.variable[1] > P2P_WILDCARD_SSID_LEN)) {
3163                return true;
3164        }
3165
3166        return false;
3167}
3168
3169static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
3170                          struct cfg80211_mgmt_tx_params *params, u64 *cookie)
3171{
3172        struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev);
3173        struct ath6kl *ar = ath6kl_priv(vif->ndev);
3174        struct ieee80211_channel *chan = params->chan;
3175        const u8 *buf = params->buf;
3176        size_t len = params->len;
3177        unsigned int wait = params->wait;
3178        bool no_cck = params->no_cck;
3179        u32 id, freq;
3180        const struct ieee80211_mgmt *mgmt;
3181        bool more_data, queued;
3182
3183        /* default to the current channel, but use the one specified as argument
3184         * if any
3185         */
3186        freq = vif->ch_hint;
3187        if (chan)
3188                freq = chan->center_freq;
3189
3190        /* never send freq zero to the firmware */
3191        if (WARN_ON(freq == 0))
3192                return -EINVAL;
3193
3194        mgmt = (const struct ieee80211_mgmt *) buf;
3195        if (vif->nw_type == AP_NETWORK && test_bit(CONNECTED, &vif->flags) &&
3196            ieee80211_is_probe_resp(mgmt->frame_control) &&
3197            ath6kl_is_p2p_go_ssid(buf, len)) {
3198                /*
3199                 * Send Probe Response frame in GO mode using a separate WMI
3200                 * command to allow the target to fill in the generic IEs.
3201                 */
3202                *cookie = 0; /* TX status not supported */
3203                return ath6kl_send_go_probe_resp(vif, buf, len, freq);
3204        }
3205
3206        id = vif->send_action_id++;
3207        if (id == 0) {
3208                /*
3209                 * 0 is a reserved value in the WMI command and shall not be
3210                 * used for the command.
3211                 */
3212                id = vif->send_action_id++;
3213        }
3214
3215        *cookie = id;
3216
3217        /* AP mode Power saving processing */
3218        if (vif->nw_type == AP_NETWORK) {
3219                queued = ath6kl_mgmt_powersave_ap(vif, id, freq, wait, buf, len,
3220                                                  &more_data, no_cck);
3221                if (queued)
3222                        return 0;
3223        }
3224
3225        return ath6kl_wmi_send_mgmt_cmd(ar->wmi, vif->fw_vif_idx, id, freq,
3226                                        wait, buf, len, no_cck);
3227}
3228
3229static void ath6kl_mgmt_frame_register(struct wiphy *wiphy,
3230                                       struct wireless_dev *wdev,
3231                                       u16 frame_type, bool reg)
3232{
3233        struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev);
3234
3235        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: frame_type=0x%x reg=%d\n",
3236                   __func__, frame_type, reg);
3237        if (frame_type == IEEE80211_STYPE_PROBE_REQ) {
3238                /*
3239                 * Note: This notification callback is not allowed to sleep, so
3240                 * we cannot send WMI_PROBE_REQ_REPORT_CMD here. Instead, we
3241                 * hardcode target to report Probe Request frames all the time.
3242                 */
3243                vif->probe_req_report = reg;
3244        }
3245}
3246
3247static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy,
3248                        struct net_device *dev,
3249                        struct cfg80211_sched_scan_request *request)
3250{
3251        struct ath6kl *ar = ath6kl_priv(dev);
3252        struct ath6kl_vif *vif = netdev_priv(dev);
3253        u16 interval;
3254        int ret, rssi_thold;
3255        int n_match_sets = request->n_match_sets;
3256
3257        /*
3258         * If there's a matchset w/o an SSID, then assume it's just for
3259         * the RSSI (nothing else is currently supported) and ignore it.
3260         * The device only supports a global RSSI filter that we set below.
3261         */
3262        if (n_match_sets == 1 && !request->match_sets[0].ssid.ssid_len)
3263                n_match_sets = 0;
3264
3265        if (ar->state != ATH6KL_STATE_ON)
3266                return -EIO;
3267
3268        if (vif->sme_state != SME_DISCONNECTED)
3269                return -EBUSY;
3270
3271        ath6kl_cfg80211_scan_complete_event(vif, true);
3272
3273        ret = ath6kl_set_probed_ssids(ar, vif, request->ssids,
3274                                      request->n_ssids,
3275                                      request->match_sets,
3276                                      n_match_sets);
3277        if (ret < 0)
3278                return ret;
3279
3280        if (!n_match_sets) {
3281                ret = ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
3282                                               ALL_BSS_FILTER, 0);
3283                if (ret < 0)
3284                        return ret;
3285        } else {
3286                 ret = ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
3287                                                MATCHED_SSID_FILTER, 0);
3288                if (ret < 0)
3289                        return ret;
3290        }
3291
3292        if (test_bit(ATH6KL_FW_CAPABILITY_RSSI_SCAN_THOLD,
3293                     ar->fw_capabilities)) {
3294                if (request->min_rssi_thold <= NL80211_SCAN_RSSI_THOLD_OFF)
3295                        rssi_thold = 0;
3296                else if (request->min_rssi_thold < -127)
3297                        rssi_thold = -127;
3298                else
3299                        rssi_thold = request->min_rssi_thold;
3300
3301                ret = ath6kl_wmi_set_rssi_filter_cmd(ar->wmi, vif->fw_vif_idx,
3302                                                     rssi_thold);
3303                if (ret) {
3304                        ath6kl_err("failed to set RSSI threshold for scan\n");
3305                        return ret;
3306                }
3307        }
3308
3309        /* fw uses seconds, also make sure that it's >0 */
3310        interval = max_t(u16, 1, request->interval / 1000);
3311
3312        ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx,
3313                                  interval, interval,
3314                                  vif->bg_scan_period, 0, 0, 0, 3, 0, 0, 0);
3315
3316        /* this also clears IE in fw if it's not set */
3317        ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
3318                                       WMI_FRAME_PROBE_REQ,
3319                                       request->ie, request->ie_len);
3320        if (ret) {
3321                ath6kl_warn("Failed to set probe request IE for scheduled scan: %d\n",
3322                            ret);
3323                return ret;
3324        }
3325
3326        ret = ath6kl_wmi_enable_sched_scan_cmd(ar->wmi, vif->fw_vif_idx, true);
3327        if (ret)
3328                return ret;
3329
3330        set_bit(SCHED_SCANNING, &vif->flags);
3331
3332        return 0;
3333}
3334
3335static int ath6kl_cfg80211_sscan_stop(struct wiphy *wiphy,
3336                                      struct net_device *dev)
3337{
3338        struct ath6kl_vif *vif = netdev_priv(dev);
3339        bool stopped;
3340
3341        stopped = __ath6kl_cfg80211_sscan_stop(vif);
3342
3343        if (!stopped)
3344                return -EIO;
3345
3346        return 0;
3347}
3348
3349static int ath6kl_cfg80211_set_bitrate(struct wiphy *wiphy,
3350                                       struct net_device *dev,
3351                                       const u8 *addr,
3352                                       const struct cfg80211_bitrate_mask *mask)
3353{
3354        struct ath6kl *ar = ath6kl_priv(dev);
3355        struct ath6kl_vif *vif = netdev_priv(dev);
3356
3357        return ath6kl_wmi_set_bitrate_mask(ar->wmi, vif->fw_vif_idx,
3358                                           mask);
3359}
3360
3361static int ath6kl_cfg80211_set_txe_config(struct wiphy *wiphy,
3362                                          struct net_device *dev,
3363                                          u32 rate, u32 pkts, u32 intvl)
3364{
3365        struct ath6kl *ar = ath6kl_priv(dev);
3366        struct ath6kl_vif *vif = netdev_priv(dev);
3367
3368        if (vif->nw_type != INFRA_NETWORK ||
3369            !test_bit(ATH6KL_FW_CAPABILITY_TX_ERR_NOTIFY, ar->fw_capabilities))
3370                return -EOPNOTSUPP;
3371
3372        if (vif->sme_state != SME_CONNECTED)
3373                return -ENOTCONN;
3374
3375        /* save this since the firmware won't report the interval */
3376        vif->txe_intvl = intvl;
3377
3378        return ath6kl_wmi_set_txe_notify(ar->wmi, vif->fw_vif_idx,
3379                                         rate, pkts, intvl);
3380}
3381
3382static const struct ieee80211_txrx_stypes
3383ath6kl_mgmt_stypes[NUM_NL80211_IFTYPES] = {
3384        [NL80211_IFTYPE_STATION] = {
3385                .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3386                BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
3387                .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3388                BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
3389        },
3390        [NL80211_IFTYPE_AP] = {
3391                .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3392                BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
3393                .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3394                BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
3395        },
3396        [NL80211_IFTYPE_P2P_CLIENT] = {
3397                .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3398                BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
3399                .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3400                BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
3401        },
3402        [NL80211_IFTYPE_P2P_GO] = {
3403                .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3404                BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
3405                .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3406                BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
3407        },
3408};
3409
3410static struct cfg80211_ops ath6kl_cfg80211_ops = {
3411        .add_virtual_intf = ath6kl_cfg80211_add_iface,
3412        .del_virtual_intf = ath6kl_cfg80211_del_iface,
3413        .change_virtual_intf = ath6kl_cfg80211_change_iface,
3414        .scan = ath6kl_cfg80211_scan,
3415        .connect = ath6kl_cfg80211_connect,
3416        .disconnect = ath6kl_cfg80211_disconnect,
3417        .add_key = ath6kl_cfg80211_add_key,
3418        .get_key = ath6kl_cfg80211_get_key,
3419        .del_key = ath6kl_cfg80211_del_key,
3420        .set_default_key = ath6kl_cfg80211_set_default_key,
3421        .set_wiphy_params = ath6kl_cfg80211_set_wiphy_params,
3422        .set_tx_power = ath6kl_cfg80211_set_txpower,
3423        .get_tx_power = ath6kl_cfg80211_get_txpower,
3424        .set_power_mgmt = ath6kl_cfg80211_set_power_mgmt,
3425        .join_ibss = ath6kl_cfg80211_join_ibss,
3426        .leave_ibss = ath6kl_cfg80211_leave_ibss,
3427        .get_station = ath6kl_get_station,
3428        .set_pmksa = ath6kl_set_pmksa,
3429        .del_pmksa = ath6kl_del_pmksa,
3430        .flush_pmksa = ath6kl_flush_pmksa,
3431        CFG80211_TESTMODE_CMD(ath6kl_tm_cmd)
3432#ifdef CONFIG_PM
3433        .suspend = __ath6kl_cfg80211_suspend,
3434        .resume = __ath6kl_cfg80211_resume,
3435#endif
3436        .start_ap = ath6kl_start_ap,
3437        .change_beacon = ath6kl_change_beacon,
3438        .stop_ap = ath6kl_stop_ap,
3439        .del_station = ath6kl_del_station,
3440        .change_station = ath6kl_change_station,
3441        .remain_on_channel = ath6kl_remain_on_channel,
3442        .cancel_remain_on_channel = ath6kl_cancel_remain_on_channel,
3443        .mgmt_tx = ath6kl_mgmt_tx,
3444        .mgmt_frame_register = ath6kl_mgmt_frame_register,
3445        .sched_scan_start = ath6kl_cfg80211_sscan_start,
3446        .sched_scan_stop = ath6kl_cfg80211_sscan_stop,
3447        .set_bitrate_mask = ath6kl_cfg80211_set_bitrate,
3448        .set_cqm_txe_config = ath6kl_cfg80211_set_txe_config,
3449};
3450
3451void ath6kl_cfg80211_stop(struct ath6kl_vif *vif)
3452{
3453        ath6kl_cfg80211_sscan_disable(vif);
3454
3455        switch (vif->sme_state) {
3456        case SME_DISCONNECTED:
3457                break;
3458        case SME_CONNECTING:
3459                cfg80211_connect_result(vif->ndev, vif->bssid, NULL, 0,
3460                                        NULL, 0,
3461                                        WLAN_STATUS_UNSPECIFIED_FAILURE,
3462                                        GFP_KERNEL);
3463                break;
3464        case SME_CONNECTED:
3465                cfg80211_disconnected(vif->ndev, 0, NULL, 0, GFP_KERNEL);
3466                break;
3467        }
3468
3469        if (vif->ar->state != ATH6KL_STATE_RECOVERY &&
3470            (test_bit(CONNECTED, &vif->flags) ||
3471            test_bit(CONNECT_PEND, &vif->flags)))
3472                ath6kl_wmi_disconnect_cmd(vif->ar->wmi, vif->fw_vif_idx);
3473
3474        vif->sme_state = SME_DISCONNECTED;
3475        clear_bit(CONNECTED, &vif->flags);
3476        clear_bit(CONNECT_PEND, &vif->flags);
3477
3478        /* Stop netdev queues, needed during recovery */
3479        netif_stop_queue(vif->ndev);
3480        netif_carrier_off(vif->ndev);
3481
3482        /* disable scanning */
3483        if (vif->ar->state != ATH6KL_STATE_RECOVERY &&
3484            ath6kl_wmi_scanparams_cmd(vif->ar->wmi, vif->fw_vif_idx, 0xFFFF,
3485                                      0, 0, 0, 0, 0, 0, 0, 0, 0) != 0)
3486                ath6kl_warn("failed to disable scan during stop\n");
3487
3488        ath6kl_cfg80211_scan_complete_event(vif, true);
3489}
3490
3491void ath6kl_cfg80211_stop_all(struct ath6kl *ar)
3492{
3493        struct ath6kl_vif *vif;
3494
3495        vif = ath6kl_vif_first(ar);
3496        if (!vif && ar->state != ATH6KL_STATE_RECOVERY) {
3497                /* save the current power mode before enabling power save */
3498                ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode;
3499
3500                if (ath6kl_wmi_powermode_cmd(ar->wmi, 0, REC_POWER) != 0)
3501                        ath6kl_warn("ath6kl_deep_sleep_enable: wmi_powermode_cmd failed\n");
3502                return;
3503        }
3504
3505        /*
3506         * FIXME: we should take ar->list_lock to protect changes in the
3507         * vif_list, but that's not trivial to do as ath6kl_cfg80211_stop()
3508         * sleeps.
3509         */
3510        list_for_each_entry(vif, &ar->vif_list, list)
3511                ath6kl_cfg80211_stop(vif);
3512}
3513
3514static void ath6kl_cfg80211_reg_notify(struct wiphy *wiphy,
3515                                       struct regulatory_request *request)
3516{
3517        struct ath6kl *ar = wiphy_priv(wiphy);
3518        u32 rates[IEEE80211_NUM_BANDS];
3519        int ret, i;
3520
3521        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
3522                   "cfg reg_notify %c%c%s%s initiator %d hint_type %d\n",
3523                   request->alpha2[0], request->alpha2[1],
3524                   request->intersect ? " intersect" : "",
3525                   request->processed ? " processed" : "",
3526                   request->initiator, request->user_reg_hint_type);
3527
3528        if (request->user_reg_hint_type != NL80211_USER_REG_HINT_CELL_BASE)
3529                return;
3530
3531        ret = ath6kl_wmi_set_regdomain_cmd(ar->wmi, request->alpha2);
3532        if (ret) {
3533                ath6kl_err("failed to set regdomain: %d\n", ret);
3534                return;
3535        }
3536
3537        /*
3538         * Firmware will apply the regdomain change only after a scan is
3539         * issued and it will send a WMI_REGDOMAIN_EVENTID when it has been
3540         * changed.
3541         */
3542
3543        for (i = 0; i < IEEE80211_NUM_BANDS; i++)
3544                if (wiphy->bands[i])
3545                        rates[i] = (1 << wiphy->bands[i]->n_bitrates) - 1;
3546
3547
3548        ret = ath6kl_wmi_beginscan_cmd(ar->wmi, 0, WMI_LONG_SCAN, false,
3549                                       false, 0, ATH6KL_FG_SCAN_INTERVAL,
3550                                       0, NULL, false, rates);
3551        if (ret) {
3552                ath6kl_err("failed to start scan for a regdomain change: %d\n",
3553                           ret);
3554                return;
3555        }
3556}
3557
3558static int ath6kl_cfg80211_vif_init(struct ath6kl_vif *vif)
3559{
3560        vif->aggr_cntxt = aggr_init(vif);
3561        if (!vif->aggr_cntxt) {
3562                ath6kl_err("failed to initialize aggr\n");
3563                return -ENOMEM;
3564        }
3565
3566        setup_timer(&vif->disconnect_timer, disconnect_timer_handler,
3567                    (unsigned long) vif->ndev);
3568        setup_timer(&vif->sched_scan_timer, ath6kl_wmi_sscan_timer,
3569                    (unsigned long) vif);
3570
3571        set_bit(WMM_ENABLED, &vif->flags);
3572        spin_lock_init(&vif->if_lock);
3573
3574        INIT_LIST_HEAD(&vif->mc_filter);
3575
3576        return 0;
3577}
3578
3579void ath6kl_cfg80211_vif_stop(struct ath6kl_vif *vif, bool wmi_ready)
3580{
3581        static u8 bcast_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
3582        bool discon_issued;
3583
3584        netif_stop_queue(vif->ndev);
3585
3586        clear_bit(WLAN_ENABLED, &vif->flags);
3587
3588        if (wmi_ready) {
3589                discon_issued = test_bit(CONNECTED, &vif->flags) ||
3590                                test_bit(CONNECT_PEND, &vif->flags);
3591                ath6kl_disconnect(vif);
3592                del_timer(&vif->disconnect_timer);
3593
3594                if (discon_issued)
3595                        ath6kl_disconnect_event(vif, DISCONNECT_CMD,
3596                                                (vif->nw_type & AP_NETWORK) ?
3597                                                bcast_mac : vif->bssid,
3598                                                0, NULL, 0);
3599        }
3600
3601        if (vif->scan_req) {
3602                cfg80211_scan_done(vif->scan_req, true);
3603                vif->scan_req = NULL;
3604        }
3605
3606        /* need to clean up enhanced bmiss detection fw state */
3607        ath6kl_cfg80211_sta_bmiss_enhance(vif, false);
3608}
3609
3610void ath6kl_cfg80211_vif_cleanup(struct ath6kl_vif *vif)
3611{
3612        struct ath6kl *ar = vif->ar;
3613        struct ath6kl_mc_filter *mc_filter, *tmp;
3614
3615        aggr_module_destroy(vif->aggr_cntxt);
3616
3617        ar->avail_idx_map |= BIT(vif->fw_vif_idx);
3618
3619        if (vif->nw_type == ADHOC_NETWORK)
3620                ar->ibss_if_active = false;
3621
3622        list_for_each_entry_safe(mc_filter, tmp, &vif->mc_filter, list) {
3623                list_del(&mc_filter->list);
3624                kfree(mc_filter);
3625        }
3626
3627        unregister_netdevice(vif->ndev);
3628
3629        ar->num_vif--;
3630}
3631
3632struct wireless_dev *ath6kl_interface_add(struct ath6kl *ar, const char *name,
3633                                          enum nl80211_iftype type,
3634                                          u8 fw_vif_idx, u8 nw_type)
3635{
3636        struct net_device *ndev;
3637        struct ath6kl_vif *vif;
3638
3639        ndev = alloc_netdev(sizeof(*vif), name, ether_setup);
3640        if (!ndev)
3641                return NULL;
3642
3643        vif = netdev_priv(ndev);
3644        ndev->ieee80211_ptr = &vif->wdev;
3645        vif->wdev.wiphy = ar->wiphy;
3646        vif->ar = ar;
3647        vif->ndev = ndev;
3648        SET_NETDEV_DEV(ndev, wiphy_dev(vif->wdev.wiphy));
3649        vif->wdev.netdev = ndev;
3650        vif->wdev.iftype = type;
3651        vif->fw_vif_idx = fw_vif_idx;
3652        vif->nw_type = nw_type;
3653        vif->next_mode = nw_type;
3654        vif->listen_intvl_t = ATH6KL_DEFAULT_LISTEN_INTVAL;
3655        vif->bmiss_time_t = ATH6KL_DEFAULT_BMISS_TIME;
3656        vif->bg_scan_period = 0;
3657        vif->htcap[IEEE80211_BAND_2GHZ].ht_enable = true;
3658        vif->htcap[IEEE80211_BAND_5GHZ].ht_enable = true;
3659
3660        memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN);
3661        if (fw_vif_idx != 0) {
3662                ndev->dev_addr[0] = (ndev->dev_addr[0] ^ (1 << fw_vif_idx)) |
3663                                     0x2;
3664                if (test_bit(ATH6KL_FW_CAPABILITY_CUSTOM_MAC_ADDR,
3665                             ar->fw_capabilities))
3666                        ndev->dev_addr[4] ^= 0x80;
3667        }
3668
3669        init_netdev(ndev);
3670
3671        ath6kl_init_control_info(vif);
3672
3673        if (ath6kl_cfg80211_vif_init(vif))
3674                goto err;
3675
3676        if (register_netdevice(ndev))
3677                goto err;
3678
3679        ar->avail_idx_map &= ~BIT(fw_vif_idx);
3680        vif->sme_state = SME_DISCONNECTED;
3681        set_bit(WLAN_ENABLED, &vif->flags);
3682        ar->wlan_pwr_state = WLAN_POWER_STATE_ON;
3683
3684        if (type == NL80211_IFTYPE_ADHOC)
3685                ar->ibss_if_active = true;
3686
3687        spin_lock_bh(&ar->list_lock);
3688        list_add_tail(&vif->list, &ar->vif_list);
3689        spin_unlock_bh(&ar->list_lock);
3690
3691        return &vif->wdev;
3692
3693err:
3694        aggr_module_destroy(vif->aggr_cntxt);
3695        free_netdev(ndev);
3696        return NULL;
3697}
3698
3699#ifdef CONFIG_PM
3700static const struct wiphy_wowlan_support ath6kl_wowlan_support = {
3701        .flags = WIPHY_WOWLAN_MAGIC_PKT |
3702                 WIPHY_WOWLAN_DISCONNECT |
3703                 WIPHY_WOWLAN_GTK_REKEY_FAILURE  |
3704                 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
3705                 WIPHY_WOWLAN_EAP_IDENTITY_REQ   |
3706                 WIPHY_WOWLAN_4WAY_HANDSHAKE,
3707        .n_patterns = WOW_MAX_FILTERS_PER_LIST,
3708        .pattern_min_len = 1,
3709        .pattern_max_len = WOW_PATTERN_SIZE,
3710};
3711#endif
3712
3713int ath6kl_cfg80211_init(struct ath6kl *ar)
3714{
3715        struct wiphy *wiphy = ar->wiphy;
3716        bool band_2gig = false, band_5gig = false, ht = false;
3717        int ret;
3718
3719        wiphy->mgmt_stypes = ath6kl_mgmt_stypes;
3720
3721        wiphy->max_remain_on_channel_duration = 5000;
3722
3723        /* set device pointer for wiphy */
3724        set_wiphy_dev(wiphy, ar->dev);
3725
3726        wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
3727                                 BIT(NL80211_IFTYPE_ADHOC) |
3728                                 BIT(NL80211_IFTYPE_AP);
3729        if (ar->p2p) {
3730                wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_GO) |
3731                                          BIT(NL80211_IFTYPE_P2P_CLIENT);
3732        }
3733
3734        if (config_enabled(CONFIG_ATH6KL_REGDOMAIN) &&
3735            test_bit(ATH6KL_FW_CAPABILITY_REGDOMAIN, ar->fw_capabilities)) {
3736                wiphy->reg_notifier = ath6kl_cfg80211_reg_notify;
3737                ar->wiphy->features |= NL80211_FEATURE_CELL_BASE_REG_HINTS;
3738        }
3739
3740        /* max num of ssids that can be probed during scanning */
3741        wiphy->max_scan_ssids = MAX_PROBED_SSIDS;
3742
3743        /* max num of ssids that can be matched after scan */
3744        if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN_MATCH_LIST,
3745                     ar->fw_capabilities))
3746                wiphy->max_match_sets = MAX_PROBED_SSIDS;
3747
3748        wiphy->max_scan_ie_len = 1000; /* FIX: what is correct limit? */
3749        switch (ar->hw.cap) {
3750        case WMI_11AN_CAP:
3751                ht = true;
3752        case WMI_11A_CAP:
3753                band_5gig = true;
3754                break;
3755        case WMI_11GN_CAP:
3756                ht = true;
3757        case WMI_11G_CAP:
3758                band_2gig = true;
3759                break;
3760        case WMI_11AGN_CAP:
3761                ht = true;
3762        case WMI_11AG_CAP:
3763                band_2gig = true;
3764                band_5gig = true;
3765                break;
3766        default:
3767                ath6kl_err("invalid phy capability!\n");
3768                return -EINVAL;
3769        }
3770
3771        /*
3772         * Even if the fw has HT support, advertise HT cap only when
3773         * the firmware has support to override RSN capability, otherwise
3774         * 4-way handshake would fail.
3775         */
3776        if (!(ht &&
3777              test_bit(ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE,
3778                       ar->fw_capabilities))) {
3779                ath6kl_band_2ghz.ht_cap.cap = 0;
3780                ath6kl_band_2ghz.ht_cap.ht_supported = false;
3781                ath6kl_band_5ghz.ht_cap.cap = 0;
3782                ath6kl_band_5ghz.ht_cap.ht_supported = false;
3783        }
3784
3785        if (ar->hw.flags & ATH6KL_HW_64BIT_RATES) {
3786                ath6kl_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3787                ath6kl_band_5ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3788                ath6kl_band_2ghz.ht_cap.mcs.rx_mask[1] = 0xff;
3789                ath6kl_band_5ghz.ht_cap.mcs.rx_mask[1] = 0xff;
3790        } else {
3791                ath6kl_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3792                ath6kl_band_5ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3793        }
3794
3795        if (band_2gig)
3796                wiphy->bands[IEEE80211_BAND_2GHZ] = &ath6kl_band_2ghz;
3797        if (band_5gig)
3798                wiphy->bands[IEEE80211_BAND_5GHZ] = &ath6kl_band_5ghz;
3799
3800        wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
3801
3802        wiphy->cipher_suites = cipher_suites;
3803        wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
3804
3805#ifdef CONFIG_PM
3806        wiphy->wowlan = &ath6kl_wowlan_support;
3807#endif
3808
3809        wiphy->max_sched_scan_ssids = MAX_PROBED_SSIDS;
3810
3811        ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM |
3812                            WIPHY_FLAG_HAVE_AP_SME |
3813                            WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
3814                            WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
3815
3816        if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN_V2, ar->fw_capabilities))
3817                ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
3818
3819        if (test_bit(ATH6KL_FW_CAPABILITY_INACTIVITY_TIMEOUT,
3820                     ar->fw_capabilities))
3821                ar->wiphy->features |= NL80211_FEATURE_INACTIVITY_TIMER;
3822
3823        ar->wiphy->probe_resp_offload =
3824                NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
3825                NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
3826                NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P;
3827
3828        ret = wiphy_register(wiphy);
3829        if (ret < 0) {
3830                ath6kl_err("couldn't register wiphy device\n");
3831                return ret;
3832        }
3833
3834        ar->wiphy_registered = true;
3835
3836        return 0;
3837}
3838
3839void ath6kl_cfg80211_cleanup(struct ath6kl *ar)
3840{
3841        wiphy_unregister(ar->wiphy);
3842
3843        ar->wiphy_registered = false;
3844}
3845
3846struct ath6kl *ath6kl_cfg80211_create(void)
3847{
3848        struct ath6kl *ar;
3849        struct wiphy *wiphy;
3850
3851        /* create a new wiphy for use with cfg80211 */
3852        wiphy = wiphy_new(&ath6kl_cfg80211_ops, sizeof(struct ath6kl));
3853
3854        if (!wiphy) {
3855                ath6kl_err("couldn't allocate wiphy device\n");
3856                return NULL;
3857        }
3858
3859        ar = wiphy_priv(wiphy);
3860        ar->wiphy = wiphy;
3861
3862        return ar;
3863}
3864
3865/* Note: ar variable must not be accessed after calling this! */
3866void ath6kl_cfg80211_destroy(struct ath6kl *ar)
3867{
3868        int i;
3869
3870        for (i = 0; i < AP_MAX_NUM_STA; i++)
3871                kfree(ar->sta_list[i].aggr_conn);
3872
3873        wiphy_free(ar->wiphy);
3874}
3875
3876