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