1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
3 * Copyright (C) 2012-2014, 2018-2024 Intel Corporation
4 * Copyright (C) 2013-2015 Intel Mobile Communications GmbH
5 * Copyright (C) 2016-2017 Intel Deutschland GmbH
7 #include <linux/etherdevice.h>
10 #include <net/cfg80211.h>
13 #include <net/addrconf.h>
14 #include "iwl-modparams.h"
19 void iwl_mvm_set_rekey_data(struct ieee80211_hw
*hw
,
20 struct ieee80211_vif
*vif
,
21 struct cfg80211_gtk_rekey_data
*data
)
23 struct iwl_mvm
*mvm
= IWL_MAC80211_GET_MVM(hw
);
24 struct iwl_mvm_vif
*mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
26 mutex_lock(&mvm
->mutex
);
28 mvmvif
->rekey_data
.kek_len
= data
->kek_len
;
29 mvmvif
->rekey_data
.kck_len
= data
->kck_len
;
30 memcpy(mvmvif
->rekey_data
.kek
, data
->kek
, data
->kek_len
);
31 memcpy(mvmvif
->rekey_data
.kck
, data
->kck
, data
->kck_len
);
32 mvmvif
->rekey_data
.akm
= data
->akm
& 0xFF;
33 mvmvif
->rekey_data
.replay_ctr
=
34 cpu_to_le64(be64_to_cpup((const __be64
*)data
->replay_ctr
));
35 mvmvif
->rekey_data
.valid
= true;
37 mutex_unlock(&mvm
->mutex
);
40 #if IS_ENABLED(CONFIG_IPV6)
41 void iwl_mvm_ipv6_addr_change(struct ieee80211_hw
*hw
,
42 struct ieee80211_vif
*vif
,
43 struct inet6_dev
*idev
)
45 struct iwl_mvm_vif
*mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
46 struct inet6_ifaddr
*ifa
;
49 memset(mvmvif
->tentative_addrs
, 0, sizeof(mvmvif
->tentative_addrs
));
51 read_lock_bh(&idev
->lock
);
52 list_for_each_entry(ifa
, &idev
->addr_list
, if_list
) {
53 mvmvif
->target_ipv6_addrs
[idx
] = ifa
->addr
;
54 if (ifa
->flags
& IFA_F_TENTATIVE
)
55 __set_bit(idx
, mvmvif
->tentative_addrs
);
57 if (idx
>= IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_MAX
)
60 read_unlock_bh(&idev
->lock
);
62 mvmvif
->num_target_ipv6_addrs
= idx
;
66 void iwl_mvm_set_default_unicast_key(struct ieee80211_hw
*hw
,
67 struct ieee80211_vif
*vif
, int idx
)
69 struct iwl_mvm_vif
*mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
71 mvmvif
->tx_key_idx
= idx
;
74 static void iwl_mvm_convert_p1k(u16
*p1k
, __le16
*out
)
78 for (i
= 0; i
< IWL_P1K_SIZE
; i
++)
79 out
[i
] = cpu_to_le16(p1k
[i
]);
82 static const u8
*iwl_mvm_find_max_pn(struct ieee80211_key_conf
*key
,
83 struct iwl_mvm_key_pn
*ptk_pn
,
84 struct ieee80211_key_seq
*seq
,
87 const u8
*ret
= seq
->ccmp
.pn
;
90 /* get the PN from mac80211, used on the default queue */
91 ieee80211_get_key_rx_seq(key
, tid
, seq
);
93 /* and use the internal data for the other queues */
94 for (i
= 1; i
< queues
; i
++) {
95 const u8
*tmp
= ptk_pn
->q
[i
].pn
[tid
];
97 if (memcmp(ret
, tmp
, IEEE80211_CCMP_PN_LEN
) <= 0)
104 struct wowlan_key_reprogram_data
{
109 static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw
*hw
,
110 struct ieee80211_vif
*vif
,
111 struct ieee80211_sta
*sta
,
112 struct ieee80211_key_conf
*key
,
115 struct iwl_mvm
*mvm
= IWL_MAC80211_GET_MVM(hw
);
116 struct iwl_mvm_vif
*mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
117 struct wowlan_key_reprogram_data
*data
= _data
;
120 switch (key
->cipher
) {
121 case WLAN_CIPHER_SUITE_WEP40
:
122 case WLAN_CIPHER_SUITE_WEP104
: { /* hack it for now */
124 struct iwl_mvm_wep_key_cmd wep_key_cmd
;
125 struct iwl_mvm_wep_key wep_key
;
127 .wep_key_cmd
.mac_id_n_color
=
128 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif
->id
,
130 .wep_key_cmd
.num_keys
= 1,
131 /* firmware sets STA_KEY_FLG_WEP_13BYTES */
132 .wep_key_cmd
.decryption_type
= STA_KEY_FLG_WEP
,
133 .wep_key
.key_index
= key
->keyidx
,
134 .wep_key
.key_size
= key
->keylen
,
138 * This will fail -- the key functions don't set support
139 * pairwise WEP keys. However, that's better than silently
140 * failing WoWLAN. Or maybe not?
142 if (key
->flags
& IEEE80211_KEY_FLAG_PAIRWISE
)
145 memcpy(&wkc
.wep_key
.key
[3], key
->key
, key
->keylen
);
146 if (key
->keyidx
== mvmvif
->tx_key_idx
) {
147 /* TX key must be at offset 0 */
148 wkc
.wep_key
.key_offset
= 0;
150 /* others start at 1 */
152 wkc
.wep_key
.key_offset
= data
->wep_key_idx
;
155 mutex_lock(&mvm
->mutex
);
156 ret
= iwl_mvm_send_cmd_pdu(mvm
, WEP_KEY
, 0, sizeof(wkc
), &wkc
);
157 data
->error
= ret
!= 0;
159 mvm
->ptk_ivlen
= key
->iv_len
;
160 mvm
->ptk_icvlen
= key
->icv_len
;
161 mvm
->gtk_ivlen
= key
->iv_len
;
162 mvm
->gtk_icvlen
= key
->icv_len
;
163 mutex_unlock(&mvm
->mutex
);
165 /* don't upload key again */
171 case WLAN_CIPHER_SUITE_BIP_GMAC_256
:
172 case WLAN_CIPHER_SUITE_BIP_GMAC_128
:
174 case WLAN_CIPHER_SUITE_AES_CMAC
:
176 * Ignore CMAC keys -- the WoWLAN firmware doesn't support them
177 * but we also shouldn't abort suspend due to that. It does have
178 * support for the IGTK key renewal, but doesn't really use the
179 * IGTK for anything. This means we could spuriously wake up or
180 * be deauthenticated, but that was considered acceptable.
183 case WLAN_CIPHER_SUITE_TKIP
:
184 case WLAN_CIPHER_SUITE_CCMP
:
185 case WLAN_CIPHER_SUITE_GCMP
:
186 case WLAN_CIPHER_SUITE_GCMP_256
:
190 mutex_lock(&mvm
->mutex
);
192 * The D3 firmware hardcodes the key offset 0 as the key it
193 * uses to transmit packets to the AP, i.e. the PTK.
195 if (key
->flags
& IEEE80211_KEY_FLAG_PAIRWISE
) {
196 mvm
->ptk_ivlen
= key
->iv_len
;
197 mvm
->ptk_icvlen
= key
->icv_len
;
198 ret
= iwl_mvm_set_sta_key(mvm
, vif
, sta
, key
, 0);
201 * firmware only supports TSC/RSC for a single key,
202 * so if there are multiple keep overwriting them
203 * with new ones -- this relies on mac80211 doing
206 mvm
->gtk_ivlen
= key
->iv_len
;
207 mvm
->gtk_icvlen
= key
->icv_len
;
208 ret
= iwl_mvm_set_sta_key(mvm
, vif
, sta
, key
, 1);
210 mutex_unlock(&mvm
->mutex
);
211 data
->error
= ret
!= 0;
214 struct wowlan_key_rsc_tsc_data
{
215 struct iwl_wowlan_rsc_tsc_params_cmd_v4
*rsc_tsc
;
219 static void iwl_mvm_wowlan_get_rsc_tsc_data(struct ieee80211_hw
*hw
,
220 struct ieee80211_vif
*vif
,
221 struct ieee80211_sta
*sta
,
222 struct ieee80211_key_conf
*key
,
225 struct iwl_mvm
*mvm
= IWL_MAC80211_GET_MVM(hw
);
226 struct wowlan_key_rsc_tsc_data
*data
= _data
;
227 struct aes_sc
*aes_sc
;
228 struct tkip_sc
*tkip_sc
, *tkip_tx_sc
= NULL
;
229 struct ieee80211_key_seq seq
;
232 switch (key
->cipher
) {
235 case WLAN_CIPHER_SUITE_TKIP
:
240 data
->rsc_tsc
->params
.all_tsc_rsc
.tkip
.unicast_rsc
;
242 &data
->rsc_tsc
->params
.all_tsc_rsc
.tkip
.tsc
;
244 pn64
= atomic64_read(&key
->tx_pn
);
245 tkip_tx_sc
->iv16
= cpu_to_le16(TKIP_PN_TO_IV16(pn64
));
246 tkip_tx_sc
->iv32
= cpu_to_le32(TKIP_PN_TO_IV32(pn64
));
249 data
->rsc_tsc
->params
.all_tsc_rsc
.tkip
.multicast_rsc
;
253 * For non-QoS this relies on the fact that both the uCode and
254 * mac80211 use TID 0 (as they need to to avoid replay attacks)
255 * for checking the IV in the frames.
257 for (i
= 0; i
< IWL_NUM_RSC
; i
++) {
258 ieee80211_get_key_rx_seq(key
, i
, &seq
);
259 tkip_sc
[i
].iv16
= cpu_to_le16(seq
.tkip
.iv16
);
260 tkip_sc
[i
].iv32
= cpu_to_le32(seq
.tkip
.iv32
);
263 data
->have_rsc_tsc
= true;
265 case WLAN_CIPHER_SUITE_CCMP
:
266 case WLAN_CIPHER_SUITE_GCMP
:
267 case WLAN_CIPHER_SUITE_GCMP_256
:
269 struct aes_sc
*aes_tx_sc
;
273 data
->rsc_tsc
->params
.all_tsc_rsc
.aes
.unicast_rsc
;
275 &data
->rsc_tsc
->params
.all_tsc_rsc
.aes
.tsc
;
277 pn64
= atomic64_read(&key
->tx_pn
);
278 aes_tx_sc
->pn
= cpu_to_le64(pn64
);
281 data
->rsc_tsc
->params
.all_tsc_rsc
.aes
.multicast_rsc
;
285 * For non-QoS this relies on the fact that both the uCode and
286 * mac80211/our RX code use TID 0 for checking the PN.
288 if (sta
&& iwl_mvm_has_new_rx_api(mvm
)) {
289 struct iwl_mvm_sta
*mvmsta
;
290 struct iwl_mvm_key_pn
*ptk_pn
;
293 mvmsta
= iwl_mvm_sta_from_mac80211(sta
);
295 ptk_pn
= rcu_dereference(mvmsta
->ptk_pn
[key
->keyidx
]);
296 if (WARN_ON(!ptk_pn
)) {
301 for (i
= 0; i
< IWL_MAX_TID_COUNT
; i
++) {
302 pn
= iwl_mvm_find_max_pn(key
, ptk_pn
, &seq
, i
,
303 mvm
->trans
->num_rx_queues
);
304 aes_sc
[i
].pn
= cpu_to_le64((u64
)pn
[5] |
314 for (i
= 0; i
< IWL_NUM_RSC
; i
++) {
315 u8
*pn
= seq
.ccmp
.pn
;
317 ieee80211_get_key_rx_seq(key
, i
, &seq
);
318 aes_sc
[i
].pn
= cpu_to_le64((u64
)pn
[5] |
326 data
->have_rsc_tsc
= true;
331 struct wowlan_key_rsc_v5_data
{
332 struct iwl_wowlan_rsc_tsc_params_cmd
*rsc
;
338 static void iwl_mvm_wowlan_get_rsc_v5_data(struct ieee80211_hw
*hw
,
339 struct ieee80211_vif
*vif
,
340 struct ieee80211_sta
*sta
,
341 struct ieee80211_key_conf
*key
,
344 struct iwl_mvm
*mvm
= IWL_MAC80211_GET_MVM(hw
);
345 struct wowlan_key_rsc_v5_data
*data
= _data
;
346 struct ieee80211_key_seq seq
;
350 /* only for ciphers that can be PTK/GTK */
351 switch (key
->cipher
) {
354 case WLAN_CIPHER_SUITE_TKIP
:
355 case WLAN_CIPHER_SUITE_CCMP
:
356 case WLAN_CIPHER_SUITE_GCMP
:
357 case WLAN_CIPHER_SUITE_GCMP_256
:
362 rsc
= data
->rsc
->ucast_rsc
;
364 if (WARN_ON(data
->gtks
>= ARRAY_SIZE(data
->gtk_ids
)))
366 data
->gtk_ids
[data
->gtks
] = key
->keyidx
;
367 rsc
= data
->rsc
->mcast_rsc
[data
->gtks
% 2];
368 if (WARN_ON(key
->keyidx
>=
369 ARRAY_SIZE(data
->rsc
->mcast_key_id_map
)))
371 data
->rsc
->mcast_key_id_map
[key
->keyidx
] = data
->gtks
% 2;
372 if (data
->gtks
>= 2) {
373 int prev
= data
->gtks
- 2;
374 int prev_idx
= data
->gtk_ids
[prev
];
376 data
->rsc
->mcast_key_id_map
[prev_idx
] =
377 IWL_MCAST_KEY_MAP_INVALID
;
382 switch (key
->cipher
) {
386 case WLAN_CIPHER_SUITE_TKIP
:
389 * For non-QoS this relies on the fact that both the uCode and
390 * mac80211 use TID 0 (as they need to to avoid replay attacks)
391 * for checking the IV in the frames.
393 for (i
= 0; i
< IWL_MAX_TID_COUNT
; i
++) {
394 ieee80211_get_key_rx_seq(key
, i
, &seq
);
396 rsc
[i
] = cpu_to_le64(((u64
)seq
.tkip
.iv32
<< 16) |
400 data
->have_rsc
= true;
402 case WLAN_CIPHER_SUITE_CCMP
:
403 case WLAN_CIPHER_SUITE_GCMP
:
404 case WLAN_CIPHER_SUITE_GCMP_256
:
406 * For non-QoS this relies on the fact that both the uCode and
407 * mac80211/our RX code use TID 0 for checking the PN.
410 struct iwl_mvm_sta
*mvmsta
;
411 struct iwl_mvm_key_pn
*ptk_pn
;
414 mvmsta
= iwl_mvm_sta_from_mac80211(sta
);
416 ptk_pn
= rcu_dereference(mvmsta
->ptk_pn
[key
->keyidx
]);
417 if (WARN_ON(!ptk_pn
)) {
422 for (i
= 0; i
< IWL_MAX_TID_COUNT
; i
++) {
423 pn
= iwl_mvm_find_max_pn(key
, ptk_pn
, &seq
, i
,
424 mvm
->trans
->num_rx_queues
);
425 rsc
[i
] = cpu_to_le64((u64
)pn
[5] |
435 for (i
= 0; i
< IWL_MAX_TID_COUNT
; i
++) {
436 u8
*pn
= seq
.ccmp
.pn
;
438 ieee80211_get_key_rx_seq(key
, i
, &seq
);
439 rsc
[i
] = cpu_to_le64((u64
)pn
[5] |
447 data
->have_rsc
= true;
452 static int iwl_mvm_wowlan_config_rsc_tsc(struct iwl_mvm
*mvm
,
453 struct ieee80211_vif
*vif
,
454 struct iwl_mvm_vif_link_info
*mvm_link
)
456 int ver
= iwl_fw_lookup_cmd_ver(mvm
->fw
, WOWLAN_TSC_RSC_PARAM
,
457 IWL_FW_CMD_VER_UNKNOWN
);
461 struct wowlan_key_rsc_v5_data data
= {};
464 data
.rsc
= kzalloc(sizeof(*data
.rsc
), GFP_KERNEL
);
468 for (i
= 0; i
< ARRAY_SIZE(data
.rsc
->mcast_key_id_map
); i
++)
469 data
.rsc
->mcast_key_id_map
[i
] =
470 IWL_MCAST_KEY_MAP_INVALID
;
471 data
.rsc
->sta_id
= cpu_to_le32(mvm_link
->ap_sta_id
);
473 ieee80211_iter_keys(mvm
->hw
, vif
,
474 iwl_mvm_wowlan_get_rsc_v5_data
,
478 ret
= iwl_mvm_send_cmd_pdu(mvm
, WOWLAN_TSC_RSC_PARAM
,
479 CMD_ASYNC
, sizeof(*data
.rsc
),
484 } else if (ver
== 4 || ver
== 2 || ver
== IWL_FW_CMD_VER_UNKNOWN
) {
485 struct wowlan_key_rsc_tsc_data data
= {};
488 data
.rsc_tsc
= kzalloc(sizeof(*data
.rsc_tsc
), GFP_KERNEL
);
493 size
= sizeof(*data
.rsc_tsc
);
494 data
.rsc_tsc
->sta_id
=
495 cpu_to_le32(mvm_link
->ap_sta_id
);
497 /* ver == 2 || ver == IWL_FW_CMD_VER_UNKNOWN */
498 size
= sizeof(data
.rsc_tsc
->params
);
501 ieee80211_iter_keys(mvm
->hw
, vif
,
502 iwl_mvm_wowlan_get_rsc_tsc_data
,
505 if (data
.have_rsc_tsc
)
506 ret
= iwl_mvm_send_cmd_pdu(mvm
, WOWLAN_TSC_RSC_PARAM
,
520 struct wowlan_key_tkip_data
{
521 struct iwl_wowlan_tkip_params_cmd tkip
;
525 static void iwl_mvm_wowlan_get_tkip_data(struct ieee80211_hw
*hw
,
526 struct ieee80211_vif
*vif
,
527 struct ieee80211_sta
*sta
,
528 struct ieee80211_key_conf
*key
,
531 struct wowlan_key_tkip_data
*data
= _data
;
532 struct iwl_p1k_cache
*rx_p1ks
;
534 struct ieee80211_key_seq seq
;
536 u16 p1k
[IWL_P1K_SIZE
];
539 switch (key
->cipher
) {
542 case WLAN_CIPHER_SUITE_TKIP
:
546 rx_p1ks
= data
->tkip
.rx_uni
;
548 pn64
= atomic64_read(&key
->tx_pn
);
550 ieee80211_get_tkip_p1k_iv(key
, TKIP_PN_TO_IV32(pn64
),
552 iwl_mvm_convert_p1k(p1k
, data
->tkip
.tx
.p1k
);
554 memcpy(data
->tkip
.mic_keys
.tx
,
555 &key
->key
[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY
],
558 rx_mic_key
= data
->tkip
.mic_keys
.rx_unicast
;
560 rx_p1ks
= data
->tkip
.rx_multi
;
561 rx_mic_key
= data
->tkip
.mic_keys
.rx_mcast
;
564 for (i
= 0; i
< IWL_NUM_RSC
; i
++) {
565 ieee80211_get_key_rx_seq(key
, i
, &seq
);
566 /* wrapping isn't allowed, AP must rekey */
567 if (seq
.tkip
.iv32
> cur_rx_iv32
)
568 cur_rx_iv32
= seq
.tkip
.iv32
;
571 ieee80211_get_tkip_rx_p1k(key
, vif
->bss_conf
.bssid
,
573 iwl_mvm_convert_p1k(p1k
, rx_p1ks
[0].p1k
);
574 ieee80211_get_tkip_rx_p1k(key
, vif
->bss_conf
.bssid
,
575 cur_rx_iv32
+ 1, p1k
);
576 iwl_mvm_convert_p1k(p1k
, rx_p1ks
[1].p1k
);
579 &key
->key
[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY
],
582 data
->have_tkip_keys
= true;
587 struct wowlan_key_gtk_type_iter
{
588 struct iwl_wowlan_kek_kck_material_cmd_v4
*kek_kck_cmd
;
591 static void iwl_mvm_wowlan_gtk_type_iter(struct ieee80211_hw
*hw
,
592 struct ieee80211_vif
*vif
,
593 struct ieee80211_sta
*sta
,
594 struct ieee80211_key_conf
*key
,
597 struct wowlan_key_gtk_type_iter
*data
= _data
;
598 __le32
*cipher
= NULL
;
600 if (key
->keyidx
== 4 || key
->keyidx
== 5)
601 cipher
= &data
->kek_kck_cmd
->igtk_cipher
;
602 if (key
->keyidx
== 6 || key
->keyidx
== 7)
603 cipher
= &data
->kek_kck_cmd
->bigtk_cipher
;
605 switch (key
->cipher
) {
608 case WLAN_CIPHER_SUITE_TKIP
:
610 data
->kek_kck_cmd
->gtk_cipher
=
611 cpu_to_le32(STA_KEY_FLG_TKIP
);
613 case WLAN_CIPHER_SUITE_BIP_GMAC_256
:
614 case WLAN_CIPHER_SUITE_BIP_GMAC_128
:
616 *cipher
= cpu_to_le32(STA_KEY_FLG_GCMP
);
618 case WLAN_CIPHER_SUITE_AES_CMAC
:
619 case WLAN_CIPHER_SUITE_BIP_CMAC_256
:
621 *cipher
= cpu_to_le32(STA_KEY_FLG_CCM
);
623 case WLAN_CIPHER_SUITE_CCMP
:
625 data
->kek_kck_cmd
->gtk_cipher
=
626 cpu_to_le32(STA_KEY_FLG_CCM
);
628 case WLAN_CIPHER_SUITE_GCMP
:
629 case WLAN_CIPHER_SUITE_GCMP_256
:
631 data
->kek_kck_cmd
->gtk_cipher
=
632 cpu_to_le32(STA_KEY_FLG_GCMP
);
637 static int iwl_mvm_send_patterns_v1(struct iwl_mvm
*mvm
,
638 struct cfg80211_wowlan
*wowlan
)
640 struct iwl_wowlan_patterns_cmd_v1
*pattern_cmd
;
641 struct iwl_host_cmd cmd
= {
642 .id
= WOWLAN_PATTERNS
,
643 .dataflags
[0] = IWL_HCMD_DFL_NOCOPY
,
647 if (!wowlan
->n_patterns
)
650 cmd
.len
[0] = struct_size(pattern_cmd
, patterns
, wowlan
->n_patterns
);
652 pattern_cmd
= kmalloc(cmd
.len
[0], GFP_KERNEL
);
656 pattern_cmd
->n_patterns
= cpu_to_le32(wowlan
->n_patterns
);
658 for (i
= 0; i
< wowlan
->n_patterns
; i
++) {
659 int mask_len
= DIV_ROUND_UP(wowlan
->patterns
[i
].pattern_len
, 8);
661 memcpy(&pattern_cmd
->patterns
[i
].mask
,
662 wowlan
->patterns
[i
].mask
, mask_len
);
663 memcpy(&pattern_cmd
->patterns
[i
].pattern
,
664 wowlan
->patterns
[i
].pattern
,
665 wowlan
->patterns
[i
].pattern_len
);
666 pattern_cmd
->patterns
[i
].mask_size
= mask_len
;
667 pattern_cmd
->patterns
[i
].pattern_size
=
668 wowlan
->patterns
[i
].pattern_len
;
671 cmd
.data
[0] = pattern_cmd
;
672 err
= iwl_mvm_send_cmd(mvm
, &cmd
);
677 static int iwl_mvm_send_patterns(struct iwl_mvm
*mvm
,
678 struct iwl_mvm_vif_link_info
*mvm_link
,
679 struct cfg80211_wowlan
*wowlan
)
681 struct iwl_wowlan_patterns_cmd
*pattern_cmd
;
682 struct iwl_host_cmd cmd
= {
683 .id
= WOWLAN_PATTERNS
,
684 .dataflags
[0] = IWL_HCMD_DFL_NOCOPY
,
687 int ver
= iwl_fw_lookup_cmd_ver(mvm
->fw
, cmd
.id
,
688 IWL_FW_CMD_VER_UNKNOWN
);
690 if (!wowlan
->n_patterns
)
693 cmd
.len
[0] = sizeof(*pattern_cmd
) +
694 wowlan
->n_patterns
* sizeof(struct iwl_wowlan_pattern_v2
);
696 pattern_cmd
= kzalloc(cmd
.len
[0], GFP_KERNEL
);
700 pattern_cmd
->n_patterns
= wowlan
->n_patterns
;
702 pattern_cmd
->sta_id
= mvm_link
->ap_sta_id
;
704 for (i
= 0; i
< wowlan
->n_patterns
; i
++) {
705 int mask_len
= DIV_ROUND_UP(wowlan
->patterns
[i
].pattern_len
, 8);
707 pattern_cmd
->patterns
[i
].pattern_type
=
708 WOWLAN_PATTERN_TYPE_BITMASK
;
710 memcpy(&pattern_cmd
->patterns
[i
].u
.bitmask
.mask
,
711 wowlan
->patterns
[i
].mask
, mask_len
);
712 memcpy(&pattern_cmd
->patterns
[i
].u
.bitmask
.pattern
,
713 wowlan
->patterns
[i
].pattern
,
714 wowlan
->patterns
[i
].pattern_len
);
715 pattern_cmd
->patterns
[i
].u
.bitmask
.mask_size
= mask_len
;
716 pattern_cmd
->patterns
[i
].u
.bitmask
.pattern_size
=
717 wowlan
->patterns
[i
].pattern_len
;
720 cmd
.data
[0] = pattern_cmd
;
721 err
= iwl_mvm_send_cmd(mvm
, &cmd
);
726 static int iwl_mvm_d3_reprogram(struct iwl_mvm
*mvm
, struct ieee80211_vif
*vif
,
727 struct ieee80211_sta
*ap_sta
)
729 struct iwl_mvm_vif
*mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
730 struct ieee80211_chanctx_conf
*ctx
;
731 u8 chains_static
, chains_dynamic
;
732 struct cfg80211_chan_def chandef
, ap_def
;
734 struct iwl_binding_cmd_v1 binding_cmd
= {};
735 struct iwl_time_quota_cmd quota_cmd
= {};
736 struct iwl_time_quota_data
*quota
;
739 if (WARN_ON_ONCE(iwl_mvm_is_cdb_supported(mvm
) ||
740 ieee80211_vif_is_mld(vif
)))
743 /* add back the PHY */
744 if (WARN_ON(!mvmvif
->deflink
.phy_ctxt
))
748 ctx
= rcu_dereference(vif
->bss_conf
.chanctx_conf
);
755 chains_static
= ctx
->rx_chains_static
;
756 chains_dynamic
= ctx
->rx_chains_dynamic
;
759 ret
= iwl_mvm_phy_ctxt_add(mvm
, mvmvif
->deflink
.phy_ctxt
, &chandef
,
760 &ap_def
, chains_static
, chains_dynamic
);
764 /* add back the MAC */
765 mvmvif
->uploaded
= false;
767 if (WARN_ON(!vif
->cfg
.assoc
))
770 ret
= iwl_mvm_mac_ctxt_add(mvm
, vif
);
774 /* add back binding - XXX refactor? */
775 binding_cmd
.id_and_color
=
776 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif
->deflink
.phy_ctxt
->id
,
777 mvmvif
->deflink
.phy_ctxt
->color
));
778 binding_cmd
.action
= cpu_to_le32(FW_CTXT_ACTION_ADD
);
780 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif
->deflink
.phy_ctxt
->id
,
781 mvmvif
->deflink
.phy_ctxt
->color
));
782 binding_cmd
.macs
[0] = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif
->id
,
784 for (i
= 1; i
< MAX_MACS_IN_BINDING
; i
++)
785 binding_cmd
.macs
[i
] = cpu_to_le32(FW_CTXT_INVALID
);
788 ret
= iwl_mvm_send_cmd_pdu_status(mvm
, BINDING_CONTEXT_CMD
,
789 IWL_BINDING_CMD_SIZE_V1
, &binding_cmd
,
792 IWL_ERR(mvm
, "Failed to add binding: %d\n", ret
);
797 IWL_ERR(mvm
, "Binding command failed: %u\n", status
);
801 ret
= iwl_mvm_sta_send_to_fw(mvm
, ap_sta
, false, 0);
804 rcu_assign_pointer(mvm
->fw_id_to_mac_id
[mvmvif
->deflink
.ap_sta_id
],
807 ret
= iwl_mvm_mac_ctxt_changed(mvm
, vif
, false, NULL
);
812 quota
= iwl_mvm_quota_cmd_get_quota(mvm
, "a_cmd
, 0);
813 quota
->id_and_color
=
814 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif
->deflink
.phy_ctxt
->id
,
815 mvmvif
->deflink
.phy_ctxt
->color
));
816 quota
->quota
= cpu_to_le32(IWL_MVM_MAX_QUOTA
);
817 quota
->max_duration
= cpu_to_le32(IWL_MVM_MAX_QUOTA
);
819 for (i
= 1; i
< MAX_BINDINGS
; i
++) {
820 quota
= iwl_mvm_quota_cmd_get_quota(mvm
, "a_cmd
, i
);
821 quota
->id_and_color
= cpu_to_le32(FW_CTXT_INVALID
);
824 ret
= iwl_mvm_send_cmd_pdu(mvm
, TIME_QUOTA_CMD
, 0,
825 iwl_mvm_quota_cmd_size(mvm
), "a_cmd
);
827 IWL_ERR(mvm
, "Failed to send quota: %d\n", ret
);
829 if (iwl_mvm_is_lar_supported(mvm
) && iwl_mvm_init_fw_regd(mvm
, false))
830 IWL_ERR(mvm
, "Failed to initialize D3 LAR information\n");
835 static int iwl_mvm_get_last_nonqos_seq(struct iwl_mvm
*mvm
,
836 struct ieee80211_vif
*vif
)
838 struct iwl_mvm_vif
*mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
839 struct iwl_nonqos_seq_query_cmd query_cmd
= {
840 .get_set_flag
= cpu_to_le32(IWL_NONQOS_SEQ_GET
),
842 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif
->id
,
845 struct iwl_host_cmd cmd
= {
846 .id
= NON_QOS_TX_COUNTER_CMD
,
847 .flags
= CMD_WANT_SKB
,
852 cmd
.data
[0] = &query_cmd
;
853 cmd
.len
[0] = sizeof(query_cmd
);
855 err
= iwl_mvm_send_cmd(mvm
, &cmd
);
859 size
= iwl_rx_packet_payload_len(cmd
.resp_pkt
);
860 if (size
< sizeof(__le16
)) {
863 err
= le16_to_cpup((__le16
*)cmd
.resp_pkt
->data
);
864 /* firmware returns next, not last-used seqno */
865 err
= (u16
) (err
- 0x10);
872 void iwl_mvm_set_last_nonqos_seq(struct iwl_mvm
*mvm
, struct ieee80211_vif
*vif
)
874 struct iwl_mvm_vif
*mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
875 struct iwl_nonqos_seq_query_cmd query_cmd
= {
876 .get_set_flag
= cpu_to_le32(IWL_NONQOS_SEQ_SET
),
878 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif
->id
,
880 .value
= cpu_to_le16(mvmvif
->seqno
),
883 /* return if called during restart, not resume from D3 */
884 if (!mvmvif
->seqno_valid
)
887 mvmvif
->seqno_valid
= false;
889 if (iwl_mvm_send_cmd_pdu(mvm
, NON_QOS_TX_COUNTER_CMD
, 0,
890 sizeof(query_cmd
), &query_cmd
))
891 IWL_ERR(mvm
, "failed to set non-QoS seqno\n");
894 static int iwl_mvm_switch_to_d3(struct iwl_mvm
*mvm
)
896 iwl_mvm_scan_stop(mvm
, IWL_MVM_SCAN_REGULAR
, true);
898 iwl_mvm_stop_device(mvm
);
900 * Set the HW restart bit -- this is mostly true as we're
901 * going to load new firmware and reprogram that, though
902 * the reprogramming is going to be manual to avoid adding
903 * all the MACs that aren't support.
904 * We don't have to clear up everything though because the
905 * reprogramming is manual. When we resume, we'll actually
906 * go through a proper restart sequence again to switch
907 * back to the runtime firmware image.
909 set_bit(IWL_MVM_STATUS_IN_HW_RESTART
, &mvm
->status
);
911 /* the fw is reset, so all the keys are cleared */
912 memset(mvm
->fw_key_table
, 0, sizeof(mvm
->fw_key_table
));
919 return iwl_mvm_load_d3_fw(mvm
);
923 iwl_mvm_get_wowlan_config(struct iwl_mvm
*mvm
,
924 struct cfg80211_wowlan
*wowlan
,
925 struct iwl_wowlan_config_cmd_v6
*wowlan_config_cmd
,
926 struct ieee80211_vif
*vif
, struct iwl_mvm_vif
*mvmvif
,
927 struct ieee80211_sta
*ap_sta
)
929 struct iwl_mvm_sta
*mvm_ap_sta
= iwl_mvm_sta_from_mac80211(ap_sta
);
931 /* TODO: wowlan_config_cmd->wowlan_ba_teardown_tids */
933 wowlan_config_cmd
->is_11n_connection
=
934 ap_sta
->deflink
.ht_cap
.ht_supported
;
935 wowlan_config_cmd
->flags
= ENABLE_L3_FILTERING
|
936 ENABLE_NBNS_FILTERING
| ENABLE_DHCP_FILTERING
;
939 wowlan_config_cmd
->flags
|= IS_11W_ASSOC
;
941 if (iwl_fw_lookup_cmd_ver(mvm
->fw
, WOWLAN_CONFIGURATION
, 0) < 6) {
942 /* Query the last used seqno and set it */
943 int ret
= iwl_mvm_get_last_nonqos_seq(mvm
, vif
);
948 wowlan_config_cmd
->non_qos_seq
= cpu_to_le16(ret
);
951 if (iwl_fw_lookup_cmd_ver(mvm
->fw
, WOWLAN_CONFIGURATION
, 0) < 7)
952 iwl_mvm_set_wowlan_qos_seq(mvm_ap_sta
, wowlan_config_cmd
);
954 if (wowlan
->disconnect
)
955 wowlan_config_cmd
->wakeup_filter
|=
956 cpu_to_le32(IWL_WOWLAN_WAKEUP_BEACON_MISS
|
957 IWL_WOWLAN_WAKEUP_LINK_CHANGE
);
958 if (wowlan
->magic_pkt
)
959 wowlan_config_cmd
->wakeup_filter
|=
960 cpu_to_le32(IWL_WOWLAN_WAKEUP_MAGIC_PACKET
);
961 if (wowlan
->gtk_rekey_failure
)
962 wowlan_config_cmd
->wakeup_filter
|=
963 cpu_to_le32(IWL_WOWLAN_WAKEUP_GTK_REKEY_FAIL
);
964 if (wowlan
->eap_identity_req
)
965 wowlan_config_cmd
->wakeup_filter
|=
966 cpu_to_le32(IWL_WOWLAN_WAKEUP_EAP_IDENT_REQ
);
967 if (wowlan
->four_way_handshake
)
968 wowlan_config_cmd
->wakeup_filter
|=
969 cpu_to_le32(IWL_WOWLAN_WAKEUP_4WAY_HANDSHAKE
);
970 if (wowlan
->n_patterns
)
971 wowlan_config_cmd
->wakeup_filter
|=
972 cpu_to_le32(IWL_WOWLAN_WAKEUP_PATTERN_MATCH
);
974 if (wowlan
->rfkill_release
)
975 wowlan_config_cmd
->wakeup_filter
|=
976 cpu_to_le32(IWL_WOWLAN_WAKEUP_RF_KILL_DEASSERT
);
980 * Set the "link change" (really "link lost") flag as well
981 * since that implies losing the TCP connection.
983 wowlan_config_cmd
->wakeup_filter
|=
984 cpu_to_le32(IWL_WOWLAN_WAKEUP_REMOTE_LINK_LOSS
|
985 IWL_WOWLAN_WAKEUP_REMOTE_SIGNATURE_TABLE
|
986 IWL_WOWLAN_WAKEUP_REMOTE_WAKEUP_PACKET
|
987 IWL_WOWLAN_WAKEUP_LINK_CHANGE
);
991 wowlan_config_cmd
->wakeup_filter
|=
992 cpu_to_le32(IWL_WOWLAN_WAKEUP_BEACON_MISS
|
993 IWL_WOWLAN_WAKEUP_LINK_CHANGE
|
994 IWL_WOWLAN_WAKEUP_RX_FRAME
|
995 IWL_WOWLAN_WAKEUP_BCN_FILTERING
);
1001 static int iwl_mvm_wowlan_config_key_params(struct iwl_mvm
*mvm
,
1002 struct ieee80211_vif
*vif
,
1003 struct iwl_mvm_vif_link_info
*mvm_link
)
1005 bool unified
= fw_has_capa(&mvm
->fw
->ucode_capa
,
1006 IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG
);
1007 struct wowlan_key_reprogram_data key_data
= {};
1008 struct iwl_mvm_vif
*mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
1015 * if we have to configure keys, call ieee80211_iter_keys(),
1016 * as we need non-atomic context in order to take the
1020 * Note that currently we don't use CMD_ASYNC in the iterator.
1021 * In case of key_data.configure_keys, all the configured
1022 * commands are SYNC, and iwl_mvm_wowlan_program_keys() will
1023 * take care of locking/unlocking mvm->mutex.
1025 ieee80211_iter_keys(mvm
->hw
, vif
, iwl_mvm_wowlan_program_keys
,
1032 ret
= iwl_mvm_wowlan_config_rsc_tsc(mvm
, vif
, mvm_link
);
1036 if (!fw_has_api(&mvm
->fw
->ucode_capa
,
1037 IWL_UCODE_TLV_API_TKIP_MIC_KEYS
)) {
1038 int ver
= iwl_fw_lookup_cmd_ver(mvm
->fw
, WOWLAN_TKIP_PARAM
,
1039 IWL_FW_CMD_VER_UNKNOWN
);
1040 struct wowlan_key_tkip_data tkip_data
= {};
1044 size
= sizeof(tkip_data
.tkip
);
1045 tkip_data
.tkip
.sta_id
=
1046 cpu_to_le32(mvm_link
->ap_sta_id
);
1047 } else if (ver
== 1 || ver
== IWL_FW_CMD_VER_UNKNOWN
) {
1048 size
= sizeof(struct iwl_wowlan_tkip_params_cmd_ver_1
);
1054 ieee80211_iter_keys(mvm
->hw
, vif
, iwl_mvm_wowlan_get_tkip_data
,
1057 if (tkip_data
.have_tkip_keys
) {
1058 /* send relevant data according to CMD version */
1059 ret
= iwl_mvm_send_cmd_pdu(mvm
,
1068 /* configure rekey data only if offloaded rekey is supported (d3) */
1069 if (mvmvif
->rekey_data
.valid
) {
1070 struct iwl_wowlan_kek_kck_material_cmd_v4 kek_kck_cmd
= {};
1071 struct iwl_wowlan_kek_kck_material_cmd_v4
*_kek_kck_cmd
=
1073 struct wowlan_key_gtk_type_iter gtk_type_data
= {
1074 .kek_kck_cmd
= _kek_kck_cmd
,
1077 cmd_ver
= iwl_fw_lookup_cmd_ver(mvm
->fw
,
1078 WOWLAN_KEK_KCK_MATERIAL
,
1079 IWL_FW_CMD_VER_UNKNOWN
);
1080 if (WARN_ON(cmd_ver
!= 2 && cmd_ver
!= 3 && cmd_ver
!= 4 &&
1081 cmd_ver
!= IWL_FW_CMD_VER_UNKNOWN
))
1084 ieee80211_iter_keys(mvm
->hw
, vif
, iwl_mvm_wowlan_gtk_type_iter
,
1087 memcpy(kek_kck_cmd
.kck
, mvmvif
->rekey_data
.kck
,
1088 mvmvif
->rekey_data
.kck_len
);
1089 kek_kck_cmd
.kck_len
= cpu_to_le16(mvmvif
->rekey_data
.kck_len
);
1090 memcpy(kek_kck_cmd
.kek
, mvmvif
->rekey_data
.kek
,
1091 mvmvif
->rekey_data
.kek_len
);
1092 kek_kck_cmd
.kek_len
= cpu_to_le16(mvmvif
->rekey_data
.kek_len
);
1093 kek_kck_cmd
.replay_ctr
= mvmvif
->rekey_data
.replay_ctr
;
1094 kek_kck_cmd
.akm
= cpu_to_le32(mvmvif
->rekey_data
.akm
);
1095 kek_kck_cmd
.sta_id
= cpu_to_le32(mvm_link
->ap_sta_id
);
1098 cmd_size
= sizeof(struct iwl_wowlan_kek_kck_material_cmd_v4
);
1102 sizeof(struct iwl_wowlan_kek_kck_material_cmd_v3
);
1105 sizeof(struct iwl_wowlan_kek_kck_material_cmd_v2
);
1106 /* skip the sta_id at the beginning */
1107 _kek_kck_cmd
= (void *)
1108 ((u8
*)_kek_kck_cmd
+ sizeof(kek_kck_cmd
.sta_id
));
1111 IWL_DEBUG_WOWLAN(mvm
, "setting akm %d\n",
1112 mvmvif
->rekey_data
.akm
);
1114 ret
= iwl_mvm_send_cmd_pdu(mvm
, WOWLAN_KEK_KCK_MATERIAL
,
1115 CMD_ASYNC
, cmd_size
, _kek_kck_cmd
);
1124 iwl_mvm_wowlan_config(struct iwl_mvm
*mvm
,
1125 struct cfg80211_wowlan
*wowlan
,
1126 struct iwl_wowlan_config_cmd_v6
*wowlan_config_cmd_v6
,
1127 struct ieee80211_vif
*vif
, struct iwl_mvm_vif
*mvmvif
,
1128 struct iwl_mvm_vif_link_info
*mvm_link
,
1129 struct ieee80211_sta
*ap_sta
)
1132 bool unified_image
= fw_has_capa(&mvm
->fw
->ucode_capa
,
1133 IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG
);
1135 mvm
->offload_tid
= wowlan_config_cmd_v6
->offloading_tid
;
1137 if (!unified_image
) {
1138 ret
= iwl_mvm_switch_to_d3(mvm
);
1142 ret
= iwl_mvm_d3_reprogram(mvm
, vif
, ap_sta
);
1147 ret
= iwl_mvm_wowlan_config_key_params(mvm
, vif
, mvm_link
);
1151 if (iwl_fw_lookup_cmd_ver(mvm
->fw
, WOWLAN_CONFIGURATION
, 0) > 6) {
1152 struct iwl_wowlan_config_cmd wowlan_config_cmd
= {
1153 .wakeup_filter
= wowlan_config_cmd_v6
->wakeup_filter
,
1154 .wowlan_ba_teardown_tids
=
1155 wowlan_config_cmd_v6
->wowlan_ba_teardown_tids
,
1156 .is_11n_connection
=
1157 wowlan_config_cmd_v6
->is_11n_connection
,
1158 .offloading_tid
= wowlan_config_cmd_v6
->offloading_tid
,
1159 .flags
= wowlan_config_cmd_v6
->flags
,
1160 .sta_id
= wowlan_config_cmd_v6
->sta_id
,
1163 ret
= iwl_mvm_send_cmd_pdu(mvm
, WOWLAN_CONFIGURATION
, 0,
1164 sizeof(wowlan_config_cmd
),
1165 &wowlan_config_cmd
);
1167 ret
= iwl_mvm_send_cmd_pdu(mvm
, WOWLAN_CONFIGURATION
, 0,
1168 sizeof(*wowlan_config_cmd_v6
),
1169 wowlan_config_cmd_v6
);
1174 if (fw_has_api(&mvm
->fw
->ucode_capa
,
1175 IWL_UCODE_TLV_API_WOWLAN_TCP_SYN_WAKE
))
1176 ret
= iwl_mvm_send_patterns(mvm
, mvm_link
, wowlan
);
1178 ret
= iwl_mvm_send_patterns_v1(mvm
, wowlan
);
1182 return iwl_mvm_send_proto_offload(mvm
, vif
, false, true, 0,
1183 mvm_link
->ap_sta_id
);
1187 iwl_mvm_netdetect_config(struct iwl_mvm
*mvm
,
1188 struct cfg80211_wowlan
*wowlan
,
1189 struct cfg80211_sched_scan_request
*nd_config
,
1190 struct ieee80211_vif
*vif
)
1193 bool unified_image
= fw_has_capa(&mvm
->fw
->ucode_capa
,
1194 IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG
);
1196 if (!unified_image
) {
1197 ret
= iwl_mvm_switch_to_d3(mvm
);
1201 /* In theory, we wouldn't have to stop a running sched
1202 * scan in order to start another one (for
1203 * net-detect). But in practice this doesn't seem to
1204 * work properly, so stop any running sched_scan now.
1206 ret
= iwl_mvm_scan_stop(mvm
, IWL_MVM_SCAN_SCHED
, true);
1211 ret
= iwl_mvm_sched_scan_start(mvm
, vif
, nd_config
, &mvm
->nd_ies
,
1212 IWL_MVM_SCAN_NETDETECT
);
1216 if (WARN_ON(mvm
->nd_match_sets
|| mvm
->nd_channels
))
1219 /* save the sched scan matchsets... */
1220 if (nd_config
->n_match_sets
) {
1221 mvm
->nd_match_sets
= kmemdup(nd_config
->match_sets
,
1222 sizeof(*nd_config
->match_sets
) *
1223 nd_config
->n_match_sets
,
1225 if (mvm
->nd_match_sets
)
1226 mvm
->n_nd_match_sets
= nd_config
->n_match_sets
;
1229 /* ...and the sched scan channels for later reporting */
1230 mvm
->nd_channels
= kmemdup(nd_config
->channels
,
1231 sizeof(*nd_config
->channels
) *
1232 nd_config
->n_channels
,
1234 if (mvm
->nd_channels
)
1235 mvm
->n_nd_channels
= nd_config
->n_channels
;
1240 static void iwl_mvm_free_nd(struct iwl_mvm
*mvm
)
1242 kfree(mvm
->nd_match_sets
);
1243 mvm
->nd_match_sets
= NULL
;
1244 mvm
->n_nd_match_sets
= 0;
1245 kfree(mvm
->nd_channels
);
1246 mvm
->nd_channels
= NULL
;
1247 mvm
->n_nd_channels
= 0;
1250 static int __iwl_mvm_suspend(struct ieee80211_hw
*hw
,
1251 struct cfg80211_wowlan
*wowlan
,
1254 struct iwl_mvm
*mvm
= IWL_MAC80211_GET_MVM(hw
);
1255 struct ieee80211_vif
*vif
= NULL
;
1256 struct iwl_mvm_vif
*mvmvif
= NULL
;
1257 struct ieee80211_sta
*ap_sta
= NULL
;
1258 struct iwl_mvm_vif_link_info
*mvm_link
;
1259 struct iwl_d3_manager_config d3_cfg_cmd_data
= {
1261 * Program the minimum sleep time to 10 seconds, as many
1262 * platforms have issues processing a wakeup signal while
1263 * still being in the process of suspending.
1265 .min_sleep_time
= cpu_to_le32(10 * 1000 * 1000),
1267 struct iwl_host_cmd d3_cfg_cmd
= {
1268 .id
= D3_CONFIG_CMD
,
1269 .flags
= CMD_WANT_SKB
| CMD_SEND_IN_D3
,
1270 .data
[0] = &d3_cfg_cmd_data
,
1271 .len
[0] = sizeof(d3_cfg_cmd_data
),
1274 int len __maybe_unused
;
1275 bool unified_image
= fw_has_capa(&mvm
->fw
->ucode_capa
,
1276 IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG
);
1280 * mac80211 shouldn't get here, but for D3 test
1281 * it doesn't warrant a warning
1287 vif
= iwl_mvm_get_bss_vif(mvm
);
1288 if (IS_ERR_OR_NULL(vif
))
1291 ret
= iwl_mvm_block_esr_sync(mvm
, vif
, IWL_MVM_ESR_BLOCKED_WOWLAN
);
1295 mutex_lock(&mvm
->mutex
);
1297 set_bit(IWL_MVM_STATUS_IN_D3
, &mvm
->status
);
1301 mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
1303 mvm_link
= mvmvif
->link
[iwl_mvm_get_primary_link(vif
)];
1304 if (WARN_ON_ONCE(!mvm_link
)) {
1309 if (mvm_link
->ap_sta_id
== IWL_INVALID_STA
) {
1310 /* if we're not associated, this must be netdetect */
1311 if (!wowlan
->nd_config
) {
1316 ret
= iwl_mvm_netdetect_config(
1317 mvm
, wowlan
, wowlan
->nd_config
, vif
);
1321 mvm
->net_detect
= true;
1323 struct iwl_wowlan_config_cmd_v6 wowlan_config_cmd
= {
1324 .offloading_tid
= 0,
1327 wowlan_config_cmd
.sta_id
= mvm_link
->ap_sta_id
;
1329 ap_sta
= rcu_dereference_protected(
1330 mvm
->fw_id_to_mac_id
[mvm_link
->ap_sta_id
],
1331 lockdep_is_held(&mvm
->mutex
));
1332 if (IS_ERR_OR_NULL(ap_sta
)) {
1337 ret
= iwl_mvm_sta_ensure_queue(
1338 mvm
, ap_sta
->txq
[wowlan_config_cmd
.offloading_tid
]);
1342 ret
= iwl_mvm_get_wowlan_config(mvm
, wowlan
, &wowlan_config_cmd
,
1343 vif
, mvmvif
, ap_sta
);
1346 ret
= iwl_mvm_wowlan_config(mvm
, wowlan
, &wowlan_config_cmd
,
1347 vif
, mvmvif
, mvm_link
, ap_sta
);
1351 mvm
->net_detect
= false;
1354 ret
= iwl_mvm_power_update_device(mvm
);
1358 ret
= iwl_mvm_power_update_mac(mvm
);
1362 #ifdef CONFIG_IWLWIFI_DEBUGFS
1363 if (mvm
->d3_wake_sysassert
)
1364 d3_cfg_cmd_data
.wakeup_flags
|=
1365 cpu_to_le32(IWL_WAKEUP_D3_CONFIG_FW_ERROR
);
1369 * Prior to 9000 device family the driver needs to stop the dbg
1370 * recording before entering D3. In later devices the FW stops the
1371 * recording automatically.
1373 if (mvm
->trans
->trans_cfg
->device_family
< IWL_DEVICE_FAMILY_9000
)
1374 iwl_fw_dbg_stop_restart_recording(&mvm
->fwrt
, NULL
, true);
1376 mvm
->trans
->system_pm_mode
= IWL_PLAT_PM_MODE_D3
;
1378 /* must be last -- this switches firmware state */
1379 ret
= iwl_mvm_send_cmd(mvm
, &d3_cfg_cmd
);
1382 #ifdef CONFIG_IWLWIFI_DEBUGFS
1383 len
= iwl_rx_packet_payload_len(d3_cfg_cmd
.resp_pkt
);
1384 if (len
>= sizeof(u32
)) {
1385 mvm
->d3_test_pme_ptr
=
1386 le32_to_cpup((__le32
*)d3_cfg_cmd
.resp_pkt
->data
);
1389 iwl_free_resp(&d3_cfg_cmd
);
1391 clear_bit(IWL_MVM_STATUS_IN_HW_RESTART
, &mvm
->status
);
1393 ret
= iwl_trans_d3_suspend(mvm
->trans
, test
, !unified_image
);
1396 iwl_mvm_free_nd(mvm
);
1398 if (!unified_image
) {
1399 if (mvm
->fw_restart
> 0) {
1401 ieee80211_restart_hw(mvm
->hw
);
1405 clear_bit(IWL_MVM_STATUS_IN_D3
, &mvm
->status
);
1408 mutex_unlock(&mvm
->mutex
);
1413 int iwl_mvm_suspend(struct ieee80211_hw
*hw
, struct cfg80211_wowlan
*wowlan
)
1415 struct iwl_mvm
*mvm
= IWL_MAC80211_GET_MVM(hw
);
1417 iwl_mvm_pause_tcm(mvm
, true);
1419 mutex_lock(&mvm
->mutex
);
1420 iwl_fw_runtime_suspend(&mvm
->fwrt
);
1421 mutex_unlock(&mvm
->mutex
);
1423 return __iwl_mvm_suspend(hw
, wowlan
, false);
1426 struct iwl_multicast_key_data
{
1427 u8 key
[WOWLAN_KEY_MAX_SIZE
];
1434 /* converted data from the different status responses */
1435 struct iwl_wowlan_status_data
{
1437 u32 num_of_gtk_rekeys
;
1438 u32 received_beacons
;
1440 u32 wake_packet_length
;
1441 u32 wake_packet_bufsize
;
1443 u16 non_qos_seq_ctr
;
1446 u8 tid_offloaded_tx
;
1449 /* including RX MIC key for TKIP */
1450 u8 key
[WOWLAN_KEY_MAX_SIZE
];
1454 } gtk
[WOWLAN_GTK_KEYS_NUM
];
1458 * We store both the TKIP and AES representations
1459 * coming from the firmware because we decode the
1460 * data from there before we iterate the keys and
1461 * know which one we need.
1464 struct ieee80211_key_seq seq
[IWL_MAX_TID_COUNT
];
1468 * We use -1 for when we have valid data but don't know
1469 * the key ID from firmware, and thus it needs to be
1470 * installed with the last key (depending on rekeying).
1479 struct ieee80211_key_seq seq
[IWL_MAX_TID_COUNT
];
1484 struct iwl_multicast_key_data igtk
;
1485 struct iwl_multicast_key_data bigtk
[WOWLAN_BIGTK_KEYS_NUM
];
1488 struct iwl_wowlan_mlo_gtk mlo_keys
[WOWLAN_MAX_MLO_KEYS
];
1493 static void iwl_mvm_report_wakeup_reasons(struct iwl_mvm
*mvm
,
1494 struct ieee80211_vif
*vif
,
1495 struct iwl_wowlan_status_data
*status
)
1497 struct sk_buff
*pkt
= NULL
;
1498 struct cfg80211_wowlan_wakeup wakeup
= {
1501 struct cfg80211_wowlan_wakeup
*wakeup_report
= &wakeup
;
1502 u32 reasons
= status
->wakeup_reasons
;
1504 if (reasons
== IWL_WOWLAN_WAKEUP_BY_NON_WIRELESS
) {
1505 wakeup_report
= NULL
;
1509 pm_wakeup_event(mvm
->dev
, 0);
1511 if (reasons
& IWL_WOWLAN_WAKEUP_BY_MAGIC_PACKET
)
1512 wakeup
.magic_pkt
= true;
1514 if (reasons
& IWL_WOWLAN_WAKEUP_BY_PATTERN
)
1515 wakeup
.pattern_idx
=
1516 status
->pattern_number
;
1518 if (reasons
& (IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_MISSED_BEACON
|
1519 IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_DEAUTH
|
1520 IWL_WOWLAN_WAKEUP_BY_GTK_REKEY_FAILURE
))
1521 wakeup
.disconnect
= true;
1523 if (reasons
& IWL_WOWLAN_WAKEUP_BY_GTK_REKEY_FAILURE
)
1524 wakeup
.gtk_rekey_failure
= true;
1526 if (reasons
& IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED
)
1527 wakeup
.rfkill_release
= true;
1529 if (reasons
& IWL_WOWLAN_WAKEUP_BY_EAPOL_REQUEST
)
1530 wakeup
.eap_identity_req
= true;
1532 if (reasons
& IWL_WOWLAN_WAKEUP_BY_FOUR_WAY_HANDSHAKE
)
1533 wakeup
.four_way_handshake
= true;
1535 if (reasons
& IWL_WOWLAN_WAKEUP_BY_REM_WAKE_LINK_LOSS
)
1536 wakeup
.tcp_connlost
= true;
1538 if (reasons
& IWL_WOWLAN_WAKEUP_BY_REM_WAKE_SIGNATURE_TABLE
)
1539 wakeup
.tcp_nomoretokens
= true;
1541 if (reasons
& IWL_WOWLAN_WAKEUP_BY_REM_WAKE_WAKEUP_PACKET
)
1542 wakeup
.tcp_match
= true;
1544 if (reasons
& IWL_WAKEUP_BY_11W_UNPROTECTED_DEAUTH_OR_DISASSOC
)
1545 wakeup
.unprot_deauth_disassoc
= true;
1547 if (status
->wake_packet
) {
1548 int pktsize
= status
->wake_packet_bufsize
;
1549 int pktlen
= status
->wake_packet_length
;
1550 const u8
*pktdata
= status
->wake_packet
;
1551 const struct ieee80211_hdr
*hdr
= (const void *)pktdata
;
1552 int truncated
= pktlen
- pktsize
;
1554 /* this would be a firmware bug */
1555 if (WARN_ON_ONCE(truncated
< 0))
1558 if (ieee80211_is_data(hdr
->frame_control
)) {
1559 int hdrlen
= ieee80211_hdrlen(hdr
->frame_control
);
1560 int ivlen
= 0, icvlen
= 4; /* also FCS */
1562 pkt
= alloc_skb(pktsize
, GFP_KERNEL
);
1566 skb_put_data(pkt
, pktdata
, hdrlen
);
1570 if (ieee80211_has_protected(hdr
->frame_control
)) {
1572 * This is unlocked and using gtk_i(c)vlen,
1573 * but since everything is under RTNL still
1574 * that's not really a problem - changing
1575 * it would be difficult.
1577 if (is_multicast_ether_addr(hdr
->addr1
)) {
1578 ivlen
= mvm
->gtk_ivlen
;
1579 icvlen
+= mvm
->gtk_icvlen
;
1581 ivlen
= mvm
->ptk_ivlen
;
1582 icvlen
+= mvm
->ptk_icvlen
;
1586 /* if truncated, FCS/ICV is (partially) gone */
1587 if (truncated
>= icvlen
) {
1589 truncated
-= icvlen
;
1591 icvlen
-= truncated
;
1595 pktsize
-= ivlen
+ icvlen
;
1598 skb_put_data(pkt
, pktdata
, pktsize
);
1600 if (ieee80211_data_to_8023(pkt
, vif
->addr
, vif
->type
))
1602 wakeup
.packet
= pkt
->data
;
1603 wakeup
.packet_present_len
= pkt
->len
;
1604 wakeup
.packet_len
= pkt
->len
- truncated
;
1605 wakeup
.packet_80211
= false;
1609 if (truncated
>= 4) {
1613 fcslen
-= truncated
;
1617 wakeup
.packet
= status
->wake_packet
;
1618 wakeup
.packet_present_len
= pktsize
;
1619 wakeup
.packet_len
= pktlen
- truncated
;
1620 wakeup
.packet_80211
= true;
1625 ieee80211_report_wowlan_wakeup(vif
, wakeup_report
, GFP_KERNEL
);
1629 static void iwl_mvm_le64_to_aes_seq(__le64 le_pn
, struct ieee80211_key_seq
*seq
)
1631 u64 pn
= le64_to_cpu(le_pn
);
1633 seq
->ccmp
.pn
[0] = pn
>> 40;
1634 seq
->ccmp
.pn
[1] = pn
>> 32;
1635 seq
->ccmp
.pn
[2] = pn
>> 24;
1636 seq
->ccmp
.pn
[3] = pn
>> 16;
1637 seq
->ccmp
.pn
[4] = pn
>> 8;
1638 seq
->ccmp
.pn
[5] = pn
;
1641 static void iwl_mvm_aes_sc_to_seq(struct aes_sc
*sc
,
1642 struct ieee80211_key_seq
*seq
)
1644 iwl_mvm_le64_to_aes_seq(sc
->pn
, seq
);
1647 static void iwl_mvm_le64_to_tkip_seq(__le64 le_pn
, struct ieee80211_key_seq
*seq
)
1649 u64 pn
= le64_to_cpu(le_pn
);
1651 seq
->tkip
.iv16
= (u16
)pn
;
1652 seq
->tkip
.iv32
= (u32
)(pn
>> 16);
1655 static void iwl_mvm_tkip_sc_to_seq(struct tkip_sc
*sc
,
1656 struct ieee80211_key_seq
*seq
)
1658 seq
->tkip
.iv32
= le32_to_cpu(sc
->iv32
);
1659 seq
->tkip
.iv16
= le16_to_cpu(sc
->iv16
);
1662 static void iwl_mvm_set_key_rx_seq_tids(struct ieee80211_key_conf
*key
,
1663 struct ieee80211_key_seq
*seq
)
1667 for (tid
= 0; tid
< IWL_MAX_TID_COUNT
; tid
++)
1668 ieee80211_set_key_rx_seq(key
, tid
, &seq
[tid
]);
1671 static void iwl_mvm_set_aes_ptk_rx_seq(struct iwl_mvm
*mvm
,
1672 struct iwl_wowlan_status_data
*status
,
1673 struct ieee80211_sta
*sta
,
1674 struct ieee80211_key_conf
*key
)
1676 struct iwl_mvm_sta
*mvmsta
= iwl_mvm_sta_from_mac80211(sta
);
1677 struct iwl_mvm_key_pn
*ptk_pn
;
1680 iwl_mvm_set_key_rx_seq_tids(key
, status
->ptk
.aes
.seq
);
1682 if (!iwl_mvm_has_new_rx_api(mvm
))
1687 ptk_pn
= rcu_dereference(mvmsta
->ptk_pn
[key
->keyidx
]);
1688 if (WARN_ON(!ptk_pn
)) {
1693 for (tid
= 0; tid
< IWL_MAX_TID_COUNT
; tid
++) {
1696 for (i
= 1; i
< mvm
->trans
->num_rx_queues
; i
++)
1697 memcpy(ptk_pn
->q
[i
].pn
[tid
],
1698 status
->ptk
.aes
.seq
[tid
].ccmp
.pn
,
1699 IEEE80211_CCMP_PN_LEN
);
1704 static void iwl_mvm_convert_key_counters(struct iwl_wowlan_status_data
*status
,
1705 union iwl_all_tsc_rsc
*sc
)
1709 BUILD_BUG_ON(IWL_MAX_TID_COUNT
> IWL_MAX_TID_COUNT
);
1710 BUILD_BUG_ON(IWL_MAX_TID_COUNT
> IWL_NUM_RSC
);
1712 /* GTK RX counters */
1713 for (i
= 0; i
< IWL_MAX_TID_COUNT
; i
++) {
1714 iwl_mvm_tkip_sc_to_seq(&sc
->tkip
.multicast_rsc
[i
],
1715 &status
->gtk_seq
[0].tkip
.seq
[i
]);
1716 iwl_mvm_aes_sc_to_seq(&sc
->aes
.multicast_rsc
[i
],
1717 &status
->gtk_seq
[0].aes
.seq
[i
]);
1719 status
->gtk_seq
[0].valid
= true;
1720 status
->gtk_seq
[0].key_id
= -1;
1722 /* PTK TX counter */
1723 status
->ptk
.tkip
.tx_pn
= (u64
)le16_to_cpu(sc
->tkip
.tsc
.iv16
) |
1724 ((u64
)le32_to_cpu(sc
->tkip
.tsc
.iv32
) << 16);
1725 status
->ptk
.aes
.tx_pn
= le64_to_cpu(sc
->aes
.tsc
.pn
);
1727 /* PTK RX counters */
1728 for (i
= 0; i
< IWL_MAX_TID_COUNT
; i
++) {
1729 iwl_mvm_tkip_sc_to_seq(&sc
->tkip
.unicast_rsc
[i
],
1730 &status
->ptk
.tkip
.seq
[i
]);
1731 iwl_mvm_aes_sc_to_seq(&sc
->aes
.unicast_rsc
[i
],
1732 &status
->ptk
.aes
.seq
[i
]);
1737 iwl_mvm_convert_key_counters_v5_gtk_seq(struct iwl_wowlan_status_data
*status
,
1738 struct iwl_wowlan_all_rsc_tsc_v5
*sc
,
1739 unsigned int idx
, unsigned int key_id
)
1743 for (tid
= 0; tid
< IWL_MAX_TID_COUNT
; tid
++) {
1744 iwl_mvm_le64_to_tkip_seq(sc
->mcast_rsc
[idx
][tid
],
1745 &status
->gtk_seq
[idx
].tkip
.seq
[tid
]);
1746 iwl_mvm_le64_to_aes_seq(sc
->mcast_rsc
[idx
][tid
],
1747 &status
->gtk_seq
[idx
].aes
.seq
[tid
]);
1750 status
->gtk_seq
[idx
].valid
= true;
1751 status
->gtk_seq
[idx
].key_id
= key_id
;
1755 iwl_mvm_convert_key_counters_v5(struct iwl_wowlan_status_data
*status
,
1756 struct iwl_wowlan_all_rsc_tsc_v5
*sc
)
1760 BUILD_BUG_ON(IWL_MAX_TID_COUNT
> IWL_MAX_TID_COUNT
);
1761 BUILD_BUG_ON(IWL_MAX_TID_COUNT
> IWL_NUM_RSC
);
1762 BUILD_BUG_ON(ARRAY_SIZE(sc
->mcast_rsc
) != ARRAY_SIZE(status
->gtk_seq
));
1764 /* GTK RX counters */
1765 for (i
= 0; i
< ARRAY_SIZE(sc
->mcast_key_id_map
); i
++) {
1766 u8 entry
= sc
->mcast_key_id_map
[i
];
1768 if (entry
< ARRAY_SIZE(sc
->mcast_rsc
))
1769 iwl_mvm_convert_key_counters_v5_gtk_seq(status
, sc
,
1773 /* PTK TX counters not needed, assigned in device */
1775 /* PTK RX counters */
1776 for (tid
= 0; tid
< IWL_MAX_TID_COUNT
; tid
++) {
1777 iwl_mvm_le64_to_tkip_seq(sc
->ucast_rsc
[tid
],
1778 &status
->ptk
.tkip
.seq
[tid
]);
1779 iwl_mvm_le64_to_aes_seq(sc
->ucast_rsc
[tid
],
1780 &status
->ptk
.aes
.seq
[tid
]);
1784 static void iwl_mvm_set_key_rx_seq_idx(struct ieee80211_key_conf
*key
,
1785 struct iwl_wowlan_status_data
*status
,
1788 switch (key
->cipher
) {
1789 case WLAN_CIPHER_SUITE_CCMP
:
1790 case WLAN_CIPHER_SUITE_GCMP
:
1791 case WLAN_CIPHER_SUITE_GCMP_256
:
1792 iwl_mvm_set_key_rx_seq_tids(key
, status
->gtk_seq
[idx
].aes
.seq
);
1794 case WLAN_CIPHER_SUITE_TKIP
:
1795 iwl_mvm_set_key_rx_seq_tids(key
, status
->gtk_seq
[idx
].tkip
.seq
);
1802 static void iwl_mvm_set_key_rx_seq(struct ieee80211_key_conf
*key
,
1803 struct iwl_wowlan_status_data
*status
,
1808 for (i
= 0; i
< ARRAY_SIZE(status
->gtk_seq
); i
++) {
1809 if (!status
->gtk_seq
[i
].valid
)
1812 /* Handle the case where we know the key ID */
1813 if (status
->gtk_seq
[i
].key_id
== key
->keyidx
) {
1816 if (status
->num_of_gtk_rekeys
)
1817 new_key_id
= status
->gtk
[0].flags
&
1818 IWL_WOWLAN_GTK_IDX_MASK
;
1820 /* Don't install a new key's value to an old key */
1821 if (new_key_id
!= key
->keyidx
)
1822 iwl_mvm_set_key_rx_seq_idx(key
, status
, i
);
1826 /* handle the case where we didn't, last key only */
1827 if (status
->gtk_seq
[i
].key_id
== -1 &&
1828 (!status
->num_of_gtk_rekeys
|| installed
))
1829 iwl_mvm_set_key_rx_seq_idx(key
, status
, i
);
1833 struct iwl_mvm_d3_gtk_iter_data
{
1834 struct iwl_mvm
*mvm
;
1835 struct iwl_wowlan_status_data
*status
;
1836 u32 gtk_cipher
, igtk_cipher
, bigtk_cipher
;
1837 bool unhandled_cipher
, igtk_support
, bigtk_support
;
1841 static void iwl_mvm_d3_find_last_keys(struct ieee80211_hw
*hw
,
1842 struct ieee80211_vif
*vif
,
1843 struct ieee80211_sta
*sta
,
1844 struct ieee80211_key_conf
*key
,
1847 struct iwl_mvm_d3_gtk_iter_data
*data
= _data
;
1848 int link_id
= vif
->active_links
? __ffs(vif
->active_links
) : -1;
1850 if (link_id
>= 0 && key
->link_id
>= 0 && link_id
!= key
->link_id
)
1853 if (data
->unhandled_cipher
)
1856 switch (key
->cipher
) {
1857 case WLAN_CIPHER_SUITE_WEP40
:
1858 case WLAN_CIPHER_SUITE_WEP104
:
1859 /* ignore WEP completely, nothing to do */
1861 case WLAN_CIPHER_SUITE_CCMP
:
1862 case WLAN_CIPHER_SUITE_GCMP
:
1863 case WLAN_CIPHER_SUITE_GCMP_256
:
1864 case WLAN_CIPHER_SUITE_TKIP
:
1865 /* we support these */
1866 data
->gtk_cipher
= key
->cipher
;
1868 case WLAN_CIPHER_SUITE_BIP_GMAC_128
:
1869 case WLAN_CIPHER_SUITE_BIP_GMAC_256
:
1870 case WLAN_CIPHER_SUITE_BIP_CMAC_256
:
1871 case WLAN_CIPHER_SUITE_AES_CMAC
:
1872 /* we support these */
1873 if (data
->igtk_support
&&
1874 (key
->keyidx
== 4 || key
->keyidx
== 5)) {
1875 data
->igtk_cipher
= key
->cipher
;
1876 } else if (data
->bigtk_support
&&
1877 (key
->keyidx
== 6 || key
->keyidx
== 7)) {
1878 data
->bigtk_cipher
= key
->cipher
;
1880 data
->unhandled_cipher
= true;
1885 /* everything else - disconnect from AP */
1886 data
->unhandled_cipher
= true;
1894 iwl_mvm_d3_set_igtk_bigtk_ipn(const struct iwl_multicast_key_data
*key
,
1895 struct ieee80211_key_seq
*seq
, u32 cipher
)
1898 case WLAN_CIPHER_SUITE_BIP_GMAC_128
:
1899 case WLAN_CIPHER_SUITE_BIP_GMAC_256
:
1900 BUILD_BUG_ON(sizeof(seq
->aes_gmac
.pn
) != sizeof(key
->ipn
));
1901 memcpy(seq
->aes_gmac
.pn
, key
->ipn
, sizeof(seq
->aes_gmac
.pn
));
1903 case WLAN_CIPHER_SUITE_BIP_CMAC_256
:
1904 case WLAN_CIPHER_SUITE_AES_CMAC
:
1905 BUILD_BUG_ON(sizeof(seq
->aes_cmac
.pn
) != sizeof(key
->ipn
));
1906 memcpy(seq
->aes_cmac
.pn
, key
->ipn
, sizeof(seq
->aes_cmac
.pn
));
1914 iwl_mvm_d3_update_igtk_bigtk(struct iwl_wowlan_status_data
*status
,
1915 struct ieee80211_key_conf
*key
,
1916 struct iwl_multicast_key_data
*key_data
)
1918 if (status
->num_of_gtk_rekeys
&& key_data
->len
) {
1919 /* remove rekeyed key */
1920 ieee80211_remove_key(key
);
1922 struct ieee80211_key_seq seq
;
1924 iwl_mvm_d3_set_igtk_bigtk_ipn(key_data
,
1927 ieee80211_set_key_rx_seq(key
, 0, &seq
);
1931 static void iwl_mvm_d3_update_keys(struct ieee80211_hw
*hw
,
1932 struct ieee80211_vif
*vif
,
1933 struct ieee80211_sta
*sta
,
1934 struct ieee80211_key_conf
*key
,
1937 struct iwl_mvm_d3_gtk_iter_data
*data
= _data
;
1938 struct iwl_wowlan_status_data
*status
= data
->status
;
1940 int link_id
= vif
->active_links
? __ffs(vif
->active_links
) : -1;
1942 if (link_id
>= 0 && key
->link_id
>= 0 && link_id
!= key
->link_id
)
1945 if (data
->unhandled_cipher
)
1948 switch (key
->cipher
) {
1949 case WLAN_CIPHER_SUITE_WEP40
:
1950 case WLAN_CIPHER_SUITE_WEP104
:
1951 /* ignore WEP completely, nothing to do */
1953 case WLAN_CIPHER_SUITE_CCMP
:
1954 case WLAN_CIPHER_SUITE_GCMP
:
1955 case WLAN_CIPHER_SUITE_GCMP_256
:
1957 atomic64_set(&key
->tx_pn
, status
->ptk
.aes
.tx_pn
);
1958 iwl_mvm_set_aes_ptk_rx_seq(data
->mvm
, status
, sta
, key
);
1962 case WLAN_CIPHER_SUITE_TKIP
:
1964 atomic64_set(&key
->tx_pn
, status
->ptk
.tkip
.tx_pn
);
1965 iwl_mvm_set_key_rx_seq_tids(key
, status
->ptk
.tkip
.seq
);
1968 keyidx
= key
->keyidx
;
1969 /* The current key is always sent by the FW, even if it wasn't
1970 * rekeyed during D3.
1971 * We remove an existing key if it has the same index as
1974 if (status
->num_of_gtk_rekeys
&&
1975 ((status
->gtk
[0].len
&& keyidx
== status
->gtk
[0].id
) ||
1976 (status
->gtk
[1].len
&& keyidx
== status
->gtk
[1].id
))) {
1977 ieee80211_remove_key(key
);
1979 iwl_mvm_set_key_rx_seq(key
, data
->status
, false);
1982 case WLAN_CIPHER_SUITE_BIP_GMAC_128
:
1983 case WLAN_CIPHER_SUITE_BIP_GMAC_256
:
1984 case WLAN_CIPHER_SUITE_BIP_CMAC_256
:
1985 case WLAN_CIPHER_SUITE_AES_CMAC
:
1986 if (key
->keyidx
== 4 || key
->keyidx
== 5) {
1987 iwl_mvm_d3_update_igtk_bigtk(status
, key
,
1990 if (key
->keyidx
== 6 || key
->keyidx
== 7) {
1991 u8 idx
= key
->keyidx
== status
->bigtk
[1].id
;
1993 iwl_mvm_d3_update_igtk_bigtk(status
, key
,
1994 &status
->bigtk
[idx
]);
1999 struct iwl_mvm_d3_mlo_old_keys
{
2000 u32 cipher
[IEEE80211_MLD_MAX_NUM_LINKS
][WOWLAN_MLO_GTK_KEY_NUM_TYPES
];
2001 struct ieee80211_key_conf
*key
[IEEE80211_MLD_MAX_NUM_LINKS
][8];
2004 static void iwl_mvm_mlo_key_ciphers(struct ieee80211_hw
*hw
,
2005 struct ieee80211_vif
*vif
,
2006 struct ieee80211_sta
*sta
,
2007 struct ieee80211_key_conf
*key
,
2010 struct iwl_mvm_d3_mlo_old_keys
*old_keys
= data
;
2011 enum iwl_wowlan_mlo_gtk_type key_type
;
2013 if (key
->link_id
< 0)
2016 if (WARN_ON(key
->link_id
>= IEEE80211_MLD_MAX_NUM_LINKS
||
2020 if (WARN_ON(old_keys
->key
[key
->link_id
][key
->keyidx
]))
2023 switch (key
->cipher
) {
2024 case WLAN_CIPHER_SUITE_CCMP
:
2025 case WLAN_CIPHER_SUITE_GCMP
:
2026 case WLAN_CIPHER_SUITE_GCMP_256
:
2027 key_type
= WOWLAN_MLO_GTK_KEY_TYPE_GTK
;
2029 case WLAN_CIPHER_SUITE_BIP_GMAC_128
:
2030 case WLAN_CIPHER_SUITE_BIP_GMAC_256
:
2031 case WLAN_CIPHER_SUITE_BIP_CMAC_256
:
2032 case WLAN_CIPHER_SUITE_AES_CMAC
:
2033 if (key
->keyidx
== 4 || key
->keyidx
== 5) {
2034 key_type
= WOWLAN_MLO_GTK_KEY_TYPE_IGTK
;
2036 } else if (key
->keyidx
== 6 || key
->keyidx
== 7) {
2037 key_type
= WOWLAN_MLO_GTK_KEY_TYPE_BIGTK
;
2042 /* ignore WEP/TKIP or unknown ciphers */
2046 old_keys
->cipher
[key
->link_id
][key_type
] = key
->cipher
;
2047 old_keys
->key
[key
->link_id
][key
->keyidx
] = key
;
2050 static bool iwl_mvm_mlo_gtk_rekey(struct iwl_wowlan_status_data
*status
,
2051 struct ieee80211_vif
*vif
,
2052 struct iwl_mvm
*mvm
)
2055 struct iwl_mvm_d3_mlo_old_keys
*old_keys
;
2058 IWL_DEBUG_WOWLAN(mvm
, "Num of MLO Keys: %d\n", status
->num_mlo_keys
);
2059 if (!status
->num_mlo_keys
)
2062 old_keys
= kzalloc(sizeof(*old_keys
), GFP_KERNEL
);
2066 /* find the cipher for each mlo key */
2067 ieee80211_iter_keys(mvm
->hw
, vif
, iwl_mvm_mlo_key_ciphers
, old_keys
);
2069 for (i
= 0; i
< status
->num_mlo_keys
; i
++) {
2070 struct iwl_wowlan_mlo_gtk
*mlo_key
= &status
->mlo_keys
[i
];
2071 struct ieee80211_key_conf
*key
, *old_key
;
2072 struct ieee80211_key_seq seq
;
2074 struct ieee80211_key_conf conf
;
2077 u16 flags
= le16_to_cpu(mlo_key
->flags
);
2078 int j
, link_id
, key_id
, key_type
;
2080 link_id
= u16_get_bits(flags
, WOWLAN_MLO_GTK_FLAG_LINK_ID_MSK
);
2081 key_id
= u16_get_bits(flags
, WOWLAN_MLO_GTK_FLAG_KEY_ID_MSK
);
2082 key_type
= u16_get_bits(flags
,
2083 WOWLAN_MLO_GTK_FLAG_KEY_TYPE_MSK
);
2085 if (!(vif
->valid_links
& BIT(link_id
)))
2088 if (WARN_ON(link_id
>= IEEE80211_MLD_MAX_NUM_LINKS
||
2090 key_type
>= WOWLAN_MLO_GTK_KEY_NUM_TYPES
))
2093 conf
.conf
.cipher
= old_keys
->cipher
[link_id
][key_type
];
2095 if (!conf
.conf
.cipher
)
2098 conf
.conf
.keylen
= 0;
2099 switch (conf
.conf
.cipher
) {
2100 case WLAN_CIPHER_SUITE_CCMP
:
2101 case WLAN_CIPHER_SUITE_GCMP
:
2102 conf
.conf
.keylen
= WLAN_KEY_LEN_CCMP
;
2104 case WLAN_CIPHER_SUITE_GCMP_256
:
2105 conf
.conf
.keylen
= WLAN_KEY_LEN_GCMP_256
;
2107 case WLAN_CIPHER_SUITE_BIP_GMAC_128
:
2108 conf
.conf
.keylen
= WLAN_KEY_LEN_BIP_GMAC_128
;
2110 case WLAN_CIPHER_SUITE_BIP_GMAC_256
:
2111 conf
.conf
.keylen
= WLAN_KEY_LEN_BIP_GMAC_256
;
2113 case WLAN_CIPHER_SUITE_AES_CMAC
:
2114 conf
.conf
.keylen
= WLAN_KEY_LEN_AES_CMAC
;
2116 case WLAN_CIPHER_SUITE_BIP_CMAC_256
:
2117 conf
.conf
.keylen
= WLAN_KEY_LEN_BIP_CMAC_256
;
2121 if (WARN_ON(!conf
.conf
.keylen
||
2122 conf
.conf
.keylen
> sizeof(conf
.key
)))
2125 memcpy(conf
.conf
.key
, mlo_key
->key
, conf
.conf
.keylen
);
2126 conf
.conf
.keyidx
= key_id
;
2128 old_key
= old_keys
->key
[link_id
][key_id
];
2130 IWL_DEBUG_WOWLAN(mvm
,
2131 "Remove MLO key id %d, link id %d\n",
2133 ieee80211_remove_key(old_key
);
2136 IWL_DEBUG_WOWLAN(mvm
, "Add MLO key id %d, link id %d\n",
2138 key
= ieee80211_gtk_rekey_add(vif
, &conf
.conf
, link_id
);
2139 if (WARN_ON(IS_ERR(key
))) {
2145 * mac80211 expects the pn in big-endian
2146 * also note that seq is a union of all cipher types
2147 * (ccmp, gcmp, cmac, gmac), and they all have the same
2148 * pn field (of length 6) so just copy it to ccmp.pn.
2150 for (j
= 5; j
>= 0; j
--)
2151 seq
.ccmp
.pn
[5 - j
] = mlo_key
->pn
[j
];
2153 /* group keys are non-QoS and use TID 0 */
2154 ieee80211_set_key_rx_seq(key
, 0, &seq
);
2162 static bool iwl_mvm_gtk_rekey(struct iwl_wowlan_status_data
*status
,
2163 struct ieee80211_vif
*vif
,
2164 struct iwl_mvm
*mvm
, u32 gtk_cipher
)
2167 struct ieee80211_key_conf
*key
;
2169 struct ieee80211_key_conf conf
;
2172 .conf
.cipher
= gtk_cipher
,
2174 int link_id
= vif
->active_links
? __ffs(vif
->active_links
) : -1;
2176 BUILD_BUG_ON(WLAN_KEY_LEN_CCMP
!= WLAN_KEY_LEN_GCMP
);
2177 BUILD_BUG_ON(sizeof(conf
.key
) < WLAN_KEY_LEN_CCMP
);
2178 BUILD_BUG_ON(sizeof(conf
.key
) < WLAN_KEY_LEN_GCMP_256
);
2179 BUILD_BUG_ON(sizeof(conf
.key
) < WLAN_KEY_LEN_TKIP
);
2180 BUILD_BUG_ON(sizeof(conf
.key
) < sizeof(status
->gtk
[0].key
));
2182 switch (gtk_cipher
) {
2183 case WLAN_CIPHER_SUITE_CCMP
:
2184 case WLAN_CIPHER_SUITE_GCMP
:
2185 conf
.conf
.keylen
= WLAN_KEY_LEN_CCMP
;
2187 case WLAN_CIPHER_SUITE_GCMP_256
:
2188 conf
.conf
.keylen
= WLAN_KEY_LEN_GCMP_256
;
2190 case WLAN_CIPHER_SUITE_TKIP
:
2191 conf
.conf
.keylen
= WLAN_KEY_LEN_TKIP
;
2197 for (i
= 0; i
< ARRAY_SIZE(status
->gtk
); i
++) {
2198 if (!status
->gtk
[i
].len
)
2201 conf
.conf
.keyidx
= status
->gtk
[i
].id
;
2202 IWL_DEBUG_WOWLAN(mvm
,
2203 "Received from FW GTK cipher %d, key index %d\n",
2204 conf
.conf
.cipher
, conf
.conf
.keyidx
);
2205 memcpy(conf
.conf
.key
, status
->gtk
[i
].key
,
2206 sizeof(status
->gtk
[i
].key
));
2208 key
= ieee80211_gtk_rekey_add(vif
, &conf
.conf
, link_id
);
2212 for (j
= 0; j
< ARRAY_SIZE(status
->gtk_seq
); j
++) {
2213 if (!status
->gtk_seq
[j
].valid
||
2214 status
->gtk_seq
[j
].key_id
!= key
->keyidx
)
2216 iwl_mvm_set_key_rx_seq_idx(key
, status
, j
);
2219 WARN_ON(j
== ARRAY_SIZE(status
->gtk_seq
));
2226 iwl_mvm_d3_igtk_bigtk_rekey_add(struct iwl_wowlan_status_data
*status
,
2227 struct ieee80211_vif
*vif
, u32 cipher
,
2228 struct iwl_multicast_key_data
*key_data
)
2230 struct ieee80211_key_conf
*key_config
;
2232 struct ieee80211_key_conf conf
;
2233 u8 key
[WOWLAN_KEY_MAX_SIZE
];
2235 .conf
.cipher
= cipher
,
2236 .conf
.keyidx
= key_data
->id
,
2238 struct ieee80211_key_seq seq
;
2239 int link_id
= vif
->active_links
? __ffs(vif
->active_links
) : -1;
2244 iwl_mvm_d3_set_igtk_bigtk_ipn(key_data
, &seq
, conf
.conf
.cipher
);
2247 case WLAN_CIPHER_SUITE_BIP_GMAC_128
:
2248 conf
.conf
.keylen
= WLAN_KEY_LEN_BIP_GMAC_128
;
2250 case WLAN_CIPHER_SUITE_BIP_GMAC_256
:
2251 conf
.conf
.keylen
= WLAN_KEY_LEN_BIP_GMAC_256
;
2253 case WLAN_CIPHER_SUITE_AES_CMAC
:
2254 conf
.conf
.keylen
= WLAN_KEY_LEN_AES_CMAC
;
2256 case WLAN_CIPHER_SUITE_BIP_CMAC_256
:
2257 conf
.conf
.keylen
= WLAN_KEY_LEN_BIP_CMAC_256
;
2262 BUILD_BUG_ON(sizeof(conf
.key
) < sizeof(key_data
->key
));
2263 memcpy(conf
.conf
.key
, key_data
->key
, conf
.conf
.keylen
);
2265 key_config
= ieee80211_gtk_rekey_add(vif
, &conf
.conf
, link_id
);
2266 if (IS_ERR(key_config
))
2268 ieee80211_set_key_rx_seq(key_config
, 0, &seq
);
2270 if (key_config
->keyidx
== 4 || key_config
->keyidx
== 5) {
2271 struct iwl_mvm_vif
*mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
2272 struct iwl_mvm_vif_link_info
*mvm_link
;
2274 link_id
= link_id
< 0 ? 0 : link_id
;
2275 mvm_link
= mvmvif
->link
[link_id
];
2276 mvm_link
->igtk
= key_config
;
2282 static int iwl_mvm_lookup_wowlan_status_ver(struct iwl_mvm
*mvm
)
2286 if (!fw_has_api(&mvm
->fw
->ucode_capa
,
2287 IWL_UCODE_TLV_API_WOWLAN_KEY_MATERIAL
))
2290 /* default to 7 (when we have IWL_UCODE_TLV_API_WOWLAN_KEY_MATERIAL) */
2291 notif_ver
= iwl_fw_lookup_notif_ver(mvm
->fw
, LONG_GROUP
,
2292 WOWLAN_GET_STATUSES
, 0);
2294 notif_ver
= iwl_fw_lookup_notif_ver(mvm
->fw
, LEGACY_GROUP
,
2295 WOWLAN_GET_STATUSES
, 7);
2300 static bool iwl_mvm_setup_connection_keep(struct iwl_mvm
*mvm
,
2301 struct ieee80211_vif
*vif
,
2302 struct iwl_wowlan_status_data
*status
)
2304 struct iwl_mvm_vif
*mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
2305 struct iwl_mvm_d3_gtk_iter_data gtkdata
= {
2310 u32 disconnection_reasons
=
2311 IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_MISSED_BEACON
|
2312 IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_DEAUTH
;
2314 if (!status
|| !vif
->bss_conf
.bssid
)
2317 if (iwl_mvm_lookup_wowlan_status_ver(mvm
) > 6 ||
2318 iwl_fw_lookup_notif_ver(mvm
->fw
, PROT_OFFLOAD_GROUP
,
2319 WOWLAN_INFO_NOTIFICATION
,
2321 gtkdata
.igtk_support
= true;
2323 if (iwl_fw_lookup_notif_ver(mvm
->fw
, PROT_OFFLOAD_GROUP
,
2324 WOWLAN_INFO_NOTIFICATION
,
2326 gtkdata
.bigtk_support
= true;
2328 /* find last GTK that we used initially, if any */
2329 ieee80211_iter_keys(mvm
->hw
, vif
,
2330 iwl_mvm_d3_find_last_keys
, >kdata
);
2331 /* not trying to keep connections with MFP/unhandled ciphers */
2332 if (gtkdata
.unhandled_cipher
)
2334 if (!gtkdata
.num_keys
)
2338 * invalidate all other GTKs that might still exist and update
2339 * the one that we used
2341 ieee80211_iter_keys(mvm
->hw
, vif
,
2342 iwl_mvm_d3_update_keys
, >kdata
);
2344 if (status
->num_of_gtk_rekeys
) {
2345 __be64 replay_ctr
= cpu_to_be64(status
->replay_ctr
);
2347 IWL_DEBUG_WOWLAN(mvm
, "num of GTK rekeying %d\n",
2348 status
->num_of_gtk_rekeys
);
2350 if (!iwl_mvm_gtk_rekey(status
, vif
, mvm
, gtkdata
.gtk_cipher
))
2353 if (!iwl_mvm_d3_igtk_bigtk_rekey_add(status
, vif
,
2354 gtkdata
.igtk_cipher
,
2358 for (i
= 0; i
< ARRAY_SIZE(status
->bigtk
); i
++) {
2359 if (!iwl_mvm_d3_igtk_bigtk_rekey_add(status
, vif
,
2360 gtkdata
.bigtk_cipher
,
2365 if (!iwl_mvm_mlo_gtk_rekey(status
, vif
, mvm
))
2368 ieee80211_gtk_rekey_notify(vif
, vif
->bss_conf
.bssid
,
2369 (void *)&replay_ctr
, GFP_KERNEL
);
2373 if (iwl_fw_lookup_notif_ver(mvm
->fw
, LONG_GROUP
,
2374 WOWLAN_GET_STATUSES
,
2375 IWL_FW_CMD_VER_UNKNOWN
) < 10) {
2376 mvmvif
->seqno_valid
= true;
2377 /* +0x10 because the set API expects next-to-use, not last-used */
2378 mvmvif
->seqno
= status
->non_qos_seq_ctr
+ 0x10;
2381 if (status
->wakeup_reasons
& disconnection_reasons
)
2387 static void iwl_mvm_convert_gtk_v2(struct iwl_wowlan_status_data
*status
,
2388 struct iwl_wowlan_gtk_status_v2
*data
)
2390 BUILD_BUG_ON(sizeof(status
->gtk
[0].key
) < sizeof(data
->key
));
2391 BUILD_BUG_ON(NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY
+
2392 sizeof(data
->tkip_mic_key
) >
2393 sizeof(status
->gtk
[0].key
));
2395 status
->gtk
[0].len
= data
->key_len
;
2396 status
->gtk
[0].flags
= data
->key_flags
;
2398 memcpy(status
->gtk
[0].key
, data
->key
, sizeof(data
->key
));
2400 /* if it's as long as the TKIP encryption key, copy MIC key */
2401 if (status
->gtk
[0].len
== NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY
)
2402 memcpy(status
->gtk
[0].key
+ NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY
,
2403 data
->tkip_mic_key
, sizeof(data
->tkip_mic_key
));
2406 static void iwl_mvm_convert_gtk_v3(struct iwl_wowlan_status_data
*status
,
2407 struct iwl_wowlan_gtk_status_v3
*data
)
2409 int data_idx
, status_idx
= 0;
2411 BUILD_BUG_ON(sizeof(status
->gtk
[0].key
) < sizeof(data
[0].key
));
2412 BUILD_BUG_ON(NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY
+
2413 sizeof(data
[0].tkip_mic_key
) >
2414 sizeof(status
->gtk
[0].key
));
2415 BUILD_BUG_ON(ARRAY_SIZE(status
->gtk
) < WOWLAN_GTK_KEYS_NUM
);
2416 for (data_idx
= 0; data_idx
< ARRAY_SIZE(status
->gtk
); data_idx
++) {
2417 if (!(data
[data_idx
].key_len
))
2419 status
->gtk
[status_idx
].len
= data
[data_idx
].key_len
;
2420 status
->gtk
[status_idx
].flags
= data
[data_idx
].key_flags
;
2421 status
->gtk
[status_idx
].id
= status
->gtk
[status_idx
].flags
&
2422 IWL_WOWLAN_GTK_IDX_MASK
;
2424 memcpy(status
->gtk
[status_idx
].key
, data
[data_idx
].key
,
2425 sizeof(data
[data_idx
].key
));
2427 /* if it's as long as the TKIP encryption key, copy MIC key */
2428 if (status
->gtk
[status_idx
].len
==
2429 NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY
)
2430 memcpy(status
->gtk
[status_idx
].key
+
2431 NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY
,
2432 data
[data_idx
].tkip_mic_key
,
2433 sizeof(data
[data_idx
].tkip_mic_key
));
2438 static void iwl_mvm_convert_igtk(struct iwl_wowlan_status_data
*status
,
2439 struct iwl_wowlan_igtk_status
*data
)
2443 BUILD_BUG_ON(sizeof(status
->igtk
.key
) < sizeof(data
->key
));
2444 BUILD_BUG_ON(sizeof(status
->igtk
.ipn
) != sizeof(data
->ipn
));
2449 status
->igtk
.len
= data
->key_len
;
2450 status
->igtk
.flags
= data
->key_flags
;
2451 status
->igtk
.id
= u32_get_bits(data
->key_flags
,
2452 IWL_WOWLAN_IGTK_BIGTK_IDX_MASK
)
2453 + WOWLAN_IGTK_MIN_INDEX
;
2455 memcpy(status
->igtk
.key
, data
->key
, sizeof(data
->key
));
2457 /* mac80211 expects big endian for memcmp() to work, convert */
2458 for (i
= 0; i
< sizeof(data
->ipn
); i
++)
2459 status
->igtk
.ipn
[i
] = data
->ipn
[sizeof(data
->ipn
) - i
- 1];
2462 static void iwl_mvm_convert_bigtk(struct iwl_wowlan_status_data
*status
,
2463 const struct iwl_wowlan_igtk_status
*data
)
2465 int data_idx
, status_idx
= 0;
2467 BUILD_BUG_ON(ARRAY_SIZE(status
->bigtk
) < WOWLAN_BIGTK_KEYS_NUM
);
2469 for (data_idx
= 0; data_idx
< WOWLAN_BIGTK_KEYS_NUM
; data_idx
++) {
2470 if (!data
[data_idx
].key_len
)
2473 status
->bigtk
[status_idx
].len
= data
[data_idx
].key_len
;
2474 status
->bigtk
[status_idx
].flags
= data
[data_idx
].key_flags
;
2475 status
->bigtk
[status_idx
].id
=
2476 u32_get_bits(data
[data_idx
].key_flags
,
2477 IWL_WOWLAN_IGTK_BIGTK_IDX_MASK
)
2478 + WOWLAN_BIGTK_MIN_INDEX
;
2480 BUILD_BUG_ON(sizeof(status
->bigtk
[status_idx
].key
) <
2481 sizeof(data
[data_idx
].key
));
2482 BUILD_BUG_ON(sizeof(status
->bigtk
[status_idx
].ipn
) <
2483 sizeof(data
[data_idx
].ipn
));
2485 memcpy(status
->bigtk
[status_idx
].key
, data
[data_idx
].key
,
2486 sizeof(data
[data_idx
].key
));
2487 memcpy(status
->bigtk
[status_idx
].ipn
, data
[data_idx
].ipn
,
2488 sizeof(data
[data_idx
].ipn
));
2493 static void iwl_mvm_parse_wowlan_info_notif(struct iwl_mvm
*mvm
,
2494 struct iwl_wowlan_info_notif
*data
,
2495 struct iwl_wowlan_status_data
*status
,
2498 u32 expected_len
= sizeof(*data
) +
2499 data
->num_mlo_link_keys
* sizeof(status
->mlo_keys
[0]);
2502 IWL_ERR(mvm
, "iwl_wowlan_info_notif data is NULL\n");
2507 if (len
< expected_len
) {
2508 IWL_ERR(mvm
, "Invalid WoWLAN info notification!\n");
2513 if (mvm
->fast_resume
)
2516 iwl_mvm_convert_key_counters_v5(status
, &data
->gtk
[0].sc
);
2517 iwl_mvm_convert_gtk_v3(status
, data
->gtk
);
2518 iwl_mvm_convert_igtk(status
, &data
->igtk
[0]);
2519 iwl_mvm_convert_bigtk(status
, data
->bigtk
);
2520 status
->replay_ctr
= le64_to_cpu(data
->replay_ctr
);
2521 status
->pattern_number
= le16_to_cpu(data
->pattern_number
);
2522 status
->tid_offloaded_tx
= data
->tid_offloaded_tx
;
2523 if (IWL_FW_CHECK(mvm
,
2524 data
->tid_offloaded_tx
>=
2525 ARRAY_SIZE(status
->qos_seq_ctr
),
2526 "tid_offloaded_tx is out of bound %d\n",
2527 data
->tid_offloaded_tx
))
2528 data
->tid_offloaded_tx
= 0;
2529 status
->qos_seq_ctr
[data
->tid_offloaded_tx
] =
2530 le16_to_cpu(data
->qos_seq_ctr
);
2531 status
->wakeup_reasons
= le32_to_cpu(data
->wakeup_reasons
);
2532 status
->num_of_gtk_rekeys
=
2533 le32_to_cpu(data
->num_of_gtk_rekeys
);
2534 status
->received_beacons
= le32_to_cpu(data
->received_beacons
);
2535 status
->tid_tear_down
= data
->tid_tear_down
;
2537 if (data
->num_mlo_link_keys
) {
2538 status
->num_mlo_keys
= data
->num_mlo_link_keys
;
2539 if (IWL_FW_CHECK(mvm
,
2540 status
->num_mlo_keys
> WOWLAN_MAX_MLO_KEYS
,
2541 "Too many mlo keys: %d, max %d\n",
2542 status
->num_mlo_keys
, WOWLAN_MAX_MLO_KEYS
))
2543 status
->num_mlo_keys
= WOWLAN_MAX_MLO_KEYS
;
2544 memcpy(status
->mlo_keys
, data
->mlo_gtks
,
2545 status
->num_mlo_keys
* sizeof(status
->mlo_keys
[0]));
2550 iwl_mvm_parse_wowlan_info_notif_v4(struct iwl_mvm
*mvm
,
2551 struct iwl_wowlan_info_notif_v4
*data
,
2552 struct iwl_wowlan_status_data
*status
,
2553 u32 len
, bool has_mlo_keys
)
2556 u32 expected_len
= sizeof(*data
);
2559 IWL_ERR(mvm
, "iwl_wowlan_info_notif data is NULL\n");
2565 expected_len
+= (data
->num_mlo_link_keys
*
2566 sizeof(status
->mlo_keys
[0]));
2568 if (len
< expected_len
) {
2569 IWL_ERR(mvm
, "Invalid WoWLAN info notification!\n");
2574 if (mvm
->fast_resume
)
2577 iwl_mvm_convert_key_counters_v5(status
, &data
->gtk
[0].sc
);
2578 iwl_mvm_convert_gtk_v3(status
, data
->gtk
);
2579 iwl_mvm_convert_igtk(status
, &data
->igtk
[0]);
2580 iwl_mvm_convert_bigtk(status
, data
->bigtk
);
2581 status
->replay_ctr
= le64_to_cpu(data
->replay_ctr
);
2582 status
->pattern_number
= le16_to_cpu(data
->pattern_number
);
2583 for (i
= 0; i
< IWL_MAX_TID_COUNT
; i
++)
2584 status
->qos_seq_ctr
[i
] =
2585 le16_to_cpu(data
->qos_seq_ctr
[i
]);
2586 status
->wakeup_reasons
= le32_to_cpu(data
->wakeup_reasons
);
2587 status
->num_of_gtk_rekeys
=
2588 le32_to_cpu(data
->num_of_gtk_rekeys
);
2589 status
->received_beacons
= le32_to_cpu(data
->received_beacons
);
2590 status
->tid_tear_down
= data
->tid_tear_down
;
2592 if (has_mlo_keys
&& data
->num_mlo_link_keys
) {
2593 status
->num_mlo_keys
= data
->num_mlo_link_keys
;
2594 if (IWL_FW_CHECK(mvm
,
2595 status
->num_mlo_keys
> WOWLAN_MAX_MLO_KEYS
,
2596 "Too many mlo keys: %d, max %d\n",
2597 status
->num_mlo_keys
, WOWLAN_MAX_MLO_KEYS
))
2598 status
->num_mlo_keys
= WOWLAN_MAX_MLO_KEYS
;
2599 memcpy(status
->mlo_keys
, data
->mlo_gtks
,
2600 status
->num_mlo_keys
* sizeof(status
->mlo_keys
[0]));
2605 iwl_mvm_parse_wowlan_info_notif_v2(struct iwl_mvm
*mvm
,
2606 struct iwl_wowlan_info_notif_v2
*data
,
2607 struct iwl_wowlan_status_data
*status
,
2613 IWL_ERR(mvm
, "iwl_wowlan_info_notif data is NULL\n");
2618 if (len
< sizeof(*data
)) {
2619 IWL_ERR(mvm
, "Invalid WoWLAN info notification!\n");
2624 iwl_mvm_convert_key_counters_v5(status
, &data
->gtk
[0].sc
);
2625 iwl_mvm_convert_gtk_v3(status
, data
->gtk
);
2626 iwl_mvm_convert_igtk(status
, &data
->igtk
[0]);
2627 status
->replay_ctr
= le64_to_cpu(data
->replay_ctr
);
2628 status
->pattern_number
= le16_to_cpu(data
->pattern_number
);
2629 for (i
= 0; i
< IWL_MAX_TID_COUNT
; i
++)
2630 status
->qos_seq_ctr
[i
] =
2631 le16_to_cpu(data
->qos_seq_ctr
[i
]);
2632 status
->wakeup_reasons
= le32_to_cpu(data
->wakeup_reasons
);
2633 status
->num_of_gtk_rekeys
=
2634 le32_to_cpu(data
->num_of_gtk_rekeys
);
2635 status
->received_beacons
= le32_to_cpu(data
->received_beacons
);
2636 status
->tid_tear_down
= data
->tid_tear_down
;
2639 /* Occasionally, templates would be nice. This is one of those times ... */
2640 #define iwl_mvm_parse_wowlan_status_common(_ver) \
2641 static struct iwl_wowlan_status_data * \
2642 iwl_mvm_parse_wowlan_status_common_ ## _ver(struct iwl_mvm *mvm, \
2643 struct iwl_wowlan_status_ ##_ver *data,\
2646 struct iwl_wowlan_status_data *status; \
2649 if (len < sizeof(*data)) { \
2650 IWL_ERR(mvm, "Invalid WoWLAN status response!\n"); \
2654 data_size = ALIGN(le32_to_cpu(data->wake_packet_bufsize), 4); \
2655 if (len != sizeof(*data) + data_size) { \
2656 IWL_ERR(mvm, "Invalid WoWLAN status response!\n"); \
2660 status = kzalloc(sizeof(*status), GFP_KERNEL); \
2664 /* copy all the common fields */ \
2665 status->replay_ctr = le64_to_cpu(data->replay_ctr); \
2666 status->pattern_number = le16_to_cpu(data->pattern_number); \
2667 status->non_qos_seq_ctr = le16_to_cpu(data->non_qos_seq_ctr); \
2668 for (i = 0; i < 8; i++) \
2669 status->qos_seq_ctr[i] = \
2670 le16_to_cpu(data->qos_seq_ctr[i]); \
2671 status->wakeup_reasons = le32_to_cpu(data->wakeup_reasons); \
2672 status->num_of_gtk_rekeys = \
2673 le32_to_cpu(data->num_of_gtk_rekeys); \
2674 status->received_beacons = le32_to_cpu(data->received_beacons); \
2675 status->wake_packet_length = \
2676 le32_to_cpu(data->wake_packet_length); \
2677 status->wake_packet_bufsize = \
2678 le32_to_cpu(data->wake_packet_bufsize); \
2679 if (status->wake_packet_bufsize) { \
2680 status->wake_packet = \
2681 kmemdup(data->wake_packet, \
2682 status->wake_packet_bufsize, \
2684 if (!status->wake_packet) { \
2689 status->wake_packet = NULL; \
2695 iwl_mvm_parse_wowlan_status_common(v6
)
2696 iwl_mvm_parse_wowlan_status_common(v7
)
2697 iwl_mvm_parse_wowlan_status_common(v9
)
2698 iwl_mvm_parse_wowlan_status_common(v12
)
2700 static struct iwl_wowlan_status_data
*
2701 iwl_mvm_send_wowlan_get_status(struct iwl_mvm
*mvm
, u8 sta_id
)
2703 struct iwl_wowlan_status_data
*status
;
2704 struct iwl_wowlan_get_status_cmd get_status_cmd
= {
2705 .sta_id
= cpu_to_le32(sta_id
),
2707 struct iwl_host_cmd cmd
= {
2708 .id
= WOWLAN_GET_STATUSES
,
2709 .flags
= CMD_WANT_SKB
,
2710 .data
= { &get_status_cmd
, },
2711 .len
= { sizeof(get_status_cmd
), },
2715 u8 cmd_ver
= iwl_fw_lookup_cmd_ver(mvm
->fw
, cmd
.id
,
2716 IWL_FW_CMD_VER_UNKNOWN
);
2718 if (cmd_ver
== IWL_FW_CMD_VER_UNKNOWN
)
2721 lockdep_assert_held(&mvm
->mutex
);
2723 ret
= iwl_mvm_send_cmd(mvm
, &cmd
);
2725 IWL_ERR(mvm
, "failed to query wakeup status (%d)\n", ret
);
2726 return ERR_PTR(ret
);
2729 len
= iwl_rx_packet_payload_len(cmd
.resp_pkt
);
2731 /* default to 7 (when we have IWL_UCODE_TLV_API_WOWLAN_KEY_MATERIAL) */
2732 notif_ver
= iwl_mvm_lookup_wowlan_status_ver(mvm
);
2734 if (notif_ver
< 7) {
2735 struct iwl_wowlan_status_v6
*v6
= (void *)cmd
.resp_pkt
->data
;
2737 status
= iwl_mvm_parse_wowlan_status_common_v6(mvm
, v6
, len
);
2741 BUILD_BUG_ON(sizeof(v6
->gtk
.decrypt_key
) >
2742 sizeof(status
->gtk
[0].key
));
2743 BUILD_BUG_ON(NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY
+
2744 sizeof(v6
->gtk
.tkip_mic_key
) >
2745 sizeof(status
->gtk
[0].key
));
2747 /* copy GTK info to the right place */
2748 memcpy(status
->gtk
[0].key
, v6
->gtk
.decrypt_key
,
2749 sizeof(v6
->gtk
.decrypt_key
));
2750 memcpy(status
->gtk
[0].key
+ NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY
,
2751 v6
->gtk
.tkip_mic_key
,
2752 sizeof(v6
->gtk
.tkip_mic_key
));
2754 iwl_mvm_convert_key_counters(status
, &v6
->gtk
.rsc
.all_tsc_rsc
);
2756 /* hardcode the key length to 16 since v6 only supports 16 */
2757 status
->gtk
[0].len
= 16;
2760 * The key index only uses 2 bits (values 0 to 3) and
2761 * we always set bit 7 which means this is the
2762 * currently used key.
2764 status
->gtk
[0].flags
= v6
->gtk
.key_index
| BIT(7);
2765 } else if (notif_ver
== 7) {
2766 struct iwl_wowlan_status_v7
*v7
= (void *)cmd
.resp_pkt
->data
;
2768 status
= iwl_mvm_parse_wowlan_status_common_v7(mvm
, v7
, len
);
2772 iwl_mvm_convert_key_counters(status
, &v7
->gtk
[0].rsc
.all_tsc_rsc
);
2773 iwl_mvm_convert_gtk_v2(status
, &v7
->gtk
[0]);
2774 iwl_mvm_convert_igtk(status
, &v7
->igtk
[0]);
2775 } else if (notif_ver
== 9 || notif_ver
== 10 || notif_ver
== 11) {
2776 struct iwl_wowlan_status_v9
*v9
= (void *)cmd
.resp_pkt
->data
;
2778 /* these three command versions have same layout and size, the
2779 * difference is only in a few not used (reserved) fields.
2781 status
= iwl_mvm_parse_wowlan_status_common_v9(mvm
, v9
, len
);
2785 iwl_mvm_convert_key_counters(status
, &v9
->gtk
[0].rsc
.all_tsc_rsc
);
2786 iwl_mvm_convert_gtk_v2(status
, &v9
->gtk
[0]);
2787 iwl_mvm_convert_igtk(status
, &v9
->igtk
[0]);
2789 status
->tid_tear_down
= v9
->tid_tear_down
;
2790 } else if (notif_ver
== 12) {
2791 struct iwl_wowlan_status_v12
*v12
= (void *)cmd
.resp_pkt
->data
;
2793 status
= iwl_mvm_parse_wowlan_status_common_v12(mvm
, v12
, len
);
2797 iwl_mvm_convert_key_counters_v5(status
, &v12
->gtk
[0].sc
);
2798 iwl_mvm_convert_gtk_v3(status
, v12
->gtk
);
2799 iwl_mvm_convert_igtk(status
, &v12
->igtk
[0]);
2801 status
->tid_tear_down
= v12
->tid_tear_down
;
2804 "Firmware advertises unknown WoWLAN status response %d!\n",
2810 iwl_free_resp(&cmd
);
2814 /* releases the MVM mutex */
2815 static bool iwl_mvm_query_wakeup_reasons(struct iwl_mvm
*mvm
,
2816 struct ieee80211_vif
*vif
,
2817 struct iwl_wowlan_status_data
*status
)
2821 struct iwl_mvm_sta
*mvm_ap_sta
;
2822 struct iwl_mvm_vif
*mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
2823 int link_id
= vif
->active_links
? __ffs(vif
->active_links
) : 0;
2824 struct iwl_mvm_vif_link_info
*mvm_link
= mvmvif
->link
[link_id
];
2825 int wowlan_info_ver
= iwl_fw_lookup_notif_ver(mvm
->fw
,
2827 WOWLAN_INFO_NOTIFICATION
,
2828 IWL_FW_CMD_VER_UNKNOWN
);
2830 if (WARN_ON(!mvm_link
))
2836 IWL_DEBUG_WOWLAN(mvm
, "wakeup reason 0x%x\n",
2837 status
->wakeup_reasons
);
2839 mvm_ap_sta
= iwl_mvm_sta_from_staid_protected(mvm
, mvm_link
->ap_sta_id
);
2843 /* firmware stores last-used value, we store next value */
2844 if (wowlan_info_ver
>= 5) {
2845 mvm_ap_sta
->tid_data
[status
->tid_offloaded_tx
].seq_number
=
2846 status
->qos_seq_ctr
[status
->tid_offloaded_tx
] + 0x10;
2848 for (i
= 0; i
< IWL_MAX_TID_COUNT
; i
++)
2849 mvm_ap_sta
->tid_data
[i
].seq_number
=
2850 status
->qos_seq_ctr
[i
] + 0x10;
2853 if (mvm
->trans
->trans_cfg
->device_family
>= IWL_DEVICE_FAMILY_22000
) {
2854 i
= mvm
->offload_tid
;
2855 iwl_trans_set_q_ptrs(mvm
->trans
,
2856 mvm_ap_sta
->tid_data
[i
].txq_id
,
2857 mvm_ap_sta
->tid_data
[i
].seq_number
>> 4);
2860 iwl_mvm_report_wakeup_reasons(mvm
, vif
, status
);
2862 keep
= iwl_mvm_setup_connection_keep(mvm
, vif
, status
);
2864 mutex_unlock(&mvm
->mutex
);
2868 #define ND_QUERY_BUF_LEN (sizeof(struct iwl_scan_offload_profile_match) * \
2869 IWL_SCAN_MAX_PROFILES)
2871 struct iwl_mvm_nd_results
{
2872 u32 matched_profiles
;
2873 u8 matches
[ND_QUERY_BUF_LEN
];
2877 iwl_mvm_netdetect_query_results(struct iwl_mvm
*mvm
,
2878 struct iwl_mvm_nd_results
*results
)
2880 struct iwl_scan_offload_match_info
*query
;
2881 struct iwl_host_cmd cmd
= {
2882 .id
= SCAN_OFFLOAD_PROFILES_QUERY_CMD
,
2883 .flags
= CMD_WANT_SKB
,
2886 size_t query_len
, matches_len
;
2887 int max_profiles
= iwl_umac_scan_get_max_profiles(mvm
->fw
);
2889 ret
= iwl_mvm_send_cmd(mvm
, &cmd
);
2891 IWL_ERR(mvm
, "failed to query matched profiles (%d)\n", ret
);
2895 if (fw_has_api(&mvm
->fw
->ucode_capa
,
2896 IWL_UCODE_TLV_API_SCAN_OFFLOAD_CHANS
)) {
2897 query_len
= sizeof(struct iwl_scan_offload_match_info
);
2898 matches_len
= sizeof(struct iwl_scan_offload_profile_match
) *
2901 query_len
= sizeof(struct iwl_scan_offload_profiles_query_v1
);
2902 matches_len
= sizeof(struct iwl_scan_offload_profile_match_v1
) *
2906 len
= iwl_rx_packet_payload_len(cmd
.resp_pkt
);
2907 if (len
< query_len
) {
2908 IWL_ERR(mvm
, "Invalid scan offload profiles query response!\n");
2913 query
= (void *)cmd
.resp_pkt
->data
;
2915 results
->matched_profiles
= le32_to_cpu(query
->matched_profiles
);
2916 memcpy(results
->matches
, query
->matches
, matches_len
);
2918 #ifdef CONFIG_IWLWIFI_DEBUGFS
2919 mvm
->last_netdetect_scans
= le32_to_cpu(query
->n_scans_done
);
2923 iwl_free_resp(&cmd
);
2927 static int iwl_mvm_query_num_match_chans(struct iwl_mvm
*mvm
,
2928 struct iwl_mvm_nd_results
*results
,
2933 if (fw_has_api(&mvm
->fw
->ucode_capa
,
2934 IWL_UCODE_TLV_API_SCAN_OFFLOAD_CHANS
)) {
2935 struct iwl_scan_offload_profile_match
*matches
=
2936 (void *)results
->matches
;
2938 for (i
= 0; i
< SCAN_OFFLOAD_MATCHING_CHANNELS_LEN
; i
++)
2939 n_chans
+= hweight8(matches
[idx
].matching_channels
[i
]);
2941 struct iwl_scan_offload_profile_match_v1
*matches
=
2942 (void *)results
->matches
;
2944 for (i
= 0; i
< SCAN_OFFLOAD_MATCHING_CHANNELS_LEN_V1
; i
++)
2945 n_chans
+= hweight8(matches
[idx
].matching_channels
[i
]);
2951 static void iwl_mvm_query_set_freqs(struct iwl_mvm
*mvm
,
2952 struct iwl_mvm_nd_results
*results
,
2953 struct cfg80211_wowlan_nd_match
*match
,
2958 if (fw_has_api(&mvm
->fw
->ucode_capa
,
2959 IWL_UCODE_TLV_API_SCAN_OFFLOAD_CHANS
)) {
2960 struct iwl_scan_offload_profile_match
*matches
=
2961 (void *)results
->matches
;
2963 for (i
= 0; i
< SCAN_OFFLOAD_MATCHING_CHANNELS_LEN
* 8; i
++)
2964 if (matches
[idx
].matching_channels
[i
/ 8] & (BIT(i
% 8)))
2965 match
->channels
[match
->n_channels
++] =
2966 mvm
->nd_channels
[i
]->center_freq
;
2968 struct iwl_scan_offload_profile_match_v1
*matches
=
2969 (void *)results
->matches
;
2971 for (i
= 0; i
< SCAN_OFFLOAD_MATCHING_CHANNELS_LEN_V1
* 8; i
++)
2972 if (matches
[idx
].matching_channels
[i
/ 8] & (BIT(i
% 8)))
2973 match
->channels
[match
->n_channels
++] =
2974 mvm
->nd_channels
[i
]->center_freq
;
2979 * enum iwl_d3_notif - d3 notifications
2980 * @IWL_D3_NOTIF_WOWLAN_INFO: WOWLAN_INFO_NOTIF was received
2981 * @IWL_D3_NOTIF_WOWLAN_WAKE_PKT: WOWLAN_WAKE_PKT_NOTIF was received
2982 * @IWL_D3_NOTIF_PROT_OFFLOAD: PROT_OFFLOAD_NOTIF was received
2983 * @IWL_D3_ND_MATCH_INFO: OFFLOAD_MATCH_INFO_NOTIF was received
2984 * @IWL_D3_NOTIF_D3_END_NOTIF: D3_END_NOTIF was received
2987 IWL_D3_NOTIF_WOWLAN_INFO
= BIT(0),
2988 IWL_D3_NOTIF_WOWLAN_WAKE_PKT
= BIT(1),
2989 IWL_D3_NOTIF_PROT_OFFLOAD
= BIT(2),
2990 IWL_D3_ND_MATCH_INFO
= BIT(3),
2991 IWL_D3_NOTIF_D3_END_NOTIF
= BIT(4)
2994 /* manage d3 resume data */
2995 struct iwl_d3_data
{
2996 struct iwl_wowlan_status_data
*status
;
2999 u32 notif_expected
; /* bitmap - see &enum iwl_d3_notif */
3000 u32 notif_received
; /* bitmap - see &enum iwl_d3_notif */
3001 struct iwl_mvm_nd_results
*nd_results
;
3002 bool nd_results_valid
;
3005 static void iwl_mvm_query_netdetect_reasons(struct iwl_mvm
*mvm
,
3006 struct ieee80211_vif
*vif
,
3007 struct iwl_d3_data
*d3_data
)
3009 struct cfg80211_wowlan_nd_info
*net_detect
= NULL
;
3010 struct cfg80211_wowlan_wakeup wakeup
= {
3013 struct cfg80211_wowlan_wakeup
*wakeup_report
= &wakeup
;
3014 unsigned long matched_profiles
;
3016 int i
, n_matches
, ret
;
3018 if (WARN_ON(!d3_data
|| !d3_data
->status
))
3021 reasons
= d3_data
->status
->wakeup_reasons
;
3023 if (reasons
& IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED
)
3024 wakeup
.rfkill_release
= true;
3026 if (reasons
!= IWL_WOWLAN_WAKEUP_BY_NON_WIRELESS
)
3029 if (!iwl_fw_lookup_notif_ver(mvm
->fw
, PROT_OFFLOAD_GROUP
,
3030 WOWLAN_INFO_NOTIFICATION
, 0)) {
3031 IWL_INFO(mvm
, "Query FW for ND results\n");
3032 ret
= iwl_mvm_netdetect_query_results(mvm
, d3_data
->nd_results
);
3035 IWL_INFO(mvm
, "Notification based ND results\n");
3036 ret
= d3_data
->nd_results_valid
? 0 : -1;
3039 if (ret
|| !d3_data
->nd_results
->matched_profiles
) {
3040 wakeup_report
= NULL
;
3044 matched_profiles
= d3_data
->nd_results
->matched_profiles
;
3045 if (mvm
->n_nd_match_sets
) {
3046 n_matches
= hweight_long(matched_profiles
);
3048 IWL_ERR(mvm
, "no net detect match information available\n");
3052 net_detect
= kzalloc(struct_size(net_detect
, matches
, n_matches
),
3054 if (!net_detect
|| !n_matches
)
3057 for_each_set_bit(i
, &matched_profiles
, mvm
->n_nd_match_sets
) {
3058 struct cfg80211_wowlan_nd_match
*match
;
3059 int idx
, n_channels
= 0;
3061 n_channels
= iwl_mvm_query_num_match_chans(mvm
,
3062 d3_data
->nd_results
,
3065 match
= kzalloc(struct_size(match
, channels
, n_channels
),
3070 net_detect
->matches
[net_detect
->n_matches
++] = match
;
3072 /* We inverted the order of the SSIDs in the scan
3073 * request, so invert the index here.
3075 idx
= mvm
->n_nd_match_sets
- i
- 1;
3076 match
->ssid
.ssid_len
= mvm
->nd_match_sets
[idx
].ssid
.ssid_len
;
3077 memcpy(match
->ssid
.ssid
, mvm
->nd_match_sets
[idx
].ssid
.ssid
,
3078 match
->ssid
.ssid_len
);
3080 if (mvm
->n_nd_channels
< n_channels
)
3083 iwl_mvm_query_set_freqs(mvm
, d3_data
->nd_results
, match
, i
);
3087 wakeup
.net_detect
= net_detect
;
3089 iwl_mvm_free_nd(mvm
);
3091 mutex_unlock(&mvm
->mutex
);
3092 ieee80211_report_wowlan_wakeup(vif
, wakeup_report
, GFP_KERNEL
);
3095 for (i
= 0; i
< net_detect
->n_matches
; i
++)
3096 kfree(net_detect
->matches
[i
]);
3101 static void iwl_mvm_d3_disconnect_iter(void *data
, u8
*mac
,
3102 struct ieee80211_vif
*vif
)
3104 /* skip the one we keep connection on */
3108 if (vif
->type
== NL80211_IFTYPE_STATION
)
3109 ieee80211_resume_disconnect(vif
);
3112 static bool iwl_mvm_check_rt_status(struct iwl_mvm
*mvm
,
3113 struct ieee80211_vif
*vif
)
3117 /* check for lmac1 error */
3118 if (iwl_fwrt_read_err_table(mvm
->trans
,
3119 mvm
->trans
->dbg
.lmac_error_event_table
[0],
3121 if (err_id
== RF_KILL_INDICATOR_FOR_WOWLAN
&& vif
) {
3122 struct cfg80211_wowlan_wakeup wakeup
= {
3123 .rfkill_release
= true,
3125 ieee80211_report_wowlan_wakeup(vif
, &wakeup
,
3131 /* check if we have lmac2 set and check for error */
3132 if (iwl_fwrt_read_err_table(mvm
->trans
,
3133 mvm
->trans
->dbg
.lmac_error_event_table
[1],
3137 /* check for umac error */
3138 if (iwl_fwrt_read_err_table(mvm
->trans
,
3139 mvm
->trans
->dbg
.umac_error_event_table
,
3147 * This function assumes:
3148 * 1. The mutex is already held.
3149 * 2. The callee functions unlock the mutex.
3152 iwl_mvm_choose_query_wakeup_reasons(struct iwl_mvm
*mvm
,
3153 struct ieee80211_vif
*vif
,
3154 struct iwl_d3_data
*d3_data
)
3156 lockdep_assert_held(&mvm
->mutex
);
3158 /* if FW uses status notification, status shouldn't be NULL here */
3159 if (!d3_data
->status
) {
3160 struct iwl_mvm_vif
*mvmvif
= iwl_mvm_vif_from_mac80211(vif
);
3161 u8 sta_id
= mvm
->net_detect
? IWL_INVALID_STA
:
3162 mvmvif
->deflink
.ap_sta_id
;
3164 /* bug - FW with MLO has status notification */
3165 WARN_ON(ieee80211_vif_is_mld(vif
));
3167 d3_data
->status
= iwl_mvm_send_wowlan_get_status(mvm
, sta_id
);
3170 if (mvm
->net_detect
) {
3171 iwl_mvm_query_netdetect_reasons(mvm
, vif
, d3_data
);
3173 bool keep
= iwl_mvm_query_wakeup_reasons(mvm
, vif
,
3176 #ifdef CONFIG_IWLWIFI_DEBUGFS
3178 mvm
->keep_vif
= vif
;
3186 #define IWL_WOWLAN_WAKEUP_REASON_HAS_WAKEUP_PKT (IWL_WOWLAN_WAKEUP_BY_MAGIC_PACKET | \
3187 IWL_WOWLAN_WAKEUP_BY_PATTERN | \
3188 IWL_WAKEUP_BY_PATTERN_IPV4_TCP_SYN |\
3189 IWL_WAKEUP_BY_PATTERN_IPV4_TCP_SYN_WILDCARD |\
3190 IWL_WAKEUP_BY_PATTERN_IPV6_TCP_SYN |\
3191 IWL_WAKEUP_BY_PATTERN_IPV6_TCP_SYN_WILDCARD)
3193 static int iwl_mvm_wowlan_store_wake_pkt(struct iwl_mvm
*mvm
,
3194 struct iwl_wowlan_wake_pkt_notif
*notif
,
3195 struct iwl_wowlan_status_data
*status
,
3198 u32 data_size
, packet_len
= le32_to_cpu(notif
->wake_packet_length
);
3200 if (len
< sizeof(*notif
)) {
3201 IWL_ERR(mvm
, "Invalid WoWLAN wake packet notification!\n");
3205 if (WARN_ON(!status
)) {
3206 IWL_ERR(mvm
, "Got wake packet notification but wowlan status data is NULL\n");
3210 if (WARN_ON(!(status
->wakeup_reasons
&
3211 IWL_WOWLAN_WAKEUP_REASON_HAS_WAKEUP_PKT
))) {
3212 IWL_ERR(mvm
, "Got wakeup packet but wakeup reason is %x\n",
3213 status
->wakeup_reasons
);
3217 data_size
= len
- offsetof(struct iwl_wowlan_wake_pkt_notif
, wake_packet
);
3219 /* data_size got the padding from the notification, remove it. */
3220 if (packet_len
< data_size
)
3221 data_size
= packet_len
;
3223 status
->wake_packet
= kmemdup(notif
->wake_packet
, data_size
,
3226 if (!status
->wake_packet
)
3229 status
->wake_packet_length
= packet_len
;
3230 status
->wake_packet_bufsize
= data_size
;
3235 static void iwl_mvm_nd_match_info_handler(struct iwl_mvm
*mvm
,
3236 struct iwl_d3_data
*d3_data
,
3237 struct iwl_scan_offload_match_info
*notif
,
3240 struct iwl_wowlan_status_data
*status
= d3_data
->status
;
3241 struct ieee80211_vif
*vif
= iwl_mvm_get_bss_vif(mvm
);
3242 struct iwl_mvm_nd_results
*results
= d3_data
->nd_results
;
3243 size_t i
, matches_len
= sizeof(struct iwl_scan_offload_profile_match
) *
3244 iwl_umac_scan_get_max_profiles(mvm
->fw
);
3246 if (IS_ERR_OR_NULL(vif
))
3249 if (len
< sizeof(struct iwl_scan_offload_match_info
)) {
3250 IWL_ERR(mvm
, "Invalid scan match info notification\n");
3254 if (!mvm
->net_detect
) {
3255 IWL_ERR(mvm
, "Unexpected scan match info notification\n");
3259 if (!status
|| status
->wakeup_reasons
!= IWL_WOWLAN_WAKEUP_BY_NON_WIRELESS
) {
3261 "Ignore scan match info notification: no reason\n");
3265 #ifdef CONFIG_IWLWIFI_DEBUGFS
3266 mvm
->last_netdetect_scans
= le32_to_cpu(notif
->n_scans_done
);
3269 results
->matched_profiles
= le32_to_cpu(notif
->matched_profiles
);
3270 IWL_INFO(mvm
, "number of matched profiles=%u\n",
3271 results
->matched_profiles
);
3273 if (results
->matched_profiles
) {
3274 memcpy(results
->matches
, notif
->matches
, matches_len
);
3275 d3_data
->nd_results_valid
= true;
3278 /* no scan should be active at this point */
3279 mvm
->scan_status
= 0;
3280 for (i
= 0; i
< mvm
->max_scans
; i
++)
3281 mvm
->scan_uid_status
[i
] = 0;
3284 static bool iwl_mvm_wait_d3_notif(struct iwl_notif_wait_data
*notif_wait
,
3285 struct iwl_rx_packet
*pkt
, void *data
)
3287 struct iwl_mvm
*mvm
=
3288 container_of(notif_wait
, struct iwl_mvm
, notif_wait
);
3289 struct iwl_d3_data
*d3_data
= data
;
3290 u32 len
= iwl_rx_packet_payload_len(pkt
);
3292 int wowlan_info_ver
= iwl_fw_lookup_notif_ver(mvm
->fw
,
3294 WOWLAN_INFO_NOTIFICATION
,
3295 IWL_FW_CMD_VER_UNKNOWN
);
3298 switch (WIDE_ID(pkt
->hdr
.group_id
, pkt
->hdr
.cmd
)) {
3299 case WIDE_ID(PROT_OFFLOAD_GROUP
, WOWLAN_INFO_NOTIFICATION
): {
3301 if (d3_data
->notif_received
& IWL_D3_NOTIF_WOWLAN_INFO
) {
3302 /* We might get two notifications due to dual bss */
3303 IWL_DEBUG_WOWLAN(mvm
,
3304 "Got additional wowlan info notification\n");
3308 if (wowlan_info_ver
< 2) {
3309 struct iwl_wowlan_info_notif_v1
*notif_v1
=
3311 struct iwl_wowlan_info_notif_v2
*notif_v2
;
3313 notif_v2
= kmemdup(notif_v1
, sizeof(*notif_v2
), GFP_ATOMIC
);
3318 notif_v2
->tid_tear_down
= notif_v1
->tid_tear_down
;
3319 notif_v2
->station_id
= notif_v1
->station_id
;
3320 memset_after(notif_v2
, 0, station_id
);
3321 iwl_mvm_parse_wowlan_info_notif_v2(mvm
, notif_v2
,
3326 } else if (wowlan_info_ver
== 2) {
3327 struct iwl_wowlan_info_notif_v2
*notif_v2
=
3330 iwl_mvm_parse_wowlan_info_notif_v2(mvm
, notif_v2
,
3333 } else if (wowlan_info_ver
< 5) {
3334 struct iwl_wowlan_info_notif_v4
*notif
=
3337 iwl_mvm_parse_wowlan_info_notif_v4(mvm
, notif
,
3338 d3_data
->status
, len
,
3339 wowlan_info_ver
> 3);
3341 struct iwl_wowlan_info_notif
*notif
=
3344 iwl_mvm_parse_wowlan_info_notif(mvm
, notif
,
3345 d3_data
->status
, len
);
3348 d3_data
->notif_received
|= IWL_D3_NOTIF_WOWLAN_INFO
;
3350 if (d3_data
->status
&&
3351 d3_data
->status
->wakeup_reasons
& IWL_WOWLAN_WAKEUP_REASON_HAS_WAKEUP_PKT
)
3352 /* We are supposed to get also wake packet notif */
3353 d3_data
->notif_expected
|= IWL_D3_NOTIF_WOWLAN_WAKE_PKT
;
3357 case WIDE_ID(PROT_OFFLOAD_GROUP
, WOWLAN_WAKE_PKT_NOTIFICATION
): {
3358 struct iwl_wowlan_wake_pkt_notif
*notif
= (void *)pkt
->data
;
3360 if (d3_data
->notif_received
& IWL_D3_NOTIF_WOWLAN_WAKE_PKT
) {
3361 /* We shouldn't get two wake packet notifications */
3363 "Got additional wowlan wake packet notification\n");
3365 d3_data
->notif_received
|= IWL_D3_NOTIF_WOWLAN_WAKE_PKT
;
3366 len
= iwl_rx_packet_payload_len(pkt
);
3367 ret
= iwl_mvm_wowlan_store_wake_pkt(mvm
, notif
,
3372 "Can't parse WOWLAN_WAKE_PKT_NOTIFICATION\n");
3377 case WIDE_ID(SCAN_GROUP
, OFFLOAD_MATCH_INFO_NOTIF
): {
3378 struct iwl_scan_offload_match_info
*notif
= (void *)pkt
->data
;
3380 if (d3_data
->notif_received
& IWL_D3_ND_MATCH_INFO
) {
3382 "Got additional netdetect match info\n");
3386 d3_data
->notif_received
|= IWL_D3_ND_MATCH_INFO
;
3388 /* explicitly set this in the 'expected' as well */
3389 d3_data
->notif_expected
|= IWL_D3_ND_MATCH_INFO
;
3391 len
= iwl_rx_packet_payload_len(pkt
);
3392 iwl_mvm_nd_match_info_handler(mvm
, d3_data
, notif
, len
);
3395 case WIDE_ID(PROT_OFFLOAD_GROUP
, D3_END_NOTIFICATION
): {
3396 struct iwl_mvm_d3_end_notif
*notif
= (void *)pkt
->data
;
3398 d3_data
->d3_end_flags
= __le32_to_cpu(notif
->flags
);
3399 d3_data
->notif_received
|= IWL_D3_NOTIF_D3_END_NOTIF
;
3407 return d3_data
->notif_received
== d3_data
->notif_expected
;
3410 static int iwl_mvm_resume_firmware(struct iwl_mvm
*mvm
, bool test
)
3413 enum iwl_d3_status d3_status
;
3414 struct iwl_host_cmd cmd
= {
3416 .flags
= CMD_WANT_SKB
| CMD_SEND_IN_D3
,
3418 bool reset
= fw_has_capa(&mvm
->fw
->ucode_capa
,
3419 IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG
);
3421 ret
= iwl_trans_d3_resume(mvm
->trans
, &d3_status
, test
, !reset
);
3425 if (d3_status
!= IWL_D3_STATUS_ALIVE
) {
3426 IWL_INFO(mvm
, "Device was reset during suspend\n");
3431 * We should trigger resume flow using command only for 22000 family
3432 * AX210 and above don't need the command since they have
3433 * the doorbell interrupt.
3435 if (mvm
->trans
->trans_cfg
->device_family
<= IWL_DEVICE_FAMILY_22000
&&
3436 fw_has_capa(&mvm
->fw
->ucode_capa
, IWL_UCODE_TLV_CAPA_D0I3_END_FIRST
)) {
3437 ret
= iwl_mvm_send_cmd(mvm
, &cmd
);
3439 IWL_ERR(mvm
, "Failed to send D0I3_END_CMD first (%d)\n",
3446 #define IWL_MVM_D3_NOTIF_TIMEOUT (HZ / 3)
3448 static int iwl_mvm_d3_notif_wait(struct iwl_mvm
*mvm
,
3449 struct iwl_d3_data
*d3_data
)
3451 static const u16 d3_resume_notif
[] = {
3452 WIDE_ID(PROT_OFFLOAD_GROUP
, WOWLAN_INFO_NOTIFICATION
),
3453 WIDE_ID(PROT_OFFLOAD_GROUP
, WOWLAN_WAKE_PKT_NOTIFICATION
),
3454 WIDE_ID(SCAN_GROUP
, OFFLOAD_MATCH_INFO_NOTIF
),
3455 WIDE_ID(PROT_OFFLOAD_GROUP
, D3_END_NOTIFICATION
)
3457 static const u16 d3_fast_resume_notif
[] = {
3458 WIDE_ID(PROT_OFFLOAD_GROUP
, D3_END_NOTIFICATION
)
3460 struct iwl_notification_wait wait_d3_notif
;
3463 if (mvm
->fast_resume
)
3464 iwl_init_notification_wait(&mvm
->notif_wait
, &wait_d3_notif
,
3465 d3_fast_resume_notif
,
3466 ARRAY_SIZE(d3_fast_resume_notif
),
3467 iwl_mvm_wait_d3_notif
, d3_data
);
3469 iwl_init_notification_wait(&mvm
->notif_wait
, &wait_d3_notif
,
3471 ARRAY_SIZE(d3_resume_notif
),
3472 iwl_mvm_wait_d3_notif
, d3_data
);
3474 ret
= iwl_mvm_resume_firmware(mvm
, d3_data
->test
);
3476 iwl_remove_notification(&mvm
->notif_wait
, &wait_d3_notif
);
3480 return iwl_wait_notification(&mvm
->notif_wait
, &wait_d3_notif
,
3481 IWL_MVM_D3_NOTIF_TIMEOUT
);
3484 static inline bool iwl_mvm_d3_resume_notif_based(struct iwl_mvm
*mvm
)
3486 return iwl_fw_lookup_notif_ver(mvm
->fw
, PROT_OFFLOAD_GROUP
,
3487 WOWLAN_INFO_NOTIFICATION
, 0) &&
3488 iwl_fw_lookup_notif_ver(mvm
->fw
, PROT_OFFLOAD_GROUP
,
3489 WOWLAN_WAKE_PKT_NOTIFICATION
, 0) &&
3490 iwl_fw_lookup_notif_ver(mvm
->fw
, PROT_OFFLOAD_GROUP
,
3491 D3_END_NOTIFICATION
, 0);
3494 static int __iwl_mvm_resume(struct iwl_mvm
*mvm
, bool test
)
3496 struct ieee80211_vif
*vif
= NULL
;
3498 struct iwl_mvm_nd_results results
= {};
3499 struct iwl_d3_data d3_data
= {
3502 IWL_D3_NOTIF_WOWLAN_INFO
|
3503 IWL_D3_NOTIF_D3_END_NOTIF
,
3504 .nd_results_valid
= false,
3505 .nd_results
= &results
,
3507 bool unified_image
= fw_has_capa(&mvm
->fw
->ucode_capa
,
3508 IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG
);
3509 bool d0i3_first
= fw_has_capa(&mvm
->fw
->ucode_capa
,
3510 IWL_UCODE_TLV_CAPA_D0I3_END_FIRST
);
3511 bool resume_notif_based
= iwl_mvm_d3_resume_notif_based(mvm
);
3514 mutex_lock(&mvm
->mutex
);
3516 /* Apparently, the device went away and device_powered_off() was called,
3517 * don't even try to read the rt_status, the device is currently
3520 if (!test_bit(IWL_MVM_STATUS_IN_D3
, &mvm
->status
)) {
3522 "Can't resume, device_powered_off() was called during wowlan\n");
3526 mvm
->last_reset_or_resume_time_jiffies
= jiffies
;
3528 /* get the BSS vif pointer again */
3529 vif
= iwl_mvm_get_bss_vif(mvm
);
3530 if (IS_ERR_OR_NULL(vif
))
3533 iwl_fw_dbg_read_d3_debug_data(&mvm
->fwrt
);
3535 if (iwl_mvm_check_rt_status(mvm
, vif
)) {
3536 set_bit(STATUS_FW_ERROR
, &mvm
->trans
->status
);
3537 iwl_mvm_dump_nic_error_log(mvm
);
3538 iwl_dbg_tlv_time_point(&mvm
->fwrt
,
3539 IWL_FW_INI_TIME_POINT_FW_ASSERT
, NULL
);
3540 iwl_fw_dbg_collect_desc(&mvm
->fwrt
, &iwl_dump_desc_assert
,
3546 if (resume_notif_based
) {
3547 d3_data
.status
= kzalloc(sizeof(*d3_data
.status
), GFP_KERNEL
);
3548 if (!d3_data
.status
) {
3549 IWL_ERR(mvm
, "Failed to allocate wowlan status\n");
3554 ret
= iwl_mvm_d3_notif_wait(mvm
, &d3_data
);
3558 ret
= iwl_mvm_resume_firmware(mvm
, test
);
3563 iwl_mvm_unblock_esr(mvm
, vif
, IWL_MVM_ESR_BLOCKED_WOWLAN
);
3565 /* after the successful handshake, we're out of D3 */
3566 mvm
->trans
->system_pm_mode
= IWL_PLAT_PM_MODE_DISABLED
;
3568 /* when reset is required we can't send these following commands */
3569 if (d3_data
.d3_end_flags
& IWL_D0I3_RESET_REQUIRE
)
3570 goto query_wakeup_reasons
;
3573 * Query the current location and source from the D3 firmware so we
3574 * can play it back when we re-intiailize the D0 firmware
3576 iwl_mvm_update_changed_regdom(mvm
);
3578 /* Re-configure PPAG settings */
3579 iwl_mvm_ppag_send_cmd(mvm
);
3582 /* Re-configure default SAR profile */
3583 iwl_mvm_sar_select_profile(mvm
, 1, 1);
3585 if (mvm
->net_detect
&& unified_image
) {
3586 /* If this is a non-unified image, we restart the FW,
3587 * so no need to stop the netdetect scan. If that
3588 * fails, continue and try to get the wake-up reasons,
3589 * but trigger a HW restart by keeping a failure code
3592 ret
= iwl_mvm_scan_stop(mvm
, IWL_MVM_SCAN_NETDETECT
,
3596 query_wakeup_reasons
:
3597 keep
= iwl_mvm_choose_query_wakeup_reasons(mvm
, vif
, &d3_data
);
3598 /* has unlocked the mutex, so skip that */
3602 mutex_unlock(&mvm
->mutex
);
3605 kfree(d3_data
.status
->wake_packet
);
3606 kfree(d3_data
.status
);
3607 iwl_mvm_free_nd(mvm
);
3609 if (!d3_data
.test
&& !mvm
->net_detect
)
3610 ieee80211_iterate_active_interfaces_mtx(mvm
->hw
,
3611 IEEE80211_IFACE_ITER_NORMAL
,
3612 iwl_mvm_d3_disconnect_iter
,
3615 clear_bit(IWL_MVM_STATUS_IN_D3
, &mvm
->status
);
3617 /* no need to reset the device in unified images, if successful */
3618 if (unified_image
&& !ret
) {
3619 /* nothing else to do if we already sent D0I3_END_CMD */
3623 if (!iwl_fw_lookup_notif_ver(mvm
->fw
, PROT_OFFLOAD_GROUP
,
3624 D3_END_NOTIFICATION
, 0)) {
3625 ret
= iwl_mvm_send_cmd_pdu(mvm
, D0I3_END_CMD
, 0, 0, NULL
);
3628 } else if (!(d3_data
.d3_end_flags
& IWL_D0I3_RESET_REQUIRE
)) {
3634 * Reconfigure the device in one of the following cases:
3635 * 1. We are not using a unified image
3636 * 2. We are using a unified image but had an error while exiting D3
3638 set_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED
, &mvm
->status
);
3640 /* regardless of what happened, we're now out of D3 */
3641 mvm
->trans
->system_pm_mode
= IWL_PLAT_PM_MODE_DISABLED
;
3646 int iwl_mvm_resume(struct ieee80211_hw
*hw
)
3648 struct iwl_mvm
*mvm
= IWL_MAC80211_GET_MVM(hw
);
3651 ret
= __iwl_mvm_resume(mvm
, false);
3653 iwl_mvm_resume_tcm(mvm
);
3655 iwl_fw_runtime_resume(&mvm
->fwrt
);
3660 void iwl_mvm_set_wakeup(struct ieee80211_hw
*hw
, bool enabled
)
3662 struct iwl_mvm
*mvm
= IWL_MAC80211_GET_MVM(hw
);
3664 device_set_wakeup_enable(mvm
->trans
->dev
, enabled
);
3667 void iwl_mvm_fast_suspend(struct iwl_mvm
*mvm
)
3669 struct iwl_d3_manager_config d3_cfg_cmd_data
= {};
3672 lockdep_assert_held(&mvm
->mutex
);
3674 IWL_DEBUG_WOWLAN(mvm
, "Starting fast suspend flow\n");
3676 mvm
->fast_resume
= true;
3677 set_bit(IWL_MVM_STATUS_IN_D3
, &mvm
->status
);
3679 WARN_ON(iwl_mvm_power_update_device(mvm
));
3680 mvm
->trans
->system_pm_mode
= IWL_PLAT_PM_MODE_D3
;
3681 ret
= iwl_mvm_send_cmd_pdu(mvm
, D3_CONFIG_CMD
, CMD_SEND_IN_D3
,
3682 sizeof(d3_cfg_cmd_data
), &d3_cfg_cmd_data
);
3685 "fast suspend: couldn't send D3_CONFIG_CMD %d\n", ret
);
3687 ret
= iwl_trans_d3_suspend(mvm
->trans
, false, false);
3689 IWL_ERR(mvm
, "fast suspend: trans_d3_suspend failed %d\n", ret
);
3692 int iwl_mvm_fast_resume(struct iwl_mvm
*mvm
)
3694 struct iwl_d3_data d3_data
= {
3696 IWL_D3_NOTIF_D3_END_NOTIF
,
3700 lockdep_assert_held(&mvm
->mutex
);
3702 IWL_DEBUG_WOWLAN(mvm
, "Starting the fast resume flow\n");
3704 mvm
->last_reset_or_resume_time_jiffies
= jiffies
;
3705 iwl_fw_dbg_read_d3_debug_data(&mvm
->fwrt
);
3707 if (iwl_mvm_check_rt_status(mvm
, NULL
)) {
3709 "iwl_mvm_check_rt_status failed, device is gone during suspend\n");
3710 set_bit(STATUS_FW_ERROR
, &mvm
->trans
->status
);
3711 iwl_mvm_dump_nic_error_log(mvm
);
3712 iwl_dbg_tlv_time_point(&mvm
->fwrt
,
3713 IWL_FW_INI_TIME_POINT_FW_ASSERT
, NULL
);
3714 iwl_fw_dbg_collect_desc(&mvm
->fwrt
, &iwl_dump_desc_assert
,
3716 mvm
->trans
->state
= IWL_TRANS_NO_FW
;
3721 ret
= iwl_mvm_d3_notif_wait(mvm
, &d3_data
);
3724 IWL_ERR(mvm
, "Couldn't get the d3 notif %d\n", ret
);
3725 mvm
->trans
->state
= IWL_TRANS_NO_FW
;
3729 clear_bit(IWL_MVM_STATUS_IN_D3
, &mvm
->status
);
3730 mvm
->trans
->system_pm_mode
= IWL_PLAT_PM_MODE_DISABLED
;
3731 mvm
->fast_resume
= false;
3736 #ifdef CONFIG_IWLWIFI_DEBUGFS
3737 static int iwl_mvm_d3_test_open(struct inode
*inode
, struct file
*file
)
3739 struct iwl_mvm
*mvm
= inode
->i_private
;
3742 if (mvm
->d3_test_active
)
3745 file
->private_data
= inode
->i_private
;
3747 iwl_mvm_pause_tcm(mvm
, true);
3749 iwl_fw_runtime_suspend(&mvm
->fwrt
);
3751 /* start pseudo D3 */
3753 wiphy_lock(mvm
->hw
->wiphy
);
3754 err
= __iwl_mvm_suspend(mvm
->hw
, mvm
->hw
->wiphy
->wowlan_config
, true);
3755 wiphy_unlock(mvm
->hw
->wiphy
);
3762 mvm
->d3_test_active
= true;
3763 mvm
->keep_vif
= NULL
;
3767 static ssize_t
iwl_mvm_d3_test_read(struct file
*file
, char __user
*user_buf
,
3768 size_t count
, loff_t
*ppos
)
3770 struct iwl_mvm
*mvm
= file
->private_data
;
3771 unsigned long end
= jiffies
+ 60 * HZ
;
3775 /* read pme_ptr if available */
3776 if (mvm
->d3_test_pme_ptr
) {
3777 pme_asserted
= iwl_trans_read_mem32(mvm
->trans
,
3778 mvm
->d3_test_pme_ptr
);
3783 if (msleep_interruptible(100))
3786 if (time_is_before_jiffies(end
)) {
3788 "ending pseudo-D3 with timeout after ~60 seconds\n");
3796 static void iwl_mvm_d3_test_disconn_work_iter(void *_data
, u8
*mac
,
3797 struct ieee80211_vif
*vif
)
3799 /* skip the one we keep connection on */
3803 if (vif
->type
== NL80211_IFTYPE_STATION
)
3804 ieee80211_connection_loss(vif
);
3807 static int iwl_mvm_d3_test_release(struct inode
*inode
, struct file
*file
)
3809 struct iwl_mvm
*mvm
= inode
->i_private
;
3810 bool unified_image
= fw_has_capa(&mvm
->fw
->ucode_capa
,
3811 IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG
);
3813 mvm
->d3_test_active
= false;
3815 iwl_fw_dbg_read_d3_debug_data(&mvm
->fwrt
);
3818 wiphy_lock(mvm
->hw
->wiphy
);
3819 __iwl_mvm_resume(mvm
, true);
3820 wiphy_unlock(mvm
->hw
->wiphy
);
3823 iwl_mvm_resume_tcm(mvm
);
3825 iwl_fw_runtime_resume(&mvm
->fwrt
);
3827 iwl_abort_notification_waits(&mvm
->notif_wait
);
3828 if (!unified_image
) {
3829 int remaining_time
= 10;
3831 ieee80211_restart_hw(mvm
->hw
);
3833 /* wait for restart and disconnect all interfaces */
3834 while (test_bit(IWL_MVM_STATUS_IN_HW_RESTART
, &mvm
->status
) &&
3835 remaining_time
> 0) {
3840 if (remaining_time
== 0)
3841 IWL_ERR(mvm
, "Timed out waiting for HW restart!\n");
3844 ieee80211_iterate_active_interfaces_atomic(
3845 mvm
->hw
, IEEE80211_IFACE_ITER_NORMAL
,
3846 iwl_mvm_d3_test_disconn_work_iter
, mvm
->keep_vif
);
3851 const struct file_operations iwl_dbgfs_d3_test_ops
= {
3852 .open
= iwl_mvm_d3_test_open
,
3853 .read
= iwl_mvm_d3_test_read
,
3854 .release
= iwl_mvm_d3_test_release
,