|
@@ -1,5 +1,5 @@
|
|
|
/*
|
|
|
- * Copyright (c) 2006 - 2009 Intel-NE, Inc. All rights reserved.
|
|
|
+ * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved.
|
|
|
*
|
|
|
* This software is available to you under a choice of one of two
|
|
|
* licenses. You may choose to be licensed under the terms of the GNU
|
|
@@ -52,6 +52,7 @@
|
|
|
#include <linux/random.h>
|
|
|
#include <linux/list.h>
|
|
|
#include <linux/threads.h>
|
|
|
+#include <linux/highmem.h>
|
|
|
#include <net/arp.h>
|
|
|
#include <net/neighbour.h>
|
|
|
#include <net/route.h>
|
|
@@ -251,6 +252,33 @@ static int parse_mpa(struct nes_cm_node *cm_node, u8 *buffer, u32 *type,
|
|
|
|
|
|
mpa_frame = (struct ietf_mpa_frame *)buffer;
|
|
|
cm_node->mpa_frame_size = ntohs(mpa_frame->priv_data_len);
|
|
|
+ /* make sure mpa private data len is less than 512 bytes */
|
|
|
+ if (cm_node->mpa_frame_size > IETF_MAX_PRIV_DATA_LEN) {
|
|
|
+ nes_debug(NES_DBG_CM, "The received Length of Private"
|
|
|
+ " Data field exceeds 512 octets\n");
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+ /*
|
|
|
+ * make sure MPA receiver interoperate with the
|
|
|
+ * received MPA version and MPA key information
|
|
|
+ *
|
|
|
+ */
|
|
|
+ if (mpa_frame->rev != mpa_version) {
|
|
|
+ nes_debug(NES_DBG_CM, "The received mpa version"
|
|
|
+ " can not be interoperated\n");
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+ if (cm_node->state != NES_CM_STATE_MPAREQ_SENT) {
|
|
|
+ if (memcmp(mpa_frame->key, IEFT_MPA_KEY_REQ, IETF_MPA_KEY_SIZE)) {
|
|
|
+ nes_debug(NES_DBG_CM, "Unexpected MPA Key received \n");
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (memcmp(mpa_frame->key, IEFT_MPA_KEY_REP, IETF_MPA_KEY_SIZE)) {
|
|
|
+ nes_debug(NES_DBG_CM, "Unexpected MPA Key received \n");
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
if (cm_node->mpa_frame_size + sizeof(struct ietf_mpa_frame) != len) {
|
|
|
nes_debug(NES_DBG_CM, "The received ietf buffer was not right"
|
|
@@ -486,6 +514,8 @@ static void nes_retrans_expired(struct nes_cm_node *cm_node)
|
|
|
send_reset(cm_node, NULL);
|
|
|
break;
|
|
|
default:
|
|
|
+ add_ref_cm_node(cm_node);
|
|
|
+ send_reset(cm_node, NULL);
|
|
|
create_event(cm_node, NES_CM_EVENT_ABORTED);
|
|
|
}
|
|
|
}
|
|
@@ -949,6 +979,7 @@ static int mini_cm_dec_refcnt_listen(struct nes_cm_core *cm_core,
|
|
|
reset_entry);
|
|
|
{
|
|
|
struct nes_cm_node *loopback = cm_node->loopbackpartner;
|
|
|
+ enum nes_cm_node_state old_state;
|
|
|
if (NES_CM_STATE_FIN_WAIT1 <= cm_node->state) {
|
|
|
rem_ref_cm_node(cm_node->cm_core, cm_node);
|
|
|
} else {
|
|
@@ -960,11 +991,12 @@ static int mini_cm_dec_refcnt_listen(struct nes_cm_core *cm_core,
|
|
|
NES_CM_STATE_CLOSED;
|
|
|
WARN_ON(1);
|
|
|
} else {
|
|
|
- cm_node->state =
|
|
|
- NES_CM_STATE_CLOSED;
|
|
|
- rem_ref_cm_node(
|
|
|
- cm_node->cm_core,
|
|
|
- cm_node);
|
|
|
+ old_state = cm_node->state;
|
|
|
+ cm_node->state = NES_CM_STATE_LISTENER_DESTROYED;
|
|
|
+ if (old_state != NES_CM_STATE_MPAREQ_RCVD)
|
|
|
+ rem_ref_cm_node(
|
|
|
+ cm_node->cm_core,
|
|
|
+ cm_node);
|
|
|
}
|
|
|
} else {
|
|
|
struct nes_cm_event event;
|
|
@@ -980,20 +1012,9 @@ static int mini_cm_dec_refcnt_listen(struct nes_cm_core *cm_core,
|
|
|
loopback->loc_port;
|
|
|
event.cm_info.cm_id = loopback->cm_id;
|
|
|
cm_event_connect_error(&event);
|
|
|
+ cm_node->state = NES_CM_STATE_LISTENER_DESTROYED;
|
|
|
loopback->state = NES_CM_STATE_CLOSED;
|
|
|
|
|
|
- event.cm_node = cm_node;
|
|
|
- event.cm_info.rem_addr =
|
|
|
- cm_node->rem_addr;
|
|
|
- event.cm_info.loc_addr =
|
|
|
- cm_node->loc_addr;
|
|
|
- event.cm_info.rem_port =
|
|
|
- cm_node->rem_port;
|
|
|
- event.cm_info.loc_port =
|
|
|
- cm_node->loc_port;
|
|
|
- event.cm_info.cm_id = cm_node->cm_id;
|
|
|
- cm_event_reset(&event);
|
|
|
-
|
|
|
rem_ref_cm_node(cm_node->cm_core,
|
|
|
cm_node);
|
|
|
|
|
@@ -1077,12 +1098,13 @@ static inline int mini_cm_accelerated(struct nes_cm_core *cm_core,
|
|
|
/**
|
|
|
* nes_addr_resolve_neigh
|
|
|
*/
|
|
|
-static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip)
|
|
|
+static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip, int arpindex)
|
|
|
{
|
|
|
struct rtable *rt;
|
|
|
struct flowi fl;
|
|
|
struct neighbour *neigh;
|
|
|
- int rc = -1;
|
|
|
+ int rc = arpindex;
|
|
|
+ struct nes_adapter *nesadapter = nesvnic->nesdev->nesadapter;
|
|
|
|
|
|
memset(&fl, 0, sizeof fl);
|
|
|
fl.nl_u.ip4_u.daddr = htonl(dst_ip);
|
|
@@ -1098,6 +1120,21 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip)
|
|
|
nes_debug(NES_DBG_CM, "Neighbor MAC address for 0x%08X"
|
|
|
" is %pM, Gateway is 0x%08X \n", dst_ip,
|
|
|
neigh->ha, ntohl(rt->rt_gateway));
|
|
|
+
|
|
|
+ if (arpindex >= 0) {
|
|
|
+ if (!memcmp(nesadapter->arp_table[arpindex].mac_addr,
|
|
|
+ neigh->ha, ETH_ALEN)){
|
|
|
+ /* Mac address same as in nes_arp_table */
|
|
|
+ neigh_release(neigh);
|
|
|
+ ip_rt_put(rt);
|
|
|
+ return rc;
|
|
|
+ }
|
|
|
+
|
|
|
+ nes_manage_arp_cache(nesvnic->netdev,
|
|
|
+ nesadapter->arp_table[arpindex].mac_addr,
|
|
|
+ dst_ip, NES_ARP_DELETE);
|
|
|
+ }
|
|
|
+
|
|
|
nes_manage_arp_cache(nesvnic->netdev, neigh->ha,
|
|
|
dst_ip, NES_ARP_ADD);
|
|
|
rc = nes_arp_table(nesvnic->nesdev, dst_ip, NULL,
|
|
@@ -1113,7 +1150,6 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip)
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
/**
|
|
|
* make_cm_node - create a new instance of a cm node
|
|
|
*/
|
|
@@ -1123,6 +1159,7 @@ static struct nes_cm_node *make_cm_node(struct nes_cm_core *cm_core,
|
|
|
{
|
|
|
struct nes_cm_node *cm_node;
|
|
|
struct timespec ts;
|
|
|
+ int oldarpindex = 0;
|
|
|
int arpindex = 0;
|
|
|
struct nes_device *nesdev;
|
|
|
struct nes_adapter *nesadapter;
|
|
@@ -1176,17 +1213,18 @@ static struct nes_cm_node *make_cm_node(struct nes_cm_core *cm_core,
|
|
|
nesadapter = nesdev->nesadapter;
|
|
|
|
|
|
cm_node->loopbackpartner = NULL;
|
|
|
+
|
|
|
/* get the mac addr for the remote node */
|
|
|
if (ipv4_is_loopback(htonl(cm_node->rem_addr)))
|
|
|
arpindex = nes_arp_table(nesdev, ntohl(nesvnic->local_ipaddr), NULL, NES_ARP_RESOLVE);
|
|
|
- else
|
|
|
- arpindex = nes_arp_table(nesdev, cm_node->rem_addr, NULL, NES_ARP_RESOLVE);
|
|
|
+ else {
|
|
|
+ oldarpindex = nes_arp_table(nesdev, cm_node->rem_addr, NULL, NES_ARP_RESOLVE);
|
|
|
+ arpindex = nes_addr_resolve_neigh(nesvnic, cm_info->rem_addr, oldarpindex);
|
|
|
+
|
|
|
+ }
|
|
|
if (arpindex < 0) {
|
|
|
- arpindex = nes_addr_resolve_neigh(nesvnic, cm_info->rem_addr);
|
|
|
- if (arpindex < 0) {
|
|
|
- kfree(cm_node);
|
|
|
- return NULL;
|
|
|
- }
|
|
|
+ kfree(cm_node);
|
|
|
+ return NULL;
|
|
|
}
|
|
|
|
|
|
/* copy the mac addr to node context */
|
|
@@ -1333,13 +1371,20 @@ static void handle_fin_pkt(struct nes_cm_node *cm_node)
|
|
|
case NES_CM_STATE_SYN_RCVD:
|
|
|
case NES_CM_STATE_SYN_SENT:
|
|
|
case NES_CM_STATE_ESTABLISHED:
|
|
|
- case NES_CM_STATE_MPAREQ_SENT:
|
|
|
case NES_CM_STATE_MPAREJ_RCVD:
|
|
|
cm_node->tcp_cntxt.rcv_nxt++;
|
|
|
cleanup_retrans_entry(cm_node);
|
|
|
cm_node->state = NES_CM_STATE_LAST_ACK;
|
|
|
send_fin(cm_node, NULL);
|
|
|
break;
|
|
|
+ case NES_CM_STATE_MPAREQ_SENT:
|
|
|
+ create_event(cm_node, NES_CM_EVENT_ABORTED);
|
|
|
+ cm_node->tcp_cntxt.rcv_nxt++;
|
|
|
+ cleanup_retrans_entry(cm_node);
|
|
|
+ cm_node->state = NES_CM_STATE_CLOSED;
|
|
|
+ add_ref_cm_node(cm_node);
|
|
|
+ send_reset(cm_node, NULL);
|
|
|
+ break;
|
|
|
case NES_CM_STATE_FIN_WAIT1:
|
|
|
cm_node->tcp_cntxt.rcv_nxt++;
|
|
|
cleanup_retrans_entry(cm_node);
|
|
@@ -1590,6 +1635,7 @@ static void handle_syn_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
|
|
|
break;
|
|
|
case NES_CM_STATE_CLOSED:
|
|
|
cleanup_retrans_entry(cm_node);
|
|
|
+ add_ref_cm_node(cm_node);
|
|
|
send_reset(cm_node, skb);
|
|
|
break;
|
|
|
case NES_CM_STATE_TSA:
|
|
@@ -1641,9 +1687,15 @@ static void handle_synack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
|
|
|
passive_open_err(cm_node, skb, 1);
|
|
|
break;
|
|
|
case NES_CM_STATE_LISTENING:
|
|
|
+ cm_node->tcp_cntxt.loc_seq_num = ntohl(tcph->ack_seq);
|
|
|
+ cleanup_retrans_entry(cm_node);
|
|
|
+ cm_node->state = NES_CM_STATE_CLOSED;
|
|
|
+ send_reset(cm_node, skb);
|
|
|
+ break;
|
|
|
case NES_CM_STATE_CLOSED:
|
|
|
cm_node->tcp_cntxt.loc_seq_num = ntohl(tcph->ack_seq);
|
|
|
cleanup_retrans_entry(cm_node);
|
|
|
+ add_ref_cm_node(cm_node);
|
|
|
send_reset(cm_node, skb);
|
|
|
break;
|
|
|
case NES_CM_STATE_ESTABLISHED:
|
|
@@ -1712,8 +1764,13 @@ static int handle_ack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
|
|
|
dev_kfree_skb_any(skb);
|
|
|
break;
|
|
|
case NES_CM_STATE_LISTENING:
|
|
|
+ cleanup_retrans_entry(cm_node);
|
|
|
+ cm_node->state = NES_CM_STATE_CLOSED;
|
|
|
+ send_reset(cm_node, skb);
|
|
|
+ break;
|
|
|
case NES_CM_STATE_CLOSED:
|
|
|
cleanup_retrans_entry(cm_node);
|
|
|
+ add_ref_cm_node(cm_node);
|
|
|
send_reset(cm_node, skb);
|
|
|
break;
|
|
|
case NES_CM_STATE_LAST_ACK:
|
|
@@ -1974,7 +2031,7 @@ static struct nes_cm_node *mini_cm_connect(struct nes_cm_core *cm_core,
|
|
|
if (!cm_node)
|
|
|
return NULL;
|
|
|
mpa_frame = &cm_node->mpa_frame;
|
|
|
- strcpy(mpa_frame->key, IEFT_MPA_KEY_REQ);
|
|
|
+ memcpy(mpa_frame->key, IEFT_MPA_KEY_REQ, IETF_MPA_KEY_SIZE);
|
|
|
mpa_frame->flags = IETF_MPA_FLAGS_CRC;
|
|
|
mpa_frame->rev = IETF_MPA_VERSION;
|
|
|
mpa_frame->priv_data_len = htons(private_data_len);
|
|
@@ -2102,30 +2159,39 @@ static int mini_cm_reject(struct nes_cm_core *cm_core,
|
|
|
cm_node->state = NES_CM_STATE_CLOSED;
|
|
|
rem_ref_cm_node(cm_core, cm_node);
|
|
|
} else {
|
|
|
- ret = send_mpa_reject(cm_node);
|
|
|
- if (ret) {
|
|
|
- cm_node->state = NES_CM_STATE_CLOSED;
|
|
|
- err = send_reset(cm_node, NULL);
|
|
|
- if (err)
|
|
|
- WARN_ON(1);
|
|
|
- } else
|
|
|
- cm_id->add_ref(cm_id);
|
|
|
+ if (cm_node->state == NES_CM_STATE_LISTENER_DESTROYED) {
|
|
|
+ rem_ref_cm_node(cm_core, cm_node);
|
|
|
+ } else {
|
|
|
+ ret = send_mpa_reject(cm_node);
|
|
|
+ if (ret) {
|
|
|
+ cm_node->state = NES_CM_STATE_CLOSED;
|
|
|
+ err = send_reset(cm_node, NULL);
|
|
|
+ if (err)
|
|
|
+ WARN_ON(1);
|
|
|
+ } else
|
|
|
+ cm_id->add_ref(cm_id);
|
|
|
+ }
|
|
|
}
|
|
|
} else {
|
|
|
cm_node->cm_id = NULL;
|
|
|
- event.cm_node = loopback;
|
|
|
- event.cm_info.rem_addr = loopback->rem_addr;
|
|
|
- event.cm_info.loc_addr = loopback->loc_addr;
|
|
|
- event.cm_info.rem_port = loopback->rem_port;
|
|
|
- event.cm_info.loc_port = loopback->loc_port;
|
|
|
- event.cm_info.cm_id = loopback->cm_id;
|
|
|
- cm_event_mpa_reject(&event);
|
|
|
- rem_ref_cm_node(cm_core, cm_node);
|
|
|
- loopback->state = NES_CM_STATE_CLOSING;
|
|
|
+ if (cm_node->state == NES_CM_STATE_LISTENER_DESTROYED) {
|
|
|
+ rem_ref_cm_node(cm_core, cm_node);
|
|
|
+ rem_ref_cm_node(cm_core, loopback);
|
|
|
+ } else {
|
|
|
+ event.cm_node = loopback;
|
|
|
+ event.cm_info.rem_addr = loopback->rem_addr;
|
|
|
+ event.cm_info.loc_addr = loopback->loc_addr;
|
|
|
+ event.cm_info.rem_port = loopback->rem_port;
|
|
|
+ event.cm_info.loc_port = loopback->loc_port;
|
|
|
+ event.cm_info.cm_id = loopback->cm_id;
|
|
|
+ cm_event_mpa_reject(&event);
|
|
|
+ rem_ref_cm_node(cm_core, cm_node);
|
|
|
+ loopback->state = NES_CM_STATE_CLOSING;
|
|
|
|
|
|
- cm_id = loopback->cm_id;
|
|
|
- rem_ref_cm_node(cm_core, loopback);
|
|
|
- cm_id->rem_ref(cm_id);
|
|
|
+ cm_id = loopback->cm_id;
|
|
|
+ rem_ref_cm_node(cm_core, loopback);
|
|
|
+ cm_id->rem_ref(cm_id);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
return ret;
|
|
@@ -2164,11 +2230,15 @@ static int mini_cm_close(struct nes_cm_core *cm_core, struct nes_cm_node *cm_nod
|
|
|
case NES_CM_STATE_CLOSING:
|
|
|
ret = -1;
|
|
|
break;
|
|
|
- case NES_CM_STATE_MPAREJ_RCVD:
|
|
|
case NES_CM_STATE_LISTENING:
|
|
|
+ cleanup_retrans_entry(cm_node);
|
|
|
+ send_reset(cm_node, NULL);
|
|
|
+ break;
|
|
|
+ case NES_CM_STATE_MPAREJ_RCVD:
|
|
|
case NES_CM_STATE_UNKNOWN:
|
|
|
case NES_CM_STATE_INITED:
|
|
|
case NES_CM_STATE_CLOSED:
|
|
|
+ case NES_CM_STATE_LISTENER_DESTROYED:
|
|
|
ret = rem_ref_cm_node(cm_core, cm_node);
|
|
|
break;
|
|
|
case NES_CM_STATE_TSA:
|
|
@@ -2687,8 +2757,6 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
|
|
|
struct nes_pd *nespd;
|
|
|
u64 tagged_offset;
|
|
|
|
|
|
-
|
|
|
-
|
|
|
ibqp = nes_get_qp(cm_id->device, conn_param->qpn);
|
|
|
if (!ibqp)
|
|
|
return -EINVAL;
|
|
@@ -2704,6 +2772,13 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
|
|
|
"%s\n", cm_node, nesvnic, nesvnic->netdev,
|
|
|
nesvnic->netdev->name);
|
|
|
|
|
|
+ if (NES_CM_STATE_LISTENER_DESTROYED == cm_node->state) {
|
|
|
+ if (cm_node->loopbackpartner)
|
|
|
+ rem_ref_cm_node(cm_node->cm_core, cm_node->loopbackpartner);
|
|
|
+ rem_ref_cm_node(cm_node->cm_core, cm_node);
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
/* associate the node with the QP */
|
|
|
nesqp->cm_node = (void *)cm_node;
|
|
|
cm_node->nesqp = nesqp;
|
|
@@ -2786,6 +2861,10 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
|
|
|
cpu_to_le32(conn_param->private_data_len +
|
|
|
sizeof(struct ietf_mpa_frame));
|
|
|
wqe->wqe_words[NES_IWARP_SQ_WQE_STAG0_IDX] = ibmr->lkey;
|
|
|
+ if (nesqp->sq_kmapped) {
|
|
|
+ nesqp->sq_kmapped = 0;
|
|
|
+ kunmap(nesqp->page);
|
|
|
+ }
|
|
|
|
|
|
nesqp->nesqp_context->ird_ord_sizes |=
|
|
|
cpu_to_le32(NES_QPCONTEXT_ORDIRD_LSMM_PRESENT |
|
|
@@ -2929,7 +3008,7 @@ int nes_reject(struct iw_cm_id *cm_id, const void *pdata, u8 pdata_len)
|
|
|
if (cm_node->mpa_frame_size > MAX_CM_BUFFER)
|
|
|
return -EINVAL;
|
|
|
|
|
|
- strcpy(&cm_node->mpa_frame.key[0], IEFT_MPA_KEY_REP);
|
|
|
+ memcpy(&cm_node->mpa_frame.key[0], IEFT_MPA_KEY_REP, IETF_MPA_KEY_SIZE);
|
|
|
if (loopback) {
|
|
|
memcpy(&loopback->mpa_frame.priv_data, pdata, pdata_len);
|
|
|
loopback->mpa_frame.priv_data_len = pdata_len;
|
|
@@ -2974,6 +3053,9 @@ int nes_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
|
|
|
if (!nesdev)
|
|
|
return -EINVAL;
|
|
|
|
|
|
+ if (!(cm_id->local_addr.sin_port) || !(cm_id->remote_addr.sin_port))
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
nes_debug(NES_DBG_CM, "QP%u, current IP = 0x%08X, Destination IP = "
|
|
|
"0x%08X:0x%04X, local = 0x%08X:0x%04X.\n", nesqp->hwqp.qp_id,
|
|
|
ntohl(nesvnic->local_ipaddr),
|
|
@@ -3251,6 +3333,11 @@ static void cm_event_connected(struct nes_cm_event *event)
|
|
|
wqe->wqe_words[NES_IWARP_SQ_WQE_LENGTH0_IDX] = 0;
|
|
|
wqe->wqe_words[NES_IWARP_SQ_WQE_STAG0_IDX] = 0;
|
|
|
|
|
|
+ if (nesqp->sq_kmapped) {
|
|
|
+ nesqp->sq_kmapped = 0;
|
|
|
+ kunmap(nesqp->page);
|
|
|
+ }
|
|
|
+
|
|
|
/* use the reserved spot on the WQ for the extra first WQE */
|
|
|
nesqp->nesqp_context->ird_ord_sizes &=
|
|
|
cpu_to_le32(~(NES_QPCONTEXT_ORDIRD_LSMM_PRESENT |
|
|
@@ -3346,7 +3433,7 @@ static void cm_event_connect_error(struct nes_cm_event *event)
|
|
|
nesqp->cm_id = NULL;
|
|
|
cm_id->provider_data = NULL;
|
|
|
cm_event.event = IW_CM_EVENT_CONNECT_REPLY;
|
|
|
- cm_event.status = IW_CM_EVENT_STATUS_REJECTED;
|
|
|
+ cm_event.status = -ECONNRESET;
|
|
|
cm_event.provider_data = cm_id->provider_data;
|
|
|
cm_event.local_addr = cm_id->local_addr;
|
|
|
cm_event.remote_addr = cm_id->remote_addr;
|
|
@@ -3390,6 +3477,8 @@ static void cm_event_reset(struct nes_cm_event *event)
|
|
|
|
|
|
nes_debug(NES_DBG_CM, "%p - cm_id = %p\n", event->cm_node, cm_id);
|
|
|
nesqp = cm_id->provider_data;
|
|
|
+ if (!nesqp)
|
|
|
+ return;
|
|
|
|
|
|
nesqp->cm_id = NULL;
|
|
|
/* cm_id->provider_data = NULL; */
|
|
@@ -3401,8 +3490,8 @@ static void cm_event_reset(struct nes_cm_event *event)
|
|
|
cm_event.private_data = NULL;
|
|
|
cm_event.private_data_len = 0;
|
|
|
|
|
|
- ret = cm_id->event_handler(cm_id, &cm_event);
|
|
|
cm_id->add_ref(cm_id);
|
|
|
+ ret = cm_id->event_handler(cm_id, &cm_event);
|
|
|
atomic_inc(&cm_closes);
|
|
|
cm_event.event = IW_CM_EVENT_CLOSE;
|
|
|
cm_event.status = IW_CM_EVENT_STATUS_OK;
|