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

📄 driver.c

📁 mcf5307实验源代码
💻 C
📖 第 1 页 / 共 4 页
字号:

#include <stdio.h>
#include <string.h>
#include "hostform.h"
#include "target.h"
#include "protocol.h"
#include "externs.h"
#include "tcp_errs.h"
#include "tcp.h"
#ifdef PLUS
  #include "nucleus.h"
#else  /* !PLUS */
  #include "nu_extr.h"
#endif /* !PLUS */

/* New includes added for the new C interface */
#include "target.h"        /* Compiler typedefs for data type sizes */
//#include "chipint.h"       /* defines to interface registers on the
//                            * ethernet card */
//#include "datasdf.h"
#include "Driver.h"

/*  Prototypes  */

/* Declarations for the interrupt service routines, tasks, and functions that
 * are required when interrupts are usde. */

uchar *xdata_ptr;               /* transmit data pointer */

int ALICNT_Count;
int CRCCNT_Count;
int COLCNT_Count;
int MPCNT_Count;

int Hisr_Activated;
int16 trans_status;
extern unsigned int    TestCount;

NU_PROTECT MacProtect;


#define  SETTOPAGE0    tempc = inportb(CRADD); \
					   tempc &= 0x3f;  \
					   outportb(CRADD,tempc);

#define  SETTOPAGE1    tempc = inportb(CRADD); \
					   tempc &= 0x3f;  \
					   tempc |= 0x40;  \
					   outportb(CRADD,tempc);

#define  ABORTDMA	   tempc = inportb(CRADD); \
					   tempc |= 0x20;  \
					   outportb(CRADD,tempc);

#define  STARTCNTLR    outportb(CRADD,0x22);

#define  STARTTRANSMIT outportb(CRADD,0x26);  


#define ENABLENETINTERRUPT	  NU_Unprotect(); 
#define DISABLENETINTERRUPT   NU_Protect( &MacProtect ); 

/*
#define  ENABLENETINTERRUPT  NU_Control_Interrupts( pre_int_level ); 
#define  DISABLENETINTERRUPT pre_int_level = NU_Control_Interrupts( MACINTLEVEL << 8 ); 
*/
							 

/*
#define  ENABLENETINTERRUPT  
#define  DISABLENETINTERRUPT 
*/

// Make MII output 3-state
#define MIIOUT3STATE   outportb( MIIEEPROMADD, MII_WRITE_TS );	 \
					   outportb( MIIEEPROMADD, MII_WRITE_TS |MII_CLK );

// reserved bits mask for MII registers.
// bit 1 means mask. all those bits in MII register are 
// reserved from access.
static const uint16 PhyRegsReservedBitsMasks[] = 
{
  0x007F,					 // Control reg reserved bits mask
  0x07C0,					 // Status reg reserved bits
  0,						 // PhyID reserved bits mask
  0,						 // PhyID reserved bits mask
  0x1C00,					 // Nway Local ability reserved bits mask
  0x1C00,					 // Nway Partner ability reserved bits mask
  0xFFE0,					 // Nway Expansion
  0,0,0,0,0,0,0,0,0,0,0,0,0, // Other regs
  0,0,0,0,0,0,0,0,0,0,0,0	 // Other regs
};


unsigned char TcrSaver = 0x20;		 // TCR saver, must half duplex to make it 
							 // comply with 802.3
unsigned char ImrSaver = 0x3f;		 // this is only used in transmiting packets.

STSTMAC  MacState;			 // statistics about MAC layer.

static uint16  			ReceiveIntHappen = 0;
static uint16  			TransmitHappen = 0;
static uint16  			BufShortHappen = 0;
static unsigned char	SndLoopBuf[256];  // for loop test only.
static unsigned char	RcvLoopBuf[RECEIVE_BUF_SIZE]; // for loop test and for buffer shortage.

struct pqueue_hdr Recv_List;

CHAR	ReadPage;
CHAR	WritePage;
CHAR	PacketDelivered;

int16 ReceiveAPacket(unsigned char*, unsigned char *, uint16 *);
void NetCtlrHisr(void);

extern struct transq_hdr trans_list;
//extern NU_HISR gNetControllerHisr;
extern NU_HISR NetControllerHisr;
extern void (*NU_old_vect_routine)(INT);


void RecoverFromBufShortage();

// see how many upgrade packets comes.
//extern UINT16				gunIdentify;
//extern unsigned  int  gDstPort;
//extern UCHAR				gucLocalIPAddr[4];
//extern UCHAR				gEtherSrcAddr[6];
//extern UCHAR				gucRemoteIPAddr[4];
//extern INT16 UpgradePackets ;
  // adding end
/* 
Name:			outportb
Description:	Send a byte out to certain port.
Parameters: 	add - address, val - value.
Return: 		None.
Test and revision:
				Ason. 2001.7
*/
void outportb( INT add, UCHAR val)
{
	*((UCHAR *)add) = val;
}


/* 
Name:			outport
Description:	send a word out to certain port.
Parameters: 	add - address, val - value.
Return: 		None.
Test and revision:
				Ason. 2001.7
*/
void outport( INT add, UINT16 val)
{
	*((UINT16 *)add) = val;
}

/* 
Name:			inportb
Description:	read a byte in from certain port.
Parameters: 	add - address.
Return: 		the byte read.
Test and reision:
				Ason. 2001.7
*/
UCHAR inportb( INT add)
{
	return( *((UCHAR *)add) );
}

/* 
Name:			inport
Description:	read a word in from certain port.
Parameters: 	add - address.
Return: 		the word read.
Test and revision:
				Ason. 2001.7
*/
UINT16 inport( INT add)
{
	return( *((UINT16 *)add) );
}


/*
Name:		  WriteMiiWord
Description:  This routine is used to write a word into Mii registers.
Parameters:   data, which data to write; data_size, how many bits.
Returns:	  None.
Test and Revision:
			  Ason. 2001.7
*/
void WriteMiiWord( UINT32 data, UINT16 data_size )
{
	UINT32 data_bit;
	
	for ( ; data_size > 0; data_size-- )
	{
	   data_bit = ( data >> (31 - MII_MDO_BIT_POSITION ) ) & MII_MDO_MASK;
	   outportb(MIIEEPROMADD, MII_WRITE | data_bit );
	   outportb(MIIEEPROMADD, MII_WRITE | MII_CLK | data_bit );
	   data <<= 1;
	}
}


/*
Name:		 ReadMiiRegister
Description: Read a certain register in Mii.
Parameters:  phy_addr, physical address of the PHY, in this case,
			 as we use internal PHY, its address is always 0x10,
			 reg_num, which register, totally 32 register.
			 reg_data_p, pointer points to the register value.
Return: 	 NET_NO_ERROR or Error code.
Test and revision:
			 Ason. 2001.6
*/
INT16 ReadMiiRegister( UINT16 phy_addr, UINT16 reg_num,  UINT16 * reg_data_p )
{
	
	UINT32	 command = ((UINT32)phy_addr <<PHY_ADDR_ALIGN)
						|((UINT32)reg_num <<REG_ADDR_ALIGN)
						|MII_READ_FRAME;
	UINT16	 bits_of_short = sizeof(UINT16) * 8;
	UINT16	 i;
	UCHAR	 tempc;

   
	*reg_data_p = 0;
 
	WriteMiiWord( PRE, (UINT16)( 2*bits_of_short ));
	WriteMiiWord( command, (UINT16) (bits_of_short - 2));
	MIIOUT3STATE

	tempc = inportb(MIIEEPROMADD);
	if ( tempc & MII_READ_DATA_MASK )
	{
		// TRY AGAIN!
		// some kind of PHY need to do this twice...
		MIIOUT3STATE
		tempc = inportb(MIIEEPROMADD);
		if ( tempc & MII_READ_DATA_MASK )
			 return( NET_ERROR_MIIRD ) ;
	}
	
	for (i = 0; i < bits_of_short; i++)
	{
		outportb(MIIEEPROMADD, MII_READ);
		outportb(MIIEEPROMADD, MII_READ | MII_CLK);

		tempc = inportb(MIIEEPROMADD);
		*reg_data_p = (*reg_data_p << 1) |(UINT16)((tempc >> MII_MDI_BIT_POSITION ) & 0x0001 );
	}
	MIIOUT3STATE

	// Mask the bits without any meaning.
	*reg_data_p &= ~PhyRegsReservedBitsMasks[reg_num];

	return(NET_NO_ERROR);
}


/*
Name:		  WriteMiiRegister
Description:  write into a mii register.
Parameters:   phy_addr, reg_num, reg_data. as "ReadMiiRegister"
Return: 	  None.
Test and revision:
			  Ason. 2001.6
*/
void WriteMiiRegister( UINT16 phy_addr, UINT16 reg_num, UINT16 reg_data )
{
	UINT32	 command = ((UINT32)phy_addr << PHY_ADDR_ALIGN )
						|((UINT32)reg_num << REG_ADDR_ALIGN )
						|MII_WRITE_FRAME
						|(UINT32)(reg_data & ~PhyRegsReservedBitsMasks[reg_num]);
	
	UINT16	 bits_of_short = sizeof(UINT16) * 8;

	WriteMiiWord( PRE, (UINT16)(2* bits_of_short));
	WriteMiiWord( command, (UINT16)( 2 * bits_of_short ));
	MIIOUT3STATE
}

/*
Name:			InitStatistics
Description:	This routine will be used to clear all statistics for 
				MAC Layer.
Parameters: 	None.
Returns:		None.
Test and revision:
				Ason.  2001.7
*/
void InitStatistics(void)
{

	MacState.Rcv.PacketReallyReceived = 0;
	MacState.Rcv.PacketReallyReceivedTcpip = 0;
	MacState.Rcv.PacketReallyReceivedVBCare = 0;
	MacState.Rcv.PacketReallyReceivedVBNotCare = 0; 
	MacState.Rcv.PacketReceived = 0;		 
	MacState.Rcv.PacketReceivedWithError = 0;
	MacState.Rcv.PacketReceivedIntact = 0;	  
	MacState.Rcv.PacketReceviedCRCErr = 0;	  
	MacState.Rcv.PacketReceviedFAEErr = 0;	  
	MacState.Rcv.PacketReceivedFIFOErr = 0;   
	MacState.Rcv.PacketReceivedMissErr = 0;   
	MacState.Rcv.PacketReceivedBMpTimes = 0;  
	MacState.Rcv.PacketReceivedDisabled = 0;  
	
	MacState.Tmt.TransmitTimes = 0;
	MacState.Tmt.TransmitTimesWithError = 0;
	MacState.Tmt.TransmitOWCErr = 0;	
	MacState.Tmt.TransmitABTErr = 0;	
	MacState.Tmt.TransmitColTimes = 0;	
	MacState.Tmt.TransmitPTXTimes = 0;	

	MacState.CouterOverflowTimes = 0;	 
	MacState.RemoteDMACompleteTimes = 0;  
	MacState.ShortBufferTimes = 0;		  
	MacState.ResetTimes = 0;			  
	MacState.IPBufShortTimes = 0;
//	MacState.VBBufShortTimes = 0;

}


/*
Name:		 wait
Description: Do something to sleep a while, as NU_Sleep is not 
			 permitted from low level service as ISR, so this 
			 is provided. because it is implemented by counting
			 instructions, when CPU is speed up, this must be
			 rewrite!!!
Paramters:	 howlong - ms to sleep.
Return: 	 none.
Test and revision:
			 Ason. 2001.7			
*/
void wait(UINT16 howlong)
{
   UINT16 i,j;
   UINT16 temps;

	 
   for ( i = 0; i < howlong; i++ )
   {
	   // assumee that takes 1ms, some test must be done!!!
	   for ( j = 0; j < 1400; j++)	// 40000, approximate 1ms.
		   temps++;
   }
}


/*
Name:			TestMacReg
Description:	Test some registers to verify that the chip is good.
Parameters: 	None.
Return: 		Error code or NU_NO_ERROR.

Test and revisioin:   Ason. 2001.5

*/
INT16 TestMacReg(void)
{
 
   UCHAR   tempc;
   UCHAR   tempd;      //add by sunsir
   UINT16  temps;
   INT16   return_value =  NET_NO_ERROR;
   INT16   i;
 
   // reset the chip. a read or a write will 
   // software-reset the chip. as datasheet is 
   // not coherent with sample, i just read once and
   // write once.
 //  while(1)
 //  {
   outportb(MAR7ADD,0xff);
  // }
   tempc = inportb(MAR7ADD);

   // wait for a while. data sheet says at least 1.5 ms.
   wait(3);
   
   // stop the card.
   SETTOPAGE0
   outportb(CRADD,0x21);
   tempc = inportb(CRADD);     //ADD BY SUNSIR
   // in the datasheet, it is said that RST IN ISR is
   // not a guarantee of stop, stop at least 1.5 ms.
   wait(3);
   
   // first of all, set to page 1.
   SETTOPAGE1
   // write and read MAC address registers.
   
   outportb(PARA0ADD,0x55);
   outportb(PARA1ADD,0x55);
   outportb(PARA2ADD,0x55);
   outportb(PARA3ADD,0x55);
   outportb(PARA4ADD,0x55);
   outportb(PARA5ADD,0x55);
   tempd = inportb(PARA0ADD); 
   if ( 0x55 != tempd)
	 return_value = NET_ERROR_NE2REG;
   if ( 0x55 != inportb(PARA0ADD) )
	 return_value = NET_ERROR_NE2REG;
   if ( 0x55 != inportb(PARA0ADD) )
	 return_value = NET_ERROR_NE2REG;
   if ( 0x55 != inportb(PARA0ADD) )
	 return_value = NET_ERROR_NE2REG;
   if ( 0x55 != inportb(PARA0ADD) )
	 return_value = NET_ERROR_NE2REG;
   if ( 0x55 != inportb(PARA0ADD) )
	 return_value = NET_ERROR_NE2REG;

   SETTOPAGE1
   outportb(PARA0ADD,0xAA);
   outportb(PARA1ADD,0xAA);
   outportb(PARA2ADD,0xAA);
   outportb(PARA3ADD,0xAA);
   outportb(PARA4ADD,0xAA);
   outportb(PARA5ADD,0xAA);

   if ( 0xAA != inportb(PARA0ADD) )
	 return_value = NET_ERROR_NE2REG;
   if ( 0xAA != inportb(PARA0ADD) )
	 return_value = NET_ERROR_NE2REG;
   if ( 0xAA != inportb(PARA0ADD) )
	 return_value = NET_ERROR_NE2REG;
   if ( 0xAA != inportb(PARA0ADD) )
	 return_value = NET_ERROR_NE2REG;
   if ( 0xAA != inportb(PARA0ADD) )
	 return_value = NET_ERROR_NE2REG;
   if ( 0xAA != inportb(PARA0ADD) )
	 return_value = NET_ERROR_NE2REG;

   return ( return_value );

}


/*
Name:			TestMacRam
Description:	Test SRAM in AX88796
Parameters: 	None
Return: 		Error code or NET_NO_ERROR
Test and revisioin:   Ason. 2001.5

*/
INT16 TestMacRam(void)
{
	INT16	i;
	INT16	return_value = NET_NO_ERROR;
	UINT16	tempus;
	UCHAR	tempc;

	// first of all, stop the card.
	SETTOPAGE0
	outportb(CRADD,0x21);
	wait(3);
		
	SETTOPAGE0

	// make loop to keep 796 from receiving data.
	outportb(TCRADD,0x22);
	
	// clear all interrupt state.
	outportb(ISRADD,0xff);
	// clear IMR.
	outportb(IMRADD,0x00);

	// set DCR, make a 68k format, word wide and DMA not always complete.
	outportb(DCRADD,0x03);

	// following lines of codes, generate the Remote DMA to test all SRAM.
	// first of all, write 0x2000 words.
	// set byte offset.
	outportb(RSAR0ADD,0);
	// set the page.
	outportb(RSAR1ADD,0x40);   // page is from 0x40 ~ 0x7f
	// set the data length.    16kbytes.
	outportb(RBCR0ADD,0x00);
	outportb(RBCR1ADD,0x40);   // 0x2000 words.

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

	for ( i = 0; i < 0x2000; i++ )	
		outport( DATAPORTADD, i );
	
	// wait for DMA to complete.
	i = 0;
	while(1)
	{
		tempc = inportb(ISRADD);
		if (  tempc & 0x40	)
		{
		   MacState.RemoteDMACompleteTimes++;
		   break;
		}
		wait(1);
		if ( i++ > NET_TMO_DMA )
		   break;
	}
	if ( i > NET_TMO_DMA )
		return( NET_ERROR_DMATMO );

	// clear the interrupt.
	outportb(ISRADD,0xff);

	// following a few lines to read out the result.
	// set byte offset.
	outportb(RSAR0ADD,0);
	// set the page.
	outportb(RSAR1ADD,0x40);
	// set the data length. 16kbytes.
	outportb(RBCR0ADD,0x00);
	outportb(RBCR1ADD,0x40);

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

	for ( i = 0 ; i < 0x2000; i++ )
	{
		tempus = inport(DATAPORTADD);
		if ( i != tempus )

⌨️ 快捷键说明

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