18c2ecf20Sopenharmony_ci/* QLogic qedr NIC Driver 28c2ecf20Sopenharmony_ci * Copyright (c) 2015-2016 QLogic Corporation 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * This software is available to you under a choice of one of two 58c2ecf20Sopenharmony_ci * licenses. You may choose to be licensed under the terms of the GNU 68c2ecf20Sopenharmony_ci * General Public License (GPL) Version 2, available from the file 78c2ecf20Sopenharmony_ci * COPYING in the main directory of this source tree, or the 88c2ecf20Sopenharmony_ci * OpenIB.org BSD license below: 98c2ecf20Sopenharmony_ci * 108c2ecf20Sopenharmony_ci * Redistribution and use in source and binary forms, with or 118c2ecf20Sopenharmony_ci * without modification, are permitted provided that the following 128c2ecf20Sopenharmony_ci * conditions are met: 138c2ecf20Sopenharmony_ci * 148c2ecf20Sopenharmony_ci * - Redistributions of source code must retain the above 158c2ecf20Sopenharmony_ci * copyright notice, this list of conditions and the following 168c2ecf20Sopenharmony_ci * disclaimer. 178c2ecf20Sopenharmony_ci * 188c2ecf20Sopenharmony_ci * - Redistributions in binary form must reproduce the above 198c2ecf20Sopenharmony_ci * copyright notice, this list of conditions and the following 208c2ecf20Sopenharmony_ci * disclaimer in the documentation and /or other materials 218c2ecf20Sopenharmony_ci * provided with the distribution. 228c2ecf20Sopenharmony_ci * 238c2ecf20Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 248c2ecf20Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 258c2ecf20Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 268c2ecf20Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 278c2ecf20Sopenharmony_ci * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 288c2ecf20Sopenharmony_ci * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 298c2ecf20Sopenharmony_ci * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 308c2ecf20Sopenharmony_ci * SOFTWARE. 318c2ecf20Sopenharmony_ci */ 328c2ecf20Sopenharmony_ci#ifndef __QEDR_H__ 338c2ecf20Sopenharmony_ci#define __QEDR_H__ 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci#include <linux/pci.h> 368c2ecf20Sopenharmony_ci#include <linux/xarray.h> 378c2ecf20Sopenharmony_ci#include <rdma/ib_addr.h> 388c2ecf20Sopenharmony_ci#include <linux/qed/qed_if.h> 398c2ecf20Sopenharmony_ci#include <linux/qed/qed_chain.h> 408c2ecf20Sopenharmony_ci#include <linux/qed/qed_rdma_if.h> 418c2ecf20Sopenharmony_ci#include <linux/qed/qede_rdma.h> 428c2ecf20Sopenharmony_ci#include <linux/qed/roce_common.h> 438c2ecf20Sopenharmony_ci#include <linux/completion.h> 448c2ecf20Sopenharmony_ci#include "qedr_hsi_rdma.h" 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci#define QEDR_NODE_DESC "QLogic 579xx RoCE HCA" 478c2ecf20Sopenharmony_ci#define DP_NAME(_dev) dev_name(&(_dev)->ibdev.dev) 488c2ecf20Sopenharmony_ci#define IS_IWARP(_dev) ((_dev)->rdma_type == QED_RDMA_TYPE_IWARP) 498c2ecf20Sopenharmony_ci#define IS_ROCE(_dev) ((_dev)->rdma_type == QED_RDMA_TYPE_ROCE) 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci#define DP_DEBUG(dev, module, fmt, ...) \ 528c2ecf20Sopenharmony_ci pr_debug("(%s) " module ": " fmt, \ 538c2ecf20Sopenharmony_ci DP_NAME(dev) ? DP_NAME(dev) : "", ## __VA_ARGS__) 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci#define QEDR_MSG_INIT "INIT" 568c2ecf20Sopenharmony_ci#define QEDR_MSG_MISC "MISC" 578c2ecf20Sopenharmony_ci#define QEDR_MSG_CQ " CQ" 588c2ecf20Sopenharmony_ci#define QEDR_MSG_MR " MR" 598c2ecf20Sopenharmony_ci#define QEDR_MSG_RQ " RQ" 608c2ecf20Sopenharmony_ci#define QEDR_MSG_SQ " SQ" 618c2ecf20Sopenharmony_ci#define QEDR_MSG_QP " QP" 628c2ecf20Sopenharmony_ci#define QEDR_MSG_SRQ " SRQ" 638c2ecf20Sopenharmony_ci#define QEDR_MSG_GSI " GSI" 648c2ecf20Sopenharmony_ci#define QEDR_MSG_IWARP " IW" 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_ci#define QEDR_CQ_MAGIC_NUMBER (0x11223344) 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci#define FW_PAGE_SIZE (RDMA_RING_PAGE_SIZE) 698c2ecf20Sopenharmony_ci#define FW_PAGE_SHIFT (12) 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_cistruct qedr_dev; 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_cistruct qedr_cnq { 748c2ecf20Sopenharmony_ci struct qedr_dev *dev; 758c2ecf20Sopenharmony_ci struct qed_chain pbl; 768c2ecf20Sopenharmony_ci struct qed_sb_info *sb; 778c2ecf20Sopenharmony_ci char name[32]; 788c2ecf20Sopenharmony_ci u64 n_comp; 798c2ecf20Sopenharmony_ci __le16 *hw_cons_ptr; 808c2ecf20Sopenharmony_ci u8 index; 818c2ecf20Sopenharmony_ci}; 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ci#define QEDR_MAX_SGID 128 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_cistruct qedr_device_attr { 868c2ecf20Sopenharmony_ci u32 vendor_id; 878c2ecf20Sopenharmony_ci u32 vendor_part_id; 888c2ecf20Sopenharmony_ci u32 hw_ver; 898c2ecf20Sopenharmony_ci u64 fw_ver; 908c2ecf20Sopenharmony_ci u64 node_guid; 918c2ecf20Sopenharmony_ci u64 sys_image_guid; 928c2ecf20Sopenharmony_ci u8 max_cnq; 938c2ecf20Sopenharmony_ci u8 max_sge; 948c2ecf20Sopenharmony_ci u16 max_inline; 958c2ecf20Sopenharmony_ci u32 max_sqe; 968c2ecf20Sopenharmony_ci u32 max_rqe; 978c2ecf20Sopenharmony_ci u8 max_qp_resp_rd_atomic_resc; 988c2ecf20Sopenharmony_ci u8 max_qp_req_rd_atomic_resc; 998c2ecf20Sopenharmony_ci u64 max_dev_resp_rd_atomic_resc; 1008c2ecf20Sopenharmony_ci u32 max_cq; 1018c2ecf20Sopenharmony_ci u32 max_qp; 1028c2ecf20Sopenharmony_ci u32 max_mr; 1038c2ecf20Sopenharmony_ci u64 max_mr_size; 1048c2ecf20Sopenharmony_ci u32 max_cqe; 1058c2ecf20Sopenharmony_ci u32 max_mw; 1068c2ecf20Sopenharmony_ci u32 max_mr_mw_fmr_pbl; 1078c2ecf20Sopenharmony_ci u64 max_mr_mw_fmr_size; 1088c2ecf20Sopenharmony_ci u32 max_pd; 1098c2ecf20Sopenharmony_ci u32 max_ah; 1108c2ecf20Sopenharmony_ci u8 max_pkey; 1118c2ecf20Sopenharmony_ci u32 max_srq; 1128c2ecf20Sopenharmony_ci u32 max_srq_wr; 1138c2ecf20Sopenharmony_ci u8 max_srq_sge; 1148c2ecf20Sopenharmony_ci u8 max_stats_queues; 1158c2ecf20Sopenharmony_ci u32 dev_caps; 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci u64 page_size_caps; 1188c2ecf20Sopenharmony_ci u8 dev_ack_delay; 1198c2ecf20Sopenharmony_ci u32 reserved_lkey; 1208c2ecf20Sopenharmony_ci u32 bad_pkey_counter; 1218c2ecf20Sopenharmony_ci struct qed_rdma_events events; 1228c2ecf20Sopenharmony_ci}; 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_ci#define QEDR_ENET_STATE_BIT (0) 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_cistruct qedr_dev { 1278c2ecf20Sopenharmony_ci struct ib_device ibdev; 1288c2ecf20Sopenharmony_ci struct qed_dev *cdev; 1298c2ecf20Sopenharmony_ci struct pci_dev *pdev; 1308c2ecf20Sopenharmony_ci struct net_device *ndev; 1318c2ecf20Sopenharmony_ci 1328c2ecf20Sopenharmony_ci enum ib_atomic_cap atomic_cap; 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_ci void *rdma_ctx; 1358c2ecf20Sopenharmony_ci struct qedr_device_attr attr; 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_ci const struct qed_rdma_ops *ops; 1388c2ecf20Sopenharmony_ci struct qed_int_info int_info; 1398c2ecf20Sopenharmony_ci 1408c2ecf20Sopenharmony_ci struct qed_sb_info *sb_array; 1418c2ecf20Sopenharmony_ci struct qedr_cnq *cnq_array; 1428c2ecf20Sopenharmony_ci int num_cnq; 1438c2ecf20Sopenharmony_ci int sb_start; 1448c2ecf20Sopenharmony_ci 1458c2ecf20Sopenharmony_ci void __iomem *db_addr; 1468c2ecf20Sopenharmony_ci u64 db_phys_addr; 1478c2ecf20Sopenharmony_ci u32 db_size; 1488c2ecf20Sopenharmony_ci u16 dpi; 1498c2ecf20Sopenharmony_ci 1508c2ecf20Sopenharmony_ci union ib_gid *sgid_tbl; 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_ci /* Lock for sgid table */ 1538c2ecf20Sopenharmony_ci spinlock_t sgid_lock; 1548c2ecf20Sopenharmony_ci 1558c2ecf20Sopenharmony_ci u64 guid; 1568c2ecf20Sopenharmony_ci 1578c2ecf20Sopenharmony_ci u32 dp_module; 1588c2ecf20Sopenharmony_ci u8 dp_level; 1598c2ecf20Sopenharmony_ci u8 num_hwfns; 1608c2ecf20Sopenharmony_ci#define QEDR_IS_CMT(dev) ((dev)->num_hwfns > 1) 1618c2ecf20Sopenharmony_ci u8 affin_hwfn_idx; 1628c2ecf20Sopenharmony_ci u8 gsi_ll2_handle; 1638c2ecf20Sopenharmony_ci 1648c2ecf20Sopenharmony_ci uint wq_multiplier; 1658c2ecf20Sopenharmony_ci u8 gsi_ll2_mac_address[ETH_ALEN]; 1668c2ecf20Sopenharmony_ci int gsi_qp_created; 1678c2ecf20Sopenharmony_ci struct qedr_cq *gsi_sqcq; 1688c2ecf20Sopenharmony_ci struct qedr_cq *gsi_rqcq; 1698c2ecf20Sopenharmony_ci struct qedr_qp *gsi_qp; 1708c2ecf20Sopenharmony_ci enum qed_rdma_type rdma_type; 1718c2ecf20Sopenharmony_ci struct xarray qps; 1728c2ecf20Sopenharmony_ci struct xarray srqs; 1738c2ecf20Sopenharmony_ci struct workqueue_struct *iwarp_wq; 1748c2ecf20Sopenharmony_ci u16 iwarp_max_mtu; 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_ci unsigned long enet_state; 1778c2ecf20Sopenharmony_ci 1788c2ecf20Sopenharmony_ci u8 user_dpm_enabled; 1798c2ecf20Sopenharmony_ci}; 1808c2ecf20Sopenharmony_ci 1818c2ecf20Sopenharmony_ci#define QEDR_MAX_SQ_PBL (0x8000) 1828c2ecf20Sopenharmony_ci#define QEDR_MAX_SQ_PBL_ENTRIES (0x10000 / sizeof(void *)) 1838c2ecf20Sopenharmony_ci#define QEDR_SQE_ELEMENT_SIZE (sizeof(struct rdma_sq_sge)) 1848c2ecf20Sopenharmony_ci#define QEDR_MAX_SQE_ELEMENTS_PER_SQE (ROCE_REQ_MAX_SINGLE_SQ_WQE_SIZE / \ 1858c2ecf20Sopenharmony_ci QEDR_SQE_ELEMENT_SIZE) 1868c2ecf20Sopenharmony_ci#define QEDR_MAX_SQE_ELEMENTS_PER_PAGE ((RDMA_RING_PAGE_SIZE) / \ 1878c2ecf20Sopenharmony_ci QEDR_SQE_ELEMENT_SIZE) 1888c2ecf20Sopenharmony_ci#define QEDR_MAX_SQE ((QEDR_MAX_SQ_PBL_ENTRIES) *\ 1898c2ecf20Sopenharmony_ci (RDMA_RING_PAGE_SIZE) / \ 1908c2ecf20Sopenharmony_ci (QEDR_SQE_ELEMENT_SIZE) /\ 1918c2ecf20Sopenharmony_ci (QEDR_MAX_SQE_ELEMENTS_PER_SQE)) 1928c2ecf20Sopenharmony_ci/* RQ */ 1938c2ecf20Sopenharmony_ci#define QEDR_MAX_RQ_PBL (0x2000) 1948c2ecf20Sopenharmony_ci#define QEDR_MAX_RQ_PBL_ENTRIES (0x10000 / sizeof(void *)) 1958c2ecf20Sopenharmony_ci#define QEDR_RQE_ELEMENT_SIZE (sizeof(struct rdma_rq_sge)) 1968c2ecf20Sopenharmony_ci#define QEDR_MAX_RQE_ELEMENTS_PER_RQE (RDMA_MAX_SGE_PER_RQ_WQE) 1978c2ecf20Sopenharmony_ci#define QEDR_MAX_RQE_ELEMENTS_PER_PAGE ((RDMA_RING_PAGE_SIZE) / \ 1988c2ecf20Sopenharmony_ci QEDR_RQE_ELEMENT_SIZE) 1998c2ecf20Sopenharmony_ci#define QEDR_MAX_RQE ((QEDR_MAX_RQ_PBL_ENTRIES) *\ 2008c2ecf20Sopenharmony_ci (RDMA_RING_PAGE_SIZE) / \ 2018c2ecf20Sopenharmony_ci (QEDR_RQE_ELEMENT_SIZE) /\ 2028c2ecf20Sopenharmony_ci (QEDR_MAX_RQE_ELEMENTS_PER_RQE)) 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_ci#define QEDR_CQE_SIZE (sizeof(union rdma_cqe)) 2058c2ecf20Sopenharmony_ci#define QEDR_MAX_CQE_PBL_SIZE (512 * 1024) 2068c2ecf20Sopenharmony_ci#define QEDR_MAX_CQE_PBL_ENTRIES (((QEDR_MAX_CQE_PBL_SIZE) / \ 2078c2ecf20Sopenharmony_ci sizeof(u64)) - 1) 2088c2ecf20Sopenharmony_ci#define QEDR_MAX_CQES ((u32)((QEDR_MAX_CQE_PBL_ENTRIES) * \ 2098c2ecf20Sopenharmony_ci (QED_CHAIN_PAGE_SIZE) / QEDR_CQE_SIZE)) 2108c2ecf20Sopenharmony_ci 2118c2ecf20Sopenharmony_ci#define QEDR_ROCE_MAX_CNQ_SIZE (0x4000) 2128c2ecf20Sopenharmony_ci 2138c2ecf20Sopenharmony_ci#define QEDR_MAX_PORT (1) 2148c2ecf20Sopenharmony_ci#define QEDR_PORT (1) 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_ci#define QEDR_UVERBS(CMD_NAME) (1ull << IB_USER_VERBS_CMD_##CMD_NAME) 2178c2ecf20Sopenharmony_ci 2188c2ecf20Sopenharmony_ci#define QEDR_ROCE_PKEY_MAX 1 2198c2ecf20Sopenharmony_ci#define QEDR_ROCE_PKEY_TABLE_LEN 1 2208c2ecf20Sopenharmony_ci#define QEDR_ROCE_PKEY_DEFAULT 0xffff 2218c2ecf20Sopenharmony_ci 2228c2ecf20Sopenharmony_cistruct qedr_pbl { 2238c2ecf20Sopenharmony_ci struct list_head list_entry; 2248c2ecf20Sopenharmony_ci void *va; 2258c2ecf20Sopenharmony_ci dma_addr_t pa; 2268c2ecf20Sopenharmony_ci}; 2278c2ecf20Sopenharmony_ci 2288c2ecf20Sopenharmony_cistruct qedr_ucontext { 2298c2ecf20Sopenharmony_ci struct ib_ucontext ibucontext; 2308c2ecf20Sopenharmony_ci struct qedr_dev *dev; 2318c2ecf20Sopenharmony_ci struct qedr_pd *pd; 2328c2ecf20Sopenharmony_ci void __iomem *dpi_addr; 2338c2ecf20Sopenharmony_ci struct rdma_user_mmap_entry *db_mmap_entry; 2348c2ecf20Sopenharmony_ci u64 dpi_phys_addr; 2358c2ecf20Sopenharmony_ci u32 dpi_size; 2368c2ecf20Sopenharmony_ci u16 dpi; 2378c2ecf20Sopenharmony_ci bool db_rec; 2388c2ecf20Sopenharmony_ci u8 edpm_mode; 2398c2ecf20Sopenharmony_ci}; 2408c2ecf20Sopenharmony_ci 2418c2ecf20Sopenharmony_ciunion db_prod32 { 2428c2ecf20Sopenharmony_ci struct rdma_pwm_val16_data data; 2438c2ecf20Sopenharmony_ci u32 raw; 2448c2ecf20Sopenharmony_ci}; 2458c2ecf20Sopenharmony_ci 2468c2ecf20Sopenharmony_ciunion db_prod64 { 2478c2ecf20Sopenharmony_ci struct rdma_pwm_val32_data data; 2488c2ecf20Sopenharmony_ci u64 raw; 2498c2ecf20Sopenharmony_ci}; 2508c2ecf20Sopenharmony_ci 2518c2ecf20Sopenharmony_cienum qedr_cq_type { 2528c2ecf20Sopenharmony_ci QEDR_CQ_TYPE_GSI, 2538c2ecf20Sopenharmony_ci QEDR_CQ_TYPE_KERNEL, 2548c2ecf20Sopenharmony_ci QEDR_CQ_TYPE_USER, 2558c2ecf20Sopenharmony_ci}; 2568c2ecf20Sopenharmony_ci 2578c2ecf20Sopenharmony_cistruct qedr_pbl_info { 2588c2ecf20Sopenharmony_ci u32 num_pbls; 2598c2ecf20Sopenharmony_ci u32 num_pbes; 2608c2ecf20Sopenharmony_ci u32 pbl_size; 2618c2ecf20Sopenharmony_ci u32 pbe_size; 2628c2ecf20Sopenharmony_ci bool two_layered; 2638c2ecf20Sopenharmony_ci}; 2648c2ecf20Sopenharmony_ci 2658c2ecf20Sopenharmony_cistruct qedr_userq { 2668c2ecf20Sopenharmony_ci struct ib_umem *umem; 2678c2ecf20Sopenharmony_ci struct qedr_pbl_info pbl_info; 2688c2ecf20Sopenharmony_ci struct qedr_pbl *pbl_tbl; 2698c2ecf20Sopenharmony_ci u64 buf_addr; 2708c2ecf20Sopenharmony_ci size_t buf_len; 2718c2ecf20Sopenharmony_ci 2728c2ecf20Sopenharmony_ci /* doorbell recovery */ 2738c2ecf20Sopenharmony_ci void __iomem *db_addr; 2748c2ecf20Sopenharmony_ci struct qedr_user_db_rec *db_rec_data; 2758c2ecf20Sopenharmony_ci struct rdma_user_mmap_entry *db_mmap_entry; 2768c2ecf20Sopenharmony_ci void __iomem *db_rec_db2_addr; 2778c2ecf20Sopenharmony_ci union db_prod32 db_rec_db2_data; 2788c2ecf20Sopenharmony_ci}; 2798c2ecf20Sopenharmony_ci 2808c2ecf20Sopenharmony_cistruct qedr_cq { 2818c2ecf20Sopenharmony_ci struct ib_cq ibcq; 2828c2ecf20Sopenharmony_ci 2838c2ecf20Sopenharmony_ci enum qedr_cq_type cq_type; 2848c2ecf20Sopenharmony_ci u32 sig; 2858c2ecf20Sopenharmony_ci 2868c2ecf20Sopenharmony_ci u16 icid; 2878c2ecf20Sopenharmony_ci 2888c2ecf20Sopenharmony_ci /* Lock to protect multiplem CQ's */ 2898c2ecf20Sopenharmony_ci spinlock_t cq_lock; 2908c2ecf20Sopenharmony_ci u8 arm_flags; 2918c2ecf20Sopenharmony_ci struct qed_chain pbl; 2928c2ecf20Sopenharmony_ci 2938c2ecf20Sopenharmony_ci void __iomem *db_addr; 2948c2ecf20Sopenharmony_ci union db_prod64 db; 2958c2ecf20Sopenharmony_ci 2968c2ecf20Sopenharmony_ci u8 pbl_toggle; 2978c2ecf20Sopenharmony_ci union rdma_cqe *latest_cqe; 2988c2ecf20Sopenharmony_ci union rdma_cqe *toggle_cqe; 2998c2ecf20Sopenharmony_ci 3008c2ecf20Sopenharmony_ci u32 cq_cons; 3018c2ecf20Sopenharmony_ci 3028c2ecf20Sopenharmony_ci struct qedr_userq q; 3038c2ecf20Sopenharmony_ci u8 destroyed; 3048c2ecf20Sopenharmony_ci u16 cnq_notif; 3058c2ecf20Sopenharmony_ci}; 3068c2ecf20Sopenharmony_ci 3078c2ecf20Sopenharmony_cistruct qedr_pd { 3088c2ecf20Sopenharmony_ci struct ib_pd ibpd; 3098c2ecf20Sopenharmony_ci u32 pd_id; 3108c2ecf20Sopenharmony_ci struct qedr_ucontext *uctx; 3118c2ecf20Sopenharmony_ci}; 3128c2ecf20Sopenharmony_ci 3138c2ecf20Sopenharmony_cistruct qedr_xrcd { 3148c2ecf20Sopenharmony_ci struct ib_xrcd ibxrcd; 3158c2ecf20Sopenharmony_ci u16 xrcd_id; 3168c2ecf20Sopenharmony_ci}; 3178c2ecf20Sopenharmony_ci 3188c2ecf20Sopenharmony_cistruct qedr_qp_hwq_info { 3198c2ecf20Sopenharmony_ci /* WQE Elements */ 3208c2ecf20Sopenharmony_ci struct qed_chain pbl; 3218c2ecf20Sopenharmony_ci u64 p_phys_addr_tbl; 3228c2ecf20Sopenharmony_ci u32 max_sges; 3238c2ecf20Sopenharmony_ci 3248c2ecf20Sopenharmony_ci /* WQE */ 3258c2ecf20Sopenharmony_ci u16 prod; 3268c2ecf20Sopenharmony_ci u16 cons; 3278c2ecf20Sopenharmony_ci u16 wqe_cons; 3288c2ecf20Sopenharmony_ci u16 gsi_cons; 3298c2ecf20Sopenharmony_ci u16 max_wr; 3308c2ecf20Sopenharmony_ci 3318c2ecf20Sopenharmony_ci /* DB */ 3328c2ecf20Sopenharmony_ci void __iomem *db; 3338c2ecf20Sopenharmony_ci union db_prod32 db_data; 3348c2ecf20Sopenharmony_ci 3358c2ecf20Sopenharmony_ci void __iomem *iwarp_db2; 3368c2ecf20Sopenharmony_ci union db_prod32 iwarp_db2_data; 3378c2ecf20Sopenharmony_ci}; 3388c2ecf20Sopenharmony_ci 3398c2ecf20Sopenharmony_ci#define QEDR_INC_SW_IDX(p_info, index) \ 3408c2ecf20Sopenharmony_ci do { \ 3418c2ecf20Sopenharmony_ci p_info->index = (p_info->index + 1) & \ 3428c2ecf20Sopenharmony_ci qed_chain_get_capacity(p_info->pbl) \ 3438c2ecf20Sopenharmony_ci } while (0) 3448c2ecf20Sopenharmony_ci 3458c2ecf20Sopenharmony_cistruct qedr_srq_hwq_info { 3468c2ecf20Sopenharmony_ci u32 max_sges; 3478c2ecf20Sopenharmony_ci u32 max_wr; 3488c2ecf20Sopenharmony_ci struct qed_chain pbl; 3498c2ecf20Sopenharmony_ci u64 p_phys_addr_tbl; 3508c2ecf20Sopenharmony_ci u32 wqe_prod; 3518c2ecf20Sopenharmony_ci u32 sge_prod; 3528c2ecf20Sopenharmony_ci u32 wr_prod_cnt; 3538c2ecf20Sopenharmony_ci atomic_t wr_cons_cnt; 3548c2ecf20Sopenharmony_ci u32 num_elems; 3558c2ecf20Sopenharmony_ci 3568c2ecf20Sopenharmony_ci struct rdma_srq_producers *virt_prod_pair_addr; 3578c2ecf20Sopenharmony_ci dma_addr_t phy_prod_pair_addr; 3588c2ecf20Sopenharmony_ci}; 3598c2ecf20Sopenharmony_ci 3608c2ecf20Sopenharmony_cistruct qedr_srq { 3618c2ecf20Sopenharmony_ci struct ib_srq ibsrq; 3628c2ecf20Sopenharmony_ci struct qedr_dev *dev; 3638c2ecf20Sopenharmony_ci 3648c2ecf20Sopenharmony_ci struct qedr_userq usrq; 3658c2ecf20Sopenharmony_ci struct qedr_srq_hwq_info hw_srq; 3668c2ecf20Sopenharmony_ci struct ib_umem *prod_umem; 3678c2ecf20Sopenharmony_ci u16 srq_id; 3688c2ecf20Sopenharmony_ci u32 srq_limit; 3698c2ecf20Sopenharmony_ci bool is_xrc; 3708c2ecf20Sopenharmony_ci /* lock to protect srq recv post */ 3718c2ecf20Sopenharmony_ci spinlock_t lock; 3728c2ecf20Sopenharmony_ci}; 3738c2ecf20Sopenharmony_ci 3748c2ecf20Sopenharmony_cienum qedr_qp_err_bitmap { 3758c2ecf20Sopenharmony_ci QEDR_QP_ERR_SQ_FULL = 1, 3768c2ecf20Sopenharmony_ci QEDR_QP_ERR_RQ_FULL = 2, 3778c2ecf20Sopenharmony_ci QEDR_QP_ERR_BAD_SR = 4, 3788c2ecf20Sopenharmony_ci QEDR_QP_ERR_BAD_RR = 8, 3798c2ecf20Sopenharmony_ci QEDR_QP_ERR_SQ_PBL_FULL = 16, 3808c2ecf20Sopenharmony_ci QEDR_QP_ERR_RQ_PBL_FULL = 32, 3818c2ecf20Sopenharmony_ci}; 3828c2ecf20Sopenharmony_ci 3838c2ecf20Sopenharmony_cienum qedr_qp_create_type { 3848c2ecf20Sopenharmony_ci QEDR_QP_CREATE_NONE, 3858c2ecf20Sopenharmony_ci QEDR_QP_CREATE_USER, 3868c2ecf20Sopenharmony_ci QEDR_QP_CREATE_KERNEL, 3878c2ecf20Sopenharmony_ci}; 3888c2ecf20Sopenharmony_ci 3898c2ecf20Sopenharmony_cienum qedr_iwarp_cm_flags { 3908c2ecf20Sopenharmony_ci QEDR_IWARP_CM_WAIT_FOR_CONNECT = BIT(0), 3918c2ecf20Sopenharmony_ci QEDR_IWARP_CM_WAIT_FOR_DISCONNECT = BIT(1), 3928c2ecf20Sopenharmony_ci}; 3938c2ecf20Sopenharmony_ci 3948c2ecf20Sopenharmony_cistruct qedr_qp { 3958c2ecf20Sopenharmony_ci struct ib_qp ibqp; /* must be first */ 3968c2ecf20Sopenharmony_ci struct qedr_dev *dev; 3978c2ecf20Sopenharmony_ci struct qedr_qp_hwq_info sq; 3988c2ecf20Sopenharmony_ci struct qedr_qp_hwq_info rq; 3998c2ecf20Sopenharmony_ci 4008c2ecf20Sopenharmony_ci u32 max_inline_data; 4018c2ecf20Sopenharmony_ci 4028c2ecf20Sopenharmony_ci /* Lock for QP's */ 4038c2ecf20Sopenharmony_ci spinlock_t q_lock; 4048c2ecf20Sopenharmony_ci struct qedr_cq *sq_cq; 4058c2ecf20Sopenharmony_ci struct qedr_cq *rq_cq; 4068c2ecf20Sopenharmony_ci struct qedr_srq *srq; 4078c2ecf20Sopenharmony_ci enum qed_roce_qp_state state; 4088c2ecf20Sopenharmony_ci u32 id; 4098c2ecf20Sopenharmony_ci struct qedr_pd *pd; 4108c2ecf20Sopenharmony_ci enum ib_qp_type qp_type; 4118c2ecf20Sopenharmony_ci enum qedr_qp_create_type create_type; 4128c2ecf20Sopenharmony_ci struct qed_rdma_qp *qed_qp; 4138c2ecf20Sopenharmony_ci u32 qp_id; 4148c2ecf20Sopenharmony_ci u16 icid; 4158c2ecf20Sopenharmony_ci u16 mtu; 4168c2ecf20Sopenharmony_ci int sgid_idx; 4178c2ecf20Sopenharmony_ci u32 rq_psn; 4188c2ecf20Sopenharmony_ci u32 sq_psn; 4198c2ecf20Sopenharmony_ci u32 qkey; 4208c2ecf20Sopenharmony_ci u32 dest_qp_num; 4218c2ecf20Sopenharmony_ci u8 timeout; 4228c2ecf20Sopenharmony_ci 4238c2ecf20Sopenharmony_ci /* Relevant to qps created from kernel space only (ULPs) */ 4248c2ecf20Sopenharmony_ci u8 prev_wqe_size; 4258c2ecf20Sopenharmony_ci u16 wqe_cons; 4268c2ecf20Sopenharmony_ci u32 err_bitmap; 4278c2ecf20Sopenharmony_ci bool signaled; 4288c2ecf20Sopenharmony_ci 4298c2ecf20Sopenharmony_ci /* SQ shadow */ 4308c2ecf20Sopenharmony_ci struct { 4318c2ecf20Sopenharmony_ci u64 wr_id; 4328c2ecf20Sopenharmony_ci enum ib_wc_opcode opcode; 4338c2ecf20Sopenharmony_ci u32 bytes_len; 4348c2ecf20Sopenharmony_ci u8 wqe_size; 4358c2ecf20Sopenharmony_ci bool signaled; 4368c2ecf20Sopenharmony_ci dma_addr_t icrc_mapping; 4378c2ecf20Sopenharmony_ci u32 *icrc; 4388c2ecf20Sopenharmony_ci struct qedr_mr *mr; 4398c2ecf20Sopenharmony_ci } *wqe_wr_id; 4408c2ecf20Sopenharmony_ci 4418c2ecf20Sopenharmony_ci /* RQ shadow */ 4428c2ecf20Sopenharmony_ci struct { 4438c2ecf20Sopenharmony_ci u64 wr_id; 4448c2ecf20Sopenharmony_ci struct ib_sge sg_list[RDMA_MAX_SGE_PER_RQ_WQE]; 4458c2ecf20Sopenharmony_ci u8 wqe_size; 4468c2ecf20Sopenharmony_ci 4478c2ecf20Sopenharmony_ci u8 smac[ETH_ALEN]; 4488c2ecf20Sopenharmony_ci u16 vlan; 4498c2ecf20Sopenharmony_ci int rc; 4508c2ecf20Sopenharmony_ci } *rqe_wr_id; 4518c2ecf20Sopenharmony_ci 4528c2ecf20Sopenharmony_ci /* Relevant to qps created from user space only (applications) */ 4538c2ecf20Sopenharmony_ci struct qedr_userq usq; 4548c2ecf20Sopenharmony_ci struct qedr_userq urq; 4558c2ecf20Sopenharmony_ci 4568c2ecf20Sopenharmony_ci /* synchronization objects used with iwarp ep */ 4578c2ecf20Sopenharmony_ci struct kref refcnt; 4588c2ecf20Sopenharmony_ci struct completion iwarp_cm_comp; 4598c2ecf20Sopenharmony_ci unsigned long iwarp_cm_flags; /* enum iwarp_cm_flags */ 4608c2ecf20Sopenharmony_ci}; 4618c2ecf20Sopenharmony_ci 4628c2ecf20Sopenharmony_cistruct qedr_ah { 4638c2ecf20Sopenharmony_ci struct ib_ah ibah; 4648c2ecf20Sopenharmony_ci struct rdma_ah_attr attr; 4658c2ecf20Sopenharmony_ci}; 4668c2ecf20Sopenharmony_ci 4678c2ecf20Sopenharmony_cienum qedr_mr_type { 4688c2ecf20Sopenharmony_ci QEDR_MR_USER, 4698c2ecf20Sopenharmony_ci QEDR_MR_KERNEL, 4708c2ecf20Sopenharmony_ci QEDR_MR_DMA, 4718c2ecf20Sopenharmony_ci QEDR_MR_FRMR, 4728c2ecf20Sopenharmony_ci}; 4738c2ecf20Sopenharmony_ci 4748c2ecf20Sopenharmony_cistruct mr_info { 4758c2ecf20Sopenharmony_ci struct qedr_pbl *pbl_table; 4768c2ecf20Sopenharmony_ci struct qedr_pbl_info pbl_info; 4778c2ecf20Sopenharmony_ci struct list_head free_pbl_list; 4788c2ecf20Sopenharmony_ci struct list_head inuse_pbl_list; 4798c2ecf20Sopenharmony_ci u32 completed; 4808c2ecf20Sopenharmony_ci u32 completed_handled; 4818c2ecf20Sopenharmony_ci}; 4828c2ecf20Sopenharmony_ci 4838c2ecf20Sopenharmony_cistruct qedr_mr { 4848c2ecf20Sopenharmony_ci struct ib_mr ibmr; 4858c2ecf20Sopenharmony_ci struct ib_umem *umem; 4868c2ecf20Sopenharmony_ci 4878c2ecf20Sopenharmony_ci struct qed_rdma_register_tid_in_params hw_mr; 4888c2ecf20Sopenharmony_ci enum qedr_mr_type type; 4898c2ecf20Sopenharmony_ci 4908c2ecf20Sopenharmony_ci struct qedr_dev *dev; 4918c2ecf20Sopenharmony_ci struct mr_info info; 4928c2ecf20Sopenharmony_ci 4938c2ecf20Sopenharmony_ci u64 *pages; 4948c2ecf20Sopenharmony_ci u32 npages; 4958c2ecf20Sopenharmony_ci}; 4968c2ecf20Sopenharmony_ci 4978c2ecf20Sopenharmony_cistruct qedr_user_mmap_entry { 4988c2ecf20Sopenharmony_ci struct rdma_user_mmap_entry rdma_entry; 4998c2ecf20Sopenharmony_ci struct qedr_dev *dev; 5008c2ecf20Sopenharmony_ci union { 5018c2ecf20Sopenharmony_ci u64 io_address; 5028c2ecf20Sopenharmony_ci void *address; 5038c2ecf20Sopenharmony_ci }; 5048c2ecf20Sopenharmony_ci size_t length; 5058c2ecf20Sopenharmony_ci u16 dpi; 5068c2ecf20Sopenharmony_ci u8 mmap_flag; 5078c2ecf20Sopenharmony_ci}; 5088c2ecf20Sopenharmony_ci 5098c2ecf20Sopenharmony_ci#define SET_FIELD2(value, name, flag) ((value) |= ((flag) << (name ## _SHIFT))) 5108c2ecf20Sopenharmony_ci 5118c2ecf20Sopenharmony_ci#define QEDR_RESP_IMM (RDMA_CQE_RESPONDER_IMM_FLG_MASK << \ 5128c2ecf20Sopenharmony_ci RDMA_CQE_RESPONDER_IMM_FLG_SHIFT) 5138c2ecf20Sopenharmony_ci#define QEDR_RESP_RDMA (RDMA_CQE_RESPONDER_RDMA_FLG_MASK << \ 5148c2ecf20Sopenharmony_ci RDMA_CQE_RESPONDER_RDMA_FLG_SHIFT) 5158c2ecf20Sopenharmony_ci#define QEDR_RESP_INV (RDMA_CQE_RESPONDER_INV_FLG_MASK << \ 5168c2ecf20Sopenharmony_ci RDMA_CQE_RESPONDER_INV_FLG_SHIFT) 5178c2ecf20Sopenharmony_ci 5188c2ecf20Sopenharmony_cistatic inline void qedr_inc_sw_cons(struct qedr_qp_hwq_info *info) 5198c2ecf20Sopenharmony_ci{ 5208c2ecf20Sopenharmony_ci info->cons = (info->cons + 1) % info->max_wr; 5218c2ecf20Sopenharmony_ci info->wqe_cons++; 5228c2ecf20Sopenharmony_ci} 5238c2ecf20Sopenharmony_ci 5248c2ecf20Sopenharmony_cistatic inline void qedr_inc_sw_prod(struct qedr_qp_hwq_info *info) 5258c2ecf20Sopenharmony_ci{ 5268c2ecf20Sopenharmony_ci info->prod = (info->prod + 1) % info->max_wr; 5278c2ecf20Sopenharmony_ci} 5288c2ecf20Sopenharmony_ci 5298c2ecf20Sopenharmony_cistatic inline int qedr_get_dmac(struct qedr_dev *dev, 5308c2ecf20Sopenharmony_ci struct rdma_ah_attr *ah_attr, u8 *mac_addr) 5318c2ecf20Sopenharmony_ci{ 5328c2ecf20Sopenharmony_ci union ib_gid zero_sgid = { { 0 } }; 5338c2ecf20Sopenharmony_ci struct in6_addr in6; 5348c2ecf20Sopenharmony_ci const struct ib_global_route *grh = rdma_ah_read_grh(ah_attr); 5358c2ecf20Sopenharmony_ci u8 *dmac; 5368c2ecf20Sopenharmony_ci 5378c2ecf20Sopenharmony_ci if (!memcmp(&grh->dgid, &zero_sgid, sizeof(union ib_gid))) { 5388c2ecf20Sopenharmony_ci DP_ERR(dev, "Local port GID not supported\n"); 5398c2ecf20Sopenharmony_ci eth_zero_addr(mac_addr); 5408c2ecf20Sopenharmony_ci return -EINVAL; 5418c2ecf20Sopenharmony_ci } 5428c2ecf20Sopenharmony_ci 5438c2ecf20Sopenharmony_ci memcpy(&in6, grh->dgid.raw, sizeof(in6)); 5448c2ecf20Sopenharmony_ci dmac = rdma_ah_retrieve_dmac(ah_attr); 5458c2ecf20Sopenharmony_ci if (!dmac) 5468c2ecf20Sopenharmony_ci return -EINVAL; 5478c2ecf20Sopenharmony_ci ether_addr_copy(mac_addr, dmac); 5488c2ecf20Sopenharmony_ci 5498c2ecf20Sopenharmony_ci return 0; 5508c2ecf20Sopenharmony_ci} 5518c2ecf20Sopenharmony_ci 5528c2ecf20Sopenharmony_cistruct qedr_iw_listener { 5538c2ecf20Sopenharmony_ci struct qedr_dev *dev; 5548c2ecf20Sopenharmony_ci struct iw_cm_id *cm_id; 5558c2ecf20Sopenharmony_ci int backlog; 5568c2ecf20Sopenharmony_ci void *qed_handle; 5578c2ecf20Sopenharmony_ci}; 5588c2ecf20Sopenharmony_ci 5598c2ecf20Sopenharmony_cistruct qedr_iw_ep { 5608c2ecf20Sopenharmony_ci struct qedr_dev *dev; 5618c2ecf20Sopenharmony_ci struct iw_cm_id *cm_id; 5628c2ecf20Sopenharmony_ci struct qedr_qp *qp; 5638c2ecf20Sopenharmony_ci void *qed_context; 5648c2ecf20Sopenharmony_ci struct kref refcnt; 5658c2ecf20Sopenharmony_ci}; 5668c2ecf20Sopenharmony_ci 5678c2ecf20Sopenharmony_cistatic inline 5688c2ecf20Sopenharmony_cistruct qedr_ucontext *get_qedr_ucontext(struct ib_ucontext *ibucontext) 5698c2ecf20Sopenharmony_ci{ 5708c2ecf20Sopenharmony_ci return container_of(ibucontext, struct qedr_ucontext, ibucontext); 5718c2ecf20Sopenharmony_ci} 5728c2ecf20Sopenharmony_ci 5738c2ecf20Sopenharmony_cistatic inline struct qedr_dev *get_qedr_dev(struct ib_device *ibdev) 5748c2ecf20Sopenharmony_ci{ 5758c2ecf20Sopenharmony_ci return container_of(ibdev, struct qedr_dev, ibdev); 5768c2ecf20Sopenharmony_ci} 5778c2ecf20Sopenharmony_ci 5788c2ecf20Sopenharmony_cistatic inline struct qedr_pd *get_qedr_pd(struct ib_pd *ibpd) 5798c2ecf20Sopenharmony_ci{ 5808c2ecf20Sopenharmony_ci return container_of(ibpd, struct qedr_pd, ibpd); 5818c2ecf20Sopenharmony_ci} 5828c2ecf20Sopenharmony_ci 5838c2ecf20Sopenharmony_cistatic inline struct qedr_xrcd *get_qedr_xrcd(struct ib_xrcd *ibxrcd) 5848c2ecf20Sopenharmony_ci{ 5858c2ecf20Sopenharmony_ci return container_of(ibxrcd, struct qedr_xrcd, ibxrcd); 5868c2ecf20Sopenharmony_ci} 5878c2ecf20Sopenharmony_ci 5888c2ecf20Sopenharmony_cistatic inline struct qedr_cq *get_qedr_cq(struct ib_cq *ibcq) 5898c2ecf20Sopenharmony_ci{ 5908c2ecf20Sopenharmony_ci return container_of(ibcq, struct qedr_cq, ibcq); 5918c2ecf20Sopenharmony_ci} 5928c2ecf20Sopenharmony_ci 5938c2ecf20Sopenharmony_cistatic inline struct qedr_qp *get_qedr_qp(struct ib_qp *ibqp) 5948c2ecf20Sopenharmony_ci{ 5958c2ecf20Sopenharmony_ci return container_of(ibqp, struct qedr_qp, ibqp); 5968c2ecf20Sopenharmony_ci} 5978c2ecf20Sopenharmony_ci 5988c2ecf20Sopenharmony_cistatic inline struct qedr_ah *get_qedr_ah(struct ib_ah *ibah) 5998c2ecf20Sopenharmony_ci{ 6008c2ecf20Sopenharmony_ci return container_of(ibah, struct qedr_ah, ibah); 6018c2ecf20Sopenharmony_ci} 6028c2ecf20Sopenharmony_ci 6038c2ecf20Sopenharmony_cistatic inline struct qedr_mr *get_qedr_mr(struct ib_mr *ibmr) 6048c2ecf20Sopenharmony_ci{ 6058c2ecf20Sopenharmony_ci return container_of(ibmr, struct qedr_mr, ibmr); 6068c2ecf20Sopenharmony_ci} 6078c2ecf20Sopenharmony_ci 6088c2ecf20Sopenharmony_cistatic inline struct qedr_srq *get_qedr_srq(struct ib_srq *ibsrq) 6098c2ecf20Sopenharmony_ci{ 6108c2ecf20Sopenharmony_ci return container_of(ibsrq, struct qedr_srq, ibsrq); 6118c2ecf20Sopenharmony_ci} 6128c2ecf20Sopenharmony_ci 6138c2ecf20Sopenharmony_cistatic inline bool qedr_qp_has_srq(struct qedr_qp *qp) 6148c2ecf20Sopenharmony_ci{ 6158c2ecf20Sopenharmony_ci return qp->srq; 6168c2ecf20Sopenharmony_ci} 6178c2ecf20Sopenharmony_ci 6188c2ecf20Sopenharmony_cistatic inline bool qedr_qp_has_sq(struct qedr_qp *qp) 6198c2ecf20Sopenharmony_ci{ 6208c2ecf20Sopenharmony_ci if (qp->qp_type == IB_QPT_GSI || qp->qp_type == IB_QPT_XRC_TGT) 6218c2ecf20Sopenharmony_ci return 0; 6228c2ecf20Sopenharmony_ci 6238c2ecf20Sopenharmony_ci return 1; 6248c2ecf20Sopenharmony_ci} 6258c2ecf20Sopenharmony_ci 6268c2ecf20Sopenharmony_cistatic inline bool qedr_qp_has_rq(struct qedr_qp *qp) 6278c2ecf20Sopenharmony_ci{ 6288c2ecf20Sopenharmony_ci if (qp->qp_type == IB_QPT_GSI || qp->qp_type == IB_QPT_XRC_INI || 6298c2ecf20Sopenharmony_ci qp->qp_type == IB_QPT_XRC_TGT || qedr_qp_has_srq(qp)) 6308c2ecf20Sopenharmony_ci return 0; 6318c2ecf20Sopenharmony_ci 6328c2ecf20Sopenharmony_ci return 1; 6338c2ecf20Sopenharmony_ci} 6348c2ecf20Sopenharmony_ci 6358c2ecf20Sopenharmony_cistatic inline struct qedr_user_mmap_entry * 6368c2ecf20Sopenharmony_ciget_qedr_mmap_entry(struct rdma_user_mmap_entry *rdma_entry) 6378c2ecf20Sopenharmony_ci{ 6388c2ecf20Sopenharmony_ci return container_of(rdma_entry, struct qedr_user_mmap_entry, 6398c2ecf20Sopenharmony_ci rdma_entry); 6408c2ecf20Sopenharmony_ci} 6418c2ecf20Sopenharmony_ci#endif 642