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

📄 if_le.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
			boff = sizeof (struct ether_header);			resid = totlen;		}	}	return (top);}/* * Process an ioctl request. */leioctl(ifp, cmd, data)	register struct ifnet *ifp;	int cmd;	caddr_t data;{	register struct ifaddr *ifa = (struct ifaddr *)data;	struct le_softc *le = &le_softc[ifp->if_unit];	volatile struct lereg1 *ler1 = le->sc_r1;	int s, error = 0;	s = splnet();	switch (cmd) {	case SIOCSIFADDR:		ifp->if_flags |= IFF_UP;		switch (ifa->ifa_addr->sa_family) {#ifdef INET		case AF_INET:			leinit(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:		    {			register struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr);			if (ns_nullhost(*ina))				ina->x_host = *(union ns_host *)(le->sc_addr);			else {				/* 				 * The manual says we can't change the address 				 * while the receiver is armed,				 * so reset everything				 */				ifp->if_flags &= ~IFF_RUNNING; 				LEWREG(LE_STOP, ler1->ler1_rdp);				bcopy((caddr_t)ina->x_host.c_host,				    (caddr_t)le->sc_addr, sizeof(le->sc_addr));			}			leinit(ifp->if_unit); /* does le_setaddr() */			break;		    }#endif		default:			leinit(ifp->if_unit);			break;		}		break;#if defined (CCITT) && defined (LLC)	case SIOCSIFCONF_X25:		ifp->if_flags |= IFF_UP;		ifa->ifa_rtrequest = cons_rtrequest;		error = x25_llcglue(PRC_IFUP, ifa->ifa_addr);		if (error == 0)			leinit(ifp->if_unit);		break;#endif /* CCITT && LLC */	case SIOCSIFFLAGS:		if ((ifp->if_flags & IFF_UP) == 0 &&		    ifp->if_flags & IFF_RUNNING) {			LEWREG(LE_STOP, ler1->ler1_rdp);			ifp->if_flags &= ~IFF_RUNNING;		} else if (ifp->if_flags & IFF_UP &&		    (ifp->if_flags & IFF_RUNNING) == 0)			leinit(ifp->if_unit);		/*		 * If the state of the promiscuous bit changes, the interface		 * must be reset to effect the change.		 */		if (((ifp->if_flags ^ le->sc_iflags) & IFF_PROMISC) &&		    (ifp->if_flags & IFF_RUNNING)) {			le->sc_iflags = ifp->if_flags;			lereset(ifp->if_unit);			lestart(ifp);		}		break;#ifdef MULTICAST	case SIOCADDMULTI:	case SIOCDELMULTI:		/* Update our multicast list  */		error = (cmd == SIOCADDMULTI) ?		    ether_addmulti((struct ifreq *)data, &le->sc_ac) :		    ether_delmulti((struct ifreq *)data, &le->sc_ac);		if (error == ENETRESET) {			/*			 * Multicast list has changed; set the hardware			 * filter accordingly.			 */			lereset(ifp->if_unit);			error = 0;		}		break;#endif	default:		error = EINVAL;	}	splx(s);	return (error);}leerror(unit, stat)	int unit;	int stat;{	if (!ledebug)		return;	/*	 * Not all transceivers implement heartbeat	 * so we only log CERR once.	 */	if ((stat & LE_CERR) && le_softc[unit].sc_cerr)		return;	log(LOG_WARNING,	    "le%d: error: stat=%b\n", unit,	    stat,	    "\20\20ERR\17BABL\16CERR\15MISS\14MERR\13RINT\12TINT\11IDON\10INTR\07INEA\06RXON\05TXON\04TDMD\03STOP\02STRT\01INIT");}lererror(unit, msg)	int unit;	char *msg;{	register struct le_softc *le = &le_softc[unit];	register volatile void *rmd;	u_char eaddr[6];	int len;	if (!ledebug)		return;	rmd = LER2_RMDADDR(le->sc_r2, le->sc_rmd);	len = LER2V_rmd3(rmd);	if (len > 11)		(*le->sc_copyfrombuf)(LER2_RBUFADDR(le->sc_r2, le->sc_rmd),			6, eaddr, 6);	log(LOG_WARNING,	    "le%d: ierror(%s): from %s: buf=%d, len=%d, rmd1=%b\n",	    unit, msg,	    len > 11 ? ether_sprintf(eaddr) : "unknown",	    le->sc_rmd, len,	    LER2V_rmd1(rmd),	    "\20\20OWN\17ERR\16FRAM\15OFLO\14CRC\13RBUF\12STP\11ENP");}lexerror(unit)	int unit;{	register struct le_softc *le = &le_softc[unit];	register volatile void *tmd;	u_char eaddr[6];	int len;	if (!ledebug)		return;	tmd = LER2_TMDADDR(le->sc_r2, 0);	len = -LER2V_tmd2(tmd);	if (len > 5)		(*le->sc_copyfrombuf)(LER2_TBUFADDR(le->sc_r2, 0), 0, eaddr, 6);	log(LOG_WARNING,	    "le%d: oerror: to %s: buf=%d, len=%d, tmd1=%b, tmd3=%b\n",	    unit,	    len > 5 ? ether_sprintf(eaddr) : "unknown",	    0, len,	    LER2V_tmd1(tmd),	    "\20\20OWN\17ERR\16RES\15MORE\14ONE\13DEF\12STP\11ENP",	    LER2V_tmd3(tmd),	    "\20\20BUFF\17UFLO\16RES\15LCOL\14LCAR\13RTRY");}/* * Write a lance register port, reading it back to ensure success. This seems * to be necessary during initialization, since the chip appears to be a bit * pokey sometimes. */static voidlewritereg(regptr, val)	register volatile u_short *regptr;	register u_short val;{	register int i = 0;	while (*regptr != val) {		*regptr = val;		MachEmptyWriteBuffer();		if (++i > 10000) {			printf("le: Reg did not settle (to x%x): x%x\n",			       val, *regptr);			return;		}		DELAY(100);	}}/* * Routines for accessing the transmit and receive buffers. Unfortunately, * CPU addressing of these buffers is done in one of 3 ways: * - contiguous (for the 3max and turbochannel option card) * - gap2, which means shorts (2 bytes) interspersed with short (2 byte) *   spaces (for the pmax) * - gap16, which means 16bytes interspersed with 16byte spaces *   for buffers which must begin on a 32byte boundary (for 3min and maxine) * The buffer offset is the logical byte offset, assuming contiguous storage. */voidcopytobuf_contig(from, lebuf, boff, len)	char *from;	volatile void *lebuf;	int boff;	int len;{	/*	 * Just call bcopy() to do the work.	 */	bcopy(from, ((char *)lebuf) + boff, len);}voidcopyfrombuf_contig(lebuf, boff, to, len)	volatile void *lebuf;	int boff;	char *to;	int len;{	/*	 * Just call bcopy() to do the work.	 */	bcopy(((char *)lebuf) + boff, to, len);}voidbzerobuf_contig(lebuf, boff, len)	volatile void *lebuf;	int boff;	int len;{	/*	 * Just let bzero() do the work	 */	bzero(((char *)lebuf) + boff, len);}/* * For the pmax the buffer consists of shorts (2 bytes) interspersed with * short (2 byte) spaces and must be accessed with halfword load/stores. * (don't worry about doing an extra byte) */voidcopytobuf_gap2(from, lebuf, boff, len)	register char *from;	volatile void *lebuf;	int boff;	register int len;{	register volatile u_short *bptr;	register int xfer;	if (boff & 0x1) {		/* handle unaligned first byte */		bptr = ((volatile u_short *)lebuf) + (boff - 1);		*bptr = (*from++ << 8) | (*bptr & 0xff);		bptr += 2;		len--;	} else		bptr = ((volatile u_short *)lebuf) + boff;	if ((unsigned)from & 0x1) {		while (len > 1) {			*bptr = (from[1] << 8) | (from[0] & 0xff);			bptr += 2;			from += 2;			len -= 2;		}	} else {		/* optimize for aligned transfers */		xfer = (int)((unsigned)len & ~0x1);		CopyToBuffer((u_short *)from, bptr, xfer);		bptr += xfer;		from += xfer;		len -= xfer;	}	if (len == 1)		*bptr = (u_short)*from;}voidcopyfrombuf_gap2(lebuf, boff, to, len)	volatile void *lebuf;	int boff;	register char *to;	register int len;{	register volatile u_short *bptr;	register u_short tmp;	register int xfer;	if (boff & 0x1) {		/* handle unaligned first byte */		bptr = ((volatile u_short *)lebuf) + (boff - 1);		*to++ = (*bptr >> 8) & 0xff;		bptr += 2;		len--;	} else		bptr = ((volatile u_short *)lebuf) + boff;	if ((unsigned)to & 0x1) {		while (len > 1) {			tmp = *bptr;			*to++ = tmp & 0xff;			*to++ = (tmp >> 8) & 0xff;			bptr += 2;			len -= 2;		}	} else {		/* optimize for aligned transfers */		xfer = (int)((unsigned)len & ~0x1);		CopyFromBuffer(bptr, to, xfer);		bptr += xfer;		to += xfer;		len -= xfer;	}	if (len == 1)		*to = *bptr & 0xff;}voidbzerobuf_gap2(lebuf, boff, len)	volatile void *lebuf;	int boff;	int len;{	register volatile u_short *bptr;	if ((unsigned)boff & 0x1) {		bptr = ((volatile u_short *)lebuf) + (boff - 1);		*bptr &= 0xff;		bptr += 2;		len--;	} else		bptr = ((volatile u_short *)lebuf) + boff;	while (len > 0) {		*bptr = 0;		bptr += 2;		len -= 2;	}}/* * For the 3min and maxine, the buffers are in main memory filled in with * 16byte blocks interspersed with 16byte spaces. */voidcopytobuf_gap16(from, lebuf, boff, len)	register char *from;	volatile void *lebuf;	int boff;	register int len;{	register char *bptr;	register int xfer;	bptr = ((char *)lebuf) + ((boff << 1) & ~0x1f);	boff &= 0xf;	xfer = min(len, 16 - boff);	while (len > 0) {		bcopy(from, ((char *)bptr) + boff, xfer);		from += xfer;		bptr += 32;		boff = 0;		len -= xfer;		xfer = min(len, 16);	}}voidcopyfrombuf_gap16(lebuf, boff, to, len)	volatile void *lebuf;	int boff;	register char *to;	register int len;{	register char *bptr;	register int xfer;	bptr = ((char *)lebuf) + ((boff << 1) & ~0x1f);	boff &= 0xf;	xfer = min(len, 16 - boff);	while (len > 0) {		bcopy(((char *)bptr) + boff, to, xfer);		to += xfer;		bptr += 32;		boff = 0;		len -= xfer;		xfer = min(len, 16);	}}voidbzerobuf_gap16(lebuf, boff, len)	volatile void *lebuf;	int boff;	register int len;{	register char *bptr;	register int xfer;	bptr = ((char *)lebuf) + ((boff << 1) & ~0x1f);	boff &= 0xf;	xfer = min(len, 16 - boff);	while (len > 0) {		bzero(((char *)bptr) + boff, xfer);		bptr += 32;		boff = 0;		len -= xfer;		xfer = min(len, 16);	}}#endif /* NLE */

⌨️ 快捷键说明

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