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.
839 lines
17 KiB
839 lines
17 KiB
/*++
|
|
|
|
Copyright (c) 1992 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
request.c
|
|
|
|
Abstract:
|
|
|
|
Ndis 3.0 MAC driver for the 3Com Etherlink III
|
|
|
|
This file handles NdisRequest. The module was for the most part extracted
|
|
from the elnkii driver
|
|
|
|
Author:
|
|
|
|
Brian Lieuallen (BrianLie) 07/02/92
|
|
|
|
Environment:
|
|
|
|
Kernel Mode Operating Systems : NT
|
|
|
|
Revision History:
|
|
|
|
Portions borrowed from ELNK3 driver by
|
|
Earle R. Horton (EarleH)
|
|
|
|
|
|
--*/
|
|
|
|
|
|
|
|
|
|
|
|
#include <ndis.h>
|
|
//#include <efilter.h>
|
|
|
|
#include "debug.h"
|
|
|
|
|
|
#include "elnk3hrd.h"
|
|
#include "elnk3sft.h"
|
|
#include "elnk3.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
NDIS_STATUS
|
|
Elnk3FilterChangeAction(
|
|
IN UINT NewFilterClasses,
|
|
IN NDIS_HANDLE MacBindingHandle
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
// If you add to this, make sure to add the
|
|
// a case in Elnk3FillInGlobalData() and in
|
|
// Elnk3QueryGlobalStatistics() if global
|
|
// information only or
|
|
// Elnk3QueryProtocolStatistics() if it is
|
|
// protocol queriable information.
|
|
//
|
|
STATIC UINT Elnk3GlobalSupportedOids[] = {
|
|
OID_GEN_SUPPORTED_LIST,
|
|
OID_GEN_HARDWARE_STATUS,
|
|
OID_GEN_MEDIA_SUPPORTED,
|
|
OID_GEN_MEDIA_IN_USE,
|
|
OID_GEN_MAXIMUM_LOOKAHEAD,
|
|
OID_GEN_MAXIMUM_FRAME_SIZE,
|
|
OID_GEN_MAXIMUM_TOTAL_SIZE,
|
|
OID_GEN_MAC_OPTIONS,
|
|
OID_GEN_PROTOCOL_OPTIONS,
|
|
OID_GEN_LINK_SPEED,
|
|
OID_GEN_TRANSMIT_BUFFER_SPACE,
|
|
OID_GEN_RECEIVE_BUFFER_SPACE,
|
|
OID_GEN_TRANSMIT_BLOCK_SIZE,
|
|
OID_GEN_RECEIVE_BLOCK_SIZE,
|
|
OID_GEN_VENDOR_ID,
|
|
OID_GEN_VENDOR_DESCRIPTION,
|
|
OID_GEN_DRIVER_VERSION,
|
|
OID_GEN_CURRENT_PACKET_FILTER,
|
|
OID_GEN_CURRENT_LOOKAHEAD,
|
|
OID_GEN_XMIT_OK,
|
|
OID_GEN_RCV_OK,
|
|
OID_GEN_XMIT_ERROR,
|
|
OID_GEN_RCV_ERROR,
|
|
OID_GEN_RCV_NO_BUFFER,
|
|
OID_802_3_PERMANENT_ADDRESS,
|
|
OID_802_3_CURRENT_ADDRESS,
|
|
OID_802_3_MULTICAST_LIST,
|
|
OID_802_3_MAXIMUM_LIST_SIZE,
|
|
OID_802_3_RCV_ERROR_ALIGNMENT,
|
|
OID_802_3_XMIT_ONE_COLLISION,
|
|
OID_802_3_XMIT_MORE_COLLISIONS
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
NDIS_STATUS
|
|
Elnk3QueryInformation(
|
|
IN NDIS_HANDLE MiniportContext,
|
|
IN NDIS_OID Oid,
|
|
IN PVOID InfoBuffer,
|
|
IN ULONG BytesLeft,
|
|
OUT PULONG BytesWritten,
|
|
OUT PULONG BytesNeeded
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
The Elnk3QueryProtocolInformation process a Query request for
|
|
NDIS_OIDs that are specific to a binding about the MAC. Note that
|
|
some of the OIDs that are specific to bindings are also queryable
|
|
on a global basis. Rather than recreate this code to handle the
|
|
global queries, I use a flag to indicate if this is a query for the
|
|
global data or the binding specific data.
|
|
|
|
Arguments:
|
|
|
|
Adapter - a pointer to the adapter.
|
|
|
|
Oid - the NDIS_OID to process.
|
|
|
|
PlaceInInfoBuffer - a pointer into the NdisRequest->InformationBuffer
|
|
into which store the result of the query.
|
|
|
|
BytesLeft - the number of bytes left in the InformationBuffer.
|
|
|
|
BytesNeeded - If there is not enough room in the information buffer
|
|
then this will contain the number of bytes needed to complete the
|
|
request.
|
|
|
|
BytesWritten - a pointer to the number of bytes written into the
|
|
InformationBuffer.
|
|
|
|
Return Value:
|
|
|
|
The function value is the status of the operation.
|
|
|
|
--*/
|
|
|
|
{
|
|
NDIS_MEDIUM Medium = NdisMedium802_3;
|
|
ULONG GenericULong = 0;
|
|
USHORT GenericUShort = 0;
|
|
UCHAR GenericArray[6];
|
|
|
|
PELNK3_ADAPTER pAdapter=MiniportContext;
|
|
|
|
NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS;
|
|
|
|
//
|
|
// Common variables for pointing to result of query
|
|
//
|
|
|
|
PVOID MoveSource;
|
|
ULONG MoveBytes;
|
|
|
|
NDIS_HARDWARE_STATUS HardwareStatus = NdisHardwareStatusReady;
|
|
|
|
//
|
|
// General Algorithm:
|
|
//
|
|
// Switch(Request)
|
|
// Get requested information
|
|
// Store results in a common variable.
|
|
// Copy result in common variable to result buffer.
|
|
//
|
|
|
|
//
|
|
// Make sure that ulong is 4 bytes. Else GenericULong must change
|
|
// to something of size 4.
|
|
//
|
|
ASSERT(sizeof(ULONG) == 4);
|
|
|
|
MoveSource = (PVOID)(&GenericULong);
|
|
MoveBytes = sizeof(GenericULong);
|
|
|
|
|
|
|
|
IF_REQ_LOUD(DbgPrint("ELNK3: QueryProtocol %08lx\n",Oid);)
|
|
|
|
|
|
//
|
|
// Switch on request type
|
|
//
|
|
|
|
switch (Oid) {
|
|
|
|
case OID_GEN_MAC_OPTIONS:
|
|
|
|
if (pAdapter->ReceiveMethod==1) {
|
|
|
|
GenericULong = NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA |
|
|
NDIS_MAC_OPTION_NO_LOOPBACK ;
|
|
|
|
} else {
|
|
|
|
GenericULong = ( NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA |
|
|
NDIS_MAC_OPTION_TRANSFERS_NOT_PEND |
|
|
NDIS_MAC_OPTION_NO_LOOPBACK);
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
case OID_GEN_SUPPORTED_LIST:
|
|
|
|
|
|
MoveSource = (PVOID)(Elnk3GlobalSupportedOids);
|
|
MoveBytes = sizeof(Elnk3GlobalSupportedOids);
|
|
|
|
break;
|
|
|
|
case OID_GEN_HARDWARE_STATUS:
|
|
|
|
HardwareStatus = NdisHardwareStatusReady;
|
|
|
|
|
|
MoveSource = (PVOID)(&HardwareStatus);
|
|
MoveBytes = sizeof(NDIS_HARDWARE_STATUS);
|
|
|
|
break;
|
|
|
|
case OID_GEN_MEDIA_SUPPORTED:
|
|
case OID_GEN_MEDIA_IN_USE:
|
|
|
|
MoveSource = (PVOID) (&Medium);
|
|
MoveBytes = sizeof(NDIS_MEDIUM);
|
|
break;
|
|
|
|
case OID_GEN_MAXIMUM_LOOKAHEAD:
|
|
|
|
GenericULong = ELNK3_MAX_LOOKAHEAD_SIZE;
|
|
|
|
break;
|
|
|
|
|
|
case OID_GEN_MAXIMUM_FRAME_SIZE:
|
|
|
|
GenericULong = (ULONG)(1514 - 14);
|
|
|
|
break;
|
|
|
|
|
|
case OID_GEN_MAXIMUM_TOTAL_SIZE:
|
|
|
|
GenericULong = (ULONG)(1514);
|
|
break;
|
|
|
|
|
|
case OID_GEN_LINK_SPEED:
|
|
|
|
GenericULong = (ULONG)(100000);
|
|
break;
|
|
|
|
|
|
case OID_GEN_TRANSMIT_BUFFER_SPACE:
|
|
|
|
GenericULong = 2048;
|
|
break;
|
|
|
|
case OID_GEN_RECEIVE_BUFFER_SPACE:
|
|
|
|
GenericULong = 2048;
|
|
break;
|
|
|
|
case OID_GEN_TRANSMIT_BLOCK_SIZE:
|
|
|
|
GenericULong = 1514;
|
|
|
|
break;
|
|
|
|
case OID_GEN_RECEIVE_BLOCK_SIZE:
|
|
|
|
GenericULong = 1514;
|
|
break;
|
|
|
|
case OID_GEN_VENDOR_ID:
|
|
|
|
NdisMoveMemory(
|
|
(PVOID)&GenericULong,
|
|
pAdapter->PermanentAddress,
|
|
3
|
|
);
|
|
GenericULong &= 0xFFFFFF00;
|
|
break;
|
|
|
|
case OID_GEN_VENDOR_DESCRIPTION:
|
|
|
|
MoveSource = (PVOID)"ELNK3 Ethernet Adapter.";
|
|
MoveBytes = 24;
|
|
|
|
break;
|
|
|
|
case OID_GEN_DRIVER_VERSION:
|
|
|
|
GenericUShort = ((USHORT)ELNK3_NDIS_MAJOR_VERSION << 8) |
|
|
ELNK3_NDIS_MINOR_VERSION;
|
|
|
|
MoveSource = (PVOID)(&GenericUShort);
|
|
MoveBytes = sizeof(GenericUShort);
|
|
break;
|
|
|
|
|
|
|
|
case OID_GEN_CURRENT_LOOKAHEAD:
|
|
|
|
|
|
GenericULong = (ULONG)(pAdapter->MaxLookAhead);
|
|
|
|
|
|
|
|
IF_REQ_LOUD(DbgPrint("Querying LookAhead: %d\n,GenericULong");)
|
|
|
|
break;
|
|
|
|
case OID_802_3_PERMANENT_ADDRESS:
|
|
|
|
IF_REQ_LOUD(DbgPrint("Querying Permanent address\n");)
|
|
|
|
NdisMoveMemory((PCHAR)GenericArray,
|
|
pAdapter->PermanentAddress,
|
|
ELNK3_LENGTH_OF_ADDRESS);
|
|
|
|
MoveSource = (PVOID)(GenericArray);
|
|
MoveBytes = sizeof(pAdapter->PermanentAddress);
|
|
break;
|
|
|
|
|
|
case OID_802_3_CURRENT_ADDRESS:
|
|
|
|
IF_REQ_LOUD(DbgPrint("Querying Current address\n");)
|
|
|
|
NdisMoveMemory(
|
|
(PCHAR)GenericArray,
|
|
pAdapter->StationAddress,
|
|
ELNK3_LENGTH_OF_ADDRESS
|
|
);
|
|
|
|
MoveSource = (PVOID)(GenericArray);
|
|
MoveBytes = sizeof(pAdapter->StationAddress);
|
|
break;
|
|
|
|
|
|
case OID_802_3_MAXIMUM_LIST_SIZE:
|
|
|
|
GenericULong = (ULONG) DEFAULT_MULTICAST_SIZE;
|
|
|
|
break;
|
|
|
|
case OID_GEN_XMIT_OK:
|
|
|
|
GenericULong = pAdapter->FramesXmitGood;
|
|
|
|
break;
|
|
|
|
case OID_GEN_RCV_OK:
|
|
|
|
GenericULong = pAdapter->FramesRcvGood;
|
|
|
|
break;
|
|
|
|
case OID_GEN_XMIT_ERROR:
|
|
|
|
GenericULong = pAdapter->FramesXmitBad;
|
|
|
|
break;
|
|
|
|
case OID_GEN_RCV_ERROR:
|
|
|
|
GenericULong = pAdapter->CrcErrors;
|
|
|
|
break;
|
|
|
|
case OID_GEN_RCV_NO_BUFFER:
|
|
|
|
GenericULong = (UINT)(pAdapter->MissedPackets);
|
|
|
|
break;
|
|
|
|
case OID_802_3_RCV_ERROR_ALIGNMENT:
|
|
|
|
GenericULong = (UINT)pAdapter->FrameAlignmentErrors;
|
|
|
|
break;
|
|
|
|
case OID_802_3_XMIT_ONE_COLLISION:
|
|
|
|
GenericULong = (UINT)pAdapter->FramesXmitOneCollision;
|
|
|
|
break;
|
|
|
|
case OID_802_3_XMIT_MORE_COLLISIONS:
|
|
|
|
GenericULong = (UINT)pAdapter->FramesXmitManyCollisions;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
StatusToReturn = NDIS_STATUS_NOT_SUPPORTED;
|
|
break;
|
|
}
|
|
|
|
if ((StatusToReturn == NDIS_STATUS_SUCCESS) &&
|
|
(Oid != OID_802_3_MULTICAST_LIST)) {
|
|
|
|
if (MoveBytes > BytesLeft) {
|
|
|
|
//
|
|
// Not enough room in InformationBuffer. Punt
|
|
//
|
|
|
|
*BytesNeeded = MoveBytes;
|
|
|
|
StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
|
|
|
|
} else {
|
|
|
|
//
|
|
// Store result.
|
|
//
|
|
|
|
NdisMoveMemory(InfoBuffer, MoveSource, MoveBytes);
|
|
|
|
(*BytesWritten) = MoveBytes;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
#if DBG
|
|
|
|
if (StatusToReturn != NDIS_STATUS_SUCCESS) {
|
|
|
|
IF_REQ_LOUD(DbgPrint("Out QueryInfo oid=%08lx failed\n",Oid);)
|
|
}
|
|
#endif
|
|
|
|
|
|
IF_VERY_LOUD( DbgPrint("Out QueryProtocol\n");)
|
|
|
|
return StatusToReturn;
|
|
|
|
}
|
|
|
|
|
|
NDIS_STATUS
|
|
Elnk3SetInformation(
|
|
IN NDIS_HANDLE MiniportContext,
|
|
IN NDIS_OID Oid,
|
|
IN PVOID InfoBuffer,
|
|
IN ULONG BytesLeft,
|
|
OUT PULONG BytesRead,
|
|
OUT PULONG BytesNeeded
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
The Elnk3SetInformation is used by Elnk3Request to set information
|
|
about the MAC.
|
|
|
|
Arguments:
|
|
|
|
Adapter - A pointer to the adapter.
|
|
|
|
Open - A pointer to an open instance.
|
|
|
|
NdisRequest - A structure which contains the request type (Set),
|
|
an array of operations to perform, and an array for holding
|
|
the results of the operations.
|
|
|
|
Return Value:
|
|
|
|
The function value is the status of the operation.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
//
|
|
// General Algorithm:
|
|
//
|
|
// Verify length
|
|
// Switch(Request)
|
|
// Process Request
|
|
//
|
|
|
|
//
|
|
// Variables for a particular request
|
|
//
|
|
|
|
PELNK3_ADAPTER pAdapter=MiniportContext;
|
|
|
|
UINT OidLength;
|
|
|
|
//
|
|
// Variables for holding the new values to be used.
|
|
//
|
|
|
|
ULONG LookAhead;
|
|
ULONG Filter;
|
|
|
|
NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS;
|
|
|
|
|
|
IF_REQ_LOUD( DbgPrint("ELNK3: SetInfo %08lx %0d\n",(UINT)Oid,BytesLeft);)
|
|
|
|
//
|
|
// Get Oid and Length of request
|
|
//
|
|
|
|
|
|
OidLength = BytesLeft;
|
|
|
|
switch (Oid) {
|
|
|
|
|
|
case OID_802_3_MULTICAST_LIST:
|
|
|
|
//
|
|
// Verify length
|
|
//
|
|
|
|
if ((OidLength % ELNK3_LENGTH_OF_ADDRESS) != 0){
|
|
|
|
StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
|
|
|
|
*BytesRead = 0;
|
|
*BytesNeeded = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
#if DBG
|
|
{
|
|
UINT j;
|
|
PUCHAR Address;
|
|
|
|
Address=InfoBuffer;
|
|
|
|
for (j=0; j<(OidLength / ELNK3_LENGTH_OF_ADDRESS); j++) {
|
|
|
|
IF_REQ_LOUD(DbgPrint(" %02x-%02x-%02x-%02x-%02x-%02x\n",
|
|
Address[j*6],
|
|
Address[j*6+1],
|
|
Address[j*6+2],
|
|
Address[j*6+3],
|
|
Address[j*6+4],
|
|
Address[j*6+5]);)
|
|
}
|
|
}
|
|
#endif
|
|
|
|
break;
|
|
|
|
|
|
case OID_GEN_CURRENT_PACKET_FILTER:
|
|
|
|
//
|
|
// Verify length
|
|
//
|
|
|
|
if (OidLength != 4 ) {
|
|
|
|
StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
|
|
|
|
*BytesRead = 0;
|
|
*BytesNeeded = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
NdisMoveMemory(&Filter, InfoBuffer, 4);
|
|
|
|
|
|
StatusToReturn=Elnk3FilterChangeAction(
|
|
Filter,
|
|
pAdapter
|
|
);
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
case OID_GEN_CURRENT_LOOKAHEAD:
|
|
|
|
//
|
|
// Verify length
|
|
//
|
|
if (OidLength != 4) {
|
|
|
|
StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
|
|
|
|
*BytesRead = 0;
|
|
*BytesNeeded = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
NdisMoveMemory(
|
|
&LookAhead,
|
|
InfoBuffer,
|
|
4
|
|
);
|
|
|
|
IF_REQ_LOUD(DbgPrint("Setting LookAhead: %d\n",LookAhead);)
|
|
|
|
|
|
if (LookAhead <= ELNK3_MAX_LOOKAHEAD_SIZE) {
|
|
|
|
pAdapter->MaxLookAhead=LookAhead;
|
|
Elnk3AdjustMaxLookAhead(pAdapter);
|
|
|
|
|
|
} else {
|
|
|
|
StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
case OID_GEN_PROTOCOL_OPTIONS:
|
|
|
|
StatusToReturn = NDIS_STATUS_SUCCESS;
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
StatusToReturn = NDIS_STATUS_INVALID_OID;
|
|
|
|
*BytesRead = 0;
|
|
*BytesNeeded = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
if (StatusToReturn == NDIS_STATUS_SUCCESS) {
|
|
|
|
*BytesRead = BytesLeft;
|
|
*BytesNeeded = 0;
|
|
|
|
}
|
|
|
|
|
|
#if DBG
|
|
|
|
if (StatusToReturn != NDIS_STATUS_SUCCESS) {
|
|
|
|
IF_REQ_LOUD(DbgPrint("Out SetInfo oid=%08lx failed\n",Oid);)
|
|
}
|
|
#endif
|
|
|
|
return StatusToReturn;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VOID
|
|
Elnk3AdjustMaxLookAhead(
|
|
IN PELNK3_ADAPTER Adapter
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine finds the open with the maximum lookahead value and
|
|
stores that in the adapter block.
|
|
|
|
Arguments:
|
|
|
|
Adapter - A pointer to the adapter block.
|
|
|
|
Returns:
|
|
|
|
None.
|
|
|
|
--*/
|
|
{
|
|
ULONG CurrentMax;
|
|
|
|
if (Adapter->MaxLookAhead < 60 ) {
|
|
|
|
Adapter->MaxLookAhead =60;
|
|
|
|
}
|
|
|
|
|
|
CurrentMax=Adapter->MaxLookAhead;
|
|
|
|
if (Adapter->ReceiveMethod==1) {
|
|
|
|
Adapter->EarlyReceiveThreshold=ELNK3_ROUND_TO_DWORD((CurrentMax+
|
|
ELNK3_ETHERNET_HEADER_SIZE)
|
|
& 0x7ff);
|
|
} else {
|
|
|
|
Adapter->EarlyReceiveThreshold=Adapter->ThresholdTarget & 0x7fc;
|
|
}
|
|
|
|
|
|
IF_REQ_LOUD(DbgPrint("ELNK3: Setting LookAhead: %d Threshold: %d\n", CurrentMax, Adapter->EarlyReceiveThreshold);)
|
|
|
|
|
|
}
|
|
|
|
|
|
NDIS_STATUS
|
|
Elnk3FilterChangeAction(
|
|
IN UINT NewFilterClasses,
|
|
IN NDIS_HANDLE MacBindingHandle
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Action routine that will get called when an address is added to
|
|
the filter that wasn't referenced by any other open binding.
|
|
|
|
Arguments:
|
|
|
|
NewFilterClasses - A bit mask that should be put on the card telling
|
|
which packet types to accept.
|
|
|
|
MacBindingHandle - The context value returned by the MAC when the
|
|
adapter was opened.
|
|
|
|
Return Value:
|
|
|
|
Status of the change (successful or pending).
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
PELNK3_ADAPTER pAdapter = MacBindingHandle;
|
|
|
|
UCHAR NewFilter=0;
|
|
|
|
IF_REQ_LOUD(DbgPrint("ELNK3: FilterChangeAction called %08lx\n",NewFilterClasses);)
|
|
|
|
if (NewFilterClasses & ~(NDIS_PACKET_TYPE_DIRECTED |
|
|
NDIS_PACKET_TYPE_MULTICAST |
|
|
NDIS_PACKET_TYPE_ALL_MULTICAST |
|
|
NDIS_PACKET_TYPE_BROADCAST |
|
|
NDIS_PACKET_TYPE_PROMISCUOUS )) {
|
|
|
|
IF_REQ_LOUD(DbgPrint("ELNK3: protocol set bogus filter\n");)
|
|
return NDIS_STATUS_NOT_SUPPORTED;
|
|
}
|
|
|
|
|
|
if (NewFilterClasses & NDIS_PACKET_TYPE_DIRECTED) {
|
|
IF_REQ_LOUD(DbgPrint("ELNK3: FilterChangeAction: directed\n");)
|
|
NewFilter|=EC_FILTER_ADDRESS;
|
|
}
|
|
|
|
if (NewFilterClasses & NDIS_PACKET_TYPE_MULTICAST ) {
|
|
IF_REQ_LOUD(DbgPrint("ELNK3: FilterChangeAction: multicast\n");)
|
|
NewFilter|=EC_FILTER_GROUP;
|
|
}
|
|
|
|
if (NewFilterClasses & NDIS_PACKET_TYPE_ALL_MULTICAST) {
|
|
IF_REQ_LOUD(DbgPrint("ELNK3: FilterChangeAction: all multicast\n");)
|
|
NewFilter|=EC_FILTER_GROUP;
|
|
}
|
|
|
|
if (NewFilterClasses & NDIS_PACKET_TYPE_BROADCAST) {
|
|
IF_REQ_LOUD(DbgPrint("ELNK3: FilterChangeAction: broadcast\n");)
|
|
NewFilter|=EC_FILTER_BROADCAST;
|
|
}
|
|
|
|
if (NewFilterClasses & NDIS_PACKET_TYPE_PROMISCUOUS) {
|
|
IF_REQ_LOUD(DbgPrint("ELNK3: FilterChangeAction: promiscuous\n");)
|
|
NewFilter|=EC_FILTER_PROMISCUOUS;
|
|
}
|
|
|
|
|
|
pAdapter->RejectBroadcast=FALSE;
|
|
|
|
if (NewFilterClasses & NDIS_PACKET_TYPE_MULTICAST) {
|
|
//
|
|
// The multicast bit is set so the card receives every thing
|
|
// that is not directed
|
|
//
|
|
if ((NewFilterClasses & (NDIS_PACKET_TYPE_BROADCAST |
|
|
NDIS_PACKET_TYPE_PROMISCUOUS))==0) {
|
|
//
|
|
// We want multicast but not broadcast and we aren't
|
|
// in promiscuous mode
|
|
//
|
|
pAdapter->RejectBroadcast=TRUE;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
pAdapter->NdisRxFilter=NewFilterClasses;
|
|
|
|
pAdapter->RxFilter=NewFilter;
|
|
|
|
ELNK3_COMMAND(pAdapter, EC_SET_RX_FILTER, NewFilter);
|
|
|
|
return NDIS_STATUS_SUCCESS;
|
|
|
|
|
|
}
|