diff options
Diffstat (limited to '')
-rw-r--r-- | private/ntos/ndis/madge/driver/request.c | 1158 |
1 files changed, 1158 insertions, 0 deletions
diff --git a/private/ntos/ndis/madge/driver/request.c b/private/ntos/ndis/madge/driver/request.c new file mode 100644 index 000000000..21172e71b --- /dev/null +++ b/private/ntos/ndis/madge/driver/request.c @@ -0,0 +1,1158 @@ +/*************************************************************************** +* +* REQUEST.C +* +* FastMAC Plus based NDIS3 miniport driver routines for handling SRB +* requests and ODI_ requsts. +* +* Copyright (c) Madge Networks Ltd 1994 +* +* COMPANY CONFIDENTIAL +* +* Created: PBA 21/06/1994 +* +****************************************************************************/ + +#include <ndis.h> + +#include "ftk_defs.h" +#include "ftk_extr.h" + +#include "mdgmport.upd" +#include "ndismod.h" + + +/*--------------------------------------------------------------------------- +| +| Global OIDs that we will support queries on. +| +---------------------------------------------------------------------------*/ + +NDIS_OID MadgeGlobalSupportedOids[] = +{ + // + // General, Operational, Mandatory. + // + + 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_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_CURRENT_PACKET_FILTER, + OID_GEN_CURRENT_LOOKAHEAD, + OID_GEN_DRIVER_VERSION, + OID_GEN_MAXIMUM_TOTAL_SIZE, + OID_GEN_PROTOCOL_OPTIONS, + OID_GEN_MAC_OPTIONS, + + // + // General, Statistical, Mandatory. + // + + OID_GEN_XMIT_OK, + OID_GEN_RCV_OK, + OID_GEN_XMIT_ERROR, + OID_GEN_RCV_ERROR, + OID_GEN_RCV_NO_BUFFER, + + // + // Token Ring, Operational, Mandatory. + // + + OID_802_5_PERMANENT_ADDRESS, + OID_802_5_CURRENT_ADDRESS, + OID_802_5_CURRENT_FUNCTIONAL, + OID_802_5_CURRENT_GROUP, + OID_802_5_LAST_OPEN_STATUS, + OID_802_5_CURRENT_RING_STATUS, + OID_802_5_CURRENT_RING_STATE, + + // + // Token Ring, Statistical, Mandatory. + // + + OID_802_5_LINE_ERRORS, + OID_802_5_LOST_FRAMES, + + // + // Token Ring Statistical, Optional. + // + + OID_802_5_BURST_ERRORS, + OID_802_5_AC_ERRORS, + OID_802_5_FRAME_COPIED_ERRORS, + OID_802_5_TOKEN_ERRORS + + // + // There are three more Token Ring error stat's but TI MAC code does not + // support them, so we go without! (ABORT_DELIMITERS, FREQUENCY_ERRORS, + // and INTERNAL_ERRORS). + // +}; + + +/************************************************************************** +* +* Function - MadgeCompletePendingRequest +* +* Parameters - ndisAdap -> Pointer NDIS3 level adapter structure. +* +* Purpose - Complete a pending request on the adapter specified. +* +* Returns - Nothing. +* +***************************************************************************/ + +VOID +MadgeCompletePendingRequest(PMADGE_ADAPTER ndisAdap) +{ + BOOLEAN success; + ADAPTER * ftkAdapter; + ULONG * infoBuffer; + +// MadgePrint1("MadgeCompletePendingRequest started\n"); + + success = ndisAdap->SrbRequestStatus; + + switch(ndisAdap->RequestType) + { + case NdisRequestQueryInformation: + + infoBuffer = (ULONG *) ndisAdap->InformationBuffer; + + if (success) + { + ftkAdapter = adapter_record[ndisAdap->FtkAdapterHandle]; + + ndisAdap->ReceiveCongestionCount += + ftkAdapter->status_info->error_log.congestion_errors; + ndisAdap->LineErrors += + ftkAdapter->status_info->error_log.line_errors; + ndisAdap->BurstErrors += + ftkAdapter->status_info->error_log.burst_errors; + ndisAdap->AcErrors += + ftkAdapter->status_info->error_log.ari_fci_errors; + ndisAdap->TokenErrors += + ftkAdapter->status_info->error_log.token_errors; + + switch(ndisAdap->RequestOid) + { + case OID_GEN_RCV_NO_BUFFER: + + *infoBuffer = ndisAdap->ReceiveCongestionCount; + break; + + case OID_802_5_LINE_ERRORS: + + *infoBuffer = ndisAdap->LineErrors; + break; + + case OID_802_5_BURST_ERRORS: + + *infoBuffer = ndisAdap->BurstErrors; + break; + + case OID_802_5_AC_ERRORS: + + *infoBuffer = ndisAdap->AcErrors; + break; + + case OID_802_5_TOKEN_ERRORS: + + *infoBuffer = ndisAdap->TokenErrors; + break; + } + + ndisAdap->JustReadErrorLog = ndisAdap->RequestOid; + } + + // + // And complete the request. + // + + NdisMQueryInformationComplete( + ndisAdap->UsedInISR.MiniportHandle, + (success) ? NDIS_STATUS_SUCCESS : NDIS_STATUS_FAILURE + ); + + break; + + case NdisRequestSetInformation: + + // + // All we need to do is complete the request. + // + + NdisMSetInformationComplete( + ndisAdap->UsedInISR.MiniportHandle, + (success) ? NDIS_STATUS_SUCCESS : NDIS_STATUS_FAILURE + ); + + break; + } + +// MadgePrint1("MadgeCompletePendingRequest finished\n"); +} + + +/*************************************************************************** +* +* Function - MadgeQueryInformation +* +* Parameters - adapterContext -> Pointer NDIS3 level adapter structure. +* oid -> The OID. +* infoBuffer -> Pointer to the information buffer. +* infoLength -> Length of the information buffer. +* bytesWritten -> Pointer to a holder for the number of +* bytes we've written. +* bytesNeeded -> Pointer to a holder for the number of +* bytes we need. +* +* Purpose - Set adapter information. +* +* Returns - An NDIS3 status code. +* +***************************************************************************/ + +NDIS_STATUS +MadgeQueryInformation( + NDIS_HANDLE adapterContext, + NDIS_OID oid, + PVOID infoBuffer, + ULONG infoLength, + PULONG bytesWritten, + PULONG bytesNeeded + ) +{ + PMADGE_ADAPTER ndisAdap; + UINT supportedOids; + UINT i; + ULONG genericULong; + USHORT genericUShort; + UCHAR genericArray[6]; + PVOID sourceBuffer; + ULONG sourceLength; + UCHAR * vendorID; + + + static UCHAR VendorDescription[] = DRIVER_VERSION; + +// MadgePrint2("MadgeQueryInformation Oid = %08x\n", (UINT) oid); + + // + // Do some pre-calculation. + // + + ndisAdap = PMADGE_ADAPTER_FROM_CONTEXT(adapterContext); + sourceBuffer = (PVOID) &genericULong; + sourceLength = (ULONG) sizeof(ULONG); + vendorID = (UCHAR *) &genericULong; + supportedOids = sizeof(MadgeGlobalSupportedOids) / sizeof(NDIS_OID); + + // + // Check that we recognise the OID. + // + +#ifdef OID_MADGE_MONITOR + + if (oid == OID_MADGE_MONITOR) + { + if (sizeof(MADGE_MONITOR) > infoLength) + { + *bytesNeeded = sizeof(MADGE_MONITOR); + return NDIS_STATUS_BUFFER_TOO_SHORT; + } + + MADGE_MOVE_MEMORY( + infoBuffer, + &(ndisAdap->MonitorInfo), + sizeof(MADGE_MONITOR) + ); + + *bytesWritten = sizeof(MADGE_MONITOR); + + // Clear out the Monitor Structure + for (i = 0; i < sizeof(MADGE_MONITOR); i++) + { + ((UCHAR *) &(ndisAdap->MonitorInfo))[i] = (UCHAR) 0; + } + + return NDIS_STATUS_SUCCESS; + } + +#endif + + for (i = 0; i < supportedOids; i++) + { + if (oid == MadgeGlobalSupportedOids[i]) + { + break; + } + } + + if (i == supportedOids) + { + *bytesWritten = 0; + MadgePrint1("OID not supported\n"); + return NDIS_STATUS_INVALID_OID; + } + + // + // Now decode the OID based on the component bytes - this should make + // the switch statement slightly quicker than a simple linear list. + // + // The OIDs are classed by category (General or Media Specific) and type + // (Operational or Statistical), so we'll deal with them thus : + // General Operational + // General Statistical + // Media Specific Operational + // Media Specific Statistical + // + + switch (oid & OID_TYPE_MASK) + { + /*-----------------------------------------------------------------*/ + + case OID_TYPE_GENERAL_OPERATIONAL: + + switch (oid) + { + case OID_GEN_SUPPORTED_LIST: + + sourceBuffer = MadgeGlobalSupportedOids; + sourceLength = sizeof(MadgeGlobalSupportedOids); + break; + + case OID_GEN_HARDWARE_STATUS: + + genericULong = ndisAdap->HardwareStatus; + break; + + case OID_GEN_MEDIA_SUPPORTED: + + genericULong = NdisMedium802_5; + break; + + case OID_GEN_MEDIA_IN_USE: + + genericULong = NdisMedium802_5; + break; + + case OID_GEN_MAXIMUM_LOOKAHEAD: + + // + // The maximum lookahead size is the size of the whole + // frame, less the MAC header. It is NOT the maximum + // frame size according to the ring speed. + // + + genericULong = ndisAdap->MaxFrameSize - FRAME_HEADER_SIZE; + + // + // WARNING: What about Source Routing in the header? + // + +// MadgePrint2("OID_GEN_MAXIMUM_LOOKAHEAD = %ld\n", +// genericULong); + + break; + + case OID_GEN_MAXIMUM_FRAME_SIZE: + case OID_GEN_MAXIMUM_TOTAL_SIZE: + + // + // Note that the MAXIMUM_FRAME_SIZE is the largest frame + // supported, not including any MAC header, while the + // MAXIMUM_TOTAL_SIZE does include the MAC header. + // + + genericULong = ndisAdap->MaxFrameSize; + + if (oid == OID_GEN_MAXIMUM_FRAME_SIZE) + { + genericULong -= FRAME_HEADER_SIZE; + } + +// MadgePrint2("OID_GEN_MAXIMUM_FRAME_SIZE = %ld\n", +// genericULong); + + break; + + case OID_GEN_LINK_SPEED: + + // + // Is this right? Shouldn't it be 16000000 and 4000000? + // + + genericULong = + (driver_ring_speed(ndisAdap->FtkAdapterHandle) == 16) + ? 160000 + : 40000; + break; + + case OID_GEN_TRANSMIT_BUFFER_SPACE: + + genericULong = + ndisAdap->MaxFrameSize * ndisAdap->FastmacTxSlots; + break; + + case OID_GEN_RECEIVE_BUFFER_SPACE: + + genericULong = + ndisAdap->MaxFrameSize * ndisAdap->FastmacRxSlots; + break; + + case OID_GEN_TRANSMIT_BLOCK_SIZE: + + genericULong = ndisAdap->MaxFrameSize; + break; + + case OID_GEN_RECEIVE_BLOCK_SIZE: + + genericULong = ndisAdap->MaxFrameSize; + break; + + case OID_GEN_VENDOR_ID: + + MADGE_MOVE_MEMORY( + vendorID, + &ndisAdap->PermanentNodeAddress, + 3 + ); + vendorID[3] = 0x00; + break; + + case OID_GEN_VENDOR_DESCRIPTION: + + sourceBuffer = VendorDescription; + sourceLength = sizeof(VendorDescription); + break; + + case OID_GEN_CURRENT_PACKET_FILTER: + + genericULong = (ULONG) ndisAdap->CurrentPacketFilter; + break; + + case OID_GEN_CURRENT_LOOKAHEAD: + + genericULong = (ULONG) ndisAdap->CurrentLookahead; + +// MadgePrint2("OID_GEN_CURRENT_LOOKAHEAD = %ld\n", +// genericULong); + + break; + + case OID_GEN_DRIVER_VERSION: + + genericUShort = (MADGE_NDIS_MAJOR_VERSION << 8) + + MADGE_NDIS_MINOR_VERSION; + sourceBuffer = &genericUShort; + sourceLength = sizeof(USHORT); + break; + + case OID_GEN_MAC_OPTIONS: + + genericULong = (ULONG) + (NDIS_MAC_OPTION_TRANSFERS_NOT_PEND | + NDIS_MAC_OPTION_RECEIVE_SERIALIZED); + break; + + default: + + MadgePrint2("OID %x not recognised\n", oid); + return NDIS_STATUS_INVALID_OID; + } + break; + + /*-----------------------------------------------------------------*/ + + case OID_TYPE_GENERAL_STATISTICS: + + // + // Might need these later. + // + + *bytesWritten = sourceLength; + ndisAdap->RequestType = NdisRequestQueryInformation; + ndisAdap->RequestOid = oid; + ndisAdap->InformationBuffer = infoBuffer; + + switch (oid) + { + case OID_GEN_XMIT_OK: + + genericULong = (ULONG) ndisAdap->FramesTransmitted; + break; + + case OID_GEN_RCV_OK: + + genericULong = (ULONG) ndisAdap->FramesReceived; + break; + + case OID_GEN_XMIT_ERROR: + + genericULong = (ULONG) ndisAdap->FrameTransmitErrors; + break; + + case OID_GEN_RCV_ERROR: + + genericULong = (ULONG) ndisAdap->FrameReceiveErrors; + break; + + case OID_GEN_RCV_NO_BUFFER: + + // + // We need to issue a READ_ERROR_LOG SRB to recover an + // up to date value for this counter. + // + + if (ndisAdap->JustReadErrorLog != 0 && + ndisAdap->JustReadErrorLog != oid) + { + genericULong = (ULONG) + ndisAdap->ReceiveCongestionCount; + } + else if (infoLength >= sourceLength) + { + driver_get_status(ndisAdap->FtkAdapterHandle); + return NDIS_STATUS_PENDING; + } + break; + + default: + + MadgePrint2("OID %x not recognised\n", oid); + return NDIS_STATUS_INVALID_OID; + } + break; + + /*-----------------------------------------------------------------*/ + + case OID_TYPE_802_5_OPERATIONAL: + + switch (oid) + { + case OID_802_5_PERMANENT_ADDRESS: + + sourceBuffer = &genericArray; + sourceLength = sizeof(ndisAdap->PermanentNodeAddress); + + MADGE_MOVE_MEMORY( + sourceBuffer, + &ndisAdap->PermanentNodeAddress, + sizeof(ndisAdap->PermanentNodeAddress) + ); + break; + + case OID_802_5_CURRENT_ADDRESS: + + sourceBuffer = &genericArray; + sourceLength = + sizeof(ndisAdap->OpeningNodeAddress); + + MADGE_MOVE_MEMORY( + sourceBuffer, + &ndisAdap->OpeningNodeAddress, + sizeof(ndisAdap->OpeningNodeAddress) + ); + break; + + case OID_802_5_CURRENT_FUNCTIONAL: + + genericULong = + ndisAdap->FunctionalAddress & 0xffffffff; + break; + + case OID_802_5_CURRENT_GROUP: + + genericULong = + ndisAdap->GroupAddress & 0xffffffff; + break; + + case OID_802_5_LAST_OPEN_STATUS: + + genericULong = ndisAdap->LastOpenStatus; + break; + + case OID_802_5_CURRENT_RING_STATUS: + + genericULong = ndisAdap->CurrentRingStatus; + break; + + case OID_802_5_CURRENT_RING_STATE: + + genericULong = NdisRingStateOpened; + break; + + default: + + MadgePrint2("OID %x not recognised\n", oid); + return NDIS_STATUS_INVALID_OID; + } + break; + + /*-----------------------------------------------------------------*/ + + case OID_TYPE_802_5_STATISTICS: + + // + // We do a bit of pre-processing here in case we have to queue + // an SRB request. In this instance we want everything ready bar + // the actual data. + // + + if (sourceLength > infoLength) + { + break; + } + + *bytesWritten = sourceLength; + ndisAdap->RequestType = NdisRequestQueryInformation; + ndisAdap->RequestOid = oid; + ndisAdap->InformationBuffer = infoBuffer; + + // + // Now get on with working out the data. + // + + switch (oid) + { + case OID_802_5_LINE_ERRORS: + + // + // We need to issue a READ_ERROR_LOG SRB to recover an + // up to date value for this counter. + // + + if (ndisAdap->JustReadErrorLog != 0 && + ndisAdap->JustReadErrorLog != oid) + { + genericULong = (ULONG) ndisAdap->LineErrors; + } + else + { + driver_get_status(ndisAdap->FtkAdapterHandle); + return NDIS_STATUS_PENDING; + } + break; + + case OID_802_5_LOST_FRAMES: + + // + // This counter is managed by the transmit process using + // the transmit status returned by FastmacPlus. + // + + genericULong = (ULONG) ndisAdap->LostFrames; + break; + + case OID_802_5_BURST_ERRORS: + + if (ndisAdap->JustReadErrorLog != 0 && + ndisAdap->JustReadErrorLog != oid) + { + genericULong= (ULONG) ndisAdap->BurstErrors; + } + else + { + driver_get_status(ndisAdap->FtkAdapterHandle); + return NDIS_STATUS_PENDING; + } + break; + + case OID_802_5_AC_ERRORS: + + if (ndisAdap->JustReadErrorLog != 0 && + ndisAdap->JustReadErrorLog != oid) + { + genericULong= (ULONG) ndisAdap->AcErrors; + } + else + { + driver_get_status(ndisAdap->FtkAdapterHandle); + return NDIS_STATUS_PENDING; + } + break; + + case OID_802_5_FRAME_COPIED_ERRORS: + + // + // This counter is managed by the receive process using + // the receive status returned by FastmacPlus. + // + + genericULong = (ULONG) ndisAdap->FrameCopiedErrors; + break; + + case OID_802_5_TOKEN_ERRORS: + + if (ndisAdap->JustReadErrorLog != 0 && + ndisAdap->JustReadErrorLog != oid) + { + genericULong = (ULONG) ndisAdap->TokenErrors; + } + else + { + driver_get_status(ndisAdap->FtkAdapterHandle); + return NDIS_STATUS_PENDING; + } + break; + + default: + + MadgePrint2("OID %x not recognised\n", oid); + return NDIS_STATUS_INVALID_OID; + } + break; + } + + // + // Check memory allocation provided by caller - report required amount + // if we haven't got enough. + // + + if (sourceLength > infoLength) + { + *bytesNeeded = sourceLength; + return NDIS_STATUS_BUFFER_TOO_SHORT; + } + + MADGE_MOVE_MEMORY( + infoBuffer, + sourceBuffer, + sourceLength + ); + + *bytesWritten = sourceLength; + + return NDIS_STATUS_SUCCESS; +} + + +/*--------------------------------------------------------------------------- +| +| Function - MadgeChangeGroupAddress +| +| Parameters - ndisAdap -> Pointer to our NDIS level adapter structure. +| newAddress -> The new group address. +| +| Purpose - Queue an SRB to change the group address. +| +| Returns - Nothing. +| +---------------------------------------------------------------------------*/ + +STATIC VOID +MadgeChangeGroupAddress( + PMADGE_ADAPTER ndisAdap, + TR_FUNCTIONAL_ADDRESS newAddress + ) +{ + MULTI_ADDRESS multiAddress; + +// MadgePrint1("MadgeChangeGroupAddress started\n"); + + ndisAdap->GroupAddress = newAddress; + multiAddress.all = (DWORD) newAddress; + + ndisAdap->RequestType = NdisRequestSetInformation; + + // + // And call the FTK to change the address. + // + + driver_set_group_address(ndisAdap->FtkAdapterHandle, &multiAddress); + +// MadgePrint1("MadgeChangeGroupAddress finished\n"); +} + + +/*--------------------------------------------------------------------------- +| +| Function - MadgeChangeFunctionalAddress +| +| Parameters - ndisAdap -> Pointer to our NDIS level adapter structure. +| newAddress -> The new functional address. +| +| Purpose - Queue an SRB to change the functional address. +| +| Returns - Nothing. +| +---------------------------------------------------------------------------*/ + +STATIC VOID +MadgeChangeFunctionalAddress( + PMADGE_ADAPTER ndisAdap, + TR_FUNCTIONAL_ADDRESS newAddress + ) +{ + MULTI_ADDRESS multiAddress; + +// MadgePrint2("MadgeChangeFunctionalAddress started %08x\n", +// (UINT) newAddress); + + ndisAdap->FunctionalAddress = newAddress; + multiAddress.all = (DWORD) newAddress; + + ndisAdap->RequestType = NdisRequestSetInformation; + + // + // And call the FTK to change the address. + // + + driver_set_functional_address(ndisAdap->FtkAdapterHandle, &multiAddress); + +// MadgePrint1("MadgeChangeFunctionalAddress finished\n"); +} + + +/*--------------------------------------------------------------------------- +| +| Function - MadgeChangeFilter +| +| Parameters - ndisAdap -> Pointer to our NDIS level adapter structure. +| newFilter -> The new packet filter. +| +| Purpose - Change the packet filter. +| +| Returns - NDIS_STATUS_PENDING if an SRB is required, +| NDIS_STATUS_NOT_SUPPORTED if we don't support the filter +| types, otherwise NDIS_STATUS_SUCCESS. +| +---------------------------------------------------------------------------*/ + +NDIS_STATUS +MadgeChangeFilter( + PMADGE_ADAPTER ndisAdap, + UINT newFilter + ) +{ + UINT index; + UINT modifyOpenOptions; + UINT oldFilter; + + // + // Lookup table for the various ways we might want to modify the open + // options of the adapter. + // + +#define MOO_NO_CHANGE (0xffff) +#define MOO_MASK ((WORD) (~(OPEN_OPT_COPY_ALL_MACS | OPEN_OPT_COPY_ALL_LLCS))) + +WORD MooLookupTable[] = { + MOO_NO_CHANGE, + OPEN_OPT_COPY_ALL_MACS | OPEN_OPT_COPY_ALL_LLCS, + OPEN_OPT_COPY_ALL_MACS, + OPEN_OPT_COPY_ALL_MACS | OPEN_OPT_COPY_ALL_LLCS, + 0, + MOO_NO_CHANGE, + OPEN_OPT_COPY_ALL_MACS, + MOO_NO_CHANGE, + 0, + OPEN_OPT_COPY_ALL_MACS | OPEN_OPT_COPY_ALL_LLCS, + MOO_NO_CHANGE, + OPEN_OPT_COPY_ALL_MACS | OPEN_OPT_COPY_ALL_LLCS, + 0, + MOO_NO_CHANGE, + OPEN_OPT_COPY_ALL_MACS, + MOO_NO_CHANGE + }; + +// MadgePrint2("MadgeChangeFilter started filter = %04x\n", +// (UINT) newFilter); + + // + // Do some pre-calculation. + // + + modifyOpenOptions = 0; + index = 0; + oldFilter = ndisAdap->CurrentPacketFilter; + +// MadgePrint2("Old filter = %04x\n", oldFilter); + + // + // By default, the card will receive directed frames, broadcast frames, + // and matching functional and group address frames. Thus the following + // filter types are handled automatically, whether we want them or not: + // NDIS_PACKET_TYPE_DIRECTED NDIS_PACKET_TYPE_BROADCAST + // NDIS_PACKET_TYPE_FUNCTIONAL NDIS_PACKET_TYPE_GROUP + // + // Of the remaining filters, the following are not supported (see below) + // NDIS_PACKET_TYPE_MULTICAST NDIS_PACKET_TYPE_ALL_FUNCTIONAL + // NDIS_PACKET_TYPE_ALL_MULTICAST NDIS_PACKET_TYPE_SOURCE_ROUTING + // + // This leaves NDIS_PACKET_TYPE_PROMISCUOUS and NDIS_PACKET_TYPE_MAC, + // which we can handle if we want to. + // + + if ((newFilter & (NDIS_PACKET_TYPE_MULTICAST | + NDIS_PACKET_TYPE_ALL_FUNCTIONAL | + NDIS_PACKET_TYPE_ALL_MULTICAST | + NDIS_PACKET_TYPE_MAC_FRAME | + NDIS_PACKET_TYPE_SOURCE_ROUTING)) != 0) + + { + // + // These filters are not supported - there is no way our MAC/hw can + // be this selective, although the host software could do its own + // filtering i.e. enable promiscuous mode, and then throw away all + // frames except those indicated above. At some stage it might be + // an idea to do this anyway, together with a caveat that it is not + // going to be a high performance solution. + // + // Anyway, in the mean time, return NDIS_STATUS_NOT_SUPPORTED. + // + + return NDIS_STATUS_NOT_SUPPORTED; + } + + // + // Only allow promiscuous mode if it has been enabled. + // + + if ((newFilter & (NDIS_PACKET_TYPE_PROMISCUOUS | + NDIS_PACKET_TYPE_MAC_FRAME)) != 0) + { + if (!ndisAdap->PromiscuousMode) + { + return NDIS_STATUS_NOT_SUPPORTED; + } + } + + // + // We've weeded out the illegal ones now - note that no change has been + // made to the current filter - this is as specified in the paperwork! + // + // Make a note of the _adapter_ notion of the filter. Each + // binding will have its own idea of what it wants, but this is + // the Filter Database's problem, not ours! + // + + ndisAdap->CurrentPacketFilter = newFilter; + + // + // Now we have to work out which bits need setting in the Modify Open + // Options SRB - when I looked at this there didn't appear to be any + // obvious way of simplifying the logic, so I use a look up table to do + // the decoding instead. You'll just have to take my word for it that I + // worked all the permutations out correctly! + // + + if (oldFilter & NDIS_PACKET_TYPE_MAC_FRAME) + { + index |= 8; + } + if (oldFilter & NDIS_PACKET_TYPE_PROMISCUOUS) + { + index |= 4; + } + if (newFilter & NDIS_PACKET_TYPE_MAC_FRAME) + { + index |= 2; + } + if (newFilter & NDIS_PACKET_TYPE_PROMISCUOUS) + { + index |= 1; + } + +// MadgePrint2("index = %d\n", index); + + modifyOpenOptions = + (ndisAdap->OpenOptions & MOO_MASK) | MooLookupTable[index]; + +// MadgePrint2("modifyOpenOptions = %04x\n", modifyOpenOptions); + + // + // Now see if we need to issue an SRB - note that MOO_NO_CHANGE is not + // zero, to distinguish from the case when we actually want to write out + // zero to turn all the options off. + // + + if (modifyOpenOptions != MOO_NO_CHANGE) + { + // + // We have to issue a ModifyOpenOptions SRB. + // + + ndisAdap->RequestType = NdisRequestSetInformation; + ndisAdap->OpenOptions = (WORD) modifyOpenOptions; + + driver_modify_open_options( + ndisAdap->FtkAdapterHandle, + ndisAdap->OpenOptions + ); + +// MadgePrint1("MadgeChangeFilter pended\n"); + + return NDIS_STATUS_PENDING; + } + +// MadgePrint1("MadgeChangeFilter finished\n"); + + return NDIS_STATUS_SUCCESS; +} + + + +/*************************************************************************** +* +* Function - MadgeSetInformation +* +* Parameters - adapterContext -> Pointer NDIS3 level adapter structure. +* oid -> The OID. +* infoBuffer -> Pointer to the information buffer. +* infoLength -> Length of the information buffer. +* bytesRead -> Pointer to a holder for the number of +* bytes we've read. +* bytesNeeded -> Pointer to a holder for the number of +* bytes we need. +* +* Purpose - Set adapter information. +* +* Returns - An NDIS3 status code. +* +***************************************************************************/ + +NDIS_STATUS +MadgeSetInformation( + NDIS_HANDLE adapterContext, + NDIS_OID oid, + PVOID infoBuffer, + ULONG infoLength, + PULONG bytesRead, + PULONG bytesNeeded + ) +{ + PMADGE_ADAPTER ndisAdap; + NDIS_STATUS retCode; + +// MadgePrint2("MadgeSetInformation Oid = %08x\n", (UINT) oid); + + // + // Do some pre-calculation. + // + + ndisAdap = PMADGE_ADAPTER_FROM_CONTEXT(adapterContext); + + // + // Process the request. + // + + switch (oid) + { + case OID_802_5_CURRENT_FUNCTIONAL: + + if (infoLength != TR_LENGTH_OF_FUNCTIONAL) + { + *bytesNeeded = TR_LENGTH_OF_FUNCTIONAL; + retCode = NDIS_STATUS_INVALID_LENGTH; + } + else + { + MadgeChangeFunctionalAddress( + ndisAdap, + *((TR_FUNCTIONAL_ADDRESS *) infoBuffer) + ); + *bytesRead = TR_LENGTH_OF_FUNCTIONAL; + retCode = NDIS_STATUS_PENDING; + } + break; + + case OID_802_5_CURRENT_GROUP: + + if (infoLength != TR_LENGTH_OF_FUNCTIONAL) + { + *bytesNeeded = TR_LENGTH_OF_FUNCTIONAL; + retCode = NDIS_STATUS_INVALID_LENGTH; + } + else + { + MadgeChangeGroupAddress( + ndisAdap, + *((TR_FUNCTIONAL_ADDRESS *) infoBuffer) + ); + *bytesRead = TR_LENGTH_OF_FUNCTIONAL; + retCode = NDIS_STATUS_PENDING; + } + break; + + case OID_GEN_CURRENT_PACKET_FILTER: + + if (infoLength != sizeof(UINT)) + { + *bytesNeeded = sizeof(UINT); + retCode = NDIS_STATUS_INVALID_LENGTH; + } + else + { + retCode = MadgeChangeFilter( + ndisAdap, + *((UINT *) infoBuffer) + ); + *bytesRead = sizeof(UINT); + } + break; + + case OID_GEN_CURRENT_LOOKAHEAD: + + // + // It IS important to record the current lookahead. On WFWG + // machines it is not possible to indicate the whole frame + // as lookahead, so take a note of it here. + // + +// MadgePrint3("Set lookahead infoLength = %d (%d)\n", infoLength, sizeof(ULONG)); + + if (infoLength != sizeof(ULONG)) + { + *bytesNeeded = sizeof(ULONG); + retCode = NDIS_STATUS_INVALID_LENGTH; + } + else + { + ndisAdap->CurrentLookahead = + MIN( + ndisAdap->MaxFrameSize - FRAME_HEADER_SIZE, + MAX( + *((ULONG *) infoBuffer), + MADGE_MINIMUM_LOOKAHEAD + ) + ); + *bytesRead = sizeof(ULONG); + retCode = NDIS_STATUS_SUCCESS; + } + break; + + case OID_GEN_PROTOCOL_OPTIONS: + + // + // This does nothing - we really don't care about the protocol + // options at the moment since we are too stupid to make use of + // them anyway. + // + + *bytesRead = 4; + retCode = NDIS_STATUS_SUCCESS; + break; + + default: + + MadgePrint1("Invalid OID\n"); + retCode = NDIS_STATUS_INVALID_OID; + break; + } + + return retCode; +} + +/******** End of REQUEST.C ************************************************/ |