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 ¬if->gtk[0].sc);
432 iwl_mld_convert_ptk_resume_seq(mld, wowlan_status, ¬if->gtk[0].sc);
433 /* only one igtk is passed by FW */
434 iwl_mld_convert_igtk_resume_data(wowlan_status, ¬if->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