blob: b0795b05980380655bc93763a701cb994d6498f8 [file] [log] [blame]
Sudeep Duttfb4d0e32015-04-29 05:32:33 -07001/*
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.h>
22#include <linux/pci.h>
23#include <linux/miscdevice.h>
24#include <linux/dmaengine.h>
Ashutosh Dixitb7f94442015-09-29 18:10:44 -070025#include <linux/anon_inodes.h>
Sudeep Duttfb4d0e32015-04-29 05:32:33 -070026#include <linux/file.h>
27#include <linux/scif.h>
28
29#include "../common/mic_dev.h"
30
31#define SCIF_MGMT_NODE 0
32#define SCIF_DEFAULT_WATCHDOG_TO 30
33#define SCIF_NODE_ACCEPT_TIMEOUT (3 * HZ)
34#define SCIF_NODE_ALIVE_TIMEOUT (SCIF_DEFAULT_WATCHDOG_TO * HZ)
35
36/*
37 * Generic state used for certain node QP message exchanges
38 * like Unregister, Alloc etc.
39 */
40enum scif_msg_state {
41 OP_IDLE = 1,
42 OP_IN_PROGRESS,
43 OP_COMPLETED,
44 OP_FAILED
45};
46
47/*
48 * struct scif_info - Global SCIF information
49 *
50 * @nodeid: Node ID this node is to others
51 * @maxid: Max known node ID
52 * @total: Total number of SCIF nodes
53 * @nr_zombies: number of zombie endpoints
54 * @eplock: Lock to synchronize listening, zombie endpoint lists
55 * @connlock: Lock to synchronize connected and disconnected lists
56 * @nb_connect_lock: Synchronize non blocking connect operations
57 * @port_lock: Synchronize access to SCIF ports
58 * @uaccept: List of user acceptreq waiting for acceptreg
59 * @listen: List of listening end points
60 * @zombie: List of zombie end points with pending RMA's
61 * @connected: List of end points in connected state
62 * @disconnected: List of end points in disconnected state
63 * @nb_connect_list: List for non blocking connections
64 * @misc_work: miscellaneous SCIF tasks
65 * @conflock: Lock to synchronize SCIF node configuration changes
66 * @en_msg_log: Enable debug message logging
67 * @p2p_enable: Enable P2P SCIF network
68 * @mdev: The MISC device
69 * @conn_work: Work for workqueue handling all connections
70 * @exitwq: Wait queue for waiting for an EXIT node QP message response
71 * @loopb_dev: Dummy SCIF device used for loopback
72 * @loopb_wq: Workqueue used for handling loopback messages
73 * @loopb_wqname[16]: Name of loopback workqueue
74 * @loopb_work: Used for submitting work to loopb_wq
75 * @loopb_recv_q: List of messages received on the loopb_wq
76 * @card_initiated_exit: set when the card has initiated the exit
77 */
78struct scif_info {
79 u8 nodeid;
80 u8 maxid;
81 u8 total;
82 u32 nr_zombies;
83 spinlock_t eplock;
84 struct mutex connlock;
85 spinlock_t nb_connect_lock;
86 spinlock_t port_lock;
87 struct list_head uaccept;
88 struct list_head listen;
89 struct list_head zombie;
90 struct list_head connected;
91 struct list_head disconnected;
92 struct list_head nb_connect_list;
93 struct work_struct misc_work;
94 struct mutex conflock;
95 u8 en_msg_log;
96 u8 p2p_enable;
97 struct miscdevice mdev;
98 struct work_struct conn_work;
99 wait_queue_head_t exitwq;
100 struct scif_dev *loopb_dev;
101 struct workqueue_struct *loopb_wq;
102 char loopb_wqname[16];
103 struct work_struct loopb_work;
104 struct list_head loopb_recv_q;
105 bool card_initiated_exit;
106};
107
108/*
109 * struct scif_p2p_info - SCIF mapping information used for P2P
110 *
111 * @ppi_peer_id - SCIF peer node id
112 * @ppi_sg - Scatter list for bar information (One for mmio and one for aper)
113 * @sg_nentries - Number of entries in the scatterlist
114 * @ppi_da: DMA address for MMIO and APER bars
115 * @ppi_len: Length of MMIO and APER bars
116 * @ppi_list: Link in list of mapping information
117 */
118struct scif_p2p_info {
119 u8 ppi_peer_id;
120 struct scatterlist *ppi_sg[2];
121 u64 sg_nentries[2];
122 dma_addr_t ppi_da[2];
123 u64 ppi_len[2];
124#define SCIF_PPI_MMIO 0
125#define SCIF_PPI_APER 1
126 struct list_head ppi_list;
127};
128
129/*
130 * struct scif_dev - SCIF remote device specific fields
131 *
132 * @node: Node id
133 * @p2p: List of P2P mapping information
134 * @qpairs: The node queue pair for exchanging control messages
135 * @intr_wq: Workqueue for handling Node QP messages
136 * @intr_wqname: Name of node QP workqueue for handling interrupts
137 * @intr_bh: Used for submitting work to intr_wq
138 * @lock: Lock used for synchronizing access to the scif device
139 * @sdev: SCIF hardware device on the SCIF hardware bus
140 * @db: doorbell the peer will trigger to generate an interrupt on self
141 * @rdb: Doorbell to trigger on the peer to generate an interrupt on the peer
142 * @cookie: Cookie received while registering the interrupt handler
Ashutosh Dixitd3d912e2015-09-29 18:11:15 -0700143 * @peer_add_work: Work for handling device_add for peer devices
Sudeep Duttfb4d0e32015-04-29 05:32:33 -0700144 * @p2p_dwork: Delayed work to enable polling for P2P state
145 * @qp_dwork: Delayed work for enabling polling for remote QP information
146 * @p2p_retry: Number of times to retry polling of P2P state
147 * @base_addr: P2P aperture bar base address
148 * @mic_mw mmio: The peer MMIO information used for P2P
149 * @spdev: SCIF peer device on the SCIF peer bus
150 * @node_remove_ack_pending: True if a node_remove_ack is pending
151 * @exit_ack_pending: true if an exit_ack is pending
152 * @disconn_wq: Used while waiting for a node remove response
153 * @disconn_rescnt: Keeps track of number of node remove requests sent
154 * @exit: Status of exit message
155 * @qp_dma_addr: Queue pair DMA address passed to the peer
156*/
157struct scif_dev {
158 u8 node;
159 struct list_head p2p;
160 struct scif_qp *qpairs;
161 struct workqueue_struct *intr_wq;
162 char intr_wqname[16];
163 struct work_struct intr_bh;
164 struct mutex lock;
165 struct scif_hw_dev *sdev;
166 int db;
167 int rdb;
168 struct mic_irq *cookie;
Ashutosh Dixitd3d912e2015-09-29 18:11:15 -0700169 struct work_struct peer_add_work;
Sudeep Duttfb4d0e32015-04-29 05:32:33 -0700170 struct delayed_work p2p_dwork;
171 struct delayed_work qp_dwork;
172 int p2p_retry;
173 dma_addr_t base_addr;
174 struct mic_mw mmio;
175 struct scif_peer_dev __rcu *spdev;
176 bool node_remove_ack_pending;
177 bool exit_ack_pending;
178 wait_queue_head_t disconn_wq;
179 atomic_t disconn_rescnt;
180 enum scif_msg_state exit;
181 dma_addr_t qp_dma_addr;
182};
183
184extern struct scif_info scif_info;
185extern struct idr scif_ports;
Ashutosh Dixitd3d912e2015-09-29 18:11:15 -0700186extern struct bus_type scif_peer_bus;
Sudeep Duttfb4d0e32015-04-29 05:32:33 -0700187extern struct scif_dev *scif_dev;
188extern const struct file_operations scif_fops;
Ashutosh Dixitb7f94442015-09-29 18:10:44 -0700189extern const struct file_operations scif_anon_fops;
Sudeep Duttfb4d0e32015-04-29 05:32:33 -0700190
191/* Size of the RB for the Node QP */
192#define SCIF_NODE_QP_SIZE 0x10000
193
194#include "scif_nodeqp.h"
195
196/*
197 * scifdev_self:
198 * @dev: The remote SCIF Device
199 *
200 * Returns true if the SCIF Device passed is the self aka Loopback SCIF device.
201 */
202static inline int scifdev_self(struct scif_dev *dev)
203{
204 return dev->node == scif_info.nodeid;
205}
206
207static inline bool scif_is_mgmt_node(void)
208{
209 return !scif_info.nodeid;
210}
211
212/*
213 * scifdev_is_p2p:
214 * @dev: The remote SCIF Device
215 *
216 * Returns true if the SCIF Device is a MIC Peer to Peer SCIF device.
217 */
218static inline bool scifdev_is_p2p(struct scif_dev *dev)
219{
220 if (scif_is_mgmt_node())
221 return false;
222 else
223 return dev != &scif_dev[SCIF_MGMT_NODE] &&
224 !scifdev_self(dev);
225}
226
227/*
228 * scifdev_alive:
229 * @scifdev: The remote SCIF Device
230 *
231 * Returns true if the remote SCIF Device is running or sleeping for
232 * this endpoint.
233 */
234static inline int _scifdev_alive(struct scif_dev *scifdev)
235{
236 struct scif_peer_dev *spdev;
237
238 rcu_read_lock();
239 spdev = rcu_dereference(scifdev->spdev);
240 rcu_read_unlock();
241 return !!spdev;
242}
243
Sudeep Dutte9089f42015-04-29 05:32:35 -0700244#include "scif_epd.h"
245
Sudeep Duttfb4d0e32015-04-29 05:32:33 -0700246void __init scif_init_debugfs(void);
247void scif_exit_debugfs(void);
248int scif_setup_intr_wq(struct scif_dev *scifdev);
249void scif_destroy_intr_wq(struct scif_dev *scifdev);
250void scif_cleanup_scifdev(struct scif_dev *dev);
251void scif_handle_remove_node(int node);
252void scif_disconnect_node(u32 node_id, bool mgmt_initiated);
253void scif_free_qp(struct scif_dev *dev);
254void scif_misc_handler(struct work_struct *work);
255void scif_stop(struct scif_dev *scifdev);
256irqreturn_t scif_intr_handler(int irq, void *data);
257#endif /* SCIF_MAIN_H */