/******************************************************************************
 *
 * Copyright(c) 2010 - 2014 Intel Corporation. All rights reserved.
 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
 * Copyright(c) 2016 - 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 "iwl-tm-gnl.h"

#include <net/genetlink.h>

#include <linux/export.h>

#include "iwl-csr.h"
#include "iwl-dnt-cfg.h"
#include "iwl-dnt-dispatch.h"
#include "iwl-drv.h"
#include "iwl-fh.h"
#include "iwl-io.h"
#include "iwl-op-mode.h"
#include "iwl-prph.h"
#include "iwl-tm-infc.h"
#include "iwl-trans.h"

/**
 * iwl_tm_validate_fw_cmd() - Validates FW host command input data
 * @data_in:    Input to be validated
 *
 */
static int iwl_tm_validate_fw_cmd(struct iwl_tm_data* data_in) {
  struct iwl_tm_cmd_request* cmd_req;
  uint32_t data_buf_size;

  if (!data_in->data || (data_in->len < sizeof(struct iwl_tm_cmd_request))) {
    return -EINVAL;
  }

  cmd_req = (struct iwl_tm_cmd_request*)data_in->data;

  data_buf_size = data_in->len - sizeof(struct iwl_tm_cmd_request);
  if (data_buf_size < cmd_req->len) {
    return -EINVAL;
  }

  return 0;
}

/**
 * iwl_tm_validate_reg_ops() - Checks the input data for registers operations
 * @data_in:    data is casted to iwl_tm_regs_request len in
 *      the size of the request struct in bytes.
 */
static int iwl_tm_validate_reg_ops(struct iwl_tm_data* data_in) {
  struct iwl_tm_regs_request* request;
  uint32_t request_size;
  uint32_t idx;

  if (!data_in->data || (data_in->len < sizeof(struct iwl_tm_regs_request))) {
    return -EINVAL;
  }

  request = (struct iwl_tm_regs_request*)(data_in->data);
  request_size = sizeof(struct iwl_tm_regs_request) + request->num * sizeof(struct iwl_tm_reg_op);
  if (data_in->len < request_size) {
    return -EINVAL;
  }

  /*
   * Calculate result size - result is returned only for read ops
   * Also, verifying inputs
   */
  for (idx = 0; idx < request->num; idx++) {
    if (request->reg_ops[idx].op_type >= IWL_TM_REG_OP_MAX) {
      return -EINVAL;
    }

    /*
     * Allow access only to FH/CSR/HBUS in direct mode.
     * Since we don't have the upper bounds for the CSR
     * and HBUS segments, we will use only the upper
     * bound of FH for sanity check.
     */
    if (!IS_AL_ADDR(request->reg_ops[idx].address)) {
      if (request->reg_ops[idx].address >= FH_MEM_UPPER_BOUND) {
        return -EINVAL;
      }
    }
  }

  return 0;
}

/**
 * iwl_tm_trace_end - Ends debug trace. Common for all op modes.
 * @dev: testmode device struct
 */
static int iwl_tm_trace_end(struct iwl_tm_gnl_dev* dev) {
  struct iwl_trans* trans = dev->trans;
  struct iwl_test_trace* trace = &dev->tst.trace;

  if (!trace->enabled) {
    return -EILSEQ;
  }

  if (trace->cpu_addr && trace->dma_addr) {
    dma_free_coherent(trans->dev, trace->size, trace->cpu_addr, trace->dma_addr);
  }
  memset(trace, 0, sizeof(struct iwl_test_trace));

  return 0;
}

/**
 * iwl_tm_trace_begin() - Checks input data for trace request
 * @dev:    testmode device struct
 * @data_in:    Only size is relevant - Desired size of trace buffer.
 * @data_out:   Trace request data (address & size)
 */
static int iwl_tm_trace_begin(struct iwl_tm_gnl_dev* dev, struct iwl_tm_data* data_in,
                              struct iwl_tm_data* data_out) {
  struct iwl_tm_trace_request* req = data_in->data;
  struct iwl_tm_trace_request* resp;

  if (!data_in->data || data_in->len < sizeof(struct iwl_tm_trace_request)) {
    return -EINVAL;
  }

  req = data_in->data;

  /* size zero means use the default */
  if (!req->size) {
    req->size = TRACE_BUFF_SIZE_DEF;
  } else if (req->size < TRACE_BUFF_SIZE_MIN || req->size > TRACE_BUFF_SIZE_MAX) {
    return -EINVAL;
  } else if (!dev->dnt->mon_buf_cpu_addr) {
    return -ENOMEM;
  }

  resp = kmalloc(sizeof(*resp), GFP_KERNEL);
  if (!resp) {
    return -ENOMEM;
  }
  resp->size = dev->dnt->mon_buf_size;
  /* Casting to avoid compilation warnings when DMA address is 32bit */
  resp->addr = (uint64_t)dev->dnt->mon_base_addr;

  data_out->data = resp;
  data_out->len = sizeof(*resp);

  return 0;
}

static bool iwl_tm_gnl_valid_hw_addr(uint32_t addr) {
  /* TODO need to implement */
  return true;
}

/**
 * iwl_tm_validate_sram_write_req() - Checks input data of SRAM write request
 * @dev:    testmode device struct
 * @data_in:    SRAM access request
 */
static int iwl_tm_validate_sram_write_req(struct iwl_tm_gnl_dev* dev, struct iwl_tm_data* data_in) {
  struct iwl_tm_sram_write_request* cmd_in;
  uint32_t data_buf_size;

  if (!dev->trans->op_mode) {
    IWL_ERR(dev->trans, "No op_mode!\n");
    return -ENODEV;
  }

  if (!data_in->data || data_in->len < sizeof(struct iwl_tm_sram_write_request)) {
    return -EINVAL;
  }

  cmd_in = data_in->data;

  data_buf_size = data_in->len - sizeof(struct iwl_tm_sram_write_request);
  if (data_buf_size < cmd_in->len) {
    return -EINVAL;
  }

  if (iwl_tm_gnl_valid_hw_addr(cmd_in->offset)) {
    return 0;
  }

  if ((cmd_in->offset < IWL_ABS_PRPH_START) && (cmd_in->offset >= IWL_ABS_PRPH_START + PRPH_END)) {
    return 0;
  }

  return -EINVAL;
}

/**
 * iwl_tm_validate_sram_read_req() - Checks input data of SRAM read request
 * @dev:    testmode device struct
 * @data_in:    SRAM access request
 */
static int iwl_tm_validate_sram_read_req(struct iwl_tm_gnl_dev* dev, struct iwl_tm_data* data_in) {
  struct iwl_tm_sram_read_request* cmd_in;

  if (!dev->trans->op_mode) {
    IWL_ERR(dev->trans, "No op_mode!\n");
    return -ENODEV;
  }

  if (!data_in->data || data_in->len < sizeof(struct iwl_tm_sram_read_request)) {
    return -EINVAL;
  }

  cmd_in = data_in->data;

  if (iwl_tm_gnl_valid_hw_addr(cmd_in->offset)) {
    return 0;
  }

  if ((cmd_in->offset < IWL_ABS_PRPH_START) && (cmd_in->offset >= IWL_ABS_PRPH_START + PRPH_END)) {
    return 0;
  }

  return -EINVAL;
}

/**
 * iwl_tm_notifications_en() - Checks input for enable test notifications
 * @tst:    Device's test data pointer
 * @data_in:    uint32_t notification (flag)
 */
static int iwl_tm_notifications_en(struct iwl_test* tst, struct iwl_tm_data* data_in) {
  uint32_t notification_en;

  if (!data_in->data || (data_in->len != sizeof(uint32_t))) {
    return -EINVAL;
  }

  notification_en = *(uint32_t*)data_in->data;
  if ((notification_en != NOTIFICATIONS_ENABLE) && (notification_en != NOTIFICATIONS_DISABLE)) {
    return -EINVAL;
  }

  tst->notify = notification_en == NOTIFICATIONS_ENABLE;

  return 0;
}

/**
 * iwl_tm_validate_tx_cmd() - Validates FW host command input data
 * @data_in:    Input to be validated
 *
 */
static int iwl_tm_validate_tx_cmd(struct iwl_tm_data* data_in) {
  struct iwl_tm_mod_tx_request* cmd_req;
  uint32_t data_buf_size;

  if (!data_in->data || (data_in->len < sizeof(struct iwl_tm_mod_tx_request))) {
    return -EINVAL;
  }

  cmd_req = (struct iwl_tm_mod_tx_request*)data_in->data;

  data_buf_size = data_in->len - sizeof(struct iwl_tm_mod_tx_request);
  if (data_buf_size < cmd_req->len) {
    return -EINVAL;
  }

  if (cmd_req->sta_id >= IWL_TM_STATION_COUNT) {
    return -EINVAL;
  }

  return 0;
}

/**
 * iwl_tm_validate_rx_hdrs_mode_req() - Validates RX headers mode request
 * @data_in:    Input to be validated
 *
 */
static int iwl_tm_validate_rx_hdrs_mode_req(struct iwl_tm_data* data_in) {
  if (!data_in->data || (data_in->len < sizeof(struct iwl_xvt_rx_hdrs_mode_request))) {
    return -EINVAL;
  }

  return 0;
}

static int iwl_tm_validate_get_chip_id(struct iwl_trans* trans) { return 0; }

/**
 * iwl_tm_validate_apmg_pd_mode_req() - Validates apmg rx mode request
 * @data_in:    Input to be validated
 *
 */
static int iwl_tm_validate_apmg_pd_mode_req(struct iwl_tm_data* data_in) {
  if (!data_in->data || (data_in->len != sizeof(struct iwl_xvt_apmg_pd_mode_request))) {
    return -EINVAL;
  }

  return 0;
}

static int iwl_tm_get_device_status(struct iwl_tm_gnl_dev* dev, struct iwl_tm_data* data_in,
                                    struct iwl_tm_data* data_out) {
  __u32* status;

  status = kmalloc(sizeof(__u32), GFP_KERNEL);
  if (!status) {
    return -ENOMEM;
  }

  *status = dev->dnt->iwl_dnt_status;

  data_out->data = status;
  data_out->len = sizeof(__u32);

  return 0;
}

#if IS_ENABLED(CPTCFG_IWLXVT)
static int iwl_tm_switch_op_mode(struct iwl_tm_gnl_dev* dev, struct iwl_tm_data* data_in) {
  struct iwl_switch_op_mode* switch_cmd = data_in->data;
  struct iwl_drv* drv;
  int ret = 0;

  if (data_in->len < sizeof(*switch_cmd)) {
    return -EINVAL;
  }

  drv = iwl_drv_get_dev_container(dev->trans->dev);
  if (!drv) {
    IWL_ERR(dev->trans, "Couldn't retrieve device information\n");
    return -ENODEV;
  }

  /* Executing switch command */
  ret = iwl_drv_switch_op_mode(drv, switch_cmd->new_op_mode);

  if (ret < 0)
    IWL_ERR(dev->trans, "Failed to switch op mode to %s (err:%d)\n", switch_cmd->new_op_mode, ret);

  return ret;
}
#endif

static int iwl_tm_gnl_get_sil_step(struct iwl_trans* trans, struct iwl_tm_data* data_out) {
  struct iwl_sil_step* resp;
  data_out->data = kmalloc(sizeof(struct iwl_sil_step), GFP_KERNEL);
  if (!data_out->data) {
    return -ENOMEM;
  }
  data_out->len = sizeof(struct iwl_sil_step);
  resp = (struct iwl_sil_step*)data_out->data;
  resp->silicon_step = CSR_HW_REV_STEP(trans->hw_rev);
  return 0;
}

static int iwl_tm_gnl_get_build_info(struct iwl_trans* trans, struct iwl_tm_data* data_out) {
  struct iwl_tm_build_info* resp;

  data_out->data = kmalloc(sizeof(*resp), GFP_KERNEL);
  if (!data_out->data) {
    return -ENOMEM;
  }
  data_out->len = sizeof(struct iwl_tm_build_info);
  resp = (struct iwl_tm_build_info*)data_out->data;

  memset(resp, 0, sizeof(*resp));
  strncpy(resp->driver_version, BACKPORTS_GIT_TRACKED, sizeof(resp->driver_version));
#ifdef BACKPORTS_BRANCH_TSTAMP
  strncpy(resp->branch_time, BACKPORTS_BRANCH_TSTAMP, sizeof(resp->branch_time));
#endif
  strncpy(resp->build_time, BACKPORTS_BUILD_TSTAMP, sizeof(resp->build_time));

  return 0;
}

static int iwl_tm_gnl_get_sil_type(struct iwl_trans* trans, struct iwl_tm_data* data_out) {
  struct iwl_tm_sil_type* resp;

  resp = kzalloc(sizeof(*resp), GFP_KERNEL);
  if (!resp) {
    return -ENOMEM;
  }

  resp->silicon_type = CSR_HW_REV_TYPE(trans->hw_rev);

  data_out->data = resp;
  data_out->len = sizeof(*resp);

  return 0;
}

static int iwl_tm_gnl_get_rfid(struct iwl_trans* trans, struct iwl_tm_data* data_out) {
  struct iwl_tm_rfid* resp;

  resp = kzalloc(sizeof(*resp), GFP_KERNEL);
  if (!resp) {
    return -ENOMEM;
  }

  IWL_DEBUG_INFO(trans, "HW RFID=0x08%X\n", trans->hw_rf_id);

  resp->flavor = CSR_HW_RFID_FLAVOR(trans->hw_rf_id);
  resp->dash = CSR_HW_RFID_DASH(trans->hw_rf_id);
  resp->step = CSR_HW_RFID_STEP(trans->hw_rf_id);
  resp->type = CSR_HW_RFID_TYPE(trans->hw_rf_id);

  data_out->data = resp;
  data_out->len = sizeof(*resp);

  return 0;
}

/*
 * Testmode GNL family types (This NL family
 * will eventually replace nl80211 support in
 * iwl xVM modules)
 */

#define IWL_TM_GNL_FAMILY_NAME "iwl_tm_gnl"
#define IWL_TM_GNL_MC_GRP_NAME "iwl_tm_mcgrp"
#define IWL_TM_GNL_VERSION_NR 1

#define IWL_TM_GNL_DEVNAME_LEN 256

/**
 * struct iwl_tm_gnl_cmd - Required data for command execution.
 * @dev_name:   Target device
 * @cmd:    Command index
 * @data_in:    Input data
 * @data_out:   Output data, to be sent when
 *      command is done.
 */
struct iwl_tm_gnl_cmd {
  const char* dev_name;
  uint32_t cmd;
  struct iwl_tm_data data_in;
  struct iwl_tm_data data_out;
};

static struct list_head dev_list; /* protected by mutex or RCU */
static struct mutex dev_list_mtx;

/* Testmode GNL family command attributes  */
enum iwl_tm_gnl_cmd_attr_t {
  IWL_TM_GNL_MSG_ATTR_INVALID = 0,
  IWL_TM_GNL_MSG_ATTR_DEVNAME,
  IWL_TM_GNL_MSG_ATTR_CMD,
  IWL_TM_GNL_MSG_ATTR_DATA,
  IWL_TM_GNL_MSG_ATTR_MAX
};

/* TM GNL family definition */
static struct genl_family iwl_tm_gnl_family;
static __genl_const struct genl_multicast_group iwl_tm_gnl_mcgrps[] = {
    {
        .name = IWL_TM_GNL_MC_GRP_NAME,
    },
};

/* TM GNL bus policy */
static const struct nla_policy iwl_tm_gnl_msg_policy[IWL_TM_GNL_MSG_ATTR_MAX] = {
    [IWL_TM_GNL_MSG_ATTR_DEVNAME] = {.type = NLA_NUL_STRING, .len = IWL_TM_GNL_DEVNAME_LEN - 1},
    [IWL_TM_GNL_MSG_ATTR_CMD] =
        {
            .type = NLA_U32,
        },
    [IWL_TM_GNL_MSG_ATTR_DATA] =
        {
            .type = NLA_BINARY,
        },
};

/**
 * iwl_tm_gnl_get_dev() - Retrieve device information
 * @dev_name:   Device to be found
 *
 * Finds the device information according to device name,
 * must be protected by list mutex when used (mutex is not
 * locked inside the function to allow code flexibility)
 */
static struct iwl_tm_gnl_dev* iwl_tm_gnl_get_dev(const char* dev_name) {
  struct iwl_tm_gnl_dev *dev_itr, *dev = NULL;

  iwl_assert_lock_held(&dev_list_mtx);

  list_for_each_entry(dev_itr, &dev_list, list) {
    if (!strcmp(dev_itr->dev_name, dev_name)) {
      dev = dev_itr;
      break;
    }
  }

  return dev;
}

/**
 * iwl_tm_gnl_create_message() - Creates a genl message
 * @pid:    Netlink PID that the message is addressed to
 * @seq:    sequence number (usually the one of the sender)
 * @cmd_data:   Message's data
 * @flags:  Resources allocation flags
 */
static struct sk_buff* iwl_tm_gnl_create_msg(uint32_t pid, uint32_t seq,
                                             struct iwl_tm_gnl_cmd cmd_data, gfp_t flags) {
  void* nlmsg_head;
  struct sk_buff* skb;
  int ret;

  skb = genlmsg_new(NLMSG_GOODSIZE, flags);
  if (!skb) {
    goto send_msg_err;
  }

  nlmsg_head = genlmsg_put(skb, pid, seq, &iwl_tm_gnl_family, 0, IWL_TM_GNL_CMD_EXECUTE);
  if (!nlmsg_head) {
    goto send_msg_err;
  }

  ret = nla_put_string(skb, IWL_TM_GNL_MSG_ATTR_DEVNAME, cmd_data.dev_name);
  if (ret) {
    goto send_msg_err;
  }

  ret = nla_put_u32(skb, IWL_TM_GNL_MSG_ATTR_CMD, cmd_data.cmd);
  if (ret) {
    goto send_msg_err;
  }

  if (cmd_data.data_out.len && cmd_data.data_out.data) {
    ret = nla_put(skb, IWL_TM_GNL_MSG_ATTR_DATA, cmd_data.data_out.len, cmd_data.data_out.data);
    if (ret) {
      goto send_msg_err;
    }
  }

  genlmsg_end(skb, nlmsg_head);

  return skb;

send_msg_err:
  if (skb) {
    kfree_skb(skb);
  }

  return NULL;
}

/**
 * iwl_tm_gnl_send_msg() - Sends a message to mcast or userspace listener
 * @trans:  transport
 * @cmd:    Command index
 * @check_notify: only send when notify is set
 * @data_out:   Data to be sent
 *
 * Initiate a message sending to user space (as apposed
 * to replying to a message that was initiated by user
 * space). Uses multicast broadcasting method.
 */
int iwl_tm_gnl_send_msg(struct iwl_trans* trans, uint32_t cmd, bool check_notify, void* data_out,
                        uint32_t data_len, gfp_t flags) {
  struct iwl_tm_gnl_dev* dev;
  struct iwl_tm_gnl_cmd cmd_data;
  struct sk_buff* skb;
  uint32_t nlportid;

  if (WARN_ON_ONCE(!trans)) {
    return -EINVAL;
  }

  if (!trans->tmdev) {
    return 0;
  }
  dev = trans->tmdev;

  nlportid = READ_ONCE(dev->nl_events_portid);

  if (check_notify && !dev->tst.notify) {
    return 0;
  }

  memset(&cmd_data, 0, sizeof(struct iwl_tm_gnl_cmd));
  cmd_data.dev_name = dev_name(trans->dev);
  cmd_data.cmd = cmd;
  cmd_data.data_out.data = data_out;
  cmd_data.data_out.len = data_len;

  skb = iwl_tm_gnl_create_msg(nlportid, 0, cmd_data, flags);
  if (!skb) {
    return -EINVAL;
  }

  if (nlportid) {
    return genlmsg_unicast(&init_net, skb, nlportid);
  }
  return genlmsg_multicast(&iwl_tm_gnl_family, skb, 0, 0, flags);
}
IWL_EXPORT_SYMBOL(iwl_tm_gnl_send_msg);

/**
 * iwl_tm_gnl_reply() - Sends command's results back to user space
 * @info:   info struct received in .doit callback
 * @cmd_data:   Data of command to be responded
 */
static int iwl_tm_gnl_reply(struct genl_info* info, struct iwl_tm_gnl_cmd cmd_data) {
  struct sk_buff* skb;

  skb = iwl_tm_gnl_create_msg(genl_info_snd_portid(info), info->snd_seq, cmd_data, GFP_KERNEL);
  if (!skb) {
    return -EINVAL;
  }

  return genlmsg_reply(skb, info);
}

/**
 * iwl_tm_gnl_cmd_execute() - Execute IWL testmode GNL command
 * @cmd_data:   Pointer to the data of command to be executed
 */
static int iwl_tm_gnl_cmd_execute(struct iwl_tm_gnl_cmd* cmd_data) {
  struct iwl_tm_gnl_dev* dev;
  bool common_op = false;
  int ret = 0;
  mutex_lock(&dev_list_mtx);
  dev = iwl_tm_gnl_get_dev(cmd_data->dev_name);
  mutex_unlock(&dev_list_mtx);
  if (!dev) {
    return -ENODEV;
  }

  IWL_DEBUG_INFO(dev->trans, "%s cmd=0x%X\n", __func__, cmd_data->cmd);
  switch (cmd_data->cmd) {
    case IWL_TM_USER_CMD_HCMD:
      ret = iwl_tm_validate_fw_cmd(&cmd_data->data_in);
      break;

    case IWL_TM_USER_CMD_REG_ACCESS:
      ret = iwl_tm_validate_reg_ops(&cmd_data->data_in);
      break;

    case IWL_TM_USER_CMD_SRAM_WRITE:
      ret = iwl_tm_validate_sram_write_req(dev, &cmd_data->data_in);
      break;

    case IWL_TM_USER_CMD_BEGIN_TRACE:
      ret = iwl_tm_trace_begin(dev, &cmd_data->data_in, &cmd_data->data_out);
      common_op = true;
      break;

    case IWL_TM_USER_CMD_END_TRACE:
      ret = iwl_tm_trace_end(dev);
      common_op = true;
      break;

    case IWL_XVT_CMD_MOD_TX:
      ret = iwl_tm_validate_tx_cmd(&cmd_data->data_in);
      break;

    case IWL_XVT_CMD_RX_HDRS_MODE:
      ret = iwl_tm_validate_rx_hdrs_mode_req(&cmd_data->data_in);
      break;

    case IWL_XVT_CMD_APMG_PD_MODE:
      ret = iwl_tm_validate_apmg_pd_mode_req(&cmd_data->data_in);
      break;

    case IWL_TM_USER_CMD_NOTIFICATIONS:
      ret = iwl_tm_notifications_en(&dev->tst, &cmd_data->data_in);
      common_op = true;
      break;

    case IWL_TM_USER_CMD_GET_DEVICE_STATUS:
      ret = iwl_tm_get_device_status(dev, &cmd_data->data_in, &cmd_data->data_out);
      common_op = true;
      break;
#if IS_ENABLED(CPTCFG_IWLXVT)
    case IWL_TM_USER_CMD_SWITCH_OP_MODE:
      ret = iwl_tm_switch_op_mode(dev, &cmd_data->data_in);
      common_op = true;
      break;
#endif
    case IWL_XVT_CMD_GET_CHIP_ID:
      ret = iwl_tm_validate_get_chip_id(dev->trans);
      break;

    case IWL_TM_USER_CMD_GET_SIL_STEP:
      ret = iwl_tm_gnl_get_sil_step(dev->trans, &cmd_data->data_out);
      common_op = true;
      break;

    case IWL_TM_USER_CMD_GET_DRIVER_BUILD_INFO:
      ret = iwl_tm_gnl_get_build_info(dev->trans, &cmd_data->data_out);
      common_op = true;
      break;

    case IWL_TM_USER_CMD_GET_SIL_TYPE:
      ret = iwl_tm_gnl_get_sil_type(dev->trans, &cmd_data->data_out);
      common_op = true;
      break;

    case IWL_TM_USER_CMD_GET_RFID:
      ret = iwl_tm_gnl_get_rfid(dev->trans, &cmd_data->data_out);
      common_op = true;
      break;
  }
  if (ret) {
    IWL_ERR(dev->trans, "%s Error=%d\n", __func__, ret);
    return ret;
  }

  if (!common_op)
    ret = iwl_tm_execute_cmd(&dev->trans->testmode, cmd_data->cmd, &cmd_data->data_in,
                             &cmd_data->data_out);

  if (ret) {
    IWL_ERR(dev->trans, "%s ret=%d\n", __func__, ret);
  } else {
    IWL_DEBUG_INFO(dev->trans, "%s ended Ok\n", __func__);
  }
  return ret;
}

/**
 * iwl_tm_mem_dump() - Returns memory buffer data
 * @dev:    testmode device struct
 * @data_in:    input data
 * @data_out:   Dump data
 */
static int iwl_tm_mem_dump(struct iwl_tm_gnl_dev* dev, struct iwl_tm_data* data_in,
                           struct iwl_tm_data* data_out) {
  int ret;

  ret = iwl_tm_validate_sram_read_req(dev, data_in);
  if (ret) {
    return ret;
  }

  return iwl_tm_execute_cmd(&dev->trans->testmode, IWL_TM_USER_CMD_SRAM_READ, data_in, data_out);
}

/**
 * iwl_tm_trace_dump() - Returns trace buffer data
 * @tst:    Device's test data
 * @data_out:   Dump data
 */
static int iwl_tm_trace_dump(struct iwl_tm_gnl_dev* dev, struct iwl_tm_data* data_out) {
  int ret;
  uint32_t buf_size;

  if (!(dev->dnt->iwl_dnt_status & IWL_DNT_STATUS_MON_CONFIGURED)) {
    IWL_ERR(dev->trans, "Invalid monitor status\n");
    return -EINVAL;
  }

  if (dev->dnt->mon_buf_size == 0) {
    IWL_ERR(dev->trans, "No available monitor buffer\n");
    return -ENOMEM;
  }

  buf_size = dev->dnt->mon_buf_size;
  data_out->data = kmalloc(buf_size, GFP_KERNEL);
  if (!data_out->data) {
    return -ENOMEM;
  }

  ret = iwl_dnt_dispatch_pull(dev->trans, data_out->data, buf_size, MONITOR);
  if (ret < 0) {
    kfree(data_out->data);
    return ret;
  }
  data_out->len = ret;

  return 0;
}

/**
 * iwl_tm_gnl_command_dump() - Returns dump buffer data
 * @cmd_data:   Pointer to the data of dump command.
 *      Only device name and command index are the relevant input.
 *      Data out is the start address of the buffer, and it's size.
 */
static int iwl_tm_gnl_command_dump(struct iwl_tm_gnl_cmd* cmd_data) {
  struct iwl_tm_gnl_dev* dev;
  int ret = 0;

  mutex_lock(&dev_list_mtx);
  dev = iwl_tm_gnl_get_dev(cmd_data->dev_name);
  mutex_unlock(&dev_list_mtx);
  if (!dev) {
    return -ENODEV;
  }

  switch (cmd_data->cmd) {
    case IWL_TM_USER_CMD_TRACE_DUMP:
      ret = iwl_tm_trace_dump(dev, &cmd_data->data_out);
      break;

    case IWL_TM_USER_CMD_SRAM_READ:
      ret = iwl_tm_mem_dump(dev, &cmd_data->data_in, &cmd_data->data_out);
      break;

    default:
      return -EOPNOTSUPP;
  }

  return ret;
}

/**
 * iwl_tm_gnl_parse_msg - Extract input cmd data out of netlink attributes
 * @attrs:  Input netlink attributes
 * @cmd_data:   Command
 */
static int iwl_tm_gnl_parse_msg(struct nlattr** attrs, struct iwl_tm_gnl_cmd* cmd_data) {
  memset(cmd_data, 0, sizeof(struct iwl_tm_gnl_cmd));

  if (!attrs[IWL_TM_GNL_MSG_ATTR_DEVNAME] || !attrs[IWL_TM_GNL_MSG_ATTR_CMD]) {
    return -EINVAL;
  }

  cmd_data->dev_name = nla_data(attrs[IWL_TM_GNL_MSG_ATTR_DEVNAME]);
  cmd_data->cmd = nla_get_u32(attrs[IWL_TM_GNL_MSG_ATTR_CMD]);

  if (attrs[IWL_TM_GNL_MSG_ATTR_DATA]) {
    cmd_data->data_in.data = nla_data(attrs[IWL_TM_GNL_MSG_ATTR_DATA]);
    cmd_data->data_in.len = nla_len(attrs[IWL_TM_GNL_MSG_ATTR_DATA]);
  }

  return 0;
}

/**
 * iwl_tm_gnl_cmd_do() - Executes IWL testmode GNL command
 */
static int iwl_tm_gnl_cmd_do(struct sk_buff* skb, struct genl_info* info) {
  struct iwl_tm_gnl_cmd cmd_data;
  int ret;

  ret = iwl_tm_gnl_parse_msg(info->attrs, &cmd_data);
  if (ret) {
    return ret;
  }

  ret = iwl_tm_gnl_cmd_execute(&cmd_data);
  if (!ret && cmd_data.data_out.len) {
    ret = iwl_tm_gnl_reply(info, cmd_data);
    /*
     * In this case, data out should be allocated in
     * iwl_tm_gnl_cmd_execute so it should be freed
     * here
     */
    kfree(cmd_data.data_out.data);
  }

  return ret;
}

/**
 * iwl_tm_gnl_dump() - Executes IWL testmode GNL command
 * cb->args[0]: Command number, incremented by one (as it may be zero)
 *      We're keeping the command so we can tell if is it the
 *      first dump call or not.
 * cb->args[1]: Buffer data to dump
 * cb->args[2]: Buffer size
 * cb->args[3]: Buffer offset from where to dump in the next round
 */
static int iwl_tm_gnl_dump(struct sk_buff* skb, struct netlink_callback* cb) {
  struct iwl_tm_gnl_cmd cmd_data;
  void* nlmsg_head = NULL;
  struct nlattr* attrs[IWL_TM_GNL_MSG_ATTR_MAX];
  void* dump_addr;
  unsigned long dump_offset;
  int dump_size, chunk_size, ret;

  if (!cb->args[0]) {
    /*
     * This is the first part of the dump - Parse dump data
     * out of the data in the netlink header and set up the
     * dump in cb->args[].
     */
    ret = nlmsg_parse(cb->nlh, GENL_HDRLEN, attrs, IWL_TM_GNL_MSG_ATTR_MAX - 1,
                      iwl_tm_gnl_msg_policy, NULL);
    if (ret) {
      return ret;
    }

    ret = iwl_tm_gnl_parse_msg(attrs, &cmd_data);
    if (ret) {
      return ret;
    }

    ret = iwl_tm_gnl_command_dump(&cmd_data);
    if (ret) {
      return ret;
    }

    /* Incrementing command since command number may be zero */
    cb->args[0] = cmd_data.cmd + 1;
    cb->args[1] = (unsigned long)cmd_data.data_out.data;
    cb->args[2] = cmd_data.data_out.len;
    cb->args[3] = 0;

    if (!cb->args[2]) {
      return -ENODATA;
    }
  }

  dump_addr = (uint8_t*)cb->args[1];
  dump_size = cb->args[2];
  dump_offset = cb->args[3];

  nlmsg_head = genlmsg_put(skb, NETLINK_CB_PORTID(cb->skb), cb->nlh->nlmsg_seq, &iwl_tm_gnl_family,
                           NLM_F_MULTI, IWL_TM_GNL_CMD_EXECUTE);

  /*
   * Reserve some room for NL attribute header,
   * 16 bytes should be enough.
   */
  chunk_size = skb_tailroom(skb) - 16;
  if (chunk_size <= 0) {
    ret = -ENOMEM;
    goto dump_err;
  }

  if (chunk_size > dump_size - dump_offset) {
    chunk_size = dump_size - dump_offset;
  }

  if (chunk_size) {
    ret = nla_put(skb, IWL_TM_GNL_MSG_ATTR_DATA, chunk_size, dump_addr + dump_offset);
    if (ret) {
      goto dump_err;
    }
  }

  genlmsg_end(skb, nlmsg_head);

  /* move offset */
  cb->args[3] += chunk_size;

  return cb->args[2] - cb->args[3];

dump_err:
  genlmsg_cancel(skb, nlmsg_head);
  return ret;
}

static int iwl_tm_gnl_done(struct netlink_callback* cb) {
  switch (cb->args[0] - 1) {
    case IWL_TM_USER_CMD_SRAM_READ:
    case IWL_TM_USER_CMD_TRACE_DUMP:
      kfree((void*)cb->args[1]);
      return 0;
  }

  return -EOPNOTSUPP;
}

static int iwl_tm_gnl_cmd_subscribe(struct sk_buff* skb, struct genl_info* info) {
  struct iwl_tm_gnl_dev* dev;
  const char* dev_name;
  int ret;

  if (!info->attrs[IWL_TM_GNL_MSG_ATTR_DEVNAME]) {
    return -EINVAL;
  }

  dev_name = nla_data(info->attrs[IWL_TM_GNL_MSG_ATTR_DEVNAME]);

  mutex_lock(&dev_list_mtx);
  dev = iwl_tm_gnl_get_dev(dev_name);
  if (!dev) {
    ret = -ENODEV;
    goto unlock;
  }

  if (dev->nl_events_portid) {
    ret = -EBUSY;
    goto unlock;
  }

  dev->nl_events_portid = genl_info_snd_portid(info);
  ret = 0;

unlock:
  mutex_unlock(&dev_list_mtx);
  return ret;
}

/*
 * iwl_tm_gnl_ops - GNL Family commands.
 * There is only one NL command, and only one callback,
 * which handles all NL messages.
 */
static __genl_const struct genl_ops iwl_tm_gnl_ops[] = {
    {
        .cmd = IWL_TM_GNL_CMD_EXECUTE,
        .policy = iwl_tm_gnl_msg_policy,
        .doit = iwl_tm_gnl_cmd_do,
        .dumpit = iwl_tm_gnl_dump,
        .done = iwl_tm_gnl_done,
    },
    {
        .cmd = IWL_TM_GNL_CMD_SUBSCRIBE_EVENTS,
        .policy = iwl_tm_gnl_msg_policy,
        .doit = iwl_tm_gnl_cmd_subscribe,
    },
};

static struct genl_family iwl_tm_gnl_family __genl_ro_after_init = {
    .hdrsize = 0,
    .name = IWL_TM_GNL_FAMILY_NAME,
    .version = IWL_TM_GNL_VERSION_NR,
    .maxattr = IWL_TM_GNL_MSG_ATTR_MAX,
    .module = THIS_MODULE,
    .ops = iwl_tm_gnl_ops,
    .n_ops = ARRAY_SIZE(iwl_tm_gnl_ops),
    .mcgrps = iwl_tm_gnl_mcgrps,
    .n_mcgrps = ARRAY_SIZE(iwl_tm_gnl_mcgrps),
};

/**
 * iwl_tm_gnl_add() - Registers a devices/op-mode in the iwl-tm-gnl list
 * @trans:  transport struct for the device to register for
 */
void iwl_tm_gnl_add(struct iwl_trans* trans) {
  struct iwl_tm_gnl_dev* dev;

  if (!trans) {
    return;
  }

  if (trans->tmdev) {
    return;
  }

  mutex_lock(&dev_list_mtx);

  if (iwl_tm_gnl_get_dev(dev_name(trans->dev))) {
    goto unlock;
  }

  dev = kzalloc(sizeof(*dev), GFP_KERNEL);
  if (!dev) {
    goto unlock;
  }

  dev->dev_name = dev_name(trans->dev);
  trans->tmdev = dev;
  dev->trans = trans;
  list_add_tail_rcu(&dev->list, &dev_list);

unlock:
  mutex_unlock(&dev_list_mtx);
}

/**
 * iwl_tm_gnl_remove() - Unregisters a devices/op-mode in the iwl-tm-gnl list
 * @trans:  transport struct for the device
 */
void iwl_tm_gnl_remove(struct iwl_trans* trans) {
  struct iwl_tm_gnl_dev *dev_itr, *tmp;

  if (WARN_ON_ONCE(!trans)) {
    return;
  }

  /* Searching for operation mode in list */
  mutex_lock(&dev_list_mtx);
  list_for_each_entry_safe(dev_itr, tmp, &dev_list, list) {
    if (dev_itr->trans == trans) {
      /*
       * Device found. Removing it from list
       * and releasing it's resources
       */
      list_del_rcu(&dev_itr->list);
      synchronize_rcu();
      kfree(dev_itr);
      break;
    }
  }

  trans->tmdev = NULL;
  mutex_unlock(&dev_list_mtx);
}

static int iwl_tm_gnl_netlink_notify(struct notifier_block* nb, unsigned long state,
                                     void* _notify) {
  struct netlink_notify* notify = _notify;
  struct iwl_tm_gnl_dev* dev;

  rcu_read_lock();
  list_for_each_entry_rcu(dev, &dev_list, list) {
    if (dev->nl_events_portid == netlink_notify_portid(notify)) {
      dev->nl_events_portid = 0;
    }
  }
  rcu_read_unlock();

  return NOTIFY_OK;
}

static struct notifier_block iwl_tm_gnl_netlink_notifier = {
    .notifier_call = iwl_tm_gnl_netlink_notify,
};

/**
 * iwl_tm_gnl_init() - Registers tm-gnl module
 *
 * Registers Testmode GNL family and initializes
 * TM GNL global variables
 */
int iwl_tm_gnl_init(void) {
  int ret;

  INIT_LIST_HEAD(&dev_list);
  mutex_init(&dev_list_mtx);

  ret = genl_register_family(&iwl_tm_gnl_family);
  if (ret) {
    return ret;
  }
  ret = netlink_register_notifier(&iwl_tm_gnl_netlink_notifier);
  if (ret) {
    genl_unregister_family(&iwl_tm_gnl_family);
  }
  return ret;
}

/**
 * iwl_tm_gnl_exit() - Unregisters Testmode GNL family
 */
int iwl_tm_gnl_exit(void) {
  netlink_unregister_notifier(&iwl_tm_gnl_netlink_notifier);
  return genl_unregister_family(&iwl_tm_gnl_family);
}

/**
 * iwl_tm_fw_send_rx() - Send a spontaneous rx message to user
 * @trans:  Pointer to the transport layer
 * @rxb:    Contains rx packet to be sent
 */
void iwl_tm_gnl_send_rx(struct iwl_trans* trans, struct iwl_rx_cmd_buffer* rxb) {
  struct iwl_rx_packet* pkt = rxb_addr(rxb);
  int length = iwl_rx_packet_len(pkt);

  /* the length doesn't include len_n_flags field, so add it manually */
  length += sizeof(__le32);

  iwl_tm_gnl_send_msg(trans, IWL_TM_USER_CMD_NOTIF_UCODE_RX_PKT, true, (void*)pkt, length,
                      GFP_ATOMIC);
}
IWL_EXPORT_SYMBOL(iwl_tm_gnl_send_rx);
