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