/*
 * drivers/pci/ats.c
 *
 * Copyright (C) 2009 Intel Corporation, Yu Zhao <yu.zhao@intel.com>
 * Copyright (C) 2011 Advanced Micro Devices,
 *
 * PCI Express I/O Virtualization (IOV) support.
 *   Address Translation Service 1.0
 *   Page Request Interface added by Joerg Roedel <joerg.roedel@amd.com>
 *   PASID support added by Joerg Roedel <joerg.roedel@amd.com>
 */

#include <linux/pci-ats.h>
#include <linux/pci.h>

#include "pci.h"

static int ats_alloc_one(struct pci_dev *dev, int ps)
{
	int pos;
	u16 cap;
	struct pci_ats *ats;

	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ATS);
	if (!pos)
		return -ENODEV;

	ats = kzalloc(sizeof(*ats), GFP_KERNEL);
	if (!ats)
		return -ENOMEM;

	ats->pos = pos;
	ats->stu = ps;
	pci_read_config_word(dev, pos + PCI_ATS_CAP, &cap);
	ats->qdep = PCI_ATS_CAP_QDEP(cap) ? PCI_ATS_CAP_QDEP(cap) :
					    PCI_ATS_MAX_QDEP;
	dev->ats = ats;

	return 0;
}

static void ats_free_one(struct pci_dev *dev)
{
	kfree(dev->ats);
	dev->ats = NULL;
}

/**
 * pci_enable_ats - enable the ATS capability
 * @dev: the PCI device
 * @ps: the IOMMU page shift
 *
 * Returns 0 on success, or negative on failure.
 */
int pci_enable_ats(struct pci_dev *dev, int ps)
{
	int rc;
	u16 ctrl;

	BUG_ON(dev->ats && dev->ats->is_enabled);

	if (ps < PCI_ATS_MIN_STU)
		return -EINVAL;

	if (dev->is_physfn || dev->is_virtfn) {
		struct pci_dev *pdev = dev->is_physfn ? dev : dev->physfn;

		mutex_lock(&pdev->sriov->lock);
		if (pdev->ats)
			rc = pdev->ats->stu == ps ? 0 : -EINVAL;
		else
			rc = ats_alloc_one(pdev, ps);

		if (!rc)
			pdev->ats->ref_cnt++;
		mutex_unlock(&pdev->sriov->lock);
		if (rc)
			return rc;
	}

	if (!dev->is_physfn) {
		rc = ats_alloc_one(dev, ps);
		if (rc)
			return rc;
	}

	ctrl = PCI_ATS_CTRL_ENABLE;
	if (!dev->is_virtfn)
		ctrl |= PCI_ATS_CTRL_STU(ps - PCI_ATS_MIN_STU);
	pci_write_config_word(dev, dev->ats->pos + PCI_ATS_CTRL, ctrl);

	dev->ats->is_enabled = 1;

	return 0;
}
EXPORT_SYMBOL_GPL(pci_enable_ats);

/**
 * pci_disable_ats - disable the ATS capability
 * @dev: the PCI device
 */
void pci_disable_ats(struct pci_dev *dev)
{
	u16 ctrl;

	BUG_ON(!dev->ats || !dev->ats->is_enabled);

	pci_read_config_word(dev, dev->ats->pos + PCI_ATS_CTRL, &ctrl);
	ctrl &= ~PCI_ATS_CTRL_ENABLE;
	pci_write_config_word(dev, dev->ats->pos + PCI_ATS_CTRL, ctrl);

	dev->ats->is_enabled = 0;

	if (dev->is_physfn || dev->is_virtfn) {
		struct pci_dev *pdev = dev->is_physfn ? dev : dev->physfn;

		mutex_lock(&pdev->sriov->lock);
		pdev->ats->ref_cnt--;
		if (!pdev->ats->ref_cnt)
			ats_free_one(pdev);
		mutex_unlock(&pdev->sriov->lock);
	}

	if (!dev->is_physfn)
		ats_free_one(dev);
}
EXPORT_SYMBOL_GPL(pci_disable_ats);

/**
 * pci_ats_queue_depth - query the ATS Invalidate Queue Depth
 * @dev: the PCI device
 *
 * Returns the queue depth on success, or negative on failure.
 *
 * The ATS spec uses 0 in the Invalidate Queue Depth field to
 * indicate that the function can accept 32 Invalidate Request.
 * But here we use the `real' values (i.e. 1~32) for the Queue
 * Depth; and 0 indicates the function shares the Queue with
 * other functions (doesn't exclusively own a Queue).
 */
int pci_ats_queue_depth(struct pci_dev *dev)
{
	int pos;
	u16 cap;

	if (dev->is_virtfn)
		return 0;

	if (dev->ats)
		return dev->ats->qdep;

	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ATS);
	if (!pos)
		return -ENODEV;

	pci_read_config_word(dev, pos + PCI_ATS_CAP, &cap);

	return PCI_ATS_CAP_QDEP(cap) ? PCI_ATS_CAP_QDEP(cap) :
				       PCI_ATS_MAX_QDEP;
}
EXPORT_SYMBOL_GPL(pci_ats_queue_depth);

#ifdef CONFIG_PCI_PRI
/**
 * pci_enable_pri - Enable PRI capability
 * @ pdev: PCI device structure
 *
 * Returns 0 on success, negative value on error
 */
int pci_enable_pri(struct pci_dev *pdev, u32 reqs)
{
	u16 control, status;
	u32 max_requests;
	int pos;

	pos = pci_find_ext_capability(pdev, PCI_PRI_CAP);
	if (!pos)
		return -EINVAL;

	pci_read_config_word(pdev, pos + PCI_PRI_CONTROL_OFF, &control);
	pci_read_config_word(pdev, pos + PCI_PRI_STATUS_OFF,  &status);
	if ((control & PCI_PRI_ENABLE) || !(status & PCI_PRI_STATUS_STOPPED))
		return -EBUSY;

	pci_read_config_dword(pdev, pos + PCI_PRI_MAX_REQ_OFF, &max_requests);
	reqs = min(max_requests, reqs);
	pci_write_config_dword(pdev, pos + PCI_PRI_ALLOC_REQ_OFF, reqs);

	control |= PCI_PRI_ENABLE;
	pci_write_config_word(pdev, pos + PCI_PRI_CONTROL_OFF, control);

	return 0;
}
EXPORT_SYMBOL_GPL(pci_enable_pri);

/**
 * pci_disable_pri - Disable PRI capability
 * @pdev: PCI device structure
 *
 * Only clears the enabled-bit, regardless of its former value
 */
void pci_disable_pri(struct pci_dev *pdev)
{
	u16 control;
	int pos;

	pos = pci_find_ext_capability(pdev, PCI_PRI_CAP);
	if (!pos)
		return;

	pci_read_config_word(pdev, pos + PCI_PRI_CONTROL_OFF, &control);
	control &= ~PCI_PRI_ENABLE;
	pci_write_config_word(pdev, pos + PCI_PRI_CONTROL_OFF, control);
}
EXPORT_SYMBOL_GPL(pci_disable_pri);

/**
 * pci_pri_enabled - Checks if PRI capability is enabled
 * @pdev: PCI device structure
 *
 * Returns true if PRI is enabled on the device, false otherwise
 */
bool pci_pri_enabled(struct pci_dev *pdev)
{
	u16 control;
	int pos;

	pos = pci_find_ext_capability(pdev, PCI_PRI_CAP);
	if (!pos)
		return false;

	pci_read_config_word(pdev, pos + PCI_PRI_CONTROL_OFF, &control);

	return (control & PCI_PRI_ENABLE) ? true : false;
}
EXPORT_SYMBOL_GPL(pci_pri_enabled);

/**
 * pci_reset_pri - Resets device's PRI state
 * @pdev: PCI device structure
 *
 * The PRI capability must be disabled before this function is called.
 * Returns 0 on success, negative value on error.
 */
int pci_reset_pri(struct pci_dev *pdev)
{
	u16 control;
	int pos;

	pos = pci_find_ext_capability(pdev, PCI_PRI_CAP);
	if (!pos)
		return -EINVAL;

	pci_read_config_word(pdev, pos + PCI_PRI_CONTROL_OFF, &control);
	if (control & PCI_PRI_ENABLE)
		return -EBUSY;

	control |= PCI_PRI_RESET;

	pci_write_config_word(pdev, pos + PCI_PRI_CONTROL_OFF, control);

	return 0;
}
EXPORT_SYMBOL_GPL(pci_reset_pri);

/**
 * pci_pri_stopped - Checks whether the PRI capability is stopped
 * @pdev: PCI device structure
 *
 * Returns true if the PRI capability on the device is disabled and the
 * device has no outstanding PRI requests, false otherwise. The device
 * indicates this via the STOPPED bit in the status register of the
 * capability.
 * The device internal state can be cleared by resetting the PRI state
 * with pci_reset_pri(). This can force the capability into the STOPPED
 * state.
 */
bool pci_pri_stopped(struct pci_dev *pdev)
{
	u16 control, status;
	int pos;

	pos = pci_find_ext_capability(pdev, PCI_PRI_CAP);
	if (!pos)
		return true;

	pci_read_config_word(pdev, pos + PCI_PRI_CONTROL_OFF, &control);
	pci_read_config_word(pdev, pos + PCI_PRI_STATUS_OFF,  &status);

	if (control & PCI_PRI_ENABLE)
		return false;

	return (status & PCI_PRI_STATUS_STOPPED) ? true : false;
}
EXPORT_SYMBOL_GPL(pci_pri_stopped);

/**
 * pci_pri_status - Request PRI status of a device
 * @pdev: PCI device structure
 *
 * Returns negative value on failure, status on success. The status can
 * be checked against status-bits. Supported bits are currently:
 * PCI_PRI_STATUS_RF:      Response failure
 * PCI_PRI_STATUS_UPRGI:   Unexpected Page Request Group Index
 * PCI_PRI_STATUS_STOPPED: PRI has stopped
 */
int pci_pri_status(struct pci_dev *pdev)
{
	u16 status, control;
	int pos;

	pos = pci_find_ext_capability(pdev, PCI_PRI_CAP);
	if (!pos)
		return -EINVAL;

	pci_read_config_word(pdev, pos + PCI_PRI_CONTROL_OFF, &control);
	pci_read_config_word(pdev, pos + PCI_PRI_STATUS_OFF,  &status);

	/* Stopped bit is undefined when enable == 1, so clear it */
	if (control & PCI_PRI_ENABLE)
		status &= ~PCI_PRI_STATUS_STOPPED;

	return status;
}
EXPORT_SYMBOL_GPL(pci_pri_status);
#endif /* CONFIG_PCI_PRI */

#ifdef CONFIG_PCI_PASID
/**
 * pci_enable_pasid - Enable the PASID capability
 * @pdev: PCI device structure
 * @features: Features to enable
 *
 * Returns 0 on success, negative value on error. This function checks
 * whether the features are actually supported by the device and returns
 * an error if not.
 */
int pci_enable_pasid(struct pci_dev *pdev, int features)
{
	u16 control, supported;
	int pos;

	pos = pci_find_ext_capability(pdev, PCI_PASID_CAP);
	if (!pos)
		return -EINVAL;

	pci_read_config_word(pdev, pos + PCI_PASID_CONTROL_OFF, &control);
	pci_read_config_word(pdev, pos + PCI_PASID_CAP_OFF,     &supported);

	if (!(supported & PCI_PASID_ENABLE))
		return -EINVAL;

	supported &= PCI_PASID_EXEC | PCI_PASID_PRIV;

	/* User wants to enable anything unsupported? */
	if ((supported & features) != features)
		return -EINVAL;

	control = PCI_PASID_ENABLE | features;

	pci_write_config_word(pdev, pos + PCI_PASID_CONTROL_OFF, control);

	return 0;
}
EXPORT_SYMBOL_GPL(pci_enable_pasid);

/**
 * pci_disable_pasid - Disable the PASID capability
 * @pdev: PCI device structure
 *
 */
void pci_disable_pasid(struct pci_dev *pdev)
{
	u16 control = 0;
	int pos;

	pos = pci_find_ext_capability(pdev, PCI_PASID_CAP);
	if (!pos)
		return;

	pci_write_config_word(pdev, pos + PCI_PASID_CONTROL_OFF, control);
}
EXPORT_SYMBOL_GPL(pci_disable_pasid);

/**
 * pci_pasid_features - Check which PASID features are supported
 * @pdev: PCI device structure
 *
 * Returns a negative value when no PASI capability is present.
 * Otherwise is returns a bitmask with supported features. Current
 * features reported are:
 * PCI_PASID_ENABLE - PASID capability can be enabled
 * PCI_PASID_EXEC - Execute permission supported
 * PCI_PASID_PRIV - Priviledged mode supported
 */
int pci_pasid_features(struct pci_dev *pdev)
{
	u16 supported;
	int pos;

	pos = pci_find_ext_capability(pdev, PCI_PASID_CAP);
	if (!pos)
		return -EINVAL;

	pci_read_config_word(pdev, pos + PCI_PASID_CAP_OFF, &supported);

	supported &= PCI_PASID_ENABLE | PCI_PASID_EXEC | PCI_PASID_PRIV;

	return supported;
}
EXPORT_SYMBOL_GPL(pci_pasid_features);

#define PASID_NUMBER_SHIFT	8
#define PASID_NUMBER_MASK	(0x1f << PASID_NUMBER_SHIFT)
/**
 * pci_max_pasid - Get maximum number of PASIDs supported by device
 * @pdev: PCI device structure
 *
 * Returns negative value when PASID capability is not present.
 * Otherwise it returns the numer of supported PASIDs.
 */
int pci_max_pasids(struct pci_dev *pdev)
{
	u16 supported;
	int pos;

	pos = pci_find_ext_capability(pdev, PCI_PASID_CAP);
	if (!pos)
		return -EINVAL;

	pci_read_config_word(pdev, pos + PCI_PASID_CAP_OFF, &supported);

	supported = (supported & PASID_NUMBER_MASK) >> PASID_NUMBER_SHIFT;

	return (1 << supported);
}
EXPORT_SYMBOL_GPL(pci_max_pasids);
#endif /* CONFIG_PCI_PASID */
