/* * 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 #include #include #include #include #include #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__ */