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

qedr: Add GSI support

Add support for GSI over light L2.
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 1d1424c8
obj-$(CONFIG_INFINIBAND_QEDR) := qedr.o
qedr-y := main.o verbs.o
qedr-y := main.o verbs.o qedr_cm.o
......@@ -138,6 +138,9 @@ static int qedr_register_device(struct qedr_dev *dev)
dev->ibdev.query_pkey = qedr_query_pkey;
dev->ibdev.create_ah = qedr_create_ah;
dev->ibdev.destroy_ah = qedr_destroy_ah;
dev->ibdev.get_dma_mr = qedr_get_dma_mr;
dev->ibdev.dereg_mr = qedr_dereg_mr;
dev->ibdev.reg_user_mr = qedr_reg_user_mr;
......
......@@ -55,6 +55,7 @@
#define QEDR_MSG_RQ " RQ"
#define QEDR_MSG_SQ " SQ"
#define QEDR_MSG_QP " QP"
#define QEDR_MSG_GSI " GSI"
#define QEDR_CQ_MAGIC_NUMBER (0x11223344)
......@@ -148,6 +149,10 @@ struct qedr_dev {
u8 num_hwfns;
uint wq_multiplier;
u8 gsi_ll2_mac_address[ETH_ALEN];
int gsi_qp_created;
struct qedr_cq *gsi_sqcq;
struct qedr_cq *gsi_rqcq;
struct qedr_qp *gsi_qp;
};
#define QEDR_MAX_SQ_PBL (0x8000)
......@@ -246,6 +251,9 @@ struct qedr_cq {
u16 icid;
/* Lock to protect completion handler */
spinlock_t comp_handler_lock;
/* Lock to protect multiplem CQ's */
spinlock_t cq_lock;
u8 arm_flags;
......@@ -292,6 +300,7 @@ struct qedr_qp_hwq_info {
u16 prod;
u16 cons;
u16 wqe_cons;
u16 gsi_cons;
u16 max_wr;
/* DB */
......@@ -366,6 +375,7 @@ struct qedr_qp {
struct ib_sge sg_list[RDMA_MAX_SGE_PER_RQ_WQE];
u8 wqe_size;
u8 smac[ETH_ALEN];
u16 vlan_id;
int rc;
} *rqe_wr_id;
......@@ -473,6 +483,11 @@ static inline struct qedr_qp *get_qedr_qp(struct ib_qp *ibqp)
return container_of(ibqp, struct qedr_qp, ibqp);
}
static inline struct qedr_ah *get_qedr_ah(struct ib_ah *ibah)
{
return container_of(ibah, struct qedr_ah, ibah);
}
static inline struct qedr_mr *get_qedr_mr(struct ib_mr *ibmr)
{
return container_of(ibmr, struct qedr_mr, ibmr);
......
This diff is collapsed.
......@@ -32,9 +32,30 @@
#ifndef LINUX_QEDR_CM_H_
#define LINUX_QEDR_CM_H_
#define QEDR_GSI_MAX_RECV_WR (4096)
#define QEDR_GSI_MAX_SEND_WR (4096)
#define QEDR_GSI_MAX_RECV_SGE (1) /* LL2 FW limitation */
#define ETH_P_ROCE (0x8915)
#define QEDR_ROCE_V2_UDP_SPORT (0000)
static inline u32 qedr_get_ipv4_from_gid(u8 *gid)
{
return *(u32 *)(void *)&gid[12];
}
/* RDMA CM */
int qedr_gsi_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc);
int qedr_gsi_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *wr,
struct ib_recv_wr **bad_wr);
int qedr_gsi_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
struct ib_send_wr **bad_wr);
struct ib_qp *qedr_create_gsi_qp(struct qedr_dev *dev,
struct ib_qp_init_attr *attrs,
struct qedr_qp *qp);
void qedr_store_gsi_qp_cq(struct qedr_dev *dev,
struct qedr_qp *qp, struct ib_qp_init_attr *attrs);
int qedr_destroy_gsi_qp(struct qedr_dev *dev);
void qedr_inc_sw_gsi_cons(struct qedr_qp_hwq_info *info);
#endif
......@@ -1502,6 +1502,15 @@ struct ib_qp *qedr_create_qp(struct ib_pd *ibpd,
qedr_set_qp_init_params(dev, qp, pd, attrs);
if (attrs->qp_type == IB_QPT_GSI) {
if (udata) {
DP_ERR(dev,
"create qp: unexpected udata when creating GSI QP\n");
goto err0;
}
return qedr_create_gsi_qp(dev, attrs, qp);
}
memset(&in_params, 0, sizeof(in_params));
if (udata) {
......@@ -2068,6 +2077,8 @@ int qedr_destroy_qp(struct ib_qp *ibqp)
rc = dev->ops->rdma_destroy_qp(dev->rdma_ctx, qp->qed_qp);
if (rc)
return rc;
} else {
qedr_destroy_gsi_qp(dev);
}
if (ibqp->uobject && ibqp->uobject->context) {
......@@ -2083,6 +2094,27 @@ int qedr_destroy_qp(struct ib_qp *ibqp)
return rc;
}
struct ib_ah *qedr_create_ah(struct ib_pd *ibpd, struct ib_ah_attr *attr)
{
struct qedr_ah *ah;
ah = kzalloc(sizeof(*ah), GFP_ATOMIC);
if (!ah)
return ERR_PTR(-ENOMEM);
ah->attr = *attr;
return &ah->ibah;
}
int qedr_destroy_ah(struct ib_ah *ibah)
{
struct qedr_ah *ah = get_qedr_ah(ibah);
kfree(ah);
return 0;
}
static void free_mr_info(struct qedr_dev *dev, struct mr_info *info)
{
struct qedr_pbl *pbl, *tmp;
......@@ -2934,6 +2966,9 @@ int qedr_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
*bad_wr = NULL;
if (qp->qp_type == IB_QPT_GSI)
return qedr_gsi_post_send(ibqp, wr, bad_wr);
spin_lock_irqsave(&qp->q_lock, flags);
if ((qp->state == QED_ROCE_QP_STATE_RESET) ||
......@@ -2990,6 +3025,9 @@ int qedr_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *wr,
unsigned long flags;
int status = 0;
if (qp->qp_type == IB_QPT_GSI)
return qedr_gsi_post_recv(ibqp, wr, bad_wr);
spin_lock_irqsave(&qp->q_lock, flags);
if ((qp->state == QED_ROCE_QP_STATE_RESET) ||
......@@ -3416,6 +3454,9 @@ int qedr_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc)
int update = 0;
int done = 0;
if (cq->cq_type == QEDR_CQ_TYPE_GSI)
return qedr_gsi_poll_cq(ibcq, num_entries, wc);
spin_lock_irqsave(&cq->cq_lock, flags);
old_cons = qed_chain_get_cons_idx_u32(&cq->pbl);
while (num_entries && is_valid_cqe(cq, cqe)) {
......
......@@ -70,6 +70,9 @@ 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);
struct ib_ah *qedr_create_ah(struct ib_pd *ibpd, struct ib_ah_attr *attr);
int qedr_destroy_ah(struct ib_ah *ibah);
int qedr_dereg_mr(struct ib_mr *);
struct ib_mr *qedr_get_dma_mr(struct ib_pd *, int acc);
......
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