Commit cecbcddf authored by Ram Amrani's avatar Ram Amrani Committed by Doug Ledford

qedr: Add support for QP verbs

Add support for Queue Pair verbs which adds, deletes,
modifies and queries Queue Pairs.
Signed-off-by: default avatarRajesh Borundia <rajesh.borundia@cavium.com>
Signed-off-by: default avatarRam Amrani <Ram.Amrani@cavium.com>
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
parent a7efd777
......@@ -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
/* 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;
......
This diff is collapsed.
......@@ -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__ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment