📄 dm9000end.c
字号:
tmp1=DM9000A_read_reg(0xf2);
tmp2=DM9000A_read_reg(0xf2);
/* DM9000_IN_CHAR( 0xf2, tmp1 );
DM9000_IN_CHAR( 0xf2, tmp2 );*/
RxLen = tmp1 + (tmp2<<8);
}
else
{
/* Word mode */
DM9000_OUT_ADDR(0xf2);
RxStatus=DM9000_IN_WORD();
RxLen=DM9000_IN_WORD();
/* RxStatus = htons( RxStatus );*/
/* RxLen = htons( RxLen );*/
}
/* Packet Status check */
if( RxLen < 0x40)
{
GoodPacket = 0;
}
if( RxLen > DM9000_PKT_MAX )
{
/* 芯片工作状态出错需要复位 */
dm9000Reset( dev );
dm9000Config( dev );
/* INT_UNLOCK(oldv);*/
/*2007-4-18 shengdegang add*/
intUnlock(oldv);
return 2;
}
/*RxStatus 高字节为状态 打印的数据为4001 其中01为起始符,40为状态*/
if( RxStatus & 0xbf00)
{
GoodPacket = 0;
/*if( RxStatus & 0x100 ) fifo error */
/*if( RxStatus & 0x200 ) crc error */
/*if( RxStatus & 0x8000 ) length error */
}
/* Move data from DM9000 */
skb->len = 0;
if( GoodPacket && (skb != NULL) )
{ /* good packet*/
skb->len = RxLen;
rdptr = skb->pData;
/* Read received packet from RX SARM */
if (dev->io_mode == 2)
{
/* Byte mode */
for( i=0; i<RxLen; i++ )
{
rdptr[i]=DM9000_IN_BYTE();
}
}
else
{
/* Word mode */
tmplen = (RxLen + 1) / 2;
for( i = 0; i < tmplen; i++ )
{
tmp3=DM9000_IN_WORD();
tmp3 = htons( tmp3 );
*((UWORD *)rdptr)++ = tmp3;
}
EnterInterCount++;
printf("enter dm9000a interrupt timers is %d\n",EnterInterCount);
/*
rdptr = skb->pData;
if( (rdptr[0xc] == 0x08) && (rdptr[0xd] == 0x06) )
whz_puts("ARP\r\n");
*/
}
/* Pass to upper layer */
/* INT_UNLOCK(oldv);*/
/*2007-4-18 shengdegang add*/
intUnlock(oldv);
return 0;
}
else
{
printf("the packet is bad!\n");
/* bad packet*/
/* Without buffer or error packet */
if( dev->io_mode == 2 )
{
/* Byte mode */
for( i = 0; i < RxLen; i++ )
tmp1=DM9000_IN_BYTE();
}
else
{
/* Word mode */
tmplen = (RxLen + 1) / 2;
for( i = 0; i < tmplen; i++ )
tmp3=DM9000_IN_WORD();
}
/*INT_UNLOCK(oldv);*/
/*2007-4-18 shengdegang add*/
intUnlock(oldv);
dm9000Reset( dev );
dm9000Config( dev );
/*add end*/
return 1;
}
}
printf ("rxbyte!=DM9000_PKT_RDY!\n");
/*INT_UNLOCK(oldv);*/
/*2007-4-18 shengdegang add*/
intUnlock(oldv);
dm9000Reset( dev );
dm9000Config( dev );
/*add end*/
return 1;
}
/* Stop the interface.
The interface is stopped when it is brought.
*/
static int dmfe_stop_dm9000( END_DEVICE *dev)
{
/* RESET devie */
phy_write( dev, 0x00, 0x8000 ); /* PHY RESET */
/*2007-4-11 shengdegang modify*/
DM9000A_write_reg(0x1f, 0x01);
DM9000A_write_reg(0xff, 0x80);
DM9000A_write_reg(0x05, 0x00);
/* DM9000_OUT_CHAR( 0x1f, 0x01 );*/ /* Power-Down PHY */
/* DM9000_OUT_CHAR( 0xff, 0x80 ); */ /* Disable all interrupt */
/* DM9000_OUT_CHAR( 0x05, 0x00 ); */ /* Disable RX */
return 0;
}
/* Identify NIC type
*/
static void identify_nic( END_DEVICE *dev )
{
UWORD phy_reg3;
/*2007-4-11 shengdegang modify*/
DM9000A_write_reg(0, DM9000_EXT_MII);
/* DM9000_OUT_CHAR( 0, DM9000_EXT_MII );*/
phy_reg3 = phy_read( dev, 3 );
switch( phy_reg3 & 0xfff0 )
{
case 0xb900:
if (phy_read(dev, 31) == 0x4404)
{
dev->nic_type = HOMERUN_NIC;
program_dm9801( dev, phy_reg3);
}
else
{
dev->nic_type = LONGRUN_NIC;
program_dm9802(dev);
}
break;
default:
dev->nic_type = FASTETHER_NIC;
break;
}
/*2007-4-11 shengdegang modify*/
DM9000A_write_reg(0, DM9000_INT_MII);
/* DM9000_OUT_CHAR( 0, DM9000_INT_MII );*/
}
/* Set PHY operationg mode
*/
static void set_PHY_mode( END_DEVICE *dev )
{
int i;
UWORD phy_reg4 = 0x01e1, phy_reg0=0x1000;
if ( !(dev->op_mode & DM9000_AUTO) )
{
switch(dev->op_mode)
{
case DM9000_10MHD:
phy_reg4 = 0x21;
phy_reg0 = 0x0000;
for (i=0;i<65535;i++);
break;
case DM9000_10MFD:
phy_reg4 = 0x41;
/*phy_reg0 = 0x0100; */
phy_reg0 = 0x1100;
for (i=0;i<65535;i++);
break;
case DM9000_100MHD:
phy_reg4 = 0x81;
phy_reg0 = 0x2000;
for (i=0;i<65535;i++);
break;
case DM9000_100MFD:
phy_reg4 = 0x101;
phy_reg0 = 0x3100; /*add by whz from 2100 */
for (i=0;i<65535;i++);
break;
}
phy_write(dev, 4, phy_reg4); /* Set PHY media mode */
phy_write(dev, 0, phy_reg0); /* Tmp */
}
/*2007-4-11 shengdegang modify*/
DM9000A_write_reg(0x1e, 0x01);
DM9000A_write_reg(0x1f, 0x00);
}
/* Set DM9000 multicast address
* Set DM9000 Physical Address
*/
static void dm9000_hash_table(END_DEVICE *dev)
{
/* Set Node address */
/*2007-4-11 shengdegang modify*/
DM9000A_write_reg(0x10, dev->enetAddr[0]);
DM9000A_write_reg(0x11, dev->enetAddr[1]);
DM9000A_write_reg(0x12, dev->enetAddr[2]);
DM9000A_write_reg(0x13, dev->enetAddr[3]);
DM9000A_write_reg(0x14, dev->enetAddr[4]);
DM9000A_write_reg(0x15, dev->enetAddr[5]);
/* Write the hash table to MAC MD table */
/*2007-4-11 shengdegang modify*/
DM9000A_write_reg(0x16, dev->mcastFilter[0]);
DM9000A_write_reg(0x17, dev->mcastFilter[1]);
DM9000A_write_reg(0x18, dev->mcastFilter[2]);
DM9000A_write_reg(0x19, dev->mcastFilter[3]);
DM9000A_write_reg(0x1a, dev->mcastFilter[4]);
DM9000A_write_reg(0x1b, dev->mcastFilter[5]);
DM9000A_write_reg(0x1c, dev->mcastFilter[6]);
DM9000A_write_reg(0x1d, dev->mcastFilter[7]);
}
/*Init HomeRun DM9801
*/
static void program_dm9801( END_DEVICE *dev, UWORD HPNA_rev )
{
UWORD reg16, reg17, reg24, reg25;
if( !nfloor )
nfloor = DM9801_NOISE_FLOOR;
reg16 = phy_read(dev, 16);
reg17 = phy_read(dev, 17);
reg24 = phy_read(dev, 24);
reg25 = phy_read(dev, 25);
switch( HPNA_rev )
{
case 0xb900: /* DM9801 E3 */
reg16 |= 0x1000;
reg25 = ( (reg24 + nfloor) & 0x00ff) | 0xf000;
break;
case 0xb901: /* DM9801 E4 */
reg25 = ( (reg24 + nfloor) & 0x00ff) | 0xc200;
reg17 = (reg17 & 0xfff0) + nfloor + 3;
break;
case 0xb902: /* DM9801 E5 */
case 0xb903: /* DM9801 E6 */
default:
reg16 |= 0x1000;
reg25 = ( (reg24 + nfloor - 3) & 0x00ff) | 0xc200;
reg17 = (reg17 & 0xfff0) + nfloor;
break;
}
phy_write(dev, 16, reg16);
phy_write(dev, 17, reg17);
phy_write(dev, 25, reg25);
}
/*Init LongRun DM9802
*/
static void program_dm9802(END_DEVICE *dev)
{
UWORD reg25;
if ( !nfloor )
nfloor = DM9802_NOISE_FLOOR;
reg25 = phy_read(dev, 25);
reg25 = (reg25 & 0xff00) + nfloor;
phy_write(dev, 25, reg25);
}
/*Read a word from phyxcer
*
*/
static UWORD phy_read( END_DEVICE *dev, int reg )
{
UCHAR tmp1, tmp2;
/* Fill the phyxcer register into REG_0C */
/*2007-4-11 shengdegang modify*/
DM9000A_write_reg(0xc, DM9000_PHY | reg);
/* DM9000_OUT_CHAR( 0xc, DM9000_PHY | reg );*/
/*2007-4-11 shengdegang modify*/
DM9000A_write_reg(0xb, 0xc);
/* DM9000_OUT_CHAR( 0xb, 0xc );*/ /* Issue phyxcer read command */
do
{
udelay(100); /* Wait read complete */
/*2007-4-11 shengdegang modify*/
tmp1=DM9000A_read_reg(0xb);
/* DM9000_IN_CHAR( 0xb, tmp1 );*/
}while( tmp1&1 );
/*2007-4-11 shengdegang modify*/
DM9000A_write_reg(0xb, 0x0);
/* DM9000_OUT_CHAR( 0xb, 0x0 ); */ /* Clear phyxcer read command */
/* The read data keeps on REG_0D & REG_0E */
/*2007-4-11 shengdegang modify*/
tmp1=DM9000A_read_reg(0xe);
tmp2=DM9000A_read_reg(0xd);
/* DM9000_IN_CHAR( 0xe , tmp1 );
DM9000_IN_CHAR( 0xd , tmp2 );*/
return ( (tmp1 << 8 ) | tmp2 );
}
/* Write a word to phyxcer
*
*/
static void phy_write( END_DEVICE *dev, int reg, UWORD value)
{
UCHAR tmp1;
/* Fill the phyxcer register into REG_0C */
/*2007-4-11 shengdegang modify*/
DM9000A_write_reg(0xc, DM9000_PHY | reg);
/* DM9000_OUT_CHAR( 0xc, DM9000_PHY | reg );*/
/* Fill the written data into REG_0D & REG_0E */
/*2007-4-11 shengdegang modify*/
DM9000A_write_reg(0xd, (value & 0xff));
DM9000A_write_reg(0xe, ( (value >> 8) & 0xff));
/* DM9000_OUT_CHAR( 0xd, (value & 0xff) );
DM9000_OUT_CHAR( 0xe, ( (value >> 8) & 0xff) );*/
/*2007-4-11 shengdegang modify*/
DM9000A_write_reg(0xb, 0xa);
/* DM9000_OUT_CHAR( 0xb, 0xa ); */ /* Issue phyxcer write command */
do
{
udelay(100); /* Wait read complete */
/*2007-4-11 shengdegang modify*/
tmp1=DM9000A_read_reg(0xb);
/* DM9000_IN_CHAR( 0xb, tmp1 );*/
}while( tmp1&1 );
/*2007-4-11 shengdegang modify*/
DM9000A_write_reg(0xb, 0x0);
/* DM9000_OUT_CHAR( 0xb, 0x0 ); */ /* Clear phyxcer write command */
}
/* Read a word data from SROM
static UWORD read_srom_word( END_DEVICE *dev, UCHAR offset)
{
UCHAR tmp1, tmp2;
DM9000_OUT_CHAR( 0xc, offset);
DM9000_OUT_CHAR( 0xb, 0x4);
do
{
udelay(100); // Wait read complete
DM9000_IN_CHAR( 0xb, tmp1 );
}while( tmp1&1 );
DM9000_OUT_CHAR( 0xb, 0x0);
DM9000_IN_CHAR( 0xe, tmp1 );
DM9000_IN_CHAR( 0xd, tmp2 );
return ( (tmp1<<8) + tmp2 );
}
*/
/*
static void write_srom_word( END_DEVICE *dev, UCHAR offset, UWORD value )
{
unsigned char tmp1;
//DM9000_OUT_CHAR( 0xc, offset);
sysOutByte(0x300,0xc);
sysOutByte(0x304,offset);
DM9000_OUT_CHAR( 0xd, (value & 0xff) );
DM9000_OUT_CHAR( 0xe, ( (value >> 8) & 0xff) );
DM9000_OUT_CHAR( 0xb, 0x12);
do
{
udelay(100); // Wait read complete
DM9000_IN_CHAR( 0xb, tmp1 );
}while( tmp1&1 );
DM9000_OUT_CHAR( 0xb, 0x0);
}
*/
/* Calculate the CRC valude of the Rx packet
flag = 1 : return the reverse CRC (for the received packet CRC)
0 : return the normal CRC (for Hash Table index)
*/
unsigned long cal_CRC(unsigned char * Data, unsigned int Len, UCHAR flag)
{
unsigned long Crc = 0xffffffff;
while (Len--)
{
Crc = CrcTable[(Crc ^ *Data++) & 0xFF] ^ (Crc >> 8);
}
if( flag )
return ~Crc;
else
return Crc;
}
/* Delay N us
*/
void udelay( int us )
{
taskDelay(us/10);
/*
for( ;us > 0; us-- )
{
Delay500ns();
Delay500ns();
}*/
}
/* Delay 500 ns
static void Delay500ns(void)
{
int i;
register int dummy;
for(i=0;i<2;i++)
{
dummy=i;
}
}
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -