Commit e411e058 authored by Kalderon, Michal's avatar Kalderon, Michal Committed by Doug Ledford

RDMA/qedr: Add iWARP connection management functions

Implements the iWARP connection management functions:
connect, accept, create listener and destroy listener
Signed-off-by: default avatarMichal Kalderon <Michal.Kalderon@cavium.com>
Signed-off-by: default avatarRam Amrani <Ram.Amrani@cavium.com>
Signed-off-by: default avatarAriel Elior <Ariel.Elior@cavium.com>
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
parent de0089e6
...@@ -145,6 +145,12 @@ int qedr_iw_register_device(struct qedr_dev *dev) ...@@ -145,6 +145,12 @@ int qedr_iw_register_device(struct qedr_dev *dev)
dev->ibdev.iwcm = kzalloc(sizeof(*dev->ibdev.iwcm), GFP_KERNEL); dev->ibdev.iwcm = kzalloc(sizeof(*dev->ibdev.iwcm), GFP_KERNEL);
if (!dev->ibdev.iwcm) if (!dev->ibdev.iwcm)
return -ENOMEM; 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->add_ref = qedr_iw_qp_add_ref;
dev->ibdev.iwcm->rem_ref = qedr_iw_qp_rem_ref; dev->ibdev.iwcm->rem_ref = qedr_iw_qp_rem_ref;
dev->ibdev.iwcm->get_qp = qedr_iw_get_qp; dev->ibdev.iwcm->get_qp = qedr_iw_get_qp;
...@@ -296,6 +302,9 @@ static void qedr_free_resources(struct qedr_dev *dev) ...@@ -296,6 +302,9 @@ static void qedr_free_resources(struct qedr_dev *dev)
{ {
int i; int i;
if (IS_IWARP(dev))
destroy_workqueue(dev->iwarp_wq);
for (i = 0; i < dev->num_cnq; i++) { for (i = 0; i < dev->num_cnq; i++) {
qedr_free_mem_sb(dev, &dev->sb_array[i], dev->sb_start + 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); 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) ...@@ -323,6 +332,7 @@ static int qedr_alloc_resources(struct qedr_dev *dev)
if (IS_IWARP(dev)) { if (IS_IWARP(dev)) {
spin_lock_init(&dev->idr_lock); spin_lock_init(&dev->idr_lock);
idr_init(&dev->qpidr); idr_init(&dev->qpidr);
dev->iwarp_wq = create_singlethread_workqueue("qedr_iwarpq");
} }
/* Allocate Status blocks for CNQ */ /* Allocate Status blocks for CNQ */
...@@ -800,6 +810,7 @@ static int qedr_init_hw(struct qedr_dev *dev) ...@@ -800,6 +810,7 @@ static int qedr_init_hw(struct qedr_dev *dev)
in_params->events = &events; in_params->events = &events;
in_params->cq_mode = QED_RDMA_CQ_MODE_32_BITS; in_params->cq_mode = QED_RDMA_CQ_MODE_32_BITS;
in_params->max_mtu = dev->ndev->mtu; 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); ether_addr_copy(&in_params->mac_addr[0], dev->ndev->dev_addr);
rc = dev->ops->rdma_init(dev->cdev, in_params); rc = dev->ops->rdma_init(dev->cdev, in_params);
......
...@@ -60,6 +60,7 @@ ...@@ -60,6 +60,7 @@
#define QEDR_MSG_SQ " SQ" #define QEDR_MSG_SQ " SQ"
#define QEDR_MSG_QP " QP" #define QEDR_MSG_QP " QP"
#define QEDR_MSG_GSI " GSI" #define QEDR_MSG_GSI " GSI"
#define QEDR_MSG_IWARP " IW"
#define QEDR_CQ_MAGIC_NUMBER (0x11223344) #define QEDR_CQ_MAGIC_NUMBER (0x11223344)
...@@ -167,6 +168,9 @@ struct qedr_dev { ...@@ -167,6 +168,9 @@ struct qedr_dev {
enum qed_rdma_type rdma_type; enum qed_rdma_type rdma_type;
spinlock_t idr_lock; /* Protect qpidr data-structure */ spinlock_t idr_lock; /* Protect qpidr data-structure */
struct idr qpidr; struct idr qpidr;
struct workqueue_struct *iwarp_wq;
u16 iwarp_max_mtu;
unsigned long enet_state; unsigned long enet_state;
}; };
...@@ -344,7 +348,7 @@ enum qedr_qp_err_bitmap { ...@@ -344,7 +348,7 @@ enum qedr_qp_err_bitmap {
struct qedr_qp { struct qedr_qp {
struct ib_qp ibqp; /* must be first */ struct ib_qp ibqp; /* must be first */
struct qedr_dev *dev; struct qedr_dev *dev;
struct qedr_iw_ep *ep;
struct qedr_qp_hwq_info sq; struct qedr_qp_hwq_info sq;
struct qedr_qp_hwq_info rq; struct qedr_qp_hwq_info rq;
...@@ -402,6 +406,7 @@ struct qedr_qp { ...@@ -402,6 +406,7 @@ struct qedr_qp {
struct qedr_userq usq; struct qedr_userq usq;
struct qedr_userq urq; struct qedr_userq urq;
atomic_t refcnt; atomic_t refcnt;
bool destroyed;
}; };
struct qedr_ah { struct qedr_ah {
...@@ -482,6 +487,21 @@ static inline int qedr_get_dmac(struct qedr_dev *dev, ...@@ -482,6 +487,21 @@ static inline int qedr_get_dmac(struct qedr_dev *dev,
return 0; 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 static inline
struct qedr_ucontext *get_qedr_ucontext(struct ib_ucontext *ibucontext) struct qedr_ucontext *get_qedr_ucontext(struct ib_ucontext *ibucontext)
{ {
......
This diff is collapsed.
...@@ -30,6 +30,18 @@ ...@@ -30,6 +30,18 @@
* SOFTWARE. * SOFTWARE.
*/ */
#include <rdma/iw_cm.h> #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_add_ref(struct ib_qp *qp);
void qedr_iw_qp_rem_ref(struct ib_qp *qp); void qedr_iw_qp_rem_ref(struct ib_qp *qp);
......
...@@ -2257,6 +2257,23 @@ int qedr_destroy_qp(struct ib_qp *ibqp) ...@@ -2257,6 +2257,23 @@ int qedr_destroy_qp(struct ib_qp *ibqp)
/* Change the QP state to ERROR */ /* Change the QP state to ERROR */
qedr_modify_qp(ibqp, &attr, attr_mask, NULL); 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) if (qp->qp_type == IB_QPT_GSI)
......
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