// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/iwlwifi/test/sim-mvm.h"

extern "C" {
#include "src/iwlwifi/fw/api/commands.h"
#include "src/iwlwifi/fw/api/datapath.h"
#include "src/iwlwifi/fw/api/sta.h"
}  // extern "C"

#include "src/iwlwifi/test/inspect-host-cmd.h"

namespace wlan {
namespace testing {

static void build_response_with_status(SimMvmResponse* resp, uint32_t status) {
  // Check 'struct iwl_rx_packet'. The 'len_n_flags' includes the 'iwl_cmd_header' size and
  // its payload, which is 'iwl_cmd_response'.
  resp->resize(sizeof(struct iwl_cmd_header) + sizeof(struct iwl_cmd_response));

  struct iwl_cmd_response* cmd_resp = reinterpret_cast<struct iwl_cmd_response*>(resp->data());
  cmd_resp->status = cpu_to_le32(status);
}

zx_status_t SimMvm::SendCmd(struct iwl_host_cmd* cmd, bool* notify_wait) {
  INSPECT_HOST_CMD(cmd);
  uint8_t opcode = iwl_cmd_opcode(cmd->id);
  uint8_t group_id = iwl_cmd_groupid(cmd->id);
  SimMvmResponse resp;  // Used by command functions to return packet.
  zx_status_t ret;

  *notify_wait = false;
  switch (group_id) {
    case LONG_GROUP:
      switch (opcode) {  // enum iwl_legacy_cmds
        // No state change for the following commands.

        // On real hardware, this command will reply a pakcet to unblock the driver waiting.
        // In the simulated code, we don't generate the packet. Instead, we unblock it directly.
        case PHY_CONFIGURATION_CMD:
          // passthru

        // The driver code expects 2 notifications from the firmware in this command:
        //
        //   1. In iwl_mvm_time_event_send_add(), it waits for the notification of the completion of
        //      TIME_EVENT_CMD command.
        //   2. In iwl_mvm_protect_session(), it waits for the TIME_EVENT_NOTIFICATION.
        //
        // However, the current sim-mvm code can only unblock the first wait. So added
        // TODO(fxbug.dev/51671) to track this.
        case TIME_EVENT_CMD:
          // passthru

          // The above commands require unblock the notification.
          *notify_wait = true;
          __FALLTHROUGH;
        case SHARED_MEM_CFG:
        case TX_ANT_CONFIGURATION_CMD:
        case PHY_DB_CMD:
        case PHY_CONTEXT_CMD:
        case REPLY_THERMAL_MNG_BACKOFF:
        case POWER_TABLE_CMD:
        case BT_CONFIG:
        case MAC_CONTEXT_CMD:
        case TXPATH_FLUSH:
        case SCAN_OFFLOAD_REQUEST_CMD:
        case SCAN_CFG_CMD:
        case SCAN_REQ_UMAC:
        case MAC_PM_POWER_TABLE:
        case SCD_QUEUE_CFG:
        case FW_PAGING_BLOCK_CMD:
        case TIME_QUOTA_CMD:
        case MCAST_FILTER_CMD:
        case REPLY_BEACON_FILTERING_CMD:
          return ZX_OK;

        // Command would return 'status' back to driver.
        case BINDING_CONTEXT_CMD:
          build_response_with_status(&resp, 0);
          ret = ZX_OK;
          break;

        case ADD_STA:  // fall-thru
        case REMOVE_STA:
        case ADD_STA_KEY:
          build_response_with_status(&resp, ADD_STA_SUCCESS);
          ret = ZX_OK;
          break;

        case NVM_ACCESS_CMD:
          ret = nvm_.HandleCommand(cmd, &resp);
          break;

        default:
          IWL_ERR(nullptr, "unsupported long command ID : %#x\n", cmd->id);
          INSPECT_HOST_CMD(cmd);
          return ZX_ERR_NOT_SUPPORTED;
      }
      break;

    case DATA_PATH_GROUP:
      switch (opcode) {  // enum iwl_data_path_subcmd_ids
        case DQA_ENABLE_CMD:
          ret = ZX_OK;
          break;

        default:
          IWL_ERR(nullptr, "unsupported data path command ID : %#x\n", cmd->id);
          INSPECT_HOST_CMD(cmd);
          return ZX_ERR_NOT_SUPPORTED;
      }
      break;

    default:
      IWL_ERR(nullptr, "unsupported command ID : %#x\n", cmd->id);
      INSPECT_HOST_CMD(cmd);
      return ZX_ERR_NOT_SUPPORTED;
  }

  // Prepare the response packet buffer if the command requires a response.
  struct iwl_rx_packet* resp_pkt = reinterpret_cast<struct iwl_rx_packet*>(resp_buf_.data());
  ZX_ASSERT(sizeof(*resp_pkt) + resp.size() <= resp_buf_.size());  // avoid overflow
  if (cmd->flags & CMD_WANT_SKB) {
    resp_pkt->len_n_flags = cpu_to_le32(resp.size());
    resp_pkt->hdr.cmd = opcode;
    resp_pkt->hdr.group_id = group_id;
    resp_pkt->hdr.sequence = 0;
    memcpy(resp_pkt->data, resp.data(), resp.size());
    cmd->resp_pkt = resp_pkt;
  } else {
    cmd->resp_pkt = nullptr;
  }

  return ret;
}

}  // namespace testing
}  // namespace wlan
