/******************************************************************************
 *
 * 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 "iwl-dbg-tlv.h"

#include <linux/firmware.h>

#include "iwl-trans.h"

void iwl_fw_dbg_copy_tlv(struct iwl_trans* trans, struct iwl_ucode_tlv* tlv, bool ext) {
  struct iwl_apply_point_data* data;
  struct iwl_fw_ini_header* header = (void*)&tlv->data[0];
  uint32_t apply_point = le32_to_cpu(header->apply_point);

  int copy_size = le32_to_cpu(tlv->length) + sizeof(*tlv);

  if (WARN_ONCE(apply_point >= IWL_FW_INI_APPLY_NUM, "Invalid apply point id %d\n", apply_point)) {
    return;
  }

  if (ext) {
    data = &trans->apply_points_ext[apply_point];
  } else {
    data = &trans->apply_points[apply_point];
  }

  /*
   * Make sure we still have room to copy this TLV. Offset points to the
   * location the last copy ended.
   */
  if (WARN_ONCE(data->offset + copy_size > data->size, "Not enough memory for apply point %d\n",
                apply_point)) {
    return;
  }

  memcpy(data->data + data->offset, (void*)tlv, copy_size);
  data->offset += copy_size;
}

void iwl_alloc_dbg_tlv(struct iwl_trans* trans, size_t len, const uint8_t* data, bool ext) {
  struct iwl_ucode_tlv* tlv;
  uint32_t size[IWL_FW_INI_APPLY_NUM] = {0};
  int i;

  while (len >= sizeof(*tlv)) {
    uint32_t tlv_len, tlv_type, apply;
    struct iwl_fw_ini_header* hdr;

    len -= sizeof(*tlv);
    tlv = (void*)data;

    tlv_len = le32_to_cpu(tlv->length);
    tlv_type = le32_to_cpu(tlv->type);

    if (len < tlv_len) {
      return;
    }

    len -= ALIGN(tlv_len, 4);
    data += sizeof(*tlv) + ALIGN(tlv_len, 4);

    if (!(tlv_type & IWL_UCODE_INI_TLV_GROUP)) {
      continue;
    }

    hdr = (void*)&tlv->data[0];
    apply = le32_to_cpu(hdr->apply_point);

    IWL_DEBUG_FW(trans, "Read TLV %x, apply point %d\n", le32_to_cpu(tlv->type), apply);

    if (WARN_ON(apply >= IWL_FW_INI_APPLY_NUM)) {
      continue;
    }

    size[apply] += sizeof(*tlv) + tlv_len;
  }

  for (i = 0; i < ARRAY_SIZE(size); i++) {
    void* mem;

    if (!size[i]) {
      continue;
    }

    mem = kzalloc(size[i], GFP_KERNEL);

    if (!mem) {
      IWL_ERR(trans, "No memory for apply point %d\n", i);
      return;
    }

    if (ext) {
      trans->apply_points_ext[i].data = mem;
      trans->apply_points_ext[i].size = size[i];
    } else {
      trans->apply_points[i].data = mem;
      trans->apply_points[i].size = size[i];
    }

    trans->ini_valid = true;
  }
}

void iwl_fw_dbg_free(struct iwl_trans* trans) {
  int i;

  for (i = 0; i < ARRAY_SIZE(trans->apply_points); i++) {
    kfree(trans->apply_points[i].data);
    trans->apply_points[i].size = 0;
    trans->apply_points[i].offset = 0;

    kfree(trans->apply_points_ext[i].data);
    trans->apply_points_ext[i].size = 0;
    trans->apply_points_ext[i].offset = 0;
  }
}

static int iwl_parse_fw_dbg_tlv(struct iwl_trans* trans, const uint8_t* data, size_t len) {
  struct iwl_ucode_tlv* tlv;
  enum iwl_ucode_tlv_type tlv_type;
  uint32_t tlv_len;

  while (len >= sizeof(*tlv)) {
    len -= sizeof(*tlv);
    tlv = (void*)data;

    tlv_len = le32_to_cpu(tlv->length);
    tlv_type = le32_to_cpu(tlv->type);

    if (len < tlv_len) {
      IWL_ERR(trans, "invalid TLV len: %zd/%u\n", len, tlv_len);
      return -EINVAL;
    }
    len -= ALIGN(tlv_len, 4);
    data += sizeof(*tlv) + ALIGN(tlv_len, 4);

    switch (tlv_type) {
      case IWL_UCODE_TLV_TYPE_BUFFER_ALLOCATION:
      case IWL_UCODE_TLV_TYPE_HCMD:
      case IWL_UCODE_TLV_TYPE_REGIONS:
      case IWL_UCODE_TLV_TYPE_TRIGGERS:
      case IWL_UCODE_TLV_TYPE_DEBUG_FLOW:
        iwl_fw_dbg_copy_tlv(trans, tlv, true);
      default:
        WARN_ONCE(1, "Invalid TLV %x\n", tlv_type);
        break;
    }
  }

  return 0;
}

void iwl_load_fw_dbg_tlv(struct device* dev, struct iwl_trans* trans) {
  const struct firmware* fw;
  int res;

  if (trans->external_ini_loaded || !iwlwifi_mod_params.enable_ini) {
    return;
  }

  res = request_firmware(&fw, "iwl-dbg-tlv.ini", dev);
  if (res) {
    return;
  }

  iwl_alloc_dbg_tlv(trans, fw->size, fw->data, true);
  iwl_parse_fw_dbg_tlv(trans, fw->data, fw->size);

  trans->external_ini_loaded = true;
  release_firmware(fw);
}
