[ewg] [PATCH 1/5] nes: accelerated loopback support

Glenn Grundstrom NetEffect glenn at lists.openfabrics.org
Fri Nov 30 09:51:23 PST 2007


This patch allows accelerated loopback connections to
be made through the driver.  Prior to this patch iWarp
acclerated loopback requests were not handled.

Signed-off-by: Glenn Grundstrom <ggrundstrom at neteffect.com>

---

diff --git a/drivers/infiniband/hw/nes/nes.c b/drivers/infiniband/hw/nes/nes.c
index 4f7ae5c..a5e0bb5 100644
--- a/drivers/infiniband/hw/nes/nes.c
+++ b/drivers/infiniband/hw/nes/nes.c
@@ -175,6 +175,8 @@ static int nes_inetaddr_event(struct notifier_block *notifier,
 					nes_write_indexed(nesdev,
 							NES_IDX_DST_IP_ADDR+(0x10*PCI_FUNC(nesdev->pcidev->devfn)), 0);
 
+					nes_manage_arp_cache(netdev, netdev->dev_addr,
+							ntohl(nesvnic->local_ipaddr), NES_ARP_DELETE);
 					nesvnic->local_ipaddr = 0;
 					return NOTIFY_OK;
 					break;
@@ -191,6 +193,8 @@ static int nes_inetaddr_event(struct notifier_block *notifier,
 					nes_write_indexed(nesdev,
 							NES_IDX_DST_IP_ADDR+(0x10*PCI_FUNC(nesdev->pcidev->devfn)),
 							ntohl(ifa->ifa_address));
+					nes_manage_arp_cache(netdev, netdev->dev_addr,
+							ntohl(nesvnic->local_ipaddr), NES_ARP_ADD);
 					return NOTIFY_OK;
 					break;
 				default:
diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c
index 4023a2c..3005cb1 100644
--- a/drivers/infiniband/hw/nes/nes_cm.c
+++ b/drivers/infiniband/hw/nes/nes_cm.c
@@ -1616,6 +1616,7 @@ struct nes_cm_node * mini_cm_connect(struct nes_cm_core *cm_core,
 	struct nes_cm_node *cm_node;
 	struct nes_cm_listener *loopbackremotelistener;
 	struct nes_cm_node *loopbackremotenode;
+	struct nes_cm_info loopback_cm_info;
 
 	u16 mpa_frame_size = sizeof(struct ietf_mpa_frame) +
 			ntohs(mpa_frame->priv_data_len);
@@ -1632,6 +1633,7 @@ struct nes_cm_node * mini_cm_connect(struct nes_cm_core *cm_core,
 
 	// set our node side to client (active) side
 	cm_node->tcp_cntxt.client = 1;
+	cm_node->tcp_cntxt.rcv_wscale = NES_CM_DEFAULT_RCV_WND_SCALE;
 
 	if (cm_info->loc_addr == cm_info->rem_addr) {
 		loopbackremotelistener = find_listener(cm_core, cm_node->rem_addr,
@@ -1639,13 +1641,14 @@ struct nes_cm_node * mini_cm_connect(struct nes_cm_core *cm_core,
 		if (loopbackremotelistener == NULL) {
 			create_event(cm_node, NES_CM_EVENT_ABORTED);
 		} else {
-			u16 temp;
-			temp = cm_info->loc_port;
-			cm_info->loc_port = cm_info->rem_port;
-			cm_info->rem_port = temp;
-			loopbackremotenode = make_cm_node(cm_core, nesvnic, cm_info,
+			loopback_cm_info = *cm_info;
+			loopback_cm_info.loc_port = cm_info->rem_port;
+			loopback_cm_info.rem_port = cm_info->loc_port;
+			loopback_cm_info.cm_id = loopbackremotelistener->cm_id;
+			loopbackremotenode = make_cm_node(cm_core, nesvnic, &loopback_cm_info,
 					loopbackremotelistener);
 			loopbackremotenode->loopbackpartner = cm_node;
+			loopbackremotenode->tcp_cntxt.rcv_wscale = NES_CM_DEFAULT_RCV_WND_SCALE;
 			cm_node->loopbackpartner = loopbackremotenode;
 			memcpy(loopbackremotenode->mpa_frame_buf, &mpa_frame->priv_data,
 					mpa_frame_size);
@@ -1654,6 +1657,14 @@ struct nes_cm_node * mini_cm_connect(struct nes_cm_core *cm_core,
 
 			// we are done handling this state, set node to a TSA state
 			cm_node->state = NES_CM_STATE_TSA;
+			cm_node->tcp_cntxt.rcv_nxt = loopbackremotenode->tcp_cntxt.loc_seq_num;
+			loopbackremotenode->tcp_cntxt.rcv_nxt = cm_node->tcp_cntxt.loc_seq_num;
+			cm_node->tcp_cntxt.max_snd_wnd = loopbackremotenode->tcp_cntxt.rcv_wnd;
+			loopbackremotenode->tcp_cntxt.max_snd_wnd = cm_node->tcp_cntxt.rcv_wnd;
+			cm_node->tcp_cntxt.snd_wnd = loopbackremotenode->tcp_cntxt.rcv_wnd;
+			loopbackremotenode->tcp_cntxt.snd_wnd = cm_node->tcp_cntxt.rcv_wnd;
+			cm_node->tcp_cntxt.snd_wscale = loopbackremotenode->tcp_cntxt.rcv_wscale;
+			loopbackremotenode->tcp_cntxt.snd_wscale = cm_node->tcp_cntxt.rcv_wscale;
 
 			create_event(loopbackremotenode, NES_CM_EVENT_MPA_REQ);
 		}
@@ -1665,7 +1676,6 @@ struct nes_cm_node * mini_cm_connect(struct nes_cm_core *cm_core,
 	/* init our MPA frame ptr */
 	memcpy(&cm_node->mpa_frame, mpa_frame, mpa_frame_size);
 	cm_node->mpa_frame_size = mpa_frame_size;
-	cm_node->tcp_cntxt.snd_wscale = NES_CM_DEFAULT_RCV_WND_SCALE;
 
 	/* send a syn and goto syn sent state */
 	cm_node->state = NES_CM_STATE_SYN_SENT;
@@ -2284,7 +2294,6 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
 	struct iw_cm_event cm_event;
 	struct nes_hw_qp_wqe *wqe;
 	struct nes_v4_quad nes_quad;
-	struct iw_cm_id *lb_cm_id;
 	int ret;
 
 	ibqp = nes_get_qp(cm_id->device, conn_param->qpn);
@@ -2338,24 +2347,29 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
 		/* setup our first outgoing iWarp send WQE (the IETF frame response) */
 		wqe = &nesqp->hwqp.sq_vbase[0];
 
-		u64temp = (u64)nesqp;
-		u64temp |= NES_SW_CONTEXT_ALIGN>>1;
-		wqe->wqe_words[NES_IWARP_SQ_WQE_COMP_CTX_LOW_IDX] = cpu_to_le32((u32)(u64temp));
-		wqe->wqe_words[NES_IWARP_SQ_WQE_COMP_CTX_HIGH_IDX] = cpu_to_le32((u32)(u64temp>>32));
-		wqe->wqe_words[NES_IWARP_SQ_WQE_MISC_IDX] =
-				cpu_to_le32(NES_IWARP_SQ_WQE_STREAMING | NES_IWARP_SQ_WQE_WRPDU);
-		wqe->wqe_words[NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX] =
-				cpu_to_le32(conn_param->private_data_len + sizeof(struct ietf_mpa_frame));
-		wqe->wqe_words[NES_IWARP_SQ_WQE_FRAG0_LOW_IDX] =
-				cpu_to_le32((u32)nesqp->ietf_frame_pbase);
-		wqe->wqe_words[NES_IWARP_SQ_WQE_FRAG0_HIGH_IDX] =
-				cpu_to_le32((u32)((u64)nesqp->ietf_frame_pbase >> 32));
-		wqe->wqe_words[NES_IWARP_SQ_WQE_LENGTH0_IDX] =
-				cpu_to_le32(conn_param->private_data_len + sizeof(struct ietf_mpa_frame));
-		wqe->wqe_words[NES_IWARP_SQ_WQE_STAG0_IDX] = 0;
-
-		nesqp->nesqp_context->ird_ord_sizes |= cpu_to_le32(
-				NES_QPCONTEXT_ORDIRD_LSMM_PRESENT | NES_QPCONTEXT_ORDIRD_WRPDU);
+		if (cm_id->remote_addr.sin_addr.s_addr != cm_id->local_addr.sin_addr.s_addr) {
+			u64temp = (u64)nesqp;
+			u64temp |= NES_SW_CONTEXT_ALIGN>>1;
+			wqe->wqe_words[NES_IWARP_SQ_WQE_COMP_CTX_LOW_IDX] = cpu_to_le32((u32)(u64temp));
+			wqe->wqe_words[NES_IWARP_SQ_WQE_COMP_CTX_HIGH_IDX] = cpu_to_le32((u32)(u64temp>>32));
+			wqe->wqe_words[NES_IWARP_SQ_WQE_MISC_IDX] =
+					cpu_to_le32(NES_IWARP_SQ_WQE_STREAMING | NES_IWARP_SQ_WQE_WRPDU);
+			wqe->wqe_words[NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX] =
+					cpu_to_le32(conn_param->private_data_len + sizeof(struct ietf_mpa_frame));
+			wqe->wqe_words[NES_IWARP_SQ_WQE_FRAG0_LOW_IDX] =
+					cpu_to_le32((u32)nesqp->ietf_frame_pbase);
+			wqe->wqe_words[NES_IWARP_SQ_WQE_FRAG0_HIGH_IDX] =
+					cpu_to_le32((u32)((u64)nesqp->ietf_frame_pbase >> 32));
+			wqe->wqe_words[NES_IWARP_SQ_WQE_LENGTH0_IDX] =
+					cpu_to_le32(conn_param->private_data_len + sizeof(struct ietf_mpa_frame));
+			wqe->wqe_words[NES_IWARP_SQ_WQE_STAG0_IDX] = 0;
+
+			nesqp->nesqp_context->ird_ord_sizes |= cpu_to_le32(
+					NES_QPCONTEXT_ORDIRD_LSMM_PRESENT | NES_QPCONTEXT_ORDIRD_WRPDU);
+		} else {
+			nesqp->nesqp_context->ird_ord_sizes |= cpu_to_le32((NES_QPCONTEXT_ORDIRD_LSMM_PRESENT |
+					NES_QPCONTEXT_ORDIRD_WRPDU | NES_QPCONTEXT_ORDIRD_ALSMM));
+		}
 		nesqp->skip_lsmm = 1;
 
 
@@ -2530,8 +2544,9 @@ int nes_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
 	nesqp->ietf_frame->rev = IETF_MPA_VERSION;
 	nesqp->ietf_frame->priv_data_len = htons(conn_param->private_data_len);
 
-	nes_manage_apbvt(nesvnic, ntohs(cm_id->local_addr.sin_port),
-			PCI_FUNC(nesdev->pcidev->devfn), NES_MANAGE_APBVT_ADD);
+	if (cm_id->local_addr.sin_addr.s_addr != cm_id->remote_addr.sin_addr.s_addr)
+		nes_manage_apbvt(nesvnic, ntohs(cm_id->local_addr.sin_port),
+				PCI_FUNC(nesdev->pcidev->devfn), NES_MANAGE_APBVT_ADD);
 
 	/* set up the connection params for the node */
 	cm_info.loc_addr = (cm_id->local_addr.sin_addr.s_addr);
@@ -2547,8 +2562,9 @@ int nes_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
 	/* create a connect CM node connection */
 	cm_node = g_cm_core->api->connect(g_cm_core, nesvnic, nesqp->ietf_frame, &cm_info);
 	if (!cm_node) {
-		nes_manage_apbvt(nesvnic, ntohs(cm_id->local_addr.sin_port),
-				PCI_FUNC(nesdev->pcidev->devfn), NES_MANAGE_APBVT_DEL);
+		if (cm_id->local_addr.sin_addr.s_addr != cm_id->remote_addr.sin_addr.s_addr)
+			nes_manage_apbvt(nesvnic, ntohs(cm_id->local_addr.sin_port),
+					PCI_FUNC(nesdev->pcidev->devfn), NES_MANAGE_APBVT_DEL);
 		nes_rem_ref(&nesqp->ibqp);
 		kfree(nesqp->ietf_frame);
 		nesqp->ietf_frame = NULL;
diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c
index 311127e..5fb241a 100644
--- a/drivers/infiniband/hw/nes/nes_verbs.c
+++ b/drivers/infiniband/hw/nes/nes_verbs.c
@@ -2712,6 +2712,7 @@ static struct ib_mr *nes_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
 			list_for_each_entry(chunk, &region->chunk_list, list) {
 				for (nmap_index = 0; nmap_index < chunk->nmap; ++nmap_index) {
 					chunk_pages = sg_dma_len(&chunk->page_list[nmap_index]) >> PAGE_SHIFT;
+					/* nespbl->page = chunk->page_list[0].page; */
 					nespbl->page = sg_page(&chunk->page_list[0]);
 					for (page_index=0; page_index<chunk_pages; page_index++) {
 						((u32 *)pbl)[0] = cpu_to_le32((u32)



More information about the ewg mailing list