From e611b132f9b8abe35b362e5870b74bce94a1e58e Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 16 May 2020 20:51:50 -0700 Subject: initial commit --- private/ntos/ndis/lt200/lttimer.c | 280 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 280 insertions(+) create mode 100644 private/ntos/ndis/lt200/lttimer.c (limited to 'private/ntos/ndis/lt200/lttimer.c') diff --git a/private/ntos/ndis/lt200/lttimer.c b/private/ntos/ndis/lt200/lttimer.c new file mode 100644 index 000000000..99186d552 --- /dev/null +++ b/private/ntos/ndis/lt200/lttimer.c @@ -0,0 +1,280 @@ +/*++ + +Copyright (c) 1992 Microsoft Corporation + +Module Name: + + lttimer.c + +Abstract: + + This module contains the polling timer processing routines. + +Author: + + Stephen Hou (stephh@microsoft.com) + Nikhil Kamkolkar (nikhilk@microsoft.com) + +Revision History: + 19 Jun 1992 Initial Version (dch@pacvax.pacersoft.com) + +Notes: Tab stop: 4 +--*/ + +#define LTTIMER_H_LOCALS +#include "ltmain.h" +#include "lttimer.h" +#include "ltreset.h" + + +// Define file id for errorlogging +#define FILENUM LTTIMER + + +VOID +LtTimerPoll( + IN PVOID SystemSpecific1, + IN PVOID Context, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3 + ) +/*++ + +Routine Description: + + This is the polling timer routine. It will receive data from the card + and process all the queues that are there- send/receive/loopback. NOTE: + Priority must be given to sends. + +Arguments: + + Context : Pointer to the Adapter structure. + All other parameters as described in NDIS 3.0 + +Return Value: + + None. + +--*/ +{ + USHORT ResponseLength; + UCHAR Data, ResponseType; + LT_INIT_RESPONSE InitPacket; + PRECV_DESC RecvDesc; + PUCHAR RecvPkt; + NDIS_STATUS Status; + + BOOLEAN ProcessReset = FALSE; + + BOOLEAN ClearCardData = FALSE; + PLT_ADAPTER Adapter = (PLT_ADAPTER)Context; + + DBGPRINT(DBG_COMP_TIMER, DBG_LEVEL_LOW, + ("LtTimerPoll: Entering...\n")); + + LtReferenceAdapter(Adapter, &Status); + if (Status != NDIS_STATUS_SUCCESS) + { + // We are probably shutting down. + ASSERTMSG("LtTimerPoll: Adapter not closing!\n", + ((Adapter->Flags & ADAPTER_CLOSING) == 0)); + + // Remove the reference we added at timer set. + LtDeReferenceAdapter(Adapter); + return; + } + + // BUGBUG: Verify reset handling. + + // !!! Send's get very high priority. In total, the queue is processed + // !!! three times, twice in the timer and once in LtSend + LtSendProcessQueue(Adapter); + + // Check for receive data + NdisRawReadPortUchar(SC_PORT, &Data); + + if (Data & RX_READY) + { + // Get the length of the response on the card + NdisRawReadPortUchar(XFER_PORT, &Data); + + ResponseLength = (USHORT)(Data & 0xFF); + + NdisRawReadPortUchar(XFER_PORT, &Data); + + ResponseLength |= (Data << 8); + + // Now get the IO code. + NdisRawReadPortUchar(XFER_PORT, &ResponseType); + + DBGPRINT(DBG_COMP_TIMER, DBG_LEVEL_INFO, + ("LtPoll: RespType = %x, RespLength = %d\n", + ResponseType, ResponseLength)); + + switch (ResponseType) + { + case LT_RSP_LAP_INIT: + + if (ResponseLength != sizeof(LT_INIT_RESPONSE)) + { + DBGPRINT(DBG_COMP_TIMER, DBG_LEVEL_ERR, + ("LtTimerPoll: Bad response length %lx! \n", ResponseLength)); + + ClearCardData = TRUE; + } + break; + + case LT_RSP_LAP_FRAME: + + // Verify the frame is of the maximum packet size possible. + if (ResponseLength > LT_MAX_PACKET_SIZE) + { + DBGPRINT(DBG_COMP_TIMER, DBG_LEVEL_ERR, + ("LtTimerPoll: Bad packet length %lx! \n", ResponseLength)); + + // Keep track of number of bad receives + NdisDprAcquireSpinLock(&Adapter->Lock); + ++Adapter->GeneralMandatory[GM_RECEIVE_BAD]; + NdisDprReleaseSpinLock(&Adapter->Lock); + + ClearCardData = TRUE; + break; + } + + // Allocate a receive buffer descriptor for the packet. + NdisAllocateMemory( + &RecvDesc, + (UINT)(sizeof(RECV_DESC)+ResponseLength), + 0, + LtNdisPhyAddr); + + if (RecvDesc == NULL) + { + // Keep track of the number of times we couldnt get a buffer. + NdisDprAcquireSpinLock(&Adapter->Lock); + ++Adapter->GeneralMandatory[GM_RECEIVE_NO_BUFFER]; + NdisDprReleaseSpinLock(&Adapter->Lock); + + ClearCardData = TRUE; + break; + } + + + // Get a pointer to the receive packet storage. + RecvPkt = (PUCHAR)((PUCHAR)RecvDesc + sizeof(RECV_DESC)); + + NdisRawReadPortBufferUchar(XFER_PORT, + RecvPkt, + ResponseLength); + + RecvDesc->Broadcast = IS_PACKET_BROADCAST(RecvPkt); + RecvDesc->BufferLength = ResponseLength; + + DBGPRINT(DBG_COMP_TIMER, DBG_LEVEL_INFO, + ("LtTimerPoll: Recd Pkt Desc %lx Pkt %lx! \n", + RecvDesc, RecvPkt)); + + NdisDprAcquireSpinLock(&Adapter->Lock); + ++Adapter->GeneralMandatory[GM_RECEIVE_GOOD]; + if (RecvDesc->Broadcast) + { + ++Adapter->GeneralOptionalFrameCount[GO_BROADCAST_RECEIVES]; + LtAddLongToLargeInteger( + Adapter->GeneralOptionalByteCount[GO_BROADCAST_RECEIVES], + RecvDesc->BufferLength); + + Adapter->MediaMandatory[MM_IN_BROADCASTS]++; + + } + else + { + ++Adapter->GeneralOptionalFrameCount[GO_DIRECTED_RECEIVES]; + LtAddLongToLargeInteger( + Adapter->GeneralOptionalByteCount[GO_DIRECTED_RECEIVES], + RecvDesc->BufferLength); + } + + InsertTailList( + &Adapter->Receive, + &RecvDesc->Linkage); + + NdisDprReleaseSpinLock(&Adapter->Lock); + break; + + case LT_RSP_STATUS: + + if (ResponseLength != sizeof(LT_STATUS_RESPONSE)) + { + ClearCardData = TRUE; + break; + } + + NdisRawReadPortBufferUchar(XFER_PORT, + (PUCHAR)&Adapter->LastCardStatusResponse, + ResponseLength); + + DBGPRINT(DBG_COMP_TIMER, DBG_LEVEL_INFO, + ("Node ID = %lx, Rom Ver = %lx, FirmWare Ver %lx\n", + Adapter->LastCardStatusResponse.NodeId, + Adapter->LastCardStatusResponse.RomVer, + Adapter->LastCardStatusResponse.SwVer)); + + break; + + default: + DBGPRINT(DBG_COMP_TIMER, DBG_LEVEL_ERR, + ("LtTimerPoll: Unknown response type %lx\n", ResponseType)); + + ClearCardData = TRUE; + break; + } + } + + if (ClearCardData) + { + DBGPRINT(DBG_COMP_TIMER, DBG_LEVEL_WARN, + ("LtTimerPoll: Clearing Card of response %d\n", ResponseLength)); + + while (ResponseLength-- > 0 ) + { + NdisRawReadPortUchar(XFER_PORT, &Data); + } + } + + // Call all the processing routines if their respective queues are + // not empty! + NdisDprAcquireSpinLock(&Adapter->Lock); + + ASSERT (Adapter->Flags & ADAPTER_NODE_ID_VALID); + + if (Adapter->Flags & ADAPTER_RESET_IN_PROGRESS) + { + ProcessReset = TRUE; + } + NdisDprReleaseSpinLock(&Adapter->Lock); + + if (ProcessReset) + { + LtResetComplete(Adapter); + } + + // Process our receive queue. + LtRecvProcessQueue(Adapter); + + // Process send queue as processing receives would have entailed + // some sends. + // NOTE: Process LoopQueue after SendQueue as the Send Packet + // goes into the loop queue if it is a broadcast, after + // being sent out on the net. + LtSendProcessQueue(Adapter); + LtLoopProcessQueue(Adapter); + + DBGPRINT(DBG_COMP_TIMER, DBG_LEVEL_LOW, + ("LtTimerPoll: Setting timer and Leaving...\n")); + + // Re-arm the timer + NdisSetTimer(&Adapter->PollingTimer, LT_POLLING_TIME); + + // Remove the reference we added at the beginning of this routine. + LtDeReferenceAdapter(Adapter); +} -- cgit v1.2.3