cachepc-linux

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

d3.c (74268B)


      1// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
      2/*
      3 * Copyright (C) 2012-2014, 2018-2022 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		struct {
    124			struct iwl_mvm_wep_key_cmd wep_key_cmd;
    125			struct iwl_mvm_wep_key wep_key;
    126		} __packed wkc = {
    127			.wep_key_cmd.mac_id_n_color =
    128				cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
    129								mvmvif->color)),
    130			.wep_key_cmd.num_keys = 1,
    131			/* firmware sets STA_KEY_FLG_WEP_13BYTES */
    132			.wep_key_cmd.decryption_type = STA_KEY_FLG_WEP,
    133			.wep_key.key_index = key->keyidx,
    134			.wep_key.key_size = key->keylen,
    135		};
    136
    137		/*
    138		 * This will fail -- the key functions don't set support
    139		 * pairwise WEP keys. However, that's better than silently
    140		 * failing WoWLAN. Or maybe not?
    141		 */
    142		if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
    143			break;
    144
    145		memcpy(&wkc.wep_key.key[3], key->key, key->keylen);
    146		if (key->keyidx == mvmvif->tx_key_idx) {
    147			/* TX key must be at offset 0 */
    148			wkc.wep_key.key_offset = 0;
    149		} else {
    150			/* others start at 1 */
    151			data->wep_key_idx++;
    152			wkc.wep_key.key_offset = data->wep_key_idx;
    153		}
    154
    155		mutex_lock(&mvm->mutex);
    156		ret = iwl_mvm_send_cmd_pdu(mvm, WEP_KEY, 0, sizeof(wkc), &wkc);
    157		data->error = ret != 0;
    158
    159		mvm->ptk_ivlen = key->iv_len;
    160		mvm->ptk_icvlen = key->icv_len;
    161		mvm->gtk_ivlen = key->iv_len;
    162		mvm->gtk_icvlen = key->icv_len;
    163		mutex_unlock(&mvm->mutex);
    164
    165		/* don't upload key again */
    166		return;
    167	}
    168	default:
    169		data->error = true;
    170		return;
    171	case WLAN_CIPHER_SUITE_BIP_GMAC_256:
    172	case WLAN_CIPHER_SUITE_BIP_GMAC_128:
    173		return;
    174	case WLAN_CIPHER_SUITE_AES_CMAC:
    175		/*
    176		 * Ignore CMAC keys -- the WoWLAN firmware doesn't support them
    177		 * but we also shouldn't abort suspend due to that. It does have
    178		 * support for the IGTK key renewal, but doesn't really use the
    179		 * IGTK for anything. This means we could spuriously wake up or
    180		 * be deauthenticated, but that was considered acceptable.
    181		 */
    182		return;
    183	case WLAN_CIPHER_SUITE_TKIP:
    184	case WLAN_CIPHER_SUITE_CCMP:
    185	case WLAN_CIPHER_SUITE_GCMP:
    186	case WLAN_CIPHER_SUITE_GCMP_256:
    187		break;
    188	}
    189
    190	mutex_lock(&mvm->mutex);
    191	/*
    192	 * The D3 firmware hardcodes the key offset 0 as the key it
    193	 * uses to transmit packets to the AP, i.e. the PTK.
    194	 */
    195	if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
    196		mvm->ptk_ivlen = key->iv_len;
    197		mvm->ptk_icvlen = key->icv_len;
    198		ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, 0);
    199	} else {
    200		/*
    201		 * firmware only supports TSC/RSC for a single key,
    202		 * so if there are multiple keep overwriting them
    203		 * with new ones -- this relies on mac80211 doing
    204		 * list_add_tail().
    205		 */
    206		mvm->gtk_ivlen = key->iv_len;
    207		mvm->gtk_icvlen = key->icv_len;
    208		ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, 1);
    209	}
    210	mutex_unlock(&mvm->mutex);
    211	data->error = ret != 0;
    212}
    213
    214struct wowlan_key_rsc_tsc_data {
    215	struct iwl_wowlan_rsc_tsc_params_cmd_v4 *rsc_tsc;
    216	bool have_rsc_tsc;
    217};
    218
    219static void iwl_mvm_wowlan_get_rsc_tsc_data(struct ieee80211_hw *hw,
    220					    struct ieee80211_vif *vif,
    221					    struct ieee80211_sta *sta,
    222					    struct ieee80211_key_conf *key,
    223					    void *_data)
    224{
    225	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
    226	struct wowlan_key_rsc_tsc_data *data = _data;
    227	struct aes_sc *aes_sc;
    228	struct tkip_sc *tkip_sc, *tkip_tx_sc = NULL;
    229	struct ieee80211_key_seq seq;
    230	int i;
    231
    232	switch (key->cipher) {
    233	default:
    234		break;
    235	case WLAN_CIPHER_SUITE_TKIP:
    236		if (sta) {
    237			u64 pn64;
    238
    239			tkip_sc =
    240			   data->rsc_tsc->params.all_tsc_rsc.tkip.unicast_rsc;
    241			tkip_tx_sc =
    242				&data->rsc_tsc->params.all_tsc_rsc.tkip.tsc;
    243
    244			pn64 = atomic64_read(&key->tx_pn);
    245			tkip_tx_sc->iv16 = cpu_to_le16(TKIP_PN_TO_IV16(pn64));
    246			tkip_tx_sc->iv32 = cpu_to_le32(TKIP_PN_TO_IV32(pn64));
    247		} else {
    248			tkip_sc =
    249			  data->rsc_tsc->params.all_tsc_rsc.tkip.multicast_rsc;
    250		}
    251
    252		/*
    253		 * For non-QoS this relies on the fact that both the uCode and
    254		 * mac80211 use TID 0 (as they need to to avoid replay attacks)
    255		 * for checking the IV in the frames.
    256		 */
    257		for (i = 0; i < IWL_NUM_RSC; i++) {
    258			ieee80211_get_key_rx_seq(key, i, &seq);
    259			tkip_sc[i].iv16 = cpu_to_le16(seq.tkip.iv16);
    260			tkip_sc[i].iv32 = cpu_to_le32(seq.tkip.iv32);
    261		}
    262
    263		data->have_rsc_tsc = true;
    264		break;
    265	case WLAN_CIPHER_SUITE_CCMP:
    266	case WLAN_CIPHER_SUITE_GCMP:
    267	case WLAN_CIPHER_SUITE_GCMP_256:
    268		if (sta) {
    269			struct aes_sc *aes_tx_sc;
    270			u64 pn64;
    271
    272			aes_sc =
    273			   data->rsc_tsc->params.all_tsc_rsc.aes.unicast_rsc;
    274			aes_tx_sc =
    275				&data->rsc_tsc->params.all_tsc_rsc.aes.tsc;
    276
    277			pn64 = atomic64_read(&key->tx_pn);
    278			aes_tx_sc->pn = cpu_to_le64(pn64);
    279		} else {
    280			aes_sc =
    281			   data->rsc_tsc->params.all_tsc_rsc.aes.multicast_rsc;
    282		}
    283
    284		/*
    285		 * For non-QoS this relies on the fact that both the uCode and
    286		 * mac80211/our RX code use TID 0 for checking the PN.
    287		 */
    288		if (sta && iwl_mvm_has_new_rx_api(mvm)) {
    289			struct iwl_mvm_sta *mvmsta;
    290			struct iwl_mvm_key_pn *ptk_pn;
    291			const u8 *pn;
    292
    293			mvmsta = iwl_mvm_sta_from_mac80211(sta);
    294			rcu_read_lock();
    295			ptk_pn = rcu_dereference(mvmsta->ptk_pn[key->keyidx]);
    296			if (WARN_ON(!ptk_pn)) {
    297				rcu_read_unlock();
    298				break;
    299			}
    300
    301			for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
    302				pn = iwl_mvm_find_max_pn(key, ptk_pn, &seq, i,
    303						mvm->trans->num_rx_queues);
    304				aes_sc[i].pn = cpu_to_le64((u64)pn[5] |
    305							   ((u64)pn[4] << 8) |
    306							   ((u64)pn[3] << 16) |
    307							   ((u64)pn[2] << 24) |
    308							   ((u64)pn[1] << 32) |
    309							   ((u64)pn[0] << 40));
    310			}
    311
    312			rcu_read_unlock();
    313		} else {
    314			for (i = 0; i < IWL_NUM_RSC; i++) {
    315				u8 *pn = seq.ccmp.pn;
    316
    317				ieee80211_get_key_rx_seq(key, i, &seq);
    318				aes_sc[i].pn = cpu_to_le64((u64)pn[5] |
    319							   ((u64)pn[4] << 8) |
    320							   ((u64)pn[3] << 16) |
    321							   ((u64)pn[2] << 24) |
    322							   ((u64)pn[1] << 32) |
    323							   ((u64)pn[0] << 40));
    324			}
    325		}
    326		data->have_rsc_tsc = true;
    327		break;
    328	}
    329}
    330
    331struct wowlan_key_rsc_v5_data {
    332	struct iwl_wowlan_rsc_tsc_params_cmd *rsc;
    333	bool have_rsc;
    334	int gtks;
    335	int gtk_ids[4];
    336};
    337
    338static void iwl_mvm_wowlan_get_rsc_v5_data(struct ieee80211_hw *hw,
    339					   struct ieee80211_vif *vif,
    340					   struct ieee80211_sta *sta,
    341					   struct ieee80211_key_conf *key,
    342					   void *_data)
    343{
    344	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
    345	struct wowlan_key_rsc_v5_data *data = _data;
    346	struct ieee80211_key_seq seq;
    347	__le64 *rsc;
    348	int i;
    349
    350	/* only for ciphers that can be PTK/GTK */
    351	switch (key->cipher) {
    352	default:
    353		return;
    354	case WLAN_CIPHER_SUITE_TKIP:
    355	case WLAN_CIPHER_SUITE_CCMP:
    356	case WLAN_CIPHER_SUITE_GCMP:
    357	case WLAN_CIPHER_SUITE_GCMP_256:
    358		break;
    359	}
    360
    361	if (sta) {
    362		rsc = data->rsc->ucast_rsc;
    363	} else {
    364		if (WARN_ON(data->gtks >= ARRAY_SIZE(data->gtk_ids)))
    365			return;
    366		data->gtk_ids[data->gtks] = key->keyidx;
    367		rsc = data->rsc->mcast_rsc[data->gtks % 2];
    368		if (WARN_ON(key->keyidx >=
    369				ARRAY_SIZE(data->rsc->mcast_key_id_map)))
    370			return;
    371		data->rsc->mcast_key_id_map[key->keyidx] = data->gtks % 2;
    372		if (data->gtks >= 2) {
    373			int prev = data->gtks - 2;
    374			int prev_idx = data->gtk_ids[prev];
    375
    376			data->rsc->mcast_key_id_map[prev_idx] =
    377				IWL_MCAST_KEY_MAP_INVALID;
    378		}
    379		data->gtks++;
    380	}
    381
    382	switch (key->cipher) {
    383	default:
    384		WARN_ON(1);
    385		break;
    386	case WLAN_CIPHER_SUITE_TKIP:
    387
    388		/*
    389		 * For non-QoS this relies on the fact that both the uCode and
    390		 * mac80211 use TID 0 (as they need to to avoid replay attacks)
    391		 * for checking the IV in the frames.
    392		 */
    393		for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
    394			ieee80211_get_key_rx_seq(key, i, &seq);
    395
    396			rsc[i] = cpu_to_le64(((u64)seq.tkip.iv32 << 16) |
    397					     seq.tkip.iv16);
    398		}
    399
    400		data->have_rsc = true;
    401		break;
    402	case WLAN_CIPHER_SUITE_CCMP:
    403	case WLAN_CIPHER_SUITE_GCMP:
    404	case WLAN_CIPHER_SUITE_GCMP_256:
    405		/*
    406		 * For non-QoS this relies on the fact that both the uCode and
    407		 * mac80211/our RX code use TID 0 for checking the PN.
    408		 */
    409		if (sta) {
    410			struct iwl_mvm_sta *mvmsta;
    411			struct iwl_mvm_key_pn *ptk_pn;
    412			const u8 *pn;
    413
    414			mvmsta = iwl_mvm_sta_from_mac80211(sta);
    415			rcu_read_lock();
    416			ptk_pn = rcu_dereference(mvmsta->ptk_pn[key->keyidx]);
    417			if (WARN_ON(!ptk_pn)) {
    418				rcu_read_unlock();
    419				break;
    420			}
    421
    422			for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
    423				pn = iwl_mvm_find_max_pn(key, ptk_pn, &seq, i,
    424						mvm->trans->num_rx_queues);
    425				rsc[i] = cpu_to_le64((u64)pn[5] |
    426						     ((u64)pn[4] << 8) |
    427						     ((u64)pn[3] << 16) |
    428						     ((u64)pn[2] << 24) |
    429						     ((u64)pn[1] << 32) |
    430						     ((u64)pn[0] << 40));
    431			}
    432
    433			rcu_read_unlock();
    434		} else {
    435			for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
    436				u8 *pn = seq.ccmp.pn;
    437
    438				ieee80211_get_key_rx_seq(key, i, &seq);
    439				rsc[i] = cpu_to_le64((u64)pn[5] |
    440						     ((u64)pn[4] << 8) |
    441						     ((u64)pn[3] << 16) |
    442						     ((u64)pn[2] << 24) |
    443						     ((u64)pn[1] << 32) |
    444						     ((u64)pn[0] << 40));
    445			}
    446		}
    447		data->have_rsc = true;
    448		break;
    449	}
    450}
    451
    452static int iwl_mvm_wowlan_config_rsc_tsc(struct iwl_mvm *mvm,
    453					 struct ieee80211_vif *vif)
    454{
    455	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
    456	int ver = iwl_fw_lookup_cmd_ver(mvm->fw, WOWLAN_TSC_RSC_PARAM,
    457					IWL_FW_CMD_VER_UNKNOWN);
    458	int ret;
    459
    460	if (ver == 5) {
    461		struct wowlan_key_rsc_v5_data data = {};
    462		int i;
    463
    464		data.rsc = kmalloc(sizeof(*data.rsc), GFP_KERNEL);
    465		if (!data.rsc)
    466			return -ENOMEM;
    467
    468		memset(data.rsc, 0xff, sizeof(*data.rsc));
    469
    470		for (i = 0; i < ARRAY_SIZE(data.rsc->mcast_key_id_map); i++)
    471			data.rsc->mcast_key_id_map[i] =
    472				IWL_MCAST_KEY_MAP_INVALID;
    473		data.rsc->sta_id = cpu_to_le32(mvmvif->ap_sta_id);
    474
    475		ieee80211_iter_keys(mvm->hw, vif,
    476				    iwl_mvm_wowlan_get_rsc_v5_data,
    477				    &data);
    478
    479		if (data.have_rsc)
    480			ret = iwl_mvm_send_cmd_pdu(mvm, WOWLAN_TSC_RSC_PARAM,
    481						   CMD_ASYNC, sizeof(*data.rsc),
    482						   data.rsc);
    483		else
    484			ret = 0;
    485		kfree(data.rsc);
    486	} else if (ver == 4 || ver == 2 || ver == IWL_FW_CMD_VER_UNKNOWN) {
    487		struct wowlan_key_rsc_tsc_data data = {};
    488		int size;
    489
    490		data.rsc_tsc = kzalloc(sizeof(*data.rsc_tsc), GFP_KERNEL);
    491		if (!data.rsc_tsc)
    492			return -ENOMEM;
    493
    494		if (ver == 4) {
    495			size = sizeof(*data.rsc_tsc);
    496			data.rsc_tsc->sta_id = cpu_to_le32(mvmvif->ap_sta_id);
    497		} else {
    498			/* ver == 2 || ver == IWL_FW_CMD_VER_UNKNOWN */
    499			size = sizeof(data.rsc_tsc->params);
    500		}
    501
    502		ieee80211_iter_keys(mvm->hw, vif,
    503				    iwl_mvm_wowlan_get_rsc_tsc_data,
    504				    &data);
    505
    506		if (data.have_rsc_tsc)
    507			ret = iwl_mvm_send_cmd_pdu(mvm, WOWLAN_TSC_RSC_PARAM,
    508						   CMD_ASYNC, size,
    509						   data.rsc_tsc);
    510		else
    511			ret = 0;
    512		kfree(data.rsc_tsc);
    513	} else {
    514		ret = 0;
    515		WARN_ON_ONCE(1);
    516	}
    517
    518	return ret;
    519}
    520
    521struct wowlan_key_tkip_data {
    522	struct iwl_wowlan_tkip_params_cmd tkip;
    523	bool have_tkip_keys;
    524};
    525
    526static void iwl_mvm_wowlan_get_tkip_data(struct ieee80211_hw *hw,
    527					 struct ieee80211_vif *vif,
    528					 struct ieee80211_sta *sta,
    529					 struct ieee80211_key_conf *key,
    530					 void *_data)
    531{
    532	struct wowlan_key_tkip_data *data = _data;
    533	struct iwl_p1k_cache *rx_p1ks;
    534	u8 *rx_mic_key;
    535	struct ieee80211_key_seq seq;
    536	u32 cur_rx_iv32 = 0;
    537	u16 p1k[IWL_P1K_SIZE];
    538	int i;
    539
    540	switch (key->cipher) {
    541	default:
    542		break;
    543	case WLAN_CIPHER_SUITE_TKIP:
    544		if (sta) {
    545			u64 pn64;
    546
    547			rx_p1ks = data->tkip.rx_uni;
    548
    549			pn64 = atomic64_read(&key->tx_pn);
    550
    551			ieee80211_get_tkip_p1k_iv(key, TKIP_PN_TO_IV32(pn64),
    552						  p1k);
    553			iwl_mvm_convert_p1k(p1k, data->tkip.tx.p1k);
    554
    555			memcpy(data->tkip.mic_keys.tx,
    556			       &key->key[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY],
    557			       IWL_MIC_KEY_SIZE);
    558
    559			rx_mic_key = data->tkip.mic_keys.rx_unicast;
    560		} else {
    561			rx_p1ks = data->tkip.rx_multi;
    562			rx_mic_key = data->tkip.mic_keys.rx_mcast;
    563		}
    564
    565		for (i = 0; i < IWL_NUM_RSC; i++) {
    566			/* wrapping isn't allowed, AP must rekey */
    567			if (seq.tkip.iv32 > cur_rx_iv32)
    568				cur_rx_iv32 = seq.tkip.iv32;
    569		}
    570
    571		ieee80211_get_tkip_rx_p1k(key, vif->bss_conf.bssid,
    572					  cur_rx_iv32, p1k);
    573		iwl_mvm_convert_p1k(p1k, rx_p1ks[0].p1k);
    574		ieee80211_get_tkip_rx_p1k(key, vif->bss_conf.bssid,
    575					  cur_rx_iv32 + 1, p1k);
    576		iwl_mvm_convert_p1k(p1k, rx_p1ks[1].p1k);
    577
    578		memcpy(rx_mic_key,
    579		       &key->key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY],
    580		       IWL_MIC_KEY_SIZE);
    581
    582		data->have_tkip_keys = true;
    583		break;
    584	}
    585}
    586
    587struct wowlan_key_gtk_type_iter {
    588	struct iwl_wowlan_kek_kck_material_cmd_v4 *kek_kck_cmd;
    589};
    590
    591static void iwl_mvm_wowlan_gtk_type_iter(struct ieee80211_hw *hw,
    592					 struct ieee80211_vif *vif,
    593					 struct ieee80211_sta *sta,
    594					 struct ieee80211_key_conf *key,
    595					 void *_data)
    596{
    597	struct wowlan_key_gtk_type_iter *data = _data;
    598
    599	switch (key->cipher) {
    600	default:
    601		return;
    602	case WLAN_CIPHER_SUITE_BIP_GMAC_256:
    603	case WLAN_CIPHER_SUITE_BIP_GMAC_128:
    604		data->kek_kck_cmd->igtk_cipher = cpu_to_le32(STA_KEY_FLG_GCMP);
    605		return;
    606	case WLAN_CIPHER_SUITE_AES_CMAC:
    607		data->kek_kck_cmd->igtk_cipher = cpu_to_le32(STA_KEY_FLG_CCM);
    608		return;
    609	case WLAN_CIPHER_SUITE_CCMP:
    610		if (!sta)
    611			data->kek_kck_cmd->gtk_cipher =
    612				cpu_to_le32(STA_KEY_FLG_CCM);
    613		break;
    614	case WLAN_CIPHER_SUITE_GCMP:
    615	case WLAN_CIPHER_SUITE_GCMP_256:
    616		if (!sta)
    617			data->kek_kck_cmd->gtk_cipher =
    618				cpu_to_le32(STA_KEY_FLG_GCMP);
    619		break;
    620	}
    621}
    622
    623static int iwl_mvm_send_patterns_v1(struct iwl_mvm *mvm,
    624				    struct cfg80211_wowlan *wowlan)
    625{
    626	struct iwl_wowlan_patterns_cmd_v1 *pattern_cmd;
    627	struct iwl_host_cmd cmd = {
    628		.id = WOWLAN_PATTERNS,
    629		.dataflags[0] = IWL_HCMD_DFL_NOCOPY,
    630	};
    631	int i, err;
    632
    633	if (!wowlan->n_patterns)
    634		return 0;
    635
    636	cmd.len[0] = struct_size(pattern_cmd, patterns, wowlan->n_patterns);
    637
    638	pattern_cmd = kmalloc(cmd.len[0], GFP_KERNEL);
    639	if (!pattern_cmd)
    640		return -ENOMEM;
    641
    642	pattern_cmd->n_patterns = cpu_to_le32(wowlan->n_patterns);
    643
    644	for (i = 0; i < wowlan->n_patterns; i++) {
    645		int mask_len = DIV_ROUND_UP(wowlan->patterns[i].pattern_len, 8);
    646
    647		memcpy(&pattern_cmd->patterns[i].mask,
    648		       wowlan->patterns[i].mask, mask_len);
    649		memcpy(&pattern_cmd->patterns[i].pattern,
    650		       wowlan->patterns[i].pattern,
    651		       wowlan->patterns[i].pattern_len);
    652		pattern_cmd->patterns[i].mask_size = mask_len;
    653		pattern_cmd->patterns[i].pattern_size =
    654			wowlan->patterns[i].pattern_len;
    655	}
    656
    657	cmd.data[0] = pattern_cmd;
    658	err = iwl_mvm_send_cmd(mvm, &cmd);
    659	kfree(pattern_cmd);
    660	return err;
    661}
    662
    663static int iwl_mvm_send_patterns(struct iwl_mvm *mvm,
    664				 struct ieee80211_vif *vif,
    665				 struct cfg80211_wowlan *wowlan)
    666{
    667	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
    668	struct iwl_wowlan_patterns_cmd *pattern_cmd;
    669	struct iwl_host_cmd cmd = {
    670		.id = WOWLAN_PATTERNS,
    671		.dataflags[0] = IWL_HCMD_DFL_NOCOPY,
    672	};
    673	int i, err;
    674	int ver = iwl_fw_lookup_cmd_ver(mvm->fw, cmd.id,
    675					IWL_FW_CMD_VER_UNKNOWN);
    676
    677	if (!wowlan->n_patterns)
    678		return 0;
    679
    680	cmd.len[0] = sizeof(*pattern_cmd) +
    681		wowlan->n_patterns * sizeof(struct iwl_wowlan_pattern_v2);
    682
    683	pattern_cmd = kzalloc(cmd.len[0], GFP_KERNEL);
    684	if (!pattern_cmd)
    685		return -ENOMEM;
    686
    687	pattern_cmd->n_patterns = wowlan->n_patterns;
    688	if (ver >= 3)
    689		pattern_cmd->sta_id = mvmvif->ap_sta_id;
    690
    691	for (i = 0; i < wowlan->n_patterns; i++) {
    692		int mask_len = DIV_ROUND_UP(wowlan->patterns[i].pattern_len, 8);
    693
    694		pattern_cmd->patterns[i].pattern_type =
    695			WOWLAN_PATTERN_TYPE_BITMASK;
    696
    697		memcpy(&pattern_cmd->patterns[i].u.bitmask.mask,
    698		       wowlan->patterns[i].mask, mask_len);
    699		memcpy(&pattern_cmd->patterns[i].u.bitmask.pattern,
    700		       wowlan->patterns[i].pattern,
    701		       wowlan->patterns[i].pattern_len);
    702		pattern_cmd->patterns[i].u.bitmask.mask_size = mask_len;
    703		pattern_cmd->patterns[i].u.bitmask.pattern_size =
    704			wowlan->patterns[i].pattern_len;
    705	}
    706
    707	cmd.data[0] = pattern_cmd;
    708	err = iwl_mvm_send_cmd(mvm, &cmd);
    709	kfree(pattern_cmd);
    710	return err;
    711}
    712
    713static int iwl_mvm_d3_reprogram(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
    714				struct ieee80211_sta *ap_sta)
    715{
    716	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
    717	struct ieee80211_chanctx_conf *ctx;
    718	u8 chains_static, chains_dynamic;
    719	struct cfg80211_chan_def chandef;
    720	int ret, i;
    721	struct iwl_binding_cmd_v1 binding_cmd = {};
    722	struct iwl_time_quota_cmd quota_cmd = {};
    723	struct iwl_time_quota_data *quota;
    724	u32 status;
    725
    726	if (WARN_ON_ONCE(iwl_mvm_is_cdb_supported(mvm)))
    727		return -EINVAL;
    728
    729	/* add back the PHY */
    730	if (WARN_ON(!mvmvif->phy_ctxt))
    731		return -EINVAL;
    732
    733	rcu_read_lock();
    734	ctx = rcu_dereference(vif->chanctx_conf);
    735	if (WARN_ON(!ctx)) {
    736		rcu_read_unlock();
    737		return -EINVAL;
    738	}
    739	chandef = ctx->def;
    740	chains_static = ctx->rx_chains_static;
    741	chains_dynamic = ctx->rx_chains_dynamic;
    742	rcu_read_unlock();
    743
    744	ret = iwl_mvm_phy_ctxt_add(mvm, mvmvif->phy_ctxt, &chandef,
    745				   chains_static, chains_dynamic);
    746	if (ret)
    747		return ret;
    748
    749	/* add back the MAC */
    750	mvmvif->uploaded = false;
    751
    752	if (WARN_ON(!vif->bss_conf.assoc))
    753		return -EINVAL;
    754
    755	ret = iwl_mvm_mac_ctxt_add(mvm, vif);
    756	if (ret)
    757		return ret;
    758
    759	/* add back binding - XXX refactor? */
    760	binding_cmd.id_and_color =
    761		cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->phy_ctxt->id,
    762						mvmvif->phy_ctxt->color));
    763	binding_cmd.action = cpu_to_le32(FW_CTXT_ACTION_ADD);
    764	binding_cmd.phy =
    765		cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->phy_ctxt->id,
    766						mvmvif->phy_ctxt->color));
    767	binding_cmd.macs[0] = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
    768							      mvmvif->color));
    769	for (i = 1; i < MAX_MACS_IN_BINDING; i++)
    770		binding_cmd.macs[i] = cpu_to_le32(FW_CTXT_INVALID);
    771
    772	status = 0;
    773	ret = iwl_mvm_send_cmd_pdu_status(mvm, BINDING_CONTEXT_CMD,
    774					  IWL_BINDING_CMD_SIZE_V1, &binding_cmd,
    775					  &status);
    776	if (ret) {
    777		IWL_ERR(mvm, "Failed to add binding: %d\n", ret);
    778		return ret;
    779	}
    780
    781	if (status) {
    782		IWL_ERR(mvm, "Binding command failed: %u\n", status);
    783		return -EIO;
    784	}
    785
    786	ret = iwl_mvm_sta_send_to_fw(mvm, ap_sta, false, 0);
    787	if (ret)
    788		return ret;
    789	rcu_assign_pointer(mvm->fw_id_to_mac_id[mvmvif->ap_sta_id], ap_sta);
    790
    791	ret = iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
    792	if (ret)
    793		return ret;
    794
    795	/* and some quota */
    796	quota = iwl_mvm_quota_cmd_get_quota(mvm, &quota_cmd, 0);
    797	quota->id_and_color =
    798		cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->phy_ctxt->id,
    799						mvmvif->phy_ctxt->color));
    800	quota->quota = cpu_to_le32(IWL_MVM_MAX_QUOTA);
    801	quota->max_duration = cpu_to_le32(IWL_MVM_MAX_QUOTA);
    802
    803	for (i = 1; i < MAX_BINDINGS; i++) {
    804		quota = iwl_mvm_quota_cmd_get_quota(mvm, &quota_cmd, i);
    805		quota->id_and_color = cpu_to_le32(FW_CTXT_INVALID);
    806	}
    807
    808	ret = iwl_mvm_send_cmd_pdu(mvm, TIME_QUOTA_CMD, 0,
    809				   iwl_mvm_quota_cmd_size(mvm), &quota_cmd);
    810	if (ret)
    811		IWL_ERR(mvm, "Failed to send quota: %d\n", ret);
    812
    813	if (iwl_mvm_is_lar_supported(mvm) && iwl_mvm_init_fw_regd(mvm))
    814		IWL_ERR(mvm, "Failed to initialize D3 LAR information\n");
    815
    816	return 0;
    817}
    818
    819static int iwl_mvm_get_last_nonqos_seq(struct iwl_mvm *mvm,
    820				       struct ieee80211_vif *vif)
    821{
    822	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
    823	struct iwl_nonqos_seq_query_cmd query_cmd = {
    824		.get_set_flag = cpu_to_le32(IWL_NONQOS_SEQ_GET),
    825		.mac_id_n_color =
    826			cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
    827							mvmvif->color)),
    828	};
    829	struct iwl_host_cmd cmd = {
    830		.id = NON_QOS_TX_COUNTER_CMD,
    831		.flags = CMD_WANT_SKB,
    832	};
    833	int err;
    834	u32 size;
    835
    836	cmd.data[0] = &query_cmd;
    837	cmd.len[0] = sizeof(query_cmd);
    838
    839	err = iwl_mvm_send_cmd(mvm, &cmd);
    840	if (err)
    841		return err;
    842
    843	size = iwl_rx_packet_payload_len(cmd.resp_pkt);
    844	if (size < sizeof(__le16)) {
    845		err = -EINVAL;
    846	} else {
    847		err = le16_to_cpup((__le16 *)cmd.resp_pkt->data);
    848		/* firmware returns next, not last-used seqno */
    849		err = (u16) (err - 0x10);
    850	}
    851
    852	iwl_free_resp(&cmd);
    853	return err;
    854}
    855
    856void iwl_mvm_set_last_nonqos_seq(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
    857{
    858	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
    859	struct iwl_nonqos_seq_query_cmd query_cmd = {
    860		.get_set_flag = cpu_to_le32(IWL_NONQOS_SEQ_SET),
    861		.mac_id_n_color =
    862			cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
    863							mvmvif->color)),
    864		.value = cpu_to_le16(mvmvif->seqno),
    865	};
    866
    867	/* return if called during restart, not resume from D3 */
    868	if (!mvmvif->seqno_valid)
    869		return;
    870
    871	mvmvif->seqno_valid = false;
    872
    873	if (iwl_mvm_send_cmd_pdu(mvm, NON_QOS_TX_COUNTER_CMD, 0,
    874				 sizeof(query_cmd), &query_cmd))
    875		IWL_ERR(mvm, "failed to set non-QoS seqno\n");
    876}
    877
    878static int iwl_mvm_switch_to_d3(struct iwl_mvm *mvm)
    879{
    880	iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_REGULAR, true);
    881
    882	iwl_mvm_stop_device(mvm);
    883	/*
    884	 * Set the HW restart bit -- this is mostly true as we're
    885	 * going to load new firmware and reprogram that, though
    886	 * the reprogramming is going to be manual to avoid adding
    887	 * all the MACs that aren't support.
    888	 * We don't have to clear up everything though because the
    889	 * reprogramming is manual. When we resume, we'll actually
    890	 * go through a proper restart sequence again to switch
    891	 * back to the runtime firmware image.
    892	 */
    893	set_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);
    894
    895	/* the fw is reset, so all the keys are cleared */
    896	memset(mvm->fw_key_table, 0, sizeof(mvm->fw_key_table));
    897
    898	mvm->ptk_ivlen = 0;
    899	mvm->ptk_icvlen = 0;
    900	mvm->ptk_ivlen = 0;
    901	mvm->ptk_icvlen = 0;
    902
    903	return iwl_mvm_load_d3_fw(mvm);
    904}
    905
    906static int
    907iwl_mvm_get_wowlan_config(struct iwl_mvm *mvm,
    908			  struct cfg80211_wowlan *wowlan,
    909			  struct iwl_wowlan_config_cmd *wowlan_config_cmd,
    910			  struct ieee80211_vif *vif, struct iwl_mvm_vif *mvmvif,
    911			  struct ieee80211_sta *ap_sta)
    912{
    913	struct iwl_mvm_sta *mvm_ap_sta = iwl_mvm_sta_from_mac80211(ap_sta);
    914
    915	/* TODO: wowlan_config_cmd->wowlan_ba_teardown_tids */
    916
    917	wowlan_config_cmd->is_11n_connection =
    918					ap_sta->deflink.ht_cap.ht_supported;
    919	wowlan_config_cmd->flags = ENABLE_L3_FILTERING |
    920		ENABLE_NBNS_FILTERING | ENABLE_DHCP_FILTERING;
    921
    922	if (iwl_fw_lookup_cmd_ver(mvm->fw, WOWLAN_CONFIGURATION, 0) < 6) {
    923		/* Query the last used seqno and set it */
    924		int ret = iwl_mvm_get_last_nonqos_seq(mvm, vif);
    925
    926		if (ret < 0)
    927			return ret;
    928
    929		wowlan_config_cmd->non_qos_seq = cpu_to_le16(ret);
    930	}
    931
    932	iwl_mvm_set_wowlan_qos_seq(mvm_ap_sta, wowlan_config_cmd);
    933
    934	if (wowlan->disconnect)
    935		wowlan_config_cmd->wakeup_filter |=
    936			cpu_to_le32(IWL_WOWLAN_WAKEUP_BEACON_MISS |
    937				    IWL_WOWLAN_WAKEUP_LINK_CHANGE);
    938	if (wowlan->magic_pkt)
    939		wowlan_config_cmd->wakeup_filter |=
    940			cpu_to_le32(IWL_WOWLAN_WAKEUP_MAGIC_PACKET);
    941	if (wowlan->gtk_rekey_failure)
    942		wowlan_config_cmd->wakeup_filter |=
    943			cpu_to_le32(IWL_WOWLAN_WAKEUP_GTK_REKEY_FAIL);
    944	if (wowlan->eap_identity_req)
    945		wowlan_config_cmd->wakeup_filter |=
    946			cpu_to_le32(IWL_WOWLAN_WAKEUP_EAP_IDENT_REQ);
    947	if (wowlan->four_way_handshake)
    948		wowlan_config_cmd->wakeup_filter |=
    949			cpu_to_le32(IWL_WOWLAN_WAKEUP_4WAY_HANDSHAKE);
    950	if (wowlan->n_patterns)
    951		wowlan_config_cmd->wakeup_filter |=
    952			cpu_to_le32(IWL_WOWLAN_WAKEUP_PATTERN_MATCH);
    953
    954	if (wowlan->rfkill_release)
    955		wowlan_config_cmd->wakeup_filter |=
    956			cpu_to_le32(IWL_WOWLAN_WAKEUP_RF_KILL_DEASSERT);
    957
    958	if (wowlan->tcp) {
    959		/*
    960		 * Set the "link change" (really "link lost") flag as well
    961		 * since that implies losing the TCP connection.
    962		 */
    963		wowlan_config_cmd->wakeup_filter |=
    964			cpu_to_le32(IWL_WOWLAN_WAKEUP_REMOTE_LINK_LOSS |
    965				    IWL_WOWLAN_WAKEUP_REMOTE_SIGNATURE_TABLE |
    966				    IWL_WOWLAN_WAKEUP_REMOTE_WAKEUP_PACKET |
    967				    IWL_WOWLAN_WAKEUP_LINK_CHANGE);
    968	}
    969
    970	if (wowlan->any) {
    971		wowlan_config_cmd->wakeup_filter |=
    972			cpu_to_le32(IWL_WOWLAN_WAKEUP_BEACON_MISS |
    973				    IWL_WOWLAN_WAKEUP_LINK_CHANGE |
    974				    IWL_WOWLAN_WAKEUP_RX_FRAME |
    975				    IWL_WOWLAN_WAKEUP_BCN_FILTERING);
    976	}
    977
    978	return 0;
    979}
    980
    981static int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm,
    982					    struct ieee80211_vif *vif)
    983{
    984	bool unified = fw_has_capa(&mvm->fw->ucode_capa,
    985				   IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);
    986	struct wowlan_key_reprogram_data key_data = {};
    987	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
    988	int ret;
    989	u8 cmd_ver;
    990	size_t cmd_size;
    991
    992	if (!unified) {
    993		/*
    994		 * if we have to configure keys, call ieee80211_iter_keys(),
    995		 * as we need non-atomic context in order to take the
    996		 * required locks.
    997		 */
    998		/*
    999		 * Note that currently we don't use CMD_ASYNC in the iterator.
   1000		 * In case of key_data.configure_keys, all the configured
   1001		 * commands are SYNC, and iwl_mvm_wowlan_program_keys() will
   1002		 * take care of locking/unlocking mvm->mutex.
   1003		 */
   1004		ieee80211_iter_keys(mvm->hw, vif, iwl_mvm_wowlan_program_keys,
   1005				    &key_data);
   1006
   1007		if (key_data.error)
   1008			return -EIO;
   1009	}
   1010
   1011	ret = iwl_mvm_wowlan_config_rsc_tsc(mvm, vif);
   1012	if (ret)
   1013		return ret;
   1014
   1015	if (!fw_has_api(&mvm->fw->ucode_capa,
   1016			IWL_UCODE_TLV_API_TKIP_MIC_KEYS)) {
   1017		int ver = iwl_fw_lookup_cmd_ver(mvm->fw, WOWLAN_TKIP_PARAM,
   1018						IWL_FW_CMD_VER_UNKNOWN);
   1019		struct wowlan_key_tkip_data tkip_data = {};
   1020		int size;
   1021
   1022		if (ver == 2) {
   1023			size = sizeof(tkip_data.tkip);
   1024			tkip_data.tkip.sta_id =
   1025				cpu_to_le32(mvmvif->ap_sta_id);
   1026		} else if (ver == 1 || ver == IWL_FW_CMD_VER_UNKNOWN) {
   1027			size = sizeof(struct iwl_wowlan_tkip_params_cmd_ver_1);
   1028		} else {
   1029			WARN_ON_ONCE(1);
   1030			return -EINVAL;
   1031		}
   1032
   1033		ieee80211_iter_keys(mvm->hw, vif, iwl_mvm_wowlan_get_tkip_data,
   1034				    &tkip_data);
   1035
   1036		if (tkip_data.have_tkip_keys) {
   1037			/* send relevant data according to CMD version */
   1038			ret = iwl_mvm_send_cmd_pdu(mvm,
   1039						   WOWLAN_TKIP_PARAM,
   1040						   CMD_ASYNC, size,
   1041						   &tkip_data.tkip);
   1042			if (ret)
   1043				return ret;
   1044		}
   1045	}
   1046
   1047	/* configure rekey data only if offloaded rekey is supported (d3) */
   1048	if (mvmvif->rekey_data.valid) {
   1049		struct iwl_wowlan_kek_kck_material_cmd_v4 kek_kck_cmd = {};
   1050		struct iwl_wowlan_kek_kck_material_cmd_v4 *_kek_kck_cmd =
   1051			&kek_kck_cmd;
   1052		struct wowlan_key_gtk_type_iter gtk_type_data = {
   1053			.kek_kck_cmd = _kek_kck_cmd,
   1054		};
   1055
   1056		cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw,
   1057						WOWLAN_KEK_KCK_MATERIAL,
   1058						IWL_FW_CMD_VER_UNKNOWN);
   1059		if (WARN_ON(cmd_ver != 2 && cmd_ver != 3 && cmd_ver != 4 &&
   1060			    cmd_ver != IWL_FW_CMD_VER_UNKNOWN))
   1061			return -EINVAL;
   1062
   1063		ieee80211_iter_keys(mvm->hw, vif, iwl_mvm_wowlan_gtk_type_iter,
   1064				    &gtk_type_data);
   1065
   1066		memcpy(kek_kck_cmd.kck, mvmvif->rekey_data.kck,
   1067		       mvmvif->rekey_data.kck_len);
   1068		kek_kck_cmd.kck_len = cpu_to_le16(mvmvif->rekey_data.kck_len);
   1069		memcpy(kek_kck_cmd.kek, mvmvif->rekey_data.kek,
   1070		       mvmvif->rekey_data.kek_len);
   1071		kek_kck_cmd.kek_len = cpu_to_le16(mvmvif->rekey_data.kek_len);
   1072		kek_kck_cmd.replay_ctr = mvmvif->rekey_data.replay_ctr;
   1073		kek_kck_cmd.akm = cpu_to_le32(mvmvif->rekey_data.akm);
   1074		kek_kck_cmd.sta_id = cpu_to_le32(mvmvif->ap_sta_id);
   1075
   1076		if (cmd_ver == 4) {
   1077			cmd_size = sizeof(struct iwl_wowlan_kek_kck_material_cmd_v4);
   1078		} else {
   1079			if (cmd_ver == 3)
   1080				cmd_size =
   1081					sizeof(struct iwl_wowlan_kek_kck_material_cmd_v3);
   1082			else
   1083				cmd_size =
   1084					sizeof(struct iwl_wowlan_kek_kck_material_cmd_v2);
   1085			/* skip the sta_id at the beginning */
   1086			_kek_kck_cmd = (void *)
   1087				((u8 *)_kek_kck_cmd + sizeof(kek_kck_cmd.sta_id));
   1088		}
   1089
   1090		IWL_DEBUG_WOWLAN(mvm, "setting akm %d\n",
   1091				 mvmvif->rekey_data.akm);
   1092
   1093		ret = iwl_mvm_send_cmd_pdu(mvm, WOWLAN_KEK_KCK_MATERIAL,
   1094					   CMD_ASYNC, cmd_size, _kek_kck_cmd);
   1095		if (ret)
   1096			return ret;
   1097	}
   1098
   1099	return 0;
   1100}
   1101
   1102static int
   1103iwl_mvm_wowlan_config(struct iwl_mvm *mvm,
   1104		      struct cfg80211_wowlan *wowlan,
   1105		      struct iwl_wowlan_config_cmd *wowlan_config_cmd,
   1106		      struct ieee80211_vif *vif, struct iwl_mvm_vif *mvmvif,
   1107		      struct ieee80211_sta *ap_sta)
   1108{
   1109	int ret;
   1110	bool unified_image = fw_has_capa(&mvm->fw->ucode_capa,
   1111					 IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);
   1112
   1113	mvm->offload_tid = wowlan_config_cmd->offloading_tid;
   1114
   1115	if (!unified_image) {
   1116		ret = iwl_mvm_switch_to_d3(mvm);
   1117		if (ret)
   1118			return ret;
   1119
   1120		ret = iwl_mvm_d3_reprogram(mvm, vif, ap_sta);
   1121		if (ret)
   1122			return ret;
   1123	}
   1124
   1125	/*
   1126	 * This needs to be unlocked due to lock ordering
   1127	 * constraints. Since we're in the suspend path
   1128	 * that isn't really a problem though.
   1129	 */
   1130	mutex_unlock(&mvm->mutex);
   1131	ret = iwl_mvm_wowlan_config_key_params(mvm, vif);
   1132	mutex_lock(&mvm->mutex);
   1133	if (ret)
   1134		return ret;
   1135
   1136	ret = iwl_mvm_send_cmd_pdu(mvm, WOWLAN_CONFIGURATION, 0,
   1137				   sizeof(*wowlan_config_cmd),
   1138				   wowlan_config_cmd);
   1139	if (ret)
   1140		return ret;
   1141
   1142	if (fw_has_api(&mvm->fw->ucode_capa,
   1143		       IWL_UCODE_TLV_API_WOWLAN_TCP_SYN_WAKE))
   1144		ret = iwl_mvm_send_patterns(mvm, vif, wowlan);
   1145	else
   1146		ret = iwl_mvm_send_patterns_v1(mvm, wowlan);
   1147	if (ret)
   1148		return ret;
   1149
   1150	return iwl_mvm_send_proto_offload(mvm, vif, false, true, 0);
   1151}
   1152
   1153static int
   1154iwl_mvm_netdetect_config(struct iwl_mvm *mvm,
   1155			 struct cfg80211_wowlan *wowlan,
   1156			 struct cfg80211_sched_scan_request *nd_config,
   1157			 struct ieee80211_vif *vif)
   1158{
   1159	int ret;
   1160	bool unified_image = fw_has_capa(&mvm->fw->ucode_capa,
   1161					 IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);
   1162
   1163	if (!unified_image) {
   1164		ret = iwl_mvm_switch_to_d3(mvm);
   1165		if (ret)
   1166			return ret;
   1167	} else {
   1168		/* In theory, we wouldn't have to stop a running sched
   1169		 * scan in order to start another one (for
   1170		 * net-detect).  But in practice this doesn't seem to
   1171		 * work properly, so stop any running sched_scan now.
   1172		 */
   1173		ret = iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_SCHED, true);
   1174		if (ret)
   1175			return ret;
   1176	}
   1177
   1178	ret = iwl_mvm_sched_scan_start(mvm, vif, nd_config, &mvm->nd_ies,
   1179				       IWL_MVM_SCAN_NETDETECT);
   1180	if (ret)
   1181		return ret;
   1182
   1183	if (WARN_ON(mvm->nd_match_sets || mvm->nd_channels))
   1184		return -EBUSY;
   1185
   1186	/* save the sched scan matchsets... */
   1187	if (nd_config->n_match_sets) {
   1188		mvm->nd_match_sets = kmemdup(nd_config->match_sets,
   1189					     sizeof(*nd_config->match_sets) *
   1190					     nd_config->n_match_sets,
   1191					     GFP_KERNEL);
   1192		if (mvm->nd_match_sets)
   1193			mvm->n_nd_match_sets = nd_config->n_match_sets;
   1194	}
   1195
   1196	/* ...and the sched scan channels for later reporting */
   1197	mvm->nd_channels = kmemdup(nd_config->channels,
   1198				   sizeof(*nd_config->channels) *
   1199				   nd_config->n_channels,
   1200				   GFP_KERNEL);
   1201	if (mvm->nd_channels)
   1202		mvm->n_nd_channels = nd_config->n_channels;
   1203
   1204	return 0;
   1205}
   1206
   1207static void iwl_mvm_free_nd(struct iwl_mvm *mvm)
   1208{
   1209	kfree(mvm->nd_match_sets);
   1210	mvm->nd_match_sets = NULL;
   1211	mvm->n_nd_match_sets = 0;
   1212	kfree(mvm->nd_channels);
   1213	mvm->nd_channels = NULL;
   1214	mvm->n_nd_channels = 0;
   1215}
   1216
   1217static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
   1218			     struct cfg80211_wowlan *wowlan,
   1219			     bool test)
   1220{
   1221	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
   1222	struct ieee80211_vif *vif = NULL;
   1223	struct iwl_mvm_vif *mvmvif = NULL;
   1224	struct ieee80211_sta *ap_sta = NULL;
   1225	struct iwl_d3_manager_config d3_cfg_cmd_data = {
   1226		/*
   1227		 * Program the minimum sleep time to 10 seconds, as many
   1228		 * platforms have issues processing a wakeup signal while
   1229		 * still being in the process of suspending.
   1230		 */
   1231		.min_sleep_time = cpu_to_le32(10 * 1000 * 1000),
   1232	};
   1233	struct iwl_host_cmd d3_cfg_cmd = {
   1234		.id = D3_CONFIG_CMD,
   1235		.flags = CMD_WANT_SKB | CMD_SEND_IN_D3,
   1236		.data[0] = &d3_cfg_cmd_data,
   1237		.len[0] = sizeof(d3_cfg_cmd_data),
   1238	};
   1239	int ret;
   1240	int len __maybe_unused;
   1241	bool unified_image = fw_has_capa(&mvm->fw->ucode_capa,
   1242					 IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);
   1243
   1244	if (!wowlan) {
   1245		/*
   1246		 * mac80211 shouldn't get here, but for D3 test
   1247		 * it doesn't warrant a warning
   1248		 */
   1249		WARN_ON(!test);
   1250		return -EINVAL;
   1251	}
   1252
   1253	mutex_lock(&mvm->mutex);
   1254
   1255	set_bit(IWL_MVM_STATUS_IN_D3, &mvm->status);
   1256
   1257	synchronize_net();
   1258
   1259	vif = iwl_mvm_get_bss_vif(mvm);
   1260	if (IS_ERR_OR_NULL(vif)) {
   1261		ret = 1;
   1262		goto out_noreset;
   1263	}
   1264
   1265	mvmvif = iwl_mvm_vif_from_mac80211(vif);
   1266
   1267	if (mvmvif->ap_sta_id == IWL_MVM_INVALID_STA) {
   1268		/* if we're not associated, this must be netdetect */
   1269		if (!wowlan->nd_config) {
   1270			ret = 1;
   1271			goto out_noreset;
   1272		}
   1273
   1274		ret = iwl_mvm_netdetect_config(
   1275			mvm, wowlan, wowlan->nd_config, vif);
   1276		if (ret)
   1277			goto out;
   1278
   1279		mvm->net_detect = true;
   1280	} else {
   1281		struct iwl_wowlan_config_cmd wowlan_config_cmd = {};
   1282
   1283		wowlan_config_cmd.sta_id = mvmvif->ap_sta_id;
   1284
   1285		ap_sta = rcu_dereference_protected(
   1286			mvm->fw_id_to_mac_id[mvmvif->ap_sta_id],
   1287			lockdep_is_held(&mvm->mutex));
   1288		if (IS_ERR_OR_NULL(ap_sta)) {
   1289			ret = -EINVAL;
   1290			goto out_noreset;
   1291		}
   1292
   1293		ret = iwl_mvm_get_wowlan_config(mvm, wowlan, &wowlan_config_cmd,
   1294						vif, mvmvif, ap_sta);
   1295		if (ret)
   1296			goto out_noreset;
   1297		ret = iwl_mvm_wowlan_config(mvm, wowlan, &wowlan_config_cmd,
   1298					    vif, mvmvif, ap_sta);
   1299		if (ret)
   1300			goto out;
   1301
   1302		mvm->net_detect = false;
   1303	}
   1304
   1305	ret = iwl_mvm_power_update_device(mvm);
   1306	if (ret)
   1307		goto out;
   1308
   1309	ret = iwl_mvm_power_update_mac(mvm);
   1310	if (ret)
   1311		goto out;
   1312
   1313#ifdef CONFIG_IWLWIFI_DEBUGFS
   1314	if (mvm->d3_wake_sysassert)
   1315		d3_cfg_cmd_data.wakeup_flags |=
   1316			cpu_to_le32(IWL_WAKEUP_D3_CONFIG_FW_ERROR);
   1317#endif
   1318
   1319	/*
   1320	 * Prior to 9000 device family the driver needs to stop the dbg
   1321	 * recording before entering D3. In later devices the FW stops the
   1322	 * recording automatically.
   1323	 */
   1324	if (mvm->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_9000)
   1325		iwl_fw_dbg_stop_restart_recording(&mvm->fwrt, NULL, true);
   1326
   1327	mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_D3;
   1328
   1329	/* must be last -- this switches firmware state */
   1330	ret = iwl_mvm_send_cmd(mvm, &d3_cfg_cmd);
   1331	if (ret)
   1332		goto out;
   1333#ifdef CONFIG_IWLWIFI_DEBUGFS
   1334	len = iwl_rx_packet_payload_len(d3_cfg_cmd.resp_pkt);
   1335	if (len >= sizeof(u32)) {
   1336		mvm->d3_test_pme_ptr =
   1337			le32_to_cpup((__le32 *)d3_cfg_cmd.resp_pkt->data);
   1338	}
   1339#endif
   1340	iwl_free_resp(&d3_cfg_cmd);
   1341
   1342	clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);
   1343
   1344	ret = iwl_trans_d3_suspend(mvm->trans, test, !unified_image);
   1345 out:
   1346	if (ret < 0) {
   1347		iwl_mvm_free_nd(mvm);
   1348
   1349		if (!unified_image) {
   1350			if (mvm->fw_restart > 0) {
   1351				mvm->fw_restart--;
   1352				ieee80211_restart_hw(mvm->hw);
   1353			}
   1354		}
   1355
   1356		clear_bit(IWL_MVM_STATUS_IN_D3, &mvm->status);
   1357	}
   1358 out_noreset:
   1359	mutex_unlock(&mvm->mutex);
   1360
   1361	return ret;
   1362}
   1363
   1364int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
   1365{
   1366	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
   1367
   1368	iwl_mvm_pause_tcm(mvm, true);
   1369
   1370	iwl_fw_runtime_suspend(&mvm->fwrt);
   1371
   1372	return __iwl_mvm_suspend(hw, wowlan, false);
   1373}
   1374
   1375/* converted data from the different status responses */
   1376struct iwl_wowlan_status_data {
   1377	u64 replay_ctr;
   1378	u32 num_of_gtk_rekeys;
   1379	u32 received_beacons;
   1380	u32 wakeup_reasons;
   1381	u32 wake_packet_length;
   1382	u32 wake_packet_bufsize;
   1383	u16 pattern_number;
   1384	u16 non_qos_seq_ctr;
   1385	u16 qos_seq_ctr[8];
   1386	u8 tid_tear_down;
   1387
   1388	struct {
   1389		/* including RX MIC key for TKIP */
   1390		u8 key[WOWLAN_KEY_MAX_SIZE];
   1391		u8 len;
   1392		u8 flags;
   1393	} gtk;
   1394
   1395	struct {
   1396		/*
   1397		 * We store both the TKIP and AES representations
   1398		 * coming from the firmware because we decode the
   1399		 * data from there before we iterate the keys and
   1400		 * know which one we need.
   1401		 */
   1402		struct {
   1403			struct ieee80211_key_seq seq[IWL_MAX_TID_COUNT];
   1404		} tkip, aes;
   1405
   1406		/*
   1407		 * We use -1 for when we have valid data but don't know
   1408		 * the key ID from firmware, and thus it needs to be
   1409		 * installed with the last key (depending on rekeying).
   1410		 */
   1411		s8 key_id;
   1412		bool valid;
   1413	} gtk_seq[2];
   1414
   1415	struct {
   1416		/* Same as above */
   1417		struct {
   1418			struct ieee80211_key_seq seq[IWL_MAX_TID_COUNT];
   1419			u64 tx_pn;
   1420		} tkip, aes;
   1421	} ptk;
   1422
   1423	struct {
   1424		u64 ipn;
   1425		u8 key[WOWLAN_KEY_MAX_SIZE];
   1426		u8 len;
   1427		u8 flags;
   1428	} igtk;
   1429
   1430	u8 wake_packet[];
   1431};
   1432
   1433static void iwl_mvm_report_wakeup_reasons(struct iwl_mvm *mvm,
   1434					  struct ieee80211_vif *vif,
   1435					  struct iwl_wowlan_status_data *status)
   1436{
   1437	struct sk_buff *pkt = NULL;
   1438	struct cfg80211_wowlan_wakeup wakeup = {
   1439		.pattern_idx = -1,
   1440	};
   1441	struct cfg80211_wowlan_wakeup *wakeup_report = &wakeup;
   1442	u32 reasons = status->wakeup_reasons;
   1443
   1444	if (reasons == IWL_WOWLAN_WAKEUP_BY_NON_WIRELESS) {
   1445		wakeup_report = NULL;
   1446		goto report;
   1447	}
   1448
   1449	pm_wakeup_event(mvm->dev, 0);
   1450
   1451	if (reasons & IWL_WOWLAN_WAKEUP_BY_MAGIC_PACKET)
   1452		wakeup.magic_pkt = true;
   1453
   1454	if (reasons & IWL_WOWLAN_WAKEUP_BY_PATTERN)
   1455		wakeup.pattern_idx =
   1456			status->pattern_number;
   1457
   1458	if (reasons & (IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_MISSED_BEACON |
   1459		       IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_DEAUTH))
   1460		wakeup.disconnect = true;
   1461
   1462	if (reasons & IWL_WOWLAN_WAKEUP_BY_GTK_REKEY_FAILURE)
   1463		wakeup.gtk_rekey_failure = true;
   1464
   1465	if (reasons & IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED)
   1466		wakeup.rfkill_release = true;
   1467
   1468	if (reasons & IWL_WOWLAN_WAKEUP_BY_EAPOL_REQUEST)
   1469		wakeup.eap_identity_req = true;
   1470
   1471	if (reasons & IWL_WOWLAN_WAKEUP_BY_FOUR_WAY_HANDSHAKE)
   1472		wakeup.four_way_handshake = true;
   1473
   1474	if (reasons & IWL_WOWLAN_WAKEUP_BY_REM_WAKE_LINK_LOSS)
   1475		wakeup.tcp_connlost = true;
   1476
   1477	if (reasons & IWL_WOWLAN_WAKEUP_BY_REM_WAKE_SIGNATURE_TABLE)
   1478		wakeup.tcp_nomoretokens = true;
   1479
   1480	if (reasons & IWL_WOWLAN_WAKEUP_BY_REM_WAKE_WAKEUP_PACKET)
   1481		wakeup.tcp_match = true;
   1482
   1483	if (status->wake_packet_bufsize) {
   1484		int pktsize = status->wake_packet_bufsize;
   1485		int pktlen = status->wake_packet_length;
   1486		const u8 *pktdata = status->wake_packet;
   1487		const struct ieee80211_hdr *hdr = (const void *)pktdata;
   1488		int truncated = pktlen - pktsize;
   1489
   1490		/* this would be a firmware bug */
   1491		if (WARN_ON_ONCE(truncated < 0))
   1492			truncated = 0;
   1493
   1494		if (ieee80211_is_data(hdr->frame_control)) {
   1495			int hdrlen = ieee80211_hdrlen(hdr->frame_control);
   1496			int ivlen = 0, icvlen = 4; /* also FCS */
   1497
   1498			pkt = alloc_skb(pktsize, GFP_KERNEL);
   1499			if (!pkt)
   1500				goto report;
   1501
   1502			skb_put_data(pkt, pktdata, hdrlen);
   1503			pktdata += hdrlen;
   1504			pktsize -= hdrlen;
   1505
   1506			if (ieee80211_has_protected(hdr->frame_control)) {
   1507				/*
   1508				 * This is unlocked and using gtk_i(c)vlen,
   1509				 * but since everything is under RTNL still
   1510				 * that's not really a problem - changing
   1511				 * it would be difficult.
   1512				 */
   1513				if (is_multicast_ether_addr(hdr->addr1)) {
   1514					ivlen = mvm->gtk_ivlen;
   1515					icvlen += mvm->gtk_icvlen;
   1516				} else {
   1517					ivlen = mvm->ptk_ivlen;
   1518					icvlen += mvm->ptk_icvlen;
   1519				}
   1520			}
   1521
   1522			/* if truncated, FCS/ICV is (partially) gone */
   1523			if (truncated >= icvlen) {
   1524				icvlen = 0;
   1525				truncated -= icvlen;
   1526			} else {
   1527				icvlen -= truncated;
   1528				truncated = 0;
   1529			}
   1530
   1531			pktsize -= ivlen + icvlen;
   1532			pktdata += ivlen;
   1533
   1534			skb_put_data(pkt, pktdata, pktsize);
   1535
   1536			if (ieee80211_data_to_8023(pkt, vif->addr, vif->type))
   1537				goto report;
   1538			wakeup.packet = pkt->data;
   1539			wakeup.packet_present_len = pkt->len;
   1540			wakeup.packet_len = pkt->len - truncated;
   1541			wakeup.packet_80211 = false;
   1542		} else {
   1543			int fcslen = 4;
   1544
   1545			if (truncated >= 4) {
   1546				truncated -= 4;
   1547				fcslen = 0;
   1548			} else {
   1549				fcslen -= truncated;
   1550				truncated = 0;
   1551			}
   1552			pktsize -= fcslen;
   1553			wakeup.packet = status->wake_packet;
   1554			wakeup.packet_present_len = pktsize;
   1555			wakeup.packet_len = pktlen - truncated;
   1556			wakeup.packet_80211 = true;
   1557		}
   1558	}
   1559
   1560 report:
   1561	ieee80211_report_wowlan_wakeup(vif, wakeup_report, GFP_KERNEL);
   1562	kfree_skb(pkt);
   1563}
   1564
   1565static void iwl_mvm_le64_to_aes_seq(__le64 le_pn, struct ieee80211_key_seq *seq)
   1566{
   1567	u64 pn = le64_to_cpu(le_pn);
   1568
   1569	seq->ccmp.pn[0] = pn >> 40;
   1570	seq->ccmp.pn[1] = pn >> 32;
   1571	seq->ccmp.pn[2] = pn >> 24;
   1572	seq->ccmp.pn[3] = pn >> 16;
   1573	seq->ccmp.pn[4] = pn >> 8;
   1574	seq->ccmp.pn[5] = pn;
   1575}
   1576
   1577static void iwl_mvm_aes_sc_to_seq(struct aes_sc *sc,
   1578				  struct ieee80211_key_seq *seq)
   1579{
   1580	iwl_mvm_le64_to_aes_seq(sc->pn, seq);
   1581}
   1582
   1583static void iwl_mvm_le64_to_tkip_seq(__le64 le_pn, struct ieee80211_key_seq *seq)
   1584{
   1585	u64 pn = le64_to_cpu(le_pn);
   1586
   1587	seq->tkip.iv16 = (u16)pn;
   1588	seq->tkip.iv32 = (u32)(pn >> 16);
   1589}
   1590
   1591static void iwl_mvm_tkip_sc_to_seq(struct tkip_sc *sc,
   1592				   struct ieee80211_key_seq *seq)
   1593{
   1594	seq->tkip.iv32 = le32_to_cpu(sc->iv32);
   1595	seq->tkip.iv16 = le16_to_cpu(sc->iv16);
   1596}
   1597
   1598static void iwl_mvm_set_key_rx_seq_tids(struct ieee80211_key_conf *key,
   1599					struct ieee80211_key_seq *seq)
   1600{
   1601	int tid;
   1602
   1603	for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++)
   1604		ieee80211_set_key_rx_seq(key, tid, &seq[tid]);
   1605}
   1606
   1607static void iwl_mvm_set_aes_ptk_rx_seq(struct iwl_mvm *mvm,
   1608				       struct iwl_wowlan_status_data *status,
   1609				       struct ieee80211_sta *sta,
   1610				       struct ieee80211_key_conf *key)
   1611{
   1612	struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
   1613	struct iwl_mvm_key_pn *ptk_pn;
   1614	int tid;
   1615
   1616	iwl_mvm_set_key_rx_seq_tids(key, status->ptk.aes.seq);
   1617
   1618	if (!iwl_mvm_has_new_rx_api(mvm))
   1619		return;
   1620
   1621
   1622	rcu_read_lock();
   1623	ptk_pn = rcu_dereference(mvmsta->ptk_pn[key->keyidx]);
   1624	if (WARN_ON(!ptk_pn)) {
   1625		rcu_read_unlock();
   1626		return;
   1627	}
   1628
   1629	for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++) {
   1630		int i;
   1631
   1632		for (i = 1; i < mvm->trans->num_rx_queues; i++)
   1633			memcpy(ptk_pn->q[i].pn[tid],
   1634			       status->ptk.aes.seq[tid].ccmp.pn,
   1635			       IEEE80211_CCMP_PN_LEN);
   1636	}
   1637	rcu_read_unlock();
   1638}
   1639
   1640static void iwl_mvm_convert_key_counters(struct iwl_wowlan_status_data *status,
   1641					 union iwl_all_tsc_rsc *sc)
   1642{
   1643	int i;
   1644
   1645	BUILD_BUG_ON(IWL_MAX_TID_COUNT > IWL_MAX_TID_COUNT);
   1646	BUILD_BUG_ON(IWL_MAX_TID_COUNT > IWL_NUM_RSC);
   1647
   1648	/* GTK RX counters */
   1649	for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
   1650		iwl_mvm_tkip_sc_to_seq(&sc->tkip.multicast_rsc[i],
   1651				       &status->gtk_seq[0].tkip.seq[i]);
   1652		iwl_mvm_aes_sc_to_seq(&sc->aes.multicast_rsc[i],
   1653				      &status->gtk_seq[0].aes.seq[i]);
   1654	}
   1655	status->gtk_seq[0].valid = true;
   1656	status->gtk_seq[0].key_id = -1;
   1657
   1658	/* PTK TX counter */
   1659	status->ptk.tkip.tx_pn = (u64)le16_to_cpu(sc->tkip.tsc.iv16) |
   1660				 ((u64)le32_to_cpu(sc->tkip.tsc.iv32) << 16);
   1661	status->ptk.aes.tx_pn = le64_to_cpu(sc->aes.tsc.pn);
   1662
   1663	/* PTK RX counters */
   1664	for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
   1665		iwl_mvm_tkip_sc_to_seq(&sc->tkip.unicast_rsc[i],
   1666				       &status->ptk.tkip.seq[i]);
   1667		iwl_mvm_aes_sc_to_seq(&sc->aes.unicast_rsc[i],
   1668				      &status->ptk.aes.seq[i]);
   1669	}
   1670}
   1671
   1672static void
   1673iwl_mvm_convert_key_counters_v5_gtk_seq(struct iwl_wowlan_status_data *status,
   1674					struct iwl_wowlan_all_rsc_tsc_v5 *sc,
   1675					unsigned int idx, unsigned int key_id)
   1676{
   1677	int tid;
   1678
   1679	for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++) {
   1680		iwl_mvm_le64_to_tkip_seq(sc->mcast_rsc[idx][tid],
   1681					 &status->gtk_seq[idx].tkip.seq[tid]);
   1682		iwl_mvm_le64_to_aes_seq(sc->mcast_rsc[idx][tid],
   1683					&status->gtk_seq[idx].aes.seq[tid]);
   1684	}
   1685
   1686	status->gtk_seq[idx].valid = true;
   1687	status->gtk_seq[idx].key_id = key_id;
   1688}
   1689
   1690static void
   1691iwl_mvm_convert_key_counters_v5(struct iwl_wowlan_status_data *status,
   1692				struct iwl_wowlan_all_rsc_tsc_v5 *sc)
   1693{
   1694	int i, tid;
   1695
   1696	BUILD_BUG_ON(IWL_MAX_TID_COUNT > IWL_MAX_TID_COUNT);
   1697	BUILD_BUG_ON(IWL_MAX_TID_COUNT > IWL_NUM_RSC);
   1698	BUILD_BUG_ON(ARRAY_SIZE(sc->mcast_rsc) != ARRAY_SIZE(status->gtk_seq));
   1699
   1700	/* GTK RX counters */
   1701	for (i = 0; i < ARRAY_SIZE(sc->mcast_key_id_map); i++) {
   1702		u8 entry = sc->mcast_key_id_map[i];
   1703
   1704		if (entry < ARRAY_SIZE(sc->mcast_rsc))
   1705			iwl_mvm_convert_key_counters_v5_gtk_seq(status, sc,
   1706								entry, i);
   1707	}
   1708
   1709	/* PTK TX counters not needed, assigned in device */
   1710
   1711	/* PTK RX counters */
   1712	for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++) {
   1713		iwl_mvm_le64_to_tkip_seq(sc->ucast_rsc[tid],
   1714					 &status->ptk.tkip.seq[tid]);
   1715		iwl_mvm_le64_to_aes_seq(sc->ucast_rsc[tid],
   1716					&status->ptk.aes.seq[tid]);
   1717	}
   1718}
   1719
   1720static void iwl_mvm_set_key_rx_seq_idx(struct ieee80211_key_conf *key,
   1721				       struct iwl_wowlan_status_data *status,
   1722				       int idx)
   1723{
   1724	switch (key->cipher) {
   1725	case WLAN_CIPHER_SUITE_CCMP:
   1726	case WLAN_CIPHER_SUITE_GCMP:
   1727	case WLAN_CIPHER_SUITE_GCMP_256:
   1728		iwl_mvm_set_key_rx_seq_tids(key, status->gtk_seq[idx].aes.seq);
   1729		break;
   1730	case WLAN_CIPHER_SUITE_TKIP:
   1731		iwl_mvm_set_key_rx_seq_tids(key, status->gtk_seq[idx].tkip.seq);
   1732		break;
   1733	default:
   1734		WARN_ON(1);
   1735	}
   1736}
   1737
   1738static void iwl_mvm_set_key_rx_seq(struct ieee80211_key_conf *key,
   1739				   struct iwl_wowlan_status_data *status,
   1740				   bool installed)
   1741{
   1742	int i;
   1743
   1744	for (i = 0; i < ARRAY_SIZE(status->gtk_seq); i++) {
   1745		if (!status->gtk_seq[i].valid)
   1746			continue;
   1747
   1748		/* Handle the case where we know the key ID */
   1749		if (status->gtk_seq[i].key_id == key->keyidx) {
   1750			s8 new_key_id = -1;
   1751
   1752			if (status->num_of_gtk_rekeys)
   1753				new_key_id = status->gtk.flags &
   1754						IWL_WOWLAN_GTK_IDX_MASK;
   1755
   1756			/* Don't install a new key's value to an old key */
   1757			if (new_key_id != key->keyidx)
   1758				iwl_mvm_set_key_rx_seq_idx(key, status, i);
   1759			continue;
   1760		}
   1761
   1762		/* handle the case where we didn't, last key only */
   1763		if (status->gtk_seq[i].key_id == -1 &&
   1764		    (!status->num_of_gtk_rekeys || installed))
   1765			iwl_mvm_set_key_rx_seq_idx(key, status, i);
   1766	}
   1767}
   1768
   1769struct iwl_mvm_d3_gtk_iter_data {
   1770	struct iwl_mvm *mvm;
   1771	struct iwl_wowlan_status_data *status;
   1772	void *last_gtk;
   1773	u32 cipher;
   1774	bool find_phase, unhandled_cipher;
   1775	int num_keys;
   1776};
   1777
   1778static void iwl_mvm_d3_update_keys(struct ieee80211_hw *hw,
   1779				   struct ieee80211_vif *vif,
   1780				   struct ieee80211_sta *sta,
   1781				   struct ieee80211_key_conf *key,
   1782				   void *_data)
   1783{
   1784	struct iwl_mvm_d3_gtk_iter_data *data = _data;
   1785	struct iwl_wowlan_status_data *status = data->status;
   1786
   1787	if (data->unhandled_cipher)
   1788		return;
   1789
   1790	switch (key->cipher) {
   1791	case WLAN_CIPHER_SUITE_WEP40:
   1792	case WLAN_CIPHER_SUITE_WEP104:
   1793		/* ignore WEP completely, nothing to do */
   1794		return;
   1795	case WLAN_CIPHER_SUITE_CCMP:
   1796	case WLAN_CIPHER_SUITE_GCMP:
   1797	case WLAN_CIPHER_SUITE_GCMP_256:
   1798	case WLAN_CIPHER_SUITE_TKIP:
   1799		/* we support these */
   1800		break;
   1801	default:
   1802		/* everything else (even CMAC for MFP) - disconnect from AP */
   1803		data->unhandled_cipher = true;
   1804		return;
   1805	}
   1806
   1807	data->num_keys++;
   1808
   1809	/*
   1810	 * pairwise key - update sequence counters only;
   1811	 * note that this assumes no TDLS sessions are active
   1812	 */
   1813	if (sta) {
   1814		if (data->find_phase)
   1815			return;
   1816
   1817		switch (key->cipher) {
   1818		case WLAN_CIPHER_SUITE_CCMP:
   1819		case WLAN_CIPHER_SUITE_GCMP:
   1820		case WLAN_CIPHER_SUITE_GCMP_256:
   1821			atomic64_set(&key->tx_pn, status->ptk.aes.tx_pn);
   1822			iwl_mvm_set_aes_ptk_rx_seq(data->mvm, status, sta, key);
   1823			break;
   1824		case WLAN_CIPHER_SUITE_TKIP:
   1825			atomic64_set(&key->tx_pn, status->ptk.tkip.tx_pn);
   1826			iwl_mvm_set_key_rx_seq_tids(key, status->ptk.tkip.seq);
   1827			break;
   1828		}
   1829
   1830		/* that's it for this key */
   1831		return;
   1832	}
   1833
   1834	if (data->find_phase) {
   1835		data->last_gtk = key;
   1836		data->cipher = key->cipher;
   1837		return;
   1838	}
   1839
   1840	if (data->status->num_of_gtk_rekeys)
   1841		ieee80211_remove_key(key);
   1842
   1843	if (data->last_gtk == key)
   1844		iwl_mvm_set_key_rx_seq(key, data->status, false);
   1845}
   1846
   1847static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm,
   1848					  struct ieee80211_vif *vif,
   1849					  struct iwl_wowlan_status_data *status)
   1850{
   1851	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
   1852	struct iwl_mvm_d3_gtk_iter_data gtkdata = {
   1853		.mvm = mvm,
   1854		.status = status,
   1855	};
   1856	u32 disconnection_reasons =
   1857		IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_MISSED_BEACON |
   1858		IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_DEAUTH;
   1859
   1860	if (!status || !vif->bss_conf.bssid)
   1861		return false;
   1862
   1863	if (status->wakeup_reasons & disconnection_reasons)
   1864		return false;
   1865
   1866	/* find last GTK that we used initially, if any */
   1867	gtkdata.find_phase = true;
   1868	ieee80211_iter_keys(mvm->hw, vif,
   1869			    iwl_mvm_d3_update_keys, &gtkdata);
   1870	/* not trying to keep connections with MFP/unhandled ciphers */
   1871	if (gtkdata.unhandled_cipher)
   1872		return false;
   1873	if (!gtkdata.num_keys)
   1874		goto out;
   1875	if (!gtkdata.last_gtk)
   1876		return false;
   1877
   1878	/*
   1879	 * invalidate all other GTKs that might still exist and update
   1880	 * the one that we used
   1881	 */
   1882	gtkdata.find_phase = false;
   1883	ieee80211_iter_keys(mvm->hw, vif,
   1884			    iwl_mvm_d3_update_keys, &gtkdata);
   1885
   1886	IWL_DEBUG_WOWLAN(mvm, "num of GTK rekeying %d\n",
   1887			 status->num_of_gtk_rekeys);
   1888	if (status->num_of_gtk_rekeys) {
   1889		struct ieee80211_key_conf *key;
   1890		struct {
   1891			struct ieee80211_key_conf conf;
   1892			u8 key[32];
   1893		} conf = {
   1894			.conf.cipher = gtkdata.cipher,
   1895			.conf.keyidx =
   1896				status->gtk.flags & IWL_WOWLAN_GTK_IDX_MASK,
   1897		};
   1898		__be64 replay_ctr;
   1899
   1900		IWL_DEBUG_WOWLAN(mvm,
   1901				 "Received from FW GTK cipher %d, key index %d\n",
   1902				 conf.conf.cipher, conf.conf.keyidx);
   1903
   1904		BUILD_BUG_ON(WLAN_KEY_LEN_CCMP != WLAN_KEY_LEN_GCMP);
   1905		BUILD_BUG_ON(sizeof(conf.key) < WLAN_KEY_LEN_CCMP);
   1906		BUILD_BUG_ON(sizeof(conf.key) < WLAN_KEY_LEN_GCMP_256);
   1907		BUILD_BUG_ON(sizeof(conf.key) < WLAN_KEY_LEN_TKIP);
   1908		BUILD_BUG_ON(sizeof(conf.key) < sizeof(status->gtk.key));
   1909
   1910		memcpy(conf.conf.key, status->gtk.key, sizeof(status->gtk.key));
   1911
   1912		switch (gtkdata.cipher) {
   1913		case WLAN_CIPHER_SUITE_CCMP:
   1914		case WLAN_CIPHER_SUITE_GCMP:
   1915			conf.conf.keylen = WLAN_KEY_LEN_CCMP;
   1916			break;
   1917		case WLAN_CIPHER_SUITE_GCMP_256:
   1918			conf.conf.keylen = WLAN_KEY_LEN_GCMP_256;
   1919			break;
   1920		case WLAN_CIPHER_SUITE_TKIP:
   1921			conf.conf.keylen = WLAN_KEY_LEN_TKIP;
   1922			break;
   1923		}
   1924
   1925		key = ieee80211_gtk_rekey_add(vif, &conf.conf);
   1926		if (IS_ERR(key))
   1927			return false;
   1928		iwl_mvm_set_key_rx_seq(key, status, true);
   1929
   1930		replay_ctr = cpu_to_be64(status->replay_ctr);
   1931
   1932		ieee80211_gtk_rekey_notify(vif, vif->bss_conf.bssid,
   1933					   (void *)&replay_ctr, GFP_KERNEL);
   1934	}
   1935
   1936out:
   1937	if (iwl_fw_lookup_notif_ver(mvm->fw, LONG_GROUP,
   1938				    WOWLAN_GET_STATUSES, 0) < 10) {
   1939		mvmvif->seqno_valid = true;
   1940		/* +0x10 because the set API expects next-to-use, not last-used */
   1941		mvmvif->seqno = status->non_qos_seq_ctr + 0x10;
   1942	}
   1943
   1944	return true;
   1945}
   1946
   1947/* Occasionally, templates would be nice. This is one of those times ... */
   1948#define iwl_mvm_parse_wowlan_status_common(_ver)			\
   1949static struct iwl_wowlan_status_data *					\
   1950iwl_mvm_parse_wowlan_status_common_ ## _ver(struct iwl_mvm *mvm,	\
   1951					    struct iwl_wowlan_status_ ##_ver *data,\
   1952					    int len)			\
   1953{									\
   1954	struct iwl_wowlan_status_data *status;				\
   1955	int data_size, i;						\
   1956									\
   1957	if (len < sizeof(*data)) {					\
   1958		IWL_ERR(mvm, "Invalid WoWLAN status response!\n");	\
   1959		return NULL;						\
   1960	}								\
   1961									\
   1962	data_size = ALIGN(le32_to_cpu(data->wake_packet_bufsize), 4);	\
   1963	if (len != sizeof(*data) + data_size) {				\
   1964		IWL_ERR(mvm, "Invalid WoWLAN status response!\n");	\
   1965		return NULL;						\
   1966	}								\
   1967									\
   1968	status = kzalloc(sizeof(*status) + data_size, GFP_KERNEL);	\
   1969	if (!status)							\
   1970		return NULL;						\
   1971									\
   1972	/* copy all the common fields */				\
   1973	status->replay_ctr = le64_to_cpu(data->replay_ctr);		\
   1974	status->pattern_number = le16_to_cpu(data->pattern_number);	\
   1975	status->non_qos_seq_ctr = le16_to_cpu(data->non_qos_seq_ctr);	\
   1976	for (i = 0; i < 8; i++)						\
   1977		status->qos_seq_ctr[i] =				\
   1978			le16_to_cpu(data->qos_seq_ctr[i]);		\
   1979	status->wakeup_reasons = le32_to_cpu(data->wakeup_reasons);	\
   1980	status->num_of_gtk_rekeys =					\
   1981		le32_to_cpu(data->num_of_gtk_rekeys);			\
   1982	status->received_beacons = le32_to_cpu(data->received_beacons);	\
   1983	status->wake_packet_length =					\
   1984		le32_to_cpu(data->wake_packet_length);			\
   1985	status->wake_packet_bufsize =					\
   1986		le32_to_cpu(data->wake_packet_bufsize);			\
   1987	memcpy(status->wake_packet, data->wake_packet,			\
   1988	       status->wake_packet_bufsize);				\
   1989									\
   1990	return status;							\
   1991}
   1992
   1993iwl_mvm_parse_wowlan_status_common(v6)
   1994iwl_mvm_parse_wowlan_status_common(v7)
   1995iwl_mvm_parse_wowlan_status_common(v9)
   1996iwl_mvm_parse_wowlan_status_common(v12)
   1997
   1998static void iwl_mvm_convert_gtk_v2(struct iwl_wowlan_status_data *status,
   1999				   struct iwl_wowlan_gtk_status_v2 *data)
   2000{
   2001	BUILD_BUG_ON(sizeof(status->gtk.key) < sizeof(data->key));
   2002	BUILD_BUG_ON(NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY +
   2003		     sizeof(data->tkip_mic_key) >
   2004		     sizeof(status->gtk.key));
   2005
   2006	status->gtk.len = data->key_len;
   2007	status->gtk.flags = data->key_flags;
   2008
   2009	memcpy(status->gtk.key, data->key, sizeof(data->key));
   2010
   2011	/* if it's as long as the TKIP encryption key, copy MIC key */
   2012	if (status->gtk.len == NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY)
   2013		memcpy(status->gtk.key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY,
   2014		       data->tkip_mic_key, sizeof(data->tkip_mic_key));
   2015}
   2016
   2017static void iwl_mvm_convert_gtk_v3(struct iwl_wowlan_status_data *status,
   2018				   struct iwl_wowlan_gtk_status_v3 *data)
   2019{
   2020	/* The parts we need are identical in v2 and v3 */
   2021#define CHECK(_f) do {							\
   2022	BUILD_BUG_ON(offsetof(struct iwl_wowlan_gtk_status_v2, _f) !=	\
   2023		     offsetof(struct iwl_wowlan_gtk_status_v3, _f));	\
   2024	BUILD_BUG_ON(offsetofend(struct iwl_wowlan_gtk_status_v2, _f) !=\
   2025		     offsetofend(struct iwl_wowlan_gtk_status_v3, _f));	\
   2026} while (0)
   2027
   2028	CHECK(key);
   2029	CHECK(key_len);
   2030	CHECK(key_flags);
   2031	CHECK(tkip_mic_key);
   2032#undef CHECK
   2033
   2034	iwl_mvm_convert_gtk_v2(status, (void *)data);
   2035}
   2036
   2037static void iwl_mvm_convert_igtk(struct iwl_wowlan_status_data *status,
   2038				 struct iwl_wowlan_igtk_status *data)
   2039{
   2040	const u8 *ipn = data->ipn;
   2041
   2042	BUILD_BUG_ON(sizeof(status->igtk.key) < sizeof(data->key));
   2043
   2044	status->igtk.len = data->key_len;
   2045	status->igtk.flags = data->key_flags;
   2046
   2047	memcpy(status->igtk.key, data->key, sizeof(data->key));
   2048
   2049	status->igtk.ipn = ((u64)ipn[5] <<  0) |
   2050			   ((u64)ipn[4] <<  8) |
   2051			   ((u64)ipn[3] << 16) |
   2052			   ((u64)ipn[2] << 24) |
   2053			   ((u64)ipn[1] << 32) |
   2054			   ((u64)ipn[0] << 40);
   2055}
   2056
   2057static struct iwl_wowlan_status_data *
   2058iwl_mvm_send_wowlan_get_status(struct iwl_mvm *mvm, u8 sta_id)
   2059{
   2060	struct iwl_wowlan_status_data *status;
   2061	struct iwl_wowlan_get_status_cmd get_status_cmd = {
   2062		.sta_id = cpu_to_le32(sta_id),
   2063	};
   2064	struct iwl_host_cmd cmd = {
   2065		.id = WOWLAN_GET_STATUSES,
   2066		.flags = CMD_WANT_SKB,
   2067		.data = { &get_status_cmd, },
   2068		.len = { sizeof(get_status_cmd), },
   2069	};
   2070	int ret, len;
   2071	u8 notif_ver;
   2072	u8 cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, cmd.id,
   2073					   IWL_FW_CMD_VER_UNKNOWN);
   2074
   2075	if (cmd_ver == IWL_FW_CMD_VER_UNKNOWN)
   2076		cmd.len[0] = 0;
   2077
   2078	lockdep_assert_held(&mvm->mutex);
   2079
   2080	ret = iwl_mvm_send_cmd(mvm, &cmd);
   2081	if (ret) {
   2082		IWL_ERR(mvm, "failed to query wakeup status (%d)\n", ret);
   2083		return ERR_PTR(ret);
   2084	}
   2085
   2086	len = iwl_rx_packet_payload_len(cmd.resp_pkt);
   2087
   2088	/* default to 7 (when we have IWL_UCODE_TLV_API_WOWLAN_KEY_MATERIAL) */
   2089	notif_ver = iwl_fw_lookup_notif_ver(mvm->fw, LONG_GROUP,
   2090					    WOWLAN_GET_STATUSES, 0);
   2091	if (!notif_ver)
   2092		notif_ver = iwl_fw_lookup_notif_ver(mvm->fw, LEGACY_GROUP,
   2093						    WOWLAN_GET_STATUSES, 7);
   2094
   2095	if (!fw_has_api(&mvm->fw->ucode_capa,
   2096			IWL_UCODE_TLV_API_WOWLAN_KEY_MATERIAL)) {
   2097		struct iwl_wowlan_status_v6 *v6 = (void *)cmd.resp_pkt->data;
   2098
   2099		status = iwl_mvm_parse_wowlan_status_common_v6(mvm, v6, len);
   2100		if (!status)
   2101			goto out_free_resp;
   2102
   2103		BUILD_BUG_ON(sizeof(v6->gtk.decrypt_key) >
   2104			     sizeof(status->gtk.key));
   2105		BUILD_BUG_ON(NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY +
   2106			     sizeof(v6->gtk.tkip_mic_key) >
   2107			     sizeof(status->gtk.key));
   2108
   2109		/* copy GTK info to the right place */
   2110		memcpy(status->gtk.key, v6->gtk.decrypt_key,
   2111		       sizeof(v6->gtk.decrypt_key));
   2112		memcpy(status->gtk.key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY,
   2113		       v6->gtk.tkip_mic_key,
   2114		       sizeof(v6->gtk.tkip_mic_key));
   2115
   2116		iwl_mvm_convert_key_counters(status, &v6->gtk.rsc.all_tsc_rsc);
   2117
   2118		/* hardcode the key length to 16 since v6 only supports 16 */
   2119		status->gtk.len = 16;
   2120
   2121		/*
   2122		 * The key index only uses 2 bits (values 0 to 3) and
   2123		 * we always set bit 7 which means this is the
   2124		 * currently used key.
   2125		 */
   2126		status->gtk.flags = v6->gtk.key_index | BIT(7);
   2127	} else if (notif_ver == 7) {
   2128		struct iwl_wowlan_status_v7 *v7 = (void *)cmd.resp_pkt->data;
   2129
   2130		status = iwl_mvm_parse_wowlan_status_common_v7(mvm, v7, len);
   2131		if (!status)
   2132			goto out_free_resp;
   2133
   2134		iwl_mvm_convert_key_counters(status, &v7->gtk[0].rsc.all_tsc_rsc);
   2135		iwl_mvm_convert_gtk_v2(status, &v7->gtk[0]);
   2136		iwl_mvm_convert_igtk(status, &v7->igtk[0]);
   2137	} else if (notif_ver == 9 || notif_ver == 10 || notif_ver == 11) {
   2138		struct iwl_wowlan_status_v9 *v9 = (void *)cmd.resp_pkt->data;
   2139
   2140		/* these three command versions have same layout and size, the
   2141		 * difference is only in a few not used (reserved) fields.
   2142		 */
   2143		status = iwl_mvm_parse_wowlan_status_common_v9(mvm, v9, len);
   2144		if (!status)
   2145			goto out_free_resp;
   2146
   2147		iwl_mvm_convert_key_counters(status, &v9->gtk[0].rsc.all_tsc_rsc);
   2148		iwl_mvm_convert_gtk_v2(status, &v9->gtk[0]);
   2149		iwl_mvm_convert_igtk(status, &v9->igtk[0]);
   2150
   2151		status->tid_tear_down = v9->tid_tear_down;
   2152	} else if (notif_ver == 12) {
   2153		struct iwl_wowlan_status_v12 *v12 = (void *)cmd.resp_pkt->data;
   2154
   2155		status = iwl_mvm_parse_wowlan_status_common_v12(mvm, v12, len);
   2156		if (!status)
   2157			goto out_free_resp;
   2158
   2159		iwl_mvm_convert_key_counters_v5(status, &v12->gtk[0].sc);
   2160		iwl_mvm_convert_gtk_v3(status, &v12->gtk[0]);
   2161		iwl_mvm_convert_igtk(status, &v12->igtk[0]);
   2162
   2163		status->tid_tear_down = v12->tid_tear_down;
   2164	} else {
   2165		IWL_ERR(mvm,
   2166			"Firmware advertises unknown WoWLAN status response %d!\n",
   2167			notif_ver);
   2168		status = NULL;
   2169	}
   2170
   2171out_free_resp:
   2172	iwl_free_resp(&cmd);
   2173	return status;
   2174}
   2175
   2176static struct iwl_wowlan_status_data *
   2177iwl_mvm_get_wakeup_status(struct iwl_mvm *mvm, u8 sta_id)
   2178{
   2179	u8 cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, OFFLOADS_QUERY_CMD,
   2180					   IWL_FW_CMD_VER_UNKNOWN);
   2181	__le32 station_id = cpu_to_le32(sta_id);
   2182	u32 cmd_size = cmd_ver != IWL_FW_CMD_VER_UNKNOWN ? sizeof(station_id) : 0;
   2183
   2184	if (!mvm->net_detect) {
   2185		/* only for tracing for now */
   2186		int ret = iwl_mvm_send_cmd_pdu(mvm, OFFLOADS_QUERY_CMD, 0,
   2187					       cmd_size, &station_id);
   2188		if (ret)
   2189			IWL_ERR(mvm, "failed to query offload statistics (%d)\n", ret);
   2190	}
   2191
   2192	return iwl_mvm_send_wowlan_get_status(mvm, sta_id);
   2193}
   2194
   2195/* releases the MVM mutex */
   2196static bool iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
   2197					 struct ieee80211_vif *vif)
   2198{
   2199	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
   2200	struct iwl_wowlan_status_data *status;
   2201	int i;
   2202	bool keep;
   2203	struct iwl_mvm_sta *mvm_ap_sta;
   2204
   2205	status = iwl_mvm_get_wakeup_status(mvm, mvmvif->ap_sta_id);
   2206	if (!status)
   2207		goto out_unlock;
   2208
   2209	IWL_DEBUG_WOWLAN(mvm, "wakeup reason 0x%x\n",
   2210			 status->wakeup_reasons);
   2211
   2212	/* still at hard-coded place 0 for D3 image */
   2213	mvm_ap_sta = iwl_mvm_sta_from_staid_protected(mvm, 0);
   2214	if (!mvm_ap_sta)
   2215		goto out_free;
   2216
   2217	for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
   2218		u16 seq = status->qos_seq_ctr[i];
   2219		/* firmware stores last-used value, we store next value */
   2220		seq += 0x10;
   2221		mvm_ap_sta->tid_data[i].seq_number = seq;
   2222	}
   2223
   2224	if (mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22000) {
   2225		i = mvm->offload_tid;
   2226		iwl_trans_set_q_ptrs(mvm->trans,
   2227				     mvm_ap_sta->tid_data[i].txq_id,
   2228				     mvm_ap_sta->tid_data[i].seq_number >> 4);
   2229	}
   2230
   2231	/* now we have all the data we need, unlock to avoid mac80211 issues */
   2232	mutex_unlock(&mvm->mutex);
   2233
   2234	iwl_mvm_report_wakeup_reasons(mvm, vif, status);
   2235
   2236	keep = iwl_mvm_setup_connection_keep(mvm, vif, status);
   2237
   2238	kfree(status);
   2239	return keep;
   2240
   2241out_free:
   2242	kfree(status);
   2243out_unlock:
   2244	mutex_unlock(&mvm->mutex);
   2245	return false;
   2246}
   2247
   2248#define ND_QUERY_BUF_LEN (sizeof(struct iwl_scan_offload_profile_match) * \
   2249			  IWL_SCAN_MAX_PROFILES)
   2250
   2251struct iwl_mvm_nd_query_results {
   2252	u32 matched_profiles;
   2253	u8 matches[ND_QUERY_BUF_LEN];
   2254};
   2255
   2256static int
   2257iwl_mvm_netdetect_query_results(struct iwl_mvm *mvm,
   2258				struct iwl_mvm_nd_query_results *results)
   2259{
   2260	struct iwl_scan_offload_profiles_query *query;
   2261	struct iwl_host_cmd cmd = {
   2262		.id = SCAN_OFFLOAD_PROFILES_QUERY_CMD,
   2263		.flags = CMD_WANT_SKB,
   2264	};
   2265	int ret, len;
   2266	size_t query_len, matches_len;
   2267	int max_profiles = iwl_umac_scan_get_max_profiles(mvm->fw);
   2268
   2269	ret = iwl_mvm_send_cmd(mvm, &cmd);
   2270	if (ret) {
   2271		IWL_ERR(mvm, "failed to query matched profiles (%d)\n", ret);
   2272		return ret;
   2273	}
   2274
   2275	if (fw_has_api(&mvm->fw->ucode_capa,
   2276		       IWL_UCODE_TLV_API_SCAN_OFFLOAD_CHANS)) {
   2277		query_len = sizeof(struct iwl_scan_offload_profiles_query);
   2278		matches_len = sizeof(struct iwl_scan_offload_profile_match) *
   2279			max_profiles;
   2280	} else {
   2281		query_len = sizeof(struct iwl_scan_offload_profiles_query_v1);
   2282		matches_len = sizeof(struct iwl_scan_offload_profile_match_v1) *
   2283			max_profiles;
   2284	}
   2285
   2286	len = iwl_rx_packet_payload_len(cmd.resp_pkt);
   2287	if (len < query_len) {
   2288		IWL_ERR(mvm, "Invalid scan offload profiles query response!\n");
   2289		ret = -EIO;
   2290		goto out_free_resp;
   2291	}
   2292
   2293	query = (void *)cmd.resp_pkt->data;
   2294
   2295	results->matched_profiles = le32_to_cpu(query->matched_profiles);
   2296	memcpy(results->matches, query->matches, matches_len);
   2297
   2298#ifdef CONFIG_IWLWIFI_DEBUGFS
   2299	mvm->last_netdetect_scans = le32_to_cpu(query->n_scans_done);
   2300#endif
   2301
   2302out_free_resp:
   2303	iwl_free_resp(&cmd);
   2304	return ret;
   2305}
   2306
   2307static int iwl_mvm_query_num_match_chans(struct iwl_mvm *mvm,
   2308					 struct iwl_mvm_nd_query_results *query,
   2309					 int idx)
   2310{
   2311	int n_chans = 0, i;
   2312
   2313	if (fw_has_api(&mvm->fw->ucode_capa,
   2314		       IWL_UCODE_TLV_API_SCAN_OFFLOAD_CHANS)) {
   2315		struct iwl_scan_offload_profile_match *matches =
   2316			(struct iwl_scan_offload_profile_match *)query->matches;
   2317
   2318		for (i = 0; i < SCAN_OFFLOAD_MATCHING_CHANNELS_LEN; i++)
   2319			n_chans += hweight8(matches[idx].matching_channels[i]);
   2320	} else {
   2321		struct iwl_scan_offload_profile_match_v1 *matches =
   2322			(struct iwl_scan_offload_profile_match_v1 *)query->matches;
   2323
   2324		for (i = 0; i < SCAN_OFFLOAD_MATCHING_CHANNELS_LEN_V1; i++)
   2325			n_chans += hweight8(matches[idx].matching_channels[i]);
   2326	}
   2327
   2328	return n_chans;
   2329}
   2330
   2331static void iwl_mvm_query_set_freqs(struct iwl_mvm *mvm,
   2332				    struct iwl_mvm_nd_query_results *query,
   2333				    struct cfg80211_wowlan_nd_match *match,
   2334				    int idx)
   2335{
   2336	int i;
   2337
   2338	if (fw_has_api(&mvm->fw->ucode_capa,
   2339		       IWL_UCODE_TLV_API_SCAN_OFFLOAD_CHANS)) {
   2340		struct iwl_scan_offload_profile_match *matches =
   2341			(struct iwl_scan_offload_profile_match *)query->matches;
   2342
   2343		for (i = 0; i < SCAN_OFFLOAD_MATCHING_CHANNELS_LEN * 8; i++)
   2344			if (matches[idx].matching_channels[i / 8] & (BIT(i % 8)))
   2345				match->channels[match->n_channels++] =
   2346					mvm->nd_channels[i]->center_freq;
   2347	} else {
   2348		struct iwl_scan_offload_profile_match_v1 *matches =
   2349			(struct iwl_scan_offload_profile_match_v1 *)query->matches;
   2350
   2351		for (i = 0; i < SCAN_OFFLOAD_MATCHING_CHANNELS_LEN_V1 * 8; i++)
   2352			if (matches[idx].matching_channels[i / 8] & (BIT(i % 8)))
   2353				match->channels[match->n_channels++] =
   2354					mvm->nd_channels[i]->center_freq;
   2355	}
   2356}
   2357
   2358static void iwl_mvm_query_netdetect_reasons(struct iwl_mvm *mvm,
   2359					    struct ieee80211_vif *vif)
   2360{
   2361	struct cfg80211_wowlan_nd_info *net_detect = NULL;
   2362	struct cfg80211_wowlan_wakeup wakeup = {
   2363		.pattern_idx = -1,
   2364	};
   2365	struct cfg80211_wowlan_wakeup *wakeup_report = &wakeup;
   2366	struct iwl_wowlan_status_data *status;
   2367	struct iwl_mvm_nd_query_results query;
   2368	unsigned long matched_profiles;
   2369	u32 reasons = 0;
   2370	int i, n_matches, ret;
   2371
   2372	status = iwl_mvm_get_wakeup_status(mvm, IWL_MVM_INVALID_STA);
   2373	if (status) {
   2374		reasons = status->wakeup_reasons;
   2375		kfree(status);
   2376	}
   2377
   2378	if (reasons & IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED)
   2379		wakeup.rfkill_release = true;
   2380
   2381	if (reasons != IWL_WOWLAN_WAKEUP_BY_NON_WIRELESS)
   2382		goto out;
   2383
   2384	ret = iwl_mvm_netdetect_query_results(mvm, &query);
   2385	if (ret || !query.matched_profiles) {
   2386		wakeup_report = NULL;
   2387		goto out;
   2388	}
   2389
   2390	matched_profiles = query.matched_profiles;
   2391	if (mvm->n_nd_match_sets) {
   2392		n_matches = hweight_long(matched_profiles);
   2393	} else {
   2394		IWL_ERR(mvm, "no net detect match information available\n");
   2395		n_matches = 0;
   2396	}
   2397
   2398	net_detect = kzalloc(struct_size(net_detect, matches, n_matches),
   2399			     GFP_KERNEL);
   2400	if (!net_detect || !n_matches)
   2401		goto out_report_nd;
   2402
   2403	for_each_set_bit(i, &matched_profiles, mvm->n_nd_match_sets) {
   2404		struct cfg80211_wowlan_nd_match *match;
   2405		int idx, n_channels = 0;
   2406
   2407		n_channels = iwl_mvm_query_num_match_chans(mvm, &query, i);
   2408
   2409		match = kzalloc(struct_size(match, channels, n_channels),
   2410				GFP_KERNEL);
   2411		if (!match)
   2412			goto out_report_nd;
   2413
   2414		net_detect->matches[net_detect->n_matches++] = match;
   2415
   2416		/* We inverted the order of the SSIDs in the scan
   2417		 * request, so invert the index here.
   2418		 */
   2419		idx = mvm->n_nd_match_sets - i - 1;
   2420		match->ssid.ssid_len = mvm->nd_match_sets[idx].ssid.ssid_len;
   2421		memcpy(match->ssid.ssid, mvm->nd_match_sets[idx].ssid.ssid,
   2422		       match->ssid.ssid_len);
   2423
   2424		if (mvm->n_nd_channels < n_channels)
   2425			continue;
   2426
   2427		iwl_mvm_query_set_freqs(mvm, &query, match, i);
   2428	}
   2429
   2430out_report_nd:
   2431	wakeup.net_detect = net_detect;
   2432out:
   2433	iwl_mvm_free_nd(mvm);
   2434
   2435	mutex_unlock(&mvm->mutex);
   2436	ieee80211_report_wowlan_wakeup(vif, wakeup_report, GFP_KERNEL);
   2437
   2438	if (net_detect) {
   2439		for (i = 0; i < net_detect->n_matches; i++)
   2440			kfree(net_detect->matches[i]);
   2441		kfree(net_detect);
   2442	}
   2443}
   2444
   2445static void iwl_mvm_d3_disconnect_iter(void *data, u8 *mac,
   2446				       struct ieee80211_vif *vif)
   2447{
   2448	/* skip the one we keep connection on */
   2449	if (data == vif)
   2450		return;
   2451
   2452	if (vif->type == NL80211_IFTYPE_STATION)
   2453		ieee80211_resume_disconnect(vif);
   2454}
   2455
   2456static bool iwl_mvm_rt_status(struct iwl_trans *trans, u32 base, u32 *err_id)
   2457{
   2458	struct error_table_start {
   2459		/* cf. struct iwl_error_event_table */
   2460		u32 valid;
   2461		__le32 err_id;
   2462	} err_info;
   2463
   2464	if (!base)
   2465		return false;
   2466
   2467	iwl_trans_read_mem_bytes(trans, base,
   2468				 &err_info, sizeof(err_info));
   2469	if (err_info.valid && err_id)
   2470		*err_id = le32_to_cpu(err_info.err_id);
   2471
   2472	return !!err_info.valid;
   2473}
   2474
   2475static bool iwl_mvm_check_rt_status(struct iwl_mvm *mvm,
   2476				   struct ieee80211_vif *vif)
   2477{
   2478	u32 err_id;
   2479
   2480	/* check for lmac1 error */
   2481	if (iwl_mvm_rt_status(mvm->trans,
   2482			      mvm->trans->dbg.lmac_error_event_table[0],
   2483			      &err_id)) {
   2484		if (err_id == RF_KILL_INDICATOR_FOR_WOWLAN) {
   2485			struct cfg80211_wowlan_wakeup wakeup = {
   2486				.rfkill_release = true,
   2487			};
   2488			ieee80211_report_wowlan_wakeup(vif, &wakeup,
   2489						       GFP_KERNEL);
   2490		}
   2491		return true;
   2492	}
   2493
   2494	/* check if we have lmac2 set and check for error */
   2495	if (iwl_mvm_rt_status(mvm->trans,
   2496			      mvm->trans->dbg.lmac_error_event_table[1], NULL))
   2497		return true;
   2498
   2499	/* check for umac error */
   2500	if (iwl_mvm_rt_status(mvm->trans,
   2501			      mvm->trans->dbg.umac_error_event_table, NULL))
   2502		return true;
   2503
   2504	return false;
   2505}
   2506
   2507static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test)
   2508{
   2509	struct ieee80211_vif *vif = NULL;
   2510	int ret = 1;
   2511	enum iwl_d3_status d3_status;
   2512	bool keep = false;
   2513	bool unified_image = fw_has_capa(&mvm->fw->ucode_capa,
   2514					 IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);
   2515	bool d0i3_first = fw_has_capa(&mvm->fw->ucode_capa,
   2516				      IWL_UCODE_TLV_CAPA_D0I3_END_FIRST);
   2517
   2518	mutex_lock(&mvm->mutex);
   2519
   2520	mvm->last_reset_or_resume_time_jiffies = jiffies;
   2521
   2522	/* get the BSS vif pointer again */
   2523	vif = iwl_mvm_get_bss_vif(mvm);
   2524	if (IS_ERR_OR_NULL(vif))
   2525		goto err;
   2526
   2527	iwl_fw_dbg_read_d3_debug_data(&mvm->fwrt);
   2528
   2529	if (iwl_mvm_check_rt_status(mvm, vif)) {
   2530		set_bit(STATUS_FW_ERROR, &mvm->trans->status);
   2531		iwl_mvm_dump_nic_error_log(mvm);
   2532		iwl_dbg_tlv_time_point(&mvm->fwrt,
   2533				       IWL_FW_INI_TIME_POINT_FW_ASSERT, NULL);
   2534		iwl_fw_dbg_collect_desc(&mvm->fwrt, &iwl_dump_desc_assert,
   2535					false, 0);
   2536		ret = 1;
   2537		goto err;
   2538	}
   2539
   2540	ret = iwl_trans_d3_resume(mvm->trans, &d3_status, test, !unified_image);
   2541	if (ret)
   2542		goto err;
   2543
   2544	if (d3_status != IWL_D3_STATUS_ALIVE) {
   2545		IWL_INFO(mvm, "Device was reset during suspend\n");
   2546		goto err;
   2547	}
   2548
   2549	if (d0i3_first) {
   2550		struct iwl_host_cmd cmd = {
   2551			.id = D0I3_END_CMD,
   2552			.flags = CMD_WANT_SKB | CMD_SEND_IN_D3,
   2553		};
   2554		int len;
   2555
   2556		ret = iwl_mvm_send_cmd(mvm, &cmd);
   2557		if (ret < 0) {
   2558			IWL_ERR(mvm, "Failed to send D0I3_END_CMD first (%d)\n",
   2559				ret);
   2560			goto err;
   2561		}
   2562		switch (mvm->cmd_ver.d0i3_resp) {
   2563		case 0:
   2564			break;
   2565		case 1:
   2566			len = iwl_rx_packet_payload_len(cmd.resp_pkt);
   2567			if (len != sizeof(u32)) {
   2568				IWL_ERR(mvm,
   2569					"Error with D0I3_END_CMD response size (%d)\n",
   2570					len);
   2571				goto err;
   2572			}
   2573			if (IWL_D0I3_RESET_REQUIRE &
   2574			    le32_to_cpu(*(__le32 *)cmd.resp_pkt->data)) {
   2575				iwl_write32(mvm->trans, CSR_RESET,
   2576					    CSR_RESET_REG_FLAG_FORCE_NMI);
   2577				iwl_free_resp(&cmd);
   2578			}
   2579			break;
   2580		default:
   2581			WARN_ON(1);
   2582		}
   2583	}
   2584
   2585	/* after the successful handshake, we're out of D3 */
   2586	mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_DISABLED;
   2587
   2588	/*
   2589	 * Query the current location and source from the D3 firmware so we
   2590	 * can play it back when we re-intiailize the D0 firmware
   2591	 */
   2592	iwl_mvm_update_changed_regdom(mvm);
   2593
   2594	/* Re-configure PPAG settings */
   2595	iwl_mvm_ppag_send_cmd(mvm);
   2596
   2597	if (!unified_image)
   2598		/*  Re-configure default SAR profile */
   2599		iwl_mvm_sar_select_profile(mvm, 1, 1);
   2600
   2601	if (mvm->net_detect) {
   2602		/* If this is a non-unified image, we restart the FW,
   2603		 * so no need to stop the netdetect scan.  If that
   2604		 * fails, continue and try to get the wake-up reasons,
   2605		 * but trigger a HW restart by keeping a failure code
   2606		 * in ret.
   2607		 */
   2608		if (unified_image)
   2609			ret = iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_NETDETECT,
   2610						false);
   2611
   2612		iwl_mvm_query_netdetect_reasons(mvm, vif);
   2613		/* has unlocked the mutex, so skip that */
   2614		goto out;
   2615	} else {
   2616		keep = iwl_mvm_query_wakeup_reasons(mvm, vif);
   2617#ifdef CONFIG_IWLWIFI_DEBUGFS
   2618		if (keep)
   2619			mvm->keep_vif = vif;
   2620#endif
   2621		/* has unlocked the mutex, so skip that */
   2622		goto out_iterate;
   2623	}
   2624
   2625err:
   2626	iwl_mvm_free_nd(mvm);
   2627	mutex_unlock(&mvm->mutex);
   2628
   2629out_iterate:
   2630	if (!test)
   2631		ieee80211_iterate_active_interfaces_mtx(mvm->hw,
   2632			IEEE80211_IFACE_ITER_NORMAL,
   2633			iwl_mvm_d3_disconnect_iter, keep ? vif : NULL);
   2634
   2635out:
   2636	clear_bit(IWL_MVM_STATUS_IN_D3, &mvm->status);
   2637
   2638	/* no need to reset the device in unified images, if successful */
   2639	if (unified_image && !ret) {
   2640		/* nothing else to do if we already sent D0I3_END_CMD */
   2641		if (d0i3_first)
   2642			return 0;
   2643
   2644		ret = iwl_mvm_send_cmd_pdu(mvm, D0I3_END_CMD, 0, 0, NULL);
   2645		if (!ret)
   2646			return 0;
   2647	}
   2648
   2649	/*
   2650	 * Reconfigure the device in one of the following cases:
   2651	 * 1. We are not using a unified image
   2652	 * 2. We are using a unified image but had an error while exiting D3
   2653	 */
   2654	set_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, &mvm->status);
   2655
   2656	/* regardless of what happened, we're now out of D3 */
   2657	mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_DISABLED;
   2658
   2659	return 1;
   2660}
   2661
   2662int iwl_mvm_resume(struct ieee80211_hw *hw)
   2663{
   2664	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
   2665	int ret;
   2666
   2667	ret = __iwl_mvm_resume(mvm, false);
   2668
   2669	iwl_mvm_resume_tcm(mvm);
   2670
   2671	iwl_fw_runtime_resume(&mvm->fwrt);
   2672
   2673	return ret;
   2674}
   2675
   2676void iwl_mvm_set_wakeup(struct ieee80211_hw *hw, bool enabled)
   2677{
   2678	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
   2679
   2680	device_set_wakeup_enable(mvm->trans->dev, enabled);
   2681}
   2682
   2683#ifdef CONFIG_IWLWIFI_DEBUGFS
   2684static int iwl_mvm_d3_test_open(struct inode *inode, struct file *file)
   2685{
   2686	struct iwl_mvm *mvm = inode->i_private;
   2687	int err;
   2688
   2689	if (mvm->d3_test_active)
   2690		return -EBUSY;
   2691
   2692	file->private_data = inode->i_private;
   2693
   2694	iwl_mvm_pause_tcm(mvm, true);
   2695
   2696	iwl_fw_runtime_suspend(&mvm->fwrt);
   2697
   2698	/* start pseudo D3 */
   2699	rtnl_lock();
   2700	wiphy_lock(mvm->hw->wiphy);
   2701	err = __iwl_mvm_suspend(mvm->hw, mvm->hw->wiphy->wowlan_config, true);
   2702	wiphy_unlock(mvm->hw->wiphy);
   2703	rtnl_unlock();
   2704	if (err > 0)
   2705		err = -EINVAL;
   2706	if (err)
   2707		return err;
   2708
   2709	mvm->d3_test_active = true;
   2710	mvm->keep_vif = NULL;
   2711	return 0;
   2712}
   2713
   2714static ssize_t iwl_mvm_d3_test_read(struct file *file, char __user *user_buf,
   2715				    size_t count, loff_t *ppos)
   2716{
   2717	struct iwl_mvm *mvm = file->private_data;
   2718	u32 pme_asserted;
   2719
   2720	while (true) {
   2721		/* read pme_ptr if available */
   2722		if (mvm->d3_test_pme_ptr) {
   2723			pme_asserted = iwl_trans_read_mem32(mvm->trans,
   2724						mvm->d3_test_pme_ptr);
   2725			if (pme_asserted)
   2726				break;
   2727		}
   2728
   2729		if (msleep_interruptible(100))
   2730			break;
   2731	}
   2732
   2733	return 0;
   2734}
   2735
   2736static void iwl_mvm_d3_test_disconn_work_iter(void *_data, u8 *mac,
   2737					      struct ieee80211_vif *vif)
   2738{
   2739	/* skip the one we keep connection on */
   2740	if (_data == vif)
   2741		return;
   2742
   2743	if (vif->type == NL80211_IFTYPE_STATION)
   2744		ieee80211_connection_loss(vif);
   2745}
   2746
   2747static int iwl_mvm_d3_test_release(struct inode *inode, struct file *file)
   2748{
   2749	struct iwl_mvm *mvm = inode->i_private;
   2750	bool unified_image = fw_has_capa(&mvm->fw->ucode_capa,
   2751					 IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);
   2752
   2753	mvm->d3_test_active = false;
   2754
   2755	iwl_fw_dbg_read_d3_debug_data(&mvm->fwrt);
   2756
   2757	rtnl_lock();
   2758	wiphy_lock(mvm->hw->wiphy);
   2759	__iwl_mvm_resume(mvm, true);
   2760	wiphy_unlock(mvm->hw->wiphy);
   2761	rtnl_unlock();
   2762
   2763	iwl_mvm_resume_tcm(mvm);
   2764
   2765	iwl_fw_runtime_resume(&mvm->fwrt);
   2766
   2767	iwl_abort_notification_waits(&mvm->notif_wait);
   2768	if (!unified_image) {
   2769		int remaining_time = 10;
   2770
   2771		ieee80211_restart_hw(mvm->hw);
   2772
   2773		/* wait for restart and disconnect all interfaces */
   2774		while (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) &&
   2775		       remaining_time > 0) {
   2776			remaining_time--;
   2777			msleep(1000);
   2778		}
   2779
   2780		if (remaining_time == 0)
   2781			IWL_ERR(mvm, "Timed out waiting for HW restart!\n");
   2782	}
   2783
   2784	ieee80211_iterate_active_interfaces_atomic(
   2785		mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
   2786		iwl_mvm_d3_test_disconn_work_iter, mvm->keep_vif);
   2787
   2788	return 0;
   2789}
   2790
   2791const struct file_operations iwl_dbgfs_d3_test_ops = {
   2792	.llseek = no_llseek,
   2793	.open = iwl_mvm_d3_test_open,
   2794	.read = iwl_mvm_d3_test_read,
   2795	.release = iwl_mvm_d3_test_release,
   2796};
   2797#endif