diff options
Diffstat (limited to 'drivers')
| -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 08fcd25f788c..ec04786b6069 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 911846ae5c7d..d9825fda70a1 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 | ||
