summaryrefslogtreecommitdiffstats
path: root/private/ntos/ndis/lt200/lttimer.c
diff options
context:
space:
mode:
Diffstat (limited to 'private/ntos/ndis/lt200/lttimer.c')
-rw-r--r--private/ntos/ndis/lt200/lttimer.c280
1 files changed, 280 insertions, 0 deletions
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);
+}