blob: 0b9dfe1cc06c01a70926f96665a71ed232617c7f [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001/* 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
18enum 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 */
37struct 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 */
53struct 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 */
96struct 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
130static 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 */
142static 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
156static inline int scif_anon_inode_getfile(scif_epd_t epd)
157{
158 epd->anon = anon_inode_getfile("scif", &scif_anon_fops, NULL, 0);
159
160 return PTR_ERR_OR_ZERO(epd->anon);
161}
162
163static inline void scif_anon_inode_fput(scif_epd_t epd)
164{
165 if (epd->anon) {
166 fput(epd->anon);
167 epd->anon = NULL;
168 }
169}
170
171void scif_cleanup_zombie_epd(void);
172void scif_teardown_ep(void *endpt);
173void scif_cleanup_ep_qp(struct scif_endpt *ep);
174void scif_add_epd_to_zombie_list(struct scif_endpt *ep, bool eplock_held);
175void scif_get_node_info(void);
176void scif_send_acks(struct scif_dev *dev);
177void scif_conn_handler(struct work_struct *work);
178int scif_rsrv_port(u16 port);
179void scif_get_port(u16 port);
180int scif_get_new_port(void);
181void scif_put_port(u16 port);
182int scif_user_send(scif_epd_t epd, void __user *msg, int len, int flags);
183int scif_user_recv(scif_epd_t epd, void __user *msg, int len, int flags);
184void scif_cnctreq(struct scif_dev *scifdev, struct scifmsg *msg);
185void scif_cnctgnt(struct scif_dev *scifdev, struct scifmsg *msg);
186void scif_cnctgnt_ack(struct scif_dev *scifdev, struct scifmsg *msg);
187void scif_cnctgnt_nack(struct scif_dev *scifdev, struct scifmsg *msg);
188void scif_cnctrej(struct scif_dev *scifdev, struct scifmsg *msg);
189void scif_discnct(struct scif_dev *scifdev, struct scifmsg *msg);
190void scif_discnt_ack(struct scif_dev *scifdev, struct scifmsg *msg);
191void scif_clientsend(struct scif_dev *scifdev, struct scifmsg *msg);
192void scif_clientrcvd(struct scif_dev *scifdev, struct scifmsg *msg);
193int __scif_connect(scif_epd_t epd, struct scif_port_id *dst, bool non_block);
194int __scif_flush(scif_epd_t epd);
195int scif_mmap(struct vm_area_struct *vma, scif_epd_t epd);
196__poll_t __scif_pollfd(struct file *f, poll_table *wait,
197 struct scif_endpt *ep);
198int __scif_pin_pages(void *addr, size_t len, int *out_prot,
199 int map_flags, scif_pinned_pages_t *pages);
200#endif /* SCIF_EPD_H */