Back to home page

OSCL-LXR

 
 

    


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