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

📄 dm9ks_ucos.c

📁 硬件设计LPC2138+DM9000AE
💻 C
📖 第 1 页 / 共 2 页
字号:
	/* Saved the time stamp */
//	dev->trans_start = jiffies;

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

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

	return OK;
}

/*
  Stop the interface.
  The interface is stopped when it is brought.
*/
int dmfe_stop(void)
{
	DEBUG_OUT("dmfe_stop !!!");

	/* deleted timer */
//	del_timer(&netif.timer);

//	netif_stop_queue(); 

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

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

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

	return 0;
}

void dmfe_tx_done(unsigned long unused)
{
	int  tx_status;

//	DEBUG_OUT("dmfe_tx_done()");
	
	tx_status = ior(DM9KS_NSR, netif.io_addr);
	if (tx_status & 0xc) 
	{
		/* One packet sent complete */
		netif.tx_pkt_cnt--;
		
			if (netif.tx_pkt_cnt < 0)
			{
				//printk("[dmfe_tx_done] tx_pkt_cnt ERROR!!\n");
				netif.tx_pkt_cnt =0;
			}
			
			/* Queue packet check & send */
			if (netif.tx_pkt_cnt > 0) 
			{
				/* Set TX length to DM9000 */
				iow( DM9KS_TXPLL, (queue_pkt_len & 0xff));
				iow( DM9KS_TXPLH, (queue_pkt_len >> 8) & 0xff);
		
				/* Issue TX polling command */
				//iow( DM9KS_TCR, 0x1);    /* Cleared after TX complete */
				
				netif.tx_packets++;
				netif.tx_bytes+=queue_pkt_len;
			} 
				
	}

}

/*
  DM9000 insterrupt handler
  receive the packet to upper layer, free the transmitted packet
*/
void dmfe_interrupt(void)
{
	int int_status;
	u8 reg_save;

//	DEBUG_OUT("dmfe_interrupt() ---> ");

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

	/* Save previous register address */
	reg_save = inb(netif.io_addr);

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

	/* Got DM9000A/DM9010 interrupt status */
	int_status = ior(DM9KS_ISR, netif.io_addr);		/* Got ISR */
	iow( DM9KS_ISR, int_status);		/* Clear ISR status */ 

	/* Received the coming packet */
	if (int_status & DM9KS_RX_INTR) 
		dmfe_packet_receive();

	/* Trnasmit Interrupt check */
	if (int_status & DM9KS_TX_INTR)
		dmfe_tx_done(0);
	
	/* Link status change */
	if (int_status & DM9KS_LINK_INTR) 
	{
	
	}

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

	
	/* Restore previous register address */
	outb(reg_save, netif.io_addr); 

}





#if !defined(CHECKSUM)
#define check_rx_ready(a)	((a) == 0x01)
#else
inline u8 check_rx_ready(u8 rxbyte)
{
	if (!(rxbyte & 0x01))
		return 0;
	return ((rxbyte >> 4) | 0x01);
}
#endif

/*
  Received a packet and pass to upper layer
*/
void dmfe_packet_receive(void)
{
	int index;
	u8 rxbyte, temp;
	u16 i, GoodPacket, RxStatus, RxLen, tmplen, MDRAH, MDRAL;
	u32 tmpdata;

	u8* rdptr;

//	DEBUG_OUT("dmfe_packet_receive()\r\n\r\n");

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

		/* packet ready to receive check */
		if (rxbyte != 0x01)  break;

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

		RxStatus = (u16)0;
		RxLen    = (u16)0;
		
		/* Read packet status & length */
		switch (netif.io_mode) 
			{
			  case DM9KS_BYTE_MODE: 
 				    RxStatus = inb(netif.io_data) + 
				               (inb(netif.io_data) << 8);
				    RxLen = inb(netif.io_data) + 
					    (inb(netif.io_data) << 8);
				    break;
			  case DM9KS_WORD_MODE:
				    RxStatus = inw(netif.io_data);
				    RxLen    = inw(netif.io_data);
				    break;
			  case DM9KS_DWORD_MODE:
				    tmpdata  = inl(netif.io_data);
				    RxStatus = tmpdata;
				    RxLen = tmpdata >> 16;
				    break;
			  default:
				    break;
			}

		/* Packet status check */
		temp = (u8)(RxStatus>>8);
		if (temp & 0xbf)
		{
			GoodPacket = FALSE;
			if (temp & 0x01) 
			{
				netif.rx_fifo_errors++;
				//DEBUG_OUT("<RX FIFO error>\n");
			}
			if (temp & 0x02) 
			{
				netif.rx_crc_errors++;
				//DEBUG_OUT("<RX CRC error>\n");
			}
			if (temp & 0x80) 
			{
				netif.rx_length_errors++;
				//DEBUG_OUT("<RX Length error>\n");
			}
			if (temp & 0x08)
				;
				//DEBUG_OUT("<Physical Layer error>\n");
		}

		if (!GoodPacket)
		{
			// drop this packet!!!
			switch (netif.io_mode)
			{
				case DM9KS_BYTE_MODE:
			 		for (i=0; i<RxLen; i++)
						inb(netif.io_data);
					break;
				case DM9KS_WORD_MODE:
					tmplen = (RxLen + 1) / 2;
					for (i = 0; i < tmplen; i++)
						inw(netif.io_data);
					break;
				case DM9KS_DWORD_MODE:
					tmplen = (RxLen + 3) / 4;
					for (i = 0; i < tmplen; i++)
						inl(netif.io_data);
					break;
			}
			continue;/*next the packet*/
		}

		index = netbuf_alloc();
		
		if (index == -1 )
		{	
			//DEBUG_OUT("%s: Memory squeeze.\n", netif.name);
			/*re-load the value into Memory data read address register*/
			iow(DM9KS_MDRAH,MDRAH);
			iow(DM9KS_MDRAL,MDRAL);
			return;
		}
		else
		{
			/* Move data from DM9000 */
			//skb->dev = dev;
			//skb_reserve(skb, 2);
			rdptr = (u8*)&netbuf[index].data[0]         ;
			
			/* Read received packet from RX SARM */
			switch (netif.io_mode)
			{
				case DM9KS_BYTE_MODE:
			 		for (i=0; i<RxLen; i++)
						netbuf[index].data[i]=inb(netif.io_data);
					break;
				case DM9KS_WORD_MODE:
					tmplen = (RxLen + 1) / 2;
					for (i = 0; i < tmplen; i++){
						((u16 *)rdptr)[i] = inw(netif.io_data);
					}
					break;
				case DM9KS_DWORD_MODE:
					tmplen = (RxLen + 3) / 4;
					for (i = 0; i < tmplen; i++)
						((u32 *)rdptr)[i] = inl(netif.io_data);
					break;
			}
		
			/* Pass to upper layer 
			//skb->protocol = eth_type_trans(skb,dev);
#if defined(CHECKSUM)
			if (val == 0x01)
				skb->ip_summed = CHECKSUM_UNNECESSARY;
#endif
*/
			netbuf[index].flags = Recv;
			netbuf[index].eth_len = RxLen;
			
			
			netif.rx_packets++;
			netif.rx_bytes += RxLen;
		}
	
			
	}while((rxbyte & 0x01) == DM9KS_PKT_RDY);
	
}

/*
  Read a word data from SROM
*/
u16 read_srom_word(u8 offset)
{
	iow( DM9KS_EPAR, offset);
	iow( DM9KS_EPCR, 0x4);
	udelay(200);
	iow( DM9KS_EPCR, 0x0);
	return (ior( DM9KS_EPDRL, netif.io_addr) + (ior( DM9KS_EPDRH, netif.io_addr) << 8) );
}

/*
  Set DM9000A/DM9010 multicast address
*/
void dm9000_hash_table(void)
{
//	u32 hash_val;
	u16 i, oft, hash_table[4];

	DEBUG_OUT("dm9000_hash_table() --->");

	/* Set Node address */
	iow(0x10, netif.hw_addr[0]);
	iow(0x11, netif.hw_addr[1]);
	iow(0x12, netif.hw_addr[2]);
	iow(0x13, netif.hw_addr[3]);
	iow(0x14, netif.hw_addr[4]);
	iow(0x15, netif.hw_addr[5]);

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

	/* broadcast address */
	hash_table[3] = 0x8000;
#if 0
	/* 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);
	}
#endif
	/* Write the hash table to MAC MD table */
	for (i = 0, oft = 0x16; i < 4; i++) {
		iow( oft++, hash_table[i] & 0xff);
		iow( oft++, (hash_table[i] >> 8) & 0xff);
	}

DEBUG_OUT("\r\n0x%x 0x%x 0x%x 0x%x 0x%x 0x%x ",ior(0x10, netif.io_addr), 
	ior(0x11, netif.io_addr),ior(0x12, netif.io_addr), 
	ior(0x13, netif.io_addr),ior(0x14, netif.io_addr),ior(0x15, netif.io_addr));
	
}

#if 0
/*
  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)
*/
static unsigned long cal_CRC(unsigned char * Data, unsigned int Len, u8 flag)
{
	
	u32 crc = ether_crc_le(Len, Data);

	if (flag) 
		return ~crc;
		
	return crc;
	 
}
#endif

/*
   Read a byte from I/O port
*/
u8 ior(u8 reg, u32 addr)
{
	outb(reg, addr);
	return inb(netif.io_data);
}

/*
   Write a byte to I/O port
*/
void iow(u8 reg, u8 value)
{
	outb(reg, netif.io_addr);
	outb(value, netif.io_data);
}

/*
   Read a word from phyxcer
*/
u16 phy_read(u8 reg)
{
	/* Fill the phyxcer register into REG_0C */
	iow( DM9KS_EPAR, DM9KS_PHY | reg);

	iow( DM9KS_EPCR, 0xc); 	/* Issue phyxcer read command */
	udelay(100);			/* Wait read complete */
	iow( DM9KS_EPCR, 0x0); 	/* Clear phyxcer read command */

	/* The read data keeps on REG_0D & REG_0E */
	return ( ior( DM9KS_EPDRH, netif.io_addr) << 8 ) | ior( DM9KS_EPDRL, netif.io_addr);
	
}

/*
   Write a word to phyxcer
*/
void phy_write(u8 reg, u16 value)
{
	/* Fill the phyxcer register into REG_0C */
	iow( DM9KS_EPAR, DM9KS_PHY | reg);

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

	iow( DM9KS_EPCR, 0xa);	/* Issue phyxcer write command */
	udelay(500);			/* Wait write complete */
	iow( DM9KS_EPCR, 0x0);	/* Clear phyxcer write command */
}

⌨️ 快捷键说明

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