/******************************************************************************
 *
 * 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 "mvm.h"
#include "rs.h"

static void iwl_start_agg(struct iwl_mvm* mvm, struct ieee80211_sta* sta, int tid) {
  struct iwl_mvm_sta* mvmsta = iwl_mvm_sta_from_mac80211(sta);
  struct iwl_mvm_tid_data* tid_data;

  tid_data = &mvmsta->tid_data[tid];
  if (tid_data->state == IWL_AGG_OFF && mvmsta->sta_state >= IEEE80211_STA_AUTHORIZED) {
    int ret = ieee80211_start_tx_ba_session(sta, tid, 0);
    if (ret == -EAGAIN) {
      ieee80211_stop_tx_ba_session(sta, tid);
      return;
    }
    if (ret == 0) {
      tid_data->state = IWL_AGG_QUEUED;
    }
  }
}

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 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,
                                        TLC_MNG_CONFIG_PARAMS_CMD_API_S* 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->mcs[i][0] = (supp);
    if (sta->bandwidth == IEEE80211_STA_RX_BW_160) {
      cmd->mcs[i][1] = cmd->mcs[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,
                                       TLC_MNG_CONFIG_PARAMS_CMD_API_S* 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->mcs[i][0] = (rs_fw_he_ieee80211_mcs_to_rs_mcs(_mcs_80));
    cmd->mcs[i][1] = (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,
                                 TLC_MNG_CONFIG_PARAMS_CMD_API_S* cmd) {
  int i;
  unsigned long tmp;
  unsigned long supp;
  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->nonHt = supp;
  cmd->bestSuppMode = IWL_TLC_MNG_MODE_NON_HT;

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

/// TODO: merge file?
#include "rateScaleMng.c"

static void rs_drv_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* lq_sta = &mvmsta->lq_sta.rs_drv;
  struct ieee80211_supported_band* sband;
  RS_MNG_STA_INFO_S* staInfo = &lq_sta->pers;
  TLC_MNG_CONFIG_PARAMS_CMD_API_S config = {};

#ifdef CPTCFG_IWLWIFI_DEBUGFS
  iwl_mvm_reset_frame_stats(mvm);
#endif
  sband = hw->wiphy->bands[band];

  mvmsta->amsdu_enabled = 0;
  mvmsta->max_amsdu_len = sta->max_amsdu_len;

  config.maxChWidth = update ? rs_fw_bw_from_sta_bw(sta) : IWL_TLC_MNG_CH_WIDTH_20MHZ;
  config.configFlags = rs_fw_set_config_flags(mvm, sta);
  config.chainsEnabled = rs_fw_set_active_chains(iwl_mvm_get_valid_tx_ant(mvm));
  config.maxMpduLen = sta->max_amsdu_len;
  config.sgiChWidthSupport = rs_fw_sgi_cw_support(sta);
  config.amsduSupported = iwl_mvm_is_csum_supported(mvm);
  config.band = sband->band;
  rs_fw_set_supp_rates(sta, sband, &config);

  cmdHandlerTlcMngConfig(mvm, sta, mvmsta, staInfo, &config, update);
}

void iwl_mvm_rs_rate_init(struct iwl_mvm* mvm, struct ieee80211_sta* sta, enum nl80211_band band,
                          bool update) {
  if (iwl_mvm_has_tlc_offload(mvm)) {
    rs_fw_rate_init(mvm, sta, band, update);
  } else {
    rs_drv_rate_init(mvm, sta, band, update);
  }
}

void iwl_mvm_rs_tx_status(struct iwl_mvm* mvm, struct ieee80211_sta* sta, int tid,
                          struct ieee80211_tx_info* info, bool is_ndp) {
  struct iwl_mvm_sta* mvmsta = iwl_mvm_sta_from_mac80211(sta);
  struct iwl_lq_sta* lq_sta = &mvmsta->lq_sta.rs_drv;
  RS_MNG_STA_INFO_S* staInfo = &lq_sta->pers;
  TLC_STAT_COMMON_API_S stats;
  int failures = info->status.rates[0].count - 1;
  bool acked = !!(info->flags & IEEE80211_TX_STAT_ACK);

  if ((info->flags & IEEE80211_TX_CTL_AMPDU) && !(info->flags & IEEE80211_TX_STAT_AMPDU)) {
    return;
  }

  if (info->flags & IEEE80211_TX_STAT_AMPDU) {
    stats.baTxed = info->status.ampdu_len;
    stats.baAcked = info->status.ampdu_ack_len;
    stats.trafficLoad = stats.baTxed;
    stats.txed[0] = stats.baTxed;
    stats.txed[1] = 0;
    stats.acked[0] = stats.baAcked;
    stats.acked[1] = 0;
  } else {
    stats.baTxed = 0;
    stats.baAcked = 0;
    stats.trafficLoad = 0;
    stats.txed[0] = 1;
    stats.txed[1] = !!failures;
    stats.acked[0] = !failures && acked;
    stats.acked[1] = !!failures && acked;
  }

  tlcStatUpdateHandler(staInfo, &stats, mvm, sta, tid, is_ndp);
}

#ifdef CPTCFG_IWLWIFI_DEBUGFS
void iwl_mvm_reset_frame_stats(struct iwl_mvm* mvm) {}

void iwl_mvm_update_frame_stats(struct iwl_mvm* mvm, uint32_t rate, bool agg) {}

/* TODO */
int rs_pretty_print_rate(char* buf, int bufsz, const uint32_t rate) { return 0; }
#endif

static void* rs_alloc(struct ieee80211_hw* hw, struct dentry* debugfsdir) {
  return IWL_MAC80211_GET_MVM(hw);
}

static void rs_free(void* priv) {}

static void* rs_alloc_sta(void* priv, struct ieee80211_sta* sta, gfp_t gfp) {
  struct iwl_mvm* mvm = priv;
  struct iwl_mvm_sta* mvmsta = iwl_mvm_sta_from_mac80211(sta);
  struct iwl_lq_sta* lq_sta = &mvmsta->lq_sta.rs_drv;
  RS_MNG_STA_INFO_S* staInfo = &lq_sta->pers;
  void* priv_sta = lq_sta;

  rsMngResetStaInfo(mvm, sta, mvmsta, staInfo, false);
  return priv_sta;
}

static void rs_rate_init(void* priv, struct ieee80211_supported_band* sband,
                         struct cfg80211_chan_def* chandef, struct ieee80211_sta* sta,
                         void* priv_sta) {}

static void rs_rate_update(void* priv, struct ieee80211_supported_band* sband,
                           struct cfg80211_chan_def* chandef, struct ieee80211_sta* sta,
                           void* priv_sta, uint32_t changed) {
  struct iwl_mvm* mvm = priv;
  struct iwl_mvm_sta* mvmsta = iwl_mvm_sta_from_mac80211(sta);
  int tid;

  if (!mvmsta->vif) {
    return;
  }

  for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++) {
    ieee80211_stop_tx_ba_session(sta, tid);
  }

  iwl_mvm_rs_rate_init(mvm, sta, sband->band, true);
}

static void rs_free_sta(void* priv, struct ieee80211_sta* sta, void* priv_sta) {}

static inline uint8_t rs_get_tid(struct ieee80211_hdr* hdr) {
  int tid = IWL_MAX_TID_COUNT;

  if (ieee80211_is_data_qos(hdr->frame_control)) {
    tid = ieee80211_get_tid(hdr);
  }

  return tid;
}

static void rs_tx_status(void* priv, struct ieee80211_supported_band* sband,
                         struct ieee80211_sta* sta, void* priv_sta, struct sk_buff* skb) {
  struct iwl_mvm* mvm = priv;
  struct iwl_mvm_sta* mvmsta = iwl_mvm_sta_from_mac80211(sta);
  struct ieee80211_tx_info* info = IEEE80211_SKB_CB(skb);
  struct ieee80211_hdr* hdr = (void*)skb->data;

  if (!mvmsta->vif) {
    return;
  }

  if (!ieee80211_is_data(hdr->frame_control) || (info->flags & IEEE80211_TX_CTL_NO_ACK)) {
    return;
  }

  iwl_mvm_rs_tx_status(mvm, sta, rs_get_tid(hdr), info,
                       ieee80211_is_qos_nullfunc(hdr->frame_control));
}

static void rs_get_rate(void* priv, struct ieee80211_sta* sta, void* priv_sta,
                        struct ieee80211_tx_rate_control* txrc) {
  struct iwl_mvm_sta* mvmsta = NULL;
  uint32_t hwrate;
  struct ieee80211_tx_info* info = IEEE80211_SKB_CB(txrc->skb);

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

  if (rate_control_send_low(sta, mvmsta, txrc)) {
    return;
  }

  if (!mvmsta) {
    return;
  }

  hwrate = le32_to_cpu(mvmsta->lq_sta.rs_drv.lq.rs_table[0]);
  iwl_mvm_hwrate_to_tx_rate(hwrate, info->band, &info->control.rates[0]);
  info->control.rates[0].count = 1;
}

static const struct rate_control_ops rs_ops = {
    .name = RS_NAME,
    .alloc = rs_alloc,
    .free = rs_free,
    .alloc_sta = rs_alloc_sta,
    .rate_init = rs_rate_init,
    .rate_update = rs_rate_update,
    .free_sta = rs_free_sta,
    .tx_status = rs_tx_status,
    .get_rate = rs_get_rate,
};

int iwl_mvm_rate_control_register(void) { return ieee80211_rate_control_register(&rs_ops); }

void iwl_mvm_rate_control_unregister(void) { ieee80211_rate_control_unregister(&rs_ops); }

static int rs_drv_tx_protection(struct iwl_mvm* mvm, struct iwl_mvm_sta* mvmsta, bool enable) {
  if (enable) {
    mvmsta->tx_protection++;
  } else {
    mvmsta->tx_protection--;
  }

  if (mvmsta->tx_protection) {
    mvmsta->lq_sta.rs_drv.lq.flags |= LQ_FLAG_USE_RTS_MSK;
  } else {
    mvmsta->lq_sta.rs_drv.lq.flags &= ~LQ_FLAG_USE_RTS_MSK;
  }

  return iwl_mvm_send_lq_cmd(mvm, &mvmsta->lq_sta.rs_drv.lq, false);
}

int iwl_mvm_tx_protection(struct iwl_mvm* mvm, struct iwl_mvm_sta* mvmsta, bool enable) {
  if (iwl_mvm_has_tlc_offload(mvm)) {
    return rs_fw_tx_protection(mvm, mvmsta, enable);
  } else {
    return rs_drv_tx_protection(mvm, mvmsta, enable);
  }
}

void rs_update_last_rssi(struct iwl_mvm* mvm, struct iwl_mvm_sta* mvmsta,
                         struct ieee80211_rx_status* rx_status) {}
