/******************************************************************************
 *
 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
 * Copyright(c) 2018        Intel Corporation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  * Neither the name Intel Corporation nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *****************************************************************************/

#include <net/addrconf.h>
#include <net/cfg80211.h>
#include <net/ipv6.h>
#include <net/tcp.h>

#include <ddk/hw/wlan/ieee80211/c/banjo.h>
#include <linux/etherdevice.h>
#include <linux/fs.h>
#include <linux/ip.h>

#include "fw-api.h"
#include "iwl-modparams.h"
#include "mvm.h"

void iwl_mvm_set_rekey_data(struct ieee80211_hw* hw, struct ieee80211_vif* vif,
                            struct cfg80211_gtk_rekey_data* data) {
  struct iwl_mvm* mvm = IWL_MAC80211_GET_MVM(hw);
  struct iwl_mvm_vif* mvmvif = iwl_mvm_vif_from_mac80211(vif);

  if (iwlwifi_mod_params.swcrypto) {
    return;
  }

  mutex_lock(&mvm->mutex);

  memcpy(mvmvif->rekey_data.kek, data->kek, NL80211_KEK_LEN);
  memcpy(mvmvif->rekey_data.kck, data->kck, NL80211_KCK_LEN);
  mvmvif->rekey_data.replay_ctr = cpu_to_le64(be64_to_cpup((__be64*)data->replay_ctr));
  mvmvif->rekey_data.valid = true;

  mutex_unlock(&mvm->mutex);
}

#if IS_ENABLED(CONFIG_IPV6)
void iwl_mvm_ipv6_addr_change(struct ieee80211_hw* hw, struct ieee80211_vif* vif,
                              struct inet6_dev* idev) {
  struct iwl_mvm_vif* mvmvif = iwl_mvm_vif_from_mac80211(vif);
  struct inet6_ifaddr* ifa;
  int idx = 0;

  memset(mvmvif->tentative_addrs, 0, sizeof(mvmvif->tentative_addrs));

  read_lock_bh(&idev->lock);
  list_for_each_entry(ifa, &idev->addr_list, if_list) {
    mvmvif->target_ipv6_addrs[idx] = ifa->addr;
    if (ifa->flags & IFA_F_TENTATIVE) {
      __set_bit(idx, mvmvif->tentative_addrs);
    }
    idx++;
    if (idx >= IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_MAX) {
      break;
    }
  }
  read_unlock_bh(&idev->lock);

  mvmvif->num_target_ipv6_addrs = idx;
}
#endif

void iwl_mvm_set_default_unicast_key(struct ieee80211_hw* hw, struct ieee80211_vif* vif, int idx) {
  struct iwl_mvm_vif* mvmvif = iwl_mvm_vif_from_mac80211(vif);

  mvmvif->tx_key_idx = idx;
}

static void iwl_mvm_convert_p1k(uint16_t* p1k, __le16* out) {
  int i;

  for (i = 0; i < IWL_P1K_SIZE; i++) {
    out[i] = cpu_to_le16(p1k[i]);
  }
}

static const uint8_t* iwl_mvm_find_max_pn(struct ieee80211_key_conf* key,
                                          struct iwl_mvm_key_pn* ptk_pn,
                                          struct ieee80211_key_seq* seq, int tid, int queues) {
  const uint8_t* ret = seq->ccmp.pn;
  int i;

  /* get the PN from mac80211, used on the default queue */
  ieee80211_get_key_rx_seq(key, tid, seq);

  /* and use the internal data for the other queues */
  for (i = 1; i < queues; i++) {
    const uint8_t* tmp = ptk_pn->q[i].pn[tid];

    if (memcmp(ret, tmp, fuchsia_wlan_ieee80211_CCMP_PN_LEN) <= 0) {
      ret = tmp;
    }
  }

  return ret;
}

struct wowlan_key_data {
  struct iwl_wowlan_rsc_tsc_params_cmd* rsc_tsc;
  struct iwl_wowlan_tkip_params_cmd* tkip;
  bool error, use_rsc_tsc, use_tkip, configure_keys;
  int wep_key_idx;
};

static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw* hw, struct ieee80211_vif* vif,
                                        struct ieee80211_sta* sta, struct ieee80211_key_conf* key,
                                        void* _data) {
  struct iwl_mvm* mvm = IWL_MAC80211_GET_MVM(hw);
  struct iwl_mvm_vif* mvmvif = iwl_mvm_vif_from_mac80211(vif);
  struct wowlan_key_data* data = _data;
  struct aes_sc *aes_sc, *aes_tx_sc = NULL;
  struct tkip_sc *tkip_sc, *tkip_tx_sc = NULL;
  struct iwl_p1k_cache* rx_p1ks;
  uint8_t* rx_mic_key;
  struct ieee80211_key_seq seq;
  uint32_t cur_rx_iv32 = 0;
  uint16_t p1k[IWL_P1K_SIZE];
  int ret, i;

  switch (key->cipher) {
    case WLAN_CIPHER_SUITE_WEP40:
    case WLAN_CIPHER_SUITE_WEP104: { /* hack it for now */
      struct {
        struct iwl_mvm_wep_key_cmd wep_key_cmd;
        struct iwl_mvm_wep_key wep_key;
      } __packed wkc = {
          .wep_key_cmd.mac_id_n_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color)),
          .wep_key_cmd.num_keys = 1,
          /* firmware sets STA_KEY_FLG_WEP_13BYTES */
          .wep_key_cmd.decryption_type = STA_KEY_FLG_WEP,
          .wep_key.key_index = key->keyidx,
          .wep_key.key_size = key->keylen,
      };

      /*
       * This will fail -- the key functions don't set support
       * pairwise WEP keys. However, that's better than silently
       * failing WoWLAN. Or maybe not?
       */
      if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
        break;
      }

      memcpy(&wkc.wep_key.key[3], key->key, key->keylen);
      if (key->keyidx == mvmvif->tx_key_idx) {
        /* TX key must be at offset 0 */
        wkc.wep_key.key_offset = 0;
      } else {
        /* others start at 1 */
        data->wep_key_idx++;
        wkc.wep_key.key_offset = data->wep_key_idx;
      }

      if (data->configure_keys) {
        mutex_lock(&mvm->mutex);
        ret = iwl_mvm_send_cmd_pdu(mvm, WEP_KEY, 0, sizeof(wkc), &wkc);
        data->error = ret != 0;

        mvm->ptk_ivlen = key->iv_len;
        mvm->ptk_icvlen = key->icv_len;
        mvm->gtk_ivlen = key->iv_len;
        mvm->gtk_icvlen = key->icv_len;
        mutex_unlock(&mvm->mutex);
      }

      /* don't upload key again */
      return;
    }
    default:
      data->error = true;
      return;
    case WLAN_CIPHER_SUITE_AES_CMAC:
      /*
       * Ignore CMAC keys -- the WoWLAN firmware doesn't support them
       * but we also shouldn't abort suspend due to that. It does have
       * support for the IGTK key renewal, but doesn't really use the
       * IGTK for anything. This means we could spuriously wake up or
       * be deauthenticated, but that was considered acceptable.
       */
      return;
    case WLAN_CIPHER_SUITE_TKIP:
      if (sta) {
        uint64_t pn64;

        tkip_sc = data->rsc_tsc->all_tsc_rsc.tkip.unicast_rsc;
        tkip_tx_sc = &data->rsc_tsc->all_tsc_rsc.tkip.tsc;

        rx_p1ks = data->tkip->rx_uni;

        pn64 = atomic64_read(&key->tx_pn);
        tkip_tx_sc->iv16 = cpu_to_le16(TKIP_PN_TO_IV16(pn64));
        tkip_tx_sc->iv32 = cpu_to_le32(TKIP_PN_TO_IV32(pn64));

        ieee80211_get_tkip_p1k_iv(key, TKIP_PN_TO_IV32(pn64), p1k);
        iwl_mvm_convert_p1k(p1k, data->tkip->tx.p1k);

        memcpy(data->tkip->mic_keys.tx, &key->key[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY],
               IWL_MIC_KEY_SIZE);

        rx_mic_key = data->tkip->mic_keys.rx_unicast;
      } else {
        tkip_sc = data->rsc_tsc->all_tsc_rsc.tkip.multicast_rsc;
        rx_p1ks = data->tkip->rx_multi;
        rx_mic_key = data->tkip->mic_keys.rx_mcast;
      }

      /*
       * For non-QoS this relies on the fact that both the uCode and
       * mac80211 use TID 0 (as they need to to avoid replay attacks)
       * for checking the IV in the frames.
       */
      for (i = 0; i < IWL_NUM_RSC; i++) {
        ieee80211_get_key_rx_seq(key, i, &seq);
        tkip_sc[i].iv16 = cpu_to_le16(seq.tkip.iv16);
        tkip_sc[i].iv32 = cpu_to_le32(seq.tkip.iv32);
        /* wrapping isn't allowed, AP must rekey */
        if (seq.tkip.iv32 > cur_rx_iv32) {
          cur_rx_iv32 = seq.tkip.iv32;
        }
      }

      ieee80211_get_tkip_rx_p1k(key, vif->bss_conf.bssid, cur_rx_iv32, p1k);
      iwl_mvm_convert_p1k(p1k, rx_p1ks[0].p1k);
      ieee80211_get_tkip_rx_p1k(key, vif->bss_conf.bssid, cur_rx_iv32 + 1, p1k);
      iwl_mvm_convert_p1k(p1k, rx_p1ks[1].p1k);

      memcpy(rx_mic_key, &key->key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY], IWL_MIC_KEY_SIZE);

      data->use_tkip = true;
      data->use_rsc_tsc = true;
      break;
    case WLAN_CIPHER_SUITE_CCMP:
      if (sta) {
        uint64_t pn64;

        aes_sc = data->rsc_tsc->all_tsc_rsc.aes.unicast_rsc;
        aes_tx_sc = &data->rsc_tsc->all_tsc_rsc.aes.tsc;

        pn64 = atomic64_read(&key->tx_pn);
        aes_tx_sc->pn = cpu_to_le64(pn64);
      } else {
        aes_sc = data->rsc_tsc->all_tsc_rsc.aes.multicast_rsc;
      }

      /*
       * For non-QoS this relies on the fact that both the uCode and
       * mac80211/our RX code use TID 0 for checking the PN.
       */
      if (sta && iwl_mvm_has_new_rx_api(mvm)) {
        struct iwl_mvm_sta* mvmsta;
        struct iwl_mvm_key_pn* ptk_pn;
        const uint8_t* pn;

        mvmsta = iwl_mvm_sta_from_mac80211(sta);
        ptk_pn =
            rcu_dereference_protected(mvmsta->ptk_pn[key->keyidx], lockdep_is_held(&mvm->mutex));
        if (WARN_ON(!ptk_pn)) {
          break;
        }

        for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
          pn = iwl_mvm_find_max_pn(key, ptk_pn, &seq, i, mvm->trans->num_rx_queues);
          aes_sc[i].pn = cpu_to_le64((uint64_t)pn[5] | ((uint64_t)pn[4] << 8) |
                                     ((uint64_t)pn[3] << 16) | ((uint64_t)pn[2] << 24) |
                                     ((uint64_t)pn[1] << 32) | ((uint64_t)pn[0] << 40));
        }
      } else {
        for (i = 0; i < IWL_NUM_RSC; i++) {
          uint8_t* pn = seq.ccmp.pn;

          ieee80211_get_key_rx_seq(key, i, &seq);
          aes_sc[i].pn = cpu_to_le64((uint64_t)pn[5] | ((uint64_t)pn[4] << 8) |
                                     ((uint64_t)pn[3] << 16) | ((uint64_t)pn[2] << 24) |
                                     ((uint64_t)pn[1] << 32) | ((uint64_t)pn[0] << 40));
        }
      }
      data->use_rsc_tsc = true;
      break;
  }

  if (data->configure_keys) {
    mutex_lock(&mvm->mutex);
    /*
     * The D3 firmware hardcodes the key offset 0 as the key it
     * uses to transmit packets to the AP, i.e. the PTK.
     */
    if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
      mvm->ptk_ivlen = key->iv_len;
      mvm->ptk_icvlen = key->icv_len;
      ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, 0);
    } else {
      /*
       * firmware only supports TSC/RSC for a single key,
       * so if there are multiple keep overwriting them
       * with new ones -- this relies on mac80211 doing
       * list_add_tail().
       */
      mvm->gtk_ivlen = key->iv_len;
      mvm->gtk_icvlen = key->icv_len;
      ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, 1);
    }
    mutex_unlock(&mvm->mutex);
    data->error = ret != 0;
  }
}

static int iwl_mvm_send_patterns(struct iwl_mvm* mvm, struct cfg80211_wowlan* wowlan) {
  struct iwl_wowlan_patterns_cmd* pattern_cmd;
  struct iwl_host_cmd cmd = {
      .id = WOWLAN_PATTERNS,
      .dataflags[0] = IWL_HCMD_DFL_NOCOPY,
  };
  int i, err;

  if (!wowlan->n_patterns) {
    return 0;
  }

  cmd.len[0] = sizeof(*pattern_cmd) + wowlan->n_patterns * sizeof(struct iwl_wowlan_pattern);

  pattern_cmd = kmalloc(cmd.len[0], GFP_KERNEL);
  if (!pattern_cmd) {
    return -ENOMEM;
  }

  pattern_cmd->n_patterns = cpu_to_le32(wowlan->n_patterns);

  for (i = 0; i < wowlan->n_patterns; i++) {
    int mask_len = DIV_ROUND_UP(wowlan->patterns[i].pattern_len, 8);

    memcpy(&pattern_cmd->patterns[i].mask, wowlan->patterns[i].mask, mask_len);
    memcpy(&pattern_cmd->patterns[i].pattern, wowlan->patterns[i].pattern,
           wowlan->patterns[i].pattern_len);
    pattern_cmd->patterns[i].mask_size = mask_len;
    pattern_cmd->patterns[i].pattern_size = wowlan->patterns[i].pattern_len;
  }

  cmd.data[0] = pattern_cmd;
  err = iwl_mvm_send_cmd(mvm, &cmd);
  kfree(pattern_cmd);
  return err;
}

static int iwl_mvm_d3_reprogram(struct iwl_mvm* mvm, struct ieee80211_vif* vif,
                                struct ieee80211_sta* ap_sta) {
  struct iwl_mvm_vif* mvmvif = iwl_mvm_vif_from_mac80211(vif);
  struct ieee80211_chanctx_conf* ctx;
  uint8_t chains_static, chains_dynamic;
  struct cfg80211_chan_def chandef;
  int ret, i;
  struct iwl_binding_cmd_v1 binding_cmd = {};
  struct iwl_time_quota_cmd quota_cmd = {};
  struct iwl_time_quota_data* quota;
  uint32_t status;

  if (WARN_ON_ONCE(iwl_mvm_is_cdb_supported(mvm))) {
    return -EINVAL;
  }

  /* add back the PHY */
  if (WARN_ON(!mvmvif->phy_ctxt)) {
    return -EINVAL;
  }

  rcu_read_lock();
  ctx = rcu_dereference(vif->chanctx_conf);
  if (WARN_ON(!ctx)) {
    rcu_read_unlock();
    return -EINVAL;
  }
  chandef = ctx->def;
  chains_static = ctx->rx_chains_static;
  chains_dynamic = ctx->rx_chains_dynamic;
  rcu_read_unlock();

  ret = iwl_mvm_phy_ctxt_add(mvm, mvmvif->phy_ctxt, &chandef, chains_static, chains_dynamic);
  if (ret) {
    return ret;
  }

  /* add back the MAC */
  mvmvif->uploaded = false;

  if (WARN_ON(!vif->bss_conf.assoc)) {
    return -EINVAL;
  }

  ret = iwl_mvm_mac_ctxt_add(mvm, vif);
  if (ret) {
    return ret;
  }

  /* add back binding - XXX refactor? */
  binding_cmd.id_and_color =
      cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->phy_ctxt->id, mvmvif->phy_ctxt->color));
  binding_cmd.action = cpu_to_le32(FW_CTXT_ACTION_ADD);
  binding_cmd.phy = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->phy_ctxt->id, mvmvif->phy_ctxt->color));
  binding_cmd.macs[0] = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color));
  for (i = 1; i < MAX_MACS_IN_BINDING; i++) {
    binding_cmd.macs[i] = cpu_to_le32(FW_CTXT_INVALID);
  }

  status = 0;
  ret = iwl_mvm_send_cmd_pdu_status(mvm, BINDING_CONTEXT_CMD, IWL_BINDING_CMD_SIZE_V1, &binding_cmd,
                                    &status);
  if (ret) {
    IWL_ERR(mvm, "Failed to add binding: %d\n", ret);
    return ret;
  }

  if (status) {
    IWL_ERR(mvm, "Binding command failed: %u\n", status);
    return -EIO;
  }

  ret = iwl_mvm_sta_send_to_fw(mvm, ap_sta, false, 0);
  if (ret) {
    return ret;
  }
  rcu_assign_pointer(mvm->fw_id_to_mac_id[mvmvif->ap_sta_id], ap_sta);

  ret = iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
  if (ret) {
    return ret;
  }

  /* and some quota */
  quota = iwl_mvm_quota_cmd_get_quota(mvm, &quota_cmd, 0);
  quota->id_and_color =
      cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->phy_ctxt->id, mvmvif->phy_ctxt->color));
  quota->quota = cpu_to_le32(IWL_MVM_MAX_QUOTA);
  quota->max_duration = cpu_to_le32(IWL_MVM_MAX_QUOTA);

  for (i = 1; i < MAX_BINDINGS; i++) {
    quota = iwl_mvm_quota_cmd_get_quota(mvm, &quota_cmd, i);
    quota->id_and_color = cpu_to_le32(FW_CTXT_INVALID);
  }

  ret = iwl_mvm_send_cmd_pdu(mvm, TIME_QUOTA_CMD, 0, iwl_mvm_quota_cmd_size(mvm), &quota_cmd);
  if (ret) {
    IWL_ERR(mvm, "Failed to send quota: %d\n", ret);
  }

  if (iwl_mvm_is_lar_supported(mvm) && iwl_mvm_init_fw_regd(mvm)) {
    IWL_ERR(mvm, "Failed to initialize D3 LAR information\n");
  }

  return 0;
}

static int iwl_mvm_get_last_nonqos_seq(struct iwl_mvm* mvm, struct ieee80211_vif* vif) {
  struct iwl_mvm_vif* mvmvif = iwl_mvm_vif_from_mac80211(vif);
  struct iwl_nonqos_seq_query_cmd query_cmd = {
      .get_set_flag = cpu_to_le32(IWL_NONQOS_SEQ_GET),
      .mac_id_n_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color)),
  };
  struct iwl_host_cmd cmd = {
      .id = NON_QOS_TX_COUNTER_CMD,
      .flags = CMD_WANT_SKB,
  };
  int err;
  uint32_t size;

  cmd.data[0] = &query_cmd;
  cmd.len[0] = sizeof(query_cmd);

  err = iwl_mvm_send_cmd(mvm, &cmd);
  if (err) {
    return err;
  }

  size = iwl_rx_packet_payload_len(cmd.resp_pkt);
  if (size < sizeof(__le16)) {
    err = -EINVAL;
  } else {
    err = le16_to_cpup((__le16*)cmd.resp_pkt->data);
    /* firmware returns next, not last-used seqno */
    err = (uint16_t)(err - 0x10);
  }

  iwl_free_resp(&cmd);
  return err;
}

void iwl_mvm_set_last_nonqos_seq(struct iwl_mvm* mvm, struct ieee80211_vif* vif) {
  struct iwl_mvm_vif* mvmvif = iwl_mvm_vif_from_mac80211(vif);
  struct iwl_nonqos_seq_query_cmd query_cmd = {
      .get_set_flag = cpu_to_le32(IWL_NONQOS_SEQ_SET),
      .mac_id_n_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color)),
      .value = cpu_to_le16(mvmvif->seqno),
  };

  /* return if called during restart, not resume from D3 */
  if (!mvmvif->seqno_valid) {
    return;
  }

  mvmvif->seqno_valid = false;

  if (iwl_mvm_send_cmd_pdu(mvm, NON_QOS_TX_COUNTER_CMD, 0, sizeof(query_cmd), &query_cmd)) {
    IWL_ERR(mvm, "failed to set non-QoS seqno\n");
  }
}

static int iwl_mvm_switch_to_d3(struct iwl_mvm* mvm) {
  iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_REGULAR, true);

  iwl_mvm_stop_device(mvm);
  /*
   * Set the HW restart bit -- this is mostly true as we're
   * going to load new firmware and reprogram that, though
   * the reprogramming is going to be manual to avoid adding
   * all the MACs that aren't support.
   * We don't have to clear up everything though because the
   * reprogramming is manual. When we resume, we'll actually
   * go through a proper restart sequence again to switch
   * back to the runtime firmware image.
   */
  set_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);

  /* the fw is reset, so all the keys are cleared */
  memset(mvm->fw_key_table, 0, sizeof(mvm->fw_key_table));

  mvm->ptk_ivlen = 0;
  mvm->ptk_icvlen = 0;
  mvm->ptk_ivlen = 0;
  mvm->ptk_icvlen = 0;

  return iwl_mvm_load_d3_fw(mvm);
}

static int iwl_mvm_get_wowlan_config(struct iwl_mvm* mvm, struct cfg80211_wowlan* wowlan,
                                     struct iwl_wowlan_config_cmd* wowlan_config_cmd,
                                     struct ieee80211_vif* vif, struct iwl_mvm_vif* mvmvif,
                                     struct ieee80211_sta* ap_sta) {
  int ret;
  struct iwl_mvm_sta* mvm_ap_sta = iwl_mvm_sta_from_mac80211(ap_sta);

  /* TODO: wowlan_config_cmd->wowlan_ba_teardown_tids */

  wowlan_config_cmd->is_11n_connection = ap_sta->ht_cap.ht_supported;
  wowlan_config_cmd->flags = ENABLE_L3_FILTERING | ENABLE_NBNS_FILTERING | ENABLE_DHCP_FILTERING;

  /* Query the last used seqno and set it */
  ret = iwl_mvm_get_last_nonqos_seq(mvm, vif);
  if (ret < 0) {
    return ret;
  }

  wowlan_config_cmd->non_qos_seq = cpu_to_le16(ret);

  iwl_mvm_set_wowlan_qos_seq(mvm_ap_sta, wowlan_config_cmd);

  if (wowlan->disconnect)
    wowlan_config_cmd->wakeup_filter |=
        cpu_to_le32(IWL_WOWLAN_WAKEUP_BEACON_MISS | IWL_WOWLAN_WAKEUP_LINK_CHANGE);
  if (wowlan->magic_pkt) {
    wowlan_config_cmd->wakeup_filter |= cpu_to_le32(IWL_WOWLAN_WAKEUP_MAGIC_PACKET);
  }
  if (wowlan->gtk_rekey_failure) {
    wowlan_config_cmd->wakeup_filter |= cpu_to_le32(IWL_WOWLAN_WAKEUP_GTK_REKEY_FAIL);
  }
  if (wowlan->eap_identity_req) {
    wowlan_config_cmd->wakeup_filter |= cpu_to_le32(IWL_WOWLAN_WAKEUP_EAP_IDENT_REQ);
  }
  if (wowlan->four_way_handshake) {
    wowlan_config_cmd->wakeup_filter |= cpu_to_le32(IWL_WOWLAN_WAKEUP_4WAY_HANDSHAKE);
  }
  if (wowlan->n_patterns) {
    wowlan_config_cmd->wakeup_filter |= cpu_to_le32(IWL_WOWLAN_WAKEUP_PATTERN_MATCH);
  }

  if (wowlan->rfkill_release) {
    wowlan_config_cmd->wakeup_filter |= cpu_to_le32(IWL_WOWLAN_WAKEUP_RF_KILL_DEASSERT);
  }

  if (wowlan->tcp) {
    /*
     * Set the "link change" (really "link lost") flag as well
     * since that implies losing the TCP connection.
     */
    wowlan_config_cmd->wakeup_filter |=
        cpu_to_le32(IWL_WOWLAN_WAKEUP_REMOTE_LINK_LOSS | IWL_WOWLAN_WAKEUP_REMOTE_SIGNATURE_TABLE |
                    IWL_WOWLAN_WAKEUP_REMOTE_WAKEUP_PACKET | IWL_WOWLAN_WAKEUP_LINK_CHANGE);
  }

  if (wowlan->any) {
    wowlan_config_cmd->wakeup_filter |=
        cpu_to_le32(IWL_WOWLAN_WAKEUP_BEACON_MISS | IWL_WOWLAN_WAKEUP_LINK_CHANGE |
                    IWL_WOWLAN_WAKEUP_RX_FRAME | IWL_WOWLAN_WAKEUP_BCN_FILTERING);
  }

  return 0;
}

static void iwl_mvm_iter_d0i3_ap_keys(struct iwl_mvm* mvm, struct ieee80211_vif* vif,
                                      void (*iter)(struct ieee80211_hw* hw,
                                                   struct ieee80211_vif* vif,
                                                   struct ieee80211_sta* sta,
                                                   struct ieee80211_key_conf* key, void* data),
                                      void* data) {
  struct ieee80211_sta* ap_sta;

  rcu_read_lock();

  ap_sta = rcu_dereference(mvm->fw_id_to_mac_id[mvm->d0i3_ap_sta_id]);
  if (IS_ERR_OR_NULL(ap_sta)) {
    goto out;
  }

  ieee80211_iter_keys_rcu(mvm->hw, vif, iter, data);
out:
  rcu_read_unlock();
}

int iwl_mvm_wowlan_config_key_params(struct iwl_mvm* mvm, struct ieee80211_vif* vif, bool d0i3,
                                     uint32_t cmd_flags) {
  struct iwl_wowlan_kek_kck_material_cmd kek_kck_cmd = {};
  struct iwl_wowlan_tkip_params_cmd tkip_cmd = {};
  bool unified = fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);
  struct wowlan_key_data key_data = {
      .configure_keys = !d0i3 && !unified,
      .use_rsc_tsc = false,
      .tkip = &tkip_cmd,
      .use_tkip = false,
  };
  struct iwl_mvm_vif* mvmvif = iwl_mvm_vif_from_mac80211(vif);
  int ret;

  key_data.rsc_tsc = kzalloc(sizeof(*key_data.rsc_tsc), GFP_KERNEL);
  if (!key_data.rsc_tsc) {
    return -ENOMEM;
  }

  /*
   * if we have to configure keys, call ieee80211_iter_keys(),
   * as we need non-atomic context in order to take the
   * required locks.
   * for the d0i3 we can't use ieee80211_iter_keys(), as
   * taking (almost) any mutex might result in deadlock.
   */
  if (!d0i3) {
    /*
     * Note that currently we don't propagate cmd_flags
     * to the iterator. In case of key_data.configure_keys,
     * all the configured commands are SYNC, and
     * iwl_mvm_wowlan_program_keys() will take care of
     * locking/unlocking mvm->mutex.
     */
    ieee80211_iter_keys(mvm->hw, vif, iwl_mvm_wowlan_program_keys, &key_data);
  } else {
    iwl_mvm_iter_d0i3_ap_keys(mvm, vif, iwl_mvm_wowlan_program_keys, &key_data);
  }

  if (key_data.error) {
    ret = -EIO;
    goto out;
  }

  if (key_data.use_rsc_tsc) {
    ret = iwl_mvm_send_cmd_pdu(mvm, WOWLAN_TSC_RSC_PARAM, cmd_flags, sizeof(*key_data.rsc_tsc),
                               key_data.rsc_tsc);
    if (ret) {
      goto out;
    }
  }

  if (key_data.use_tkip && !fw_has_api(&mvm->fw->ucode_capa, IWL_UCODE_TLV_API_TKIP_MIC_KEYS)) {
    ret = iwl_mvm_send_cmd_pdu(mvm, WOWLAN_TKIP_PARAM, cmd_flags, sizeof(tkip_cmd), &tkip_cmd);
    if (ret) {
      goto out;
    }
  }

  /* configure rekey data only if offloaded rekey is supported (d3) */
  if (mvmvif->rekey_data.valid && !d0i3) {
    memset(&kek_kck_cmd, 0, sizeof(kek_kck_cmd));
    memcpy(kek_kck_cmd.kck, mvmvif->rekey_data.kck, NL80211_KCK_LEN);
    kek_kck_cmd.kck_len = cpu_to_le16(NL80211_KCK_LEN);
    memcpy(kek_kck_cmd.kek, mvmvif->rekey_data.kek, NL80211_KEK_LEN);
    kek_kck_cmd.kek_len = cpu_to_le16(NL80211_KEK_LEN);
    kek_kck_cmd.replay_ctr = mvmvif->rekey_data.replay_ctr;

    ret = iwl_mvm_send_cmd_pdu(mvm, WOWLAN_KEK_KCK_MATERIAL, cmd_flags, sizeof(kek_kck_cmd),
                               &kek_kck_cmd);
    if (ret) {
      goto out;
    }
  }
  ret = 0;
out:
  kfree(key_data.rsc_tsc);
  return ret;
}

static int iwl_mvm_wowlan_config(struct iwl_mvm* mvm, struct cfg80211_wowlan* wowlan,
                                 struct iwl_wowlan_config_cmd* wowlan_config_cmd,
                                 struct ieee80211_vif* vif, struct iwl_mvm_vif* mvmvif,
                                 struct ieee80211_sta* ap_sta) {
  int ret;
  bool unified_image = fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);

  if (!unified_image) {
    ret = iwl_mvm_switch_to_d3(mvm);
    if (ret) {
      return ret;
    }

    ret = iwl_mvm_d3_reprogram(mvm, vif, ap_sta);
    if (ret) {
      return ret;
    }
  }

  if (!iwlwifi_mod_params.swcrypto) {
    /*
     * This needs to be unlocked due to lock ordering
     * constraints. Since we're in the suspend path
     * that isn't really a problem though.
     */
    mutex_unlock(&mvm->mutex);
    ret = iwl_mvm_wowlan_config_key_params(mvm, vif, false, CMD_ASYNC);
    mutex_lock(&mvm->mutex);
    if (ret) {
      return ret;
    }
  }

  ret = iwl_mvm_send_cmd_pdu(mvm, WOWLAN_CONFIGURATION, 0, sizeof(*wowlan_config_cmd),
                             wowlan_config_cmd);
  if (ret) {
    return ret;
  }

  ret = iwl_mvm_send_patterns(mvm, wowlan);
  if (ret) {
    return ret;
  }

  return iwl_mvm_send_proto_offload(mvm, vif, false, true, 0);
}

static int iwl_mvm_netdetect_config(struct iwl_mvm* mvm, struct cfg80211_wowlan* wowlan,
                                    struct cfg80211_sched_scan_request* nd_config,
                                    struct ieee80211_vif* vif) {
  struct iwl_wowlan_config_cmd wowlan_config_cmd = {};
  int ret;
  bool unified_image = fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);

  if (!unified_image) {
    ret = iwl_mvm_switch_to_d3(mvm);
    if (ret) {
      return ret;
    }
  } else {
    /* In theory, we wouldn't have to stop a running sched
     * scan in order to start another one (for
     * net-detect).  But in practice this doesn't seem to
     * work properly, so stop any running sched_scan now.
     */
    ret = iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_SCHED, true);
    if (ret) {
      return ret;
    }
  }

  /* rfkill release can be either for wowlan or netdetect */
  if (wowlan->rfkill_release) {
    wowlan_config_cmd.wakeup_filter |= cpu_to_le32(IWL_WOWLAN_WAKEUP_RF_KILL_DEASSERT);
  }

  ret = iwl_mvm_send_cmd_pdu(mvm, WOWLAN_CONFIGURATION, 0, sizeof(wowlan_config_cmd),
                             &wowlan_config_cmd);
  if (ret) {
    return ret;
  }

  ret = iwl_mvm_sched_scan_start(mvm, vif, nd_config, &mvm->nd_ies, IWL_MVM_SCAN_NETDETECT);
  if (ret) {
    return ret;
  }

  if (WARN_ON(mvm->nd_match_sets || mvm->nd_channels)) {
    return -EBUSY;
  }

  /* save the sched scan matchsets... */
  if (nd_config->n_match_sets) {
    mvm->nd_match_sets =
        kmemdup(nd_config->match_sets, sizeof(*nd_config->match_sets) * nd_config->n_match_sets,
                GFP_KERNEL);
    if (mvm->nd_match_sets) {
      mvm->n_nd_match_sets = nd_config->n_match_sets;
    }
  }

  /* ...and the sched scan channels for later reporting */
  mvm->nd_channels = kmemdup(nd_config->channels,
                             sizeof(*nd_config->channels) * nd_config->n_channels, GFP_KERNEL);
  if (mvm->nd_channels) {
    mvm->n_nd_channels = nd_config->n_channels;
  }

  return 0;
}

static void iwl_mvm_free_nd(struct iwl_mvm* mvm) {
  kfree(mvm->nd_match_sets);
  mvm->nd_match_sets = NULL;
  mvm->n_nd_match_sets = 0;
  kfree(mvm->nd_channels);
  mvm->nd_channels = NULL;
  mvm->n_nd_channels = 0;
}

static int __iwl_mvm_suspend(struct ieee80211_hw* hw, struct cfg80211_wowlan* wowlan, bool test) {
  struct iwl_mvm* mvm = IWL_MAC80211_GET_MVM(hw);
  struct ieee80211_vif* vif = NULL;
  struct iwl_mvm_vif* mvmvif = NULL;
  struct ieee80211_sta* ap_sta = NULL;
  struct iwl_d3_manager_config d3_cfg_cmd_data = {
      /*
       * Program the minimum sleep time to 10 seconds, as many
       * platforms have issues processing a wakeup signal while
       * still being in the process of suspending.
       */
      .min_sleep_time = cpu_to_le32(10 * 1000 * 1000),
  };
  struct iwl_host_cmd d3_cfg_cmd = {
      .id = D3_CONFIG_CMD,
      .flags = CMD_WANT_SKB,
      .data[0] = &d3_cfg_cmd_data,
      .len[0] = sizeof(d3_cfg_cmd_data),
  };
  int ret;
  int len __maybe_unused;
  bool unified_image = fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);

  if (!wowlan) {
    /*
     * mac80211 shouldn't get here, but for D3 test
     * it doesn't warrant a warning
     */
    WARN_ON(!test);
    return -EINVAL;
  }

  mutex_lock(&mvm->mutex);

  vif = iwl_mvm_get_bss_vif(mvm);
  if (IS_ERR_OR_NULL(vif)) {
    ret = 1;
    goto out_noreset;
  }

  mvmvif = iwl_mvm_vif_from_mac80211(vif);

  if (mvmvif->ap_sta_id == IWL_MVM_INVALID_STA) {
    /* if we're not associated, this must be netdetect */
    if (!wowlan->nd_config) {
      ret = 1;
      goto out_noreset;
    }

    ret = iwl_mvm_netdetect_config(mvm, wowlan, wowlan->nd_config, vif);
    if (ret) {
      goto out;
    }

    mvm->net_detect = true;
  } else {
    struct iwl_wowlan_config_cmd wowlan_config_cmd = {};

    ap_sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[mvmvif->ap_sta_id],
                                       lockdep_is_held(&mvm->mutex));
    if (IS_ERR_OR_NULL(ap_sta)) {
      ret = -EINVAL;
      goto out_noreset;
    }

    ret = iwl_mvm_get_wowlan_config(mvm, wowlan, &wowlan_config_cmd, vif, mvmvif, ap_sta);
    if (ret) {
      goto out_noreset;
    }
    ret = iwl_mvm_wowlan_config(mvm, wowlan, &wowlan_config_cmd, vif, mvmvif, ap_sta);
    if (ret) {
      goto out;
    }

    mvm->net_detect = false;
  }

  ret = iwl_mvm_power_update_device(mvm);
  if (ret) {
    goto out;
  }

  ret = iwl_mvm_power_update_mac(mvm);
  if (ret) {
    goto out;
  }

#ifdef CPTCFG_IWLWIFI_DEBUGFS
  if (mvm->d3_wake_sysassert) {
    d3_cfg_cmd_data.wakeup_flags |= cpu_to_le32(IWL_WAKEUP_D3_CONFIG_FW_ERROR);
  }
#endif

  /*
   * TODO: this is needed because the firmware is not stopping
   * the recording automatically before entering D3.  This can
   * be removed once the FW starts doing that.
   */
  _iwl_fw_dbg_stop_recording(mvm->fwrt.trans, NULL);

  /* must be last -- this switches firmware state */
  ret = iwl_mvm_send_cmd(mvm, &d3_cfg_cmd);
  if (ret) {
    goto out;
  }
#ifdef CPTCFG_IWLWIFI_DEBUGFS
  len = iwl_rx_packet_payload_len(d3_cfg_cmd.resp_pkt);
  if (len >= sizeof(uint32_t)) {
    mvm->d3_test_pme_ptr = le32_to_cpup((__le32*)d3_cfg_cmd.resp_pkt->data);
  }
#endif
  iwl_free_resp(&d3_cfg_cmd);

  clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);

  iwl_trans_d3_suspend(mvm->trans, test, !unified_image);
out:
  if (ret < 0) {
    iwl_mvm_free_nd(mvm);

    if (!unified_image) {
      iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN);
      if (mvm->fw_restart > 0) {
        mvm->fw_restart--;
        ieee80211_restart_hw(mvm->hw);
      }
    }
  }
out_noreset:
  mutex_unlock(&mvm->mutex);

  return ret;
}

static int iwl_mvm_enter_d0i3_sync(struct iwl_mvm* mvm) {
  struct iwl_notification_wait wait_d3;
  static const uint16_t d3_notif[] = {D3_CONFIG_CMD};
  int ret;

  iwl_init_notification_wait(&mvm->notif_wait, &wait_d3, d3_notif, ARRAY_SIZE(d3_notif), NULL,
                             NULL);

  ret = iwl_mvm_enter_d0i3(mvm->hw->priv);
  if (ret) {
    goto remove_notif;
  }

  ret = iwl_wait_notification(&mvm->notif_wait, &wait_d3, HZ);
  WARN_ON_ONCE(ret);
  return ret;

remove_notif:
  iwl_remove_notification(&mvm->notif_wait, &wait_d3);
  return ret;
}

int iwl_mvm_suspend(struct ieee80211_hw* hw, struct cfg80211_wowlan* wowlan) {
  struct iwl_mvm* mvm = IWL_MAC80211_GET_MVM(hw);
  struct iwl_trans* trans = mvm->trans;
  int ret;

  /* make sure the d0i3 exit work is not pending */
  flush_work(&mvm->d0i3_exit_work);
  iwl_mvm_pause_tcm(mvm, true);

  iwl_fw_runtime_suspend(&mvm->fwrt);

  ret = iwl_trans_suspend(trans);
  if (ret) {
    return ret;
  }

  if (wowlan->any) {
    trans->system_pm_mode = IWL_PLAT_PM_MODE_D0I3;

    if (iwl_mvm_enter_d0i3_on_suspend(mvm)) {
      ret = iwl_mvm_enter_d0i3_sync(mvm);

      if (ret) {
        return ret;
      }
    }

    mutex_lock(&mvm->d0i3_suspend_mutex);
    __set_bit(D0I3_DEFER_WAKEUP, &mvm->d0i3_suspend_flags);
    mutex_unlock(&mvm->d0i3_suspend_mutex);

    iwl_trans_d3_suspend(trans, false, false);

    return 0;
  }

  trans->system_pm_mode = IWL_PLAT_PM_MODE_D3;

  return __iwl_mvm_suspend(hw, wowlan, false);
}

/* converted data from the different status responses */
struct iwl_wowlan_status_data {
  uint16_t pattern_number;
  uint16_t qos_seq_ctr[8];
  uint32_t wakeup_reasons;
  uint32_t wake_packet_length;
  uint32_t wake_packet_bufsize;
  const uint8_t* wake_packet;
};

static void iwl_mvm_report_wakeup_reasons(struct iwl_mvm* mvm, struct ieee80211_vif* vif,
                                          struct iwl_wowlan_status_data* status) {
  struct sk_buff* pkt = NULL;
  struct cfg80211_wowlan_wakeup wakeup = {
      .pattern_idx = -1,
  };
  struct cfg80211_wowlan_wakeup* wakeup_report = &wakeup;
  uint32_t reasons = status->wakeup_reasons;

  if (reasons == IWL_WOWLAN_WAKEUP_BY_NON_WIRELESS) {
    wakeup_report = NULL;
    goto report;
  }

  pm_wakeup_event(mvm->dev, 0);

  if (reasons & IWL_WOWLAN_WAKEUP_BY_MAGIC_PACKET) {
    wakeup.magic_pkt = true;
  }

  if (reasons & IWL_WOWLAN_WAKEUP_BY_PATTERN) {
    wakeup.pattern_idx = status->pattern_number;
  }

  if (reasons & (IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_MISSED_BEACON |
                 IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_DEAUTH)) {
    wakeup.disconnect = true;
  }

  if (reasons & IWL_WOWLAN_WAKEUP_BY_GTK_REKEY_FAILURE) {
    wakeup.gtk_rekey_failure = true;
  }

  if (reasons & IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED) {
    wakeup.rfkill_release = true;
  }

  if (reasons & IWL_WOWLAN_WAKEUP_BY_EAPOL_REQUEST) {
    wakeup.eap_identity_req = true;
  }

  if (reasons & IWL_WOWLAN_WAKEUP_BY_FOUR_WAY_HANDSHAKE) {
    wakeup.four_way_handshake = true;
  }

  if (reasons & IWL_WOWLAN_WAKEUP_BY_REM_WAKE_LINK_LOSS) {
    wakeup.tcp_connlost = true;
  }

  if (reasons & IWL_WOWLAN_WAKEUP_BY_REM_WAKE_SIGNATURE_TABLE) {
    wakeup.tcp_nomoretokens = true;
  }

  if (reasons & IWL_WOWLAN_WAKEUP_BY_REM_WAKE_WAKEUP_PACKET) {
    wakeup.tcp_match = true;
  }

  if (status->wake_packet_bufsize) {
    int pktsize = status->wake_packet_bufsize;
    int pktlen = status->wake_packet_length;
    const uint8_t* pktdata = status->wake_packet;
    struct ieee80211_hdr* hdr = (void*)pktdata;
    int truncated = pktlen - pktsize;

    /* this would be a firmware bug */
    if (WARN_ON_ONCE(truncated < 0)) {
      truncated = 0;
    }

    if (ieee80211_is_data(hdr->frame_control)) {
      int hdrlen = ieee80211_hdrlen(hdr->frame_control);
      int ivlen = 0, icvlen = 4; /* also FCS */

      pkt = alloc_skb(pktsize, GFP_KERNEL);
      if (!pkt) {
        goto report;
      }

      skb_put_data(pkt, pktdata, hdrlen);
      pktdata += hdrlen;
      pktsize -= hdrlen;

      if (ieee80211_has_protected(hdr->frame_control)) {
        /*
         * This is unlocked and using gtk_i(c)vlen,
         * but since everything is under RTNL still
         * that's not really a problem - changing
         * it would be difficult.
         */
        if (is_multicast_ether_addr(hdr->addr1)) {
          ivlen = mvm->gtk_ivlen;
          icvlen += mvm->gtk_icvlen;
        } else {
          ivlen = mvm->ptk_ivlen;
          icvlen += mvm->ptk_icvlen;
        }
      }

      /* if truncated, FCS/ICV is (partially) gone */
      if (truncated >= icvlen) {
        icvlen = 0;
        truncated -= icvlen;
      } else {
        icvlen -= truncated;
        truncated = 0;
      }

      pktsize -= ivlen + icvlen;
      pktdata += ivlen;

      skb_put_data(pkt, pktdata, pktsize);

      if (ieee80211_data_to_8023(pkt, vif->addr, vif->type)) {
        goto report;
      }
      wakeup.packet = pkt->data;
      wakeup.packet_present_len = pkt->len;
      wakeup.packet_len = pkt->len - truncated;
      wakeup.packet_80211 = false;
    } else {
      int fcslen = 4;

      if (truncated >= 4) {
        truncated -= 4;
        fcslen = 0;
      } else {
        fcslen -= truncated;
        truncated = 0;
      }
      pktsize -= fcslen;
      wakeup.packet = status->wake_packet;
      wakeup.packet_present_len = pktsize;
      wakeup.packet_len = pktlen - truncated;
      wakeup.packet_80211 = true;
    }
  }

report:
  ieee80211_report_wowlan_wakeup(vif, wakeup_report, GFP_KERNEL);
  kfree_skb(pkt);
}

static void iwl_mvm_aes_sc_to_seq(struct aes_sc* sc, struct ieee80211_key_seq* seq) {
  uint64_t pn;

  pn = le64_to_cpu(sc->pn);
  seq->ccmp.pn[0] = pn >> 40;
  seq->ccmp.pn[1] = pn >> 32;
  seq->ccmp.pn[2] = pn >> 24;
  seq->ccmp.pn[3] = pn >> 16;
  seq->ccmp.pn[4] = pn >> 8;
  seq->ccmp.pn[5] = pn;
}

static void iwl_mvm_tkip_sc_to_seq(struct tkip_sc* sc, struct ieee80211_key_seq* seq) {
  seq->tkip.iv32 = le32_to_cpu(sc->iv32);
  seq->tkip.iv16 = le16_to_cpu(sc->iv16);
}

static void iwl_mvm_set_aes_rx_seq(struct iwl_mvm* mvm, struct aes_sc* scs,
                                   struct ieee80211_sta* sta, struct ieee80211_key_conf* key) {
  int tid;

  BUILD_BUG_ON(IWL_NUM_RSC != fuchsia_wlan_ieee80211_TIDS_MAX);

  if (sta && iwl_mvm_has_new_rx_api(mvm)) {
    struct iwl_mvm_sta* mvmsta;
    struct iwl_mvm_key_pn* ptk_pn;

    mvmsta = iwl_mvm_sta_from_mac80211(sta);

    ptk_pn = rcu_dereference_protected(mvmsta->ptk_pn[key->keyidx], lockdep_is_held(&mvm->mutex));
    if (WARN_ON(!ptk_pn)) {
      return;
    }

    for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++) {
      struct ieee80211_key_seq seq = {};
      int i;

      iwl_mvm_aes_sc_to_seq(&scs[tid], &seq);
      ieee80211_set_key_rx_seq(key, tid, &seq);
      for (i = 1; i < mvm->trans->num_rx_queues; i++) {
        memcpy(ptk_pn->q[i].pn[tid], seq.ccmp.pn, fuchsia_wlan_ieee80211_CCMP_PN_LEN);
      }
    }
  } else {
    for (tid = 0; tid < IWL_NUM_RSC; tid++) {
      struct ieee80211_key_seq seq = {};

      iwl_mvm_aes_sc_to_seq(&scs[tid], &seq);
      ieee80211_set_key_rx_seq(key, tid, &seq);
    }
  }
}

static void iwl_mvm_set_tkip_rx_seq(struct tkip_sc* scs, struct ieee80211_key_conf* key) {
  int tid;

  BUILD_BUG_ON(IWL_NUM_RSC != fuchsia_wlan_ieee80211_TIDS_MAX);

  for (tid = 0; tid < IWL_NUM_RSC; tid++) {
    struct ieee80211_key_seq seq = {};

    iwl_mvm_tkip_sc_to_seq(&scs[tid], &seq);
    ieee80211_set_key_rx_seq(key, tid, &seq);
  }
}

static void iwl_mvm_set_key_rx_seq(struct iwl_mvm* mvm, struct ieee80211_key_conf* key,
                                   struct iwl_wowlan_status* status) {
  union iwl_all_tsc_rsc* rsc = &status->gtk[0].rsc.all_tsc_rsc;

  switch (key->cipher) {
    case WLAN_CIPHER_SUITE_CCMP:
      iwl_mvm_set_aes_rx_seq(mvm, rsc->aes.multicast_rsc, NULL, key);
      break;
    case WLAN_CIPHER_SUITE_TKIP:
      iwl_mvm_set_tkip_rx_seq(rsc->tkip.multicast_rsc, key);
      break;
    default:
      WARN_ON(1);
  }
}

struct iwl_mvm_d3_gtk_iter_data {
  struct iwl_mvm* mvm;
  struct iwl_wowlan_status* status;
  void* last_gtk;
  uint32_t cipher;
  bool find_phase, unhandled_cipher;
  int num_keys;
};

static void iwl_mvm_d3_update_keys(struct ieee80211_hw* hw, struct ieee80211_vif* vif,
                                   struct ieee80211_sta* sta, struct ieee80211_key_conf* key,
                                   void* _data) {
  struct iwl_mvm_d3_gtk_iter_data* data = _data;

  if (data->unhandled_cipher) {
    return;
  }

  switch (key->cipher) {
    case WLAN_CIPHER_SUITE_WEP40:
    case WLAN_CIPHER_SUITE_WEP104:
      /* ignore WEP completely, nothing to do */
      return;
    case WLAN_CIPHER_SUITE_CCMP:
    case WLAN_CIPHER_SUITE_TKIP:
      /* we support these */
      break;
    default:
      /* everything else (even CMAC for MFP) - disconnect from AP */
      data->unhandled_cipher = true;
      return;
  }

  data->num_keys++;

  /*
   * pairwise key - update sequence counters only;
   * note that this assumes no TDLS sessions are active
   */
  if (sta) {
    struct ieee80211_key_seq seq = {};
    union iwl_all_tsc_rsc* sc = &data->status->gtk[0].rsc.all_tsc_rsc;

    if (data->find_phase) {
      return;
    }

    switch (key->cipher) {
      case WLAN_CIPHER_SUITE_CCMP:
        iwl_mvm_set_aes_rx_seq(data->mvm, sc->aes.unicast_rsc, sta, key);
        atomic64_set(&key->tx_pn, le64_to_cpu(sc->aes.tsc.pn));
        break;
      case WLAN_CIPHER_SUITE_TKIP:
        iwl_mvm_tkip_sc_to_seq(&sc->tkip.tsc, &seq);
        iwl_mvm_set_tkip_rx_seq(sc->tkip.unicast_rsc, key);
        atomic64_set(&key->tx_pn, (uint64_t)seq.tkip.iv16 | ((uint64_t)seq.tkip.iv32 << 16));
        break;
    }

    /* that's it for this key */
    return;
  }

  if (data->find_phase) {
    data->last_gtk = key;
    data->cipher = key->cipher;
    return;
  }

  if (data->status->num_of_gtk_rekeys) {
    ieee80211_remove_key(key);
  } else if (data->last_gtk == key) {
    iwl_mvm_set_key_rx_seq(data->mvm, key, data->status);
  }
}

static bool iwl_mvm_setup_connection_keep(struct iwl_mvm* mvm, struct ieee80211_vif* vif,
                                          struct iwl_wowlan_status* status) {
  struct iwl_mvm_vif* mvmvif = iwl_mvm_vif_from_mac80211(vif);
  struct iwl_mvm_d3_gtk_iter_data gtkdata = {
      .mvm = mvm,
      .status = status,
  };
  uint32_t disconnection_reasons = IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_MISSED_BEACON |
                                   IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_DEAUTH;

  if (!status || !vif->bss_conf.bssid) {
    return false;
  }

  if (le32_to_cpu(status->wakeup_reasons) & disconnection_reasons) {
    return false;
  }

  /* find last GTK that we used initially, if any */
  gtkdata.find_phase = true;
  ieee80211_iter_keys(mvm->hw, vif, iwl_mvm_d3_update_keys, &gtkdata);
  /* not trying to keep connections with MFP/unhandled ciphers */
  if (gtkdata.unhandled_cipher) {
    return false;
  }
  if (!gtkdata.num_keys) {
    goto out;
  }
  if (!gtkdata.last_gtk) {
    return false;
  }

  /*
   * invalidate all other GTKs that might still exist and update
   * the one that we used
   */
  gtkdata.find_phase = false;
  ieee80211_iter_keys(mvm->hw, vif, iwl_mvm_d3_update_keys, &gtkdata);

  if (status->num_of_gtk_rekeys) {
    struct ieee80211_key_conf* key;
    struct {
      struct ieee80211_key_conf conf;
      uint8_t key[32];
    } conf = {
        .conf.cipher = gtkdata.cipher,
        .conf.keyidx = iwlmvm_wowlan_gtk_idx(&status->gtk[0]),
    };
    __be64 replay_ctr;

    switch (gtkdata.cipher) {
      case WLAN_CIPHER_SUITE_CCMP:
        conf.conf.keylen = WLAN_KEY_LEN_CCMP;
        memcpy(conf.conf.key, status->gtk[0].key, WLAN_KEY_LEN_CCMP);
        break;
      case WLAN_CIPHER_SUITE_TKIP:
        conf.conf.keylen = WLAN_KEY_LEN_TKIP;
        memcpy(conf.conf.key, status->gtk[0].key, 16);
        /* leave TX MIC key zeroed, we don't use it anyway */
        memcpy(conf.conf.key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY, status->gtk[0].tkip_mic_key, 8);
        break;
    }

    key = ieee80211_gtk_rekey_add(vif, &conf.conf);
    if (IS_ERR(key)) {
      return false;
    }
    iwl_mvm_set_key_rx_seq(mvm, key, status);

    replay_ctr = cpu_to_be64(le64_to_cpu(status->replay_ctr));

    ieee80211_gtk_rekey_notify(vif, vif->bss_conf.bssid, (void*)&replay_ctr, GFP_KERNEL);
  }

out:
  mvmvif->seqno_valid = true;
  /* +0x10 because the set API expects next-to-use, not last-used */
  mvmvif->seqno = le16_to_cpu(status->non_qos_seq_ctr) + 0x10;

  return true;
}

struct iwl_wowlan_status* iwl_mvm_send_wowlan_get_status(struct iwl_mvm* mvm) {
  struct iwl_wowlan_status *v7, *status;
  struct iwl_host_cmd cmd = {
      .id = WOWLAN_GET_STATUSES,
      .flags = CMD_WANT_SKB,
  };
  int ret, len, status_size;

  iwl_assert_lock_held(&mvm->mutex);

  ret = iwl_mvm_send_cmd(mvm, &cmd);
  if (ret) {
    IWL_ERR(mvm, "failed to query wakeup status (%d)\n", ret);
    return ERR_PTR(ret);
  }

  if (!fw_has_api(&mvm->fw->ucode_capa, IWL_UCODE_TLV_API_WOWLAN_KEY_MATERIAL)) {
    struct iwl_wowlan_status_v6* v6 = (void*)cmd.resp_pkt->data;
    int data_size;

    status_size = sizeof(*v6);
    len = iwl_rx_packet_payload_len(cmd.resp_pkt);

    if (len < status_size) {
      IWL_ERR(mvm, "Invalid WoWLAN status response!\n");
      status = ERR_PTR(-EIO);
      goto out_free_resp;
    }

    data_size = ALIGN(le32_to_cpu(v6->wake_packet_bufsize), 4);

    if (len != (status_size + data_size)) {
      IWL_ERR(mvm, "Invalid WoWLAN status response!\n");
      status = ERR_PTR(-EIO);
      goto out_free_resp;
    }

    status = kzalloc(sizeof(*status) + data_size, GFP_KERNEL);
    if (!status) {
      goto out_free_resp;
    }

    BUILD_BUG_ON(sizeof(v6->gtk.decrypt_key) > sizeof(status->gtk[0].key));
    BUILD_BUG_ON(sizeof(v6->gtk.tkip_mic_key) > sizeof(status->gtk[0].tkip_mic_key));

    /* copy GTK info to the right place */
    memcpy(status->gtk[0].key, v6->gtk.decrypt_key, sizeof(v6->gtk.decrypt_key));
    memcpy(status->gtk[0].tkip_mic_key, v6->gtk.tkip_mic_key, sizeof(v6->gtk.tkip_mic_key));
    memcpy(&status->gtk[0].rsc, &v6->gtk.rsc, sizeof(status->gtk[0].rsc));

    /* hardcode the key length to 16 since v6 only supports 16 */
    status->gtk[0].key_len = 16;

    /*
     * The key index only uses 2 bits (values 0 to 3) and
     * we always set bit 7 which means this is the
     * currently used key.
     */
    status->gtk[0].key_flags = v6->gtk.key_index | BIT(7);

    status->replay_ctr = v6->replay_ctr;

    /* everything starting from pattern_number is identical */
    memcpy(&status->pattern_number, &v6->pattern_number,
           offsetof(struct iwl_wowlan_status, wake_packet) -
               offsetof(struct iwl_wowlan_status, pattern_number) + data_size);

    goto out_free_resp;
  }

  v7 = (void*)cmd.resp_pkt->data;
  status_size = sizeof(*v7);
  len = iwl_rx_packet_payload_len(cmd.resp_pkt);

  if (len < status_size) {
    IWL_ERR(mvm, "Invalid WoWLAN status response!\n");
    status = ERR_PTR(-EIO);
    goto out_free_resp;
  }

  if (len != (status_size + ALIGN(le32_to_cpu(v7->wake_packet_bufsize), 4))) {
    IWL_ERR(mvm, "Invalid WoWLAN status response!\n");
    status = ERR_PTR(-EIO);
    goto out_free_resp;
  }

  status = kmemdup(v7, len, GFP_KERNEL);

out_free_resp:
  iwl_free_resp(&cmd);
  return status;
}

static struct iwl_wowlan_status* iwl_mvm_get_wakeup_status(struct iwl_mvm* mvm) {
  int ret;

  /* only for tracing for now */
  ret = iwl_mvm_send_cmd_pdu(mvm, OFFLOADS_QUERY_CMD, 0, 0, NULL);
  if (ret) {
    IWL_ERR(mvm, "failed to query offload statistics (%d)\n", ret);
  }

  return iwl_mvm_send_wowlan_get_status(mvm);
}

/* releases the MVM mutex */
static bool iwl_mvm_query_wakeup_reasons(struct iwl_mvm* mvm, struct ieee80211_vif* vif) {
  struct iwl_wowlan_status_data status;
  struct iwl_wowlan_status* fw_status;
  int i;
  bool keep;
  struct iwl_mvm_sta* mvm_ap_sta;

  fw_status = iwl_mvm_get_wakeup_status(mvm);
  if (IS_ERR_OR_NULL(fw_status)) {
    goto out_unlock;
  }

  status.pattern_number = le16_to_cpu(fw_status->pattern_number);
  for (i = 0; i < 8; i++) {
    status.qos_seq_ctr[i] = le16_to_cpu(fw_status->qos_seq_ctr[i]);
  }
  status.wakeup_reasons = le32_to_cpu(fw_status->wakeup_reasons);
  status.wake_packet_length = le32_to_cpu(fw_status->wake_packet_length);
  status.wake_packet_bufsize = le32_to_cpu(fw_status->wake_packet_bufsize);
  status.wake_packet = fw_status->wake_packet;

  /* still at hard-coded place 0 for D3 image */
  mvm_ap_sta = iwl_mvm_sta_from_staid_protected(mvm, 0);
  if (!mvm_ap_sta) {
    goto out_free;
  }

  for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
    uint16_t seq = status.qos_seq_ctr[i];
    /* firmware stores last-used value, we store next value */
    seq += 0x10;
    mvm_ap_sta->tid_data[i].seq_number = seq;
  }

  /* now we have all the data we need, unlock to avoid mac80211 issues */
  mutex_unlock(&mvm->mutex);

  iwl_mvm_report_wakeup_reasons(mvm, vif, &status);

  keep = iwl_mvm_setup_connection_keep(mvm, vif, fw_status);

  kfree(fw_status);
  return keep;

out_free:
  kfree(fw_status);
out_unlock:
  mutex_unlock(&mvm->mutex);
  return false;
}

void iwl_mvm_d0i3_update_keys(struct iwl_mvm* mvm, struct ieee80211_vif* vif,
                              struct iwl_wowlan_status* status) {
  struct iwl_mvm_d3_gtk_iter_data gtkdata = {
      .mvm = mvm,
      .status = status,
  };

  /*
   * rekey handling requires taking locks that can't be taken now.
   * however, d0i3 doesn't offload rekey, so we're fine.
   */
  if (WARN_ON_ONCE(status->num_of_gtk_rekeys)) {
    return;
  }

  /* find last GTK that we used initially, if any */
  gtkdata.find_phase = true;
  iwl_mvm_iter_d0i3_ap_keys(mvm, vif, iwl_mvm_d3_update_keys, &gtkdata);

  gtkdata.find_phase = false;
  iwl_mvm_iter_d0i3_ap_keys(mvm, vif, iwl_mvm_d3_update_keys, &gtkdata);
}

struct iwl_mvm_nd_query_results {
  uint32_t matched_profiles;
  struct iwl_scan_offload_profile_match matches[IWL_SCAN_MAX_PROFILES];
};

static int iwl_mvm_netdetect_query_results(struct iwl_mvm* mvm,
                                           struct iwl_mvm_nd_query_results* results) {
  struct iwl_scan_offload_profiles_query* query;
  struct iwl_host_cmd cmd = {
      .id = SCAN_OFFLOAD_PROFILES_QUERY_CMD,
      .flags = CMD_WANT_SKB,
  };
  int ret, len;

  ret = iwl_mvm_send_cmd(mvm, &cmd);
  if (ret) {
    IWL_ERR(mvm, "failed to query matched profiles (%d)\n", ret);
    return ret;
  }

  len = iwl_rx_packet_payload_len(cmd.resp_pkt);
  if (len < sizeof(*query)) {
    IWL_ERR(mvm, "Invalid scan offload profiles query response!\n");
    ret = -EIO;
    goto out_free_resp;
  }

  query = (void*)cmd.resp_pkt->data;

  results->matched_profiles = le32_to_cpu(query->matched_profiles);
  memcpy(results->matches, query->matches, sizeof(results->matches));

#ifdef CPTCFG_IWLWIFI_DEBUGFS
  mvm->last_netdetect_scans = le32_to_cpu(query->n_scans_done);
#endif

out_free_resp:
  iwl_free_resp(&cmd);
  return ret;
}

static void iwl_mvm_query_netdetect_reasons(struct iwl_mvm* mvm, struct ieee80211_vif* vif) {
  struct cfg80211_wowlan_nd_info* net_detect = NULL;
  struct cfg80211_wowlan_wakeup wakeup = {
      .pattern_idx = -1,
  };
  struct cfg80211_wowlan_wakeup* wakeup_report = &wakeup;
  struct iwl_mvm_nd_query_results query;
  struct iwl_wowlan_status* fw_status;
  unsigned long matched_profiles;
  uint32_t reasons = 0;
  int i, j, n_matches, ret;

  fw_status = iwl_mvm_get_wakeup_status(mvm);
  if (!IS_ERR_OR_NULL(fw_status)) {
    reasons = le32_to_cpu(fw_status->wakeup_reasons);
    kfree(fw_status);
  }

  if (reasons & IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED) {
    wakeup.rfkill_release = true;
  }

  if (reasons != IWL_WOWLAN_WAKEUP_BY_NON_WIRELESS) {
    goto out;
  }

  ret = iwl_mvm_netdetect_query_results(mvm, &query);
  if (ret || !query.matched_profiles) {
    wakeup_report = NULL;
    goto out;
  }

  matched_profiles = query.matched_profiles;
  if (mvm->n_nd_match_sets) {
    n_matches = hweight_long(matched_profiles);
  } else {
    IWL_ERR(mvm, "no net detect match information available\n");
    n_matches = 0;
  }

  net_detect = kzalloc(struct_size(net_detect, matches, n_matches), GFP_KERNEL);
  if (!net_detect || !n_matches) {
    goto out_report_nd;
  }

  for_each_set_bit(i, &matched_profiles, mvm->n_nd_match_sets) {
    struct iwl_scan_offload_profile_match* fw_match;
    struct cfg80211_wowlan_nd_match* match;
    int idx, n_channels = 0;

    fw_match = &query.matches[i];

    for (j = 0; j < SCAN_OFFLOAD_MATCHING_CHANNELS_LEN; j++) {
      n_channels += hweight8(fw_match->matching_channels[j]);
    }

    match = kzalloc(struct_size(match, channels, n_channels), GFP_KERNEL);
    if (!match) {
      goto out_report_nd;
    }

    net_detect->matches[net_detect->n_matches++] = match;

    /* We inverted the order of the SSIDs in the scan
     * request, so invert the index here.
     */
    idx = mvm->n_nd_match_sets - i - 1;
    match->ssid.ssid_len = mvm->nd_match_sets[idx].ssid.ssid_len;
    memcpy(match->ssid.ssid, mvm->nd_match_sets[idx].ssid.ssid, match->ssid.ssid_len);

    if (mvm->n_nd_channels < n_channels) {
      continue;
    }

    for (j = 0; j < SCAN_OFFLOAD_MATCHING_CHANNELS_LEN * 8; j++)
      if (fw_match->matching_channels[j / 8] & (BIT(j % 8))) {
        match->channels[match->n_channels++] = mvm->nd_channels[j]->center_freq;
      }
  }

out_report_nd:
  wakeup.net_detect = net_detect;
out:
  iwl_mvm_free_nd(mvm);

  mutex_unlock(&mvm->mutex);
  ieee80211_report_wowlan_wakeup(vif, wakeup_report, GFP_KERNEL);

  if (net_detect) {
    for (i = 0; i < net_detect->n_matches; i++) {
      kfree(net_detect->matches[i]);
    }
    kfree(net_detect);
  }
}

static void iwl_mvm_read_d3_sram(struct iwl_mvm* mvm) {
#ifdef CPTCFG_IWLWIFI_DEBUGFS
  const struct fw_img* img = &mvm->fw->img[IWL_UCODE_WOWLAN];
  uint32_t len = img->sec[IWL_UCODE_SECTION_DATA].len;
  uint32_t offs = img->sec[IWL_UCODE_SECTION_DATA].offset;

  if (!mvm->store_d3_resume_sram) {
    return;
  }

  if (!mvm->d3_resume_sram) {
    mvm->d3_resume_sram = kzalloc(len, GFP_KERNEL);
    if (!mvm->d3_resume_sram) {
      return;
    }
  }

  iwl_trans_read_mem_bytes(mvm->trans, offs, mvm->d3_resume_sram, len);
#endif
}

static void iwl_mvm_d3_disconnect_iter(void* data, uint8_t* mac, struct ieee80211_vif* vif) {
  /* skip the one we keep connection on */
  if (data == vif) {
    return;
  }

  if (vif->type == NL80211_IFTYPE_STATION) {
    ieee80211_resume_disconnect(vif);
  }
}

static int iwl_mvm_check_rt_status(struct iwl_mvm* mvm, struct ieee80211_vif* vif) {
  uint32_t base = mvm->error_event_table[0];
  struct error_table_start {
    /* cf. struct iwl_error_event_table */
    uint32_t valid;
    uint32_t error_id;
  } err_info;

  iwl_trans_read_mem_bytes(mvm->trans, base, &err_info, sizeof(err_info));

  if (err_info.valid && err_info.error_id == RF_KILL_INDICATOR_FOR_WOWLAN) {
    struct cfg80211_wowlan_wakeup wakeup = {
        .rfkill_release = true,
    };
    ieee80211_report_wowlan_wakeup(vif, &wakeup, GFP_KERNEL);
  }
  return err_info.valid;
}

static int __iwl_mvm_resume(struct iwl_mvm* mvm, bool test) {
  struct ieee80211_vif* vif = NULL;
  int ret = 1;
  enum iwl_d3_status d3_status;
  bool keep = false;
  bool unified_image = fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);
  bool d0i3_first = fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_D0I3_END_FIRST);

  mutex_lock(&mvm->mutex);

  /* get the BSS vif pointer again */
  vif = iwl_mvm_get_bss_vif(mvm);
  if (IS_ERR_OR_NULL(vif)) {
    goto err;
  }

  ret = iwl_trans_d3_resume(mvm->trans, &d3_status, test, !unified_image);
  if (ret) {
    goto err;
  }

  if (d3_status != IWL_D3_STATUS_ALIVE) {
    IWL_INFO(mvm, "Device was reset during suspend\n");
    goto err;
  }

  iwl_fw_dbg_read_d3_debug_data(&mvm->fwrt);
  /* query SRAM first in case we want event logging */
  iwl_mvm_read_d3_sram(mvm);

  if (iwl_mvm_check_rt_status(mvm, vif)) {
    set_bit(STATUS_FW_ERROR, &mvm->trans->status);
    iwl_mvm_dump_nic_error_log(mvm);
    iwl_fw_dbg_collect_desc(&mvm->fwrt, &iwl_dump_desc_assert, false, 0);
    ret = 1;
    goto err;
  }

  if (d0i3_first) {
    ret = iwl_mvm_send_cmd_pdu(mvm, D0I3_END_CMD, 0, 0, NULL);
    if (ret < 0) {
      IWL_ERR(mvm, "Failed to send D0I3_END_CMD first (%d)\n", ret);
      goto err;
    }
  }

  /*
   * Query the current location and source from the D3 firmware so we
   * can play it back when we re-intiailize the D0 firmware
   */
  iwl_mvm_update_changed_regdom(mvm);

  if (!unified_image) { /*  Re-configure default SAR profile */
    iwl_mvm_sar_select_profile(mvm, 1, 1);
  }

  if (mvm->net_detect) {
    /* If this is a non-unified image, we restart the FW,
     * so no need to stop the netdetect scan.  If that
     * fails, continue and try to get the wake-up reasons,
     * but trigger a HW restart by keeping a failure code
     * in ret.
     */
    if (unified_image) {
      ret = iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_NETDETECT, false);
    }

    iwl_mvm_query_netdetect_reasons(mvm, vif);
    /* has unlocked the mutex, so skip that */
    goto out;
  } else {
    keep = iwl_mvm_query_wakeup_reasons(mvm, vif);
#ifdef CPTCFG_IWLWIFI_DEBUGFS
    if (keep) {
      mvm->keep_vif = vif;
    }
#endif
    /* has unlocked the mutex, so skip that */
    goto out_iterate;
  }

err:
  iwl_mvm_free_nd(mvm);
  mutex_unlock(&mvm->mutex);

out_iterate:
  if (!test)
    ieee80211_iterate_active_interfaces_rtnl(mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
                                             iwl_mvm_d3_disconnect_iter, keep ? vif : NULL);

out:
  /* no need to reset the device in unified images, if successful */
  if (unified_image && !ret) {
    /* nothing else to do if we already sent D0I3_END_CMD */
    if (d0i3_first) {
      return 0;
    }

    ret = iwl_mvm_send_cmd_pdu(mvm, D0I3_END_CMD, 0, 0, NULL);
    if (!ret) {
      return 0;
    }
  }

  /*
   * Reconfigure the device in one of the following cases:
   * 1. We are not using a unified image
   * 2. We are using a unified image but had an error while exiting D3
   */
  set_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, &mvm->status);
  set_bit(IWL_MVM_STATUS_D3_RECONFIG, &mvm->status);
  /*
   * When switching images we return 1, which causes mac80211
   * to do a reconfig with IEEE80211_RECONFIG_TYPE_RESTART.
   * This type of reconfig calls iwl_mvm_restart_complete(),
   * where we unref the IWL_MVM_REF_UCODE_DOWN, so we need
   * to take the reference here.
   */
  iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN);

  return 1;
}

static int iwl_mvm_resume_d3(struct iwl_mvm* mvm) {
  iwl_trans_resume(mvm->trans);

  return __iwl_mvm_resume(mvm, false);
}

static int iwl_mvm_resume_d0i3(struct iwl_mvm* mvm) {
  bool exit_now;
  enum iwl_d3_status d3_status;
  struct iwl_trans* trans = mvm->trans;

  iwl_trans_d3_resume(trans, &d3_status, false, false);

  /*
   * make sure to clear D0I3_DEFER_WAKEUP before
   * calling iwl_trans_resume(), which might wait
   * for d0i3 exit completion.
   */
  mutex_lock(&mvm->d0i3_suspend_mutex);
  __clear_bit(D0I3_DEFER_WAKEUP, &mvm->d0i3_suspend_flags);
  exit_now = __test_and_clear_bit(D0I3_PENDING_WAKEUP, &mvm->d0i3_suspend_flags);
  mutex_unlock(&mvm->d0i3_suspend_mutex);
  if (exit_now) {
    IWL_DEBUG_RPM(mvm, "Run deferred d0i3 exit\n");
    _iwl_mvm_exit_d0i3(mvm);
  }

  iwl_trans_resume(trans);

  if (iwl_mvm_enter_d0i3_on_suspend(mvm)) {
    int ret = iwl_mvm_exit_d0i3(mvm->hw->priv);

    if (ret) {
      return ret;
    }
    /*
     * d0i3 exit will be deferred until reconfig_complete.
     * make sure there we are out of d0i3.
     */
  }
  return 0;
}

int iwl_mvm_resume(struct ieee80211_hw* hw) {
  struct iwl_mvm* mvm = IWL_MAC80211_GET_MVM(hw);
  int ret;

  if (mvm->trans->system_pm_mode == IWL_PLAT_PM_MODE_D0I3) {
    ret = iwl_mvm_resume_d0i3(mvm);
  } else {
    ret = iwl_mvm_resume_d3(mvm);
  }

  mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_DISABLED;

  iwl_mvm_resume_tcm(mvm);

  iwl_fw_runtime_resume(&mvm->fwrt);

  return ret;
}

void iwl_mvm_set_wakeup(struct ieee80211_hw* hw, bool enabled) {
  struct iwl_mvm* mvm = IWL_MAC80211_GET_MVM(hw);

  device_set_wakeup_enable(mvm->trans->dev, enabled);
}

#ifdef CPTCFG_IWLWIFI_DEBUGFS
static int iwl_mvm_d3_test_open(struct inode* inode, struct file* file) {
  struct iwl_mvm* mvm = inode->i_private;
  int err;

  if (mvm->d3_test_active) {
    return -EBUSY;
  }

  file->private_data = inode->i_private;

  synchronize_net();

  mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_D3;

  iwl_mvm_pause_tcm(mvm, true);

  iwl_fw_runtime_suspend(&mvm->fwrt);

  /* start pseudo D3 */
  rtnl_lock();
  err = __iwl_mvm_suspend(mvm->hw, mvm->hw->wiphy->wowlan_config, true);
  rtnl_unlock();
  if (err > 0) {
    err = -EINVAL;
  }
  if (err) {
    return err;
  }

  mvm->d3_test_active = true;
  mvm->keep_vif = NULL;
  return 0;
}

static ssize_t iwl_mvm_d3_test_read(struct file* file, char __user* user_buf, size_t count,
                                    loff_t* ppos) {
  struct iwl_mvm* mvm = file->private_data;
  uint32_t pme_asserted;

  while (true) {
    /* read pme_ptr if available */
    if (mvm->d3_test_pme_ptr) {
      pme_asserted = iwl_trans_read_mem32(mvm->trans, mvm->d3_test_pme_ptr);
      if (pme_asserted) {
        break;
      }
    }

    if (msleep_interruptible(100)) {
      break;
    }
  }

  return 0;
}

static void iwl_mvm_d3_test_disconn_work_iter(void* _data, uint8_t* mac,
                                              struct ieee80211_vif* vif) {
  /* skip the one we keep connection on */
  if (_data == vif) {
    return;
  }

  if (vif->type == NL80211_IFTYPE_STATION) {
    ieee80211_connection_loss(vif);
  }
}

static int iwl_mvm_d3_test_release(struct inode* inode, struct file* file) {
  struct iwl_mvm* mvm = inode->i_private;
  bool unified_image = fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);

  mvm->d3_test_active = false;

  iwl_fw_dbg_read_d3_debug_data(&mvm->fwrt);

  rtnl_lock();
  __iwl_mvm_resume(mvm, true);
  rtnl_unlock();

  iwl_mvm_resume_tcm(mvm);

  iwl_fw_runtime_resume(&mvm->fwrt);

  mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_DISABLED;

  iwl_abort_notification_waits(&mvm->notif_wait);
  if (!unified_image) {
    int remaining_time = 10;

    ieee80211_restart_hw(mvm->hw);

    /* wait for restart and disconnect all interfaces */
    while (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) && remaining_time > 0) {
      remaining_time--;
      msleep(1000);
    }

    if (remaining_time == 0) {
      IWL_ERR(mvm, "Timed out waiting for HW restart!\n");
    }
  }

  ieee80211_iterate_active_interfaces_atomic(mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
                                             iwl_mvm_d3_test_disconn_work_iter, mvm->keep_vif);

  return 0;
}

const struct file_operations iwl_dbgfs_d3_test_ops = {
    .llseek = no_llseek,
    .open = iwl_mvm_d3_test_open,
    .read = iwl_mvm_d3_test_read,
    .release = iwl_mvm_d3_test_release,
};
#endif
