cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

cfg80211.c (216927B)


      1// SPDX-License-Identifier: ISC
      2/*
      3 * Copyright (c) 2010 Broadcom Corporation
      4 */
      5
      6/* Toplevel file. Relies on dhd_linux.c to send commands to the dongle. */
      7
      8#include <linux/kernel.h>
      9#include <linux/etherdevice.h>
     10#include <linux/module.h>
     11#include <linux/vmalloc.h>
     12#include <net/cfg80211.h>
     13#include <net/netlink.h>
     14#include <uapi/linux/if_arp.h>
     15
     16#include <brcmu_utils.h>
     17#include <defs.h>
     18#include <brcmu_wifi.h>
     19#include <brcm_hw_ids.h>
     20#include "core.h"
     21#include "debug.h"
     22#include "tracepoint.h"
     23#include "fwil_types.h"
     24#include "p2p.h"
     25#include "btcoex.h"
     26#include "pno.h"
     27#include "fwsignal.h"
     28#include "cfg80211.h"
     29#include "feature.h"
     30#include "fwil.h"
     31#include "proto.h"
     32#include "vendor.h"
     33#include "bus.h"
     34#include "common.h"
     35
     36#define BRCMF_SCAN_IE_LEN_MAX		2048
     37
     38#define WPA_OUI				"\x00\x50\xF2"	/* WPA OUI */
     39#define WPA_OUI_TYPE			1
     40#define RSN_OUI				"\x00\x0F\xAC"	/* RSN OUI */
     41#define	WME_OUI_TYPE			2
     42#define WPS_OUI_TYPE			4
     43
     44#define VS_IE_FIXED_HDR_LEN		6
     45#define WPA_IE_VERSION_LEN		2
     46#define WPA_IE_MIN_OUI_LEN		4
     47#define WPA_IE_SUITE_COUNT_LEN		2
     48
     49#define WPA_CIPHER_NONE			0	/* None */
     50#define WPA_CIPHER_WEP_40		1	/* WEP (40-bit) */
     51#define WPA_CIPHER_TKIP			2	/* TKIP: default for WPA */
     52#define WPA_CIPHER_AES_CCM		4	/* AES (CCM) */
     53#define WPA_CIPHER_WEP_104		5	/* WEP (104-bit) */
     54
     55#define RSN_AKM_NONE			0	/* None (IBSS) */
     56#define RSN_AKM_UNSPECIFIED		1	/* Over 802.1x */
     57#define RSN_AKM_PSK			2	/* Pre-shared Key */
     58#define RSN_AKM_SHA256_1X		5	/* SHA256, 802.1X */
     59#define RSN_AKM_SHA256_PSK		6	/* SHA256, Pre-shared Key */
     60#define RSN_AKM_SAE			8	/* SAE */
     61#define RSN_CAP_LEN			2	/* Length of RSN capabilities */
     62#define RSN_CAP_PTK_REPLAY_CNTR_MASK	(BIT(2) | BIT(3))
     63#define RSN_CAP_MFPR_MASK		BIT(6)
     64#define RSN_CAP_MFPC_MASK		BIT(7)
     65#define RSN_PMKID_COUNT_LEN		2
     66
     67#define VNDR_IE_CMD_LEN			4	/* length of the set command
     68						 * string :"add", "del" (+ NUL)
     69						 */
     70#define VNDR_IE_COUNT_OFFSET		4
     71#define VNDR_IE_PKTFLAG_OFFSET		8
     72#define VNDR_IE_VSIE_OFFSET		12
     73#define VNDR_IE_HDR_SIZE		12
     74#define VNDR_IE_PARSE_LIMIT		5
     75
     76#define	DOT11_MGMT_HDR_LEN		24	/* d11 management header len */
     77#define	DOT11_BCN_PRB_FIXED_LEN		12	/* beacon/probe fixed length */
     78
     79#define BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS	320
     80#define BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS	400
     81#define BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS	20
     82
     83#define BRCMF_SCAN_CHANNEL_TIME		40
     84#define BRCMF_SCAN_UNASSOC_TIME		40
     85#define BRCMF_SCAN_PASSIVE_TIME		120
     86
     87#define BRCMF_ND_INFO_TIMEOUT		msecs_to_jiffies(2000)
     88
     89#define BRCMF_PS_MAX_TIMEOUT_MS		2000
     90
     91#define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
     92	(sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
     93
     94static bool check_vif_up(struct brcmf_cfg80211_vif *vif)
     95{
     96	if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state)) {
     97		brcmf_dbg(INFO, "device is not ready : status (%lu)\n",
     98			  vif->sme_state);
     99		return false;
    100	}
    101	return true;
    102}
    103
    104#define RATE_TO_BASE100KBPS(rate)   (((rate) * 10) / 2)
    105#define RATETAB_ENT(_rateid, _flags) \
    106	{                                                               \
    107		.bitrate        = RATE_TO_BASE100KBPS(_rateid),     \
    108		.hw_value       = (_rateid),                            \
    109		.flags          = (_flags),                             \
    110	}
    111
    112static struct ieee80211_rate __wl_rates[] = {
    113	RATETAB_ENT(BRCM_RATE_1M, 0),
    114	RATETAB_ENT(BRCM_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
    115	RATETAB_ENT(BRCM_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
    116	RATETAB_ENT(BRCM_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
    117	RATETAB_ENT(BRCM_RATE_6M, 0),
    118	RATETAB_ENT(BRCM_RATE_9M, 0),
    119	RATETAB_ENT(BRCM_RATE_12M, 0),
    120	RATETAB_ENT(BRCM_RATE_18M, 0),
    121	RATETAB_ENT(BRCM_RATE_24M, 0),
    122	RATETAB_ENT(BRCM_RATE_36M, 0),
    123	RATETAB_ENT(BRCM_RATE_48M, 0),
    124	RATETAB_ENT(BRCM_RATE_54M, 0),
    125};
    126
    127#define wl_g_rates		(__wl_rates + 0)
    128#define wl_g_rates_size		ARRAY_SIZE(__wl_rates)
    129#define wl_a_rates		(__wl_rates + 4)
    130#define wl_a_rates_size		(wl_g_rates_size - 4)
    131
    132#define CHAN2G(_channel, _freq) {				\
    133	.band			= NL80211_BAND_2GHZ,		\
    134	.center_freq		= (_freq),			\
    135	.hw_value		= (_channel),			\
    136	.max_antenna_gain	= 0,				\
    137	.max_power		= 30,				\
    138}
    139
    140#define CHAN5G(_channel) {					\
    141	.band			= NL80211_BAND_5GHZ,		\
    142	.center_freq		= 5000 + (5 * (_channel)),	\
    143	.hw_value		= (_channel),			\
    144	.max_antenna_gain	= 0,				\
    145	.max_power		= 30,				\
    146}
    147
    148static struct ieee80211_channel __wl_2ghz_channels[] = {
    149	CHAN2G(1, 2412), CHAN2G(2, 2417), CHAN2G(3, 2422), CHAN2G(4, 2427),
    150	CHAN2G(5, 2432), CHAN2G(6, 2437), CHAN2G(7, 2442), CHAN2G(8, 2447),
    151	CHAN2G(9, 2452), CHAN2G(10, 2457), CHAN2G(11, 2462), CHAN2G(12, 2467),
    152	CHAN2G(13, 2472), CHAN2G(14, 2484)
    153};
    154
    155static struct ieee80211_channel __wl_5ghz_channels[] = {
    156	CHAN5G(34), CHAN5G(36), CHAN5G(38), CHAN5G(40), CHAN5G(42),
    157	CHAN5G(44), CHAN5G(46), CHAN5G(48), CHAN5G(52), CHAN5G(56),
    158	CHAN5G(60), CHAN5G(64), CHAN5G(100), CHAN5G(104), CHAN5G(108),
    159	CHAN5G(112), CHAN5G(116), CHAN5G(120), CHAN5G(124), CHAN5G(128),
    160	CHAN5G(132), CHAN5G(136), CHAN5G(140), CHAN5G(144), CHAN5G(149),
    161	CHAN5G(153), CHAN5G(157), CHAN5G(161), CHAN5G(165)
    162};
    163
    164/* Band templates duplicated per wiphy. The channel info
    165 * above is added to the band during setup.
    166 */
    167static const struct ieee80211_supported_band __wl_band_2ghz = {
    168	.band = NL80211_BAND_2GHZ,
    169	.bitrates = wl_g_rates,
    170	.n_bitrates = wl_g_rates_size,
    171};
    172
    173static const struct ieee80211_supported_band __wl_band_5ghz = {
    174	.band = NL80211_BAND_5GHZ,
    175	.bitrates = wl_a_rates,
    176	.n_bitrates = wl_a_rates_size,
    177};
    178
    179/* This is to override regulatory domains defined in cfg80211 module (reg.c)
    180 * By default world regulatory domain defined in reg.c puts the flags
    181 * NL80211_RRF_NO_IR for 5GHz channels (for * 36..48 and 149..165).
    182 * With respect to these flags, wpa_supplicant doesn't * start p2p
    183 * operations on 5GHz channels. All the changes in world regulatory
    184 * domain are to be done here.
    185 */
    186static const struct ieee80211_regdomain brcmf_regdom = {
    187	.n_reg_rules = 4,
    188	.alpha2 =  "99",
    189	.reg_rules = {
    190		/* IEEE 802.11b/g, channels 1..11 */
    191		REG_RULE(2412-10, 2472+10, 40, 6, 20, 0),
    192		/* If any */
    193		/* IEEE 802.11 channel 14 - Only JP enables
    194		 * this and for 802.11b only
    195		 */
    196		REG_RULE(2484-10, 2484+10, 20, 6, 20, 0),
    197		/* IEEE 802.11a, channel 36..64 */
    198		REG_RULE(5150-10, 5350+10, 160, 6, 20, 0),
    199		/* IEEE 802.11a, channel 100..165 */
    200		REG_RULE(5470-10, 5850+10, 160, 6, 20, 0), }
    201};
    202
    203/* Note: brcmf_cipher_suites is an array of int defining which cipher suites
    204 * are supported. A pointer to this array and the number of entries is passed
    205 * on to upper layers. AES_CMAC defines whether or not the driver supports MFP.
    206 * So the cipher suite AES_CMAC has to be the last one in the array, and when
    207 * device does not support MFP then the number of suites will be decreased by 1
    208 */
    209static const u32 brcmf_cipher_suites[] = {
    210	WLAN_CIPHER_SUITE_WEP40,
    211	WLAN_CIPHER_SUITE_WEP104,
    212	WLAN_CIPHER_SUITE_TKIP,
    213	WLAN_CIPHER_SUITE_CCMP,
    214	/* Keep as last entry: */
    215	WLAN_CIPHER_SUITE_AES_CMAC
    216};
    217
    218/* Vendor specific ie. id = 221, oui and type defines exact ie */
    219struct brcmf_vs_tlv {
    220	u8 id;
    221	u8 len;
    222	u8 oui[3];
    223	u8 oui_type;
    224};
    225
    226struct parsed_vndr_ie_info {
    227	u8 *ie_ptr;
    228	u32 ie_len;	/* total length including id & length field */
    229	struct brcmf_vs_tlv vndrie;
    230};
    231
    232struct parsed_vndr_ies {
    233	u32 count;
    234	struct parsed_vndr_ie_info ie_info[VNDR_IE_PARSE_LIMIT];
    235};
    236
    237static u8 nl80211_band_to_fwil(enum nl80211_band band)
    238{
    239	switch (band) {
    240	case NL80211_BAND_2GHZ:
    241		return WLC_BAND_2G;
    242	case NL80211_BAND_5GHZ:
    243		return WLC_BAND_5G;
    244	default:
    245		WARN_ON(1);
    246		break;
    247	}
    248	return 0;
    249}
    250
    251static u16 chandef_to_chanspec(struct brcmu_d11inf *d11inf,
    252			       struct cfg80211_chan_def *ch)
    253{
    254	struct brcmu_chan ch_inf;
    255	s32 primary_offset;
    256
    257	brcmf_dbg(TRACE, "chandef: control %d center %d width %d\n",
    258		  ch->chan->center_freq, ch->center_freq1, ch->width);
    259	ch_inf.chnum = ieee80211_frequency_to_channel(ch->center_freq1);
    260	primary_offset = ch->chan->center_freq - ch->center_freq1;
    261	switch (ch->width) {
    262	case NL80211_CHAN_WIDTH_20:
    263	case NL80211_CHAN_WIDTH_20_NOHT:
    264		ch_inf.bw = BRCMU_CHAN_BW_20;
    265		WARN_ON(primary_offset != 0);
    266		break;
    267	case NL80211_CHAN_WIDTH_40:
    268		ch_inf.bw = BRCMU_CHAN_BW_40;
    269		if (primary_offset > 0)
    270			ch_inf.sb = BRCMU_CHAN_SB_U;
    271		else
    272			ch_inf.sb = BRCMU_CHAN_SB_L;
    273		break;
    274	case NL80211_CHAN_WIDTH_80:
    275		ch_inf.bw = BRCMU_CHAN_BW_80;
    276		if (primary_offset == -30)
    277			ch_inf.sb = BRCMU_CHAN_SB_LL;
    278		else if (primary_offset == -10)
    279			ch_inf.sb = BRCMU_CHAN_SB_LU;
    280		else if (primary_offset == 10)
    281			ch_inf.sb = BRCMU_CHAN_SB_UL;
    282		else
    283			ch_inf.sb = BRCMU_CHAN_SB_UU;
    284		break;
    285	case NL80211_CHAN_WIDTH_160:
    286		ch_inf.bw = BRCMU_CHAN_BW_160;
    287		if (primary_offset == -70)
    288			ch_inf.sb = BRCMU_CHAN_SB_LLL;
    289		else if (primary_offset == -50)
    290			ch_inf.sb = BRCMU_CHAN_SB_LLU;
    291		else if (primary_offset == -30)
    292			ch_inf.sb = BRCMU_CHAN_SB_LUL;
    293		else if (primary_offset == -10)
    294			ch_inf.sb = BRCMU_CHAN_SB_LUU;
    295		else if (primary_offset == 10)
    296			ch_inf.sb = BRCMU_CHAN_SB_ULL;
    297		else if (primary_offset == 30)
    298			ch_inf.sb = BRCMU_CHAN_SB_ULU;
    299		else if (primary_offset == 50)
    300			ch_inf.sb = BRCMU_CHAN_SB_UUL;
    301		else
    302			ch_inf.sb = BRCMU_CHAN_SB_UUU;
    303		break;
    304	case NL80211_CHAN_WIDTH_80P80:
    305	case NL80211_CHAN_WIDTH_5:
    306	case NL80211_CHAN_WIDTH_10:
    307	default:
    308		WARN_ON_ONCE(1);
    309	}
    310	switch (ch->chan->band) {
    311	case NL80211_BAND_2GHZ:
    312		ch_inf.band = BRCMU_CHAN_BAND_2G;
    313		break;
    314	case NL80211_BAND_5GHZ:
    315		ch_inf.band = BRCMU_CHAN_BAND_5G;
    316		break;
    317	case NL80211_BAND_60GHZ:
    318	default:
    319		WARN_ON_ONCE(1);
    320	}
    321	d11inf->encchspec(&ch_inf);
    322
    323	brcmf_dbg(TRACE, "chanspec: 0x%x\n", ch_inf.chspec);
    324	return ch_inf.chspec;
    325}
    326
    327u16 channel_to_chanspec(struct brcmu_d11inf *d11inf,
    328			struct ieee80211_channel *ch)
    329{
    330	struct brcmu_chan ch_inf;
    331
    332	ch_inf.chnum = ieee80211_frequency_to_channel(ch->center_freq);
    333	ch_inf.bw = BRCMU_CHAN_BW_20;
    334	d11inf->encchspec(&ch_inf);
    335
    336	return ch_inf.chspec;
    337}
    338
    339/* Traverse a string of 1-byte tag/1-byte length/variable-length value
    340 * triples, returning a pointer to the substring whose first element
    341 * matches tag
    342 */
    343static const struct brcmf_tlv *
    344brcmf_parse_tlvs(const void *buf, int buflen, uint key)
    345{
    346	const struct brcmf_tlv *elt = buf;
    347	int totlen = buflen;
    348
    349	/* find tagged parameter */
    350	while (totlen >= TLV_HDR_LEN) {
    351		int len = elt->len;
    352
    353		/* validate remaining totlen */
    354		if ((elt->id == key) && (totlen >= (len + TLV_HDR_LEN)))
    355			return elt;
    356
    357		elt = (struct brcmf_tlv *)((u8 *)elt + (len + TLV_HDR_LEN));
    358		totlen -= (len + TLV_HDR_LEN);
    359	}
    360
    361	return NULL;
    362}
    363
    364/* Is any of the tlvs the expected entry? If
    365 * not update the tlvs buffer pointer/length.
    366 */
    367static bool
    368brcmf_tlv_has_ie(const u8 *ie, const u8 **tlvs, u32 *tlvs_len,
    369		 const u8 *oui, u32 oui_len, u8 type)
    370{
    371	/* If the contents match the OUI and the type */
    372	if (ie[TLV_LEN_OFF] >= oui_len + 1 &&
    373	    !memcmp(&ie[TLV_BODY_OFF], oui, oui_len) &&
    374	    type == ie[TLV_BODY_OFF + oui_len]) {
    375		return true;
    376	}
    377
    378	if (tlvs == NULL)
    379		return false;
    380	/* point to the next ie */
    381	ie += ie[TLV_LEN_OFF] + TLV_HDR_LEN;
    382	/* calculate the length of the rest of the buffer */
    383	*tlvs_len -= (int)(ie - *tlvs);
    384	/* update the pointer to the start of the buffer */
    385	*tlvs = ie;
    386
    387	return false;
    388}
    389
    390static struct brcmf_vs_tlv *
    391brcmf_find_wpaie(const u8 *parse, u32 len)
    392{
    393	const struct brcmf_tlv *ie;
    394
    395	while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
    396		if (brcmf_tlv_has_ie((const u8 *)ie, &parse, &len,
    397				     WPA_OUI, TLV_OUI_LEN, WPA_OUI_TYPE))
    398			return (struct brcmf_vs_tlv *)ie;
    399	}
    400	return NULL;
    401}
    402
    403static struct brcmf_vs_tlv *
    404brcmf_find_wpsie(const u8 *parse, u32 len)
    405{
    406	const struct brcmf_tlv *ie;
    407
    408	while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
    409		if (brcmf_tlv_has_ie((u8 *)ie, &parse, &len,
    410				     WPA_OUI, TLV_OUI_LEN, WPS_OUI_TYPE))
    411			return (struct brcmf_vs_tlv *)ie;
    412	}
    413	return NULL;
    414}
    415
    416static int brcmf_vif_change_validate(struct brcmf_cfg80211_info *cfg,
    417				     struct brcmf_cfg80211_vif *vif,
    418				     enum nl80211_iftype new_type)
    419{
    420	struct brcmf_cfg80211_vif *pos;
    421	bool check_combos = false;
    422	int ret = 0;
    423	struct iface_combination_params params = {
    424		.num_different_channels = 1,
    425	};
    426
    427	list_for_each_entry(pos, &cfg->vif_list, list)
    428		if (pos == vif) {
    429			params.iftype_num[new_type]++;
    430		} else {
    431			/* concurrent interfaces so need check combinations */
    432			check_combos = true;
    433			params.iftype_num[pos->wdev.iftype]++;
    434		}
    435
    436	if (check_combos)
    437		ret = cfg80211_check_combinations(cfg->wiphy, &params);
    438
    439	return ret;
    440}
    441
    442static int brcmf_vif_add_validate(struct brcmf_cfg80211_info *cfg,
    443				  enum nl80211_iftype new_type)
    444{
    445	struct brcmf_cfg80211_vif *pos;
    446	struct iface_combination_params params = {
    447		.num_different_channels = 1,
    448	};
    449
    450	list_for_each_entry(pos, &cfg->vif_list, list)
    451		params.iftype_num[pos->wdev.iftype]++;
    452
    453	params.iftype_num[new_type]++;
    454	return cfg80211_check_combinations(cfg->wiphy, &params);
    455}
    456
    457static void convert_key_from_CPU(struct brcmf_wsec_key *key,
    458				 struct brcmf_wsec_key_le *key_le)
    459{
    460	key_le->index = cpu_to_le32(key->index);
    461	key_le->len = cpu_to_le32(key->len);
    462	key_le->algo = cpu_to_le32(key->algo);
    463	key_le->flags = cpu_to_le32(key->flags);
    464	key_le->rxiv.hi = cpu_to_le32(key->rxiv.hi);
    465	key_le->rxiv.lo = cpu_to_le16(key->rxiv.lo);
    466	key_le->iv_initialized = cpu_to_le32(key->iv_initialized);
    467	memcpy(key_le->data, key->data, sizeof(key->data));
    468	memcpy(key_le->ea, key->ea, sizeof(key->ea));
    469}
    470
    471static int
    472send_key_to_dongle(struct brcmf_if *ifp, struct brcmf_wsec_key *key)
    473{
    474	struct brcmf_pub *drvr = ifp->drvr;
    475	int err;
    476	struct brcmf_wsec_key_le key_le;
    477
    478	convert_key_from_CPU(key, &key_le);
    479
    480	brcmf_netdev_wait_pend8021x(ifp);
    481
    482	err = brcmf_fil_bsscfg_data_set(ifp, "wsec_key", &key_le,
    483					sizeof(key_le));
    484
    485	if (err)
    486		bphy_err(drvr, "wsec_key error (%d)\n", err);
    487	return err;
    488}
    489
    490static void
    491brcmf_cfg80211_update_proto_addr_mode(struct wireless_dev *wdev)
    492{
    493	struct brcmf_cfg80211_vif *vif;
    494	struct brcmf_if *ifp;
    495
    496	vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
    497	ifp = vif->ifp;
    498
    499	if ((wdev->iftype == NL80211_IFTYPE_ADHOC) ||
    500	    (wdev->iftype == NL80211_IFTYPE_AP) ||
    501	    (wdev->iftype == NL80211_IFTYPE_P2P_GO))
    502		brcmf_proto_configure_addr_mode(ifp->drvr, ifp->ifidx,
    503						ADDR_DIRECT);
    504	else
    505		brcmf_proto_configure_addr_mode(ifp->drvr, ifp->ifidx,
    506						ADDR_INDIRECT);
    507}
    508
    509static int brcmf_get_first_free_bsscfgidx(struct brcmf_pub *drvr)
    510{
    511	int bsscfgidx;
    512
    513	for (bsscfgidx = 0; bsscfgidx < BRCMF_MAX_IFS; bsscfgidx++) {
    514		/* bsscfgidx 1 is reserved for legacy P2P */
    515		if (bsscfgidx == 1)
    516			continue;
    517		if (!drvr->iflist[bsscfgidx])
    518			return bsscfgidx;
    519	}
    520
    521	return -ENOMEM;
    522}
    523
    524static int brcmf_cfg80211_request_ap_if(struct brcmf_if *ifp)
    525{
    526	struct brcmf_pub *drvr = ifp->drvr;
    527	struct brcmf_mbss_ssid_le mbss_ssid_le;
    528	int bsscfgidx;
    529	int err;
    530
    531	memset(&mbss_ssid_le, 0, sizeof(mbss_ssid_le));
    532	bsscfgidx = brcmf_get_first_free_bsscfgidx(ifp->drvr);
    533	if (bsscfgidx < 0)
    534		return bsscfgidx;
    535
    536	mbss_ssid_le.bsscfgidx = cpu_to_le32(bsscfgidx);
    537	mbss_ssid_le.SSID_len = cpu_to_le32(5);
    538	sprintf(mbss_ssid_le.SSID, "ssid%d" , bsscfgidx);
    539
    540	err = brcmf_fil_bsscfg_data_set(ifp, "bsscfg:ssid", &mbss_ssid_le,
    541					sizeof(mbss_ssid_le));
    542	if (err < 0)
    543		bphy_err(drvr, "setting ssid failed %d\n", err);
    544
    545	return err;
    546}
    547
    548/**
    549 * brcmf_ap_add_vif() - create a new AP virtual interface for multiple BSS
    550 *
    551 * @wiphy: wiphy device of new interface.
    552 * @name: name of the new interface.
    553 * @params: contains mac address for AP device.
    554 */
    555static
    556struct wireless_dev *brcmf_ap_add_vif(struct wiphy *wiphy, const char *name,
    557				      struct vif_params *params)
    558{
    559	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
    560	struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
    561	struct brcmf_pub *drvr = cfg->pub;
    562	struct brcmf_cfg80211_vif *vif;
    563	int err;
    564
    565	if (brcmf_cfg80211_vif_event_armed(cfg))
    566		return ERR_PTR(-EBUSY);
    567
    568	brcmf_dbg(INFO, "Adding vif \"%s\"\n", name);
    569
    570	vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_AP);
    571	if (IS_ERR(vif))
    572		return (struct wireless_dev *)vif;
    573
    574	brcmf_cfg80211_arm_vif_event(cfg, vif);
    575
    576	err = brcmf_cfg80211_request_ap_if(ifp);
    577	if (err) {
    578		brcmf_cfg80211_arm_vif_event(cfg, NULL);
    579		goto fail;
    580	}
    581
    582	/* wait for firmware event */
    583	err = brcmf_cfg80211_wait_vif_event(cfg, BRCMF_E_IF_ADD,
    584					    BRCMF_VIF_EVENT_TIMEOUT);
    585	brcmf_cfg80211_arm_vif_event(cfg, NULL);
    586	if (!err) {
    587		bphy_err(drvr, "timeout occurred\n");
    588		err = -EIO;
    589		goto fail;
    590	}
    591
    592	/* interface created in firmware */
    593	ifp = vif->ifp;
    594	if (!ifp) {
    595		bphy_err(drvr, "no if pointer provided\n");
    596		err = -ENOENT;
    597		goto fail;
    598	}
    599
    600	strncpy(ifp->ndev->name, name, sizeof(ifp->ndev->name) - 1);
    601	err = brcmf_net_attach(ifp, true);
    602	if (err) {
    603		bphy_err(drvr, "Registering netdevice failed\n");
    604		free_netdev(ifp->ndev);
    605		goto fail;
    606	}
    607
    608	return &ifp->vif->wdev;
    609
    610fail:
    611	brcmf_free_vif(vif);
    612	return ERR_PTR(err);
    613}
    614
    615static bool brcmf_is_apmode(struct brcmf_cfg80211_vif *vif)
    616{
    617	enum nl80211_iftype iftype;
    618
    619	iftype = vif->wdev.iftype;
    620	return iftype == NL80211_IFTYPE_AP || iftype == NL80211_IFTYPE_P2P_GO;
    621}
    622
    623static bool brcmf_is_ibssmode(struct brcmf_cfg80211_vif *vif)
    624{
    625	return vif->wdev.iftype == NL80211_IFTYPE_ADHOC;
    626}
    627
    628/**
    629 * brcmf_mon_add_vif() - create monitor mode virtual interface
    630 *
    631 * @wiphy: wiphy device of new interface.
    632 * @name: name of the new interface.
    633 */
    634static struct wireless_dev *brcmf_mon_add_vif(struct wiphy *wiphy,
    635					      const char *name)
    636{
    637	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
    638	struct brcmf_cfg80211_vif *vif;
    639	struct net_device *ndev;
    640	struct brcmf_if *ifp;
    641	int err;
    642
    643	if (cfg->pub->mon_if) {
    644		err = -EEXIST;
    645		goto err_out;
    646	}
    647
    648	vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_MONITOR);
    649	if (IS_ERR(vif)) {
    650		err = PTR_ERR(vif);
    651		goto err_out;
    652	}
    653
    654	ndev = alloc_netdev(sizeof(*ifp), name, NET_NAME_UNKNOWN, ether_setup);
    655	if (!ndev) {
    656		err = -ENOMEM;
    657		goto err_free_vif;
    658	}
    659	ndev->type = ARPHRD_IEEE80211_RADIOTAP;
    660	ndev->ieee80211_ptr = &vif->wdev;
    661	ndev->needs_free_netdev = true;
    662	ndev->priv_destructor = brcmf_cfg80211_free_netdev;
    663	SET_NETDEV_DEV(ndev, wiphy_dev(cfg->wiphy));
    664
    665	ifp = netdev_priv(ndev);
    666	ifp->vif = vif;
    667	ifp->ndev = ndev;
    668	ifp->drvr = cfg->pub;
    669
    670	vif->ifp = ifp;
    671	vif->wdev.netdev = ndev;
    672
    673	err = brcmf_net_mon_attach(ifp);
    674	if (err) {
    675		brcmf_err("Failed to attach %s device\n", ndev->name);
    676		free_netdev(ndev);
    677		goto err_free_vif;
    678	}
    679
    680	cfg->pub->mon_if = ifp;
    681
    682	return &vif->wdev;
    683
    684err_free_vif:
    685	brcmf_free_vif(vif);
    686err_out:
    687	return ERR_PTR(err);
    688}
    689
    690static int brcmf_mon_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev)
    691{
    692	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
    693	struct net_device *ndev = wdev->netdev;
    694
    695	ndev->netdev_ops->ndo_stop(ndev);
    696
    697	brcmf_net_detach(ndev, true);
    698
    699	cfg->pub->mon_if = NULL;
    700
    701	return 0;
    702}
    703
    704static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy,
    705						     const char *name,
    706						     unsigned char name_assign_type,
    707						     enum nl80211_iftype type,
    708						     struct vif_params *params)
    709{
    710	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
    711	struct brcmf_pub *drvr = cfg->pub;
    712	struct wireless_dev *wdev;
    713	int err;
    714
    715	brcmf_dbg(TRACE, "enter: %s type %d\n", name, type);
    716	err = brcmf_vif_add_validate(wiphy_to_cfg(wiphy), type);
    717	if (err) {
    718		bphy_err(drvr, "iface validation failed: err=%d\n", err);
    719		return ERR_PTR(err);
    720	}
    721	switch (type) {
    722	case NL80211_IFTYPE_ADHOC:
    723	case NL80211_IFTYPE_STATION:
    724	case NL80211_IFTYPE_AP_VLAN:
    725	case NL80211_IFTYPE_WDS:
    726	case NL80211_IFTYPE_MESH_POINT:
    727		return ERR_PTR(-EOPNOTSUPP);
    728	case NL80211_IFTYPE_MONITOR:
    729		return brcmf_mon_add_vif(wiphy, name);
    730	case NL80211_IFTYPE_AP:
    731		wdev = brcmf_ap_add_vif(wiphy, name, params);
    732		break;
    733	case NL80211_IFTYPE_P2P_CLIENT:
    734	case NL80211_IFTYPE_P2P_GO:
    735	case NL80211_IFTYPE_P2P_DEVICE:
    736		wdev = brcmf_p2p_add_vif(wiphy, name, name_assign_type, type, params);
    737		break;
    738	case NL80211_IFTYPE_UNSPECIFIED:
    739	default:
    740		return ERR_PTR(-EINVAL);
    741	}
    742
    743	if (IS_ERR(wdev))
    744		bphy_err(drvr, "add iface %s type %d failed: err=%d\n", name,
    745			 type, (int)PTR_ERR(wdev));
    746	else
    747		brcmf_cfg80211_update_proto_addr_mode(wdev);
    748
    749	return wdev;
    750}
    751
    752static void brcmf_scan_config_mpc(struct brcmf_if *ifp, int mpc)
    753{
    754	if (brcmf_feat_is_quirk_enabled(ifp, BRCMF_FEAT_QUIRK_NEED_MPC))
    755		brcmf_set_mpc(ifp, mpc);
    756}
    757
    758void brcmf_set_mpc(struct brcmf_if *ifp, int mpc)
    759{
    760	struct brcmf_pub *drvr = ifp->drvr;
    761	s32 err = 0;
    762
    763	if (check_vif_up(ifp->vif)) {
    764		err = brcmf_fil_iovar_int_set(ifp, "mpc", mpc);
    765		if (err) {
    766			bphy_err(drvr, "fail to set mpc\n");
    767			return;
    768		}
    769		brcmf_dbg(INFO, "MPC : %d\n", mpc);
    770	}
    771}
    772
    773s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
    774				struct brcmf_if *ifp, bool aborted,
    775				bool fw_abort)
    776{
    777	struct brcmf_pub *drvr = cfg->pub;
    778	struct brcmf_scan_params_le params_le;
    779	struct cfg80211_scan_request *scan_request;
    780	u64 reqid;
    781	u32 bucket;
    782	s32 err = 0;
    783
    784	brcmf_dbg(SCAN, "Enter\n");
    785
    786	/* clear scan request, because the FW abort can cause a second call */
    787	/* to this functon and might cause a double cfg80211_scan_done      */
    788	scan_request = cfg->scan_request;
    789	cfg->scan_request = NULL;
    790
    791	if (timer_pending(&cfg->escan_timeout))
    792		del_timer_sync(&cfg->escan_timeout);
    793
    794	if (fw_abort) {
    795		/* Do a scan abort to stop the driver's scan engine */
    796		brcmf_dbg(SCAN, "ABORT scan in firmware\n");
    797		memset(&params_le, 0, sizeof(params_le));
    798		eth_broadcast_addr(params_le.bssid);
    799		params_le.bss_type = DOT11_BSSTYPE_ANY;
    800		params_le.scan_type = 0;
    801		params_le.channel_num = cpu_to_le32(1);
    802		params_le.nprobes = cpu_to_le32(1);
    803		params_le.active_time = cpu_to_le32(-1);
    804		params_le.passive_time = cpu_to_le32(-1);
    805		params_le.home_time = cpu_to_le32(-1);
    806		/* Scan is aborted by setting channel_list[0] to -1 */
    807		params_le.channel_list[0] = cpu_to_le16(-1);
    808		/* E-Scan (or anyother type) can be aborted by SCAN */
    809		err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
    810					     &params_le, sizeof(params_le));
    811		if (err)
    812			bphy_err(drvr, "Scan abort failed\n");
    813	}
    814
    815	brcmf_scan_config_mpc(ifp, 1);
    816
    817	/*
    818	 * e-scan can be initiated internally
    819	 * which takes precedence.
    820	 */
    821	if (cfg->int_escan_map) {
    822		brcmf_dbg(SCAN, "scheduled scan completed (%x)\n",
    823			  cfg->int_escan_map);
    824		while (cfg->int_escan_map) {
    825			bucket = __ffs(cfg->int_escan_map);
    826			cfg->int_escan_map &= ~BIT(bucket);
    827			reqid = brcmf_pno_find_reqid_by_bucket(cfg->pno,
    828							       bucket);
    829			if (!aborted) {
    830				brcmf_dbg(SCAN, "report results: reqid=%llu\n",
    831					  reqid);
    832				cfg80211_sched_scan_results(cfg_to_wiphy(cfg),
    833							    reqid);
    834			}
    835		}
    836	} else if (scan_request) {
    837		struct cfg80211_scan_info info = {
    838			.aborted = aborted,
    839		};
    840
    841		brcmf_dbg(SCAN, "ESCAN Completed scan: %s\n",
    842			  aborted ? "Aborted" : "Done");
    843		cfg80211_scan_done(scan_request, &info);
    844	}
    845	if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
    846		brcmf_dbg(SCAN, "Scan complete, probably P2P scan\n");
    847
    848	return err;
    849}
    850
    851static int brcmf_cfg80211_del_ap_iface(struct wiphy *wiphy,
    852				       struct wireless_dev *wdev)
    853{
    854	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
    855	struct net_device *ndev = wdev->netdev;
    856	struct brcmf_if *ifp = netdev_priv(ndev);
    857	struct brcmf_pub *drvr = cfg->pub;
    858	int ret;
    859	int err;
    860
    861	brcmf_cfg80211_arm_vif_event(cfg, ifp->vif);
    862
    863	err = brcmf_fil_bsscfg_data_set(ifp, "interface_remove", NULL, 0);
    864	if (err) {
    865		bphy_err(drvr, "interface_remove failed %d\n", err);
    866		goto err_unarm;
    867	}
    868
    869	/* wait for firmware event */
    870	ret = brcmf_cfg80211_wait_vif_event(cfg, BRCMF_E_IF_DEL,
    871					    BRCMF_VIF_EVENT_TIMEOUT);
    872	if (!ret) {
    873		bphy_err(drvr, "timeout occurred\n");
    874		err = -EIO;
    875		goto err_unarm;
    876	}
    877
    878	brcmf_remove_interface(ifp, true);
    879
    880err_unarm:
    881	brcmf_cfg80211_arm_vif_event(cfg, NULL);
    882	return err;
    883}
    884
    885static
    886int brcmf_cfg80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev)
    887{
    888	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
    889	struct net_device *ndev = wdev->netdev;
    890
    891	if (ndev && ndev == cfg_to_ndev(cfg))
    892		return -ENOTSUPP;
    893
    894	/* vif event pending in firmware */
    895	if (brcmf_cfg80211_vif_event_armed(cfg))
    896		return -EBUSY;
    897
    898	if (ndev) {
    899		if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status) &&
    900		    cfg->escan_info.ifp == netdev_priv(ndev))
    901			brcmf_notify_escan_complete(cfg, netdev_priv(ndev),
    902						    true, true);
    903
    904		brcmf_fil_iovar_int_set(netdev_priv(ndev), "mpc", 1);
    905	}
    906
    907	switch (wdev->iftype) {
    908	case NL80211_IFTYPE_ADHOC:
    909	case NL80211_IFTYPE_STATION:
    910	case NL80211_IFTYPE_AP_VLAN:
    911	case NL80211_IFTYPE_WDS:
    912	case NL80211_IFTYPE_MESH_POINT:
    913		return -EOPNOTSUPP;
    914	case NL80211_IFTYPE_MONITOR:
    915		return brcmf_mon_del_vif(wiphy, wdev);
    916	case NL80211_IFTYPE_AP:
    917		return brcmf_cfg80211_del_ap_iface(wiphy, wdev);
    918	case NL80211_IFTYPE_P2P_CLIENT:
    919	case NL80211_IFTYPE_P2P_GO:
    920	case NL80211_IFTYPE_P2P_DEVICE:
    921		return brcmf_p2p_del_vif(wiphy, wdev);
    922	case NL80211_IFTYPE_UNSPECIFIED:
    923	default:
    924		return -EINVAL;
    925	}
    926	return -EOPNOTSUPP;
    927}
    928
    929static s32
    930brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
    931			 enum nl80211_iftype type,
    932			 struct vif_params *params)
    933{
    934	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
    935	struct brcmf_if *ifp = netdev_priv(ndev);
    936	struct brcmf_cfg80211_vif *vif = ifp->vif;
    937	struct brcmf_pub *drvr = cfg->pub;
    938	s32 infra = 0;
    939	s32 ap = 0;
    940	s32 err = 0;
    941
    942	brcmf_dbg(TRACE, "Enter, bsscfgidx=%d, type=%d\n", ifp->bsscfgidx,
    943		  type);
    944
    945	/* WAR: There are a number of p2p interface related problems which
    946	 * need to be handled initially (before doing the validate).
    947	 * wpa_supplicant tends to do iface changes on p2p device/client/go
    948	 * which are not always possible/allowed. However we need to return
    949	 * OK otherwise the wpa_supplicant wont start. The situation differs
    950	 * on configuration and setup (p2pon=1 module param). The first check
    951	 * is to see if the request is a change to station for p2p iface.
    952	 */
    953	if ((type == NL80211_IFTYPE_STATION) &&
    954	    ((vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) ||
    955	     (vif->wdev.iftype == NL80211_IFTYPE_P2P_GO) ||
    956	     (vif->wdev.iftype == NL80211_IFTYPE_P2P_DEVICE))) {
    957		brcmf_dbg(TRACE, "Ignoring cmd for p2p if\n");
    958		/* Now depending on whether module param p2pon=1 was used the
    959		 * response needs to be either 0 or EOPNOTSUPP. The reason is
    960		 * that if p2pon=1 is used, but a newer supplicant is used then
    961		 * we should return an error, as this combination wont work.
    962		 * In other situations 0 is returned and supplicant will start
    963		 * normally. It will give a trace in cfg80211, but it is the
    964		 * only way to get it working. Unfortunately this will result
    965		 * in situation where we wont support new supplicant in
    966		 * combination with module param p2pon=1, but that is the way
    967		 * it is. If the user tries this then unloading of driver might
    968		 * fail/lock.
    969		 */
    970		if (cfg->p2p.p2pdev_dynamically)
    971			return -EOPNOTSUPP;
    972		else
    973			return 0;
    974	}
    975	err = brcmf_vif_change_validate(wiphy_to_cfg(wiphy), vif, type);
    976	if (err) {
    977		bphy_err(drvr, "iface validation failed: err=%d\n", err);
    978		return err;
    979	}
    980	switch (type) {
    981	case NL80211_IFTYPE_MONITOR:
    982	case NL80211_IFTYPE_WDS:
    983		bphy_err(drvr, "type (%d) : currently we do not support this type\n",
    984			 type);
    985		return -EOPNOTSUPP;
    986	case NL80211_IFTYPE_ADHOC:
    987		infra = 0;
    988		break;
    989	case NL80211_IFTYPE_STATION:
    990		infra = 1;
    991		break;
    992	case NL80211_IFTYPE_AP:
    993	case NL80211_IFTYPE_P2P_GO:
    994		ap = 1;
    995		break;
    996	default:
    997		err = -EINVAL;
    998		goto done;
    999	}
   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
   1023done:
   1024	brcmf_dbg(TRACE, "Exit\n");
   1025
   1026	return err;
   1027}
   1028
   1029static 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
   1099static s32
   1100brcmf_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);
   1139exit:
   1140	return err;
   1141}
   1142
   1143static s32
   1144brcmf_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
   1168static s32
   1169brcmf_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
   1230scan_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
   1237static 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
   1250static 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
   1264static 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
   1279static 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
   1319done:
   1320	brcmf_dbg(TRACE, "Exit\n");
   1321	return err;
   1322}
   1323
   1324static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof)
   1325{
   1326	memset(prof, 0, sizeof(*prof));
   1327}
   1328
   1329static 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
   1347static 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
   1369static 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
   1394static 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
   1430static s32
   1431brcmf_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
   1575done:
   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
   1582static s32
   1583brcmf_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
   1604static 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
   1633static 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
   1672static s32
   1673brcmf_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
   1749static s32
   1750brcmf_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
   1885skip_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
   1896static s32
   1897brcmf_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
   1964static
   1965enum 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
   1976static 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
   2021static s32
   2022brcmf_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
   2248done:
   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
   2255static s32
   2256brcmf_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
   2285static s32
   2286brcmf_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
   2331done:
   2332	brcmf_dbg(TRACE, "Exit %d (qdbm)\n", qdbm & ~WL_TXPWR_OVERRIDE);
   2333	return err;
   2334}
   2335
   2336static s32
   2337brcmf_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
   2357done:
   2358	brcmf_dbg(TRACE, "Exit (0x%x %d)\n", qdbm, *dbm);
   2359	return err;
   2360}
   2361
   2362static s32
   2363brcmf_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	}
   2391done:
   2392	brcmf_dbg(TRACE, "Exit\n");
   2393	return err;
   2394}
   2395
   2396static s32
   2397brcmf_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
   2433static s32
   2434brcmf_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
   2550done:
   2551	brcmf_dbg(TRACE, "Exit\n");
   2552	return err;
   2553}
   2554
   2555static s32
   2556brcmf_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
   2606done:
   2607	brcmf_dbg(TRACE, "Exit\n");
   2608	return err;
   2609}
   2610
   2611static s32
   2612brcmf_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
   2627static void
   2628brcmf_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
   2661static 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
   2682static 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
   2714out_kfree:
   2715	kfree(buf);
   2716}
   2717
   2718static s32
   2719brcmf_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
   2767static s32
   2768brcmf_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	}
   2885done:
   2886	brcmf_dbg(TRACE, "Exit\n");
   2887	return err;
   2888}
   2889
   2890static int
   2891brcmf_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
   2925static s32
   2926brcmf_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
   2972done:
   2973	brcmf_dbg(TRACE, "Exit\n");
   2974	return err;
   2975}
   2976
   2977static 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
   3042static struct brcmf_bss_info_le *
   3043next_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
   3051static 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
   3076static 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
   3150CleanUp:
   3151
   3152	kfree(buf);
   3153
   3154	brcmf_dbg(TRACE, "Exit\n");
   3155
   3156	return err;
   3157}
   3158
   3159static 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
   3204update_bss_info_out:
   3205	brcmf_dbg(TRACE, "Exit");
   3206	return err;
   3207}
   3208
   3209void 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
   3222static 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
   3232static 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
   3244static s32
   3245brcmf_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
   3283static s32
   3284brcmf_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	}
   3392exit:
   3393	return 0;
   3394}
   3395
   3396static 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
   3407static struct cfg80211_scan_request *
   3408brcmf_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
   3425static 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
   3464static 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
   3490static struct brcmf_pno_net_info_le *
   3491brcmf_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 */
   3518static s32
   3519brcmf_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
   3598out_err:
   3599	cfg80211_sched_scan_stopped(wiphy, 0);
   3600free_req:
   3601	kfree(request);
   3602	return err;
   3603}
   3604
   3605static int
   3606brcmf_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
   3632static 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
   3645static __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
   3655static 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
   3693static s32
   3694brcmf_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
   3744static 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
   3815static void brcmf_report_wowl_wakeind(struct wiphy *wiphy, struct brcmf_if *ifp)
   3816{
   3817}
   3818
   3819#endif /* CONFIG_PM */
   3820
   3821static 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
   3849static 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
   3905static 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
   3923static 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
   3974exit:
   3975	brcmf_dbg(TRACE, "Exit\n");
   3976	/* clear any scanning activity */
   3977	cfg->scan_status = 0;
   3978	return 0;
   3979}
   3980
   3981static __used s32
   3982brcmf_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
   4002static s32
   4003brcmf_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
   4042static s32
   4043brcmf_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
   4084static s32
   4085brcmf_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
   4103static 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
   4135static 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
   4143static s32
   4144brcmf_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
   4384exit:
   4385	return err;
   4386}
   4387
   4388static s32
   4389brcmf_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;
   4434next:
   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
   4445static u32
   4446brcmf_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
   4459s32 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
   4619exit:
   4620	kfree(iovar_ie_buf);
   4621	return err;
   4622}
   4623
   4624s32 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
   4640static s32
   4641brcmf_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
   4677static s32
   4678brcmf_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
   4719static s32
   4720brcmf_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
   4960exit:
   4961	if ((err) && (!mbss)) {
   4962		brcmf_set_mpc(ifp, 1);
   4963		brcmf_configure_arp_nd_offload(ifp, true);
   4964	}
   4965	return err;
   4966}
   4967
   4968static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
   4969{
   4970	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
   4971	struct brcmf_if *ifp = netdev_priv(ndev);
   4972	struct brcmf_pub *drvr = cfg->pub;
   4973	struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
   4974	s32 err;
   4975	struct brcmf_fil_bss_enable_le bss_enable;
   4976	struct brcmf_join_params join_params;
   4977
   4978	brcmf_dbg(TRACE, "Enter\n");
   4979
   4980	if (ifp->vif->wdev.iftype == NL80211_IFTYPE_AP) {
   4981		/* Due to most likely deauths outstanding we sleep */
   4982		/* first to make sure they get processed by fw. */
   4983		msleep(400);
   4984
   4985		if (profile->use_fwauth != BIT(BRCMF_PROFILE_FWAUTH_NONE)) {
   4986			if (profile->use_fwauth & BIT(BRCMF_PROFILE_FWAUTH_PSK))
   4987				brcmf_set_pmk(ifp, NULL, 0);
   4988			if (profile->use_fwauth & BIT(BRCMF_PROFILE_FWAUTH_SAE))
   4989				brcmf_set_sae_password(ifp, NULL, 0);
   4990			profile->use_fwauth = BIT(BRCMF_PROFILE_FWAUTH_NONE);
   4991		}
   4992
   4993		if (ifp->vif->mbss) {
   4994			err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
   4995			return err;
   4996		}
   4997
   4998		/* First BSS doesn't get a full reset */
   4999		if (ifp->bsscfgidx == 0)
   5000			brcmf_fil_iovar_int_set(ifp, "closednet", 0);
   5001
   5002		memset(&join_params, 0, sizeof(join_params));
   5003		err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
   5004					     &join_params, sizeof(join_params));
   5005		if (err < 0)
   5006			bphy_err(drvr, "SET SSID error (%d)\n", err);
   5007		err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
   5008		if (err < 0)
   5009			bphy_err(drvr, "BRCMF_C_DOWN error %d\n", err);
   5010		err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 0);
   5011		if (err < 0)
   5012			bphy_err(drvr, "setting AP mode failed %d\n", err);
   5013		if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS))
   5014			brcmf_fil_iovar_int_set(ifp, "mbss", 0);
   5015		brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY,
   5016				      ifp->vif->is_11d);
   5017		/* Bring device back up so it can be used again */
   5018		err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
   5019		if (err < 0)
   5020			bphy_err(drvr, "BRCMF_C_UP error %d\n", err);
   5021
   5022		brcmf_vif_clear_mgmt_ies(ifp->vif);
   5023	} else {
   5024		bss_enable.bsscfgidx = cpu_to_le32(ifp->bsscfgidx);
   5025		bss_enable.enable = cpu_to_le32(0);
   5026		err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
   5027					       sizeof(bss_enable));
   5028		if (err < 0)
   5029			bphy_err(drvr, "bss_enable config failed %d\n", err);
   5030	}
   5031	brcmf_set_mpc(ifp, 1);
   5032	brcmf_configure_arp_nd_offload(ifp, true);
   5033	clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
   5034	brcmf_net_setcarrier(ifp, false);
   5035
   5036	return err;
   5037}
   5038
   5039static s32
   5040brcmf_cfg80211_change_beacon(struct wiphy *wiphy, struct net_device *ndev,
   5041			     struct cfg80211_beacon_data *info)
   5042{
   5043	struct brcmf_if *ifp = netdev_priv(ndev);
   5044	s32 err;
   5045
   5046	brcmf_dbg(TRACE, "Enter\n");
   5047
   5048	err = brcmf_config_ap_mgmt_ie(ifp->vif, info);
   5049
   5050	return err;
   5051}
   5052
   5053static int
   5054brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev,
   5055			   struct station_del_parameters *params)
   5056{
   5057	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
   5058	struct brcmf_pub *drvr = cfg->pub;
   5059	struct brcmf_scb_val_le scbval;
   5060	struct brcmf_if *ifp = netdev_priv(ndev);
   5061	s32 err;
   5062
   5063	if (!params->mac)
   5064		return -EFAULT;
   5065
   5066	brcmf_dbg(TRACE, "Enter %pM\n", params->mac);
   5067
   5068	if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
   5069		ifp = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp;
   5070	if (!check_vif_up(ifp->vif))
   5071		return -EIO;
   5072
   5073	memcpy(&scbval.ea, params->mac, ETH_ALEN);
   5074	scbval.val = cpu_to_le32(params->reason_code);
   5075	err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON,
   5076				     &scbval, sizeof(scbval));
   5077	if (err)
   5078		bphy_err(drvr, "SCB_DEAUTHENTICATE_FOR_REASON failed %d\n",
   5079			 err);
   5080
   5081	brcmf_dbg(TRACE, "Exit\n");
   5082	return err;
   5083}
   5084
   5085static int
   5086brcmf_cfg80211_change_station(struct wiphy *wiphy, struct net_device *ndev,
   5087			      const u8 *mac, struct station_parameters *params)
   5088{
   5089	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
   5090	struct brcmf_pub *drvr = cfg->pub;
   5091	struct brcmf_if *ifp = netdev_priv(ndev);
   5092	s32 err;
   5093
   5094	brcmf_dbg(TRACE, "Enter, MAC %pM, mask 0x%04x set 0x%04x\n", mac,
   5095		  params->sta_flags_mask, params->sta_flags_set);
   5096
   5097	/* Ignore all 00 MAC */
   5098	if (is_zero_ether_addr(mac))
   5099		return 0;
   5100
   5101	if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)))
   5102		return 0;
   5103
   5104	if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
   5105		err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SCB_AUTHORIZE,
   5106					     (void *)mac, ETH_ALEN);
   5107	else
   5108		err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SCB_DEAUTHORIZE,
   5109					     (void *)mac, ETH_ALEN);
   5110	if (err < 0)
   5111		bphy_err(drvr, "Setting SCB (de-)authorize failed, %d\n", err);
   5112
   5113	return err;
   5114}
   5115
   5116static void
   5117brcmf_cfg80211_update_mgmt_frame_registrations(struct wiphy *wiphy,
   5118					       struct wireless_dev *wdev,
   5119					       struct mgmt_frame_regs *upd)
   5120{
   5121	struct brcmf_cfg80211_vif *vif;
   5122
   5123	vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
   5124
   5125	vif->mgmt_rx_reg = upd->interface_stypes;
   5126}
   5127
   5128
   5129static int
   5130brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
   5131		       struct cfg80211_mgmt_tx_params *params, u64 *cookie)
   5132{
   5133	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
   5134	struct ieee80211_channel *chan = params->chan;
   5135	struct brcmf_pub *drvr = cfg->pub;
   5136	const u8 *buf = params->buf;
   5137	size_t len = params->len;
   5138	const struct ieee80211_mgmt *mgmt;
   5139	struct brcmf_cfg80211_vif *vif;
   5140	s32 err = 0;
   5141	s32 ie_offset;
   5142	s32 ie_len;
   5143	struct brcmf_fil_action_frame_le *action_frame;
   5144	struct brcmf_fil_af_params_le *af_params;
   5145	bool ack;
   5146	s32 chan_nr;
   5147	u32 freq;
   5148
   5149	brcmf_dbg(TRACE, "Enter\n");
   5150
   5151	*cookie = 0;
   5152
   5153	mgmt = (const struct ieee80211_mgmt *)buf;
   5154
   5155	if (!ieee80211_is_mgmt(mgmt->frame_control)) {
   5156		bphy_err(drvr, "Driver only allows MGMT packet type\n");
   5157		return -EPERM;
   5158	}
   5159
   5160	vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
   5161
   5162	if (ieee80211_is_probe_resp(mgmt->frame_control)) {
   5163		/* Right now the only reason to get a probe response */
   5164		/* is for p2p listen response or for p2p GO from     */
   5165		/* wpa_supplicant. Unfortunately the probe is send   */
   5166		/* on primary ndev, while dongle wants it on the p2p */
   5167		/* vif. Since this is only reason for a probe        */
   5168		/* response to be sent, the vif is taken from cfg.   */
   5169		/* If ever desired to send proberesp for non p2p     */
   5170		/* response then data should be checked for          */
   5171		/* "DIRECT-". Note in future supplicant will take    */
   5172		/* dedicated p2p wdev to do this and then this 'hack'*/
   5173		/* is not needed anymore.                            */
   5174		ie_offset =  DOT11_MGMT_HDR_LEN +
   5175			     DOT11_BCN_PRB_FIXED_LEN;
   5176		ie_len = len - ie_offset;
   5177		if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif)
   5178			vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
   5179		err = brcmf_vif_set_mgmt_ie(vif,
   5180					    BRCMF_VNDR_IE_PRBRSP_FLAG,
   5181					    &buf[ie_offset],
   5182					    ie_len);
   5183		cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, true,
   5184					GFP_KERNEL);
   5185	} else if (ieee80211_is_action(mgmt->frame_control)) {
   5186		if (len > BRCMF_FIL_ACTION_FRAME_SIZE + DOT11_MGMT_HDR_LEN) {
   5187			bphy_err(drvr, "invalid action frame length\n");
   5188			err = -EINVAL;
   5189			goto exit;
   5190		}
   5191		af_params = kzalloc(sizeof(*af_params), GFP_KERNEL);
   5192		if (af_params == NULL) {
   5193			bphy_err(drvr, "unable to allocate frame\n");
   5194			err = -ENOMEM;
   5195			goto exit;
   5196		}
   5197		action_frame = &af_params->action_frame;
   5198		/* Add the packet Id */
   5199		action_frame->packet_id = cpu_to_le32(*cookie);
   5200		/* Add BSSID */
   5201		memcpy(&action_frame->da[0], &mgmt->da[0], ETH_ALEN);
   5202		memcpy(&af_params->bssid[0], &mgmt->bssid[0], ETH_ALEN);
   5203		/* Add the length exepted for 802.11 header  */
   5204		action_frame->len = cpu_to_le16(len - DOT11_MGMT_HDR_LEN);
   5205		/* Add the channel. Use the one specified as parameter if any or
   5206		 * the current one (got from the firmware) otherwise
   5207		 */
   5208		if (chan)
   5209			freq = chan->center_freq;
   5210		else
   5211			brcmf_fil_cmd_int_get(vif->ifp, BRCMF_C_GET_CHANNEL,
   5212					      &freq);
   5213		chan_nr = ieee80211_frequency_to_channel(freq);
   5214		af_params->channel = cpu_to_le32(chan_nr);
   5215		af_params->dwell_time = cpu_to_le32(params->wait);
   5216		memcpy(action_frame->data, &buf[DOT11_MGMT_HDR_LEN],
   5217		       le16_to_cpu(action_frame->len));
   5218
   5219		brcmf_dbg(TRACE, "Action frame, cookie=%lld, len=%d, freq=%d\n",
   5220			  *cookie, le16_to_cpu(action_frame->len), freq);
   5221
   5222		ack = brcmf_p2p_send_action_frame(cfg, cfg_to_ndev(cfg),
   5223						  af_params);
   5224
   5225		cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, ack,
   5226					GFP_KERNEL);
   5227		kfree(af_params);
   5228	} else {
   5229		brcmf_dbg(TRACE, "Unhandled, fc=%04x!!\n", mgmt->frame_control);
   5230		brcmf_dbg_hex_dump(true, buf, len, "payload, len=%zu\n", len);
   5231	}
   5232
   5233exit:
   5234	return err;
   5235}
   5236
   5237static int brcmf_cfg80211_set_cqm_rssi_range_config(struct wiphy *wiphy,
   5238						    struct net_device *ndev,
   5239						    s32 rssi_low, s32 rssi_high)
   5240{
   5241	struct brcmf_cfg80211_vif *vif;
   5242	struct brcmf_if *ifp;
   5243	int err = 0;
   5244
   5245	brcmf_dbg(TRACE, "low=%d high=%d", rssi_low, rssi_high);
   5246
   5247	ifp = netdev_priv(ndev);
   5248	vif = ifp->vif;
   5249
   5250	if (rssi_low != vif->cqm_rssi_low || rssi_high != vif->cqm_rssi_high) {
   5251		/* The firmware will send an event when the RSSI is less than or
   5252		 * equal to a configured level and the previous RSSI event was
   5253		 * less than or equal to a different level. Set a third level
   5254		 * so that we also detect the transition from rssi <= rssi_high
   5255		 * to rssi > rssi_high.
   5256		 */
   5257		struct brcmf_rssi_event_le config = {
   5258			.rate_limit_msec = cpu_to_le32(0),
   5259			.rssi_level_num = 3,
   5260			.rssi_levels = {
   5261				clamp_val(rssi_low, S8_MIN, S8_MAX - 2),
   5262				clamp_val(rssi_high, S8_MIN + 1, S8_MAX - 1),
   5263				S8_MAX,
   5264			},
   5265		};
   5266
   5267		err = brcmf_fil_iovar_data_set(ifp, "rssi_event", &config,
   5268					       sizeof(config));
   5269		if (err) {
   5270			err = -EINVAL;
   5271		} else {
   5272			vif->cqm_rssi_low = rssi_low;
   5273			vif->cqm_rssi_high = rssi_high;
   5274		}
   5275	}
   5276
   5277	return err;
   5278}
   5279
   5280static int
   5281brcmf_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
   5282					struct wireless_dev *wdev,
   5283					u64 cookie)
   5284{
   5285	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
   5286	struct brcmf_pub *drvr = cfg->pub;
   5287	struct brcmf_cfg80211_vif *vif;
   5288	int err = 0;
   5289
   5290	brcmf_dbg(TRACE, "Enter p2p listen cancel\n");
   5291
   5292	vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
   5293	if (vif == NULL) {
   5294		bphy_err(drvr, "No p2p device available for probe response\n");
   5295		err = -ENODEV;
   5296		goto exit;
   5297	}
   5298	brcmf_p2p_cancel_remain_on_channel(vif->ifp);
   5299exit:
   5300	return err;
   5301}
   5302
   5303static int brcmf_cfg80211_get_channel(struct wiphy *wiphy,
   5304				      struct wireless_dev *wdev,
   5305				      struct cfg80211_chan_def *chandef)
   5306{
   5307	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
   5308	struct net_device *ndev = wdev->netdev;
   5309	struct brcmf_pub *drvr = cfg->pub;
   5310	struct brcmu_chan ch;
   5311	enum nl80211_band band = 0;
   5312	enum nl80211_chan_width width = 0;
   5313	u32 chanspec;
   5314	int freq, err;
   5315
   5316	if (!ndev || drvr->bus_if->state != BRCMF_BUS_UP)
   5317		return -ENODEV;
   5318
   5319	err = brcmf_fil_iovar_int_get(netdev_priv(ndev), "chanspec", &chanspec);
   5320	if (err) {
   5321		bphy_err(drvr, "chanspec failed (%d)\n", err);
   5322		return err;
   5323	}
   5324
   5325	ch.chspec = chanspec;
   5326	cfg->d11inf.decchspec(&ch);
   5327
   5328	switch (ch.band) {
   5329	case BRCMU_CHAN_BAND_2G:
   5330		band = NL80211_BAND_2GHZ;
   5331		break;
   5332	case BRCMU_CHAN_BAND_5G:
   5333		band = NL80211_BAND_5GHZ;
   5334		break;
   5335	}
   5336
   5337	switch (ch.bw) {
   5338	case BRCMU_CHAN_BW_80:
   5339		width = NL80211_CHAN_WIDTH_80;
   5340		break;
   5341	case BRCMU_CHAN_BW_40:
   5342		width = NL80211_CHAN_WIDTH_40;
   5343		break;
   5344	case BRCMU_CHAN_BW_20:
   5345		width = NL80211_CHAN_WIDTH_20;
   5346		break;
   5347	case BRCMU_CHAN_BW_80P80:
   5348		width = NL80211_CHAN_WIDTH_80P80;
   5349		break;
   5350	case BRCMU_CHAN_BW_160:
   5351		width = NL80211_CHAN_WIDTH_160;
   5352		break;
   5353	}
   5354
   5355	freq = ieee80211_channel_to_frequency(ch.control_ch_num, band);
   5356	chandef->chan = ieee80211_get_channel(wiphy, freq);
   5357	chandef->width = width;
   5358	chandef->center_freq1 = ieee80211_channel_to_frequency(ch.chnum, band);
   5359	chandef->center_freq2 = 0;
   5360
   5361	return 0;
   5362}
   5363
   5364static int brcmf_cfg80211_crit_proto_start(struct wiphy *wiphy,
   5365					   struct wireless_dev *wdev,
   5366					   enum nl80211_crit_proto_id proto,
   5367					   u16 duration)
   5368{
   5369	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
   5370	struct brcmf_cfg80211_vif *vif;
   5371
   5372	vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
   5373
   5374	/* only DHCP support for now */
   5375	if (proto != NL80211_CRIT_PROTO_DHCP)
   5376		return -EINVAL;
   5377
   5378	/* suppress and abort scanning */
   5379	set_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
   5380	brcmf_abort_scanning(cfg);
   5381
   5382	return brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_DISABLED, duration);
   5383}
   5384
   5385static void brcmf_cfg80211_crit_proto_stop(struct wiphy *wiphy,
   5386					   struct wireless_dev *wdev)
   5387{
   5388	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
   5389	struct brcmf_cfg80211_vif *vif;
   5390
   5391	vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
   5392
   5393	brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_ENABLED, 0);
   5394	clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
   5395}
   5396
   5397static s32
   5398brcmf_notify_tdls_peer_event(struct brcmf_if *ifp,
   5399			     const struct brcmf_event_msg *e, void *data)
   5400{
   5401	switch (e->reason) {
   5402	case BRCMF_E_REASON_TDLS_PEER_DISCOVERED:
   5403		brcmf_dbg(TRACE, "TDLS Peer Discovered\n");
   5404		break;
   5405	case BRCMF_E_REASON_TDLS_PEER_CONNECTED:
   5406		brcmf_dbg(TRACE, "TDLS Peer Connected\n");
   5407		brcmf_proto_add_tdls_peer(ifp->drvr, ifp->ifidx, (u8 *)e->addr);
   5408		break;
   5409	case BRCMF_E_REASON_TDLS_PEER_DISCONNECTED:
   5410		brcmf_dbg(TRACE, "TDLS Peer Disconnected\n");
   5411		brcmf_proto_delete_peer(ifp->drvr, ifp->ifidx, (u8 *)e->addr);
   5412		break;
   5413	}
   5414
   5415	return 0;
   5416}
   5417
   5418static int brcmf_convert_nl80211_tdls_oper(enum nl80211_tdls_operation oper)
   5419{
   5420	int ret;
   5421
   5422	switch (oper) {
   5423	case NL80211_TDLS_DISCOVERY_REQ:
   5424		ret = BRCMF_TDLS_MANUAL_EP_DISCOVERY;
   5425		break;
   5426	case NL80211_TDLS_SETUP:
   5427		ret = BRCMF_TDLS_MANUAL_EP_CREATE;
   5428		break;
   5429	case NL80211_TDLS_TEARDOWN:
   5430		ret = BRCMF_TDLS_MANUAL_EP_DELETE;
   5431		break;
   5432	default:
   5433		brcmf_err("unsupported operation: %d\n", oper);
   5434		ret = -EOPNOTSUPP;
   5435	}
   5436	return ret;
   5437}
   5438
   5439static int brcmf_cfg80211_tdls_oper(struct wiphy *wiphy,
   5440				    struct net_device *ndev, const u8 *peer,
   5441				    enum nl80211_tdls_operation oper)
   5442{
   5443	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
   5444	struct brcmf_pub *drvr = cfg->pub;
   5445	struct brcmf_if *ifp;
   5446	struct brcmf_tdls_iovar_le info;
   5447	int ret = 0;
   5448
   5449	ret = brcmf_convert_nl80211_tdls_oper(oper);
   5450	if (ret < 0)
   5451		return ret;
   5452
   5453	ifp = netdev_priv(ndev);
   5454	memset(&info, 0, sizeof(info));
   5455	info.mode = (u8)ret;
   5456	if (peer)
   5457		memcpy(info.ea, peer, ETH_ALEN);
   5458
   5459	ret = brcmf_fil_iovar_data_set(ifp, "tdls_endpoint",
   5460				       &info, sizeof(info));
   5461	if (ret < 0)
   5462		bphy_err(drvr, "tdls_endpoint iovar failed: ret=%d\n", ret);
   5463
   5464	return ret;
   5465}
   5466
   5467static int
   5468brcmf_cfg80211_update_conn_params(struct wiphy *wiphy,
   5469				  struct net_device *ndev,
   5470				  struct cfg80211_connect_params *sme,
   5471				  u32 changed)
   5472{
   5473	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
   5474	struct brcmf_pub *drvr = cfg->pub;
   5475	struct brcmf_if *ifp;
   5476	int err;
   5477
   5478	if (!(changed & UPDATE_ASSOC_IES))
   5479		return 0;
   5480
   5481	ifp = netdev_priv(ndev);
   5482	err = brcmf_vif_set_mgmt_ie(ifp->vif, BRCMF_VNDR_IE_ASSOCREQ_FLAG,
   5483				    sme->ie, sme->ie_len);
   5484	if (err)
   5485		bphy_err(drvr, "Set Assoc REQ IE Failed\n");
   5486	else
   5487		brcmf_dbg(TRACE, "Applied Vndr IEs for Assoc request\n");
   5488
   5489	return err;
   5490}
   5491
   5492#ifdef CONFIG_PM
   5493static int
   5494brcmf_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *ndev,
   5495			      struct cfg80211_gtk_rekey_data *gtk)
   5496{
   5497	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
   5498	struct brcmf_pub *drvr = cfg->pub;
   5499	struct brcmf_if *ifp = netdev_priv(ndev);
   5500	struct brcmf_gtk_keyinfo_le gtk_le;
   5501	int ret;
   5502
   5503	brcmf_dbg(TRACE, "Enter, bssidx=%d\n", ifp->bsscfgidx);
   5504
   5505	memcpy(gtk_le.kck, gtk->kck, sizeof(gtk_le.kck));
   5506	memcpy(gtk_le.kek, gtk->kek, sizeof(gtk_le.kek));
   5507	memcpy(gtk_le.replay_counter, gtk->replay_ctr,
   5508	       sizeof(gtk_le.replay_counter));
   5509
   5510	ret = brcmf_fil_iovar_data_set(ifp, "gtk_key_info", &gtk_le,
   5511				       sizeof(gtk_le));
   5512	if (ret < 0)
   5513		bphy_err(drvr, "gtk_key_info iovar failed: ret=%d\n", ret);
   5514
   5515	return ret;
   5516}
   5517#endif
   5518
   5519static int brcmf_cfg80211_set_pmk(struct wiphy *wiphy, struct net_device *dev,
   5520				  const struct cfg80211_pmk_conf *conf)
   5521{
   5522	struct brcmf_if *ifp;
   5523
   5524	brcmf_dbg(TRACE, "enter\n");
   5525
   5526	/* expect using firmware supplicant for 1X */
   5527	ifp = netdev_priv(dev);
   5528	if (WARN_ON(ifp->vif->profile.use_fwsup != BRCMF_PROFILE_FWSUP_1X))
   5529		return -EINVAL;
   5530
   5531	if (conf->pmk_len > BRCMF_WSEC_MAX_PSK_LEN)
   5532		return -ERANGE;
   5533
   5534	return brcmf_set_pmk(ifp, conf->pmk, conf->pmk_len);
   5535}
   5536
   5537static int brcmf_cfg80211_del_pmk(struct wiphy *wiphy, struct net_device *dev,
   5538				  const u8 *aa)
   5539{
   5540	struct brcmf_if *ifp;
   5541
   5542	brcmf_dbg(TRACE, "enter\n");
   5543	ifp = netdev_priv(dev);
   5544	if (WARN_ON(ifp->vif->profile.use_fwsup != BRCMF_PROFILE_FWSUP_1X))
   5545		return -EINVAL;
   5546
   5547	return brcmf_set_pmk(ifp, NULL, 0);
   5548}
   5549
   5550static struct cfg80211_ops brcmf_cfg80211_ops = {
   5551	.add_virtual_intf = brcmf_cfg80211_add_iface,
   5552	.del_virtual_intf = brcmf_cfg80211_del_iface,
   5553	.change_virtual_intf = brcmf_cfg80211_change_iface,
   5554	.scan = brcmf_cfg80211_scan,
   5555	.set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
   5556	.join_ibss = brcmf_cfg80211_join_ibss,
   5557	.leave_ibss = brcmf_cfg80211_leave_ibss,
   5558	.get_station = brcmf_cfg80211_get_station,
   5559	.dump_station = brcmf_cfg80211_dump_station,
   5560	.set_tx_power = brcmf_cfg80211_set_tx_power,
   5561	.get_tx_power = brcmf_cfg80211_get_tx_power,
   5562	.add_key = brcmf_cfg80211_add_key,
   5563	.del_key = brcmf_cfg80211_del_key,
   5564	.get_key = brcmf_cfg80211_get_key,
   5565	.set_default_key = brcmf_cfg80211_config_default_key,
   5566	.set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
   5567	.set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
   5568	.connect = brcmf_cfg80211_connect,
   5569	.disconnect = brcmf_cfg80211_disconnect,
   5570	.suspend = brcmf_cfg80211_suspend,
   5571	.resume = brcmf_cfg80211_resume,
   5572	.set_pmksa = brcmf_cfg80211_set_pmksa,
   5573	.del_pmksa = brcmf_cfg80211_del_pmksa,
   5574	.flush_pmksa = brcmf_cfg80211_flush_pmksa,
   5575	.start_ap = brcmf_cfg80211_start_ap,
   5576	.stop_ap = brcmf_cfg80211_stop_ap,
   5577	.change_beacon = brcmf_cfg80211_change_beacon,
   5578	.del_station = brcmf_cfg80211_del_station,
   5579	.change_station = brcmf_cfg80211_change_station,
   5580	.sched_scan_start = brcmf_cfg80211_sched_scan_start,
   5581	.sched_scan_stop = brcmf_cfg80211_sched_scan_stop,
   5582	.update_mgmt_frame_registrations =
   5583		brcmf_cfg80211_update_mgmt_frame_registrations,
   5584	.mgmt_tx = brcmf_cfg80211_mgmt_tx,
   5585	.set_cqm_rssi_range_config = brcmf_cfg80211_set_cqm_rssi_range_config,
   5586	.remain_on_channel = brcmf_p2p_remain_on_channel,
   5587	.cancel_remain_on_channel = brcmf_cfg80211_cancel_remain_on_channel,
   5588	.get_channel = brcmf_cfg80211_get_channel,
   5589	.start_p2p_device = brcmf_p2p_start_device,
   5590	.stop_p2p_device = brcmf_p2p_stop_device,
   5591	.crit_proto_start = brcmf_cfg80211_crit_proto_start,
   5592	.crit_proto_stop = brcmf_cfg80211_crit_proto_stop,
   5593	.tdls_oper = brcmf_cfg80211_tdls_oper,
   5594	.update_connect_params = brcmf_cfg80211_update_conn_params,
   5595	.set_pmk = brcmf_cfg80211_set_pmk,
   5596	.del_pmk = brcmf_cfg80211_del_pmk,
   5597};
   5598
   5599struct cfg80211_ops *brcmf_cfg80211_get_ops(struct brcmf_mp_device *settings)
   5600{
   5601	struct cfg80211_ops *ops;
   5602
   5603	ops = kmemdup(&brcmf_cfg80211_ops, sizeof(brcmf_cfg80211_ops),
   5604		       GFP_KERNEL);
   5605
   5606	if (ops && settings->roamoff)
   5607		ops->update_connect_params = NULL;
   5608
   5609	return ops;
   5610}
   5611
   5612struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
   5613					   enum nl80211_iftype type)
   5614{
   5615	struct brcmf_cfg80211_vif *vif_walk;
   5616	struct brcmf_cfg80211_vif *vif;
   5617	bool mbss;
   5618	struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0);
   5619
   5620	brcmf_dbg(TRACE, "allocating virtual interface (size=%zu)\n",
   5621		  sizeof(*vif));
   5622	vif = kzalloc(sizeof(*vif), GFP_KERNEL);
   5623	if (!vif)
   5624		return ERR_PTR(-ENOMEM);
   5625
   5626	vif->wdev.wiphy = cfg->wiphy;
   5627	vif->wdev.iftype = type;
   5628
   5629	brcmf_init_prof(&vif->profile);
   5630
   5631	if (type == NL80211_IFTYPE_AP &&
   5632	    brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) {
   5633		mbss = false;
   5634		list_for_each_entry(vif_walk, &cfg->vif_list, list) {
   5635			if (vif_walk->wdev.iftype == NL80211_IFTYPE_AP) {
   5636				mbss = true;
   5637				break;
   5638			}
   5639		}
   5640		vif->mbss = mbss;
   5641	}
   5642
   5643	list_add_tail(&vif->list, &cfg->vif_list);
   5644	return vif;
   5645}
   5646
   5647void brcmf_free_vif(struct brcmf_cfg80211_vif *vif)
   5648{
   5649	list_del(&vif->list);
   5650	kfree(vif);
   5651}
   5652
   5653void brcmf_cfg80211_free_netdev(struct net_device *ndev)
   5654{
   5655	struct brcmf_cfg80211_vif *vif;
   5656	struct brcmf_if *ifp;
   5657
   5658	ifp = netdev_priv(ndev);
   5659	vif = ifp->vif;
   5660
   5661	if (vif)
   5662		brcmf_free_vif(vif);
   5663}
   5664
   5665static bool brcmf_is_linkup(struct brcmf_cfg80211_vif *vif,
   5666			    const struct brcmf_event_msg *e)
   5667{
   5668	u32 event = e->event_code;
   5669	u32 status = e->status;
   5670
   5671	if ((vif->profile.use_fwsup == BRCMF_PROFILE_FWSUP_PSK ||
   5672	     vif->profile.use_fwsup == BRCMF_PROFILE_FWSUP_SAE) &&
   5673	    event == BRCMF_E_PSK_SUP &&
   5674	    status == BRCMF_E_STATUS_FWSUP_COMPLETED)
   5675		set_bit(BRCMF_VIF_STATUS_EAP_SUCCESS, &vif->sme_state);
   5676	if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
   5677		brcmf_dbg(CONN, "Processing set ssid\n");
   5678		memcpy(vif->profile.bssid, e->addr, ETH_ALEN);
   5679		if (vif->profile.use_fwsup != BRCMF_PROFILE_FWSUP_PSK &&
   5680		    vif->profile.use_fwsup != BRCMF_PROFILE_FWSUP_SAE)
   5681			return true;
   5682
   5683		set_bit(BRCMF_VIF_STATUS_ASSOC_SUCCESS, &vif->sme_state);
   5684	}
   5685
   5686	if (test_bit(BRCMF_VIF_STATUS_EAP_SUCCESS, &vif->sme_state) &&
   5687	    test_bit(BRCMF_VIF_STATUS_ASSOC_SUCCESS, &vif->sme_state)) {
   5688		clear_bit(BRCMF_VIF_STATUS_EAP_SUCCESS, &vif->sme_state);
   5689		clear_bit(BRCMF_VIF_STATUS_ASSOC_SUCCESS, &vif->sme_state);
   5690		return true;
   5691	}
   5692	return false;
   5693}
   5694
   5695static bool brcmf_is_linkdown(struct brcmf_cfg80211_vif *vif,
   5696			    const struct brcmf_event_msg *e)
   5697{
   5698	u32 event = e->event_code;
   5699	u16 flags = e->flags;
   5700
   5701	if ((event == BRCMF_E_DEAUTH) || (event == BRCMF_E_DEAUTH_IND) ||
   5702	    (event == BRCMF_E_DISASSOC_IND) ||
   5703	    ((event == BRCMF_E_LINK) && (!(flags & BRCMF_EVENT_MSG_LINK)))) {
   5704		brcmf_dbg(CONN, "Processing link down\n");
   5705		clear_bit(BRCMF_VIF_STATUS_EAP_SUCCESS, &vif->sme_state);
   5706		clear_bit(BRCMF_VIF_STATUS_ASSOC_SUCCESS, &vif->sme_state);
   5707		return true;
   5708	}
   5709	return false;
   5710}
   5711
   5712static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info *cfg,
   5713			       const struct brcmf_event_msg *e)
   5714{
   5715	u32 event = e->event_code;
   5716	u32 status = e->status;
   5717
   5718	if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
   5719		brcmf_dbg(CONN, "Processing Link %s & no network found\n",
   5720			  e->flags & BRCMF_EVENT_MSG_LINK ? "up" : "down");
   5721		return true;
   5722	}
   5723
   5724	if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
   5725		brcmf_dbg(CONN, "Processing connecting & no network found\n");
   5726		return true;
   5727	}
   5728
   5729	if (event == BRCMF_E_PSK_SUP &&
   5730	    status != BRCMF_E_STATUS_FWSUP_COMPLETED) {
   5731		brcmf_dbg(CONN, "Processing failed supplicant state: %u\n",
   5732			  status);
   5733		return true;
   5734	}
   5735
   5736	return false;
   5737}
   5738
   5739static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info *cfg)
   5740{
   5741	struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
   5742
   5743	kfree(conn_info->req_ie);
   5744	conn_info->req_ie = NULL;
   5745	conn_info->req_ie_len = 0;
   5746	kfree(conn_info->resp_ie);
   5747	conn_info->resp_ie = NULL;
   5748	conn_info->resp_ie_len = 0;
   5749}
   5750
   5751u8 brcmf_map_prio_to_prec(void *config, u8 prio)
   5752{
   5753	struct brcmf_cfg80211_info *cfg = (struct brcmf_cfg80211_info *)config;
   5754
   5755	if (!cfg)
   5756		return (prio == PRIO_8021D_NONE || prio == PRIO_8021D_BE) ?
   5757		       (prio ^ 2) : prio;
   5758
   5759	/* For those AC(s) with ACM flag set to 1, convert its 4-level priority
   5760	 * to an 8-level precedence which is the same as BE's
   5761	 */
   5762	if (prio > PRIO_8021D_EE &&
   5763	    cfg->ac_priority[prio] == cfg->ac_priority[PRIO_8021D_BE])
   5764		return cfg->ac_priority[prio] * 2;
   5765
   5766	/* Conversion of 4-level priority to 8-level precedence */
   5767	if (prio == PRIO_8021D_BE || prio == PRIO_8021D_BK ||
   5768	    prio == PRIO_8021D_CL || prio == PRIO_8021D_VO)
   5769		return cfg->ac_priority[prio] * 2;
   5770	else
   5771		return cfg->ac_priority[prio] * 2 + 1;
   5772}
   5773
   5774u8 brcmf_map_prio_to_aci(void *config, u8 prio)
   5775{
   5776	/* Prio here refers to the 802.1d priority in range of 0 to 7.
   5777	 * ACI here refers to the WLAN AC Index in range of 0 to 3.
   5778	 * This function will return ACI corresponding to input prio.
   5779	 */
   5780	struct brcmf_cfg80211_info *cfg = (struct brcmf_cfg80211_info *)config;
   5781
   5782	if (cfg)
   5783		return cfg->ac_priority[prio];
   5784
   5785	return prio;
   5786}
   5787
   5788static void brcmf_init_wmm_prio(u8 *priority)
   5789{
   5790	/* Initialize AC priority array to default
   5791	 * 802.1d priority as per following table:
   5792	 * 802.1d prio 0,3 maps to BE
   5793	 * 802.1d prio 1,2 maps to BK
   5794	 * 802.1d prio 4,5 maps to VI
   5795	 * 802.1d prio 6,7 maps to VO
   5796	 */
   5797	priority[0] = BRCMF_FWS_FIFO_AC_BE;
   5798	priority[3] = BRCMF_FWS_FIFO_AC_BE;
   5799	priority[1] = BRCMF_FWS_FIFO_AC_BK;
   5800	priority[2] = BRCMF_FWS_FIFO_AC_BK;
   5801	priority[4] = BRCMF_FWS_FIFO_AC_VI;
   5802	priority[5] = BRCMF_FWS_FIFO_AC_VI;
   5803	priority[6] = BRCMF_FWS_FIFO_AC_VO;
   5804	priority[7] = BRCMF_FWS_FIFO_AC_VO;
   5805}
   5806
   5807static void brcmf_wifi_prioritize_acparams(const
   5808	struct brcmf_cfg80211_edcf_acparam *acp, u8 *priority)
   5809{
   5810	u8 aci;
   5811	u8 aifsn;
   5812	u8 ecwmin;
   5813	u8 ecwmax;
   5814	u8 acm;
   5815	u8 ranking_basis[EDCF_AC_COUNT];
   5816	u8 aci_prio[EDCF_AC_COUNT]; /* AC_BE, AC_BK, AC_VI, AC_VO */
   5817	u8 index;
   5818
   5819	for (aci = 0; aci < EDCF_AC_COUNT; aci++, acp++) {
   5820		aifsn  = acp->ACI & EDCF_AIFSN_MASK;
   5821		acm = (acp->ACI & EDCF_ACM_MASK) ? 1 : 0;
   5822		ecwmin = acp->ECW & EDCF_ECWMIN_MASK;
   5823		ecwmax = (acp->ECW & EDCF_ECWMAX_MASK) >> EDCF_ECWMAX_SHIFT;
   5824		brcmf_dbg(CONN, "ACI %d aifsn %d acm %d ecwmin %d ecwmax %d\n",
   5825			  aci, aifsn, acm, ecwmin, ecwmax);
   5826		/* Default AC_VO will be the lowest ranking value */
   5827		ranking_basis[aci] = aifsn + ecwmin + ecwmax;
   5828		/* Initialise priority starting at 0 (AC_BE) */
   5829		aci_prio[aci] = 0;
   5830
   5831		/* If ACM is set, STA can't use this AC as per 802.11.
   5832		 * Change the ranking to BE
   5833		 */
   5834		if (aci != AC_BE && aci != AC_BK && acm == 1)
   5835			ranking_basis[aci] = ranking_basis[AC_BE];
   5836	}
   5837
   5838	/* Ranking method which works for AC priority
   5839	 * swapping when values for cwmin, cwmax and aifsn are varied
   5840	 * Compare each aci_prio against each other aci_prio
   5841	 */
   5842	for (aci = 0; aci < EDCF_AC_COUNT; aci++) {
   5843		for (index = 0; index < EDCF_AC_COUNT; index++) {
   5844			if (index != aci) {
   5845				/* Smaller ranking value has higher priority,
   5846				 * so increment priority for each ACI which has
   5847				 * a higher ranking value
   5848				 */
   5849				if (ranking_basis[aci] < ranking_basis[index])
   5850					aci_prio[aci]++;
   5851			}
   5852		}
   5853	}
   5854
   5855	/* By now, aci_prio[] will be in range of 0 to 3.
   5856	 * Use ACI prio to get the new priority value for
   5857	 * each 802.1d traffic type, in this range.
   5858	 */
   5859	if (!(aci_prio[AC_BE] == aci_prio[AC_BK] &&
   5860	      aci_prio[AC_BK] == aci_prio[AC_VI] &&
   5861	      aci_prio[AC_VI] == aci_prio[AC_VO])) {
   5862		/* 802.1d 0,3 maps to BE */
   5863		priority[0] = aci_prio[AC_BE];
   5864		priority[3] = aci_prio[AC_BE];
   5865
   5866		/* 802.1d 1,2 maps to BK */
   5867		priority[1] = aci_prio[AC_BK];
   5868		priority[2] = aci_prio[AC_BK];
   5869
   5870		/* 802.1d 4,5 maps to VO */
   5871		priority[4] = aci_prio[AC_VI];
   5872		priority[5] = aci_prio[AC_VI];
   5873
   5874		/* 802.1d 6,7 maps to VO */
   5875		priority[6] = aci_prio[AC_VO];
   5876		priority[7] = aci_prio[AC_VO];
   5877	} else {
   5878		/* Initialize to default priority */
   5879		brcmf_init_wmm_prio(priority);
   5880	}
   5881
   5882	brcmf_dbg(CONN, "Adj prio BE 0->%d, BK 1->%d, BK 2->%d, BE 3->%d\n",
   5883		  priority[0], priority[1], priority[2], priority[3]);
   5884
   5885	brcmf_dbg(CONN, "Adj prio VI 4->%d, VI 5->%d, VO 6->%d, VO 7->%d\n",
   5886		  priority[4], priority[5], priority[6], priority[7]);
   5887}
   5888
   5889static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg,
   5890			       struct brcmf_if *ifp)
   5891{
   5892	struct brcmf_pub *drvr = cfg->pub;
   5893	struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
   5894	struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
   5895	struct brcmf_cfg80211_edcf_acparam edcf_acparam_info[EDCF_AC_COUNT];
   5896	u32 req_len;
   5897	u32 resp_len;
   5898	s32 err = 0;
   5899
   5900	brcmf_clear_assoc_ies(cfg);
   5901
   5902	err = brcmf_fil_iovar_data_get(ifp, "assoc_info",
   5903				       cfg->extra_buf, WL_ASSOC_INFO_MAX);
   5904	if (err) {
   5905		bphy_err(drvr, "could not get assoc info (%d)\n", err);
   5906		return err;
   5907	}
   5908	assoc_info =
   5909		(struct brcmf_cfg80211_assoc_ielen_le *)cfg->extra_buf;
   5910	req_len = le32_to_cpu(assoc_info->req_len);
   5911	resp_len = le32_to_cpu(assoc_info->resp_len);
   5912	if (req_len) {
   5913		err = brcmf_fil_iovar_data_get(ifp, "assoc_req_ies",
   5914					       cfg->extra_buf,
   5915					       WL_ASSOC_INFO_MAX);
   5916		if (err) {
   5917			bphy_err(drvr, "could not get assoc req (%d)\n", err);
   5918			return err;
   5919		}
   5920		conn_info->req_ie_len = req_len;
   5921		conn_info->req_ie =
   5922		    kmemdup(cfg->extra_buf, conn_info->req_ie_len,
   5923			    GFP_KERNEL);
   5924		if (!conn_info->req_ie)
   5925			conn_info->req_ie_len = 0;
   5926	} else {
   5927		conn_info->req_ie_len = 0;
   5928		conn_info->req_ie = NULL;
   5929	}
   5930	if (resp_len) {
   5931		err = brcmf_fil_iovar_data_get(ifp, "assoc_resp_ies",
   5932					       cfg->extra_buf,
   5933					       WL_ASSOC_INFO_MAX);
   5934		if (err) {
   5935			bphy_err(drvr, "could not get assoc resp (%d)\n", err);
   5936			return err;
   5937		}
   5938		conn_info->resp_ie_len = resp_len;
   5939		conn_info->resp_ie =
   5940		    kmemdup(cfg->extra_buf, conn_info->resp_ie_len,
   5941			    GFP_KERNEL);
   5942		if (!conn_info->resp_ie)
   5943			conn_info->resp_ie_len = 0;
   5944
   5945		err = brcmf_fil_iovar_data_get(ifp, "wme_ac_sta",
   5946					       edcf_acparam_info,
   5947					       sizeof(edcf_acparam_info));
   5948		if (err) {
   5949			brcmf_err("could not get wme_ac_sta (%d)\n", err);
   5950			return err;
   5951		}
   5952
   5953		brcmf_wifi_prioritize_acparams(edcf_acparam_info,
   5954					       cfg->ac_priority);
   5955	} else {
   5956		conn_info->resp_ie_len = 0;
   5957		conn_info->resp_ie = NULL;
   5958	}
   5959	brcmf_dbg(CONN, "req len (%d) resp len (%d)\n",
   5960		  conn_info->req_ie_len, conn_info->resp_ie_len);
   5961
   5962	return err;
   5963}
   5964
   5965static s32
   5966brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
   5967		       struct net_device *ndev,
   5968		       const struct brcmf_event_msg *e)
   5969{
   5970	struct brcmf_if *ifp = netdev_priv(ndev);
   5971	struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
   5972	struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
   5973	struct wiphy *wiphy = cfg_to_wiphy(cfg);
   5974	struct ieee80211_channel *notify_channel = NULL;
   5975	struct ieee80211_supported_band *band;
   5976	struct brcmf_bss_info_le *bi;
   5977	struct brcmu_chan ch;
   5978	struct cfg80211_roam_info roam_info = {};
   5979	u32 freq;
   5980	s32 err = 0;
   5981	u8 *buf;
   5982
   5983	brcmf_dbg(TRACE, "Enter\n");
   5984
   5985	brcmf_get_assoc_ies(cfg, ifp);
   5986	memcpy(profile->bssid, e->addr, ETH_ALEN);
   5987	brcmf_update_bss_info(cfg, ifp);
   5988
   5989	buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
   5990	if (buf == NULL) {
   5991		err = -ENOMEM;
   5992		goto done;
   5993	}
   5994
   5995	/* data sent to dongle has to be little endian */
   5996	*(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
   5997	err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
   5998				     buf, WL_BSS_INFO_MAX);
   5999
   6000	if (err)
   6001		goto done;
   6002
   6003	bi = (struct brcmf_bss_info_le *)(buf + 4);
   6004	ch.chspec = le16_to_cpu(bi->chanspec);
   6005	cfg->d11inf.decchspec(&ch);
   6006
   6007	if (ch.band == BRCMU_CHAN_BAND_2G)
   6008		band = wiphy->bands[NL80211_BAND_2GHZ];
   6009	else
   6010		band = wiphy->bands[NL80211_BAND_5GHZ];
   6011
   6012	freq = ieee80211_channel_to_frequency(ch.control_ch_num, band->band);
   6013	notify_channel = ieee80211_get_channel(wiphy, freq);
   6014
   6015done:
   6016	kfree(buf);
   6017
   6018	roam_info.channel = notify_channel;
   6019	roam_info.bssid = profile->bssid;
   6020	roam_info.req_ie = conn_info->req_ie;
   6021	roam_info.req_ie_len = conn_info->req_ie_len;
   6022	roam_info.resp_ie = conn_info->resp_ie;
   6023	roam_info.resp_ie_len = conn_info->resp_ie_len;
   6024
   6025	cfg80211_roamed(ndev, &roam_info, GFP_KERNEL);
   6026	brcmf_dbg(CONN, "Report roaming result\n");
   6027
   6028	if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_1X && profile->is_ft) {
   6029		cfg80211_port_authorized(ndev, profile->bssid, GFP_KERNEL);
   6030		brcmf_dbg(CONN, "Report port authorized\n");
   6031	}
   6032
   6033	set_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
   6034	brcmf_dbg(TRACE, "Exit\n");
   6035	return err;
   6036}
   6037
   6038static s32
   6039brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg,
   6040		       struct net_device *ndev, const struct brcmf_event_msg *e,
   6041		       bool completed)
   6042{
   6043	struct brcmf_if *ifp = netdev_priv(ndev);
   6044	struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
   6045	struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
   6046	struct cfg80211_connect_resp_params conn_params;
   6047
   6048	brcmf_dbg(TRACE, "Enter\n");
   6049
   6050	if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTING,
   6051			       &ifp->vif->sme_state)) {
   6052		memset(&conn_params, 0, sizeof(conn_params));
   6053		if (completed) {
   6054			brcmf_get_assoc_ies(cfg, ifp);
   6055			brcmf_update_bss_info(cfg, ifp);
   6056			set_bit(BRCMF_VIF_STATUS_CONNECTED,
   6057				&ifp->vif->sme_state);
   6058			conn_params.status = WLAN_STATUS_SUCCESS;
   6059		} else {
   6060			conn_params.status = WLAN_STATUS_AUTH_TIMEOUT;
   6061		}
   6062		conn_params.bssid = profile->bssid;
   6063		conn_params.req_ie = conn_info->req_ie;
   6064		conn_params.req_ie_len = conn_info->req_ie_len;
   6065		conn_params.resp_ie = conn_info->resp_ie;
   6066		conn_params.resp_ie_len = conn_info->resp_ie_len;
   6067		cfg80211_connect_done(ndev, &conn_params, GFP_KERNEL);
   6068		brcmf_dbg(CONN, "Report connect result - connection %s\n",
   6069			  completed ? "succeeded" : "failed");
   6070	}
   6071	brcmf_dbg(TRACE, "Exit\n");
   6072	return 0;
   6073}
   6074
   6075static s32
   6076brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg,
   6077			       struct net_device *ndev,
   6078			       const struct brcmf_event_msg *e, void *data)
   6079{
   6080	struct brcmf_pub *drvr = cfg->pub;
   6081	static int generation;
   6082	u32 event = e->event_code;
   6083	u32 reason = e->reason;
   6084	struct station_info *sinfo;
   6085
   6086	brcmf_dbg(CONN, "event %s (%u), reason %d\n",
   6087		  brcmf_fweh_event_name(event), event, reason);
   6088	if (event == BRCMF_E_LINK && reason == BRCMF_E_REASON_LINK_BSSCFG_DIS &&
   6089	    ndev != cfg_to_ndev(cfg)) {
   6090		brcmf_dbg(CONN, "AP mode link down\n");
   6091		complete(&cfg->vif_disabled);
   6092		return 0;
   6093	}
   6094
   6095	if (((event == BRCMF_E_ASSOC_IND) || (event == BRCMF_E_REASSOC_IND)) &&
   6096	    (reason == BRCMF_E_STATUS_SUCCESS)) {
   6097		if (!data) {
   6098			bphy_err(drvr, "No IEs present in ASSOC/REASSOC_IND\n");
   6099			return -EINVAL;
   6100		}
   6101
   6102		sinfo = kzalloc(sizeof(*sinfo), GFP_KERNEL);
   6103		if (!sinfo)
   6104			return -ENOMEM;
   6105
   6106		sinfo->assoc_req_ies = data;
   6107		sinfo->assoc_req_ies_len = e->datalen;
   6108		generation++;
   6109		sinfo->generation = generation;
   6110		cfg80211_new_sta(ndev, e->addr, sinfo, GFP_KERNEL);
   6111
   6112		kfree(sinfo);
   6113	} else if ((event == BRCMF_E_DISASSOC_IND) ||
   6114		   (event == BRCMF_E_DEAUTH_IND) ||
   6115		   (event == BRCMF_E_DEAUTH)) {
   6116		cfg80211_del_sta(ndev, e->addr, GFP_KERNEL);
   6117	}
   6118	return 0;
   6119}
   6120
   6121static s32
   6122brcmf_notify_connect_status(struct brcmf_if *ifp,
   6123			    const struct brcmf_event_msg *e, void *data)
   6124{
   6125	struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
   6126	struct net_device *ndev = ifp->ndev;
   6127	struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
   6128	struct ieee80211_channel *chan;
   6129	s32 err = 0;
   6130
   6131	if ((e->event_code == BRCMF_E_DEAUTH) ||
   6132	    (e->event_code == BRCMF_E_DEAUTH_IND) ||
   6133	    (e->event_code == BRCMF_E_DISASSOC_IND) ||
   6134	    ((e->event_code == BRCMF_E_LINK) && (!e->flags))) {
   6135		brcmf_proto_delete_peer(ifp->drvr, ifp->ifidx, (u8 *)e->addr);
   6136	}
   6137
   6138	if (brcmf_is_apmode(ifp->vif)) {
   6139		err = brcmf_notify_connect_status_ap(cfg, ndev, e, data);
   6140	} else if (brcmf_is_linkup(ifp->vif, e)) {
   6141		brcmf_dbg(CONN, "Linkup\n");
   6142		if (brcmf_is_ibssmode(ifp->vif)) {
   6143			brcmf_inform_ibss(cfg, ndev, e->addr);
   6144			chan = ieee80211_get_channel(cfg->wiphy, cfg->channel);
   6145			memcpy(profile->bssid, e->addr, ETH_ALEN);
   6146			cfg80211_ibss_joined(ndev, e->addr, chan, GFP_KERNEL);
   6147			clear_bit(BRCMF_VIF_STATUS_CONNECTING,
   6148				  &ifp->vif->sme_state);
   6149			set_bit(BRCMF_VIF_STATUS_CONNECTED,
   6150				&ifp->vif->sme_state);
   6151		} else
   6152			brcmf_bss_connect_done(cfg, ndev, e, true);
   6153		brcmf_net_setcarrier(ifp, true);
   6154	} else if (brcmf_is_linkdown(ifp->vif, e)) {
   6155		brcmf_dbg(CONN, "Linkdown\n");
   6156		if (!brcmf_is_ibssmode(ifp->vif) &&
   6157		    test_bit(BRCMF_VIF_STATUS_CONNECTED,
   6158			     &ifp->vif->sme_state)) {
   6159			if (memcmp(profile->bssid, e->addr, ETH_ALEN))
   6160				return err;
   6161
   6162			brcmf_bss_connect_done(cfg, ndev, e, false);
   6163			brcmf_link_down(ifp->vif,
   6164					brcmf_map_fw_linkdown_reason(e),
   6165					e->event_code &
   6166					(BRCMF_E_DEAUTH_IND |
   6167					BRCMF_E_DISASSOC_IND)
   6168					? false : true);
   6169			brcmf_init_prof(ndev_to_prof(ndev));
   6170			if (ndev != cfg_to_ndev(cfg))
   6171				complete(&cfg->vif_disabled);
   6172			brcmf_net_setcarrier(ifp, false);
   6173		}
   6174	} else if (brcmf_is_nonetwork(cfg, e)) {
   6175		if (brcmf_is_ibssmode(ifp->vif))
   6176			clear_bit(BRCMF_VIF_STATUS_CONNECTING,
   6177				  &ifp->vif->sme_state);
   6178		else
   6179			brcmf_bss_connect_done(cfg, ndev, e, false);
   6180	}
   6181
   6182	return err;
   6183}
   6184
   6185static s32
   6186brcmf_notify_roaming_status(struct brcmf_if *ifp,
   6187			    const struct brcmf_event_msg *e, void *data)
   6188{
   6189	struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
   6190	u32 event = e->event_code;
   6191	u32 status = e->status;
   6192
   6193	if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
   6194		if (test_bit(BRCMF_VIF_STATUS_CONNECTED,
   6195			     &ifp->vif->sme_state)) {
   6196			brcmf_bss_roaming_done(cfg, ifp->ndev, e);
   6197		} else {
   6198			brcmf_bss_connect_done(cfg, ifp->ndev, e, true);
   6199			brcmf_net_setcarrier(ifp, true);
   6200		}
   6201	}
   6202
   6203	return 0;
   6204}
   6205
   6206static s32
   6207brcmf_notify_mic_status(struct brcmf_if *ifp,
   6208			const struct brcmf_event_msg *e, void *data)
   6209{
   6210	u16 flags = e->flags;
   6211	enum nl80211_key_type key_type;
   6212
   6213	if (flags & BRCMF_EVENT_MSG_GROUP)
   6214		key_type = NL80211_KEYTYPE_GROUP;
   6215	else
   6216		key_type = NL80211_KEYTYPE_PAIRWISE;
   6217
   6218	cfg80211_michael_mic_failure(ifp->ndev, (u8 *)&e->addr, key_type, -1,
   6219				     NULL, GFP_KERNEL);
   6220
   6221	return 0;
   6222}
   6223
   6224static s32 brcmf_notify_rssi(struct brcmf_if *ifp,
   6225			     const struct brcmf_event_msg *e, void *data)
   6226{
   6227	struct brcmf_cfg80211_vif *vif = ifp->vif;
   6228	struct brcmf_rssi_be *info = data;
   6229	s32 rssi, snr, noise;
   6230	s32 low, high, last;
   6231
   6232	if (e->datalen < sizeof(*info)) {
   6233		brcmf_err("insufficient RSSI event data\n");
   6234		return 0;
   6235	}
   6236
   6237	rssi = be32_to_cpu(info->rssi);
   6238	snr = be32_to_cpu(info->snr);
   6239	noise = be32_to_cpu(info->noise);
   6240
   6241	low = vif->cqm_rssi_low;
   6242	high = vif->cqm_rssi_high;
   6243	last = vif->cqm_rssi_last;
   6244
   6245	brcmf_dbg(TRACE, "rssi=%d snr=%d noise=%d low=%d high=%d last=%d\n",
   6246		  rssi, snr, noise, low, high, last);
   6247
   6248	vif->cqm_rssi_last = rssi;
   6249
   6250	if (rssi <= low || rssi == 0) {
   6251		brcmf_dbg(INFO, "LOW rssi=%d\n", rssi);
   6252		cfg80211_cqm_rssi_notify(ifp->ndev,
   6253					 NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW,
   6254					 rssi, GFP_KERNEL);
   6255	} else if (rssi > high) {
   6256		brcmf_dbg(INFO, "HIGH rssi=%d\n", rssi);
   6257		cfg80211_cqm_rssi_notify(ifp->ndev,
   6258					 NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH,
   6259					 rssi, GFP_KERNEL);
   6260	}
   6261
   6262	return 0;
   6263}
   6264
   6265static s32 brcmf_notify_vif_event(struct brcmf_if *ifp,
   6266				  const struct brcmf_event_msg *e, void *data)
   6267{
   6268	struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
   6269	struct brcmf_if_event *ifevent = (struct brcmf_if_event *)data;
   6270	struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
   6271	struct brcmf_cfg80211_vif *vif;
   6272
   6273	brcmf_dbg(TRACE, "Enter: action %u flags %u ifidx %u bsscfgidx %u\n",
   6274		  ifevent->action, ifevent->flags, ifevent->ifidx,
   6275		  ifevent->bsscfgidx);
   6276
   6277	spin_lock(&event->vif_event_lock);
   6278	event->action = ifevent->action;
   6279	vif = event->vif;
   6280
   6281	switch (ifevent->action) {
   6282	case BRCMF_E_IF_ADD:
   6283		/* waiting process may have timed out */
   6284		if (!cfg->vif_event.vif) {
   6285			spin_unlock(&event->vif_event_lock);
   6286			return -EBADF;
   6287		}
   6288
   6289		ifp->vif = vif;
   6290		vif->ifp = ifp;
   6291		if (ifp->ndev) {
   6292			vif->wdev.netdev = ifp->ndev;
   6293			ifp->ndev->ieee80211_ptr = &vif->wdev;
   6294			SET_NETDEV_DEV(ifp->ndev, wiphy_dev(cfg->wiphy));
   6295		}
   6296		spin_unlock(&event->vif_event_lock);
   6297		wake_up(&event->vif_wq);
   6298		return 0;
   6299
   6300	case BRCMF_E_IF_DEL:
   6301		spin_unlock(&event->vif_event_lock);
   6302		/* event may not be upon user request */
   6303		if (brcmf_cfg80211_vif_event_armed(cfg))
   6304			wake_up(&event->vif_wq);
   6305		return 0;
   6306
   6307	case BRCMF_E_IF_CHANGE:
   6308		spin_unlock(&event->vif_event_lock);
   6309		wake_up(&event->vif_wq);
   6310		return 0;
   6311
   6312	default:
   6313		spin_unlock(&event->vif_event_lock);
   6314		break;
   6315	}
   6316	return -EINVAL;
   6317}
   6318
   6319static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
   6320{
   6321	conf->frag_threshold = (u32)-1;
   6322	conf->rts_threshold = (u32)-1;
   6323	conf->retry_short = (u32)-1;
   6324	conf->retry_long = (u32)-1;
   6325}
   6326
   6327static void brcmf_register_event_handlers(struct brcmf_cfg80211_info *cfg)
   6328{
   6329	brcmf_fweh_register(cfg->pub, BRCMF_E_LINK,
   6330			    brcmf_notify_connect_status);
   6331	brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH_IND,
   6332			    brcmf_notify_connect_status);
   6333	brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH,
   6334			    brcmf_notify_connect_status);
   6335	brcmf_fweh_register(cfg->pub, BRCMF_E_DISASSOC_IND,
   6336			    brcmf_notify_connect_status);
   6337	brcmf_fweh_register(cfg->pub, BRCMF_E_ASSOC_IND,
   6338			    brcmf_notify_connect_status);
   6339	brcmf_fweh_register(cfg->pub, BRCMF_E_REASSOC_IND,
   6340			    brcmf_notify_connect_status);
   6341	brcmf_fweh_register(cfg->pub, BRCMF_E_ROAM,
   6342			    brcmf_notify_roaming_status);
   6343	brcmf_fweh_register(cfg->pub, BRCMF_E_MIC_ERROR,
   6344			    brcmf_notify_mic_status);
   6345	brcmf_fweh_register(cfg->pub, BRCMF_E_SET_SSID,
   6346			    brcmf_notify_connect_status);
   6347	brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
   6348			    brcmf_notify_sched_scan_results);
   6349	brcmf_fweh_register(cfg->pub, BRCMF_E_IF,
   6350			    brcmf_notify_vif_event);
   6351	brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_PROBEREQ_MSG,
   6352			    brcmf_p2p_notify_rx_mgmt_p2p_probereq);
   6353	brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_DISC_LISTEN_COMPLETE,
   6354			    brcmf_p2p_notify_listen_complete);
   6355	brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_RX,
   6356			    brcmf_p2p_notify_action_frame_rx);
   6357	brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_COMPLETE,
   6358			    brcmf_p2p_notify_action_tx_complete);
   6359	brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE,
   6360			    brcmf_p2p_notify_action_tx_complete);
   6361	brcmf_fweh_register(cfg->pub, BRCMF_E_PSK_SUP,
   6362			    brcmf_notify_connect_status);
   6363	brcmf_fweh_register(cfg->pub, BRCMF_E_RSSI, brcmf_notify_rssi);
   6364}
   6365
   6366static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg)
   6367{
   6368	kfree(cfg->conf);
   6369	cfg->conf = NULL;
   6370	kfree(cfg->extra_buf);
   6371	cfg->extra_buf = NULL;
   6372	kfree(cfg->wowl.nd);
   6373	cfg->wowl.nd = NULL;
   6374	kfree(cfg->wowl.nd_info);
   6375	cfg->wowl.nd_info = NULL;
   6376	kfree(cfg->escan_info.escan_buf);
   6377	cfg->escan_info.escan_buf = NULL;
   6378}
   6379
   6380static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg)
   6381{
   6382	cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL);
   6383	if (!cfg->conf)
   6384		goto init_priv_mem_out;
   6385	cfg->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
   6386	if (!cfg->extra_buf)
   6387		goto init_priv_mem_out;
   6388	cfg->wowl.nd = kzalloc(sizeof(*cfg->wowl.nd) + sizeof(u32), GFP_KERNEL);
   6389	if (!cfg->wowl.nd)
   6390		goto init_priv_mem_out;
   6391	cfg->wowl.nd_info = kzalloc(sizeof(*cfg->wowl.nd_info) +
   6392				    sizeof(struct cfg80211_wowlan_nd_match *),
   6393				    GFP_KERNEL);
   6394	if (!cfg->wowl.nd_info)
   6395		goto init_priv_mem_out;
   6396	cfg->escan_info.escan_buf = kzalloc(BRCMF_ESCAN_BUF_SIZE, GFP_KERNEL);
   6397	if (!cfg->escan_info.escan_buf)
   6398		goto init_priv_mem_out;
   6399
   6400	return 0;
   6401
   6402init_priv_mem_out:
   6403	brcmf_deinit_priv_mem(cfg);
   6404
   6405	return -ENOMEM;
   6406}
   6407
   6408static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg)
   6409{
   6410	s32 err = 0;
   6411
   6412	cfg->scan_request = NULL;
   6413	cfg->pwr_save = true;
   6414	cfg->dongle_up = false;		/* dongle is not up yet */
   6415	err = brcmf_init_priv_mem(cfg);
   6416	if (err)
   6417		return err;
   6418	brcmf_register_event_handlers(cfg);
   6419	mutex_init(&cfg->usr_sync);
   6420	brcmf_init_escan(cfg);
   6421	brcmf_init_conf(cfg->conf);
   6422	brcmf_init_wmm_prio(cfg->ac_priority);
   6423	init_completion(&cfg->vif_disabled);
   6424	return err;
   6425}
   6426
   6427static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg)
   6428{
   6429	cfg->dongle_up = false;	/* dongle down */
   6430	brcmf_abort_scanning(cfg);
   6431	brcmf_deinit_priv_mem(cfg);
   6432}
   6433
   6434static void init_vif_event(struct brcmf_cfg80211_vif_event *event)
   6435{
   6436	init_waitqueue_head(&event->vif_wq);
   6437	spin_lock_init(&event->vif_event_lock);
   6438}
   6439
   6440static s32 brcmf_dongle_roam(struct brcmf_if *ifp)
   6441{
   6442	struct brcmf_pub *drvr = ifp->drvr;
   6443	s32 err;
   6444	u32 bcn_timeout;
   6445	__le32 roamtrigger[2];
   6446	__le32 roam_delta[2];
   6447
   6448	/* Configure beacon timeout value based upon roaming setting */
   6449	if (ifp->drvr->settings->roamoff)
   6450		bcn_timeout = BRCMF_DEFAULT_BCN_TIMEOUT_ROAM_OFF;
   6451	else
   6452		bcn_timeout = BRCMF_DEFAULT_BCN_TIMEOUT_ROAM_ON;
   6453	err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout", bcn_timeout);
   6454	if (err) {
   6455		bphy_err(drvr, "bcn_timeout error (%d)\n", err);
   6456		goto roam_setup_done;
   6457	}
   6458
   6459	/* Enable/Disable built-in roaming to allow supplicant to take care of
   6460	 * roaming.
   6461	 */
   6462	brcmf_dbg(INFO, "Internal Roaming = %s\n",
   6463		  ifp->drvr->settings->roamoff ? "Off" : "On");
   6464	err = brcmf_fil_iovar_int_set(ifp, "roam_off",
   6465				      ifp->drvr->settings->roamoff);
   6466	if (err) {
   6467		bphy_err(drvr, "roam_off error (%d)\n", err);
   6468		goto roam_setup_done;
   6469	}
   6470
   6471	roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL);
   6472	roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL);
   6473	err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_TRIGGER,
   6474				     (void *)roamtrigger, sizeof(roamtrigger));
   6475	if (err)
   6476		bphy_err(drvr, "WLC_SET_ROAM_TRIGGER error (%d)\n", err);
   6477
   6478	roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
   6479	roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL);
   6480	err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_DELTA,
   6481				     (void *)roam_delta, sizeof(roam_delta));
   6482	if (err)
   6483		bphy_err(drvr, "WLC_SET_ROAM_DELTA error (%d)\n", err);
   6484
   6485	return 0;
   6486
   6487roam_setup_done:
   6488	return err;
   6489}
   6490
   6491static s32
   6492brcmf_dongle_scantime(struct brcmf_if *ifp)
   6493{
   6494	struct brcmf_pub *drvr = ifp->drvr;
   6495	s32 err = 0;
   6496
   6497	err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME,
   6498				    BRCMF_SCAN_CHANNEL_TIME);
   6499	if (err) {
   6500		bphy_err(drvr, "Scan assoc time error (%d)\n", err);
   6501		goto dongle_scantime_out;
   6502	}
   6503	err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_UNASSOC_TIME,
   6504				    BRCMF_SCAN_UNASSOC_TIME);
   6505	if (err) {
   6506		bphy_err(drvr, "Scan unassoc time error (%d)\n", err);
   6507		goto dongle_scantime_out;
   6508	}
   6509
   6510	err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_PASSIVE_TIME,
   6511				    BRCMF_SCAN_PASSIVE_TIME);
   6512	if (err) {
   6513		bphy_err(drvr, "Scan passive time error (%d)\n", err);
   6514		goto dongle_scantime_out;
   6515	}
   6516
   6517dongle_scantime_out:
   6518	return err;
   6519}
   6520
   6521static void brcmf_update_bw40_channel_flag(struct ieee80211_channel *channel,
   6522					   struct brcmu_chan *ch)
   6523{
   6524	u32 ht40_flag;
   6525
   6526	ht40_flag = channel->flags & IEEE80211_CHAN_NO_HT40;
   6527	if (ch->sb == BRCMU_CHAN_SB_U) {
   6528		if (ht40_flag == IEEE80211_CHAN_NO_HT40)
   6529			channel->flags &= ~IEEE80211_CHAN_NO_HT40;
   6530		channel->flags |= IEEE80211_CHAN_NO_HT40PLUS;
   6531	} else {
   6532		/* It should be one of
   6533		 * IEEE80211_CHAN_NO_HT40 or
   6534		 * IEEE80211_CHAN_NO_HT40PLUS
   6535		 */
   6536		channel->flags &= ~IEEE80211_CHAN_NO_HT40;
   6537		if (ht40_flag == IEEE80211_CHAN_NO_HT40)
   6538			channel->flags |= IEEE80211_CHAN_NO_HT40MINUS;
   6539	}
   6540}
   6541
   6542static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg,
   6543				    u32 bw_cap[])
   6544{
   6545	struct wiphy *wiphy = cfg_to_wiphy(cfg);
   6546	struct brcmf_pub *drvr = cfg->pub;
   6547	struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0);
   6548	struct ieee80211_supported_band *band;
   6549	struct ieee80211_channel *channel;
   6550	struct brcmf_chanspec_list *list;
   6551	struct brcmu_chan ch;
   6552	int err;
   6553	u8 *pbuf;
   6554	u32 i, j;
   6555	u32 total;
   6556	u32 chaninfo;
   6557
   6558	pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
   6559
   6560	if (pbuf == NULL)
   6561		return -ENOMEM;
   6562
   6563	list = (struct brcmf_chanspec_list *)pbuf;
   6564
   6565	err = brcmf_fil_iovar_data_get(ifp, "chanspecs", pbuf,
   6566				       BRCMF_DCMD_MEDLEN);
   6567	if (err) {
   6568		bphy_err(drvr, "get chanspecs error (%d)\n", err);
   6569		goto fail_pbuf;
   6570	}
   6571
   6572	band = wiphy->bands[NL80211_BAND_2GHZ];
   6573	if (band)
   6574		for (i = 0; i < band->n_channels; i++)
   6575			band->channels[i].flags = IEEE80211_CHAN_DISABLED;
   6576	band = wiphy->bands[NL80211_BAND_5GHZ];
   6577	if (band)
   6578		for (i = 0; i < band->n_channels; i++)
   6579			band->channels[i].flags = IEEE80211_CHAN_DISABLED;
   6580
   6581	total = le32_to_cpu(list->count);
   6582	for (i = 0; i < total; i++) {
   6583		ch.chspec = (u16)le32_to_cpu(list->element[i]);
   6584		cfg->d11inf.decchspec(&ch);
   6585
   6586		if (ch.band == BRCMU_CHAN_BAND_2G) {
   6587			band = wiphy->bands[NL80211_BAND_2GHZ];
   6588		} else if (ch.band == BRCMU_CHAN_BAND_5G) {
   6589			band = wiphy->bands[NL80211_BAND_5GHZ];
   6590		} else {
   6591			bphy_err(drvr, "Invalid channel Spec. 0x%x.\n",
   6592				 ch.chspec);
   6593			continue;
   6594		}
   6595		if (!band)
   6596			continue;
   6597		if (!(bw_cap[band->band] & WLC_BW_40MHZ_BIT) &&
   6598		    ch.bw == BRCMU_CHAN_BW_40)
   6599			continue;
   6600		if (!(bw_cap[band->band] & WLC_BW_80MHZ_BIT) &&
   6601		    ch.bw == BRCMU_CHAN_BW_80)
   6602			continue;
   6603
   6604		channel = NULL;
   6605		for (j = 0; j < band->n_channels; j++) {
   6606			if (band->channels[j].hw_value == ch.control_ch_num) {
   6607				channel = &band->channels[j];
   6608				break;
   6609			}
   6610		}
   6611		if (!channel) {
   6612			/* It seems firmware supports some channel we never
   6613			 * considered. Something new in IEEE standard?
   6614			 */
   6615			bphy_err(drvr, "Ignoring unexpected firmware channel %d\n",
   6616				 ch.control_ch_num);
   6617			continue;
   6618		}
   6619
   6620		if (channel->orig_flags & IEEE80211_CHAN_DISABLED)
   6621			continue;
   6622
   6623		/* assuming the chanspecs order is HT20,
   6624		 * HT40 upper, HT40 lower, and VHT80.
   6625		 */
   6626		switch (ch.bw) {
   6627		case BRCMU_CHAN_BW_160:
   6628			channel->flags &= ~IEEE80211_CHAN_NO_160MHZ;
   6629			break;
   6630		case BRCMU_CHAN_BW_80:
   6631			channel->flags &= ~IEEE80211_CHAN_NO_80MHZ;
   6632			break;
   6633		case BRCMU_CHAN_BW_40:
   6634			brcmf_update_bw40_channel_flag(channel, &ch);
   6635			break;
   6636		default:
   6637			wiphy_warn(wiphy, "Firmware reported unsupported bandwidth %d\n",
   6638				   ch.bw);
   6639			fallthrough;
   6640		case BRCMU_CHAN_BW_20:
   6641			/* enable the channel and disable other bandwidths
   6642			 * for now as mentioned order assure they are enabled
   6643			 * for subsequent chanspecs.
   6644			 */
   6645			channel->flags = IEEE80211_CHAN_NO_HT40 |
   6646					 IEEE80211_CHAN_NO_80MHZ |
   6647					 IEEE80211_CHAN_NO_160MHZ;
   6648			ch.bw = BRCMU_CHAN_BW_20;
   6649			cfg->d11inf.encchspec(&ch);
   6650			chaninfo = ch.chspec;
   6651			err = brcmf_fil_bsscfg_int_get(ifp, "per_chan_info",
   6652						       &chaninfo);
   6653			if (!err) {
   6654				if (chaninfo & WL_CHAN_RADAR)
   6655					channel->flags |=
   6656						(IEEE80211_CHAN_RADAR |
   6657						 IEEE80211_CHAN_NO_IR);
   6658				if (chaninfo & WL_CHAN_PASSIVE)
   6659					channel->flags |=
   6660						IEEE80211_CHAN_NO_IR;
   6661			}
   6662		}
   6663	}
   6664
   6665fail_pbuf:
   6666	kfree(pbuf);
   6667	return err;
   6668}
   6669
   6670static int brcmf_enable_bw40_2g(struct brcmf_cfg80211_info *cfg)
   6671{
   6672	struct brcmf_pub *drvr = cfg->pub;
   6673	struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0);
   6674	struct ieee80211_supported_band *band;
   6675	struct brcmf_fil_bwcap_le band_bwcap;
   6676	struct brcmf_chanspec_list *list;
   6677	u8 *pbuf;
   6678	u32 val;
   6679	int err;
   6680	struct brcmu_chan ch;
   6681	u32 num_chan;
   6682	int i, j;
   6683
   6684	/* verify support for bw_cap command */
   6685	val = WLC_BAND_5G;
   6686	err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &val);
   6687
   6688	if (!err) {
   6689		/* only set 2G bandwidth using bw_cap command */
   6690		band_bwcap.band = cpu_to_le32(WLC_BAND_2G);
   6691		band_bwcap.bw_cap = cpu_to_le32(WLC_BW_CAP_40MHZ);
   6692		err = brcmf_fil_iovar_data_set(ifp, "bw_cap", &band_bwcap,
   6693					       sizeof(band_bwcap));
   6694	} else {
   6695		brcmf_dbg(INFO, "fallback to mimo_bw_cap\n");
   6696		val = WLC_N_BW_40ALL;
   6697		err = brcmf_fil_iovar_int_set(ifp, "mimo_bw_cap", val);
   6698	}
   6699
   6700	if (!err) {
   6701		/* update channel info in 2G band */
   6702		pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
   6703
   6704		if (pbuf == NULL)
   6705			return -ENOMEM;
   6706
   6707		ch.band = BRCMU_CHAN_BAND_2G;
   6708		ch.bw = BRCMU_CHAN_BW_40;
   6709		ch.sb = BRCMU_CHAN_SB_NONE;
   6710		ch.chnum = 0;
   6711		cfg->d11inf.encchspec(&ch);
   6712
   6713		/* pass encoded chanspec in query */
   6714		*(__le16 *)pbuf = cpu_to_le16(ch.chspec);
   6715
   6716		err = brcmf_fil_iovar_data_get(ifp, "chanspecs", pbuf,
   6717					       BRCMF_DCMD_MEDLEN);
   6718		if (err) {
   6719			bphy_err(drvr, "get chanspecs error (%d)\n", err);
   6720			kfree(pbuf);
   6721			return err;
   6722		}
   6723
   6724		band = cfg_to_wiphy(cfg)->bands[NL80211_BAND_2GHZ];
   6725		list = (struct brcmf_chanspec_list *)pbuf;
   6726		num_chan = le32_to_cpu(list->count);
   6727		for (i = 0; i < num_chan; i++) {
   6728			ch.chspec = (u16)le32_to_cpu(list->element[i]);
   6729			cfg->d11inf.decchspec(&ch);
   6730			if (WARN_ON(ch.band != BRCMU_CHAN_BAND_2G))
   6731				continue;
   6732			if (WARN_ON(ch.bw != BRCMU_CHAN_BW_40))
   6733				continue;
   6734			for (j = 0; j < band->n_channels; j++) {
   6735				if (band->channels[j].hw_value == ch.control_ch_num)
   6736					break;
   6737			}
   6738			if (WARN_ON(j == band->n_channels))
   6739				continue;
   6740
   6741			brcmf_update_bw40_channel_flag(&band->channels[j], &ch);
   6742		}
   6743		kfree(pbuf);
   6744	}
   6745	return err;
   6746}
   6747
   6748static void brcmf_get_bwcap(struct brcmf_if *ifp, u32 bw_cap[])
   6749{
   6750	struct brcmf_pub *drvr = ifp->drvr;
   6751	u32 band, mimo_bwcap;
   6752	int err;
   6753
   6754	band = WLC_BAND_2G;
   6755	err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &band);
   6756	if (!err) {
   6757		bw_cap[NL80211_BAND_2GHZ] = band;
   6758		band = WLC_BAND_5G;
   6759		err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &band);
   6760		if (!err) {
   6761			bw_cap[NL80211_BAND_5GHZ] = band;
   6762			return;
   6763		}
   6764		WARN_ON(1);
   6765		return;
   6766	}
   6767	brcmf_dbg(INFO, "fallback to mimo_bw_cap info\n");
   6768	mimo_bwcap = 0;
   6769	err = brcmf_fil_iovar_int_get(ifp, "mimo_bw_cap", &mimo_bwcap);
   6770	if (err)
   6771		/* assume 20MHz if firmware does not give a clue */
   6772		mimo_bwcap = WLC_N_BW_20ALL;
   6773
   6774	switch (mimo_bwcap) {
   6775	case WLC_N_BW_40ALL:
   6776		bw_cap[NL80211_BAND_2GHZ] |= WLC_BW_40MHZ_BIT;
   6777		fallthrough;
   6778	case WLC_N_BW_20IN2G_40IN5G:
   6779		bw_cap[NL80211_BAND_5GHZ] |= WLC_BW_40MHZ_BIT;
   6780		fallthrough;
   6781	case WLC_N_BW_20ALL:
   6782		bw_cap[NL80211_BAND_2GHZ] |= WLC_BW_20MHZ_BIT;
   6783		bw_cap[NL80211_BAND_5GHZ] |= WLC_BW_20MHZ_BIT;
   6784		break;
   6785	default:
   6786		bphy_err(drvr, "invalid mimo_bw_cap value\n");
   6787	}
   6788}
   6789
   6790static void brcmf_update_ht_cap(struct ieee80211_supported_band *band,
   6791				u32 bw_cap[2], u32 nchain)
   6792{
   6793	band->ht_cap.ht_supported = true;
   6794	if (bw_cap[band->band] & WLC_BW_40MHZ_BIT) {
   6795		band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
   6796		band->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
   6797	}
   6798	band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
   6799	band->ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
   6800	band->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
   6801	band->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
   6802	memset(band->ht_cap.mcs.rx_mask, 0xff, nchain);
   6803	band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
   6804}
   6805
   6806static __le16 brcmf_get_mcs_map(u32 nchain, enum ieee80211_vht_mcs_support supp)
   6807{
   6808	u16 mcs_map;
   6809	int i;
   6810
   6811	for (i = 0, mcs_map = 0xFFFF; i < nchain; i++)
   6812		mcs_map = (mcs_map << 2) | supp;
   6813
   6814	return cpu_to_le16(mcs_map);
   6815}
   6816
   6817static void brcmf_update_vht_cap(struct ieee80211_supported_band *band,
   6818				 u32 bw_cap[2], u32 nchain, u32 txstreams,
   6819				 u32 txbf_bfe_cap, u32 txbf_bfr_cap)
   6820{
   6821	__le16 mcs_map;
   6822
   6823	/* not allowed in 2.4G band */
   6824	if (band->band == NL80211_BAND_2GHZ)
   6825		return;
   6826
   6827	band->vht_cap.vht_supported = true;
   6828	/* 80MHz is mandatory */
   6829	band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_80;
   6830	if (bw_cap[band->band] & WLC_BW_160MHZ_BIT) {
   6831		band->vht_cap.cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
   6832		band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_160;
   6833	}
   6834	/* all support 256-QAM */
   6835	mcs_map = brcmf_get_mcs_map(nchain, IEEE80211_VHT_MCS_SUPPORT_0_9);
   6836	band->vht_cap.vht_mcs.rx_mcs_map = mcs_map;
   6837	band->vht_cap.vht_mcs.tx_mcs_map = mcs_map;
   6838
   6839	/* Beamforming support information */
   6840	if (txbf_bfe_cap & BRCMF_TXBF_SU_BFE_CAP)
   6841		band->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE;
   6842	if (txbf_bfe_cap & BRCMF_TXBF_MU_BFE_CAP)
   6843		band->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;
   6844	if (txbf_bfr_cap & BRCMF_TXBF_SU_BFR_CAP)
   6845		band->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE;
   6846	if (txbf_bfr_cap & BRCMF_TXBF_MU_BFR_CAP)
   6847		band->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE;
   6848
   6849	if ((txbf_bfe_cap || txbf_bfr_cap) && (txstreams > 1)) {
   6850		band->vht_cap.cap |=
   6851			(2 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT);
   6852		band->vht_cap.cap |= ((txstreams - 1) <<
   6853				IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT);
   6854		band->vht_cap.cap |=
   6855			IEEE80211_VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB;
   6856	}
   6857}
   6858
   6859static int brcmf_setup_wiphybands(struct brcmf_cfg80211_info *cfg)
   6860{
   6861	struct brcmf_pub *drvr = cfg->pub;
   6862	struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0);
   6863	struct wiphy *wiphy = cfg_to_wiphy(cfg);
   6864	u32 nmode = 0;
   6865	u32 vhtmode = 0;
   6866	u32 bw_cap[2] = { WLC_BW_20MHZ_BIT, WLC_BW_20MHZ_BIT };
   6867	u32 rxchain;
   6868	u32 nchain;
   6869	int err;
   6870	s32 i;
   6871	struct ieee80211_supported_band *band;
   6872	u32 txstreams = 0;
   6873	u32 txbf_bfe_cap = 0;
   6874	u32 txbf_bfr_cap = 0;
   6875
   6876	(void)brcmf_fil_iovar_int_get(ifp, "vhtmode", &vhtmode);
   6877	err = brcmf_fil_iovar_int_get(ifp, "nmode", &nmode);
   6878	if (err) {
   6879		bphy_err(drvr, "nmode error (%d)\n", err);
   6880	} else {
   6881		brcmf_get_bwcap(ifp, bw_cap);
   6882	}
   6883	brcmf_dbg(INFO, "nmode=%d, vhtmode=%d, bw_cap=(%d, %d)\n",
   6884		  nmode, vhtmode, bw_cap[NL80211_BAND_2GHZ],
   6885		  bw_cap[NL80211_BAND_5GHZ]);
   6886
   6887	err = brcmf_fil_iovar_int_get(ifp, "rxchain", &rxchain);
   6888	if (err) {
   6889		/* rxchain unsupported by firmware of older chips */
   6890		if (err == -EBADE)
   6891			bphy_info_once(drvr, "rxchain unsupported\n");
   6892		else
   6893			bphy_err(drvr, "rxchain error (%d)\n", err);
   6894
   6895		nchain = 1;
   6896	} else {
   6897		for (nchain = 0; rxchain; nchain++)
   6898			rxchain = rxchain & (rxchain - 1);
   6899	}
   6900	brcmf_dbg(INFO, "nchain=%d\n", nchain);
   6901
   6902	err = brcmf_construct_chaninfo(cfg, bw_cap);
   6903	if (err) {
   6904		bphy_err(drvr, "brcmf_construct_chaninfo failed (%d)\n", err);
   6905		return err;
   6906	}
   6907
   6908	if (vhtmode) {
   6909		(void)brcmf_fil_iovar_int_get(ifp, "txstreams", &txstreams);
   6910		(void)brcmf_fil_iovar_int_get(ifp, "txbf_bfe_cap",
   6911					      &txbf_bfe_cap);
   6912		(void)brcmf_fil_iovar_int_get(ifp, "txbf_bfr_cap",
   6913					      &txbf_bfr_cap);
   6914	}
   6915
   6916	for (i = 0; i < ARRAY_SIZE(wiphy->bands); i++) {
   6917		band = wiphy->bands[i];
   6918		if (band == NULL)
   6919			continue;
   6920
   6921		if (nmode)
   6922			brcmf_update_ht_cap(band, bw_cap, nchain);
   6923		if (vhtmode)
   6924			brcmf_update_vht_cap(band, bw_cap, nchain, txstreams,
   6925					     txbf_bfe_cap, txbf_bfr_cap);
   6926	}
   6927
   6928	return 0;
   6929}
   6930
   6931static const struct ieee80211_txrx_stypes
   6932brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = {
   6933	[NL80211_IFTYPE_STATION] = {
   6934		.tx = 0xffff,
   6935		.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
   6936		      BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
   6937	},
   6938	[NL80211_IFTYPE_P2P_CLIENT] = {
   6939		.tx = 0xffff,
   6940		.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
   6941		      BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
   6942	},
   6943	[NL80211_IFTYPE_P2P_GO] = {
   6944		.tx = 0xffff,
   6945		.rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
   6946		      BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
   6947		      BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
   6948		      BIT(IEEE80211_STYPE_DISASSOC >> 4) |
   6949		      BIT(IEEE80211_STYPE_AUTH >> 4) |
   6950		      BIT(IEEE80211_STYPE_DEAUTH >> 4) |
   6951		      BIT(IEEE80211_STYPE_ACTION >> 4)
   6952	},
   6953	[NL80211_IFTYPE_P2P_DEVICE] = {
   6954		.tx = 0xffff,
   6955		.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
   6956		      BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
   6957	},
   6958	[NL80211_IFTYPE_AP] = {
   6959		.tx = 0xffff,
   6960		.rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
   6961		      BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
   6962		      BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
   6963		      BIT(IEEE80211_STYPE_DISASSOC >> 4) |
   6964		      BIT(IEEE80211_STYPE_AUTH >> 4) |
   6965		      BIT(IEEE80211_STYPE_DEAUTH >> 4) |
   6966		      BIT(IEEE80211_STYPE_ACTION >> 4)
   6967	}
   6968};
   6969
   6970/**
   6971 * brcmf_setup_ifmodes() - determine interface modes and combinations.
   6972 *
   6973 * @wiphy: wiphy object.
   6974 * @ifp: interface object needed for feat module api.
   6975 *
   6976 * The interface modes and combinations are determined dynamically here
   6977 * based on firmware functionality.
   6978 *
   6979 * no p2p and no mbss:
   6980 *
   6981 *	#STA <= 1, #AP <= 1, channels = 1, 2 total
   6982 *
   6983 * no p2p and mbss:
   6984 *
   6985 *	#STA <= 1, #AP <= 1, channels = 1, 2 total
   6986 *	#AP <= 4, matching BI, channels = 1, 4 total
   6987 *
   6988 * no p2p and rsdb:
   6989 *	#STA <= 1, #AP <= 2, channels = 2, 4 total
   6990 *
   6991 * p2p, no mchan, and mbss:
   6992 *
   6993 *	#STA <= 1, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 1, channels = 1, 3 total
   6994 *	#STA <= 1, #P2P-DEV <= 1, #AP <= 1, #P2P-CL <= 1, channels = 1, 4 total
   6995 *	#AP <= 4, matching BI, channels = 1, 4 total
   6996 *
   6997 * p2p, mchan, and mbss:
   6998 *
   6999 *	#STA <= 1, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 1, channels = 2, 3 total
   7000 *	#STA <= 1, #P2P-DEV <= 1, #AP <= 1, #P2P-CL <= 1, channels = 1, 4 total
   7001 *	#AP <= 4, matching BI, channels = 1, 4 total
   7002 *
   7003 * p2p, rsdb, and no mbss:
   7004 *	#STA <= 1, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 2, AP <= 2,
   7005 *	 channels = 2, 4 total
   7006 */
   7007static int brcmf_setup_ifmodes(struct wiphy *wiphy, struct brcmf_if *ifp)
   7008{
   7009	struct ieee80211_iface_combination *combo = NULL;
   7010	struct ieee80211_iface_limit *c0_limits = NULL;
   7011	struct ieee80211_iface_limit *p2p_limits = NULL;
   7012	struct ieee80211_iface_limit *mbss_limits = NULL;
   7013	bool mon_flag, mbss, p2p, rsdb, mchan;
   7014	int i, c, n_combos, n_limits;
   7015
   7016	mon_flag = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MONITOR_FLAG);
   7017	mbss = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS);
   7018	p2p = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_P2P);
   7019	rsdb = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_RSDB);
   7020	mchan = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN);
   7021
   7022	n_combos = 1 + !!(p2p && !rsdb) + !!mbss;
   7023	combo = kcalloc(n_combos, sizeof(*combo), GFP_KERNEL);
   7024	if (!combo)
   7025		goto err;
   7026
   7027	wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
   7028				 BIT(NL80211_IFTYPE_ADHOC) |
   7029				 BIT(NL80211_IFTYPE_AP);
   7030	if (mon_flag)
   7031		wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
   7032	if (p2p)
   7033		wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_CLIENT) |
   7034					  BIT(NL80211_IFTYPE_P2P_GO) |
   7035					  BIT(NL80211_IFTYPE_P2P_DEVICE);
   7036
   7037	c = 0;
   7038	i = 0;
   7039	n_limits = 1 + mon_flag + (p2p ? 2 : 0) + (rsdb || !p2p);
   7040	c0_limits = kcalloc(n_limits, sizeof(*c0_limits), GFP_KERNEL);
   7041	if (!c0_limits)
   7042		goto err;
   7043
   7044	combo[c].num_different_channels = 1 + (rsdb || (p2p && mchan));
   7045	c0_limits[i].max = 1;
   7046	c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
   7047	if (mon_flag) {
   7048		c0_limits[i].max = 1;
   7049		c0_limits[i++].types = BIT(NL80211_IFTYPE_MONITOR);
   7050	}
   7051	if (p2p) {
   7052		c0_limits[i].max = 1;
   7053		c0_limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE);
   7054		c0_limits[i].max = 1 + rsdb;
   7055		c0_limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
   7056				       BIT(NL80211_IFTYPE_P2P_GO);
   7057	}
   7058	if (p2p && rsdb) {
   7059		c0_limits[i].max = 2;
   7060		c0_limits[i++].types = BIT(NL80211_IFTYPE_AP);
   7061		combo[c].max_interfaces = 4;
   7062	} else if (p2p) {
   7063		combo[c].max_interfaces = i;
   7064	} else if (rsdb) {
   7065		c0_limits[i].max = 2;
   7066		c0_limits[i++].types = BIT(NL80211_IFTYPE_AP);
   7067		combo[c].max_interfaces = 3;
   7068	} else {
   7069		c0_limits[i].max = 1;
   7070		c0_limits[i++].types = BIT(NL80211_IFTYPE_AP);
   7071		combo[c].max_interfaces = i;
   7072	}
   7073	combo[c].n_limits = i;
   7074	combo[c].limits = c0_limits;
   7075
   7076	if (p2p && !rsdb) {
   7077		c++;
   7078		i = 0;
   7079		p2p_limits = kcalloc(4, sizeof(*p2p_limits), GFP_KERNEL);
   7080		if (!p2p_limits)
   7081			goto err;
   7082		p2p_limits[i].max = 1;
   7083		p2p_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
   7084		p2p_limits[i].max = 1;
   7085		p2p_limits[i++].types = BIT(NL80211_IFTYPE_AP);
   7086		p2p_limits[i].max = 1;
   7087		p2p_limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT);
   7088		p2p_limits[i].max = 1;
   7089		p2p_limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE);
   7090		combo[c].num_different_channels = 1;
   7091		combo[c].max_interfaces = i;
   7092		combo[c].n_limits = i;
   7093		combo[c].limits = p2p_limits;
   7094	}
   7095
   7096	if (mbss) {
   7097		c++;
   7098		i = 0;
   7099		n_limits = 1 + mon_flag;
   7100		mbss_limits = kcalloc(n_limits, sizeof(*mbss_limits),
   7101				      GFP_KERNEL);
   7102		if (!mbss_limits)
   7103			goto err;
   7104		mbss_limits[i].max = 4;
   7105		mbss_limits[i++].types = BIT(NL80211_IFTYPE_AP);
   7106		if (mon_flag) {
   7107			mbss_limits[i].max = 1;
   7108			mbss_limits[i++].types = BIT(NL80211_IFTYPE_MONITOR);
   7109		}
   7110		combo[c].beacon_int_infra_match = true;
   7111		combo[c].num_different_channels = 1;
   7112		combo[c].max_interfaces = 4 + mon_flag;
   7113		combo[c].n_limits = i;
   7114		combo[c].limits = mbss_limits;
   7115	}
   7116
   7117	wiphy->n_iface_combinations = n_combos;
   7118	wiphy->iface_combinations = combo;
   7119	return 0;
   7120
   7121err:
   7122	kfree(c0_limits);
   7123	kfree(p2p_limits);
   7124	kfree(mbss_limits);
   7125	kfree(combo);
   7126	return -ENOMEM;
   7127}
   7128
   7129#ifdef CONFIG_PM
   7130static const struct wiphy_wowlan_support brcmf_wowlan_support = {
   7131	.flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT,
   7132	.n_patterns = BRCMF_WOWL_MAXPATTERNS,
   7133	.pattern_max_len = BRCMF_WOWL_MAXPATTERNSIZE,
   7134	.pattern_min_len = 1,
   7135	.max_pkt_offset = 1500,
   7136};
   7137#endif
   7138
   7139static void brcmf_wiphy_wowl_params(struct wiphy *wiphy, struct brcmf_if *ifp)
   7140{
   7141#ifdef CONFIG_PM
   7142	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
   7143	struct brcmf_pub *drvr = cfg->pub;
   7144	struct wiphy_wowlan_support *wowl;
   7145
   7146	wowl = kmemdup(&brcmf_wowlan_support, sizeof(brcmf_wowlan_support),
   7147		       GFP_KERNEL);
   7148	if (!wowl) {
   7149		bphy_err(drvr, "only support basic wowlan features\n");
   7150		wiphy->wowlan = &brcmf_wowlan_support;
   7151		return;
   7152	}
   7153
   7154	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO)) {
   7155		if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_ND)) {
   7156			wowl->flags |= WIPHY_WOWLAN_NET_DETECT;
   7157			wowl->max_nd_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
   7158			init_waitqueue_head(&cfg->wowl.nd_data_wait);
   7159		}
   7160	}
   7161	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_GTK)) {
   7162		wowl->flags |= WIPHY_WOWLAN_SUPPORTS_GTK_REKEY;
   7163		wowl->flags |= WIPHY_WOWLAN_GTK_REKEY_FAILURE;
   7164	}
   7165
   7166	wiphy->wowlan = wowl;
   7167#endif
   7168}
   7169
   7170static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp)
   7171{
   7172	struct brcmf_pub *drvr = ifp->drvr;
   7173	const struct ieee80211_iface_combination *combo;
   7174	struct ieee80211_supported_band *band;
   7175	u16 max_interfaces = 0;
   7176	bool gscan;
   7177	__le32 bandlist[3];
   7178	u32 n_bands;
   7179	int err, i;
   7180
   7181	wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
   7182	wiphy->max_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
   7183	wiphy->max_num_pmkids = BRCMF_MAXPMKID;
   7184
   7185	err = brcmf_setup_ifmodes(wiphy, ifp);
   7186	if (err)
   7187		return err;
   7188
   7189	for (i = 0, combo = wiphy->iface_combinations;
   7190	     i < wiphy->n_iface_combinations; i++, combo++) {
   7191		max_interfaces = max(max_interfaces, combo->max_interfaces);
   7192	}
   7193
   7194	for (i = 0; i < max_interfaces && i < ARRAY_SIZE(drvr->addresses);
   7195	     i++) {
   7196		u8 *addr = drvr->addresses[i].addr;
   7197
   7198		memcpy(addr, drvr->mac, ETH_ALEN);
   7199		if (i) {
   7200			addr[0] |= BIT(1);
   7201			addr[ETH_ALEN - 1] ^= i;
   7202		}
   7203	}
   7204	wiphy->addresses = drvr->addresses;
   7205	wiphy->n_addresses = i;
   7206
   7207	wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
   7208	wiphy->cipher_suites = brcmf_cipher_suites;
   7209	wiphy->n_cipher_suites = ARRAY_SIZE(brcmf_cipher_suites);
   7210	if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP))
   7211		wiphy->n_cipher_suites--;
   7212	wiphy->bss_select_support = BIT(NL80211_BSS_SELECT_ATTR_RSSI) |
   7213				    BIT(NL80211_BSS_SELECT_ATTR_BAND_PREF) |
   7214				    BIT(NL80211_BSS_SELECT_ATTR_RSSI_ADJUST);
   7215
   7216	wiphy->flags |= WIPHY_FLAG_NETNS_OK |
   7217			WIPHY_FLAG_PS_ON_BY_DEFAULT |
   7218			WIPHY_FLAG_HAVE_AP_SME |
   7219			WIPHY_FLAG_OFFCHAN_TX |
   7220			WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
   7221	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_TDLS))
   7222		wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
   7223	if (!ifp->drvr->settings->roamoff)
   7224		wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
   7225	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_FWSUP)) {
   7226		wiphy_ext_feature_set(wiphy,
   7227				      NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_PSK);
   7228		wiphy_ext_feature_set(wiphy,
   7229				      NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X);
   7230		if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_SAE))
   7231			wiphy_ext_feature_set(wiphy,
   7232					      NL80211_EXT_FEATURE_SAE_OFFLOAD);
   7233	}
   7234	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_FWAUTH)) {
   7235		wiphy_ext_feature_set(wiphy,
   7236				      NL80211_EXT_FEATURE_4WAY_HANDSHAKE_AP_PSK);
   7237		if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_SAE))
   7238			wiphy_ext_feature_set(wiphy,
   7239					      NL80211_EXT_FEATURE_SAE_OFFLOAD_AP);
   7240	}
   7241	wiphy->mgmt_stypes = brcmf_txrx_stypes;
   7242	wiphy->max_remain_on_channel_duration = 5000;
   7243	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO)) {
   7244		gscan = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_GSCAN);
   7245		brcmf_pno_wiphy_params(wiphy, gscan);
   7246	}
   7247	/* vendor commands/events support */
   7248	wiphy->vendor_commands = brcmf_vendor_cmds;
   7249	wiphy->n_vendor_commands = BRCMF_VNDR_CMDS_LAST - 1;
   7250
   7251	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL))
   7252		brcmf_wiphy_wowl_params(wiphy, ifp);
   7253	err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BANDLIST, &bandlist,
   7254				     sizeof(bandlist));
   7255	if (err) {
   7256		bphy_err(drvr, "could not obtain band info: err=%d\n", err);
   7257		return err;
   7258	}
   7259	/* first entry in bandlist is number of bands */
   7260	n_bands = le32_to_cpu(bandlist[0]);
   7261	for (i = 1; i <= n_bands && i < ARRAY_SIZE(bandlist); i++) {
   7262		if (bandlist[i] == cpu_to_le32(WLC_BAND_2G)) {
   7263			band = kmemdup(&__wl_band_2ghz, sizeof(__wl_band_2ghz),
   7264				       GFP_KERNEL);
   7265			if (!band)
   7266				return -ENOMEM;
   7267
   7268			band->channels = kmemdup(&__wl_2ghz_channels,
   7269						 sizeof(__wl_2ghz_channels),
   7270						 GFP_KERNEL);
   7271			if (!band->channels) {
   7272				kfree(band);
   7273				return -ENOMEM;
   7274			}
   7275
   7276			band->n_channels = ARRAY_SIZE(__wl_2ghz_channels);
   7277			wiphy->bands[NL80211_BAND_2GHZ] = band;
   7278		}
   7279		if (bandlist[i] == cpu_to_le32(WLC_BAND_5G)) {
   7280			band = kmemdup(&__wl_band_5ghz, sizeof(__wl_band_5ghz),
   7281				       GFP_KERNEL);
   7282			if (!band)
   7283				return -ENOMEM;
   7284
   7285			band->channels = kmemdup(&__wl_5ghz_channels,
   7286						 sizeof(__wl_5ghz_channels),
   7287						 GFP_KERNEL);
   7288			if (!band->channels) {
   7289				kfree(band);
   7290				return -ENOMEM;
   7291			}
   7292
   7293			band->n_channels = ARRAY_SIZE(__wl_5ghz_channels);
   7294			wiphy->bands[NL80211_BAND_5GHZ] = band;
   7295		}
   7296	}
   7297
   7298	if (wiphy->bands[NL80211_BAND_5GHZ] &&
   7299	    brcmf_feat_is_enabled(ifp, BRCMF_FEAT_DOT11H))
   7300		wiphy_ext_feature_set(wiphy,
   7301				      NL80211_EXT_FEATURE_DFS_OFFLOAD);
   7302
   7303	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
   7304
   7305	wiphy_read_of_freq_limits(wiphy);
   7306
   7307	return 0;
   7308}
   7309
   7310static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
   7311{
   7312	struct brcmf_pub *drvr = cfg->pub;
   7313	struct net_device *ndev;
   7314	struct wireless_dev *wdev;
   7315	struct brcmf_if *ifp;
   7316	s32 power_mode;
   7317	s32 err = 0;
   7318
   7319	if (cfg->dongle_up)
   7320		return err;
   7321
   7322	ndev = cfg_to_ndev(cfg);
   7323	wdev = ndev->ieee80211_ptr;
   7324	ifp = netdev_priv(ndev);
   7325
   7326	/* make sure RF is ready for work */
   7327	brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
   7328
   7329	brcmf_dongle_scantime(ifp);
   7330
   7331	power_mode = cfg->pwr_save ? PM_FAST : PM_OFF;
   7332	err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, power_mode);
   7333	if (err)
   7334		goto default_conf_out;
   7335	brcmf_dbg(INFO, "power save set to %s\n",
   7336		  (power_mode ? "enabled" : "disabled"));
   7337
   7338	err = brcmf_dongle_roam(ifp);
   7339	if (err)
   7340		goto default_conf_out;
   7341	err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype,
   7342					  NULL);
   7343	if (err)
   7344		goto default_conf_out;
   7345
   7346	brcmf_configure_arp_nd_offload(ifp, true);
   7347
   7348	err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_FAKEFRAG, 1);
   7349	if (err) {
   7350		bphy_err(drvr, "failed to set frameburst mode\n");
   7351		goto default_conf_out;
   7352	}
   7353
   7354	cfg->dongle_up = true;
   7355default_conf_out:
   7356
   7357	return err;
   7358
   7359}
   7360
   7361static s32 __brcmf_cfg80211_up(struct brcmf_if *ifp)
   7362{
   7363	set_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
   7364
   7365	return brcmf_config_dongle(ifp->drvr->config);
   7366}
   7367
   7368static s32 __brcmf_cfg80211_down(struct brcmf_if *ifp)
   7369{
   7370	struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
   7371
   7372	/*
   7373	 * While going down, if associated with AP disassociate
   7374	 * from AP to save power
   7375	 */
   7376	if (check_vif_up(ifp->vif)) {
   7377		brcmf_link_down(ifp->vif, WLAN_REASON_UNSPECIFIED, true);
   7378
   7379		/* Make sure WPA_Supplicant receives all the event
   7380		   generated due to DISASSOC call to the fw to keep
   7381		   the state fw and WPA_Supplicant state consistent
   7382		 */
   7383		brcmf_delay(500);
   7384	}
   7385
   7386	brcmf_abort_scanning(cfg);
   7387	clear_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
   7388
   7389	return 0;
   7390}
   7391
   7392s32 brcmf_cfg80211_up(struct net_device *ndev)
   7393{
   7394	struct brcmf_if *ifp = netdev_priv(ndev);
   7395	struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
   7396	s32 err = 0;
   7397
   7398	mutex_lock(&cfg->usr_sync);
   7399	err = __brcmf_cfg80211_up(ifp);
   7400	mutex_unlock(&cfg->usr_sync);
   7401
   7402	return err;
   7403}
   7404
   7405s32 brcmf_cfg80211_down(struct net_device *ndev)
   7406{
   7407	struct brcmf_if *ifp = netdev_priv(ndev);
   7408	struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
   7409	s32 err = 0;
   7410
   7411	mutex_lock(&cfg->usr_sync);
   7412	err = __brcmf_cfg80211_down(ifp);
   7413	mutex_unlock(&cfg->usr_sync);
   7414
   7415	return err;
   7416}
   7417
   7418enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp)
   7419{
   7420	struct wireless_dev *wdev = &ifp->vif->wdev;
   7421
   7422	return wdev->iftype;
   7423}
   7424
   7425bool brcmf_get_vif_state_any(struct brcmf_cfg80211_info *cfg,
   7426			     unsigned long state)
   7427{
   7428	struct brcmf_cfg80211_vif *vif;
   7429
   7430	list_for_each_entry(vif, &cfg->vif_list, list) {
   7431		if (test_bit(state, &vif->sme_state))
   7432			return true;
   7433	}
   7434	return false;
   7435}
   7436
   7437static inline bool vif_event_equals(struct brcmf_cfg80211_vif_event *event,
   7438				    u8 action)
   7439{
   7440	u8 evt_action;
   7441
   7442	spin_lock(&event->vif_event_lock);
   7443	evt_action = event->action;
   7444	spin_unlock(&event->vif_event_lock);
   7445	return evt_action == action;
   7446}
   7447
   7448void brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info *cfg,
   7449				  struct brcmf_cfg80211_vif *vif)
   7450{
   7451	struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
   7452
   7453	spin_lock(&event->vif_event_lock);
   7454	event->vif = vif;
   7455	event->action = 0;
   7456	spin_unlock(&event->vif_event_lock);
   7457}
   7458
   7459bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info *cfg)
   7460{
   7461	struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
   7462	bool armed;
   7463
   7464	spin_lock(&event->vif_event_lock);
   7465	armed = event->vif != NULL;
   7466	spin_unlock(&event->vif_event_lock);
   7467
   7468	return armed;
   7469}
   7470
   7471int brcmf_cfg80211_wait_vif_event(struct brcmf_cfg80211_info *cfg,
   7472				  u8 action, ulong timeout)
   7473{
   7474	struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
   7475
   7476	return wait_event_timeout(event->vif_wq,
   7477				  vif_event_equals(event, action), timeout);
   7478}
   7479
   7480static bool brmcf_use_iso3166_ccode_fallback(struct brcmf_pub *drvr)
   7481{
   7482	switch (drvr->bus_if->chip) {
   7483	case BRCM_CC_4345_CHIP_ID:
   7484	case BRCM_CC_43602_CHIP_ID:
   7485		return true;
   7486	default:
   7487		return false;
   7488	}
   7489}
   7490
   7491static s32 brcmf_translate_country_code(struct brcmf_pub *drvr, char alpha2[2],
   7492					struct brcmf_fil_country_le *ccreq)
   7493{
   7494	struct brcmfmac_pd_cc *country_codes;
   7495	struct brcmfmac_pd_cc_entry *cc;
   7496	s32 found_index;
   7497	int i;
   7498
   7499	if ((alpha2[0] == ccreq->country_abbrev[0]) &&
   7500	    (alpha2[1] == ccreq->country_abbrev[1])) {
   7501		brcmf_dbg(TRACE, "Country code already set\n");
   7502		return -EAGAIN;
   7503	}
   7504
   7505	country_codes = drvr->settings->country_codes;
   7506	if (!country_codes) {
   7507		if (brmcf_use_iso3166_ccode_fallback(drvr)) {
   7508			brcmf_dbg(TRACE, "No country codes configured for device, using ISO3166 code and 0 rev\n");
   7509			memset(ccreq, 0, sizeof(*ccreq));
   7510			ccreq->country_abbrev[0] = alpha2[0];
   7511			ccreq->country_abbrev[1] = alpha2[1];
   7512			ccreq->ccode[0] = alpha2[0];
   7513			ccreq->ccode[1] = alpha2[1];
   7514			return 0;
   7515		}
   7516
   7517		brcmf_dbg(TRACE, "No country codes configured for device\n");
   7518		return -EINVAL;
   7519	}
   7520
   7521	found_index = -1;
   7522	for (i = 0; i < country_codes->table_size; i++) {
   7523		cc = &country_codes->table[i];
   7524		if ((cc->iso3166[0] == '\0') && (found_index == -1))
   7525			found_index = i;
   7526		if ((cc->iso3166[0] == alpha2[0]) &&
   7527		    (cc->iso3166[1] == alpha2[1])) {
   7528			found_index = i;
   7529			break;
   7530		}
   7531	}
   7532	if (found_index == -1) {
   7533		brcmf_dbg(TRACE, "No country code match found\n");
   7534		return -EINVAL;
   7535	}
   7536	memset(ccreq, 0, sizeof(*ccreq));
   7537	ccreq->rev = cpu_to_le32(country_codes->table[found_index].rev);
   7538	memcpy(ccreq->ccode, country_codes->table[found_index].cc,
   7539	       BRCMF_COUNTRY_BUF_SZ);
   7540	ccreq->country_abbrev[0] = alpha2[0];
   7541	ccreq->country_abbrev[1] = alpha2[1];
   7542	ccreq->country_abbrev[2] = 0;
   7543
   7544	return 0;
   7545}
   7546
   7547static void brcmf_cfg80211_reg_notifier(struct wiphy *wiphy,
   7548					struct regulatory_request *req)
   7549{
   7550	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
   7551	struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0);
   7552	struct brcmf_pub *drvr = cfg->pub;
   7553	struct brcmf_fil_country_le ccreq;
   7554	s32 err;
   7555	int i;
   7556
   7557	/* The country code gets set to "00" by default at boot, ignore */
   7558	if (req->alpha2[0] == '0' && req->alpha2[1] == '0')
   7559		return;
   7560
   7561	/* ignore non-ISO3166 country codes */
   7562	for (i = 0; i < 2; i++)
   7563		if (req->alpha2[i] < 'A' || req->alpha2[i] > 'Z') {
   7564			bphy_err(drvr, "not an ISO3166 code (0x%02x 0x%02x)\n",
   7565				 req->alpha2[0], req->alpha2[1]);
   7566			return;
   7567		}
   7568
   7569	brcmf_dbg(TRACE, "Enter: initiator=%d, alpha=%c%c\n", req->initiator,
   7570		  req->alpha2[0], req->alpha2[1]);
   7571
   7572	err = brcmf_fil_iovar_data_get(ifp, "country", &ccreq, sizeof(ccreq));
   7573	if (err) {
   7574		bphy_err(drvr, "Country code iovar returned err = %d\n", err);
   7575		return;
   7576	}
   7577
   7578	err = brcmf_translate_country_code(ifp->drvr, req->alpha2, &ccreq);
   7579	if (err)
   7580		return;
   7581
   7582	err = brcmf_fil_iovar_data_set(ifp, "country", &ccreq, sizeof(ccreq));
   7583	if (err) {
   7584		bphy_err(drvr, "Firmware rejected country setting\n");
   7585		return;
   7586	}
   7587	brcmf_setup_wiphybands(cfg);
   7588}
   7589
   7590static void brcmf_free_wiphy(struct wiphy *wiphy)
   7591{
   7592	int i;
   7593
   7594	if (!wiphy)
   7595		return;
   7596
   7597	if (wiphy->iface_combinations) {
   7598		for (i = 0; i < wiphy->n_iface_combinations; i++)
   7599			kfree(wiphy->iface_combinations[i].limits);
   7600	}
   7601	kfree(wiphy->iface_combinations);
   7602	if (wiphy->bands[NL80211_BAND_2GHZ]) {
   7603		kfree(wiphy->bands[NL80211_BAND_2GHZ]->channels);
   7604		kfree(wiphy->bands[NL80211_BAND_2GHZ]);
   7605	}
   7606	if (wiphy->bands[NL80211_BAND_5GHZ]) {
   7607		kfree(wiphy->bands[NL80211_BAND_5GHZ]->channels);
   7608		kfree(wiphy->bands[NL80211_BAND_5GHZ]);
   7609	}
   7610#if IS_ENABLED(CONFIG_PM)
   7611	if (wiphy->wowlan != &brcmf_wowlan_support)
   7612		kfree(wiphy->wowlan);
   7613#endif
   7614}
   7615
   7616struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
   7617						  struct cfg80211_ops *ops,
   7618						  bool p2pdev_forced)
   7619{
   7620	struct wiphy *wiphy = drvr->wiphy;
   7621	struct net_device *ndev = brcmf_get_ifp(drvr, 0)->ndev;
   7622	struct brcmf_cfg80211_info *cfg;
   7623	struct brcmf_cfg80211_vif *vif;
   7624	struct brcmf_if *ifp;
   7625	s32 err = 0;
   7626	s32 io_type;
   7627	u16 *cap = NULL;
   7628
   7629	if (!ndev) {
   7630		bphy_err(drvr, "ndev is invalid\n");
   7631		return NULL;
   7632	}
   7633
   7634	cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
   7635	if (!cfg) {
   7636		bphy_err(drvr, "Could not allocate wiphy device\n");
   7637		return NULL;
   7638	}
   7639
   7640	cfg->wiphy = wiphy;
   7641	cfg->pub = drvr;
   7642	init_vif_event(&cfg->vif_event);
   7643	INIT_LIST_HEAD(&cfg->vif_list);
   7644
   7645	vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_STATION);
   7646	if (IS_ERR(vif))
   7647		goto wiphy_out;
   7648
   7649	ifp = netdev_priv(ndev);
   7650	vif->ifp = ifp;
   7651	vif->wdev.netdev = ndev;
   7652	ndev->ieee80211_ptr = &vif->wdev;
   7653	SET_NETDEV_DEV(ndev, wiphy_dev(cfg->wiphy));
   7654
   7655	err = wl_init_priv(cfg);
   7656	if (err) {
   7657		bphy_err(drvr, "Failed to init iwm_priv (%d)\n", err);
   7658		brcmf_free_vif(vif);
   7659		goto wiphy_out;
   7660	}
   7661	ifp->vif = vif;
   7662
   7663	/* determine d11 io type before wiphy setup */
   7664	err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_VERSION, &io_type);
   7665	if (err) {
   7666		bphy_err(drvr, "Failed to get D11 version (%d)\n", err);
   7667		goto priv_out;
   7668	}
   7669	cfg->d11inf.io_type = (u8)io_type;
   7670	brcmu_d11_attach(&cfg->d11inf);
   7671
   7672	/* regulatory notifer below needs access to cfg so
   7673	 * assign it now.
   7674	 */
   7675	drvr->config = cfg;
   7676
   7677	err = brcmf_setup_wiphy(wiphy, ifp);
   7678	if (err < 0)
   7679		goto priv_out;
   7680
   7681	brcmf_dbg(INFO, "Registering custom regulatory\n");
   7682	wiphy->reg_notifier = brcmf_cfg80211_reg_notifier;
   7683	wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
   7684	wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom);
   7685
   7686	/* firmware defaults to 40MHz disabled in 2G band. We signal
   7687	 * cfg80211 here that we do and have it decide we can enable
   7688	 * it. But first check if device does support 2G operation.
   7689	 */
   7690	if (wiphy->bands[NL80211_BAND_2GHZ]) {
   7691		cap = &wiphy->bands[NL80211_BAND_2GHZ]->ht_cap.cap;
   7692		*cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
   7693	}
   7694#ifdef CONFIG_PM
   7695	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_GTK))
   7696		ops->set_rekey_data = brcmf_cfg80211_set_rekey_data;
   7697#endif
   7698	err = wiphy_register(wiphy);
   7699	if (err < 0) {
   7700		bphy_err(drvr, "Could not register wiphy device (%d)\n", err);
   7701		goto priv_out;
   7702	}
   7703
   7704	err = brcmf_setup_wiphybands(cfg);
   7705	if (err) {
   7706		bphy_err(drvr, "Setting wiphy bands failed (%d)\n", err);
   7707		goto wiphy_unreg_out;
   7708	}
   7709
   7710	/* If cfg80211 didn't disable 40MHz HT CAP in wiphy_register(),
   7711	 * setup 40MHz in 2GHz band and enable OBSS scanning.
   7712	 */
   7713	if (cap && (*cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)) {
   7714		err = brcmf_enable_bw40_2g(cfg);
   7715		if (!err)
   7716			err = brcmf_fil_iovar_int_set(ifp, "obss_coex",
   7717						      BRCMF_OBSS_COEX_AUTO);
   7718		else
   7719			*cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
   7720	}
   7721
   7722	err = brcmf_fweh_activate_events(ifp);
   7723	if (err) {
   7724		bphy_err(drvr, "FWEH activation failed (%d)\n", err);
   7725		goto wiphy_unreg_out;
   7726	}
   7727
   7728	err = brcmf_p2p_attach(cfg, p2pdev_forced);
   7729	if (err) {
   7730		bphy_err(drvr, "P2P initialisation failed (%d)\n", err);
   7731		goto wiphy_unreg_out;
   7732	}
   7733	err = brcmf_btcoex_attach(cfg);
   7734	if (err) {
   7735		bphy_err(drvr, "BT-coex initialisation failed (%d)\n", err);
   7736		brcmf_p2p_detach(&cfg->p2p);
   7737		goto wiphy_unreg_out;
   7738	}
   7739	err = brcmf_pno_attach(cfg);
   7740	if (err) {
   7741		bphy_err(drvr, "PNO initialisation failed (%d)\n", err);
   7742		brcmf_btcoex_detach(cfg);
   7743		brcmf_p2p_detach(&cfg->p2p);
   7744		goto wiphy_unreg_out;
   7745	}
   7746
   7747	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_TDLS)) {
   7748		err = brcmf_fil_iovar_int_set(ifp, "tdls_enable", 1);
   7749		if (err) {
   7750			brcmf_dbg(INFO, "TDLS not enabled (%d)\n", err);
   7751			wiphy->flags &= ~WIPHY_FLAG_SUPPORTS_TDLS;
   7752		} else {
   7753			brcmf_fweh_register(cfg->pub, BRCMF_E_TDLS_PEER_EVENT,
   7754					    brcmf_notify_tdls_peer_event);
   7755		}
   7756	}
   7757
   7758	/* (re-) activate FWEH event handling */
   7759	err = brcmf_fweh_activate_events(ifp);
   7760	if (err) {
   7761		bphy_err(drvr, "FWEH activation failed (%d)\n", err);
   7762		goto detach;
   7763	}
   7764
   7765	/* Fill in some of the advertised nl80211 supported features */
   7766	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_SCAN_RANDOM_MAC)) {
   7767		wiphy->features |= NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR;
   7768#ifdef CONFIG_PM
   7769		if (wiphy->wowlan &&
   7770		    wiphy->wowlan->flags & WIPHY_WOWLAN_NET_DETECT)
   7771			wiphy->features |= NL80211_FEATURE_ND_RANDOM_MAC_ADDR;
   7772#endif
   7773	}
   7774
   7775	return cfg;
   7776
   7777detach:
   7778	brcmf_pno_detach(cfg);
   7779	brcmf_btcoex_detach(cfg);
   7780	brcmf_p2p_detach(&cfg->p2p);
   7781wiphy_unreg_out:
   7782	wiphy_unregister(cfg->wiphy);
   7783priv_out:
   7784	wl_deinit_priv(cfg);
   7785	brcmf_free_vif(vif);
   7786	ifp->vif = NULL;
   7787wiphy_out:
   7788	brcmf_free_wiphy(wiphy);
   7789	kfree(cfg);
   7790	return NULL;
   7791}
   7792
   7793void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
   7794{
   7795	if (!cfg)
   7796		return;
   7797
   7798	brcmf_pno_detach(cfg);
   7799	brcmf_btcoex_detach(cfg);
   7800	wiphy_unregister(cfg->wiphy);
   7801	wl_deinit_priv(cfg);
   7802	brcmf_free_wiphy(cfg->wiphy);
   7803	kfree(cfg);
   7804}