nes_debug(NES_DBG_QP, "Invalid QP type: %d\n", init_attr->qp_type);
                        return ERR_PTR(-EINVAL);
        }
+       init_completion(&nesqp->sq_drained);
+       init_completion(&nesqp->rq_drained);
 
        nesqp->sig_all = (init_attr->sq_sig_type == IB_SIGNAL_ALL_WR);
        init_timer(&nesqp->terminate_timer);
        return err;
 }
 
+/**
+ * nes_drain_sq - drain sq
+ * @ibqp: pointer to ibqp
+ */
+static void nes_drain_sq(struct ib_qp *ibqp)
+{
+       struct nes_qp *nesqp = to_nesqp(ibqp);
+
+       if (nesqp->hwqp.sq_tail != nesqp->hwqp.sq_head)
+               wait_for_completion(&nesqp->sq_drained);
+}
+
+/**
+ * nes_drain_rq - drain rq
+ * @ibqp: pointer to ibqp
+ */
+static void nes_drain_rq(struct ib_qp *ibqp)
+{
+       struct nes_qp *nesqp = to_nesqp(ibqp);
+
+       if (nesqp->hwqp.rq_tail != nesqp->hwqp.rq_head)
+               wait_for_completion(&nesqp->rq_drained);
+}
 
 /**
  * nes_poll_cq
                                }
                        }
 
+                       if (nesqp->iwarp_state > NES_CQP_QP_IWARP_STATE_RTS) {
+                               if (nesqp->hwqp.sq_tail == nesqp->hwqp.sq_head)
+                                       complete(&nesqp->sq_drained);
+                               if (nesqp->hwqp.rq_tail == nesqp->hwqp.rq_head)
+                                       complete(&nesqp->rq_drained);
+                       }
+
                        entry->wr_id = wrid;
                        entry++;
                        cqe_count++;
        nesibdev->ibdev.req_notify_cq = nes_req_notify_cq;
        nesibdev->ibdev.post_send = nes_post_send;
        nesibdev->ibdev.post_recv = nes_post_recv;
+       nesibdev->ibdev.drain_sq = nes_drain_sq;
+       nesibdev->ibdev.drain_rq = nes_drain_rq;
 
        nesibdev->ibdev.iwcm = kzalloc(sizeof(*nesibdev->ibdev.iwcm), GFP_KERNEL);
        if (nesibdev->ibdev.iwcm == NULL) {