162306a36Sopenharmony_ci/* QLogic qedr NIC Driver 262306a36Sopenharmony_ci * Copyright (c) 2015-2016 QLogic Corporation 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * This software is available to you under a choice of one of two 562306a36Sopenharmony_ci * licenses. You may choose to be licensed under the terms of the GNU 662306a36Sopenharmony_ci * General Public License (GPL) Version 2, available from the file 762306a36Sopenharmony_ci * COPYING in the main directory of this source tree, or the 862306a36Sopenharmony_ci * OpenIB.org BSD license below: 962306a36Sopenharmony_ci * 1062306a36Sopenharmony_ci * Redistribution and use in source and binary forms, with or 1162306a36Sopenharmony_ci * without modification, are permitted provided that the following 1262306a36Sopenharmony_ci * conditions are met: 1362306a36Sopenharmony_ci * 1462306a36Sopenharmony_ci * - Redistributions of source code must retain the above 1562306a36Sopenharmony_ci * copyright notice, this list of conditions and the following 1662306a36Sopenharmony_ci * disclaimer. 1762306a36Sopenharmony_ci * 1862306a36Sopenharmony_ci * - Redistributions in binary form must reproduce the above 1962306a36Sopenharmony_ci * copyright notice, this list of conditions and the following 2062306a36Sopenharmony_ci * disclaimer in the documentation and /or other materials 2162306a36Sopenharmony_ci * provided with the distribution. 2262306a36Sopenharmony_ci * 2362306a36Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 2462306a36Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 2562306a36Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 2662306a36Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 2762306a36Sopenharmony_ci * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 2862306a36Sopenharmony_ci * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 2962306a36Sopenharmony_ci * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 3062306a36Sopenharmony_ci * SOFTWARE. 3162306a36Sopenharmony_ci */ 3262306a36Sopenharmony_ci#ifndef __QEDR_H__ 3362306a36Sopenharmony_ci#define __QEDR_H__ 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci#include <linux/pci.h> 3662306a36Sopenharmony_ci#include <linux/xarray.h> 3762306a36Sopenharmony_ci#include <rdma/ib_addr.h> 3862306a36Sopenharmony_ci#include <linux/qed/qed_if.h> 3962306a36Sopenharmony_ci#include <linux/qed/qed_chain.h> 4062306a36Sopenharmony_ci#include <linux/qed/qed_rdma_if.h> 4162306a36Sopenharmony_ci#include <linux/qed/qede_rdma.h> 4262306a36Sopenharmony_ci#include <linux/qed/roce_common.h> 4362306a36Sopenharmony_ci#include <linux/completion.h> 4462306a36Sopenharmony_ci#include "qedr_hsi_rdma.h" 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci#define QEDR_NODE_DESC "QLogic 579xx RoCE HCA" 4762306a36Sopenharmony_ci#define DP_NAME(_dev) dev_name(&(_dev)->ibdev.dev) 4862306a36Sopenharmony_ci#define IS_IWARP(_dev) ((_dev)->rdma_type == QED_RDMA_TYPE_IWARP) 4962306a36Sopenharmony_ci#define IS_ROCE(_dev) ((_dev)->rdma_type == QED_RDMA_TYPE_ROCE) 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci#define DP_DEBUG(dev, module, fmt, ...) \ 5262306a36Sopenharmony_ci pr_debug("(%s) " module ": " fmt, \ 5362306a36Sopenharmony_ci DP_NAME(dev) ? DP_NAME(dev) : "", ## __VA_ARGS__) 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci#define QEDR_MSG_INIT "INIT" 5662306a36Sopenharmony_ci#define QEDR_MSG_MISC "MISC" 5762306a36Sopenharmony_ci#define QEDR_MSG_CQ " CQ" 5862306a36Sopenharmony_ci#define QEDR_MSG_MR " MR" 5962306a36Sopenharmony_ci#define QEDR_MSG_RQ " RQ" 6062306a36Sopenharmony_ci#define QEDR_MSG_SQ " SQ" 6162306a36Sopenharmony_ci#define QEDR_MSG_QP " QP" 6262306a36Sopenharmony_ci#define QEDR_MSG_SRQ " SRQ" 6362306a36Sopenharmony_ci#define QEDR_MSG_GSI " GSI" 6462306a36Sopenharmony_ci#define QEDR_MSG_IWARP " IW" 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci#define QEDR_CQ_MAGIC_NUMBER (0x11223344) 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ci#define FW_PAGE_SIZE (RDMA_RING_PAGE_SIZE) 6962306a36Sopenharmony_ci#define FW_PAGE_SHIFT (12) 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_cistruct qedr_dev; 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_cistruct qedr_cnq { 7462306a36Sopenharmony_ci struct qedr_dev *dev; 7562306a36Sopenharmony_ci struct qed_chain pbl; 7662306a36Sopenharmony_ci struct qed_sb_info *sb; 7762306a36Sopenharmony_ci char name[32]; 7862306a36Sopenharmony_ci u64 n_comp; 7962306a36Sopenharmony_ci __le16 *hw_cons_ptr; 8062306a36Sopenharmony_ci u8 index; 8162306a36Sopenharmony_ci}; 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci#define QEDR_MAX_SGID 128 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_cistruct qedr_device_attr { 8662306a36Sopenharmony_ci u32 vendor_id; 8762306a36Sopenharmony_ci u32 vendor_part_id; 8862306a36Sopenharmony_ci u32 hw_ver; 8962306a36Sopenharmony_ci u64 fw_ver; 9062306a36Sopenharmony_ci u64 node_guid; 9162306a36Sopenharmony_ci u64 sys_image_guid; 9262306a36Sopenharmony_ci u8 max_cnq; 9362306a36Sopenharmony_ci u8 max_sge; 9462306a36Sopenharmony_ci u16 max_inline; 9562306a36Sopenharmony_ci u32 max_sqe; 9662306a36Sopenharmony_ci u32 max_rqe; 9762306a36Sopenharmony_ci u8 max_qp_resp_rd_atomic_resc; 9862306a36Sopenharmony_ci u8 max_qp_req_rd_atomic_resc; 9962306a36Sopenharmony_ci u64 max_dev_resp_rd_atomic_resc; 10062306a36Sopenharmony_ci u32 max_cq; 10162306a36Sopenharmony_ci u32 max_qp; 10262306a36Sopenharmony_ci u32 max_mr; 10362306a36Sopenharmony_ci u64 max_mr_size; 10462306a36Sopenharmony_ci u32 max_cqe; 10562306a36Sopenharmony_ci u32 max_mw; 10662306a36Sopenharmony_ci u32 max_mr_mw_fmr_pbl; 10762306a36Sopenharmony_ci u64 max_mr_mw_fmr_size; 10862306a36Sopenharmony_ci u32 max_pd; 10962306a36Sopenharmony_ci u32 max_ah; 11062306a36Sopenharmony_ci u8 max_pkey; 11162306a36Sopenharmony_ci u32 max_srq; 11262306a36Sopenharmony_ci u32 max_srq_wr; 11362306a36Sopenharmony_ci u8 max_srq_sge; 11462306a36Sopenharmony_ci u8 max_stats_queues; 11562306a36Sopenharmony_ci u32 dev_caps; 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_ci u64 page_size_caps; 11862306a36Sopenharmony_ci u8 dev_ack_delay; 11962306a36Sopenharmony_ci u32 reserved_lkey; 12062306a36Sopenharmony_ci u32 bad_pkey_counter; 12162306a36Sopenharmony_ci struct qed_rdma_events events; 12262306a36Sopenharmony_ci}; 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_ci#define QEDR_ENET_STATE_BIT (0) 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_cistruct qedr_dev { 12762306a36Sopenharmony_ci struct ib_device ibdev; 12862306a36Sopenharmony_ci struct qed_dev *cdev; 12962306a36Sopenharmony_ci struct pci_dev *pdev; 13062306a36Sopenharmony_ci struct net_device *ndev; 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_ci enum ib_atomic_cap atomic_cap; 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_ci void *rdma_ctx; 13562306a36Sopenharmony_ci struct qedr_device_attr attr; 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_ci const struct qed_rdma_ops *ops; 13862306a36Sopenharmony_ci struct qed_int_info int_info; 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_ci struct qed_sb_info *sb_array; 14162306a36Sopenharmony_ci struct qedr_cnq *cnq_array; 14262306a36Sopenharmony_ci int num_cnq; 14362306a36Sopenharmony_ci int sb_start; 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_ci void __iomem *db_addr; 14662306a36Sopenharmony_ci u64 db_phys_addr; 14762306a36Sopenharmony_ci u32 db_size; 14862306a36Sopenharmony_ci u16 dpi; 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_ci union ib_gid *sgid_tbl; 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_ci /* Lock for sgid table */ 15362306a36Sopenharmony_ci spinlock_t sgid_lock; 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_ci u64 guid; 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_ci u32 dp_module; 15862306a36Sopenharmony_ci u8 dp_level; 15962306a36Sopenharmony_ci u8 num_hwfns; 16062306a36Sopenharmony_ci#define QEDR_IS_CMT(dev) ((dev)->num_hwfns > 1) 16162306a36Sopenharmony_ci u8 affin_hwfn_idx; 16262306a36Sopenharmony_ci u8 gsi_ll2_handle; 16362306a36Sopenharmony_ci 16462306a36Sopenharmony_ci uint wq_multiplier; 16562306a36Sopenharmony_ci u8 gsi_ll2_mac_address[ETH_ALEN]; 16662306a36Sopenharmony_ci int gsi_qp_created; 16762306a36Sopenharmony_ci struct qedr_cq *gsi_sqcq; 16862306a36Sopenharmony_ci struct qedr_cq *gsi_rqcq; 16962306a36Sopenharmony_ci struct qedr_qp *gsi_qp; 17062306a36Sopenharmony_ci enum qed_rdma_type rdma_type; 17162306a36Sopenharmony_ci struct xarray qps; 17262306a36Sopenharmony_ci struct xarray srqs; 17362306a36Sopenharmony_ci struct workqueue_struct *iwarp_wq; 17462306a36Sopenharmony_ci u16 iwarp_max_mtu; 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_ci unsigned long enet_state; 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_ci u8 user_dpm_enabled; 17962306a36Sopenharmony_ci}; 18062306a36Sopenharmony_ci 18162306a36Sopenharmony_ci#define QEDR_MAX_SQ_PBL (0x8000) 18262306a36Sopenharmony_ci#define QEDR_MAX_SQ_PBL_ENTRIES (0x10000 / sizeof(void *)) 18362306a36Sopenharmony_ci#define QEDR_SQE_ELEMENT_SIZE (sizeof(struct rdma_sq_sge)) 18462306a36Sopenharmony_ci#define QEDR_MAX_SQE_ELEMENTS_PER_SQE (ROCE_REQ_MAX_SINGLE_SQ_WQE_SIZE / \ 18562306a36Sopenharmony_ci QEDR_SQE_ELEMENT_SIZE) 18662306a36Sopenharmony_ci#define QEDR_MAX_SQE_ELEMENTS_PER_PAGE ((RDMA_RING_PAGE_SIZE) / \ 18762306a36Sopenharmony_ci QEDR_SQE_ELEMENT_SIZE) 18862306a36Sopenharmony_ci#define QEDR_MAX_SQE ((QEDR_MAX_SQ_PBL_ENTRIES) *\ 18962306a36Sopenharmony_ci (RDMA_RING_PAGE_SIZE) / \ 19062306a36Sopenharmony_ci (QEDR_SQE_ELEMENT_SIZE) /\ 19162306a36Sopenharmony_ci (QEDR_MAX_SQE_ELEMENTS_PER_SQE)) 19262306a36Sopenharmony_ci/* RQ */ 19362306a36Sopenharmony_ci#define QEDR_MAX_RQ_PBL (0x2000) 19462306a36Sopenharmony_ci#define QEDR_MAX_RQ_PBL_ENTRIES (0x10000 / sizeof(void *)) 19562306a36Sopenharmony_ci#define QEDR_RQE_ELEMENT_SIZE (sizeof(struct rdma_rq_sge)) 19662306a36Sopenharmony_ci#define QEDR_MAX_RQE_ELEMENTS_PER_RQE (RDMA_MAX_SGE_PER_RQ_WQE) 19762306a36Sopenharmony_ci#define QEDR_MAX_RQE_ELEMENTS_PER_PAGE ((RDMA_RING_PAGE_SIZE) / \ 19862306a36Sopenharmony_ci QEDR_RQE_ELEMENT_SIZE) 19962306a36Sopenharmony_ci#define QEDR_MAX_RQE ((QEDR_MAX_RQ_PBL_ENTRIES) *\ 20062306a36Sopenharmony_ci (RDMA_RING_PAGE_SIZE) / \ 20162306a36Sopenharmony_ci (QEDR_RQE_ELEMENT_SIZE) /\ 20262306a36Sopenharmony_ci (QEDR_MAX_RQE_ELEMENTS_PER_RQE)) 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_ci#define QEDR_CQE_SIZE (sizeof(union rdma_cqe)) 20562306a36Sopenharmony_ci#define QEDR_MAX_CQE_PBL_SIZE (512 * 1024) 20662306a36Sopenharmony_ci#define QEDR_MAX_CQE_PBL_ENTRIES (((QEDR_MAX_CQE_PBL_SIZE) / \ 20762306a36Sopenharmony_ci sizeof(u64)) - 1) 20862306a36Sopenharmony_ci#define QEDR_MAX_CQES ((u32)((QEDR_MAX_CQE_PBL_ENTRIES) * \ 20962306a36Sopenharmony_ci (QED_CHAIN_PAGE_SIZE) / QEDR_CQE_SIZE)) 21062306a36Sopenharmony_ci 21162306a36Sopenharmony_ci#define QEDR_ROCE_MAX_CNQ_SIZE (0x4000) 21262306a36Sopenharmony_ci 21362306a36Sopenharmony_ci#define QEDR_MAX_PORT (1) 21462306a36Sopenharmony_ci#define QEDR_PORT (1) 21562306a36Sopenharmony_ci 21662306a36Sopenharmony_ci#define QEDR_UVERBS(CMD_NAME) (1ull << IB_USER_VERBS_CMD_##CMD_NAME) 21762306a36Sopenharmony_ci 21862306a36Sopenharmony_ci#define QEDR_ROCE_PKEY_MAX 1 21962306a36Sopenharmony_ci#define QEDR_ROCE_PKEY_TABLE_LEN 1 22062306a36Sopenharmony_ci#define QEDR_ROCE_PKEY_DEFAULT 0xffff 22162306a36Sopenharmony_ci 22262306a36Sopenharmony_cistruct qedr_pbl { 22362306a36Sopenharmony_ci struct list_head list_entry; 22462306a36Sopenharmony_ci void *va; 22562306a36Sopenharmony_ci dma_addr_t pa; 22662306a36Sopenharmony_ci}; 22762306a36Sopenharmony_ci 22862306a36Sopenharmony_cistruct qedr_ucontext { 22962306a36Sopenharmony_ci struct ib_ucontext ibucontext; 23062306a36Sopenharmony_ci struct qedr_dev *dev; 23162306a36Sopenharmony_ci struct qedr_pd *pd; 23262306a36Sopenharmony_ci void __iomem *dpi_addr; 23362306a36Sopenharmony_ci struct rdma_user_mmap_entry *db_mmap_entry; 23462306a36Sopenharmony_ci u64 dpi_phys_addr; 23562306a36Sopenharmony_ci u32 dpi_size; 23662306a36Sopenharmony_ci u16 dpi; 23762306a36Sopenharmony_ci bool db_rec; 23862306a36Sopenharmony_ci u8 edpm_mode; 23962306a36Sopenharmony_ci}; 24062306a36Sopenharmony_ci 24162306a36Sopenharmony_ciunion db_prod32 { 24262306a36Sopenharmony_ci struct rdma_pwm_val16_data data; 24362306a36Sopenharmony_ci u32 raw; 24462306a36Sopenharmony_ci}; 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_ciunion db_prod64 { 24762306a36Sopenharmony_ci struct rdma_pwm_val32_data data; 24862306a36Sopenharmony_ci u64 raw; 24962306a36Sopenharmony_ci}; 25062306a36Sopenharmony_ci 25162306a36Sopenharmony_cienum qedr_cq_type { 25262306a36Sopenharmony_ci QEDR_CQ_TYPE_GSI, 25362306a36Sopenharmony_ci QEDR_CQ_TYPE_KERNEL, 25462306a36Sopenharmony_ci QEDR_CQ_TYPE_USER, 25562306a36Sopenharmony_ci}; 25662306a36Sopenharmony_ci 25762306a36Sopenharmony_cistruct qedr_pbl_info { 25862306a36Sopenharmony_ci u32 num_pbls; 25962306a36Sopenharmony_ci u32 num_pbes; 26062306a36Sopenharmony_ci u32 pbl_size; 26162306a36Sopenharmony_ci u32 pbe_size; 26262306a36Sopenharmony_ci bool two_layered; 26362306a36Sopenharmony_ci}; 26462306a36Sopenharmony_ci 26562306a36Sopenharmony_cistruct qedr_userq { 26662306a36Sopenharmony_ci struct ib_umem *umem; 26762306a36Sopenharmony_ci struct qedr_pbl_info pbl_info; 26862306a36Sopenharmony_ci struct qedr_pbl *pbl_tbl; 26962306a36Sopenharmony_ci u64 buf_addr; 27062306a36Sopenharmony_ci size_t buf_len; 27162306a36Sopenharmony_ci 27262306a36Sopenharmony_ci /* doorbell recovery */ 27362306a36Sopenharmony_ci void __iomem *db_addr; 27462306a36Sopenharmony_ci struct qedr_user_db_rec *db_rec_data; 27562306a36Sopenharmony_ci struct rdma_user_mmap_entry *db_mmap_entry; 27662306a36Sopenharmony_ci void __iomem *db_rec_db2_addr; 27762306a36Sopenharmony_ci union db_prod32 db_rec_db2_data; 27862306a36Sopenharmony_ci}; 27962306a36Sopenharmony_ci 28062306a36Sopenharmony_cistruct qedr_cq { 28162306a36Sopenharmony_ci struct ib_cq ibcq; 28262306a36Sopenharmony_ci 28362306a36Sopenharmony_ci enum qedr_cq_type cq_type; 28462306a36Sopenharmony_ci u32 sig; 28562306a36Sopenharmony_ci 28662306a36Sopenharmony_ci u16 icid; 28762306a36Sopenharmony_ci 28862306a36Sopenharmony_ci /* Lock to protect multiplem CQ's */ 28962306a36Sopenharmony_ci spinlock_t cq_lock; 29062306a36Sopenharmony_ci u8 arm_flags; 29162306a36Sopenharmony_ci struct qed_chain pbl; 29262306a36Sopenharmony_ci 29362306a36Sopenharmony_ci void __iomem *db_addr; 29462306a36Sopenharmony_ci union db_prod64 db; 29562306a36Sopenharmony_ci 29662306a36Sopenharmony_ci u8 pbl_toggle; 29762306a36Sopenharmony_ci union rdma_cqe *latest_cqe; 29862306a36Sopenharmony_ci union rdma_cqe *toggle_cqe; 29962306a36Sopenharmony_ci 30062306a36Sopenharmony_ci u32 cq_cons; 30162306a36Sopenharmony_ci 30262306a36Sopenharmony_ci struct qedr_userq q; 30362306a36Sopenharmony_ci u8 destroyed; 30462306a36Sopenharmony_ci u16 cnq_notif; 30562306a36Sopenharmony_ci}; 30662306a36Sopenharmony_ci 30762306a36Sopenharmony_cistruct qedr_pd { 30862306a36Sopenharmony_ci struct ib_pd ibpd; 30962306a36Sopenharmony_ci u32 pd_id; 31062306a36Sopenharmony_ci struct qedr_ucontext *uctx; 31162306a36Sopenharmony_ci}; 31262306a36Sopenharmony_ci 31362306a36Sopenharmony_cistruct qedr_xrcd { 31462306a36Sopenharmony_ci struct ib_xrcd ibxrcd; 31562306a36Sopenharmony_ci u16 xrcd_id; 31662306a36Sopenharmony_ci}; 31762306a36Sopenharmony_ci 31862306a36Sopenharmony_cistruct qedr_qp_hwq_info { 31962306a36Sopenharmony_ci /* WQE Elements */ 32062306a36Sopenharmony_ci struct qed_chain pbl; 32162306a36Sopenharmony_ci u64 p_phys_addr_tbl; 32262306a36Sopenharmony_ci u32 max_sges; 32362306a36Sopenharmony_ci 32462306a36Sopenharmony_ci /* WQE */ 32562306a36Sopenharmony_ci u16 prod; 32662306a36Sopenharmony_ci u16 cons; 32762306a36Sopenharmony_ci u16 wqe_cons; 32862306a36Sopenharmony_ci u16 gsi_cons; 32962306a36Sopenharmony_ci u16 max_wr; 33062306a36Sopenharmony_ci 33162306a36Sopenharmony_ci /* DB */ 33262306a36Sopenharmony_ci void __iomem *db; 33362306a36Sopenharmony_ci union db_prod32 db_data; 33462306a36Sopenharmony_ci 33562306a36Sopenharmony_ci void __iomem *iwarp_db2; 33662306a36Sopenharmony_ci union db_prod32 iwarp_db2_data; 33762306a36Sopenharmony_ci}; 33862306a36Sopenharmony_ci 33962306a36Sopenharmony_ci#define QEDR_INC_SW_IDX(p_info, index) \ 34062306a36Sopenharmony_ci do { \ 34162306a36Sopenharmony_ci p_info->index = (p_info->index + 1) & \ 34262306a36Sopenharmony_ci qed_chain_get_capacity(p_info->pbl) \ 34362306a36Sopenharmony_ci } while (0) 34462306a36Sopenharmony_ci 34562306a36Sopenharmony_cistruct qedr_srq_hwq_info { 34662306a36Sopenharmony_ci u32 max_sges; 34762306a36Sopenharmony_ci u32 max_wr; 34862306a36Sopenharmony_ci struct qed_chain pbl; 34962306a36Sopenharmony_ci u64 p_phys_addr_tbl; 35062306a36Sopenharmony_ci u32 wqe_prod; 35162306a36Sopenharmony_ci u32 sge_prod; 35262306a36Sopenharmony_ci u32 wr_prod_cnt; 35362306a36Sopenharmony_ci atomic_t wr_cons_cnt; 35462306a36Sopenharmony_ci u32 num_elems; 35562306a36Sopenharmony_ci 35662306a36Sopenharmony_ci struct rdma_srq_producers *virt_prod_pair_addr; 35762306a36Sopenharmony_ci dma_addr_t phy_prod_pair_addr; 35862306a36Sopenharmony_ci}; 35962306a36Sopenharmony_ci 36062306a36Sopenharmony_cistruct qedr_srq { 36162306a36Sopenharmony_ci struct ib_srq ibsrq; 36262306a36Sopenharmony_ci struct qedr_dev *dev; 36362306a36Sopenharmony_ci 36462306a36Sopenharmony_ci struct qedr_userq usrq; 36562306a36Sopenharmony_ci struct qedr_srq_hwq_info hw_srq; 36662306a36Sopenharmony_ci struct ib_umem *prod_umem; 36762306a36Sopenharmony_ci u16 srq_id; 36862306a36Sopenharmony_ci u32 srq_limit; 36962306a36Sopenharmony_ci bool is_xrc; 37062306a36Sopenharmony_ci /* lock to protect srq recv post */ 37162306a36Sopenharmony_ci spinlock_t lock; 37262306a36Sopenharmony_ci}; 37362306a36Sopenharmony_ci 37462306a36Sopenharmony_cienum qedr_qp_err_bitmap { 37562306a36Sopenharmony_ci QEDR_QP_ERR_SQ_FULL = 1, 37662306a36Sopenharmony_ci QEDR_QP_ERR_RQ_FULL = 2, 37762306a36Sopenharmony_ci QEDR_QP_ERR_BAD_SR = 4, 37862306a36Sopenharmony_ci QEDR_QP_ERR_BAD_RR = 8, 37962306a36Sopenharmony_ci QEDR_QP_ERR_SQ_PBL_FULL = 16, 38062306a36Sopenharmony_ci QEDR_QP_ERR_RQ_PBL_FULL = 32, 38162306a36Sopenharmony_ci}; 38262306a36Sopenharmony_ci 38362306a36Sopenharmony_cienum qedr_qp_create_type { 38462306a36Sopenharmony_ci QEDR_QP_CREATE_NONE, 38562306a36Sopenharmony_ci QEDR_QP_CREATE_USER, 38662306a36Sopenharmony_ci QEDR_QP_CREATE_KERNEL, 38762306a36Sopenharmony_ci}; 38862306a36Sopenharmony_ci 38962306a36Sopenharmony_cienum qedr_iwarp_cm_flags { 39062306a36Sopenharmony_ci QEDR_IWARP_CM_WAIT_FOR_CONNECT = BIT(0), 39162306a36Sopenharmony_ci QEDR_IWARP_CM_WAIT_FOR_DISCONNECT = BIT(1), 39262306a36Sopenharmony_ci}; 39362306a36Sopenharmony_ci 39462306a36Sopenharmony_cistruct qedr_qp { 39562306a36Sopenharmony_ci struct ib_qp ibqp; /* must be first */ 39662306a36Sopenharmony_ci struct qedr_dev *dev; 39762306a36Sopenharmony_ci struct qedr_qp_hwq_info sq; 39862306a36Sopenharmony_ci struct qedr_qp_hwq_info rq; 39962306a36Sopenharmony_ci 40062306a36Sopenharmony_ci u32 max_inline_data; 40162306a36Sopenharmony_ci 40262306a36Sopenharmony_ci /* Lock for QP's */ 40362306a36Sopenharmony_ci spinlock_t q_lock; 40462306a36Sopenharmony_ci struct qedr_cq *sq_cq; 40562306a36Sopenharmony_ci struct qedr_cq *rq_cq; 40662306a36Sopenharmony_ci struct qedr_srq *srq; 40762306a36Sopenharmony_ci enum qed_roce_qp_state state; 40862306a36Sopenharmony_ci u32 id; 40962306a36Sopenharmony_ci struct qedr_pd *pd; 41062306a36Sopenharmony_ci enum ib_qp_type qp_type; 41162306a36Sopenharmony_ci enum qedr_qp_create_type create_type; 41262306a36Sopenharmony_ci struct qed_rdma_qp *qed_qp; 41362306a36Sopenharmony_ci u32 qp_id; 41462306a36Sopenharmony_ci u16 icid; 41562306a36Sopenharmony_ci u16 mtu; 41662306a36Sopenharmony_ci int sgid_idx; 41762306a36Sopenharmony_ci u32 rq_psn; 41862306a36Sopenharmony_ci u32 sq_psn; 41962306a36Sopenharmony_ci u32 qkey; 42062306a36Sopenharmony_ci u32 dest_qp_num; 42162306a36Sopenharmony_ci u8 timeout; 42262306a36Sopenharmony_ci 42362306a36Sopenharmony_ci /* Relevant to qps created from kernel space only (ULPs) */ 42462306a36Sopenharmony_ci u8 prev_wqe_size; 42562306a36Sopenharmony_ci u16 wqe_cons; 42662306a36Sopenharmony_ci u32 err_bitmap; 42762306a36Sopenharmony_ci bool signaled; 42862306a36Sopenharmony_ci 42962306a36Sopenharmony_ci /* SQ shadow */ 43062306a36Sopenharmony_ci struct { 43162306a36Sopenharmony_ci u64 wr_id; 43262306a36Sopenharmony_ci enum ib_wc_opcode opcode; 43362306a36Sopenharmony_ci u32 bytes_len; 43462306a36Sopenharmony_ci u8 wqe_size; 43562306a36Sopenharmony_ci bool signaled; 43662306a36Sopenharmony_ci dma_addr_t icrc_mapping; 43762306a36Sopenharmony_ci u32 *icrc; 43862306a36Sopenharmony_ci struct qedr_mr *mr; 43962306a36Sopenharmony_ci } *wqe_wr_id; 44062306a36Sopenharmony_ci 44162306a36Sopenharmony_ci /* RQ shadow */ 44262306a36Sopenharmony_ci struct { 44362306a36Sopenharmony_ci u64 wr_id; 44462306a36Sopenharmony_ci struct ib_sge sg_list[RDMA_MAX_SGE_PER_RQ_WQE]; 44562306a36Sopenharmony_ci u8 wqe_size; 44662306a36Sopenharmony_ci 44762306a36Sopenharmony_ci u8 smac[ETH_ALEN]; 44862306a36Sopenharmony_ci u16 vlan; 44962306a36Sopenharmony_ci int rc; 45062306a36Sopenharmony_ci } *rqe_wr_id; 45162306a36Sopenharmony_ci 45262306a36Sopenharmony_ci /* Relevant to qps created from user space only (applications) */ 45362306a36Sopenharmony_ci struct qedr_userq usq; 45462306a36Sopenharmony_ci struct qedr_userq urq; 45562306a36Sopenharmony_ci 45662306a36Sopenharmony_ci /* synchronization objects used with iwarp ep */ 45762306a36Sopenharmony_ci struct kref refcnt; 45862306a36Sopenharmony_ci struct completion iwarp_cm_comp; 45962306a36Sopenharmony_ci struct completion qp_rel_comp; 46062306a36Sopenharmony_ci unsigned long iwarp_cm_flags; /* enum iwarp_cm_flags */ 46162306a36Sopenharmony_ci}; 46262306a36Sopenharmony_ci 46362306a36Sopenharmony_cistruct qedr_ah { 46462306a36Sopenharmony_ci struct ib_ah ibah; 46562306a36Sopenharmony_ci struct rdma_ah_attr attr; 46662306a36Sopenharmony_ci}; 46762306a36Sopenharmony_ci 46862306a36Sopenharmony_cienum qedr_mr_type { 46962306a36Sopenharmony_ci QEDR_MR_USER, 47062306a36Sopenharmony_ci QEDR_MR_KERNEL, 47162306a36Sopenharmony_ci QEDR_MR_DMA, 47262306a36Sopenharmony_ci QEDR_MR_FRMR, 47362306a36Sopenharmony_ci}; 47462306a36Sopenharmony_ci 47562306a36Sopenharmony_cistruct mr_info { 47662306a36Sopenharmony_ci struct qedr_pbl *pbl_table; 47762306a36Sopenharmony_ci struct qedr_pbl_info pbl_info; 47862306a36Sopenharmony_ci struct list_head free_pbl_list; 47962306a36Sopenharmony_ci struct list_head inuse_pbl_list; 48062306a36Sopenharmony_ci u32 completed; 48162306a36Sopenharmony_ci u32 completed_handled; 48262306a36Sopenharmony_ci}; 48362306a36Sopenharmony_ci 48462306a36Sopenharmony_cistruct qedr_mr { 48562306a36Sopenharmony_ci struct ib_mr ibmr; 48662306a36Sopenharmony_ci struct ib_umem *umem; 48762306a36Sopenharmony_ci 48862306a36Sopenharmony_ci struct qed_rdma_register_tid_in_params hw_mr; 48962306a36Sopenharmony_ci enum qedr_mr_type type; 49062306a36Sopenharmony_ci 49162306a36Sopenharmony_ci struct qedr_dev *dev; 49262306a36Sopenharmony_ci struct mr_info info; 49362306a36Sopenharmony_ci 49462306a36Sopenharmony_ci u64 *pages; 49562306a36Sopenharmony_ci u32 npages; 49662306a36Sopenharmony_ci}; 49762306a36Sopenharmony_ci 49862306a36Sopenharmony_cistruct qedr_user_mmap_entry { 49962306a36Sopenharmony_ci struct rdma_user_mmap_entry rdma_entry; 50062306a36Sopenharmony_ci struct qedr_dev *dev; 50162306a36Sopenharmony_ci union { 50262306a36Sopenharmony_ci u64 io_address; 50362306a36Sopenharmony_ci void *address; 50462306a36Sopenharmony_ci }; 50562306a36Sopenharmony_ci size_t length; 50662306a36Sopenharmony_ci u16 dpi; 50762306a36Sopenharmony_ci u8 mmap_flag; 50862306a36Sopenharmony_ci}; 50962306a36Sopenharmony_ci 51062306a36Sopenharmony_ci#define SET_FIELD2(value, name, flag) ((value) |= ((flag) << (name ## _SHIFT))) 51162306a36Sopenharmony_ci 51262306a36Sopenharmony_ci#define QEDR_RESP_IMM (RDMA_CQE_RESPONDER_IMM_FLG_MASK << \ 51362306a36Sopenharmony_ci RDMA_CQE_RESPONDER_IMM_FLG_SHIFT) 51462306a36Sopenharmony_ci#define QEDR_RESP_RDMA (RDMA_CQE_RESPONDER_RDMA_FLG_MASK << \ 51562306a36Sopenharmony_ci RDMA_CQE_RESPONDER_RDMA_FLG_SHIFT) 51662306a36Sopenharmony_ci#define QEDR_RESP_INV (RDMA_CQE_RESPONDER_INV_FLG_MASK << \ 51762306a36Sopenharmony_ci RDMA_CQE_RESPONDER_INV_FLG_SHIFT) 51862306a36Sopenharmony_ci 51962306a36Sopenharmony_cistatic inline void qedr_inc_sw_cons(struct qedr_qp_hwq_info *info) 52062306a36Sopenharmony_ci{ 52162306a36Sopenharmony_ci info->cons = (info->cons + 1) % info->max_wr; 52262306a36Sopenharmony_ci info->wqe_cons++; 52362306a36Sopenharmony_ci} 52462306a36Sopenharmony_ci 52562306a36Sopenharmony_cistatic inline void qedr_inc_sw_prod(struct qedr_qp_hwq_info *info) 52662306a36Sopenharmony_ci{ 52762306a36Sopenharmony_ci info->prod = (info->prod + 1) % info->max_wr; 52862306a36Sopenharmony_ci} 52962306a36Sopenharmony_ci 53062306a36Sopenharmony_cistatic inline int qedr_get_dmac(struct qedr_dev *dev, 53162306a36Sopenharmony_ci struct rdma_ah_attr *ah_attr, u8 *mac_addr) 53262306a36Sopenharmony_ci{ 53362306a36Sopenharmony_ci union ib_gid zero_sgid = { { 0 } }; 53462306a36Sopenharmony_ci struct in6_addr in6; 53562306a36Sopenharmony_ci const struct ib_global_route *grh = rdma_ah_read_grh(ah_attr); 53662306a36Sopenharmony_ci u8 *dmac; 53762306a36Sopenharmony_ci 53862306a36Sopenharmony_ci if (!memcmp(&grh->dgid, &zero_sgid, sizeof(union ib_gid))) { 53962306a36Sopenharmony_ci DP_ERR(dev, "Local port GID not supported\n"); 54062306a36Sopenharmony_ci eth_zero_addr(mac_addr); 54162306a36Sopenharmony_ci return -EINVAL; 54262306a36Sopenharmony_ci } 54362306a36Sopenharmony_ci 54462306a36Sopenharmony_ci memcpy(&in6, grh->dgid.raw, sizeof(in6)); 54562306a36Sopenharmony_ci dmac = rdma_ah_retrieve_dmac(ah_attr); 54662306a36Sopenharmony_ci if (!dmac) 54762306a36Sopenharmony_ci return -EINVAL; 54862306a36Sopenharmony_ci ether_addr_copy(mac_addr, dmac); 54962306a36Sopenharmony_ci 55062306a36Sopenharmony_ci return 0; 55162306a36Sopenharmony_ci} 55262306a36Sopenharmony_ci 55362306a36Sopenharmony_cistruct qedr_iw_listener { 55462306a36Sopenharmony_ci struct qedr_dev *dev; 55562306a36Sopenharmony_ci struct iw_cm_id *cm_id; 55662306a36Sopenharmony_ci int backlog; 55762306a36Sopenharmony_ci void *qed_handle; 55862306a36Sopenharmony_ci}; 55962306a36Sopenharmony_ci 56062306a36Sopenharmony_cistruct qedr_iw_ep { 56162306a36Sopenharmony_ci struct qedr_dev *dev; 56262306a36Sopenharmony_ci struct iw_cm_id *cm_id; 56362306a36Sopenharmony_ci struct qedr_qp *qp; 56462306a36Sopenharmony_ci void *qed_context; 56562306a36Sopenharmony_ci struct kref refcnt; 56662306a36Sopenharmony_ci}; 56762306a36Sopenharmony_ci 56862306a36Sopenharmony_cistatic inline 56962306a36Sopenharmony_cistruct qedr_ucontext *get_qedr_ucontext(struct ib_ucontext *ibucontext) 57062306a36Sopenharmony_ci{ 57162306a36Sopenharmony_ci return container_of(ibucontext, struct qedr_ucontext, ibucontext); 57262306a36Sopenharmony_ci} 57362306a36Sopenharmony_ci 57462306a36Sopenharmony_cistatic inline struct qedr_dev *get_qedr_dev(struct ib_device *ibdev) 57562306a36Sopenharmony_ci{ 57662306a36Sopenharmony_ci return container_of(ibdev, struct qedr_dev, ibdev); 57762306a36Sopenharmony_ci} 57862306a36Sopenharmony_ci 57962306a36Sopenharmony_cistatic inline struct qedr_pd *get_qedr_pd(struct ib_pd *ibpd) 58062306a36Sopenharmony_ci{ 58162306a36Sopenharmony_ci return container_of(ibpd, struct qedr_pd, ibpd); 58262306a36Sopenharmony_ci} 58362306a36Sopenharmony_ci 58462306a36Sopenharmony_cistatic inline struct qedr_xrcd *get_qedr_xrcd(struct ib_xrcd *ibxrcd) 58562306a36Sopenharmony_ci{ 58662306a36Sopenharmony_ci return container_of(ibxrcd, struct qedr_xrcd, ibxrcd); 58762306a36Sopenharmony_ci} 58862306a36Sopenharmony_ci 58962306a36Sopenharmony_cistatic inline struct qedr_cq *get_qedr_cq(struct ib_cq *ibcq) 59062306a36Sopenharmony_ci{ 59162306a36Sopenharmony_ci return container_of(ibcq, struct qedr_cq, ibcq); 59262306a36Sopenharmony_ci} 59362306a36Sopenharmony_ci 59462306a36Sopenharmony_cistatic inline struct qedr_qp *get_qedr_qp(struct ib_qp *ibqp) 59562306a36Sopenharmony_ci{ 59662306a36Sopenharmony_ci return container_of(ibqp, struct qedr_qp, ibqp); 59762306a36Sopenharmony_ci} 59862306a36Sopenharmony_ci 59962306a36Sopenharmony_cistatic inline struct qedr_ah *get_qedr_ah(struct ib_ah *ibah) 60062306a36Sopenharmony_ci{ 60162306a36Sopenharmony_ci return container_of(ibah, struct qedr_ah, ibah); 60262306a36Sopenharmony_ci} 60362306a36Sopenharmony_ci 60462306a36Sopenharmony_cistatic inline struct qedr_mr *get_qedr_mr(struct ib_mr *ibmr) 60562306a36Sopenharmony_ci{ 60662306a36Sopenharmony_ci return container_of(ibmr, struct qedr_mr, ibmr); 60762306a36Sopenharmony_ci} 60862306a36Sopenharmony_ci 60962306a36Sopenharmony_cistatic inline struct qedr_srq *get_qedr_srq(struct ib_srq *ibsrq) 61062306a36Sopenharmony_ci{ 61162306a36Sopenharmony_ci return container_of(ibsrq, struct qedr_srq, ibsrq); 61262306a36Sopenharmony_ci} 61362306a36Sopenharmony_ci 61462306a36Sopenharmony_cistatic inline bool qedr_qp_has_srq(struct qedr_qp *qp) 61562306a36Sopenharmony_ci{ 61662306a36Sopenharmony_ci return qp->srq; 61762306a36Sopenharmony_ci} 61862306a36Sopenharmony_ci 61962306a36Sopenharmony_cistatic inline bool qedr_qp_has_sq(struct qedr_qp *qp) 62062306a36Sopenharmony_ci{ 62162306a36Sopenharmony_ci if (qp->qp_type == IB_QPT_GSI || qp->qp_type == IB_QPT_XRC_TGT) 62262306a36Sopenharmony_ci return false; 62362306a36Sopenharmony_ci 62462306a36Sopenharmony_ci return true; 62562306a36Sopenharmony_ci} 62662306a36Sopenharmony_ci 62762306a36Sopenharmony_cistatic inline bool qedr_qp_has_rq(struct qedr_qp *qp) 62862306a36Sopenharmony_ci{ 62962306a36Sopenharmony_ci if (qp->qp_type == IB_QPT_GSI || qp->qp_type == IB_QPT_XRC_INI || 63062306a36Sopenharmony_ci qp->qp_type == IB_QPT_XRC_TGT || qedr_qp_has_srq(qp)) 63162306a36Sopenharmony_ci return false; 63262306a36Sopenharmony_ci 63362306a36Sopenharmony_ci return true; 63462306a36Sopenharmony_ci} 63562306a36Sopenharmony_ci 63662306a36Sopenharmony_cistatic inline struct qedr_user_mmap_entry * 63762306a36Sopenharmony_ciget_qedr_mmap_entry(struct rdma_user_mmap_entry *rdma_entry) 63862306a36Sopenharmony_ci{ 63962306a36Sopenharmony_ci return container_of(rdma_entry, struct qedr_user_mmap_entry, 64062306a36Sopenharmony_ci rdma_entry); 64162306a36Sopenharmony_ci} 64262306a36Sopenharmony_ci#endif 643