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

#include <vnet/vnet.h>
#include <vnet/devices/devices.h>
#include <vnet/interface/tx_queue_funcs.h>
#include <vlib/unix/unix.h>

VLIB_REGISTER_LOG_CLASS (if_txq_log, static) = {
  .class_name = "interface",
  .subclass_name = "tx-queue",
};

#define log_debug(fmt, ...) vlib_log_debug (if_txq_log.class, fmt, __VA_ARGS__)
#define log_err(fmt, ...)   vlib_log_err (if_txq_log.class, fmt, __VA_ARGS__)

static u64
tx_queue_key (u32 hw_if_index, u32 queue_id)
{
  return ((u64) hw_if_index << 32) | queue_id;
}

u32
vnet_hw_if_get_tx_queue_index_by_id (vnet_main_t *vnm, u32 hw_if_index,
				     u32 queue_id)
{
  vnet_interface_main_t *im = &vnm->interface_main;
  u64 key = tx_queue_key (hw_if_index, queue_id);
  uword *p = hash_get_mem (im->txq_index_by_hw_if_index_and_queue_id, &key);
  return p ? p[0] : ~0;
}

u32
vnet_hw_if_register_tx_queue (vnet_main_t *vnm, u32 hw_if_index, u32 queue_id)
{
  vnet_interface_main_t *im = &vnm->interface_main;
  vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, hw_if_index);
  vnet_hw_if_tx_queue_t *txq;
  u64 key = tx_queue_key (hw_if_index, queue_id);
  u32 queue_index;

  if (hash_get_mem (im->txq_index_by_hw_if_index_and_queue_id, &key))
    clib_panic ("Trying to register already registered queue id (%u) in the "
		"interface %v\n",
		queue_id, hi->name);

  pool_get_zero (im->hw_if_tx_queues, txq);
  queue_index = txq - im->hw_if_tx_queues;
  vec_add1 (hi->tx_queue_indices, queue_index);
  hash_set_mem_alloc (&im->txq_index_by_hw_if_index_and_queue_id, &key,
		      queue_index);
  txq->hw_if_index = hw_if_index;
  txq->queue_id = queue_id;

  log_debug ("register: interface %v queue-id %u", hi->name, queue_id);

  return queue_index;
}

void
vnet_hw_if_unregister_tx_queue (vnet_main_t *vnm, u32 queue_index)
{
  vnet_interface_main_t *im = &vnm->interface_main;
  vnet_hw_if_tx_queue_t *txq;
  txq = vnet_hw_if_get_tx_queue (vnm, queue_index);
  vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, txq->hw_if_index);
  u64 key;

  key = tx_queue_key (txq->hw_if_index, txq->queue_id);
  hash_unset_mem_free (&im->txq_index_by_hw_if_index_and_queue_id, &key);

  for (int i = 0; i < vec_len (hi->tx_queue_indices); i++)
    if (hi->tx_queue_indices[i] == queue_index)
      {
	vec_del1 (hi->tx_queue_indices, i);
	break;
      }

  log_debug ("unregister: interface %v queue-id %u", hi->name, txq->queue_id);
  clib_bitmap_free (txq->threads);
  pool_put_index (im->hw_if_tx_queues, queue_index);
}

void
vnet_hw_if_unregister_all_tx_queues (vnet_main_t *vnm, u32 hw_if_index)
{
  vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, hw_if_index);
  vnet_interface_main_t *im = &vnm->interface_main;
  vnet_hw_if_tx_queue_t *txq;
  u64 key;

  log_debug ("unregister_all: interface %v", hi->name);

  for (int i = 0; i < vec_len (hi->tx_queue_indices); i++)
    {
      txq = vnet_hw_if_get_tx_queue (vnm, hi->tx_queue_indices[i]);
      key = tx_queue_key (txq->hw_if_index, txq->queue_id);
      hash_unset_mem_free (&im->txq_index_by_hw_if_index_and_queue_id, &key);

      clib_bitmap_free (txq->threads);
      pool_put_index (im->hw_if_tx_queues, hi->tx_queue_indices[i]);
    }

  vec_free (hi->tx_queue_indices);
}

void
vnet_hw_if_tx_queue_assign_thread (vnet_main_t *vnm, u32 queue_index,
				   u32 thread_index)
{
  vnet_hw_if_tx_queue_t *txq = vnet_hw_if_get_tx_queue (vnm, queue_index);
  vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, txq->hw_if_index);
  txq->threads = clib_bitmap_set (txq->threads, thread_index, 1);
  if (clib_bitmap_count_set_bits (txq->threads) > 1)
    txq->shared_queue = 1;
  log_debug (
    "assign_thread: interface %v queue-id %u thread %u queue-shared %s",
    hi->name, txq->queue_id, thread_index,
    (txq->shared_queue == 1 ? "yes" : "no"));
}

void
vnet_hw_if_tx_queue_unassign_thread (vnet_main_t *vnm, u32 queue_index,
				     u32 thread_index)
{
  vnet_hw_if_tx_queue_t *txq = vnet_hw_if_get_tx_queue (vnm, queue_index);
  vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, txq->hw_if_index);
  txq->threads = clib_bitmap_set (txq->threads, thread_index, 0);
  if (clib_bitmap_count_set_bits (txq->threads) < 2)
    txq->shared_queue = 0;
  log_debug (
    "unassign_thread: interface %v queue-id %u thread %u queue-shared %s",
    hi->name, txq->queue_id, thread_index,
    (txq->shared_queue == 1 ? "yes" : "no"));
}
