/******************************************************************************
 *
 * 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 "fw-api.h"
#include "iwl-op-mode.h"
#include "mvm.h"
#include "rs.h"
#include "sta.h"

static uint8_t rs_fw_bw_from_sta_bw(struct ieee80211_sta* sta) {
  switch (sta->bandwidth) {
    case IEEE80211_STA_RX_BW_160:
      return IWL_TLC_MNG_CH_WIDTH_160MHZ;
    case IEEE80211_STA_RX_BW_80:
      return IWL_TLC_MNG_CH_WIDTH_80MHZ;
    case IEEE80211_STA_RX_BW_40:
      return IWL_TLC_MNG_CH_WIDTH_40MHZ;
    case IEEE80211_STA_RX_BW_20:
    default:
      return IWL_TLC_MNG_CH_WIDTH_20MHZ;
  }
}

static uint8_t rs_fw_set_active_chains(uint8_t chains) {
  uint8_t fw_chains = 0;

  if (chains & ANT_A) {
    fw_chains |= IWL_TLC_MNG_CHAIN_A_MSK;
  }
  if (chains & ANT_B) {
    fw_chains |= IWL_TLC_MNG_CHAIN_B_MSK;
  }
  if (chains & ANT_C) {
    WARN(false, "tlc offload doesn't support antenna C. chains: 0x%x\n", chains);
  }

  return fw_chains;
}

static uint8_t rs_fw_sgi_cw_support(struct ieee80211_sta* sta) {
  struct ieee80211_sta_ht_cap* ht_cap = &sta->ht_cap;
  struct ieee80211_sta_vht_cap* vht_cap = &sta->vht_cap;
  struct ieee80211_sta_he_cap* he_cap = &sta->he_cap;
  uint8_t supp = 0;

  if (he_cap && he_cap->has_he) {
    return 0;
  }

  if (ht_cap->cap & IEEE80211_HT_CAP_SGI_20) {
    supp |= BIT(IWL_TLC_MNG_CH_WIDTH_20MHZ);
  }
  if (ht_cap->cap & IEEE80211_HT_CAP_SGI_40) {
    supp |= BIT(IWL_TLC_MNG_CH_WIDTH_40MHZ);
  }
  if (vht_cap->cap & IEEE80211_VHT_CAP_SHORT_GI_80) {
    supp |= BIT(IWL_TLC_MNG_CH_WIDTH_80MHZ);
  }
  if (vht_cap->cap & IEEE80211_VHT_CAP_SHORT_GI_160) {
    supp |= BIT(IWL_TLC_MNG_CH_WIDTH_160MHZ);
  }

  return supp;
}

static uint16_t rs_fw_set_config_flags(struct iwl_mvm* mvm, struct ieee80211_sta* sta) {
  struct ieee80211_sta_ht_cap* ht_cap = &sta->ht_cap;
  struct ieee80211_sta_vht_cap* vht_cap = &sta->vht_cap;
  struct ieee80211_sta_he_cap* he_cap = &sta->he_cap;
  bool vht_ena = vht_cap && vht_cap->vht_supported;
  uint16_t flags = 0;

  if (mvm->cfg->ht_params->stbc && (num_of_ant(iwl_mvm_get_valid_tx_ant(mvm)) > 1)) {
    if (he_cap && he_cap->has_he) {
      if (he_cap->he_cap_elem.phy_cap_info[2] & IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ) {
        flags |= IWL_TLC_MNG_CFG_FLAGS_STBC_MSK;
      }

      if (he_cap->he_cap_elem.phy_cap_info[7] & IEEE80211_HE_PHY_CAP7_STBC_RX_ABOVE_80MHZ) {
        flags |= IWL_TLC_MNG_CFG_FLAGS_HE_STBC_160MHZ_MSK;
      }
    } else if ((ht_cap && (ht_cap->cap & IEEE80211_HT_CAP_RX_STBC)) ||
               (vht_ena && (vht_cap->cap & IEEE80211_VHT_CAP_RXSTBC_MASK))) {
      flags |= IWL_TLC_MNG_CFG_FLAGS_STBC_MSK;
    }
  }

  if (mvm->cfg->ht_params->ldpc && ((ht_cap && (ht_cap->cap & IEEE80211_HT_CAP_LDPC_CODING)) ||
                                    (vht_ena && (vht_cap->cap & IEEE80211_VHT_CAP_RXLDPC)))) {
    flags |= IWL_TLC_MNG_CFG_FLAGS_LDPC_MSK;
  }

  if (he_cap && he_cap->has_he &&
      (he_cap->he_cap_elem.phy_cap_info[3] & IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_MASK)) {
    flags |= IWL_TLC_MNG_CFG_FLAGS_HE_DCM_NSS_1_MSK;
  }

  return flags;
}

static int rs_fw_vht_highest_rx_mcs_index(const struct ieee80211_sta_vht_cap* vht_cap, int nss) {
  uint16_t rx_mcs = le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map) & (0x3 << (2 * (nss - 1)));
  rx_mcs >>= (2 * (nss - 1));

  switch (rx_mcs) {
    case IEEE80211_VHT_MCS_SUPPORT_0_7:
      return IWL_TLC_MNG_HT_RATE_MCS7;
    case IEEE80211_VHT_MCS_SUPPORT_0_8:
      return IWL_TLC_MNG_HT_RATE_MCS8;
    case IEEE80211_VHT_MCS_SUPPORT_0_9:
      return IWL_TLC_MNG_HT_RATE_MCS9;
    default:
      WARN_ON_ONCE(1);
      break;
  }

  return 0;
}

static void rs_fw_vht_set_enabled_rates(const struct ieee80211_sta* sta,
                                        const struct ieee80211_sta_vht_cap* vht_cap,
                                        struct iwl_tlc_config_cmd* cmd) {
  uint16_t supp;
  int i, highest_mcs;

  for (i = 0; i < sta->rx_nss; i++) {
    if (i == MAX_NSS) {
      break;
    }

    highest_mcs = rs_fw_vht_highest_rx_mcs_index(vht_cap, i + 1);
    if (!highest_mcs) {
      continue;
    }

    supp = BIT(highest_mcs + 1) - 1;
    if (sta->bandwidth == IEEE80211_STA_RX_BW_20) {
      supp &= ~BIT(IWL_TLC_MNG_HT_RATE_MCS9);
    }

    cmd->ht_rates[i][0] = cpu_to_le16(supp);
    if (sta->bandwidth == IEEE80211_STA_RX_BW_160) {
      cmd->ht_rates[i][1] = cmd->ht_rates[i][0];
    }
  }
}

static uint16_t rs_fw_he_ieee80211_mcs_to_rs_mcs(uint16_t mcs) {
  switch (mcs) {
    case IEEE80211_HE_MCS_SUPPORT_0_7:
      return BIT(IWL_TLC_MNG_HT_RATE_MCS7 + 1) - 1;
    case IEEE80211_HE_MCS_SUPPORT_0_9:
      return BIT(IWL_TLC_MNG_HT_RATE_MCS9 + 1) - 1;
    case IEEE80211_HE_MCS_SUPPORT_0_11:
      return BIT(IWL_TLC_MNG_HT_RATE_MCS11 + 1) - 1;
    case IEEE80211_HE_MCS_NOT_SUPPORTED:
      return 0;
  }

  WARN(1, "invalid HE MCS %d\n", mcs);
  return 0;
}

static void rs_fw_he_set_enabled_rates(const struct ieee80211_sta* sta,
                                       const struct ieee80211_sta_he_cap* he_cap,
                                       struct iwl_tlc_config_cmd* cmd) {
  uint16_t mcs_160 = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_160);
  uint16_t mcs_80 = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_80);
  int i;

  for (i = 0; i < sta->rx_nss && i < MAX_NSS; i++) {
    uint16_t _mcs_160 = (mcs_160 >> (2 * i)) & 0x3;
    uint16_t _mcs_80 = (mcs_80 >> (2 * i)) & 0x3;

    cmd->ht_rates[i][0] = cpu_to_le16(rs_fw_he_ieee80211_mcs_to_rs_mcs(_mcs_80));
    cmd->ht_rates[i][1] = cpu_to_le16(rs_fw_he_ieee80211_mcs_to_rs_mcs(_mcs_160));
  }
}

static void rs_fw_set_supp_rates(struct ieee80211_sta* sta, struct ieee80211_supported_band* sband,
                                 struct iwl_tlc_config_cmd* cmd) {
  int i;
  unsigned long tmp;
  unsigned long supp; /* must be unsigned long for for_each_set_bit */
  const struct ieee80211_sta_ht_cap* ht_cap = &sta->ht_cap;
  const struct ieee80211_sta_vht_cap* vht_cap = &sta->vht_cap;
  const struct ieee80211_sta_he_cap* he_cap = &sta->he_cap;

  /* non HT rates */
  supp = 0;
  tmp = sta->supp_rates[sband->band];
  for_each_set_bit(i, &tmp, BITS_PER_LONG) supp |= BIT(sband->bitrates[i].hw_value);

  cmd->non_ht_rates = cpu_to_le16(supp);
  cmd->mode = IWL_TLC_MNG_MODE_NON_HT;

  /* HT/VHT rates */
  if (he_cap && he_cap->has_he) {
    cmd->mode = IWL_TLC_MNG_MODE_HE;
    rs_fw_he_set_enabled_rates(sta, he_cap, cmd);
  } else if (vht_cap && vht_cap->vht_supported) {
    cmd->mode = IWL_TLC_MNG_MODE_VHT;
    rs_fw_vht_set_enabled_rates(sta, vht_cap, cmd);
  } else if (ht_cap && ht_cap->ht_supported) {
    cmd->mode = IWL_TLC_MNG_MODE_HT;
    cmd->ht_rates[0][0] = cpu_to_le16(ht_cap->mcs.rx_mask[0]);
    cmd->ht_rates[1][0] = cpu_to_le16(ht_cap->mcs.rx_mask[1]);
  }
}

void iwl_mvm_tlc_update_notif(struct iwl_mvm* mvm, struct iwl_rx_cmd_buffer* rxb) {
  struct iwl_rx_packet* pkt = rxb_addr(rxb);
  struct iwl_tlc_update_notif* notif;
  struct ieee80211_sta* sta;
  struct iwl_mvm_sta* mvmsta;
  struct iwl_lq_sta_rs_fw* lq_sta;
  uint32_t flags;

  rcu_read_lock();

  notif = (void*)pkt->data;
  sta = rcu_dereference(mvm->fw_id_to_mac_id[notif->sta_id]);
  if (IS_ERR_OR_NULL(sta)) {
    IWL_ERR(mvm, "Invalid sta id (%d) in FW TLC notification\n", notif->sta_id);
    goto out;
  }

  mvmsta = iwl_mvm_sta_from_mac80211(sta);

  if (!mvmsta) {
    IWL_ERR(mvm, "Invalid sta id (%d) in FW TLC notification\n", notif->sta_id);
    goto out;
  }

  flags = le32_to_cpu(notif->flags);

  lq_sta = &mvmsta->lq_sta.rs_fw;

  if (flags & IWL_TLC_NOTIF_FLAG_RATE) {
    lq_sta->last_rate_n_flags = le32_to_cpu(notif->rate);
    IWL_DEBUG_RATE(mvm, "new rate_n_flags: 0x%X\n", lq_sta->last_rate_n_flags);
  }

  if (flags & IWL_TLC_NOTIF_FLAG_AMSDU) {
    uint16_t size = le32_to_cpu(notif->amsdu_size);
    int i;

    if (WARN_ON(sta->max_amsdu_len < size)) {
      goto out;
    }

    mvmsta->amsdu_enabled = le32_to_cpu(notif->amsdu_enabled);
    mvmsta->max_amsdu_len = size;
    sta->max_rc_amsdu_len = mvmsta->max_amsdu_len;

    for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
      if (mvmsta->amsdu_enabled & BIT(i)) {
        sta->max_tid_amsdu_len[i] = iwl_mvm_max_amsdu_size(mvm, sta, i);
      } else
      /*
       * Not so elegant, but this will effectively
       * prevent AMSDU on this TID
       */
      {
        sta->max_tid_amsdu_len[i] = 1;
      }
    }

    IWL_DEBUG_RATE(mvm,
                   "AMSDU update. AMSDU size: %d, AMSDU selected size: %d, AMSDU TID bitmap 0x%X\n",
                   le32_to_cpu(notif->amsdu_size), size, mvmsta->amsdu_enabled);
  }
out:
  rcu_read_unlock();
}

void rs_fw_rate_init(struct iwl_mvm* mvm, struct ieee80211_sta* sta, enum nl80211_band band,
                     bool update) {
  struct ieee80211_hw* hw = mvm->hw;
  struct iwl_mvm_sta* mvmsta = iwl_mvm_sta_from_mac80211(sta);
  struct iwl_lq_sta_rs_fw* lq_sta = &mvmsta->lq_sta.rs_fw;
  uint32_t cmd_id = iwl_cmd_id(TLC_MNG_CONFIG_CMD, DATA_PATH_GROUP, 0);
  struct ieee80211_supported_band* sband;
  struct iwl_tlc_config_cmd cfg_cmd = {
      .sta_id = mvmsta->sta_id,
      .max_ch_width = update ? rs_fw_bw_from_sta_bw(sta) : RATE_MCS_CHAN_WIDTH_20,
      .flags = cpu_to_le16(rs_fw_set_config_flags(mvm, sta)),
      .chains = rs_fw_set_active_chains(iwl_mvm_get_valid_tx_ant(mvm)),
      .max_mpdu_len = cpu_to_le16(sta->max_amsdu_len),
      .sgi_ch_width_supp = rs_fw_sgi_cw_support(sta),
      .amsdu = iwl_mvm_is_csum_supported(mvm),
  };
  int ret;

  memset(lq_sta, 0, offsetof(typeof(*lq_sta), pers));

#ifdef CPTCFG_IWLWIFI_DEBUGFS
  iwl_mvm_reset_frame_stats(mvm);
#endif
  sband = hw->wiphy->bands[band];
  rs_fw_set_supp_rates(sta, sband, &cfg_cmd);

  ret = iwl_mvm_send_cmd_pdu(mvm, cmd_id, 0, sizeof(cfg_cmd), &cfg_cmd);
  if (ret) {
    IWL_ERR(mvm, "Failed to send rate scale config (%d)\n", ret);
  }
}

void iwl_mvm_rs_add_sta(struct iwl_mvm* mvm, struct iwl_mvm_sta* mvmsta) {
  struct iwl_lq_sta_rs_fw* lq_sta = &mvmsta->lq_sta.rs_fw;

  IWL_DEBUG_RATE(mvm, "create station rate scale window\n");

  lq_sta->pers.drv = mvm;
  lq_sta->pers.sta_id = mvmsta->sta_id;
  lq_sta->pers.chains = 0;
  memset(lq_sta->pers.chain_signal, 0, sizeof(lq_sta->pers.chain_signal));
  lq_sta->pers.last_rssi = S8_MIN;
  lq_sta->last_rate_n_flags = 0;

#ifdef CPTCFG_MAC80211_DEBUGFS
  lq_sta->pers.dbg_fixed_rate = 0;
#endif
}

int rs_fw_tx_protection(struct iwl_mvm* mvm, struct iwl_mvm_sta* mvmsta, bool enable) {
  /* TODO: need to introduce a new FW cmd since LQ cmd is not relevant */
  IWL_DEBUG_RATE(mvm, "tx protection - not implemented yet.\n");
  return 0;
}
