scif_epd.h 6.3 KB

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