Lines Matching +full:key +full:- +full:wakeup
1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
3 * Copyright (C) 2012-2014, 2018-2023 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()
470 for (i = 0; i < ARRAY_SIZE(data.rsc->mcast_key_id_map); i++) in iwl_mvm_wowlan_config_rsc_tsc()
471 data.rsc->mcast_key_id_map[i] = in iwl_mvm_wowlan_config_rsc_tsc()
473 data.rsc->sta_id = cpu_to_le32(mvmvif->deflink.ap_sta_id); in iwl_mvm_wowlan_config_rsc_tsc()
475 ieee80211_iter_keys(mvm->hw, vif, in iwl_mvm_wowlan_config_rsc_tsc()
492 return -ENOMEM; in iwl_mvm_wowlan_config_rsc_tsc()
496 data.rsc_tsc->sta_id = in iwl_mvm_wowlan_config_rsc_tsc()
497 cpu_to_le32(mvmvif->deflink.ap_sta_id); in iwl_mvm_wowlan_config_rsc_tsc()
500 size = sizeof(data.rsc_tsc->params); in iwl_mvm_wowlan_config_rsc_tsc()
503 ieee80211_iter_keys(mvm->hw, vif, in iwl_mvm_wowlan_config_rsc_tsc()
530 struct ieee80211_key_conf *key, in iwl_mvm_wowlan_get_tkip_data() argument
541 switch (key->cipher) { in iwl_mvm_wowlan_get_tkip_data()
548 rx_p1ks = data->tkip.rx_uni; in iwl_mvm_wowlan_get_tkip_data()
550 pn64 = atomic64_read(&key->tx_pn); in iwl_mvm_wowlan_get_tkip_data()
552 ieee80211_get_tkip_p1k_iv(key, TKIP_PN_TO_IV32(pn64), in iwl_mvm_wowlan_get_tkip_data()
554 iwl_mvm_convert_p1k(p1k, data->tkip.tx.p1k); in iwl_mvm_wowlan_get_tkip_data()
556 memcpy(data->tkip.mic_keys.tx, in iwl_mvm_wowlan_get_tkip_data()
557 &key->key[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY], in iwl_mvm_wowlan_get_tkip_data()
560 rx_mic_key = data->tkip.mic_keys.rx_unicast; in iwl_mvm_wowlan_get_tkip_data()
562 rx_p1ks = data->tkip.rx_multi; in iwl_mvm_wowlan_get_tkip_data()
563 rx_mic_key = data->tkip.mic_keys.rx_mcast; in iwl_mvm_wowlan_get_tkip_data()
567 ieee80211_get_key_rx_seq(key, i, &seq); in iwl_mvm_wowlan_get_tkip_data()
573 ieee80211_get_tkip_rx_p1k(key, vif->bss_conf.bssid, in iwl_mvm_wowlan_get_tkip_data()
576 ieee80211_get_tkip_rx_p1k(key, vif->bss_conf.bssid, in iwl_mvm_wowlan_get_tkip_data()
581 &key->key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY], in iwl_mvm_wowlan_get_tkip_data()
584 data->have_tkip_keys = true; in iwl_mvm_wowlan_get_tkip_data()
596 struct ieee80211_key_conf *key, in iwl_mvm_wowlan_gtk_type_iter() argument
601 switch (key->cipher) { in iwl_mvm_wowlan_gtk_type_iter()
606 data->kek_kck_cmd->gtk_cipher = in iwl_mvm_wowlan_gtk_type_iter()
611 data->kek_kck_cmd->igtk_cipher = cpu_to_le32(STA_KEY_FLG_GCMP); in iwl_mvm_wowlan_gtk_type_iter()
614 data->kek_kck_cmd->igtk_cipher = cpu_to_le32(STA_KEY_FLG_CCM); in iwl_mvm_wowlan_gtk_type_iter()
618 data->kek_kck_cmd->gtk_cipher = in iwl_mvm_wowlan_gtk_type_iter()
624 data->kek_kck_cmd->gtk_cipher = in iwl_mvm_wowlan_gtk_type_iter()
640 if (!wowlan->n_patterns) in iwl_mvm_send_patterns_v1()
643 cmd.len[0] = struct_size(pattern_cmd, patterns, wowlan->n_patterns); in iwl_mvm_send_patterns_v1()
647 return -ENOMEM; in iwl_mvm_send_patterns_v1()
649 pattern_cmd->n_patterns = cpu_to_le32(wowlan->n_patterns); in iwl_mvm_send_patterns_v1()
651 for (i = 0; i < wowlan->n_patterns; i++) { in iwl_mvm_send_patterns_v1()
652 int mask_len = DIV_ROUND_UP(wowlan->patterns[i].pattern_len, 8); in iwl_mvm_send_patterns_v1()
654 memcpy(&pattern_cmd->patterns[i].mask, in iwl_mvm_send_patterns_v1()
655 wowlan->patterns[i].mask, mask_len); in iwl_mvm_send_patterns_v1()
656 memcpy(&pattern_cmd->patterns[i].pattern, in iwl_mvm_send_patterns_v1()
657 wowlan->patterns[i].pattern, in iwl_mvm_send_patterns_v1()
658 wowlan->patterns[i].pattern_len); in iwl_mvm_send_patterns_v1()
659 pattern_cmd->patterns[i].mask_size = mask_len; in iwl_mvm_send_patterns_v1()
660 pattern_cmd->patterns[i].pattern_size = in iwl_mvm_send_patterns_v1()
661 wowlan->patterns[i].pattern_len; in iwl_mvm_send_patterns_v1()
681 int ver = iwl_fw_lookup_cmd_ver(mvm->fw, cmd.id, in iwl_mvm_send_patterns()
684 if (!wowlan->n_patterns) in iwl_mvm_send_patterns()
688 wowlan->n_patterns * sizeof(struct iwl_wowlan_pattern_v2); in iwl_mvm_send_patterns()
692 return -ENOMEM; in iwl_mvm_send_patterns()
694 pattern_cmd->n_patterns = wowlan->n_patterns; in iwl_mvm_send_patterns()
696 pattern_cmd->sta_id = mvmvif->deflink.ap_sta_id; in iwl_mvm_send_patterns()
698 for (i = 0; i < wowlan->n_patterns; i++) { in iwl_mvm_send_patterns()
699 int mask_len = DIV_ROUND_UP(wowlan->patterns[i].pattern_len, 8); in iwl_mvm_send_patterns()
701 pattern_cmd->patterns[i].pattern_type = in iwl_mvm_send_patterns()
704 memcpy(&pattern_cmd->patterns[i].u.bitmask.mask, in iwl_mvm_send_patterns()
705 wowlan->patterns[i].mask, mask_len); in iwl_mvm_send_patterns()
706 memcpy(&pattern_cmd->patterns[i].u.bitmask.pattern, in iwl_mvm_send_patterns()
707 wowlan->patterns[i].pattern, in iwl_mvm_send_patterns()
708 wowlan->patterns[i].pattern_len); in iwl_mvm_send_patterns()
709 pattern_cmd->patterns[i].u.bitmask.mask_size = mask_len; in iwl_mvm_send_patterns()
710 pattern_cmd->patterns[i].u.bitmask.pattern_size = in iwl_mvm_send_patterns()
711 wowlan->patterns[i].pattern_len; in iwl_mvm_send_patterns()
734 return -EINVAL; in iwl_mvm_d3_reprogram()
737 if (WARN_ON(!mvmvif->deflink.phy_ctxt)) in iwl_mvm_d3_reprogram()
738 return -EINVAL; in iwl_mvm_d3_reprogram()
741 ctx = rcu_dereference(vif->bss_conf.chanctx_conf); in iwl_mvm_d3_reprogram()
744 return -EINVAL; in iwl_mvm_d3_reprogram()
746 chandef = ctx->def; in iwl_mvm_d3_reprogram()
747 chains_static = ctx->rx_chains_static; in iwl_mvm_d3_reprogram()
748 chains_dynamic = ctx->rx_chains_dynamic; in iwl_mvm_d3_reprogram()
751 ret = iwl_mvm_phy_ctxt_add(mvm, mvmvif->deflink.phy_ctxt, &chandef, in iwl_mvm_d3_reprogram()
757 mvmvif->uploaded = false; in iwl_mvm_d3_reprogram()
759 if (WARN_ON(!vif->cfg.assoc)) in iwl_mvm_d3_reprogram()
760 return -EINVAL; in iwl_mvm_d3_reprogram()
766 /* add back binding - XXX refactor? */ in iwl_mvm_d3_reprogram()
768 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->deflink.phy_ctxt->id, in iwl_mvm_d3_reprogram()
769 mvmvif->deflink.phy_ctxt->color)); in iwl_mvm_d3_reprogram()
772 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->deflink.phy_ctxt->id, in iwl_mvm_d3_reprogram()
773 mvmvif->deflink.phy_ctxt->color)); in iwl_mvm_d3_reprogram()
774 binding_cmd.macs[0] = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, in iwl_mvm_d3_reprogram()
775 mvmvif->color)); in iwl_mvm_d3_reprogram()
790 return -EIO; in iwl_mvm_d3_reprogram()
796 rcu_assign_pointer(mvm->fw_id_to_mac_id[mvmvif->deflink.ap_sta_id], in iwl_mvm_d3_reprogram()
805 quota->id_and_color = in iwl_mvm_d3_reprogram()
806 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->deflink.phy_ctxt->id, in iwl_mvm_d3_reprogram()
807 mvmvif->deflink.phy_ctxt->color)); in iwl_mvm_d3_reprogram()
808 quota->quota = cpu_to_le32(IWL_MVM_MAX_QUOTA); in iwl_mvm_d3_reprogram()
809 quota->max_duration = cpu_to_le32(IWL_MVM_MAX_QUOTA); in iwl_mvm_d3_reprogram()
813 quota->id_and_color = cpu_to_le32(FW_CTXT_INVALID); in iwl_mvm_d3_reprogram()
834 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, in iwl_mvm_get_last_nonqos_seq()
835 mvmvif->color)), in iwl_mvm_get_last_nonqos_seq()
853 err = -EINVAL; in iwl_mvm_get_last_nonqos_seq()
855 err = le16_to_cpup((__le16 *)cmd.resp_pkt->data); in iwl_mvm_get_last_nonqos_seq()
856 /* firmware returns next, not last-used seqno */ in iwl_mvm_get_last_nonqos_seq()
857 err = (u16) (err - 0x10); in iwl_mvm_get_last_nonqos_seq()
870 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, in iwl_mvm_set_last_nonqos_seq()
871 mvmvif->color)), in iwl_mvm_set_last_nonqos_seq()
872 .value = cpu_to_le16(mvmvif->seqno), in iwl_mvm_set_last_nonqos_seq()
876 if (!mvmvif->seqno_valid) in iwl_mvm_set_last_nonqos_seq()
879 mvmvif->seqno_valid = false; in iwl_mvm_set_last_nonqos_seq()
883 IWL_ERR(mvm, "failed to set non-QoS seqno\n"); in iwl_mvm_set_last_nonqos_seq()
892 * Set the HW restart bit -- this is mostly true as we're in iwl_mvm_switch_to_d3()
901 set_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status); in iwl_mvm_switch_to_d3()
904 memset(mvm->fw_key_table, 0, sizeof(mvm->fw_key_table)); in iwl_mvm_switch_to_d3()
906 mvm->ptk_ivlen = 0; in iwl_mvm_switch_to_d3()
907 mvm->ptk_icvlen = 0; in iwl_mvm_switch_to_d3()
908 mvm->ptk_ivlen = 0; in iwl_mvm_switch_to_d3()
909 mvm->ptk_icvlen = 0; in iwl_mvm_switch_to_d3()
923 /* TODO: wowlan_config_cmd->wowlan_ba_teardown_tids */ in iwl_mvm_get_wowlan_config()
925 wowlan_config_cmd->is_11n_connection = in iwl_mvm_get_wowlan_config()
926 ap_sta->deflink.ht_cap.ht_supported; in iwl_mvm_get_wowlan_config()
927 wowlan_config_cmd->flags = ENABLE_L3_FILTERING | in iwl_mvm_get_wowlan_config()
930 if (iwl_fw_lookup_cmd_ver(mvm->fw, WOWLAN_CONFIGURATION, 0) < 6) { in iwl_mvm_get_wowlan_config()
937 wowlan_config_cmd->non_qos_seq = cpu_to_le16(ret); in iwl_mvm_get_wowlan_config()
942 if (wowlan->disconnect) in iwl_mvm_get_wowlan_config()
943 wowlan_config_cmd->wakeup_filter |= in iwl_mvm_get_wowlan_config()
946 if (wowlan->magic_pkt) in iwl_mvm_get_wowlan_config()
947 wowlan_config_cmd->wakeup_filter |= in iwl_mvm_get_wowlan_config()
949 if (wowlan->gtk_rekey_failure) in iwl_mvm_get_wowlan_config()
950 wowlan_config_cmd->wakeup_filter |= in iwl_mvm_get_wowlan_config()
952 if (wowlan->eap_identity_req) in iwl_mvm_get_wowlan_config()
953 wowlan_config_cmd->wakeup_filter |= in iwl_mvm_get_wowlan_config()
955 if (wowlan->four_way_handshake) in iwl_mvm_get_wowlan_config()
956 wowlan_config_cmd->wakeup_filter |= in iwl_mvm_get_wowlan_config()
958 if (wowlan->n_patterns) in iwl_mvm_get_wowlan_config()
959 wowlan_config_cmd->wakeup_filter |= in iwl_mvm_get_wowlan_config()
962 if (wowlan->rfkill_release) in iwl_mvm_get_wowlan_config()
963 wowlan_config_cmd->wakeup_filter |= in iwl_mvm_get_wowlan_config()
966 if (wowlan->tcp) { in iwl_mvm_get_wowlan_config()
971 wowlan_config_cmd->wakeup_filter |= in iwl_mvm_get_wowlan_config()
978 if (wowlan->any) { in iwl_mvm_get_wowlan_config()
979 wowlan_config_cmd->wakeup_filter |= in iwl_mvm_get_wowlan_config()
992 bool unified = fw_has_capa(&mvm->fw->ucode_capa, in iwl_mvm_wowlan_config_key_params()
1003 * as we need non-atomic context in order to take the in iwl_mvm_wowlan_config_key_params()
1010 * take care of locking/unlocking mvm->mutex. in iwl_mvm_wowlan_config_key_params()
1012 ieee80211_iter_keys(mvm->hw, vif, iwl_mvm_wowlan_program_keys, in iwl_mvm_wowlan_config_key_params()
1016 return -EIO; in iwl_mvm_wowlan_config_key_params()
1023 if (!fw_has_api(&mvm->fw->ucode_capa, in iwl_mvm_wowlan_config_key_params()
1025 int ver = iwl_fw_lookup_cmd_ver(mvm->fw, WOWLAN_TKIP_PARAM, in iwl_mvm_wowlan_config_key_params()
1033 cpu_to_le32(mvmvif->deflink.ap_sta_id); in iwl_mvm_wowlan_config_key_params()
1038 return -EINVAL; in iwl_mvm_wowlan_config_key_params()
1041 ieee80211_iter_keys(mvm->hw, vif, iwl_mvm_wowlan_get_tkip_data, in iwl_mvm_wowlan_config_key_params()
1056 if (mvmvif->rekey_data.valid) { in iwl_mvm_wowlan_config_key_params()
1064 cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, in iwl_mvm_wowlan_config_key_params()
1069 return -EINVAL; in iwl_mvm_wowlan_config_key_params()
1071 ieee80211_iter_keys(mvm->hw, vif, iwl_mvm_wowlan_gtk_type_iter, in iwl_mvm_wowlan_config_key_params()
1074 memcpy(kek_kck_cmd.kck, mvmvif->rekey_data.kck, in iwl_mvm_wowlan_config_key_params()
1075 mvmvif->rekey_data.kck_len); in iwl_mvm_wowlan_config_key_params()
1076 kek_kck_cmd.kck_len = cpu_to_le16(mvmvif->rekey_data.kck_len); in iwl_mvm_wowlan_config_key_params()
1077 memcpy(kek_kck_cmd.kek, mvmvif->rekey_data.kek, in iwl_mvm_wowlan_config_key_params()
1078 mvmvif->rekey_data.kek_len); in iwl_mvm_wowlan_config_key_params()
1079 kek_kck_cmd.kek_len = cpu_to_le16(mvmvif->rekey_data.kek_len); in iwl_mvm_wowlan_config_key_params()
1080 kek_kck_cmd.replay_ctr = mvmvif->rekey_data.replay_ctr; in iwl_mvm_wowlan_config_key_params()
1081 kek_kck_cmd.akm = cpu_to_le32(mvmvif->rekey_data.akm); in iwl_mvm_wowlan_config_key_params()
1082 kek_kck_cmd.sta_id = cpu_to_le32(mvmvif->deflink.ap_sta_id); in iwl_mvm_wowlan_config_key_params()
1099 mvmvif->rekey_data.akm); in iwl_mvm_wowlan_config_key_params()
1118 bool unified_image = fw_has_capa(&mvm->fw->ucode_capa, in iwl_mvm_wowlan_config()
1121 mvm->offload_tid = wowlan_config_cmd->offloading_tid; in iwl_mvm_wowlan_config()
1143 if (fw_has_api(&mvm->fw->ucode_capa, in iwl_mvm_wowlan_config()
1161 bool unified_image = fw_has_capa(&mvm->fw->ucode_capa, in iwl_mvm_netdetect_config()
1171 * net-detect). But in practice this doesn't seem to in iwl_mvm_netdetect_config()
1179 ret = iwl_mvm_sched_scan_start(mvm, vif, nd_config, &mvm->nd_ies, in iwl_mvm_netdetect_config()
1184 if (WARN_ON(mvm->nd_match_sets || mvm->nd_channels)) in iwl_mvm_netdetect_config()
1185 return -EBUSY; in iwl_mvm_netdetect_config()
1188 if (nd_config->n_match_sets) { in iwl_mvm_netdetect_config()
1189 mvm->nd_match_sets = kmemdup(nd_config->match_sets, in iwl_mvm_netdetect_config()
1190 sizeof(*nd_config->match_sets) * in iwl_mvm_netdetect_config()
1191 nd_config->n_match_sets, in iwl_mvm_netdetect_config()
1193 if (mvm->nd_match_sets) in iwl_mvm_netdetect_config()
1194 mvm->n_nd_match_sets = nd_config->n_match_sets; in iwl_mvm_netdetect_config()
1198 mvm->nd_channels = kmemdup(nd_config->channels, in iwl_mvm_netdetect_config()
1199 sizeof(*nd_config->channels) * in iwl_mvm_netdetect_config()
1200 nd_config->n_channels, in iwl_mvm_netdetect_config()
1202 if (mvm->nd_channels) in iwl_mvm_netdetect_config()
1203 mvm->n_nd_channels = nd_config->n_channels; in iwl_mvm_netdetect_config()
1210 kfree(mvm->nd_match_sets); in iwl_mvm_free_nd()
1211 mvm->nd_match_sets = NULL; in iwl_mvm_free_nd()
1212 mvm->n_nd_match_sets = 0; in iwl_mvm_free_nd()
1213 kfree(mvm->nd_channels); in iwl_mvm_free_nd()
1214 mvm->nd_channels = NULL; in iwl_mvm_free_nd()
1215 mvm->n_nd_channels = 0; in iwl_mvm_free_nd()
1229 * platforms have issues processing a wakeup signal while in __iwl_mvm_suspend()
1242 bool unified_image = fw_has_capa(&mvm->fw->ucode_capa, in __iwl_mvm_suspend()
1251 return -EINVAL; in __iwl_mvm_suspend()
1254 mutex_lock(&mvm->mutex); in __iwl_mvm_suspend()
1256 set_bit(IWL_MVM_STATUS_IN_D3, &mvm->status); in __iwl_mvm_suspend()
1268 if (mvmvif->deflink.ap_sta_id == IWL_MVM_INVALID_STA) { in __iwl_mvm_suspend()
1270 if (!wowlan->nd_config) { in __iwl_mvm_suspend()
1276 mvm, wowlan, wowlan->nd_config, vif); in __iwl_mvm_suspend()
1280 mvm->net_detect = true; in __iwl_mvm_suspend()
1286 wowlan_config_cmd.sta_id = mvmvif->deflink.ap_sta_id; in __iwl_mvm_suspend()
1289 mvm->fw_id_to_mac_id[mvmvif->deflink.ap_sta_id], in __iwl_mvm_suspend()
1290 lockdep_is_held(&mvm->mutex)); in __iwl_mvm_suspend()
1292 ret = -EINVAL; in __iwl_mvm_suspend()
1297 mvm, ap_sta->txq[wowlan_config_cmd.offloading_tid]); in __iwl_mvm_suspend()
1310 mvm->net_detect = false; in __iwl_mvm_suspend()
1322 if (mvm->d3_wake_sysassert) in __iwl_mvm_suspend()
1332 if (mvm->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_9000) in __iwl_mvm_suspend()
1333 iwl_fw_dbg_stop_restart_recording(&mvm->fwrt, NULL, true); in __iwl_mvm_suspend()
1335 mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_D3; in __iwl_mvm_suspend()
1337 /* must be last -- this switches firmware state */ in __iwl_mvm_suspend()
1344 mvm->d3_test_pme_ptr = in __iwl_mvm_suspend()
1345 le32_to_cpup((__le32 *)d3_cfg_cmd.resp_pkt->data); in __iwl_mvm_suspend()
1350 clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status); in __iwl_mvm_suspend()
1352 ret = iwl_trans_d3_suspend(mvm->trans, test, !unified_image); in __iwl_mvm_suspend()
1358 if (mvm->fw_restart > 0) { in __iwl_mvm_suspend()
1359 mvm->fw_restart--; in __iwl_mvm_suspend()
1360 ieee80211_restart_hw(mvm->hw); in __iwl_mvm_suspend()
1364 clear_bit(IWL_MVM_STATUS_IN_D3, &mvm->status); in __iwl_mvm_suspend()
1367 mutex_unlock(&mvm->mutex); in __iwl_mvm_suspend()
1378 iwl_fw_runtime_suspend(&mvm->fwrt); in iwl_mvm_suspend()
1384 u8 key[WOWLAN_KEY_MAX_SIZE]; member
1405 /* including RX MIC key for TKIP */
1406 u8 key[WOWLAN_KEY_MAX_SIZE]; member
1424 * We use -1 for when we have valid data but don't know
1425 * the key ID from firmware, and thus it needs to be
1426 * installed with the last key (depending on rekeying).
1451 struct cfg80211_wowlan_wakeup wakeup = { in iwl_mvm_report_wakeup_reasons() local
1452 .pattern_idx = -1, in iwl_mvm_report_wakeup_reasons()
1454 struct cfg80211_wowlan_wakeup *wakeup_report = &wakeup; in iwl_mvm_report_wakeup_reasons()
1455 u32 reasons = status->wakeup_reasons; in iwl_mvm_report_wakeup_reasons()
1462 pm_wakeup_event(mvm->dev, 0); in iwl_mvm_report_wakeup_reasons()
1465 wakeup.magic_pkt = true; in iwl_mvm_report_wakeup_reasons()
1468 wakeup.pattern_idx = in iwl_mvm_report_wakeup_reasons()
1469 status->pattern_number; in iwl_mvm_report_wakeup_reasons()
1473 wakeup.disconnect = true; in iwl_mvm_report_wakeup_reasons()
1476 wakeup.gtk_rekey_failure = true; in iwl_mvm_report_wakeup_reasons()
1479 wakeup.rfkill_release = true; in iwl_mvm_report_wakeup_reasons()
1482 wakeup.eap_identity_req = true; in iwl_mvm_report_wakeup_reasons()
1485 wakeup.four_way_handshake = true; in iwl_mvm_report_wakeup_reasons()
1488 wakeup.tcp_connlost = true; in iwl_mvm_report_wakeup_reasons()
1491 wakeup.tcp_nomoretokens = true; in iwl_mvm_report_wakeup_reasons()
1494 wakeup.tcp_match = true; in iwl_mvm_report_wakeup_reasons()
1496 if (status->wake_packet) { in iwl_mvm_report_wakeup_reasons()
1497 int pktsize = status->wake_packet_bufsize; in iwl_mvm_report_wakeup_reasons()
1498 int pktlen = status->wake_packet_length; in iwl_mvm_report_wakeup_reasons()
1499 const u8 *pktdata = status->wake_packet; in iwl_mvm_report_wakeup_reasons()
1501 int truncated = pktlen - pktsize; in iwl_mvm_report_wakeup_reasons()
1507 if (ieee80211_is_data(hdr->frame_control)) { in iwl_mvm_report_wakeup_reasons()
1508 int hdrlen = ieee80211_hdrlen(hdr->frame_control); in iwl_mvm_report_wakeup_reasons()
1517 pktsize -= hdrlen; in iwl_mvm_report_wakeup_reasons()
1519 if (ieee80211_has_protected(hdr->frame_control)) { in iwl_mvm_report_wakeup_reasons()
1523 * that's not really a problem - changing in iwl_mvm_report_wakeup_reasons()
1526 if (is_multicast_ether_addr(hdr->addr1)) { in iwl_mvm_report_wakeup_reasons()
1527 ivlen = mvm->gtk_ivlen; in iwl_mvm_report_wakeup_reasons()
1528 icvlen += mvm->gtk_icvlen; in iwl_mvm_report_wakeup_reasons()
1530 ivlen = mvm->ptk_ivlen; in iwl_mvm_report_wakeup_reasons()
1531 icvlen += mvm->ptk_icvlen; in iwl_mvm_report_wakeup_reasons()
1538 truncated -= icvlen; in iwl_mvm_report_wakeup_reasons()
1540 icvlen -= truncated; in iwl_mvm_report_wakeup_reasons()
1544 pktsize -= ivlen + icvlen; in iwl_mvm_report_wakeup_reasons()
1549 if (ieee80211_data_to_8023(pkt, vif->addr, vif->type)) in iwl_mvm_report_wakeup_reasons()
1551 wakeup.packet = pkt->data; in iwl_mvm_report_wakeup_reasons()
1552 wakeup.packet_present_len = pkt->len; in iwl_mvm_report_wakeup_reasons()
1553 wakeup.packet_len = pkt->len - truncated; in iwl_mvm_report_wakeup_reasons()
1554 wakeup.packet_80211 = false; in iwl_mvm_report_wakeup_reasons()
1559 truncated -= 4; in iwl_mvm_report_wakeup_reasons()
1562 fcslen -= truncated; in iwl_mvm_report_wakeup_reasons()
1565 pktsize -= fcslen; in iwl_mvm_report_wakeup_reasons()
1566 wakeup.packet = status->wake_packet; in iwl_mvm_report_wakeup_reasons()
1567 wakeup.packet_present_len = pktsize; in iwl_mvm_report_wakeup_reasons()
1568 wakeup.packet_len = pktlen - truncated; in iwl_mvm_report_wakeup_reasons()
1569 wakeup.packet_80211 = true; in iwl_mvm_report_wakeup_reasons()
1582 seq->ccmp.pn[0] = pn >> 40; in iwl_mvm_le64_to_aes_seq()
1583 seq->ccmp.pn[1] = pn >> 32; in iwl_mvm_le64_to_aes_seq()
1584 seq->ccmp.pn[2] = pn >> 24; in iwl_mvm_le64_to_aes_seq()
1585 seq->ccmp.pn[3] = pn >> 16; in iwl_mvm_le64_to_aes_seq()
1586 seq->ccmp.pn[4] = pn >> 8; in iwl_mvm_le64_to_aes_seq()
1587 seq->ccmp.pn[5] = pn; in iwl_mvm_le64_to_aes_seq()
1593 iwl_mvm_le64_to_aes_seq(sc->pn, seq); in iwl_mvm_aes_sc_to_seq()
1600 seq->tkip.iv16 = (u16)pn; in iwl_mvm_le64_to_tkip_seq()
1601 seq->tkip.iv32 = (u32)(pn >> 16); in iwl_mvm_le64_to_tkip_seq()
1607 seq->tkip.iv32 = le32_to_cpu(sc->iv32); in iwl_mvm_tkip_sc_to_seq()
1608 seq->tkip.iv16 = le16_to_cpu(sc->iv16); in iwl_mvm_tkip_sc_to_seq()
1611 static void iwl_mvm_set_key_rx_seq_tids(struct ieee80211_key_conf *key, in iwl_mvm_set_key_rx_seq_tids() argument
1617 ieee80211_set_key_rx_seq(key, tid, &seq[tid]); in iwl_mvm_set_key_rx_seq_tids()
1623 struct ieee80211_key_conf *key) in iwl_mvm_set_aes_ptk_rx_seq() argument
1629 iwl_mvm_set_key_rx_seq_tids(key, status->ptk.aes.seq); in iwl_mvm_set_aes_ptk_rx_seq()
1636 ptk_pn = rcu_dereference(mvmsta->ptk_pn[key->keyidx]); in iwl_mvm_set_aes_ptk_rx_seq()
1645 for (i = 1; i < mvm->trans->num_rx_queues; i++) in iwl_mvm_set_aes_ptk_rx_seq()
1646 memcpy(ptk_pn->q[i].pn[tid], in iwl_mvm_set_aes_ptk_rx_seq()
1647 status->ptk.aes.seq[tid].ccmp.pn, in iwl_mvm_set_aes_ptk_rx_seq()
1663 iwl_mvm_tkip_sc_to_seq(&sc->tkip.multicast_rsc[i], in iwl_mvm_convert_key_counters()
1664 &status->gtk_seq[0].tkip.seq[i]); in iwl_mvm_convert_key_counters()
1665 iwl_mvm_aes_sc_to_seq(&sc->aes.multicast_rsc[i], in iwl_mvm_convert_key_counters()
1666 &status->gtk_seq[0].aes.seq[i]); in iwl_mvm_convert_key_counters()
1668 status->gtk_seq[0].valid = true; in iwl_mvm_convert_key_counters()
1669 status->gtk_seq[0].key_id = -1; in iwl_mvm_convert_key_counters()
1672 status->ptk.tkip.tx_pn = (u64)le16_to_cpu(sc->tkip.tsc.iv16) | in iwl_mvm_convert_key_counters()
1673 ((u64)le32_to_cpu(sc->tkip.tsc.iv32) << 16); in iwl_mvm_convert_key_counters()
1674 status->ptk.aes.tx_pn = le64_to_cpu(sc->aes.tsc.pn); in iwl_mvm_convert_key_counters()
1678 iwl_mvm_tkip_sc_to_seq(&sc->tkip.unicast_rsc[i], in iwl_mvm_convert_key_counters()
1679 &status->ptk.tkip.seq[i]); in iwl_mvm_convert_key_counters()
1680 iwl_mvm_aes_sc_to_seq(&sc->aes.unicast_rsc[i], in iwl_mvm_convert_key_counters()
1681 &status->ptk.aes.seq[i]); in iwl_mvm_convert_key_counters()
1693 iwl_mvm_le64_to_tkip_seq(sc->mcast_rsc[idx][tid], in iwl_mvm_convert_key_counters_v5_gtk_seq()
1694 &status->gtk_seq[idx].tkip.seq[tid]); in iwl_mvm_convert_key_counters_v5_gtk_seq()
1695 iwl_mvm_le64_to_aes_seq(sc->mcast_rsc[idx][tid], in iwl_mvm_convert_key_counters_v5_gtk_seq()
1696 &status->gtk_seq[idx].aes.seq[tid]); in iwl_mvm_convert_key_counters_v5_gtk_seq()
1699 status->gtk_seq[idx].valid = true; in iwl_mvm_convert_key_counters_v5_gtk_seq()
1700 status->gtk_seq[idx].key_id = key_id; in iwl_mvm_convert_key_counters_v5_gtk_seq()
1711 BUILD_BUG_ON(ARRAY_SIZE(sc->mcast_rsc) != ARRAY_SIZE(status->gtk_seq)); in iwl_mvm_convert_key_counters_v5()
1714 for (i = 0; i < ARRAY_SIZE(sc->mcast_key_id_map); i++) { in iwl_mvm_convert_key_counters_v5()
1715 u8 entry = sc->mcast_key_id_map[i]; in iwl_mvm_convert_key_counters_v5()
1717 if (entry < ARRAY_SIZE(sc->mcast_rsc)) in iwl_mvm_convert_key_counters_v5()
1726 iwl_mvm_le64_to_tkip_seq(sc->ucast_rsc[tid], in iwl_mvm_convert_key_counters_v5()
1727 &status->ptk.tkip.seq[tid]); in iwl_mvm_convert_key_counters_v5()
1728 iwl_mvm_le64_to_aes_seq(sc->ucast_rsc[tid], in iwl_mvm_convert_key_counters_v5()
1729 &status->ptk.aes.seq[tid]); in iwl_mvm_convert_key_counters_v5()
1733 static void iwl_mvm_set_key_rx_seq_idx(struct ieee80211_key_conf *key, in iwl_mvm_set_key_rx_seq_idx() argument
1737 switch (key->cipher) { in iwl_mvm_set_key_rx_seq_idx()
1741 iwl_mvm_set_key_rx_seq_tids(key, status->gtk_seq[idx].aes.seq); in iwl_mvm_set_key_rx_seq_idx()
1744 iwl_mvm_set_key_rx_seq_tids(key, status->gtk_seq[idx].tkip.seq); in iwl_mvm_set_key_rx_seq_idx()
1751 static void iwl_mvm_set_key_rx_seq(struct ieee80211_key_conf *key, in iwl_mvm_set_key_rx_seq() argument
1757 for (i = 0; i < ARRAY_SIZE(status->gtk_seq); i++) { in iwl_mvm_set_key_rx_seq()
1758 if (!status->gtk_seq[i].valid) in iwl_mvm_set_key_rx_seq()
1761 /* Handle the case where we know the key ID */ in iwl_mvm_set_key_rx_seq()
1762 if (status->gtk_seq[i].key_id == key->keyidx) { in iwl_mvm_set_key_rx_seq()
1763 s8 new_key_id = -1; in iwl_mvm_set_key_rx_seq()
1765 if (status->num_of_gtk_rekeys) in iwl_mvm_set_key_rx_seq()
1766 new_key_id = status->gtk[0].flags & in iwl_mvm_set_key_rx_seq()
1769 /* Don't install a new key's value to an old key */ in iwl_mvm_set_key_rx_seq()
1770 if (new_key_id != key->keyidx) in iwl_mvm_set_key_rx_seq()
1771 iwl_mvm_set_key_rx_seq_idx(key, status, i); in iwl_mvm_set_key_rx_seq()
1775 /* handle the case where we didn't, last key only */ in iwl_mvm_set_key_rx_seq()
1776 if (status->gtk_seq[i].key_id == -1 && in iwl_mvm_set_key_rx_seq()
1777 (!status->num_of_gtk_rekeys || installed)) in iwl_mvm_set_key_rx_seq()
1778 iwl_mvm_set_key_rx_seq_idx(key, status, i); in iwl_mvm_set_key_rx_seq()
1793 struct ieee80211_key_conf *key, in iwl_mvm_d3_find_last_keys() argument
1798 if (data->unhandled_cipher) in iwl_mvm_d3_find_last_keys()
1801 switch (key->cipher) { in iwl_mvm_d3_find_last_keys()
1811 data->gtk_cipher = key->cipher; in iwl_mvm_d3_find_last_keys()
1818 if (data->igtk_support && in iwl_mvm_d3_find_last_keys()
1819 (key->keyidx == 4 || key->keyidx == 5)) { in iwl_mvm_d3_find_last_keys()
1820 data->igtk_cipher = key->cipher; in iwl_mvm_d3_find_last_keys()
1821 } else if (data->bigtk_support && in iwl_mvm_d3_find_last_keys()
1822 (key->keyidx == 6 || key->keyidx == 7)) { in iwl_mvm_d3_find_last_keys()
1823 data->bigtk_cipher = key->cipher; in iwl_mvm_d3_find_last_keys()
1825 data->unhandled_cipher = true; in iwl_mvm_d3_find_last_keys()
1830 /* everything else - disconnect from AP */ in iwl_mvm_d3_find_last_keys()
1831 data->unhandled_cipher = true; in iwl_mvm_d3_find_last_keys()
1835 data->num_keys++; in iwl_mvm_d3_find_last_keys()
1839 iwl_mvm_d3_set_igtk_bigtk_ipn(const struct iwl_multicast_key_data *key, in iwl_mvm_d3_set_igtk_bigtk_ipn() argument
1845 BUILD_BUG_ON(sizeof(seq->aes_gmac.pn) != sizeof(key->ipn)); in iwl_mvm_d3_set_igtk_bigtk_ipn()
1846 memcpy(seq->aes_gmac.pn, key->ipn, sizeof(seq->aes_gmac.pn)); in iwl_mvm_d3_set_igtk_bigtk_ipn()
1849 BUILD_BUG_ON(sizeof(seq->aes_cmac.pn) != sizeof(key->ipn)); in iwl_mvm_d3_set_igtk_bigtk_ipn()
1850 memcpy(seq->aes_cmac.pn, key->ipn, sizeof(seq->aes_cmac.pn)); in iwl_mvm_d3_set_igtk_bigtk_ipn()
1857 struct ieee80211_key_conf *key, in iwl_mvm_d3_update_igtk_bigtk() argument
1860 if (status->num_of_gtk_rekeys && key_data->len) { in iwl_mvm_d3_update_igtk_bigtk()
1861 /* remove rekeyed key */ in iwl_mvm_d3_update_igtk_bigtk()
1862 ieee80211_remove_key(key); in iwl_mvm_d3_update_igtk_bigtk()
1868 key->cipher); in iwl_mvm_d3_update_igtk_bigtk()
1869 ieee80211_set_key_rx_seq(key, 0, &seq); in iwl_mvm_d3_update_igtk_bigtk()
1876 struct ieee80211_key_conf *key, in iwl_mvm_d3_update_keys() argument
1880 struct iwl_wowlan_status_data *status = data->status; in iwl_mvm_d3_update_keys()
1883 if (data->unhandled_cipher) in iwl_mvm_d3_update_keys()
1886 switch (key->cipher) { in iwl_mvm_d3_update_keys()
1895 atomic64_set(&key->tx_pn, status->ptk.aes.tx_pn); in iwl_mvm_d3_update_keys()
1896 iwl_mvm_set_aes_ptk_rx_seq(data->mvm, status, sta, key); in iwl_mvm_d3_update_keys()
1902 atomic64_set(&key->tx_pn, status->ptk.tkip.tx_pn); in iwl_mvm_d3_update_keys()
1903 iwl_mvm_set_key_rx_seq_tids(key, status->ptk.tkip.seq); in iwl_mvm_d3_update_keys()
1906 keyidx = key->keyidx; in iwl_mvm_d3_update_keys()
1907 /* The current key is always sent by the FW, even if it wasn't in iwl_mvm_d3_update_keys()
1909 * We remove an existing key if it has the same index as in iwl_mvm_d3_update_keys()
1910 * a new key in iwl_mvm_d3_update_keys()
1912 if (status->num_of_gtk_rekeys && in iwl_mvm_d3_update_keys()
1913 ((status->gtk[0].len && keyidx == status->gtk[0].id) || in iwl_mvm_d3_update_keys()
1914 (status->gtk[1].len && keyidx == status->gtk[1].id))) { in iwl_mvm_d3_update_keys()
1915 ieee80211_remove_key(key); in iwl_mvm_d3_update_keys()
1917 iwl_mvm_set_key_rx_seq(key, data->status, false); in iwl_mvm_d3_update_keys()
1924 if (key->keyidx == 4 || key->keyidx == 5) { in iwl_mvm_d3_update_keys()
1925 iwl_mvm_d3_update_igtk_bigtk(status, key, in iwl_mvm_d3_update_keys()
1926 &status->igtk); in iwl_mvm_d3_update_keys()
1928 if (key->keyidx == 6 || key->keyidx == 7) { in iwl_mvm_d3_update_keys()
1929 u8 idx = key->keyidx == status->bigtk[1].id; in iwl_mvm_d3_update_keys()
1931 iwl_mvm_d3_update_igtk_bigtk(status, key, in iwl_mvm_d3_update_keys()
1932 &status->bigtk[idx]); in iwl_mvm_d3_update_keys()
1942 struct ieee80211_key_conf *key; in iwl_mvm_gtk_rekey() local
1945 u8 key[32]; in iwl_mvm_gtk_rekey() member
1951 BUILD_BUG_ON(sizeof(conf.key) < WLAN_KEY_LEN_CCMP); in iwl_mvm_gtk_rekey()
1952 BUILD_BUG_ON(sizeof(conf.key) < WLAN_KEY_LEN_GCMP_256); in iwl_mvm_gtk_rekey()
1953 BUILD_BUG_ON(sizeof(conf.key) < WLAN_KEY_LEN_TKIP); in iwl_mvm_gtk_rekey()
1954 BUILD_BUG_ON(sizeof(conf.key) < sizeof(status->gtk[0].key)); in iwl_mvm_gtk_rekey()
1971 for (i = 0; i < ARRAY_SIZE(status->gtk); i++) { in iwl_mvm_gtk_rekey()
1972 if (!status->gtk[i].len) in iwl_mvm_gtk_rekey()
1975 conf.conf.keyidx = status->gtk[i].id; in iwl_mvm_gtk_rekey()
1977 "Received from FW GTK cipher %d, key index %d\n", in iwl_mvm_gtk_rekey()
1979 memcpy(conf.conf.key, status->gtk[i].key, in iwl_mvm_gtk_rekey()
1980 sizeof(status->gtk[i].key)); in iwl_mvm_gtk_rekey()
1982 key = ieee80211_gtk_rekey_add(vif, &conf.conf); in iwl_mvm_gtk_rekey()
1983 if (IS_ERR(key)) in iwl_mvm_gtk_rekey()
1985 iwl_mvm_set_key_rx_seq_idx(key, status, i); in iwl_mvm_gtk_rekey()
1999 u8 key[WOWLAN_KEY_MAX_SIZE]; in iwl_mvm_d3_igtk_bigtk_rekey_add() member
2002 .conf.keyidx = key_data->id, in iwl_mvm_d3_igtk_bigtk_rekey_add()
2006 if (!key_data->len) in iwl_mvm_d3_igtk_bigtk_rekey_add()
2027 BUILD_BUG_ON(sizeof(conf.key) < sizeof(key_data->key)); in iwl_mvm_d3_igtk_bigtk_rekey_add()
2028 memcpy(conf.conf.key, key_data->key, conf.conf.keylen); in iwl_mvm_d3_igtk_bigtk_rekey_add()
2035 if (key_config->keyidx == 4 || key_config->keyidx == 5) { in iwl_mvm_d3_igtk_bigtk_rekey_add()
2037 int link_id = vif->active_links ? __ffs(vif->active_links) : 0; in iwl_mvm_d3_igtk_bigtk_rekey_add()
2039 mvmvif->link[link_id]; in iwl_mvm_d3_igtk_bigtk_rekey_add()
2041 mvm_link->igtk = key_config; in iwl_mvm_d3_igtk_bigtk_rekey_add()
2051 if (!fw_has_api(&mvm->fw->ucode_capa, in iwl_mvm_lookup_wowlan_status_ver()
2056 notif_ver = iwl_fw_lookup_notif_ver(mvm->fw, LONG_GROUP, in iwl_mvm_lookup_wowlan_status_ver()
2059 notif_ver = iwl_fw_lookup_notif_ver(mvm->fw, LEGACY_GROUP, in iwl_mvm_lookup_wowlan_status_ver()
2080 if (!status || !vif->bss_conf.bssid) in iwl_mvm_setup_connection_keep()
2083 if (status->wakeup_reasons & disconnection_reasons) in iwl_mvm_setup_connection_keep()
2087 iwl_fw_lookup_notif_ver(mvm->fw, PROT_OFFLOAD_GROUP, in iwl_mvm_setup_connection_keep()
2092 if (iwl_fw_lookup_notif_ver(mvm->fw, PROT_OFFLOAD_GROUP, in iwl_mvm_setup_connection_keep()
2098 ieee80211_iter_keys(mvm->hw, vif, in iwl_mvm_setup_connection_keep()
2110 ieee80211_iter_keys(mvm->hw, vif, in iwl_mvm_setup_connection_keep()
2113 if (status->num_of_gtk_rekeys) { in iwl_mvm_setup_connection_keep()
2114 __be64 replay_ctr = cpu_to_be64(status->replay_ctr); in iwl_mvm_setup_connection_keep()
2117 status->num_of_gtk_rekeys); in iwl_mvm_setup_connection_keep()
2124 &status->igtk)) in iwl_mvm_setup_connection_keep()
2127 for (i = 0; i < ARRAY_SIZE(status->bigtk); i++) { in iwl_mvm_setup_connection_keep()
2130 &status->bigtk[i])) in iwl_mvm_setup_connection_keep()
2134 ieee80211_gtk_rekey_notify(vif, vif->bss_conf.bssid, in iwl_mvm_setup_connection_keep()
2139 if (iwl_fw_lookup_notif_ver(mvm->fw, LONG_GROUP, in iwl_mvm_setup_connection_keep()
2141 mvmvif->seqno_valid = true; in iwl_mvm_setup_connection_keep()
2142 /* +0x10 because the set API expects next-to-use, not last-used */ in iwl_mvm_setup_connection_keep()
2143 mvmvif->seqno = status->non_qos_seq_ctr + 0x10; in iwl_mvm_setup_connection_keep()
2152 BUILD_BUG_ON(sizeof(status->gtk[0].key) < sizeof(data->key)); in iwl_mvm_convert_gtk_v2()
2154 sizeof(data->tkip_mic_key) > in iwl_mvm_convert_gtk_v2()
2155 sizeof(status->gtk[0].key)); in iwl_mvm_convert_gtk_v2()
2157 status->gtk[0].len = data->key_len; in iwl_mvm_convert_gtk_v2()
2158 status->gtk[0].flags = data->key_flags; in iwl_mvm_convert_gtk_v2()
2160 memcpy(status->gtk[0].key, data->key, sizeof(data->key)); in iwl_mvm_convert_gtk_v2()
2162 /* if it's as long as the TKIP encryption key, copy MIC key */ in iwl_mvm_convert_gtk_v2()
2163 if (status->gtk[0].len == NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY) in iwl_mvm_convert_gtk_v2()
2164 memcpy(status->gtk[0].key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY, in iwl_mvm_convert_gtk_v2()
2165 data->tkip_mic_key, sizeof(data->tkip_mic_key)); in iwl_mvm_convert_gtk_v2()
2173 BUILD_BUG_ON(sizeof(status->gtk[0].key) < sizeof(data[0].key)); in iwl_mvm_convert_gtk_v3()
2176 sizeof(status->gtk[0].key)); in iwl_mvm_convert_gtk_v3()
2177 BUILD_BUG_ON(ARRAY_SIZE(status->gtk) < WOWLAN_GTK_KEYS_NUM); in iwl_mvm_convert_gtk_v3()
2178 for (data_idx = 0; data_idx < ARRAY_SIZE(status->gtk); data_idx++) { in iwl_mvm_convert_gtk_v3()
2181 status->gtk[status_idx].len = data[data_idx].key_len; in iwl_mvm_convert_gtk_v3()
2182 status->gtk[status_idx].flags = data[data_idx].key_flags; in iwl_mvm_convert_gtk_v3()
2183 status->gtk[status_idx].id = status->gtk[status_idx].flags & in iwl_mvm_convert_gtk_v3()
2186 memcpy(status->gtk[status_idx].key, data[data_idx].key, in iwl_mvm_convert_gtk_v3()
2187 sizeof(data[data_idx].key)); in iwl_mvm_convert_gtk_v3()
2189 /* if it's as long as the TKIP encryption key, copy MIC key */ in iwl_mvm_convert_gtk_v3()
2190 if (status->gtk[status_idx].len == in iwl_mvm_convert_gtk_v3()
2192 memcpy(status->gtk[status_idx].key + in iwl_mvm_convert_gtk_v3()
2203 BUILD_BUG_ON(sizeof(status->igtk.key) < sizeof(data->key)); in iwl_mvm_convert_igtk()
2205 if (!data->key_len) in iwl_mvm_convert_igtk()
2208 status->igtk.len = data->key_len; in iwl_mvm_convert_igtk()
2209 status->igtk.flags = data->key_flags; in iwl_mvm_convert_igtk()
2210 status->igtk.id = u32_get_bits(data->key_flags, in iwl_mvm_convert_igtk()
2214 memcpy(status->igtk.key, data->key, sizeof(data->key)); in iwl_mvm_convert_igtk()
2215 memcpy(status->igtk.ipn, data->ipn, sizeof(data->ipn)); in iwl_mvm_convert_igtk()
2223 BUILD_BUG_ON(ARRAY_SIZE(status->bigtk) < WOWLAN_BIGTK_KEYS_NUM); in iwl_mvm_convert_bigtk()
2229 status->bigtk[status_idx].len = data[data_idx].key_len; in iwl_mvm_convert_bigtk()
2230 status->bigtk[status_idx].flags = data[data_idx].key_flags; in iwl_mvm_convert_bigtk()
2231 status->bigtk[status_idx].id = in iwl_mvm_convert_bigtk()
2236 BUILD_BUG_ON(sizeof(status->bigtk[status_idx].key) < in iwl_mvm_convert_bigtk()
2237 sizeof(data[data_idx].key)); in iwl_mvm_convert_bigtk()
2238 BUILD_BUG_ON(sizeof(status->bigtk[status_idx].ipn) < in iwl_mvm_convert_bigtk()
2241 memcpy(status->bigtk[status_idx].key, data[data_idx].key, in iwl_mvm_convert_bigtk()
2242 sizeof(data[data_idx].key)); in iwl_mvm_convert_bigtk()
2243 memcpy(status->bigtk[status_idx].ipn, data[data_idx].ipn, in iwl_mvm_convert_bigtk()
2268 iwl_mvm_convert_key_counters_v5(status, &data->gtk[0].sc); in iwl_mvm_parse_wowlan_info_notif()
2269 iwl_mvm_convert_gtk_v3(status, data->gtk); in iwl_mvm_parse_wowlan_info_notif()
2270 iwl_mvm_convert_igtk(status, &data->igtk[0]); in iwl_mvm_parse_wowlan_info_notif()
2271 iwl_mvm_convert_bigtk(status, data->bigtk); in iwl_mvm_parse_wowlan_info_notif()
2272 status->replay_ctr = le64_to_cpu(data->replay_ctr); in iwl_mvm_parse_wowlan_info_notif()
2273 status->pattern_number = le16_to_cpu(data->pattern_number); in iwl_mvm_parse_wowlan_info_notif()
2275 status->qos_seq_ctr[i] = in iwl_mvm_parse_wowlan_info_notif()
2276 le16_to_cpu(data->qos_seq_ctr[i]); in iwl_mvm_parse_wowlan_info_notif()
2277 status->wakeup_reasons = le32_to_cpu(data->wakeup_reasons); in iwl_mvm_parse_wowlan_info_notif()
2278 status->num_of_gtk_rekeys = in iwl_mvm_parse_wowlan_info_notif()
2279 le32_to_cpu(data->num_of_gtk_rekeys); in iwl_mvm_parse_wowlan_info_notif()
2280 status->received_beacons = le32_to_cpu(data->received_beacons); in iwl_mvm_parse_wowlan_info_notif()
2281 status->tid_tear_down = data->tid_tear_down; in iwl_mvm_parse_wowlan_info_notif()
2304 iwl_mvm_convert_key_counters_v5(status, &data->gtk[0].sc); in iwl_mvm_parse_wowlan_info_notif_v2()
2305 iwl_mvm_convert_gtk_v3(status, data->gtk); in iwl_mvm_parse_wowlan_info_notif_v2()
2306 iwl_mvm_convert_igtk(status, &data->igtk[0]); in iwl_mvm_parse_wowlan_info_notif_v2()
2307 status->replay_ctr = le64_to_cpu(data->replay_ctr); in iwl_mvm_parse_wowlan_info_notif_v2()
2308 status->pattern_number = le16_to_cpu(data->pattern_number); in iwl_mvm_parse_wowlan_info_notif_v2()
2310 status->qos_seq_ctr[i] = in iwl_mvm_parse_wowlan_info_notif_v2()
2311 le16_to_cpu(data->qos_seq_ctr[i]); in iwl_mvm_parse_wowlan_info_notif_v2()
2312 status->wakeup_reasons = le32_to_cpu(data->wakeup_reasons); in iwl_mvm_parse_wowlan_info_notif_v2()
2313 status->num_of_gtk_rekeys = in iwl_mvm_parse_wowlan_info_notif_v2()
2314 le32_to_cpu(data->num_of_gtk_rekeys); in iwl_mvm_parse_wowlan_info_notif_v2()
2315 status->received_beacons = le32_to_cpu(data->received_beacons); in iwl_mvm_parse_wowlan_info_notif_v2()
2316 status->tid_tear_down = data->tid_tear_down; in iwl_mvm_parse_wowlan_info_notif_v2()
2334 data_size = ALIGN(le32_to_cpu(data->wake_packet_bufsize), 4); \
2345 status->replay_ctr = le64_to_cpu(data->replay_ctr); \
2346 status->pattern_number = le16_to_cpu(data->pattern_number); \
2347 status->non_qos_seq_ctr = le16_to_cpu(data->non_qos_seq_ctr); \
2349 status->qos_seq_ctr[i] = \
2350 le16_to_cpu(data->qos_seq_ctr[i]); \
2351 status->wakeup_reasons = le32_to_cpu(data->wakeup_reasons); \
2352 status->num_of_gtk_rekeys = \
2353 le32_to_cpu(data->num_of_gtk_rekeys); \
2354 status->received_beacons = le32_to_cpu(data->received_beacons); \
2355 status->wake_packet_length = \
2356 le32_to_cpu(data->wake_packet_length); \
2357 status->wake_packet_bufsize = \
2358 le32_to_cpu(data->wake_packet_bufsize); \
2359 if (status->wake_packet_bufsize) { \
2360 status->wake_packet = \
2361 kmemdup(data->wake_packet, \
2362 status->wake_packet_bufsize, \
2364 if (!status->wake_packet) { \
2369 status->wake_packet = NULL; \
2395 u8 cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, cmd.id, in iwl_mvm_parse_wowlan_status_common()
2401 lockdep_assert_held(&mvm->mutex); in iwl_mvm_parse_wowlan_status_common()
2405 IWL_ERR(mvm, "failed to query wakeup status (%d)\n", ret); in iwl_mvm_parse_wowlan_status_common()
2415 struct iwl_wowlan_status_v6 *v6 = (void *)cmd.resp_pkt->data; in iwl_mvm_parse_wowlan_status_common()
2421 BUILD_BUG_ON(sizeof(v6->gtk.decrypt_key) > in iwl_mvm_parse_wowlan_status_common()
2422 sizeof(status->gtk[0].key)); in iwl_mvm_parse_wowlan_status_common()
2424 sizeof(v6->gtk.tkip_mic_key) > in iwl_mvm_parse_wowlan_status_common()
2425 sizeof(status->gtk[0].key)); in iwl_mvm_parse_wowlan_status_common()
2428 memcpy(status->gtk[0].key, v6->gtk.decrypt_key, in iwl_mvm_parse_wowlan_status_common()
2429 sizeof(v6->gtk.decrypt_key)); in iwl_mvm_parse_wowlan_status_common()
2430 memcpy(status->gtk[0].key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY, in iwl_mvm_parse_wowlan_status_common()
2431 v6->gtk.tkip_mic_key, in iwl_mvm_parse_wowlan_status_common()
2432 sizeof(v6->gtk.tkip_mic_key)); in iwl_mvm_parse_wowlan_status_common()
2434 iwl_mvm_convert_key_counters(status, &v6->gtk.rsc.all_tsc_rsc); in iwl_mvm_parse_wowlan_status_common()
2436 /* hardcode the key length to 16 since v6 only supports 16 */ in iwl_mvm_parse_wowlan_status_common()
2437 status->gtk[0].len = 16; in iwl_mvm_parse_wowlan_status_common()
2440 * The key index only uses 2 bits (values 0 to 3) and in iwl_mvm_parse_wowlan_status_common()
2442 * currently used key. in iwl_mvm_parse_wowlan_status_common()
2444 status->gtk[0].flags = v6->gtk.key_index | BIT(7); in iwl_mvm_parse_wowlan_status_common()
2446 struct iwl_wowlan_status_v7 *v7 = (void *)cmd.resp_pkt->data; in iwl_mvm_parse_wowlan_status_common()
2452 iwl_mvm_convert_key_counters(status, &v7->gtk[0].rsc.all_tsc_rsc); in iwl_mvm_parse_wowlan_status_common()
2453 iwl_mvm_convert_gtk_v2(status, &v7->gtk[0]); in iwl_mvm_parse_wowlan_status_common()
2454 iwl_mvm_convert_igtk(status, &v7->igtk[0]); in iwl_mvm_parse_wowlan_status_common()
2456 struct iwl_wowlan_status_v9 *v9 = (void *)cmd.resp_pkt->data; in iwl_mvm_parse_wowlan_status_common()
2465 iwl_mvm_convert_key_counters(status, &v9->gtk[0].rsc.all_tsc_rsc); in iwl_mvm_parse_wowlan_status_common()
2466 iwl_mvm_convert_gtk_v2(status, &v9->gtk[0]); in iwl_mvm_parse_wowlan_status_common()
2467 iwl_mvm_convert_igtk(status, &v9->igtk[0]); in iwl_mvm_parse_wowlan_status_common()
2469 status->tid_tear_down = v9->tid_tear_down; in iwl_mvm_parse_wowlan_status_common()
2471 struct iwl_wowlan_status_v12 *v12 = (void *)cmd.resp_pkt->data; in iwl_mvm_parse_wowlan_status_common()
2477 iwl_mvm_convert_key_counters_v5(status, &v12->gtk[0].sc); in iwl_mvm_parse_wowlan_status_common()
2478 iwl_mvm_convert_gtk_v3(status, v12->gtk); in iwl_mvm_parse_wowlan_status_common()
2479 iwl_mvm_convert_igtk(status, &v12->igtk[0]); in iwl_mvm_parse_wowlan_status_common()
2481 status->tid_tear_down = v12->tid_tear_down; in iwl_mvm_parse_wowlan_status_common()
2506 IWL_DEBUG_WOWLAN(mvm, "wakeup reason 0x%x\n", in iwl_mvm_query_wakeup_reasons()
2507 status->wakeup_reasons); in iwl_mvm_query_wakeup_reasons()
2509 /* still at hard-coded place 0 for D3 image */ in iwl_mvm_query_wakeup_reasons()
2515 u16 seq = status->qos_seq_ctr[i]; in iwl_mvm_query_wakeup_reasons()
2516 /* firmware stores last-used value, we store next value */ in iwl_mvm_query_wakeup_reasons()
2518 mvm_ap_sta->tid_data[i].seq_number = seq; in iwl_mvm_query_wakeup_reasons()
2521 if (mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22000) { in iwl_mvm_query_wakeup_reasons()
2522 i = mvm->offload_tid; in iwl_mvm_query_wakeup_reasons()
2523 iwl_trans_set_q_ptrs(mvm->trans, in iwl_mvm_query_wakeup_reasons()
2524 mvm_ap_sta->tid_data[i].txq_id, in iwl_mvm_query_wakeup_reasons()
2525 mvm_ap_sta->tid_data[i].seq_number >> 4); in iwl_mvm_query_wakeup_reasons()
2532 mutex_unlock(&mvm->mutex); in iwl_mvm_query_wakeup_reasons()
2555 int max_profiles = iwl_umac_scan_get_max_profiles(mvm->fw); in iwl_mvm_netdetect_query_results()
2563 if (fw_has_api(&mvm->fw->ucode_capa, in iwl_mvm_netdetect_query_results()
2577 ret = -EIO; in iwl_mvm_netdetect_query_results()
2581 query = (void *)cmd.resp_pkt->data; in iwl_mvm_netdetect_query_results()
2583 results->matched_profiles = le32_to_cpu(query->matched_profiles); in iwl_mvm_netdetect_query_results()
2584 memcpy(results->matches, query->matches, matches_len); in iwl_mvm_netdetect_query_results()
2587 mvm->last_netdetect_scans = le32_to_cpu(query->n_scans_done); in iwl_mvm_netdetect_query_results()
2601 if (fw_has_api(&mvm->fw->ucode_capa, in iwl_mvm_query_num_match_chans()
2604 (void *)results->matches; in iwl_mvm_query_num_match_chans()
2610 (void *)results->matches; in iwl_mvm_query_num_match_chans()
2626 if (fw_has_api(&mvm->fw->ucode_capa, in iwl_mvm_query_set_freqs()
2629 (void *)results->matches; in iwl_mvm_query_set_freqs()
2633 match->channels[match->n_channels++] = in iwl_mvm_query_set_freqs()
2634 mvm->nd_channels[i]->center_freq; in iwl_mvm_query_set_freqs()
2637 (void *)results->matches; in iwl_mvm_query_set_freqs()
2641 match->channels[match->n_channels++] = in iwl_mvm_query_set_freqs()
2642 mvm->nd_channels[i]->center_freq; in iwl_mvm_query_set_freqs()
2647 * enum iwl_d3_notif - d3 notifications
2667 u32 notif_expected; /* bitmap - see &enum iwl_d3_notif */
2668 u32 notif_received; /* bitmap - see &enum iwl_d3_notif */
2678 struct cfg80211_wowlan_wakeup wakeup = { in iwl_mvm_query_netdetect_reasons() local
2679 .pattern_idx = -1, in iwl_mvm_query_netdetect_reasons()
2681 struct cfg80211_wowlan_wakeup *wakeup_report = &wakeup; in iwl_mvm_query_netdetect_reasons()
2686 if (WARN_ON(!d3_data || !d3_data->status)) in iwl_mvm_query_netdetect_reasons()
2689 reasons = d3_data->status->wakeup_reasons; in iwl_mvm_query_netdetect_reasons()
2692 wakeup.rfkill_release = true; in iwl_mvm_query_netdetect_reasons()
2697 if (!iwl_fw_lookup_notif_ver(mvm->fw, PROT_OFFLOAD_GROUP, in iwl_mvm_query_netdetect_reasons()
2700 ret = iwl_mvm_netdetect_query_results(mvm, d3_data->nd_results); in iwl_mvm_query_netdetect_reasons()
2704 ret = d3_data->nd_results_valid ? 0 : -1; in iwl_mvm_query_netdetect_reasons()
2707 if (ret || !d3_data->nd_results->matched_profiles) { in iwl_mvm_query_netdetect_reasons()
2712 matched_profiles = d3_data->nd_results->matched_profiles; in iwl_mvm_query_netdetect_reasons()
2713 if (mvm->n_nd_match_sets) { in iwl_mvm_query_netdetect_reasons()
2725 for_each_set_bit(i, &matched_profiles, mvm->n_nd_match_sets) { in iwl_mvm_query_netdetect_reasons()
2730 d3_data->nd_results, in iwl_mvm_query_netdetect_reasons()
2738 net_detect->matches[net_detect->n_matches++] = match; in iwl_mvm_query_netdetect_reasons()
2743 idx = mvm->n_nd_match_sets - i - 1; in iwl_mvm_query_netdetect_reasons()
2744 match->ssid.ssid_len = mvm->nd_match_sets[idx].ssid.ssid_len; in iwl_mvm_query_netdetect_reasons()
2745 memcpy(match->ssid.ssid, mvm->nd_match_sets[idx].ssid.ssid, in iwl_mvm_query_netdetect_reasons()
2746 match->ssid.ssid_len); in iwl_mvm_query_netdetect_reasons()
2748 if (mvm->n_nd_channels < n_channels) in iwl_mvm_query_netdetect_reasons()
2751 iwl_mvm_query_set_freqs(mvm, d3_data->nd_results, match, i); in iwl_mvm_query_netdetect_reasons()
2755 wakeup.net_detect = net_detect; in iwl_mvm_query_netdetect_reasons()
2759 mutex_unlock(&mvm->mutex); in iwl_mvm_query_netdetect_reasons()
2763 for (i = 0; i < net_detect->n_matches; i++) in iwl_mvm_query_netdetect_reasons()
2764 kfree(net_detect->matches[i]); in iwl_mvm_query_netdetect_reasons()
2776 if (vif->type == NL80211_IFTYPE_STATION) in iwl_mvm_d3_disconnect_iter()
2805 if (iwl_mvm_rt_status(mvm->trans, in iwl_mvm_check_rt_status()
2806 mvm->trans->dbg.lmac_error_event_table[0], in iwl_mvm_check_rt_status()
2809 struct cfg80211_wowlan_wakeup wakeup = { in iwl_mvm_check_rt_status() local
2812 ieee80211_report_wowlan_wakeup(vif, &wakeup, in iwl_mvm_check_rt_status()
2819 if (iwl_mvm_rt_status(mvm->trans, in iwl_mvm_check_rt_status()
2820 mvm->trans->dbg.lmac_error_event_table[1], NULL)) in iwl_mvm_check_rt_status()
2824 if (iwl_mvm_rt_status(mvm->trans, in iwl_mvm_check_rt_status()
2825 mvm->trans->dbg.umac_error_event_table, NULL)) in iwl_mvm_check_rt_status()
2841 lockdep_assert_held(&mvm->mutex); in iwl_mvm_choose_query_wakeup_reasons()
2844 if (!d3_data->status) { in iwl_mvm_choose_query_wakeup_reasons()
2846 u8 sta_id = mvm->net_detect ? IWL_MVM_INVALID_STA : in iwl_mvm_choose_query_wakeup_reasons()
2847 mvmvif->deflink.ap_sta_id; in iwl_mvm_choose_query_wakeup_reasons()
2849 d3_data->status = iwl_mvm_send_wowlan_get_status(mvm, sta_id); in iwl_mvm_choose_query_wakeup_reasons()
2852 if (mvm->net_detect) { in iwl_mvm_choose_query_wakeup_reasons()
2856 d3_data->status); in iwl_mvm_choose_query_wakeup_reasons()
2860 mvm->keep_vif = vif; in iwl_mvm_choose_query_wakeup_reasons()
2880 u32 data_size, packet_len = le32_to_cpu(notif->wake_packet_length); in iwl_mvm_wowlan_store_wake_pkt()
2884 return -EIO; in iwl_mvm_wowlan_store_wake_pkt()
2889 return -EIO; in iwl_mvm_wowlan_store_wake_pkt()
2892 if (WARN_ON(!(status->wakeup_reasons & in iwl_mvm_wowlan_store_wake_pkt()
2894 IWL_ERR(mvm, "Got wakeup packet but wakeup reason is %x\n", in iwl_mvm_wowlan_store_wake_pkt()
2895 status->wakeup_reasons); in iwl_mvm_wowlan_store_wake_pkt()
2896 return -EIO; in iwl_mvm_wowlan_store_wake_pkt()
2899 data_size = len - offsetof(struct iwl_wowlan_wake_pkt_notif, wake_packet); in iwl_mvm_wowlan_store_wake_pkt()
2905 status->wake_packet = kmemdup(notif->wake_packet, data_size, in iwl_mvm_wowlan_store_wake_pkt()
2908 if (!status->wake_packet) in iwl_mvm_wowlan_store_wake_pkt()
2909 return -ENOMEM; in iwl_mvm_wowlan_store_wake_pkt()
2911 status->wake_packet_length = packet_len; in iwl_mvm_wowlan_store_wake_pkt()
2912 status->wake_packet_bufsize = data_size; in iwl_mvm_wowlan_store_wake_pkt()
2922 struct iwl_wowlan_status_data *status = d3_data->status; in iwl_mvm_nd_match_info_handler()
2924 struct iwl_mvm_nd_results *results = d3_data->nd_results; in iwl_mvm_nd_match_info_handler()
2926 iwl_umac_scan_get_max_profiles(mvm->fw); in iwl_mvm_nd_match_info_handler()
2936 if (!mvm->net_detect) { in iwl_mvm_nd_match_info_handler()
2941 if (!status || status->wakeup_reasons != IWL_WOWLAN_WAKEUP_BY_NON_WIRELESS) { in iwl_mvm_nd_match_info_handler()
2948 mvm->last_netdetect_scans = le32_to_cpu(notif->n_scans_done); in iwl_mvm_nd_match_info_handler()
2951 results->matched_profiles = le32_to_cpu(notif->matched_profiles); in iwl_mvm_nd_match_info_handler()
2953 results->matched_profiles); in iwl_mvm_nd_match_info_handler()
2955 if (results->matched_profiles) { in iwl_mvm_nd_match_info_handler()
2956 memcpy(results->matches, notif->matches, matches_len); in iwl_mvm_nd_match_info_handler()
2957 d3_data->nd_results_valid = TRUE; in iwl_mvm_nd_match_info_handler()
2961 mvm->scan_status = 0; in iwl_mvm_nd_match_info_handler()
2962 for (i = 0; i < mvm->max_scans; i++) in iwl_mvm_nd_match_info_handler()
2963 mvm->scan_uid_status[i] = 0; in iwl_mvm_nd_match_info_handler()
2974 int wowlan_info_ver = iwl_fw_lookup_notif_ver(mvm->fw, in iwl_mvm_wait_d3_notif()
2980 switch (WIDE_ID(pkt->hdr.group_id, pkt->hdr.cmd)) { in iwl_mvm_wait_d3_notif()
2983 if (d3_data->notif_received & IWL_D3_NOTIF_WOWLAN_INFO) { in iwl_mvm_wait_d3_notif()
2992 (void *)pkt->data; in iwl_mvm_wait_d3_notif()
3000 notif_v2->tid_tear_down = notif_v1->tid_tear_down; in iwl_mvm_wait_d3_notif()
3001 notif_v2->station_id = notif_v1->station_id; in iwl_mvm_wait_d3_notif()
3004 d3_data->status, in iwl_mvm_wait_d3_notif()
3010 (void *)pkt->data; in iwl_mvm_wait_d3_notif()
3013 d3_data->status, in iwl_mvm_wait_d3_notif()
3017 (void *)pkt->data; in iwl_mvm_wait_d3_notif()
3020 d3_data->status, len); in iwl_mvm_wait_d3_notif()
3023 d3_data->notif_received |= IWL_D3_NOTIF_WOWLAN_INFO; in iwl_mvm_wait_d3_notif()
3025 if (d3_data->status && in iwl_mvm_wait_d3_notif()
3026 d3_data->status->wakeup_reasons & IWL_WOWLAN_WAKEUP_REASON_HAS_WAKEUP_PKT) in iwl_mvm_wait_d3_notif()
3028 d3_data->notif_expected |= IWL_D3_NOTIF_WOWLAN_WAKE_PKT; in iwl_mvm_wait_d3_notif()
3033 struct iwl_wowlan_wake_pkt_notif *notif = (void *)pkt->data; in iwl_mvm_wait_d3_notif()
3035 if (d3_data->notif_received & IWL_D3_NOTIF_WOWLAN_WAKE_PKT) { in iwl_mvm_wait_d3_notif()
3040 d3_data->notif_received |= IWL_D3_NOTIF_WOWLAN_WAKE_PKT; in iwl_mvm_wait_d3_notif()
3043 d3_data->status, in iwl_mvm_wait_d3_notif()
3053 struct iwl_scan_offload_match_info *notif = (void *)pkt->data; in iwl_mvm_wait_d3_notif()
3055 if (d3_data->notif_received & IWL_D3_ND_MATCH_INFO) { in iwl_mvm_wait_d3_notif()
3061 d3_data->notif_received |= IWL_D3_ND_MATCH_INFO; in iwl_mvm_wait_d3_notif()
3064 d3_data->notif_expected |= IWL_D3_ND_MATCH_INFO; in iwl_mvm_wait_d3_notif()
3071 struct iwl_mvm_d3_end_notif *notif = (void *)pkt->data; in iwl_mvm_wait_d3_notif()
3073 d3_data->d3_end_flags = __le32_to_cpu(notif->flags); in iwl_mvm_wait_d3_notif()
3074 d3_data->notif_received |= IWL_D3_NOTIF_D3_END_NOTIF; in iwl_mvm_wait_d3_notif()
3082 return d3_data->notif_received == d3_data->notif_expected; in iwl_mvm_wait_d3_notif()
3093 bool reset = fw_has_capa(&mvm->fw->ucode_capa, in iwl_mvm_resume_firmware()
3096 ret = iwl_trans_d3_resume(mvm->trans, &d3_status, test, !reset); in iwl_mvm_resume_firmware()
3102 return -ENOENT; in iwl_mvm_resume_firmware()
3110 if (mvm->trans->trans_cfg->device_family <= IWL_DEVICE_FAMILY_22000 && in iwl_mvm_resume_firmware()
3111 fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_D0I3_END_FIRST)) { in iwl_mvm_resume_firmware()
3135 iwl_init_notification_wait(&mvm->notif_wait, &wait_d3_notif, in iwl_mvm_d3_notif_wait()
3139 ret = iwl_mvm_resume_firmware(mvm, d3_data->test); in iwl_mvm_d3_notif_wait()
3141 iwl_remove_notification(&mvm->notif_wait, &wait_d3_notif); in iwl_mvm_d3_notif_wait()
3145 return iwl_wait_notification(&mvm->notif_wait, &wait_d3_notif, in iwl_mvm_d3_notif_wait()
3151 return iwl_fw_lookup_notif_ver(mvm->fw, PROT_OFFLOAD_GROUP, in iwl_mvm_d3_resume_notif_based()
3153 iwl_fw_lookup_notif_ver(mvm->fw, PROT_OFFLOAD_GROUP, in iwl_mvm_d3_resume_notif_based()
3155 iwl_fw_lookup_notif_ver(mvm->fw, PROT_OFFLOAD_GROUP, in iwl_mvm_d3_resume_notif_based()
3172 bool unified_image = fw_has_capa(&mvm->fw->ucode_capa, in __iwl_mvm_resume()
3174 bool d0i3_first = fw_has_capa(&mvm->fw->ucode_capa, in __iwl_mvm_resume()
3179 mutex_lock(&mvm->mutex); in __iwl_mvm_resume()
3181 mvm->last_reset_or_resume_time_jiffies = jiffies; in __iwl_mvm_resume()
3188 iwl_fw_dbg_read_d3_debug_data(&mvm->fwrt); in __iwl_mvm_resume()
3191 set_bit(STATUS_FW_ERROR, &mvm->trans->status); in __iwl_mvm_resume()
3193 iwl_dbg_tlv_time_point(&mvm->fwrt, in __iwl_mvm_resume()
3195 iwl_fw_dbg_collect_desc(&mvm->fwrt, &iwl_dump_desc_assert, in __iwl_mvm_resume()
3205 ret = -ENOMEM; in __iwl_mvm_resume()
3219 mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_DISABLED; in __iwl_mvm_resume()
3227 * can play it back when we re-intiailize the D0 firmware in __iwl_mvm_resume()
3231 /* Re-configure PPAG settings */ in __iwl_mvm_resume()
3235 /* Re-configure default SAR profile */ in __iwl_mvm_resume()
3238 if (mvm->net_detect && unified_image) { in __iwl_mvm_resume()
3239 /* If this is a non-unified image, we restart the FW, in __iwl_mvm_resume()
3241 * fails, continue and try to get the wake-up reasons, in __iwl_mvm_resume()
3255 mutex_unlock(&mvm->mutex); in __iwl_mvm_resume()
3258 kfree(d3_data.status->wake_packet); in __iwl_mvm_resume()
3262 if (!d3_data.test && !mvm->net_detect) in __iwl_mvm_resume()
3263 ieee80211_iterate_active_interfaces_mtx(mvm->hw, in __iwl_mvm_resume()
3268 clear_bit(IWL_MVM_STATUS_IN_D3, &mvm->status); in __iwl_mvm_resume()
3276 if (!iwl_fw_lookup_notif_ver(mvm->fw, PROT_OFFLOAD_GROUP, in __iwl_mvm_resume()
3291 set_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, &mvm->status); in __iwl_mvm_resume()
3294 mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_DISABLED; in __iwl_mvm_resume()
3308 iwl_fw_runtime_resume(&mvm->fwrt); in iwl_mvm_resume()
3317 device_set_wakeup_enable(mvm->trans->dev, enabled); in iwl_mvm_set_wakeup()
3323 struct iwl_mvm *mvm = inode->i_private; in iwl_mvm_d3_test_open()
3326 if (mvm->d3_test_active) in iwl_mvm_d3_test_open()
3327 return -EBUSY; in iwl_mvm_d3_test_open()
3329 file->private_data = inode->i_private; in iwl_mvm_d3_test_open()
3333 iwl_fw_runtime_suspend(&mvm->fwrt); in iwl_mvm_d3_test_open()
3337 wiphy_lock(mvm->hw->wiphy); in iwl_mvm_d3_test_open()
3338 err = __iwl_mvm_suspend(mvm->hw, mvm->hw->wiphy->wowlan_config, true); in iwl_mvm_d3_test_open()
3339 wiphy_unlock(mvm->hw->wiphy); in iwl_mvm_d3_test_open()
3342 err = -EINVAL; in iwl_mvm_d3_test_open()
3346 mvm->d3_test_active = true; in iwl_mvm_d3_test_open()
3347 mvm->keep_vif = NULL; in iwl_mvm_d3_test_open()
3354 struct iwl_mvm *mvm = file->private_data; in iwl_mvm_d3_test_read()
3359 if (mvm->d3_test_pme_ptr) { in iwl_mvm_d3_test_read()
3360 pme_asserted = iwl_trans_read_mem32(mvm->trans, in iwl_mvm_d3_test_read()
3361 mvm->d3_test_pme_ptr); in iwl_mvm_d3_test_read()
3380 if (vif->type == NL80211_IFTYPE_STATION) in iwl_mvm_d3_test_disconn_work_iter()
3386 struct iwl_mvm *mvm = inode->i_private; in iwl_mvm_d3_test_release()
3387 bool unified_image = fw_has_capa(&mvm->fw->ucode_capa, in iwl_mvm_d3_test_release()
3390 mvm->d3_test_active = false; in iwl_mvm_d3_test_release()
3392 iwl_fw_dbg_read_d3_debug_data(&mvm->fwrt); in iwl_mvm_d3_test_release()
3395 wiphy_lock(mvm->hw->wiphy); in iwl_mvm_d3_test_release()
3397 wiphy_unlock(mvm->hw->wiphy); in iwl_mvm_d3_test_release()
3402 iwl_fw_runtime_resume(&mvm->fwrt); in iwl_mvm_d3_test_release()
3404 iwl_abort_notification_waits(&mvm->notif_wait); in iwl_mvm_d3_test_release()
3408 ieee80211_restart_hw(mvm->hw); in iwl_mvm_d3_test_release()
3411 while (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) && in iwl_mvm_d3_test_release()
3413 remaining_time--; in iwl_mvm_d3_test_release()
3422 mvm->hw, IEEE80211_IFACE_ITER_NORMAL, in iwl_mvm_d3_test_release()
3423 iwl_mvm_d3_test_disconn_work_iter, mvm->keep_vif); in iwl_mvm_d3_test_release()