// SPDX-License-Identifier: GPL-2.0-only
/****************************************************************************
 * Driver for Solarflare network controllers and boards
 * Copyright 2005-2018 Solarflare Communications Inc.
 * Copyright 2019-2022 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 "efx_common.h"
#include "efx_channels.h"
#include "io.h"
#include "ef100_nic.h"
#include "ef100_netdev.h"
#include "ef100_sriov.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 = pci_get_drvdata(pci_dev);
	struct efx_probe_data *probe_data;

	if (!efx)
		return;

	probe_data = container_of(efx, struct efx_probe_data, efx);
	ef100_remove_netdev(probe_data);
#ifdef CONFIG_SFC_SRIOV
	efx_fini_struct_tc(efx);
#endif

	ef100_remove(efx);
	efx_fini_io(efx);

	pci_dbg(pci_dev, "shutdown successful\n");

	pci_set_drvdata(pci_dev, NULL);
	efx_fini_struct(efx);
	kfree(probe_data);
};

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

	/* Allocate probe data and struct efx_nic */
	probe_data = kzalloc(sizeof(*probe_data), GFP_KERNEL);
	if (!probe_data)
		return -ENOMEM;
	probe_data->pci_dev = pci_dev;
	efx = &probe_data->efx;

	efx->type = (const struct efx_nic_type *)entry->driver_data;

	efx->pci_dev = pci_dev;
	pci_set_drvdata(pci_dev, efx);
	rc = efx_init_struct(efx, pci_dev);
	if (rc)
		goto fail;

	efx->vi_stride = EF100_DEFAULT_VI_STRIDE;
	pci_info(pci_dev, "Solarflare EF100 NIC detected\n");

	rc = ef100_pci_find_func_ctrl_window(efx, &fcw);
	if (rc) {
		pci_err(pci_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) {
		pci_err(pci_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;

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

	efx->state = STATE_PROBED;
	rc = ef100_probe_netdev(probe_data);
	if (rc)
		goto fail;

	pci_dbg(pci_dev, "initialisation successful\n");

	return 0;

fail:
	ef100_pci_remove(pci_dev);
	return rc;
}

#ifdef CONFIG_SFC_SRIOV
static int ef100_pci_sriov_configure(struct pci_dev *dev, int num_vfs)
{
	struct efx_nic *efx = pci_get_drvdata(dev);
	int rc;

	if (efx->type->sriov_configure) {
		rc = efx->type->sriov_configure(efx, num_vfs);
		if (rc)
			return rc;
		else
			return num_vfs;
	}
	return -ENOENT;
}
#endif

/* 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,
#ifdef CONFIG_SFC_SRIOV
	.sriov_configure = ef100_pci_sriov_configure,
#endif
	.err_handler    = &efx_err_handlers,
};

MODULE_DEVICE_TABLE(pci, ef100_pci_table);
