/*
 * Copyright (c) 2016 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 * pci.c: Linux user space PCI bus management.
 *
 * Copyright (c) 2008 Eliot Dresselhaus
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

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

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <sys/ioctl.h>
#include <net/if.h>
#ifdef __linux__
#include <linux/ethtool.h>
#include <linux/sockios.h>
#endif /* __linux__ */

vlib_pci_main_t pci_main;

VLIB_REGISTER_LOG_CLASS (pci_log, static) = {
  .class_name = "pci",
};

#define log_debug(h, f, ...)                                                  \
  vlib_log (VLIB_LOG_LEVEL_DEBUG, pci_log.class, "%U: " f,                    \
	    format_vlib_pci_log, h, ##__VA_ARGS__)

u8 *
format_vlib_pci_log (u8 *s, va_list *va)
{
  vlib_pci_dev_handle_t h = va_arg (*va, vlib_pci_dev_handle_t);
  return format (s, "%U", format_vlib_pci_addr,
		 vlib_pci_get_addr (vlib_get_main (), h));
}

vlib_pci_device_info_t *__attribute__ ((weak))
vlib_pci_get_device_info (vlib_main_t *vm, vlib_pci_addr_t *addr,
			  clib_error_t **error)
{
  if (error)
    *error = clib_error_return (0, "unsupported");
  return 0;
}

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

vlib_pci_addr_t * __attribute__ ((weak)) vlib_pci_get_all_dev_addrs ()
{
  return 0;
}

static clib_error_t *
_vlib_pci_config_set_control_bit (vlib_main_t *vm, vlib_pci_dev_handle_t h,
				  u16 bit, int new_val, int *already_set)
{
  u16 control, old;
  clib_error_t *err;

  err = vlib_pci_read_write_config (
    vm, h, VLIB_READ, STRUCT_OFFSET_OF (vlib_pci_config_t, command), &old,
    STRUCT_SIZE_OF (vlib_pci_config_t, command));

  if (err)
    return err;

  control = new_val ? old | bit : old & ~bit;
  *already_set = old == control;
  if (*already_set)
    return 0;

  return vlib_pci_read_write_config (
    vm, h, VLIB_WRITE, STRUCT_OFFSET_OF (vlib_pci_config_t, command), &control,
    STRUCT_SIZE_OF (vlib_pci_config_t, command));
}

clib_error_t *
vlib_pci_intr_enable (vlib_main_t *vm, vlib_pci_dev_handle_t h)
{
  const vlib_pci_config_reg_command_t cmd = { .intx_disable = 1 };
  clib_error_t *err;
  int already_set = 0;

  err = _vlib_pci_config_set_control_bit (vm, h, cmd.as_u16, 0, &already_set);
  log_debug (h, "interrupt%senabled", already_set ? " " : " already ");
  return err;
}

clib_error_t *
vlib_pci_intr_disable (vlib_main_t *vm, vlib_pci_dev_handle_t h)
{
  const vlib_pci_config_reg_command_t cmd = { .intx_disable = 1 };
  clib_error_t *err;
  int already_set = 0;

  err = _vlib_pci_config_set_control_bit (vm, h, cmd.as_u16, 1, &already_set);
  log_debug (h, "interrupt%sdisabled", already_set ? " " : " already ");
  return err;
}

clib_error_t *
vlib_pci_bus_master_enable (vlib_main_t *vm, vlib_pci_dev_handle_t h)
{
  const vlib_pci_config_reg_command_t cmd = { .bus_master = 1 };
  clib_error_t *err;
  int already_set = 0;

  err = _vlib_pci_config_set_control_bit (vm, h, cmd.as_u16, 1, &already_set);
  log_debug (h, "bus-master%senabled", already_set ? " " : " already ");
  return err;
}

clib_error_t *
vlib_pci_bus_master_disable (vlib_main_t *vm, vlib_pci_dev_handle_t h)
{
  const vlib_pci_config_reg_command_t cmd = { .bus_master = 1 };
  clib_error_t *err;
  int already_set = 0;

  err = _vlib_pci_config_set_control_bit (vm, h, cmd.as_u16, 0, &already_set);
  log_debug (h, "bus-master%sdisabled", already_set ? " " : " already ");
  return err;
}

clib_error_t *
vlib_pci_function_level_reset (vlib_main_t *vm, vlib_pci_dev_handle_t h)
{
  vlib_pci_config_t cfg;
  pci_capability_pcie_t *cap;
  pci_capability_pcie_dev_control_t dev_control;
  clib_error_t *err;
  u8 offset;

  log_debug (h, "function level reset");

  err = vlib_pci_read_write_config (vm, h, VLIB_READ, 0, &cfg, sizeof (cfg));
  if (err)
    return err;

  offset = cfg.cap_ptr;
  do
    {
      cap = (pci_capability_pcie_t *) (cfg.data + offset);

      if (cap->capability_id == PCI_CAP_ID_PCIE)
	break;

      offset = cap->next_offset;
    }
  while (offset);

  if (cap->capability_id != PCI_CAP_ID_PCIE)
    return clib_error_return (0, "PCIe capability config not found");

  if (cap->dev_caps.flr_capable == 0)
    return clib_error_return (0, "PCIe function level reset not supported");

  dev_control = cap->dev_control;
  dev_control.function_level_reset = 1;

  if ((err = vlib_pci_write_config_u16 (
	 vm, h, offset + STRUCT_OFFSET_OF (pci_capability_pcie_t, dev_control),
	 &dev_control.as_u16)))
    return err;

  return 0;
}

static clib_error_t *
show_pci_fn (vlib_main_t * vm,
	     unformat_input_t * input, vlib_cli_command_t * cmd)
{
  vlib_pci_addr_t *addr = 0, *addrs;
  int show_all = 0;
  u8 *s = 0;

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (input, "all"))
	show_all = 1;
      else
	return clib_error_return (0, "unknown input `%U'",
				  format_unformat_error, input);
    }

  vlib_cli_output (vm, "%-13s%-5s%-12s%-14s%-16s%-32s%s",
		   "Address", "Sock", "VID:PID", "Link Speed", "Driver",
		   "Product Name", "Vital Product Data");

  addrs = vlib_pci_get_all_dev_addrs ();

  vec_foreach (addr, addrs)
    {
      vlib_pci_device_info_t *d;
      d = vlib_pci_get_device_info (vm, addr, 0);

      if (!d)
        continue;

      if (d->device_class != PCI_CLASS_NETWORK_ETHERNET && !show_all)
	continue;

      vec_reset_length (s);
      if (d->numa_node >= 0)
	s = format (s, "  %d", d->numa_node);

      vlib_cli_output (
	vm, "%-13U%-5v%04x:%04x   %-14U%-16s%-32v%U", format_vlib_pci_addr,
	addr, s, d->vendor_id, d->device_id, format_vlib_pci_link_speed, d,
	d->driver_name ? (char *) d->driver_name : "", d->product_name,
	format_vlib_pci_vpd, d->vpd_r, (u8 *) 0);
      vlib_pci_free_device_info (d);
    }

  vec_free (s);
  vec_free (addrs);
  return 0;
}

uword
unformat_vlib_pci_addr (unformat_input_t * input, va_list * args)
{
  vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
  u32 x[4];

  if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
    return 0;

  addr->domain = x[0];
  addr->bus = x[1];
  addr->slot = x[2];
  addr->function = x[3];

  return 1;
}

u8 *
format_vlib_pci_addr (u8 * s, va_list * va)
{
  vlib_pci_addr_t *addr = va_arg (*va, vlib_pci_addr_t *);
  return format (s, "%04x:%02x:%02x.%x", addr->domain, addr->bus,
		 addr->slot, addr->function);
}

u8 *
format_vlib_pci_link_port (u8 *s, va_list *va)
{
  vlib_pci_config_t *c = va_arg (*va, vlib_pci_config_t *);
  pci_capability_pcie_t *r = pci_config_find_capability (c, PCI_CAP_ID_PCIE);

  if (!r)
    return format (s, "unknown");

  return format (s, "P%d", r->link_caps.port_number);
}

static u8 *
_vlib_pci_link_speed (u8 *s, u8 speed, u8 width)
{
  static char *speeds[] = {
    [1] = "2.5", [2] = "5.0", [3] = "8.0", [4] = "16.0", [5] = "32.0"
  };

  if (speed >= ARRAY_LEN (speeds) || speeds[speed] == 0)
    s = format (s, "unknown speed");
  else
    s = format (s, "%s GT/s", speeds[speed]);

  return format (s, " x%u", width);
}

u8 *
format_vlib_pci_link_speed (u8 *s, va_list *va)
{
  vlib_pci_config_t *c = va_arg (*va, vlib_pci_config_t *);
  pci_capability_pcie_t *r = pci_config_find_capability (c, PCI_CAP_ID_PCIE);

  if (!r)
    return format (s, "unknown");

  return _vlib_pci_link_speed (s, r->link_status.link_speed,
			       r->link_status.negotiated_link_width);
}

u8 *
format_vlib_pci_link_speed_cap (u8 *s, va_list *va)
{
  vlib_pci_config_t *c = va_arg (*va, vlib_pci_config_t *);
  pci_capability_pcie_t *r = pci_config_find_capability (c, PCI_CAP_ID_PCIE);

  if (!r)
    return format (s, "unknown");

  return _vlib_pci_link_speed (s, r->link_caps.max_link_speed,
			       r->link_caps.max_link_width);
}

u8 *
format_vlib_pci_vpd (u8 * s, va_list * args)
{
  u8 *data = va_arg (*args, u8 *);
  u8 *id = va_arg (*args, u8 *);
  u32 indent = format_get_indent (s);
  char *string_types[] = { "PN", "EC", "SN", "MN", 0 };
  uword p = 0;
  int first_line = 1;

  if (vec_len (data) < 3)
    return s;

  while (p + 3 < vec_len (data))
    {

      if (data[p] == 0 && data[p + 1] == 0)
	return s;

      if (p + data[p + 2] > vec_len (data))
	return s;

      if (id == 0)
	{
	  int is_string = 0;
	  char **c = string_types;

	  while (c[0])
	    {
	      if (*(u16 *) & data[p] == *(u16 *) c[0])
		is_string = 1;
	      c++;
	    }

	  if (data[p + 2])
	    {
	      if (!first_line)
		s = format (s, "\n%U", format_white_space, indent);
	      else
		{
		  first_line = 0;
		  s = format (s, " ");
		}

	      s = format (s, "%c%c: ", data[p], data[p + 1]);
	      if (is_string)
		vec_add (s, data + p + 3, data[p + 2]);
	      else
		{
		  int i;
		  const int max_bytes = 8;
		  s = format (s, "0x");
		  for (i = 0; i < clib_min (data[p + 2], max_bytes); i++)
		    s = format (s, " %02x", data[p + 3 + i]);

		  if (data[p + 2] > max_bytes)
		    s = format (s, " ...");
		}
	    }
	}
      else if (*(u16 *) & data[p] == *(u16 *) id)
	{
	  vec_add (s, data + p + 3, data[p + 2]);
	  return s;
	}

      p += 3 + data[p + 2];
    }

  return s;
}

VLIB_CLI_COMMAND (show_pci_command, static) = {
  .path = "show pci",
  .short_help = "show pci [all]",
  .function = show_pci_fn,
};
