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

📄 rtl8139.c

📁 Minix3.11的源码。[MINIX 3是一个为高可靠性应用而设计的自由且简洁的类UNIX系统。]
💻 C
📖 第 1 页 / 共 5 页
字号:
#if DEAD_CODE	src_phys= rep->re_rx_buf + d_start;	cps = sys_physcopy(		NONE, PHYS_SEG, src_phys,		SELF, D, (vir_bytes) &rxstat, sizeof(rxstat));	if (cps != OK) printf("RTL8139: warning, sys_abscopy failed: %d\n", cps);#endif	if (rep->re_clear_rx)	{#if 0		printf("rl_readv: late buffer overflow\n");#endif		goto suspend;	/* Buffer overflow */	}	/* Should convert from little endian to host byte order */	if (!(rxstat & RL_RXS_ROK))	{		printf("rxstat = 0x%08lx\n", rxstat);		printf("d_start: 0x%x, d_end: 0x%x, rxstat: 0x%lx\n",			d_start, d_end, rxstat);		panic("rtl8139","received packet not OK", NO_NUM);	}	totlen= (rxstat >> RL_RXS_LEN_S);	if (totlen < 8 || totlen > 2*ETH_MAX_PACK_SIZE)	{		/* Someting went wrong */		printf(		"rl_readv: bad length (%u) in status 0x%08lx at offset 0x%x\n",			totlen, rxstat, d_start);		printf(		"d_start: 0x%x, d_end: 0x%x, totlen: %d, rxstat: 0x%lx\n",			d_start, d_end, totlen, rxstat);		panic(NULL, NULL, NO_NUM);	}#if 0	printf("d_start: 0x%x, d_end: 0x%x, totlen: %d, rxstat: 0x%x\n",		d_start, d_end, totlen, rxstat);#endif	if (totlen+4 > amount)	{		printf("rl_readv: packet not yet ready\n");		goto suspend;	}	/* Should subtract the CRC */	packlen= totlen - ETH_CRC_SIZE;	if (vectored)	{		int iov_offset = 0;#if 0		if ((cps = sys_umap(re_client, D, (vir_bytes) mp->DL_ADDR,			count * sizeof(rep->re_iovec[0]), &iov_src)) != OK)			printf("sys_umap failed: %d\n", cps);#endif		size= 0;		o= d_start+4;		src_phys= rep->re_rx_buf;		for (i= 0; i<count; i += IOVEC_NR,			iov_src += IOVEC_NR * sizeof(rep->re_iovec[0]),			iov_offset += IOVEC_NR * sizeof(rep->re_iovec[0]))		{			n= IOVEC_NR;			if (i+n > count)				n= count-i;#if 0			cps = sys_physcopy(NONE, PHYS_SEG, iov_src, SELF, D, (vir_bytes) rep->re_iovec, 				n * sizeof(rep->re_iovec[0]));	if (cps != OK) printf("RTL8139: warning, sys_abscopy failed: %d\n", cps);#else			cps = sys_vircopy(re_client, D, (vir_bytes) mp->DL_ADDR + iov_offset,				SELF, D, (vir_bytes) rep->re_iovec, n * sizeof(rep->re_iovec[0]));	if (cps != OK) printf("RTL8139: warning, sys_vircopy failed: %d (%d)\n", cps, __LINE__);#endif			for (j= 0, iovp= rep->re_iovec; j<n; j++, iovp++)			{				s= iovp->iov_size;				if (size + s > packlen)				{					assert(packlen > size);					s= packlen-size;				}#if 0				if (sys_umap(re_client, D, iovp->iov_addr, s, &dst_phys) != OK)				  panic("rtl8139","umap_local failed\n", NO_NUM);#endif				if (o >= RX_BUFSIZE)				{					o -= RX_BUFSIZE;					assert(o < RX_BUFSIZE);				}				if (o+s > RX_BUFSIZE)				{					assert(o<RX_BUFSIZE);					s1= RX_BUFSIZE-o;#if 0					cps = sys_abscopy(src_phys+o, dst_phys, s1);	if (cps != OK) printf("RTL8139: warning, sys_abscopy failed: %d\n", cps);					cps = sys_abscopy(src_phys, dst_phys+s1, s-s1);	if (cps != OK) printf("RTL8139: warning, sys_abscopy failed: %d\n", cps);#else					cps = sys_vircopy(SELF, D, (vir_bytes) rep->v_re_rx_buf+o,					re_client, D, iovp->iov_addr, s1);	if (cps != OK) printf("RTL8139: warning, sys_vircopy failed: %d (%d)\n", cps, __LINE__);					cps = sys_vircopy(SELF, D, (vir_bytes) rep->v_re_rx_buf,					re_client, D, iovp->iov_addr+s1, s-s1);	if (cps != OK) printf("RTL8139: warning, sys_vircopy failed: %d (%d)\n", cps, __LINE__);#endif				}				else				{#if 0					cps = sys_abscopy(src_phys+o, dst_phys, s);	if (cps != OK) printf("RTL8139: warning, sys_abscopy failed: %d\n", cps);#else					cps = sys_vircopy(SELF, D, (vir_bytes) rep->v_re_rx_buf+o,					re_client, D, iovp->iov_addr, s);	if (cps != OK) printf("RTL8139: warning, sys_vircopy failed: %d (%d)\n", cps, __LINE__);#endif				}				size += s;				if (size == packlen)					break;				o += s;			}			if (size == packlen)				break;		}		if (size < packlen)		{			assert(0);		}	}	else	{  		assert(0);#if 0		size= mp->DL_COUNT;		if (size < ETH_MIN_PACK_SIZE || size > ETH_MAX_PACK_SIZE_TAGGED)			panic("rtl8139","invalid packet size", size);		if (OK != sys_umap(re_client, D, (vir_bytes)mp->DL_ADDR, size, &phys_user))			panic("rtl8139","umap_local failed", NO_NUM);		p= rep->re_tx[tx_head].ret_buf;		cps = sys_abscopy(phys_user, p, size);		if (cps != OK) printf("RTL8139: warning, sys_abscopy failed: %d\n", cps);#endif		}		if (rep->re_clear_rx)		{			/* For some reason the receiver FIFO is not stopped when			 * the buffer is full.			 */	#if 0			printf("rl_readv: later buffer overflow\n");	#endif			goto suspend;	/* Buffer overflow */		}		rep->re_stat.ets_packetR++;		rep->re_read_s= packlen;		rep->re_flags= (rep->re_flags & ~REF_READING) | REF_PACK_RECV;		/* Avoid overflow in 16-bit computations */		l= d_start;		l += totlen+4;		l= (l+3) & ~3;	/* align */		if (l >= RX_BUFSIZE)		{			l -= RX_BUFSIZE;			assert(l < RX_BUFSIZE);		}		rl_outw(port, RL_CAPR, l-RL_CAPR_DATA_OFF);		if (!from_int)			reply(rep, OK, FALSE);		return;	suspend:		if (from_int)		{			assert(rep->re_flags & REF_READING);			/* No need to store any state */			return;		}		rep->re_rx_mess= *mp;		assert(!(rep->re_flags & REF_READING));		rep->re_flags |= REF_READING;		reply(rep, OK, FALSE);	}	/*===========================================================================*	 *				rl_writev				     *	 *===========================================================================*/	static void rl_writev(mp, from_int, vectored)	message *mp;	int from_int;	int vectored;	{		phys_bytes p, iov_src, phys_user;		int i, j, n, s, port, count, size;		int tx_head, re_client;		re_t *rep;		iovec_t *iovp;		char *ret;		int cps;		port = mp->DL_PORT;		count = mp->DL_COUNT;		if (port < 0 || port >= RE_PORT_NR)			panic("rtl8139","illegal port", port);		rep= &re_table[port];		re_client= mp->DL_PROC;		rep->re_client= re_client;		assert(rep->re_mode == REM_ENABLED);		assert(rep->re_flags & REF_ENABLED);		if (from_int)		{			assert(rep->re_flags & REF_SEND_AVAIL);			rep->re_flags &= ~REF_SEND_AVAIL;			rep->re_send_int= FALSE;			rep->re_tx_alive= TRUE;		}		tx_head= rep->re_tx_head;		if (rep->re_tx[tx_head].ret_busy)		{			assert(!(rep->re_flags & REF_SEND_AVAIL));			rep->re_flags |= REF_SEND_AVAIL;			if (rep->re_tx[tx_head].ret_busy)				goto suspend;			/* Race condition, the interrupt handler may clear re_busy			 * before we got a chance to set REF_SEND_AVAIL. Checking			 * ret_busy twice should be sufficient.			 */	#if 0			printf("rl_writev: race detected\n");	#endif			rep->re_flags &= ~REF_SEND_AVAIL;			rep->re_send_int= FALSE;		}		assert(!(rep->re_flags & REF_SEND_AVAIL));		assert(!(rep->re_flags & REF_PACK_SENT));		if (vectored)		{			int iov_offset = 0;#if 0			if (OK != sys_umap(re_client, D, (vir_bytes)mp->DL_ADDR,				count * sizeof(rep->re_iovec[0]), &iov_src))				panic("rtl8139","umap_local failed", NO_NUM);#endif			size= 0;#if 0			p= rep->re_tx[tx_head].ret_buf;#else			ret = rep->re_tx[tx_head].v_ret_buf;#endif			for (i= 0; i<count; i += IOVEC_NR,				iov_src += IOVEC_NR * sizeof(rep->re_iovec[0]),				iov_offset += IOVEC_NR * sizeof(rep->re_iovec[0]))			{				n= IOVEC_NR;				if (i+n > count)					n= count-i;#if 0				cps = sys_physcopy(NONE, PHYS_SEG, iov_src, SELF, D, (vir_bytes) rep->re_iovec, 					n * sizeof(rep->re_iovec[0]));		if (cps != OK) printf("RTL8139: warning, sys_abscopy failed: %d\n", cps);#else				cps = sys_vircopy(re_client, D, ((vir_bytes) mp->DL_ADDR) + iov_offset,					SELF, D, (vir_bytes) rep->re_iovec, 					n * sizeof(rep->re_iovec[0]));	if (cps != OK) printf("RTL8139: warning, sys_vircopy failed: %d\n", cps);#endif			for (j= 0, iovp= rep->re_iovec; j<n; j++, iovp++)			{				s= iovp->iov_size;				if (size + s > ETH_MAX_PACK_SIZE_TAGGED)				{				  panic("rtl8139","invalid packet size",			  	    NO_NUM);				}				if (OK != sys_umap(re_client, D, iovp->iov_addr, s, &phys_user))				  panic("rtl8139","umap_local failed\n", NO_NUM);#if 0				cps = sys_abscopy(phys_user, p, s);	if (cps != OK) printf("RTL8139: warning, sys_abscopy failed: %d\n", cps);#else				cps = sys_vircopy(re_client, D, iovp->iov_addr,					SELF, D, (vir_bytes) ret, s);		if (cps != OK) printf("RTL8139: warning, sys_vircopy failed: %d\n", cps);#endif				size += s;#if 0				p += s;#endif				ret += s;			}		}		if (size < ETH_MIN_PACK_SIZE)			panic("rtl8139","invalid packet size", size);	}	else	{  		size= mp->DL_COUNT;		if (size < ETH_MIN_PACK_SIZE || size > ETH_MAX_PACK_SIZE_TAGGED)			panic("rtl8139","invalid packet size", size);#if 0		if (OK != sys_umap(re_client, D, (vir_bytes)mp->DL_ADDR, size, &phys_user))			panic("rtl8139","umap_local failed\n", NO_NUM);		p= rep->re_tx[tx_head].ret_buf;		cps = sys_abscopy(phys_user, p, size);	if (cps != OK) printf("RTL8139: warning, sys_abscopy failed: %d\n", cps);#else		ret = rep->re_tx[tx_head].v_ret_buf;		cps = sys_vircopy(re_client, D, (vir_bytes)mp->DL_ADDR, 			SELF, D, (vir_bytes) ret, size);	if (cps != OK) printf("RTL8139: warning, sys_abscopy failed: %d\n", cps);#endif	}	rl_outl(rep->re_base_port, RL_TSD0+tx_head*4, 		rep->re_ertxth | size);	rep->re_tx[tx_head].ret_busy= TRUE;	if (++tx_head == N_TX_BUF)		tx_head= 0;	assert(tx_head < RL_N_TX);	rep->re_tx_head= tx_head;	rep->re_flags |= REF_PACK_SENT;	/* If the interrupt handler called, don't send a reply. The reply	 * will be sent after all interrupts are handled. 	 */	if (from_int)		return;	reply(rep, OK, FALSE);	return;suspend:#if 0		printf("rl_writev: head %d, tail %d, busy: %d %d %d %d\n",			tx_head, rep->re_tx_tail,			rep->re_tx[0].ret_busy, rep->re_tx[1].ret_busy,			rep->re_tx[2].ret_busy, rep->re_tx[3].ret_busy);		printf("rl_writev: TSD: 0x%x, 0x%x, 0x%x, 0x%x\n",			rl_inl(rep->re_base_port, RL_TSD0+0*4),			rl_inl(rep->re_base_port, RL_TSD0+1*4),			rl_inl(rep->re_base_port, RL_TSD0+2*4),			rl_inl(rep->re_base_port, RL_TSD0+3*4));#endif	if (from_int)		panic("rtl8139","should not be sending\n", NO_NUM);	rep->re_tx_mess= *mp;	reply(rep, OK, FALSE);}/*===========================================================================* *				rl_check_ints				     * *===========================================================================*/static void rl_check_ints(rep)re_t *rep;{#if 010-1f	R/W	TSD[0-3]	Transmit Status of Descriptor [0-3]	31	R	CRS	Carrier Sense Lost	30	R	TABT	Transmit Abort	29	R	OWC	Out of Window Collision	27-24	R	NCC[3-0] Number of Collision Count	23-22			reserved	21-16	R/W	ERTXH[5-0] Early Tx Threshold	15	R	TOK	Transmit OK	14	R	TUN	Transmit FIFO Underrun	13	R/W	OWN	OWN	12-0	R/W	SIZE	Descriptor Size3e-3f	R/W	ISR		Interrupt Status Register	6	R/W	FOVW	Fx FIFO Overflow Interrupt	5	R/W	PUN/LinkChg Packet Underrun / Link Change Interrupt	3	R/W	TER	Transmit Error Interrupt	2	R/W	TOK	Transmit OK Interrupt3e-3f	R/W	ISR		Interrupt Status Register	15	R/W	SERR	System Error Interrupt	14	R/W	TimeOut	Time Out Interrupt	13	R/W	LenChg	Cable Length Change Interrupt3e-3f	R/W	ISR		Interrupt Status Register	4	R/W	RXOVW	Rx Buffer Overflow Interrupt	1	R/W	RER	Receive Error Interrupt	0	R/W	ROK	Receive OK Interrupt4c-4f	R/W	MPC		Missed Packet Counter60-61	R	TSAD		Transmit Status of All Descriptors	15-12	R	TOK[3-0] TOK bit of Descriptor [3-0]	11-8	R	TUN[3-0] TUN bit of Descriptor [3-0]	7-4	R	TABT[3-0] TABT bit of Descriptor [3-0]	3-0     R       OWN[3-0] OWN bit of Descriptor [3-0]6c-6d	R	DIS		Disconnect Counter	15-0	R	DCNT	Disconnect Counter6e-6f	R	FCSC		False Carrier Sense Counter	15-0	R	FCSCNT	False Carrier event counter72-73	R	REC		RX_ER Counter	15-0	R	RXERCNT	Received packet counter#endif	int re_flags;	re_flags= rep->re_flags;	if ((re_flags & REF_READING) &&		!(rl_inb(rep->re_base_port, RL_CR) & RL_CR_BUFE))	{		if (rep->re_rx_mess.m_type == DL_READV)		{			rl_readv(&rep->re_rx_mess, TRUE /* from int */,				TRUE /* vectored */);		}		else		{			assert(rep->re_rx_mess.m_type == DL_READ);			rl_readv(&rep->re_rx_mess, TRUE /* from int */,				FALSE /* !vectored */);		}	}	if (rep->re_clear_rx)		rl_clear_rx(rep);	if (rep->re_need_reset)		rl_do_reset(rep);	if (rep->re_send_int)	{		if (rep->re_tx_mess.m_type == DL_WRITEV)		{			rl_writev(&rep->re_tx_mess, TRUE /* from int */,				TRUE /* vectored */);		}		else		{			assert(rep->re_tx_mess.m_type == DL_WRITE);			rl_writev(&rep->re_tx_mess, TRUE /* from int */,				FALSE /* !vectored */);		}	}	if (rep->re_report_link)		rl_report_link(rep);	if (rep->re_flags & (REF_PACK_SENT | REF_PACK_RECV))		reply(rep, OK, TRUE);}/*===========================================================================* *				rl_report_link				     * *===========================================================================*/static void rl_report_link(rep)re_t *rep;{	port_t port;	u16_t mii_ctrl, mii_status, mii_ana, mii_anlpa, mii_ane, mii_extstat;	u8_t msr;	int f, link_up;	rep->re_report_link= FALSE;	port= rep->re_base_port;	msr= rl_inb(port, RL_MSR);	link_up= !(msr & RL_MSR_LINKB);	rep->re_link_up= link_up;	if (!link_up)	{		printf("%s: link down\n", rep->re_name);		return;	}	mii_ctrl= rl_inw(port, RL_BMCR);	mii_status= rl_inw(port, RL_BMSR);	mii_ana= rl_inw(port, RL_ANAR);	mii_anlpa= rl_inw(port, RL_ANLPAR);	mii_ane= rl_inw(port, RL_ANER);	mii_extstat= 0;	if (mii_ctrl & (MII_CTRL_LB|MII_CTRL_PD|MII_CTRL_ISO))	{		printf("%s: PHY: ", rep->re_name);		f= 1;		if (mii_ctrl & MII_CTRL_LB)		{			printf("loopback mode");			f= 0;

⌨️ 快捷键说明

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