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

📄 dm9000x.c.maceeprom

📁 一个嵌入linux下s3c2410通过i2c读写eerom的驱动程序和应用程序。
💻 MACEEPROM
📖 第 1 页 / 共 4 页
字号:
 	/* Re-enable interrupt mask */ 	iow(db, 0xff, 0x83);	/* Restore previous register address */	outb(reg_save, db->ioaddr);	//dev->interrupt=0;  //mark by simon 2001.9.4            /* release interrupt lock */	spin_unlock(&db->lock); // add by simon 2001.9.4 for kernel 2.4}/*  Get statistics from driver.*/static struct net_device_stats * dmfe_get_stats(struct DEVICE *dev){	board_info_t *db = (board_info_t *)dev->priv;	DMFE_DBUG(0, "dmfe_get_stats", 0);	return &db->stats;}/*  Process the upper socket ioctl command*/static int dmfe_do_ioctl(struct DEVICE *dev, struct ifreq *ifr, int cmd){	DMFE_DBUG(0, "dmfe_do_ioctl()", 0);	return 0;}/*  A periodic timer routine  Dynamic media sense, allocated Rx buffer...*/static void dmfe_timer(unsigned long data){	struct DEVICE *dev = (struct DEVICE *)data;	board_info_t *db = (board_info_t *)dev->priv;	u8 reg_save, tmp_reg;	DMFE_DBUG(0, "dmfe_timer()", 0);	/* Save previous register address */	reg_save = inb(db->ioaddr);	/* TX timeout check */	if (dev->trans_start && ((jiffies - dev->trans_start) > DMFE_TX_TIMEOUT)) {		db->device_wait_reset = 1;		db->reset_tx_timeout++;	}	/* DM9000 dynamic RESET check and do */	if (db->device_wait_reset) {		//dev->tbusy = 1; //mark by simon 2001.9.4 for kernel 2.4		netif_stop_queue(dev); // add by simon 2001.9.4 for kernel 2.4		db->reset_counter++;		db->device_wait_reset = 0;		dev->trans_start = 0;		dmfe_init_dm9000(dev);		//mark below by simon 2001.9.4 for kernel 2.4		//dev->tbusy = 0;		/* Active upper layer, send again */		netif_wake_queue(dev); // add by simon 2001.9.4 for kernel 2.4		//mark_bh(NET_BH); //MARK BY SIMON 2001.9.4	}	/* Auto Sense Media mode policy:		FastEthernet NIC: don't need to do anything.		Media Force mode: don't need to do anything.		HomeRun/LongRun NIC and AUTO_Mode:			INT_MII not link, select EXT_MII			EXT_MII not link, select INT_MII	 */	if ( (db->nic_type != FASTETHER_NIC) && (db->op_mode & DM9000_AUTO) ) {		tmp_reg = ior(db, 0x01);	/* Got link status */		if ( !(tmp_reg & 0x40) ) { /* not link */			db->reg0 ^= 0x80;			iow(db, 0x00, db->reg0);		}	}	/* Restore previous register address */	outb(reg_save, db->ioaddr);	/* Set timer again */	db->timer.expires = DMFE_TIMER_WUT;	add_timer(&db->timer);}/*  Received a packet and pass to upper layer*/static void dmfe_packet_receive(struct DEVICE *dev, board_info_t *db){	struct sk_buff *skb;	u8 rxbyte;	u8 *rdptr;	u16 i, RxStatus, RxLen, GoodPacket, tmplen;	//u16 n; 	/* 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) {			iow(db, 0x05, 0x00);	/* Stop Device */			iow(db, 0xfe, 0x80);	/* Stop INT request */			db->device_wait_reset = 1; 			db->reset_rx_status++;		}		/* 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 */				outb(0xf2, db->ioaddr);				RxStatus = inw(db->io_data);				//RxStatus = (RxStatus>>8) | (RxStatus<<8); //note by HHTECH				RxLen = inw(db->io_data);				//RxLen = (RxLen>>8) | (RxLen<<8); //note by HHTECH#ifdef DM9000_DEBUG				printk("RxStatus %04x, RxLen %04x\n",RxStatus,RxLen);#endif			}			/* Packet Status check */			if (RxLen < 0x40) { 				GoodPacket = 0; 				db->runt_length_counter++; 			}			if (RxLen > DM9000_PKT_MAX) { 				printk("<DM9000> RST: RX Len:%x\n", RxLen);				db->device_wait_reset = 1; 				db->long_length_counter++; 			}			if (RxStatus & 0xbf00) {				GoodPacket = 0;				if (RxStatus & 0x100) db->stats.rx_fifo_errors++;				if (RxStatus & 0x200) db->stats.rx_crc_errors++;				if (RxStatus & 0x8000) db->stats.rx_length_errors++;			}			/* Move data from DM9000 */    if (!db->device_wait_reset) {	if ( GoodPacket && ((skb = dev_alloc_skb(RxLen + 4)) != NULL ) ) {	//HHTECH	/*skb=(struct sk_buff *)0x20014000;	if ( GoodPacket ) {*/	    skb->dev = dev;	    skb_reserve(skb, 2);	    rdptr = (u8 *) skb_put(skb, RxLen - 4);	/* Read received packet from RX SARM */	    if (db->io_mode == 2) {/* Byte mode */		for (i=0; i<RxLen; i++)			rdptr[i]=inb(db->io_data);		} else {		/* Word mode */		tmplen = (RxLen + 1) / 2;		for (i = 0; i < tmplen; i++)		    ((u16 *)rdptr)[i] = inw(db->io_data);/*   for(n=0;n<RxLen;n+=2){    if(n%10==0 && n)	printk("\n");      printk("%04x ",((u16 *)rdptr)[n]);   }printk("\n");*/					}	/* Pass to upper layer */	skb->protocol = eth_type_trans(skb,dev);	netif_rx(skb);	db->stats.rx_packets++; 	} else {					/* Without buffer or error packet */					if (db->io_mode == 2) {						/* Byte mode */						for (i = 0; i < RxLen; i++)							inb(db->io_data);					} else {						/* Word mode */						tmplen = (RxLen + 1) / 2;						for (i = 0; i < tmplen; i++)							inw(db->io_data);					}				}			}		}	}while( rxbyte  && !db->device_wait_reset);}/*  Read a word data from SROM*/static u16 read_srom_word(board_info_t *db, int offset){	iow(db, 0xc, offset);	iow(db, 0xb, 0x4);	udelay(200);	iow(db, 0xb, 0x0);	return (ior(db, 0xd) + (ior(db, 0xe) << 8) );}/*  Set DM9000 multicast address*/static void dm9000_hash_table(struct 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);	/* 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);	}}/*  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){	unsigned long Crc = 0xffffffff;	while (Len--) {		Crc = CrcTable[(Crc ^ *Data++) & 0xFF] ^ (Crc >> 8);	}	if (flag) return ~Crc;	else return Crc;}/*   Read a byte from I/O port*/static u8 ior(board_info_t *db, int reg){	outb(reg, db->ioaddr);	return inb(db->io_data);}/*   Write a byte to I/O port*/static void iow(board_info_t *db, int reg, u8 value){	outb(reg, db->ioaddr);	outb(value, db->io_data);}/*   Read a word from phyxcer*/static 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*/static 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 */}#ifdef MODULE    MODULE_AUTHOR("Sten Wang, sten_wang@davicom.com.tw");    MODULE_DESCRIPTION("Davicom DM9000 ISA/uP Fast Ethernet Driver");    MODULE_PARM(debug, "i");    MODULE_PARM(mode, "i");    MODULE_PARM(reg5, "i");    MODULE_PARM(reg9, "i");    MODULE_PARM(rega, "i");    MODULE_PARM(nfloor, "i");/* Description:    when user used insmod to add module, system invoked init_module()   to initilize and register.*/int init_module(void){	DMFE_DBUG(0, "init_module() ", debug);	if (debug) dmfe_debug = debug;   /* set debug flag */	switch(mode) {	case DM9000_10MHD:	case DM9000_100MHD:	case DM9000_10MFD:	case DM9000_100MFD:	case DM9000_1M_HPNA:		media_mode = mode;		break;	default:		media_mode = DM9000_AUTO;	}	nfloor = (nfloor > 15) ? 0:nfloor;	return dmfe_probe(0);              /* search board and register */}/* Description:    when user used rmmod to delete module, system invoked clean_module()   to  un-register DEVICE.*/void cleanup_module(void){	struct DEVICE *next_dev;	board_info_t * db;	DMFE_DBUG(0, "clean_module()", 0);	while (dmfe_root_dev) {		next_dev = ((board_info_t *)dmfe_root_dev->priv)->next_dev;		unregister_netdev(dmfe_root_dev);		db = (board_info_t *)dmfe_root_dev->priv;		release_region(dmfe_root_dev->base_addr, 2);		kfree(db);		/* free board information */		kfree(dmfe_root_dev);	/* free device structure */		dmfe_root_dev = next_dev;	}	DMFE_DBUG(0, "clean_module() exit", 0);}#endif  /* MODULE *//*****************************************************************************/unsigned char input_data[]={0x0,0x0,0x00,0x00,0x05,0x20,0x86,0x00,0x00,0x03,0x00,0x10,0x00,0x05,0x1E,0x01,0x01,0x01,0x61,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x01};

⌨️ 快捷键说明

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