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

📄 oaknet.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * *    Copyright (c) 1999-2000 Grant Erickson <grant@lcse.umn.edu> * *    Module name: oaknet.c * *    Description: *      Driver for the National Semiconductor DP83902AV Ethernet controller *      on-board the IBM PowerPC "Oak" evaluation board. Adapted from the *      various other 8390 drivers written by Donald Becker and Paul Gortmaker. * *      Additional inspiration from the "tcd8390.c" driver from TiVo, Inc.  *      and "enetLib.c" from IBM. * */#include <linux/module.h>#include <linux/errno.h>#include <linux/delay.h>#include <linux/netdevice.h>#include <linux/etherdevice.h>#include <linux/init.h>#include <asm/board.h>#include <asm/io.h>#include "8390.h"/* Preprocessor Defines */#if !defined(TRUE) || TRUE != 1#define	TRUE	1#endif#if !defined(FALSE) || FALSE != 0#define	FALSE	0#endif#define	OAKNET_START_PG		0x20	/* First page of TX buffer */#define	OAKNET_STOP_PG		0x40	/* Last pagge +1 of RX ring */#define	OAKNET_WAIT		(2 * HZ / 100)	/* 20 ms *//* Experimenting with some fixes for a broken driver... */#define	OAKNET_DISINT#define	OAKNET_HEADCHECK#define	OAKNET_RWFIX/* Global Variables */static const char *name = "National DP83902AV";static struct net_device *oaknet_devs;/* Function Prototypes */static int	 oaknet_open(struct net_device *dev);static int	 oaknet_close(struct net_device *dev);static void	 oaknet_reset_8390(struct net_device *dev);static void	 oaknet_get_8390_hdr(struct net_device *dev,				     struct e8390_pkt_hdr *hdr, int ring_page);static void	 oaknet_block_input(struct net_device *dev, int count,				    struct sk_buff *skb, int ring_offset);static void	 oaknet_block_output(struct net_device *dev, int count,				     const unsigned char *buf, int start_page);static void	 oaknet_dma_error(struct net_device *dev, const char *name);/* * int oaknet_init() * * Description: *   This routine performs all the necessary platform-specific initiali- *   zation and set-up for the IBM "Oak" evaluation board's National *   Semiconductor DP83902AV "ST-NIC" Ethernet controller. * * Input(s): *   N/A * * Output(s): *   N/A * * Returns: *   0 if OK, otherwise system error number on error. * */static int __init oaknet_init(void){	register int i;	int reg0, regd;	int ret;	struct net_device tmp, *dev = NULL;#if 0	unsigned long ioaddr = OAKNET_IO_BASE; #else	unsigned long ioaddr = ioremap(OAKNET_IO_BASE, OAKNET_IO_SIZE);#endif	bd_t *bip = (bd_t *)__res;	if (!ioaddr)		return -ENOMEM;	/*	 * This MUST happen here because of the nic_* macros	 * which have an implicit dependency on dev->base_addr.	 */	tmp.base_addr = ioaddr;	dev = &tmp;	ret = -EBUSY;	if (!request_region(OAKNET_IO_BASE, OAKNET_IO_SIZE, name))		goto out_unmap;	/* Quick register check to see if the device is really there. */	ret = -ENODEV;	if ((reg0 = ei_ibp(ioaddr)) == 0xFF)		goto out_region;	/*	 * That worked. Now a more thorough check, using the multicast	 * address registers, that the device is definitely out there	 * and semi-functional.	 */	ei_obp(E8390_NODMA + E8390_PAGE1 + E8390_STOP, ioaddr + E8390_CMD);	regd = ei_ibp(ioaddr + 0x0D);	ei_obp(0xFF, ioaddr + 0x0D);	ei_obp(E8390_NODMA + E8390_PAGE0, ioaddr + E8390_CMD);	ei_ibp(ioaddr + EN0_COUNTER0);	/* It's no good. Fix things back up and leave. */	ret = -ENODEV;	if (ei_ibp(ioaddr + EN0_COUNTER0) != 0) {		ei_obp(reg0, ioaddr);		ei_obp(regd, ioaddr + 0x0D);		goto out_region;	}	/*	 * We're not using the old-style probing API, so we have to allocate	 * our own device structure.	 */	dev = init_etherdev(NULL, 0);	ret = -ENOMEM;	if (!dev)		goto out_region;	SET_MODULE_OWNER(dev);	oaknet_devs = dev;	/*	 * This controller is on an embedded board, so the base address	 * and interrupt assignments are pre-assigned and unchageable.	 */	dev->base_addr = ioaddr;	dev->irq = OAKNET_INT;	/* Allocate 8390-specific device-private area and fields. */	ret = -ENOMEM;	if (ethdev_init(dev)) {		printk(" unable to get memory for dev->priv.\n");		goto out_dev;	}	/*	 * Disable all chip interrupts for now and ACK all pending	 * interrupts.	 */	ei_obp(0x0, ioaddr + EN0_IMR);	ei_obp(0xFF, ioaddr + EN0_ISR);	/* Attempt to get the interrupt line */	ret = -EAGAIN;	if (request_irq(dev->irq, ei_interrupt, 0, name, dev)) {		printk("%s: unable to request interrupt %d.\n",		       dev->name, dev->irq);		goto out_priv;	}	/* Tell the world about what and where we've found. */	printk("%s: %s at", dev->name, name);	for (i = 0; i < ETHER_ADDR_LEN; ++i) {		dev->dev_addr[i] = bip->bi_enetaddr[i];		printk("%c%.2x", (i ? ':' : ' '), dev->dev_addr[i]);	}	printk(", found at %#lx, using IRQ %d.\n", dev->base_addr, dev->irq);	/* Set up some required driver fields and then we're done. */	ei_status.name		= name;	ei_status.word16	= FALSE;	ei_status.tx_start_page	= OAKNET_START_PG;	ei_status.rx_start_page = OAKNET_START_PG + TX_PAGES;	ei_status.stop_page	= OAKNET_STOP_PG;	ei_status.reset_8390	= &oaknet_reset_8390;	ei_status.block_input	= &oaknet_block_input;	ei_status.block_output	= &oaknet_block_output;	ei_status.get_8390_hdr	= &oaknet_get_8390_hdr;	dev->open = oaknet_open;	dev->stop = oaknet_close;	NS8390_init(dev, FALSE);	return (0);out_priv:	kfree(dev->priv);out_dev:	unregister_netdev(dev);	kfree(dev);out_region:	release_region(OAKNET_IO_BASE, OAKNET_IO_SIZE);out_unmap:	iounmap(ioaddr);	return ret;}/* * static int oaknet_open() * * Description: *   This routine is a modest wrapper around ei_open, the 8390-generic, *   driver open routine. This just increments the module usage count *   and passes along the status from ei_open. * * Input(s): *  *dev - Pointer to the device structure for this driver. * * Output(s): *  *dev - Pointer to the device structure for this driver, potentially *         modified by ei_open. * * Returns: *   0 if OK, otherwise < 0 on error. * */static intoaknet_open(struct net_device *dev){	int status = ei_open(dev);	return (status);}/* * static int oaknet_close() * * Description: *   This routine is a modest wrapper around ei_close, the 8390-generic, *   driver close routine. This just decrements the module usage count *   and passes along the status from ei_close. * * Input(s): *  *dev - Pointer to the device structure for this driver. * * Output(s): *  *dev - Pointer to the device structure for this driver, potentially *         modified by ei_close. * * Returns: *   0 if OK, otherwise < 0 on error. * */static intoaknet_close(struct net_device *dev){	int status = ei_close(dev);	return (status);}/* * static void oaknet_reset_8390() * * Description: *   This routine resets the DP83902 chip. * * Input(s): *  *dev - Pointer to the device structure for this driver. * * Output(s): *   N/A * * Returns: *   N/A * */static voidoaknet_reset_8390(struct net_device *dev){	int base = E8390_BASE;	/*	 * We have no provision of reseting the controller as is done	 * in other drivers, such as "ne.c". However, the following	 * seems to work well enough in the TiVo driver.	 */	printk("Resetting %s...\n", dev->name);	ei_obp(E8390_STOP | E8390_NODMA | E8390_PAGE0, base + E8390_CMD);	ei_status.txing = 0;	ei_status.dmaing = 0;}/* * static void oaknet_get_8390_hdr() * * Description: *   This routine grabs the 8390-specific header. It's similar to the *   block input routine, but we don't need to be concerned with ring wrap *   as the header will be at the start of a page, so we optimize accordingly. * * Input(s): *  *dev       - Pointer to the device structure for this driver. *  *hdr       - Pointer to storage for the 8390-specific packet header. *   ring_page - ? * * Output(s): *  *hdr       - Pointer to the 8390-specific packet header for the just- *               received frame. * * Returns: *   N/A * */static voidoaknet_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,		    int ring_page){	int base = dev->base_addr;	/*	 * This should NOT happen. If it does, it is the LAST thing you'll	 * see.	 */	if (ei_status.dmaing) {		oaknet_dma_error(dev, "oaknet_get_8390_hdr");

⌨️ 快捷键说明

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