/******************************************************************************
 *
 * Copyright(c) 2014 Intel Mobile Communications GmbH
 * Copyright(c) 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 <linux/etherdevice.h>

#include "iwl-io.h"
#include "iwl-prph.h"
#include "mvm.h"
#include "time-event.h"

#define TU_TO_US(x) (x * 1024)
#define TU_TO_MS(x) (TU_TO_US(x) / 1000)

void iwl_mvm_teardown_tdls_peers(struct iwl_mvm* mvm) {
  struct ieee80211_sta* sta;
  struct iwl_mvm_sta* mvmsta;
  int i;

  iwl_assert_lock_held(&mvm->mutex);

  for (i = 0; i < ARRAY_SIZE(mvm->fw_id_to_mac_id); i++) {
    sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[i], lockdep_is_held(&mvm->mutex));
    if (!sta || IS_ERR(sta) || !sta->tdls) {
      continue;
    }

    mvmsta = iwl_mvm_sta_from_mac80211(sta);
    ieee80211_tdls_oper_request(mvmsta->vif, sta->addr, NL80211_TDLS_TEARDOWN,
                                WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED, GFP_KERNEL);
  }
}

int iwl_mvm_tdls_sta_count(struct iwl_mvm* mvm, struct ieee80211_vif* vif) {
  struct ieee80211_sta* sta;
  struct iwl_mvm_sta* mvmsta;
  int count = 0;
  int i;

  iwl_assert_lock_held(&mvm->mutex);

  for (i = 0; i < ARRAY_SIZE(mvm->fw_id_to_mac_id); i++) {
    sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[i], lockdep_is_held(&mvm->mutex));
    if (!sta || IS_ERR(sta) || !sta->tdls) {
      continue;
    }

    if (vif) {
      mvmsta = iwl_mvm_sta_from_mac80211(sta);
      if (mvmsta->vif != vif) {
        continue;
      }
    }

    count++;
  }

  return count;
}

static void iwl_mvm_tdls_config(struct iwl_mvm* mvm, struct ieee80211_vif* vif) {
  struct iwl_rx_packet* pkt;
  struct iwl_tdls_config_res* resp;
  struct iwl_tdls_config_cmd tdls_cfg_cmd = {};
  struct iwl_host_cmd cmd = {
      .id = TDLS_CONFIG_CMD,
      .flags = CMD_WANT_SKB,
      .data =
          {
              &tdls_cfg_cmd,
          },
      .len =
          {
              sizeof(struct iwl_tdls_config_cmd),
          },
  };
  struct ieee80211_sta* sta;
  int ret, i, cnt;
  struct iwl_mvm_vif* mvmvif = iwl_mvm_vif_from_mac80211(vif);

  iwl_assert_lock_held(&mvm->mutex);

  tdls_cfg_cmd.id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color));
  tdls_cfg_cmd.tx_to_ap_tid = IWL_MVM_TDLS_FW_TID;
  tdls_cfg_cmd.tx_to_ap_ssn = cpu_to_le16(0); /* not used for now */

  /* for now the Tx cmd is empty and unused */

  /* populate TDLS peer data */
  cnt = 0;
  for (i = 0; i < ARRAY_SIZE(mvm->fw_id_to_mac_id); i++) {
    sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[i], lockdep_is_held(&mvm->mutex));
    if (IS_ERR_OR_NULL(sta) || !sta->tdls) {
      continue;
    }

    tdls_cfg_cmd.sta_info[cnt].sta_id = i;
    tdls_cfg_cmd.sta_info[cnt].tx_to_peer_tid = IWL_MVM_TDLS_FW_TID;
    tdls_cfg_cmd.sta_info[cnt].tx_to_peer_ssn = cpu_to_le16(0);
    tdls_cfg_cmd.sta_info[cnt].is_initiator = cpu_to_le32(sta->tdls_initiator ? 1 : 0);

    cnt++;
  }

  tdls_cfg_cmd.tdls_peer_count = cnt;
  IWL_DEBUG_TDLS(mvm, "send TDLS config to FW for %d peers\n", cnt);

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

  pkt = cmd.resp_pkt;

  WARN_ON_ONCE(iwl_rx_packet_payload_len(pkt) != sizeof(*resp));

  /* we don't really care about the response at this point */

  iwl_free_resp(&cmd);
}

void iwl_mvm_recalc_tdls_state(struct iwl_mvm* mvm, struct ieee80211_vif* vif, bool sta_added) {
  int tdls_sta_cnt = iwl_mvm_tdls_sta_count(mvm, vif);

  /* when the first peer joins, send a power update first */
  if (tdls_sta_cnt == 1 && sta_added) {
    iwl_mvm_power_update_mac(mvm);
  }

  /* Configure the FW with TDLS peer info only if TDLS channel switch
   * capability is set.
   * TDLS config data is used currently only in TDLS channel switch code.
   * Supposed to serve also TDLS buffer station which is not implemneted
   * yet in FW*/
  if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_TDLS_CHANNEL_SWITCH)) {
    iwl_mvm_tdls_config(mvm, vif);
  }

  /* when the last peer leaves, send a power update last */
  if (tdls_sta_cnt == 0 && !sta_added) {
    iwl_mvm_power_update_mac(mvm);
  }
}

void iwl_mvm_mac_mgd_protect_tdls_discover(struct ieee80211_hw* hw, struct ieee80211_vif* vif) {
  struct iwl_mvm* mvm = IWL_MAC80211_GET_MVM(hw);
  uint32_t duration = 2 * vif->bss_conf.dtim_period * vif->bss_conf.beacon_int;

  /*
   * iwl_mvm_protect_session() reads directly from the device
   * (the system time), so make sure it is available.
   */
  if (iwl_mvm_ref_sync(mvm, IWL_MVM_REF_PROTECT_TDLS)) {
    return;
  }

  mutex_lock(&mvm->mutex);
  /* Protect the session to hear the TDLS setup response on the channel */
  iwl_mvm_protect_session(mvm, vif, duration, duration, 100, true);
  mutex_unlock(&mvm->mutex);

  iwl_mvm_unref(mvm, IWL_MVM_REF_PROTECT_TDLS);
}

static const char* iwl_mvm_tdls_cs_state_str(enum iwl_mvm_tdls_cs_state state) {
  switch (state) {
    case IWL_MVM_TDLS_SW_IDLE:
      return "IDLE";
    case IWL_MVM_TDLS_SW_REQ_SENT:
      return "REQ SENT";
    case IWL_MVM_TDLS_SW_RESP_RCVD:
      return "RESP RECEIVED";
    case IWL_MVM_TDLS_SW_REQ_RCVD:
      return "REQ RECEIVED";
    case IWL_MVM_TDLS_SW_ACTIVE:
      return "ACTIVE";
  }

  return NULL;
}

static void iwl_mvm_tdls_update_cs_state(struct iwl_mvm* mvm, enum iwl_mvm_tdls_cs_state state) {
  if (mvm->tdls_cs.state == state) {
    return;
  }

  IWL_DEBUG_TDLS(mvm, "TDLS channel switch state: %s -> %s\n",
                 iwl_mvm_tdls_cs_state_str(mvm->tdls_cs.state), iwl_mvm_tdls_cs_state_str(state));
  mvm->tdls_cs.state = state;

  /* we only send requests to our switching peer - update sent time */
  if (state == IWL_MVM_TDLS_SW_REQ_SENT) {
    mvm->tdls_cs.peer.sent_timestamp = iwl_read_prph(mvm->trans, DEVICE_SYSTEM_TIME_REG);
  }

  if (state == IWL_MVM_TDLS_SW_IDLE) {
    mvm->tdls_cs.cur_sta_id = IWL_MVM_INVALID_STA;
  }
}

void iwl_mvm_rx_tdls_notif(struct iwl_mvm* mvm, struct iwl_rx_cmd_buffer* rxb) {
  struct iwl_rx_packet* pkt = rxb_addr(rxb);
  struct iwl_tdls_channel_switch_notif* notif = (void*)pkt->data;
  struct ieee80211_sta* sta;
  unsigned int delay;
  struct iwl_mvm_sta* mvmsta;
  struct ieee80211_vif* vif;
  uint32_t sta_id = le32_to_cpu(notif->sta_id);

  iwl_assert_lock_held(&mvm->mutex);

  /* can fail sometimes */
  if (!le32_to_cpu(notif->status)) {
    iwl_mvm_tdls_update_cs_state(mvm, IWL_MVM_TDLS_SW_IDLE);
    return;
  }

  if (WARN_ON(sta_id >= IWL_MVM_STATION_COUNT)) {
    return;
  }

  sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id], lockdep_is_held(&mvm->mutex));
  /* the station may not be here, but if it is, it must be a TDLS peer */
  if (IS_ERR_OR_NULL(sta) || WARN_ON(!sta->tdls)) {
    return;
  }

  mvmsta = iwl_mvm_sta_from_mac80211(sta);
  vif = mvmsta->vif;

  /*
   * Update state and possibly switch again after this is over (DTIM).
   * Also convert TU to msec.
   */
  delay = TU_TO_MS(vif->bss_conf.dtim_period * vif->bss_conf.beacon_int);
  mod_delayed_work(system_wq, &mvm->tdls_cs.dwork, msecs_to_jiffies(delay));

  iwl_mvm_tdls_update_cs_state(mvm, IWL_MVM_TDLS_SW_ACTIVE);
}

static int iwl_mvm_tdls_check_action(struct iwl_mvm* mvm, enum iwl_tdls_channel_switch_type type,
                                     const uint8_t* peer, bool peer_initiator, uint32_t timestamp) {
  bool same_peer = false;
  int ret = 0;

  /* get the existing peer if it's there */
  if (mvm->tdls_cs.state != IWL_MVM_TDLS_SW_IDLE &&
      mvm->tdls_cs.cur_sta_id != IWL_MVM_INVALID_STA) {
    struct ieee80211_sta* sta = rcu_dereference_protected(
        mvm->fw_id_to_mac_id[mvm->tdls_cs.cur_sta_id], lockdep_is_held(&mvm->mutex));
    if (!IS_ERR_OR_NULL(sta)) {
      same_peer = ether_addr_equal(peer, sta->addr);
    }
  }

  switch (mvm->tdls_cs.state) {
    case IWL_MVM_TDLS_SW_IDLE:
      /*
       * might be spurious packet from the peer after the switch is
       * already done
       */
      if (type == TDLS_MOVE_CH) {
        ret = -EINVAL;
      }
      break;
    case IWL_MVM_TDLS_SW_REQ_SENT:
      /* only allow requests from the same peer */
      if (!same_peer) {
        ret = -EBUSY;
      } else if (type == TDLS_SEND_CHAN_SW_RESP_AND_MOVE_CH && !peer_initiator)
      /*
       * We received a ch-switch request while an outgoing
       * one is pending. Allow it if the peer is the link
       * initiator.
       */
      {
        ret = -EBUSY;
      } else if (type == TDLS_SEND_CHAN_SW_REQ)
      /* wait for idle before sending another request */
      {
        ret = -EBUSY;
      } else if (timestamp <= mvm->tdls_cs.peer.sent_timestamp)
      /* we got a stale response - ignore it */
      {
        ret = -EINVAL;
      }
      break;
    case IWL_MVM_TDLS_SW_RESP_RCVD:
      /*
       * we are waiting for the FW to give an "active" notification,
       * so ignore requests in the meantime
       */
      ret = -EBUSY;
      break;
    case IWL_MVM_TDLS_SW_REQ_RCVD:
      /* as above, allow the link initiator to proceed */
      if (type == TDLS_SEND_CHAN_SW_REQ) {
        if (!same_peer) {
          ret = -EBUSY;
        } else if (peer_initiator) { /* they are the initiator */
          ret = -EBUSY;
        }
      } else if (type == TDLS_MOVE_CH) {
        ret = -EINVAL;
      }
      break;
    case IWL_MVM_TDLS_SW_ACTIVE:
      /*
       * the only valid request when active is a request to return
       * to the base channel by the current off-channel peer
       */
      if (type != TDLS_MOVE_CH || !same_peer) {
        ret = -EBUSY;
      }
      break;
  }

  if (ret)
    IWL_DEBUG_TDLS(mvm, "Invalid TDLS action %d state %d peer %pM same_peer %d initiator %d\n",
                   type, mvm->tdls_cs.state, peer, same_peer, peer_initiator);

  return ret;
}

static int iwl_mvm_tdls_config_channel_switch(struct iwl_mvm* mvm, struct ieee80211_vif* vif,
                                              enum iwl_tdls_channel_switch_type type,
                                              const uint8_t* peer, bool peer_initiator,
                                              uint8_t oper_class, struct cfg80211_chan_def* chandef,
                                              uint32_t timestamp, uint16_t switch_time,
                                              uint16_t switch_timeout, struct sk_buff* skb,
                                              uint32_t ch_sw_tm_ie) {
  struct ieee80211_sta* sta;
  struct iwl_mvm_sta* mvmsta;
  struct ieee80211_tx_info* info;
  struct ieee80211_hdr* hdr;
  struct iwl_tdls_channel_switch_cmd cmd = {0};
  int ret;

  iwl_assert_lock_held(&mvm->mutex);

  ret = iwl_mvm_tdls_check_action(mvm, type, peer, peer_initiator, timestamp);
  if (ret) {
    return ret;
  }

  if (!skb || WARN_ON(skb->len > IWL_TDLS_CH_SW_FRAME_MAX_SIZE)) {
    ret = -EINVAL;
    goto out;
  }

  cmd.switch_type = type;
  cmd.timing.frame_timestamp = cpu_to_le32(timestamp);
  cmd.timing.switch_time = cpu_to_le32(switch_time);
  cmd.timing.switch_timeout = cpu_to_le32(switch_timeout);

  rcu_read_lock();
  sta = ieee80211_find_sta(vif, peer);
  if (!sta) {
    rcu_read_unlock();
    ret = -ENOENT;
    goto out;
  }
  mvmsta = iwl_mvm_sta_from_mac80211(sta);
  cmd.peer_sta_id = cpu_to_le32(mvmsta->sta_id);

  if (!chandef) {
    if (mvm->tdls_cs.state == IWL_MVM_TDLS_SW_REQ_SENT && mvm->tdls_cs.peer.chandef.chan) {
      /* actually moving to the channel */
      chandef = &mvm->tdls_cs.peer.chandef;
    } else if (mvm->tdls_cs.state == IWL_MVM_TDLS_SW_ACTIVE && type == TDLS_MOVE_CH) {
      /* we need to return to base channel */
      struct ieee80211_chanctx_conf* chanctx = rcu_dereference(vif->chanctx_conf);

      if (WARN_ON_ONCE(!chanctx)) {
        rcu_read_unlock();
        goto out;
      }

      chandef = &chanctx->def;
    }
  }

  if (chandef) {
    cmd.ci.band = (chandef->chan->band == NL80211_BAND_2GHZ ? PHY_BAND_24 : PHY_BAND_5);
    cmd.ci.channel = chandef->chan->hw_value;
    cmd.ci.width = iwl_mvm_get_channel_width(chandef);
    cmd.ci.ctrl_pos = iwl_mvm_get_ctrl_pos(chandef);
  }

  /* keep quota calculation simple for now - 50% of DTIM for TDLS */
  cmd.timing.max_offchan_duration =
      cpu_to_le32(TU_TO_US(vif->bss_conf.dtim_period * vif->bss_conf.beacon_int) / 2);

  /* Switch time is the first element in the switch-timing IE. */
  cmd.frame.switch_time_offset = cpu_to_le32(ch_sw_tm_ie + 2);

  info = IEEE80211_SKB_CB(skb);
  hdr = (void*)skb->data;
  if (info->control.hw_key) {
    if (info->control.hw_key->cipher != WLAN_CIPHER_SUITE_CCMP) {
      rcu_read_unlock();
      ret = -EINVAL;
      goto out;
    }
    iwl_mvm_set_tx_cmd_ccmp(info, &cmd.frame.tx_cmd);
  }

  iwl_mvm_set_tx_cmd(mvm, skb, &cmd.frame.tx_cmd, info, mvmsta->sta_id);

  iwl_mvm_set_tx_cmd_rate(mvm, &cmd.frame.tx_cmd, info, sta, hdr->frame_control);
  rcu_read_unlock();

  memcpy(cmd.frame.data, skb->data, skb->len);

  ret = iwl_mvm_send_cmd_pdu(mvm, TDLS_CHANNEL_SWITCH_CMD, 0, sizeof(cmd), &cmd);
  if (ret) {
    IWL_ERR(mvm, "Failed to send TDLS_CHANNEL_SWITCH cmd: %d\n", ret);
    goto out;
  }

  /* channel switch has started, update state */
  if (type != TDLS_MOVE_CH) {
    mvm->tdls_cs.cur_sta_id = mvmsta->sta_id;
    iwl_mvm_tdls_update_cs_state(
        mvm, type == TDLS_SEND_CHAN_SW_REQ ? IWL_MVM_TDLS_SW_REQ_SENT : IWL_MVM_TDLS_SW_REQ_RCVD);
  } else {
    iwl_mvm_tdls_update_cs_state(mvm, IWL_MVM_TDLS_SW_RESP_RCVD);
  }

out:

  /* channel switch failed - we are idle */
  if (ret) {
    iwl_mvm_tdls_update_cs_state(mvm, IWL_MVM_TDLS_SW_IDLE);
  }

  return ret;
}

void iwl_mvm_tdls_ch_switch_work(struct work_struct* work) {
  struct iwl_mvm* mvm;
  struct ieee80211_sta* sta;
  struct iwl_mvm_sta* mvmsta;
  struct ieee80211_vif* vif;
  unsigned int delay;
  int ret;

  mvm = container_of(work, struct iwl_mvm, tdls_cs.dwork.work);
  mutex_lock(&mvm->mutex);

  /* called after an active channel switch has finished or timed-out */
  iwl_mvm_tdls_update_cs_state(mvm, IWL_MVM_TDLS_SW_IDLE);

  /* station might be gone, in that case do nothing */
  if (mvm->tdls_cs.peer.sta_id == IWL_MVM_INVALID_STA) {
    goto out;
  }

  sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[mvm->tdls_cs.peer.sta_id],
                                  lockdep_is_held(&mvm->mutex));
  /* the station may not be here, but if it is, it must be a TDLS peer */
  if (!sta || IS_ERR(sta) || WARN_ON(!sta->tdls)) {
    goto out;
  }

  mvmsta = iwl_mvm_sta_from_mac80211(sta);
  vif = mvmsta->vif;
  ret = iwl_mvm_tdls_config_channel_switch(mvm, vif, TDLS_SEND_CHAN_SW_REQ, sta->addr,
                                           mvm->tdls_cs.peer.initiator, mvm->tdls_cs.peer.op_class,
                                           &mvm->tdls_cs.peer.chandef, 0, 0, 0,
                                           mvm->tdls_cs.peer.skb, mvm->tdls_cs.peer.ch_sw_tm_ie);
  if (ret) {
    IWL_ERR(mvm, "Not sending TDLS channel switch: %d\n", ret);
  }

  /* retry after a DTIM if we failed sending now */
  delay = TU_TO_MS(vif->bss_conf.dtim_period * vif->bss_conf.beacon_int);
  schedule_delayed_work(&mvm->tdls_cs.dwork, msecs_to_jiffies(delay));
out:
  mutex_unlock(&mvm->mutex);
}

int iwl_mvm_tdls_channel_switch(struct ieee80211_hw* hw, struct ieee80211_vif* vif,
                                struct ieee80211_sta* sta, uint8_t oper_class,
                                struct cfg80211_chan_def* chandef, struct sk_buff* tmpl_skb,
                                uint32_t ch_sw_tm_ie) {
  struct iwl_mvm* mvm = IWL_MAC80211_GET_MVM(hw);
  struct iwl_mvm_sta* mvmsta;
  unsigned int delay;
  int ret;

  mutex_lock(&mvm->mutex);

  IWL_DEBUG_TDLS(mvm, "TDLS channel switch with %pM ch %d width %d\n", sta->addr,
                 chandef->chan->center_freq, chandef->width);

  /* we only support a single peer for channel switching */
  if (mvm->tdls_cs.peer.sta_id != IWL_MVM_INVALID_STA) {
    IWL_DEBUG_TDLS(mvm, "Existing peer. Can't start switch with %pM\n", sta->addr);
    ret = -EBUSY;
    goto out;
  }

  ret = iwl_mvm_tdls_config_channel_switch(mvm, vif, TDLS_SEND_CHAN_SW_REQ, sta->addr,
                                           sta->tdls_initiator, oper_class, chandef, 0, 0, 0,
                                           tmpl_skb, ch_sw_tm_ie);
  if (ret) {
    goto out;
  }

  /*
   * Mark the peer as "in tdls switch" for this vif. We only allow a
   * single such peer per vif.
   */
  mvm->tdls_cs.peer.skb = skb_copy(tmpl_skb, GFP_KERNEL);
  if (!mvm->tdls_cs.peer.skb) {
    ret = -ENOMEM;
    goto out;
  }

  mvmsta = iwl_mvm_sta_from_mac80211(sta);
  mvm->tdls_cs.peer.sta_id = mvmsta->sta_id;
  mvm->tdls_cs.peer.chandef = *chandef;
  mvm->tdls_cs.peer.initiator = sta->tdls_initiator;
  mvm->tdls_cs.peer.op_class = oper_class;
  mvm->tdls_cs.peer.ch_sw_tm_ie = ch_sw_tm_ie;

  /*
   * Wait for 2 DTIM periods before attempting the next switch. The next
   * switch will be made sooner if the current one completes before that.
   */
  delay = 2 * TU_TO_MS(vif->bss_conf.dtim_period * vif->bss_conf.beacon_int);
  mod_delayed_work(system_wq, &mvm->tdls_cs.dwork, msecs_to_jiffies(delay));

out:
  mutex_unlock(&mvm->mutex);
  return ret;
}

void iwl_mvm_tdls_cancel_channel_switch(struct ieee80211_hw* hw, struct ieee80211_vif* vif,
                                        struct ieee80211_sta* sta) {
  struct iwl_mvm* mvm = IWL_MAC80211_GET_MVM(hw);
  struct ieee80211_sta* cur_sta;
  bool wait_for_phy = false;

  mutex_lock(&mvm->mutex);

  IWL_DEBUG_TDLS(mvm, "TDLS cancel channel switch with %pM\n", sta->addr);

  /* we only support a single peer for channel switching */
  if (mvm->tdls_cs.peer.sta_id == IWL_MVM_INVALID_STA) {
    IWL_DEBUG_TDLS(mvm, "No ch switch peer - %pM\n", sta->addr);
    goto out;
  }

  cur_sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[mvm->tdls_cs.peer.sta_id],
                                      lockdep_is_held(&mvm->mutex));
  /* make sure it's the same peer */
  if (cur_sta != sta) {
    goto out;
  }

  /*
   * If we're currently in a switch because of the now canceled peer,
   * wait a DTIM here to make sure the phy is back on the base channel.
   * We can't otherwise force it.
   */
  if (mvm->tdls_cs.cur_sta_id == mvm->tdls_cs.peer.sta_id &&
      mvm->tdls_cs.state != IWL_MVM_TDLS_SW_IDLE) {
    wait_for_phy = true;
  }

  mvm->tdls_cs.peer.sta_id = IWL_MVM_INVALID_STA;
  dev_kfree_skb(mvm->tdls_cs.peer.skb);
  mvm->tdls_cs.peer.skb = NULL;

out:
  mutex_unlock(&mvm->mutex);

  /* make sure the phy is on the base channel */
  if (wait_for_phy) {
    msleep(TU_TO_MS(vif->bss_conf.dtim_period * vif->bss_conf.beacon_int));
  }

  /* flush the channel switch state */
  flush_delayed_work(&mvm->tdls_cs.dwork);

  IWL_DEBUG_TDLS(mvm, "TDLS ending channel switch with %pM\n", sta->addr);
}

void iwl_mvm_tdls_recv_channel_switch(struct ieee80211_hw* hw, struct ieee80211_vif* vif,
                                      struct ieee80211_tdls_ch_sw_params* params) {
  struct iwl_mvm* mvm = IWL_MAC80211_GET_MVM(hw);
  enum iwl_tdls_channel_switch_type type;
  unsigned int delay;
  const char* action_str = params->action_code == WLAN_TDLS_CHANNEL_SWITCH_REQUEST ? "REQ" : "RESP";

  mutex_lock(&mvm->mutex);

  IWL_DEBUG_TDLS(mvm, "Received TDLS ch switch action %s from %pM status %d\n", action_str,
                 params->sta->addr, params->status);

  /*
   * we got a non-zero status from a peer we were switching to - move to
   * the idle state and retry again later
   */
  if (params->action_code == WLAN_TDLS_CHANNEL_SWITCH_RESPONSE && params->status != 0 &&
      mvm->tdls_cs.state == IWL_MVM_TDLS_SW_REQ_SENT &&
      mvm->tdls_cs.cur_sta_id != IWL_MVM_INVALID_STA) {
    struct ieee80211_sta* cur_sta;

    /* make sure it's the same peer */
    cur_sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[mvm->tdls_cs.cur_sta_id],
                                        lockdep_is_held(&mvm->mutex));
    if (cur_sta == params->sta) {
      iwl_mvm_tdls_update_cs_state(mvm, IWL_MVM_TDLS_SW_IDLE);
      goto retry;
    }
  }

  type = (params->action_code == WLAN_TDLS_CHANNEL_SWITCH_REQUEST)
             ? TDLS_SEND_CHAN_SW_RESP_AND_MOVE_CH
             : TDLS_MOVE_CH;

  iwl_mvm_tdls_config_channel_switch(mvm, vif, type, params->sta->addr, params->sta->tdls_initiator,
                                     0, params->chandef, params->timestamp, params->switch_time,
                                     params->switch_timeout, params->tmpl_skb, params->ch_sw_tm_ie);

retry:
  /* register a timeout in case we don't succeed in switching */
  delay = vif->bss_conf.dtim_period * vif->bss_conf.beacon_int * 1024 / 1000;
  mod_delayed_work(system_wq, &mvm->tdls_cs.dwork, msecs_to_jiffies(delay));
  mutex_unlock(&mvm->mutex);
}

#ifdef CPTCFG_IWLMVM_TDLS_PEER_CACHE
void iwl_mvm_tdls_peer_cache_pkt(struct iwl_mvm* mvm, struct ieee80211_hdr* hdr, uint32_t len,
                                 int rxq) {
  struct iwl_mvm_tdls_peer_counter* cnt;
  uint8_t* addr;

  /*
   * To reduce code runtime and complexity, we don't check the packet
   * arrived on the correct vif, or even if the current vif is a station.
   * While it is theoretically possible for a TDLS peer to also be
   * connected to us in the capacity of a AP/GO, this will not happen
   * in practice.
   */

  if (list_empty(&mvm->tdls_peer_cache_list)) {
    return;
  }

  if (len < sizeof(*hdr) || !ieee80211_is_data(hdr->frame_control)) {
    return;
  }

  addr = rxq < 0 ? ieee80211_get_DA(hdr) : ieee80211_get_SA(hdr);

  /* we rely on the Rx and Tx path mutual atomicity for the counters */
  rcu_read_lock();
  list_for_each_entry_rcu(cnt, &mvm->tdls_peer_cache_list,
                          list) if (ether_addr_equal(cnt->mac.addr, addr)) {
    if (rxq < 0) {
      cnt->tx_bytes += len;
    } else {
      cnt->rx[rxq].bytes += len;
    }

    break;
  }
  rcu_read_unlock();
}

void iwl_mvm_tdls_peer_cache_clear(struct iwl_mvm* mvm, struct ieee80211_vif* vif) {
  struct iwl_mvm_tdls_peer_counter *cnt, *tmp;

  /*
   * mvm->mutex is held or the HW is already unregistered, barring
   * vendor commands that can change the list.
   */
  list_for_each_entry_safe(cnt, tmp, &mvm->tdls_peer_cache_list, list) {
    if (vif && cnt->vif != vif) {
      continue;
    }

    mvm->tdls_peer_cache_cnt--;
    list_del_rcu(&cnt->list);
    kfree_rcu(cnt, rcu_head);
  }
}

/* requires RCU read side lock taken */
struct iwl_mvm_tdls_peer_counter* iwl_mvm_tdls_peer_cache_find(struct iwl_mvm* mvm,
                                                               const uint8_t* addr) {
  struct iwl_mvm_tdls_peer_counter* cnt;

  list_for_each_entry_rcu(cnt, &mvm->tdls_peer_cache_list,
                          list) if (memcmp(addr, cnt->mac.addr, ETH_ALEN) == 0) {
    break;
  }

  if (&cnt->list == &mvm->tdls_peer_cache_list) {
    return NULL;
  }

  return cnt;
}
#endif /* CPTCFG_IWLMVM_TDLS_PEER_CACHE */
