/*+ * 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 /*+ * * 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; iLinkStatus == 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; }