Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d67288a3 authored by Serge Semin's avatar Serge Semin Committed by Jon Mason
Browse files

NTB: Alter Scratchpads API to support multi-ports devices



Even though there is no any real NTB hardware, which would have both more
than two ports and Scratchpad registers, it is logically correct to have
Scratchpad API accepting a peer port index as well. Intel/AMD drivers utilize
Primary and Secondary topology to split Scratchpad between connected root
devices. Since port-index API introduced, Intel/AMD NTB hardware drivers can
use device port to determine which Scratchpad registers actually belong to
local and peer devices. The same approach can be used if some potential
hardware in future will be multi-port and have some set of Scratchpads.
Here are the brief of changes in the API:
 ntb_spad_count() - return number of Scratchpads per each port
 ntb_peer_spad_addr(pidx, sidx) - address of Scratchpad register of the
peer device with pidx-index
 ntb_peer_spad_read(pidx, sidx) - read specified Scratchpad register of the
peer with pidx-index
 ntb_peer_spad_write(pidx, sidx) - write data to Scratchpad register of the
peer with pidx-index

Since there is hardware which doesn't support Scratchpad registers, the
corresponding API methods are now made optional.

Signed-off-by: default avatarSerge Semin <fancer.lancer@gmail.com>
Acked-by: default avatarAllen Hubbe <Allen.Hubbe@dell.com>
Signed-off-by: default avatarJon Mason <jdmason@kudzu.us>
parent 443b9a14
Loading
Loading
Loading
Loading
+7 −7
Original line number Original line Diff line number Diff line
@@ -432,30 +432,30 @@ static int amd_ntb_spad_write(struct ntb_dev *ntb,
	return 0;
	return 0;
}
}


static u32 amd_ntb_peer_spad_read(struct ntb_dev *ntb, int idx)
static u32 amd_ntb_peer_spad_read(struct ntb_dev *ntb, int pidx, int sidx)
{
{
	struct amd_ntb_dev *ndev = ntb_ndev(ntb);
	struct amd_ntb_dev *ndev = ntb_ndev(ntb);
	void __iomem *mmio = ndev->self_mmio;
	void __iomem *mmio = ndev->self_mmio;
	u32 offset;
	u32 offset;


	if (idx < 0 || idx >= ndev->spad_count)
	if (sidx < 0 || sidx >= ndev->spad_count)
		return -EINVAL;
		return -EINVAL;


	offset = ndev->peer_spad + (idx << 2);
	offset = ndev->peer_spad + (sidx << 2);
	return readl(mmio + AMD_SPAD_OFFSET + offset);
	return readl(mmio + AMD_SPAD_OFFSET + offset);
}
}


static int amd_ntb_peer_spad_write(struct ntb_dev *ntb,
static int amd_ntb_peer_spad_write(struct ntb_dev *ntb, int pidx,
				   int idx, u32 val)
				   int sidx, u32 val)
{
{
	struct amd_ntb_dev *ndev = ntb_ndev(ntb);
	struct amd_ntb_dev *ndev = ntb_ndev(ntb);
	void __iomem *mmio = ndev->self_mmio;
	void __iomem *mmio = ndev->self_mmio;
	u32 offset;
	u32 offset;


	if (idx < 0 || idx >= ndev->spad_count)
	if (sidx < 0 || sidx >= ndev->spad_count)
		return -EINVAL;
		return -EINVAL;


	offset = ndev->peer_spad + (idx << 2);
	offset = ndev->peer_spad + (sidx << 2);
	writel(val, mmio + AMD_SPAD_OFFSET + offset);
	writel(val, mmio + AMD_SPAD_OFFSET + offset);


	return 0;
	return 0;
+7 −7
Original line number Original line Diff line number Diff line
@@ -1409,30 +1409,30 @@ static int intel_ntb_spad_write(struct ntb_dev *ntb,
			       ndev->self_reg->spad);
			       ndev->self_reg->spad);
}
}


static int intel_ntb_peer_spad_addr(struct ntb_dev *ntb, int idx,
static int intel_ntb_peer_spad_addr(struct ntb_dev *ntb, int pidx, int sidx,
				    phys_addr_t *spad_addr)
				    phys_addr_t *spad_addr)
{
{
	struct intel_ntb_dev *ndev = ntb_ndev(ntb);
	struct intel_ntb_dev *ndev = ntb_ndev(ntb);


	return ndev_spad_addr(ndev, idx, spad_addr, ndev->peer_addr,
	return ndev_spad_addr(ndev, sidx, spad_addr, ndev->peer_addr,
			      ndev->peer_reg->spad);
			      ndev->peer_reg->spad);
}
}


static u32 intel_ntb_peer_spad_read(struct ntb_dev *ntb, int idx)
static u32 intel_ntb_peer_spad_read(struct ntb_dev *ntb, int pidx, int sidx)
{
{
	struct intel_ntb_dev *ndev = ntb_ndev(ntb);
	struct intel_ntb_dev *ndev = ntb_ndev(ntb);


	return ndev_spad_read(ndev, idx,
	return ndev_spad_read(ndev, sidx,
			      ndev->peer_mmio +
			      ndev->peer_mmio +
			      ndev->peer_reg->spad);
			      ndev->peer_reg->spad);
}
}


static int intel_ntb_peer_spad_write(struct ntb_dev *ntb,
static int intel_ntb_peer_spad_write(struct ntb_dev *ntb, int pidx,
				     int idx, u32 val)
				     int sidx, u32 val)
{
{
	struct intel_ntb_dev *ndev = ntb_ndev(ntb);
	struct intel_ntb_dev *ndev = ntb_ndev(ntb);


	return ndev_spad_write(ndev, idx, val,
	return ndev_spad_write(ndev, sidx, val,
			       ndev->peer_mmio +
			       ndev->peer_mmio +
			       ndev->peer_reg->spad);
			       ndev->peer_reg->spad);
}
}
+7 −8
Original line number Original line Diff line number Diff line
@@ -862,17 +862,17 @@ static void ntb_transport_link_work(struct work_struct *work)
			size = max_mw_size;
			size = max_mw_size;


		spad = MW0_SZ_HIGH + (i * 2);
		spad = MW0_SZ_HIGH + (i * 2);
		ntb_peer_spad_write(ndev, spad, upper_32_bits(size));
		ntb_peer_spad_write(ndev, PIDX, spad, upper_32_bits(size));


		spad = MW0_SZ_LOW + (i * 2);
		spad = MW0_SZ_LOW + (i * 2);
		ntb_peer_spad_write(ndev, spad, lower_32_bits(size));
		ntb_peer_spad_write(ndev, PIDX, spad, lower_32_bits(size));
	}
	}


	ntb_peer_spad_write(ndev, NUM_MWS, nt->mw_count);
	ntb_peer_spad_write(ndev, PIDX, NUM_MWS, nt->mw_count);


	ntb_peer_spad_write(ndev, NUM_QPS, nt->qp_count);
	ntb_peer_spad_write(ndev, PIDX, NUM_QPS, nt->qp_count);


	ntb_peer_spad_write(ndev, VERSION, NTB_TRANSPORT_VERSION);
	ntb_peer_spad_write(ndev, PIDX, VERSION, NTB_TRANSPORT_VERSION);


	/* Query the remote side for its info */
	/* Query the remote side for its info */
	val = ntb_spad_read(ndev, VERSION);
	val = ntb_spad_read(ndev, VERSION);
@@ -948,7 +948,7 @@ static void ntb_qp_link_work(struct work_struct *work)


	val = ntb_spad_read(nt->ndev, QP_LINKS);
	val = ntb_spad_read(nt->ndev, QP_LINKS);


	ntb_peer_spad_write(nt->ndev, QP_LINKS, val | BIT(qp->qp_num));
	ntb_peer_spad_write(nt->ndev, PIDX, QP_LINKS, val | BIT(qp->qp_num));


	/* query remote spad for qp ready bits */
	/* query remote spad for qp ready bits */
	dev_dbg_ratelimited(&pdev->dev, "Remote QP link status = %x\n", val);
	dev_dbg_ratelimited(&pdev->dev, "Remote QP link status = %x\n", val);
@@ -2108,8 +2108,7 @@ void ntb_transport_link_down(struct ntb_transport_qp *qp)


	val = ntb_spad_read(qp->ndev, QP_LINKS);
	val = ntb_spad_read(qp->ndev, QP_LINKS);


	ntb_peer_spad_write(qp->ndev, QP_LINKS,
	ntb_peer_spad_write(qp->ndev, PIDX, QP_LINKS, val & ~BIT(qp->qp_num));
			    val & ~BIT(qp->qp_num));


	if (qp->link_is_up)
	if (qp->link_is_up)
		ntb_send_link_down(qp);
		ntb_send_link_down(qp);
+3 −3
Original line number Original line Diff line number Diff line
@@ -518,9 +518,9 @@ static void perf_link_work(struct work_struct *work)
	if (max_mw_size && size > max_mw_size)
	if (max_mw_size && size > max_mw_size)
		size = max_mw_size;
		size = max_mw_size;


	ntb_peer_spad_write(ndev, MW_SZ_HIGH, upper_32_bits(size));
	ntb_peer_spad_write(ndev, PIDX, MW_SZ_HIGH, upper_32_bits(size));
	ntb_peer_spad_write(ndev, MW_SZ_LOW, lower_32_bits(size));
	ntb_peer_spad_write(ndev, PIDX, MW_SZ_LOW, lower_32_bits(size));
	ntb_peer_spad_write(ndev, VERSION, PERF_VERSION);
	ntb_peer_spad_write(ndev, PIDX, VERSION, PERF_VERSION);


	/* now read what peer wrote */
	/* now read what peer wrote */
	val = ntb_spad_read(ndev, VERSION);
	val = ntb_spad_read(ndev, VERSION);
+7 −1
Original line number Original line Diff line number Diff line
@@ -138,7 +138,7 @@ static void pp_ping(unsigned long ctx)
			"Ping bits %#llx read %#x write %#x\n",
			"Ping bits %#llx read %#x write %#x\n",
			db_bits, spad_rd, spad_wr);
			db_bits, spad_rd, spad_wr);


		ntb_peer_spad_write(pp->ntb, 0, spad_wr);
		ntb_peer_spad_write(pp->ntb, PIDX, 0, spad_wr);
		ntb_peer_db_set(pp->ntb, db_bits);
		ntb_peer_db_set(pp->ntb, db_bits);
		ntb_db_clear_mask(pp->ntb, db_mask);
		ntb_db_clear_mask(pp->ntb, db_mask);


@@ -225,6 +225,12 @@ static int pp_probe(struct ntb_client *client,
		}
		}
	}
	}


	if (ntb_spad_count(ntb) < 1) {
		dev_dbg(&ntb->dev, "no enough scratchpads\n");
		rc = -EINVAL;
		goto err_pp;
	}

	if (ntb_spad_is_unsafe(ntb)) {
	if (ntb_spad_is_unsafe(ntb)) {
		dev_dbg(&ntb->dev, "scratchpad is unsafe\n");
		dev_dbg(&ntb->dev, "scratchpad is unsafe\n");
		if (!unsafe) {
		if (!unsafe) {
Loading