aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/hw/nes/nes_cm.c77
-rw-r--r--drivers/infiniband/hw/nes/nes_cm.h1
2 files changed, 50 insertions, 28 deletions
diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c
index 08fcd25f788..ec04786b606 100644
--- a/drivers/infiniband/hw/nes/nes_cm.c
+++ b/drivers/infiniband/hw/nes/nes_cm.c
@@ -978,6 +978,7 @@ static int mini_cm_dec_refcnt_listen(struct nes_cm_core *cm_core,
978 reset_entry); 978 reset_entry);
979 { 979 {
980 struct nes_cm_node *loopback = cm_node->loopbackpartner; 980 struct nes_cm_node *loopback = cm_node->loopbackpartner;
981 enum nes_cm_node_state old_state;
981 if (NES_CM_STATE_FIN_WAIT1 <= cm_node->state) { 982 if (NES_CM_STATE_FIN_WAIT1 <= cm_node->state) {
982 rem_ref_cm_node(cm_node->cm_core, cm_node); 983 rem_ref_cm_node(cm_node->cm_core, cm_node);
983 } else { 984 } else {
@@ -989,11 +990,12 @@ static int mini_cm_dec_refcnt_listen(struct nes_cm_core *cm_core,
989 NES_CM_STATE_CLOSED; 990 NES_CM_STATE_CLOSED;
990 WARN_ON(1); 991 WARN_ON(1);
991 } else { 992 } else {
992 cm_node->state = 993 old_state = cm_node->state;
993 NES_CM_STATE_CLOSED; 994 cm_node->state = NES_CM_STATE_LISTENER_DESTROYED;
994 rem_ref_cm_node( 995 if (old_state != NES_CM_STATE_MPAREQ_RCVD)
995 cm_node->cm_core, 996 rem_ref_cm_node(
996 cm_node); 997 cm_node->cm_core,
998 cm_node);
997 } 999 }
998 } else { 1000 } else {
999 struct nes_cm_event event; 1001 struct nes_cm_event event;
@@ -1009,6 +1011,7 @@ static int mini_cm_dec_refcnt_listen(struct nes_cm_core *cm_core,
1009 loopback->loc_port; 1011 loopback->loc_port;
1010 event.cm_info.cm_id = loopback->cm_id; 1012 event.cm_info.cm_id = loopback->cm_id;
1011 cm_event_connect_error(&event); 1013 cm_event_connect_error(&event);
1014 cm_node->state = NES_CM_STATE_LISTENER_DESTROYED;
1012 loopback->state = NES_CM_STATE_CLOSED; 1015 loopback->state = NES_CM_STATE_CLOSED;
1013 1016
1014 event.cm_node = cm_node; 1017 event.cm_node = cm_node;
@@ -2131,30 +2134,39 @@ static int mini_cm_reject(struct nes_cm_core *cm_core,
2131 cm_node->state = NES_CM_STATE_CLOSED; 2134 cm_node->state = NES_CM_STATE_CLOSED;
2132 rem_ref_cm_node(cm_core, cm_node); 2135 rem_ref_cm_node(cm_core, cm_node);
2133 } else { 2136 } else {
2134 ret = send_mpa_reject(cm_node); 2137 if (cm_node->state == NES_CM_STATE_LISTENER_DESTROYED) {
2135 if (ret) { 2138 rem_ref_cm_node(cm_core, cm_node);
2136 cm_node->state = NES_CM_STATE_CLOSED; 2139 } else {
2137 err = send_reset(cm_node, NULL); 2140 ret = send_mpa_reject(cm_node);
2138 if (err) 2141 if (ret) {
2139 WARN_ON(1); 2142 cm_node->state = NES_CM_STATE_CLOSED;
2140 } else 2143 err = send_reset(cm_node, NULL);
2141 cm_id->add_ref(cm_id); 2144 if (err)
2145 WARN_ON(1);
2146 } else
2147 cm_id->add_ref(cm_id);
2148 }
2142 } 2149 }
2143 } else { 2150 } else {
2144 cm_node->cm_id = NULL; 2151 cm_node->cm_id = NULL;
2145 event.cm_node = loopback; 2152 if (cm_node->state == NES_CM_STATE_LISTENER_DESTROYED) {
2146 event.cm_info.rem_addr = loopback->rem_addr; 2153 rem_ref_cm_node(cm_core, cm_node);
2147 event.cm_info.loc_addr = loopback->loc_addr; 2154 rem_ref_cm_node(cm_core, loopback);
2148 event.cm_info.rem_port = loopback->rem_port; 2155 } else {
2149 event.cm_info.loc_port = loopback->loc_port; 2156 event.cm_node = loopback;
2150 event.cm_info.cm_id = loopback->cm_id; 2157 event.cm_info.rem_addr = loopback->rem_addr;
2151 cm_event_mpa_reject(&event); 2158 event.cm_info.loc_addr = loopback->loc_addr;
2152 rem_ref_cm_node(cm_core, cm_node); 2159 event.cm_info.rem_port = loopback->rem_port;
2153 loopback->state = NES_CM_STATE_CLOSING; 2160 event.cm_info.loc_port = loopback->loc_port;
2161 event.cm_info.cm_id = loopback->cm_id;
2162 cm_event_mpa_reject(&event);
2163 rem_ref_cm_node(cm_core, cm_node);
2164 loopback->state = NES_CM_STATE_CLOSING;
2154 2165
2155 cm_id = loopback->cm_id; 2166 cm_id = loopback->cm_id;
2156 rem_ref_cm_node(cm_core, loopback); 2167 rem_ref_cm_node(cm_core, loopback);
2157 cm_id->rem_ref(cm_id); 2168 cm_id->rem_ref(cm_id);
2169 }
2158 } 2170 }
2159 2171
2160 return ret; 2172 return ret;
@@ -2198,6 +2210,7 @@ static int mini_cm_close(struct nes_cm_core *cm_core, struct nes_cm_node *cm_nod
2198 case NES_CM_STATE_UNKNOWN: 2210 case NES_CM_STATE_UNKNOWN:
2199 case NES_CM_STATE_INITED: 2211 case NES_CM_STATE_INITED:
2200 case NES_CM_STATE_CLOSED: 2212 case NES_CM_STATE_CLOSED:
2213 case NES_CM_STATE_LISTENER_DESTROYED:
2201 ret = rem_ref_cm_node(cm_core, cm_node); 2214 ret = rem_ref_cm_node(cm_core, cm_node);
2202 break; 2215 break;
2203 case NES_CM_STATE_TSA: 2216 case NES_CM_STATE_TSA:
@@ -2716,8 +2729,6 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
2716 struct nes_pd *nespd; 2729 struct nes_pd *nespd;
2717 u64 tagged_offset; 2730 u64 tagged_offset;
2718 2731
2719
2720
2721 ibqp = nes_get_qp(cm_id->device, conn_param->qpn); 2732 ibqp = nes_get_qp(cm_id->device, conn_param->qpn);
2722 if (!ibqp) 2733 if (!ibqp)
2723 return -EINVAL; 2734 return -EINVAL;
@@ -2733,6 +2744,13 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
2733 "%s\n", cm_node, nesvnic, nesvnic->netdev, 2744 "%s\n", cm_node, nesvnic, nesvnic->netdev,
2734 nesvnic->netdev->name); 2745 nesvnic->netdev->name);
2735 2746
2747 if (NES_CM_STATE_LISTENER_DESTROYED == cm_node->state) {
2748 if (cm_node->loopbackpartner)
2749 rem_ref_cm_node(cm_node->cm_core, cm_node->loopbackpartner);
2750 rem_ref_cm_node(cm_node->cm_core, cm_node);
2751 return -EINVAL;
2752 }
2753
2736 /* associate the node with the QP */ 2754 /* associate the node with the QP */
2737 nesqp->cm_node = (void *)cm_node; 2755 nesqp->cm_node = (void *)cm_node;
2738 cm_node->nesqp = nesqp; 2756 cm_node->nesqp = nesqp;
@@ -3003,6 +3021,9 @@ int nes_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
3003 if (!nesdev) 3021 if (!nesdev)
3004 return -EINVAL; 3022 return -EINVAL;
3005 3023
3024 if (!(cm_id->local_addr.sin_port) || !(cm_id->remote_addr.sin_port))
3025 return -EINVAL;
3026
3006 nes_debug(NES_DBG_CM, "QP%u, current IP = 0x%08X, Destination IP = " 3027 nes_debug(NES_DBG_CM, "QP%u, current IP = 0x%08X, Destination IP = "
3007 "0x%08X:0x%04X, local = 0x%08X:0x%04X.\n", nesqp->hwqp.qp_id, 3028 "0x%08X:0x%04X, local = 0x%08X:0x%04X.\n", nesqp->hwqp.qp_id,
3008 ntohl(nesvnic->local_ipaddr), 3029 ntohl(nesvnic->local_ipaddr),
@@ -3375,7 +3396,7 @@ static void cm_event_connect_error(struct nes_cm_event *event)
3375 nesqp->cm_id = NULL; 3396 nesqp->cm_id = NULL;
3376 cm_id->provider_data = NULL; 3397 cm_id->provider_data = NULL;
3377 cm_event.event = IW_CM_EVENT_CONNECT_REPLY; 3398 cm_event.event = IW_CM_EVENT_CONNECT_REPLY;
3378 cm_event.status = IW_CM_EVENT_STATUS_REJECTED; 3399 cm_event.status = -ECONNRESET;
3379 cm_event.provider_data = cm_id->provider_data; 3400 cm_event.provider_data = cm_id->provider_data;
3380 cm_event.local_addr = cm_id->local_addr; 3401 cm_event.local_addr = cm_id->local_addr;
3381 cm_event.remote_addr = cm_id->remote_addr; 3402 cm_event.remote_addr = cm_id->remote_addr;
diff --git a/drivers/infiniband/hw/nes/nes_cm.h b/drivers/infiniband/hw/nes/nes_cm.h
index 911846ae5c7..d9825fda70a 100644
--- a/drivers/infiniband/hw/nes/nes_cm.h
+++ b/drivers/infiniband/hw/nes/nes_cm.h
@@ -200,6 +200,7 @@ enum nes_cm_node_state {
200 NES_CM_STATE_TIME_WAIT, 200 NES_CM_STATE_TIME_WAIT,
201 NES_CM_STATE_LAST_ACK, 201 NES_CM_STATE_LAST_ACK,
202 NES_CM_STATE_CLOSING, 202 NES_CM_STATE_CLOSING,
203 NES_CM_STATE_LISTENER_DESTROYED,
203 NES_CM_STATE_CLOSED 204 NES_CM_STATE_CLOSED
204}; 205};
205 206