/* SPDX-License-Identifier: Apache-2.0
 * Copyright (c) 2023 Cisco Systems, Inc.
 */

#include <vnet/vnet.h>
#include <vnet/dev/dev.h>
#include <vnet/dev/pci.h>
#include <dev_ena/ena.h>
#include <dev_ena/ena_inlines.h>
#include <vnet/ethernet/ethernet.h>
#include <vnet/plugin/plugin.h>
#include <vpp/app/version.h>

static ena_aq_host_info_t host_info = {
  .os_type = 3, /* DPDK */
  .kernel_ver_str = VPP_BUILD_VER,
  .os_dist_str = VPP_BUILD_VER,
  .driver_version = {
    .major = 16,
    .minor = 0,
    .sub_minor = 0,
  },
  .ena_spec_version = {
    .major = 2,
    .minor = 0,
  },
  .driver_supported_features = {
    .rx_offset = 1,
    .rss_configurable_function_key = 1,
  }
};

VLIB_REGISTER_LOG_CLASS (ena_log, static) = {
  .class_name = "ena",
  .subclass_name = "init",
};

#define _(f, n, s, d)                                                         \
  { .name = #n, .desc = d, .severity = VL_COUNTER_SEVERITY_##s },

static vlib_error_desc_t ena_rx_node_counters[] = {
  foreach_ena_rx_node_counter
};
static vlib_error_desc_t ena_tx_node_counters[] = {
  foreach_ena_tx_node_counter
};
#undef _

vnet_dev_node_t ena_rx_node = {
  .error_counters = ena_rx_node_counters,
  .n_error_counters = ARRAY_LEN (ena_rx_node_counters),
  .format_trace = format_ena_rx_trace,
};

vnet_dev_node_t ena_tx_node = {
  .error_counters = ena_tx_node_counters,
  .n_error_counters = ARRAY_LEN (ena_tx_node_counters),
};

static void
ena_deinit (vlib_main_t *vm, vnet_dev_t *dev)
{
  ena_aenq_stop (vm, dev);
  ena_aq_stop (vm, dev);
}

static vnet_dev_rv_t
ena_alloc (vlib_main_t *vm, vnet_dev_t *dev)
{
  ena_device_t *ed = vnet_dev_get_data (dev);
  vnet_dev_rv_t rv;

  if ((rv = vnet_dev_dma_mem_alloc (vm, dev, 4096, 4096,
				    (void **) &ed->host_info)))
    return rv;

  if ((rv = vnet_dev_dma_mem_alloc (vm, dev, sizeof (ena_mmio_resp_t), 0,
				    (void **) &ed->mmio_resp)))
    return rv;

  if ((rv = ena_aq_olloc (vm, dev, ENA_ADMIN_QUEUE_DEPTH)))
    return rv;

  if ((rv = ena_aenq_olloc (vm, dev, ENA_ASYNC_QUEUE_DEPTH)))
    return rv;

  return VNET_DEV_OK;
}

static void
ena_free (vlib_main_t *vm, vnet_dev_t *dev)
{
  ena_device_t *ed = vnet_dev_get_data (dev);

  ena_aenq_free (vm, dev);
  ena_aq_free (vm, dev);

  vnet_dev_dma_mem_free (vm, dev, ed->host_info);
  vnet_dev_dma_mem_free (vm, dev, ed->mmio_resp);
}

static vnet_dev_rv_t
ena_init (vlib_main_t *vm, vnet_dev_t *dev)
{
  ena_device_t *ed = vnet_dev_get_data (dev);
  ena_aq_feat_host_attr_config_t host_attr = {};
  vlib_pci_config_hdr_t pci_cfg_hdr;
  vnet_dev_rv_t rv = VNET_DEV_OK;

  vnet_dev_port_add_args_t port = {
    .port = {
      .attr = {
        .type = VNET_DEV_PORT_TYPE_ETHERNET,
      },
      .ops = {
        .init = ena_port_init,
        .start = ena_port_start,
        .stop = ena_port_stop,
        .config_change = ena_port_cfg_change,
        .config_change_validate = ena_port_cfg_change_validate,
      },
      .data_size = sizeof (ena_port_t),
    },
    .rx_node = &ena_rx_node,
    .tx_node = &ena_tx_node,
    .rx_queue = {
      .config = {
        .data_size = sizeof (ena_rxq_t),
        .default_size = 512,
        .min_size = 32,
        .size_is_power_of_two = 1,
      },
      .ops = {
        .alloc = ena_rx_queue_alloc,
        .start = ena_rx_queue_start,
        .stop = ena_rx_queue_stop,
        .free = ena_rx_queue_free,
      },
    },
    .tx_queue = {
      .config = {
        .data_size = sizeof (ena_txq_t),
        .default_size = 512,
        .min_size = 32,
        .size_is_power_of_two = 1,
      },
      .ops = {
        .alloc = ena_tx_queue_alloc,
        .start = ena_tx_queue_start,
        .stop = ena_tx_queue_stop,
        .free = ena_tx_queue_free,
      },
    },
  };

  if ((rv = vnet_dev_pci_read_config_header (vm, dev, &pci_cfg_hdr)))
    goto err;

  log_debug (dev, "revision_id 0x%x", pci_cfg_hdr.revision_id);

  ed->readless = (pci_cfg_hdr.revision_id & 1) == 0;

  if ((rv = vnet_dev_pci_map_region (vm, dev, 0, &ed->reg_bar)))
    goto err;

  if ((rv = ena_reg_reset (vm, dev, ENA_RESET_REASON_NORMAL)))
    goto err;

  if ((rv = ena_aq_start (vm, dev)))
    goto err;

  *ed->host_info = host_info;
  ed->host_info->num_cpus = vlib_get_n_threads ();
  ena_set_mem_addr (vm, dev, &host_attr.os_info_ba, ed->host_info);

  if ((rv = ena_aq_set_feature (vm, dev, ENA_ADMIN_FEAT_ID_HOST_ATTR_CONFIG,
				&host_attr)))
    return rv;

  if ((rv = ena_aq_get_feature (vm, dev, ENA_ADMIN_FEAT_ID_DEVICE_ATTRIBUTES,
				&ed->dev_attr)))
    return rv;

  if (ena_aq_feature_is_supported (dev, ENA_ADMIN_FEAT_ID_MAX_QUEUES_EXT))
    {
      ena_aq_feat_max_queue_ext_t max_q_ext;
      if ((rv = ena_aq_get_feature (vm, dev, ENA_ADMIN_FEAT_ID_MAX_QUEUES_EXT,
				    &max_q_ext)))
	goto err;
      port.port.attr.max_rx_queues =
	clib_min (max_q_ext.max_rx_cq_num, max_q_ext.max_rx_sq_num);
      port.port.attr.max_tx_queues =
	clib_min (max_q_ext.max_tx_cq_num, max_q_ext.max_tx_sq_num);
      port.rx_queue.config.max_size =
	clib_min (max_q_ext.max_rx_cq_depth, max_q_ext.max_rx_sq_depth);
      port.tx_queue.config.max_size =
	clib_min (max_q_ext.max_tx_cq_depth, max_q_ext.max_tx_sq_depth);
    }
  else
    {
      log_err (dev, "device doesn't support MAX_QUEUES_EXT");
      return VNET_DEV_ERR_UNSUPPORTED_DEVICE_VER;
    }

  if ((rv = ena_aenq_start (vm, dev)))
    goto err;

  port.port.attr.max_supported_rx_frame_size = ed->dev_attr.max_mtu;

  if (ena_aq_feature_is_supported (dev, ENA_ADMIN_FEAT_ID_MTU))
    port.port.attr.caps.change_max_rx_frame_size = 1;

  vnet_dev_set_hw_addr_eth_mac (&port.port.attr.hw_addr,
				ed->dev_attr.mac_addr);

  return vnet_dev_port_add (vm, dev, 0, &port);

err:
  ena_free (vm, dev);
  return rv;
}

static u8 *
ena_probe (vlib_main_t *vm, vnet_dev_bus_index_t bus_index, void *dev_info)
{
  vnet_dev_bus_pci_device_info_t *di = dev_info;
  const struct
  {
    u16 device_id;
    char *description;
  } ena_dev_types[] = {
    { .device_id = 0x0ec2, .description = "Elastic Network Adapter (ENA) PF" },
    { .device_id = 0xec20, .description = "Elastic Network Adapter (ENA) VF" },
  };

  if (di->vendor_id != 0x1d0f) /* AMAZON */
    return 0;

  FOREACH_ARRAY_ELT (dt, ena_dev_types)
    {
      if (dt->device_id == di->device_id)
	return format (0, "%s", dt->description);
    }

  return 0;
}

VNET_DEV_REGISTER_DRIVER (ena) = {
  .name = "ena",
  .bus = "pci",
  .device_data_sz = sizeof (ena_device_t),
  .ops = {
    .alloc = ena_alloc,
    .init = ena_init,
    .deinit = ena_deinit,
    .free = ena_free,
    .format_info = format_ena_dev_info,
    .probe = ena_probe,
  },
};

VLIB_PLUGIN_REGISTER () = {
  .version = VPP_BUILD_VER,
  .description = "dev_ena",
};
