xref: /linux/drivers/net/wireless/intel/iwlwifi/mld/d3.c (revision 301b0dfa9db3f1e204de95e803bbd88fbd878c7c)
1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2 /*
3  * Copyright (C) 2024-2026 Intel Corporation
4  */
5 #include "mld.h"
6 
7 #include "d3.h"
8 #include "power.h"
9 #include "hcmd.h"
10 #include "iface.h"
11 #include "mcc.h"
12 #include "sta.h"
13 #include "mlo.h"
14 #include "key.h"
15 
16 #include "fw/api/d3.h"
17 #include "fw/api/offload.h"
18 #include "fw/api/sta.h"
19 #include "fw/dbg.h"
20 
21 #include <net/ipv6.h>
22 #include <net/addrconf.h>
23 #include <linux/bitops.h>
24 
25 /**
26  * enum iwl_mld_d3_notif - d3 notifications
27  * @IWL_D3_NOTIF_WOWLAN_INFO: WOWLAN_INFO_NOTIF is expected/was received
28  * @IWL_D3_NOTIF_WOWLAN_WAKE_PKT: WOWLAN_WAKE_PKT_NOTIF is expected/was received
29  * @IWL_D3_NOTIF_PROT_OFFLOAD: PROT_OFFLOAD_NOTIF is expected/was received
30  * @IWL_D3_ND_MATCH_INFO: OFFLOAD_MATCH_INFO_NOTIF is expected/was received
31  * @IWL_D3_NOTIF_D3_END_NOTIF: D3_END_NOTIF is expected/was received
32  */
33 enum iwl_mld_d3_notif {
34 	IWL_D3_NOTIF_WOWLAN_INFO =	BIT(0),
35 	IWL_D3_NOTIF_WOWLAN_WAKE_PKT =	BIT(1),
36 	IWL_D3_NOTIF_PROT_OFFLOAD =	BIT(2),
37 	IWL_D3_ND_MATCH_INFO      =     BIT(3),
38 	IWL_D3_NOTIF_D3_END_NOTIF =	BIT(4)
39 };
40 
41 struct iwl_mld_resume_key_iter_data {
42 	struct iwl_mld *mld;
43 	struct iwl_mld_wowlan_status *wowlan_status;
44 };
45 
46 struct iwl_mld_rsc_resume_iter_data {
47 	struct iwl_mld *mld;
48 	const struct iwl_wowlan_all_rsc_tsc_v5 *notif;
49 	int queue;
50 };
51 
52 struct iwl_mld_suspend_key_iter_data {
53 	struct iwl_wowlan_rsc_tsc_params_cmd *rsc;
54 	bool have_rsc;
55 	int gtks;
56 	int found_gtk_idx[4];
57 	__le32 gtk_cipher;
58 	__le32 igtk_cipher;
59 	__le32 bigtk_cipher;
60 };
61 
62 struct iwl_mld_mcast_key_data {
63 	u8 key[WOWLAN_KEY_MAX_SIZE];
64 	u8 len;
65 	u8 flags;
66 	u8 id;
67 	union {
68 		struct {
69 			struct ieee80211_key_seq aes_seq[IWL_MAX_TID_COUNT];
70 			struct ieee80211_key_seq tkip_seq[IWL_MAX_TID_COUNT];
71 		} gtk;
72 		struct {
73 			struct ieee80211_key_seq cmac_gmac_seq;
74 		} igtk_bigtk;
75 	};
76 
77 };
78 
79 struct iwl_mld_wowlan_mlo_key {
80 	u8 key[WOWLAN_KEY_MAX_SIZE];
81 	u8 idx, type, link_id;
82 	u8 pn[6];
83 };
84 
85 /**
86  * struct iwl_mld_wowlan_status - contains wowlan status data from
87  * all wowlan notifications
88  * @wakeup_reasons: wakeup reasons, see &enum iwl_wowlan_wakeup_reason
89  * @replay_ctr: GTK rekey replay counter
90  * @pattern_number: number of the matched patterns on packets
91  * @last_qos_seq: QoS sequence counter of offloaded tid
92  * @num_of_gtk_rekeys: number of GTK rekeys during D3
93  * @tid_offloaded_tx: tid used by the firmware to transmit data packets
94  *	while in wowlan
95  * @wake_packet: wakeup packet received
96  * @wake_packet_length: wake packet length
97  * @wake_packet_bufsize: wake packet bufsize
98  * @gtk: data of the last two used gtk's by the FW upon resume
99  * @igtk: data of the last used igtk by the FW upon resume
100  * @bigtk: data of the last two used gtk's by the FW upon resume
101  * @ptk: last seq numbers per tid passed by the FW,
102  *	holds both in tkip and aes formats
103  * @num_mlo_keys: number of &struct iwl_mld_wowlan_mlo_key structs
104  * @mlo_keys: array of MLO keys
105  */
106 struct iwl_mld_wowlan_status {
107 	u32 wakeup_reasons;
108 	u64 replay_ctr;
109 	u16 pattern_number;
110 	u16 last_qos_seq;
111 	u32 num_of_gtk_rekeys;
112 	u8 tid_offloaded_tx;
113 	u8 *wake_packet;
114 	u32 wake_packet_length;
115 	u32 wake_packet_bufsize;
116 	struct iwl_mld_mcast_key_data gtk[WOWLAN_GTK_KEYS_NUM];
117 	struct iwl_mld_mcast_key_data igtk;
118 	struct iwl_mld_mcast_key_data bigtk[WOWLAN_BIGTK_KEYS_NUM];
119 	struct {
120 		struct ieee80211_key_seq aes_seq[IWL_MAX_TID_COUNT];
121 		struct ieee80211_key_seq tkip_seq[IWL_MAX_TID_COUNT];
122 
123 	} ptk;
124 
125 	int num_mlo_keys;
126 	struct iwl_mld_wowlan_mlo_key mlo_keys[WOWLAN_MAX_MLO_KEYS];
127 };
128 
129 #define NETDETECT_QUERY_BUF_LEN \
130 	(sizeof(struct iwl_scan_offload_profile_match) * \
131 	 IWL_SCAN_MAX_PROFILES_V2)
132 
133 /**
134  * struct iwl_mld_netdetect_res - contains netdetect results from
135  * match_info_notif
136  * @matched_profiles: bitmap of matched profiles, referencing the
137  *	matches passed in the scan offload request
138  * @matches: array of match information, one for each match
139  */
140 struct iwl_mld_netdetect_res {
141 	u32 matched_profiles;
142 	u8 matches[NETDETECT_QUERY_BUF_LEN];
143 };
144 
145 /**
146  * struct iwl_mld_resume_data - d3 resume flow data
147  * @notifs_expected: bitmap of expected notifications from fw,
148  *	see &enum iwl_mld_d3_notif
149  * @notifs_received: bitmap of received notifications from fw,
150  *	see &enum iwl_mld_d3_notif
151  * @d3_end_flags: bitmap of flags from d3_end_notif
152  * @notif_handling_err: error handling one of the resume notifications
153  * @wowlan_status: wowlan status data from all wowlan notifications
154  * @netdetect_res: contains netdetect results from match_info_notif
155  */
156 struct iwl_mld_resume_data {
157 	u32 notifs_expected;
158 	u32 notifs_received;
159 	u32 d3_end_flags;
160 	bool notif_handling_err;
161 	struct iwl_mld_wowlan_status *wowlan_status;
162 	struct iwl_mld_netdetect_res *netdetect_res;
163 };
164 
165 #define IWL_WOWLAN_WAKEUP_REASON_HAS_WAKEUP_PKT \
166 	(IWL_WOWLAN_WAKEUP_BY_MAGIC_PACKET | \
167 	IWL_WOWLAN_WAKEUP_BY_PATTERN | \
168 	IWL_WAKEUP_BY_PATTERN_IPV4_TCP_SYN |\
169 	IWL_WAKEUP_BY_PATTERN_IPV4_TCP_SYN_WILDCARD |\
170 	IWL_WAKEUP_BY_PATTERN_IPV6_TCP_SYN |\
171 	IWL_WAKEUP_BY_PATTERN_IPV6_TCP_SYN_WILDCARD)
172 
173 #define IWL_WOWLAN_OFFLOAD_TID 0
174 
175 void iwl_mld_set_rekey_data(struct ieee80211_hw *hw,
176 			    struct ieee80211_vif *vif,
177 			    struct cfg80211_gtk_rekey_data *data)
178 {
179 	struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw);
180 	struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif);
181 	struct iwl_mld_wowlan_data *wowlan_data = &mld_vif->wowlan_data;
182 
183 	lockdep_assert_wiphy(mld->wiphy);
184 
185 	wowlan_data->rekey_data.kek_len = data->kek_len;
186 	wowlan_data->rekey_data.kck_len = data->kck_len;
187 	memcpy(wowlan_data->rekey_data.kek, data->kek, data->kek_len);
188 	memcpy(wowlan_data->rekey_data.kck, data->kck, data->kck_len);
189 	wowlan_data->rekey_data.akm = data->akm & 0xFF;
190 	wowlan_data->rekey_data.replay_ctr =
191 		cpu_to_le64(be64_to_cpup((const __be64 *)data->replay_ctr));
192 	wowlan_data->rekey_data.valid = true;
193 }
194 
195 #if IS_ENABLED(CONFIG_IPV6)
196 void iwl_mld_ipv6_addr_change(struct ieee80211_hw *hw,
197 			      struct ieee80211_vif *vif,
198 			      struct inet6_dev *idev)
199 {
200 	struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif);
201 	struct iwl_mld_wowlan_data *wowlan_data = &mld_vif->wowlan_data;
202 	struct inet6_ifaddr *ifa;
203 	int idx = 0;
204 
205 	memset(wowlan_data->tentative_addrs, 0,
206 	       sizeof(wowlan_data->tentative_addrs));
207 
208 	read_lock_bh(&idev->lock);
209 	list_for_each_entry(ifa, &idev->addr_list, if_list) {
210 		wowlan_data->target_ipv6_addrs[idx] = ifa->addr;
211 		if (ifa->flags & IFA_F_TENTATIVE)
212 			__set_bit(idx, wowlan_data->tentative_addrs);
213 		idx++;
214 		if (idx >= IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_MAX)
215 			break;
216 	}
217 	read_unlock_bh(&idev->lock);
218 
219 	wowlan_data->num_target_ipv6_addrs = idx;
220 }
221 #endif
222 
223 static int
224 iwl_mld_netdetect_config(struct iwl_mld *mld,
225 			 struct ieee80211_vif *vif,
226 			 const struct cfg80211_wowlan *wowlan)
227 {
228 	int ret;
229 	struct cfg80211_sched_scan_request *netdetect_cfg =
230 		wowlan->nd_config;
231 	struct ieee80211_scan_ies ies = {};
232 
233 	ret = iwl_mld_scan_stop(mld, IWL_MLD_SCAN_SCHED, true);
234 	if (ret)
235 		return ret;
236 
237 	ret = iwl_mld_sched_scan_start(mld, vif, netdetect_cfg, &ies,
238 				       IWL_MLD_SCAN_NETDETECT);
239 	return ret;
240 }
241 
242 static void
243 iwl_mld_le64_to_tkip_seq(__le64 le_pn, struct ieee80211_key_seq *seq)
244 {
245 	u64 pn = le64_to_cpu(le_pn);
246 
247 	seq->tkip.iv16 = (u16)pn;
248 	seq->tkip.iv32 = (u32)(pn >> 16);
249 }
250 
251 static void
252 iwl_mld_le64_to_aes_seq(__le64 le_pn, struct ieee80211_key_seq *seq)
253 {
254 	u64 pn = le64_to_cpu(le_pn);
255 
256 	seq->ccmp.pn[0] = pn >> 40;
257 	seq->ccmp.pn[1] = pn >> 32;
258 	seq->ccmp.pn[2] = pn >> 24;
259 	seq->ccmp.pn[3] = pn >> 16;
260 	seq->ccmp.pn[4] = pn >> 8;
261 	seq->ccmp.pn[5] = pn;
262 }
263 
264 static void
265 iwl_mld_convert_gtk_resume_seq(struct iwl_mld_mcast_key_data *gtk_data,
266 			       const struct iwl_wowlan_all_rsc_tsc_v5 *sc,
267 			       int rsc_idx)
268 {
269 	struct ieee80211_key_seq *aes_seq = gtk_data->gtk.aes_seq;
270 	struct ieee80211_key_seq *tkip_seq = gtk_data->gtk.tkip_seq;
271 
272 	if (rsc_idx >= ARRAY_SIZE(sc->mcast_rsc))
273 		return;
274 
275 	/* We store both the TKIP and AES representations coming from the
276 	 * FW because we decode the data from there before we iterate
277 	 * the keys and know which type is used.
278 	 */
279 	for (int tid = 0; tid < IWL_MAX_TID_COUNT; tid++) {
280 		iwl_mld_le64_to_tkip_seq(sc->mcast_rsc[rsc_idx][tid],
281 					 &tkip_seq[tid]);
282 		iwl_mld_le64_to_aes_seq(sc->mcast_rsc[rsc_idx][tid],
283 					&aes_seq[tid]);
284 	}
285 }
286 
287 static void
288 iwl_mld_convert_gtk_resume_data(struct iwl_mld *mld,
289 				struct iwl_mld_wowlan_status *wowlan_status,
290 				const struct iwl_wowlan_gtk_status *gtk_data,
291 				const struct iwl_wowlan_all_rsc_tsc_v5 *sc,
292 				int rsc_notif_ver)
293 {
294 	int status_idx = 0;
295 
296 	BUILD_BUG_ON(sizeof(wowlan_status->gtk[0].key) <
297 		     sizeof(gtk_data[0].key));
298 	BUILD_BUG_ON(ARRAY_SIZE(wowlan_status->gtk) < WOWLAN_GTK_KEYS_NUM);
299 
300 	for (int notif_idx = 0; notif_idx < ARRAY_SIZE(wowlan_status->gtk);
301 	     notif_idx++) {
302 		int rsc_idx;
303 		u8 key_status = gtk_data[notif_idx].key_status;
304 
305 		if (!key_status)
306 			continue;
307 
308 		wowlan_status->gtk[status_idx].len =
309 			gtk_data[notif_idx].key_len;
310 		wowlan_status->gtk[status_idx].flags =
311 			gtk_data[notif_idx].key_flags;
312 		wowlan_status->gtk[status_idx].id =
313 			wowlan_status->gtk[status_idx].flags &
314 			IWL_WOWLAN_GTK_IDX_MASK;
315 		/* If RSC_NOTIF is not supported */
316 		if (rsc_notif_ver == IWL_FW_CMD_VER_UNKNOWN) {
317 			/* The rsc for both gtk keys are stored in
318 			 * gtk[0]->sc->mcast_rsc. The gtk ids can be any two
319 			 * numbers between 0 and 3, the id_map maps between the
320 			 * key id and the index in sc->mcast
321 			 */
322 			rsc_idx =
323 				sc->mcast_key_id_map[wowlan_status->gtk[status_idx].id];
324 			iwl_mld_convert_gtk_resume_seq(&wowlan_status->gtk[status_idx],
325 						       sc, rsc_idx);
326 		}
327 
328 		if (key_status == IWL_WOWLAN_STATUS_NEW_KEY) {
329 			memcpy(wowlan_status->gtk[status_idx].key,
330 			       gtk_data[notif_idx].key,
331 			       sizeof(gtk_data[notif_idx].key));
332 
333 			/* if it's as long as the TKIP encryption key,
334 			 * copy MIC key
335 			 */
336 			if (wowlan_status->gtk[status_idx].len ==
337 			    NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY)
338 				memcpy(wowlan_status->gtk[status_idx].key +
339 				       NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY,
340 				       gtk_data[notif_idx].tkip_mic_key,
341 				       sizeof(gtk_data[notif_idx].tkip_mic_key));
342 		} else {
343 			/* If the key status is WOWLAN_STATUS_OLD_KEY, it
344 			 * indicates that no key material is present, Set the
345 			 * key length to 0 as an indication
346 			 */
347 			wowlan_status->gtk[status_idx].len = 0;
348 		}
349 		status_idx++;
350 	}
351 }
352 
353 static void
354 iwl_mld_convert_ptk_resume_seq(struct iwl_mld *mld,
355 			       struct iwl_mld_wowlan_status *wowlan_status,
356 			       const struct iwl_wowlan_all_rsc_tsc_v5 *sc)
357 {
358 	struct ieee80211_key_seq *aes_seq = wowlan_status->ptk.aes_seq;
359 	struct ieee80211_key_seq *tkip_seq = wowlan_status->ptk.tkip_seq;
360 
361 	BUILD_BUG_ON(ARRAY_SIZE(sc->ucast_rsc) != IWL_MAX_TID_COUNT);
362 
363 	for (int tid = 0; tid < IWL_MAX_TID_COUNT; tid++) {
364 		iwl_mld_le64_to_aes_seq(sc->ucast_rsc[tid], &aes_seq[tid]);
365 		iwl_mld_le64_to_tkip_seq(sc->ucast_rsc[tid], &tkip_seq[tid]);
366 	}
367 }
368 
369 static void
370 iwl_mld_convert_mcast_ipn(struct iwl_mld_mcast_key_data *key_status,
371 			  const struct iwl_wowlan_igtk_status *key)
372 {
373 	struct ieee80211_key_seq *seq =
374 		&key_status->igtk_bigtk.cmac_gmac_seq;
375 	u8 ipn_len = ARRAY_SIZE(key->ipn);
376 
377 	BUILD_BUG_ON(ipn_len != ARRAY_SIZE(seq->aes_gmac.pn));
378 	BUILD_BUG_ON(ipn_len != ARRAY_SIZE(seq->aes_cmac.pn));
379 	BUILD_BUG_ON(offsetof(struct ieee80211_key_seq, aes_gmac) !=
380 		     offsetof(struct ieee80211_key_seq, aes_cmac));
381 
382 	/* mac80211 expects big endian for memcmp() to work, convert.
383 	 * We don't have the key cipher yet so copy to both to cmac and gmac
384 	 */
385 	for (int i = 0; i < ipn_len; i++) {
386 		seq->aes_gmac.pn[i] = key->ipn[ipn_len - i - 1];
387 		seq->aes_cmac.pn[i] = key->ipn[ipn_len - i - 1];
388 	}
389 }
390 
391 static void
392 iwl_mld_convert_igtk_resume_data(struct iwl_mld_wowlan_status *wowlan_status,
393 				 const struct iwl_wowlan_igtk_status *igtk)
394 {
395 	if (!igtk->key_status)
396 		return;
397 
398 	BUILD_BUG_ON(sizeof(wowlan_status->igtk.key) < sizeof(igtk->key));
399 
400 	wowlan_status->igtk.len = igtk->key_len;
401 	wowlan_status->igtk.flags = igtk->key_flags;
402 	wowlan_status->igtk.id =
403 		u32_get_bits(igtk->key_flags,
404 			     IWL_WOWLAN_IGTK_BIGTK_IDX_MASK) +
405 		WOWLAN_IGTK_MIN_INDEX;
406 
407 	if (igtk->key_status == IWL_WOWLAN_STATUS_NEW_KEY)
408 		memcpy(wowlan_status->igtk.key, igtk->key, sizeof(igtk->key));
409 	else
410 		/* If the key status is WOWLAN_STATUS_OLD_KEY, it indicates
411 		 * that no key material is present. Set the key length to 0
412 		 * as an indication.
413 		 */
414 		wowlan_status->igtk.len = 0;
415 
416 	iwl_mld_convert_mcast_ipn(&wowlan_status->igtk, igtk);
417 }
418 
419 static void
420 iwl_mld_convert_bigtk_resume_data(struct iwl_mld_wowlan_status *wowlan_status,
421 				  const struct iwl_wowlan_igtk_status *bigtk)
422 {
423 	int status_idx = 0;
424 
425 	BUILD_BUG_ON(ARRAY_SIZE(wowlan_status->bigtk) < WOWLAN_BIGTK_KEYS_NUM);
426 
427 	for (int notif_idx = 0; notif_idx < WOWLAN_BIGTK_KEYS_NUM;
428 	     notif_idx++) {
429 		if (!bigtk[notif_idx].key_status)
430 			continue;
431 
432 		wowlan_status->bigtk[status_idx].len = bigtk[notif_idx].key_len;
433 		wowlan_status->bigtk[status_idx].flags =
434 			bigtk[notif_idx].key_flags;
435 		wowlan_status->bigtk[status_idx].id =
436 			u32_get_bits(bigtk[notif_idx].key_flags,
437 				     IWL_WOWLAN_IGTK_BIGTK_IDX_MASK)
438 			+ WOWLAN_BIGTK_MIN_INDEX;
439 
440 		BUILD_BUG_ON(sizeof(wowlan_status->bigtk[status_idx].key) <
441 			     sizeof(bigtk[notif_idx].key));
442 		if (bigtk[notif_idx].key_status == IWL_WOWLAN_STATUS_NEW_KEY)
443 			memcpy(wowlan_status->bigtk[status_idx].key,
444 			       bigtk[notif_idx].key,
445 			       sizeof(bigtk[notif_idx].key));
446 		else
447 			/* If the key status is WOWLAN_STATUS_OLD_KEY, it
448 			 * indicates that no key material is present. Set the
449 			 * key length to 0 as an indication.
450 			 */
451 			wowlan_status->bigtk[status_idx].len = 0;
452 
453 		iwl_mld_convert_mcast_ipn(&wowlan_status->bigtk[status_idx],
454 					  &bigtk[notif_idx]);
455 		status_idx++;
456 	}
457 }
458 
459 static void
460 iwl_mld_convert_mlo_keys(struct iwl_mld *mld,
461 			 const struct iwl_wowlan_info_notif *notif,
462 			 struct iwl_mld_wowlan_status *wowlan_status)
463 {
464 	if (!notif->num_mlo_link_keys)
465 		return;
466 
467 	wowlan_status->num_mlo_keys = notif->num_mlo_link_keys;
468 
469 	if (IWL_FW_CHECK(mld, wowlan_status->num_mlo_keys > WOWLAN_MAX_MLO_KEYS,
470 			 "Too many MLO keys: %d, max %d\n",
471 			 wowlan_status->num_mlo_keys, WOWLAN_MAX_MLO_KEYS))
472 		wowlan_status->num_mlo_keys = WOWLAN_MAX_MLO_KEYS;
473 
474 	for (int i = 0; i < wowlan_status->num_mlo_keys; i++) {
475 		const struct iwl_wowlan_mlo_gtk *fw_mlo_key = &notif->mlo_gtks[i];
476 		struct iwl_mld_wowlan_mlo_key *driver_mlo_key =
477 			&wowlan_status->mlo_keys[i];
478 		u16 flags = le16_to_cpu(fw_mlo_key->flags);
479 
480 		driver_mlo_key->link_id =
481 			u16_get_bits(flags, WOWLAN_MLO_GTK_FLAG_LINK_ID_MSK);
482 		driver_mlo_key->type =
483 			u16_get_bits(flags, WOWLAN_MLO_GTK_FLAG_KEY_TYPE_MSK);
484 		driver_mlo_key->idx =
485 			u16_get_bits(flags, WOWLAN_MLO_GTK_FLAG_KEY_ID_MSK);
486 
487 		BUILD_BUG_ON(sizeof(driver_mlo_key->key) != sizeof(fw_mlo_key->key));
488 		BUILD_BUG_ON(sizeof(driver_mlo_key->pn) != sizeof(fw_mlo_key->pn));
489 
490 		memcpy(driver_mlo_key->key, fw_mlo_key->key, sizeof(fw_mlo_key->key));
491 		memcpy(driver_mlo_key->pn, fw_mlo_key->pn, sizeof(fw_mlo_key->pn));
492 	}
493 }
494 
495 static void
496 iwl_mld_convert_wowlan_notif_v5(const struct iwl_wowlan_info_notif_v5 *notif_v5,
497 				struct iwl_wowlan_info_notif *notif)
498 {
499 	/* Convert GTK from v3 to the new format */
500 	BUILD_BUG_ON(ARRAY_SIZE(notif->gtk) != ARRAY_SIZE(notif_v5->gtk));
501 
502 	for (int i = 0; i < ARRAY_SIZE(notif_v5->gtk); i++) {
503 		const struct iwl_wowlan_gtk_status_v3 *gtk_v3 = &notif_v5->gtk[i];
504 		struct iwl_wowlan_gtk_status *gtk = &notif->gtk[i];
505 
506 		/* Copy key material and metadata */
507 		BUILD_BUG_ON(sizeof(gtk->key) != sizeof(gtk_v3->key));
508 		BUILD_BUG_ON(sizeof(gtk->tkip_mic_key) != sizeof(gtk_v3->tkip_mic_key));
509 
510 		memcpy(gtk->key, gtk_v3->key, sizeof(gtk_v3->key));
511 
512 		gtk->key_len = gtk_v3->key_len;
513 		gtk->key_flags = gtk_v3->key_flags;
514 
515 		memcpy(gtk->tkip_mic_key, gtk_v3->tkip_mic_key,
516 		       sizeof(gtk_v3->tkip_mic_key));
517 		gtk->sc = gtk_v3->sc;
518 
519 		/* Set key_status based on whether key material is present.
520 		 * in v5, a key is either invalid (should be skipped) or has
521 		 * both meta data and the key itself.
522 		 */
523 		if (gtk_v3->key_len)
524 			gtk->key_status = IWL_WOWLAN_STATUS_NEW_KEY;
525 	}
526 
527 	/* Convert IGTK from v1 to the new format, only one IGTK is passed by FW */
528 	BUILD_BUG_ON(offsetof(struct iwl_wowlan_igtk_status, key_status) !=
529 		     sizeof(struct iwl_wowlan_igtk_status_v1));
530 
531 	memcpy(&notif->igtk[0], &notif_v5->igtk[0],
532 	       offsetof(struct iwl_wowlan_igtk_status, key_status));
533 
534 	/* Set key_status based on whether key material is present.
535 	 * in v5, a key is either invalid (should be skipped) or has
536 	 * both meta data and the key itself.
537 	 */
538 	if (notif_v5->igtk[0].key_len)
539 		notif->igtk[0].key_status = IWL_WOWLAN_STATUS_NEW_KEY;
540 
541 	/* Convert BIGTK from v1 to the new format */
542 	BUILD_BUG_ON(ARRAY_SIZE(notif->bigtk) != ARRAY_SIZE(notif_v5->bigtk));
543 
544 	for (int i = 0; i < ARRAY_SIZE(notif_v5->bigtk); i++) {
545 		/* Copy everything until key_status */
546 		memcpy(&notif->bigtk[i], &notif_v5->bigtk[i],
547 		       offsetof(struct iwl_wowlan_igtk_status, key_status));
548 
549 		/* Set key_status based on whether key material is present.
550 		 * in v5, a key is either invalid (should be skipped) or has
551 		 * both meta data and the key itself.
552 		 */
553 		if (notif_v5->bigtk[i].key_len)
554 			notif->bigtk[i].key_status = IWL_WOWLAN_STATUS_NEW_KEY;
555 	}
556 
557 	notif->replay_ctr = notif_v5->replay_ctr;
558 	notif->pattern_number = notif_v5->pattern_number;
559 	notif->qos_seq_ctr = notif_v5->qos_seq_ctr;
560 	notif->wakeup_reasons = notif_v5->wakeup_reasons;
561 	notif->num_of_gtk_rekeys = notif_v5->num_of_gtk_rekeys;
562 	notif->transmitted_ndps = notif_v5->transmitted_ndps;
563 	notif->received_beacons = notif_v5->received_beacons;
564 	notif->tid_tear_down = notif_v5->tid_tear_down;
565 	notif->station_id = notif_v5->station_id;
566 	notif->num_mlo_link_keys = notif_v5->num_mlo_link_keys;
567 	notif->tid_offloaded_tx = notif_v5->tid_offloaded_tx;
568 
569 	/* Copy MLO GTK keys */
570 	if (notif_v5->num_mlo_link_keys) {
571 		memcpy(notif->mlo_gtks, notif_v5->mlo_gtks,
572 		       notif_v5->num_mlo_link_keys * sizeof(struct iwl_wowlan_mlo_gtk));
573 	}
574 }
575 
576 static bool iwl_mld_validate_wowlan_notif_size(struct iwl_mld *mld,
577 					       u32 len,
578 					       u32 expected_len,
579 					       u8 num_mlo_keys,
580 					       int version)
581 {
582 	u32 len_with_mlo_keys;
583 
584 	if (IWL_FW_CHECK(mld, len < expected_len,
585 			 "Invalid wowlan_info_notif v%d (expected=%u got=%u)\n",
586 			 version, expected_len, len))
587 		return false;
588 
589 	len_with_mlo_keys = expected_len +
590 		(num_mlo_keys * sizeof(struct iwl_wowlan_mlo_gtk));
591 
592 	if (IWL_FW_CHECK(mld, len < len_with_mlo_keys,
593 			 "Invalid wowlan_info_notif v%d with MLO keys (expected=%u got=%u)\n",
594 			 version, len_with_mlo_keys, len))
595 		return false;
596 
597 	return true;
598 }
599 
600 static bool
601 iwl_mld_handle_wowlan_info_notif(struct iwl_mld *mld,
602 				 struct iwl_mld_wowlan_status *wowlan_status,
603 				 struct iwl_rx_packet *pkt)
604 {
605 	const struct iwl_wowlan_info_notif *notif;
606 	struct iwl_wowlan_info_notif *converted_notif __free(kfree) = NULL;
607 	u32 len = iwl_rx_packet_payload_len(pkt);
608 	int wowlan_info_ver = iwl_fw_lookup_notif_ver(mld->fw,
609 						      PROT_OFFLOAD_GROUP,
610 						      WOWLAN_INFO_NOTIFICATION,
611 						      IWL_FW_CMD_VER_UNKNOWN);
612 	int rsc_notif_ver = iwl_fw_lookup_notif_ver(mld->fw,
613 						    DATA_PATH_GROUP,
614 						    RSC_NOTIF,
615 						    IWL_FW_CMD_VER_UNKNOWN);
616 
617 	if (wowlan_info_ver == 5) {
618 		/* v5 format - validate before conversion */
619 		const struct iwl_wowlan_info_notif_v5 *notif_v5 = (void *)pkt->data;
620 
621 		if (!iwl_mld_validate_wowlan_notif_size(mld, len,
622 							sizeof(*notif_v5),
623 							notif_v5->num_mlo_link_keys,
624 							5))
625 			return true;
626 
627 		converted_notif = kzalloc_flex(*converted_notif, mlo_gtks,
628 					       notif_v5->num_mlo_link_keys,
629 					       GFP_ATOMIC);
630 		if (!converted_notif) {
631 			IWL_ERR(mld,
632 				"Failed to allocate memory for converted wowlan_info_notif\n");
633 			return true;
634 		}
635 
636 		iwl_mld_convert_wowlan_notif_v5(notif_v5,
637 						converted_notif);
638 		notif = converted_notif;
639 	} else if (wowlan_info_ver == 6) {
640 		notif = (void *)pkt->data;
641 		if (!iwl_mld_validate_wowlan_notif_size(mld, len,
642 							sizeof(*notif),
643 							notif->num_mlo_link_keys,
644 							6))
645 			return true;
646 	} else {
647 		/* smaller versions are not supported */
648 		IWL_WARN(mld,
649 			 "Unsupported wowlan_info_notif version %d\n",
650 			 wowlan_info_ver);
651 		return true;
652 	}
653 
654 	if (IWL_FW_CHECK(mld, notif->tid_offloaded_tx != IWL_WOWLAN_OFFLOAD_TID,
655 			 "Invalid tid_offloaded_tx %d\n",
656 			 notif->tid_offloaded_tx))
657 		return true;
658 
659 	iwl_mld_convert_gtk_resume_data(mld, wowlan_status, notif->gtk,
660 					&notif->gtk[0].sc, rsc_notif_ver);
661 	if (rsc_notif_ver == IWL_FW_CMD_VER_UNKNOWN)
662 		iwl_mld_convert_ptk_resume_seq(mld, wowlan_status,
663 					       &notif->gtk[0].sc);
664 	/* only one igtk is passed by FW */
665 	iwl_mld_convert_igtk_resume_data(wowlan_status, &notif->igtk[0]);
666 	iwl_mld_convert_bigtk_resume_data(wowlan_status, notif->bigtk);
667 
668 	wowlan_status->replay_ctr = le64_to_cpu(notif->replay_ctr);
669 	wowlan_status->pattern_number = le16_to_cpu(notif->pattern_number);
670 
671 	wowlan_status->tid_offloaded_tx = notif->tid_offloaded_tx;
672 	wowlan_status->last_qos_seq = le16_to_cpu(notif->qos_seq_ctr);
673 	wowlan_status->num_of_gtk_rekeys =
674 		le32_to_cpu(notif->num_of_gtk_rekeys);
675 	wowlan_status->wakeup_reasons = le32_to_cpu(notif->wakeup_reasons);
676 
677 	iwl_mld_convert_mlo_keys(mld, notif, wowlan_status);
678 
679 	return false;
680 }
681 
682 static bool
683 iwl_mld_handle_wake_pkt_notif(struct iwl_mld *mld,
684 			      struct iwl_mld_wowlan_status *wowlan_status,
685 			      struct iwl_rx_packet *pkt)
686 {
687 	const struct iwl_wowlan_wake_pkt_notif *notif = (void *)pkt->data;
688 	u32 actual_size, len = iwl_rx_packet_payload_len(pkt);
689 	u32 expected_size = le32_to_cpu(notif->wake_packet_length);
690 
691 	if (IWL_FW_CHECK(mld, len < sizeof(*notif),
692 			 "Invalid WoWLAN wake packet notification (expected size=%zu got=%u)\n",
693 			 sizeof(*notif), len))
694 		return true;
695 
696 	if (IWL_FW_CHECK(mld, !(wowlan_status->wakeup_reasons &
697 				IWL_WOWLAN_WAKEUP_REASON_HAS_WAKEUP_PKT),
698 			 "Got wake packet but wakeup reason is %x\n",
699 			 wowlan_status->wakeup_reasons))
700 		return true;
701 
702 	actual_size = len - offsetof(struct iwl_wowlan_wake_pkt_notif,
703 				     wake_packet);
704 
705 	/* actual_size got the padding from the notification, remove it. */
706 	if (expected_size < actual_size)
707 		actual_size = expected_size;
708 	wowlan_status->wake_packet = kmemdup(notif->wake_packet, actual_size,
709 					     GFP_ATOMIC);
710 	if (!wowlan_status->wake_packet)
711 		return true;
712 
713 	wowlan_status->wake_packet_length = expected_size;
714 	wowlan_status->wake_packet_bufsize = actual_size;
715 
716 	return false;
717 }
718 
719 static void
720 iwl_mld_set_wake_packet(struct iwl_mld *mld,
721 			struct ieee80211_vif *vif,
722 			const struct iwl_mld_wowlan_status *wowlan_status,
723 			struct cfg80211_wowlan_wakeup *wakeup,
724 			struct sk_buff **_pkt)
725 {
726 	int pkt_bufsize = wowlan_status->wake_packet_bufsize;
727 	int expected_pktlen = wowlan_status->wake_packet_length;
728 	const u8 *pktdata = wowlan_status->wake_packet;
729 	const struct ieee80211_hdr *hdr = (const void *)pktdata;
730 	int truncated = expected_pktlen - pkt_bufsize;
731 
732 	if (ieee80211_is_data(hdr->frame_control)) {
733 		int hdrlen = ieee80211_hdrlen(hdr->frame_control);
734 		int ivlen = 0, icvlen = 4; /* also FCS */
735 
736 		struct sk_buff *pkt = alloc_skb(pkt_bufsize, GFP_KERNEL);
737 		*_pkt = pkt;
738 		if (!pkt)
739 			return;
740 
741 		skb_put_data(pkt, pktdata, hdrlen);
742 		pktdata += hdrlen;
743 		pkt_bufsize -= hdrlen;
744 
745 		/* if truncated, FCS/ICV is (partially) gone */
746 		if (truncated >= icvlen) {
747 			truncated -= icvlen;
748 			icvlen = 0;
749 		} else {
750 			icvlen -= truncated;
751 			truncated = 0;
752 		}
753 
754 		pkt_bufsize -= ivlen + icvlen;
755 		pktdata += ivlen;
756 
757 		skb_put_data(pkt, pktdata, pkt_bufsize);
758 
759 		if (ieee80211_data_to_8023(pkt, vif->addr, vif->type))
760 			return;
761 		wakeup->packet = pkt->data;
762 		wakeup->packet_present_len = pkt->len;
763 		wakeup->packet_len = pkt->len - truncated;
764 		wakeup->packet_80211 = false;
765 	} else {
766 		int fcslen = 4;
767 
768 		if (truncated >= 4) {
769 			truncated -= 4;
770 			fcslen = 0;
771 		} else {
772 			fcslen -= truncated;
773 			truncated = 0;
774 		}
775 		pkt_bufsize -= fcslen;
776 		wakeup->packet = wowlan_status->wake_packet;
777 		wakeup->packet_present_len = pkt_bufsize;
778 		wakeup->packet_len = expected_pktlen - truncated;
779 		wakeup->packet_80211 = true;
780 	}
781 }
782 
783 static void
784 iwl_mld_report_wowlan_wakeup(struct iwl_mld *mld,
785 			     struct ieee80211_vif *vif,
786 			     struct iwl_mld_wowlan_status *wowlan_status)
787 {
788 	struct sk_buff *pkt = NULL;
789 	struct cfg80211_wowlan_wakeup wakeup = {
790 		.pattern_idx = -1,
791 	};
792 	u32 reasons = wowlan_status->wakeup_reasons;
793 
794 	if (reasons == IWL_WOWLAN_WAKEUP_BY_NON_WIRELESS) {
795 		ieee80211_report_wowlan_wakeup(vif, NULL, GFP_KERNEL);
796 		return;
797 	}
798 
799 	pm_wakeup_event(mld->dev, 0);
800 
801 	if (reasons & IWL_WOWLAN_WAKEUP_BY_MAGIC_PACKET)
802 		wakeup.magic_pkt = true;
803 
804 	if (reasons & IWL_WOWLAN_WAKEUP_BY_PATTERN)
805 		wakeup.pattern_idx =
806 			wowlan_status->pattern_number;
807 
808 	if (reasons & (IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_MISSED_BEACON |
809 		       IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_DEAUTH |
810 		       IWL_WOWLAN_WAKEUP_BY_GTK_REKEY_FAILURE))
811 		wakeup.disconnect = true;
812 
813 	if (reasons & IWL_WOWLAN_WAKEUP_BY_GTK_REKEY_FAILURE)
814 		wakeup.gtk_rekey_failure = true;
815 
816 	if (reasons & IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED)
817 		wakeup.rfkill_release = true;
818 
819 	if (reasons & IWL_WOWLAN_WAKEUP_BY_EAPOL_REQUEST)
820 		wakeup.eap_identity_req = true;
821 
822 	if (reasons & IWL_WOWLAN_WAKEUP_BY_FOUR_WAY_HANDSHAKE)
823 		wakeup.four_way_handshake = true;
824 
825 	if (reasons & IWL_WOWLAN_WAKEUP_BY_REM_WAKE_LINK_LOSS)
826 		wakeup.tcp_connlost = true;
827 
828 	if (reasons & IWL_WOWLAN_WAKEUP_BY_REM_WAKE_SIGNATURE_TABLE)
829 		wakeup.tcp_nomoretokens = true;
830 
831 	if (reasons & IWL_WOWLAN_WAKEUP_BY_REM_WAKE_WAKEUP_PACKET)
832 		wakeup.tcp_match = true;
833 
834 	if (reasons & IWL_WAKEUP_BY_11W_UNPROTECTED_DEAUTH_OR_DISASSOC)
835 		wakeup.unprot_deauth_disassoc = true;
836 
837 	if (wowlan_status->wake_packet)
838 		iwl_mld_set_wake_packet(mld, vif, wowlan_status, &wakeup, &pkt);
839 
840 	ieee80211_report_wowlan_wakeup(vif, &wakeup, GFP_KERNEL);
841 	kfree_skb(pkt);
842 }
843 
844 static void
845 iwl_mld_set_key_rx_seq_tids(struct ieee80211_key_conf *key,
846 			    struct ieee80211_key_seq *seq)
847 {
848 	int tid;
849 
850 	for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++)
851 		ieee80211_set_key_rx_seq(key, tid, &seq[tid]);
852 }
853 
854 static void
855 iwl_mld_update_mcast_rx_seq(struct ieee80211_key_conf *key,
856 			    struct iwl_mld_mcast_key_data *key_data)
857 {
858 	switch (key->cipher) {
859 	case WLAN_CIPHER_SUITE_CCMP:
860 	case WLAN_CIPHER_SUITE_GCMP:
861 	case WLAN_CIPHER_SUITE_GCMP_256:
862 		iwl_mld_set_key_rx_seq_tids(key,
863 					    key_data->gtk.aes_seq);
864 		break;
865 	case WLAN_CIPHER_SUITE_TKIP:
866 		iwl_mld_set_key_rx_seq_tids(key,
867 					    key_data->gtk.tkip_seq);
868 		break;
869 	case WLAN_CIPHER_SUITE_BIP_GMAC_128:
870 	case WLAN_CIPHER_SUITE_BIP_GMAC_256:
871 	case WLAN_CIPHER_SUITE_BIP_CMAC_256:
872 	case WLAN_CIPHER_SUITE_AES_CMAC:
873 		/* igtk/bigtk ciphers*/
874 		ieee80211_set_key_rx_seq(key, 0,
875 					 &key_data->igtk_bigtk.cmac_gmac_seq);
876 		break;
877 	default:
878 		WARN_ON(1);
879 	}
880 }
881 
882 static void
883 iwl_mld_update_ptk_rx_seq(struct iwl_mld *mld,
884 			  struct iwl_mld_wowlan_status *wowlan_status,
885 			  struct ieee80211_sta *sta,
886 			  struct ieee80211_key_conf *key,
887 			  bool is_tkip)
888 {
889 	struct iwl_mld_sta *mld_sta =
890 		iwl_mld_sta_from_mac80211(sta);
891 	struct iwl_mld_ptk_pn *mld_ptk_pn =
892 		wiphy_dereference(mld->wiphy,
893 				  mld_sta->ptk_pn[key->keyidx]);
894 
895 	iwl_mld_set_key_rx_seq_tids(key, is_tkip ?
896 				    wowlan_status->ptk.tkip_seq :
897 				    wowlan_status->ptk.aes_seq);
898 	if (is_tkip)
899 		return;
900 
901 	if (WARN_ON(!mld_ptk_pn))
902 		return;
903 
904 	for (int tid = 0; tid < IWL_MAX_TID_COUNT; tid++) {
905 		for (int i = 1; i < mld->trans->info.num_rxqs; i++)
906 			memcpy(mld_ptk_pn->q[i].pn[tid],
907 			       wowlan_status->ptk.aes_seq[tid].ccmp.pn,
908 			       IEEE80211_CCMP_PN_LEN);
909 	}
910 }
911 
912 static void
913 iwl_mld_resume_keys_iter(struct ieee80211_hw *hw,
914 			 struct ieee80211_vif *vif,
915 			 struct ieee80211_sta *sta,
916 			 struct ieee80211_key_conf *key,
917 			 void *_data)
918 {
919 	struct iwl_mld_resume_key_iter_data *data = _data;
920 	struct iwl_mld_wowlan_status *wowlan_status = data->wowlan_status;
921 	u8 status_idx;
922 	int rsc_notif_ver = iwl_fw_lookup_notif_ver(data->mld->fw,
923 						    DATA_PATH_GROUP,
924 						    RSC_NOTIF,
925 						    IWL_FW_CMD_VER_UNKNOWN);
926 
927 	/* If RSC_NOTIF is not supported */
928 	if (rsc_notif_ver == IWL_FW_CMD_VER_UNKNOWN &&
929 	    key->keyidx >= 0 && key->keyidx <= 3) {
930 		/* PTK */
931 		if (sta) {
932 			iwl_mld_update_ptk_rx_seq(data->mld, wowlan_status,
933 						  sta, key,
934 						  key->cipher ==
935 						  WLAN_CIPHER_SUITE_TKIP);
936 		/* GTK */
937 		} else {
938 			status_idx = key->keyidx == wowlan_status->gtk[1].id;
939 			iwl_mld_update_mcast_rx_seq(key,
940 						    &wowlan_status->gtk[status_idx]);
941 		}
942 	}
943 
944 	/* IGTK */
945 	if (key->keyidx == 4 || key->keyidx == 5) {
946 		if (key->keyidx == wowlan_status->igtk.id)
947 			iwl_mld_update_mcast_rx_seq(key, &wowlan_status->igtk);
948 	}
949 
950 	/* BIGTK */
951 	if (key->keyidx == 6 || key->keyidx == 7) {
952 		status_idx = key->keyidx == wowlan_status->bigtk[1].id;
953 		iwl_mld_update_mcast_rx_seq(key,
954 					    &wowlan_status->bigtk[status_idx]);
955 	}
956 }
957 
958 static void
959 iwl_mld_rsc_update_key_iter(struct ieee80211_hw *hw,
960 			    struct ieee80211_vif *vif,
961 			    struct ieee80211_sta *sta,
962 			    struct ieee80211_key_conf *key,
963 			    void *_data)
964 {
965 	struct iwl_mld_rsc_resume_iter_data *data = _data;
966 	struct ieee80211_key_seq seq;
967 
968 	if (key->keyidx > 3)
969 		return;
970 
971 	if (sta) {
972 		/* PTK */
973 		BUILD_BUG_ON(ARRAY_SIZE(data->notif->ucast_rsc) !=
974 			     IWL_MAX_TID_COUNT);
975 
976 		if (key->cipher == WLAN_CIPHER_SUITE_TKIP) {
977 			/* TKIP: just update key sequences */
978 			for (int tid = 0; tid < IWL_MAX_TID_COUNT; tid++) {
979 				iwl_mld_le64_to_tkip_seq(data->notif->ucast_rsc[tid],
980 							 &seq);
981 				ieee80211_set_key_rx_seq(key, tid, &seq);
982 			}
983 		} else {
984 			struct iwl_mld_sta *mld_sta = iwl_mld_sta_from_mac80211(sta);
985 			struct iwl_mld_ptk_pn *mld_ptk_pn =
986 				rcu_dereference_wiphy(data->mld->wiphy,
987 						      mld_sta->ptk_pn[key->keyidx]);
988 
989 			if (WARN_ON(!mld_ptk_pn))
990 				return;
991 
992 			if (WARN_ON(data->queue >=
993 				    data->mld->trans->info.num_rxqs))
994 				return;
995 
996 			for (int tid = 0; tid < IWL_MAX_TID_COUNT; tid++) {
997 				iwl_mld_le64_to_aes_seq(data->notif->ucast_rsc[tid],
998 							&seq);
999 				ieee80211_set_key_rx_seq(key, tid, &seq);
1000 				memcpy(mld_ptk_pn->q[data->queue].pn[tid],
1001 				       seq.ccmp.pn,
1002 				       IEEE80211_CCMP_PN_LEN);
1003 			}
1004 		}
1005 
1006 		IWL_DEBUG_WOWLAN(data->mld,
1007 				 "Updated PTK RSC for key %d on queue %d\n",
1008 				 key->keyidx, data->queue);
1009 	} else {
1010 		/* GTK */
1011 		int rsc_idx = data->notif->mcast_key_id_map[key->keyidx];
1012 
1013 		if (rsc_idx == IWL_MCAST_KEY_MAP_INVALID)
1014 			return;
1015 
1016 		if (IWL_FW_CHECK(data->mld,
1017 				 rsc_idx >= ARRAY_SIZE(data->notif->mcast_rsc),
1018 				 "Invalid mcast key mapping: %d for key %d\n",
1019 				 rsc_idx, key->keyidx))
1020 			return;
1021 
1022 		for (int tid = 0; tid < IWL_MAX_TID_COUNT; tid++) {
1023 			__le64 rsc =
1024 				data->notif->mcast_rsc[rsc_idx][tid];
1025 
1026 			if (key->cipher == WLAN_CIPHER_SUITE_TKIP)
1027 				iwl_mld_le64_to_tkip_seq(rsc, &seq);
1028 			else
1029 				iwl_mld_le64_to_aes_seq(rsc, &seq);
1030 			ieee80211_set_key_rx_seq(key, tid, &seq);
1031 		}
1032 
1033 		IWL_DEBUG_WOWLAN(data->mld,
1034 				 "Updated GTK %d RSC (rsc_idx %d) on queue %d\n",
1035 				 key->keyidx, rsc_idx, data->queue);
1036 	}
1037 }
1038 
1039 void
1040 iwl_mld_process_rsc_notification(struct iwl_mld *mld,
1041 				 struct ieee80211_vif *vif,
1042 				 const struct iwl_wowlan_all_rsc_tsc_v5 *notif,
1043 				 int queue)
1044 {
1045 	struct iwl_mld_rsc_resume_iter_data iter_data = {
1046 		.mld = mld,
1047 		.notif = notif,
1048 		.queue = queue,
1049 	};
1050 
1051 	/* Iterate through all active keys and update RSC */
1052 	ieee80211_iter_keys_rcu(mld->hw, vif,
1053 				iwl_mld_rsc_update_key_iter,
1054 				&iter_data);
1055 }
1056 
1057 static void
1058 iwl_mld_add_mcast_rekey(struct ieee80211_vif *vif,
1059 			struct iwl_mld *mld,
1060 			struct iwl_mld_mcast_key_data *key_data,
1061 			struct ieee80211_bss_conf *link_conf)
1062 {
1063 	struct ieee80211_key_conf *key_config;
1064 	int link_id = vif->active_links ? __ffs(vif->active_links) : -1;
1065 
1066 	if (!key_data->len)
1067 		return;
1068 
1069 	key_config = ieee80211_gtk_rekey_add(vif, key_data->id, key_data->key,
1070 					     sizeof(key_data->key), link_id);
1071 	if (IS_ERR(key_config))
1072 		return;
1073 
1074 	iwl_mld_update_mcast_rx_seq(key_config, key_data);
1075 
1076 	/* The FW holds only one IGTK so we keep track of the valid one */
1077 	if (key_config->keyidx == 4 || key_config->keyidx == 5) {
1078 		struct iwl_mld_link_sta *mld_ap_link_sta;
1079 
1080 		mld_ap_link_sta = iwl_mld_get_ap_link_sta(vif,
1081 							  link_conf->link_id);
1082 		if (WARN_ON(!mld_ap_link_sta))
1083 			return;
1084 
1085 		/* If we had more than one rekey, mac80211 will tell us to
1086 		 * remove the old and add the new so we will update the IGTK in
1087 		 * drv_set_key
1088 		 */
1089 		if (mld_ap_link_sta->rx_igtk &&
1090 		    mld_ap_link_sta->rx_igtk != key_config) {
1091 			/* mark the old IGTK as not in FW */
1092 			mld_ap_link_sta->rx_igtk->hw_key_idx =
1093 				STA_KEY_IDX_INVALID;
1094 			mld_ap_link_sta->rx_igtk = key_config;
1095 		}
1096 	}
1097 
1098 	/* Also keep track of the new BIGTK */
1099 	if (key_config->keyidx == 6 || key_config->keyidx == 7)
1100 		iwl_mld_track_bigtk(mld, vif, key_config, true);
1101 }
1102 
1103 static void
1104 iwl_mld_add_all_rekeys(struct iwl_mld *mld,
1105 		       struct ieee80211_vif *vif,
1106 		       struct iwl_mld_wowlan_status *wowlan_status,
1107 		       struct ieee80211_bss_conf *link_conf)
1108 {
1109 	int i;
1110 
1111 	for (i = 0; i < ARRAY_SIZE(wowlan_status->gtk); i++)
1112 		iwl_mld_add_mcast_rekey(vif, mld, &wowlan_status->gtk[i],
1113 					link_conf);
1114 
1115 	iwl_mld_add_mcast_rekey(vif, mld, &wowlan_status->igtk, link_conf);
1116 
1117 	for (i = 0; i < ARRAY_SIZE(wowlan_status->bigtk); i++)
1118 		iwl_mld_add_mcast_rekey(vif, mld, &wowlan_status->bigtk[i],
1119 					link_conf);
1120 }
1121 
1122 static void iwl_mld_mlo_rekey(struct iwl_mld *mld,
1123 			      struct iwl_mld_wowlan_status *wowlan_status,
1124 			      struct ieee80211_vif *vif)
1125 {
1126 	IWL_DEBUG_WOWLAN(mld, "Num of MLO Keys: %d\n", wowlan_status->num_mlo_keys);
1127 
1128 	if (!wowlan_status->num_mlo_keys)
1129 		return;
1130 
1131 	for (int i = 0; i < wowlan_status->num_mlo_keys; i++) {
1132 		struct iwl_mld_wowlan_mlo_key *mlo_key = &wowlan_status->mlo_keys[i];
1133 		struct ieee80211_key_conf *key;
1134 		struct ieee80211_key_seq seq;
1135 		u8 link_id = mlo_key->link_id;
1136 
1137 		if (IWL_FW_CHECK(mld, mlo_key->link_id >= IEEE80211_MLD_MAX_NUM_LINKS ||
1138 				      mlo_key->idx >= 8 ||
1139 				      mlo_key->type >= WOWLAN_MLO_GTK_KEY_NUM_TYPES,
1140 				      "Invalid MLO key link_id %d, idx %d, type %d\n",
1141 				      mlo_key->link_id, mlo_key->idx, mlo_key->type))
1142 			continue;
1143 
1144 		if (!(vif->valid_links & BIT(link_id)) ||
1145 		    (vif->active_links & BIT(link_id)))
1146 			continue;
1147 
1148 		IWL_DEBUG_WOWLAN(mld, "Add MLO key id %d, link id %d\n",
1149 				 mlo_key->idx, link_id);
1150 
1151 		key = ieee80211_gtk_rekey_add(vif, mlo_key->idx, mlo_key->key,
1152 					      sizeof(mlo_key->key), link_id);
1153 
1154 		if (IS_ERR(key))
1155 			continue;
1156 
1157 		/*
1158 		 * mac80211 expects the PN in big-endian
1159 		 * also note that seq is a union of all cipher types
1160 		 * (ccmp, gcmp, cmac, gmac), and they all have the same
1161 		 * pn field (of length 6) so just copy it to ccmp.pn.
1162 		 */
1163 		for (int j = 5; j >= 0; j--)
1164 			seq.ccmp.pn[5 - j] = mlo_key->pn[j];
1165 
1166 		/* group keys are non-QoS and use TID 0 */
1167 		ieee80211_set_key_rx_seq(key, 0, &seq);
1168 	}
1169 }
1170 
1171 static bool
1172 iwl_mld_update_sec_keys(struct iwl_mld *mld,
1173 			struct ieee80211_vif *vif,
1174 			struct iwl_mld_wowlan_status *wowlan_status)
1175 {
1176 	int link_id = vif->active_links ? __ffs(vif->active_links) : 0;
1177 	struct ieee80211_bss_conf *link_conf =
1178 		link_conf_dereference_protected(vif, link_id);
1179 	__be64 replay_ctr = cpu_to_be64(wowlan_status->replay_ctr);
1180 	struct iwl_mld_resume_key_iter_data key_iter_data = {
1181 		.mld = mld,
1182 		.wowlan_status = wowlan_status,
1183 	};
1184 
1185 	if (WARN_ON(!link_conf))
1186 		return false;
1187 
1188 	ieee80211_iter_keys(mld->hw, vif, iwl_mld_resume_keys_iter,
1189 			    &key_iter_data);
1190 
1191 	IWL_DEBUG_WOWLAN(mld, "Number of rekeys: %d\n",
1192 			 wowlan_status->num_of_gtk_rekeys);
1193 
1194 	if (!wowlan_status->num_of_gtk_rekeys)
1195 		return true;
1196 
1197 	iwl_mld_add_all_rekeys(mld, vif, wowlan_status,
1198 			       link_conf);
1199 
1200 	iwl_mld_mlo_rekey(mld, wowlan_status, vif);
1201 
1202 	ieee80211_gtk_rekey_notify(vif, link_conf->bssid,
1203 				   (void *)&replay_ctr, GFP_KERNEL);
1204 	return true;
1205 }
1206 
1207 static bool
1208 iwl_mld_process_wowlan_status(struct iwl_mld *mld,
1209 			      struct ieee80211_vif *vif,
1210 			      struct iwl_mld_wowlan_status *wowlan_status)
1211 {
1212 	struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif);
1213 	struct ieee80211_sta *ap_sta = mld_vif->ap_sta;
1214 	struct iwl_mld_txq *mld_txq;
1215 
1216 	iwl_mld_report_wowlan_wakeup(mld, vif, wowlan_status);
1217 
1218 	if (WARN_ON(!ap_sta))
1219 		return false;
1220 
1221 	mld_txq =
1222 		iwl_mld_txq_from_mac80211(ap_sta->txq[wowlan_status->tid_offloaded_tx]);
1223 
1224 	/* Update the pointers of the Tx queue that may have moved during
1225 	 * suspend if the firmware sent frames.
1226 	 * The firmware stores last-used value, we store next value.
1227 	 */
1228 	WARN_ON(!mld_txq->status.allocated);
1229 	iwl_trans_set_q_ptrs(mld->trans, mld_txq->fw_id,
1230 			     (wowlan_status->last_qos_seq +
1231 			     0x10) >> 4);
1232 
1233 	if (!iwl_mld_update_sec_keys(mld, vif, wowlan_status))
1234 		return false;
1235 
1236 	if (wowlan_status->wakeup_reasons &
1237 	    (IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_MISSED_BEACON |
1238 	     IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_DEAUTH |
1239 	     IWL_WOWLAN_WAKEUP_BY_GTK_REKEY_FAILURE))
1240 		return false;
1241 
1242 	return true;
1243 }
1244 
1245 static bool
1246 iwl_mld_netdetect_match_info_handler(struct iwl_mld *mld,
1247 				     struct iwl_mld_resume_data *resume_data,
1248 				     struct iwl_rx_packet *pkt)
1249 {
1250 	struct iwl_mld_netdetect_res *results = resume_data->netdetect_res;
1251 	const struct iwl_scan_offload_match_info *notif = (void *)pkt->data;
1252 	u32 len = iwl_rx_packet_payload_len(pkt);
1253 
1254 	if (IWL_FW_CHECK(mld, !mld->netdetect,
1255 			 "Got scan match info notif when mld->netdetect==%d\n",
1256 			 mld->netdetect))
1257 		return true;
1258 
1259 	if (IWL_FW_CHECK(mld, len < sizeof(*notif),
1260 			 "Invalid scan offload match notif of length: %d\n",
1261 			 len))
1262 		return true;
1263 
1264 	if (IWL_FW_CHECK(mld, resume_data->wowlan_status->wakeup_reasons !=
1265 			 IWL_WOWLAN_WAKEUP_BY_NON_WIRELESS,
1266 			 "Ignore scan match info: unexpected wakeup reason (expected=0x%x got=0x%x)\n",
1267 			 IWL_WOWLAN_WAKEUP_BY_NON_WIRELESS,
1268 			 resume_data->wowlan_status->wakeup_reasons))
1269 		return true;
1270 
1271 	results->matched_profiles = le32_to_cpu(notif->matched_profiles);
1272 	IWL_DEBUG_WOWLAN(mld, "number of matched profiles=%u\n",
1273 			 results->matched_profiles);
1274 
1275 	if (results->matched_profiles)
1276 		memcpy(results->matches, notif->matches,
1277 		       NETDETECT_QUERY_BUF_LEN);
1278 
1279 	/* No scan should be active at this point */
1280 	mld->scan.status = 0;
1281 	memset(mld->scan.uid_status, 0, sizeof(mld->scan.uid_status));
1282 	return false;
1283 }
1284 
1285 static void
1286 iwl_mld_set_netdetect_info(struct iwl_mld *mld,
1287 			   const struct cfg80211_sched_scan_request *netdetect_cfg,
1288 			   struct cfg80211_wowlan_nd_info *netdetect_info,
1289 			   struct iwl_mld_netdetect_res *netdetect_res,
1290 			   unsigned long matched_profiles)
1291 {
1292 	int i;
1293 
1294 	for_each_set_bit(i, &matched_profiles, netdetect_cfg->n_match_sets) {
1295 		struct cfg80211_wowlan_nd_match *match;
1296 		int idx, j, n_channels = 0;
1297 		struct iwl_scan_offload_profile_match *matches =
1298 			(void *)netdetect_res->matches;
1299 
1300 		for (int k = 0; k < SCAN_OFFLOAD_MATCHING_CHANNELS_LEN; k++)
1301 			n_channels +=
1302 				hweight8(matches[i].matching_channels[k]);
1303 		match = kzalloc_flex(*match, channels, n_channels);
1304 		if (!match)
1305 			return;
1306 
1307 		netdetect_info->matches[netdetect_info->n_matches] = match;
1308 		netdetect_info->n_matches++;
1309 
1310 		/* We inverted the order of the SSIDs in the scan
1311 		 * request, so invert the index here.
1312 		 */
1313 		idx = netdetect_cfg->n_match_sets - i - 1;
1314 		match->ssid.ssid_len =
1315 			netdetect_cfg->match_sets[idx].ssid.ssid_len;
1316 		memcpy(match->ssid.ssid,
1317 		       netdetect_cfg->match_sets[idx].ssid.ssid,
1318 		       match->ssid.ssid_len);
1319 
1320 		if (netdetect_cfg->n_channels < n_channels)
1321 			continue;
1322 
1323 		for_each_set_bit(j,
1324 				 (unsigned long *)&matches[i].matching_channels[0],
1325 				 sizeof(matches[i].matching_channels)) {
1326 			match->channels[match->n_channels] =
1327 				netdetect_cfg->channels[j]->center_freq;
1328 			match->n_channels++;
1329 		}
1330 	}
1331 }
1332 
1333 static void
1334 iwl_mld_process_netdetect_res(struct iwl_mld *mld,
1335 			      struct ieee80211_vif *vif,
1336 			      struct iwl_mld_resume_data *resume_data)
1337 {
1338 	struct cfg80211_wowlan_nd_info *netdetect_info = NULL;
1339 	const struct cfg80211_sched_scan_request *netdetect_cfg;
1340 	struct cfg80211_wowlan_wakeup wakeup = {
1341 		.pattern_idx = -1,
1342 	};
1343 	struct cfg80211_wowlan_wakeup *wakeup_report = &wakeup;
1344 	unsigned long matched_profiles;
1345 	u32 wakeup_reasons;
1346 	int n_matches;
1347 
1348 	lockdep_assert_wiphy(mld->wiphy);
1349 
1350 	if (WARN_ON(!mld->wiphy->wowlan_config ||
1351 		    !mld->wiphy->wowlan_config->nd_config)) {
1352 		IWL_DEBUG_WOWLAN(mld,
1353 				 "Netdetect isn't configured on resume flow\n");
1354 		goto out;
1355 	}
1356 
1357 	netdetect_cfg = mld->wiphy->wowlan_config->nd_config;
1358 	wakeup_reasons = resume_data->wowlan_status->wakeup_reasons;
1359 
1360 	if (wakeup_reasons & IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED)
1361 		wakeup.rfkill_release = true;
1362 
1363 	if (wakeup_reasons != IWL_WOWLAN_WAKEUP_BY_NON_WIRELESS)
1364 		goto out;
1365 
1366 	if (!resume_data->netdetect_res->matched_profiles) {
1367 		IWL_DEBUG_WOWLAN(mld,
1368 				 "Netdetect results aren't valid\n");
1369 		wakeup_report = NULL;
1370 		goto out;
1371 	}
1372 
1373 	matched_profiles = resume_data->netdetect_res->matched_profiles;
1374 	if (!netdetect_cfg->n_match_sets) {
1375 		IWL_DEBUG_WOWLAN(mld,
1376 				 "No netdetect match sets are configured\n");
1377 		goto out;
1378 	}
1379 	n_matches = hweight_long(matched_profiles);
1380 	netdetect_info = kzalloc_flex(*netdetect_info, matches, n_matches);
1381 	if (netdetect_info)
1382 		iwl_mld_set_netdetect_info(mld, netdetect_cfg, netdetect_info,
1383 					   resume_data->netdetect_res,
1384 					   matched_profiles);
1385 
1386 	wakeup.net_detect = netdetect_info;
1387  out:
1388 	ieee80211_report_wowlan_wakeup(vif, wakeup_report, GFP_KERNEL);
1389 	if (netdetect_info) {
1390 		for (int i = 0; i < netdetect_info->n_matches; i++)
1391 			kfree(netdetect_info->matches[i]);
1392 		kfree(netdetect_info);
1393 	}
1394 }
1395 
1396 static bool iwl_mld_handle_d3_notif(struct iwl_notif_wait_data *notif_wait,
1397 				    struct iwl_rx_packet *pkt, void *data)
1398 {
1399 	struct iwl_mld_resume_data *resume_data = data;
1400 	struct iwl_mld *mld =
1401 		container_of(notif_wait, struct iwl_mld, notif_wait);
1402 
1403 	switch (WIDE_ID(pkt->hdr.group_id, pkt->hdr.cmd)) {
1404 	case WIDE_ID(PROT_OFFLOAD_GROUP, WOWLAN_INFO_NOTIFICATION): {
1405 		if (resume_data->notifs_received & IWL_D3_NOTIF_WOWLAN_INFO) {
1406 			IWL_DEBUG_WOWLAN(mld,
1407 					 "got additional wowlan_info notif\n");
1408 			break;
1409 		}
1410 		resume_data->notif_handling_err =
1411 			iwl_mld_handle_wowlan_info_notif(mld,
1412 							 resume_data->wowlan_status,
1413 							 pkt);
1414 		resume_data->notifs_received |= IWL_D3_NOTIF_WOWLAN_INFO;
1415 
1416 		if (resume_data->wowlan_status->wakeup_reasons &
1417 		    IWL_WOWLAN_WAKEUP_REASON_HAS_WAKEUP_PKT)
1418 			resume_data->notifs_expected |=
1419 				IWL_D3_NOTIF_WOWLAN_WAKE_PKT;
1420 		break;
1421 	}
1422 	case WIDE_ID(PROT_OFFLOAD_GROUP, WOWLAN_WAKE_PKT_NOTIFICATION): {
1423 		if (resume_data->notifs_received &
1424 		    IWL_D3_NOTIF_WOWLAN_WAKE_PKT) {
1425 			/* We shouldn't get two wake packet notifications */
1426 			IWL_DEBUG_WOWLAN(mld,
1427 					 "Got additional wowlan wake packet notification\n");
1428 			break;
1429 		}
1430 		resume_data->notif_handling_err =
1431 			iwl_mld_handle_wake_pkt_notif(mld,
1432 						      resume_data->wowlan_status,
1433 						      pkt);
1434 		resume_data->notifs_received |= IWL_D3_NOTIF_WOWLAN_WAKE_PKT;
1435 		break;
1436 	}
1437 	case WIDE_ID(SCAN_GROUP, OFFLOAD_MATCH_INFO_NOTIF): {
1438 		if (resume_data->notifs_received & IWL_D3_ND_MATCH_INFO) {
1439 			IWL_ERR(mld,
1440 				"Got additional netdetect match info\n");
1441 			break;
1442 		}
1443 
1444 		resume_data->notif_handling_err =
1445 			iwl_mld_netdetect_match_info_handler(mld, resume_data,
1446 							     pkt);
1447 		resume_data->notifs_received |= IWL_D3_ND_MATCH_INFO;
1448 		break;
1449 	}
1450 	case WIDE_ID(PROT_OFFLOAD_GROUP, D3_END_NOTIFICATION): {
1451 		struct iwl_d3_end_notif *notif = (void *)pkt->data;
1452 
1453 		resume_data->d3_end_flags = le32_to_cpu(notif->flags);
1454 		resume_data->notifs_received |= IWL_D3_NOTIF_D3_END_NOTIF;
1455 		break;
1456 	}
1457 	default:
1458 		WARN_ON(1);
1459 	}
1460 
1461 	return resume_data->notifs_received == resume_data->notifs_expected;
1462 }
1463 
1464 #define IWL_MLD_D3_NOTIF_TIMEOUT (HZ / 3)
1465 
1466 static int iwl_mld_wait_d3_notif(struct iwl_mld *mld,
1467 				 struct iwl_mld_resume_data *resume_data,
1468 				 bool with_wowlan)
1469 {
1470 	static const u16 wowlan_resume_notif[] = {
1471 		WIDE_ID(PROT_OFFLOAD_GROUP, WOWLAN_INFO_NOTIFICATION),
1472 		WIDE_ID(PROT_OFFLOAD_GROUP, WOWLAN_WAKE_PKT_NOTIFICATION),
1473 		WIDE_ID(SCAN_GROUP, OFFLOAD_MATCH_INFO_NOTIF),
1474 		WIDE_ID(PROT_OFFLOAD_GROUP, D3_END_NOTIFICATION)
1475 	};
1476 	static const u16 d3_resume_notif[] = {
1477 		WIDE_ID(PROT_OFFLOAD_GROUP, D3_END_NOTIFICATION)
1478 	};
1479 	struct iwl_notification_wait wait_d3_notif;
1480 	int ret;
1481 
1482 	if (with_wowlan)
1483 		iwl_init_notification_wait(&mld->notif_wait, &wait_d3_notif,
1484 					   wowlan_resume_notif,
1485 					   ARRAY_SIZE(wowlan_resume_notif),
1486 					   iwl_mld_handle_d3_notif,
1487 					   resume_data);
1488 	else
1489 		iwl_init_notification_wait(&mld->notif_wait, &wait_d3_notif,
1490 					   d3_resume_notif,
1491 					   ARRAY_SIZE(d3_resume_notif),
1492 					   iwl_mld_handle_d3_notif,
1493 					   resume_data);
1494 
1495 	ret = iwl_trans_d3_resume(mld->trans, false);
1496 	if (ret) {
1497 		/* Avoid sending commands if the FW is dead */
1498 		iwl_trans_notify_fw_error(mld->trans);
1499 		iwl_remove_notification(&mld->notif_wait, &wait_d3_notif);
1500 		return ret;
1501 	}
1502 
1503 	ret = iwl_wait_notification(&mld->notif_wait, &wait_d3_notif,
1504 				    IWL_MLD_D3_NOTIF_TIMEOUT);
1505 	if (ret)
1506 		IWL_ERR(mld, "Couldn't get the d3 notif %d\n", ret);
1507 
1508 	if (resume_data->notif_handling_err)
1509 		ret = -EIO;
1510 
1511 	return ret;
1512 }
1513 
1514 int iwl_mld_no_wowlan_suspend(struct iwl_mld *mld)
1515 {
1516 	struct iwl_d3_manager_config d3_cfg_cmd_data = {};
1517 	int ret;
1518 
1519 	if (mld->debug_max_sleep) {
1520 		d3_cfg_cmd_data.wakeup_host_timer =
1521 			cpu_to_le32(mld->debug_max_sleep);
1522 		d3_cfg_cmd_data.wakeup_flags =
1523 			cpu_to_le32(IWL_WAKEUP_D3_HOST_TIMER);
1524 	}
1525 
1526 	lockdep_assert_wiphy(mld->wiphy);
1527 
1528 	IWL_DEBUG_WOWLAN(mld, "Starting the no wowlan suspend flow\n");
1529 
1530 	iwl_mld_low_latency_stop(mld);
1531 
1532 	ret = iwl_mld_update_device_power(mld, true);
1533 	if (ret) {
1534 		IWL_ERR(mld,
1535 			"d3 suspend: couldn't send power_device %d\n", ret);
1536 		return ret;
1537 	}
1538 
1539 	ret = iwl_mld_send_cmd_pdu(mld, D3_CONFIG_CMD,
1540 				   &d3_cfg_cmd_data);
1541 	if (ret) {
1542 		IWL_ERR(mld,
1543 			"d3 suspend: couldn't send D3_CONFIG_CMD %d\n", ret);
1544 		return ret;
1545 	}
1546 
1547 	ret = iwl_trans_d3_suspend(mld->trans, false);
1548 	if (ret) {
1549 		IWL_ERR(mld, "d3 suspend: trans_d3_suspend failed %d\n", ret);
1550 		/* We are going to stop the FW. Avoid sending commands in that flow */
1551 		iwl_trans_notify_fw_error(mld->trans);
1552 	} else {
1553 		/* Async notification might send hcmds, which is not allowed in suspend */
1554 		iwl_mld_cancel_async_notifications(mld);
1555 		mld->fw_status.in_d3 = true;
1556 	}
1557 
1558 	return ret;
1559 }
1560 
1561 int iwl_mld_no_wowlan_resume(struct iwl_mld *mld)
1562 {
1563 	struct iwl_mld_resume_data resume_data = {
1564 		.notifs_expected =
1565 			IWL_D3_NOTIF_D3_END_NOTIF,
1566 	};
1567 	int ret;
1568 
1569 	lockdep_assert_wiphy(mld->wiphy);
1570 
1571 	IWL_DEBUG_WOWLAN(mld, "Starting the no wowlan resume flow\n");
1572 
1573 	mld->fw_status.in_d3 = false;
1574 	iwl_fw_dbg_read_d3_debug_data(&mld->fwrt);
1575 
1576 	ret = iwl_mld_wait_d3_notif(mld, &resume_data, false);
1577 	if (ret)
1578 		return ret;
1579 
1580 	if (!ret && (resume_data.d3_end_flags & IWL_D0I3_RESET_REQUIRE))
1581 		return -ENODEV;
1582 
1583 	iwl_mld_low_latency_restart(mld);
1584 
1585 	return iwl_mld_update_device_power(mld, false);
1586 }
1587 
1588 static void
1589 iwl_mld_aes_seq_to_le64_pn(struct ieee80211_key_conf *key,
1590 			   __le64 *key_rsc)
1591 {
1592 	for (int i = 0; i < IWL_MAX_TID_COUNT; i++) {
1593 		struct ieee80211_key_seq seq;
1594 		u8 *pn = key->cipher == WLAN_CIPHER_SUITE_CCMP ? seq.ccmp.pn :
1595 			seq.gcmp.pn;
1596 
1597 		ieee80211_get_key_rx_seq(key, i, &seq);
1598 		key_rsc[i] = cpu_to_le64((u64)pn[5] |
1599 					 ((u64)pn[4] << 8) |
1600 					 ((u64)pn[3] << 16) |
1601 					 ((u64)pn[2] << 24) |
1602 					 ((u64)pn[1] << 32) |
1603 					 ((u64)pn[0] << 40));
1604 	}
1605 }
1606 
1607 static void
1608 iwl_mld_suspend_set_ucast_pn(struct iwl_mld *mld, struct ieee80211_sta *sta,
1609 			     struct ieee80211_key_conf *key, __le64 *key_rsc)
1610 {
1611 	struct iwl_mld_sta *mld_sta =
1612 		iwl_mld_sta_from_mac80211(sta);
1613 	struct iwl_mld_ptk_pn *mld_ptk_pn;
1614 
1615 	if (WARN_ON(key->keyidx >= ARRAY_SIZE(mld_sta->ptk_pn)))
1616 		return;
1617 
1618 	mld_ptk_pn = wiphy_dereference(mld->wiphy,
1619 				       mld_sta->ptk_pn[key->keyidx]);
1620 	if (WARN_ON(!mld_ptk_pn))
1621 		return;
1622 
1623 	for (int tid = 0; tid < IWL_MAX_TID_COUNT; tid++) {
1624 		struct ieee80211_key_seq seq;
1625 		u8 *max_pn = seq.ccmp.pn;
1626 
1627 		/* get the PN from mac80211, used on the default queue */
1628 		ieee80211_get_key_rx_seq(key, tid, &seq);
1629 
1630 		/* and use the internal data for all queues */
1631 		for (int que = 1; que < mld->trans->info.num_rxqs; que++) {
1632 			u8 *cur_pn = mld_ptk_pn->q[que].pn[tid];
1633 
1634 			if (memcmp(max_pn, cur_pn, IEEE80211_CCMP_PN_LEN) < 0)
1635 				max_pn = cur_pn;
1636 		}
1637 		key_rsc[tid] = cpu_to_le64((u64)max_pn[5] |
1638 					   ((u64)max_pn[4] << 8) |
1639 					   ((u64)max_pn[3] << 16) |
1640 					   ((u64)max_pn[2] << 24) |
1641 					   ((u64)max_pn[1] << 32) |
1642 					   ((u64)max_pn[0] << 40));
1643 	}
1644 }
1645 
1646 static void
1647 iwl_mld_suspend_convert_tkip_ipn(struct ieee80211_key_conf *key,
1648 				 __le64 *rsc)
1649 {
1650 	struct ieee80211_key_seq seq;
1651 
1652 	for (int i = 0; i < IWL_MAX_TID_COUNT; i++) {
1653 		ieee80211_get_key_rx_seq(key, i, &seq);
1654 		rsc[i] =
1655 			cpu_to_le64(((u64)seq.tkip.iv32 << 16) |
1656 				    seq.tkip.iv16);
1657 	}
1658 }
1659 
1660 static void
1661 iwl_mld_suspend_key_data_iter(struct ieee80211_hw *hw,
1662 			      struct ieee80211_vif *vif,
1663 			      struct ieee80211_sta *sta,
1664 			      struct ieee80211_key_conf *key,
1665 			      void *_data)
1666 {
1667 	struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw);
1668 	struct iwl_mld_suspend_key_iter_data *data = _data;
1669 	__le64 *key_rsc;
1670 	__le32 cipher = 0;
1671 
1672 	switch (key->cipher) {
1673 	case WLAN_CIPHER_SUITE_CCMP:
1674 		cipher = cpu_to_le32(STA_KEY_FLG_CCM);
1675 		fallthrough;
1676 	case WLAN_CIPHER_SUITE_GCMP:
1677 	case WLAN_CIPHER_SUITE_GCMP_256:
1678 		if (!cipher)
1679 			cipher = cpu_to_le32(STA_KEY_FLG_GCMP);
1680 		fallthrough;
1681 	case WLAN_CIPHER_SUITE_TKIP:
1682 		if (!cipher)
1683 			cipher = cpu_to_le32(STA_KEY_FLG_TKIP);
1684 		if (sta) {
1685 			key_rsc = data->rsc->ucast_rsc;
1686 			if (key->cipher == WLAN_CIPHER_SUITE_TKIP)
1687 				iwl_mld_suspend_convert_tkip_ipn(key, key_rsc);
1688 			else
1689 				iwl_mld_suspend_set_ucast_pn(mld, sta, key,
1690 							     key_rsc);
1691 
1692 			data->have_rsc = true;
1693 			return;
1694 		}
1695 		/* We're iterating from old to new, there're 4 possible
1696 		 * gtk ids, and only the last two keys matter
1697 		 */
1698 		if (WARN_ON(data->gtks >=
1699 				ARRAY_SIZE(data->found_gtk_idx)))
1700 			return;
1701 
1702 		if (WARN_ON(key->keyidx >=
1703 				ARRAY_SIZE(data->rsc->mcast_key_id_map)))
1704 			return;
1705 		data->gtk_cipher = cipher;
1706 		data->found_gtk_idx[data->gtks] = key->keyidx;
1707 		key_rsc = data->rsc->mcast_rsc[data->gtks % 2];
1708 		data->rsc->mcast_key_id_map[key->keyidx] =
1709 			data->gtks % 2;
1710 
1711 		if (data->gtks >= 2) {
1712 			int prev = data->gtks % 2;
1713 			int prev_idx = data->found_gtk_idx[prev];
1714 
1715 			data->rsc->mcast_key_id_map[prev_idx] =
1716 				IWL_MCAST_KEY_MAP_INVALID;
1717 		}
1718 
1719 		if (key->cipher == WLAN_CIPHER_SUITE_TKIP)
1720 			iwl_mld_suspend_convert_tkip_ipn(key, key_rsc);
1721 		else
1722 			iwl_mld_aes_seq_to_le64_pn(key, key_rsc);
1723 
1724 		data->gtks++;
1725 		data->have_rsc = true;
1726 		break;
1727 	case WLAN_CIPHER_SUITE_BIP_GMAC_128:
1728 	case WLAN_CIPHER_SUITE_BIP_GMAC_256:
1729 		cipher = cpu_to_le32(STA_KEY_FLG_GCMP);
1730 		fallthrough;
1731 	case WLAN_CIPHER_SUITE_BIP_CMAC_256:
1732 	case WLAN_CIPHER_SUITE_AES_CMAC:
1733 		if (!cipher)
1734 			cipher = cpu_to_le32(STA_KEY_FLG_CCM);
1735 		if (key->keyidx == 4 || key->keyidx == 5)
1736 			data->igtk_cipher = cipher;
1737 
1738 		if (key->keyidx == 6 || key->keyidx == 7)
1739 			data->bigtk_cipher = cipher;
1740 
1741 		break;
1742 	}
1743 }
1744 
1745 static int
1746 iwl_mld_send_kek_kck_cmd(struct iwl_mld *mld,
1747 			 struct iwl_mld_vif *mld_vif,
1748 			 struct iwl_mld_suspend_key_iter_data data,
1749 			 int ap_sta_id)
1750 {
1751 	struct iwl_wowlan_kek_kck_material_cmd_v4 kek_kck_cmd = {};
1752 	struct iwl_mld_rekey_data *rekey_data =
1753 		&mld_vif->wowlan_data.rekey_data;
1754 
1755 	memcpy(kek_kck_cmd.kck, rekey_data->kck,
1756 	       rekey_data->kck_len);
1757 	kek_kck_cmd.kck_len = cpu_to_le16(rekey_data->kck_len);
1758 	memcpy(kek_kck_cmd.kek, rekey_data->kek,
1759 	       rekey_data->kek_len);
1760 	kek_kck_cmd.kek_len = cpu_to_le16(rekey_data->kek_len);
1761 	kek_kck_cmd.replay_ctr = rekey_data->replay_ctr;
1762 	kek_kck_cmd.akm = cpu_to_le32(rekey_data->akm);
1763 	kek_kck_cmd.sta_id = cpu_to_le32(ap_sta_id);
1764 	kek_kck_cmd.gtk_cipher = data.gtk_cipher;
1765 	kek_kck_cmd.igtk_cipher = data.igtk_cipher;
1766 	kek_kck_cmd.bigtk_cipher = data.bigtk_cipher;
1767 
1768 	IWL_DEBUG_WOWLAN(mld, "setting akm %d\n",
1769 			 rekey_data->akm);
1770 
1771 	return iwl_mld_send_cmd_pdu(mld, WOWLAN_KEK_KCK_MATERIAL,
1772 				    &kek_kck_cmd);
1773 }
1774 
1775 static int
1776 iwl_mld_suspend_send_security_cmds(struct iwl_mld *mld,
1777 				   struct ieee80211_vif *vif,
1778 				   struct iwl_mld_vif *mld_vif,
1779 				   int ap_sta_id)
1780 {
1781 	struct iwl_mld_suspend_key_iter_data data = {};
1782 	int ret;
1783 
1784 	data.rsc = kzalloc_obj(*data.rsc);
1785 	if (!data.rsc)
1786 		return -ENOMEM;
1787 
1788 	memset(data.rsc->mcast_key_id_map, IWL_MCAST_KEY_MAP_INVALID,
1789 	       ARRAY_SIZE(data.rsc->mcast_key_id_map));
1790 
1791 	data.rsc->sta_id = cpu_to_le32(ap_sta_id);
1792 	ieee80211_iter_keys(mld->hw, vif,
1793 			    iwl_mld_suspend_key_data_iter,
1794 			    &data);
1795 
1796 	if (data.have_rsc)
1797 		ret = iwl_mld_send_cmd_pdu(mld, WOWLAN_TSC_RSC_PARAM,
1798 					   data.rsc);
1799 	else
1800 		ret = 0;
1801 
1802 	if (!ret && mld_vif->wowlan_data.rekey_data.valid)
1803 		ret = iwl_mld_send_kek_kck_cmd(mld, mld_vif, data, ap_sta_id);
1804 
1805 	kfree(data.rsc);
1806 
1807 	return ret;
1808 }
1809 
1810 static void
1811 iwl_mld_set_wowlan_config_cmd(struct iwl_mld *mld,
1812 			      struct cfg80211_wowlan *wowlan,
1813 			      struct iwl_wowlan_config_cmd *wowlan_config_cmd,
1814 			      struct ieee80211_sta *ap_sta,
1815 			      struct ieee80211_bss_conf *link)
1816 {
1817 	wowlan_config_cmd->is_11n_connection =
1818 					ap_sta->deflink.ht_cap.ht_supported;
1819 	wowlan_config_cmd->flags = ENABLE_L3_FILTERING |
1820 		ENABLE_NBNS_FILTERING | ENABLE_DHCP_FILTERING;
1821 
1822 	if (ap_sta->mfp)
1823 		wowlan_config_cmd->flags |= IS_11W_ASSOC;
1824 
1825 	if (iwl_mld_beacon_protection_enabled(mld, link))
1826 		wowlan_config_cmd->flags |= HAS_BEACON_PROTECTION;
1827 
1828 	if (wowlan->disconnect)
1829 		wowlan_config_cmd->wakeup_filter |=
1830 			cpu_to_le32(IWL_WOWLAN_WAKEUP_BEACON_MISS |
1831 				    IWL_WOWLAN_WAKEUP_LINK_CHANGE);
1832 	if (wowlan->magic_pkt)
1833 		wowlan_config_cmd->wakeup_filter |=
1834 			cpu_to_le32(IWL_WOWLAN_WAKEUP_MAGIC_PACKET);
1835 	if (wowlan->gtk_rekey_failure)
1836 		wowlan_config_cmd->wakeup_filter |=
1837 			cpu_to_le32(IWL_WOWLAN_WAKEUP_GTK_REKEY_FAIL);
1838 	if (wowlan->eap_identity_req)
1839 		wowlan_config_cmd->wakeup_filter |=
1840 			cpu_to_le32(IWL_WOWLAN_WAKEUP_EAP_IDENT_REQ);
1841 	if (wowlan->four_way_handshake)
1842 		wowlan_config_cmd->wakeup_filter |=
1843 			cpu_to_le32(IWL_WOWLAN_WAKEUP_4WAY_HANDSHAKE);
1844 	if (wowlan->n_patterns)
1845 		wowlan_config_cmd->wakeup_filter |=
1846 			cpu_to_le32(IWL_WOWLAN_WAKEUP_PATTERN_MATCH);
1847 
1848 	if (wowlan->rfkill_release)
1849 		wowlan_config_cmd->wakeup_filter |=
1850 			cpu_to_le32(IWL_WOWLAN_WAKEUP_RF_KILL_DEASSERT);
1851 
1852 	if (wowlan->any) {
1853 		wowlan_config_cmd->wakeup_filter |=
1854 			cpu_to_le32(IWL_WOWLAN_WAKEUP_BEACON_MISS |
1855 				    IWL_WOWLAN_WAKEUP_LINK_CHANGE |
1856 				    IWL_WOWLAN_WAKEUP_RX_FRAME |
1857 				    IWL_WOWLAN_WAKEUP_BCN_FILTERING);
1858 	}
1859 }
1860 
1861 static int iwl_mld_send_patterns(struct iwl_mld *mld,
1862 				 struct cfg80211_wowlan *wowlan,
1863 				 int ap_sta_id)
1864 {
1865 	struct iwl_wowlan_patterns_cmd *pattern_cmd;
1866 	struct iwl_host_cmd cmd = {
1867 		.id = WOWLAN_PATTERNS,
1868 		.dataflags[0] = IWL_HCMD_DFL_NOCOPY,
1869 	};
1870 	int ret;
1871 
1872 	if (!wowlan->n_patterns)
1873 		return 0;
1874 
1875 	cmd.len[0] = struct_size(pattern_cmd, patterns, wowlan->n_patterns);
1876 
1877 	pattern_cmd = kzalloc(cmd.len[0], GFP_KERNEL);
1878 	if (!pattern_cmd)
1879 		return -ENOMEM;
1880 
1881 	pattern_cmd->n_patterns = wowlan->n_patterns;
1882 	pattern_cmd->sta_id = ap_sta_id;
1883 
1884 	for (int i = 0; i < wowlan->n_patterns; i++) {
1885 		int mask_len = DIV_ROUND_UP(wowlan->patterns[i].pattern_len, 8);
1886 
1887 		pattern_cmd->patterns[i].pattern_type =
1888 			WOWLAN_PATTERN_TYPE_BITMASK;
1889 
1890 		memcpy(&pattern_cmd->patterns[i].u.bitmask.mask,
1891 		       wowlan->patterns[i].mask, mask_len);
1892 		memcpy(&pattern_cmd->patterns[i].u.bitmask.pattern,
1893 		       wowlan->patterns[i].pattern,
1894 		       wowlan->patterns[i].pattern_len);
1895 		pattern_cmd->patterns[i].u.bitmask.mask_size = mask_len;
1896 		pattern_cmd->patterns[i].u.bitmask.pattern_size =
1897 			wowlan->patterns[i].pattern_len;
1898 	}
1899 
1900 	cmd.data[0] = pattern_cmd;
1901 	ret = iwl_mld_send_cmd(mld, &cmd);
1902 	kfree(pattern_cmd);
1903 	return ret;
1904 }
1905 
1906 static int
1907 iwl_mld_send_proto_offload(struct iwl_mld *mld,
1908 			   struct ieee80211_vif *vif,
1909 			   u8 ap_sta_id)
1910 {
1911 	struct iwl_proto_offload_cmd_v4 *cmd __free(kfree);
1912 	struct iwl_host_cmd hcmd = {
1913 		.id = PROT_OFFLOAD_CONFIG_CMD,
1914 		.dataflags[0] = IWL_HCMD_DFL_NOCOPY,
1915 		.len[0] = sizeof(*cmd),
1916 	};
1917 	u32 enabled = 0;
1918 
1919 	cmd = kzalloc(hcmd.len[0], GFP_KERNEL);
1920 	if (!cmd) {
1921 		IWL_DEBUG_WOWLAN(mld, "Failed to allocate proto offload cmd\n");
1922 		return -ENOMEM;
1923 	}
1924 
1925 #if IS_ENABLED(CONFIG_IPV6)
1926 	struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif);
1927 	struct iwl_mld_wowlan_data *wowlan_data = &mld_vif->wowlan_data;
1928 	struct iwl_ns_config *nsc;
1929 	struct iwl_targ_addr *addrs;
1930 	int n_nsc, n_addrs;
1931 	int i, c;
1932 	int num_skipped = 0;
1933 
1934 	nsc = cmd->ns_config;
1935 	n_nsc = IWL_PROTO_OFFLOAD_NUM_NS_CONFIG_V3L;
1936 	addrs = cmd->targ_addrs;
1937 	n_addrs = IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V3L;
1938 
1939 	/* For each address we have (and that will fit) fill a target
1940 	 * address struct and combine for NS offload structs with the
1941 	 * solicited node addresses.
1942 	 */
1943 	for (i = 0, c = 0;
1944 		i < wowlan_data->num_target_ipv6_addrs &&
1945 		i < n_addrs && c < n_nsc; i++) {
1946 		int j;
1947 		struct in6_addr solicited_addr;
1948 
1949 		/* Because ns is offloaded skip tentative address to avoid
1950 		 * violating RFC4862.
1951 		 */
1952 		if (test_bit(i, wowlan_data->tentative_addrs)) {
1953 			num_skipped++;
1954 			continue;
1955 		}
1956 
1957 		addrconf_addr_solict_mult(&wowlan_data->target_ipv6_addrs[i],
1958 					  &solicited_addr);
1959 		for (j = 0; j < n_nsc && j < c; j++)
1960 			if (ipv6_addr_cmp(&nsc[j].dest_ipv6_addr,
1961 					  &solicited_addr) == 0)
1962 				break;
1963 		if (j == c)
1964 			c++;
1965 		addrs[i].addr = wowlan_data->target_ipv6_addrs[i];
1966 		addrs[i].config_num = cpu_to_le32(j);
1967 		nsc[j].dest_ipv6_addr = solicited_addr;
1968 		memcpy(nsc[j].target_mac_addr, vif->addr, ETH_ALEN);
1969 	}
1970 
1971 	if (wowlan_data->num_target_ipv6_addrs - num_skipped)
1972 		enabled |= IWL_D3_PROTO_IPV6_VALID;
1973 
1974 	cmd->num_valid_ipv6_addrs = cpu_to_le32(i - num_skipped);
1975 	if (enabled & IWL_D3_PROTO_IPV6_VALID)
1976 		enabled |= IWL_D3_PROTO_OFFLOAD_NS;
1977 #endif
1978 
1979 	if (vif->cfg.arp_addr_cnt) {
1980 		enabled |= IWL_D3_PROTO_OFFLOAD_ARP | IWL_D3_PROTO_IPV4_VALID;
1981 		cmd->common.host_ipv4_addr = vif->cfg.arp_addr_list[0];
1982 		ether_addr_copy(cmd->common.arp_mac_addr, vif->addr);
1983 	}
1984 
1985 	enabled |= IWL_D3_PROTO_OFFLOAD_BTM;
1986 	cmd->common.enabled = cpu_to_le32(enabled);
1987 	cmd->sta_id = cpu_to_le32(ap_sta_id);
1988 	hcmd.data[0] = cmd;
1989 	return iwl_mld_send_cmd(mld, &hcmd);
1990 }
1991 
1992 static int
1993 iwl_mld_wowlan_config(struct iwl_mld *mld, struct ieee80211_vif *bss_vif,
1994 		      struct cfg80211_wowlan *wowlan)
1995 {
1996 	struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(bss_vif);
1997 	struct ieee80211_sta *ap_sta = mld_vif->ap_sta;
1998 	struct iwl_wowlan_config_cmd wowlan_config_cmd = {
1999 			.offloading_tid = IWL_WOWLAN_OFFLOAD_TID,
2000 	};
2001 	u32 sta_id_mask;
2002 	int ap_sta_id, ret;
2003 	int link_id = iwl_mld_get_primary_link(bss_vif);
2004 	struct ieee80211_bss_conf *link_conf;
2005 
2006 	ret = iwl_mld_block_emlsr_sync(mld, bss_vif,
2007 				       IWL_MLD_EMLSR_BLOCKED_WOWLAN, link_id);
2008 	if (ret)
2009 		return ret;
2010 
2011 	link_conf = link_conf_dereference_protected(bss_vif, link_id);
2012 
2013 	if (WARN_ON(!ap_sta || !link_conf))
2014 		return -EINVAL;
2015 
2016 	sta_id_mask = iwl_mld_fw_sta_id_mask(mld, ap_sta);
2017 	if (WARN_ON(hweight32(sta_id_mask) != 1))
2018 		return -EINVAL;
2019 
2020 	ap_sta_id = __ffs(sta_id_mask);
2021 	wowlan_config_cmd.sta_id = ap_sta_id;
2022 
2023 	ret = iwl_mld_ensure_queue(mld,
2024 				   ap_sta->txq[wowlan_config_cmd.offloading_tid]);
2025 	if (ret)
2026 		return ret;
2027 
2028 	iwl_mld_set_wowlan_config_cmd(mld, wowlan,
2029 				      &wowlan_config_cmd, ap_sta, link_conf);
2030 	ret = iwl_mld_send_cmd_pdu(mld, WOWLAN_CONFIGURATION,
2031 				   &wowlan_config_cmd);
2032 	if (ret)
2033 		return ret;
2034 
2035 	ret = iwl_mld_suspend_send_security_cmds(mld, bss_vif, mld_vif,
2036 						 ap_sta_id);
2037 	if (ret)
2038 		return ret;
2039 
2040 	ret = iwl_mld_send_patterns(mld, wowlan, ap_sta_id);
2041 	if (ret)
2042 		return ret;
2043 
2044 	ret = iwl_mld_send_proto_offload(mld, bss_vif, ap_sta_id);
2045 	if (ret)
2046 		return ret;
2047 
2048 	iwl_mld_enable_beacon_filter(mld, link_conf, true);
2049 	return iwl_mld_update_mac_power(mld, bss_vif, true);
2050 }
2051 
2052 int iwl_mld_wowlan_suspend(struct iwl_mld *mld, struct cfg80211_wowlan *wowlan)
2053 {
2054 	struct ieee80211_vif *bss_vif;
2055 
2056 	lockdep_assert_wiphy(mld->wiphy);
2057 
2058 	if (WARN_ON(!wowlan))
2059 		return 1;
2060 
2061 	bss_vif = iwl_mld_get_bss_vif(mld);
2062 	if (!bss_vif)
2063 		return 1;
2064 
2065 	IWL_DEBUG_WOWLAN(mld, "Starting the wowlan suspend flow\n");
2066 
2067 	if (!bss_vif->cfg.assoc) {
2068 		int ret;
2069 		/*
2070 		 * If not associated we can only do netdetect, if
2071 		 * that's not enabled then just suspend normally.
2072 		 */
2073 		if (!wowlan->nd_config)
2074 			return 1;
2075 
2076 		ret = iwl_mld_netdetect_config(mld, bss_vif, wowlan);
2077 		if (!ret)
2078 			mld->netdetect = true;
2079 
2080 		return ret;
2081 	}
2082 
2083 	return iwl_mld_wowlan_config(mld, bss_vif, wowlan);
2084 }
2085 
2086 /* Returns 0 on success, 1 if an error occurred in firmware during d3,
2087  * A negative value is expected only in unrecovreable cases.
2088  */
2089 int iwl_mld_wowlan_resume(struct iwl_mld *mld)
2090 {
2091 	struct ieee80211_vif *bss_vif;
2092 	struct ieee80211_bss_conf *link_conf;
2093 	struct iwl_mld_netdetect_res netdetect_res;
2094 	struct iwl_mld_resume_data resume_data = {
2095 		.notifs_expected =
2096 			IWL_D3_NOTIF_WOWLAN_INFO |
2097 			IWL_D3_NOTIF_D3_END_NOTIF,
2098 		.netdetect_res = &netdetect_res,
2099 	};
2100 	int link_id;
2101 	int ret;
2102 
2103 	lockdep_assert_wiphy(mld->wiphy);
2104 
2105 	IWL_DEBUG_WOWLAN(mld, "Starting the wowlan resume flow\n");
2106 
2107 	if (!mld->fw_status.in_d3) {
2108 		IWL_DEBUG_WOWLAN(mld,
2109 				 "Device_powered_off() was called during wowlan\n");
2110 		goto err;
2111 	}
2112 
2113 	mld->fw_status.resuming = true;
2114 	mld->fw_status.in_d3 = false;
2115 	mld->scan.last_start_time_jiffies = jiffies;
2116 
2117 	bss_vif = iwl_mld_get_bss_vif(mld);
2118 	if (WARN_ON(!bss_vif))
2119 		goto err;
2120 
2121 	/* We can't have several links upon wowlan entry,
2122 	 * this is enforced in the suspend flow.
2123 	 */
2124 	WARN_ON(hweight16(bss_vif->active_links) > 1);
2125 	link_id = bss_vif->active_links ? __ffs(bss_vif->active_links) : 0;
2126 	link_conf = link_conf_dereference_protected(bss_vif, link_id);
2127 
2128 	if (WARN_ON(!link_conf))
2129 		goto err;
2130 
2131 	iwl_fw_dbg_read_d3_debug_data(&mld->fwrt);
2132 
2133 	resume_data.wowlan_status = kzalloc_obj(*resume_data.wowlan_status);
2134 	if (!resume_data.wowlan_status)
2135 		return -ENOMEM;
2136 
2137 	if (mld->netdetect)
2138 		resume_data.notifs_expected |= IWL_D3_ND_MATCH_INFO;
2139 
2140 	ret = iwl_mld_wait_d3_notif(mld, &resume_data, true);
2141 	if (ret) {
2142 		IWL_ERR(mld, "Couldn't get the d3 notifs %d\n", ret);
2143 		goto err;
2144 	}
2145 
2146 	if (resume_data.d3_end_flags & IWL_D0I3_RESET_REQUIRE) {
2147 		mld->fw_status.in_hw_restart = true;
2148 		goto process_wakeup_results;
2149 	}
2150 
2151 	iwl_mld_update_changed_regdomain(mld);
2152 	iwl_mld_update_mac_power(mld, bss_vif, false);
2153 	iwl_mld_enable_beacon_filter(mld, link_conf, false);
2154 	iwl_mld_update_device_power(mld, false);
2155 
2156 	if (mld->netdetect)
2157 		ret = iwl_mld_scan_stop(mld, IWL_MLD_SCAN_NETDETECT, false);
2158 
2159  process_wakeup_results:
2160 	if (mld->netdetect) {
2161 		iwl_mld_process_netdetect_res(mld, bss_vif, &resume_data);
2162 		mld->netdetect = false;
2163 	} else {
2164 		bool keep_connection =
2165 			iwl_mld_process_wowlan_status(mld, bss_vif,
2166 						      resume_data.wowlan_status);
2167 
2168 		/* EMLSR state will be cleared if the connection is not kept */
2169 		if (keep_connection)
2170 			iwl_mld_unblock_emlsr(mld, bss_vif,
2171 					      IWL_MLD_EMLSR_BLOCKED_WOWLAN);
2172 		else
2173 			ieee80211_resume_disconnect(bss_vif);
2174 	}
2175 
2176 	goto out;
2177 
2178  err:
2179 	mld->fw_status.in_hw_restart = true;
2180 	ret = 1;
2181  out:
2182 	mld->fw_status.resuming = false;
2183 
2184 	if (resume_data.wowlan_status) {
2185 		kfree(resume_data.wowlan_status->wake_packet);
2186 		kfree(resume_data.wowlan_status);
2187 	}
2188 
2189 	return ret;
2190 }
2191