1/* 2 * Intel MIC Platform Software Stack (MPSS) 3 * 4 * Copyright(c) 2014 Intel Corporation. 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License, version 2, as 8 * published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, but 11 * WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * General Public License for more details. 14 * 15 * Intel SCIF driver. 16 * 17 */ 18#ifndef SCIF_MAIN_H 19#define SCIF_MAIN_H 20 21#include <linux/sched/signal.h> 22#include <linux/pci.h> 23#include <linux/miscdevice.h> 24#include <linux/dmaengine.h> 25#include <linux/iova.h> 26#include <linux/anon_inodes.h> 27#include <linux/file.h> 28#include <linux/vmalloc.h> 29#include <linux/scif.h> 30#include "../common/mic_dev.h" 31 32#define SCIF_MGMT_NODE 0 33#define SCIF_DEFAULT_WATCHDOG_TO 30 34#define SCIF_NODE_ACCEPT_TIMEOUT (3 * HZ) 35#define SCIF_NODE_ALIVE_TIMEOUT (SCIF_DEFAULT_WATCHDOG_TO * HZ) 36#define SCIF_RMA_TEMP_CACHE_LIMIT 0x20000 37 38/* 39 * Generic state used for certain node QP message exchanges 40 * like Unregister, Alloc etc. 41 */ 42enum scif_msg_state { 43 OP_IDLE = 1, 44 OP_IN_PROGRESS, 45 OP_COMPLETED, 46 OP_FAILED 47}; 48 49/* 50 * struct scif_info - Global SCIF information 51 * 52 * @nodeid: Node ID this node is to others 53 * @maxid: Max known node ID 54 * @total: Total number of SCIF nodes 55 * @nr_zombies: number of zombie endpoints 56 * @eplock: Lock to synchronize listening, zombie endpoint lists 57 * @connlock: Lock to synchronize connected and disconnected lists 58 * @nb_connect_lock: Synchronize non blocking connect operations 59 * @port_lock: Synchronize access to SCIF ports 60 * @uaccept: List of user acceptreq waiting for acceptreg 61 * @listen: List of listening end points 62 * @zombie: List of zombie end points with pending RMA's 63 * @connected: List of end points in connected state 64 * @disconnected: List of end points in disconnected state 65 * @nb_connect_list: List for non blocking connections 66 * @misc_work: miscellaneous SCIF tasks 67 * @conflock: Lock to synchronize SCIF node configuration changes 68 * @en_msg_log: Enable debug message logging 69 * @p2p_enable: Enable P2P SCIF network 70 * @mdev: The MISC device 71 * @conn_work: Work for workqueue handling all connections 72 * @exitwq: Wait queue for waiting for an EXIT node QP message response 73 * @loopb_dev: Dummy SCIF device used for loopback 74 * @loopb_wq: Workqueue used for handling loopback messages 75 * @loopb_wqname[16]: Name of loopback workqueue 76 * @loopb_work: Used for submitting work to loopb_wq 77 * @loopb_recv_q: List of messages received on the loopb_wq 78 * @card_initiated_exit: set when the card has initiated the exit 79 * @rmalock: Synchronize access to RMA operations 80 * @fencelock: Synchronize access to list of remote fences requested. 81 * @rma: List of temporary registered windows to be destroyed. 82 * @rma_tc: List of temporary registered & cached Windows to be destroyed 83 * @fence: List of remote fence requests 84 * @mmu_notif_work: Work for registration caching MMU notifier workqueue 85 * @mmu_notif_cleanup: List of temporary cached windows for reg cache 86 * @rma_tc_limit: RMA temporary cache limit 87 */ 88struct scif_info { 89 u8 nodeid; 90 u8 maxid; 91 u8 total; 92 u32 nr_zombies; 93 struct mutex eplock; 94 struct mutex connlock; 95 spinlock_t nb_connect_lock; 96 spinlock_t port_lock; 97 struct list_head uaccept; 98 struct list_head listen; 99 struct list_head zombie; 100 struct list_head connected; 101 struct list_head disconnected; 102 struct list_head nb_connect_list; 103 struct work_struct misc_work; 104 struct mutex conflock; 105 u8 en_msg_log; 106 u8 p2p_enable; 107 struct miscdevice mdev; 108 struct work_struct conn_work; 109 wait_queue_head_t exitwq; 110 struct scif_dev *loopb_dev; 111 struct workqueue_struct *loopb_wq; 112 char loopb_wqname[16]; 113 struct work_struct loopb_work; 114 struct list_head loopb_recv_q; 115 bool card_initiated_exit; 116 spinlock_t rmalock; 117 struct mutex fencelock; 118 struct list_head rma; 119 struct list_head rma_tc; 120 struct list_head fence; 121 struct work_struct mmu_notif_work; 122 struct list_head mmu_notif_cleanup; 123 unsigned long rma_tc_limit; 124}; 125 126/* 127 * struct scif_p2p_info - SCIF mapping information used for P2P 128 * 129 * @ppi_peer_id - SCIF peer node id 130 * @ppi_sg - Scatter list for bar information (One for mmio and one for aper) 131 * @sg_nentries - Number of entries in the scatterlist 132 * @ppi_da: DMA address for MMIO and APER bars 133 * @ppi_len: Length of MMIO and APER bars 134 * @ppi_list: Link in list of mapping information 135 */ 136struct scif_p2p_info { 137 u8 ppi_peer_id; 138 struct scatterlist *ppi_sg[2]; 139 u64 sg_nentries[2]; 140 dma_addr_t ppi_da[2]; 141 u64 ppi_len[2]; 142#define SCIF_PPI_MMIO 0 143#define SCIF_PPI_APER 1 144 struct list_head ppi_list; 145}; 146 147/* 148 * struct scif_dev - SCIF remote device specific fields 149 * 150 * @node: Node id 151 * @p2p: List of P2P mapping information 152 * @qpairs: The node queue pair for exchanging control messages 153 * @intr_wq: Workqueue for handling Node QP messages 154 * @intr_wqname: Name of node QP workqueue for handling interrupts 155 * @intr_bh: Used for submitting work to intr_wq 156 * @lock: Lock used for synchronizing access to the scif device 157 * @sdev: SCIF hardware device on the SCIF hardware bus 158 * @db: doorbell the peer will trigger to generate an interrupt on self 159 * @rdb: Doorbell to trigger on the peer to generate an interrupt on the peer 160 * @cookie: Cookie received while registering the interrupt handler 161 * @peer_add_work: Work for handling device_add for peer devices 162 * @p2p_dwork: Delayed work to enable polling for P2P state 163 * @qp_dwork: Delayed work for enabling polling for remote QP information 164 * @p2p_retry: Number of times to retry polling of P2P state 165 * @base_addr: P2P aperture bar base address 166 * @mic_mw mmio: The peer MMIO information used for P2P 167 * @spdev: SCIF peer device on the SCIF peer bus 168 * @node_remove_ack_pending: True if a node_remove_ack is pending 169 * @exit_ack_pending: true if an exit_ack is pending 170 * @disconn_wq: Used while waiting for a node remove response 171 * @disconn_rescnt: Keeps track of number of node remove requests sent 172 * @exit: Status of exit message 173 * @qp_dma_addr: Queue pair DMA address passed to the peer 174 * @dma_ch_idx: Round robin index for DMA channels 175 * @signal_pool: DMA pool used for scheduling scif_fence_signal DMA's 176*/ 177struct scif_dev { 178 u8 node; 179 struct list_head p2p; 180 struct scif_qp *qpairs; 181 struct workqueue_struct *intr_wq; 182 char intr_wqname[16]; 183 struct work_struct intr_bh; 184 struct mutex lock; 185 struct scif_hw_dev *sdev; 186 int db; 187 int rdb; 188 struct mic_irq *cookie; 189 struct work_struct peer_add_work; 190 struct delayed_work p2p_dwork; 191 struct delayed_work qp_dwork; 192 int p2p_retry; 193 dma_addr_t base_addr; 194 struct mic_mw mmio; 195 struct scif_peer_dev __rcu *spdev; 196 bool node_remove_ack_pending; 197 bool exit_ack_pending; 198 wait_queue_head_t disconn_wq; 199 atomic_t disconn_rescnt; 200 enum scif_msg_state exit; 201 dma_addr_t qp_dma_addr; 202 int dma_ch_idx; 203 struct dma_pool *signal_pool; 204}; 205 206extern bool scif_reg_cache_enable; 207extern bool scif_ulimit_check; 208extern struct scif_info scif_info; 209extern struct idr scif_ports; 210extern struct bus_type scif_peer_bus; 211extern struct scif_dev *scif_dev; 212extern const struct file_operations scif_fops; 213extern const struct file_operations scif_anon_fops; 214 215/* Size of the RB for the Node QP */ 216#define SCIF_NODE_QP_SIZE 0x10000 217 218#include "scif_nodeqp.h" 219#include "scif_rma.h" 220#include "scif_rma_list.h" 221 222/* 223 * scifdev_self: 224 * @dev: The remote SCIF Device 225 * 226 * Returns true if the SCIF Device passed is the self aka Loopback SCIF device. 227 */ 228static inline int scifdev_self(struct scif_dev *dev) 229{ 230 return dev->node == scif_info.nodeid; 231} 232 233static inline bool scif_is_mgmt_node(void) 234{ 235 return !scif_info.nodeid; 236} 237 238/* 239 * scifdev_is_p2p: 240 * @dev: The remote SCIF Device 241 * 242 * Returns true if the SCIF Device is a MIC Peer to Peer SCIF device. 243 */ 244static inline bool scifdev_is_p2p(struct scif_dev *dev) 245{ 246 if (scif_is_mgmt_node()) 247 return false; 248 else 249 return dev != &scif_dev[SCIF_MGMT_NODE] && 250 !scifdev_self(dev); 251} 252 253/* 254 * scifdev_alive: 255 * @scifdev: The remote SCIF Device 256 * 257 * Returns true if the remote SCIF Device is running or sleeping for 258 * this endpoint. 259 */ 260static inline int _scifdev_alive(struct scif_dev *scifdev) 261{ 262 struct scif_peer_dev *spdev; 263 264 rcu_read_lock(); 265 spdev = rcu_dereference(scifdev->spdev); 266 rcu_read_unlock(); 267 return !!spdev; 268} 269 270#include "scif_epd.h" 271 272void __init scif_init_debugfs(void); 273void scif_exit_debugfs(void); 274int scif_setup_intr_wq(struct scif_dev *scifdev); 275void scif_destroy_intr_wq(struct scif_dev *scifdev); 276void scif_cleanup_scifdev(struct scif_dev *dev); 277void scif_handle_remove_node(int node); 278void scif_disconnect_node(u32 node_id, bool mgmt_initiated); 279void scif_free_qp(struct scif_dev *dev); 280void scif_misc_handler(struct work_struct *work); 281void scif_stop(struct scif_dev *scifdev); 282irqreturn_t scif_intr_handler(int irq, void *data); 283#endif /* SCIF_MAIN_H */ 284