2 * Copyright (c) 2014 VMware, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
27 /* Due to an imported header file */
28 #pragma warning( disable:4505 )
33 #define OVS_DBG_MOD OVS_DBG_DISPATCH
36 typedef struct _OVS_OID_CONTEXT {
37 NDIS_EVENT oidComplete;
39 } OVS_OID_CONTEXT, *POVS_OID_CONTEXT;
43 OvsExtOidRequestComplete(NDIS_HANDLE filterModuleContext,
44 PNDIS_OID_REQUEST oidRequest,
47 OvsOidRequestCompleteMethod(POVS_SWITCH_CONTEXT switchObject,
48 PNDIS_OID_REQUEST oidRequest,
49 PNDIS_OID_REQUEST origOidRequest,
52 OvsOidRequestCompleteSetInfo(POVS_SWITCH_CONTEXT switchObject,
53 PNDIS_OID_REQUEST oidRequest,
54 PNDIS_OID_REQUEST origOidRequest,
57 OvsOidRequestCompleteQuery(POVS_SWITCH_CONTEXT switchObject,
58 PNDIS_OID_REQUEST oidRequest,
59 PNDIS_OID_REQUEST origOidRequest,
63 OvsProcessSetOidPortProp(POVS_SWITCH_CONTEXT switchObject,
64 PNDIS_OID_REQUEST oidRequest);
66 OvsProcessSetOidPort(POVS_SWITCH_CONTEXT switchObject,
67 PNDIS_OID_REQUEST oidRequest);
69 OvsProcessSetOidNic(POVS_SWITCH_CONTEXT switchObject,
70 PNDIS_OID_REQUEST oidRequest);
73 OvsCheckOidHeaderFunc(PNDIS_OBJECT_HEADER header,
77 return header->Type != NDIS_OBJECT_TYPE_DEFAULT ||
78 header->Revision < propRev ||
79 header->Size < propSize;
82 #define OvsCheckOidHeader(_hdr, _rev) \
83 OvsCheckOidHeaderFunc(_hdr, _rev, ##NDIS_SIZEOF_##_rev)
86 OvsOidSetOrigRequest(PNDIS_OID_REQUEST clonedRequest,
87 PNDIS_OID_REQUEST origRequest)
89 *(PVOID*)(&clonedRequest->SourceReserved[0]) = origRequest;
92 static __inline PNDIS_OID_REQUEST
93 OvsOidGetOrigRequest(PNDIS_OID_REQUEST clonedRequest)
95 return *((PVOID*)(&clonedRequest->SourceReserved[0]));
99 OvsOidSetContext(PNDIS_OID_REQUEST clonedRequest,
100 POVS_OID_CONTEXT origRequest)
102 *(PVOID*)(&clonedRequest->SourceReserved[8]) = origRequest;
105 static __inline POVS_OID_CONTEXT
106 OvsOidGetContext(PNDIS_OID_REQUEST clonedRequest)
108 return *((PVOID*)(&clonedRequest->SourceReserved[8]));
112 OvsProcessSetOidPortProp(POVS_SWITCH_CONTEXT switchObject,
113 PNDIS_OID_REQUEST oidRequest)
115 NDIS_STATUS status = NDIS_STATUS_SUCCESS;
116 struct _SET *setInfo = &(oidRequest->DATA.SET_INFORMATION);
117 PNDIS_SWITCH_PORT_PROPERTY_PARAMETERS portPropParam =
118 setInfo->InformationBuffer;
119 BOOLEAN checkFailed = TRUE;
121 UNREFERENCED_PARAMETER(switchObject);
123 if (setInfo->Oid == OID_SWITCH_PORT_PROPERTY_DELETE) {
124 checkFailed = OvsCheckOidHeader(
125 (PNDIS_OBJECT_HEADER)portPropParam,
126 NDIS_SWITCH_PORT_PROPERTY_DELETE_PARAMETERS_REVISION_1);
128 /* it must be a add or update request */
129 checkFailed = OvsCheckOidHeader(
130 (PNDIS_OBJECT_HEADER)portPropParam,
131 NDIS_SWITCH_PORT_PROPERTY_PARAMETERS_REVISION_1);
135 status = NDIS_STATUS_INVALID_PARAMETER;
139 if (portPropParam->PropertyType == NdisSwitchPortPropertyTypeVlan) {
140 status = NDIS_STATUS_NOT_SUPPORTED;
149 OvsProcessSetOidPort(POVS_SWITCH_CONTEXT switchObject,
150 PNDIS_OID_REQUEST oidRequest)
152 NDIS_STATUS status = NDIS_STATUS_SUCCESS;
153 struct _SET *setInfo = &(oidRequest->DATA.SET_INFORMATION);
154 PNDIS_SWITCH_PORT_PARAMETERS portParam = setInfo->InformationBuffer;
156 if (OvsCheckOidHeader((PNDIS_OBJECT_HEADER)portParam,
157 NDIS_SWITCH_PORT_PARAMETERS_REVISION_1)) {
158 status = NDIS_STATUS_NOT_SUPPORTED;
162 switch(setInfo->Oid) {
163 case OID_SWITCH_PORT_CREATE:
164 status = HvCreatePort(switchObject, portParam);
166 case OID_SWITCH_PORT_TEARDOWN:
167 HvTeardownPort(switchObject, portParam);
169 case OID_SWITCH_PORT_DELETE:
170 HvDeletePort(switchObject, portParam);
181 OvsProcessSetOidNic(POVS_SWITCH_CONTEXT switchObject,
182 PNDIS_OID_REQUEST oidRequest)
184 NDIS_STATUS status = NDIS_STATUS_SUCCESS;
185 struct _SET *setInfo = &(oidRequest->DATA.SET_INFORMATION);
186 PNDIS_SWITCH_NIC_PARAMETERS nicParam = setInfo->InformationBuffer;
188 if (OvsCheckOidHeader((PNDIS_OBJECT_HEADER)nicParam,
189 NDIS_SWITCH_NIC_PARAMETERS_REVISION_1)) {
190 status = NDIS_STATUS_NOT_SUPPORTED;
194 switch(setInfo->Oid) {
195 case OID_SWITCH_NIC_CREATE:
196 status = HvCreateNic(switchObject, nicParam);
198 case OID_SWITCH_NIC_CONNECT:
199 HvConnectNic(switchObject, nicParam);
201 case OID_SWITCH_NIC_UPDATED:
202 HvUpdateNic(switchObject, nicParam);
204 case OID_SWITCH_NIC_DISCONNECT:
205 HvDisconnectNic(switchObject, nicParam);
207 case OID_SWITCH_NIC_DELETE:
208 HvDeleteNic(switchObject, nicParam);
220 OvsProcessSetOid(POVS_SWITCH_CONTEXT switchObject,
221 PNDIS_OID_REQUEST oidRequest,
224 NDIS_STATUS status = NDIS_STATUS_SUCCESS;
225 struct _SET *setInfo = &(oidRequest->DATA.SET_INFORMATION);
229 OVS_LOG_TRACE("Enter: oidRequest %p, Oid: %lu",
230 oidRequest, setInfo->Oid);
232 /* Verify the basic Oid paramters first */
233 if (setInfo->InformationBufferLength &&
234 (setInfo->InformationBufferLength < sizeof(NDIS_OBJECT_HEADER))) {
235 status = NDIS_STATUS_INVALID_OID;
236 OVS_LOG_INFO("Invalid input %d", setInfo->InformationBufferLength);
240 /* Documentation does not specify what should be done
241 * if informationBuffer is not present. Although it mentions the
242 * structure type informationBUffer points to for each oid request,
243 * but it does not explicitly mention that it is a MUST.
244 * hence we are following this scenario same way as what sample code
246 if (!(setInfo->InformationBufferLength)) {
247 /* We cannot do anything about this oid request,
248 * lets just pass it down. */
249 OVS_LOG_INFO("Buffer Length Zero");
253 switch(setInfo->Oid) {
254 case OID_SWITCH_PORT_PROPERTY_ADD:
255 case OID_SWITCH_PORT_PROPERTY_UPDATE:
256 case OID_SWITCH_PORT_PROPERTY_DELETE:
257 status = OvsProcessSetOidPortProp(switchObject, oidRequest);
260 case OID_SWITCH_PORT_CREATE:
261 case OID_SWITCH_PORT_UPDATED:
262 case OID_SWITCH_PORT_TEARDOWN:
263 case OID_SWITCH_PORT_DELETE:
264 status = OvsProcessSetOidPort(switchObject, oidRequest);
267 case OID_SWITCH_NIC_CREATE:
268 case OID_SWITCH_NIC_CONNECT:
269 case OID_SWITCH_NIC_UPDATED:
270 case OID_SWITCH_NIC_DISCONNECT:
271 case OID_SWITCH_NIC_DELETE:
272 status = OvsProcessSetOidNic(switchObject, oidRequest);
276 /* Non handled OID request */
280 if (status != NDIS_STATUS_SUCCESS) {
289 OVS_LOG_TRACE("Exit: status %8x.", status);
294 OvsProcessMethodOid(POVS_SWITCH_CONTEXT switchObject,
295 PNDIS_OID_REQUEST oidRequest,
297 PULONG bytesNeededParam)
299 NDIS_STATUS status = NDIS_STATUS_SUCCESS;
300 struct _METHOD *methodInfo = &(oidRequest->DATA.METHOD_INFORMATION);
301 struct _SET *nicReqSetInfo = NULL;
302 PNDIS_OBJECT_HEADER header = NULL;
303 PNDIS_OID_REQUEST nicOidRequest = NULL;
305 UNREFERENCED_PARAMETER(switchObject);
307 OVS_LOG_TRACE("Enter: oidRequest %p, Oid: %lu",
308 oidRequest, methodInfo->Oid);
311 *bytesNeededParam = 0;
312 header = methodInfo->InformationBuffer;
314 switch(methodInfo->Oid) {
315 /* We deal with only OID_SWITCH_NIC_REQUEST as of now */
316 case OID_SWITCH_NIC_REQUEST:
317 if (OvsCheckOidHeader(header,
318 NDIS_SWITCH_NIC_OID_REQUEST_REVISION_1)) {
319 OVS_LOG_INFO("Check Header failed");
320 status = NDIS_STATUS_NOT_SUPPORTED;
325 nicOidRequest = (((PNDIS_SWITCH_NIC_OID_REQUEST)header)->OidRequest);
326 nicReqSetInfo = &(nicOidRequest->DATA.SET_INFORMATION);
328 /* Fail the SR-IOV VF case */
329 if ((nicOidRequest->RequestType == NdisRequestSetInformation) &&
330 (nicReqSetInfo->Oid == OID_NIC_SWITCH_ALLOCATE_VF)) {
331 OVS_LOG_INFO("We do not support Oid: "
332 "OID_NIC_SWITCH_ALLOCATE_VF");
333 status = NDIS_STATUS_FAILURE;
343 OVS_LOG_TRACE("Exit: status %8x.", status);
348 * --------------------------------------------------------------------------
349 * Implements filter driver's FilterOidRequest function.
350 * --------------------------------------------------------------------------
354 OvsExtOidRequest(NDIS_HANDLE filterModuleContext,
355 PNDIS_OID_REQUEST oidRequest)
357 POVS_SWITCH_CONTEXT switchObject = (POVS_SWITCH_CONTEXT)filterModuleContext;
358 NDIS_STATUS status = NDIS_STATUS_SUCCESS;
359 PNDIS_OID_REQUEST clonedOidRequest = NULL;
360 struct _METHOD *methodInfo = &(oidRequest->DATA.METHOD_INFORMATION);
361 BOOLEAN completeOid = FALSE;
362 ULONG bytesNeeded = 0;
364 OVS_LOG_TRACE("Enter: oidRequest %p, reqType: %d",
365 oidRequest, oidRequest->RequestType);
366 status = NdisAllocateCloneOidRequest(switchObject->NdisFilterHandle,
367 oidRequest, OVS_MEMORY_TAG,
369 if (status != NDIS_STATUS_SUCCESS) {
373 NdisInterlockedIncrement(&(switchObject->pendingOidCount));
375 /* set the original oid request in cloned one. */
376 OvsOidSetOrigRequest(clonedOidRequest, oidRequest);
377 OvsOidSetContext(clonedOidRequest, NULL);
379 switch(clonedOidRequest->RequestType) {
380 case NdisRequestSetInformation:
381 status = OvsProcessSetOid(switchObject, clonedOidRequest,
384 case NdisRequestMethod:
385 status = OvsProcessMethodOid(switchObject, clonedOidRequest,
386 &completeOid, &bytesNeeded);
389 /* We do not handle other request types as of now.
390 * We are just a passthrough for those. */
394 if (completeOid == TRUE) {
395 /* dont leave any reference back to original request,
396 * even if we are freeing it up. */
397 OVS_LOG_INFO("Complete True oidRequest %p.", oidRequest);
398 OvsOidSetOrigRequest(clonedOidRequest, NULL);
399 NdisFreeCloneOidRequest(switchObject->NdisFilterHandle,
401 methodInfo->BytesNeeded = bytesNeeded;
402 NdisInterlockedDecrement(&switchObject->pendingOidCount);
406 /* pass the request down */
407 status = NdisFOidRequest(switchObject->NdisFilterHandle, clonedOidRequest);
408 if (status != NDIS_STATUS_PENDING) {
409 OvsExtOidRequestComplete(switchObject, clonedOidRequest, status);
410 /* sample code says so */
411 status = NDIS_STATUS_PENDING;
415 OVS_LOG_TRACE("Exit: status %8x.", status);
420 * --------------------------------------------------------------------------
421 * Implements filter driver's FilterOidRequestComplete function.
422 * --------------------------------------------------------------------------
425 OvsExtOidRequestComplete(NDIS_HANDLE filterModuleContext,
426 PNDIS_OID_REQUEST oidRequest,
429 POVS_SWITCH_CONTEXT switchObject = (POVS_SWITCH_CONTEXT)filterModuleContext;
430 PNDIS_OID_REQUEST origReq = OvsOidGetOrigRequest(oidRequest);
431 POVS_OID_CONTEXT oidContext = OvsOidGetContext(oidRequest);
433 /* Only one of the two should be set */
434 ASSERT(origReq != NULL || oidContext != NULL);
435 ASSERT(oidContext != NULL || origReq != NULL);
437 OVS_LOG_TRACE("Enter: oidRequest %p, reqType: %d",
438 oidRequest, oidRequest->RequestType);
440 if (origReq == NULL) {
441 NdisInterlockedDecrement(&(switchObject->pendingOidCount));
442 oidContext->status = status;
443 NdisSetEvent(&oidContext->oidComplete);
444 OVS_LOG_INFO("Internally generated request");
448 switch(oidRequest->RequestType) {
449 case NdisRequestMethod:
450 OvsOidRequestCompleteMethod(switchObject, oidRequest,
454 case NdisRequestSetInformation:
455 OvsOidRequestCompleteSetInfo(switchObject, oidRequest,
459 case NdisRequestQueryInformation:
460 case NdisRequestQueryStatistics:
462 OvsOidRequestCompleteQuery(switchObject, oidRequest,
467 OvsOidSetOrigRequest(oidRequest, NULL);
469 NdisFreeCloneOidRequest(switchObject->NdisFilterHandle, oidRequest);
470 NdisFOidRequestComplete(switchObject->NdisFilterHandle, origReq, status);
471 NdisInterlockedDecrement(&(switchObject->pendingOidCount));
474 OVS_LOG_TRACE("Exit");
478 OvsOidRequestCompleteMethod(POVS_SWITCH_CONTEXT switchObject,
479 PNDIS_OID_REQUEST oidRequest,
480 PNDIS_OID_REQUEST origOidRequest,
483 UNREFERENCED_PARAMETER(status);
484 UNREFERENCED_PARAMETER(switchObject);
486 struct _METHOD *methodInfo = &(oidRequest->DATA.METHOD_INFORMATION);
487 struct _METHOD *origMethodInfo = &(origOidRequest->DATA.
490 OVS_LOG_TRACE("Enter: oidRequest %p, Oid: %lu",
491 oidRequest, methodInfo->Oid);
493 origMethodInfo->OutputBufferLength = methodInfo->OutputBufferLength;
494 origMethodInfo->BytesRead = methodInfo->BytesRead;
495 origMethodInfo->BytesNeeded = methodInfo->BytesNeeded;
496 origMethodInfo->BytesWritten = methodInfo->BytesWritten;
498 OVS_LOG_TRACE("Exit");
502 OvsOidRequestCompleteSetInfo(POVS_SWITCH_CONTEXT switchObject,
503 PNDIS_OID_REQUEST oidRequest,
504 PNDIS_OID_REQUEST origOidRequest,
507 struct _SET *setInfo = &(oidRequest->DATA.SET_INFORMATION);
508 struct _SET *origSetInfo = &(origOidRequest->DATA.SET_INFORMATION);
509 PNDIS_OBJECT_HEADER origHeader = origSetInfo->InformationBuffer;
511 OVS_LOG_TRACE("Enter: oidRequest %p, Oid: %lu",
512 oidRequest, setInfo->Oid);
514 origSetInfo->BytesRead = setInfo->BytesRead;
515 origSetInfo->BytesNeeded = setInfo->BytesNeeded;
517 if (status != NDIS_STATUS_SUCCESS) {
519 switch(setInfo->Oid) {
520 case OID_SWITCH_PORT_CREATE:
521 HvDeletePort(switchObject,
522 (PNDIS_SWITCH_PORT_PARAMETERS)origHeader);
525 case OID_SWITCH_NIC_CREATE:
526 HvDeleteNic(switchObject,
527 (PNDIS_SWITCH_NIC_PARAMETERS)origHeader);
535 OVS_LOG_TRACE("Exit");
539 OvsOidRequestCompleteQuery(POVS_SWITCH_CONTEXT switchObject,
540 PNDIS_OID_REQUEST oidRequest,
541 PNDIS_OID_REQUEST origOidRequest,
544 UNREFERENCED_PARAMETER(switchObject);
545 UNREFERENCED_PARAMETER(status);
547 struct _QUERY *queryInfo = &((oidRequest->DATA).QUERY_INFORMATION);
548 struct _QUERY *origQueryInfo = &((origOidRequest->DATA).QUERY_INFORMATION);
550 OVS_LOG_TRACE("Enter: oidRequest %p, Oid: %lu",
551 oidRequest, queryInfo->Oid);
553 origQueryInfo->BytesWritten = queryInfo->BytesWritten;
554 origQueryInfo->BytesNeeded = queryInfo->BytesNeeded;
556 OVS_LOG_TRACE("Exit");
560 * --------------------------------------------------------------------------
561 * Implements filter driver's FilterCancelOidRequest function.
562 * --------------------------------------------------------------------------
565 OvsExtCancelOidRequest(NDIS_HANDLE filterModuleContext,
568 OVS_LOG_TRACE("Enter: requestId: %p", requestId);
570 UNREFERENCED_PARAMETER(filterModuleContext);
571 UNREFERENCED_PARAMETER(requestId);
576 * --------------------------------------------------------------------------
577 * Utility function to issue the specified OID to the NDIS stack. The OID is
578 * directed towards the miniport edge of the extensible switch.
579 * An OID that gets issued may not complete immediately, and in such cases, the
580 * function waits for the OID to complete. Thus, this function must not be
581 * called at the PASSIVE_LEVEL.
582 * --------------------------------------------------------------------------
585 OvsIssueOidRequest(POVS_SWITCH_CONTEXT switchContext,
586 NDIS_REQUEST_TYPE oidType,
587 UINT32 oidRequestEnum,
588 PVOID oidInputBuffer,
590 PVOID oidOutputBuffer,
592 UINT32 *outputSizeNeeded)
595 PNDIS_OID_REQUEST oidRequest;
596 POVS_OID_CONTEXT oidContext;
597 ULONG OvsExtOidRequestId = 'ISVO';
599 DBG_UNREFERENCED_PARAMETER(inputSize);
600 DBG_UNREFERENCED_PARAMETER(oidInputBuffer);
602 OVS_LOG_TRACE("Enter: switchContext: %p, oidType: %d",
603 switchContext, oidType);
605 ASSERT(oidInputBuffer == NULL || inputSize != 0);
606 ASSERT(oidOutputBuffer == NULL || outputSize != 0);
607 ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
609 oidRequest = OvsAllocateMemory(sizeof *oidRequest);
611 status = NDIS_STATUS_RESOURCES;
615 oidContext = OvsAllocateMemory(sizeof *oidContext);
617 OvsFreeMemory(oidRequest);
618 status = NDIS_STATUS_RESOURCES;
622 RtlZeroMemory(oidRequest, sizeof *oidRequest);
623 RtlZeroMemory(oidContext, sizeof *oidContext);
625 oidRequest->Header.Type = NDIS_OBJECT_TYPE_OID_REQUEST;
626 oidRequest->Header.Revision = NDIS_OID_REQUEST_REVISION_1;
627 oidRequest->Header.Size = NDIS_SIZEOF_OID_REQUEST_REVISION_1;
629 oidRequest->RequestType = oidType;
630 oidRequest->PortNumber = 0;
631 oidRequest->Timeout = 0;
632 oidRequest->RequestId = (PVOID)OvsExtOidRequestId;
635 case NdisRequestQueryInformation:
636 oidRequest->DATA.QUERY_INFORMATION.Oid = oidRequestEnum;
637 oidRequest->DATA.QUERY_INFORMATION.InformationBuffer = oidOutputBuffer;
638 oidRequest->DATA.QUERY_INFORMATION.InformationBufferLength = outputSize;
642 status = NDIS_STATUS_INVALID_PARAMETER;
647 * We make use of the SourceReserved field in the OID request to store
648 * pointers to the original OID (if any), and also context for completion
651 oidContext->status = NDIS_STATUS_SUCCESS;
652 NdisInitializeEvent(&oidContext->oidComplete);
654 OvsOidSetOrigRequest(oidRequest, NULL);
655 OvsOidSetContext(oidRequest, oidContext);
657 NdisInterlockedIncrement(&(switchContext->pendingOidCount));
658 status = NdisFOidRequest(switchContext->NdisFilterHandle, oidRequest);
659 if (status == NDIS_STATUS_PENDING) {
660 NdisWaitEvent(&oidContext->oidComplete, 0);
662 NdisInterlockedDecrement(&(switchContext->pendingOidCount));
665 if (status == NDIS_STATUS_INVALID_LENGTH ||
666 oidContext->status == NDIS_STATUS_INVALID_LENGTH) {
668 case NdisRequestQueryInformation:
669 *outputSizeNeeded = oidRequest->DATA.QUERY_INFORMATION.BytesNeeded;
673 status = oidContext->status;
674 ASSERT(status != NDIS_STATUS_PENDING);
676 OvsFreeMemory(oidRequest);
677 OvsFreeMemory(oidContext);
680 OVS_LOG_TRACE("Exit: status %8x.", status);
686 * --------------------------------------------------------------------------
687 * Utility function to query if the extensible switch has completed activation
689 * --------------------------------------------------------------------------
692 OvsQuerySwitchActivationComplete(POVS_SWITCH_CONTEXT switchContext,
693 BOOLEAN *switchActive)
696 PNDIS_SWITCH_PARAMETERS switchParams;
697 UINT32 outputSizeNeeded;
699 OVS_LOG_TRACE("Enter: switchContext: %p, switchActive: %p",
700 switchContext, switchActive);
702 switchParams = OvsAllocateMemory(sizeof *switchParams);
704 status = NDIS_STATUS_RESOURCES;
709 * Even though 'switchParms' is supposed to be populated by the OID, it
710 * needs to be initialized nevertheless. Otherwise, OID returns
711 * NDIS_STATUS_INVALID_PARAMETER. This is not clear in the documentation.
713 RtlZeroMemory(switchParams, sizeof *switchParams);
714 switchParams->Header.Revision = NDIS_SWITCH_PARAMETERS_REVISION_1;
715 switchParams->Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
716 switchParams->Header.Size = NDIS_SIZEOF_NDIS_SWITCH_PARAMETERS_REVISION_1;
718 status = OvsIssueOidRequest(switchContext, NdisRequestQueryInformation,
719 OID_SWITCH_PARAMETERS, NULL, 0,
720 (PVOID)switchParams, sizeof *switchParams,
723 ASSERT(status != NDIS_STATUS_INVALID_LENGTH);
724 ASSERT(status != NDIS_STATUS_PENDING);
725 if (status == NDIS_STATUS_SUCCESS) {
726 ASSERT(switchParams->Header.Type == NDIS_OBJECT_TYPE_DEFAULT);
727 ASSERT(switchParams->Header.Revision == NDIS_SWITCH_PARAMETERS_REVISION_1);
728 ASSERT(switchParams->Header.Size ==
729 NDIS_SIZEOF_NDIS_SWITCH_PARAMETERS_REVISION_1);
730 *switchActive = switchParams->IsActive;
733 OvsFreeMemory(switchParams);
736 OVS_LOG_TRACE("Exit: status %8x, switchActive: %d.",
737 status, *switchActive);
743 * --------------------------------------------------------------------------
744 * Utility function to get the array of ports on the extensible switch. Upon
745 * success, the caller needs to free the returned array.
746 * --------------------------------------------------------------------------
749 OvsGetPortsOnSwitch(POVS_SWITCH_CONTEXT switchContext,
750 PNDIS_SWITCH_PORT_ARRAY *portArrayOut)
752 PNDIS_SWITCH_PORT_ARRAY portArray;
753 UINT32 arraySize = sizeof *portArray;
754 NDIS_STATUS status = NDIS_STATUS_FAILURE;
756 OVS_LOG_TRACE("Enter: switchContext: %p, portArray: %p",
757 switchContext, portArrayOut);
759 UINT32 reqdArraySize;
761 portArray = OvsAllocateMemory(arraySize);
763 status = NDIS_STATUS_RESOURCES;
768 * Even though 'portArray' is supposed to be populated by the OID, it
769 * needs to be initialized nevertheless. Otherwise, OID returns
770 * NDIS_STATUS_INVALID_PARAMETER. This is not clear in the documentation.
772 RtlZeroMemory(portArray, sizeof *portArray);
773 portArray->Header.Revision = NDIS_SWITCH_PORT_ARRAY_REVISION_1;
774 portArray->Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
775 portArray->Header.Size = NDIS_SIZEOF_NDIS_SWITCH_PORT_ARRAY_REVISION_1;
777 status = OvsIssueOidRequest(switchContext, NdisRequestQueryInformation,
778 OID_SWITCH_PORT_ARRAY, NULL, 0,
779 (PVOID)portArray, arraySize,
781 if (status == NDIS_STATUS_SUCCESS) {
782 *portArrayOut = portArray;
786 OvsFreeMemory(portArray);
787 arraySize = reqdArraySize;
788 if (status != NDIS_STATUS_INVALID_LENGTH) {
791 } while(status == NDIS_STATUS_INVALID_LENGTH);
794 OVS_LOG_TRACE("Exit: status %8x.", status);
800 * --------------------------------------------------------------------------
801 * Utility function to get the array of nics on the extensible switch. Upon
802 * success, the caller needs to free the returned array.
803 * --------------------------------------------------------------------------
806 OvsGetNicsOnSwitch(POVS_SWITCH_CONTEXT switchContext,
807 PNDIS_SWITCH_NIC_ARRAY *nicArrayOut)
809 PNDIS_SWITCH_NIC_ARRAY nicArray;
810 UINT32 arraySize = sizeof *nicArray;
811 NDIS_STATUS status = NDIS_STATUS_FAILURE;
813 OVS_LOG_TRACE("Enter: switchContext: %p, nicArray: %p",
814 switchContext, nicArrayOut);
817 UINT32 reqdArraySize;
819 nicArray = OvsAllocateMemory(arraySize);
821 status = NDIS_STATUS_RESOURCES;
826 * Even though 'nicArray' is supposed to be populated by the OID, it
827 * needs to be initialized nevertheless. Otherwise, OID returns
828 * NDIS_STATUS_INVALID_PARAMETER. This is not clear in the documentation.
830 RtlZeroMemory(nicArray, sizeof *nicArray);
831 nicArray->Header.Revision = NDIS_SWITCH_NIC_ARRAY_REVISION_1;
832 nicArray->Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
833 nicArray->Header.Size = NDIS_SIZEOF_NDIS_SWITCH_NIC_ARRAY_REVISION_1;
835 status = OvsIssueOidRequest(switchContext, NdisRequestQueryInformation,
836 OID_SWITCH_NIC_ARRAY, NULL, 0,
837 (PVOID)nicArray, arraySize,
839 if (status == NDIS_STATUS_SUCCESS) {
840 *nicArrayOut = nicArray;
844 OvsFreeMemory(nicArray);
845 arraySize = reqdArraySize;
846 if (status != NDIS_STATUS_INVALID_LENGTH) {
849 } while(status == NDIS_STATUS_INVALID_LENGTH);
852 OVS_LOG_TRACE("Exit: status %8x.", status);