diff options
Diffstat (limited to 'drivers/infiniband')
-rw-r--r-- | drivers/infiniband/hw/nes/nes_cm.c | 77 | ||||
-rw-r--r-- | drivers/infiniband/hw/nes/nes_cm.h | 1 |
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 | ||