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