| /* | |
| * Copyright (C) 2008-2013 Emulex. 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 | |
| * 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. | |
| * | |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
| * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
| * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE | |
| * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
| * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
| * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
| * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
| * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
| * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF | |
| * THE POSSIBILITY OF SUCH DAMAGE. | |
| */ | |
| #ifndef __OCRDMA_MAIN_H__ | |
| #define __OCRDMA_MAIN_H__ | |
| #include <inttypes.h> | |
| #include <stddef.h> | |
| #include <endian.h> | |
| #include <infiniband/driver.h> | |
| #include <util/udma_barrier.h> | |
| #include <ccan/list.h> | |
| #define ocrdma_err(format, arg...) printf(format, ##arg) | |
| #define OCRDMA_DPP_PAGE_SIZE (4096) | |
| #define ROUND_UP_X(_val, _x) \ | |
| (((unsigned long)(_val) + ((_x)-1)) & (long)~((_x)-1)) | |
| struct ocrdma_qp; | |
| struct ocrdma_device { | |
| struct verbs_device ibv_dev; | |
| struct ocrdma_qp **qp_tbl; | |
| pthread_mutex_t dev_lock; | |
| pthread_spinlock_t flush_q_lock; | |
| int id; | |
| int gen; | |
| uint32_t wqe_size; | |
| uint32_t rqe_size; | |
| uint32_t dpp_wqe_size; | |
| uint32_t max_inline_data; | |
| uint8_t fw_ver[32]; | |
| }; | |
| struct ocrdma_devctx { | |
| struct verbs_context ibv_ctx; | |
| uint32_t *ah_tbl; | |
| uint32_t ah_tbl_len; | |
| pthread_mutex_t tbl_lock; | |
| }; | |
| struct ocrdma_pd { | |
| struct ibv_pd ibv_pd; | |
| struct ocrdma_device *dev; | |
| struct ocrdma_devctx *uctx; | |
| void *dpp_va; | |
| }; | |
| struct ocrdma_mr { | |
| struct verbs_mr vmr; | |
| }; | |
| struct ocrdma_cq { | |
| struct ibv_cq ibv_cq; | |
| struct ocrdma_device *dev; | |
| uint16_t cq_id; | |
| uint16_t cq_dbid; | |
| uint16_t getp; | |
| pthread_spinlock_t cq_lock; | |
| uint32_t max_hw_cqe; | |
| uint32_t cq_mem_size; | |
| struct ocrdma_cqe *va; | |
| void *db_va; | |
| uint32_t db_size; | |
| uint32_t phase; | |
| int phase_change; | |
| uint8_t deferred_arm; | |
| uint8_t deferred_sol; | |
| uint8_t first_arm; | |
| struct list_head sq_head; | |
| struct list_head rq_head; | |
| }; | |
| enum { | |
| OCRDMA_DPP_WQE_INDEX_MASK = 0xFFFF, | |
| OCRDMA_DPP_CQE_VALID_BIT_SHIFT = 31, | |
| OCRDMA_DPP_CQE_VALID_BIT_MASK = 1 << 31 | |
| }; | |
| struct ocrdma_dpp_cqe { | |
| uint32_t wqe_idx_valid; | |
| }; | |
| enum { | |
| OCRDMA_PD_MAX_DPP_ENABLED_QP = 16 | |
| }; | |
| struct ocrdma_qp_hwq_info { | |
| uint8_t *va; /* virtual address */ | |
| uint32_t max_sges; | |
| uint32_t free_cnt; | |
| uint32_t head, tail; | |
| uint32_t entry_size; | |
| uint32_t max_cnt; | |
| uint32_t max_wqe_idx; | |
| uint32_t len; | |
| uint16_t dbid; /* qid, where to ring the doorbell. */ | |
| }; | |
| struct ocrdma_srq { | |
| struct ibv_srq ibv_srq; | |
| struct ocrdma_device *dev; | |
| void *db_va; | |
| uint32_t db_size; | |
| pthread_spinlock_t q_lock; | |
| struct ocrdma_qp_hwq_info rq; | |
| uint32_t max_rq_sges; | |
| uint32_t id; | |
| uint64_t *rqe_wr_id_tbl; | |
| uint32_t *idx_bit_fields; | |
| uint32_t bit_fields_len; | |
| uint32_t db_shift; | |
| }; | |
| enum { | |
| OCRDMA_CREATE_QP_REQ_DPP_CREDIT_LIMIT = 1 | |
| }; | |
| enum ocrdma_qp_state { | |
| OCRDMA_QPS_RST = 0, | |
| OCRDMA_QPS_INIT = 1, | |
| OCRDMA_QPS_RTR = 2, | |
| OCRDMA_QPS_RTS = 3, | |
| OCRDMA_QPS_SQE = 4, | |
| OCRDMA_QPS_SQ_DRAINING = 5, | |
| OCRDMA_QPS_ERR = 6, | |
| OCRDMA_QPS_SQD = 7 | |
| }; | |
| struct ocrdma_qp { | |
| struct ibv_qp ibv_qp; | |
| struct ocrdma_device *dev; | |
| pthread_spinlock_t q_lock; | |
| struct ocrdma_qp_hwq_info sq; | |
| struct ocrdma_cq *sq_cq; | |
| struct { | |
| uint64_t wrid; | |
| uint16_t dpp_wqe_idx; | |
| uint16_t dpp_wqe; | |
| uint8_t signaled; | |
| uint8_t rsvd[3]; | |
| } *wqe_wr_id_tbl; | |
| struct ocrdma_qp_hwq_info dpp_q; | |
| int dpp_enabled; | |
| struct ocrdma_qp_hwq_info rq; | |
| struct ocrdma_cq *rq_cq; | |
| uint64_t *rqe_wr_id_tbl; | |
| void *db_va; | |
| void *db_sq_va; | |
| void *db_rq_va; | |
| uint32_t max_inline_data; | |
| struct ocrdma_srq *srq; | |
| struct ocrdma_cq *dpp_cq; | |
| uint32_t db_size; | |
| uint32_t max_ord; | |
| uint32_t max_ird; | |
| uint32_t dpp_prev_indx; | |
| enum ibv_qp_type qp_type; | |
| enum ocrdma_qp_state state; | |
| struct list_node sq_entry; | |
| struct list_node rq_entry; | |
| uint16_t id; | |
| uint16_t rsvd; | |
| uint32_t db_shift; | |
| int signaled; /* signaled QP */ | |
| }; | |
| enum { | |
| OCRDMA_AH_ID_MASK = 0x3FF, | |
| OCRDMA_AH_VLAN_VALID_MASK = 0x01, | |
| OCRDMA_AH_VLAN_VALID_SHIFT = 0x1F, | |
| OCRDMA_AH_L3_TYPE_MASK = 0x03, | |
| OCRDMA_AH_L3_TYPE_SHIFT = 0x1D | |
| }; | |
| struct ocrdma_ah { | |
| struct ibv_ah ibv_ah; | |
| struct ocrdma_pd *pd; | |
| uint16_t id; | |
| uint8_t isvlan; | |
| uint8_t hdr_type; | |
| }; | |
| #define get_ocrdma_xxx(xxx, type) \ | |
| container_of(ib##xxx, struct ocrdma_##type, ibv_##xxx) | |
| static inline struct ocrdma_devctx *get_ocrdma_ctx(struct ibv_context *ibctx) | |
| { | |
| return container_of(ibctx, struct ocrdma_devctx, ibv_ctx.context); | |
| } | |
| static inline struct ocrdma_device *get_ocrdma_dev(struct ibv_device *ibdev) | |
| { | |
| return container_of(ibdev, struct ocrdma_device, ibv_dev.device); | |
| } | |
| static inline struct ocrdma_qp *get_ocrdma_qp(struct ibv_qp *ibqp) | |
| { | |
| return get_ocrdma_xxx(qp, qp); | |
| } | |
| static inline struct ocrdma_srq *get_ocrdma_srq(struct ibv_srq *ibsrq) | |
| { | |
| return get_ocrdma_xxx(srq, srq); | |
| } | |
| static inline struct ocrdma_pd *get_ocrdma_pd(struct ibv_pd *ibpd) | |
| { | |
| return get_ocrdma_xxx(pd, pd); | |
| } | |
| static inline struct ocrdma_cq *get_ocrdma_cq(struct ibv_cq *ibcq) | |
| { | |
| return get_ocrdma_xxx(cq, cq); | |
| } | |
| static inline struct ocrdma_ah *get_ocrdma_ah(struct ibv_ah *ibah) | |
| { | |
| return get_ocrdma_xxx(ah, ah); | |
| } | |
| void ocrdma_init_ahid_tbl(struct ocrdma_devctx *ctx); | |
| int ocrdma_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 ocrdma_query_port(struct ibv_context *, uint8_t, struct ibv_port_attr *); | |
| struct ibv_pd *ocrdma_alloc_pd(struct ibv_context *); | |
| int ocrdma_free_pd(struct ibv_pd *); | |
| struct ibv_mr *ocrdma_reg_mr(struct ibv_pd *pd, void *addr, size_t len, | |
| uint64_t hca_va, int access); | |
| int ocrdma_dereg_mr(struct verbs_mr *vmr); | |
| struct ibv_cq *ocrdma_create_cq(struct ibv_context *, int, | |
| struct ibv_comp_channel *, int); | |
| int ocrdma_resize_cq(struct ibv_cq *, int); | |
| int ocrdma_destroy_cq(struct ibv_cq *); | |
| int ocrdma_poll_cq(struct ibv_cq *, int, struct ibv_wc *); | |
| int ocrdma_arm_cq(struct ibv_cq *, int); | |
| struct ibv_qp *ocrdma_create_qp(struct ibv_pd *, struct ibv_qp_init_attr *); | |
| int ocrdma_modify_qp(struct ibv_qp *, struct ibv_qp_attr *, | |
| int ibv_qp_attr_mask); | |
| int ocrdma_query_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr, int attr_mask, | |
| struct ibv_qp_init_attr *init_attr); | |
| int ocrdma_destroy_qp(struct ibv_qp *); | |
| int ocrdma_post_send(struct ibv_qp *, struct ibv_send_wr *, | |
| struct ibv_send_wr **); | |
| int ocrdma_post_recv(struct ibv_qp *, struct ibv_recv_wr *, | |
| struct ibv_recv_wr **); | |
| struct ibv_srq *ocrdma_create_srq(struct ibv_pd *, struct ibv_srq_init_attr *); | |
| int ocrdma_modify_srq(struct ibv_srq *, struct ibv_srq_attr *, int); | |
| int ocrdma_destroy_srq(struct ibv_srq *); | |
| int ocrdma_query_srq(struct ibv_srq *ibsrq, struct ibv_srq_attr *attr); | |
| int ocrdma_post_srq_recv(struct ibv_srq *, struct ibv_recv_wr *, | |
| struct ibv_recv_wr **); | |
| struct ibv_ah *ocrdma_create_ah(struct ibv_pd *, struct ibv_ah_attr *); | |
| int ocrdma_destroy_ah(struct ibv_ah *); | |
| int ocrdma_attach_mcast(struct ibv_qp *, const union ibv_gid *, uint16_t); | |
| int ocrdma_detach_mcast(struct ibv_qp *, const union ibv_gid *, uint16_t); | |
| void ocrdma_async_event(struct ibv_async_event *event); | |
| #endif /* __OCRDMA_MAIN_H__ */ |