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