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