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