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

#include "vppinfra/pool.h"
#include <vnet/vnet.h>
#include <vnet/ethernet/ethernet.h>
#include <vnet/dev/dev.h>
#include <vnet/dev/log.h>
#include <vnet/dev/counters.h>

VLIB_REGISTER_LOG_CLASS (dev_log, static) = {
  .class_name = "dev",
};

vnet_dev_main_t vnet_dev_main = { .next_rx_queue_thread = 1 };

vnet_dev_bus_t *
vnet_dev_find_device_bus (vlib_main_t *vm, vnet_dev_device_id_t id)
{
  vnet_dev_main_t *dm = &vnet_dev_main;
  vnet_dev_bus_t *bus;

  pool_foreach (bus, dm->buses)
    {
      int n = strlen (bus->registration->name);
      int l = strlen (id);
      int dl = strlen (VNET_DEV_DEVICE_ID_PREFIX_DELIMITER);

      if (l <= n + dl)
	continue;

      if (strncmp (bus->registration->name, id, n))
	continue;

      if (strncmp (VNET_DEV_DEVICE_ID_PREFIX_DELIMITER, id + n, dl))
	continue;

      return bus;
    }

  return 0;
}

void *
vnet_dev_get_device_info (vlib_main_t *vm, vnet_dev_device_id_t id)
{
  vnet_dev_bus_t *bus;

  bus = vnet_dev_find_device_bus (vm, id);
  if (bus == 0)
    return 0;

  return bus->ops.get_device_info (vm, id);
}

vnet_dev_t *
vnet_dev_alloc (vlib_main_t *vm, vnet_dev_device_id_t id,
		vnet_dev_driver_t *driver)
{
  vnet_dev_main_t *dm = &vnet_dev_main;
  vnet_dev_t *dev = 0, **devp = 0;

  dev = vnet_dev_alloc_with_data (sizeof (vnet_dev_t),
				  driver->registration->device_data_sz);

  pool_get (dm->devices, devp);
  devp[0] = dev;
  dev->index = devp - dm->devices;
  dev->driver_index = driver->index;
  dev->ops = driver->registration->ops;
  dev->bus_index = driver->bus_index;
  clib_memcpy (dev->device_id, id, sizeof (dev->device_id));
  hash_set (dm->device_index_by_id, dev->device_id, dev->index);

  if ((vnet_dev_process_create (vm, dev)) == VNET_DEV_OK)
    return dev;

  vnet_dev_free (vm, dev);
  return 0;
}

vnet_dev_rv_t
vnet_dev_init (vlib_main_t *vm, vnet_dev_t *dev)
{
  vnet_dev_main_t *dm = &vnet_dev_main;
  vnet_dev_bus_t *bus = pool_elt_at_index (dm->buses, dev->bus_index);
  vnet_dev_rv_t rv;

  vnet_dev_validate (vm, dev);

  if ((rv = bus->ops.device_open (vm, dev)) != VNET_DEV_OK)
    return rv;

  if ((rv = dev->ops.alloc (vm, dev)) != VNET_DEV_OK)
    {
      log_err (dev, "device init failed [rv %d]", rv);
      if (dev->ops.deinit)
	dev->ops.deinit (vm, dev);
      if (dev->ops.free)
	dev->ops.free (vm, dev);
      return rv;
    }

  if ((rv = dev->ops.init (vm, dev)) != VNET_DEV_OK)
    {
      log_err (dev, "device init failed [rv %d]", rv);
      if (dev->ops.deinit)
	dev->ops.deinit (vm, dev);
      if (dev->ops.free)
	dev->ops.free (vm, dev);
      return rv;
    }

  dev->initialized = 1;
  dev->not_first_init = 1;
  return VNET_DEV_OK;
}

void
vnet_dev_deinit (vlib_main_t *vm, vnet_dev_t *dev)
{
  ASSERT (dev->initialized == 1);
  vnet_dev_bus_t *bus;

  vnet_dev_validate (vm, dev);

  foreach_vnet_dev_port (p, dev)
    ASSERT (p->interface_created == 0);

  if (dev->ops.deinit)
    dev->ops.deinit (vm, dev);

  bus = vnet_dev_get_bus (dev);
  if (bus->ops.device_close)
    bus->ops.device_close (vm, dev);

  vnet_dev_process_quit (vm, dev);

  dev->initialized = 0;
}

void
vnet_dev_free (vlib_main_t *vm, vnet_dev_t *dev)
{
  vnet_dev_main_t *dm = &vnet_dev_main;

  vnet_dev_validate (vm, dev);

  ASSERT (dev->initialized == 0);

  foreach_vnet_dev_port (p, dev)
    vnet_dev_port_free (vm, p);

  vec_free (dev->description);
  pool_free (dev->ports);
  pool_free (dev->periodic_ops);
  hash_unset (dm->device_index_by_id, dev->device_id);
  pool_put_index (dm->devices, dev->index);
}

vnet_dev_rv_t
vnet_dev_reset (vlib_main_t *vm, vnet_dev_t *dev)
{
  vnet_dev_rv_t rv;

  ASSERT (dev->initialized == 1);
  vnet_dev_validate (vm, dev);

  if (dev->ops.reset == 0)
    return VNET_DEV_ERR_NOT_SUPPORTED;

  if ((rv = dev->ops.reset (vm, dev)) != VNET_DEV_OK)
    {
      log_err (dev, "device reset failed [rv %d]", rv);
      return rv;
    }

  return VNET_DEV_OK;
}

void
vnet_dev_detach (vlib_main_t *vm, vnet_dev_t *dev)
{
  foreach_vnet_dev_port (p, dev)
    if (p->interface_created)
      vnet_dev_port_if_remove (vm, p);
  vnet_dev_deinit (vm, dev);
  vnet_dev_free (vm, dev);
}

vnet_dev_rv_t
vnet_dev_dma_mem_alloc (vlib_main_t *vm, vnet_dev_t *dev, u32 size, u32 align,
			void **pp)
{
  vnet_dev_main_t *dm = &vnet_dev_main;
  vnet_dev_bus_t *bus = pool_elt_at_index (dm->buses, dev->bus_index);
  vnet_dev_rv_t rv;

  vnet_dev_validate (vm, dev);

  if (!bus->ops.dma_mem_alloc_fn)
    return VNET_DEV_ERR_NOT_SUPPORTED;

  rv = bus->ops.dma_mem_alloc_fn (vm, dev, size, align, pp);
  if (rv == VNET_DEV_OK)
    log_debug (dev, "%u bytes va %p dma-addr 0x%lx numa %u align %u", size,
	       *pp, vnet_dev_get_dma_addr (vm, dev, *pp), dev->numa_node,
	       align);
  return rv;
}

void
vnet_dev_dma_mem_free (vlib_main_t *vm, vnet_dev_t *dev, void *p)
{
  vnet_dev_main_t *dm = &vnet_dev_main;
  vnet_dev_bus_t *bus = pool_elt_at_index (dm->buses, dev->bus_index);

  vnet_dev_validate (vm, dev);

  if (p == 0 || !bus->ops.dma_mem_free_fn)
    return;

  return bus->ops.dma_mem_free_fn (vm, dev, p);
}

clib_error_t *
vnet_dev_admin_up_down_fn (vnet_main_t *vnm, u32 hw_if_index, u32 flags)
{
  vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, hw_if_index);
  vlib_main_t *vm = vlib_get_main ();
  vnet_dev_port_t *p = vnet_dev_get_port_from_dev_instance (hi->dev_instance);
  vnet_dev_rv_t rv = VNET_DEV_OK;
  u32 is_up = (flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) != 0;

  if (is_up && p->started == 0)
    rv = vnet_dev_process_call_port_op (vm, p, vnet_dev_port_start);
  else if (!is_up && p->started)
    rv = vnet_dev_process_call_port_op_no_rv (vm, p, vnet_dev_port_stop);

  if (rv != VNET_DEV_OK)
    return clib_error_return (0, "failed to change port admin state: %U",
			      format_vnet_dev_rv, rv);

  return 0;
}

static void
vnet_dev_feature_update_cb (u32 sw_if_index, u8 arc_index, u8 is_enable,
			    void *cb)
{
  vlib_main_t *vm = vlib_get_main ();
  vnet_main_t *vnm = vnet_get_main ();
  vnet_feature_main_t *fm = &feature_main;
  vnet_feature_config_main_t *cm;
  vnet_dev_main_t *vdm = &vnet_dev_main;
  vnet_dev_port_t *port;
  vnet_hw_interface_t *hw;
  u32 current_config_index = ~0;
  u32 next_index = ~0;
  int update_runtime = 0;

  if (arc_index != vdm->eth_port_rx_feature_arc_index)
    return;

  hw = vnet_get_sup_hw_interface (vnm, sw_if_index);
  port = vnet_dev_get_port_from_dev_instance (hw->dev_instance);

  if (port == 0 || port->intf.sw_if_index != sw_if_index)
    return;

  if (vnet_have_features (arc_index, sw_if_index))
    {
      cm = &fm->feature_config_mains[arc_index];
      current_config_index =
	vec_elt (cm->config_index_by_sw_if_index, sw_if_index);
      vnet_get_config_data (&cm->config_main, &current_config_index,
			    &next_index, 0);
      if (port->intf.feature_arc == 0 ||
	  port->intf.rx_next_index != next_index ||
	  port->intf.current_config_index != current_config_index)
	{
	  port->intf.current_config_index = current_config_index;
	  port->intf.rx_next_index = next_index;
	  port->intf.feature_arc_index = arc_index;
	  port->intf.feature_arc = 1;
	  update_runtime = 1;
	}
    }
  else
    {
      if (port->intf.feature_arc)
	{
	  port->intf.current_config_index = 0;
	  port->intf.rx_next_index =
	    port->intf.redirect_to_node ?
		    port->intf.redirect_to_node_next_index :
		    vnet_dev_default_next_index_by_port_type[port->attr.type];
	  port->intf.feature_arc_index = 0;
	  port->intf.feature_arc = 0;
	  update_runtime = 1;
	}
    }

  if (update_runtime)
    {
      foreach_vnet_dev_port_rx_queue (rxq, port)
	vnet_dev_rx_queue_rt_request (
	  vm, rxq,
	  (vnet_dev_rx_queue_rt_req_t){ .update_next_index = 1,
					.update_feature_arc = 1 });
      log_debug (port->dev, "runtime update requested due to chgange in "
			    "feature arc configuration");
    }
}

static int
sort_driver_registrations (void *a0, void *a1)
{
  vnet_dev_driver_registration_t **r0 = a0;
  vnet_dev_driver_registration_t **r1 = a1;

  if (r0[0]->priority > r1[0]->priority)
    return -1;
  else if (r0[0]->priority < r1[0]->priority)
    return 1;

  return 0;
}

static clib_error_t *
vnet_dev_main_init (vlib_main_t *vm)
{
  vnet_dev_main_t *dm = &vnet_dev_main;
  vnet_dev_driver_registration_t **drv = 0;
  u32 temp_space_sz = 0;

  dm->device_index_by_id = hash_create_string (0, sizeof (uword));

  for (vnet_dev_bus_registration_t *r = dm->bus_registrations; r;
       r = r->next_registration)
    {
      vnet_dev_bus_t *bus;
      pool_get_zero (dm->buses, bus);
      bus->registration = r;
      bus->index = bus - dm->buses;
      bus->ops = r->ops;
      if (!r->device_data_size ||
	  r->device_data_size > STRUCT_SIZE_OF (vnet_dev_t, bus_data))
	return clib_error_return (
	  0, "bus device data for bus '%s' is too big not specified", r->name);

      log_debug (0, "bus '%s' registered", r->name);
    }

  for (vnet_dev_driver_registration_t *r = dm->driver_registrations; r;
       r = r->next_registration)
    vec_add1 (drv, r);

  vec_sort_with_function (drv, sort_driver_registrations);

  vec_foreach_pointer (r, drv)
    {
      vnet_dev_driver_t *driver;
      vnet_dev_bus_t *bus;
      vnet_device_class_t *dev_class;
      int bus_index = -1;

      pool_foreach (bus, dm->buses)
	{
	  if (strcmp (bus->registration->name, r->bus) == 0)
	    {
	      bus_index = bus->index;
	      break;
	    }
	}

      if (bus_index < 0)
	return clib_error_return (0, "unknown bus '%s'", r->bus);

      pool_get_zero (dm->drivers, driver);
      driver->registration = r;
      driver->index = driver - dm->drivers;
      driver->bus_index = bus_index;
      driver->ops = r->ops;
      dev_class = clib_mem_alloc (sizeof (vnet_device_class_t));
      *dev_class = (vnet_device_class_t){
	.name = r->name,
	.format_device_name = format_vnet_dev_interface_name,
	.format_device = format_vnet_dev_interface_info,
	.admin_up_down_function = vnet_dev_admin_up_down_fn,
	.rx_redirect_to_node = vnet_dev_set_interface_next_node,
	.clear_counters = vnet_dev_clear_hw_interface_counters,
	.rx_mode_change_function = vnet_dev_rx_mode_change_fn,
	.mac_addr_change_function = vnet_dev_port_mac_change,
	.mac_addr_add_del_function = vnet_dev_add_del_mac_address,
	.flow_ops_function = vnet_dev_flow_ops_fn,
	.set_rss_queues_function = vnet_dev_interface_set_rss_queues,
      };
      driver->dev_class_index = vnet_register_device_class (vm, dev_class);
      log_debug (0, "driver '%s' registered on bus '%s'", r->name,
		 bus->registration->name);

      if (temp_space_sz < r->runtime_temp_space_sz)
	temp_space_sz = r->runtime_temp_space_sz;
    }

  if (dm->startup_config)
    log_debug (0, "startup config: %v", dm->startup_config);

  vec_free (drv);

  if (temp_space_sz > 0)
    {
      const u32 align = CLIB_CACHE_LINE_BYTES;
      u32 sz = round_pow2 (temp_space_sz, align);
      dm->log2_runtime_temp_space_sz =
	get_lowest_set_bit_index (max_pow2 (sz));
      sz = 1 << dm->log2_runtime_temp_space_sz;
      sz *= vlib_get_n_threads ();
      dm->runtime_temp_spaces = clib_mem_alloc_aligned (sz, align);
      clib_memset (dm->runtime_temp_spaces, 0, sz);
      log_debug (0,
		 "requested %u bytes for runtime temp storage, allocated %u "
		 "per thread (total %u)",
		 temp_space_sz, 1 << dm->log2_runtime_temp_space_sz, sz);
    }

  vnet_feature_register (vnet_dev_feature_update_cb, 0);

  return 0;
}

VLIB_INIT_FUNCTION (vnet_dev_main_init);

clib_error_t *
vnet_dev_num_workers_change (vlib_main_t *vm)
{
  vnet_dev_main_t *dm = &vnet_dev_main;

  if (dm->log2_runtime_temp_space_sz > 0)
    {
      const u32 align = CLIB_CACHE_LINE_BYTES;
      uword sz =
	(1ULL << dm->log2_runtime_temp_space_sz) * vlib_get_n_threads ();
      if (dm->runtime_temp_spaces)
	clib_mem_free (dm->runtime_temp_spaces);
      dm->runtime_temp_spaces = clib_mem_alloc_aligned (sz, align);
      clib_memset (dm->runtime_temp_spaces, 0, sz);
      log_debug (0, "runtime temp storage resized to %u", sz);
    }

  return 0;
}

VLIB_NUM_WORKERS_CHANGE_FN (vnet_dev_num_workers_change);
