Commit e8a71a38 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'ntb-5.1' of git://github.com/jonmason/ntb

Pull NTB updates from Jon Mason:

 - fixes for switchtec debugability and mapping table entries

 - NTB transport improvements

 - a reworking of the peer_db_addr for better abstraction

* tag 'ntb-5.1' of git://github.com/jonmason/ntb:
  NTB: add new parameter to peer_db_addr() db_bit and db_data
  NTB: ntb_transport: Ensure the destination buffer is mapped for TX DMA
  NTB: ntb_transport: Free MWs in ntb_transport_link_cleanup()
  ntb_hw_switchtec: Added support of >=4G memory windows
  ntb_hw_switchtec: NT req id mapping table register entry number should be 512
  ntb_hw_switchtec: debug print 64bit aligned crosslink BAR Numbers
parents 2b9c272c ebb09b33
Loading
Loading
Loading
Loading
+19 −6
Original line number Diff line number Diff line
@@ -180,7 +180,7 @@ int ndev_mw_to_bar(struct intel_ntb_dev *ndev, int idx)
	return ndev->reg->mw_bar[idx];
}

static inline int ndev_db_addr(struct intel_ntb_dev *ndev,
void ndev_db_addr(struct intel_ntb_dev *ndev,
			       phys_addr_t *db_addr, resource_size_t *db_size,
			       phys_addr_t reg_addr, unsigned long reg)
{
@@ -196,8 +196,6 @@ static inline int ndev_db_addr(struct intel_ntb_dev *ndev,
		*db_size = ndev->reg->db_size;
		dev_dbg(&ndev->ntb.pdev->dev, "Peer db size %llx\n", *db_size);
	}

	return 0;
}

u64 ndev_db_read(struct intel_ntb_dev *ndev,
@@ -1111,13 +1109,28 @@ int intel_ntb_db_clear_mask(struct ntb_dev *ntb, u64 db_bits)
				  ndev->self_reg->db_mask);
}

int intel_ntb_peer_db_addr(struct ntb_dev *ntb, phys_addr_t *db_addr,
			   resource_size_t *db_size)
static int intel_ntb_peer_db_addr(struct ntb_dev *ntb, phys_addr_t *db_addr,
			   resource_size_t *db_size, u64 *db_data, int db_bit)
{
	u64 db_bits;
	struct intel_ntb_dev *ndev = ntb_ndev(ntb);

	return ndev_db_addr(ndev, db_addr, db_size, ndev->peer_addr,
	if (unlikely(db_bit >= BITS_PER_LONG_LONG))
		return -EINVAL;

	db_bits = BIT_ULL(db_bit);

	if (unlikely(db_bits & ~ntb_ndev(ntb)->db_valid_mask))
		return -EINVAL;

	ndev_db_addr(ndev, db_addr, db_size, ndev->peer_addr,
			    ndev->peer_reg->db_bell);

	if (db_data)
		*db_data = db_bits;


	return 0;
}

static int intel_ntb_peer_db_set(struct ntb_dev *ntb, u64 db_bits)
+3 −2
Original line number Diff line number Diff line
@@ -147,6 +147,9 @@ extern struct intel_b2b_addr xeon_b2b_dsd_addr;
int ndev_init_isr(struct intel_ntb_dev *ndev, int msix_min, int msix_max,
		int msix_shift, int total_shift);
enum ntb_topo xeon_ppd_topo(struct intel_ntb_dev *ndev, u8 ppd);
void ndev_db_addr(struct intel_ntb_dev *ndev,
				phys_addr_t *db_addr, resource_size_t *db_size,
				phys_addr_t reg_addr, unsigned long reg);
u64 ndev_db_read(struct intel_ntb_dev *ndev, void __iomem *mmio);
int ndev_db_write(struct intel_ntb_dev *ndev, u64 db_bits,
				void __iomem *mmio);
@@ -166,8 +169,6 @@ int intel_ntb_db_vector_count(struct ntb_dev *ntb);
u64 intel_ntb_db_vector_mask(struct ntb_dev *ntb, int db_vector);
int intel_ntb_db_set_mask(struct ntb_dev *ntb, u64 db_bits);
int intel_ntb_db_clear_mask(struct ntb_dev *ntb, u64 db_bits);
int intel_ntb_peer_db_addr(struct ntb_dev *ntb, phys_addr_t *db_addr,
		resource_size_t *db_size);
int intel_ntb_spad_is_unsafe(struct ntb_dev *ntb);
int intel_ntb_spad_count(struct ntb_dev *ntb);
u32 intel_ntb_spad_read(struct ntb_dev *ntb, int idx);
+32 −1
Original line number Diff line number Diff line
@@ -532,6 +532,37 @@ static int intel_ntb3_mw_set_trans(struct ntb_dev *ntb, int pidx, int idx,
	return 0;
}

int intel_ntb3_peer_db_addr(struct ntb_dev *ntb, phys_addr_t *db_addr,
				resource_size_t *db_size,
				u64 *db_data, int db_bit)
{
	phys_addr_t db_addr_base;
	struct intel_ntb_dev *ndev = ntb_ndev(ntb);

	if (unlikely(db_bit >= BITS_PER_LONG_LONG))
		return -EINVAL;

	if (unlikely(BIT_ULL(db_bit) & ~ntb_ndev(ntb)->db_valid_mask))
		return -EINVAL;

	ndev_db_addr(ndev, &db_addr_base, db_size, ndev->peer_addr,
				ndev->peer_reg->db_bell);

	if (db_addr) {
		*db_addr = db_addr_base + (db_bit * 4);
		dev_dbg(&ndev->ntb.pdev->dev, "Peer db addr %llx db bit %d\n",
				*db_addr, db_bit);
	}

	if (db_data) {
		*db_data = 1;
		dev_dbg(&ndev->ntb.pdev->dev, "Peer db data %llx db bit %d\n",
				*db_data, db_bit);
	}

	return 0;
}

static int intel_ntb3_peer_db_set(struct ntb_dev *ntb, u64 db_bits)
{
	struct intel_ntb_dev *ndev = ntb_ndev(ntb);
@@ -584,7 +615,7 @@ const struct ntb_dev_ops intel_ntb3_ops = {
	.db_clear		= intel_ntb3_db_clear,
	.db_set_mask		= intel_ntb_db_set_mask,
	.db_clear_mask		= intel_ntb_db_clear_mask,
	.peer_db_addr		= intel_ntb_peer_db_addr,
	.peer_db_addr		= intel_ntb3_peer_db_addr,
	.peer_db_set		= intel_ntb3_peer_db_set,
	.spad_is_unsafe		= intel_ntb_spad_is_unsafe,
	.spad_count		= intel_ntb_spad_count,
+16 −4
Original line number Diff line number Diff line
@@ -236,6 +236,7 @@ static void switchtec_ntb_mw_clr_direct(struct switchtec_ntb *sndev, int idx)
	ctl_val &= ~NTB_CTRL_BAR_DIR_WIN_EN;
	iowrite32(ctl_val, &ctl->bar_entry[bar].ctl);
	iowrite32(0, &ctl->bar_entry[bar].win_size);
	iowrite32(0, &ctl->bar_ext_entry[bar].win_size);
	iowrite64(sndev->self_partition, &ctl->bar_entry[bar].xlate_addr);
}

@@ -258,7 +259,9 @@ static void switchtec_ntb_mw_set_direct(struct switchtec_ntb *sndev, int idx,
	ctl_val |= NTB_CTRL_BAR_DIR_WIN_EN;

	iowrite32(ctl_val, &ctl->bar_entry[bar].ctl);
	iowrite32(xlate_pos | size, &ctl->bar_entry[bar].win_size);
	iowrite32(xlate_pos | (lower_32_bits(size) & 0xFFFFF000),
		  &ctl->bar_entry[bar].win_size);
	iowrite32(upper_32_bits(size), &ctl->bar_ext_entry[bar].win_size);
	iowrite64(sndev->self_partition | addr,
		  &ctl->bar_entry[bar].xlate_addr);
}
@@ -679,11 +682,16 @@ static u64 switchtec_ntb_db_read_mask(struct ntb_dev *ntb)

static int switchtec_ntb_peer_db_addr(struct ntb_dev *ntb,
				      phys_addr_t *db_addr,
				      resource_size_t *db_size)
				      resource_size_t *db_size,
				      u64 *db_data,
				      int db_bit)
{
	struct switchtec_ntb *sndev = ntb_sndev(ntb);
	unsigned long offset;

	if (unlikely(db_bit >= BITS_PER_LONG_LONG))
		return -EINVAL;

	offset = (unsigned long)sndev->mmio_peer_dbmsg->odb -
		(unsigned long)sndev->stdev->mmio;

@@ -693,6 +701,8 @@ static int switchtec_ntb_peer_db_addr(struct ntb_dev *ntb,
		*db_addr = pci_resource_start(ntb->pdev, 0) + offset;
	if (db_size)
		*db_size = sizeof(u32);
	if (db_data)
		*db_data = BIT_ULL(db_bit) << sndev->db_peer_shift;

	return 0;
}
@@ -1025,7 +1035,9 @@ static int crosslink_setup_mws(struct switchtec_ntb *sndev, int ntb_lut_idx,
		ctl_val |= NTB_CTRL_BAR_DIR_WIN_EN;

		iowrite32(ctl_val, &ctl->bar_entry[bar].ctl);
		iowrite32(xlate_pos | size, &ctl->bar_entry[bar].win_size);
		iowrite32(xlate_pos | (lower_32_bits(size) & 0xFFFFF000),
			  &ctl->bar_entry[bar].win_size);
		iowrite32(upper_32_bits(size), &ctl->bar_ext_entry[bar].win_size);
		iowrite64(sndev->peer_partition | addr,
			  &ctl->bar_entry[bar].xlate_addr);
	}
@@ -1092,7 +1104,7 @@ static int crosslink_enum_partition(struct switchtec_ntb *sndev,

		dev_dbg(&sndev->stdev->dev,
			"Crosslink BAR%d addr: %llx\n",
			i, bar_addr);
			i*2, bar_addr);

		if (bar_addr != bar_space * i)
			continue;
+29 −2
Original line number Diff line number Diff line
@@ -144,7 +144,9 @@ struct ntb_transport_qp {
	struct list_head tx_free_q;
	spinlock_t ntb_tx_free_q_lock;
	void __iomem *tx_mw;
	dma_addr_t tx_mw_phys;
	phys_addr_t tx_mw_phys;
	size_t tx_mw_size;
	dma_addr_t tx_mw_dma_addr;
	unsigned int tx_index;
	unsigned int tx_max_entry;
	unsigned int tx_max_frame;
@@ -862,6 +864,9 @@ static void ntb_transport_link_cleanup(struct ntb_transport_ctx *nt)
	if (!nt->link_is_up)
		cancel_delayed_work_sync(&nt->link_work);

	for (i = 0; i < nt->mw_count; i++)
		ntb_free_mw(nt, i);

	/* The scratchpad registers keep the values if the remote side
	 * goes down, blast them now to give them a sane value the next
	 * time they are accessed
@@ -1049,6 +1054,7 @@ static int ntb_transport_init_queue(struct ntb_transport_ctx *nt,
	tx_size = (unsigned int)mw_size / num_qps_mw;
	qp_offset = tx_size * (qp_num / mw_count);

	qp->tx_mw_size = tx_size;
	qp->tx_mw = nt->mw_vec[mw_num].vbase + qp_offset;
	if (!qp->tx_mw)
		return -EINVAL;
@@ -1644,7 +1650,7 @@ static int ntb_async_tx_submit(struct ntb_transport_qp *qp,
	dma_cookie_t cookie;

	device = chan->device;
	dest = qp->tx_mw_phys + qp->tx_max_frame * entry->tx_index;
	dest = qp->tx_mw_dma_addr + qp->tx_max_frame * entry->tx_index;
	buff_off = (size_t)buf & ~PAGE_MASK;
	dest_off = (size_t)dest & ~PAGE_MASK;

@@ -1863,6 +1869,18 @@ ntb_transport_create_queue(void *data, struct device *client_dev,
		qp->rx_dma_chan = NULL;
	}

	if (qp->tx_dma_chan) {
		qp->tx_mw_dma_addr =
			dma_map_resource(qp->tx_dma_chan->device->dev,
					 qp->tx_mw_phys, qp->tx_mw_size,
					 DMA_FROM_DEVICE, 0);
		if (dma_mapping_error(qp->tx_dma_chan->device->dev,
				      qp->tx_mw_dma_addr)) {
			qp->tx_mw_dma_addr = 0;
			goto err1;
		}
	}

	dev_dbg(&pdev->dev, "Using %s memcpy for TX\n",
		qp->tx_dma_chan ? "DMA" : "CPU");

@@ -1904,6 +1922,10 @@ err1:
	qp->rx_alloc_entry = 0;
	while ((entry = ntb_list_rm(&qp->ntb_rx_q_lock, &qp->rx_free_q)))
		kfree(entry);
	if (qp->tx_mw_dma_addr)
		dma_unmap_resource(qp->tx_dma_chan->device->dev,
				   qp->tx_mw_dma_addr, qp->tx_mw_size,
				   DMA_FROM_DEVICE, 0);
	if (qp->tx_dma_chan)
		dma_release_channel(qp->tx_dma_chan);
	if (qp->rx_dma_chan)
@@ -1945,6 +1967,11 @@ void ntb_transport_free_queue(struct ntb_transport_qp *qp)
		 */
		dma_sync_wait(chan, qp->last_cookie);
		dmaengine_terminate_all(chan);

		dma_unmap_resource(chan->device->dev,
				   qp->tx_mw_dma_addr, qp->tx_mw_size,
				   DMA_FROM_DEVICE, 0);

		dma_release_channel(chan);
	}

Loading