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

📄 au1000_eth.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 3 页
字号:
  DMA memory allocation, derived from pci_alloc_consistent.  However, the Au1000 data cache is coherent (when programmed  so), therefore we return KSEG0 address, not KSEG1.*/static void *dma_alloc(size_t size, dma_addr_t * dma_handle){	void *ret;	int gfp = GFP_ATOMIC | GFP_DMA;	ret = (void *) __get_free_pages(gfp, get_order(size));	if (ret != NULL) {		memset(ret, 0, size);		*dma_handle = virt_to_bus(ret);		ret = KSEG0ADDR(ret);	}	return ret;}static void dma_free(void *vaddr, size_t size){	vaddr = KSEG0ADDR(vaddr);	free_pages((unsigned long) vaddr, get_order(size));}static void hard_stop(struct net_device *dev){	struct au1000_private *aup = (struct au1000_private *) dev->priv;	if (au1000_debug > 4)		printk(KERN_INFO "%s: hard stop\n", dev->name);	aup->mac->control &= ~(MAC_RX_ENABLE | MAC_TX_ENABLE);	sync();	mdelay(10);}static void reset_mac(struct net_device *dev){	u32 flags;	struct au1000_private *aup = (struct au1000_private *) dev->priv;	if (au1000_debug > 4)		printk(KERN_INFO "%s: reset mac, aup %x\n", dev->name, (unsigned)aup);	spin_lock_irqsave(&aup->lock, flags);	del_timer(&aup->timer);	hard_stop(dev);	*aup->enable |= MAC_DMA_RESET;	sync();	mdelay(10);	aup->tx_full = 0;	spin_unlock_irqrestore(&aup->lock, flags);}static void cleanup_buffers(struct net_device *dev){	int i;	struct au1000_private *aup = (struct au1000_private *) dev->priv;	for (i=0; i<NUM_RX_DMA; i++) {		if (aup->rx_db_inuse[i]) {			ReleaseDB(aup, aup->rx_db_inuse[i]);			aup->rx_db_inuse[i] = 0;		}	}	for (i=0; i<NUM_TX_DMA; i++) {		if (aup->tx_db_inuse[i]) {			ReleaseDB(aup, aup->tx_db_inuse[i]);			aup->tx_db_inuse[i] = 0;		}	}}/*  * Setup the receive and transmit "rings".  These pointers are the addresses * of the rx and tx MAC DMA registers so they are fixed by the hardware -- * these are not descriptors sitting in memory. */static void setup_hw_rings(struct au1000_private *aup, u32 rx_base, u32 tx_base){	int i;	for (i=0; i<NUM_RX_DMA; i++) {		aup->rx_dma_ring[i] = (volatile rx_dma_t *) ioremap_nocache((unsigned long)					(rx_base + sizeof(rx_dma_t)*i), sizeof(rx_dma_t));	}	for (i=0; i<NUM_TX_DMA; i++) {		aup->tx_dma_ring[i] = (volatile tx_dma_t *)ioremap_nocache((unsigned long)				(tx_base + sizeof(tx_dma_t)*i), sizeof(tx_dma_t));	}}/* * Probe for a AU1000 ethernet controller. */int __init au1000_probe(struct net_device *dev){	int base_addr = au1000_iflist[next_dev].port;	int irq = au1000_iflist[next_dev].irq;#ifndef CONFIG_MIPS_AU1000_ENET	return -ENODEV;#endif	if (au1000_debug > 4)		printk(KERN_INFO "%s: au1000_probe base_addr %x\n", 				dev->name, base_addr);	if (next_dev >= NUM_INTERFACES) {		return -ENODEV;	}	if (au1000_probe1(dev, base_addr, irq, next_dev) == 0) {		next_dev++;		return 0;	}	next_dev++;	return -ENODEV;}static int __initau1000_probe1(struct net_device *dev, long ioaddr, int irq, int port_num){	static unsigned version_printed = 0;	struct au1000_private *aup = NULL;	int i, retval = 0;	db_dest_t *pDB, *pDBfree;	u16 link, speed;	if ((ioaddr != AU1000_ETH0_BASE) && (ioaddr != AU1000_ETH1_BASE))  {		return -ENODEV;	}	if (!request_region(ioaddr, MAC_IOSIZE, "Au1000 ENET")) {		 return -ENODEV;	}	if (version_printed++ == 0) printk(version);	if (!dev) {		dev = init_etherdev(0, sizeof(struct au1000_private));	}	if (!dev) {		 printk (KERN_ERR "au1000 eth: init_etherdev failed\n");  		 return -ENODEV;	}	printk("%s: Au1000 ethernet found at 0x%lx, irq %d\n",	       dev->name, ioaddr, irq);	/* Initialize our private structure */	if (dev->priv == NULL) {		aup = (struct au1000_private *) kmalloc(sizeof(*aup), GFP_KERNEL);		if (aup == NULL) {			retval = -ENOMEM;			goto free_region;		}		dev->priv = aup;	}	aup = dev->priv;	memset(aup, 0, sizeof(*aup));	/* Allocate the data buffers */	aup->vaddr = (u32)dma_alloc(MAX_BUF_SIZE * (NUM_TX_BUFFS+NUM_RX_BUFFS), &aup->dma_addr);	if (!aup->vaddr) {		retval = -ENOMEM;		goto free_region;	}	/* aup->mac is the base address of the MAC's registers */	aup->mac = (volatile mac_reg_t *)ioremap_nocache((unsigned long)ioaddr, sizeof(*aup->mac));	/* Setup some variables for quick register address access */	if (ioaddr == AU1000_ETH0_BASE) {		aup->enable = (volatile u32 *)			ioremap_nocache((unsigned long)MAC0_ENABLE, sizeof(*aup->enable)); 		memcpy(dev->dev_addr, au1000_mac_addr[0], sizeof(dev->dev_addr));		setup_hw_rings(aup, MAC0_RX_DMA_ADDR, MAC0_TX_DMA_ADDR);	}	else if (ioaddr == AU1000_ETH1_BASE) {		aup->enable = (volatile u32 *)			ioremap_nocache((unsigned long)MAC1_ENABLE, sizeof(*aup->enable)); 		memcpy(dev->dev_addr, au1000_mac_addr[1], sizeof(dev->dev_addr));		setup_hw_rings(aup, MAC1_RX_DMA_ADDR, MAC1_TX_DMA_ADDR);	}	else { /* should never happen */		 printk (KERN_ERR "au1000 eth: bad ioaddr %x\n", (unsigned)ioaddr);  		 retval = -ENODEV;		 goto free_region;	}	aup->phy_addr = PHY_ADDRESS;	/* bring the device out of reset, otherwise probing the mii	 * will hang */	*aup->enable = MAC_EN_RESET0 | MAC_EN_RESET1 | MAC_EN_RESET2 |		MAC_EN_CLOCK_ENABLE | MAC_EN_TOSS;	sync();	mdelay(2);	if (mii_probe(dev) != 0) {		 goto free_region;	}	aup->phy_ops->phy_status(dev, aup->phy_addr, &link, &speed);	if (!link) {		printk(KERN_INFO "%s: link down resetting...\n", dev->name);		aup->phy_ops->phy_reset(dev, aup->phy_addr);		aup->phy_ops->phy_init(dev, aup->phy_addr);	}	else {		printk(KERN_INFO "%s: link up (%s)\n", dev->name, phy_link[speed]);	}	pDBfree = NULL;	/* setup the data buffer descriptors and attach a buffer to each one */	pDB = aup->db;	for (i=0; i<(NUM_TX_BUFFS+NUM_RX_BUFFS); i++) {		pDB->pnext = pDBfree;		pDBfree = pDB;		pDB->vaddr = (u32 *)((unsigned)aup->vaddr + MAX_BUF_SIZE*i);		pDB->dma_addr = (dma_addr_t)virt_to_bus(pDB->vaddr);		pDB++;	}	aup->pDBfree = pDBfree;	for (i=0; i<NUM_RX_DMA; i++) {		pDB = GetFreeDB(aup);		if (!pDB) goto free_region;		aup->rx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr;		aup->rx_db_inuse[i] = pDB;	}	for (i=0; i<NUM_TX_DMA; i++) {		pDB = GetFreeDB(aup);		if (!pDB) goto free_region;		aup->tx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr;		aup->tx_dma_ring[i]->len = 0;		aup->tx_db_inuse[i] = pDB;	}	spin_lock_init(&aup->lock);	dev->base_addr = ioaddr;	dev->irq = irq;	dev->open = au1000_open;	dev->hard_start_xmit = au1000_tx;	dev->stop = au1000_close;	dev->get_stats = au1000_get_stats;	dev->set_multicast_list = &set_rx_mode;	dev->do_ioctl = &au1000_ioctl;	dev->set_config = &au1000_set_config;	dev->tx_timeout = au1000_tx_timeout;	dev->watchdog_timeo = ETH_TX_TIMEOUT;	/* Fill in the fields of the device structure with ethernet values. */	ether_setup(dev);	/* 	 * The boot code uses the ethernet controller, so reset it to start fresh.	 * au1000_init() expects that the device is in reset state.	 */	reset_mac(dev);	return 0;free_region:	release_region(ioaddr, MAC_IOSIZE);	unregister_netdev(dev);	if (aup->vaddr)		dma_free((void *)aup->vaddr, MAX_BUF_SIZE * (NUM_TX_BUFFS+NUM_RX_BUFFS));	if (dev->priv != NULL)		kfree(dev->priv);	kfree(dev);	printk(KERN_ERR "%s: au1000_probe1 failed.  Returns %d\n",	       dev->name, retval);	return retval;}/*  * Initialize the interface. * * When the device powers up, the clocks are disabled and the * mac is in reset state.  When the interface is closed, we * do the same -- reset the device and disable the clocks to * conserve power. Thus, whenever au1000_init() is called, * the device should already be in reset state. */static int au1000_init(struct net_device *dev){	struct au1000_private *aup = (struct au1000_private *) dev->priv;	u32 flags;	int i;	u32 value, control;	if (au1000_debug > 4) printk("%s: au1000_init", dev->name);	spin_lock_irqsave(&aup->lock, flags);	/* bring the device out of reset */	value = MAC_EN_RESET0 | MAC_EN_RESET1 | MAC_EN_RESET2 |		MAC_EN_CLOCK_ENABLE | MAC_EN_TOSS;	*aup->enable = value;	sync();	mdelay(200);	aup->mac->control = 0;	aup->tx_head = (aup->tx_dma_ring[0]->buff_stat & 0xC) >> 2;	aup->tx_tail = aup->tx_head;	aup->rx_head = (aup->rx_dma_ring[0]->buff_stat & 0xC) >> 2;	aup->mac->mac_addr_high = dev->dev_addr[5]<<8 | dev->dev_addr[4];	aup->mac->mac_addr_low = dev->dev_addr[3]<<24 | dev->dev_addr[2]<<16 |		dev->dev_addr[1]<<8 | dev->dev_addr[0];	for (i=0; i<NUM_RX_DMA; i++) {		aup->rx_dma_ring[i]->buff_stat |= RX_DMA_ENABLE;	}	sync();	control = MAC_DISABLE_RX_OWN | MAC_RX_ENABLE | MAC_TX_ENABLE;#ifndef CONFIG_CPU_LITTLE_ENDIAN	control |= MAC_BIG_ENDIAN;#endif	aup->mac->control = control;	spin_unlock_irqrestore(&aup->lock, flags);	return 0;}static void au1000_timer(unsigned long data){	struct net_device *dev = (struct net_device *)data;	struct au1000_private *aup = (struct au1000_private *) dev->priv;	u16 mii_data, link, speed;	if (!dev) {		/* fatal error, don't restart the timer */		printk(KERN_ERR "au1000_timer error: NULL dev\n");		return;	}	if (!(dev->flags & IFF_UP)) {		goto set_timer;	}	if (aup->phy_ops->phy_status(dev, aup->phy_addr, &link, &speed) == 0) {		if (link) {			if (!(dev->flags & IFF_RUNNING)) {				netif_carrier_on(dev);				dev->flags |= IFF_RUNNING;				printk(KERN_DEBUG "%s: link up\n", dev->name);			}		}		else {			if (dev->flags & IFF_RUNNING) {				netif_carrier_off(dev);				dev->flags &= ~IFF_RUNNING;				dev->if_port = 0;				printk(KERN_DEBUG "%s: link down\n", dev->name);			}		}	}set_timer:	aup->timer.expires = RUN_AT((1*HZ)); 	aup->timer.data = (unsigned long)dev;	aup->timer.function = &au1000_timer; /* timer handler */	add_timer(&aup->timer);}static int au1000_open(struct net_device *dev){	int retval;	struct au1000_private *aup = (struct au1000_private *) dev->priv;	MOD_INC_USE_COUNT;	if (au1000_debug > 4)		printk("%s: open: dev=%p\n", dev->name, dev);	if ((retval = au1000_init(dev))) {		printk(KERN_ERR "%s: error in au1000_init\n", dev->name);		free_irq(dev->irq, dev);		MOD_DEC_USE_COUNT;		return retval;	}	netif_start_queue(dev);	if ((retval = request_irq(dev->irq, &au1000_interrupt, 0, dev->name, dev))) {		printk(KERN_ERR "%s: unable to get IRQ %d\n", dev->name, dev->irq);		MOD_DEC_USE_COUNT;		return retval;	}	aup->timer.expires = RUN_AT((3*HZ)); 	aup->timer.data = (unsigned long)dev;	aup->timer.function = &au1000_timer; /* timer handler */	add_timer(&aup->timer);	if (au1000_debug > 4)		printk("%s: open: Initialization done.\n", dev->name);	return 0;}static int au1000_close(struct net_device *dev){	u32 flags;	struct au1000_private *aup = (struct au1000_private *) dev->priv;	if (au1000_debug > 4)		printk("%s: close: dev=%p\n", dev->name, dev);	spin_lock_irqsave(&aup->lock, flags);		/* stop the device */	if (netif_device_present(dev)) {

⌨️ 快捷键说明

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