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