File Index
Files and directories
Sign in
FILE

d3.c

File preview with syntax highlighting.

linux-6.19.14/drivers/net/wireless/intel/iwlwifi/mvm/d3.c C
   1// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
   2/*
   3 * Copyright (C) 2012-2014, 2018-2026 Intel Corporation
   4 * Copyright (C) 2013-2015 Intel Mobile Communications GmbH
   5 * Copyright (C) 2016-2017 Intel Deutschland GmbH
   6 */
   7#include <linux/etherdevice.h>
   8#include <linux/ip.h>
   9#include <linux/fs.h>
  10#include <net/cfg80211.h>
  11#include <net/ipv6.h>
  12#include <net/tcp.h>
  13#include <net/addrconf.h>
  14#include "iwl-modparams.h"
  15#include "fw-api.h"
  16#include "mvm.h"
  17#include "fw/img.h"
  18
  19void iwl_mvm_set_rekey_data(struct ieee80211_hw *hw,
  20			    struct ieee80211_vif *vif,
  21			    struct cfg80211_gtk_rekey_data *data)
  22{
  23	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
  24	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
  25
  26	mutex_lock(&mvm->mutex);
  27
  28	mvmvif->rekey_data.kek_len = data->kek_len;
  29	mvmvif->rekey_data.kck_len = data->kck_len;
  30	memcpy(mvmvif->rekey_data.kek, data->kek, data->kek_len);
  31	memcpy(mvmvif->rekey_data.kck, data->kck, data->kck_len);
  32	mvmvif->rekey_data.akm = data->akm & 0xFF;
  33	mvmvif->rekey_data.replay_ctr =
  34		cpu_to_le64(be64_to_cpup((const __be64 *)data->replay_ctr));
  35	mvmvif->rekey_data.valid = true;
  36
  37	mutex_unlock(&mvm->mutex);
  38}
  39
  40#if IS_ENABLED(CONFIG_IPV6)
  41void iwl_mvm_ipv6_addr_change(struct ieee80211_hw *hw,
  42			      struct ieee80211_vif *vif,
  43			      struct inet6_dev *idev)
  44{
  45	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
  46	struct inet6_ifaddr *ifa;
  47	int idx = 0;
  48
  49	memset(mvmvif->tentative_addrs, 0, sizeof(mvmvif->tentative_addrs));
  50
  51	read_lock_bh(&idev->lock);
  52	list_for_each_entry(ifa, &idev->addr_list, if_list) {
  53		mvmvif->target_ipv6_addrs[idx] = ifa->addr;
  54		if (ifa->flags & IFA_F_TENTATIVE)
  55			__set_bit(idx, mvmvif->tentative_addrs);
  56		idx++;
  57		if (idx >= IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_MAX)
  58			break;
  59	}
  60	read_unlock_bh(&idev->lock);
  61
  62	mvmvif->num_target_ipv6_addrs = idx;
  63}
  64#endif
  65
  66void iwl_mvm_set_default_unicast_key(struct ieee80211_hw *hw,
  67				     struct ieee80211_vif *vif, int idx)
  68{
  69	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
  70
  71	mvmvif->tx_key_idx = idx;
  72}
  73
  74static void iwl_mvm_convert_p1k(u16 *p1k, __le16 *out)
  75{
  76	int i;
  77
  78	for (i = 0; i < IWL_P1K_SIZE; i++)
  79		out[i] = cpu_to_le16(p1k[i]);
  80}
  81
  82static const u8 *iwl_mvm_find_max_pn(struct ieee80211_key_conf *key,
  83				     struct iwl_mvm_key_pn *ptk_pn,
  84				     struct ieee80211_key_seq *seq,
  85				     int tid, int queues)
  86{
  87	const u8 *ret = seq->ccmp.pn;
  88	int i;
  89
  90	/* get the PN from mac80211, used on the default queue */
  91	ieee80211_get_key_rx_seq(key, tid, seq);
  92
  93	/* and use the internal data for the other queues */
  94	for (i = 1; i < queues; i++) {
  95		const u8 *tmp = ptk_pn->q[i].pn[tid];
  96
  97		if (memcmp(ret, tmp, IEEE80211_CCMP_PN_LEN) <= 0)
  98			ret = tmp;
  99	}
 100
 101	return ret;
 102}
 103
 104struct wowlan_key_reprogram_data {
 105	bool error;
 106	int wep_key_idx;
 107};
 108
 109static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
 110					struct ieee80211_vif *vif,
 111					struct ieee80211_sta *sta,
 112					struct ieee80211_key_conf *key,
 113					void *_data)
 114{
 115	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
 116	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
 117	struct wowlan_key_reprogram_data *data = _data;
 118	int ret;
 119
 120	switch (key->cipher) {
 121	case WLAN_CIPHER_SUITE_WEP40:
 122	case WLAN_CIPHER_SUITE_WEP104: { /* hack it for now */
 123		DEFINE_RAW_FLEX(struct iwl_mvm_wep_key_cmd, wkc, wep_key, 1);
 124		struct iwl_mvm_wep_key *wep_key = wkc->wep_key;
 125
 126		wkc->mac_id_n_color =
 127			cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
 128							mvmvif->color));
 129		wkc->num_keys = 1;
 130		/* firmware sets STA_KEY_FLG_WEP_13BYTES */
 131		wkc->decryption_type = STA_KEY_FLG_WEP;
 132		wep_key->key_index = key->keyidx;
 133		wep_key->key_size = key->keylen;
 134
 135		/*
 136		 * This will fail -- the key functions don't set support
 137		 * pairwise WEP keys. However, that's better than silently
 138		 * failing WoWLAN. Or maybe not?
 139		 */
 140		if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
 141			break;
 142
 143		memcpy(&wep_key->key[3], key->key, key->keylen);
 144		if (key->keyidx == mvmvif->tx_key_idx) {
 145			/* TX key must be at offset 0 */
 146			wep_key->key_offset = 0;
 147		} else {
 148			/* others start at 1 */
 149			data->wep_key_idx++;
 150			wep_key->key_offset = data->wep_key_idx;
 151		}
 152
 153		mutex_lock(&mvm->mutex);
 154		ret = iwl_mvm_send_cmd_pdu(mvm, WEP_KEY, 0,
 155					   __struct_size(wkc), wkc);
 156		data->error = ret != 0;
 157
 158		mvm->ptk_ivlen = key->iv_len;
 159		mvm->ptk_icvlen = key->icv_len;
 160		mvm->gtk_ivlen = key->iv_len;
 161		mvm->gtk_icvlen = key->icv_len;
 162		mutex_unlock(&mvm->mutex);
 163
 164		/* don't upload key again */
 165		return;
 166	}
 167	default:
 168		data->error = true;
 169		return;
 170	case WLAN_CIPHER_SUITE_BIP_GMAC_256:
 171	case WLAN_CIPHER_SUITE_BIP_GMAC_128:
 172		return;
 173	case WLAN_CIPHER_SUITE_AES_CMAC:
 174		/*
 175		 * Ignore CMAC keys -- the WoWLAN firmware doesn't support them
 176		 * but we also shouldn't abort suspend due to that. It does have
 177		 * support for the IGTK key renewal, but doesn't really use the
 178		 * IGTK for anything. This means we could spuriously wake up or
 179		 * be deauthenticated, but that was considered acceptable.
 180		 */
 181		return;
 182	case WLAN_CIPHER_SUITE_TKIP:
 183	case WLAN_CIPHER_SUITE_CCMP:
 184	case WLAN_CIPHER_SUITE_GCMP:
 185	case WLAN_CIPHER_SUITE_GCMP_256:
 186		break;
 187	}
 188
 189	mutex_lock(&mvm->mutex);
 190	/*
 191	 * The D3 firmware hardcodes the key offset 0 as the key it
 192	 * uses to transmit packets to the AP, i.e. the PTK.
 193	 */
 194	if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
 195		mvm->ptk_ivlen = key->iv_len;
 196		mvm->ptk_icvlen = key->icv_len;
 197		ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, 0);
 198	} else {
 199		/*
 200		 * firmware only supports TSC/RSC for a single key,
 201		 * so if there are multiple keep overwriting them
 202		 * with new ones -- this relies on mac80211 doing
 203		 * list_add_tail().
 204		 */
 205		mvm->gtk_ivlen = key->iv_len;
 206		mvm->gtk_icvlen = key->icv_len;
 207		ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, 1);
 208	}
 209	mutex_unlock(&mvm->mutex);
 210	data->error = ret != 0;
 211}
 212
 213struct wowlan_key_rsc_tsc_data {
 214	struct iwl_wowlan_rsc_tsc_params_cmd_ver_2 *rsc_tsc;
 215	bool have_rsc_tsc;
 216};
 217
 218static void iwl_mvm_wowlan_get_rsc_tsc_data(struct ieee80211_hw *hw,
 219					    struct ieee80211_vif *vif,
 220					    struct ieee80211_sta *sta,
 221					    struct ieee80211_key_conf *key,
 222					    void *_data)
 223{
 224	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
 225	struct wowlan_key_rsc_tsc_data *data = _data;
 226	struct aes_sc *aes_sc;
 227	struct tkip_sc *tkip_sc, *tkip_tx_sc = NULL;
 228	struct ieee80211_key_seq seq;
 229	int i;
 230
 231	switch (key->cipher) {
 232	default:
 233		break;
 234	case WLAN_CIPHER_SUITE_TKIP:
 235		if (sta) {
 236			u64 pn64;
 237
 238			tkip_sc =
 239			   data->rsc_tsc->all_tsc_rsc.tkip.unicast_rsc;
 240			tkip_tx_sc =
 241				&data->rsc_tsc->all_tsc_rsc.tkip.tsc;
 242
 243			pn64 = atomic64_read(&key->tx_pn);
 244			tkip_tx_sc->iv16 = cpu_to_le16(TKIP_PN_TO_IV16(pn64));
 245			tkip_tx_sc->iv32 = cpu_to_le32(TKIP_PN_TO_IV32(pn64));
 246		} else {
 247			tkip_sc =
 248			  data->rsc_tsc->all_tsc_rsc.tkip.multicast_rsc;
 249		}
 250
 251		/*
 252		 * For non-QoS this relies on the fact that both the uCode and
 253		 * mac80211 use TID 0 (as they need to avoid replay attacks)
 254		 * for checking the IV in the frames.
 255		 */
 256		for (i = 0; i < IWL_NUM_RSC; i++) {
 257			ieee80211_get_key_rx_seq(key, i, &seq);
 258			tkip_sc[i].iv16 = cpu_to_le16(seq.tkip.iv16);
 259			tkip_sc[i].iv32 = cpu_to_le32(seq.tkip.iv32);
 260		}
 261
 262		data->have_rsc_tsc = true;
 263		break;
 264	case WLAN_CIPHER_SUITE_CCMP:
 265	case WLAN_CIPHER_SUITE_GCMP:
 266	case WLAN_CIPHER_SUITE_GCMP_256:
 267		if (sta) {
 268			struct aes_sc *aes_tx_sc;
 269			u64 pn64;
 270
 271			aes_sc =
 272			   data->rsc_tsc->all_tsc_rsc.aes.unicast_rsc;
 273			aes_tx_sc =
 274				&data->rsc_tsc->all_tsc_rsc.aes.tsc;
 275
 276			pn64 = atomic64_read(&key->tx_pn);
 277			aes_tx_sc->pn = cpu_to_le64(pn64);
 278		} else {
 279			aes_sc =
 280			   data->rsc_tsc->all_tsc_rsc.aes.multicast_rsc;
 281		}
 282
 283		/*
 284		 * For non-QoS this relies on the fact that both the uCode and
 285		 * mac80211/our RX code use TID 0 for checking the PN.
 286		 */
 287		if (sta && iwl_mvm_has_new_rx_api(mvm)) {
 288			struct iwl_mvm_sta *mvmsta;
 289			struct iwl_mvm_key_pn *ptk_pn;
 290			const u8 *pn;
 291
 292			mvmsta = iwl_mvm_sta_from_mac80211(sta);
 293			rcu_read_lock();
 294			ptk_pn = rcu_dereference(mvmsta->ptk_pn[key->keyidx]);
 295			if (WARN_ON(!ptk_pn)) {
 296				rcu_read_unlock();
 297				break;
 298			}
 299
 300			for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
 301				pn = iwl_mvm_find_max_pn(key, ptk_pn, &seq, i,
 302						mvm->trans->info.num_rxqs);
 303				aes_sc[i].pn = cpu_to_le64((u64)pn[5] |
 304							   ((u64)pn[4] << 8) |
 305							   ((u64)pn[3] << 16) |
 306							   ((u64)pn[2] << 24) |
 307							   ((u64)pn[1] << 32) |
 308							   ((u64)pn[0] << 40));
 309			}
 310
 311			rcu_read_unlock();
 312		} else {
 313			for (i = 0; i < IWL_NUM_RSC; i++) {
 314				u8 *pn = seq.ccmp.pn;
 315
 316				ieee80211_get_key_rx_seq(key, i, &seq);
 317				aes_sc[i].pn = cpu_to_le64((u64)pn[5] |
 318							   ((u64)pn[4] << 8) |
 319							   ((u64)pn[3] << 16) |
 320							   ((u64)pn[2] << 24) |
 321							   ((u64)pn[1] << 32) |
 322							   ((u64)pn[0] << 40));
 323			}
 324		}
 325		data->have_rsc_tsc = true;
 326		break;
 327	}
 328}
 329
 330struct wowlan_key_rsc_v5_data {
 331	struct iwl_wowlan_rsc_tsc_params_cmd *rsc;
 332	bool have_rsc;
 333	int gtks;
 334	int gtk_ids[4];
 335};
 336
 337static void iwl_mvm_wowlan_get_rsc_v5_data(struct ieee80211_hw *hw,
 338					   struct ieee80211_vif *vif,
 339					   struct ieee80211_sta *sta,
 340					   struct ieee80211_key_conf *key,
 341					   void *_data)
 342{
 343	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
 344	struct wowlan_key_rsc_v5_data *data = _data;
 345	struct ieee80211_key_seq seq;
 346	__le64 *rsc;
 347	int i;
 348
 349	/* only for ciphers that can be PTK/GTK */
 350	switch (key->cipher) {
 351	default:
 352		return;
 353	case WLAN_CIPHER_SUITE_TKIP:
 354	case WLAN_CIPHER_SUITE_CCMP:
 355	case WLAN_CIPHER_SUITE_GCMP:
 356	case WLAN_CIPHER_SUITE_GCMP_256:
 357		break;
 358	}
 359
 360	if (sta) {
 361		rsc = data->rsc->ucast_rsc;
 362	} else {
 363		if (WARN_ON(data->gtks >= ARRAY_SIZE(data->gtk_ids)))
 364			return;
 365		data->gtk_ids[data->gtks] = key->keyidx;
 366		rsc = data->rsc->mcast_rsc[data->gtks % 2];
 367		if (WARN_ON(key->keyidx >=
 368				ARRAY_SIZE(data->rsc->mcast_key_id_map)))
 369			return;
 370		data->rsc->mcast_key_id_map[key->keyidx] = data->gtks % 2;
 371		if (data->gtks >= 2) {
 372			int prev = data->gtks - 2;
 373			int prev_idx = data->gtk_ids[prev];
 374
 375			data->rsc->mcast_key_id_map[prev_idx] =
 376				IWL_MCAST_KEY_MAP_INVALID;
 377		}
 378		data->gtks++;
 379	}
 380
 381	switch (key->cipher) {
 382	default:
 383		WARN_ON(1);
 384		break;
 385	case WLAN_CIPHER_SUITE_TKIP:
 386
 387		/*
 388		 * For non-QoS this relies on the fact that both the uCode and
 389		 * mac80211 use TID 0 (as they need to avoid replay attacks)
 390		 * for checking the IV in the frames.
 391		 */
 392		for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
 393			ieee80211_get_key_rx_seq(key, i, &seq);
 394
 395			rsc[i] = cpu_to_le64(((u64)seq.tkip.iv32 << 16) |
 396					     seq.tkip.iv16);
 397		}
 398
 399		data->have_rsc = true;
 400		break;
 401	case WLAN_CIPHER_SUITE_CCMP:
 402	case WLAN_CIPHER_SUITE_GCMP:
 403	case WLAN_CIPHER_SUITE_GCMP_256:
 404		/*
 405		 * For non-QoS this relies on the fact that both the uCode and
 406		 * mac80211/our RX code use TID 0 for checking the PN.
 407		 */
 408		if (sta) {
 409			struct iwl_mvm_sta *mvmsta;
 410			struct iwl_mvm_key_pn *ptk_pn;
 411			const u8 *pn;
 412
 413			mvmsta = iwl_mvm_sta_from_mac80211(sta);
 414			rcu_read_lock();
 415			ptk_pn = rcu_dereference(mvmsta->ptk_pn[key->keyidx]);
 416			if (WARN_ON(!ptk_pn)) {
 417				rcu_read_unlock();
 418				break;
 419			}
 420
 421			for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
 422				pn = iwl_mvm_find_max_pn(key, ptk_pn, &seq, i,
 423						mvm->trans->info.num_rxqs);
 424				rsc[i] = cpu_to_le64((u64)pn[5] |
 425						     ((u64)pn[4] << 8) |
 426						     ((u64)pn[3] << 16) |
 427						     ((u64)pn[2] << 24) |
 428						     ((u64)pn[1] << 32) |
 429						     ((u64)pn[0] << 40));
 430			}
 431
 432			rcu_read_unlock();
 433		} else {
 434			for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
 435				u8 *pn = seq.ccmp.pn;
 436
 437				ieee80211_get_key_rx_seq(key, i, &seq);
 438				rsc[i] = cpu_to_le64((u64)pn[5] |
 439						     ((u64)pn[4] << 8) |
 440						     ((u64)pn[3] << 16) |
 441						     ((u64)pn[2] << 24) |
 442						     ((u64)pn[1] << 32) |
 443						     ((u64)pn[0] << 40));
 444			}
 445		}
 446		data->have_rsc = true;
 447		break;
 448	}
 449}
 450
 451static int iwl_mvm_wowlan_config_rsc_tsc(struct iwl_mvm *mvm,
 452					 struct ieee80211_vif *vif,
 453					 struct iwl_mvm_vif_link_info *mvm_link)
 454{
 455	int ver = iwl_fw_lookup_cmd_ver(mvm->fw, WOWLAN_TSC_RSC_PARAM,
 456					IWL_FW_CMD_VER_UNKNOWN);
 457	int ret;
 458
 459	if (ver == 5) {
 460		struct wowlan_key_rsc_v5_data data = {};
 461		int i;
 462
 463		data.rsc = kzalloc(sizeof(*data.rsc), GFP_KERNEL);
 464		if (!data.rsc)
 465			return -ENOMEM;
 466
 467		for (i = 0; i < ARRAY_SIZE(data.rsc->mcast_key_id_map); i++)
 468			data.rsc->mcast_key_id_map[i] =
 469				IWL_MCAST_KEY_MAP_INVALID;
 470		data.rsc->sta_id = cpu_to_le32(mvm_link->ap_sta_id);
 471
 472		ieee80211_iter_keys(mvm->hw, vif,
 473				    iwl_mvm_wowlan_get_rsc_v5_data,
 474				    &data);
 475
 476		if (data.have_rsc)
 477			ret = iwl_mvm_send_cmd_pdu(mvm, WOWLAN_TSC_RSC_PARAM,
 478						   CMD_ASYNC, sizeof(*data.rsc),
 479						   data.rsc);
 480		else
 481			ret = 0;
 482		kfree(data.rsc);
 483	} else if (ver == 2 || ver == IWL_FW_CMD_VER_UNKNOWN) {
 484		struct wowlan_key_rsc_tsc_data data = {};
 485
 486		data.rsc_tsc = kzalloc(sizeof(*data.rsc_tsc), GFP_KERNEL);
 487		if (!data.rsc_tsc)
 488			return -ENOMEM;
 489
 490		ieee80211_iter_keys(mvm->hw, vif,
 491				    iwl_mvm_wowlan_get_rsc_tsc_data,
 492				    &data);
 493
 494		if (data.have_rsc_tsc)
 495			ret = iwl_mvm_send_cmd_pdu(mvm, WOWLAN_TSC_RSC_PARAM,
 496						   CMD_ASYNC,
 497						   sizeof(*data.rsc_tsc),
 498						   data.rsc_tsc);
 499		else
 500			ret = 0;
 501		kfree(data.rsc_tsc);
 502	} else {
 503		ret = 0;
 504		WARN_ON_ONCE(1);
 505	}
 506
 507	return ret;
 508}
 509
 510struct wowlan_key_tkip_data {
 511	struct iwl_wowlan_tkip_params_cmd tkip;
 512	bool have_tkip_keys;
 513};
 514
 515static void iwl_mvm_wowlan_get_tkip_data(struct ieee80211_hw *hw,
 516					 struct ieee80211_vif *vif,
 517					 struct ieee80211_sta *sta,
 518					 struct ieee80211_key_conf *key,
 519					 void *_data)
 520{
 521	struct wowlan_key_tkip_data *data = _data;
 522	struct iwl_p1k_cache *rx_p1ks;
 523	u8 *rx_mic_key;
 524	struct ieee80211_key_seq seq;
 525	u32 cur_rx_iv32 = 0;
 526	u16 p1k[IWL_P1K_SIZE];
 527	int i;
 528
 529	switch (key->cipher) {
 530	default:
 531		break;
 532	case WLAN_CIPHER_SUITE_TKIP:
 533		if (sta) {
 534			u64 pn64;
 535
 536			rx_p1ks = data->tkip.rx_uni;
 537
 538			pn64 = atomic64_read(&key->tx_pn);
 539
 540			ieee80211_get_tkip_p1k_iv(key, TKIP_PN_TO_IV32(pn64),
 541						  p1k);
 542			iwl_mvm_convert_p1k(p1k, data->tkip.tx.p1k);
 543
 544			memcpy(data->tkip.mic_keys.tx,
 545			       &key->key[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY],
 546			       IWL_MIC_KEY_SIZE);
 547
 548			rx_mic_key = data->tkip.mic_keys.rx_unicast;
 549		} else {
 550			rx_p1ks = data->tkip.rx_multi;
 551			rx_mic_key = data->tkip.mic_keys.rx_mcast;
 552		}
 553
 554		for (i = 0; i < IWL_NUM_RSC; i++) {
 555			ieee80211_get_key_rx_seq(key, i, &seq);
 556			/* wrapping isn't allowed, AP must rekey */
 557			if (seq.tkip.iv32 > cur_rx_iv32)
 558				cur_rx_iv32 = seq.tkip.iv32;
 559		}
 560
 561		ieee80211_get_tkip_rx_p1k(key, vif->bss_conf.bssid,
 562					  cur_rx_iv32, p1k);
 563		iwl_mvm_convert_p1k(p1k, rx_p1ks[0].p1k);
 564		ieee80211_get_tkip_rx_p1k(key, vif->bss_conf.bssid,
 565					  cur_rx_iv32 + 1, p1k);
 566		iwl_mvm_convert_p1k(p1k, rx_p1ks[1].p1k);
 567
 568		memcpy(rx_mic_key,
 569		       &key->key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY],
 570		       IWL_MIC_KEY_SIZE);
 571
 572		data->have_tkip_keys = true;
 573		break;
 574	}
 575}
 576
 577struct wowlan_key_gtk_type_iter {
 578	struct iwl_wowlan_kek_kck_material_cmd_v4 *kek_kck_cmd;
 579};
 580
 581static void iwl_mvm_wowlan_gtk_type_iter(struct ieee80211_hw *hw,
 582					 struct ieee80211_vif *vif,
 583					 struct ieee80211_sta *sta,
 584					 struct ieee80211_key_conf *key,
 585					 void *_data)
 586{
 587	struct wowlan_key_gtk_type_iter *data = _data;
 588	__le32 *cipher = NULL;
 589
 590	if (key->keyidx == 4 || key->keyidx == 5)
 591		cipher = &data->kek_kck_cmd->igtk_cipher;
 592	if (key->keyidx == 6 || key->keyidx == 7)
 593		cipher = &data->kek_kck_cmd->bigtk_cipher;
 594
 595	switch (key->cipher) {
 596	default:
 597		return;
 598	case WLAN_CIPHER_SUITE_TKIP:
 599		if (!sta)
 600			data->kek_kck_cmd->gtk_cipher =
 601				cpu_to_le32(STA_KEY_FLG_TKIP);
 602		return;
 603	case WLAN_CIPHER_SUITE_BIP_GMAC_256:
 604	case WLAN_CIPHER_SUITE_BIP_GMAC_128:
 605		if (cipher)
 606			*cipher = cpu_to_le32(STA_KEY_FLG_GCMP);
 607		return;
 608	case WLAN_CIPHER_SUITE_AES_CMAC:
 609	case WLAN_CIPHER_SUITE_BIP_CMAC_256:
 610		if (cipher)
 611			*cipher = cpu_to_le32(STA_KEY_FLG_CCM);
 612		return;
 613	case WLAN_CIPHER_SUITE_CCMP:
 614		if (!sta)
 615			data->kek_kck_cmd->gtk_cipher =
 616				cpu_to_le32(STA_KEY_FLG_CCM);
 617		return;
 618	case WLAN_CIPHER_SUITE_GCMP:
 619	case WLAN_CIPHER_SUITE_GCMP_256:
 620		if (!sta)
 621			data->kek_kck_cmd->gtk_cipher =
 622				cpu_to_le32(STA_KEY_FLG_GCMP);
 623		return;
 624	}
 625}
 626
 627static int iwl_mvm_send_patterns_v1(struct iwl_mvm *mvm,
 628				    struct cfg80211_wowlan *wowlan)
 629{
 630	struct iwl_wowlan_patterns_cmd_v1 *pattern_cmd;
 631	struct iwl_host_cmd cmd = {
 632		.id = WOWLAN_PATTERNS,
 633		.dataflags[0] = IWL_HCMD_DFL_NOCOPY,
 634	};
 635	int i, err;
 636
 637	if (!wowlan->n_patterns)
 638		return 0;
 639
 640	cmd.len[0] = struct_size(pattern_cmd, patterns, wowlan->n_patterns);
 641
 642	pattern_cmd = kmalloc(cmd.len[0], GFP_KERNEL);
 643	if (!pattern_cmd)
 644		return -ENOMEM;
 645
 646	pattern_cmd->n_patterns = cpu_to_le32(wowlan->n_patterns);
 647
 648	for (i = 0; i < wowlan->n_patterns; i++) {
 649		int mask_len = DIV_ROUND_UP(wowlan->patterns[i].pattern_len, 8);
 650
 651		memcpy(&pattern_cmd->patterns[i].mask,
 652		       wowlan->patterns[i].mask, mask_len);
 653		memcpy(&pattern_cmd->patterns[i].pattern,
 654		       wowlan->patterns[i].pattern,
 655		       wowlan->patterns[i].pattern_len);
 656		pattern_cmd->patterns[i].mask_size = mask_len;
 657		pattern_cmd->patterns[i].pattern_size =
 658			wowlan->patterns[i].pattern_len;
 659	}
 660
 661	cmd.data[0] = pattern_cmd;
 662	err = iwl_mvm_send_cmd(mvm, &cmd);
 663	kfree(pattern_cmd);
 664	return err;
 665}
 666
 667static int iwl_mvm_send_patterns(struct iwl_mvm *mvm,
 668				 struct iwl_mvm_vif_link_info *mvm_link,
 669				 struct cfg80211_wowlan *wowlan)
 670{
 671	struct iwl_wowlan_patterns_cmd *pattern_cmd;
 672	struct iwl_host_cmd cmd = {
 673		.id = WOWLAN_PATTERNS,
 674		.dataflags[0] = IWL_HCMD_DFL_NOCOPY,
 675	};
 676	int i, err;
 677	int ver = iwl_fw_lookup_cmd_ver(mvm->fw, cmd.id,
 678					IWL_FW_CMD_VER_UNKNOWN);
 679
 680	if (!wowlan->n_patterns)
 681		return 0;
 682
 683	cmd.len[0] = sizeof(*pattern_cmd) +
 684		wowlan->n_patterns * sizeof(struct iwl_wowlan_pattern_v2);
 685
 686	pattern_cmd = kzalloc(cmd.len[0], GFP_KERNEL);
 687	if (!pattern_cmd)
 688		return -ENOMEM;
 689
 690	pattern_cmd->n_patterns = wowlan->n_patterns;
 691	if (ver >= 3)
 692		pattern_cmd->sta_id = mvm_link->ap_sta_id;
 693
 694	for (i = 0; i < wowlan->n_patterns; i++) {
 695		int mask_len = DIV_ROUND_UP(wowlan->patterns[i].pattern_len, 8);
 696
 697		pattern_cmd->patterns[i].pattern_type =
 698			WOWLAN_PATTERN_TYPE_BITMASK;
 699
 700		memcpy(&pattern_cmd->patterns[i].u.bitmask.mask,
 701		       wowlan->patterns[i].mask, mask_len);
 702		memcpy(&pattern_cmd->patterns[i].u.bitmask.pattern,
 703		       wowlan->patterns[i].pattern,
 704		       wowlan->patterns[i].pattern_len);
 705		pattern_cmd->patterns[i].u.bitmask.mask_size = mask_len;
 706		pattern_cmd->patterns[i].u.bitmask.pattern_size =
 707			wowlan->patterns[i].pattern_len;
 708	}
 709
 710	cmd.data[0] = pattern_cmd;
 711	err = iwl_mvm_send_cmd(mvm, &cmd);
 712	kfree(pattern_cmd);
 713	return err;
 714}
 715
 716static int iwl_mvm_d3_reprogram(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
 717				struct ieee80211_sta *ap_sta)
 718{
 719	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
 720	struct ieee80211_chanctx_conf *ctx;
 721	u8 chains_static, chains_dynamic;
 722	struct cfg80211_chan_def chandef, ap_def;
 723	int ret, i;
 724	struct iwl_binding_cmd_v1 binding_cmd = {};
 725	struct iwl_time_quota_cmd quota_cmd = {};
 726	struct iwl_time_quota_data *quota;
 727	u32 status;
 728
 729	if (WARN_ON_ONCE(iwl_mvm_is_cdb_supported(mvm) ||
 730			 ieee80211_vif_is_mld(vif)))
 731		return -EINVAL;
 732
 733	/* add back the PHY */
 734	if (WARN_ON(!mvmvif->deflink.phy_ctxt))
 735		return -EINVAL;
 736
 737	rcu_read_lock();
 738	ctx = rcu_dereference(vif->bss_conf.chanctx_conf);
 739	if (WARN_ON(!ctx)) {
 740		rcu_read_unlock();
 741		return -EINVAL;
 742	}
 743	chandef = ctx->def;
 744	ap_def = ctx->ap;
 745	chains_static = ctx->rx_chains_static;
 746	chains_dynamic = ctx->rx_chains_dynamic;
 747	rcu_read_unlock();
 748
 749	ret = iwl_mvm_phy_ctxt_add(mvm, mvmvif->deflink.phy_ctxt, &chandef,
 750				   &ap_def, chains_static, chains_dynamic);
 751	if (ret)
 752		return ret;
 753
 754	/* add back the MAC */
 755	mvmvif->uploaded = false;
 756
 757	if (WARN_ON(!vif->cfg.assoc))
 758		return -EINVAL;
 759
 760	ret = iwl_mvm_mac_ctxt_add(mvm, vif);
 761	if (ret)
 762		return ret;
 763
 764	/* add back binding - XXX refactor? */
 765	binding_cmd.id_and_color =
 766		cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->deflink.phy_ctxt->id,
 767						mvmvif->deflink.phy_ctxt->color));
 768	binding_cmd.action = cpu_to_le32(FW_CTXT_ACTION_ADD);
 769	binding_cmd.phy =
 770		cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->deflink.phy_ctxt->id,
 771						mvmvif->deflink.phy_ctxt->color));
 772	binding_cmd.macs[0] = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
 773							      mvmvif->color));
 774	for (i = 1; i < MAX_MACS_IN_BINDING; i++)
 775		binding_cmd.macs[i] = cpu_to_le32(FW_CTXT_INVALID);
 776
 777	status = 0;
 778	ret = iwl_mvm_send_cmd_pdu_status(mvm, BINDING_CONTEXT_CMD,
 779					  IWL_BINDING_CMD_SIZE_V1, &binding_cmd,
 780					  &status);
 781	if (ret) {
 782		IWL_ERR(mvm, "Failed to add binding: %d\n", ret);
 783		return ret;
 784	}
 785
 786	if (status) {
 787		IWL_ERR(mvm, "Binding command failed: %u\n", status);
 788		return -EIO;
 789	}
 790
 791	ret = iwl_mvm_sta_send_to_fw(mvm, ap_sta, false, 0);
 792	if (ret)
 793		return ret;
 794	rcu_assign_pointer(mvm->fw_id_to_mac_id[mvmvif->deflink.ap_sta_id],
 795			   ap_sta);
 796
 797	ret = iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
 798	if (ret)
 799		return ret;
 800
 801	/* and some quota */
 802	quota = iwl_mvm_quota_cmd_get_quota(mvm, &quota_cmd, 0);
 803	quota->id_and_color =
 804		cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->deflink.phy_ctxt->id,
 805						mvmvif->deflink.phy_ctxt->color));
 806	quota->quota = cpu_to_le32(IWL_MVM_MAX_QUOTA);
 807	quota->max_duration = cpu_to_le32(IWL_MVM_MAX_QUOTA);
 808
 809	for (i = 1; i < MAX_BINDINGS; i++) {
 810		quota = iwl_mvm_quota_cmd_get_quota(mvm, &quota_cmd, i);
 811		quota->id_and_color = cpu_to_le32(FW_CTXT_INVALID);
 812	}
 813
 814	ret = iwl_mvm_send_cmd_pdu(mvm, TIME_QUOTA_CMD, 0,
 815				   iwl_mvm_quota_cmd_size(mvm), &quota_cmd);
 816	if (ret)
 817		IWL_ERR(mvm, "Failed to send quota: %d\n", ret);
 818
 819	if (iwl_mvm_is_lar_supported(mvm) && iwl_mvm_init_fw_regd(mvm, false))
 820		IWL_ERR(mvm, "Failed to initialize D3 LAR information\n");
 821
 822	return 0;
 823}
 824
 825static int iwl_mvm_get_last_nonqos_seq(struct iwl_mvm *mvm,
 826				       struct ieee80211_vif *vif)
 827{
 828	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
 829	struct iwl_nonqos_seq_query_cmd query_cmd = {
 830		.get_set_flag = cpu_to_le32(IWL_NONQOS_SEQ_GET),
 831		.mac_id_n_color =
 832			cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
 833							mvmvif->color)),
 834	};
 835	struct iwl_host_cmd cmd = {
 836		.id = NON_QOS_TX_COUNTER_CMD,
 837		.flags = CMD_WANT_SKB,
 838	};
 839	int err;
 840	u32 size;
 841
 842	cmd.data[0] = &query_cmd;
 843	cmd.len[0] = sizeof(query_cmd);
 844
 845	err = iwl_mvm_send_cmd(mvm, &cmd);
 846	if (err)
 847		return err;
 848
 849	size = iwl_rx_packet_payload_len(cmd.resp_pkt);
 850	if (size < sizeof(__le16)) {
 851		err = -EINVAL;
 852	} else {
 853		err = le16_to_cpup((__le16 *)cmd.resp_pkt->data);
 854		/* firmware returns next, not last-used seqno */
 855		err = (u16) (err - 0x10);
 856	}
 857
 858	iwl_free_resp(&cmd);
 859	return err;
 860}
 861
 862void iwl_mvm_set_last_nonqos_seq(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
 863{
 864	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
 865	struct iwl_nonqos_seq_query_cmd query_cmd = {
 866		.get_set_flag = cpu_to_le32(IWL_NONQOS_SEQ_SET),
 867		.mac_id_n_color =
 868			cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
 869							mvmvif->color)),
 870		.value = cpu_to_le16(mvmvif->seqno),
 871	};
 872
 873	/* return if called during restart, not resume from D3 */
 874	if (!mvmvif->seqno_valid)
 875		return;
 876
 877	mvmvif->seqno_valid = false;
 878
 879	if (iwl_mvm_send_cmd_pdu(mvm, NON_QOS_TX_COUNTER_CMD, 0,
 880				 sizeof(query_cmd), &query_cmd))
 881		IWL_ERR(mvm, "failed to set non-QoS seqno\n");
 882}
 883
 884static int iwl_mvm_switch_to_d3(struct iwl_mvm *mvm)
 885{
 886	iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_REGULAR, true);
 887
 888	iwl_mvm_stop_device(mvm);
 889	/*
 890	 * Set the HW restart bit -- this is mostly true as we're
 891	 * going to load new firmware and reprogram that, though
 892	 * the reprogramming is going to be manual to avoid adding
 893	 * all the MACs that aren't support.
 894	 * We don't have to clear up everything though because the
 895	 * reprogramming is manual. When we resume, we'll actually
 896	 * go through a proper restart sequence again to switch
 897	 * back to the runtime firmware image.
 898	 */
 899	set_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);
 900
 901	/* the fw is reset, so all the keys are cleared */
 902	memset(mvm->fw_key_table, 0, sizeof(mvm->fw_key_table));
 903
 904	mvm->ptk_ivlen = 0;
 905	mvm->ptk_icvlen = 0;
 906	mvm->ptk_ivlen = 0;
 907	mvm->ptk_icvlen = 0;
 908
 909	return iwl_mvm_load_d3_fw(mvm);
 910}
 911
 912static int
 913iwl_mvm_get_wowlan_config(struct iwl_mvm *mvm,
 914			  struct cfg80211_wowlan *wowlan,
 915			  struct iwl_wowlan_config_cmd_v6 *wowlan_config_cmd,
 916			  struct ieee80211_vif *vif, struct iwl_mvm_vif *mvmvif,
 917			  struct ieee80211_sta *ap_sta)
 918{
 919	struct iwl_mvm_sta *mvm_ap_sta = iwl_mvm_sta_from_mac80211(ap_sta);
 920
 921	/* TODO: wowlan_config_cmd->wowlan_ba_teardown_tids */
 922
 923	wowlan_config_cmd->is_11n_connection =
 924					ap_sta->deflink.ht_cap.ht_supported;
 925	wowlan_config_cmd->flags = ENABLE_L3_FILTERING |
 926		ENABLE_NBNS_FILTERING | ENABLE_DHCP_FILTERING;
 927
 928	if (ap_sta->mfp)
 929		wowlan_config_cmd->flags |= IS_11W_ASSOC;
 930
 931	if (rcu_access_pointer(mvmvif->bcn_prot.keys[0]) ||
 932	    rcu_access_pointer(mvmvif->bcn_prot.keys[1]))
 933		wowlan_config_cmd->flags |= HAS_BEACON_PROTECTION;
 934
 935	if (iwl_fw_lookup_cmd_ver(mvm->fw, WOWLAN_CONFIGURATION, 0) < 6) {
 936		/* Query the last used seqno and set it */
 937		int ret = iwl_mvm_get_last_nonqos_seq(mvm, vif);
 938
 939		if (ret < 0)
 940			return ret;
 941
 942		wowlan_config_cmd->non_qos_seq = cpu_to_le16(ret);
 943	}
 944
 945	if (iwl_fw_lookup_cmd_ver(mvm->fw, WOWLAN_CONFIGURATION, 0) < 7)
 946		iwl_mvm_set_wowlan_qos_seq(mvm_ap_sta, wowlan_config_cmd);
 947
 948	if (wowlan->disconnect)
 949		wowlan_config_cmd->wakeup_filter |=
 950			cpu_to_le32(IWL_WOWLAN_WAKEUP_BEACON_MISS |
 951				    IWL_WOWLAN_WAKEUP_LINK_CHANGE);
 952	if (wowlan->magic_pkt)
 953		wowlan_config_cmd->wakeup_filter |=
 954			cpu_to_le32(IWL_WOWLAN_WAKEUP_MAGIC_PACKET);
 955	if (wowlan->gtk_rekey_failure)
 956		wowlan_config_cmd->wakeup_filter |=
 957			cpu_to_le32(IWL_WOWLAN_WAKEUP_GTK_REKEY_FAIL);
 958	if (wowlan->eap_identity_req)
 959		wowlan_config_cmd->wakeup_filter |=
 960			cpu_to_le32(IWL_WOWLAN_WAKEUP_EAP_IDENT_REQ);
 961	if (wowlan->four_way_handshake)
 962		wowlan_config_cmd->wakeup_filter |=
 963			cpu_to_le32(IWL_WOWLAN_WAKEUP_4WAY_HANDSHAKE);
 964	if (wowlan->n_patterns)
 965		wowlan_config_cmd->wakeup_filter |=
 966			cpu_to_le32(IWL_WOWLAN_WAKEUP_PATTERN_MATCH);
 967
 968	if (wowlan->rfkill_release)
 969		wowlan_config_cmd->wakeup_filter |=
 970			cpu_to_le32(IWL_WOWLAN_WAKEUP_RF_KILL_DEASSERT);
 971
 972	if (wowlan->tcp) {
 973		/*
 974		 * Set the "link change" (really "link lost") flag as well
 975		 * since that implies losing the TCP connection.
 976		 */
 977		wowlan_config_cmd->wakeup_filter |=
 978			cpu_to_le32(IWL_WOWLAN_WAKEUP_REMOTE_LINK_LOSS |
 979				    IWL_WOWLAN_WAKEUP_REMOTE_SIGNATURE_TABLE |
 980				    IWL_WOWLAN_WAKEUP_REMOTE_WAKEUP_PACKET |
 981				    IWL_WOWLAN_WAKEUP_LINK_CHANGE);
 982	}
 983
 984	if (wowlan->any) {
 985		wowlan_config_cmd->wakeup_filter |=
 986			cpu_to_le32(IWL_WOWLAN_WAKEUP_BEACON_MISS |
 987				    IWL_WOWLAN_WAKEUP_LINK_CHANGE |
 988				    IWL_WOWLAN_WAKEUP_RX_FRAME |
 989				    IWL_WOWLAN_WAKEUP_BCN_FILTERING);
 990	}
 991
 992	return 0;
 993}
 994
 995static int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm,
 996					    struct ieee80211_vif *vif,
 997					    struct iwl_mvm_vif_link_info *mvm_link)
 998{
 999	bool unified = fw_has_capa(&mvm->fw->ucode_capa,
1000				   IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);
1001	struct wowlan_key_reprogram_data key_data = {};
1002	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1003	int ret;
1004	u8 cmd_ver;
1005	size_t cmd_size;
1006
1007	if (!unified) {
1008		/*
1009		 * if we have to configure keys, call ieee80211_iter_keys(),
1010		 * as we need non-atomic context in order to take the
1011		 * required locks.
1012		 */
1013		/*
1014		 * Note that currently we don't use CMD_ASYNC in the iterator.
1015		 * In case of key_data.configure_keys, all the configured
1016		 * commands are SYNC, and iwl_mvm_wowlan_program_keys() will
1017		 * take care of locking/unlocking mvm->mutex.
1018		 */
1019		ieee80211_iter_keys(mvm->hw, vif, iwl_mvm_wowlan_program_keys,
1020				    &key_data);
1021
1022		if (key_data.error)
1023			return -EIO;
1024	}
1025
1026	ret = iwl_mvm_wowlan_config_rsc_tsc(mvm, vif, mvm_link);
1027	if (ret)
1028		return ret;
1029
1030	if (!fw_has_api(&mvm->fw->ucode_capa,
1031			IWL_UCODE_TLV_API_TKIP_MIC_KEYS)) {
1032		int ver = iwl_fw_lookup_cmd_ver(mvm->fw, WOWLAN_TKIP_PARAM,
1033						IWL_FW_CMD_VER_UNKNOWN);
1034		struct wowlan_key_tkip_data tkip_data = {};
1035		int size;
1036
1037		if (ver == 2) {
1038			size = sizeof(tkip_data.tkip);
1039			tkip_data.tkip.sta_id =
1040				cpu_to_le32(mvm_link->ap_sta_id);
1041		} else if (ver == 1 || ver == IWL_FW_CMD_VER_UNKNOWN) {
1042			size = sizeof(struct iwl_wowlan_tkip_params_cmd_ver_1);
1043		} else {
1044			WARN_ON_ONCE(1);
1045			return -EINVAL;
1046		}
1047
1048		ieee80211_iter_keys(mvm->hw, vif, iwl_mvm_wowlan_get_tkip_data,
1049				    &tkip_data);
1050
1051		if (tkip_data.have_tkip_keys) {
1052			/* send relevant data according to CMD version */
1053			ret = iwl_mvm_send_cmd_pdu(mvm,
1054						   WOWLAN_TKIP_PARAM,
1055						   CMD_ASYNC, size,
1056						   &tkip_data.tkip);
1057			if (ret)
1058				return ret;
1059		}
1060	}
1061
1062	/* configure rekey data only if offloaded rekey is supported (d3) */
1063	if (mvmvif->rekey_data.valid) {
1064		struct iwl_wowlan_kek_kck_material_cmd_v4 kek_kck_cmd = {};
1065		struct iwl_wowlan_kek_kck_material_cmd_v4 *_kek_kck_cmd =
1066			&kek_kck_cmd;
1067		struct wowlan_key_gtk_type_iter gtk_type_data = {
1068			.kek_kck_cmd = _kek_kck_cmd,
1069		};
1070
1071		cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw,
1072						WOWLAN_KEK_KCK_MATERIAL,
1073						IWL_FW_CMD_VER_UNKNOWN);
1074		if (WARN_ON(cmd_ver != 2 && cmd_ver != 3 && cmd_ver != 4 &&
1075			    cmd_ver != IWL_FW_CMD_VER_UNKNOWN))
1076			return -EINVAL;
1077
1078		ieee80211_iter_keys(mvm->hw, vif, iwl_mvm_wowlan_gtk_type_iter,
1079				    &gtk_type_data);
1080
1081		memcpy(kek_kck_cmd.kck, mvmvif->rekey_data.kck,
1082		       mvmvif->rekey_data.kck_len);
1083		kek_kck_cmd.kck_len = cpu_to_le16(mvmvif->rekey_data.kck_len);
1084		memcpy(kek_kck_cmd.kek, mvmvif->rekey_data.kek,
1085		       mvmvif->rekey_data.kek_len);
1086		kek_kck_cmd.kek_len = cpu_to_le16(mvmvif->rekey_data.kek_len);
1087		kek_kck_cmd.replay_ctr = mvmvif->rekey_data.replay_ctr;
1088		kek_kck_cmd.akm = cpu_to_le32(mvmvif->rekey_data.akm);
1089		kek_kck_cmd.sta_id = cpu_to_le32(mvm_link->ap_sta_id);
1090
1091		if (cmd_ver == 4) {
1092			cmd_size = sizeof(struct iwl_wowlan_kek_kck_material_cmd_v4);
1093		} else {
1094			if (cmd_ver == 3)
1095				cmd_size =
1096					sizeof(struct iwl_wowlan_kek_kck_material_cmd_v3);
1097			else
1098				cmd_size =
1099					sizeof(struct iwl_wowlan_kek_kck_material_cmd_v2);
1100			/* skip the sta_id at the beginning */
1101			_kek_kck_cmd = (void *)
1102				((u8 *)_kek_kck_cmd + sizeof(kek_kck_cmd.sta_id));
1103		}
1104
1105		IWL_DEBUG_WOWLAN(mvm, "setting akm %d\n",
1106				 mvmvif->rekey_data.akm);
1107
1108		ret = iwl_mvm_send_cmd_pdu(mvm, WOWLAN_KEK_KCK_MATERIAL,
1109					   CMD_ASYNC, cmd_size, _kek_kck_cmd);
1110		if (ret)
1111			return ret;
1112	}
1113
1114	return 0;
1115}
1116
1117static int
1118iwl_mvm_wowlan_config(struct iwl_mvm *mvm,
1119		      struct cfg80211_wowlan *wowlan,
1120		      struct iwl_wowlan_config_cmd_v6 *wowlan_config_cmd_v6,
1121		      struct ieee80211_vif *vif, struct iwl_mvm_vif *mvmvif,
1122		      struct iwl_mvm_vif_link_info *mvm_link,
1123		      struct ieee80211_sta *ap_sta)
1124{
1125	int ret;
1126	bool unified_image = fw_has_capa(&mvm->fw->ucode_capa,
1127					 IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);
1128
1129	mvm->offload_tid = wowlan_config_cmd_v6->offloading_tid;
1130
1131	if (!unified_image) {
1132		ret = iwl_mvm_switch_to_d3(mvm);
1133		if (ret)
1134			return ret;
1135
1136		ret = iwl_mvm_d3_reprogram(mvm, vif, ap_sta);
1137		if (ret)
1138			return ret;
1139	}
1140
1141	ret = iwl_mvm_wowlan_config_key_params(mvm, vif, mvm_link);
1142	if (ret)
1143		return ret;
1144
1145	if (iwl_fw_lookup_cmd_ver(mvm->fw, WOWLAN_CONFIGURATION, 0) > 6) {
1146		struct iwl_wowlan_config_cmd wowlan_config_cmd = {
1147			.wakeup_filter = wowlan_config_cmd_v6->wakeup_filter,
1148			.wowlan_ba_teardown_tids =
1149				wowlan_config_cmd_v6->wowlan_ba_teardown_tids,
1150			.is_11n_connection =
1151				wowlan_config_cmd_v6->is_11n_connection,
1152			.offloading_tid = wowlan_config_cmd_v6->offloading_tid,
1153			.flags = wowlan_config_cmd_v6->flags,
1154			.sta_id = wowlan_config_cmd_v6->sta_id,
1155		};
1156
1157		ret = iwl_mvm_send_cmd_pdu(mvm, WOWLAN_CONFIGURATION, 0,
1158					   sizeof(wowlan_config_cmd),
1159					   &wowlan_config_cmd);
1160	} else {
1161		ret = iwl_mvm_send_cmd_pdu(mvm, WOWLAN_CONFIGURATION, 0,
1162					   sizeof(*wowlan_config_cmd_v6),
1163					   wowlan_config_cmd_v6);
1164	}
1165	if (ret)
1166		return ret;
1167
1168	if (fw_has_api(&mvm->fw->ucode_capa,
1169		       IWL_UCODE_TLV_API_WOWLAN_TCP_SYN_WAKE))
1170		ret = iwl_mvm_send_patterns(mvm, mvm_link, wowlan);
1171	else
1172		ret = iwl_mvm_send_patterns_v1(mvm, wowlan);
1173	if (ret)
1174		return ret;
1175
1176	return iwl_mvm_send_proto_offload(mvm, vif, false, true, 0,
1177					  mvm_link->ap_sta_id);
1178}
1179
1180static int
1181iwl_mvm_netdetect_config(struct iwl_mvm *mvm,
1182			 struct cfg80211_wowlan *wowlan,
1183			 struct cfg80211_sched_scan_request *nd_config,
1184			 struct ieee80211_vif *vif)
1185{
1186	int ret;
1187	bool unified_image = fw_has_capa(&mvm->fw->ucode_capa,
1188					 IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);
1189
1190	if (!unified_image) {
1191		ret = iwl_mvm_switch_to_d3(mvm);
1192		if (ret)
1193			return ret;
1194	} else {
1195		/* In theory, we wouldn't have to stop a running sched
1196		 * scan in order to start another one (for
1197		 * net-detect).  But in practice this doesn't seem to
1198		 * work properly, so stop any running sched_scan now.
1199		 */
1200		ret = iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_SCHED, true);
1201		if (ret)
1202			return ret;
1203	}
1204
1205	ret = iwl_mvm_sched_scan_start(mvm, vif, nd_config, &mvm->nd_ies,
1206				       IWL_MVM_SCAN_NETDETECT);
1207	if (ret)
1208		return ret;
1209
1210	if (WARN_ON(mvm->nd_match_sets || mvm->nd_channels))
1211		return -EBUSY;
1212
1213	/* save the sched scan matchsets... */
1214	if (nd_config->n_match_sets) {
1215		mvm->nd_match_sets = kmemdup(nd_config->match_sets,
1216					     sizeof(*nd_config->match_sets) *
1217					     nd_config->n_match_sets,
1218					     GFP_KERNEL);
1219		if (mvm->nd_match_sets)
1220			mvm->n_nd_match_sets = nd_config->n_match_sets;
1221	}
1222
1223	/* ...and the sched scan channels for later reporting */
1224	mvm->nd_channels = kmemdup(nd_config->channels,
1225				   sizeof(*nd_config->channels) *
1226				   nd_config->n_channels,
1227				   GFP_KERNEL);
1228	if (mvm->nd_channels)
1229		mvm->n_nd_channels = nd_config->n_channels;
1230
1231	return 0;
1232}
1233
1234static void iwl_mvm_free_nd(struct iwl_mvm *mvm)
1235{
1236	kfree(mvm->nd_match_sets);
1237	mvm->nd_match_sets = NULL;
1238	mvm->n_nd_match_sets = 0;
1239	kfree(mvm->nd_channels);
1240	mvm->nd_channels = NULL;
1241	mvm->n_nd_channels = 0;
1242}
1243
1244static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
1245			     struct cfg80211_wowlan *wowlan)
1246{
1247	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1248	struct ieee80211_vif *vif = NULL;
1249	struct iwl_mvm_vif *mvmvif = NULL;
1250	struct ieee80211_sta *ap_sta = NULL;
1251	struct iwl_mvm_vif_link_info *mvm_link;
1252	struct iwl_d3_manager_config d3_cfg_cmd = {
1253		/*
1254		 * Program the minimum sleep time to 10 seconds, as many
1255		 * platforms have issues processing a wakeup signal while
1256		 * still being in the process of suspending.
1257		 */
1258		.min_sleep_time = cpu_to_le32(10 * 1000 * 1000),
1259	};
1260	int ret;
1261	int len __maybe_unused;
1262	bool unified_image = fw_has_capa(&mvm->fw->ucode_capa,
1263					 IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);
1264
1265	if (!wowlan) {
1266		/* mac80211 shouldn't get here */
1267		WARN_ON(1);
1268		return -EINVAL;
1269	}
1270
1271	vif = iwl_mvm_get_bss_vif(mvm);
1272	if (IS_ERR_OR_NULL(vif))
1273		return 1;
1274
1275	mutex_lock(&mvm->mutex);
1276
1277	set_bit(IWL_MVM_STATUS_IN_D3, &mvm->status);
1278
1279	synchronize_net();
1280
1281	mvmvif = iwl_mvm_vif_from_mac80211(vif);
1282
1283	mvm_link = mvmvif->link[iwl_mvm_get_primary_link(vif)];
1284	if (WARN_ON_ONCE(!mvm_link)) {
1285		ret = -EINVAL;
1286		goto out_noreset;
1287	}
1288
1289	if (mvm_link->ap_sta_id == IWL_INVALID_STA) {
1290		/* if we're not associated, this must be netdetect */
1291		if (!wowlan->nd_config) {
1292			ret = 1;
1293			goto out_noreset;
1294		}
1295
1296		ret = iwl_mvm_netdetect_config(
1297			mvm, wowlan, wowlan->nd_config, vif);
1298		if (ret)
1299			goto out;
1300
1301		mvm->net_detect = true;
1302	} else {
1303		struct iwl_wowlan_config_cmd_v6 wowlan_config_cmd = {
1304			.offloading_tid = 0,
1305		};
1306
1307		wowlan_config_cmd.sta_id = mvm_link->ap_sta_id;
1308
1309		ap_sta = rcu_dereference_protected(
1310			mvm->fw_id_to_mac_id[mvm_link->ap_sta_id],
1311			lockdep_is_held(&mvm->mutex));
1312		if (IS_ERR_OR_NULL(ap_sta)) {
1313			ret = -EINVAL;
1314			goto out_noreset;
1315		}
1316
1317		ret = iwl_mvm_sta_ensure_queue(
1318			mvm, ap_sta->txq[wowlan_config_cmd.offloading_tid]);
1319		if (ret)
1320			goto out_noreset;
1321
1322		ret = iwl_mvm_get_wowlan_config(mvm, wowlan, &wowlan_config_cmd,
1323						vif, mvmvif, ap_sta);
1324		if (ret)
1325			goto out_noreset;
1326		ret = iwl_mvm_wowlan_config(mvm, wowlan, &wowlan_config_cmd,
1327					    vif, mvmvif, mvm_link, ap_sta);
1328		if (ret)
1329			goto out;
1330
1331		mvm->net_detect = false;
1332	}
1333
1334	ret = iwl_mvm_power_update_device(mvm);
1335	if (ret)
1336		goto out;
1337
1338	ret = iwl_mvm_power_update_mac(mvm);
1339	if (ret)
1340		goto out;
1341
1342#ifdef CONFIG_IWLWIFI_DEBUGFS
1343	if (mvm->d3_wake_sysassert)
1344		d3_cfg_cmd.wakeup_flags |=
1345			cpu_to_le32(IWL_WAKEUP_D3_CONFIG_FW_ERROR);
1346#endif
1347
1348	/*
1349	 * Prior to 9000 device family the driver needs to stop the dbg
1350	 * recording before entering D3. In later devices the FW stops the
1351	 * recording automatically.
1352	 */
1353	if (mvm->trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_9000)
1354		iwl_fw_dbg_stop_restart_recording(&mvm->fwrt, NULL, true);
1355
1356	/* must be last -- this switches firmware state */
1357	ret = iwl_mvm_send_cmd_pdu(mvm, D3_CONFIG_CMD, 0, sizeof(d3_cfg_cmd),
1358				   &d3_cfg_cmd);
1359	if (ret)
1360		goto out;
1361
1362	clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);
1363
1364	ret = iwl_trans_d3_suspend(mvm->trans, !unified_image);
1365 out:
1366	if (ret < 0) {
1367		iwl_mvm_free_nd(mvm);
1368
1369		clear_bit(IWL_MVM_STATUS_IN_D3, &mvm->status);
1370	}
1371 out_noreset:
1372	mutex_unlock(&mvm->mutex);
1373
1374	return ret;
1375}
1376
1377int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
1378{
1379	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1380
1381	iwl_mvm_pause_tcm(mvm, true);
1382
1383	mutex_lock(&mvm->mutex);
1384	iwl_fw_runtime_suspend(&mvm->fwrt);
1385	mutex_unlock(&mvm->mutex);
1386
1387	return __iwl_mvm_suspend(hw, wowlan);
1388}
1389
1390struct iwl_multicast_key_data {
1391	u8 key[WOWLAN_KEY_MAX_SIZE];
1392	u8 len;
1393	u8 flags;
1394	u8 id;
1395	u8 ipn[6];
1396};
1397
1398/* converted data from the different status responses */
1399struct iwl_wowlan_status_data {
1400	u64 replay_ctr;
1401	u32 num_of_gtk_rekeys;
1402	u32 received_beacons;
1403	u32 wakeup_reasons;
1404	u32 wake_packet_length;
1405	u32 wake_packet_bufsize;
1406	u16 pattern_number;
1407	u16 non_qos_seq_ctr;
1408	u16 qos_seq_ctr[8];
1409	u8 tid_tear_down;
1410	u8 tid_offloaded_tx;
1411
1412	struct {
1413		/* including RX MIC key for TKIP */
1414		u8 key[WOWLAN_KEY_MAX_SIZE];
1415		u8 len;
1416		u8 flags;
1417		u8 id;
1418	} gtk[WOWLAN_GTK_KEYS_NUM];
1419
1420	struct {
1421		/*
1422		 * We store both the TKIP and AES representations
1423		 * coming from the firmware because we decode the
1424		 * data from there before we iterate the keys and
1425		 * know which one we need.
1426		 */
1427		struct {
1428			struct ieee80211_key_seq seq[IWL_MAX_TID_COUNT];
1429		} tkip, aes;
1430
1431		/*
1432		 * We use -1 for when we have valid data but don't know
1433		 * the key ID from firmware, and thus it needs to be
1434		 * installed with the last key (depending on rekeying).
1435		 */
1436		s8 key_id;
1437		bool valid;
1438	} gtk_seq[2];
1439
1440	struct {
1441		/* Same as above */
1442		struct {
1443			struct ieee80211_key_seq seq[IWL_MAX_TID_COUNT];
1444			u64 tx_pn;
1445		} tkip, aes;
1446	} ptk;
1447
1448	struct iwl_multicast_key_data igtk;
1449	struct iwl_multicast_key_data bigtk[WOWLAN_BIGTK_KEYS_NUM];
1450
1451	u8 *wake_packet;
1452};
1453
1454static void iwl_mvm_report_wakeup_reasons(struct iwl_mvm *mvm,
1455					  struct ieee80211_vif *vif,
1456					  struct iwl_wowlan_status_data *status)
1457{
1458	struct sk_buff *pkt = NULL;
1459	struct cfg80211_wowlan_wakeup wakeup = {
1460		.pattern_idx = -1,
1461	};
1462	struct cfg80211_wowlan_wakeup *wakeup_report = &wakeup;
1463	u32 reasons = status->wakeup_reasons;
1464
1465	if (reasons == IWL_WOWLAN_WAKEUP_BY_NON_WIRELESS) {
1466		wakeup_report = NULL;
1467		goto report;
1468	}
1469
1470	pm_wakeup_event(mvm->dev, 0);
1471
1472	if (reasons & IWL_WOWLAN_WAKEUP_BY_MAGIC_PACKET)
1473		wakeup.magic_pkt = true;
1474
1475	if (reasons & IWL_WOWLAN_WAKEUP_BY_PATTERN)
1476		wakeup.pattern_idx =
1477			status->pattern_number;
1478
1479	if (reasons & (IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_MISSED_BEACON |
1480		       IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_DEAUTH |
1481		       IWL_WOWLAN_WAKEUP_BY_GTK_REKEY_FAILURE))
1482		wakeup.disconnect = true;
1483
1484	if (reasons & IWL_WOWLAN_WAKEUP_BY_GTK_REKEY_FAILURE)
1485		wakeup.gtk_rekey_failure = true;
1486
1487	if (reasons & IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED)
1488		wakeup.rfkill_release = true;
1489
1490	if (reasons & IWL_WOWLAN_WAKEUP_BY_EAPOL_REQUEST)
1491		wakeup.eap_identity_req = true;
1492
1493	if (reasons & IWL_WOWLAN_WAKEUP_BY_FOUR_WAY_HANDSHAKE)
1494		wakeup.four_way_handshake = true;
1495
1496	if (reasons & IWL_WOWLAN_WAKEUP_BY_REM_WAKE_LINK_LOSS)
1497		wakeup.tcp_connlost = true;
1498
1499	if (reasons & IWL_WOWLAN_WAKEUP_BY_REM_WAKE_SIGNATURE_TABLE)
1500		wakeup.tcp_nomoretokens = true;
1501
1502	if (reasons & IWL_WOWLAN_WAKEUP_BY_REM_WAKE_WAKEUP_PACKET)
1503		wakeup.tcp_match = true;
1504
1505	if (reasons & IWL_WAKEUP_BY_11W_UNPROTECTED_DEAUTH_OR_DISASSOC)
1506		wakeup.unprot_deauth_disassoc = true;
1507
1508	if (status->wake_packet) {
1509		int pktsize = status->wake_packet_bufsize;
1510		int pktlen = status->wake_packet_length;
1511		const u8 *pktdata = status->wake_packet;
1512		const struct ieee80211_hdr *hdr = (const void *)pktdata;
1513		int truncated = pktlen - pktsize;
1514
1515		/* this would be a firmware bug */
1516		if (WARN_ON_ONCE(truncated < 0))
1517			truncated = 0;
1518
1519		if (ieee80211_is_data(hdr->frame_control)) {
1520			int hdrlen = ieee80211_hdrlen(hdr->frame_control);
1521			int ivlen = 0, icvlen = 4; /* also FCS */
1522
1523			pkt = alloc_skb(pktsize, GFP_KERNEL);
1524			if (!pkt)
1525				goto report;
1526
1527			skb_put_data(pkt, pktdata, hdrlen);
1528			pktdata += hdrlen;
1529			pktsize -= hdrlen;
1530
1531			if (ieee80211_has_protected(hdr->frame_control)) {
1532				/*
1533				 * This is unlocked and using gtk_i(c)vlen,
1534				 * but since everything is under RTNL still
1535				 * that's not really a problem - changing
1536				 * it would be difficult.
1537				 */
1538				if (is_multicast_ether_addr(hdr->addr1)) {
1539					ivlen = mvm->gtk_ivlen;
1540					icvlen += mvm->gtk_icvlen;
1541				} else {
1542					ivlen = mvm->ptk_ivlen;
1543					icvlen += mvm->ptk_icvlen;
1544				}
1545			}
1546
1547			/* if truncated, FCS/ICV is (partially) gone */
1548			if (truncated >= icvlen) {
1549				icvlen = 0;
1550				truncated -= icvlen;
1551			} else {
1552				icvlen -= truncated;
1553				truncated = 0;
1554			}
1555
1556			pktsize -= ivlen + icvlen;
1557			pktdata += ivlen;
1558
1559			skb_put_data(pkt, pktdata, pktsize);
1560
1561			if (ieee80211_data_to_8023(pkt, vif->addr, vif->type))
1562				goto report;
1563			wakeup.packet = pkt->data;
1564			wakeup.packet_present_len = pkt->len;
1565			wakeup.packet_len = pkt->len - truncated;
1566			wakeup.packet_80211 = false;
1567		} else {
1568			int fcslen = 4;
1569
1570			if (truncated >= 4) {
1571				truncated -= 4;
1572				fcslen = 0;
1573			} else {
1574				fcslen -= truncated;
1575				truncated = 0;
1576			}
1577			pktsize -= fcslen;
1578			wakeup.packet = status->wake_packet;
1579			wakeup.packet_present_len = pktsize;
1580			wakeup.packet_len = pktlen - truncated;
1581			wakeup.packet_80211 = true;
1582		}
1583	}
1584
1585 report:
1586	ieee80211_report_wowlan_wakeup(vif, wakeup_report, GFP_KERNEL);
1587	kfree_skb(pkt);
1588}
1589
1590static void iwl_mvm_le64_to_aes_seq(__le64 le_pn, struct ieee80211_key_seq *seq)
1591{
1592	u64 pn = le64_to_cpu(le_pn);
1593
1594	seq->ccmp.pn[0] = pn >> 40;
1595	seq->ccmp.pn[1] = pn >> 32;
1596	seq->ccmp.pn[2] = pn >> 24;
1597	seq->ccmp.pn[3] = pn >> 16;
1598	seq->ccmp.pn[4] = pn >> 8;
1599	seq->ccmp.pn[5] = pn;
1600}
1601
1602static void iwl_mvm_aes_sc_to_seq(struct aes_sc *sc,
1603				  struct ieee80211_key_seq *seq)
1604{
1605	iwl_mvm_le64_to_aes_seq(sc->pn, seq);
1606}
1607
1608static void iwl_mvm_le64_to_tkip_seq(__le64 le_pn, struct ieee80211_key_seq *seq)
1609{
1610	u64 pn = le64_to_cpu(le_pn);
1611
1612	seq->tkip.iv16 = (u16)pn;
1613	seq->tkip.iv32 = (u32)(pn >> 16);
1614}
1615
1616static void iwl_mvm_tkip_sc_to_seq(struct tkip_sc *sc,
1617				   struct ieee80211_key_seq *seq)
1618{
1619	seq->tkip.iv32 = le32_to_cpu(sc->iv32);
1620	seq->tkip.iv16 = le16_to_cpu(sc->iv16);
1621}
1622
1623static void iwl_mvm_set_key_rx_seq_tids(struct ieee80211_key_conf *key,
1624					struct ieee80211_key_seq *seq)
1625{
1626	int tid;
1627
1628	for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++)
1629		ieee80211_set_key_rx_seq(key, tid, &seq[tid]);
1630}
1631
1632static void iwl_mvm_set_aes_ptk_rx_seq(struct iwl_mvm *mvm,
1633				       struct iwl_wowlan_status_data *status,
1634				       struct ieee80211_sta *sta,
1635				       struct ieee80211_key_conf *key)
1636{
1637	struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
1638	struct iwl_mvm_key_pn *ptk_pn;
1639	int tid;
1640
1641	iwl_mvm_set_key_rx_seq_tids(key, status->ptk.aes.seq);
1642
1643	if (!iwl_mvm_has_new_rx_api(mvm))
1644		return;
1645
1646
1647	rcu_read_lock();
1648	ptk_pn = rcu_dereference(mvmsta->ptk_pn[key->keyidx]);
1649	if (WARN_ON(!ptk_pn)) {
1650		rcu_read_unlock();
1651		return;
1652	}
1653
1654	for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++) {
1655		int i;
1656
1657		for (i = 1; i < mvm->trans->info.num_rxqs; i++)
1658			memcpy(ptk_pn->q[i].pn[tid],
1659			       status->ptk.aes.seq[tid].ccmp.pn,
1660			       IEEE80211_CCMP_PN_LEN);
1661	}
1662	rcu_read_unlock();
1663}
1664
1665static void iwl_mvm_convert_key_counters(struct iwl_wowlan_status_data *status,
1666					 union iwl_all_tsc_rsc *sc, u8 key_idx)
1667{
1668	int i;
1669
1670	BUILD_BUG_ON(IWL_MAX_TID_COUNT > IWL_MAX_TID_COUNT);
1671	BUILD_BUG_ON(IWL_MAX_TID_COUNT > IWL_NUM_RSC);
1672
1673	/* GTK RX counters */
1674	for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
1675		iwl_mvm_tkip_sc_to_seq(&sc->tkip.multicast_rsc[i],
1676				       &status->gtk_seq[0].tkip.seq[i]);
1677		iwl_mvm_aes_sc_to_seq(&sc->aes.multicast_rsc[i],
1678				      &status->gtk_seq[0].aes.seq[i]);
1679	}
1680	status->gtk_seq[0].valid = true;
1681	status->gtk_seq[0].key_id = key_idx;
1682
1683	/* PTK TX counter */
1684	status->ptk.tkip.tx_pn = (u64)le16_to_cpu(sc->tkip.tsc.iv16) |
1685				 ((u64)le32_to_cpu(sc->tkip.tsc.iv32) << 16);
1686	status->ptk.aes.tx_pn = le64_to_cpu(sc->aes.tsc.pn);
1687
1688	/* PTK RX counters */
1689	for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
1690		iwl_mvm_tkip_sc_to_seq(&sc->tkip.unicast_rsc[i],
1691				       &status->ptk.tkip.seq[i]);
1692		iwl_mvm_aes_sc_to_seq(&sc->aes.unicast_rsc[i],
1693				      &status->ptk.aes.seq[i]);
1694	}
1695}
1696
1697static void
1698iwl_mvm_convert_key_counters_v5_gtk_seq(struct iwl_wowlan_status_data *status,
1699					struct iwl_wowlan_all_rsc_tsc_v5 *sc,
1700					unsigned int idx, unsigned int key_id)
1701{
1702	int tid;
1703
1704	for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++) {
1705		iwl_mvm_le64_to_tkip_seq(sc->mcast_rsc[idx][tid],
1706					 &status->gtk_seq[idx].tkip.seq[tid]);
1707		iwl_mvm_le64_to_aes_seq(sc->mcast_rsc[idx][tid],
1708					&status->gtk_seq[idx].aes.seq[tid]);
1709	}
1710
1711	status->gtk_seq[idx].valid = true;
1712	status->gtk_seq[idx].key_id = key_id;
1713}
1714
1715static void
1716iwl_mvm_convert_key_counters_v5(struct iwl_wowlan_status_data *status,
1717				struct iwl_wowlan_all_rsc_tsc_v5 *sc)
1718{
1719	int i, tid;
1720
1721	BUILD_BUG_ON(IWL_MAX_TID_COUNT > IWL_MAX_TID_COUNT);
1722	BUILD_BUG_ON(IWL_MAX_TID_COUNT > IWL_NUM_RSC);
1723	BUILD_BUG_ON(ARRAY_SIZE(sc->mcast_rsc) != ARRAY_SIZE(status->gtk_seq));
1724
1725	/* GTK RX counters */
1726	for (i = 0; i < ARRAY_SIZE(sc->mcast_key_id_map); i++) {
1727		u8 entry = sc->mcast_key_id_map[i];
1728
1729		if (entry < ARRAY_SIZE(sc->mcast_rsc))
1730			iwl_mvm_convert_key_counters_v5_gtk_seq(status, sc,
1731								entry, i);
1732	}
1733
1734	/* PTK TX counters not needed, assigned in device */
1735
1736	/* PTK RX counters */
1737	for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++) {
1738		iwl_mvm_le64_to_tkip_seq(sc->ucast_rsc[tid],
1739					 &status->ptk.tkip.seq[tid]);
1740		iwl_mvm_le64_to_aes_seq(sc->ucast_rsc[tid],
1741					&status->ptk.aes.seq[tid]);
1742	}
1743}
1744
1745static void iwl_mvm_set_key_rx_seq_idx(struct ieee80211_key_conf *key,
1746				       struct iwl_wowlan_status_data *status,
1747				       int idx)
1748{
1749	switch (key->cipher) {
1750	case WLAN_CIPHER_SUITE_CCMP:
1751	case WLAN_CIPHER_SUITE_GCMP:
1752	case WLAN_CIPHER_SUITE_GCMP_256:
1753		iwl_mvm_set_key_rx_seq_tids(key, status->gtk_seq[idx].aes.seq);
1754		break;
1755	case WLAN_CIPHER_SUITE_TKIP:
1756		iwl_mvm_set_key_rx_seq_tids(key, status->gtk_seq[idx].tkip.seq);
1757		break;
1758	default:
1759		WARN_ON(1);
1760	}
1761}
1762
1763static void iwl_mvm_set_key_rx_seq(struct ieee80211_key_conf *key,
1764				   struct iwl_wowlan_status_data *status)
1765{
1766	int i;
1767
1768	for (i = 0; i < ARRAY_SIZE(status->gtk_seq); i++) {
1769		if (!status->gtk_seq[i].valid)
1770			continue;
1771
1772		if (status->gtk_seq[i].key_id == key->keyidx)
1773			iwl_mvm_set_key_rx_seq_idx(key, status, i);
1774	}
1775}
1776
1777struct iwl_mvm_d3_gtk_iter_data {
1778	struct iwl_mvm *mvm;
1779	struct iwl_wowlan_status_data *status;
1780};
1781
1782static void
1783iwl_mvm_d3_set_igtk_bigtk_ipn(const struct iwl_multicast_key_data *key,
1784			      struct ieee80211_key_seq *seq, u32 cipher)
1785{
1786	switch (cipher) {
1787	case WLAN_CIPHER_SUITE_BIP_GMAC_128:
1788	case WLAN_CIPHER_SUITE_BIP_GMAC_256:
1789		BUILD_BUG_ON(sizeof(seq->aes_gmac.pn) != sizeof(key->ipn));
1790		memcpy(seq->aes_gmac.pn, key->ipn, sizeof(seq->aes_gmac.pn));
1791		break;
1792	case WLAN_CIPHER_SUITE_BIP_CMAC_256:
1793	case WLAN_CIPHER_SUITE_AES_CMAC:
1794		BUILD_BUG_ON(sizeof(seq->aes_cmac.pn) != sizeof(key->ipn));
1795		memcpy(seq->aes_cmac.pn, key->ipn, sizeof(seq->aes_cmac.pn));
1796		break;
1797	default:
1798		WARN_ON(1);
1799	}
1800}
1801
1802static void
1803iwl_mvm_d3_update_igtk_bigtk(struct iwl_wowlan_status_data *status,
1804			     struct ieee80211_key_conf *key,
1805			     struct iwl_multicast_key_data *key_data)
1806{
1807	struct ieee80211_key_seq seq;
1808
1809	iwl_mvm_d3_set_igtk_bigtk_ipn(key_data, &seq, key->cipher);
1810	ieee80211_set_key_rx_seq(key, 0, &seq);
1811}
1812
1813static void iwl_mvm_d3_update_keys(struct ieee80211_hw *hw,
1814				   struct ieee80211_vif *vif,
1815				   struct ieee80211_sta *sta,
1816				   struct ieee80211_key_conf *key,
1817				   void *_data)
1818{
1819	struct iwl_mvm_d3_gtk_iter_data *data = _data;
1820	struct iwl_wowlan_status_data *status = data->status;
1821	s8 keyidx;
1822	int link_id = vif->active_links ? __ffs(vif->active_links) : -1;
1823
1824	if (link_id >= 0 && key->link_id >= 0 && link_id != key->link_id)
1825		return;
1826
1827	switch (key->cipher) {
1828	case WLAN_CIPHER_SUITE_WEP40:
1829	case WLAN_CIPHER_SUITE_WEP104:
1830		/* ignore WEP completely, nothing to do */
1831		return;
1832	case WLAN_CIPHER_SUITE_CCMP:
1833	case WLAN_CIPHER_SUITE_GCMP:
1834	case WLAN_CIPHER_SUITE_GCMP_256:
1835		if (sta) {
1836			atomic64_set(&key->tx_pn, status->ptk.aes.tx_pn);
1837			iwl_mvm_set_aes_ptk_rx_seq(data->mvm, status, sta, key);
1838			return;
1839		}
1840		fallthrough;
1841	case WLAN_CIPHER_SUITE_TKIP:
1842		if (sta) {
1843			atomic64_set(&key->tx_pn, status->ptk.tkip.tx_pn);
1844			iwl_mvm_set_key_rx_seq_tids(key, status->ptk.tkip.seq);
1845			return;
1846		}
1847		keyidx = key->keyidx;
1848		/*
1849		 * Update the seq even if there was a rekey. If there was a
1850		 * rekey, we will update again after replacing the key
1851		 */
1852		if ((status->gtk[0].len && keyidx == status->gtk[0].id) ||
1853		    (status->gtk[1].len && keyidx == status->gtk[1].id))
1854			iwl_mvm_set_key_rx_seq(key, status);
1855		break;
1856	case WLAN_CIPHER_SUITE_BIP_GMAC_128:
1857	case WLAN_CIPHER_SUITE_BIP_GMAC_256:
1858	case WLAN_CIPHER_SUITE_BIP_CMAC_256:
1859	case WLAN_CIPHER_SUITE_AES_CMAC:
1860		if (key->keyidx == 4 || key->keyidx == 5) {
1861			iwl_mvm_d3_update_igtk_bigtk(status, key,
1862						     &status->igtk);
1863		}
1864		if (key->keyidx == 6 || key->keyidx == 7) {
1865			u8 idx = key->keyidx == status->bigtk[1].id;
1866
1867			iwl_mvm_d3_update_igtk_bigtk(status, key,
1868						     &status->bigtk[idx]);
1869		}
1870	}
1871}
1872
1873static bool iwl_mvm_gtk_rekey(struct iwl_wowlan_status_data *status,
1874			      struct ieee80211_vif *vif,
1875			      struct iwl_mvm *mvm)
1876{
1877	int i, j;
1878	struct ieee80211_key_conf *key;
1879	int link_id = vif->active_links ? __ffs(vif->active_links) : -1;
1880
1881	for (i = 0; i < ARRAY_SIZE(status->gtk); i++) {
1882		if (!status->gtk[i].len)
1883			continue;
1884
1885		IWL_DEBUG_WOWLAN(mvm,
1886				 "Received from FW GTK: key index %d\n",
1887				 status->gtk[i].id);
1888
1889		key = ieee80211_gtk_rekey_add(vif, status->gtk[i].id,
1890					      status->gtk[i].key,
1891					      sizeof(status->gtk[i].key),
1892					      link_id);
1893		if (IS_ERR(key)) {
1894			/* FW may send also the old keys */
1895			if (PTR_ERR(key) == -EALREADY)
1896				continue;
1897			return false;
1898		}
1899
1900		for (j = 0; j < ARRAY_SIZE(status->gtk_seq); j++) {
1901			if (!status->gtk_seq[j].valid ||
1902			    status->gtk_seq[j].key_id != key->keyidx)
1903				continue;
1904			iwl_mvm_set_key_rx_seq_idx(key, status, j);
1905			break;
1906		}
1907		WARN_ON(j == ARRAY_SIZE(status->gtk_seq));
1908	}
1909
1910	return true;
1911}
1912
1913static bool
1914iwl_mvm_d3_igtk_bigtk_rekey_add(struct iwl_wowlan_status_data *status,
1915				struct ieee80211_vif *vif,
1916				struct iwl_multicast_key_data *key_data)
1917{
1918	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1919	struct ieee80211_key_conf *key_config;
1920	struct ieee80211_key_seq seq;
1921	int link_id = vif->active_links ? __ffs(vif->active_links) : -1;
1922	s8 keyidx = key_data->id;
1923
1924	if (!key_data->len)
1925		return true;
1926
1927	key_config = ieee80211_gtk_rekey_add(vif, keyidx, key_data->key,
1928					     sizeof(key_data->key), link_id);
1929	if (IS_ERR(key_config)) {
1930		/* FW may send also the old keys */
1931		return PTR_ERR(key_config) == -EALREADY;
1932	}
1933
1934	iwl_mvm_d3_set_igtk_bigtk_ipn(key_data, &seq, key_config->cipher);
1935	ieee80211_set_key_rx_seq(key_config, 0, &seq);
1936
1937	if (keyidx == 4 || keyidx == 5) {
1938		struct iwl_mvm_vif_link_info *mvm_link;
1939
1940		link_id = link_id < 0 ? 0 : link_id;
1941		mvm_link = mvmvif->link[link_id];
1942		if (mvm_link->igtk)
1943			mvm_link->igtk->hw_key_idx = STA_KEY_IDX_INVALID;
1944		mvm_link->igtk = key_config;
1945	}
1946
1947	if (vif->type == NL80211_IFTYPE_STATION && (keyidx == 6 || keyidx == 7))
1948		rcu_assign_pointer(mvmvif->bcn_prot.keys[keyidx - 6],
1949				   key_config);
1950
1951	return true;
1952}
1953
1954static int iwl_mvm_lookup_wowlan_status_ver(struct iwl_mvm *mvm)
1955{
1956	u8 notif_ver;
1957
1958	if (!fw_has_api(&mvm->fw->ucode_capa,
1959			IWL_UCODE_TLV_API_WOWLAN_KEY_MATERIAL))
1960		return 6;
1961
1962	/* default to 7 (when we have IWL_UCODE_TLV_API_WOWLAN_KEY_MATERIAL) */
1963	notif_ver = iwl_fw_lookup_notif_ver(mvm->fw, LONG_GROUP,
1964					    WOWLAN_GET_STATUSES, 0);
1965	if (!notif_ver)
1966		notif_ver = iwl_fw_lookup_notif_ver(mvm->fw, LEGACY_GROUP,
1967						    WOWLAN_GET_STATUSES, 7);
1968
1969	return notif_ver;
1970}
1971
1972static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm,
1973					  struct ieee80211_vif *vif,
1974					  struct iwl_wowlan_status_data *status)
1975{
1976	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1977	struct iwl_mvm_d3_gtk_iter_data gtkdata = {
1978		.mvm = mvm,
1979		.status = status,
1980	};
1981	int i;
1982	u32 disconnection_reasons =
1983		IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_MISSED_BEACON |
1984		IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_DEAUTH;
1985
1986	if (!status || !vif->bss_conf.bssid)
1987		return false;
1988	/*
1989	 * invalidate all other GTKs that might still exist and update
1990	 * the one that we used
1991	 */
1992	ieee80211_iter_keys(mvm->hw, vif,
1993			    iwl_mvm_d3_update_keys, &gtkdata);
1994
1995	if (status->num_of_gtk_rekeys) {
1996		__be64 replay_ctr = cpu_to_be64(status->replay_ctr);
1997
1998		IWL_DEBUG_WOWLAN(mvm, "num of GTK rekeying %d\n",
1999				 status->num_of_gtk_rekeys);
2000
2001		if (!iwl_mvm_gtk_rekey(status, vif, mvm))
2002			return false;
2003
2004		if (!iwl_mvm_d3_igtk_bigtk_rekey_add(status, vif,
2005						     &status->igtk))
2006			return false;
2007
2008		for (i = 0; i < ARRAY_SIZE(status->bigtk); i++) {
2009			if (!iwl_mvm_d3_igtk_bigtk_rekey_add(status, vif,
2010							     &status->bigtk[i]))
2011				return false;
2012		}
2013
2014		ieee80211_gtk_rekey_notify(vif, vif->bss_conf.bssid,
2015					   (void *)&replay_ctr, GFP_KERNEL);
2016	}
2017
2018	if (iwl_fw_lookup_notif_ver(mvm->fw, LONG_GROUP,
2019				    WOWLAN_GET_STATUSES,
2020				    IWL_FW_CMD_VER_UNKNOWN) < 10) {
2021		mvmvif->seqno_valid = true;
2022		/* +0x10 because the set API expects next-to-use, not last-used */
2023		mvmvif->seqno = status->non_qos_seq_ctr + 0x10;
2024	}
2025
2026	if (status->wakeup_reasons & disconnection_reasons)
2027		return false;
2028
2029	return true;
2030}
2031
2032static void iwl_mvm_convert_gtk_v2(struct iwl_wowlan_status_data *status,
2033				   struct iwl_wowlan_gtk_status_v2 *data)
2034{
2035	BUILD_BUG_ON(sizeof(status->gtk[0].key) < sizeof(data->key));
2036	BUILD_BUG_ON(NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY +
2037		     sizeof(data->tkip_mic_key) >
2038		     sizeof(status->gtk[0].key));
2039
2040	status->gtk[0].len = data->key_len;
2041	status->gtk[0].flags = data->key_flags;
2042	status->gtk[0].id = status->gtk[0].flags & IWL_WOWLAN_GTK_IDX_MASK;
2043
2044	memcpy(status->gtk[0].key, data->key, sizeof(data->key));
2045
2046	/* if it's as long as the TKIP encryption key, copy MIC key */
2047	if (status->gtk[0].len == NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY)
2048		memcpy(status->gtk[0].key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY,
2049		       data->tkip_mic_key, sizeof(data->tkip_mic_key));
2050}
2051
2052static void iwl_mvm_convert_gtk_v3(struct iwl_wowlan_status_data *status,
2053				   struct iwl_wowlan_gtk_status_v3 *data)
2054{
2055	int data_idx, status_idx = 0;
2056
2057	BUILD_BUG_ON(sizeof(status->gtk[0].key) < sizeof(data[0].key));
2058	BUILD_BUG_ON(NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY +
2059		     sizeof(data[0].tkip_mic_key) >
2060		     sizeof(status->gtk[0].key));
2061	BUILD_BUG_ON(ARRAY_SIZE(status->gtk) < WOWLAN_GTK_KEYS_NUM);
2062	for (data_idx = 0; data_idx < ARRAY_SIZE(status->gtk); data_idx++) {
2063		if (!(data[data_idx].key_len))
2064			continue;
2065		status->gtk[status_idx].len = data[data_idx].key_len;
2066		status->gtk[status_idx].flags = data[data_idx].key_flags;
2067		status->gtk[status_idx].id = status->gtk[status_idx].flags &
2068				    IWL_WOWLAN_GTK_IDX_MASK;
2069
2070		memcpy(status->gtk[status_idx].key, data[data_idx].key,
2071		       sizeof(data[data_idx].key));
2072
2073		/* if it's as long as the TKIP encryption key, copy MIC key */
2074		if (status->gtk[status_idx].len ==
2075		    NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY)
2076			memcpy(status->gtk[status_idx].key +
2077			       NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY,
2078			       data[data_idx].tkip_mic_key,
2079			       sizeof(data[data_idx].tkip_mic_key));
2080		status_idx++;
2081	}
2082}
2083
2084static void iwl_mvm_convert_igtk(struct iwl_wowlan_status_data *status,
2085				 struct iwl_wowlan_igtk_status_v1 *data)
2086{
2087	int i;
2088
2089	BUILD_BUG_ON(sizeof(status->igtk.key) < sizeof(data->key));
2090	BUILD_BUG_ON(sizeof(status->igtk.ipn) != sizeof(data->ipn));
2091
2092	if (!data->key_len)
2093		return;
2094
2095	status->igtk.len = data->key_len;
2096	status->igtk.flags = data->key_flags;
2097	status->igtk.id = u32_get_bits(data->key_flags,
2098				       IWL_WOWLAN_IGTK_BIGTK_IDX_MASK)
2099		+ WOWLAN_IGTK_MIN_INDEX;
2100
2101	memcpy(status->igtk.key, data->key, sizeof(data->key));
2102
2103	/* mac80211 expects big endian for memcmp() to work, convert */
2104	for (i = 0; i < sizeof(data->ipn); i++)
2105		status->igtk.ipn[i] = data->ipn[sizeof(data->ipn) - i - 1];
2106}
2107
2108static void iwl_mvm_convert_bigtk(struct iwl_wowlan_status_data *status,
2109				  const struct iwl_wowlan_igtk_status_v1 *data)
2110{
2111	int data_idx, status_idx = 0;
2112
2113	BUILD_BUG_ON(ARRAY_SIZE(status->bigtk) < WOWLAN_BIGTK_KEYS_NUM);
2114
2115	for (data_idx = 0; data_idx < WOWLAN_BIGTK_KEYS_NUM; data_idx++) {
2116		if (!data[data_idx].key_len)
2117			continue;
2118
2119		status->bigtk[status_idx].len = data[data_idx].key_len;
2120		status->bigtk[status_idx].flags = data[data_idx].key_flags;
2121		status->bigtk[status_idx].id =
2122			u32_get_bits(data[data_idx].key_flags,
2123				     IWL_WOWLAN_IGTK_BIGTK_IDX_MASK)
2124			+ WOWLAN_BIGTK_MIN_INDEX;
2125
2126		BUILD_BUG_ON(sizeof(status->bigtk[status_idx].key) <
2127			     sizeof(data[data_idx].key));
2128		BUILD_BUG_ON(sizeof(status->bigtk[status_idx].ipn) <
2129			     sizeof(data[data_idx].ipn));
2130
2131		memcpy(status->bigtk[status_idx].key, data[data_idx].key,
2132		       sizeof(data[data_idx].key));
2133		memcpy(status->bigtk[status_idx].ipn, data[data_idx].ipn,
2134		       sizeof(data[data_idx].ipn));
2135		status_idx++;
2136	}
2137}
2138
2139static void iwl_mvm_parse_wowlan_info_notif(struct iwl_mvm *mvm,
2140					    struct iwl_wowlan_info_notif_v5 *data,
2141					    struct iwl_wowlan_status_data *status,
2142					    u32 len)
2143{
2144	if (IWL_FW_CHECK(mvm, data->num_mlo_link_keys,
2145			 "MLO is not supported, shouldn't receive MLO keys\n"))
2146		return;
2147
2148	if (len < sizeof(*data)) {
2149		IWL_ERR(mvm, "Invalid WoWLAN info notification!\n");
2150		status = NULL;
2151		return;
2152	}
2153
2154	if (mvm->fast_resume)
2155		return;
2156
2157	iwl_mvm_convert_key_counters_v5(status, &data->gtk[0].sc);
2158	iwl_mvm_convert_gtk_v3(status, data->gtk);
2159	iwl_mvm_convert_igtk(status, &data->igtk[0]);
2160	iwl_mvm_convert_bigtk(status, data->bigtk);
2161	status->replay_ctr = le64_to_cpu(data->replay_ctr);
2162	status->pattern_number = le16_to_cpu(data->pattern_number);
2163	status->tid_offloaded_tx = data->tid_offloaded_tx;
2164	if (IWL_FW_CHECK(mvm,
2165			 data->tid_offloaded_tx >=
2166			 ARRAY_SIZE(status->qos_seq_ctr),
2167			 "tid_offloaded_tx is out of bound %d\n",
2168			 data->tid_offloaded_tx))
2169		data->tid_offloaded_tx = 0;
2170	status->qos_seq_ctr[data->tid_offloaded_tx] =
2171		le16_to_cpu(data->qos_seq_ctr);
2172	status->wakeup_reasons = le32_to_cpu(data->wakeup_reasons);
2173	status->num_of_gtk_rekeys =
2174		le32_to_cpu(data->num_of_gtk_rekeys);
2175	status->received_beacons = le32_to_cpu(data->received_beacons);
2176	status->tid_tear_down = data->tid_tear_down;
2177}
2178
2179static void
2180iwl_mvm_parse_wowlan_info_notif_v3(struct iwl_mvm *mvm,
2181				   struct iwl_wowlan_info_notif_v3 *data,
2182				   struct iwl_wowlan_status_data *status,
2183				   u32 len)
2184{
2185	u32 i;
2186
2187	if (len < sizeof(*data)) {
2188		IWL_ERR(mvm, "Invalid WoWLAN info notification!\n");
2189		status = NULL;
2190		return;
2191	}
2192
2193	if (mvm->fast_resume)
2194		return;
2195
2196	iwl_mvm_convert_key_counters_v5(status, &data->gtk[0].sc);
2197	iwl_mvm_convert_gtk_v3(status, data->gtk);
2198	iwl_mvm_convert_igtk(status, &data->igtk[0]);
2199	iwl_mvm_convert_bigtk(status, data->bigtk);
2200	status->replay_ctr = le64_to_cpu(data->replay_ctr);
2201	status->pattern_number = le16_to_cpu(data->pattern_number);
2202	for (i = 0; i < IWL_MAX_TID_COUNT; i++)
2203		status->qos_seq_ctr[i] =
2204			le16_to_cpu(data->qos_seq_ctr[i]);
2205	status->wakeup_reasons = le32_to_cpu(data->wakeup_reasons);
2206	status->num_of_gtk_rekeys =
2207		le32_to_cpu(data->num_of_gtk_rekeys);
2208	status->received_beacons = le32_to_cpu(data->received_beacons);
2209	status->tid_tear_down = data->tid_tear_down;
2210}
2211
2212static void
2213iwl_mvm_parse_wowlan_info_notif_v1(struct iwl_mvm *mvm,
2214				   struct iwl_wowlan_info_notif_v1 *data,
2215				   struct iwl_wowlan_status_data *status,
2216				   u32 len)
2217{
2218	u32 i;
2219
2220	if (len < sizeof(*data)) {
2221		IWL_ERR(mvm, "Invalid WoWLAN info notification!\n");
2222		status = NULL;
2223		return;
2224	}
2225
2226	iwl_mvm_convert_key_counters_v5(status, &data->gtk[0].sc);
2227	iwl_mvm_convert_gtk_v3(status, data->gtk);
2228	iwl_mvm_convert_igtk(status, &data->igtk[0]);
2229	status->replay_ctr = le64_to_cpu(data->replay_ctr);
2230	status->pattern_number = le16_to_cpu(data->pattern_number);
2231	for (i = 0; i < IWL_MAX_TID_COUNT; i++)
2232		status->qos_seq_ctr[i] =
2233			le16_to_cpu(data->qos_seq_ctr[i]);
2234	status->wakeup_reasons = le32_to_cpu(data->wakeup_reasons);
2235	status->num_of_gtk_rekeys =
2236		le32_to_cpu(data->num_of_gtk_rekeys);
2237	status->received_beacons = le32_to_cpu(data->received_beacons);
2238	status->tid_tear_down = data->tid_tear_down;
2239}
2240
2241/* Occasionally, templates would be nice. This is one of those times ... */
2242#define iwl_mvm_parse_wowlan_status_common(_ver)			\
2243static struct iwl_wowlan_status_data *					\
2244iwl_mvm_parse_wowlan_status_common_ ## _ver(struct iwl_mvm *mvm,	\
2245					    struct iwl_wowlan_status_ ##_ver *data,\
2246					    int len)			\
2247{									\
2248	struct iwl_wowlan_status_data *status;				\
2249	int data_size, i;						\
2250									\
2251	if (len < sizeof(*data)) {					\
2252		IWL_ERR(mvm, "Invalid WoWLAN status response!\n");	\
2253		return NULL;						\
2254	}								\
2255									\
2256	data_size = ALIGN(le32_to_cpu(data->wake_packet_bufsize), 4);	\
2257	if (len != sizeof(*data) + data_size) {				\
2258		IWL_ERR(mvm, "Invalid WoWLAN status response!\n");	\
2259		return NULL;						\
2260	}								\
2261									\
2262	status = kzalloc(sizeof(*status), GFP_KERNEL);			\
2263	if (!status)							\
2264		return NULL;						\
2265									\
2266	/* copy all the common fields */				\
2267	status->replay_ctr = le64_to_cpu(data->replay_ctr);		\
2268	status->pattern_number = le16_to_cpu(data->pattern_number);	\
2269	status->non_qos_seq_ctr = le16_to_cpu(data->non_qos_seq_ctr);	\
2270	for (i = 0; i < 8; i++)						\
2271		status->qos_seq_ctr[i] =				\
2272			le16_to_cpu(data->qos_seq_ctr[i]);		\
2273	status->wakeup_reasons = le32_to_cpu(data->wakeup_reasons);	\
2274	status->num_of_gtk_rekeys =					\
2275		le32_to_cpu(data->num_of_gtk_rekeys);			\
2276	status->received_beacons = le32_to_cpu(data->received_beacons);	\
2277	status->wake_packet_length =					\
2278		le32_to_cpu(data->wake_packet_length);			\
2279	status->wake_packet_bufsize =					\
2280		le32_to_cpu(data->wake_packet_bufsize);			\
2281	if (status->wake_packet_bufsize) {				\
2282		status->wake_packet =					\
2283			kmemdup(data->wake_packet,			\
2284				status->wake_packet_bufsize,		\
2285				GFP_KERNEL);				\
2286		if (!status->wake_packet) {				\
2287			kfree(status);					\
2288			return NULL;					\
2289		}							\
2290	} else {							\
2291		status->wake_packet = NULL;				\
2292	}								\
2293									\
2294	return status;							\
2295}
2296
2297iwl_mvm_parse_wowlan_status_common(v6)
2298iwl_mvm_parse_wowlan_status_common(v7)
2299
2300static struct iwl_wowlan_status_data *
2301iwl_mvm_send_wowlan_get_status(struct iwl_mvm *mvm, u8 sta_id)
2302{
2303	struct iwl_wowlan_status_data *status;
2304	struct iwl_wowlan_get_status_cmd get_status_cmd = {
2305		.sta_id = cpu_to_le32(sta_id),
2306	};
2307	struct iwl_host_cmd cmd = {
2308		.id = WOWLAN_GET_STATUSES,
2309		.flags = CMD_WANT_SKB,
2310		.data = { &get_status_cmd, },
2311		.len = { sizeof(get_status_cmd), },
2312	};
2313	int ret, len;
2314	u8 notif_ver;
2315	u8 cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, cmd.id,
2316					   IWL_FW_CMD_VER_UNKNOWN);
2317
2318	if (cmd_ver == IWL_FW_CMD_VER_UNKNOWN)
2319		cmd.len[0] = 0;
2320
2321	lockdep_assert_held(&mvm->mutex);
2322
2323	ret = iwl_mvm_send_cmd(mvm, &cmd);
2324	if (ret) {
2325		IWL_ERR(mvm, "failed to query wakeup status (%d)\n", ret);
2326		return ERR_PTR(ret);
2327	}
2328
2329	len = iwl_rx_packet_payload_len(cmd.resp_pkt);
2330
2331	/* default to 7 (when we have IWL_UCODE_TLV_API_WOWLAN_KEY_MATERIAL) */
2332	notif_ver = iwl_mvm_lookup_wowlan_status_ver(mvm);
2333
2334	if (notif_ver < 7) {
2335		struct iwl_wowlan_status_v6 *v6 = (void *)cmd.resp_pkt->data;
2336
2337		status = iwl_mvm_parse_wowlan_status_common_v6(mvm, v6, len);
2338		if (!status)
2339			goto out_free_resp;
2340
2341		BUILD_BUG_ON(sizeof(v6->gtk.decrypt_key) >
2342			     sizeof(status->gtk[0].key));
2343		BUILD_BUG_ON(NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY +
2344			     sizeof(v6->gtk.tkip_mic_key) >
2345			     sizeof(status->gtk[0].key));
2346
2347		/* copy GTK info to the right place */
2348		memcpy(status->gtk[0].key, v6->gtk.decrypt_key,
2349		       sizeof(v6->gtk.decrypt_key));
2350		memcpy(status->gtk[0].key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY,
2351		       v6->gtk.tkip_mic_key,
2352		       sizeof(v6->gtk.tkip_mic_key));
2353
2354		iwl_mvm_convert_key_counters(status, &v6->gtk.rsc.all_tsc_rsc,
2355					     v6->gtk.key_index);
2356
2357		/* hardcode the key length to 16 since v6 only supports 16 */
2358		status->gtk[0].len = 16;
2359
2360		/*
2361		 * The key index only uses 2 bits (values 0 to 3) and
2362		 * we always set bit 7 which means this is the
2363		 * currently used key.
2364		 */
2365		status->gtk[0].flags = v6->gtk.key_index | BIT(7);
2366		status->gtk[0].id = v6->gtk.key_index;
2367	} else if (notif_ver == 7) {
2368		struct iwl_wowlan_status_v7 *v7 = (void *)cmd.resp_pkt->data;
2369
2370		status = iwl_mvm_parse_wowlan_status_common_v7(mvm, v7, len);
2371		if (!status)
2372			goto out_free_resp;
2373
2374		iwl_mvm_convert_key_counters(status, &v7->gtk[0].rsc.all_tsc_rsc,
2375					     v7->gtk[0].key_flags & IWL_WOWLAN_GTK_IDX_MASK);
2376		iwl_mvm_convert_gtk_v2(status, &v7->gtk[0]);
2377		iwl_mvm_convert_igtk(status, &v7->igtk[0]);
2378	} else {
2379		IWL_ERR(mvm,
2380			"Firmware advertises unknown WoWLAN status response %d!\n",
2381			notif_ver);
2382		status = NULL;
2383	}
2384
2385out_free_resp:
2386	iwl_free_resp(&cmd);
2387	return status;
2388}
2389
2390/* releases the MVM mutex */
2391static bool iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
2392					 struct ieee80211_vif *vif,
2393					 struct iwl_wowlan_status_data *status)
2394{
2395	int i;
2396	bool keep = false;
2397	struct iwl_mvm_sta *mvm_ap_sta;
2398	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
2399	int link_id = vif->active_links ? __ffs(vif->active_links) : 0;
2400	struct iwl_mvm_vif_link_info *mvm_link = mvmvif->link[link_id];
2401	int wowlan_info_ver = iwl_fw_lookup_notif_ver(mvm->fw,
2402						      PROT_OFFLOAD_GROUP,
2403						      WOWLAN_INFO_NOTIFICATION,
2404						      IWL_FW_CMD_VER_UNKNOWN);
2405
2406	if (WARN_ON(!mvm_link))
2407		goto out_unlock;
2408
2409	if (!status)
2410		goto out_unlock;
2411
2412	IWL_DEBUG_WOWLAN(mvm, "wakeup reason 0x%x\n",
2413			 status->wakeup_reasons);
2414
2415	mvm_ap_sta = iwl_mvm_sta_from_staid_protected(mvm, mvm_link->ap_sta_id);
2416	if (!mvm_ap_sta)
2417		goto out_unlock;
2418
2419	/* firmware stores last-used value, we store next value */
2420	if (wowlan_info_ver >= 5) {
2421		mvm_ap_sta->tid_data[status->tid_offloaded_tx].seq_number =
2422			status->qos_seq_ctr[status->tid_offloaded_tx] + 0x10;
2423	} else {
2424		for (i = 0; i < IWL_MAX_TID_COUNT; i++)
2425			mvm_ap_sta->tid_data[i].seq_number =
2426				status->qos_seq_ctr[i] + 0x10;
2427	}
2428
2429	if (mvm->trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_22000) {
2430		i = mvm->offload_tid;
2431		iwl_trans_set_q_ptrs(mvm->trans,
2432				     mvm_ap_sta->tid_data[i].txq_id,
2433				     mvm_ap_sta->tid_data[i].seq_number >> 4);
2434	}
2435
2436	iwl_mvm_report_wakeup_reasons(mvm, vif, status);
2437
2438	keep = iwl_mvm_setup_connection_keep(mvm, vif, status);
2439out_unlock:
2440	mutex_unlock(&mvm->mutex);
2441	return keep;
2442}
2443
2444#define ND_QUERY_BUF_LEN (sizeof(struct iwl_scan_offload_profile_match) * \
2445			  IWL_SCAN_MAX_PROFILES)
2446
2447struct iwl_mvm_nd_results {
2448	u32 matched_profiles;
2449	u8 matches[ND_QUERY_BUF_LEN];
2450};
2451
2452static int
2453iwl_mvm_netdetect_query_results(struct iwl_mvm *mvm,
2454				struct iwl_mvm_nd_results *results)
2455{
2456	struct iwl_scan_offload_match_info *query;
2457	struct iwl_host_cmd cmd = {
2458		.id = SCAN_OFFLOAD_PROFILES_QUERY_CMD,
2459		.flags = CMD_WANT_SKB,
2460	};
2461	int ret, len;
2462	size_t query_len, matches_len;
2463	int max_profiles = iwl_umac_scan_get_max_profiles(mvm->fw);
2464
2465	ret = iwl_mvm_send_cmd(mvm, &cmd);
2466	if (ret) {
2467		IWL_ERR(mvm, "failed to query matched profiles (%d)\n", ret);
2468		return ret;
2469	}
2470
2471	if (fw_has_api(&mvm->fw->ucode_capa,
2472		       IWL_UCODE_TLV_API_SCAN_OFFLOAD_CHANS)) {
2473		query_len = sizeof(struct iwl_scan_offload_match_info);
2474		matches_len = sizeof(struct iwl_scan_offload_profile_match) *
2475			max_profiles;
2476	} else {
2477		query_len = sizeof(struct iwl_scan_offload_profiles_query_v1);
2478		matches_len = sizeof(struct iwl_scan_offload_profile_match_v1) *
2479			max_profiles;
2480	}
2481
2482	len = iwl_rx_packet_payload_len(cmd.resp_pkt);
2483	if (len < query_len) {
2484		IWL_ERR(mvm, "Invalid scan offload profiles query response!\n");
2485		ret = -EIO;
2486		goto out_free_resp;
2487	}
2488
2489	query = (void *)cmd.resp_pkt->data;
2490
2491	results->matched_profiles = le32_to_cpu(query->matched_profiles);
2492	memcpy(results->matches, query->matches, matches_len);
2493
2494#ifdef CONFIG_IWLWIFI_DEBUGFS
2495	mvm->last_netdetect_scans = le32_to_cpu(query->n_scans_done);
2496#endif
2497
2498out_free_resp:
2499	iwl_free_resp(&cmd);
2500	return ret;
2501}
2502
2503static int iwl_mvm_query_num_match_chans(struct iwl_mvm *mvm,
2504					 struct iwl_mvm_nd_results *results,
2505					 int idx)
2506{
2507	int n_chans = 0, i;
2508
2509	if (fw_has_api(&mvm->fw->ucode_capa,
2510		       IWL_UCODE_TLV_API_SCAN_OFFLOAD_CHANS)) {
2511		struct iwl_scan_offload_profile_match *matches =
2512			(void *)results->matches;
2513
2514		for (i = 0; i < SCAN_OFFLOAD_MATCHING_CHANNELS_LEN; i++)
2515			n_chans += hweight8(matches[idx].matching_channels[i]);
2516	} else {
2517		struct iwl_scan_offload_profile_match_v1 *matches =
2518			(void *)results->matches;
2519
2520		for (i = 0; i < SCAN_OFFLOAD_MATCHING_CHANNELS_LEN_V1; i++)
2521			n_chans += hweight8(matches[idx].matching_channels[i]);
2522	}
2523
2524	return n_chans;
2525}
2526
2527static void iwl_mvm_query_set_freqs(struct iwl_mvm *mvm,
2528				    struct iwl_mvm_nd_results *results,
2529				    struct cfg80211_wowlan_nd_match *match,
2530				    int idx)
2531{
2532	int i;
2533	int n_channels = 0;
2534
2535	if (fw_has_api(&mvm->fw->ucode_capa,
2536		       IWL_UCODE_TLV_API_SCAN_OFFLOAD_CHANS)) {
2537		struct iwl_scan_offload_profile_match *matches =
2538			 (void *)results->matches;
2539
2540		for (i = 0; i < SCAN_OFFLOAD_MATCHING_CHANNELS_LEN * 8; i++)
2541			if (matches[idx].matching_channels[i / 8] & (BIT(i % 8)))
2542				match->channels[n_channels++] =
2543					mvm->nd_channels[i]->center_freq;
2544	} else {
2545		struct iwl_scan_offload_profile_match_v1 *matches =
2546			 (void *)results->matches;
2547
2548		for (i = 0; i < SCAN_OFFLOAD_MATCHING_CHANNELS_LEN_V1 * 8; i++)
2549			if (matches[idx].matching_channels[i / 8] & (BIT(i % 8)))
2550				match->channels[n_channels++] =
2551					mvm->nd_channels[i]->center_freq;
2552	}
2553	/* We may have ended up with fewer channels than we allocated. */
2554	match->n_channels = n_channels;
2555}
2556
2557/**
2558 * enum iwl_d3_notif - d3 notifications
2559 * @IWL_D3_NOTIF_WOWLAN_INFO: WOWLAN_INFO_NOTIF was received
2560 * @IWL_D3_NOTIF_WOWLAN_WAKE_PKT: WOWLAN_WAKE_PKT_NOTIF was received
2561 * @IWL_D3_NOTIF_PROT_OFFLOAD: PROT_OFFLOAD_NOTIF was received
2562 * @IWL_D3_ND_MATCH_INFO: OFFLOAD_MATCH_INFO_NOTIF was received
2563 * @IWL_D3_NOTIF_D3_END_NOTIF: D3_END_NOTIF was received
2564 */
2565enum iwl_d3_notif {
2566	IWL_D3_NOTIF_WOWLAN_INFO =	BIT(0),
2567	IWL_D3_NOTIF_WOWLAN_WAKE_PKT =	BIT(1),
2568	IWL_D3_NOTIF_PROT_OFFLOAD =	BIT(2),
2569	IWL_D3_ND_MATCH_INFO      =     BIT(3),
2570	IWL_D3_NOTIF_D3_END_NOTIF =	BIT(4)
2571};
2572
2573/* manage d3 resume data */
2574struct iwl_d3_data {
2575	struct iwl_wowlan_status_data *status;
2576	u32 d3_end_flags;
2577	u32 notif_expected;	/* bitmap - see &enum iwl_d3_notif */
2578	u32 notif_received;	/* bitmap - see &enum iwl_d3_notif */
2579	struct iwl_mvm_nd_results *nd_results;
2580	bool nd_results_valid;
2581};
2582
2583static void iwl_mvm_query_netdetect_reasons(struct iwl_mvm *mvm,
2584					    struct ieee80211_vif *vif,
2585					    struct iwl_d3_data *d3_data)
2586{
2587	struct cfg80211_wowlan_nd_info *net_detect = NULL;
2588	struct cfg80211_wowlan_wakeup wakeup = {
2589		.pattern_idx = -1,
2590	};
2591	struct cfg80211_wowlan_wakeup *wakeup_report = &wakeup;
2592	unsigned long matched_profiles;
2593	u32 reasons = 0;
2594	int i, n_matches, ret;
2595
2596	if (WARN_ON(!d3_data || !d3_data->status))
2597		goto out;
2598
2599	reasons = d3_data->status->wakeup_reasons;
2600
2601	if (reasons & IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED)
2602		wakeup.rfkill_release = true;
2603
2604	if (reasons != IWL_WOWLAN_WAKEUP_BY_NON_WIRELESS)
2605		goto out;
2606
2607	if (!iwl_fw_lookup_notif_ver(mvm->fw, PROT_OFFLOAD_GROUP,
2608				     WOWLAN_INFO_NOTIFICATION, 0)) {
2609		IWL_INFO(mvm, "Query FW for ND results\n");
2610		ret = iwl_mvm_netdetect_query_results(mvm, d3_data->nd_results);
2611
2612	} else {
2613		IWL_INFO(mvm, "Notification based ND results\n");
2614		ret = d3_data->nd_results_valid ? 0 : -1;
2615	}
2616
2617	if (ret || !d3_data->nd_results->matched_profiles) {
2618		wakeup_report = NULL;
2619		goto out;
2620	}
2621
2622	matched_profiles = d3_data->nd_results->matched_profiles;
2623	if (mvm->n_nd_match_sets) {
2624		n_matches = hweight_long(matched_profiles);
2625	} else {
2626		IWL_ERR(mvm, "no net detect match information available\n");
2627		n_matches = 0;
2628	}
2629
2630	net_detect = kzalloc(struct_size(net_detect, matches, n_matches),
2631			     GFP_KERNEL);
2632	if (!net_detect || !n_matches)
2633		goto out_report_nd;
2634	net_detect->n_matches = n_matches;
2635	n_matches = 0;
2636
2637	for_each_set_bit(i, &matched_profiles, mvm->n_nd_match_sets) {
2638		struct cfg80211_wowlan_nd_match *match;
2639		int idx, n_channels = 0;
2640
2641		n_channels = iwl_mvm_query_num_match_chans(mvm,
2642							   d3_data->nd_results,
2643							   i);
2644
2645		match = kzalloc(struct_size(match, channels, n_channels),
2646				GFP_KERNEL);
2647		if (!match)
2648			goto out_report_nd;
2649		match->n_channels = n_channels;
2650
2651		net_detect->matches[n_matches++] = match;
2652
2653		/* We inverted the order of the SSIDs in the scan
2654		 * request, so invert the index here.
2655		 */
2656		idx = mvm->n_nd_match_sets - i - 1;
2657		match->ssid.ssid_len = mvm->nd_match_sets[idx].ssid.ssid_len;
2658		memcpy(match->ssid.ssid, mvm->nd_match_sets[idx].ssid.ssid,
2659		       match->ssid.ssid_len);
2660
2661		if (mvm->n_nd_channels < n_channels)
2662			continue;
2663
2664		iwl_mvm_query_set_freqs(mvm, d3_data->nd_results, match, i);
2665	}
2666	/* We may have fewer matches than we allocated. */
2667	net_detect->n_matches = n_matches;
2668
2669out_report_nd:
2670	wakeup.net_detect = net_detect;
2671out:
2672	iwl_mvm_free_nd(mvm);
2673
2674	mutex_unlock(&mvm->mutex);
2675	ieee80211_report_wowlan_wakeup(vif, wakeup_report, GFP_KERNEL);
2676
2677	if (net_detect) {
2678		for (i = 0; i < net_detect->n_matches; i++)
2679			kfree(net_detect->matches[i]);
2680		kfree(net_detect);
2681	}
2682}
2683
2684static void iwl_mvm_d3_disconnect_iter(void *data, u8 *mac,
2685				       struct ieee80211_vif *vif)
2686{
2687	/* skip the one we keep connection on */
2688	if (data == vif)
2689		return;
2690
2691	if (vif->type == NL80211_IFTYPE_STATION)
2692		ieee80211_resume_disconnect(vif);
2693}
2694
2695enum rt_status {
2696	FW_ALIVE,
2697	FW_NEEDS_RESET,
2698	FW_ERROR,
2699};
2700
2701static enum rt_status iwl_mvm_check_rt_status(struct iwl_mvm *mvm,
2702					      struct ieee80211_vif *vif)
2703{
2704	u32 err_id;
2705
2706	/* check for lmac1 error */
2707	if (iwl_fwrt_read_err_table(mvm->trans,
2708				    mvm->trans->dbg.lmac_error_event_table[0],
2709				    &err_id)) {
2710		if (err_id == RF_KILL_INDICATOR_FOR_WOWLAN) {
2711			IWL_WARN(mvm, "Rfkill was toggled during suspend\n");
2712			if (vif) {
2713				struct cfg80211_wowlan_wakeup wakeup = {
2714					.rfkill_release = true,
2715				};
2716
2717				ieee80211_report_wowlan_wakeup(vif, &wakeup,
2718							       GFP_KERNEL);
2719			}
2720
2721			return FW_NEEDS_RESET;
2722		}
2723		return FW_ERROR;
2724	}
2725
2726	/* check if we have lmac2 set and check for error */
2727	if (iwl_fwrt_read_err_table(mvm->trans,
2728				    mvm->trans->dbg.lmac_error_event_table[1],
2729				    NULL))
2730		return FW_ERROR;
2731
2732	/* check for umac error */
2733	if (iwl_fwrt_read_err_table(mvm->trans,
2734				    mvm->trans->dbg.umac_error_event_table,
2735				    NULL))
2736		return FW_ERROR;
2737
2738	return FW_ALIVE;
2739}
2740
2741/*
2742 * This function assumes:
2743 *	1. The mutex is already held.
2744 *	2. The callee functions unlock the mutex.
2745 */
2746static bool
2747iwl_mvm_choose_query_wakeup_reasons(struct iwl_mvm *mvm,
2748				    struct ieee80211_vif *vif,
2749				    struct iwl_d3_data *d3_data)
2750{
2751	lockdep_assert_held(&mvm->mutex);
2752
2753	/* if FW uses status notification, status shouldn't be NULL here */
2754	if (!d3_data->status) {
2755		struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
2756		u8 sta_id = mvm->net_detect ? IWL_INVALID_STA :
2757					      mvmvif->deflink.ap_sta_id;
2758
2759		/* bug - FW with MLO has status notification */
2760		WARN_ON(ieee80211_vif_is_mld(vif));
2761
2762		d3_data->status = iwl_mvm_send_wowlan_get_status(mvm, sta_id);
2763	}
2764
2765	if (mvm->net_detect) {
2766		iwl_mvm_query_netdetect_reasons(mvm, vif, d3_data);
2767		return false;
2768	}
2769
2770	return iwl_mvm_query_wakeup_reasons(mvm, vif,
2771					    d3_data->status);
2772}
2773
2774#define IWL_WOWLAN_WAKEUP_REASON_HAS_WAKEUP_PKT (IWL_WOWLAN_WAKEUP_BY_MAGIC_PACKET | \
2775						 IWL_WOWLAN_WAKEUP_BY_PATTERN | \
2776						 IWL_WAKEUP_BY_PATTERN_IPV4_TCP_SYN |\
2777						 IWL_WAKEUP_BY_PATTERN_IPV4_TCP_SYN_WILDCARD |\
2778						 IWL_WAKEUP_BY_PATTERN_IPV6_TCP_SYN |\
2779						 IWL_WAKEUP_BY_PATTERN_IPV6_TCP_SYN_WILDCARD)
2780
2781static int iwl_mvm_wowlan_store_wake_pkt(struct iwl_mvm *mvm,
2782					 struct iwl_wowlan_wake_pkt_notif *notif,
2783					 struct iwl_wowlan_status_data *status,
2784					 u32 len)
2785{
2786	u32 data_size, packet_len = le32_to_cpu(notif->wake_packet_length);
2787
2788	if (len < sizeof(*notif)) {
2789		IWL_ERR(mvm, "Invalid WoWLAN wake packet notification!\n");
2790		return -EIO;
2791	}
2792
2793	if (WARN_ON(!status)) {
2794		IWL_ERR(mvm, "Got wake packet notification but wowlan status data is NULL\n");
2795		return -EIO;
2796	}
2797
2798	if (WARN_ON(!(status->wakeup_reasons &
2799		      IWL_WOWLAN_WAKEUP_REASON_HAS_WAKEUP_PKT))) {
2800		IWL_ERR(mvm, "Got wakeup packet but wakeup reason is %x\n",
2801			status->wakeup_reasons);
2802		return -EIO;
2803	}
2804
2805	data_size = len - offsetof(struct iwl_wowlan_wake_pkt_notif, wake_packet);
2806
2807	/* data_size got the padding from the notification, remove it. */
2808	if (packet_len < data_size)
2809		data_size = packet_len;
2810
2811	status->wake_packet = kmemdup(notif->wake_packet, data_size,
2812				      GFP_ATOMIC);
2813
2814	if (!status->wake_packet)
2815		return -ENOMEM;
2816
2817	status->wake_packet_length = packet_len;
2818	status->wake_packet_bufsize = data_size;
2819
2820	return 0;
2821}
2822
2823static void iwl_mvm_nd_match_info_handler(struct iwl_mvm *mvm,
2824					  struct iwl_d3_data *d3_data,
2825					  struct iwl_scan_offload_match_info *notif,
2826					  u32 len)
2827{
2828	struct iwl_wowlan_status_data *status = d3_data->status;
2829	struct ieee80211_vif *vif = iwl_mvm_get_bss_vif(mvm);
2830	struct iwl_mvm_nd_results *results = d3_data->nd_results;
2831	size_t i, matches_len = sizeof(struct iwl_scan_offload_profile_match) *
2832		iwl_umac_scan_get_max_profiles(mvm->fw);
2833
2834	if (IS_ERR_OR_NULL(vif))
2835		return;
2836
2837	if (len < sizeof(struct iwl_scan_offload_match_info) + matches_len) {
2838		IWL_ERR(mvm, "Invalid scan match info notification\n");
2839		return;
2840	}
2841
2842	if (!mvm->net_detect) {
2843		IWL_ERR(mvm, "Unexpected scan match info notification\n");
2844		return;
2845	}
2846
2847	if (!status || status->wakeup_reasons != IWL_WOWLAN_WAKEUP_BY_NON_WIRELESS) {
2848		IWL_ERR(mvm,
2849			"Ignore scan match info notification: no reason\n");
2850		return;
2851	}
2852
2853#ifdef CONFIG_IWLWIFI_DEBUGFS
2854	mvm->last_netdetect_scans = le32_to_cpu(notif->n_scans_done);
2855#endif
2856
2857	results->matched_profiles = le32_to_cpu(notif->matched_profiles);
2858	IWL_INFO(mvm, "number of matched profiles=%u\n",
2859		 results->matched_profiles);
2860
2861	if (results->matched_profiles) {
2862		memcpy(results->matches, notif->matches, matches_len);
2863		d3_data->nd_results_valid = true;
2864	}
2865
2866	/* no scan should be active at this point */
2867	mvm->scan_status = 0;
2868	for (i = 0; i < mvm->max_scans; i++)
2869		mvm->scan_uid_status[i] = 0;
2870}
2871
2872static bool iwl_mvm_wait_d3_notif(struct iwl_notif_wait_data *notif_wait,
2873				  struct iwl_rx_packet *pkt, void *data)
2874{
2875	struct iwl_mvm *mvm =
2876		container_of(notif_wait, struct iwl_mvm, notif_wait);
2877	struct iwl_d3_data *d3_data = data;
2878	u32 len = iwl_rx_packet_payload_len(pkt);
2879	int ret;
2880	int wowlan_info_ver = iwl_fw_lookup_notif_ver(mvm->fw,
2881						      PROT_OFFLOAD_GROUP,
2882						      WOWLAN_INFO_NOTIFICATION,
2883						      IWL_FW_CMD_VER_UNKNOWN);
2884
2885
2886	switch (WIDE_ID(pkt->hdr.group_id, pkt->hdr.cmd)) {
2887	case WIDE_ID(PROT_OFFLOAD_GROUP, WOWLAN_INFO_NOTIFICATION): {
2888
2889		if (d3_data->notif_received & IWL_D3_NOTIF_WOWLAN_INFO) {
2890			/* We might get two notifications due to dual bss */
2891			IWL_DEBUG_WOWLAN(mvm,
2892					 "Got additional wowlan info notification\n");
2893			break;
2894		}
2895
2896		if (wowlan_info_ver == 1) {
2897			struct iwl_wowlan_info_notif_v1 *notif_v1 =
2898				(void *)pkt->data;
2899
2900			iwl_mvm_parse_wowlan_info_notif_v1(mvm, notif_v1,
2901							   d3_data->status,
2902							   len);
2903		} else if (wowlan_info_ver == 3) {
2904			struct iwl_wowlan_info_notif_v3 *notif =
2905				(void *)pkt->data;
2906
2907			iwl_mvm_parse_wowlan_info_notif_v3(mvm, notif,
2908							   d3_data->status, len);
2909		} else if (wowlan_info_ver == 5) {
2910			struct iwl_wowlan_info_notif_v5 *notif =
2911				(void *)pkt->data;
2912
2913			iwl_mvm_parse_wowlan_info_notif(mvm, notif,
2914							d3_data->status, len);
2915		} else {
2916			IWL_FW_CHECK(mvm, 1,
2917				     "Firmware advertises unknown WoWLAN info notification %d!\n",
2918				     wowlan_info_ver);
2919			return false;
2920		}
2921
2922		d3_data->notif_received |= IWL_D3_NOTIF_WOWLAN_INFO;
2923
2924		if (d3_data->status &&
2925		    d3_data->status->wakeup_reasons & IWL_WOWLAN_WAKEUP_REASON_HAS_WAKEUP_PKT)
2926			/* We are supposed to get also wake packet notif */
2927			d3_data->notif_expected |= IWL_D3_NOTIF_WOWLAN_WAKE_PKT;
2928
2929		break;
2930	}
2931	case WIDE_ID(PROT_OFFLOAD_GROUP, WOWLAN_WAKE_PKT_NOTIFICATION): {
2932		struct iwl_wowlan_wake_pkt_notif *notif = (void *)pkt->data;
2933
2934		if (d3_data->notif_received & IWL_D3_NOTIF_WOWLAN_WAKE_PKT) {
2935			/* We shouldn't get two wake packet notifications */
2936			IWL_ERR(mvm,
2937				"Got additional wowlan wake packet notification\n");
2938		} else {
2939			d3_data->notif_received |= IWL_D3_NOTIF_WOWLAN_WAKE_PKT;
2940			len =  iwl_rx_packet_payload_len(pkt);
2941			ret = iwl_mvm_wowlan_store_wake_pkt(mvm, notif,
2942							    d3_data->status,
2943							    len);
2944			if (ret)
2945				IWL_ERR(mvm,
2946					"Can't parse WOWLAN_WAKE_PKT_NOTIFICATION\n");
2947		}
2948
2949		break;
2950	}
2951	case WIDE_ID(SCAN_GROUP, OFFLOAD_MATCH_INFO_NOTIF): {
2952		struct iwl_scan_offload_match_info *notif = (void *)pkt->data;
2953
2954		if (d3_data->notif_received & IWL_D3_ND_MATCH_INFO) {
2955			IWL_ERR(mvm,
2956				"Got additional netdetect match info\n");
2957			break;
2958		}
2959
2960		d3_data->notif_received |= IWL_D3_ND_MATCH_INFO;
2961
2962		/* explicitly set this in the 'expected' as well */
2963		d3_data->notif_expected |= IWL_D3_ND_MATCH_INFO;
2964
2965		len = iwl_rx_packet_payload_len(pkt);
2966		iwl_mvm_nd_match_info_handler(mvm, d3_data, notif, len);
2967		break;
2968	}
2969	case WIDE_ID(PROT_OFFLOAD_GROUP, D3_END_NOTIFICATION): {
2970		struct iwl_d3_end_notif *notif = (void *)pkt->data;
2971
2972		d3_data->d3_end_flags = __le32_to_cpu(notif->flags);
2973		d3_data->notif_received |= IWL_D3_NOTIF_D3_END_NOTIF;
2974
2975		break;
2976	}
2977	default:
2978		WARN_ON(1);
2979	}
2980
2981	return d3_data->notif_received == d3_data->notif_expected;
2982}
2983
2984static int iwl_mvm_resume_firmware(struct iwl_mvm *mvm)
2985{
2986	int ret;
2987	struct iwl_host_cmd cmd = {
2988		.id = D0I3_END_CMD,
2989		.flags = CMD_WANT_SKB,
2990	};
2991	bool reset = fw_has_capa(&mvm->fw->ucode_capa,
2992				 IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);
2993
2994	ret = iwl_trans_d3_resume(mvm->trans, !reset);
2995	if (ret)
2996		return ret;
2997
2998	/*
2999	 * We should trigger resume flow using command only for 22000 family
3000	 * AX210 and above don't need the command since they have
3001	 * the doorbell interrupt.
3002	 */
3003	if (mvm->trans->mac_cfg->device_family <= IWL_DEVICE_FAMILY_22000 &&
3004	    fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_D0I3_END_FIRST)) {
3005		ret = iwl_mvm_send_cmd(mvm, &cmd);
3006		if (ret < 0)
3007			IWL_ERR(mvm, "Failed to send D0I3_END_CMD first (%d)\n",
3008				ret);
3009	}
3010
3011	return ret;
3012}
3013
3014#define IWL_MVM_D3_NOTIF_TIMEOUT (HZ / 3)
3015
3016static int iwl_mvm_d3_notif_wait(struct iwl_mvm *mvm,
3017				 struct iwl_d3_data *d3_data)
3018{
3019	static const u16 d3_resume_notif[] = {
3020		WIDE_ID(PROT_OFFLOAD_GROUP, WOWLAN_INFO_NOTIFICATION),
3021		WIDE_ID(PROT_OFFLOAD_GROUP, WOWLAN_WAKE_PKT_NOTIFICATION),
3022		WIDE_ID(SCAN_GROUP, OFFLOAD_MATCH_INFO_NOTIF),
3023		WIDE_ID(PROT_OFFLOAD_GROUP, D3_END_NOTIFICATION)
3024	};
3025	static const u16 d3_fast_resume_notif[] = {
3026		WIDE_ID(PROT_OFFLOAD_GROUP, D3_END_NOTIFICATION)
3027	};
3028	struct iwl_notification_wait wait_d3_notif;
3029	int ret;
3030
3031	if (mvm->fast_resume)
3032		iwl_init_notification_wait(&mvm->notif_wait, &wait_d3_notif,
3033					   d3_fast_resume_notif,
3034					   ARRAY_SIZE(d3_fast_resume_notif),
3035					   iwl_mvm_wait_d3_notif, d3_data);
3036	else
3037		iwl_init_notification_wait(&mvm->notif_wait, &wait_d3_notif,
3038					   d3_resume_notif,
3039					   ARRAY_SIZE(d3_resume_notif),
3040					   iwl_mvm_wait_d3_notif, d3_data);
3041
3042	ret = iwl_mvm_resume_firmware(mvm);
3043	if (ret) {
3044		iwl_remove_notification(&mvm->notif_wait, &wait_d3_notif);
3045		return ret;
3046	}
3047
3048	return iwl_wait_notification(&mvm->notif_wait, &wait_d3_notif,
3049				     IWL_MVM_D3_NOTIF_TIMEOUT);
3050}
3051
3052static inline bool iwl_mvm_d3_resume_notif_based(struct iwl_mvm *mvm)
3053{
3054	return iwl_fw_lookup_notif_ver(mvm->fw, PROT_OFFLOAD_GROUP,
3055				       WOWLAN_INFO_NOTIFICATION, 0) &&
3056		iwl_fw_lookup_notif_ver(mvm->fw, PROT_OFFLOAD_GROUP,
3057					WOWLAN_WAKE_PKT_NOTIFICATION, 0) &&
3058		iwl_fw_lookup_notif_ver(mvm->fw, PROT_OFFLOAD_GROUP,
3059					D3_END_NOTIFICATION, 0);
3060}
3061
3062static int __iwl_mvm_resume(struct iwl_mvm *mvm)
3063{
3064	struct ieee80211_vif *vif = NULL;
3065	int ret = 1;
3066	struct iwl_mvm_nd_results results = {};
3067	struct iwl_d3_data d3_data = {
3068		.notif_expected =
3069			IWL_D3_NOTIF_WOWLAN_INFO |
3070			IWL_D3_NOTIF_D3_END_NOTIF,
3071		.nd_results_valid = false,
3072		.nd_results = &results,
3073	};
3074	bool unified_image = fw_has_capa(&mvm->fw->ucode_capa,
3075					 IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);
3076	bool d0i3_first = fw_has_capa(&mvm->fw->ucode_capa,
3077				      IWL_UCODE_TLV_CAPA_D0I3_END_FIRST);
3078	bool resume_notif_based = iwl_mvm_d3_resume_notif_based(mvm);
3079	enum rt_status rt_status;
3080	bool keep = false;
3081
3082	mutex_lock(&mvm->mutex);
3083
3084	/* Apparently, the device went away and device_powered_off() was called,
3085	 * don't even try to read the rt_status, the device is currently
3086	 * inaccessible.
3087	 */
3088	if (!test_bit(IWL_MVM_STATUS_IN_D3, &mvm->status)) {
3089		IWL_INFO(mvm,
3090			 "Can't resume, device_powered_off() was called during wowlan\n");
3091		goto err;
3092	}
3093
3094	mvm->last_reset_or_resume_time_jiffies = jiffies;
3095
3096	/* get the BSS vif pointer again */
3097	vif = iwl_mvm_get_bss_vif(mvm);
3098	if (IS_ERR_OR_NULL(vif))
3099		goto err;
3100
3101	iwl_fw_dbg_read_d3_debug_data(&mvm->fwrt);
3102
3103	rt_status = iwl_mvm_check_rt_status(mvm, vif);
3104	if (rt_status != FW_ALIVE) {
3105		iwl_trans_notify_fw_error(mvm->trans);
3106		if (rt_status == FW_ERROR) {
3107			IWL_ERR(mvm, "FW Error occurred during suspend. Restarting.\n");
3108			iwl_mvm_dump_nic_error_log(mvm);
3109			iwl_dbg_tlv_time_point(&mvm->fwrt,
3110					       IWL_FW_INI_TIME_POINT_FW_ASSERT,
3111					       NULL);
3112			iwl_fw_dbg_collect_desc(&mvm->fwrt,
3113						&iwl_dump_desc_assert,
3114						false, 0);
3115		}
3116		ret = 1;
3117		goto err;
3118	}
3119
3120	if (resume_notif_based) {
3121		d3_data.status = kzalloc(sizeof(*d3_data.status), GFP_KERNEL);
3122		if (!d3_data.status) {
3123			IWL_ERR(mvm, "Failed to allocate wowlan status\n");
3124			ret = -ENOMEM;
3125			goto err;
3126		}
3127
3128		ret = iwl_mvm_d3_notif_wait(mvm, &d3_data);
3129		if (ret)
3130			goto err;
3131	} else {
3132		ret = iwl_mvm_resume_firmware(mvm);
3133		if (ret < 0)
3134			goto err;
3135	}
3136
3137	/* when reset is required we can't send these following commands */
3138	if (d3_data.d3_end_flags & IWL_D0I3_RESET_REQUIRE)
3139		goto query_wakeup_reasons;
3140
3141	/*
3142	 * Query the current location and source from the D3 firmware so we
3143	 * can play it back when we re-intiailize the D0 firmware
3144	 */
3145	iwl_mvm_update_changed_regdom(mvm);
3146
3147	/* Re-configure PPAG settings */
3148	iwl_mvm_ppag_send_cmd(mvm);
3149
3150	if (!unified_image)
3151		/*  Re-configure default SAR profile */
3152		iwl_mvm_sar_select_profile(mvm, 1, 1);
3153
3154	if (mvm->net_detect && unified_image) {
3155		/* If this is a non-unified image, we restart the FW,
3156		 * so no need to stop the netdetect scan.  If that
3157		 * fails, continue and try to get the wake-up reasons,
3158		 * but trigger a HW restart by keeping a failure code
3159		 * in ret.
3160		 */
3161		ret = iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_NETDETECT,
3162					false);
3163	}
3164
3165query_wakeup_reasons:
3166	keep = iwl_mvm_choose_query_wakeup_reasons(mvm, vif, &d3_data);
3167	/* has unlocked the mutex, so skip that */
3168	goto out;
3169
3170err:
3171	mutex_unlock(&mvm->mutex);
3172out:
3173	if (d3_data.status)
3174		kfree(d3_data.status->wake_packet);
3175	kfree(d3_data.status);
3176	iwl_mvm_free_nd(mvm);
3177
3178	if (!mvm->net_detect)
3179		ieee80211_iterate_active_interfaces_mtx(mvm->hw,
3180							IEEE80211_IFACE_ITER_NORMAL,
3181							iwl_mvm_d3_disconnect_iter,
3182							keep ? vif : NULL);
3183
3184	clear_bit(IWL_MVM_STATUS_IN_D3, &mvm->status);
3185
3186	/* no need to reset the device in unified images, if successful */
3187	if (unified_image && !ret) {
3188		/* nothing else to do if we already sent D0I3_END_CMD */
3189		if (d0i3_first)
3190			return 0;
3191
3192		if (!iwl_fw_lookup_notif_ver(mvm->fw, PROT_OFFLOAD_GROUP,
3193					     D3_END_NOTIFICATION, 0)) {
3194			ret = iwl_mvm_send_cmd_pdu(mvm, D0I3_END_CMD, 0, 0, NULL);
3195			if (!ret)
3196				return 0;
3197		} else if (!(d3_data.d3_end_flags & IWL_D0I3_RESET_REQUIRE)) {
3198			return 0;
3199		}
3200	}
3201
3202	/*
3203	 * Reconfigure the device in one of the following cases:
3204	 * 1. We are not using a unified image
3205	 * 2. We are using a unified image but had an error while exiting D3
3206	 */
3207	set_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, &mvm->status);
3208
3209	return 1;
3210}
3211
3212int iwl_mvm_resume(struct ieee80211_hw *hw)
3213{
3214	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
3215	int ret;
3216
3217	ret = __iwl_mvm_resume(mvm);
3218
3219	iwl_mvm_resume_tcm(mvm);
3220
3221	iwl_fw_runtime_resume(&mvm->fwrt);
3222
3223	return ret;
3224}
3225
3226void iwl_mvm_set_wakeup(struct ieee80211_hw *hw, bool enabled)
3227{
3228	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
3229
3230	device_set_wakeup_enable(mvm->trans->dev, enabled);
3231}
3232
3233void iwl_mvm_fast_suspend(struct iwl_mvm *mvm)
3234{
3235	struct iwl_d3_manager_config d3_cfg_cmd_data = {};
3236	int ret;
3237
3238	lockdep_assert_held(&mvm->mutex);
3239
3240	IWL_DEBUG_WOWLAN(mvm, "Starting fast suspend flow\n");
3241
3242	iwl_mvm_pause_tcm(mvm, true);
3243
3244	mvm->fast_resume = true;
3245	set_bit(IWL_MVM_STATUS_IN_D3, &mvm->status);
3246
3247	WARN_ON(iwl_mvm_power_update_device(mvm));
3248	ret = iwl_mvm_send_cmd_pdu(mvm, D3_CONFIG_CMD, 0,
3249				   sizeof(d3_cfg_cmd_data), &d3_cfg_cmd_data);
3250	if (ret)
3251		IWL_ERR(mvm,
3252			"fast suspend: couldn't send D3_CONFIG_CMD %d\n", ret);
3253
3254	ret = iwl_trans_d3_suspend(mvm->trans, false);
3255	if (ret)
3256		IWL_ERR(mvm, "fast suspend: trans_d3_suspend failed %d\n", ret);
3257}
3258
3259int iwl_mvm_fast_resume(struct iwl_mvm *mvm)
3260{
3261	struct iwl_d3_data d3_data = {
3262		.notif_expected =
3263			IWL_D3_NOTIF_D3_END_NOTIF,
3264	};
3265	enum rt_status rt_status;
3266	int ret;
3267
3268	lockdep_assert_held(&mvm->mutex);
3269
3270	IWL_DEBUG_WOWLAN(mvm, "Starting the fast resume flow\n");
3271
3272	mvm->last_reset_or_resume_time_jiffies = jiffies;
3273	iwl_fw_dbg_read_d3_debug_data(&mvm->fwrt);
3274
3275	rt_status = iwl_mvm_check_rt_status(mvm, NULL);
3276	if (rt_status != FW_ALIVE) {
3277		iwl_trans_notify_fw_error(mvm->trans);
3278		if (rt_status == FW_ERROR) {
3279			IWL_ERR(mvm,
3280				"iwl_mvm_check_rt_status failed, device is gone during suspend\n");
3281			iwl_mvm_dump_nic_error_log(mvm);
3282			iwl_dbg_tlv_time_point(&mvm->fwrt,
3283					       IWL_FW_INI_TIME_POINT_FW_ASSERT,
3284					       NULL);
3285			iwl_fw_dbg_collect_desc(&mvm->fwrt,
3286						&iwl_dump_desc_assert,
3287						false, 0);
3288		}
3289		ret = -ENODEV;
3290
3291		goto out;
3292	}
3293	ret = iwl_mvm_d3_notif_wait(mvm, &d3_data);
3294
3295	if (ret) {
3296		IWL_ERR(mvm, "Couldn't get the d3 notif %d\n", ret);
3297		mvm->trans->state = IWL_TRANS_NO_FW;
3298	}
3299
3300	iwl_mvm_resume_tcm(mvm);
3301
3302out:
3303	clear_bit(IWL_MVM_STATUS_IN_D3, &mvm->status);
3304	mvm->fast_resume = false;
3305
3306	return ret;
3307}
~/ Read-only file preview.