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