Technical information

8-15
Sample Driver
Receive Interrupt Handling
When a packet is received, the AIC-6915 adds a new entry to the Receive Completion
Descriptor Queue and generates either an
E
ARLY
R
X
Q1I
NT
(or
E
ARLY
R
X
Q2I
NT
) or an
R
X
Q1D
ONE
I
NT
(or
R
X
Q2D
ONE
I
NT
), depending on which receive interrupts have been
enabled. When the driver processes this interrupt, it must first read the Receive
Completion Queue consumer and producer indices. For a single completion queue
implementation, these indices are contained in registers
C
OMPLETION
Q
UEUE
1C
ONSUMER
I
NDEX
and
C
OMPLETION
Q
UEUE
1P
RODUCER
I
NDEX
. The
consumer index points to the next Receive Completion Descriptor which has not yet been
processed by the driver. In this Receive Completion Descriptor, the
E
ND
I
NDEX
field is an
index to the Receive Buffer Descriptor which contains the packet just received. The driver
uses this index to extract the Receive Buffer containing the packet just received. The
packet length and receive status are also contained in the Completion Descriptor.
Example:
// Windows NT example
// Receive Interrupt Handling Pseudocode
// This example is for the polling model
// Illustrates the use of a single Receive Completion Queue and Receive Buffer
// Queue
// Process the receive interrupt
// Read the Completion Queue pointer registers
AIC6915_READ_REG(Adapter->RegisterBaseVa->CompletionQueue1ProducerIndex,
&CompletionQueue1ProducerValue);
AIC6915_READ_REG(Adapter->RegisterBaseVa->CompletionQueue1ConsumerIndex,
&CompletionQueue1ConsumerValue);
// Get the Receive Completion Queue producer and consumer index fields
RxComQProducerIndex =
CompletionQueue1ProducerValue.RxCompletionQ1ProducerIndex;
RxComQConsumerIndex =
CompletionQueue1ConsumerValue.RxCompletionQ1ConsumerIndex;
// We got a receive interrupt. Process all Completion Queue entries until
// we’re caught up.
while (RxComQConsumerIndex != RxComQProducerIndex )
{
// Get the completion descriptor pointed to by the current consumer index
RxCompletionDesc = Adapter->RxCompletionDesc[RxComQConsumerIndex];
// Get the buffer descriptor index
RxDescIndex = RxCompletionDesc->EndIndex;
// Get the receive status and packet length
RxStatus = (USHORT)RxCompletionDesc->Status1;
Length = (USHORT)RxCompletionDesc->Length;
// Using the EndIndex in the completion descriptor, get the current
// receive buffer