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