/*
 * Copyright IBM Corp. 2012
 *
 * Author(s):
 *   Jan Glauber <jang@linux.vnet.ibm.com>
 */

#define COMPONENT "zPCI"
#define pr_fmt(fmt) COMPONENT ": " fmt

#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/delay.h>
#include <linux/pci.h>
#include <asm/pci_clp.h>

/*
 * Call Logical Processor
 * Retry logic is handled by the caller.
 */
static inline u8 clp_instr(void *req)
{
	u64 ilpm;
	u8 cc;

	asm volatile (
		"	.insn	rrf,0xb9a00000,%[ilpm],%[req],0x0,0x2\n"
		"	ipm	%[cc]\n"
		"	srl	%[cc],28\n"
		: [cc] "=d" (cc), [ilpm] "=d" (ilpm)
		: [req] "a" (req)
		: "cc", "memory");
	return cc;
}

static void *clp_alloc_block(void)
{
	struct page *page = alloc_pages(GFP_KERNEL, get_order(CLP_BLK_SIZE));
	return (page) ? page_address(page) : NULL;
}

static void clp_free_block(void *ptr)
{
	free_pages((unsigned long) ptr, get_order(CLP_BLK_SIZE));
}

static void clp_store_query_pci_fngrp(struct zpci_dev *zdev,
				      struct clp_rsp_query_pci_grp *response)
{
	zdev->tlb_refresh = response->refresh;
	zdev->dma_mask = response->dasm;
	zdev->msi_addr = response->msia;
	zdev->fmb_update = response->mui;

	pr_debug("Supported number of MSI vectors: %u\n", response->noi);
	switch (response->version) {
	case 1:
		zdev->max_bus_speed = PCIE_SPEED_5_0GT;
		break;
	default:
		zdev->max_bus_speed = PCI_SPEED_UNKNOWN;
		break;
	}
}

static int clp_query_pci_fngrp(struct zpci_dev *zdev, u8 pfgid)
{
	struct clp_req_rsp_query_pci_grp *rrb;
	int rc;

	rrb = clp_alloc_block();
	if (!rrb)
		return -ENOMEM;

	memset(rrb, 0, sizeof(*rrb));
	rrb->request.hdr.len = sizeof(rrb->request);
	rrb->request.hdr.cmd = CLP_QUERY_PCI_FNGRP;
	rrb->response.hdr.len = sizeof(rrb->response);
	rrb->request.pfgid = pfgid;

	rc = clp_instr(rrb);
	if (!rc && rrb->response.hdr.rsp == CLP_RC_OK)
		clp_store_query_pci_fngrp(zdev, &rrb->response);
	else {
		pr_err("Query PCI FNGRP failed with response: %x  cc: %d\n",
			rrb->response.hdr.rsp, rc);
		rc = -EIO;
	}
	clp_free_block(rrb);
	return rc;
}

static int clp_store_query_pci_fn(struct zpci_dev *zdev,
				  struct clp_rsp_query_pci *response)
{
	int i;

	for (i = 0; i < PCI_BAR_COUNT; i++) {
		zdev->bars[i].val = le32_to_cpu(response->bar[i]);
		zdev->bars[i].size = response->bar_size[i];
	}
	zdev->start_dma = response->sdma;
	zdev->end_dma = response->edma;
	zdev->pchid = response->pchid;
	zdev->pfgid = response->pfgid;
	return 0;
}

static int clp_query_pci_fn(struct zpci_dev *zdev, u32 fh)
{
	struct clp_req_rsp_query_pci *rrb;
	int rc;

	rrb = clp_alloc_block();
	if (!rrb)
		return -ENOMEM;

	memset(rrb, 0, sizeof(*rrb));
	rrb->request.hdr.len = sizeof(rrb->request);
	rrb->request.hdr.cmd = CLP_QUERY_PCI_FN;
	rrb->response.hdr.len = sizeof(rrb->response);
	rrb->request.fh = fh;

	rc = clp_instr(rrb);
	if (!rc && rrb->response.hdr.rsp == CLP_RC_OK) {
		rc = clp_store_query_pci_fn(zdev, &rrb->response);
		if (rc)
			goto out;
		if (rrb->response.pfgid)
			rc = clp_query_pci_fngrp(zdev, rrb->response.pfgid);
	} else {
		pr_err("Query PCI failed with response: %x  cc: %d\n",
			 rrb->response.hdr.rsp, rc);
		rc = -EIO;
	}
out:
	clp_free_block(rrb);
	return rc;
}

int clp_add_pci_device(u32 fid, u32 fh, int configured)
{
	struct zpci_dev *zdev;
	int rc;

	zdev = zpci_alloc_device();
	if (IS_ERR(zdev))
		return PTR_ERR(zdev);

	zdev->fh = fh;
	zdev->fid = fid;

	/* Query function properties and update zdev */
	rc = clp_query_pci_fn(zdev, fh);
	if (rc)
		goto error;

	if (configured)
		zdev->state = ZPCI_FN_STATE_CONFIGURED;
	else
		zdev->state = ZPCI_FN_STATE_STANDBY;

	rc = zpci_create_device(zdev);
	if (rc)
		goto error;
	return 0;

error:
	zpci_free_device(zdev);
	return rc;
}

/*
 * Enable/Disable a given PCI function defined by its function handle.
 */
static int clp_set_pci_fn(u32 *fh, u8 nr_dma_as, u8 command)
{
	struct clp_req_rsp_set_pci *rrb;
	int rc, retries = 1000;

	rrb = clp_alloc_block();
	if (!rrb)
		return -ENOMEM;

	do {
		memset(rrb, 0, sizeof(*rrb));
		rrb->request.hdr.len = sizeof(rrb->request);
		rrb->request.hdr.cmd = CLP_SET_PCI_FN;
		rrb->response.hdr.len = sizeof(rrb->response);
		rrb->request.fh = *fh;
		rrb->request.oc = command;
		rrb->request.ndas = nr_dma_as;

		rc = clp_instr(rrb);
		if (rrb->response.hdr.rsp == CLP_RC_SETPCIFN_BUSY) {
			retries--;
			if (retries < 0)
				break;
			msleep(1);
		}
	} while (rrb->response.hdr.rsp == CLP_RC_SETPCIFN_BUSY);

	if (!rc && rrb->response.hdr.rsp == CLP_RC_OK)
		*fh = rrb->response.fh;
	else {
		pr_err("Set PCI FN failed with response: %x  cc: %d\n",
			rrb->response.hdr.rsp, rc);
		rc = -EIO;
	}
	clp_free_block(rrb);
	return rc;
}

int clp_enable_fh(struct zpci_dev *zdev, u8 nr_dma_as)
{
	u32 fh = zdev->fh;
	int rc;

	rc = clp_set_pci_fn(&fh, nr_dma_as, CLP_SET_ENABLE_PCI_FN);
	if (!rc)
		/* Success -> store enabled handle in zdev */
		zdev->fh = fh;
	return rc;
}

int clp_disable_fh(struct zpci_dev *zdev)
{
	u32 fh = zdev->fh;
	int rc;

	if (!zdev_enabled(zdev))
		return 0;

	dev_info(&zdev->pdev->dev, "disabling fn handle: 0x%x\n", fh);
	rc = clp_set_pci_fn(&fh, 0, CLP_SET_DISABLE_PCI_FN);
	if (!rc)
		/* Success -> store disabled handle in zdev */
		zdev->fh = fh;
	else
		dev_err(&zdev->pdev->dev,
			"Failed to disable fn handle: 0x%x\n", fh);
	return rc;
}

static void clp_check_pcifn_entry(struct clp_fh_list_entry *entry)
{
	int present, rc;

	if (!entry->vendor_id)
		return;

	/* TODO: be a little bit more scalable */
	present = zpci_fid_present(entry->fid);

	if (present)
		pr_debug("%s: device %x already present\n", __func__, entry->fid);

	/* skip already used functions */
	if (present && entry->config_state)
		return;

	/* aev 306: function moved to stand-by state */
	if (present && !entry->config_state) {
		/*
		 * The handle is already disabled, that means no iota/irq freeing via
		 * the firmware interfaces anymore. Need to free resources manually
		 * (DMA memory, debug, sysfs)...
		 */
		zpci_stop_device(get_zdev_by_fid(entry->fid));
		return;
	}

	rc = clp_add_pci_device(entry->fid, entry->fh, entry->config_state);
	if (rc)
		pr_err("Failed to add fid: 0x%x\n", entry->fid);
}

int clp_find_pci_devices(void)
{
	struct clp_req_rsp_list_pci *rrb;
	u64 resume_token = 0;
	int entries, i, rc;

	rrb = clp_alloc_block();
	if (!rrb)
		return -ENOMEM;

	do {
		memset(rrb, 0, sizeof(*rrb));
		rrb->request.hdr.len = sizeof(rrb->request);
		rrb->request.hdr.cmd = CLP_LIST_PCI;
		/* store as many entries as possible */
		rrb->response.hdr.len = CLP_BLK_SIZE - LIST_PCI_HDR_LEN;
		rrb->request.resume_token = resume_token;

		/* Get PCI function handle list */
		rc = clp_instr(rrb);
		if (rc || rrb->response.hdr.rsp != CLP_RC_OK) {
			pr_err("List PCI failed with response: 0x%x  cc: %d\n",
				rrb->response.hdr.rsp, rc);
			rc = -EIO;
			goto out;
		}

		WARN_ON_ONCE(rrb->response.entry_size !=
			sizeof(struct clp_fh_list_entry));

		entries = (rrb->response.hdr.len - LIST_PCI_HDR_LEN) /
			rrb->response.entry_size;
		pr_info("Detected number of PCI functions: %u\n", entries);

		/* Store the returned resume token as input for the next call */
		resume_token = rrb->response.resume_token;

		for (i = 0; i < entries; i++)
			clp_check_pcifn_entry(&rrb->response.fh_list[i]);
	} while (resume_token);

	pr_debug("Maximum number of supported PCI functions: %u\n",
		rrb->response.max_fn);
out:
	clp_free_block(rrb);
	return rc;
}
