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_t7(struct c4iw_dev *dev) 68 { 69 return dev->chip_version == CHELSIO_T7; 70 } 71 72 static inline int dev_is_t6(struct c4iw_dev *dev) 73 { 74 return dev->chip_version == CHELSIO_T6; 75 } 76 77 static inline int dev_is_t5(struct c4iw_dev *dev) 78 { 79 return dev->chip_version == CHELSIO_T5; 80 } 81 82 static inline int dev_is_t4(struct c4iw_dev *dev) 83 { 84 return dev->chip_version == CHELSIO_T4; 85 } 86 87 struct c4iw_context { 88 struct ibv_context ibv_ctx; 89 struct t4_dev_status_page *status_page; 90 int status_page_size; 91 }; 92 93 struct c4iw_pd { 94 struct ibv_pd ibv_pd; 95 }; 96 97 struct c4iw_mr { 98 struct ibv_mr ibv_mr; 99 uint64_t va_fbo; 100 uint32_t len; 101 }; 102 103 static inline u32 c4iw_mmid(u32 stag) 104 { 105 return (stag >> 8); 106 } 107 108 struct c4iw_cq { 109 struct ibv_cq ibv_cq; 110 struct c4iw_dev *rhp; 111 struct t4_cq cq; 112 pthread_spinlock_t lock; 113 #ifdef STALL_DETECTION 114 struct timeval time; 115 int dumped; 116 #endif 117 }; 118 119 struct c4iw_qp { 120 struct ibv_qp ibv_qp; 121 struct c4iw_dev *rhp; 122 struct t4_wq wq; 123 pthread_spinlock_t lock; 124 int sq_sig_all; 125 }; 126 127 #define to_c4iw_xxx(xxx, type) \ 128 ((struct c4iw_##type *) \ 129 ((void *) ib##xxx - offsetof(struct c4iw_##type, ibv_##xxx))) 130 131 static inline struct c4iw_dev *to_c4iw_dev(struct ibv_device *ibdev) 132 { 133 return to_c4iw_xxx(dev, dev); 134 } 135 136 static inline struct c4iw_context *to_c4iw_context(struct ibv_context *ibctx) 137 { 138 return to_c4iw_xxx(ctx, context); 139 } 140 141 static inline struct c4iw_pd *to_c4iw_pd(struct ibv_pd *ibpd) 142 { 143 return to_c4iw_xxx(pd, pd); 144 } 145 146 static inline struct c4iw_cq *to_c4iw_cq(struct ibv_cq *ibcq) 147 { 148 return to_c4iw_xxx(cq, cq); 149 } 150 151 static inline struct c4iw_qp *to_c4iw_qp(struct ibv_qp *ibqp) 152 { 153 return to_c4iw_xxx(qp, qp); 154 } 155 156 static inline struct c4iw_mr *to_c4iw_mr(struct ibv_mr *ibmr) 157 { 158 return to_c4iw_xxx(mr, mr); 159 } 160 161 static inline struct c4iw_qp *get_qhp(struct c4iw_dev *rhp, u32 qid) 162 { 163 return rhp->qpid2ptr[qid]; 164 } 165 166 static inline struct c4iw_cq *get_chp(struct c4iw_dev *rhp, u32 qid) 167 { 168 return rhp->cqid2ptr[qid]; 169 } 170 171 static inline unsigned long_log2(unsigned long x) 172 { 173 unsigned r = 0; 174 for (x >>= 1; x > 0; x >>= 1) 175 r++; 176 return r; 177 } 178 179 int c4iw_query_device(struct ibv_context *context, 180 struct ibv_device_attr *attr); 181 int c4iw_query_port(struct ibv_context *context, uint8_t port, 182 struct ibv_port_attr *attr); 183 184 struct ibv_pd *c4iw_alloc_pd(struct ibv_context *context); 185 int c4iw_free_pd(struct ibv_pd *pd); 186 187 struct ibv_mr *c4iw_reg_mr(struct ibv_pd *pd, void *addr, 188 size_t length, int access); 189 int c4iw_dereg_mr(struct ibv_mr *mr); 190 191 struct ibv_cq *c4iw_create_cq(struct ibv_context *context, int cqe, 192 struct ibv_comp_channel *channel, 193 int comp_vector); 194 int c4iw_resize_cq(struct ibv_cq *cq, int cqe); 195 int c4iw_destroy_cq(struct ibv_cq *cq); 196 int c4iw_poll_cq(struct ibv_cq *cq, int ne, struct ibv_wc *wc); 197 int c4iw_arm_cq(struct ibv_cq *cq, int solicited); 198 void c4iw_cq_event(struct ibv_cq *cq); 199 void c4iw_init_cq_buf(struct c4iw_cq *cq, int nent); 200 201 struct ibv_srq *c4iw_create_srq(struct ibv_pd *pd, 202 struct ibv_srq_init_attr *attr); 203 int c4iw_modify_srq(struct ibv_srq *srq, 204 struct ibv_srq_attr *attr, 205 int mask); 206 int c4iw_destroy_srq(struct ibv_srq *srq); 207 int c4iw_post_srq_recv(struct ibv_srq *ibsrq, 208 struct ibv_recv_wr *wr, 209 struct ibv_recv_wr **bad_wr); 210 211 struct ibv_qp *c4iw_create_qp(struct ibv_pd *pd, 212 struct ibv_qp_init_attr *attr); 213 int c4iw_modify_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr, 214 int attr_mask); 215 int c4iw_destroy_qp(struct ibv_qp *qp); 216 int c4iw_query_qp(struct ibv_qp *qp, 217 struct ibv_qp_attr *attr, 218 int attr_mask, 219 struct ibv_qp_init_attr *init_attr); 220 void c4iw_flush_qp(struct c4iw_qp *qhp); 221 void c4iw_flush_qps(struct c4iw_dev *dev); 222 int c4iw_post_send(struct ibv_qp *ibqp, struct ibv_send_wr *wr, 223 struct ibv_send_wr **bad_wr); 224 int c4iw_post_receive(struct ibv_qp *ibqp, struct ibv_recv_wr *wr, 225 struct ibv_recv_wr **bad_wr); 226 struct ibv_ah *c4iw_create_ah(struct ibv_pd *pd, 227 struct ibv_ah_attr *ah_attr); 228 int c4iw_destroy_ah(struct ibv_ah *ah); 229 int c4iw_attach_mcast(struct ibv_qp *qp, const union ibv_gid *gid, 230 uint16_t lid); 231 int c4iw_detach_mcast(struct ibv_qp *qp, const union ibv_gid *gid, 232 uint16_t lid); 233 void c4iw_async_event(struct ibv_async_event *event); 234 void c4iw_flush_hw_cq(struct c4iw_cq *chp); 235 int c4iw_flush_rq(struct t4_wq *wq, struct t4_cq *cq, int count); 236 void c4iw_flush_sq(struct c4iw_qp *qhp); 237 void c4iw_count_rcqes(struct t4_cq *cq, struct t4_wq *wq, int *count); 238 239 #define FW_MAJ 0 240 #define FW_MIN 0 241 242 static inline unsigned long align(unsigned long val, unsigned long align) 243 { 244 return (val + align - 1) & ~(align - 1); 245 } 246 247 #ifdef STATS 248 249 #define INC_STAT(a) { c4iw_stats.a++; } 250 251 struct c4iw_stats { 252 unsigned long send; 253 unsigned long recv; 254 unsigned long read; 255 unsigned long write; 256 unsigned long arm; 257 unsigned long cqe; 258 unsigned long mr; 259 unsigned long qp; 260 unsigned long cq; 261 }; 262 extern struct c4iw_stats c4iw_stats; 263 #else 264 #define INC_STAT(a) 265 #endif 266 267 #ifdef STALL_DETECTION 268 void dump_state(void); 269 extern int stall_to; 270 #endif 271 272 #endif /* IWCH_H */ 273