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

📄 qq

📁 bootloader源代码
💻
📖 第 1 页 / 共 2 页
字号:
		if (irq_type & ETHIRQ_RX)		irq_clear |= (irq_stat | 0x01);	if (irq_type & ETHIRQ_TX)		irq_clear |= (irq_stat | 0x02);	iow(db, 0xfe, irq_clear);	if (quasar_irq_pending(0) && ((irq_stat & ~irq_clear) == 0))		quasar_clear_irq(0);	return 0;}int dmfe_send_packet(struct sk_buff *skb, struct net_device *dev){	board_info_t *db = (board_info_t *) dev->priv;	unsigned char *data_ptr;	int i, tmplen;	/* Disable all interrupt */	iow(db, 0xff, 0x80);	/* Move data to DM9000 TX RAM */	data_ptr = (char *)skb->data;	dmfe_outb(0xf8, db->ioaddr);	if (db->io_mode == 2) {		/* Byte mode */		for (i = 0; i < skb->len; i++)			dmfe_outb((data_ptr[i] & 0xff), db->io_data);	} else {		/* Word mode */		tmplen = (skb->len + 1) / 2;		dmfe_outsw((u16 *) data_ptr, tmplen, db->io_data);	}	/* 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 */	/* Re-enable interrupt mask */ 	iow(db, 0xff, 0x83);	/* wait for completion */	while ((dmfe_irq_pending(dev) | ETHIRQ_TX) == 0)		;	dmfe_irq_clear(ETHIRQ_TX, dev);	return 0;}int dmfe_receive_packet(struct net_device *dev){	board_info_t *db = (board_info_t *) dev->priv;	struct sk_buff *skb;	u8 rxbyte;	u8 *rdptr;	u16 i, RxStatus, RxLen, GoodPacket, tmplen;	int npacket = 0;#if DM9000_RXDMA	int reloc, last_lo = 0, last_hi = 0;#endif	// while ((dmfe_irq_pending(dev) | ETHIRQ_RX) == 0)	// 	;	dmfe_irq_clear(ETHIRQ_RX, dev);	/* Check packet ready or not */	do {		rxbyte = ior(db, 0xf0);	/* Dummy read */		rxbyte = ior(db, 0xf0);	/* Got most updated data */		/* Status check: this byte must be 0 or 1 */		if (rxbyte > DM9000_PKT_RDY) {			PrintUart("<DM9000> STOP\r\n", -1);			iow(db, 0x05, 0x00);	/* Stop Device */			iow(db, 0xfe, 0x80);	/* Stop INT request */			db->device_wait_reset = 1; 		}		/* packet ready to receive check */		if (rxbyte == DM9000_PKT_RDY) {			/* A packet ready now  & Get status/length */			GoodPacket = 1;			if (db->io_mode == 2) {				/* Byte mode */				RxStatus = ior(db, 0xf2) + (ior(db, 0xf2) << 8);				RxLen = ior(db, 0xf2) + (ior(db, 0xf2) << 8);			} else {				/* Word mode */				dmfe_outb(0xf2, db->ioaddr);				RxStatus = dmfe_inw(db->io_data);				RxLen = dmfe_inw(db->io_data);			}			/* Packet Status check */			if (RxLen < 0x40) { 				GoodPacket = 0; 			}			if (RxLen > DM9000_PKT_MAX) { 				PrintUart("<DM9000> RST : Overflow\r\n", -1);				db->device_wait_reset = 1; 			}			if (RxStatus & 0xbf00) 				GoodPacket = 0;			/* Move data from DM9000 */			if (!db->device_wait_reset) {				if ((skb = skb_alloc(RxLen + 8)) == NULL) 					PrintUart("<DM9000> SKB allocation fail.\r\n", -1);				if (GoodPacket && skb) {					skb->len = RxLen;					rdptr = (u8 *) skb->data;					/* Read received packet from RX SARM */					if (db->io_mode == 2) {						/* Byte mode */						for (i = 0; i < RxLen; i++)							rdptr[i] = dmfe_inb(db->io_data);					} else {						/* Word mode */						tmplen = (RxLen + 1) / 2;#if DM9000_RXDMA						if ((tmplen & 0x03) != 0) {							reloc = 1;							last_lo = ior(db, 0xf4);							last_hi = ior(db, 0xf5);							dmfe_outb(0xf2, db->ioaddr);						} else							reloc = 0;						dmfe_start_rxdma((u16 *) rdptr, tmplen, db->io_data);						dmfe_cleanup_rxdma();						if (reloc) {	// DMA transfers by 8 bytes. so it needs validating RXMEM ptr							last_lo += (tmplen << 1);							while (last_lo >= 0x100) {								if (++last_hi == 0x40)									last_hi = 0x0c;								last_lo -= 0x100;							}							iow(db, 0xf4, last_lo);							iow(db, 0xf5, last_hi);						}#else						dmfe_insw((u16 *) rdptr, tmplen, db->io_data);#endif					}					/* Pass to upper layer */					skb_put(skb);					++npacket;				} else {					PrintUart("<DM9000> : Bad Packet\r\n", -1);					/* Without buffer or error packet */					if (db->io_mode == 2) {						/* Byte mode */						for (i = 0; i < RxLen; i++)							dmfe_inb(db->io_data);					} else {						/* Word mode */						tmplen = (RxLen + 1) / 2;						for (i = 0; i < tmplen; i++)							dmfe_inw(db->io_data);					}				}			}		}	} while (rxbyte && !db->device_wait_reset);	return npacket;}void dmfe_print_status(struct net_device *dev){	static struct {		int addr;		int len; 	} s_reg_list[] = {		{ 0x00, 1 },		{ 0x01, 1 },		{ 0x02, 1 },		{ 0x03, 1 },		{ 0x04, 1 },		{ 0x05, 1 },		{ 0x06, 1 },		{ 0x07, 1 },		{ 0x08, 1 },		{ 0x09, 1 },		{ 0x0a, 1 },		{ 0x0b, 1 },		{ 0x0c, 1 },		{ 0x0d, 2 },		{ 0x0f, 1 },		{ 0x10, 6 },		{ 0x16, 8 },		{ 0x1e, 1 },		{ 0x1f, 1 },		{ 0x22, 2 },		{ 0x24, 2 },		{ 0x28, 2 },		{ 0x2a, 2 },		{ 0x2c, 1 },		{ 0x2f, 1 },		{ 0xf4, 2 },		{ 0xfa, 2 },		{ 0xfc, 2 },		{ 0xfe, 1 },		{ 0xff, 1 },		{ -1, 0 },	};		board_info_t *db = (board_info_t *) dev->priv;	int i, j;		for (i = 0; s_reg_list[i].addr >= 0; ++i) {		PrintFormat("%02X : ", s_reg_list[i].addr);		for (j = 0; j < s_reg_list[i].len; ++j)			PrintFormat("%02X ", ior(db, s_reg_list[i].addr + j));		PrintFormat("\n");	}}//// Miscellaneous///* Identify NIC type*/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);	}static int g_nfloor = 0;void program_dm9801(board_info_t *db, u16 HPNA_rev){	u16 reg16, reg17, reg24, reg25;	if (!g_nfloor) 		g_nfloor = DM9801_NOISE_FLOOR;	reg16 = phy_read(db, 16);	reg17 = phy_read(db, 17);	reg24 = phy_read(db, 24);	reg25 = phy_read(db, 25);	switch (HPNA_rev) {	case 0xb900: /* DM9801 E3 */		reg16 |= 0x1000;		reg25 = ((reg24 + g_nfloor) & 0x00ff) | 0xf000;		break;	case 0xb901: /* DM9801 E4 */		reg25 = ((reg24 + g_nfloor) & 0x00ff) | 0xc200;		reg17 = (reg17 & 0xfff0) + g_nfloor + 3;		break;	case 0xb902: /* DM9801 E5 */	case 0xb903: /* DM9801 E6 */	default:		reg16 |= 0x1000;		reg25 = ((reg24 + g_nfloor - 3) & 0x00ff) | 0xc200;		reg17 = (reg17 & 0xfff0) + g_nfloor;		break;	}	phy_write(db, 16, reg16);	phy_write(db, 17, reg17);	phy_write(db, 25, reg25);}/*	Init LongRun DM9802*/void program_dm9802(board_info_t *db){	u16 reg25;	if (!g_nfloor) 		g_nfloor = DM9802_NOISE_FLOOR;	reg25 = phy_read(db, 25);	reg25 = (reg25 & 0xff00) + g_nfloor;	phy_write(db, 25, reg25);}/* Set PHY operationg mode*/void set_PHY_mode(board_info_t *db){	u16 phy_reg4 = 0x01e1, phy_reg0=0x1000;	if (!(db->op_mode & DM9000_AUTO)) {		switch (db->op_mode) {		case DM9000_10MHD: 			phy_reg4 = 0x21;             phy_reg0 = 0x0000; 			break;		case DM9000_10MFD: 			phy_reg4 = 0x41;             phy_reg0 = 0x1100;             break;		case DM9000_100MHD: 			phy_reg4 = 0x81; 			phy_reg0 = 0x2000; 			break;		case DM9000_100MFD: 			phy_reg4 = 0x101; 			phy_reg0 =0x3100;             break;		}		phy_write(db, 4, phy_reg4);	/* Set PHY media mode */		phy_write(db, 0, phy_reg0);	/*  Tmp */	}	iow(db, 0x1e, 0x01);		/* Let GPIO0 output */	iow(db, 0x1f, 0x00);		/* Enable PHY */}/*   Read a word from phyxcer*/u16 phy_read(board_info_t *db, int reg){	/* Fill the phyxcer register into REG_0C */	iow(db, 0xc, DM9000_PHY | reg);	iow(db, 0xb, 0xc); /* Issue phyxcer read command */	udelay(100);	/* Wait read complete */	iow(db, 0xb, 0x0); /* Clear phyxcer read command */	/* The read data keeps on REG_0D & REG_0E */	return (ior(db, 0xe) << 8) | ior(db, 0xd);}/*   Write a word to phyxcer*/void phy_write(board_info_t *db, int reg, u16 value){	/* Fill the phyxcer register into REG_0C */	iow(db, 0xc, DM9000_PHY | reg);	/* Fill the written data into REG_0D & REG_0E */	iow(db, 0xd, (value & 0xff));	iow(db, 0xe, ((value >> 8) & 0xff));	iow(db, 0xb, 0xa);		/* Issue phyxcer write command */	udelay(500);		/* Wait write complete */	iow(db, 0xb, 0x0);		/* Clear phyxcer write command */}/* * EEPROM interface * * chipset : HOLTEK HT93LC46 * size : 1K bit = 128 bytes = 64 words * * DM9000 registers *   0xb : EEPROM control register *   0xc : EEPROM address register *   0xd : EEPROM data register low byte *   0xe : EEPROM data register high byte */// reg : index of register // now it workks as 64 words * 16 bits// so the reg is between [0..63]unsigned short dmfe_eeprom_readw(struct net_device *dev, int reg){	board_info_t *db = (board_info_t *) dev->priv;	iow(db, 0xc, reg);	// Address	iow(db, 0xb, 0x4);	// READ Register	udelay(200);		// delay	iow(db, 0xb, 0x0);	// end READ command	return (unsigned short) (ior(db, 0xd) + (ior(db, 0xe) << 8));}void dmfe_eeprom_writew(struct net_device *dev, int reg, int data){	board_info_t *db = (board_info_t *) dev->priv;	iow(db, 0xc, reg);	// Address	iow(db, 0xd, (data & 0xff));		// Data Low	iow(db, 0xe, (data >> 8) & 0xff);	// Data High	iow(db, 0xb, 0x12);	// WRITE Register with Write EEPROM Enable	udelay(200);		// delay	iow(db, 0xb, 0x0);	// end WRITE command}#endif	// SUPPORT_NET

⌨️ 快捷键说明

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