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

Merge tag 'ntb-6.18' of https://github.com/jonmason/ntb

Pull NTB updates from Jon Mason:

 - Add support for Renesas R-Car and allow arbitrary BAR mapping in EPF

 - Update ntb_hw_amd to support the latest generation secondary topology
   and add a new maintainer

 - Fix a bug by adding a mutex to ensure `link_event_callback` executes
   sequentially

* tag 'ntb-6.18' of https://github.com/jonmason/ntb:
  NTB: epf: Add Renesas rcar support
  NTB: epf: Allow arbitrary BAR mapping
  ntb: Add mutex to make link_event_callback executed linearly.
  MAINTAINERS: Update for the NTB AMD driver maintainer
  ntb_hw_amd: Update amd_ntb_get_link_status to support latest generation secondary topology
parents aac31903 006824a1
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -18338,6 +18338,7 @@ F: Documentation/core-api/symbol-namespaces.rst
F:	scripts/nsdeps
NTB AMD DRIVER
M:	Basavaraj Natikar <Basavaraj.Natikar@amd.com>
M:	Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
L:	ntb@lists.linux.dev
S:	Supported
+17 −1
Original line number Diff line number Diff line
@@ -197,13 +197,22 @@ static int amd_ntb_mw_set_trans(struct ntb_dev *ntb, int pidx, int idx,

static int amd_ntb_get_link_status(struct amd_ntb_dev *ndev)
{
	struct pci_dev *pdev = NULL;
	struct pci_dev *pdev = ndev->ntb.pdev;
	struct pci_dev *pci_swds = NULL;
	struct pci_dev *pci_swus = NULL;
	u32 stat;
	int rc;

	if (ndev->ntb.topo == NTB_TOPO_SEC) {
		if (ndev->dev_data->is_endpoint) {
			rc = pcie_capability_read_dword(pdev, PCI_EXP_LNKCTL, &stat);
			if (rc)
				return rc;

			ndev->lnk_sta = stat;
			return 0;
		}

		/* Locate the pointer to Downstream Switch for this device */
		pci_swds = pci_upstream_bridge(ndev->ntb.pdev);
		if (pci_swds) {
@@ -1311,6 +1320,11 @@ static const struct ntb_dev_data dev_data[] = {
		.mw_count = 2,
		.mw_idx = 2,
	},
	{ /* for device 0x17d7 */
		.mw_count = 2,
		.mw_idx = 2,
		.is_endpoint = true,
	},
};

static const struct pci_device_id amd_ntb_pci_tbl[] = {
@@ -1319,6 +1333,8 @@ static const struct pci_device_id amd_ntb_pci_tbl[] = {
	{ PCI_VDEVICE(AMD, 0x14c0), (kernel_ulong_t)&dev_data[1] },
	{ PCI_VDEVICE(AMD, 0x14c3), (kernel_ulong_t)&dev_data[1] },
	{ PCI_VDEVICE(AMD, 0x155a), (kernel_ulong_t)&dev_data[1] },
	{ PCI_VDEVICE(AMD, 0x17d4), (kernel_ulong_t)&dev_data[1] },
	{ PCI_VDEVICE(AMD, 0x17d7), (kernel_ulong_t)&dev_data[2] },
	{ PCI_VDEVICE(HYGON, 0x145b), (kernel_ulong_t)&dev_data[0] },
	{ 0, }
};
+1 −0
Original line number Diff line number Diff line
@@ -168,6 +168,7 @@ enum {
struct ntb_dev_data {
	const unsigned char mw_count;
	const unsigned int mw_idx;
	const bool is_endpoint;
};

struct amd_ntb_dev;
+68 −50
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@
#define NTB_EPF_COMMAND_TIMEOUT	1000 /* 1 Sec */

enum pci_barno {
	NO_BAR = -1,
	BAR_0,
	BAR_1,
	BAR_2,
@@ -57,16 +58,26 @@ enum pci_barno {
	BAR_5,
};

enum epf_ntb_bar {
	BAR_CONFIG,
	BAR_PEER_SPAD,
	BAR_DB,
	BAR_MW1,
	BAR_MW2,
	BAR_MW3,
	BAR_MW4,
	NTB_BAR_NUM,
};

#define NTB_EPF_MAX_MW_COUNT	(NTB_BAR_NUM - BAR_MW1)

struct ntb_epf_dev {
	struct ntb_dev ntb;
	struct device *dev;
	/* Mutex to protect providing commands to NTB EPF */
	struct mutex cmd_lock;

	enum pci_barno ctrl_reg_bar;
	enum pci_barno peer_spad_reg_bar;
	enum pci_barno db_reg_bar;
	enum pci_barno mw_bar;
	const enum pci_barno *barno_map;

	unsigned int mw_count;
	unsigned int spad_count;
@@ -85,17 +96,6 @@ struct ntb_epf_dev {

#define ntb_ndev(__ntb) container_of(__ntb, struct ntb_epf_dev, ntb)

struct ntb_epf_data {
	/* BAR that contains both control region and self spad region */
	enum pci_barno ctrl_reg_bar;
	/* BAR that contains peer spad region */
	enum pci_barno peer_spad_reg_bar;
	/* BAR that contains Doorbell region and Memory window '1' */
	enum pci_barno db_reg_bar;
	/* BAR that contains memory windows*/
	enum pci_barno mw_bar;
};

static int ntb_epf_send_command(struct ntb_epf_dev *ndev, u32 command,
				u32 argument)
{
@@ -144,7 +144,7 @@ static int ntb_epf_mw_to_bar(struct ntb_epf_dev *ndev, int idx)
		return -EINVAL;
	}

	return idx + 2;
	return ndev->barno_map[BAR_MW1 + idx];
}

static int ntb_epf_mw_count(struct ntb_dev *ntb, int pidx)
@@ -413,7 +413,9 @@ static int ntb_epf_mw_set_trans(struct ntb_dev *ntb, int pidx, int idx,
		return -EINVAL;
	}

	bar = idx + ndev->mw_bar;
	bar = ntb_epf_mw_to_bar(ndev, idx);
	if (bar < 0)
		return bar;

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

@@ -455,7 +457,9 @@ static int ntb_epf_peer_mw_get_addr(struct ntb_dev *ntb, int idx,
	if (idx == 0)
		offset = readl(ndev->ctrl_reg + NTB_EPF_MW1_OFFSET);

	bar = idx + ndev->mw_bar;
	bar = ntb_epf_mw_to_bar(ndev, idx);
	if (bar < 0)
		return bar;

	if (base)
		*base = pci_resource_start(ndev->ntb.pdev, bar) + offset;
@@ -560,6 +564,11 @@ static int ntb_epf_init_dev(struct ntb_epf_dev *ndev)
	ndev->mw_count = readl(ndev->ctrl_reg + NTB_EPF_MW_COUNT);
	ndev->spad_count = readl(ndev->ctrl_reg + NTB_EPF_SPAD_COUNT);

	if (ndev->mw_count > NTB_EPF_MAX_MW_COUNT) {
		dev_err(dev, "Unsupported MW count: %u\n", ndev->mw_count);
		return -EINVAL;
	}

	return 0;
}

@@ -596,14 +605,15 @@ static int ntb_epf_init_pci(struct ntb_epf_dev *ndev,
		dev_warn(&pdev->dev, "Cannot DMA highmem\n");
	}

	ndev->ctrl_reg = pci_iomap(pdev, ndev->ctrl_reg_bar, 0);
	ndev->ctrl_reg = pci_iomap(pdev, ndev->barno_map[BAR_CONFIG], 0);
	if (!ndev->ctrl_reg) {
		ret = -EIO;
		goto err_pci_regions;
	}

	if (ndev->peer_spad_reg_bar) {
		ndev->peer_spad_reg = pci_iomap(pdev, ndev->peer_spad_reg_bar, 0);
	if (ndev->barno_map[BAR_PEER_SPAD] != ndev->barno_map[BAR_CONFIG]) {
		ndev->peer_spad_reg = pci_iomap(pdev,
						ndev->barno_map[BAR_PEER_SPAD], 0);
		if (!ndev->peer_spad_reg) {
			ret = -EIO;
			goto err_pci_regions;
@@ -614,7 +624,7 @@ static int ntb_epf_init_pci(struct ntb_epf_dev *ndev,
		ndev->peer_spad_reg = ndev->ctrl_reg + spad_off  + spad_sz;
	}

	ndev->db_reg = pci_iomap(pdev, ndev->db_reg_bar, 0);
	ndev->db_reg = pci_iomap(pdev, ndev->barno_map[BAR_DB], 0);
	if (!ndev->db_reg) {
		ret = -EIO;
		goto err_pci_regions;
@@ -659,12 +669,7 @@ static void ntb_epf_cleanup_isr(struct ntb_epf_dev *ndev)
static int ntb_epf_pci_probe(struct pci_dev *pdev,
			     const struct pci_device_id *id)
{
	enum pci_barno peer_spad_reg_bar = BAR_1;
	enum pci_barno ctrl_reg_bar = BAR_0;
	enum pci_barno db_reg_bar = BAR_2;
	enum pci_barno mw_bar = BAR_2;
	struct device *dev = &pdev->dev;
	struct ntb_epf_data *data;
	struct ntb_epf_dev *ndev;
	int ret;

@@ -675,18 +680,10 @@ static int ntb_epf_pci_probe(struct pci_dev *pdev,
	if (!ndev)
		return -ENOMEM;

	data = (struct ntb_epf_data *)id->driver_data;
	if (data) {
		peer_spad_reg_bar = data->peer_spad_reg_bar;
		ctrl_reg_bar = data->ctrl_reg_bar;
		db_reg_bar = data->db_reg_bar;
		mw_bar = data->mw_bar;
	}
	ndev->barno_map = (const enum pci_barno *)id->driver_data;
	if (!ndev->barno_map)
		return -EINVAL;

	ndev->peer_spad_reg_bar = peer_spad_reg_bar;
	ndev->ctrl_reg_bar = ctrl_reg_bar;
	ndev->db_reg_bar = db_reg_bar;
	ndev->mw_bar = mw_bar;
	ndev->dev = dev;

	ntb_epf_init_struct(ndev, pdev);
@@ -730,30 +727,51 @@ static void ntb_epf_pci_remove(struct pci_dev *pdev)
	ntb_epf_deinit_pci(ndev);
}

static const struct ntb_epf_data j721e_data = {
	.ctrl_reg_bar = BAR_0,
	.peer_spad_reg_bar = BAR_1,
	.db_reg_bar = BAR_2,
	.mw_bar = BAR_2,
static const enum pci_barno j721e_map[NTB_BAR_NUM] = {
	[BAR_CONFIG]	= BAR_0,
	[BAR_PEER_SPAD]	= BAR_1,
	[BAR_DB]	= BAR_2,
	[BAR_MW1]	= BAR_2,
	[BAR_MW2]	= BAR_3,
	[BAR_MW3]	= BAR_4,
	[BAR_MW4]	= BAR_5
};

static const struct ntb_epf_data mx8_data = {
	.ctrl_reg_bar = BAR_0,
	.peer_spad_reg_bar = BAR_0,
	.db_reg_bar = BAR_2,
	.mw_bar = BAR_4,
static const enum pci_barno mx8_map[NTB_BAR_NUM] = {
	[BAR_CONFIG]	= BAR_0,
	[BAR_PEER_SPAD]	= BAR_0,
	[BAR_DB]	= BAR_2,
	[BAR_MW1]	= BAR_4,
	[BAR_MW2]	= BAR_5,
	[BAR_MW3]	= NO_BAR,
	[BAR_MW4]	= NO_BAR
};

static const enum pci_barno rcar_barno[NTB_BAR_NUM] = {
	[BAR_CONFIG]	= BAR_0,
	[BAR_PEER_SPAD]	= BAR_0,
	[BAR_DB]	= BAR_4,
	[BAR_MW1]	= BAR_2,
	[BAR_MW2]	= NO_BAR,
	[BAR_MW3]	= NO_BAR,
	[BAR_MW4]	= NO_BAR,
};

static const struct pci_device_id ntb_epf_pci_tbl[] = {
	{
		PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_J721E),
		.class = PCI_CLASS_MEMORY_RAM << 8, .class_mask = 0xffff00,
		.driver_data = (kernel_ulong_t)&j721e_data,
		.driver_data = (kernel_ulong_t)j721e_map,
	},
	{
		PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, 0x0809),
		.class = PCI_CLASS_MEMORY_RAM << 8, .class_mask = 0xffff00,
		.driver_data = (kernel_ulong_t)&mx8_data,
		.driver_data = (kernel_ulong_t)mx8_map,
	},
	{
		PCI_DEVICE(PCI_VENDOR_ID_RENESAS, 0x0030),
		.class = PCI_CLASS_MEMORY_RAM << 8, .class_mask = 0xffff00,
		.driver_data = (kernel_ulong_t)rcar_barno,
	},
	{ },
};
+7 −0
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/uaccess.h>
#include <linux/mutex.h>
#include "linux/ntb.h"
#include "linux/ntb_transport.h"

@@ -241,6 +242,9 @@ struct ntb_transport_ctx {
	struct work_struct link_cleanup;

	struct dentry *debugfs_node_dir;

	/* Make sure workq of link event be executed serially */
	struct mutex link_event_lock;
};

enum {
@@ -1024,6 +1028,7 @@ static void ntb_transport_link_cleanup_work(struct work_struct *work)
	struct ntb_transport_ctx *nt =
		container_of(work, struct ntb_transport_ctx, link_cleanup);

	guard(mutex)(&nt->link_event_lock);
	ntb_transport_link_cleanup(nt);
}

@@ -1047,6 +1052,8 @@ static void ntb_transport_link_work(struct work_struct *work)
	u32 val;
	int rc = 0, i, spad;

	guard(mutex)(&nt->link_event_lock);

	/* send the local info, in the opposite order of the way we read it */

	if (nt->use_msi) {