Esempio n. 1
0
/*
  Stop the interface.
  The interface is stopped when it is brought.
*/
static int dmfe_stop(struct net_device *dev)
{
	board_info_t *db = (board_info_t *)dev->priv;
	DMFE_DBUG(0, "dmfe_stop", 0);

	/* deleted timer */
	del_timer(&db->timer);

	netif_stop_queue(dev); 

	/* free interrupt */
	free_irq(dev->irq, dev);

	/* RESET devie */
	phy_write(db, 0x00, 0x8000);	/* PHY RESET */
	//iow(db, DM9KS_GPR, 0x01); 	/* Power-Down PHY */
	iow(db, DM9KS_IMR, DM9KS_DISINTR);	/* Disable all interrupt */
	iow(db, DM9KS_RXCR, 0x00);	/* Disable RX */

	/* Dump Statistic counter */
#if FALSE
	printk("\nRX FIFO OVERFLOW %lx\n", db->stats.rx_fifo_errors);
	printk("RX CRC %lx\n", db->stats.rx_crc_errors);
	printk("RX LEN Err %lx\n", db->stats.rx_length_errors);
	printk("RESET %x\n", db->reset_counter);
	printk("RESET: TX Timeout %x\n", db->reset_tx_timeout);
	printk("g_TX_nsr %x\n", g_TX_nsr);
#endif

	return 0;
}
Esempio n. 2
0
void __attribute__((interrupt("IRQ")))dm9000_isr(void)
{
	unsigned char int_status,Rx_ready;
	unsigned short Rx_status,Rx_len;
	int i;
	if(EINT0PEND & (1 << 7)){ //dm9000
		int_status = ior(0xfe);
		if(int_status & 1){ //rx
			Rx_ready = ior(0xf0);
			Rx_ready = ior(0xf0);
			if(Rx_ready == 1){
				DM9000_INDEX = 0xf2;
				Rx_status = DM9000_DATA16;
				Rx_len = DM9000_DATA16;
				for(i = 0;i < (Rx_len + 1) / 2;i++){
					((unsigned short*)Net_Rxbuf)[i] = DM9000_DATA16;
				}
				///
				uart_puts(Net_Rxbuf + 42);
			}
			iow(0xfe,1);
		}
		if(int_status & 2){//tx
			if(ior(0x01) & (4 | 8)){
				uart_printf("dm9000 send complete\n");
			}
			iow(0xfe,2);
		}
		EINT0PEND = (1 << 7);
	}
	VIC0ADDRESS = 0;
	VIC1ADDRESS = 0;
}
Esempio n. 3
0
/* Identify NIC type */
static void identify_nic(board_info_t * db)
{
    u16 phy_reg3;

    iow(db, 0, DM9000_EXT_MII);
    phy_reg3 = phy_read(db, 3);

    switch (phy_reg3 & 0xfff0) {

    case 0xb900:

        if (phy_read(db, 31) == 0x4404) {
            db->nic_type = HOMERUN_NIC;
            program_dm9801(db, phy_reg3);
        } else {
            db->nic_type = LONGRUN_NIC;
            program_dm9802(db);
        }
        break;
    default:
        db->nic_type = FASTETHER_NIC;
        break;
    }

    iow(db, 0, DM9000_INT_MII);
}
Esempio n. 4
0
//----DM9000A复位---------------------------------------------------------------
//功能:软件复位DM9000A。某些寄存器的值不受软件复位的影响。
//参数:无
//返回:无
//-----------------------------------------------------------------------------
void dm9000a_reset(void)
{
    iow(DM9000A_NCR, 0x01); // RESET
    do {
        Djy_DelayUs(30);    // 延时30us,应用手册上说至少20us
    } while (ior(DM9000A_NCR) & 0x01);
    iow(DM9000A_NCR, 0x00);
}
Esempio n. 5
0
/*
  Read a word data from SROM
*/
static u16 read_srom_word(board_info_t *db, int offset)
{
	iow(db, DM9KS_EPAR, offset);
	iow(db, DM9KS_EPCR, 0x4);
	while(ior(db, DM9KS_EPCR)&0x1);	/* Wait read complete */
	iow(db, DM9KS_EPCR, 0x0);
	return (ior(db, DM9KS_EPDRL) + (ior(db, DM9KS_EPDRH) << 8) );
}
Esempio n. 6
0
void dm9000_send(unsigned long addr,int size)
{
	int i;
	irq_disable(1);
	DM9000_INDEX = 0xf8;
	for(i = 0;i < (size + 1)/2; i++)
		DM9000_DATA16 = ((short *)addr)[i];
	iow(0xfd,(size >> 8) & 0xff);
	iow(0xfc,size & 0xff);
	iow(0x02,1);
	irq_enable(1);
}
Esempio n. 7
0
/*
   Read a word from phyxcer
*/
static u16 phy_read(board_info_t *db, int reg)
{
	/* Fill the phyxcer register into REG_0C */
	iow(db, DM9KS_EPAR, DM9KS_PHY | reg);

	iow(db, DM9KS_EPCR, 0xc); 	/* Issue phyxcer read command */
	while(ior(db, DM9KS_EPCR)&0x1);	/* Wait read complete */
	iow(db, DM9KS_EPCR, 0x0); 	/* Clear phyxcer read command */

	/* The read data keeps on REG_0D & REG_0E */
	return ( ior(db, DM9KS_EPDRH) << 8 ) | ior(db, DM9KS_EPDRL);
	
}
Esempio n. 8
0
/*
   Write a word to phyxcer
*/
static void phy_write(board_info_t *db, int reg, u16 value)
{
	/* Fill the phyxcer register into REG_0C */
	iow(db, DM9KS_EPAR, DM9KS_PHY | reg);

	/* Fill the written data into REG_0D & REG_0E */
	iow(db, DM9KS_EPDRL, (value & 0xff));
	iow(db, DM9KS_EPDRH, ( (value >> 8) & 0xff));

	iow(db, DM9KS_EPCR, 0xa);	/* Issue phyxcer write command */
	while(ior(db, DM9KS_EPCR)&0x1);	/* Wait read complete */
	iow(db, DM9KS_EPCR, 0x0);	/* Clear phyxcer write command */
}
Esempio n. 9
0
//----写PHY(半字)--------------------------------------------------------------
//功能:向PHY中写入16位的数据
//参数:reg,寄存器偏移地址
//      value,要写入的值
//返回:无
//-----------------------------------------------------------------------------
static void phyw_h(u8 reg, u16 value)
{
    iow(DM9000A_EPAR, reg|0x40);// 使用内部PHY时bit[7:6]要为01b
    iow(DM9000A_EPDRL, value&0xFF);
    iow(DM9000A_EPDRH, (value&0xFF00)>>8);
    iow(DM9000A_EPCR, 0x0A);        // 选择PHY功能,写功能
    while (ior(DM9000A_EPCR) & 0x01)
    {
        Djy_DelayUs(10);
    }
    Djy_DelayUs(150);
    iow(DM9000A_EPCR, 0x00);        // 由程序清零
}
Esempio n. 10
0
//----复位DM9000A到某一特定的原始状态---------------------------------------------
//功能:让DM9000A回到这样一个状态:除了中断未打开之外,其它有关于DM9000A的所有初始化工作
//      均已完成的地步。DM9000A芯片在从内部RAM中读数据时,如果读到的标志位不是1也不是0
//      时,会调用本函数,本函数需要清空RAM中的数据及使读写指针复位。
//参数:无
//返回:无
//-----------------------------------------------------------------------------
void dm9000a_reset_to_new(void)
{
    u8 flags;

    iow(DM9000A_IMR, 0x00); // 禁止发送、接收中断

    ior(DM9000A_ISR);   // 清除所有中断状态

    flags = 0x80;   // 读地址复位到0xC000,写地址复位到0x0000
    flags |= 0x01;  // 使能接收中断
    iow(DM9000A_IMR, flags);

    iow(DM9000A_TCR, 0);
    iow(DM9000A_RCR, 0x3d); // 使能接收(广播、Runt包,不使用混杂模式)
}
Esempio n. 11
0
/* Hardware start transmission.
 * Send a packet to media from the upper layer.
 */
static int dmfe_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
    board_info_t *db = (board_info_t *) dev->priv;
    char *data_ptr;
    int i, tmplen;
    DMFE_DBUG(0, "dmfe_start_xmit", 0);

    if (db->tx_pkt_cnt > 1) return 1;

    netif_stop_queue(dev);


    /* Disable all interrupt */
    iow(db, 0xff, 0x80);

    /* Move data to DM9000 TX RAM */
    data_ptr = (char *) skb->data;
    outb(0xf8, db->ioaddr);

    db->sent_pkt_len = skb->len;

    if (db->io_mode == DM9000_BYTE_MODE) {	    /* Byte mode */
        for (i = 0; i < skb->len; i++)
            outb((data_ptr[i] & 0xff), db->io_data);
    } else if (db->io_mode == DM9000_WORD_MODE) {   /* Word mode */
        tmplen = (skb->len + 1) / 2;
        for (i = 0; i < tmplen; i++)
            outw(((u16 *) data_ptr)[i], db->io_data);
    } else {					    /* DWord mode */
        tmplen = (skb->len + 3) / 4;
        for (i = 0; i < tmplen; i++)
            outl(((u32 *) data_ptr)[i], db->io_data);
    }

    /* TX control: First packet immediately send, second packet queue */
    if (db->tx_pkt_cnt == 0) {			/* First Packet */
        db->tx_pkt_cnt++;

        /* Set TX length to DM9000 */
        iow(db, 0xfc, skb->len & 0xff);
        iow(db, 0xfd, (skb->len >> 8) & 0xff);

        /* Issue TX polling command */
        iow(db, 0x2, 0x1);			/* Cleared after TX complete */

        /* saved the time stamp */
        dev->trans_start = jiffies;
    } else {					/* Second packet */
Esempio n. 12
0
bool_t debug_dm9000a_write_reg(char *param)
{
    char *word, *next_param;
    u32 reg = 0;
    u32 value = 0;

    // 提取为SOCKET号
    if (param)
    {
        next_param = param;
        word = Sh_GetWord(next_param, &next_param);
        reg = __sh_atol(word);
        word = Sh_GetWord(next_param, &next_param);
        value = __sh_atol(word);
        word = Sh_GetWord(next_param, &next_param);
        if(word != NULL)
        {
            printf("\r\n参数错误\r\n");
            return false;
        }
    }

    if (Lock_SempPend(semp_dm9000, 10000*mS) == true)
    {
        Int_SaveAsynLine(cn_int_line_enet); // 关闭DM9000A的外部中断
        printf("\r\n写入DM9000A的【%4x】寄存器:%4x", reg, value);
        iow(reg, value);

        printf("\r\n");

        Int_RestoreAsynLine(cn_int_line_enet);  // 打开DM9000A的外部中断
        Lock_SempPost(semp_dm9000);
    }
    return true;
}
Esempio n. 13
0
/*
 *  Set DM9000 multicast address
 */
static void
dm9000_hash_table_unlocked(struct net_device *dev)
{
	board_info_t *db = netdev_priv(dev);
	struct netdev_hw_addr *ha;
	int i, oft;
	u32 hash_val;
	u16 hash_table[4];
	u8 rcr = RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN;

	//dm9000_dbg(db, 1, "entering %s\n", __func__);

	for (i = 0, oft = DM9000_PAR; i < 6; i++, oft++)
		iow(db, oft, dev->dev_addr[i]);

	/* Clear Hash Table */
	for (i = 0; i < 4; i++)
		hash_table[i] = 0x0;

	/* broadcast address */
	hash_table[3] = 0x8000;

	if (dev->flags & IFF_PROMISC)
		rcr |= RCR_PRMSC;

	if (dev->flags & IFF_ALLMULTI)
		rcr |= RCR_ALL;

	/* the multicast address in Hash Table : 64 bits */
	netdev_for_each_mc_addr(ha, dev) {
		hash_val = ether_crc_le(6, ha->addr) & 0x3f;
		hash_table[hash_val / 16] |= (u16) 1 << (hash_val % 16);
	}
Esempio n. 14
0
//----DM9000A初始化-------------------------------------------------------------
//功能:初始化DM9000A
//参数:无
//返回:正常时返回0,错误时返回错误号
//-----------------------------------------------------------------------------
u32 dm9000a_init(void)
{
    u16 i;

    dm9000a_reset();    // 软件复位

    if (dm9000a_probe() != 0)   // 探查当前操作的芯片是否为DM9000A(读出ID进行对比)
        return -1;
    iow(DM9000A_GPR, 0x00); // PHYPD=0时使能PHY,默认为1表示不使能内部PHY
    Djy_DelayUs(20*mS);

    iow(DM9000A_NCR, 0x03); // 选择内部PHY
    Djy_DelayUs(20);
    iow(DM9000A_NCR, 0x03); // 选择内部PHY(重复一次)
    Djy_DelayUs(20);

    ior(DM9000A_NSR);   // 清除发送状态(读取即可清除)

    dm9000a_set_macaddr(MyMAC); // 设置MAC地址
    dm9000a_set_multicastaddr();    // 设置多播地址

    set_phy_mode(); // 自动协商

    while (!(phyr_h(1) & 0x20))     // 自动协商完成标志位
    {
        Djy_EventDelay(5*mS);   // 50mS
    }

    // 读回IO、Base模式
    ehi.io = (ior(DM9000A_ISR)>>6) & 0x3;
    ehi.base = (phyr_h(17)>>12) & 0xF;

    semp_dm9000 = Lock_SempCreate(1, 1, NULL);
    if (semp_dm9000 == NULL)
    {
        return -1;
    }

    dm9000a_reset_to_new();
    // TODO DM9000A具有IP、UDP、TCP的检验和自动计算功能
    //...

    i = ior(DM9000A_NSR);       // xxx del 需要等于0x40才表示连接成功

    return 0;
}
Esempio n. 15
0
//----读PHY(半字)--------------------------------------------------------------
//功能:从PHY中读取16位的数据
//参数:reg,寄存器偏移地址
//返回:读得的寄存器值
//-----------------------------------------------------------------------------
static u16 phyr_h(u8 reg)
{
    u16 tmp;

    iow(DM9000A_EPAR, reg|0x40);    // 使用内部PHY时bit[7:6]要为01b
    iow(DM9000A_EPCR, 0x0C);        // 选择PHY功能,读取功能
    while (ior(DM9000A_EPCR) & 0x01)
    {
        Djy_DelayUs(10);
    }
    Djy_DelayUs(150);
    iow(DM9000A_EPCR, 0x00);        // 由程序清零
    tmp = ior(DM9000A_EPDRL);
    tmp |= ior(DM9000A_EPDRH)<<8;

    return tmp;
}
Esempio n. 16
0
static void
dm9000_reset(struct board_info *db)
{
    dev_dbg(db->dev, "resetting device\n");

    /* Reset DM9000, see DM9000 Application Notes V1.22 Jun 11, 2004 page 29
     * The essential point is that we have to do a double reset, and the
     * instruction is to set LBK into MAC internal loopback mode.
     */
    iow(db, DM9000_NCR, NCR_RST | NCR_MAC_LBK);
    udelay(100); /* Application note says at least 20 us */
    if (ior(db, DM9000_NCR) & 1)
        dev_err(db->dev, "dm9000 did not respond to first reset\n");

    iow(db, DM9000_NCR, 0);
    iow(db, DM9000_NCR, NCR_RST | NCR_MAC_LBK);
    udelay(100);
    if (ior(db, DM9000_NCR) & 1)
        dev_err(db->dev, "dm9000 did not respond to second reset\n");
}
Esempio n. 17
0
//#if defined(CONFIG_DM9000_16BIT)
static void dm9000_reset(board_info_t *db)
{
	dev_dbg(db->dev, "resetting device\n");

	iow(db, DM9000_GPCR, 0x0f);
	iow(db, DM9000_GPR, 0);
	iow(db, DM9000_NCR, 3);

	do {
		udelay(100);
	} while (ior(db, DM9000_NCR) & 0x1);

	iow(db, DM9000_NCR, 0);
	iow(db, DM9000_NCR, 3);

	do {
		udelay(100);
	} while (ior(db, DM9000_NCR) & 0x1);

	if ((ior(db, DM9000_PIDL) != 0) || (ior(db, DM9000_PIDH) != 0x90))
		printk(KERN_INFO "ERROR : resetting ");
}
Esempio n. 18
0
/*
  A periodic timer routine
*/
static void dmfe_timer(unsigned long data)
{
	struct net_device * dev = (struct net_device *)data;
	board_info_t *db = (board_info_t *)dev->priv;
	DMFE_DBUG(0, "dmfe_timer()", 0);
	
	if (db->cont_rx_pkt_cnt>=CONT_RX_PKT_CNT)
	{
		db->cont_rx_pkt_cnt=0;
		iow(db, DM9KS_IMR, DM9KS_REGFF);
	}
	/* Set timer again */
	db->timer.expires = DMFE_TIMER_WUT;
	add_timer(&db->timer);
	
	return;
}
Esempio n. 19
0
/*
  Set DM9000/DM9010 multicast address
*/
static void dm9000_hash_table(struct net_device *dev)
{
	board_info_t *db = (board_info_t *)dev->priv;
	struct dev_mc_list *mcptr = dev->mc_list;
	int mc_cnt = dev->mc_count;
	u32 hash_val;
	u16 i, oft, hash_table[4];

	DMFE_DBUG(0, "dm9000_hash_table()", 0);

	/* enable promiscuous mode */
	if (dev->flags & IFF_PROMISC){
		//printk(KERN_INFO "DM9KS:enable promiscuous mode\n");
		iow(db, DM9KS_RXCR, ior(db,DM9KS_RXCR)|(1<<1));
		return;
	}else{
		//printk(KERN_INFO "DM9KS:disable promiscuous mode\n");
		iow(db, DM9KS_RXCR, ior(db,DM9KS_RXCR)&(~(1<<1)));
	}
		
	/* Receive all multicast packets */
	if (dev->flags & IFF_ALLMULTI){
		//printk(KERN_INFO "DM9KS:Pass all multicast\n");
		iow(db, DM9KS_RXCR, ior(db,DM9KS_RXCR)|(1<<3));
	}else{
		//printk(KERN_INFO "DM9KS:Disable pass all multicast\n");
		iow(db, DM9KS_RXCR, ior(db,DM9KS_RXCR)&(~(1<<3)));
	}
	
	/* Set Node address */
	for (i = 0, oft = 0x10; i < 6; i++, oft++)
		iow(db, oft, dev->dev_addr[i]);

	/* Clear Hash Table */
	for (i = 0; i < 4; i++)
		hash_table[i] = 0x0;

	/* broadcast address */
	hash_table[3] = 0x8000;

	/* the multicast address in Hash Table : 64 bits */
	for (i = 0; i < mc_cnt; i++, mcptr = mcptr->next) {
		hash_val = cal_CRC((char *)mcptr->dmi_addr, 6, 0) & 0x3f; 
		hash_table[hash_val / 16] |= (u16) 1 << (hash_val % 16);
	}

	/* Write the hash table to MAC MD table */
	for (i = 0, oft = 0x16; i < 4; i++) {
		iow(db, oft++, hash_table[i] & 0xff);
		iow(db, oft++, (hash_table[i] >> 8) & 0xff);
	}
}
Esempio n. 20
0
/*
  Received a packet and pass to upper layer
*/
static void dmfe_packet_receive(struct net_device *dev)
{
	board_info_t *db = (board_info_t *)dev->priv;
	struct sk_buff *skb;
	u8 rxbyte;
	u16 i, GoodPacket, tmplen = 0, MDRAH, MDRAL;
	u32 tmpdata;

	rx_t rx;

	u16 * ptr = (u16*)&rx;
	u8* rdptr;

	DMFE_DBUG(0, "dmfe_packet_receive()", 0);

	db->cont_rx_pkt_cnt=0;
	
	do {
		/*store the value of Memory Data Read address register*/
		MDRAH=ior(db, DM9KS_MDRAH);
		MDRAL=ior(db, DM9KS_MDRAL);
		
		ior(db, DM9KS_MRCMDX);		/* Dummy read */
		rxbyte = inb(db->io_data);	/* Got most updated data */

#ifdef CHECKSUM	
		if (rxbyte&0x2)			/* check RX byte */
		{	
      printk("dm9ks: abnormal!\n");
			dmfe_reset(dev); 
			break;	
    }else { 
      if (!(rxbyte&0x1))
				break;	
    }		
#else
		if (rxbyte==0)
			break;
		
		if (rxbyte>1)
		{	
      printk("dm9ks: Rxbyte error!\n");
		  dmfe_reset(dev);
      break;	
    }
#endif

		/* A packet ready now  & Get status/length */
		GoodPacket = TRUE;
		outb(DM9KS_MRCMD, db->io_addr);

		/* Read packet status & length */
		switch (db->io_mode) 
			{
			  case DM9KS_BYTE_MODE: 
 				    *ptr = inb(db->io_data) + 
				               (inb(db->io_data) << 8);
				    *(ptr+1) = inb(db->io_data) + 
					    (inb(db->io_data) << 8);
				    break;
			  case DM9KS_WORD_MODE:
				    *ptr = inw(db->io_data);
				    *(ptr+1)    = inw(db->io_data);
				    break;
			  case DM9KS_DWORD_MODE:
				    tmpdata  = inl(db->io_data);
				    *ptr = tmpdata;
				    *(ptr+1)    = tmpdata >> 16;
				    break;
			  default:
				    break;
			}

		/* Packet status check */
		if (rx.desc.status & 0xbf)
		{
			GoodPacket = FALSE;
			if (rx.desc.status & 0x01) 
			{
				db->stats.rx_fifo_errors++;
				printk(KERN_INFO"<RX FIFO error>\n");
			}
			if (rx.desc.status & 0x02) 
			{
				db->stats.rx_crc_errors++;
				printk(KERN_INFO"<RX CRC error>\n");
			}
			if (rx.desc.status & 0x80) 
			{
				db->stats.rx_length_errors++;
				printk(KERN_INFO"<RX Length error>\n");
			}
			if (rx.desc.status & 0x08)
				printk(KERN_INFO"<Physical Layer error>\n");
		}

		if (!GoodPacket)
		{
			// drop this packet!!!
			switch (db->io_mode)
			{
				case DM9KS_BYTE_MODE:
			 		for (i=0; i<rx.desc.length; i++)
						inb(db->io_data);
					break;
				case DM9KS_WORD_MODE:
					tmplen = (rx.desc.length + 1) / 2;
					for (i = 0; i < tmplen; i++)
						inw(db->io_data);
					break;
				case DM9KS_DWORD_MODE:
					tmplen = (rx.desc.length + 3) / 4;
					for (i = 0; i < tmplen; i++)
						inl(db->io_data);
					break;
			}
			continue;/*next the packet*/
		}
		
		skb = dev_alloc_skb(rx.desc.length+4);
		if (skb == NULL )
		{	
			printk(KERN_INFO "%s: Memory squeeze.\n", dev->name);
			/*re-load the value into Memory data read address register*/
			iow(db,DM9KS_MDRAH,MDRAH);
			iow(db,DM9KS_MDRAL,MDRAL);
			return;
		}
		else
		{
			/* Move data from DM9000 */
			skb->dev = dev;
			skb_reserve(skb, 2);
			rdptr = (u8*)skb_put(skb, rx.desc.length - 4);
			
			/* Read received packet from RX SARM */
			switch (db->io_mode)
			{
				case DM9KS_BYTE_MODE:
			 		for (i=0; i<rx.desc.length; i++)
						rdptr[i]=inb(db->io_data);
					break;
				case DM9KS_WORD_MODE:
					tmplen = (rx.desc.length + 1) / 2;
					for (i = 0; i < tmplen; i++)
						((u16 *)rdptr)[i] = inw(db->io_data);
					break;
				case DM9KS_DWORD_MODE:
					tmplen = (rx.desc.length + 3) / 4;
					for (i = 0; i < tmplen; i++)
						((u32 *)rdptr)[i] = inl(db->io_data);
					break;
			}
		
			/* Pass to upper layer */
			skb->protocol = eth_type_trans(skb,dev);

#ifdef CHECKSUM
		if((rxbyte&0xe0)==0)	/* receive packet no checksum fail */
				skb->ip_summed = CHECKSUM_UNNECESSARY;
#endif
		
			netif_rx(skb);
			dev->last_rx=jiffies;
			db->stats.rx_packets++;
			db->stats.rx_bytes += rx.desc.length;
			db->cont_rx_pkt_cnt++;
#ifdef RDBG /* check RX FIFO pointer */
			u16 MDRAH1, MDRAL1;
			u16 tmp_ptr;
			MDRAH1 = ior(db,DM9KS_MDRAH);
			MDRAL1 = ior(db,DM9KS_MDRAL);
			tmp_ptr = (MDRAH<<8)|MDRAL;
			switch (db->io_mode)
			{
				case DM9KS_BYTE_MODE:
					tmp_ptr += rx.desc.length+4;
					break;
				case DM9KS_WORD_MODE:
					tmp_ptr += ((rx.desc.length+1)/2)*2+4;
					break;
				case DM9KS_DWORD_MODE:
					tmp_ptr += ((rx.desc.length+3)/4)*4+4;
					break;
			}
			if (tmp_ptr >=0x4000)
				tmp_ptr = (tmp_ptr - 0x4000) + 0xc00;
			if (tmp_ptr != ((MDRAH1<<8)|MDRAL1))
				printk("[dm9ks:RX FIFO ERROR\n");
#endif
				
			if (db->cont_rx_pkt_cnt>=CONT_RX_PKT_CNT)
			{
				dmfe_tx_done(0);
				break;
			}
		}
			
	}while((rxbyte & 0x01) == DM9KS_PKT_RDY);
	DMFE_DBUG(0, "[END]dmfe_packet_receive()", 0);
	
}
Esempio n. 21
0
void dm9000_init(void)
{
	SROM_BW |= (1 << 4);
	GPNCON &= ~(0x3 << 14);
	GPNCON |= (2 << 14);
	EINT0CON0 &= ~(7 << 12);
	EINT0CON0 |= (1 << 12);
	EINT0MASK &= ~(1 << 7);
	vic_request(1,dm9000_isr);

	//dm9000
	iow(0x1f,0x00);
	iow(0x00,1);
	delay(10);
	iow(0x00,0);
	iow(0xff,(1 << 7));
	iow(0x10,0x00);
	iow(0x11,0x11);
	iow(0x12,0x22);
	iow(0x13,0x33);
	iow(0x14,0x44);
	iow(0x15,0x55);
	iow(0x01,(1 << 2)|(1 << 3)|(1 << 5));
	iow(0xfe,0xff);
	iow(0xff,(1 << 7)|(1 << 1)|(1 << 0));
	iow(0x05,1);
}
Esempio n. 22
0
/* Initilize dm9000 board */
static void dmfe_init_dm9000(struct net_device *dev)
{
    board_info_t *db = (board_info_t *) dev->priv;
    DMFE_DBUG(0, "dmfe_init_dm9000()", 0);

    /* set the internal PHY power-on, GPIOs normal, and wait 2ms */
    iow(db, 0x1F, 0);		/* GPR (reg_1Fh)bit GPIO0=0 pre-activate PHY */
    udelay(20);			/* wait 2ms for PHY power-on ready */

    /* do a software reset and wait 20us */
    iow(db, DM9000_NCR, 3);
    udelay(20);			/* wait 20us at least for software reset ok */
    iow(db, 0, 3);		/* NCR (reg_00h) bit[0] RST=1 & Loopback=1,
				 * reset on. Added by SPenser */
    udelay(20);			/* wait 20us at least for software reset ok */

// Marked by Spenser
    /* set GPIO0=1 then GPIO0=0 to turn off and on the internal PHY */
    iow(db, 0x1F, 1);		/* GPR (reg_1Fh) bit[0] GPIO0=1 turn-off PHY  */
    iow(db, 0x1F, 0);		/* GPR (reg_1Fh) bit[0] GPIO0=0 activate PHY  */
    udelay(1000);		/* wait 4ms linking PHY (AUTO sense) if RX/TX */
    udelay(1000);
    udelay(1000);
    udelay(1000);

    /* I/O mode */
    db->io_mode = ior(db, 0xfe) >> 6;	/* ISR bit7:6 keeps I/O mode */

    /* NIC Type: FASTETHER, HOMERUN, LONGRUN */
    identify_nic(db);

    /* Set PHY */
    db->op_mode = media_mode;
    set_PHY_mode(db);

    /* Init needed register value */
    db->reg0 = DM9000_NCR;
    if ((db->nic_type != FASTETHER_NIC) && (db->op_mode & DM9000_1M_HPNA))
        db->reg0 |= DM9000_EXT_MII;

    /* User passed argument */
    db->reg5 = reg5;
    db->reg8 = reg8;
    db->reg9 = reg9;
    db->rega = rega;

    /* Program operating register */
    iow(db, 0x00, 0x08);
    iow(db, 0x02, 0);		/* TX Polling clear */
    iow(db, 0x2f, 0);		/* Special Mode */
    iow(db, 0x01, 0x2c);	/* clear TX status */
    iow(db, 0xfe, 0x0f);	/* Clear interrupt status */
    iow(db, 0x08, 0x37);
    iow(db, 0x09, 0x38);	/* Flow control: High/Low water */
    iow(db, 0x0a, 0x29);	/* flow control */

    /* Set address filter table */
    dm9000_hash_table(dev);

    /* Activate DM9000 */
    iow(db, 0x05, db->reg5 | 1);	/* RX enable */
    iow(db, 0xff, DM9000_REGFF);	/* Enable TX/RX interrupt mask */

    /* Init Driver variable */
    db->link_failed	= 1;
    db->tx_pkt_cnt	= 0;
    db->queue_pkt_len	= 0;
    dev->trans_start	= 0;

    netif_carrier_on(dev);
    spin_lock_init(&db->lock);
}
Esempio n. 23
0
//----设置MAC地址---------------------------------------------------------------
//功能:设置MAC地址
//参数:mac,以太网的地址数组(6个字节)
//返回:无
//-----------------------------------------------------------------------------
void dm9000a_set_macaddr(u8 mac[])
{
    for (int i=0; i<6; i++)
        iow(DM9000A_PAR0+i, mac[i]);
}
Esempio n. 24
0
//----设置多播地址---------------------------------------------------------------
//功能:设置多播地址
//参数:mulicast,多播地址数组(8个字节)
//返回:无
//-----------------------------------------------------------------------------
void dm9000a_set_multicastaddr(void)
{
    // 设置多播地址
    for (int i=0; i<8; i++)
        iow(DM9000A_MAR0+i, 0xFF);
}
Esempio n. 25
0
/**
 * Reciving singlas from ethernet controller -
 * TX - transmited packet
 * RX - recived packet
 * LinkChange - Connected/Diconncted Ethernet Cable
 *
 */
void ethernet_interrupts_simple()
{
    frame *curr_frame = 0;
	int filtered;
	uint8_t interruption =ior(ISR);    //which interruption

    packet_num++;

    iow(IMR, 0);
 //   iow(IMR, PAR_set);
   // printf("ISR 0x%2X \n",interruption);

    if( interruption & 0x01 )      //RX
    {

    	iow(ISR,0x01);
    	curr_frame = get_free_frame();
    	if(curr_frame == 0)
    	{
    		return; //ERROR no more free frames
    	}

    	aaa=ReceivePacket(curr_frame->f_data,&curr_frame->f_len);
    	if(aaa == 0)
    	{
        	filtered =   filter_packiets(curr_frame->f_data,curr_frame->f_len);

        	if (filtered == 0)
        	{
        		printf(" RX:UDP \n");
        		add_rx_frame(curr_frame);

        	}
        	else if (filtered == 10) //arp
        	{
        		printf(" RX:ARP \n");
        		add_rx_frame(curr_frame);
        	}
        	else
        	{
    			release_frame(curr_frame);
    		}
        	curr_frame = 0;

    	}
    	else
    	{
    		printf("%s Recived Bad Frame \n",__FUNCTION__);

    		release_frame(curr_frame);
    		curr_frame = 0;
    	}

    	/* ethernet_header *tmp = (ethernet_header *) RXT;
    	 ether_addr adres =  { 0x01, 0x60, 0x6E, 0x11, 0x01, 0x1F  };


    	 tmp->eth_src_addr = adres;
         TransmitPacket(RXT,rx_len);*/
    }


    if(interruption & 0x02)    //TX
    {
    	iow(ISR,0x02);
    	tx_control = 0;

    }
    if(interruption & 0x20)    //LinkChange
    {
    	iow(ISR,0x20);

/*    	iow(0x00,0x01);  // software reset
    	usleep(10);
    	  enable interrupts to activate DM9000 ~on
    	  iow(IMR, INTR_set2);    IMR REG. FFH PAR=1 only, or + PTM=1& PRM=1 enable RxTx interrupts
    	  iow(0xFF, 0x80);
    	   enable RX (Broadcast/ ALL_MULTICAST) ~go
    	  iow(RCR , RCR_set | RX_ENABLE | PASS_MULTICAST);   RCR REG. 05 RXEN Bit [0] = 1 to enable the RX machine/ filter */

    	//printf(" LinkCHange \n");
    	if(link_control == 0)
    		link_control = 1;
    	else
    		link_control = 0;
    }




    iow(IMR, INTR_set2);
}
Esempio n. 26
0
	static irqreturn_t dmfe_interrupt(int irq, void *dev_id) /* for kernel 2.6.20*/
	#endif
#endif
{
	struct net_device *dev = dev_id;
	board_info_t *db;
	int int_status,i;
	u8 reg_save;

	DMFE_DBUG(0, "dmfe_interrupt()", 0);

	/* A real interrupt coming */
	db = (board_info_t *)dev->priv;
	spin_lock(&db->lock);

	/* Save previous register address */
	reg_save = inb(db->io_addr);

	/* Disable all interrupt */
	iow(db, DM9KS_IMR, DM9KS_DISINTR); 

	/* Got DM9000/DM9010 interrupt status */
	int_status = ior(db, DM9KS_ISR);		/* Got ISR */
	iow(db, DM9KS_ISR, int_status);		/* Clear ISR status */ 

	/* Link status change */
	if (int_status & DM9KS_LINK_INTR) 
	{
		netif_stop_queue(dev);
		for(i=0; i<500; i++) /*wait link OK, waiting time =0.5s */
		{
			phy_read(db,0x1);
			if(phy_read(db,0x1) & 0x4) /*Link OK*/
			{
				/* wait for detected Speed */
				for(i=0; i<200;i++)
					udelay(1000);
				/* set media speed */
				if(phy_read(db,0)&0x2000) db->Speed =100;
				else db->Speed =10;
				break;
			}
			udelay(1000);
		}
		netif_wake_queue(dev);
		//printk("[INTR]i=%d speed=%d\n",i, (int)(db->Speed));	
	}
	/* Received the coming packet */
	if (int_status & DM9KS_RX_INTR) 
		dmfe_packet_receive(dev);

	/* Trnasmit Interrupt check */
	if (int_status & DM9KS_TX_INTR)
		dmfe_tx_done(0);
	
	if (db->cont_rx_pkt_cnt>=CONT_RX_PKT_CNT)
	{
		iow(db, DM9KS_IMR, 0xa2);
	}
	else
	{
		/* Re-enable interrupt mask */ 
		iow(db, DM9KS_IMR, DM9KS_REGFF);
	}
	
	/* Restore previous register address */
	outb(reg_save, db->io_addr); 

	spin_unlock(&db->lock); 
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
	return IRQ_HANDLED;
#endif
}
Esempio n. 27
0
//----发送一帧数据---------------------------------------------------------------
//功能:发送一个数据包到以太网上
//参数:upsec,上层数据包(一个链表结构)的头指针
//返回:正常时为发送的字节数;错误时为-1
//-----------------------------------------------------------------------------
s32 __hw_write_out(struct enet_send_section *upsec)
{
    u16 dat;
    u32 i, len, times, totlen;
    struct enet_send_section* pt_ssec;

    // 请求DM9000A硬件操作的信号量,如果没有发出去,则返回
    if (Lock_SempPend(semp_dm9000, 0) == true)
    {
        Int_SaveAsynLine(cn_int_line_enet); // 关闭DM9000A的外部中断
        totlen = 0;
        pt_ssec = upsec;

        ADDRW8(DM9000A_MWCMD);
        if (ehi.io == 0)    // 16-bit
        {
            u8* pt_data;    // 定义字节为8位的,下面进行强制转换
            while (pt_ssec != NULL)
            {
                pt_data = (u8*)pt_ssec->data;
                len = pt_ssec->count;
                totlen += len;
                if ((ptu32_t)pt_data & 0x01)    //判断指针是否双字节对齐
                {
                    for (i=0; i<len; i+=2)
                    {
                        dat = pt_data[i] + (pt_data[i+1]<<8);
                        DATAW16(dat);
                    }
                }
                else
                {
                    times = (len+1)/2;
                    for (i=0; i<times; i++)
                        DATAW16(((u16*)pt_data)[i]);
                }

                pt_ssec = pt_ssec->next_data_ssection;
            }
        }
        else if (ehi.io == 1) // 32-bit
        {
        }
        else if (ehi.io == 2) // 8-bit
        {
        }

        if (totlen > 0)
        {
            iow(DM9000A_TXPLH, (totlen>>8) & 0xff);
            iow(DM9000A_TXPLL, totlen & 0xff);
            iow(DM9000A_NSR, 0x2c);     // 清除状态寄存器
            iow(DM9000A_TCR, ior(DM9000A_TCR) | 0x01);      //发送数据到以太网上

            // 等待发送完成
            // NSR中TX1END及TX2END(发送完成)
            // ISR中PTM(发送完成)
            times = 100;    // 相当等待于3S
            while (!(ior(DM9000A_NSR) & 0x0C) || !(ior(DM9000A_ISR) & 0x02))
            {
                if (times == 0)
                {
                    dm9000a_reset_to_new();
                    break ;
                }
                times--;
                Djy_DelayUs(10);
            }
        }
Esempio n. 28
0
/*
  Hardware start transmission.
  Send a packet to media from the upper layer.
*/
static int dmfe_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
	board_info_t *db = (board_info_t *)dev->priv;
	char * data_ptr;
	int i, tmplen;
	u16 MDWAH, MDWAL;
	
	#ifdef TDBUG /* check TX FIFO pointer */
			u16 MDWAH1, MDWAL1;
			u16 tx_ptr;
	#endif
	
	DMFE_DBUG(0, "dmfe_start_xmit", 0);
	if (db->chip_revision != 0x1A)
	{	
		if(db->Speed == 10)
			{if (db->tx_pkt_cnt >= 1) return 1;}
		else
			{if (db->tx_pkt_cnt >= 2) return 1;}
	}else
		if (db->tx_pkt_cnt >= 2) return 1;
	
	/* packet counting */
	db->tx_pkt_cnt++;

	db->stats.tx_packets++;
	db->stats.tx_bytes+=skb->len;
	if (db->chip_revision != 0x1A)
	{
		if (db->Speed == 10)
			{if (db->tx_pkt_cnt >= 1) netif_stop_queue(dev);}
		else
			{if (db->tx_pkt_cnt >= 2) netif_stop_queue(dev);}
	}else
		if (db->tx_pkt_cnt >= 2) netif_stop_queue(dev);		

	/* Disable all interrupt */
	iow(db, DM9KS_IMR, DM9KS_DISINTR);

	MDWAH = ior(db,DM9KS_MDWAH);
	MDWAL = ior(db,DM9KS_MDWAL);

	/* Set TX length to reg. 0xfc & 0xfd */
	iow(db, DM9KS_TXPLL, (skb->len & 0xff));
	iow(db, DM9KS_TXPLH, (skb->len >> 8) & 0xff);

	/* Move data to TX SRAM */
	data_ptr = (char *)skb->data;
	
	outb(DM9KS_MWCMD, db->io_addr); // Write data into SRAM trigger
	switch(db->io_mode)
	{
		case DM9KS_BYTE_MODE:
			for (i = 0; i < skb->len; i++)
				outb((data_ptr[i] & 0xff), db->io_data);
			break;
		case DM9KS_WORD_MODE:
			tmplen = (skb->len + 1) / 2;
			for (i = 0; i < tmplen; i++)
        outw(((u16 *)data_ptr)[i], db->io_data);
      break;
    case DM9KS_DWORD_MODE:
      tmplen = (skb->len + 3) / 4;			
			for (i = 0; i< tmplen; i++)
				outl(((u32 *)data_ptr)[i], db->io_data);
			break;
	}
	
#ifndef ETRANS
	/* Issue TX polling command */
	iow(db, DM9KS_TCR, 0x1); /* Cleared after TX complete*/
#endif

	#ifdef TDBUG /* check TX FIFO pointer */
			MDWAH1 = ior(db,DM9KS_MDWAH);
			MDWAL1 = ior(db,DM9KS_MDWAL);
			tx_ptr = (MDWAH<<8)|MDWAL;
			switch (db->io_mode)
			{
				case DM9KS_BYTE_MODE:
					tx_ptr += skb->len;
					break;
				case DM9KS_WORD_MODE:
					tx_ptr += ((skb->len + 1) / 2)*2;
					break;
				case DM9KS_DWORD_MODE:
					tx_ptr += ((skb->len+3)/4)*4;
					break;
			}
			if (tx_ptr > 0x0bff)
					tx_ptr -= 0x0c00;
			if (tx_ptr != ((MDWAH1<<8)|MDWAL1))
					printk("[dm9ks:TX FIFO ERROR\n");
	#endif
	/* Saved the time stamp */
	dev->trans_start = jiffies;
	db->cont_rx_pkt_cnt =0;

	/* Free this SKB */
	dev_kfree_skb(skb);

	/* Re-enable interrupt */
	iow(db, DM9KS_IMR, DM9KS_REGFF);

	return 0;
}
Esempio n. 29
0
/* 
	Initilize dm9000 board
*/
static void dmfe_init_dm9000(struct net_device *dev)
{
	board_info_t *db = (board_info_t *)dev->priv;
	DMFE_DBUG(0, "dmfe_init_dm9000()", 0);

	spin_lock_init(&db->lock);
	
	iow(db, DM9KS_GPR, 0);	/* GPR (reg_1Fh)bit GPIO0=0 pre-activate PHY */
	mdelay(20);		/* wait for PHY power-on ready */

	/* do a software reset and wait 20us */
	iow(db, DM9KS_NCR, 3);
	udelay(20);		/* wait 20us at least for software reset ok */
	iow(db, DM9KS_NCR, 3);	/* NCR (reg_00h) bit[0] RST=1 & Loopback=1, reset on */
	udelay(20);		/* wait 20us at least for software reset ok */

	/* I/O mode */
	db->io_mode = ior(db, DM9KS_ISR) >> 6; /* ISR bit7:6 keeps I/O mode */

	/* Set PHY */
	db->op_mode = media_mode;
	set_PHY_mode(db);

	/* Program operating register */
	iow(db, DM9KS_NCR, 0);
	iow(db, DM9KS_TCR, 0);		/* TX Polling clear */
	iow(db, DM9KS_BPTR, 0x3f);	/* Less 3kb, 600us */
	iow(db, DM9KS_SMCR, 0);		/* Special Mode */
	iow(db, DM9KS_NSR, 0x2c);	/* clear TX status */
	iow(db, DM9KS_ISR, 0x0f); 	/* Clear interrupt status */
	iow(db, DM9KS_TCR2, 0x80);	/* Set LED mode 1 */
	if (db->chip_revision == 0x1A){ 
		/* Data bus current driving/sinking capability  */
		iow(db, DM9KS_BUSCR, 0x01);	/* default: 2mA */
	}
#ifdef FLOW_CONTROL
	iow(db, DM9KS_BPTR, 0x37);
	iow(db, DM9KS_FCTR, 0x38);
	iow(db, DM9KS_FCR, 0x29);
#endif

#ifdef DM8606
	iow(db,0x34,1);
#endif

	if (dev->features & NETIF_F_HW_CSUM){
		printk(KERN_INFO "DM9KS:enable TX checksum\n");
		iow(db, DM9KS_TCCR, 0x07);	/* TX UDP/TCP/IP checksum enable */
	}
	if (db->rx_csum){
		printk(KERN_INFO "DM9KS:enable RX checksum\n");
		iow(db, DM9KS_RCSR, 0x02);	/* RX checksum enable */
	}

#ifdef ETRANS
	/*If TX loading is heavy, the driver can try to anbel "early transmit".
	The programmer can tune the "Early Transmit Threshold" to get 
	the optimization. (DM9KS_ETXCSR.[1-0])
	
	Side Effect: It will happen "Transmit under-run". When TX under-run
	always happens, the programmer can increase the value of "Early 
	Transmit Threshold". */
	iow(db, DM9KS_ETXCSR, 0x83);
#endif
 
	/* Set address filter table */
	dm9000_hash_table(dev);

	/* Activate DM9000/DM9010 */
	iow(db, DM9KS_IMR, DM9KS_REGFF); /* Enable TX/RX interrupt mask */
	iow(db, DM9KS_RXCR, DM9KS_REG05 | 1);	/* RX enable */
	
	/* Init Driver variable */
	db->tx_pkt_cnt 		= 0;
		
	netif_carrier_on(dev);

}
Esempio n. 30
0
void handle_rx_snif(simrf_rx_info_t *rxinfo, uint8_t *rx_buffer)
{
	int i;
	iow(magic[0]);
	iow(magic[1]);
	iow(magic[2]);
	iow(magic[3]);
	iow(1); // version
	iow(0); // CMD_FRAME
	
	iow(rxinfo->frame_length + 3 + 2);
	iow(rxinfo->fc_raw & 0xff);
	iow(rxinfo->fc_raw >> 8);
	iow(rxinfo->sequence_number);
	for (i = 0; i < rxinfo->frame_length; ++i) {
		iow(rx_buffer[i]);
	}
	iow(rxinfo->rssi);
	// This is TI cc25xx FCS format, with FCS valid hardcoded
	iow(rxinfo->lqi | 0x80);
}