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