/******************************************************************************
 *
 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
 * Copyright(c) 2016 Intel Deutschland GmbH
 * 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 <string.h>
#include <zircon/types.h>

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

struct iwl_mvm_iface_iterator_data {
  struct iwl_mvm_vif* ignore_vif;
  int idx;

  struct iwl_mvm_phy_ctxt* phyctxt;

  uint16_t ids[MAX_MACS_IN_BINDING];
  uint16_t colors[MAX_MACS_IN_BINDING];
};

static zx_status_t iwl_mvm_binding_cmd(struct iwl_mvm* mvm, uint32_t action,
                                       struct iwl_mvm_iface_iterator_data* data) {
  struct iwl_binding_cmd cmd;
  struct iwl_mvm_phy_ctxt* phyctxt = data->phyctxt;
  int i;
  int size;

  memset(&cmd, 0, sizeof(cmd));

  if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_BINDING_CDB_SUPPORT)) {
    size = sizeof(cmd);
    if (iwl_mvm_get_channel_band(phyctxt->chandef.primary) == WLAN_INFO_BAND_2GHZ ||
        !iwl_mvm_is_cdb_supported(mvm)) {
      cmd.lmac_id = cpu_to_le32(IWL_LMAC_24G_INDEX);
    } else {
      cmd.lmac_id = cpu_to_le32(IWL_LMAC_5G_INDEX);
    }
  } else {
    size = IWL_BINDING_CMD_SIZE_V1;
  }

  cmd.id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(phyctxt->id, phyctxt->color));
  cmd.action = cpu_to_le32(action);
  cmd.phy = cpu_to_le32(FW_CMD_ID_AND_COLOR(phyctxt->id, phyctxt->color));

  for (i = 0; i < MAX_MACS_IN_BINDING; i++) {
    cmd.macs[i] = cpu_to_le32(FW_CTXT_INVALID);
  }
  for (i = 0; i < data->idx; i++) {
    cmd.macs[i] = cpu_to_le32(FW_CMD_ID_AND_COLOR(data->ids[i], data->colors[i]));
  }

  uint32_t status = 0;
  zx_status_t ret = iwl_mvm_send_cmd_pdu_status(mvm, BINDING_CONTEXT_CMD, size, &cmd, &status);
  if (ret != ZX_OK) {
    IWL_ERR(mvm, "Failed to send binding (action:%d): %d\n", action, ret);
    return ret;
  }

  if (status) {
    IWL_ERR(mvm, "Binding command failed: %u\n", status);
    ret = ZX_ERR_IO;
  }

  return ret;
}

static void iwl_mvm_iface_iterator(void* _data, struct iwl_mvm_vif* mvmvif) {
  struct iwl_mvm_iface_iterator_data* data = _data;

  if (mvmvif == data->ignore_vif) {
    return;
  }

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

  if (WARN_ON_ONCE(data->idx >= MAX_MACS_IN_BINDING)) {
    return;
  }

  data->ids[data->idx] = mvmvif->id;
  data->colors[data->idx] = mvmvif->color;
  data->idx++;
}

static zx_status_t iwl_mvm_binding_update(struct iwl_mvm_vif* mvmvif,
                                          struct iwl_mvm_phy_ctxt* phyctxt, bool add) {
  struct iwl_mvm_iface_iterator_data data = {
      .ignore_vif = mvmvif,
      .phyctxt = phyctxt,
  };
  uint32_t action = FW_CTXT_ACTION_MODIFY;

  iwl_assert_lock_held(&mvmvif->mvm->mutex);

  ieee80211_iterate_active_interfaces_atomic(mvmvif->mvm, iwl_mvm_iface_iterator, &data);

  /*
   * If there are no other interfaces yet we
   * need to create a new binding.
   */
  if (data.idx == 0) {
    if (add) {
      action = FW_CTXT_ACTION_ADD;
    } else {
      action = FW_CTXT_ACTION_REMOVE;
    }
  }

  if (add) {
    if (data.idx >= MAX_MACS_IN_BINDING) {
      IWL_WARN(mvmvif, "cannot add. reached max # of binding: %d >= %d\n", data.idx,
               MAX_MACS_IN_BINDING);
      return ZX_ERR_OUT_OF_RANGE;
    }

    data.ids[data.idx] = mvmvif->id;
    data.colors[data.idx] = mvmvif->color;
    data.idx++;
  }

  return iwl_mvm_binding_cmd(mvmvif->mvm, action, &data);
}

zx_status_t iwl_mvm_binding_add_vif(struct iwl_mvm_vif* mvmvif) {
  if (!mvmvif->phy_ctxt) {
    IWL_ERR(mvmvif, "%s(): mvmvif->phy_ctxt is NULL\n", __func__);
    return ZX_ERR_BAD_STATE;
  }

#if 0   // NEEDS_PORTING
  /*
   * Update SF - Disable if needed. if this fails, SF might still be on
   * while many macs are bound, which is forbidden - so fail the binding.
   */
  if (iwl_mvm_sf_update(mvm, vif, false)) {
    return -EINVAL;
  }
#endif  // NEEDS_PORTING

  return iwl_mvm_binding_update(mvmvif, mvmvif->phy_ctxt, true);
}

zx_status_t iwl_mvm_binding_remove_vif(struct iwl_mvm_vif* mvmvif) {
  if (!mvmvif->phy_ctxt) {
    IWL_ERR(mvmvif, "phy_ctxt cannot be null\n");
    return ZX_ERR_INVALID_ARGS;
  }

  zx_status_t ret = iwl_mvm_binding_update(mvmvif, mvmvif->phy_ctxt, false);

#if 0   // NEEDS_PORTING
  if (ret != ZX_OK)
    if (iwl_mvm_sf_update(mvm, vif, true)) {
      IWL_ERR(mvm, "Failed to update SF state\n");
    }
#endif  // NEEDS_PORTING

  return ret;
}
