/******************************************************************************
 *
 * 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 "internal.h"
#include "iwl-context-info.h"
#include "iwl-fh.h"
#include "iwl-prph.h"
#include "iwl-trans.h"

void iwl_pcie_ctxt_info_free_paging(struct iwl_trans* trans) {
  struct iwl_trans_pcie* trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
  struct iwl_self_init_dram* dram = &trans_pcie->init_dram;
  int i;

  if (!dram->paging) {
    WARN_ON(dram->paging_cnt);
    return;
  }

  /* free paging*/
  for (i = 0; i < dram->paging_cnt; i++)
    dma_free_coherent(trans->dev, dram->paging[i].size, dram->paging[i].block,
                      dram->paging[i].physical);

  kfree(dram->paging);
  dram->paging_cnt = 0;
  dram->paging = NULL;
}

int iwl_pcie_init_fw_sec(struct iwl_trans* trans, const struct fw_img* fw,
                         struct iwl_context_info_dram* ctxt_dram) {
  struct iwl_trans_pcie* trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
  struct iwl_self_init_dram* dram = &trans_pcie->init_dram;
  int i, ret, lmac_cnt, umac_cnt, paging_cnt;

  if (WARN(dram->paging, "paging shouldn't already be initialized (%d pages)\n",
           dram->paging_cnt)) {
    iwl_pcie_ctxt_info_free_paging(trans);
  }

  lmac_cnt = iwl_pcie_get_num_sections(fw, 0);
  /* add 1 due to separator */
  umac_cnt = iwl_pcie_get_num_sections(fw, lmac_cnt + 1);
  /* add 2 due to separators */
  paging_cnt = iwl_pcie_get_num_sections(fw, lmac_cnt + umac_cnt + 2);

  dram->fw = kcalloc(umac_cnt + lmac_cnt, sizeof(*dram->fw), GFP_KERNEL);
  if (!dram->fw) {
    return -ENOMEM;
  }
  dram->paging = kcalloc(paging_cnt, sizeof(*dram->paging), GFP_KERNEL);
  if (!dram->paging) {
    return -ENOMEM;
  }

  /* initialize lmac sections */
  for (i = 0; i < lmac_cnt; i++) {
    ret = iwl_pcie_ctxt_info_alloc_dma(trans, &fw->sec[i], &dram->fw[dram->fw_cnt]);
    if (ret) {
      return ret;
    }
    ctxt_dram->lmac_img[i] = cpu_to_le64(dram->fw[dram->fw_cnt].physical);
    dram->fw_cnt++;
  }

  /* initialize umac sections */
  for (i = 0; i < umac_cnt; i++) {
    /* access FW with +1 to make up for lmac separator */
    ret = iwl_pcie_ctxt_info_alloc_dma(trans, &fw->sec[dram->fw_cnt + 1], &dram->fw[dram->fw_cnt]);
    if (ret) {
      return ret;
    }
    ctxt_dram->umac_img[i] = cpu_to_le64(dram->fw[dram->fw_cnt].physical);
    dram->fw_cnt++;
  }

  /*
   * Initialize paging.
   * Paging memory isn't stored in dram->fw as the umac and lmac - it is
   * stored separately.
   * This is since the timing of its release is different -
   * while fw memory can be released on alive, the paging memory can be
   * freed only when the device goes down.
   * Given that, the logic here in accessing the fw image is a bit
   * different - fw_cnt isn't changing so loop counter is added to it.
   */
  for (i = 0; i < paging_cnt; i++) {
    /* access FW with +2 to make up for lmac & umac separators */
    int fw_idx = dram->fw_cnt + i + 2;

    ret = iwl_pcie_ctxt_info_alloc_dma(trans, &fw->sec[fw_idx], &dram->paging[i]);
    if (ret) {
      return ret;
    }

    ctxt_dram->virtual_img[i] = cpu_to_le64(dram->paging[i].physical);
    dram->paging_cnt++;
  }

  return 0;
}

int iwl_pcie_ctxt_info_init(struct iwl_trans* trans, const struct fw_img* fw) {
  struct iwl_trans_pcie* trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
  struct iwl_context_info* ctxt_info;
  struct iwl_context_info_rbd_cfg* rx_cfg;
  uint32_t control_flags = 0, rb_size;
  int ret;

  ctxt_info = dma_alloc_coherent(trans->dev, sizeof(*ctxt_info), &trans_pcie->ctxt_info_dma_addr,
                                 GFP_KERNEL);
  if (!ctxt_info) {
    return -ENOMEM;
  }

  ctxt_info->version.version = 0;
  ctxt_info->version.mac_id = cpu_to_le16((uint16_t)iwl_read32(trans, CSR_HW_REV));
  /* size is in DWs */
  ctxt_info->version.size = cpu_to_le16(sizeof(*ctxt_info) / 4);

  switch (trans_pcie->rx_buf_size) {
    case IWL_AMSDU_2K:
      rb_size = IWL_CTXT_INFO_RB_SIZE_2K;
      break;
    case IWL_AMSDU_4K:
      rb_size = IWL_CTXT_INFO_RB_SIZE_4K;
      break;
    case IWL_AMSDU_8K:
      rb_size = IWL_CTXT_INFO_RB_SIZE_8K;
      break;
    case IWL_AMSDU_12K:
      rb_size = IWL_CTXT_INFO_RB_SIZE_12K;
      break;
    default:
      WARN_ON(1);
      rb_size = IWL_CTXT_INFO_RB_SIZE_4K;
  }

  BUILD_BUG_ON(RX_QUEUE_CB_SIZE(MQ_RX_TABLE_SIZE) > 0xF);
  control_flags = IWL_CTXT_INFO_TFD_FORMAT_LONG |
                  (RX_QUEUE_CB_SIZE(MQ_RX_TABLE_SIZE) << IWL_CTXT_INFO_RB_CB_SIZE_POS) |
                  (rb_size << IWL_CTXT_INFO_RB_SIZE_POS);
  ctxt_info->control.control_flags = cpu_to_le32(control_flags);

  /* initialize RX default queue */
  rx_cfg = &ctxt_info->rbd_cfg;
  rx_cfg->free_rbd_addr = cpu_to_le64(trans_pcie->rxq->bd_dma);
  rx_cfg->used_rbd_addr = cpu_to_le64(trans_pcie->rxq->used_bd_dma);
  rx_cfg->status_wr_ptr = cpu_to_le64(trans_pcie->rxq->rb_stts_dma);

  /* initialize TX command queue */
  ctxt_info->hcmd_cfg.cmd_queue_addr =
      cpu_to_le64(trans_pcie->txq[trans_pcie->cmd_queue]->dma_addr);
  ctxt_info->hcmd_cfg.cmd_queue_size = TFD_QUEUE_CB_SIZE(TFD_CMD_SLOTS);

  /* allocate ucode sections in dram and set addresses */
  ret = iwl_pcie_init_fw_sec(trans, fw, &ctxt_info->dram);
  if (ret) {
    dma_free_coherent(trans->dev, sizeof(*trans_pcie->ctxt_info), ctxt_info,
                      trans_pcie->ctxt_info_dma_addr);
    return ret;
  }

  trans_pcie->ctxt_info = ctxt_info;

  iwl_enable_interrupts(trans);

  /* Configure debug, if exists */
  if (iwl_pcie_dbg_on(trans)) {
    iwl_pcie_apply_destination(trans);
  }

  /* kick FW self load */
  iwl_write64(trans, CSR_CTXT_INFO_BA, trans_pcie->ctxt_info_dma_addr);
  iwl_write_prph(trans, UREG_CPU_INIT_RUN, 1);

  /* Context info will be released upon alive or failure to get one */

  return 0;
}

void iwl_pcie_ctxt_info_free(struct iwl_trans* trans) {
  struct iwl_trans_pcie* trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);

  if (!trans_pcie->ctxt_info) {
    return;
  }

  dma_free_coherent(trans->dev, sizeof(*trans_pcie->ctxt_info), trans_pcie->ctxt_info,
                    trans_pcie->ctxt_info_dma_addr);
  trans_pcie->ctxt_info_dma_addr = 0;
  trans_pcie->ctxt_info = NULL;

  iwl_pcie_ctxt_info_free_fw_img(trans);
}
