162306a36Sopenharmony_ci/* This file is part of the Emulex RoCE Device Driver for 262306a36Sopenharmony_ci * RoCE (RDMA over Converged Ethernet) adapters. 362306a36Sopenharmony_ci * Copyright (C) 2012-2015 Emulex. All rights reserved. 462306a36Sopenharmony_ci * EMULEX and SLI are trademarks of Emulex. 562306a36Sopenharmony_ci * www.emulex.com 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * This software is available to you under a choice of one of two licenses. 862306a36Sopenharmony_ci * You may choose to be licensed under the terms of the GNU General Public 962306a36Sopenharmony_ci * License (GPL) Version 2, available from the file COPYING in the main 1062306a36Sopenharmony_ci * directory of this source tree, or the BSD license below: 1162306a36Sopenharmony_ci * 1262306a36Sopenharmony_ci * Redistribution and use in source and binary forms, with or without 1362306a36Sopenharmony_ci * modification, are permitted provided that the following conditions 1462306a36Sopenharmony_ci * are met: 1562306a36Sopenharmony_ci * 1662306a36Sopenharmony_ci * - Redistributions of source code must retain the above copyright notice, 1762306a36Sopenharmony_ci * this list of conditions and the following disclaimer. 1862306a36Sopenharmony_ci * 1962306a36Sopenharmony_ci * - Redistributions in binary form must reproduce the above copyright 2062306a36Sopenharmony_ci * notice, this list of conditions and the following disclaimer in 2162306a36Sopenharmony_ci * the documentation and/or other materials provided with the distribution. 2262306a36Sopenharmony_ci * 2362306a36Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 2462306a36Sopenharmony_ci * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,THE 2562306a36Sopenharmony_ci * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2662306a36Sopenharmony_ci * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 2762306a36Sopenharmony_ci * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2862306a36Sopenharmony_ci * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2962306a36Sopenharmony_ci * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 3062306a36Sopenharmony_ci * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 3162306a36Sopenharmony_ci * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 3262306a36Sopenharmony_ci * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 3362306a36Sopenharmony_ci * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3462306a36Sopenharmony_ci * 3562306a36Sopenharmony_ci * Contact Information: 3662306a36Sopenharmony_ci * linux-drivers@emulex.com 3762306a36Sopenharmony_ci * 3862306a36Sopenharmony_ci * Emulex 3962306a36Sopenharmony_ci * 3333 Susan Street 4062306a36Sopenharmony_ci * Costa Mesa, CA 92626 4162306a36Sopenharmony_ci */ 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci#ifndef __OCRDMA_H__ 4462306a36Sopenharmony_ci#define __OCRDMA_H__ 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci#include <linux/mutex.h> 4762306a36Sopenharmony_ci#include <linux/list.h> 4862306a36Sopenharmony_ci#include <linux/spinlock.h> 4962306a36Sopenharmony_ci#include <linux/pci.h> 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci#include <rdma/ib_verbs.h> 5262306a36Sopenharmony_ci#include <rdma/ib_user_verbs.h> 5362306a36Sopenharmony_ci#include <rdma/ib_addr.h> 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci#include <be_roce.h> 5662306a36Sopenharmony_ci#include "ocrdma_sli.h" 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci#define OCRDMA_ROCE_DRV_VERSION "11.0.0.0" 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_ci#define OCRDMA_ROCE_DRV_DESC "Emulex OneConnect RoCE Driver" 6162306a36Sopenharmony_ci#define OCRDMA_NODE_DESC "Emulex OneConnect RoCE HCA" 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci#define OC_NAME_SH OCRDMA_NODE_DESC "(Skyhawk)" 6462306a36Sopenharmony_ci#define OC_NAME_UNKNOWN OCRDMA_NODE_DESC "(Unknown)" 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci#define OC_SKH_DEVICE_PF 0x720 6762306a36Sopenharmony_ci#define OC_SKH_DEVICE_VF 0x728 6862306a36Sopenharmony_ci#define OCRDMA_MAX_AH 512 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ci#define OCRDMA_UVERBS(CMD_NAME) (1ull << IB_USER_VERBS_CMD_##CMD_NAME) 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci#define convert_to_64bit(lo, hi) ((u64)hi << 32 | (u64)lo) 7362306a36Sopenharmony_ci#define EQ_INTR_PER_SEC_THRSH_HI 150000 7462306a36Sopenharmony_ci#define EQ_INTR_PER_SEC_THRSH_LOW 100000 7562306a36Sopenharmony_ci#define EQ_AIC_MAX_EQD 20 7662306a36Sopenharmony_ci#define EQ_AIC_MIN_EQD 0 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_civoid ocrdma_eqd_set_task(struct work_struct *work); 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_cistruct ocrdma_dev_attr { 8162306a36Sopenharmony_ci u8 fw_ver[32]; 8262306a36Sopenharmony_ci u32 vendor_id; 8362306a36Sopenharmony_ci u32 device_id; 8462306a36Sopenharmony_ci u16 max_pd; 8562306a36Sopenharmony_ci u16 max_dpp_pds; 8662306a36Sopenharmony_ci u16 max_cq; 8762306a36Sopenharmony_ci u16 max_cqe; 8862306a36Sopenharmony_ci u16 max_qp; 8962306a36Sopenharmony_ci u16 max_wqe; 9062306a36Sopenharmony_ci u16 max_rqe; 9162306a36Sopenharmony_ci u16 max_srq; 9262306a36Sopenharmony_ci u32 max_inline_data; 9362306a36Sopenharmony_ci int max_send_sge; 9462306a36Sopenharmony_ci int max_recv_sge; 9562306a36Sopenharmony_ci int max_srq_sge; 9662306a36Sopenharmony_ci int max_rdma_sge; 9762306a36Sopenharmony_ci int max_mr; 9862306a36Sopenharmony_ci u64 max_mr_size; 9962306a36Sopenharmony_ci u32 max_num_mr_pbl; 10062306a36Sopenharmony_ci int max_mw; 10162306a36Sopenharmony_ci int max_map_per_fmr; 10262306a36Sopenharmony_ci int max_pages_per_frmr; 10362306a36Sopenharmony_ci u16 max_ord_per_qp; 10462306a36Sopenharmony_ci u16 max_ird_per_qp; 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_ci int device_cap_flags; 10762306a36Sopenharmony_ci u8 cq_overflow_detect; 10862306a36Sopenharmony_ci u8 srq_supported; 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci u32 wqe_size; 11162306a36Sopenharmony_ci u32 rqe_size; 11262306a36Sopenharmony_ci u32 ird_page_size; 11362306a36Sopenharmony_ci u8 local_ca_ack_delay; 11462306a36Sopenharmony_ci u8 ird; 11562306a36Sopenharmony_ci u8 num_ird_pages; 11662306a36Sopenharmony_ci u8 udp_encap; 11762306a36Sopenharmony_ci}; 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_cistruct ocrdma_dma_mem { 12062306a36Sopenharmony_ci void *va; 12162306a36Sopenharmony_ci dma_addr_t pa; 12262306a36Sopenharmony_ci u32 size; 12362306a36Sopenharmony_ci}; 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_cistruct ocrdma_pbl { 12662306a36Sopenharmony_ci void *va; 12762306a36Sopenharmony_ci dma_addr_t pa; 12862306a36Sopenharmony_ci}; 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_cistruct ocrdma_queue_info { 13162306a36Sopenharmony_ci void *va; 13262306a36Sopenharmony_ci dma_addr_t dma; 13362306a36Sopenharmony_ci u32 size; 13462306a36Sopenharmony_ci u16 len; 13562306a36Sopenharmony_ci u16 entry_size; /* Size of an element in the queue */ 13662306a36Sopenharmony_ci u16 id; /* qid, where to ring the doorbell. */ 13762306a36Sopenharmony_ci u16 head, tail; 13862306a36Sopenharmony_ci bool created; 13962306a36Sopenharmony_ci}; 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_cistruct ocrdma_aic_obj { /* Adaptive interrupt coalescing (AIC) info */ 14262306a36Sopenharmony_ci u32 prev_eqd; 14362306a36Sopenharmony_ci u64 eq_intr_cnt; 14462306a36Sopenharmony_ci u64 prev_eq_intr_cnt; 14562306a36Sopenharmony_ci}; 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_cistruct ocrdma_eq { 14862306a36Sopenharmony_ci struct ocrdma_queue_info q; 14962306a36Sopenharmony_ci u32 vector; 15062306a36Sopenharmony_ci int cq_cnt; 15162306a36Sopenharmony_ci struct ocrdma_dev *dev; 15262306a36Sopenharmony_ci char irq_name[32]; 15362306a36Sopenharmony_ci struct ocrdma_aic_obj aic_obj; 15462306a36Sopenharmony_ci}; 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_cistruct ocrdma_mq { 15762306a36Sopenharmony_ci struct ocrdma_queue_info sq; 15862306a36Sopenharmony_ci struct ocrdma_queue_info cq; 15962306a36Sopenharmony_ci bool rearm_cq; 16062306a36Sopenharmony_ci}; 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_cistruct mqe_ctx { 16362306a36Sopenharmony_ci struct mutex lock; /* for serializing mailbox commands on MQ */ 16462306a36Sopenharmony_ci wait_queue_head_t cmd_wait; 16562306a36Sopenharmony_ci u32 tag; 16662306a36Sopenharmony_ci u16 cqe_status; 16762306a36Sopenharmony_ci u16 ext_status; 16862306a36Sopenharmony_ci bool cmd_done; 16962306a36Sopenharmony_ci bool fw_error_state; 17062306a36Sopenharmony_ci}; 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_cistruct ocrdma_hw_mr { 17362306a36Sopenharmony_ci u32 lkey; 17462306a36Sopenharmony_ci u8 fr_mr; 17562306a36Sopenharmony_ci u8 remote_atomic; 17662306a36Sopenharmony_ci u8 remote_rd; 17762306a36Sopenharmony_ci u8 remote_wr; 17862306a36Sopenharmony_ci u8 local_rd; 17962306a36Sopenharmony_ci u8 local_wr; 18062306a36Sopenharmony_ci u8 mw_bind; 18162306a36Sopenharmony_ci u8 rsvd; 18262306a36Sopenharmony_ci u64 len; 18362306a36Sopenharmony_ci struct ocrdma_pbl *pbl_table; 18462306a36Sopenharmony_ci u32 num_pbls; 18562306a36Sopenharmony_ci u32 num_pbes; 18662306a36Sopenharmony_ci u32 pbl_size; 18762306a36Sopenharmony_ci u32 pbe_size; 18862306a36Sopenharmony_ci u64 va; 18962306a36Sopenharmony_ci}; 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_cistruct ocrdma_mr { 19262306a36Sopenharmony_ci struct ib_mr ibmr; 19362306a36Sopenharmony_ci struct ib_umem *umem; 19462306a36Sopenharmony_ci struct ocrdma_hw_mr hwmr; 19562306a36Sopenharmony_ci u64 *pages; 19662306a36Sopenharmony_ci u32 npages; 19762306a36Sopenharmony_ci}; 19862306a36Sopenharmony_ci 19962306a36Sopenharmony_cistruct ocrdma_stats { 20062306a36Sopenharmony_ci u8 type; 20162306a36Sopenharmony_ci struct ocrdma_dev *dev; 20262306a36Sopenharmony_ci}; 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_cistruct ocrdma_pd_resource_mgr { 20562306a36Sopenharmony_ci u32 pd_norm_start; 20662306a36Sopenharmony_ci u16 pd_norm_count; 20762306a36Sopenharmony_ci u16 pd_norm_thrsh; 20862306a36Sopenharmony_ci u16 max_normal_pd; 20962306a36Sopenharmony_ci u32 pd_dpp_start; 21062306a36Sopenharmony_ci u16 pd_dpp_count; 21162306a36Sopenharmony_ci u16 pd_dpp_thrsh; 21262306a36Sopenharmony_ci u16 max_dpp_pd; 21362306a36Sopenharmony_ci u16 dpp_page_index; 21462306a36Sopenharmony_ci unsigned long *pd_norm_bitmap; 21562306a36Sopenharmony_ci unsigned long *pd_dpp_bitmap; 21662306a36Sopenharmony_ci bool pd_prealloc_valid; 21762306a36Sopenharmony_ci}; 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_cistruct stats_mem { 22062306a36Sopenharmony_ci struct ocrdma_mqe mqe; 22162306a36Sopenharmony_ci void *va; 22262306a36Sopenharmony_ci dma_addr_t pa; 22362306a36Sopenharmony_ci u32 size; 22462306a36Sopenharmony_ci char *debugfs_mem; 22562306a36Sopenharmony_ci}; 22662306a36Sopenharmony_ci 22762306a36Sopenharmony_cistruct phy_info { 22862306a36Sopenharmony_ci u16 auto_speeds_supported; 22962306a36Sopenharmony_ci u16 fixed_speeds_supported; 23062306a36Sopenharmony_ci u16 phy_type; 23162306a36Sopenharmony_ci u16 interface_type; 23262306a36Sopenharmony_ci}; 23362306a36Sopenharmony_ci 23462306a36Sopenharmony_cienum ocrdma_flags { 23562306a36Sopenharmony_ci OCRDMA_FLAGS_LINK_STATUS_INIT = 0x01 23662306a36Sopenharmony_ci}; 23762306a36Sopenharmony_ci 23862306a36Sopenharmony_cistruct ocrdma_dev { 23962306a36Sopenharmony_ci struct ib_device ibdev; 24062306a36Sopenharmony_ci struct ocrdma_dev_attr attr; 24162306a36Sopenharmony_ci 24262306a36Sopenharmony_ci struct mutex dev_lock; /* provides syncronise access to device data */ 24362306a36Sopenharmony_ci spinlock_t flush_q_lock ____cacheline_aligned; 24462306a36Sopenharmony_ci 24562306a36Sopenharmony_ci struct ocrdma_cq **cq_tbl; 24662306a36Sopenharmony_ci struct ocrdma_qp **qp_tbl; 24762306a36Sopenharmony_ci 24862306a36Sopenharmony_ci struct ocrdma_eq *eq_tbl; 24962306a36Sopenharmony_ci int eq_cnt; 25062306a36Sopenharmony_ci struct delayed_work eqd_work; 25162306a36Sopenharmony_ci u16 base_eqid; 25262306a36Sopenharmony_ci u16 max_eq; 25362306a36Sopenharmony_ci 25462306a36Sopenharmony_ci /* provided synchronization to sgid table for 25562306a36Sopenharmony_ci * updating gid entries triggered by notifier. 25662306a36Sopenharmony_ci */ 25762306a36Sopenharmony_ci spinlock_t sgid_lock; 25862306a36Sopenharmony_ci 25962306a36Sopenharmony_ci int gsi_qp_created; 26062306a36Sopenharmony_ci struct ocrdma_cq *gsi_sqcq; 26162306a36Sopenharmony_ci struct ocrdma_cq *gsi_rqcq; 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_ci struct { 26462306a36Sopenharmony_ci struct ocrdma_av *va; 26562306a36Sopenharmony_ci dma_addr_t pa; 26662306a36Sopenharmony_ci u32 size; 26762306a36Sopenharmony_ci u32 num_ah; 26862306a36Sopenharmony_ci /* provide synchronization for av 26962306a36Sopenharmony_ci * entry allocations. 27062306a36Sopenharmony_ci */ 27162306a36Sopenharmony_ci spinlock_t lock; 27262306a36Sopenharmony_ci u32 ahid; 27362306a36Sopenharmony_ci struct ocrdma_pbl pbl; 27462306a36Sopenharmony_ci } av_tbl; 27562306a36Sopenharmony_ci 27662306a36Sopenharmony_ci void *mbx_cmd; 27762306a36Sopenharmony_ci struct ocrdma_mq mq; 27862306a36Sopenharmony_ci struct mqe_ctx mqe_ctx; 27962306a36Sopenharmony_ci 28062306a36Sopenharmony_ci struct be_dev_info nic_info; 28162306a36Sopenharmony_ci struct phy_info phy; 28262306a36Sopenharmony_ci char model_number[32]; 28362306a36Sopenharmony_ci u32 hba_port_num; 28462306a36Sopenharmony_ci 28562306a36Sopenharmony_ci struct list_head entry; 28662306a36Sopenharmony_ci int id; 28762306a36Sopenharmony_ci u64 *stag_arr; 28862306a36Sopenharmony_ci u8 sl; /* service level */ 28962306a36Sopenharmony_ci bool pfc_state; 29062306a36Sopenharmony_ci atomic_t update_sl; 29162306a36Sopenharmony_ci u16 pvid; 29262306a36Sopenharmony_ci u32 asic_id; 29362306a36Sopenharmony_ci u32 flags; 29462306a36Sopenharmony_ci 29562306a36Sopenharmony_ci ulong last_stats_time; 29662306a36Sopenharmony_ci struct mutex stats_lock; /* provide synch for debugfs operations */ 29762306a36Sopenharmony_ci struct stats_mem stats_mem; 29862306a36Sopenharmony_ci struct ocrdma_stats rsrc_stats; 29962306a36Sopenharmony_ci struct ocrdma_stats rx_stats; 30062306a36Sopenharmony_ci struct ocrdma_stats wqe_stats; 30162306a36Sopenharmony_ci struct ocrdma_stats tx_stats; 30262306a36Sopenharmony_ci struct ocrdma_stats db_err_stats; 30362306a36Sopenharmony_ci struct ocrdma_stats tx_qp_err_stats; 30462306a36Sopenharmony_ci struct ocrdma_stats rx_qp_err_stats; 30562306a36Sopenharmony_ci struct ocrdma_stats tx_dbg_stats; 30662306a36Sopenharmony_ci struct ocrdma_stats rx_dbg_stats; 30762306a36Sopenharmony_ci struct ocrdma_stats driver_stats; 30862306a36Sopenharmony_ci struct ocrdma_stats reset_stats; 30962306a36Sopenharmony_ci struct dentry *dir; 31062306a36Sopenharmony_ci atomic_t async_err_stats[OCRDMA_MAX_ASYNC_ERRORS]; 31162306a36Sopenharmony_ci atomic_t cqe_err_stats[OCRDMA_MAX_CQE_ERR]; 31262306a36Sopenharmony_ci struct ocrdma_pd_resource_mgr *pd_mgr; 31362306a36Sopenharmony_ci}; 31462306a36Sopenharmony_ci 31562306a36Sopenharmony_cistruct ocrdma_cq { 31662306a36Sopenharmony_ci struct ib_cq ibcq; 31762306a36Sopenharmony_ci struct ocrdma_cqe *va; 31862306a36Sopenharmony_ci u32 phase; 31962306a36Sopenharmony_ci u32 getp; /* pointer to pending wrs to 32062306a36Sopenharmony_ci * return to stack, wrap arounds 32162306a36Sopenharmony_ci * at max_hw_cqe 32262306a36Sopenharmony_ci */ 32362306a36Sopenharmony_ci u32 max_hw_cqe; 32462306a36Sopenharmony_ci bool phase_change; 32562306a36Sopenharmony_ci spinlock_t cq_lock ____cacheline_aligned; /* provide synchronization 32662306a36Sopenharmony_ci * to cq polling 32762306a36Sopenharmony_ci */ 32862306a36Sopenharmony_ci /* syncronizes cq completion handler invoked from multiple context */ 32962306a36Sopenharmony_ci spinlock_t comp_handler_lock ____cacheline_aligned; 33062306a36Sopenharmony_ci u16 id; 33162306a36Sopenharmony_ci u16 eqn; 33262306a36Sopenharmony_ci 33362306a36Sopenharmony_ci struct ocrdma_ucontext *ucontext; 33462306a36Sopenharmony_ci dma_addr_t pa; 33562306a36Sopenharmony_ci u32 len; 33662306a36Sopenharmony_ci u32 cqe_cnt; 33762306a36Sopenharmony_ci 33862306a36Sopenharmony_ci /* head of all qp's sq and rq for which cqes need to be flushed 33962306a36Sopenharmony_ci * by the software. 34062306a36Sopenharmony_ci */ 34162306a36Sopenharmony_ci struct list_head sq_head, rq_head; 34262306a36Sopenharmony_ci}; 34362306a36Sopenharmony_ci 34462306a36Sopenharmony_cistruct ocrdma_pd { 34562306a36Sopenharmony_ci struct ib_pd ibpd; 34662306a36Sopenharmony_ci struct ocrdma_ucontext *uctx; 34762306a36Sopenharmony_ci u32 id; 34862306a36Sopenharmony_ci int num_dpp_qp; 34962306a36Sopenharmony_ci u32 dpp_page; 35062306a36Sopenharmony_ci bool dpp_enabled; 35162306a36Sopenharmony_ci}; 35262306a36Sopenharmony_ci 35362306a36Sopenharmony_cistruct ocrdma_ah { 35462306a36Sopenharmony_ci struct ib_ah ibah; 35562306a36Sopenharmony_ci struct ocrdma_av *av; 35662306a36Sopenharmony_ci u16 sgid_index; 35762306a36Sopenharmony_ci u32 id; 35862306a36Sopenharmony_ci u8 hdr_type; 35962306a36Sopenharmony_ci}; 36062306a36Sopenharmony_ci 36162306a36Sopenharmony_cistruct ocrdma_qp_hwq_info { 36262306a36Sopenharmony_ci u8 *va; /* virtual address */ 36362306a36Sopenharmony_ci u32 max_sges; 36462306a36Sopenharmony_ci u32 head, tail; 36562306a36Sopenharmony_ci u32 entry_size; 36662306a36Sopenharmony_ci u32 max_cnt; 36762306a36Sopenharmony_ci u32 max_wqe_idx; 36862306a36Sopenharmony_ci u16 dbid; /* qid, where to ring the doorbell. */ 36962306a36Sopenharmony_ci u32 len; 37062306a36Sopenharmony_ci dma_addr_t pa; 37162306a36Sopenharmony_ci}; 37262306a36Sopenharmony_ci 37362306a36Sopenharmony_cistruct ocrdma_srq { 37462306a36Sopenharmony_ci struct ib_srq ibsrq; 37562306a36Sopenharmony_ci u8 __iomem *db; 37662306a36Sopenharmony_ci struct ocrdma_qp_hwq_info rq; 37762306a36Sopenharmony_ci u64 *rqe_wr_id_tbl; 37862306a36Sopenharmony_ci u32 *idx_bit_fields; 37962306a36Sopenharmony_ci u32 bit_fields_len; 38062306a36Sopenharmony_ci 38162306a36Sopenharmony_ci /* provide synchronization to multiple context(s) posting rqe */ 38262306a36Sopenharmony_ci spinlock_t q_lock ____cacheline_aligned; 38362306a36Sopenharmony_ci 38462306a36Sopenharmony_ci struct ocrdma_pd *pd; 38562306a36Sopenharmony_ci u32 id; 38662306a36Sopenharmony_ci}; 38762306a36Sopenharmony_ci 38862306a36Sopenharmony_cistruct ocrdma_qp { 38962306a36Sopenharmony_ci struct ib_qp ibqp; 39062306a36Sopenharmony_ci 39162306a36Sopenharmony_ci u8 __iomem *sq_db; 39262306a36Sopenharmony_ci struct ocrdma_qp_hwq_info sq; 39362306a36Sopenharmony_ci struct { 39462306a36Sopenharmony_ci uint64_t wrid; 39562306a36Sopenharmony_ci uint16_t dpp_wqe_idx; 39662306a36Sopenharmony_ci uint16_t dpp_wqe; 39762306a36Sopenharmony_ci uint8_t signaled; 39862306a36Sopenharmony_ci uint8_t rsvd[3]; 39962306a36Sopenharmony_ci } *wqe_wr_id_tbl; 40062306a36Sopenharmony_ci u32 max_inline_data; 40162306a36Sopenharmony_ci 40262306a36Sopenharmony_ci /* provide synchronization to multiple context(s) posting wqe, rqe */ 40362306a36Sopenharmony_ci spinlock_t q_lock ____cacheline_aligned; 40462306a36Sopenharmony_ci struct ocrdma_cq *sq_cq; 40562306a36Sopenharmony_ci /* list maintained per CQ to flush SQ errors */ 40662306a36Sopenharmony_ci struct list_head sq_entry; 40762306a36Sopenharmony_ci 40862306a36Sopenharmony_ci u8 __iomem *rq_db; 40962306a36Sopenharmony_ci struct ocrdma_qp_hwq_info rq; 41062306a36Sopenharmony_ci u64 *rqe_wr_id_tbl; 41162306a36Sopenharmony_ci struct ocrdma_cq *rq_cq; 41262306a36Sopenharmony_ci struct ocrdma_srq *srq; 41362306a36Sopenharmony_ci /* list maintained per CQ to flush RQ errors */ 41462306a36Sopenharmony_ci struct list_head rq_entry; 41562306a36Sopenharmony_ci 41662306a36Sopenharmony_ci enum ocrdma_qp_state state; /* QP state */ 41762306a36Sopenharmony_ci int cap_flags; 41862306a36Sopenharmony_ci u32 max_ord, max_ird; 41962306a36Sopenharmony_ci 42062306a36Sopenharmony_ci u32 id; 42162306a36Sopenharmony_ci struct ocrdma_pd *pd; 42262306a36Sopenharmony_ci 42362306a36Sopenharmony_ci enum ib_qp_type qp_type; 42462306a36Sopenharmony_ci 42562306a36Sopenharmony_ci int sgid_idx; 42662306a36Sopenharmony_ci u32 qkey; 42762306a36Sopenharmony_ci bool dpp_enabled; 42862306a36Sopenharmony_ci u8 *ird_q_va; 42962306a36Sopenharmony_ci bool signaled; 43062306a36Sopenharmony_ci}; 43162306a36Sopenharmony_ci 43262306a36Sopenharmony_cistruct ocrdma_ucontext { 43362306a36Sopenharmony_ci struct ib_ucontext ibucontext; 43462306a36Sopenharmony_ci 43562306a36Sopenharmony_ci struct list_head mm_head; 43662306a36Sopenharmony_ci struct mutex mm_list_lock; /* protects list entries of mm type */ 43762306a36Sopenharmony_ci struct ocrdma_pd *cntxt_pd; 43862306a36Sopenharmony_ci int pd_in_use; 43962306a36Sopenharmony_ci 44062306a36Sopenharmony_ci struct { 44162306a36Sopenharmony_ci u32 *va; 44262306a36Sopenharmony_ci dma_addr_t pa; 44362306a36Sopenharmony_ci u32 len; 44462306a36Sopenharmony_ci } ah_tbl; 44562306a36Sopenharmony_ci}; 44662306a36Sopenharmony_ci 44762306a36Sopenharmony_cistruct ocrdma_mm { 44862306a36Sopenharmony_ci struct { 44962306a36Sopenharmony_ci u64 phy_addr; 45062306a36Sopenharmony_ci unsigned long len; 45162306a36Sopenharmony_ci } key; 45262306a36Sopenharmony_ci struct list_head entry; 45362306a36Sopenharmony_ci}; 45462306a36Sopenharmony_ci 45562306a36Sopenharmony_cistatic inline struct ocrdma_dev *get_ocrdma_dev(struct ib_device *ibdev) 45662306a36Sopenharmony_ci{ 45762306a36Sopenharmony_ci return container_of(ibdev, struct ocrdma_dev, ibdev); 45862306a36Sopenharmony_ci} 45962306a36Sopenharmony_ci 46062306a36Sopenharmony_cistatic inline struct ocrdma_ucontext *get_ocrdma_ucontext(struct ib_ucontext 46162306a36Sopenharmony_ci *ibucontext) 46262306a36Sopenharmony_ci{ 46362306a36Sopenharmony_ci return container_of(ibucontext, struct ocrdma_ucontext, ibucontext); 46462306a36Sopenharmony_ci} 46562306a36Sopenharmony_ci 46662306a36Sopenharmony_cistatic inline struct ocrdma_pd *get_ocrdma_pd(struct ib_pd *ibpd) 46762306a36Sopenharmony_ci{ 46862306a36Sopenharmony_ci return container_of(ibpd, struct ocrdma_pd, ibpd); 46962306a36Sopenharmony_ci} 47062306a36Sopenharmony_ci 47162306a36Sopenharmony_cistatic inline struct ocrdma_cq *get_ocrdma_cq(struct ib_cq *ibcq) 47262306a36Sopenharmony_ci{ 47362306a36Sopenharmony_ci return container_of(ibcq, struct ocrdma_cq, ibcq); 47462306a36Sopenharmony_ci} 47562306a36Sopenharmony_ci 47662306a36Sopenharmony_cistatic inline struct ocrdma_qp *get_ocrdma_qp(struct ib_qp *ibqp) 47762306a36Sopenharmony_ci{ 47862306a36Sopenharmony_ci return container_of(ibqp, struct ocrdma_qp, ibqp); 47962306a36Sopenharmony_ci} 48062306a36Sopenharmony_ci 48162306a36Sopenharmony_cistatic inline struct ocrdma_mr *get_ocrdma_mr(struct ib_mr *ibmr) 48262306a36Sopenharmony_ci{ 48362306a36Sopenharmony_ci return container_of(ibmr, struct ocrdma_mr, ibmr); 48462306a36Sopenharmony_ci} 48562306a36Sopenharmony_ci 48662306a36Sopenharmony_cistatic inline struct ocrdma_ah *get_ocrdma_ah(struct ib_ah *ibah) 48762306a36Sopenharmony_ci{ 48862306a36Sopenharmony_ci return container_of(ibah, struct ocrdma_ah, ibah); 48962306a36Sopenharmony_ci} 49062306a36Sopenharmony_ci 49162306a36Sopenharmony_cistatic inline struct ocrdma_srq *get_ocrdma_srq(struct ib_srq *ibsrq) 49262306a36Sopenharmony_ci{ 49362306a36Sopenharmony_ci return container_of(ibsrq, struct ocrdma_srq, ibsrq); 49462306a36Sopenharmony_ci} 49562306a36Sopenharmony_ci 49662306a36Sopenharmony_cistatic inline int is_cqe_valid(struct ocrdma_cq *cq, struct ocrdma_cqe *cqe) 49762306a36Sopenharmony_ci{ 49862306a36Sopenharmony_ci int cqe_valid; 49962306a36Sopenharmony_ci cqe_valid = le32_to_cpu(cqe->flags_status_srcqpn) & OCRDMA_CQE_VALID; 50062306a36Sopenharmony_ci return (cqe_valid == cq->phase); 50162306a36Sopenharmony_ci} 50262306a36Sopenharmony_ci 50362306a36Sopenharmony_cistatic inline int is_cqe_for_sq(struct ocrdma_cqe *cqe) 50462306a36Sopenharmony_ci{ 50562306a36Sopenharmony_ci return (le32_to_cpu(cqe->flags_status_srcqpn) & 50662306a36Sopenharmony_ci OCRDMA_CQE_QTYPE) ? 0 : 1; 50762306a36Sopenharmony_ci} 50862306a36Sopenharmony_ci 50962306a36Sopenharmony_cistatic inline int is_cqe_invalidated(struct ocrdma_cqe *cqe) 51062306a36Sopenharmony_ci{ 51162306a36Sopenharmony_ci return (le32_to_cpu(cqe->flags_status_srcqpn) & 51262306a36Sopenharmony_ci OCRDMA_CQE_INVALIDATE) ? 1 : 0; 51362306a36Sopenharmony_ci} 51462306a36Sopenharmony_ci 51562306a36Sopenharmony_cistatic inline int is_cqe_imm(struct ocrdma_cqe *cqe) 51662306a36Sopenharmony_ci{ 51762306a36Sopenharmony_ci return (le32_to_cpu(cqe->flags_status_srcqpn) & 51862306a36Sopenharmony_ci OCRDMA_CQE_IMM) ? 1 : 0; 51962306a36Sopenharmony_ci} 52062306a36Sopenharmony_ci 52162306a36Sopenharmony_cistatic inline int is_cqe_wr_imm(struct ocrdma_cqe *cqe) 52262306a36Sopenharmony_ci{ 52362306a36Sopenharmony_ci return (le32_to_cpu(cqe->flags_status_srcqpn) & 52462306a36Sopenharmony_ci OCRDMA_CQE_WRITE_IMM) ? 1 : 0; 52562306a36Sopenharmony_ci} 52662306a36Sopenharmony_ci 52762306a36Sopenharmony_cistatic inline int ocrdma_resolve_dmac(struct ocrdma_dev *dev, 52862306a36Sopenharmony_ci struct rdma_ah_attr *ah_attr, u8 *mac_addr) 52962306a36Sopenharmony_ci{ 53062306a36Sopenharmony_ci struct in6_addr in6; 53162306a36Sopenharmony_ci 53262306a36Sopenharmony_ci memcpy(&in6, rdma_ah_read_grh(ah_attr)->dgid.raw, sizeof(in6)); 53362306a36Sopenharmony_ci if (rdma_is_multicast_addr(&in6)) 53462306a36Sopenharmony_ci rdma_get_mcast_mac(&in6, mac_addr); 53562306a36Sopenharmony_ci else if (rdma_link_local_addr(&in6)) 53662306a36Sopenharmony_ci rdma_get_ll_mac(&in6, mac_addr); 53762306a36Sopenharmony_ci else 53862306a36Sopenharmony_ci memcpy(mac_addr, ah_attr->roce.dmac, ETH_ALEN); 53962306a36Sopenharmony_ci return 0; 54062306a36Sopenharmony_ci} 54162306a36Sopenharmony_ci 54262306a36Sopenharmony_cistatic inline char *hca_name(struct ocrdma_dev *dev) 54362306a36Sopenharmony_ci{ 54462306a36Sopenharmony_ci switch (dev->nic_info.pdev->device) { 54562306a36Sopenharmony_ci case OC_SKH_DEVICE_PF: 54662306a36Sopenharmony_ci case OC_SKH_DEVICE_VF: 54762306a36Sopenharmony_ci return OC_NAME_SH; 54862306a36Sopenharmony_ci default: 54962306a36Sopenharmony_ci return OC_NAME_UNKNOWN; 55062306a36Sopenharmony_ci } 55162306a36Sopenharmony_ci} 55262306a36Sopenharmony_ci 55362306a36Sopenharmony_cistatic inline int ocrdma_get_eq_table_index(struct ocrdma_dev *dev, 55462306a36Sopenharmony_ci int eqid) 55562306a36Sopenharmony_ci{ 55662306a36Sopenharmony_ci int indx; 55762306a36Sopenharmony_ci 55862306a36Sopenharmony_ci for (indx = 0; indx < dev->eq_cnt; indx++) { 55962306a36Sopenharmony_ci if (dev->eq_tbl[indx].q.id == eqid) 56062306a36Sopenharmony_ci return indx; 56162306a36Sopenharmony_ci } 56262306a36Sopenharmony_ci 56362306a36Sopenharmony_ci return -EINVAL; 56462306a36Sopenharmony_ci} 56562306a36Sopenharmony_ci 56662306a36Sopenharmony_cistatic inline u8 ocrdma_get_asic_type(struct ocrdma_dev *dev) 56762306a36Sopenharmony_ci{ 56862306a36Sopenharmony_ci if (dev->nic_info.dev_family == 0xF && !dev->asic_id) { 56962306a36Sopenharmony_ci pci_read_config_dword( 57062306a36Sopenharmony_ci dev->nic_info.pdev, 57162306a36Sopenharmony_ci OCRDMA_SLI_ASIC_ID_OFFSET, &dev->asic_id); 57262306a36Sopenharmony_ci } 57362306a36Sopenharmony_ci 57462306a36Sopenharmony_ci return (dev->asic_id & OCRDMA_SLI_ASIC_GEN_NUM_MASK) >> 57562306a36Sopenharmony_ci OCRDMA_SLI_ASIC_GEN_NUM_SHIFT; 57662306a36Sopenharmony_ci} 57762306a36Sopenharmony_ci 57862306a36Sopenharmony_cistatic inline u8 ocrdma_get_pfc_prio(u8 *pfc, u8 prio) 57962306a36Sopenharmony_ci{ 58062306a36Sopenharmony_ci return *(pfc + prio); 58162306a36Sopenharmony_ci} 58262306a36Sopenharmony_ci 58362306a36Sopenharmony_cistatic inline u8 ocrdma_get_app_prio(u8 *app_prio, u8 prio) 58462306a36Sopenharmony_ci{ 58562306a36Sopenharmony_ci return *(app_prio + prio); 58662306a36Sopenharmony_ci} 58762306a36Sopenharmony_ci 58862306a36Sopenharmony_cistatic inline u8 ocrdma_is_enabled_and_synced(u32 state) 58962306a36Sopenharmony_ci{ /* May also be used to interpret TC-state, QCN-state 59062306a36Sopenharmony_ci * Appl-state and Logical-link-state in future. 59162306a36Sopenharmony_ci */ 59262306a36Sopenharmony_ci return (state & OCRDMA_STATE_FLAG_ENABLED) && 59362306a36Sopenharmony_ci (state & OCRDMA_STATE_FLAG_SYNC); 59462306a36Sopenharmony_ci} 59562306a36Sopenharmony_ci 59662306a36Sopenharmony_cistatic inline u8 ocrdma_get_ae_link_state(u32 ae_state) 59762306a36Sopenharmony_ci{ 59862306a36Sopenharmony_ci return ((ae_state & OCRDMA_AE_LSC_LS_MASK) >> OCRDMA_AE_LSC_LS_SHIFT); 59962306a36Sopenharmony_ci} 60062306a36Sopenharmony_ci 60162306a36Sopenharmony_cistatic inline bool ocrdma_is_udp_encap_supported(struct ocrdma_dev *dev) 60262306a36Sopenharmony_ci{ 60362306a36Sopenharmony_ci return (dev->attr.udp_encap & OCRDMA_L3_TYPE_IPV4) || 60462306a36Sopenharmony_ci (dev->attr.udp_encap & OCRDMA_L3_TYPE_IPV6); 60562306a36Sopenharmony_ci} 60662306a36Sopenharmony_ci 60762306a36Sopenharmony_ci#endif 608