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

📄 ether00.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (readl(ETHER_INT_SRC(dev->base_addr)) &	    (ETHER_INT_SRC_INTSBUS_MSK |	     ETHER_INT_SRC_INTNRABT_MSK	     |ETHER_INT_SRC_DMPARERR_MSK))	{		/*		 * Hardware errors, we can either ignore them and hope they go away		 *or reset the device, I'll try the first for now to see if they happen		 */		printk("Hardware error\n");	}}static void ether00_setup_ethernet_address(struct net_device* dev){	int tmp;	dev->addr_len=6;	writew(0,ETHER_ARC_ADR(dev->base_addr));	writel((dev->dev_addr[0]<<24) |		(dev->dev_addr[1]<<16) |		(dev->dev_addr[2]<<8) |		dev->dev_addr[3],		ETHER_ARC_DATA(dev->base_addr));	writew(4,ETHER_ARC_ADR(dev->base_addr));	tmp=readl(ETHER_ARC_DATA(dev->base_addr));	tmp&=0xffff;	tmp|=(dev->dev_addr[4]<<24) | (dev->dev_addr[5]<<16);	writel(tmp, ETHER_ARC_DATA(dev->base_addr));	/* Enable this entry in the ARC */	writel(1,ETHER_ARC_ENA(dev->base_addr));	return;}static void ether00_reset(struct net_device *dev){	/* reset the controller */	writew(ETHER_MAC_CTL_RESET_MSK,ETHER_MAC_CTL(dev->base_addr));	/*	 * Make sure we're not going to send anything	 */	writew(ETHER_TX_CTL_TXHALT_MSK,ETHER_TX_CTL(dev->base_addr));	/*	 * Make sure we're not going to receive anything	 */	writew(ETHER_RX_CTL_RXHALT_MSK,ETHER_RX_CTL(dev->base_addr));	/*	 * Disable Interrupts for now, and set the burst size to 8 bytes	 */	writel(ETHER_DMA_CTL_INTMASK_MSK |	       ((8 << ETHER_DMA_CTL_DMBURST_OFST) & ETHER_DMA_CTL_DMBURST_MSK)	       |(2<<ETHER_DMA_CTL_RXALIGN_OFST),	       ETHER_DMA_CTL(dev->base_addr));	/*	 * Set TxThrsh - start transmitting a packet after 1514	 * bytes or when a packet is complete, whichever comes first	 */	 writew(1514,ETHER_TXTHRSH(dev->base_addr));	/*	 * Set TxPollCtr.  Each cycle is	 * 61.44 microseconds with a 33 MHz bus	 */	 writew(1,ETHER_TXPOLLCTR(dev->base_addr));	/*	 * Set Rx_Ctl - Turn off reception and let RxData turn it	 * on later	 */	 writew(ETHER_RX_CTL_RXHALT_MSK,ETHER_RX_CTL(dev->base_addr));}static void ether00_set_multicast(struct net_device* dev){	int count=dev->mc_count;	/* Set promiscuous mode if it's asked for. */	if (dev->flags&IFF_PROMISC){		writew( ETHER_ARC_CTL_COMPEN_MSK |			ETHER_ARC_CTL_BROADACC_MSK |			ETHER_ARC_CTL_GROUPACC_MSK |			ETHER_ARC_CTL_STATIONACC_MSK,			ETHER_ARC_CTL(dev->base_addr));		return;	}	/*	 * Get all multicast packets if required, or if there are too	 * many addresses to fit in hardware	 */	if (dev->flags & IFF_ALLMULTI){		writew( ETHER_ARC_CTL_COMPEN_MSK |			ETHER_ARC_CTL_GROUPACC_MSK |			ETHER_ARC_CTL_BROADACC_MSK,			ETHER_ARC_CTL(dev->base_addr));		return;	}	if (dev->mc_count > (ETHER_ARC_SIZE - 1)){		printk(KERN_WARNING "Too many multicast addresses for hardware to filter - receiving all multicast packets\n");		writew( ETHER_ARC_CTL_COMPEN_MSK |			ETHER_ARC_CTL_GROUPACC_MSK |			ETHER_ARC_CTL_BROADACC_MSK,			ETHER_ARC_CTL(dev->base_addr));		return;	}	if(dev->mc_count){		struct dev_mc_list *mc_list_ent=dev->mc_list;		unsigned int temp,i;		DEBUG(printk("mc_count=%d mc_list=%#x\n",dev-> mc_count, dev->mc_list));		DEBUG(printk("mc addr=%02#x%02x%02x%02x%02x%02x\n",			     mc_list_ent->dmi_addr[5],			     mc_list_ent->dmi_addr[4],			     mc_list_ent->dmi_addr[3],			     mc_list_ent->dmi_addr[2],			     mc_list_ent->dmi_addr[1],			     mc_list_ent->dmi_addr[0]);)		/*		 * The first 6 bytes are the MAC address, so		 * don't change them!		 */		writew(4,ETHER_ARC_ADR(dev->base_addr));		temp=readl(ETHER_ARC_DATA(dev->base_addr));		temp&=0xffff0000;		/* Disable the current multicast stuff */		writel(1,ETHER_ARC_ENA(dev->base_addr));		for(;;){			temp|=mc_list_ent->dmi_addr[1] |				mc_list_ent->dmi_addr[0]<<8;			writel(temp,ETHER_ARC_DATA(dev->base_addr));			i=readl(ETHER_ARC_ADR(dev->base_addr));			writew(i+4,ETHER_ARC_ADR(dev->base_addr));			temp=mc_list_ent->dmi_addr[5]|				mc_list_ent->dmi_addr[4]<<8 |				mc_list_ent->dmi_addr[3]<<16 |				mc_list_ent->dmi_addr[2]<<24;			writel(temp,ETHER_ARC_DATA(dev->base_addr));			count--;			if(!mc_list_ent->next || !count){				break;			}			DEBUG(printk("mc_list_next=%#x\n",mc_list_ent->next);)			mc_list_ent=mc_list_ent->next;			i=readl(ETHER_ARC_ADR(dev->base_addr));			writel(i+4,ETHER_ARC_ADR(dev->base_addr));			temp=mc_list_ent->dmi_addr[3]|				mc_list_ent->dmi_addr[2]<<8 |				mc_list_ent->dmi_addr[1]<<16 |				mc_list_ent->dmi_addr[0]<<24;			writel(temp,ETHER_ARC_DATA(dev->base_addr));			i=readl(ETHER_ARC_ADR(dev->base_addr));			writel(i+4,ETHER_ARC_ADR(dev->base_addr));			temp=mc_list_ent->dmi_addr[4]<<16 |				mc_list_ent->dmi_addr[5]<<24;			writel(temp,ETHER_ARC_DATA(dev->base_addr));			count--;			if(!mc_list_ent->next || !count){				break;			}			mc_list_ent=mc_list_ent->next;		}		if(count)			printk(KERN_WARNING "Multicast list size error\n");		writew( ETHER_ARC_CTL_BROADACC_MSK|			ETHER_ARC_CTL_COMPEN_MSK,			ETHER_ARC_CTL(dev->base_addr));	}	/* enable the active ARC enties */	writew((1<<(count+2))-1,ETHER_ARC_ENA(dev->base_addr));;}static int ether00_open(struct net_device* dev){	int result,tmp;	struct net_priv* priv;	dev->base_addr=ioremap_nocache(base,SZ_4K);	dev->irq=irq;	dev->priv=kmalloc(sizeof(struct net_priv),GFP_KERNEL);	if(!dev->priv)		return -ENOMEM;	memset(dev->priv,0,sizeof(struct net_priv));	priv=(struct net_priv*)dev->priv;	priv->tq_memupdate.routine=ether00_mem_update;	priv->tq_memupdate.data=(void*) dev;	if (!is_valid_ether_addr(dev->dev_addr))		return -EINVAL;	/* Install interrupt handlers */	result=request_irq(dev->irq,ether00_int,0,"ether00",dev);	if(result)		return result;	result=request_irq(phy_irq,ether00_phy_int,0,"ether00_phy",dev);	if(result)		return result;	ether00_reset(dev);	result=ether00_mem_init(dev);	if(result) return result;	ether00_setup_ethernet_address(dev);	ether00_set_multicast(dev);	result=ether00_write_phy(dev,PHY_CONTROL, PHY_CONTROL_ANEGEN_MSK | PHY_CONTROL_RANEG_MSK);	if(result) return result;	result=ether00_write_phy(dev,PHY_IRQ_CONTROL, PHY_IRQ_CONTROL_LS_CHG_IE_MSK |				 PHY_IRQ_CONTROL_ANEG_COMP_IE_MSK);	if(result) return result;	/* Start the device enable interrupts */	writew(ETHER_RX_CTL_RXEN_MSK	       | ETHER_RX_CTL_STRIPCRC_MSK	       | ETHER_RX_CTL_ENGOOD_MSK	       | ETHER_RX_CTL_ENRXPAR_MSK| ETHER_RX_CTL_ENLONGERR_MSK	       | ETHER_RX_CTL_ENOVER_MSK| ETHER_RX_CTL_ENCRCERR_MSK,	       ETHER_RX_CTL(dev->base_addr));	writew(ETHER_TX_CTL_TXEN_MSK|	       ETHER_TX_CTL_ENEXDEFER_MSK|	       ETHER_TX_CTL_ENLCARR_MSK|	       ETHER_TX_CTL_ENEXCOLL_MSK|	       ETHER_TX_CTL_ENLATECOLL_MSK|	       ETHER_TX_CTL_ENTXPAR_MSK|	       ETHER_TX_CTL_ENCOMP_MSK,	       ETHER_TX_CTL(dev->base_addr));	tmp=readl(ETHER_DMA_CTL(dev->base_addr));	writel(tmp&~ETHER_DMA_CTL_INTMASK_MSK,ETHER_DMA_CTL(dev->base_addr));	return 0;}static int ether00_tx(struct sk_buff* skb, struct net_device* dev){	struct net_priv *priv=dev->priv;	struct tx_fda_ent *fda_ptr;	int i;	/*	 *	Find an empty slot in which to stick the frame	 */	fda_ptr=(struct tx_fda_ent*)__dma_va(readl(ETHER_TXFRMPTR(dev->base_addr)));	i=0;	while(i<TX_NUM_FDESC){		if (fda_ptr->fd.FDStat||(fda_ptr->fd.FDCtl & FDCTL_COWNSFD_MSK)){			fda_ptr =(struct tx_fda_ent*) __dma_va((struct tx_fda_ent*)fda_ptr->fd.FDNext);		}		else {			break;		}		i++;	}	/* Write the skb data from the cache*/	consistent_sync(skb->data,skb->len,PCI_DMA_TODEVICE);	fda_ptr->bd.BuffData=(char*)__pa(skb->data);	fda_ptr->bd.BuffLength=(unsigned short)skb->len;	/* Save the pointer to the skb for freeing later */	fda_ptr->fd.FDSystem=(unsigned int)skb;	fda_ptr->fd.FDStat=0;	/* Pass ownership of the buffers to the controller */	fda_ptr->fd.FDCtl=1;	fda_ptr->fd.FDCtl|=FDCTL_COWNSFD_MSK;	/* If the next buffer in the list is full, stop the queue */	fda_ptr=(struct tx_fda_ent*)__dma_va(fda_ptr->fd.FDNext);	if ((fda_ptr->fd.FDStat)||(fda_ptr->fd.FDCtl & FDCTL_COWNSFD_MSK)){		netif_stop_queue(dev);		priv->queue_stopped=1;	}	return 0;}static struct net_device_stats *ether00_stats(struct net_device* dev){	struct net_priv *priv=dev->priv;	return &priv->stats;}static int ether00_stop(struct net_device* dev){	struct net_priv *priv=dev->priv;	int tmp;	/* Stop/disable the device. */	tmp=readw(ETHER_RX_CTL(dev->base_addr));	tmp&=~(ETHER_RX_CTL_RXEN_MSK | ETHER_RX_CTL_ENGOOD_MSK);	tmp|=ETHER_RX_CTL_RXHALT_MSK;	writew(tmp,ETHER_RX_CTL(dev->base_addr));	tmp=readl(ETHER_TX_CTL(dev->base_addr));	tmp&=~ETHER_TX_CTL_TXEN_MSK;	tmp|=ETHER_TX_CTL_TXHALT_MSK;	writel(tmp,ETHER_TX_CTL(dev->base_addr));	/* Free up system resources */	free_irq(dev->irq,dev);	free_irq(phy_irq,dev);	iounmap(priv->dma_data);	kfree(priv);	return 0;}static void ether00_get_ethernet_address(struct net_device* dev){	struct mtd_info *mymtd=NULL;	int i;	size_t retlen;	/*	 * For the Epxa10 dev board (camelot), the ethernet MAC	 * address is of the form  00:aa:aa:00:xx:xx where	 * 00:aa:aa is the Altera vendor ID and xx:xx is the	 * last 2 bytes of the board serial number, as programmed	 * into the OTP area of the flash device on EBI1. If this	 * isn't an expa10 dev board, or there's no mtd support to	 * read the serial number from flash then we'll force the	 * use to set their own mac address using ifconfig.	 */#ifdef CONFIG_ARCH_CAMELOT#ifdef CONFIG_MTD	/* get the mtd_info structure for the first mtd device*/	for(i=0;i<MAX_MTD_DEVICES;i++){		mymtd=get_mtd_device(NULL,i);		if(mymtd && !strcmp(mymtd->name,"master"))			break;	}	if(!mymtd || !mymtd->read_oob){		printk(KERN_WARNING "%s: Failed to read MAC address from flash\n",dev->name);	}else{		mymtd->read_oob(mymtd,10,1,&retlen,&dev->dev_addr[5]);		mymtd->read_oob(mymtd,11,1,&retlen,&dev->dev_addr[4]);		dev->dev_addr[3]=0;		dev->dev_addr[2]=vendor_id[1];		dev->dev_addr[1]=vendor_id[0];		dev->dev_addr[0]=0;	}#else	printk(KERN_WARNING "%s: MTD support required to read MAC address from EPXA10 dev board\n", dev->name);#endif#endif	if (!is_valid_ether_addr(dev->dev_addr))		printk("%s: Invalid ethernet MAC address.  Please set using "			"ifconfig\n", dev->name);}static int ether00_init(struct net_device* dev){	ether_setup(dev);	dev->open=ether00_open;	dev->stop=ether00_stop;	dev->set_multicast_list=ether00_set_multicast;	dev->hard_start_xmit=ether00_tx;	dev->get_stats=ether00_stats;	ether00_get_ethernet_address(dev);	SET_MODULE_OWNER(dev);	return 0;}struct net_device ether00_dev={	init:ether00_init,	name:"eth%d",};static void __exit ether00_cleanup_module(void){	unregister_netdev(&ether00_dev);}module_exit(ether00_cleanup_module);static int __init ether00_mod_init(void){	int result;	result=register_netdev(&ether00_dev);	if(result)		printk("Ether00: Error %i registering driver\n",result);	return result;}module_init(ether00_mod_init);

⌨️ 快捷键说明

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