/*
 * SPDX-License-Identifier: Apache-2.0
 * Copyright (c) 2024 Tom Jones <thj@freebsd.org>
 *
 * This software was developed by Tom Jones <thj@freebsd.org> under sponsorship
 * from the FreeBSD Foundation.
 *
 */

#include <vlib/vlib.h>
#include <vlib/pci/pci.h>
#include <vlib/unix/unix.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/eventfd.h>

#include <sys/pciio.h>

#include <fcntl.h>
#include <dirent.h>
#include <net/if.h>

extern vlib_pci_main_t freebsd_pci_main;

uword
vlib_pci_get_private_data (vlib_main_t *vm, vlib_pci_dev_handle_t h)
{
  return 0;
}

void
vlib_pci_set_private_data (vlib_main_t *vm, vlib_pci_dev_handle_t h,
			   uword private_data)
{
}

vlib_pci_addr_t *
vlib_pci_get_addr (vlib_main_t *vm, vlib_pci_dev_handle_t h)
{
  return NULL;
}

u32
vlib_pci_get_numa_node (vlib_main_t *vm, vlib_pci_dev_handle_t h)
{
  return 0;
}

u32
vlib_pci_get_num_msix_interrupts (vlib_main_t *vm, vlib_pci_dev_handle_t h)
{
  return 0;
}

/* Call to allocate/initialize the pci subsystem.
   This is not an init function so that users can explicitly enable
   pci only when it's needed. */
clib_error_t *pci_bus_init (vlib_main_t *vm);

vlib_pci_device_info_t *
vlib_pci_get_device_info (vlib_main_t *vm, vlib_pci_addr_t *addr,
			  clib_error_t **error)
{
  /* Populate a vlib_pci_device_info_t from the given address */
  clib_error_t *err = NULL;
  vlib_pci_device_info_t *di = NULL;

  int fd = -1;
  struct pci_conf_io pci;
  struct pci_conf match;
  struct pci_match_conf pattern;
  bzero (&match, sizeof (match));
  bzero (&pattern, sizeof (pattern));

  pattern.pc_sel.pc_domain = addr->domain;
  pattern.pc_sel.pc_bus = addr->bus;
  pattern.pc_sel.pc_dev = addr->slot;
  pattern.pc_sel.pc_func = addr->function;
  pattern.flags = PCI_GETCONF_MATCH_DOMAIN | PCI_GETCONF_MATCH_BUS |
		  PCI_GETCONF_MATCH_DEV | PCI_GETCONF_MATCH_FUNC;

  pci.pat_buf_len = sizeof (pattern);
  pci.num_patterns = 1;
  pci.patterns = &pattern;
  pci.match_buf_len = sizeof (match);
  pci.num_matches = 1;
  pci.matches = &match;
  pci.offset = 0;
  pci.generation = 0;
  pci.status = 0;

  fd = open ("/dev/pci", 0);
  if (fd == -1)
    {
      err = clib_error_return_unix (0, "open '/dev/pci'");
      goto error;
    }

  if (ioctl (fd, PCIOCGETCONF, &pci) == -1)
    {
      err = clib_error_return_unix (0, "reading PCIOCGETCONF");
      goto error;
    }

  di = clib_mem_alloc (sizeof (vlib_pci_device_info_t));
  clib_memset (di, 0, sizeof (vlib_pci_device_info_t));

  di->addr.as_u32 = addr->as_u32;
  di->numa_node = 0; /* TODO: Place holder until we have NUMA on FreeBSD */

  di->device_class = match.pc_class;
  di->vendor_id = match.pc_vendor;
  di->device_id = match.pc_device;
  di->revision = match.pc_revid;

  di->product_name = NULL;
  di->vpd_r = 0;
  di->vpd_w = 0;
  di->driver_name = format (0, "%s", &match.pd_name);
  di->iommu_group = -1;

  goto done;

error:
  vlib_pci_free_device_info (di);
  di = NULL;
done:
  if (error)
    *error = err;
  close (fd);
  return di;
}

clib_error_t *__attribute__ ((weak))
vlib_pci_get_device_root_bus (vlib_pci_addr_t *addr, vlib_pci_addr_t *root_bus)
{
  return NULL;
}

clib_error_t *
vlib_pci_bind_to_uio (vlib_main_t *vm, vlib_pci_addr_t *addr,
		      char *uio_drv_name, int force)
{
  clib_error_t *error = 0;

  if (error)
    {
      return error;
    }

  if (strncmp ("auto", uio_drv_name, 5) == 0)
    {
      /* TODO: We should confirm that nic_uio is loaded and return an error. */
      uio_drv_name = "nic_uio";
    }
  return error;
}

clib_error_t *
vlib_pci_register_intx_handler (vlib_main_t *vm, vlib_pci_dev_handle_t h,
				pci_intx_handler_function_t *intx_handler)
{
  return NULL;
}

clib_error_t *
vlib_pci_unregister_intx_handler (vlib_main_t *vm, vlib_pci_dev_handle_t h)
{
  return NULL;
}

clib_error_t *
vlib_pci_register_msix_handler (vlib_main_t *vm, vlib_pci_dev_handle_t h,
				u32 start, u32 count,
				pci_msix_handler_function_t *msix_handler)
{
  return NULL;
}

clib_error_t *
vlib_pci_unregister_msix_handler (vlib_main_t *vm, vlib_pci_dev_handle_t h,
				  u32 start, u32 count)
{
  return NULL;
}

clib_error_t *
vlib_pci_enable_msix_irq (vlib_main_t *vm, vlib_pci_dev_handle_t h, u16 start,
			  u16 count)
{
  return NULL;
}

uword
vlib_pci_get_msix_file_index (vlib_main_t *vm, vlib_pci_dev_handle_t h,
			      u16 index)
{
  return 0;
}

clib_error_t *
vlib_pci_disable_msix_irq (vlib_main_t *vm, vlib_pci_dev_handle_t h, u16 start,
			   u16 count)
{
  return NULL;
}

/* Configuration space read/write. */
clib_error_t *
vlib_pci_read_write_config (vlib_main_t *vm, vlib_pci_dev_handle_t h,
			    vlib_read_or_write_t read_or_write, uword address,
			    void *data, u32 n_bytes)
{
  return NULL;
}

clib_error_t *
vlib_pci_map_region (vlib_main_t *vm, vlib_pci_dev_handle_t h, u32 resource,
		     void **result)
{
  return NULL;
}

clib_error_t *
vlib_pci_map_region_fixed (vlib_main_t *vm, vlib_pci_dev_handle_t h,
			   u32 resource, u8 *addr, void **result)
{
  return NULL;
}

clib_error_t *
vlib_pci_io_region (vlib_main_t *vm, vlib_pci_dev_handle_t h, u32 resource)
{
  return NULL;
}

clib_error_t *
vlib_pci_read_write_io (vlib_main_t *vm, vlib_pci_dev_handle_t h,
			vlib_read_or_write_t read_or_write, uword offset,
			void *data, u32 length)
{
  return NULL;
}

clib_error_t *
vlib_pci_map_dma (vlib_main_t *vm, vlib_pci_dev_handle_t h, void *ptr)
{
  return NULL;
}

int
vlib_pci_supports_virtual_addr_dma (vlib_main_t *vm, vlib_pci_dev_handle_t h)
{
  return 0;
}

clib_error_t *
vlib_pci_device_open (vlib_main_t *vm, vlib_pci_addr_t *addr,
		      pci_device_id_t ids[], vlib_pci_dev_handle_t *handle)
{
  return NULL;
}

void
vlib_pci_device_close (vlib_main_t *vm, vlib_pci_dev_handle_t h)
{
}

void
init_device_from_registered (vlib_main_t *vm, vlib_pci_device_info_t *di)
{
}

static int
pci_addr_cmp (void *v1, void *v2)
{
  vlib_pci_addr_t *a1 = v1;
  vlib_pci_addr_t *a2 = v2;

  if (a1->domain > a2->domain)
    return 1;
  if (a1->domain < a2->domain)
    return -1;
  if (a1->bus > a2->bus)
    return 1;
  if (a1->bus < a2->bus)
    return -1;
  if (a1->slot > a2->slot)
    return 1;
  if (a1->slot < a2->slot)
    return -1;
  if (a1->function > a2->function)
    return 1;
  if (a1->function < a2->function)
    return -1;
  return 0;
}

vlib_pci_addr_t *
vlib_pci_get_all_dev_addrs ()
{
  vlib_pci_addr_t *addrs = 0;

  int fd = -1;
  struct pci_conf_io pci;
  struct pci_conf matches[32];
  bzero (matches, sizeof (matches));

  pci.pat_buf_len = 0;
  pci.num_patterns = 0;
  pci.patterns = NULL;
  pci.match_buf_len = sizeof (matches);
  pci.num_matches = 32;
  pci.matches = (struct pci_conf *) &matches;
  pci.offset = 0;
  pci.generation = 0;
  pci.status = 0;

  fd = open ("/dev/pci", 0);
  if (fd == -1)
    {
      clib_error_return_unix (0, "opening /dev/pci");
      return (NULL);
    }

  if (ioctl (fd, PCIOCGETCONF, &pci) == -1)
    {
      clib_error_return_unix (0, "reading pci config");
      close (fd);
      return (NULL);
    }

  for (int i = 0; i < pci.num_matches; i++)
    {
      struct pci_conf *m = &pci.matches[i];
      vlib_pci_addr_t addr;

      addr.domain = m->pc_sel.pc_domain;
      addr.bus = m->pc_sel.pc_bus;
      addr.slot = m->pc_sel.pc_dev;
      addr.function = m->pc_sel.pc_func;

      vec_add1 (addrs, addr);
    }

  vec_sort_with_function (addrs, pci_addr_cmp);
  close (fd);

  return addrs;
}

clib_error_t *
freebsd_pci_init (vlib_main_t *vm)
{
  vlib_pci_main_t *pm = &pci_main;
  vlib_pci_addr_t *addr = 0, *addrs;

  pm->vlib_main = vm;

  ASSERT (sizeof (vlib_pci_addr_t) == sizeof (u32));

  addrs = vlib_pci_get_all_dev_addrs ();
  vec_foreach (addr, addrs)
    {
      vlib_pci_device_info_t *d;
      if ((d = vlib_pci_get_device_info (vm, addr, 0)))
	{
	  init_device_from_registered (vm, d);
	  vlib_pci_free_device_info (d);
	}
    }

  return 0;
}

VLIB_INIT_FUNCTION (freebsd_pci_init) = {
  .runs_after = VLIB_INITS ("unix_input_init"),
};
