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

📄 dm9000.c

📁 dm9000aep linux2.6驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
	if (db->addr_res != NULL) {		release_resource(db->addr_res);		kfree(db->addr_req);	}}#define res_size(_r) (((_r)->end - (_r)->start) + 1)static unsigned char macaddr[] = {0x00,0x0e,0x3a,0xaa,0xbb,0xcc};/* * Search DM9000 board, allocate space and register it */static intdm9000_probe(struct device *dev){	struct platform_device *pdev = to_platform_device(dev);	struct dm9000_plat_data *pdata = pdev->dev.platform_data;	struct board_info *db;	/* Point a board information structure */	struct net_device *ndev;	unsigned long base;	int ret = 0;	int iosize;	int i;	u32 id_val;      // dm9000_cpu_init();	/* Init network device */	ndev = alloc_etherdev(sizeof (struct board_info));	if (!ndev) {		printk("%s: could not allocate device.\n", CARDNAME);		return -ENOMEM;	}	SET_MODULE_OWNER(ndev);	SET_NETDEV_DEV(ndev, dev);	PRINTK2("dm9000_probe()\n");	/* setup board info structure */	db = (struct board_info *) ndev->priv;	memset(db, 0, sizeof (*db));	spin_lock_init(&db->lock);	if (pdev->num_resources < 2) {		ret = -ENODEV;		goto out;	}	switch (pdev->num_resources) {	case 2:		base = pdev->resource[0].start;		if (!request_mem_region(base, 4, ndev->name)) {			ret = -EBUSY;			goto out;		}		ndev->base_addr = base;		ndev->irq = pdev->resource[1].start;		db->io_addr = (void *)base;		db->io_data = (void *)(base + 4);		break;	case 3:  //this		db->addr_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);		db->data_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);		db->irq_res  = platform_get_resource(pdev, IORESOURCE_IRQ, 0);		if (db->addr_res == NULL || db->data_res == NULL) {			printk(KERN_ERR PFX "insufficient resources\n");			ret = -ENOENT;			goto out;		}		i = res_size(db->addr_res);		db->addr_req = request_mem_region(db->addr_res->start, i,						  pdev->name);		if (db->addr_req == NULL) {			printk(KERN_ERR PFX "cannot claim address reg area\n");			ret = -EIO;			goto out;		}		db->io_addr = ioremap(db->addr_res->start, i);/*io_addr 的虚拟地址add by yf 20080623*/		if (db->io_addr == NULL) {			printk(KERN_ERR "failed to ioremap address reg\n");			ret = -EINVAL;			goto out;		}		iosize = res_size(db->data_res);		db->data_req = request_mem_region(db->data_res->start, iosize,						  pdev->name);		if (db->data_req == NULL) {			printk(KERN_ERR PFX "cannot claim data reg area\n");			ret = -EIO;			goto out;		}		db->io_data = ioremap(db->data_res->start, iosize);/*io_data 的虚拟地址 add by yf 20080623*/		if (db->io_data == NULL) {			printk(KERN_ERR "failed to ioremap data reg\n");			ret = -EINVAL;			goto out;		}		/* fill in parameters for net-dev structure */		ndev->base_addr = (unsigned long)db->io_addr;		ndev->irq	= db->irq_res->start;		/* ensure at least we have a default set of IO routines */		dm9000_set_io(db, iosize);	}	/* check to see if anything is being over-ridden */	if (pdata != NULL) {		/* check to see if the driver wants to over-ride the		 * default IO width */		if (pdata->flags & DM9000_PLATF_8BITONLY)			dm9000_set_io(db, 1);		if (pdata->flags & DM9000_PLATF_16BITONLY)			dm9000_set_io(db, 2);		if (pdata->flags & DM9000_PLATF_32BITONLY)			dm9000_set_io(db, 4);		/* check to see if there are any IO routine		 * over-rides */		if (pdata->inblk != NULL)			db->inblk = pdata->inblk;		if (pdata->outblk != NULL)			db->outblk = pdata->outblk;		if (pdata->dumpblk != NULL)			db->dumpblk = pdata->dumpblk;	}	dm9000_reset(db);	/* try two times, DM9000 sometimes gets the first read wrong */	for (i = 0; i < 2; i++) {		id_val  = ior(db, DM9000_VIDL);		id_val |= (u32)ior(db, DM9000_VIDH) << 8;		id_val |= (u32)ior(db, DM9000_PIDL) << 16;		id_val |= (u32)ior(db, DM9000_PIDH) << 24;		if (id_val == DM9000_ID)                      {           printk("found DM9000 ID:0x%x\n", id_val);			  break;                      }		printk("%s: read wrong id 0x%08x\n", CARDNAME, id_val);	}	if (id_val != DM9000_ID) {		printk("%s: wrong id: 0x%08x\n", CARDNAME, id_val);		goto release;	}	/* from this point we assume that we have found a DM9000 */	/* driver system function */	ether_setup(ndev);	ndev->open		 = &dm9000_open;	ndev->hard_start_xmit    = &dm9000_start_xmit;	ndev->tx_timeout         = &dm9000_timeout;	ndev->watchdog_timeo = msecs_to_jiffies(watchdog);	ndev->stop		 = &dm9000_stop;	ndev->get_stats		 = &dm9000_get_stats;	ndev->set_multicast_list = &dm9000_hash_table;#ifdef DM9000_PROGRAM_EEPROM	program_eeprom(db);#endif	db->msg_enable       = NETIF_MSG_LINK;	db->mii.phy_id_mask  = 0x1f;	db->mii.reg_num_mask = 0x1f;	db->mii.force_media  = 0;	db->mii.full_duplex  = 0;	db->mii.dev	     = ndev;	db->mii.mdio_read    = dm9000_phy_read;	db->mii.mdio_write   = dm9000_phy_write;	/* Read SROM content */	//for (i = 0; i < 64; i++)	//	((u16 *) db->srom)[i] = read_srom_word(db, i);	/* Set Node Address */	for (i = 0; i < 6; i++)		ndev->dev_addr[i] = macaddr[i];//ndev->dev_addr[i] = db->srom[i];	if (!is_valid_ether_addr(ndev->dev_addr))		printk("%s: Invalid ethernet MAC address.  Please "		       "set using ifconfig\n", ndev->name);	dev_set_drvdata(dev, ndev);	ret = register_netdev(ndev);	if (ret == 0) {		printk("%s: dm9000 at %p,%p IRQ %d MAC: ",		       ndev->name,  db->io_addr, db->io_data, ndev->irq);		for (i = 0; i < 5; i++)			printk("%02x:", ndev->dev_addr[i]);		printk("%02x\n", ndev->dev_addr[5]);	}	return 0; release: out:	printk("%s: not found (%d).\n", CARDNAME, ret);	dm9000_release_board(pdev, db);	kfree(ndev);	return ret;}#include <asm-arm/arch-s3c2410/regs-gpio.h>/* *  Open the interface. *  The interface is opened whenever "ifconfig" actives it. */static intdm9000_open(struct net_device *dev){	board_info_t *db = (board_info_t *) dev->priv;			PRINTK2("entering dm9000_open\n");	set_irq_type(dev->irq, IRQT_HIGH);	if (request_irq(dev->irq, &dm9000_interrupt, SA_SHIRQ, dev->name, dev))		return -EAGAIN;		/* Initialize DM9000 board */	dm9000_reset(db);	dm9000_init_dm9000(dev);	/* Init driver variable */	db->dbug_cnt = 0;	/* set and active a timer process */	init_timer(&db->timer);	db->timer.expires  = DM9000_TIMER_WUT;	db->timer.data     = (unsigned long) dev;	db->timer.function = &dm9000_timer;	add_timer(&db->timer);	mii_check_media(&db->mii, netif_msg_link(db), 1);	netif_start_queue(dev);	return 0;}/* * Initilize dm9000 board */static voiddm9000_init_dm9000(struct net_device *dev){	board_info_t *db = (board_info_t *) dev->priv;//       int i;	static  int speed, link,  duplex;	PRINTK1("entering %s\n",__FUNCTION__);	/* GPIO0 on pre-activate PHY */	//iow(db, DM9000_GPCR, GPCR_GEP_CNTL);	/* Let GPIO0 output */	iow(db, DM9000_GPR, 1);	/* Enable PHY */	udelay(500);	iow(db, DM9000_GPR, 0);	/* Enable PHY */       udelay(20);				/* software-RESET NIC */ 	iow(db, DM9000_NCR, 0x03);  //add by yf 20080704	udelay(20);     	iow(db, DM9000_NCR, 0x03);  //add by yf 20080704      udelay(20);	/* I/O mode */	db->io_mode = ior(db, DM9000_ISR) >> 6;	/* ISR bit7:6 keeps I/O mode */	PRINTK1 ("io_mode: 0x%x\n", db->io_mode  );      	/* Set PHY */	db->op_mode = media_mode;//add by yf 20080704	set_PHY_mode(dev);//add by yf 20080704		udelay(10);	  	      iow(db, DM9000_NCR, 0);  //add by yf 20080704  	iow(db, DM9000_TCR, 0);	        /* TX Polling clear */		iow(db, DM9000_BPTR, 0x3f);	/* Less 3Kb, 200us */	iow(db, DM9000_SMCR, 0x00);    /* Special Mode */	iow(db, DM9000_NSR , 0x2c);   /* Clear TX status */	iow(db, DM9000_ISR, 0x0f);     /* Clear interrupt status */	iow(db,DM9000_TCR2 , 0x80); 	/* LED mode setting */	//iow(db,DM9000_BUSCR, 0x61); //8mA	/* Added by jackal at 03/29/2004 */#if defined(CHECKSUM)	iow(db, DM9000_TCCR, 0x07);			/* TX UDP/TCP/IP checksum enable */	iow(db, DM9000_RCSR, 0x02);			/*Receive checksum enable */#endif#if defined(ETRANS)	iow(db, DM9000_ETXCSR, 0x83);#endif		/* Set address filter table */	dm9000_hash_table(dev);				/* Program operating register */     	iow(db, DM9000_NCR, 0x0);  /* enable chip functions and disable loopback back to normal*/     		/* clear TX status */	iow(db, DM9000_NSR, NSR_WAKEST | NSR_TX2END | NSR_TX1END);	iow(db, DM9000_ISR, ISR_CLR_STATUS); /* Clear interrupt status */	/* Enable TX/RX interrupt mask */	iow(db, DM9000_IMR,  DM9000_IMR_SET);//IMR_PAR | IMR_PTM | IMR_PRM|(1<<5));	/* Activate DM9000 */	iow(db, DM9000_RCR, DM9000_RCR_SET | 0x01);//RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN);			/* Init Driver variable */	db->tx_pkt_cnt = 0;	db->queue_pkt_len = 0;	dev->trans_start = 0;		link = (ior(db , 0x01)&0x40) ? TRUE : FALSE ;	speed = ( ior(db , 0x01)&0x80) ? 10 : 100;	duplex = ( ior (db, 0x00 ) & 8 ) ? FULL: HALF; 	PRINTK1("link : %d , speed:%d, duplex:%d\n", link, speed, duplex);	spin_lock_init(&db->lock);}/* *  Hardware start transmission. *  Send a packet to media from the upper layer. */static intdm9000_start_xmit(struct sk_buff *skb, struct net_device *dev){	board_info_t *db = (board_info_t *) dev->priv;	PRINTK3("dm9000_start_xmit\n");	if (db->tx_pkt_cnt > 1)		return 1;	netif_stop_queue(dev);	/* Disable all interrupts */	iow(db, DM9000_IMR, IMR_PAR);	/* Move data to DM9000 TX RAM */	writeb(DM9000_MWCMD, db->io_addr);	(db->outblk)(db->io_data, skb->data, skb->len);	db->stats.tx_bytes += skb->len;	/* 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, DM9000_TXPLL, skb->len & 0xff);		iow(db, DM9000_TXPLH, (skb->len >> 8) & 0xff);		/* Issue TX polling command */		iow(db, DM9000_TCR, TCR_TXREQ);	/* Cleared after TX complete */		dev->trans_start = jiffies;	/* save the time stamp */	} else {		/* Second packet */		db->tx_pkt_cnt++;		db->queue_pkt_len = skb->len;	}	/* free this SKB */	dev_kfree_skb(skb);	/* Re-enable resource check */	if (db->tx_pkt_cnt == 1)		netif_wake_queue(dev);	/* Re-enable interrupt */	iow(db, DM9000_IMR, IMR_PAR | IMR_PTM | IMR_PRM);	return 0;}static voiddm9000_shutdown(struct net_device *dev){	board_info_t *db = (board_info_t *) dev->priv;	/* RESET device */	dm9000_phy_write(dev, 0, MII_BMCR, BMCR_RESET);	/* PHY RESET */	iow(db, DM9000_GPR, 0x01);	/* Power-Down PHY */	iow(db, DM9000_IMR, IMR_PAR);	/* Disable all interrupt */	iow(db, DM9000_RCR, 0x00);	/* Disable RX */}/* * Stop the interface. * The interface is stopped when it is brought. */static intdm9000_stop(struct net_device *ndev){	board_info_t *db = (board_info_t *) ndev->priv;	PRINTK1("entering %s\n",__FUNCTION__);	/* deleted timer */	del_timer(&db->timer);	netif_stop_queue(ndev);	netif_carrier_off(ndev);	/* free interrupt */	free_irq(ndev->irq, ndev);	dm9000_shutdown(ndev);	return 0;}/* * DM9000 interrupt handler * receive the packet to upper layer, free the transmitted packet */voiddm9000_tx_done(struct net_device *dev, board_info_t * db)

⌨️ 快捷键说明

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