diff options
Diffstat (limited to '')
-rw-r--r-- | private/ntos/ndis/wd/umi.c | 347 |
1 files changed, 347 insertions, 0 deletions
diff --git a/private/ntos/ndis/wd/umi.c b/private/ntos/ndis/wd/umi.c new file mode 100644 index 000000000..2fcf9ed2c --- /dev/null +++ b/private/ntos/ndis/wd/umi.c @@ -0,0 +1,347 @@ +/*++ + +Copyright (c) 1990 Microsoft Corporation + +Module Name: + + umi.c + +Abstract: + + Upper MAC Interface functions for the NDIS 3.0 Western Digital driver. + +Author: + + Sean Selitrennikoff (seanse) 15-Jan-92 + +Environment: + + Kernel mode, FSD + +Revision History: + + +--*/ + +#include <ndis.h> +#include <efilter.h> +#include "wdlmi.h" +#include "wdhrd.h" +#include "wdsft.h" +#include "wdumi.h" + + + +#if DBG + +extern UCHAR WdDebugLog[]; +extern UCHAR WdDebugLogPlace; + +#define IF_LOG(A) A + +extern +VOID +LOG (UCHAR A); + +#else + +#define IF_LOG(A) + +#endif + + +LM_STATUS +UM_Send_Complete( + LM_STATUS Status, + Ptr_Adapter_Struc Adapt + ) +/*++ + +Routine Description: + + This routine is called back when the packet on the front of + PacketsOnCard has been fully transmitted by the Lower MAC. + + + NOTE: The lock is held before the LM_ routines are called and + therefore held at the beginning of this call. + +Arguments: + + Status - Status of the send. + + Adapt - A pointer to an LMI adapter structure. + +Return: + + SUCCESS + EVENTS_DISABLED + +--*/ +{ + + PWD_ADAPTER Adapter = PWD_ADAPTER_FROM_Ptr_Adapter_Struc(Adapt); + PWD_OPEN Open; + PNDIS_PACKET Packet; + + // + // Remove packet from front of queue. If the complete queue is empty + // then we have nothing to complete. This shouldn't really happen but + // there is a window where it could. + // + + IF_LOG(LOG('c')); + + if ( (Packet = Adapter->PacketsOnCard) != NULL ) { + + Adapter->WakeUpTimeout = FALSE; + + Adapter->PacketsOnCard = RESERVED(Packet)->NextPacket; + + if ( Adapter->PacketsOnCard == NULL ) { + + Adapter->PacketsOnCardTail = NULL; + + } + + Open = RESERVED(Packet)->Open; + + IF_LOUD( DbgPrint("Completing send for open 0x%lx\n",Open);) + + if ( RESERVED(Packet)->Loopback ) { + + // + // Put packet on loopback + // + + if ( Adapter->LoopbackQueue == NULL ) { + + Adapter->LoopbackQueue = Adapter->LoopbackQTail = Packet; + + } else { + + RESERVED(Adapter->LoopbackQTail)->NextPacket = Packet; + + Adapter->LoopbackQTail = Packet; + + } + + RESERVED(Packet)->NextPacket = NULL; + + } else { + + IF_LOUD( DbgPrint("Not a loopback packet\n");) + + // + // Complete send + // + + if ( Status == SUCCESS ) { + + Adapter->FramesXmitGood++; + + } else { + + Adapter->FramesXmitBad++; + } + + NdisReleaseSpinLock(&Adapter->Lock); + + NdisCompleteSend(Open->NdisBindingContext, + Packet, + (Status == SUCCESS ? NDIS_STATUS_SUCCESS + : NDIS_STATUS_FAILURE) + ); + + NdisAcquireSpinLock(&Adapter->Lock); + + WdRemoveReference(Open); + + } + } + + // + // If there are any sends waiting and there is not a reset to be + // done, queue them up + // + + if ( (Adapter->XmitQueue != NULL) && !(Adapter->ResetRequested) ) { + + // + // Remove packet from front. + // + + Packet = Adapter->XmitQueue; + + Adapter->XmitQueue = RESERVED(Packet)->NextPacket; + + if (Adapter->XmitQueue == NULL) { + + Adapter->XmitQTail = NULL; + + } + + // + // Start packet send. + // + + IF_LOG(LOG('t')); + + Status = LM_Send(Packet, Adapt); + + if (Status == OUT_OF_RESOURCES) { + + IF_LOG(LOG('2')); + + // + // Put packet back on xmit queue. + // + + if (Adapter->XmitQueue != NULL) { + + RESERVED(Packet)->NextPacket = Adapter->XmitQueue; + + Adapter->XmitQueue = Packet; + + } else { + + Adapter->XmitQueue = Packet; + + Adapter->XmitQTail = Packet; + + } + + } else if (Status == SUCCESS) { + + // + // Put packet at end of card list. + // + + IF_LOG(LOG('3')); + + if (Adapter->PacketsOnCard == NULL) { + + Adapter->PacketsOnCard = Adapter->PacketsOnCardTail = Packet; + + } else { + + RESERVED(Adapter->PacketsOnCardTail)->NextPacket = Packet; + + Adapter->PacketsOnCardTail = Packet; + + } + + ASSERT(Adapter->PacketsOnCard != NULL); + + RESERVED(Packet)->NextPacket = NULL; + + } + + } + + IF_LOG(LOG('C')); + + return(SUCCESS); +} + + +LM_STATUS +UM_Receive_Packet( + ULONG PacketSize, + Ptr_Adapter_Struc Adapt + ) +/*++ + +Routine Description: + + This routine is called whenever the lower MAC receives a packet. + + +Arguments: + + PacketSize - Total size of the packet + + Adapt - A pointer to an LMI adapter structure. + +Return: + + SUCCESS + EVENTS_DISABLED + +--*/ +{ + PWD_ADAPTER Adapter = PWD_ADAPTER_FROM_Ptr_Adapter_Struc(Adapt); + ULONG IndicateLen; + + Adapter->WakeUpTimeout = FALSE; + + // + // Setup for indication + // + + Adapter->IndicatedAPacket = TRUE; + + Adapter->IndicatingPacket = (PNDIS_PACKET)NULL; + + IndicateLen = ((Adapter->MaxLookAhead + WD_HEADER_SIZE) > PacketSize ? + PacketSize : + Adapter->MaxLookAhead + WD_HEADER_SIZE + ); + + if (LM_Receive_Lookahead( + IndicateLen, + 0, + Adapter->LookAhead, + &(Adapter->LMAdapter)) != SUCCESS) { + + return(SUCCESS); + + } + + // + // Indicate packet + // + + Adapter->FramesRcvGood++; + + NdisReleaseSpinLock(&Adapter->Lock); + + if (PacketSize < WD_HEADER_SIZE) { + + if (PacketSize >= ETH_LENGTH_OF_ADDRESS) { + + // + // Runt packet + // + + EthFilterIndicateReceive( + Adapt->FilterDB, + (NDIS_HANDLE)Adapter, + (PCHAR)Adapter->LookAhead, + Adapter->LookAhead, + PacketSize, + NULL, + 0, + 0 + ); + + } + + } else { + + EthFilterIndicateReceive( + Adapt->FilterDB, + (NDIS_HANDLE)Adapter, + (PCHAR)Adapter->LookAhead, + Adapter->LookAhead, + WD_HEADER_SIZE, + Adapter->LookAhead + WD_HEADER_SIZE, + IndicateLen - WD_HEADER_SIZE, + PacketSize - WD_HEADER_SIZE + ); + } + + NdisAcquireSpinLock(&Adapter->Lock); + + return(SUCCESS); +} |