diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c
index 1a556f4..bf646d1 100644
--- a/net/smc/af_smc.c
+++ b/net/smc/af_smc.c
@@ -492,7 +492,7 @@ static int smcr_lgr_reg_rmbs(struct smc_link *link,
 			     struct smc_buf_desc *rmb_desc)
 {
 	struct smc_link_group *lgr = link->lgr;
-	int i, rc = 0;
+	int i, lnk = 0, rc = 0;
 
 	rc = smc_llc_flow_initiate(lgr, SMC_LLC_FLOW_RKEY);
 	if (rc)
@@ -507,14 +507,20 @@ static int smcr_lgr_reg_rmbs(struct smc_link *link,
 		rc = smcr_link_reg_rmb(&lgr->lnk[i], rmb_desc);
 		if (rc)
 			goto out;
+		/* available link count inc */
+		lnk++;
 	}
 
-	/* exchange confirm_rkey msg with peer */
-	rc = smc_llc_do_confirm_rkey(link, rmb_desc);
-	if (rc) {
-		rc = -EFAULT;
-		goto out;
+	/* do not exchange confirm_rkey msg since there are only one link */
+	if (lnk > 1) {
+		/* exchange confirm_rkey msg with peer */
+		rc = smc_llc_do_confirm_rkey(link, rmb_desc);
+		if (rc) {
+			rc = -EFAULT;
+			goto out;
+		}
 	}
+
 	rmb_desc->is_conf_rkey = true;
 out:
 	mutex_unlock(&lgr->llc_conf_mutex);
@@ -932,6 +938,31 @@ static int smc_find_rdma_device(struct smc_sock *smc, struct smc_init_info *ini)
 	return 0;
 }
 
+/* just prototype code
+ * since tcp connect has not happen, using route to perform smc_pnet_find_roce_by_pnetid
+ */
+static int smc_find_rdma_device_with_dst(struct smc_sock *smc, struct smc_init_info *ini)
+{
+	struct sock *tsk = smc->clcsock->sk;
+	struct rtable *rt;
+
+	rt = ip_route_output(sock_net(tsk), smc->remote_address.v4.sin_addr.s_addr,
+			     0, 0, 0);
+
+	if (IS_ERR(rt))
+		return -ECONNRESET;
+
+	smc_pnet_find_roce_by_pnetid(rt->dst.dev, ini);
+	__builtin_prefetch(&ini->ib_dev->mac[ini->ib_port - 1]);
+
+	if (!ini->check_smcrv2 && !ini->ib_dev)
+		return SMC_CLC_DECL_NOSMCRDEV;
+	if (ini->check_smcrv2 && !ini->smcrv2.ib_dev_v2)
+		return SMC_CLC_DECL_NOSMCRDEV;
+
+	return 0;
+}
+
 /* check if there is an ISM device available for this connection. */
 /* called for connect and listen */
 static int smc_find_ism_device(struct smc_sock *smc, struct smc_init_info *ini)
@@ -1019,13 +1050,17 @@ static int smc_find_proposal_devices(struct smc_sock *smc,
 
 	/* check if there is an rdma device available */
 	if (!(ini->smcr_version & SMC_V1) ||
-	    smc_find_rdma_device(smc, ini))
+	    smc_find_rdma_device_with_dst(smc, ini))
 		ini->smcr_version &= ~SMC_V1;
 	/* else RDMA is supported for this connection */
 
 	ini->smc_type_v1 = smc_indicated_type(ini->smcd_version & SMC_V1,
 					      ini->smcr_version & SMC_V1);
 
+	/* just prototype, do this for simple */
+	ini->smc_type_v2 = SMC_TYPE_N;
+	return rc;
+
 	/* check if there is an ism v2 device available */
 	if (!(ini->smcd_version & SMC_V2) ||
 	    !smc_ism_is_v2_capable() ||
@@ -1492,11 +1527,7 @@ static void smc_connect_work(struct work_struct *work)
 		smc->sk.sk_err = smc->clcsock->sk->sk_err;
 	} else if ((1 << smc->clcsock->sk->sk_state) &
 					(TCPF_SYN_SENT | TCPF_SYN_RECV)) {
-		rc = sk_stream_wait_connect(smc->clcsock->sk, &timeo);
-		if ((rc == -EPIPE) &&
-		    ((1 << smc->clcsock->sk->sk_state) &
-					(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)))
-			rc = 0;
+		rc = 0;
 	}
 	release_sock(smc->clcsock->sk);
 	lock_sock(&smc->sk);
@@ -1580,9 +1611,10 @@ static int smc_connect(struct socket *sock, struct sockaddr *addr,
 		rc = -EALREADY;
 		goto out;
 	}
-	rc = kernel_connect(smc->clcsock, addr, alen, flags);
-	if (rc && rc != -EINPROGRESS)
-		goto out;
+
+	/* copy remote address backup */
+	memcpy(&smc->remote_address.ss, addr, alen);
+	rc = -EINPROGRESS;
 
 	if (smc->use_fallback) {
 		sock->state = rc ? SS_CONNECTING : SS_CONNECTED;
@@ -2452,9 +2484,17 @@ static int smc_listen(struct socket *sock, int backlog)
 {
 	struct sock *sk = sock->sk;
 	struct smc_sock *smc;
-	int rc;
+	int rc, val;
 
 	smc = smc_sk(sk);
+
+	/* enable server clcsock tcp fastopen.
+	 * just a proto type code, magic number 5 for no reason
+	 */
+	val = 5;
+	smc->clcsock->ops->setsockopt(smc->clcsock, SOL_TCP,
+				      TCP_FASTOPEN, KERNEL_SOCKPTR(&val), sizeof(val));
+
 	lock_sock(sk);
 
 	rc = -EINVAL;
diff --git a/net/smc/smc.h b/net/smc/smc.h
index 5ed765e..ef18894 100644
--- a/net/smc/smc.h
+++ b/net/smc/smc.h
@@ -261,6 +261,14 @@ struct smc_sock {				/* smc sock container */
 	int			fallback_rsn;	/* reason for fallback */
 	u32			peer_diagnosis; /* decline reason from peer */
 	atomic_t                queued_smc_hs;  /* queued smc handshakes */
+
+	union {
+		struct sockaddr		addr;
+		struct sockaddr_in	v4;
+		struct sockaddr_in6	v6;
+		struct sockaddr_storage ss;
+	} remote_address;
+
 	struct inet_connection_sock_af_ops		af_ops;
 	const struct inet_connection_sock_af_ops	*ori_af_ops;
 						/* original af ops */
diff --git a/net/smc/smc_clc.c b/net/smc/smc_clc.c
index f9f3f59..f944c67 100644
--- a/net/smc/smc_clc.c
+++ b/net/smc/smc_clc.c
@@ -20,6 +20,7 @@
 #include <net/addrconf.h>
 #include <net/sock.h>
 #include <net/tcp.h>
+#include <net/route.h>
 
 #include "smc.h"
 #include "smc_core.h"
@@ -486,8 +487,7 @@ static int smc_clc_prfx_set4_rcu(struct dst_entry *dst, __be32 ipv4,
 		return -ENODEV;
 
 	in_dev_for_each_ifa_rcu(ifa, in_dev) {
-		if (!inet_ifa_match(ipv4, ifa))
-			continue;
+		/* delete this for simple, just prototype code*/
 		prop->prefix_len = inet_mask_len(ifa->ifa_mask);
 		prop->outgoing_subnet = ifa->ifa_address & ifa->ifa_mask;
 		/* prop->ipv6_prefixes_cnt = 0; already done by memset before */
@@ -528,10 +528,10 @@ static int smc_clc_prfx_set6_rcu(struct dst_entry *dst,
 
 /* retrieve and set prefixes in CLC proposal msg */
 static int smc_clc_prfx_set(struct socket *clcsock,
+			    struct dst_entry *dst,
 			    struct smc_clc_msg_proposal_prefix *prop,
 			    struct smc_clc_ipv6_prefix *ipv6_prfx)
 {
-	struct dst_entry *dst = sk_dst_get(clcsock->sk);
 	struct sockaddr_storage addrs;
 	struct sockaddr_in6 *addr6;
 	struct sockaddr_in *addr;
@@ -802,7 +802,8 @@ int smc_clc_send_decline(struct smc_sock *smc, u32 peer_diag_info, u8 version)
 }
 
 /* send CLC PROPOSAL message across internal TCP socket */
-int smc_clc_send_proposal(struct smc_sock *smc, struct smc_init_info *ini)
+int smc_clc_send_proposal_with_nexthop(struct smc_sock *smc,
+				       struct dst_entry *dst, struct smc_init_info *ini)
 {
 	struct smc_clc_smcd_v2_extension *smcd_v2_ext;
 	struct smc_clc_msg_proposal_prefix *pclc_prfx;
@@ -838,7 +839,7 @@ int smc_clc_send_proposal(struct smc_sock *smc, struct smc_init_info *ini)
 
 	/* retrieve ip prefixes for CLC proposal msg */
 	if (ini->smc_type_v1 != SMC_TYPE_N) {
-		rc = smc_clc_prfx_set(smc->clcsock, pclc_prfx, ipv6_prfx);
+		rc = smc_clc_prfx_set(smc->clcsock, dst, pclc_prfx, ipv6_prfx);
 		if (rc) {
 			if (ini->smc_type_v2 == SMC_TYPE_N) {
 				kfree(pclc);
@@ -961,6 +962,11 @@ int smc_clc_send_proposal(struct smc_sock *smc, struct smc_init_info *ini)
 	}
 	vec[i].iov_base = trl;
 	vec[i++].iov_len = sizeof(*trl);
+
+	msg.msg_flags	|= MSG_FASTOPEN;
+	msg.msg_name	= &smc->remote_address.addr;
+	msg.msg_namelen = sizeof(struct sockaddr_in);
+
 	/* due to the few bytes needed for clc-handshake this cannot block */
 	len = kernel_sendmsg(smc->clcsock, &msg, vec, i, plen);
 	if (len < 0) {
@@ -975,6 +981,22 @@ int smc_clc_send_proposal(struct smc_sock *smc, struct smc_init_info *ini)
 	return reason_code;
 }
 
+int smc_clc_send_proposal(struct smc_sock *smc, struct smc_init_info *ini)
+{
+	struct sock *tsk = smc->clcsock->sk;
+	struct rtable *rt;
+	int rc;
+
+	rt = ip_route_output(sock_net(tsk), smc->remote_address.v4.sin_addr.s_addr,
+			     0, 0, 0);
+
+	if (IS_ERR(rt))
+		return -ECONNRESET;
+
+	rc = smc_clc_send_proposal_with_nexthop(smc, &rt->dst, ini);
+	return rc;
+}
+
 /* build and send CLC CONFIRM / ACCEPT message */
 static int smc_clc_send_confirm_accept(struct smc_sock *smc,
 				       struct smc_clc_msg_accept_confirm_v2 *clc_v2,
diff --git a/net/smc/smc_core.c b/net/smc/smc_core.c
index f40f6ed..ef5e5411 100644
--- a/net/smc/smc_core.c
+++ b/net/smc/smc_core.c
@@ -1765,6 +1765,8 @@ int smc_vlan_by_tcpsk(struct socket *clcsock, struct smc_init_info *ini)
 	int rc = 0;
 
 	ini->vlan_id = 0;
+	/* just for simple , prototype code */
+	return 0;
 	if (!dst) {
 		rc = -ENOTCONN;
 		goto out;
diff --git a/net/smc/smc_pnet.c b/net/smc/smc_pnet.c
index 7055ed1..6aa3304 100644
--- a/net/smc/smc_pnet.c
+++ b/net/smc/smc_pnet.c
@@ -1064,8 +1064,8 @@ static void smc_pnet_find_rdma_dev(struct net_device *netdev,
  * If nothing found, check pnetid table.
  * If nothing found, try to use handshake device
  */
-static void smc_pnet_find_roce_by_pnetid(struct net_device *ndev,
-					 struct smc_init_info *ini)
+void smc_pnet_find_roce_by_pnetid(struct net_device *ndev,
+				  struct smc_init_info *ini)
 {
 	u8 ndev_pnetid[SMC_MAX_PNETID_LEN];
 	struct net *net;
diff --git a/net/smc/smc_pnet.h b/net/smc/smc_pnet.h
index 80a88ee..2ffaf22 100644
--- a/net/smc/smc_pnet.h
+++ b/net/smc/smc_pnet.h
@@ -67,4 +67,7 @@ void smc_pnet_find_alt_roce(struct smc_link_group *lgr,
 			    struct smc_ib_device *known_dev);
 bool smc_pnet_is_ndev_pnetid(struct net *net, u8 *pnetid);
 bool smc_pnet_is_pnetid_set(u8 *pnetid);
+
+void smc_pnet_find_roce_by_pnetid(struct net_device *ndev,
+				  struct smc_init_info *ini);
 #endif
