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