xref: /linux/drivers/ntb/hw/intel/ntb_hw_gen3.c (revision 4b4193256c8d3bc3a5397b5cd9494c2ad386317d)
1f6e51c35SDave Jiang /*
2f6e51c35SDave Jiang  * This file is provided under a dual BSD/GPLv2 license.  When using or
3f6e51c35SDave Jiang  *   redistributing this file, you may do so under either license.
4f6e51c35SDave Jiang  *
5f6e51c35SDave Jiang  *   GPL LICENSE SUMMARY
6f6e51c35SDave Jiang  *
7f6e51c35SDave Jiang  *   Copyright(c) 2017 Intel Corporation. All rights reserved.
8f6e51c35SDave Jiang  *
9f6e51c35SDave Jiang  *   This program is free software; you can redistribute it and/or modify
10f6e51c35SDave Jiang  *   it under the terms of version 2 of the GNU General Public License as
11f6e51c35SDave Jiang  *   published by the Free Software Foundation.
12f6e51c35SDave Jiang  *
13f6e51c35SDave Jiang  *   BSD LICENSE
14f6e51c35SDave Jiang  *
15f6e51c35SDave Jiang  *   Copyright(c) 2017 Intel Corporation. All rights reserved.
16f6e51c35SDave Jiang  *
17f6e51c35SDave Jiang  *   Redistribution and use in source and binary forms, with or without
18f6e51c35SDave Jiang  *   modification, are permitted provided that the following conditions
19f6e51c35SDave Jiang  *   are met:
20f6e51c35SDave Jiang  *
21f6e51c35SDave Jiang  *     * Redistributions of source code must retain the above copyright
22f6e51c35SDave Jiang  *       notice, this list of conditions and the following disclaimer.
23f6e51c35SDave Jiang  *     * Redistributions in binary form must reproduce the above copy
24f6e51c35SDave Jiang  *       notice, this list of conditions and the following disclaimer in
25f6e51c35SDave Jiang  *       the documentation and/or other materials provided with the
26f6e51c35SDave Jiang  *       distribution.
27f6e51c35SDave Jiang  *     * Neither the name of Intel Corporation nor the names of its
28f6e51c35SDave Jiang  *       contributors may be used to endorse or promote products derived
29f6e51c35SDave Jiang  *       from this software without specific prior written permission.
30f6e51c35SDave Jiang  *
31f6e51c35SDave Jiang  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32f6e51c35SDave Jiang  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33f6e51c35SDave Jiang  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34f6e51c35SDave Jiang  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35f6e51c35SDave Jiang  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
36f6e51c35SDave Jiang  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
37f6e51c35SDave Jiang  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
38f6e51c35SDave Jiang  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
39f6e51c35SDave Jiang  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
40f6e51c35SDave Jiang  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
41f6e51c35SDave Jiang  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42f6e51c35SDave Jiang  *
436c1e8ab2SDave Jiang  * Intel PCIe GEN3 NTB Linux driver
44f6e51c35SDave Jiang  *
45f6e51c35SDave Jiang  */
46f6e51c35SDave Jiang 
47f6e51c35SDave Jiang #include <linux/debugfs.h>
48f6e51c35SDave Jiang #include <linux/delay.h>
49f6e51c35SDave Jiang #include <linux/init.h>
50f6e51c35SDave Jiang #include <linux/interrupt.h>
51f6e51c35SDave Jiang #include <linux/module.h>
52f6e51c35SDave Jiang #include <linux/pci.h>
53f6e51c35SDave Jiang #include <linux/random.h>
54f6e51c35SDave Jiang #include <linux/slab.h>
55f6e51c35SDave Jiang #include <linux/ntb.h>
56f6e51c35SDave Jiang 
57f6e51c35SDave Jiang #include "ntb_hw_intel.h"
58f6e51c35SDave Jiang #include "ntb_hw_gen1.h"
59f6e51c35SDave Jiang #include "ntb_hw_gen3.h"
60f6e51c35SDave Jiang 
616c1e8ab2SDave Jiang static int gen3_poll_link(struct intel_ntb_dev *ndev);
626c1e8ab2SDave Jiang 
636c1e8ab2SDave Jiang static const struct intel_ntb_reg gen3_reg = {
646c1e8ab2SDave Jiang 	.poll_link		= gen3_poll_link,
65f6e51c35SDave Jiang 	.link_is_up		= xeon_link_is_up,
666c1e8ab2SDave Jiang 	.db_ioread		= gen3_db_ioread,
676c1e8ab2SDave Jiang 	.db_iowrite		= gen3_db_iowrite,
68f6e51c35SDave Jiang 	.db_size		= sizeof(u32),
696c1e8ab2SDave Jiang 	.ntb_ctl		= GEN3_NTBCNTL_OFFSET,
70f6e51c35SDave Jiang 	.mw_bar			= {2, 4},
71f6e51c35SDave Jiang };
72f6e51c35SDave Jiang 
736c1e8ab2SDave Jiang static const struct intel_ntb_alt_reg gen3_pri_reg = {
746c1e8ab2SDave Jiang 	.db_bell		= GEN3_EM_DOORBELL_OFFSET,
756c1e8ab2SDave Jiang 	.db_clear		= GEN3_IM_INT_STATUS_OFFSET,
766c1e8ab2SDave Jiang 	.db_mask		= GEN3_IM_INT_DISABLE_OFFSET,
776c1e8ab2SDave Jiang 	.spad			= GEN3_IM_SPAD_OFFSET,
78f6e51c35SDave Jiang };
79f6e51c35SDave Jiang 
806c1e8ab2SDave Jiang static const struct intel_ntb_alt_reg gen3_b2b_reg = {
816c1e8ab2SDave Jiang 	.db_bell		= GEN3_IM_DOORBELL_OFFSET,
826c1e8ab2SDave Jiang 	.db_clear		= GEN3_EM_INT_STATUS_OFFSET,
836c1e8ab2SDave Jiang 	.db_mask		= GEN3_EM_INT_DISABLE_OFFSET,
846c1e8ab2SDave Jiang 	.spad			= GEN3_B2B_SPAD_OFFSET,
85f6e51c35SDave Jiang };
86f6e51c35SDave Jiang 
876c1e8ab2SDave Jiang static const struct intel_ntb_xlat_reg gen3_sec_xlat = {
886c1e8ab2SDave Jiang /*	.bar0_base		= GEN3_EMBAR0_OFFSET, */
896c1e8ab2SDave Jiang 	.bar2_limit		= GEN3_IMBAR1XLMT_OFFSET,
906c1e8ab2SDave Jiang 	.bar2_xlat		= GEN3_IMBAR1XBASE_OFFSET,
91f6e51c35SDave Jiang };
92f6e51c35SDave Jiang 
gen3_poll_link(struct intel_ntb_dev * ndev)936c1e8ab2SDave Jiang static int gen3_poll_link(struct intel_ntb_dev *ndev)
94f6e51c35SDave Jiang {
95f6e51c35SDave Jiang 	u16 reg_val;
96f6e51c35SDave Jiang 	int rc;
97f6e51c35SDave Jiang 
98f6e51c35SDave Jiang 	ndev->reg->db_iowrite(ndev->db_link_mask,
99f6e51c35SDave Jiang 			      ndev->self_mmio +
100f6e51c35SDave Jiang 			      ndev->self_reg->db_clear);
101f6e51c35SDave Jiang 
102f6e51c35SDave Jiang 	rc = pci_read_config_word(ndev->ntb.pdev,
1036c1e8ab2SDave Jiang 				  GEN3_LINK_STATUS_OFFSET, &reg_val);
104f6e51c35SDave Jiang 	if (rc)
105f6e51c35SDave Jiang 		return 0;
106f6e51c35SDave Jiang 
107f6e51c35SDave Jiang 	if (reg_val == ndev->lnk_sta)
108f6e51c35SDave Jiang 		return 0;
109f6e51c35SDave Jiang 
110f6e51c35SDave Jiang 	ndev->lnk_sta = reg_val;
111f6e51c35SDave Jiang 
112f6e51c35SDave Jiang 	return 1;
113f6e51c35SDave Jiang }
114f6e51c35SDave Jiang 
gen3_init_isr(struct intel_ntb_dev * ndev)1156c1e8ab2SDave Jiang static int gen3_init_isr(struct intel_ntb_dev *ndev)
116f6e51c35SDave Jiang {
117f6e51c35SDave Jiang 	int i;
118f6e51c35SDave Jiang 
119f6e51c35SDave Jiang 	/*
120f6e51c35SDave Jiang 	 * The MSIX vectors and the interrupt status bits are not lined up
121f6e51c35SDave Jiang 	 * on Skylake. By default the link status bit is bit 32, however it
122f6e51c35SDave Jiang 	 * is by default MSIX vector0. We need to fixup to line them up.
123f6e51c35SDave Jiang 	 * The vectors at reset is 1-32,0. We need to reprogram to 0-32.
124f6e51c35SDave Jiang 	 */
125f6e51c35SDave Jiang 
1266c1e8ab2SDave Jiang 	for (i = 0; i < GEN3_DB_MSIX_VECTOR_COUNT; i++)
1276c1e8ab2SDave Jiang 		iowrite8(i, ndev->self_mmio + GEN3_INTVEC_OFFSET + i);
128f6e51c35SDave Jiang 
129f6e51c35SDave Jiang 	/* move link status down one as workaround */
130f6e51c35SDave Jiang 	if (ndev->hwerr_flags & NTB_HWERR_MSIX_VECTOR32_BAD) {
1316c1e8ab2SDave Jiang 		iowrite8(GEN3_DB_MSIX_VECTOR_COUNT - 2,
1326c1e8ab2SDave Jiang 			 ndev->self_mmio + GEN3_INTVEC_OFFSET +
1336c1e8ab2SDave Jiang 			 (GEN3_DB_MSIX_VECTOR_COUNT - 1));
134f6e51c35SDave Jiang 	}
135f6e51c35SDave Jiang 
1366c1e8ab2SDave Jiang 	return ndev_init_isr(ndev, GEN3_DB_MSIX_VECTOR_COUNT,
1376c1e8ab2SDave Jiang 			     GEN3_DB_MSIX_VECTOR_COUNT,
1386c1e8ab2SDave Jiang 			     GEN3_DB_MSIX_VECTOR_SHIFT,
1396c1e8ab2SDave Jiang 			     GEN3_DB_TOTAL_SHIFT);
140f6e51c35SDave Jiang }
141f6e51c35SDave Jiang 
gen3_setup_b2b_mw(struct intel_ntb_dev * ndev,const struct intel_b2b_addr * addr,const struct intel_b2b_addr * peer_addr)1426c1e8ab2SDave Jiang static int gen3_setup_b2b_mw(struct intel_ntb_dev *ndev,
143f6e51c35SDave Jiang 			    const struct intel_b2b_addr *addr,
144f6e51c35SDave Jiang 			    const struct intel_b2b_addr *peer_addr)
145f6e51c35SDave Jiang {
146f6e51c35SDave Jiang 	struct pci_dev *pdev;
147f6e51c35SDave Jiang 	void __iomem *mmio;
148f6e51c35SDave Jiang 	phys_addr_t bar_addr;
149f6e51c35SDave Jiang 
150f6e51c35SDave Jiang 	pdev = ndev->ntb.pdev;
151f6e51c35SDave Jiang 	mmio = ndev->self_mmio;
152f6e51c35SDave Jiang 
153f6e51c35SDave Jiang 	/* setup incoming bar limits == base addrs (zero length windows) */
154f6e51c35SDave Jiang 	bar_addr = addr->bar2_addr64;
1556c1e8ab2SDave Jiang 	iowrite64(bar_addr, mmio + GEN3_IMBAR1XLMT_OFFSET);
1566c1e8ab2SDave Jiang 	bar_addr = ioread64(mmio + GEN3_IMBAR1XLMT_OFFSET);
157f6e51c35SDave Jiang 	dev_dbg(&pdev->dev, "IMBAR1XLMT %#018llx\n", bar_addr);
158f6e51c35SDave Jiang 
159f6e51c35SDave Jiang 	bar_addr = addr->bar4_addr64;
1606c1e8ab2SDave Jiang 	iowrite64(bar_addr, mmio + GEN3_IMBAR2XLMT_OFFSET);
1616c1e8ab2SDave Jiang 	bar_addr = ioread64(mmio + GEN3_IMBAR2XLMT_OFFSET);
162f6e51c35SDave Jiang 	dev_dbg(&pdev->dev, "IMBAR2XLMT %#018llx\n", bar_addr);
163f6e51c35SDave Jiang 
164f6e51c35SDave Jiang 	/* zero incoming translation addrs */
1656c1e8ab2SDave Jiang 	iowrite64(0, mmio + GEN3_IMBAR1XBASE_OFFSET);
1666c1e8ab2SDave Jiang 	iowrite64(0, mmio + GEN3_IMBAR2XBASE_OFFSET);
167f6e51c35SDave Jiang 
168f6e51c35SDave Jiang 	ndev->peer_mmio = ndev->self_mmio;
169f6e51c35SDave Jiang 
170f6e51c35SDave Jiang 	return 0;
171f6e51c35SDave Jiang }
172f6e51c35SDave Jiang 
gen3_init_ntb(struct intel_ntb_dev * ndev)1736c1e8ab2SDave Jiang static int gen3_init_ntb(struct intel_ntb_dev *ndev)
174f6e51c35SDave Jiang {
175f6e51c35SDave Jiang 	int rc;
176f6e51c35SDave Jiang 
177f6e51c35SDave Jiang 
178f6e51c35SDave Jiang 	ndev->mw_count = XEON_MW_COUNT;
1796c1e8ab2SDave Jiang 	ndev->spad_count = GEN3_SPAD_COUNT;
1806c1e8ab2SDave Jiang 	ndev->db_count = GEN3_DB_COUNT;
1816c1e8ab2SDave Jiang 	ndev->db_link_mask = GEN3_DB_LINK_BIT;
182f6e51c35SDave Jiang 
183f6e51c35SDave Jiang 	/* DB fixup for using 31 right now */
184f6e51c35SDave Jiang 	if (ndev->hwerr_flags & NTB_HWERR_MSIX_VECTOR32_BAD)
185f6e51c35SDave Jiang 		ndev->db_link_mask |= BIT_ULL(31);
186f6e51c35SDave Jiang 
187f6e51c35SDave Jiang 	switch (ndev->ntb.topo) {
188f6e51c35SDave Jiang 	case NTB_TOPO_B2B_USD:
189f6e51c35SDave Jiang 	case NTB_TOPO_B2B_DSD:
1906c1e8ab2SDave Jiang 		ndev->self_reg = &gen3_pri_reg;
1916c1e8ab2SDave Jiang 		ndev->peer_reg = &gen3_b2b_reg;
1926c1e8ab2SDave Jiang 		ndev->xlat_reg = &gen3_sec_xlat;
193f6e51c35SDave Jiang 
194f6e51c35SDave Jiang 		if (ndev->ntb.topo == NTB_TOPO_B2B_USD) {
1956c1e8ab2SDave Jiang 			rc = gen3_setup_b2b_mw(ndev,
196f6e51c35SDave Jiang 					      &xeon_b2b_dsd_addr,
197f6e51c35SDave Jiang 					      &xeon_b2b_usd_addr);
198f6e51c35SDave Jiang 		} else {
1996c1e8ab2SDave Jiang 			rc = gen3_setup_b2b_mw(ndev,
200f6e51c35SDave Jiang 					      &xeon_b2b_usd_addr,
201f6e51c35SDave Jiang 					      &xeon_b2b_dsd_addr);
202f6e51c35SDave Jiang 		}
203f6e51c35SDave Jiang 
204f6e51c35SDave Jiang 		if (rc)
205f6e51c35SDave Jiang 			return rc;
206f6e51c35SDave Jiang 
207f6e51c35SDave Jiang 		/* Enable Bus Master and Memory Space on the secondary side */
208f6e51c35SDave Jiang 		iowrite16(PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER,
2096c1e8ab2SDave Jiang 			  ndev->self_mmio + GEN3_SPCICMD_OFFSET);
210f6e51c35SDave Jiang 
211f6e51c35SDave Jiang 		break;
212f6e51c35SDave Jiang 
213f6e51c35SDave Jiang 	default:
214f6e51c35SDave Jiang 		return -EINVAL;
215f6e51c35SDave Jiang 	}
216f6e51c35SDave Jiang 
217f6e51c35SDave Jiang 	ndev->db_valid_mask = BIT_ULL(ndev->db_count) - 1;
218f6e51c35SDave Jiang 
219f6e51c35SDave Jiang 	ndev->reg->db_iowrite(ndev->db_valid_mask,
220f6e51c35SDave Jiang 			      ndev->self_mmio +
221f6e51c35SDave Jiang 			      ndev->self_reg->db_mask);
222f6e51c35SDave Jiang 
223f6e51c35SDave Jiang 	return 0;
224f6e51c35SDave Jiang }
225f6e51c35SDave Jiang 
gen3_init_dev(struct intel_ntb_dev * ndev)2266c1e8ab2SDave Jiang int gen3_init_dev(struct intel_ntb_dev *ndev)
227f6e51c35SDave Jiang {
228f6e51c35SDave Jiang 	struct pci_dev *pdev;
229f6e51c35SDave Jiang 	u8 ppd;
230f6e51c35SDave Jiang 	int rc;
231f6e51c35SDave Jiang 
232f6e51c35SDave Jiang 	pdev = ndev->ntb.pdev;
233f6e51c35SDave Jiang 
2346c1e8ab2SDave Jiang 	ndev->reg = &gen3_reg;
235f6e51c35SDave Jiang 
236f6e51c35SDave Jiang 	rc = pci_read_config_byte(pdev, XEON_PPD_OFFSET, &ppd);
237f6e51c35SDave Jiang 	if (rc)
238f6e51c35SDave Jiang 		return -EIO;
239f6e51c35SDave Jiang 
240f6e51c35SDave Jiang 	ndev->ntb.topo = xeon_ppd_topo(ndev, ppd);
241f6e51c35SDave Jiang 	dev_dbg(&pdev->dev, "ppd %#x topo %s\n", ppd,
242f6e51c35SDave Jiang 		ntb_topo_string(ndev->ntb.topo));
243f6e51c35SDave Jiang 	if (ndev->ntb.topo == NTB_TOPO_NONE)
244f6e51c35SDave Jiang 		return -EINVAL;
245f6e51c35SDave Jiang 
246f6e51c35SDave Jiang 	ndev->hwerr_flags |= NTB_HWERR_MSIX_VECTOR32_BAD;
247f6e51c35SDave Jiang 
2486c1e8ab2SDave Jiang 	rc = gen3_init_ntb(ndev);
249f6e51c35SDave Jiang 	if (rc)
250f6e51c35SDave Jiang 		return rc;
251f6e51c35SDave Jiang 
2526c1e8ab2SDave Jiang 	return gen3_init_isr(ndev);
253f6e51c35SDave Jiang }
254f6e51c35SDave Jiang 
ndev_ntb3_debugfs_read(struct file * filp,char __user * ubuf,size_t count,loff_t * offp)255f6e51c35SDave Jiang ssize_t ndev_ntb3_debugfs_read(struct file *filp, char __user *ubuf,
256f6e51c35SDave Jiang 				      size_t count, loff_t *offp)
257f6e51c35SDave Jiang {
258f6e51c35SDave Jiang 	struct intel_ntb_dev *ndev;
259f6e51c35SDave Jiang 	void __iomem *mmio;
260f6e51c35SDave Jiang 	char *buf;
261f6e51c35SDave Jiang 	size_t buf_size;
262f6e51c35SDave Jiang 	ssize_t ret, off;
263f6e51c35SDave Jiang 	union { u64 v64; u32 v32; u16 v16; } u;
264f6e51c35SDave Jiang 
265f6e51c35SDave Jiang 	ndev = filp->private_data;
266f6e51c35SDave Jiang 	mmio = ndev->self_mmio;
267f6e51c35SDave Jiang 
268f6e51c35SDave Jiang 	buf_size = min(count, 0x800ul);
269f6e51c35SDave Jiang 
270f6e51c35SDave Jiang 	buf = kmalloc(buf_size, GFP_KERNEL);
271f6e51c35SDave Jiang 	if (!buf)
272f6e51c35SDave Jiang 		return -ENOMEM;
273f6e51c35SDave Jiang 
274f6e51c35SDave Jiang 	off = 0;
275f6e51c35SDave Jiang 
276f6e51c35SDave Jiang 	off += scnprintf(buf + off, buf_size - off,
277f6e51c35SDave Jiang 			 "NTB Device Information:\n");
278f6e51c35SDave Jiang 
279f6e51c35SDave Jiang 	off += scnprintf(buf + off, buf_size - off,
280f6e51c35SDave Jiang 			 "Connection Topology -\t%s\n",
281f6e51c35SDave Jiang 			 ntb_topo_string(ndev->ntb.topo));
282f6e51c35SDave Jiang 
283f6e51c35SDave Jiang 	off += scnprintf(buf + off, buf_size - off,
284f6e51c35SDave Jiang 			 "NTB CTL -\t\t%#06x\n", ndev->ntb_ctl);
285f6e51c35SDave Jiang 	off += scnprintf(buf + off, buf_size - off,
286f6e51c35SDave Jiang 			 "LNK STA -\t\t%#06x\n", ndev->lnk_sta);
287f6e51c35SDave Jiang 
288f6e51c35SDave Jiang 	if (!ndev->reg->link_is_up(ndev))
289f6e51c35SDave Jiang 		off += scnprintf(buf + off, buf_size - off,
290f6e51c35SDave Jiang 				 "Link Status -\t\tDown\n");
291f6e51c35SDave Jiang 	else {
292f6e51c35SDave Jiang 		off += scnprintf(buf + off, buf_size - off,
293f6e51c35SDave Jiang 				 "Link Status -\t\tUp\n");
294f6e51c35SDave Jiang 		off += scnprintf(buf + off, buf_size - off,
295f6e51c35SDave Jiang 				 "Link Speed -\t\tPCI-E Gen %u\n",
296f6e51c35SDave Jiang 				 NTB_LNK_STA_SPEED(ndev->lnk_sta));
297f6e51c35SDave Jiang 		off += scnprintf(buf + off, buf_size - off,
298f6e51c35SDave Jiang 				 "Link Width -\t\tx%u\n",
299f6e51c35SDave Jiang 				 NTB_LNK_STA_WIDTH(ndev->lnk_sta));
300f6e51c35SDave Jiang 	}
301f6e51c35SDave Jiang 
302f6e51c35SDave Jiang 	off += scnprintf(buf + off, buf_size - off,
303f6e51c35SDave Jiang 			 "Memory Window Count -\t%u\n", ndev->mw_count);
304f6e51c35SDave Jiang 	off += scnprintf(buf + off, buf_size - off,
305f6e51c35SDave Jiang 			 "Scratchpad Count -\t%u\n", ndev->spad_count);
306f6e51c35SDave Jiang 	off += scnprintf(buf + off, buf_size - off,
307f6e51c35SDave Jiang 			 "Doorbell Count -\t%u\n", ndev->db_count);
308f6e51c35SDave Jiang 	off += scnprintf(buf + off, buf_size - off,
309f6e51c35SDave Jiang 			 "Doorbell Vector Count -\t%u\n", ndev->db_vec_count);
310f6e51c35SDave Jiang 	off += scnprintf(buf + off, buf_size - off,
311f6e51c35SDave Jiang 			 "Doorbell Vector Shift -\t%u\n", ndev->db_vec_shift);
312f6e51c35SDave Jiang 
313f6e51c35SDave Jiang 	off += scnprintf(buf + off, buf_size - off,
314f6e51c35SDave Jiang 			 "Doorbell Valid Mask -\t%#llx\n", ndev->db_valid_mask);
315f6e51c35SDave Jiang 	off += scnprintf(buf + off, buf_size - off,
316f6e51c35SDave Jiang 			 "Doorbell Link Mask -\t%#llx\n", ndev->db_link_mask);
317f6e51c35SDave Jiang 	off += scnprintf(buf + off, buf_size - off,
318f6e51c35SDave Jiang 			 "Doorbell Mask Cached -\t%#llx\n", ndev->db_mask);
319f6e51c35SDave Jiang 
320f6e51c35SDave Jiang 	u.v64 = ndev_db_read(ndev, mmio + ndev->self_reg->db_mask);
321f6e51c35SDave Jiang 	off += scnprintf(buf + off, buf_size - off,
322f6e51c35SDave Jiang 			 "Doorbell Mask -\t\t%#llx\n", u.v64);
323f6e51c35SDave Jiang 
324f6e51c35SDave Jiang 	u.v64 = ndev_db_read(ndev, mmio + ndev->self_reg->db_bell);
325f6e51c35SDave Jiang 	off += scnprintf(buf + off, buf_size - off,
326f6e51c35SDave Jiang 			 "Doorbell Bell -\t\t%#llx\n", u.v64);
327f6e51c35SDave Jiang 
328f6e51c35SDave Jiang 	off += scnprintf(buf + off, buf_size - off,
329f6e51c35SDave Jiang 			 "\nNTB Incoming XLAT:\n");
330f6e51c35SDave Jiang 
3316c1e8ab2SDave Jiang 	u.v64 = ioread64(mmio + GEN3_IMBAR1XBASE_OFFSET);
332f6e51c35SDave Jiang 	off += scnprintf(buf + off, buf_size - off,
333f6e51c35SDave Jiang 			 "IMBAR1XBASE -\t\t%#018llx\n", u.v64);
334f6e51c35SDave Jiang 
3356c1e8ab2SDave Jiang 	u.v64 = ioread64(mmio + GEN3_IMBAR2XBASE_OFFSET);
336f6e51c35SDave Jiang 	off += scnprintf(buf + off, buf_size - off,
337f6e51c35SDave Jiang 			 "IMBAR2XBASE -\t\t%#018llx\n", u.v64);
338f6e51c35SDave Jiang 
3396c1e8ab2SDave Jiang 	u.v64 = ioread64(mmio + GEN3_IMBAR1XLMT_OFFSET);
340f6e51c35SDave Jiang 	off += scnprintf(buf + off, buf_size - off,
341f6e51c35SDave Jiang 			 "IMBAR1XLMT -\t\t\t%#018llx\n", u.v64);
342f6e51c35SDave Jiang 
3436c1e8ab2SDave Jiang 	u.v64 = ioread64(mmio + GEN3_IMBAR2XLMT_OFFSET);
344f6e51c35SDave Jiang 	off += scnprintf(buf + off, buf_size - off,
345f6e51c35SDave Jiang 			 "IMBAR2XLMT -\t\t\t%#018llx\n", u.v64);
346f6e51c35SDave Jiang 
347f6e51c35SDave Jiang 	if (ntb_topo_is_b2b(ndev->ntb.topo)) {
348f6e51c35SDave Jiang 		off += scnprintf(buf + off, buf_size - off,
349f6e51c35SDave Jiang 				 "\nNTB Outgoing B2B XLAT:\n");
350f6e51c35SDave Jiang 
3516c1e8ab2SDave Jiang 		u.v64 = ioread64(mmio + GEN3_EMBAR1XBASE_OFFSET);
352f6e51c35SDave Jiang 		off += scnprintf(buf + off, buf_size - off,
353f6e51c35SDave Jiang 				 "EMBAR1XBASE -\t\t%#018llx\n", u.v64);
354f6e51c35SDave Jiang 
3556c1e8ab2SDave Jiang 		u.v64 = ioread64(mmio + GEN3_EMBAR2XBASE_OFFSET);
356f6e51c35SDave Jiang 		off += scnprintf(buf + off, buf_size - off,
357f6e51c35SDave Jiang 				 "EMBAR2XBASE -\t\t%#018llx\n", u.v64);
358f6e51c35SDave Jiang 
3596c1e8ab2SDave Jiang 		u.v64 = ioread64(mmio + GEN3_EMBAR1XLMT_OFFSET);
360f6e51c35SDave Jiang 		off += scnprintf(buf + off, buf_size - off,
361f6e51c35SDave Jiang 				 "EMBAR1XLMT -\t\t%#018llx\n", u.v64);
362f6e51c35SDave Jiang 
3636c1e8ab2SDave Jiang 		u.v64 = ioread64(mmio + GEN3_EMBAR2XLMT_OFFSET);
364f6e51c35SDave Jiang 		off += scnprintf(buf + off, buf_size - off,
365f6e51c35SDave Jiang 				 "EMBAR2XLMT -\t\t%#018llx\n", u.v64);
366f6e51c35SDave Jiang 
367f6e51c35SDave Jiang 		off += scnprintf(buf + off, buf_size - off,
368f6e51c35SDave Jiang 				 "\nNTB Secondary BAR:\n");
369f6e51c35SDave Jiang 
3706c1e8ab2SDave Jiang 		u.v64 = ioread64(mmio + GEN3_EMBAR0_OFFSET);
371f6e51c35SDave Jiang 		off += scnprintf(buf + off, buf_size - off,
372f6e51c35SDave Jiang 				 "EMBAR0 -\t\t%#018llx\n", u.v64);
373f6e51c35SDave Jiang 
3746c1e8ab2SDave Jiang 		u.v64 = ioread64(mmio + GEN3_EMBAR1_OFFSET);
375f6e51c35SDave Jiang 		off += scnprintf(buf + off, buf_size - off,
376f6e51c35SDave Jiang 				 "EMBAR1 -\t\t%#018llx\n", u.v64);
377f6e51c35SDave Jiang 
3786c1e8ab2SDave Jiang 		u.v64 = ioread64(mmio + GEN3_EMBAR2_OFFSET);
379f6e51c35SDave Jiang 		off += scnprintf(buf + off, buf_size - off,
380f6e51c35SDave Jiang 				 "EMBAR2 -\t\t%#018llx\n", u.v64);
381f6e51c35SDave Jiang 	}
382f6e51c35SDave Jiang 
383f6e51c35SDave Jiang 	off += scnprintf(buf + off, buf_size - off,
384f6e51c35SDave Jiang 			 "\nNTB Statistics:\n");
385f6e51c35SDave Jiang 
3866c1e8ab2SDave Jiang 	u.v16 = ioread16(mmio + GEN3_USMEMMISS_OFFSET);
387f6e51c35SDave Jiang 	off += scnprintf(buf + off, buf_size - off,
388f6e51c35SDave Jiang 			 "Upstream Memory Miss -\t%u\n", u.v16);
389f6e51c35SDave Jiang 
390f6e51c35SDave Jiang 	off += scnprintf(buf + off, buf_size - off,
391f6e51c35SDave Jiang 			 "\nNTB Hardware Errors:\n");
392f6e51c35SDave Jiang 
393f6e51c35SDave Jiang 	if (!pci_read_config_word(ndev->ntb.pdev,
3946c1e8ab2SDave Jiang 				  GEN3_DEVSTS_OFFSET, &u.v16))
395f6e51c35SDave Jiang 		off += scnprintf(buf + off, buf_size - off,
396f6e51c35SDave Jiang 				 "DEVSTS -\t\t%#06x\n", u.v16);
397f6e51c35SDave Jiang 
398f6e51c35SDave Jiang 	if (!pci_read_config_word(ndev->ntb.pdev,
3996c1e8ab2SDave Jiang 				  GEN3_LINK_STATUS_OFFSET, &u.v16))
400f6e51c35SDave Jiang 		off += scnprintf(buf + off, buf_size - off,
401f6e51c35SDave Jiang 				 "LNKSTS -\t\t%#06x\n", u.v16);
402f6e51c35SDave Jiang 
403f6e51c35SDave Jiang 	if (!pci_read_config_dword(ndev->ntb.pdev,
4046c1e8ab2SDave Jiang 				   GEN3_UNCERRSTS_OFFSET, &u.v32))
405f6e51c35SDave Jiang 		off += scnprintf(buf + off, buf_size - off,
406f6e51c35SDave Jiang 				 "UNCERRSTS -\t\t%#06x\n", u.v32);
407f6e51c35SDave Jiang 
408f6e51c35SDave Jiang 	if (!pci_read_config_dword(ndev->ntb.pdev,
4096c1e8ab2SDave Jiang 				   GEN3_CORERRSTS_OFFSET, &u.v32))
410f6e51c35SDave Jiang 		off += scnprintf(buf + off, buf_size - off,
411f6e51c35SDave Jiang 				 "CORERRSTS -\t\t%#06x\n", u.v32);
412f6e51c35SDave Jiang 
413f6e51c35SDave Jiang 	ret = simple_read_from_buffer(ubuf, count, offp, buf, off);
414f6e51c35SDave Jiang 	kfree(buf);
415f6e51c35SDave Jiang 	return ret;
416f6e51c35SDave Jiang }
417f6e51c35SDave Jiang 
intel_ntb3_link_enable(struct ntb_dev * ntb,enum ntb_speed max_speed,enum ntb_width max_width)418*26bfe3d0SDave Jiang int intel_ntb3_link_enable(struct ntb_dev *ntb, enum ntb_speed max_speed,
419f6e51c35SDave Jiang 		enum ntb_width max_width)
420f6e51c35SDave Jiang {
421f6e51c35SDave Jiang 	struct intel_ntb_dev *ndev;
422f6e51c35SDave Jiang 	u32 ntb_ctl;
423f6e51c35SDave Jiang 
424f6e51c35SDave Jiang 	ndev = container_of(ntb, struct intel_ntb_dev, ntb);
425f6e51c35SDave Jiang 
426f6e51c35SDave Jiang 	dev_dbg(&ntb->pdev->dev,
427f6e51c35SDave Jiang 		"Enabling link with max_speed %d max_width %d\n",
428f6e51c35SDave Jiang 		max_speed, max_width);
429f6e51c35SDave Jiang 
430f6e51c35SDave Jiang 	if (max_speed != NTB_SPEED_AUTO)
431f6e51c35SDave Jiang 		dev_dbg(&ntb->pdev->dev, "ignoring max_speed %d\n", max_speed);
432f6e51c35SDave Jiang 	if (max_width != NTB_WIDTH_AUTO)
433f6e51c35SDave Jiang 		dev_dbg(&ntb->pdev->dev, "ignoring max_width %d\n", max_width);
434f6e51c35SDave Jiang 
435f6e51c35SDave Jiang 	ntb_ctl = ioread32(ndev->self_mmio + ndev->reg->ntb_ctl);
436f6e51c35SDave Jiang 	ntb_ctl &= ~(NTB_CTL_DISABLE | NTB_CTL_CFG_LOCK);
437f6e51c35SDave Jiang 	ntb_ctl |= NTB_CTL_P2S_BAR2_SNOOP | NTB_CTL_S2P_BAR2_SNOOP;
438f6e51c35SDave Jiang 	ntb_ctl |= NTB_CTL_P2S_BAR4_SNOOP | NTB_CTL_S2P_BAR4_SNOOP;
439f6e51c35SDave Jiang 	iowrite32(ntb_ctl, ndev->self_mmio + ndev->reg->ntb_ctl);
440f6e51c35SDave Jiang 
441f6e51c35SDave Jiang 	return 0;
442f6e51c35SDave Jiang }
intel_ntb3_mw_set_trans(struct ntb_dev * ntb,int pidx,int idx,dma_addr_t addr,resource_size_t size)443f6e51c35SDave Jiang static int intel_ntb3_mw_set_trans(struct ntb_dev *ntb, int pidx, int idx,
444f6e51c35SDave Jiang 				   dma_addr_t addr, resource_size_t size)
445f6e51c35SDave Jiang {
446f6e51c35SDave Jiang 	struct intel_ntb_dev *ndev = ntb_ndev(ntb);
447f6e51c35SDave Jiang 	unsigned long xlat_reg, limit_reg;
448f6e51c35SDave Jiang 	resource_size_t bar_size, mw_size;
449f6e51c35SDave Jiang 	void __iomem *mmio;
450f6e51c35SDave Jiang 	u64 base, limit, reg_val;
451f6e51c35SDave Jiang 	int bar;
452f6e51c35SDave Jiang 
453f6e51c35SDave Jiang 	if (pidx != NTB_DEF_PEER_IDX)
454f6e51c35SDave Jiang 		return -EINVAL;
455f6e51c35SDave Jiang 
456f6e51c35SDave Jiang 	if (idx >= ndev->b2b_idx && !ndev->b2b_off)
457f6e51c35SDave Jiang 		idx += 1;
458f6e51c35SDave Jiang 
459f6e51c35SDave Jiang 	bar = ndev_mw_to_bar(ndev, idx);
460f6e51c35SDave Jiang 	if (bar < 0)
461f6e51c35SDave Jiang 		return bar;
462f6e51c35SDave Jiang 
463f6e51c35SDave Jiang 	bar_size = pci_resource_len(ndev->ntb.pdev, bar);
464f6e51c35SDave Jiang 
465f6e51c35SDave Jiang 	if (idx == ndev->b2b_idx)
466f6e51c35SDave Jiang 		mw_size = bar_size - ndev->b2b_off;
467f6e51c35SDave Jiang 	else
468f6e51c35SDave Jiang 		mw_size = bar_size;
469f6e51c35SDave Jiang 
470f6e51c35SDave Jiang 	/* hardware requires that addr is aligned to bar size */
471f6e51c35SDave Jiang 	if (addr & (bar_size - 1))
472f6e51c35SDave Jiang 		return -EINVAL;
473f6e51c35SDave Jiang 
474f6e51c35SDave Jiang 	/* make sure the range fits in the usable mw size */
475f6e51c35SDave Jiang 	if (size > mw_size)
476f6e51c35SDave Jiang 		return -EINVAL;
477f6e51c35SDave Jiang 
478f6e51c35SDave Jiang 	mmio = ndev->self_mmio;
479f6e51c35SDave Jiang 	xlat_reg = ndev->xlat_reg->bar2_xlat + (idx * 0x10);
480f6e51c35SDave Jiang 	limit_reg = ndev->xlat_reg->bar2_limit + (idx * 0x10);
481f6e51c35SDave Jiang 	base = pci_resource_start(ndev->ntb.pdev, bar);
482f6e51c35SDave Jiang 
483f6e51c35SDave Jiang 	/* Set the limit if supported, if size is not mw_size */
484f6e51c35SDave Jiang 	if (limit_reg && size != mw_size)
485f6e51c35SDave Jiang 		limit = base + size;
486f6e51c35SDave Jiang 	else
487f6e51c35SDave Jiang 		limit = base + mw_size;
488f6e51c35SDave Jiang 
489f6e51c35SDave Jiang 	/* set and verify setting the translation address */
490f6e51c35SDave Jiang 	iowrite64(addr, mmio + xlat_reg);
491f6e51c35SDave Jiang 	reg_val = ioread64(mmio + xlat_reg);
492f6e51c35SDave Jiang 	if (reg_val != addr) {
493f6e51c35SDave Jiang 		iowrite64(0, mmio + xlat_reg);
494f6e51c35SDave Jiang 		return -EIO;
495f6e51c35SDave Jiang 	}
496f6e51c35SDave Jiang 
497f6e51c35SDave Jiang 	dev_dbg(&ntb->pdev->dev, "BAR %d IMBARXBASE: %#Lx\n", bar, reg_val);
498f6e51c35SDave Jiang 
499f6e51c35SDave Jiang 	/* set and verify setting the limit */
500f6e51c35SDave Jiang 	iowrite64(limit, mmio + limit_reg);
501f6e51c35SDave Jiang 	reg_val = ioread64(mmio + limit_reg);
502f6e51c35SDave Jiang 	if (reg_val != limit) {
503f6e51c35SDave Jiang 		iowrite64(base, mmio + limit_reg);
504f6e51c35SDave Jiang 		iowrite64(0, mmio + xlat_reg);
505f6e51c35SDave Jiang 		return -EIO;
506f6e51c35SDave Jiang 	}
507f6e51c35SDave Jiang 
508f6e51c35SDave Jiang 	dev_dbg(&ntb->pdev->dev, "BAR %d IMBARXLMT: %#Lx\n", bar, reg_val);
509f6e51c35SDave Jiang 
510f6e51c35SDave Jiang 	/* setup the EP */
511f6e51c35SDave Jiang 	limit_reg = ndev->xlat_reg->bar2_limit + (idx * 0x10) + 0x4000;
5126c1e8ab2SDave Jiang 	base = ioread64(mmio + GEN3_EMBAR1_OFFSET + (8 * idx));
513f6e51c35SDave Jiang 	base &= ~0xf;
514f6e51c35SDave Jiang 
515f6e51c35SDave Jiang 	if (limit_reg && size != mw_size)
516f6e51c35SDave Jiang 		limit = base + size;
517f6e51c35SDave Jiang 	else
518f6e51c35SDave Jiang 		limit = base + mw_size;
519f6e51c35SDave Jiang 
520f6e51c35SDave Jiang 	/* set and verify setting the limit */
521f6e51c35SDave Jiang 	iowrite64(limit, mmio + limit_reg);
522f6e51c35SDave Jiang 	reg_val = ioread64(mmio + limit_reg);
523f6e51c35SDave Jiang 	if (reg_val != limit) {
524f6e51c35SDave Jiang 		iowrite64(base, mmio + limit_reg);
525f6e51c35SDave Jiang 		iowrite64(0, mmio + xlat_reg);
526f6e51c35SDave Jiang 		return -EIO;
527f6e51c35SDave Jiang 	}
528f6e51c35SDave Jiang 
529f6e51c35SDave Jiang 	dev_dbg(&ntb->pdev->dev, "BAR %d EMBARXLMT: %#Lx\n", bar, reg_val);
530f6e51c35SDave Jiang 
531f6e51c35SDave Jiang 	return 0;
532f6e51c35SDave Jiang }
533f6e51c35SDave Jiang 
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)534*26bfe3d0SDave Jiang int intel_ntb3_peer_db_addr(struct ntb_dev *ntb, phys_addr_t *db_addr,
535ebb09b33SLeonid Ravich 				   resource_size_t *db_size,
536ebb09b33SLeonid Ravich 				   u64 *db_data, int db_bit)
537ebb09b33SLeonid Ravich {
538ebb09b33SLeonid Ravich 	phys_addr_t db_addr_base;
539ebb09b33SLeonid Ravich 	struct intel_ntb_dev *ndev = ntb_ndev(ntb);
540ebb09b33SLeonid Ravich 
541ebb09b33SLeonid Ravich 	if (unlikely(db_bit >= BITS_PER_LONG_LONG))
542ebb09b33SLeonid Ravich 		return -EINVAL;
543ebb09b33SLeonid Ravich 
544ebb09b33SLeonid Ravich 	if (unlikely(BIT_ULL(db_bit) & ~ntb_ndev(ntb)->db_valid_mask))
545ebb09b33SLeonid Ravich 		return -EINVAL;
546ebb09b33SLeonid Ravich 
547ebb09b33SLeonid Ravich 	ndev_db_addr(ndev, &db_addr_base, db_size, ndev->peer_addr,
548ebb09b33SLeonid Ravich 				ndev->peer_reg->db_bell);
549ebb09b33SLeonid Ravich 
550ebb09b33SLeonid Ravich 	if (db_addr) {
551ebb09b33SLeonid Ravich 		*db_addr = db_addr_base + (db_bit * 4);
552ebb09b33SLeonid Ravich 		dev_dbg(&ndev->ntb.pdev->dev, "Peer db addr %llx db bit %d\n",
553ebb09b33SLeonid Ravich 				*db_addr, db_bit);
554ebb09b33SLeonid Ravich 	}
555ebb09b33SLeonid Ravich 
556ebb09b33SLeonid Ravich 	if (db_data) {
557ebb09b33SLeonid Ravich 		*db_data = 1;
558ebb09b33SLeonid Ravich 		dev_dbg(&ndev->ntb.pdev->dev, "Peer db data %llx db bit %d\n",
559ebb09b33SLeonid Ravich 				*db_data, db_bit);
560ebb09b33SLeonid Ravich 	}
561ebb09b33SLeonid Ravich 
562ebb09b33SLeonid Ravich 	return 0;
563ebb09b33SLeonid Ravich }
564ebb09b33SLeonid Ravich 
intel_ntb3_peer_db_set(struct ntb_dev * ntb,u64 db_bits)565*26bfe3d0SDave Jiang int intel_ntb3_peer_db_set(struct ntb_dev *ntb, u64 db_bits)
566f6e51c35SDave Jiang {
567f6e51c35SDave Jiang 	struct intel_ntb_dev *ndev = ntb_ndev(ntb);
568f6e51c35SDave Jiang 	int bit;
569f6e51c35SDave Jiang 
570f6e51c35SDave Jiang 	if (db_bits & ~ndev->db_valid_mask)
571f6e51c35SDave Jiang 		return -EINVAL;
572f6e51c35SDave Jiang 
573f6e51c35SDave Jiang 	while (db_bits) {
574f6e51c35SDave Jiang 		bit = __ffs(db_bits);
575f6e51c35SDave Jiang 		iowrite32(1, ndev->peer_mmio +
576f6e51c35SDave Jiang 				ndev->peer_reg->db_bell + (bit * 4));
577f6e51c35SDave Jiang 		db_bits &= db_bits - 1;
578f6e51c35SDave Jiang 	}
579f6e51c35SDave Jiang 
580f6e51c35SDave Jiang 	return 0;
581f6e51c35SDave Jiang }
582f6e51c35SDave Jiang 
intel_ntb3_db_read(struct ntb_dev * ntb)583*26bfe3d0SDave Jiang u64 intel_ntb3_db_read(struct ntb_dev *ntb)
584f6e51c35SDave Jiang {
585f6e51c35SDave Jiang 	struct intel_ntb_dev *ndev = ntb_ndev(ntb);
586f6e51c35SDave Jiang 
587f6e51c35SDave Jiang 	return ndev_db_read(ndev,
588f6e51c35SDave Jiang 			    ndev->self_mmio +
589f6e51c35SDave Jiang 			    ndev->self_reg->db_clear);
590f6e51c35SDave Jiang }
591f6e51c35SDave Jiang 
intel_ntb3_db_clear(struct ntb_dev * ntb,u64 db_bits)592*26bfe3d0SDave Jiang int intel_ntb3_db_clear(struct ntb_dev *ntb, u64 db_bits)
593f6e51c35SDave Jiang {
594f6e51c35SDave Jiang 	struct intel_ntb_dev *ndev = ntb_ndev(ntb);
595f6e51c35SDave Jiang 
596f6e51c35SDave Jiang 	return ndev_db_write(ndev, db_bits,
597f6e51c35SDave Jiang 			     ndev->self_mmio +
598f6e51c35SDave Jiang 			     ndev->self_reg->db_clear);
599f6e51c35SDave Jiang }
600f6e51c35SDave Jiang 
601f6e51c35SDave Jiang const struct ntb_dev_ops intel_ntb3_ops = {
602f6e51c35SDave Jiang 	.mw_count		= intel_ntb_mw_count,
603f6e51c35SDave Jiang 	.mw_get_align		= intel_ntb_mw_get_align,
604f6e51c35SDave Jiang 	.mw_set_trans		= intel_ntb3_mw_set_trans,
605f6e51c35SDave Jiang 	.peer_mw_count		= intel_ntb_peer_mw_count,
606f6e51c35SDave Jiang 	.peer_mw_get_addr	= intel_ntb_peer_mw_get_addr,
607f6e51c35SDave Jiang 	.link_is_up		= intel_ntb_link_is_up,
608f6e51c35SDave Jiang 	.link_enable		= intel_ntb3_link_enable,
609f6e51c35SDave Jiang 	.link_disable		= intel_ntb_link_disable,
610f6e51c35SDave Jiang 	.db_valid_mask		= intel_ntb_db_valid_mask,
611f6e51c35SDave Jiang 	.db_vector_count	= intel_ntb_db_vector_count,
612f6e51c35SDave Jiang 	.db_vector_mask		= intel_ntb_db_vector_mask,
613f6e51c35SDave Jiang 	.db_read		= intel_ntb3_db_read,
614f6e51c35SDave Jiang 	.db_clear		= intel_ntb3_db_clear,
615f6e51c35SDave Jiang 	.db_set_mask		= intel_ntb_db_set_mask,
616f6e51c35SDave Jiang 	.db_clear_mask		= intel_ntb_db_clear_mask,
617ebb09b33SLeonid Ravich 	.peer_db_addr		= intel_ntb3_peer_db_addr,
618f6e51c35SDave Jiang 	.peer_db_set		= intel_ntb3_peer_db_set,
619f6e51c35SDave Jiang 	.spad_is_unsafe		= intel_ntb_spad_is_unsafe,
620f6e51c35SDave Jiang 	.spad_count		= intel_ntb_spad_count,
621f6e51c35SDave Jiang 	.spad_read		= intel_ntb_spad_read,
622f6e51c35SDave Jiang 	.spad_write		= intel_ntb_spad_write,
623f6e51c35SDave Jiang 	.peer_spad_addr		= intel_ntb_peer_spad_addr,
624f6e51c35SDave Jiang 	.peer_spad_read		= intel_ntb_peer_spad_read,
625f6e51c35SDave Jiang 	.peer_spad_write	= intel_ntb_peer_spad_write,
626f6e51c35SDave Jiang };
627f6e51c35SDave Jiang 
628