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

📄 netdrv.cpp

📁 coldfire5206芯片的boot程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	BOOL txp;
	BOOL resend;
	UCHAR tempc;

	//  following lines are according to 88796 data sheet which 
	//  says very detailed about what to do when buffer overflows. 
	//  I change a little with throwing away all the packets waiting
	//  on the buffer link and make buffer empty.

	//  step 1, save TXP in 
	tempc = inportb(CRADD);
	if ( tempc & 0x04 )
		txp = TRUE;
	else 
		txp = FALSE;

	// step 2, stop 796
	outportb(CRADD,0x21);

	// step 3. wait for at least 1.5 ms.
	Sleep(10);

	// step 4, clear RBCR0 and RBCR1.
	SETTOPAGE0();
	outportb(RBCR0ADD,0x00);
	outportb(RBCR1ADD,0x00);  

	// step 5
	if ( TRUE == txp )
	{
		tempc = inportb(ISRADD);
		if ( ( tempc & 0x02 ) || ( tempc & 0x08 ) )
			resend = FALSE;
		else
			resend = TRUE;
	}
	else
	{
		resend = FALSE;
	}

	// step 6 loop, i know, this will shut the data link from out side.
	outportb( TCRADD, 0x20);

	// step 8. remove all the packet from the receive buffer.
	// as the packet has already been lost, just throw 
	// all the packets in the buffer away.
	// the method is set the two dynamic read and write
	// registers.
	outportb(BNRYADD,0x46);
	SETTOPAGE1();
	outportb(CPRADD,0x47);
	SETTOPAGE0();
	ReadPage = 0x47;  

	// step 9.
	outportb(ISRADD,0x10);

	// step 10.
	outportb(TCRADD, 0x20);

	// step 7. start. data sheet got some errors here,
	//                if i start it really in step 7, data could 
	//                still be flowed in of step 8,9,10, that could
	//                make trouble.
	//                step 6 will do this, but why do i find problems?
	outportb(CRADD,0x22);

	// step 11.
	if ( TRUE == resend )
	{
		outportb(CRADD,0x26);
	}

	// step 12. this is for my application environment.
	// when buffer shortage happens, there should be
	// also an receive interrupt.
	ReceiveIntHappen = 0;
	BufShortHappen = 0;

	return;
}
*/

/*
Name:          RemoteRead
Description:   read data into a buffer use remote DMA.
Parameters:    cur_page: current page to start, may start at the middle
possition of a page.
len:      lenth of the DMA, words.
buf:      where to save data.
Return:        NET_NO_ERROR or error code.
Test and Revision:   Ason, 2001.5
*/
INT16 RemoteRead(UINT16 cur_page, UINT16 len, UINT16 *buf)
{

	UCHAR tempc;
	UCHAR regtemp;
	UINT16 i;
	UINT16 tempss;
	UINT32 pre_int_level;


	// pre_int_level = NU_Control_Interrupts( MACINTLEVEL << 8 );


	SETTOPAGE0();
	regtemp = (cur_page & 0xff00) >> 8;
	outportb(RSAR1ADD, regtemp);

	regtemp = cur_page & 0xff;
	outportb(RSAR0ADD,regtemp);

	regtemp = (( (len<<1) & 0xff00) >> 8) & 0xff;
	outportb(RBCR1ADD,regtemp);

	regtemp = (len<<1) & 0xff;
	outportb(RBCR0ADD,regtemp);

	// start remote DMA to read.
	outportb( CRADD,0x0a );  

	for (i = 0; i <len; i++ )
		*( buf + i ) = inport( DATAPORTADD );

	// wait for the read DMA to finish.
	i = 0;
	while(1)
	{
		tempc = inportb(ISRADD);
		if ( tempc & 0x40 )
		{
			//           MacState.RemoteDMACompleteTimes++;
			break;
		}
		Sleep(1);
		if ( i++ > NET_TMO_DMA )
			break;
	}
	if ( i > NET_TMO_DMA )
	{
		//NU_Control_Interrupts( pre_int_level );
		return( NET_ERROR_DMATMO );
	}

	outportb( ISRADD, 0x40 );

	//NU_Control_Interrupts( pre_int_level );
	return( NET_NO_ERROR );

}


/*
Name:          RemoteWrite
Description:   write data into a buffer using remote DMA.
Parameters:    cur_page: current page to start, may start at the middle
possition of a page.
len:      lenth of the DMA, words.
buf:      where to copy the data.
Return:        NET_NO_ERROR or Error code.
Test and Revision:   Ason, 2001.5
*/
BOOL RemoteWrite(UINT16 cur_page, UINT16 len, UINT16 *buf)
{
	CHAR tempc;
	UCHAR regtemp;
	UINT16 i;


	SETTOPAGE0();
	regtemp = (cur_page & 0xff00) >> 8;
	outportb(RSAR1ADD, regtemp);

	regtemp = cur_page & 0xff;
	outportb(RSAR0ADD,regtemp);

	regtemp = (( (len<<1) & 0xff00) >> 8) & 0xff;
	outportb(RBCR1ADD,regtemp);

	regtemp = (len<<1) & 0xff;
	outportb(RBCR0ADD,regtemp);

	// start remote DMA to write.
	outportb( CRADD,0x12 );   

	// buf maybe exceed the scope for adding pads, but
	// it just read, do no harm.
	for (i = 0; i <len; i++ )
		outport(DATAPORTADD, *(buf + i));

	// wait for the read DMA to finish.
	i = 0;
	while(1)
	{
		tempc = inportb(ISRADD);
		if ( 0x40 & tempc )
		{
			//	      MacState.RemoteDMACompleteTimes++;
			break;
		}
		Sleep(1);
		if ( i++ > NET_TMO_DMA )
			break;
	}
	if ( i > NET_TMO_DMA )
	{
		return( NET_ERROR_DMATMO );
	}

	outportb(ISRADD,0x40);  // clear DMA interrupt.

	return( NET_NO_ERROR );

}

/*
Name:         TransmitAPacket
Description:  Transmit a packet promptly.
Parameters:   buf - buffer to hold the packet, point to word.
length - length in word
Returns:      NET_NO_ERROR or Error code.
Test and revision:
Ason.  2001.7
*/
INT16 TransmitAPacket( UCHAR *pInfoBuf, UINT16 length )
{
	UCHAR tempc,regtemp;
	UINT16 temps;
	INT16 return_value,i;
	UINT32 pre_int_level;
	UINT16 tempss;

	UINT16 length1;
	//	UCHAR  acOldInfo[512];

	// 构造UDP包
	length1 = length;
	//	memcpy(acOldInfo, pInfoBuf, length);
	//	ConstructEtherNetFrame(acOldInfo, &length1, pInfoBuf, &length);

	// 检查发送长度
	if ( length % 2 )
		length++;
	if ( length < TRANSMIT_BUF_MIN_SIZE )
		length = TRANSMIT_BUF_MIN_SIZE;          // add PAD.
	else if ( length > TRANSMIT_BUF_MAX_SIZE ) 
		return( NET_ERROR_EXCEEDMTU );		                            // MTU exceeded.
	length /= 2;

	UINT16* buf = (UINT16*)pInfoBuf;
	//  I am pretty sure this will be called only in
	//  tasks, so, change to NO_PREEMPTION to solve
	//  conflict of the two protocols.( TCP/IP and VB)
	//  NU_Change_Preemption( NU_NO_PREEMPT );

	//  I could not use IMR in 88796(don't know why?), and 
	//  I don't wanna disabling of this interrupt influence
	//  low level interrupts, so, I just use CPU IMR. IMR could
	//  only mask low level interrupt, back to CR.
	//
	//pre_int_lev = NU_Control_Interrupts( MACINTLEVEL << 8 );  
	DISABLENETINTERRUPT;


	return_value = RemoteWrite( ((UINT16)WritePage) << 8 , length, buf );
	if ( NET_NO_ERROR != return_value )
	{
		//NU_Change_Preemption( NU_PREEMPT );
		//NU_Control_Interrupts( pre_int_lev );  
		ENABLENETINTERRUPT;
		return( return_value );
	}

	outportb( TPSRADD,WritePage );

	// length is destined to be even.
	outportb(TBCR0ADD,(length<<1) % 256);
	outportb(TBCR1ADD,(length<<1) / 256);

	PacketDelivered = 0;
	STARTTRANSMIT

		// This is also very important, as if we enable interrupt here
		// and in interrupt service, there destined to be a "SETTOPAGE0();".
		// refer to SETTOPAGE0();, read CR out(TXP bit still exist), then
		// write CR in( now TXP don't exist), dual-transmition occur!!! 
		i = 0;
	while( TRUE )
	{
		regtemp = inportb( CRADD );
		if ( !(regtemp & 0x04) )
			break;
		Sleep(1);
		if ( i++ > NET_TMO_TMIT )
			break;
	}
	if ( i > NET_TMO_TMIT )
	{
		//NU_Control_Interrupts( pre_int_lev );  
		ENABLENETINTERRUPT;
		// NU_Change_Preemption( NU_PREEMPT );
		return ( NET_ERROR_TRANSBLOCK );
	}

	// first of all, open interrupt to make sure we
	// can receive now.
	//NU_Control_Interrupts( pre_int_lev );  

	// See if we get the packet delivered, if it is not delivered,
	// just wait for a while, and when we are waiting, other 
	// tasks who should call "TransmitAPacket" will not be allowed.
	// Attention!!! transmit interrupt may happen here, in this case,
	// we will not get ISR set in the following lines, so, we use 
	// "PacketDelivered" to help us out.
	i = 0;
	while( TRUE )
	{
		// No need to SETTOPAGE0(); and mask interrupt, as in interrupt service, 
		// after each time of "SETTOPAGE1();", there is a "SETTOPAGE0();".
		regtemp = inportb( ISRADD );
		if ( ( regtemp & 0x08 ) || ( regtemp & 0x02 ) || ( 1 == PacketDelivered ) )
			break;
		Sleep(1);
		if ( i++ > NET_TMO_TMIT )
			break;
	}

	ENABLENETINTERRUPT;
	// NU_Change_Preemption( NU_PREEMPT );
	if ( i > NET_TMO_TMIT )
		return( NET_ERROR_TRANSBLOCK );
	else 
		return( length1 );

}


/*
Name:         ConfigMacMii
Description:  set neccessary things in MII register set, 
as 10M/100M, duplex and such staff.
Parameters:   mode, 0 - 10M, 1-100M, 2- autonegotiation.
Return:       TRUE, success, FALSE, fail.
Test and revision:
Ason, 2001.7.
*/
INT16 ConfigMacMii(INT16 mode)
{

	INT16 return_value;
	UINT32 i;
	UINT16 tempus;
	UCHAR tempc;

	SETTOPAGE0();
	outportb(CRADD,0x21);
	Sleep(10);

	// reset MII register set.
	tempus = 0x8000;
	WriteMiiRegister(0x10,0x00,tempus); // 0x10 is the PHY ID of our internal PHY,
	// you may refer to 88796 data sheet. 
	i = 0;
	while( TRUE )
	{
		return_value = ReadMiiRegister(0x10,0x00,&tempus);
		if (  NET_NO_ERROR != return_value )
			return( NET_ERROR_PHYREAD );
		if ( ! ( tempus & 0x8000 ) )
			break;
		Sleep(1);
		if ( i++ > NET_TMO_MIIRST )
			return( NET_ERROR_MIIRST );
	}

	tempus &= 0xcfff;      // clear 10/100/auto-negotiation bit.
	if ( 2 == mode)
		tempus |= 0x1000;    // set auto negotiation.  
	else if ( 1 == mode )
		tempus |= 0x2000;    // set to 100M.

	tempus &= 0xfeff;       // set to half duplex.
	WriteMiiRegister(0x10,0x00,tempus);

	// say i am not capable of 100Base-TX and 100Base-T.
	// Why say I am not capable of 100M?s
	// WriteMiiRegister(0x10,0x04,0x0061);

	// say i will see interrupt of link state/jabber/remote fault/false carrier.
	// but i don't know why the two bits writable can not be set.
	// WriteMiiRegister(0x10,31,0x0);

	return( NET_NO_ERROR );
}

/************************************************************************
Name:         ReceiveAPacket
Description:  This routine will received a packet now 
dangling on the MAC buffer, and "ReadPage" is 
a global thing.
Parameters:   buf - the buffer used to hold the packet.
Returns:      0 - A packet is successfully received.
1 - No packet is found.
2 - this is a viewbed packet, and we care about it, saved.
3 - this is a viewbed packet, but we don't care about it, discard.
-1 - NET_ERROR_PAKLEN.
Test and revision:
Ason. 2001.7
*************************************************************************/
INT16 ReceiveAPacket( UCHAR *tcpip_buf, UINT16 nLength)
{
	UCHAR tempc, cur_page;
	UINT16 packet_len = 0;
	int		return_value;
	UCHAR  temp_buf[50];  // temporary buffer to hold packet head.
	char acTempAddr[6];

	packet_len = 0;
	DISABLENETINTERRUPT;

	//*type = packet_type = NET_PTL_NOONE;

	SETTOPAGE0();
	tempc = inportb(RSRADD);

	// when set to page1, there should be an interrupt entry protection.
	SETTOPAGE1();
	cur_page = inportb(CPRADD);
	SETTOPAGE0();

	if ( ReadPage == cur_page )
	{
		ENABLENETINTERRUPT;
		return( NET_ERROR_NOPAKIN );
	}

	// 
	// read packet head, refer to "STORAGE FORMAT FOR RECEIVED PACKETS" in  AX88796-16.pdf
	return_value = RemoteRead( ((UINT16)ReadPage) << 8 , 25, (UINT16*)temp_buf );
	if( NET_NO_ERROR != return_value )
	{
		ENABLENETINTERRUPT;
		return( return_value );
	}

	memset(acTempAddr, 0xFF, 6);

//////////////////////////////////////////////////////////
// DEBUG:直连网线升级错误, modify by shiliangcai
// 原因:因为使用直连网线升级时,网络时断时续,所以会有ARP包,而判断条件中,
// IP包不是必要条件,导致ARP包当作IP包处理,结果长度错误,导致读越界
// 修改:将IP包判断做为必要条件

	//	通过判断以太网地址,源地址(PC网卡)相同,目标地址是0xffffffffffff(广播)
	//  而且需要判断是IP包, *(temp_buf + 16) == 0x08 &&  *(temp_buf + 17) == 0x00
	if (  (*(temp_buf + 16) == 0x08 &&  *(temp_buf + 17) == 0x00)
		&& ((s_nUpateProcessFlag == 0) 
		    || (s_nUpateProcessFlag == 1)
		    || (!memcmp(g_stNetFrameHead.stETHead.ucDstAddr, temp_buf + 10, 6) 
			    &&!memcmp((UINT8*)acTempAddr, temp_buf + 4, 6))))
//  DEBUG:直连网线升级错误 end
//////////////////////////////////////////////////////////////////////////////////////
	{	
		s_nDstPort = *(UINT16*)(temp_buf + 38);

		packet_len = *(UINT16*)(temp_buf + 42);

		packet_len -= 8;	// UDP head
#ifdef BIOS_DEBUG
		if (packet_len > RECEIVE_BUF_MAX_SIZE - 8)
		{
			packet_len = RECEIVE_BUF_MAX_SIZE - 8;
		}
#endif		
		// (((UINT16)ReadPage) << 8) + 46, how 46 get is  (access)4+6+6+2 (ip)20 udp(8)
		return_value = RemoteRead( (((UINT16)ReadPage) << 8) + 46, ( packet_len + 1) >> 1, (UINT16 *)(tcpip_buf) );
		if (tcpip_buf[0] != 0xaa || tcpip_buf[1] != 0x55 || tcpip_buf[2] != 0xa5
			|| packet_len < 35)
		{
			packet_len = 0;
		}
		else
		{
			// 下面不用switch语句的原因是大部分情况都是 == 2,如果用switch会降低中断效率
			if (s_nUpateProcessFlag == 2)
			{
				if (memcmp(tcpip_buf + 3, g_stSysFlag.stFSysFlag.acFlashID, 8))
				{
					packet_len = 0;
				}
			}
			else 
			{
				if (s_nUpateProcessFlag == 1)
				{
					if (packet_len == 55 
						&& !memcmp(tcpip_buf + 3, g_stSysFlag.stFSysFlag.acFlashID, 8))
					{
						memcpy(g_stNetFrameHead.stIPHead.ucDstAddr, temp_buf + 30, 4);
						memcpy(g_stNetFrameHead.stIPHead.ucSrcAddr, temp_buf + 34, 4);
						memcpy(g_stNetFrameHead.stETHead.ucDstAddr, temp_buf + 10, 6);
						if( g_stNetFrameHead.stIPHead.ucDstAddr[3] == 1 )
							g_stNetFrameHead.stIPHead.ucSrcAddr[3] = g_stNetFrameHead.stIPHead.ucDstAddr[3] + 1;
						else
							g_stNetFrameHead.stIPHead.ucSrcAddr[3] = g_stNetFrameHead.stIPHead.ucDstAddr[3] - 1;

						s_nUpateProcessFlag = 2;
					}
					else
					{
						packet_len = 0;
					}
				}
				else	// == 0
				{
					UCHAR actempMonitorID[8];
					memset(actempMonitorID, 0x00, 8);
					if (packet_len == 55 && !memcmp(tcpip_buf + 3, actempMonitorID, 8)
						&& *(tcpip_buf + 3 + 8 + 7) == 0x80	// CPT_CMD
						&& *(tcpip_buf + 3 + 8 + 8) == 0x36	// VERSION
						&& *(tcpip_buf + 3 + 8 + 8 + 13) == g_stSysFlag.stFSysFlag.ucSelfMachineID)
					{
						memcpy(g_stNetFrameHead.stIPHead.ucDstAddr, temp_buf + 30, 4);
						memcpy(g_stNetFrameHead.stIPHead.ucSrcAddr, temp_buf + 34, 4);
						memcpy(g_stNetFrameHead.stETHead.ucDstAddr, temp_buf + 10, 6);
						if( g_stNetFrameHead.stIPHead.ucDstAddr[3] == 1 )
							g_stNetFrameHead.stIPHead.ucSrcAddr[3] = g_stNetFrameHead.stIPHead.ucDstAddr[3] + 1;
						else
							g_stNetFrameHead.stIPHead.ucSrcAddr[3] = g_stNetFrameHead.stIPHead.ucDstAddr[3] - 1;

						s_nUpateProcessFlag = 2;
					}
					else
					{
						packet_len = 0;
					}
				}	
			}
		}	
	}	


	SETTOPAGE0();
	outportb( BNRYADD,ReadPage );
	ReadPage = temp_buf[1];

	SETTOPAGE1();

⌨️ 快捷键说明

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