summaryrefslogtreecommitdiffstats
path: root/private/ntos/ndis/dc21x4/request.c
diff options
context:
space:
mode:
Diffstat (limited to 'private/ntos/ndis/dc21x4/request.c')
-rw-r--r--private/ntos/ndis/dc21x4/request.c530
1 files changed, 530 insertions, 0 deletions
diff --git a/private/ntos/ndis/dc21x4/request.c b/private/ntos/ndis/dc21x4/request.c
new file mode 100644
index 000000000..a29f09643
--- /dev/null
+++ b/private/ntos/ndis/dc21x4/request.c
@@ -0,0 +1,530 @@
+/*+
+ * file: request.c
+ *
+ * Copyright (C) 1992-1995 by
+ * Digital Equipment Corporation, Maynard, Massachusetts.
+ * All rights reserved.
+ *
+ * This software is furnished under a license and may be used and copied
+ * only in accordance of the terms of such license and with the
+ * inclusion of the above copyright notice. This software or any other
+ * copies thereof may not be provided or otherwise made available to any
+ * other person. No title to and ownership of the software is hereby
+ * transferred.
+ *
+ * The information in this software is subject to change without notice
+ * and should not be construed as a commitment by digital equipment
+ * corporation.
+ *
+ * Digital assumes no responsibility for the use or reliability of its
+ * software on equipment which is not supplied by digital.
+ *
+ *
+ * Abstract: This file contains the request handler for the NDIS 4.0
+ * miniport driver for DEC's DC21X4 Ethernet adapter.
+ *
+ * Author: Philippe Klein
+ *
+ * Revision History:
+ *
+ * phk 28-Aug-1994 Initial entry
+ *
+-*/
+
+#include <precomp.h>
+
+
+
+
+
+
+/*+
+ *
+ * DC21X4QueryInformation
+ *
+ * Routine Description:
+ *
+ * DC21X4QueryInformation handles a query operation for a
+ * single OID.
+ *
+-*/
+
+extern
+NDIS_STATUS
+DC21X4QueryInformation(
+ IN NDIS_HANDLE MiniportAdapterContext,
+ IN NDIS_OID Oid,
+ IN PVOID InformationBuffer,
+ IN ULONG InformationBufferLength,
+ OUT PULONG BytesWritten,
+ OUT PULONG BytesNeeded
+ )
+
+{
+ NDIS_STATUS NdisStatus;
+ PDC21X4_ADAPTER Adapter;
+
+ PNDIS_OID OidArray;
+ NDIS_OID OidIndex;
+ INT MaxOid;
+ BOOLEAN ValidOid;
+
+ UINT MissedFrames;
+ UINT Overflows;
+
+ ULONG Buffer;
+ PVOID BufferPtr;
+ UINT BufferLength;
+
+ INT i;
+
+#if _DBG
+ DbgPrint("DC21X4QueryInformation\n");
+ DbgPrint(" Oid = %08x\n",Oid);
+#endif
+
+ Adapter = (PDC21X4_ADAPTER)MiniportAdapterContext;
+
+ // Check that the OID is valid.
+
+ OidArray = (PNDIS_OID)DC21X4GlobalOids;
+ MaxOid = sizeof(DC21X4GlobalOids)/sizeof(ULONG);
+
+ ValidOid = FALSE;
+
+ for (i=0; i<MaxOid; i++) {
+
+ if (Oid == OidArray[i]) {
+ ValidOid = TRUE;
+ break;
+ }
+ }
+ if (ValidOid == FALSE) {
+#if _DBG
+ DbgPrint(" INVALID Oid\n");
+#endif
+ *BytesWritten = 0;
+ return NDIS_STATUS_INVALID_OID;
+ }
+
+ BufferPtr = &Buffer;
+ BufferLength = sizeof(Buffer);
+
+ switch (Oid & OID_TYPE_MASK) {
+
+ case OID_TYPE_GENERAL_OPERATIONAL:
+
+ switch (Oid) {
+
+ case OID_GEN_SUPPORTED_LIST:
+
+ BufferPtr = (PVOID)OidArray;
+ BufferLength = sizeof(DC21X4GlobalOids);
+ break;
+
+ case OID_GEN_HARDWARE_STATUS:
+
+ Buffer = NdisHardwareStatusReady;
+ break;
+
+ case OID_GEN_MEDIA_SUPPORTED:
+ case OID_GEN_MEDIA_IN_USE:
+
+ Buffer = NdisMedium802_3;
+ break;
+
+ case OID_GEN_MEDIA_CONNECT_STATUS:
+
+ Buffer = Adapter->LinkStatus == LinkFail ?
+ NdisMediaStateDisconnected : NdisMediaStateConnected;
+ break;
+
+ case OID_GEN_MAXIMUM_LOOKAHEAD:
+
+ Buffer = DC21X4_MAX_LOOKAHEAD;
+ break;
+
+ case OID_GEN_MAXIMUM_FRAME_SIZE:
+
+ Buffer = DC21X4_MAX_FRAME_SIZE - ETH_HEADER_SIZE;
+ break;
+
+ case OID_GEN_MAXIMUM_TOTAL_SIZE:
+
+ Buffer = DC21X4_MAX_FRAME_SIZE;
+ break;
+
+ case OID_GEN_LINK_SPEED:
+
+ Buffer = Adapter->LinkSpeed;
+ break;
+
+ case OID_GEN_MAC_OPTIONS:
+
+ Buffer = NDIS_MAC_OPTION_TRANSFERS_NOT_PEND
+ | NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA
+ | NDIS_MAC_OPTION_RECEIVE_SERIALIZED
+ | NDIS_MAC_OPTION_NO_LOOPBACK;
+ if (Adapter->FullDuplexLink) {
+ Buffer |= NDIS_MAC_OPTION_FULL_DUPLEX;
+ }
+ Adapter->FullDuplex = Adapter->FullDuplexLink;
+ break;
+
+ case OID_GEN_PROTOCOL_OPTIONS:
+
+ BufferLength = 0;
+ break;
+
+ case OID_GEN_TRANSMIT_BUFFER_SPACE:
+
+ Buffer =
+ ((DC21X4_NUMBER_OF_MAX_TRANSMIT_BUFFERS)
+ *(DC21X4_MAX_TRANSMIT_BUFFER_SIZE + Adapter->CacheLineSize))
+ + ((DC21X4_NUMBER_OF_MAX_TRANSMIT_BUFFERS)
+ *(DC21X4_MAX_TRANSMIT_BUFFER_SIZE + Adapter->CacheLineSize))
+ + (DC21X4_SETUP_BUFFER_SIZE);
+ break;
+
+ case OID_GEN_RECEIVE_BUFFER_SPACE:
+
+ if (Adapter->RcvBufferSpace.AllocSize) {
+ Buffer = Adapter->RcvBufferSpace.AllocSize;
+ }
+ else {
+ Buffer =
+ ( (Adapter->ReceiveRingSize + Adapter->ExtraReceiveBuffers)
+ * (DC21X4_RECEIVE_BUFFER_SIZE + Adapter->RcvHeaderSize + Adapter->CacheLineSize)
+ );
+ }
+ break;
+
+ case OID_GEN_TRANSMIT_BLOCK_SIZE:
+
+ Buffer = DC21X4_MAX_TRANSMIT_BUFFER_SIZE;
+ break;
+
+ case OID_GEN_RECEIVE_BLOCK_SIZE:
+
+ Buffer = DC21X4_RECEIVE_BUFFER_SIZE;
+ break;
+
+ case OID_GEN_VENDOR_ID:
+
+ if (Adapter->PermanentAddressValid) {
+
+ Buffer = 0;
+ MOVE_MEMORY (BufferPtr, Adapter->PermanentNetworkAddress, 3);
+ BufferLength = 3;
+ }
+ else {
+ BufferLength = 0;
+ }
+ break;
+
+ case OID_GEN_VENDOR_DESCRIPTION:
+
+ switch(Adapter->DeviceId) {
+
+ case DC21040_CFID:
+
+ switch (Adapter->AdapterType) {
+
+ case NdisInterfaceEisa:
+
+ BufferPtr = (PVOID)DC21040EisaDescriptor;
+ BufferLength = sizeof(DC21040EisaDescriptor);
+ break;
+
+ default:
+ case NdisInterfacePci:
+
+ BufferPtr = (PVOID)DC21040PciDescriptor;
+ BufferLength = sizeof(DC21040PciDescriptor);
+ break;
+ }
+ break;
+
+ case DC21041_CFID:
+
+ BufferPtr = (PVOID)DC21041PciDescriptor;
+ BufferLength = sizeof(DC21041PciDescriptor);
+ break;
+
+ case DC21140_CFID:
+
+ BufferPtr = (PVOID)DC21140PciDescriptor;
+ BufferLength = sizeof(DC21140PciDescriptor);
+ break;
+
+ case DC21142_CFID:
+
+ BufferPtr = (PVOID)DC21142PciDescriptor;
+ BufferLength = sizeof(DC21142PciDescriptor);
+ break;
+
+
+ default:
+
+ BufferLength = 0;
+ }
+
+ break;
+
+ case OID_GEN_CURRENT_LOOKAHEAD:
+
+ Buffer = DC21X4_MAX_LOOKAHEAD;
+ break;
+
+ case OID_GEN_DRIVER_VERSION:
+
+ Buffer = (DC21X4_NDIS_MAJOR_VERSION << 8)
+ + DC21X4_NDIS_MINOR_VERSION;
+ BufferLength = sizeof(USHORT);
+ }
+
+ break;
+
+ case OID_TYPE_GENERAL_STATISTICS:
+
+ DC21X4_READ_PORT(
+ DC21X4_MISSED_FRAME,
+ &Buffer
+ );
+
+ MissedFrames = Buffer & DC21X4_MISSED_FRAME_COUNTER;
+ Adapter->GeneralMandatory[GM_MISSED_FRAMES] += MissedFrames;
+
+ switch(Adapter->DeviceId) {
+
+ case DC21041_CFID:
+ case DC21142_CFID:
+
+ Overflows = (Buffer >> DC21X4_OVERFLOW_COUNTER_SHIFT)
+ & DC21X4_OVERFLOW_COUNTER;
+ Adapter->IndicateOverflow = (Overflows!=0);
+ Adapter->MediaOptional[MO_RECEIVE_OVERFLOW]+= Overflows;
+
+ }
+
+ OidIndex = (Oid & OID_INDEX_MASK) - 1;
+
+ switch (Oid & OID_REQUIRED_MASK) {
+
+ case OID_REQUIRED_MANDATORY:
+
+ BufferPtr = (PVOID)&Adapter->GeneralMandatory[OidIndex];
+#if _DBG
+ DbgPrint("GMandatory[%d] = %d\n", OidIndex,
+ Adapter->GeneralMandatory[OidIndex]);
+#endif
+ break;
+
+
+ case OID_REQUIRED_OPTIONAL:
+
+ if (Oid == OID_GEN_RCV_CRC_ERROR) {
+
+ BufferPtr = &Adapter->GeneralOptional[GO_RECEIVE_CRC_ERROR];
+ break;
+ }
+
+ if (Oid == OID_GEN_TRANSMIT_QUEUE_LENGTH) {
+
+ BufferPtr = &Adapter->GeneralOptional[GO_TRANSMIT_QUEUE_LENGTH];
+ break;
+ }
+
+ if (OidIndex & 0x01) {
+
+ // Frame count
+ BufferPtr = &Adapter->GeneralOptionalCount[OidIndex >> 1].FrameCount;
+#if _DBG
+ DbgPrint("FrameCount[%d] = %d\n", OidIndex >> 1,
+ Adapter->GeneralOptionalCount[OidIndex >> 1].FrameCount);
+#endif
+ } else {
+
+ // Byte count
+ BufferPtr = &Adapter->GeneralOptionalCount[OidIndex >> 1].ByteCount;
+ BufferLength = sizeof(DC21X4_LARGE_INTEGER);
+#if _DBG
+ DbgPrint("ByteCount[%d] = %d\n", OidIndex >> 1,
+ Adapter->GeneralOptionalCount[OidIndex >> 1].ByteCount);
+#endif
+ }
+
+ }
+
+ break;
+
+ case OID_TYPE_802_3_OPERATIONAL:
+
+ switch (Oid) {
+
+ case OID_802_3_PERMANENT_ADDRESS:
+
+ if (Adapter->PermanentAddressValid) {
+ BufferPtr = Adapter->PermanentNetworkAddress;
+ BufferLength = 6;
+ }
+ else {
+ BufferLength = 0;
+ }
+ break;
+
+ case OID_802_3_CURRENT_ADDRESS:
+
+ BufferPtr = Adapter->CurrentNetworkAddress;
+ BufferLength = 6;
+ break;
+
+ case OID_802_3_MAXIMUM_LIST_SIZE:
+
+ Buffer = Adapter->MaxMulticastAddresses;
+ }
+ break;
+
+ case OID_TYPE_802_3_STATISTICS:
+
+ OidIndex = (Oid & OID_INDEX_MASK) - 1;
+
+ switch (Oid & OID_REQUIRED_MASK) {
+
+ case OID_REQUIRED_MANDATORY:
+
+ BufferPtr = &Adapter->MediaMandatory[OidIndex];
+ break;
+
+ case OID_REQUIRED_OPTIONAL:
+
+ BufferPtr = &Adapter->MediaOptional[OidIndex];
+ }
+ break;
+
+ }
+
+
+ if (BufferLength > InformationBufferLength) {
+ *BytesNeeded = BufferLength;
+ NdisStatus = NDIS_STATUS_INVALID_LENGTH;
+ }
+ else {
+ MOVE_MEMORY(InformationBuffer,BufferPtr,BufferLength);
+ *BytesWritten = BufferLength;
+ NdisStatus = NDIS_STATUS_SUCCESS;
+ }
+
+ return NdisStatus;
+
+}
+
+
+
+
+
+
+
+
+/*+
+ * DC21X4SetInformation
+ *
+ * Routine Description:
+ *
+ * DC21X4SetInformation handles a set operation for a
+ * single OID.
+ *
+-*/
+extern
+NDIS_STATUS
+DC21X4SetInformation(
+ IN NDIS_HANDLE MiniportAdapterContext,
+ IN NDIS_OID Oid,
+ IN PVOID InformationBuffer,
+ IN ULONG InformationBufferLength,
+ OUT PULONG BytesRead,
+ OUT PULONG BytesNeeded
+ )
+
+{
+ NDIS_STATUS NdisStatus;
+ PDC21X4_ADAPTER Adapter;
+ ULONG Filter;
+
+#if _DBG
+ DbgPrint("DC21X4SetInformation\n");
+ DbgPrint(" Oid = %08x\n",Oid);
+#endif
+
+
+ Adapter = (PDC21X4_ADAPTER)MiniportAdapterContext;
+
+ *BytesNeeded = 0;
+
+ switch (Oid) {
+
+ case OID_802_3_MULTICAST_LIST:
+
+ if (InformationBufferLength % ETH_LENGTH_OF_ADDRESS) {
+ *BytesRead = 0;
+ NdisStatus = NDIS_STATUS_INVALID_LENGTH;
+ }
+ else {
+
+ NdisStatus = DC21X4ChangeMulticastAddresses(
+ Adapter,
+ InformationBuffer,
+ (InformationBufferLength/ETH_LENGTH_OF_ADDRESS)
+ );
+ }
+ break;
+
+ case OID_GEN_CURRENT_PACKET_FILTER:
+
+ if (InformationBufferLength != sizeof(Filter)) {
+ *BytesRead = 0;
+ *BytesNeeded = sizeof(Filter);
+ return NDIS_STATUS_INVALID_LENGTH;
+ }
+
+ MOVE_MEMORY(&Filter,InformationBuffer,sizeof(Filter));
+ *BytesRead = 4;
+
+ if (Filter & ( NDIS_PACKET_TYPE_SOURCE_ROUTING
+ | NDIS_PACKET_TYPE_SMT
+ | NDIS_PACKET_TYPE_MAC_FRAME
+ | NDIS_PACKET_TYPE_FUNCTIONAL
+ | NDIS_PACKET_TYPE_ALL_FUNCTIONAL
+ | NDIS_PACKET_TYPE_GROUP
+ )) {
+
+ NdisStatus = NDIS_STATUS_NOT_SUPPORTED;
+ }
+ else {
+
+ NdisStatus = DC21X4ChangeFilter (
+ Adapter,
+ Filter
+ );
+ }
+ break;
+
+ case OID_GEN_CURRENT_LOOKAHEAD:
+
+ // We indicate success but do not modify the
+ // DC21X4 Lookahead parameter which always
+ // indicate the whole packet.
+ //
+
+ NdisStatus = NDIS_STATUS_SUCCESS;
+ break;
+
+ default:
+
+ NdisStatus = NDIS_STATUS_INVALID_OID;
+ }
+
+ return NdisStatus;
+
+}
+