ne.c

来自「移植网卡驱动时有用: uboot-1.1.4 中的rtl8019驱动: 分别」· C语言 代码 · 共 1,013 行 · 第 1/3 页

C
1,013
字号
		while ((inb_p(ioaddr + EN0_ISR) & ENISR_RESET) == 0)		if (jiffies - reset_start_time > 2*HZ/100) {			if (bad_card) {				printk(" (warning: no reset ack)");				break;			} else {				printk(" not found (no reset ack).\n");				ret = -ENODEV;				goto err_out;			}		}		outb_p(0xff, ioaddr + EN0_ISR);		/* Ack all intr. */	}	/* Read the 16 bytes of station address PROM.	   We must first initialize registers, similar to NS8390_init(eifdev, 0).	   We can't reliably read the SAPROM address without this.	   (I learned the hard way!). */	{		struct {unsigned char value, offset; } program_seq[] =		{			{E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, /* Select page 0*/			{0x48,	EN0_DCFG},	/* Set byte-wide (0x48) access. */			{0x00,	EN0_RCNTLO},	/* Clear the count regs. */			{0x00,	EN0_RCNTHI},			{0x00,	EN0_IMR},	/* Mask completion irq. */			{0xFF,	EN0_ISR},			{E8390_RXOFF, EN0_RXCR},	/* 0x20  Set to monitor */			{E8390_TXOFF, EN0_TXCR},	/* 0x02  and loopback mode. */			{32,	EN0_RCNTLO},			{0x00,	EN0_RCNTHI},			{0x00,	EN0_RSARLO},	/* DMA starting at 0x0000. */			{0x00,	EN0_RSARHI},			{E8390_RREAD+E8390_START, E8390_CMD},		};		for (i = 0; i < sizeof(program_seq)/sizeof(program_seq[0]); i++)			outb_p(program_seq[i].value, ioaddr + program_seq[i].offset);	}	for(i = 0; i < 32 /*sizeof(SA_prom)*/; i+=2) {		SA_prom[i] = inb(ioaddr + NE_DATAPORT);		SA_prom[i+1] = inb(ioaddr + NE_DATAPORT);//			printk("%p=%x,%x\n", ioaddr + NE_DATAPORT, SA_prom[i], SA_prom[i+1]);					if (SA_prom[i] != SA_prom[i+1])			wordlength = 1;	}#if defined(CONFIG_M5307) || defined(CONFIG_M5407)    {	outb_p(E8390_NODMA+E8390_PAGE1+E8390_STOP, ioaddr + E8390_CMD);	for(i = 0; i < 6; i++)	{		SA_prom[i] = inb(ioaddr + i + 1);	}	SA_prom[14] = SA_prom[15] = 0x57;    }#endif /* CONFIG_M5307 || CONFIG_M5407 */#if defined(CONFIG_NETtel) || defined(CONFIG_SECUREEDGEMP3)    {	unsigned char *ep;	static int nr = 0;	ep = (unsigned char *) (0xf0006000 + (nr++ * 6));	/*	 * MAC address should be in FLASH, check that it is valid.	 * If good use it, otherwise use the default.	 */	if (((ep[0] == 0xff) && (ep[1] == 0xff) && (ep[2] == 0xff) &&	    (ep[3] == 0xff) && (ep[4] == 0xff) && (ep[5] == 0xff)) ||	    ((ep[0] == 0) && (ep[1] == 0) && (ep[2] == 0) &&	    (ep[3] == 0) && (ep[4] == 0) && (ep[5] == 0))) {		ep = (unsigned char *) &ne_defethaddr[0];		ne_defethaddr[5]++;	}	for(i = 0; i < 6; i++)		SA_prom[i] = ep[i];	SA_prom[14] = SA_prom[15] = 0x57;#if 0	{		unsigned char val;		/*	 	 * Set ethernet interface to be AUI.	 	 */		val = inb_p(ioaddr + EN0_RCNTHI);		outb_p(0x01 , (ioaddr + EN0_RCNTHI));	}#endif#if defined(CONFIG_M5206e) && defined(CONFIG_NETtel)	wordlength = 1;	/* We must set the 8390 for 8bit mode. */	outb_p(0x48, ioaddr + EN0_DCFG);#endif	start_page = NESM_START_PG;	stop_page = NESM_STOP_PG;    }#elif defined(CONFIG_CFV240)    {	unsigned char *ep = (unsigned char *) 0xffc0406b;	/*	 * MAC address should be in FLASH, check that it is valid.	 * If good use it, otherwise use the default.	 */	if (((ep[0] == 0xff) && (ep[1] == 0xff) && (ep[2] == 0xff) &&	    (ep[3] == 0xff) && (ep[4] == 0xff) && (ep[5] == 0xff)) ||	    ((ep[0] == 0) && (ep[1] == 0) && (ep[2] == 0) &&	    (ep[3] == 0) && (ep[4] == 0) && (ep[5] == 0))) {		ep = (unsigned char *) &ne_defethaddr[0];		ne_defethaddr[5]++;	}	outb_p(E8390_NODMA+E8390_PAGE1+E8390_STOP, ioaddr + E8390_CMD);	for(i = 0; i < 6; i++)		SA_prom[i] = ep[i];	SA_prom[14] = SA_prom[15] = 0x57;    }#elif defined(CONFIG_M5206e)    {	outb_p(E8390_NODMA+E8390_PAGE1+E8390_STOP, ioaddr + E8390_CMD);	for(i = 0; i < 6; i++)	{		SA_prom[i] = inb(ioaddr + i + 1);	}	SA_prom[14] = SA_prom[15] = 0x57;    }#elif defined(CONFIG_BOARD_MBA44)    {	unsigned char ne_defethaddr[6] = {0x00, 0x80, 0x49, 0x12, 0x34, 0x56};//	ne_defethaddr[5]++;	printk("NE2000 driver modified by http://www.21spacetime.net\n");	outb_p(E8390_NODMA+E8390_PAGE1+E8390_STOP, ioaddr + E8390_CMD);	for(i = 0; i < 6; i++)	{		SA_prom[i] = ne_defethaddr[i];	}	SA_prom[14] = SA_prom[15] = 0x57;  	#if (ETH_ADDR_SFT==0)		wordlength = 1;		/* We must set the 8390 for 8bit mode. */        	outb_p(0x48, ioaddr + EN0_DCFG);  	#else		wordlength = 2;		/* We must set the 8390 for 16bit mode. */			outb_p(0x49, ioaddr + EN0_DCFG);   		//test----------------------------		printk("wordlength = 2\n");		//test----------------------------  	#endif    }#endif /* CONFIG_BOARD_MBA44 */#if !(defined(CONFIG_M5206e) && defined(CONFIG_NETtel))	if (wordlength == 2)	{	#ifndef CONFIG_COLDFIRE		for (i = 0; i < 16; i++)			SA_prom[i] = SA_prom[i+i];			//test----------------------------			printk("SA_prom[0]=%x,SA_prom[1]=%x,,SA_prom[2]=%x,SA_prom[3]=%x,SA_prom[4]=%x,SA_prom[5]=%x\n",SA_prom[0],SA_prom[1],SA_prom[2],SA_prom[3],SA_prom[4],SA_prom[5]);			//test----------------------------	#endif		/* We must set the 8390 for word mode. */		outb_p(0x49, ioaddr + EN0_DCFG);		start_page = NESM_START_PG;		stop_page = NESM_STOP_PG;		//test----------------------------		printk("start_page test\n");		//test----------------------------	} else {		start_page = NE1SM_START_PG;		stop_page = NE1SM_STOP_PG;	}#endif#if defined(CONFIG_CPU_H8300H)	start_page = NESM_START_PG;	stop_page = NESM_STOP_PG;	H8300_INIT_NE();#endif#if defined(CONFIG_BOARD_MBA44)	start_page = NESM_START_PG;	stop_page = NESM_STOP_PG;	//test----------------------------	printk("start_page test\n");	//test----------------------------#endif	//test SA_prom[14] SA_prom[15] SA_prom[0] SA_prom[1] SA_prom[2]	printk("SA_prom[14]=%x,SA_prom[15]=%x,,SA_prom[0]=%x,SA_prom[1]=%x,SA_prom[2]=%x\n",SA_prom[14],SA_prom[15],SA_prom[0],SA_prom[1],SA_prom[2]);	//test----------------------------	neX000 = (SA_prom[14] == 0x57  &&  SA_prom[15] == 0x57);	ctron =  (SA_prom[0] == 0x00 && SA_prom[1] == 0x00 && SA_prom[2] == 0x1d);	copam =  (SA_prom[14] == 0x49 && SA_prom[15] == 0x00);	/* Set up the rest of the parameters. */	if (!(neX000 || bad_card || copam)) 	{		name = (wordlength == 2) ? "NE2000" : "NE1000";	}	else if (ctron)	{		name = (wordlength == 2) ? "Ctron-8" : "Ctron-16";		start_page = 0x01;		stop_page = (wordlength == 2) ? 0x40 : 0x20;	}	else	{	#ifdef SUPPORT_NE_BAD_CLONES		/* Ack!  Well, there might be a *bad* NE*000 clone there.		   Check for total bogus addresses. */		for (i = 0; bad_clone_list[i].name8; i++)		{			if (SA_prom[0] == bad_clone_list[i].SAprefix[0] &&				SA_prom[1] == bad_clone_list[i].SAprefix[1] &&				SA_prom[2] == bad_clone_list[i].SAprefix[2])			{				if (wordlength == 2)				{					name = bad_clone_list[i].name16;				} else {					name = bad_clone_list[i].name8;				}				break;			}		}		if (bad_clone_list[i].name8 == NULL)		{			printk(" not found (invalid signature %2.2x %2.2x).\n",				SA_prom[14], SA_prom[15]);			ret = -ENXIO;			goto err_out;		}#else		printk(" not found.\n");		ret = -ENXIO;		goto err_out;#endif	}	if (dev->irq < 2)	{		unsigned long cookie = probe_irq_on();		outb_p(0x50, ioaddr + EN0_IMR);	/* Enable one interrupt. */		outb_p(0x00, ioaddr + EN0_RCNTLO);		outb_p(0x00, ioaddr + EN0_RCNTHI);		outb_p(E8390_RREAD+E8390_START, ioaddr); /* Trigger it... */		mdelay(10);		/* wait 10ms for interrupt to propagate */		outb_p(0x00, ioaddr + EN0_IMR); 		/* Mask it again. */		dev->irq = probe_irq_off(cookie);		if (ei_debug > 2)			printk(" autoirq is %d\n", dev->irq);	} else if (dev->irq == 2)		/* Fixup for users that don't know that IRQ 2 is really IRQ 9,		   or don't know which one to set. */		dev->irq = 9;	if (! dev->irq) {		printk(" failed to detect IRQ line.\n");		ret = -EAGAIN;		goto err_out;	}	/* Allocate dev->priv and fill in 8390 specific dev fields. */	if (ethdev_init(dev))	{        	printk (" unable to get memory for dev->priv.\n");        	ret = -ENOMEM;		goto err_out;	}	/* Snarf the interrupt now.  There's no point in waiting since we cannot	   share and the board will usually be enabled. */	ret = request_irq(dev->irq, ei_interrupt, 0, name, dev);#ifdef CONFIG_COLDFIRE	if (ret == 0)		ne2000_irqsetup(dev->irq);#endif	if (ret) {		printk (" unable to get IRQ %d (errno=%d).\n", dev->irq, ret);		goto err_out_kfree;	}	dev->base_addr = ioaddr;	for(i = 0; i < ETHER_ADDR_LEN; i++) {		printk(" %2.2x", SA_prom[i]);		dev->dev_addr[i] = SA_prom[i];	}	printk("\n%s: %s found at %#x, using IRQ %d\n",		dev->name, name, ioaddr, dev->irq);	ei_status.name = name;	ei_status.tx_start_page = start_page;	ei_status.stop_page = stop_page;	ei_status.word16 = (wordlength == 2);	ei_status.rx_start_page = start_page + TX_PAGES;#ifdef PACKETBUF_MEMSIZE	 /* Allow the packet buffer size to be overridden by know-it-alls. */	ei_status.stop_page = ei_status.tx_start_page + PACKETBUF_MEMSIZE;#endif	ei_status.reset_8390 = &ne_reset_8390;	ei_status.block_input = &ne_block_input;	ei_status.block_output = &ne_block_output;	ei_status.get_8390_hdr = &ne_get_8390_hdr;	ei_status.priv = 0;	dev->open = &ne_open;	dev->stop = &ne_close;	NS8390_init(dev, 0);	return 0;err_out_kfree:	kfree(dev->priv);	dev->priv = NULL;err_out:#if !defined(CONFIG_COLDFIRE) && !defined(CONFIG_CPU_H8300H)	release_region(ioaddr, NE_IO_EXTENT);#endif	return ret;}static int ne_open(struct net_device *dev){	ei_open(dev);	return 0;}static int ne_close(struct net_device *dev){	if (ei_debug > 1)		printk(KERN_DEBUG "%s: Shutting down ethercard.\n", dev->name);	ei_close(dev);	return 0;

⌨️ 快捷键说明

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