aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/i40iw/i40iw_utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/hw/i40iw/i40iw_utils.c')
-rw-r--r--drivers/infiniband/hw/i40iw/i40iw_utils.c60
1 files changed, 58 insertions, 2 deletions
diff --git a/drivers/infiniband/hw/i40iw/i40iw_utils.c b/drivers/infiniband/hw/i40iw/i40iw_utils.c
index 56d986924a4c..e311ec559f4e 100644
--- a/drivers/infiniband/hw/i40iw/i40iw_utils.c
+++ b/drivers/infiniband/hw/i40iw/i40iw_utils.c
@@ -337,6 +337,7 @@ struct i40iw_cqp_request *i40iw_get_cqp_request(struct i40iw_cqp *cqp, bool wait
337 */ 337 */
338void i40iw_free_cqp_request(struct i40iw_cqp *cqp, struct i40iw_cqp_request *cqp_request) 338void i40iw_free_cqp_request(struct i40iw_cqp *cqp, struct i40iw_cqp_request *cqp_request)
339{ 339{
340 struct i40iw_device *iwdev = container_of(cqp, struct i40iw_device, cqp);
340 unsigned long flags; 341 unsigned long flags;
341 342
342 if (cqp_request->dynamic) { 343 if (cqp_request->dynamic) {
@@ -350,6 +351,7 @@ void i40iw_free_cqp_request(struct i40iw_cqp *cqp, struct i40iw_cqp_request *cqp
350 list_add_tail(&cqp_request->list, &cqp->cqp_avail_reqs); 351 list_add_tail(&cqp_request->list, &cqp->cqp_avail_reqs);
351 spin_unlock_irqrestore(&cqp->req_lock, flags); 352 spin_unlock_irqrestore(&cqp->req_lock, flags);
352 } 353 }
354 wake_up(&iwdev->close_wq);
353} 355}
354 356
355/** 357/**
@@ -365,6 +367,56 @@ void i40iw_put_cqp_request(struct i40iw_cqp *cqp,
365} 367}
366 368
367/** 369/**
370 * i40iw_free_pending_cqp_request -free pending cqp request objs
371 * @cqp: cqp ptr
372 * @cqp_request: to be put back in cqp list
373 */
374static void i40iw_free_pending_cqp_request(struct i40iw_cqp *cqp,
375 struct i40iw_cqp_request *cqp_request)
376{
377 struct i40iw_device *iwdev = container_of(cqp, struct i40iw_device, cqp);
378
379 if (cqp_request->waiting) {
380 cqp_request->compl_info.error = true;
381 cqp_request->request_done = true;
382 wake_up(&cqp_request->waitq);
383 }
384 i40iw_put_cqp_request(cqp, cqp_request);
385 wait_event_timeout(iwdev->close_wq,
386 !atomic_read(&cqp_request->refcount),
387 1000);
388}
389
390/**
391 * i40iw_cleanup_pending_cqp_op - clean-up cqp with no completions
392 * @iwdev: iwarp device
393 */
394void i40iw_cleanup_pending_cqp_op(struct i40iw_device *iwdev)
395{
396 struct i40iw_sc_dev *dev = &iwdev->sc_dev;
397 struct i40iw_cqp *cqp = &iwdev->cqp;
398 struct i40iw_cqp_request *cqp_request = NULL;
399 struct cqp_commands_info *pcmdinfo = NULL;
400 u32 i, pending_work, wqe_idx;
401
402 pending_work = I40IW_RING_WORK_AVAILABLE(cqp->sc_cqp.sq_ring);
403 wqe_idx = I40IW_RING_GETCURRENT_TAIL(cqp->sc_cqp.sq_ring);
404 for (i = 0; i < pending_work; i++) {
405 cqp_request = (struct i40iw_cqp_request *)(unsigned long)cqp->scratch_array[wqe_idx];
406 if (cqp_request)
407 i40iw_free_pending_cqp_request(cqp, cqp_request);
408 wqe_idx = (wqe_idx + 1) % I40IW_RING_GETSIZE(cqp->sc_cqp.sq_ring);
409 }
410
411 while (!list_empty(&dev->cqp_cmd_head)) {
412 pcmdinfo = (struct cqp_commands_info *)i40iw_remove_head(&dev->cqp_cmd_head);
413 cqp_request = container_of(pcmdinfo, struct i40iw_cqp_request, info);
414 if (cqp_request)
415 i40iw_free_pending_cqp_request(cqp, cqp_request);
416 }
417}
418
419/**
368 * i40iw_free_qp - callback after destroy cqp completes 420 * i40iw_free_qp - callback after destroy cqp completes
369 * @cqp_request: cqp request for destroy qp 421 * @cqp_request: cqp request for destroy qp
370 * @num: not used 422 * @num: not used
@@ -546,8 +598,12 @@ void i40iw_rem_ref(struct ib_qp *ibqp)
546 cqp_info->in.u.qp_destroy.scratch = (uintptr_t)cqp_request; 598 cqp_info->in.u.qp_destroy.scratch = (uintptr_t)cqp_request;
547 cqp_info->in.u.qp_destroy.remove_hash_idx = true; 599 cqp_info->in.u.qp_destroy.remove_hash_idx = true;
548 status = i40iw_handle_cqp_op(iwdev, cqp_request); 600 status = i40iw_handle_cqp_op(iwdev, cqp_request);
549 if (status) 601 if (!status)
550 i40iw_pr_err("CQP-OP Destroy QP fail"); 602 return;
603
604 i40iw_rem_pdusecount(iwqp->iwpd, iwdev);
605 i40iw_free_qp_resources(iwdev, iwqp, qp_num);
606 i40iw_rem_devusecount(iwdev);
551} 607}
552 608
553/** 609/**