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

📄 eepro.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 4 页
字号:
#define	I_ADD_REG0	0x04#define	I_ADD_REG1	0x05#define	I_ADD_REG2	0x06#define	I_ADD_REG3	0x07#define	I_ADD_REG4	0x08#define	I_ADD_REG5	0x09#define	EEPROM_REG_PRO 0x0a#define	EEPROM_REG_10  0x0b#define EESK 0x01#define EECS 0x02#define EEDI 0x04#define EEDO 0x08/* do a full reset */#define eepro_reset(ioaddr) outb(RESET_CMD, ioaddr)/* do a nice reset */#define eepro_sel_reset(ioaddr) 	{ \					outb(SEL_RESET_CMD, ioaddr); \					SLOW_DOWN; \					SLOW_DOWN; \					}/* disable all interrupts */#define eepro_dis_int(ioaddr) outb(ALL_MASK, ioaddr + INT_MASK_REG)/* clear all interrupts */#define eepro_clear_int(ioaddr) outb(ALL_MASK, ioaddr + STATUS_REG)/* enable tx/rx */#define eepro_en_int(ioaddr) outb(ALL_MASK & ~(RX_MASK | TX_MASK), \							ioaddr + INT_MASK_REG)/* enable exec event interrupt */#define eepro_en_intexec(ioaddr) outb(ALL_MASK & ~(EXEC_MASK), ioaddr + INT_MASK_REG)/* enable rx */#define eepro_en_rx(ioaddr) outb(RCV_ENABLE_CMD, ioaddr)/* disable rx */#define eepro_dis_rx(ioaddr) outb(RCV_DISABLE_CMD, ioaddr)/* switch bank */#define eepro_sw2bank0(ioaddr) outb(BANK0_SELECT, ioaddr)#define eepro_sw2bank1(ioaddr) outb(BANK1_SELECT, ioaddr)#define eepro_sw2bank2(ioaddr) outb(BANK2_SELECT, ioaddr)/* enable interrupt line */#define eepro_en_intline(ioaddr) outb(inb(ioaddr + REG1) | INT_ENABLE,\				ioaddr + REG1)/* disable interrupt line */#define eepro_dis_intline(ioaddr) outb(inb(ioaddr + REG1) & 0x7f, \				ioaddr + REG1);/* set diagnose flag */#define eepro_diag(ioaddr) outb(DIAGNOSE_CMD, ioaddr)/* ack for rx int */#define eepro_ack_rx(ioaddr) outb (RX_INT, ioaddr + STATUS_REG)/* ack for tx int */#define eepro_ack_tx(ioaddr) outb (TX_INT, ioaddr + STATUS_REG)/* a complete sel reset */#define eepro_complete_selreset(ioaddr) { \						lp->stats.tx_errors++;\						eepro_sel_reset(ioaddr);\						lp->tx_end = \							lp->xmt_lower_limit;\						lp->tx_start = lp->tx_end;\						lp->tx_last = 0;\						dev->trans_start = jiffies;\						netif_wake_queue(dev);\						eepro_en_rx(ioaddr);\					}/* Check for a network adaptor of this type, and return '0' if one exists.   If dev->base_addr == 0, probe all likely locations.   If dev->base_addr == 1, always return failure.   If dev->base_addr == 2, allocate space for the device and return success   (detachable devices only).   */int __init eepro_probe(struct net_device *dev){	int i;	int base_addr = dev->base_addr;	SET_MODULE_OWNER(dev);#ifdef PnPWakeup	/* XXXX for multiple cards should this only be run once? */	/* Wakeup: */	#define WakeupPort 0x279	#define WakeupSeq    {0x6A, 0xB5, 0xDA, 0xED, 0xF6, 0xFB, 0x7D, 0xBE,\	                      0xDF, 0x6F, 0x37, 0x1B, 0x0D, 0x86, 0xC3, 0x61,\	                      0xB0, 0x58, 0x2C, 0x16, 0x8B, 0x45, 0xA2, 0xD1,\	                      0xE8, 0x74, 0x3A, 0x9D, 0xCE, 0xE7, 0x73, 0x43}	{		unsigned short int WS[32]=WakeupSeq;		if (check_region(WakeupPort, 2)==0) {			if (net_debug>5)				printk(KERN_DEBUG "Waking UP\n");			outb_p(0,WakeupPort);			outb_p(0,WakeupPort);			for (i=0; i<32; i++) {				outb_p(WS[i],WakeupPort);				if (net_debug>5) printk(KERN_DEBUG ": %#x ",WS[i]);			}		} else printk(KERN_WARNING "Checkregion Failed!\n");	}#endif	if (base_addr > 0x1ff)		/* Check a single specified location. */		return eepro_probe1(dev, base_addr);	else if (base_addr != 0)	/* Don't probe at all. */		return -ENXIO;	for (i = 0; eepro_portlist[i]; i++) {		int ioaddr = eepro_portlist[i];		if (check_region(ioaddr, EEPRO_IO_EXTENT))			continue;		if (eepro_probe1(dev, ioaddr) == 0)			return 0;	}	return -ENODEV;}static void __init printEEPROMInfo(short ioaddr, struct net_device *dev){	unsigned short Word;	int i,j;	for (i=0, j=ee_Checksum; i<ee_SIZE; i++)		j+=read_eeprom(ioaddr,i,dev);	printk(KERN_DEBUG "Checksum: %#x\n",j&0xffff);	Word=read_eeprom(ioaddr, 0, dev);	printk(KERN_DEBUG "Word0:\n");	printk(KERN_DEBUG " Plug 'n Pray: %d\n",GetBit(Word,ee_PnP));	printk(KERN_DEBUG " Buswidth: %d\n",(GetBit(Word,ee_BusWidth)+1)*8 );	printk(KERN_DEBUG " AutoNegotiation: %d\n",GetBit(Word,ee_AutoNeg));	printk(KERN_DEBUG " IO Address: %#x\n", (Word>>ee_IO0)<<4);	if (net_debug>4)  {		Word=read_eeprom(ioaddr, 1, dev);		printk(KERN_DEBUG "Word1:\n");		printk(KERN_DEBUG " INT: %d\n", Word & ee_IntMask);		printk(KERN_DEBUG " LI: %d\n", GetBit(Word,ee_LI));		printk(KERN_DEBUG " PC: %d\n", GetBit(Word,ee_PC));		printk(KERN_DEBUG " TPE/AUI: %d\n", GetBit(Word,ee_TPE_AUI));		printk(KERN_DEBUG " Jabber: %d\n", GetBit(Word,ee_Jabber));		printk(KERN_DEBUG " AutoPort: %d\n", GetBit(!Word,ee_Jabber));		printk(KERN_DEBUG " Duplex: %d\n", GetBit(Word,ee_Duplex));	}	Word=read_eeprom(ioaddr, 5, dev);	printk(KERN_DEBUG "Word5:\n");	printk(KERN_DEBUG " BNC: %d\n",GetBit(Word,ee_BNC_TPE));	printk(KERN_DEBUG " NumConnectors: %d\n",GetBit(Word,ee_NumConn));	printk(KERN_DEBUG " Has ");	if (GetBit(Word,ee_PortTPE)) printk(KERN_DEBUG "TPE ");	if (GetBit(Word,ee_PortBNC)) printk(KERN_DEBUG "BNC ");	if (GetBit(Word,ee_PortAUI)) printk(KERN_DEBUG "AUI ");	printk(KERN_DEBUG "port(s) \n");	Word=read_eeprom(ioaddr, 6, dev);	printk(KERN_DEBUG "Word6:\n");	printk(KERN_DEBUG " Stepping: %d\n",Word & ee_StepMask);	printk(KERN_DEBUG " BoardID: %d\n",Word>>ee_BoardID);	Word=read_eeprom(ioaddr, 7, dev);	printk(KERN_DEBUG "Word7:\n");	printk(KERN_DEBUG " INT to IRQ:\n");	for (i=0, j=0; i<15; i++)		if (GetBit(Word,i)) printk(KERN_DEBUG " INT%d -> IRQ %d;",j++,i);	printk(KERN_DEBUG "\n");}/* function to recalculate the limits of buffer based on rcv_ram */static void eepro_recalc (struct net_device *dev){	struct eepro_local *	lp;	lp = dev->priv;	lp->xmt_ram = RAM_SIZE - lp->rcv_ram;	if (lp->eepro == LAN595FX_10ISA) {		lp->xmt_lower_limit = XMT_START_10;		lp->xmt_upper_limit = (lp->xmt_ram - 2);		lp->rcv_lower_limit = lp->xmt_ram;		lp->rcv_upper_limit = (RAM_SIZE - 2);	}	else {		lp->rcv_lower_limit = RCV_START_PRO;		lp->rcv_upper_limit = (lp->rcv_ram - 2);		lp->xmt_lower_limit = lp->rcv_ram;		lp->xmt_upper_limit = (RAM_SIZE - 2);	}}/* prints boot-time info */static void eepro_print_info (struct net_device *dev){	struct eepro_local *	lp = dev->priv;	int			i;	const char *		ifmap[] = {"AUI", "10Base2", "10BaseT"};	i = inb(dev->base_addr + ID_REG);	printk(KERN_DEBUG " id: %#x ",i);	printk(KERN_DEBUG " io: %#x ", (unsigned)dev->base_addr);	switch (lp->eepro) {		case LAN595FX_10ISA:			printk(KERN_INFO "%s: Intel EtherExpress 10 ISA\n at %#x,",					dev->name, (unsigned)dev->base_addr);			break;		case LAN595FX:			printk(KERN_INFO "%s: Intel EtherExpress Pro/10+ ISA\n at %#x,", 					dev->name, (unsigned)dev->base_addr);			break;		case LAN595TX:			printk(KERN_INFO "%s: Intel EtherExpress Pro/10 ISA at %#x,",					dev->name, (unsigned)dev->base_addr);			break;		case LAN595:			printk(KERN_INFO "%s: Intel 82595-based lan card at %#x,", 					dev->name, (unsigned)dev->base_addr);	}	for (i=0; i < 6; i++)		printk(KERN_INFO "%c%02x", i ? ':' : ' ', dev->dev_addr[i]);	if (net_debug > 3)		printk(KERN_DEBUG ", %dK RCV buffer",				(int)(lp->rcv_ram)/1024);	if (dev->irq > 2)		printk(KERN_INFO ", IRQ %d, %s.\n", dev->irq, ifmap[dev->if_port]);	else 		printk(KERN_INFO ", %s.\n", ifmap[dev->if_port]);	if (net_debug > 3) {		i = read_eeprom(dev->base_addr, 5, dev);		if (i & 0x2000) /* bit 13 of EEPROM word 5 */			printk(KERN_DEBUG "%s: Concurrent Processing is "				"enabled but not used!\n", dev->name);	}	/* Check the station address for the manufacturer's code */	if (net_debug>3)		printEEPROMInfo(dev->base_addr, dev);}/* This is the real probe routine.  Linux has a history of friendly device   probes on the ISA bus.  A good device probe avoids doing writes, and   verifies that the correct device exists and functions.  */static int __init eepro_probe1(struct net_device *dev, short ioaddr){	unsigned short station_addr[6], id, counter;	int i, j, irqMask, retval = 0;	struct eepro_local *lp;	enum iftype { AUI=0, BNC=1, TPE=2 };	/* Now, we are going to check for the signature of the	   ID_REG (register 2 of bank 0) */	id=inb(ioaddr + ID_REG);	if (((id) & ID_REG_MASK) != ID_REG_SIG) {		retval = -ENODEV;		goto exit;	}		/* We seem to have the 82595 signature, let's		   play with its counter (last 2 bits of		   register 2 of bank 0) to be sure. */		counter = (id & R_ROBIN_BITS);	if (((id=inb(ioaddr+ID_REG)) & R_ROBIN_BITS)!=(counter + 0x40)) {		retval = -ENODEV;		goto exit;	}			/* Initialize the device structure */			dev->priv = kmalloc(sizeof(struct eepro_local), GFP_KERNEL);	if (!dev->priv) {		retval = -ENOMEM;		goto exit;	}			memset(dev->priv, 0, sizeof(struct eepro_local));			lp = (struct eepro_local *)dev->priv;	/* default values */	lp->eepro = 0;	lp->xmt_bar = XMT_BAR_PRO;	lp->xmt_lower_limit_reg = XMT_LOWER_LIMIT_REG_PRO;	lp->xmt_upper_limit_reg = XMT_UPPER_LIMIT_REG_PRO;	lp->eeprom_reg = EEPROM_REG_PRO;			/* Now, get the ethernet hardware address from			   the EEPROM */			station_addr[0] = read_eeprom(ioaddr, 2, dev);			/* FIXME - find another way to know that we've found			 * an Etherexpress 10			 */			if (station_addr[0] == 0x0000 ||			    station_addr[0] == 0xffff) {				lp->eepro = LAN595FX_10ISA;		lp->eeprom_reg = EEPROM_REG_10;		lp->xmt_lower_limit_reg = XMT_LOWER_LIMIT_REG_10;		lp->xmt_upper_limit_reg = XMT_UPPER_LIMIT_REG_10;		lp->xmt_bar = XMT_BAR_10;				station_addr[0] = read_eeprom(ioaddr, 2, dev);			}			station_addr[1] = read_eeprom(ioaddr, 3, dev);			station_addr[2] = read_eeprom(ioaddr, 4, dev);	if (!lp->eepro) {		if (read_eeprom(ioaddr,7,dev)== ee_FX_INT2IRQ)			lp->eepro = 2;		else if (station_addr[2] == SA_ADDR1)			lp->eepro = 1;			}			/* Fill in the 'dev' fields. */			dev->base_addr = ioaddr;	for (i=0; i < 6; i++)				dev->dev_addr[i] = ((unsigned char *) station_addr)[5-i];	/* RX buffer must be more than 3K and less than 29K */	if (dev->mem_end < 3072 || dev->mem_end > 29696)		lp->rcv_ram = RCV_DEFAULT_RAM;	/* calculate {xmt,rcv}_{lower,upper}_limit */	eepro_recalc(dev);			if (GetBit( read_eeprom(ioaddr, 5, dev),ee_BNC_TPE))				dev->if_port = BNC;	else		dev->if_port = TPE;	if ((dev->irq < 2) && (lp->eepro!=0)) {				i = read_eeprom(ioaddr, 1, dev);				irqMask = read_eeprom(ioaddr, 7, dev);				i &= 0x07; /* Mask off INT number */				for (j=0; ((j<16) && (i>=0)); j++) {					if ((irqMask & (1<<j))!=0) {						if (i==0) {							dev->irq = j;							break; /* found bit corresponding to irq */						}						i--; /* count bits set in irqMask */					}				}				if (dev->irq < 2) {			printk(KERN_ERR " Duh! illegal interrupt vector stored in EEPROM.\n");					kfree(dev->priv);			retval = -ENODEV;			goto freeall;				} else			if (dev->irq==2) dev->irq = 9;			}			/* Grab the region so we can find another board if autoIRQ fails. */			request_region(ioaddr, EEPRO_IO_EXTENT, dev->name);			((struct eepro_local *)dev->priv)->lock = SPIN_LOCK_UNLOCKED;			dev->open               = eepro_open;			dev->stop               = eepro_close;			dev->hard_start_xmit    = eepro_send_packet;			dev->get_stats          = eepro_get_stats;			dev->set_multicast_list = &set_multicast_list;			dev->tx_timeout		= eepro_tx_timeout;			dev->watchdog_timeo	= TX_TIMEOUT;			/* Fill in the fields of the device structure with			   ethernet generic values */			ether_setup(dev);	/* print boot time info */	eepro_print_info(dev);	/* reset 82595 */			eepro_reset(ioaddr);exit:	return retval;freeall:	kfree(dev->priv);	goto exit;}/* Open/initialize the board.  This is called (in the current kernel)   sometime after booting when the 'ifconfig' program is run.   This routine should set everything up anew at each open, even   registers that "should" only need to be set once at boot, so that   there is non-reboot way to recover if something goes wrong.   */static char irqrmap[] = {-1,-1,0,1,-1,2,-1,-1,-1,0,3,4,-1,-1,-1,-1};static char irqrmap2[] = {-1,-1,4,0,1,2,-1,3,-1,4,5,6,7,-1,-1,-1};static int	eepro_grab_irq(struct net_device *dev){	int irqlist[] = { 3, 4, 5, 7, 9, 10, 11, 12, 0 };	int *irqp = irqlist, temp_reg, ioaddr = dev->base_addr;	eepro_sw2bank1(ioaddr); /* be CAREFUL, BANK 1 now */	/* Enable the interrupt line. */	eepro_en_intline(ioaddr);	/* be CAREFUL, BANK 0 now */	eepro_sw2bank0(ioaddr);	/* clear all interrupts */	eepro_clear_int(ioaddr);

⌨️ 快捷键说明

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