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

📄 ns8390.c

📁 freebsd v4.4内核源码
💻 C
📖 第 1 页 / 共 2 页
字号:
}/**************************************************************************ETH_RESET - Reset adapter**************************************************************************/eth_reset(){	int i;	if (eth_flags & FLAG_790)		outb(eth_nic_base+D8390_P0_COMMAND,			D8390_COMMAND_PS0 | D8390_COMMAND_STP);	else		outb(eth_nic_base+D8390_P0_COMMAND,			D8390_COMMAND_PS0 | D8390_COMMAND_RD2 |			D8390_COMMAND_STP);	if (eth_flags & FLAG_16BIT)		outb(eth_nic_base+D8390_P0_DCR, 0x49);	else		outb(eth_nic_base+D8390_P0_DCR, 0x48);	outb(eth_nic_base+D8390_P0_RBCR0, 0);	outb(eth_nic_base+D8390_P0_RBCR1, 0);	outb(eth_nic_base+D8390_P0_RCR, 4);	/* allow broadcast frames */	outb(eth_nic_base+D8390_P0_TCR, 2);	outb(eth_nic_base+D8390_P0_TPSR, eth_tx_start);	outb(eth_nic_base+D8390_P0_PSTART, eth_tx_start + D8390_TXBUF_SIZE);	if (eth_flags & FLAG_790) outb(eth_nic_base + 0x09, 0);	outb(eth_nic_base+D8390_P0_PSTOP, eth_memsize);	outb(eth_nic_base+D8390_P0_BOUND, eth_tx_start + D8390_TXBUF_SIZE);	outb(eth_nic_base+D8390_P0_ISR, 0xFF);	outb(eth_nic_base+D8390_P0_IMR, 0);	if (eth_flags & FLAG_790)		outb(eth_nic_base+D8390_P0_COMMAND, D8390_COMMAND_PS1 |			D8390_COMMAND_STP);	else		outb(eth_nic_base+D8390_P0_COMMAND, D8390_COMMAND_PS1 |			D8390_COMMAND_RD2 | D8390_COMMAND_STP);	for (i=0; i<6; i++)#ifdef	INCLUDE_EGY		outb(eth_nic_base+D8390_P1_PAR0+i*2, eth_node_addr[i]); /* for EGY-98 XXX HN2 */#else		outb(eth_nic_base+D8390_P1_PAR0+i, eth_node_addr[i]);#endif	for (i=0; i<6; i++)		outb(eth_nic_base+D8390_P1_MAR0+i, 0xFF);	outb(eth_nic_base+D8390_P1_CURR, eth_tx_start + D8390_TXBUF_SIZE+1);	if (eth_flags & FLAG_790)		outb(eth_nic_base+D8390_P0_COMMAND, D8390_COMMAND_PS0 |			D8390_COMMAND_STA);	else		outb(eth_nic_base+D8390_P0_COMMAND, D8390_COMMAND_PS0 |			D8390_COMMAND_RD2 | D8390_COMMAND_STA);	outb(eth_nic_base+D8390_P0_ISR, 0xFF);	outb(eth_nic_base+D8390_P0_TCR, 0);#ifdef INCLUDE_3COM        if (eth_vendor == VENDOR_3COM) {        /*         * No way to tell whether or not we're supposed to use         * the 3Com's transceiver unless the user tells us.         * 'aui' should have some compile time default value         * which can be changed from the command menu.         */                if (aui)                        outb(eth_asic_base + _3COM_CR, 0);                else                        outb(eth_asic_base + _3COM_CR, _3COM_CR_XSEL);        }#endif	return(1);}/**************************************************************************ETH_TRANSMIT - Transmit a frame**************************************************************************/eth_transmit(d,t,s,p)	char *d;			/* Destination */	unsigned short t;		/* Type */	unsigned short s;		/* size */	char *p;			/* Packet */{	unsigned char c;#ifdef INCLUDE_3COM        if (eth_vendor == VENDOR_3COM) {                bcopy(d, eth_bmem, 6);                             /* dst */                bcopy(eth_node_addr, eth_bmem+6, ETHER_ADDR_LEN);  /* src */                *(eth_bmem+12) = t>>8;                             /* type */                *(eth_bmem+13) = t;                bcopy(p, eth_bmem+14, s);                s += 14;		while (s < ETHER_MIN_LEN) *(eth_bmem+(s++)) = 0;        }#endif#ifdef INCLUDE_WD	if (eth_vendor == VENDOR_WD) {		/* Memory interface */		if (eth_flags & FLAG_16BIT) {			outb(eth_asic_base + WD_LAAR, eth_laar | WD_LAAR_M16EN);#ifndef PC98			inb(0x84);#else			(void)outb(0x5f,0);#endif		}		if (eth_flags & FLAG_790) {			outb(eth_asic_base + WD_MSR, WD_MSR_MENB);#ifndef PC98			inb(0x84);#else			(void)outb(0x5f,0);#endif		}#ifndef PC98		inb(0x84);#else		(void)outb(0x5f,0);#endif		bcopy(d, eth_bmem, 6);				   /* dst */		bcopy(eth_node_addr, eth_bmem+6, ETHER_ADDR_LEN);  /* src */		*(eth_bmem+12) = t>>8;				   /* type */		*(eth_bmem+13) = t;		bcopy(p, eth_bmem+14, s);		s += 14;		while (s < ETHER_MIN_LEN) *(eth_bmem+(s++)) = 0;		if (eth_flags & FLAG_790) {			outb(eth_asic_base + WD_MSR, 0);#ifndef PC98			inb(0x84);#else			(void)outb(0x5f,0);#endif		}		if (eth_flags & FLAG_16BIT) {			outb(eth_asic_base + WD_LAAR, eth_laar & ~WD_LAAR_M16EN);#ifndef PC98			inb(0x84);#else			(void)outb(0x5f,0);#endif		}	}#endif#if defined(INCLUDE_NE) || defined(INCLUDE_LGY) || defined(INCLUDE_EGY)	if (eth_vendor == VENDOR_NOVELL) {	/* Programmed I/O */		unsigned short type;		type = (t >> 8) | (t << 8);		eth_pio_write(d, eth_tx_start<<8, 6);		eth_pio_write(eth_node_addr, (eth_tx_start<<8)+6, 6);		eth_pio_write(&type, (eth_tx_start<<8)+12, 2);		eth_pio_write(p, (eth_tx_start<<8)+14, s);		s += 14;		if (s < ETHER_MIN_LEN) s = ETHER_MIN_LEN;	}#endif#ifndef	PC98	twiddle();#else	if (twiddle_counter-- <= 0) {		twiddle();		twiddle_counter = twiddle_max;	}#endif	if (eth_flags & FLAG_790)		outb(eth_nic_base+D8390_P0_COMMAND, D8390_COMMAND_PS0 |			D8390_COMMAND_STA);	else		outb(eth_nic_base+D8390_P0_COMMAND, D8390_COMMAND_PS0 |			D8390_COMMAND_RD2 | D8390_COMMAND_STA);	outb(eth_nic_base+D8390_P0_TPSR, eth_tx_start);	outb(eth_nic_base+D8390_P0_TBCR0, s);	outb(eth_nic_base+D8390_P0_TBCR1, s>>8);	if (eth_flags & FLAG_790)		outb(eth_nic_base+D8390_P0_COMMAND, D8390_COMMAND_PS0 |			D8390_COMMAND_TXP | D8390_COMMAND_STA);	else		outb(eth_nic_base+D8390_P0_COMMAND, D8390_COMMAND_PS0 |			D8390_COMMAND_TXP | D8390_COMMAND_RD2 |			D8390_COMMAND_STA);	return(0);}voidset_twiddle_max(int max){	twiddle_max = max;}/**************************************************************************ETH_POLL - Wait for a frame**************************************************************************/eth_poll(){	int ret = 0;	unsigned short type = 0;	unsigned char bound,curr,rstat;	unsigned short len, copylen;	unsigned short pktoff;	unsigned char *p;	struct ringbuffer pkthdr;	rstat = inb(eth_nic_base+D8390_P0_RSR);	if (rstat & D8390_RSTAT_OVER) {		eth_reset();		return(0);	}	if (!(rstat & D8390_RSTAT_PRX)) return(0);	bound = inb(eth_nic_base+D8390_P0_BOUND)+1;	if (bound == eth_memsize) bound = eth_tx_start + D8390_TXBUF_SIZE;	outb(eth_nic_base+D8390_P0_COMMAND, D8390_COMMAND_PS1);	curr = inb(eth_nic_base+D8390_P1_CURR);	outb(eth_nic_base+D8390_P0_COMMAND, D8390_COMMAND_PS0);	if (curr == eth_memsize) curr=eth_tx_start + D8390_TXBUF_SIZE;	if (curr == bound) return(0);	if (eth_vendor == VENDOR_WD) {		if (eth_flags & FLAG_16BIT) {			outb(eth_asic_base + WD_LAAR, eth_laar | WD_LAAR_M16EN);#ifndef PC98			inb(0x84);#else			(void)outb(0x5f,0);#endif		}		if (eth_flags & FLAG_790) {			outb(eth_asic_base + WD_MSR, WD_MSR_MENB);#ifndef PC98			inb(0x84);#else			(void)outb(0x5f,0);#endif		}#ifndef PC98		inb(0x84);#else		(void)outb(0x5f,0);#endif	}	pktoff = (bound << 8);	if (eth_flags & FLAG_PIO)		eth_pio_read(pktoff, &pkthdr, 4);	else		bcopy(eth_rmem + pktoff, &pkthdr, 4);	len = pkthdr.len - 4; /* sub CRC */	pktoff += 4;	if (len > 1514) len = 1514;	bound = pkthdr.bound;		/* New bound ptr */	if ( (pkthdr.status & D8390_RSTAT_PRX) && (len > 14) && (len < 1518)) {		p = packet;		packetlen = copylen = len;		len = (eth_memsize << 8) - pktoff;		if (packetlen > len) {		/* We have a wrap-around */			if (eth_flags & FLAG_PIO)				eth_pio_read(pktoff, p, len);			else				bcopy(eth_rmem + pktoff, p, len);			pktoff = (eth_tx_start + D8390_TXBUF_SIZE) << 8;			p += len;			copylen -= len;		}		if (eth_flags & FLAG_PIO)			eth_pio_read(pktoff, p, copylen);		else			bcopy(eth_rmem + pktoff, p, copylen);		type = (packet[12]<<8) | packet[13];		ret = 1;	}	if (eth_vendor == VENDOR_WD) {		if (eth_flags & FLAG_790) {			outb(eth_asic_base + WD_MSR, 0);#ifndef PC98			inb(0x84);#else			(void)outb(0x5f,0);#endif		}		if (eth_flags & FLAG_16BIT) {			outb(eth_asic_base + WD_LAAR, eth_laar &				~WD_LAAR_M16EN);#ifndef PC98			inb(0x84);#else			(void)outb(0x5f,0);#endif		}#ifndef PC98		inb(0x84);#else		(void)outb(0x5f,0);#endif	}	if (bound == (eth_tx_start + D8390_TXBUF_SIZE))		bound = eth_memsize;	outb(eth_nic_base+D8390_P0_BOUND, bound-1);	if (ret && (type == ARP)) {		struct arprequest *arpreq;		unsigned long reqip;		arpreq = (struct arprequest *)&packet[ETHER_HDR_LEN];		convert_ipaddr(&reqip, arpreq->tipaddr);		if ((ntohs(arpreq->opcode) == ARP_REQUEST) &&			(reqip == arptable[ARP_CLIENT].ipaddr)) {				arpreq->opcode = htons(ARP_REPLY);				bcopy(arpreq->sipaddr, arpreq->tipaddr, 4);				bcopy(arpreq->shwaddr, arpreq->thwaddr, 6);				bcopy(arptable[ARP_CLIENT].node, arpreq->shwaddr, 6);				convert_ipaddr(arpreq->sipaddr, &reqip);				eth_transmit(arpreq->thwaddr, ARP, sizeof(struct arprequest),					arpreq);				return(0);		}	}	return(ret);}#if defined(INCLUDE_NE) || defined(INCLUDE_LGY) || defined(INCLUDE_EGY)/**************************************************************************ETH_PIO_READ - Read a frame via Programmed I/O**************************************************************************/eth_pio_read(src, dst, cnt)	unsigned short src;	unsigned char *dst;	unsigned short cnt;{	if (cnt & 1) cnt++;	outb(eth_nic_base + D8390_P0_COMMAND, D8390_COMMAND_RD2 |		D8390_COMMAND_STA);	outb(eth_nic_base + D8390_P0_RBCR0, cnt);	outb(eth_nic_base + D8390_P0_RBCR1, cnt>>8);	outb(eth_nic_base + D8390_P0_RSAR0, src);	outb(eth_nic_base + D8390_P0_RSAR1, src>>8);	outb(eth_nic_base + D8390_P0_COMMAND, D8390_COMMAND_RD0 |		D8390_COMMAND_STA);	if (eth_flags & FLAG_16BIT) {		while (cnt) {			*((unsigned short *)dst) = inw(eth_asic_base + NE_DATA);			dst += 2;			cnt -= 2;		}	}	else {		while (cnt--)			*(dst++) = inb(eth_asic_base + NE_DATA);	}}/**************************************************************************ETH_PIO_WRITE - Write a frame via Programmed I/O**************************************************************************/eth_pio_write(src, dst, cnt)	unsigned char *src;	unsigned short dst;	unsigned short cnt;{	outb(eth_nic_base + D8390_P0_COMMAND, D8390_COMMAND_RD2 |		D8390_COMMAND_STA);	outb(eth_nic_base + D8390_P0_ISR, D8390_ISR_RDC);	outb(eth_nic_base + D8390_P0_RBCR0, cnt);	outb(eth_nic_base + D8390_P0_RBCR1, cnt>>8);	outb(eth_nic_base + D8390_P0_RSAR0, dst);	outb(eth_nic_base + D8390_P0_RSAR1, dst>>8);	outb(eth_nic_base + D8390_P0_COMMAND, D8390_COMMAND_RD1 |		D8390_COMMAND_STA);	if (eth_flags & FLAG_16BIT) {		if (cnt & 1) cnt++;		/* Round up */		while (cnt) {			outw(eth_asic_base + NE_DATA, *((unsigned short *)src));			src += 2;			cnt -= 2;		}	}	else {		while (cnt--)			outb(eth_asic_base + NE_DATA, *(src++));	}	cnt = 200;	while((inb(eth_nic_base + D8390_P0_ISR) & D8390_ISR_RDC)		!= D8390_ISR_RDC && --cnt);}#else/**************************************************************************ETH_PIO_READ - Dummy routine when NE2000 not compiled in**************************************************************************/eth_pio_read() {}#endif

⌨️ 快捷键说明

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