File Index
Files and directories
Sign in
FILE

cfg80211.c

File preview with syntax highlighting.

linux-6.19.14/drivers/net/wireless/ath/ath6kl/cfg80211.c C
   1/*
   2 * Copyright (c) 2004-2011 Atheros Communications Inc.
   3 * Copyright (c) 2011-2012 Qualcomm Atheros, Inc.
   4 *
   5 * Permission to use, copy, modify, and/or distribute this software for any
   6 * purpose with or without fee is hereby granted, provided that the above
   7 * copyright notice and this permission notice appear in all copies.
   8 *
   9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  16 */
  17
  18#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  19
  20#include <linux/moduleparam.h>
  21#include <linux/inetdevice.h>
  22#include <linux/export.h>
  23#include <linux/sched/signal.h>
  24
  25#include "core.h"
  26#include "cfg80211.h"
  27#include "debug.h"
  28#include "hif-ops.h"
  29#include "testmode.h"
  30
  31#define RATETAB_ENT(_rate, _rateid, _flags) {   \
  32	.bitrate    = (_rate),                  \
  33	.flags      = (_flags),                 \
  34	.hw_value   = (_rateid),                \
  35}
  36
  37#define CHAN2G(_channel, _freq, _flags) {   \
  38	.band           = NL80211_BAND_2GHZ,  \
  39	.hw_value       = (_channel),           \
  40	.center_freq    = (_freq),              \
  41	.flags          = (_flags),             \
  42	.max_antenna_gain   = 0,                \
  43	.max_power      = 30,                   \
  44}
  45
  46#define CHAN5G(_channel, _flags) {		    \
  47	.band           = NL80211_BAND_5GHZ,      \
  48	.hw_value       = (_channel),               \
  49	.center_freq    = 5000 + (5 * (_channel)),  \
  50	.flags          = (_flags),                 \
  51	.max_antenna_gain   = 0,                    \
  52	.max_power      = 30,                       \
  53}
  54
  55#define DEFAULT_BG_SCAN_PERIOD 60
  56
  57struct ath6kl_cfg80211_match_probe_ssid {
  58	struct cfg80211_ssid ssid;
  59	u8 flag;
  60};
  61
  62static struct ieee80211_rate ath6kl_rates[] = {
  63	RATETAB_ENT(10, 0x1, 0),
  64	RATETAB_ENT(20, 0x2, 0),
  65	RATETAB_ENT(55, 0x4, 0),
  66	RATETAB_ENT(110, 0x8, 0),
  67	RATETAB_ENT(60, 0x10, 0),
  68	RATETAB_ENT(90, 0x20, 0),
  69	RATETAB_ENT(120, 0x40, 0),
  70	RATETAB_ENT(180, 0x80, 0),
  71	RATETAB_ENT(240, 0x100, 0),
  72	RATETAB_ENT(360, 0x200, 0),
  73	RATETAB_ENT(480, 0x400, 0),
  74	RATETAB_ENT(540, 0x800, 0),
  75};
  76
  77#define ath6kl_a_rates     (ath6kl_rates + 4)
  78#define ath6kl_a_rates_size    8
  79#define ath6kl_g_rates     (ath6kl_rates + 0)
  80#define ath6kl_g_rates_size    12
  81
  82#define ath6kl_g_htcap IEEE80211_HT_CAP_SGI_20
  83#define ath6kl_a_htcap (IEEE80211_HT_CAP_SUP_WIDTH_20_40 | \
  84			IEEE80211_HT_CAP_SGI_20		 | \
  85			IEEE80211_HT_CAP_SGI_40)
  86
  87static struct ieee80211_channel ath6kl_2ghz_channels[] = {
  88	CHAN2G(1, 2412, 0),
  89	CHAN2G(2, 2417, 0),
  90	CHAN2G(3, 2422, 0),
  91	CHAN2G(4, 2427, 0),
  92	CHAN2G(5, 2432, 0),
  93	CHAN2G(6, 2437, 0),
  94	CHAN2G(7, 2442, 0),
  95	CHAN2G(8, 2447, 0),
  96	CHAN2G(9, 2452, 0),
  97	CHAN2G(10, 2457, 0),
  98	CHAN2G(11, 2462, 0),
  99	CHAN2G(12, 2467, 0),
 100	CHAN2G(13, 2472, 0),
 101	CHAN2G(14, 2484, 0),
 102};
 103
 104static struct ieee80211_channel ath6kl_5ghz_a_channels[] = {
 105	CHAN5G(36, 0), CHAN5G(40, 0),
 106	CHAN5G(44, 0), CHAN5G(48, 0),
 107	CHAN5G(52, 0), CHAN5G(56, 0),
 108	CHAN5G(60, 0), CHAN5G(64, 0),
 109	CHAN5G(100, 0), CHAN5G(104, 0),
 110	CHAN5G(108, 0), CHAN5G(112, 0),
 111	CHAN5G(116, 0), CHAN5G(120, 0),
 112	CHAN5G(124, 0), CHAN5G(128, 0),
 113	CHAN5G(132, 0), CHAN5G(136, 0),
 114	CHAN5G(140, 0), CHAN5G(149, 0),
 115	CHAN5G(153, 0), CHAN5G(157, 0),
 116	CHAN5G(161, 0), CHAN5G(165, 0),
 117	CHAN5G(184, 0), CHAN5G(188, 0),
 118	CHAN5G(192, 0), CHAN5G(196, 0),
 119	CHAN5G(200, 0), CHAN5G(204, 0),
 120	CHAN5G(208, 0), CHAN5G(212, 0),
 121	CHAN5G(216, 0),
 122};
 123
 124static struct ieee80211_supported_band ath6kl_band_2ghz = {
 125	.n_channels = ARRAY_SIZE(ath6kl_2ghz_channels),
 126	.channels = ath6kl_2ghz_channels,
 127	.n_bitrates = ath6kl_g_rates_size,
 128	.bitrates = ath6kl_g_rates,
 129	.ht_cap.cap = ath6kl_g_htcap,
 130	.ht_cap.ht_supported = true,
 131};
 132
 133static struct ieee80211_supported_band ath6kl_band_5ghz = {
 134	.n_channels = ARRAY_SIZE(ath6kl_5ghz_a_channels),
 135	.channels = ath6kl_5ghz_a_channels,
 136	.n_bitrates = ath6kl_a_rates_size,
 137	.bitrates = ath6kl_a_rates,
 138	.ht_cap.cap = ath6kl_a_htcap,
 139	.ht_cap.ht_supported = true,
 140};
 141
 142#define CCKM_KRK_CIPHER_SUITE 0x004096ff /* use for KRK */
 143
 144/* returns true if scheduled scan was stopped */
 145static bool __ath6kl_cfg80211_sscan_stop(struct ath6kl_vif *vif)
 146{
 147	struct ath6kl *ar = vif->ar;
 148
 149	if (!test_and_clear_bit(SCHED_SCANNING, &vif->flags))
 150		return false;
 151
 152	timer_delete_sync(&vif->sched_scan_timer);
 153
 154	if (ar->state == ATH6KL_STATE_RECOVERY)
 155		return true;
 156
 157	ath6kl_wmi_enable_sched_scan_cmd(ar->wmi, vif->fw_vif_idx, false);
 158
 159	return true;
 160}
 161
 162static void ath6kl_cfg80211_sscan_disable(struct ath6kl_vif *vif)
 163{
 164	struct ath6kl *ar = vif->ar;
 165	bool stopped;
 166
 167	stopped = __ath6kl_cfg80211_sscan_stop(vif);
 168
 169	if (!stopped)
 170		return;
 171
 172	cfg80211_sched_scan_stopped(ar->wiphy, 0);
 173}
 174
 175static int ath6kl_set_wpa_version(struct ath6kl_vif *vif,
 176				  enum nl80211_wpa_versions wpa_version)
 177{
 178	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: %u\n", __func__, wpa_version);
 179
 180	if (!wpa_version) {
 181		vif->auth_mode = NONE_AUTH;
 182	} else if (wpa_version & NL80211_WPA_VERSION_2) {
 183		vif->auth_mode = WPA2_AUTH;
 184	} else if (wpa_version & NL80211_WPA_VERSION_1) {
 185		vif->auth_mode = WPA_AUTH;
 186	} else {
 187		ath6kl_err("%s: %u not supported\n", __func__, wpa_version);
 188		return -ENOTSUPP;
 189	}
 190
 191	return 0;
 192}
 193
 194static int ath6kl_set_auth_type(struct ath6kl_vif *vif,
 195				enum nl80211_auth_type auth_type)
 196{
 197	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: 0x%x\n", __func__, auth_type);
 198
 199	switch (auth_type) {
 200	case NL80211_AUTHTYPE_OPEN_SYSTEM:
 201		vif->dot11_auth_mode = OPEN_AUTH;
 202		break;
 203	case NL80211_AUTHTYPE_SHARED_KEY:
 204		vif->dot11_auth_mode = SHARED_AUTH;
 205		break;
 206	case NL80211_AUTHTYPE_NETWORK_EAP:
 207		vif->dot11_auth_mode = LEAP_AUTH;
 208		break;
 209
 210	case NL80211_AUTHTYPE_AUTOMATIC:
 211		vif->dot11_auth_mode = OPEN_AUTH | SHARED_AUTH;
 212		break;
 213
 214	default:
 215		ath6kl_err("%s: 0x%x not supported\n", __func__, auth_type);
 216		return -ENOTSUPP;
 217	}
 218
 219	return 0;
 220}
 221
 222static int ath6kl_set_cipher(struct ath6kl_vif *vif, u32 cipher, bool ucast)
 223{
 224	u8 *ar_cipher = ucast ? &vif->prwise_crypto : &vif->grp_crypto;
 225	u8 *ar_cipher_len = ucast ? &vif->prwise_crypto_len :
 226		&vif->grp_crypto_len;
 227
 228	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: cipher 0x%x, ucast %u\n",
 229		   __func__, cipher, ucast);
 230
 231	switch (cipher) {
 232	case 0:
 233		/* our own hack to use value 0 as no crypto used */
 234		*ar_cipher = NONE_CRYPT;
 235		*ar_cipher_len = 0;
 236		break;
 237	case WLAN_CIPHER_SUITE_WEP40:
 238		*ar_cipher = WEP_CRYPT;
 239		*ar_cipher_len = 5;
 240		break;
 241	case WLAN_CIPHER_SUITE_WEP104:
 242		*ar_cipher = WEP_CRYPT;
 243		*ar_cipher_len = 13;
 244		break;
 245	case WLAN_CIPHER_SUITE_TKIP:
 246		*ar_cipher = TKIP_CRYPT;
 247		*ar_cipher_len = 0;
 248		break;
 249	case WLAN_CIPHER_SUITE_CCMP:
 250		*ar_cipher = AES_CRYPT;
 251		*ar_cipher_len = 0;
 252		break;
 253	case WLAN_CIPHER_SUITE_SMS4:
 254		*ar_cipher = WAPI_CRYPT;
 255		*ar_cipher_len = 0;
 256		break;
 257	default:
 258		ath6kl_err("cipher 0x%x not supported\n", cipher);
 259		return -ENOTSUPP;
 260	}
 261
 262	return 0;
 263}
 264
 265static void ath6kl_set_key_mgmt(struct ath6kl_vif *vif, u32 key_mgmt)
 266{
 267	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: 0x%x\n", __func__, key_mgmt);
 268
 269	if (key_mgmt == WLAN_AKM_SUITE_PSK) {
 270		if (vif->auth_mode == WPA_AUTH)
 271			vif->auth_mode = WPA_PSK_AUTH;
 272		else if (vif->auth_mode == WPA2_AUTH)
 273			vif->auth_mode = WPA2_PSK_AUTH;
 274	} else if (key_mgmt == 0x00409600) {
 275		if (vif->auth_mode == WPA_AUTH)
 276			vif->auth_mode = WPA_AUTH_CCKM;
 277		else if (vif->auth_mode == WPA2_AUTH)
 278			vif->auth_mode = WPA2_AUTH_CCKM;
 279	} else if (key_mgmt != WLAN_AKM_SUITE_8021X) {
 280		vif->auth_mode = NONE_AUTH;
 281	}
 282}
 283
 284static bool ath6kl_cfg80211_ready(struct ath6kl_vif *vif)
 285{
 286	struct ath6kl *ar = vif->ar;
 287
 288	if (!test_bit(WMI_READY, &ar->flag)) {
 289		ath6kl_err("wmi is not ready\n");
 290		return false;
 291	}
 292
 293	if (!test_bit(WLAN_ENABLED, &vif->flags)) {
 294		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "wlan disabled\n");
 295		return false;
 296	}
 297
 298	return true;
 299}
 300
 301static bool ath6kl_is_wpa_ie(const u8 *pos)
 302{
 303	return pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
 304		pos[2] == 0x00 && pos[3] == 0x50 &&
 305		pos[4] == 0xf2 && pos[5] == 0x01;
 306}
 307
 308static bool ath6kl_is_rsn_ie(const u8 *pos)
 309{
 310	return pos[0] == WLAN_EID_RSN;
 311}
 312
 313static bool ath6kl_is_wps_ie(const u8 *pos)
 314{
 315	return (pos[0] == WLAN_EID_VENDOR_SPECIFIC &&
 316		pos[1] >= 4 &&
 317		pos[2] == 0x00 && pos[3] == 0x50 && pos[4] == 0xf2 &&
 318		pos[5] == 0x04);
 319}
 320
 321static int ath6kl_set_assoc_req_ies(struct ath6kl_vif *vif, const u8 *ies,
 322				    size_t ies_len)
 323{
 324	struct ath6kl *ar = vif->ar;
 325	const u8 *pos;
 326	u8 *buf = NULL;
 327	size_t len = 0;
 328	int ret;
 329
 330	/*
 331	 * Clear previously set flag
 332	 */
 333
 334	ar->connect_ctrl_flags &= ~CONNECT_WPS_FLAG;
 335
 336	/*
 337	 * Filter out RSN/WPA IE(s)
 338	 */
 339
 340	if (ies && ies_len) {
 341		buf = kmalloc(ies_len, GFP_KERNEL);
 342		if (buf == NULL)
 343			return -ENOMEM;
 344		pos = ies;
 345
 346		while (pos + 1 < ies + ies_len) {
 347			if (pos + 2 + pos[1] > ies + ies_len)
 348				break;
 349			if (!(ath6kl_is_wpa_ie(pos) || ath6kl_is_rsn_ie(pos))) {
 350				memcpy(buf + len, pos, 2 + pos[1]);
 351				len += 2 + pos[1];
 352			}
 353
 354			if (ath6kl_is_wps_ie(pos))
 355				ar->connect_ctrl_flags |= CONNECT_WPS_FLAG;
 356
 357			pos += 2 + pos[1];
 358		}
 359	}
 360
 361	ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
 362				       WMI_FRAME_ASSOC_REQ, buf, len);
 363	kfree(buf);
 364	return ret;
 365}
 366
 367static int ath6kl_nliftype_to_drv_iftype(enum nl80211_iftype type, u8 *nw_type)
 368{
 369	switch (type) {
 370	case NL80211_IFTYPE_STATION:
 371	case NL80211_IFTYPE_P2P_CLIENT:
 372		*nw_type = INFRA_NETWORK;
 373		break;
 374	case NL80211_IFTYPE_ADHOC:
 375		*nw_type = ADHOC_NETWORK;
 376		break;
 377	case NL80211_IFTYPE_AP:
 378	case NL80211_IFTYPE_P2P_GO:
 379		*nw_type = AP_NETWORK;
 380		break;
 381	default:
 382		ath6kl_err("invalid interface type %u\n", type);
 383		return -ENOTSUPP;
 384	}
 385
 386	return 0;
 387}
 388
 389static bool ath6kl_is_valid_iftype(struct ath6kl *ar, enum nl80211_iftype type,
 390				   u8 *if_idx, u8 *nw_type)
 391{
 392	int i;
 393
 394	if (ath6kl_nliftype_to_drv_iftype(type, nw_type))
 395		return false;
 396
 397	if (ar->ibss_if_active || ((type == NL80211_IFTYPE_ADHOC) &&
 398				   ar->num_vif))
 399		return false;
 400
 401	if (type == NL80211_IFTYPE_STATION ||
 402	    type == NL80211_IFTYPE_AP || type == NL80211_IFTYPE_ADHOC) {
 403		for (i = 0; i < ar->vif_max; i++) {
 404			if ((ar->avail_idx_map) & BIT(i)) {
 405				*if_idx = i;
 406				return true;
 407			}
 408		}
 409	}
 410
 411	if (type == NL80211_IFTYPE_P2P_CLIENT ||
 412	    type == NL80211_IFTYPE_P2P_GO) {
 413		for (i = ar->max_norm_iface; i < ar->vif_max; i++) {
 414			if ((ar->avail_idx_map) & BIT(i)) {
 415				*if_idx = i;
 416				return true;
 417			}
 418		}
 419	}
 420
 421	return false;
 422}
 423
 424static bool ath6kl_is_tx_pending(struct ath6kl *ar)
 425{
 426	return ar->tx_pending[ath6kl_wmi_get_control_ep(ar->wmi)] == 0;
 427}
 428
 429static void ath6kl_cfg80211_sta_bmiss_enhance(struct ath6kl_vif *vif,
 430					      bool enable)
 431{
 432	int err;
 433
 434	if (WARN_ON(!test_bit(WMI_READY, &vif->ar->flag)))
 435		return;
 436
 437	if (vif->nw_type != INFRA_NETWORK)
 438		return;
 439
 440	if (!test_bit(ATH6KL_FW_CAPABILITY_BMISS_ENHANCE,
 441		      vif->ar->fw_capabilities))
 442		return;
 443
 444	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s fw bmiss enhance\n",
 445		   enable ? "enable" : "disable");
 446
 447	err = ath6kl_wmi_sta_bmiss_enhance_cmd(vif->ar->wmi,
 448					       vif->fw_vif_idx, enable);
 449	if (err)
 450		ath6kl_err("failed to %s enhanced bmiss detection: %d\n",
 451			   enable ? "enable" : "disable", err);
 452}
 453
 454static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
 455				   struct cfg80211_connect_params *sme)
 456{
 457	struct ath6kl *ar = ath6kl_priv(dev);
 458	struct ath6kl_vif *vif = netdev_priv(dev);
 459	int status;
 460	u8 nw_subtype = (ar->p2p) ? SUBTYPE_P2PDEV : SUBTYPE_NONE;
 461	u16 interval;
 462
 463	ath6kl_cfg80211_sscan_disable(vif);
 464
 465	vif->sme_state = SME_CONNECTING;
 466
 467	if (!ath6kl_cfg80211_ready(vif))
 468		return -EIO;
 469
 470	if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
 471		ath6kl_err("destroy in progress\n");
 472		return -EBUSY;
 473	}
 474
 475	if (test_bit(SKIP_SCAN, &ar->flag) &&
 476	    ((sme->channel && sme->channel->center_freq == 0) ||
 477	     (sme->bssid && is_zero_ether_addr(sme->bssid)))) {
 478		ath6kl_err("SkipScan: channel or bssid invalid\n");
 479		return -EINVAL;
 480	}
 481
 482	if (down_interruptible(&ar->sem)) {
 483		ath6kl_err("busy, couldn't get access\n");
 484		return -ERESTARTSYS;
 485	}
 486
 487	if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
 488		ath6kl_err("busy, destroy in progress\n");
 489		up(&ar->sem);
 490		return -EBUSY;
 491	}
 492
 493	if (ar->tx_pending[ath6kl_wmi_get_control_ep(ar->wmi)]) {
 494		/*
 495		 * sleep until the command queue drains
 496		 */
 497		wait_event_interruptible_timeout(ar->event_wq,
 498						 ath6kl_is_tx_pending(ar),
 499						 WMI_TIMEOUT);
 500		if (signal_pending(current)) {
 501			ath6kl_err("cmd queue drain timeout\n");
 502			up(&ar->sem);
 503			return -EINTR;
 504		}
 505	}
 506
 507	status = ath6kl_set_assoc_req_ies(vif, sme->ie, sme->ie_len);
 508	if (status) {
 509		up(&ar->sem);
 510		return status;
 511	}
 512
 513	if (sme->ie == NULL || sme->ie_len == 0)
 514		ar->connect_ctrl_flags &= ~CONNECT_WPS_FLAG;
 515
 516	if (test_bit(CONNECTED, &vif->flags) &&
 517	    vif->ssid_len == sme->ssid_len &&
 518	    !memcmp(vif->ssid, sme->ssid, vif->ssid_len)) {
 519		vif->reconnect_flag = true;
 520		status = ath6kl_wmi_reconnect_cmd(ar->wmi, vif->fw_vif_idx,
 521						  vif->req_bssid,
 522						  vif->ch_hint);
 523
 524		up(&ar->sem);
 525		if (status) {
 526			ath6kl_err("wmi_reconnect_cmd failed\n");
 527			return -EIO;
 528		}
 529		return 0;
 530	} else if (vif->ssid_len == sme->ssid_len &&
 531		   !memcmp(vif->ssid, sme->ssid, vif->ssid_len)) {
 532		ath6kl_disconnect(vif);
 533	}
 534
 535	memset(vif->ssid, 0, sizeof(vif->ssid));
 536	vif->ssid_len = sme->ssid_len;
 537	memcpy(vif->ssid, sme->ssid, sme->ssid_len);
 538
 539	if (sme->channel)
 540		vif->ch_hint = sme->channel->center_freq;
 541
 542	memset(vif->req_bssid, 0, sizeof(vif->req_bssid));
 543	if (sme->bssid && !is_broadcast_ether_addr(sme->bssid))
 544		memcpy(vif->req_bssid, sme->bssid, sizeof(vif->req_bssid));
 545
 546	ath6kl_set_wpa_version(vif, sme->crypto.wpa_versions);
 547
 548	status = ath6kl_set_auth_type(vif, sme->auth_type);
 549	if (status) {
 550		up(&ar->sem);
 551		return status;
 552	}
 553
 554	if (sme->crypto.n_ciphers_pairwise)
 555		ath6kl_set_cipher(vif, sme->crypto.ciphers_pairwise[0], true);
 556	else
 557		ath6kl_set_cipher(vif, 0, true);
 558
 559	ath6kl_set_cipher(vif, sme->crypto.cipher_group, false);
 560
 561	if (sme->crypto.n_akm_suites)
 562		ath6kl_set_key_mgmt(vif, sme->crypto.akm_suites[0]);
 563
 564	if ((sme->key_len) &&
 565	    (vif->auth_mode == NONE_AUTH) &&
 566	    (vif->prwise_crypto == WEP_CRYPT)) {
 567		struct ath6kl_key *key = NULL;
 568
 569		if (sme->key_idx > WMI_MAX_KEY_INDEX) {
 570			ath6kl_err("key index %d out of bounds\n",
 571				   sme->key_idx);
 572			up(&ar->sem);
 573			return -ENOENT;
 574		}
 575
 576		key = &vif->keys[sme->key_idx];
 577		key->key_len = sme->key_len;
 578		memcpy(key->key, sme->key, key->key_len);
 579		key->cipher = vif->prwise_crypto;
 580		vif->def_txkey_index = sme->key_idx;
 581
 582		ath6kl_wmi_addkey_cmd(ar->wmi, vif->fw_vif_idx, sme->key_idx,
 583				      vif->prwise_crypto,
 584				      GROUP_USAGE | TX_USAGE,
 585				      key->key_len,
 586				      NULL, 0,
 587				      key->key, KEY_OP_INIT_VAL, NULL,
 588				      NO_SYNC_WMIFLAG);
 589	}
 590
 591	if (!ar->usr_bss_filter) {
 592		clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags);
 593		if (ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
 594					     ALL_BSS_FILTER, 0) != 0) {
 595			ath6kl_err("couldn't set bss filtering\n");
 596			up(&ar->sem);
 597			return -EIO;
 598		}
 599	}
 600
 601	vif->nw_type = vif->next_mode;
 602
 603	/* enable enhanced bmiss detection if applicable */
 604	ath6kl_cfg80211_sta_bmiss_enhance(vif, true);
 605
 606	if (vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT)
 607		nw_subtype = SUBTYPE_P2PCLIENT;
 608
 609	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
 610		   "%s: connect called with authmode %d dot11 auth %d"
 611		   " PW crypto %d PW crypto len %d GRP crypto %d"
 612		   " GRP crypto len %d channel hint %u\n",
 613		   __func__,
 614		   vif->auth_mode, vif->dot11_auth_mode, vif->prwise_crypto,
 615		   vif->prwise_crypto_len, vif->grp_crypto,
 616		   vif->grp_crypto_len, vif->ch_hint);
 617
 618	vif->reconnect_flag = 0;
 619
 620	if (vif->nw_type == INFRA_NETWORK) {
 621		interval = max_t(u16, vif->listen_intvl_t,
 622				 ATH6KL_MAX_WOW_LISTEN_INTL);
 623		status = ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx,
 624						       interval,
 625						       0);
 626		if (status) {
 627			ath6kl_err("couldn't set listen intervel\n");
 628			up(&ar->sem);
 629			return status;
 630		}
 631	}
 632
 633	status = ath6kl_wmi_connect_cmd(ar->wmi, vif->fw_vif_idx, vif->nw_type,
 634					vif->dot11_auth_mode, vif->auth_mode,
 635					vif->prwise_crypto,
 636					vif->prwise_crypto_len,
 637					vif->grp_crypto, vif->grp_crypto_len,
 638					vif->ssid_len, vif->ssid,
 639					vif->req_bssid, vif->ch_hint,
 640					ar->connect_ctrl_flags, nw_subtype);
 641
 642	if (sme->bg_scan_period == 0) {
 643		/* disable background scan if period is 0 */
 644		sme->bg_scan_period = 0xffff;
 645	} else if (sme->bg_scan_period == -1) {
 646		/* configure default value if not specified */
 647		sme->bg_scan_period = DEFAULT_BG_SCAN_PERIOD;
 648	}
 649
 650	ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx, 0, 0,
 651				  sme->bg_scan_period, 0, 0, 0, 3, 0, 0, 0);
 652
 653	up(&ar->sem);
 654
 655	if (status == -EINVAL) {
 656		memset(vif->ssid, 0, sizeof(vif->ssid));
 657		vif->ssid_len = 0;
 658		ath6kl_err("invalid request\n");
 659		return -ENOENT;
 660	} else if (status) {
 661		ath6kl_err("ath6kl_wmi_connect_cmd failed\n");
 662		return -EIO;
 663	}
 664
 665	if ((!(ar->connect_ctrl_flags & CONNECT_DO_WPA_OFFLOAD)) &&
 666	    ((vif->auth_mode == WPA_PSK_AUTH) ||
 667	     (vif->auth_mode == WPA2_PSK_AUTH))) {
 668		mod_timer(&vif->disconnect_timer,
 669			  jiffies + msecs_to_jiffies(DISCON_TIMER_INTVAL));
 670	}
 671
 672	ar->connect_ctrl_flags &= ~CONNECT_DO_WPA_OFFLOAD;
 673	set_bit(CONNECT_PEND, &vif->flags);
 674
 675	return 0;
 676}
 677
 678static struct cfg80211_bss *
 679ath6kl_add_bss_if_needed(struct ath6kl_vif *vif,
 680			 enum network_type nw_type,
 681			 const u8 *bssid,
 682			 struct ieee80211_channel *chan,
 683			 const u8 *beacon_ie,
 684			 size_t beacon_ie_len)
 685{
 686	struct ath6kl *ar = vif->ar;
 687	struct cfg80211_bss *bss;
 688	u16 cap_val;
 689	enum ieee80211_bss_type bss_type;
 690	u8 *ie;
 691
 692	if (nw_type & ADHOC_NETWORK) {
 693		cap_val = WLAN_CAPABILITY_IBSS;
 694		bss_type = IEEE80211_BSS_TYPE_IBSS;
 695	} else {
 696		cap_val = WLAN_CAPABILITY_ESS;
 697		bss_type = IEEE80211_BSS_TYPE_ESS;
 698	}
 699
 700	bss = cfg80211_get_bss(ar->wiphy, chan, bssid,
 701			       vif->ssid, vif->ssid_len,
 702			       bss_type, IEEE80211_PRIVACY_ANY);
 703	if (bss == NULL) {
 704		/*
 705		 * Since cfg80211 may not yet know about the BSS,
 706		 * generate a partial entry until the first BSS info
 707		 * event becomes available.
 708		 *
 709		 * Prepend SSID element since it is not included in the Beacon
 710		 * IEs from the target.
 711		 */
 712		ie = kmalloc(2 + vif->ssid_len + beacon_ie_len, GFP_KERNEL);
 713		if (ie == NULL)
 714			return NULL;
 715		ie[0] = WLAN_EID_SSID;
 716		ie[1] = vif->ssid_len;
 717		memcpy(ie + 2, vif->ssid, vif->ssid_len);
 718		memcpy(ie + 2 + vif->ssid_len, beacon_ie, beacon_ie_len);
 719		bss = cfg80211_inform_bss(ar->wiphy, chan,
 720					  CFG80211_BSS_FTYPE_UNKNOWN,
 721					  bssid, 0, cap_val, 100,
 722					  ie, 2 + vif->ssid_len + beacon_ie_len,
 723					  0, GFP_KERNEL);
 724		if (bss)
 725			ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
 726				   "added bss %pM to cfg80211\n", bssid);
 727		kfree(ie);
 728	} else {
 729		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "cfg80211 already has a bss\n");
 730	}
 731
 732	return bss;
 733}
 734
 735void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel,
 736				   u8 *bssid, u16 listen_intvl,
 737				   u16 beacon_intvl,
 738				   enum network_type nw_type,
 739				   u8 beacon_ie_len, u8 assoc_req_len,
 740				   u8 assoc_resp_len, u8 *assoc_info)
 741{
 742	struct ieee80211_channel *chan;
 743	struct ath6kl *ar = vif->ar;
 744	struct cfg80211_bss *bss;
 745
 746	/* capinfo + listen interval */
 747	u8 assoc_req_ie_offset = sizeof(u16) + sizeof(u16);
 748
 749	/* capinfo + status code +  associd */
 750	u8 assoc_resp_ie_offset = sizeof(u16) + sizeof(u16) + sizeof(u16);
 751
 752	u8 *assoc_req_ie = assoc_info + beacon_ie_len + assoc_req_ie_offset;
 753	u8 *assoc_resp_ie = assoc_info + beacon_ie_len + assoc_req_len +
 754	    assoc_resp_ie_offset;
 755
 756	assoc_req_len -= assoc_req_ie_offset;
 757	assoc_resp_len -= assoc_resp_ie_offset;
 758
 759	/*
 760	 * Store Beacon interval here; DTIM period will be available only once
 761	 * a Beacon frame from the AP is seen.
 762	 */
 763	vif->assoc_bss_beacon_int = beacon_intvl;
 764	clear_bit(DTIM_PERIOD_AVAIL, &vif->flags);
 765
 766	if (nw_type & ADHOC_NETWORK) {
 767		if (vif->wdev.iftype != NL80211_IFTYPE_ADHOC) {
 768			ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
 769				   "%s: ath6k not in ibss mode\n", __func__);
 770			return;
 771		}
 772	}
 773
 774	if (nw_type & INFRA_NETWORK) {
 775		if (vif->wdev.iftype != NL80211_IFTYPE_STATION &&
 776		    vif->wdev.iftype != NL80211_IFTYPE_P2P_CLIENT) {
 777			ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
 778				   "%s: ath6k not in station mode\n", __func__);
 779			return;
 780		}
 781	}
 782
 783	chan = ieee80211_get_channel(ar->wiphy, (int) channel);
 784
 785	bss = ath6kl_add_bss_if_needed(vif, nw_type, bssid, chan,
 786				       assoc_info, beacon_ie_len);
 787	if (!bss) {
 788		ath6kl_err("could not add cfg80211 bss entry\n");
 789		return;
 790	}
 791
 792	if (nw_type & ADHOC_NETWORK) {
 793		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "ad-hoc %s selected\n",
 794			   nw_type & ADHOC_CREATOR ? "creator" : "joiner");
 795		cfg80211_ibss_joined(vif->ndev, bssid, chan, GFP_KERNEL);
 796		cfg80211_put_bss(ar->wiphy, bss);
 797		return;
 798	}
 799
 800	if (vif->sme_state == SME_CONNECTING) {
 801		/* inform connect result to cfg80211 */
 802		vif->sme_state = SME_CONNECTED;
 803		cfg80211_connect_result(vif->ndev, bssid,
 804					assoc_req_ie, assoc_req_len,
 805					assoc_resp_ie, assoc_resp_len,
 806					WLAN_STATUS_SUCCESS, GFP_KERNEL);
 807		cfg80211_put_bss(ar->wiphy, bss);
 808	} else if (vif->sme_state == SME_CONNECTED) {
 809		struct cfg80211_roam_info roam_info = {
 810			.links[0].bss = bss,
 811			.req_ie = assoc_req_ie,
 812			.req_ie_len = assoc_req_len,
 813			.resp_ie = assoc_resp_ie,
 814			.resp_ie_len = assoc_resp_len,
 815		};
 816		/* inform roam event to cfg80211 */
 817		cfg80211_roamed(vif->ndev, &roam_info, GFP_KERNEL);
 818	}
 819}
 820
 821static int ath6kl_cfg80211_disconnect(struct wiphy *wiphy,
 822				      struct net_device *dev, u16 reason_code)
 823{
 824	struct ath6kl *ar = ath6kl_priv(dev);
 825	struct ath6kl_vif *vif = netdev_priv(dev);
 826
 827	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: reason=%u\n", __func__,
 828		   reason_code);
 829
 830	ath6kl_cfg80211_sscan_disable(vif);
 831
 832	if (!ath6kl_cfg80211_ready(vif))
 833		return -EIO;
 834
 835	if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
 836		ath6kl_err("busy, destroy in progress\n");
 837		return -EBUSY;
 838	}
 839
 840	if (down_interruptible(&ar->sem)) {
 841		ath6kl_err("busy, couldn't get access\n");
 842		return -ERESTARTSYS;
 843	}
 844
 845	vif->reconnect_flag = 0;
 846	ath6kl_disconnect(vif);
 847	memset(vif->ssid, 0, sizeof(vif->ssid));
 848	vif->ssid_len = 0;
 849
 850	if (!test_bit(SKIP_SCAN, &ar->flag))
 851		memset(vif->req_bssid, 0, sizeof(vif->req_bssid));
 852
 853	up(&ar->sem);
 854
 855	return 0;
 856}
 857
 858void ath6kl_cfg80211_disconnect_event(struct ath6kl_vif *vif, u8 reason,
 859				      u8 *bssid, u8 assoc_resp_len,
 860				      u8 *assoc_info, u16 proto_reason)
 861{
 862	struct ath6kl *ar = vif->ar;
 863
 864	if (vif->scan_req) {
 865		struct cfg80211_scan_info info = {
 866			.aborted = true,
 867		};
 868
 869		cfg80211_scan_done(vif->scan_req, &info);
 870		vif->scan_req = NULL;
 871	}
 872
 873	if (vif->nw_type & ADHOC_NETWORK) {
 874		if (vif->wdev.iftype != NL80211_IFTYPE_ADHOC)
 875			ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
 876				   "%s: ath6k not in ibss mode\n", __func__);
 877		return;
 878	}
 879
 880	if (vif->nw_type & INFRA_NETWORK) {
 881		if (vif->wdev.iftype != NL80211_IFTYPE_STATION &&
 882		    vif->wdev.iftype != NL80211_IFTYPE_P2P_CLIENT) {
 883			ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
 884				   "%s: ath6k not in station mode\n", __func__);
 885			return;
 886		}
 887	}
 888
 889	clear_bit(CONNECT_PEND, &vif->flags);
 890
 891	if (vif->sme_state == SME_CONNECTING) {
 892		cfg80211_connect_result(vif->ndev,
 893					bssid, NULL, 0,
 894					NULL, 0,
 895					WLAN_STATUS_UNSPECIFIED_FAILURE,
 896					GFP_KERNEL);
 897	} else if (vif->sme_state == SME_CONNECTED) {
 898		cfg80211_disconnected(vif->ndev, proto_reason,
 899				      NULL, 0, false, GFP_KERNEL);
 900	}
 901
 902	vif->sme_state = SME_DISCONNECTED;
 903
 904	/*
 905	 * Send a disconnect command to target when a disconnect event is
 906	 * received with reason code other than 3 (DISCONNECT_CMD - disconnect
 907	 * request from host) to make the firmware stop trying to connect even
 908	 * after giving disconnect event. There will be one more disconnect
 909	 * event for this disconnect command with reason code DISCONNECT_CMD
 910	 * which won't be notified to cfg80211.
 911	 */
 912	if (reason != DISCONNECT_CMD)
 913		ath6kl_wmi_disconnect_cmd(ar->wmi, vif->fw_vif_idx);
 914}
 915
 916static int ath6kl_set_probed_ssids(struct ath6kl *ar,
 917				   struct ath6kl_vif *vif,
 918				   struct cfg80211_ssid *ssids, int n_ssids,
 919				   struct cfg80211_match_set *match_set,
 920				   int n_match_ssid)
 921{
 922	u8 i, j, index_to_add, ssid_found = false;
 923	struct ath6kl_cfg80211_match_probe_ssid ssid_list[MAX_PROBED_SSIDS];
 924
 925	memset(ssid_list, 0, sizeof(ssid_list));
 926
 927	if (n_ssids > MAX_PROBED_SSIDS ||
 928	    n_match_ssid > MAX_PROBED_SSIDS)
 929		return -EINVAL;
 930
 931	for (i = 0; i < n_ssids; i++) {
 932		memcpy(ssid_list[i].ssid.ssid,
 933		       ssids[i].ssid,
 934		       ssids[i].ssid_len);
 935		ssid_list[i].ssid.ssid_len = ssids[i].ssid_len;
 936
 937		if (ssids[i].ssid_len)
 938			ssid_list[i].flag = SPECIFIC_SSID_FLAG;
 939		else
 940			ssid_list[i].flag = ANY_SSID_FLAG;
 941
 942		if (ar->wiphy->max_match_sets != 0 && n_match_ssid == 0)
 943			ssid_list[i].flag |= MATCH_SSID_FLAG;
 944	}
 945
 946	index_to_add = i;
 947
 948	for (i = 0; i < n_match_ssid; i++) {
 949		ssid_found = false;
 950
 951		for (j = 0; j < n_ssids; j++) {
 952			if ((match_set[i].ssid.ssid_len ==
 953			     ssid_list[j].ssid.ssid_len) &&
 954			    (!memcmp(ssid_list[j].ssid.ssid,
 955				     match_set[i].ssid.ssid,
 956				     match_set[i].ssid.ssid_len))) {
 957				ssid_list[j].flag |= MATCH_SSID_FLAG;
 958				ssid_found = true;
 959				break;
 960			}
 961		}
 962
 963		if (ssid_found)
 964			continue;
 965
 966		if (index_to_add >= MAX_PROBED_SSIDS)
 967			continue;
 968
 969		ssid_list[index_to_add].ssid.ssid_len =
 970			match_set[i].ssid.ssid_len;
 971		memcpy(ssid_list[index_to_add].ssid.ssid,
 972		       match_set[i].ssid.ssid,
 973		       match_set[i].ssid.ssid_len);
 974		ssid_list[index_to_add].flag |= MATCH_SSID_FLAG;
 975		index_to_add++;
 976	}
 977
 978	for (i = 0; i < index_to_add; i++) {
 979		ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx, i,
 980					  ssid_list[i].flag,
 981					  ssid_list[i].ssid.ssid_len,
 982					  ssid_list[i].ssid.ssid);
 983	}
 984
 985	/* Make sure no old entries are left behind */
 986	for (i = index_to_add; i < MAX_PROBED_SSIDS; i++) {
 987		ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx, i,
 988					  DISABLE_SSID_FLAG, 0, NULL);
 989	}
 990
 991	return 0;
 992}
 993
 994static int ath6kl_cfg80211_scan(struct wiphy *wiphy,
 995				struct cfg80211_scan_request *request)
 996{
 997	struct ath6kl_vif *vif = ath6kl_vif_from_wdev(request->wdev);
 998	struct ath6kl *ar = ath6kl_priv(vif->ndev);
 999	s8 n_channels = 0;
1000	u16 *channels = NULL;
1001	int ret = 0;
1002	u32 force_fg_scan = 0;
1003
1004	if (!ath6kl_cfg80211_ready(vif))
1005		return -EIO;
1006
1007	ath6kl_cfg80211_sscan_disable(vif);
1008
1009	if (!ar->usr_bss_filter) {
1010		clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags);
1011		ret = ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
1012					       ALL_BSS_FILTER, 0);
1013		if (ret) {
1014			ath6kl_err("couldn't set bss filtering\n");
1015			return ret;
1016		}
1017	}
1018
1019	ret = ath6kl_set_probed_ssids(ar, vif, request->ssids,
1020				      request->n_ssids, NULL, 0);
1021	if (ret < 0)
1022		return ret;
1023
1024	/* this also clears IE in fw if it's not set */
1025	ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
1026				       WMI_FRAME_PROBE_REQ,
1027				       request->ie, request->ie_len);
1028	if (ret) {
1029		ath6kl_err("failed to set Probe Request appie for scan\n");
1030		return ret;
1031	}
1032
1033	/*
1034	 * Scan only the requested channels if the request specifies a set of
1035	 * channels. If the list is longer than the target supports, do not
1036	 * configure the list and instead, scan all available channels.
1037	 */
1038	if (request->n_channels > 0 &&
1039	    request->n_channels <= WMI_MAX_CHANNELS) {
1040		u8 i;
1041
1042		n_channels = request->n_channels;
1043
1044		channels = kcalloc(n_channels, sizeof(u16), GFP_KERNEL);
1045		if (channels == NULL) {
1046			ath6kl_warn("failed to set scan channels, scan all channels");
1047			n_channels = 0;
1048		}
1049
1050		for (i = 0; i < n_channels; i++)
1051			channels[i] = request->channels[i]->center_freq;
1052	}
1053
1054	if (test_bit(CONNECTED, &vif->flags))
1055		force_fg_scan = 1;
1056
1057	vif->scan_req = request;
1058
1059	ret = ath6kl_wmi_beginscan_cmd(ar->wmi, vif->fw_vif_idx,
1060				       WMI_LONG_SCAN, force_fg_scan,
1061				       false, 0,
1062				       ATH6KL_FG_SCAN_INTERVAL,
1063				       n_channels, channels,
1064				       request->no_cck,
1065				       request->rates);
1066	if (ret) {
1067		ath6kl_err("failed to start scan: %d\n", ret);
1068		vif->scan_req = NULL;
1069	}
1070
1071	kfree(channels);
1072
1073	return ret;
1074}
1075
1076void ath6kl_cfg80211_scan_complete_event(struct ath6kl_vif *vif, bool aborted)
1077{
1078	struct ath6kl *ar = vif->ar;
1079	struct cfg80211_scan_info info = {
1080		.aborted = aborted,
1081	};
1082	int i;
1083
1084	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: status%s\n", __func__,
1085		   aborted ? " aborted" : "");
1086
1087	if (!vif->scan_req)
1088		return;
1089
1090	if (aborted)
1091		goto out;
1092
1093	if (vif->scan_req->n_ssids && vif->scan_req->ssids[0].ssid_len) {
1094		for (i = 0; i < vif->scan_req->n_ssids; i++) {
1095			ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx,
1096						  i, DISABLE_SSID_FLAG,
1097						  0, NULL);
1098		}
1099	}
1100
1101out:
1102	cfg80211_scan_done(vif->scan_req, &info);
1103	vif->scan_req = NULL;
1104}
1105
1106void ath6kl_cfg80211_ch_switch_notify(struct ath6kl_vif *vif, int freq,
1107				      enum wmi_phy_mode mode)
1108{
1109	struct cfg80211_chan_def chandef;
1110
1111	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1112		   "channel switch notify nw_type %d freq %d mode %d\n",
1113		   vif->nw_type, freq, mode);
1114
1115	cfg80211_chandef_create(&chandef,
1116				ieee80211_get_channel(vif->ar->wiphy, freq),
1117				(mode == WMI_11G_HT20 &&
1118				 ath6kl_band_2ghz.ht_cap.ht_supported) ?
1119					NL80211_CHAN_HT20 : NL80211_CHAN_NO_HT);
1120
1121	wiphy_lock(vif->ar->wiphy);
1122	cfg80211_ch_switch_notify(vif->ndev, &chandef, 0);
1123	wiphy_unlock(vif->ar->wiphy);
1124}
1125
1126static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
1127				   int link_id, u8 key_index, bool pairwise,
1128				   const u8 *mac_addr,
1129				   struct key_params *params)
1130{
1131	struct ath6kl *ar = ath6kl_priv(ndev);
1132	struct ath6kl_vif *vif = netdev_priv(ndev);
1133	struct ath6kl_key *key = NULL;
1134	int seq_len;
1135	u8 key_usage;
1136	u8 key_type;
1137
1138	if (!ath6kl_cfg80211_ready(vif))
1139		return -EIO;
1140
1141	if (params->cipher == CCKM_KRK_CIPHER_SUITE) {
1142		if (params->key_len != WMI_KRK_LEN)
1143			return -EINVAL;
1144		return ath6kl_wmi_add_krk_cmd(ar->wmi, vif->fw_vif_idx,
1145					      params->key);
1146	}
1147
1148	if (key_index > WMI_MAX_KEY_INDEX) {
1149		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1150			   "%s: key index %d out of bounds\n", __func__,
1151			   key_index);
1152		return -ENOENT;
1153	}
1154
1155	key = &vif->keys[key_index];
1156	memset(key, 0, sizeof(struct ath6kl_key));
1157
1158	if (pairwise)
1159		key_usage = PAIRWISE_USAGE;
1160	else
1161		key_usage = GROUP_USAGE;
1162
1163	seq_len = params->seq_len;
1164	if (params->cipher == WLAN_CIPHER_SUITE_SMS4 &&
1165	    seq_len > ATH6KL_KEY_SEQ_LEN) {
1166		/* Only first half of the WPI PN is configured */
1167		seq_len = ATH6KL_KEY_SEQ_LEN;
1168	}
1169	if (params->key_len > WLAN_MAX_KEY_LEN ||
1170	    seq_len > sizeof(key->seq))
1171		return -EINVAL;
1172
1173	key->key_len = params->key_len;
1174	memcpy(key->key, params->key, key->key_len);
1175	key->seq_len = seq_len;
1176	memcpy(key->seq, params->seq, key->seq_len);
1177	key->cipher = params->cipher;
1178
1179	switch (key->cipher) {
1180	case WLAN_CIPHER_SUITE_WEP40:
1181	case WLAN_CIPHER_SUITE_WEP104:
1182		key_type = WEP_CRYPT;
1183		break;
1184
1185	case WLAN_CIPHER_SUITE_TKIP:
1186		key_type = TKIP_CRYPT;
1187		break;
1188
1189	case WLAN_CIPHER_SUITE_CCMP:
1190		key_type = AES_CRYPT;
1191		break;
1192	case WLAN_CIPHER_SUITE_SMS4:
1193		key_type = WAPI_CRYPT;
1194		break;
1195
1196	default:
1197		return -ENOTSUPP;
1198	}
1199
1200	if (((vif->auth_mode == WPA_PSK_AUTH) ||
1201	     (vif->auth_mode == WPA2_PSK_AUTH)) &&
1202	    (key_usage & GROUP_USAGE))
1203		timer_delete(&vif->disconnect_timer);
1204
1205	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1206		   "%s: index %d, key_len %d, key_type 0x%x, key_usage 0x%x, seq_len %d\n",
1207		   __func__, key_index, key->key_len, key_type,
1208		   key_usage, key->seq_len);
1209
1210	if (vif->nw_type == AP_NETWORK && !pairwise &&
1211	    (key_type == TKIP_CRYPT || key_type == AES_CRYPT ||
1212	     key_type == WAPI_CRYPT)) {
1213		ar->ap_mode_bkey.valid = true;
1214		ar->ap_mode_bkey.key_index = key_index;
1215		ar->ap_mode_bkey.key_type = key_type;
1216		ar->ap_mode_bkey.key_len = key->key_len;
1217		memcpy(ar->ap_mode_bkey.key, key->key, key->key_len);
1218		if (!test_bit(CONNECTED, &vif->flags)) {
1219			ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1220				   "Delay initial group key configuration until AP mode has been started\n");
1221			/*
1222			 * The key will be set in ath6kl_connect_ap_mode() once
1223			 * the connected event is received from the target.
1224			 */
1225			return 0;
1226		}
1227	}
1228
1229	if (vif->next_mode == AP_NETWORK && key_type == WEP_CRYPT &&
1230	    !test_bit(CONNECTED, &vif->flags)) {
1231		/*
1232		 * Store the key locally so that it can be re-configured after
1233		 * the AP mode has properly started
1234		 * (ath6kl_install_statioc_wep_keys).
1235		 */
1236		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1237			   "Delay WEP key configuration until AP mode has been started\n");
1238		vif->wep_key_list[key_index].key_len = key->key_len;
1239		memcpy(vif->wep_key_list[key_index].key, key->key,
1240		       key->key_len);
1241		return 0;
1242	}
1243
1244	return ath6kl_wmi_addkey_cmd(ar->wmi, vif->fw_vif_idx, key_index,
1245				     key_type, key_usage, key->key_len,
1246				     key->seq, key->seq_len, key->key,
1247				     KEY_OP_INIT_VAL,
1248				     (u8 *) mac_addr, SYNC_BOTH_WMIFLAG);
1249}
1250
1251static int ath6kl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
1252				   int link_id, u8 key_index, bool pairwise,
1253				   const u8 *mac_addr)
1254{
1255	struct ath6kl *ar = ath6kl_priv(ndev);
1256	struct ath6kl_vif *vif = netdev_priv(ndev);
1257
1258	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
1259
1260	if (!ath6kl_cfg80211_ready(vif))
1261		return -EIO;
1262
1263	if (key_index > WMI_MAX_KEY_INDEX) {
1264		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1265			   "%s: key index %d out of bounds\n", __func__,
1266			   key_index);
1267		return -ENOENT;
1268	}
1269
1270	if (!vif->keys[key_index].key_len) {
1271		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1272			   "%s: index %d is empty\n", __func__, key_index);
1273		return 0;
1274	}
1275
1276	vif->keys[key_index].key_len = 0;
1277
1278	return ath6kl_wmi_deletekey_cmd(ar->wmi, vif->fw_vif_idx, key_index);
1279}
1280
1281static int ath6kl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
1282				   int link_id, u8 key_index, bool pairwise,
1283				   const u8 *mac_addr, void *cookie,
1284				   void (*callback) (void *cookie,
1285						     struct key_params *))
1286{
1287	struct ath6kl_vif *vif = netdev_priv(ndev);
1288	struct ath6kl_key *key = NULL;
1289	struct key_params params;
1290
1291	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
1292
1293	if (!ath6kl_cfg80211_ready(vif))
1294		return -EIO;
1295
1296	if (key_index > WMI_MAX_KEY_INDEX) {
1297		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1298			   "%s: key index %d out of bounds\n", __func__,
1299			   key_index);
1300		return -ENOENT;
1301	}
1302
1303	key = &vif->keys[key_index];
1304	memset(&params, 0, sizeof(params));
1305	params.cipher = key->cipher;
1306	params.key_len = key->key_len;
1307	params.seq_len = key->seq_len;
1308	params.seq = key->seq;
1309	params.key = key->key;
1310
1311	callback(cookie, &params);
1312
1313	return key->key_len ? 0 : -ENOENT;
1314}
1315
1316static int ath6kl_cfg80211_set_default_key(struct wiphy *wiphy,
1317					   struct net_device *ndev, int link_id,
1318					   u8 key_index, bool unicast,
1319					   bool multicast)
1320{
1321	struct ath6kl *ar = ath6kl_priv(ndev);
1322	struct ath6kl_vif *vif = netdev_priv(ndev);
1323	struct ath6kl_key *key = NULL;
1324	u8 key_usage;
1325	enum ath6kl_crypto_type key_type = NONE_CRYPT;
1326
1327	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
1328
1329	if (!ath6kl_cfg80211_ready(vif))
1330		return -EIO;
1331
1332	if (key_index > WMI_MAX_KEY_INDEX) {
1333		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1334			   "%s: key index %d out of bounds\n",
1335			   __func__, key_index);
1336		return -ENOENT;
1337	}
1338
1339	if (!vif->keys[key_index].key_len) {
1340		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: invalid key index %d\n",
1341			   __func__, key_index);
1342		return -EINVAL;
1343	}
1344
1345	vif->def_txkey_index = key_index;
1346	key = &vif->keys[vif->def_txkey_index];
1347	key_usage = GROUP_USAGE;
1348	if (vif->prwise_crypto == WEP_CRYPT)
1349		key_usage |= TX_USAGE;
1350	if (unicast)
1351		key_type = vif->prwise_crypto;
1352	if (multicast)
1353		key_type = vif->grp_crypto;
1354
1355	if (vif->next_mode == AP_NETWORK && !test_bit(CONNECTED, &vif->flags))
1356		return 0; /* Delay until AP mode has been started */
1357
1358	return ath6kl_wmi_addkey_cmd(ar->wmi, vif->fw_vif_idx,
1359				     vif->def_txkey_index,
1360				     key_type, key_usage,
1361				     key->key_len, key->seq, key->seq_len,
1362				     key->key,
1363				     KEY_OP_INIT_VAL, NULL,
1364				     SYNC_BOTH_WMIFLAG);
1365}
1366
1367void ath6kl_cfg80211_tkip_micerr_event(struct ath6kl_vif *vif, u8 keyid,
1368				       bool ismcast)
1369{
1370	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1371		   "%s: keyid %d, ismcast %d\n", __func__, keyid, ismcast);
1372
1373	cfg80211_michael_mic_failure(vif->ndev, vif->bssid,
1374				     (ismcast ? NL80211_KEYTYPE_GROUP :
1375				      NL80211_KEYTYPE_PAIRWISE), keyid, NULL,
1376				     GFP_KERNEL);
1377}
1378
1379static int ath6kl_cfg80211_set_wiphy_params(struct wiphy *wiphy, int radio_idx,
1380					    u32 changed)
1381{
1382	struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
1383	struct ath6kl_vif *vif;
1384	int ret;
1385
1386	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: changed 0x%x\n", __func__,
1387		   changed);
1388
1389	vif = ath6kl_vif_first(ar);
1390	if (!vif)
1391		return -EIO;
1392
1393	if (!ath6kl_cfg80211_ready(vif))
1394		return -EIO;
1395
1396	if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1397		ret = ath6kl_wmi_set_rts_cmd(ar->wmi, wiphy->rts_threshold);
1398		if (ret != 0) {
1399			ath6kl_err("ath6kl_wmi_set_rts_cmd failed\n");
1400			return -EIO;
1401		}
1402	}
1403
1404	return 0;
1405}
1406
1407static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy,
1408				       struct wireless_dev *wdev,
1409				       int radio_idx,
1410				       enum nl80211_tx_power_setting type,
1411				       int mbm)
1412{
1413	struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
1414	struct ath6kl_vif *vif;
1415	int dbm = MBM_TO_DBM(mbm);
1416
1417	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type 0x%x, dbm %d\n", __func__,
1418		   type, dbm);
1419
1420	vif = ath6kl_vif_first(ar);
1421	if (!vif)
1422		return -EIO;
1423
1424	if (!ath6kl_cfg80211_ready(vif))
1425		return -EIO;
1426
1427	switch (type) {
1428	case NL80211_TX_POWER_AUTOMATIC:
1429		return 0;
1430	case NL80211_TX_POWER_LIMITED:
1431		ar->tx_pwr = dbm;
1432		break;
1433	default:
1434		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type 0x%x not supported\n",
1435			   __func__, type);
1436		return -EOPNOTSUPP;
1437	}
1438
1439	ath6kl_wmi_set_tx_pwr_cmd(ar->wmi, vif->fw_vif_idx, dbm);
1440
1441	return 0;
1442}
1443
1444static int ath6kl_cfg80211_get_txpower(struct wiphy *wiphy,
1445				       struct wireless_dev *wdev,
1446				       int radio_idx,
1447				       unsigned int link_id,
1448				       int *dbm)
1449{
1450	struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
1451	struct ath6kl_vif *vif;
1452
1453	vif = ath6kl_vif_first(ar);
1454	if (!vif)
1455		return -EIO;
1456
1457	if (!ath6kl_cfg80211_ready(vif))
1458		return -EIO;
1459
1460	if (test_bit(CONNECTED, &vif->flags)) {
1461		ar->tx_pwr = 255;
1462
1463		if (ath6kl_wmi_get_tx_pwr_cmd(ar->wmi, vif->fw_vif_idx) != 0) {
1464			ath6kl_err("ath6kl_wmi_get_tx_pwr_cmd failed\n");
1465			return -EIO;
1466		}
1467
1468		wait_event_interruptible_timeout(ar->event_wq, ar->tx_pwr != 255,
1469						 5 * HZ);
1470
1471		if (signal_pending(current)) {
1472			ath6kl_err("target did not respond\n");
1473			return -EINTR;
1474		}
1475	}
1476
1477	*dbm = ar->tx_pwr;
1478	return 0;
1479}
1480
1481static int ath6kl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
1482					  struct net_device *dev,
1483					  bool pmgmt, int timeout)
1484{
1485	struct ath6kl *ar = ath6kl_priv(dev);
1486	struct wmi_power_mode_cmd mode;
1487	struct ath6kl_vif *vif = netdev_priv(dev);
1488
1489	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: pmgmt %d, timeout %d\n",
1490		   __func__, pmgmt, timeout);
1491
1492	if (!ath6kl_cfg80211_ready(vif))
1493		return -EIO;
1494
1495	if (pmgmt) {
1496		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: rec power\n", __func__);
1497		mode.pwr_mode = REC_POWER;
1498	} else {
1499		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: max perf\n", __func__);
1500		mode.pwr_mode = MAX_PERF_POWER;
1501	}
1502
1503	if (ath6kl_wmi_powermode_cmd(ar->wmi, vif->fw_vif_idx,
1504				     mode.pwr_mode) != 0) {
1505		ath6kl_err("wmi_powermode_cmd failed\n");
1506		return -EIO;
1507	}
1508
1509	return 0;
1510}
1511
1512static struct wireless_dev *ath6kl_cfg80211_add_iface(struct wiphy *wiphy,
1513						      const char *name,
1514						      unsigned char name_assign_type,
1515						      enum nl80211_iftype type,
1516						      struct vif_params *params)
1517{
1518	struct ath6kl *ar = wiphy_priv(wiphy);
1519	struct wireless_dev *wdev;
1520	u8 if_idx, nw_type;
1521
1522	if (ar->num_vif == ar->vif_max) {
1523		ath6kl_err("Reached maximum number of supported vif\n");
1524		return ERR_PTR(-EINVAL);
1525	}
1526
1527	if (!ath6kl_is_valid_iftype(ar, type, &if_idx, &nw_type)) {
1528		ath6kl_err("Not a supported interface type\n");
1529		return ERR_PTR(-EINVAL);
1530	}
1531
1532	wdev = ath6kl_interface_add(ar, name, name_assign_type, type, if_idx, nw_type);
1533	if (!wdev)
1534		return ERR_PTR(-ENOMEM);
1535
1536	ar->num_vif++;
1537
1538	return wdev;
1539}
1540
1541static int ath6kl_cfg80211_del_iface(struct wiphy *wiphy,
1542				     struct wireless_dev *wdev)
1543{
1544	struct ath6kl *ar = wiphy_priv(wiphy);
1545	struct ath6kl_vif *vif = netdev_priv(wdev->netdev);
1546
1547	spin_lock_bh(&ar->list_lock);
1548	list_del(&vif->list);
1549	spin_unlock_bh(&ar->list_lock);
1550
1551	ath6kl_cfg80211_vif_stop(vif, test_bit(WMI_READY, &ar->flag));
1552
1553	rtnl_lock();
1554	ath6kl_cfg80211_vif_cleanup(vif);
1555	rtnl_unlock();
1556
1557	return 0;
1558}
1559
1560static int ath6kl_cfg80211_change_iface(struct wiphy *wiphy,
1561					struct net_device *ndev,
1562					enum nl80211_iftype type,
1563					struct vif_params *params)
1564{
1565	struct ath6kl_vif *vif = netdev_priv(ndev);
1566	int i;
1567
1568	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type %u\n", __func__, type);
1569
1570	/*
1571	 * Don't bring up p2p on an interface which is not initialized
1572	 * for p2p operation where fw does not have capability to switch
1573	 * dynamically between non-p2p and p2p type interface.
1574	 */
1575	if (!test_bit(ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX,
1576		      vif->ar->fw_capabilities) &&
1577	    (type == NL80211_IFTYPE_P2P_CLIENT ||
1578	     type == NL80211_IFTYPE_P2P_GO)) {
1579		if (vif->ar->vif_max == 1) {
1580			if (vif->fw_vif_idx != 0)
1581				return -EINVAL;
1582			else
1583				goto set_iface_type;
1584		}
1585
1586		for (i = vif->ar->max_norm_iface; i < vif->ar->vif_max; i++) {
1587			if (i == vif->fw_vif_idx)
1588				break;
1589		}
1590
1591		if (i == vif->ar->vif_max) {
1592			ath6kl_err("Invalid interface to bring up P2P\n");
1593			return -EINVAL;
1594		}
1595	}
1596
1597	/* need to clean up enhanced bmiss detection fw state */
1598	ath6kl_cfg80211_sta_bmiss_enhance(vif, false);
1599
1600set_iface_type:
1601	switch (type) {
1602	case NL80211_IFTYPE_STATION:
1603	case NL80211_IFTYPE_P2P_CLIENT:
1604		vif->next_mode = INFRA_NETWORK;
1605		break;
1606	case NL80211_IFTYPE_ADHOC:
1607		vif->next_mode = ADHOC_NETWORK;
1608		break;
1609	case NL80211_IFTYPE_AP:
1610	case NL80211_IFTYPE_P2P_GO:
1611		vif->next_mode = AP_NETWORK;
1612		break;
1613	default:
1614		ath6kl_err("invalid interface type %u\n", type);
1615		return -EOPNOTSUPP;
1616	}
1617
1618	vif->wdev.iftype = type;
1619
1620	return 0;
1621}
1622
1623static int ath6kl_cfg80211_join_ibss(struct wiphy *wiphy,
1624				     struct net_device *dev,
1625				     struct cfg80211_ibss_params *ibss_param)
1626{
1627	struct ath6kl *ar = ath6kl_priv(dev);
1628	struct ath6kl_vif *vif = netdev_priv(dev);
1629	int status;
1630
1631	if (!ath6kl_cfg80211_ready(vif))
1632		return -EIO;
1633
1634	vif->ssid_len = ibss_param->ssid_len;
1635	memcpy(vif->ssid, ibss_param->ssid, vif->ssid_len);
1636
1637	if (ibss_param->chandef.chan)
1638		vif->ch_hint = ibss_param->chandef.chan->center_freq;
1639
1640	if (ibss_param->channel_fixed) {
1641		/*
1642		 * TODO: channel_fixed: The channel should be fixed, do not
1643		 * search for IBSSs to join on other channels. Target
1644		 * firmware does not support this feature, needs to be
1645		 * updated.
1646		 */
1647		return -EOPNOTSUPP;
1648	}
1649
1650	memset(vif->req_bssid, 0, sizeof(vif->req_bssid));
1651	if (ibss_param->bssid && !is_broadcast_ether_addr(ibss_param->bssid))
1652		memcpy(vif->req_bssid, ibss_param->bssid,
1653		       sizeof(vif->req_bssid));
1654
1655	ath6kl_set_wpa_version(vif, 0);
1656
1657	status = ath6kl_set_auth_type(vif, NL80211_AUTHTYPE_OPEN_SYSTEM);
1658	if (status)
1659		return status;
1660
1661	if (ibss_param->privacy) {
1662		ath6kl_set_cipher(vif, WLAN_CIPHER_SUITE_WEP40, true);
1663		ath6kl_set_cipher(vif, WLAN_CIPHER_SUITE_WEP40, false);
1664	} else {
1665		ath6kl_set_cipher(vif, 0, true);
1666		ath6kl_set_cipher(vif, 0, false);
1667	}
1668
1669	vif->nw_type = vif->next_mode;
1670
1671	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1672		   "%s: connect called with authmode %d dot11 auth %d"
1673		   " PW crypto %d PW crypto len %d GRP crypto %d"
1674		   " GRP crypto len %d channel hint %u\n",
1675		   __func__,
1676		   vif->auth_mode, vif->dot11_auth_mode, vif->prwise_crypto,
1677		   vif->prwise_crypto_len, vif->grp_crypto,
1678		   vif->grp_crypto_len, vif->ch_hint);
1679
1680	status = ath6kl_wmi_connect_cmd(ar->wmi, vif->fw_vif_idx, vif->nw_type,
1681					vif->dot11_auth_mode, vif->auth_mode,
1682					vif->prwise_crypto,
1683					vif->prwise_crypto_len,
1684					vif->grp_crypto, vif->grp_crypto_len,
1685					vif->ssid_len, vif->ssid,
1686					vif->req_bssid, vif->ch_hint,
1687					ar->connect_ctrl_flags, SUBTYPE_NONE);
1688	set_bit(CONNECT_PEND, &vif->flags);
1689
1690	return 0;
1691}
1692
1693static int ath6kl_cfg80211_leave_ibss(struct wiphy *wiphy,
1694				      struct net_device *dev)
1695{
1696	struct ath6kl_vif *vif = netdev_priv(dev);
1697
1698	if (!ath6kl_cfg80211_ready(vif))
1699		return -EIO;
1700
1701	ath6kl_disconnect(vif);
1702	memset(vif->ssid, 0, sizeof(vif->ssid));
1703	vif->ssid_len = 0;
1704
1705	return 0;
1706}
1707
1708static const u32 cipher_suites[] = {
1709	WLAN_CIPHER_SUITE_WEP40,
1710	WLAN_CIPHER_SUITE_WEP104,
1711	WLAN_CIPHER_SUITE_TKIP,
1712	WLAN_CIPHER_SUITE_CCMP,
1713	CCKM_KRK_CIPHER_SUITE,
1714	WLAN_CIPHER_SUITE_SMS4,
1715};
1716
1717static bool is_rate_legacy(s32 rate)
1718{
1719	static const s32 legacy[] = { 1000, 2000, 5500, 11000,
1720		6000, 9000, 12000, 18000, 24000,
1721		36000, 48000, 54000
1722	};
1723	u8 i;
1724
1725	for (i = 0; i < ARRAY_SIZE(legacy); i++)
1726		if (rate == legacy[i])
1727			return true;
1728
1729	return false;
1730}
1731
1732static bool is_rate_ht20(s32 rate, u8 *mcs, bool *sgi)
1733{
1734	static const s32 ht20[] = { 6500, 13000, 19500, 26000, 39000,
1735		52000, 58500, 65000, 72200
1736	};
1737	u8 i;
1738
1739	for (i = 0; i < ARRAY_SIZE(ht20); i++) {
1740		if (rate == ht20[i]) {
1741			if (i == ARRAY_SIZE(ht20) - 1)
1742				/* last rate uses sgi */
1743				*sgi = true;
1744			else
1745				*sgi = false;
1746
1747			*mcs = i;
1748			return true;
1749		}
1750	}
1751	return false;
1752}
1753
1754static bool is_rate_ht40(s32 rate, u8 *mcs, bool *sgi)
1755{
1756	static const s32 ht40[] = { 13500, 27000, 40500, 54000,
1757		81000, 108000, 121500, 135000,
1758		150000
1759	};
1760	u8 i;
1761
1762	for (i = 0; i < ARRAY_SIZE(ht40); i++) {
1763		if (rate == ht40[i]) {
1764			if (i == ARRAY_SIZE(ht40) - 1)
1765				/* last rate uses sgi */
1766				*sgi = true;
1767			else
1768				*sgi = false;
1769
1770			*mcs = i;
1771			return true;
1772		}
1773	}
1774
1775	return false;
1776}
1777
1778static int ath6kl_get_station(struct wiphy *wiphy, struct net_device *dev,
1779			      const u8 *mac, struct station_info *sinfo)
1780{
1781	struct ath6kl *ar = ath6kl_priv(dev);
1782	struct ath6kl_vif *vif = netdev_priv(dev);
1783	long left;
1784	bool sgi;
1785	s32 rate;
1786	int ret;
1787	u8 mcs;
1788
1789	if (memcmp(mac, vif->bssid, ETH_ALEN) != 0)
1790		return -ENOENT;
1791
1792	if (down_interruptible(&ar->sem))
1793		return -EBUSY;
1794
1795	set_bit(STATS_UPDATE_PEND, &vif->flags);
1796
1797	ret = ath6kl_wmi_get_stats_cmd(ar->wmi, vif->fw_vif_idx);
1798
1799	if (ret != 0) {
1800		up(&ar->sem);
1801		return -EIO;
1802	}
1803
1804	left = wait_event_interruptible_timeout(ar->event_wq,
1805						!test_bit(STATS_UPDATE_PEND,
1806							  &vif->flags),
1807						WMI_TIMEOUT);
1808
1809	up(&ar->sem);
1810
1811	if (left == 0)
1812		return -ETIMEDOUT;
1813	else if (left < 0)
1814		return left;
1815
1816	if (vif->target_stats.rx_byte) {
1817		sinfo->rx_bytes = vif->target_stats.rx_byte;
1818		sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BYTES64);
1819		sinfo->rx_packets = vif->target_stats.rx_pkt;
1820		sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_PACKETS);
1821	}
1822
1823	if (vif->target_stats.tx_byte) {
1824		sinfo->tx_bytes = vif->target_stats.tx_byte;
1825		sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BYTES64);
1826		sinfo->tx_packets = vif->target_stats.tx_pkt;
1827		sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_PACKETS);
1828	}
1829
1830	sinfo->signal = vif->target_stats.cs_rssi;
1831	sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL);
1832
1833	rate = vif->target_stats.tx_ucast_rate;
1834
1835	if (is_rate_legacy(rate)) {
1836		sinfo->txrate.legacy = rate / 100;
1837	} else if (is_rate_ht20(rate, &mcs, &sgi)) {
1838		if (sgi) {
1839			sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
1840			sinfo->txrate.mcs = mcs - 1;
1841		} else {
1842			sinfo->txrate.mcs = mcs;
1843		}
1844
1845		sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
1846		sinfo->txrate.bw = RATE_INFO_BW_20;
1847	} else if (is_rate_ht40(rate, &mcs, &sgi)) {
1848		if (sgi) {
1849			sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
1850			sinfo->txrate.mcs = mcs - 1;
1851		} else {
1852			sinfo->txrate.mcs = mcs;
1853		}
1854
1855		sinfo->txrate.bw = RATE_INFO_BW_40;
1856		sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
1857	} else {
1858		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1859			   "invalid rate from stats: %d\n", rate);
1860		ath6kl_debug_war(ar, ATH6KL_WAR_INVALID_RATE);
1861		return 0;
1862	}
1863
1864	sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
1865
1866	if (test_bit(CONNECTED, &vif->flags) &&
1867	    test_bit(DTIM_PERIOD_AVAIL, &vif->flags) &&
1868	    vif->nw_type == INFRA_NETWORK) {
1869		sinfo->filled |= BIT_ULL(NL80211_STA_INFO_BSS_PARAM);
1870		sinfo->bss_param.flags = 0;
1871		sinfo->bss_param.dtim_period = vif->assoc_bss_dtim_period;
1872		sinfo->bss_param.beacon_interval = vif->assoc_bss_beacon_int;
1873	}
1874
1875	return 0;
1876}
1877
1878static int ath6kl_set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1879			    struct cfg80211_pmksa *pmksa)
1880{
1881	struct ath6kl *ar = ath6kl_priv(netdev);
1882	struct ath6kl_vif *vif = netdev_priv(netdev);
1883
1884	return ath6kl_wmi_setpmkid_cmd(ar->wmi, vif->fw_vif_idx, pmksa->bssid,
1885				       pmksa->pmkid, true);
1886}
1887
1888static int ath6kl_del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1889			    struct cfg80211_pmksa *pmksa)
1890{
1891	struct ath6kl *ar = ath6kl_priv(netdev);
1892	struct ath6kl_vif *vif = netdev_priv(netdev);
1893
1894	return ath6kl_wmi_setpmkid_cmd(ar->wmi, vif->fw_vif_idx, pmksa->bssid,
1895				       pmksa->pmkid, false);
1896}
1897
1898static int ath6kl_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
1899{
1900	struct ath6kl *ar = ath6kl_priv(netdev);
1901	struct ath6kl_vif *vif = netdev_priv(netdev);
1902
1903	if (test_bit(CONNECTED, &vif->flags))
1904		return ath6kl_wmi_setpmkid_cmd(ar->wmi, vif->fw_vif_idx,
1905					       vif->bssid, NULL, false);
1906	return 0;
1907}
1908
1909static int ath6kl_wow_usr(struct ath6kl *ar, struct ath6kl_vif *vif,
1910			  struct cfg80211_wowlan *wow, u32 *filter)
1911{
1912	int ret, pos;
1913	u8 mask[WOW_PATTERN_SIZE];
1914	u16 i;
1915
1916	/* Configure the patterns that we received from the user. */
1917	for (i = 0; i < wow->n_patterns; i++) {
1918		/*
1919		 * Convert given nl80211 specific mask value to equivalent
1920		 * driver specific mask value and send it to the chip along
1921		 * with patterns. For example, If the mask value defined in
1922		 * struct cfg80211_wowlan is 0xA (equivalent binary is 1010),
1923		 * then equivalent driver specific mask value is
1924		 * "0xFF 0x00 0xFF 0x00".
1925		 */
1926		memset(&mask, 0, sizeof(mask));
1927		for (pos = 0; pos < wow->patterns[i].pattern_len; pos++) {
1928			if (wow->patterns[i].mask[pos / 8] & (0x1 << (pos % 8)))
1929				mask[pos] = 0xFF;
1930		}
1931		/*
1932		 * Note: Pattern's offset is not passed as part of wowlan
1933		 * parameter from CFG layer. So it's always passed as ZERO
1934		 * to the firmware. It means, given WOW patterns are always
1935		 * matched from the first byte of received pkt in the firmware.
1936		 */
1937		ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
1938				vif->fw_vif_idx, WOW_LIST_ID,
1939				wow->patterns[i].pattern_len,
1940				0 /* pattern offset */,
1941				wow->patterns[i].pattern, mask);
1942		if (ret)
1943			return ret;
1944	}
1945
1946	if (wow->disconnect)
1947		*filter |= WOW_FILTER_OPTION_NWK_DISASSOC;
1948
1949	if (wow->magic_pkt)
1950		*filter |= WOW_FILTER_OPTION_MAGIC_PACKET;
1951
1952	if (wow->gtk_rekey_failure)
1953		*filter |= WOW_FILTER_OPTION_GTK_ERROR;
1954
1955	if (wow->eap_identity_req)
1956		*filter |= WOW_FILTER_OPTION_EAP_REQ;
1957
1958	if (wow->four_way_handshake)
1959		*filter |= WOW_FILTER_OPTION_8021X_4WAYHS;
1960
1961	return 0;
1962}
1963
1964static int ath6kl_wow_ap(struct ath6kl *ar, struct ath6kl_vif *vif)
1965{
1966	static const u8 unicst_pattern[] = { 0x00, 0x00, 0x00,
1967		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1968		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1969		0x00, 0x08 };
1970	static const u8 unicst_mask[] = { 0x01, 0x00, 0x00,
1971		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1972		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1973		0x00, 0x7f };
1974	u8 unicst_offset = 0;
1975	static const u8 arp_pattern[] = { 0x08, 0x06 };
1976	static const u8 arp_mask[] = { 0xff, 0xff };
1977	u8 arp_offset = 20;
1978	static const u8 discvr_pattern[] = { 0xe0, 0x00, 0x00, 0xf8 };
1979	static const u8 discvr_mask[] = { 0xf0, 0x00, 0x00, 0xf8 };
1980	u8 discvr_offset = 38;
1981	static const u8 dhcp_pattern[] = { 0xff, 0xff, 0xff, 0xff,
1982		0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1983		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
1984		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1985		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1986		0x00, 0x00, 0x00, 0x00, 0x00, 0x43 /* port 67 */ };
1987	static const u8 dhcp_mask[] = { 0xff, 0xff, 0xff, 0xff,
1988		0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1989		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
1990		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1991		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1992		0x00, 0x00, 0x00, 0x00, 0xff, 0xff /* port 67 */ };
1993	u8 dhcp_offset = 0;
1994	int ret;
1995
1996	/* Setup unicast IP, EAPOL-like and ARP pkt pattern */
1997	ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
1998			vif->fw_vif_idx, WOW_LIST_ID,
1999			sizeof(unicst_pattern), unicst_offset,
2000			unicst_pattern, unicst_mask);
2001	if (ret) {
2002		ath6kl_err("failed to add WOW unicast IP pattern\n");
2003		return ret;
2004	}
2005
2006	/* Setup all ARP pkt pattern */
2007	ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
2008			vif->fw_vif_idx, WOW_LIST_ID,
2009			sizeof(arp_pattern), arp_offset,
2010			arp_pattern, arp_mask);
2011	if (ret) {
2012		ath6kl_err("failed to add WOW ARP pattern\n");
2013		return ret;
2014	}
2015
2016	/*
2017	 * Setup multicast pattern for mDNS 224.0.0.251,
2018	 * SSDP 239.255.255.250 and LLMNR  224.0.0.252
2019	 */
2020	ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
2021			vif->fw_vif_idx, WOW_LIST_ID,
2022			sizeof(discvr_pattern), discvr_offset,
2023			discvr_pattern, discvr_mask);
2024	if (ret) {
2025		ath6kl_err("failed to add WOW mDNS/SSDP/LLMNR pattern\n");
2026		return ret;
2027	}
2028
2029	/* Setup all DHCP broadcast pkt pattern */
2030	ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
2031			vif->fw_vif_idx, WOW_LIST_ID,
2032			sizeof(dhcp_pattern), dhcp_offset,
2033			dhcp_pattern, dhcp_mask);
2034	if (ret) {
2035		ath6kl_err("failed to add WOW DHCP broadcast pattern\n");
2036		return ret;
2037	}
2038
2039	return 0;
2040}
2041
2042static int ath6kl_wow_sta(struct ath6kl *ar, struct ath6kl_vif *vif)
2043{
2044	struct net_device *ndev = vif->ndev;
2045	static const u8 discvr_pattern[] = { 0xe0, 0x00, 0x00, 0xf8 };
2046	static const u8 discvr_mask[] = { 0xf0, 0x00, 0x00, 0xf8 };
2047	u8 discvr_offset = 38;
2048	u8 mac_mask[ETH_ALEN];
2049	int ret;
2050
2051	/* Setup unicast pkt pattern */
2052	eth_broadcast_addr(mac_mask);
2053	ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
2054				vif->fw_vif_idx, WOW_LIST_ID,
2055				ETH_ALEN, 0, ndev->dev_addr,
2056				mac_mask);
2057	if (ret) {
2058		ath6kl_err("failed to add WOW unicast pattern\n");
2059		return ret;
2060	}
2061
2062	/*
2063	 * Setup multicast pattern for mDNS 224.0.0.251,
2064	 * SSDP 239.255.255.250 and LLMNR 224.0.0.252
2065	 */
2066	if ((ndev->flags & IFF_ALLMULTI) ||
2067	    (ndev->flags & IFF_MULTICAST && netdev_mc_count(ndev) > 0)) {
2068		ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
2069				vif->fw_vif_idx, WOW_LIST_ID,
2070				sizeof(discvr_pattern), discvr_offset,
2071				discvr_pattern, discvr_mask);
2072		if (ret) {
2073			ath6kl_err("failed to add WOW mDNS/SSDP/LLMNR pattern\n");
2074			return ret;
2075		}
2076	}
2077
2078	return 0;
2079}
2080
2081static int is_hsleep_mode_procsed(struct ath6kl_vif *vif)
2082{
2083	return test_bit(HOST_SLEEP_MODE_CMD_PROCESSED, &vif->flags);
2084}
2085
2086static bool is_ctrl_ep_empty(struct ath6kl *ar)
2087{
2088	return !ar->tx_pending[ar->ctrl_ep];
2089}
2090
2091static int ath6kl_cfg80211_host_sleep(struct ath6kl *ar, struct ath6kl_vif *vif)
2092{
2093	int ret, left;
2094
2095	clear_bit(HOST_SLEEP_MODE_CMD_PROCESSED, &vif->flags);
2096
2097	ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
2098						 ATH6KL_HOST_MODE_ASLEEP);
2099	if (ret)
2100		return ret;
2101
2102	left = wait_event_interruptible_timeout(ar->event_wq,
2103						is_hsleep_mode_procsed(vif),
2104						WMI_TIMEOUT);
2105	if (left == 0) {
2106		ath6kl_warn("timeout, didn't get host sleep cmd processed event\n");
2107		ret = -ETIMEDOUT;
2108	} else if (left < 0) {
2109		ath6kl_warn("error while waiting for host sleep cmd processed event %d\n",
2110			    left);
2111		ret = left;
2112	}
2113
2114	if (ar->tx_pending[ar->ctrl_ep]) {
2115		left = wait_event_interruptible_timeout(ar->event_wq,
2116							is_ctrl_ep_empty(ar),
2117							WMI_TIMEOUT);
2118		if (left == 0) {
2119			ath6kl_warn("clear wmi ctrl data timeout\n");
2120			ret = -ETIMEDOUT;
2121		} else if (left < 0) {
2122			ath6kl_warn("clear wmi ctrl data failed: %d\n", left);
2123			ret = left;
2124		}
2125	}
2126
2127	return ret;
2128}
2129
2130static int ath6kl_wow_suspend_vif(struct ath6kl_vif *vif,
2131				  struct cfg80211_wowlan *wow, u32 *filter)
2132{
2133	struct ath6kl *ar = vif->ar;
2134	struct in_device *in_dev;
2135	struct in_ifaddr *ifa;
2136	int ret;
2137	u16 i, bmiss_time;
2138	__be32 ips[MAX_IP_ADDRS];
2139	u8 index = 0;
2140
2141	if (!test_bit(NETDEV_MCAST_ALL_ON, &vif->flags) &&
2142	    test_bit(ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER,
2143		     ar->fw_capabilities)) {
2144		ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi,
2145						vif->fw_vif_idx, false);
2146		if (ret)
2147			return ret;
2148	}
2149
2150	/* Clear existing WOW patterns */
2151	for (i = 0; i < WOW_MAX_FILTERS_PER_LIST; i++)
2152		ath6kl_wmi_del_wow_pattern_cmd(ar->wmi, vif->fw_vif_idx,
2153					       WOW_LIST_ID, i);
2154
2155	/*
2156	 * Skip the default WOW pattern configuration
2157	 * if the driver receives any WOW patterns from
2158	 * the user.
2159	 */
2160	if (wow)
2161		ret = ath6kl_wow_usr(ar, vif, wow, filter);
2162	else if (vif->nw_type == AP_NETWORK)
2163		ret = ath6kl_wow_ap(ar, vif);
2164	else
2165		ret = ath6kl_wow_sta(ar, vif);
2166
2167	if (ret)
2168		return ret;
2169
2170	netif_stop_queue(vif->ndev);
2171
2172	if (vif->nw_type != AP_NETWORK) {
2173		ret = ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx,
2174						    ATH6KL_MAX_WOW_LISTEN_INTL,
2175						    0);
2176		if (ret)
2177			return ret;
2178
2179		/* Set listen interval x 15 times as bmiss time */
2180		bmiss_time = ATH6KL_MAX_WOW_LISTEN_INTL * 15;
2181		if (bmiss_time > ATH6KL_MAX_BMISS_TIME)
2182			bmiss_time = ATH6KL_MAX_BMISS_TIME;
2183
2184		ret = ath6kl_wmi_bmisstime_cmd(ar->wmi, vif->fw_vif_idx,
2185					       bmiss_time, 0);
2186		if (ret)
2187			return ret;
2188
2189		ret = ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx,
2190						0xFFFF, 0, 0xFFFF, 0, 0, 0,
2191						0, 0, 0, 0);
2192		if (ret)
2193			return ret;
2194	}
2195
2196	/* Setup own IP addr for ARP agent. */
2197	in_dev = __in_dev_get_rtnl(vif->ndev);
2198	if (!in_dev)
2199		return 0;
2200
2201	ifa = rtnl_dereference(in_dev->ifa_list);
2202	memset(&ips, 0, sizeof(ips));
2203
2204	/* Configure IP addr only if IP address count < MAX_IP_ADDRS */
2205	while (index < MAX_IP_ADDRS && ifa) {
2206		ips[index] = ifa->ifa_local;
2207		ifa = rtnl_dereference(ifa->ifa_next);
2208		index++;
2209	}
2210
2211	if (ifa) {
2212		ath6kl_err("total IP addr count is exceeding fw limit\n");
2213		return -EINVAL;
2214	}
2215
2216	ret = ath6kl_wmi_set_ip_cmd(ar->wmi, vif->fw_vif_idx, ips[0], ips[1]);
2217	if (ret) {
2218		ath6kl_err("fail to setup ip for arp agent\n");
2219		return ret;
2220	}
2221
2222	return ret;
2223}
2224
2225static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
2226{
2227	struct ath6kl_vif *first_vif, *vif;
2228	int ret = 0;
2229	u32 filter = 0;
2230	bool connected = false;
2231
2232	/* enter / leave wow suspend on first vif always */
2233	first_vif = ath6kl_vif_first(ar);
2234	if (WARN_ON(!first_vif) ||
2235	    !ath6kl_cfg80211_ready(first_vif))
2236		return -EIO;
2237
2238	if (wow && (wow->n_patterns > WOW_MAX_FILTERS_PER_LIST))
2239		return -EINVAL;
2240
2241	/* install filters for each connected vif */
2242	spin_lock_bh(&ar->list_lock);
2243	list_for_each_entry(vif, &ar->vif_list, list) {
2244		if (!test_bit(CONNECTED, &vif->flags) ||
2245		    !ath6kl_cfg80211_ready(vif))
2246			continue;
2247		connected = true;
2248
2249		ret = ath6kl_wow_suspend_vif(vif, wow, &filter);
2250		if (ret)
2251			break;
2252	}
2253	spin_unlock_bh(&ar->list_lock);
2254
2255	if (!connected)
2256		return -ENOTCONN;
2257	else if (ret)
2258		return ret;
2259
2260	ar->state = ATH6KL_STATE_SUSPENDING;
2261
2262	ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, first_vif->fw_vif_idx,
2263					  ATH6KL_WOW_MODE_ENABLE,
2264					  filter,
2265					  WOW_HOST_REQ_DELAY);
2266	if (ret)
2267		return ret;
2268
2269	return ath6kl_cfg80211_host_sleep(ar, first_vif);
2270}
2271
2272static int ath6kl_wow_resume_vif(struct ath6kl_vif *vif)
2273{
2274	struct ath6kl *ar = vif->ar;
2275	int ret;
2276
2277	if (vif->nw_type != AP_NETWORK) {
2278		ret = ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx,
2279						0, 0, 0, 0, 0, 0, 3, 0, 0, 0);
2280		if (ret)
2281			return ret;
2282
2283		ret = ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx,
2284						    vif->listen_intvl_t, 0);
2285		if (ret)
2286			return ret;
2287
2288		ret = ath6kl_wmi_bmisstime_cmd(ar->wmi, vif->fw_vif_idx,
2289					       vif->bmiss_time_t, 0);
2290		if (ret)
2291			return ret;
2292	}
2293
2294	if (!test_bit(NETDEV_MCAST_ALL_OFF, &vif->flags) &&
2295	    test_bit(ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER,
2296		     ar->fw_capabilities)) {
2297		ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi,
2298						  vif->fw_vif_idx, true);
2299		if (ret)
2300			return ret;
2301	}
2302
2303	netif_wake_queue(vif->ndev);
2304
2305	return 0;
2306}
2307
2308static int ath6kl_wow_resume(struct ath6kl *ar)
2309{
2310	struct ath6kl_vif *vif;
2311	int ret;
2312
2313	vif = ath6kl_vif_first(ar);
2314	if (WARN_ON(!vif) ||
2315	    !ath6kl_cfg80211_ready(vif))
2316		return -EIO;
2317
2318	ar->state = ATH6KL_STATE_RESUMING;
2319
2320	ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
2321						 ATH6KL_HOST_MODE_AWAKE);
2322	if (ret) {
2323		ath6kl_warn("Failed to configure host sleep mode for wow resume: %d\n",
2324			    ret);
2325		goto cleanup;
2326	}
2327
2328	spin_lock_bh(&ar->list_lock);
2329	list_for_each_entry(vif, &ar->vif_list, list) {
2330		if (!test_bit(CONNECTED, &vif->flags) ||
2331		    !ath6kl_cfg80211_ready(vif))
2332			continue;
2333		ret = ath6kl_wow_resume_vif(vif);
2334		if (ret)
2335			break;
2336	}
2337	spin_unlock_bh(&ar->list_lock);
2338
2339	if (ret)
2340		goto cleanup;
2341
2342	ar->state = ATH6KL_STATE_ON;
2343	return 0;
2344
2345cleanup:
2346	ar->state = ATH6KL_STATE_WOW;
2347	return ret;
2348}
2349
2350static int ath6kl_cfg80211_deepsleep_suspend(struct ath6kl *ar)
2351{
2352	struct ath6kl_vif *vif;
2353	int ret;
2354
2355	vif = ath6kl_vif_first(ar);
2356	if (!vif)
2357		return -EIO;
2358
2359	if (!test_bit(WMI_READY, &ar->flag)) {
2360		ath6kl_err("deepsleep failed as wmi is not ready\n");
2361		return -EIO;
2362	}
2363
2364	ath6kl_cfg80211_stop_all(ar);
2365
2366	/* Save the current power mode before enabling power save */
2367	ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode;
2368
2369	ret = ath6kl_wmi_powermode_cmd(ar->wmi, 0, REC_POWER);
2370	if (ret)
2371		return ret;
2372
2373	/* Disable WOW mode */
2374	ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, vif->fw_vif_idx,
2375					  ATH6KL_WOW_MODE_DISABLE,
2376					  0, 0);
2377	if (ret)
2378		return ret;
2379
2380	/* Flush all non control pkts in TX path */
2381	ath6kl_tx_data_cleanup(ar);
2382
2383	ret = ath6kl_cfg80211_host_sleep(ar, vif);
2384	if (ret)
2385		return ret;
2386
2387	return 0;
2388}
2389
2390static int ath6kl_cfg80211_deepsleep_resume(struct ath6kl *ar)
2391{
2392	struct ath6kl_vif *vif;
2393	int ret;
2394
2395	vif = ath6kl_vif_first(ar);
2396
2397	if (!vif)
2398		return -EIO;
2399
2400	if (ar->wmi->pwr_mode != ar->wmi->saved_pwr_mode) {
2401		ret = ath6kl_wmi_powermode_cmd(ar->wmi, 0,
2402					       ar->wmi->saved_pwr_mode);
2403		if (ret)
2404			return ret;
2405	}
2406
2407	ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
2408						 ATH6KL_HOST_MODE_AWAKE);
2409	if (ret)
2410		return ret;
2411
2412	ar->state = ATH6KL_STATE_ON;
2413
2414	/* Reset scan parameter to default values */
2415	ret = ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx,
2416					0, 0, 0, 0, 0, 0, 3, 0, 0, 0);
2417	if (ret)
2418		return ret;
2419
2420	return 0;
2421}
2422
2423int ath6kl_cfg80211_suspend(struct ath6kl *ar,
2424			    enum ath6kl_cfg_suspend_mode mode,
2425			    struct cfg80211_wowlan *wow)
2426{
2427	struct ath6kl_vif *vif;
2428	enum ath6kl_state prev_state;
2429	int ret;
2430
2431	switch (mode) {
2432	case ATH6KL_CFG_SUSPEND_WOW:
2433
2434		ath6kl_dbg(ATH6KL_DBG_SUSPEND, "wow mode suspend\n");
2435
2436		/* Flush all non control pkts in TX path */
2437		ath6kl_tx_data_cleanup(ar);
2438
2439		prev_state = ar->state;
2440
2441		ret = ath6kl_wow_suspend(ar, wow);
2442		if (ret) {
2443			ar->state = prev_state;
2444			return ret;
2445		}
2446
2447		ar->state = ATH6KL_STATE_WOW;
2448		break;
2449
2450	case ATH6KL_CFG_SUSPEND_DEEPSLEEP:
2451
2452		ath6kl_dbg(ATH6KL_DBG_SUSPEND, "deep sleep suspend\n");
2453
2454		ret = ath6kl_cfg80211_deepsleep_suspend(ar);
2455		if (ret) {
2456			ath6kl_err("deepsleep suspend failed: %d\n", ret);
2457			return ret;
2458		}
2459
2460		ar->state = ATH6KL_STATE_DEEPSLEEP;
2461
2462		break;
2463
2464	case ATH6KL_CFG_SUSPEND_CUTPOWER:
2465
2466		ath6kl_cfg80211_stop_all(ar);
2467
2468		if (ar->state == ATH6KL_STATE_OFF) {
2469			ath6kl_dbg(ATH6KL_DBG_SUSPEND,
2470				   "suspend hw off, no action for cutpower\n");
2471			break;
2472		}
2473
2474		ath6kl_dbg(ATH6KL_DBG_SUSPEND, "suspend cutting power\n");
2475
2476		ret = ath6kl_init_hw_stop(ar);
2477		if (ret) {
2478			ath6kl_warn("failed to stop hw during suspend: %d\n",
2479				    ret);
2480		}
2481
2482		ar->state = ATH6KL_STATE_CUTPOWER;
2483
2484		break;
2485
2486	default:
2487		break;
2488	}
2489
2490	list_for_each_entry(vif, &ar->vif_list, list)
2491		ath6kl_cfg80211_scan_complete_event(vif, true);
2492
2493	return 0;
2494}
2495EXPORT_SYMBOL(ath6kl_cfg80211_suspend);
2496
2497int ath6kl_cfg80211_resume(struct ath6kl *ar)
2498{
2499	int ret;
2500
2501	switch (ar->state) {
2502	case  ATH6KL_STATE_WOW:
2503		ath6kl_dbg(ATH6KL_DBG_SUSPEND, "wow mode resume\n");
2504
2505		ret = ath6kl_wow_resume(ar);
2506		if (ret) {
2507			ath6kl_warn("wow mode resume failed: %d\n", ret);
2508			return ret;
2509		}
2510
2511		break;
2512
2513	case ATH6KL_STATE_DEEPSLEEP:
2514		ath6kl_dbg(ATH6KL_DBG_SUSPEND, "deep sleep resume\n");
2515
2516		ret = ath6kl_cfg80211_deepsleep_resume(ar);
2517		if (ret) {
2518			ath6kl_warn("deep sleep resume failed: %d\n", ret);
2519			return ret;
2520		}
2521		break;
2522
2523	case ATH6KL_STATE_CUTPOWER:
2524		ath6kl_dbg(ATH6KL_DBG_SUSPEND, "resume restoring power\n");
2525
2526		ret = ath6kl_init_hw_start(ar);
2527		if (ret) {
2528			ath6kl_warn("Failed to boot hw in resume: %d\n", ret);
2529			return ret;
2530		}
2531		break;
2532
2533	default:
2534		break;
2535	}
2536
2537	return 0;
2538}
2539EXPORT_SYMBOL(ath6kl_cfg80211_resume);
2540
2541#ifdef CONFIG_PM
2542
2543/* hif layer decides what suspend mode to use */
2544static int __ath6kl_cfg80211_suspend(struct wiphy *wiphy,
2545				 struct cfg80211_wowlan *wow)
2546{
2547	struct ath6kl *ar = wiphy_priv(wiphy);
2548
2549	ath6kl_recovery_suspend(ar);
2550
2551	return ath6kl_hif_suspend(ar, wow);
2552}
2553
2554static int __ath6kl_cfg80211_resume(struct wiphy *wiphy)
2555{
2556	struct ath6kl *ar = wiphy_priv(wiphy);
2557	int err;
2558
2559	err = ath6kl_hif_resume(ar);
2560	if (err)
2561		return err;
2562
2563	ath6kl_recovery_resume(ar);
2564
2565	return 0;
2566}
2567
2568/*
2569 * FIXME: WOW suspend mode is selected if the host sdio controller supports
2570 * both sdio irq wake up and keep power. The target pulls sdio data line to
2571 * wake up the host when WOW pattern matches. This causes sdio irq handler
2572 * is being called in the host side which internally hits ath6kl's RX path.
2573 *
2574 * Since sdio interrupt is not disabled, RX path executes even before
2575 * the host executes the actual resume operation from PM module.
2576 *
2577 * In the current scenario, WOW resume should happen before start processing
2578 * any data from the target. So It's required to perform WOW resume in RX path.
2579 * Ideally we should perform WOW resume only in the actual platform
2580 * resume path. This area needs bit rework to avoid WOW resume in RX path.
2581 *
2582 * ath6kl_check_wow_status() is called from ath6kl_rx().
2583 */
2584void ath6kl_check_wow_status(struct ath6kl *ar)
2585{
2586	if (ar->state == ATH6KL_STATE_SUSPENDING)
2587		return;
2588
2589	if (ar->state == ATH6KL_STATE_WOW)
2590		ath6kl_cfg80211_resume(ar);
2591}
2592
2593#else
2594
2595void ath6kl_check_wow_status(struct ath6kl *ar)
2596{
2597}
2598#endif
2599
2600static int ath6kl_set_htcap(struct ath6kl_vif *vif, enum nl80211_band band,
2601			    bool ht_enable)
2602{
2603	struct ath6kl_htcap *htcap = &vif->htcap[band];
2604
2605	if (htcap->ht_enable == ht_enable)
2606		return 0;
2607
2608	if (ht_enable) {
2609		/* Set default ht capabilities */
2610		htcap->ht_enable = true;
2611		htcap->cap_info = (band == NL80211_BAND_2GHZ) ?
2612				   ath6kl_g_htcap : ath6kl_a_htcap;
2613		htcap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K;
2614	} else /* Disable ht */
2615		memset(htcap, 0, sizeof(*htcap));
2616
2617	return ath6kl_wmi_set_htcap_cmd(vif->ar->wmi, vif->fw_vif_idx,
2618					band, htcap);
2619}
2620
2621static int ath6kl_restore_htcap(struct ath6kl_vif *vif)
2622{
2623	struct wiphy *wiphy = vif->ar->wiphy;
2624	int band, ret = 0;
2625
2626	for (band = 0; band < NUM_NL80211_BANDS; band++) {
2627		if (!wiphy->bands[band])
2628			continue;
2629
2630		ret = ath6kl_set_htcap(vif, band,
2631				wiphy->bands[band]->ht_cap.ht_supported);
2632		if (ret)
2633			return ret;
2634	}
2635
2636	return ret;
2637}
2638
2639static bool ath6kl_is_p2p_ie(const u8 *pos)
2640{
2641	return pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
2642		pos[2] == 0x50 && pos[3] == 0x6f &&
2643		pos[4] == 0x9a && pos[5] == 0x09;
2644}
2645
2646static int ath6kl_set_ap_probe_resp_ies(struct ath6kl_vif *vif,
2647					const u8 *ies, size_t ies_len)
2648{
2649	struct ath6kl *ar = vif->ar;
2650	const u8 *pos;
2651	u8 *buf = NULL;
2652	size_t len = 0;
2653	int ret;
2654
2655	/*
2656	 * Filter out P2P IE(s) since they will be included depending on
2657	 * the Probe Request frame in ath6kl_send_go_probe_resp().
2658	 */
2659
2660	if (ies && ies_len) {
2661		buf = kmalloc(ies_len, GFP_KERNEL);
2662		if (buf == NULL)
2663			return -ENOMEM;
2664		pos = ies;
2665		while (pos + 1 < ies + ies_len) {
2666			if (pos + 2 + pos[1] > ies + ies_len)
2667				break;
2668			if (!ath6kl_is_p2p_ie(pos)) {
2669				memcpy(buf + len, pos, 2 + pos[1]);
2670				len += 2 + pos[1];
2671			}
2672			pos += 2 + pos[1];
2673		}
2674	}
2675
2676	ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
2677				       WMI_FRAME_PROBE_RESP, buf, len);
2678	kfree(buf);
2679	return ret;
2680}
2681
2682static int ath6kl_set_ies(struct ath6kl_vif *vif,
2683			  struct cfg80211_beacon_data *info)
2684{
2685	struct ath6kl *ar = vif->ar;
2686	int res;
2687
2688	/* this also clears IE in fw if it's not set */
2689	res = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
2690				       WMI_FRAME_BEACON,
2691				       info->beacon_ies,
2692				       info->beacon_ies_len);
2693	if (res)
2694		return res;
2695
2696	/* this also clears IE in fw if it's not set */
2697	res = ath6kl_set_ap_probe_resp_ies(vif, info->proberesp_ies,
2698					   info->proberesp_ies_len);
2699	if (res)
2700		return res;
2701
2702	/* this also clears IE in fw if it's not set */
2703	res = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
2704				       WMI_FRAME_ASSOC_RESP,
2705				       info->assocresp_ies,
2706				       info->assocresp_ies_len);
2707	if (res)
2708		return res;
2709
2710	return 0;
2711}
2712
2713static int ath6kl_get_rsn_capab(struct cfg80211_beacon_data *beacon,
2714				u8 *rsn_capab)
2715{
2716	const u8 *rsn_ie;
2717	size_t rsn_ie_len;
2718	u16 cnt;
2719
2720	if (!beacon->tail)
2721		return -EINVAL;
2722
2723	rsn_ie = cfg80211_find_ie(WLAN_EID_RSN, beacon->tail, beacon->tail_len);
2724	if (!rsn_ie)
2725		return -EINVAL;
2726
2727	rsn_ie_len = *(rsn_ie + 1);
2728	/* skip element id and length */
2729	rsn_ie += 2;
2730
2731	/* skip version */
2732	if (rsn_ie_len < 2)
2733		return -EINVAL;
2734	rsn_ie +=  2;
2735	rsn_ie_len -= 2;
2736
2737	/* skip group cipher suite */
2738	if (rsn_ie_len < 4)
2739		return 0;
2740	rsn_ie +=  4;
2741	rsn_ie_len -= 4;
2742
2743	/* skip pairwise cipher suite */
2744	if (rsn_ie_len < 2)
2745		return 0;
2746	cnt = get_unaligned_le16(rsn_ie);
2747	rsn_ie += (2 + cnt * 4);
2748	rsn_ie_len -= (2 + cnt * 4);
2749
2750	/* skip akm suite */
2751	if (rsn_ie_len < 2)
2752		return 0;
2753	cnt = get_unaligned_le16(rsn_ie);
2754	rsn_ie += (2 + cnt * 4);
2755	rsn_ie_len -= (2 + cnt * 4);
2756
2757	if (rsn_ie_len < 2)
2758		return 0;
2759
2760	memcpy(rsn_capab, rsn_ie, 2);
2761
2762	return 0;
2763}
2764
2765static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,
2766			   struct cfg80211_ap_settings *info)
2767{
2768	struct ath6kl *ar = ath6kl_priv(dev);
2769	struct ath6kl_vif *vif = netdev_priv(dev);
2770	struct ieee80211_mgmt *mgmt;
2771	bool hidden = false;
2772	u8 *ies;
2773	struct wmi_connect_cmd p;
2774	int res;
2775	int i, ret;
2776	u16 rsn_capab = 0;
2777	int inactivity_timeout = 0;
2778
2779	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s:\n", __func__);
2780
2781	if (!ath6kl_cfg80211_ready(vif))
2782		return -EIO;
2783
2784	if (vif->next_mode != AP_NETWORK)
2785		return -EOPNOTSUPP;
2786
2787	res = ath6kl_set_ies(vif, &info->beacon);
2788
2789	ar->ap_mode_bkey.valid = false;
2790
2791	ret = ath6kl_wmi_ap_set_beacon_intvl_cmd(ar->wmi, vif->fw_vif_idx,
2792						 info->beacon_interval);
2793
2794	if (ret)
2795		ath6kl_warn("Failed to set beacon interval: %d\n", ret);
2796
2797	ret = ath6kl_wmi_ap_set_dtim_cmd(ar->wmi, vif->fw_vif_idx,
2798					 info->dtim_period);
2799
2800	/* ignore error, just print a warning and continue normally */
2801	if (ret)
2802		ath6kl_warn("Failed to set dtim_period in beacon: %d\n", ret);
2803
2804	if (info->beacon.head == NULL)
2805		return -EINVAL;
2806	mgmt = (struct ieee80211_mgmt *) info->beacon.head;
2807	ies = mgmt->u.beacon.variable;
2808	if (ies > info->beacon.head + info->beacon.head_len)
2809		return -EINVAL;
2810
2811	if (info->ssid == NULL)
2812		return -EINVAL;
2813	memcpy(vif->ssid, info->ssid, info->ssid_len);
2814	vif->ssid_len = info->ssid_len;
2815	if (info->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
2816		hidden = true;
2817
2818	res = ath6kl_wmi_ap_hidden_ssid(ar->wmi, vif->fw_vif_idx, hidden);
2819	if (res)
2820		return res;
2821
2822	ret = ath6kl_set_auth_type(vif, info->auth_type);
2823	if (ret)
2824		return ret;
2825
2826	memset(&p, 0, sizeof(p));
2827
2828	for (i = 0; i < info->crypto.n_akm_suites; i++) {
2829		switch (info->crypto.akm_suites[i]) {
2830		case WLAN_AKM_SUITE_8021X:
2831			if (info->crypto.wpa_versions & NL80211_WPA_VERSION_1)
2832				p.auth_mode |= WPA_AUTH;
2833			if (info->crypto.wpa_versions & NL80211_WPA_VERSION_2)
2834				p.auth_mode |= WPA2_AUTH;
2835			break;
2836		case WLAN_AKM_SUITE_PSK:
2837			if (info->crypto.wpa_versions & NL80211_WPA_VERSION_1)
2838				p.auth_mode |= WPA_PSK_AUTH;
2839			if (info->crypto.wpa_versions & NL80211_WPA_VERSION_2)
2840				p.auth_mode |= WPA2_PSK_AUTH;
2841			break;
2842		}
2843	}
2844	if (p.auth_mode == 0)
2845		p.auth_mode = NONE_AUTH;
2846	vif->auth_mode = p.auth_mode;
2847
2848	for (i = 0; i < info->crypto.n_ciphers_pairwise; i++) {
2849		switch (info->crypto.ciphers_pairwise[i]) {
2850		case WLAN_CIPHER_SUITE_WEP40:
2851		case WLAN_CIPHER_SUITE_WEP104:
2852			p.prwise_crypto_type |= WEP_CRYPT;
2853			break;
2854		case WLAN_CIPHER_SUITE_TKIP:
2855			p.prwise_crypto_type |= TKIP_CRYPT;
2856			break;
2857		case WLAN_CIPHER_SUITE_CCMP:
2858			p.prwise_crypto_type |= AES_CRYPT;
2859			break;
2860		case WLAN_CIPHER_SUITE_SMS4:
2861			p.prwise_crypto_type |= WAPI_CRYPT;
2862			break;
2863		}
2864	}
2865	if (p.prwise_crypto_type == 0) {
2866		p.prwise_crypto_type = NONE_CRYPT;
2867		ath6kl_set_cipher(vif, 0, true);
2868	} else if (info->crypto.n_ciphers_pairwise == 1) {
2869		ath6kl_set_cipher(vif, info->crypto.ciphers_pairwise[0], true);
2870	}
2871
2872	switch (info->crypto.cipher_group) {
2873	case WLAN_CIPHER_SUITE_WEP40:
2874	case WLAN_CIPHER_SUITE_WEP104:
2875		p.grp_crypto_type = WEP_CRYPT;
2876		break;
2877	case WLAN_CIPHER_SUITE_TKIP:
2878		p.grp_crypto_type = TKIP_CRYPT;
2879		break;
2880	case WLAN_CIPHER_SUITE_CCMP:
2881		p.grp_crypto_type = AES_CRYPT;
2882		break;
2883	case WLAN_CIPHER_SUITE_SMS4:
2884		p.grp_crypto_type = WAPI_CRYPT;
2885		break;
2886	default:
2887		p.grp_crypto_type = NONE_CRYPT;
2888		break;
2889	}
2890	ath6kl_set_cipher(vif, info->crypto.cipher_group, false);
2891
2892	p.nw_type = AP_NETWORK;
2893	vif->nw_type = vif->next_mode;
2894
2895	p.ssid_len = vif->ssid_len;
2896	memcpy(p.ssid, vif->ssid, vif->ssid_len);
2897	p.dot11_auth_mode = vif->dot11_auth_mode;
2898	p.ch = cpu_to_le16(info->chandef.chan->center_freq);
2899
2900	/* Enable uAPSD support by default */
2901	res = ath6kl_wmi_ap_set_apsd(ar->wmi, vif->fw_vif_idx, true);
2902	if (res < 0)
2903		return res;
2904
2905	if (vif->wdev.iftype == NL80211_IFTYPE_P2P_GO) {
2906		p.nw_subtype = SUBTYPE_P2PGO;
2907	} else {
2908		/*
2909		 * Due to firmware limitation, it is not possible to
2910		 * do P2P mgmt operations in AP mode
2911		 */
2912		p.nw_subtype = SUBTYPE_NONE;
2913	}
2914
2915	if (info->inactivity_timeout) {
2916		inactivity_timeout = info->inactivity_timeout;
2917
2918		if (test_bit(ATH6KL_FW_CAPABILITY_AP_INACTIVITY_MINS,
2919			     ar->fw_capabilities))
2920			inactivity_timeout = DIV_ROUND_UP(inactivity_timeout,
2921							  60);
2922
2923		res = ath6kl_wmi_set_inact_period(ar->wmi, vif->fw_vif_idx,
2924						  inactivity_timeout);
2925		if (res < 0)
2926			return res;
2927	}
2928
2929	if (ath6kl_set_htcap(vif, info->chandef.chan->band,
2930			     cfg80211_get_chandef_type(&info->chandef)
2931					!= NL80211_CHAN_NO_HT))
2932		return -EIO;
2933
2934	/*
2935	 * Get the PTKSA replay counter in the RSN IE. Supplicant
2936	 * will use the RSN IE in M3 message and firmware has to
2937	 * advertise the same in beacon/probe response. Send
2938	 * the complete RSN IE capability field to firmware
2939	 */
2940	if (!ath6kl_get_rsn_capab(&info->beacon, (u8 *) &rsn_capab) &&
2941	    test_bit(ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE,
2942		     ar->fw_capabilities)) {
2943		res = ath6kl_wmi_set_ie_cmd(ar->wmi, vif->fw_vif_idx,
2944					    WLAN_EID_RSN, WMI_RSN_IE_CAPB,
2945					    (const u8 *) &rsn_capab,
2946					    sizeof(rsn_capab));
2947		vif->rsn_capab = rsn_capab;
2948		if (res < 0)
2949			return res;
2950	}
2951
2952	memcpy(&vif->profile, &p, sizeof(p));
2953	res = ath6kl_wmi_ap_profile_commit(ar->wmi, vif->fw_vif_idx, &p);
2954	if (res < 0)
2955		return res;
2956
2957	return 0;
2958}
2959
2960static int ath6kl_change_beacon(struct wiphy *wiphy, struct net_device *dev,
2961				struct cfg80211_ap_update *params)
2962{
2963	struct ath6kl_vif *vif = netdev_priv(dev);
2964
2965	if (!ath6kl_cfg80211_ready(vif))
2966		return -EIO;
2967
2968	if (vif->next_mode != AP_NETWORK)
2969		return -EOPNOTSUPP;
2970
2971	return ath6kl_set_ies(vif, &params->beacon);
2972}
2973
2974static int ath6kl_stop_ap(struct wiphy *wiphy, struct net_device *dev,
2975			  unsigned int link_id)
2976{
2977	struct ath6kl *ar = ath6kl_priv(dev);
2978	struct ath6kl_vif *vif = netdev_priv(dev);
2979
2980	if (vif->nw_type != AP_NETWORK)
2981		return -EOPNOTSUPP;
2982	if (!test_bit(CONNECTED, &vif->flags))
2983		return -ENOTCONN;
2984
2985	ath6kl_wmi_disconnect_cmd(ar->wmi, vif->fw_vif_idx);
2986	clear_bit(CONNECTED, &vif->flags);
2987	netif_carrier_off(vif->ndev);
2988
2989	/* Restore ht setting in firmware */
2990	return ath6kl_restore_htcap(vif);
2991}
2992
2993static const u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
2994
2995static int ath6kl_del_station(struct wiphy *wiphy, struct net_device *dev,
2996			      struct station_del_parameters *params)
2997{
2998	struct ath6kl *ar = ath6kl_priv(dev);
2999	struct ath6kl_vif *vif = netdev_priv(dev);
3000	const u8 *addr = params->mac ? params->mac : bcast_addr;
3001
3002	return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx, WMI_AP_DEAUTH,
3003				      addr, WLAN_REASON_PREV_AUTH_NOT_VALID);
3004}
3005
3006static int ath6kl_change_station(struct wiphy *wiphy, struct net_device *dev,
3007				 const u8 *mac,
3008				 struct station_parameters *params)
3009{
3010	struct ath6kl *ar = ath6kl_priv(dev);
3011	struct ath6kl_vif *vif = netdev_priv(dev);
3012	int err;
3013
3014	if (vif->nw_type != AP_NETWORK)
3015		return -EOPNOTSUPP;
3016
3017	err = cfg80211_check_station_change(wiphy, params,
3018					    CFG80211_STA_AP_MLME_CLIENT);
3019	if (err)
3020		return err;
3021
3022	if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
3023		return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx,
3024					      WMI_AP_MLME_AUTHORIZE, mac, 0);
3025	return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx,
3026				      WMI_AP_MLME_UNAUTHORIZE, mac, 0);
3027}
3028
3029static int ath6kl_remain_on_channel(struct wiphy *wiphy,
3030				    struct wireless_dev *wdev,
3031				    struct ieee80211_channel *chan,
3032				    unsigned int duration,
3033				    u64 *cookie)
3034{
3035	struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev);
3036	struct ath6kl *ar = ath6kl_priv(vif->ndev);
3037	u32 id;
3038
3039	/* TODO: if already pending or ongoing remain-on-channel,
3040	 * return -EBUSY */
3041	id = ++vif->last_roc_id;
3042	if (id == 0) {
3043		/* Do not use 0 as the cookie value */
3044		id = ++vif->last_roc_id;
3045	}
3046	*cookie = id;
3047
3048	return ath6kl_wmi_remain_on_chnl_cmd(ar->wmi, vif->fw_vif_idx,
3049					     chan->center_freq, duration);
3050}
3051
3052static int ath6kl_cancel_remain_on_channel(struct wiphy *wiphy,
3053					   struct wireless_dev *wdev,
3054					   u64 cookie)
3055{
3056	struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev);
3057	struct ath6kl *ar = ath6kl_priv(vif->ndev);
3058
3059	if (cookie != vif->last_roc_id)
3060		return -ENOENT;
3061	vif->last_cancel_roc_id = cookie;
3062
3063	return ath6kl_wmi_cancel_remain_on_chnl_cmd(ar->wmi, vif->fw_vif_idx);
3064}
3065
3066static int ath6kl_send_go_probe_resp(struct ath6kl_vif *vif,
3067				     const u8 *buf, size_t len,
3068				     unsigned int freq)
3069{
3070	struct ath6kl *ar = vif->ar;
3071	const u8 *pos;
3072	u8 *p2p;
3073	int p2p_len;
3074	int ret;
3075	const struct ieee80211_mgmt *mgmt;
3076
3077	mgmt = (const struct ieee80211_mgmt *) buf;
3078
3079	/* Include P2P IE(s) from the frame generated in user space. */
3080
3081	p2p = kmalloc(len, GFP_KERNEL);
3082	if (p2p == NULL)
3083		return -ENOMEM;
3084	p2p_len = 0;
3085
3086	pos = mgmt->u.probe_resp.variable;
3087	while (pos + 1 < buf + len) {
3088		if (pos + 2 + pos[1] > buf + len)
3089			break;
3090		if (ath6kl_is_p2p_ie(pos)) {
3091			memcpy(p2p + p2p_len, pos, 2 + pos[1]);
3092			p2p_len += 2 + pos[1];
3093		}
3094		pos += 2 + pos[1];
3095	}
3096
3097	ret = ath6kl_wmi_send_probe_response_cmd(ar->wmi, vif->fw_vif_idx, freq,
3098						 mgmt->da, p2p, p2p_len);
3099	kfree(p2p);
3100	return ret;
3101}
3102
3103static bool ath6kl_mgmt_powersave_ap(struct ath6kl_vif *vif,
3104				     u32 id,
3105				     u32 freq,
3106				     u32 wait,
3107				     const u8 *buf,
3108				     size_t len,
3109				     bool *more_data,
3110				     bool no_cck)
3111{
3112	struct ieee80211_mgmt *mgmt;
3113	struct ath6kl_sta *conn;
3114	bool is_psq_empty = false;
3115	struct ath6kl_mgmt_buff *mgmt_buf;
3116	size_t mgmt_buf_size;
3117	struct ath6kl *ar = vif->ar;
3118
3119	mgmt = (struct ieee80211_mgmt *) buf;
3120	if (is_multicast_ether_addr(mgmt->da))
3121		return false;
3122
3123	conn = ath6kl_find_sta(vif, mgmt->da);
3124	if (!conn)
3125		return false;
3126
3127	if (conn->sta_flags & STA_PS_SLEEP) {
3128		if (!(conn->sta_flags & STA_PS_POLLED)) {
3129			/* Queue the frames if the STA is sleeping */
3130			mgmt_buf_size = len + sizeof(struct ath6kl_mgmt_buff);
3131			mgmt_buf = kmalloc(mgmt_buf_size, GFP_KERNEL);
3132			if (!mgmt_buf)
3133				return false;
3134
3135			INIT_LIST_HEAD(&mgmt_buf->list);
3136			mgmt_buf->id = id;
3137			mgmt_buf->freq = freq;
3138			mgmt_buf->wait = wait;
3139			mgmt_buf->len = len;
3140			mgmt_buf->no_cck = no_cck;
3141			memcpy(mgmt_buf->buf, buf, len);
3142			spin_lock_bh(&conn->psq_lock);
3143			is_psq_empty = skb_queue_empty(&conn->psq) &&
3144					(conn->mgmt_psq_len == 0);
3145			list_add_tail(&mgmt_buf->list, &conn->mgmt_psq);
3146			conn->mgmt_psq_len++;
3147			spin_unlock_bh(&conn->psq_lock);
3148
3149			/*
3150			 * If this is the first pkt getting queued
3151			 * for this STA, update the PVB for this
3152			 * STA.
3153			 */
3154			if (is_psq_empty)
3155				ath6kl_wmi_set_pvb_cmd(ar->wmi, vif->fw_vif_idx,
3156						       conn->aid, 1);
3157			return true;
3158		}
3159
3160		/*
3161		 * This tx is because of a PsPoll.
3162		 * Determine if MoreData bit has to be set.
3163		 */
3164		spin_lock_bh(&conn->psq_lock);
3165		if (!skb_queue_empty(&conn->psq) || (conn->mgmt_psq_len != 0))
3166			*more_data = true;
3167		spin_unlock_bh(&conn->psq_lock);
3168	}
3169
3170	return false;
3171}
3172
3173/* Check if SSID length is greater than DIRECT- */
3174static bool ath6kl_is_p2p_go_ssid(const u8 *buf, size_t len)
3175{
3176	const struct ieee80211_mgmt *mgmt;
3177	mgmt = (const struct ieee80211_mgmt *) buf;
3178
3179	/* variable[1] contains the SSID tag length */
3180	if (buf + len >= &mgmt->u.probe_resp.variable[1] &&
3181	    (mgmt->u.probe_resp.variable[1] > P2P_WILDCARD_SSID_LEN)) {
3182		return true;
3183	}
3184
3185	return false;
3186}
3187
3188static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
3189			  struct cfg80211_mgmt_tx_params *params, u64 *cookie)
3190{
3191	struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev);
3192	struct ath6kl *ar = ath6kl_priv(vif->ndev);
3193	struct ieee80211_channel *chan = params->chan;
3194	const u8 *buf = params->buf;
3195	size_t len = params->len;
3196	unsigned int wait = params->wait;
3197	bool no_cck = params->no_cck;
3198	u32 id, freq;
3199	const struct ieee80211_mgmt *mgmt;
3200	bool more_data, queued;
3201
3202	/* default to the current channel, but use the one specified as argument
3203	 * if any
3204	 */
3205	freq = vif->ch_hint;
3206	if (chan)
3207		freq = chan->center_freq;
3208
3209	/* never send freq zero to the firmware */
3210	if (WARN_ON(freq == 0))
3211		return -EINVAL;
3212
3213	mgmt = (const struct ieee80211_mgmt *) buf;
3214	if (vif->nw_type == AP_NETWORK && test_bit(CONNECTED, &vif->flags) &&
3215	    ieee80211_is_probe_resp(mgmt->frame_control) &&
3216	    ath6kl_is_p2p_go_ssid(buf, len)) {
3217		/*
3218		 * Send Probe Response frame in GO mode using a separate WMI
3219		 * command to allow the target to fill in the generic IEs.
3220		 */
3221		*cookie = 0; /* TX status not supported */
3222		return ath6kl_send_go_probe_resp(vif, buf, len, freq);
3223	}
3224
3225	id = vif->send_action_id++;
3226	if (id == 0) {
3227		/*
3228		 * 0 is a reserved value in the WMI command and shall not be
3229		 * used for the command.
3230		 */
3231		id = vif->send_action_id++;
3232	}
3233
3234	*cookie = id;
3235
3236	/* AP mode Power saving processing */
3237	if (vif->nw_type == AP_NETWORK) {
3238		queued = ath6kl_mgmt_powersave_ap(vif, id, freq, wait, buf, len,
3239						  &more_data, no_cck);
3240		if (queued)
3241			return 0;
3242	}
3243
3244	return ath6kl_wmi_send_mgmt_cmd(ar->wmi, vif->fw_vif_idx, id, freq,
3245					wait, buf, len, no_cck);
3246}
3247
3248static int ath6kl_get_antenna(struct wiphy *wiphy, int radio_idx,
3249			      u32 *tx_ant, u32 *rx_ant)
3250{
3251	struct ath6kl *ar = wiphy_priv(wiphy);
3252	*tx_ant = ar->hw.tx_ant;
3253	*rx_ant = ar->hw.rx_ant;
3254	return 0;
3255}
3256
3257static void ath6kl_update_mgmt_frame_registrations(struct wiphy *wiphy,
3258						   struct wireless_dev *wdev,
3259						   struct mgmt_frame_regs *upd)
3260{
3261	struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev);
3262
3263	/*
3264	 * FIXME: send WMI_PROBE_REQ_REPORT_CMD here instead of hardcoding
3265	 *	  the reporting in the target all the time, this callback
3266	 *	  *is* allowed to sleep after all.
3267	 */
3268	vif->probe_req_report =
3269		upd->interface_stypes & BIT(IEEE80211_STYPE_PROBE_REQ >> 4);
3270}
3271
3272static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy,
3273			struct net_device *dev,
3274			struct cfg80211_sched_scan_request *request)
3275{
3276	struct ath6kl *ar = ath6kl_priv(dev);
3277	struct ath6kl_vif *vif = netdev_priv(dev);
3278	u16 interval;
3279	int ret, rssi_thold;
3280	int n_match_sets = request->n_match_sets;
3281
3282	/*
3283	 * If there's a matchset w/o an SSID, then assume it's just for
3284	 * the RSSI (nothing else is currently supported) and ignore it.
3285	 * The device only supports a global RSSI filter that we set below.
3286	 */
3287	if (n_match_sets == 1 && !request->match_sets[0].ssid.ssid_len)
3288		n_match_sets = 0;
3289
3290	if (ar->state != ATH6KL_STATE_ON)
3291		return -EIO;
3292
3293	if (vif->sme_state != SME_DISCONNECTED)
3294		return -EBUSY;
3295
3296	ath6kl_cfg80211_scan_complete_event(vif, true);
3297
3298	ret = ath6kl_set_probed_ssids(ar, vif, request->ssids,
3299				      request->n_ssids,
3300				      request->match_sets,
3301				      n_match_sets);
3302	if (ret < 0)
3303		return ret;
3304
3305	if (!n_match_sets) {
3306		ret = ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
3307					       ALL_BSS_FILTER, 0);
3308		if (ret < 0)
3309			return ret;
3310	} else {
3311		ret = ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
3312					       MATCHED_SSID_FILTER, 0);
3313		if (ret < 0)
3314			return ret;
3315	}
3316
3317	if (test_bit(ATH6KL_FW_CAPABILITY_RSSI_SCAN_THOLD,
3318		     ar->fw_capabilities)) {
3319		if (request->min_rssi_thold <= NL80211_SCAN_RSSI_THOLD_OFF)
3320			rssi_thold = 0;
3321		else if (request->min_rssi_thold < -127)
3322			rssi_thold = -127;
3323		else
3324			rssi_thold = request->min_rssi_thold;
3325
3326		ret = ath6kl_wmi_set_rssi_filter_cmd(ar->wmi, vif->fw_vif_idx,
3327						     rssi_thold);
3328		if (ret) {
3329			ath6kl_err("failed to set RSSI threshold for scan\n");
3330			return ret;
3331		}
3332	}
3333
3334	/* fw uses seconds, also make sure that it's >0 */
3335	interval = max_t(u16, 1, request->scan_plans[0].interval);
3336
3337	ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx,
3338				  interval, interval,
3339				  vif->bg_scan_period, 0, 0, 0, 3, 0, 0, 0);
3340
3341	/* this also clears IE in fw if it's not set */
3342	ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
3343				       WMI_FRAME_PROBE_REQ,
3344				       request->ie, request->ie_len);
3345	if (ret) {
3346		ath6kl_warn("Failed to set probe request IE for scheduled scan: %d\n",
3347			    ret);
3348		return ret;
3349	}
3350
3351	ret = ath6kl_wmi_enable_sched_scan_cmd(ar->wmi, vif->fw_vif_idx, true);
3352	if (ret)
3353		return ret;
3354
3355	set_bit(SCHED_SCANNING, &vif->flags);
3356
3357	return 0;
3358}
3359
3360static int ath6kl_cfg80211_sscan_stop(struct wiphy *wiphy,
3361				      struct net_device *dev, u64 reqid)
3362{
3363	struct ath6kl_vif *vif = netdev_priv(dev);
3364	bool stopped;
3365
3366	stopped = __ath6kl_cfg80211_sscan_stop(vif);
3367
3368	if (!stopped)
3369		return -EIO;
3370
3371	return 0;
3372}
3373
3374static int ath6kl_cfg80211_set_bitrate(struct wiphy *wiphy,
3375				       struct net_device *dev,
3376				       unsigned int link_id,
3377				       const u8 *addr,
3378				       const struct cfg80211_bitrate_mask *mask)
3379{
3380	struct ath6kl *ar = ath6kl_priv(dev);
3381	struct ath6kl_vif *vif = netdev_priv(dev);
3382
3383	return ath6kl_wmi_set_bitrate_mask(ar->wmi, vif->fw_vif_idx,
3384					   mask);
3385}
3386
3387static int ath6kl_cfg80211_set_txe_config(struct wiphy *wiphy,
3388					  struct net_device *dev,
3389					  u32 rate, u32 pkts, u32 intvl)
3390{
3391	struct ath6kl *ar = ath6kl_priv(dev);
3392	struct ath6kl_vif *vif = netdev_priv(dev);
3393
3394	if (vif->nw_type != INFRA_NETWORK ||
3395	    !test_bit(ATH6KL_FW_CAPABILITY_TX_ERR_NOTIFY, ar->fw_capabilities))
3396		return -EOPNOTSUPP;
3397
3398	if (vif->sme_state != SME_CONNECTED)
3399		return -ENOTCONN;
3400
3401	/* save this since the firmware won't report the interval */
3402	vif->txe_intvl = intvl;
3403
3404	return ath6kl_wmi_set_txe_notify(ar->wmi, vif->fw_vif_idx,
3405					 rate, pkts, intvl);
3406}
3407
3408static const struct ieee80211_txrx_stypes
3409ath6kl_mgmt_stypes[NUM_NL80211_IFTYPES] = {
3410	[NL80211_IFTYPE_STATION] = {
3411		.tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3412		BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
3413		.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3414		BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
3415	},
3416	[NL80211_IFTYPE_AP] = {
3417		.tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3418		BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
3419		.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3420		BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
3421	},
3422	[NL80211_IFTYPE_P2P_CLIENT] = {
3423		.tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3424		BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
3425		.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3426		BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
3427	},
3428	[NL80211_IFTYPE_P2P_GO] = {
3429		.tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3430		BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
3431		.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3432		BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
3433	},
3434};
3435
3436static struct cfg80211_ops ath6kl_cfg80211_ops = {
3437	.add_virtual_intf = ath6kl_cfg80211_add_iface,
3438	.del_virtual_intf = ath6kl_cfg80211_del_iface,
3439	.change_virtual_intf = ath6kl_cfg80211_change_iface,
3440	.scan = ath6kl_cfg80211_scan,
3441	.connect = ath6kl_cfg80211_connect,
3442	.disconnect = ath6kl_cfg80211_disconnect,
3443	.add_key = ath6kl_cfg80211_add_key,
3444	.get_key = ath6kl_cfg80211_get_key,
3445	.del_key = ath6kl_cfg80211_del_key,
3446	.set_default_key = ath6kl_cfg80211_set_default_key,
3447	.set_wiphy_params = ath6kl_cfg80211_set_wiphy_params,
3448	.set_tx_power = ath6kl_cfg80211_set_txpower,
3449	.get_tx_power = ath6kl_cfg80211_get_txpower,
3450	.set_power_mgmt = ath6kl_cfg80211_set_power_mgmt,
3451	.join_ibss = ath6kl_cfg80211_join_ibss,
3452	.leave_ibss = ath6kl_cfg80211_leave_ibss,
3453	.get_station = ath6kl_get_station,
3454	.set_pmksa = ath6kl_set_pmksa,
3455	.del_pmksa = ath6kl_del_pmksa,
3456	.flush_pmksa = ath6kl_flush_pmksa,
3457	CFG80211_TESTMODE_CMD(ath6kl_tm_cmd)
3458#ifdef CONFIG_PM
3459	.suspend = __ath6kl_cfg80211_suspend,
3460	.resume = __ath6kl_cfg80211_resume,
3461#endif
3462	.start_ap = ath6kl_start_ap,
3463	.change_beacon = ath6kl_change_beacon,
3464	.stop_ap = ath6kl_stop_ap,
3465	.del_station = ath6kl_del_station,
3466	.change_station = ath6kl_change_station,
3467	.remain_on_channel = ath6kl_remain_on_channel,
3468	.cancel_remain_on_channel = ath6kl_cancel_remain_on_channel,
3469	.mgmt_tx = ath6kl_mgmt_tx,
3470	.update_mgmt_frame_registrations =
3471		ath6kl_update_mgmt_frame_registrations,
3472	.get_antenna = ath6kl_get_antenna,
3473	.sched_scan_start = ath6kl_cfg80211_sscan_start,
3474	.sched_scan_stop = ath6kl_cfg80211_sscan_stop,
3475	.set_bitrate_mask = ath6kl_cfg80211_set_bitrate,
3476	.set_cqm_txe_config = ath6kl_cfg80211_set_txe_config,
3477};
3478
3479void ath6kl_cfg80211_stop(struct ath6kl_vif *vif)
3480{
3481	ath6kl_cfg80211_sscan_disable(vif);
3482
3483	switch (vif->sme_state) {
3484	case SME_DISCONNECTED:
3485		break;
3486	case SME_CONNECTING:
3487		cfg80211_connect_result(vif->ndev, vif->bssid, NULL, 0,
3488					NULL, 0,
3489					WLAN_STATUS_UNSPECIFIED_FAILURE,
3490					GFP_KERNEL);
3491		break;
3492	case SME_CONNECTED:
3493		cfg80211_disconnected(vif->ndev, 0, NULL, 0, true, GFP_KERNEL);
3494		break;
3495	}
3496
3497	if (vif->ar->state != ATH6KL_STATE_RECOVERY &&
3498	    (test_bit(CONNECTED, &vif->flags) ||
3499	    test_bit(CONNECT_PEND, &vif->flags)))
3500		ath6kl_wmi_disconnect_cmd(vif->ar->wmi, vif->fw_vif_idx);
3501
3502	vif->sme_state = SME_DISCONNECTED;
3503	clear_bit(CONNECTED, &vif->flags);
3504	clear_bit(CONNECT_PEND, &vif->flags);
3505
3506	/* Stop netdev queues, needed during recovery */
3507	netif_stop_queue(vif->ndev);
3508	netif_carrier_off(vif->ndev);
3509
3510	/* disable scanning */
3511	if (vif->ar->state != ATH6KL_STATE_RECOVERY &&
3512	    ath6kl_wmi_scanparams_cmd(vif->ar->wmi, vif->fw_vif_idx, 0xFFFF,
3513				      0, 0, 0, 0, 0, 0, 0, 0, 0) != 0)
3514		ath6kl_warn("failed to disable scan during stop\n");
3515
3516	ath6kl_cfg80211_scan_complete_event(vif, true);
3517}
3518
3519void ath6kl_cfg80211_stop_all(struct ath6kl *ar)
3520{
3521	struct ath6kl_vif *vif;
3522
3523	vif = ath6kl_vif_first(ar);
3524	if (!vif && ar->state != ATH6KL_STATE_RECOVERY) {
3525		/* save the current power mode before enabling power save */
3526		ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode;
3527
3528		if (ath6kl_wmi_powermode_cmd(ar->wmi, 0, REC_POWER) != 0)
3529			ath6kl_warn("ath6kl_deep_sleep_enable: wmi_powermode_cmd failed\n");
3530		return;
3531	}
3532
3533	/*
3534	 * FIXME: we should take ar->list_lock to protect changes in the
3535	 * vif_list, but that's not trivial to do as ath6kl_cfg80211_stop()
3536	 * sleeps.
3537	 */
3538	list_for_each_entry(vif, &ar->vif_list, list)
3539		ath6kl_cfg80211_stop(vif);
3540}
3541
3542static void ath6kl_cfg80211_reg_notify(struct wiphy *wiphy,
3543				       struct regulatory_request *request)
3544{
3545	struct ath6kl *ar = wiphy_priv(wiphy);
3546	u32 rates[NUM_NL80211_BANDS];
3547	int ret, i;
3548
3549	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
3550		   "cfg reg_notify %c%c%s%s initiator %d hint_type %d\n",
3551		   request->alpha2[0], request->alpha2[1],
3552		   request->intersect ? " intersect" : "",
3553		   request->processed ? " processed" : "",
3554		   request->initiator, request->user_reg_hint_type);
3555
3556	if (request->user_reg_hint_type != NL80211_USER_REG_HINT_CELL_BASE)
3557		return;
3558
3559	ret = ath6kl_wmi_set_regdomain_cmd(ar->wmi, request->alpha2);
3560	if (ret) {
3561		ath6kl_err("failed to set regdomain: %d\n", ret);
3562		return;
3563	}
3564
3565	/*
3566	 * Firmware will apply the regdomain change only after a scan is
3567	 * issued and it will send a WMI_REGDOMAIN_EVENTID when it has been
3568	 * changed.
3569	 */
3570
3571	for (i = 0; i < NUM_NL80211_BANDS; i++)
3572		if (wiphy->bands[i])
3573			rates[i] = (1 << wiphy->bands[i]->n_bitrates) - 1;
3574
3575
3576	ret = ath6kl_wmi_beginscan_cmd(ar->wmi, 0, WMI_LONG_SCAN, false,
3577				       false, 0, ATH6KL_FG_SCAN_INTERVAL,
3578				       0, NULL, false, rates);
3579	if (ret) {
3580		ath6kl_err("failed to start scan for a regdomain change: %d\n",
3581			   ret);
3582		return;
3583	}
3584}
3585
3586static int ath6kl_cfg80211_vif_init(struct ath6kl_vif *vif)
3587{
3588	vif->aggr_cntxt = aggr_init(vif);
3589	if (!vif->aggr_cntxt) {
3590		ath6kl_err("failed to initialize aggr\n");
3591		return -ENOMEM;
3592	}
3593
3594	timer_setup(&vif->disconnect_timer, disconnect_timer_handler, 0);
3595	timer_setup(&vif->sched_scan_timer, ath6kl_wmi_sscan_timer, 0);
3596
3597	set_bit(WMM_ENABLED, &vif->flags);
3598	spin_lock_init(&vif->if_lock);
3599
3600	INIT_LIST_HEAD(&vif->mc_filter);
3601
3602	return 0;
3603}
3604
3605void ath6kl_cfg80211_vif_stop(struct ath6kl_vif *vif, bool wmi_ready)
3606{
3607	static u8 bcast_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
3608	bool discon_issued;
3609
3610	netif_stop_queue(vif->ndev);
3611
3612	clear_bit(WLAN_ENABLED, &vif->flags);
3613
3614	if (wmi_ready) {
3615		discon_issued = test_bit(CONNECTED, &vif->flags) ||
3616				test_bit(CONNECT_PEND, &vif->flags);
3617		ath6kl_disconnect(vif);
3618		timer_delete(&vif->disconnect_timer);
3619
3620		if (discon_issued)
3621			ath6kl_disconnect_event(vif, DISCONNECT_CMD,
3622						(vif->nw_type & AP_NETWORK) ?
3623						bcast_mac : vif->bssid,
3624						0, NULL, 0);
3625	}
3626
3627	if (vif->scan_req) {
3628		struct cfg80211_scan_info info = {
3629			.aborted = true,
3630		};
3631
3632		cfg80211_scan_done(vif->scan_req, &info);
3633		vif->scan_req = NULL;
3634	}
3635
3636	/* need to clean up enhanced bmiss detection fw state */
3637	ath6kl_cfg80211_sta_bmiss_enhance(vif, false);
3638}
3639
3640void ath6kl_cfg80211_vif_cleanup(struct ath6kl_vif *vif)
3641{
3642	struct ath6kl *ar = vif->ar;
3643	struct ath6kl_mc_filter *mc_filter, *tmp;
3644
3645	aggr_module_destroy(vif->aggr_cntxt);
3646
3647	ar->avail_idx_map |= BIT(vif->fw_vif_idx);
3648
3649	if (vif->nw_type == ADHOC_NETWORK)
3650		ar->ibss_if_active = false;
3651
3652	list_for_each_entry_safe(mc_filter, tmp, &vif->mc_filter, list) {
3653		list_del(&mc_filter->list);
3654		kfree(mc_filter);
3655	}
3656
3657	cfg80211_unregister_netdevice(vif->ndev);
3658
3659	ar->num_vif--;
3660}
3661
3662static const char ath6kl_gstrings_sta_stats[][ETH_GSTRING_LEN] = {
3663	/* Common stats names used by many drivers. */
3664	"tx_pkts_nic", "tx_bytes_nic", "rx_pkts_nic", "rx_bytes_nic",
3665
3666	/* TX stats. */
3667	"d_tx_ucast_pkts", "d_tx_bcast_pkts",
3668	"d_tx_ucast_bytes", "d_tx_bcast_bytes",
3669	"d_tx_rts_ok", "d_tx_error", "d_tx_fail",
3670	"d_tx_retry", "d_tx_multi_retry", "d_tx_rts_fail",
3671	"d_tx_tkip_counter_measures",
3672
3673	/* RX Stats. */
3674	"d_rx_ucast_pkts", "d_rx_ucast_rate", "d_rx_bcast_pkts",
3675	"d_rx_ucast_bytes", "d_rx_bcast_bytes", "d_rx_frag_pkt",
3676	"d_rx_error", "d_rx_crc_err", "d_rx_keycache_miss",
3677	"d_rx_decrypt_crc_err", "d_rx_duplicate_frames",
3678	"d_rx_mic_err", "d_rx_tkip_format_err", "d_rx_ccmp_format_err",
3679	"d_rx_ccmp_replay_err",
3680
3681	/* Misc stats. */
3682	"d_beacon_miss", "d_num_connects", "d_num_disconnects",
3683	"d_beacon_avg_rssi", "d_arp_received", "d_arp_matched",
3684	"d_arp_replied"
3685};
3686
3687#define ATH6KL_STATS_LEN	ARRAY_SIZE(ath6kl_gstrings_sta_stats)
3688
3689static int ath6kl_get_sset_count(struct net_device *dev, int sset)
3690{
3691	int rv = 0;
3692
3693	if (sset == ETH_SS_STATS)
3694		rv += ATH6KL_STATS_LEN;
3695
3696	if (rv == 0)
3697		return -EOPNOTSUPP;
3698	return rv;
3699}
3700
3701static void ath6kl_get_stats(struct net_device *dev,
3702			    struct ethtool_stats *stats,
3703			    u64 *data)
3704{
3705	struct ath6kl_vif *vif = netdev_priv(dev);
3706	struct ath6kl *ar = vif->ar;
3707	int i = 0;
3708	struct target_stats *tgt_stats;
3709
3710	memset(data, 0, sizeof(u64) * ATH6KL_STATS_LEN);
3711
3712	ath6kl_read_tgt_stats(ar, vif);
3713
3714	tgt_stats = &vif->target_stats;
3715
3716	data[i++] = tgt_stats->tx_ucast_pkt + tgt_stats->tx_bcast_pkt;
3717	data[i++] = tgt_stats->tx_ucast_byte + tgt_stats->tx_bcast_byte;
3718	data[i++] = tgt_stats->rx_ucast_pkt + tgt_stats->rx_bcast_pkt;
3719	data[i++] = tgt_stats->rx_ucast_byte + tgt_stats->rx_bcast_byte;
3720
3721	data[i++] = tgt_stats->tx_ucast_pkt;
3722	data[i++] = tgt_stats->tx_bcast_pkt;
3723	data[i++] = tgt_stats->tx_ucast_byte;
3724	data[i++] = tgt_stats->tx_bcast_byte;
3725	data[i++] = tgt_stats->tx_rts_success_cnt;
3726	data[i++] = tgt_stats->tx_err;
3727	data[i++] = tgt_stats->tx_fail_cnt;
3728	data[i++] = tgt_stats->tx_retry_cnt;
3729	data[i++] = tgt_stats->tx_mult_retry_cnt;
3730	data[i++] = tgt_stats->tx_rts_fail_cnt;
3731	data[i++] = tgt_stats->tkip_cnter_measures_invoked;
3732
3733	data[i++] = tgt_stats->rx_ucast_pkt;
3734	data[i++] = tgt_stats->rx_ucast_rate;
3735	data[i++] = tgt_stats->rx_bcast_pkt;
3736	data[i++] = tgt_stats->rx_ucast_byte;
3737	data[i++] = tgt_stats->rx_bcast_byte;
3738	data[i++] = tgt_stats->rx_frgment_pkt;
3739	data[i++] = tgt_stats->rx_err;
3740	data[i++] = tgt_stats->rx_crc_err;
3741	data[i++] = tgt_stats->rx_key_cache_miss;
3742	data[i++] = tgt_stats->rx_decrypt_err;
3743	data[i++] = tgt_stats->rx_dupl_frame;
3744	data[i++] = tgt_stats->tkip_local_mic_fail;
3745	data[i++] = tgt_stats->tkip_fmt_err;
3746	data[i++] = tgt_stats->ccmp_fmt_err;
3747	data[i++] = tgt_stats->ccmp_replays;
3748
3749	data[i++] = tgt_stats->cs_bmiss_cnt;
3750	data[i++] = tgt_stats->cs_connect_cnt;
3751	data[i++] = tgt_stats->cs_discon_cnt;
3752	data[i++] = tgt_stats->cs_ave_beacon_rssi;
3753	data[i++] = tgt_stats->arp_received;
3754	data[i++] = tgt_stats->arp_matched;
3755	data[i++] = tgt_stats->arp_replied;
3756
3757	if (i !=  ATH6KL_STATS_LEN) {
3758		WARN_ON_ONCE(1);
3759		ath6kl_err("ethtool stats error, i: %d  STATS_LEN: %d\n",
3760			   i, (int)ATH6KL_STATS_LEN);
3761	}
3762}
3763
3764/* These stats are per NIC, not really per vdev, so we just ignore dev. */
3765static void ath6kl_get_strings(struct net_device *dev, u32 sset, u8 *data)
3766{
3767	int sz_sta_stats = 0;
3768
3769	if (sset == ETH_SS_STATS) {
3770		sz_sta_stats = sizeof(ath6kl_gstrings_sta_stats);
3771		memcpy(data, ath6kl_gstrings_sta_stats, sz_sta_stats);
3772	}
3773}
3774
3775static const struct ethtool_ops ath6kl_ethtool_ops = {
3776	.get_drvinfo = cfg80211_get_drvinfo,
3777	.get_link = ethtool_op_get_link,
3778	.get_strings = ath6kl_get_strings,
3779	.get_ethtool_stats = ath6kl_get_stats,
3780	.get_sset_count = ath6kl_get_sset_count,
3781};
3782
3783struct wireless_dev *ath6kl_interface_add(struct ath6kl *ar, const char *name,
3784					  unsigned char name_assign_type,
3785					  enum nl80211_iftype type,
3786					  u8 fw_vif_idx, u8 nw_type)
3787{
3788	struct net_device *ndev;
3789	struct ath6kl_vif *vif;
3790	u8 addr[ETH_ALEN];
3791
3792	ndev = alloc_netdev(sizeof(*vif), name, name_assign_type, ether_setup);
3793	if (!ndev)
3794		return NULL;
3795
3796	vif = netdev_priv(ndev);
3797	ndev->ieee80211_ptr = &vif->wdev;
3798	vif->wdev.wiphy = ar->wiphy;
3799	vif->ar = ar;
3800	vif->ndev = ndev;
3801	SET_NETDEV_DEV(ndev, wiphy_dev(vif->wdev.wiphy));
3802	vif->wdev.netdev = ndev;
3803	vif->wdev.iftype = type;
3804	vif->fw_vif_idx = fw_vif_idx;
3805	vif->nw_type = nw_type;
3806	vif->next_mode = nw_type;
3807	vif->listen_intvl_t = ATH6KL_DEFAULT_LISTEN_INTVAL;
3808	vif->bmiss_time_t = ATH6KL_DEFAULT_BMISS_TIME;
3809	vif->bg_scan_period = 0;
3810	vif->htcap[NL80211_BAND_2GHZ].ht_enable = true;
3811	vif->htcap[NL80211_BAND_5GHZ].ht_enable = true;
3812
3813	ether_addr_copy(addr, ar->mac_addr);
3814	if (fw_vif_idx != 0) {
3815		addr[0] = (addr[0] ^ (1 << fw_vif_idx)) | 0x2;
3816		if (test_bit(ATH6KL_FW_CAPABILITY_CUSTOM_MAC_ADDR,
3817			     ar->fw_capabilities))
3818			addr[4] ^= 0x80;
3819	}
3820	eth_hw_addr_set(ndev, addr);
3821
3822	init_netdev(ndev);
3823
3824	ath6kl_init_control_info(vif);
3825
3826	if (ath6kl_cfg80211_vif_init(vif))
3827		goto err;
3828
3829	netdev_set_default_ethtool_ops(ndev, &ath6kl_ethtool_ops);
3830
3831	if (cfg80211_register_netdevice(ndev))
3832		goto err;
3833
3834	ar->avail_idx_map &= ~BIT(fw_vif_idx);
3835	vif->sme_state = SME_DISCONNECTED;
3836	set_bit(WLAN_ENABLED, &vif->flags);
3837	ar->wlan_pwr_state = WLAN_POWER_STATE_ON;
3838
3839	if (type == NL80211_IFTYPE_ADHOC)
3840		ar->ibss_if_active = true;
3841
3842	spin_lock_bh(&ar->list_lock);
3843	list_add_tail(&vif->list, &ar->vif_list);
3844	spin_unlock_bh(&ar->list_lock);
3845
3846	return &vif->wdev;
3847
3848err:
3849	aggr_module_destroy(vif->aggr_cntxt);
3850	free_netdev(ndev);
3851	return NULL;
3852}
3853
3854#ifdef CONFIG_PM
3855static const struct wiphy_wowlan_support ath6kl_wowlan_support = {
3856	.flags = WIPHY_WOWLAN_MAGIC_PKT |
3857		 WIPHY_WOWLAN_DISCONNECT |
3858		 WIPHY_WOWLAN_GTK_REKEY_FAILURE  |
3859		 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
3860		 WIPHY_WOWLAN_EAP_IDENTITY_REQ   |
3861		 WIPHY_WOWLAN_4WAY_HANDSHAKE,
3862	.n_patterns = WOW_MAX_FILTERS_PER_LIST,
3863	.pattern_min_len = 1,
3864	.pattern_max_len = WOW_PATTERN_SIZE,
3865};
3866#endif
3867
3868int ath6kl_cfg80211_init(struct ath6kl *ar)
3869{
3870	struct wiphy *wiphy = ar->wiphy;
3871	bool band_2gig = false, band_5gig = false, ht = false;
3872	int ret;
3873
3874	wiphy->mgmt_stypes = ath6kl_mgmt_stypes;
3875
3876	wiphy->max_remain_on_channel_duration = 5000;
3877
3878	/* set device pointer for wiphy */
3879	set_wiphy_dev(wiphy, ar->dev);
3880
3881	wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
3882				 BIT(NL80211_IFTYPE_ADHOC) |
3883				 BIT(NL80211_IFTYPE_AP);
3884	if (ar->p2p) {
3885		wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_GO) |
3886					  BIT(NL80211_IFTYPE_P2P_CLIENT);
3887	}
3888
3889	if (IS_ENABLED(CONFIG_ATH6KL_REGDOMAIN) &&
3890	    test_bit(ATH6KL_FW_CAPABILITY_REGDOMAIN, ar->fw_capabilities)) {
3891		wiphy->reg_notifier = ath6kl_cfg80211_reg_notify;
3892		ar->wiphy->features |= NL80211_FEATURE_CELL_BASE_REG_HINTS;
3893	}
3894
3895	/* max num of ssids that can be probed during scanning */
3896	wiphy->max_scan_ssids = MAX_PROBED_SSIDS;
3897
3898	/* max num of ssids that can be matched after scan */
3899	if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN_MATCH_LIST,
3900		     ar->fw_capabilities))
3901		wiphy->max_match_sets = MAX_PROBED_SSIDS;
3902
3903	wiphy->max_scan_ie_len = 1000; /* FIX: what is correct limit? */
3904	switch (ar->hw.cap) {
3905	case WMI_11AN_CAP:
3906		ht = true;
3907		fallthrough;
3908	case WMI_11A_CAP:
3909		band_5gig = true;
3910		break;
3911	case WMI_11GN_CAP:
3912		ht = true;
3913		fallthrough;
3914	case WMI_11G_CAP:
3915		band_2gig = true;
3916		break;
3917	case WMI_11AGN_CAP:
3918		ht = true;
3919		fallthrough;
3920	case WMI_11AG_CAP:
3921		band_2gig = true;
3922		band_5gig = true;
3923		break;
3924	default:
3925		ath6kl_err("invalid phy capability!\n");
3926		return -EINVAL;
3927	}
3928
3929	/*
3930	 * Even if the fw has HT support, advertise HT cap only when
3931	 * the firmware has support to override RSN capability, otherwise
3932	 * 4-way handshake would fail.
3933	 */
3934	if (!(ht &&
3935	      test_bit(ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE,
3936		       ar->fw_capabilities))) {
3937		ath6kl_band_2ghz.ht_cap.cap = 0;
3938		ath6kl_band_2ghz.ht_cap.ht_supported = false;
3939		ath6kl_band_5ghz.ht_cap.cap = 0;
3940		ath6kl_band_5ghz.ht_cap.ht_supported = false;
3941
3942		if (ht)
3943			ath6kl_err("Firmware lacks RSN-CAP-OVERRIDE, so HT (802.11n) is disabled.");
3944	}
3945
3946	if (test_bit(ATH6KL_FW_CAPABILITY_64BIT_RATES,
3947		     ar->fw_capabilities)) {
3948		ath6kl_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3949		ath6kl_band_5ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3950		ath6kl_band_2ghz.ht_cap.mcs.rx_mask[1] = 0xff;
3951		ath6kl_band_5ghz.ht_cap.mcs.rx_mask[1] = 0xff;
3952		ar->hw.tx_ant = 0x3; /* mask, 2 antenna */
3953		ar->hw.rx_ant = 0x3;
3954	} else {
3955		ath6kl_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3956		ath6kl_band_5ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3957		ar->hw.tx_ant = 1;
3958		ar->hw.rx_ant = 1;
3959	}
3960
3961	wiphy->available_antennas_tx = ar->hw.tx_ant;
3962	wiphy->available_antennas_rx = ar->hw.rx_ant;
3963
3964	if (band_2gig)
3965		wiphy->bands[NL80211_BAND_2GHZ] = &ath6kl_band_2ghz;
3966	if (band_5gig)
3967		wiphy->bands[NL80211_BAND_5GHZ] = &ath6kl_band_5ghz;
3968
3969	wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
3970
3971	wiphy->cipher_suites = cipher_suites;
3972	wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
3973
3974#ifdef CONFIG_PM
3975	wiphy->wowlan = &ath6kl_wowlan_support;
3976#endif
3977
3978	wiphy->max_sched_scan_ssids = MAX_PROBED_SSIDS;
3979
3980	ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM |
3981			    WIPHY_FLAG_HAVE_AP_SME |
3982			    WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
3983			    WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
3984
3985	if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN_V2, ar->fw_capabilities))
3986		ar->wiphy->max_sched_scan_reqs = 1;
3987
3988	if (test_bit(ATH6KL_FW_CAPABILITY_INACTIVITY_TIMEOUT,
3989		     ar->fw_capabilities))
3990		ar->wiphy->features |= NL80211_FEATURE_INACTIVITY_TIMER;
3991
3992	ar->wiphy->probe_resp_offload =
3993		NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
3994		NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
3995		NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P;
3996
3997	ret = wiphy_register(wiphy);
3998	if (ret < 0) {
3999		ath6kl_err("couldn't register wiphy device\n");
4000		return ret;
4001	}
4002
4003	ar->wiphy_registered = true;
4004
4005	return 0;
4006}
4007
4008void ath6kl_cfg80211_cleanup(struct ath6kl *ar)
4009{
4010	wiphy_unregister(ar->wiphy);
4011
4012	ar->wiphy_registered = false;
4013}
4014
4015struct ath6kl *ath6kl_cfg80211_create(void)
4016{
4017	struct ath6kl *ar;
4018	struct wiphy *wiphy;
4019
4020	/* create a new wiphy for use with cfg80211 */
4021	wiphy = wiphy_new(&ath6kl_cfg80211_ops, sizeof(struct ath6kl));
4022
4023	if (!wiphy) {
4024		ath6kl_err("couldn't allocate wiphy device\n");
4025		return NULL;
4026	}
4027
4028	ar = wiphy_priv(wiphy);
4029	ar->wiphy = wiphy;
4030
4031	return ar;
4032}
4033
4034/* Note: ar variable must not be accessed after calling this! */
4035void ath6kl_cfg80211_destroy(struct ath6kl *ar)
4036{
4037	int i;
4038
4039	for (i = 0; i < AP_MAX_NUM_STA; i++)
4040		kfree(ar->sta_list[i].aggr_conn);
4041
4042	wiphy_free(ar->wiphy);
4043}
4044
~/ Read-only file preview.