Linux-libre 5.3.12-gnu
[librecmc/linux-libre.git] / drivers / misc / mic / scif / scif_epd.h
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Intel MIC Platform Software Stack (MPSS)
4  *
5  * Copyright(c) 2014 Intel Corporation.
6  *
7  * Intel SCIF driver.
8  */
9 #ifndef SCIF_EPD_H
10 #define SCIF_EPD_H
11
12 #include <linux/delay.h>
13 #include <linux/scif.h>
14 #include <linux/scif_ioctl.h>
15
16 #define SCIF_EPLOCK_HELD true
17
18 enum scif_epd_state {
19         SCIFEP_UNBOUND,
20         SCIFEP_BOUND,
21         SCIFEP_LISTENING,
22         SCIFEP_CONNECTED,
23         SCIFEP_CONNECTING,
24         SCIFEP_MAPPING,
25         SCIFEP_CLOSING,
26         SCIFEP_CLLISTEN,
27         SCIFEP_DISCONNECTED,
28         SCIFEP_ZOMBIE
29 };
30
31 /*
32  * struct scif_conreq - Data structure added to the connection list.
33  *
34  * @msg: connection request message received
35  * @list: link to list of connection requests
36  */
37 struct scif_conreq {
38         struct scifmsg msg;
39         struct list_head list;
40 };
41
42 /* Size of the RB for the Endpoint QP */
43 #define SCIF_ENDPT_QP_SIZE 0x1000
44
45 /*
46  * scif_endpt_qp_info - SCIF endpoint queue pair
47  *
48  * @qp - Qpair for this endpoint
49  * @qp_offset - DMA address of the QP
50  * @gnt_pld - Payload in a SCIF_CNCT_GNT message containing the
51  * physical address of the remote_qp.
52  */
53 struct scif_endpt_qp_info {
54         struct scif_qp *qp;
55         dma_addr_t qp_offset;
56         dma_addr_t gnt_pld;
57 };
58
59 /*
60  * struct scif_endpt - The SCIF endpoint data structure
61  *
62  * @state: end point state
63  * @lock: lock synchronizing access to endpoint fields like state etc
64  * @port: self port information
65  * @peer: peer port information
66  * @backlog: maximum pending connection requests
67  * @qp_info: Endpoint QP information for SCIF messaging
68  * @remote_dev: scifdev used by this endpt to communicate with remote node.
69  * @remote_ep: remote endpoint
70  * @conreqcnt: Keep track of number of connection requests.
71  * @files: Open file information used to match the id passed in with
72  *         the flush routine.
73  * @conlist: list of connection requests
74  * @conwq: waitqueue for connection processing
75  * @discon: completion used during disconnection
76  * @sendwq: waitqueue used during sending messages
77  * @recvwq: waitqueue used during message receipt
78  * @sendlock: Synchronize ordering of messages sent
79  * @recvlock: Synchronize ordering of messages received
80  * @list: link to list of various endpoints like connected, listening etc
81  * @li_accept: pending ACCEPTREG
82  * @acceptcnt: pending ACCEPTREG cnt
83  * @liacceptlist: link to listen accept
84  * @miacceptlist: link to uaccept
85  * @listenep: associated listen ep
86  * @conn_work: Non blocking connect work
87  * @conn_port: Connection port
88  * @conn_err: Errors during connection
89  * @conn_async_state: Async connection
90  * @conn_pend_wq: Used by poll while waiting for incoming connections
91  * @conn_list: List of async connection requests
92  * @rma_info: Information for triggering SCIF RMA and DMA operations
93  * @mmu_list: link to list of MMU notifier cleanup work
94  * @anon: anonymous file for use in kernel mode scif poll
95  */
96 struct scif_endpt {
97         enum scif_epd_state state;
98         spinlock_t lock;
99         struct scif_port_id port;
100         struct scif_port_id peer;
101         int backlog;
102         struct scif_endpt_qp_info qp_info;
103         struct scif_dev *remote_dev;
104         u64 remote_ep;
105         int conreqcnt;
106         struct files_struct *files;
107         struct list_head conlist;
108         wait_queue_head_t conwq;
109         struct completion discon;
110         wait_queue_head_t sendwq;
111         wait_queue_head_t recvwq;
112         struct mutex sendlock;
113         struct mutex recvlock;
114         struct list_head list;
115         struct list_head li_accept;
116         int acceptcnt;
117         struct list_head liacceptlist;
118         struct list_head miacceptlist;
119         struct scif_endpt *listenep;
120         struct scif_port_id conn_port;
121         int conn_err;
122         int conn_async_state;
123         wait_queue_head_t conn_pend_wq;
124         struct list_head conn_list;
125         struct scif_endpt_rma_info rma_info;
126         struct list_head mmu_list;
127         struct file *anon;
128 };
129
130 static inline int scifdev_alive(struct scif_endpt *ep)
131 {
132         return _scifdev_alive(ep->remote_dev);
133 }
134
135 /*
136  * scif_verify_epd:
137  * ep: SCIF endpoint
138  *
139  * Checks several generic error conditions and returns the
140  * appropriate error.
141  */
142 static inline int scif_verify_epd(struct scif_endpt *ep)
143 {
144         if (ep->state == SCIFEP_DISCONNECTED)
145                 return -ECONNRESET;
146
147         if (ep->state != SCIFEP_CONNECTED)
148                 return -ENOTCONN;
149
150         if (!scifdev_alive(ep))
151                 return -ENODEV;
152
153         return 0;
154 }
155
156 static inline int scif_anon_inode_getfile(scif_epd_t epd)
157 {
158         epd->anon = anon_inode_getfile("scif", &scif_anon_fops, NULL, 0);
159         if (IS_ERR(epd->anon))
160                 return PTR_ERR(epd->anon);
161         return 0;
162 }
163
164 static inline void scif_anon_inode_fput(scif_epd_t epd)
165 {
166         if (epd->anon) {
167                 fput(epd->anon);
168                 epd->anon = NULL;
169         }
170 }
171
172 void scif_cleanup_zombie_epd(void);
173 void scif_teardown_ep(void *endpt);
174 void scif_cleanup_ep_qp(struct scif_endpt *ep);
175 void scif_add_epd_to_zombie_list(struct scif_endpt *ep, bool eplock_held);
176 void scif_get_node_info(void);
177 void scif_send_acks(struct scif_dev *dev);
178 void scif_conn_handler(struct work_struct *work);
179 int scif_rsrv_port(u16 port);
180 void scif_get_port(u16 port);
181 int scif_get_new_port(void);
182 void scif_put_port(u16 port);
183 int scif_user_send(scif_epd_t epd, void __user *msg, int len, int flags);
184 int scif_user_recv(scif_epd_t epd, void __user *msg, int len, int flags);
185 void scif_cnctreq(struct scif_dev *scifdev, struct scifmsg *msg);
186 void scif_cnctgnt(struct scif_dev *scifdev, struct scifmsg *msg);
187 void scif_cnctgnt_ack(struct scif_dev *scifdev, struct scifmsg *msg);
188 void scif_cnctgnt_nack(struct scif_dev *scifdev, struct scifmsg *msg);
189 void scif_cnctrej(struct scif_dev *scifdev, struct scifmsg *msg);
190 void scif_discnct(struct scif_dev *scifdev, struct scifmsg *msg);
191 void scif_discnt_ack(struct scif_dev *scifdev, struct scifmsg *msg);
192 void scif_clientsend(struct scif_dev *scifdev, struct scifmsg *msg);
193 void scif_clientrcvd(struct scif_dev *scifdev, struct scifmsg *msg);
194 int __scif_connect(scif_epd_t epd, struct scif_port_id *dst, bool non_block);
195 int __scif_flush(scif_epd_t epd);
196 int scif_mmap(struct vm_area_struct *vma, scif_epd_t epd);
197 __poll_t __scif_pollfd(struct file *f, poll_table *wait,
198                            struct scif_endpt *ep);
199 int __scif_pin_pages(void *addr, size_t len, int *out_prot,
200                      int map_flags, scif_pinned_pages_t *pages);
201 #endif /* SCIF_EPD_H */