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