// SPDX-License-Identifier: GPL-2.0-only
/****************************************************************************
 * Driver for Solarflare network controllers and boards
 * Copyright 2005-2018 Solarflare Communications Inc.
 * Copyright 2019-2020 Xilinx Inc.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 as published
 * by the Free Software Foundation, incorporated herein by reference.
 */

#include "net_driver.h"
#include <linux/module.h>
#include <linux/aer.h>
#include "efx_common.h"
#include "efx_channels.h"
#include "io.h"
#include "ef100_nic.h"
#include "ef100_netdev.h"
#include "ef100_regs.h"
#include "ef100.h"

#define EFX_EF100_PCI_DEFAULT_BAR	2

/* Number of bytes at start of vendor specified extended capability that indicate
 * that the capability is vendor specified. i.e. offset from value returned by
 * pci_find_next_ext_capability() to beginning of vendor specified capability
 * header.
 */
#define PCI_EXT_CAP_HDR_LENGTH  4

/* Expected size of a Xilinx continuation address table entry. */
#define ESE_GZ_CFGBAR_CONT_CAP_MIN_LENGTH      16

struct ef100_func_ctl_window {
	bool valid;
	unsigned int bar;
	u64 offset;
};

static int ef100_pci_walk_xilinx_table(struct efx_nic *efx, u64 offset,
				       struct ef100_func_ctl_window *result);

/* Number of bytes to offset when reading bit position x with dword accessors. */
#define ROUND_DOWN_TO_DWORD(x) (((x) & (~31)) >> 3)

#define EXTRACT_BITS(x, lbn, width) \
	(((x) >> ((lbn) & 31)) & ((1ull << (width)) - 1))

static u32 _ef100_pci_get_bar_bits_with_width(struct efx_nic *efx,
					      int structure_start,
					      int lbn, int width)
{
	efx_dword_t dword;

	efx_readd(efx, &dword, structure_start + ROUND_DOWN_TO_DWORD(lbn));

	return EXTRACT_BITS(le32_to_cpu(dword.u32[0]), lbn, width);
}

#define ef100_pci_get_bar_bits(efx, entry_location, bitdef)	\
	_ef100_pci_get_bar_bits_with_width(efx, entry_location,	\
		ESF_GZ_CFGBAR_ ## bitdef ## _LBN,		\
		ESF_GZ_CFGBAR_ ## bitdef ## _WIDTH)

static int ef100_pci_parse_ef100_entry(struct efx_nic *efx, int entry_location,
				       struct ef100_func_ctl_window *result)
{
	u64 offset = ef100_pci_get_bar_bits(efx, entry_location, EF100_FUNC_CTL_WIN_OFF) <<
					ESE_GZ_EF100_FUNC_CTL_WIN_OFF_SHIFT;
	u32 bar = ef100_pci_get_bar_bits(efx, entry_location, EF100_BAR);

	netif_dbg(efx, probe, efx->net_dev,
		  "Found EF100 function control window bar=%d offset=0x%llx\n",
		  bar, offset);

	if (result->valid) {
		netif_err(efx, probe, efx->net_dev,
			  "Duplicated EF100 table entry.\n");
		return -EINVAL;
	}

	if (bar == ESE_GZ_CFGBAR_EF100_BAR_NUM_EXPANSION_ROM ||
	    bar == ESE_GZ_CFGBAR_EF100_BAR_NUM_INVALID) {
		netif_err(efx, probe, efx->net_dev,
			  "Bad BAR value of %d in Xilinx capabilities EF100 entry.\n",
			  bar);
		return -EINVAL;
	}

	result->bar = bar;
	result->offset = offset;
	result->valid = true;
	return 0;
}

static bool ef100_pci_does_bar_overflow(struct efx_nic *efx, int bar,
					u64 next_entry)
{
	return next_entry + ESE_GZ_CFGBAR_ENTRY_HEADER_SIZE >
					pci_resource_len(efx->pci_dev, bar);
}

/* Parse a Xilinx capabilities table entry describing a continuation to a new
 * sub-table.
 */
static int ef100_pci_parse_continue_entry(struct efx_nic *efx, int entry_location,
					  struct ef100_func_ctl_window *result)
{
	unsigned int previous_bar;
	efx_oword_t entry;
	u64 offset;
	int rc = 0;
	u32 bar;

	efx_reado(efx, &entry, entry_location);

	bar = EFX_OWORD_FIELD32(entry, ESF_GZ_CFGBAR_CONT_CAP_BAR);

	offset = EFX_OWORD_FIELD64(entry, ESF_GZ_CFGBAR_CONT_CAP_OFFSET) <<
		ESE_GZ_CONT_CAP_OFFSET_BYTES_SHIFT;

	previous_bar = efx->mem_bar;

	if (bar == ESE_GZ_VSEC_BAR_NUM_EXPANSION_ROM ||
	    bar == ESE_GZ_VSEC_BAR_NUM_INVALID) {
		netif_err(efx, probe, efx->net_dev,
			  "Bad BAR value of %d in Xilinx capabilities sub-table.\n",
			  bar);
		return -EINVAL;
	}

	if (bar != previous_bar) {
		efx_fini_io(efx);

		if (ef100_pci_does_bar_overflow(efx, bar, offset)) {
			netif_err(efx, probe, efx->net_dev,
				  "Xilinx table will overrun BAR[%d] offset=0x%llx\n",
				  bar, offset);
			return -EINVAL;
		}

		/* Temporarily map new BAR. */
		rc = efx_init_io(efx, bar,
				 (dma_addr_t)DMA_BIT_MASK(ESF_GZ_TX_SEND_ADDR_WIDTH),
				 pci_resource_len(efx->pci_dev, bar));
		if (rc) {
			netif_err(efx, probe, efx->net_dev,
				  "Mapping new BAR for Xilinx table failed, rc=%d\n", rc);
			return rc;
		}
	}

	rc = ef100_pci_walk_xilinx_table(efx, offset, result);
	if (rc)
		return rc;

	if (bar != previous_bar) {
		efx_fini_io(efx);

		/* Put old BAR back. */
		rc = efx_init_io(efx, previous_bar,
				 (dma_addr_t)DMA_BIT_MASK(ESF_GZ_TX_SEND_ADDR_WIDTH),
				 pci_resource_len(efx->pci_dev, previous_bar));
		if (rc) {
			netif_err(efx, probe, efx->net_dev,
				  "Putting old BAR back failed, rc=%d\n", rc);
			return rc;
		}
	}

	return 0;
}

/* Iterate over the Xilinx capabilities table in the currently mapped BAR and
 * call ef100_pci_parse_ef100_entry() on any EF100 entries and
 * ef100_pci_parse_continue_entry() on any table continuations.
 */
static int ef100_pci_walk_xilinx_table(struct efx_nic *efx, u64 offset,
				       struct ef100_func_ctl_window *result)
{
	u64 current_entry = offset;
	int rc = 0;

	while (true) {
		u32 id = ef100_pci_get_bar_bits(efx, current_entry, ENTRY_FORMAT);
		u32 last = ef100_pci_get_bar_bits(efx, current_entry, ENTRY_LAST);
		u32 rev = ef100_pci_get_bar_bits(efx, current_entry, ENTRY_REV);
		u32 entry_size;

		if (id == ESE_GZ_CFGBAR_ENTRY_LAST)
			return 0;

		entry_size = ef100_pci_get_bar_bits(efx, current_entry, ENTRY_SIZE);

		netif_dbg(efx, probe, efx->net_dev,
			  "Seen Xilinx table entry 0x%x size 0x%x at 0x%llx in BAR[%d]\n",
			  id, entry_size, current_entry, efx->mem_bar);

		if (entry_size < sizeof(u32) * 2) {
			netif_err(efx, probe, efx->net_dev,
				  "Xilinx table entry too short len=0x%x\n", entry_size);
			return -EINVAL;
		}

		switch (id) {
		case ESE_GZ_CFGBAR_ENTRY_EF100:
			if (rev != ESE_GZ_CFGBAR_ENTRY_REV_EF100 ||
			    entry_size < ESE_GZ_CFGBAR_ENTRY_SIZE_EF100) {
				netif_err(efx, probe, efx->net_dev,
					  "Bad length or rev for EF100 entry in Xilinx capabilities table. entry_size=%d rev=%d.\n",
					  entry_size, rev);
				return -EINVAL;
			}

			rc = ef100_pci_parse_ef100_entry(efx, current_entry,
							 result);
			if (rc)
				return rc;
			break;
		case ESE_GZ_CFGBAR_ENTRY_CONT_CAP_ADDR:
			if (rev != 0 || entry_size < ESE_GZ_CFGBAR_CONT_CAP_MIN_LENGTH) {
				netif_err(efx, probe, efx->net_dev,
					  "Bad length or rev for continue entry in Xilinx capabilities table. entry_size=%d rev=%d.\n",
					  entry_size, rev);
				return -EINVAL;
			}

			rc = ef100_pci_parse_continue_entry(efx, current_entry, result);
			if (rc)
				return rc;
			break;
		default:
			/* Ignore unknown table entries. */
			break;
		}

		if (last)
			return 0;

		current_entry += entry_size;

		if (ef100_pci_does_bar_overflow(efx, efx->mem_bar, current_entry)) {
			netif_err(efx, probe, efx->net_dev,
				  "Xilinx table overrun at position=0x%llx.\n",
				  current_entry);
			return -EINVAL;
		}
	}
}

static int _ef100_pci_get_config_bits_with_width(struct efx_nic *efx,
						 int structure_start, int lbn,
						 int width, u32 *result)
{
	int rc, pos = structure_start + ROUND_DOWN_TO_DWORD(lbn);
	u32 temp;

	rc = pci_read_config_dword(efx->pci_dev, pos, &temp);
	if (rc) {
		netif_err(efx, probe, efx->net_dev,
			  "Failed to read PCI config dword at %d\n",
			  pos);
		return rc;
	}

	*result = EXTRACT_BITS(temp, lbn, width);

	return 0;
}

#define ef100_pci_get_config_bits(efx, entry_location, bitdef, result)	\
	_ef100_pci_get_config_bits_with_width(efx, entry_location,	\
		 ESF_GZ_VSEC_ ## bitdef ## _LBN,			\
		 ESF_GZ_VSEC_ ## bitdef ## _WIDTH, result)

/* Call ef100_pci_walk_xilinx_table() for the Xilinx capabilities table pointed
 * to by this PCI_EXT_CAP_ID_VNDR.
 */
static int ef100_pci_parse_xilinx_cap(struct efx_nic *efx, int vndr_cap,
				      bool has_offset_hi,
				      struct ef100_func_ctl_window *result)
{
	u32 offset_high = 0;
	u32 offset_lo = 0;
	u64 offset = 0;
	u32 bar = 0;
	int rc = 0;

	rc = ef100_pci_get_config_bits(efx, vndr_cap, TBL_BAR, &bar);
	if (rc) {
		netif_err(efx, probe, efx->net_dev,
			  "Failed to read ESF_GZ_VSEC_TBL_BAR, rc=%d\n",
			  rc);
		return rc;
	}

	if (bar == ESE_GZ_CFGBAR_CONT_CAP_BAR_NUM_EXPANSION_ROM ||
	    bar == ESE_GZ_CFGBAR_CONT_CAP_BAR_NUM_INVALID) {
		netif_err(efx, probe, efx->net_dev,
			  "Bad BAR value of %d in Xilinx capabilities sub-table.\n",
			  bar);
		return -EINVAL;
	}

	rc = ef100_pci_get_config_bits(efx, vndr_cap, TBL_OFF_LO, &offset_lo);
	if (rc) {
		netif_err(efx, probe, efx->net_dev,
			  "Failed to read ESF_GZ_VSEC_TBL_OFF_LO, rc=%d\n",
			  rc);
		return rc;
	}

	/* Get optional extension to 64bit offset. */
	if (has_offset_hi) {
		rc = ef100_pci_get_config_bits(efx, vndr_cap, TBL_OFF_HI, &offset_high);
		if (rc) {
			netif_err(efx, probe, efx->net_dev,
				  "Failed to read ESF_GZ_VSEC_TBL_OFF_HI, rc=%d\n",
				  rc);
			return rc;
		}
	}

	offset = (((u64)offset_lo) << ESE_GZ_VSEC_TBL_OFF_LO_BYTES_SHIFT) |
		 (((u64)offset_high) << ESE_GZ_VSEC_TBL_OFF_HI_BYTES_SHIFT);

	if (offset > pci_resource_len(efx->pci_dev, bar) - sizeof(u32) * 2) {
		netif_err(efx, probe, efx->net_dev,
			  "Xilinx table will overrun BAR[%d] offset=0x%llx\n",
			  bar, offset);
		return -EINVAL;
	}

	/* Temporarily map BAR. */
	rc = efx_init_io(efx, bar,
			 (dma_addr_t)DMA_BIT_MASK(ESF_GZ_TX_SEND_ADDR_WIDTH),
			 pci_resource_len(efx->pci_dev, bar));
	if (rc) {
		netif_err(efx, probe, efx->net_dev,
			  "efx_init_io failed, rc=%d\n", rc);
		return rc;
	}

	rc = ef100_pci_walk_xilinx_table(efx, offset, result);

	/* Unmap temporarily mapped BAR. */
	efx_fini_io(efx);
	return rc;
}

/* Call ef100_pci_parse_ef100_entry() for each Xilinx PCI_EXT_CAP_ID_VNDR
 * capability.
 */
static int ef100_pci_find_func_ctrl_window(struct efx_nic *efx,
					   struct ef100_func_ctl_window *result)
{
	int num_xilinx_caps = 0;
	int cap = 0;

	result->valid = false;

	while ((cap = pci_find_next_ext_capability(efx->pci_dev, cap, PCI_EXT_CAP_ID_VNDR)) != 0) {
		int vndr_cap = cap + PCI_EXT_CAP_HDR_LENGTH;
		u32 vsec_ver = 0;
		u32 vsec_len = 0;
		u32 vsec_id = 0;
		int rc = 0;

		num_xilinx_caps++;

		rc = ef100_pci_get_config_bits(efx, vndr_cap, ID, &vsec_id);
		if (rc) {
			netif_err(efx, probe, efx->net_dev,
				  "Failed to read ESF_GZ_VSEC_ID, rc=%d\n",
				  rc);
			return rc;
		}

		rc = ef100_pci_get_config_bits(efx, vndr_cap, VER, &vsec_ver);
		if (rc) {
			netif_err(efx, probe, efx->net_dev,
				  "Failed to read ESF_GZ_VSEC_VER, rc=%d\n",
				  rc);
			return rc;
		}

		/* Get length of whole capability - i.e. starting at cap */
		rc = ef100_pci_get_config_bits(efx, vndr_cap, LEN, &vsec_len);
		if (rc) {
			netif_err(efx, probe, efx->net_dev,
				  "Failed to read ESF_GZ_VSEC_LEN, rc=%d\n",
				  rc);
			return rc;
		}

		if (vsec_id == ESE_GZ_XILINX_VSEC_ID &&
		    vsec_ver == ESE_GZ_VSEC_VER_XIL_CFGBAR &&
		    vsec_len >= ESE_GZ_VSEC_LEN_MIN) {
			bool has_offset_hi = (vsec_len >= ESE_GZ_VSEC_LEN_HIGH_OFFT);

			rc = ef100_pci_parse_xilinx_cap(efx, vndr_cap,
							has_offset_hi, result);
			if (rc)
				return rc;
		}
	}

	if (num_xilinx_caps && !result->valid) {
		netif_err(efx, probe, efx->net_dev,
			  "Seen %d Xilinx tables, but no EF100 entry.\n",
			  num_xilinx_caps);
		return -EINVAL;
	}

	return 0;
}

/* Final NIC shutdown
 * This is called only at module unload (or hotplug removal).  A PF can call
 * this on its VFs to ensure they are unbound first.
 */
static void ef100_pci_remove(struct pci_dev *pci_dev)
{
	struct efx_nic *efx;

	efx = pci_get_drvdata(pci_dev);
	if (!efx)
		return;

	rtnl_lock();
	dev_close(efx->net_dev);
	rtnl_unlock();

	/* Unregistering our netdev notifier triggers unbinding of TC indirect
	 * blocks, so we have to do it before PCI removal.
	 */
	unregister_netdevice_notifier(&efx->netdev_notifier);
	ef100_remove(efx);
	efx_fini_io(efx);
	netif_dbg(efx, drv, efx->net_dev, "shutdown successful\n");

	pci_set_drvdata(pci_dev, NULL);
	efx_fini_struct(efx);
	free_netdev(efx->net_dev);

	pci_disable_pcie_error_reporting(pci_dev);
};

static int ef100_pci_probe(struct pci_dev *pci_dev,
			   const struct pci_device_id *entry)
{
	struct ef100_func_ctl_window fcw = { 0 };
	struct net_device *net_dev;
	struct efx_nic *efx;
	int rc;

	/* Allocate and initialise a struct net_device and struct efx_nic */
	net_dev = alloc_etherdev_mq(sizeof(*efx), EFX_MAX_CORE_TX_QUEUES);
	if (!net_dev)
		return -ENOMEM;
	efx = netdev_priv(net_dev);
	efx->type = (const struct efx_nic_type *)entry->driver_data;

	pci_set_drvdata(pci_dev, efx);
	SET_NETDEV_DEV(net_dev, &pci_dev->dev);
	rc = efx_init_struct(efx, pci_dev, net_dev);
	if (rc)
		goto fail;

	efx->vi_stride = EF100_DEFAULT_VI_STRIDE;
	netif_info(efx, probe, efx->net_dev,
		   "Solarflare EF100 NIC detected\n");

	rc = ef100_pci_find_func_ctrl_window(efx, &fcw);
	if (rc) {
		netif_err(efx, probe, efx->net_dev,
			  "Error looking for ef100 function control window, rc=%d\n",
			  rc);
		goto fail;
	}

	if (!fcw.valid) {
		/* Extended capability not found - use defaults. */
		fcw.bar = EFX_EF100_PCI_DEFAULT_BAR;
		fcw.offset = 0;
		fcw.valid = true;
	}

	if (fcw.offset > pci_resource_len(efx->pci_dev, fcw.bar) - ESE_GZ_FCW_LEN) {
		netif_err(efx, probe, efx->net_dev,
			  "Func control window overruns BAR\n");
		rc = -EIO;
		goto fail;
	}

	/* Set up basic I/O (BAR mappings etc) */
	rc = efx_init_io(efx, fcw.bar,
			 (dma_addr_t)DMA_BIT_MASK(ESF_GZ_TX_SEND_ADDR_WIDTH),
			 pci_resource_len(efx->pci_dev, fcw.bar));
	if (rc)
		goto fail;

	efx->reg_base = fcw.offset;

	efx->netdev_notifier.notifier_call = ef100_netdev_event;
	rc = register_netdevice_notifier(&efx->netdev_notifier);
	if (rc) {
		netif_err(efx, probe, efx->net_dev,
			  "Failed to register netdevice notifier, rc=%d\n", rc);
		goto fail;
	}

	rc = efx->type->probe(efx);
	if (rc)
		goto fail;

	netif_dbg(efx, probe, efx->net_dev, "initialisation successful\n");

	return 0;

fail:
	ef100_pci_remove(pci_dev);
	return rc;
}

/* PCI device ID table */
static const struct pci_device_id ef100_pci_table[] = {
	{PCI_DEVICE(PCI_VENDOR_ID_XILINX, 0x0100),  /* Riverhead PF */
		.driver_data = (unsigned long) &ef100_pf_nic_type },
	{PCI_DEVICE(PCI_VENDOR_ID_XILINX, 0x1100),  /* Riverhead VF */
		.driver_data = (unsigned long) &ef100_vf_nic_type },
	{0}                     /* end of list */
};

struct pci_driver ef100_pci_driver = {
	.name           = "sfc_ef100",
	.id_table       = ef100_pci_table,
	.probe          = ef100_pci_probe,
	.remove         = ef100_pci_remove,
	.err_handler    = &efx_err_handlers,
};

MODULE_DEVICE_TABLE(pci, ef100_pci_table);
