?? netdrv.cpp
字號:
/*********************************************************************************
* FileName: netdrv.cpp
* Description: In this cpp file, all the routines used in net driver is provided.
* Version: v1.2
*
* Function List:
*
* History:
* <author> <time> <desc>
* Ason 2001.5 establish this file
* shiliangcai 2002.10 refresh this file, for bios and update
* old program is in "main\net\netdrv.cpp"
**********************************************************************************/
//#define MDEBUG
#include "bastype.h"
#include "mcf5206.h"
#include "netdrv.h"
//UCHAR gStatusChange = FALSE;
//STSTMAC MacState; // statistics about MAC layer.
//static UINT16 ReceiveIntHappen = 0;
//static UINT16 TransmitHappen = 0;
//static UINT16 BufShortHappen = 0;
//static UCHAR SndLoopBuf[256]; // for loop test only.
//static UCHAR RcvLoopBuf[RECEIVE_BUF_MAX_SIZE]; // for loop test and for buffer shortage.
//struct pqueue_hdr Recv_List;
#ifdef BIOS_DEBUG
#include "graph.h"
// for test, use TIME1, 13500 = 1s,
UINT32 g_nOneTransferTimeForTest1;
UINT32 g_nOneTransferTimeForTest2;
UINT32 g_nOneTransferTimeForTest3;
UINT32 g_nOneTransferTimeForTest4;
UINT32 g_nOneTransferTimeForTest5;
UINT32 g_nOneTransferTimeForTest6;
static UINT32 g_nSendSta;
static UINT32 g_nRecSta;
static UINT32 g_nErroSta;
#endif
// 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
};
static UCHAR g_acNetReceiveFrame[NET_RECEIVE_BUF_FRAME_COUNT][RECEIVE_BUF_MAX_SIZE];
static UINT16 g_anNetReceiveFrameLength[NET_RECEIVE_BUF_FRAME_COUNT];
static UINT16 g_nNetReceiveInIndex;
static UINT16 g_nNetReceiveOutIndex;
static UCHAR g_acNetTransmitBuffer[TRANSMIT_BUF_MAX_SIZE];
static UCHAR g_nNetTransmitLen;
static NETFRAMEHEAD g_stNetFrameHead;
static CHAR ReadPage;
static CHAR WritePage;
static CHAR PacketDelivered;
// s_nUpateProcessFlag表示是從主程序跳過來,還是主程序無效而執行升級
// 如果是前者,s_nUpateProcessFlag = 1,第一次就需要比較機器ID,接收升級文件
// 如果是后者,s_nUpateProcessFlag = 0,第一次不需要比較機器ID,接收版本命令
// 成功處理玩第一次后,s_nUpateProcessFlag = 2,不再區分,都需要比較機器ID
static UCHAR s_nUpateProcessFlag;
static UINT16 s_nErrorCount;
//void RecoverFromBufShortage(void);
//UCHAR gucRemoteIPAddr[4];
extern SYSCONFIGFLAG g_stSysFlag;
static UINT16 s_nDstPort;
/***********************************************************************
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: 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;
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.
outportb(MAR7ADD,0xff);
tempc = inportb(MAR7ADD);
// wait for a while. data sheet says at least 1.5 ms.
Sleep(10);
// stop the card.
SETTOPAGE0();
outportb(CRADD,0x21);
// in the datasheet, it is said that RST IN ISR is
// not a guarantee of stop, stop at least 1.5 ms.
Sleep(10);
// 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);
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;
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);
Sleep(10);
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(i <= NET_TMO_DMA)
{
if (inportb(ISRADD) & 0x40)
break;
Sleep(10);
i ++;
}
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++ )
{
if ( i != inport(DATAPORTADD))
{
return_value = NET_ERROR_DMAERR;
break;
}
}
// wait for DMA to complete.
i = 0;
while(i <= NET_TMO_DMA)
{
if (inportb(ISRADD) & 0x40)
break;
Sleep(10);
i ++;
}
if ( i > NET_TMO_DMA )
return( NET_ERROR_DMATMO );
// clear the interrupt.
outportb(ISRADD, 0xff);
// abort DMA
tempc = inportb(CRADD);
tempc |= 0x20;
outportb(CRADD,tempc);
return( return_value );
}
/*
Name: InitMacCntlr
Description: Initialize MAC controller of 88796
Parameters: A string witch holds MAC address.
Return: mode - 0, loop; 1, normal.
Only the work mode is set, the intrrupt routines
are not set anyway.
Test and revisioin: Ason. 2001.5
*/
void InitMacCntlr(UCHAR *mac_addr, INT16 mode)
{
UCHAR tempc;
// Step 1, turn to page 0 and set all those
// important things in page 0,
SETTOPAGE0();
// step 1.1
// 0x21, stop the controller and abort remote DMA.
outportb(CRADD,0x21);
Sleep(10);
// step 1.2 clear all interrupt and disable all interrupt.
outportb(ISRADD,0xff);
// the reset bit will not generate interrupt actually in 796
outportb(IMRADD,0x00);
// step 1.3
// 0x03, DCR. 16-bit DMA transfering, byte order 68K
// Dual 16-bit DMA mode, remote DMA is not always complete,
outportb(DCRADD,0x03);
// step 1.4
// 0x00, TCR. CRC appended by Transmitter.
// No loop back.
// Half duplex, PAD enabled, Retransmite in
// later collision, 88796 loop back.
if ( 0 == mode )
outportb(TCRADD,0x22);
else
outportb(TCRADD,0x20);
// outportb(TCRADD,0x00);
// step 1.5
// 0x24, RCR. Packets with receive errors are rejected.
// reject runt packet.
// accept broadcast.
// not check multicast packet. !!!
// Non promiscuous mode.
// normal mode.
// Low active interrupt.
outportb(RCRADD,0x44);
// step 1.6
// DMA registers.
// PSTARD set to 0x46. Attention, this is start address for receiving.
outportb(PSTARTADD,0x46);
// PSTOP set to 0x80.
outportb(PSTOPADD,0x80);
// BNRY set to 0x46. Same as PSTARD.
outportb(BNRYADD,0x46);
// TSR, This is no use actually.
outportb(TSRADD,0x40);
// TBCR0
outportb(TBCR0ADD,0x00);
// TBCR1
outportb(TBCR1ADD,0x00);
// ISR, clear all ISR.
outportb(ISRADD,0xff);
// RSAR0ADD,
outportb(RSAR0ADD,0x00);
// RSAR1ADD,
outportb(RSAR1ADD,0x40);
// RBCR0ADD.
outportb(RBCR0ADD,0x00);
// RBCR1ADD.
outportb(RBCR1ADD,0x00);
// 1.7 Gap registers?
// outportb(IFGS1ADD,0x00);
// outportb(IFGS2ADD,0x00);
// outportb(IFGADD,0x00);
// 1.8 TPSRADD.
outportb( TPSRADD, WritePage);
// now, change to page 1.
SETTOPAGE1();
// step 2.1
// CURR
outportb(CPRADD,0x47);
// step 2.2
// MAC Address 00001b182202 plus bednumber.
outportb(PARA0ADD,*mac_addr);
outportb(PARA1ADD,*(mac_addr+1));
outportb(PARA2ADD,*(mac_addr+2));
outportb(PARA3ADD,*(mac_addr+3));
outportb(PARA4ADD,*(mac_addr+4));
outportb(PARA5ADD,*(mac_addr+5));
// step 2.3
// multicast address, don't use multicast.
outportb(MAR0ADD,0x00);
outportb(MAR1ADD,0x00);
outportb(MAR2ADD,0x00);
outportb(MAR3ADD,0x00);
outportb(MAR4ADD,0x00);
outportb(MAR5ADD,0x00);
outportb(MAR6ADD,0x00);
outportb(MAR7ADD,0x00);
ReadPage = 0x47; // read page should be same with current page.
WritePage = 0x40; // actually, this will not change.
return;
}
/*
Name: SetIntRt
Description: open interrupt and let NIC to work.
Parameters: None.
Return: None.
Test and revisioin: Ason. 2001.5
*/
void SetIntRt(void)
{
CHAR tempc;
UINT16 temps;
// enable the MAC controller in terrupt.
// first of all, set to page 0.
SETTOPAGE0();
// IMR register difinition:
// 7 - Reserved
// 6 RDCE DMA Complete Interrupt enable. Default “low” disabled.
// 5 CNTE Counter Overflow Interrupt Enable. Default “low” disabled.
// 4 OVWE Overwrite Interrupt Enable. Default “low” disabled.
// 3 TXEE Transmit Error Interrupt Enable. Default “low” disabled.
// 2 RXEE Receive Error Interrupt Enable. Default “low” disabled.
// 1 PTXE Packet Transmitted Interrupt enable. Default “low” disabled.
// 0 PRXE Packet Received Interrupt Enable. Default “low” disabled.
// following don't generate interrupt
// 1、a reserve bit (7)
// 2、when remote DMA is finished(6)
outportb(IMRADD,0x3F);
// clear all interrupt once more.
SETTOPAGE0();
outportb(ISRADD,0xff);
// start the controller.
outportb(CRADD,0x22);
return;
}
/*
Name: RecoverFromBufShortage
Descriptioin: This routine will be used to recover from
the buffer shortage error. please refer to 796 data sheet.
Parameters: None.
Return: None.
Test and revision:
Ason. 2001.8
void RecoverFromBufShortage(void)
{
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -