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

📄 ns8390.c

📁 freebsd v4.4内核源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/**************************************************************************NETBOOT -  BOOTP/TFTP Bootstrap ProgramAuthor: Martin Renters  Date: May/94 This code is based heavily on David Greenman's if_ed.c driver Copyright (C) 1993-1994, David Greenman, Martin Renters.  This software may be used, modified, copied, distributed, and sold, in  both source and binary form provided that the above copyright and these  terms are retained. Under no circumstances are the authors responsible for  the proper functioning of this software, nor do the authors assume any  responsibility for damages incurred with its use.3c503 support added by Bill Paul (wpaul@ctr.columbia.edu) on 11/15/94SMC8416 support added by Bill Paul (wpaul@ctr.columbia.edu) on 12/25/94**************************************************************************/DELAY(int x){ volatile long a, b, l;   for (x; x>0; x--) b=a;}  #include "netboot.h"#include "ns8390.h"#ifdef _3COM_USE_AUIshort aui=1;#elseshort aui=0;#endifunsigned short eth_nic_base;unsigned short eth_asic_base;unsigned char  eth_tx_start;unsigned char  eth_laar;unsigned char  eth_flags;unsigned char  eth_vendor;unsigned char  eth_memsize;unsigned char  *eth_bmem;unsigned char  *eth_rmem;unsigned char  *eth_node_addr;#ifdef	PC98int twiddle_max = 1;int twiddle_counter = 0;#endif/**************************************************************************The following two variables are used externally**************************************************************************/char eth_driver[] = "ed0";char packet[ETHER_MAX_LEN];int  packetlen;#ifdef PC98#ifdef	INCLUDE_LGYint type98 = TYPE98_LGY;#endif#ifdef	INCLUDE_EGYint type98 = TYPE98_EGY;#endif#endif#if	defined(INCLUDE_NE) || defined(INCLUDE_LGY) || defined(INCLUDE_EGY)static unsigned short ne_base_list[]= {#ifdef	NE_BASE	NE_BASE,#endif	0xff80, 0xff40, 0xff00, 0xfec0,	0x280, 0x300, 0};#endif/**************************************************************************ETH_PROBE - Look for an adapter**************************************************************************/eth_probe(){	int i;	struct wd_board *brd;	char *name;	unsigned short chksum;	unsigned char c;	eth_vendor = VENDOR_NONE;#ifdef INCLUDE_WD	/******************************************************************	Search for WD/SMC cards	******************************************************************/	for (eth_asic_base = WD_LOW_BASE; eth_asic_base <= WD_HIGH_BASE;		eth_asic_base += 0x20) {		chksum = 0;		/* Check for WD/SMC card by checking ethernet address */		if (inb(eth_asic_base+8) != 0) continue;		if (inb(eth_asic_base+9) != 0) continue;		if (inb(eth_asic_base+10) != 0xC0) continue;		for (i=8; i<16; i++)			chksum += inb(i+eth_asic_base);		if ((chksum & 0x00FF) == 0x00FF)			break;	}	if (eth_asic_base <= WD_HIGH_BASE) { /* We've found a board */		eth_vendor = VENDOR_WD;		eth_nic_base = eth_asic_base + WD_NIC_ADDR;		c = inb(eth_asic_base+WD_BID);	/* Get board id */		for (brd = wd_boards; brd->name; brd++)			if (brd->id == c) break;		if (!brd->name) {			printf("\nUnknown Ethernet type %x\n", c);			return(0);	/* Unknown type */		}		eth_flags = brd->flags;		eth_memsize = brd->memsize;		eth_tx_start = 0;		if ((c == TYPE_WD8013EP) &&			(inb(eth_asic_base + WD_ICR) & WD_ICR_16BIT)) {				eth_flags = FLAG_16BIT;				eth_memsize = MEM_16384;		}		if ((c & WD_SOFTCONFIG) && (!(eth_flags & FLAG_790))) {			eth_bmem = (char *)(0x80000 |			 ((inb(eth_asic_base + WD_MSR) & 0x3F) << 13));		} else			eth_bmem = (char *)WD_DEFAULT_MEM;		if (brd->id == TYPE_SMC8216T || brd->id == TYPE_SMC8216C) {			(unsigned int) *(eth_bmem + 8192) = (unsigned int)0;			if ((unsigned int) *(eth_bmem + 8192)) {				brd += 2;				eth_memsize = brd->memsize;			}		}		outb(eth_asic_base + WD_MSR, 0x80);	/* Reset */		printf("\n%s base 0x%x, memory 0x%X, addr ",			brd->name, eth_asic_base, eth_bmem);		for (i=0; i<6; i++) {			printf("%b",(int)(arptable[ARP_CLIENT].node[i] =				inb(i+eth_asic_base+WD_LAR)));				if (i < 5) printf (":");		}		if (eth_flags & FLAG_790) {			outb(eth_asic_base+WD_MSR, WD_MSR_MENB);			outb(eth_asic_base+0x04, (inb(eth_asic_base+0x04) |				0x80));			outb(eth_asic_base+0x0B,				(((unsigned)eth_bmem >> 13) & 0x0F) |				(((unsigned)eth_bmem >> 11) & 0x40) |				(inb(eth_asic_base+0x0B) & 0xB0));			outb(eth_asic_base+0x04, (inb(eth_asic_base+0x04) &				~0x80));		} else {			outb(eth_asic_base+WD_MSR,				(((unsigned)eth_bmem >> 13) & 0x3F) | 0x40);		}		if (eth_flags & FLAG_16BIT) {			if (eth_flags & FLAG_790) {				eth_laar = inb(eth_asic_base + WD_LAAR);				outb(eth_asic_base + WD_LAAR, WD_LAAR_M16EN);#ifndef PC98				inb(0x84);#else				(void)outb(0x5f,0);#endif			} else {				outb(eth_asic_base + WD_LAAR, (eth_laar =					WD_LAAR_M16EN | WD_LAAR_L16EN | 1));			}		}		goto found_board;	}#endif#ifdef INCLUDE_3COM        /******************************************************************        Search for 3Com 3c503 if no WD/SMC cards        ******************************************************************/        if (eth_vendor == VENDOR_NONE) {                eth_asic_base = _3COM_BASE + _3COM_ASIC_OFFSET;                eth_nic_base = _3COM_BASE;                eth_vendor = VENDOR_3COM;        /*         * Note that we use the same settings for both 8 and 16 bit cards:         * both have an 8K bank of memory at page 1 while only the 16 bit         * cards have a bank at page 0.         */                eth_memsize = MEM_16384;                eth_tx_start = 32;        /* Check our base address */                switch(inb(eth_asic_base + _3COM_BCFR)) {                        case _3COM_BCFR_300:                                if ((int)eth_nic_base != 0x300)                                        return(0);                                break;                        case _3COM_BCFR_310:                                if ((int)eth_nic_base != 0x310)                                        return(0);                                break;                        case _3COM_BCFR_330:                                if ((int)eth_nic_base != 0x330)                                        return(0);                                break;                        case _3COM_BCFR_350:                                if ((int)eth_nic_base != 0x350)                                        return(0);                                break;                        case _3COM_BCFR_250:                                if ((int)eth_nic_base != 0x250)                                        return(0);                                break;                        case _3COM_BCFR_280:                                if ((int)eth_nic_base != 0x280)                                        return(0);                                break;                        case _3COM_BCFR_2A0:                                if ((int)eth_nic_base != 0x2a0)                                        return(0);                                break;                        case _3COM_BCFR_2E0:                                if ((int)eth_nic_base != 0x2e0)                                        return(0);                                break;                        default:                                return (0);                }        /* Now get the shared memory address */                switch (inb(eth_asic_base + _3COM_PCFR)) {                        case _3COM_PCFR_DC000:                                eth_bmem = (char *)0xdc000;                                break;                        case _3COM_PCFR_D8000:                                eth_bmem = (char *)0xd8000;                                break;                        case _3COM_PCFR_CC000:                                eth_bmem = (char *)0xcc000;                                break;                        case _3COM_PCFR_C8000:                                eth_bmem = (char *)0xc8000;                                break;                        default:                                return (0);                        }        /* Need this to make eth_poll() happy. */                eth_rmem = eth_bmem - 0x2000;        /* Reset NIC and ASIC */                outb (eth_asic_base + _3COM_CR , _3COM_CR_RST | _3COM_CR_XSEL);                outb (eth_asic_base + _3COM_CR , _3COM_CR_XSEL);        /* Get our ethernet address */                outb(eth_asic_base + _3COM_CR, _3COM_CR_EALO | _3COM_CR_XSEL);                printf("\n3Com 3c503 base 0x%x, memory 0x%X addr ",                                 eth_nic_base, eth_bmem);                for (i=0; i<6; i++) {                        printf("%b",(int)(arptable[ARP_CLIENT].node[i] =			inb(eth_nic_base+i)));                        if (i < 5) printf (":");                }                outb(eth_asic_base + _3COM_CR, _3COM_CR_XSEL);        /*         * Initialize GA configuration register. Set bank and enable shared         * mem. We always use bank 1.         */                outb(eth_asic_base + _3COM_GACFR, _3COM_GACFR_RSEL |                                _3COM_GACFR_MBS0);                outb(eth_asic_base + _3COM_VPTR2, 0xff);                outb(eth_asic_base + _3COM_VPTR1, 0xff);                outb(eth_asic_base + _3COM_VPTR0, 0x00);        /*         * Clear memory and verify that it worked (we use only 8K)         */                bzero(eth_bmem, 0x2000);                for(i = 0; i < 0x2000; ++i)                        if (*((eth_bmem)+i)) {                                printf ("Failed to clear 3c503 shared mem.\n");                                return (0);                        }        /*         * Initialize GA page/start/stop registers.         */                outb(eth_asic_base + _3COM_PSTR, eth_tx_start);                outb(eth_asic_base + _3COM_PSPR, eth_memsize);		goto found_board;        }#endif#if	defined(INCLUDE_NE) || defined(INCLUDE_LGY) || defined(INCLUDE_EGY)	/******************************************************************	Search for NE1000/2000 if no WD/SMC or 3com cards	******************************************************************/	if (eth_vendor == VENDOR_NONE) {		char romdata[16], testbuf[32];		char test[] = "NE1000/2000 memory";		unsigned short *tent_base=ne_base_list;		eth_bmem = (char *)0;		/* No shared memory */ne_again:		eth_asic_base = *tent_base + NE_ASIC_OFFSET;		eth_nic_base = *tent_base;#ifdef	PC98		printf("Looking for LGY/EGY at 0x%x\n", eth_nic_base);#else		printf("Looking for NE1000/NE2000 at 0x%x\n", eth_nic_base);#endif		eth_vendor = VENDOR_NOVELL;		eth_flags = FLAG_PIO;		eth_memsize = MEM_16384;		eth_tx_start = 32;#ifdef GWETHER		outb(eth_asic_base + NE_RESET, 0);		DELAY(200);#endif		c = inb(eth_asic_base + NE_RESET);		outb(eth_asic_base + NE_RESET, c);		DELAY(5000);#ifndef PC98	        inb(0x84);#else		(void)outb(0x5f,0);#endif		outb(eth_nic_base + D8390_P0_COMMAND, D8390_COMMAND_STP |			D8390_COMMAND_RD2);		outb(eth_nic_base + D8390_P0_RCR, D8390_RCR_MON);		outb(eth_nic_base + D8390_P0_DCR, D8390_DCR_FT1 | D8390_DCR_LS);		outb(eth_nic_base + D8390_P0_PSTART, MEM_8192);		outb(eth_nic_base + D8390_P0_PSTOP, MEM_16384);		eth_pio_write(test, 8192, sizeof(test));		eth_pio_read(8192, testbuf, sizeof(test));		if (!bcompare(test, testbuf, sizeof(test))) {			eth_flags |= FLAG_16BIT;			eth_memsize = MEM_32768;			eth_tx_start = 64;			outb(eth_nic_base + D8390_P0_DCR, D8390_DCR_WTS |				D8390_DCR_FT1 | D8390_DCR_LS);			outb(eth_nic_base + D8390_P0_PSTART, MEM_16384);			outb(eth_nic_base + D8390_P0_PSTOP, MEM_32768);			eth_pio_write(test, 16384, sizeof(test));			eth_pio_read(16384, testbuf, sizeof(test));			if (!bcompare(testbuf, test, sizeof(test)))				if (*++tent_base)					goto ne_again;				else					return (0);		}		eth_pio_read(0, romdata, 16);#ifdef PC98		printf("\n%s base 0x%x, addr ",			type98 == TYPE98_LGY ? "Ethernet adapter LGY-98" :			(type98 == TYPE98_EGY ? "Ethernet adapter EGY-98" :			(type98 == TYPE98_ICM ? "Ethernet adapter ICM" :			"Unknown")),			eth_nic_base);#else		printf("\nNE1000/NE2000 (%d bit) base 0x%x, addr ",			eth_flags & FLAG_16BIT ? 16:8, eth_nic_base);#endif		for (i=0; i<6; i++) {			printf("%b",(int)(arptable[ARP_CLIENT].node[i] = romdata[i				+ ((eth_flags & FLAG_16BIT) ? i : 0)]));			if (i < 5) printf (":");		}		goto found_board;	}#endiffound_board:	printf("\n");	if (eth_vendor == VENDOR_NONE) return(0);        if (eth_vendor != VENDOR_3COM) eth_rmem = eth_bmem;	eth_node_addr = arptable[ARP_CLIENT].node;	eth_reset();	return(eth_vendor);

⌨️ 快捷键说明

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