Skip to content

Commit

Permalink
RDMA/qedr: Add iWARP connection management functions
Browse files Browse the repository at this point in the history
Implements the iWARP connection management functions:
connect, accept, create listener and destroy listener

Signed-off-by: Michal Kalderon <Michal.Kalderon@cavium.com>
Signed-off-by: Ram Amrani <Ram.Amrani@cavium.com>
Signed-off-by: Ariel Elior <Ariel.Elior@cavium.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
  • Loading branch information
Kalderon, Michal authored and Doug Ledford committed Aug 18, 2017
1 parent de0089e commit e411e05
Showing 5 changed files with 750 additions and 1 deletion.
11 changes: 11 additions & 0 deletions drivers/infiniband/hw/qedr/main.c
Original file line number Diff line number Diff line change
@@ -145,6 +145,12 @@ int qedr_iw_register_device(struct qedr_dev *dev)
dev->ibdev.iwcm = kzalloc(sizeof(*dev->ibdev.iwcm), GFP_KERNEL);
if (!dev->ibdev.iwcm)
return -ENOMEM;

dev->ibdev.iwcm->connect = qedr_iw_connect;
dev->ibdev.iwcm->accept = qedr_iw_accept;
dev->ibdev.iwcm->reject = qedr_iw_reject;
dev->ibdev.iwcm->create_listen = qedr_iw_create_listen;
dev->ibdev.iwcm->destroy_listen = qedr_iw_destroy_listen;
dev->ibdev.iwcm->add_ref = qedr_iw_qp_add_ref;
dev->ibdev.iwcm->rem_ref = qedr_iw_qp_rem_ref;
dev->ibdev.iwcm->get_qp = qedr_iw_get_qp;
@@ -296,6 +302,9 @@ static void qedr_free_resources(struct qedr_dev *dev)
{
int i;

if (IS_IWARP(dev))
destroy_workqueue(dev->iwarp_wq);

for (i = 0; i < dev->num_cnq; i++) {
qedr_free_mem_sb(dev, &dev->sb_array[i], dev->sb_start + i);
dev->ops->common->chain_free(dev->cdev, &dev->cnq_array[i].pbl);
@@ -323,6 +332,7 @@ static int qedr_alloc_resources(struct qedr_dev *dev)
if (IS_IWARP(dev)) {
spin_lock_init(&dev->idr_lock);
idr_init(&dev->qpidr);
dev->iwarp_wq = create_singlethread_workqueue("qedr_iwarpq");
}

/* Allocate Status blocks for CNQ */
@@ -800,6 +810,7 @@ static int qedr_init_hw(struct qedr_dev *dev)
in_params->events = &events;
in_params->cq_mode = QED_RDMA_CQ_MODE_32_BITS;
in_params->max_mtu = dev->ndev->mtu;
dev->iwarp_max_mtu = dev->ndev->mtu;
ether_addr_copy(&in_params->mac_addr[0], dev->ndev->dev_addr);

rc = dev->ops->rdma_init(dev->cdev, in_params);
22 changes: 21 additions & 1 deletion drivers/infiniband/hw/qedr/qedr.h
Original file line number Diff line number Diff line change
@@ -60,6 +60,7 @@
#define QEDR_MSG_SQ " SQ"
#define QEDR_MSG_QP " QP"
#define QEDR_MSG_GSI " GSI"
#define QEDR_MSG_IWARP " IW"

#define QEDR_CQ_MAGIC_NUMBER (0x11223344)

@@ -167,6 +168,9 @@ struct qedr_dev {
enum qed_rdma_type rdma_type;
spinlock_t idr_lock; /* Protect qpidr data-structure */
struct idr qpidr;
struct workqueue_struct *iwarp_wq;
u16 iwarp_max_mtu;

unsigned long enet_state;
};

@@ -344,7 +348,7 @@ enum qedr_qp_err_bitmap {
struct qedr_qp {
struct ib_qp ibqp; /* must be first */
struct qedr_dev *dev;

struct qedr_iw_ep *ep;
struct qedr_qp_hwq_info sq;
struct qedr_qp_hwq_info rq;

@@ -402,6 +406,7 @@ struct qedr_qp {
struct qedr_userq usq;
struct qedr_userq urq;
atomic_t refcnt;
bool destroyed;
};

struct qedr_ah {
@@ -482,6 +487,21 @@ static inline int qedr_get_dmac(struct qedr_dev *dev,
return 0;
}

struct qedr_iw_listener {
struct qedr_dev *dev;
struct iw_cm_id *cm_id;
int backlog;
void *qed_handle;
};

struct qedr_iw_ep {
struct qedr_dev *dev;
struct iw_cm_id *cm_id;
struct qedr_qp *qp;
void *qed_context;
u8 during_connect;
};

static inline
struct qedr_ucontext *get_qedr_ucontext(struct ib_ucontext *ibucontext)
{
689 changes: 689 additions & 0 deletions drivers/infiniband/hw/qedr/qedr_iw_cm.c

Large diffs are not rendered by default.

12 changes: 12 additions & 0 deletions drivers/infiniband/hw/qedr/qedr_iw_cm.h
Original file line number Diff line number Diff line change
@@ -30,6 +30,18 @@
* SOFTWARE.
*/
#include <rdma/iw_cm.h>

int qedr_iw_connect(struct iw_cm_id *cm_id,
struct iw_cm_conn_param *conn_param);

int qedr_iw_create_listen(struct iw_cm_id *cm_id, int backlog);

int qedr_iw_destroy_listen(struct iw_cm_id *cm_id);

int qedr_iw_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param);

int qedr_iw_reject(struct iw_cm_id *cm_id, const void *pdata, u8 pdata_len);

void qedr_iw_qp_add_ref(struct ib_qp *qp);

void qedr_iw_qp_rem_ref(struct ib_qp *qp);
17 changes: 17 additions & 0 deletions drivers/infiniband/hw/qedr/verbs.c
Original file line number Diff line number Diff line change
@@ -2257,6 +2257,23 @@ int qedr_destroy_qp(struct ib_qp *ibqp)
/* Change the QP state to ERROR */
qedr_modify_qp(ibqp, &attr, attr_mask, NULL);
}
} else {
/* Wait for the connect/accept to complete */
if (qp->ep) {
int wait_count = 1;

while (qp->ep->during_connect) {
DP_DEBUG(dev, QEDR_MSG_QP,
"Still in during connect/accept\n");

msleep(100);
if (wait_count++ > 200) {
DP_NOTICE(dev,
"during connect timeout\n");
break;
}
}
}
}

if (qp->qp_type == IB_QPT_GSI)

0 comments on commit e411e05

Please sign in to comment.