summaryrefslogtreecommitdiffstats
path: root/private/ntos/ndis/ibmtok2i
diff options
context:
space:
mode:
Diffstat (limited to 'private/ntos/ndis/ibmtok2i')
-rw-r--r--private/ntos/ndis/ibmtok2i/command.c715
-rw-r--r--private/ntos/ndis/ibmtok2i/interrup.c1376
-rw-r--r--private/ntos/ndis/ibmtok2i/log.txt77
-rw-r--r--private/ntos/ndis/ibmtok2i/makefile6
-rw-r--r--private/ntos/ndis/ibmtok2i/request.c1346
-rw-r--r--private/ntos/ndis/ibmtok2i/reset.c1918
-rw-r--r--private/ntos/ndis/ibmtok2i/send.c706
-rw-r--r--private/ntos/ndis/ibmtok2i/sources48
-rw-r--r--private/ntos/ndis/ibmtok2i/tok162.c2504
-rw-r--r--private/ntos/ndis/ibmtok2i/tok162.rc38
-rw-r--r--private/ntos/ndis/ibmtok2i/tok162hw.h1382
-rw-r--r--private/ntos/ndis/ibmtok2i/tok162pr.h315
-rw-r--r--private/ntos/ndis/ibmtok2i/tok162sw.h699
13 files changed, 11130 insertions, 0 deletions
diff --git a/private/ntos/ndis/ibmtok2i/command.c b/private/ntos/ndis/ibmtok2i/command.c
new file mode 100644
index 000000000..7b139ed3d
--- /dev/null
+++ b/private/ntos/ndis/ibmtok2i/command.c
@@ -0,0 +1,715 @@
+/*++
+
+Copyright (c) 1990 Microsoft Corporation
+
+Module Name:
+
+ command.c
+
+Abstract:
+
+ This file contains the code for managing command and transmit blocks on
+ the TOK162's queues. It is based loosely on the NE3200 driver.
+
+Author:
+
+ Kevin Martin(KevinMa) 04-Jan-1993
+
+Environment:
+
+ Kernel Mode - Or whatever is the equivalent on OS/2 and DOS.
+
+Revision History:
+
+
+--*/
+
+#include <tok162sw.h>
+
+VOID
+TOK162SendCommandBlock(
+ PTOK162_ADAPTER Adapter,
+ PTOK162_SUPER_COMMAND_BLOCK CommandBlock
+ );
+
+
+VOID
+TOK162SubmitCommandBlock(
+ IN PTOK162_ADAPTER Adapter,
+ IN PTOK162_SUPER_COMMAND_BLOCK CommandBlock
+ )
+
+/*++
+
+Routine Description:
+
+ Submit a complete Command Block for execution by the TOK162.
+
+Arguments:
+
+ Adapter - The adapter that points to the ring entry structures.
+
+ CommandBlock - Holds the pointer to the Command Block to be
+ submitted.
+
+Return Value:
+
+ None.
+
+--*/
+{
+ //
+ // Pointer to the most recently submitted Command Block.
+ //
+ PTOK162_SUPER_COMMAND_BLOCK PreviousCommandBlock;
+
+ // Ensure that our command block is on an even boundary.
+ //
+ ASSERT(!(NdisGetPhysicalAddressLow(CommandBlock->Self) & 1));
+
+ //
+ // Timestamp the command block.
+ //
+ CommandBlock->Timeout = FALSE;
+ CommandBlock->Hardware.State = TOK162_STATE_WAIT_FOR_ADAPTER;
+
+ //
+ // If the adapter is currently executing a command add this to
+ // the end of the waiting list. Otherwise submit this command to the card.
+ //
+ if (Adapter->CommandOnCard != NULL) {
+
+ //
+ // Pend this command
+ //
+ IF_LOG('i');
+
+ PreviousCommandBlock = Adapter->WaitingCommandTail;
+ Adapter->WaitingCommandTail = CommandBlock;
+
+ //
+ // Check if there are any other pendings. If not, we are
+ // the first pending. If there are others, tack this one on
+ // the end.
+ //
+ if (PreviousCommandBlock == NULL) {
+
+ Adapter->WaitingCommandHead = CommandBlock;
+
+ } else {
+
+ PreviousCommandBlock->NextCommand = CommandBlock;
+
+ }
+
+ } else {
+
+ //
+ // Set this command as the active one
+ //
+ Adapter->CommandOnCard = CommandBlock;
+
+ //
+ // Log that we are sending the command to the card
+ //
+ IF_LOG('I');
+
+ //
+ // send the command out to the card
+ //
+ TOK162SendCommandBlock(Adapter,CommandBlock);
+
+ }
+
+}
+
+VOID
+TOK162SubmitTransmitBlock(
+ IN PTOK162_ADAPTER Adapter,
+ IN PTOK162_SUPER_COMMAND_BLOCK CommandBlock
+ )
+
+/*++
+
+Routine Description:
+
+ Submit a complete Command Block for execution by the TOK162.
+
+Arguments:
+
+ Adapter - The adapter that points to the ring entry structures.
+
+ CommandBlock - Holds the pointer to the transmit block to be
+ submitted.
+
+Return Value:
+
+ None.
+
+--*/
+{
+ //
+ // Pointer to the most recently submitted Transmit Block.
+ //
+ PTOK162_SUPER_COMMAND_BLOCK PreviousCommandBlock;
+
+ // Ensure that our command block is on an even boundary.
+ //
+ ASSERT(!(NdisGetPhysicalAddressLow(CommandBlock->Self) & 1));
+
+ //
+ // Timestamp the transmit block.
+ //
+ CommandBlock->Timeout = FALSE;
+ CommandBlock->Hardware.State = TOK162_STATE_WAIT_FOR_ADAPTER;
+
+ //
+ // If the adapter is currently executing a transmit add this to
+ // the end of the waiting list. Otherwise submit this transmit to
+ // the card.
+ //
+ if (Adapter->TransmitOnCard != NULL) {
+
+ //
+ // Log that we have to pend the transmit
+ IF_LOG('w');
+
+ //
+ // Pend this transmit
+ //
+ PreviousCommandBlock = Adapter->WaitingTransmitTail;
+ Adapter->WaitingTransmitTail = CommandBlock;
+
+ //
+ // Check if there are any other pendings
+ //
+ if (PreviousCommandBlock == NULL) {
+
+ Adapter->WaitingTransmitHead = CommandBlock;
+
+ } else {
+
+ PreviousCommandBlock->NextCommand = CommandBlock;
+
+ }
+
+ } else {
+
+ //
+ // Mark this transmit as the active one.
+ //
+ Adapter->TransmitOnCard = CommandBlock;
+
+ //
+ // Log that we are sending the transmit over the wire
+ //
+ IF_LOG('W');
+
+ //
+ // send the transmit to the card
+ //
+ TOK162SendCommandBlock(Adapter,CommandBlock);
+
+ }
+
+}
+
+BOOLEAN
+TOK162AcquireTransmitBlock(
+ IN PTOK162_ADAPTER Adapter,
+ OUT PTOK162_SUPER_COMMAND_BLOCK * CommandBlock
+ )
+
+/*++
+
+Routine Description:
+
+ Sees if a Transmit Block is available and if so returns its index.
+
+Arguments:
+
+ Adapter - The adapter that has the transmit queue
+
+ CommandBlock - Will receive a pointer to a Command Block if one is
+ available.
+
+Return Value:
+
+ Returns FALSE if there are no free Command Blocks.
+
+--*/
+
+{
+
+ //
+ // Pointer to the available transmit block
+ //
+ PTOK162_SUPER_COMMAND_BLOCK temp;
+
+ //
+ // Get a pointer to the Transmit Block.
+ //
+ temp = Adapter->TransmitQueue + Adapter->NextTransmitBlock;
+
+ //
+ // If there aren't any available transmits, we return FALSE
+ //
+ if (Adapter->NumberOfAvailableTransmitBlocks == 0) {
+
+ //
+ // Log that there weren't any available
+ //
+ IF_LOG('x');
+
+ return FALSE;
+
+ }
+
+ //
+ // Decrement the number of available transit blocks.
+ //
+ Adapter->NumberOfAvailableTransmitBlocks--;
+
+ //
+ // Initialize the Transmit Command Block.
+ //
+ temp->Hardware.NextPending = TOK162_NULL;
+ temp->CommandBlock = FALSE;
+
+ //
+ // Increment to next transmit command block
+ //
+ if (Adapter->NextTransmitBlock == (Adapter->NumberOfTransmitLists - 1)) {
+
+ Adapter->NextTransmitBlock = 0;
+
+ } else {
+
+ Adapter->NextTransmitBlock++;
+ }
+
+ //
+ // Return the transmit block pointer.
+ //
+ *CommandBlock = temp;
+
+ //
+ // Log that we returned a transmit block.
+ //
+ IF_LOG('X');
+
+ return(TRUE);
+
+}
+
+VOID
+TOK162AcquireCommandBlock(
+ IN PTOK162_ADAPTER Adapter,
+ OUT PTOK162_SUPER_COMMAND_BLOCK * CommandBlock
+ )
+
+/*++
+
+Routine Description:
+
+ Gets the command block.
+
+Arguments:
+
+ Adapter - The adapter that points to the ring entry structures.
+
+ CommandBlock - Will receive a pointer to a Command Block.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+ //
+ // Pointer to the command block to be returned.
+ //
+ PTOK162_SUPER_COMMAND_BLOCK temp;
+
+ //
+ // This is a pointer to the Command Block.
+ //
+ temp = Adapter->CommandQueue + Adapter->NextCommandBlock;
+
+ ASSERT(Adapter->NumberOfAvailableCommandBlocks > 0);
+
+ IF_LOG('l');
+
+ //
+ // Decrement the number of available command blocks
+ //
+ Adapter->NumberOfAvailableCommandBlocks--;
+
+ //
+ // Initialize the Command Block.
+ //
+ NdisZeroMemory(
+ temp,
+ sizeof(TOK162_SUPER_COMMAND_BLOCK)
+ );
+
+ //
+ // There aren't any linked command blocks right now.
+ //
+ temp->Hardware.NextPending = TOK162_NULL;
+
+ //
+ // This is a command block and not a transmit block
+ //
+ temp->CommandBlock = TRUE;
+
+ //
+ // Set the self-referential pointer.
+ //
+ NdisSetPhysicalAddressLow(
+ temp->Self,
+ NdisGetPhysicalAddressLow(Adapter->CommandQueuePhysical) +
+ Adapter->NextCommandBlock * sizeof(TOK162_SUPER_COMMAND_BLOCK)
+ );
+
+ //
+ // Increment to next command block
+ //
+ if (Adapter->NextCommandBlock == (TOK162_NUMBER_OF_CMD_BLOCKS - 1)) {
+
+ Adapter->NextCommandBlock = 0;
+
+ } else {
+
+ Adapter->NextCommandBlock++;
+
+ }
+
+ //
+ // Return the Command Block pointer.
+ //
+ *CommandBlock = temp;
+
+ //
+ // Log that we returned a command block
+ //
+ IF_LOG('L');
+
+}
+
+
+VOID
+TOK162RelinquishCommandBlock(
+ IN PTOK162_ADAPTER Adapter,
+ IN PTOK162_SUPER_COMMAND_BLOCK CommandBlock
+ )
+
+/*++
+
+Routine Description:
+
+ Relinquish the Command Block resource.
+
+Arguments:
+
+ Adapter - The adapter that owns the Command Block.
+
+ CommandBlock - The Command Block to relinquish.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+ //
+ // If there is a waiting chain of commands -- submit the first one
+ //
+ if (Adapter->WaitingCommandHead != NULL) {
+
+ //
+ // Log that we found pending commands
+ //
+ IF_LOG('j');
+
+ //
+ // Mark the next one as the active one.
+ //
+ Adapter->CommandOnCard = Adapter->WaitingCommandHead;
+
+ //
+ // Update the waiting command head.
+ //
+ Adapter->WaitingCommandHead =
+ Adapter->WaitingCommandHead->NextCommand;
+
+ //
+ // Update the waiting command tail pointer
+ //
+ if (Adapter->WaitingCommandHead == NULL) {
+
+ Adapter->WaitingCommandTail = NULL;
+
+ }
+
+ //
+ // Send out the new command
+ //
+ TOK162SendCommandBlock(Adapter,Adapter->CommandOnCard);
+
+ } else {
+
+ //
+ // Indicate that the queue was empty.
+ //
+ IF_LOG('J');
+
+ //
+ // No commands on the card. We're done for now.
+ //
+ Adapter->CommandOnCard = NULL;
+
+ }
+
+ //
+ // Free the command block
+ //
+ CommandBlock->Hardware.State = TOK162_STATE_FREE;
+ CommandBlock->NextCommand = NULL;
+
+ //
+ // Increment the number of available command blocks
+ //
+ Adapter->NumberOfAvailableCommandBlocks++;
+
+}
+
+
+VOID
+TOK162RelinquishTransmitBlock(
+ IN PTOK162_ADAPTER Adapter,
+ IN PTOK162_SUPER_COMMAND_BLOCK CommandBlock
+ )
+
+/*++
+
+Routine Description:
+
+ Relinquish the Transmit Command Block resource.
+
+Arguments:
+
+ Adapter - The adapter that owns the Command Block.
+
+ CommandBlock - The transmit block to relinquish.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+ //
+ // If there is a waiting chain of commands -- submit the first one
+ //
+ if (Adapter->WaitingTransmitHead != NULL) {
+
+ //
+ // Log that there is a waiting send.
+ //
+ IF_LOG('y');
+
+ //
+ // Update the queue pointers
+ //
+ Adapter->TransmitOnCard = Adapter->WaitingTransmitHead;
+
+ Adapter->WaitingTransmitHead =
+ Adapter->WaitingTransmitHead->NextCommand;
+
+ if (Adapter->WaitingTransmitHead == NULL) {
+
+ Adapter->WaitingTransmitTail = NULL;
+
+ }
+
+ //
+ // Submit this command to the card.
+ //
+ TOK162SendCommandBlock(Adapter,Adapter->TransmitOnCard);
+
+ } else {
+
+ //
+ // Log that the waiting queue was empty.
+ //
+ IF_LOG('Y');
+
+ //
+ // We are done with submits
+ //
+ Adapter->TransmitOnCard = NULL;
+
+ }
+
+ //
+ // Free the transmit block
+ //
+ CommandBlock->Hardware.State = TOK162_STATE_FREE;
+ CommandBlock->NextCommand = NULL;
+
+ //
+ // Increment the number of available transmit blocks
+ //
+ Adapter->NumberOfAvailableTransmitBlocks++;
+
+ //
+ // Decrement the number of queued transmit blocks
+ //
+ Adapter->TransmitsQueued--;
+
+}
+
+
+void
+TOK162SendCommandBlock(
+ IN PTOK162_ADAPTER Adapter,
+ IN PTOK162_SUPER_COMMAND_BLOCK CommandBlock
+ )
+{
+/*++
+
+Routine Description:
+
+ Submits the command block passed in to the card.
+
+Arguments:
+
+ Adapter - The adapter that owns the Command Block.
+
+ CommandBlock - The command/transmit block to submit.
+
+Return Value:
+
+ None.
+
+--*/
+
+ //
+ // This is the "execution" variable for the SCB. The standard is to just
+ // send the interrupt adapter, execute, and don't reset the
+ // adapter-to-system interrupt bits. The initial init open command will
+ // add in the scb clear bit.
+ ULONG ScbExecute = EXECUTE_SCB_COMMAND;
+
+ //
+ // First figure out the SCB, based on the command
+ //
+ Adapter->Scb->Command = CommandBlock->Hardware.CommandCode;
+
+ switch(Adapter->Scb->Command) {
+
+ //
+ // We have a transmit.
+ //
+ case CMD_DMA_XMIT:
+
+ //
+ // Point the Scb to the transmit list
+ //
+ Adapter->Scb->Parm1 =
+ BYTE_SWAP(HIGH_WORD(CommandBlock->PhysicalTransmitEntry));
+
+ Adapter->Scb->Parm2 =
+ BYTE_SWAP(LOW_WORD(CommandBlock->PhysicalTransmitEntry));
+
+ break;
+
+ //
+ // These are the Immediate Data commands. Close doesn't care what
+ // is passed, however.
+ //
+ case CMD_DMA_CLOSE:
+ case CMD_DMA_SET_GRP_ADDR:
+ case CMD_DMA_SET_FUNC_ADDR:
+
+ //
+ // The parameter is set according to the ImmediateData field of
+ // the command block.
+ //
+ Adapter->Scb->Parm1 =
+ BYTE_SWAP(HIGH_WORD(CommandBlock->Hardware.ImmediateData));
+
+ Adapter->Scb->Parm2 =
+ BYTE_SWAP(LOW_WORD(CommandBlock->Hardware.ImmediateData));
+
+ break;
+
+ //
+ // The rest use a pointer.
+ //
+
+ //
+ // In the case of an open, we have to check to see if this is part
+ // of the initial init. If so, we need to get the SCB Clear bit
+ // set so we have proper timing for the receieve command. After
+ // that decision has been made, the open command is treated like
+ // any other pointer command.
+ //
+ case CMD_DMA_OPEN:
+
+ if (Adapter->InitialInit == TRUE) {
+
+ ScbExecute |= CMD_PIO_SCB_REQUEST;
+
+ }
+
+ case CMD_DMA_READ_ERRLOG:
+ case CMD_DMA_READ:
+ case CMD_DMA_RCV:
+ case CMD_DMA_IMPL_ENABLE:
+
+ //
+ // The parameter is set according to the ParmPointer field of
+ // the command block.
+ //
+ Adapter->Scb->Parm1 =
+ BYTE_SWAP(HIGH_WORD(CommandBlock->Hardware.ParmPointer));
+
+ Adapter->Scb->Parm2 =
+ BYTE_SWAP(LOW_WORD(CommandBlock->Hardware.ParmPointer));
+
+ break;
+
+ }
+
+ //
+ // Mark the command block as executing
+ //
+ CommandBlock->Hardware.State = TOK162_STATE_EXECUTING;
+
+ //
+ // Log that we are sending an SCB to the card.
+ //
+ IF_LOG('Z');
+
+ //
+ // Display the SCB on the debugger
+ //
+ EXTRA_LOUD_DEBUG(DbgPrint("SCB going out is %x,%x,%x\n",
+ Adapter->Scb->Command,
+ Adapter->Scb->Parm1,
+ Adapter->Scb->Parm2);)
+
+ //
+ // Finally, send the command out to the card
+ //
+ WRITE_ADAPTER_USHORT(Adapter,
+ PORT_OFFSET_COMMAND,
+ ScbExecute
+ );
+
+}
diff --git a/private/ntos/ndis/ibmtok2i/interrup.c b/private/ntos/ndis/ibmtok2i/interrup.c
new file mode 100644
index 000000000..8db43f373
--- /dev/null
+++ b/private/ntos/ndis/ibmtok2i/interrup.c
@@ -0,0 +1,1376 @@
+/*++
+
+Copyright (c) 1990 Microsoft Corporation
+
+Module Name:
+
+ interrup.c
+
+Abstract:
+
+ This module contains the interrupt-processing code for the
+ TOK162 NDIS 3.0 driver.
+
+Author:
+
+ Kevin Martin (KevinMa) 26-Jan-1994
+
+Environment:
+
+ Kernel Mode.
+
+Revision History:
+
+--*/
+
+#include <tok162sw.h>
+
+VOID
+TOK162ProcessReceiveInterrupts(
+ IN PTOK162_ADAPTER Adapter
+ );
+
+VOID
+TOK162ProcessCommandInterrupts(
+ IN PTOK162_ADAPTER Adapter
+ );
+
+
+VOID
+TOK162Isr(
+ OUT PBOOLEAN InterruptRecognized,
+ OUT PBOOLEAN QueueDpc,
+ IN PVOID Context
+ )
+
+/*++
+
+Routine Description:
+
+ Interrupt service routine for the TOK162. Used only during init.
+ The NdisMRegisterInterrupt() call (reset.c) specified not to call the
+ ISR for every interrupt. The DPC is called directly instead.
+
+Arguments:
+
+ Interrupt - Interrupt object for the TOK162.
+
+ Context - Really a pointer to the adapter.
+
+Return Value:
+
+ Returns true if the interrupt really was from the TOK162 and whether the
+ wrapper should queue a DPC.
+
+--*/
+
+{
+
+ //
+ // Holds the pointer to the adapter structure.
+ //
+ PTOK162_ADAPTER Adapter = Context;
+
+ //
+ // Holds IsrpHigh with some bits masked off.
+ //
+ USHORT Sif;
+
+ //
+ // Indicate that an interrupt has occurred (internal logging and
+ // debug print's).
+ //
+ VERY_LOUD_DEBUG(DbgPrint("TOK162!ISR\n");)
+ IF_LOG('o');
+
+ //
+ // Read the adapter interrupt register
+ //
+ READ_ADAPTER_USHORT(Adapter,PORT_OFFSET_STATUS,&Sif);
+
+ //
+ // Check if this is our interrupt. If it is, set flag indicating that the
+ // interrupt is recognized. Otherwise indicate that the interrupt is not
+ // ours.
+ //
+ if ((Sif & STATUS_SYSTEM_INTERRUPT) != 0) {
+
+ *InterruptRecognized = TRUE;
+
+ } else {
+
+ *InterruptRecognized = FALSE;
+
+ }
+
+ //
+ // Mask off the interrupt type portion of the register.
+ //
+ Sif = (UCHAR) (Sif & STATUS_INT_CODE_MASK);
+
+ //
+ // If this is a receive, go ahead and do the DPC. This allows us to keep
+ // in synch with the card concerning the receive list index. Also, for a
+ // a receive there is no need to allow the SSB to be updated as the DPC
+ // routine will do this for us. If it isn't a receive, we need to indicate
+ // that no DPC is necessary and we also allow the SSB to be updated.
+ //
+ if (Sif == STATUS_INT_CODE_RECEIVE_STATUS) {
+
+ IF_LOG('p');
+
+ *QueueDpc = TRUE;
+
+ //
+ // If we have a command, then it is the open or an error has occurred.
+ // Indicate that the Ssb can be cleared after the open info has been
+ // obtained.
+ //
+ } else if (Sif == STATUS_INT_CODE_CMD_STATUS) {
+
+ if (Adapter->Ssb->Command == CMD_DMA_OPEN) {
+
+ Adapter->SsbStatus1 = Adapter->Ssb->Status1;
+ Adapter->InitialOpenComplete = TRUE;
+
+ }
+
+ //
+ // Enable updating of the SSB
+ //
+ IF_LOG('z');
+
+ WRITE_ADAPTER_USHORT(Adapter,
+ PORT_OFFSET_STATUS,
+ ENABLE_SSB_UPDATE
+ );
+
+
+ *QueueDpc = FALSE;
+
+ //
+ // If we get the SCB clear interrupt, then we can do the receive command.
+ //
+ } else if (Sif == STATUS_INT_CODE_SCB_CLEAR) {
+
+ DoTheReceive(Adapter);
+ Adapter->InitialReceiveSent = TRUE;
+
+ } else {
+
+ //
+ // Enable updating of the SSB
+ //
+ IF_LOG('z');
+
+ WRITE_ADAPTER_USHORT(Adapter,
+ PORT_OFFSET_STATUS,
+ ENABLE_SSB_UPDATE
+ );
+
+ *QueueDpc = FALSE;
+
+ }
+
+ //
+ // Indicate the ISR routine has ended.
+ //
+ IF_LOG('O');
+}
+
+
+VOID
+TOK162DeferredTimer(
+ IN PVOID SystemSpecific1,
+ IN PTOK162_ADAPTER Adapter,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3
+ )
+/*++
+
+Routine Description:
+
+ Just an entry point to distinguish between a timer call and the wrapper
+ calling the DPC directly.
+
+Arguments:
+
+ Adapter - pointer to current adapter
+
+ The rest are not used, but simply passed on
+
+Return Value:
+
+ None
+
+--*/
+{
+ //
+ // Indicate that a timer has expired.
+ //
+ VERY_LOUD_DEBUG(DbgPrint("TOK162!Deferred Timer called\n");)
+
+ //
+ // Call the standard DPC handler.
+ //
+ TOK162HandleInterrupt(Adapter);
+}
+
+
+VOID
+TOK162HandleInterrupt(
+ IN NDIS_HANDLE MiniportAdapterContext
+ )
+
+/*++
+
+Routine Description:
+
+ Main routine for processing interrupts.
+
+Arguments:
+
+ Adapter - The Adapter to process interrupts for.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+ //
+ // Pointer to the TOK162 adapter structure.
+ //
+ PTOK162_ADAPTER Adapter = ((PTOK162_ADAPTER)MiniportAdapterContext);
+
+ //
+ // Holds the value of the interrupt type
+ //
+ USHORT IMask = 0;
+
+ //
+ // If any receive interrupts are processed, we have to indicate that
+ // the receive work has been completed after all interrupts have been
+ // processed.
+ //
+ BOOLEAN IndicateReceiveComplete = FALSE;
+
+ //
+ // Indicate that the DPC routine has been called.
+ //
+ EXTRA_LOUD_DEBUG(DbgPrint("TOK162!DPC was just called\n");)
+ IF_LOG('r');
+
+ //
+ // Loop through processing interrupts until we have processed them all.
+ //
+ while (TRUE) {
+
+ //
+ // Read the adapter interrupt register
+ //
+ READ_ADAPTER_USHORT(Adapter,
+ PORT_OFFSET_STATUS,
+ &IMask
+ );
+
+ //
+ // If this is not our interrupt, end DPC processing
+ //
+ if ((IMask & STATUS_SYSTEM_INTERRUPT) == 0) {
+
+ //
+ // Indicate that we received a bad interrupt and break
+ // out of the loop.
+ //
+ IF_LOG('a');
+
+ break;
+
+ } else {
+
+ //
+ // Indicatate that the interrupt was found to be ours.
+ //
+ IF_LOG('A');
+
+ //
+ // Record pertinent information about the interrupt as this
+ // card/chipset only allows one interrupt to be indicated by
+ // the card at a time.
+ //
+ Adapter->SsbCommand = Adapter->Ssb->Command;
+ Adapter->SsbStatus1 = Adapter->Ssb->Status1;
+ Adapter->SsbStatus2 = Adapter->Ssb->Status2;
+ Adapter->SsbStatus3 = Adapter->Ssb->Status3;
+
+ }
+
+ //
+ // Figure out the type of interrupt
+ //
+ IMask = (UCHAR) (IMask & STATUS_INT_CODE_MASK);
+
+ //
+ // Indicate the type of interrupt to the debugger.
+ //
+ EXTRA_LOUD_DEBUG(DbgPrint("TOK162!New IMask is %x\n",IMask);)
+
+ //
+ // Process the interrupt based on the type of interrupt.
+ //
+ switch(IMask) {
+
+ case STATUS_INT_CODE_RING:
+
+ //
+ // We have a ring status change. Log this fact.
+ //
+ IF_LOG('b');
+
+ //
+ // If we have a soft error, it is possible that the
+ // card has become overrun with receives. Therefore, the
+ // TOK162ProcessRingInterrupts will return TRUE in this
+ // case to allow us to call ProcessReceiveInterrupts().
+ // In all other cases, TOK162ProcessRingInterrupts() will
+ // return FALSE.
+ //
+ if (TOK162ProcessRingInterrupts(Adapter) == TRUE) {
+
+ TOK162ProcessReceiveInterrupts(Adapter);
+
+ //
+ // Indicate that we did process receives during this
+ // DPC.
+ //
+ IndicateReceiveComplete = TRUE;
+
+ }
+
+ break;
+
+ case STATUS_INT_CODE_RECEIVE_STATUS:
+
+ //
+ // We have a receive interrupt. Log this fact.
+ //
+ IF_LOG('c');
+
+ //
+ // Process the interrupt.
+ //
+ TOK162ProcessReceiveInterrupts(Adapter);
+
+ //
+ // Indicate that we did process a receive during this
+ // DPC.
+ //
+ IndicateReceiveComplete = TRUE;
+
+ break;
+
+ case STATUS_INT_CODE_XMIT_STATUS:
+
+ //
+ // We have a transmit interrupt. Log this fact.
+ //
+ IF_LOG('d');
+
+ //
+ // Process the transmit.
+ //
+ TOK162ProcessTransmitInterrupts(Adapter);
+
+ break;
+
+ case STATUS_INT_CODE_CMD_STATUS:
+
+ //
+ // We have a command interrupt to process. Log this fact.
+ //
+ IF_LOG('e');
+
+ //
+ // If there is a command structure that has been sent to the
+ // adapter, then we will process that command. Otherwise, we
+ // simply return.
+ //
+ if (Adapter->CommandOnCard != NULL) {
+
+ //
+ // Process the active command.
+ //
+ TOK162ProcessCommandInterrupts(Adapter);
+
+ }
+ break;
+
+ default:
+
+ //
+ // The interrupt type is not one that we know (illegal value).
+ // Indicate this to the debugger.
+ //
+ LOUD_DEBUG(DbgPrint("TOK162!Int Command %x, %x\n",Adapter->SsbCommand,
+ Adapter->SsbStatus1);)
+
+ break;
+
+ }
+
+ //
+ // Indicate that we are about to dismiss the interrupt.
+ //
+ IF_LOG('z');
+
+ //
+ // Dismiss the interrupt, allowing the SSB to be updated.
+ //
+ WRITE_ADAPTER_USHORT(Adapter,
+ PORT_OFFSET_STATUS,
+ ENABLE_SSB_UPDATE
+ );
+
+ }
+
+ //
+ // If we processed any receive interrupts, IndicateReceiveComplete() will
+ // be set to TRUE. In this case, we need to indicate that all receives
+ // are complete.
+ //
+ if (IndicateReceiveComplete) {
+
+ //
+ // Indicate to the debugger that we are doing the complete.
+ //
+ EXTRA_LOUD_DEBUG(DbgPrint("TOK162!Doing the indicate complete on the receive\n");)
+
+ //
+ // Call the Token Ring Filter to indicate the receive complete.
+ //
+ NdisMTrIndicateReceiveComplete(Adapter->MiniportAdapterHandle);
+
+ }
+
+ //
+ // Log and indicate to the debugger that we are ending DPC processing.
+ //
+ IF_LOG('R');
+ EXTRA_LOUD_DEBUG(DbgPrint("TOK162!Ending DPC processing\n");)
+
+}
+
+
+VOID
+TOK162ProcessReceiveInterrupts(
+ IN PTOK162_ADAPTER Adapter
+ )
+
+/*++
+
+Routine Description:
+
+ Process the packets that have finished receiving.
+
+ NOTE: This routine assumes that no other thread of execution
+ is processing receives!
+
+Arguments:
+
+ Adapter - The adapter to indicate to.
+
+Return Value:
+
+ Whether to clear interrupt or not
+
+--*/
+
+{
+
+ //
+ // We don't get here unless there was a receive. Loop through
+ // the receive blocks starting at the last known block owned by
+ // the hardware.
+ //
+ // After we find a packet we give the routine that process the
+ // packet through the filter, the buffers virtual address (which
+ // is always the lookahead size) and as the MAC Context the
+ // index to the receive block.
+ //
+
+ //
+ // Pointer to the receive block being examined.
+ //
+ PTOK162_SUPER_RECEIVE_LIST CurrentEntry = Adapter->ReceiveQueueCurrent;
+
+ //
+ // Used during receiveindicate to let the filter know the header size
+ // of the given buffer.
+ //
+ USHORT HeaderSize;
+
+ //
+ // Used to indicate the total size of the frame to the filter.
+ //
+ USHORT FrameSize;
+
+ //
+ // Points to the beginning of the received buffer. Used to determine the
+ // size of the frame header (source routing).
+ //
+ PUCHAR Temp;
+
+ //
+ // Log the fact that we are processing a receive.
+ //
+ IF_LOG('C');
+
+ //
+ // Continue processing receives until we have exhausted them.
+ //
+ while (TRUE) {
+
+ //
+ // Ensure that our Receive Entry is on an even boundary.
+ //
+ ASSERT(!(NdisGetPhysicalAddressLow(CurrentEntry->Self) & 1));
+
+ //
+ // Send the receive status byte to the debugger.
+ //
+ EXTRA_LOUD_DEBUG(DbgPrint(
+ "TOK162!Receive CSTAT == %x\n",CurrentEntry->Hardware.CSTAT);)
+
+ //
+ // Check to see if CSTAT has been changed indicating
+ // the receive entry has been modified
+ //
+ if (CurrentEntry->Hardware.CSTAT & RECEIVE_CSTAT_VALID) {
+
+ //
+ // Record the receive list entry following the last good
+ // entry as the starting point for the next time receives
+ // are processed.
+ //
+ Adapter->ReceiveQueueCurrent = CurrentEntry;
+
+ //
+ // Tell the adapter to allow more receives.
+ //
+ WRITE_ADAPTER_USHORT(Adapter,
+ PORT_OFFSET_COMMAND,
+ ENABLE_RECEIVE_VALID
+ );
+
+ return;
+
+ }
+
+ //
+ // Get a pointer to the first byte of the current receive buffer.
+ //
+ Temp = (PUCHAR)CurrentEntry->ReceiveBuffer;
+
+ //
+ // If the source routing bit is on, figure out the size of the
+ // MAC Frame header. Otherwise, the size is set to the default
+ // of 14 (decimal).
+ //
+ HeaderSize = 14;
+
+
+ if (Temp[8] & 0x80) {
+
+ //
+ // Source routing bit is on in source address, so calculate
+ // the frame header size.
+ //
+ HeaderSize = (Temp[14] & 0x1f) + 14;
+
+ }
+
+ //
+ // Save the received header size.
+ //
+ Adapter->SizeOfReceivedHeader = HeaderSize;
+
+ //
+ // Record the fact that we had a good receive.
+ //
+ Adapter->GoodReceives++;
+
+ //
+ // Make sure the adapter and the system are in synch.
+ //
+ NdisFlushBuffer(CurrentEntry->FlushBuffer, FALSE);
+
+ //
+ // Get the frame size of this buffer.
+ //
+ FrameSize = BYTE_SWAP(CurrentEntry->Hardware.FrameSize);
+
+ //
+ // Indicate the frame size to the debugger
+ //
+ EXTRA_LOUD_DEBUG(DbgPrint("TOK162!Frame size is %u\n",
+ FrameSize);)
+
+ //
+ // If the frame that we have been passed has an invalid length
+ // (less than the reported header size) then we need to check
+ // if the frame size is larger than the default address length.
+ //
+ if (FrameSize >= HeaderSize) {
+
+ //
+ // We have a 'normal' packet. Indicate this to the debugger
+ // and log it.
+ EXTRA_LOUD_DEBUG(DbgPrint("TOK162!Doing receive indicate\n");)
+ IF_LOG('q');
+
+ //
+ // Do the indication to the filter.
+ //
+ NdisMTrIndicateReceive(
+ Adapter->MiniportAdapterHandle,
+ (NDIS_HANDLE)(
+ ((PUCHAR)(CurrentEntry->ReceiveBuffer))+HeaderSize),
+ CurrentEntry->ReceiveBuffer,
+ (UINT)HeaderSize,
+ ((PUCHAR)CurrentEntry->ReceiveBuffer) + HeaderSize,
+ FrameSize - HeaderSize,
+ FrameSize - HeaderSize
+ );
+
+ } else {
+
+ //
+ // If the frame size is greater than or equal to the length
+ // of an address (network address, 12 bytes) then we can
+ // indicate it as a runt packet to the filter. Otherwise,
+ // we ignore the received buffer.
+ //
+ if (FrameSize >= TOK162_LENGTH_OF_ADDRESS) {
+
+ //
+ // Indicate this is a runt packet to the debugger
+ //
+ VERY_LOUD_DEBUG(DbgPrint(
+ "TOK162!Doing receive indicate for a runt\n");)
+
+ //
+ // Indicate the packet to the filter.
+ //
+ NdisMTrIndicateReceive(
+ Adapter->MiniportAdapterHandle,
+ (NDIS_HANDLE)(
+ ((PUCHAR)(CurrentEntry->ReceiveBuffer)) + HeaderSize),
+ (PUCHAR)Temp,
+ (UINT)FrameSize,
+ NULL,
+ 0,
+ 0
+ );
+
+ }
+
+ }
+
+ //
+ // Mark the receive list as processed and able to receive another
+ // buffer.
+ //
+ CurrentEntry->Hardware.CSTAT = RECEIVE_CSTAT_REQUEST_RESET;
+
+ //
+ // Move to the next entry to see if there are more to process.
+ //
+ CurrentEntry = CurrentEntry->NextEntry;
+
+ //
+ // Log the fact that we are telling the card to send us more receives.
+ //
+ IF_LOG('Q');
+
+ //
+ // Tell the card that we are ready to process more receives.
+ //
+ WRITE_ADAPTER_USHORT(Adapter,
+ PORT_OFFSET_COMMAND,
+ ENABLE_RECEIVE_VALID
+ );
+
+ }
+
+}
+
+
+VOID
+TOK162ProcessCommandInterrupts(
+ IN PTOK162_ADAPTER Adapter
+ )
+
+/*++
+
+Routine Description:
+
+ Process the Command Complete interrupts.
+
+ NOTE: This routine assumes that it is being executed in a
+ single thread of execution.
+
+Arguments:
+
+ Adapter - The adapter that was sent from.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+
+ //
+ // Pointer to command block being processed.
+ //
+ PTOK162_SUPER_COMMAND_BLOCK CurrentCommandBlock = Adapter->CommandOnCard;
+
+ //
+ // Status variable
+ //
+ NDIS_STATUS Status;
+
+ //
+ // NetCard Address Block
+ //
+ PTOK162_ADDRESSBLOCK Addresses;
+ //
+ // Ensure that the Command Block is on an even boundary.
+ //
+ ASSERT(!(NdisGetPhysicalAddressLow(CurrentCommandBlock->Self) & 1));
+
+ //
+ // Log the fact that we are processing a command interrupt.
+ //
+ IF_LOG('E');
+
+ //
+ // Process the command based on the command code.
+ //
+ switch(CurrentCommandBlock->Hardware.CommandCode) {
+
+ case CMD_DMA_READ:
+
+ //
+ // We are processing a read command. The read command is
+ // generated by a query request.
+ //
+ // Indicate we are processing a read command to the
+ // debugger.
+ //
+ VERY_LOUD_DEBUG(DbgPrint("TOK162!DPC for read adapter called\n");)
+
+ // Get a pointer to the block of memory set aside for the
+ // read command.
+ //
+ Addresses = (PTOK162_ADDRESSBLOCK)Adapter->AdapterBuf;
+
+ //
+ // Check the Oid to see if we are after the permanent card
+ // address or the current addresses.
+ //
+ if (Adapter->Oid == OID_802_5_PERMANENT_ADDRESS) {
+ //
+ // Update the permanent node address
+ //
+ NdisMoveMemory(
+ Adapter->NetworkAddress,
+ Addresses->NodeAddress,
+ 6
+ );
+
+ } else {
+
+ //
+ // Update the current network address
+ //
+ NdisMoveMemory(
+ (UNALIGNED PUCHAR)Adapter->CurrentAddress,
+ Addresses->NodeAddress,
+ 6);
+ }
+
+ //
+ // Finish the query and relenquish the command block
+ //
+ TOK162FinishQueryInformation(Adapter);
+ TOK162RelinquishCommandBlock(Adapter, CurrentCommandBlock);
+
+ break;
+
+ case CMD_DMA_OPEN:
+
+ //
+ // An open command is generated during a reset command. The
+ // initial open is called during adapter initialization and
+ // no DPC is generated.
+ //
+ // Indicate we are processing an open to the debugger.
+ //
+ VERY_LOUD_DEBUG(DbgPrint("TOK162!Processing the open command.\n");)
+
+ //
+ // Relinquish the command block associcated with this open.
+ //
+ TOK162RelinquishCommandBlock(Adapter, CurrentCommandBlock);
+
+ //
+ // Check to see if the open succeeded.
+ //
+ if ((Adapter->SsbStatus1 & OPEN_COMPLETION_MASK_RESULT)
+ != OPEN_RESULT_ADAPTER_OPEN) {
+
+ //
+ // The open failed. Set the current ring state and set the
+ // return variable to NDIS_STATUS_FAILURE.
+ //
+ Adapter->CurrentRingState = NdisRingStateOpenFailure;
+ Adapter->OpenErrorCode = Adapter->SsbStatus1;
+ Status = NDIS_STATUS_FAILURE;
+
+ //
+ // Display the error code on the debugger.
+ //
+ VERY_LOUD_DEBUG(DbgPrint(
+ "TOK162!Error on the open - %x\n",Adapter->SsbStatus1);)
+
+ } else {
+
+ //
+ // The open succeeded. Set the current ring state and set the
+ // return variable to NDIS_STATUS_SUCCESS.
+ //
+ Adapter->CurrentRingState = NdisRingStateOpened;
+ Adapter->OpenErrorCode = 0;
+ Status = NDIS_STATUS_SUCCESS;
+
+ //
+ // Now send out the receive command. Display the fact that
+ // DoReceive is being called on the debugger.
+ //
+ VERY_LOUD_DEBUG(DbgPrint("Doing the receive\n");)
+
+ //
+ // Check if the receive command succeeded. If not, set the
+ // return variable to NDIS_STATUS_FAILURE. It is currently
+ // set to NDIS_STATUS_SUCCESS, so no change is necessary
+ // if the receive command succeeds.
+ //
+ if (DoTheReceive(Adapter) == FALSE) {
+
+ Status = NDIS_STATUS_FAILURE;
+
+ }
+
+ }
+
+ //
+ // Indicate to the wrapper the result of the open/receive for
+ // the original reset request.
+ //
+ TOK162DoResetIndications(Adapter, Status);
+ break;
+
+ case CMD_DMA_READ_ERRLOG:
+
+ LOUD_DEBUG(DbgPrint("TOK162!DPC for read errorlog called\n");)
+
+ //
+ // Record the values for the error counters
+ //
+ Adapter->ReceiveCongestionError +=
+ Adapter->ErrorLog->ReceiveCongestionError;
+
+ Adapter->LineError += Adapter->ErrorLog->LineError;
+
+ Adapter->LostFrameError += Adapter->ErrorLog->LostFrameError;
+
+ Adapter->BurstError += Adapter->ErrorLog->BurstError;
+
+ Adapter->FrameCopiedError += Adapter->ErrorLog->FrameCopiedError;
+
+ Adapter->TokenError += Adapter->ErrorLog->TokenError;
+
+ Adapter->InternalError += Adapter->ErrorLog->InternalError;
+
+ Adapter->ARIFCIError += Adapter->ErrorLog->ARIFCIError;
+
+ Adapter->AbortDelimeter += Adapter->ErrorLog->AbortDelimeter;
+
+ Adapter->DMABusError += Adapter->ErrorLog->DMABusError;
+
+ //
+ // Indicate the values to the debugger
+ //
+ VERY_LOUD_DEBUG(DbgPrint("TOK162!CongestionErrors = %u\n",
+ Adapter->ErrorLog->ReceiveCongestionError);)
+
+ VERY_LOUD_DEBUG(DbgPrint("TOK162!LineErrors = %u\n",
+ Adapter->ErrorLog->LineError);)
+
+ VERY_LOUD_DEBUG(DbgPrint("TOK162!LostFrameErrors = %u\n",
+ Adapter->ErrorLog->LostFrameError);)
+
+ VERY_LOUD_DEBUG(DbgPrint("TOK162!BurstErrors = %u\n",
+ Adapter->ErrorLog->BurstError);)
+
+ VERY_LOUD_DEBUG(DbgPrint("TOK162!FrameCopiedErrors = %u\n",
+ Adapter->ErrorLog->FrameCopiedError);)
+
+ VERY_LOUD_DEBUG(DbgPrint("TOK162!TokenErrors = %u\n",
+ Adapter->ErrorLog->TokenError);)
+
+ VERY_LOUD_DEBUG(DbgPrint("TOK162!InternalErrors = %u\n",
+ Adapter->ErrorLog->InternalError);)
+
+ VERY_LOUD_DEBUG(DbgPrint("TOK162!ARIFCIErrors = %u\n",
+ Adapter->ErrorLog->ARIFCIError);)
+
+ VERY_LOUD_DEBUG(DbgPrint("TOK162!AbortDelimeters = %u\n",
+ Adapter->ErrorLog->AbortDelimeter);)
+
+ VERY_LOUD_DEBUG(DbgPrint("TOK162!DMABusErrors = %u\n",
+ Adapter->ErrorLog->DMABusError);)
+
+ //
+ // If a query for information generated this interrupt, finish
+ // the query.
+ //
+ if (Adapter->RequestInProgress) {
+
+ TOK162FinishQueryInformation(Adapter);
+
+ }
+
+ //
+ // Relinquish the command block associated with this
+ // readadapterlog.
+ //
+ TOK162RelinquishCommandBlock(Adapter, CurrentCommandBlock);
+
+ break;
+
+
+ default:
+
+ //
+ // Did this command come from a set information request?
+ //
+ if (CurrentCommandBlock->Set) {
+
+ //
+ // Relinquish the command block.
+ //
+ TOK162RelinquishCommandBlock(Adapter, CurrentCommandBlock);
+
+ //
+ // Mark the current request state as complete.
+ //
+ Adapter->RequestInProgress = FALSE;
+
+ //
+ // Inform the wrapper the request has been completed.
+ //
+ NdisMSetInformationComplete(
+ Adapter->MiniportAdapterHandle,
+ NDIS_STATUS_SUCCESS);
+
+ //
+ // Not from a set. If this is the unique case of where a group
+ // address and a functional address had to be set to satisfy a
+ // packet filter change command (two commands for one), then we
+ // will only do an indication on the last one. The first one,
+ // however, still needs to have the command block associated
+ // with it relinquished.
+ //
+ } else if ((CurrentCommandBlock->Hardware.CommandCode == CMD_DMA_SET_GRP_ADDR) ||
+ (CurrentCommandBlock->Hardware.CommandCode == CMD_DMA_SET_FUNC_ADDR)) {
+
+ TOK162RelinquishCommandBlock(Adapter, CurrentCommandBlock);
+
+ }
+
+ break;
+ }
+
+}
+
+
+VOID
+TOK162ProcessTransmitInterrupts(
+ IN PTOK162_ADAPTER Adapter
+ )
+
+/*++
+
+Routine Description:
+
+ Process the Transmit Complete interrupts.
+
+ NOTE: This routine assumes that it is being executed in a
+ single thread of execution.
+
+Arguments:
+
+ Adapter - The adapter the transmit was sent from.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+ //
+ // Pointer to command block being processed.
+ //
+ PTOK162_SUPER_COMMAND_BLOCK CurrentCommandBlock = Adapter->TransmitOnCard;
+
+ //
+ // Pointer to the packet that started this transmission.
+ //
+ PNDIS_PACKET OwningPacket;
+
+ //
+ // Points to the reserved part of the OwningPacket.
+ //
+ PTOK162_RESERVED Reserved;
+
+ //
+ // Holds CSTAT variable for transmit
+ //
+ USHORT Cstat;
+
+ //
+ // Status variable
+ //
+ NDIS_STATUS Status;
+
+ //
+ // Ensure that the Command Block is on an even boundary.
+ //
+ ASSERT(!(NdisGetPhysicalAddressLow(CurrentCommandBlock->Self) & 1));
+
+ //
+ // Log the fact that we are processing a transmit interrupt
+ //
+ IF_LOG('D');
+
+ //
+ // Check if there is any reason to continue with the process. It is
+ // possible during a reset that not all of the transmits had completed.
+ // The reset path takes care of aborting all sends that didn't complete
+ // so we don't want to process anything during a reset. In the general
+ // case we don't want to process any transmit that doesn't have an
+ // associated command block.
+ //
+ if ((CurrentCommandBlock == NULL) ||
+ (Adapter->ResetInProgress == TRUE)) {
+
+ //
+ // Log the fact that we received a possibly bogus transmit interrupt.
+ //
+ IF_LOG('p');
+ return;
+
+ }
+
+ //
+ // Get a pointer to the owning packet and the reserved part of
+ // the packet.
+ //
+ OwningPacket = CurrentCommandBlock->OwningPacket;
+ Reserved = PTOK162_RESERVED_FROM_PACKET(OwningPacket);
+
+ //
+ // Check if this packet was constrained.
+ //
+ if (CurrentCommandBlock->UsedTOK162Buffer == FALSE) {
+ //
+ // Pointer to the current NDIS_BUFFER that we need to do the
+ // completemapregister on.
+ //
+ PNDIS_BUFFER CurrentBuffer;
+
+ //
+ // Index to the map register being freed.
+ //
+ UINT CurMapRegister;
+
+ //
+ // The transmit is finished, so we can release
+ // the physical mapping used for it.
+ //
+ NdisQueryPacket(
+ OwningPacket,
+ NULL,
+ NULL,
+ &CurrentBuffer,
+ NULL
+ );
+
+ //
+ // Compute the first map register used by this transmit.
+ //
+ CurMapRegister = CurrentCommandBlock->CommandBlockIndex *
+ Adapter->TransmitThreshold;
+
+ //
+ // Loop through the NDIS_BUFFERs until there are no more.
+ //
+ while (CurrentBuffer != NULL) {
+
+ //
+ // Free the current map register.
+ //
+ NdisMCompleteBufferPhysicalMapping(
+ Adapter->MiniportAdapterHandle,
+ CurrentBuffer,
+ CurMapRegister
+ );
+
+ //
+ // Move to the next map register.
+ //
+ ++CurMapRegister;
+
+ //
+ // Get the next NDIS_BUFFER
+ //
+ NdisGetNextBuffer(
+ CurrentBuffer,
+ &CurrentBuffer
+ );
+
+ }
+
+ }
+
+ //
+ // If there was an error transmitting this
+ // packet, update our error counters.
+ //
+ Cstat = CurrentCommandBlock->Hardware.TransmitEntry.CSTAT;
+
+ //
+ // Display the completion status for the transmit entry on the debugger.
+ //
+ VERY_LOUD_DEBUG(DbgPrint(
+ "TOK162!Csat for the command block is %x\n",Cstat);)
+
+ //
+ // Check if there was an error on the transmit. Set Status and increment
+ // appropriate counter.
+ //
+ if ((Cstat & TRANSMIT_CSTAT_XMIT_ERROR) != 0) {
+
+ Adapter->BadTransmits++;
+ Status = NDIS_STATUS_FAILURE;
+
+ } else {
+
+ Adapter->GoodTransmits++;
+ Status = NDIS_STATUS_SUCCESS;
+
+ }
+
+ //
+ // Release the command block.
+ //
+ TOK162RelinquishTransmitBlock(Adapter, CurrentCommandBlock);
+
+ //
+ // Indicate to the filter than the send has been completed.
+ //
+ NdisMSendComplete(
+ Adapter->MiniportAdapterHandle,
+ OwningPacket,
+ Status
+ );
+
+}
+
+
+
+BOOLEAN
+TOK162ProcessRingInterrupts(
+ IN PTOK162_ADAPTER Adapter
+ )
+/*++
+
+Routine Description:
+
+ Process ring status interrupts.
+
+Arguments:
+
+ Adapter - The adapter registering the ring interrupt
+
+Return Value:
+
+ FALSE - Don't need to process receives as a result of the ring condition
+ TRUE - Need to process receives
+
+--*/
+{
+ //
+ // Holds the return status value
+ //
+ ULONG RingStatus;
+
+ //
+ // Command block variable used if we need to read the errorlog due to
+ // an overflow condition.
+ //
+ PTOK162_SUPER_COMMAND_BLOCK CommandBlock;
+
+ //
+ // Return value for the function. Assume we don't need to process
+ // receives.
+ //
+ BOOLEAN SoftError = FALSE;
+
+ //
+ // Log that we are processing a ring DPC. Display the ring interrupt
+ // information on the debugger.
+ //
+ IF_LOG('B');
+ VERY_LOUD_DEBUG(DbgPrint(
+ "TOK162!Doing ring processing -%04x\n",Adapter->SsbStatus1);)
+
+ //
+ // Initialize Ring Status to 0
+ //
+ RingStatus = 0;
+
+ //
+ // Determine the reason for the ring interrupt.
+ //
+ if (Adapter->SsbStatus1 & RING_STATUS_SIGNAL_LOSS) {
+
+ RingStatus |= NDIS_RING_SIGNAL_LOSS;
+
+ } else if (Adapter->SsbStatus1 & RING_STATUS_HARD_ERROR) {
+
+ RingStatus |= NDIS_RING_HARD_ERROR;
+
+ } else if (Adapter->SsbStatus1 & RING_STATUS_SOFT_ERROR) {
+
+ //
+ // If we have a soft error, we should check the receives.
+ //
+ RingStatus |= NDIS_RING_SOFT_ERROR;
+ SoftError = TRUE;
+
+ } else if (Adapter->SsbStatus1 & RING_STATUS_XMIT_BEACON) {
+
+ RingStatus |= NDIS_RING_TRANSMIT_BEACON;
+
+ } else if (Adapter->SsbStatus1 & RING_STATUS_LOBE_WIRE_FAULT) {
+
+ RingStatus |= NDIS_RING_LOBE_WIRE_FAULT;
+
+ } else if (Adapter->SsbStatus1 & RING_STATUS_AUTO_REMOVE_1) {
+
+ RingStatus |= NDIS_RING_AUTO_REMOVAL_ERROR;
+
+ } else if (Adapter->SsbStatus1 & RING_STATUS_REMOVE_RECEIVED) {
+
+ RingStatus |= NDIS_RING_REMOVE_RECEIVED;
+
+ } else if (Adapter->SsbStatus1 & RING_STATUS_OVERFLOW) {
+
+ RingStatus |= NDIS_RING_COUNTER_OVERFLOW;
+
+ } else if (Adapter->SsbStatus1 & RING_STATUS_SINGLESTATION) {
+
+ RingStatus |= NDIS_RING_SINGLE_STATION;
+
+ } else if (Adapter->SsbStatus1 & RING_STATUS_RINGRECOVERY) {
+
+ RingStatus |= NDIS_RING_RING_RECOVERY;
+
+ }
+
+ //
+ // Display the ring status that we will be indicating to the filter on
+ // the debugger.
+ //
+ VERY_LOUD_DEBUG(DbgPrint(
+ "TOK162!Indicating ring status - %lx\n",RingStatus);)
+
+ //
+ // Save the current status for query purposes.
+ //
+ Adapter->LastNotifyStatus = RingStatus;
+
+ //
+ // Indicate to the filter the ring status.
+ //
+ NdisMIndicateStatus(
+ Adapter->MiniportAdapterHandle,
+ NDIS_STATUS_RING_STATUS,
+ &RingStatus,
+ sizeof(ULONG)
+ );
+
+ //
+ // Tell the filter that we have completed the ring status.
+ //
+ NdisMIndicateStatusComplete(Adapter->MiniportAdapterHandle);
+
+ //
+ // If a counter has overflowed, we need to read the stats from
+ // the adapter to clear this condition.
+ //
+ if ((Adapter->SsbStatus1 & RING_STATUS_OVERFLOW) != 0) {
+
+
+ //
+ // Get a command block.
+ //
+ TOK162AcquireCommandBlock(Adapter,
+ &CommandBlock
+ );
+
+
+ //
+ // Set up the command block for a read_error_log command.
+ //
+ CommandBlock->Set = FALSE;
+ CommandBlock->NextCommand = NULL;
+ CommandBlock->Hardware.Status = 0;
+ CommandBlock->Hardware.NextPending = TOK162_NULL;
+ CommandBlock->Hardware.CommandCode = CMD_DMA_READ_ERRLOG;
+ CommandBlock->Hardware.ParmPointer =
+ NdisGetPhysicalAddressLow(Adapter->ErrorLogPhysical);
+
+ //
+ // Submit the command to the card.
+ //
+ TOK162SubmitCommandBlock(Adapter,
+ CommandBlock
+ );
+
+ }
+
+ //
+ // Return whether processreceiveinterrupts needs to be called.
+ //
+ return(SoftError);
+
+}
+
diff --git a/private/ntos/ndis/ibmtok2i/log.txt b/private/ntos/ndis/ibmtok2i/log.txt
new file mode 100644
index 000000000..b56b48d52
--- /dev/null
+++ b/private/ntos/ndis/ibmtok2i/log.txt
@@ -0,0 +1,77 @@
+a - Not our Interrupt interrup.c
+A - Our Interrupt interrup.c
+
+b - Ring Status Interrupt interrup.c
+B - Ring Status DPC interrup.c
+
+c - Receive Interrupt interrup.c
+C - Receive DPC interrup.c
+
+d - Transmit Interrupt interrup.c
+D - Transmit DPC interrup.c
+
+e - Command Interrupt interrup.c
+E - Command DPC interrup.c
+
+f -
+F - Receive Command Failed reset.c
+
+g - DoTheOpen Entered reset.c
+G - DoTheOpen Exited reset.c
+
+h - Open succeeded reset.c
+H - Open failed reset.c
+
+i - Command Block Pended command.c
+I - Command Block Sent command.c
+
+j - Command Block Relinquished, queue not empty command.c
+J - Command Block Relinquished, queue empty command.c
+
+k -
+K -
+
+l - Acquire Command Block Entered command.c
+L - Acquire Command Block Exited command.c
+
+m -
+M -
+
+n - TransferData Entered tok162.c
+N - TransferData Exited tok162.c
+
+o - ISR called interrup.c
+O - ISR leaving interrup.c
+
+p - ISR is for Receive interrup.c
+P -
+
+q - Indicate Receive interrup.c
+Q - Receive Valid Interrupt Issued interrup.c
+
+r - Entering DPC interrup.c
+R - Leaving DPC interrup.c
+
+s - Send Entered send.c
+S - Send Exited send.c
+
+t - Tramsmit Packet Entered send.c
+T - Transmit Packet Exited send.c
+
+u - Transmit Packet Exited Resources send.c
+U - Transmit Packet Exited Error send.c
+
+v - Transmit Constrain Entered send.c
+V - Transmit Constrain Exited send.c
+
+w - Transmit Command Pended command.c
+W - Transmit Command Sent command.c
+
+x - No Transmit Blocks Available command.c
+X - Transmit Block allocated command.c
+
+y - Transmit Block Relinquished, queue not empty command.c
+Y - Transmit Block Relinquished, queue empty command.c
+
+z - SSB Update interrup.c, reset.c
+Z - Execute SCB command.c, reset.c
diff --git a/private/ntos/ndis/ibmtok2i/makefile b/private/ntos/ndis/ibmtok2i/makefile
new file mode 100644
index 000000000..6ee4f43fa
--- /dev/null
+++ b/private/ntos/ndis/ibmtok2i/makefile
@@ -0,0 +1,6 @@
+#
+# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
+# file to this component. This file merely indirects to the real make file
+# that is shared by all the components of NT OS/2
+#
+!INCLUDE $(NTMAKEENV)\makefile.def
diff --git a/private/ntos/ndis/ibmtok2i/request.c b/private/ntos/ndis/ibmtok2i/request.c
new file mode 100644
index 000000000..a5dcbfd7d
--- /dev/null
+++ b/private/ntos/ndis/ibmtok2i/request.c
@@ -0,0 +1,1346 @@
+/*++
+
+Copyright (c) 1991 Microsoft Corporation
+
+Module Name:
+
+ request.c
+
+Abstract:
+
+ This file contains code to implement MiniportQueryInformation and
+ MiniportSetInformation. This driver conforms to the
+ NDIS 3.0 Miniport interface.
+
+Author:
+
+ Kevin Martin (KevinMa) 27-Jan-1994
+
+Environment:
+
+ Kernel Mode - Or whatever is the equivalent on OS/2 and DOS.
+
+Revision History:
+
+
+--*/
+
+#include <tok162sw.h>
+
+extern
+NDIS_STATUS
+TOK162ChangeAddress(
+ OUT PTOK162_ADAPTER Adapter,
+ IN ULONG Address,
+ IN NDIS_OID Oid,
+ IN USHORT Command,
+ IN BOOLEAN Set
+ );
+
+extern
+NDIS_STATUS
+TOK162SetInformation(
+ IN NDIS_HANDLE MiniportAdapterContext,
+ IN NDIS_OID Oid,
+ IN PVOID InformationBuffer,
+ IN ULONG InformationBufferLength,
+ OUT PULONG BytesRead,
+ OUT PULONG BytesNeeded
+ )
+
+/*++
+
+Routine Description:
+
+ TOK162SetInformation handles a set operation for a
+ single OID.
+
+Arguments:
+
+ MiniportAdapterContext - The adapter that the set is for.
+
+ BytesNeeded - If there is not enough data in OvbBuffer
+ to satisfy the OID, returns the amount of storage needed.
+
+Return Value:
+
+ NDIS_STATUS_SUCCESS
+ NDIS_STATUS_PENDING
+ NDIS_STATUS_INVALID_LENGTH
+ NDIS_STATUS_INVALID_OID
+
+--*/
+
+{
+ //
+ // Pointer to the TOK162 adapter structure.
+ //
+ PTOK162_ADAPTER Adapter =
+ PTOK162_ADAPTER_FROM_CONTEXT_HANDLE(MiniportAdapterContext);
+
+ //
+ // Return value from NDIS calls
+ //
+ NDIS_STATUS Status;
+
+ //
+ // Temporary storage for the packet filter
+ //
+ ULONG TempFilter;
+
+ //
+ // If we are in the middle of a reset, return this fact
+ //
+ if (Adapter->ResetInProgress == TRUE) {
+
+ return(NDIS_STATUS_RESET_IN_PROGRESS);
+
+ }
+
+ //
+ // Process request based on the OID
+ //
+ switch (Oid) {
+
+ case OID_802_5_CURRENT_FUNCTIONAL:
+
+ if (InformationBufferLength != TR_LENGTH_OF_FUNCTIONAL) {
+
+ //
+ // The data must be a multiple of the functional
+ // address size.
+ //
+
+ Status = NDIS_STATUS_INVALID_DATA;
+
+ }
+
+ //
+ // Save the address away
+ //
+ NdisMoveMemory(&Adapter->FunctionalAddress,
+ InformationBuffer,
+ InformationBufferLength
+ );
+
+ //
+ // Need to reverse it
+ //
+ Adapter->FunctionalAddress =
+ BYTE_SWAP_ULONG(Adapter->FunctionalAddress);
+
+ VERY_LOUD_DEBUG(DbgPrint("Functional Address is now %08x\n",
+ Adapter->FunctionalAddress);)
+
+ //
+ // Now call the filter package to set up the address if the
+ // functional address has been set in the packet filter.
+ //
+ if (!(Adapter->CurrentPacketFilter & NDIS_PACKET_TYPE_ALL_FUNCTIONAL) &&
+ (Adapter->CurrentPacketFilter & NDIS_PACKET_TYPE_FUNCTIONAL)
+ )
+ {
+ Status = TOK162ChangeAddress(
+ Adapter,
+ Adapter->FunctionalAddress,
+ Oid,
+ CMD_DMA_SET_FUNC_ADDR,
+ TRUE
+ );
+
+ //
+ // Nothing changed with the card, so return SUCCESS
+ //
+ } else {
+
+ Status = NDIS_STATUS_SUCCESS;
+
+ }
+
+ //
+ // Set number of bytes read
+ //
+ *BytesRead = TR_LENGTH_OF_FUNCTIONAL;
+
+ break;
+
+ case OID_802_5_CURRENT_GROUP:
+
+ //
+ // Group addresses and Functional addresses are the same length.
+ //
+ if (InformationBufferLength != TR_LENGTH_OF_FUNCTIONAL) {
+
+ //
+ // The data must be a multiple of the group
+ // address size.
+ //
+ Status = NDIS_STATUS_INVALID_DATA;
+
+ }
+
+ //
+ // Save the address away
+ //
+ NdisMoveMemory(&Adapter->GroupAddress,
+ InformationBuffer,
+ InformationBufferLength
+ );
+
+
+ //
+ // Need to reverse it
+ //
+ Adapter->GroupAddress =
+ BYTE_SWAP_ULONG(Adapter->GroupAddress);
+
+ //
+ // Now call the filter package to set up the address if group
+ // addresses have been set in the packet filter.
+ //
+ if ((Adapter->CurrentPacketFilter & NDIS_PACKET_TYPE_GROUP) != 0) {
+
+ Status = TOK162ChangeAddress(
+ Adapter,
+ Adapter->GroupAddress,
+ Oid,
+ CMD_DMA_SET_GRP_ADDR,
+ TRUE
+ );
+ } else {
+
+ Status = NDIS_STATUS_SUCCESS;
+
+ }
+
+ //
+ // Set number of bytes read
+ //
+ *BytesRead = TR_LENGTH_OF_FUNCTIONAL;
+
+ break;
+
+ case OID_GEN_CURRENT_PACKET_FILTER:
+
+ //
+ // Make sure the new packet filter is the correct size (length)
+ //
+ if (InformationBufferLength != 4) {
+
+ Status = NDIS_STATUS_INVALID_DATA;
+
+ }
+
+ //
+ //
+ TempFilter = *(PULONG)(InformationBuffer);
+ LOUD_DEBUG(DbgPrint("GEN_CURRENT_PACKET_FILTER = %x\n",TempFilter);)
+
+ //
+ // Make sure the new filter is not something we don't support
+ //
+ if (TempFilter & (NDIS_PACKET_TYPE_MULTICAST |
+ NDIS_PACKET_TYPE_ALL_MULTICAST |
+ NDIS_PACKET_TYPE_SMT |
+ NDIS_PACKET_TYPE_PROMISCUOUS |
+ NDIS_PACKET_TYPE_MAC_FRAME
+ )) {
+
+ Status = NDIS_STATUS_NOT_SUPPORTED;
+
+ *BytesRead = 4;
+ *BytesNeeded = 0;
+
+ break;
+ }
+
+ if (Adapter->CurrentPacketFilter != TempFilter) {
+
+ Adapter->CurrentPacketFilter = TempFilter;
+
+ //
+ // This is a filter we can deal with. Go change the functional
+ // and group addresses based on the filter.
+ //
+ Status = TOK162ChangeFuncGroup(Adapter);
+
+ } else {
+
+ Status = NDIS_STATUS_SUCCESS;
+
+ *BytesRead = 4;
+ *BytesNeeded = 0;
+
+ }
+
+ break;
+
+ case OID_GEN_CURRENT_LOOKAHEAD:
+
+ //
+ // We don't change anything, but we accept any value.
+ //
+ *BytesRead = 4;
+
+ Status = NDIS_STATUS_SUCCESS;
+
+ break;
+
+ //
+ // We got an OID that is not settable.
+ //
+ default:
+
+ Status = NDIS_STATUS_INVALID_OID;
+ break;
+ }
+
+ //
+ // If we have a request pending as a result of any work we've done,
+ // mark it.
+ //
+ if (Status == NDIS_STATUS_PENDING) {
+
+ Adapter->RequestInProgress = TRUE;
+
+ }
+
+ return Status;
+}
+
+extern
+NDIS_STATUS
+TOK162ChangeAddress(
+ OUT PTOK162_ADAPTER Adapter,
+ IN ULONG Address,
+ IN NDIS_OID Oid,
+ IN USHORT Command,
+ IN BOOLEAN Set
+ )
+/*++
+
+Routine Description:
+
+ TOK162ChangeAddress will submit a command for either a group or
+ functional address, based on what is passed in.
+
+Arguments:
+
+ Adapter - Structure representing the current adapter
+
+ Address - The ULONG address to send to the card
+
+ Oid - Current Oid (Either functional or group)
+
+ Command - Command to send to card
+
+ Set - Whether to mark the command as a set. If we need to change two
+ addresses (ChangeFuncGroup) as the result of one Oid, we will
+ only do a completion for the one with the set. In the normal
+ case of one address being set, Set will always be TRUE.
+
+Return Value:
+
+ NDIS_STATUS_PENDING
+
+--*/
+{
+ //
+ // Command block pointer
+ //
+ PTOK162_SUPER_COMMAND_BLOCK CommandBlock;
+
+ //
+ // Set the adapter Oid to the current Oid
+ //
+ Adapter->Oid = Oid;
+
+ //
+ // Get a command block
+ //
+ TOK162AcquireCommandBlock(Adapter,
+ &CommandBlock
+ );
+
+ //
+ // Set the command block based on the parameters passed in
+ //
+ CommandBlock->Set = Set;
+ CommandBlock->NextCommand = NULL;
+ CommandBlock->Hardware.Status = 0;
+ CommandBlock->Hardware.NextPending = TOK162_NULL;
+ CommandBlock->Hardware.CommandCode = Command;
+ CommandBlock->Hardware.ImmediateData = Address;
+
+ //
+ // Display the address about to be set on the debugger.
+ //
+ LOUD_DEBUG(DbgPrint("Address being set is %08x\n",
+ CommandBlock->Hardware.ImmediateData);)
+
+ //
+ // Indicate that a request is in progress
+ //
+ Adapter->RequestInProgress = TRUE;
+
+ //
+ // Make this request be in progress.
+ //
+ TOK162SubmitCommandBlock(Adapter, CommandBlock);
+
+ //
+ // Complete the request when the interrupt comes in.
+ //
+ return NDIS_STATUS_PENDING;
+}
+
+
+NDIS_STATUS
+TOK162QueryInformation(
+ IN NDIS_HANDLE MiniportAdapterContext,
+ IN NDIS_OID Oid,
+ IN PVOID InformationBuffer,
+ IN ULONG InformationBufferLength,
+ OUT PULONG BytesWritten,
+ OUT PULONG BytesNeeded
+)
+
+/*++
+
+Routine Description:
+
+ The TOK162QueryInformation process a Query request for specific
+ NDIS_OIDs
+
+Arguments:
+
+ MiniportAdapterContext - a pointer to the adapter.
+
+ Oid - the NDIS_OID to process.
+
+ InformationBuffer - a pointer into the
+ NdisRequest->InformationBuffer into which
+ we store the result of the query
+
+ InformationBufferLength - a pointer to the number of bytes left in the
+ InformationBuffer.
+
+ BytesWritten - a pointer to the number of bytes written into
+ the InformationBuffer.
+
+ BytesNeeded - If there is not enough room in the information
+ buffer this will contain the number of bytes
+ needed to complete the request.
+
+Return Value:
+
+ The function value is the status of the operation.(NDIS_STATUS_PENDING)
+
+--*/
+
+{
+ //
+ // Command block used for the request.
+ //
+ PTOK162_SUPER_COMMAND_BLOCK CommandBlock;
+
+ //
+ // Adapter structure for the current card
+ //
+ PTOK162_ADAPTER Adapter =
+ PTOK162_ADAPTER_FROM_CONTEXT_HANDLE(MiniportAdapterContext);
+
+ NDIS_STATUS Status = NDIS_STATUS_PENDING;
+
+ //
+ // If we are in the middle of a reset, return this fact
+ //
+ if (Adapter->ResetInProgress == TRUE)
+ {
+ return(NDIS_STATUS_RESET_IN_PROGRESS);
+ }
+
+ //
+ // Save the information passed in
+ //
+ Adapter->BytesWritten = BytesWritten;
+
+ Adapter->BytesNeeded = BytesNeeded;
+
+ Adapter->Oid = Oid;
+
+ Adapter->InformationBuffer = InformationBuffer;
+
+ Adapter->InformationBufferLength = InformationBufferLength;
+
+ //
+ // Figure out the specific command based on the OID
+ //
+ switch(Oid)
+ {
+ case OID_802_5_CURRENT_FUNCTIONAL:
+
+ if (InformationBufferLength != TR_LENGTH_OF_FUNCTIONAL)
+ {
+ //
+ // The data must be a multiple of the functional
+ // address size.
+ //
+ Status = NDIS_STATUS_INVALID_DATA;
+ }
+ else
+ {
+ //
+ // Save the address away
+ //
+ NdisMoveMemory(
+ InformationBuffer,
+ &Adapter->FunctionalAddress,
+ InformationBufferLength);
+
+ Status = NDIS_STATUS_SUCCESS;
+ }
+
+ break;
+
+ case OID_802_5_CURRENT_GROUP:
+
+ if (InformationBufferLength != TR_LENGTH_OF_FUNCTIONAL)
+ {
+ //
+ // The data must be a multiple of the group
+ // address size.
+ //
+ Status = NDIS_STATUS_INVALID_DATA;
+ }
+ else
+ {
+ //
+ // Save the address away
+ //
+ NdisMoveMemory(
+ InformationBuffer,
+ &Adapter->GroupAddress,
+ InformationBufferLength);
+
+ Status = NDIS_STATUS_SUCCESS;
+ }
+
+ break;
+
+ //
+ // If the permanent address is requested, we need to read from
+ // the adapter at the permanent address offset.
+ //
+ case OID_802_5_PERMANENT_ADDRESS:
+
+ //
+ // Get a command block
+ //
+ TOK162AcquireCommandBlock(Adapter, &CommandBlock);
+
+ //
+ // Notify that this is from a set
+ //
+ CommandBlock->Set = TRUE;
+
+ //
+ // Setup the common fields of the command block.
+ //
+ CommandBlock->NextCommand = NULL;
+ CommandBlock->Hardware.Status = 0;
+ CommandBlock->Hardware.NextPending = TOK162_NULL;
+
+ //
+ // Fill in the adapter buffer area with the information to
+ // obtain the permanent address.
+ //
+ Adapter->AdapterBuf->DataCount = BYTE_SWAP(0x0006);
+
+ Adapter->AdapterBuf->DataAddress =
+ BYTE_SWAP(Adapter->UniversalAddress);
+
+ //
+ // Set the command block for the read adapter command.
+ //
+ CommandBlock->Hardware.CommandCode = CMD_DMA_READ;
+
+ CommandBlock->Hardware.ParmPointer =
+ NdisGetPhysicalAddressLow(Adapter->AdapterBufPhysical);
+
+ break;
+
+ //
+ // For any of the current addresses (functional, group, network)
+ // we will want to read the current addresses as the adapter has
+ // them recorded.
+ //
+ case OID_802_5_CURRENT_ADDRESS:
+
+ //
+ // Get a command block
+ //
+ TOK162AcquireCommandBlock(Adapter, &CommandBlock);
+
+ //
+ // Notify that this is from a set
+ //
+ CommandBlock->Set = TRUE;
+
+ //
+ // Setup the common fields of the command block.
+ //
+ CommandBlock->NextCommand = NULL;
+ CommandBlock->Hardware.Status = 0;
+ CommandBlock->Hardware.NextPending = TOK162_NULL;
+
+ //
+ // Set up the adapter buffer to get the current addresses.
+ //
+ Adapter->AdapterBuf->DataCount = BYTE_SWAP(0x000e);
+
+ Adapter->AdapterBuf->DataAddress =
+ BYTE_SWAP(Adapter->AdapterAddresses);
+
+ //
+ // Set the command block for the read adapter command.
+ //
+ CommandBlock->Hardware.CommandCode = CMD_DMA_READ;
+
+ CommandBlock->Hardware.ParmPointer =
+ NdisGetPhysicalAddressLow(Adapter->AdapterBufPhysical);
+
+ break;
+
+ //
+ // For any other OID, we read the errorlog to help make sure we
+ // don't get a counter overflow and lose information.
+ //
+ default:
+
+ //
+ // Get a command block
+ //
+ TOK162AcquireCommandBlock(Adapter, &CommandBlock);
+
+ //
+ // Notify that this is from a set
+ //
+ CommandBlock->Set = TRUE;
+
+ //
+ // Setup the common fields of the command block.
+ //
+ CommandBlock->NextCommand = NULL;
+ CommandBlock->Hardware.Status = 0;
+ CommandBlock->Hardware.NextPending = TOK162_NULL;
+
+ //
+ // Set the command block for a read error log command.
+ //
+ CommandBlock->Hardware.CommandCode = CMD_DMA_READ_ERRLOG;
+
+ CommandBlock->Hardware.ParmPointer =
+ NdisGetPhysicalAddressLow(Adapter->ErrorLogPhysical);
+
+ break;
+ }
+
+ //
+ // If we need to process the command block...
+ //
+ if (NDIS_STATUS_PENDING == Status)
+ {
+ //
+ // Now that we're set up, let's do it!
+ //
+ Adapter->RequestInProgress = TRUE;
+
+ //
+ // Submit the command to the card
+ //
+ TOK162SubmitCommandBlock(Adapter, CommandBlock);
+ }
+
+ return(Status);
+}
+
+VOID
+TOK162FinishQueryInformation(
+ IN PTOK162_ADAPTER Adapter
+)
+
+/*++
+
+Routine Description:
+
+ The TOK162FinishQueryInformation finish processing a Query request for
+ NDIS_OIDs that are specific about the Driver.
+
+Arguments:
+
+ Adapter - a pointer to the adapter.
+
+Return Value:
+
+ The function value is the status of the operation.
+
+--*/
+
+{
+//
+// The list of Oid's that we support with this driver.
+//
+static
+NDIS_OID TOK162GlobalSupportedOids[] = {
+ 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_GEN_RCV_CRC_ERROR,
+ OID_GEN_TRANSMIT_QUEUE_LENGTH,
+ 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,
+ OID_802_5_LINE_ERRORS,
+ OID_802_5_LOST_FRAMES,
+ OID_802_5_BURST_ERRORS,
+ OID_802_5_FRAME_COPIED_ERRORS,
+ OID_802_5_TOKEN_ERRORS
+ };
+
+ //
+ // Variable to keep track of the bytes written out.
+ //
+ PUINT BytesWritten = Adapter->BytesWritten;
+
+ //
+ // Variable to keep track of the bytes needed
+ //
+ PUINT BytesNeeded = Adapter->BytesNeeded;
+
+ //
+ // The actual Oid that just finished.
+ //
+ NDIS_OID Oid = Adapter->Oid;
+
+ //
+ // Result buffer.
+ //
+ PVOID InformationBuffer = Adapter->InformationBuffer;
+
+ //
+ // Length of result buffer.
+ //
+ UINT InformationBufferLength = Adapter->InformationBufferLength;
+
+ //
+ // The medium supported by this driver.
+ //
+ NDIS_MEDIUM Medium = NdisMedium802_5;
+
+ //
+ // Generic repository for ULONG results
+ //
+ UINT GenericUlong;
+
+ //
+ // Generic repository for USHORT results
+ //
+ USHORT GenericUShort;
+
+ //
+ // Generic repository for character array results
+ //
+ UCHAR GenericArray[6];
+
+ //
+ // Pointer to source of result Common variables for pointing to result of query
+ //
+ PVOID MoveSource = (PVOID)(&GenericUlong);
+
+ //
+ // Number of bytes to be moved, defaulting to the size of a ULONG.
+ //
+ ULONG MoveBytes = sizeof(ULONG);
+
+ //
+ // Hardware Status
+ //
+ NDIS_HARDWARE_STATUS HardwareStatus;
+
+ //
+ // Return value of NDIS calls
+ //
+ NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
+
+ //
+ // Initialize bytes written and bytes needed
+ //
+ *BytesWritten = 0;
+ *BytesNeeded = 0;
+
+ //
+ // Switch on the Oid
+ //
+ switch(Oid){
+
+ //
+ // The MAC options represents the options our driver supports/needs.
+ //
+ case OID_GEN_MAC_OPTIONS:
+
+ //
+ // We don't pend transfers.
+ // we copy lookahead data, and we have serialized receives.
+ //
+ GenericUlong = (ULONG)(NDIS_MAC_OPTION_TRANSFERS_NOT_PEND |
+ NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA |
+ NDIS_MAC_OPTION_RECEIVE_SERIALIZED
+ );
+
+ break;
+
+ //
+ // We return the list of Oid's we support (list above)
+ //
+ case OID_GEN_SUPPORTED_LIST:
+
+ //
+ // Point to the beginning of the list.
+ //
+ MoveSource = (PVOID)(TOK162GlobalSupportedOids);
+
+ //
+ // We have to move the whole list.
+ //
+ MoveBytes = sizeof(TOK162GlobalSupportedOids);
+
+ break;
+
+ case OID_GEN_HARDWARE_STATUS:
+
+ //
+ // If we have a reset in progress, the hardware status is
+ // set to reset. Otherwise, we return that we are ready.
+ //
+ if (Adapter->ResetInProgress) {
+
+ HardwareStatus = NdisHardwareStatusReset;
+
+ } else {
+
+ HardwareStatus = NdisHardwareStatusReady;
+
+ }
+
+ //
+ // Set the pointer to the HardwareStatus variable
+ //
+ MoveSource = (PVOID)(&HardwareStatus);
+
+ //
+ // Move the size of hardware status bytes
+ //
+ MoveBytes = sizeof(NDIS_HARDWARE_STATUS);
+
+ break;
+
+ //
+ // Simply indicate that we support TokenRing.
+ //
+ case OID_GEN_MEDIA_SUPPORTED:
+ case OID_GEN_MEDIA_IN_USE:
+
+ MoveSource = (PVOID) (&Medium);
+ MoveBytes = sizeof(NDIS_MEDIUM);
+ break;
+
+ //
+ // The maximum lookahead, current lookahead, and frame size are
+ // static and are equal to the maximum frame size minus the header
+ // size.
+ //
+ case OID_GEN_MAXIMUM_LOOKAHEAD:
+ case OID_GEN_CURRENT_LOOKAHEAD:
+
+ GenericUlong = Adapter->ReceiveBufferSize - TOK162_HEADER_SIZE;
+ break;
+
+ case OID_GEN_MAXIMUM_FRAME_SIZE:
+
+ GenericUlong = Adapter->ReceiveBufferSize - 14;
+ break;
+
+ //
+ // Total sizes are easier because we don't have to subtract out the
+ // header size.
+ //
+ case OID_GEN_MAXIMUM_TOTAL_SIZE:
+ case OID_GEN_TRANSMIT_BLOCK_SIZE:
+ case OID_GEN_RECEIVE_BLOCK_SIZE:
+ GenericUlong = Adapter->ReceiveBufferSize;
+ break;
+
+
+ //
+ // Link speed is either 4MBPS or 16MBPS depending on which we're
+ // running on.
+ //
+ case OID_GEN_LINK_SPEED:
+
+ GenericUlong = (Adapter->Running16Mbps == TRUE) ? (ULONG)160000 :
+ (ULONG)40000;
+
+ break;
+
+
+ //
+ // Transmit buffer space is found by multiplying the size of the
+ // transmit buffers (same as receive buffer size) by the number
+ // of transmit lists.
+ //
+ case OID_GEN_TRANSMIT_BUFFER_SPACE:
+
+ GenericUlong = (ULONG)Adapter->ReceiveBufferSize *
+ Adapter->NumberOfTransmitLists;
+
+ break;
+
+ //
+ // Receive buffer space is equal to multiplying the size of receive
+ // buffers by the number of receive lists.
+ //
+ case OID_GEN_RECEIVE_BUFFER_SPACE:
+
+ GenericUlong = (ULONG)Adapter->ReceiveBufferSize *
+ RECEIVE_LIST_COUNT;
+
+ break;
+
+
+ //
+ // The vendor ID is calculated by ANDing the current network address
+ // with 0xFFFFFF00.
+ //
+ case OID_GEN_VENDOR_ID:
+
+ //
+ // Get the current network address.
+ //
+ GenericUlong = 0;
+ NdisMoveMemory(
+ (PVOID)&GenericUlong,
+ Adapter->CurrentAddress,
+ 3
+ );
+ GenericUlong &= 0xFFFFFF00;
+
+ MoveSource = (PVOID)(&GenericUlong);
+
+ MoveBytes = sizeof(GenericUlong);
+
+ break;
+
+ //
+ // Return our vendor string
+ //
+ case OID_GEN_VENDOR_DESCRIPTION:
+
+ MoveSource = (PVOID)"IBM TokenRing 16/4 II Adapter ";
+
+ MoveBytes = 30;
+
+ break;
+
+ //
+ // Return our version (3.10) number
+ //
+ case OID_GEN_DRIVER_VERSION:
+
+ GenericUShort = (USHORT)0x0300;
+
+ MoveSource = (PVOID)(&GenericUShort);
+
+ MoveBytes = sizeof(GenericUShort);
+
+ break;
+
+ //
+ // Return the permanent address
+ //
+ case OID_802_5_PERMANENT_ADDRESS:
+
+ TR_COPY_NETWORK_ADDRESS(
+ (PCHAR)GenericArray,
+ Adapter->NetworkAddress
+ );
+
+ MoveSource = (PVOID)(GenericArray);
+
+ MoveBytes = TR_LENGTH_OF_ADDRESS;
+
+ break;
+
+ //
+ // Return the current address.
+ //
+ case OID_802_5_CURRENT_ADDRESS:
+
+ TR_COPY_NETWORK_ADDRESS(
+ (PCHAR)GenericArray,
+ Adapter->CurrentAddress
+ );
+
+ MoveSource = (PVOID)(GenericArray);
+
+ MoveBytes = TR_LENGTH_OF_ADDRESS;
+
+ break;
+
+ //
+ // Return the current functional address.
+ //
+ case OID_802_5_CURRENT_FUNCTIONAL:
+
+ //
+ // Get the address stored in the adapter structure
+ //
+ GenericUlong = (ULONG)Adapter->FunctionalAddress;
+
+ //
+ // Now we need to reverse the crazy thing.
+ //
+ GenericUlong = BYTE_SWAP_ULONG(GenericUlong);
+
+ break;
+
+ //
+ // Return the current group address.
+ //
+ case OID_802_5_CURRENT_GROUP:
+
+ //
+ // Get the address stored in the adapter structure
+ //
+ GenericUlong = (ULONG)Adapter->GroupAddress;
+
+ //
+ // Now we need to reverse the crazy thing.
+ //
+ GenericUlong = BYTE_SWAP_ULONG(GenericUlong);
+
+ break;
+
+ //
+ // Return the number of good transmits
+ //
+ case OID_GEN_XMIT_OK:
+
+ GenericUlong = (ULONG) Adapter->GoodTransmits;
+
+ break;
+
+ //
+ // Return the number of good receives
+ //
+ case OID_GEN_RCV_OK:
+
+ GenericUlong = (ULONG) Adapter->GoodReceives;
+
+ break;
+
+ //
+ // Return the number of transmit errors
+ //
+ case OID_GEN_XMIT_ERROR:
+
+ GenericUlong = (ULONG) Adapter->BadTransmits;
+
+ break;
+
+ //
+ // Return the number of receive errors
+ //
+ case OID_GEN_RCV_ERROR:
+
+ GenericUlong = (ULONG) 0;
+
+ break;
+
+ //
+ // Return the number of congestion errors that have occurred
+ //
+ case OID_GEN_RCV_NO_BUFFER:
+
+ GenericUlong = (ULONG) Adapter->ReceiveCongestionError;
+
+ break;
+
+ //
+ // Return the number of CRC errors (receives)
+ //
+ case OID_GEN_RCV_CRC_ERROR:
+
+ GenericUlong = (ULONG) 0;
+
+ break;
+
+ //
+ // Return the current transmit queue length
+ //
+ case OID_GEN_TRANSMIT_QUEUE_LENGTH:
+
+ GenericUlong = (ULONG) Adapter->TransmitsQueued;
+
+ break;
+
+ //
+ // Return the number of Line errors
+ //
+ case OID_802_5_LINE_ERRORS:
+
+ GenericUlong = (ULONG) Adapter->LineError;
+
+ break;
+
+ //
+ // Return the last ring status.
+ //
+ case OID_802_5_CURRENT_RING_STATUS:
+
+ GenericUlong = (ULONG)Adapter->LastNotifyStatus;
+
+ break;
+
+ //
+ // Return the current ring state.
+ //
+ case OID_802_5_CURRENT_RING_STATE:
+
+ GenericUlong = (ULONG)Adapter->CurrentRingState;
+
+ break;
+
+ //
+ // Last open error code.
+ //
+ case OID_802_5_LAST_OPEN_STATUS:
+
+ GenericUlong = (ULONG)(NDIS_STATUS_TOKEN_RING_OPEN_ERROR |
+ (NDIS_STATUS)Adapter->OpenErrorCode);
+
+ break;
+
+ //
+ // Return the number of Lost Frames
+ //
+ case OID_802_5_LOST_FRAMES:
+
+ GenericUlong = (ULONG) Adapter->LostFrameError;
+
+ break;
+
+ //
+ // Return the number of Burst errors
+ //
+ case OID_802_5_BURST_ERRORS:
+
+ GenericUlong = (ULONG) Adapter->BurstError;
+
+ break;
+
+ //
+ // Return the number of Frame Copied Errors
+ //
+ case OID_802_5_FRAME_COPIED_ERRORS:
+
+ GenericUlong = (ULONG) Adapter->FrameCopiedError;
+
+ break;
+
+ //
+ // Return the number of Token errors
+ //
+ case OID_802_5_TOKEN_ERRORS:
+
+ GenericUlong = (ULONG) Adapter->TokenError;
+
+ break;
+ //
+ // Must be an unsupported Oid
+ //
+ default:
+
+ Status = NDIS_STATUS_INVALID_OID;
+
+ break;
+ }
+
+
+ //
+ // If there weren't any errors, copy the bytes indicated above.
+ //
+ if (Status == NDIS_STATUS_SUCCESS) {
+
+ //
+ // Make sure we don't have too much to move. If so, return an error.
+ //
+ if (MoveBytes > InformationBufferLength) {
+
+ //
+ // Not enough room in InformationBuffer. Punt
+ //
+
+ *BytesNeeded = MoveBytes;
+
+ Status = NDIS_STATUS_INVALID_LENGTH;
+
+ //
+ // Do the copy
+ //
+ } else {
+
+ *BytesWritten = MoveBytes;
+
+ if (MoveBytes > 0) {
+
+ NdisMoveMemory(
+ InformationBuffer,
+ MoveSource,
+ MoveBytes
+ );
+ }
+ }
+ }
+
+ //
+ // We're finished with the request.
+ //
+ Adapter->RequestInProgress = FALSE;
+
+ //
+ // Indicate the result to the protocol(s)
+ //
+ NdisMQueryInformationComplete(
+ Adapter->MiniportAdapterHandle,
+ Status
+ );
+
+ return;
+}
+
+
+NDIS_STATUS
+TOK162ChangeFuncGroup(
+ IN PTOK162_ADAPTER Adapter
+)
+/*++
+
+Routine Description:
+
+ The TOK162ChangeFuncGroup modifies the appropriate adapter
+ address (functional, group, or both). This routine submits two command
+ blocks representing one call to the system. Therefore, only the group
+ address change performs a status indication (the Set variable).
+
+Arguments:
+
+ Adapter - a pointer to the adapter.
+
+Return Value:
+
+ The function value is the status of the operation.
+
+--*/
+
+{
+ //
+ // Address to be set. Used for both functional and group addresses.
+ //
+ ULONG Address;
+
+ //
+ // Variable to hold the return value of NDIS calls
+ //
+ NDIS_STATUS Status;
+
+ //
+ // First check the functional address status, including the all
+ // functional address.
+ //
+ if ((Adapter->CurrentPacketFilter & NDIS_PACKET_TYPE_ALL_FUNCTIONAL) != 0) {
+
+ Address = 0x7FFFFFFF;
+
+ } else if ((Adapter->CurrentPacketFilter & NDIS_PACKET_TYPE_FUNCTIONAL) != 0) {
+
+ Address = Adapter->FunctionalAddress;
+
+ } else {
+
+ Address = 0;
+
+ }
+
+ //
+ // Change the functional address on the card.
+ //
+ Status = TOK162ChangeAddress(
+ Adapter,
+ Address,
+ OID_802_5_CURRENT_FUNCTIONAL,
+ CMD_DMA_SET_FUNC_ADDR,
+ FALSE
+ );
+
+ //
+ // Now check the group address status
+ //
+ if ((Adapter->CurrentPacketFilter & NDIS_PACKET_TYPE_GROUP) != 0) {
+
+ Address = Adapter->GroupAddress;
+
+ } else {
+
+ Address = 0;
+
+ }
+
+ //
+ // Change the group address on the card.
+ //
+ Status = TOK162ChangeAddress(
+ Adapter,
+ Address,
+ OID_802_5_CURRENT_GROUP,
+ CMD_DMA_SET_GRP_ADDR,
+ TRUE
+ );
+
+ return(Status);
+}
diff --git a/private/ntos/ndis/ibmtok2i/reset.c b/private/ntos/ndis/ibmtok2i/reset.c
new file mode 100644
index 000000000..ca967de06
--- /dev/null
+++ b/private/ntos/ndis/ibmtok2i/reset.c
@@ -0,0 +1,1918 @@
+/*++
+
+Copyright (c) 1992 Microsoft Corporation
+
+Module Name:
+
+ reset.c
+
+Abstract:
+
+ This is the file containing the reset code for the IBM Token Ring 16/4 II
+ ISA adapter. This driver conforms to the NDIS 3.0 Miniport interface.
+
+Author:
+
+ Kevin Martin (KevinMa) 1-Feb-1994
+
+Environment:
+
+ Kernel Mode - Or whatever is the equivalent on OS/2 and DOS.
+
+Revision History:
+
+--*/
+
+#include <tok162sw.h>
+
+#pragma NDIS_INIT_FUNCTION(TOK162InitialInit)
+
+//
+// Declarations for functions private to this file.
+//
+extern
+VOID
+TOK162ProcessRequestQueue(
+ IN PTOK162_ADAPTER Adapter,
+ IN BOOLEAN StatisticsUpdated
+ );
+
+VOID
+TOK162WriteInitializationBlock(
+ IN PTOK162_ADAPTER Adapter
+ );
+
+VOID
+TOK162SetInitializationBlock(
+ IN PTOK162_ADAPTER Adapter
+ );
+
+VOID
+TOK162SetInitializationBlockAndInit(
+ IN PTOK162_ADAPTER Adapter,
+ OUT PNDIS_STATUS Status
+ );
+
+NDIS_STATUS
+TOK162ChangeCurrentAddress(
+ IN PTOK162_ADAPTER Adapter
+ );
+
+VOID
+TOK162ResetCommandBlocks(
+ IN PTOK162_ADAPTER Adapter
+ );
+
+BOOLEAN
+CheckResetResults(
+ IN PTOK162_ADAPTER Adapter
+ );
+
+NDIS_STATUS
+CheckInitResults(
+ IN PTOK162_ADAPTER Adapter
+ );
+
+VOID
+TOK162GetAdapterOffsets(
+ IN PTOK162_ADAPTER Adapter
+ );
+VOID
+TOK162ResetReceiveQueue(
+ IN PTOK162_ADAPTER Adapter
+ );
+
+VOID
+TOK162AbortSend(
+ IN PTOK162_ADAPTER Adapter,
+ IN PTOK162_SUPER_COMMAND_BLOCK CurrentCommandBlock
+ );
+
+extern
+void
+TOK162SendCommandBlock(
+ IN PTOK162_ADAPTER Adapter,
+ IN PTOK162_SUPER_COMMAND_BLOCK CommandBlock
+ );
+
+
+
+
+BOOLEAN
+TOK162InitialInit(
+ IN PTOK162_ADAPTER Adapter
+ )
+
+/*++
+
+Routine Description:
+
+ This routine sets up the initial init of the driver.
+
+Arguments:
+
+ Adapter - The adapter structure for the hardware.
+
+Return Value:
+
+ TRUE if successful, FALSE if not.
+
+--*/
+
+{
+ //
+ // Holds status returned from NDIS calls.
+ //
+ NDIS_STATUS Status;
+
+ //
+ // First we make sure that the device is stopped.
+ //
+ TOK162DisableInterrupt(Adapter);
+
+ //
+ // Set flags indicating we are doing the initial init
+ //
+ Adapter->InitialInit = TRUE;
+ Adapter->ResetState = InitialInit;
+ Adapter->InitialOpenComplete = FALSE;
+ Adapter->InitialReceiveSent = FALSE;
+ Adapter->ResetInProgress = TRUE;
+
+ //
+ // Initialize the interrupt.
+ //
+ Status = NdisMRegisterInterrupt(
+ &Adapter->Interrupt,
+ Adapter->MiniportAdapterHandle,
+ Adapter->InterruptLevel,
+ Adapter->InterruptLevel,
+ FALSE,
+ FALSE,
+ NdisInterruptLatched
+ );
+
+ //
+ // Report the status of the interrupt registering to the debugger
+ //
+ VERY_LOUD_DEBUG(DbgPrint(
+ "IBMTOK2I!Status from Registering Interrupt -%u was %u\n",
+ Adapter->InterruptLevel,
+ Status);)
+
+ //
+ // If the interrupt register failed, mark the interrupt level at 0 so
+ // we know not to do a deregister.
+ //
+ if (Status != NDIS_STATUS_SUCCESS) {
+
+ Adapter->InterruptLevel = 0;
+ return FALSE;
+
+ }
+
+ //
+ // Initialize the open command to zeros
+ //
+ NdisZeroMemory(Adapter->Open,sizeof(OPEN_COMMAND));
+
+ //
+ // Set up the Open command block
+ //
+
+ //
+ // Set the options
+ //
+ Adapter->Open->Options = OPEN_OPTION_CONTENDER;
+
+ //
+ // Set the receive and transmit list sizes as well as the buffer size
+ //
+ Adapter->Open->ReceiveListSize = BYTE_SWAP(OPEN_RECEIVE_LIST_SIZE);
+ Adapter->Open->TransmitListSize = BYTE_SWAP(OPEN_TRANSMIT_LIST_SIZE);
+ Adapter->Open->BufferSize = BYTE_SWAP(OPEN_BUFFER_SIZE);
+
+ //
+ // Make sure the adapter can handle one entire frame
+ //
+ Adapter->Open->TransmitBufCountMin =
+ (Adapter->ReceiveBufferSize / OPEN_BUFFER_SIZE) + 1;
+
+ Adapter->Open->TransmitBufCountMax = Adapter->Open->TransmitBufCountMin;
+
+ //
+ // Reset the adapter
+ //
+ TOK162ResetAdapter(Adapter);
+
+ //
+ // Reenable interrupts
+ //
+ TOK162EnableInterrupt(Adapter);
+
+ //
+ // Go through the reset stages
+ //
+ VERY_LOUD_DEBUG(DbgPrint("IBMTOK2I!Calling TOK162ResetHandler\n");)
+
+ TOK162ResetHandler(NULL,Adapter,NULL,NULL);
+
+ VERY_LOUD_DEBUG(DbgPrint("IBMTOK2I!Back from TOK162ResetHandler\n");)
+
+ //
+ // The Initial init is done.
+ //
+ Adapter->InitialInit = FALSE;
+
+ //
+ // Check the reset status and return TRUE if successful, FALSE if not.
+ //
+ if (Adapter->ResetResult == NDIS_STATUS_SUCCESS) {
+
+ return TRUE;
+
+ } else {
+
+ return FALSE;
+
+ }
+
+}
+
+
+VOID
+TOK162EnableAdapter(
+ IN NDIS_HANDLE Context
+ )
+
+/*++
+
+Routine Description:
+
+ This routine is used to start an already initialized TOK162.
+
+Arguments:
+
+ Context - The adapter for the TOK162.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+ //
+ // Pointer to an adapter structure. Makes Context (passed in value)
+ // a structure we can deal with.
+ //
+ PTOK162_ADAPTER Adapter = (PTOK162_ADAPTER)Context;
+
+ //
+ // Enable the adapter
+ //
+ WRITE_ADAPTER_USHORT(Adapter,
+ PORT_OFFSET_ADAPTER_ENABLE,
+ 0x2525
+ );
+
+}
+
+
+VOID
+TOK162EnableInterrupt(
+ IN NDIS_HANDLE Context
+ )
+
+/*++
+
+Routine Description:
+
+ This routine is used to turn on the interrupt mask.
+
+Arguments:
+
+ Context - The adapter for the TOK162.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+ //
+ // Pointer to an adapter structure. Makes Context (passed in value)
+ // a structure we can deal with.
+ //
+ PTOK162_ADAPTER Adapter = (PTOK162_ADAPTER)Context;
+
+ //
+ // Enable further interrupts.
+ //
+ WRITE_ADAPTER_USHORT(Adapter,
+ PORT_OFFSET_SWITCH_INT_ENABLE,
+ 0x2525
+ );
+
+}
+
+VOID
+TOK162DisableInterrupt(
+ IN NDIS_HANDLE Context
+ )
+
+/*++
+
+Routine Description:
+
+ This routine is used to turn off the interrupt mask.
+
+Arguments:
+
+ Context - The adapter for the TOK162.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+ //
+ // Pointer to an adapter structure. Makes Context (passed in value)
+ // a structure we can deal with.
+ //
+ PTOK162_ADAPTER Adapter = (PTOK162_ADAPTER)Context;
+
+ //
+ // Disable the adapter interrupt.
+ //
+ WRITE_ADAPTER_USHORT(
+ Adapter,
+ PORT_OFFSET_SWITCH_INT_DISABLE,
+ 0x2525
+ );
+
+}
+
+VOID
+TOK162ResetAdapter(
+ IN PTOK162_ADAPTER Adapter
+ )
+
+/*++
+
+Routine Description:
+
+ This routine is used to reset the adapter.
+
+Arguments:
+
+ Adapter - The TOK162 adapter to reset.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+ //
+ // Mark the current ring state as closed (we are going to be removed
+ // from the ring by doing the reset).
+ //
+
+ Adapter->CurrentRingState = NdisRingStateClosed;
+
+ //
+ // This is very simple with this adapter. We simply issue a reset
+ // command right here and this will stop the chip.
+ //
+ WRITE_ADAPTER_USHORT(Adapter,
+ PORT_OFFSET_ADAPTER_RESET,
+ 0x2525
+ );
+
+ //
+ // Allow the adapter to finish completing the reset
+ //
+ NdisStallExecution(50);
+
+ //
+ // Enable the adapter to allow us to access the adapter's registers.
+ //
+ TOK162EnableAdapter(Adapter);
+
+ //
+ // Allow the adapter to finish completing the reset
+ //
+ NdisStallExecution(50);
+
+}
+
+VOID
+TOK162SetInitializationBlock(
+ IN PTOK162_ADAPTER Adapter
+ )
+
+/*++
+
+Routine Description:
+
+ This routine simply fills the Initialization block
+ with the information necessary for initialization.
+
+ NOTE: this routine assumes a single thread of execution is accessing
+ the particular adapter.
+
+Arguments:
+
+ Adapter - The adapter which holds the initialization block
+ to initialize.
+
+Return Value:
+
+ None.
+
+
+--*/
+
+{
+ //
+ // Pointer to the initialization block
+ //
+ PADAPTER_INITIALIZATION Initialization = Adapter->InitializationBlock;
+
+ //
+ // Initialize the init block to zeros
+ //
+ NdisZeroMemory(
+ Initialization,
+ sizeof(ADAPTER_INITIALIZATION)
+ );
+
+ //
+ // Set the initializtion options as follows:
+ // Reserved bit must be on
+ // DMA Burst mode (versus cyclical) for the SSB/SCB
+ // DMA Burst mode (versus cyclical) for the xmit/rcv lists
+ // DMA Burst mode (versus cyclical) for the xmit/rcv status
+ // DMA Burst mode (versus cyclical) for the receive buffers
+ // DMA Burst mode (versus cyclical) for the transmit buffers
+ // Don't allow Early Token Release
+ //
+ Initialization->Options = INIT_OPTIONS_RESERVED |
+ INIT_OPTIONS_SCBSSB_BURST |
+ INIT_OPTIONS_LIST_BURST |
+ INIT_OPTIONS_LIST_STATUS_BURST |
+ INIT_OPTIONS_RECEIVE_BURST |
+ INIT_OPTIONS_XMIT_BURST |
+ INIT_OPTIONS_DISABLE_ETR;
+
+ //
+ // If we are running at 16MBPS, OR in this fact.
+ //
+ if (Adapter->Running16Mbps == TRUE) {
+
+ Initialization->Options |= INIT_OPTIONS_SPEED_16;
+
+ }
+
+ //
+ // Set the receive and transmit burst sizes to the max.
+ //
+ Initialization->ReceiveBurstSize = TOK162_BURST_SIZE;
+ Initialization->TransmitBurstSize = TOK162_BURST_SIZE;
+
+ //
+ // Set the DMA retries (values found in TOK162HW.H)
+ //
+ Initialization->DMAAbortThresholds = TOK162_DMA_RETRIES;
+
+ //
+ // Set the pointers to the SCB and SSB blocks.
+ //
+ Initialization->SCBHigh = HIGH_WORD(
+ NdisGetPhysicalAddressLow(Adapter->ScbPhysical));
+
+ Initialization->SCBLow = LOW_WORD(
+ NdisGetPhysicalAddressLow(Adapter->ScbPhysical));
+
+ Initialization->SSBHigh = HIGH_WORD(
+ NdisGetPhysicalAddressLow(Adapter->SsbPhysical));
+
+ Initialization->SSBLow = LOW_WORD(
+ NdisGetPhysicalAddressLow(Adapter->SsbPhysical));
+}
+
+
+VOID
+TOK162SetInitializationBlockAndInit(
+ IN PTOK162_ADAPTER Adapter,
+ OUT PNDIS_STATUS Status
+ )
+
+/*++
+
+Routine Description:
+
+ It is this routine's responsibility to make sure that the
+ Initialization block is filled and the adapter is initialized
+ and started.
+
+Arguments:
+
+ Adapter - The adapter whose hardware is to be initialized.
+ Status - Result of the Init
+
+Return Value:
+
+ None.
+
+--*/
+{
+
+ //
+ // Simple iterative variable to keep track of the number of retries.
+ //
+ USHORT Retries;
+
+ //
+ // Check to make sure Reset went OK
+ //
+ if (Adapter->InitialInit == TRUE) {
+
+ Retries = 0;
+
+ while ((CheckResetResults(Adapter) == FALSE) && (Retries++ < 3)) {
+
+ TOK162ResetAdapter(Adapter);
+
+ }
+
+ if (Retries == 3) {
+
+ *Status = NDIS_STATUS_DEVICE_FAILED;
+
+ return;
+
+ }
+
+ }
+
+ //
+ // Reset the receive queue, the command block queue, and the transmit
+ // queue.
+ //
+ TOK162ResetReceiveQueue(Adapter);
+ TOK162ResetCommandBlocks(Adapter);
+ TOK162ResetVariables(Adapter);
+
+ //
+ // Fill in the adapter's initialization block.
+ //
+ VERY_LOUD_DEBUG(DbgPrint("TOK162!Setting init block\n");)
+
+ TOK162SetInitializationBlock(Adapter);
+
+ //
+ // Write the initialization sequence to the adapter
+ //
+ VERY_LOUD_DEBUG(DbgPrint("TOK162!Writing Init block to adapter\n");)
+
+ TOK162WriteInitializationBlock(Adapter);
+
+ //
+ // Check the results
+ //
+ if (Adapter->InitialInit == TRUE) {
+
+ VERY_LOUD_DEBUG(DbgPrint("TOK162!Checking init results\n");)
+
+ *Status = CheckInitResults(Adapter);
+
+ }
+
+ return;
+
+}
+
+
+VOID
+TOK162ResetHandler(
+ IN PVOID SystemSpecific1,
+ IN PTOK162_ADAPTER Adapter,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3
+ )
+
+/*++
+
+Routine Description:
+
+ Continue the reset given the current reset state (Adapter->ResetState).
+
+Arguments:
+ SystemSpecific1 - Not used.
+ Adapter - The adapter whose hardware is being reset.
+ SystemSpecific2 - Not used.
+ SystemSpecific3 - Not used.
+
+Return Value:
+
+ None.
+
+--*/
+{
+ //
+ // Holds the return value from NDIS calls.
+ //
+ NDIS_STATUS Status;
+
+ //
+ // Variable for the number of retries.
+ //
+ USHORT Retries;
+
+ //
+ // Holds the result of the receive command.
+ //
+ BOOLEAN ReceiveResult;
+
+ //
+ // Initialize retries to 0.
+ //
+ Retries = 0;
+
+ //
+ // Cancel the reset timer
+ //
+ NdisMCancelTimer(&(Adapter->ResetTimer),&ReceiveResult);
+
+ //
+ // Based on the current Adapter->ResetState, proceed with the reset.
+ //
+ switch(Adapter->ResetState) {
+
+ //
+ // The initialinit case means we are at the beginning and do not
+ // run off of interrupts. Everything is polled and we continue until
+ // we are finished with the reset, successful or not.
+ //
+ case InitialInit:
+
+ //
+ // For up to 3 times, try to init the chipset.
+ //
+ do {
+
+ TOK162SetInitializationBlockAndInit(Adapter,&Status);
+ Retries++;
+
+ } while ((Status != NDIS_STATUS_SUCCESS) && (Retries < 3));
+
+ //
+ // If everything went ok, get the adapter information offsets
+ // and do the open/receive combo.
+ //
+
+ if (Status == NDIS_STATUS_SUCCESS) {
+
+ TOK162GetAdapterOffsets(Adapter);
+
+ //
+ // Do the open and if successful wait for the receive to
+ // complete (Status is already set to successful). If
+ // there was a problem, though, we need to set the error
+ // code.
+ //
+ if (DoTheOpen(Adapter) != TRUE) {
+
+ Status = NDIS_STATUS_FAILURE;
+
+ } else {
+
+ while (Adapter->InitialReceiveSent == FALSE) {
+
+ NdisStallExecution(500);
+
+ }
+
+ }
+
+ }
+
+ //
+ // Do the reset indications
+ //
+ TOK162DoResetIndications(Adapter,Status);
+
+ break;
+
+ //
+ // CheckReset is the first stage of a non-init reset. Because of
+ // the retry mechanism, CheckReset and CheckResetRetry have the same
+ // entry point logically with the exception of the resetting of the
+ // retry variable.
+ //
+
+ case CheckReset:
+
+ Adapter->ResetRetries = 0;
+
+ case CheckResetRetry:
+
+ //
+ // Increment the retry count
+ //
+ Adapter->ResetRetries++;
+
+ //
+ // See if we have gone too long.
+ // If we have gone for 5 seconds without the reset
+ // going true, reset the adapter again. Ten seconds is
+ // the breaking point to actually return an error condition.
+ //
+ if (Adapter->ResetRetries == 200) {
+
+ TOK162ResetAdapter(Adapter);
+
+ NdisMSetTimer(&(Adapter->ResetTimer),
+ 100
+ );
+
+ return;
+
+ } else if (Adapter->ResetRetries > 400) {
+
+ //
+ // Do the reset indications.
+ //
+ TOK162DoResetIndications(Adapter,NDIS_STATUS_FAILURE);
+ return;
+
+ }
+
+ //
+ // Check the result of the reset command. If it fails,
+ // set the state to CheckResetRetry.
+ //
+ if (CheckResetResults(Adapter) == FALSE) {
+
+ Adapter->ResetState = CheckResetRetry;
+
+ //
+ // If success, move to the next state (DoTheInit)
+ //
+ } else {
+
+ //
+ // We haven't had any retries of the init yet.
+ //
+ Adapter->InitRetries = 0;
+
+ VERY_LOUD_DEBUG(DbgPrint(
+ "TOK162!Moving to the init stage - %u\n",Adapter->ResetRetries);)
+
+ Adapter->ResetState = DoTheInit;
+
+ }
+
+ //
+ // Set the timer for the reset and leave this timer routine.
+ //
+ NdisMSetTimer(&(Adapter->ResetTimer),
+ 50
+ );
+
+ return;
+ break;
+
+ //
+ // DoTheInit sends the initialization block out to the card, and
+ // sets the next state to CheckInit.
+ //
+ case DoTheInit:
+
+ Adapter->ResetState = CheckInit;
+
+ //
+ // Send the init block out to the adapter
+ //
+ TOK162SetInitializationBlockAndInit(Adapter,
+ &Adapter->ResetResult);
+
+ //
+ // Set the timer for the reset and leave this timer routine.
+ //
+ NdisMSetTimer(&(Adapter->ResetTimer),
+ 200
+ );
+
+ return;
+ break;
+
+ //
+ // The CheckInit stage looks at the init results. If successful,
+ // the open command is issued and the regular interrupt handler
+ // will take care of the rest. If unsuccessful, the retry count
+ // is incremented and we wait until either the init results return
+ // successful or the retry count expires.
+ //
+ case CheckInit:
+
+ //
+ // Increment the retry count
+ //
+ Adapter->InitRetries++;
+
+ //
+ // If we have expired the retry count, do the indications
+ //
+ if (Adapter->InitRetries > 400) {
+
+ VERY_LOUD_DEBUG(DbgPrint("TOK162!Initialization failed\n");)
+ TOK162DoResetIndications(Adapter,NDIS_STATUS_FAILURE);
+ return;
+
+ }
+
+ //
+ // Check the result of the init.
+ //
+ Adapter->ResetResult = CheckInitResults(Adapter);
+
+ //
+ // If we were successful, issue the open command.
+ //
+ if (Adapter->ResetResult == NDIS_STATUS_SUCCESS) {
+
+ VERY_LOUD_DEBUG(DbgPrint("TOK162!Calling do the open\n");)
+ DoTheOpen(Adapter);
+
+ return;
+
+ //
+ // If not successful, start the timer and end this timer routine.
+ //
+ } else {
+
+ NdisMSetTimer(&(Adapter->ResetTimer),
+ 50
+ );
+
+ }
+
+ return;
+ break;
+ }
+
+}
+
+VOID
+TOK162DoResetIndications(
+ IN PTOK162_ADAPTER Adapter,
+ IN NDIS_STATUS Status
+ )
+
+/*++
+
+Routine Description:
+
+ This routine is called by TOK162ResetDpc to perform any
+ indications which need to be done after a reset. Note that
+ this routine will be called after either a successful reset
+ or a failed reset.
+
+Arguments:
+
+ Adapter - The adapter whose hardware has been initialized.
+
+ Status - The status of the reset to send to the protocol(s).
+
+Return Value:
+
+ None.
+
+--*/
+{
+
+ //
+ // Although it should never happen, if we get called when there
+ // isn't a reset in progress, just return.
+ //
+ if (Adapter->ResetInProgress == FALSE) {
+
+ return;
+
+ }
+
+ //
+ // If we have a bad result, we stop the chip and do the indication
+ // back to the protocol(s).
+ //
+ if (Status != NDIS_STATUS_SUCCESS) {
+
+ LOUD_DEBUG(DbgPrint("TOK162!Reset failed\n");)
+
+ //
+ // Stop the chip
+ //
+ TOK162ResetAdapter(Adapter);
+
+ //
+ // Reset has failed, errorlog an entry.
+ //
+ NdisWriteErrorLogEntry(
+ Adapter->MiniportAdapterHandle,
+ NDIS_ERROR_CODE_HARDWARE_FAILURE,
+ 0
+ );
+
+ }
+
+ //
+ // We are no longer resetting the adapter.
+ //
+ Adapter->ResetInProgress = FALSE;
+
+ //
+ // If this is during the initial init, just set the adapter variable.
+ //
+ if (Adapter->InitialInit == TRUE) {
+
+ Adapter->ResetResult = Status;
+
+ //
+ // Otherwise, send the status back to the protocol(s).
+ //
+ } else {
+
+ NdisMResetComplete(
+ Adapter->MiniportAdapterHandle,
+ Status,
+ TRUE
+ );
+
+ }
+
+
+}
+
+extern
+NDIS_STATUS
+TOK162SetupForReset(
+ IN PTOK162_ADAPTER Adapter
+ )
+
+/*++
+
+Routine Description:
+
+ This routine is used to write the resetting interrupt to the
+ token ring card, and then set up a timer to do the initialization
+ sequence under DPC.
+
+Arguments:
+
+ Adapter - The adapter whose hardware is to be initialized.
+
+Return Value:
+
+ Status of the reset process (always PENDING).
+
+--*/
+{
+ //
+ // The reset is now in progres.
+ //
+ Adapter->ResetInProgress = TRUE;
+
+ //
+ // Shut down the chip. We won't be doing any more work until
+ // the reset is complete.
+ //
+ TOK162ResetAdapter(Adapter);
+
+ //
+ // Set the timer for the dpc routine. The wait is for 100 milliseconds.
+ //
+ NdisMSetTimer(&(Adapter->ResetTimer),
+ 500
+ );
+
+
+ //
+ // Indicate the reset is pending
+ //
+ return NDIS_STATUS_PENDING;
+}
+
+
+VOID
+TOK162ResetVariables(
+ IN PTOK162_ADAPTER Adapter
+ )
+
+/*++
+
+Routine Description:
+
+ This routine sets variables to their proper value after a reset.
+
+Arguments:
+
+ Adapter - Adapter we are resetting.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+ //
+ // Reset the command queue and block variables
+ //
+ Adapter->CommandOnCard = NULL;
+ Adapter->WaitingCommandHead = NULL;
+ Adapter->WaitingCommandTail = NULL;
+ Adapter->NumberOfAvailableCommandBlocks = TOK162_NUMBER_OF_CMD_BLOCKS;
+ Adapter->NextCommandBlock = 0;
+
+ //
+ // Reset the transmit queue and block variables
+ //
+ Adapter->TransmitOnCard = NULL;
+ Adapter->WaitingTransmitHead = NULL;
+ Adapter->WaitingTransmitTail = NULL;
+ Adapter->NumberOfAvailableTransmitBlocks =
+ Adapter->NumberOfTransmitLists;
+ Adapter->NextTransmitBlock = 0;
+ Adapter->TransmitsQueued = 0;
+}
+
+
+VOID
+TOK162ResetCommandBlocks(
+ IN PTOK162_ADAPTER Adapter
+ )
+
+/*++
+
+Routine Description:
+
+ This routine sets command block elements to their proper value after
+ a reset.
+
+Arguments:
+
+ Adapter - Adapter we are resetting.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+ //
+ // Pointer to a Command Block. Used while initializing
+ // the Command Queue.
+ //
+ PTOK162_SUPER_COMMAND_BLOCK CurrentCommandBlock;
+
+ //
+ // Simple iteration variable.
+ //
+ UINT i;
+
+ //
+ // Abort all pending transmits
+ //
+ CurrentCommandBlock = Adapter->TransmitOnCard;
+
+ while (CurrentCommandBlock != NULL) {
+
+ TOK162AbortSend(Adapter,CurrentCommandBlock);
+ CurrentCommandBlock = CurrentCommandBlock->NextCommand;
+
+ }
+
+ //
+ // Put the Transmit Blocks into a known state.
+ //
+ for (i = 0, CurrentCommandBlock = Adapter->TransmitQueue;
+ i < Adapter->NumberOfTransmitLists;
+ i++, CurrentCommandBlock++
+ ) {
+
+ CurrentCommandBlock->Hardware.State = TOK162_STATE_FREE;
+ CurrentCommandBlock->NextCommand = NULL;
+ CurrentCommandBlock->CommandBlock = FALSE;
+ CurrentCommandBlock->CommandBlockIndex = (USHORT)i;
+ CurrentCommandBlock->Timeout = FALSE;
+ }
+
+ //
+ // Now do the same for the command queue.
+ //
+ for (i = 0, CurrentCommandBlock = Adapter->CommandQueue;
+ i < TOK162_NUMBER_OF_CMD_BLOCKS;
+ i++, CurrentCommandBlock++
+ ) {
+
+ CurrentCommandBlock->Hardware.State = TOK162_STATE_FREE;
+ CurrentCommandBlock->NextCommand = NULL;
+ CurrentCommandBlock->CommandBlock = TRUE;
+ CurrentCommandBlock->CommandBlockIndex = (USHORT)i;
+ CurrentCommandBlock->Timeout = FALSE;
+ }
+}
+
+
+
+BOOLEAN
+CheckResetResults(PTOK162_ADAPTER Adapter
+ )
+
+/*++
+
+Routine Description:
+
+ This routine checks the current state of the reset command and returns
+ whether the reset was successful.
+
+Arguments:
+
+ Adapter - Adapter we are resetting.
+
+Return Value:
+
+ TRUE if reset is successful, FALSE if not.
+
+--*/
+{
+ //
+ // Count of the total delay waiting for the chip to give results
+ //
+ UINT TotalDelay;
+
+ //
+ // Indicating if we can break out of a loop by having definitive results.
+ //
+ BOOLEAN Complete;
+
+ //
+ // Variable holding value of the status.
+ //
+ USHORT Value;
+
+ //
+ // Return value, TRUE or FALSE.
+ //
+ BOOLEAN Success;
+
+ //
+ // Initialize the variables.
+ //
+ Complete = FALSE;
+ TotalDelay = 0;
+ Success = FALSE;
+
+ //
+ // If we are running in a DPC, we don't want to check more than once
+ //
+ if (Adapter->InitialInit == FALSE) {
+
+ Complete = TRUE;
+
+ }
+
+ //
+ // Loop until Complete is TRUE.
+ //
+ do {
+
+ //
+ // First get the status
+ //
+ READ_ADAPTER_USHORT(Adapter,
+ PORT_OFFSET_STATUS,
+ &Value
+ );
+
+
+ //
+ // Check for Initialize
+ //
+ if ((Value & STATUS_INIT_INITIALIZE) != 0) {
+
+ //
+ // Mask off the Test and Error Bits
+ //
+ Value = Value & 0x00FF;
+ Value = Value & ~STATUS_INIT_INITIALIZE;
+
+
+ //
+ // Check test and error to see if they are zero. If so,
+ // we are done and successful.
+ //
+ if ((Value & (STATUS_INIT_TEST | STATUS_INIT_ERROR)) == 0) {
+
+ Complete = TRUE;
+ Success = TRUE;
+ VERY_LOUD_DEBUG(DbgPrint("TOK162!Returning True\n");)
+
+ }
+
+ //
+ // If init isn't set but test and error are, we are done but
+ // have failed.
+ //
+ } else if ((Value & (STATUS_INIT_TEST | STATUS_INIT_ERROR)) ==
+ (STATUS_INIT_TEST | STATUS_INIT_ERROR)) {
+
+ Complete = TRUE;
+ Success = FALSE;
+
+ }
+
+ //
+ // If we aren't done yet, then we need to sleep for a while and
+ // try again.
+ //
+ if (Complete == FALSE) {
+
+ NdisStallExecution(500000);
+ TotalDelay += 500000;
+
+ }
+
+ //
+ // If we have gone past the total time allowed or we have completed,
+ // then we end. Otherwise we loop again.
+ //
+ } while ((TotalDelay < 5000000) && (Complete == FALSE));
+
+ //
+ // Return success/failure.
+ //
+ return(Success);
+}
+
+
+
+NDIS_STATUS
+CheckInitResults(PTOK162_ADAPTER Adapter
+ )
+
+/*++
+
+Routine Description:
+
+ This routine checks the current state of the init command and returns
+ whether the init was successful.
+
+Arguments:
+
+ Adapter - Adapter we are resetting.
+
+Return Value:
+
+ TRUE if init is successful, FALSE if not.
+
+--*/
+{
+
+ //
+ // Count of the total delay waiting for the chip to give results
+ //
+ UINT TotalDelay;
+
+ //
+ // Indicating if we can break out of a loop by having definitive results.
+ //
+ BOOLEAN Complete;
+
+ //
+ // Variable holding value of the status.
+ //
+ USHORT Value;
+
+ //
+ // Return value, TRUE or FALSE.
+ //
+ BOOLEAN Success;
+
+ //
+ // Initialize the variables.
+ //
+ Complete = FALSE;
+ TotalDelay = 0;
+ Success = FALSE;
+
+ //
+ // If we are running in a DPC, we don't want to check more than once
+ //
+ if (Adapter->InitialInit == FALSE) {
+
+ Complete = TRUE;
+
+ }
+
+ //
+ // Loop until Complete == TRUE
+ //
+ do {
+
+ //
+ // First get the status
+ //
+ READ_ADAPTER_USHORT(Adapter,
+ PORT_OFFSET_STATUS,
+ &Value
+ );
+
+ //
+ // Check for Initialize, Test, and Error to be correct
+ //
+ if ((Value & (STATUS_INIT_INITIALIZE | STATUS_INIT_TEST)) == 0) {
+
+ //
+ // Check Error Bit
+ //
+ Complete = TRUE;
+
+ if ((Value & STATUS_INIT_ERROR) != 0) {
+
+ Success = FALSE;
+
+ } else {
+
+ Success = TRUE;
+
+ }
+ }
+
+ //
+ // If we aren't finished (Complete), Stall and try again.
+ //
+ if (Complete == FALSE) {
+
+ NdisStallExecution(100000);
+ TotalDelay += 100000;
+
+ }
+
+ } while ((TotalDelay < 10000000) && (Complete == FALSE));
+
+ //
+ // Display the values of the SCB and SSB to the debugger. After init
+ // the SCB should be 0000E2C18BD4 and the SSB should be FFFFD7D1D9C5D4C3.
+ //
+ LOUD_DEBUG(DbgPrint("TOK162!SCB Value after init = %04x%04x%04x\n",
+ Adapter->Scb->Command,
+ Adapter->Scb->Parm1,
+ Adapter->Scb->Parm2);)
+
+ //
+ // If we are successful, return STATUS_SUCCESS
+ //
+ if (Success == TRUE) {
+
+ VERY_LOUD_DEBUG(DbgPrint("TOK162!Returning Success\n");)
+ return(NDIS_STATUS_SUCCESS);
+
+ } else {
+
+ VERY_LOUD_DEBUG(DbgPrint("TOK162!Returning Failure\n");)
+ return(NDIS_STATUS_FAILURE);
+
+ }
+}
+
+
+BOOLEAN
+DoTheOpen(
+ PTOK162_ADAPTER Adapter
+ )
+/*++
+
+Routine Description:
+
+ This routine acquires and submits the open command. If called during the
+ initial init, the result of the open command is polled.
+
+Arguments:
+
+ Adapter - Adapter we are opening.
+
+Return Value:
+
+ TRUE if open is successful, FALSE if not.
+
+--*/
+{
+ //
+ // Result of open for polling (initialinit) mode
+ //
+ USHORT Result;
+
+ //
+ // Command block used for the open.
+ //
+ PTOK162_SUPER_COMMAND_BLOCK Command;
+
+ //
+ // Log DoTheOpen entered
+ //
+ IF_LOG('g');
+
+ //
+ // Change the ring state
+ //
+ Adapter->CurrentRingState = NdisRingStateOpening;
+
+ //
+ // Initialize the group and functional addresses. These will be set
+ // after the reset has finished.
+ //
+ Adapter->Open->GroupAddress = 0;
+ Adapter->Open->FunctionalAddress = 0;
+
+ //
+ // Set the address the adapter should enter the ring with.
+ //
+ NdisMoveMemory(
+ Adapter->Open->NodeAddress,
+ Adapter->CurrentAddress,
+ TOK162_LENGTH_OF_ADDRESS
+ );
+
+ //
+ // Acquire a command block
+ //
+ TOK162AcquireCommandBlock(Adapter,
+ &Command
+ );
+
+ //
+ // Set up the command block for the open
+ //
+ Command->Hardware.CommandCode = CMD_DMA_OPEN;
+ Command->Hardware.ParmPointer =
+ NdisGetPhysicalAddressLow(Adapter->OpenPhysical);
+
+ //
+ // Issue the command to the controller
+ //
+ TOK162SubmitCommandBlock(Adapter,
+ Command
+ );
+
+ //
+ // During initialinit we have to poll for completion of the open. This
+ // is because there is no way to pend the initial init.
+ //
+ if (Adapter->InitialInit == TRUE) {
+
+ //
+ // Poll until the SSB contains an open.
+ //
+ while (Adapter->InitialOpenComplete == FALSE) {
+
+ NdisStallExecution(5000);
+
+ }
+
+ //
+ // Get the result of the open.
+ //
+ Result = Adapter->SsbStatus1 & OPEN_COMPLETION_MASK_RESULT;
+
+ //
+ // Return the command block
+ //
+ TOK162RelinquishCommandBlock(Adapter,
+ Command
+ );
+
+ //
+ // Figure out the error code
+ //
+ if (Result == OPEN_RESULT_ADAPTER_OPEN) {
+
+ //
+ // Log open successful
+ //
+ IF_LOG('h');
+
+ //
+ // Set the current ring state
+ //
+ Adapter->CurrentRingState = NdisRingStateOpened;
+
+ //
+ // Return TRUE
+ //
+ return(TRUE);
+
+ } else {
+
+ //
+ // Log open unsuccessful
+ //
+ IF_LOG('H');
+
+ //
+ // Set the current ring state
+ //
+ Adapter->CurrentRingState = NdisRingStateOpenFailure;
+
+ //
+ // Return FALSE
+ //
+ return(FALSE);
+
+ }
+
+ }
+
+ //
+ // Log DoTheOpen exited.
+ //
+ IF_LOG('G');
+
+ return(TRUE);
+
+}
+
+
+BOOLEAN
+DoTheReceive(
+ PTOK162_ADAPTER Adapter
+ )
+/*++
+
+Routine Description:
+
+ This routine submits the receive command to the current adapter.
+
+Arguments:
+
+ Adapter - Adapter we are submitting the receive.
+
+Return Value:
+
+ TRUE
+
+--*/
+{
+ //
+ // Command block used for the open.
+ //
+ PTOK162_SUPER_COMMAND_BLOCK Command;
+
+ //
+ // Dismiss the interrupt, allowing the SSB to be updated.
+ //
+ WRITE_ADAPTER_USHORT(Adapter,
+ PORT_OFFSET_STATUS,
+ ENABLE_SSB_UPDATE
+ );
+
+ //
+ // Acquire a command block
+ //
+ TOK162AcquireCommandBlock(Adapter,
+ &Command
+ );
+
+ //
+ // Set up the command block for the receive
+ //
+ Command->Hardware.CommandCode = CMD_DMA_RCV;
+
+ Command->Hardware.ParmPointer =
+ NdisGetPhysicalAddressLow(Adapter->ReceiveQueuePhysical);
+
+ //
+ // Issue the command to the controller
+ //
+ TOK162SubmitCommandBlock(Adapter,
+ Command
+ );
+
+ //
+ // Return the command block
+ //
+ TOK162RelinquishCommandBlock(Adapter,
+ Command
+ );
+
+ VERY_LOUD_DEBUG(DbgPrint("TOK162!Returning from DoTheReceive\n");)
+
+ return(TRUE);
+
+}
+
+
+VOID
+TOK162WriteInitializationBlock(
+ PTOK162_ADAPTER Adapter
+ )
+/*++
+
+Routine Description:
+
+ This routine writes the initialization block to the adapter
+
+Arguments:
+
+ Adapter - Adapter we are initializing
+
+Return Value:
+
+ None
+
+--*/
+{
+ //
+ // Simple index variable.
+ //
+ USHORT i;
+
+ //
+ // Pointer to the current value in the initialization block
+ //
+ PUSHORT val;
+
+ //
+ // Set the address of the adapter to 0x0200.
+ //
+ WRITE_ADAPTER_USHORT(Adapter,PORT_OFFSET_ADDRESS,0x0200);
+
+ //
+ // Write out the initialization bytes
+ //
+ val = (PUSHORT)Adapter->InitializationBlock;
+
+ for (i = 0;
+ i < (sizeof(ADAPTER_INITIALIZATION)/2);
+ i++,val++) {
+
+ WRITE_ADAPTER_USHORT(Adapter,
+ PORT_OFFSET_DATA_AUTO_INC,
+ *val
+ );
+
+ NdisStallExecution(10);
+
+ }
+
+ //
+ // Issue the command to the adapter
+ //
+ WRITE_ADAPTER_USHORT(Adapter,
+ PORT_OFFSET_COMMAND,
+ EXECUTE_SCB_COMMAND
+ );
+
+}
+
+
+VOID
+TOK162GetAdapterOffsets(
+ IN PTOK162_ADAPTER Adapter
+ )
+/*++
+
+Routine Description:
+
+ This routine gets the offsets into adapter memory of adapter
+ parameter lists.
+
+Arguments:
+
+ Adapter - Adapter we are obtaining info from
+
+Return Value:
+
+ None
+
+--*/
+{
+ //
+ // Get the pointers for READ.ADAPTER
+ //
+
+ WRITE_ADAPTER_USHORT(Adapter,
+ PORT_OFFSET_ADDRESS,
+ 0x0A00
+ );
+
+ //
+ // Get the universal address offset
+ //
+ READ_ADAPTER_USHORT(Adapter,
+ PORT_OFFSET_DATA_AUTO_INC,
+ &Adapter->UniversalAddress
+ );
+
+ VERY_LOUD_DEBUG(DbgPrint("TOK162!Universal address offset is %x\n",
+ Adapter->UniversalAddress);)
+
+ //
+ // Get the microcode level offset
+ //
+ READ_ADAPTER_USHORT(Adapter,
+ PORT_OFFSET_DATA_AUTO_INC,
+ &Adapter->MicrocodeLevel
+ );
+
+ //
+ // Get the current addresses (network, functional, group) offset
+ //
+ READ_ADAPTER_USHORT(Adapter,
+ PORT_OFFSET_DATA_AUTO_INC,
+ &Adapter->AdapterAddresses
+ );
+
+ VERY_LOUD_DEBUG(DbgPrint("TOK162!Adapter addresses offset is %x\n",
+ Adapter->AdapterAddresses);)
+
+ //
+ // Get the adapter parameters offset
+ //
+ READ_ADAPTER_USHORT(Adapter,
+ PORT_OFFSET_DATA_AUTO_INC,
+ &Adapter->AdapterParms
+ );
+
+
+ //
+ // Get the adapter Mac Buffer offset
+ //
+ READ_ADAPTER_USHORT(Adapter,
+ PORT_OFFSET_DATA_AUTO_INC,
+ &Adapter->MacBuffer
+ );
+
+}
+
+
+VOID
+TOK162ResetReceiveQueue(
+ IN PTOK162_ADAPTER Adapter
+ )
+/*++
+
+Routine Description:
+
+ This routine resets the receive queue structures to their initialized
+ state. Most fields don't change and don't need to be updated, otherwise
+ the initreceivequeue function would be called.
+
+Arguments:
+
+ Adapter - Adapter whose receive queue is being reset
+
+Return Value:
+
+ None.
+
+--*/
+{
+ //
+ // Simple iterative variable.
+ //
+ USHORT i;
+
+ //
+ // Pointer to the current receive entry.
+ //
+ PTOK162_SUPER_RECEIVE_LIST CurrentReceiveEntry;
+
+ //
+ // Set pointer to current receive list to queue head
+ //
+ Adapter->ReceiveQueueCurrent = Adapter->ReceiveQueue;
+
+ //
+ // For each receive list, reset the cstat and flush buffers
+ //
+ for (i = 0, CurrentReceiveEntry = Adapter->ReceiveQueue;
+ i < Adapter->NumberOfReceiveBuffers;
+ i++, CurrentReceiveEntry++
+ ) {
+
+ //
+ // Flush the flush buffers
+ //
+ NdisFlushBuffer(CurrentReceiveEntry->FlushBuffer, FALSE);
+
+ //
+ // Reset the CSTAT to allow this receive buffer to be re-used.
+ //
+ CurrentReceiveEntry->Hardware.CSTAT = RECEIVE_CSTAT_REQUEST_RESET;
+
+ }
+
+}
+
+
+VOID
+TOK162AbortSend(
+ IN PTOK162_ADAPTER Adapter,
+ OUT PTOK162_SUPER_COMMAND_BLOCK CurrentCommandBlock
+ )
+/*++
+
+Routine Description:
+
+ This routine aborts the transmit block that was passed in.
+
+Arguments:
+
+ Adapter - Adapter whose receive queue is being reset
+ CurrentCommandBlock - Transmit to be aborted.
+
+Return Value:
+
+ None.
+
+--*/
+{
+ //
+ // Pointer to the packet that started this transmission.
+ //
+ PNDIS_PACKET OwningPacket = CurrentCommandBlock->OwningPacket;
+
+ //
+ // If we used map registers we need to do the completion on them.
+ //
+ if (CurrentCommandBlock->UsedTOK162Buffer == FALSE) {
+
+ //
+ // Pointer to the current buffer we are looking at.
+ //
+ PNDIS_BUFFER CurrentBuffer;
+
+ //
+ // Map register to complete
+ //
+ UINT CurMapRegister;
+
+ //
+ // The transmit is being aborted, so we can release
+ // the physical mapping used for it.
+ //
+
+ NdisQueryPacket(
+ OwningPacket,
+ NULL,
+ NULL,
+ &CurrentBuffer,
+ NULL
+ );
+
+ //
+ // Get the starting map register for this buffer.
+ //
+ CurMapRegister = CurrentCommandBlock->CommandBlockIndex *
+ Adapter->TransmitThreshold;
+
+ //
+ // Loop until there aren't any more buffers.
+ //
+ while (CurrentBuffer) {
+
+ //
+ // Release the current map register.
+ //
+ NdisMCompleteBufferPhysicalMapping(
+ Adapter->MiniportAdapterHandle,
+ CurrentBuffer,
+ CurMapRegister
+ );
+
+ //
+ // Move to the next map register.
+ //
+ ++CurMapRegister;
+
+ //
+ // Move to the next buffer
+ //
+ NdisGetNextBuffer(
+ CurrentBuffer,
+ &CurrentBuffer
+ );
+
+ }
+
+ }
+}
diff --git a/private/ntos/ndis/ibmtok2i/send.c b/private/ntos/ndis/ibmtok2i/send.c
new file mode 100644
index 000000000..d360bc596
--- /dev/null
+++ b/private/ntos/ndis/ibmtok2i/send.c
@@ -0,0 +1,706 @@
+/*++
+
+Copyright (c) 1990 Microsoft Corporation
+
+Module Name:
+
+ send.c
+
+Abstract:
+
+ This file contains the code for putting a packet through the
+ staged allocation for transmission.
+
+Author:
+
+ Kevin Martin(KevinMa) 20-Dec-1993
+
+Environment:
+
+ Kernel Mode - Or whatever is the equivalent on OS/2 and DOS.
+
+Revision History:
+
+
+--*/
+
+#include <tok162sw.h>
+
+
+NDIS_STATUS
+TOK162ConstrainPacket(
+ IN PTOK162_ADAPTER Adapter,
+ IN PNDIS_PACKET Packet,
+ OUT PTOK162_SUPER_COMMAND_BLOCK CommandBlock
+ );
+
+NDIS_STATUS
+TOK162TransmitPacket(
+ IN PTOK162_ADAPTER Adapter,
+ PNDIS_PACKET FirstPacket
+ );
+
+#if DBG
+VOID
+PrintTransmitEntry(
+ IN PTOK162_SUPER_COMMAND_BLOCK TransmitBlock
+ );
+#endif
+
+NDIS_STATUS
+TOK162Send(
+ IN NDIS_HANDLE MiniportAdapterContext,
+ IN PNDIS_PACKET Packet,
+ IN UINT Flags
+ )
+
+/*++
+
+Routine Description:
+
+ The TOK162Send request instructs a Miniport to transmit a packet through
+ the adapter onto the medium.
+
+Arguments:
+
+ MiniportAdapterContext - The context value returned by the Miniport when
+ the adapter was initialized. In reality, it is
+ a pointer to TOK162_ADAPTER.
+
+ Packet - A pointer to a descriptor for the packet that is
+ to be transmitted.
+
+Return Value:
+
+ The function value is the status of the operation.
+
+--*/
+
+{
+ //
+ // Pointer to the adapter.
+ //
+ PTOK162_ADAPTER Adapter =
+ PTOK162_ADAPTER_FROM_CONTEXT_HANDLE(MiniportAdapterContext);
+
+ //
+ // Status returned from TOK162TransmitPacket.
+ //
+ NDIS_STATUS Status;
+
+ //
+ // Points to the MAC reserved portion of this packet. This
+ // interpretation of the reserved section is only valid during
+ // the allocation phase of the packet.
+ //
+ PTOK162_RESERVED Reserved = PTOK162_RESERVED_FROM_PACKET(Packet);
+
+ //
+ // The number of ndis buffers in the packet.
+ //
+ UINT NdisBufferCount;
+
+ //
+ // The number of physical buffers in the entire packet.
+ //
+ UINT PhysicalBufferCount;
+
+ //
+ // The total amount of data contained within the ndis packet.
+ //
+ UINT TotalVirtualLength;
+
+ //
+ // Log the fact that we are entering TOK162Send.
+ //
+ IF_LOG('s');
+
+ ASSERT(sizeof(TOK162_RESERVED) <= sizeof(Packet->MiniportReserved));
+
+ //
+ // If we are in the middle of a reset, return this fact
+ //
+ if (Adapter->ResetInProgress == TRUE) {
+
+ return(NDIS_STATUS_RESET_IN_PROGRESS);
+
+ }
+
+ //
+ // Determine if and how much adapter space would need to be allocated
+ // to meet hardware constraints.
+ //
+ NdisQueryPacket(
+ Packet,
+ &PhysicalBufferCount,
+ &NdisBufferCount,
+ NULL,
+ &TotalVirtualLength
+ );
+
+ //
+ // See if the packet exceeds TOK162_MAXIMUM_BLOCKS_PER_PACKET.
+ // Keep in mind that if the total virtual packet length is less than
+ // MINIMUM_TOKENRING_PACKET_SIZE then we'll have to chain on an
+ // additional buffer to pad the packet out to the minimum size.
+ //
+ if ((PhysicalBufferCount > Adapter->TransmitThreshold) ||
+ (TotalVirtualLength < MINIMUM_TOKENRING_PACKET_SIZE)) {
+
+ Reserved->NdisBuffersToMove = NdisBufferCount;
+
+ } else {
+
+ Reserved->NdisBuffersToMove = 0;
+ }
+
+ //
+ // See if we can send it now.
+ //
+ Status = TOK162TransmitPacket(Adapter, Packet);
+
+ //
+ // Log the fact that we are leaving TOK162Send
+ //
+ IF_LOG('S');
+
+ return Status;
+}
+
+
+NDIS_STATUS
+TOK162TransmitPacket(
+ IN PTOK162_ADAPTER Adapter,
+ PNDIS_PACKET FirstPacket
+ )
+
+/*++
+
+Routine Description:
+
+ This routine attempts to take a packet through a stage of allocation.
+
+Arguments:
+
+ Adapter - The adapter that the packets are coming through.
+
+ FirstPacket - Packet to be sent.
+
+Return Value:
+
+ NDIS_STATUS_RESOURCES - if there are not enough resources
+ NDIS_STATUS_PENDING - if sending.
+
+--*/
+
+{
+ //
+ // Status
+ //
+ NDIS_STATUS Status;
+
+ //
+ // If we successfully acquire a command block, this
+ // is a pointer to it.
+ //
+ PTOK162_SUPER_COMMAND_BLOCK CommandBlock;
+
+ //
+ // Points to the reserved portion of the packet.
+ //
+ PTOK162_RESERVED Reserved = PTOK162_RESERVED_FROM_PACKET(FirstPacket);
+
+ //
+ // Pointer to the TOK162 data block descriptor being filled.
+ //
+ UNALIGNED PTOK162_DATA_BLOCK DataBlock;
+
+ //
+ // The total amount of data in the ndis packet.
+ //
+ UINT TotalDataLength;
+
+ //
+ // The number of ndis buffers in the packet.
+ //
+ UINT NdisBufferCount;
+
+ //
+ // Points to the current ndis buffer being walked.
+ //
+ PNDIS_BUFFER CurrentBuffer;
+
+
+ //
+ // Log the fact we are in TOK162TransmitPacket.
+ //
+ IF_LOG('t');
+
+ //
+ // See if there is a free transmit block
+ //
+ if (TOK162AcquireTransmitBlock(
+ Adapter,
+ &CommandBlock
+ )) {
+
+ // We have a command block.
+ // Initialize the general fields of the Command Block.
+ //
+ CommandBlock->OwningPacket = FirstPacket;
+ CommandBlock->NextCommand = NULL;
+ CommandBlock->Hardware.Status = 0;
+ CommandBlock->Hardware.NextPending = TOK162_NULL;
+ CommandBlock->Hardware.CommandCode = CMD_DMA_XMIT;
+
+ //
+ // Check to see if we need to constrain the packet
+ //
+ if (PTOK162_RESERVED_FROM_PACKET(
+ FirstPacket)->NdisBuffersToMove != 0) {
+
+ //
+ // Now we merge the packet into a buffer
+ //
+ Status = TOK162ConstrainPacket(Adapter,
+ FirstPacket,
+ CommandBlock
+ );
+
+ //
+ // Otherwise, we will use the map registers and send the packet out
+ // as is.
+ //
+ } else {
+
+ //
+ // Array to hold the physical segments
+ //
+ NDIS_PHYSICAL_ADDRESS_UNIT PhysicalSegmentArray[TOK162_MAX_SG];
+
+ //
+ // Number of physical segments in the buffer
+ //
+ UINT BufferPhysicalSegments;
+
+ //
+ // map register to use for this buffer
+ //
+ UINT CurMapRegister;
+
+ //
+ // Iteration variable
+ //
+ UINT i;
+
+ //
+ // Assume we will be successful
+ //
+ Status = NDIS_STATUS_SUCCESS;
+
+ //
+ // Get the first buffer as well as the number of ndis buffers in
+ // the packet.
+ //
+ NdisQueryPacket(
+ FirstPacket,
+ NULL,
+ &NdisBufferCount,
+ &CurrentBuffer,
+ &TotalDataLength
+ );
+
+ //
+ // Each packet is sent out complete and is not chained.
+ //
+ CommandBlock->Hardware.TransmitEntry.ForwardPointer = 0xFFFFFFFF;
+
+ //
+ // Let the card know this buffer is ready to send.
+ //
+ CommandBlock->Hardware.TransmitEntry.CSTAT =
+ TRANSMIT_CSTAT_REQUEST;
+
+ //
+ // We didn't have to constrain.
+ //
+ CommandBlock->UsedTOK162Buffer = FALSE;
+
+ //
+ // Store the frame size.
+ //
+ CommandBlock->Hardware.TransmitEntry.FrameSize =
+ BYTE_SWAP((USHORT)TotalDataLength);
+
+ //
+ // Get the first map register to use
+ //
+ CurMapRegister = CommandBlock->CommandBlockIndex *
+ Adapter->TransmitThreshold;
+
+ //
+ // Go through all of the buffers in the packet getting
+ // the actual physical buffers from each MDL.
+ //
+ DataBlock = (UNALIGNED PTOK162_DATA_BLOCK)
+ &(CommandBlock->Hardware.TransmitEntry.DataCount1);
+
+ while (CurrentBuffer != NULL) {
+
+ NdisMStartBufferPhysicalMapping(
+ Adapter->MiniportAdapterHandle,
+ CurrentBuffer,
+ CurMapRegister,
+ TRUE,
+ PhysicalSegmentArray,
+ &BufferPhysicalSegments
+ );
+
+ CurMapRegister++;
+
+ //
+ // Store segments into command block
+ //
+ for (i = 0; i < BufferPhysicalSegments ; i++) {
+ DataBlock->Size =
+ BYTE_SWAP((USHORT)PhysicalSegmentArray[i].Length + 0x8000);
+
+ DataBlock->IBMPhysicalAddress = BYTE_SWAP_ULONG(
+ NdisGetPhysicalAddressLow(PhysicalSegmentArray[i].PhysicalAddress));
+
+ LOUD_DEBUG(DbgPrint("Address set is %08x\n",DataBlock->IBMPhysicalAddress);)
+
+ DataBlock++;
+ }
+
+ //
+ // Make sure the buffer, if cached, is updated in memory
+ //
+ NdisFlushBuffer(CurrentBuffer, TRUE);
+
+ //
+ // Get the next buffer
+ //
+ NdisGetNextBuffer(
+ CurrentBuffer,
+ &CurrentBuffer
+ );
+
+
+ }
+
+ //
+ // We'll be one past the last entry, so move back
+ //
+ DataBlock--;
+
+ //
+ // Strip off the high bit (already byte_swapped) to let the card
+ // know this is the last entry.
+ //
+ DataBlock->Size &= 0xFF7F;
+ }
+
+ if (Status == NDIS_STATUS_SUCCESS) {
+
+ //
+ // Indicate that we have one more transmit queued
+ //
+ Adapter->TransmitsQueued++;
+
+ //
+ // Display the send structure on the debugger
+ //
+ EXTRA_LOUD_DEBUG(PrintTransmitEntry(CommandBlock);)
+
+ //
+ // Submit the transmit block to be sent out
+ //
+ TOK162SubmitTransmitBlock(
+ Adapter,
+ CommandBlock
+ );
+
+ } else {
+
+ //
+ // Log the fact that we have an unsuccessful transmit setup
+ // and return the error code.
+ //
+ IF_LOG('U');
+ return(Status);
+
+ }
+
+ //
+ // No transmit block was available.
+ //
+ } else {
+
+ //
+ // Log the fact that we couldn't get a transmit block and return
+ // RESOURCES error.
+ //
+ IF_LOG('u');
+ return(NDIS_STATUS_RESOURCES);
+
+ }
+
+ //
+ // Log that we are leaving TOK162TransmitPacket
+ //
+ IF_LOG('T');
+ LOUD_DEBUG(DbgPrint("Transmit is now set to pending\n");)
+
+ //
+ // Indicate the send has pended.
+ //
+ return(NDIS_STATUS_PENDING);
+
+}
+
+NDIS_STATUS
+TOK162ConstrainPacket(
+ IN PTOK162_ADAPTER Adapter,
+ IN PNDIS_PACKET Packet,
+ OUT PTOK162_SUPER_COMMAND_BLOCK CommandBlock
+ )
+
+/*++
+
+Routine Description:
+
+ Given a packet and if necessary attempt to acquire adapter
+ buffer resources so that the packet meets TOK162 hardware/MAC.BIN
+ contraints.
+
+Arguments:
+
+ Adapter - The adapter the packet is coming through.
+
+ Packet - The packet whose buffers are to be constrained.
+ The packet reserved section is filled with information
+ detailing how the packet needs to be adjusted.
+
+ CommandBlock - Command block describing the packet to be sent.
+
+Return Value:
+
+ Status - SUCCESS.
+
+--*/
+
+{
+
+ //
+ // Pointer to the reserved section of the packet to be contrained.
+ //
+ PTOK162_RESERVED Reserved = PTOK162_RESERVED_FROM_PACKET(Packet);
+
+ //
+ // Will point into the virtual address space addressed
+ // by the adapter buffer if one was successfully allocated.
+ //
+ PCHAR CurrentDestination;
+
+ //
+ // Will hold the total amount of data copied to the
+ // adapter buffer.
+ //
+ UINT TotalDataMoved = 0;
+
+ //
+ // Will point to the current source buffer.
+ //
+ PNDIS_BUFFER SourceBuffer;
+
+ //
+ // Points to the virtual address of the source buffers data.
+ //
+ PVOID SourceData;
+
+ //
+ // Will point to the number of bytes of data in the source
+ // buffer.
+ //
+ UINT SourceLength;
+
+ //
+ // The total amount of data contained within the ndis packet.
+ //
+ UINT TotalVirtualLength;
+
+ //
+ // Simple iteration variable.
+ //
+ INT i;
+
+ //
+ // Log that we entered TOK162ConstrainPacket
+ //
+ IF_LOG('v');
+
+ //
+ // Indicate that we are using this buffer
+ //
+ CommandBlock->UsedTOK162Buffer = TRUE;
+
+ //
+ // Get info on the data to be transmitted.
+ //
+ NdisQueryPacket(
+ Packet,
+ NULL,
+ NULL,
+ &SourceBuffer,
+ &TotalVirtualLength
+ );
+
+ NdisQueryBuffer(
+ SourceBuffer,
+ &SourceData,
+ &SourceLength
+ );
+
+ //
+ // There is no link to this transmit list, and
+ // this list is ready to send.
+ //
+ CommandBlock->Hardware.TransmitEntry.ForwardPointer = 0xFFFFFFFF;
+ CommandBlock->Hardware.TransmitEntry.CSTAT = TRANSMIT_CSTAT_REQUEST;
+
+ //
+ // Set frame size to total virtual length of the packet.
+ //
+ CommandBlock->Hardware.TransmitEntry.FrameSize =
+ BYTE_SWAP(TotalVirtualLength);
+
+ //
+ // Set data count to frame size
+ //
+ CommandBlock->Hardware.TransmitEntry.DataCount1 =
+ CommandBlock->Hardware.TransmitEntry.FrameSize;
+
+ //
+ // Set the address to the buffer associated with this transmit block
+ //
+ CommandBlock->Hardware.TransmitEntry.PhysicalAddress1=BYTE_SWAP_ULONG(
+ NdisGetPhysicalAddressLow(CommandBlock->TOK162BufferPhysicalAddress));
+
+ //
+ // Make sure count fields for the second and third entries are 0.
+ //
+ CommandBlock->Hardware.TransmitEntry.DataCount2 = 0x00000000;
+ CommandBlock->Hardware.TransmitEntry.DataCount3 = 0x00000000;
+
+ //
+ // Fill in the buffer with the data from the users buffers.
+ //
+ CurrentDestination = (PVOID)CommandBlock->TOK162BufferAddress;
+
+ for (
+ i = Reserved->NdisBuffersToMove;
+ i;
+ i--
+ ) {
+
+ NdisMoveMemory(
+ CurrentDestination,
+ SourceData,
+ SourceLength
+ );
+
+ CurrentDestination = (PCHAR)CurrentDestination + SourceLength;
+
+ TotalDataMoved += SourceLength;
+
+ if (i > 1) {
+
+ NdisGetNextBuffer(
+ SourceBuffer,
+ &SourceBuffer
+ );
+
+ NdisQueryBuffer(
+ SourceBuffer,
+ &SourceData,
+ &SourceLength
+ );
+
+ }
+
+ }
+
+ //
+ // If the packet is less than the minimum TokenRing
+ // packet size, then clear the remaining part of
+ // the buffer up to the minimum packet size.
+ //
+ if (TotalVirtualLength < MINIMUM_TOKENRING_PACKET_SIZE) {
+
+ NdisZeroMemory(
+ CurrentDestination,
+ MINIMUM_TOKENRING_PACKET_SIZE - TotalVirtualLength
+ );
+
+ }
+
+
+ //
+ // Make sure the card and the system are in sync.
+ //
+ // The following was removed on 1/26/95 because it causes a hang
+ // on MIPs machines.
+ //
+ // NdisFlushBuffer(CommandBlock->FlushBuffer,TRUE);
+
+ //
+ // Log that we are leaving TOK162ConstrainPacket
+ //
+ IF_LOG('V');
+
+ return(NDIS_STATUS_SUCCESS);
+}
+
+#if DBG
+VOID
+PrintTransmitEntry(
+ IN PTOK162_SUPER_COMMAND_BLOCK TransmitBlock
+ )
+/*++
+
+Routine Description:
+
+ This routine displays a transmit list on the debug screen
+
+Arguments:
+
+ CommandBlock - Pointer to the command block with the transmit list
+
+Return Value:
+
+ None.
+--*/
+
+{
+
+ //
+ // Pointer to the transmit list portion of the transmit block.
+ //
+ TOK162_TRANSMIT_LIST Transmit = TransmitBlock->Hardware.TransmitEntry;
+
+ //
+ // Display all of the information about the send on the debugger.
+ //
+ DbgPrint("Forward Pointer = %08lx\n",Transmit.ForwardPointer);
+ DbgPrint("CSTAT = %x\n" ,Transmit.CSTAT);
+ DbgPrint("Frame Size = %04x\n" ,Transmit.FrameSize);
+ DbgPrint("DataCount1 = %04x\n" ,Transmit.DataCount1);
+ DbgPrint("DataAddress1 = %08lx\n",Transmit.PhysicalAddress1);
+ DbgPrint("DataCount2 = %04x\n" ,Transmit.DataCount2);
+ DbgPrint("DataAddress2 = %08lx\n",Transmit.PhysicalAddress2);
+ DbgPrint("DataCount3 = %04x\n" ,Transmit.DataCount3);
+ DbgPrint("DataAddress3 = %08lx\n",Transmit.PhysicalAddress3);
+
+}
+#endif
diff --git a/private/ntos/ndis/ibmtok2i/sources b/private/ntos/ndis/ibmtok2i/sources
new file mode 100644
index 000000000..9e402e3a4
--- /dev/null
+++ b/private/ntos/ndis/ibmtok2i/sources
@@ -0,0 +1,48 @@
+!IF 0
+
+Copyright (c) 1989 Microsoft Corporation
+
+Module Name:
+
+ sources.
+
+Abstract:
+
+ This file specifies the target component being built and the list of
+ sources files needed to build that component. Also specifies optional
+ compiler switches and libraries that are unique for the component being
+ built.
+
+
+Author:
+
+ Steve Wood (stevewo) 12-Apr-1990
+
+NOTE: Commented description of this file is in \nt\bak\bin\sources.tpl
+
+!ENDIF
+
+MAJORCOMP=ntos
+MINORCOMP=ndis
+
+TARGETNAME=ibmtok2i
+TARGETPATH=\nt\public\sdk\lib
+TARGETTYPE=DRIVER
+
+TARGETLIBS=$(BASEDIR)\public\sdk\lib\*\ndis.lib
+
+C_DEFINES=$(C_DEFINES) -DNDIS_MINIPORT_DRIVER
+
+INCLUDES=inc;..\..\inc;..\..\..\inc
+
+SOURCES=command.c \
+ interrup.c \
+ tok162.c \
+ request.c \
+ reset.c \
+ send.c \
+ tok162.rc
+
+RELATIVE_DEPTH=..\..
+
+MSC_WARNING_LEVEL=/W3 /WX
diff --git a/private/ntos/ndis/ibmtok2i/tok162.c b/private/ntos/ndis/ibmtok2i/tok162.c
new file mode 100644
index 000000000..dce952707
--- /dev/null
+++ b/private/ntos/ndis/ibmtok2i/tok162.c
@@ -0,0 +1,2504 @@
+/*++
+
+Copyright (c) 1990 Microsoft Corporation
+
+Module Name:
+
+ TOK162.c
+
+Abstract:
+
+ This is the main file for the IBM Token-Ring 16/4 Adapter II.
+ This driver conforms to the NDIS 3.0 Miniport interface.
+
+Author:
+
+ Kevin Martin (KevinMa) 27-Jan-1994
+
+Environment:
+
+ Kernel Mode.
+
+Revision History:
+
+--*/
+
+
+#include <TOK162sw.h>
+
+#pragma NDIS_INIT_FUNCTION(TOK162Initialize)
+
+//
+// If debug messages and logging is wanted, set the DBG environment variable.
+//
+#if DBG
+
+//
+// Variable which indicates the level of debugging messages. Values are
+// defined below.
+//
+UCHAR Tok162Debug = 0;
+
+//
+// Pointer to the logging table. The table is allocated when the adapter
+// memory is allocated.
+//
+PUCHAR Tok162Log;
+
+//
+// Index pointer for the logging macro.
+//
+USHORT Tok162LogPlace = 0;
+
+#endif
+
+//
+// Function declarations for functions private to this file.
+//
+BOOLEAN
+TOK162AllocateAdapterMemory(
+ IN PTOK162_ADAPTER Adapter
+ );
+
+
+NTSTATUS
+DriverEntry(
+ IN PDRIVER_OBJECT DriverObject,
+ IN PUNICODE_STRING RegistryPath
+ )
+/*++
+
+Routine Description:
+
+ This is the primary initialization routine for the TOK162 driver.
+ It is simply responsible for the intializing the wrapper and registering
+ the MAC. It then calls a system and architecture specific routine that
+ will initialize and register each adapter.
+
+Arguments:
+
+ DriverObject - Pointer to driver object created by the system.
+
+Return Value:
+
+ The status of the operation.
+
+--*/
+
+{
+ //
+ // Receives the status of the NdisMRegisterMiniport operation.
+ //
+ NDIS_STATUS Status;
+
+ //
+ // Handle for our driver given to us by the wrapper.
+ //
+ NDIS_HANDLE NdisWrapperHandle;
+
+ //
+ // Miniport driver characteristics
+ //
+ char Tmp[sizeof(NDIS_MINIPORT_CHARACTERISTICS)];
+
+ PNDIS_MINIPORT_CHARACTERISTICS TOK162Char =
+ (PNDIS_MINIPORT_CHARACTERISTICS)(PVOID)Tmp;
+
+ //
+ // Initialize the wrapper.
+ //
+ NdisMInitializeWrapper(
+ &NdisWrapperHandle,
+ DriverObject,
+ RegistryPath,
+ NULL
+ );
+
+ //
+ // Initialize the Miniport characteristics for the call to
+ // NdisRegisterMac.
+ //
+ TOK162Char->MajorNdisVersion = TOK162_NDIS_MAJOR_VERSION;
+ TOK162Char->MinorNdisVersion = TOK162_NDIS_MINOR_VERSION;
+
+ //
+ // Define the entry points into this driver for the wrapper.
+ //
+ TOK162Char->CheckForHangHandler = TOK162CheckForHang;
+ TOK162Char->DisableInterruptHandler = TOK162DisableInterrupt;
+ TOK162Char->EnableInterruptHandler = TOK162EnableInterrupt;
+ TOK162Char->HaltHandler = TOK162Halt;
+ TOK162Char->HandleInterruptHandler = TOK162HandleInterrupt;
+ TOK162Char->InitializeHandler = TOK162Initialize;
+ TOK162Char->ISRHandler = TOK162Isr;
+ TOK162Char->QueryInformationHandler = TOK162QueryInformation;
+
+ //
+ // We don't support reconfigure so we pass a null.
+ //
+ TOK162Char->ReconfigureHandler = NULL;
+ TOK162Char->ResetHandler = TOK162Reset;
+ TOK162Char->SendHandler = TOK162Send;
+ TOK162Char->SetInformationHandler = TOK162SetInformation;
+ TOK162Char->TransferDataHandler = TOK162TransferData;
+
+ //
+ // Register the driver.
+ //
+ Status = NdisMRegisterMiniport(
+ NdisWrapperHandle,
+ TOK162Char,
+ sizeof(*TOK162Char)
+ );
+
+ //
+ // If everything went ok, return STATUS_SUCCESS
+ //
+ if (Status == NDIS_STATUS_SUCCESS) {
+
+ return STATUS_SUCCESS;
+
+ }
+
+ //
+ // We can only get here if something went wrong with registering
+ // the miniport or *all* of the adapters.
+ //
+ NdisTerminateWrapper(NdisWrapperHandle, NULL);
+ return STATUS_UNSUCCESSFUL;
+
+}
+
+
+NDIS_STATUS
+TOK162RegisterAdapter(
+ IN NDIS_HANDLE ConfigurationHandle,
+ IN NDIS_HANDLE MiniportAdapterHandle,
+ IN PUCHAR CurrentAddress,
+ IN UINT PortAddress,
+ IN ULONG MaxFrameSize
+ )
+
+/*++
+
+Routine Description:
+
+ This routine (and its interface) are not portable. They are
+ defined by the OS, the architecture, and the particular TOK162
+ implementation.
+
+ This routine is responsible for the allocation of the datastructures
+ for the driver as well as any hardware specific details necessary
+ to talk with the device.
+
+Arguments:
+
+ ConfigurationHandle - Handle passed to NdisRegisterAdapter.
+ MiniportAdapterHandle - Handle received from
+ CurrentAddress - The network address found in the registry
+ PortAddress - The starting i/o port address found in the
+ registry
+
+Return Value:
+
+ Returns NDIS_STATUS_SUCCESS if everything goes ok, else
+ if anything occurred that prevents the initialization
+ of the adapter it returns an appropriate NDIS error.
+
+--*/
+
+{
+
+ //
+ // Holds the value returned by NDIS calls.
+ //
+ NDIS_STATUS Status;
+
+ //
+ // Holds information needed when registering the adapter.
+ //
+ PTOK162_ADAPTER Adapter;
+
+ // We put in this assertion to make sure that ushort are 2 bytes.
+ // if they aren't then the initialization block definition needs
+ // to be changed.
+ //
+ ASSERT(sizeof(TOK162_PHYSICAL_ADDRESS) == 4);
+
+ //
+ // Allocate the Adapter memory
+ //
+ TOK162_ALLOC_PHYS(&Status, &Adapter, sizeof(TOK162_ADAPTER));
+
+ //
+ // If everything went ok (Status == NDIS_STATUS_SUCCESS), zero the
+ // memory, and then assign values that we know to the adapter structure.
+ //
+ if (Status != NDIS_STATUS_SUCCESS) {
+
+ //
+ // The allocation didn't work, so return an error indicating resource
+ // problems.
+ //
+ return NDIS_STATUS_RESOURCES;
+ }
+
+ NdisZeroMemory(
+ Adapter,
+ sizeof(TOK162_ADAPTER)
+ );
+
+ //
+ // Assign the handle and io port address base
+ //
+ Adapter->MiniportAdapterHandle = MiniportAdapterHandle;
+ Adapter->PortIOBase = PortAddress;
+
+ //
+ // Set the receive, transmit, and command buffer and block
+ // information.
+ //
+ Adapter->NumberOfReceiveBuffers = RECEIVE_LIST_COUNT;
+ Adapter->NumberOfTransmitLists = TRANSMIT_LIST_COUNT;
+
+ Adapter->NumberOfAvailableCommandBlocks =
+ TOK162_NUMBER_OF_CMD_BLOCKS;
+
+ //
+ // Set the address the adapter should enter the ring with.
+ //
+ NdisMoveMemory(
+ Adapter->CurrentAddress,
+ CurrentAddress,
+ TOK162_LENGTH_OF_ADDRESS
+ );
+
+ //
+ // Notify the wrapper of our attributes
+ //
+ NdisMSetAttributes(
+ MiniportAdapterHandle,
+ (NDIS_HANDLE)Adapter,
+ TRUE,
+ NdisInterfaceIsa
+ );
+
+ //
+ // Register our shutdown handler.
+ //
+
+ NdisMRegisterAdapterShutdownHandler(
+ Adapter->MiniportAdapterHandle, // miniport handle.
+ Adapter, // shutdown context.
+ TOK162Shutdown // shutdown handler.
+ );
+
+ //
+ // Register our port usage
+ //
+ Status = NdisMRegisterIoPortRange(
+ (PVOID *)(&(Adapter->PortIOAddress)),
+ MiniportAdapterHandle,
+ Adapter->PortIOBase,
+ 0x10
+ );
+
+ //
+ // If there was a problem with the registration, free the memory
+ // associated with the adapter and return resource error
+ //
+ if (Status != NDIS_STATUS_SUCCESS) {
+
+ goto Error1Exit;
+
+ }
+
+ //
+ // Obtain all of the other adapter parameters
+ //
+ Status = TOK162GetAdapterConfiguration(Adapter);
+
+ if (Status != NDIS_STATUS_SUCCESS) {
+
+ goto Error1Exit;
+
+ }
+
+ if (MaxFrameSize != 0) {
+
+ Adapter->ReceiveBufferSize = (USHORT)MaxFrameSize;
+
+ }
+
+
+ //
+ // Allocate the map registers
+ //
+ Status = NdisMAllocateMapRegisters(
+ Adapter->MiniportAdapterHandle,
+ Adapter->ConfigurationBlock.DMAChannel,
+ FALSE,
+ Adapter->NumberOfTransmitLists *
+ Adapter->TransmitThreshold,
+ Adapter->ReceiveBufferSize
+ );
+
+ //
+ // If there were any problems, return resources error.
+ //
+ if (Status != NDIS_STATUS_SUCCESS) {
+
+ goto Error2Exit;
+
+ }
+
+ //
+ // Allocate memory for all of the adapter structures
+ //
+ if (TOK162AllocateAdapterMemory(Adapter) == FALSE) {
+
+ //
+ // We get here if the allocateadaptermemory call fails. All we
+ // can do is log the resource problem, display the fact that the
+ // register failed, and return resources.
+ //
+
+ goto Error3Exit;
+
+ }
+
+ //
+ // The allocation succeeded.
+ // Reset the variables associated with the adapter
+ //
+ TOK162ResetVariables(Adapter);
+
+ //
+ // Initialize deferred and reset timers
+ //
+ NdisMInitializeTimer(
+ &Adapter->DeferredTimer,
+ Adapter->MiniportAdapterHandle,
+ (PVOID) TOK162DeferredTimer,
+ (PVOID) Adapter
+ );
+
+ NdisMInitializeTimer(
+ &Adapter->ResetTimer,
+ Adapter->MiniportAdapterHandle,
+ (PVOID) TOK162ResetHandler,
+ (PVOID) Adapter
+ );
+
+ //
+ // Initialize the adapter
+ //
+ VERY_LOUD_DEBUG(DbgPrint("TOK162!Calling InitialInit\n");)
+
+ if (TOK162InitialInit(Adapter) == FALSE) {
+
+ //
+ // If there was an error (FALSE), write the log entry, and
+ // free up all of the resources.
+ //
+ NdisWriteErrorLogEntry(
+ MiniportAdapterHandle,
+ NDIS_ERROR_CODE_ADAPTER_NOT_FOUND,
+ 0
+ );
+
+ //
+ // Return resources to the wrapper
+ //
+ if (Adapter->InterruptLevel != 0) {
+
+ NdisMDeregisterInterrupt(&Adapter->Interrupt);
+
+ }
+
+ goto Error3Exit;
+
+ }
+
+ //
+ // Display success to the debugger.
+ //
+ VERY_LOUD_DEBUG(DbgPrint(
+ "TOK162!Returning TRUE from RegisterAdapter\n");)
+
+ return NDIS_STATUS_SUCCESS;
+
+//
+// Error3Exit level indicates that we need to deregister the map registers
+// and deallocate the adapter-related allocated memory.
+//
+Error3Exit:
+
+ NdisMFreeMapRegisters(Adapter->MiniportAdapterHandle);
+ TOK162DeleteAdapterMemory(Adapter);
+
+//
+// Error2Exit level indicates that we need to deregister the IO Port Range.
+//
+Error2Exit:
+
+ NdisMDeregisterIoPortRange(Adapter->MiniportAdapterHandle,
+ Adapter->PortIOBase,
+ 0x30,
+ Adapter->PortIOAddress
+ );
+
+
+//
+// Error1Exit level indicates that we need to free the memory allocated
+// for the adapter structure. Log that register adapter failed.
+//
+Error1Exit:
+
+ NdisWriteErrorLogEntry(
+ MiniportAdapterHandle,
+ NDIS_ERROR_CODE_OUT_OF_RESOURCES,
+ 0
+ );
+
+ VERY_LOUD_DEBUG(DbgPrint(
+ "TOK162!Returning FALSE from RegisterAdapter\n");)
+
+ TOK162_FREE_PHYS(Adapter);
+ return NDIS_STATUS_RESOURCES;
+
+}
+
+
+extern
+NDIS_STATUS
+TOK162GetAdapterConfiguration(
+ IN PTOK162_ADAPTER Adapter
+ )
+/*++
+
+Routine Description:
+
+ This routine obtains all of the settings from the adapter
+
+Arguments:
+
+ Adapter - Current Adapter structure
+
+Return Value:
+
+ NDIS_STATUS_SUCCESS if allocation of structure is successful.
+ NDIS_STATUS_RESOURCES if not.
+
+--*/
+{
+ //
+ // Holds value of the switches registers
+ //
+ PADAPTERSWITCHES Switches;
+
+ //
+ // Variable used to obtain the switches.
+ //
+ USHORT temp;
+
+ //
+ // Read in the switches registers from the adapter
+ //
+ READ_ADAPTER_USHORT(Adapter,
+ PORT_OFFSET_SWITCH_INT_DISABLE,
+ &temp
+ );
+
+ Switches = (PADAPTERSWITCHES)&temp;
+
+ //
+ // Display the value of the switches on the debugger.
+ //
+ VERY_LOUD_DEBUG(DbgPrint("TOK162!Switches are: %X\n",temp);)
+
+ //
+ // Display the individual values of the switches. These values are
+ // the values of the switches, not actual values that the switches
+ // represent (i.e. - interrupt 9 will be seen as 00, the switch
+ // positions representing interrupt 9).
+ //
+ VERY_LOUD_DEBUG(DbgPrint(
+ "TOK162!Reserved - %x\n", Switches->Reserved);)
+ VERY_LOUD_DEBUG(DbgPrint(
+ "TOK162!Setting AdapterMode - %x\n", Switches->AdapterMode);)
+ VERY_LOUD_DEBUG(DbgPrint(
+ "TOK162!Setting Waitstate - %x\n", Switches->WaitState);)
+ VERY_LOUD_DEBUG(DbgPrint(
+ "TOK162!Setting RPL - %x\n", Switches->RPL);)
+ VERY_LOUD_DEBUG(DbgPrint(
+ "TOK162!Setting RPL/IO Address - %x\n",Switches->RPL_PIO_Address);)
+ VERY_LOUD_DEBUG(DbgPrint(
+ "TOK162!Setting RingSpeed - %02x\n", Switches->RingSpeed);)
+ VERY_LOUD_DEBUG(DbgPrint(
+ "TOK162!Setting UTP/STP - %x\n", Switches->UTP_STP);)
+ VERY_LOUD_DEBUG(DbgPrint(
+ "TOK162!Setting DMA - %u\n", Switches->DMA);)
+ VERY_LOUD_DEBUG(DbgPrint(
+ "TOK162!Setting Interrupt - %u\n", Switches->IntRequest);)
+
+ //
+ // Get the adapter mode
+ //
+ if (Switches->AdapterMode == SW_ADAPTERMODE_NORMAL) {
+
+ Adapter->ConfigurationBlock.AdapterMode = CFG_ADAPTERMODE_NORMAL;
+
+ } else {
+
+ Adapter->ConfigurationBlock.AdapterMode = CFG_ADAPTERMODE_TEST;
+
+ }
+
+ //
+ // Get the adatper wait state setting.
+ //
+ if (Switches->WaitState == SW_WAITSTATE_NORMAL) {
+
+ Adapter->ConfigurationBlock.WaitState = CFG_WAITSTATE_NORMAL;
+
+ } else {
+
+ Adapter->ConfigurationBlock.WaitState = CFG_WAITSTATE_FAST;
+
+ }
+
+ //
+ // Check if Remote Program Load (RPL) is set. If it is, get the
+ // RPL Address.
+ //
+ if (Switches->RPL == SW_RPL_ENABLE) {
+
+ Adapter->ConfigurationBlock.RPL = TRUE;
+
+ switch(Switches->RPL_PIO_Address) {
+
+ case SW_PIO_ADDR_8:
+
+ Adapter->ConfigurationBlock.RPLAddress = CFG_RPLADDR_C0000;
+ break;
+
+ case SW_PIO_ADDR_C:
+
+ Adapter->ConfigurationBlock.RPLAddress = CFG_RPLADDR_C4000;
+ break;
+
+ case SW_PIO_ADDR_A:
+
+ Adapter->ConfigurationBlock.RPLAddress = CFG_RPLADDR_C8000;
+ break;
+
+ case SW_PIO_ADDR_E:
+
+ Adapter->ConfigurationBlock.RPLAddress = CFG_RPLADDR_CC000;
+ break;
+
+ case SW_PIO_ADDR_9:
+
+ Adapter->ConfigurationBlock.RPLAddress = CFG_RPLADDR_D0000;
+ break;
+
+ case SW_PIO_ADDR_D:
+
+ Adapter->ConfigurationBlock.RPLAddress = CFG_RPLADDR_D4000;
+ break;
+
+ case SW_PIO_ADDR_B:
+
+ Adapter->ConfigurationBlock.RPLAddress = CFG_RPLADDR_D8000;
+ break;
+
+ case SW_PIO_ADDR_F:
+
+ Adapter->ConfigurationBlock.RPLAddress = CFG_RPLADDR_DC000;
+ break;
+
+ }
+
+ } else {
+
+ //
+ // RPL is not enabled. Record this fact and zero out the RPL address.
+ //
+ Adapter->ConfigurationBlock.RPL = FALSE;
+ Adapter->ConfigurationBlock.RPLAddress = 0x0000;
+
+ }
+
+
+ //
+ // Get the ring speed.
+ //
+ if (Switches->RingSpeed == SW_RINGSPEED_4) {
+
+ //
+ // If the adapter is running at 4MBPS, set the ring speed
+ // value, allow up to 3 scatter-gathers per transmit, and
+ // set the receive buffer size (the max for the ring at this
+ // speed).
+ //
+ Adapter->ConfigurationBlock.RingSpeed = CFG_RINGSPEED_4;
+
+ Adapter->TransmitThreshold = 3;
+
+ Adapter->Running16Mbps = FALSE;
+
+ Adapter->ReceiveBufferSize = RECEIVE_LIST_BUFFER_SIZE_4;
+
+ } else {
+
+ //
+ // If the adapter is running at 16MBPS, set the ring speed
+ // value, allow up to 2 scatter-gathers per transmit, and
+ // set the receive buffer size (the max for the ring at this
+ // speed).
+ //
+ Adapter->ConfigurationBlock.RingSpeed = CFG_RINGSPEED_16;
+
+ Adapter->TransmitThreshold = 1;
+
+ Adapter->Running16Mbps = TRUE;
+
+ Adapter->ReceiveBufferSize = RECEIVE_LIST_BUFFER_SIZE_16;
+ }
+
+
+ //
+ // Get the connector type
+ //
+ if (Switches->UTP_STP == SW_UTP) {
+
+ Adapter->ConfigurationBlock.UTPorSTP = CFG_MEDIATYPE_UTP;
+
+ } else {
+
+ Adapter->ConfigurationBlock.UTPorSTP = CFG_MEDIATYPE_STP;
+
+ }
+
+ //
+ // Get the DMA channel in use.
+ //
+ switch(Switches->DMA) {
+
+ case SW_DMA_5:
+
+ Adapter->ConfigurationBlock.DMAChannel = CFG_DMACHANNEL_5;
+ break;
+
+ case SW_DMA_6:
+
+ Adapter->ConfigurationBlock.DMAChannel = CFG_DMACHANNEL_6;
+ break;
+
+ case SW_DMA_7:
+
+ Adapter->ConfigurationBlock.DMAChannel = CFG_DMACHANNEL_7;
+ break;
+
+ }
+
+ //
+ // Get the interrupt level.
+ //
+ switch(Switches->IntRequest) {
+
+ case SW_INT_9:
+
+ Adapter->InterruptLevel = CFG_INT_9;
+ break;
+
+ case SW_INT_10:
+
+ Adapter->InterruptLevel = CFG_INT_10;
+ break;
+
+ case SW_INT_11:
+
+ Adapter->InterruptLevel = CFG_INT_11;
+ break;
+
+ case SW_INT_15:
+
+ Adapter->InterruptLevel = CFG_INT_15;
+ break;
+
+ }
+
+ //
+ // Return that we succeeded.
+ //
+ return(NDIS_STATUS_SUCCESS);
+}
+
+
+extern
+NDIS_STATUS
+TOK162Initialize(
+ OUT PNDIS_STATUS OpenErrorStatus,
+ OUT PUINT SelectedMediumIndex,
+ IN PNDIS_MEDIUM MediumArray,
+ IN UINT MediumArraySize,
+ IN NDIS_HANDLE MiniportAdapterHandle,
+ IN NDIS_HANDLE ConfigurationHandle
+ )
+
+/*++
+
+Routine Description:
+
+ This routine is used to initialize each adapter card/chip.
+
+Arguments:
+
+ OpenErrorStatus - Token Ring Adapter Open Status
+ SelectedMediumIndex - Medium used for transmission (Token Ring)
+ MediumArray - Array of mediums supported by wrapper
+ MiniportAdapterHandle - Adapter Handle
+ ConfigurationHandle - Configuration Handle
+
+Return Value:
+
+ Result of registering this adapter.
+
+--*/
+
+{
+ //
+ // Handle returned by NdisOpenConfiguration
+ //
+ NDIS_HANDLE ConfigHandle;
+
+ //
+ // Simple indexing variable
+ //
+ ULONG i;
+
+ //
+ // Buffer to copy the passed in network address.
+ //
+ UCHAR NetworkAddress[TOK162_LENGTH_OF_ADDRESS];
+
+ //
+ // Receives address of the network address string in the registry
+ //
+ PVOID NetAddress;
+
+ //
+ // Length of above network address string
+ //
+ ULONG Length;
+
+ //
+ // Beginning port address for this adapter
+ //
+ ULONG PortAddress;
+
+ //
+ // Variable holding value returned by NdisReadConfiguration
+ //
+ PNDIS_CONFIGURATION_PARAMETER ReturnedValue;
+
+ //
+ // Description string constants found in registry
+ //
+ NDIS_STRING IOAddressStr = NDIS_STRING_CONST("IOBaseAddress");
+ NDIS_STRING MaxFrameStr = NDIS_STRING_CONST("MAXFRAMESIZE");
+
+ //
+ // Return value from NDIS calls
+ //
+ NDIS_STATUS Status;
+
+ //
+ // Value to be passed along as MaxFrameSize
+ //
+ ULONG MaxFrameSize;
+
+ //
+ // Cache-Alignment variable
+ //
+ ULONG Alignment;
+
+ //
+ // Search for the medium type (802.5)
+ //
+ for (i = 0; i < MediumArraySize; i++){
+
+
+ if (MediumArray[i] == NdisMedium802_5){
+ break;
+
+ }
+
+ }
+
+ //
+ // See if Token Ring is supported by the wrapper
+ //
+ if (i == MediumArraySize) {
+
+ return NDIS_STATUS_UNSUPPORTED_MEDIA;
+
+ }
+
+ //
+ // Tell wrapper the index in the medium array we're using
+ //
+ *SelectedMediumIndex = i;
+
+ //
+ // Get access to the configuration information
+ //
+ NdisOpenConfiguration(
+ &Status,
+ &ConfigHandle,
+ ConfigurationHandle
+ );
+
+ //
+ // If there was an error, return with the error code.
+ //
+ if (Status != NDIS_STATUS_SUCCESS) {
+
+ return Status;
+
+ }
+
+ //
+ // Read net address from the configuration info.
+ //
+ NdisReadNetworkAddress(
+ &Status,
+ &NetAddress,
+ &Length,
+ ConfigHandle
+ );
+
+ //
+ // Make sure the call worked and the address returned is of valid length
+ //
+ if ((Length == TOK162_LENGTH_OF_ADDRESS) &&
+ (Status == NDIS_STATUS_SUCCESS)) {
+
+ NdisMoveMemory(
+ NetworkAddress,
+ NetAddress,
+ TOK162_LENGTH_OF_ADDRESS
+ );
+
+ //
+ // If not, set the current address to all 0's, forcing the adapter
+ // to use the permanent address as the current address.
+ //
+ } else {
+
+ NdisZeroMemory(
+ NetworkAddress,
+ TOK162_LENGTH_OF_ADDRESS
+ );
+
+ }
+
+ //
+ // Get the port address from the configuration info.
+ //
+ NdisReadConfiguration(
+ &Status,
+ &ReturnedValue,
+ ConfigHandle,
+ &IOAddressStr,
+ NdisParameterHexInteger
+ );
+
+ PortAddress = ReturnedValue->ParameterData.IntegerData;
+
+ //
+ // Get the max frame size if indicated by user
+ //
+ NdisReadConfiguration(
+ &Status,
+ &ReturnedValue,
+ ConfigHandle,
+ &MaxFrameStr,
+ NdisParameterInteger
+ );
+
+ if (Status == NDIS_STATUS_SUCCESS) {
+
+ MaxFrameSize = (ULONG)(ReturnedValue->ParameterData.IntegerData);
+
+ Alignment = NdisGetCacheFillSize();
+
+ if ( Alignment < sizeof(ULONG) ) {
+
+ Alignment = sizeof(ULONG);
+ }
+
+ MaxFrameSize = (MaxFrameSize + (Alignment - 1)) & ~(Alignment - 1);
+
+ if ((MaxFrameSize > RECEIVE_LIST_BUFFER_SIZE_16) ||
+ (MaxFrameSize < RECEIVE_LIST_BUFFER_SIZE_4)) {
+
+ MaxFrameSize = 0;
+
+ }
+
+ } else {
+
+ MaxFrameSize = 0;
+
+ }
+
+ //
+ // We're done with the configuration info.
+ //
+ NdisCloseConfiguration(ConfigHandle);
+
+ //
+ // Go register this adapter.
+ //
+ Status = TOK162RegisterAdapter(
+ ConfigurationHandle,
+ MiniportAdapterHandle,
+ NetworkAddress,
+ PortAddress,
+ MaxFrameSize
+ );
+
+ //
+ // Return the value TOK162RegisterAdapter returned
+ //
+ return Status;
+
+}
+
+
+BOOLEAN
+TOK162AllocateAdapterMemory(
+ IN PTOK162_ADAPTER Adapter
+ )
+/*++
+
+Routine Description:
+
+ This routine allocates memory for:
+
+ - SCB
+
+ - SSB
+
+ - ErrorLog Block
+
+ - ReadAdapter Block
+
+ - Initialization Block
+
+ - Open Command Block
+
+ - Command Queue
+
+ - Transmit Command Queue
+
+ - Transmit Buffers
+
+ - Flush Buffer Pool
+
+ - Receive Queue
+
+ - Receive Buffers
+
+ - Receive Flush Buffers
+
+Arguments:
+
+ Adapter - The adapter to allocate memory for.
+
+Return Value:
+
+ Returns FALSE if some memory needed for the adapter could not
+ be allocated.
+
+--*/
+
+{
+ //
+ // Pointer to a Super Receive List. Used while initializing
+ // the Receive Queue.
+ //
+ PTOK162_SUPER_RECEIVE_LIST CurrentReceiveEntry;
+
+ //
+ // Pointer to a Command Block. Used while initializing
+ // the Command Queue.
+ //
+ PTOK162_SUPER_COMMAND_BLOCK CurrentCommandBlock;
+
+ //
+ // Simple iteration variable.
+ //
+ UINT i;
+
+ //
+ // Status of allocation
+ //
+ NDIS_STATUS Status;
+
+#if DBG
+
+ //
+ // If debugging is specified, we need to allocate the trace log
+ // buffer.
+ //
+
+ NDIS_PHYSICAL_ADDRESS ndp;
+
+ NdisMAllocateSharedMemory(
+ Adapter->MiniportAdapterHandle,
+ LOG_SIZE,
+ FALSE,
+ (PVOID *)&Tok162Log,
+ &ndp);
+#endif
+ //
+ // Allocate the SCB
+ //
+
+ VERY_LOUD_DEBUG(DbgPrint("Allocating SCB\n");)
+
+ NdisMAllocateSharedMemory(
+ Adapter->MiniportAdapterHandle,
+ sizeof(SCB) + 8,
+ FALSE,
+ (PVOID *) &Adapter->Scb,
+ &Adapter->ScbPhysical
+ );
+
+ VERY_LOUD_DEBUG(DbgPrint("Address of SCB is %lx\n",(ULONG)Adapter->Scb);)
+
+ //
+ // If the Scb could not be allocated, a NULL pointer will have been
+ // returned.
+ //
+ if (Adapter->Scb == NULL) {
+
+ return FALSE;
+
+ }
+
+ //
+ // Allocate the SSB
+ //
+ VERY_LOUD_DEBUG(DbgPrint("Allocating SSB\n");)
+
+ NdisMAllocateSharedMemory(
+ Adapter->MiniportAdapterHandle,
+ sizeof(SSB) + 8,
+ FALSE,
+ (PVOID *) &Adapter->Ssb,
+ &Adapter->SsbPhysical
+ );
+
+ VERY_LOUD_DEBUG(DbgPrint("Address of SSB is %lx\n",(ULONG)Adapter->Ssb);)
+
+ //
+ // If the Ssb could not be allocated, a NULL pointer will have been
+ // returned.
+ //
+ if (Adapter->Ssb == NULL) {
+
+ return FALSE;
+
+ }
+
+ //
+ // Allocate the ErrorLog Block
+ //
+ VERY_LOUD_DEBUG(DbgPrint("Allocating ErrorLog Block\n");)
+
+ NdisMAllocateSharedMemory(
+ Adapter->MiniportAdapterHandle,
+ sizeof(TOK162_ERRORLOG) + 8,
+ FALSE,
+ (PVOID *) &Adapter->ErrorLog,
+ &Adapter->ErrorLogPhysical
+ );
+
+ //
+ // If the ErrorLog could not be allocated, a NULL pointer will have been
+ // returned.
+ //
+ if (Adapter->ErrorLog == NULL) {
+
+ return FALSE;
+
+ }
+
+ //
+ // Allocate the ReadAdapter Buffer
+ //
+ VERY_LOUD_DEBUG(DbgPrint("Allocating ReadAdapterBuffer\n");)
+
+ NdisMAllocateSharedMemory(
+ Adapter->MiniportAdapterHandle,
+ 4096,
+ FALSE,
+ (PVOID *) &Adapter->AdapterBuf,
+ &Adapter->AdapterBufPhysical
+ );
+
+ VERY_LOUD_DEBUG(DbgPrint("Address of ReadAdapterBuf is %lx\n",(ULONG)Adapter->AdapterBuf);)
+
+ //
+ // If the ReadAdapter Buffer could not be allocated, a NULL
+ // pointer will have been returned.
+ //
+ if (Adapter->AdapterBuf == NULL) {
+
+ return FALSE;
+
+ }
+
+ //
+ // Allocate the Initialization Block
+ //
+ VERY_LOUD_DEBUG(DbgPrint("Allocating Initialization Block\n");)
+
+ NdisMAllocateSharedMemory(
+ Adapter->MiniportAdapterHandle,
+ sizeof(ADAPTER_INITIALIZATION) + 8,
+ FALSE,
+ (PVOID *) &Adapter->InitializationBlock,
+ &Adapter->InitializationBlockPhysical
+ );
+
+ //
+ // If the Initialization Block could not be allocated, a NULL pointer
+ // will have been returned.
+ //
+ if (Adapter->InitializationBlock == NULL) {
+
+ return FALSE;
+
+ }
+
+ //
+ // Allocate the Open Command Block
+ //
+
+ VERY_LOUD_DEBUG(DbgPrint("Allocating Open Command\n");)
+
+ NdisMAllocateSharedMemory(
+ Adapter->MiniportAdapterHandle,
+ sizeof(OPEN_COMMAND) + 8,
+ FALSE,
+ (PVOID *) &Adapter->Open,
+ &Adapter->OpenPhysical
+ );
+
+ VERY_LOUD_DEBUG(DbgPrint(
+ "Address of Open Command is %lx\n",(ULONG)Adapter->Open);)
+
+ //
+ // If the Open Command Block could not be allocated, a NULL pointer
+ // will have been returned.
+ //
+ if (Adapter->Open == NULL) {
+
+ return FALSE;
+
+ }
+
+ //
+ // Allocate the command block queue
+ //
+ VERY_LOUD_DEBUG(DbgPrint("Allocating Command Block Queue\n");)
+
+ NdisMAllocateSharedMemory(
+ Adapter->MiniportAdapterHandle,
+ sizeof(TOK162_SUPER_COMMAND_BLOCK) * (TOK162_NUMBER_OF_CMD_BLOCKS+1),
+ FALSE,
+ (PVOID *) &Adapter->CommandQueue,
+ &Adapter->CommandQueuePhysical
+ );
+
+ //
+ // If the Command Block Queue could not be allocated, a NULL pointer
+ // will have been returned.
+ //
+ if (Adapter->CommandQueue == NULL) {
+
+ return FALSE;
+
+ }
+
+ //
+ // Initialize the command block queue command blocks
+ //
+ for (i = 0, CurrentCommandBlock = Adapter->CommandQueue;
+ i < TOK162_NUMBER_OF_CMD_BLOCKS;
+ i++, CurrentCommandBlock++
+ ) {
+
+ //
+ // Set the state of this command block to free, the
+ // NextPending pointer and Next pointer to null, and
+ // the command timeout state to FALSE
+ //
+ CurrentCommandBlock->Hardware.State = TOK162_STATE_FREE;
+ CurrentCommandBlock->Hardware.NextPending = TOK162_NULL;
+ CurrentCommandBlock->NextCommand = NULL;
+ CurrentCommandBlock->Timeout = FALSE;
+
+ //
+ // Set the Self pointer of the command block
+ //
+ NdisSetPhysicalAddressHigh (CurrentCommandBlock->Self, 0);
+ NdisSetPhysicalAddressLow(
+ CurrentCommandBlock->Self,
+ NdisGetPhysicalAddressLow(Adapter->CommandQueuePhysical) +
+ i * sizeof(TOK162_SUPER_COMMAND_BLOCK));
+
+ //
+ // This is a command block and not a transmit command block
+ //
+ CurrentCommandBlock->CommandBlock = TRUE;
+
+ //
+ // Set the index of this command block
+ //
+ CurrentCommandBlock->CommandBlockIndex = (USHORT)i;
+
+ }
+
+ //
+ // Allocate Flush Buffer Pool
+ //
+ VERY_LOUD_DEBUG(DbgPrint("Allocating Flush Buffer Pool\n");)
+
+ NdisAllocateBufferPool(
+ &Status,
+ (PVOID*)&Adapter->FlushBufferPoolHandle,
+ Adapter->NumberOfReceiveBuffers + Adapter->NumberOfTransmitLists
+ );
+
+ //
+ // If there was a problem allocating the flush buffer pool,
+ // write out an errorlog entry, delete the allocated adapter memory,
+ // and return FALSE
+ //
+ if (Status != NDIS_STATUS_SUCCESS) {
+
+ return FALSE;
+
+ }
+
+ //
+ // Allocate the Transmit Command Queue.
+ //
+ VERY_LOUD_DEBUG(DbgPrint("Allocating Transmit Command Block Queue\n");)
+
+ NdisMAllocateSharedMemory(
+ Adapter->MiniportAdapterHandle,
+ sizeof(TOK162_SUPER_COMMAND_BLOCK) *
+ (Adapter->NumberOfTransmitLists+1),
+ FALSE,
+ (PVOID*)&Adapter->TransmitQueue,
+ &Adapter->TransmitQueuePhysical
+ );
+
+
+ //
+ // If the Transmit Block Queue could not be allocated, a NULL pointer
+ // will have been returned.
+ //
+ if (Adapter->TransmitQueue == NULL) {
+
+ return FALSE;
+
+ }
+
+ //
+ // Initialize the transmit command queue
+ //
+ if (TOK162InitializeTransmitQueue(Adapter) == FALSE) {
+
+ return FALSE;
+ }
+
+ //
+ // Allocate the Receive Queue.
+ //
+ VERY_LOUD_DEBUG(DbgPrint("Allocating Receive Queue\n");)
+
+ NdisMAllocateSharedMemory(
+ Adapter->MiniportAdapterHandle,
+ sizeof(TOK162_SUPER_RECEIVE_LIST) *
+ (Adapter->NumberOfReceiveBuffers+1),
+ FALSE,
+ (PVOID*)&Adapter->ReceiveQueue,
+ &Adapter->ReceiveQueuePhysical
+ );
+
+ //
+ // If the Receive Queue could not be allocated, a NULL pointer will
+ // have been returned.
+ //
+ if (Adapter->ReceiveQueue == NULL) {
+
+ return FALSE;
+
+ }
+
+ //
+ // Initialize the receieve queue entries. First zero out the entire
+ // queue memory.
+ //
+ NdisZeroMemory(
+ Adapter->ReceiveQueue,
+ sizeof(TOK162_SUPER_RECEIVE_LIST) * Adapter->NumberOfReceiveBuffers
+ );
+
+ //
+ // Allocate the receive buffers and attach them to the Receive
+ // Queue entries.
+ //
+ VERY_LOUD_DEBUG(DbgPrint("Allocating Receive Buffers\n");)
+
+ for (i = 0, CurrentReceiveEntry = Adapter->ReceiveQueue;
+ i < Adapter->NumberOfReceiveBuffers;
+ i++, CurrentReceiveEntry++
+ ) {
+
+ VERY_LOUD_DEBUG(DbgPrint("ReceiveEntry[%d] = %08x\n",i,
+ CurrentReceiveEntry);)
+
+ NdisMAllocateSharedMemory(
+ Adapter->MiniportAdapterHandle,
+ Adapter->ReceiveBufferSize+8,
+ TRUE,
+ &CurrentReceiveEntry->ReceiveBuffer,
+ &CurrentReceiveEntry->ReceiveBufferPhysical
+ );
+
+ VERY_LOUD_DEBUG(DbgPrint("Receive Buffer is %08x\n",CurrentReceiveEntry->ReceiveBuffer);)
+
+ //
+ // If the current buffer could not be allocated, write the errorlog
+ // entry, delete allocated adapter memory, and return FALSE
+ //
+ if (!CurrentReceiveEntry->ReceiveBuffer) {
+
+ return FALSE;
+
+ }
+
+ //
+ // Build flush buffers
+ //
+ NdisAllocateBuffer(
+ &Status,
+ &CurrentReceiveEntry->FlushBuffer,
+ Adapter->FlushBufferPoolHandle,
+ CurrentReceiveEntry->ReceiveBuffer,
+ Adapter->ReceiveBufferSize
+ );
+
+ if (Status != NDIS_STATUS_SUCCESS) {
+
+ return FALSE;
+
+ }
+
+ //
+ // Initialize receive lists
+ //
+ NdisFlushBuffer(CurrentReceiveEntry->FlushBuffer, FALSE);
+
+ //
+ // Set the CSTAT to indicate this buffer is free
+ //
+ CurrentReceiveEntry->Hardware.CSTAT = RECEIVE_CSTAT_REQUEST_RESET;
+
+ //
+ // Set the size of the buffer
+ //
+ CurrentReceiveEntry->Hardware.DataCount1 =
+ BYTE_SWAP(Adapter->ReceiveBufferSize);
+
+ //
+ // Set the address of the buffer
+ //
+ CurrentReceiveEntry->Hardware.PhysicalAddress1 = BYTE_SWAP_ULONG(
+ NdisGetPhysicalAddressLow(
+ CurrentReceiveEntry->ReceiveBufferPhysical));
+
+ //
+ // Set the self-referencing pointer
+ //
+ NdisSetPhysicalAddressHigh (CurrentReceiveEntry->Self, 0);
+ NdisSetPhysicalAddressLow(
+ CurrentReceiveEntry->Self,
+ NdisGetPhysicalAddressLow(Adapter->ReceiveQueuePhysical) +
+ i * sizeof(TOK162_SUPER_RECEIVE_LIST));
+
+ //
+ // Create a circular list of receive buffers. For every one but the
+ // last, set the forward pointer to the next entry. The last entry
+ // has to point to the first entry (queue head).
+ //
+ if (i != (Adapter->NumberOfReceiveBuffers - 1)) {
+
+ CurrentReceiveEntry->Hardware.ForwardPointer = BYTE_SWAP_ULONG(
+ NdisGetPhysicalAddressLow(Adapter->ReceiveQueuePhysical) +
+ (i + 1) * sizeof(TOK162_SUPER_RECEIVE_LIST));
+
+ CurrentReceiveEntry->NextEntry = (PTOK162_SUPER_RECEIVE_LIST)(
+ (PUCHAR)(Adapter->ReceiveQueue) +
+ (i+1) * (sizeof(TOK162_SUPER_RECEIVE_LIST)));
+
+ } else {
+
+ CurrentReceiveEntry->Hardware.ForwardPointer = BYTE_SWAP_ULONG(
+ NdisGetPhysicalAddressLow(Adapter->ReceiveQueuePhysical)
+ );
+
+ CurrentReceiveEntry->NextEntry = Adapter->ReceiveQueue;
+
+ }
+
+ }
+
+ //
+ // If we made it this far, everything is ok. Return TRUE.
+ //
+ return TRUE;
+
+}
+
+
+VOID
+TOK162DeleteAdapterMemory(
+ IN PTOK162_ADAPTER Adapter
+ )
+
+/*++
+
+Routine Description:
+
+ This routine deallocates memory for:
+
+ - SCB
+
+ - SSB
+
+ - ErrorLog Block
+
+ - ReadAdapter Block
+
+ - Initialization Block
+
+ - Open Command Block
+
+ - Command Queue
+
+ - Transmit Command Queue
+
+ - Transmit Buffers
+
+ - Flush Buffer Pool
+
+ - Receive Queue
+
+ - Receive Buffers
+
+ - Receive Flush Buffers
+
+Arguments:
+
+ Adapter - The adapter to deallocate memory for.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+
+ //
+ // Pointer to a command block used to initialize the command blocks
+ // and the transmit command blocks.
+ //
+ PTOK162_SUPER_COMMAND_BLOCK CommandBlock;
+
+ //
+ // Iteration variable
+ //
+ USHORT i;
+
+ //
+ // Display to the debugger where we are
+ //
+ VERY_LOUD_DEBUG(DbgPrint("In delete adapter memory\n");)
+
+ //
+ // Free the SCB
+ //
+ if (Adapter->Scb != NULL) {
+
+ VERY_LOUD_DEBUG(DbgPrint("Freeing SCB\n");)
+
+ NdisMFreeSharedMemory(
+ Adapter->MiniportAdapterHandle,
+ sizeof(SCB) + 8,
+ FALSE,
+ Adapter->Scb,
+ Adapter->ScbPhysical
+ );
+
+ }
+
+ //
+ // Free the SSB
+ //
+ if (Adapter->Ssb != NULL) {
+
+ VERY_LOUD_DEBUG(DbgPrint("Freeing SSB - %x %x\n",Adapter->Ssb,
+ Adapter->SsbPhysical);)
+
+ NdisMFreeSharedMemory(
+ Adapter->MiniportAdapterHandle,
+ sizeof(SSB) + 8,
+ FALSE,
+ Adapter->Ssb,
+ Adapter->SsbPhysical
+ );
+
+ }
+
+ //
+ // Free the errorlog block
+ //
+ if (Adapter->ErrorLog != NULL) {
+
+ VERY_LOUD_DEBUG(DbgPrint("Freeing ErrorLog - %x\n",
+ Adapter->ErrorLog);)
+
+ NdisMFreeSharedMemory(
+ Adapter->MiniportAdapterHandle,
+ sizeof(TOK162_ERRORLOG) + 8,
+ FALSE,
+ Adapter->ErrorLog,
+ Adapter->ErrorLogPhysical
+ );
+
+ }
+
+ //
+ // Free the read adapter block
+ //
+ if (Adapter->AdapterBuf != NULL) {
+
+ VERY_LOUD_DEBUG(DbgPrint("Freeing Read Adapter Block\n");)
+
+ NdisMFreeSharedMemory(
+ Adapter->MiniportAdapterHandle,
+ 4096,
+ FALSE,
+ Adapter->AdapterBuf,
+ Adapter->AdapterBufPhysical
+ );
+
+ }
+
+ //
+ // Free the initialization block
+ //
+ if (Adapter->InitializationBlock != NULL) {
+
+ VERY_LOUD_DEBUG(DbgPrint("Freeing Initialization Block\n");)
+
+ NdisMFreeSharedMemory(
+ Adapter->MiniportAdapterHandle,
+ sizeof(ADAPTER_INITIALIZATION) + 8,
+ FALSE,
+ Adapter->InitializationBlock,
+ Adapter->InitializationBlockPhysical
+ );
+
+ }
+
+ //
+ // Free the open command block
+ //
+ if (Adapter->Open != NULL) {
+
+ VERY_LOUD_DEBUG(DbgPrint("Freeing Open Block - %x\n",Adapter->Open);)
+
+ NdisMFreeSharedMemory(
+ Adapter->MiniportAdapterHandle,
+ sizeof(OPEN_COMMAND) + 8,
+ FALSE,
+ Adapter->Open,
+ Adapter->OpenPhysical
+ );
+
+ }
+
+ //
+ // Free the command queue
+ //
+ if (Adapter->CommandQueue != NULL) {
+
+ VERY_LOUD_DEBUG(DbgPrint("Freeing CommandQueue\n");)
+
+ NdisMFreeSharedMemory(
+ Adapter->MiniportAdapterHandle,
+ sizeof(TOK162_SUPER_COMMAND_BLOCK) *
+ (TOK162_NUMBER_OF_CMD_BLOCKS + 1),
+ FALSE,
+ Adapter->CommandQueue,
+ Adapter->CommandQueuePhysical
+ );
+
+ }
+
+ //
+ // Free the transmit command queue, transmit buffers, and flush buffers
+ //
+ if (Adapter->TransmitQueue != NULL) {
+
+ VERY_LOUD_DEBUG(DbgPrint("Freeing TransmitQueue\n");)
+
+ //
+ // First the buffers
+ //
+ for (i = 0, CommandBlock = Adapter->TransmitQueue;
+ i < Adapter->NumberOfTransmitLists;
+ i++,CommandBlock++
+ ) {
+
+ if (CommandBlock->TOK162BufferAddress != ((ULONG)NULL)) {
+
+ NdisMFreeSharedMemory(
+ Adapter->MiniportAdapterHandle,
+ Adapter->ReceiveBufferSize,
+ FALSE,
+ (PVOID)(CommandBlock->TOK162BufferAddress),
+ CommandBlock->TOK162BufferPhysicalAddress
+ );
+
+ }
+
+ if (CommandBlock->FlushBuffer != NULL) {
+
+ NdisFreeBuffer(
+ CommandBlock->FlushBuffer
+ );
+
+ }
+
+ }
+
+ //
+ // Now the queue itself
+ //
+ NdisMFreeSharedMemory(
+ Adapter->MiniportAdapterHandle,
+ sizeof(TOK162_SUPER_COMMAND_BLOCK) *
+ Adapter->NumberOfTransmitLists,
+ FALSE,
+ Adapter->TransmitQueue,
+ Adapter->TransmitQueuePhysical
+ );
+
+ }
+
+ //
+ // Free the receive queue, receive buffers, and flush buffers
+ //
+ if (Adapter->ReceiveQueue != NULL) {
+
+ //
+ // Pointer to current Receive Entry being deallocated.
+ //
+ PTOK162_SUPER_RECEIVE_LIST CurrentReceiveEntry;
+
+ //
+ // Simple iteration counter.
+ //
+ UINT i;
+
+ VERY_LOUD_DEBUG(DbgPrint("Freeing ReceiveCommandQueue\n");)
+
+ for (i = 0, CurrentReceiveEntry = Adapter->ReceiveQueue;
+ i < Adapter->NumberOfReceiveBuffers;
+ i++, CurrentReceiveEntry++
+ ) {
+
+ if (CurrentReceiveEntry->ReceiveBuffer) {
+ NdisMFreeSharedMemory(
+ Adapter->MiniportAdapterHandle,
+ Adapter->ReceiveBufferSize,
+ TRUE,
+ CurrentReceiveEntry->ReceiveBuffer,
+ CurrentReceiveEntry->ReceiveBufferPhysical
+ );
+
+
+ if (CurrentReceiveEntry->FlushBuffer != NULL) {
+
+ NdisFreeBuffer(
+ CurrentReceiveEntry->FlushBuffer
+ );
+
+ }
+ }
+
+ }
+
+ NdisMFreeSharedMemory(
+ Adapter->MiniportAdapterHandle,
+ sizeof(TOK162_SUPER_RECEIVE_LIST) *
+ Adapter->NumberOfReceiveBuffers,
+ FALSE,
+ Adapter->ReceiveQueue,
+ Adapter->ReceiveQueuePhysical
+ );
+
+ }
+
+ //
+ // Free the flush buffer pool handle
+ //
+ if (Adapter->FlushBufferPoolHandle) {
+
+ VERY_LOUD_DEBUG(DbgPrint("Freeing BufferPool\n");)
+
+ NdisFreeBufferPool(
+ Adapter->FlushBufferPoolHandle
+ );
+
+ }
+
+}
+
+
+extern
+VOID
+TOK162Halt(
+ IN NDIS_HANDLE MiniportAdapterContext
+ )
+
+/*++
+
+Routine Description:
+
+ TOK162Halt removes an adapter previously initialized.
+
+Arguments:
+
+ MiniportAdapterContext - The context value that the Miniport returned
+ from Tok162Initialize; actually is pointer to
+ a TOK162_ADAPTER.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+ //
+ // Pointer to an adapter structure. Makes Context (passed in value)
+ // a structure we can deal with.
+ //
+ PTOK162_ADAPTER Adapter =
+ PTOK162_ADAPTER_FROM_CONTEXT_HANDLE(MiniportAdapterContext);
+
+ //
+ // Shut down the chip.
+ //
+ TOK162DisableInterrupt(Adapter);
+
+ //
+ // Return resources to the wrapper
+ //
+ NdisMDeregisterInterrupt(&Adapter->Interrupt);
+
+ NdisMDeregisterIoPortRange(Adapter->MiniportAdapterHandle,
+ Adapter->PortIOBase,
+ 0x30,
+ Adapter->PortIOAddress
+ );
+
+ NdisMFreeMapRegisters(Adapter->MiniportAdapterHandle);
+
+ //
+ // Free the allocated memory for the adapter-related structures
+ //
+ TOK162DeleteAdapterMemory(Adapter);
+
+ //
+ // Finally, free the allocated memory for the adapter structure itself
+ //
+ TOK162_FREE_PHYS(Adapter);
+
+}
+
+
+extern
+VOID
+TOK162Shutdown(
+ IN NDIS_HANDLE MiniportAdapterContext
+ )
+
+/*++
+
+Routine Description:
+
+ TOK162Shutdown-- removes an adapter previously initialized.
+
+Arguments:
+
+ MiniportAdapterContext - The context value that the Miniport returned
+ from Tok162Initialize; actually is pointer to
+ a TOK162_ADAPTER.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+ //
+ // Pointer to an adapter structure. Makes Context (passed in value)
+ // a structure we can deal with.
+ //
+
+ PTOK162_ADAPTER Adapter =
+ PTOK162_ADAPTER_FROM_CONTEXT_HANDLE(MiniportAdapterContext);
+
+ //
+ // Simply remove ourselves from the ring by doing a reset of the
+ // adapter.
+ //
+ TOK162ResetAdapter(Adapter);
+
+}
+
+
+NDIS_STATUS
+TOK162Reset(
+ OUT PBOOLEAN AddressingReset,
+ IN NDIS_HANDLE MiniportAdapterContext
+ )
+/*++
+
+Routine Description:
+
+ The TOK162Reset request instructs the Miniport to issue a hardware reset
+ to the network adapter. The driver also resets its software state. See
+ the description of NdisMReset for a detailed description of this request.
+
+Arguments:
+
+ MiniportAdapterContext - Pointer to the adapter structure.
+
+Return Value:
+
+ The function value is the status of the operation.
+--*/
+
+{
+ //
+ // Pointer to an adapter structure. Makes Context (passed in value)
+ // a structure we can deal with.
+ //
+ PTOK162_ADAPTER Adapter =
+ PTOK162_ADAPTER_FROM_CONTEXT_HANDLE(MiniportAdapterContext);
+
+#if DBG
+ Tok162Debug = 0x08;
+#endif
+
+ VERY_LOUD_DEBUG(DbgPrint("Reset called\n");)
+
+ //
+ // Make sure we aren't already doing a reset.
+ //
+ if (Adapter->ResetInProgress == FALSE) {
+
+ Adapter->ResetInProgress = TRUE;
+
+ Adapter->ResetState = CheckReset;
+
+ TOK162SetupForReset(
+ Adapter
+ );
+
+ return NDIS_STATUS_PENDING;
+
+ } else {
+
+ //
+ // If we are doing a reset currently, return this fact.
+ //
+ return NDIS_STATUS_RESET_IN_PROGRESS;
+
+ }
+
+}
+
+
+BOOLEAN
+TOK162CheckForHang(
+ IN NDIS_HANDLE MiniportAdapterContext
+ )
+
+/*++
+
+Routine Description:
+
+ This routine is called by the wrapper to determine if the adapter
+ is hung.
+
+Arguments:
+
+ Context - Really a pointer to the adapter.
+
+Return Value:
+
+ None.
+
+--*/
+{
+
+ //
+ // Pointer to an adapter structure. Makes Context (passed in value)
+ // a structure we can deal with.
+ //
+ PTOK162_ADAPTER Adapter =
+ PTOK162_ADAPTER_FROM_CONTEXT_HANDLE(MiniportAdapterContext);
+
+ //
+ // Variable pointing to the outstanding command. Used to make the
+ // code easier to read (could use Adapter->CommandOnCard).
+ //
+ PTOK162_SUPER_COMMAND_BLOCK FirstPendingCommand = Adapter->CommandOnCard;
+
+ //
+ // Variable pointing to the outstanding transmit. Used to make the
+ // code easier to read (could use Adapter->TransmitOnCard).
+ //
+ PTOK162_SUPER_COMMAND_BLOCK FirstPendingTransmit =
+ Adapter->TransmitOnCard;
+
+ //
+ // If we're in the middle of a reset, just return false
+ //
+ if (Adapter->ResetInProgress == TRUE) {
+
+ return FALSE;
+
+ }
+
+ //
+ // First see if there is a command outstanding
+ //
+ if (FirstPendingCommand != NULL) {
+
+ //
+ // See if the command block has timed-out.
+ //
+ if (FirstPendingCommand->Timeout) {
+
+ //
+ // See if we have given it enough time
+ //
+ if ( FirstPendingCommand->TimeoutCount >= 40) {
+
+ LOUD_DEBUG(DbgPrint("Returning True from checkforhang\n");)
+ return TRUE;
+
+ } else {
+
+ FirstPendingCommand->TimeoutCount++;
+
+ }
+
+ } else {
+
+ //
+ // Mark the current command as timed out and get the clock
+ // rolling.
+ //
+ FirstPendingCommand->Timeout = TRUE;
+ FirstPendingCommand->TimeoutCount = 0;
+
+ }
+
+ }
+
+ //
+ // Check if there is an outstanding transmit
+ //
+ if (FirstPendingTransmit != NULL) {
+
+ //
+ // See if the transmit has timed-out.
+ //
+ if (FirstPendingTransmit->Timeout) {
+
+ //
+ // See if we have given it enough time
+ //
+ if ( FirstPendingTransmit->TimeoutCount >= 40) {
+
+ //
+ // Give up, the card appears dead.
+ //
+ return TRUE;
+
+ } else {
+
+ FirstPendingTransmit->TimeoutCount++;
+
+ }
+
+ } else {
+
+ //
+ // Set outstanding transmit to timeout and start the clock
+ // rolling.
+ //
+ FirstPendingTransmit->Timeout = TRUE;
+ FirstPendingTransmit->TimeoutCount = 0;
+
+ }
+
+ }
+
+ //
+ // If we got here, we aren't hung.
+ //
+ return FALSE;
+}
+
+
+NDIS_STATUS
+TOK162TransferData(
+ OUT PNDIS_PACKET Packet,
+ OUT PUINT BytesTransferred,
+ IN NDIS_HANDLE MiniportAdapterContext,
+ IN NDIS_HANDLE MiniportReceiveContext,
+ IN UINT ByteOffset,
+ IN UINT BytesToTransfer
+ )
+
+/*++
+
+Routine Description:
+
+ A protocol calls the TOK162TransferData request (indirectly via
+ NdisTransferData) from within its Receive event handler
+ to instruct the Miniport to copy the contents of the received packet
+ a specified packet buffer.
+
+Arguments:
+
+ MiniportAdapterContext - The context value returned by the driver when the
+ adapter was initialized. In reality this is a
+ pointer to TOK162_ADAPTER.
+
+ MiniportReceiveContext - The context value passed by the driver on its
+ call to NdisMIndicateReceive. The driver can
+ use this value to determine which packet, on
+ which adapter, is being received.
+
+ ByteOffset - An unsigned integer specifying the offset within
+ the received packet at which the copy is to begin.
+ If the entire packet is to be copied,
+ ByteOffset must be zero.
+
+ BytesToTransfer - An unsigned integer specifying the number of
+ bytes to copy. It is legal to transfer zero
+ bytes; this has no effect. If the sum of
+ ByteOffset and BytesToTransfer is greater than
+ the size of the received packet, then the
+ remainder of the packet (starting from
+ ByteOffset) is transferred, and the trailing
+ portion of the receive buffer is not modified.
+
+ Packet - A pointer to a descriptor for the packet storage
+ into which the MAC is to copy the received packet.
+
+ BytesTransfered - A pointer to an unsigned integer. The miniport
+ writes the actual number of bytes transferred
+ into this location. This value is not valid if
+ the return status is STATUS_PENDING.
+
+Return Value:
+
+ The function value is the status of the operation.
+
+--*/
+{
+
+ //
+ // Pointer to an adapter structure. Makes Context (passed in value)
+ // a structure we can deal with.
+ //
+ PTOK162_ADAPTER Adapter =
+ PTOK162_ADAPTER_FROM_CONTEXT_HANDLE(MiniportAdapterContext);
+
+ //
+ // Holds the count of the number of ndis buffers comprising the
+ // destination packet.
+ //
+ UINT DestinationBufferCount;
+
+ //
+ // Points to the buffer into which we are putting data.
+ //
+ PNDIS_BUFFER DestinationCurrentBuffer;
+
+ //
+ // Points to the location in Buffer from which we are extracting data.
+ //
+ PUCHAR SourceCurrentAddress;
+
+ //
+ // Holds the virtual address of the current destination buffer.
+ //
+ PVOID DestinationVirtualAddress;
+
+ //
+ // Holds the length of the current destination buffer.
+ //
+ UINT DestinationCurrentLength;
+
+ //
+ // Keep a local variable of BytesTransferred so we aren't referencing
+ // through a pointer.
+ //
+ UINT LocalBytesTransferred = 0;
+
+ //
+ // Display where we are on the debugger and log where we are.
+ //
+ LOUD_DEBUG(DbgPrint("TOK162!Transfer Data called\n");)
+ IF_LOG('n');
+
+ //
+ // Display number of bytes to transfer on the debugger
+ //
+ VERY_LOUD_DEBUG(DbgPrint("Copying %u bytes\n",BytesToTransfer);)
+
+ //
+ // Initialize the number of bytes transferred to 0
+ //
+ *BytesTransferred = 0;
+
+ //
+ // If we don't have any more to transfer, we're done
+ //
+ if (BytesToTransfer == 0) {
+
+ return NDIS_STATUS_SUCCESS;
+
+ }
+
+ //
+ // Get the first buffer of the destination.
+ //
+ NdisQueryPacket(
+ Packet,
+ NULL,
+ &DestinationBufferCount,
+ &DestinationCurrentBuffer,
+ NULL
+ );
+
+ //
+ // Could have a null packet. If so, we are done.
+ //
+ if (DestinationBufferCount == 0) {
+
+ return NDIS_STATUS_SUCCESS;
+
+ }
+
+ //
+ // Get information on the buffer.
+ //
+ NdisQueryBuffer(
+ DestinationCurrentBuffer,
+ &DestinationVirtualAddress,
+ &DestinationCurrentLength
+ );
+
+ //
+ // Set up the source address.
+ //
+ SourceCurrentAddress = (PCHAR)(MiniportReceiveContext) + ByteOffset;
+
+ //
+ // Do the actual transfer from source to destination
+ //
+ while (LocalBytesTransferred < BytesToTransfer) {
+
+ //
+ // Check to see whether we've exhausted the current destination
+ // buffer. If so, move onto the next one.
+ //
+ if (!DestinationCurrentLength) {
+
+ NdisGetNextBuffer(
+ DestinationCurrentBuffer,
+ &DestinationCurrentBuffer
+ );
+
+ if (!DestinationCurrentBuffer) {
+
+ //
+ // We've reached the end of the packet. We return
+ // with what we've done so far. (Which must be shorter
+ // than requested.)
+ //
+
+ break;
+
+ }
+
+ NdisQueryBuffer(
+ DestinationCurrentBuffer,
+ &DestinationVirtualAddress,
+ &DestinationCurrentLength
+ );
+
+ continue;
+
+ }
+
+ //
+ // Copy the data.
+ //
+ {
+ //
+ // Holds the amount of data to move.
+ //
+ UINT AmountToMove;
+
+ //
+ // Holds the amount desired remaining.
+ //
+ UINT Remaining = BytesToTransfer - LocalBytesTransferred;
+
+
+ AmountToMove = DestinationCurrentLength;
+
+ AmountToMove = ((Remaining < AmountToMove)?
+ (Remaining):(AmountToMove));
+
+ NdisMoveMemory(
+ DestinationVirtualAddress,
+ SourceCurrentAddress,
+ AmountToMove
+ );
+
+ //
+ // Update pointers and counters
+ //
+ SourceCurrentAddress += AmountToMove;
+ LocalBytesTransferred += AmountToMove;
+ DestinationCurrentLength -= AmountToMove;
+
+ }
+
+ }
+
+ //
+ // Indicate how many bytes were transferred
+ //
+ *BytesTransferred = LocalBytesTransferred;
+
+ //
+ // Display total bytes transferred on debugger
+ //
+ VERY_LOUD_DEBUG(DbgPrint("Total bytes transferred = %x\n",
+ *BytesTransferred);)
+
+
+ //
+ // Log the fact that we are leaving transferdata
+ //
+ IF_LOG('N');
+
+ return NDIS_STATUS_SUCCESS;
+
+}
+
+
+BOOLEAN
+TOK162InitializeTransmitQueue(
+ IN PTOK162_ADAPTER Adapter
+ )
+/*++
+
+Routine Description:
+
+ This routine initializes the transmit queue
+
+Arguments:
+
+ Adapter - Current Adapter structure
+
+Return Value:
+
+ None.
+
+--*/
+{
+ //
+ // Local pointer to command blocks
+ //
+ PTOK162_SUPER_COMMAND_BLOCK CurrentCommandBlock;
+
+ //
+ // Counter variable
+ //
+ USHORT i;
+
+ //
+ // Status variable
+ //
+ NDIS_STATUS Status;
+
+ //
+ // Initialize the Adapter structure fields associate with transmit lists
+ //
+ Adapter->NextTransmitBlock = 0;
+ Adapter->NumberOfAvailableTransmitBlocks =
+ Adapter->NumberOfTransmitLists;
+
+ //
+ // Zero the memory of the transmit queue
+ //
+ NdisZeroMemory(
+ Adapter->TransmitQueue,
+ sizeof(TOK162_SUPER_COMMAND_BLOCK) * Adapter->NumberOfTransmitLists
+ );
+
+ //
+ // Put the Transmit Command Blocks into a known state.
+ //
+ for (i = 0, CurrentCommandBlock = Adapter->TransmitQueue;
+ i < Adapter->NumberOfTransmitLists;
+ i++, CurrentCommandBlock++
+ ) {
+
+ //
+ // Set the next command pointer to NULL
+ //
+ CurrentCommandBlock->NextCommand = NULL;
+
+ //
+ // Set the self-referential pointer
+ //
+ NdisSetPhysicalAddressHigh (CurrentCommandBlock->Self, 0);
+ NdisSetPhysicalAddressLow(
+ CurrentCommandBlock->Self,
+ NdisGetPhysicalAddressLow(Adapter->TransmitQueuePhysical) +
+ i * sizeof(TOK162_SUPER_COMMAND_BLOCK));
+
+ CurrentCommandBlock->PhysicalTransmitEntry =
+ NdisGetPhysicalAddressLow(CurrentCommandBlock->Self);
+
+ //
+ // This is a transmit block, not a command block
+ //
+ CurrentCommandBlock->CommandBlock = FALSE;
+
+ //
+ // Set the index and the timeout values
+ //
+ CurrentCommandBlock->CommandBlockIndex = i;
+ CurrentCommandBlock->Timeout = FALSE;
+
+ //
+ // Initialize the hardware portion of the command block.
+ // Set the state to free and next pending to NULL.
+ //
+ CurrentCommandBlock->Hardware.State = TOK162_STATE_FREE;
+ CurrentCommandBlock->Hardware.NextPending = TOK162_NULL;
+
+ //
+ // Allocate the transmit buffer associated with this transmit
+ // list entry
+ //
+ NdisMAllocateSharedMemory(
+ Adapter->MiniportAdapterHandle,
+ Adapter->ReceiveBufferSize + 8,
+ FALSE,
+ &((PVOID)CurrentCommandBlock->TOK162BufferAddress),
+ &CurrentCommandBlock->TOK162BufferPhysicalAddress
+ );
+
+ LOUD_DEBUG(DbgPrint("XMITBuffer %u = %lx %lx\n",i,
+ CurrentCommandBlock->TOK162BufferAddress,
+ NdisGetPhysicalAddressLow(
+ CurrentCommandBlock->TOK162BufferPhysicalAddress));)
+
+ //
+ // If the allocation failed, write the errorlog and return FALSE
+ //
+ if (CurrentCommandBlock->TOK162BufferAddress == (ULONG)NULL) {
+
+ NdisWriteErrorLogEntry(
+ Adapter->MiniportAdapterHandle,
+ NDIS_ERROR_CODE_OUT_OF_RESOURCES,
+ 0
+ );
+
+ return FALSE;
+
+ }
+
+//
+// Remove the following section because it isn't needed. Flush buffers on
+// transmits appear to be causing hangs on mips machines.
+//
+#if 0
+ //
+ // Build flush buffers
+ //
+ NdisAllocateBuffer(
+ &Status,
+ &CurrentCommandBlock->FlushBuffer,
+ Adapter->FlushBufferPoolHandle,
+ (PVOID)CurrentCommandBlock->TOK162BufferAddress,
+ Adapter->ReceiveBufferSize
+ );
+
+ if (Status != NDIS_STATUS_SUCCESS) {
+
+ return FALSE;
+
+ }
+#endif
+ }
+
+ //
+ // If we got here, everything is ok. Return TRUE.
+ //
+ return TRUE;
+
+}
diff --git a/private/ntos/ndis/ibmtok2i/tok162.rc b/private/ntos/ndis/ibmtok2i/tok162.rc
new file mode 100644
index 000000000..f211525d9
--- /dev/null
+++ b/private/ntos/ndis/ibmtok2i/tok162.rc
@@ -0,0 +1,38 @@
+#include <windows.h>
+#include <ntverp.h>
+
+/*-----------------------------------------------*/
+/* the following lines are specific to this file */
+/*-----------------------------------------------*/
+
+/* VER_FILETYPE, VER_FILESUBTYPE, VER_FILEDESCRIPTION_STR
+ * and VER_INTERNALNAME_STR must be defined before including COMMON.VER
+ * The strings don't need a '\0', since common.ver has them.
+ */
+#define VER_FILETYPE VFT_DRV
+/* possible values: VFT_UNKNOWN
+ VFT_APP
+ VFT_DLL
+ VFT_DRV
+ VFT_FONT
+ VFT_VXD
+ VFT_STATIC_LIB
+*/
+#define VER_FILESUBTYPE VFT2_DRV_NETWORK
+/* possible values VFT2_UNKNOWN
+ VFT2_DRV_PRINTER
+ VFT2_DRV_KEYBOARD
+ VFT2_DRV_LANGUAGE
+ VFT2_DRV_DISPLAY
+ VFT2_DRV_MOUSE
+ VFT2_DRV_NETWORK
+ VFT2_DRV_SYSTEM
+ VFT2_DRV_INSTALLABLE
+ VFT2_DRV_SOUND
+ VFT2_DRV_COMM
+*/
+#define VER_FILEDESCRIPTION_STR "IBM Token Ring 16/4 Adapter II ISA Network Driver"
+#define VER_INTERNALNAME_STR "IBMTOK2I.SYS"
+#define VER_ORIGINALFILENAME_STR "IBMTOK2I.SYS"
+
+#include "common.ver"
diff --git a/private/ntos/ndis/ibmtok2i/tok162hw.h b/private/ntos/ndis/ibmtok2i/tok162hw.h
new file mode 100644
index 000000000..d0cf26ab3
--- /dev/null
+++ b/private/ntos/ndis/ibmtok2i/tok162hw.h
@@ -0,0 +1,1382 @@
+/*++
+
+Copyright (c) 1990 Microsoft Corporation
+
+Module Name:
+
+ tokhrd.h
+
+Abstract:
+
+ The hardware-related definitions for the IBM Token-Ring 16/4 II
+ ISA driver.
+
+Author:
+
+ Kevin Martin (kevinma) 1-Feb-1994
+
+Environment:
+
+ Architecturally, there is an assumption in this driver that we are
+ on a little endian machine.
+
+Notes:
+
+ References to "IBM Spec" refer to the IBM "Supplement to the LAN
+ Technical Reference (Token-Ring Network 16/4 Adapter II)" Specification.
+ The document number is - SD21-052-00.
+
+ References to "TI Spec" refer to the Texas Instruments "TMS380 Second-
+ Generation Token Ring" User's Guide. The document number is - SPWU005.
+
+Revision History:
+
+--*/
+
+//
+// Pack everything on word boundaries
+//
+#include <pshpack2.h>
+
+//
+// Define "Physical Addresses" which are ULONG in size. The card
+// wants physical addresses.
+//
+typedef ULONG TOK162_PHYSICAL_ADDRESS, *PTOK162_PHYSICAL_ADDRESS;
+
+
+//
+// The length of an address (network) is 6 bytes
+//
+#define TOK162_LENGTH_OF_ADDRESS 6
+
+//
+// Define a NULL pointer
+//
+#define TOK162_NULL ((TOK162_PHYSICAL_ADDRESS)(-1L))
+
+//
+// Default number of command blocks
+//
+#define TOK162_NUMBER_OF_CMD_BLOCKS 4
+
+//
+// Burst size for transmit and receive DMA. A zero tells the adapter to
+// use the size of the transfer as the burst size.
+//
+// IBM Spec, Page 21
+
+#define TOK162_BURST_SIZE 0
+
+//
+// Number of retries to attempt after a DMA error
+//
+#define TOK162_DMA_RETRIES 0x0303
+
+//
+// Minimum packet size for a valid transfer/receive
+//
+#define MINIMUM_TOKENRING_PACKET_SIZE 32
+
+//
+// Default packet header size
+//
+#define TOK162_HEADER_SIZE 32
+
+//
+// TOK162 Receive/Command Block States
+//
+#define TOK162_STATE_FREE ((USHORT)0x0000)
+#define TOK162_STATE_EXECUTING ((USHORT)0x0001)
+#define TOK162_STATE_WAIT_FOR_ADAPTER ((USHORT)0x0002)
+
+//
+// Start of I/O ports based on switch settings.
+//
+// IBM Spec, Page 9.
+//
+#define BASE_OPTION_ZERO 0x86A0
+#define BASE_OPTION_ONE 0xC6A0
+#define BASE_OPTION_TWO 0xA6A0
+#define BASE_OPTION_THREE 0xE6A0
+#define BASE_OPTION_FOUR 0x96A0
+#define BASE_OPTION_FIVE 0xD6A0
+#define BASE_OPTION_SIX 0xB6A0
+#define BASE_OPTION_SEVEN 0xF6A0
+
+//
+// Offsets from above of the actual ports used.
+//
+// IBM Spec, Page 4.
+//
+#define PORT_OFFSET_DATA 0x0000
+#define PORT_OFFSET_DATA_AUTO_INC 0x0002
+#define PORT_OFFSET_ADDRESS 0x0004
+#define PORT_OFFSET_STATUS 0x0006
+#define PORT_OFFSET_COMMAND 0x0006
+#define PORT_OFFSET_ADAPTER_RESET 0x0008
+#define PORT_OFFSET_ADAPTER_ENABLE 0x000A
+#define PORT_OFFSET_SWITCH_INT_DISABLE 0x000C
+#define PORT_OFFSET_SWITCH_INT_ENABLE 0x000E
+
+//
+// Macro to write a ULONG variable to a register on the adapter
+//
+#define WRITE_ADAPTER_ULONG(a, p, v) \
+ NdisRawWritePortUshort((ULONG) (a)->PortIOAddress + (p), \
+ (ULONG) (v))
+
+//
+// Macro to read a ULONG variable from a register on the adapter
+//
+#define READ_ADAPTER_ULONG(a, p, v) \
+ NdisRawReadPortUshort((ULONG) (a)->PortIOAddress + (p), \
+ (PULONG) (v))
+
+//
+// Macro to write a USHORT variable to a register on the adapter
+//
+#define WRITE_ADAPTER_USHORT(a, p, v) \
+ NdisRawWritePortUshort((ULONG) (a)->PortIOAddress + (p), \
+ (USHORT) (v))
+
+//
+// Macro to read a USHORT variable from a register on the adapter
+//
+#define READ_ADAPTER_USHORT(a, p, v) \
+ NdisRawReadPortUshort((ULONG) (a)->PortIOAddress + (p), \
+ (PUSHORT) (v))
+
+//
+// Macro to write a CHAR variable to a register on the adapter
+//
+#define WRITE_ADAPTER_UCHAR(a, p, v) \
+ NdisRawWritePortUchar((ULONG)(a)->PortIOAddress + (p), \
+ (UCHAR)(v))
+
+//
+// Macro to read a ULONG variable from a register on the adapter
+//
+#define READ_ADAPTER_UCHAR(a, p, v) \
+ NdisRawReadPortUchar((ULONG)(a)->PortIOAddress + (p), \
+ (PUCHAR)(v))
+
+//
+// Masks for the command register
+//
+// IBM Spec, Pages 5-6.
+//
+#define CMD_PIO_INTERRUPT 0x8000
+#define CMD_PIO_RESET 0x4000
+#define CMD_PIO_SSB_CLEAR 0x2000
+#define CMD_PIO_EXECUTE 0x1000
+#define CMD_PIO_SCB_REQUEST 0x0800
+#define CMD_PIO_RCV_CONTINUE 0x0400
+#define CMD_PIO_RCV_VALID 0x0200
+#define CMD_PIO_XMIT_VALID 0x0100
+#define CMD_PIO_RESET_SYSTEM 0x0080
+
+//
+// Common mask combinations
+//
+#define EXECUTE_SCB_COMMAND 0x9080 // int+exec+resetsysint
+#define ENABLE_SSB_UPDATE 0xA000 // int+ssbclear
+#define ENABLE_RECEIVE_VALID 0x8200 // int+rcvvalid
+
+//
+// Masks for the status register.
+//
+// IBM Spec, Pages 6-7.
+//
+#define STATUS_ADAPTER_INTERRUPT 0x8000
+#define STATUS_SYSTEM_INTERRUPT 0x0080
+
+//
+// Masks for adapter interrupts.
+//
+// IBM Spec, Page 7.
+//
+#define STATUS_INT_CODE_MASK 0x000F
+#define STATUS_INT_CODE_CHECK 0x0000
+#define STATUS_INT_CODE_IMPL 0x0002
+#define STATUS_INT_CODE_RING 0x0004
+#define STATUS_INT_CODE_SCB_CLEAR 0x0006
+#define STATUS_INT_CODE_CMD_STATUS 0x0008
+#define STATUS_INT_CODE_RECEIVE_STATUS 0x000A
+#define STATUS_INT_CODE_XMIT_STATUS 0x000C
+
+//
+// My Mask for System Interrupts
+//
+#define MASK_ADAPTER_CHECK 0x0001
+#define MASK_RING_STATUS 0x0002
+#define MASK_SCB_CLEAR 0x0004
+#define MASK_COMMAND_STATUS 0x0008
+#define MASK_RECEIVE_STATUS 0x0010
+#define MASK_TRANSMIT_STATUS 0x0020
+
+
+//
+// Adapter switch structure. The switches determine the configuration of the
+// card.
+//
+// IBM Spec, Page 8.
+//
+typedef struct _ADAPTERSWITCHES {
+
+ //
+ // Connector Type.
+ //
+ USHORT UTP_STP:1;
+
+ //
+ // Token Ring Speed
+ //
+ USHORT RingSpeed:1;
+
+ //
+ // DMA Channel
+ //
+ USHORT DMA:2;
+
+ //
+ // Is Remote Program Load enabled?
+ //
+ USHORT RPL:1;
+
+ //
+ // Adapter mode, test or normal
+ //
+ USHORT AdapterMode:1;
+
+ //
+ // Adapter wait state
+ //
+ USHORT WaitState:1;
+
+ //
+ // Interrupt Request Level
+ //
+ USHORT IntRequest:2;
+
+ //
+ // RPL address (if RPL enabled) or adapter I/O base address
+ //
+ USHORT RPL_PIO_Address:3;
+
+ //
+ // Not used.
+ //
+ USHORT Reserved:4;
+} ADAPTERSWITCHES,*PADAPTERSWITCHES;
+
+//
+// #defines for the I/O Address switches
+//
+// IBM Spec, Page 9.
+//
+#define SW_PIO_ADDR_8 0x00
+#define SW_PIO_ADDR_C 0x01
+#define SW_PIO_ADDR_A 0x02
+#define SW_PIO_ADDR_E 0x03
+#define SW_PIO_ADDR_9 0x04
+#define SW_PIO_ADDR_D 0x05
+#define SW_PIO_ADDR_B 0x06
+#define SW_PIO_ADDR_F 0x07
+
+//
+// #defines for the interrupt request level
+//
+// IBM Spec, Page 9.
+//
+#define SW_INT_9 0x00
+#define SW_INT_11 0x01
+#define SW_INT_10 0x02
+#define SW_INT_15 0x03
+
+//
+// #defines for the wait state.
+//
+// IBM Spec, Page 9.
+//
+#define SW_WAITSTATE_NORMAL 0x00
+#define SW_WAITSTATE_FAST 0x01
+
+//
+// #defines for the adapter mode.
+//
+// IBM Spec, Page 10.
+//
+#define SW_ADAPTERMODE_NORMAL 0x00
+#define SW_ADAPTERMODE_TEST 0x01
+
+//
+// #defines for RPL
+//
+// IBM Spec, Page 10.
+//
+#define SW_RPL_DISABLE 0x00
+#define SW_RPL_ENABLE 0x01
+
+//
+// #defines for the DMA channel
+//
+// IBM Spec, Page 10.
+//
+#define SW_DMA_5 0x00
+#define SW_DMA_7 0x01
+#define SW_DMA_6 0x02
+
+//
+// #defines for the ring speed.
+//
+// IBM Spec, Page 10.
+//
+#define SW_RINGSPEED_4 0x00
+#define SW_RINGSPEED_16 0x01
+
+//
+// #defines for the connector interface.
+//
+// IBM Spec, Page 10.
+//
+#define SW_STP 0x00
+#define SW_UTP 0x01
+
+//
+// DMA Command Values
+//
+// IBM Spec, Page 25.
+//
+#define CMD_DMA_OPEN 0x0300
+#define CMD_DMA_XMIT 0x0400
+#define CMD_DMA_XMIT_HALT 0x0500
+#define CMD_DMA_RCV 0x0600
+#define CMD_DMA_CLOSE 0x0700
+#define CMD_DMA_SET_GRP_ADDR 0x0800
+#define CMD_DMA_SET_FUNC_ADDR 0x0900
+#define CMD_DMA_READ_ERRLOG 0x0A00
+#define CMD_DMA_READ 0x0B00
+#define CMD_DMA_IMPL_ENABLE 0x0C00
+#define CMD_DMA_START_STOP_TRACE 0x0D00
+
+//
+// System Command Block structure.
+//
+// IBM Spec, Pages 13-14.
+//
+typedef struct _SCB {
+
+ //
+ // Command to be submitted to the card.
+ //
+ USHORT Command;
+
+ //
+ // Parameter USHORTs, different for different commands.
+ //
+ USHORT Parm1;
+ USHORT Parm2;
+
+} SCB, *PSCB;
+
+//
+// Generic System Status Block Structure.
+//
+// IBM Spec, Page 15.
+//
+typedef struct _SSB {
+
+ //
+ // Command for which status is returned.
+ //
+ USHORT Command;
+
+ //
+ // Status USHORTs, different for different commands
+ //
+ USHORT Status1;
+ USHORT Status2;
+ USHORT Status3;
+
+} SSB, *PSSB;
+
+//
+// Ring Status SSB #defines and structure
+//
+// IBM Spec, Page 15-16.
+//
+typedef struct _SSB_RING_STATUS {
+
+ //
+ // Command code, will be SSB_CMD_RING_STATUS
+ //
+ USHORT Command;
+
+ //
+ // Ring Status code, as defined below.
+ //
+ USHORT RingStatus;
+
+ //
+ // Last two not used.
+ //
+ USHORT Reserved1;
+ USHORT Reserved2;
+
+} SSB_RING_STATUS,*PSSB_RING_STATUS;
+
+#define SSB_CMD_RING_STATUS 0x0100
+
+#define RING_STATUS_OVERFLOW 0x8000
+#define RING_STATUS_SINGLESTATION 0x4000
+#define RING_STATUS_RINGRECOVERY 0x2000
+#define RING_STATUS_SIGNAL_LOSS 0x0080
+#define RING_STATUS_HARD_ERROR 0x0040
+#define RING_STATUS_SOFT_ERROR 0x0020
+#define RING_STATUS_XMIT_BEACON 0x0010
+#define RING_STATUS_LOBE_WIRE_FAULT 0x0008
+#define RING_STATUS_AUTO_REMOVE_1 0x0004
+#define RING_STATUS_REMOVE_RECEIVED 0x0001
+
+//
+// Command Reject Status SSB #defines and structure
+//
+typedef struct _SSB_CMD_REJECT_STATUS {
+
+ //
+ // Command code, will be SSB_CMD_COMMAND_REJECT_STATUS
+ //
+ USHORT Command;
+
+ //
+ // Reason for rejection, as defined below.
+ //
+ USHORT Reason;
+
+ //
+ // Command that was rejected.
+ //
+ USHORT SCBCommand;
+
+ //
+ // Not used.
+ //
+ USHORT Reserved;
+
+} SSB_CMD_REJECT_STATUS, *PSSB_CMD_REJECT_STATUS;
+
+#define SSB_CMD_COMMAND_REJECT_STATUS 0x0200
+
+#define CMD_REJECT_STATUS_BAD_CMD 0x0080
+#define CMD_REJECT_STATUS_BAD_ADDR 0x0040
+#define CMD_REJECT_STATUS_BAD_OPEN 0x0020
+#define CMD_REJECT_STATUS_BAD_CLOSED 0x0010
+#define CMD_REJECT_STATUS_BAD_SAME 0x0008
+
+//
+// Adapter Check Port information, structure and defines
+//
+// IBM Spec, Pages 18-19.
+//
+
+//
+// Offsets within the adapter memory where the values for the check can
+// be obtained.
+//
+// IBM Spec, Page 18.
+//
+#define ADAPTER_CHECK_PORT_OFFSET_BASE 0x05E0
+#define ADAPTER_CHECK_PORT_OFFSET_PARM0 0x05E2
+#define ADAPTER_CHECK_PORT_OFFSET_PARM1 0x05E4
+#define ADAPTER_CHECK_PORT_OFFSET_PARM2 0x05E6
+
+//
+// Structure that can be used to gather all of the adapter check information.
+//
+typedef struct _ADAPTER_CHECK {
+
+ //
+ // USHORT indicating why the adapter check occurred. Reasons are defined
+ // below.
+ //
+ USHORT Check;
+
+ //
+ // The parameters are used based on the reason above. Please see the spec
+ // as to what the different parameters are for the given reason.
+ //
+ USHORT Parm0;
+ USHORT Parm1;
+ USHORT Parm2;
+
+} ADAPTER_CHECK, *PADAPTER_CHECK;
+
+#define ADAPTER_CHECK_DMA_ABORT_READ 0x4000
+#define ADAPTER_CHECK_DMA_ABORT_WRITE 0x2000
+#define ADAPTER_CHECK_ILLEGAL_OPCODE 0x1000
+#define ADAPTER_CHECK_PARITY_ERR 0x0800
+#define ADAPTER_CHECK_PARITY_ERR_EXT 0x0400
+#define ADAPTER_CHECK_PARITY_ERR_SIM 0x0200 // System Interface Master
+#define ADAPTER_CHECK_PARITY_ERR_PHM 0x0100 // Protocol Handler Master
+#define ADAPTER_CHECK_PARITY_ERR_RR 0x0080 // Ring Receive
+#define ADAPTER_CHECK_PARITY_ERR_RXMT 0x0040 // Ring Transmit
+#define ADAPTER_CHECK_RING_UNDERRUN 0x0020
+#define ADAPTER_CHECK_RING_OVERRUN 0x0010
+#define ADAPTER_CHECK_INVALID_INT 0x0008
+#define ADAPTER_CHECK_INVALID_ERR_INT 0x0004
+#define ADAPTER_CHECK_INVALID_XOP 0x0002
+#define ADAPTER_CHECK_PROGRAM_CHECK 0x0001
+
+//
+// Initialization Structure.
+//
+// IBM Spec, Pages 19-25.
+//
+
+//
+// This structure needs to be packed on a two-byte boundary or the
+// SCB pointer will be off during the loop that sends the initialization
+// bytes to the card.
+//
+
+typedef struct _ADAPTER_INITIALIZATION {
+
+ //
+ // Initialization options as defined below
+ //
+ USHORT Options;
+
+ //
+ // Reserved USHORTs
+ //
+ USHORT Reserved1;
+ USHORT Reserved2;
+ USHORT Reserved3;
+
+ //
+ // Size of DMA bursts on receives
+ //
+ USHORT ReceiveBurstSize;
+
+ //
+ // Size of DMA bursts on transmits
+ //
+ USHORT TransmitBurstSize;
+
+ //
+ // Number of retries on DMA errors before giving up
+ //
+ USHORT DMAAbortThresholds;
+
+ //
+ // Pointer to the SCB (physical pointer), split into two words
+ // because we are writing them to the adaper in words
+ //
+ USHORT SCBHigh;
+ USHORT SCBLow;
+
+ //
+ // Pointer to the SSB (physical pointer), split into words because
+ // we are writing them to the adapter in words
+ //
+ USHORT SSBHigh;
+ USHORT SSBLow;
+
+} ADAPTER_INITIALIZATION, *PADAPTER_INITIALIZATION;
+
+//
+// Initialization options
+//
+#define INIT_OPTIONS_RESERVED 0x8000
+#define INIT_OPTIONS_SCBSSB_BURST 0x1000
+#define INIT_OPTIONS_SCBSSB_CYCLE 0x0000
+#define INIT_OPTIONS_LIST_BURST 0x0800
+#define INIT_OPTIONS_LIST_CYCLE 0x0000
+#define INIT_OPTIONS_LIST_STATUS_BURST 0x0400
+#define INIT_OPTIONS_LIST_STATUS_CYCLE 0x0000
+#define INIT_OPTIONS_RECEIVE_BURST 0x0200
+#define INIT_OPTIONS_RECEIVE_CYCLE 0x0000
+#define INIT_OPTIONS_XMIT_BURST 0x0100
+#define INIT_OPTIONS_XMIT_CYCLE 0x0000
+#define INIT_OPTIONS_SPEED_16 0x0040
+#define INIT_OPTIONS_SPEED_4 0x0000
+#define INIT_OPTIONS_DISABLE_ETR 0x0020
+#define INIT_OPTIONS_ENABLE_ETR 0x0000
+
+//
+// Starting address on card of where to write the init block
+//
+// IBM Spec, Page 22.
+//
+#define INIT_ADAPTER_PORT_OFFSET 0x0200
+
+//
+// Value to write to the command register after the init block has been
+// downloaded.
+//
+#define INIT_ADAPTER_INTERRUPT 0x9080
+
+//
+// Bit masks for initialization results.
+//
+// IBM Spec, Page 23.
+//
+#define STATUS_INIT_INITIALIZE 0x0040
+#define STATUS_INIT_TEST 0x0020
+#define STATUS_INIT_ERROR 0x0010
+
+//
+// Bring-Up Error Codes
+//
+// IBM Spec, Pages 23-24
+//
+#define BRING_UP_ERR_INIT_TEST 0x0000
+#define BRING_UP_ERR_CRC 0x0001
+#define BRING_UP_ERR_RAM 0x0002
+#define BRING_UP_ERR_INSTRUCTION_TEST 0x0003
+#define BRING_UP_ERR_INT_TEST 0x0004
+#define BRING_UP_ERR_PROTOCOL_HANDLER 0x0005
+#define BRING_UP_ERR_SYSTEM_INTERFACE_REG 0x0006
+
+//
+// Initialize Error Codes
+//
+// IBM Spec, Page 24.
+//
+#define INITIALIZE_ERR_PARM_LEN 0x0001
+#define INITIALIZE_ERR_INV_OPTIONS 0x0002
+#define INITIALIZE_ERR_INV_RCV_BURST 0x0003
+#define INITIALIZE_ERR_INV_XMIT_BURST 0x0004
+#define INITIALIZE_ERR_INV_DMA_ABORT 0x0005
+#define INITIALIZE_ERR_INV_SCB 0x0006
+#define INITIALIZE_ERR_INV_SSB 0x0007
+#define INITIALIZE_ERR_DMA_TIMEOUT 0x0009
+#define INITIALIZE_ERR_DMA_BUS 0x000B
+#define INITIALIZE_ERR_DMA_DATA 0x000C
+#define INITIALIZE_ERR_ADAPTER_CHECK 0x000D
+
+//
+// Recommended burst sizes.
+//
+// IBM Spec, Page 25.
+//
+#define DEFAULT_BURST_SIZE_FAST 0x004C
+#define DEFAULT_BURST_SIZE_NORMAL 0x0040
+
+//
+// TOK162 ErrorLog structure.
+//
+// IBM Spec, Page 35.
+//
+typedef struct _TOK162_ERRORLOG {
+
+ //
+ // These are error count fields. The adapter resets the internal
+ // counters after they are read into this structure.
+ //
+ UCHAR LineError;
+ UCHAR InternalError;
+ UCHAR BurstError;
+ UCHAR ARIFCIError;
+ UCHAR AbortDelimeter;
+ UCHAR Reserved1;
+ UCHAR LostFrameError;
+ UCHAR ReceiveCongestionError;
+ UCHAR FrameCopiedError;
+ UCHAR Reserved2;
+ UCHAR TokenError;
+ UCHAR Reserved3;
+ UCHAR DMABusError;
+ UCHAR Reserved4;
+
+} TOK162_ERRORLOG, *PTOK162_ERRORLOG;
+
+//
+// TOK162 Read Adapter Log structure. Used to get permanent address, current
+// addresses (network, group, functional), the microcode level, and the MAC
+// buffer.
+//
+// IBM Spec, Pages 32-33.
+//
+typedef struct _TOK162_READADAPTERBUF {
+
+ //
+ // Number of bytes to be read from the adapter
+ //
+ USHORT DataCount;
+
+ //
+ // Offset for buffer
+ //
+ USHORT DataAddress;
+
+ //
+ // Buffer space
+ //
+ UCHAR BufferSpace[68-6];
+
+} TOK162_READADAPTERBUF, *PTOK162_READADAPTERBUF;
+
+//
+// TOK162 Address Block
+//
+// IBM Spec, Page 33.
+//
+typedef struct _TOK162_ADDRESSBLOCK {
+
+ //
+ // The node address. Used for both the current address and the permanent
+ // address (depending on the read call).
+ //
+ UCHAR NodeAddress[6];
+
+ //
+ // The current group address.
+ //
+ UCHAR GroupAddress[4];
+
+ //
+ // The current functional address.
+ //
+ UCHAR FunctionalAddress[4];
+
+} TOK162_ADDRESSBLOCK, *PTOK162_ADDRESSBLOCK;
+
+//
+// TOK162 Receive List
+//
+// IBM Spec, Pages 36-40.
+//
+typedef struct _TOK162_RECEIVE_LIST {
+
+ //
+ // This is the physical address of the next entry
+ // in the Receive Ring.
+ //
+ TOK162_PHYSICAL_ADDRESS ForwardPointer;
+
+ //
+ // List entry characteristics
+ //
+ USHORT CSTAT;
+
+ //
+ // This is the total size of the received frame.
+ //
+ USHORT FrameSize;
+
+ //
+ // This is the length (in bytes) of the buffer associated. IBM Format.
+ //
+ USHORT DataCount1;
+
+ //
+ // This is the address of the buffer associated. IBM Format.
+ //
+ ULONG PhysicalAddress1;
+
+ //
+ // This is the length (in bytes) of this block. Stored in IBM format
+ //
+ USHORT DataCount2;
+
+ //
+ // This is the physical address of this block. Stored in IBM Format
+ //
+ ULONG PhysicalAddress2;
+
+ //
+ // This is the length (in bytes) of this block. Stored in IBM format
+ //
+ USHORT DataCount3;
+
+ //
+ // This is the physical address of this block. Stored in IBM Format
+ //
+ ULONG PhysicalAddress3;
+
+ //
+ // This is the length (in bytes) of this block. Stored in IBM format
+ //
+ USHORT DataCount4;
+
+ //
+ // This is the physical address of this block. Stored in IBM Format
+ //
+ ULONG PhysicalAddress4;
+
+ //
+ // This is the length (in bytes) of this block. Stored in IBM format
+ //
+ USHORT DataCoun5;
+
+ //
+ // This is the physical address of this block. Stored in IBM Format
+ //
+ ULONG PhysicalAddress5;
+
+ //
+ // This is the length (in bytes) of this block. Stored in IBM format
+ //
+ USHORT DataCount6;
+
+ //
+ // This is the physical address of this block. Stored in IBM Format
+ //
+ ULONG PhysicalAddress6;
+
+ //
+ // This is the length (in bytes) of this block. Stored in IBM format
+ //
+ USHORT DataCount7;
+
+ //
+ // This is the physical address of this block. Stored in IBM Format
+ //
+ ULONG PhysicalAddress7;
+
+ //
+ // This is the length (in bytes) of this block. Stored in IBM format
+ //
+ USHORT DataCount8;
+
+ //
+ // This is the physical address of this block. Stored in IBM Format
+ //
+ ULONG PhysicalAddress8;
+
+ //
+ // This is the length (in bytes) of this block. Stored in IBM format
+ //
+ USHORT DataCount9;
+
+ //
+ // This is the physical address of this block. Stored in IBM Format
+ //
+ ULONG PhysicalAddress9;
+
+} TOK162_RECEIVE_LIST, *PTOK162_RECEIVE_LIST;
+
+//
+// Receive and Transmit buffer sizes, depending on the ring speed.
+//
+// IBM Spec, Page 13.
+//
+#define RECEIVE_LIST_BUFFER_SIZE_4 4500
+#define RECEIVE_LIST_BUFFER_SIZE_16 17986
+
+//
+// The number of receive lists/buffers
+//
+#define RECEIVE_LIST_COUNT 3
+
+//
+// Receive CSTAT bit masks
+//
+// IBM Spec, Pages 38-39.
+//
+#define RECEIVE_CSTAT_REQUEST_RESET 0x0088 // Valid bit + frame int
+#define RECEIVE_CSTAT_VALID 0x0080 // Valid bit
+
+//
+// Transmit list entry. This is exactly like the receive list entry.
+//
+// IBM Spec, Pages 46-55.
+//
+typedef struct _TOK162_TRANSMIT_LIST {
+
+ //
+ // This is the physical address of the next entry
+ // in the Transmit Chain.
+ //
+ TOK162_PHYSICAL_ADDRESS ForwardPointer;
+
+ //
+ // List entry characteristics. IBM Format.
+ //
+ USHORT CSTAT;
+
+ //
+ // This is the total size of the received frame. IBM Format.
+ //
+ USHORT FrameSize;
+
+ //
+ // This is the length (in bytes) of this block. Stored in IBM format
+ //
+ USHORT DataCount1;
+
+ //
+ // This is the physical address of this block. Stored in IBM Format
+ //
+ TOK162_PHYSICAL_ADDRESS PhysicalAddress1;
+
+ //
+ // This is the length (in bytes) of this block. Stored in IBM format
+ //
+ USHORT DataCount2;
+
+ //
+ // This is the physical address of this block. Stored in IBM Format
+ //
+ TOK162_PHYSICAL_ADDRESS PhysicalAddress2;
+
+ //
+ // This is the length (in bytes) of this block. Stored in IBM format
+ //
+ USHORT DataCount3;
+
+ //
+ // This is the physical address of this block. Stored in IBM Format
+ //
+ TOK162_PHYSICAL_ADDRESS PhysicalAddress3;
+
+ //
+ // This is the length (in bytes) of this block. Stored in IBM format
+ //
+ USHORT DataCount4;
+
+ //
+ // This is the physical address of this block. Stored in IBM Format
+ //
+ TOK162_PHYSICAL_ADDRESS PhysicalAddress4;
+
+ //
+ // This is the length (in bytes) of this block. Stored in IBM format
+ //
+ USHORT DataCoun5;
+
+ //
+ // This is the physical address of this block. Stored in IBM Format
+ //
+ TOK162_PHYSICAL_ADDRESS PhysicalAddress5;
+
+ //
+ // This is the length (in bytes) of this block. Stored in IBM format
+ //
+ USHORT DataCount6;
+
+ //
+ // This is the physical address of this block. Stored in IBM Format
+ //
+ TOK162_PHYSICAL_ADDRESS PhysicalAddress6;
+
+ //
+ // This is the length (in bytes) of this block. Stored in IBM format
+ //
+ USHORT DataCount7;
+
+ //
+ // This is the physical address of this block. Stored in IBM Format
+ //
+ TOK162_PHYSICAL_ADDRESS PhysicalAddress7;
+
+ //
+ // This is the length (in bytes) of this block. Stored in IBM format
+ //
+ USHORT DataCount8;
+
+ //
+ // This is the physical address of this block. Stored in IBM Format
+ //
+ TOK162_PHYSICAL_ADDRESS PhysicalAddress8;
+
+ //
+ // This is the length (in bytes) of this block. Stored in IBM format
+ //
+ USHORT DataCount9;
+
+ //
+ // This is the physical address of this block. Stored in IBM Format
+ //
+ TOK162_PHYSICAL_ADDRESS PhysicalAddress9;
+
+} TOK162_TRANSMIT_LIST, *PTOK162_TRANSMIT_LIST;
+
+//
+// The number of transmit lists
+//
+#define TRANSMIT_LIST_COUNT 0x0002
+
+//
+// The maximum number of transmit list scatter-gathers
+//
+#define TOK162_MAX_SG 0x0003
+
+//
+// Transmit CSTAT bit masks
+//
+#define TRANSMIT_CSTAT_REQUEST 0x00B0
+#define TRANSMIT_CSTAT_XMIT_ERROR 0x0004
+
+//
+// TOK162 Command Block. Contains all of the fields necessary to support
+// both commands and transmits.
+//
+typedef struct _TOK162_COMMAND_BLOCK {
+
+ //
+ // Transmit List Entry
+ //
+ TOK162_TRANSMIT_LIST TransmitEntry;
+
+ //
+ // This is the state of this Command Block.
+ //
+ USHORT State;
+
+ //
+ // This is the status of this Command Block.
+ //
+ USHORT Status;
+
+ //
+ // This is the physical address of the next Command Block
+ // to be executed. If this address == -1, then there are
+ // no more commands to be executed.
+ //
+ UNALIGNED TOK162_PHYSICAL_ADDRESS NextPending;
+
+ //
+ // This is the TOK162 Command Code.
+ //
+ USHORT CommandCode;
+
+ //
+ // Pointer used by different commands
+ //
+ ULONG ParmPointer;
+
+ //
+ // This is the immediate data to be used by all commands
+ // other than transmit.
+ //
+ ULONG ImmediateData;
+
+} TOK162_COMMAND_BLOCK, *PTOK162_COMMAND_BLOCK;
+
+
+//
+// Data block pointer
+// Used only to reference the different fields of the transmit list entry.
+// Allows code to access the transmit list entries in a for loop rather than
+// having code for each specific entry.
+//
+// Must be packed on a 2 byte boundary.
+//
+typedef struct _TOK162_DATA_BLOCK {
+
+ //
+ // size of the block. IBM format.
+ //
+ USHORT Size;
+
+ //
+ // physical pointer to the buffer. IBM format.
+ //
+ TOK162_PHYSICAL_ADDRESS IBMPhysicalAddress;
+
+} TOK162_DATA_BLOCK,*PTOK162_DATA_BLOCK;
+
+//
+// Numerical values for switches
+// (e.g. - Interrupt 5 instead of 00 [switch value])
+//
+// IBM Spec, Pages 8-10.
+//
+
+//
+// Adapter mode values
+//
+#define CFG_ADAPTERMODE_NORMAL 0x0000
+#define CFG_ADAPTERMODE_TEST 0x0001
+
+//
+// Wait state values
+//
+#define CFG_WAITSTATE_NORMAL 0x0000
+#define CFG_WAITSTATE_FAST 0x0001
+
+//
+// DMA channel values
+//
+#define CFG_DMACHANNEL_5 0x0005
+#define CFG_DMACHANNEL_6 0x0006
+#define CFG_DMACHANNEL_7 0x0007
+
+//
+// Connector type values
+//
+#define CFG_MEDIATYPE_STP 0x0000
+#define CFG_MEDIATYPE_UTP 0x0001
+
+//
+// Adapter interrupt values
+//
+#define CFG_INT_9 0x0009
+#define CFG_INT_10 0x000A
+#define CFG_INT_11 0x000B
+#define CFG_INT_15 0x000F
+
+//
+// RPL address values
+//
+#define CFG_RPLADDR_C0000 0xC0000
+#define CFG_RPLADDR_C4000 0xC4000
+#define CFG_RPLADDR_C8000 0xC8000
+#define CFG_RPLADDR_CC000 0xCC000
+#define CFG_RPLADDR_D0000 0xD0000
+#define CFG_RPLADDR_D4000 0xD4000
+#define CFG_RPLADDR_D8000 0xD8000
+#define CFG_RPLADDR_DC000 0xDC000
+
+//
+// Ring speed values
+//
+#define CFG_RINGSPEED_4 0x0004
+#define CFG_RINGSPEED_16 0x0010
+
+//
+// command and result structures
+//
+
+//
+// Open command structure. Submitted to the card to insert the system in
+// the Token Ring.
+//
+// IBM Spec, Pages 27-32.
+//
+typedef struct _OPEN_COMMAND {
+
+ //
+ // Open options. Defined below.
+ //
+ USHORT Options;
+
+ //
+ // Address to insert ourselves into the ring under.
+ //
+ UCHAR NodeAddress[6];
+
+ //
+ // Group address adapter should respond to.
+ //
+ ULONG GroupAddress;
+
+ //
+ // Functional address adapter should respond to.
+ //
+ ULONG FunctionalAddress;
+
+ //
+ // Size of the receive list structure
+ //
+ USHORT ReceiveListSize;
+ //
+ // Size of the transmit list structure
+ //
+ USHORT TransmitListSize;
+
+ //
+ // Adapter buffer size.
+ //
+ USHORT BufferSize;
+
+ //
+ // Unused.
+ //
+ USHORT Reserved1;
+ USHORT Reserved2;
+
+ //
+ // Minimum number of buffers to reserve for transmits
+ //
+ UCHAR TransmitBufCountMin;
+
+ //
+ // Maximum number of buffers to reserve for transmits
+ //
+ UCHAR TransmitBufCountMax;
+
+ //
+ // Pointer to the system product ID
+ //
+ ULONG ProdIDAddress;
+
+} OPEN_COMMAND, *POPEN_COMMAND;
+
+#define OPEN_OPTION_PASS_BEACON_FRAMES 0x8000
+#define OPEN_OPTION_DISABLE_DMA_TIMEOUT 0x4000
+#define OPEN_OPTION_ENABLE_DMA_TIMEOUT 0x0000
+#define OPEN_OPTION_WRAP_INTERFACE 0x0080
+#define OPEN_OPTION_DISABLE_HARD_ERROR 0x0040
+#define OPEN_OPTION_ENABLE_HARD_ERROR 0x0000
+#define OPEN_OPTION_DISABLE_SOFT_ERROR 0x0020
+#define OPEN_OPTION_ENABLE_SOFT_ERROR 0x0000
+#define OPEN_OPTION_PASS_ADAPTER_FRAMES 0x0010
+#define OPEN_OPTION_PASS_ATTENTION_FRAMES 0x0008
+#define OPEN_OPTION_PAD_ROUTING_FIELD 0x0004
+#define OPEN_OPTION_FRAME_HOLD 0x0002
+#define OPEN_OPTION_CONTENDER 0x0001
+
+//
+// Values to set the open parameters to
+//
+#define OPEN_RECEIVE_LIST_SIZE 0x000e
+#define OPEN_TRANSMIT_LIST_SIZE 0x001A
+#define OPEN_BUFFER_SIZE 512
+
+//
+// Open completion structure (SSB)
+//
+// IBM Spec, Pages 31-32.
+//
+typedef struct _OPEN_COMPLETION {
+
+ //
+ // Better be CMD_DMA_OPEN.
+ //
+ USHORT Command;
+
+ //
+ // Completion code. Bitmasks defined below.
+ //
+ USHORT Completion;
+
+ //
+ // Not used.
+ //
+ USHORT Reserved1;
+ USHORT Reserved2;
+
+} OPEN_COMPLETION, *POPEN_COMPLETION;
+
+#define OPEN_COMPLETION_MASK_PHASE 0xF000
+#define OPEN_COMPLETION_MASK_ERROR 0x0F00
+#define OPEN_COMPLETION_MASK_RESULT 0x00FF
+
+#define OPEN_COMPLETION_PHASE_LOBE 0x1000
+#define OPEN_COMPLETION_PHASE_INSERTION 0x2000
+#define OPEN_COMPLETION_PHASE_VERIFY 0x3000
+#define OPEN_COMPLETION_PHASE_RING 0x4000
+#define OPEN_COMPLETION_PHASE_PARMS 0x5000
+
+#define OPEN_COMPLETION_ERROR_FUNCTION 0x0100
+#define OPEN_COMPLETION_ERROR_SIGLOSS 0x0200
+#define OPEN_COMPLETION_ERROR_TIMEOUT 0x0500
+#define OPEN_COMPLETION_ERROR_RINGFAIL 0x0600
+#define OPEN_COMPLETION_ERROR_RINGBEACON 0x0700
+#define OPEN_COMPLETION_ERROR_DUPLICATE 0x0800
+#define OPEN_COMPLETION_ERROR_REQPARMS 0x0900
+#define OPEN_COMPLETION_ERROR_REMOVE_REC 0x0A00
+#define OPEN_COMPLETION_ERROR_IMPL_REC 0x0B00
+#define OPEN_COMPLETION_ERROR_DUPMOD 0x0C00
+
+#define OPEN_RESULT_ADAPTER_OPEN 0x0080
+#define OPEN_RESULT_NODE_ADDR_ERROR 0x0040
+#define OPEN_RESULT_LIST_SIZE_ERROR 0x0020
+#define OPEN_RESULT_BUF_SIZE_ERROR 0x0010
+#define OPEN_RESULT_EXT_RAM_ERROR 0x0008
+#define OPEN_RESULT_XMIT_CNT_ERROR 0x0004
+#define OPEN_RESULT_OPEN_ERROR 0x0002
+
+//
+// The adapter requires many of the WORD values and almost all of the
+// DWORD values to be in IBM format, versus Intel Format. The difference
+// between the two is as follows:
+//
+// If you are storing the value 0x1234, a word value, memory would look like:
+//
+// --------- ---------
+// | | | |
+// Intel | 34 | | 12 |
+// | | | |
+// --------- ---------
+// Address 100 101
+//
+//
+// --------- ---------
+// | | | |
+// IBM | 12 | | 34 |
+// | | | |
+// --------- ---------
+// Address 100 101
+//
+//
+// If you are storing the value 0x12345678, a dword value, memory would look
+// like:
+//
+// --------- --------- --------- ---------
+// | | | | | | | |
+// Intel | 78 | | 56 | | 34 | | 12 |
+// | | | | | | | |
+// --------- --------- --------- ---------
+// Address 100 101
+//
+//
+// --------- --------- --------- ---------
+// | | | | | | | |
+// IBM | 12 | | 34 | | 56 | | 78 |
+// | | | | | | | |
+// --------- --------- --------- ---------
+// Address 100 101
+//
+//
+// To convert "Intel" WORDs and DWORDs to "IBM" format, the following macros
+// are used.
+//
+
+//
+// Macro to byte swap a word.
+//
+#define BYTE_SWAP(_word) (\
+ (USHORT) (((_word) >> 8) | ((_word) << 8)) )
+
+//
+// Macro to byte swap a word.
+//
+#define WORD_SWAP(_dword) (\
+ (ULONG) (((_dword) >> 16) | ((_dword) << 16)) )
+
+//
+// Macro to get low byte of a word.
+//
+#define LOW_BYTE(_word) (\
+ (UCHAR) ((_word) & 0x00FF) )
+
+//
+// Macro to get high byte of a word.
+//
+#define HIGH_BYTE(_word) (\
+ (UCHAR) (((_word) >> 8) & 0x00FF) )
+
+//
+// Macro to get low word of a dword.
+//
+#define LOW_WORD(_dword) (\
+ (USHORT) ((_dword) & 0x0000FFFF) )
+
+//
+// Macro to get high word of a dword.
+//
+#define HIGH_WORD(_dword) (\
+ (USHORT) (((_dword) >> 16) & 0x0000FFFF) )
+
+//
+// Macro to create a dword from two words.
+//
+#define MAKE_LONG(_highword,_lowword) (\
+ (ULONG) ((((ULONG)_highword) << 16) + _lowword))
+
+//
+// Macro to byte swap a dword.
+//
+#define BYTE_SWAP_ULONG(_ulong) (\
+ (ULONG)((ULONG)(BYTE_SWAP(LOW_WORD(_ulong)) << 16) + \
+ BYTE_SWAP(HIGH_WORD(_ulong))))
+
+//
+// End the packing
+//
+#include <poppack.h>
diff --git a/private/ntos/ndis/ibmtok2i/tok162pr.h b/private/ntos/ndis/ibmtok2i/tok162pr.h
new file mode 100644
index 000000000..1875cdd23
--- /dev/null
+++ b/private/ntos/ndis/ibmtok2i/tok162pr.h
@@ -0,0 +1,315 @@
+/*++
+
+Copyright (c) 1990 Microsoft Corporation
+
+Module Name:
+
+ tok162pr.h
+
+Abstract:
+
+ The procedure declarations for the IBM Token-Ring 16/4 II
+ ISA driver.
+
+Author:
+
+ Kevin Martin (kevinma) 1-Feb-1994
+
+Environment:
+
+ Architecturally, there is an assumption in this driver that we are
+ on a little endian machine.
+
+Notes:
+
+ optional-notes
+
+Revision History:
+
+
+--*/
+
+#ifndef _TOK162PROC_
+#define _TOK162PROC_
+
+//
+// We define the external interfaces to the TOK162 driver.
+// These routines are only external to permit separate
+// compilation. Given a truely fast compiler they could
+// all reside in a single file and be static.
+//
+
+extern
+VOID
+TOK162DisableInterrupt(
+ IN NDIS_HANDLE MiniportAdapterContext
+ );
+
+extern
+VOID
+TOK162EnableInterrupt(
+ IN NDIS_HANDLE MiniportAdapterContext
+ );
+
+extern
+VOID
+TOK162Halt(
+ IN NDIS_HANDLE MiniportAdapterContext
+ );
+
+extern
+VOID
+TOK162Shutdown(
+ IN NDIS_HANDLE MiniportAdapterContext
+ );
+
+extern
+VOID
+TOK162HandleInterrupt(
+ IN NDIS_HANDLE MiniportAdapterContext
+ );
+
+extern
+BOOLEAN
+TOK162InitialInit(
+ IN PTOK162_ADAPTER Adapter
+ );
+extern
+NDIS_STATUS
+TOK162Initialize(
+ OUT PNDIS_STATUS OpenErrorStatus,
+ OUT PUINT SelectedMediumIndex,
+ IN PNDIS_MEDIUM MediumArray,
+ IN UINT MediumArraySize,
+ IN NDIS_HANDLE MiniportAdapterHandle,
+ IN NDIS_HANDLE WrapperConfigurationContext
+ );
+
+extern
+NDIS_STATUS
+TOK162QueryInformation(
+ IN NDIS_HANDLE MiniportAdapterContext,
+ IN NDIS_OID Oid,
+ IN PVOID InformationBuffer,
+ IN ULONG InformationBufferLength,
+ OUT PULONG BytesWritten,
+ OUT PULONG BytesNeeded
+ );
+
+extern
+NDIS_STATUS
+TOK162SetInformation(
+ IN NDIS_HANDLE MiniportAdapterContext,
+ IN NDIS_OID Oid,
+ IN PVOID InformationBuffer,
+ IN ULONG InformationBufferLength,
+ OUT PULONG BytesRead,
+ OUT PULONG BytesNeeded
+ );
+
+extern
+VOID
+TOK162Isr(
+ OUT PBOOLEAN InterruptRecognized,
+ OUT PBOOLEAN QueueDpc,
+ IN NDIS_HANDLE MiniportAdapterContext
+ );
+
+extern
+NDIS_STATUS
+TOK162Reset(
+ OUT PBOOLEAN AddressingReset,
+ IN NDIS_HANDLE MiniportAdapterContext
+ );
+
+extern
+NDIS_STATUS
+TOK162TransferData(
+ OUT PNDIS_PACKET Packet,
+ OUT PUINT BytesTransferred,
+ IN NDIS_HANDLE MiniportAdapterContext,
+ IN NDIS_HANDLE MiniportReceiveContext,
+ IN UINT ByteOffset,
+ IN UINT BytesToTransfer
+ );
+
+extern
+NDIS_STATUS
+TOK162Send(
+ IN NDIS_HANDLE MiniportAdapterContext,
+ IN PNDIS_PACKET Packet,
+ IN UINT Flags
+ );
+
+extern
+VOID
+TOK162CopyFromBufferToPacket(
+ IN PCHAR Buffer,
+ IN UINT BytesToCopy,
+ IN PNDIS_PACKET Packet,
+ IN UINT Offset,
+ OUT PUINT BytesCopied
+ );
+
+
+VOID
+TOK162FinishQueryInformation(
+ IN PTOK162_ADAPTER Adapter
+);
+
+extern
+NDIS_STATUS
+TOK162RegisterAdapter(
+ IN NDIS_HANDLE ConfigurationHandle,
+ IN NDIS_HANDLE MiniportAdapterHandle,
+ IN PUCHAR CurrentAddress,
+ IN UINT PortAddress,
+ IN ULONG MaxFrameSize
+ );
+
+extern
+VOID
+TOK162AcquireCommandBlock(
+ IN PTOK162_ADAPTER Adapter,
+ OUT PTOK162_SUPER_COMMAND_BLOCK * CommandBlock
+ );
+
+extern
+BOOLEAN
+TOK162AcquireTransmitBlock(
+ IN PTOK162_ADAPTER Adapter,
+ OUT PTOK162_SUPER_COMMAND_BLOCK * CommandBlock
+ );
+
+extern
+VOID
+TOK162RelinquishCommandBlock(
+ IN PTOK162_ADAPTER Adapter,
+ IN PTOK162_SUPER_COMMAND_BLOCK CommandBlock
+ );
+
+extern
+VOID
+TOK162SubmitCommandBlock(
+ IN PTOK162_ADAPTER Adapter,
+ IN PTOK162_SUPER_COMMAND_BLOCK CommandBlock
+ );
+
+extern
+VOID
+TOK162DoAdapterReset(
+ IN PTOK162_ADAPTER Adapter
+ );
+
+extern
+NDIS_STATUS
+TOK162SetupForReset(
+ IN PTOK162_ADAPTER Adapter
+ );
+
+BOOLEAN
+TOK162CheckForHang(
+ IN NDIS_HANDLE MiniportAdapterContext
+ );
+
+VOID
+TOK162ResetVariables(
+ IN PTOK162_ADAPTER Adapter
+ );
+
+VOID
+TOK162ResetHandler(
+ IN PVOID SystemSpecific1,
+ IN PTOK162_ADAPTER Adapter,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3
+ );
+
+VOID
+TOK162DeferredTimer(
+ IN PVOID SystemSpecific1,
+ IN PTOK162_ADAPTER Adapter,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3
+ );
+
+
+extern
+NDIS_STATUS
+TOK162GetAdapterConfiguration(
+ IN PTOK162_ADAPTER Adapter
+ );
+extern
+VOID
+TOK162ResetAdapter(
+ IN PTOK162_ADAPTER Adapter
+ );
+
+BOOLEAN
+DoTheOpen(
+ PTOK162_ADAPTER Adapter
+ );
+
+BOOLEAN
+DoTheReceive(
+ PTOK162_ADAPTER Adapter
+ );
+
+extern
+NDIS_STATUS
+TOK162ChangeFuncGroup(
+ IN PTOK162_ADAPTER Adapter
+);
+
+
+BOOLEAN
+TOK162InitializeTransmitQueue(
+ IN PTOK162_ADAPTER Adapter
+ );
+VOID
+TOK162ResetTimer(
+ IN PVOID SystemSpecific1,
+ IN PTOK162_ADAPTER Adapter,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3
+ );
+VOID
+TOK162DoResetIndications(
+ IN PTOK162_ADAPTER Adapter,
+ IN NDIS_STATUS Status
+ );
+
+BOOLEAN
+TOK162AcquireTransmitBlock(
+ IN PTOK162_ADAPTER Adapter,
+ OUT PTOK162_SUPER_COMMAND_BLOCK * CommandBlock
+ );
+
+VOID
+TOK162RelinquishTransmitBlock(
+ IN PTOK162_ADAPTER Adapter,
+ IN PTOK162_SUPER_COMMAND_BLOCK CommandBlock
+ );
+
+VOID
+TOK162SubmitTransmitBlock(
+ IN PTOK162_ADAPTER Adapter,
+ IN PTOK162_SUPER_COMMAND_BLOCK CommandBlock
+ );
+VOID
+TOK162ProcessTransmitInterrupts(
+ IN PTOK162_ADAPTER Adapter
+ );
+extern
+BOOLEAN
+TOK162ProcessRingInterrupts(
+ IN PTOK162_ADAPTER Adapter
+ );
+
+extern
+VOID
+TOK162DeleteAdapterMemory(
+ IN PTOK162_ADAPTER Adapter
+ );
+
+#endif //_TOK162PROC_
diff --git a/private/ntos/ndis/ibmtok2i/tok162sw.h b/private/ntos/ndis/ibmtok2i/tok162sw.h
new file mode 100644
index 000000000..8f431b6b1
--- /dev/null
+++ b/private/ntos/ndis/ibmtok2i/tok162sw.h
@@ -0,0 +1,699 @@
+/*++
+
+Copyright (c) 1992 Microsoft Corporation
+
+Module Name:
+
+ tok162sw.h
+
+Abstract:
+
+ The hardware-related definitions for the IBM Token-Ring 16/4 II
+ ISA driver.
+
+Author:
+
+ Kevin Martin (kevinma) 1-Feb-1994
+
+Environment:
+
+ Architecturally, there is an assumption in this driver that we are
+ on a little endian machine.
+
+Notes:
+
+ optional-notes
+
+Revision History:
+
+
+--*/
+
+#include <ndis.h>
+#include <tok162hw.h>
+
+//
+// Temporary #define for debugging regardless of DBG flag
+//
+#define MYDBGPRINT DbgPrint;
+
+//
+// Debugging flags.
+//
+#if DBG
+
+//
+// Degrees of debugging output. Can be OR'd in any combination.
+//
+#define TOK162_DEBUG_LOUD 0x1
+#define TOK162_DEBUG_VERY_LOUD 0x2
+#define TOK162_DEBUG_EXTRA_LOUD 0x4
+
+//
+// The degree of debugging output being displayed on the debugger currently.
+// Defined in TOK162.C.
+//
+extern UCHAR Tok162Debug;
+
+//
+// Macros that decide on the debugging based on Tok162Debug.
+//
+#define LOUD_DEBUG(A) if (Tok162Debug & TOK162_DEBUG_LOUD) { A ; }
+#define VERY_LOUD_DEBUG(A) if (Tok162Debug & TOK162_DEBUG_VERY_LOUD) { A ; }
+#define EXTRA_LOUD_DEBUG(A) if (Tok162Debug & TOK162_DEBUG_EXTRA_LOUD) { A ; }
+#define CURRENT_DEBUG(A) if (Tok162Debug & 8) { A ; }
+
+//
+// The size of the logging array
+//
+#define LOG_SIZE 256
+
+//
+// Pointer for the logging array. Allocated in TOK162.C
+// (AllocateAdapterMemory)
+//
+extern PUCHAR Tok162Log;
+
+//
+// The current index into the logging array.
+//
+extern USHORT Tok162LogPlace;
+
+//
+// Logging macro.
+//
+#define IF_LOG(ch) { Tok162Log[Tok162LogPlace] = (ch); \
+ Tok162LogPlace = (Tok162LogPlace + 1) % LOG_SIZE; }
+
+#else // if dbg
+
+//
+// Make sure all of the debugging and logging calls resolve to NULL
+//
+#define LOUD_DEBUG(A)
+#define VERY_LOUD_DEBUG(A)
+#define EXTRA_LOUD_DEBUG(A)
+
+#define IF_LOG(ch) { }
+
+#endif // if dbg
+
+//
+// Version constants for this driver
+//
+#define TOK162_NDIS_MAJOR_VERSION 3
+#define TOK162_NDIS_MINOR_VERSION 0
+
+//
+// Macro to allocate physical memory.
+//
+#define TOK162_ALLOC_PHYS(_Status, _pBuffer, _Length) \
+{ \
+ NDIS_PHYSICAL_ADDRESS MinusOne = NDIS_PHYSICAL_ADDRESS_CONST (-1, -1); \
+ *(_Status) = NdisAllocateMemory( \
+ (PVOID*)(_pBuffer), \
+ (_Length), \
+ 0, \
+ MinusOne); \
+}
+
+//
+// Macro to free physical memory previously allocated.
+//
+#define TOK162_FREE_PHYS(_Buffer) NdisFreeMemory((_Buffer), 0, 0)
+
+//
+// Enumeration for the reset stages.
+//
+enum ResetStates{InitialInit,
+ CheckReset,
+ CheckResetRetry,
+ DoTheInit,
+ CheckInit,
+ CheckInitRetry
+ };
+
+//
+// Adapter structure is defined further down.
+//
+struct _TOK162_ADAPTER;
+
+
+//
+// TOK162 Configuration Block
+//
+// This structure contains configuration data for the TOK162. This
+// structure is filled in based on the switches.
+//
+typedef struct _TOK162_CONFIGURATION_BLOCK {
+
+ //
+ // This is the adapter mode;
+ //
+ USHORT AdapterMode;
+
+ //
+ // This field contains the wait state
+ //
+ USHORT WaitState;
+
+ //
+ // This field contains the RPL
+ //
+ BOOLEAN RPL;
+
+ //
+ // This field contains the RPL Address
+ //
+ UINT RPLAddress;
+
+ //
+ // This field contains the DMA Channel
+ //
+ USHORT DMAChannel;
+
+ //
+ // This field contains the Ring Speed
+ //
+ USHORT RingSpeed;
+
+ //
+ // Interrupt level
+ //
+ USHORT InterruptLevel;
+
+ //
+ // This field contains the connector type
+ //
+ USHORT UTPorSTP;
+
+} TOK162_CONFIGURATION_BLOCK, *PTOK162_CONFIGURATION_BLOCK;
+
+//
+// In addition to the Command Block fields which the TOK162HW.H
+// defines, we need some additional fields for our own purposes.
+// To ensure that these fields are properly aligned (and to
+// ensure that the actual Command Block is properly aligned)
+// we'll defined a Super Command Block. This structure will
+// contain a "normal" TOK162 Command Block plus some additional
+// fields. This structure is used for both commands and transmits.
+//
+typedef struct _TOK162_SUPER_COMMAND_BLOCK {
+
+ //
+ // The actual TOK162 Command Block.
+ //
+ TOK162_COMMAND_BLOCK Hardware;
+
+ //
+ // This contains the physical address of the above Command Block.
+ //
+ NDIS_PHYSICAL_ADDRESS Self;
+ TOK162_PHYSICAL_ADDRESS PhysicalTransmitEntry;
+
+ //
+ // Constrain Buffer addresses
+ //
+ NDIS_PHYSICAL_ADDRESS TOK162BufferPhysicalAddress;
+ TOK162_PHYSICAL_ADDRESS TOK162BufferAddress;
+
+ //
+ // This contains the virtual address of the next pending command.
+ //
+ struct _TOK162_SUPER_COMMAND_BLOCK *NextCommand;
+
+ //
+ // Points to the packet from which data is being transmitted
+ // through this Command Block.
+ //
+ PNDIS_PACKET OwningPacket;
+
+ //
+ // When a packet is submitted to the hardware we record
+ // here whether it used adapter buffers and if so, the buffer
+ // index.
+ //
+ BOOLEAN UsedTOK162Buffer;
+
+ //
+ // Is this from a set
+ //
+ BOOLEAN Set;
+
+ //
+ // If this is a public (adapter-wide) command block, then
+ // this will contain this block's index into the adapter's
+ // command queue.
+ //
+ USHORT CommandBlockIndex;
+
+ //
+ // This tells if the command block is a regular or transmit command block.
+ //
+ BOOLEAN CommandBlock;
+
+ //
+ // This field is used to timestamp the command blocks
+ // as they are placed into the command queue. If a
+ // block fails to execute, the adapter will get a kick in the ass to
+ // start it up again.
+ //
+ BOOLEAN Timeout;
+
+ //
+ // Count of the number of times we have retried a command.
+ //
+ UCHAR TimeoutCount;
+
+ //
+ // Points to an Mdl which points to this buffer
+ //
+ PNDIS_BUFFER FlushBuffer;
+
+} TOK162_SUPER_COMMAND_BLOCK, *PTOK162_SUPER_COMMAND_BLOCK;
+
+//
+// In addition to the Receive Entry fields which the TOK162HW.H
+// defines, we need some additional fields for our own purposes.
+// To ensure that these fields are properly aligned (and to
+// ensure that the actual Receive Entry is properly aligned)
+// we'll defined a Super Receive Entry. This structure will
+// contain a "normal" TOK162 Receive Entry plus some additional
+// fields.
+//
+typedef struct _TOK162_SUPER_RECEIVE_LIST {
+
+ //
+ // The actual TOK162 Receive List.
+ //
+ TOK162_RECEIVE_LIST Hardware;
+
+ //
+ // This contains the physical address of the above Receive List.
+ //
+ NDIS_PHYSICAL_ADDRESS Self;
+
+ //
+ // This contains the virtual address of this Receive List's
+ // frame buffer.
+ //
+ PVOID ReceiveBuffer;
+ NDIS_PHYSICAL_ADDRESS ReceiveBufferPhysical;
+
+ //
+ // This contains the virtual address of the next
+ // Receive List in the Receive Queue.
+ //
+ struct _TOK162_SUPER_RECEIVE_LIST *NextEntry;
+
+ //
+ // Points to an Mdl which points to this buffer
+ //
+ PNDIS_BUFFER FlushBuffer;
+
+} TOK162_SUPER_RECEIVE_LIST, *PTOK162_SUPER_RECEIVE_LIST;
+
+//
+// Adapter Structure
+//
+
+typedef struct _TOK162_ADAPTER {
+
+ //
+ // Handle given by NDIS when the miniport was initialized.
+ //
+ NDIS_HANDLE MiniportAdapterHandle;
+
+ //
+ // Interrupt pointers and variables for the adapter
+ //
+ NDIS_MINIPORT_INTERRUPT Interrupt;
+ USHORT InterruptLevel;
+
+ //
+ // Are we running at 16Mbps?
+ //
+ BOOLEAN Running16Mbps;
+
+ //
+ // Pointers for the System Command Block for the adapter
+ //
+ PSCB Scb;
+ NDIS_PHYSICAL_ADDRESS ScbPhysical;
+
+ //
+ // Pointers for the System Status Block for the adapter
+ //
+ PSSB Ssb;
+ NDIS_PHYSICAL_ADDRESS SsbPhysical;
+
+ //
+ // Command queue and related variables
+ //
+ PTOK162_SUPER_COMMAND_BLOCK CommandQueue;
+ NDIS_PHYSICAL_ADDRESS CommandQueuePhysical;
+
+ //
+ // Index to next command block
+ //
+ UINT NextCommandBlock;
+
+ //
+ // Number of command blocks available for use
+ //
+ UINT NumberOfAvailableCommandBlocks;
+
+ //
+ // Active command.
+ //
+ PTOK162_SUPER_COMMAND_BLOCK CommandOnCard;
+
+ //
+ // First pending command.
+ //
+ PTOK162_SUPER_COMMAND_BLOCK WaitingCommandHead;
+
+ //
+ // Last pending command.
+ //
+ PTOK162_SUPER_COMMAND_BLOCK WaitingCommandTail;
+
+ //
+ // Current packet filter on adapter
+ //
+ UINT CurrentPacketFilter;
+
+ //
+ // Is there an outstanding request
+ //
+ BOOLEAN RequestInProgress;
+
+ //
+ // Number of bytes needed and written.
+ //
+ PUINT BytesWritten;
+ PUINT BytesNeeded;
+
+ //
+ // Current Oid processing.
+ //
+ NDIS_OID Oid;
+
+ //
+ // Buffer and length of buffer used for doing query/set info calls.
+ //
+ PVOID InformationBuffer;
+ UINT InformationBufferLength;
+
+ //
+ // Current interrupt value
+ //
+ USHORT InterruptMask;
+
+ //
+ // Command that caused the interrupt
+ //
+ USHORT SsbCommand;
+
+ //
+ // The status variables that are saved as the result of an interrupt
+ //
+ USHORT SsbStatus1;
+ USHORT SsbStatus2;
+ USHORT SsbStatus3;
+
+ //
+ // The I/O Base address of the adapter.
+ //
+ ULONG PortIOBase;
+ PVOID PortIOAddress;
+
+ //
+ // Pointers and variables for the Open block for the adapter
+ //
+ POPEN_COMMAND Open;
+ NDIS_PHYSICAL_ADDRESS OpenPhysical;
+
+ //
+ // The network address for the adapter and the current one being used.
+ //
+ CHAR NetworkAddress[TOK162_LENGTH_OF_ADDRESS];
+ CHAR CurrentAddress[TOK162_LENGTH_OF_ADDRESS];
+
+ //
+ // Functional and Group Addresses for the adapter
+ //
+ ULONG FunctionalAddress;
+ ULONG GroupAddress;
+
+ //
+ // Pointer to the Receive Queue.
+ //
+ PTOK162_SUPER_RECEIVE_LIST ReceiveQueue;
+ NDIS_PHYSICAL_ADDRESS ReceiveQueuePhysical;
+
+ //
+ // Pointer to the current receive list
+ //
+ PTOK162_SUPER_RECEIVE_LIST ReceiveQueueCurrent;
+
+ //
+ // Number of frame header bytes in the buffer.
+ //
+ USHORT SizeOfReceivedHeader;
+
+ //
+ // Count of the receive buffers
+ //
+ UINT NumberOfReceiveBuffers;
+
+ //
+ // Size of the receive buffer, based on the ring speed.
+ //
+ USHORT ReceiveBufferSize;
+
+ //
+ // The receive flush buffer pool handle
+ //
+ PNDIS_HANDLE FlushBufferPoolHandle;
+
+ //
+ // Pointer to the Transmit Command Queue.
+ //
+ PTOK162_SUPER_COMMAND_BLOCK TransmitQueue;
+ NDIS_PHYSICAL_ADDRESS TransmitQueuePhysical;
+
+ //
+ // Index of next available transmit block
+ //
+ UINT NextTransmitBlock;
+
+ //
+ // Pointer to active transmit.
+ //
+ PTOK162_SUPER_COMMAND_BLOCK TransmitOnCard;
+
+ //
+ // Pointer to head of waiting queue.
+ //
+ PTOK162_SUPER_COMMAND_BLOCK WaitingTransmitHead;
+
+ //
+ // Pointer to tail of waiting queue
+ //
+ PTOK162_SUPER_COMMAND_BLOCK WaitingTransmitTail;
+
+ //
+ // Number of transmit blocks currently free
+ //
+ UINT NumberOfAvailableTransmitBlocks;
+
+ //
+ // Total number of transmit blocks/lists
+ //
+ UINT NumberOfTransmitLists;
+
+ //
+ // Maximum number of physical buffers that we can handle and still not
+ // have to merge the packet
+ //
+ USHORT TransmitThreshold;
+
+ //
+ // Flag that when enabled lets routines know that a reset
+ // is in progress.
+ //
+ BOOLEAN ResetInProgress;
+
+ //
+ // Are we doing the initial initialization?
+ //
+ BOOLEAN InitialInit;
+
+ //
+ // Has the initial open completed?
+ //
+ BOOLEAN InitialOpenComplete;
+
+ //
+ // Has the initial receive command been sent
+ //
+ BOOLEAN InitialReceiveSent;
+
+ //
+ // Last open error code.
+ //
+ USHORT OpenErrorCode;
+
+ //
+ // Reset State
+ //
+ USHORT ResetState;
+
+ //
+ // Variables to keep track of the number of retries attempted during
+ // a reset
+ //
+ USHORT ResetRetries;
+ USHORT InitRetries;
+
+ //
+ // Result of Reset command
+ //
+ NDIS_STATUS ResetResult;
+
+ //
+ // Offsets into adapter memory for different structures.
+ // These are obtained at initialization time and the values
+ // are read using the READ.ADAPTER DMA command.
+ //
+ USHORT UniversalAddress;
+ USHORT MicrocodeLevel;
+ USHORT AdapterAddresses;
+ USHORT AdapterParms;
+ USHORT MacBuffer;
+
+ //
+ // Buffer for READ.ERROR.LOG
+ //
+ PTOK162_ERRORLOG ErrorLog;
+ NDIS_PHYSICAL_ADDRESS ErrorLogPhysical;
+
+ //
+ // Buffer for READ.ADAPTER for node addresses. If more info is needed
+ // in the future, this will have to be changed as the current addresses
+ // are being stored here (func,node,group)
+ //
+ PTOK162_READADAPTERBUF AdapterBuf;
+ NDIS_PHYSICAL_ADDRESS AdapterBufPhysical;
+
+ //
+ // Counters to hold the various number of errors/statistics for both
+ // reception and transmission.
+ //
+ UINT ReceiveCongestionError;
+ UINT LineError;
+ UINT LostFrameError;
+ UINT BurstError;
+ UINT FrameCopiedError;
+ UINT TokenError;
+ UINT InternalError;
+ UINT ARIFCIError;
+ UINT AbortDelimeter;
+ UINT DMABusError;
+
+ //
+ // Packet counts
+ //
+ UINT GoodTransmits;
+ UINT GoodReceives;
+ UINT TransmitsQueued;
+ UINT BadTransmits;
+ UINT BadReceives;
+
+ //
+ // Timer objects for TOK162InterruptHandler and TOK162ResetHandler
+ //
+ NDIS_MINIPORT_TIMER DeferredTimer;
+ NDIS_MINIPORT_TIMER ResetTimer;
+
+ //
+ // Holds number of different types of RING.STATUS.CHANGE
+ // indications.
+ //
+ UINT SignalLoss;
+ UINT HardError;
+ UINT SoftError;
+ UINT TransmitBeacon;
+ UINT LobeWireFault;
+ UINT AutoRemovalError;
+ UINT RemoveReceived;
+ UINT CounterOverflow;
+ UINT SingleStation;
+ UINT RingRecovery;
+
+ //
+ // Current state of the ring.
+ //
+ NDIS_802_5_RING_STATE CurrentRingState;
+
+ //
+ // Last ring status indicated to protocols.
+ //
+ NDIS_STATUS LastNotifyStatus;
+
+ //
+ // This is a pointer to the Configuration Block for this
+ // adapter. The Configuration Block will be modified during
+ // changes to the packet filter.
+ //
+ TOK162_CONFIGURATION_BLOCK ConfigurationBlock;
+
+ //
+ // Pointer to the initialization block
+ //
+ PADAPTER_INITIALIZATION InitializationBlock;
+ NDIS_PHYSICAL_ADDRESS InitializationBlockPhysical;
+
+ //
+ // This points to the next adapter registered for the same Miniport
+ //
+ LIST_ENTRY AdapterList;
+
+} TOK162_ADAPTER,*PTOK162_ADAPTER;
+
+//
+// Given a MiniportContextHandle return the PTOK162_ADAPTER
+// it represents.
+//
+#define PTOK162_ADAPTER_FROM_CONTEXT_HANDLE(Handle) \
+ ((PTOK162_ADAPTER)(Handle))
+
+//
+// This record type is inserted into the MiniportReserved portion
+// of the packet header when the packet is going through the
+// staged allocation of buffer space prior to the actual send.
+//
+typedef struct _TOK162_RESERVED {
+
+ //
+ // Number of Buffers to move
+ //
+ UINT NdisBuffersToMove;
+
+ //
+ // Don't need this part. Reserve it.
+ //
+ UINT Reserved;
+
+
+} TOK162_RESERVED,*PTOK162_RESERVED;
+
+//
+// This macro will return a pointer to the TOK162 reserved portion
+// of a packet given a pointer to a packet.
+//
+#define PTOK162_RESERVED_FROM_PACKET(Packet) \
+ ((PTOK162_RESERVED)((Packet)->MiniportReserved))
+
+#include <tok162pr.h>