[ofw] [PATCH] [RFC] winverbs/qp: add support for modify qp

Sean Hefty sean.hefty at intel.com
Thu May 1 19:05:48 PDT 2008


Initial implementation for QP:Modify.

The underlying channel interface does not support asynchronous modify, so
the implementation is restricted to synchronous operation.

Signed-off-by: Sean Hefty <sean.hefty at intel.com>
---
Index: core/winverbs/kernel/wv_driver.c
===================================================================
--- core/winverbs/kernel/wv_driver.c	(revision 1103)
+++ core/winverbs/kernel/wv_driver.c	(working copy)
@@ -269,7 +269,7 @@
 		WvQpQuery(prov, Request);
 		break;
 	case WV_IOCTL_QP_MODIFY:
-		//WvQpModify(prov, Request);
+		WvQpModify(prov, Request);
 		WdfRequestComplete(Request, STATUS_NOT_IMPLEMENTED);
 		break;
 	case WV_IOCTL_QP_ATTACH:
Index: core/winverbs/kernel/wv_qp.c
===================================================================
--- core/winverbs/kernel/wv_qp.c	(revision 1103)
+++ core/winverbs/kernel/wv_qp.c	(working copy)
@@ -62,7 +62,7 @@
 	case IB_QPS_INIT:	return WV_IO_QP_STATE_INIT;
 	case IB_QPS_RTR:	return WV_IO_QP_STATE_RTR;
 	case IB_QPS_RTS:	return WV_IO_QP_STATE_RTS;
-	case IB_QPS_SQD:	return WV_IO_QP_STATE_SDQ;
+	case IB_QPS_SQD:	return WV_IO_QP_STATE_SQD;
 	case IB_QPS_SQERR:	return WV_IO_QP_STATE_SQERROR;
 	default:			return WV_IO_QP_STATE_ERROR;
 	}
@@ -84,6 +84,22 @@
 	pAv->SourcePathBits = pVerbsAv->path_bits;
 }
 
+static void WvVerbsConvertAv(ib_av_attr_t *pVerbsAv, WV_IO_AV *pAv)
+{
+	if (pAv->GrhValid) {
+		RtlCopyMemory(&pVerbsAv->grh, pAv, sizeof pVerbsAv->grh);
+		pVerbsAv->grh_valid = 1;
+	} else {
+		pVerbsAv->grh_valid = 0;
+	}
+
+	pVerbsAv->port_num = pAv->PortNumber;
+	pVerbsAv->sl = pAv->ServiceLevel;
+	pVerbsAv->dlid = pAv->DLid;
+	pVerbsAv->static_rate = pAv->StaticRate;
+	pVerbsAv->path_bits = pAv->SourcePathBits;
+}
+
 static void WvQpAttrConvertVerbs(WV_IO_QP_ATTRIBUTES *pAttr, ib_qp_attr_t *pVerbsAttr)
 {
 	pAttr->QpType			= pVerbsAttr->qp_type;
@@ -123,6 +139,147 @@
 	pAttr->RnrRetryCount	= pVerbsAttr->primary_av.conn.rnr_retry_cnt;
 }
 
+static ib_qp_opts_t WvVerbsConvertOptions(UINT32 Options)
+{
+	UINT32 opt = 0;
+
+	if ((Options & WV_IO_QP_ATTR_CURRENT_STATE) == WV_IO_QP_ATTR_CURRENT_STATE) {
+		opt |= IB_MOD_QP_CURRENT_STATE;
+	}
+	if ((Options & WV_IO_QP_ATTR_ACCESS_FLAGS) == WV_IO_QP_ATTR_ACCESS_FLAGS) {
+		opt |= IB_MOD_QP_ACCESS_CTRL;
+	}
+	if ((Options & WV_IO_QP_ATTR_PKEY_INDEX) == WV_IO_QP_ATTR_PKEY_INDEX) {
+		opt |= IB_MOD_QP_PKEY;
+	}
+	if ((Options & WV_IO_QP_ATTR_PORT) == WV_IO_QP_ATTR_PORT) {
+		opt |= IB_MOD_QP_PRIMARY_PORT;
+	}
+	if ((Options & WV_IO_QP_ATTR_QKEY) == WV_IO_QP_ATTR_QKEY) {
+		opt |= IB_MOD_QP_QKEY;
+	}
+	if ((Options & WV_IO_QP_ATTR_AV) == WV_IO_QP_ATTR_AV ||
+		(Options & WV_IO_QP_ATTR_PATH_MTU) == WV_IO_QP_ATTR_PATH_MTU) {
+		opt |= IB_MOD_QP_PRIMARY_AV;
+	}
+	if ((Options & WV_IO_QP_ATTR_TIMEOUT) == WV_IO_QP_ATTR_TIMEOUT) {
+		opt |= IB_MOD_QP_LOCAL_ACK_TIMEOUT;
+	}
+	if ((Options & WV_IO_QP_ATTR_RETRY_COUNT) == WV_IO_QP_ATTR_RETRY_COUNT) {
+		opt |= IB_MOD_QP_RETRY_CNT;
+	}
+	if ((Options & WV_IO_QP_ATTR_RNR_RETRY) == WV_IO_QP_ATTR_RNR_RETRY) {
+		opt |= IB_MOD_QP_RNR_RETRY_CNT;
+	}
+	if ((Options & WV_IO_QP_ATTR_INITIATOR_DEPTH) == WV_IO_QP_ATTR_INITIATOR_DEPTH) {
+		opt |= IB_MOD_QP_INIT_DEPTH;
+	}
+	if ((Options & WV_IO_QP_ATTR_ALTERNATE_AV) == WV_IO_QP_ATTR_ALTERNATE_AV) {
+		opt |= IB_MOD_QP_ALTERNATE_AV;
+	}
+	if ((Options & WV_IO_QP_ATTR_MIN_RNR_TIMER) == WV_IO_QP_ATTR_MIN_RNR_TIMER) {
+		opt |= IB_MOD_QP_RNR_NAK_TIMEOUT;
+	}
+	if ((Options & WV_IO_QP_ATTR_RESPONDER_RESOURCES) == WV_IO_QP_ATTR_RESPONDER_RESOURCES) {
+		opt |= IB_MOD_QP_RESP_RES;
+	}
+	if ((Options & WV_IO_QP_ATTR_PATH_MIG_STATE) == WV_IO_QP_ATTR_PATH_MIG_STATE) {
+		opt |= IB_MOD_QP_APM_STATE;
+	}
+	if ((Options & WV_IO_QP_ATTR_CAPABILITIES) == WV_IO_QP_ATTR_CAPABILITIES) {
+		opt |= IB_MOD_QP_SQ_DEPTH | IB_MOD_QP_RQ_DEPTH;
+	}
+
+	return (ib_qp_opts_t) opt;
+}
+
+static ib_qp_state_t WvVerbsConvertState(UINT8 State)
+{
+	switch (State) {
+	case WV_IO_QP_STATE_RESET:		return IB_QPS_RESET;
+	case WV_IO_QP_STATE_INIT:		return IB_QPS_INIT;
+	case WV_IO_QP_STATE_RTR:		return IB_QPS_RTR;
+	case WV_IO_QP_STATE_RTS:		return IB_QPS_RTS;
+	case WV_IO_QP_STATE_SQD:		return IB_QPS_SQD;
+	case WV_IO_QP_STATE_SQERROR:	return IB_QPS_SQERR;
+	default:						return IB_QPS_ERROR;
+	}
+}
+
+static void WvVerbsConvertAttr(ib_qp_mod_t *pVerbsAttr, WV_IO_QP_ATTRIBUTES *pAttr)
+{
+	switch (pAttr->QpState) {
+	case WV_IO_QP_STATE_RESET:
+		pVerbsAttr->req_state = IB_QPS_RESET;
+		break;
+	case WV_IO_QP_STATE_INIT:
+		pVerbsAttr->req_state = IB_QPS_INIT;
+
+		pVerbsAttr->state.init.primary_port = pAttr->PrimaryAddressVector.PortNumber;
+		pVerbsAttr->state.init.qkey			= pAttr->Qkey;
+		pVerbsAttr->state.init.pkey_index	= pAttr->PkeyIndex;
+		pVerbsAttr->state.init.access_ctrl	= pAttr->AccessFlags;
+		break;
+	case WV_IO_QP_STATE_RTR:
+		pVerbsAttr->req_state = IB_QPS_RTR;
+
+		pVerbsAttr->state.rtr.rq_psn		= pAttr->ReceivePsn;
+		pVerbsAttr->state.rtr.dest_qp		= pAttr->DestinationQpn;
+		WvVerbsConvertAv(&pVerbsAttr->state.rtr.primary_av,
+						 &pAttr->PrimaryAddressVector);
+		pVerbsAttr->state.rtr.resp_res		= (UINT8) pAttr->ResponderResources;
+		pVerbsAttr->state.rtr.rnr_nak_timeout = pAttr->RnrNakTimeout;
+
+		pVerbsAttr->state.rtr.opts = WvVerbsConvertOptions(pAttr->Options);
+		WvVerbsConvertAv(&pVerbsAttr->state.rtr.alternate_av,
+						 &pAttr->AlternateAddressVector);
+		pVerbsAttr->state.rtr.qkey			= pAttr->Qkey;
+		pVerbsAttr->state.rtr.pkey_index	= pAttr->PkeyIndex;
+		pVerbsAttr->state.rtr.access_ctrl	= pAttr->AccessFlags;
+		pVerbsAttr->state.rtr.sq_depth		= pAttr->SendDepth;
+		pVerbsAttr->state.rtr.rq_depth		= pAttr->ReceiveDepth;
+		break;
+	case WV_IO_QP_STATE_RTS:
+		pVerbsAttr->req_state = IB_QPS_RTS;
+
+		pVerbsAttr->state.rts.sq_psn		= pAttr->SendPsn;
+		pVerbsAttr->state.rts.retry_cnt		= pAttr->SequenceErrorRetryCount;
+		pVerbsAttr->state.rts.rnr_retry_cnt	= pAttr->RnrRetryCount;
+		pVerbsAttr->state.rts.local_ack_timeout = pAttr->LocalAckTimeout;
+		pVerbsAttr->state.rts.init_depth	= (UINT8) pAttr->InitiatorDepth;
+
+		pVerbsAttr->state.rts.opts = WvVerbsConvertOptions(pAttr->Options);
+		pVerbsAttr->state.rts.rnr_nak_timeout = pAttr->RnrNakTimeout;
+		pVerbsAttr->state.rts.current_state = WvVerbsConvertState(pAttr->CurrentQpState);
+		pVerbsAttr->state.rts.qkey			= pAttr->Qkey;
+		pVerbsAttr->state.rts.access_ctrl	= pAttr->AccessFlags;
+		pVerbsAttr->state.rts.resp_res		= (UINT8) pAttr->ResponderResources;
+
+		WvVerbsConvertAv(&pVerbsAttr->state.rts.primary_av,
+						 &pAttr->PrimaryAddressVector);
+		WvVerbsConvertAv(&pVerbsAttr->state.rts.alternate_av,
+						 &pAttr->AlternateAddressVector);
+
+		pVerbsAttr->state.rts.sq_depth		= pAttr->SendDepth;
+		pVerbsAttr->state.rts.rq_depth		= pAttr->ReceiveDepth;
+
+		pVerbsAttr->state.rts.apm_state		= pAttr->ApmState;
+		pVerbsAttr->state.rts.primary_port	= pAttr->PrimaryAddressVector.PortNumber;
+		pVerbsAttr->state.rts.pkey_index	= pAttr->PkeyIndex;
+		break;
+	case WV_IO_QP_STATE_SQD:
+		pVerbsAttr->req_state = IB_QPS_SQD;
+		pVerbsAttr->state.sqd.sqd_event = 1;
+		break;
+	case WV_IO_QP_STATE_SQERROR:
+		pVerbsAttr->req_state = IB_QPS_SQERR;
+		break;
+	default:
+		pVerbsAttr->req_state = IB_QPS_ERROR;
+		break;
+	}
+}
+
 static void WvQpGet(WV_QUEUE_PAIR *pQp)
 {
 	InterlockedIncrement(&pQp->Ref);
@@ -406,6 +563,41 @@
 	WdfRequestCompleteWithInformation(Request, status, len);
 }
 
+void WvQpModify(WV_PROVIDER *pProvider, WDFREQUEST Request)
+{
+	WV_IO_QP_ATTRIBUTES		*pattr;
+	UINT8					*out;
+	size_t					outlen, len = 0;
+	WV_QUEUE_PAIR			*qp;
+	ib_qp_mod_t				attr;
+	NTSTATUS				status;
+	ib_api_status_t			ib_status;
+
+	status = WdfRequestRetrieveInputBuffer(Request, sizeof(WV_IO_QP_ATTRIBUTES),
+										   &pattr, NULL);
+	if (!NT_SUCCESS(status)) {
+		goto complete;
+	}
+	status = WdfRequestRetrieveOutputBuffer(Request, 0, &out, &outlen);
+	if (!NT_SUCCESS(status) && status != STATUS_BUFFER_TOO_SMALL) {
+		goto complete;
+	}
+
+	WvVerbsConvertAttr(&attr, pattr);
+	qp = WvQpAcquire(pProvider, pattr->Id.Id);
+	if (qp == NULL) {
+		status = STATUS_NOT_FOUND;
+		goto complete;
+	}
+
+	ib_status = qp->pVerbs->ndi_modify_qp(qp->hVerbsQp, &attr, NULL, outlen, out);
+	WvQpRelease(qp);
+	len = outlen;
+
+complete:
+	WdfRequestCompleteWithInformation(Request, status, len);
+}
+
 void WvQpAttach(WV_PROVIDER *pProvider, WDFREQUEST Request)
 {
 	WV_MULTICAST			*pmc;
Index: core/winverbs/kernel/wv_qp.h
===================================================================
--- core/winverbs/kernel/wv_qp.h	(revision 1103)
+++ core/winverbs/kernel/wv_qp.h	(working copy)
@@ -64,7 +64,7 @@
 void WvQpFree(WV_QUEUE_PAIR *pQp);
 void WvQpRemoveHandler(WV_QUEUE_PAIR *pQp);
 
-//void WvQpModify(WV_PROVIDER *pProvider, WDFREQUEST Request);
+void WvQpModify(WV_PROVIDER *pProvider, WDFREQUEST Request);
 void WvQpQuery(WV_PROVIDER *pProvider, WDFREQUEST Request);
 void WvQpAttach(WV_PROVIDER *pProvider, WDFREQUEST Request);
 void WvQpDetach(WV_PROVIDER *pProvider, WDFREQUEST Request);
Index: core/winverbs/user/wv_qp.cpp
===================================================================
--- core/winverbs/user/wv_qp.cpp	(revision 1007)
+++ core/winverbs/user/wv_qp.cpp	(working copy)
@@ -168,6 +168,7 @@
 
 	pAttr->PathMtu = pIoAttr->PathMtu;
 	pAttr->LocalAckTimeout = pIoAttr->LocalAckTimeout;
+	pAttr->RnrNakTimeout = pIoAttr->RnrNakTimeout;
 	pAttr->SequenceErrorRetryCount = pIoAttr->SequenceErrorRetryCount;
 	pAttr->RnrRetryCount = pIoAttr->RnrRetryCount;
 }
@@ -202,6 +203,7 @@
 
 	pIoAttr->PathMtu = pAttr->PathMtu;
 	pIoAttr->LocalAckTimeout = pAttr->LocalAckTimeout;
+	pIoAttr->RnrNakTimeout = pAttr->RnrNakTimeout;
 	pIoAttr->SequenceErrorRetryCount = pAttr->SequenceErrorRetryCount;
 	pIoAttr->RnrRetryCount = pAttr->RnrRetryCount;
 }
Index: core/winverbs/wv_ioctl.h
===================================================================
--- core/winverbs/wv_ioctl.h	(revision 1097)
+++ core/winverbs/wv_ioctl.h	(working copy)
@@ -500,10 +500,32 @@
 #define WV_IO_QP_STATE_INIT		1
 #define WV_IO_QP_STATE_RTR		2
 #define WV_IO_QP_STATE_RTS		3
-#define WV_IO_QP_STATE_SDQ		4
+#define WV_IO_QP_STATE_SQD		4
 #define WV_IO_QP_STATE_SQERROR	5
 #define WV_IO_QP_STATE_ERROR	6
 
+#define WV_IO_QP_ATTR_STATE						0x00000001
+#define WV_IO_QP_ATTR_CURRENT_STATE				0x00000002
+#define WV_IO_QP_ATTR_ENABLE_SQD_ASYNC_NOTIFY	0x00000004
+#define WV_IO_QP_ATTR_ACCESS_FLAGS				0x00000008
+#define WV_IO_QP_ATTR_PKEY_INDEX				0x00000010
+#define WV_IO_QP_ATTR_PORT						0x00000020
+#define WV_IO_QP_ATTR_QKEY						0x00000040
+#define WV_IO_QP_ATTR_AV						0x00000080
+#define WV_IO_QP_ATTR_PATH_MTU					0x00000100
+#define WV_IO_QP_ATTR_TIMEOUT					0x00000200
+#define WV_IO_QP_ATTR_RETRY_COUNT				0x00000400
+#define WV_IO_QP_ATTR_RNR_RETRY					0x00000800
+#define WV_IO_QP_ATTR_RQ_PSN					0x00001000
+#define WV_IO_QP_ATTR_INITIATOR_DEPTH			0x00002000
+#define WV_IO_QP_ATTR_ALTERNATE_AV				0x00004000
+#define WV_IO_QP_ATTR_MIN_RNR_TIMER				0x00008000
+#define WV_IO_QP_ATTR_SQ_PSN					0x00010000
+#define WV_IO_QP_ATTR_RESPONDER_RESOURCES		0x00020000
+#define WV_IO_QP_ATTR_PATH_MIG_STATE			0x00040000
+#define WV_IO_QP_ATTR_CAPABILITIES				0x00080000
+#define WV_IO_QP_ATTR_DESTINATION_QPN			0x00100000
+
 typedef struct _WV_IO_QP_ATTRIBUTES
 {
 	WV_IO_ID		Id;
@@ -534,9 +556,10 @@
 
 	UINT8			PathMtu;
 	UINT8			LocalAckTimeout;
+	UINT8			RnrNakTimeout;
 	UINT8			SequenceErrorRetryCount;
 	UINT8			RnrRetryCount;
-	UINT32			Reserved;
+	UINT8			Reserved[3];
 
 }	WV_IO_QP_ATTRIBUTES;
 
Index: inc/user/rdma/winverbs.h
===================================================================
--- inc/user/rdma/winverbs.h	(revision 1070)
+++ inc/user/rdma/winverbs.h	(working copy)
@@ -392,6 +392,7 @@
 
 	UINT8				PathMtu;
 	UINT8				LocalAckTimeout;
+	UINT8				RnrNakTimeout;
 	UINT8				SequenceErrorRetryCount;
 	UINT8				RnrRetryCount;
 





More information about the ofw mailing list