linux/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2010 Broadcom Corporation
   3 *
   4 * Permission to use, copy, modify, and/or distribute this software for any
   5 * purpose with or without fee is hereby granted, provided that the above
   6 * copyright notice and this permission notice appear in all copies.
   7 *
   8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15 */
  16
  17/* Toplevel file. Relies on dhd_linux.c to send commands to the dongle. */
  18
  19#include <linux/kernel.h>
  20#include <linux/etherdevice.h>
  21#include <linux/module.h>
  22#include <linux/vmalloc.h>
  23#include <net/cfg80211.h>
  24#include <net/netlink.h>
  25
  26#include <brcmu_utils.h>
  27#include <defs.h>
  28#include <brcmu_wifi.h>
  29#include "core.h"
  30#include "debug.h"
  31#include "tracepoint.h"
  32#include "fwil_types.h"
  33#include "p2p.h"
  34#include "btcoex.h"
  35#include "pno.h"
  36#include "cfg80211.h"
  37#include "feature.h"
  38#include "fwil.h"
  39#include "proto.h"
  40#include "vendor.h"
  41#include "bus.h"
  42#include "common.h"
  43
  44#define BRCMF_SCAN_IE_LEN_MAX           2048
  45
  46#define WPA_OUI                         "\x00\x50\xF2"  /* WPA OUI */
  47#define WPA_OUI_TYPE                    1
  48#define RSN_OUI                         "\x00\x0F\xAC"  /* RSN OUI */
  49#define WME_OUI_TYPE                    2
  50#define WPS_OUI_TYPE                    4
  51
  52#define VS_IE_FIXED_HDR_LEN             6
  53#define WPA_IE_VERSION_LEN              2
  54#define WPA_IE_MIN_OUI_LEN              4
  55#define WPA_IE_SUITE_COUNT_LEN          2
  56
  57#define WPA_CIPHER_NONE                 0       /* None */
  58#define WPA_CIPHER_WEP_40               1       /* WEP (40-bit) */
  59#define WPA_CIPHER_TKIP                 2       /* TKIP: default for WPA */
  60#define WPA_CIPHER_AES_CCM              4       /* AES (CCM) */
  61#define WPA_CIPHER_WEP_104              5       /* WEP (104-bit) */
  62
  63#define RSN_AKM_NONE                    0       /* None (IBSS) */
  64#define RSN_AKM_UNSPECIFIED             1       /* Over 802.1x */
  65#define RSN_AKM_PSK                     2       /* Pre-shared Key */
  66#define RSN_AKM_SHA256_1X               5       /* SHA256, 802.1X */
  67#define RSN_AKM_SHA256_PSK              6       /* SHA256, Pre-shared Key */
  68#define RSN_CAP_LEN                     2       /* Length of RSN capabilities */
  69#define RSN_CAP_PTK_REPLAY_CNTR_MASK    (BIT(2) | BIT(3))
  70#define RSN_CAP_MFPR_MASK               BIT(6)
  71#define RSN_CAP_MFPC_MASK               BIT(7)
  72#define RSN_PMKID_COUNT_LEN             2
  73
  74#define VNDR_IE_CMD_LEN                 4       /* length of the set command
  75                                                 * string :"add", "del" (+ NUL)
  76                                                 */
  77#define VNDR_IE_COUNT_OFFSET            4
  78#define VNDR_IE_PKTFLAG_OFFSET          8
  79#define VNDR_IE_VSIE_OFFSET             12
  80#define VNDR_IE_HDR_SIZE                12
  81#define VNDR_IE_PARSE_LIMIT             5
  82
  83#define DOT11_MGMT_HDR_LEN              24      /* d11 management header len */
  84#define DOT11_BCN_PRB_FIXED_LEN         12      /* beacon/probe fixed length */
  85
  86#define BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS    320
  87#define BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS   400
  88#define BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS       20
  89
  90#define BRCMF_SCAN_CHANNEL_TIME         40
  91#define BRCMF_SCAN_UNASSOC_TIME         40
  92#define BRCMF_SCAN_PASSIVE_TIME         120
  93
  94#define BRCMF_ND_INFO_TIMEOUT           msecs_to_jiffies(2000)
  95
  96#define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
  97        (sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
  98
  99static bool check_vif_up(struct brcmf_cfg80211_vif *vif)
 100{
 101        if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state)) {
 102                brcmf_dbg(INFO, "device is not ready : status (%lu)\n",
 103                          vif->sme_state);
 104                return false;
 105        }
 106        return true;
 107}
 108
 109#define RATE_TO_BASE100KBPS(rate)   (((rate) * 10) / 2)
 110#define RATETAB_ENT(_rateid, _flags) \
 111        {                                                               \
 112                .bitrate        = RATE_TO_BASE100KBPS(_rateid),     \
 113                .hw_value       = (_rateid),                            \
 114                .flags          = (_flags),                             \
 115        }
 116
 117static struct ieee80211_rate __wl_rates[] = {
 118        RATETAB_ENT(BRCM_RATE_1M, 0),
 119        RATETAB_ENT(BRCM_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
 120        RATETAB_ENT(BRCM_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
 121        RATETAB_ENT(BRCM_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
 122        RATETAB_ENT(BRCM_RATE_6M, 0),
 123        RATETAB_ENT(BRCM_RATE_9M, 0),
 124        RATETAB_ENT(BRCM_RATE_12M, 0),
 125        RATETAB_ENT(BRCM_RATE_18M, 0),
 126        RATETAB_ENT(BRCM_RATE_24M, 0),
 127        RATETAB_ENT(BRCM_RATE_36M, 0),
 128        RATETAB_ENT(BRCM_RATE_48M, 0),
 129        RATETAB_ENT(BRCM_RATE_54M, 0),
 130};
 131
 132#define wl_g_rates              (__wl_rates + 0)
 133#define wl_g_rates_size         ARRAY_SIZE(__wl_rates)
 134#define wl_a_rates              (__wl_rates + 4)
 135#define wl_a_rates_size         (wl_g_rates_size - 4)
 136
 137#define CHAN2G(_channel, _freq) {                               \
 138        .band                   = NL80211_BAND_2GHZ,            \
 139        .center_freq            = (_freq),                      \
 140        .hw_value               = (_channel),                   \
 141        .max_antenna_gain       = 0,                            \
 142        .max_power              = 30,                           \
 143}
 144
 145#define CHAN5G(_channel) {                                      \
 146        .band                   = NL80211_BAND_5GHZ,            \
 147        .center_freq            = 5000 + (5 * (_channel)),      \
 148        .hw_value               = (_channel),                   \
 149        .max_antenna_gain       = 0,                            \
 150        .max_power              = 30,                           \
 151}
 152
 153static struct ieee80211_channel __wl_2ghz_channels[] = {
 154        CHAN2G(1, 2412), CHAN2G(2, 2417), CHAN2G(3, 2422), CHAN2G(4, 2427),
 155        CHAN2G(5, 2432), CHAN2G(6, 2437), CHAN2G(7, 2442), CHAN2G(8, 2447),
 156        CHAN2G(9, 2452), CHAN2G(10, 2457), CHAN2G(11, 2462), CHAN2G(12, 2467),
 157        CHAN2G(13, 2472), CHAN2G(14, 2484)
 158};
 159
 160static struct ieee80211_channel __wl_5ghz_channels[] = {
 161        CHAN5G(34), CHAN5G(36), CHAN5G(38), CHAN5G(40), CHAN5G(42),
 162        CHAN5G(44), CHAN5G(46), CHAN5G(48), CHAN5G(52), CHAN5G(56),
 163        CHAN5G(60), CHAN5G(64), CHAN5G(100), CHAN5G(104), CHAN5G(108),
 164        CHAN5G(112), CHAN5G(116), CHAN5G(120), CHAN5G(124), CHAN5G(128),
 165        CHAN5G(132), CHAN5G(136), CHAN5G(140), CHAN5G(144), CHAN5G(149),
 166        CHAN5G(153), CHAN5G(157), CHAN5G(161), CHAN5G(165)
 167};
 168
 169/* Band templates duplicated per wiphy. The channel info
 170 * above is added to the band during setup.
 171 */
 172static const struct ieee80211_supported_band __wl_band_2ghz = {
 173        .band = NL80211_BAND_2GHZ,
 174        .bitrates = wl_g_rates,
 175        .n_bitrates = wl_g_rates_size,
 176};
 177
 178static const struct ieee80211_supported_band __wl_band_5ghz = {
 179        .band = NL80211_BAND_5GHZ,
 180        .bitrates = wl_a_rates,
 181        .n_bitrates = wl_a_rates_size,
 182};
 183
 184/* This is to override regulatory domains defined in cfg80211 module (reg.c)
 185 * By default world regulatory domain defined in reg.c puts the flags
 186 * NL80211_RRF_NO_IR for 5GHz channels (for * 36..48 and 149..165).
 187 * With respect to these flags, wpa_supplicant doesn't * start p2p
 188 * operations on 5GHz channels. All the changes in world regulatory
 189 * domain are to be done here.
 190 */
 191static const struct ieee80211_regdomain brcmf_regdom = {
 192        .n_reg_rules = 4,
 193        .alpha2 =  "99",
 194        .reg_rules = {
 195                /* IEEE 802.11b/g, channels 1..11 */
 196                REG_RULE(2412-10, 2472+10, 40, 6, 20, 0),
 197                /* If any */
 198                /* IEEE 802.11 channel 14 - Only JP enables
 199                 * this and for 802.11b only
 200                 */
 201                REG_RULE(2484-10, 2484+10, 20, 6, 20, 0),
 202                /* IEEE 802.11a, channel 36..64 */
 203                REG_RULE(5150-10, 5350+10, 80, 6, 20, 0),
 204                /* IEEE 802.11a, channel 100..165 */
 205                REG_RULE(5470-10, 5850+10, 80, 6, 20, 0), }
 206};
 207
 208/* Note: brcmf_cipher_suites is an array of int defining which cipher suites
 209 * are supported. A pointer to this array and the number of entries is passed
 210 * on to upper layers. AES_CMAC defines whether or not the driver supports MFP.
 211 * So the cipher suite AES_CMAC has to be the last one in the array, and when
 212 * device does not support MFP then the number of suites will be decreased by 1
 213 */
 214static const u32 brcmf_cipher_suites[] = {
 215        WLAN_CIPHER_SUITE_WEP40,
 216        WLAN_CIPHER_SUITE_WEP104,
 217        WLAN_CIPHER_SUITE_TKIP,
 218        WLAN_CIPHER_SUITE_CCMP,
 219        /* Keep as last entry: */
 220        WLAN_CIPHER_SUITE_AES_CMAC
 221};
 222
 223/* Vendor specific ie. id = 221, oui and type defines exact ie */
 224struct brcmf_vs_tlv {
 225        u8 id;
 226        u8 len;
 227        u8 oui[3];
 228        u8 oui_type;
 229};
 230
 231struct parsed_vndr_ie_info {
 232        u8 *ie_ptr;
 233        u32 ie_len;     /* total length including id & length field */
 234        struct brcmf_vs_tlv vndrie;
 235};
 236
 237struct parsed_vndr_ies {
 238        u32 count;
 239        struct parsed_vndr_ie_info ie_info[VNDR_IE_PARSE_LIMIT];
 240};
 241
 242static u8 nl80211_band_to_fwil(enum nl80211_band band)
 243{
 244        switch (band) {
 245        case NL80211_BAND_2GHZ:
 246                return WLC_BAND_2G;
 247        case NL80211_BAND_5GHZ:
 248                return WLC_BAND_5G;
 249        default:
 250                WARN_ON(1);
 251                break;
 252        }
 253        return 0;
 254}
 255
 256static u16 chandef_to_chanspec(struct brcmu_d11inf *d11inf,
 257                               struct cfg80211_chan_def *ch)
 258{
 259        struct brcmu_chan ch_inf;
 260        s32 primary_offset;
 261
 262        brcmf_dbg(TRACE, "chandef: control %d center %d width %d\n",
 263                  ch->chan->center_freq, ch->center_freq1, ch->width);
 264        ch_inf.chnum = ieee80211_frequency_to_channel(ch->center_freq1);
 265        primary_offset = ch->chan->center_freq - ch->center_freq1;
 266        switch (ch->width) {
 267        case NL80211_CHAN_WIDTH_20:
 268        case NL80211_CHAN_WIDTH_20_NOHT:
 269                ch_inf.bw = BRCMU_CHAN_BW_20;
 270                WARN_ON(primary_offset != 0);
 271                break;
 272        case NL80211_CHAN_WIDTH_40:
 273                ch_inf.bw = BRCMU_CHAN_BW_40;
 274                if (primary_offset > 0)
 275                        ch_inf.sb = BRCMU_CHAN_SB_U;
 276                else
 277                        ch_inf.sb = BRCMU_CHAN_SB_L;
 278                break;
 279        case NL80211_CHAN_WIDTH_80:
 280                ch_inf.bw = BRCMU_CHAN_BW_80;
 281                if (primary_offset == -30)
 282                        ch_inf.sb = BRCMU_CHAN_SB_LL;
 283                else if (primary_offset == -10)
 284                        ch_inf.sb = BRCMU_CHAN_SB_LU;
 285                else if (primary_offset == 10)
 286                        ch_inf.sb = BRCMU_CHAN_SB_UL;
 287                else
 288                        ch_inf.sb = BRCMU_CHAN_SB_UU;
 289                break;
 290        case NL80211_CHAN_WIDTH_80P80:
 291        case NL80211_CHAN_WIDTH_160:
 292        case NL80211_CHAN_WIDTH_5:
 293        case NL80211_CHAN_WIDTH_10:
 294        default:
 295                WARN_ON_ONCE(1);
 296        }
 297        switch (ch->chan->band) {
 298        case NL80211_BAND_2GHZ:
 299                ch_inf.band = BRCMU_CHAN_BAND_2G;
 300                break;
 301        case NL80211_BAND_5GHZ:
 302                ch_inf.band = BRCMU_CHAN_BAND_5G;
 303                break;
 304        case NL80211_BAND_60GHZ:
 305        default:
 306                WARN_ON_ONCE(1);
 307        }
 308        d11inf->encchspec(&ch_inf);
 309
 310        return ch_inf.chspec;
 311}
 312
 313u16 channel_to_chanspec(struct brcmu_d11inf *d11inf,
 314                        struct ieee80211_channel *ch)
 315{
 316        struct brcmu_chan ch_inf;
 317
 318        ch_inf.chnum = ieee80211_frequency_to_channel(ch->center_freq);
 319        ch_inf.bw = BRCMU_CHAN_BW_20;
 320        d11inf->encchspec(&ch_inf);
 321
 322        return ch_inf.chspec;
 323}
 324
 325/* Traverse a string of 1-byte tag/1-byte length/variable-length value
 326 * triples, returning a pointer to the substring whose first element
 327 * matches tag
 328 */
 329static const struct brcmf_tlv *
 330brcmf_parse_tlvs(const void *buf, int buflen, uint key)
 331{
 332        const struct brcmf_tlv *elt = buf;
 333        int totlen = buflen;
 334
 335        /* find tagged parameter */
 336        while (totlen >= TLV_HDR_LEN) {
 337                int len = elt->len;
 338
 339                /* validate remaining totlen */
 340                if ((elt->id == key) && (totlen >= (len + TLV_HDR_LEN)))
 341                        return elt;
 342
 343                elt = (struct brcmf_tlv *)((u8 *)elt + (len + TLV_HDR_LEN));
 344                totlen -= (len + TLV_HDR_LEN);
 345        }
 346
 347        return NULL;
 348}
 349
 350/* Is any of the tlvs the expected entry? If
 351 * not update the tlvs buffer pointer/length.
 352 */
 353static bool
 354brcmf_tlv_has_ie(const u8 *ie, const u8 **tlvs, u32 *tlvs_len,
 355                 const u8 *oui, u32 oui_len, u8 type)
 356{
 357        /* If the contents match the OUI and the type */
 358        if (ie[TLV_LEN_OFF] >= oui_len + 1 &&
 359            !memcmp(&ie[TLV_BODY_OFF], oui, oui_len) &&
 360            type == ie[TLV_BODY_OFF + oui_len]) {
 361                return true;
 362        }
 363
 364        if (tlvs == NULL)
 365                return false;
 366        /* point to the next ie */
 367        ie += ie[TLV_LEN_OFF] + TLV_HDR_LEN;
 368        /* calculate the length of the rest of the buffer */
 369        *tlvs_len -= (int)(ie - *tlvs);
 370        /* update the pointer to the start of the buffer */
 371        *tlvs = ie;
 372
 373        return false;
 374}
 375
 376static struct brcmf_vs_tlv *
 377brcmf_find_wpaie(const u8 *parse, u32 len)
 378{
 379        const struct brcmf_tlv *ie;
 380
 381        while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
 382                if (brcmf_tlv_has_ie((const u8 *)ie, &parse, &len,
 383                                     WPA_OUI, TLV_OUI_LEN, WPA_OUI_TYPE))
 384                        return (struct brcmf_vs_tlv *)ie;
 385        }
 386        return NULL;
 387}
 388
 389static struct brcmf_vs_tlv *
 390brcmf_find_wpsie(const u8 *parse, u32 len)
 391{
 392        const struct brcmf_tlv *ie;
 393
 394        while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
 395                if (brcmf_tlv_has_ie((u8 *)ie, &parse, &len,
 396                                     WPA_OUI, TLV_OUI_LEN, WPS_OUI_TYPE))
 397                        return (struct brcmf_vs_tlv *)ie;
 398        }
 399        return NULL;
 400}
 401
 402static int brcmf_vif_change_validate(struct brcmf_cfg80211_info *cfg,
 403                                     struct brcmf_cfg80211_vif *vif,
 404                                     enum nl80211_iftype new_type)
 405{
 406        struct brcmf_cfg80211_vif *pos;
 407        bool check_combos = false;
 408        int ret = 0;
 409        struct iface_combination_params params = {
 410                .num_different_channels = 1,
 411        };
 412
 413        list_for_each_entry(pos, &cfg->vif_list, list)
 414                if (pos == vif) {
 415                        params.iftype_num[new_type]++;
 416                } else {
 417                        /* concurrent interfaces so need check combinations */
 418                        check_combos = true;
 419                        params.iftype_num[pos->wdev.iftype]++;
 420                }
 421
 422        if (check_combos)
 423                ret = cfg80211_check_combinations(cfg->wiphy, &params);
 424
 425        return ret;
 426}
 427
 428static int brcmf_vif_add_validate(struct brcmf_cfg80211_info *cfg,
 429                                  enum nl80211_iftype new_type)
 430{
 431        struct brcmf_cfg80211_vif *pos;
 432        struct iface_combination_params params = {
 433                .num_different_channels = 1,
 434        };
 435
 436        list_for_each_entry(pos, &cfg->vif_list, list)
 437                params.iftype_num[pos->wdev.iftype]++;
 438
 439        params.iftype_num[new_type]++;
 440        return cfg80211_check_combinations(cfg->wiphy, &params);
 441}
 442
 443static void convert_key_from_CPU(struct brcmf_wsec_key *key,
 444                                 struct brcmf_wsec_key_le *key_le)
 445{
 446        key_le->index = cpu_to_le32(key->index);
 447        key_le->len = cpu_to_le32(key->len);
 448        key_le->algo = cpu_to_le32(key->algo);
 449        key_le->flags = cpu_to_le32(key->flags);
 450        key_le->rxiv.hi = cpu_to_le32(key->rxiv.hi);
 451        key_le->rxiv.lo = cpu_to_le16(key->rxiv.lo);
 452        key_le->iv_initialized = cpu_to_le32(key->iv_initialized);
 453        memcpy(key_le->data, key->data, sizeof(key->data));
 454        memcpy(key_le->ea, key->ea, sizeof(key->ea));
 455}
 456
 457static int
 458send_key_to_dongle(struct brcmf_if *ifp, struct brcmf_wsec_key *key)
 459{
 460        int err;
 461        struct brcmf_wsec_key_le key_le;
 462
 463        convert_key_from_CPU(key, &key_le);
 464
 465        brcmf_netdev_wait_pend8021x(ifp);
 466
 467        err = brcmf_fil_bsscfg_data_set(ifp, "wsec_key", &key_le,
 468                                        sizeof(key_le));
 469
 470        if (err)
 471                brcmf_err("wsec_key error (%d)\n", err);
 472        return err;
 473}
 474
 475static void
 476brcmf_cfg80211_update_proto_addr_mode(struct wireless_dev *wdev)
 477{
 478        struct brcmf_cfg80211_vif *vif;
 479        struct brcmf_if *ifp;
 480
 481        vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
 482        ifp = vif->ifp;
 483
 484        if ((wdev->iftype == NL80211_IFTYPE_ADHOC) ||
 485            (wdev->iftype == NL80211_IFTYPE_AP) ||
 486            (wdev->iftype == NL80211_IFTYPE_P2P_GO))
 487                brcmf_proto_configure_addr_mode(ifp->drvr, ifp->ifidx,
 488                                                ADDR_DIRECT);
 489        else
 490                brcmf_proto_configure_addr_mode(ifp->drvr, ifp->ifidx,
 491                                                ADDR_INDIRECT);
 492}
 493
 494static int brcmf_get_first_free_bsscfgidx(struct brcmf_pub *drvr)
 495{
 496        int bsscfgidx;
 497
 498        for (bsscfgidx = 0; bsscfgidx < BRCMF_MAX_IFS; bsscfgidx++) {
 499                /* bsscfgidx 1 is reserved for legacy P2P */
 500                if (bsscfgidx == 1)
 501                        continue;
 502                if (!drvr->iflist[bsscfgidx])
 503                        return bsscfgidx;
 504        }
 505
 506        return -ENOMEM;
 507}
 508
 509static int brcmf_cfg80211_request_ap_if(struct brcmf_if *ifp)
 510{
 511        struct brcmf_mbss_ssid_le mbss_ssid_le;
 512        int bsscfgidx;
 513        int err;
 514
 515        memset(&mbss_ssid_le, 0, sizeof(mbss_ssid_le));
 516        bsscfgidx = brcmf_get_first_free_bsscfgidx(ifp->drvr);
 517        if (bsscfgidx < 0)
 518                return bsscfgidx;
 519
 520        mbss_ssid_le.bsscfgidx = cpu_to_le32(bsscfgidx);
 521        mbss_ssid_le.SSID_len = cpu_to_le32(5);
 522        sprintf(mbss_ssid_le.SSID, "ssid%d" , bsscfgidx);
 523
 524        err = brcmf_fil_bsscfg_data_set(ifp, "bsscfg:ssid", &mbss_ssid_le,
 525                                        sizeof(mbss_ssid_le));
 526        if (err < 0)
 527                brcmf_err("setting ssid failed %d\n", err);
 528
 529        return err;
 530}
 531
 532/**
 533 * brcmf_ap_add_vif() - create a new AP virtual interface for multiple BSS
 534 *
 535 * @wiphy: wiphy device of new interface.
 536 * @name: name of the new interface.
 537 * @params: contains mac address for AP device.
 538 */
 539static
 540struct wireless_dev *brcmf_ap_add_vif(struct wiphy *wiphy, const char *name,
 541                                      struct vif_params *params)
 542{
 543        struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
 544        struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
 545        struct brcmf_cfg80211_vif *vif;
 546        int err;
 547
 548        if (brcmf_cfg80211_vif_event_armed(cfg))
 549                return ERR_PTR(-EBUSY);
 550
 551        brcmf_dbg(INFO, "Adding vif \"%s\"\n", name);
 552
 553        vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_AP);
 554        if (IS_ERR(vif))
 555                return (struct wireless_dev *)vif;
 556
 557        brcmf_cfg80211_arm_vif_event(cfg, vif);
 558
 559        err = brcmf_cfg80211_request_ap_if(ifp);
 560        if (err) {
 561                brcmf_cfg80211_arm_vif_event(cfg, NULL);
 562                goto fail;
 563        }
 564
 565        /* wait for firmware event */
 566        err = brcmf_cfg80211_wait_vif_event(cfg, BRCMF_E_IF_ADD,
 567                                            BRCMF_VIF_EVENT_TIMEOUT);
 568        brcmf_cfg80211_arm_vif_event(cfg, NULL);
 569        if (!err) {
 570                brcmf_err("timeout occurred\n");
 571                err = -EIO;
 572                goto fail;
 573        }
 574
 575        /* interface created in firmware */
 576        ifp = vif->ifp;
 577        if (!ifp) {
 578                brcmf_err("no if pointer provided\n");
 579                err = -ENOENT;
 580                goto fail;
 581        }
 582
 583        strncpy(ifp->ndev->name, name, sizeof(ifp->ndev->name) - 1);
 584        err = brcmf_net_attach(ifp, true);
 585        if (err) {
 586                brcmf_err("Registering netdevice failed\n");
 587                free_netdev(ifp->ndev);
 588                goto fail;
 589        }
 590
 591        return &ifp->vif->wdev;
 592
 593fail:
 594        brcmf_free_vif(vif);
 595        return ERR_PTR(err);
 596}
 597
 598static bool brcmf_is_apmode(struct brcmf_cfg80211_vif *vif)
 599{
 600        enum nl80211_iftype iftype;
 601
 602        iftype = vif->wdev.iftype;
 603        return iftype == NL80211_IFTYPE_AP || iftype == NL80211_IFTYPE_P2P_GO;
 604}
 605
 606static bool brcmf_is_ibssmode(struct brcmf_cfg80211_vif *vif)
 607{
 608        return vif->wdev.iftype == NL80211_IFTYPE_ADHOC;
 609}
 610
 611static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy,
 612                                                     const char *name,
 613                                                     unsigned char name_assign_type,
 614                                                     enum nl80211_iftype type,
 615                                                     struct vif_params *params)
 616{
 617        struct wireless_dev *wdev;
 618        int err;
 619
 620        brcmf_dbg(TRACE, "enter: %s type %d\n", name, type);
 621        err = brcmf_vif_add_validate(wiphy_to_cfg(wiphy), type);
 622        if (err) {
 623                brcmf_err("iface validation failed: err=%d\n", err);
 624                return ERR_PTR(err);
 625        }
 626        switch (type) {
 627        case NL80211_IFTYPE_ADHOC:
 628        case NL80211_IFTYPE_STATION:
 629        case NL80211_IFTYPE_AP_VLAN:
 630        case NL80211_IFTYPE_WDS:
 631        case NL80211_IFTYPE_MONITOR:
 632        case NL80211_IFTYPE_MESH_POINT:
 633                return ERR_PTR(-EOPNOTSUPP);
 634        case NL80211_IFTYPE_AP:
 635                wdev = brcmf_ap_add_vif(wiphy, name, params);
 636                break;
 637        case NL80211_IFTYPE_P2P_CLIENT:
 638        case NL80211_IFTYPE_P2P_GO:
 639        case NL80211_IFTYPE_P2P_DEVICE:
 640                wdev = brcmf_p2p_add_vif(wiphy, name, name_assign_type, type, params);
 641                break;
 642        case NL80211_IFTYPE_UNSPECIFIED:
 643        default:
 644                return ERR_PTR(-EINVAL);
 645        }
 646
 647        if (IS_ERR(wdev))
 648                brcmf_err("add iface %s type %d failed: err=%d\n",
 649                          name, type, (int)PTR_ERR(wdev));
 650        else
 651                brcmf_cfg80211_update_proto_addr_mode(wdev);
 652
 653        return wdev;
 654}
 655
 656static void brcmf_scan_config_mpc(struct brcmf_if *ifp, int mpc)
 657{
 658        if (brcmf_feat_is_quirk_enabled(ifp, BRCMF_FEAT_QUIRK_NEED_MPC))
 659                brcmf_set_mpc(ifp, mpc);
 660}
 661
 662void brcmf_set_mpc(struct brcmf_if *ifp, int mpc)
 663{
 664        s32 err = 0;
 665
 666        if (check_vif_up(ifp->vif)) {
 667                err = brcmf_fil_iovar_int_set(ifp, "mpc", mpc);
 668                if (err) {
 669                        brcmf_err("fail to set mpc\n");
 670                        return;
 671                }
 672                brcmf_dbg(INFO, "MPC : %d\n", mpc);
 673        }
 674}
 675
 676s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
 677                                struct brcmf_if *ifp, bool aborted,
 678                                bool fw_abort)
 679{
 680        struct brcmf_scan_params_le params_le;
 681        struct cfg80211_scan_request *scan_request;
 682        u64 reqid;
 683        u32 bucket;
 684        s32 err = 0;
 685
 686        brcmf_dbg(SCAN, "Enter\n");
 687
 688        /* clear scan request, because the FW abort can cause a second call */
 689        /* to this functon and might cause a double cfg80211_scan_done      */
 690        scan_request = cfg->scan_request;
 691        cfg->scan_request = NULL;
 692
 693        if (timer_pending(&cfg->escan_timeout))
 694                del_timer_sync(&cfg->escan_timeout);
 695
 696        if (fw_abort) {
 697                /* Do a scan abort to stop the driver's scan engine */
 698                brcmf_dbg(SCAN, "ABORT scan in firmware\n");
 699                memset(&params_le, 0, sizeof(params_le));
 700                eth_broadcast_addr(params_le.bssid);
 701                params_le.bss_type = DOT11_BSSTYPE_ANY;
 702                params_le.scan_type = 0;
 703                params_le.channel_num = cpu_to_le32(1);
 704                params_le.nprobes = cpu_to_le32(1);
 705                params_le.active_time = cpu_to_le32(-1);
 706                params_le.passive_time = cpu_to_le32(-1);
 707                params_le.home_time = cpu_to_le32(-1);
 708                /* Scan is aborted by setting channel_list[0] to -1 */
 709                params_le.channel_list[0] = cpu_to_le16(-1);
 710                /* E-Scan (or anyother type) can be aborted by SCAN */
 711                err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
 712                                             &params_le, sizeof(params_le));
 713                if (err)
 714                        brcmf_err("Scan abort failed\n");
 715        }
 716
 717        brcmf_scan_config_mpc(ifp, 1);
 718
 719        /*
 720         * e-scan can be initiated internally
 721         * which takes precedence.
 722         */
 723        if (cfg->int_escan_map) {
 724                brcmf_dbg(SCAN, "scheduled scan completed (%x)\n",
 725                          cfg->int_escan_map);
 726                while (cfg->int_escan_map) {
 727                        bucket = __ffs(cfg->int_escan_map);
 728                        cfg->int_escan_map &= ~BIT(bucket);
 729                        reqid = brcmf_pno_find_reqid_by_bucket(cfg->pno,
 730                                                               bucket);
 731                        if (!aborted) {
 732                                brcmf_dbg(SCAN, "report results: reqid=%llu\n",
 733                                          reqid);
 734                                cfg80211_sched_scan_results(cfg_to_wiphy(cfg),
 735                                                            reqid);
 736                        }
 737                }
 738        } else if (scan_request) {
 739                struct cfg80211_scan_info info = {
 740                        .aborted = aborted,
 741                };
 742
 743                brcmf_dbg(SCAN, "ESCAN Completed scan: %s\n",
 744                          aborted ? "Aborted" : "Done");
 745                cfg80211_scan_done(scan_request, &info);
 746        }
 747        if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
 748                brcmf_dbg(SCAN, "Scan complete, probably P2P scan\n");
 749
 750        return err;
 751}
 752
 753static int brcmf_cfg80211_del_ap_iface(struct wiphy *wiphy,
 754                                       struct wireless_dev *wdev)
 755{
 756        struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
 757        struct net_device *ndev = wdev->netdev;
 758        struct brcmf_if *ifp = netdev_priv(ndev);
 759        int ret;
 760        int err;
 761
 762        brcmf_cfg80211_arm_vif_event(cfg, ifp->vif);
 763
 764        err = brcmf_fil_bsscfg_data_set(ifp, "interface_remove", NULL, 0);
 765        if (err) {
 766                brcmf_err("interface_remove failed %d\n", err);
 767                goto err_unarm;
 768        }
 769
 770        /* wait for firmware event */
 771        ret = brcmf_cfg80211_wait_vif_event(cfg, BRCMF_E_IF_DEL,
 772                                            BRCMF_VIF_EVENT_TIMEOUT);
 773        if (!ret) {
 774                brcmf_err("timeout occurred\n");
 775                err = -EIO;
 776                goto err_unarm;
 777        }
 778
 779        brcmf_remove_interface(ifp, true);
 780
 781err_unarm:
 782        brcmf_cfg80211_arm_vif_event(cfg, NULL);
 783        return err;
 784}
 785
 786static
 787int brcmf_cfg80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev)
 788{
 789        struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
 790        struct net_device *ndev = wdev->netdev;
 791
 792        if (ndev && ndev == cfg_to_ndev(cfg))
 793                return -ENOTSUPP;
 794
 795        /* vif event pending in firmware */
 796        if (brcmf_cfg80211_vif_event_armed(cfg))
 797                return -EBUSY;
 798
 799        if (ndev) {
 800                if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status) &&
 801                    cfg->escan_info.ifp == netdev_priv(ndev))
 802                        brcmf_notify_escan_complete(cfg, netdev_priv(ndev),
 803                                                    true, true);
 804
 805                brcmf_fil_iovar_int_set(netdev_priv(ndev), "mpc", 1);
 806        }
 807
 808        switch (wdev->iftype) {
 809        case NL80211_IFTYPE_ADHOC:
 810        case NL80211_IFTYPE_STATION:
 811        case NL80211_IFTYPE_AP_VLAN:
 812        case NL80211_IFTYPE_WDS:
 813        case NL80211_IFTYPE_MONITOR:
 814        case NL80211_IFTYPE_MESH_POINT:
 815                return -EOPNOTSUPP;
 816        case NL80211_IFTYPE_AP:
 817                return brcmf_cfg80211_del_ap_iface(wiphy, wdev);
 818        case NL80211_IFTYPE_P2P_CLIENT:
 819        case NL80211_IFTYPE_P2P_GO:
 820        case NL80211_IFTYPE_P2P_DEVICE:
 821                return brcmf_p2p_del_vif(wiphy, wdev);
 822        case NL80211_IFTYPE_UNSPECIFIED:
 823        default:
 824                return -EINVAL;
 825        }
 826        return -EOPNOTSUPP;
 827}
 828
 829static s32
 830brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
 831                         enum nl80211_iftype type,
 832                         struct vif_params *params)
 833{
 834        struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
 835        struct brcmf_if *ifp = netdev_priv(ndev);
 836        struct brcmf_cfg80211_vif *vif = ifp->vif;
 837        s32 infra = 0;
 838        s32 ap = 0;
 839        s32 err = 0;
 840
 841        brcmf_dbg(TRACE, "Enter, bsscfgidx=%d, type=%d\n", ifp->bsscfgidx,
 842                  type);
 843
 844        /* WAR: There are a number of p2p interface related problems which
 845         * need to be handled initially (before doing the validate).
 846         * wpa_supplicant tends to do iface changes on p2p device/client/go
 847         * which are not always possible/allowed. However we need to return
 848         * OK otherwise the wpa_supplicant wont start. The situation differs
 849         * on configuration and setup (p2pon=1 module param). The first check
 850         * is to see if the request is a change to station for p2p iface.
 851         */
 852        if ((type == NL80211_IFTYPE_STATION) &&
 853            ((vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) ||
 854             (vif->wdev.iftype == NL80211_IFTYPE_P2P_GO) ||
 855             (vif->wdev.iftype == NL80211_IFTYPE_P2P_DEVICE))) {
 856                brcmf_dbg(TRACE, "Ignoring cmd for p2p if\n");
 857                /* Now depending on whether module param p2pon=1 was used the
 858                 * response needs to be either 0 or EOPNOTSUPP. The reason is
 859                 * that if p2pon=1 is used, but a newer supplicant is used then
 860                 * we should return an error, as this combination wont work.
 861                 * In other situations 0 is returned and supplicant will start
 862                 * normally. It will give a trace in cfg80211, but it is the
 863                 * only way to get it working. Unfortunately this will result
 864                 * in situation where we wont support new supplicant in
 865                 * combination with module param p2pon=1, but that is the way
 866                 * it is. If the user tries this then unloading of driver might
 867                 * fail/lock.
 868                 */
 869                if (cfg->p2p.p2pdev_dynamically)
 870                        return -EOPNOTSUPP;
 871                else
 872                        return 0;
 873        }
 874        err = brcmf_vif_change_validate(wiphy_to_cfg(wiphy), vif, type);
 875        if (err) {
 876                brcmf_err("iface validation failed: err=%d\n", err);
 877                return err;
 878        }
 879        switch (type) {
 880        case NL80211_IFTYPE_MONITOR:
 881        case NL80211_IFTYPE_WDS:
 882                brcmf_err("type (%d) : currently we do not support this type\n",
 883                          type);
 884                return -EOPNOTSUPP;
 885        case NL80211_IFTYPE_ADHOC:
 886                infra = 0;
 887                break;
 888        case NL80211_IFTYPE_STATION:
 889                infra = 1;
 890                break;
 891        case NL80211_IFTYPE_AP:
 892        case NL80211_IFTYPE_P2P_GO:
 893                ap = 1;
 894                break;
 895        default:
 896                err = -EINVAL;
 897                goto done;
 898        }
 899
 900        if (ap) {
 901                if (type == NL80211_IFTYPE_P2P_GO) {
 902                        brcmf_dbg(INFO, "IF Type = P2P GO\n");
 903                        err = brcmf_p2p_ifchange(cfg, BRCMF_FIL_P2P_IF_GO);
 904                }
 905                if (!err) {
 906                        brcmf_dbg(INFO, "IF Type = AP\n");
 907                }
 908        } else {
 909                err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, infra);
 910                if (err) {
 911                        brcmf_err("WLC_SET_INFRA error (%d)\n", err);
 912                        err = -EAGAIN;
 913                        goto done;
 914                }
 915                brcmf_dbg(INFO, "IF Type = %s\n", brcmf_is_ibssmode(vif) ?
 916                          "Adhoc" : "Infra");
 917        }
 918        ndev->ieee80211_ptr->iftype = type;
 919
 920        brcmf_cfg80211_update_proto_addr_mode(&vif->wdev);
 921
 922done:
 923        brcmf_dbg(TRACE, "Exit\n");
 924
 925        return err;
 926}
 927
 928static void brcmf_escan_prep(struct brcmf_cfg80211_info *cfg,
 929                             struct brcmf_scan_params_le *params_le,
 930                             struct cfg80211_scan_request *request)
 931{
 932        u32 n_ssids;
 933        u32 n_channels;
 934        s32 i;
 935        s32 offset;
 936        u16 chanspec;
 937        char *ptr;
 938        struct brcmf_ssid_le ssid_le;
 939
 940        eth_broadcast_addr(params_le->bssid);
 941        params_le->bss_type = DOT11_BSSTYPE_ANY;
 942        params_le->scan_type = BRCMF_SCANTYPE_ACTIVE;
 943        params_le->channel_num = 0;
 944        params_le->nprobes = cpu_to_le32(-1);
 945        params_le->active_time = cpu_to_le32(-1);
 946        params_le->passive_time = cpu_to_le32(-1);
 947        params_le->home_time = cpu_to_le32(-1);
 948        memset(&params_le->ssid_le, 0, sizeof(params_le->ssid_le));
 949
 950        n_ssids = request->n_ssids;
 951        n_channels = request->n_channels;
 952
 953        /* Copy channel array if applicable */
 954        brcmf_dbg(SCAN, "### List of channelspecs to scan ### %d\n",
 955                  n_channels);
 956        if (n_channels > 0) {
 957                for (i = 0; i < n_channels; i++) {
 958                        chanspec = channel_to_chanspec(&cfg->d11inf,
 959                                                       request->channels[i]);
 960                        brcmf_dbg(SCAN, "Chan : %d, Channel spec: %x\n",
 961                                  request->channels[i]->hw_value, chanspec);
 962                        params_le->channel_list[i] = cpu_to_le16(chanspec);
 963                }
 964        } else {
 965                brcmf_dbg(SCAN, "Scanning all channels\n");
 966        }
 967        /* Copy ssid array if applicable */
 968        brcmf_dbg(SCAN, "### List of SSIDs to scan ### %d\n", n_ssids);
 969        if (n_ssids > 0) {
 970                offset = offsetof(struct brcmf_scan_params_le, channel_list) +
 971                                n_channels * sizeof(u16);
 972                offset = roundup(offset, sizeof(u32));
 973                ptr = (char *)params_le + offset;
 974                for (i = 0; i < n_ssids; i++) {
 975                        memset(&ssid_le, 0, sizeof(ssid_le));
 976                        ssid_le.SSID_len =
 977                                        cpu_to_le32(request->ssids[i].ssid_len);
 978                        memcpy(ssid_le.SSID, request->ssids[i].ssid,
 979                               request->ssids[i].ssid_len);
 980                        if (!ssid_le.SSID_len)
 981                                brcmf_dbg(SCAN, "%d: Broadcast scan\n", i);
 982                        else
 983                                brcmf_dbg(SCAN, "%d: scan for  %.32s size=%d\n",
 984                                          i, ssid_le.SSID, ssid_le.SSID_len);
 985                        memcpy(ptr, &ssid_le, sizeof(ssid_le));
 986                        ptr += sizeof(ssid_le);
 987                }
 988        } else {
 989                brcmf_dbg(SCAN, "Performing passive scan\n");
 990                params_le->scan_type = BRCMF_SCANTYPE_PASSIVE;
 991        }
 992        /* Adding mask to channel numbers */
 993        params_le->channel_num =
 994                cpu_to_le32((n_ssids << BRCMF_SCAN_PARAMS_NSSID_SHIFT) |
 995                        (n_channels & BRCMF_SCAN_PARAMS_COUNT_MASK));
 996}
 997
 998static s32
 999brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp,
1000                struct cfg80211_scan_request *request)
1001{
1002        s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
1003                          offsetof(struct brcmf_escan_params_le, params_le);
1004        struct brcmf_escan_params_le *params;
1005        s32 err = 0;
1006
1007        brcmf_dbg(SCAN, "E-SCAN START\n");
1008
1009        if (request != NULL) {
1010                /* Allocate space for populating ssids in struct */
1011                params_size += sizeof(u32) * ((request->n_channels + 1) / 2);
1012
1013                /* Allocate space for populating ssids in struct */
1014                params_size += sizeof(struct brcmf_ssid_le) * request->n_ssids;
1015        }
1016
1017        params = kzalloc(params_size, GFP_KERNEL);
1018        if (!params) {
1019                err = -ENOMEM;
1020                goto exit;
1021        }
1022        BUG_ON(params_size + sizeof("escan") >= BRCMF_DCMD_MEDLEN);
1023        brcmf_escan_prep(cfg, &params->params_le, request);
1024        params->version = cpu_to_le32(BRCMF_ESCAN_REQ_VERSION);
1025        params->action = cpu_to_le16(WL_ESCAN_ACTION_START);
1026        params->sync_id = cpu_to_le16(0x1234);
1027
1028        err = brcmf_fil_iovar_data_set(ifp, "escan", params, params_size);
1029        if (err) {
1030                if (err == -EBUSY)
1031                        brcmf_dbg(INFO, "system busy : escan canceled\n");
1032                else
1033                        brcmf_err("error (%d)\n", err);
1034        }
1035
1036        kfree(params);
1037exit:
1038        return err;
1039}
1040
1041static s32
1042brcmf_do_escan(struct brcmf_if *ifp, struct cfg80211_scan_request *request)
1043{
1044        struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
1045        s32 err;
1046        struct brcmf_scan_results *results;
1047        struct escan_info *escan = &cfg->escan_info;
1048
1049        brcmf_dbg(SCAN, "Enter\n");
1050        escan->ifp = ifp;
1051        escan->wiphy = cfg->wiphy;
1052        escan->escan_state = WL_ESCAN_STATE_SCANNING;
1053
1054        brcmf_scan_config_mpc(ifp, 0);
1055        results = (struct brcmf_scan_results *)cfg->escan_info.escan_buf;
1056        results->version = 0;
1057        results->count = 0;
1058        results->buflen = WL_ESCAN_RESULTS_FIXED_SIZE;
1059
1060        err = escan->run(cfg, ifp, request);
1061        if (err)
1062                brcmf_scan_config_mpc(ifp, 1);
1063        return err;
1064}
1065
1066static s32
1067brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
1068{
1069        struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1070        struct brcmf_cfg80211_vif *vif;
1071        s32 err = 0;
1072
1073        brcmf_dbg(TRACE, "Enter\n");
1074        vif = container_of(request->wdev, struct brcmf_cfg80211_vif, wdev);
1075        if (!check_vif_up(vif))
1076                return -EIO;
1077
1078        if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
1079                brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status);
1080                return -EAGAIN;
1081        }
1082        if (test_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status)) {
1083                brcmf_err("Scanning being aborted: status (%lu)\n",
1084                          cfg->scan_status);
1085                return -EAGAIN;
1086        }
1087        if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) {
1088                brcmf_err("Scanning suppressed: status (%lu)\n",
1089                          cfg->scan_status);
1090                return -EAGAIN;
1091        }
1092        if (test_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state)) {
1093                brcmf_err("Connecting: status (%lu)\n", vif->sme_state);
1094                return -EAGAIN;
1095        }
1096
1097        /* If scan req comes for p2p0, send it over primary I/F */
1098        if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
1099                vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif;
1100
1101        brcmf_dbg(SCAN, "START ESCAN\n");
1102
1103        cfg->scan_request = request;
1104        set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
1105
1106        cfg->escan_info.run = brcmf_run_escan;
1107        err = brcmf_p2p_scan_prep(wiphy, request, vif);
1108        if (err)
1109                goto scan_out;
1110
1111        err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_PRBREQ_FLAG,
1112                                    request->ie, request->ie_len);
1113        if (err)
1114                goto scan_out;
1115
1116        err = brcmf_do_escan(vif->ifp, request);
1117        if (err)
1118                goto scan_out;
1119
1120        /* Arm scan timeout timer */
1121        mod_timer(&cfg->escan_timeout,
1122                  jiffies + msecs_to_jiffies(BRCMF_ESCAN_TIMER_INTERVAL_MS));
1123
1124        return 0;
1125
1126scan_out:
1127        brcmf_err("scan error (%d)\n", err);
1128        clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
1129        cfg->scan_request = NULL;
1130        return err;
1131}
1132
1133static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold)
1134{
1135        s32 err = 0;
1136
1137        err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "rtsthresh",
1138                                      rts_threshold);
1139        if (err)
1140                brcmf_err("Error (%d)\n", err);
1141
1142        return err;
1143}
1144
1145static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold)
1146{
1147        s32 err = 0;
1148
1149        err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "fragthresh",
1150                                      frag_threshold);
1151        if (err)
1152                brcmf_err("Error (%d)\n", err);
1153
1154        return err;
1155}
1156
1157static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l)
1158{
1159        s32 err = 0;
1160        u32 cmd = (l ? BRCMF_C_SET_LRL : BRCMF_C_SET_SRL);
1161
1162        err = brcmf_fil_cmd_int_set(netdev_priv(ndev), cmd, retry);
1163        if (err) {
1164                brcmf_err("cmd (%d) , error (%d)\n", cmd, err);
1165                return err;
1166        }
1167        return err;
1168}
1169
1170static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1171{
1172        struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1173        struct net_device *ndev = cfg_to_ndev(cfg);
1174        struct brcmf_if *ifp = netdev_priv(ndev);
1175        s32 err = 0;
1176
1177        brcmf_dbg(TRACE, "Enter\n");
1178        if (!check_vif_up(ifp->vif))
1179                return -EIO;
1180
1181        if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
1182            (cfg->conf->rts_threshold != wiphy->rts_threshold)) {
1183                cfg->conf->rts_threshold = wiphy->rts_threshold;
1184                err = brcmf_set_rts(ndev, cfg->conf->rts_threshold);
1185                if (!err)
1186                        goto done;
1187        }
1188        if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
1189            (cfg->conf->frag_threshold != wiphy->frag_threshold)) {
1190                cfg->conf->frag_threshold = wiphy->frag_threshold;
1191                err = brcmf_set_frag(ndev, cfg->conf->frag_threshold);
1192                if (!err)
1193                        goto done;
1194        }
1195        if (changed & WIPHY_PARAM_RETRY_LONG
1196            && (cfg->conf->retry_long != wiphy->retry_long)) {
1197                cfg->conf->retry_long = wiphy->retry_long;
1198                err = brcmf_set_retry(ndev, cfg->conf->retry_long, true);
1199                if (!err)
1200                        goto done;
1201        }
1202        if (changed & WIPHY_PARAM_RETRY_SHORT
1203            && (cfg->conf->retry_short != wiphy->retry_short)) {
1204                cfg->conf->retry_short = wiphy->retry_short;
1205                err = brcmf_set_retry(ndev, cfg->conf->retry_short, false);
1206                if (!err)
1207                        goto done;
1208        }
1209
1210done:
1211        brcmf_dbg(TRACE, "Exit\n");
1212        return err;
1213}
1214
1215static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof)
1216{
1217        memset(prof, 0, sizeof(*prof));
1218}
1219
1220static u16 brcmf_map_fw_linkdown_reason(const struct brcmf_event_msg *e)
1221{
1222        u16 reason;
1223
1224        switch (e->event_code) {
1225        case BRCMF_E_DEAUTH:
1226        case BRCMF_E_DEAUTH_IND:
1227        case BRCMF_E_DISASSOC_IND:
1228                reason = e->reason;
1229                break;
1230        case BRCMF_E_LINK:
1231        default:
1232                reason = 0;
1233                break;
1234        }
1235        return reason;
1236}
1237
1238static int brcmf_set_pmk(struct brcmf_if *ifp, const u8 *pmk_data, u16 pmk_len)
1239{
1240        struct brcmf_wsec_pmk_le pmk;
1241        int i, err;
1242
1243        /* convert to firmware key format */
1244        pmk.key_len = cpu_to_le16(pmk_len << 1);
1245        pmk.flags = cpu_to_le16(BRCMF_WSEC_PASSPHRASE);
1246        for (i = 0; i < pmk_len; i++)
1247                snprintf(&pmk.key[2 * i], 3, "%02x", pmk_data[i]);
1248
1249        /* store psk in firmware */
1250        err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_WSEC_PMK,
1251                                     &pmk, sizeof(pmk));
1252        if (err < 0)
1253                brcmf_err("failed to change PSK in firmware (len=%u)\n",
1254                          pmk_len);
1255
1256        return err;
1257}
1258
1259static void brcmf_link_down(struct brcmf_cfg80211_vif *vif, u16 reason)
1260{
1261        struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(vif->wdev.wiphy);
1262        s32 err = 0;
1263
1264        brcmf_dbg(TRACE, "Enter\n");
1265
1266        if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state)) {
1267                brcmf_dbg(INFO, "Call WLC_DISASSOC to stop excess roaming\n ");
1268                err = brcmf_fil_cmd_data_set(vif->ifp,
1269                                             BRCMF_C_DISASSOC, NULL, 0);
1270                if (err) {
1271                        brcmf_err("WLC_DISASSOC failed (%d)\n", err);
1272                }
1273                if ((vif->wdev.iftype == NL80211_IFTYPE_STATION) ||
1274                    (vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT))
1275                        cfg80211_disconnected(vif->wdev.netdev, reason, NULL, 0,
1276                                              true, GFP_KERNEL);
1277        }
1278        clear_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state);
1279        clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
1280        brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_ENABLED, 0);
1281        if (vif->profile.use_fwsup != BRCMF_PROFILE_FWSUP_NONE) {
1282                brcmf_set_pmk(vif->ifp, NULL, 0);
1283                vif->profile.use_fwsup = BRCMF_PROFILE_FWSUP_NONE;
1284        }
1285        brcmf_dbg(TRACE, "Exit\n");
1286}
1287
1288static s32
1289brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
1290                      struct cfg80211_ibss_params *params)
1291{
1292        struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1293        struct brcmf_if *ifp = netdev_priv(ndev);
1294        struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1295        struct brcmf_join_params join_params;
1296        size_t join_params_size = 0;
1297        s32 err = 0;
1298        s32 wsec = 0;
1299        s32 bcnprd;
1300        u16 chanspec;
1301        u32 ssid_len;
1302
1303        brcmf_dbg(TRACE, "Enter\n");
1304        if (!check_vif_up(ifp->vif))
1305                return -EIO;
1306
1307        if (params->ssid)
1308                brcmf_dbg(CONN, "SSID: %s\n", params->ssid);
1309        else {
1310                brcmf_dbg(CONN, "SSID: NULL, Not supported\n");
1311                return -EOPNOTSUPP;
1312        }
1313
1314        set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1315
1316        if (params->bssid)
1317                brcmf_dbg(CONN, "BSSID: %pM\n", params->bssid);
1318        else
1319                brcmf_dbg(CONN, "No BSSID specified\n");
1320
1321        if (params->chandef.chan)
1322                brcmf_dbg(CONN, "channel: %d\n",
1323                          params->chandef.chan->center_freq);
1324        else
1325                brcmf_dbg(CONN, "no channel specified\n");
1326
1327        if (params->channel_fixed)
1328                brcmf_dbg(CONN, "fixed channel required\n");
1329        else
1330                brcmf_dbg(CONN, "no fixed channel required\n");
1331
1332        if (params->ie && params->ie_len)
1333                brcmf_dbg(CONN, "ie len: %d\n", params->ie_len);
1334        else
1335                brcmf_dbg(CONN, "no ie specified\n");
1336
1337        if (params->beacon_interval)
1338                brcmf_dbg(CONN, "beacon interval: %d\n",
1339                          params->beacon_interval);
1340        else
1341                brcmf_dbg(CONN, "no beacon interval specified\n");
1342
1343        if (params->basic_rates)
1344                brcmf_dbg(CONN, "basic rates: %08X\n", params->basic_rates);
1345        else
1346                brcmf_dbg(CONN, "no basic rates specified\n");
1347
1348        if (params->privacy)
1349                brcmf_dbg(CONN, "privacy required\n");
1350        else
1351                brcmf_dbg(CONN, "no privacy required\n");
1352
1353        /* Configure Privacy for starter */
1354        if (params->privacy)
1355                wsec |= WEP_ENABLED;
1356
1357        err = brcmf_fil_iovar_int_set(ifp, "wsec", wsec);
1358        if (err) {
1359                brcmf_err("wsec failed (%d)\n", err);
1360                goto done;
1361        }
1362
1363        /* Configure Beacon Interval for starter */
1364        if (params->beacon_interval)
1365                bcnprd = params->beacon_interval;
1366        else
1367                bcnprd = 100;
1368
1369        err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD, bcnprd);
1370        if (err) {
1371                brcmf_err("WLC_SET_BCNPRD failed (%d)\n", err);
1372                goto done;
1373        }
1374
1375        /* Configure required join parameter */
1376        memset(&join_params, 0, sizeof(struct brcmf_join_params));
1377
1378        /* SSID */
1379        ssid_len = min_t(u32, params->ssid_len, IEEE80211_MAX_SSID_LEN);
1380        memcpy(join_params.ssid_le.SSID, params->ssid, ssid_len);
1381        join_params.ssid_le.SSID_len = cpu_to_le32(ssid_len);
1382        join_params_size = sizeof(join_params.ssid_le);
1383
1384        /* BSSID */
1385        if (params->bssid) {
1386                memcpy(join_params.params_le.bssid, params->bssid, ETH_ALEN);
1387                join_params_size += BRCMF_ASSOC_PARAMS_FIXED_SIZE;
1388                memcpy(profile->bssid, params->bssid, ETH_ALEN);
1389        } else {
1390                eth_broadcast_addr(join_params.params_le.bssid);
1391                eth_zero_addr(profile->bssid);
1392        }
1393
1394        /* Channel */
1395        if (params->chandef.chan) {
1396                u32 target_channel;
1397
1398                cfg->channel =
1399                        ieee80211_frequency_to_channel(
1400                                params->chandef.chan->center_freq);
1401                if (params->channel_fixed) {
1402                        /* adding chanspec */
1403                        chanspec = chandef_to_chanspec(&cfg->d11inf,
1404                                                       &params->chandef);
1405                        join_params.params_le.chanspec_list[0] =
1406                                cpu_to_le16(chanspec);
1407                        join_params.params_le.chanspec_num = cpu_to_le32(1);
1408                        join_params_size += sizeof(join_params.params_le);
1409                }
1410
1411                /* set channel for starter */
1412                target_channel = cfg->channel;
1413                err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_CHANNEL,
1414                                            target_channel);
1415                if (err) {
1416                        brcmf_err("WLC_SET_CHANNEL failed (%d)\n", err);
1417                        goto done;
1418                }
1419        } else
1420                cfg->channel = 0;
1421
1422        cfg->ibss_starter = false;
1423
1424
1425        err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
1426                                     &join_params, join_params_size);
1427        if (err) {
1428                brcmf_err("WLC_SET_SSID failed (%d)\n", err);
1429                goto done;
1430        }
1431
1432done:
1433        if (err)
1434                clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1435        brcmf_dbg(TRACE, "Exit\n");
1436        return err;
1437}
1438
1439static s32
1440brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
1441{
1442        struct brcmf_if *ifp = netdev_priv(ndev);
1443
1444        brcmf_dbg(TRACE, "Enter\n");
1445        if (!check_vif_up(ifp->vif)) {
1446                /* When driver is being unloaded, it can end up here. If an
1447                 * error is returned then later on a debug trace in the wireless
1448                 * core module will be printed. To avoid this 0 is returned.
1449                 */
1450                return 0;
1451        }
1452
1453        brcmf_link_down(ifp->vif, WLAN_REASON_DEAUTH_LEAVING);
1454        brcmf_net_setcarrier(ifp, false);
1455
1456        brcmf_dbg(TRACE, "Exit\n");
1457
1458        return 0;
1459}
1460
1461static s32 brcmf_set_wpa_version(struct net_device *ndev,
1462                                 struct cfg80211_connect_params *sme)
1463{
1464        struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1465        struct brcmf_cfg80211_security *sec;
1466        s32 val = 0;
1467        s32 err = 0;
1468
1469        if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1470                val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
1471        else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1472                val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
1473        else
1474                val = WPA_AUTH_DISABLED;
1475        brcmf_dbg(CONN, "setting wpa_auth to 0x%0x\n", val);
1476        err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wpa_auth", val);
1477        if (err) {
1478                brcmf_err("set wpa_auth failed (%d)\n", err);
1479                return err;
1480        }
1481        sec = &profile->sec;
1482        sec->wpa_versions = sme->crypto.wpa_versions;
1483        return err;
1484}
1485
1486static s32 brcmf_set_auth_type(struct net_device *ndev,
1487                               struct cfg80211_connect_params *sme)
1488{
1489        struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1490        struct brcmf_cfg80211_security *sec;
1491        s32 val = 0;
1492        s32 err = 0;
1493
1494        switch (sme->auth_type) {
1495        case NL80211_AUTHTYPE_OPEN_SYSTEM:
1496                val = 0;
1497                brcmf_dbg(CONN, "open system\n");
1498                break;
1499        case NL80211_AUTHTYPE_SHARED_KEY:
1500                val = 1;
1501                brcmf_dbg(CONN, "shared key\n");
1502                break;
1503        default:
1504                val = 2;
1505                brcmf_dbg(CONN, "automatic, auth type (%d)\n", sme->auth_type);
1506                break;
1507        }
1508
1509        err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "auth", val);
1510        if (err) {
1511                brcmf_err("set auth failed (%d)\n", err);
1512                return err;
1513        }
1514        sec = &profile->sec;
1515        sec->auth_type = sme->auth_type;
1516        return err;
1517}
1518
1519static s32
1520brcmf_set_wsec_mode(struct net_device *ndev,
1521                    struct cfg80211_connect_params *sme)
1522{
1523        struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1524        struct brcmf_cfg80211_security *sec;
1525        s32 pval = 0;
1526        s32 gval = 0;
1527        s32 wsec;
1528        s32 err = 0;
1529
1530        if (sme->crypto.n_ciphers_pairwise) {
1531                switch (sme->crypto.ciphers_pairwise[0]) {
1532                case WLAN_CIPHER_SUITE_WEP40:
1533                case WLAN_CIPHER_SUITE_WEP104:
1534                        pval = WEP_ENABLED;
1535                        break;
1536                case WLAN_CIPHER_SUITE_TKIP:
1537                        pval = TKIP_ENABLED;
1538                        break;
1539                case WLAN_CIPHER_SUITE_CCMP:
1540                        pval = AES_ENABLED;
1541                        break;
1542                case WLAN_CIPHER_SUITE_AES_CMAC:
1543                        pval = AES_ENABLED;
1544                        break;
1545                default:
1546                        brcmf_err("invalid cipher pairwise (%d)\n",
1547                                  sme->crypto.ciphers_pairwise[0]);
1548                        return -EINVAL;
1549                }
1550        }
1551        if (sme->crypto.cipher_group) {
1552                switch (sme->crypto.cipher_group) {
1553                case WLAN_CIPHER_SUITE_WEP40:
1554                case WLAN_CIPHER_SUITE_WEP104:
1555                        gval = WEP_ENABLED;
1556                        break;
1557                case WLAN_CIPHER_SUITE_TKIP:
1558                        gval = TKIP_ENABLED;
1559                        break;
1560                case WLAN_CIPHER_SUITE_CCMP:
1561                        gval = AES_ENABLED;
1562                        break;
1563                case WLAN_CIPHER_SUITE_AES_CMAC:
1564                        gval = AES_ENABLED;
1565                        break;
1566                default:
1567                        brcmf_err("invalid cipher group (%d)\n",
1568                                  sme->crypto.cipher_group);
1569                        return -EINVAL;
1570                }
1571        }
1572
1573        brcmf_dbg(CONN, "pval (%d) gval (%d)\n", pval, gval);
1574        /* In case of privacy, but no security and WPS then simulate */
1575        /* setting AES. WPS-2.0 allows no security                   */
1576        if (brcmf_find_wpsie(sme->ie, sme->ie_len) && !pval && !gval &&
1577            sme->privacy)
1578                pval = AES_ENABLED;
1579
1580        wsec = pval | gval;
1581        err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wsec", wsec);
1582        if (err) {
1583                brcmf_err("error (%d)\n", err);
1584                return err;
1585        }
1586
1587        sec = &profile->sec;
1588        sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1589        sec->cipher_group = sme->crypto.cipher_group;
1590
1591        return err;
1592}
1593
1594static s32
1595brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
1596{
1597        struct brcmf_if *ifp = netdev_priv(ndev);
1598        struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1599        s32 val;
1600        s32 err;
1601        const struct brcmf_tlv *rsn_ie;
1602        const u8 *ie;
1603        u32 ie_len;
1604        u32 offset;
1605        u16 rsn_cap;
1606        u32 mfp;
1607        u16 count;
1608
1609        profile->use_fwsup = BRCMF_PROFILE_FWSUP_NONE;
1610
1611        if (!sme->crypto.n_akm_suites)
1612                return 0;
1613
1614        err = brcmf_fil_bsscfg_int_get(netdev_priv(ndev), "wpa_auth", &val);
1615        if (err) {
1616                brcmf_err("could not get wpa_auth (%d)\n", err);
1617                return err;
1618        }
1619        if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1620                switch (sme->crypto.akm_suites[0]) {
1621                case WLAN_AKM_SUITE_8021X:
1622                        val = WPA_AUTH_UNSPECIFIED;
1623                        if (sme->want_1x)
1624                                profile->use_fwsup = BRCMF_PROFILE_FWSUP_1X;
1625                        break;
1626                case WLAN_AKM_SUITE_PSK:
1627                        val = WPA_AUTH_PSK;
1628                        break;
1629                default:
1630                        brcmf_err("invalid cipher group (%d)\n",
1631                                  sme->crypto.cipher_group);
1632                        return -EINVAL;
1633                }
1634        } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1635                switch (sme->crypto.akm_suites[0]) {
1636                case WLAN_AKM_SUITE_8021X:
1637                        val = WPA2_AUTH_UNSPECIFIED;
1638                        if (sme->want_1x)
1639                                profile->use_fwsup = BRCMF_PROFILE_FWSUP_1X;
1640                        break;
1641                case WLAN_AKM_SUITE_8021X_SHA256:
1642                        val = WPA2_AUTH_1X_SHA256;
1643                        if (sme->want_1x)
1644                                profile->use_fwsup = BRCMF_PROFILE_FWSUP_1X;
1645                        break;
1646                case WLAN_AKM_SUITE_PSK_SHA256:
1647                        val = WPA2_AUTH_PSK_SHA256;
1648                        break;
1649                case WLAN_AKM_SUITE_PSK:
1650                        val = WPA2_AUTH_PSK;
1651                        break;
1652                default:
1653                        brcmf_err("invalid cipher group (%d)\n",
1654                                  sme->crypto.cipher_group);
1655                        return -EINVAL;
1656                }
1657        }
1658
1659        if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_1X)
1660                brcmf_dbg(INFO, "using 1X offload\n");
1661
1662        if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP))
1663                goto skip_mfp_config;
1664        /* The MFP mode (1 or 2) needs to be determined, parse IEs. The
1665         * IE will not be verified, just a quick search for MFP config
1666         */
1667        rsn_ie = brcmf_parse_tlvs((const u8 *)sme->ie, sme->ie_len,
1668                                  WLAN_EID_RSN);
1669        if (!rsn_ie)
1670                goto skip_mfp_config;
1671        ie = (const u8 *)rsn_ie;
1672        ie_len = rsn_ie->len + TLV_HDR_LEN;
1673        /* Skip unicast suite */
1674        offset = TLV_HDR_LEN + WPA_IE_VERSION_LEN + WPA_IE_MIN_OUI_LEN;
1675        if (offset + WPA_IE_SUITE_COUNT_LEN >= ie_len)
1676                goto skip_mfp_config;
1677        /* Skip multicast suite */
1678        count = ie[offset] + (ie[offset + 1] << 8);
1679        offset += WPA_IE_SUITE_COUNT_LEN + (count * WPA_IE_MIN_OUI_LEN);
1680        if (offset + WPA_IE_SUITE_COUNT_LEN >= ie_len)
1681                goto skip_mfp_config;
1682        /* Skip auth key management suite(s) */
1683        count = ie[offset] + (ie[offset + 1] << 8);
1684        offset += WPA_IE_SUITE_COUNT_LEN + (count * WPA_IE_MIN_OUI_LEN);
1685        if (offset + WPA_IE_SUITE_COUNT_LEN > ie_len)
1686                goto skip_mfp_config;
1687        /* Ready to read capabilities */
1688        mfp = BRCMF_MFP_NONE;
1689        rsn_cap = ie[offset] + (ie[offset + 1] << 8);
1690        if (rsn_cap & RSN_CAP_MFPR_MASK)
1691                mfp = BRCMF_MFP_REQUIRED;
1692        else if (rsn_cap & RSN_CAP_MFPC_MASK)
1693                mfp = BRCMF_MFP_CAPABLE;
1694        brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "mfp", mfp);
1695
1696skip_mfp_config:
1697        brcmf_dbg(CONN, "setting wpa_auth to %d\n", val);
1698        err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wpa_auth", val);
1699        if (err) {
1700                brcmf_err("could not set wpa_auth (%d)\n", err);
1701                return err;
1702        }
1703
1704        return err;
1705}
1706
1707static s32
1708brcmf_set_sharedkey(struct net_device *ndev,
1709                    struct cfg80211_connect_params *sme)
1710{
1711        struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1712        struct brcmf_cfg80211_security *sec;
1713        struct brcmf_wsec_key key;
1714        s32 val;
1715        s32 err = 0;
1716
1717        brcmf_dbg(CONN, "key len (%d)\n", sme->key_len);
1718
1719        if (sme->key_len == 0)
1720                return 0;
1721
1722        sec = &profile->sec;
1723        brcmf_dbg(CONN, "wpa_versions 0x%x cipher_pairwise 0x%x\n",
1724                  sec->wpa_versions, sec->cipher_pairwise);
1725
1726        if (sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
1727                return 0;
1728
1729        if (!(sec->cipher_pairwise &
1730            (WLAN_CIPHER_SUITE_WEP40 | WLAN_CIPHER_SUITE_WEP104)))
1731                return 0;
1732
1733        memset(&key, 0, sizeof(key));
1734        key.len = (u32) sme->key_len;
1735        key.index = (u32) sme->key_idx;
1736        if (key.len > sizeof(key.data)) {
1737                brcmf_err("Too long key length (%u)\n", key.len);
1738                return -EINVAL;
1739        }
1740        memcpy(key.data, sme->key, key.len);
1741        key.flags = BRCMF_PRIMARY_KEY;
1742        switch (sec->cipher_pairwise) {
1743        case WLAN_CIPHER_SUITE_WEP40:
1744                key.algo = CRYPTO_ALGO_WEP1;
1745                break;
1746        case WLAN_CIPHER_SUITE_WEP104:
1747                key.algo = CRYPTO_ALGO_WEP128;
1748                break;
1749        default:
1750                brcmf_err("Invalid algorithm (%d)\n",
1751                          sme->crypto.ciphers_pairwise[0]);
1752                return -EINVAL;
1753        }
1754        /* Set the new key/index */
1755        brcmf_dbg(CONN, "key length (%d) key index (%d) algo (%d)\n",
1756                  key.len, key.index, key.algo);
1757        brcmf_dbg(CONN, "key \"%s\"\n", key.data);
1758        err = send_key_to_dongle(netdev_priv(ndev), &key);
1759        if (err)
1760                return err;
1761
1762        if (sec->auth_type == NL80211_AUTHTYPE_SHARED_KEY) {
1763                brcmf_dbg(CONN, "set auth_type to shared key\n");
1764                val = WL_AUTH_SHARED_KEY;       /* shared key */
1765                err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "auth", val);
1766                if (err)
1767                        brcmf_err("set auth failed (%d)\n", err);
1768        }
1769        return err;
1770}
1771
1772static
1773enum nl80211_auth_type brcmf_war_auth_type(struct brcmf_if *ifp,
1774                                           enum nl80211_auth_type type)
1775{
1776        if (type == NL80211_AUTHTYPE_AUTOMATIC &&
1777            brcmf_feat_is_quirk_enabled(ifp, BRCMF_FEAT_QUIRK_AUTO_AUTH)) {
1778                brcmf_dbg(CONN, "WAR: use OPEN instead of AUTO\n");
1779                type = NL80211_AUTHTYPE_OPEN_SYSTEM;
1780        }
1781        return type;
1782}
1783
1784static void brcmf_set_join_pref(struct brcmf_if *ifp,
1785                                struct cfg80211_bss_selection *bss_select)
1786{
1787        struct brcmf_join_pref_params join_pref_params[2];
1788        enum nl80211_band band;
1789        int err, i = 0;
1790
1791        join_pref_params[i].len = 2;
1792        join_pref_params[i].rssi_gain = 0;
1793
1794        if (bss_select->behaviour != NL80211_BSS_SELECT_ATTR_BAND_PREF)
1795                brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_ASSOC_PREFER, WLC_BAND_AUTO);
1796
1797        switch (bss_select->behaviour) {
1798        case __NL80211_BSS_SELECT_ATTR_INVALID:
1799                brcmf_c_set_joinpref_default(ifp);
1800                return;
1801        case NL80211_BSS_SELECT_ATTR_BAND_PREF:
1802                join_pref_params[i].type = BRCMF_JOIN_PREF_BAND;
1803                band = bss_select->param.band_pref;
1804                join_pref_params[i].band = nl80211_band_to_fwil(band);
1805                i++;
1806                break;
1807        case NL80211_BSS_SELECT_ATTR_RSSI_ADJUST:
1808                join_pref_params[i].type = BRCMF_JOIN_PREF_RSSI_DELTA;
1809                band = bss_select->param.adjust.band;
1810                join_pref_params[i].band = nl80211_band_to_fwil(band);
1811                join_pref_params[i].rssi_gain = bss_select->param.adjust.delta;
1812                i++;
1813                break;
1814        case NL80211_BSS_SELECT_ATTR_RSSI:
1815        default:
1816                break;
1817        }
1818        join_pref_params[i].type = BRCMF_JOIN_PREF_RSSI;
1819        join_pref_params[i].len = 2;
1820        join_pref_params[i].rssi_gain = 0;
1821        join_pref_params[i].band = 0;
1822        err = brcmf_fil_iovar_data_set(ifp, "join_pref", join_pref_params,
1823                                       sizeof(join_pref_params));
1824        if (err)
1825                brcmf_err("Set join_pref error (%d)\n", err);
1826}
1827
1828static s32
1829brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1830                       struct cfg80211_connect_params *sme)
1831{
1832        struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1833        struct brcmf_if *ifp = netdev_priv(ndev);
1834        struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1835        struct ieee80211_channel *chan = sme->channel;
1836        struct brcmf_join_params join_params;
1837        size_t join_params_size;
1838        const struct brcmf_tlv *rsn_ie;
1839        const struct brcmf_vs_tlv *wpa_ie;
1840        const void *ie;
1841        u32 ie_len;
1842        struct brcmf_ext_join_params_le *ext_join_params;
1843        u16 chanspec;
1844        s32 err = 0;
1845        u32 ssid_len;
1846
1847        brcmf_dbg(TRACE, "Enter\n");
1848        if (!check_vif_up(ifp->vif))
1849                return -EIO;
1850
1851        if (!sme->ssid) {
1852                brcmf_err("Invalid ssid\n");
1853                return -EOPNOTSUPP;
1854        }
1855
1856        if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif) {
1857                /* A normal (non P2P) connection request setup. */
1858                ie = NULL;
1859                ie_len = 0;
1860                /* find the WPA_IE */
1861                wpa_ie = brcmf_find_wpaie((u8 *)sme->ie, sme->ie_len);
1862                if (wpa_ie) {
1863                        ie = wpa_ie;
1864                        ie_len = wpa_ie->len + TLV_HDR_LEN;
1865                } else {
1866                        /* find the RSN_IE */
1867                        rsn_ie = brcmf_parse_tlvs((const u8 *)sme->ie,
1868                                                  sme->ie_len,
1869                                                  WLAN_EID_RSN);
1870                        if (rsn_ie) {
1871                                ie = rsn_ie;
1872                                ie_len = rsn_ie->len + TLV_HDR_LEN;
1873                        }
1874                }
1875                brcmf_fil_iovar_data_set(ifp, "wpaie", ie, ie_len);
1876        }
1877
1878        err = brcmf_vif_set_mgmt_ie(ifp->vif, BRCMF_VNDR_IE_ASSOCREQ_FLAG,
1879                                    sme->ie, sme->ie_len);
1880        if (err)
1881                brcmf_err("Set Assoc REQ IE Failed\n");
1882        else
1883                brcmf_dbg(TRACE, "Applied Vndr IEs for Assoc request\n");
1884
1885        set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1886
1887        if (chan) {
1888                cfg->channel =
1889                        ieee80211_frequency_to_channel(chan->center_freq);
1890                chanspec = channel_to_chanspec(&cfg->d11inf, chan);
1891                brcmf_dbg(CONN, "channel=%d, center_req=%d, chanspec=0x%04x\n",
1892                          cfg->channel, chan->center_freq, chanspec);
1893        } else {
1894                cfg->channel = 0;
1895                chanspec = 0;
1896        }
1897
1898        brcmf_dbg(INFO, "ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
1899
1900        err = brcmf_set_wpa_version(ndev, sme);
1901        if (err) {
1902                brcmf_err("wl_set_wpa_version failed (%d)\n", err);
1903                goto done;
1904        }
1905
1906        sme->auth_type = brcmf_war_auth_type(ifp, sme->auth_type);
1907        err = brcmf_set_auth_type(ndev, sme);
1908        if (err) {
1909                brcmf_err("wl_set_auth_type failed (%d)\n", err);
1910                goto done;
1911        }
1912
1913        err = brcmf_set_wsec_mode(ndev, sme);
1914        if (err) {
1915                brcmf_err("wl_set_set_cipher failed (%d)\n", err);
1916                goto done;
1917        }
1918
1919        err = brcmf_set_key_mgmt(ndev, sme);
1920        if (err) {
1921                brcmf_err("wl_set_key_mgmt failed (%d)\n", err);
1922                goto done;
1923        }
1924
1925        err = brcmf_set_sharedkey(ndev, sme);
1926        if (err) {
1927                brcmf_err("brcmf_set_sharedkey failed (%d)\n", err);
1928                goto done;
1929        }
1930
1931        if (sme->crypto.psk) {
1932                if (WARN_ON(profile->use_fwsup != BRCMF_PROFILE_FWSUP_NONE)) {
1933                        err = -EINVAL;
1934                        goto done;
1935                }
1936                brcmf_dbg(INFO, "using PSK offload\n");
1937                profile->use_fwsup = BRCMF_PROFILE_FWSUP_PSK;
1938        }
1939
1940        if (profile->use_fwsup != BRCMF_PROFILE_FWSUP_NONE) {
1941                /* enable firmware supplicant for this interface */
1942                err = brcmf_fil_iovar_int_set(ifp, "sup_wpa", 1);
1943                if (err < 0) {
1944                        brcmf_err("failed to enable fw supplicant\n");
1945                        goto done;
1946                }
1947        }
1948
1949        if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_PSK) {
1950                err = brcmf_set_pmk(ifp, sme->crypto.psk,
1951                                    BRCMF_WSEC_MAX_PSK_LEN);
1952                if (err)
1953                        goto done;
1954        }
1955
1956        /* Join with specific BSSID and cached SSID
1957         * If SSID is zero join based on BSSID only
1958         */
1959        join_params_size = offsetof(struct brcmf_ext_join_params_le, assoc_le) +
1960                offsetof(struct brcmf_assoc_params_le, chanspec_list);
1961        if (cfg->channel)
1962                join_params_size += sizeof(u16);
1963        ext_join_params = kzalloc(join_params_size, GFP_KERNEL);
1964        if (ext_join_params == NULL) {
1965                err = -ENOMEM;
1966                goto done;
1967        }
1968        ssid_len = min_t(u32, sme->ssid_len, IEEE80211_MAX_SSID_LEN);
1969        ext_join_params->ssid_le.SSID_len = cpu_to_le32(ssid_len);
1970        memcpy(&ext_join_params->ssid_le.SSID, sme->ssid, ssid_len);
1971        if (ssid_len < IEEE80211_MAX_SSID_LEN)
1972                brcmf_dbg(CONN, "SSID \"%s\", len (%d)\n",
1973                          ext_join_params->ssid_le.SSID, ssid_len);
1974
1975        /* Set up join scan parameters */
1976        ext_join_params->scan_le.scan_type = -1;
1977        ext_join_params->scan_le.home_time = cpu_to_le32(-1);
1978
1979        if (sme->bssid)
1980                memcpy(&ext_join_params->assoc_le.bssid, sme->bssid, ETH_ALEN);
1981        else
1982                eth_broadcast_addr(ext_join_params->assoc_le.bssid);
1983
1984        if (cfg->channel) {
1985                ext_join_params->assoc_le.chanspec_num = cpu_to_le32(1);
1986
1987                ext_join_params->assoc_le.chanspec_list[0] =
1988                        cpu_to_le16(chanspec);
1989                /* Increase dwell time to receive probe response or detect
1990                 * beacon from target AP at a noisy air only during connect
1991                 * command.
1992                 */
1993                ext_join_params->scan_le.active_time =
1994                        cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS);
1995                ext_join_params->scan_le.passive_time =
1996                        cpu_to_le32(BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS);
1997                /* To sync with presence period of VSDB GO send probe request
1998                 * more frequently. Probe request will be stopped when it gets
1999                 * probe response from target AP/GO.
2000                 */
2001                ext_join_params->scan_le.nprobes =
2002                        cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS /
2003                                    BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS);
2004        } else {
2005                ext_join_params->scan_le.active_time = cpu_to_le32(-1);
2006                ext_join_params->scan_le.passive_time = cpu_to_le32(-1);
2007                ext_join_params->scan_le.nprobes = cpu_to_le32(-1);
2008        }
2009
2010        brcmf_set_join_pref(ifp, &sme->bss_select);
2011
2012        err  = brcmf_fil_bsscfg_data_set(ifp, "join", ext_join_params,
2013                                         join_params_size);
2014        kfree(ext_join_params);
2015        if (!err)
2016                /* This is it. join command worked, we are done */
2017                goto done;
2018
2019        /* join command failed, fallback to set ssid */
2020        memset(&join_params, 0, sizeof(join_params));
2021        join_params_size = sizeof(join_params.ssid_le);
2022
2023        memcpy(&join_params.ssid_le.SSID, sme->ssid, ssid_len);
2024        join_params.ssid_le.SSID_len = cpu_to_le32(ssid_len);
2025
2026        if (sme->bssid)
2027                memcpy(join_params.params_le.bssid, sme->bssid, ETH_ALEN);
2028        else
2029                eth_broadcast_addr(join_params.params_le.bssid);
2030
2031        if (cfg->channel) {
2032                join_params.params_le.chanspec_list[0] = cpu_to_le16(chanspec);
2033                join_params.params_le.chanspec_num = cpu_to_le32(1);
2034                join_params_size += sizeof(join_params.params_le);
2035        }
2036        err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
2037                                     &join_params, join_params_size);
2038        if (err)
2039                brcmf_err("BRCMF_C_SET_SSID failed (%d)\n", err);
2040
2041done:
2042        if (err)
2043                clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
2044        brcmf_dbg(TRACE, "Exit\n");
2045        return err;
2046}
2047
2048static s32
2049brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
2050                       u16 reason_code)
2051{
2052        struct brcmf_if *ifp = netdev_priv(ndev);
2053        struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
2054        struct brcmf_scb_val_le scbval;
2055        s32 err = 0;
2056
2057        brcmf_dbg(TRACE, "Enter. Reason code = %d\n", reason_code);
2058        if (!check_vif_up(ifp->vif))
2059                return -EIO;
2060
2061        clear_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
2062        clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
2063        cfg80211_disconnected(ndev, reason_code, NULL, 0, true, GFP_KERNEL);
2064
2065        memcpy(&scbval.ea, &profile->bssid, ETH_ALEN);
2066        scbval.val = cpu_to_le32(reason_code);
2067        err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_DISASSOC,
2068                                     &scbval, sizeof(scbval));
2069        if (err)
2070                brcmf_err("error (%d)\n", err);
2071
2072        brcmf_dbg(TRACE, "Exit\n");
2073        return err;
2074}
2075
2076static s32
2077brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
2078                            enum nl80211_tx_power_setting type, s32 mbm)
2079{
2080        struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2081        struct net_device *ndev = cfg_to_ndev(cfg);
2082        struct brcmf_if *ifp = netdev_priv(ndev);
2083        s32 err;
2084        s32 disable;
2085        u32 qdbm = 127;
2086
2087        brcmf_dbg(TRACE, "Enter %d %d\n", type, mbm);
2088        if (!check_vif_up(ifp->vif))
2089                return -EIO;
2090
2091        switch (type) {
2092        case NL80211_TX_POWER_AUTOMATIC:
2093                break;
2094        case NL80211_TX_POWER_LIMITED:
2095        case NL80211_TX_POWER_FIXED:
2096                if (mbm < 0) {
2097                        brcmf_err("TX_POWER_FIXED - dbm is negative\n");
2098                        err = -EINVAL;
2099                        goto done;
2100                }
2101                qdbm =  MBM_TO_DBM(4 * mbm);
2102                if (qdbm > 127)
2103                        qdbm = 127;
2104                qdbm |= WL_TXPWR_OVERRIDE;
2105                break;
2106        default:
2107                brcmf_err("Unsupported type %d\n", type);
2108                err = -EINVAL;
2109                goto done;
2110        }
2111        /* Make sure radio is off or on as far as software is concerned */
2112        disable = WL_RADIO_SW_DISABLE << 16;
2113        err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_RADIO, disable);
2114        if (err)
2115                brcmf_err("WLC_SET_RADIO error (%d)\n", err);
2116
2117        err = brcmf_fil_iovar_int_set(ifp, "qtxpower", qdbm);
2118        if (err)
2119                brcmf_err("qtxpower error (%d)\n", err);
2120
2121done:
2122        brcmf_dbg(TRACE, "Exit %d (qdbm)\n", qdbm & ~WL_TXPWR_OVERRIDE);
2123        return err;
2124}
2125
2126static s32
2127brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
2128                            s32 *dbm)
2129{
2130        struct brcmf_cfg80211_vif *vif = wdev_to_vif(wdev);
2131        s32 qdbm = 0;
2132        s32 err;
2133
2134        brcmf_dbg(TRACE, "Enter\n");
2135        if (!check_vif_up(vif))
2136                return -EIO;
2137
2138        err = brcmf_fil_iovar_int_get(vif->ifp, "qtxpower", &qdbm);
2139        if (err) {
2140                brcmf_err("error (%d)\n", err);
2141                goto done;
2142        }
2143        *dbm = (qdbm & ~WL_TXPWR_OVERRIDE) / 4;
2144
2145done:
2146        brcmf_dbg(TRACE, "Exit (0x%x %d)\n", qdbm, *dbm);
2147        return err;
2148}
2149
2150static s32
2151brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
2152                                  u8 key_idx, bool unicast, bool multicast)
2153{
2154        struct brcmf_if *ifp = netdev_priv(ndev);
2155        u32 index;
2156        u32 wsec;
2157        s32 err = 0;
2158
2159        brcmf_dbg(TRACE, "Enter\n");
2160        brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2161        if (!check_vif_up(ifp->vif))
2162                return -EIO;
2163
2164        err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2165        if (err) {
2166                brcmf_err("WLC_GET_WSEC error (%d)\n", err);
2167                goto done;
2168        }
2169
2170        if (wsec & WEP_ENABLED) {
2171                /* Just select a new current key */
2172                index = key_idx;
2173                err = brcmf_fil_cmd_int_set(ifp,
2174                                            BRCMF_C_SET_KEY_PRIMARY, index);
2175                if (err)
2176                        brcmf_err("error (%d)\n", err);
2177        }
2178done:
2179        brcmf_dbg(TRACE, "Exit\n");
2180        return err;
2181}
2182
2183static s32
2184brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
2185                       u8 key_idx, bool pairwise, const u8 *mac_addr)
2186{
2187        struct brcmf_if *ifp = netdev_priv(ndev);
2188        struct brcmf_wsec_key *key;
2189        s32 err;
2190
2191        brcmf_dbg(TRACE, "Enter\n");
2192        brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2193
2194        if (!check_vif_up(ifp->vif))
2195                return -EIO;
2196
2197        if (key_idx >= BRCMF_MAX_DEFAULT_KEYS) {
2198                /* we ignore this key index in this case */
2199                return -EINVAL;
2200        }
2201
2202        key = &ifp->vif->profile.key[key_idx];
2203
2204        if (key->algo == CRYPTO_ALGO_OFF) {
2205                brcmf_dbg(CONN, "Ignore clearing of (never configured) key\n");
2206                return -EINVAL;
2207        }
2208
2209        memset(key, 0, sizeof(*key));
2210        key->index = (u32)key_idx;
2211        key->flags = BRCMF_PRIMARY_KEY;
2212
2213        /* Clear the key/index */
2214        err = send_key_to_dongle(ifp, key);
2215
2216        brcmf_dbg(TRACE, "Exit\n");
2217        return err;
2218}
2219
2220static s32
2221brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
2222                       u8 key_idx, bool pairwise, const u8 *mac_addr,
2223                       struct key_params *params)
2224{
2225        struct brcmf_if *ifp = netdev_priv(ndev);
2226        struct brcmf_wsec_key *key;
2227        s32 val;
2228        s32 wsec;
2229        s32 err;
2230        u8 keybuf[8];
2231        bool ext_key;
2232
2233        brcmf_dbg(TRACE, "Enter\n");
2234        brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2235        if (!check_vif_up(ifp->vif))
2236                return -EIO;
2237
2238        if (key_idx >= BRCMF_MAX_DEFAULT_KEYS) {
2239                /* we ignore this key index in this case */
2240                brcmf_err("invalid key index (%d)\n", key_idx);
2241                return -EINVAL;
2242        }
2243
2244        if (params->key_len == 0)
2245                return brcmf_cfg80211_del_key(wiphy, ndev, key_idx, pairwise,
2246                                              mac_addr);
2247
2248        if (params->key_len > sizeof(key->data)) {
2249                brcmf_err("Too long key length (%u)\n", params->key_len);
2250                return -EINVAL;
2251        }
2252
2253        ext_key = false;
2254        if (mac_addr && (params->cipher != WLAN_CIPHER_SUITE_WEP40) &&
2255            (params->cipher != WLAN_CIPHER_SUITE_WEP104)) {
2256                brcmf_dbg(TRACE, "Ext key, mac %pM", mac_addr);
2257                ext_key = true;
2258        }
2259
2260        key = &ifp->vif->profile.key[key_idx];
2261        memset(key, 0, sizeof(*key));
2262        if ((ext_key) && (!is_multicast_ether_addr(mac_addr)))
2263                memcpy((char *)&key->ea, (void *)mac_addr, ETH_ALEN);
2264        key->len = params->key_len;
2265        key->index = key_idx;
2266        memcpy(key->data, params->key, key->len);
2267        if (!ext_key)
2268                key->flags = BRCMF_PRIMARY_KEY;
2269
2270        switch (params->cipher) {
2271        case WLAN_CIPHER_SUITE_WEP40:
2272                key->algo = CRYPTO_ALGO_WEP1;
2273                val = WEP_ENABLED;
2274                brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2275                break;
2276        case WLAN_CIPHER_SUITE_WEP104:
2277                key->algo = CRYPTO_ALGO_WEP128;
2278                val = WEP_ENABLED;
2279                brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2280                break;
2281        case WLAN_CIPHER_SUITE_TKIP:
2282                if (!brcmf_is_apmode(ifp->vif)) {
2283                        brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
2284                        memcpy(keybuf, &key->data[24], sizeof(keybuf));
2285                        memcpy(&key->data[24], &key->data[16], sizeof(keybuf));
2286                        memcpy(&key->data[16], keybuf, sizeof(keybuf));
2287                }
2288                key->algo = CRYPTO_ALGO_TKIP;
2289                val = TKIP_ENABLED;
2290                brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2291                break;
2292        case WLAN_CIPHER_SUITE_AES_CMAC:
2293                key->algo = CRYPTO_ALGO_AES_CCM;
2294                val = AES_ENABLED;
2295                brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2296                break;
2297        case WLAN_CIPHER_SUITE_CCMP:
2298                key->algo = CRYPTO_ALGO_AES_CCM;
2299                val = AES_ENABLED;
2300                brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n");
2301                break;
2302        default:
2303                brcmf_err("Invalid cipher (0x%x)\n", params->cipher);
2304                err = -EINVAL;
2305                goto done;
2306        }
2307
2308        err = send_key_to_dongle(ifp, key);
2309        if (ext_key || err)
2310                goto done;
2311
2312        err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2313        if (err) {
2314                brcmf_err("get wsec error (%d)\n", err);
2315                goto done;
2316        }
2317        wsec |= val;
2318        err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
2319        if (err) {
2320                brcmf_err("set wsec error (%d)\n", err);
2321                goto done;
2322        }
2323
2324done:
2325        brcmf_dbg(TRACE, "Exit\n");
2326        return err;
2327}
2328
2329static s32
2330brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_idx,
2331                       bool pairwise, const u8 *mac_addr, void *cookie,
2332                       void (*callback)(void *cookie,
2333                                        struct key_params *params))
2334{
2335        struct key_params params;
2336        struct brcmf_if *ifp = netdev_priv(ndev);
2337        struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
2338        struct brcmf_cfg80211_security *sec;
2339        s32 wsec;
2340        s32 err = 0;
2341
2342        brcmf_dbg(TRACE, "Enter\n");
2343        brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2344        if (!check_vif_up(ifp->vif))
2345                return -EIO;
2346
2347        memset(&params, 0, sizeof(params));
2348
2349        err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2350        if (err) {
2351                brcmf_err("WLC_GET_WSEC error (%d)\n", err);
2352                /* Ignore this error, may happen during DISASSOC */
2353                err = -EAGAIN;
2354                goto done;
2355        }
2356        if (wsec & WEP_ENABLED) {
2357                sec = &profile->sec;
2358                if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
2359                        params.cipher = WLAN_CIPHER_SUITE_WEP40;
2360                        brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2361                } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
2362                        params.cipher = WLAN_CIPHER_SUITE_WEP104;
2363                        brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2364                }
2365        } else if (wsec & TKIP_ENABLED) {
2366                params.cipher = WLAN_CIPHER_SUITE_TKIP;
2367                brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2368        } else if (wsec & AES_ENABLED) {
2369                params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
2370                brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2371        } else  {
2372                brcmf_err("Invalid algo (0x%x)\n", wsec);
2373                err = -EINVAL;
2374                goto done;
2375        }
2376        callback(cookie, &params);
2377
2378done:
2379        brcmf_dbg(TRACE, "Exit\n");
2380        return err;
2381}
2382
2383static s32
2384brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
2385                                       struct net_device *ndev, u8 key_idx)
2386{
2387        struct brcmf_if *ifp = netdev_priv(ndev);
2388
2389        brcmf_dbg(TRACE, "Enter key_idx %d\n", key_idx);
2390
2391        if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP))
2392                return 0;
2393
2394        brcmf_dbg(INFO, "Not supported\n");
2395
2396        return -EOPNOTSUPP;
2397}
2398
2399static void
2400brcmf_cfg80211_reconfigure_wep(struct brcmf_if *ifp)
2401{
2402        s32 err;
2403        u8 key_idx;
2404        struct brcmf_wsec_key *key;
2405        s32 wsec;
2406
2407        for (key_idx = 0; key_idx < BRCMF_MAX_DEFAULT_KEYS; key_idx++) {
2408                key = &ifp->vif->profile.key[key_idx];
2409                if ((key->algo == CRYPTO_ALGO_WEP1) ||
2410                    (key->algo == CRYPTO_ALGO_WEP128))
2411                        break;
2412        }
2413        if (key_idx == BRCMF_MAX_DEFAULT_KEYS)
2414                return;
2415
2416        err = send_key_to_dongle(ifp, key);
2417        if (err) {
2418                brcmf_err("Setting WEP key failed (%d)\n", err);
2419                return;
2420        }
2421        err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2422        if (err) {
2423                brcmf_err("get wsec error (%d)\n", err);
2424                return;
2425        }
2426        wsec |= WEP_ENABLED;
2427        err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
2428        if (err)
2429                brcmf_err("set wsec error (%d)\n", err);
2430}
2431
2432static void brcmf_convert_sta_flags(u32 fw_sta_flags, struct station_info *si)
2433{
2434        struct nl80211_sta_flag_update *sfu;
2435
2436        brcmf_dbg(TRACE, "flags %08x\n", fw_sta_flags);
2437        si->filled |= BIT(NL80211_STA_INFO_STA_FLAGS);
2438        sfu = &si->sta_flags;
2439        sfu->mask = BIT(NL80211_STA_FLAG_WME) |
2440                    BIT(NL80211_STA_FLAG_AUTHENTICATED) |
2441                    BIT(NL80211_STA_FLAG_ASSOCIATED) |
2442                    BIT(NL80211_STA_FLAG_AUTHORIZED);
2443        if (fw_sta_flags & BRCMF_STA_WME)
2444                sfu->set |= BIT(NL80211_STA_FLAG_WME);
2445        if (fw_sta_flags & BRCMF_STA_AUTHE)
2446                sfu->set |= BIT(NL80211_STA_FLAG_AUTHENTICATED);
2447        if (fw_sta_flags & BRCMF_STA_ASSOC)
2448                sfu->set |= BIT(NL80211_STA_FLAG_ASSOCIATED);
2449        if (fw_sta_flags & BRCMF_STA_AUTHO)
2450                sfu->set |= BIT(NL80211_STA_FLAG_AUTHORIZED);
2451}
2452
2453static void brcmf_fill_bss_param(struct brcmf_if *ifp, struct station_info *si)
2454{
2455        struct {
2456                __le32 len;
2457                struct brcmf_bss_info_le bss_le;
2458        } *buf;
2459        u16 capability;
2460        int err;
2461
2462        buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2463        if (!buf)
2464                return;
2465
2466        buf->len = cpu_to_le32(WL_BSS_INFO_MAX);
2467        err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO, buf,
2468                                     WL_BSS_INFO_MAX);
2469        if (err) {
2470                brcmf_err("Failed to get bss info (%d)\n", err);
2471                goto out_kfree;
2472        }
2473        si->filled |= BIT(NL80211_STA_INFO_BSS_PARAM);
2474        si->bss_param.beacon_interval = le16_to_cpu(buf->bss_le.beacon_period);
2475        si->bss_param.dtim_period = buf->bss_le.dtim_period;
2476        capability = le16_to_cpu(buf->bss_le.capability);
2477        if (capability & IEEE80211_HT_STBC_PARAM_DUAL_CTS_PROT)
2478                si->bss_param.flags |= BSS_PARAM_FLAGS_CTS_PROT;
2479        if (capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
2480                si->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_PREAMBLE;
2481        if (capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)
2482                si->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME;
2483
2484out_kfree:
2485        kfree(buf);
2486}
2487
2488static s32
2489brcmf_cfg80211_get_station_ibss(struct brcmf_if *ifp,
2490                                struct station_info *sinfo)
2491{
2492        struct brcmf_scb_val_le scbval;
2493        struct brcmf_pktcnt_le pktcnt;
2494        s32 err;
2495        u32 rate;
2496        u32 rssi;
2497
2498        /* Get the current tx rate */
2499        err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_RATE, &rate);
2500        if (err < 0) {
2501                brcmf_err("BRCMF_C_GET_RATE error (%d)\n", err);
2502                return err;
2503        }
2504        sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
2505        sinfo->txrate.legacy = rate * 5;
2506
2507        memset(&scbval, 0, sizeof(scbval));
2508        err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_RSSI, &scbval,
2509                                     sizeof(scbval));
2510        if (err) {
2511                brcmf_err("BRCMF_C_GET_RSSI error (%d)\n", err);
2512                return err;
2513        }
2514        rssi = le32_to_cpu(scbval.val);
2515        sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
2516        sinfo->signal = rssi;
2517
2518        err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_GET_PKTCNTS, &pktcnt,
2519                                     sizeof(pktcnt));
2520        if (err) {
2521                brcmf_err("BRCMF_C_GET_GET_PKTCNTS error (%d)\n", err);
2522                return err;
2523        }
2524        sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS) |
2525                         BIT(NL80211_STA_INFO_RX_DROP_MISC) |
2526                         BIT(NL80211_STA_INFO_TX_PACKETS) |
2527                         BIT(NL80211_STA_INFO_TX_FAILED);
2528        sinfo->rx_packets = le32_to_cpu(pktcnt.rx_good_pkt);
2529        sinfo->rx_dropped_misc = le32_to_cpu(pktcnt.rx_bad_pkt);
2530        sinfo->tx_packets = le32_to_cpu(pktcnt.tx_good_pkt);
2531        sinfo->tx_failed  = le32_to_cpu(pktcnt.tx_bad_pkt);
2532
2533        return 0;
2534}
2535
2536static s32
2537brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
2538                           const u8 *mac, struct station_info *sinfo)
2539{
2540        struct brcmf_if *ifp = netdev_priv(ndev);
2541        struct brcmf_scb_val_le scb_val;
2542        s32 err = 0;
2543        struct brcmf_sta_info_le sta_info_le;
2544        u32 sta_flags;
2545        u32 is_tdls_peer;
2546        s32 total_rssi;
2547        s32 count_rssi;
2548        int rssi;
2549        u32 i;
2550
2551        brcmf_dbg(TRACE, "Enter, MAC %pM\n", mac);
2552        if (!check_vif_up(ifp->vif))
2553                return -EIO;
2554
2555        if (brcmf_is_ibssmode(ifp->vif))
2556                return brcmf_cfg80211_get_station_ibss(ifp, sinfo);
2557
2558        memset(&sta_info_le, 0, sizeof(sta_info_le));
2559        memcpy(&sta_info_le, mac, ETH_ALEN);
2560        err = brcmf_fil_iovar_data_get(ifp, "tdls_sta_info",
2561                                       &sta_info_le,
2562                                       sizeof(sta_info_le));
2563        is_tdls_peer = !err;
2564        if (err) {
2565                err = brcmf_fil_iovar_data_get(ifp, "sta_info",
2566                                               &sta_info_le,
2567                                               sizeof(sta_info_le));
2568                if (err < 0) {
2569                        brcmf_err("GET STA INFO failed, %d\n", err);
2570                        goto done;
2571                }
2572        }
2573        brcmf_dbg(TRACE, "version %d\n", le16_to_cpu(sta_info_le.ver));
2574        sinfo->filled = BIT(NL80211_STA_INFO_INACTIVE_TIME);
2575        sinfo->inactive_time = le32_to_cpu(sta_info_le.idle) * 1000;
2576        sta_flags = le32_to_cpu(sta_info_le.flags);
2577        brcmf_convert_sta_flags(sta_flags, sinfo);
2578        sinfo->sta_flags.mask |= BIT(NL80211_STA_FLAG_TDLS_PEER);
2579        if (is_tdls_peer)
2580                sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_TDLS_PEER);
2581        else
2582                sinfo->sta_flags.set &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
2583        if (sta_flags & BRCMF_STA_ASSOC) {
2584                sinfo->filled |= BIT(NL80211_STA_INFO_CONNECTED_TIME);
2585                sinfo->connected_time = le32_to_cpu(sta_info_le.in);
2586                brcmf_fill_bss_param(ifp, sinfo);
2587        }
2588        if (sta_flags & BRCMF_STA_SCBSTATS) {
2589                sinfo->filled |= BIT(NL80211_STA_INFO_TX_FAILED);
2590                sinfo->tx_failed = le32_to_cpu(sta_info_le.tx_failures);
2591                sinfo->filled |= BIT(NL80211_STA_INFO_TX_PACKETS);
2592                sinfo->tx_packets = le32_to_cpu(sta_info_le.tx_pkts);
2593                sinfo->tx_packets += le32_to_cpu(sta_info_le.tx_mcast_pkts);
2594                sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS);
2595                sinfo->rx_packets = le32_to_cpu(sta_info_le.rx_ucast_pkts);
2596                sinfo->rx_packets += le32_to_cpu(sta_info_le.rx_mcast_pkts);
2597                if (sinfo->tx_packets) {
2598                        sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
2599                        sinfo->txrate.legacy =
2600                                le32_to_cpu(sta_info_le.tx_rate) / 100;
2601                }
2602                if (sinfo->rx_packets) {
2603                        sinfo->filled |= BIT(NL80211_STA_INFO_RX_BITRATE);
2604                        sinfo->rxrate.legacy =
2605                                le32_to_cpu(sta_info_le.rx_rate) / 100;
2606                }
2607                if (le16_to_cpu(sta_info_le.ver) >= 4) {
2608                        sinfo->filled |= BIT(NL80211_STA_INFO_TX_BYTES);
2609                        sinfo->tx_bytes = le64_to_cpu(sta_info_le.tx_tot_bytes);
2610                        sinfo->filled |= BIT(NL80211_STA_INFO_RX_BYTES);
2611                        sinfo->rx_bytes = le64_to_cpu(sta_info_le.rx_tot_bytes);
2612                }
2613                total_rssi = 0;
2614                count_rssi = 0;
2615                for (i = 0; i < BRCMF_ANT_MAX; i++) {
2616                        if (sta_info_le.rssi[i]) {
2617                                sinfo->chain_signal_avg[count_rssi] =
2618                                        sta_info_le.rssi[i];
2619                                sinfo->chain_signal[count_rssi] =
2620                                        sta_info_le.rssi[i];
2621                                total_rssi += sta_info_le.rssi[i];
2622                                count_rssi++;
2623                        }
2624                }
2625                if (count_rssi) {
2626                        sinfo->filled |= BIT(NL80211_STA_INFO_CHAIN_SIGNAL);
2627                        sinfo->chains = count_rssi;
2628
2629                        sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
2630                        total_rssi /= count_rssi;
2631                        sinfo->signal = total_rssi;
2632                } else if (test_bit(BRCMF_VIF_STATUS_CONNECTED,
2633                        &ifp->vif->sme_state)) {
2634                        memset(&scb_val, 0, sizeof(scb_val));
2635                        err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_RSSI,
2636                                                     &scb_val, sizeof(scb_val));
2637                        if (err) {
2638                                brcmf_err("Could not get rssi (%d)\n", err);
2639                                goto done;
2640                        } else {
2641                                rssi = le32_to_cpu(scb_val.val);
2642                                sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
2643                                sinfo->signal = rssi;
2644                                brcmf_dbg(CONN, "RSSI %d dBm\n", rssi);
2645                        }
2646                }
2647        }
2648done:
2649        brcmf_dbg(TRACE, "Exit\n");
2650        return err;
2651}
2652
2653static int
2654brcmf_cfg80211_dump_station(struct wiphy *wiphy, struct net_device *ndev,
2655                            int idx, u8 *mac, struct station_info *sinfo)
2656{
2657        struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2658        struct brcmf_if *ifp = netdev_priv(ndev);
2659        s32 err;
2660
2661        brcmf_dbg(TRACE, "Enter, idx %d\n", idx);
2662
2663        if (idx == 0) {
2664                cfg->assoclist.count = cpu_to_le32(BRCMF_MAX_ASSOCLIST);
2665                err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_ASSOCLIST,
2666                                             &cfg->assoclist,
2667                                             sizeof(cfg->assoclist));
2668                if (err) {
2669                        brcmf_err("BRCMF_C_GET_ASSOCLIST unsupported, err=%d\n",
2670                                  err);
2671                        cfg->assoclist.count = 0;
2672                        return -EOPNOTSUPP;
2673                }
2674        }
2675        if (idx < le32_to_cpu(cfg->assoclist.count)) {
2676                memcpy(mac, cfg->assoclist.mac[idx], ETH_ALEN);
2677                return brcmf_cfg80211_get_station(wiphy, ndev, mac, sinfo);
2678        }
2679        return -ENOENT;
2680}
2681
2682static s32
2683brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
2684                           bool enabled, s32 timeout)
2685{
2686        s32 pm;
2687        s32 err = 0;
2688        struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2689        struct brcmf_if *ifp = netdev_priv(ndev);
2690
2691        brcmf_dbg(TRACE, "Enter\n");
2692
2693        /*
2694         * Powersave enable/disable request is coming from the
2695         * cfg80211 even before the interface is up. In that
2696         * scenario, driver will be storing the power save
2697         * preference in cfg struct to apply this to
2698         * FW later while initializing the dongle
2699         */
2700        cfg->pwr_save = enabled;
2701        if (!check_vif_up(ifp->vif)) {
2702
2703                brcmf_dbg(INFO, "Device is not ready, storing the value in cfg_info struct\n");
2704                goto done;
2705        }
2706
2707        pm = enabled ? PM_FAST : PM_OFF;
2708        /* Do not enable the power save after assoc if it is a p2p interface */
2709        if (ifp->vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) {
2710                brcmf_dbg(INFO, "Do not enable power save for P2P clients\n");
2711                pm = PM_OFF;
2712        }
2713        brcmf_dbg(INFO, "power save %s\n", (pm ? "enabled" : "disabled"));
2714
2715        err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, pm);
2716        if (err) {
2717                if (err == -ENODEV)
2718                        brcmf_err("net_device is not ready yet\n");
2719                else
2720                        brcmf_err("error (%d)\n", err);
2721        }
2722done:
2723        brcmf_dbg(TRACE, "Exit\n");
2724        return err;
2725}
2726
2727static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg,
2728                                   struct brcmf_bss_info_le *bi)
2729{
2730        struct wiphy *wiphy = cfg_to_wiphy(cfg);
2731        struct ieee80211_channel *notify_channel;
2732        struct cfg80211_bss *bss;
2733        struct ieee80211_supported_band *band;
2734        struct brcmu_chan ch;
2735        u16 channel;
2736        u32 freq;
2737        u16 notify_capability;
2738        u16 notify_interval;
2739        u8 *notify_ie;
2740        size_t notify_ielen;
2741        s32 notify_signal;
2742
2743        if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) {
2744                brcmf_err("Bss info is larger than buffer. Discarding\n");
2745                return 0;
2746        }
2747
2748        if (!bi->ctl_ch) {
2749                ch.chspec = le16_to_cpu(bi->chanspec);
2750                cfg->d11inf.decchspec(&ch);
2751                bi->ctl_ch = ch.control_ch_num;
2752        }
2753        channel = bi->ctl_ch;
2754
2755        if (channel <= CH_MAX_2G_CHANNEL)
2756                band = wiphy->bands[NL80211_BAND_2GHZ];
2757        else
2758                band = wiphy->bands[NL80211_BAND_5GHZ];
2759
2760        freq = ieee80211_channel_to_frequency(channel, band->band);
2761        notify_channel = ieee80211_get_channel(wiphy, freq);
2762
2763        notify_capability = le16_to_cpu(bi->capability);
2764        notify_interval = le16_to_cpu(bi->beacon_period);
2765        notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2766        notify_ielen = le32_to_cpu(bi->ie_length);
2767        notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2768
2769        brcmf_dbg(CONN, "bssid: %pM\n", bi->BSSID);
2770        brcmf_dbg(CONN, "Channel: %d(%d)\n", channel, freq);
2771        brcmf_dbg(CONN, "Capability: %X\n", notify_capability);
2772        brcmf_dbg(CONN, "Beacon interval: %d\n", notify_interval);
2773        brcmf_dbg(CONN, "Signal: %d\n", notify_signal);
2774
2775        bss = cfg80211_inform_bss(wiphy, notify_channel,
2776                                  CFG80211_BSS_FTYPE_UNKNOWN,
2777                                  (const u8 *)bi->BSSID,
2778                                  0, notify_capability,
2779                                  notify_interval, notify_ie,
2780                                  notify_ielen, notify_signal,
2781                                  GFP_KERNEL);
2782
2783        if (!bss)
2784                return -ENOMEM;
2785
2786        cfg80211_put_bss(wiphy, bss);
2787
2788        return 0;
2789}
2790
2791static struct brcmf_bss_info_le *
2792next_bss_le(struct brcmf_scan_results *list, struct brcmf_bss_info_le *bss)
2793{
2794        if (bss == NULL)
2795                return list->bss_info_le;
2796        return (struct brcmf_bss_info_le *)((unsigned long)bss +
2797                                            le32_to_cpu(bss->length));
2798}
2799
2800static s32 brcmf_inform_bss(struct brcmf_cfg80211_info *cfg)
2801{
2802        struct brcmf_scan_results *bss_list;
2803        struct brcmf_bss_info_le *bi = NULL;    /* must be initialized */
2804        s32 err = 0;
2805        int i;
2806
2807        bss_list = (struct brcmf_scan_results *)cfg->escan_info.escan_buf;
2808        if (bss_list->count != 0 &&
2809            bss_list->version != BRCMF_BSS_INFO_VERSION) {
2810                brcmf_err("Version %d != WL_BSS_INFO_VERSION\n",
2811                          bss_list->version);
2812                return -EOPNOTSUPP;
2813        }
2814        brcmf_dbg(SCAN, "scanned AP count (%d)\n", bss_list->count);
2815        for (i = 0; i < bss_list->count; i++) {
2816                bi = next_bss_le(bss_list, bi);
2817                err = brcmf_inform_single_bss(cfg, bi);
2818                if (err)
2819                        break;
2820        }
2821        return err;
2822}
2823
2824static s32 brcmf_inform_ibss(struct brcmf_cfg80211_info *cfg,
2825                             struct net_device *ndev, const u8 *bssid)
2826{
2827        struct wiphy *wiphy = cfg_to_wiphy(cfg);
2828        struct ieee80211_channel *notify_channel;
2829        struct brcmf_bss_info_le *bi = NULL;
2830        struct ieee80211_supported_band *band;
2831        struct cfg80211_bss *bss;
2832        struct brcmu_chan ch;
2833        u8 *buf = NULL;
2834        s32 err = 0;
2835        u32 freq;
2836        u16 notify_capability;
2837        u16 notify_interval;
2838        u8 *notify_ie;
2839        size_t notify_ielen;
2840        s32 notify_signal;
2841
2842        brcmf_dbg(TRACE, "Enter\n");
2843
2844        buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2845        if (buf == NULL) {
2846                err = -ENOMEM;
2847                goto CleanUp;
2848        }
2849
2850        *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
2851
2852        err = brcmf_fil_cmd_data_get(netdev_priv(ndev), BRCMF_C_GET_BSS_INFO,
2853                                     buf, WL_BSS_INFO_MAX);
2854        if (err) {
2855                brcmf_err("WLC_GET_BSS_INFO failed: %d\n", err);
2856                goto CleanUp;
2857        }
2858
2859        bi = (struct brcmf_bss_info_le *)(buf + 4);
2860
2861        ch.chspec = le16_to_cpu(bi->chanspec);
2862        cfg->d11inf.decchspec(&ch);
2863
2864        if (ch.band == BRCMU_CHAN_BAND_2G)
2865                band = wiphy->bands[NL80211_BAND_2GHZ];
2866        else
2867                band = wiphy->bands[NL80211_BAND_5GHZ];
2868
2869        freq = ieee80211_channel_to_frequency(ch.control_ch_num, band->band);
2870        cfg->channel = freq;
2871        notify_channel = ieee80211_get_channel(wiphy, freq);
2872
2873        notify_capability = le16_to_cpu(bi->capability);
2874        notify_interval = le16_to_cpu(bi->beacon_period);
2875        notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2876        notify_ielen = le32_to_cpu(bi->ie_length);
2877        notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2878
2879        brcmf_dbg(CONN, "channel: %d(%d)\n", ch.control_ch_num, freq);
2880        brcmf_dbg(CONN, "capability: %X\n", notify_capability);
2881        brcmf_dbg(CONN, "beacon interval: %d\n", notify_interval);
2882        brcmf_dbg(CONN, "signal: %d\n", notify_signal);
2883
2884        bss = cfg80211_inform_bss(wiphy, notify_channel,
2885                                  CFG80211_BSS_FTYPE_UNKNOWN, bssid, 0,
2886                                  notify_capability, notify_interval,
2887                                  notify_ie, notify_ielen, notify_signal,
2888                                  GFP_KERNEL);
2889
2890        if (!bss) {
2891                err = -ENOMEM;
2892                goto CleanUp;
2893        }
2894
2895        cfg80211_put_bss(wiphy, bss);
2896
2897CleanUp:
2898
2899        kfree(buf);
2900
2901        brcmf_dbg(TRACE, "Exit\n");
2902
2903        return err;
2904}
2905
2906static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg,
2907                                 struct brcmf_if *ifp)
2908{
2909        struct brcmf_bss_info_le *bi;
2910        const struct brcmf_tlv *tim;
2911        u16 beacon_interval;
2912        u8 dtim_period;
2913        size_t ie_len;
2914        u8 *ie;
2915        s32 err = 0;
2916
2917        brcmf_dbg(TRACE, "Enter\n");
2918        if (brcmf_is_ibssmode(ifp->vif))
2919                return err;
2920
2921        *(__le32 *)cfg->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
2922        err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
2923                                     cfg->extra_buf, WL_EXTRA_BUF_MAX);
2924        if (err) {
2925                brcmf_err("Could not get bss info %d\n", err);
2926                goto update_bss_info_out;
2927        }
2928
2929        bi = (struct brcmf_bss_info_le *)(cfg->extra_buf + 4);
2930        err = brcmf_inform_single_bss(cfg, bi);
2931        if (err)
2932                goto update_bss_info_out;
2933
2934        ie = ((u8 *)bi) + le16_to_cpu(bi->ie_offset);
2935        ie_len = le32_to_cpu(bi->ie_length);
2936        beacon_interval = le16_to_cpu(bi->beacon_period);
2937
2938        tim = brcmf_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
2939        if (tim)
2940                dtim_period = tim->data[1];
2941        else {
2942                /*
2943                * active scan was done so we could not get dtim
2944                * information out of probe response.
2945                * so we speficially query dtim information to dongle.
2946                */
2947                u32 var;
2948                err = brcmf_fil_iovar_int_get(ifp, "dtim_assoc", &var);
2949                if (err) {
2950                        brcmf_err("wl dtim_assoc failed (%d)\n", err);
2951                        goto update_bss_info_out;
2952                }
2953                dtim_period = (u8)var;
2954        }
2955
2956update_bss_info_out:
2957        brcmf_dbg(TRACE, "Exit");
2958        return err;
2959}
2960
2961void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg)
2962{
2963        struct escan_info *escan = &cfg->escan_info;
2964
2965        set_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
2966        if (cfg->int_escan_map || cfg->scan_request) {
2967                escan->escan_state = WL_ESCAN_STATE_IDLE;
2968                brcmf_notify_escan_complete(cfg, escan->ifp, true, true);
2969        }
2970        clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
2971        clear_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
2972}
2973
2974static void brcmf_cfg80211_escan_timeout_worker(struct work_struct *work)
2975{
2976        struct brcmf_cfg80211_info *cfg =
2977                        container_of(work, struct brcmf_cfg80211_info,
2978                                     escan_timeout_work);
2979
2980        brcmf_inform_bss(cfg);
2981        brcmf_notify_escan_complete(cfg, cfg->escan_info.ifp, true, true);
2982}
2983
2984static void brcmf_escan_timeout(struct timer_list *t)
2985{
2986        struct brcmf_cfg80211_info *cfg =
2987                        from_timer(cfg, t, escan_timeout);
2988
2989        if (cfg->int_escan_map || cfg->scan_request) {
2990                brcmf_err("timer expired\n");
2991                schedule_work(&cfg->escan_timeout_work);
2992        }
2993}
2994
2995static s32
2996brcmf_compare_update_same_bss(struct brcmf_cfg80211_info *cfg,
2997                              struct brcmf_bss_info_le *bss,
2998                              struct brcmf_bss_info_le *bss_info_le)
2999{
3000        struct brcmu_chan ch_bss, ch_bss_info_le;
3001
3002        ch_bss.chspec = le16_to_cpu(bss->chanspec);
3003        cfg->d11inf.decchspec(&ch_bss);
3004        ch_bss_info_le.chspec = le16_to_cpu(bss_info_le->chanspec);
3005        cfg->d11inf.decchspec(&ch_bss_info_le);
3006
3007        if (!memcmp(&bss_info_le->BSSID, &bss->BSSID, ETH_ALEN) &&
3008                ch_bss.band == ch_bss_info_le.band &&
3009                bss_info_le->SSID_len == bss->SSID_len &&
3010                !memcmp(bss_info_le->SSID, bss->SSID, bss_info_le->SSID_len)) {
3011                if ((bss->flags & BRCMF_BSS_RSSI_ON_CHANNEL) ==
3012                        (bss_info_le->flags & BRCMF_BSS_RSSI_ON_CHANNEL)) {
3013                        s16 bss_rssi = le16_to_cpu(bss->RSSI);
3014                        s16 bss_info_rssi = le16_to_cpu(bss_info_le->RSSI);
3015
3016                        /* preserve max RSSI if the measurements are
3017                        * both on-channel or both off-channel
3018                        */
3019                        if (bss_info_rssi > bss_rssi)
3020                                bss->RSSI = bss_info_le->RSSI;
3021                } else if ((bss->flags & BRCMF_BSS_RSSI_ON_CHANNEL) &&
3022                        (bss_info_le->flags & BRCMF_BSS_RSSI_ON_CHANNEL) == 0) {
3023                        /* preserve the on-channel rssi measurement
3024                        * if the new measurement is off channel
3025                        */
3026                        bss->RSSI = bss_info_le->RSSI;
3027                        bss->flags |= BRCMF_BSS_RSSI_ON_CHANNEL;
3028                }
3029                return 1;
3030        }
3031        return 0;
3032}
3033
3034static s32
3035brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
3036                             const struct brcmf_event_msg *e, void *data)
3037{
3038        struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
3039        s32 status;
3040        struct brcmf_escan_result_le *escan_result_le;
3041        u32 escan_buflen;
3042        struct brcmf_bss_info_le *bss_info_le;
3043        struct brcmf_bss_info_le *bss = NULL;
3044        u32 bi_length;
3045        struct brcmf_scan_results *list;
3046        u32 i;
3047        bool aborted;
3048
3049        status = e->status;
3050
3051        if (status == BRCMF_E_STATUS_ABORT)
3052                goto exit;
3053
3054        if (!test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
3055                brcmf_err("scan not ready, bsscfgidx=%d\n", ifp->bsscfgidx);
3056                return -EPERM;
3057        }
3058
3059        if (status == BRCMF_E_STATUS_PARTIAL) {
3060                brcmf_dbg(SCAN, "ESCAN Partial result\n");
3061                if (e->datalen < sizeof(*escan_result_le)) {
3062                        brcmf_err("invalid event data length\n");
3063                        goto exit;
3064                }
3065                escan_result_le = (struct brcmf_escan_result_le *) data;
3066                if (!escan_result_le) {
3067                        brcmf_err("Invalid escan result (NULL pointer)\n");
3068                        goto exit;
3069                }
3070                escan_buflen = le32_to_cpu(escan_result_le->buflen);
3071                if (escan_buflen > BRCMF_ESCAN_BUF_SIZE ||
3072                    escan_buflen > e->datalen ||
3073                    escan_buflen < sizeof(*escan_result_le)) {
3074                        brcmf_err("Invalid escan buffer length: %d\n",
3075                                  escan_buflen);
3076                        goto exit;
3077                }
3078                if (le16_to_cpu(escan_result_le->bss_count) != 1) {
3079                        brcmf_err("Invalid bss_count %d: ignoring\n",
3080                                  escan_result_le->bss_count);
3081                        goto exit;
3082                }
3083                bss_info_le = &escan_result_le->bss_info_le;
3084
3085                if (brcmf_p2p_scan_finding_common_channel(cfg, bss_info_le))
3086                        goto exit;
3087
3088                if (!cfg->int_escan_map && !cfg->scan_request) {
3089                        brcmf_dbg(SCAN, "result without cfg80211 request\n");
3090                        goto exit;
3091                }
3092
3093                bi_length = le32_to_cpu(bss_info_le->length);
3094                if (bi_length != escan_buflen - WL_ESCAN_RESULTS_FIXED_SIZE) {
3095                        brcmf_err("Ignoring invalid bss_info length: %d\n",
3096                                  bi_length);
3097                        goto exit;
3098                }
3099
3100                if (!(cfg_to_wiphy(cfg)->interface_modes &
3101                                        BIT(NL80211_IFTYPE_ADHOC))) {
3102                        if (le16_to_cpu(bss_info_le->capability) &
3103                                                WLAN_CAPABILITY_IBSS) {
3104                                brcmf_err("Ignoring IBSS result\n");
3105                                goto exit;
3106                        }
3107                }
3108
3109                list = (struct brcmf_scan_results *)
3110                                cfg->escan_info.escan_buf;
3111                if (bi_length > BRCMF_ESCAN_BUF_SIZE - list->buflen) {
3112                        brcmf_err("Buffer is too small: ignoring\n");
3113                        goto exit;
3114                }
3115
3116                for (i = 0; i < list->count; i++) {
3117                        bss = bss ? (struct brcmf_bss_info_le *)
3118                                ((unsigned char *)bss +
3119                                le32_to_cpu(bss->length)) : list->bss_info_le;
3120                        if (brcmf_compare_update_same_bss(cfg, bss,
3121                                                          bss_info_le))
3122                                goto exit;
3123                }
3124                memcpy(&cfg->escan_info.escan_buf[list->buflen], bss_info_le,
3125                       bi_length);
3126                list->version = le32_to_cpu(bss_info_le->version);
3127                list->buflen += bi_length;
3128                list->count++;
3129        } else {
3130                cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
3131                if (brcmf_p2p_scan_finding_common_channel(cfg, NULL))
3132                        goto exit;
3133                if (cfg->int_escan_map || cfg->scan_request) {
3134                        brcmf_inform_bss(cfg);
3135                        aborted = status != BRCMF_E_STATUS_SUCCESS;
3136                        brcmf_notify_escan_complete(cfg, ifp, aborted, false);
3137                } else
3138                        brcmf_dbg(SCAN, "Ignored scan complete result 0x%x\n",
3139                                  status);
3140        }
3141exit:
3142        return 0;
3143}
3144
3145static void brcmf_init_escan(struct brcmf_cfg80211_info *cfg)
3146{
3147        brcmf_fweh_register(cfg->pub, BRCMF_E_ESCAN_RESULT,
3148                            brcmf_cfg80211_escan_handler);
3149        cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
3150        /* Init scan_timeout timer */
3151        timer_setup(&cfg->escan_timeout, brcmf_escan_timeout, 0);
3152        INIT_WORK(&cfg->escan_timeout_work,
3153                  brcmf_cfg80211_escan_timeout_worker);
3154}
3155
3156static struct cfg80211_scan_request *
3157brcmf_alloc_internal_escan_request(struct wiphy *wiphy, u32 n_netinfo) {
3158        struct cfg80211_scan_request *req;
3159        size_t req_size;
3160
3161        req_size = sizeof(*req) +
3162                   n_netinfo * sizeof(req->channels[0]) +
3163                   n_netinfo * sizeof(*req->ssids);
3164
3165        req = kzalloc(req_size, GFP_KERNEL);
3166        if (req) {
3167                req->wiphy = wiphy;
3168                req->ssids = (void *)(&req->channels[0]) +
3169                             n_netinfo * sizeof(req->channels[0]);
3170        }
3171        return req;
3172}
3173
3174static int brcmf_internal_escan_add_info(struct cfg80211_scan_request *req,
3175                                         u8 *ssid, u8 ssid_len, u8 channel)
3176{
3177        struct ieee80211_channel *chan;
3178        enum nl80211_band band;
3179        int freq, i;
3180
3181        if (channel <= CH_MAX_2G_CHANNEL)
3182                band = NL80211_BAND_2GHZ;
3183        else
3184                band = NL80211_BAND_5GHZ;
3185
3186        freq = ieee80211_channel_to_frequency(channel, band);
3187        if (!freq)
3188                return -EINVAL;
3189
3190        chan = ieee80211_get_channel(req->wiphy, freq);
3191        if (!chan)
3192                return -EINVAL;
3193
3194        for (i = 0; i < req->n_channels; i++) {
3195                if (req->channels[i] == chan)
3196                        break;
3197        }
3198        if (i == req->n_channels)
3199                req->channels[req->n_channels++] = chan;
3200
3201        for (i = 0; i < req->n_ssids; i++) {
3202                if (req->ssids[i].ssid_len == ssid_len &&
3203                    !memcmp(req->ssids[i].ssid, ssid, ssid_len))
3204                        break;
3205        }
3206        if (i == req->n_ssids) {
3207                memcpy(req->ssids[req->n_ssids].ssid, ssid, ssid_len);
3208                req->ssids[req->n_ssids++].ssid_len = ssid_len;
3209        }
3210        return 0;
3211}
3212
3213static int brcmf_start_internal_escan(struct brcmf_if *ifp, u32 fwmap,
3214                                      struct cfg80211_scan_request *request)
3215{
3216        struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
3217        int err;
3218
3219        if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
3220                if (cfg->int_escan_map)
3221                        brcmf_dbg(SCAN, "aborting internal scan: map=%u\n",
3222                                  cfg->int_escan_map);
3223                /* Abort any on-going scan */
3224                brcmf_abort_scanning(cfg);
3225        }
3226
3227        brcmf_dbg(SCAN, "start internal scan: map=%u\n", fwmap);
3228        set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
3229        cfg->escan_info.run = brcmf_run_escan;
3230        err = brcmf_do_escan(ifp, request);
3231        if (err) {
3232                clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
3233                return err;
3234        }
3235        cfg->int_escan_map = fwmap;
3236        return 0;
3237}
3238
3239static struct brcmf_pno_net_info_le *
3240brcmf_get_netinfo_array(struct brcmf_pno_scanresults_le *pfn_v1)
3241{
3242        struct brcmf_pno_scanresults_v2_le *pfn_v2;
3243        struct brcmf_pno_net_info_le *netinfo;
3244
3245        switch (pfn_v1->version) {
3246        default:
3247                WARN_ON(1);
3248                /* fall-thru */
3249        case cpu_to_le32(1):
3250                netinfo = (struct brcmf_pno_net_info_le *)(pfn_v1 + 1);
3251                break;
3252        case cpu_to_le32(2):
3253                pfn_v2 = (struct brcmf_pno_scanresults_v2_le *)pfn_v1;
3254                netinfo = (struct brcmf_pno_net_info_le *)(pfn_v2 + 1);
3255                break;
3256        }
3257
3258        return netinfo;
3259}
3260
3261/* PFN result doesn't have all the info which are required by the supplicant
3262 * (For e.g IEs) Do a target Escan so that sched scan results are reported
3263 * via wl_inform_single_bss in the required format. Escan does require the
3264 * scan request in the form of cfg80211_scan_request. For timebeing, create
3265 * cfg80211_scan_request one out of the received PNO event.
3266 */
3267static s32
3268brcmf_notify_sched_scan_results(struct brcmf_if *ifp,
3269                                const struct brcmf_event_msg *e, void *data)
3270{
3271        struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
3272        struct brcmf_pno_net_info_le *netinfo, *netinfo_start;
3273        struct cfg80211_scan_request *request = NULL;
3274        struct wiphy *wiphy = cfg_to_wiphy(cfg);
3275        int i, err = 0;
3276        struct brcmf_pno_scanresults_le *pfn_result;
3277        u32 bucket_map;
3278        u32 result_count;
3279        u32 status;
3280        u32 datalen;
3281
3282        brcmf_dbg(SCAN, "Enter\n");
3283
3284        if (e->datalen < (sizeof(*pfn_result) + sizeof(*netinfo))) {
3285                brcmf_dbg(SCAN, "Event data to small. Ignore\n");
3286                return 0;
3287        }
3288
3289        if (e->event_code == BRCMF_E_PFN_NET_LOST) {
3290                brcmf_dbg(SCAN, "PFN NET LOST event. Do Nothing\n");
3291                return 0;
3292        }
3293
3294        pfn_result = (struct brcmf_pno_scanresults_le *)data;
3295        result_count = le32_to_cpu(pfn_result->count);
3296        status = le32_to_cpu(pfn_result->status);
3297
3298        /* PFN event is limited to fit 512 bytes so we may get
3299         * multiple NET_FOUND events. For now place a warning here.
3300         */
3301        WARN_ON(status != BRCMF_PNO_SCAN_COMPLETE);
3302        brcmf_dbg(SCAN, "PFN NET FOUND event. count: %d\n", result_count);
3303        if (!result_count) {
3304                brcmf_err("FALSE PNO Event. (pfn_count == 0)\n");
3305                goto out_err;
3306        }
3307
3308        netinfo_start = brcmf_get_netinfo_array(pfn_result);
3309        datalen = e->datalen - ((void *)netinfo_start - (void *)pfn_result);
3310        if (datalen < result_count * sizeof(*netinfo)) {
3311                brcmf_err("insufficient event data\n");
3312                goto out_err;
3313        }
3314
3315        request = brcmf_alloc_internal_escan_request(wiphy,
3316                                                     result_count);
3317        if (!request) {
3318                err = -ENOMEM;
3319                goto out_err;
3320        }
3321
3322        bucket_map = 0;
3323        for (i = 0; i < result_count; i++) {
3324                netinfo = &netinfo_start[i];
3325
3326                if (netinfo->SSID_len > IEEE80211_MAX_SSID_LEN)
3327                        netinfo->SSID_len = IEEE80211_MAX_SSID_LEN;
3328                brcmf_dbg(SCAN, "SSID:%.32s Channel:%d\n",
3329                          netinfo->SSID, netinfo->channel);
3330                bucket_map |= brcmf_pno_get_bucket_map(cfg->pno, netinfo);
3331                err = brcmf_internal_escan_add_info(request,
3332                                                    netinfo->SSID,
3333                                                    netinfo->SSID_len,
3334                                                    netinfo->channel);
3335                if (err)
3336                        goto out_err;
3337        }
3338
3339        if (!bucket_map)
3340                goto free_req;
3341
3342        err = brcmf_start_internal_escan(ifp, bucket_map, request);
3343        if (!err)
3344                goto free_req;
3345
3346out_err:
3347        cfg80211_sched_scan_stopped(wiphy, 0);
3348free_req:
3349        kfree(request);
3350        return err;
3351}
3352
3353static int
3354brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
3355                                struct net_device *ndev,
3356                                struct cfg80211_sched_scan_request *req)
3357{
3358        struct brcmf_if *ifp = netdev_priv(ndev);
3359        struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3360
3361        brcmf_dbg(SCAN, "Enter: n_match_sets=%d n_ssids=%d\n",
3362                  req->n_match_sets, req->n_ssids);
3363
3364        if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) {
3365                brcmf_err("Scanning suppressed: status=%lu\n",
3366                          cfg->scan_status);
3367                return -EAGAIN;
3368        }
3369
3370        if (req->n_match_sets <= 0) {
3371                brcmf_dbg(SCAN, "invalid number of matchsets specified: %d\n",
3372                          req->n_match_sets);
3373                return -EINVAL;
3374        }
3375
3376        return brcmf_pno_start_sched_scan(ifp, req);
3377}
3378
3379static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,
3380                                          struct net_device *ndev, u64 reqid)
3381{
3382        struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3383        struct brcmf_if *ifp = netdev_priv(ndev);
3384
3385        brcmf_dbg(SCAN, "enter\n");
3386        brcmf_pno_stop_sched_scan(ifp, reqid);
3387        if (cfg->int_escan_map)
3388                brcmf_notify_escan_complete(cfg, ifp, true, true);
3389        return 0;
3390}
3391
3392static __always_inline void brcmf_delay(u32 ms)
3393{
3394        if (ms < 1000 / HZ) {
3395                cond_resched();
3396                mdelay(ms);
3397        } else {
3398                msleep(ms);
3399        }
3400}
3401
3402static s32 brcmf_config_wowl_pattern(struct brcmf_if *ifp, u8 cmd[4],
3403                                     u8 *pattern, u32 patternsize, u8 *mask,
3404                                     u32 packet_offset)
3405{
3406        struct brcmf_fil_wowl_pattern_le *filter;
3407        u32 masksize;
3408        u32 patternoffset;
3409        u8 *buf;
3410        u32 bufsize;
3411        s32 ret;
3412
3413        masksize = (patternsize + 7) / 8;
3414        patternoffset = sizeof(*filter) - sizeof(filter->cmd) + masksize;
3415
3416        bufsize = sizeof(*filter) + patternsize + masksize;
3417        buf = kzalloc(bufsize, GFP_KERNEL);
3418        if (!buf)
3419                return -ENOMEM;
3420        filter = (struct brcmf_fil_wowl_pattern_le *)buf;
3421
3422        memcpy(filter->cmd, cmd, 4);
3423        filter->masksize = cpu_to_le32(masksize);
3424        filter->offset = cpu_to_le32(packet_offset);
3425        filter->patternoffset = cpu_to_le32(patternoffset);
3426        filter->patternsize = cpu_to_le32(patternsize);
3427        filter->type = cpu_to_le32(BRCMF_WOWL_PATTERN_TYPE_BITMAP);
3428
3429        if ((mask) && (masksize))
3430                memcpy(buf + sizeof(*filter), mask, masksize);
3431        if ((pattern) && (patternsize))
3432                memcpy(buf + sizeof(*filter) + masksize, pattern, patternsize);
3433
3434        ret = brcmf_fil_iovar_data_set(ifp, "wowl_pattern", buf, bufsize);
3435
3436        kfree(buf);
3437        return ret;
3438}
3439
3440static s32
3441brcmf_wowl_nd_results(struct brcmf_if *ifp, const struct brcmf_event_msg *e,
3442                      void *data)
3443{
3444        struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
3445        struct brcmf_pno_scanresults_le *pfn_result;
3446        struct brcmf_pno_net_info_le *netinfo;
3447
3448        brcmf_dbg(SCAN, "Enter\n");
3449
3450        if (e->datalen < (sizeof(*pfn_result) + sizeof(*netinfo))) {
3451                brcmf_dbg(SCAN, "Event data to small. Ignore\n");
3452                return 0;
3453        }
3454
3455        pfn_result = (struct brcmf_pno_scanresults_le *)data;
3456
3457        if (e->event_code == BRCMF_E_PFN_NET_LOST) {
3458                brcmf_dbg(SCAN, "PFN NET LOST event. Ignore\n");
3459                return 0;
3460        }
3461
3462        if (le32_to_cpu(pfn_result->count) < 1) {
3463                brcmf_err("Invalid result count, expected 1 (%d)\n",
3464                          le32_to_cpu(pfn_result->count));
3465                return -EINVAL;
3466        }
3467
3468        netinfo = brcmf_get_netinfo_array(pfn_result);
3469        memcpy(cfg->wowl.nd->ssid.ssid, netinfo->SSID, netinfo->SSID_len);
3470        cfg->wowl.nd->ssid.ssid_len = netinfo->SSID_len;
3471        cfg->wowl.nd->n_channels = 1;
3472        cfg->wowl.nd->channels[0] =
3473                ieee80211_channel_to_frequency(netinfo->channel,
3474                        netinfo->channel <= CH_MAX_2G_CHANNEL ?
3475                                        NL80211_BAND_2GHZ : NL80211_BAND_5GHZ);
3476        cfg->wowl.nd_info->n_matches = 1;
3477        cfg->wowl.nd_info->matches[0] = cfg->wowl.nd;
3478
3479        /* Inform (the resume task) that the net detect information was recvd */
3480        cfg->wowl.nd_data_completed = true;
3481        wake_up(&cfg->wowl.nd_data_wait);
3482
3483        return 0;
3484}
3485
3486#ifdef CONFIG_PM
3487
3488static void brcmf_report_wowl_wakeind(struct wiphy *wiphy, struct brcmf_if *ifp)
3489{
3490        struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3491        struct brcmf_wowl_wakeind_le wake_ind_le;
3492        struct cfg80211_wowlan_wakeup wakeup_data;
3493        struct cfg80211_wowlan_wakeup *wakeup;
3494        u32 wakeind;
3495        s32 err;
3496        int timeout;
3497
3498        err = brcmf_fil_iovar_data_get(ifp, "wowl_wakeind", &wake_ind_le,
3499                                       sizeof(wake_ind_le));
3500        if (err) {
3501                brcmf_err("Get wowl_wakeind failed, err = %d\n", err);
3502                return;
3503        }
3504
3505        wakeind = le32_to_cpu(wake_ind_le.ucode_wakeind);
3506        if (wakeind & (BRCMF_WOWL_MAGIC | BRCMF_WOWL_DIS | BRCMF_WOWL_BCN |
3507                       BRCMF_WOWL_RETR | BRCMF_WOWL_NET |
3508                       BRCMF_WOWL_PFN_FOUND)) {
3509                wakeup = &wakeup_data;
3510                memset(&wakeup_data, 0, sizeof(wakeup_data));
3511                wakeup_data.pattern_idx = -1;
3512
3513                if (wakeind & BRCMF_WOWL_MAGIC) {
3514                        brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_MAGIC\n");
3515                        wakeup_data.magic_pkt = true;
3516                }
3517                if (wakeind & BRCMF_WOWL_DIS) {
3518                        brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_DIS\n");
3519                        wakeup_data.disconnect = true;
3520                }
3521                if (wakeind & BRCMF_WOWL_BCN) {
3522                        brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_BCN\n");
3523                        wakeup_data.disconnect = true;
3524                }
3525                if (wakeind & BRCMF_WOWL_RETR) {
3526                        brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_RETR\n");
3527                        wakeup_data.disconnect = true;
3528                }
3529                if (wakeind & BRCMF_WOWL_NET) {
3530                        brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_NET\n");
3531                        /* For now always map to pattern 0, no API to get
3532                         * correct information available at the moment.
3533                         */
3534                        wakeup_data.pattern_idx = 0;
3535                }
3536                if (wakeind & BRCMF_WOWL_PFN_FOUND) {
3537                        brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_PFN_FOUND\n");
3538                        timeout = wait_event_timeout(cfg->wowl.nd_data_wait,
3539                                cfg->wowl.nd_data_completed,
3540                                BRCMF_ND_INFO_TIMEOUT);
3541                        if (!timeout)
3542                                brcmf_err("No result for wowl net detect\n");
3543                        else
3544                                wakeup_data.net_detect = cfg->wowl.nd_info;
3545                }
3546                if (wakeind & BRCMF_WOWL_GTK_FAILURE) {
3547                        brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_GTK_FAILURE\n");
3548                        wakeup_data.gtk_rekey_failure = true;
3549                }
3550        } else {
3551                wakeup = NULL;
3552        }
3553        cfg80211_report_wowlan_wakeup(&ifp->vif->wdev, wakeup, GFP_KERNEL);
3554}
3555
3556#else
3557
3558static void brcmf_report_wowl_wakeind(struct wiphy *wiphy, struct brcmf_if *ifp)
3559{
3560}
3561
3562#endif /* CONFIG_PM */
3563
3564static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
3565{
3566        struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3567        struct net_device *ndev = cfg_to_ndev(cfg);
3568        struct brcmf_if *ifp = netdev_priv(ndev);
3569
3570        brcmf_dbg(TRACE, "Enter\n");
3571
3572        if (cfg->wowl.active) {
3573                brcmf_report_wowl_wakeind(wiphy, ifp);
3574                brcmf_fil_iovar_int_set(ifp, "wowl_clear", 0);
3575                brcmf_config_wowl_pattern(ifp, "clr", NULL, 0, NULL, 0);
3576                if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_ARP_ND))
3577                        brcmf_configure_arp_nd_offload(ifp, true);
3578                brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM,
3579                                      cfg->wowl.pre_pmmode);
3580                cfg->wowl.active = false;
3581                if (cfg->wowl.nd_enabled) {
3582                        brcmf_cfg80211_sched_scan_stop(cfg->wiphy, ifp->ndev, 0);
3583                        brcmf_fweh_unregister(cfg->pub, BRCMF_E_PFN_NET_FOUND);
3584                        brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
3585                                            brcmf_notify_sched_scan_results);
3586                        cfg->wowl.nd_enabled = false;
3587                }
3588        }
3589        return 0;
3590}
3591
3592static void brcmf_configure_wowl(struct brcmf_cfg80211_info *cfg,
3593                                 struct brcmf_if *ifp,
3594                                 struct cfg80211_wowlan *wowl)
3595{
3596        u32 wowl_config;
3597        struct brcmf_wowl_wakeind_le wowl_wakeind;
3598        u32 i;
3599
3600        brcmf_dbg(TRACE, "Suspend, wowl config.\n");
3601
3602        if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_ARP_ND))
3603                brcmf_configure_arp_nd_offload(ifp, false);
3604        brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_PM, &cfg->wowl.pre_pmmode);
3605        brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, PM_MAX);
3606
3607        wowl_config = 0;
3608        if (wowl->disconnect)
3609                wowl_config = BRCMF_WOWL_DIS | BRCMF_WOWL_BCN | BRCMF_WOWL_RETR;
3610        if (wowl->magic_pkt)
3611                wowl_config |= BRCMF_WOWL_MAGIC;
3612        if ((wowl->patterns) && (wowl->n_patterns)) {
3613                wowl_config |= BRCMF_WOWL_NET;
3614                for (i = 0; i < wowl->n_patterns; i++) {
3615                        brcmf_config_wowl_pattern(ifp, "add",
3616                                (u8 *)wowl->patterns[i].pattern,
3617                                wowl->patterns[i].pattern_len,
3618                                (u8 *)wowl->patterns[i].mask,
3619                                wowl->patterns[i].pkt_offset);
3620                }
3621        }
3622        if (wowl->nd_config) {
3623                brcmf_cfg80211_sched_scan_start(cfg->wiphy, ifp->ndev,
3624                                                wowl->nd_config);
3625                wowl_config |= BRCMF_WOWL_PFN_FOUND;
3626
3627                cfg->wowl.nd_data_completed = false;
3628                cfg->wowl.nd_enabled = true;
3629                /* Now reroute the event for PFN to the wowl function. */
3630                brcmf_fweh_unregister(cfg->pub, BRCMF_E_PFN_NET_FOUND);
3631                brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
3632                                    brcmf_wowl_nd_results);
3633        }
3634        if (wowl->gtk_rekey_failure)
3635                wowl_config |= BRCMF_WOWL_GTK_FAILURE;
3636        if (!test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state))
3637                wowl_config |= BRCMF_WOWL_UNASSOC;
3638
3639        memcpy(&wowl_wakeind, "clear", 6);
3640        brcmf_fil_iovar_data_set(ifp, "wowl_wakeind", &wowl_wakeind,
3641                                 sizeof(wowl_wakeind));
3642        brcmf_fil_iovar_int_set(ifp, "wowl", wowl_config);
3643        brcmf_fil_iovar_int_set(ifp, "wowl_activate", 1);
3644        brcmf_bus_wowl_config(cfg->pub->bus_if, true);
3645        cfg->wowl.active = true;
3646}
3647
3648static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
3649                                  struct cfg80211_wowlan *wowl)
3650{
3651        struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3652        struct net_device *ndev = cfg_to_ndev(cfg);
3653        struct brcmf_if *ifp = netdev_priv(ndev);
3654        struct brcmf_cfg80211_vif *vif;
3655
3656        brcmf_dbg(TRACE, "Enter\n");
3657
3658        /* if the primary net_device is not READY there is nothing
3659         * we can do but pray resume goes smoothly.
3660         */
3661        if (!check_vif_up(ifp->vif))
3662                goto exit;
3663
3664        /* Stop scheduled scan */
3665        if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO))
3666                brcmf_cfg80211_sched_scan_stop(wiphy, ndev, 0);
3667
3668        /* end any scanning */
3669        if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
3670                brcmf_abort_scanning(cfg);
3671
3672        if (wowl == NULL) {
3673                brcmf_bus_wowl_config(cfg->pub->bus_if, false);
3674                list_for_each_entry(vif, &cfg->vif_list, list) {
3675                        if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state))
3676                                continue;
3677                        /* While going to suspend if associated with AP
3678                         * disassociate from AP to save power while system is
3679                         * in suspended state
3680                         */
3681                        brcmf_link_down(vif, WLAN_REASON_UNSPECIFIED);
3682                        /* Make sure WPA_Supplicant receives all the event
3683                         * generated due to DISASSOC call to the fw to keep
3684                         * the state fw and WPA_Supplicant state consistent
3685                         */
3686                        brcmf_delay(500);
3687                }
3688                /* Configure MPC */
3689                brcmf_set_mpc(ifp, 1);
3690
3691        } else {
3692                /* Configure WOWL paramaters */
3693                brcmf_configure_wowl(cfg, ifp, wowl);
3694        }
3695
3696exit:
3697        brcmf_dbg(TRACE, "Exit\n");
3698        /* clear any scanning activity */
3699        cfg->scan_status = 0;
3700        return 0;
3701}
3702
3703static __used s32
3704brcmf_update_pmklist(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp)
3705{
3706        struct brcmf_pmk_list_le *pmk_list;
3707        int i;
3708        u32 npmk;
3709        s32 err;
3710
3711        pmk_list = &cfg->pmk_list;
3712        npmk = le32_to_cpu(pmk_list->npmk);
3713
3714        brcmf_dbg(CONN, "No of elements %d\n", npmk);
3715        for (i = 0; i < npmk; i++)
3716                brcmf_dbg(CONN, "PMK[%d]: %pM\n", i, &pmk_list->pmk[i].bssid);
3717
3718        err = brcmf_fil_iovar_data_set(ifp, "pmkid_info", pmk_list,
3719                                       sizeof(*pmk_list));
3720
3721        return err;
3722}
3723
3724static s32
3725brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
3726                         struct cfg80211_pmksa *pmksa)
3727{
3728        struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3729        struct brcmf_if *ifp = netdev_priv(ndev);
3730        struct brcmf_pmksa *pmk = &cfg->pmk_list.pmk[0];
3731        s32 err;
3732        u32 npmk, i;
3733
3734        brcmf_dbg(TRACE, "Enter\n");
3735        if (!check_vif_up(ifp->vif))
3736                return -EIO;
3737
3738        npmk = le32_to_cpu(cfg->pmk_list.npmk);
3739        for (i = 0; i < npmk; i++)
3740                if (!memcmp(pmksa->bssid, pmk[i].bssid, ETH_ALEN))
3741                        break;
3742        if (i < BRCMF_MAXPMKID) {
3743                memcpy(pmk[i].bssid, pmksa->bssid, ETH_ALEN);
3744                memcpy(pmk[i].pmkid, pmksa->pmkid, WLAN_PMKID_LEN);
3745                if (i == npmk) {
3746                        npmk++;
3747                        cfg->pmk_list.npmk = cpu_to_le32(npmk);
3748                }
3749        } else {
3750                brcmf_err("Too many PMKSA entries cached %d\n", npmk);
3751                return -EINVAL;
3752        }
3753
3754        brcmf_dbg(CONN, "set_pmksa - PMK bssid: %pM =\n", pmk[npmk].bssid);
3755        for (i = 0; i < WLAN_PMKID_LEN; i += 4)
3756                brcmf_dbg(CONN, "%02x %02x %02x %02x\n", pmk[npmk].pmkid[i],
3757                          pmk[npmk].pmkid[i + 1], pmk[npmk].pmkid[i + 2],
3758                          pmk[npmk].pmkid[i + 3]);
3759
3760        err = brcmf_update_pmklist(cfg, ifp);
3761
3762        brcmf_dbg(TRACE, "Exit\n");
3763        return err;
3764}
3765
3766static s32
3767brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
3768                         struct cfg80211_pmksa *pmksa)
3769{
3770        struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3771        struct brcmf_if *ifp = netdev_priv(ndev);
3772        struct brcmf_pmksa *pmk = &cfg->pmk_list.pmk[0];
3773        s32 err;
3774        u32 npmk, i;
3775
3776        brcmf_dbg(TRACE, "Enter\n");
3777        if (!check_vif_up(ifp->vif))
3778                return -EIO;
3779
3780        brcmf_dbg(CONN, "del_pmksa - PMK bssid = %pM\n", pmksa->bssid);
3781
3782        npmk = le32_to_cpu(cfg->pmk_list.npmk);
3783        for (i = 0; i < npmk; i++)
3784                if (!memcmp(pmksa->bssid, pmk[i].bssid, ETH_ALEN))
3785                        break;
3786
3787        if ((npmk > 0) && (i < npmk)) {
3788                for (; i < (npmk - 1); i++) {
3789                        memcpy(&pmk[i].bssid, &pmk[i + 1].bssid, ETH_ALEN);
3790                        memcpy(&pmk[i].pmkid, &pmk[i + 1].pmkid,
3791                               WLAN_PMKID_LEN);
3792                }
3793                memset(&pmk[i], 0, sizeof(*pmk));
3794                cfg->pmk_list.npmk = cpu_to_le32(npmk - 1);
3795        } else {
3796                brcmf_err("Cache entry not found\n");
3797                return -EINVAL;
3798        }
3799
3800        err = brcmf_update_pmklist(cfg, ifp);
3801
3802        brcmf_dbg(TRACE, "Exit\n");
3803        return err;
3804
3805}
3806
3807static s32
3808brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
3809{
3810        struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3811        struct brcmf_if *ifp = netdev_priv(ndev);
3812        s32 err;
3813
3814        brcmf_dbg(TRACE, "Enter\n");
3815        if (!check_vif_up(ifp->vif))
3816                return -EIO;
3817
3818        memset(&cfg->pmk_list, 0, sizeof(cfg->pmk_list));
3819        err = brcmf_update_pmklist(cfg, ifp);
3820
3821        brcmf_dbg(TRACE, "Exit\n");
3822        return err;
3823
3824}
3825
3826static s32 brcmf_configure_opensecurity(struct brcmf_if *ifp)
3827{
3828        s32 err;
3829        s32 wpa_val;
3830
3831        /* set auth */
3832        err = brcmf_fil_bsscfg_int_set(ifp, "auth", 0);
3833        if (err < 0) {
3834                brcmf_err("auth error %d\n", err);
3835                return err;
3836        }
3837        /* set wsec */
3838        err = brcmf_fil_bsscfg_int_set(ifp, "wsec", 0);
3839        if (err < 0) {
3840                brcmf_err("wsec error %d\n", err);
3841                return err;
3842        }
3843        /* set upper-layer auth */
3844        if (brcmf_is_ibssmode(ifp->vif))
3845                wpa_val = WPA_AUTH_NONE;
3846        else
3847                wpa_val = WPA_AUTH_DISABLED;
3848        err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", wpa_val);
3849        if (err < 0) {
3850                brcmf_err("wpa_auth error %d\n", err);
3851                return err;
3852        }
3853
3854        return 0;
3855}
3856
3857static bool brcmf_valid_wpa_oui(u8 *oui, bool is_rsn_ie)
3858{
3859        if (is_rsn_ie)
3860                return (memcmp(oui, RSN_OUI, TLV_OUI_LEN) == 0);
3861
3862        return (memcmp(oui, WPA_OUI, TLV_OUI_LEN) == 0);
3863}
3864
3865static s32
3866brcmf_configure_wpaie(struct brcmf_if *ifp,
3867                      const struct brcmf_vs_tlv *wpa_ie,
3868                      bool is_rsn_ie)
3869{
3870        u32 auth = 0; /* d11 open authentication */
3871        u16 count;
3872        s32 err = 0;
3873        s32 len;
3874        u32 i;
3875        u32 wsec;
3876        u32 pval = 0;
3877        u32 gval = 0;
3878        u32 wpa_auth = 0;
3879        u32 offset;
3880        u8 *data;
3881        u16 rsn_cap;
3882        u32 wme_bss_disable;
3883        u32 mfp;
3884
3885        brcmf_dbg(TRACE, "Enter\n");
3886        if (wpa_ie == NULL)
3887                goto exit;
3888
3889        len = wpa_ie->len + TLV_HDR_LEN;
3890        data = (u8 *)wpa_ie;
3891        offset = TLV_HDR_LEN;
3892        if (!is_rsn_ie)
3893                offset += VS_IE_FIXED_HDR_LEN;
3894        else
3895                offset += WPA_IE_VERSION_LEN;
3896
3897        /* check for multicast cipher suite */
3898        if (offset + WPA_IE_MIN_OUI_LEN > len) {
3899                err = -EINVAL;
3900                brcmf_err("no multicast cipher suite\n");
3901                goto exit;
3902        }
3903
3904        if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3905                err = -EINVAL;
3906                brcmf_err("ivalid OUI\n");
3907                goto exit;
3908        }
3909        offset += TLV_OUI_LEN;
3910
3911        /* pick up multicast cipher */
3912        switch (data[offset]) {
3913        case WPA_CIPHER_NONE:
3914                gval = 0;
3915                break;
3916        case WPA_CIPHER_WEP_40:
3917        case WPA_CIPHER_WEP_104:
3918                gval = WEP_ENABLED;
3919                break;
3920        case WPA_CIPHER_TKIP:
3921                gval = TKIP_ENABLED;
3922                break;
3923        case WPA_CIPHER_AES_CCM:
3924                gval = AES_ENABLED;
3925                break;
3926        default:
3927                err = -EINVAL;
3928                brcmf_err("Invalid multi cast cipher info\n");
3929                goto exit;
3930        }
3931
3932        offset++;
3933        /* walk thru unicast cipher list and pick up what we recognize */
3934        count = data[offset] + (data[offset + 1] << 8);
3935        offset += WPA_IE_SUITE_COUNT_LEN;
3936        /* Check for unicast suite(s) */
3937        if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3938                err = -EINVAL;
3939                brcmf_err("no unicast cipher suite\n");
3940                goto exit;
3941        }
3942        for (i = 0; i < count; i++) {
3943                if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3944                        err = -EINVAL;
3945                        brcmf_err("ivalid OUI\n");
3946                        goto exit;
3947                }
3948                offset += TLV_OUI_LEN;
3949                switch (data[offset]) {
3950                case WPA_CIPHER_NONE:
3951                        break;
3952                case WPA_CIPHER_WEP_40:
3953                case WPA_CIPHER_WEP_104:
3954                        pval |= WEP_ENABLED;
3955                        break;
3956                case WPA_CIPHER_TKIP:
3957                        pval |= TKIP_ENABLED;
3958                        break;
3959                case WPA_CIPHER_AES_CCM:
3960                        pval |= AES_ENABLED;
3961                        break;
3962                default:
3963                        brcmf_err("Invalid unicast security info\n");
3964                }
3965                offset++;
3966        }
3967        /* walk thru auth management suite list and pick up what we recognize */
3968        count = data[offset] + (data[offset + 1] << 8);
3969        offset += WPA_IE_SUITE_COUNT_LEN;
3970        /* Check for auth key management suite(s) */
3971        if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3972                err = -EINVAL;
3973                brcmf_err("no auth key mgmt suite\n");
3974                goto exit;
3975        }
3976        for (i = 0; i < count; i++) {
3977                if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3978                        err = -EINVAL;
3979                        brcmf_err("ivalid OUI\n");
3980                        goto exit;
3981                }
3982                offset += TLV_OUI_LEN;
3983                switch (data[offset]) {
3984                case RSN_AKM_NONE:
3985                        brcmf_dbg(TRACE, "RSN_AKM_NONE\n");
3986                        wpa_auth |= WPA_AUTH_NONE;
3987                        break;
3988                case RSN_AKM_UNSPECIFIED:
3989                        brcmf_dbg(TRACE, "RSN_AKM_UNSPECIFIED\n");
3990                        is_rsn_ie ? (wpa_auth |= WPA2_AUTH_UNSPECIFIED) :
3991                                    (wpa_auth |= WPA_AUTH_UNSPECIFIED);
3992                        break;
3993                case RSN_AKM_PSK:
3994                        brcmf_dbg(TRACE, "RSN_AKM_PSK\n");
3995                        is_rsn_ie ? (wpa_auth |= WPA2_AUTH_PSK) :
3996                                    (wpa_auth |= WPA_AUTH_PSK);
3997                        break;
3998                case RSN_AKM_SHA256_PSK:
3999                        brcmf_dbg(TRACE, "RSN_AKM_MFP_PSK\n");
4000                        wpa_auth |= WPA2_AUTH_PSK_SHA256;
4001                        break;
4002                case RSN_AKM_SHA256_1X:
4003                        brcmf_dbg(TRACE, "RSN_AKM_MFP_1X\n");
4004                        wpa_auth |= WPA2_AUTH_1X_SHA256;
4005                        break;
4006                default:
4007                        brcmf_err("Invalid key mgmt info\n");
4008                }
4009                offset++;
4010        }
4011
4012        mfp = BRCMF_MFP_NONE;
4013        if (is_rsn_ie) {
4014                wme_bss_disable = 1;
4015                if ((offset + RSN_CAP_LEN) <= len) {
4016                        rsn_cap = data[offset] + (data[offset + 1] << 8);
4017                        if (rsn_cap & RSN_CAP_PTK_REPLAY_CNTR_MASK)
4018                                wme_bss_disable = 0;
4019                        if (rsn_cap & RSN_CAP_MFPR_MASK) {
4020                                brcmf_dbg(TRACE, "MFP Required\n");
4021                                mfp = BRCMF_MFP_REQUIRED;
4022                                /* Firmware only supports mfp required in
4023                                 * combination with WPA2_AUTH_PSK_SHA256 or
4024                                 * WPA2_AUTH_1X_SHA256.
4025                                 */
4026                                if (!(wpa_auth & (WPA2_AUTH_PSK_SHA256 |
4027                                                  WPA2_AUTH_1X_SHA256))) {
4028                                        err = -EINVAL;
4029                                        goto exit;
4030                                }
4031                                /* Firmware has requirement that WPA2_AUTH_PSK/
4032                                 * WPA2_AUTH_UNSPECIFIED be set, if SHA256 OUI
4033                                 * is to be included in the rsn ie.
4034                                 */
4035                                if (wpa_auth & WPA2_AUTH_PSK_SHA256)
4036                                        wpa_auth |= WPA2_AUTH_PSK;
4037                                else if (wpa_auth & WPA2_AUTH_1X_SHA256)
4038                                        wpa_auth |= WPA2_AUTH_UNSPECIFIED;
4039                        } else if (rsn_cap & RSN_CAP_MFPC_MASK) {
4040                                brcmf_dbg(TRACE, "MFP Capable\n");
4041                                mfp = BRCMF_MFP_CAPABLE;
4042                        }
4043                }
4044                offset += RSN_CAP_LEN;
4045                /* set wme_bss_disable to sync RSN Capabilities */
4046                err = brcmf_fil_bsscfg_int_set(ifp, "wme_bss_disable",
4047                                               wme_bss_disable);
4048                if (err < 0) {
4049                        brcmf_err("wme_bss_disable error %d\n", err);
4050                        goto exit;
4051                }
4052
4053                /* Skip PMKID cnt as it is know to be 0 for AP. */
4054                offset += RSN_PMKID_COUNT_LEN;
4055
4056                /* See if there is BIP wpa suite left for MFP */
4057                if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP) &&
4058                    ((offset + WPA_IE_MIN_OUI_LEN) <= len)) {
4059                        err = brcmf_fil_bsscfg_data_set(ifp, "bip",
4060                                                        &data[offset],
4061                                                        WPA_IE_MIN_OUI_LEN);
4062                        if (err < 0) {
4063                                brcmf_err("bip error %d\n", err);
4064                                goto exit;
4065                        }
4066                }
4067        }
4068        /* FOR WPS , set SES_OW_ENABLED */
4069        wsec = (pval | gval | SES_OW_ENABLED);
4070
4071        /* set auth */
4072        err = brcmf_fil_bsscfg_int_set(ifp, "auth", auth);
4073        if (err < 0) {
4074                brcmf_err("auth error %d\n", err);
4075                goto exit;
4076        }
4077        /* set wsec */
4078        err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
4079        if (err < 0) {
4080                brcmf_err("wsec error %d\n", err);
4081                goto exit;
4082        }
4083        /* Configure MFP, this needs to go after wsec otherwise the wsec command
4084         * will overwrite the values set by MFP
4085         */
4086        if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP)) {
4087                err = brcmf_fil_bsscfg_int_set(ifp, "mfp", mfp);
4088                if (err < 0) {
4089                        brcmf_err("mfp error %d\n", err);
4090                        goto exit;
4091                }
4092        }
4093        /* set upper-layer auth */
4094        err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", wpa_auth);
4095        if (err < 0) {
4096                brcmf_err("wpa_auth error %d\n", err);
4097                goto exit;
4098        }
4099
4100exit:
4101        return err;
4102}
4103
4104static s32
4105brcmf_parse_vndr_ies(const u8 *vndr_ie_buf, u32 vndr_ie_len,
4106                     struct parsed_vndr_ies *vndr_ies)
4107{
4108        struct brcmf_vs_tlv *vndrie;
4109        struct brcmf_tlv *ie;
4110        struct parsed_vndr_ie_info *parsed_info;
4111        s32 remaining_len;
4112
4113        remaining_len = (s32)vndr_ie_len;
4114        memset(vndr_ies, 0, sizeof(*vndr_ies));
4115
4116        ie = (struct brcmf_tlv *)vndr_ie_buf;
4117        while (ie) {
4118                if (ie->id != WLAN_EID_VENDOR_SPECIFIC)
4119                        goto next;
4120                vndrie = (struct brcmf_vs_tlv *)ie;
4121                /* len should be bigger than OUI length + one */
4122                if (vndrie->len < (VS_IE_FIXED_HDR_LEN - TLV_HDR_LEN + 1)) {
4123                        brcmf_err("invalid vndr ie. length is too small %d\n",
4124                                  vndrie->len);
4125                        goto next;
4126                }
4127                /* if wpa or wme ie, do not add ie */
4128                if (!memcmp(vndrie->oui, (u8 *)WPA_OUI, TLV_OUI_LEN) &&
4129                    ((vndrie->oui_type == WPA_OUI_TYPE) ||
4130                    (vndrie->oui_type == WME_OUI_TYPE))) {
4131                        brcmf_dbg(TRACE, "Found WPA/WME oui. Do not add it\n");
4132                        goto next;
4133                }
4134
4135                parsed_info = &vndr_ies->ie_info[vndr_ies->count];
4136
4137                /* save vndr ie information */
4138                parsed_info->ie_ptr = (char *)vndrie;
4139                parsed_info->ie_len = vndrie->len + TLV_HDR_LEN;
4140                memcpy(&parsed_info->vndrie, vndrie, sizeof(*vndrie));
4141
4142                vndr_ies->count++;
4143
4144                brcmf_dbg(TRACE, "** OUI %02x %02x %02x, type 0x%02x\n",
4145                          parsed_info->vndrie.oui[0],
4146                          parsed_info->vndrie.oui[1],
4147                          parsed_info->vndrie.oui[2],
4148                          parsed_info->vndrie.oui_type);
4149
4150                if (vndr_ies->count >= VNDR_IE_PARSE_LIMIT)
4151                        break;
4152next:
4153                remaining_len -= (ie->len + TLV_HDR_LEN);
4154                if (remaining_len <= TLV_HDR_LEN)
4155                        ie = NULL;
4156                else
4157                        ie = (struct brcmf_tlv *)(((u8 *)ie) + ie->len +
4158                                TLV_HDR_LEN);
4159        }
4160        return 0;
4161}
4162
4163static u32
4164brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd)
4165{
4166
4167        strncpy(iebuf, add_del_cmd, VNDR_IE_CMD_LEN - 1);
4168        iebuf[VNDR_IE_CMD_LEN - 1] = '\0';
4169
4170        put_unaligned_le32(1, &iebuf[VNDR_IE_COUNT_OFFSET]);
4171
4172        put_unaligned_le32(pktflag, &iebuf[VNDR_IE_PKTFLAG_OFFSET]);
4173
4174        memcpy(&iebuf[VNDR_IE_VSIE_OFFSET], ie_ptr, ie_len);
4175
4176        return ie_len + VNDR_IE_HDR_SIZE;
4177}
4178
4179s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
4180                          const u8 *vndr_ie_buf, u32 vndr_ie_len)
4181{
4182        struct brcmf_if *ifp;
4183        struct vif_saved_ie *saved_ie;
4184        s32 err = 0;
4185        u8  *iovar_ie_buf;
4186        u8  *curr_ie_buf;
4187        u8  *mgmt_ie_buf = NULL;
4188        int mgmt_ie_buf_len;
4189        u32 *mgmt_ie_len;
4190        u32 del_add_ie_buf_len = 0;
4191        u32 total_ie_buf_len = 0;
4192        u32 parsed_ie_buf_len = 0;
4193        struct parsed_vndr_ies old_vndr_ies;
4194        struct parsed_vndr_ies new_vndr_ies;
4195        struct parsed_vndr_ie_info *vndrie_info;
4196        s32 i;
4197        u8 *ptr;
4198        int remained_buf_len;
4199
4200        if (!vif)
4201                return -ENODEV;
4202        ifp = vif->ifp;
4203        saved_ie = &vif->saved_ie;
4204
4205        brcmf_dbg(TRACE, "bsscfgidx %d, pktflag : 0x%02X\n", ifp->bsscfgidx,
4206                  pktflag);
4207        iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
4208        if (!iovar_ie_buf)
4209                return -ENOMEM;
4210        curr_ie_buf = iovar_ie_buf;
4211        switch (pktflag) {
4212        case BRCMF_VNDR_IE_PRBREQ_FLAG:
4213                mgmt_ie_buf = saved_ie->probe_req_ie;
4214                mgmt_ie_len = &saved_ie->probe_req_ie_len;
4215                mgmt_ie_buf_len = sizeof(saved_ie->probe_req_ie);
4216                break;
4217        case BRCMF_VNDR_IE_PRBRSP_FLAG:
4218                mgmt_ie_buf = saved_ie->probe_res_ie;
4219                mgmt_ie_len = &saved_ie->probe_res_ie_len;
4220                mgmt_ie_buf_len = sizeof(saved_ie->probe_res_ie);
4221                break;
4222        case BRCMF_VNDR_IE_BEACON_FLAG:
4223                mgmt_ie_buf = saved_ie->beacon_ie;
4224                mgmt_ie_len = &saved_ie->beacon_ie_len;
4225                mgmt_ie_buf_len = sizeof(saved_ie->beacon_ie);
4226                break;
4227        case BRCMF_VNDR_IE_ASSOCREQ_FLAG:
4228                mgmt_ie_buf = saved_ie->assoc_req_ie;
4229                mgmt_ie_len = &saved_ie->assoc_req_ie_len;
4230                mgmt_ie_buf_len = sizeof(saved_ie->assoc_req_ie);
4231                break;
4232        default:
4233                err = -EPERM;
4234                brcmf_err("not suitable type\n");
4235                goto exit;
4236        }
4237
4238        if (vndr_ie_len > mgmt_ie_buf_len) {
4239                err = -ENOMEM;
4240                brcmf_err("extra IE size too big\n");
4241                goto exit;
4242        }
4243
4244        /* parse and save new vndr_ie in curr_ie_buff before comparing it */
4245        if (vndr_ie_buf && vndr_ie_len && curr_ie_buf) {
4246                ptr = curr_ie_buf;
4247                brcmf_parse_vndr_ies(vndr_ie_buf, vndr_ie_len, &new_vndr_ies);
4248                for (i = 0; i < new_vndr_ies.count; i++) {
4249                        vndrie_info = &new_vndr_ies.ie_info[i];
4250                        memcpy(ptr + parsed_ie_buf_len, vndrie_info->ie_ptr,
4251                               vndrie_info->ie_len);
4252                        parsed_ie_buf_len += vndrie_info->ie_len;
4253                }
4254        }
4255
4256        if (mgmt_ie_buf && *mgmt_ie_len) {
4257                if (parsed_ie_buf_len && (parsed_ie_buf_len == *mgmt_ie_len) &&
4258                    (memcmp(mgmt_ie_buf, curr_ie_buf,
4259                            parsed_ie_buf_len) == 0)) {
4260                        brcmf_dbg(TRACE, "Previous mgmt IE equals to current IE\n");
4261                        goto exit;
4262                }
4263
4264                /* parse old vndr_ie */
4265                brcmf_parse_vndr_ies(mgmt_ie_buf, *mgmt_ie_len, &old_vndr_ies);
4266
4267                /* make a command to delete old ie */
4268                for (i = 0; i < old_vndr_ies.count; i++) {
4269                        vndrie_info = &old_vndr_ies.ie_info[i];
4270
4271                        brcmf_dbg(TRACE, "DEL ID : %d, Len: %d , OUI:%02x:%02x:%02x\n",
4272                                  vndrie_info->vndrie.id,
4273                                  vndrie_info->vndrie.len,
4274                                  vndrie_info->vndrie.oui[0],
4275                                  vndrie_info->vndrie.oui[1],
4276                                  vndrie_info->vndrie.oui[2]);
4277
4278                        del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
4279                                                           vndrie_info->ie_ptr,
4280                                                           vndrie_info->ie_len,
4281                                                           "del");
4282                        curr_ie_buf += del_add_ie_buf_len;
4283                        total_ie_buf_len += del_add_ie_buf_len;
4284                }
4285        }
4286
4287        *mgmt_ie_len = 0;
4288        /* Add if there is any extra IE */
4289        if (mgmt_ie_buf && parsed_ie_buf_len) {
4290                ptr = mgmt_ie_buf;
4291
4292                remained_buf_len = mgmt_ie_buf_len;
4293
4294                /* make a command to add new ie */
4295                for (i = 0; i < new_vndr_ies.count; i++) {
4296                        vndrie_info = &new_vndr_ies.ie_info[i];
4297
4298                        /* verify remained buf size before copy data */
4299                        if (remained_buf_len < (vndrie_info->vndrie.len +
4300                                                        VNDR_IE_VSIE_OFFSET)) {
4301                                brcmf_err("no space in mgmt_ie_buf: len left %d",
4302                                          remained_buf_len);
4303                                break;
4304                        }
4305                        remained_buf_len -= (vndrie_info->ie_len +
4306                                             VNDR_IE_VSIE_OFFSET);
4307
4308                        brcmf_dbg(TRACE, "ADDED ID : %d, Len: %d, OUI:%02x:%02x:%02x\n",
4309                                  vndrie_info->vndrie.id,
4310                                  vndrie_info->vndrie.len,
4311                                  vndrie_info->vndrie.oui[0],
4312                                  vndrie_info->vndrie.oui[1],
4313                                  vndrie_info->vndrie.oui[2]);
4314
4315                        del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
4316                                                           vndrie_info->ie_ptr,
4317                                                           vndrie_info->ie_len,
4318                                                           "add");
4319
4320                        /* save the parsed IE in wl struct */
4321                        memcpy(ptr + (*mgmt_ie_len), vndrie_info->ie_ptr,
4322                               vndrie_info->ie_len);
4323                        *mgmt_ie_len += vndrie_info->ie_len;
4324
4325                        curr_ie_buf += del_add_ie_buf_len;
4326                        total_ie_buf_len += del_add_ie_buf_len;
4327                }
4328        }
4329        if (total_ie_buf_len) {
4330                err  = brcmf_fil_bsscfg_data_set(ifp, "vndr_ie", iovar_ie_buf,
4331                                                 total_ie_buf_len);
4332                if (err)
4333                        brcmf_err("vndr ie set error : %d\n", err);
4334        }
4335
4336exit:
4337        kfree(iovar_ie_buf);
4338        return err;
4339}
4340
4341s32 brcmf_vif_clear_mgmt_ies(struct brcmf_cfg80211_vif *vif)
4342{
4343        s32 pktflags[] = {
4344                BRCMF_VNDR_IE_PRBREQ_FLAG,
4345                BRCMF_VNDR_IE_PRBRSP_FLAG,
4346                BRCMF_VNDR_IE_BEACON_FLAG
4347        };
4348        int i;
4349
4350        for (i = 0; i < ARRAY_SIZE(pktflags); i++)
4351                brcmf_vif_set_mgmt_ie(vif, pktflags[i], NULL, 0);
4352
4353        memset(&vif->saved_ie, 0, sizeof(vif->saved_ie));
4354        return 0;
4355}
4356
4357static s32
4358brcmf_config_ap_mgmt_ie(struct brcmf_cfg80211_vif *vif,
4359                        struct cfg80211_beacon_data *beacon)
4360{
4361        s32 err;
4362
4363        /* Set Beacon IEs to FW */
4364        err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_BEACON_FLAG,
4365                                    beacon->tail, beacon->tail_len);
4366        if (err) {
4367                brcmf_err("Set Beacon IE Failed\n");
4368                return err;
4369        }
4370        brcmf_dbg(TRACE, "Applied Vndr IEs for Beacon\n");
4371
4372        /* Set Probe Response IEs to FW */
4373        err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_PRBRSP_FLAG,
4374                                    beacon->proberesp_ies,
4375                                    beacon->proberesp_ies_len);
4376        if (err)
4377                brcmf_err("Set Probe Resp IE Failed\n");
4378        else
4379                brcmf_dbg(TRACE, "Applied Vndr IEs for Probe Resp\n");
4380
4381        return err;
4382}
4383
4384static s32
4385brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
4386                        struct cfg80211_ap_settings *settings)
4387{
4388        s32 ie_offset;
4389        struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4390        struct brcmf_if *ifp = netdev_priv(ndev);
4391        const struct brcmf_tlv *ssid_ie;
4392        const struct brcmf_tlv *country_ie;
4393        struct brcmf_ssid_le ssid_le;
4394        s32 err = -EPERM;
4395        const struct brcmf_tlv *rsn_ie;
4396        const struct brcmf_vs_tlv *wpa_ie;
4397        struct brcmf_join_params join_params;
4398        enum nl80211_iftype dev_role;
4399        struct brcmf_fil_bss_enable_le bss_enable;
4400        u16 chanspec = chandef_to_chanspec(&cfg->d11inf, &settings->chandef);
4401        bool mbss;
4402        int is_11d;
4403        bool supports_11d;
4404
4405        brcmf_dbg(TRACE, "ctrlchn=%d, center=%d, bw=%d, beacon_interval=%d, dtim_period=%d,\n",
4406                  settings->chandef.chan->hw_value,
4407                  settings->chandef.center_freq1, settings->chandef.width,
4408                  settings->beacon_interval, settings->dtim_period);
4409        brcmf_dbg(TRACE, "ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n",
4410                  settings->ssid, settings->ssid_len, settings->auth_type,
4411                  settings->inactivity_timeout);
4412        dev_role = ifp->vif->wdev.iftype;
4413        mbss = ifp->vif->mbss;
4414
4415        /* store current 11d setting */
4416        if (brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_REGULATORY,
4417                                  &ifp->vif->is_11d)) {
4418                is_11d = supports_11d = false;
4419        } else {
4420                country_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
4421                                              settings->beacon.tail_len,
4422                                              WLAN_EID_COUNTRY);
4423                is_11d = country_ie ? 1 : 0;
4424                supports_11d = true;
4425        }
4426
4427        memset(&ssid_le, 0, sizeof(ssid_le));
4428        if (settings->ssid == NULL || settings->ssid_len == 0) {
4429                ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
4430                ssid_ie = brcmf_parse_tlvs(
4431                                (u8 *)&settings->beacon.head[ie_offset],
4432                                settings->beacon.head_len - ie_offset,
4433                                WLAN_EID_SSID);
4434                if (!ssid_ie || ssid_ie->len > IEEE80211_MAX_SSID_LEN)
4435                        return -EINVAL;
4436
4437                memcpy(ssid_le.SSID, ssid_ie->data, ssid_ie->len);
4438                ssid_le.SSID_len = cpu_to_le32(ssid_ie->len);
4439                brcmf_dbg(TRACE, "SSID is (%s) in Head\n", ssid_le.SSID);
4440        } else {
4441                memcpy(ssid_le.SSID, settings->ssid, settings->ssid_len);
4442                ssid_le.SSID_len = cpu_to_le32((u32)settings->ssid_len);
4443        }
4444
4445        if (!mbss) {
4446                brcmf_set_mpc(ifp, 0);
4447                brcmf_configure_arp_nd_offload(ifp, false);
4448        }
4449
4450        /* find the RSN_IE */
4451        rsn_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
4452                                  settings->beacon.tail_len, WLAN_EID_RSN);
4453
4454        /* find the WPA_IE */
4455        wpa_ie = brcmf_find_wpaie((u8 *)settings->beacon.tail,
4456                                  settings->beacon.tail_len);
4457
4458        if ((wpa_ie != NULL || rsn_ie != NULL)) {
4459                brcmf_dbg(TRACE, "WPA(2) IE is found\n");
4460                if (wpa_ie != NULL) {
4461                        /* WPA IE */
4462                        err = brcmf_configure_wpaie(ifp, wpa_ie, false);
4463                        if (err < 0)
4464                                goto exit;
4465                } else {
4466                        struct brcmf_vs_tlv *tmp_ie;
4467
4468                        tmp_ie = (struct brcmf_vs_tlv *)rsn_ie;
4469
4470                        /* RSN IE */
4471                        err = brcmf_configure_wpaie(ifp, tmp_ie, true);
4472                        if (err < 0)
4473                                goto exit;
4474                }
4475        } else {
4476                brcmf_dbg(TRACE, "No WPA(2) IEs found\n");
4477                brcmf_configure_opensecurity(ifp);
4478        }
4479
4480        /* Parameters shared by all radio interfaces */
4481        if (!mbss) {
4482                if ((supports_11d) && (is_11d != ifp->vif->is_11d)) {
4483                        err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY,
4484                                                    is_11d);
4485                        if (err < 0) {
4486                                brcmf_err("Regulatory Set Error, %d\n", err);
4487                                goto exit;
4488                        }
4489                }
4490                if (settings->beacon_interval) {
4491                        err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD,
4492                                                    settings->beacon_interval);
4493                        if (err < 0) {
4494                                brcmf_err("Beacon Interval Set Error, %d\n",
4495                                          err);
4496                                goto exit;
4497                        }
4498                }
4499                if (settings->dtim_period) {
4500                        err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_DTIMPRD,
4501                                                    settings->dtim_period);
4502                        if (err < 0) {
4503                                brcmf_err("DTIM Interval Set Error, %d\n", err);
4504                                goto exit;
4505                        }
4506                }
4507
4508                if ((dev_role == NL80211_IFTYPE_AP) &&
4509                    ((ifp->ifidx == 0) ||
4510                     !brcmf_feat_is_enabled(ifp, BRCMF_FEAT_RSDB))) {
4511                        err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
4512                        if (err < 0) {
4513                                brcmf_err("BRCMF_C_DOWN error %d\n", err);
4514                                goto exit;
4515                        }
4516                        brcmf_fil_iovar_int_set(ifp, "apsta", 0);
4517                }
4518
4519                err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 1);
4520                if (err < 0) {
4521                        brcmf_err("SET INFRA error %d\n", err);
4522                        goto exit;
4523                }
4524        } else if (WARN_ON(supports_11d && (is_11d != ifp->vif->is_11d))) {
4525                /* Multiple-BSS should use same 11d configuration */
4526                err = -EINVAL;
4527                goto exit;
4528        }
4529
4530        /* Interface specific setup */
4531        if (dev_role == NL80211_IFTYPE_AP) {
4532                if ((brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) && (!mbss))
4533                        brcmf_fil_iovar_int_set(ifp, "mbss", 1);
4534
4535                err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 1);
4536                if (err < 0) {
4537                        brcmf_err("setting AP mode failed %d\n", err);
4538                        goto exit;
4539                }
4540                if (!mbss) {
4541                        /* Firmware 10.x requires setting channel after enabling
4542                         * AP and before bringing interface up.
4543                         */
4544                        err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
4545                        if (err < 0) {
4546                                brcmf_err("Set Channel failed: chspec=%d, %d\n",
4547                                          chanspec, err);
4548                                goto exit;
4549                        }
4550                }
4551                err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
4552                if (err < 0) {
4553                        brcmf_err("BRCMF_C_UP error (%d)\n", err);
4554                        goto exit;
4555                }
4556                /* On DOWN the firmware removes the WEP keys, reconfigure
4557                 * them if they were set.
4558                 */
4559                brcmf_cfg80211_reconfigure_wep(ifp);
4560
4561                memset(&join_params, 0, sizeof(join_params));
4562                /* join parameters starts with ssid */
4563                memcpy(&join_params.ssid_le, &ssid_le, sizeof(ssid_le));
4564                /* create softap */
4565                err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
4566                                             &join_params, sizeof(join_params));
4567                if (err < 0) {
4568                        brcmf_err("SET SSID error (%d)\n", err);
4569                        goto exit;
4570                }
4571
4572                if (settings->hidden_ssid) {
4573                        err = brcmf_fil_iovar_int_set(ifp, "closednet", 1);
4574                        if (err) {
4575                                brcmf_err("closednet error (%d)\n", err);
4576                                goto exit;
4577                        }
4578                }
4579
4580                brcmf_dbg(TRACE, "AP mode configuration complete\n");
4581        } else if (dev_role == NL80211_IFTYPE_P2P_GO) {
4582                err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
4583                if (err < 0) {
4584                        brcmf_err("Set Channel failed: chspec=%d, %d\n",
4585                                  chanspec, err);
4586                        goto exit;
4587                }
4588                err = brcmf_fil_bsscfg_data_set(ifp, "ssid", &ssid_le,
4589                                                sizeof(ssid_le));
4590                if (err < 0) {
4591                        brcmf_err("setting ssid failed %d\n", err);
4592                        goto exit;
4593                }
4594                bss_enable.bsscfgidx = cpu_to_le32(ifp->bsscfgidx);
4595                bss_enable.enable = cpu_to_le32(1);
4596                err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
4597                                               sizeof(bss_enable));
4598                if (err < 0) {
4599                        brcmf_err("bss_enable config failed %d\n", err);
4600                        goto exit;
4601                }
4602
4603                brcmf_dbg(TRACE, "GO mode configuration complete\n");
4604        } else {
4605                WARN_ON(1);
4606        }
4607
4608        brcmf_config_ap_mgmt_ie(ifp->vif, &settings->beacon);
4609        set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
4610        brcmf_net_setcarrier(ifp, true);
4611
4612exit:
4613        if ((err) && (!mbss)) {
4614                brcmf_set_mpc(ifp, 1);
4615                brcmf_configure_arp_nd_offload(ifp, true);
4616        }
4617        return err;
4618}
4619
4620static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
4621{
4622        struct brcmf_if *ifp = netdev_priv(ndev);
4623        s32 err;
4624        struct brcmf_fil_bss_enable_le bss_enable;
4625        struct brcmf_join_params join_params;
4626
4627        brcmf_dbg(TRACE, "Enter\n");
4628
4629        if (ifp->vif->wdev.iftype == NL80211_IFTYPE_AP) {
4630                /* Due to most likely deauths outstanding we sleep */
4631                /* first to make sure they get processed by fw. */
4632                msleep(400);
4633
4634                if (ifp->vif->mbss) {
4635                        err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
4636                        return err;
4637                }
4638
4639                /* First BSS doesn't get a full reset */
4640                if (ifp->bsscfgidx == 0)
4641                        brcmf_fil_iovar_int_set(ifp, "closednet", 0);
4642
4643                memset(&join_params, 0, sizeof(join_params));
4644                err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
4645                                             &join_params, sizeof(join_params));
4646                if (err < 0)
4647                        brcmf_err("SET SSID error (%d)\n", err);
4648                err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
4649                if (err < 0)
4650                        brcmf_err("BRCMF_C_DOWN error %d\n", err);
4651                err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 0);
4652                if (err < 0)
4653                        brcmf_err("setting AP mode failed %d\n", err);
4654                if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS))
4655                        brcmf_fil_iovar_int_set(ifp, "mbss", 0);
4656                brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY,
4657                                      ifp->vif->is_11d);
4658                /* Bring device back up so it can be used again */
4659                err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
4660                if (err < 0)
4661                        brcmf_err("BRCMF_C_UP error %d\n", err);
4662
4663                brcmf_vif_clear_mgmt_ies(ifp->vif);
4664        } else {
4665                bss_enable.bsscfgidx = cpu_to_le32(ifp->bsscfgidx);
4666                bss_enable.enable = cpu_to_le32(0);
4667                err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
4668                                               sizeof(bss_enable));
4669                if (err < 0)
4670                        brcmf_err("bss_enable config failed %d\n", err);
4671        }
4672        brcmf_set_mpc(ifp, 1);
4673        brcmf_configure_arp_nd_offload(ifp, true);
4674        clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
4675        brcmf_net_setcarrier(ifp, false);
4676
4677        return err;
4678}
4679
4680static s32
4681brcmf_cfg80211_change_beacon(struct wiphy *wiphy, struct net_device *ndev,
4682                             struct cfg80211_beacon_data *info)
4683{
4684        struct brcmf_if *ifp = netdev_priv(ndev);
4685        s32 err;
4686
4687        brcmf_dbg(TRACE, "Enter\n");
4688
4689        err = brcmf_config_ap_mgmt_ie(ifp->vif, info);
4690
4691        return err;
4692}
4693
4694static int
4695brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev,
4696                           struct station_del_parameters *params)
4697{
4698        struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4699        struct brcmf_scb_val_le scbval;
4700        struct brcmf_if *ifp = netdev_priv(ndev);
4701        s32 err;
4702
4703        if (!params->mac)
4704                return -EFAULT;
4705
4706        brcmf_dbg(TRACE, "Enter %pM\n", params->mac);
4707
4708        if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
4709                ifp = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp;
4710        if (!check_vif_up(ifp->vif))
4711                return -EIO;
4712
4713        memcpy(&scbval.ea, params->mac, ETH_ALEN);
4714        scbval.val = cpu_to_le32(params->reason_code);
4715        err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON,
4716                                     &scbval, sizeof(scbval));
4717        if (err)
4718                brcmf_err("SCB_DEAUTHENTICATE_FOR_REASON failed %d\n", err);
4719
4720        brcmf_dbg(TRACE, "Exit\n");
4721        return err;
4722}
4723
4724static int
4725brcmf_cfg80211_change_station(struct wiphy *wiphy, struct net_device *ndev,
4726                              const u8 *mac, struct station_parameters *params)
4727{
4728        struct brcmf_if *ifp = netdev_priv(ndev);
4729        s32 err;
4730
4731        brcmf_dbg(TRACE, "Enter, MAC %pM, mask 0x%04x set 0x%04x\n", mac,
4732                  params->sta_flags_mask, params->sta_flags_set);
4733
4734        /* Ignore all 00 MAC */
4735        if (is_zero_ether_addr(mac))
4736                return 0;
4737
4738        if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)))
4739                return 0;
4740
4741        if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
4742                err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SCB_AUTHORIZE,
4743                                             (void *)mac, ETH_ALEN);
4744        else
4745                err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SCB_DEAUTHORIZE,
4746                                             (void *)mac, ETH_ALEN);
4747        if (err < 0)
4748                brcmf_err("Setting SCB (de-)authorize failed, %d\n", err);
4749
4750        return err;
4751}
4752
4753static void
4754brcmf_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
4755                                   struct wireless_dev *wdev,
4756                                   u16 frame_type, bool reg)
4757{
4758        struct brcmf_cfg80211_vif *vif;
4759        u16 mgmt_type;
4760
4761        brcmf_dbg(TRACE, "Enter, frame_type %04x, reg=%d\n", frame_type, reg);
4762
4763        mgmt_type = (frame_type & IEEE80211_FCTL_STYPE) >> 4;
4764        vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4765        if (reg)
4766                vif->mgmt_rx_reg |= BIT(mgmt_type);
4767        else
4768                vif->mgmt_rx_reg &= ~BIT(mgmt_type);
4769}
4770
4771
4772static int
4773brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
4774                       struct cfg80211_mgmt_tx_params *params, u64 *cookie)
4775{
4776        struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4777        struct ieee80211_channel *chan = params->chan;
4778        const u8 *buf = params->buf;
4779        size_t len = params->len;
4780        const struct ieee80211_mgmt *mgmt;
4781        struct brcmf_cfg80211_vif *vif;
4782        s32 err = 0;
4783        s32 ie_offset;
4784        s32 ie_len;
4785        struct brcmf_fil_action_frame_le *action_frame;
4786        struct brcmf_fil_af_params_le *af_params;
4787        bool ack;
4788        s32 chan_nr;
4789        u32 freq;
4790
4791        brcmf_dbg(TRACE, "Enter\n");
4792
4793        *cookie = 0;
4794
4795        mgmt = (const struct ieee80211_mgmt *)buf;
4796
4797        if (!ieee80211_is_mgmt(mgmt->frame_control)) {
4798                brcmf_err("Driver only allows MGMT packet type\n");
4799                return -EPERM;
4800        }
4801
4802        vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4803
4804        if (ieee80211_is_probe_resp(mgmt->frame_control)) {
4805                /* Right now the only reason to get a probe response */
4806                /* is for p2p listen response or for p2p GO from     */
4807                /* wpa_supplicant. Unfortunately the probe is send   */
4808                /* on primary ndev, while dongle wants it on the p2p */
4809                /* vif. Since this is only reason for a probe        */
4810                /* response to be sent, the vif is taken from cfg.   */
4811                /* If ever desired to send proberesp for non p2p     */
4812                /* response then data should be checked for          */
4813                /* "DIRECT-". Note in future supplicant will take    */
4814                /* dedicated p2p wdev to do this and then this 'hack'*/
4815                /* is not needed anymore.                            */
4816                ie_offset =  DOT11_MGMT_HDR_LEN +
4817                             DOT11_BCN_PRB_FIXED_LEN;
4818                ie_len = len - ie_offset;
4819                if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif)
4820                        vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
4821                err = brcmf_vif_set_mgmt_ie(vif,
4822                                            BRCMF_VNDR_IE_PRBRSP_FLAG,
4823                                            &buf[ie_offset],
4824                                            ie_len);
4825                cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, true,
4826                                        GFP_KERNEL);
4827        } else if (ieee80211_is_action(mgmt->frame_control)) {
4828                if (len > BRCMF_FIL_ACTION_FRAME_SIZE + DOT11_MGMT_HDR_LEN) {
4829                        brcmf_err("invalid action frame length\n");
4830                        err = -EINVAL;
4831                        goto exit;
4832                }
4833                af_params = kzalloc(sizeof(*af_params), GFP_KERNEL);
4834                if (af_params == NULL) {
4835                        brcmf_err("unable to allocate frame\n");
4836                        err = -ENOMEM;
4837                        goto exit;
4838                }
4839                action_frame = &af_params->action_frame;
4840                /* Add the packet Id */
4841                action_frame->packet_id = cpu_to_le32(*cookie);
4842                /* Add BSSID */
4843                memcpy(&action_frame->da[0], &mgmt->da[0], ETH_ALEN);
4844                memcpy(&af_params->bssid[0], &mgmt->bssid[0], ETH_ALEN);
4845                /* Add the length exepted for 802.11 header  */
4846                action_frame->len = cpu_to_le16(len - DOT11_MGMT_HDR_LEN);
4847                /* Add the channel. Use the one specified as parameter if any or
4848                 * the current one (got from the firmware) otherwise
4849                 */
4850                if (chan)
4851                        freq = chan->center_freq;
4852                else
4853                        brcmf_fil_cmd_int_get(vif->ifp, BRCMF_C_GET_CHANNEL,
4854                                              &freq);
4855                chan_nr = ieee80211_frequency_to_channel(freq);
4856                af_params->channel = cpu_to_le32(chan_nr);
4857
4858                memcpy(action_frame->data, &buf[DOT11_MGMT_HDR_LEN],
4859                       le16_to_cpu(action_frame->len));
4860
4861                brcmf_dbg(TRACE, "Action frame, cookie=%lld, len=%d, freq=%d\n",
4862                          *cookie, le16_to_cpu(action_frame->len), freq);
4863
4864                ack = brcmf_p2p_send_action_frame(cfg, cfg_to_ndev(cfg),
4865                                                  af_params);
4866
4867                cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, ack,
4868                                        GFP_KERNEL);
4869                kfree(af_params);
4870        } else {
4871                brcmf_dbg(TRACE, "Unhandled, fc=%04x!!\n", mgmt->frame_control);
4872                brcmf_dbg_hex_dump(true, buf, len, "payload, len=%zu\n", len);
4873        }
4874
4875exit:
4876        return err;
4877}
4878
4879
4880static int
4881brcmf_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
4882                                        struct wireless_dev *wdev,
4883                                        u64 cookie)
4884{
4885        struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4886        struct brcmf_cfg80211_vif *vif;
4887        int err = 0;
4888
4889        brcmf_dbg(TRACE, "Enter p2p listen cancel\n");
4890
4891        vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
4892        if (vif == NULL) {
4893                brcmf_err("No p2p device available for probe response\n");
4894                err = -ENODEV;
4895                goto exit;
4896        }
4897        brcmf_p2p_cancel_remain_on_channel(vif->ifp);
4898exit:
4899        return err;
4900}
4901
4902static int brcmf_cfg80211_get_channel(struct wiphy *wiphy,
4903                                      struct wireless_dev *wdev,
4904                                      struct cfg80211_chan_def *chandef)
4905{
4906        struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4907        struct net_device *ndev = wdev->netdev;
4908        struct brcmf_if *ifp;
4909        struct brcmu_chan ch;
4910        enum nl80211_band band = 0;
4911        enum nl80211_chan_width width = 0;
4912        u32 chanspec;
4913        int freq, err;
4914
4915        if (!ndev)
4916                return -ENODEV;
4917        ifp = netdev_priv(ndev);
4918
4919        err = brcmf_fil_iovar_int_get(ifp, "chanspec", &chanspec);
4920        if (err) {
4921                brcmf_err("chanspec failed (%d)\n", err);
4922                return err;
4923        }
4924
4925        ch.chspec = chanspec;
4926        cfg->d11inf.decchspec(&ch);
4927
4928        switch (ch.band) {
4929        case BRCMU_CHAN_BAND_2G:
4930                band = NL80211_BAND_2GHZ;
4931                break;
4932        case BRCMU_CHAN_BAND_5G:
4933                band = NL80211_BAND_5GHZ;
4934                break;
4935        }
4936
4937        switch (ch.bw) {
4938        case BRCMU_CHAN_BW_80:
4939                width = NL80211_CHAN_WIDTH_80;
4940                break;
4941        case BRCMU_CHAN_BW_40:
4942                width = NL80211_CHAN_WIDTH_40;
4943                break;
4944        case BRCMU_CHAN_BW_20:
4945                width = NL80211_CHAN_WIDTH_20;
4946                break;
4947        case BRCMU_CHAN_BW_80P80:
4948                width = NL80211_CHAN_WIDTH_80P80;
4949                break;
4950        case BRCMU_CHAN_BW_160:
4951                width = NL80211_CHAN_WIDTH_160;
4952                break;
4953        }
4954
4955        freq = ieee80211_channel_to_frequency(ch.control_ch_num, band);
4956        chandef->chan = ieee80211_get_channel(wiphy, freq);
4957        chandef->width = width;
4958        chandef->center_freq1 = ieee80211_channel_to_frequency(ch.chnum, band);
4959        chandef->center_freq2 = 0;
4960
4961        return 0;
4962}
4963
4964static int brcmf_cfg80211_crit_proto_start(struct wiphy *wiphy,
4965                                           struct wireless_dev *wdev,
4966                                           enum nl80211_crit_proto_id proto,
4967                                           u16 duration)
4968{
4969        struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4970        struct brcmf_cfg80211_vif *vif;
4971
4972        vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4973
4974        /* only DHCP support for now */
4975        if (proto != NL80211_CRIT_PROTO_DHCP)
4976                return -EINVAL;
4977
4978        /* suppress and abort scanning */
4979        set_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
4980        brcmf_abort_scanning(cfg);
4981
4982        return brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_DISABLED, duration);
4983}
4984
4985static void brcmf_cfg80211_crit_proto_stop(struct wiphy *wiphy,
4986                                           struct wireless_dev *wdev)
4987{
4988        struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4989        struct brcmf_cfg80211_vif *vif;
4990
4991        vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4992
4993        brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_ENABLED, 0);
4994        clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
4995}
4996
4997static s32
4998brcmf_notify_tdls_peer_event(struct brcmf_if *ifp,
4999                             const struct brcmf_event_msg *e, void *data)
5000{
5001        switch (e->reason) {
5002        case BRCMF_E_REASON_TDLS_PEER_DISCOVERED:
5003                brcmf_dbg(TRACE, "TDLS Peer Discovered\n");
5004                break;
5005        case BRCMF_E_REASON_TDLS_PEER_CONNECTED:
5006                brcmf_dbg(TRACE, "TDLS Peer Connected\n");
5007                brcmf_proto_add_tdls_peer(ifp->drvr, ifp->ifidx, (u8 *)e->addr);
5008                break;
5009        case BRCMF_E_REASON_TDLS_PEER_DISCONNECTED:
5010                brcmf_dbg(TRACE, "TDLS Peer Disconnected\n");
5011                brcmf_proto_delete_peer(ifp->drvr, ifp->ifidx, (u8 *)e->addr);
5012                break;
5013        }
5014
5015        return 0;
5016}
5017
5018static int brcmf_convert_nl80211_tdls_oper(enum nl80211_tdls_operation oper)
5019{
5020        int ret;
5021
5022        switch (oper) {
5023        case NL80211_TDLS_DISCOVERY_REQ:
5024                ret = BRCMF_TDLS_MANUAL_EP_DISCOVERY;
5025                break;
5026        case NL80211_TDLS_SETUP:
5027                ret = BRCMF_TDLS_MANUAL_EP_CREATE;
5028                break;
5029        case NL80211_TDLS_TEARDOWN:
5030                ret = BRCMF_TDLS_MANUAL_EP_DELETE;
5031                break;
5032        default:
5033                brcmf_err("unsupported operation: %d\n", oper);
5034                ret = -EOPNOTSUPP;
5035        }
5036        return ret;
5037}
5038
5039static int brcmf_cfg80211_tdls_oper(struct wiphy *wiphy,
5040                                    struct net_device *ndev, const u8 *peer,
5041                                    enum nl80211_tdls_operation oper)
5042{
5043        struct brcmf_if *ifp;
5044        struct brcmf_tdls_iovar_le info;
5045        int ret = 0;
5046
5047        ret = brcmf_convert_nl80211_tdls_oper(oper);
5048        if (ret < 0)
5049                return ret;
5050
5051        ifp = netdev_priv(ndev);
5052        memset(&info, 0, sizeof(info));
5053        info.mode = (u8)ret;
5054        if (peer)
5055                memcpy(info.ea, peer, ETH_ALEN);
5056
5057        ret = brcmf_fil_iovar_data_set(ifp, "tdls_endpoint",
5058                                       &info, sizeof(info));
5059        if (ret < 0)
5060                brcmf_err("tdls_endpoint iovar failed: ret=%d\n", ret);
5061
5062        return ret;
5063}
5064
5065static int
5066brcmf_cfg80211_update_conn_params(struct wiphy *wiphy,
5067                                  struct net_device *ndev,
5068                                  struct cfg80211_connect_params *sme,
5069                                  u32 changed)
5070{
5071        struct brcmf_if *ifp;
5072        int err;
5073
5074        if (!(changed & UPDATE_ASSOC_IES))
5075                return 0;
5076
5077        ifp = netdev_priv(ndev);
5078        err = brcmf_vif_set_mgmt_ie(ifp->vif, BRCMF_VNDR_IE_ASSOCREQ_FLAG,
5079                                    sme->ie, sme->ie_len);
5080        if (err)
5081                brcmf_err("Set Assoc REQ IE Failed\n");
5082        else
5083                brcmf_dbg(TRACE, "Applied Vndr IEs for Assoc request\n");
5084
5085        return err;
5086}
5087
5088#ifdef CONFIG_PM
5089static int
5090brcmf_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *ndev,
5091                              struct cfg80211_gtk_rekey_data *gtk)
5092{
5093        struct brcmf_if *ifp = netdev_priv(ndev);
5094        struct brcmf_gtk_keyinfo_le gtk_le;
5095        int ret;
5096
5097        brcmf_dbg(TRACE, "Enter, bssidx=%d\n", ifp->bsscfgidx);
5098
5099        memcpy(gtk_le.kck, gtk->kck, sizeof(gtk_le.kck));
5100        memcpy(gtk_le.kek, gtk->kek, sizeof(gtk_le.kek));
5101        memcpy(gtk_le.replay_counter, gtk->replay_ctr,
5102               sizeof(gtk_le.replay_counter));
5103
5104        ret = brcmf_fil_iovar_data_set(ifp, "gtk_key_info", &gtk_le,
5105                                       sizeof(gtk_le));
5106        if (ret < 0)
5107                brcmf_err("gtk_key_info iovar failed: ret=%d\n", ret);
5108
5109        return ret;
5110}
5111#endif
5112
5113static int brcmf_cfg80211_set_pmk(struct wiphy *wiphy, struct net_device *dev,
5114                                  const struct cfg80211_pmk_conf *conf)
5115{
5116        struct brcmf_if *ifp;
5117
5118        brcmf_dbg(TRACE, "enter\n");
5119
5120        /* expect using firmware supplicant for 1X */
5121        ifp = netdev_priv(dev);
5122        if (WARN_ON(ifp->vif->profile.use_fwsup != BRCMF_PROFILE_FWSUP_1X))
5123                return -EINVAL;
5124
5125        if (conf->pmk_len > BRCMF_WSEC_MAX_PSK_LEN)
5126                return -ERANGE;
5127
5128        return brcmf_set_pmk(ifp, conf->pmk, conf->pmk_len);
5129}
5130
5131static int brcmf_cfg80211_del_pmk(struct wiphy *wiphy, struct net_device *dev,
5132                                  const u8 *aa)
5133{
5134        struct brcmf_if *ifp;
5135
5136        brcmf_dbg(TRACE, "enter\n");
5137        ifp = netdev_priv(dev);
5138        if (WARN_ON(ifp->vif->profile.use_fwsup != BRCMF_PROFILE_FWSUP_1X))
5139                return -EINVAL;
5140
5141        return brcmf_set_pmk(ifp, NULL, 0);
5142}
5143
5144static struct cfg80211_ops brcmf_cfg80211_ops = {
5145        .add_virtual_intf = brcmf_cfg80211_add_iface,
5146        .del_virtual_intf = brcmf_cfg80211_del_iface,
5147        .change_virtual_intf = brcmf_cfg80211_change_iface,
5148        .scan = brcmf_cfg80211_scan,
5149        .set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
5150        .join_ibss = brcmf_cfg80211_join_ibss,
5151        .leave_ibss = brcmf_cfg80211_leave_ibss,
5152        .get_station = brcmf_cfg80211_get_station,
5153        .dump_station = brcmf_cfg80211_dump_station,
5154        .set_tx_power = brcmf_cfg80211_set_tx_power,
5155        .get_tx_power = brcmf_cfg80211_get_tx_power,
5156        .add_key = brcmf_cfg80211_add_key,
5157        .del_key = brcmf_cfg80211_del_key,
5158        .get_key = brcmf_cfg80211_get_key,
5159        .set_default_key = brcmf_cfg80211_config_default_key,
5160        .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
5161        .set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
5162        .connect = brcmf_cfg80211_connect,
5163        .disconnect = brcmf_cfg80211_disconnect,
5164        .suspend = brcmf_cfg80211_suspend,
5165        .resume = brcmf_cfg80211_resume,
5166        .set_pmksa = brcmf_cfg80211_set_pmksa,
5167        .del_pmksa = brcmf_cfg80211_del_pmksa,
5168        .flush_pmksa = brcmf_cfg80211_flush_pmksa,
5169        .start_ap = brcmf_cfg80211_start_ap,
5170        .stop_ap = brcmf_cfg80211_stop_ap,
5171        .change_beacon = brcmf_cfg80211_change_beacon,
5172        .del_station = brcmf_cfg80211_del_station,
5173        .change_station = brcmf_cfg80211_change_station,
5174        .sched_scan_start = brcmf_cfg80211_sched_scan_start,
5175        .sched_scan_stop = brcmf_cfg80211_sched_scan_stop,
5176        .mgmt_frame_register = brcmf_cfg80211_mgmt_frame_register,
5177        .mgmt_tx = brcmf_cfg80211_mgmt_tx,
5178        .remain_on_channel = brcmf_p2p_remain_on_channel,
5179        .cancel_remain_on_channel = brcmf_cfg80211_cancel_remain_on_channel,
5180        .get_channel = brcmf_cfg80211_get_channel,
5181        .start_p2p_device = brcmf_p2p_start_device,
5182        .stop_p2p_device = brcmf_p2p_stop_device,
5183        .crit_proto_start = brcmf_cfg80211_crit_proto_start,
5184        .crit_proto_stop = brcmf_cfg80211_crit_proto_stop,
5185        .tdls_oper = brcmf_cfg80211_tdls_oper,
5186        .update_connect_params = brcmf_cfg80211_update_conn_params,
5187        .set_pmk = brcmf_cfg80211_set_pmk,
5188        .del_pmk = brcmf_cfg80211_del_pmk,
5189};
5190
5191struct cfg80211_ops *brcmf_cfg80211_get_ops(void)
5192{
5193        return kmemdup(&brcmf_cfg80211_ops, sizeof(brcmf_cfg80211_ops),
5194                       GFP_KERNEL);
5195}
5196
5197struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
5198                                           enum nl80211_iftype type)
5199{
5200        struct brcmf_cfg80211_vif *vif_walk;
5201        struct brcmf_cfg80211_vif *vif;
5202        bool mbss;
5203
5204        brcmf_dbg(TRACE, "allocating virtual interface (size=%zu)\n",
5205                  sizeof(*vif));
5206        vif = kzalloc(sizeof(*vif), GFP_KERNEL);
5207        if (!vif)
5208                return ERR_PTR(-ENOMEM);
5209
5210        vif->wdev.wiphy = cfg->wiphy;
5211        vif->wdev.iftype = type;
5212
5213        brcmf_init_prof(&vif->profile);
5214
5215        if (type == NL80211_IFTYPE_AP) {
5216                mbss = false;
5217                list_for_each_entry(vif_walk, &cfg->vif_list, list) {
5218                        if (vif_walk->wdev.iftype == NL80211_IFTYPE_AP) {
5219                                mbss = true;
5220                                break;
5221                        }
5222                }
5223                vif->mbss = mbss;
5224        }
5225
5226        list_add_tail(&vif->list, &cfg->vif_list);
5227        return vif;
5228}
5229
5230void brcmf_free_vif(struct brcmf_cfg80211_vif *vif)
5231{
5232        list_del(&vif->list);
5233        kfree(vif);
5234}
5235
5236void brcmf_cfg80211_free_netdev(struct net_device *ndev)
5237{
5238        struct brcmf_cfg80211_vif *vif;
5239        struct brcmf_if *ifp;
5240
5241        ifp = netdev_priv(ndev);
5242        vif = ifp->vif;
5243
5244        if (vif)
5245                brcmf_free_vif(vif);
5246}
5247
5248static bool brcmf_is_linkup(struct brcmf_cfg80211_vif *vif,
5249                            const struct brcmf_event_msg *e)
5250{
5251        u32 event = e->event_code;
5252        u32 status = e->status;
5253
5254        if (vif->profile.use_fwsup == BRCMF_PROFILE_FWSUP_PSK &&
5255            event == BRCMF_E_PSK_SUP &&
5256            status == BRCMF_E_STATUS_FWSUP_COMPLETED)
5257                set_bit(BRCMF_VIF_STATUS_EAP_SUCCESS, &vif->sme_state);
5258        if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
5259                brcmf_dbg(CONN, "Processing set ssid\n");
5260                memcpy(vif->profile.bssid, e->addr, ETH_ALEN);
5261                if (vif->profile.use_fwsup != BRCMF_PROFILE_FWSUP_PSK)
5262                        return true;
5263
5264                set_bit(BRCMF_VIF_STATUS_ASSOC_SUCCESS, &vif->sme_state);
5265        }
5266
5267        if (test_bit(BRCMF_VIF_STATUS_EAP_SUCCESS, &vif->sme_state) &&
5268            test_bit(BRCMF_VIF_STATUS_ASSOC_SUCCESS, &vif->sme_state)) {
5269                clear_bit(BRCMF_VIF_STATUS_EAP_SUCCESS, &vif->sme_state);
5270                clear_bit(BRCMF_VIF_STATUS_ASSOC_SUCCESS, &vif->sme_state);
5271                return true;
5272        }
5273        return false;
5274}
5275
5276static bool brcmf_is_linkdown(const struct brcmf_event_msg *e)
5277{
5278        u32 event = e->event_code;
5279        u16 flags = e->flags;
5280
5281        if ((event == BRCMF_E_DEAUTH) || (event == BRCMF_E_DEAUTH_IND) ||
5282            (event == BRCMF_E_DISASSOC_IND) ||
5283            ((event == BRCMF_E_LINK) && (!(flags & BRCMF_EVENT_MSG_LINK)))) {
5284                brcmf_dbg(CONN, "Processing link down\n");
5285                return true;
5286        }
5287        return false;
5288}
5289
5290static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info *cfg,
5291                               const struct brcmf_event_msg *e)
5292{
5293        u32 event = e->event_code;
5294        u32 status = e->status;
5295
5296        if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
5297                brcmf_dbg(CONN, "Processing Link %s & no network found\n",
5298                          e->flags & BRCMF_EVENT_MSG_LINK ? "up" : "down");
5299                return true;
5300        }
5301
5302        if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
5303                brcmf_dbg(CONN, "Processing connecting & no network found\n");
5304                return true;
5305        }
5306
5307        if (event == BRCMF_E_PSK_SUP &&
5308            status != BRCMF_E_STATUS_FWSUP_COMPLETED) {
5309                brcmf_dbg(CONN, "Processing failed supplicant state: %u\n",
5310                          status);
5311                return true;
5312        }
5313
5314        return false;
5315}
5316
5317static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info *cfg)
5318{
5319        struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
5320
5321        kfree(conn_info->req_ie);
5322        conn_info->req_ie = NULL;
5323        conn_info->req_ie_len = 0;
5324        kfree(conn_info->resp_ie);
5325        conn_info->resp_ie = NULL;
5326        conn_info->resp_ie_len = 0;
5327}
5328
5329static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg,
5330                               struct brcmf_if *ifp)
5331{
5332        struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
5333        struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
5334        u32 req_len;
5335        u32 resp_len;
5336        s32 err = 0;
5337
5338        brcmf_clear_assoc_ies(cfg);
5339
5340        err = brcmf_fil_iovar_data_get(ifp, "assoc_info",
5341                                       cfg->extra_buf, WL_ASSOC_INFO_MAX);
5342        if (err) {
5343                brcmf_err("could not get assoc info (%d)\n", err);
5344                return err;
5345        }
5346        assoc_info =
5347                (struct brcmf_cfg80211_assoc_ielen_le *)cfg->extra_buf;
5348        req_len = le32_to_cpu(assoc_info->req_len);
5349        resp_len = le32_to_cpu(assoc_info->resp_len);
5350        if (req_len) {
5351                err = brcmf_fil_iovar_data_get(ifp, "assoc_req_ies",
5352                                               cfg->extra_buf,
5353                                               WL_ASSOC_INFO_MAX);
5354                if (err) {
5355                        brcmf_err("could not get assoc req (%d)\n", err);
5356                        return err;
5357                }
5358                conn_info->req_ie_len = req_len;
5359                conn_info->req_ie =
5360                    kmemdup(cfg->extra_buf, conn_info->req_ie_len,
5361                            GFP_KERNEL);
5362        } else {
5363                conn_info->req_ie_len = 0;
5364                conn_info->req_ie = NULL;
5365        }
5366        if (resp_len) {
5367                err = brcmf_fil_iovar_data_get(ifp, "assoc_resp_ies",
5368                                               cfg->extra_buf,
5369                                               WL_ASSOC_INFO_MAX);
5370                if (err) {
5371                        brcmf_err("could not get assoc resp (%d)\n", err);
5372                        return err;
5373                }
5374                conn_info->resp_ie_len = resp_len;
5375                conn_info->resp_ie =
5376                    kmemdup(cfg->extra_buf, conn_info->resp_ie_len,
5377                            GFP_KERNEL);
5378        } else {
5379                conn_info->resp_ie_len = 0;
5380                conn_info->resp_ie = NULL;
5381        }
5382        brcmf_dbg(CONN, "req len (%d) resp len (%d)\n",
5383                  conn_info->req_ie_len, conn_info->resp_ie_len);
5384
5385        return err;
5386}
5387
5388static s32
5389brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
5390                       struct net_device *ndev,
5391                       const struct brcmf_event_msg *e)
5392{
5393        struct brcmf_if *ifp = netdev_priv(ndev);
5394        struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
5395        struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
5396        struct wiphy *wiphy = cfg_to_wiphy(cfg);
5397        struct ieee80211_channel *notify_channel = NULL;
5398        struct ieee80211_supported_band *band;
5399        struct brcmf_bss_info_le *bi;
5400        struct brcmu_chan ch;
5401        struct cfg80211_roam_info roam_info = {};
5402        u32 freq;
5403        s32 err = 0;
5404        u8 *buf;
5405
5406        brcmf_dbg(TRACE, "Enter\n");
5407
5408        brcmf_get_assoc_ies(cfg, ifp);
5409        memcpy(profile->bssid, e->addr, ETH_ALEN);
5410        brcmf_update_bss_info(cfg, ifp);
5411
5412        buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
5413        if (buf == NULL) {
5414                err = -ENOMEM;
5415                goto done;
5416        }
5417
5418        /* data sent to dongle has to be little endian */
5419        *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
5420        err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
5421                                     buf, WL_BSS_INFO_MAX);
5422
5423        if (err)
5424                goto done;
5425
5426        bi = (struct brcmf_bss_info_le *)(buf + 4);
5427        ch.chspec = le16_to_cpu(bi->chanspec);
5428        cfg->d11inf.decchspec(&ch);
5429
5430        if (ch.band == BRCMU_CHAN_BAND_2G)
5431                band = wiphy->bands[NL80211_BAND_2GHZ];
5432        else
5433                band = wiphy->bands[NL80211_BAND_5GHZ];
5434
5435        freq = ieee80211_channel_to_frequency(ch.control_ch_num, band->band);
5436        notify_channel = ieee80211_get_channel(wiphy, freq);
5437
5438done:
5439        kfree(buf);
5440
5441        roam_info.channel = notify_channel;
5442        roam_info.bssid = profile->bssid;
5443        roam_info.req_ie = conn_info->req_ie;
5444        roam_info.req_ie_len = conn_info->req_ie_len;
5445        roam_info.resp_ie = conn_info->resp_ie;
5446        roam_info.resp_ie_len = conn_info->resp_ie_len;
5447
5448        cfg80211_roamed(ndev, &roam_info, GFP_KERNEL);
5449        brcmf_dbg(CONN, "Report roaming result\n");
5450
5451        set_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
5452        brcmf_dbg(TRACE, "Exit\n");
5453        return err;
5454}
5455
5456static s32
5457brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg,
5458                       struct net_device *ndev, const struct brcmf_event_msg *e,
5459                       bool completed)
5460{
5461        struct brcmf_if *ifp = netdev_priv(ndev);
5462        struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
5463        struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
5464        struct cfg80211_connect_resp_params conn_params;
5465
5466        brcmf_dbg(TRACE, "Enter\n");
5467
5468        if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTING,
5469                               &ifp->vif->sme_state)) {
5470                memset(&conn_params, 0, sizeof(conn_params));
5471                if (completed) {
5472                        brcmf_get_assoc_ies(cfg, ifp);
5473                        brcmf_update_bss_info(cfg, ifp);
5474                        set_bit(BRCMF_VIF_STATUS_CONNECTED,
5475                                &ifp->vif->sme_state);
5476                        conn_params.status = WLAN_STATUS_SUCCESS;
5477                } else {
5478                        conn_params.status = WLAN_STATUS_AUTH_TIMEOUT;
5479                }
5480                conn_params.bssid = profile->bssid;
5481                conn_params.req_ie = conn_info->req_ie;
5482                conn_params.req_ie_len = conn_info->req_ie_len;
5483                conn_params.resp_ie = conn_info->resp_ie;
5484                conn_params.resp_ie_len = conn_info->resp_ie_len;
5485                cfg80211_connect_done(ndev, &conn_params, GFP_KERNEL);
5486                brcmf_dbg(CONN, "Report connect result - connection %s\n",
5487                          completed ? "succeeded" : "failed");
5488        }
5489        brcmf_dbg(TRACE, "Exit\n");
5490        return 0;
5491}
5492
5493static s32
5494brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg,
5495                               struct net_device *ndev,
5496                               const struct brcmf_event_msg *e, void *data)
5497{
5498        static int generation;
5499        u32 event = e->event_code;
5500        u32 reason = e->reason;
5501        struct station_info sinfo;
5502
5503        brcmf_dbg(CONN, "event %s (%u), reason %d\n",
5504                  brcmf_fweh_event_name(event), event, reason);
5505        if (event == BRCMF_E_LINK && reason == BRCMF_E_REASON_LINK_BSSCFG_DIS &&
5506            ndev != cfg_to_ndev(cfg)) {
5507                brcmf_dbg(CONN, "AP mode link down\n");
5508                complete(&cfg->vif_disabled);
5509                return 0;
5510        }
5511
5512        if (((event == BRCMF_E_ASSOC_IND) || (event == BRCMF_E_REASSOC_IND)) &&
5513            (reason == BRCMF_E_STATUS_SUCCESS)) {
5514                memset(&sinfo, 0, sizeof(sinfo));
5515                if (!data) {
5516                        brcmf_err("No IEs present in ASSOC/REASSOC_IND");
5517                        return -EINVAL;
5518                }
5519                sinfo.assoc_req_ies = data;
5520                sinfo.assoc_req_ies_len = e->datalen;
5521                generation++;
5522                sinfo.generation = generation;
5523                cfg80211_new_sta(ndev, e->addr, &sinfo, GFP_KERNEL);
5524        } else if ((event == BRCMF_E_DISASSOC_IND) ||
5525                   (event == BRCMF_E_DEAUTH_IND) ||
5526                   (event == BRCMF_E_DEAUTH)) {
5527                cfg80211_del_sta(ndev, e->addr, GFP_KERNEL);
5528        }
5529        return 0;
5530}
5531
5532static s32
5533brcmf_notify_connect_status(struct brcmf_if *ifp,
5534                            const struct brcmf_event_msg *e, void *data)
5535{
5536        struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5537        struct net_device *ndev = ifp->ndev;
5538        struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
5539        struct ieee80211_channel *chan;
5540        s32 err = 0;
5541
5542        if ((e->event_code == BRCMF_E_DEAUTH) ||
5543            (e->event_code == BRCMF_E_DEAUTH_IND) ||
5544            (e->event_code == BRCMF_E_DISASSOC_IND) ||
5545            ((e->event_code == BRCMF_E_LINK) && (!e->flags))) {
5546                brcmf_proto_delete_peer(ifp->drvr, ifp->ifidx, (u8 *)e->addr);
5547        }
5548
5549        if (brcmf_is_apmode(ifp->vif)) {
5550                err = brcmf_notify_connect_status_ap(cfg, ndev, e, data);
5551        } else if (brcmf_is_linkup(ifp->vif, e)) {
5552                brcmf_dbg(CONN, "Linkup\n");
5553                if (brcmf_is_ibssmode(ifp->vif)) {
5554                        brcmf_inform_ibss(cfg, ndev, e->addr);
5555                        chan = ieee80211_get_channel(cfg->wiphy, cfg->channel);
5556                        memcpy(profile->bssid, e->addr, ETH_ALEN);
5557                        cfg80211_ibss_joined(ndev, e->addr, chan, GFP_KERNEL);
5558                        clear_bit(BRCMF_VIF_STATUS_CONNECTING,
5559                                  &ifp->vif->sme_state);
5560                        set_bit(BRCMF_VIF_STATUS_CONNECTED,
5561                                &ifp->vif->sme_state);
5562                } else
5563                        brcmf_bss_connect_done(cfg, ndev, e, true);
5564                brcmf_net_setcarrier(ifp, true);
5565        } else if (brcmf_is_linkdown(e)) {
5566                brcmf_dbg(CONN, "Linkdown\n");
5567                if (!brcmf_is_ibssmode(ifp->vif)) {
5568                        brcmf_bss_connect_done(cfg, ndev, e, false);
5569                        brcmf_link_down(ifp->vif,
5570                                        brcmf_map_fw_linkdown_reason(e));
5571                        brcmf_init_prof(ndev_to_prof(ndev));
5572                        if (ndev != cfg_to_ndev(cfg))
5573                                complete(&cfg->vif_disabled);
5574                        brcmf_net_setcarrier(ifp, false);
5575                }
5576        } else if (brcmf_is_nonetwork(cfg, e)) {
5577                if (brcmf_is_ibssmode(ifp->vif))
5578                        clear_bit(BRCMF_VIF_STATUS_CONNECTING,
5579                                  &ifp->vif->sme_state);
5580                else
5581                        brcmf_bss_connect_done(cfg, ndev, e, false);
5582        }
5583
5584        return err;
5585}
5586
5587static s32
5588brcmf_notify_roaming_status(struct brcmf_if *ifp,
5589                            const struct brcmf_event_msg *e, void *data)
5590{
5591        struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5592        u32 event = e->event_code;
5593        u32 status = e->status;
5594
5595        if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
5596                if (test_bit(BRCMF_VIF_STATUS_CONNECTED,
5597                             &ifp->vif->sme_state)) {
5598                        brcmf_bss_roaming_done(cfg, ifp->ndev, e);
5599                } else {
5600                        brcmf_bss_connect_done(cfg, ifp->ndev, e, true);
5601                        brcmf_net_setcarrier(ifp, true);
5602                }
5603        }
5604
5605        return 0;
5606}
5607
5608static s32
5609brcmf_notify_mic_status(struct brcmf_if *ifp,
5610                        const struct brcmf_event_msg *e, void *data)
5611{
5612        u16 flags = e->flags;
5613        enum nl80211_key_type key_type;
5614
5615        if (flags & BRCMF_EVENT_MSG_GROUP)
5616                key_type = NL80211_KEYTYPE_GROUP;
5617        else
5618                key_type = NL80211_KEYTYPE_PAIRWISE;
5619
5620        cfg80211_michael_mic_failure(ifp->ndev, (u8 *)&e->addr, key_type, -1,
5621                                     NULL, GFP_KERNEL);
5622
5623        return 0;
5624}
5625
5626static s32 brcmf_notify_vif_event(struct brcmf_if *ifp,
5627                                  const struct brcmf_event_msg *e, void *data)
5628{
5629        struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5630        struct brcmf_if_event *ifevent = (struct brcmf_if_event *)data;
5631        struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
5632        struct brcmf_cfg80211_vif *vif;
5633
5634        brcmf_dbg(TRACE, "Enter: action %u flags %u ifidx %u bsscfgidx %u\n",
5635                  ifevent->action, ifevent->flags, ifevent->ifidx,
5636                  ifevent->bsscfgidx);
5637
5638        spin_lock(&event->vif_event_lock);
5639        event->action = ifevent->action;
5640        vif = event->vif;
5641
5642        switch (ifevent->action) {
5643        case BRCMF_E_IF_ADD:
5644                /* waiting process may have timed out */
5645                if (!cfg->vif_event.vif) {
5646                        spin_unlock(&event->vif_event_lock);
5647                        return -EBADF;
5648                }
5649
5650                ifp->vif = vif;
5651                vif->ifp = ifp;
5652                if (ifp->ndev) {
5653                        vif->wdev.netdev = ifp->ndev;
5654                        ifp->ndev->ieee80211_ptr = &vif->wdev;
5655                        SET_NETDEV_DEV(ifp->ndev, wiphy_dev(cfg->wiphy));
5656                }
5657                spin_unlock(&event->vif_event_lock);
5658                wake_up(&event->vif_wq);
5659                return 0;
5660
5661        case BRCMF_E_IF_DEL:
5662                spin_unlock(&event->vif_event_lock);
5663                /* event may not be upon user request */
5664                if (brcmf_cfg80211_vif_event_armed(cfg))
5665                        wake_up(&event->vif_wq);
5666                return 0;
5667
5668        case BRCMF_E_IF_CHANGE:
5669                spin_unlock(&event->vif_event_lock);
5670                wake_up(&event->vif_wq);
5671                return 0;
5672
5673        default:
5674                spin_unlock(&event->vif_event_lock);
5675                break;
5676        }
5677        return -EINVAL;
5678}
5679
5680static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
5681{
5682        conf->frag_threshold = (u32)-1;
5683        conf->rts_threshold = (u32)-1;
5684        conf->retry_short = (u32)-1;
5685        conf->retry_long = (u32)-1;
5686}
5687
5688static void brcmf_register_event_handlers(struct brcmf_cfg80211_info *cfg)
5689{
5690        brcmf_fweh_register(cfg->pub, BRCMF_E_LINK,
5691                            brcmf_notify_connect_status);
5692        brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH_IND,
5693                            brcmf_notify_connect_status);
5694        brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH,
5695                            brcmf_notify_connect_status);
5696        brcmf_fweh_register(cfg->pub, BRCMF_E_DISASSOC_IND,
5697                            brcmf_notify_connect_status);
5698        brcmf_fweh_register(cfg->pub, BRCMF_E_ASSOC_IND,
5699                            brcmf_notify_connect_status);
5700        brcmf_fweh_register(cfg->pub, BRCMF_E_REASSOC_IND,
5701                            brcmf_notify_connect_status);
5702        brcmf_fweh_register(cfg->pub, BRCMF_E_ROAM,
5703                            brcmf_notify_roaming_status);
5704        brcmf_fweh_register(cfg->pub, BRCMF_E_MIC_ERROR,
5705                            brcmf_notify_mic_status);
5706        brcmf_fweh_register(cfg->pub, BRCMF_E_SET_SSID,
5707                            brcmf_notify_connect_status);
5708        brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
5709                            brcmf_notify_sched_scan_results);
5710        brcmf_fweh_register(cfg->pub, BRCMF_E_IF,
5711                            brcmf_notify_vif_event);
5712        brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_PROBEREQ_MSG,
5713                            brcmf_p2p_notify_rx_mgmt_p2p_probereq);
5714        brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_DISC_LISTEN_COMPLETE,
5715                            brcmf_p2p_notify_listen_complete);
5716        brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_RX,
5717                            brcmf_p2p_notify_action_frame_rx);
5718        brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_COMPLETE,
5719                            brcmf_p2p_notify_action_tx_complete);
5720        brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE,
5721                            brcmf_p2p_notify_action_tx_complete);
5722        brcmf_fweh_register(cfg->pub, BRCMF_E_PSK_SUP,
5723                            brcmf_notify_connect_status);
5724}
5725
5726static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg)
5727{
5728        kfree(cfg->conf);
5729        cfg->conf = NULL;
5730        kfree(cfg->extra_buf);
5731        cfg->extra_buf = NULL;
5732        kfree(cfg->wowl.nd);
5733        cfg->wowl.nd = NULL;
5734        kfree(cfg->wowl.nd_info);
5735        cfg->wowl.nd_info = NULL;
5736        kfree(cfg->escan_info.escan_buf);
5737        cfg->escan_info.escan_buf = NULL;
5738}
5739
5740static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg)
5741{
5742        cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL);
5743        if (!cfg->conf)
5744                goto init_priv_mem_out;
5745        cfg->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
5746        if (!cfg->extra_buf)
5747                goto init_priv_mem_out;
5748        cfg->wowl.nd = kzalloc(sizeof(*cfg->wowl.nd) + sizeof(u32), GFP_KERNEL);
5749        if (!cfg->wowl.nd)
5750                goto init_priv_mem_out;
5751        cfg->wowl.nd_info = kzalloc(sizeof(*cfg->wowl.nd_info) +
5752                                    sizeof(struct cfg80211_wowlan_nd_match *),
5753                                    GFP_KERNEL);
5754        if (!cfg->wowl.nd_info)
5755                goto init_priv_mem_out;
5756        cfg->escan_info.escan_buf = kzalloc(BRCMF_ESCAN_BUF_SIZE, GFP_KERNEL);
5757        if (!cfg->escan_info.escan_buf)
5758                goto init_priv_mem_out;
5759
5760        return 0;
5761
5762init_priv_mem_out:
5763        brcmf_deinit_priv_mem(cfg);
5764
5765        return -ENOMEM;
5766}
5767
5768static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg)
5769{
5770        s32 err = 0;
5771
5772        cfg->scan_request = NULL;
5773        cfg->pwr_save = true;
5774        cfg->dongle_up = false;         /* dongle is not up yet */
5775        err = brcmf_init_priv_mem(cfg);
5776        if (err)
5777                return err;
5778        brcmf_register_event_handlers(cfg);
5779        mutex_init(&cfg->usr_sync);
5780        brcmf_init_escan(cfg);
5781        brcmf_init_conf(cfg->conf);
5782        init_completion(&cfg->vif_disabled);
5783        return err;
5784}
5785
5786static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg)
5787{
5788        cfg->dongle_up = false; /* dongle down */
5789        brcmf_abort_scanning(cfg);
5790        brcmf_deinit_priv_mem(cfg);
5791}
5792
5793static void init_vif_event(struct brcmf_cfg80211_vif_event *event)
5794{
5795        init_waitqueue_head(&event->vif_wq);
5796        spin_lock_init(&event->vif_event_lock);
5797}
5798
5799static s32 brcmf_dongle_roam(struct brcmf_if *ifp)
5800{
5801        s32 err;
5802        u32 bcn_timeout;
5803        __le32 roamtrigger[2];
5804        __le32 roam_delta[2];
5805
5806        /* Configure beacon timeout value based upon roaming setting */
5807        if (ifp->drvr->settings->roamoff)
5808                bcn_timeout = BRCMF_DEFAULT_BCN_TIMEOUT_ROAM_OFF;
5809        else
5810                bcn_timeout = BRCMF_DEFAULT_BCN_TIMEOUT_ROAM_ON;
5811        err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout", bcn_timeout);
5812        if (err) {
5813                brcmf_err("bcn_timeout error (%d)\n", err);
5814                goto roam_setup_done;
5815        }
5816
5817        /* Enable/Disable built-in roaming to allow supplicant to take care of
5818         * roaming.
5819         */
5820        brcmf_dbg(INFO, "Internal Roaming = %s\n",
5821                  ifp->drvr->settings->roamoff ? "Off" : "On");
5822        err = brcmf_fil_iovar_int_set(ifp, "roam_off",
5823                                      ifp->drvr->settings->roamoff);
5824        if (err) {
5825                brcmf_err("roam_off error (%d)\n", err);
5826                goto roam_setup_done;
5827        }
5828
5829        roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL);
5830        roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL);
5831        err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_TRIGGER,
5832                                     (void *)roamtrigger, sizeof(roamtrigger));
5833        if (err) {
5834                brcmf_err("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
5835                goto roam_setup_done;
5836        }
5837
5838        roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
5839        roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL);
5840        err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_DELTA,
5841                                     (void *)roam_delta, sizeof(roam_delta));
5842        if (err) {
5843                brcmf_err("WLC_SET_ROAM_DELTA error (%d)\n", err);
5844                goto roam_setup_done;
5845        }
5846
5847roam_setup_done:
5848        return err;
5849}
5850
5851static s32
5852brcmf_dongle_scantime(struct brcmf_if *ifp)
5853{
5854        s32 err = 0;
5855
5856        err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME,
5857                                    BRCMF_SCAN_CHANNEL_TIME);
5858        if (err) {
5859                brcmf_err("Scan assoc time error (%d)\n", err);
5860                goto dongle_scantime_out;
5861        }
5862        err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_UNASSOC_TIME,
5863                                    BRCMF_SCAN_UNASSOC_TIME);
5864        if (err) {
5865                brcmf_err("Scan unassoc time error (%d)\n", err);
5866                goto dongle_scantime_out;
5867        }
5868
5869        err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_PASSIVE_TIME,
5870                                    BRCMF_SCAN_PASSIVE_TIME);
5871        if (err) {
5872                brcmf_err("Scan passive time error (%d)\n", err);
5873                goto dongle_scantime_out;
5874        }
5875
5876dongle_scantime_out:
5877        return err;
5878}
5879
5880static void brcmf_update_bw40_channel_flag(struct ieee80211_channel *channel,
5881                                           struct brcmu_chan *ch)
5882{
5883        u32 ht40_flag;
5884
5885        ht40_flag = channel->flags & IEEE80211_CHAN_NO_HT40;
5886        if (ch->sb == BRCMU_CHAN_SB_U) {
5887                if (ht40_flag == IEEE80211_CHAN_NO_HT40)
5888                        channel->flags &= ~IEEE80211_CHAN_NO_HT40;
5889                channel->flags |= IEEE80211_CHAN_NO_HT40PLUS;
5890        } else {
5891                /* It should be one of
5892                 * IEEE80211_CHAN_NO_HT40 or
5893                 * IEEE80211_CHAN_NO_HT40PLUS
5894                 */
5895                channel->flags &= ~IEEE80211_CHAN_NO_HT40;
5896                if (ht40_flag == IEEE80211_CHAN_NO_HT40)
5897                        channel->flags |= IEEE80211_CHAN_NO_HT40MINUS;
5898        }
5899}
5900
5901static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg,
5902                                    u32 bw_cap[])
5903{
5904        struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0);
5905        struct ieee80211_supported_band *band;
5906        struct ieee80211_channel *channel;
5907        struct wiphy *wiphy;
5908        struct brcmf_chanspec_list *list;
5909        struct brcmu_chan ch;
5910        int err;
5911        u8 *pbuf;
5912        u32 i, j;
5913        u32 total;
5914        u32 chaninfo;
5915
5916        pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
5917
5918        if (pbuf == NULL)
5919                return -ENOMEM;
5920
5921        list = (struct brcmf_chanspec_list *)pbuf;
5922
5923        err = brcmf_fil_iovar_data_get(ifp, "chanspecs", pbuf,
5924                                       BRCMF_DCMD_MEDLEN);
5925        if (err) {
5926                brcmf_err("get chanspecs error (%d)\n", err);
5927                goto fail_pbuf;
5928        }
5929
5930        wiphy = cfg_to_wiphy(cfg);
5931        band = wiphy->bands[NL80211_BAND_2GHZ];
5932        if (band)
5933                for (i = 0; i < band->n_channels; i++)
5934                        band->channels[i].flags = IEEE80211_CHAN_DISABLED;
5935        band = wiphy->bands[NL80211_BAND_5GHZ];
5936        if (band)
5937                for (i = 0; i < band->n_channels; i++)
5938                        band->channels[i].flags = IEEE80211_CHAN_DISABLED;
5939
5940        total = le32_to_cpu(list->count);
5941        for (i = 0; i < total; i++) {
5942                ch.chspec = (u16)le32_to_cpu(list->element[i]);
5943                cfg->d11inf.decchspec(&ch);
5944
5945                if (ch.band == BRCMU_CHAN_BAND_2G) {
5946                        band = wiphy->bands[NL80211_BAND_2GHZ];
5947                } else if (ch.band == BRCMU_CHAN_BAND_5G) {
5948                        band = wiphy->bands[NL80211_BAND_5GHZ];
5949                } else {
5950                        brcmf_err("Invalid channel Spec. 0x%x.\n", ch.chspec);
5951                        continue;
5952                }
5953                if (!band)
5954                        continue;
5955                if (!(bw_cap[band->band] & WLC_BW_40MHZ_BIT) &&
5956                    ch.bw == BRCMU_CHAN_BW_40)
5957                        continue;
5958                if (!(bw_cap[band->band] & WLC_BW_80MHZ_BIT) &&
5959                    ch.bw == BRCMU_CHAN_BW_80)
5960                        continue;
5961
5962                channel = NULL;
5963                for (j = 0; j < band->n_channels; j++) {
5964                        if (band->channels[j].hw_value == ch.control_ch_num) {
5965                                channel = &band->channels[j];
5966                                break;
5967                        }
5968                }
5969                if (!channel) {
5970                        /* It seems firmware supports some channel we never
5971                         * considered. Something new in IEEE standard?
5972                         */
5973                        brcmf_err("Ignoring unexpected firmware channel %d\n",
5974                                  ch.control_ch_num);
5975                        continue;
5976                }
5977
5978                if (channel->orig_flags & IEEE80211_CHAN_DISABLED)
5979                        continue;
5980
5981                /* assuming the chanspecs order is HT20,
5982                 * HT40 upper, HT40 lower, and VHT80.
5983                 */
5984                if (ch.bw == BRCMU_CHAN_BW_80) {
5985                        channel->flags &= ~IEEE80211_CHAN_NO_80MHZ;
5986                } else if (ch.bw == BRCMU_CHAN_BW_40) {
5987                        brcmf_update_bw40_channel_flag(channel, &ch);
5988                } else {
5989                        /* enable the channel and disable other bandwidths
5990                         * for now as mentioned order assure they are enabled
5991                         * for subsequent chanspecs.
5992                         */
5993                        channel->flags = IEEE80211_CHAN_NO_HT40 |
5994                                         IEEE80211_CHAN_NO_80MHZ;
5995                        ch.bw = BRCMU_CHAN_BW_20;
5996                        cfg->d11inf.encchspec(&ch);
5997                        chaninfo = ch.chspec;
5998                        err = brcmf_fil_bsscfg_int_get(ifp, "per_chan_info",
5999                                                       &chaninfo);
6000                        if (!err) {
6001                                if (chaninfo & WL_CHAN_RADAR)
6002                                        channel->flags |=
6003                                                (IEEE80211_CHAN_RADAR |
6004                                                 IEEE80211_CHAN_NO_IR);
6005                                if (chaninfo & WL_CHAN_PASSIVE)
6006                                        channel->flags |=
6007                                                IEEE80211_CHAN_NO_IR;
6008                        }
6009                }
6010        }
6011
6012fail_pbuf:
6013        kfree(pbuf);
6014        return err;
6015}
6016
6017static int brcmf_enable_bw40_2g(struct brcmf_cfg80211_info *cfg)
6018{
6019        struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0);
6020        struct ieee80211_supported_band *band;
6021        struct brcmf_fil_bwcap_le band_bwcap;
6022        struct brcmf_chanspec_list *list;
6023        u8 *pbuf;
6024        u32 val;
6025        int err;
6026        struct brcmu_chan ch;
6027        u32 num_chan;
6028        int i, j;
6029
6030        /* verify support for bw_cap command */
6031        val = WLC_BAND_5G;
6032        err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &val);
6033
6034        if (!err) {
6035                /* only set 2G bandwidth using bw_cap command */
6036                band_bwcap.band = cpu_to_le32(WLC_BAND_2G);
6037                band_bwcap.bw_cap = cpu_to_le32(WLC_BW_CAP_40MHZ);
6038                err = brcmf_fil_iovar_data_set(ifp, "bw_cap", &band_bwcap,
6039                                               sizeof(band_bwcap));
6040        } else {
6041                brcmf_dbg(INFO, "fallback to mimo_bw_cap\n");
6042                val = WLC_N_BW_40ALL;
6043                err = brcmf_fil_iovar_int_set(ifp, "mimo_bw_cap", val);
6044        }
6045
6046        if (!err) {
6047                /* update channel info in 2G band */
6048                pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
6049
6050                if (pbuf == NULL)
6051                        return -ENOMEM;
6052
6053                ch.band = BRCMU_CHAN_BAND_2G;
6054                ch.bw = BRCMU_CHAN_BW_40;
6055                ch.sb = BRCMU_CHAN_SB_NONE;
6056                ch.chnum = 0;
6057                cfg->d11inf.encchspec(&ch);
6058
6059                /* pass encoded chanspec in query */
6060                *(__le16 *)pbuf = cpu_to_le16(ch.chspec);
6061
6062                err = brcmf_fil_iovar_data_get(ifp, "chanspecs", pbuf,
6063                                               BRCMF_DCMD_MEDLEN);
6064                if (err) {
6065                        brcmf_err("get chanspecs error (%d)\n", err);
6066                        kfree(pbuf);
6067                        return err;
6068                }
6069
6070                band = cfg_to_wiphy(cfg)->bands[NL80211_BAND_2GHZ];
6071                list = (struct brcmf_chanspec_list *)pbuf;
6072                num_chan = le32_to_cpu(list->count);
6073                for (i = 0; i < num_chan; i++) {
6074                        ch.chspec = (u16)le32_to_cpu(list->element[i]);
6075                        cfg->d11inf.decchspec(&ch);
6076                        if (WARN_ON(ch.band != BRCMU_CHAN_BAND_2G))
6077                                continue;
6078                        if (WARN_ON(ch.bw != BRCMU_CHAN_BW_40))
6079                                continue;
6080                        for (j = 0; j < band->n_channels; j++) {
6081                                if (band->channels[j].hw_value == ch.control_ch_num)
6082                                        break;
6083                        }
6084                        if (WARN_ON(j == band->n_channels))
6085                                continue;
6086
6087                        brcmf_update_bw40_channel_flag(&band->channels[j], &ch);
6088                }
6089                kfree(pbuf);
6090        }
6091        return err;
6092}
6093
6094static void brcmf_get_bwcap(struct brcmf_if *ifp, u32 bw_cap[])
6095{
6096        u32 band, mimo_bwcap;
6097        int err;
6098
6099        band = WLC_BAND_2G;
6100        err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &band);
6101        if (!err) {
6102                bw_cap[NL80211_BAND_2GHZ] = band;
6103                band = WLC_BAND_5G;
6104                err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &band);
6105                if (!err) {
6106                        bw_cap[NL80211_BAND_5GHZ] = band;
6107                        return;
6108                }
6109                WARN_ON(1);
6110                return;
6111        }
6112        brcmf_dbg(INFO, "fallback to mimo_bw_cap info\n");
6113        mimo_bwcap = 0;
6114        err = brcmf_fil_iovar_int_get(ifp, "mimo_bw_cap", &mimo_bwcap);
6115        if (err)
6116                /* assume 20MHz if firmware does not give a clue */
6117                mimo_bwcap = WLC_N_BW_20ALL;
6118
6119        switch (mimo_bwcap) {
6120        case WLC_N_BW_40ALL:
6121                bw_cap[NL80211_BAND_2GHZ] |= WLC_BW_40MHZ_BIT;
6122                /* fall-thru */
6123        case WLC_N_BW_20IN2G_40IN5G:
6124                bw_cap[NL80211_BAND_5GHZ] |= WLC_BW_40MHZ_BIT;
6125                /* fall-thru */
6126        case WLC_N_BW_20ALL:
6127                bw_cap[NL80211_BAND_2GHZ] |= WLC_BW_20MHZ_BIT;
6128                bw_cap[NL80211_BAND_5GHZ] |= WLC_BW_20MHZ_BIT;
6129                break;
6130        default:
6131                brcmf_err("invalid mimo_bw_cap value\n");
6132        }
6133}
6134
6135static void brcmf_update_ht_cap(struct ieee80211_supported_band *band,
6136                                u32 bw_cap[2], u32 nchain)
6137{
6138        band->ht_cap.ht_supported = true;
6139        if (bw_cap[band->band] & WLC_BW_40MHZ_BIT) {
6140                band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
6141                band->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
6142        }
6143        band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
6144        band->ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
6145        band->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
6146        band->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
6147        memset(band->ht_cap.mcs.rx_mask, 0xff, nchain);
6148        band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
6149}
6150
6151static __le16 brcmf_get_mcs_map(u32 nchain, enum ieee80211_vht_mcs_support supp)
6152{
6153        u16 mcs_map;
6154        int i;
6155
6156        for (i = 0, mcs_map = 0xFFFF; i < nchain; i++)
6157                mcs_map = (mcs_map << 2) | supp;
6158
6159        return cpu_to_le16(mcs_map);
6160}
6161
6162static void brcmf_update_vht_cap(struct ieee80211_supported_band *band,
6163                                 u32 bw_cap[2], u32 nchain, u32 txstreams,
6164                                 u32 txbf_bfe_cap, u32 txbf_bfr_cap)
6165{
6166        __le16 mcs_map;
6167
6168        /* not allowed in 2.4G band */
6169        if (band->band == NL80211_BAND_2GHZ)
6170                return;
6171
6172        band->vht_cap.vht_supported = true;
6173        /* 80MHz is mandatory */
6174        band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_80;
6175        if (bw_cap[band->band] & WLC_BW_160MHZ_BIT) {
6176                band->vht_cap.cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
6177                band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_160;
6178        }
6179        /* all support 256-QAM */
6180        mcs_map = brcmf_get_mcs_map(nchain, IEEE80211_VHT_MCS_SUPPORT_0_9);
6181        band->vht_cap.vht_mcs.rx_mcs_map = mcs_map;
6182        band->vht_cap.vht_mcs.tx_mcs_map = mcs_map;
6183
6184        /* Beamforming support information */
6185        if (txbf_bfe_cap & BRCMF_TXBF_SU_BFE_CAP)
6186                band->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE;
6187        if (txbf_bfe_cap & BRCMF_TXBF_MU_BFE_CAP)
6188                band->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;
6189        if (txbf_bfr_cap & BRCMF_TXBF_SU_BFR_CAP)
6190                band->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE;
6191        if (txbf_bfr_cap & BRCMF_TXBF_MU_BFR_CAP)
6192                band->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE;
6193
6194        if ((txbf_bfe_cap || txbf_bfr_cap) && (txstreams > 1)) {
6195                band->vht_cap.cap |=
6196                        (2 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT);
6197                band->vht_cap.cap |= ((txstreams - 1) <<
6198                                IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT);
6199                band->vht_cap.cap |=
6200                        IEEE80211_VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB;
6201        }
6202}
6203
6204static int brcmf_setup_wiphybands(struct brcmf_cfg80211_info *cfg)
6205{
6206        struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0);
6207        struct wiphy *wiphy;
6208        u32 nmode = 0;
6209        u32 vhtmode = 0;
6210        u32 bw_cap[2] = { WLC_BW_20MHZ_BIT, WLC_BW_20MHZ_BIT };
6211        u32 rxchain;
6212        u32 nchain;
6213        int err;
6214        s32 i;
6215        struct ieee80211_supported_band *band;
6216        u32 txstreams = 0;
6217        u32 txbf_bfe_cap = 0;
6218        u32 txbf_bfr_cap = 0;
6219
6220        (void)brcmf_fil_iovar_int_get(ifp, "vhtmode", &vhtmode);
6221        err = brcmf_fil_iovar_int_get(ifp, "nmode", &nmode);
6222        if (err) {
6223                brcmf_err("nmode error (%d)\n", err);
6224        } else {
6225                brcmf_get_bwcap(ifp, bw_cap);
6226        }
6227        brcmf_dbg(INFO, "nmode=%d, vhtmode=%d, bw_cap=(%d, %d)\n",
6228                  nmode, vhtmode, bw_cap[NL80211_BAND_2GHZ],
6229                  bw_cap[NL80211_BAND_5GHZ]);
6230
6231        err = brcmf_fil_iovar_int_get(ifp, "rxchain", &rxchain);
6232        if (err) {
6233                brcmf_err("rxchain error (%d)\n", err);
6234                nchain = 1;
6235        } else {
6236                for (nchain = 0; rxchain; nchain++)
6237                        rxchain = rxchain & (rxchain - 1);
6238        }
6239        brcmf_dbg(INFO, "nchain=%d\n", nchain);
6240
6241        err = brcmf_construct_chaninfo(cfg, bw_cap);
6242        if (err) {
6243                brcmf_err("brcmf_construct_chaninfo failed (%d)\n", err);
6244                return err;
6245        }
6246
6247        if (vhtmode) {
6248                (void)brcmf_fil_iovar_int_get(ifp, "txstreams", &txstreams);
6249                (void)brcmf_fil_iovar_int_get(ifp, "txbf_bfe_cap",
6250                                              &txbf_bfe_cap);
6251                (void)brcmf_fil_iovar_int_get(ifp, "txbf_bfr_cap",
6252                                              &txbf_bfr_cap);
6253        }
6254
6255        wiphy = cfg_to_wiphy(cfg);
6256        for (i = 0; i < ARRAY_SIZE(wiphy->bands); i++) {
6257                band = wiphy->bands[i];
6258                if (band == NULL)
6259                        continue;
6260
6261                if (nmode)
6262                        brcmf_update_ht_cap(band, bw_cap, nchain);
6263                if (vhtmode)
6264                        brcmf_update_vht_cap(band, bw_cap, nchain, txstreams,
6265                                             txbf_bfe_cap, txbf_bfr_cap);
6266        }
6267
6268        return 0;
6269}
6270
6271static const struct ieee80211_txrx_stypes
6272brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = {
6273        [NL80211_IFTYPE_STATION] = {
6274                .tx = 0xffff,
6275                .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
6276                      BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
6277        },
6278        [NL80211_IFTYPE_P2P_CLIENT] = {
6279                .tx = 0xffff,
6280                .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
6281                      BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
6282        },
6283        [NL80211_IFTYPE_P2P_GO] = {
6284                .tx = 0xffff,
6285                .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
6286                      BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
6287                      BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
6288                      BIT(IEEE80211_STYPE_DISASSOC >> 4) |
6289                      BIT(IEEE80211_STYPE_AUTH >> 4) |
6290                      BIT(IEEE80211_STYPE_DEAUTH >> 4) |
6291                      BIT(IEEE80211_STYPE_ACTION >> 4)
6292        },
6293        [NL80211_IFTYPE_P2P_DEVICE] = {
6294                .tx = 0xffff,
6295                .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
6296                      BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
6297        }
6298};
6299
6300/**
6301 * brcmf_setup_ifmodes() - determine interface modes and combinations.
6302 *
6303 * @wiphy: wiphy object.
6304 * @ifp: interface object needed for feat module api.
6305 *
6306 * The interface modes and combinations are determined dynamically here
6307 * based on firmware functionality.
6308 *
6309 * no p2p and no mbss:
6310 *
6311 *      #STA <= 1, #AP <= 1, channels = 1, 2 total
6312 *
6313 * no p2p and mbss:
6314 *
6315 *      #STA <= 1, #AP <= 1, channels = 1, 2 total
6316 *      #AP <= 4, matching BI, channels = 1, 4 total
6317 *
6318 * p2p, no mchan, and mbss:
6319 *
6320 *      #STA <= 1, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 1, channels = 1, 3 total
6321 *      #STA <= 1, #P2P-DEV <= 1, #AP <= 1, #P2P-CL <= 1, channels = 1, 4 total
6322 *      #AP <= 4, matching BI, channels = 1, 4 total
6323 *
6324 * p2p, mchan, and mbss:
6325 *
6326 *      #STA <= 1, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 1, channels = 2, 3 total
6327 *      #STA <= 1, #P2P-DEV <= 1, #AP <= 1, #P2P-CL <= 1, channels = 1, 4 total
6328 *      #AP <= 4, matching BI, channels = 1, 4 total
6329 */
6330static int brcmf_setup_ifmodes(struct wiphy *wiphy, struct brcmf_if *ifp)
6331{
6332        struct ieee80211_iface_combination *combo = NULL;
6333        struct ieee80211_iface_limit *c0_limits = NULL;
6334        struct ieee80211_iface_limit *p2p_limits = NULL;
6335        struct ieee80211_iface_limit *mbss_limits = NULL;
6336        bool mbss, p2p;
6337        int i, c, n_combos;
6338
6339        mbss = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS);
6340        p2p = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_P2P);
6341
6342        n_combos = 1 + !!p2p + !!mbss;
6343        combo = kcalloc(n_combos, sizeof(*combo), GFP_KERNEL);
6344        if (!combo)
6345                goto err;
6346
6347        wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
6348                                 BIT(NL80211_IFTYPE_ADHOC) |
6349                                 BIT(NL80211_IFTYPE_AP);
6350
6351        c = 0;
6352        i = 0;
6353        c0_limits = kcalloc(p2p ? 3 : 2, sizeof(*c0_limits), GFP_KERNEL);
6354        if (!c0_limits)
6355                goto err;
6356        c0_limits[i].max = 1;
6357        c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
6358        if (p2p) {
6359                if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN))
6360                        combo[c].num_different_channels = 2;
6361                else
6362                        combo[c].num_different_channels = 1;
6363                wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_CLIENT) |
6364                                          BIT(NL80211_IFTYPE_P2P_GO) |
6365                                          BIT(NL80211_IFTYPE_P2P_DEVICE);
6366                c0_limits[i].max = 1;
6367                c0_limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE);
6368                c0_limits[i].max = 1;
6369                c0_limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
6370                                       BIT(NL80211_IFTYPE_P2P_GO);
6371        } else {
6372                combo[c].num_different_channels = 1;
6373                c0_limits[i].max = 1;
6374                c0_limits[i++].types = BIT(NL80211_IFTYPE_AP);
6375        }
6376        combo[c].max_interfaces = i;
6377        combo[c].n_limits = i;
6378        combo[c].limits = c0_limits;
6379
6380        if (p2p) {
6381                c++;
6382                i = 0;
6383                p2p_limits = kcalloc(4, sizeof(*p2p_limits), GFP_KERNEL);
6384                if (!p2p_limits)
6385                        goto err;
6386                p2p_limits[i].max = 1;
6387                p2p_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
6388                p2p_limits[i].max = 1;
6389                p2p_limits[i++].types = BIT(NL80211_IFTYPE_AP);
6390                p2p_limits[i].max = 1;
6391                p2p_limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT);
6392                p2p_limits[i].max = 1;
6393                p2p_limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE);
6394                combo[c].num_different_channels = 1;
6395                combo[c].max_interfaces = i;
6396                combo[c].n_limits = i;
6397                combo[c].limits = p2p_limits;
6398        }
6399
6400        if (mbss) {
6401                c++;
6402                i = 0;
6403                mbss_limits = kcalloc(1, sizeof(*mbss_limits), GFP_KERNEL);
6404                if (!mbss_limits)
6405                        goto err;
6406                mbss_limits[i].max = 4;
6407                mbss_limits[i++].types = BIT(NL80211_IFTYPE_AP);
6408                combo[c].beacon_int_infra_match = true;
6409                combo[c].num_different_channels = 1;
6410                combo[c].max_interfaces = 4;
6411                combo[c].n_limits = i;
6412                combo[c].limits = mbss_limits;
6413        }
6414
6415        wiphy->n_iface_combinations = n_combos;
6416        wiphy->iface_combinations = combo;
6417        return 0;
6418
6419err:
6420        kfree(c0_limits);
6421        kfree(p2p_limits);
6422        kfree(mbss_limits);
6423        kfree(combo);
6424        return -ENOMEM;
6425}
6426
6427#ifdef CONFIG_PM
6428static const struct wiphy_wowlan_support brcmf_wowlan_support = {
6429        .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT,
6430        .n_patterns = BRCMF_WOWL_MAXPATTERNS,
6431        .pattern_max_len = BRCMF_WOWL_MAXPATTERNSIZE,
6432        .pattern_min_len = 1,
6433        .max_pkt_offset = 1500,
6434};
6435#endif
6436
6437static void brcmf_wiphy_wowl_params(struct wiphy *wiphy, struct brcmf_if *ifp)
6438{
6439#ifdef CONFIG_PM
6440        struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
6441        struct wiphy_wowlan_support *wowl;
6442
6443        wowl = kmemdup(&brcmf_wowlan_support, sizeof(brcmf_wowlan_support),
6444                       GFP_KERNEL);
6445        if (!wowl) {
6446                brcmf_err("only support basic wowlan features\n");
6447                wiphy->wowlan = &brcmf_wowlan_support;
6448                return;
6449        }
6450
6451        if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO)) {
6452                if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_ND)) {
6453                        wowl->flags |= WIPHY_WOWLAN_NET_DETECT;
6454                        wowl->max_nd_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
6455                        init_waitqueue_head(&cfg->wowl.nd_data_wait);
6456                }
6457        }
6458        if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_GTK)) {
6459                wowl->flags |= WIPHY_WOWLAN_SUPPORTS_GTK_REKEY;
6460                wowl->flags |= WIPHY_WOWLAN_GTK_REKEY_FAILURE;
6461        }
6462
6463        wiphy->wowlan = wowl;
6464#endif
6465}
6466
6467static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp)
6468{
6469        struct brcmf_pub *drvr = ifp->drvr;
6470        const struct ieee80211_iface_combination *combo;
6471        struct ieee80211_supported_band *band;
6472        u16 max_interfaces = 0;
6473        bool gscan;
6474        __le32 bandlist[3];
6475        u32 n_bands;
6476        int err, i;
6477
6478        wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
6479        wiphy->max_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
6480        wiphy->max_num_pmkids = BRCMF_MAXPMKID;
6481
6482        err = brcmf_setup_ifmodes(wiphy, ifp);
6483        if (err)
6484                return err;
6485
6486        for (i = 0, combo = wiphy->iface_combinations;
6487             i < wiphy->n_iface_combinations; i++, combo++) {
6488                max_interfaces = max(max_interfaces, combo->max_interfaces);
6489        }
6490
6491        for (i = 0; i < max_interfaces && i < ARRAY_SIZE(drvr->addresses);
6492             i++) {
6493                u8 *addr = drvr->addresses[i].addr;
6494
6495                memcpy(addr, drvr->mac, ETH_ALEN);
6496                if (i) {
6497                        addr[0] |= BIT(1);
6498                        addr[ETH_ALEN - 1] ^= i;
6499                }
6500        }
6501        wiphy->addresses = drvr->addresses;
6502        wiphy->n_addresses = i;
6503
6504        wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
6505        wiphy->cipher_suites = brcmf_cipher_suites;
6506        wiphy->n_cipher_suites = ARRAY_SIZE(brcmf_cipher_suites);
6507        if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP))
6508                wiphy->n_cipher_suites--;
6509        wiphy->bss_select_support = BIT(NL80211_BSS_SELECT_ATTR_RSSI) |
6510                                    BIT(NL80211_BSS_SELECT_ATTR_BAND_PREF) |
6511                                    BIT(NL80211_BSS_SELECT_ATTR_RSSI_ADJUST);
6512
6513        wiphy->flags |= WIPHY_FLAG_NETNS_OK |
6514                        WIPHY_FLAG_PS_ON_BY_DEFAULT |
6515                        WIPHY_FLAG_OFFCHAN_TX |
6516                        WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
6517        if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_TDLS))
6518                wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
6519        if (!ifp->drvr->settings->roamoff)
6520                wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
6521        if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_FWSUP)) {
6522                wiphy_ext_feature_set(wiphy,
6523                                      NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_PSK);
6524                wiphy_ext_feature_set(wiphy,
6525                                      NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X);
6526        }
6527        wiphy->mgmt_stypes = brcmf_txrx_stypes;
6528        wiphy->max_remain_on_channel_duration = 5000;
6529        if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO)) {
6530                gscan = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_GSCAN);
6531                brcmf_pno_wiphy_params(wiphy, gscan);
6532        }
6533        /* vendor commands/events support */
6534        wiphy->vendor_commands = brcmf_vendor_cmds;
6535        wiphy->n_vendor_commands = BRCMF_VNDR_CMDS_LAST - 1;
6536
6537        if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL))
6538                brcmf_wiphy_wowl_params(wiphy, ifp);
6539        err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BANDLIST, &bandlist,
6540                                     sizeof(bandlist));
6541        if (err) {
6542                brcmf_err("could not obtain band info: err=%d\n", err);
6543                return err;
6544        }
6545        /* first entry in bandlist is number of bands */
6546        n_bands = le32_to_cpu(bandlist[0]);
6547        for (i = 1; i <= n_bands && i < ARRAY_SIZE(bandlist); i++) {
6548                if (bandlist[i] == cpu_to_le32(WLC_BAND_2G)) {
6549                        band = kmemdup(&__wl_band_2ghz, sizeof(__wl_band_2ghz),
6550                                       GFP_KERNEL);
6551                        if (!band)
6552                                return -ENOMEM;
6553
6554                        band->channels = kmemdup(&__wl_2ghz_channels,
6555                                                 sizeof(__wl_2ghz_channels),
6556                                                 GFP_KERNEL);
6557                        if (!band->channels) {
6558                                kfree(band);
6559                                return -ENOMEM;
6560                        }
6561
6562                        band->n_channels = ARRAY_SIZE(__wl_2ghz_channels);
6563                        wiphy->bands[NL80211_BAND_2GHZ] = band;
6564                }
6565                if (bandlist[i] == cpu_to_le32(WLC_BAND_5G)) {
6566                        band = kmemdup(&__wl_band_5ghz, sizeof(__wl_band_5ghz),
6567                                       GFP_KERNEL);
6568                        if (!band)
6569                                return -ENOMEM;
6570
6571                        band->channels = kmemdup(&__wl_5ghz_channels,
6572                                                 sizeof(__wl_5ghz_channels),
6573                                                 GFP_KERNEL);
6574                        if (!band->channels) {
6575                                kfree(band);
6576                                return -ENOMEM;
6577                        }
6578
6579                        band->n_channels = ARRAY_SIZE(__wl_5ghz_channels);
6580                        wiphy->bands[NL80211_BAND_5GHZ] = band;
6581                }
6582        }
6583
6584        wiphy_read_of_freq_limits(wiphy);
6585
6586        return 0;
6587}
6588
6589static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
6590{
6591        struct net_device *ndev;
6592        struct wireless_dev *wdev;
6593        struct brcmf_if *ifp;
6594        s32 power_mode;
6595        s32 err = 0;
6596
6597        if (cfg->dongle_up)
6598                return err;
6599
6600        ndev = cfg_to_ndev(cfg);
6601        wdev = ndev->ieee80211_ptr;
6602        ifp = netdev_priv(ndev);
6603
6604        /* make sure RF is ready for work */
6605        brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
6606
6607        brcmf_dongle_scantime(ifp);
6608
6609        power_mode = cfg->pwr_save ? PM_FAST : PM_OFF;
6610        err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, power_mode);
6611        if (err)
6612                goto default_conf_out;
6613        brcmf_dbg(INFO, "power save set to %s\n",
6614                  (power_mode ? "enabled" : "disabled"));
6615
6616        err = brcmf_dongle_roam(ifp);
6617        if (err)
6618                goto default_conf_out;
6619        err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype,
6620                                          NULL);
6621        if (err)
6622                goto default_conf_out;
6623
6624        brcmf_configure_arp_nd_offload(ifp, true);
6625
6626        cfg->dongle_up = true;
6627default_conf_out:
6628
6629        return err;
6630
6631}
6632
6633static s32 __brcmf_cfg80211_up(struct brcmf_if *ifp)
6634{
6635        set_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
6636
6637        return brcmf_config_dongle(ifp->drvr->config);
6638}
6639
6640static s32 __brcmf_cfg80211_down(struct brcmf_if *ifp)
6641{
6642        struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
6643
6644        /*
6645         * While going down, if associated with AP disassociate
6646         * from AP to save power
6647         */
6648        if (check_vif_up(ifp->vif)) {
6649                brcmf_link_down(ifp->vif, WLAN_REASON_UNSPECIFIED);
6650
6651                /* Make sure WPA_Supplicant receives all the event
6652                   generated due to DISASSOC call to the fw to keep
6653                   the state fw and WPA_Supplicant state consistent
6654                 */
6655                brcmf_delay(500);
6656        }
6657
6658        brcmf_abort_scanning(cfg);
6659        clear_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
6660
6661        return 0;
6662}
6663
6664s32 brcmf_cfg80211_up(struct net_device *ndev)
6665{
6666        struct brcmf_if *ifp = netdev_priv(ndev);
6667        struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
6668        s32 err = 0;
6669
6670        mutex_lock(&cfg->usr_sync);
6671        err = __brcmf_cfg80211_up(ifp);
6672        mutex_unlock(&cfg->usr_sync);
6673
6674        return err;
6675}
6676
6677s32 brcmf_cfg80211_down(struct net_device *ndev)
6678{
6679        struct brcmf_if *ifp = netdev_priv(ndev);
6680        struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
6681        s32 err = 0;
6682
6683        mutex_lock(&cfg->usr_sync);
6684        err = __brcmf_cfg80211_down(ifp);
6685        mutex_unlock(&cfg->usr_sync);
6686
6687        return err;
6688}
6689
6690enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp)
6691{
6692        struct wireless_dev *wdev = &ifp->vif->wdev;
6693
6694        return wdev->iftype;
6695}
6696
6697bool brcmf_get_vif_state_any(struct brcmf_cfg80211_info *cfg,
6698                             unsigned long state)
6699{
6700        struct brcmf_cfg80211_vif *vif;
6701
6702        list_for_each_entry(vif, &cfg->vif_list, list) {
6703                if (test_bit(state, &vif->sme_state))
6704                        return true;
6705        }
6706        return false;
6707}
6708
6709static inline bool vif_event_equals(struct brcmf_cfg80211_vif_event *event,
6710                                    u8 action)
6711{
6712        u8 evt_action;
6713
6714        spin_lock(&event->vif_event_lock);
6715        evt_action = event->action;
6716        spin_unlock(&event->vif_event_lock);
6717        return evt_action == action;
6718}
6719
6720void brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info *cfg,
6721                                  struct brcmf_cfg80211_vif *vif)
6722{
6723        struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
6724
6725        spin_lock(&event->vif_event_lock);
6726        event->vif = vif;
6727        event->action = 0;
6728        spin_unlock(&event->vif_event_lock);
6729}
6730
6731bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info *cfg)
6732{
6733        struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
6734        bool armed;
6735
6736        spin_lock(&event->vif_event_lock);
6737        armed = event->vif != NULL;
6738        spin_unlock(&event->vif_event_lock);
6739
6740        return armed;
6741}
6742
6743int brcmf_cfg80211_wait_vif_event(struct brcmf_cfg80211_info *cfg,
6744                                  u8 action, ulong timeout)
6745{
6746        struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
6747
6748        return wait_event_timeout(event->vif_wq,
6749                                  vif_event_equals(event, action), timeout);
6750}
6751
6752static s32 brcmf_translate_country_code(struct brcmf_pub *drvr, char alpha2[2],
6753                                        struct brcmf_fil_country_le *ccreq)
6754{
6755        struct brcmfmac_pd_cc *country_codes;
6756        struct brcmfmac_pd_cc_entry *cc;
6757        s32 found_index;
6758        int i;
6759
6760        country_codes = drvr->settings->country_codes;
6761        if (!country_codes) {
6762                brcmf_dbg(TRACE, "No country codes configured for device\n");
6763                return -EINVAL;
6764        }
6765
6766        if ((alpha2[0] == ccreq->country_abbrev[0]) &&
6767            (alpha2[1] == ccreq->country_abbrev[1])) {
6768                brcmf_dbg(TRACE, "Country code already set\n");
6769                return -EAGAIN;
6770        }
6771
6772        found_index = -1;
6773        for (i = 0; i < country_codes->table_size; i++) {
6774                cc = &country_codes->table[i];
6775                if ((cc->iso3166[0] == '\0') && (found_index == -1))
6776                        found_index = i;
6777                if ((cc->iso3166[0] == alpha2[0]) &&
6778                    (cc->iso3166[1] == alpha2[1])) {
6779                        found_index = i;
6780                        break;
6781                }
6782        }
6783        if (found_index == -1) {
6784                brcmf_dbg(TRACE, "No country code match found\n");
6785                return -EINVAL;
6786        }
6787        memset(ccreq, 0, sizeof(*ccreq));
6788        ccreq->rev = cpu_to_le32(country_codes->table[found_index].rev);
6789        memcpy(ccreq->ccode, country_codes->table[found_index].cc,
6790               BRCMF_COUNTRY_BUF_SZ);
6791        ccreq->country_abbrev[0] = alpha2[0];
6792        ccreq->country_abbrev[1] = alpha2[1];
6793        ccreq->country_abbrev[2] = 0;
6794
6795        return 0;
6796}
6797
6798static void brcmf_cfg80211_reg_notifier(struct wiphy *wiphy,
6799                                        struct regulatory_request *req)
6800{
6801        struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
6802        struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0);
6803        struct brcmf_fil_country_le ccreq;
6804        s32 err;
6805        int i;
6806
6807        /* The country code gets set to "00" by default at boot, ignore */
6808        if (req->alpha2[0] == '0' && req->alpha2[1] == '0')
6809                return;
6810
6811        /* ignore non-ISO3166 country codes */
6812        for (i = 0; i < 2; i++)
6813                if (req->alpha2[i] < 'A' || req->alpha2[i] > 'Z') {
6814                        brcmf_err("not an ISO3166 code (0x%02x 0x%02x)\n",
6815                                  req->alpha2[0], req->alpha2[1]);
6816                        return;
6817                }
6818
6819        brcmf_dbg(TRACE, "Enter: initiator=%d, alpha=%c%c\n", req->initiator,
6820                  req->alpha2[0], req->alpha2[1]);
6821
6822        err = brcmf_fil_iovar_data_get(ifp, "country", &ccreq, sizeof(ccreq));
6823        if (err) {
6824                brcmf_err("Country code iovar returned err = %d\n", err);
6825                return;
6826        }
6827
6828        err = brcmf_translate_country_code(ifp->drvr, req->alpha2, &ccreq);
6829        if (err)
6830                return;
6831
6832        err = brcmf_fil_iovar_data_set(ifp, "country", &ccreq, sizeof(ccreq));
6833        if (err) {
6834                brcmf_err("Firmware rejected country setting\n");
6835                return;
6836        }
6837        brcmf_setup_wiphybands(cfg);
6838}
6839
6840static void brcmf_free_wiphy(struct wiphy *wiphy)
6841{
6842        int i;
6843
6844        if (!wiphy)
6845                return;
6846
6847        if (wiphy->iface_combinations) {
6848                for (i = 0; i < wiphy->n_iface_combinations; i++)
6849                        kfree(wiphy->iface_combinations[i].limits);
6850        }
6851        kfree(wiphy->iface_combinations);
6852        if (wiphy->bands[NL80211_BAND_2GHZ]) {
6853                kfree(wiphy->bands[NL80211_BAND_2GHZ]->channels);
6854                kfree(wiphy->bands[NL80211_BAND_2GHZ]);
6855        }
6856        if (wiphy->bands[NL80211_BAND_5GHZ]) {
6857                kfree(wiphy->bands[NL80211_BAND_5GHZ]->channels);
6858                kfree(wiphy->bands[NL80211_BAND_5GHZ]);
6859        }
6860#if IS_ENABLED(CONFIG_PM)
6861        if (wiphy->wowlan != &brcmf_wowlan_support)
6862                kfree(wiphy->wowlan);
6863#endif
6864}
6865
6866struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
6867                                                  struct cfg80211_ops *ops,
6868                                                  bool p2pdev_forced)
6869{
6870        struct wiphy *wiphy = drvr->wiphy;
6871        struct net_device *ndev = brcmf_get_ifp(drvr, 0)->ndev;
6872        struct brcmf_cfg80211_info *cfg;
6873        struct brcmf_cfg80211_vif *vif;
6874        struct brcmf_if *ifp;
6875        s32 err = 0;
6876        s32 io_type;
6877        u16 *cap = NULL;
6878
6879        if (!ndev) {
6880                brcmf_err("ndev is invalid\n");
6881                return NULL;
6882        }
6883
6884        cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
6885        if (!cfg) {
6886                brcmf_err("Could not allocate wiphy device\n");
6887                return NULL;
6888        }
6889
6890        cfg->wiphy = wiphy;
6891        cfg->pub = drvr;
6892        init_vif_event(&cfg->vif_event);
6893        INIT_LIST_HEAD(&cfg->vif_list);
6894
6895        vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_STATION);
6896        if (IS_ERR(vif))
6897                goto wiphy_out;
6898
6899        ifp = netdev_priv(ndev);
6900        vif->ifp = ifp;
6901        vif->wdev.netdev = ndev;
6902        ndev->ieee80211_ptr = &vif->wdev;
6903        SET_NETDEV_DEV(ndev, wiphy_dev(cfg->wiphy));
6904
6905        err = wl_init_priv(cfg);
6906        if (err) {
6907                brcmf_err("Failed to init iwm_priv (%d)\n", err);
6908                brcmf_free_vif(vif);
6909                goto wiphy_out;
6910        }
6911        ifp->vif = vif;
6912
6913        /* determine d11 io type before wiphy setup */
6914        err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_VERSION, &io_type);
6915        if (err) {
6916                brcmf_err("Failed to get D11 version (%d)\n", err);
6917                goto priv_out;
6918        }
6919        cfg->d11inf.io_type = (u8)io_type;
6920        brcmu_d11_attach(&cfg->d11inf);
6921
6922        err = brcmf_setup_wiphy(wiphy, ifp);
6923        if (err < 0)
6924                goto priv_out;
6925
6926        /* regulatory notifer below needs access to cfg so
6927         * assign it now.
6928         */
6929        drvr->config = cfg;
6930
6931        brcmf_dbg(INFO, "Registering custom regulatory\n");
6932        wiphy->reg_notifier = brcmf_cfg80211_reg_notifier;
6933        wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
6934        wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom);
6935
6936        /* firmware defaults to 40MHz disabled in 2G band. We signal
6937         * cfg80211 here that we do and have it decide we can enable
6938         * it. But first check if device does support 2G operation.
6939         */
6940        if (wiphy->bands[NL80211_BAND_2GHZ]) {
6941                cap = &wiphy->bands[NL80211_BAND_2GHZ]->ht_cap.cap;
6942                *cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
6943        }
6944#ifdef CONFIG_PM
6945        if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_GTK))
6946                ops->set_rekey_data = brcmf_cfg80211_set_rekey_data;
6947#endif
6948        err = wiphy_register(wiphy);
6949        if (err < 0) {
6950                brcmf_err("Could not register wiphy device (%d)\n", err);
6951                goto priv_out;
6952        }
6953
6954        err = brcmf_setup_wiphybands(cfg);
6955        if (err) {
6956                brcmf_err("Setting wiphy bands failed (%d)\n", err);
6957                goto wiphy_unreg_out;
6958        }
6959
6960        /* If cfg80211 didn't disable 40MHz HT CAP in wiphy_register(),
6961         * setup 40MHz in 2GHz band and enable OBSS scanning.
6962         */
6963        if (cap && (*cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)) {
6964                err = brcmf_enable_bw40_2g(cfg);
6965                if (!err)
6966                        err = brcmf_fil_iovar_int_set(ifp, "obss_coex",
6967                                                      BRCMF_OBSS_COEX_AUTO);
6968                else
6969                        *cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
6970        }
6971
6972        err = brcmf_fweh_activate_events(ifp);
6973        if (err) {
6974                brcmf_err("FWEH activation failed (%d)\n", err);
6975                goto wiphy_unreg_out;
6976        }
6977
6978        err = brcmf_p2p_attach(cfg, p2pdev_forced);
6979        if (err) {
6980                brcmf_err("P2P initialisation failed (%d)\n", err);
6981                goto wiphy_unreg_out;
6982        }
6983        err = brcmf_btcoex_attach(cfg);
6984        if (err) {
6985                brcmf_err("BT-coex initialisation failed (%d)\n", err);
6986                brcmf_p2p_detach(&cfg->p2p);
6987                goto wiphy_unreg_out;
6988        }
6989        err = brcmf_pno_attach(cfg);
6990        if (err) {
6991                brcmf_err("PNO initialisation failed (%d)\n", err);
6992                brcmf_btcoex_detach(cfg);
6993                brcmf_p2p_detach(&cfg->p2p);
6994                goto wiphy_unreg_out;
6995        }
6996
6997        if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_TDLS)) {
6998                err = brcmf_fil_iovar_int_set(ifp, "tdls_enable", 1);
6999                if (err) {
7000                        brcmf_dbg(INFO, "TDLS not enabled (%d)\n", err);
7001                        wiphy->flags &= ~WIPHY_FLAG_SUPPORTS_TDLS;
7002                } else {
7003                        brcmf_fweh_register(cfg->pub, BRCMF_E_TDLS_PEER_EVENT,
7004                                            brcmf_notify_tdls_peer_event);
7005                }
7006        }
7007
7008        /* (re-) activate FWEH event handling */
7009        err = brcmf_fweh_activate_events(ifp);
7010        if (err) {
7011                brcmf_err("FWEH activation failed (%d)\n", err);
7012                goto detach;
7013        }
7014
7015        /* Fill in some of the advertised nl80211 supported features */
7016        if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_SCAN_RANDOM_MAC)) {
7017                wiphy->features |= NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR;
7018#ifdef CONFIG_PM
7019                if (wiphy->wowlan &&
7020                    wiphy->wowlan->flags & WIPHY_WOWLAN_NET_DETECT)
7021                        wiphy->features |= NL80211_FEATURE_ND_RANDOM_MAC_ADDR;
7022#endif
7023        }
7024
7025        return cfg;
7026
7027detach:
7028        brcmf_pno_detach(cfg);
7029        brcmf_btcoex_detach(cfg);
7030        brcmf_p2p_detach(&cfg->p2p);
7031wiphy_unreg_out:
7032        wiphy_unregister(cfg->wiphy);
7033priv_out:
7034        wl_deinit_priv(cfg);
7035        brcmf_free_vif(vif);
7036        ifp->vif = NULL;
7037wiphy_out:
7038        brcmf_free_wiphy(wiphy);
7039        kfree(cfg);
7040        return NULL;
7041}
7042
7043void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
7044{
7045        if (!cfg)
7046                return;
7047
7048        brcmf_pno_detach(cfg);
7049        brcmf_btcoex_detach(cfg);
7050        wiphy_unregister(cfg->wiphy);
7051        kfree(cfg->ops);
7052        wl_deinit_priv(cfg);
7053        brcmf_free_wiphy(cfg->wiphy);
7054        kfree(cfg);
7055}
7056