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