⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lan91c96_intr.c

📁 ARM9基于WINDOWSCE的BSP源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
    
    //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 + -