File Index
Files and directories
Sign in
FILE

cfg80211.c

File preview with syntax highlighting.

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