mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	qedr: Add support for QP verbs
Add support for Queue Pair verbs which adds, deletes, modifies and queries Queue Pairs. Signed-off-by: Rajesh Borundia <rajesh.borundia@cavium.com> Signed-off-by: Ram Amrani <Ram.Amrani@cavium.com> Signed-off-by: Doug Ledford <dledford@redhat.com>
This commit is contained in:
		
							parent
							
								
									a7efd7773e
								
							
						
					
					
						commit
						cecbcddf64
					
				
					 7 changed files with 1320 additions and 1 deletions
				
			
		| 
						 | 
				
			
			@ -48,6 +48,8 @@ MODULE_AUTHOR("QLogic Corporation");
 | 
			
		|||
MODULE_LICENSE("Dual BSD/GPL");
 | 
			
		||||
MODULE_VERSION(QEDR_MODULE_VERSION);
 | 
			
		||||
 | 
			
		||||
#define QEDR_WQ_MULTIPLIER_DFT	(3)
 | 
			
		||||
 | 
			
		||||
void qedr_ib_dispatch_event(struct qedr_dev *dev, u8 port_num,
 | 
			
		||||
			    enum ib_event_type type)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -94,7 +96,11 @@ static int qedr_register_device(struct qedr_dev *dev)
 | 
			
		|||
				     QEDR_UVERBS(CREATE_CQ) |
 | 
			
		||||
				     QEDR_UVERBS(RESIZE_CQ) |
 | 
			
		||||
				     QEDR_UVERBS(DESTROY_CQ) |
 | 
			
		||||
				     QEDR_UVERBS(REQ_NOTIFY_CQ);
 | 
			
		||||
				     QEDR_UVERBS(REQ_NOTIFY_CQ) |
 | 
			
		||||
				     QEDR_UVERBS(CREATE_QP) |
 | 
			
		||||
				     QEDR_UVERBS(MODIFY_QP) |
 | 
			
		||||
				     QEDR_UVERBS(QUERY_QP) |
 | 
			
		||||
				     QEDR_UVERBS(DESTROY_QP);
 | 
			
		||||
 | 
			
		||||
	dev->ibdev.phys_port_cnt = 1;
 | 
			
		||||
	dev->ibdev.num_comp_vectors = dev->num_cnq;
 | 
			
		||||
| 
						 | 
				
			
			@ -120,6 +126,11 @@ static int qedr_register_device(struct qedr_dev *dev)
 | 
			
		|||
	dev->ibdev.resize_cq = qedr_resize_cq;
 | 
			
		||||
	dev->ibdev.req_notify_cq = qedr_arm_cq;
 | 
			
		||||
 | 
			
		||||
	dev->ibdev.create_qp = qedr_create_qp;
 | 
			
		||||
	dev->ibdev.modify_qp = qedr_modify_qp;
 | 
			
		||||
	dev->ibdev.query_qp = qedr_query_qp;
 | 
			
		||||
	dev->ibdev.destroy_qp = qedr_destroy_qp;
 | 
			
		||||
 | 
			
		||||
	dev->ibdev.query_pkey = qedr_query_pkey;
 | 
			
		||||
 | 
			
		||||
	dev->ibdev.dma_device = &dev->pdev->dev;
 | 
			
		||||
| 
						 | 
				
			
			@ -630,6 +641,8 @@ static struct qedr_dev *qedr_add(struct qed_dev *cdev, struct pci_dev *pdev,
 | 
			
		|||
		goto init_err;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	dev->wq_multiplier = QEDR_WQ_MULTIPLIER_DFT;
 | 
			
		||||
 | 
			
		||||
	qedr_pci_set_atomic(dev, pdev);
 | 
			
		||||
 | 
			
		||||
	rc = qedr_alloc_resources(dev);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -52,6 +52,9 @@
 | 
			
		|||
#define QEDR_MSG_MISC "MISC"
 | 
			
		||||
#define QEDR_MSG_CQ   "  CQ"
 | 
			
		||||
#define QEDR_MSG_MR   "  MR"
 | 
			
		||||
#define QEDR_MSG_RQ   "  RQ"
 | 
			
		||||
#define QEDR_MSG_SQ   "  SQ"
 | 
			
		||||
#define QEDR_MSG_QP   "  QP"
 | 
			
		||||
 | 
			
		||||
#define QEDR_CQ_MAGIC_NUMBER   (0x11223344)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -143,6 +146,8 @@ struct qedr_dev {
 | 
			
		|||
	u32			dp_module;
 | 
			
		||||
	u8			dp_level;
 | 
			
		||||
	u8			num_hwfns;
 | 
			
		||||
	uint			wq_multiplier;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define QEDR_MAX_SQ_PBL			(0x8000)
 | 
			
		||||
| 
						 | 
				
			
			@ -272,6 +277,122 @@ struct qedr_mm {
 | 
			
		|||
	struct list_head entry;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
union db_prod32 {
 | 
			
		||||
	struct rdma_pwm_val16_data data;
 | 
			
		||||
	u32 raw;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct qedr_qp_hwq_info {
 | 
			
		||||
	/* WQE Elements */
 | 
			
		||||
	struct qed_chain pbl;
 | 
			
		||||
	u64 p_phys_addr_tbl;
 | 
			
		||||
	u32 max_sges;
 | 
			
		||||
 | 
			
		||||
	/* WQE */
 | 
			
		||||
	u16 prod;
 | 
			
		||||
	u16 cons;
 | 
			
		||||
	u16 wqe_cons;
 | 
			
		||||
	u16 max_wr;
 | 
			
		||||
 | 
			
		||||
	/* DB */
 | 
			
		||||
	void __iomem *db;
 | 
			
		||||
	union db_prod32 db_data;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define QEDR_INC_SW_IDX(p_info, index)					\
 | 
			
		||||
	do {								\
 | 
			
		||||
		p_info->index = (p_info->index + 1) &			\
 | 
			
		||||
				qed_chain_get_capacity(p_info->pbl)	\
 | 
			
		||||
	} while (0)
 | 
			
		||||
 | 
			
		||||
enum qedr_qp_err_bitmap {
 | 
			
		||||
	QEDR_QP_ERR_SQ_FULL = 1,
 | 
			
		||||
	QEDR_QP_ERR_RQ_FULL = 2,
 | 
			
		||||
	QEDR_QP_ERR_BAD_SR = 4,
 | 
			
		||||
	QEDR_QP_ERR_BAD_RR = 8,
 | 
			
		||||
	QEDR_QP_ERR_SQ_PBL_FULL = 16,
 | 
			
		||||
	QEDR_QP_ERR_RQ_PBL_FULL = 32,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct qedr_qp {
 | 
			
		||||
	struct ib_qp ibqp;	/* must be first */
 | 
			
		||||
	struct qedr_dev *dev;
 | 
			
		||||
 | 
			
		||||
	struct qedr_qp_hwq_info sq;
 | 
			
		||||
	struct qedr_qp_hwq_info rq;
 | 
			
		||||
 | 
			
		||||
	u32 max_inline_data;
 | 
			
		||||
 | 
			
		||||
	/* Lock for QP's */
 | 
			
		||||
	spinlock_t q_lock;
 | 
			
		||||
	struct qedr_cq *sq_cq;
 | 
			
		||||
	struct qedr_cq *rq_cq;
 | 
			
		||||
	struct qedr_srq *srq;
 | 
			
		||||
	enum qed_roce_qp_state state;
 | 
			
		||||
	u32 id;
 | 
			
		||||
	struct qedr_pd *pd;
 | 
			
		||||
	enum ib_qp_type qp_type;
 | 
			
		||||
	struct qed_rdma_qp *qed_qp;
 | 
			
		||||
	u32 qp_id;
 | 
			
		||||
	u16 icid;
 | 
			
		||||
	u16 mtu;
 | 
			
		||||
	int sgid_idx;
 | 
			
		||||
	u32 rq_psn;
 | 
			
		||||
	u32 sq_psn;
 | 
			
		||||
	u32 qkey;
 | 
			
		||||
	u32 dest_qp_num;
 | 
			
		||||
 | 
			
		||||
	/* Relevant to qps created from kernel space only (ULPs) */
 | 
			
		||||
	u8 prev_wqe_size;
 | 
			
		||||
	u16 wqe_cons;
 | 
			
		||||
	u32 err_bitmap;
 | 
			
		||||
	bool signaled;
 | 
			
		||||
 | 
			
		||||
	/* SQ shadow */
 | 
			
		||||
	struct {
 | 
			
		||||
		u64 wr_id;
 | 
			
		||||
		enum ib_wc_opcode opcode;
 | 
			
		||||
		u32 bytes_len;
 | 
			
		||||
		u8 wqe_size;
 | 
			
		||||
		bool signaled;
 | 
			
		||||
		dma_addr_t icrc_mapping;
 | 
			
		||||
		u32 *icrc;
 | 
			
		||||
		struct qedr_mr *mr;
 | 
			
		||||
	} *wqe_wr_id;
 | 
			
		||||
 | 
			
		||||
	/* RQ shadow */
 | 
			
		||||
	struct {
 | 
			
		||||
		u64 wr_id;
 | 
			
		||||
		struct ib_sge sg_list[RDMA_MAX_SGE_PER_RQ_WQE];
 | 
			
		||||
		u8 wqe_size;
 | 
			
		||||
 | 
			
		||||
		u16 vlan_id;
 | 
			
		||||
		int rc;
 | 
			
		||||
	} *rqe_wr_id;
 | 
			
		||||
 | 
			
		||||
	/* Relevant to qps created from user space only (applications) */
 | 
			
		||||
	struct qedr_userq usq;
 | 
			
		||||
	struct qedr_userq urq;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static inline int qedr_get_dmac(struct qedr_dev *dev,
 | 
			
		||||
				struct ib_ah_attr *ah_attr, u8 *mac_addr)
 | 
			
		||||
{
 | 
			
		||||
	union ib_gid zero_sgid = { { 0 } };
 | 
			
		||||
	struct in6_addr in6;
 | 
			
		||||
 | 
			
		||||
	if (!memcmp(&ah_attr->grh.dgid, &zero_sgid, sizeof(union ib_gid))) {
 | 
			
		||||
		DP_ERR(dev, "Local port GID not supported\n");
 | 
			
		||||
		eth_zero_addr(mac_addr);
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	memcpy(&in6, ah_attr->grh.dgid.raw, sizeof(in6));
 | 
			
		||||
	ether_addr_copy(mac_addr, ah_attr->dmac);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline
 | 
			
		||||
struct qedr_ucontext *get_qedr_ucontext(struct ib_ucontext *ibucontext)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -293,4 +414,8 @@ static inline struct qedr_cq *get_qedr_cq(struct ib_cq *ibcq)
 | 
			
		|||
	return container_of(ibcq, struct qedr_cq, ibcq);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline struct qedr_qp *get_qedr_qp(struct ib_qp *ibqp)
 | 
			
		||||
{
 | 
			
		||||
	return container_of(ibqp, struct qedr_qp, ibqp);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										40
									
								
								drivers/infiniband/hw/qedr/qedr_cm.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								drivers/infiniband/hw/qedr/qedr_cm.h
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,40 @@
 | 
			
		|||
/* QLogic qedr NIC Driver
 | 
			
		||||
 * Copyright (c) 2015-2016  QLogic Corporation
 | 
			
		||||
 *
 | 
			
		||||
 * This software is available to you under a choice of one of two
 | 
			
		||||
 * licenses.  You may choose to be licensed under the terms of the GNU
 | 
			
		||||
 * General Public License (GPL) Version 2, available from the file
 | 
			
		||||
 * COPYING in the main directory of this source tree, or the
 | 
			
		||||
 * OpenIB.org BSD license below:
 | 
			
		||||
 *
 | 
			
		||||
 *     Redistribution and use in source and binary forms, with or
 | 
			
		||||
 *     without modification, are permitted provided that the following
 | 
			
		||||
 *     conditions are met:
 | 
			
		||||
 *
 | 
			
		||||
 *      - Redistributions of source code must retain the above
 | 
			
		||||
 *        copyright notice, this list of conditions and the following
 | 
			
		||||
 *        disclaimer.
 | 
			
		||||
 *
 | 
			
		||||
 *      - Redistributions in binary form must reproduce the above
 | 
			
		||||
 *        copyright notice, this list of conditions and the following
 | 
			
		||||
 *        disclaimer in the documentation and /or other materials
 | 
			
		||||
 *        provided with the distribution.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | 
			
		||||
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
			
		||||
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 | 
			
		||||
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 | 
			
		||||
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 | 
			
		||||
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
			
		||||
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
			
		||||
 * SOFTWARE.
 | 
			
		||||
 */
 | 
			
		||||
#ifndef LINUX_QEDR_CM_H_
 | 
			
		||||
#define LINUX_QEDR_CM_H_
 | 
			
		||||
 | 
			
		||||
static inline u32 qedr_get_ipv4_from_gid(u8 *gid)
 | 
			
		||||
{
 | 
			
		||||
	return *(u32 *)(void *)&gid[12];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -158,6 +158,17 @@ struct rdma_srq_sge {
 | 
			
		|||
	__le32 l_key;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Rdma doorbell data for SQ and RQ */
 | 
			
		||||
struct rdma_pwm_val16_data {
 | 
			
		||||
	__le16 icid;
 | 
			
		||||
	__le16 value;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
union rdma_pwm_val16_data_union {
 | 
			
		||||
	struct rdma_pwm_val16_data as_struct;
 | 
			
		||||
	__le32 as_dword;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Rdma doorbell data for CQ */
 | 
			
		||||
struct rdma_pwm_val32_data {
 | 
			
		||||
	__le16 icid;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
				
			
			@ -62,5 +62,12 @@ struct ib_cq *qedr_create_cq(struct ib_device *ibdev,
 | 
			
		|||
int qedr_resize_cq(struct ib_cq *, int cqe, struct ib_udata *);
 | 
			
		||||
int qedr_destroy_cq(struct ib_cq *);
 | 
			
		||||
int qedr_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags);
 | 
			
		||||
struct ib_qp *qedr_create_qp(struct ib_pd *, struct ib_qp_init_attr *attrs,
 | 
			
		||||
			     struct ib_udata *);
 | 
			
		||||
int qedr_modify_qp(struct ib_qp *, struct ib_qp_attr *attr,
 | 
			
		||||
		   int attr_mask, struct ib_udata *udata);
 | 
			
		||||
int qedr_query_qp(struct ib_qp *, struct ib_qp_attr *qp_attr,
 | 
			
		||||
		  int qp_attr_mask, struct ib_qp_init_attr *);
 | 
			
		||||
int qedr_destroy_qp(struct ib_qp *ibqp);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -69,4 +69,38 @@ struct qedr_create_cq_uresp {
 | 
			
		|||
	__u16 icid;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct qedr_create_qp_ureq {
 | 
			
		||||
	__u32 qp_handle_hi;
 | 
			
		||||
	__u32 qp_handle_lo;
 | 
			
		||||
 | 
			
		||||
	/* SQ */
 | 
			
		||||
	/* user space virtual address of SQ buffer */
 | 
			
		||||
	__u64 sq_addr;
 | 
			
		||||
 | 
			
		||||
	/* length of SQ buffer */
 | 
			
		||||
	__u64 sq_len;
 | 
			
		||||
 | 
			
		||||
	/* RQ */
 | 
			
		||||
	/* user space virtual address of RQ buffer */
 | 
			
		||||
	__u64 rq_addr;
 | 
			
		||||
 | 
			
		||||
	/* length of RQ buffer */
 | 
			
		||||
	__u64 rq_len;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct qedr_create_qp_uresp {
 | 
			
		||||
	__u32 qp_id;
 | 
			
		||||
	__u32 atomic_supported;
 | 
			
		||||
 | 
			
		||||
	/* SQ */
 | 
			
		||||
	__u32 sq_db_offset;
 | 
			
		||||
	__u16 sq_icid;
 | 
			
		||||
 | 
			
		||||
	/* RQ */
 | 
			
		||||
	__u32 rq_db_offset;
 | 
			
		||||
	__u16 rq_icid;
 | 
			
		||||
 | 
			
		||||
	__u32 rq_db2_offset;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif /* __QEDR_USER_H__ */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue