Exemple #1
0
static int amd_ntb_mw_get_align(struct ntb_dev *ntb, int pidx, int idx,
				resource_size_t *addr_align,
				resource_size_t *size_align,
				resource_size_t *size_max)
{
	struct amd_ntb_dev *ndev = ntb_ndev(ntb);
	int bar;

	if (pidx != NTB_DEF_PEER_IDX)
		return -EINVAL;

	bar = ndev_mw_to_bar(ndev, idx);
	if (bar < 0)
		return bar;

	if (addr_align)
		*addr_align = SZ_4K;

	if (size_align)
		*size_align = 1;

	if (size_max)
		*size_max = pci_resource_len(ndev->ntb.pdev, bar);

	return 0;
}
Exemple #2
0
static int amd_ntb_mw_get_range(struct ntb_dev *ntb, int idx,
				phys_addr_t *base,
				resource_size_t *size,
				resource_size_t *align,
				resource_size_t *align_size)
{
	struct amd_ntb_dev *ndev = ntb_ndev(ntb);
	int bar;

	bar = ndev_mw_to_bar(ndev, idx);
	if (bar < 0)
		return bar;

	if (base)
		*base = pci_resource_start(ndev->ntb.pdev, bar);

	if (size)
		*size = pci_resource_len(ndev->ntb.pdev, bar);

	if (align)
		*align = SZ_4K;

	if (align_size)
		*align_size = 1;

	return 0;
}
Exemple #3
0
static int amd_ntb_peer_mw_get_addr(struct ntb_dev *ntb, int idx,
				    phys_addr_t *base, resource_size_t *size)
{
	struct amd_ntb_dev *ndev = ntb_ndev(ntb);
	int bar;

	bar = ndev_mw_to_bar(ndev, idx);
	if (bar < 0)
		return bar;

	if (base)
		*base = pci_resource_start(ndev->ntb.pdev, bar);

	if (size)
		*size = pci_resource_len(ndev->ntb.pdev, bar);

	return 0;
}
Exemple #4
0
static int amd_ntb_mw_set_trans(struct ntb_dev *ntb, int pidx, int idx,
				dma_addr_t addr, resource_size_t size)
{
	struct amd_ntb_dev *ndev = ntb_ndev(ntb);
	unsigned long xlat_reg, limit_reg = 0;
	resource_size_t mw_size;
	void __iomem *mmio, *peer_mmio;
	u64 base_addr, limit, reg_val;
	int bar;

	if (pidx != NTB_DEF_PEER_IDX)
		return -EINVAL;

	bar = ndev_mw_to_bar(ndev, idx);
	if (bar < 0)
		return bar;

	mw_size = pci_resource_len(ntb->pdev, bar);

	/* make sure the range fits in the usable mw size */
	if (size > mw_size)
		return -EINVAL;

	mmio = ndev->self_mmio;
	peer_mmio = ndev->peer_mmio;

	base_addr = pci_resource_start(ntb->pdev, bar);

	if (bar != 1) {
		xlat_reg = AMD_BAR23XLAT_OFFSET + ((bar - 2) << 2);
		limit_reg = AMD_BAR23LMT_OFFSET + ((bar - 2) << 2);

		/* Set the limit if supported */
		limit = size;

		/* set and verify setting the translation address */
		write64(addr, peer_mmio + xlat_reg);
		reg_val = read64(peer_mmio + xlat_reg);
		if (reg_val != addr) {
			write64(0, peer_mmio + xlat_reg);
			return -EIO;
		}

		/* set and verify setting the limit */
		write64(limit, peer_mmio + limit_reg);
		reg_val = read64(peer_mmio + limit_reg);
		if (reg_val != limit) {
			write64(base_addr, mmio + limit_reg);
			write64(0, peer_mmio + xlat_reg);
			return -EIO;
		}
	} else {
		xlat_reg = AMD_BAR1XLAT_OFFSET;
		limit_reg = AMD_BAR1LMT_OFFSET;

		/* Set the limit if supported */
		limit = size;

		/* set and verify setting the translation address */
		write64(addr, peer_mmio + xlat_reg);
		reg_val = read64(peer_mmio + xlat_reg);
		if (reg_val != addr) {
			write64(0, peer_mmio + xlat_reg);
			return -EIO;
		}

		/* set and verify setting the limit */
		writel(limit, peer_mmio + limit_reg);
		reg_val = readl(peer_mmio + limit_reg);
		if (reg_val != limit) {
			writel(base_addr, mmio + limit_reg);
			writel(0, peer_mmio + xlat_reg);
			return -EIO;
		}
	}

	return 0;
}