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