?? interrup.c
字號(hào):
WriteWord(MMU_CMD,MC_FREEPKT);
// Acknowledge the interrupt
SelectBank(BANK2);
WriteWord(INT_REG,ReadWord(INT_REG) & (0xff00 | TX_INT));
// Re-enable Transmission
SelectBank(BANK0);
WriteWord(TCR,ReadWord(TCR)|TCR_ENABLE);
// Get next interrupt, if any
CardGetInterruptStatus(Adapter, &InterruptStatus);
}
while(InterruptStatus & RCV_INT) {
USHORT wStatusWord;
USHORT wControlWord;
// PUSHORT pwData = (PUSHORT)PacketBuffer;
PUSHORT pwData = (PUSHORT)Adapter->Lookahead;
UINT PacketLength;
UINT i;
Adapter->ReceivePacketCount++;
// Setup pointer address register to point to first byte of Frame
SelectBank(BANK2);
WriteWord(POINTER,0xE000);
// Check for an error
wStatusWord = ReadWord(DATA_1);
// DEBUGMSG(ZONE_INTR, (TEXT("CELAN:Statsu word = %04x \r\n"),wStatusWord));
if(!(wStatusWord & 0xAC00)) {
// Read packet length
PacketLength = (0x07ff & ReadWord(DATA_1))-6;
DEBUGMSG(ZONE_INTR, (TEXT("CELAN:Packet length = %04x \r\n"),PacketLength));
if (PacketLength>1518) {
DEBUGMSG(ZONE_ERROR, (TEXT("CELAN:Packet too big.\r\n")));
DEBUGMSG(ZONE_ERROR, (TEXT("CELAN:Packet length = %04x \r\n"),PacketLength));
PacketLength=1518;
}
// Read all data
for(i=0;i<(PacketLength>>1);i++) {
*pwData = ReadWord(DATA_1);
DEBUGMSG(ZONE_INTR, (TEXT("%04x "),*pwData));
pwData++;
}
wControlWord = ReadWord(DATA_1);
if(wControlWord & 0x2000) {
*pwData = wControlWord;
DEBUGMSG(ZONE_INTR, (TEXT("Odd data %04x \r\n"),*pwData));
PacketLength++;
}
DEBUGMSG(ZONE_INTR, (TEXT("\r\n"),*pwData));
if(PacketLength < Adapter->MaxLookAhead + CELAN_HEADER_SIZE) {
PacketLength = Adapter->MaxLookAhead + CELAN_HEADER_SIZE;
}
if(PacketLength < CELAN_HEADER_SIZE) {
DEBUGMSG(ZONE_INTR,
(TEXT("Calling NdisMEtheIndicateReceive %x, %x, %x, %x, %x, %x, %x\r\n"),
Adapter->MiniportAdapterHandle,
Adapter,
Adapter->Lookahead,
PacketLength,
NULL,
0,
0
));
NdisMEthIndicateReceive(
Adapter->MiniportAdapterHandle,
(NDIS_HANDLE)Adapter,
(PCHAR)Adapter->Lookahead,
PacketLength,
NULL,
0,
0
);
} else {
DEBUGMSG(ZONE_INTR,
(TEXT("Calling NdisMEtheIndicateReceive %x, %x, %x, %x, %x, %x, %x\r\n"),
Adapter->MiniportAdapterHandle,
Adapter,
Adapter->Lookahead,
CELAN_HEADER_SIZE,
Adapter->Lookahead+CELAN_HEADER_SIZE,
PacketLength-CELAN_HEADER_SIZE,
PacketLength-CELAN_HEADER_SIZE
));
NdisMEthIndicateReceive(
Adapter->MiniportAdapterHandle,
(NDIS_HANDLE)Adapter,
(PCHAR)Adapter->Lookahead,
CELAN_HEADER_SIZE,
(PCHAR)Adapter->Lookahead+CELAN_HEADER_SIZE,
PacketLength-CELAN_HEADER_SIZE,
PacketLength-CELAN_HEADER_SIZE
);
}
Adapter->FramesRcvGood++;
DEBUGMSG(ZONE_INTR, (TEXT("Calling NdisMEtheIndicateReceiveComplete\r\n")));
NdisMEthIndicateReceiveComplete(Adapter->MiniportAdapterHandle);
} else {
DEBUGMSG(ZONE_ERROR,(TEXT("Receive frame status error (%04x)\r\n"),wStatusWord));
if (wStatusWord & 0x8000)
Adapter->FrameAlignmentErrors++;
if (wStatusWord & 0x2000)
Adapter->CrcErrors++;
}
// Release the memory for the received frame
WriteWord(MMU_CMD,0x0080);
while(ReadWord(MMU_CMD)&1);
// Get next interrupt, if any
CardGetInterruptStatus(Adapter, &InterruptStatus);
}
// Re-enable receiving
SelectBank(BANK0);
WriteWord(RCR,Adapter->NicReceiveConfig);
SelectBank(Bank);
}
NDIS_STATUS
CelanSend(
IN NDIS_HANDLE MiniportAdapterContext,
IN PNDIS_PACKET Packet,
IN UINT Flags
)
/*++
Routine Description:
The CelanSend request instructs a driver to transmit a packet through
the adapter onto the medium.
Arguments:
MiniportAdapterContext - Context registered with the wrapper, really
a pointer to the adapter.
Packet - A pointer to a descriptor for the packet that is to be
transmitted.
SendFlags - Optional send flags
Notes:
This miniport driver will always accept a send. This is because
the Celan has limited send resources and the driver needs packets
to copy to the adapter immediately after a transmit completes in
order to keep the adapter as busy as possible.
This is not required for other adapters, as they have enough
resources to keep the transmitter busy until the wrapper submits
the next packet.
--*/
{
PUCHAR CurBufAddress;
UINT CurBufLen;
UINT PacketLength;
PNDIS_BUFFER CurBuffer;
int i;
USHORT wFrameHandle;
USHORT cwBufferSize;
BOOL CurHiByte=FALSE;
USHORT CurData;
#define WAIT_LOOP 1000000
PCELAN_ADAPTER Adapter = (PCELAN_ADAPTER)(MiniportAdapterContext);
DEBUGMSG(ZONE_FUNCTION, (TEXT("+CELAN:Send\r\n")));
// Get the packet length and the first buffer
NdisQueryPacket(Packet,NULL,NULL,&CurBuffer,&PacketLength);
DEBUGMSG(ZONE_XMIT, (TEXT("The Packet length is %d bytes.\r\n"),PacketLength));
// Skip 0 length copies
if (PacketLength == 0) {
return NDIS_STATUS_SUCCESS;
}
if (PacketLength >= 0x800) {
DEBUGMSG(ZONE_ERROR, (TEXT("CelanSend : The Packet is too big(%d bytes)\r\n"),PacketLength));
return NDIS_STATUS_FAILURE;
}
// Calcurate buffer size
cwBufferSize = 2 + 2 + PacketLength + 1;
if (cwBufferSize & 1) {
cwBufferSize++;
}
// Allocate TX buffer
DEBUGMSG(ZONE_XMIT, (TEXT("Allocationg buffers...\r\n")));
SelectBank(BANK2);
WriteWord(MMU_CMD,MC_ALLOC|(cwBufferSize>>8));
// Loop here until the request is satisfied, or we timeout
for (i=0;(i<WAIT_LOOP)&&!(ReadWord(INT_REG) & ALLOC_INT);i++);
if(i==WAIT_LOOP) {
PrintRegs;
DEBUGMSG(ZONE_ERROR, (TEXT("Allocationg timeout.\r\n")));
return NDIS_STATUS_FAILURE;
}
// Get the allocated packet number
wFrameHandle = ReadWord(PNR_ARR) >> 8;
DEBUGMSG(ZONE_XMIT, (TEXT(" Packet #%d is allocated.\r\n"),wFrameHandle));
// Set the packet number to be accessed
WriteWord(PNR_ARR,wFrameHandle);
// Initialize pointer
WriteWord(POINTER,PTR_AUTOINC); // Auto increment mode
// Get the first non-zero buffer
NdisQueryBuffer(CurBuffer,(PVOID*)&CurBufAddress,&CurBufLen);
while(CurBuffer && (CurBufLen == 0)) {
NdisGetNextBuffer(CurBuffer,&CurBuffer);
NdisQueryBuffer(CurBuffer,(PVOID*)&CurBufAddress,&CurBufLen);
}
// Write the Status word
WriteWord(DATA_1,0);
// Write the byte count
WriteWord(DATA_1,cwBufferSize);
do {
DEBUGMSG(ZONE_XMIT, (TEXT("Buffer %x = %d byte.\r\n"),CurBufAddress,CurBufLen));
while(CurBufLen) {
DEBUGMSG(ZONE_XMIT, (TEXT("%02x "),*CurBufAddress));
if (CurHiByte) {
CurData |= (*CurBufAddress)<<8;
WriteWord(DATA_1,CurData);
CurHiByte = FALSE;
} else {
CurData = *CurBufAddress;
CurHiByte = TRUE;
}
CurBufAddress++;
CurBufLen--;
PacketLength--;
}
DEBUGMSG(ZONE_XMIT, (TEXT("\r\n")));
//
// Move to the next buffer
//
NdisGetNextBuffer(CurBuffer, &CurBuffer);
if (CurBuffer){
NdisQueryBuffer(CurBuffer, (PVOID *)&CurBufAddress, &CurBufLen);
}
//
// Get address and length of the next buffer
//
while (CurBuffer && (CurBufLen == 0)) {
NdisGetNextBuffer(CurBuffer, &CurBuffer);
if (CurBuffer){
NdisQueryBuffer(CurBuffer, (PVOID *)&CurBufAddress, &CurBufLen);
}
}
} while (CurBuffer);
if (PacketLength !=0 ) {
DEBUGMSG(ZONE_ERROR,(TEXT("Fatal Error, packet length mismatch!!\r\r")));
}
// Write control byte
if (CurHiByte) {
CurData = CurData | 0x3000;
WriteWord(DATA_1,CurData);
} else {
WriteWord(DATA_1,0x1000);
}
// Enqueue Frame number into TX FIFO
DEBUGMSG(ZONE_XMIT, (TEXT("Start transmission.\r\n")));
WriteWord(MMU_CMD, MC_ENQUEUE);
Adapter->FramesXmitGood++;
DEBUGMSG(ZONE_FUNCTION, (TEXT("-CELAN:Send\r\n")));
return(NDIS_STATUS_SUCCESS);
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -