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->