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

📄 em86xx_eth.c

📁 bootloader源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
#endif /*BOOTLOADER*/  	 	}  		desc_ptr->desc0 = DescOwnByDma;  	}	private->last_rxidx = count; /* This is the last desc we read */	/* make sure rx is not suspended */	em86xx_write_reg(EM86XX_RPDR_REG, 0x0);  	return 0;}/* Resetting rx descriptor: error recovery for "rx buf unavailable" */static void em86xx_eth_reset_rx_buf(struct net_device *dev){	register int i;	volatile struct em86xx_desc *desc_ptr = NULL;	/* Reset rx desc */	desc_ptr = (struct em86xx_desc *)(rxdsc); 	for (i = 0; i < num_rxdesc; i++, desc_ptr++) 		desc_ptr->desc0 = DescOwnByDma;   	  	em86xx_write_reg(EM86XX_RPDR_REG,  0x0);	em86xx_set_reg(EM86XX_CR_REG, DmaRxStart); }#ifndef BOOTLOADER/* Get the stats information */static struct net_device_stats *em86xx_eth_stats(struct net_device *dev){	if (dev != NULL)     		return(&(((EM86XX_ETH_PRIV *)dev->priv)->stats));  	else    		return(NULL);}#endif/* Ethernet interrupt handler */#ifdef BOOTLOADERstatic void em86xx_eth_intr_handler(int irq, void *dev_id)#elsestatic void em86xx_eth_intr_handler(int irq, void *dev_id, struct pt_regs *regs)#endif{       unsigned long status;       struct net_device *dev = (struct net_device *)dev_id;#ifdef BOOTLOADER        if( memcmp(dev->name,DRIVER, sizeof(DRIVER)) != 0)                 return;#else        if (dev_id != (void *)&em86xx_eth_dev)                return;#endif        /* Check status */        status = em86xx_read_reg(EM86XX_SR_REG);        //clear all interrupt requests        em86xx_write_reg(EM86XX_SR_REG, status) ;        if (status & DmaIntNormal) {                 if (status & DmaIntRxCompleted)                          em86xx_eth_rx((struct net_device *)dev_id);                else                        ERR_PRINT("%s: unhandled NIS 0x%08lx\n", dev->name, status);        }  	if (status & DmaIntAbnormal) {                 if (status & DmaIntRxNoBuffer) {                         ERR_PRINT("%s: receive buffer unavailable 0x%08lx\n", dev->name, status);                        em86xx_eth_reset_rx_buf((struct net_device *)dev_id);                } else if (status & DmaIntRxStopped) {                        ERR_PRINT("%s: receive process stopped\n", dev->name);                        em86xx_set_reg(EM86XX_CR_REG, DmaRxStart);                 } else if (status & DmaIntTxStopped ) {                        ERR_PRINT("%s: transmit process stopped\n", dev->name);                        em86xx_write_reg(EM86XX_CR_REG, DmaRxStart);                 } else if (status & DmaIntTxUnderflow) {                        ERR_PRINT("%s: transmit underflow\n", dev->name);                } else if (status & DmaIntEarlyTx ) {                        ERR_PRINT("%s: Early transmit interrupt\n", dev->name);                } else if (status & DmaIntBusError ) {                        ERR_PRINT("%s: Fatal bus error\n", dev->name);                } else {                        ERR_PRINT("%s: unhandled AIS 0x%08lx\n", dev->name, status);                }        } 	if (((status & DmaIntAbnormal) == 0) && ((status & DmaIntNormal) == 0)) {                ERR_PRINT("%s: Unknown SR 0x%08lx\n", dev->name, status);        }        return;}#ifndef BOOTLOADER/* Handling ioctl call */static int em86xx_eth_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd){	/* TODO: Not implemented yet */	struct mii_ioctl_data *data = (struct mii_ioctl_data *)&ifr->ifr_data;    	switch(cmd) {	case SIOCGMIIREG:		/* Read MII PHY register. */		data->val_out = em86xx_mii_read(data->phy_id & 0x1f, data->reg_num & 0x1f);		return 0;	case SIOCSMIIREG:		/* Write MII PHY register. */		em86xx_mii_write(data->phy_id, data->reg_num, data->val_in);		return 0;	default:		return -EOPNOTSUPP;	}  	return(-EIO);}#endif/* Kernel level ethernet initialization */static int em86xx_eth_init(struct net_device *dev){	DBG_PRINT("em86xx_eth_init\n");	if (dev == NULL)  		goto failed;	rxdsc = (volatile struct em86xx_desc *)NON_CACHED((u32)eth_rxdsc);	txdsc = (volatile struct em86xx_desc *)NON_CACHED((u32)eth_txdsc);	rxbuf = (volatile unsigned char *)NON_CACHED((u32)eth_rxbuf);	txbuf = (volatile unsigned char *)NON_CACHED((u32)eth_txbuf);	/* Ethernet device initialization */#ifdef BOOTLOADER        /* Fill in the fields of the device structure with ethernet-generic values.*///      dev->type               = ARPHRD_ETHER;        dev->mtu                = ETH_DATA_LEN; /* eth_mtu */        dev->addr_len           = ETH_ALEN;        memset(dev->broadcast, 0xff, ETH_ALEN);        dev->hard_header_len = ETH_HLEN;#else	ether_setup(dev);#endif	if (em86xx_set_mac(dev))  		goto failed;	/* Hook up with handlers */#ifdef BOOTLOADER        dev->send_packet         = em86xx_eth_tx;        dev->open                = em86xx_eth_open;        dev->close               = em86xx_eth_close;#else	dev->get_stats		 = em86xx_eth_stats;	dev->hard_start_xmit	 = em86xx_eth_tx;	dev->open		 = em86xx_eth_open;	dev->stop		 = em86xx_eth_close;	dev->set_multicast_list  = em86xx_eth_set_multicast_list;	dev->do_ioctl		 = em86xx_eth_ioctl;	dev->set_mac_address	 = em86xx_eth_set_macaddr;	dev->tx_queue_len = num_txdesc; 	dev->flags &= ~IFF_MULTICAST;	dev->flags |= IFF_DEBUG;#endif	return 0;failed:	return(-EIO);}static int em86xx_eth_reset_desc(struct net_device *dev, int *reset){	EM86XX_ETH_PRIV *private;	if (dev == NULL)  		return(-EIO);	else		private = (EM86XX_ETH_PRIV *)dev->priv;	if (*reset)  		memset(dev->priv, 0, sizeof(EM86XX_ETH_PRIV));	*reset = 0;	/* Clear all tx/rx buffer memory */	memset((void *)(rxbuf), 0, num_rxdesc * R_BUF_SIZE);	memset((void *)(txbuf), 0, num_txdesc * T_BUF_SIZE);	/* Initialize the indices */	private->last_rxidx = 0;	private->next_txidx = 0;	/* Intialize the descriptors */	em86xx_eth_setup_desc();	return 0;}/* Driver installation: this is where the thing starts */#ifdef BOOTLOADERint em86xx_eth_probe(struct net_device *dev)#elsestatic int __init em86xx_eth_startup(void)#endif{#ifndef BOOTLOADER	struct net_device *dev 	= &em86xx_eth_dev;#endif	int err = 0, i;	EM86XX_ETH_PRIV *private= NULL;#ifndef STATIC_BUF_ALLOC	unsigned long max_num_rxdsc, max_num_txdsc;	unsigned long rxbuf_size, txbuf_size;#endif	if (dev_count != 0) {		err = -EIO;  		goto failed;	} #ifndef STATIC_BUF_ALLOC		/* Validating module parameters */	max_num_rxdsc = max_num_txdsc = PAGE_SIZE / (2 * sizeof(struct em86xx_desc));	if (((num_rxdesc < MIN_NUM_RDESC) || (num_rxdesc > max_num_rxdsc)) ||	    ((num_txdesc < MIN_NUM_TDESC) || (num_txdesc > max_num_txdsc))) {		err = -EIO;		goto failed;	} else if ((desc_page = __get_free_page(GFP_KERNEL | GFP_DMA)) == 0) {		err = -ENOMEM;		goto failed;	}	/* Split a page for both rx/tx descriptor */	eth_rxdsc = (struct em86xx_desc *)desc_page;	eth_txdsc = (struct em86xx_desc *)(desc_page + ((1 << PAGE_SHIFT) / 2));	/* Calculate the size needed for tx/rx -- aligned by pages */	rxbuf_size = num_rxdesc * R_BUF_SIZE;	txbuf_size = num_txdesc * T_BUF_SIZE;	if ((rxbuf_size & (PAGE_SIZE - 1)) != 0)		rxbuf_size = (rxbuf_size & PAGE_MASK) + PAGE_SIZE;	if ((txbuf_size & (PAGE_SIZE - 1)) != 0)		txbuf_size = (txbuf_size & PAGE_MASK) + PAGE_SIZE;	DBG_PRINT("txbuf_size = 0x%08lx, rxbuf_size = 0x%08lx\n", txbuf_size, rxbuf_size);	/* Calculate the order needed for tx/rx */	for (rxbuf_order = 0; rxbuf_order < MAX_ORDER; rxbuf_order++) {		if ((PAGE_SIZE * (1 << rxbuf_order)) >= rxbuf_size)			break;	}	for (txbuf_order = 0; txbuf_order < MAX_ORDER; txbuf_order++) {		if ((PAGE_SIZE * (1 << txbuf_order)) >= txbuf_size)			break;	}	if ((rxbuf_order >= MAX_ORDER) || (txbuf_order >= MAX_ORDER)) {		err = -ENOMEM;		goto failed;	}	DBG_PRINT("txbuf_order = 0x%08lx, rxbuf_order = 0x%08lx\n", txbuf_order, rxbuf_order);			if ((rxbuf_pages = __get_free_pages(GFP_KERNEL | GFP_DMA, rxbuf_order)) == 0) {		err = -ENOMEM;		goto failed;	} else if ((txbuf_pages = __get_free_pages(GFP_KERNEL | GFP_DMA, txbuf_order)) == 0) {		err = -ENOMEM;		goto failed;	}	eth_rxbuf  = (unsigned char *)rxbuf_pages;	eth_txbuf  = (unsigned char *)txbuf_pages;#endif#ifndef BOOTLOADER	SET_MODULE_OWNER(&em86xx_eth_dev);#endif	MSG_PRINT("Ethernet driver for EM86XX (v1.0)");	dev->priv = NULL;	/* Set up default mac address and others */	max_link_loop 	= DEF_LINK_LOOP;	ld_count 	= 1;	reset_flag 	= 1;	/* Get a device name: normally it'll be eth0 */#ifdef BOOTLOADER        memcpy( dev->name, DRIVER, sizeof(DRIVER));        /* Register ISR */        dev->irq = IRQ_ETHERNET;        em86xx_request_irq(IRQ_ETHERNET, em86xx_eth_intr_handler, dev);#else	if ((err = dev_alloc_name(&em86xx_eth_dev, "eth%d")) < 0)  		goto failed;	/* Register ISR */	if ((err = request_irq(IRQ_ETHERNET, em86xx_eth_intr_handler, 0, "ethernet",       	 	 &em86xx_eth_dev)) != 0) {  		err = -EIO;  		goto failed;	} else#endif   		MSG_PRINT(" on %s (IRQ: %d)", dev->name, IRQ_ETHERNET);	if (em86xx_get_macaddr(dev->dev_addr)) {  		err = -EIO;  		goto failed;	}	MSG_PRINT("\n(MAC %02x", dev->dev_addr[0]);	for (i = 1; i < 6; i++)	  	MSG_PRINT(":%02x", dev->dev_addr[i]);	MSG_PRINT(", tx_desc/rx_desc = %ld/%ld)\n", num_txdesc, num_rxdesc);	/* Allocate memory for private data */#ifdef BOOTLOADER        dev->priv = private = (EM86XX_ETH_PRIV *)malloc(sizeof(EM86XX_ETH_PRIV));//, GFP_KERNEL);#else	dev->priv = private = (EM86XX_ETH_PRIV *)kmalloc(sizeof(EM86XX_ETH_PRIV), GFP_KERNEL);#endif	if (dev->priv == NULL) {		err = -ENOMEM;		goto failed;	} 	/* Point to driver initialization routine and register the device with kernel */	dev->init = em86xx_eth_init;#ifdef BOOTLOADER        em86xx_eth_init(dev);        dev->state = NETDEV_DOWN;#else	if (register_netdev(dev) != 0) {  		err = -EIO;  		goto failed;	}#endif	MSG_PRINT("%s: driver installation completed.\n", dev->name);	dev_count++;	return 0;failed:  	if (dev->priv != NULL) {#ifdef BOOTLOADER                free(dev->priv);#else    		kfree(dev->priv);#endif    		dev->priv = NULL;  	}#ifndef STATIC_BUF_ALLOC	if (desc_page   != 0)		free_page(desc_page);	if (rxbuf_pages != 0)		free_pages(rxbuf_pages, rxbuf_order);	if (txbuf_pages != 0)		free_pages(txbuf_pages, txbuf_order);#endif  	MSG_PRINT("%s: driver installation failed.\n", dev->name);  	return(err);}#ifndef BOOTLOADER/* Uninstallation of drive */static void __exit em86xx_eth_shutdown(void){	if (dev_count != 0) {		/* Turn off IRQ and stop receive/transmit */  		em86xx_write_reg(EM86XX_CR_REG, 0);  		em86xx_write_reg(EM86XX_IER_REG, 0);  		/* Unregister the device and ISR */  		free_irq(IRQ_ETHERNET, &em86xx_eth_dev);		unregister_netdev(&em86xx_eth_dev);		/* Set desc base address registers to 0 */		em86xx_write_reg(EM86XX_RLBAR_REG, 0);		em86xx_write_reg(EM86XX_TLBAR_REG, 0);#ifndef STATIC_BUF_ALLOC		if (desc_page   != 0)			free_page(desc_page);		if (rxbuf_pages != 0)			free_pages(rxbuf_pages, rxbuf_order);		if (txbuf_pages != 0)			free_pages(txbuf_pages, txbuf_order);#endif		/* Free up memory */		if (em86xx_eth_dev.priv != NULL) {			kfree(em86xx_eth_dev.priv);			em86xx_eth_dev.priv = NULL;  		}	} }/* Register startup/shutdown routines */module_init(em86xx_eth_startup);module_exit(em86xx_eth_shutdown);#endif

⌨️ 快捷键说明

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