1 /* 2 * Copyright (c) 2006-2016 Chelsio, Inc. All rights reserved. 3 * 4 * This software is available to you under a choice of one of two 5 * licenses. You may choose to be licensed under the terms of the GNU 6 * General Public License (GPL) Version 2, available from the file 7 * COPYING in the main directory of this source tree, or the 8 * OpenIB.org BSD license below: 9 * 10 * Redistribution and use in source and binary forms, with or 11 * without modification, are permitted provided that the following 12 * conditions are met: 13 * 14 * - Redistributions of source code must retain the above 15 * copyright notice, this list of conditions and the following 16 * disclaimer. 17 * 18 * - Redistributions in binary form must reproduce the above 19 * copyright notice, this list of conditions and the following 20 * disclaimer in the documentation and/or other materials 21 * provided with the distribution. 22 * 23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30 * SOFTWARE. 31 */ 32 #ifndef IWCH_H 33 #define IWCH_H 34 35 #include <pthread.h> 36 #include <inttypes.h> 37 #include <stddef.h> 38 #include <string.h> 39 #include <syslog.h> 40 #include <sys/errno.h> 41 #include <sys/time.h> 42 #include <infiniband/driver.h> 43 #include <infiniband/udma_barrier.h> 44 #include <sys/queue.h> 45 #include "t4.h" 46 47 extern unsigned long c4iw_page_size; 48 extern unsigned long c4iw_page_shift; 49 extern unsigned long c4iw_page_mask; 50 51 struct c4iw_mr; 52 53 struct c4iw_dev { 54 struct verbs_device ibv_dev; 55 unsigned chip_version; 56 int max_mr; 57 struct c4iw_mr **mmid2ptr; 58 int max_qp; 59 struct c4iw_qp **qpid2ptr; 60 int max_cq; 61 struct c4iw_cq **cqid2ptr; 62 pthread_spinlock_t lock; 63 TAILQ_ENTRY(c4iw_dev) list; 64 int abi_version; 65 }; 66 67 static inline int dev_is_t6(struct c4iw_dev *dev) 68 { 69 return dev->chip_version == CHELSIO_T6; 70 } 71 72 static inline int dev_is_t5(struct c4iw_dev *dev) 73 { 74 return dev->chip_version == CHELSIO_T5; 75 } 76 77 static inline int dev_is_t4(struct c4iw_dev *dev) 78 { 79 return dev->chip_version == CHELSIO_T4; 80 } 81 82 struct c4iw_context { 83 struct ibv_context ibv_ctx; 84 struct t4_dev_status_page *status_page; 85 int status_page_size; 86 }; 87 88 struct c4iw_pd { 89 struct ibv_pd ibv_pd; 90 }; 91 92 struct c4iw_mr { 93 struct ibv_mr ibv_mr; 94 uint64_t va_fbo; 95 uint32_t len; 96 }; 97 98 static inline u32 c4iw_mmid(u32 stag) 99 { 100 return (stag >> 8); 101 } 102 103 struct c4iw_cq { 104 struct ibv_cq ibv_cq; 105 struct c4iw_dev *rhp; 106 struct t4_cq cq; 107 pthread_spinlock_t lock; 108 #ifdef STALL_DETECTION 109 struct timeval time; 110 int dumped; 111 #endif 112 }; 113 114 struct c4iw_qp { 115 struct ibv_qp ibv_qp; 116 struct c4iw_dev *rhp; 117 struct t4_wq wq; 118 pthread_spinlock_t lock; 119 int sq_sig_all; 120 }; 121 122 #define to_c4iw_xxx(xxx, type) \ 123 ((struct c4iw_##type *) \ 124 ((void *) ib##xxx - offsetof(struct c4iw_##type, ibv_##xxx))) 125 126 static inline struct c4iw_dev *to_c4iw_dev(struct ibv_device *ibdev) 127 { 128 return to_c4iw_xxx(dev, dev); 129 } 130 131 static inline struct c4iw_context *to_c4iw_context(struct ibv_context *ibctx) 132 { 133 return to_c4iw_xxx(ctx, context); 134 } 135 136 static inline struct c4iw_pd *to_c4iw_pd(struct ibv_pd *ibpd) 137 { 138 return to_c4iw_xxx(pd, pd); 139 } 140 141 static inline struct c4iw_cq *to_c4iw_cq(struct ibv_cq *ibcq) 142 { 143 return to_c4iw_xxx(cq, cq); 144 } 145 146 static inline struct c4iw_qp *to_c4iw_qp(struct ibv_qp *ibqp) 147 { 148 return to_c4iw_xxx(qp, qp); 149 } 150 151 static inline struct c4iw_mr *to_c4iw_mr(struct ibv_mr *ibmr) 152 { 153 return to_c4iw_xxx(mr, mr); 154 } 155 156 static inline struct c4iw_qp *get_qhp(struct c4iw_dev *rhp, u32 qid) 157 { 158 return rhp->qpid2ptr[qid]; 159 } 160 161 static inline struct c4iw_cq *get_chp(struct c4iw_dev *rhp, u32 qid) 162 { 163 return rhp->cqid2ptr[qid]; 164 } 165 166 static inline unsigned long_log2(unsigned long x) 167 { 168 unsigned r = 0; 169 for (x >>= 1; x > 0; x >>= 1) 170 r++; 171 return r; 172 } 173 174 int c4iw_query_device(struct ibv_context *context, 175 struct ibv_device_attr *attr); 176 int c4iw_query_port(struct ibv_context *context, uint8_t port, 177 struct ibv_port_attr *attr); 178 179 struct ibv_pd *c4iw_alloc_pd(struct ibv_context *context); 180 int c4iw_free_pd(struct ibv_pd *pd); 181 182 struct ibv_mr *c4iw_reg_mr(struct ibv_pd *pd, void *addr, 183 size_t length, int access); 184 int c4iw_dereg_mr(struct ibv_mr *mr); 185 186 struct ibv_cq *c4iw_create_cq(struct ibv_context *context, int cqe, 187 struct ibv_comp_channel *channel, 188 int comp_vector); 189 int c4iw_resize_cq(struct ibv_cq *cq, int cqe); 190 int c4iw_destroy_cq(struct ibv_cq *cq); 191 int c4iw_poll_cq(struct ibv_cq *cq, int ne, struct ibv_wc *wc); 192 int c4iw_arm_cq(struct ibv_cq *cq, int solicited); 193 void c4iw_cq_event(struct ibv_cq *cq); 194 void c4iw_init_cq_buf(struct c4iw_cq *cq, int nent); 195 196 struct ibv_srq *c4iw_create_srq(struct ibv_pd *pd, 197 struct ibv_srq_init_attr *attr); 198 int c4iw_modify_srq(struct ibv_srq *srq, 199 struct ibv_srq_attr *attr, 200 int mask); 201 int c4iw_destroy_srq(struct ibv_srq *srq); 202 int c4iw_post_srq_recv(struct ibv_srq *ibsrq, 203 struct ibv_recv_wr *wr, 204 struct ibv_recv_wr **bad_wr); 205 206 struct ibv_qp *c4iw_create_qp(struct ibv_pd *pd, 207 struct ibv_qp_init_attr *attr); 208 int c4iw_modify_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr, 209 int attr_mask); 210 int c4iw_destroy_qp(struct ibv_qp *qp); 211 int c4iw_query_qp(struct ibv_qp *qp, 212 struct ibv_qp_attr *attr, 213 int attr_mask, 214 struct ibv_qp_init_attr *init_attr); 215 void c4iw_flush_qp(struct c4iw_qp *qhp); 216 void c4iw_flush_qps(struct c4iw_dev *dev); 217 int c4iw_post_send(struct ibv_qp *ibqp, struct ibv_send_wr *wr, 218 struct ibv_send_wr **bad_wr); 219 int c4iw_post_receive(struct ibv_qp *ibqp, struct ibv_recv_wr *wr, 220 struct ibv_recv_wr **bad_wr); 221 struct ibv_ah *c4iw_create_ah(struct ibv_pd *pd, 222 struct ibv_ah_attr *ah_attr); 223 int c4iw_destroy_ah(struct ibv_ah *ah); 224 int c4iw_attach_mcast(struct ibv_qp *qp, const union ibv_gid *gid, 225 uint16_t lid); 226 int c4iw_detach_mcast(struct ibv_qp *qp, const union ibv_gid *gid, 227 uint16_t lid); 228 void c4iw_async_event(struct ibv_async_event *event); 229 void c4iw_flush_hw_cq(struct c4iw_cq *chp); 230 int c4iw_flush_rq(struct t4_wq *wq, struct t4_cq *cq, int count); 231 void c4iw_flush_sq(struct c4iw_qp *qhp); 232 void c4iw_count_rcqes(struct t4_cq *cq, struct t4_wq *wq, int *count); 233 234 #define FW_MAJ 0 235 #define FW_MIN 0 236 237 static inline unsigned long align(unsigned long val, unsigned long align) 238 { 239 return (val + align - 1) & ~(align - 1); 240 } 241 242 #ifdef STATS 243 244 #define INC_STAT(a) { c4iw_stats.a++; } 245 246 struct c4iw_stats { 247 unsigned long send; 248 unsigned long recv; 249 unsigned long read; 250 unsigned long write; 251 unsigned long arm; 252 unsigned long cqe; 253 unsigned long mr; 254 unsigned long qp; 255 unsigned long cq; 256 }; 257 extern struct c4iw_stats c4iw_stats; 258 #else 259 #define INC_STAT(a) 260 #endif 261 262 #ifdef STALL_DETECTION 263 void dump_state(void); 264 extern int stall_to; 265 #endif 266 267 #endif /* IWCH_H */ 268