211 lines
6.3 KiB
C
211 lines
6.3 KiB
C
/*
|
|
* Intel MIC Platform Software Stack (MPSS)
|
|
*
|
|
* Copyright(c) 2014 Intel Corporation.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License, version 2, as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* General Public License for more details.
|
|
*
|
|
* Intel SCIF driver.
|
|
*
|
|
*/
|
|
#ifndef SCIF_EPD_H
|
|
#define SCIF_EPD_H
|
|
|
|
#include <linux/delay.h>
|
|
#include <linux/scif.h>
|
|
#include <linux/scif_ioctl.h>
|
|
|
|
#define SCIF_EPLOCK_HELD true
|
|
|
|
enum scif_epd_state {
|
|
SCIFEP_UNBOUND,
|
|
SCIFEP_BOUND,
|
|
SCIFEP_LISTENING,
|
|
SCIFEP_CONNECTED,
|
|
SCIFEP_CONNECTING,
|
|
SCIFEP_MAPPING,
|
|
SCIFEP_CLOSING,
|
|
SCIFEP_CLLISTEN,
|
|
SCIFEP_DISCONNECTED,
|
|
SCIFEP_ZOMBIE
|
|
};
|
|
|
|
/*
|
|
* struct scif_conreq - Data structure added to the connection list.
|
|
*
|
|
* @msg: connection request message received
|
|
* @list: link to list of connection requests
|
|
*/
|
|
struct scif_conreq {
|
|
struct scifmsg msg;
|
|
struct list_head list;
|
|
};
|
|
|
|
/* Size of the RB for the Endpoint QP */
|
|
#define SCIF_ENDPT_QP_SIZE 0x1000
|
|
|
|
/*
|
|
* scif_endpt_qp_info - SCIF endpoint queue pair
|
|
*
|
|
* @qp - Qpair for this endpoint
|
|
* @qp_offset - DMA address of the QP
|
|
* @gnt_pld - Payload in a SCIF_CNCT_GNT message containing the
|
|
* physical address of the remote_qp.
|
|
*/
|
|
struct scif_endpt_qp_info {
|
|
struct scif_qp *qp;
|
|
dma_addr_t qp_offset;
|
|
dma_addr_t gnt_pld;
|
|
};
|
|
|
|
/*
|
|
* struct scif_endpt - The SCIF endpoint data structure
|
|
*
|
|
* @state: end point state
|
|
* @lock: lock synchronizing access to endpoint fields like state etc
|
|
* @port: self port information
|
|
* @peer: peer port information
|
|
* @backlog: maximum pending connection requests
|
|
* @qp_info: Endpoint QP information for SCIF messaging
|
|
* @remote_dev: scifdev used by this endpt to communicate with remote node.
|
|
* @remote_ep: remote endpoint
|
|
* @conreqcnt: Keep track of number of connection requests.
|
|
* @files: Open file information used to match the id passed in with
|
|
* the flush routine.
|
|
* @conlist: list of connection requests
|
|
* @conwq: waitqueue for connection processing
|
|
* @discon: completion used during disconnection
|
|
* @sendwq: waitqueue used during sending messages
|
|
* @recvwq: waitqueue used during message receipt
|
|
* @sendlock: Synchronize ordering of messages sent
|
|
* @recvlock: Synchronize ordering of messages received
|
|
* @list: link to list of various endpoints like connected, listening etc
|
|
* @li_accept: pending ACCEPTREG
|
|
* @acceptcnt: pending ACCEPTREG cnt
|
|
* @liacceptlist: link to listen accept
|
|
* @miacceptlist: link to uaccept
|
|
* @listenep: associated listen ep
|
|
* @conn_work: Non blocking connect work
|
|
* @conn_port: Connection port
|
|
* @conn_err: Errors during connection
|
|
* @conn_async_state: Async connection
|
|
* @conn_pend_wq: Used by poll while waiting for incoming connections
|
|
* @conn_list: List of async connection requests
|
|
* @rma_info: Information for triggering SCIF RMA and DMA operations
|
|
* @mmu_list: link to list of MMU notifier cleanup work
|
|
* @anon: anonymous file for use in kernel mode scif poll
|
|
*/
|
|
struct scif_endpt {
|
|
enum scif_epd_state state;
|
|
spinlock_t lock;
|
|
struct scif_port_id port;
|
|
struct scif_port_id peer;
|
|
int backlog;
|
|
struct scif_endpt_qp_info qp_info;
|
|
struct scif_dev *remote_dev;
|
|
u64 remote_ep;
|
|
int conreqcnt;
|
|
struct files_struct *files;
|
|
struct list_head conlist;
|
|
wait_queue_head_t conwq;
|
|
struct completion discon;
|
|
wait_queue_head_t sendwq;
|
|
wait_queue_head_t recvwq;
|
|
struct mutex sendlock;
|
|
struct mutex recvlock;
|
|
struct list_head list;
|
|
struct list_head li_accept;
|
|
int acceptcnt;
|
|
struct list_head liacceptlist;
|
|
struct list_head miacceptlist;
|
|
struct scif_endpt *listenep;
|
|
struct scif_port_id conn_port;
|
|
int conn_err;
|
|
int conn_async_state;
|
|
wait_queue_head_t conn_pend_wq;
|
|
struct list_head conn_list;
|
|
struct scif_endpt_rma_info rma_info;
|
|
struct list_head mmu_list;
|
|
struct file *anon;
|
|
};
|
|
|
|
static inline int scifdev_alive(struct scif_endpt *ep)
|
|
{
|
|
return _scifdev_alive(ep->remote_dev);
|
|
}
|
|
|
|
/*
|
|
* scif_verify_epd:
|
|
* ep: SCIF endpoint
|
|
*
|
|
* Checks several generic error conditions and returns the
|
|
* appropriate error.
|
|
*/
|
|
static inline int scif_verify_epd(struct scif_endpt *ep)
|
|
{
|
|
if (ep->state == SCIFEP_DISCONNECTED)
|
|
return -ECONNRESET;
|
|
|
|
if (ep->state != SCIFEP_CONNECTED)
|
|
return -ENOTCONN;
|
|
|
|
if (!scifdev_alive(ep))
|
|
return -ENODEV;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static inline int scif_anon_inode_getfile(scif_epd_t epd)
|
|
{
|
|
epd->anon = anon_inode_getfile("scif", &scif_anon_fops, NULL, 0);
|
|
if (IS_ERR(epd->anon))
|
|
return PTR_ERR(epd->anon);
|
|
return 0;
|
|
}
|
|
|
|
static inline void scif_anon_inode_fput(scif_epd_t epd)
|
|
{
|
|
if (epd->anon) {
|
|
fput(epd->anon);
|
|
epd->anon = NULL;
|
|
}
|
|
}
|
|
|
|
void scif_cleanup_zombie_epd(void);
|
|
void scif_teardown_ep(void *endpt);
|
|
void scif_cleanup_ep_qp(struct scif_endpt *ep);
|
|
void scif_add_epd_to_zombie_list(struct scif_endpt *ep, bool eplock_held);
|
|
void scif_get_node_info(void);
|
|
void scif_send_acks(struct scif_dev *dev);
|
|
void scif_conn_handler(struct work_struct *work);
|
|
int scif_rsrv_port(u16 port);
|
|
void scif_get_port(u16 port);
|
|
int scif_get_new_port(void);
|
|
void scif_put_port(u16 port);
|
|
int scif_user_send(scif_epd_t epd, void __user *msg, int len, int flags);
|
|
int scif_user_recv(scif_epd_t epd, void __user *msg, int len, int flags);
|
|
void scif_cnctreq(struct scif_dev *scifdev, struct scifmsg *msg);
|
|
void scif_cnctgnt(struct scif_dev *scifdev, struct scifmsg *msg);
|
|
void scif_cnctgnt_ack(struct scif_dev *scifdev, struct scifmsg *msg);
|
|
void scif_cnctgnt_nack(struct scif_dev *scifdev, struct scifmsg *msg);
|
|
void scif_cnctrej(struct scif_dev *scifdev, struct scifmsg *msg);
|
|
void scif_discnct(struct scif_dev *scifdev, struct scifmsg *msg);
|
|
void scif_discnt_ack(struct scif_dev *scifdev, struct scifmsg *msg);
|
|
void scif_clientsend(struct scif_dev *scifdev, struct scifmsg *msg);
|
|
void scif_clientrcvd(struct scif_dev *scifdev, struct scifmsg *msg);
|
|
int __scif_connect(scif_epd_t epd, struct scif_port_id *dst, bool non_block);
|
|
int __scif_flush(scif_epd_t epd);
|
|
int scif_mmap(struct vm_area_struct *vma, scif_epd_t epd);
|
|
__poll_t __scif_pollfd(struct file *f, poll_table *wait,
|
|
struct scif_endpt *ep);
|
|
int __scif_pin_pages(void *addr, size_t len, int *out_prot,
|
|
int map_flags, scif_pinned_pages_t *pages);
|
|
#endif /* SCIF_EPD_H */
|