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_err("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 (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 = kzalloc(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 + 1, 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 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(NL80211_STA_INFO_RX_BYTES64);
1815                sinfo->rx_packets = vif->target_stats.rx_pkt;
1816                sinfo->filled |= BIT(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(NL80211_STA_INFO_TX_BYTES64);
1822                sinfo->tx_packets = vif->target_stats.tx_pkt;
1823                sinfo->filled |= BIT(NL80211_STA_INFO_TX_PACKETS);
1824        }
1825
1826        sinfo->signal = vif->target_stats.cs_rssi;
1827        sinfo->filled |= BIT(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(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(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 = 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 = 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        int ies_len;
2770        struct wmi_connect_cmd p;
2771        int res;
2772        int i, ret;
2773        u16 rsn_capab = 0;
2774        int inactivity_timeout = 0;
2775
2776        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s:\n", __func__);
2777
2778        if (!ath6kl_cfg80211_ready(vif))
2779                return -EIO;
2780
2781        if (vif->next_mode != AP_NETWORK)
2782                return -EOPNOTSUPP;
2783
2784        res = ath6kl_set_ies(vif, &info->beacon);
2785
2786        ar->ap_mode_bkey.valid = false;
2787
2788        ret = ath6kl_wmi_ap_set_beacon_intvl_cmd(ar->wmi, vif->fw_vif_idx,
2789                                                 info->beacon_interval);
2790
2791        if (ret)
2792                ath6kl_warn("Failed to set beacon interval: %d\n", ret);
2793
2794        ret = ath6kl_wmi_ap_set_dtim_cmd(ar->wmi, vif->fw_vif_idx,
2795                                         info->dtim_period);
2796
2797        /* ignore error, just print a warning and continue normally */
2798        if (ret)
2799                ath6kl_warn("Failed to set dtim_period in beacon: %d\n", ret);
2800
2801        if (info->beacon.head == NULL)
2802                return -EINVAL;
2803        mgmt = (struct ieee80211_mgmt *) info->beacon.head;
2804        ies = mgmt->u.beacon.variable;
2805        if (ies > info->beacon.head + info->beacon.head_len)
2806                return -EINVAL;
2807        ies_len = info->beacon.head + info->beacon.head_len - ies;
2808
2809        if (info->ssid == NULL)
2810                return -EINVAL;
2811        memcpy(vif->ssid, info->ssid, info->ssid_len);
2812        vif->ssid_len = info->ssid_len;
2813        if (info->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
2814                hidden = true;
2815
2816        res = ath6kl_wmi_ap_hidden_ssid(ar->wmi, vif->fw_vif_idx, hidden);
2817        if (res)
2818                return res;
2819
2820        ret = ath6kl_set_auth_type(vif, info->auth_type);
2821        if (ret)
2822                return ret;
2823
2824        memset(&p, 0, sizeof(p));
2825
2826        for (i = 0; i < info->crypto.n_akm_suites; i++) {
2827                switch (info->crypto.akm_suites[i]) {
2828                case WLAN_AKM_SUITE_8021X:
2829                        if (info->crypto.wpa_versions & NL80211_WPA_VERSION_1)
2830                                p.auth_mode |= WPA_AUTH;
2831                        if (info->crypto.wpa_versions & NL80211_WPA_VERSION_2)
2832                                p.auth_mode |= WPA2_AUTH;
2833                        break;
2834                case WLAN_AKM_SUITE_PSK:
2835                        if (info->crypto.wpa_versions & NL80211_WPA_VERSION_1)
2836                                p.auth_mode |= WPA_PSK_AUTH;
2837                        if (info->crypto.wpa_versions & NL80211_WPA_VERSION_2)
2838                                p.auth_mode |= WPA2_PSK_AUTH;
2839                        break;
2840                }
2841        }
2842        if (p.auth_mode == 0)
2843                p.auth_mode = NONE_AUTH;
2844        vif->auth_mode = p.auth_mode;
2845
2846        for (i = 0; i < info->crypto.n_ciphers_pairwise; i++) {
2847                switch (info->crypto.ciphers_pairwise[i]) {
2848                case WLAN_CIPHER_SUITE_WEP40:
2849                case WLAN_CIPHER_SUITE_WEP104:
2850                        p.prwise_crypto_type |= WEP_CRYPT;
2851                        break;
2852                case WLAN_CIPHER_SUITE_TKIP:
2853                        p.prwise_crypto_type |= TKIP_CRYPT;
2854                        break;
2855                case WLAN_CIPHER_SUITE_CCMP:
2856                        p.prwise_crypto_type |= AES_CRYPT;
2857                        break;
2858                case WLAN_CIPHER_SUITE_SMS4:
2859                        p.prwise_crypto_type |= WAPI_CRYPT;
2860                        break;
2861                }
2862        }
2863        if (p.prwise_crypto_type == 0) {
2864                p.prwise_crypto_type = NONE_CRYPT;
2865                ath6kl_set_cipher(vif, 0, true);
2866        } else if (info->crypto.n_ciphers_pairwise == 1) {
2867                ath6kl_set_cipher(vif, info->crypto.ciphers_pairwise[0], true);
2868        }
2869
2870        switch (info->crypto.cipher_group) {
2871        case WLAN_CIPHER_SUITE_WEP40:
2872        case WLAN_CIPHER_SUITE_WEP104:
2873                p.grp_crypto_type = WEP_CRYPT;
2874                break;
2875        case WLAN_CIPHER_SUITE_TKIP:
2876                p.grp_crypto_type = TKIP_CRYPT;
2877                break;
2878        case WLAN_CIPHER_SUITE_CCMP:
2879                p.grp_crypto_type = AES_CRYPT;
2880                break;
2881        case WLAN_CIPHER_SUITE_SMS4:
2882                p.grp_crypto_type = WAPI_CRYPT;
2883                break;
2884        default:
2885                p.grp_crypto_type = NONE_CRYPT;
2886                break;
2887        }
2888        ath6kl_set_cipher(vif, info->crypto.cipher_group, false);
2889
2890        p.nw_type = AP_NETWORK;
2891        vif->nw_type = vif->next_mode;
2892
2893        p.ssid_len = vif->ssid_len;
2894        memcpy(p.ssid, vif->ssid, vif->ssid_len);
2895        p.dot11_auth_mode = vif->dot11_auth_mode;
2896        p.ch = cpu_to_le16(info->chandef.chan->center_freq);
2897
2898        /* Enable uAPSD support by default */
2899        res = ath6kl_wmi_ap_set_apsd(ar->wmi, vif->fw_vif_idx, true);
2900        if (res < 0)
2901                return res;
2902
2903        if (vif->wdev.iftype == NL80211_IFTYPE_P2P_GO) {
2904                p.nw_subtype = SUBTYPE_P2PGO;
2905        } else {
2906                /*
2907                 * Due to firmware limitation, it is not possible to
2908                 * do P2P mgmt operations in AP mode
2909                 */
2910                p.nw_subtype = SUBTYPE_NONE;
2911        }
2912
2913        if (info->inactivity_timeout) {
2914                inactivity_timeout = info->inactivity_timeout;
2915
2916                if (test_bit(ATH6KL_FW_CAPABILITY_AP_INACTIVITY_MINS,
2917                             ar->fw_capabilities))
2918                        inactivity_timeout = DIV_ROUND_UP(inactivity_timeout,
2919                                                          60);
2920
2921                res = ath6kl_wmi_set_inact_period(ar->wmi, vif->fw_vif_idx,
2922                                                  inactivity_timeout);
2923                if (res < 0)
2924                        return res;
2925        }
2926
2927        if (ath6kl_set_htcap(vif, info->chandef.chan->band,
2928                             cfg80211_get_chandef_type(&info->chandef)
2929                                        != NL80211_CHAN_NO_HT))
2930                return -EIO;
2931
2932        /*
2933         * Get the PTKSA replay counter in the RSN IE. Supplicant
2934         * will use the RSN IE in M3 message and firmware has to
2935         * advertise the same in beacon/probe response. Send
2936         * the complete RSN IE capability field to firmware
2937         */
2938        if (!ath6kl_get_rsn_capab(&info->beacon, (u8 *) &rsn_capab) &&
2939            test_bit(ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE,
2940                     ar->fw_capabilities)) {
2941                res = ath6kl_wmi_set_ie_cmd(ar->wmi, vif->fw_vif_idx,
2942                                            WLAN_EID_RSN, WMI_RSN_IE_CAPB,
2943                                            (const u8 *) &rsn_capab,
2944                                            sizeof(rsn_capab));
2945                vif->rsn_capab = rsn_capab;
2946                if (res < 0)
2947                        return res;
2948        }
2949
2950        memcpy(&vif->profile, &p, sizeof(p));
2951        res = ath6kl_wmi_ap_profile_commit(ar->wmi, vif->fw_vif_idx, &p);
2952        if (res < 0)
2953                return res;
2954
2955        return 0;
2956}
2957
2958static int ath6kl_change_beacon(struct wiphy *wiphy, struct net_device *dev,
2959                                struct cfg80211_beacon_data *beacon)
2960{
2961        struct ath6kl_vif *vif = netdev_priv(dev);
2962
2963        if (!ath6kl_cfg80211_ready(vif))
2964                return -EIO;
2965
2966        if (vif->next_mode != AP_NETWORK)
2967                return -EOPNOTSUPP;
2968
2969        return ath6kl_set_ies(vif, beacon);
2970}
2971
2972static int ath6kl_stop_ap(struct wiphy *wiphy, struct net_device *dev)
2973{
2974        struct ath6kl *ar = ath6kl_priv(dev);
2975        struct ath6kl_vif *vif = netdev_priv(dev);
2976
2977        if (vif->nw_type != AP_NETWORK)
2978                return -EOPNOTSUPP;
2979        if (!test_bit(CONNECTED, &vif->flags))
2980                return -ENOTCONN;
2981
2982        ath6kl_wmi_disconnect_cmd(ar->wmi, vif->fw_vif_idx);
2983        clear_bit(CONNECTED, &vif->flags);
2984        netif_carrier_off(vif->ndev);
2985
2986        /* Restore ht setting in firmware */
2987        return ath6kl_restore_htcap(vif);
2988}
2989
2990static const u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
2991
2992static int ath6kl_del_station(struct wiphy *wiphy, struct net_device *dev,
2993                              struct station_del_parameters *params)
2994{
2995        struct ath6kl *ar = ath6kl_priv(dev);
2996        struct ath6kl_vif *vif = netdev_priv(dev);
2997        const u8 *addr = params->mac ? params->mac : bcast_addr;
2998
2999        return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx, WMI_AP_DEAUTH,
3000                                      addr, WLAN_REASON_PREV_AUTH_NOT_VALID);
3001}
3002
3003static int ath6kl_change_station(struct wiphy *wiphy, struct net_device *dev,
3004                                 const u8 *mac,
3005                                 struct station_parameters *params)
3006{
3007        struct ath6kl *ar = ath6kl_priv(dev);
3008        struct ath6kl_vif *vif = netdev_priv(dev);
3009        int err;
3010
3011        if (vif->nw_type != AP_NETWORK)
3012                return -EOPNOTSUPP;
3013
3014        err = cfg80211_check_station_change(wiphy, params,
3015                                            CFG80211_STA_AP_MLME_CLIENT);
3016        if (err)
3017                return err;
3018
3019        if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
3020                return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx,
3021                                              WMI_AP_MLME_AUTHORIZE, mac, 0);
3022        return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx,
3023                                      WMI_AP_MLME_UNAUTHORIZE, mac, 0);
3024}
3025
3026static int ath6kl_remain_on_channel(struct wiphy *wiphy,
3027                                    struct wireless_dev *wdev,
3028                                    struct ieee80211_channel *chan,
3029                                    unsigned int duration,
3030                                    u64 *cookie)
3031{
3032        struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev);
3033        struct ath6kl *ar = ath6kl_priv(vif->ndev);
3034        u32 id;
3035
3036        /* TODO: if already pending or ongoing remain-on-channel,
3037         * return -EBUSY */
3038        id = ++vif->last_roc_id;
3039        if (id == 0) {
3040                /* Do not use 0 as the cookie value */
3041                id = ++vif->last_roc_id;
3042        }
3043        *cookie = id;
3044
3045        return ath6kl_wmi_remain_on_chnl_cmd(ar->wmi, vif->fw_vif_idx,
3046                                             chan->center_freq, duration);
3047}
3048
3049static int ath6kl_cancel_remain_on_channel(struct wiphy *wiphy,
3050                                           struct wireless_dev *wdev,
3051                                           u64 cookie)
3052{
3053        struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev);
3054        struct ath6kl *ar = ath6kl_priv(vif->ndev);
3055
3056        if (cookie != vif->last_roc_id)
3057                return -ENOENT;
3058        vif->last_cancel_roc_id = cookie;
3059
3060        return ath6kl_wmi_cancel_remain_on_chnl_cmd(ar->wmi, vif->fw_vif_idx);
3061}
3062
3063static int ath6kl_send_go_probe_resp(struct ath6kl_vif *vif,
3064                                     const u8 *buf, size_t len,
3065                                     unsigned int freq)
3066{
3067        struct ath6kl *ar = vif->ar;
3068        const u8 *pos;
3069        u8 *p2p;
3070        int p2p_len;
3071        int ret;
3072        const struct ieee80211_mgmt *mgmt;
3073
3074        mgmt = (const struct ieee80211_mgmt *) buf;
3075
3076        /* Include P2P IE(s) from the frame generated in user space. */
3077
3078        p2p = kmalloc(len, GFP_KERNEL);
3079        if (p2p == NULL)
3080                return -ENOMEM;
3081        p2p_len = 0;
3082
3083        pos = mgmt->u.probe_resp.variable;
3084        while (pos + 1 < buf + len) {
3085                if (pos + 2 + pos[1] > buf + len)
3086                        break;
3087                if (ath6kl_is_p2p_ie(pos)) {
3088                        memcpy(p2p + p2p_len, pos, 2 + pos[1]);
3089                        p2p_len += 2 + pos[1];
3090                }
3091                pos += 2 + pos[1];
3092        }
3093
3094        ret = ath6kl_wmi_send_probe_response_cmd(ar->wmi, vif->fw_vif_idx, freq,
3095                                                 mgmt->da, p2p, p2p_len);
3096        kfree(p2p);
3097        return ret;
3098}
3099
3100static bool ath6kl_mgmt_powersave_ap(struct ath6kl_vif *vif,
3101                                     u32 id,
3102                                     u32 freq,
3103                                     u32 wait,
3104                                     const u8 *buf,
3105                                     size_t len,
3106                                     bool *more_data,
3107                                     bool no_cck)
3108{
3109        struct ieee80211_mgmt *mgmt;
3110        struct ath6kl_sta *conn;
3111        bool is_psq_empty = false;
3112        struct ath6kl_mgmt_buff *mgmt_buf;
3113        size_t mgmt_buf_size;
3114        struct ath6kl *ar = vif->ar;
3115
3116        mgmt = (struct ieee80211_mgmt *) buf;
3117        if (is_multicast_ether_addr(mgmt->da))
3118                return false;
3119
3120        conn = ath6kl_find_sta(vif, mgmt->da);
3121        if (!conn)
3122                return false;
3123
3124        if (conn->sta_flags & STA_PS_SLEEP) {
3125                if (!(conn->sta_flags & STA_PS_POLLED)) {
3126                        /* Queue the frames if the STA is sleeping */
3127                        mgmt_buf_size = len + sizeof(struct ath6kl_mgmt_buff);
3128                        mgmt_buf = kmalloc(mgmt_buf_size, GFP_KERNEL);
3129                        if (!mgmt_buf)
3130                                return false;
3131
3132                        INIT_LIST_HEAD(&mgmt_buf->list);
3133                        mgmt_buf->id = id;
3134                        mgmt_buf->freq = freq;
3135                        mgmt_buf->wait = wait;
3136                        mgmt_buf->len = len;
3137                        mgmt_buf->no_cck = no_cck;
3138                        memcpy(mgmt_buf->buf, buf, len);
3139                        spin_lock_bh(&conn->psq_lock);
3140                        is_psq_empty = skb_queue_empty(&conn->psq) &&
3141                                        (conn->mgmt_psq_len == 0);
3142                        list_add_tail(&mgmt_buf->list, &conn->mgmt_psq);
3143                        conn->mgmt_psq_len++;
3144                        spin_unlock_bh(&conn->psq_lock);
3145
3146                        /*
3147                         * If this is the first pkt getting queued
3148                         * for this STA, update the PVB for this
3149                         * STA.
3150                         */
3151                        if (is_psq_empty)
3152                                ath6kl_wmi_set_pvb_cmd(ar->wmi, vif->fw_vif_idx,
3153                                                       conn->aid, 1);
3154                        return true;
3155                }
3156
3157                /*
3158                 * This tx is because of a PsPoll.
3159                 * Determine if MoreData bit has to be set.
3160                 */
3161                spin_lock_bh(&conn->psq_lock);
3162                if (!skb_queue_empty(&conn->psq) || (conn->mgmt_psq_len != 0))
3163                        *more_data = true;
3164                spin_unlock_bh(&conn->psq_lock);
3165        }
3166
3167        return false;
3168}
3169
3170/* Check if SSID length is greater than DIRECT- */
3171static bool ath6kl_is_p2p_go_ssid(const u8 *buf, size_t len)
3172{
3173        const struct ieee80211_mgmt *mgmt;
3174        mgmt = (const struct ieee80211_mgmt *) buf;
3175
3176        /* variable[1] contains the SSID tag length */
3177        if (buf + len >= &mgmt->u.probe_resp.variable[1] &&
3178            (mgmt->u.probe_resp.variable[1] > P2P_WILDCARD_SSID_LEN)) {
3179                return true;
3180        }
3181
3182        return false;
3183}
3184
3185static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
3186                          struct cfg80211_mgmt_tx_params *params, u64 *cookie)
3187{
3188        struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev);
3189        struct ath6kl *ar = ath6kl_priv(vif->ndev);
3190        struct ieee80211_channel *chan = params->chan;
3191        const u8 *buf = params->buf;
3192        size_t len = params->len;
3193        unsigned int wait = params->wait;
3194        bool no_cck = params->no_cck;
3195        u32 id, freq;
3196        const struct ieee80211_mgmt *mgmt;
3197        bool more_data, queued;
3198
3199        /* default to the current channel, but use the one specified as argument
3200         * if any
3201         */
3202        freq = vif->ch_hint;
3203        if (chan)
3204                freq = chan->center_freq;
3205
3206        /* never send freq zero to the firmware */
3207        if (WARN_ON(freq == 0))
3208                return -EINVAL;
3209
3210        mgmt = (const struct ieee80211_mgmt *) buf;
3211        if (vif->nw_type == AP_NETWORK && test_bit(CONNECTED, &vif->flags) &&
3212            ieee80211_is_probe_resp(mgmt->frame_control) &&
3213            ath6kl_is_p2p_go_ssid(buf, len)) {
3214                /*
3215                 * Send Probe Response frame in GO mode using a separate WMI
3216                 * command to allow the target to fill in the generic IEs.
3217                 */
3218                *cookie = 0; /* TX status not supported */
3219                return ath6kl_send_go_probe_resp(vif, buf, len, freq);
3220        }
3221
3222        id = vif->send_action_id++;
3223        if (id == 0) {
3224                /*
3225                 * 0 is a reserved value in the WMI command and shall not be
3226                 * used for the command.
3227                 */
3228                id = vif->send_action_id++;
3229        }
3230
3231        *cookie = id;
3232
3233        /* AP mode Power saving processing */
3234        if (vif->nw_type == AP_NETWORK) {
3235                queued = ath6kl_mgmt_powersave_ap(vif, id, freq, wait, buf, len,
3236                                                  &more_data, no_cck);
3237                if (queued)
3238                        return 0;
3239        }
3240
3241        return ath6kl_wmi_send_mgmt_cmd(ar->wmi, vif->fw_vif_idx, id, freq,
3242                                        wait, buf, len, no_cck);
3243}
3244
3245static int ath6kl_get_antenna(struct wiphy *wiphy,
3246                              u32 *tx_ant, u32 *rx_ant)
3247{
3248        struct ath6kl *ar = wiphy_priv(wiphy);
3249        *tx_ant = ar->hw.tx_ant;
3250        *rx_ant = ar->hw.rx_ant;
3251        return 0;
3252}
3253
3254static void ath6kl_mgmt_frame_register(struct wiphy *wiphy,
3255                                       struct wireless_dev *wdev,
3256                                       u16 frame_type, bool reg)
3257{
3258        struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev);
3259
3260        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: frame_type=0x%x reg=%d\n",
3261                   __func__, frame_type, reg);
3262        if (frame_type == IEEE80211_STYPE_PROBE_REQ) {
3263                /*
3264                 * Note: This notification callback is not allowed to sleep, so
3265                 * we cannot send WMI_PROBE_REQ_REPORT_CMD here. Instead, we
3266                 * hardcode target to report Probe Request frames all the time.
3267                 */
3268                vif->probe_req_report = reg;
3269        }
3270}
3271
3272static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy,
3273                        struct net_device *dev,
3274                        struct cfg80211_sched_scan_request *request)
3275{
3276        struct ath6kl *ar = ath6kl_priv(dev);
3277        struct ath6kl_vif *vif = netdev_priv(dev);
3278        u16 interval;
3279        int ret, rssi_thold;
3280        int n_match_sets = request->n_match_sets;
3281
3282        /*
3283         * If there's a matchset w/o an SSID, then assume it's just for
3284         * the RSSI (nothing else is currently supported) and ignore it.
3285         * The device only supports a global RSSI filter that we set below.
3286         */
3287        if (n_match_sets == 1 && !request->match_sets[0].ssid.ssid_len)
3288                n_match_sets = 0;
3289
3290        if (ar->state != ATH6KL_STATE_ON)
3291                return -EIO;
3292
3293        if (vif->sme_state != SME_DISCONNECTED)
3294                return -EBUSY;
3295
3296        ath6kl_cfg80211_scan_complete_event(vif, true);
3297
3298        ret = ath6kl_set_probed_ssids(ar, vif, request->ssids,
3299                                      request->n_ssids,
3300                                      request->match_sets,
3301                                      n_match_sets);
3302        if (ret < 0)
3303                return ret;
3304
3305        if (!n_match_sets) {
3306                ret = ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
3307                                               ALL_BSS_FILTER, 0);
3308                if (ret < 0)
3309                        return ret;
3310        } else {
3311                 ret = ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
3312                                                MATCHED_SSID_FILTER, 0);
3313                if (ret < 0)
3314                        return ret;
3315        }
3316
3317        if (test_bit(ATH6KL_FW_CAPABILITY_RSSI_SCAN_THOLD,
3318                     ar->fw_capabilities)) {
3319                if (request->min_rssi_thold <= NL80211_SCAN_RSSI_THOLD_OFF)
3320                        rssi_thold = 0;
3321                else if (request->min_rssi_thold < -127)
3322                        rssi_thold = -127;
3323                else
3324                        rssi_thold = request->min_rssi_thold;
3325
3326                ret = ath6kl_wmi_set_rssi_filter_cmd(ar->wmi, vif->fw_vif_idx,
3327                                                     rssi_thold);
3328                if (ret) {
3329                        ath6kl_err("failed to set RSSI threshold for scan\n");
3330                        return ret;
3331                }
3332        }
3333
3334        /* fw uses seconds, also make sure that it's >0 */
3335        interval = max_t(u16, 1, request->scan_plans[0].interval);
3336
3337        ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx,
3338                                  interval, interval,
3339                                  vif->bg_scan_period, 0, 0, 0, 3, 0, 0, 0);
3340
3341        /* this also clears IE in fw if it's not set */
3342        ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
3343                                       WMI_FRAME_PROBE_REQ,
3344                                       request->ie, request->ie_len);
3345        if (ret) {
3346                ath6kl_warn("Failed to set probe request IE for scheduled scan: %d\n",
3347                            ret);
3348                return ret;
3349        }
3350
3351        ret = ath6kl_wmi_enable_sched_scan_cmd(ar->wmi, vif->fw_vif_idx, true);
3352        if (ret)
3353                return ret;
3354
3355        set_bit(SCHED_SCANNING, &vif->flags);
3356
3357        return 0;
3358}
3359
3360static int ath6kl_cfg80211_sscan_stop(struct wiphy *wiphy,
3361                                      struct net_device *dev, u64 reqid)
3362{
3363        struct ath6kl_vif *vif = netdev_priv(dev);
3364        bool stopped;
3365
3366        stopped = __ath6kl_cfg80211_sscan_stop(vif);
3367
3368        if (!stopped)
3369                return -EIO;
3370
3371        return 0;
3372}
3373
3374static int ath6kl_cfg80211_set_bitrate(struct wiphy *wiphy,
3375                                       struct net_device *dev,
3376                                       const u8 *addr,
3377                                       const struct cfg80211_bitrate_mask *mask)
3378{
3379        struct ath6kl *ar = ath6kl_priv(dev);
3380        struct ath6kl_vif *vif = netdev_priv(dev);
3381
3382        return ath6kl_wmi_set_bitrate_mask(ar->wmi, vif->fw_vif_idx,
3383                                           mask);
3384}
3385
3386static int ath6kl_cfg80211_set_txe_config(struct wiphy *wiphy,
3387                                          struct net_device *dev,
3388                                          u32 rate, u32 pkts, u32 intvl)
3389{
3390        struct ath6kl *ar = ath6kl_priv(dev);
3391        struct ath6kl_vif *vif = netdev_priv(dev);
3392
3393        if (vif->nw_type != INFRA_NETWORK ||
3394            !test_bit(ATH6KL_FW_CAPABILITY_TX_ERR_NOTIFY, ar->fw_capabilities))
3395                return -EOPNOTSUPP;
3396
3397        if (vif->sme_state != SME_CONNECTED)
3398                return -ENOTCONN;
3399
3400        /* save this since the firmware won't report the interval */
3401        vif->txe_intvl = intvl;
3402
3403        return ath6kl_wmi_set_txe_notify(ar->wmi, vif->fw_vif_idx,
3404                                         rate, pkts, intvl);
3405}
3406
3407static const struct ieee80211_txrx_stypes
3408ath6kl_mgmt_stypes[NUM_NL80211_IFTYPES] = {
3409        [NL80211_IFTYPE_STATION] = {
3410                .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3411                BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
3412                .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3413                BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
3414        },
3415        [NL80211_IFTYPE_AP] = {
3416                .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3417                BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
3418                .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3419                BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
3420        },
3421        [NL80211_IFTYPE_P2P_CLIENT] = {
3422                .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3423                BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
3424                .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3425                BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
3426        },
3427        [NL80211_IFTYPE_P2P_GO] = {
3428                .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3429                BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
3430                .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3431                BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
3432        },
3433};
3434
3435static struct cfg80211_ops ath6kl_cfg80211_ops = {
3436        .add_virtual_intf = ath6kl_cfg80211_add_iface,
3437        .del_virtual_intf = ath6kl_cfg80211_del_iface,
3438        .change_virtual_intf = ath6kl_cfg80211_change_iface,
3439        .scan = ath6kl_cfg80211_scan,
3440        .connect = ath6kl_cfg80211_connect,
3441        .disconnect = ath6kl_cfg80211_disconnect,
3442        .add_key = ath6kl_cfg80211_add_key,
3443        .get_key = ath6kl_cfg80211_get_key,
3444        .del_key = ath6kl_cfg80211_del_key,
3445        .set_default_key = ath6kl_cfg80211_set_default_key,
3446        .set_wiphy_params = ath6kl_cfg80211_set_wiphy_params,
3447        .set_tx_power = ath6kl_cfg80211_set_txpower,
3448        .get_tx_power = ath6kl_cfg80211_get_txpower,
3449        .set_power_mgmt = ath6kl_cfg80211_set_power_mgmt,
3450        .join_ibss = ath6kl_cfg80211_join_ibss,
3451        .leave_ibss = ath6kl_cfg80211_leave_ibss,
3452        .get_station = ath6kl_get_station,
3453        .set_pmksa = ath6kl_set_pmksa,
3454        .del_pmksa = ath6kl_del_pmksa,
3455        .flush_pmksa = ath6kl_flush_pmksa,
3456        CFG80211_TESTMODE_CMD(ath6kl_tm_cmd)
3457#ifdef CONFIG_PM
3458        .suspend = __ath6kl_cfg80211_suspend,
3459        .resume = __ath6kl_cfg80211_resume,
3460#endif
3461        .start_ap = ath6kl_start_ap,
3462        .change_beacon = ath6kl_change_beacon,
3463        .stop_ap = ath6kl_stop_ap,
3464        .del_station = ath6kl_del_station,
3465        .change_station = ath6kl_change_station,
3466        .remain_on_channel = ath6kl_remain_on_channel,
3467        .cancel_remain_on_channel = ath6kl_cancel_remain_on_channel,
3468        .mgmt_tx = ath6kl_mgmt_tx,
3469        .mgmt_frame_register = ath6kl_mgmt_frame_register,
3470        .get_antenna = ath6kl_get_antenna,
3471        .sched_scan_start = ath6kl_cfg80211_sscan_start,
3472        .sched_scan_stop = ath6kl_cfg80211_sscan_stop,
3473        .set_bitrate_mask = ath6kl_cfg80211_set_bitrate,
3474        .set_cqm_txe_config = ath6kl_cfg80211_set_txe_config,
3475};
3476
3477void ath6kl_cfg80211_stop(struct ath6kl_vif *vif)
3478{
3479        ath6kl_cfg80211_sscan_disable(vif);
3480
3481        switch (vif->sme_state) {
3482        case SME_DISCONNECTED:
3483                break;
3484        case SME_CONNECTING:
3485                cfg80211_connect_result(vif->ndev, vif->bssid, NULL, 0,
3486                                        NULL, 0,
3487                                        WLAN_STATUS_UNSPECIFIED_FAILURE,
3488                                        GFP_KERNEL);
3489                break;
3490        case SME_CONNECTED:
3491                cfg80211_disconnected(vif->ndev, 0, NULL, 0, true, GFP_KERNEL);
3492                break;
3493        }
3494
3495        if (vif->ar->state != ATH6KL_STATE_RECOVERY &&
3496            (test_bit(CONNECTED, &vif->flags) ||
3497            test_bit(CONNECT_PEND, &vif->flags)))
3498                ath6kl_wmi_disconnect_cmd(vif->ar->wmi, vif->fw_vif_idx);
3499
3500        vif->sme_state = SME_DISCONNECTED;
3501        clear_bit(CONNECTED, &vif->flags);
3502        clear_bit(CONNECT_PEND, &vif->flags);
3503
3504        /* Stop netdev queues, needed during recovery */
3505        netif_stop_queue(vif->ndev);
3506        netif_carrier_off(vif->ndev);
3507
3508        /* disable scanning */
3509        if (vif->ar->state != ATH6KL_STATE_RECOVERY &&
3510            ath6kl_wmi_scanparams_cmd(vif->ar->wmi, vif->fw_vif_idx, 0xFFFF,
3511                                      0, 0, 0, 0, 0, 0, 0, 0, 0) != 0)
3512                ath6kl_warn("failed to disable scan during stop\n");
3513
3514        ath6kl_cfg80211_scan_complete_event(vif, true);
3515}
3516
3517void ath6kl_cfg80211_stop_all(struct ath6kl *ar)
3518{
3519        struct ath6kl_vif *vif;
3520
3521        vif = ath6kl_vif_first(ar);
3522        if (!vif && ar->state != ATH6KL_STATE_RECOVERY) {
3523                /* save the current power mode before enabling power save */
3524                ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode;
3525
3526                if (ath6kl_wmi_powermode_cmd(ar->wmi, 0, REC_POWER) != 0)
3527                        ath6kl_warn("ath6kl_deep_sleep_enable: wmi_powermode_cmd failed\n");
3528                return;
3529        }
3530
3531        /*
3532         * FIXME: we should take ar->list_lock to protect changes in the
3533         * vif_list, but that's not trivial to do as ath6kl_cfg80211_stop()
3534         * sleeps.
3535         */
3536        list_for_each_entry(vif, &ar->vif_list, list)
3537                ath6kl_cfg80211_stop(vif);
3538}
3539
3540static void ath6kl_cfg80211_reg_notify(struct wiphy *wiphy,
3541                                       struct regulatory_request *request)
3542{
3543        struct ath6kl *ar = wiphy_priv(wiphy);
3544        u32 rates[NUM_NL80211_BANDS];
3545        int ret, i;
3546
3547        ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
3548                   "cfg reg_notify %c%c%s%s initiator %d hint_type %d\n",
3549                   request->alpha2[0], request->alpha2[1],
3550                   request->intersect ? " intersect" : "",
3551                   request->processed ? " processed" : "",
3552                   request->initiator, request->user_reg_hint_type);
3553
3554        if (request->user_reg_hint_type != NL80211_USER_REG_HINT_CELL_BASE)
3555                return;
3556
3557        ret = ath6kl_wmi_set_regdomain_cmd(ar->wmi, request->alpha2);
3558        if (ret) {
3559                ath6kl_err("failed to set regdomain: %d\n", ret);
3560                return;
3561        }
3562
3563        /*
3564         * Firmware will apply the regdomain change only after a scan is
3565         * issued and it will send a WMI_REGDOMAIN_EVENTID when it has been
3566         * changed.
3567         */
3568
3569        for (i = 0; i < NUM_NL80211_BANDS; i++)
3570                if (wiphy->bands[i])
3571                        rates[i] = (1 << wiphy->bands[i]->n_bitrates) - 1;
3572
3573
3574        ret = ath6kl_wmi_beginscan_cmd(ar->wmi, 0, WMI_LONG_SCAN, false,
3575                                       false, 0, ATH6KL_FG_SCAN_INTERVAL,
3576                                       0, NULL, false, rates);
3577        if (ret) {
3578                ath6kl_err("failed to start scan for a regdomain change: %d\n",
3579                           ret);
3580                return;
3581        }
3582}
3583
3584static int ath6kl_cfg80211_vif_init(struct ath6kl_vif *vif)
3585{
3586        vif->aggr_cntxt = aggr_init(vif);
3587        if (!vif->aggr_cntxt) {
3588                ath6kl_err("failed to initialize aggr\n");
3589                return -ENOMEM;
3590        }
3591
3592        setup_timer(&vif->disconnect_timer, disconnect_timer_handler,
3593                    (unsigned long) vif->ndev);
3594        setup_timer(&vif->sched_scan_timer, ath6kl_wmi_sscan_timer,
3595                    (unsigned long) vif);
3596
3597        set_bit(WMM_ENABLED, &vif->flags);
3598        spin_lock_init(&vif->if_lock);
3599
3600        INIT_LIST_HEAD(&vif->mc_filter);
3601
3602        return 0;
3603}
3604
3605void ath6kl_cfg80211_vif_stop(struct ath6kl_vif *vif, bool wmi_ready)
3606{
3607        static u8 bcast_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
3608        bool discon_issued;
3609
3610        netif_stop_queue(vif->ndev);
3611
3612        clear_bit(WLAN_ENABLED, &vif->flags);
3613
3614        if (wmi_ready) {
3615                discon_issued = test_bit(CONNECTED, &vif->flags) ||
3616                                test_bit(CONNECT_PEND, &vif->flags);
3617                ath6kl_disconnect(vif);
3618                del_timer(&vif->disconnect_timer);
3619
3620                if (discon_issued)
3621                        ath6kl_disconnect_event(vif, DISCONNECT_CMD,
3622                                                (vif->nw_type & AP_NETWORK) ?
3623                                                bcast_mac : vif->bssid,
3624                                                0, NULL, 0);
3625        }
3626
3627        if (vif->scan_req) {
3628                struct cfg80211_scan_info info = {
3629                        .aborted = true,
3630                };
3631
3632                cfg80211_scan_done(vif->scan_req, &info);
3633                vif->scan_req = NULL;
3634        }
3635
3636        /* need to clean up enhanced bmiss detection fw state */
3637        ath6kl_cfg80211_sta_bmiss_enhance(vif, false);
3638}
3639
3640void ath6kl_cfg80211_vif_cleanup(struct ath6kl_vif *vif)
3641{
3642        struct ath6kl *ar = vif->ar;
3643        struct ath6kl_mc_filter *mc_filter, *tmp;
3644
3645        aggr_module_destroy(vif->aggr_cntxt);
3646
3647        ar->avail_idx_map |= BIT(vif->fw_vif_idx);
3648
3649        if (vif->nw_type == ADHOC_NETWORK)
3650                ar->ibss_if_active = false;
3651
3652        list_for_each_entry_safe(mc_filter, tmp, &vif->mc_filter, list) {
3653                list_del(&mc_filter->list);
3654                kfree(mc_filter);
3655        }
3656
3657        unregister_netdevice(vif->ndev);
3658
3659        ar->num_vif--;
3660}
3661
3662static const char ath6kl_gstrings_sta_stats[][ETH_GSTRING_LEN] = {
3663        /* Common stats names used by many drivers. */
3664        "tx_pkts_nic", "tx_bytes_nic", "rx_pkts_nic", "rx_bytes_nic",
3665
3666        /* TX stats. */
3667        "d_tx_ucast_pkts", "d_tx_bcast_pkts",
3668        "d_tx_ucast_bytes", "d_tx_bcast_bytes",
3669        "d_tx_rts_ok", "d_tx_error", "d_tx_fail",
3670        "d_tx_retry", "d_tx_multi_retry", "d_tx_rts_fail",
3671        "d_tx_tkip_counter_measures",
3672
3673        /* RX Stats. */
3674        "d_rx_ucast_pkts", "d_rx_ucast_rate", "d_rx_bcast_pkts",
3675        "d_rx_ucast_bytes", "d_rx_bcast_bytes", "d_rx_frag_pkt",
3676        "d_rx_error", "d_rx_crc_err", "d_rx_keycache_miss",
3677        "d_rx_decrypt_crc_err", "d_rx_duplicate_frames",
3678        "d_rx_mic_err", "d_rx_tkip_format_err", "d_rx_ccmp_format_err",
3679        "d_rx_ccmp_replay_err",
3680
3681        /* Misc stats. */
3682        "d_beacon_miss", "d_num_connects", "d_num_disconnects",
3683        "d_beacon_avg_rssi", "d_arp_received", "d_arp_matched",
3684        "d_arp_replied"
3685};
3686
3687#define ATH6KL_STATS_LEN        ARRAY_SIZE(ath6kl_gstrings_sta_stats)
3688
3689static int ath6kl_get_sset_count(struct net_device *dev, int sset)
3690{
3691        int rv = 0;
3692
3693        if (sset == ETH_SS_STATS)
3694                rv += ATH6KL_STATS_LEN;
3695
3696        if (rv == 0)
3697                return -EOPNOTSUPP;
3698        return rv;
3699}
3700
3701static void ath6kl_get_stats(struct net_device *dev,
3702                            struct ethtool_stats *stats,
3703                            u64 *data)
3704{
3705        struct ath6kl_vif *vif = netdev_priv(dev);
3706        struct ath6kl *ar = vif->ar;
3707        int i = 0;
3708        struct target_stats *tgt_stats;
3709
3710        memset(data, 0, sizeof(u64) * ATH6KL_STATS_LEN);
3711
3712        ath6kl_read_tgt_stats(ar, vif);
3713
3714        tgt_stats = &vif->target_stats;
3715
3716        data[i++] = tgt_stats->tx_ucast_pkt + tgt_stats->tx_bcast_pkt;
3717        data[i++] = tgt_stats->tx_ucast_byte + tgt_stats->tx_bcast_byte;
3718        data[i++] = tgt_stats->rx_ucast_pkt + tgt_stats->rx_bcast_pkt;
3719        data[i++] = tgt_stats->rx_ucast_byte + tgt_stats->rx_bcast_byte;
3720
3721        data[i++] = tgt_stats->tx_ucast_pkt;
3722        data[i++] = tgt_stats->tx_bcast_pkt;
3723        data[i++] = tgt_stats->tx_ucast_byte;
3724        data[i++] = tgt_stats->tx_bcast_byte;
3725        data[i++] = tgt_stats->tx_rts_success_cnt;
3726        data[i++] = tgt_stats->tx_err;
3727        data[i++] = tgt_stats->tx_fail_cnt;
3728        data[i++] = tgt_stats->tx_retry_cnt;
3729        data[i++] = tgt_stats->tx_mult_retry_cnt;
3730        data[i++] = tgt_stats->tx_rts_fail_cnt;
3731        data[i++] = tgt_stats->tkip_cnter_measures_invoked;
3732
3733        data[i++] = tgt_stats->rx_ucast_pkt;
3734        data[i++] = tgt_stats->rx_ucast_rate;
3735        data[i++] = tgt_stats->rx_bcast_pkt;
3736        data[i++] = tgt_stats->rx_ucast_byte;
3737        data[i++] = tgt_stats->rx_bcast_byte;
3738        data[i++] = tgt_stats->rx_frgment_pkt;
3739        data[i++] = tgt_stats->rx_err;
3740        data[i++] = tgt_stats->rx_crc_err;
3741        data[i++] = tgt_stats->rx_key_cache_miss;
3742        data[i++] = tgt_stats->rx_decrypt_err;
3743        data[i++] = tgt_stats->rx_dupl_frame;
3744        data[i++] = tgt_stats->tkip_local_mic_fail;
3745        data[i++] = tgt_stats->tkip_fmt_err;
3746        data[i++] = tgt_stats->ccmp_fmt_err;
3747        data[i++] = tgt_stats->ccmp_replays;
3748
3749        data[i++] = tgt_stats->cs_bmiss_cnt;
3750        data[i++] = tgt_stats->cs_connect_cnt;
3751        data[i++] = tgt_stats->cs_discon_cnt;
3752        data[i++] = tgt_stats->cs_ave_beacon_rssi;
3753        data[i++] = tgt_stats->arp_received;
3754        data[i++] = tgt_stats->arp_matched;
3755        data[i++] = tgt_stats->arp_replied;
3756
3757        if (i !=  ATH6KL_STATS_LEN) {
3758                WARN_ON_ONCE(1);
3759                ath6kl_err("ethtool stats error, i: %d  STATS_LEN: %d\n",
3760                           i, (int)ATH6KL_STATS_LEN);
3761        }
3762}
3763
3764/* These stats are per NIC, not really per vdev, so we just ignore dev. */
3765static void ath6kl_get_strings(struct net_device *dev, u32 sset, u8 *data)
3766{
3767        int sz_sta_stats = 0;
3768
3769        if (sset == ETH_SS_STATS) {
3770                sz_sta_stats = sizeof(ath6kl_gstrings_sta_stats);
3771                memcpy(data, ath6kl_gstrings_sta_stats, sz_sta_stats);
3772        }
3773}
3774
3775static const struct ethtool_ops ath6kl_ethtool_ops = {
3776        .get_drvinfo = cfg80211_get_drvinfo,
3777        .get_link = ethtool_op_get_link,
3778        .get_strings = ath6kl_get_strings,
3779        .get_ethtool_stats = ath6kl_get_stats,
3780        .get_sset_count = ath6kl_get_sset_count,
3781};
3782
3783struct wireless_dev *ath6kl_interface_add(struct ath6kl *ar, const char *name,
3784                                          unsigned char name_assign_type,
3785                                          enum nl80211_iftype type,
3786                                          u8 fw_vif_idx, u8 nw_type)
3787{
3788        struct net_device *ndev;
3789        struct ath6kl_vif *vif;
3790
3791        ndev = alloc_netdev(sizeof(*vif), name, name_assign_type, ether_setup);
3792        if (!ndev)
3793                return NULL;
3794
3795        vif = netdev_priv(ndev);
3796        ndev->ieee80211_ptr = &vif->wdev;
3797        vif->wdev.wiphy = ar->wiphy;
3798        vif->ar = ar;
3799        vif->ndev = ndev;
3800        SET_NETDEV_DEV(ndev, wiphy_dev(vif->wdev.wiphy));
3801        vif->wdev.netdev = ndev;
3802        vif->wdev.iftype = type;
3803        vif->fw_vif_idx = fw_vif_idx;
3804        vif->nw_type = nw_type;
3805        vif->next_mode = nw_type;
3806        vif->listen_intvl_t = ATH6KL_DEFAULT_LISTEN_INTVAL;
3807        vif->bmiss_time_t = ATH6KL_DEFAULT_BMISS_TIME;
3808        vif->bg_scan_period = 0;
3809        vif->htcap[NL80211_BAND_2GHZ].ht_enable = true;
3810        vif->htcap[NL80211_BAND_5GHZ].ht_enable = true;
3811
3812        memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN);
3813        if (fw_vif_idx != 0) {
3814                ndev->dev_addr[0] = (ndev->dev_addr[0] ^ (1 << fw_vif_idx)) |
3815                                     0x2;
3816                if (test_bit(ATH6KL_FW_CAPABILITY_CUSTOM_MAC_ADDR,
3817                             ar->fw_capabilities))
3818                        ndev->dev_addr[4] ^= 0x80;
3819        }
3820
3821        init_netdev(ndev);
3822
3823        ath6kl_init_control_info(vif);
3824
3825        if (ath6kl_cfg80211_vif_init(vif))
3826                goto err;
3827
3828        netdev_set_default_ethtool_ops(ndev, &ath6kl_ethtool_ops);
3829
3830        if (register_netdevice(ndev))
3831                goto err;
3832
3833        ar->avail_idx_map &= ~BIT(fw_vif_idx);
3834        vif->sme_state = SME_DISCONNECTED;
3835        set_bit(WLAN_ENABLED, &vif->flags);
3836        ar->wlan_pwr_state = WLAN_POWER_STATE_ON;
3837
3838        if (type == NL80211_IFTYPE_ADHOC)
3839                ar->ibss_if_active = true;
3840
3841        spin_lock_bh(&ar->list_lock);
3842        list_add_tail(&vif->list, &ar->vif_list);
3843        spin_unlock_bh(&ar->list_lock);
3844
3845        return &vif->wdev;
3846
3847err:
3848        aggr_module_destroy(vif->aggr_cntxt);
3849        free_netdev(ndev);
3850        return NULL;
3851}
3852
3853#ifdef CONFIG_PM
3854static const struct wiphy_wowlan_support ath6kl_wowlan_support = {
3855        .flags = WIPHY_WOWLAN_MAGIC_PKT |
3856                 WIPHY_WOWLAN_DISCONNECT |
3857                 WIPHY_WOWLAN_GTK_REKEY_FAILURE  |
3858                 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
3859                 WIPHY_WOWLAN_EAP_IDENTITY_REQ   |
3860                 WIPHY_WOWLAN_4WAY_HANDSHAKE,
3861        .n_patterns = WOW_MAX_FILTERS_PER_LIST,
3862        .pattern_min_len = 1,
3863        .pattern_max_len = WOW_PATTERN_SIZE,
3864};
3865#endif
3866
3867int ath6kl_cfg80211_init(struct ath6kl *ar)
3868{
3869        struct wiphy *wiphy = ar->wiphy;
3870        bool band_2gig = false, band_5gig = false, ht = false;
3871        int ret;
3872
3873        wiphy->mgmt_stypes = ath6kl_mgmt_stypes;
3874
3875        wiphy->max_remain_on_channel_duration = 5000;
3876
3877        /* set device pointer for wiphy */
3878        set_wiphy_dev(wiphy, ar->dev);
3879
3880        wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
3881                                 BIT(NL80211_IFTYPE_ADHOC) |
3882                                 BIT(NL80211_IFTYPE_AP);
3883        if (ar->p2p) {
3884                wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_GO) |
3885                                          BIT(NL80211_IFTYPE_P2P_CLIENT);
3886        }
3887
3888        if (IS_ENABLED(CONFIG_ATH6KL_REGDOMAIN) &&
3889            test_bit(ATH6KL_FW_CAPABILITY_REGDOMAIN, ar->fw_capabilities)) {
3890                wiphy->reg_notifier = ath6kl_cfg80211_reg_notify;
3891                ar->wiphy->features |= NL80211_FEATURE_CELL_BASE_REG_HINTS;
3892        }
3893
3894        /* max num of ssids that can be probed during scanning */
3895        wiphy->max_scan_ssids = MAX_PROBED_SSIDS;
3896
3897        /* max num of ssids that can be matched after scan */
3898        if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN_MATCH_LIST,
3899                     ar->fw_capabilities))
3900                wiphy->max_match_sets = MAX_PROBED_SSIDS;
3901
3902        wiphy->max_scan_ie_len = 1000; /* FIX: what is correct limit? */
3903        switch (ar->hw.cap) {
3904        case WMI_11AN_CAP:
3905                ht = true;
3906        case WMI_11A_CAP:
3907                band_5gig = true;
3908                break;
3909        case WMI_11GN_CAP:
3910                ht = true;
3911        case WMI_11G_CAP:
3912                band_2gig = true;
3913                break;
3914        case WMI_11AGN_CAP:
3915                ht = true;
3916        case WMI_11AG_CAP:
3917                band_2gig = true;
3918                band_5gig = true;
3919                break;
3920        default:
3921                ath6kl_err("invalid phy capability!\n");
3922                return -EINVAL;
3923        }
3924
3925        /*
3926         * Even if the fw has HT support, advertise HT cap only when
3927         * the firmware has support to override RSN capability, otherwise
3928         * 4-way handshake would fail.
3929         */
3930        if (!(ht &&
3931              test_bit(ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE,
3932                       ar->fw_capabilities))) {
3933                ath6kl_band_2ghz.ht_cap.cap = 0;
3934                ath6kl_band_2ghz.ht_cap.ht_supported = false;
3935                ath6kl_band_5ghz.ht_cap.cap = 0;
3936                ath6kl_band_5ghz.ht_cap.ht_supported = false;
3937
3938                if (ht)
3939                        ath6kl_err("Firmware lacks RSN-CAP-OVERRIDE, so HT (802.11n) is disabled.");
3940        }
3941
3942        if (test_bit(ATH6KL_FW_CAPABILITY_64BIT_RATES,
3943                     ar->fw_capabilities)) {
3944                ath6kl_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3945                ath6kl_band_5ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3946                ath6kl_band_2ghz.ht_cap.mcs.rx_mask[1] = 0xff;
3947                ath6kl_band_5ghz.ht_cap.mcs.rx_mask[1] = 0xff;
3948                ar->hw.tx_ant = 0x3; /* mask, 2 antenna */
3949                ar->hw.rx_ant = 0x3;
3950        } else {
3951                ath6kl_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3952                ath6kl_band_5ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3953                ar->hw.tx_ant = 1;
3954                ar->hw.rx_ant = 1;
3955        }
3956
3957        wiphy->available_antennas_tx = ar->hw.tx_ant;
3958        wiphy->available_antennas_rx = ar->hw.rx_ant;
3959
3960        if (band_2gig)
3961                wiphy->bands[NL80211_BAND_2GHZ] = &ath6kl_band_2ghz;
3962        if (band_5gig)
3963                wiphy->bands[NL80211_BAND_5GHZ] = &ath6kl_band_5ghz;
3964
3965        wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
3966
3967        wiphy->cipher_suites = cipher_suites;
3968        wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
3969
3970#ifdef CONFIG_PM
3971        wiphy->wowlan = &ath6kl_wowlan_support;
3972#endif
3973
3974        wiphy->max_sched_scan_ssids = MAX_PROBED_SSIDS;
3975
3976        ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM |
3977                            WIPHY_FLAG_HAVE_AP_SME |
3978                            WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
3979                            WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
3980
3981        if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN_V2, ar->fw_capabilities))
3982                ar->wiphy->max_sched_scan_reqs = 1;
3983
3984        if (test_bit(ATH6KL_FW_CAPABILITY_INACTIVITY_TIMEOUT,
3985                     ar->fw_capabilities))
3986                ar->wiphy->features |= NL80211_FEATURE_INACTIVITY_TIMER;
3987
3988        ar->wiphy->probe_resp_offload =
3989                NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
3990                NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
3991                NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P;
3992
3993        ret = wiphy_register(wiphy);
3994        if (ret < 0) {
3995                ath6kl_err("couldn't register wiphy device\n");
3996                return ret;
3997        }
3998
3999        ar->wiphy_registered = true;
4000
4001        return 0;
4002}
4003
4004void ath6kl_cfg80211_cleanup(struct ath6kl *ar)
4005{
4006        wiphy_unregister(ar->wiphy);
4007
4008        ar->wiphy_registered = false;
4009}
4010
4011struct ath6kl *ath6kl_cfg80211_create(void)
4012{
4013        struct ath6kl *ar;
4014        struct wiphy *wiphy;
4015
4016        /* create a new wiphy for use with cfg80211 */
4017        wiphy = wiphy_new(&ath6kl_cfg80211_ops, sizeof(struct ath6kl));
4018
4019        if (!wiphy) {
4020                ath6kl_err("couldn't allocate wiphy device\n");
4021                return NULL;
4022        }
4023
4024        ar = wiphy_priv(wiphy);
4025        ar->wiphy = wiphy;
4026
4027        return ar;
4028}
4029
4030/* Note: ar variable must not be accessed after calling this! */
4031void ath6kl_cfg80211_destroy(struct ath6kl *ar)
4032{
4033        int i;
4034
4035        for (i = 0; i < AP_MAX_NUM_STA; i++)
4036                kfree(ar->sta_list[i].aggr_conn);
4037
4038        wiphy_free(ar->wiphy);
4039}
4040
4041