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