18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * This file is provided under a dual BSD/GPLv2 license. When using or 38c2ecf20Sopenharmony_ci * redistributing this file, you may do so under either license. 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * GPL LICENSE SUMMARY 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * Copyright(c) 2017 Intel Corporation. All rights reserved. 88c2ecf20Sopenharmony_ci * 98c2ecf20Sopenharmony_ci * This program is free software; you can redistribute it and/or modify 108c2ecf20Sopenharmony_ci * it under the terms of version 2 of the GNU General Public License as 118c2ecf20Sopenharmony_ci * published by the Free Software Foundation. 128c2ecf20Sopenharmony_ci * 138c2ecf20Sopenharmony_ci * BSD LICENSE 148c2ecf20Sopenharmony_ci * 158c2ecf20Sopenharmony_ci * Copyright(c) 2017 Intel Corporation. All rights reserved. 168c2ecf20Sopenharmony_ci * 178c2ecf20Sopenharmony_ci * Redistribution and use in source and binary forms, with or without 188c2ecf20Sopenharmony_ci * modification, are permitted provided that the following conditions 198c2ecf20Sopenharmony_ci * are met: 208c2ecf20Sopenharmony_ci * 218c2ecf20Sopenharmony_ci * * Redistributions of source code must retain the above copyright 228c2ecf20Sopenharmony_ci * notice, this list of conditions and the following disclaimer. 238c2ecf20Sopenharmony_ci * * Redistributions in binary form must reproduce the above copy 248c2ecf20Sopenharmony_ci * notice, this list of conditions and the following disclaimer in 258c2ecf20Sopenharmony_ci * the documentation and/or other materials provided with the 268c2ecf20Sopenharmony_ci * distribution. 278c2ecf20Sopenharmony_ci * * Neither the name of Intel Corporation nor the names of its 288c2ecf20Sopenharmony_ci * contributors may be used to endorse or promote products derived 298c2ecf20Sopenharmony_ci * from this software without specific prior written permission. 308c2ecf20Sopenharmony_ci * 318c2ecf20Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 328c2ecf20Sopenharmony_ci * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 338c2ecf20Sopenharmony_ci * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 348c2ecf20Sopenharmony_ci * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 358c2ecf20Sopenharmony_ci * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 368c2ecf20Sopenharmony_ci * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 378c2ecf20Sopenharmony_ci * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 388c2ecf20Sopenharmony_ci * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 398c2ecf20Sopenharmony_ci * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 408c2ecf20Sopenharmony_ci * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 418c2ecf20Sopenharmony_ci * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 428c2ecf20Sopenharmony_ci * 438c2ecf20Sopenharmony_ci * Intel PCIe GEN3 NTB Linux driver 448c2ecf20Sopenharmony_ci * 458c2ecf20Sopenharmony_ci */ 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci#include <linux/debugfs.h> 488c2ecf20Sopenharmony_ci#include <linux/delay.h> 498c2ecf20Sopenharmony_ci#include <linux/init.h> 508c2ecf20Sopenharmony_ci#include <linux/interrupt.h> 518c2ecf20Sopenharmony_ci#include <linux/module.h> 528c2ecf20Sopenharmony_ci#include <linux/pci.h> 538c2ecf20Sopenharmony_ci#include <linux/random.h> 548c2ecf20Sopenharmony_ci#include <linux/slab.h> 558c2ecf20Sopenharmony_ci#include <linux/ntb.h> 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci#include "ntb_hw_intel.h" 588c2ecf20Sopenharmony_ci#include "ntb_hw_gen1.h" 598c2ecf20Sopenharmony_ci#include "ntb_hw_gen3.h" 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_cistatic int gen3_poll_link(struct intel_ntb_dev *ndev); 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_cistatic const struct intel_ntb_reg gen3_reg = { 648c2ecf20Sopenharmony_ci .poll_link = gen3_poll_link, 658c2ecf20Sopenharmony_ci .link_is_up = xeon_link_is_up, 668c2ecf20Sopenharmony_ci .db_ioread = gen3_db_ioread, 678c2ecf20Sopenharmony_ci .db_iowrite = gen3_db_iowrite, 688c2ecf20Sopenharmony_ci .db_size = sizeof(u32), 698c2ecf20Sopenharmony_ci .ntb_ctl = GEN3_NTBCNTL_OFFSET, 708c2ecf20Sopenharmony_ci .mw_bar = {2, 4}, 718c2ecf20Sopenharmony_ci}; 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_cistatic const struct intel_ntb_alt_reg gen3_pri_reg = { 748c2ecf20Sopenharmony_ci .db_bell = GEN3_EM_DOORBELL_OFFSET, 758c2ecf20Sopenharmony_ci .db_clear = GEN3_IM_INT_STATUS_OFFSET, 768c2ecf20Sopenharmony_ci .db_mask = GEN3_IM_INT_DISABLE_OFFSET, 778c2ecf20Sopenharmony_ci .spad = GEN3_IM_SPAD_OFFSET, 788c2ecf20Sopenharmony_ci}; 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_cistatic const struct intel_ntb_alt_reg gen3_b2b_reg = { 818c2ecf20Sopenharmony_ci .db_bell = GEN3_IM_DOORBELL_OFFSET, 828c2ecf20Sopenharmony_ci .db_clear = GEN3_EM_INT_STATUS_OFFSET, 838c2ecf20Sopenharmony_ci .db_mask = GEN3_EM_INT_DISABLE_OFFSET, 848c2ecf20Sopenharmony_ci .spad = GEN3_B2B_SPAD_OFFSET, 858c2ecf20Sopenharmony_ci}; 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_cistatic const struct intel_ntb_xlat_reg gen3_sec_xlat = { 888c2ecf20Sopenharmony_ci/* .bar0_base = GEN3_EMBAR0_OFFSET, */ 898c2ecf20Sopenharmony_ci .bar2_limit = GEN3_IMBAR1XLMT_OFFSET, 908c2ecf20Sopenharmony_ci .bar2_xlat = GEN3_IMBAR1XBASE_OFFSET, 918c2ecf20Sopenharmony_ci}; 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_cistatic int gen3_poll_link(struct intel_ntb_dev *ndev) 948c2ecf20Sopenharmony_ci{ 958c2ecf20Sopenharmony_ci u16 reg_val; 968c2ecf20Sopenharmony_ci int rc; 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_ci ndev->reg->db_iowrite(ndev->db_link_mask, 998c2ecf20Sopenharmony_ci ndev->self_mmio + 1008c2ecf20Sopenharmony_ci ndev->self_reg->db_clear); 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_ci rc = pci_read_config_word(ndev->ntb.pdev, 1038c2ecf20Sopenharmony_ci GEN3_LINK_STATUS_OFFSET, ®_val); 1048c2ecf20Sopenharmony_ci if (rc) 1058c2ecf20Sopenharmony_ci return 0; 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_ci if (reg_val == ndev->lnk_sta) 1088c2ecf20Sopenharmony_ci return 0; 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_ci ndev->lnk_sta = reg_val; 1118c2ecf20Sopenharmony_ci 1128c2ecf20Sopenharmony_ci return 1; 1138c2ecf20Sopenharmony_ci} 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_cistatic int gen3_init_isr(struct intel_ntb_dev *ndev) 1168c2ecf20Sopenharmony_ci{ 1178c2ecf20Sopenharmony_ci int i; 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ci /* 1208c2ecf20Sopenharmony_ci * The MSIX vectors and the interrupt status bits are not lined up 1218c2ecf20Sopenharmony_ci * on Skylake. By default the link status bit is bit 32, however it 1228c2ecf20Sopenharmony_ci * is by default MSIX vector0. We need to fixup to line them up. 1238c2ecf20Sopenharmony_ci * The vectors at reset is 1-32,0. We need to reprogram to 0-32. 1248c2ecf20Sopenharmony_ci */ 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_ci for (i = 0; i < GEN3_DB_MSIX_VECTOR_COUNT; i++) 1278c2ecf20Sopenharmony_ci iowrite8(i, ndev->self_mmio + GEN3_INTVEC_OFFSET + i); 1288c2ecf20Sopenharmony_ci 1298c2ecf20Sopenharmony_ci /* move link status down one as workaround */ 1308c2ecf20Sopenharmony_ci if (ndev->hwerr_flags & NTB_HWERR_MSIX_VECTOR32_BAD) { 1318c2ecf20Sopenharmony_ci iowrite8(GEN3_DB_MSIX_VECTOR_COUNT - 2, 1328c2ecf20Sopenharmony_ci ndev->self_mmio + GEN3_INTVEC_OFFSET + 1338c2ecf20Sopenharmony_ci (GEN3_DB_MSIX_VECTOR_COUNT - 1)); 1348c2ecf20Sopenharmony_ci } 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_ci return ndev_init_isr(ndev, GEN3_DB_MSIX_VECTOR_COUNT, 1378c2ecf20Sopenharmony_ci GEN3_DB_MSIX_VECTOR_COUNT, 1388c2ecf20Sopenharmony_ci GEN3_DB_MSIX_VECTOR_SHIFT, 1398c2ecf20Sopenharmony_ci GEN3_DB_TOTAL_SHIFT); 1408c2ecf20Sopenharmony_ci} 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_cistatic int gen3_setup_b2b_mw(struct intel_ntb_dev *ndev, 1438c2ecf20Sopenharmony_ci const struct intel_b2b_addr *addr, 1448c2ecf20Sopenharmony_ci const struct intel_b2b_addr *peer_addr) 1458c2ecf20Sopenharmony_ci{ 1468c2ecf20Sopenharmony_ci struct pci_dev *pdev; 1478c2ecf20Sopenharmony_ci void __iomem *mmio; 1488c2ecf20Sopenharmony_ci phys_addr_t bar_addr; 1498c2ecf20Sopenharmony_ci 1508c2ecf20Sopenharmony_ci pdev = ndev->ntb.pdev; 1518c2ecf20Sopenharmony_ci mmio = ndev->self_mmio; 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_ci /* setup incoming bar limits == base addrs (zero length windows) */ 1548c2ecf20Sopenharmony_ci bar_addr = addr->bar2_addr64; 1558c2ecf20Sopenharmony_ci iowrite64(bar_addr, mmio + GEN3_IMBAR1XLMT_OFFSET); 1568c2ecf20Sopenharmony_ci bar_addr = ioread64(mmio + GEN3_IMBAR1XLMT_OFFSET); 1578c2ecf20Sopenharmony_ci dev_dbg(&pdev->dev, "IMBAR1XLMT %#018llx\n", bar_addr); 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_ci bar_addr = addr->bar4_addr64; 1608c2ecf20Sopenharmony_ci iowrite64(bar_addr, mmio + GEN3_IMBAR2XLMT_OFFSET); 1618c2ecf20Sopenharmony_ci bar_addr = ioread64(mmio + GEN3_IMBAR2XLMT_OFFSET); 1628c2ecf20Sopenharmony_ci dev_dbg(&pdev->dev, "IMBAR2XLMT %#018llx\n", bar_addr); 1638c2ecf20Sopenharmony_ci 1648c2ecf20Sopenharmony_ci /* zero incoming translation addrs */ 1658c2ecf20Sopenharmony_ci iowrite64(0, mmio + GEN3_IMBAR1XBASE_OFFSET); 1668c2ecf20Sopenharmony_ci iowrite64(0, mmio + GEN3_IMBAR2XBASE_OFFSET); 1678c2ecf20Sopenharmony_ci 1688c2ecf20Sopenharmony_ci ndev->peer_mmio = ndev->self_mmio; 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_ci return 0; 1718c2ecf20Sopenharmony_ci} 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_cistatic int gen3_init_ntb(struct intel_ntb_dev *ndev) 1748c2ecf20Sopenharmony_ci{ 1758c2ecf20Sopenharmony_ci int rc; 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_ci 1788c2ecf20Sopenharmony_ci ndev->mw_count = XEON_MW_COUNT; 1798c2ecf20Sopenharmony_ci ndev->spad_count = GEN3_SPAD_COUNT; 1808c2ecf20Sopenharmony_ci ndev->db_count = GEN3_DB_COUNT; 1818c2ecf20Sopenharmony_ci ndev->db_link_mask = GEN3_DB_LINK_BIT; 1828c2ecf20Sopenharmony_ci 1838c2ecf20Sopenharmony_ci /* DB fixup for using 31 right now */ 1848c2ecf20Sopenharmony_ci if (ndev->hwerr_flags & NTB_HWERR_MSIX_VECTOR32_BAD) 1858c2ecf20Sopenharmony_ci ndev->db_link_mask |= BIT_ULL(31); 1868c2ecf20Sopenharmony_ci 1878c2ecf20Sopenharmony_ci switch (ndev->ntb.topo) { 1888c2ecf20Sopenharmony_ci case NTB_TOPO_B2B_USD: 1898c2ecf20Sopenharmony_ci case NTB_TOPO_B2B_DSD: 1908c2ecf20Sopenharmony_ci ndev->self_reg = &gen3_pri_reg; 1918c2ecf20Sopenharmony_ci ndev->peer_reg = &gen3_b2b_reg; 1928c2ecf20Sopenharmony_ci ndev->xlat_reg = &gen3_sec_xlat; 1938c2ecf20Sopenharmony_ci 1948c2ecf20Sopenharmony_ci if (ndev->ntb.topo == NTB_TOPO_B2B_USD) { 1958c2ecf20Sopenharmony_ci rc = gen3_setup_b2b_mw(ndev, 1968c2ecf20Sopenharmony_ci &xeon_b2b_dsd_addr, 1978c2ecf20Sopenharmony_ci &xeon_b2b_usd_addr); 1988c2ecf20Sopenharmony_ci } else { 1998c2ecf20Sopenharmony_ci rc = gen3_setup_b2b_mw(ndev, 2008c2ecf20Sopenharmony_ci &xeon_b2b_usd_addr, 2018c2ecf20Sopenharmony_ci &xeon_b2b_dsd_addr); 2028c2ecf20Sopenharmony_ci } 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_ci if (rc) 2058c2ecf20Sopenharmony_ci return rc; 2068c2ecf20Sopenharmony_ci 2078c2ecf20Sopenharmony_ci /* Enable Bus Master and Memory Space on the secondary side */ 2088c2ecf20Sopenharmony_ci iowrite16(PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER, 2098c2ecf20Sopenharmony_ci ndev->self_mmio + GEN3_SPCICMD_OFFSET); 2108c2ecf20Sopenharmony_ci 2118c2ecf20Sopenharmony_ci break; 2128c2ecf20Sopenharmony_ci 2138c2ecf20Sopenharmony_ci default: 2148c2ecf20Sopenharmony_ci return -EINVAL; 2158c2ecf20Sopenharmony_ci } 2168c2ecf20Sopenharmony_ci 2178c2ecf20Sopenharmony_ci ndev->db_valid_mask = BIT_ULL(ndev->db_count) - 1; 2188c2ecf20Sopenharmony_ci 2198c2ecf20Sopenharmony_ci ndev->reg->db_iowrite(ndev->db_valid_mask, 2208c2ecf20Sopenharmony_ci ndev->self_mmio + 2218c2ecf20Sopenharmony_ci ndev->self_reg->db_mask); 2228c2ecf20Sopenharmony_ci 2238c2ecf20Sopenharmony_ci return 0; 2248c2ecf20Sopenharmony_ci} 2258c2ecf20Sopenharmony_ci 2268c2ecf20Sopenharmony_ciint gen3_init_dev(struct intel_ntb_dev *ndev) 2278c2ecf20Sopenharmony_ci{ 2288c2ecf20Sopenharmony_ci struct pci_dev *pdev; 2298c2ecf20Sopenharmony_ci u8 ppd; 2308c2ecf20Sopenharmony_ci int rc; 2318c2ecf20Sopenharmony_ci 2328c2ecf20Sopenharmony_ci pdev = ndev->ntb.pdev; 2338c2ecf20Sopenharmony_ci 2348c2ecf20Sopenharmony_ci ndev->reg = &gen3_reg; 2358c2ecf20Sopenharmony_ci 2368c2ecf20Sopenharmony_ci rc = pci_read_config_byte(pdev, XEON_PPD_OFFSET, &ppd); 2378c2ecf20Sopenharmony_ci if (rc) 2388c2ecf20Sopenharmony_ci return -EIO; 2398c2ecf20Sopenharmony_ci 2408c2ecf20Sopenharmony_ci ndev->ntb.topo = xeon_ppd_topo(ndev, ppd); 2418c2ecf20Sopenharmony_ci dev_dbg(&pdev->dev, "ppd %#x topo %s\n", ppd, 2428c2ecf20Sopenharmony_ci ntb_topo_string(ndev->ntb.topo)); 2438c2ecf20Sopenharmony_ci if (ndev->ntb.topo == NTB_TOPO_NONE) 2448c2ecf20Sopenharmony_ci return -EINVAL; 2458c2ecf20Sopenharmony_ci 2468c2ecf20Sopenharmony_ci ndev->hwerr_flags |= NTB_HWERR_MSIX_VECTOR32_BAD; 2478c2ecf20Sopenharmony_ci 2488c2ecf20Sopenharmony_ci rc = gen3_init_ntb(ndev); 2498c2ecf20Sopenharmony_ci if (rc) 2508c2ecf20Sopenharmony_ci return rc; 2518c2ecf20Sopenharmony_ci 2528c2ecf20Sopenharmony_ci return gen3_init_isr(ndev); 2538c2ecf20Sopenharmony_ci} 2548c2ecf20Sopenharmony_ci 2558c2ecf20Sopenharmony_cissize_t ndev_ntb3_debugfs_read(struct file *filp, char __user *ubuf, 2568c2ecf20Sopenharmony_ci size_t count, loff_t *offp) 2578c2ecf20Sopenharmony_ci{ 2588c2ecf20Sopenharmony_ci struct intel_ntb_dev *ndev; 2598c2ecf20Sopenharmony_ci void __iomem *mmio; 2608c2ecf20Sopenharmony_ci char *buf; 2618c2ecf20Sopenharmony_ci size_t buf_size; 2628c2ecf20Sopenharmony_ci ssize_t ret, off; 2638c2ecf20Sopenharmony_ci union { u64 v64; u32 v32; u16 v16; } u; 2648c2ecf20Sopenharmony_ci 2658c2ecf20Sopenharmony_ci ndev = filp->private_data; 2668c2ecf20Sopenharmony_ci mmio = ndev->self_mmio; 2678c2ecf20Sopenharmony_ci 2688c2ecf20Sopenharmony_ci buf_size = min(count, 0x800ul); 2698c2ecf20Sopenharmony_ci 2708c2ecf20Sopenharmony_ci buf = kmalloc(buf_size, GFP_KERNEL); 2718c2ecf20Sopenharmony_ci if (!buf) 2728c2ecf20Sopenharmony_ci return -ENOMEM; 2738c2ecf20Sopenharmony_ci 2748c2ecf20Sopenharmony_ci off = 0; 2758c2ecf20Sopenharmony_ci 2768c2ecf20Sopenharmony_ci off += scnprintf(buf + off, buf_size - off, 2778c2ecf20Sopenharmony_ci "NTB Device Information:\n"); 2788c2ecf20Sopenharmony_ci 2798c2ecf20Sopenharmony_ci off += scnprintf(buf + off, buf_size - off, 2808c2ecf20Sopenharmony_ci "Connection Topology -\t%s\n", 2818c2ecf20Sopenharmony_ci ntb_topo_string(ndev->ntb.topo)); 2828c2ecf20Sopenharmony_ci 2838c2ecf20Sopenharmony_ci off += scnprintf(buf + off, buf_size - off, 2848c2ecf20Sopenharmony_ci "NTB CTL -\t\t%#06x\n", ndev->ntb_ctl); 2858c2ecf20Sopenharmony_ci off += scnprintf(buf + off, buf_size - off, 2868c2ecf20Sopenharmony_ci "LNK STA -\t\t%#06x\n", ndev->lnk_sta); 2878c2ecf20Sopenharmony_ci 2888c2ecf20Sopenharmony_ci if (!ndev->reg->link_is_up(ndev)) 2898c2ecf20Sopenharmony_ci off += scnprintf(buf + off, buf_size - off, 2908c2ecf20Sopenharmony_ci "Link Status -\t\tDown\n"); 2918c2ecf20Sopenharmony_ci else { 2928c2ecf20Sopenharmony_ci off += scnprintf(buf + off, buf_size - off, 2938c2ecf20Sopenharmony_ci "Link Status -\t\tUp\n"); 2948c2ecf20Sopenharmony_ci off += scnprintf(buf + off, buf_size - off, 2958c2ecf20Sopenharmony_ci "Link Speed -\t\tPCI-E Gen %u\n", 2968c2ecf20Sopenharmony_ci NTB_LNK_STA_SPEED(ndev->lnk_sta)); 2978c2ecf20Sopenharmony_ci off += scnprintf(buf + off, buf_size - off, 2988c2ecf20Sopenharmony_ci "Link Width -\t\tx%u\n", 2998c2ecf20Sopenharmony_ci NTB_LNK_STA_WIDTH(ndev->lnk_sta)); 3008c2ecf20Sopenharmony_ci } 3018c2ecf20Sopenharmony_ci 3028c2ecf20Sopenharmony_ci off += scnprintf(buf + off, buf_size - off, 3038c2ecf20Sopenharmony_ci "Memory Window Count -\t%u\n", ndev->mw_count); 3048c2ecf20Sopenharmony_ci off += scnprintf(buf + off, buf_size - off, 3058c2ecf20Sopenharmony_ci "Scratchpad Count -\t%u\n", ndev->spad_count); 3068c2ecf20Sopenharmony_ci off += scnprintf(buf + off, buf_size - off, 3078c2ecf20Sopenharmony_ci "Doorbell Count -\t%u\n", ndev->db_count); 3088c2ecf20Sopenharmony_ci off += scnprintf(buf + off, buf_size - off, 3098c2ecf20Sopenharmony_ci "Doorbell Vector Count -\t%u\n", ndev->db_vec_count); 3108c2ecf20Sopenharmony_ci off += scnprintf(buf + off, buf_size - off, 3118c2ecf20Sopenharmony_ci "Doorbell Vector Shift -\t%u\n", ndev->db_vec_shift); 3128c2ecf20Sopenharmony_ci 3138c2ecf20Sopenharmony_ci off += scnprintf(buf + off, buf_size - off, 3148c2ecf20Sopenharmony_ci "Doorbell Valid Mask -\t%#llx\n", ndev->db_valid_mask); 3158c2ecf20Sopenharmony_ci off += scnprintf(buf + off, buf_size - off, 3168c2ecf20Sopenharmony_ci "Doorbell Link Mask -\t%#llx\n", ndev->db_link_mask); 3178c2ecf20Sopenharmony_ci off += scnprintf(buf + off, buf_size - off, 3188c2ecf20Sopenharmony_ci "Doorbell Mask Cached -\t%#llx\n", ndev->db_mask); 3198c2ecf20Sopenharmony_ci 3208c2ecf20Sopenharmony_ci u.v64 = ndev_db_read(ndev, mmio + ndev->self_reg->db_mask); 3218c2ecf20Sopenharmony_ci off += scnprintf(buf + off, buf_size - off, 3228c2ecf20Sopenharmony_ci "Doorbell Mask -\t\t%#llx\n", u.v64); 3238c2ecf20Sopenharmony_ci 3248c2ecf20Sopenharmony_ci u.v64 = ndev_db_read(ndev, mmio + ndev->self_reg->db_bell); 3258c2ecf20Sopenharmony_ci off += scnprintf(buf + off, buf_size - off, 3268c2ecf20Sopenharmony_ci "Doorbell Bell -\t\t%#llx\n", u.v64); 3278c2ecf20Sopenharmony_ci 3288c2ecf20Sopenharmony_ci off += scnprintf(buf + off, buf_size - off, 3298c2ecf20Sopenharmony_ci "\nNTB Incoming XLAT:\n"); 3308c2ecf20Sopenharmony_ci 3318c2ecf20Sopenharmony_ci u.v64 = ioread64(mmio + GEN3_IMBAR1XBASE_OFFSET); 3328c2ecf20Sopenharmony_ci off += scnprintf(buf + off, buf_size - off, 3338c2ecf20Sopenharmony_ci "IMBAR1XBASE -\t\t%#018llx\n", u.v64); 3348c2ecf20Sopenharmony_ci 3358c2ecf20Sopenharmony_ci u.v64 = ioread64(mmio + GEN3_IMBAR2XBASE_OFFSET); 3368c2ecf20Sopenharmony_ci off += scnprintf(buf + off, buf_size - off, 3378c2ecf20Sopenharmony_ci "IMBAR2XBASE -\t\t%#018llx\n", u.v64); 3388c2ecf20Sopenharmony_ci 3398c2ecf20Sopenharmony_ci u.v64 = ioread64(mmio + GEN3_IMBAR1XLMT_OFFSET); 3408c2ecf20Sopenharmony_ci off += scnprintf(buf + off, buf_size - off, 3418c2ecf20Sopenharmony_ci "IMBAR1XLMT -\t\t\t%#018llx\n", u.v64); 3428c2ecf20Sopenharmony_ci 3438c2ecf20Sopenharmony_ci u.v64 = ioread64(mmio + GEN3_IMBAR2XLMT_OFFSET); 3448c2ecf20Sopenharmony_ci off += scnprintf(buf + off, buf_size - off, 3458c2ecf20Sopenharmony_ci "IMBAR2XLMT -\t\t\t%#018llx\n", u.v64); 3468c2ecf20Sopenharmony_ci 3478c2ecf20Sopenharmony_ci if (ntb_topo_is_b2b(ndev->ntb.topo)) { 3488c2ecf20Sopenharmony_ci off += scnprintf(buf + off, buf_size - off, 3498c2ecf20Sopenharmony_ci "\nNTB Outgoing B2B XLAT:\n"); 3508c2ecf20Sopenharmony_ci 3518c2ecf20Sopenharmony_ci u.v64 = ioread64(mmio + GEN3_EMBAR1XBASE_OFFSET); 3528c2ecf20Sopenharmony_ci off += scnprintf(buf + off, buf_size - off, 3538c2ecf20Sopenharmony_ci "EMBAR1XBASE -\t\t%#018llx\n", u.v64); 3548c2ecf20Sopenharmony_ci 3558c2ecf20Sopenharmony_ci u.v64 = ioread64(mmio + GEN3_EMBAR2XBASE_OFFSET); 3568c2ecf20Sopenharmony_ci off += scnprintf(buf + off, buf_size - off, 3578c2ecf20Sopenharmony_ci "EMBAR2XBASE -\t\t%#018llx\n", u.v64); 3588c2ecf20Sopenharmony_ci 3598c2ecf20Sopenharmony_ci u.v64 = ioread64(mmio + GEN3_EMBAR1XLMT_OFFSET); 3608c2ecf20Sopenharmony_ci off += scnprintf(buf + off, buf_size - off, 3618c2ecf20Sopenharmony_ci "EMBAR1XLMT -\t\t%#018llx\n", u.v64); 3628c2ecf20Sopenharmony_ci 3638c2ecf20Sopenharmony_ci u.v64 = ioread64(mmio + GEN3_EMBAR2XLMT_OFFSET); 3648c2ecf20Sopenharmony_ci off += scnprintf(buf + off, buf_size - off, 3658c2ecf20Sopenharmony_ci "EMBAR2XLMT -\t\t%#018llx\n", u.v64); 3668c2ecf20Sopenharmony_ci 3678c2ecf20Sopenharmony_ci off += scnprintf(buf + off, buf_size - off, 3688c2ecf20Sopenharmony_ci "\nNTB Secondary BAR:\n"); 3698c2ecf20Sopenharmony_ci 3708c2ecf20Sopenharmony_ci u.v64 = ioread64(mmio + GEN3_EMBAR0_OFFSET); 3718c2ecf20Sopenharmony_ci off += scnprintf(buf + off, buf_size - off, 3728c2ecf20Sopenharmony_ci "EMBAR0 -\t\t%#018llx\n", u.v64); 3738c2ecf20Sopenharmony_ci 3748c2ecf20Sopenharmony_ci u.v64 = ioread64(mmio + GEN3_EMBAR1_OFFSET); 3758c2ecf20Sopenharmony_ci off += scnprintf(buf + off, buf_size - off, 3768c2ecf20Sopenharmony_ci "EMBAR1 -\t\t%#018llx\n", u.v64); 3778c2ecf20Sopenharmony_ci 3788c2ecf20Sopenharmony_ci u.v64 = ioread64(mmio + GEN3_EMBAR2_OFFSET); 3798c2ecf20Sopenharmony_ci off += scnprintf(buf + off, buf_size - off, 3808c2ecf20Sopenharmony_ci "EMBAR2 -\t\t%#018llx\n", u.v64); 3818c2ecf20Sopenharmony_ci } 3828c2ecf20Sopenharmony_ci 3838c2ecf20Sopenharmony_ci off += scnprintf(buf + off, buf_size - off, 3848c2ecf20Sopenharmony_ci "\nNTB Statistics:\n"); 3858c2ecf20Sopenharmony_ci 3868c2ecf20Sopenharmony_ci u.v16 = ioread16(mmio + GEN3_USMEMMISS_OFFSET); 3878c2ecf20Sopenharmony_ci off += scnprintf(buf + off, buf_size - off, 3888c2ecf20Sopenharmony_ci "Upstream Memory Miss -\t%u\n", u.v16); 3898c2ecf20Sopenharmony_ci 3908c2ecf20Sopenharmony_ci off += scnprintf(buf + off, buf_size - off, 3918c2ecf20Sopenharmony_ci "\nNTB Hardware Errors:\n"); 3928c2ecf20Sopenharmony_ci 3938c2ecf20Sopenharmony_ci if (!pci_read_config_word(ndev->ntb.pdev, 3948c2ecf20Sopenharmony_ci GEN3_DEVSTS_OFFSET, &u.v16)) 3958c2ecf20Sopenharmony_ci off += scnprintf(buf + off, buf_size - off, 3968c2ecf20Sopenharmony_ci "DEVSTS -\t\t%#06x\n", u.v16); 3978c2ecf20Sopenharmony_ci 3988c2ecf20Sopenharmony_ci if (!pci_read_config_word(ndev->ntb.pdev, 3998c2ecf20Sopenharmony_ci GEN3_LINK_STATUS_OFFSET, &u.v16)) 4008c2ecf20Sopenharmony_ci off += scnprintf(buf + off, buf_size - off, 4018c2ecf20Sopenharmony_ci "LNKSTS -\t\t%#06x\n", u.v16); 4028c2ecf20Sopenharmony_ci 4038c2ecf20Sopenharmony_ci if (!pci_read_config_dword(ndev->ntb.pdev, 4048c2ecf20Sopenharmony_ci GEN3_UNCERRSTS_OFFSET, &u.v32)) 4058c2ecf20Sopenharmony_ci off += scnprintf(buf + off, buf_size - off, 4068c2ecf20Sopenharmony_ci "UNCERRSTS -\t\t%#06x\n", u.v32); 4078c2ecf20Sopenharmony_ci 4088c2ecf20Sopenharmony_ci if (!pci_read_config_dword(ndev->ntb.pdev, 4098c2ecf20Sopenharmony_ci GEN3_CORERRSTS_OFFSET, &u.v32)) 4108c2ecf20Sopenharmony_ci off += scnprintf(buf + off, buf_size - off, 4118c2ecf20Sopenharmony_ci "CORERRSTS -\t\t%#06x\n", u.v32); 4128c2ecf20Sopenharmony_ci 4138c2ecf20Sopenharmony_ci ret = simple_read_from_buffer(ubuf, count, offp, buf, off); 4148c2ecf20Sopenharmony_ci kfree(buf); 4158c2ecf20Sopenharmony_ci return ret; 4168c2ecf20Sopenharmony_ci} 4178c2ecf20Sopenharmony_ci 4188c2ecf20Sopenharmony_ciint intel_ntb3_link_enable(struct ntb_dev *ntb, enum ntb_speed max_speed, 4198c2ecf20Sopenharmony_ci enum ntb_width max_width) 4208c2ecf20Sopenharmony_ci{ 4218c2ecf20Sopenharmony_ci struct intel_ntb_dev *ndev; 4228c2ecf20Sopenharmony_ci u32 ntb_ctl; 4238c2ecf20Sopenharmony_ci 4248c2ecf20Sopenharmony_ci ndev = container_of(ntb, struct intel_ntb_dev, ntb); 4258c2ecf20Sopenharmony_ci 4268c2ecf20Sopenharmony_ci dev_dbg(&ntb->pdev->dev, 4278c2ecf20Sopenharmony_ci "Enabling link with max_speed %d max_width %d\n", 4288c2ecf20Sopenharmony_ci max_speed, max_width); 4298c2ecf20Sopenharmony_ci 4308c2ecf20Sopenharmony_ci if (max_speed != NTB_SPEED_AUTO) 4318c2ecf20Sopenharmony_ci dev_dbg(&ntb->pdev->dev, "ignoring max_speed %d\n", max_speed); 4328c2ecf20Sopenharmony_ci if (max_width != NTB_WIDTH_AUTO) 4338c2ecf20Sopenharmony_ci dev_dbg(&ntb->pdev->dev, "ignoring max_width %d\n", max_width); 4348c2ecf20Sopenharmony_ci 4358c2ecf20Sopenharmony_ci ntb_ctl = ioread32(ndev->self_mmio + ndev->reg->ntb_ctl); 4368c2ecf20Sopenharmony_ci ntb_ctl &= ~(NTB_CTL_DISABLE | NTB_CTL_CFG_LOCK); 4378c2ecf20Sopenharmony_ci ntb_ctl |= NTB_CTL_P2S_BAR2_SNOOP | NTB_CTL_S2P_BAR2_SNOOP; 4388c2ecf20Sopenharmony_ci ntb_ctl |= NTB_CTL_P2S_BAR4_SNOOP | NTB_CTL_S2P_BAR4_SNOOP; 4398c2ecf20Sopenharmony_ci iowrite32(ntb_ctl, ndev->self_mmio + ndev->reg->ntb_ctl); 4408c2ecf20Sopenharmony_ci 4418c2ecf20Sopenharmony_ci return 0; 4428c2ecf20Sopenharmony_ci} 4438c2ecf20Sopenharmony_cistatic int intel_ntb3_mw_set_trans(struct ntb_dev *ntb, int pidx, int idx, 4448c2ecf20Sopenharmony_ci dma_addr_t addr, resource_size_t size) 4458c2ecf20Sopenharmony_ci{ 4468c2ecf20Sopenharmony_ci struct intel_ntb_dev *ndev = ntb_ndev(ntb); 4478c2ecf20Sopenharmony_ci unsigned long xlat_reg, limit_reg; 4488c2ecf20Sopenharmony_ci resource_size_t bar_size, mw_size; 4498c2ecf20Sopenharmony_ci void __iomem *mmio; 4508c2ecf20Sopenharmony_ci u64 base, limit, reg_val; 4518c2ecf20Sopenharmony_ci int bar; 4528c2ecf20Sopenharmony_ci 4538c2ecf20Sopenharmony_ci if (pidx != NTB_DEF_PEER_IDX) 4548c2ecf20Sopenharmony_ci return -EINVAL; 4558c2ecf20Sopenharmony_ci 4568c2ecf20Sopenharmony_ci if (idx >= ndev->b2b_idx && !ndev->b2b_off) 4578c2ecf20Sopenharmony_ci idx += 1; 4588c2ecf20Sopenharmony_ci 4598c2ecf20Sopenharmony_ci bar = ndev_mw_to_bar(ndev, idx); 4608c2ecf20Sopenharmony_ci if (bar < 0) 4618c2ecf20Sopenharmony_ci return bar; 4628c2ecf20Sopenharmony_ci 4638c2ecf20Sopenharmony_ci bar_size = pci_resource_len(ndev->ntb.pdev, bar); 4648c2ecf20Sopenharmony_ci 4658c2ecf20Sopenharmony_ci if (idx == ndev->b2b_idx) 4668c2ecf20Sopenharmony_ci mw_size = bar_size - ndev->b2b_off; 4678c2ecf20Sopenharmony_ci else 4688c2ecf20Sopenharmony_ci mw_size = bar_size; 4698c2ecf20Sopenharmony_ci 4708c2ecf20Sopenharmony_ci /* hardware requires that addr is aligned to bar size */ 4718c2ecf20Sopenharmony_ci if (addr & (bar_size - 1)) 4728c2ecf20Sopenharmony_ci return -EINVAL; 4738c2ecf20Sopenharmony_ci 4748c2ecf20Sopenharmony_ci /* make sure the range fits in the usable mw size */ 4758c2ecf20Sopenharmony_ci if (size > mw_size) 4768c2ecf20Sopenharmony_ci return -EINVAL; 4778c2ecf20Sopenharmony_ci 4788c2ecf20Sopenharmony_ci mmio = ndev->self_mmio; 4798c2ecf20Sopenharmony_ci xlat_reg = ndev->xlat_reg->bar2_xlat + (idx * 0x10); 4808c2ecf20Sopenharmony_ci limit_reg = ndev->xlat_reg->bar2_limit + (idx * 0x10); 4818c2ecf20Sopenharmony_ci base = pci_resource_start(ndev->ntb.pdev, bar); 4828c2ecf20Sopenharmony_ci 4838c2ecf20Sopenharmony_ci /* Set the limit if supported, if size is not mw_size */ 4848c2ecf20Sopenharmony_ci if (limit_reg && size != mw_size) 4858c2ecf20Sopenharmony_ci limit = base + size; 4868c2ecf20Sopenharmony_ci else 4878c2ecf20Sopenharmony_ci limit = base + mw_size; 4888c2ecf20Sopenharmony_ci 4898c2ecf20Sopenharmony_ci /* set and verify setting the translation address */ 4908c2ecf20Sopenharmony_ci iowrite64(addr, mmio + xlat_reg); 4918c2ecf20Sopenharmony_ci reg_val = ioread64(mmio + xlat_reg); 4928c2ecf20Sopenharmony_ci if (reg_val != addr) { 4938c2ecf20Sopenharmony_ci iowrite64(0, mmio + xlat_reg); 4948c2ecf20Sopenharmony_ci return -EIO; 4958c2ecf20Sopenharmony_ci } 4968c2ecf20Sopenharmony_ci 4978c2ecf20Sopenharmony_ci dev_dbg(&ntb->pdev->dev, "BAR %d IMBARXBASE: %#Lx\n", bar, reg_val); 4988c2ecf20Sopenharmony_ci 4998c2ecf20Sopenharmony_ci /* set and verify setting the limit */ 5008c2ecf20Sopenharmony_ci iowrite64(limit, mmio + limit_reg); 5018c2ecf20Sopenharmony_ci reg_val = ioread64(mmio + limit_reg); 5028c2ecf20Sopenharmony_ci if (reg_val != limit) { 5038c2ecf20Sopenharmony_ci iowrite64(base, mmio + limit_reg); 5048c2ecf20Sopenharmony_ci iowrite64(0, mmio + xlat_reg); 5058c2ecf20Sopenharmony_ci return -EIO; 5068c2ecf20Sopenharmony_ci } 5078c2ecf20Sopenharmony_ci 5088c2ecf20Sopenharmony_ci dev_dbg(&ntb->pdev->dev, "BAR %d IMBARXLMT: %#Lx\n", bar, reg_val); 5098c2ecf20Sopenharmony_ci 5108c2ecf20Sopenharmony_ci /* setup the EP */ 5118c2ecf20Sopenharmony_ci limit_reg = ndev->xlat_reg->bar2_limit + (idx * 0x10) + 0x4000; 5128c2ecf20Sopenharmony_ci base = ioread64(mmio + GEN3_EMBAR1_OFFSET + (8 * idx)); 5138c2ecf20Sopenharmony_ci base &= ~0xf; 5148c2ecf20Sopenharmony_ci 5158c2ecf20Sopenharmony_ci if (limit_reg && size != mw_size) 5168c2ecf20Sopenharmony_ci limit = base + size; 5178c2ecf20Sopenharmony_ci else 5188c2ecf20Sopenharmony_ci limit = base + mw_size; 5198c2ecf20Sopenharmony_ci 5208c2ecf20Sopenharmony_ci /* set and verify setting the limit */ 5218c2ecf20Sopenharmony_ci iowrite64(limit, mmio + limit_reg); 5228c2ecf20Sopenharmony_ci reg_val = ioread64(mmio + limit_reg); 5238c2ecf20Sopenharmony_ci if (reg_val != limit) { 5248c2ecf20Sopenharmony_ci iowrite64(base, mmio + limit_reg); 5258c2ecf20Sopenharmony_ci iowrite64(0, mmio + xlat_reg); 5268c2ecf20Sopenharmony_ci return -EIO; 5278c2ecf20Sopenharmony_ci } 5288c2ecf20Sopenharmony_ci 5298c2ecf20Sopenharmony_ci dev_dbg(&ntb->pdev->dev, "BAR %d EMBARXLMT: %#Lx\n", bar, reg_val); 5308c2ecf20Sopenharmony_ci 5318c2ecf20Sopenharmony_ci return 0; 5328c2ecf20Sopenharmony_ci} 5338c2ecf20Sopenharmony_ci 5348c2ecf20Sopenharmony_ciint intel_ntb3_peer_db_addr(struct ntb_dev *ntb, phys_addr_t *db_addr, 5358c2ecf20Sopenharmony_ci resource_size_t *db_size, 5368c2ecf20Sopenharmony_ci u64 *db_data, int db_bit) 5378c2ecf20Sopenharmony_ci{ 5388c2ecf20Sopenharmony_ci phys_addr_t db_addr_base; 5398c2ecf20Sopenharmony_ci struct intel_ntb_dev *ndev = ntb_ndev(ntb); 5408c2ecf20Sopenharmony_ci 5418c2ecf20Sopenharmony_ci if (unlikely(db_bit >= BITS_PER_LONG_LONG)) 5428c2ecf20Sopenharmony_ci return -EINVAL; 5438c2ecf20Sopenharmony_ci 5448c2ecf20Sopenharmony_ci if (unlikely(BIT_ULL(db_bit) & ~ntb_ndev(ntb)->db_valid_mask)) 5458c2ecf20Sopenharmony_ci return -EINVAL; 5468c2ecf20Sopenharmony_ci 5478c2ecf20Sopenharmony_ci ndev_db_addr(ndev, &db_addr_base, db_size, ndev->peer_addr, 5488c2ecf20Sopenharmony_ci ndev->peer_reg->db_bell); 5498c2ecf20Sopenharmony_ci 5508c2ecf20Sopenharmony_ci if (db_addr) { 5518c2ecf20Sopenharmony_ci *db_addr = db_addr_base + (db_bit * 4); 5528c2ecf20Sopenharmony_ci dev_dbg(&ndev->ntb.pdev->dev, "Peer db addr %llx db bit %d\n", 5538c2ecf20Sopenharmony_ci *db_addr, db_bit); 5548c2ecf20Sopenharmony_ci } 5558c2ecf20Sopenharmony_ci 5568c2ecf20Sopenharmony_ci if (db_data) { 5578c2ecf20Sopenharmony_ci *db_data = 1; 5588c2ecf20Sopenharmony_ci dev_dbg(&ndev->ntb.pdev->dev, "Peer db data %llx db bit %d\n", 5598c2ecf20Sopenharmony_ci *db_data, db_bit); 5608c2ecf20Sopenharmony_ci } 5618c2ecf20Sopenharmony_ci 5628c2ecf20Sopenharmony_ci return 0; 5638c2ecf20Sopenharmony_ci} 5648c2ecf20Sopenharmony_ci 5658c2ecf20Sopenharmony_ciint intel_ntb3_peer_db_set(struct ntb_dev *ntb, u64 db_bits) 5668c2ecf20Sopenharmony_ci{ 5678c2ecf20Sopenharmony_ci struct intel_ntb_dev *ndev = ntb_ndev(ntb); 5688c2ecf20Sopenharmony_ci int bit; 5698c2ecf20Sopenharmony_ci 5708c2ecf20Sopenharmony_ci if (db_bits & ~ndev->db_valid_mask) 5718c2ecf20Sopenharmony_ci return -EINVAL; 5728c2ecf20Sopenharmony_ci 5738c2ecf20Sopenharmony_ci while (db_bits) { 5748c2ecf20Sopenharmony_ci bit = __ffs(db_bits); 5758c2ecf20Sopenharmony_ci iowrite32(1, ndev->peer_mmio + 5768c2ecf20Sopenharmony_ci ndev->peer_reg->db_bell + (bit * 4)); 5778c2ecf20Sopenharmony_ci db_bits &= db_bits - 1; 5788c2ecf20Sopenharmony_ci } 5798c2ecf20Sopenharmony_ci 5808c2ecf20Sopenharmony_ci return 0; 5818c2ecf20Sopenharmony_ci} 5828c2ecf20Sopenharmony_ci 5838c2ecf20Sopenharmony_ciu64 intel_ntb3_db_read(struct ntb_dev *ntb) 5848c2ecf20Sopenharmony_ci{ 5858c2ecf20Sopenharmony_ci struct intel_ntb_dev *ndev = ntb_ndev(ntb); 5868c2ecf20Sopenharmony_ci 5878c2ecf20Sopenharmony_ci return ndev_db_read(ndev, 5888c2ecf20Sopenharmony_ci ndev->self_mmio + 5898c2ecf20Sopenharmony_ci ndev->self_reg->db_clear); 5908c2ecf20Sopenharmony_ci} 5918c2ecf20Sopenharmony_ci 5928c2ecf20Sopenharmony_ciint intel_ntb3_db_clear(struct ntb_dev *ntb, u64 db_bits) 5938c2ecf20Sopenharmony_ci{ 5948c2ecf20Sopenharmony_ci struct intel_ntb_dev *ndev = ntb_ndev(ntb); 5958c2ecf20Sopenharmony_ci 5968c2ecf20Sopenharmony_ci return ndev_db_write(ndev, db_bits, 5978c2ecf20Sopenharmony_ci ndev->self_mmio + 5988c2ecf20Sopenharmony_ci ndev->self_reg->db_clear); 5998c2ecf20Sopenharmony_ci} 6008c2ecf20Sopenharmony_ci 6018c2ecf20Sopenharmony_ciconst struct ntb_dev_ops intel_ntb3_ops = { 6028c2ecf20Sopenharmony_ci .mw_count = intel_ntb_mw_count, 6038c2ecf20Sopenharmony_ci .mw_get_align = intel_ntb_mw_get_align, 6048c2ecf20Sopenharmony_ci .mw_set_trans = intel_ntb3_mw_set_trans, 6058c2ecf20Sopenharmony_ci .peer_mw_count = intel_ntb_peer_mw_count, 6068c2ecf20Sopenharmony_ci .peer_mw_get_addr = intel_ntb_peer_mw_get_addr, 6078c2ecf20Sopenharmony_ci .link_is_up = intel_ntb_link_is_up, 6088c2ecf20Sopenharmony_ci .link_enable = intel_ntb3_link_enable, 6098c2ecf20Sopenharmony_ci .link_disable = intel_ntb_link_disable, 6108c2ecf20Sopenharmony_ci .db_valid_mask = intel_ntb_db_valid_mask, 6118c2ecf20Sopenharmony_ci .db_vector_count = intel_ntb_db_vector_count, 6128c2ecf20Sopenharmony_ci .db_vector_mask = intel_ntb_db_vector_mask, 6138c2ecf20Sopenharmony_ci .db_read = intel_ntb3_db_read, 6148c2ecf20Sopenharmony_ci .db_clear = intel_ntb3_db_clear, 6158c2ecf20Sopenharmony_ci .db_set_mask = intel_ntb_db_set_mask, 6168c2ecf20Sopenharmony_ci .db_clear_mask = intel_ntb_db_clear_mask, 6178c2ecf20Sopenharmony_ci .peer_db_addr = intel_ntb3_peer_db_addr, 6188c2ecf20Sopenharmony_ci .peer_db_set = intel_ntb3_peer_db_set, 6198c2ecf20Sopenharmony_ci .spad_is_unsafe = intel_ntb_spad_is_unsafe, 6208c2ecf20Sopenharmony_ci .spad_count = intel_ntb_spad_count, 6218c2ecf20Sopenharmony_ci .spad_read = intel_ntb_spad_read, 6228c2ecf20Sopenharmony_ci .spad_write = intel_ntb_spad_write, 6238c2ecf20Sopenharmony_ci .peer_spad_addr = intel_ntb_peer_spad_addr, 6248c2ecf20Sopenharmony_ci .peer_spad_read = intel_ntb_peer_spad_read, 6258c2ecf20Sopenharmony_ci .peer_spad_write = intel_ntb_peer_spad_write, 6268c2ecf20Sopenharmony_ci}; 6278c2ecf20Sopenharmony_ci 628