📄 lan91c96_intr.c
字号:
//Read TXDONE Pkt# from FIFO Port Register
LAN91C96_Read(IOBase + BANK2_FIFOS, &PacketNumber);
PacketNumber &= 0x007F;
//Write to Packet Number Register
LAN91C96_Write(IOBase + BANK2_PNR,(USHORT) PacketNumber);
//Release the Packet
LAN91C96_Write(IOBase + BANK2_MMUCMD,(USHORT) CMD_REL_SPEC);
//Check for errors
LAN91C96_Write(IOBase + BANK_SELECT,(USHORT)0);
LAN91C96_Read(IOBase + BANK0_STS, &TempWord);
if (TempWord & TFS_OKAY)
{
RetStatus = NDIS_STATUS_SUCCESS;
//Update statistic counters
Adapter->Stat_TxOK++;
}
else
{
if (TempWord & TFS_ERROR)
{
RetStatus = NDIS_STATUS_FAILURE;
Adapter->Stat_TxError++;
}
}
//Release the packet ownership and return the status
LocalPkt = (MINIPORT_PACKET *) 0;
DequePacket(Adapter->AckPending, LocalPkt);
NdisPacket = CONTAINING_RECORD(LocalPkt,NDIS_PACKET,MiniportReserved[0]);
NdisMSendComplete(Adapter->AdapterHandle, NdisPacket, RetStatus);
//Ready for next packet
if (Adapter->TxResPending)
{
NdisMSendResourcesAvailable(Adapter->AdapterHandle);
Adapter->TxResPending = FALSE;
}
//Acknowledge the interrupt
LAN91C96_Write(IOBase + BANK_SELECT,(USHORT)2);
LAN91C96_Write(IOBase + BANK2_INT_STS, INT_TX_CMP);
RETAILMSG(ZONE_INTR, (TEXT("LAN91C96: <== TX Interrupt Handler\r\n")));
return;
}
VOID RCV_Interrupt_Handler (MINIPORT_ADAPTER *Adapter)
{
ULONG IOBase,
DataPort,
PtrPort,
RxFifoPort,
MMUPort;
USHORT FIFO,
PacketStatus,
PacketRange,
TempRange,
temp,Plength;
UCHAR *ReadBuffer;
MAC_RECEIVE_CONTEXT Context;
unsigned short * pBuffer;
// ULONG i=1;
RETAILMSG(ZONE_INTR, (TEXT("LAN91C96: ==> RCV Interrupt Handler\r\n")));
IOBase = Adapter->IOBase;
DataPort = IOBase + BANK2_DATA1;
PtrPort = IOBase + BANK2_PTR;
RxFifoPort = IOBase + BANK2_RX_FIFO;
MMUPort = IOBase;
//Check the fifo for the packets to be recvd
LAN91C96_Write(IOBase + BANK_SELECT,(USHORT)2);
LAN91C96_Read(IOBase + BANK2_FIFOS, &FIFO);
while(!((FIFO & FIFO_RX_EMPTY)))
{
// ULONG i=1;
//Set the pointer to Recieve Area, Auto Increment and Read mode
LAN91C96_Write(PtrPort, (USHORT) (PTR_RCV | PTR_AUTO | PTR_READ));
// LAN91C96_Write(PtrPort, (USHORT) (PTR_RCV | PTR_READ));
NdisStallExecution(1);
//Read the first word of the rx area to get the packet status and length
LAN91C96_Read(DataPort, &PacketStatus);
//*************************
// LAN91C96_Write(PtrPort, (USHORT) (PTR_RCV | PTR_READ |0x2));
// LAN91C96_Write(PtrPort, (USHORT) (PTR_AUTO));
LAN91C96_Read(DataPort, &PacketRange);
RETAILMSG(0, (TEXT("PacketStatus = 0x%x\r\n"),PacketStatus));
RETAILMSG(0, (TEXT("PacketRange = 0x%x\r\n"),PacketRange));
//*************************
//Check for errors. And discard if bad.
if ((PacketStatus & RFS_ERROR) || (PacketRange > LOOK_AHEAD_BUFFER_SIZE) || (PacketRange < MIN_FRAME_SIZE))
{
//Release the frame. This acknowledges the interrupt.
LAN91C96_Write(MMUPort, (USHORT) CMD_REM_REL_TOP);
//Update the counter
Adapter->Stat_RxError++;
if(PacketStatus & RFS_ALIGN)
Adapter->Stat_AlignError++;
//Get ready for the next packet
LAN91C96_Read( IOBase + BANK2_FIFOS, &FIFO);
continue;
}
if (Adapter->PromiscuousMode != TRUE)
{
if (PacketStatus & RFS_BCAST)
{
if (Adapter->RCVBroadcast == FALSE)
{
//Release the frame. This acknowledges the interrupt.
LAN91C96_Write(MMUPort, (USHORT) CMD_REM_REL_TOP);
//Get ready for the next packet
LAN91C96_Read( IOBase + BANK2_FIFOS, &FIFO);
continue;
}
}
else
{
if ((PacketStatus & RFS_MCAST) && (Adapter->RCVAllMulticast == FALSE))
{
//Recv only the mulitcast with the address in the multicast table
if(!CheckMultiCastAddress(ReadBuffer,Adapter))
{
//Release the frame. This acknowledges the interrupt.
LAN91C96_Write(MMUPort, (USHORT) CMD_REM_REL_TOP);
//Get ready for the next packet
LAN91C96_Read( IOBase + BANK2_FIFOS, &FIFO);
continue;
}
}
}
}
//Good frame received - adjust range for SMSC packet overhead.
PacketRange -= FRAME_OVERHEAD;
if (PacketStatus & RFS_ODD)
PacketRange++;
ReadBuffer = Adapter->LookAheadBuffer;
// NdisRawReadPortBufferUshort(DataPort,(PUSHORT) ReadBuffer,PacketRange>>1);
//{
pBuffer = (unsigned short *)ReadBuffer;
// Plength = (PacketRange>>1);
// RETAILMSG (0, (TEXT(" Plength = 0x%x\r\n"),PacketRange));
// LAN91C96_Write(PtrPort, (USHORT) (PTR_RCV | PTR_READ |PTR_AUTO |(0x4)));
*M68K_ADD = (DataPort + 1);
for(Plength = (PacketRange>>1);Plength>0;Plength--)
{
// LAN91C96_Write(PtrPort, (USHORT) (PTR_RCV | PTR_READ |(i*2+0x2)));
// LAN91C96_Write(PtrPort, (USHORT) (PTR_AUTO));
//********** LAN91C96_Read(DataPort, pBuffer);
*pBuffer++ = *M68K_DATA;
// RETAILMSG (ZQ, (TEXT(" pBuffer = 0x%x\r\n"),*pBuffer));
// pBuffer++;
// i++;
}
//}
if (PacketRange & 0x01)
{
// LAN91C96_Write(PtrPort, (USHORT) (PTR_RCV | PTR_READ |(i*2+0x2)));
// LAN91C96_Write(PtrPort, (USHORT) (PTR_AUTO));
//********** LAN91C96_Read(DataPort, &temp);
temp = *M68K_DATA;
ReadBuffer[PacketRange-1] = (temp&0xFF);
}
// Release the frame. This acknowledges the interrupt.
LAN91C96_Write(MMUPort,(USHORT) CMD_REM_REL_TOP);
Context.Range = PacketRange;
Context.PacketData = ReadBuffer;
TempRange = PacketRange - ETHERNET_HEADER_SIZE;
//Indicate the frame
NdisMEthIndicateReceive(Adapter->AdapterHandle,
(NDIS_HANDLE) &Context,
(void *) ReadBuffer,
(UINT) ETHERNET_HEADER_SIZE,
(void *) ((char *) ReadBuffer + ETHERNET_HEADER_SIZE),
TempRange,
TempRange);
Adapter->NeedIndComplete = TRUE;
//Update the counter
Adapter->Stat_RxOK++;
//Next Frame
LAN91C96_Write(IOBase + BANK_SELECT,(USHORT)2);
LAN91C96_Read( IOBase + BANK2_FIFOS, &FIFO);
}
if (Adapter->NeedIndComplete)
{
NdisMEthIndicateReceiveComplete(Adapter->AdapterHandle);
//Clear the TX resource pending, since the memory is available
NdisMSendResourcesAvailable(Adapter->AdapterHandle);
}
Adapter->NeedIndComplete = FALSE;
RETAILMSG(ZONE_INTR, (TEXT("LAN91C96: <== RCV Interrupt Handler\r\n")));
return;
}
BOOLEAN CheckMultiCastAddress(UCHAR *ReadBuffer, MINIPORT_ADAPTER *Adapter)
{
UINT Result;
PUCHAR ListEntry;
ULONG Count;
RETAILMSG(ZONE_INTR, (TEXT("LAN91C96: ==> CheckMultiCastAddress\r\n")));
Result = 1;
Count = 0;
ListEntry = Adapter->MulticastTable.MulticastTableEntry;
//If empty list then get out.
if(Adapter->MulticastTable.MulticastTableEntryCount == 0)
return FALSE;
// checking all the multicasttable entries against frame address.
for(Count = 0; Count <Adapter->MulticastTable.MulticastTableEntryCount; Count++)
{
// Compare the Ethernet Frame Address with MulticastTableList
ETH_COMPARE_NETWORK_ADDRESSES(ReadBuffer, ListEntry, &Result);
if(!Result) break;
ListEntry += 6;//See next entry in multicast list
}
//returning the value depending upon the MultiCastTableCount.
//If Less than TotalCount return TRUE means finds some multicast address
// same as frame adress
RETAILMSG(ZONE_INTR, (TEXT("LAN91C96: <== CheckMultiCastAddress\r\n")));
if(Count <= Adapter->MulticastTable.MulticastTableEntryCount)
return TRUE;
else
return FALSE;
}
VOID AllocIntEnabler (MINIPORT_ADAPTER *Adapter)
{
USHORT SavedBS, OldIntReg;
LAN91C96_Read(Adapter->IOBase + BANK_SELECT, &SavedBS);
LAN91C96_Write(Adapter->IOBase + BANK_SELECT,(USHORT) 2);
LAN91C96_Read(Adapter->IOBase + BANK2_INT_STS, &OldIntReg);
OldIntReg &= 0xFF00; //Donot ack
OldIntReg |= INT_ALLOC;
LAN91C96_Write(Adapter->IOBase + BANK2_INT_STS,OldIntReg);
LAN91C96_Write(Adapter->IOBase + BANK_SELECT, SavedBS);
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -