mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
530 lines
14 KiB
530 lines
14 KiB
/*+
|
|
* 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;
|
|
|
|
}
|
|
|