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) 2012 Intel Corporation. All rights reserved. 88c2ecf20Sopenharmony_ci * Copyright (C) 2015 EMC Corporation. All Rights Reserved. 98c2ecf20Sopenharmony_ci * 108c2ecf20Sopenharmony_ci * This program is free software; you can redistribute it and/or modify 118c2ecf20Sopenharmony_ci * it under the terms of version 2 of the GNU General Public License as 128c2ecf20Sopenharmony_ci * published by the Free Software Foundation. 138c2ecf20Sopenharmony_ci * 148c2ecf20Sopenharmony_ci * BSD LICENSE 158c2ecf20Sopenharmony_ci * 168c2ecf20Sopenharmony_ci * Copyright(c) 2012 Intel Corporation. All rights reserved. 178c2ecf20Sopenharmony_ci * Copyright (C) 2015 EMC Corporation. All Rights Reserved. 188c2ecf20Sopenharmony_ci * 198c2ecf20Sopenharmony_ci * Redistribution and use in source and binary forms, with or without 208c2ecf20Sopenharmony_ci * modification, are permitted provided that the following conditions 218c2ecf20Sopenharmony_ci * are met: 228c2ecf20Sopenharmony_ci * 238c2ecf20Sopenharmony_ci * * Redistributions of source code must retain the above copyright 248c2ecf20Sopenharmony_ci * notice, this list of conditions and the following disclaimer. 258c2ecf20Sopenharmony_ci * * Redistributions in binary form must reproduce the above copy 268c2ecf20Sopenharmony_ci * notice, this list of conditions and the following disclaimer in 278c2ecf20Sopenharmony_ci * the documentation and/or other materials provided with the 288c2ecf20Sopenharmony_ci * distribution. 298c2ecf20Sopenharmony_ci * * Neither the name of Intel Corporation nor the names of its 308c2ecf20Sopenharmony_ci * contributors may be used to endorse or promote products derived 318c2ecf20Sopenharmony_ci * from this software without specific prior written permission. 328c2ecf20Sopenharmony_ci * 338c2ecf20Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 348c2ecf20Sopenharmony_ci * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 358c2ecf20Sopenharmony_ci * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 368c2ecf20Sopenharmony_ci * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 378c2ecf20Sopenharmony_ci * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 388c2ecf20Sopenharmony_ci * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 398c2ecf20Sopenharmony_ci * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 408c2ecf20Sopenharmony_ci * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 418c2ecf20Sopenharmony_ci * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 428c2ecf20Sopenharmony_ci * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 438c2ecf20Sopenharmony_ci * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 448c2ecf20Sopenharmony_ci * 458c2ecf20Sopenharmony_ci * Intel PCIe NTB Linux driver 468c2ecf20Sopenharmony_ci * 478c2ecf20Sopenharmony_ci * Contact Information: 488c2ecf20Sopenharmony_ci * Jon Mason <jon.mason@intel.com> 498c2ecf20Sopenharmony_ci */ 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci#ifndef NTB_HW_INTEL_H 528c2ecf20Sopenharmony_ci#define NTB_HW_INTEL_H 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_ci#include <linux/ntb.h> 558c2ecf20Sopenharmony_ci#include <linux/pci.h> 568c2ecf20Sopenharmony_ci#include <linux/io-64-nonatomic-lo-hi.h> 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci/* PCI device IDs */ 598c2ecf20Sopenharmony_ci#define PCI_DEVICE_ID_INTEL_NTB_B2B_JSF 0x3725 608c2ecf20Sopenharmony_ci#define PCI_DEVICE_ID_INTEL_NTB_PS_JSF 0x3726 618c2ecf20Sopenharmony_ci#define PCI_DEVICE_ID_INTEL_NTB_SS_JSF 0x3727 628c2ecf20Sopenharmony_ci#define PCI_DEVICE_ID_INTEL_NTB_B2B_SNB 0x3C0D 638c2ecf20Sopenharmony_ci#define PCI_DEVICE_ID_INTEL_NTB_PS_SNB 0x3C0E 648c2ecf20Sopenharmony_ci#define PCI_DEVICE_ID_INTEL_NTB_SS_SNB 0x3C0F 658c2ecf20Sopenharmony_ci#define PCI_DEVICE_ID_INTEL_NTB_B2B_IVT 0x0E0D 668c2ecf20Sopenharmony_ci#define PCI_DEVICE_ID_INTEL_NTB_PS_IVT 0x0E0E 678c2ecf20Sopenharmony_ci#define PCI_DEVICE_ID_INTEL_NTB_SS_IVT 0x0E0F 688c2ecf20Sopenharmony_ci#define PCI_DEVICE_ID_INTEL_NTB_B2B_HSX 0x2F0D 698c2ecf20Sopenharmony_ci#define PCI_DEVICE_ID_INTEL_NTB_PS_HSX 0x2F0E 708c2ecf20Sopenharmony_ci#define PCI_DEVICE_ID_INTEL_NTB_SS_HSX 0x2F0F 718c2ecf20Sopenharmony_ci#define PCI_DEVICE_ID_INTEL_NTB_B2B_BDX 0x6F0D 728c2ecf20Sopenharmony_ci#define PCI_DEVICE_ID_INTEL_NTB_PS_BDX 0x6F0E 738c2ecf20Sopenharmony_ci#define PCI_DEVICE_ID_INTEL_NTB_SS_BDX 0x6F0F 748c2ecf20Sopenharmony_ci#define PCI_DEVICE_ID_INTEL_NTB_B2B_SKX 0x201C 758c2ecf20Sopenharmony_ci#define PCI_DEVICE_ID_INTEL_NTB_B2B_ICX 0x347e 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_ci/* Ntb control and link status */ 788c2ecf20Sopenharmony_ci#define NTB_CTL_CFG_LOCK BIT(0) 798c2ecf20Sopenharmony_ci#define NTB_CTL_DISABLE BIT(1) 808c2ecf20Sopenharmony_ci#define NTB_CTL_S2P_BAR2_SNOOP BIT(2) 818c2ecf20Sopenharmony_ci#define NTB_CTL_P2S_BAR2_SNOOP BIT(4) 828c2ecf20Sopenharmony_ci#define NTB_CTL_S2P_BAR4_SNOOP BIT(6) 838c2ecf20Sopenharmony_ci#define NTB_CTL_P2S_BAR4_SNOOP BIT(8) 848c2ecf20Sopenharmony_ci#define NTB_CTL_S2P_BAR5_SNOOP BIT(12) 858c2ecf20Sopenharmony_ci#define NTB_CTL_P2S_BAR5_SNOOP BIT(14) 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_ci#define NTB_LNK_STA_ACTIVE_BIT 0x2000 888c2ecf20Sopenharmony_ci#define NTB_LNK_STA_SPEED_MASK 0x000f 898c2ecf20Sopenharmony_ci#define NTB_LNK_STA_WIDTH_MASK 0x03f0 908c2ecf20Sopenharmony_ci#define NTB_LNK_STA_ACTIVE(x) (!!((x) & NTB_LNK_STA_ACTIVE_BIT)) 918c2ecf20Sopenharmony_ci#define NTB_LNK_STA_SPEED(x) ((x) & NTB_LNK_STA_SPEED_MASK) 928c2ecf20Sopenharmony_ci#define NTB_LNK_STA_WIDTH(x) (((x) & NTB_LNK_STA_WIDTH_MASK) >> 4) 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_ci/* flags to indicate unsafe api */ 958c2ecf20Sopenharmony_ci#define NTB_UNSAFE_DB BIT_ULL(0) 968c2ecf20Sopenharmony_ci#define NTB_UNSAFE_SPAD BIT_ULL(1) 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_ci#define NTB_BAR_MASK_64 ~(0xfull) 998c2ecf20Sopenharmony_ci#define NTB_BAR_MASK_32 ~(0xfu) 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_cistruct intel_ntb_dev; 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_cistruct intel_ntb_reg { 1048c2ecf20Sopenharmony_ci int (*poll_link)(struct intel_ntb_dev *ndev); 1058c2ecf20Sopenharmony_ci int (*link_is_up)(struct intel_ntb_dev *ndev); 1068c2ecf20Sopenharmony_ci u64 (*db_ioread)(const void __iomem *mmio); 1078c2ecf20Sopenharmony_ci void (*db_iowrite)(u64 db_bits, void __iomem *mmio); 1088c2ecf20Sopenharmony_ci unsigned long ntb_ctl; 1098c2ecf20Sopenharmony_ci resource_size_t db_size; 1108c2ecf20Sopenharmony_ci int mw_bar[]; 1118c2ecf20Sopenharmony_ci}; 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_cistruct intel_ntb_alt_reg { 1148c2ecf20Sopenharmony_ci unsigned long db_bell; 1158c2ecf20Sopenharmony_ci unsigned long db_mask; 1168c2ecf20Sopenharmony_ci unsigned long db_clear; 1178c2ecf20Sopenharmony_ci unsigned long spad; 1188c2ecf20Sopenharmony_ci}; 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_cistruct intel_ntb_xlat_reg { 1218c2ecf20Sopenharmony_ci unsigned long bar0_base; 1228c2ecf20Sopenharmony_ci unsigned long bar2_xlat; 1238c2ecf20Sopenharmony_ci unsigned long bar2_limit; 1248c2ecf20Sopenharmony_ci unsigned short bar2_idx; 1258c2ecf20Sopenharmony_ci}; 1268c2ecf20Sopenharmony_ci 1278c2ecf20Sopenharmony_cistruct intel_b2b_addr { 1288c2ecf20Sopenharmony_ci phys_addr_t bar0_addr; 1298c2ecf20Sopenharmony_ci phys_addr_t bar2_addr64; 1308c2ecf20Sopenharmony_ci phys_addr_t bar4_addr64; 1318c2ecf20Sopenharmony_ci phys_addr_t bar4_addr32; 1328c2ecf20Sopenharmony_ci phys_addr_t bar5_addr32; 1338c2ecf20Sopenharmony_ci}; 1348c2ecf20Sopenharmony_ci 1358c2ecf20Sopenharmony_cistruct intel_ntb_vec { 1368c2ecf20Sopenharmony_ci struct intel_ntb_dev *ndev; 1378c2ecf20Sopenharmony_ci int num; 1388c2ecf20Sopenharmony_ci}; 1398c2ecf20Sopenharmony_ci 1408c2ecf20Sopenharmony_cistruct intel_ntb_dev { 1418c2ecf20Sopenharmony_ci struct ntb_dev ntb; 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_ci /* offset of peer bar0 in b2b bar */ 1448c2ecf20Sopenharmony_ci unsigned long b2b_off; 1458c2ecf20Sopenharmony_ci /* mw idx used to access peer bar0 */ 1468c2ecf20Sopenharmony_ci unsigned int b2b_idx; 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci /* BAR45 is split into BAR4 and BAR5 */ 1498c2ecf20Sopenharmony_ci bool bar4_split; 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ci u32 ntb_ctl; 1528c2ecf20Sopenharmony_ci u32 lnk_sta; 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_ci unsigned char mw_count; 1558c2ecf20Sopenharmony_ci unsigned char spad_count; 1568c2ecf20Sopenharmony_ci unsigned char db_count; 1578c2ecf20Sopenharmony_ci unsigned char db_vec_count; 1588c2ecf20Sopenharmony_ci unsigned char db_vec_shift; 1598c2ecf20Sopenharmony_ci 1608c2ecf20Sopenharmony_ci u64 db_valid_mask; 1618c2ecf20Sopenharmony_ci u64 db_link_mask; 1628c2ecf20Sopenharmony_ci u64 db_mask; 1638c2ecf20Sopenharmony_ci 1648c2ecf20Sopenharmony_ci /* synchronize rmw access of db_mask and hw reg */ 1658c2ecf20Sopenharmony_ci spinlock_t db_mask_lock; 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_ci struct msix_entry *msix; 1688c2ecf20Sopenharmony_ci struct intel_ntb_vec *vec; 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_ci const struct intel_ntb_reg *reg; 1718c2ecf20Sopenharmony_ci const struct intel_ntb_alt_reg *self_reg; 1728c2ecf20Sopenharmony_ci const struct intel_ntb_alt_reg *peer_reg; 1738c2ecf20Sopenharmony_ci const struct intel_ntb_xlat_reg *xlat_reg; 1748c2ecf20Sopenharmony_ci void __iomem *self_mmio; 1758c2ecf20Sopenharmony_ci void __iomem *peer_mmio; 1768c2ecf20Sopenharmony_ci phys_addr_t peer_addr; 1778c2ecf20Sopenharmony_ci 1788c2ecf20Sopenharmony_ci unsigned long last_ts; 1798c2ecf20Sopenharmony_ci struct delayed_work hb_timer; 1808c2ecf20Sopenharmony_ci 1818c2ecf20Sopenharmony_ci unsigned long hwerr_flags; 1828c2ecf20Sopenharmony_ci unsigned long unsafe_flags; 1838c2ecf20Sopenharmony_ci unsigned long unsafe_flags_ignore; 1848c2ecf20Sopenharmony_ci 1858c2ecf20Sopenharmony_ci struct dentry *debugfs_dir; 1868c2ecf20Sopenharmony_ci struct dentry *debugfs_info; 1878c2ecf20Sopenharmony_ci 1888c2ecf20Sopenharmony_ci /* gen4 entries */ 1898c2ecf20Sopenharmony_ci int dev_up; 1908c2ecf20Sopenharmony_ci}; 1918c2ecf20Sopenharmony_ci 1928c2ecf20Sopenharmony_ci#define ntb_ndev(__ntb) container_of(__ntb, struct intel_ntb_dev, ntb) 1938c2ecf20Sopenharmony_ci#define hb_ndev(__work) container_of(__work, struct intel_ntb_dev, \ 1948c2ecf20Sopenharmony_ci hb_timer.work) 1958c2ecf20Sopenharmony_ci 1968c2ecf20Sopenharmony_cistatic inline int pdev_is_gen1(struct pci_dev *pdev) 1978c2ecf20Sopenharmony_ci{ 1988c2ecf20Sopenharmony_ci switch (pdev->device) { 1998c2ecf20Sopenharmony_ci case PCI_DEVICE_ID_INTEL_NTB_SS_JSF: 2008c2ecf20Sopenharmony_ci case PCI_DEVICE_ID_INTEL_NTB_SS_SNB: 2018c2ecf20Sopenharmony_ci case PCI_DEVICE_ID_INTEL_NTB_SS_IVT: 2028c2ecf20Sopenharmony_ci case PCI_DEVICE_ID_INTEL_NTB_SS_HSX: 2038c2ecf20Sopenharmony_ci case PCI_DEVICE_ID_INTEL_NTB_SS_BDX: 2048c2ecf20Sopenharmony_ci case PCI_DEVICE_ID_INTEL_NTB_PS_JSF: 2058c2ecf20Sopenharmony_ci case PCI_DEVICE_ID_INTEL_NTB_PS_SNB: 2068c2ecf20Sopenharmony_ci case PCI_DEVICE_ID_INTEL_NTB_PS_IVT: 2078c2ecf20Sopenharmony_ci case PCI_DEVICE_ID_INTEL_NTB_PS_HSX: 2088c2ecf20Sopenharmony_ci case PCI_DEVICE_ID_INTEL_NTB_PS_BDX: 2098c2ecf20Sopenharmony_ci case PCI_DEVICE_ID_INTEL_NTB_B2B_JSF: 2108c2ecf20Sopenharmony_ci case PCI_DEVICE_ID_INTEL_NTB_B2B_SNB: 2118c2ecf20Sopenharmony_ci case PCI_DEVICE_ID_INTEL_NTB_B2B_IVT: 2128c2ecf20Sopenharmony_ci case PCI_DEVICE_ID_INTEL_NTB_B2B_HSX: 2138c2ecf20Sopenharmony_ci case PCI_DEVICE_ID_INTEL_NTB_B2B_BDX: 2148c2ecf20Sopenharmony_ci return 1; 2158c2ecf20Sopenharmony_ci } 2168c2ecf20Sopenharmony_ci return 0; 2178c2ecf20Sopenharmony_ci} 2188c2ecf20Sopenharmony_ci 2198c2ecf20Sopenharmony_cistatic inline int pdev_is_gen3(struct pci_dev *pdev) 2208c2ecf20Sopenharmony_ci{ 2218c2ecf20Sopenharmony_ci if (pdev->device == PCI_DEVICE_ID_INTEL_NTB_B2B_SKX) 2228c2ecf20Sopenharmony_ci return 1; 2238c2ecf20Sopenharmony_ci 2248c2ecf20Sopenharmony_ci return 0; 2258c2ecf20Sopenharmony_ci} 2268c2ecf20Sopenharmony_ci 2278c2ecf20Sopenharmony_cistatic inline int pdev_is_gen4(struct pci_dev *pdev) 2288c2ecf20Sopenharmony_ci{ 2298c2ecf20Sopenharmony_ci if (pdev->device == PCI_DEVICE_ID_INTEL_NTB_B2B_ICX) 2308c2ecf20Sopenharmony_ci return 1; 2318c2ecf20Sopenharmony_ci 2328c2ecf20Sopenharmony_ci return 0; 2338c2ecf20Sopenharmony_ci} 2348c2ecf20Sopenharmony_ci#endif 235