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