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