diff options
Diffstat (limited to 'private/ntos/ndis/dc21x4/request.c')
-rw-r--r-- | private/ntos/ndis/dc21x4/request.c | 530 |
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; + +} + |