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

📄 dm9000end.c

📁 DM9000A的VXWORKS下驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
						
						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 + -