| /* |
| * Copyright (c) 2006-2016 Chelsio, Inc. All rights reserved. |
| * |
| * This software is available to you under a choice of one of two |
| * licenses. You may choose to be licensed under the terms of the GNU |
| * General Public License (GPL) Version 2, available from the file |
| * COPYING in the main directory of this source tree, or the |
| * OpenIB.org BSD license below: |
| * |
| * Redistribution and use in source and binary forms, with or |
| * without modification, are permitted provided that the following |
| * conditions are met: |
| * |
| * - Redistributions of source code must retain the above |
| * copyright notice, this list of conditions and the following |
| * disclaimer. |
| * |
| * - Redistributions in binary form must reproduce the above |
| * copyright notice, this list of conditions and the following |
| * disclaimer in the documentation and/or other materials |
| * provided with the distribution. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
| * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
| * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
| * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS |
| * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN |
| * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
| * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
| * SOFTWARE. |
| */ |
| #ifndef IWCH_H |
| #define IWCH_H |
| |
| #include <pthread.h> |
| #include <inttypes.h> |
| #include <stddef.h> |
| #include <string.h> |
| #include <syslog.h> |
| #include <sys/errno.h> |
| #include <sys/time.h> |
| #include <infiniband/driver.h> |
| #include <util/udma_barrier.h> |
| #include <ccan/list.h> |
| #include "t4.h" |
| |
| extern unsigned long c4iw_page_size; |
| extern unsigned long c4iw_page_shift; |
| extern unsigned long c4iw_page_mask; |
| |
| struct c4iw_mr; |
| |
| struct c4iw_dev { |
| struct verbs_device ibv_dev; |
| unsigned chip_version; |
| int max_mr; |
| struct c4iw_mr **mmid2ptr; |
| int max_qp; |
| struct c4iw_qp **qpid2ptr; |
| int max_cq; |
| struct c4iw_cq **cqid2ptr; |
| struct list_head srq_list; |
| pthread_spinlock_t lock; |
| struct list_node list; |
| int abi_version; |
| bool write_cmpl_supported; |
| }; |
| |
| static inline int dev_is_t6(struct c4iw_dev *dev) |
| { |
| return dev->chip_version == CHELSIO_T6; |
| } |
| |
| static inline int dev_is_t5(struct c4iw_dev *dev) |
| { |
| return dev->chip_version == CHELSIO_T5; |
| } |
| |
| static inline int dev_is_t4(struct c4iw_dev *dev) |
| { |
| return dev->chip_version == CHELSIO_T4; |
| } |
| |
| struct c4iw_context { |
| struct verbs_context ibv_ctx; |
| struct t4_dev_status_page *status_page; |
| int status_page_size; |
| }; |
| |
| struct c4iw_pd { |
| struct ibv_pd ibv_pd; |
| }; |
| |
| struct c4iw_mr { |
| struct verbs_mr vmr; |
| uint64_t va_fbo; |
| uint32_t len; |
| }; |
| |
| static inline u32 c4iw_mmid(u32 stag) |
| { |
| return (stag >> 8); |
| } |
| |
| struct c4iw_cq { |
| struct ibv_cq ibv_cq; |
| struct c4iw_dev *rhp; |
| struct t4_cq cq; |
| pthread_spinlock_t lock; |
| #ifdef STALL_DETECTION |
| struct timeval time; |
| int dumped; |
| #endif |
| }; |
| |
| struct c4iw_qp { |
| struct ibv_qp ibv_qp; |
| struct c4iw_dev *rhp; |
| struct t4_wq wq; |
| pthread_spinlock_t lock; |
| int sq_sig_all; |
| struct c4iw_srq *srq; |
| }; |
| |
| #define to_c4iw_xxx(xxx, type) \ |
| container_of(ib##xxx, struct c4iw_##type, ibv_##xxx) |
| |
| struct c4iw_srq { |
| struct ibv_srq ibv_srq; |
| int type; /* must be 2nd in this struct */ |
| struct c4iw_dev *rhp; |
| struct t4_srq wq; |
| struct list_node list; |
| pthread_spinlock_t lock; |
| uint32_t srq_limit; |
| int armed; |
| __u32 flags; |
| }; |
| |
| static inline struct c4iw_srq *to_c4iw_srq(struct ibv_srq *ibsrq) |
| { |
| return to_c4iw_xxx(srq, srq); |
| } |
| |
| static inline struct c4iw_dev *to_c4iw_dev(struct ibv_device *ibdev) |
| { |
| return container_of(ibdev, struct c4iw_dev, ibv_dev.device); |
| } |
| |
| static inline struct c4iw_context *to_c4iw_context(struct ibv_context *ibctx) |
| { |
| return container_of(ibctx, struct c4iw_context, ibv_ctx.context); |
| } |
| |
| static inline struct c4iw_pd *to_c4iw_pd(struct ibv_pd *ibpd) |
| { |
| return to_c4iw_xxx(pd, pd); |
| } |
| |
| static inline struct c4iw_cq *to_c4iw_cq(struct ibv_cq *ibcq) |
| { |
| return to_c4iw_xxx(cq, cq); |
| } |
| |
| static inline struct c4iw_qp *to_c4iw_qp(struct ibv_qp *ibqp) |
| { |
| return to_c4iw_xxx(qp, qp); |
| } |
| |
| static inline struct c4iw_mr *to_c4iw_mr(struct verbs_mr *vmr) |
| { |
| return container_of(vmr, struct c4iw_mr, vmr); |
| } |
| |
| static inline struct c4iw_qp *get_qhp(struct c4iw_dev *rhp, u32 qid) |
| { |
| return rhp->qpid2ptr[qid]; |
| } |
| |
| static inline struct c4iw_cq *get_chp(struct c4iw_dev *rhp, u32 qid) |
| { |
| return rhp->cqid2ptr[qid]; |
| } |
| |
| static inline unsigned long_log2(unsigned long x) |
| { |
| unsigned r = 0; |
| for (x >>= 1; x > 0; x >>= 1) |
| r++; |
| return r; |
| } |
| |
| int c4iw_query_device(struct ibv_context *context, |
| const struct ibv_query_device_ex_input *input, |
| struct ibv_device_attr_ex *attr, size_t attr_size); |
| int c4iw_query_port(struct ibv_context *context, uint8_t port, |
| struct ibv_port_attr *attr); |
| |
| struct ibv_pd *c4iw_alloc_pd(struct ibv_context *context); |
| int c4iw_free_pd(struct ibv_pd *pd); |
| |
| struct ibv_mr *c4iw_reg_mr(struct ibv_pd *pd, void *addr, size_t length, |
| uint64_t hca_va, int access); |
| int c4iw_dereg_mr(struct verbs_mr *vmr); |
| |
| struct ibv_cq *c4iw_create_cq(struct ibv_context *context, int cqe, |
| struct ibv_comp_channel *channel, |
| int comp_vector); |
| int c4iw_destroy_cq(struct ibv_cq *cq); |
| int c4iw_poll_cq(struct ibv_cq *cq, int ne, struct ibv_wc *wc); |
| int c4iw_arm_cq(struct ibv_cq *cq, int solicited); |
| void c4iw_cq_event(struct ibv_cq *cq); |
| void c4iw_init_cq_buf(struct c4iw_cq *cq, int nent); |
| |
| struct ibv_srq *c4iw_create_srq(struct ibv_pd *pd, |
| struct ibv_srq_init_attr *attr); |
| int c4iw_modify_srq(struct ibv_srq *srq, |
| struct ibv_srq_attr *attr, |
| int mask); |
| int c4iw_destroy_srq(struct ibv_srq *srq); |
| int c4iw_post_srq_recv(struct ibv_srq *ibsrq, |
| struct ibv_recv_wr *wr, |
| struct ibv_recv_wr **bad_wr); |
| int c4iw_query_srq(struct ibv_srq *ibsrq, struct ibv_srq_attr *attr); |
| |
| struct ibv_qp *c4iw_create_qp(struct ibv_pd *pd, |
| struct ibv_qp_init_attr *attr); |
| int c4iw_modify_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr, |
| int attr_mask); |
| int c4iw_destroy_qp(struct ibv_qp *qp); |
| int c4iw_query_qp(struct ibv_qp *qp, |
| struct ibv_qp_attr *attr, |
| int attr_mask, |
| struct ibv_qp_init_attr *init_attr); |
| void c4iw_flush_qp(struct c4iw_qp *qhp); |
| void c4iw_flush_qps(struct c4iw_dev *dev); |
| int c4iw_post_send(struct ibv_qp *ibqp, struct ibv_send_wr *wr, |
| struct ibv_send_wr **bad_wr); |
| int c4iw_post_receive(struct ibv_qp *ibqp, struct ibv_recv_wr *wr, |
| struct ibv_recv_wr **bad_wr); |
| int c4iw_attach_mcast(struct ibv_qp *qp, const union ibv_gid *gid, |
| uint16_t lid); |
| int c4iw_detach_mcast(struct ibv_qp *qp, const union ibv_gid *gid, |
| uint16_t lid); |
| void c4iw_async_event(struct ibv_context *context, |
| struct ibv_async_event *event); |
| void c4iw_flush_hw_cq(struct c4iw_cq *chp, struct c4iw_qp *flush_qhp); |
| int c4iw_flush_rq(struct t4_wq *wq, struct t4_cq *cq, int count); |
| void c4iw_flush_sq(struct c4iw_qp *qhp); |
| void c4iw_count_rcqes(struct t4_cq *cq, struct t4_wq *wq, int *count); |
| void c4iw_copy_wr_to_srq(struct t4_srq *srq, union t4_recv_wr *wqe, u8 len16); |
| void c4iw_flush_srqidx(struct c4iw_qp *qhp, u32 srqidx); |
| |
| #define FW_MAJ 0 |
| #define FW_MIN 0 |
| |
| #ifdef STATS |
| |
| #define INC_STAT(a) { c4iw_stats.a++; } |
| |
| struct c4iw_stats { |
| unsigned long send; |
| unsigned long recv; |
| unsigned long read; |
| unsigned long write; |
| unsigned long arm; |
| unsigned long cqe; |
| unsigned long mr; |
| unsigned long qp; |
| unsigned long cq; |
| }; |
| extern struct c4iw_stats c4iw_stats; |
| #else |
| #define INC_STAT(a) |
| #endif |
| |
| #ifdef STALL_DETECTION |
| void dump_state(void); |
| extern int stall_to; |
| #endif |
| |
| #endif /* IWCH_H */ |