1 /* 2 * Copyright (c) 2014, Cisco Systems, Inc. All rights reserved. 3 * 4 * LICENSE_BEGIN 5 * 6 * This software is available to you under a choice of one of two 7 * licenses. You may choose to be licensed under the terms of the GNU 8 * General Public License (GPL) Version 2, available from the file 9 * COPYING in the main directory of this source tree, or the 10 * BSD license below: 11 * 12 * Redistribution and use in source and binary forms, with or 13 * without modification, are permitted provided that the following 14 * conditions are met: 15 * 16 * - Redistributions of source code must retain the above 17 * copyright notice, this list of conditions and the following 18 * disclaimer. 19 * 20 * - Redistributions in binary form must reproduce the above 21 * copyright notice, this list of conditions and the following 22 * disclaimer in the documentation and/or other materials 23 * provided with the distribution. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 28 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 29 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 30 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 31 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 32 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 33 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 35 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 * 38 * LICENSE_END 39 * 40 * 41 */ 42 43 #ifndef _USD_H_ 44 #define _USD_H_ 45 46 #include <sys/queue.h> 47 48 #include "kcompat.h" 49 #include "vnic_rq.h" 50 #include "vnic_wq.h" 51 #include "vnic_cq.h" 52 #include "wq_enet_desc.h" 53 #include "rq_enet_desc.h" 54 #include "vnic_intr.h" 55 56 #include "usnic_abi.h" 57 #include "usnic_direct.h" 58 #include "usd_ib_sysfs.h" 59 60 #define USD_INVALID_HANDLE (~0) 61 #define USD_SF_ISSET(flags, flagname) \ 62 ((flags >> USD_SFS_##flagname) & 1) 63 64 #define USD_SEND_MAX_COPY 992 65 #define USD_MAX_PRESEND 4 66 67 #define USD_CTXF_CLOSE_CMD_FD (1u << 0) 68 #define USD_DEVF_CLOSE_CTX (1u << 0) 69 70 #ifndef USD_DEBUG 71 #define USD_DEBUG 0 72 #endif 73 74 /* 75 * Group interrupt vector userspace map info 76 */ 77 struct usd_grp_vect_map { 78 void *va; 79 size_t len; 80 uint32_t vfid; 81 }; 82 83 /* 84 * structure storing interrupt resource and its mapping to FD 85 */ 86 struct usd_cq_comp_intr { 87 struct vnic_intr uci_vintr; 88 int uci_offset; 89 int uci_refcnt; 90 LIST_ENTRY(usd_cq_comp_intr) uci_ctx_link; 91 }; 92 93 /* 94 * Instance of a usd context, corresponding to an 95 * opened libibverbs context 96 */ 97 struct usd_context { 98 struct usd_ib_dev *ucx_ib_dev; /* parent IB dev */ 99 int ucx_ib_dev_fd; /* file desc for IB dev */ 100 int ucmd_ib_dev_fd; /* Another open file descriptor for IB dev 101 * used for encapusulating user commands 102 * through GET_CONTEXT IB command */ 103 104 uint32_t ucx_flags; 105 int ucx_caps[USD_CAP_MAX]; /* device capablities */ 106 107 pthread_mutex_t ucx_mutex; /* protect intr_list */ 108 LIST_HEAD(intr_head, usd_cq_comp_intr) ucx_intr_list; 109 110 /* Remove these after moving ud_attrs here */ 111 int event_fd; 112 unsigned num_comp_vectors; 113 }; 114 115 /* 116 * Instance of a device opened by user 117 */ 118 struct usd_device { 119 struct usd_context *ud_ctx; 120 121 uint32_t ud_flags; 122 struct usd_device_attrs ud_attrs; /* TODO move this to usd_ctx */ 123 124 /* VFs we have associated with this device */ 125 struct usd_vf *ud_vf_list; 126 127 /* PD for this device */ 128 uint32_t ud_pd_handle; 129 130 /* destination related */ 131 int ud_arp_sockfd; /* for ARP */ 132 TAILQ_HEAD(, usd_dest_req) ud_pending_reqs; 133 TAILQ_HEAD(, usd_dest_req) ud_completed_reqs; 134 135 TAILQ_ENTRY(usd_device) ud_link; 136 137 struct usd_grp_vect_map grp_vect_map; 138 }; 139 140 /* 141 * Registered memory region 142 */ 143 struct usd_mr { 144 struct usd_device *umr_dev; 145 void *umr_vaddr; 146 uint32_t umr_handle; 147 uint32_t umr_lkey; 148 uint32_t umr_rkey; 149 size_t umr_length; 150 }; 151 152 /* 153 * Information about the PCI virtual function 154 */ 155 struct usd_vf { 156 uint32_t vf_id; 157 int vf_refcnt; 158 struct vnic_dev_bar vf_bar0; 159 size_t vf_bar_map_len; 160 struct vnic_dev *vf_vdev; 161 struct vnic_dev_iomap_info iomaps[RES_TYPE_MAX]; 162 163 /* Will also protect the devcmd region */ 164 pthread_mutex_t vf_lock; 165 struct usd_vf *vf_next; 166 struct usd_vf *vf_prev; 167 }; 168 169 /* 170 * Holding place for information about a VF 171 */ 172 struct usd_vf_info { 173 uint32_t vi_vfid; 174 dma_addr_t vi_bar_bus_addr; 175 uint32_t vi_bar_len; 176 size_t vi_barhead_len; 177 struct usnic_vnic_barres_info barres[RES_TYPE_MAX]; 178 }; 179 180 /* 181 * Internal representation of a filter 182 */ 183 struct usd_qp_filter { 184 enum usd_filter_type qf_type; 185 union { 186 struct { 187 int u_sockfd; 188 } qf_udp; 189 } qf_filter; 190 }; 191 192 /* 193 * Definitions and structures about queues 194 */ 195 196 /* 197 * this is used to keep track of what has been allocated and/or 198 * initialized to assist with teardown of partially completed queues 199 */ 200 enum usd_qstate { 201 USD_QS_FILTER_ALLOC = (1 << 0), 202 USD_QS_VERBS_CREATED = (1 << 1), 203 USD_QS_VF_MAPPED = (1 << 2), 204 USD_QS_VNIC_ALLOCATED = (1 << 3), 205 USD_QS_VNIC_INITIALIZED = (1 << 4), 206 USD_QS_READY = (1 << 5) 207 }; 208 209 struct usd_cq_impl { 210 struct usd_cq ucq_cq; 211 struct usd_device *ucq_dev; 212 struct usd_vf *ucq_vf; 213 214 uint32_t ucq_state; 215 216 struct vnic_cq ucq_vnic_cq; 217 218 void *ucq_desc_ring; 219 uint32_t ucq_next_desc; 220 uint32_t ucq_last_color; 221 222 uint32_t ucq_index; 223 uint32_t ucq_num_entries; 224 uint32_t ucq_cqe_mask; 225 uint32_t ucq_color_shift; 226 uint32_t ucq_handle; 227 228 int comp_fd; 229 int comp_vec; 230 int comp_req_notify; 231 int intr_offset; 232 struct usd_cq_comp_intr *ucq_intr; 233 234 struct usd_rq **ucq_rq_map; 235 struct usd_wq **ucq_wq_map; 236 }; 237 #define to_cqi(CQ) ((struct usd_cq_impl *)(CQ)) 238 #define to_usdcq(CQ) (&(CQ)->ucq_cq) 239 240 struct usd_rq { 241 struct usd_cq_impl *urq_cq; 242 uint32_t urq_state; 243 244 uint32_t urq_index; 245 uint32_t urq_num_entries; 246 struct vnic_rq urq_vnic_rq; 247 248 void **urq_context; 249 250 char *urq_rxbuf; 251 char **urq_post_addr; 252 uint32_t urq_recv_credits; /* number of available descriptors */ 253 struct rq_enet_desc *urq_desc_ring; 254 struct rq_enet_desc *urq_next_desc; 255 uint32_t urq_post_index; /* next rxbuf to post */ 256 uint32_t urq_post_index_mask; 257 uint32_t urq_last_comp; 258 uint32_t urq_accum_bytes; 259 260 uint32_t urq_num_rxbuf; 261 uint32_t urq_rxbuf_size; 262 }; 263 264 struct usd_wq_post_info { 265 void *wp_context; 266 uint32_t wp_len; 267 }; 268 269 struct usd_wq { 270 struct usd_cq_impl *uwq_cq; 271 uint32_t uwq_state; 272 struct vnic_wq uwq_vnic_wq; 273 274 uint32_t uwq_index; 275 uint32_t uwq_num_entries; 276 uint32_t uwq_send_credits; 277 struct wq_enet_desc *uwq_desc_ring; 278 struct wq_enet_desc *uwq_next_desc; 279 uint32_t uwq_post_index; 280 uint32_t uwq_post_index_mask; 281 uint32_t uwq_last_comp; 282 283 uint8_t *uwq_copybuf; 284 struct usd_wq_post_info *uwq_post_info; 285 286 /* used only for PIO QPs */ 287 void *pio_v_wq_addr; 288 uint64_t pio_p_wq_addr; 289 char *pio_v_pkt_buf; 290 uint64_t pio_p_pkt_buf; 291 }; 292 293 struct usd_qp_impl { 294 struct usd_qp uq_qp; /* user's view of QP */ 295 296 struct usd_device *uq_dev; 297 struct usd_vf *uq_vf; 298 299 struct usd_qp_attrs uq_attrs; 300 301 uint32_t uq_qp_handle; /* IB QP handle */ 302 uint32_t uq_qp_num; 303 304 /* primary filter for this QP */ 305 struct usd_qp_filter uq_filter; 306 307 struct usd_wq uq_wq; 308 struct usd_rq uq_rq; 309 }; 310 #define to_qpi(Q) ((struct usd_qp_impl *)(Q)) 311 #define to_usdqp(Q) (&(Q)->uq_qp) 312 313 struct usd_dest { 314 union { 315 struct { 316 struct usd_udp_hdr u_hdr; 317 } ds_udp; 318 } ds_dest; 319 }; 320 321 extern struct usd_qp_ops usd_qp_ops_ud_udp; 322 extern struct usd_qp_ops usd_qp_ops_ud_pio_udp; 323 extern struct usd_qp_ops usd_qp_ops_ud_raw; 324 #endif /* _USD_H_ */ 325