📄 nicinterrupt.c
字号:
rxPackets=NIC_READ_PORT_UCHAR(pAdapter->IoBaseAddress , FRAMES_RECEIVED_OK_REGISTER);
txPackets=NIC_READ_PORT_UCHAR(pAdapter->IoBaseAddress , FRAMES_TRANSMITTED_OK_REGISTER);
highPackets=NIC_READ_PORT_UCHAR(pAdapter->IoBaseAddress , UPPER_FRAMES_OK_REGISTER);
rxPackets += ((highPackets & 0x03) << 8);
txPackets += ((highPackets & 0x30) << 4);
/* if (pAdapter->Hardware.SQEDisable) statistics->TxSQEErrors += txPackets; */
pStatistics->RxFramesOk += rxPackets;
pStatistics->TxFramesOk += txPackets;
rxBytes=NIC_READ_PORT_USHORT( pAdapter->IoBaseAddress , BYTES_RECEIVED_OK_REGISTER);
txBytes=NIC_READ_PORT_USHORT( pAdapter->IoBaseAddress , BYTES_TRANSMITTED_OK_REGISTER);
/*some thing are in Win 5 Registers, we'll switch to registers win 4*/
NIC_COMMAND( pAdapter->IoBaseAddress , COMMAND_SELECT_REGISTER_WINDOW | REGISTER_WINDOW_4);
highBytes=NIC_READ_PORT_UCHAR( pAdapter->IoBaseAddress, UPPER_BYTES_OK_REGISTER);
rxBytes += ((highBytes & 0x0F) << 8);
txBytes += ((highBytes & 0xF0) << 4);
pStatistics->RxBytesOk += rxBytes;
pStatistics->TxBytesOk += txBytes;
retValueWord=NIC_READ_PORT_UCHAR( pAdapter->IoBaseAddress , BAD_SSD_REGISTER);
pStatistics->RxBadSSD +=retValueWord;
DebugMsg(" Now Update Statistic Interuptor -- Done!\n");
return;
}
/***************************************************************
*** his routine handles the Count Down Timer Interrupt.
*** called by Interrupt handler.
**/
VOID NIC_IntCountDownTimer(IN NIC_INFORMATION * pAdapter)
{
/* PDPD_LIST_ENTRY pHeadDPDVirtual = pAdapter->HeadDPDVirtual;
DebugMsg(" Now Count Down Timer Interrupts! \n");
This clears the FSH_DPD_EMPTY and a raise condition of hardware.
pAdapter->TailDPDVirtual->FrameStartHeader = 0;
while (1)
{
if (!(headDPDVirtual->FrameStartHeader & FSH_DOWN_COMPLETE))
break;
ASSERT(headDPDVirtual->Packet != NULL);
DEV_FREE_SKB(headDPDVirtual->SocketBuffer);
headDPDVirtual->SocketBuffer = NULL;
Clear the down complete bit in the frame start header.
headDPDVirtual->FrameStartHeader = 0;
pAdapter->BytesInDPDQueue -= headDPDVirtual->PacketLength;
headDPDVirtual = headDPDVirtual->Next;
ASSERT(pAdapter->HeadDPDVirtual != NULL);
}
pAdapter->HeadDPDVirtual = headDPDVirtual;
if (pAdapter->BytesInDPDQueue)
tc90x_SetCountDownTimer(pAdapter);
If DPD ring is full, run the bottom half
if ((device->tbusy) && (pAdapter->DPDRingFull==TRUE))
{ DBGPRINT_SEND(("CountdownTimer: set RingFull false,mark bh\n"));
pAdapter->DPDRingFull = FALSE;
clear_bit(0, (void*)&device->tbusy);
mark_bh(NET_BH);
}
*/
DebugMsg(" Count Down Timer Interuptor--Done!\n");
}
/*****************************************************************
*** This routine handles the receive event interrupt ,
*** called from Interrupt handler rountines
**/
void NIC_IntUpComplete(IN PNIC_INFORMATION pAdapter )
{
PUPD_LIST_ENTRY pThisUPD = pAdapter->Resources.pHeadUPD;
/* PSKB socketBuffer; */
DWORD upPacketStatus;
DWORD lFrameLength;
PPCIADDR pDataBufferNew;
PETHNET_ADDRESS_INFORMATION EthAddr;
while (1)
{
/* If done with all UPDs break. */
upPacketStatus = pThisUPD->UpPacketStatus;
/* Get the frame length from the UPD. */
lFrameLength = upPacketStatus & UP_PACKET_LENGTH_MASK ;
if (! (upPacketStatus & UP_PACKET_STATUS_COMPLETE) )
{
break; /*error bits are undefined until Complete Bit set*/
}
/* Check if there is any error bit set. */
if (upPacketStatus & UP_PACKET_STATUS_ERROR)
{
if ( ( lFrameLength < ETHERNET_MINIMUM_FRAME_SIZE) ||
(upPacketStatus & UP_PACKET_STATUS_OVERRUN) ||
(upPacketStatus & UP_PACKET_STATUS_ALIGNMENT_ERROR) ||
(upPacketStatus & UP_PACKET_STATUS_CRC_ERROR) ||
(upPacketStatus & UP_PACKET_STATUS_OVERSIZE_FRAME) )
{
if (upPacketStatus & UP_PACKET_STATUS_RUNT_FRAME)
{
}
if (upPacketStatus & UP_PACKET_STATUS_ALIGNMENT_ERROR)
{
pAdapter->Statistics.RxAlignmentError++;
}
if (upPacketStatus & UP_PACKET_STATUS_CRC_ERROR)
{
pAdapter->Statistics.RxBadCRCError++;
}
if (upPacketStatus & UP_PACKET_STATUS_OVERSIZE_FRAME)
{
pAdapter->Statistics.RxOversizeError++;
}
/* Discard this packet and move on. */
pThisUPD->UpPacketStatus = 0;
pThisUPD = pThisUPD->pNext;
continue;
}
else
{
pAdapter->Statistics.RxFramesOk++;
pAdapter->Statistics.RxBytesOk += lFrameLength;
}
}
/* Try to allocate SKB
socketBuffer = DEV_ALLOC_SKB( ETHERNET_MAXIMUM_FRAME_SIZE + 2 +
pAdapter->Hardware.CacheLineSize);
if (socketBuffer != 0)
{*/
/* Align IP on 16 byte boundaries*/
/*skb_reserve(socketBuffer, 2);
dataPointer = skb_put(socketBuffer, ETHERNET_MAXIMUM_FRAME_SIZE );
pCurrentUPDVirtual->SGList[0].Address = virt_to_bus(dataPointer);
pCurrentUPDVirtual->SGList[0].Count = ETHERNET_MAXIMUM_FRAME_SIZE | 0x80000000;
pCurrentUPDVirtual->RxBufferVirtual = dataPointer;
pCurrentUPDVirtual->SocketBuffer->protocol =
eth_type_trans(
pCurrentUPDVirtual->SocketBuffer,
device);
SetRxTcpIpChecksumOffloadFlagsInSocketBuffer(
pAdapter,
pCurrentUPDVirtual->SocketBuffer,
pCurrentUPDVirtual->UpPacketStatus);
netif_rx(pCurrentUPDVirtual->SocketBuffer);
device->last_rx = jiffies;
pCurrentUPDVirtual->SocketBuffer = socketBuffer;
Check for Multicast
EthAddr = (PETH_ADDR)(pCurrentUPDVirtual->SocketBuffer->data);
if( (EthAddr->Addr[0] & ETH_MULTICAST_BIT) &&
!(COMPARE_MACS(EthAddr, BroadcastAddr)) )
pAdapter->Statistics.Rx_MulticastPkts++;*/
/* }
else
{
DebugMsg("Memory allocation failed!");
some thing else must to be done !
}
pCurrentUPDVirtual->UpPacketStatus = 0;
pCurrentUPDVirtual = pCurrentUPDVirtual->Next;
*/
}
pAdapter->Resources.pHeadUPD = pThisUPD;
return;
}
/****************************************************************
*** This routine handles the Tx complete event.
*** called from Interrupt Handler rountines
**/
VOID NIC_IntTxComplete(IN PNIC_INFORMATION pAdapter )
{
UCHAR txStatus;
txStatus=NIC_READ_PORT_UCHAR (pAdapter->IoBaseAddress , TX_STATUS_REGISTER);
NIC_WRITE_PORT_UCHAR(pAdapter->IoBaseAddress , TX_STATUS_REGISTER,txStatus);
if (! (txStatus & TX_STATUS_COMPLETE) )
{ /*when TX_STATUS_COMPLETE bit (bit 7)is false, other bits are undefined*/
DebugMsg("Nothing happens , don't vex me anymore!\n");
return;
}
if (txStatus & TX_STATUS_RECLAIM_ERROR)
{
/* Reclaim error occurs. */
pAdapter->Statistics.TxReclaimError++;
}
if (txStatus & TX_STATUS_STACK_OVERFLOW)
{
/* STACK OVERFLOW error occurs,we must reenable the Transmitter. */
pAdapter->Statistics.TxStackOverFlow ++;
NIC_COMMAND(pAdapter->IoBaseAddress , COMMAND_TX_ENABLE);
}
else if (txStatus & TX_STATUS_MAXIMUM_COLLISION)
{
pAdapter->Statistics.TxMaximumCollisions++;
/**Typically the Driver should resubmit the data packet which
encounted 16 times collision for transmitting ,
but we don't do this*/
NIC_COMMAND(pAdapter->IoBaseAddress , COMMAND_TX_ENABLE);
}
else if (txStatus & TX_STATUS_HWERROR)
{
/*under run error , must reset Tx*/
pAdapter->Statistics.TxHWErrors++;
/* if (NIC_TxResetAndEnable(pAdapter) != NIC_STATUS_SUCCESS) */
{
pAdapter->Hardware.Status = HARDWARE_STATUS_HUNG;
return;
}
}
else if (txStatus & TX_STATUS_JABBER)
{ /*NIC feel too long it's in Tx progress , must reset*/
pAdapter->Statistics.TxJabberError++;
/* if (NIC_TxResetAndEnable(pAdapter) != NIC_STATUS_SUCCESS) */
{
pAdapter->Hardware.Status = HARDWARE_STATUS_HUNG;
return;
}
}
else
{
if (txStatus != 0 )
{
pAdapter->Statistics.TxUnknownError++;
/* NIC_COMMAND(pAdapter, COMMAND_TX_ENABLE); */
}
}
return;
}
/** Above are rountines about interrupt handlers
*** End of Interrupt.c
******************************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -