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

📄 if_ace.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
	if ((eistat & (RCS_ROVRN | RCS_RCRC | RCS_RODD)) ||	    len < ET_MINLEN || len > ET_MAXLEN+CRC_SIZE) {		if (eistat & RCS_ROVRN)			is->is_stats.rx_overruns++;		if (eistat & RCS_RCRC)			is->is_stats.rx_crc_errors++;		if (eistat & RCS_RODD)			is->is_stats.rx_align_errors++;		if (len < ET_MINLEN)			is->is_stats.rx_underruns++;		if (len > ET_MAXLEN+CRC_SIZE)			is->is_stats.rx_overruns++;		is->is_if.if_ierrors++;		rxseg->rx_csr = 0;		return;	} else		is->is_stats.rx_datagrams++;	ace = (struct ether_header *)rxseg->rx_data;	len -= sizeof (struct ether_header);	/*	 * Deal with trailer protocol: if type is trailer	 * get true type from first 16-bit word past data.	 * Remember that type was trailer by setting off.	 */	ace->ether_type = ntohs((u_short)ace->ether_type);#define	acedataaddr(ace, off, type) \    ((type)(((caddr_t)(((char *)ace)+sizeof (struct ether_header))+(off))))	if (ace->ether_type >= ETHERTYPE_TRAIL &&	    ace->ether_type < ETHERTYPE_TRAIL+ETHERTYPE_NTRAILER) {		off = (ace->ether_type - ETHERTYPE_TRAIL) * 512;		if (off >= ETHERMTU)			goto setup;		/* sanity */		ace->ether_type = ntohs(*acedataaddr(ace, off, u_short *));		resid = ntohs(*(acedataaddr(ace, off+2, u_short *)));		if (off + resid > len)			goto setup;		/* sanity */		len = off + resid;	} else		off = 0;	if (len == 0)		goto setup;	/*	 * Pull packet off interface.  Off is nonzero if packet	 * has trailing header; aceget will then force this header	 * information to be at the front.	 */	m = aceget((u_char *)rxseg->rx_data, len, off, &is->is_if);	if (m)		ether_input(&is->is_if, ace, m);setup:	rxseg->rx_csr = 0;	goto again;}/* * Routine to copy from mbuf chain to transmit buffer on the VERSAbus * If packet size is less than the minimum legal size, * the buffer is expanded.  We probably should zero out the extra * bytes for security, but that would slow things down. */aceput(txbuf, m)	char *txbuf;	struct mbuf *m;#ifdef notdef{	register u_char *bp, *mcp;	register short *s1, *s2;	register u_int len;	register struct mbuf *mp;	int total;	total = mp->m_pkthdr.len;	bp = (u_char *)txbuf;	for (mp = m; mp; mp = mp->m_next) {		len = mp->m_len;		if (len == 0)			continue;		mcp = mtod(mp, u_char *);		if (((int)mcp & 01) && ((int)bp & 01)) {			/* source & destination at odd addresses */			movob(bp++, *mcp++);			--len;		}		if (len > 1 && (((int)mcp & 01)==0) && (((int)bp & 01)==0)) {			int l = len & 1;			s1 = (short *)bp;			s2 = (short *)mcp;			len >>= 1;		/* count # of shorts */			while (len-- != 0)				movow(s1++, *s2++);			len = l;		/* # remaining bytes */			bp = (u_char *)s1;			mcp = (u_char *)s2;		}		while (len-- != 0)			movob(bp++, *mcp++);	}	m_freem(m);	return (total);}#else{	register u_char *bp, *mcp;	register short *s1, *s2;	register u_int len;	register struct mbuf *mp;	int total;	total = 0;	bp = (u_char *)txbuf;	for (mp = m; (mp); mp = mp->m_next) {		len = mp->m_len;		if (len == 0)			continue;		total += len;		mcp = mtod(mp, u_char *);		if (((int)mcp & 01) && ((int)bp & 01)) {			/* source & destination at odd addresses */			movob(bp++, *mcp++);			--len;		}		if (len > 1 && (((int)mcp & 01)==0) && (((int)bp & 01)==0)) {			register u_int l;			s1 = (short *)bp;			s2 = (short *)mcp;			l = len >> 1;		/* count # of shorts */			while (l-- != 0)				movow(s1++, *s2++);			len &= 1;		/* # remaining bytes */			bp = (u_char *)s1;			mcp = (u_char *)s2;		}		while (len-- != 0)			movob(bp++, *mcp++);	}	m_freem(m);	return (total);}#endif/* * Routine to copy from VERSAbus memory into mbufs. * * Warning: This makes the fairly safe assumption that * mbufs have even lengths. */struct mbuf *aceget(rxbuf, totlen, off, ifp)	u_char *rxbuf;	int totlen, off;	struct ifnet *ifp;{	register u_char *cp, *mcp;	register struct mbuf *m;	register int tlen;	struct mbuf *top = 0, **mp = &top;	int len;	u_char *packet_end;	rxbuf += sizeof (struct ether_header);	cp = rxbuf;	packet_end = cp + totlen;	if (off) {		off += 2 * sizeof(u_short);		totlen -= 2 * sizeof(u_short);		cp = rxbuf + off;	}	MGETHDR(m, M_DONTWAIT, MT_DATA);	if (m == 0)		return (0);	m->m_pkthdr.rcvif = ifp;	m->m_pkthdr.len = totlen;	m->m_len = MHLEN;	while (totlen > 0) {		if (top) {			MGET(m, M_DONTWAIT, MT_DATA);			if (m == 0) {				m_freem(top);				return (0);			}			m->m_len = MLEN;		}		len = min(totlen, (packet_end - cp));		if (len >= MINCLSIZE) {			MCLGET(m, M_DONTWAIT);			if (m->m_flags & M_EXT)				m->m_len = len = min(len, MCLBYTES);			else				len = m->m_len;		} else {			/*			 * Place initial small packet/header at end of mbuf.			 */			if (len < m->m_len) {				if (top == 0 && len + max_linkhdr <= m->m_len)					m->m_data += max_linkhdr;				m->m_len = len;			} else				len = m->m_len;		}		mcp = mtod(m, u_char *);		/*bcopy((caddr_t)cp, (caddr_t)mcp, len);*/		/*cp += len; mcp += len;*/		tlen = len;		if (((int)mcp & 01) && ((int)cp & 01)) {			/* source & destination at odd addresses */			*mcp++ = *cp++;			--tlen;		}		if (tlen > 1 && (((int)mcp&01) == 0) && (((int)cp&01) == 0)) {			register short *s1, *s2;			register int l;			s1 = (short *)mcp;			s2 = (short *)cp;			l = tlen >> 1;		/* count # of shorts */			while (l-- > 0)		/* copy shorts */				*s1++ = *s2++;			tlen &= 1;		/* # remaining bytes */			mcp = (u_char *)s1;			cp = (u_char *)s2;		}		while (tlen-- > 0)			*mcp++ = *cp++;		*mp = m;		mp = &m->m_next;		totlen -= len;		if (cp == packet_end)			cp = rxbuf;	}	return (top);}/* backoff table masks */short	random_mask_tbl[16] = {	0x0040, 0x00c0, 0x01c0, 0x03c0, 0x07c0, 0x0fc0, 0x1fc0, 0x3fc0,	0x7fc0, 0xffc0, 0xffc0, 0xffc0, 0xffc0, 0xffc0, 0xffc0, 0xffc0};acebakoff(is, txseg, retries)	struct ace_softc *is;	struct tx_segment *txseg;	register int retries;{	register short *pBakNum, random_num;	short *pMask;	pMask = &random_mask_tbl[0];	pBakNum = &txseg->tx_backoff[0];	while (--retries >= 0) {		random_num = (is->is_currnd = (is->is_currnd * 18741)-13849);		random_num &= *pMask++;		*pBakNum++ = random_num ^ (short)(0xff00 | 0x00fc);	}}/* * Process an ioctl request. */aceioctl(ifp, cmd, data)	register struct ifnet *ifp;	int cmd;	caddr_t data;{	register struct ifaddr *ifa = (struct ifaddr *)data;	struct acedevice *addr;	int s = splimp(), error = 0;	switch (cmd) {	case SIOCSIFADDR:		ifp->if_flags |= IFF_UP;		switch (ifa->ifa_addr->sa_family) {#ifdef INET		case AF_INET:			aceinit(ifp->if_unit);	/* before arpwhohas */			((struct arpcom *)ifp)->ac_ipaddr =				IA_SIN(ifa)->sin_addr;			arpwhohas((struct arpcom *)ifp, &IA_SIN(ifa)->sin_addr);			break;#endif#ifdef NS		case AF_NS: {			struct ns_addr *ina = &IA_SNS(ifa)->sns_addr;			struct ace_softc *is = &ace_softc[ifp->if_unit];			if (!ns_nullhost(*ina)) {				ifp->if_flags &= ~IFF_RUNNING;				addr = (struct acedevice *)				    aceinfo[ifp->if_unit]->ui_addr;				movow(&addr->csr, CSR_RESET);				DELAY(10000);				/* set station address & copy addr to arp */				acesetaddr(ifp->if_unit, addr, 				    ina->x_host.c_host);			} else				ina->x_host = *(union ns_host *)is->is_addr;			aceinit(ifp->if_unit);			break;		}#endif		default:			aceinit(ifp->if_unit);			break;		}		break;	case SIOCSIFFLAGS:		if ((ifp->if_flags&IFF_UP) == 0 && ifp->if_flags&IFF_RUNNING) {			addr = (struct acedevice *)			    (aceinfo[ifp->if_unit]->ui_addr);			movow(&addr->csr, CSR_RESET);			ifp->if_flags &= ~IFF_RUNNING;		} else if (ifp->if_flags&IFF_UP &&		    (ifp->if_flags&IFF_RUNNING) == 0)			aceinit(ifp->if_unit);		break;	default:		error = EINVAL;	}	splx(s);	return (error);}/* * Set the on-board station address, then read it back * to initialize the address used by ARP (among others). */acesetaddr(unit, addr, station)	short unit;	struct acedevice *addr;	u_char *station;{	struct ace_softc *is = &ace_softc[unit];	register short *wp, i;	for (wp = (short *)addr->station, i = 0; i < 6; i++)		movow(wp++, ~*station++); 	for (wp = (short *)addr->station, i = 0; i < 6; i++)		is->is_addr[i] = ~*wp++;	printf("ace%d: hardware address %s\n", unit,	    ether_sprintf(is->is_addr));}/* * Setup the device for use.  Initialize dual-ported memory, * backoff parameters, and various other software state. */acesetup(unit)	int unit;{	register struct ace_softc *is = &ace_softc[unit];	register char *pData1;	register short i;	struct acedevice *addr;	bzero(is->is_dpm, 16384*2);	is->is_currnd = 49123;	addr = (struct acedevice *)aceinfo[unit]->ui_addr;	is->is_segboundry = (addr->segb >> 11) & 0xf;	pData1 = is->is_dpm + (is->is_segboundry << 11);	for (i = SEG_MAX + 1 - is->is_segboundry; --i >= 0;) {		acebakoff(is, (struct tx_segment *)pData1, 15);		pData1 += sizeof (struct tx_segment);	}	is->is_eictr = 0;	is->is_eoctr = is->is_txnext = is->is_segboundry;	bzero((char *)&is->is_stats, sizeof (is->is_stats));}#endif

⌨️ 快捷键说明

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