| 1 | /* |
| 2 | * Copyright 2010-2017 Intel Corporation. |
| 3 | * |
| 4 | * This program is free software; you can redistribute it and/or modify |
| 5 | * it under the terms of the GNU General Public License, version 2, |
| 6 | * as published by the Free Software Foundation. |
| 7 | * |
| 8 | * This program is distributed in the hope that it will be useful, |
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 11 | * General Public License for more details. |
| 12 | * |
| 13 | * Disclaimer: The codes contained in these modules may be specific to |
| 14 | * the Intel Software Development Platform codenamed Knights Ferry, |
| 15 | * and the Intel product codenamed Knights Corner, and are not backward |
| 16 | * compatible with other Intel products. Additionally, Intel will NOT |
| 17 | * support the codes or instruction set in future products. |
| 18 | * |
| 19 | * Intel offers no warranty of any kind regarding the code. This code is |
| 20 | * licensed on an "AS IS" basis and Intel is not obligated to provide |
| 21 | * any support, assistance, installation, training, or other services |
| 22 | * of any kind. Intel is also not obligated to provide any updates, |
| 23 | * enhancements or extensions. Intel specifically disclaims any warranty |
| 24 | * of merchantability, non-infringement, fitness for any particular |
| 25 | * purpose, and any other warranty. |
| 26 | * |
| 27 | * Further, Intel disclaims all liability of any kind, including but |
| 28 | * not limited to liability for infringement of any proprietary rights, |
| 29 | * relating to the use of the code, even if Intel is notified of the |
| 30 | * possibility of such liability. Except as expressly stated in an Intel |
| 31 | * license agreement provided with this code and agreed upon with Intel, |
| 32 | * no license, express or implied, by estoppel or otherwise, to any |
| 33 | * intellectual property rights is granted herein. |
| 34 | */ |
| 35 | |
| 36 | #ifndef MICSCIF_NODEQP |
| 37 | #define MICSCIF_NODEQP |
| 38 | |
| 39 | #include "micscif_rb.h" |
| 40 | |
| 41 | /* Payload Description */ |
| 42 | #define SCIF_INIT 1 /* Address of node's node First message sent by a node to |
| 43 | * array the host, and host to node |
| 44 | */ |
| 45 | #define SCIF_EXIT 2 /* Last message telling the host the driver is exiting */ |
| 46 | #define SCIF_NODE_ADD 3 /* Tell Online nodes a new node exits */ |
| 47 | #define SCIF_NODE_ADD_ACK 4 /* Confirm to host sequence is finished TODO Needed??? */ |
| 48 | #define SCIF_CNCT_REQ 5 /* Phys addr of Request connection to a port */ |
| 49 | #define SCIF_CNCT_GNT 6 /* Phys addr of new Grant connection request */ |
| 50 | #define SCIF_CNCT_GNTACK 7 /* Error type Reject a connection request */ |
| 51 | #define SCIF_CNCT_GNTNACK 8 /* Error type Reject a connection request */ |
| 52 | #define SCIF_CNCT_REJ 9 /* Error type Reject a connection request */ |
| 53 | #define SCIF_CNCT_TERM 10 /* Terminate type Terminate a connection request */ |
| 54 | #define SCIF_TERM_ACK 11 /* Terminate type Terminate a connection request */ |
| 55 | #define SCIF_DISCNCT 12 /* Notify peer that connection is being terminated */ |
| 56 | #define SCIF_DISCNT_ACK 13 /* Notify peer that connection is being terminated */ |
| 57 | #define SCIF_REGISTER 14 /* Tell peer about a new registered window */ |
| 58 | #define SCIF_REGISTER_ACK 15 /* Notify peer about unregistration success */ |
| 59 | #define SCIF_REGISTER_NACK 16 /* Notify peer about registration success */ |
| 60 | #define SCIF_UNREGISTER 17 /* Tell peer about unregistering a registered window */ |
| 61 | #define SCIF_UNREGISTER_ACK 18 /* Notify peer about registration failure */ |
| 62 | #define SCIF_UNREGISTER_NACK 19 /* Notify peer about unregistration failure */ |
| 63 | #define SCIF_ALLOC_REQ 20 /* Request a mapped buffer */ |
| 64 | #define SCIF_ALLOC_GNT 21 /* Notify peer about allocation success */ |
| 65 | #define SCIF_ALLOC_REJ 22 /* Notify peer about allocation failure */ |
| 66 | #define SCIF_FREE_PHYS 23 /* Free previously allocated GTT/PCI mappings */ |
| 67 | #define SCIF_FREE_VIRT 24 /* Free previously allocated virtual memory */ |
| 68 | #define SCIF_CLIENT_SENT 25 /* Notify the peer that a data message has been written to the RB */ |
| 69 | #define SCIF_CLIENT_RCVD 26 /* Notify the peer that a data message has been read from the RB */ |
| 70 | #define SCIF_MUNMAP 27 /* Acknowledgment for a SCIF_MMAP request */ |
| 71 | #define SCIF_MARK 28 /* SCIF Remote Fence Mark Request */ |
| 72 | #define SCIF_MARK_ACK 29 /* SCIF Remote Fence Mark Success */ |
| 73 | #define SCIF_MARK_NACK 30 /* SCIF Remote Fence Mark Failure */ |
| 74 | #define SCIF_WAIT 31 /* SCIF Remote Fence Wait Request */ |
| 75 | #define SCIF_WAIT_ACK 32 /* SCIF Remote Fence Wait Success */ |
| 76 | #define SCIF_WAIT_NACK 33 /* SCIF Remote Fence Wait Failure */ |
| 77 | #define SCIF_SIG_LOCAL 34 /* SCIF Remote Fence Local Signal Request */ |
| 78 | #define SCIF_SIG_REMOTE 35 /* SCIF Remote Fence Remote Signal Request */ |
| 79 | #define SCIF_SIG_ACK 36 /* SCIF Remote Fence Remote Signal Success */ |
| 80 | #define SCIF_SIG_NACK 37 /* SCIF Remote Fence Remote Signal Failure */ |
| 81 | #define SCIF_NODE_CREATE_DEP 42 /* Notify the Host that a new dependency is |
| 82 | * being created between two nodes |
| 83 | */ |
| 84 | #define SCIF_NODE_DESTROY_DEP 43 /* Notify the Host that an existing dependency is |
| 85 | * being destroyed between two nodes |
| 86 | */ |
| 87 | #define SCIF_NODE_REMOVE 44 /* Request to deactivate a set of remote SCIF nodes */ |
| 88 | #define SCIF_NODE_REMOVE_ACK 45 /* Response to a SCIF_NODE_REMOVE message */ |
| 89 | #define SCIF_NODE_WAKE_UP 46 /* Notification to the Host to wake up a remote node */ |
| 90 | #define SCIF_NODE_WAKE_UP_ACK 47 /* Response to SCIF_NODE_WAKE_UP message */ |
| 91 | #define SCIF_NODE_WAKE_UP_NACK 48 /* Response to SCIF_NODE_WAKE_UP message. Think Lost Node */ |
| 92 | #define SCIF_NODE_ALIVE 49 /* Check if kn* card is alive */ |
| 93 | #define SCIF_NODE_ALIVE_ACK 50 /* ACK the for above message */ |
| 94 | #define SMPT_SET 51 /* Add a smpt entry */ |
| 95 | #define SCIF_PROXY_DMA 56 /* Proxies DMA read requests to peer for performance */ |
| 96 | #define SCIF_PROXY_ORDERED_DMA 57 /* Proxies DMA read requests to peer for performance */ |
| 97 | #define SCIF_NODE_CONNECT 58 /* Setup a p2p connection b/w two nodes */ |
| 98 | #define SCIF_NODE_CONNECT_NACK 59 /* p2p connection is not successful */ |
| 99 | #define SCIF_NODE_ADD_NACK 60 /* SCIF_NODE_ADD failed report to the waiting thread(s) */ |
| 100 | #define SCIF_GET_NODE_INFO 61 /* Get current node mask from the host*/ |
| 101 | #define SCIF_TEST 62 /* Test value Used for test only */ |
| 102 | #define SCIF_MAX_MSG SCIF_TEST |
| 103 | |
| 104 | |
| 105 | /* |
| 106 | * The *only* reason we need 2 uint64_t for payload |
| 107 | * right now is because the SCIF_CNCT_GNT message needs |
| 108 | * to send across both the QP offset and the QP id. |
| 109 | * |
| 110 | * Now we have to increase this to 3 uint64_t because |
| 111 | * the Alloc message requires the remote EP, allocation size |
| 112 | * and the allocation handle. |
| 113 | * |
| 114 | * Increased to 4 uint64_t because SCIF_FENCE requires |
| 115 | * ep, offset, len and the waitqueue pointer to wake up. |
| 116 | */ |
| 117 | struct nodemsg { |
| 118 | struct scif_portID src; |
| 119 | struct scif_portID dst; |
| 120 | uint32_t uop; |
| 121 | uint64_t payload[4]; |
| 122 | } __attribute__ ((packed)); |
| 123 | |
| 124 | |
| 125 | /* |
| 126 | * Generic state used for certain node QP message exchanges |
| 127 | * like Unregister, Alloc etc. |
| 128 | */ |
| 129 | enum micscif_msg_state { |
| 130 | OP_IDLE = 1, |
| 131 | OP_IN_PROGRESS, |
| 132 | OP_COMPLETED, |
| 133 | OP_FAILED |
| 134 | }; |
| 135 | |
| 136 | /* |
| 137 | * Generic structure used for exchanging ALLOC_REQ/GNT messages. |
| 138 | */ |
| 139 | struct allocmsg { |
| 140 | dma_addr_t phys_addr; |
| 141 | void *vaddr; |
| 142 | uint32_t uop; |
| 143 | size_t size; |
| 144 | enum micscif_msg_state state; |
| 145 | wait_queue_head_t allocwq; |
| 146 | }; |
| 147 | |
| 148 | /* Interesting structure -- a little difficult because we can only |
| 149 | * write across the PCIe, so any r/w pointer we need to read is |
| 150 | * local. We only need to read the read pointer on the inbound_q |
| 151 | * and read the write pointer in the outbound_q |
| 152 | */ |
| 153 | struct micscif_qp { |
| 154 | uint64_t ep; |
| 155 | uint64_t magic; |
| 156 | uint64_t blast; |
| 157 | #define SCIFEP_MAGIC 0x5c1f000000005c1f |
| 158 | struct micscif_rb outbound_q; |
| 159 | struct micscif_rb inbound_q; |
| 160 | /* FIXME cache align local_write/read */ |
| 161 | uint32_t local_write; /* For local inbound */ |
| 162 | uint32_t local_read; /* For local outbound */ |
| 163 | volatile struct micscif_qp *remote_qp; |
| 164 | dma_addr_t local_buf; /* Local BS */ |
| 165 | dma_addr_t local_qp; |
| 166 | dma_addr_t remote_buf; /* Remote BS */ |
| 167 | volatile uint32_t qp_state; |
| 168 | #define QP_OFFLINE 0xdead |
| 169 | #define QP_ONLINE 0xc0de |
| 170 | uint16_t scif_version; |
| 171 | spinlock_t qp_send_lock; |
| 172 | spinlock_t qp_recv_lock; |
| 173 | }; |
| 174 | |
| 175 | /* |
| 176 | * An element in the loopback Node QP message list. |
| 177 | */ |
| 178 | struct loopb_msg { |
| 179 | struct nodemsg msg; |
| 180 | struct list_head list_member; |
| 181 | }; |
| 182 | |
| 183 | struct micscif_qp *micscif_nodeqp_nextmsg(struct micscif_dev *scifdev); |
| 184 | int micscif_nodeqp_send(struct micscif_dev *scifdev, struct nodemsg *msg, struct endpt *ep); |
| 185 | int micscif_nodeqp_intrhandler(struct micscif_dev *scifdev, struct micscif_qp *qp); |
| 186 | int micscif_loopb_msg_handler(struct micscif_dev *scifdev, struct micscif_qp *qp); |
| 187 | |
| 188 | // Card side only functions |
| 189 | int micscif_setup_card_qp(phys_addr_t host_phys, struct micscif_dev *dev); |
| 190 | |
| 191 | int micscif_setuphost_response(struct micscif_dev *scifdev, uint64_t payload); |
| 192 | int micscif_setup_qp_connect(struct micscif_qp *qp, dma_addr_t *qp_offset, int local_size, struct micscif_dev *scifdev); |
| 193 | int micscif_setup_qp_accept(struct micscif_qp *qp, dma_addr_t *qp_offset, dma_addr_t phys, int local_size, struct micscif_dev *scifdev); |
| 194 | int micscif_setup_qp_connect_response(struct micscif_dev *scifdev, struct micscif_qp *qp, uint64_t payload); |
| 195 | int micscif_setup_loopback_qp(struct micscif_dev *scifdev); |
| 196 | int micscif_destroy_loopback_qp(struct micscif_dev *scifdev); |
| 197 | void micscif_teardown_ep(void *endpt); |
| 198 | void micscif_add_epd_to_zombie_list(struct endpt *ep, bool mi_eplock_held); |
| 199 | |
| 200 | #endif /* MICSCIF_NODEQP */ |