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

📄 ne2000.c

📁 三星2410的BSP开发包
💻 C
📖 第 1 页 / 共 4 页
字号:
    if (ramEnd & 0xffff0000) {
        pstop = 0xff;
    }

    //
    // Allocate 1 packet for transmit
    //
    tbb_start = (BYTE)(srambase>>8);
    pstart = tbb_start+6;   // Allocate 6 256 byte buffers for transmit

    // compute sramsize
    sramsize = ramEnd - srambase;

    EdbgOutputDebugString("EDBG:NE2000:HWRamTest: srambase: 0x%X, sramsize: 0x%X, pstart: 0x%B\r\n",
       srambase, sramsize, pstart);

    // check the full RAM bank
    if (!HWCheckRam(srambase,sramsize)) {
        EdbgOutputDebugString("EDBG:NE2000:HWRamTest full RAM check failed.\r\n");
        bRet = FALSE;
        goto hwrt_done;
    }

    bRet = TRUE;

hwrt_done:
    HWStartAdapter();
    return bRet;
}   // HWRamTest


/*

// Obsolete, now replaced by HWSetMCRegs()

//
//  HWClearMCRegs - Clear the adapter's multicast address registers.
//
static void
HWClearMCRegs()
{
    DWORD j;
    UsePage1();
    j = NIC_MC_ADDR;

    // Now clear out all multicast address registers.
    while (j < NIC_MC_ADDR+8) {
        WriteByte(j, 0);
        j++;
    }
    UsePage0();
}  // HWClearMCRegs
*/

////////////////////////////////////////////////////////////////////////////////
//	HWSetMCRegs()
//
//	Description:
//
//		This function is used to set the multicast registers.
//
//	Arguments:
//
//		pucMulticastRegs :: If not null then use this instead of 0xFF or 0x00
//						       depending on bAllMulticast below.
//
//		bAllMulticast	 :: TRUE == Set all to 0xff	:: FALSE = Set all to 0x00
//
//	Return value:
//
//
static void
HWSetMCRegs(PUCHAR	pucMulticastRegs, BOOL bAllMulticast)
{
	DWORD	j;
	UCHAR	ucData;
    
	UsePage1();	
	
	if (pucMulticastRegs)
	{
		EdbgOutputDebugString(
			"Ne2kDbg:: MulticastRegs set to : %x-%x-%x-%x-%x-%x-%x-%x\r\n",
			pucMulticastRegs[0],
			pucMulticastRegs[1],
			pucMulticastRegs[2],
			pucMulticastRegs[3],
			pucMulticastRegs[4],
			pucMulticastRegs[5],
			pucMulticastRegs[6],
			pucMulticastRegs[7]);

		for (j = 0 ; j < 8 ; j++)		
			WriteByte(NIC_MC_ADDR + j, pucMulticastRegs[j]);		
	}
	else
	{
		if (bAllMulticast)
		{
			EdbgOutputDebugString("Ne2kDbg:: HWSetMCRegs():: Set all to 0xff\r\n");
			ucData = 0xFF;
		}
		else
		{
			EdbgOutputDebugString("Ne2kDbg:: HWSetMCRegs():: Set all to 0x00\r\n");
			ucData = 0x00;
		}

		for (j = 0 ; j < 8 ; j++)
			WriteByte(NIC_MC_ADDR + j, ucData);	
	}

    UsePage0();

}	//	HWSetMCRegs()


//
//   HWInit - completely initialize the hardware and leave it in a
//          state that is ready to transmit and receive packets.
//
static BOOL
HWInit(void)
{
    int n;

    WriteCmd(NIC_AbortDmaStop); // Stop the NIC
    
    // Initialize Data Configuration register for auto remove.
    // This gets reset later on.
    WriteByte(NIC_DATA_CONFIG, NIC_DCR_FIFO|NIC_DCR_AUTO_INIT);

    // Bug workaround for SRAM memory protection.
    WriteByte(NIC_XMIT_START, 0xA0);
    WriteByte(NIC_XMIT_CONFIG, 0);
    WriteByte(NIC_RCV_CONFIG, NIC_RECEIVE_MONITOR_MODE);

    WriteByte(NIC_PAGE_START, 4);
    WriteByte(NIC_BOUNDARY,   4);
    WriteByte(NIC_PAGE_STOP, 0xff);
    WriteByte(NIC_XMIT_COUNT_LSB, 0x3c);
    WriteByte(NIC_XMIT_COUNT_MSB, 0);
    WriteByte(NIC_INTR_STATUS, 0xff);
    UsePage1Stop();
    WriteByte(NIC_CURRENT, 4);
    UsePage0();

    // If command register reflects the last command assume it is OK
    if (ReadCmd() != NIC_Page0) {
        EdbgOutputDebugString("EDBG:NE2000Init:HWInit failed to read cmd reg\r\n");
        goto hw_dead;
    }
    
    WriteByte(NIC_RMT_COUNT_LSB, 55); // initialization errata
    WriteCmd(NIC_RemoteDmaRd);

    HWStartAdapter();
    if (!HWRamTest()) { // see how much adapter RAM
        EdbgOutputDebugString("EDBG:NE2000Init:HWInit HWRamTest failed\r\n");
        goto hw_dead;
    }

    WriteCmd(NIC_AbortDmaStop);

    // Read the ethernet address
    // The NE2000 address PROM only decodes even addresses, so you
    // have to read WORDs and discard the high byte.
    WriteByte(NIC_RMT_COUNT_LSB, 12);
    WriteByte(NIC_RMT_COUNT_MSB, 0);
    WriteByte(NIC_RMT_ADDR_LSB, 0);
    WriteByte(NIC_RMT_ADDR_MSB, 0);
    WriteCmd(NIC_RemoteDmaRd);
    for (n = 0; n < 6; n++) {
        ethernetaddr[n] = (BYTE)ReadWord(NIC_RACK_NIC);
    }

    // copy node address to page1 physical address registers
    UsePage1Stop();
    for (n = 0; n < 6; n++) {
        WriteByte(NIC_PHYS_ADDR+n, ethernetaddr[n]);
    }
    
	//
	//	Init multicast registers to 0
	//

	memset(
		g_pucMulticastList,
		0x00,
		MAX_MULTICAST_LIST * 6);

	g_dwMulticastListInUse = 0x00;

	HWSetMCRegs(NULL, FALSE);				


    WriteCmd(NIC_AbortDmaStop); // back to page0

    // Initialize the page start, stop, and boundary registers based on the
    // results of ram_test().
    WriteByte(NIC_PAGE_START, pstart);
    WriteByte(NIC_BOUNDARY, (BYTE)(pstart+1));
    WriteByte(NIC_PAGE_STOP, pstop);
    UsePage1Stop();
    WriteByte(NIC_CURRENT, (BYTE)(pstart+1));
    WriteCmd(NIC_AbortDmaStop); // back to page0
    NextPage = pstart+1;
    tbb_start = (BYTE)(srambase >> 8);
    
    memset(erase_header, 0xff, sizeof(erase_header));
    return TRUE;

hw_dead:
    WriteCmd(NIC_AbortDmaStop); // stop NIC
    return FALSE;
} // HWinit


// This is called to initialze the ethernet low level driver.  The base address of the ethernet hardware
// is passed into the routine.  The routine will return TRUE for a successful initialization.
BOOL
NE2000Init( BYTE *pbBaseAddress, DWORD dwMultiplier, USHORT MacAddr[3])
{
    BOOL bRet;
    int n;
    PBYTE pDst;
    PBYTE pSrc;

    EdbgOutputDebugString("+EDBG:NE2000Init\r\n");
#ifdef USE_ISA_PNP_STUFF
    pbBaseAddress = NE2000InitISAPNP(DEFAULT_IOBASE, DEFAULT_IRQ);
#endif // USE_ISA_PNP_STUFF
    pbEthernetBase = pbBaseAddress;
    EdbgOutputDebugString("EDBG:NE2000Init using I/O range at 0x%X\r\n", pbBaseAddress);
    InitRcvQueue();
    bRet = HWInit();
	if( NULL != MacAddr ) {
	    pDst = (PBYTE)MacAddr;
    	pSrc = ethernetaddr;
	    for (n = 6; n; n--) {
    	    *pDst++ = *pSrc++;
	    }
	}
    EdbgOutputDebugString("-EDBG:NE2000Init\r\n");
    return bRet;
}   // NE2000Init

// Interrupts left disabled at init, call this function to turn them on
void
NE2000EnableInts()
{
    //EdbgOutputDebugString("NE2000EnableInts\n");
    bIntMask = IMR_RCV|IMR_XMIT|IMR_RCV_ERR|IMR_XMIT_ERR|IMR_OVERFLOW;
    UsePage0();
    WriteByte(NIC_INTR_MASK, bIntMask);
}

void
NE2000DisableInts()
{
    //EdbgOutputDebugString("NE2000DisableInts\n");
    bIntMask = 0;
    UsePage0();
    WriteByte(NIC_INTR_MASK, bIntMask);
}


////////////////////////////////////////////////////////////////////////////////
//	NE2000CurrentPacketFilter()
//	
//	Description:
//
//		This function is called to set the h/w filter.
//		We support:
//			PROMISCUOUS, ALL MULTICAST, BROADCAST, DIRECTED.
//
//	Arguments:
//
//		dwFilter::	The filter mode 
//
//	Return value:
//
//		TRUE if successful, FALSE otherwise.
//
void
Ne2000CurrentPacketFilter(DWORD	dwFilter)
{	
	DWORD	dwReceiveConfig = 0x00;


	if (dwFilter & (PACKET_TYPE_ALL_MULTICAST | PACKET_TYPE_PROMISCUOUS))
	{
		//
		//	Need all multicast..
		//
        HWSetMCRegs(NULL, TRUE);
	}
    else        
	{
		//
        //	No longer need "all multicast".        
		//	When we do support MULTICAST LIST then we should copy the list
		//	to the h/w here..
		//

		UCHAR	pucMulticastList[MAX_MULTICAST_LIST][6];

		memcpy(
			pucMulticastList,
			&(g_pucMulticastList[0][0]),
			g_dwMulticastListInUse * 6);
        
		NE2000MulticastList(
			&(pucMulticastList[0][0]),
			g_dwMulticastListInUse);
	}
    

    //
    //	The multicast bit in the RCR should be on if multicast/all multicast packets 
	//	(or is promiscuous) is needed.
    //
    if(dwFilter & 
		(PACKET_TYPE_ALL_MULTICAST | PACKET_TYPE_MULTICAST | PACKET_TYPE_PROMISCUOUS))    
    {
        dwReceiveConfig |= RCR_MULTICAST;
    }
    else
    {
        dwReceiveConfig &= ~RCR_MULTICAST;
    }

    //
    //	The promiscuous physical bit in the RCR should be on if ANY
    //	protocol wants to be promiscuous.
    //
    if (dwFilter & PACKET_TYPE_PROMISCUOUS)
    {
        dwReceiveConfig |= RCR_ALL_PHYS;
    }
    else
    {
        dwReceiveConfig &= ~RCR_ALL_PHYS;
    }

    //
    // The broadcast bit in the RCR should be on if ANY protocol wants
    // broadcast packets (or is promiscuous).
    //
    if
    (
        dwFilter & (PACKET_TYPE_BROADCAST |
                                 PACKET_TYPE_PROMISCUOUS)
    )
    {
        dwReceiveConfig |= RCR_BROADCAST;
    }
    else
    {
        dwReceiveConfig &= ~RCR_BROADCAST;
    }


	//
	//	EDBG always receive directed and broadcast as a minimum.
	//
	
	dwReceiveConfig |= RCR_BROADCAST;	
	
	ucFilter	 = (BYTE)dwReceiveConfig;
	dwNdisFilter = dwFilter;

	EdbgOutputDebugString("NE2KDBG:: Set Ndis filter [0x%x] -> [0x%x]\r\n",
		dwFilter,
		dwReceiveConfig);

    UsePage0();    
    WriteByte(NIC_RCV_CONFIG, (BYTE)dwReceiveConfig);

}	//	Ne2000CurrentPacketFilter()





////////////////////////////////////////////////////////////////////////////////
//	ComputeCrc()
//	
//	Description:
//
//		Runs the AUTODIN II CRC algorithm on buffer Buffer of length Length.
//
//	Arguments:
//
//		Buffer - the input buffer
//		Length - the length of Buffer
//
//	Return value:
//
//		The 32-bit CRC value.
//
//	Note:
//
//		This function is adopted from netcard\ne2000 miniport driver.
//		
ULONG
ComputeCrc(
    IN PUCHAR Buffer,
    IN UINT Length)
{
    ULONG Crc, Carry;
    UINT i, j;
    UCHAR CurByte;

    Crc = 0xffffffff;

    for (i = 0; i < Length; i++) {

        CurByte = Buffer[i];

        for (j = 0; j < 8; j++) {

            Carry = ((Crc & 0x80000000) ? 1 : 0) ^ (CurByte & 0x01);

            Crc <<= 1;

            CurByte >>= 1;

            if (Carry) {

                Crc = (Crc ^ 0x04c11db6) | Carry;

            }

        }

    }

    return Crc;

}	//	ComputeCrc()



////////////////////////////////////////////////////////////////////////////////
//	GetMulticastBit()
//	
//	Description:
//

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -