/**
 * IBM Accelerator Family 'GenWQE'
 *
 * (C) Copyright IBM Corp. 2013
 *
 * Author: Frank Haverkamp <haver@linux.vnet.ibm.com>
 * Author: Joerg-Stephan Vogt <jsvogt@de.ibm.com>
 * Author: Michael Jung <mijung@gmx.net>
 * Author: Michael Ruettger <michael@ibmra.de>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License (version 2 only)
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 */

/*
 * Miscelanous functionality used in the other GenWQE driver parts.
 */

#include <linux/kernel.h>
#include <linux/dma-mapping.h>
#include <linux/sched.h>
#include <linux/vmalloc.h>
#include <linux/page-flags.h>
#include <linux/scatterlist.h>
#include <linux/hugetlb.h>
#include <linux/iommu.h>
#include <linux/delay.h>
#include <linux/pci.h>
#include <linux/dma-mapping.h>
#include <linux/ctype.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <asm/pgtable.h>

#include "genwqe_driver.h"
#include "card_base.h"
#include "card_ddcb.h"

/**
 * __genwqe_writeq() - Write 64-bit register
 * @cd:	        genwqe device descriptor
 * @byte_offs:  byte offset within BAR
 * @val:        64-bit value
 *
 * Return: 0 if success; < 0 if error
 */
int __genwqe_writeq(struct genwqe_dev *cd, u64 byte_offs, u64 val)
{
	struct pci_dev *pci_dev = cd->pci_dev;

	if (cd->err_inject & GENWQE_INJECT_HARDWARE_FAILURE)
		return -EIO;

	if (cd->mmio == NULL)
		return -EIO;

	if (pci_channel_offline(pci_dev))
		return -EIO;

	__raw_writeq((__force u64)cpu_to_be64(val), cd->mmio + byte_offs);
	return 0;
}

/**
 * __genwqe_readq() - Read 64-bit register
 * @cd:         genwqe device descriptor
 * @byte_offs:  offset within BAR
 *
 * Return: value from register
 */
u64 __genwqe_readq(struct genwqe_dev *cd, u64 byte_offs)
{
	if (cd->err_inject & GENWQE_INJECT_HARDWARE_FAILURE)
		return 0xffffffffffffffffull;

	if ((cd->err_inject & GENWQE_INJECT_GFIR_FATAL) &&
	    (byte_offs == IO_SLC_CFGREG_GFIR))
		return 0x000000000000ffffull;

	if ((cd->err_inject & GENWQE_INJECT_GFIR_INFO) &&
	    (byte_offs == IO_SLC_CFGREG_GFIR))
		return 0x00000000ffff0000ull;

	if (cd->mmio == NULL)
		return 0xffffffffffffffffull;

	return be64_to_cpu((__force __be64)__raw_readq(cd->mmio + byte_offs));
}

/**
 * __genwqe_writel() - Write 32-bit register
 * @cd:	        genwqe device descriptor
 * @byte_offs:  byte offset within BAR
 * @val:        32-bit value
 *
 * Return: 0 if success; < 0 if error
 */
int __genwqe_writel(struct genwqe_dev *cd, u64 byte_offs, u32 val)
{
	struct pci_dev *pci_dev = cd->pci_dev;

	if (cd->err_inject & GENWQE_INJECT_HARDWARE_FAILURE)
		return -EIO;

	if (cd->mmio == NULL)
		return -EIO;

	if (pci_channel_offline(pci_dev))
		return -EIO;

	__raw_writel((__force u32)cpu_to_be32(val), cd->mmio + byte_offs);
	return 0;
}

/**
 * __genwqe_readl() - Read 32-bit register
 * @cd:         genwqe device descriptor
 * @byte_offs:  offset within BAR
 *
 * Return: Value from register
 */
u32 __genwqe_readl(struct genwqe_dev *cd, u64 byte_offs)
{
	if (cd->err_inject & GENWQE_INJECT_HARDWARE_FAILURE)
		return 0xffffffff;

	if (cd->mmio == NULL)
		return 0xffffffff;

	return be32_to_cpu((__force __be32)__raw_readl(cd->mmio + byte_offs));
}

/**
 * genwqe_read_app_id() - Extract app_id
 *
 * app_unitcfg need to be filled with valid data first
 */
int genwqe_read_app_id(struct genwqe_dev *cd, char *app_name, int len)
{
	int i, j;
	u32 app_id = (u32)cd->app_unitcfg;

	memset(app_name, 0, len);
	for (i = 0, j = 0; j < min(len, 4); j++) {
		char ch = (char)((app_id >> (24 - j*8)) & 0xff);

		if (ch == ' ')
			continue;
		app_name[i++] = isprint(ch) ? ch : 'X';
	}
	return i;
}

/**
 * genwqe_init_crc32() - Prepare a lookup table for fast crc32 calculations
 *
 * Existing kernel functions seem to use a different polynom,
 * therefore we could not use them here.
 *
 * Genwqe's Polynomial = 0x20044009
 */
#define CRC32_POLYNOMIAL	0x20044009
static u32 crc32_tab[256];	/* crc32 lookup table */

void genwqe_init_crc32(void)
{
	int i, j;
	u32 crc;

	for (i = 0;  i < 256;  i++) {
		crc = i << 24;
		for (j = 0;  j < 8;  j++) {
			if (crc & 0x80000000)
				crc = (crc << 1) ^ CRC32_POLYNOMIAL;
			else
				crc = (crc << 1);
		}
		crc32_tab[i] = crc;
	}
}

/**
 * genwqe_crc32() - Generate 32-bit crc as required for DDCBs
 * @buff:       pointer to data buffer
 * @len:        length of data for calculation
 * @init:       initial crc (0xffffffff at start)
 *
 * polynomial = x^32 * + x^29 + x^18 + x^14 + x^3 + 1 (0x20044009)

 * Example: 4 bytes 0x01 0x02 0x03 0x04 with init=0xffffffff should
 * result in a crc32 of 0xf33cb7d3.
 *
 * The existing kernel crc functions did not cover this polynom yet.
 *
 * Return: crc32 checksum.
 */
u32 genwqe_crc32(u8 *buff, size_t len, u32 init)
{
	int i;
	u32 crc;

	crc = init;
	while (len--) {
		i = ((crc >> 24) ^ *buff++) & 0xFF;
		crc = (crc << 8) ^ crc32_tab[i];
	}
	return crc;
}

void *__genwqe_alloc_consistent(struct genwqe_dev *cd, size_t size,
			       dma_addr_t *dma_handle)
{
	if (get_order(size) > MAX_ORDER)
		return NULL;

	return pci_alloc_consistent(cd->pci_dev, size, dma_handle);
}

void __genwqe_free_consistent(struct genwqe_dev *cd, size_t size,
			     void *vaddr, dma_addr_t dma_handle)
{
	if (vaddr == NULL)
		return;

	pci_free_consistent(cd->pci_dev, size, vaddr, dma_handle);
}

static void genwqe_unmap_pages(struct genwqe_dev *cd, dma_addr_t *dma_list,
			      int num_pages)
{
	int i;
	struct pci_dev *pci_dev = cd->pci_dev;

	for (i = 0; (i < num_pages) && (dma_list[i] != 0x0); i++) {
		pci_unmap_page(pci_dev, dma_list[i],
			       PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
		dma_list[i] = 0x0;
	}
}

static int genwqe_map_pages(struct genwqe_dev *cd,
			   struct page **page_list, int num_pages,
			   dma_addr_t *dma_list)
{
	int i;
	struct pci_dev *pci_dev = cd->pci_dev;

	/* establish DMA mapping for requested pages */
	for (i = 0; i < num_pages; i++) {
		dma_addr_t daddr;

		dma_list[i] = 0x0;
		daddr = pci_map_page(pci_dev, page_list[i],
				     0,	 /* map_offs */
				     PAGE_SIZE,
				     PCI_DMA_BIDIRECTIONAL);  /* FIXME rd/rw */

		if (pci_dma_mapping_error(pci_dev, daddr)) {
			dev_err(&pci_dev->dev,
				"[%s] err: no dma addr daddr=%016llx!\n",
				__func__, (long long)daddr);
			goto err;
		}

		dma_list[i] = daddr;
	}
	return 0;

 err:
	genwqe_unmap_pages(cd, dma_list, num_pages);
	return -EIO;
}

static int genwqe_sgl_size(int num_pages)
{
	int len, num_tlb = num_pages / 7;

	len = sizeof(struct sg_entry) * (num_pages+num_tlb + 1);
	return roundup(len, PAGE_SIZE);
}

/**
 * genwqe_alloc_sync_sgl() - Allocate memory for sgl and overlapping pages
 *
 * Allocates memory for sgl and overlapping pages. Pages which might
 * overlap other user-space memory blocks are being cached for DMAs,
 * such that we do not run into syncronization issues. Data is copied
 * from user-space into the cached pages.
 */
int genwqe_alloc_sync_sgl(struct genwqe_dev *cd, struct genwqe_sgl *sgl,
			  void __user *user_addr, size_t user_size)
{
	int rc;
	struct pci_dev *pci_dev = cd->pci_dev;

	sgl->fpage_offs = offset_in_page((unsigned long)user_addr);
	sgl->fpage_size = min_t(size_t, PAGE_SIZE-sgl->fpage_offs, user_size);
	sgl->nr_pages = DIV_ROUND_UP(sgl->fpage_offs + user_size, PAGE_SIZE);
	sgl->lpage_size = (user_size - sgl->fpage_size) % PAGE_SIZE;

	dev_dbg(&pci_dev->dev, "[%s] uaddr=%p usize=%8ld nr_pages=%ld fpage_offs=%lx fpage_size=%ld lpage_size=%ld\n",
		__func__, user_addr, user_size, sgl->nr_pages,
		sgl->fpage_offs, sgl->fpage_size, sgl->lpage_size);

	sgl->user_addr = user_addr;
	sgl->user_size = user_size;
	sgl->sgl_size = genwqe_sgl_size(sgl->nr_pages);

	if (get_order(sgl->sgl_size) > MAX_ORDER) {
		dev_err(&pci_dev->dev,
			"[%s] err: too much memory requested!\n", __func__);
		return -ENOMEM;
	}

	sgl->sgl = __genwqe_alloc_consistent(cd, sgl->sgl_size,
					     &sgl->sgl_dma_addr);
	if (sgl->sgl == NULL) {
		dev_err(&pci_dev->dev,
			"[%s] err: no memory available!\n", __func__);
		return -ENOMEM;
	}

	/* Only use buffering on incomplete pages */
	if ((sgl->fpage_size != 0) && (sgl->fpage_size != PAGE_SIZE)) {
		sgl->fpage = __genwqe_alloc_consistent(cd, PAGE_SIZE,
						       &sgl->fpage_dma_addr);
		if (sgl->fpage == NULL)
			goto err_out;

		/* Sync with user memory */
		if (copy_from_user(sgl->fpage + sgl->fpage_offs,
				   user_addr, sgl->fpage_size)) {
			rc = -EFAULT;
			goto err_out;
		}
	}
	if (sgl->lpage_size != 0) {
		sgl->lpage = __genwqe_alloc_consistent(cd, PAGE_SIZE,
						       &sgl->lpage_dma_addr);
		if (sgl->lpage == NULL)
			goto err_out1;

		/* Sync with user memory */
		if (copy_from_user(sgl->lpage, user_addr + user_size -
				   sgl->lpage_size, sgl->lpage_size)) {
			rc = -EFAULT;
			goto err_out1;
		}
	}
	return 0;

 err_out1:
	__genwqe_free_consistent(cd, PAGE_SIZE, sgl->fpage,
				 sgl->fpage_dma_addr);
 err_out:
	__genwqe_free_consistent(cd, sgl->sgl_size, sgl->sgl,
				 sgl->sgl_dma_addr);
	return -ENOMEM;
}

int genwqe_setup_sgl(struct genwqe_dev *cd, struct genwqe_sgl *sgl,
		     dma_addr_t *dma_list)
{
	int i = 0, j = 0, p;
	unsigned long dma_offs, map_offs;
	dma_addr_t prev_daddr = 0;
	struct sg_entry *s, *last_s = NULL;
	size_t size = sgl->user_size;

	dma_offs = 128;		/* next block if needed/dma_offset */
	map_offs = sgl->fpage_offs; /* offset in first page */

	s = &sgl->sgl[0];	/* first set of 8 entries */
	p = 0;			/* page */
	while (p < sgl->nr_pages) {
		dma_addr_t daddr;
		unsigned int size_to_map;

		/* always write the chaining entry, cleanup is done later */
		j = 0;
		s[j].target_addr = cpu_to_be64(sgl->sgl_dma_addr + dma_offs);
		s[j].len	 = cpu_to_be32(128);
		s[j].flags	 = cpu_to_be32(SG_CHAINED);
		j++;

		while (j < 8) {
			/* DMA mapping for requested page, offs, size */
			size_to_map = min(size, PAGE_SIZE - map_offs);

			if ((p == 0) && (sgl->fpage != NULL)) {
				daddr = sgl->fpage_dma_addr + map_offs;

			} else if ((p == sgl->nr_pages - 1) &&
				   (sgl->lpage != NULL)) {
				daddr = sgl->lpage_dma_addr;
			} else {
				daddr = dma_list[p] + map_offs;
			}

			size -= size_to_map;
			map_offs = 0;

			if (prev_daddr == daddr) {
				u32 prev_len = be32_to_cpu(last_s->len);

				/* pr_info("daddr combining: "
					"%016llx/%08x -> %016llx\n",
					prev_daddr, prev_len, daddr); */

				last_s->len = cpu_to_be32(prev_len +
							  size_to_map);

				p++; /* process next page */
				if (p == sgl->nr_pages)
					goto fixup;  /* nothing to do */

				prev_daddr = daddr + size_to_map;
				continue;
			}

			/* start new entry */
			s[j].target_addr = cpu_to_be64(daddr);
			s[j].len	 = cpu_to_be32(size_to_map);
			s[j].flags	 = cpu_to_be32(SG_DATA);
			prev_daddr = daddr + size_to_map;
			last_s = &s[j];
			j++;

			p++;	/* process next page */
			if (p == sgl->nr_pages)
				goto fixup;  /* nothing to do */
		}
		dma_offs += 128;
		s += 8;		/* continue 8 elements further */
	}
 fixup:
	if (j == 1) {		/* combining happend on last entry! */
		s -= 8;		/* full shift needed on previous sgl block */
		j =  7;		/* shift all elements */
	}

	for (i = 0; i < j; i++)	/* move elements 1 up */
		s[i] = s[i + 1];

	s[i].target_addr = cpu_to_be64(0);
	s[i].len	 = cpu_to_be32(0);
	s[i].flags	 = cpu_to_be32(SG_END_LIST);
	return 0;
}

/**
 * genwqe_free_sync_sgl() - Free memory for sgl and overlapping pages
 *
 * After the DMA transfer has been completed we free the memory for
 * the sgl and the cached pages. Data is being transfered from cached
 * pages into user-space buffers.
 */
int genwqe_free_sync_sgl(struct genwqe_dev *cd, struct genwqe_sgl *sgl)
{
	int rc = 0;
	struct pci_dev *pci_dev = cd->pci_dev;

	if (sgl->fpage) {
		if (copy_to_user(sgl->user_addr, sgl->fpage + sgl->fpage_offs,
				 sgl->fpage_size)) {
			dev_err(&pci_dev->dev, "[%s] err: copying fpage!\n",
				__func__);
			rc = -EFAULT;
		}
		__genwqe_free_consistent(cd, PAGE_SIZE, sgl->fpage,
					 sgl->fpage_dma_addr);
		sgl->fpage = NULL;
		sgl->fpage_dma_addr = 0;
	}
	if (sgl->lpage) {
		if (copy_to_user(sgl->user_addr + sgl->user_size -
				 sgl->lpage_size, sgl->lpage,
				 sgl->lpage_size)) {
			dev_err(&pci_dev->dev, "[%s] err: copying lpage!\n",
				__func__);
			rc = -EFAULT;
		}
		__genwqe_free_consistent(cd, PAGE_SIZE, sgl->lpage,
					 sgl->lpage_dma_addr);
		sgl->lpage = NULL;
		sgl->lpage_dma_addr = 0;
	}
	__genwqe_free_consistent(cd, sgl->sgl_size, sgl->sgl,
				 sgl->sgl_dma_addr);

	sgl->sgl = NULL;
	sgl->sgl_dma_addr = 0x0;
	sgl->sgl_size = 0;
	return rc;
}

/**
 * free_user_pages() - Give pinned pages back
 *
 * Documentation of get_user_pages is in mm/memory.c:
 *
 * If the page is written to, set_page_dirty (or set_page_dirty_lock,
 * as appropriate) must be called after the page is finished with, and
 * before put_page is called.
 *
 * FIXME Could be of use to others and might belong in the generic
 * code, if others agree. E.g.
 *    ll_free_user_pages in drivers/staging/lustre/lustre/llite/rw26.c
 *    ceph_put_page_vector in net/ceph/pagevec.c
 *    maybe more?
 */
static int free_user_pages(struct page **page_list, unsigned int nr_pages,
			   int dirty)
{
	unsigned int i;

	for (i = 0; i < nr_pages; i++) {
		if (page_list[i] != NULL) {
			if (dirty)
				set_page_dirty_lock(page_list[i]);
			put_page(page_list[i]);
		}
	}
	return 0;
}

/**
 * genwqe_user_vmap() - Map user-space memory to virtual kernel memory
 * @cd:         pointer to genwqe device
 * @m:          mapping params
 * @uaddr:      user virtual address
 * @size:       size of memory to be mapped
 *
 * We need to think about how we could speed this up. Of course it is
 * not a good idea to do this over and over again, like we are
 * currently doing it. Nevertheless, I am curious where on the path
 * the performance is spend. Most probably within the memory
 * allocation functions, but maybe also in the DMA mapping code.
 *
 * Restrictions: The maximum size of the possible mapping currently depends
 *               on the amount of memory we can get using kzalloc() for the
 *               page_list and pci_alloc_consistent for the sg_list.
 *               The sg_list is currently itself not scattered, which could
 *               be fixed with some effort. The page_list must be split into
 *               PAGE_SIZE chunks too. All that will make the complicated
 *               code more complicated.
 *
 * Return: 0 if success
 */
int genwqe_user_vmap(struct genwqe_dev *cd, struct dma_mapping *m, void *uaddr,
		     unsigned long size, struct ddcb_requ *req)
{
	int rc = -EINVAL;
	unsigned long data, offs;
	struct pci_dev *pci_dev = cd->pci_dev;

	if ((uaddr == NULL) || (size == 0)) {
		m->size = 0;	/* mark unused and not added */
		return -EINVAL;
	}
	m->u_vaddr = uaddr;
	m->size    = size;

	/* determine space needed for page_list. */
	data = (unsigned long)uaddr;
	offs = offset_in_page(data);
	m->nr_pages = DIV_ROUND_UP(offs + size, PAGE_SIZE);

	m->page_list = kcalloc(m->nr_pages,
			       sizeof(struct page *) + sizeof(dma_addr_t),
			       GFP_KERNEL);
	if (!m->page_list) {
		dev_err(&pci_dev->dev, "err: alloc page_list failed\n");
		m->nr_pages = 0;
		m->u_vaddr = NULL;
		m->size = 0;	/* mark unused and not added */
		return -ENOMEM;
	}
	m->dma_list = (dma_addr_t *)(m->page_list + m->nr_pages);

	/* pin user pages in memory */
	rc = get_user_pages_fast(data & PAGE_MASK, /* page aligned addr */
				 m->nr_pages,
				 1,		/* write by caller */
				 m->page_list);	/* ptrs to pages */
	if (rc < 0)
		goto fail_get_user_pages;

	/* assumption: get_user_pages can be killed by signals. */
	if (rc < m->nr_pages) {
		free_user_pages(m->page_list, rc, 0);
		rc = -EFAULT;
		goto fail_get_user_pages;
	}

	rc = genwqe_map_pages(cd, m->page_list, m->nr_pages, m->dma_list);
	if (rc != 0)
		goto fail_free_user_pages;

	return 0;

 fail_free_user_pages:
	free_user_pages(m->page_list, m->nr_pages, 0);

 fail_get_user_pages:
	kfree(m->page_list);
	m->page_list = NULL;
	m->dma_list = NULL;
	m->nr_pages = 0;
	m->u_vaddr = NULL;
	m->size = 0;		/* mark unused and not added */
	return rc;
}

/**
 * genwqe_user_vunmap() - Undo mapping of user-space mem to virtual kernel
 *                        memory
 * @cd:         pointer to genwqe device
 * @m:          mapping params
 */
int genwqe_user_vunmap(struct genwqe_dev *cd, struct dma_mapping *m,
		       struct ddcb_requ *req)
{
	struct pci_dev *pci_dev = cd->pci_dev;

	if (!dma_mapping_used(m)) {
		dev_err(&pci_dev->dev, "[%s] err: mapping %p not used!\n",
			__func__, m);
		return -EINVAL;
	}

	if (m->dma_list)
		genwqe_unmap_pages(cd, m->dma_list, m->nr_pages);

	if (m->page_list) {
		free_user_pages(m->page_list, m->nr_pages, 1);

		kfree(m->page_list);
		m->page_list = NULL;
		m->dma_list = NULL;
		m->nr_pages = 0;
	}

	m->u_vaddr = NULL;
	m->size = 0;		/* mark as unused and not added */
	return 0;
}

/**
 * genwqe_card_type() - Get chip type SLU Configuration Register
 * @cd:         pointer to the genwqe device descriptor
 * Return: 0: Altera Stratix-IV 230
 *         1: Altera Stratix-IV 530
 *         2: Altera Stratix-V A4
 *         3: Altera Stratix-V A7
 */
u8 genwqe_card_type(struct genwqe_dev *cd)
{
	u64 card_type = cd->slu_unitcfg;

	return (u8)((card_type & IO_SLU_UNITCFG_TYPE_MASK) >> 20);
}

/**
 * genwqe_card_reset() - Reset the card
 * @cd:         pointer to the genwqe device descriptor
 */
int genwqe_card_reset(struct genwqe_dev *cd)
{
	u64 softrst;
	struct pci_dev *pci_dev = cd->pci_dev;

	if (!genwqe_is_privileged(cd))
		return -ENODEV;

	/* new SL */
	__genwqe_writeq(cd, IO_SLC_CFGREG_SOFTRESET, 0x1ull);
	msleep(1000);
	__genwqe_readq(cd, IO_HSU_FIR_CLR);
	__genwqe_readq(cd, IO_APP_FIR_CLR);
	__genwqe_readq(cd, IO_SLU_FIR_CLR);

	/*
	 * Read-modify-write to preserve the stealth bits
	 *
	 * For SL >= 039, Stealth WE bit allows removing
	 * the read-modify-wrote.
	 * r-m-w may require a mask 0x3C to avoid hitting hard
	 * reset again for error reset (should be 0, chicken).
	 */
	softrst = __genwqe_readq(cd, IO_SLC_CFGREG_SOFTRESET) & 0x3cull;
	__genwqe_writeq(cd, IO_SLC_CFGREG_SOFTRESET, softrst | 0x2ull);

	/* give ERRORRESET some time to finish */
	msleep(50);

	if (genwqe_need_err_masking(cd)) {
		dev_info(&pci_dev->dev,
			 "[%s] masking errors for old bitstreams\n", __func__);
		__genwqe_writeq(cd, IO_SLC_MISC_DEBUG, 0x0aull);
	}
	return 0;
}

int genwqe_read_softreset(struct genwqe_dev *cd)
{
	u64 bitstream;

	if (!genwqe_is_privileged(cd))
		return -ENODEV;

	bitstream = __genwqe_readq(cd, IO_SLU_BITSTREAM) & 0x1;
	cd->softreset = (bitstream == 0) ? 0x8ull : 0xcull;
	return 0;
}

/**
 * genwqe_set_interrupt_capability() - Configure MSI capability structure
 * @cd:         pointer to the device
 * Return: 0 if no error
 */
int genwqe_set_interrupt_capability(struct genwqe_dev *cd, int count)
{
	int rc;
	struct pci_dev *pci_dev = cd->pci_dev;

	rc = pci_enable_msi_range(pci_dev, 1, count);
	if (rc < 0)
		return rc;

	cd->flags |= GENWQE_FLAG_MSI_ENABLED;
	return 0;
}

/**
 * genwqe_reset_interrupt_capability() - Undo genwqe_set_interrupt_capability()
 * @cd:         pointer to the device
 */
void genwqe_reset_interrupt_capability(struct genwqe_dev *cd)
{
	struct pci_dev *pci_dev = cd->pci_dev;

	if (cd->flags & GENWQE_FLAG_MSI_ENABLED) {
		pci_disable_msi(pci_dev);
		cd->flags &= ~GENWQE_FLAG_MSI_ENABLED;
	}
}

/**
 * set_reg_idx() - Fill array with data. Ignore illegal offsets.
 * @cd:         card device
 * @r:          debug register array
 * @i:          index to desired entry
 * @m:          maximum possible entries
 * @addr:       addr which is read
 * @index:      index in debug array
 * @val:        read value
 */
static int set_reg_idx(struct genwqe_dev *cd, struct genwqe_reg *r,
		       unsigned int *i, unsigned int m, u32 addr, u32 idx,
		       u64 val)
{
	if (WARN_ON_ONCE(*i >= m))
		return -EFAULT;

	r[*i].addr = addr;
	r[*i].idx = idx;
	r[*i].val = val;
	++*i;
	return 0;
}

static int set_reg(struct genwqe_dev *cd, struct genwqe_reg *r,
		   unsigned int *i, unsigned int m, u32 addr, u64 val)
{
	return set_reg_idx(cd, r, i, m, addr, 0, val);
}

int genwqe_read_ffdc_regs(struct genwqe_dev *cd, struct genwqe_reg *regs,
			 unsigned int max_regs, int all)
{
	unsigned int i, j, idx = 0;
	u32 ufir_addr, ufec_addr, sfir_addr, sfec_addr;
	u64 gfir, sluid, appid, ufir, ufec, sfir, sfec;

	/* Global FIR */
	gfir = __genwqe_readq(cd, IO_SLC_CFGREG_GFIR);
	set_reg(cd, regs, &idx, max_regs, IO_SLC_CFGREG_GFIR, gfir);

	/* UnitCfg for SLU */
	sluid = __genwqe_readq(cd, IO_SLU_UNITCFG); /* 0x00000000 */
	set_reg(cd, regs, &idx, max_regs, IO_SLU_UNITCFG, sluid);

	/* UnitCfg for APP */
	appid = __genwqe_readq(cd, IO_APP_UNITCFG); /* 0x02000000 */
	set_reg(cd, regs, &idx, max_regs, IO_APP_UNITCFG, appid);

	/* Check all chip Units */
	for (i = 0; i < GENWQE_MAX_UNITS; i++) {

		/* Unit FIR */
		ufir_addr = (i << 24) | 0x008;
		ufir = __genwqe_readq(cd, ufir_addr);
		set_reg(cd, regs, &idx, max_regs, ufir_addr, ufir);

		/* Unit FEC */
		ufec_addr = (i << 24) | 0x018;
		ufec = __genwqe_readq(cd, ufec_addr);
		set_reg(cd, regs, &idx, max_regs, ufec_addr, ufec);

		for (j = 0; j < 64; j++) {
			/* wherever there is a primary 1, read the 2ndary */
			if (!all && (!(ufir & (1ull << j))))
				continue;

			sfir_addr = (i << 24) | (0x100 + 8 * j);
			sfir = __genwqe_readq(cd, sfir_addr);
			set_reg(cd, regs, &idx, max_regs, sfir_addr, sfir);

			sfec_addr = (i << 24) | (0x300 + 8 * j);
			sfec = __genwqe_readq(cd, sfec_addr);
			set_reg(cd, regs, &idx, max_regs, sfec_addr, sfec);
		}
	}

	/* fill with invalid data until end */
	for (i = idx; i < max_regs; i++) {
		regs[i].addr = 0xffffffff;
		regs[i].val = 0xffffffffffffffffull;
	}
	return idx;
}

/**
 * genwqe_ffdc_buff_size() - Calculates the number of dump registers
 */
int genwqe_ffdc_buff_size(struct genwqe_dev *cd, int uid)
{
	int entries = 0, ring, traps, traces, trace_entries;
	u32 eevptr_addr, l_addr, d_len, d_type;
	u64 eevptr, val, addr;

	eevptr_addr = GENWQE_UID_OFFS(uid) | IO_EXTENDED_ERROR_POINTER;
	eevptr = __genwqe_readq(cd, eevptr_addr);

	if ((eevptr != 0x0) && (eevptr != -1ull)) {
		l_addr = GENWQE_UID_OFFS(uid) | eevptr;

		while (1) {
			val = __genwqe_readq(cd, l_addr);

			if ((val == 0x0) || (val == -1ull))
				break;

			/* 38:24 */
			d_len  = (val & 0x0000007fff000000ull) >> 24;

			/* 39 */
			d_type = (val & 0x0000008000000000ull) >> 36;

			if (d_type) {	/* repeat */
				entries += d_len;
			} else {	/* size in bytes! */
				entries += d_len >> 3;
			}

			l_addr += 8;
		}
	}

	for (ring = 0; ring < 8; ring++) {
		addr = GENWQE_UID_OFFS(uid) | IO_EXTENDED_DIAG_MAP(ring);
		val = __genwqe_readq(cd, addr);

		if ((val == 0x0ull) || (val == -1ull))
			continue;

		traps = (val >> 24) & 0xff;
		traces = (val >> 16) & 0xff;
		trace_entries = val & 0xffff;

		entries += traps + (traces * trace_entries);
	}
	return entries;
}

/**
 * genwqe_ffdc_buff_read() - Implements LogoutExtendedErrorRegisters procedure
 */
int genwqe_ffdc_buff_read(struct genwqe_dev *cd, int uid,
			  struct genwqe_reg *regs, unsigned int max_regs)
{
	int i, traps, traces, trace, trace_entries, trace_entry, ring;
	unsigned int idx = 0;
	u32 eevptr_addr, l_addr, d_addr, d_len, d_type;
	u64 eevptr, e, val, addr;

	eevptr_addr = GENWQE_UID_OFFS(uid) | IO_EXTENDED_ERROR_POINTER;
	eevptr = __genwqe_readq(cd, eevptr_addr);

	if ((eevptr != 0x0) && (eevptr != 0xffffffffffffffffull)) {
		l_addr = GENWQE_UID_OFFS(uid) | eevptr;
		while (1) {
			e = __genwqe_readq(cd, l_addr);
			if ((e == 0x0) || (e == 0xffffffffffffffffull))
				break;

			d_addr = (e & 0x0000000000ffffffull);	    /* 23:0 */
			d_len  = (e & 0x0000007fff000000ull) >> 24; /* 38:24 */
			d_type = (e & 0x0000008000000000ull) >> 36; /* 39 */
			d_addr |= GENWQE_UID_OFFS(uid);

			if (d_type) {
				for (i = 0; i < (int)d_len; i++) {
					val = __genwqe_readq(cd, d_addr);
					set_reg_idx(cd, regs, &idx, max_regs,
						    d_addr, i, val);
				}
			} else {
				d_len >>= 3; /* Size in bytes! */
				for (i = 0; i < (int)d_len; i++, d_addr += 8) {
					val = __genwqe_readq(cd, d_addr);
					set_reg_idx(cd, regs, &idx, max_regs,
						    d_addr, 0, val);
				}
			}
			l_addr += 8;
		}
	}

	/*
	 * To save time, there are only 6 traces poplulated on Uid=2,
	 * Ring=1. each with iters=512.
	 */
	for (ring = 0; ring < 8; ring++) { /* 0 is fls, 1 is fds,
					      2...7 are ASI rings */
		addr = GENWQE_UID_OFFS(uid) | IO_EXTENDED_DIAG_MAP(ring);
		val = __genwqe_readq(cd, addr);

		if ((val == 0x0ull) || (val == -1ull))
			continue;

		traps = (val >> 24) & 0xff;	/* Number of Traps	*/
		traces = (val >> 16) & 0xff;	/* Number of Traces	*/
		trace_entries = val & 0xffff;	/* Entries per trace	*/

		/* Note: This is a combined loop that dumps both the traps */
		/* (for the trace == 0 case) as well as the traces 1 to    */
		/* 'traces'.						   */
		for (trace = 0; trace <= traces; trace++) {
			u32 diag_sel =
				GENWQE_EXTENDED_DIAG_SELECTOR(ring, trace);

			addr = (GENWQE_UID_OFFS(uid) |
				IO_EXTENDED_DIAG_SELECTOR);
			__genwqe_writeq(cd, addr, diag_sel);

			for (trace_entry = 0;
			     trace_entry < (trace ? trace_entries : traps);
			     trace_entry++) {
				addr = (GENWQE_UID_OFFS(uid) |
					IO_EXTENDED_DIAG_READ_MBX);
				val = __genwqe_readq(cd, addr);
				set_reg_idx(cd, regs, &idx, max_regs, addr,
					    (diag_sel<<16) | trace_entry, val);
			}
		}
	}
	return 0;
}

/**
 * genwqe_write_vreg() - Write register in virtual window
 *
 * Note, these registers are only accessible to the PF through the
 * VF-window. It is not intended for the VF to access.
 */
int genwqe_write_vreg(struct genwqe_dev *cd, u32 reg, u64 val, int func)
{
	__genwqe_writeq(cd, IO_PF_SLC_VIRTUAL_WINDOW, func & 0xf);
	__genwqe_writeq(cd, reg, val);
	return 0;
}

/**
 * genwqe_read_vreg() - Read register in virtual window
 *
 * Note, these registers are only accessible to the PF through the
 * VF-window. It is not intended for the VF to access.
 */
u64 genwqe_read_vreg(struct genwqe_dev *cd, u32 reg, int func)
{
	__genwqe_writeq(cd, IO_PF_SLC_VIRTUAL_WINDOW, func & 0xf);
	return __genwqe_readq(cd, reg);
}

/**
 * genwqe_base_clock_frequency() - Deteremine base clock frequency of the card
 *
 * Note: From a design perspective it turned out to be a bad idea to
 * use codes here to specifiy the frequency/speed values. An old
 * driver cannot understand new codes and is therefore always a
 * problem. Better is to measure out the value or put the
 * speed/frequency directly into a register which is always a valid
 * value for old as well as for new software.
 *
 * Return: Card clock in MHz
 */
int genwqe_base_clock_frequency(struct genwqe_dev *cd)
{
	u16 speed;		/*         MHz  MHz  MHz  MHz */
	static const int speed_grade[] = { 250, 200, 166, 175 };

	speed = (u16)((cd->slu_unitcfg >> 28) & 0x0full);
	if (speed >= ARRAY_SIZE(speed_grade))
		return 0;	/* illegal value */

	return speed_grade[speed];
}

/**
 * genwqe_stop_traps() - Stop traps
 *
 * Before reading out the analysis data, we need to stop the traps.
 */
void genwqe_stop_traps(struct genwqe_dev *cd)
{
	__genwqe_writeq(cd, IO_SLC_MISC_DEBUG_SET, 0xcull);
}

/**
 * genwqe_start_traps() - Start traps
 *
 * After having read the data, we can/must enable the traps again.
 */
void genwqe_start_traps(struct genwqe_dev *cd)
{
	__genwqe_writeq(cd, IO_SLC_MISC_DEBUG_CLR, 0xcull);

	if (genwqe_need_err_masking(cd))
		__genwqe_writeq(cd, IO_SLC_MISC_DEBUG, 0x0aull);
}
