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

📄 dm9000x.c

📁 uboot详细解读可用启动引导LINUX2.6内核
💻 C
📖 第 1 页 / 共 2 页
字号:
	do {		DM9000_DBG("resetting the DM9000, 1st reset\n");		udelay(25); /* Wait at least 20 us */	} while (DM9000_ior(DM9000_NCR) & 1);	DM9000_iow(DM9000_NCR, 0);	DM9000_iow(DM9000_NCR, 3); /* Issue a second reset */	do {		DM9000_DBG("resetting the DM9000, 2nd reset\n");		udelay(25); /* Wait at least 20 us */	} while (DM9000_ior(DM9000_NCR) & 1);	/* Check whether the ethernet controller is present */	if ((DM9000_ior(DM9000_PIDL) != 0x0) ||	    (DM9000_ior(DM9000_PIDH) != 0x90))		printf("ERROR: resetting DM9000 -> not responding\n");}/* Initilize dm9000 board*/inteth_init(bd_t * bd){	int i, oft, lnk;	u8 io_mode;	struct board_info *db = &dm9000_info;	DM9000_DBG("eth_init()\n");	/* RESET device */	dm9000_reset();	dm9000_probe();	/* Auto-detect 8/16/32 bit mode, ISR Bit 6+7 indicate bus width */	io_mode = DM9000_ior(DM9000_ISR) >> 6;	switch (io_mode) {	case 0x0:  /* 16-bit mode */		printf("DM9000: running in 16 bit mode\n");		db->outblk    = dm9000_outblk_16bit;		db->inblk     = dm9000_inblk_16bit;		db->rx_status = dm9000_rx_status_16bit;		break;	case 0x01:  /* 32-bit mode */		printf("DM9000: running in 32 bit mode\n");		db->outblk    = dm9000_outblk_32bit;		db->inblk     = dm9000_inblk_32bit;		db->rx_status = dm9000_rx_status_32bit;		break;	case 0x02: /* 8 bit mode */		printf("DM9000: running in 8 bit mode\n");		db->outblk    = dm9000_outblk_8bit;		db->inblk     = dm9000_inblk_8bit;		db->rx_status = dm9000_rx_status_8bit;		break;	default:		/* Assume 8 bit mode, will probably not work anyway */		printf("DM9000: Undefined IO-mode:0x%x\n", io_mode);		db->outblk    = dm9000_outblk_8bit;		db->inblk     = dm9000_inblk_8bit;		db->rx_status = dm9000_rx_status_8bit;		break;	}	/* NIC Type: FASTETHER, HOMERUN, LONGRUN */	identify_nic();	/* GPIO0 on pre-activate PHY */	DM9000_iow(DM9000_GPR, 0x00);	/*REG_1F bit0 activate phyxcer */	/* Set PHY */	set_PHY_mode();	/* Program operating register, only intern phy supported by now */	DM9000_iow(DM9000_NCR, 0x0);	/* TX Polling clear */	DM9000_iow(DM9000_TCR, 0);	/* Less 3Kb, 200us */	DM9000_iow(DM9000_BPTR, 0x3f);	/* Flow Control : High/Low Water */	DM9000_iow(DM9000_FCTR, FCTR_HWOT(3) | FCTR_LWOT(8));	/* SH FIXME: This looks strange! Flow Control */	DM9000_iow(DM9000_FCR, 0x0);	/* Special Mode */	DM9000_iow(DM9000_SMCR, 0);	/* clear TX status */	DM9000_iow(DM9000_NSR, NSR_WAKEST | NSR_TX2END | NSR_TX1END);	/* Clear interrupt status */	DM9000_iow(DM9000_ISR, 0x0f);	/* Set Node address */#ifndef CONFIG_AT91SAM9261EK	for (i = 0; i < 6; i++)		((u16 *) bd->bi_enetaddr)[i] = read_srom_word(i);#endif	if (is_zero_ether_addr(bd->bi_enetaddr) ||	    is_multicast_ether_addr(bd->bi_enetaddr)) {		/* try reading from environment */		u8 i;		char *s, *e;		s = getenv ("ethaddr");		for (i = 0; i < 6; ++i) {			bd->bi_enetaddr[i] = s ?				simple_strtoul (s, &e, 16) : 0;			if (s)				s = (*e) ? e + 1 : e;		}	}	printf("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", bd->bi_enetaddr[0],	       bd->bi_enetaddr[1], bd->bi_enetaddr[2], bd->bi_enetaddr[3],	       bd->bi_enetaddr[4], bd->bi_enetaddr[5]);	for (i = 0, oft = 0x10; i < 6; i++, oft++)		DM9000_iow(oft, bd->bi_enetaddr[i]);	for (i = 0, oft = 0x16; i < 8; i++, oft++)		DM9000_iow(oft, 0xff);	/* read back mac, just to be sure */	for (i = 0, oft = 0x10; i < 6; i++, oft++)		DM9000_DBG("%02x:", DM9000_ior(oft));	DM9000_DBG("\n");	/* Activate DM9000 */	/* RX enable */	DM9000_iow(DM9000_RCR, RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN);	/* Enable TX/RX interrupt mask */	DM9000_iow(DM9000_IMR, IMR_PAR);	i = 0;	while (!(phy_read(1) & 0x20)) {	/* autonegation complete bit */		udelay(1000);		i++;		if (i == 10000) {			printf("could not establish link\n");			return 0;		}	}	/* see what we've got */	lnk = phy_read(17) >> 12;	printf("operating at ");	switch (lnk) {	case 1:		printf("10M half duplex ");		break;	case 2:		printf("10M full duplex ");		break;	case 4:		printf("100M half duplex ");		break;	case 8:		printf("100M full duplex ");		break;	default:		printf("unknown: %d ", lnk);		break;	}	printf("mode\n");	return 0;}/*  Hardware start transmission.  Send a packet to media from the upper layer.*/inteth_send(volatile void *packet, int length){	int tmo;	struct board_info *db = &dm9000_info;	DM9000_DMP_PACKET("eth_send", packet, length);	DM9000_iow(DM9000_ISR, IMR_PTM); /* Clear Tx bit in ISR */	/* Move data to DM9000 TX RAM */	DM9000_outb(DM9000_MWCMD, DM9000_IO); /* Prepare for TX-data */	/* push the data to the TX-fifo */	(db->outblk)(packet, length);	/* Set TX length to DM9000 */	DM9000_iow(DM9000_TXPLL, length & 0xff);	DM9000_iow(DM9000_TXPLH, (length >> 8) & 0xff);	/* Issue TX polling command */	DM9000_iow(DM9000_TCR, TCR_TXREQ); /* Cleared after TX complete */	/* wait for end of transmission */	tmo = get_timer(0) + 5 * CFG_HZ;	while ( !(DM9000_ior(DM9000_NSR) & (NSR_TX1END | NSR_TX2END)) ||		!(DM9000_ior(DM9000_ISR) & IMR_PTM) ) {		if (get_timer(0) >= tmo) {			printf("transmission timeout\n");			break;		}	}	DM9000_iow(DM9000_ISR, IMR_PTM); /* Clear Tx bit in ISR */	DM9000_DBG("transmit done\n\n");	return 0;}/*  Stop the interface.  The interface is stopped when it is brought.*/voideth_halt(void){	DM9000_DBG("eth_halt\n");	/* RESET devie */	phy_write(0, 0x8000);	/* PHY RESET */	DM9000_iow(DM9000_GPR, 0x01);	/* Power-Down PHY */	DM9000_iow(DM9000_IMR, 0x80);	/* Disable all interrupt */	DM9000_iow(DM9000_RCR, 0x00);	/* Disable RX */}/*  Received a packet and pass to upper layer*/inteth_rx(void){	u8 rxbyte, *rdptr = (u8 *) NetRxPackets[0];	u16 RxStatus, RxLen = 0;	struct board_info *db = &dm9000_info;	/* Check packet ready or not, we must check	   the ISR status first for DM9000A */	if (!(DM9000_ior(DM9000_ISR) & 0x01)) /* Rx-ISR bit must be set. */		return 0;	DM9000_iow(DM9000_ISR, 0x01); /* clear PR status latched in bit 0 */	/* There is _at least_ 1 package in the fifo, read them all */	for (;;) {		DM9000_ior(DM9000_MRCMDX);	/* Dummy read */		/* Get most updated data,		   only look at bits 0:1, See application notes DM9000 */		rxbyte = DM9000_inb(DM9000_DATA) & 0x03;		/* Status check: this byte must be 0 or 1 */		if (rxbyte > DM9000_PKT_RDY) {			DM9000_iow(DM9000_RCR, 0x00);	/* Stop Device */			DM9000_iow(DM9000_ISR, 0x80);	/* Stop INT request */			printf("DM9000 error: status check fail: 0x%x\n",				rxbyte);			return 0;		}		if (rxbyte != DM9000_PKT_RDY)			return 0; /* No packet received, ignore */		DM9000_DBG("receiving packet\n");		/* A packet ready now  & Get status/length */		(db->rx_status)(&RxStatus, &RxLen);		DM9000_DBG("rx status: 0x%04x rx len: %d\n", RxStatus, RxLen);		/* Move data from DM9000 */		/* Read received packet from RX SRAM */		(db->inblk)(rdptr, RxLen);		if ((RxStatus & 0xbf00) || (RxLen < 0x40)			|| (RxLen > DM9000_PKT_MAX)) {			if (RxStatus & 0x100) {				printf("rx fifo error\n");			}			if (RxStatus & 0x200) {				printf("rx crc error\n");			}			if (RxStatus & 0x8000) {				printf("rx length error\n");			}			if (RxLen > DM9000_PKT_MAX) {				printf("rx length too big\n");				dm9000_reset();			}		} else {			DM9000_DMP_PACKET("eth_rx", rdptr, RxLen);			DM9000_DBG("passing packet to upper layer\n");			NetReceive(NetRxPackets[0], RxLen);		}	}	return 0;}/*  Read a word data from SROM*/u16read_srom_word(int offset){	DM9000_iow(DM9000_EPAR, offset);	DM9000_iow(DM9000_EPCR, 0x4);	udelay(8000);	DM9000_iow(DM9000_EPCR, 0x0);	return (DM9000_ior(DM9000_EPDRL) + (DM9000_ior(DM9000_EPDRH) << 8));}voidwrite_srom_word(int offset, u16 val){	DM9000_iow(DM9000_EPAR, offset);	DM9000_iow(DM9000_EPDRH, ((val >> 8) & 0xff));	DM9000_iow(DM9000_EPDRL, (val & 0xff));	DM9000_iow(DM9000_EPCR, 0x12);	udelay(8000);	DM9000_iow(DM9000_EPCR, 0);}/*   Read a byte from I/O port*/static u8DM9000_ior(int reg){	DM9000_outb(reg, DM9000_IO);	return DM9000_inb(DM9000_DATA);}/*   Write a byte to I/O port*/static voidDM9000_iow(int reg, u8 value){	DM9000_outb(reg, DM9000_IO);	DM9000_outb(value, DM9000_DATA);}/*   Read a word from phyxcer*/static u16phy_read(int reg){	u16 val;	/* Fill the phyxcer register into REG_0C */	DM9000_iow(DM9000_EPAR, DM9000_PHY | reg);	DM9000_iow(DM9000_EPCR, 0xc);	/* Issue phyxcer read command */	udelay(100);			/* Wait read complete */	DM9000_iow(DM9000_EPCR, 0x0);	/* Clear phyxcer read command */	val = (DM9000_ior(DM9000_EPDRH) << 8) | DM9000_ior(DM9000_EPDRL);	/* The read data keeps on REG_0D & REG_0E */	DM9000_DBG("phy_read(0x%x): 0x%x\n", reg, val);	return val;}/*   Write a word to phyxcer*/static voidphy_write(int reg, u16 value){	/* Fill the phyxcer register into REG_0C */	DM9000_iow(DM9000_EPAR, DM9000_PHY | reg);	/* Fill the written data into REG_0D & REG_0E */	DM9000_iow(DM9000_EPDRL, (value & 0xff));	DM9000_iow(DM9000_EPDRH, ((value >> 8) & 0xff));	DM9000_iow(DM9000_EPCR, 0xa);	/* Issue phyxcer write command */	udelay(500);			/* Wait write complete */	DM9000_iow(DM9000_EPCR, 0x0);	/* Clear phyxcer write command */	DM9000_DBG("phy_write(reg:0x%x, value:0x%x)\n", reg, value);}

⌨️ 快捷键说明

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