aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/nes
diff options
context:
space:
mode:
authorFaisal Latif <faisal.latif@intel.com>2010-08-14 21:05:04 +0000
committerRoland Dreier <rolandd@cisco.com>2010-09-08 14:38:04 -0700
commit67d70721151726286763209ecadc3fce86abfdce (patch)
treef0975af0127100aeb17287cc6709909fd3ad8862 /drivers/infiniband/hw/nes
parentRDMA/nes: Fix double CLOSE event indication crash (diff)
downloadlinux-dev-67d70721151726286763209ecadc3fce86abfdce.tar.xz
linux-dev-67d70721151726286763209ecadc3fce86abfdce.zip
RDMA/nes: Change state to closing after FIN
When the driver receives an AE for FIN received, it closes the connection without changing the state of the connection in the hardware to closing. By changing the state to closing, hardware will do a normal close sequence. Signed-off-by: Faisal Latif <faisal.latif@intel.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband/hw/nes')
-rw-r--r--drivers/infiniband/hw/nes/nes_hw.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c
index f8233c851c69..ba93a8be6bf6 100644
--- a/drivers/infiniband/hw/nes/nes_hw.c
+++ b/drivers/infiniband/hw/nes/nes_hw.c
@@ -3468,6 +3468,18 @@ static void nes_process_iwarp_aeqe(struct nes_device *nesdev,
return; /* Ignore it, wait for close complete */
if (atomic_inc_return(&nesqp->close_timer_started) == 1) {
+ if ((tcp_state == NES_AEQE_TCP_STATE_CLOSE_WAIT) &&
+ (nesqp->ibqp_state == IB_QPS_RTS)) {
+ spin_lock_irqsave(&nesqp->lock, flags);
+ nesqp->hw_iwarp_state = iwarp_state;
+ nesqp->hw_tcp_state = tcp_state;
+ nesqp->last_aeq = async_event_id;
+ next_iwarp_state = NES_CQP_QP_IWARP_STATE_CLOSING;
+ nesqp->hw_iwarp_state = NES_AEQE_IWARP_STATE_CLOSING;
+ spin_unlock_irqrestore(&nesqp->lock, flags);
+ nes_hw_modify_qp(nesdev, nesqp, next_iwarp_state, 0, 0);
+ nes_cm_disconn(nesqp);
+ }
nesqp->cm_id->add_ref(nesqp->cm_id);
schedule_nes_timer(nesqp->cm_node, (struct sk_buff *)nesqp,
NES_TIMER_TYPE_CLOSE, 1, 0);
@@ -3477,7 +3489,6 @@ static void nes_process_iwarp_aeqe(struct nes_device *nesdev,
nesqp->hwqp.qp_id, atomic_read(&nesqp->refcount),
async_event_id, nesqp->last_aeq, tcp_state);
}
-
break;
case NES_AEQE_AEID_LLP_CLOSE_COMPLETE:
if (nesqp->term_flags) {