Lines Matching +full:key +full:- +full:wakeup

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
14 #include "iwl-modparams.h"
15 #include "fw-api.h"
26 mutex_lock(&mvm->mutex); in iwl_mvm_set_rekey_data()
28 mvmvif->rekey_data.kek_len = data->kek_len; in iwl_mvm_set_rekey_data()
29 mvmvif->rekey_data.kck_len = data->kck_len; in iwl_mvm_set_rekey_data()
30 memcpy(mvmvif->rekey_data.kek, data->kek, data->kek_len); in iwl_mvm_set_rekey_data()
31 memcpy(mvmvif->rekey_data.kck, data->kck, data->kck_len); in iwl_mvm_set_rekey_data()
32 mvmvif->rekey_data.akm = data->akm & 0xFF; in iwl_mvm_set_rekey_data()
33 mvmvif->rekey_data.replay_ctr = in iwl_mvm_set_rekey_data()
34 cpu_to_le64(be64_to_cpup((const __be64 *)data->replay_ctr)); in iwl_mvm_set_rekey_data()
35 mvmvif->rekey_data.valid = true; in iwl_mvm_set_rekey_data()
37 mutex_unlock(&mvm->mutex); in iwl_mvm_set_rekey_data()
49 memset(mvmvif->tentative_addrs, 0, sizeof(mvmvif->tentative_addrs)); in iwl_mvm_ipv6_addr_change()
51 read_lock_bh(&idev->lock); in iwl_mvm_ipv6_addr_change()
52 list_for_each_entry(ifa, &idev->addr_list, if_list) { in iwl_mvm_ipv6_addr_change()
53 mvmvif->target_ipv6_addrs[idx] = ifa->addr; in iwl_mvm_ipv6_addr_change()
54 if (ifa->flags & IFA_F_TENTATIVE) in iwl_mvm_ipv6_addr_change()
55 __set_bit(idx, mvmvif->tentative_addrs); in iwl_mvm_ipv6_addr_change()
60 read_unlock_bh(&idev->lock); in iwl_mvm_ipv6_addr_change()
62 mvmvif->num_target_ipv6_addrs = idx; in iwl_mvm_ipv6_addr_change()
71 mvmvif->tx_key_idx = idx; in iwl_mvm_set_default_unicast_key()
82 static const u8 *iwl_mvm_find_max_pn(struct ieee80211_key_conf *key, in iwl_mvm_find_max_pn() argument
87 const u8 *ret = seq->ccmp.pn; in iwl_mvm_find_max_pn()
91 ieee80211_get_key_rx_seq(key, tid, seq); in iwl_mvm_find_max_pn()
95 const u8 *tmp = ptk_pn->q[i].pn[tid]; in iwl_mvm_find_max_pn()
112 struct ieee80211_key_conf *key, in iwl_mvm_wowlan_program_keys() argument
120 switch (key->cipher) { in iwl_mvm_wowlan_program_keys()
128 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, in iwl_mvm_wowlan_program_keys()
129 mvmvif->color)), in iwl_mvm_wowlan_program_keys()
133 .wep_key.key_index = key->keyidx, in iwl_mvm_wowlan_program_keys()
134 .wep_key.key_size = key->keylen, in iwl_mvm_wowlan_program_keys()
138 * This will fail -- the key functions don't set support in iwl_mvm_wowlan_program_keys()
142 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) in iwl_mvm_wowlan_program_keys()
145 memcpy(&wkc.wep_key.key[3], key->key, key->keylen); in iwl_mvm_wowlan_program_keys()
146 if (key->keyidx == mvmvif->tx_key_idx) { in iwl_mvm_wowlan_program_keys()
147 /* TX key must be at offset 0 */ in iwl_mvm_wowlan_program_keys()
151 data->wep_key_idx++; in iwl_mvm_wowlan_program_keys()
152 wkc.wep_key.key_offset = data->wep_key_idx; in iwl_mvm_wowlan_program_keys()
155 mutex_lock(&mvm->mutex); in iwl_mvm_wowlan_program_keys()
157 data->error = ret != 0; in iwl_mvm_wowlan_program_keys()
159 mvm->ptk_ivlen = key->iv_len; in iwl_mvm_wowlan_program_keys()
160 mvm->ptk_icvlen = key->icv_len; in iwl_mvm_wowlan_program_keys()
161 mvm->gtk_ivlen = key->iv_len; in iwl_mvm_wowlan_program_keys()
162 mvm->gtk_icvlen = key->icv_len; in iwl_mvm_wowlan_program_keys()
163 mutex_unlock(&mvm->mutex); in iwl_mvm_wowlan_program_keys()
165 /* don't upload key again */ in iwl_mvm_wowlan_program_keys()
169 data->error = true; in iwl_mvm_wowlan_program_keys()
176 * Ignore CMAC keys -- the WoWLAN firmware doesn't support them in iwl_mvm_wowlan_program_keys()
178 * support for the IGTK key renewal, but doesn't really use the in iwl_mvm_wowlan_program_keys()
190 mutex_lock(&mvm->mutex); in iwl_mvm_wowlan_program_keys()
192 * The D3 firmware hardcodes the key offset 0 as the key it in iwl_mvm_wowlan_program_keys()
195 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) { in iwl_mvm_wowlan_program_keys()
196 mvm->ptk_ivlen = key->iv_len; in iwl_mvm_wowlan_program_keys()
197 mvm->ptk_icvlen = key->icv_len; in iwl_mvm_wowlan_program_keys()
198 ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, 0); in iwl_mvm_wowlan_program_keys()
201 * firmware only supports TSC/RSC for a single key, in iwl_mvm_wowlan_program_keys()
203 * with new ones -- this relies on mac80211 doing in iwl_mvm_wowlan_program_keys()
206 mvm->gtk_ivlen = key->iv_len; in iwl_mvm_wowlan_program_keys()
207 mvm->gtk_icvlen = key->icv_len; in iwl_mvm_wowlan_program_keys()
208 ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, 1); in iwl_mvm_wowlan_program_keys()
210 mutex_unlock(&mvm->mutex); in iwl_mvm_wowlan_program_keys()
211 data->error = ret != 0; in iwl_mvm_wowlan_program_keys()
222 struct ieee80211_key_conf *key, in iwl_mvm_wowlan_get_rsc_tsc_data() argument
232 switch (key->cipher) { in iwl_mvm_wowlan_get_rsc_tsc_data()
240 data->rsc_tsc->params.all_tsc_rsc.tkip.unicast_rsc; in iwl_mvm_wowlan_get_rsc_tsc_data()
242 &data->rsc_tsc->params.all_tsc_rsc.tkip.tsc; in iwl_mvm_wowlan_get_rsc_tsc_data()
244 pn64 = atomic64_read(&key->tx_pn); in iwl_mvm_wowlan_get_rsc_tsc_data()
245 tkip_tx_sc->iv16 = cpu_to_le16(TKIP_PN_TO_IV16(pn64)); in iwl_mvm_wowlan_get_rsc_tsc_data()
246 tkip_tx_sc->iv32 = cpu_to_le32(TKIP_PN_TO_IV32(pn64)); in iwl_mvm_wowlan_get_rsc_tsc_data()
249 data->rsc_tsc->params.all_tsc_rsc.tkip.multicast_rsc; in iwl_mvm_wowlan_get_rsc_tsc_data()
253 * For non-QoS this relies on the fact that both the uCode and in iwl_mvm_wowlan_get_rsc_tsc_data()
258 ieee80211_get_key_rx_seq(key, i, &seq); in iwl_mvm_wowlan_get_rsc_tsc_data()
263 data->have_rsc_tsc = true; in iwl_mvm_wowlan_get_rsc_tsc_data()
273 data->rsc_tsc->params.all_tsc_rsc.aes.unicast_rsc; in iwl_mvm_wowlan_get_rsc_tsc_data()
275 &data->rsc_tsc->params.all_tsc_rsc.aes.tsc; in iwl_mvm_wowlan_get_rsc_tsc_data()
277 pn64 = atomic64_read(&key->tx_pn); in iwl_mvm_wowlan_get_rsc_tsc_data()
278 aes_tx_sc->pn = cpu_to_le64(pn64); in iwl_mvm_wowlan_get_rsc_tsc_data()
281 data->rsc_tsc->params.all_tsc_rsc.aes.multicast_rsc; in iwl_mvm_wowlan_get_rsc_tsc_data()
285 * For non-QoS this relies on the fact that both the uCode and in iwl_mvm_wowlan_get_rsc_tsc_data()
295 ptk_pn = rcu_dereference(mvmsta->ptk_pn[key->keyidx]); in iwl_mvm_wowlan_get_rsc_tsc_data()
302 pn = iwl_mvm_find_max_pn(key, ptk_pn, &seq, i, in iwl_mvm_wowlan_get_rsc_tsc_data()
303 mvm->trans->num_rx_queues); in iwl_mvm_wowlan_get_rsc_tsc_data()
317 ieee80211_get_key_rx_seq(key, i, &seq); in iwl_mvm_wowlan_get_rsc_tsc_data()
326 data->have_rsc_tsc = true; in iwl_mvm_wowlan_get_rsc_tsc_data()
341 struct ieee80211_key_conf *key, in iwl_mvm_wowlan_get_rsc_v5_data() argument
351 switch (key->cipher) { in iwl_mvm_wowlan_get_rsc_v5_data()
362 rsc = data->rsc->ucast_rsc; in iwl_mvm_wowlan_get_rsc_v5_data()
364 if (WARN_ON(data->gtks >= ARRAY_SIZE(data->gtk_ids))) in iwl_mvm_wowlan_get_rsc_v5_data()
366 data->gtk_ids[data->gtks] = key->keyidx; in iwl_mvm_wowlan_get_rsc_v5_data()
367 rsc = data->rsc->mcast_rsc[data->gtks % 2]; in iwl_mvm_wowlan_get_rsc_v5_data()
368 if (WARN_ON(key->keyidx >= in iwl_mvm_wowlan_get_rsc_v5_data()
369 ARRAY_SIZE(data->rsc->mcast_key_id_map))) in iwl_mvm_wowlan_get_rsc_v5_data()
371 data->rsc->mcast_key_id_map[key->keyidx] = data->gtks % 2; in iwl_mvm_wowlan_get_rsc_v5_data()
372 if (data->gtks >= 2) { in iwl_mvm_wowlan_get_rsc_v5_data()
373 int prev = data->gtks - 2; in iwl_mvm_wowlan_get_rsc_v5_data()
374 int prev_idx = data->gtk_ids[prev]; in iwl_mvm_wowlan_get_rsc_v5_data()
376 data->rsc->mcast_key_id_map[prev_idx] = in iwl_mvm_wowlan_get_rsc_v5_data()
379 data->gtks++; in iwl_mvm_wowlan_get_rsc_v5_data()
382 switch (key->cipher) { in iwl_mvm_wowlan_get_rsc_v5_data()
389 * For non-QoS this relies on the fact that both the uCode and in iwl_mvm_wowlan_get_rsc_v5_data()
394 ieee80211_get_key_rx_seq(key, i, &seq); in iwl_mvm_wowlan_get_rsc_v5_data()
400 data->have_rsc = true; in iwl_mvm_wowlan_get_rsc_v5_data()
406 * For non-QoS this relies on the fact that both the uCode and in iwl_mvm_wowlan_get_rsc_v5_data()
416 ptk_pn = rcu_dereference(mvmsta->ptk_pn[key->keyidx]); in iwl_mvm_wowlan_get_rsc_v5_data()
423 pn = iwl_mvm_find_max_pn(key, ptk_pn, &seq, i, in iwl_mvm_wowlan_get_rsc_v5_data()
424 mvm->trans->num_rx_queues); in iwl_mvm_wowlan_get_rsc_v5_data()
438 ieee80211_get_key_rx_seq(key, i, &seq); in iwl_mvm_wowlan_get_rsc_v5_data()
447 data->have_rsc = true; in iwl_mvm_wowlan_get_rsc_v5_data()
456 int ver = iwl_fw_lookup_cmd_ver(mvm->fw, WOWLAN_TSC_RSC_PARAM, in iwl_mvm_wowlan_config_rsc_tsc()
466 return -ENOMEM; in iwl_mvm_wowlan_config_rsc_tsc()
468 for (i = 0; i < ARRAY_SIZE(data.rsc->mcast_key_id_map); i++) in iwl_mvm_wowlan_config_rsc_tsc()
469 data.rsc->mcast_key_id_map[i] = in iwl_mvm_wowlan_config_rsc_tsc()
471 data.rsc->sta_id = cpu_to_le32(mvm_link->ap_sta_id); in iwl_mvm_wowlan_config_rsc_tsc()
473 ieee80211_iter_keys(mvm->hw, vif, in iwl_mvm_wowlan_config_rsc_tsc()
490 return -ENOMEM; in iwl_mvm_wowlan_config_rsc_tsc()
494 data.rsc_tsc->sta_id = in iwl_mvm_wowlan_config_rsc_tsc()
495 cpu_to_le32(mvm_link->ap_sta_id); in iwl_mvm_wowlan_config_rsc_tsc()
498 size = sizeof(data.rsc_tsc->params); in iwl_mvm_wowlan_config_rsc_tsc()
501 ieee80211_iter_keys(mvm->hw, vif, in iwl_mvm_wowlan_config_rsc_tsc()
528 struct ieee80211_key_conf *key, in iwl_mvm_wowlan_get_tkip_data() argument
539 switch (key->cipher) { in iwl_mvm_wowlan_get_tkip_data()
546 rx_p1ks = data->tkip.rx_uni; in iwl_mvm_wowlan_get_tkip_data()
548 pn64 = atomic64_read(&key->tx_pn); in iwl_mvm_wowlan_get_tkip_data()
550 ieee80211_get_tkip_p1k_iv(key, TKIP_PN_TO_IV32(pn64), in iwl_mvm_wowlan_get_tkip_data()
552 iwl_mvm_convert_p1k(p1k, data->tkip.tx.p1k); in iwl_mvm_wowlan_get_tkip_data()
554 memcpy(data->tkip.mic_keys.tx, in iwl_mvm_wowlan_get_tkip_data()
555 &key->key[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY], in iwl_mvm_wowlan_get_tkip_data()
558 rx_mic_key = data->tkip.mic_keys.rx_unicast; in iwl_mvm_wowlan_get_tkip_data()
560 rx_p1ks = data->tkip.rx_multi; in iwl_mvm_wowlan_get_tkip_data()
561 rx_mic_key = data->tkip.mic_keys.rx_mcast; in iwl_mvm_wowlan_get_tkip_data()
565 ieee80211_get_key_rx_seq(key, i, &seq); in iwl_mvm_wowlan_get_tkip_data()
571 ieee80211_get_tkip_rx_p1k(key, vif->bss_conf.bssid, in iwl_mvm_wowlan_get_tkip_data()
574 ieee80211_get_tkip_rx_p1k(key, vif->bss_conf.bssid, in iwl_mvm_wowlan_get_tkip_data()
579 &key->key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY], in iwl_mvm_wowlan_get_tkip_data()
582 data->have_tkip_keys = true; in iwl_mvm_wowlan_get_tkip_data()
594 struct ieee80211_key_conf *key, in iwl_mvm_wowlan_gtk_type_iter() argument
600 if (key->keyidx == 4 || key->keyidx == 5) in iwl_mvm_wowlan_gtk_type_iter()
601 cipher = &data->kek_kck_cmd->igtk_cipher; in iwl_mvm_wowlan_gtk_type_iter()
602 if (key->keyidx == 6 || key->keyidx == 7) in iwl_mvm_wowlan_gtk_type_iter()
603 cipher = &data->kek_kck_cmd->bigtk_cipher; in iwl_mvm_wowlan_gtk_type_iter()
605 switch (key->cipher) { in iwl_mvm_wowlan_gtk_type_iter()
610 data->kek_kck_cmd->gtk_cipher = in iwl_mvm_wowlan_gtk_type_iter()
625 data->kek_kck_cmd->gtk_cipher = in iwl_mvm_wowlan_gtk_type_iter()
631 data->kek_kck_cmd->gtk_cipher = in iwl_mvm_wowlan_gtk_type_iter()
647 if (!wowlan->n_patterns) in iwl_mvm_send_patterns_v1()
650 cmd.len[0] = struct_size(pattern_cmd, patterns, wowlan->n_patterns); in iwl_mvm_send_patterns_v1()
654 return -ENOMEM; in iwl_mvm_send_patterns_v1()
656 pattern_cmd->n_patterns = cpu_to_le32(wowlan->n_patterns); in iwl_mvm_send_patterns_v1()
658 for (i = 0; i < wowlan->n_patterns; i++) { in iwl_mvm_send_patterns_v1()
659 int mask_len = DIV_ROUND_UP(wowlan->patterns[i].pattern_len, 8); in iwl_mvm_send_patterns_v1()
661 memcpy(&pattern_cmd->patterns[i].mask, in iwl_mvm_send_patterns_v1()
662 wowlan->patterns[i].mask, mask_len); in iwl_mvm_send_patterns_v1()
663 memcpy(&pattern_cmd->patterns[i].pattern, in iwl_mvm_send_patterns_v1()
664 wowlan->patterns[i].pattern, in iwl_mvm_send_patterns_v1()
665 wowlan->patterns[i].pattern_len); in iwl_mvm_send_patterns_v1()
666 pattern_cmd->patterns[i].mask_size = mask_len; in iwl_mvm_send_patterns_v1()
667 pattern_cmd->patterns[i].pattern_size = in iwl_mvm_send_patterns_v1()
668 wowlan->patterns[i].pattern_len; in iwl_mvm_send_patterns_v1()
687 int ver = iwl_fw_lookup_cmd_ver(mvm->fw, cmd.id, in iwl_mvm_send_patterns()
690 if (!wowlan->n_patterns) in iwl_mvm_send_patterns()
694 wowlan->n_patterns * sizeof(struct iwl_wowlan_pattern_v2); in iwl_mvm_send_patterns()
698 return -ENOMEM; in iwl_mvm_send_patterns()
700 pattern_cmd->n_patterns = wowlan->n_patterns; in iwl_mvm_send_patterns()
702 pattern_cmd->sta_id = mvm_link->ap_sta_id; in iwl_mvm_send_patterns()
704 for (i = 0; i < wowlan->n_patterns; i++) { in iwl_mvm_send_patterns()
705 int mask_len = DIV_ROUND_UP(wowlan->patterns[i].pattern_len, 8); in iwl_mvm_send_patterns()
707 pattern_cmd->patterns[i].pattern_type = in iwl_mvm_send_patterns()
710 memcpy(&pattern_cmd->patterns[i].u.bitmask.mask, in iwl_mvm_send_patterns()
711 wowlan->patterns[i].mask, mask_len); in iwl_mvm_send_patterns()
712 memcpy(&pattern_cmd->patterns[i].u.bitmask.pattern, in iwl_mvm_send_patterns()
713 wowlan->patterns[i].pattern, in iwl_mvm_send_patterns()
714 wowlan->patterns[i].pattern_len); in iwl_mvm_send_patterns()
715 pattern_cmd->patterns[i].u.bitmask.mask_size = mask_len; in iwl_mvm_send_patterns()
716 pattern_cmd->patterns[i].u.bitmask.pattern_size = in iwl_mvm_send_patterns()
717 wowlan->patterns[i].pattern_len; in iwl_mvm_send_patterns()
741 return -EINVAL; in iwl_mvm_d3_reprogram()
744 if (WARN_ON(!mvmvif->deflink.phy_ctxt)) in iwl_mvm_d3_reprogram()
745 return -EINVAL; in iwl_mvm_d3_reprogram()
748 ctx = rcu_dereference(vif->bss_conf.chanctx_conf); in iwl_mvm_d3_reprogram()
751 return -EINVAL; in iwl_mvm_d3_reprogram()
753 chandef = ctx->def; in iwl_mvm_d3_reprogram()
754 ap_def = ctx->ap; in iwl_mvm_d3_reprogram()
755 chains_static = ctx->rx_chains_static; in iwl_mvm_d3_reprogram()
756 chains_dynamic = ctx->rx_chains_dynamic; in iwl_mvm_d3_reprogram()
759 ret = iwl_mvm_phy_ctxt_add(mvm, mvmvif->deflink.phy_ctxt, &chandef, in iwl_mvm_d3_reprogram()
765 mvmvif->uploaded = false; in iwl_mvm_d3_reprogram()
767 if (WARN_ON(!vif->cfg.assoc)) in iwl_mvm_d3_reprogram()
768 return -EINVAL; in iwl_mvm_d3_reprogram()
774 /* add back binding - XXX refactor? */ in iwl_mvm_d3_reprogram()
776 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->deflink.phy_ctxt->id, in iwl_mvm_d3_reprogram()
777 mvmvif->deflink.phy_ctxt->color)); in iwl_mvm_d3_reprogram()
780 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->deflink.phy_ctxt->id, in iwl_mvm_d3_reprogram()
781 mvmvif->deflink.phy_ctxt->color)); in iwl_mvm_d3_reprogram()
782 binding_cmd.macs[0] = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, in iwl_mvm_d3_reprogram()
783 mvmvif->color)); in iwl_mvm_d3_reprogram()
798 return -EIO; in iwl_mvm_d3_reprogram()
804 rcu_assign_pointer(mvm->fw_id_to_mac_id[mvmvif->deflink.ap_sta_id], in iwl_mvm_d3_reprogram()
813 quota->id_and_color = in iwl_mvm_d3_reprogram()
814 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->deflink.phy_ctxt->id, in iwl_mvm_d3_reprogram()
815 mvmvif->deflink.phy_ctxt->color)); in iwl_mvm_d3_reprogram()
816 quota->quota = cpu_to_le32(IWL_MVM_MAX_QUOTA); in iwl_mvm_d3_reprogram()
817 quota->max_duration = cpu_to_le32(IWL_MVM_MAX_QUOTA); in iwl_mvm_d3_reprogram()
821 quota->id_and_color = cpu_to_le32(FW_CTXT_INVALID); in iwl_mvm_d3_reprogram()
842 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, in iwl_mvm_get_last_nonqos_seq()
843 mvmvif->color)), in iwl_mvm_get_last_nonqos_seq()
861 err = -EINVAL; in iwl_mvm_get_last_nonqos_seq()
863 err = le16_to_cpup((__le16 *)cmd.resp_pkt->data); in iwl_mvm_get_last_nonqos_seq()
864 /* firmware returns next, not last-used seqno */ in iwl_mvm_get_last_nonqos_seq()
865 err = (u16) (err - 0x10); in iwl_mvm_get_last_nonqos_seq()
878 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, in iwl_mvm_set_last_nonqos_seq()
879 mvmvif->color)), in iwl_mvm_set_last_nonqos_seq()
880 .value = cpu_to_le16(mvmvif->seqno), in iwl_mvm_set_last_nonqos_seq()
884 if (!mvmvif->seqno_valid) in iwl_mvm_set_last_nonqos_seq()
887 mvmvif->seqno_valid = false; in iwl_mvm_set_last_nonqos_seq()
891 IWL_ERR(mvm, "failed to set non-QoS seqno\n"); in iwl_mvm_set_last_nonqos_seq()
900 * Set the HW restart bit -- this is mostly true as we're in iwl_mvm_switch_to_d3()
909 set_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status); in iwl_mvm_switch_to_d3()
912 memset(mvm->fw_key_table, 0, sizeof(mvm->fw_key_table)); in iwl_mvm_switch_to_d3()
914 mvm->ptk_ivlen = 0; in iwl_mvm_switch_to_d3()
915 mvm->ptk_icvlen = 0; in iwl_mvm_switch_to_d3()
916 mvm->ptk_ivlen = 0; in iwl_mvm_switch_to_d3()
917 mvm->ptk_icvlen = 0; in iwl_mvm_switch_to_d3()
931 /* TODO: wowlan_config_cmd->wowlan_ba_teardown_tids */ in iwl_mvm_get_wowlan_config()
933 wowlan_config_cmd->is_11n_connection = in iwl_mvm_get_wowlan_config()
934 ap_sta->deflink.ht_cap.ht_supported; in iwl_mvm_get_wowlan_config()
935 wowlan_config_cmd->flags = ENABLE_L3_FILTERING | in iwl_mvm_get_wowlan_config()
938 if (ap_sta->mfp) in iwl_mvm_get_wowlan_config()
939 wowlan_config_cmd->flags |= IS_11W_ASSOC; in iwl_mvm_get_wowlan_config()
941 if (iwl_fw_lookup_cmd_ver(mvm->fw, WOWLAN_CONFIGURATION, 0) < 6) { in iwl_mvm_get_wowlan_config()
948 wowlan_config_cmd->non_qos_seq = cpu_to_le16(ret); in iwl_mvm_get_wowlan_config()
951 if (iwl_fw_lookup_cmd_ver(mvm->fw, WOWLAN_CONFIGURATION, 0) < 7) in iwl_mvm_get_wowlan_config()
954 if (wowlan->disconnect) in iwl_mvm_get_wowlan_config()
955 wowlan_config_cmd->wakeup_filter |= in iwl_mvm_get_wowlan_config()
958 if (wowlan->magic_pkt) in iwl_mvm_get_wowlan_config()
959 wowlan_config_cmd->wakeup_filter |= in iwl_mvm_get_wowlan_config()
961 if (wowlan->gtk_rekey_failure) in iwl_mvm_get_wowlan_config()
962 wowlan_config_cmd->wakeup_filter |= in iwl_mvm_get_wowlan_config()
964 if (wowlan->eap_identity_req) in iwl_mvm_get_wowlan_config()
965 wowlan_config_cmd->wakeup_filter |= in iwl_mvm_get_wowlan_config()
967 if (wowlan->four_way_handshake) in iwl_mvm_get_wowlan_config()
968 wowlan_config_cmd->wakeup_filter |= in iwl_mvm_get_wowlan_config()
970 if (wowlan->n_patterns) in iwl_mvm_get_wowlan_config()
971 wowlan_config_cmd->wakeup_filter |= in iwl_mvm_get_wowlan_config()
974 if (wowlan->rfkill_release) in iwl_mvm_get_wowlan_config()
975 wowlan_config_cmd->wakeup_filter |= in iwl_mvm_get_wowlan_config()
978 if (wowlan->tcp) { in iwl_mvm_get_wowlan_config()
983 wowlan_config_cmd->wakeup_filter |= in iwl_mvm_get_wowlan_config()
990 if (wowlan->any) { in iwl_mvm_get_wowlan_config()
991 wowlan_config_cmd->wakeup_filter |= in iwl_mvm_get_wowlan_config()
1005 bool unified = fw_has_capa(&mvm->fw->ucode_capa, in iwl_mvm_wowlan_config_key_params()
1016 * as we need non-atomic context in order to take the in iwl_mvm_wowlan_config_key_params()
1023 * take care of locking/unlocking mvm->mutex. in iwl_mvm_wowlan_config_key_params()
1025 ieee80211_iter_keys(mvm->hw, vif, iwl_mvm_wowlan_program_keys, in iwl_mvm_wowlan_config_key_params()
1029 return -EIO; in iwl_mvm_wowlan_config_key_params()
1036 if (!fw_has_api(&mvm->fw->ucode_capa, in iwl_mvm_wowlan_config_key_params()
1038 int ver = iwl_fw_lookup_cmd_ver(mvm->fw, WOWLAN_TKIP_PARAM, in iwl_mvm_wowlan_config_key_params()
1046 cpu_to_le32(mvm_link->ap_sta_id); in iwl_mvm_wowlan_config_key_params()
1051 return -EINVAL; in iwl_mvm_wowlan_config_key_params()
1054 ieee80211_iter_keys(mvm->hw, vif, iwl_mvm_wowlan_get_tkip_data, in iwl_mvm_wowlan_config_key_params()
1069 if (mvmvif->rekey_data.valid) { in iwl_mvm_wowlan_config_key_params()
1077 cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, in iwl_mvm_wowlan_config_key_params()
1082 return -EINVAL; in iwl_mvm_wowlan_config_key_params()
1084 ieee80211_iter_keys(mvm->hw, vif, iwl_mvm_wowlan_gtk_type_iter, in iwl_mvm_wowlan_config_key_params()
1087 memcpy(kek_kck_cmd.kck, mvmvif->rekey_data.kck, in iwl_mvm_wowlan_config_key_params()
1088 mvmvif->rekey_data.kck_len); in iwl_mvm_wowlan_config_key_params()
1089 kek_kck_cmd.kck_len = cpu_to_le16(mvmvif->rekey_data.kck_len); in iwl_mvm_wowlan_config_key_params()
1090 memcpy(kek_kck_cmd.kek, mvmvif->rekey_data.kek, in iwl_mvm_wowlan_config_key_params()
1091 mvmvif->rekey_data.kek_len); in iwl_mvm_wowlan_config_key_params()
1092 kek_kck_cmd.kek_len = cpu_to_le16(mvmvif->rekey_data.kek_len); in iwl_mvm_wowlan_config_key_params()
1093 kek_kck_cmd.replay_ctr = mvmvif->rekey_data.replay_ctr; in iwl_mvm_wowlan_config_key_params()
1094 kek_kck_cmd.akm = cpu_to_le32(mvmvif->rekey_data.akm); in iwl_mvm_wowlan_config_key_params()
1095 kek_kck_cmd.sta_id = cpu_to_le32(mvm_link->ap_sta_id); in iwl_mvm_wowlan_config_key_params()
1112 mvmvif->rekey_data.akm); in iwl_mvm_wowlan_config_key_params()
1132 bool unified_image = fw_has_capa(&mvm->fw->ucode_capa, in iwl_mvm_wowlan_config()
1135 mvm->offload_tid = wowlan_config_cmd_v6->offloading_tid; in iwl_mvm_wowlan_config()
1151 if (iwl_fw_lookup_cmd_ver(mvm->fw, WOWLAN_CONFIGURATION, 0) > 6) { in iwl_mvm_wowlan_config()
1153 .wakeup_filter = wowlan_config_cmd_v6->wakeup_filter, in iwl_mvm_wowlan_config()
1155 wowlan_config_cmd_v6->wowlan_ba_teardown_tids, in iwl_mvm_wowlan_config()
1157 wowlan_config_cmd_v6->is_11n_connection, in iwl_mvm_wowlan_config()
1158 .offloading_tid = wowlan_config_cmd_v6->offloading_tid, in iwl_mvm_wowlan_config()
1159 .flags = wowlan_config_cmd_v6->flags, in iwl_mvm_wowlan_config()
1160 .sta_id = wowlan_config_cmd_v6->sta_id, in iwl_mvm_wowlan_config()
1174 if (fw_has_api(&mvm->fw->ucode_capa, in iwl_mvm_wowlan_config()
1183 mvm_link->ap_sta_id); in iwl_mvm_wowlan_config()
1193 bool unified_image = fw_has_capa(&mvm->fw->ucode_capa, in iwl_mvm_netdetect_config()
1203 * net-detect). But in practice this doesn't seem to in iwl_mvm_netdetect_config()
1211 ret = iwl_mvm_sched_scan_start(mvm, vif, nd_config, &mvm->nd_ies, in iwl_mvm_netdetect_config()
1216 if (WARN_ON(mvm->nd_match_sets || mvm->nd_channels)) in iwl_mvm_netdetect_config()
1217 return -EBUSY; in iwl_mvm_netdetect_config()
1220 if (nd_config->n_match_sets) { in iwl_mvm_netdetect_config()
1221 mvm->nd_match_sets = kmemdup(nd_config->match_sets, in iwl_mvm_netdetect_config()
1222 sizeof(*nd_config->match_sets) * in iwl_mvm_netdetect_config()
1223 nd_config->n_match_sets, in iwl_mvm_netdetect_config()
1225 if (mvm->nd_match_sets) in iwl_mvm_netdetect_config()
1226 mvm->n_nd_match_sets = nd_config->n_match_sets; in iwl_mvm_netdetect_config()
1230 mvm->nd_channels = kmemdup(nd_config->channels, in iwl_mvm_netdetect_config()
1231 sizeof(*nd_config->channels) * in iwl_mvm_netdetect_config()
1232 nd_config->n_channels, in iwl_mvm_netdetect_config()
1234 if (mvm->nd_channels) in iwl_mvm_netdetect_config()
1235 mvm->n_nd_channels = nd_config->n_channels; in iwl_mvm_netdetect_config()
1242 kfree(mvm->nd_match_sets); in iwl_mvm_free_nd()
1243 mvm->nd_match_sets = NULL; in iwl_mvm_free_nd()
1244 mvm->n_nd_match_sets = 0; in iwl_mvm_free_nd()
1245 kfree(mvm->nd_channels); in iwl_mvm_free_nd()
1246 mvm->nd_channels = NULL; in iwl_mvm_free_nd()
1247 mvm->n_nd_channels = 0; in iwl_mvm_free_nd()
1262 * platforms have issues processing a wakeup signal while in __iwl_mvm_suspend()
1275 bool unified_image = fw_has_capa(&mvm->fw->ucode_capa, in __iwl_mvm_suspend()
1284 return -EINVAL; in __iwl_mvm_suspend()
1295 mutex_lock(&mvm->mutex); in __iwl_mvm_suspend()
1297 set_bit(IWL_MVM_STATUS_IN_D3, &mvm->status); in __iwl_mvm_suspend()
1303 mvm_link = mvmvif->link[iwl_mvm_get_primary_link(vif)]; in __iwl_mvm_suspend()
1305 ret = -EINVAL; in __iwl_mvm_suspend()
1309 if (mvm_link->ap_sta_id == IWL_INVALID_STA) { in __iwl_mvm_suspend()
1311 if (!wowlan->nd_config) { in __iwl_mvm_suspend()
1317 mvm, wowlan, wowlan->nd_config, vif); in __iwl_mvm_suspend()
1321 mvm->net_detect = true; in __iwl_mvm_suspend()
1327 wowlan_config_cmd.sta_id = mvm_link->ap_sta_id; in __iwl_mvm_suspend()
1330 mvm->fw_id_to_mac_id[mvm_link->ap_sta_id], in __iwl_mvm_suspend()
1331 lockdep_is_held(&mvm->mutex)); in __iwl_mvm_suspend()
1333 ret = -EINVAL; in __iwl_mvm_suspend()
1338 mvm, ap_sta->txq[wowlan_config_cmd.offloading_tid]); in __iwl_mvm_suspend()
1351 mvm->net_detect = false; in __iwl_mvm_suspend()
1363 if (mvm->d3_wake_sysassert) in __iwl_mvm_suspend()
1373 if (mvm->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_9000) in __iwl_mvm_suspend()
1374 iwl_fw_dbg_stop_restart_recording(&mvm->fwrt, NULL, true); in __iwl_mvm_suspend()
1376 mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_D3; in __iwl_mvm_suspend()
1378 /* must be last -- this switches firmware state */ in __iwl_mvm_suspend()
1385 mvm->d3_test_pme_ptr = in __iwl_mvm_suspend()
1386 le32_to_cpup((__le32 *)d3_cfg_cmd.resp_pkt->data); in __iwl_mvm_suspend()
1391 clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status); in __iwl_mvm_suspend()
1393 ret = iwl_trans_d3_suspend(mvm->trans, test, !unified_image); in __iwl_mvm_suspend()
1398 clear_bit(IWL_MVM_STATUS_IN_D3, &mvm->status); in __iwl_mvm_suspend()
1401 mutex_unlock(&mvm->mutex); in __iwl_mvm_suspend()
1412 mutex_lock(&mvm->mutex); in iwl_mvm_suspend()
1413 iwl_fw_runtime_suspend(&mvm->fwrt); in iwl_mvm_suspend()
1414 mutex_unlock(&mvm->mutex); in iwl_mvm_suspend()
1420 u8 key[WOWLAN_KEY_MAX_SIZE]; member
1442 /* including RX MIC key for TKIP */
1443 u8 key[WOWLAN_KEY_MAX_SIZE]; member
1461 * We use -1 for when we have valid data but don't know
1462 * the key ID from firmware, and thus it needs to be
1463 * installed with the last key (depending on rekeying).
1491 struct cfg80211_wowlan_wakeup wakeup = { in iwl_mvm_report_wakeup_reasons() local
1492 .pattern_idx = -1, in iwl_mvm_report_wakeup_reasons()
1494 struct cfg80211_wowlan_wakeup *wakeup_report = &wakeup; in iwl_mvm_report_wakeup_reasons()
1495 u32 reasons = status->wakeup_reasons; in iwl_mvm_report_wakeup_reasons()
1502 pm_wakeup_event(mvm->dev, 0); in iwl_mvm_report_wakeup_reasons()
1505 wakeup.magic_pkt = true; in iwl_mvm_report_wakeup_reasons()
1508 wakeup.pattern_idx = in iwl_mvm_report_wakeup_reasons()
1509 status->pattern_number; in iwl_mvm_report_wakeup_reasons()
1514 wakeup.disconnect = true; in iwl_mvm_report_wakeup_reasons()
1517 wakeup.gtk_rekey_failure = true; in iwl_mvm_report_wakeup_reasons()
1520 wakeup.rfkill_release = true; in iwl_mvm_report_wakeup_reasons()
1523 wakeup.eap_identity_req = true; in iwl_mvm_report_wakeup_reasons()
1526 wakeup.four_way_handshake = true; in iwl_mvm_report_wakeup_reasons()
1529 wakeup.tcp_connlost = true; in iwl_mvm_report_wakeup_reasons()
1532 wakeup.tcp_nomoretokens = true; in iwl_mvm_report_wakeup_reasons()
1535 wakeup.tcp_match = true; in iwl_mvm_report_wakeup_reasons()
1538 wakeup.unprot_deauth_disassoc = true; in iwl_mvm_report_wakeup_reasons()
1540 if (status->wake_packet) { in iwl_mvm_report_wakeup_reasons()
1541 int pktsize = status->wake_packet_bufsize; in iwl_mvm_report_wakeup_reasons()
1542 int pktlen = status->wake_packet_length; in iwl_mvm_report_wakeup_reasons()
1543 const u8 *pktdata = status->wake_packet; in iwl_mvm_report_wakeup_reasons()
1545 int truncated = pktlen - pktsize; in iwl_mvm_report_wakeup_reasons()
1551 if (ieee80211_is_data(hdr->frame_control)) { in iwl_mvm_report_wakeup_reasons()
1552 int hdrlen = ieee80211_hdrlen(hdr->frame_control); in iwl_mvm_report_wakeup_reasons()
1561 pktsize -= hdrlen; in iwl_mvm_report_wakeup_reasons()
1563 if (ieee80211_has_protected(hdr->frame_control)) { in iwl_mvm_report_wakeup_reasons()
1567 * that's not really a problem - changing in iwl_mvm_report_wakeup_reasons()
1570 if (is_multicast_ether_addr(hdr->addr1)) { in iwl_mvm_report_wakeup_reasons()
1571 ivlen = mvm->gtk_ivlen; in iwl_mvm_report_wakeup_reasons()
1572 icvlen += mvm->gtk_icvlen; in iwl_mvm_report_wakeup_reasons()
1574 ivlen = mvm->ptk_ivlen; in iwl_mvm_report_wakeup_reasons()
1575 icvlen += mvm->ptk_icvlen; in iwl_mvm_report_wakeup_reasons()
1582 truncated -= icvlen; in iwl_mvm_report_wakeup_reasons()
1584 icvlen -= truncated; in iwl_mvm_report_wakeup_reasons()
1588 pktsize -= ivlen + icvlen; in iwl_mvm_report_wakeup_reasons()
1593 if (ieee80211_data_to_8023(pkt, vif->addr, vif->type)) in iwl_mvm_report_wakeup_reasons()
1595 wakeup.packet = pkt->data; in iwl_mvm_report_wakeup_reasons()
1596 wakeup.packet_present_len = pkt->len; in iwl_mvm_report_wakeup_reasons()
1597 wakeup.packet_len = pkt->len - truncated; in iwl_mvm_report_wakeup_reasons()
1598 wakeup.packet_80211 = false; in iwl_mvm_report_wakeup_reasons()
1603 truncated -= 4; in iwl_mvm_report_wakeup_reasons()
1606 fcslen -= truncated; in iwl_mvm_report_wakeup_reasons()
1609 pktsize -= fcslen; in iwl_mvm_report_wakeup_reasons()
1610 wakeup.packet = status->wake_packet; in iwl_mvm_report_wakeup_reasons()
1611 wakeup.packet_present_len = pktsize; in iwl_mvm_report_wakeup_reasons()
1612 wakeup.packet_len = pktlen - truncated; in iwl_mvm_report_wakeup_reasons()
1613 wakeup.packet_80211 = true; in iwl_mvm_report_wakeup_reasons()
1626 seq->ccmp.pn[0] = pn >> 40; in iwl_mvm_le64_to_aes_seq()
1627 seq->ccmp.pn[1] = pn >> 32; in iwl_mvm_le64_to_aes_seq()
1628 seq->ccmp.pn[2] = pn >> 24; in iwl_mvm_le64_to_aes_seq()
1629 seq->ccmp.pn[3] = pn >> 16; in iwl_mvm_le64_to_aes_seq()
1630 seq->ccmp.pn[4] = pn >> 8; in iwl_mvm_le64_to_aes_seq()
1631 seq->ccmp.pn[5] = pn; in iwl_mvm_le64_to_aes_seq()
1637 iwl_mvm_le64_to_aes_seq(sc->pn, seq); in iwl_mvm_aes_sc_to_seq()
1644 seq->tkip.iv16 = (u16)pn; in iwl_mvm_le64_to_tkip_seq()
1645 seq->tkip.iv32 = (u32)(pn >> 16); in iwl_mvm_le64_to_tkip_seq()
1651 seq->tkip.iv32 = le32_to_cpu(sc->iv32); in iwl_mvm_tkip_sc_to_seq()
1652 seq->tkip.iv16 = le16_to_cpu(sc->iv16); in iwl_mvm_tkip_sc_to_seq()
1655 static void iwl_mvm_set_key_rx_seq_tids(struct ieee80211_key_conf *key, in iwl_mvm_set_key_rx_seq_tids() argument
1661 ieee80211_set_key_rx_seq(key, tid, &seq[tid]); in iwl_mvm_set_key_rx_seq_tids()
1667 struct ieee80211_key_conf *key) in iwl_mvm_set_aes_ptk_rx_seq() argument
1673 iwl_mvm_set_key_rx_seq_tids(key, status->ptk.aes.seq); in iwl_mvm_set_aes_ptk_rx_seq()
1680 ptk_pn = rcu_dereference(mvmsta->ptk_pn[key->keyidx]); in iwl_mvm_set_aes_ptk_rx_seq()
1689 for (i = 1; i < mvm->trans->num_rx_queues; i++) in iwl_mvm_set_aes_ptk_rx_seq()
1690 memcpy(ptk_pn->q[i].pn[tid], in iwl_mvm_set_aes_ptk_rx_seq()
1691 status->ptk.aes.seq[tid].ccmp.pn, in iwl_mvm_set_aes_ptk_rx_seq()
1707 iwl_mvm_tkip_sc_to_seq(&sc->tkip.multicast_rsc[i], in iwl_mvm_convert_key_counters()
1708 &status->gtk_seq[0].tkip.seq[i]); in iwl_mvm_convert_key_counters()
1709 iwl_mvm_aes_sc_to_seq(&sc->aes.multicast_rsc[i], in iwl_mvm_convert_key_counters()
1710 &status->gtk_seq[0].aes.seq[i]); in iwl_mvm_convert_key_counters()
1712 status->gtk_seq[0].valid = true; in iwl_mvm_convert_key_counters()
1713 status->gtk_seq[0].key_id = -1; in iwl_mvm_convert_key_counters()
1716 status->ptk.tkip.tx_pn = (u64)le16_to_cpu(sc->tkip.tsc.iv16) | in iwl_mvm_convert_key_counters()
1717 ((u64)le32_to_cpu(sc->tkip.tsc.iv32) << 16); in iwl_mvm_convert_key_counters()
1718 status->ptk.aes.tx_pn = le64_to_cpu(sc->aes.tsc.pn); in iwl_mvm_convert_key_counters()
1722 iwl_mvm_tkip_sc_to_seq(&sc->tkip.unicast_rsc[i], in iwl_mvm_convert_key_counters()
1723 &status->ptk.tkip.seq[i]); in iwl_mvm_convert_key_counters()
1724 iwl_mvm_aes_sc_to_seq(&sc->aes.unicast_rsc[i], in iwl_mvm_convert_key_counters()
1725 &status->ptk.aes.seq[i]); in iwl_mvm_convert_key_counters()
1737 iwl_mvm_le64_to_tkip_seq(sc->mcast_rsc[idx][tid], in iwl_mvm_convert_key_counters_v5_gtk_seq()
1738 &status->gtk_seq[idx].tkip.seq[tid]); in iwl_mvm_convert_key_counters_v5_gtk_seq()
1739 iwl_mvm_le64_to_aes_seq(sc->mcast_rsc[idx][tid], in iwl_mvm_convert_key_counters_v5_gtk_seq()
1740 &status->gtk_seq[idx].aes.seq[tid]); in iwl_mvm_convert_key_counters_v5_gtk_seq()
1743 status->gtk_seq[idx].valid = true; in iwl_mvm_convert_key_counters_v5_gtk_seq()
1744 status->gtk_seq[idx].key_id = key_id; in iwl_mvm_convert_key_counters_v5_gtk_seq()
1755 BUILD_BUG_ON(ARRAY_SIZE(sc->mcast_rsc) != ARRAY_SIZE(status->gtk_seq)); in iwl_mvm_convert_key_counters_v5()
1758 for (i = 0; i < ARRAY_SIZE(sc->mcast_key_id_map); i++) { in iwl_mvm_convert_key_counters_v5()
1759 u8 entry = sc->mcast_key_id_map[i]; in iwl_mvm_convert_key_counters_v5()
1761 if (entry < ARRAY_SIZE(sc->mcast_rsc)) in iwl_mvm_convert_key_counters_v5()
1770 iwl_mvm_le64_to_tkip_seq(sc->ucast_rsc[tid], in iwl_mvm_convert_key_counters_v5()
1771 &status->ptk.tkip.seq[tid]); in iwl_mvm_convert_key_counters_v5()
1772 iwl_mvm_le64_to_aes_seq(sc->ucast_rsc[tid], in iwl_mvm_convert_key_counters_v5()
1773 &status->ptk.aes.seq[tid]); in iwl_mvm_convert_key_counters_v5()
1777 static void iwl_mvm_set_key_rx_seq_idx(struct ieee80211_key_conf *key, in iwl_mvm_set_key_rx_seq_idx() argument
1781 switch (key->cipher) { in iwl_mvm_set_key_rx_seq_idx()
1785 iwl_mvm_set_key_rx_seq_tids(key, status->gtk_seq[idx].aes.seq); in iwl_mvm_set_key_rx_seq_idx()
1788 iwl_mvm_set_key_rx_seq_tids(key, status->gtk_seq[idx].tkip.seq); in iwl_mvm_set_key_rx_seq_idx()
1795 static void iwl_mvm_set_key_rx_seq(struct ieee80211_key_conf *key, in iwl_mvm_set_key_rx_seq() argument
1801 for (i = 0; i < ARRAY_SIZE(status->gtk_seq); i++) { in iwl_mvm_set_key_rx_seq()
1802 if (!status->gtk_seq[i].valid) in iwl_mvm_set_key_rx_seq()
1805 /* Handle the case where we know the key ID */ in iwl_mvm_set_key_rx_seq()
1806 if (status->gtk_seq[i].key_id == key->keyidx) { in iwl_mvm_set_key_rx_seq()
1807 s8 new_key_id = -1; in iwl_mvm_set_key_rx_seq()
1809 if (status->num_of_gtk_rekeys) in iwl_mvm_set_key_rx_seq()
1810 new_key_id = status->gtk[0].flags & in iwl_mvm_set_key_rx_seq()
1813 /* Don't install a new key's value to an old key */ in iwl_mvm_set_key_rx_seq()
1814 if (new_key_id != key->keyidx) in iwl_mvm_set_key_rx_seq()
1815 iwl_mvm_set_key_rx_seq_idx(key, status, i); in iwl_mvm_set_key_rx_seq()
1819 /* handle the case where we didn't, last key only */ in iwl_mvm_set_key_rx_seq()
1820 if (status->gtk_seq[i].key_id == -1 && in iwl_mvm_set_key_rx_seq()
1821 (!status->num_of_gtk_rekeys || installed)) in iwl_mvm_set_key_rx_seq()
1822 iwl_mvm_set_key_rx_seq_idx(key, status, i); in iwl_mvm_set_key_rx_seq()
1837 struct ieee80211_key_conf *key, in iwl_mvm_d3_find_last_keys() argument
1841 int link_id = vif->active_links ? __ffs(vif->active_links) : -1; in iwl_mvm_d3_find_last_keys()
1843 if (link_id >= 0 && key->link_id >= 0 && link_id != key->link_id) in iwl_mvm_d3_find_last_keys()
1846 if (data->unhandled_cipher) in iwl_mvm_d3_find_last_keys()
1849 switch (key->cipher) { in iwl_mvm_d3_find_last_keys()
1859 data->gtk_cipher = key->cipher; in iwl_mvm_d3_find_last_keys()
1866 if (data->igtk_support && in iwl_mvm_d3_find_last_keys()
1867 (key->keyidx == 4 || key->keyidx == 5)) { in iwl_mvm_d3_find_last_keys()
1868 data->igtk_cipher = key->cipher; in iwl_mvm_d3_find_last_keys()
1869 } else if (data->bigtk_support && in iwl_mvm_d3_find_last_keys()
1870 (key->keyidx == 6 || key->keyidx == 7)) { in iwl_mvm_d3_find_last_keys()
1871 data->bigtk_cipher = key->cipher; in iwl_mvm_d3_find_last_keys()
1873 data->unhandled_cipher = true; in iwl_mvm_d3_find_last_keys()
1878 /* everything else - disconnect from AP */ in iwl_mvm_d3_find_last_keys()
1879 data->unhandled_cipher = true; in iwl_mvm_d3_find_last_keys()
1883 data->num_keys++; in iwl_mvm_d3_find_last_keys()
1887 iwl_mvm_d3_set_igtk_bigtk_ipn(const struct iwl_multicast_key_data *key, in iwl_mvm_d3_set_igtk_bigtk_ipn() argument
1893 BUILD_BUG_ON(sizeof(seq->aes_gmac.pn) != sizeof(key->ipn)); in iwl_mvm_d3_set_igtk_bigtk_ipn()
1894 memcpy(seq->aes_gmac.pn, key->ipn, sizeof(seq->aes_gmac.pn)); in iwl_mvm_d3_set_igtk_bigtk_ipn()
1898 BUILD_BUG_ON(sizeof(seq->aes_cmac.pn) != sizeof(key->ipn)); in iwl_mvm_d3_set_igtk_bigtk_ipn()
1899 memcpy(seq->aes_cmac.pn, key->ipn, sizeof(seq->aes_cmac.pn)); in iwl_mvm_d3_set_igtk_bigtk_ipn()
1908 struct ieee80211_key_conf *key, in iwl_mvm_d3_update_igtk_bigtk() argument
1911 if (status->num_of_gtk_rekeys && key_data->len) { in iwl_mvm_d3_update_igtk_bigtk()
1912 /* remove rekeyed key */ in iwl_mvm_d3_update_igtk_bigtk()
1913 ieee80211_remove_key(key); in iwl_mvm_d3_update_igtk_bigtk()
1919 key->cipher); in iwl_mvm_d3_update_igtk_bigtk()
1920 ieee80211_set_key_rx_seq(key, 0, &seq); in iwl_mvm_d3_update_igtk_bigtk()
1927 struct ieee80211_key_conf *key, in iwl_mvm_d3_update_keys() argument
1931 struct iwl_wowlan_status_data *status = data->status; in iwl_mvm_d3_update_keys()
1933 int link_id = vif->active_links ? __ffs(vif->active_links) : -1; in iwl_mvm_d3_update_keys()
1935 if (link_id >= 0 && key->link_id >= 0 && link_id != key->link_id) in iwl_mvm_d3_update_keys()
1938 if (data->unhandled_cipher) in iwl_mvm_d3_update_keys()
1941 switch (key->cipher) { in iwl_mvm_d3_update_keys()
1950 atomic64_set(&key->tx_pn, status->ptk.aes.tx_pn); in iwl_mvm_d3_update_keys()
1951 iwl_mvm_set_aes_ptk_rx_seq(data->mvm, status, sta, key); in iwl_mvm_d3_update_keys()
1957 atomic64_set(&key->tx_pn, status->ptk.tkip.tx_pn); in iwl_mvm_d3_update_keys()
1958 iwl_mvm_set_key_rx_seq_tids(key, status->ptk.tkip.seq); in iwl_mvm_d3_update_keys()
1961 keyidx = key->keyidx; in iwl_mvm_d3_update_keys()
1962 /* The current key is always sent by the FW, even if it wasn't in iwl_mvm_d3_update_keys()
1964 * We remove an existing key if it has the same index as in iwl_mvm_d3_update_keys()
1965 * a new key in iwl_mvm_d3_update_keys()
1967 if (status->num_of_gtk_rekeys && in iwl_mvm_d3_update_keys()
1968 ((status->gtk[0].len && keyidx == status->gtk[0].id) || in iwl_mvm_d3_update_keys()
1969 (status->gtk[1].len && keyidx == status->gtk[1].id))) { in iwl_mvm_d3_update_keys()
1970 ieee80211_remove_key(key); in iwl_mvm_d3_update_keys()
1972 iwl_mvm_set_key_rx_seq(key, data->status, false); in iwl_mvm_d3_update_keys()
1979 if (key->keyidx == 4 || key->keyidx == 5) { in iwl_mvm_d3_update_keys()
1980 iwl_mvm_d3_update_igtk_bigtk(status, key, in iwl_mvm_d3_update_keys()
1981 &status->igtk); in iwl_mvm_d3_update_keys()
1983 if (key->keyidx == 6 || key->keyidx == 7) { in iwl_mvm_d3_update_keys()
1984 u8 idx = key->keyidx == status->bigtk[1].id; in iwl_mvm_d3_update_keys()
1986 iwl_mvm_d3_update_igtk_bigtk(status, key, in iwl_mvm_d3_update_keys()
1987 &status->bigtk[idx]); in iwl_mvm_d3_update_keys()
1994 struct ieee80211_key_conf *key[IEEE80211_MLD_MAX_NUM_LINKS][8]; member
2000 struct ieee80211_key_conf *key, in iwl_mvm_mlo_key_ciphers() argument
2006 if (key->link_id < 0) in iwl_mvm_mlo_key_ciphers()
2009 if (WARN_ON(key->link_id >= IEEE80211_MLD_MAX_NUM_LINKS || in iwl_mvm_mlo_key_ciphers()
2010 key->keyidx >= 8)) in iwl_mvm_mlo_key_ciphers()
2013 if (WARN_ON(old_keys->key[key->link_id][key->keyidx])) in iwl_mvm_mlo_key_ciphers()
2016 switch (key->cipher) { in iwl_mvm_mlo_key_ciphers()
2026 if (key->keyidx == 4 || key->keyidx == 5) { in iwl_mvm_mlo_key_ciphers()
2029 } else if (key->keyidx == 6 || key->keyidx == 7) { in iwl_mvm_mlo_key_ciphers()
2039 old_keys->cipher[key->link_id][key_type] = key->cipher; in iwl_mvm_mlo_key_ciphers()
2040 old_keys->key[key->link_id][key->keyidx] = key; in iwl_mvm_mlo_key_ciphers()
2051 IWL_DEBUG_WOWLAN(mvm, "Num of MLO Keys: %d\n", status->num_mlo_keys); in iwl_mvm_mlo_gtk_rekey()
2052 if (!status->num_mlo_keys) in iwl_mvm_mlo_gtk_rekey()
2059 /* find the cipher for each mlo key */ in iwl_mvm_mlo_gtk_rekey()
2060 ieee80211_iter_keys(mvm->hw, vif, iwl_mvm_mlo_key_ciphers, old_keys); in iwl_mvm_mlo_gtk_rekey()
2062 for (i = 0; i < status->num_mlo_keys; i++) { in iwl_mvm_mlo_gtk_rekey()
2063 struct iwl_wowlan_mlo_gtk *mlo_key = &status->mlo_keys[i]; in iwl_mvm_mlo_gtk_rekey()
2064 struct ieee80211_key_conf *key, *old_key; in iwl_mvm_mlo_gtk_rekey() local
2068 u8 key[32]; in iwl_mvm_mlo_gtk_rekey() member
2070 u16 flags = le16_to_cpu(mlo_key->flags); in iwl_mvm_mlo_gtk_rekey()
2078 if (!(vif->valid_links & BIT(link_id))) in iwl_mvm_mlo_gtk_rekey()
2086 conf.conf.cipher = old_keys->cipher[link_id][key_type]; in iwl_mvm_mlo_gtk_rekey()
2115 conf.conf.keylen > sizeof(conf.key))) in iwl_mvm_mlo_gtk_rekey()
2118 memcpy(conf.conf.key, mlo_key->key, conf.conf.keylen); in iwl_mvm_mlo_gtk_rekey()
2121 old_key = old_keys->key[link_id][key_id]; in iwl_mvm_mlo_gtk_rekey()
2124 "Remove MLO key id %d, link id %d\n", in iwl_mvm_mlo_gtk_rekey()
2129 IWL_DEBUG_WOWLAN(mvm, "Add MLO key id %d, link id %d\n", in iwl_mvm_mlo_gtk_rekey()
2131 key = ieee80211_gtk_rekey_add(vif, &conf.conf, link_id); in iwl_mvm_mlo_gtk_rekey()
2132 if (WARN_ON(IS_ERR(key))) { in iwl_mvm_mlo_gtk_rekey()
2138 * mac80211 expects the pn in big-endian in iwl_mvm_mlo_gtk_rekey()
2143 for (j = 5; j >= 0; j--) in iwl_mvm_mlo_gtk_rekey()
2144 seq.ccmp.pn[5 - j] = mlo_key->pn[j]; in iwl_mvm_mlo_gtk_rekey()
2146 /* group keys are non-QoS and use TID 0 */ in iwl_mvm_mlo_gtk_rekey()
2147 ieee80211_set_key_rx_seq(key, 0, &seq); in iwl_mvm_mlo_gtk_rekey()
2160 struct ieee80211_key_conf *key; in iwl_mvm_gtk_rekey() local
2163 u8 key[32]; in iwl_mvm_gtk_rekey() member
2167 int link_id = vif->active_links ? __ffs(vif->active_links) : -1; in iwl_mvm_gtk_rekey()
2170 BUILD_BUG_ON(sizeof(conf.key) < WLAN_KEY_LEN_CCMP); in iwl_mvm_gtk_rekey()
2171 BUILD_BUG_ON(sizeof(conf.key) < WLAN_KEY_LEN_GCMP_256); in iwl_mvm_gtk_rekey()
2172 BUILD_BUG_ON(sizeof(conf.key) < WLAN_KEY_LEN_TKIP); in iwl_mvm_gtk_rekey()
2173 BUILD_BUG_ON(sizeof(conf.key) < sizeof(status->gtk[0].key)); in iwl_mvm_gtk_rekey()
2190 for (i = 0; i < ARRAY_SIZE(status->gtk); i++) { in iwl_mvm_gtk_rekey()
2191 if (!status->gtk[i].len) in iwl_mvm_gtk_rekey()
2194 conf.conf.keyidx = status->gtk[i].id; in iwl_mvm_gtk_rekey()
2196 "Received from FW GTK cipher %d, key index %d\n", in iwl_mvm_gtk_rekey()
2198 memcpy(conf.conf.key, status->gtk[i].key, in iwl_mvm_gtk_rekey()
2199 sizeof(status->gtk[i].key)); in iwl_mvm_gtk_rekey()
2201 key = ieee80211_gtk_rekey_add(vif, &conf.conf, link_id); in iwl_mvm_gtk_rekey()
2202 if (IS_ERR(key)) in iwl_mvm_gtk_rekey()
2205 for (j = 0; j < ARRAY_SIZE(status->gtk_seq); j++) { in iwl_mvm_gtk_rekey()
2206 if (!status->gtk_seq[j].valid || in iwl_mvm_gtk_rekey()
2207 status->gtk_seq[j].key_id != key->keyidx) in iwl_mvm_gtk_rekey()
2209 iwl_mvm_set_key_rx_seq_idx(key, status, j); in iwl_mvm_gtk_rekey()
2212 WARN_ON(j == ARRAY_SIZE(status->gtk_seq)); in iwl_mvm_gtk_rekey()
2226 u8 key[WOWLAN_KEY_MAX_SIZE]; in iwl_mvm_d3_igtk_bigtk_rekey_add() member
2229 .conf.keyidx = key_data->id, in iwl_mvm_d3_igtk_bigtk_rekey_add()
2232 int link_id = vif->active_links ? __ffs(vif->active_links) : -1; in iwl_mvm_d3_igtk_bigtk_rekey_add()
2234 if (!key_data->len) in iwl_mvm_d3_igtk_bigtk_rekey_add()
2255 BUILD_BUG_ON(sizeof(conf.key) < sizeof(key_data->key)); in iwl_mvm_d3_igtk_bigtk_rekey_add()
2256 memcpy(conf.conf.key, key_data->key, conf.conf.keylen); in iwl_mvm_d3_igtk_bigtk_rekey_add()
2263 if (key_config->keyidx == 4 || key_config->keyidx == 5) { in iwl_mvm_d3_igtk_bigtk_rekey_add()
2268 mvm_link = mvmvif->link[link_id]; in iwl_mvm_d3_igtk_bigtk_rekey_add()
2269 mvm_link->igtk = key_config; in iwl_mvm_d3_igtk_bigtk_rekey_add()
2279 if (!fw_has_api(&mvm->fw->ucode_capa, in iwl_mvm_lookup_wowlan_status_ver()
2284 notif_ver = iwl_fw_lookup_notif_ver(mvm->fw, LONG_GROUP, in iwl_mvm_lookup_wowlan_status_ver()
2287 notif_ver = iwl_fw_lookup_notif_ver(mvm->fw, LEGACY_GROUP, in iwl_mvm_lookup_wowlan_status_ver()
2307 if (!status || !vif->bss_conf.bssid) in iwl_mvm_setup_connection_keep()
2311 iwl_fw_lookup_notif_ver(mvm->fw, PROT_OFFLOAD_GROUP, in iwl_mvm_setup_connection_keep()
2316 if (iwl_fw_lookup_notif_ver(mvm->fw, PROT_OFFLOAD_GROUP, in iwl_mvm_setup_connection_keep()
2322 ieee80211_iter_keys(mvm->hw, vif, in iwl_mvm_setup_connection_keep()
2334 ieee80211_iter_keys(mvm->hw, vif, in iwl_mvm_setup_connection_keep()
2337 if (status->num_of_gtk_rekeys) { in iwl_mvm_setup_connection_keep()
2338 __be64 replay_ctr = cpu_to_be64(status->replay_ctr); in iwl_mvm_setup_connection_keep()
2341 status->num_of_gtk_rekeys); in iwl_mvm_setup_connection_keep()
2348 &status->igtk)) in iwl_mvm_setup_connection_keep()
2351 for (i = 0; i < ARRAY_SIZE(status->bigtk); i++) { in iwl_mvm_setup_connection_keep()
2354 &status->bigtk[i])) in iwl_mvm_setup_connection_keep()
2361 ieee80211_gtk_rekey_notify(vif, vif->bss_conf.bssid, in iwl_mvm_setup_connection_keep()
2366 if (iwl_fw_lookup_notif_ver(mvm->fw, LONG_GROUP, in iwl_mvm_setup_connection_keep()
2369 mvmvif->seqno_valid = true; in iwl_mvm_setup_connection_keep()
2370 /* +0x10 because the set API expects next-to-use, not last-used */ in iwl_mvm_setup_connection_keep()
2371 mvmvif->seqno = status->non_qos_seq_ctr + 0x10; in iwl_mvm_setup_connection_keep()
2374 if (status->wakeup_reasons & disconnection_reasons) in iwl_mvm_setup_connection_keep()
2383 BUILD_BUG_ON(sizeof(status->gtk[0].key) < sizeof(data->key)); in iwl_mvm_convert_gtk_v2()
2385 sizeof(data->tkip_mic_key) > in iwl_mvm_convert_gtk_v2()
2386 sizeof(status->gtk[0].key)); in iwl_mvm_convert_gtk_v2()
2388 status->gtk[0].len = data->key_len; in iwl_mvm_convert_gtk_v2()
2389 status->gtk[0].flags = data->key_flags; in iwl_mvm_convert_gtk_v2()
2391 memcpy(status->gtk[0].key, data->key, sizeof(data->key)); in iwl_mvm_convert_gtk_v2()
2393 /* if it's as long as the TKIP encryption key, copy MIC key */ in iwl_mvm_convert_gtk_v2()
2394 if (status->gtk[0].len == NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY) in iwl_mvm_convert_gtk_v2()
2395 memcpy(status->gtk[0].key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY, in iwl_mvm_convert_gtk_v2()
2396 data->tkip_mic_key, sizeof(data->tkip_mic_key)); in iwl_mvm_convert_gtk_v2()
2404 BUILD_BUG_ON(sizeof(status->gtk[0].key) < sizeof(data[0].key)); in iwl_mvm_convert_gtk_v3()
2407 sizeof(status->gtk[0].key)); in iwl_mvm_convert_gtk_v3()
2408 BUILD_BUG_ON(ARRAY_SIZE(status->gtk) < WOWLAN_GTK_KEYS_NUM); in iwl_mvm_convert_gtk_v3()
2409 for (data_idx = 0; data_idx < ARRAY_SIZE(status->gtk); data_idx++) { in iwl_mvm_convert_gtk_v3()
2412 status->gtk[status_idx].len = data[data_idx].key_len; in iwl_mvm_convert_gtk_v3()
2413 status->gtk[status_idx].flags = data[data_idx].key_flags; in iwl_mvm_convert_gtk_v3()
2414 status->gtk[status_idx].id = status->gtk[status_idx].flags & in iwl_mvm_convert_gtk_v3()
2417 memcpy(status->gtk[status_idx].key, data[data_idx].key, in iwl_mvm_convert_gtk_v3()
2418 sizeof(data[data_idx].key)); in iwl_mvm_convert_gtk_v3()
2420 /* if it's as long as the TKIP encryption key, copy MIC key */ in iwl_mvm_convert_gtk_v3()
2421 if (status->gtk[status_idx].len == in iwl_mvm_convert_gtk_v3()
2423 memcpy(status->gtk[status_idx].key + in iwl_mvm_convert_gtk_v3()
2436 BUILD_BUG_ON(sizeof(status->igtk.key) < sizeof(data->key)); in iwl_mvm_convert_igtk()
2437 BUILD_BUG_ON(sizeof(status->igtk.ipn) != sizeof(data->ipn)); in iwl_mvm_convert_igtk()
2439 if (!data->key_len) in iwl_mvm_convert_igtk()
2442 status->igtk.len = data->key_len; in iwl_mvm_convert_igtk()
2443 status->igtk.flags = data->key_flags; in iwl_mvm_convert_igtk()
2444 status->igtk.id = u32_get_bits(data->key_flags, in iwl_mvm_convert_igtk()
2448 memcpy(status->igtk.key, data->key, sizeof(data->key)); in iwl_mvm_convert_igtk()
2451 for (i = 0; i < sizeof(data->ipn); i++) in iwl_mvm_convert_igtk()
2452 status->igtk.ipn[i] = data->ipn[sizeof(data->ipn) - i - 1]; in iwl_mvm_convert_igtk()
2460 BUILD_BUG_ON(ARRAY_SIZE(status->bigtk) < WOWLAN_BIGTK_KEYS_NUM); in iwl_mvm_convert_bigtk()
2466 status->bigtk[status_idx].len = data[data_idx].key_len; in iwl_mvm_convert_bigtk()
2467 status->bigtk[status_idx].flags = data[data_idx].key_flags; in iwl_mvm_convert_bigtk()
2468 status->bigtk[status_idx].id = in iwl_mvm_convert_bigtk()
2473 BUILD_BUG_ON(sizeof(status->bigtk[status_idx].key) < in iwl_mvm_convert_bigtk()
2474 sizeof(data[data_idx].key)); in iwl_mvm_convert_bigtk()
2475 BUILD_BUG_ON(sizeof(status->bigtk[status_idx].ipn) < in iwl_mvm_convert_bigtk()
2478 memcpy(status->bigtk[status_idx].key, data[data_idx].key, in iwl_mvm_convert_bigtk()
2479 sizeof(data[data_idx].key)); in iwl_mvm_convert_bigtk()
2480 memcpy(status->bigtk[status_idx].ipn, data[data_idx].ipn, in iwl_mvm_convert_bigtk()
2492 data->num_mlo_link_keys * sizeof(status->mlo_keys[0]); in iwl_mvm_parse_wowlan_info_notif()
2500 if (mvm->fast_resume) in iwl_mvm_parse_wowlan_info_notif()
2503 iwl_mvm_convert_key_counters_v5(status, &data->gtk[0].sc); in iwl_mvm_parse_wowlan_info_notif()
2504 iwl_mvm_convert_gtk_v3(status, data->gtk); in iwl_mvm_parse_wowlan_info_notif()
2505 iwl_mvm_convert_igtk(status, &data->igtk[0]); in iwl_mvm_parse_wowlan_info_notif()
2506 iwl_mvm_convert_bigtk(status, data->bigtk); in iwl_mvm_parse_wowlan_info_notif()
2507 status->replay_ctr = le64_to_cpu(data->replay_ctr); in iwl_mvm_parse_wowlan_info_notif()
2508 status->pattern_number = le16_to_cpu(data->pattern_number); in iwl_mvm_parse_wowlan_info_notif()
2509 status->tid_offloaded_tx = data->tid_offloaded_tx; in iwl_mvm_parse_wowlan_info_notif()
2511 data->tid_offloaded_tx >= in iwl_mvm_parse_wowlan_info_notif()
2512 ARRAY_SIZE(status->qos_seq_ctr), in iwl_mvm_parse_wowlan_info_notif()
2514 data->tid_offloaded_tx)) in iwl_mvm_parse_wowlan_info_notif()
2515 data->tid_offloaded_tx = 0; in iwl_mvm_parse_wowlan_info_notif()
2516 status->qos_seq_ctr[data->tid_offloaded_tx] = in iwl_mvm_parse_wowlan_info_notif()
2517 le16_to_cpu(data->qos_seq_ctr); in iwl_mvm_parse_wowlan_info_notif()
2518 status->wakeup_reasons = le32_to_cpu(data->wakeup_reasons); in iwl_mvm_parse_wowlan_info_notif()
2519 status->num_of_gtk_rekeys = in iwl_mvm_parse_wowlan_info_notif()
2520 le32_to_cpu(data->num_of_gtk_rekeys); in iwl_mvm_parse_wowlan_info_notif()
2521 status->received_beacons = le32_to_cpu(data->received_beacons); in iwl_mvm_parse_wowlan_info_notif()
2522 status->tid_tear_down = data->tid_tear_down; in iwl_mvm_parse_wowlan_info_notif()
2524 if (data->num_mlo_link_keys) { in iwl_mvm_parse_wowlan_info_notif()
2525 status->num_mlo_keys = data->num_mlo_link_keys; in iwl_mvm_parse_wowlan_info_notif()
2527 status->num_mlo_keys > WOWLAN_MAX_MLO_KEYS, in iwl_mvm_parse_wowlan_info_notif()
2529 status->num_mlo_keys, WOWLAN_MAX_MLO_KEYS)) in iwl_mvm_parse_wowlan_info_notif()
2530 status->num_mlo_keys = WOWLAN_MAX_MLO_KEYS; in iwl_mvm_parse_wowlan_info_notif()
2531 memcpy(status->mlo_keys, data->mlo_gtks, in iwl_mvm_parse_wowlan_info_notif()
2532 status->num_mlo_keys * sizeof(status->mlo_keys[0])); in iwl_mvm_parse_wowlan_info_notif()
2546 expected_len += (data->num_mlo_link_keys * in iwl_mvm_parse_wowlan_info_notif_v4()
2547 sizeof(status->mlo_keys[0])); in iwl_mvm_parse_wowlan_info_notif_v4()
2555 if (mvm->fast_resume) in iwl_mvm_parse_wowlan_info_notif_v4()
2558 iwl_mvm_convert_key_counters_v5(status, &data->gtk[0].sc); in iwl_mvm_parse_wowlan_info_notif_v4()
2559 iwl_mvm_convert_gtk_v3(status, data->gtk); in iwl_mvm_parse_wowlan_info_notif_v4()
2560 iwl_mvm_convert_igtk(status, &data->igtk[0]); in iwl_mvm_parse_wowlan_info_notif_v4()
2561 iwl_mvm_convert_bigtk(status, data->bigtk); in iwl_mvm_parse_wowlan_info_notif_v4()
2562 status->replay_ctr = le64_to_cpu(data->replay_ctr); in iwl_mvm_parse_wowlan_info_notif_v4()
2563 status->pattern_number = le16_to_cpu(data->pattern_number); in iwl_mvm_parse_wowlan_info_notif_v4()
2565 status->qos_seq_ctr[i] = in iwl_mvm_parse_wowlan_info_notif_v4()
2566 le16_to_cpu(data->qos_seq_ctr[i]); in iwl_mvm_parse_wowlan_info_notif_v4()
2567 status->wakeup_reasons = le32_to_cpu(data->wakeup_reasons); in iwl_mvm_parse_wowlan_info_notif_v4()
2568 status->num_of_gtk_rekeys = in iwl_mvm_parse_wowlan_info_notif_v4()
2569 le32_to_cpu(data->num_of_gtk_rekeys); in iwl_mvm_parse_wowlan_info_notif_v4()
2570 status->received_beacons = le32_to_cpu(data->received_beacons); in iwl_mvm_parse_wowlan_info_notif_v4()
2571 status->tid_tear_down = data->tid_tear_down; in iwl_mvm_parse_wowlan_info_notif_v4()
2573 if (has_mlo_keys && data->num_mlo_link_keys) { in iwl_mvm_parse_wowlan_info_notif_v4()
2574 status->num_mlo_keys = data->num_mlo_link_keys; in iwl_mvm_parse_wowlan_info_notif_v4()
2576 status->num_mlo_keys > WOWLAN_MAX_MLO_KEYS, in iwl_mvm_parse_wowlan_info_notif_v4()
2578 status->num_mlo_keys, WOWLAN_MAX_MLO_KEYS)) in iwl_mvm_parse_wowlan_info_notif_v4()
2579 status->num_mlo_keys = WOWLAN_MAX_MLO_KEYS; in iwl_mvm_parse_wowlan_info_notif_v4()
2580 memcpy(status->mlo_keys, data->mlo_gtks, in iwl_mvm_parse_wowlan_info_notif_v4()
2581 status->num_mlo_keys * sizeof(status->mlo_keys[0])); in iwl_mvm_parse_wowlan_info_notif_v4()
2599 iwl_mvm_convert_key_counters_v5(status, &data->gtk[0].sc); in iwl_mvm_parse_wowlan_info_notif_v2()
2600 iwl_mvm_convert_gtk_v3(status, data->gtk); in iwl_mvm_parse_wowlan_info_notif_v2()
2601 iwl_mvm_convert_igtk(status, &data->igtk[0]); in iwl_mvm_parse_wowlan_info_notif_v2()
2602 status->replay_ctr = le64_to_cpu(data->replay_ctr); in iwl_mvm_parse_wowlan_info_notif_v2()
2603 status->pattern_number = le16_to_cpu(data->pattern_number); in iwl_mvm_parse_wowlan_info_notif_v2()
2605 status->qos_seq_ctr[i] = in iwl_mvm_parse_wowlan_info_notif_v2()
2606 le16_to_cpu(data->qos_seq_ctr[i]); in iwl_mvm_parse_wowlan_info_notif_v2()
2607 status->wakeup_reasons = le32_to_cpu(data->wakeup_reasons); in iwl_mvm_parse_wowlan_info_notif_v2()
2608 status->num_of_gtk_rekeys = in iwl_mvm_parse_wowlan_info_notif_v2()
2609 le32_to_cpu(data->num_of_gtk_rekeys); in iwl_mvm_parse_wowlan_info_notif_v2()
2610 status->received_beacons = le32_to_cpu(data->received_beacons); in iwl_mvm_parse_wowlan_info_notif_v2()
2611 status->tid_tear_down = data->tid_tear_down; in iwl_mvm_parse_wowlan_info_notif_v2()
2629 data_size = ALIGN(le32_to_cpu(data->wake_packet_bufsize), 4); \
2640 status->replay_ctr = le64_to_cpu(data->replay_ctr); \
2641 status->pattern_number = le16_to_cpu(data->pattern_number); \
2642 status->non_qos_seq_ctr = le16_to_cpu(data->non_qos_seq_ctr); \
2644 status->qos_seq_ctr[i] = \
2645 le16_to_cpu(data->qos_seq_ctr[i]); \
2646 status->wakeup_reasons = le32_to_cpu(data->wakeup_reasons); \
2647 status->num_of_gtk_rekeys = \
2648 le32_to_cpu(data->num_of_gtk_rekeys); \
2649 status->received_beacons = le32_to_cpu(data->received_beacons); \
2650 status->wake_packet_length = \
2651 le32_to_cpu(data->wake_packet_length); \
2652 status->wake_packet_bufsize = \
2653 le32_to_cpu(data->wake_packet_bufsize); \
2654 if (status->wake_packet_bufsize) { \
2655 status->wake_packet = \
2656 kmemdup(data->wake_packet, \
2657 status->wake_packet_bufsize, \
2659 if (!status->wake_packet) { \
2664 status->wake_packet = NULL; \
2690 u8 cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, cmd.id, in iwl_mvm_parse_wowlan_status_common()
2696 lockdep_assert_held(&mvm->mutex); in iwl_mvm_parse_wowlan_status_common()
2700 IWL_ERR(mvm, "failed to query wakeup status (%d)\n", ret); in iwl_mvm_parse_wowlan_status_common()
2710 struct iwl_wowlan_status_v6 *v6 = (void *)cmd.resp_pkt->data; in iwl_mvm_parse_wowlan_status_common()
2716 BUILD_BUG_ON(sizeof(v6->gtk.decrypt_key) > in iwl_mvm_parse_wowlan_status_common()
2717 sizeof(status->gtk[0].key)); in iwl_mvm_parse_wowlan_status_common()
2719 sizeof(v6->gtk.tkip_mic_key) > in iwl_mvm_parse_wowlan_status_common()
2720 sizeof(status->gtk[0].key)); in iwl_mvm_parse_wowlan_status_common()
2723 memcpy(status->gtk[0].key, v6->gtk.decrypt_key, in iwl_mvm_parse_wowlan_status_common()
2724 sizeof(v6->gtk.decrypt_key)); in iwl_mvm_parse_wowlan_status_common()
2725 memcpy(status->gtk[0].key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY, in iwl_mvm_parse_wowlan_status_common()
2726 v6->gtk.tkip_mic_key, in iwl_mvm_parse_wowlan_status_common()
2727 sizeof(v6->gtk.tkip_mic_key)); in iwl_mvm_parse_wowlan_status_common()
2729 iwl_mvm_convert_key_counters(status, &v6->gtk.rsc.all_tsc_rsc); in iwl_mvm_parse_wowlan_status_common()
2731 /* hardcode the key length to 16 since v6 only supports 16 */ in iwl_mvm_parse_wowlan_status_common()
2732 status->gtk[0].len = 16; in iwl_mvm_parse_wowlan_status_common()
2735 * The key index only uses 2 bits (values 0 to 3) and in iwl_mvm_parse_wowlan_status_common()
2737 * currently used key. in iwl_mvm_parse_wowlan_status_common()
2739 status->gtk[0].flags = v6->gtk.key_index | BIT(7); in iwl_mvm_parse_wowlan_status_common()
2741 struct iwl_wowlan_status_v7 *v7 = (void *)cmd.resp_pkt->data; in iwl_mvm_parse_wowlan_status_common()
2747 iwl_mvm_convert_key_counters(status, &v7->gtk[0].rsc.all_tsc_rsc); in iwl_mvm_parse_wowlan_status_common()
2748 iwl_mvm_convert_gtk_v2(status, &v7->gtk[0]); in iwl_mvm_parse_wowlan_status_common()
2749 iwl_mvm_convert_igtk(status, &v7->igtk[0]); in iwl_mvm_parse_wowlan_status_common()
2751 struct iwl_wowlan_status_v9 *v9 = (void *)cmd.resp_pkt->data; in iwl_mvm_parse_wowlan_status_common()
2760 iwl_mvm_convert_key_counters(status, &v9->gtk[0].rsc.all_tsc_rsc); in iwl_mvm_parse_wowlan_status_common()
2761 iwl_mvm_convert_gtk_v2(status, &v9->gtk[0]); in iwl_mvm_parse_wowlan_status_common()
2762 iwl_mvm_convert_igtk(status, &v9->igtk[0]); in iwl_mvm_parse_wowlan_status_common()
2764 status->tid_tear_down = v9->tid_tear_down; in iwl_mvm_parse_wowlan_status_common()
2766 struct iwl_wowlan_status_v12 *v12 = (void *)cmd.resp_pkt->data; in iwl_mvm_parse_wowlan_status_common()
2772 iwl_mvm_convert_key_counters_v5(status, &v12->gtk[0].sc); in iwl_mvm_parse_wowlan_status_common()
2773 iwl_mvm_convert_gtk_v3(status, v12->gtk); in iwl_mvm_parse_wowlan_status_common()
2774 iwl_mvm_convert_igtk(status, &v12->igtk[0]); in iwl_mvm_parse_wowlan_status_common()
2776 status->tid_tear_down = v12->tid_tear_down; in iwl_mvm_parse_wowlan_status_common()
2798 int link_id = vif->active_links ? __ffs(vif->active_links) : 0; in iwl_mvm_query_wakeup_reasons()
2799 struct iwl_mvm_vif_link_info *mvm_link = mvmvif->link[link_id]; in iwl_mvm_query_wakeup_reasons()
2800 int wowlan_info_ver = iwl_fw_lookup_notif_ver(mvm->fw, in iwl_mvm_query_wakeup_reasons()
2811 IWL_DEBUG_WOWLAN(mvm, "wakeup reason 0x%x\n", in iwl_mvm_query_wakeup_reasons()
2812 status->wakeup_reasons); in iwl_mvm_query_wakeup_reasons()
2814 mvm_ap_sta = iwl_mvm_sta_from_staid_protected(mvm, mvm_link->ap_sta_id); in iwl_mvm_query_wakeup_reasons()
2818 /* firmware stores last-used value, we store next value */ in iwl_mvm_query_wakeup_reasons()
2820 mvm_ap_sta->tid_data[status->tid_offloaded_tx].seq_number = in iwl_mvm_query_wakeup_reasons()
2821 status->qos_seq_ctr[status->tid_offloaded_tx] + 0x10; in iwl_mvm_query_wakeup_reasons()
2824 mvm_ap_sta->tid_data[i].seq_number = in iwl_mvm_query_wakeup_reasons()
2825 status->qos_seq_ctr[i] + 0x10; in iwl_mvm_query_wakeup_reasons()
2828 if (mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22000) { in iwl_mvm_query_wakeup_reasons()
2829 i = mvm->offload_tid; in iwl_mvm_query_wakeup_reasons()
2830 iwl_trans_set_q_ptrs(mvm->trans, in iwl_mvm_query_wakeup_reasons()
2831 mvm_ap_sta->tid_data[i].txq_id, in iwl_mvm_query_wakeup_reasons()
2832 mvm_ap_sta->tid_data[i].seq_number >> 4); in iwl_mvm_query_wakeup_reasons()
2839 mutex_unlock(&mvm->mutex); in iwl_mvm_query_wakeup_reasons()
2862 int max_profiles = iwl_umac_scan_get_max_profiles(mvm->fw); in iwl_mvm_netdetect_query_results()
2870 if (fw_has_api(&mvm->fw->ucode_capa, in iwl_mvm_netdetect_query_results()
2884 ret = -EIO; in iwl_mvm_netdetect_query_results()
2888 query = (void *)cmd.resp_pkt->data; in iwl_mvm_netdetect_query_results()
2890 results->matched_profiles = le32_to_cpu(query->matched_profiles); in iwl_mvm_netdetect_query_results()
2891 memcpy(results->matches, query->matches, matches_len); in iwl_mvm_netdetect_query_results()
2894 mvm->last_netdetect_scans = le32_to_cpu(query->n_scans_done); in iwl_mvm_netdetect_query_results()
2908 if (fw_has_api(&mvm->fw->ucode_capa, in iwl_mvm_query_num_match_chans()
2911 (void *)results->matches; in iwl_mvm_query_num_match_chans()
2917 (void *)results->matches; in iwl_mvm_query_num_match_chans()
2934 if (fw_has_api(&mvm->fw->ucode_capa, in iwl_mvm_query_set_freqs()
2937 (void *)results->matches; in iwl_mvm_query_set_freqs()
2941 match->channels[n_channels++] = in iwl_mvm_query_set_freqs()
2942 mvm->nd_channels[i]->center_freq; in iwl_mvm_query_set_freqs()
2945 (void *)results->matches; in iwl_mvm_query_set_freqs()
2949 match->channels[n_channels++] = in iwl_mvm_query_set_freqs()
2950 mvm->nd_channels[i]->center_freq; in iwl_mvm_query_set_freqs()
2953 match->n_channels = n_channels; in iwl_mvm_query_set_freqs()
2957 * enum iwl_d3_notif - d3 notifications
2977 u32 notif_expected; /* bitmap - see &enum iwl_d3_notif */
2978 u32 notif_received; /* bitmap - see &enum iwl_d3_notif */
2988 struct cfg80211_wowlan_wakeup wakeup = { in iwl_mvm_query_netdetect_reasons() local
2989 .pattern_idx = -1, in iwl_mvm_query_netdetect_reasons()
2991 struct cfg80211_wowlan_wakeup *wakeup_report = &wakeup; in iwl_mvm_query_netdetect_reasons()
2996 if (WARN_ON(!d3_data || !d3_data->status)) in iwl_mvm_query_netdetect_reasons()
2999 reasons = d3_data->status->wakeup_reasons; in iwl_mvm_query_netdetect_reasons()
3002 wakeup.rfkill_release = true; in iwl_mvm_query_netdetect_reasons()
3007 if (!iwl_fw_lookup_notif_ver(mvm->fw, PROT_OFFLOAD_GROUP, in iwl_mvm_query_netdetect_reasons()
3010 ret = iwl_mvm_netdetect_query_results(mvm, d3_data->nd_results); in iwl_mvm_query_netdetect_reasons()
3014 ret = d3_data->nd_results_valid ? 0 : -1; in iwl_mvm_query_netdetect_reasons()
3017 if (ret || !d3_data->nd_results->matched_profiles) { in iwl_mvm_query_netdetect_reasons()
3022 matched_profiles = d3_data->nd_results->matched_profiles; in iwl_mvm_query_netdetect_reasons()
3023 if (mvm->n_nd_match_sets) { in iwl_mvm_query_netdetect_reasons()
3034 net_detect->n_matches = n_matches; in iwl_mvm_query_netdetect_reasons()
3037 for_each_set_bit(i, &matched_profiles, mvm->n_nd_match_sets) { in iwl_mvm_query_netdetect_reasons()
3042 d3_data->nd_results, in iwl_mvm_query_netdetect_reasons()
3049 match->n_channels = n_channels; in iwl_mvm_query_netdetect_reasons()
3051 net_detect->matches[n_matches++] = match; in iwl_mvm_query_netdetect_reasons()
3056 idx = mvm->n_nd_match_sets - i - 1; in iwl_mvm_query_netdetect_reasons()
3057 match->ssid.ssid_len = mvm->nd_match_sets[idx].ssid.ssid_len; in iwl_mvm_query_netdetect_reasons()
3058 memcpy(match->ssid.ssid, mvm->nd_match_sets[idx].ssid.ssid, in iwl_mvm_query_netdetect_reasons()
3059 match->ssid.ssid_len); in iwl_mvm_query_netdetect_reasons()
3061 if (mvm->n_nd_channels < n_channels) in iwl_mvm_query_netdetect_reasons()
3064 iwl_mvm_query_set_freqs(mvm, d3_data->nd_results, match, i); in iwl_mvm_query_netdetect_reasons()
3067 net_detect->n_matches = n_matches; in iwl_mvm_query_netdetect_reasons()
3070 wakeup.net_detect = net_detect; in iwl_mvm_query_netdetect_reasons()
3074 mutex_unlock(&mvm->mutex); in iwl_mvm_query_netdetect_reasons()
3078 for (i = 0; i < net_detect->n_matches; i++) in iwl_mvm_query_netdetect_reasons()
3079 kfree(net_detect->matches[i]); in iwl_mvm_query_netdetect_reasons()
3091 if (vif->type == NL80211_IFTYPE_STATION) in iwl_mvm_d3_disconnect_iter()
3107 if (iwl_fwrt_read_err_table(mvm->trans, in iwl_mvm_check_rt_status()
3108 mvm->trans->dbg.lmac_error_event_table[0], in iwl_mvm_check_rt_status()
3113 struct cfg80211_wowlan_wakeup wakeup = { in iwl_mvm_check_rt_status() local
3117 ieee80211_report_wowlan_wakeup(vif, &wakeup, in iwl_mvm_check_rt_status()
3127 if (iwl_fwrt_read_err_table(mvm->trans, in iwl_mvm_check_rt_status()
3128 mvm->trans->dbg.lmac_error_event_table[1], in iwl_mvm_check_rt_status()
3133 if (iwl_fwrt_read_err_table(mvm->trans, in iwl_mvm_check_rt_status()
3134 mvm->trans->dbg.umac_error_event_table, in iwl_mvm_check_rt_status()
3151 lockdep_assert_held(&mvm->mutex); in iwl_mvm_choose_query_wakeup_reasons()
3154 if (!d3_data->status) { in iwl_mvm_choose_query_wakeup_reasons()
3156 u8 sta_id = mvm->net_detect ? IWL_INVALID_STA : in iwl_mvm_choose_query_wakeup_reasons()
3157 mvmvif->deflink.ap_sta_id; in iwl_mvm_choose_query_wakeup_reasons()
3159 /* bug - FW with MLO has status notification */ in iwl_mvm_choose_query_wakeup_reasons()
3162 d3_data->status = iwl_mvm_send_wowlan_get_status(mvm, sta_id); in iwl_mvm_choose_query_wakeup_reasons()
3165 if (mvm->net_detect) { in iwl_mvm_choose_query_wakeup_reasons()
3169 d3_data->status); in iwl_mvm_choose_query_wakeup_reasons()
3173 mvm->keep_vif = vif; in iwl_mvm_choose_query_wakeup_reasons()
3193 u32 data_size, packet_len = le32_to_cpu(notif->wake_packet_length); in iwl_mvm_wowlan_store_wake_pkt()
3197 return -EIO; in iwl_mvm_wowlan_store_wake_pkt()
3202 return -EIO; in iwl_mvm_wowlan_store_wake_pkt()
3205 if (WARN_ON(!(status->wakeup_reasons & in iwl_mvm_wowlan_store_wake_pkt()
3207 IWL_ERR(mvm, "Got wakeup packet but wakeup reason is %x\n", in iwl_mvm_wowlan_store_wake_pkt()
3208 status->wakeup_reasons); in iwl_mvm_wowlan_store_wake_pkt()
3209 return -EIO; in iwl_mvm_wowlan_store_wake_pkt()
3212 data_size = len - offsetof(struct iwl_wowlan_wake_pkt_notif, wake_packet); in iwl_mvm_wowlan_store_wake_pkt()
3218 status->wake_packet = kmemdup(notif->wake_packet, data_size, in iwl_mvm_wowlan_store_wake_pkt()
3221 if (!status->wake_packet) in iwl_mvm_wowlan_store_wake_pkt()
3222 return -ENOMEM; in iwl_mvm_wowlan_store_wake_pkt()
3224 status->wake_packet_length = packet_len; in iwl_mvm_wowlan_store_wake_pkt()
3225 status->wake_packet_bufsize = data_size; in iwl_mvm_wowlan_store_wake_pkt()
3235 struct iwl_wowlan_status_data *status = d3_data->status; in iwl_mvm_nd_match_info_handler()
3237 struct iwl_mvm_nd_results *results = d3_data->nd_results; in iwl_mvm_nd_match_info_handler()
3239 iwl_umac_scan_get_max_profiles(mvm->fw); in iwl_mvm_nd_match_info_handler()
3249 if (!mvm->net_detect) { in iwl_mvm_nd_match_info_handler()
3254 if (!status || status->wakeup_reasons != IWL_WOWLAN_WAKEUP_BY_NON_WIRELESS) { in iwl_mvm_nd_match_info_handler()
3261 mvm->last_netdetect_scans = le32_to_cpu(notif->n_scans_done); in iwl_mvm_nd_match_info_handler()
3264 results->matched_profiles = le32_to_cpu(notif->matched_profiles); in iwl_mvm_nd_match_info_handler()
3266 results->matched_profiles); in iwl_mvm_nd_match_info_handler()
3268 if (results->matched_profiles) { in iwl_mvm_nd_match_info_handler()
3269 memcpy(results->matches, notif->matches, matches_len); in iwl_mvm_nd_match_info_handler()
3270 d3_data->nd_results_valid = true; in iwl_mvm_nd_match_info_handler()
3274 mvm->scan_status = 0; in iwl_mvm_nd_match_info_handler()
3275 for (i = 0; i < mvm->max_scans; i++) in iwl_mvm_nd_match_info_handler()
3276 mvm->scan_uid_status[i] = 0; in iwl_mvm_nd_match_info_handler()
3287 int wowlan_info_ver = iwl_fw_lookup_notif_ver(mvm->fw, in iwl_mvm_wait_d3_notif()
3293 switch (WIDE_ID(pkt->hdr.group_id, pkt->hdr.cmd)) { in iwl_mvm_wait_d3_notif()
3296 if (d3_data->notif_received & IWL_D3_NOTIF_WOWLAN_INFO) { in iwl_mvm_wait_d3_notif()
3305 (void *)pkt->data; in iwl_mvm_wait_d3_notif()
3313 notif_v2->tid_tear_down = notif_v1->tid_tear_down; in iwl_mvm_wait_d3_notif()
3314 notif_v2->station_id = notif_v1->station_id; in iwl_mvm_wait_d3_notif()
3317 d3_data->status, in iwl_mvm_wait_d3_notif()
3323 (void *)pkt->data; in iwl_mvm_wait_d3_notif()
3326 d3_data->status, in iwl_mvm_wait_d3_notif()
3330 (void *)pkt->data; in iwl_mvm_wait_d3_notif()
3333 d3_data->status, len, in iwl_mvm_wait_d3_notif()
3337 (void *)pkt->data; in iwl_mvm_wait_d3_notif()
3340 d3_data->status, len); in iwl_mvm_wait_d3_notif()
3343 d3_data->notif_received |= IWL_D3_NOTIF_WOWLAN_INFO; in iwl_mvm_wait_d3_notif()
3345 if (d3_data->status && in iwl_mvm_wait_d3_notif()
3346 d3_data->status->wakeup_reasons & IWL_WOWLAN_WAKEUP_REASON_HAS_WAKEUP_PKT) in iwl_mvm_wait_d3_notif()
3348 d3_data->notif_expected |= IWL_D3_NOTIF_WOWLAN_WAKE_PKT; in iwl_mvm_wait_d3_notif()
3353 struct iwl_wowlan_wake_pkt_notif *notif = (void *)pkt->data; in iwl_mvm_wait_d3_notif()
3355 if (d3_data->notif_received & IWL_D3_NOTIF_WOWLAN_WAKE_PKT) { in iwl_mvm_wait_d3_notif()
3360 d3_data->notif_received |= IWL_D3_NOTIF_WOWLAN_WAKE_PKT; in iwl_mvm_wait_d3_notif()
3363 d3_data->status, in iwl_mvm_wait_d3_notif()
3373 struct iwl_scan_offload_match_info *notif = (void *)pkt->data; in iwl_mvm_wait_d3_notif()
3375 if (d3_data->notif_received & IWL_D3_ND_MATCH_INFO) { in iwl_mvm_wait_d3_notif()
3381 d3_data->notif_received |= IWL_D3_ND_MATCH_INFO; in iwl_mvm_wait_d3_notif()
3384 d3_data->notif_expected |= IWL_D3_ND_MATCH_INFO; in iwl_mvm_wait_d3_notif()
3391 struct iwl_d3_end_notif *notif = (void *)pkt->data; in iwl_mvm_wait_d3_notif()
3393 d3_data->d3_end_flags = __le32_to_cpu(notif->flags); in iwl_mvm_wait_d3_notif()
3394 d3_data->notif_received |= IWL_D3_NOTIF_D3_END_NOTIF; in iwl_mvm_wait_d3_notif()
3402 return d3_data->notif_received == d3_data->notif_expected; in iwl_mvm_wait_d3_notif()
3413 bool reset = fw_has_capa(&mvm->fw->ucode_capa, in iwl_mvm_resume_firmware()
3416 ret = iwl_trans_d3_resume(mvm->trans, &d3_status, test, !reset); in iwl_mvm_resume_firmware()
3422 return -ENOENT; in iwl_mvm_resume_firmware()
3430 if (mvm->trans->trans_cfg->device_family <= IWL_DEVICE_FAMILY_22000 && in iwl_mvm_resume_firmware()
3431 fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_D0I3_END_FIRST)) { in iwl_mvm_resume_firmware()
3458 if (mvm->fast_resume) in iwl_mvm_d3_notif_wait()
3459 iwl_init_notification_wait(&mvm->notif_wait, &wait_d3_notif, in iwl_mvm_d3_notif_wait()
3464 iwl_init_notification_wait(&mvm->notif_wait, &wait_d3_notif, in iwl_mvm_d3_notif_wait()
3469 ret = iwl_mvm_resume_firmware(mvm, d3_data->test); in iwl_mvm_d3_notif_wait()
3471 iwl_remove_notification(&mvm->notif_wait, &wait_d3_notif); in iwl_mvm_d3_notif_wait()
3475 return iwl_wait_notification(&mvm->notif_wait, &wait_d3_notif, in iwl_mvm_d3_notif_wait()
3481 return iwl_fw_lookup_notif_ver(mvm->fw, PROT_OFFLOAD_GROUP, in iwl_mvm_d3_resume_notif_based()
3483 iwl_fw_lookup_notif_ver(mvm->fw, PROT_OFFLOAD_GROUP, in iwl_mvm_d3_resume_notif_based()
3485 iwl_fw_lookup_notif_ver(mvm->fw, PROT_OFFLOAD_GROUP, in iwl_mvm_d3_resume_notif_based()
3502 bool unified_image = fw_has_capa(&mvm->fw->ucode_capa, in __iwl_mvm_resume()
3504 bool d0i3_first = fw_has_capa(&mvm->fw->ucode_capa, in __iwl_mvm_resume()
3510 mutex_lock(&mvm->mutex); in __iwl_mvm_resume()
3516 if (!test_bit(IWL_MVM_STATUS_IN_D3, &mvm->status)) { in __iwl_mvm_resume()
3522 mvm->last_reset_or_resume_time_jiffies = jiffies; in __iwl_mvm_resume()
3529 iwl_fw_dbg_read_d3_debug_data(&mvm->fwrt); in __iwl_mvm_resume()
3533 set_bit(STATUS_FW_ERROR, &mvm->trans->status); in __iwl_mvm_resume()
3537 iwl_dbg_tlv_time_point(&mvm->fwrt, in __iwl_mvm_resume()
3540 iwl_fw_dbg_collect_desc(&mvm->fwrt, in __iwl_mvm_resume()
3552 ret = -ENOMEM; in __iwl_mvm_resume()
3568 mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_DISABLED; in __iwl_mvm_resume()
3576 * can play it back when we re-intiailize the D0 firmware in __iwl_mvm_resume()
3580 /* Re-configure PPAG settings */ in __iwl_mvm_resume()
3584 /* Re-configure default SAR profile */ in __iwl_mvm_resume()
3587 if (mvm->net_detect && unified_image) { in __iwl_mvm_resume()
3588 /* If this is a non-unified image, we restart the FW, in __iwl_mvm_resume()
3590 * fails, continue and try to get the wake-up reasons, in __iwl_mvm_resume()
3604 mutex_unlock(&mvm->mutex); in __iwl_mvm_resume()
3607 kfree(d3_data.status->wake_packet); in __iwl_mvm_resume()
3611 if (!d3_data.test && !mvm->net_detect) in __iwl_mvm_resume()
3612 ieee80211_iterate_active_interfaces_mtx(mvm->hw, in __iwl_mvm_resume()
3617 clear_bit(IWL_MVM_STATUS_IN_D3, &mvm->status); in __iwl_mvm_resume()
3625 if (!iwl_fw_lookup_notif_ver(mvm->fw, PROT_OFFLOAD_GROUP, in __iwl_mvm_resume()
3640 set_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, &mvm->status); in __iwl_mvm_resume()
3643 mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_DISABLED; in __iwl_mvm_resume()
3657 iwl_fw_runtime_resume(&mvm->fwrt); in iwl_mvm_resume()
3666 device_set_wakeup_enable(mvm->trans->dev, enabled); in iwl_mvm_set_wakeup()
3674 lockdep_assert_held(&mvm->mutex); in iwl_mvm_fast_suspend()
3678 mvm->fast_resume = true; in iwl_mvm_fast_suspend()
3679 set_bit(IWL_MVM_STATUS_IN_D3, &mvm->status); in iwl_mvm_fast_suspend()
3682 mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_D3; in iwl_mvm_fast_suspend()
3689 ret = iwl_trans_d3_suspend(mvm->trans, false, false); in iwl_mvm_fast_suspend()
3703 lockdep_assert_held(&mvm->mutex); in iwl_mvm_fast_resume()
3707 mvm->last_reset_or_resume_time_jiffies = jiffies; in iwl_mvm_fast_resume()
3708 iwl_fw_dbg_read_d3_debug_data(&mvm->fwrt); in iwl_mvm_fast_resume()
3712 set_bit(STATUS_FW_ERROR, &mvm->trans->status); in iwl_mvm_fast_resume()
3717 iwl_dbg_tlv_time_point(&mvm->fwrt, in iwl_mvm_fast_resume()
3720 iwl_fw_dbg_collect_desc(&mvm->fwrt, in iwl_mvm_fast_resume()
3724 mvm->trans->state = IWL_TRANS_NO_FW; in iwl_mvm_fast_resume()
3725 ret = -ENODEV; in iwl_mvm_fast_resume()
3733 mvm->trans->state = IWL_TRANS_NO_FW; in iwl_mvm_fast_resume()
3737 clear_bit(IWL_MVM_STATUS_IN_D3, &mvm->status); in iwl_mvm_fast_resume()
3738 mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_DISABLED; in iwl_mvm_fast_resume()
3739 mvm->fast_resume = false; in iwl_mvm_fast_resume()
3747 struct iwl_mvm *mvm = inode->i_private; in iwl_mvm_d3_test_open()
3750 if (mvm->d3_test_active) in iwl_mvm_d3_test_open()
3751 return -EBUSY; in iwl_mvm_d3_test_open()
3753 file->private_data = inode->i_private; in iwl_mvm_d3_test_open()
3757 iwl_fw_runtime_suspend(&mvm->fwrt); in iwl_mvm_d3_test_open()
3761 wiphy_lock(mvm->hw->wiphy); in iwl_mvm_d3_test_open()
3762 err = __iwl_mvm_suspend(mvm->hw, mvm->hw->wiphy->wowlan_config, true); in iwl_mvm_d3_test_open()
3763 wiphy_unlock(mvm->hw->wiphy); in iwl_mvm_d3_test_open()
3766 err = -EINVAL; in iwl_mvm_d3_test_open()
3770 mvm->d3_test_active = true; in iwl_mvm_d3_test_open()
3771 mvm->keep_vif = NULL; in iwl_mvm_d3_test_open()
3778 struct iwl_mvm *mvm = file->private_data; in iwl_mvm_d3_test_read()
3784 if (mvm->d3_test_pme_ptr) { in iwl_mvm_d3_test_read()
3785 pme_asserted = iwl_trans_read_mem32(mvm->trans, in iwl_mvm_d3_test_read()
3786 mvm->d3_test_pme_ptr); in iwl_mvm_d3_test_read()
3796 "ending pseudo-D3 with timeout after ~60 seconds\n"); in iwl_mvm_d3_test_read()
3797 return -ETIMEDOUT; in iwl_mvm_d3_test_read()
3811 if (vif->type == NL80211_IFTYPE_STATION) in iwl_mvm_d3_test_disconn_work_iter()
3817 struct iwl_mvm *mvm = inode->i_private; in iwl_mvm_d3_test_release()
3818 bool unified_image = fw_has_capa(&mvm->fw->ucode_capa, in iwl_mvm_d3_test_release()
3821 mvm->d3_test_active = false; in iwl_mvm_d3_test_release()
3823 iwl_fw_dbg_read_d3_debug_data(&mvm->fwrt); in iwl_mvm_d3_test_release()
3826 wiphy_lock(mvm->hw->wiphy); in iwl_mvm_d3_test_release()
3828 wiphy_unlock(mvm->hw->wiphy); in iwl_mvm_d3_test_release()
3833 iwl_fw_runtime_resume(&mvm->fwrt); in iwl_mvm_d3_test_release()
3835 iwl_abort_notification_waits(&mvm->notif_wait); in iwl_mvm_d3_test_release()
3839 ieee80211_restart_hw(mvm->hw); in iwl_mvm_d3_test_release()
3842 while (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) && in iwl_mvm_d3_test_release()
3844 remaining_time--; in iwl_mvm_d3_test_release()
3853 mvm->hw, IEEE80211_IFACE_ITER_NORMAL, in iwl_mvm_d3_test_release()
3854 iwl_mvm_d3_test_disconn_work_iter, mvm->keep_vif); in iwl_mvm_d3_test_release()