/******************************************************************************
 *
 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
 * Copyright(c) 2013 - 2014 Intel Mobile Communications 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 <fuchsia/hardware/wlan/info/c/banjo.h>

#include <fuchsia/hardware/wlanphyinfo/c/banjo.h>

#include "third_party/iwlwifi/mvm/fw-api.h"
#include "third_party/iwlwifi/mvm/mvm.h"

// A channel setting used as default value. In some cases, we need an arbitrary value for channel.
// For example, during initializing a PHY context in firmware, we need a (whatever) value to add
// an entry in firmware. This value usually will be changed later.
const wlan_channel_t default_channel = {
    .primary = 1,
    .cbw = CHANNEL_BANDWIDTH_CBW20,
};

// Converts channel number to band type.
//
// Args:
//   chan_num: starts from 1.
//
// Returns:
//   the band ID.
wlan_info_band_t iwl_mvm_get_channel_band(uint8_t chan_num) {
  return chan_num < 14 ? WLAN_INFO_BAND_2GHZ : WLAN_INFO_BAND_5GHZ;
}

/* Maps the driver specific channel width definition to the fw values */
uint8_t iwl_mvm_get_channel_width(const wlan_channel_t* chandef) {
  switch (chandef->cbw) {
    case CHANNEL_BANDWIDTH_CBW20:
      return PHY_VHT_CHANNEL_MODE20;
    case CHANNEL_BANDWIDTH_CBW40:
    case CHANNEL_BANDWIDTH_CBW40BELOW:  // fall-thru
      return PHY_VHT_CHANNEL_MODE40;
    case CHANNEL_BANDWIDTH_CBW80:
      return PHY_VHT_CHANNEL_MODE80;
    case CHANNEL_BANDWIDTH_CBW160:
      return PHY_VHT_CHANNEL_MODE160;
    default:
      WARN(1, "Invalid channel width=%u", chandef->width);
      return PHY_VHT_CHANNEL_MODE20;
  }
}

/*
 * Maps the driver specific control channel position (relative to the center
 * freq) definitions to the the fw values.
 *
 * Here is the channel list: https://en.wikipedia.org/wiki/List_of_WLAN_channels
 */
uint8_t iwl_mvm_get_ctrl_pos(const wlan_channel_t* chandef) {
  uint8_t primary = chandef->primary;
  channel_bandwidth_t cbw = chandef->cbw;
  uint8_t base;

  if (chandef->cbw == CHANNEL_BANDWIDTH_CBW20) {
    // 20Mhz always uses the default value.
    return PHY_VHT_CTRL_POS_1_BELOW;
  }

  // TODO(fxbug.dev/29830): move out the center freq calculation into a shared lib.

  if (36 <= primary && primary <= 64) {
    base = 36;
  } else if (100 <= primary && primary <= 128) {
    base = 100;
  } else if (132 <= primary && primary <= 144) {
    if (cbw == CHANNEL_BANDWIDTH_CBW160) {  // This group doesn't support 160MHz primary
                                            // channels. Use default value.
      return PHY_VHT_CTRL_POS_1_BELOW;
    }
    base = 132;
  } else if (149 <= primary && primary <= 161) {
    if (cbw == CHANNEL_BANDWIDTH_CBW160) {  // This group doesn't support 160MHz primary
                                            // channels. Use default value.
      return PHY_VHT_CTRL_POS_1_BELOW;
    }
    base = 149;
  } else {
    // 2.4GHz band or invalid channel index. Use default value.
    return PHY_VHT_CTRL_POS_1_BELOW;
  }

  uint8_t offset_to_base = primary - base;
  uint8_t mask;                          // used to mask the chan_index.
                                         // # of 1's means the bandwidth.
  bool has_bit2 = offset_to_base & 0x4;  // for HT40+/- checking
  switch (chandef->cbw) {
    case CHANNEL_BANDWIDTH_CBW40:  // The secondary channel is above the primary.
      mask = 0x7;                  // Keep 3 bits.
      if (has_bit2) {              // Channel 40, 48, 56 ... doesn't allow HT40+.
        return PHY_VHT_CTRL_POS_1_BELOW;
      }
      break;
    case CHANNEL_BANDWIDTH_CBW40BELOW:  // The secondary channel is below the primary.
      mask = 0x7;                       // Keep 3 bits.
      if (!has_bit2) {                  // Channel 36, 44, 52 ... doesn't allow HT40-.
        return PHY_VHT_CTRL_POS_1_BELOW;
      }
      break;
    case CHANNEL_BANDWIDTH_CBW80:
      mask = 0xf;  // Keep 4 bits.
      break;
    case CHANNEL_BANDWIDTH_CBW160:
      mask = 0x1f;  // Keep 5 bits.
      break;
    /*
     * The FW is expected to check the control channel position only
     * when in HT/VHT and the channel width is not 20MHz. Return
     * this value as the default one.
     */
    default:
      IWL_WARN(chandef, "Invalid channel bandwidth (primary=%u cbw=%u)\n", chandef->primary,
               chandef->cbw);
      return PHY_VHT_CTRL_POS_1_BELOW;
  }

  // Now, calculate offset from the primary channel index to the center.
  //
  // Take primary channel 48 @80MHz channel as example:
  //
  //            primary          | freq |           | mask=0xf |  half
  //            channel          |offset| chan num  | (CBW80)  |bandwidth=8 (40MHz)
  //  ==============================================================================
  //
  //   36  -------------------->     0    base           ^          ^
  //        base index                                   |          |
  //   40                           20    base + 4       |          |
  //                                      -------------- | -------- | <----------- center freq/index
  //   44                           40    base + 8       |     ^    v    | 10Mhz
  //                                                     |     |
  //   48  -------------------->    60    base + 12      |     v --- This is offset_to_center.
  //        offset_to_base = 12                          |
  //                                80                   v
  //
  // We can get:
  //
  //   offset_to_base = 48 - 36       # = 12 indexes
  //   mask = 0xf                     # 80MHz
  //   half_bandwidth = 8             # 40MHz
  //   center_index = 8 - 2 = 6       # 30MHz (offset to the base index)
  //   offset_to_center = 12 - 6 = 6  # 60MHz - 30MHz = +30MHz
  //
  uint8_t half_bandwith = (mask + 1) / 2;    // # of channel indexes within the half bandwidth.
  uint8_t center_index = half_bandwith - 2;  // 2 indexes = 2 * 5MHz = 10Mhz.
  int offset_to_center = (offset_to_base & mask) - center_index;

  const int mhz_per_index = 5;  // 5 MHz for each channel index.
  switch (offset_to_center * mhz_per_index) {
    case -70:
      return PHY_VHT_CTRL_POS_4_BELOW;
    case -50:
      return PHY_VHT_CTRL_POS_3_BELOW;
    case -30:
      return PHY_VHT_CTRL_POS_2_BELOW;
    case -10:
      return PHY_VHT_CTRL_POS_1_BELOW;
    case 10:
      return PHY_VHT_CTRL_POS_1_ABOVE;
    case 30:
      return PHY_VHT_CTRL_POS_2_ABOVE;
    case 50:
      return PHY_VHT_CTRL_POS_3_ABOVE;
    case 70:
      return PHY_VHT_CTRL_POS_4_ABOVE;
    default:
      IWL_WARN(chandef, "Invalid channel definition (primary=%u cbw=%u)\n", chandef->primary,
               chandef->cbw);
      return PHY_VHT_CTRL_POS_1_BELOW;
  }
}

/*
 * Construct the generic fields of the PHY context command
 */
static void iwl_mvm_phy_ctxt_cmd_hdr(struct iwl_mvm_phy_ctxt* ctxt, struct iwl_phy_context_cmd* cmd,
                                     uint32_t action, uint32_t apply_time) {
  memset(cmd, 0, sizeof(struct iwl_phy_context_cmd));

  cmd->id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(ctxt->id, ctxt->color));
  cmd->action = cpu_to_le32(action);
  cmd->apply_time = cpu_to_le32(apply_time);
}

/*
 * Add the phy configuration to the PHY context command
 */
static void iwl_mvm_phy_ctxt_cmd_data(struct iwl_mvm* mvm, struct iwl_phy_context_cmd* cmd,
                                      const wlan_channel_t* chandef, uint8_t chains_static,
                                      uint8_t chains_dynamic) {
  uint8_t active_cnt, idle_cnt;

  /* Set the channel info data */
  cmd->ci.band =
      iwl_mvm_get_channel_band(chandef->primary) == WLAN_INFO_BAND_2GHZ ? PHY_BAND_24 : PHY_BAND_5;

  cmd->ci.channel = chandef->primary;
  cmd->ci.width = iwl_mvm_get_channel_width(chandef);
  cmd->ci.ctrl_pos = iwl_mvm_get_ctrl_pos(chandef);

  /* Set rx the chains */
  idle_cnt = chains_static;
  active_cnt = chains_dynamic;

#if 0   // NEEDS_PORTING
  /* In scenarios where we only ever use a single-stream rates,
   * i.e. legacy 11b/g/a associations, single-stream APs or even
   * static SMPS, enable both chains to get diversity, improving
   * the case where we're far enough from the AP that attenuation
   * between the two antennas is sufficiently different to impact
   * performance.
   */
  if (active_cnt == 1 && iwl_mvm_rx_diversity_allowed(mvm)) {
    idle_cnt = 2;
    active_cnt = 2;
  }
#endif  // NEEDS_PORTING

  cmd->rxchain_info = cpu_to_le32(iwl_mvm_get_valid_rx_ant(mvm) << PHY_RX_CHAIN_VALID_POS);
  cmd->rxchain_info |= cpu_to_le32(idle_cnt << PHY_RX_CHAIN_CNT_POS);
  cmd->rxchain_info |= cpu_to_le32(active_cnt << PHY_RX_CHAIN_MIMO_CNT_POS);
#ifdef CPTCFG_IWLWIFI_DEBUGFS
  if (unlikely(mvm->dbgfs_rx_phyinfo)) {
    cmd->rxchain_info = cpu_to_le32(mvm->dbgfs_rx_phyinfo);
  }
#endif

  cmd->txchain_info = cpu_to_le32(iwl_mvm_get_valid_tx_ant(mvm));
}

/*
 * Send a command to apply the current phy configuration. The command is send
 * only if something in the configuration changed: in case that this is the
 * first time that the phy configuration is applied or in case that the phy
 * configuration changed from the previous apply.
 */
static zx_status_t iwl_mvm_phy_ctxt_apply(struct iwl_mvm* mvm, struct iwl_mvm_phy_ctxt* ctxt,
                                          const wlan_channel_t* chandef, uint8_t chains_static,
                                          uint8_t chains_dynamic, uint32_t action,
                                          uint32_t apply_time) {
  struct iwl_phy_context_cmd cmd;
  zx_status_t ret;

  /* Set the command header fields */
  iwl_mvm_phy_ctxt_cmd_hdr(ctxt, &cmd, action, apply_time);

  /* Set the command data */
  iwl_mvm_phy_ctxt_cmd_data(mvm, &cmd, chandef, chains_static, chains_dynamic);

  ret = iwl_mvm_send_cmd_pdu(mvm, PHY_CONTEXT_CMD, 0, sizeof(struct iwl_phy_context_cmd), &cmd);
  if (ret != ZX_OK) {
    IWL_ERR(mvm, "PHY ctxt cmd error. ret=%d\n", ret);
  }
  return ret;
}

/*
 * Send a command to add a PHY context based on the current HW configuration.
 */
zx_status_t iwl_mvm_phy_ctxt_add(struct iwl_mvm* mvm, struct iwl_mvm_phy_ctxt* ctxt,
                                 wlan_channel_t* chandef, uint8_t chains_static,
                                 uint8_t chains_dynamic) {
  WARN_ON(!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) && ctxt->ref);
  iwl_assert_lock_held(&mvm->mutex);

#ifdef CPTCFG_IWLWIFI_FRQ_MGR
  ctxt->fm_tx_power_limit = IWL_DEFAULT_MAX_TX_POWER;
#endif

  return iwl_mvm_phy_ctxt_apply(mvm, ctxt, chandef, chains_static, chains_dynamic,
                                FW_CTXT_ACTION_ADD, 0);
}

/*
 * Update the number of references to the given PHY context. This is valid only
 * in case the PHY context was already created, i.e., its reference count > 0.
 */
void iwl_mvm_phy_ctxt_ref(struct iwl_mvm* mvm, struct iwl_mvm_phy_ctxt* ctxt) {
  iwl_assert_lock_held(&mvm->mutex);
  ctxt->ref++;
}

/*
 * Send a command to modify the PHY context based on the current HW
 * configuration. Note that the function does not check that the configuration
 * changed.
 */
zx_status_t iwl_mvm_phy_ctxt_changed(struct iwl_mvm* mvm, struct iwl_mvm_phy_ctxt* ctxt,
                                     const wlan_channel_t* chandef, uint8_t chains_static,
                                     uint8_t chains_dynamic) {
  enum iwl_ctxt_action action = FW_CTXT_ACTION_MODIFY;

  iwl_assert_lock_held(&mvm->mutex);

  if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_BINDING_CDB_SUPPORT) &&
      iwl_mvm_get_channel_band(chandef->primary) !=
          iwl_mvm_get_channel_band(ctxt->chandef.primary)) {
    zx_status_t ret;

    /* ... remove it here ...*/
    ret = iwl_mvm_phy_ctxt_apply(mvm, ctxt, chandef, chains_static, chains_dynamic,
                                 FW_CTXT_ACTION_REMOVE, 0);
    if (ret != ZX_OK) {
      return ret;
    }

    /* ... and proceed to add it again */
    action = FW_CTXT_ACTION_ADD;
  }

  ctxt->chandef = *chandef;
  return iwl_mvm_phy_ctxt_apply(mvm, ctxt, chandef, chains_static, chains_dynamic, action, 0);
}

zx_status_t iwl_mvm_phy_ctxt_unref(struct iwl_mvm* mvm, struct iwl_mvm_phy_ctxt* ctxt) {
  iwl_assert_lock_held(&mvm->mutex);

  if (!ctxt) {
    return ZX_ERR_INVALID_ARGS;
  }

  if (ctxt->ref == 0) {
    return ZX_ERR_BAD_STATE;
  }

  ctxt->ref--;

  /*
   * Move unused phy's to a default channel. When the phy is moved the,
   * fw will cleanup immediate quiet bit if it was previously set,
   * otherwise we might not be able to reuse this phy.
   */
  if (ctxt->ref == 0) {
    // TODO(45353): support MIMO Rx.
    iwl_mvm_phy_ctxt_changed(mvm, ctxt, &default_channel, 1, 1);
  }

  return ZX_OK;
}

#if 0   // NEEDS_PORTING
static void iwl_mvm_binding_iterator(void* _data, uint8_t* mac, struct ieee80211_vif* vif) {
  unsigned long* data = _data;
  struct iwl_mvm_vif* mvmvif = iwl_mvm_vif_from_mac80211(vif);

  if (!mvmvif->phy_ctxt) {
    return;
  }

  if (vif->type == NL80211_IFTYPE_STATION || vif->type == NL80211_IFTYPE_AP) {
    __set_bit(mvmvif->phy_ctxt->id, data);
  }
}

int iwl_mvm_phy_ctx_count(struct iwl_mvm* mvm) {
  unsigned long phy_ctxt_counter = 0;

  ieee80211_iterate_active_interfaces_atomic(mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
                                             iwl_mvm_binding_iterator, &phy_ctxt_counter);

  return hweight8(phy_ctxt_counter);
}
#endif  // NEEDS_PORTING
