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

📄 if_il.c

📁 open bsd vax module -if function
💻 C
📖 第 1 页 / 共 2 页
字号:
		    is->is_if.if_flags |= IFF_ALLMULTI;		    goto too_many_multis;		}	}#endif MULTI	/*	 * Set board online.	 * Hang receive buffer and start any pending	 * writes by faking a transmit complete.	 * Receive bcr is not a multiple of 8 so buffer	 * chaining can't happen.	 */	addr->il_csr = ILC_ONLINE;	while ((addr->il_csr & IL_CDONE) == 0)		;	addr->il_bar = is->is_ifuba.ifu_r.ifrw_info & 0xffff;	addr->il_bcr = sizeof(struct il_rheader) + ETHERMTU + 6;	addr->il_csr =	    ((is->is_ifuba.ifu_r.ifrw_info >> 2) & IL_EUA)|ILC_RCV|IL_RIE;	while ((addr->il_csr & IL_CDONE) == 0)		;	is->is_if.if_flags |= IFF_RUNNING | IFF_OACTIVE;	is->is_flags |= ILF_RUNNING;	is->is_lastcmd = 0;	ilcint(unit);	splx(s);}/* * Start output on interface. * Get another datagram to send off of the interface queue, * and map it to the interface before starting the output. */ilstart(ifp)	register struct ifnet *ifp;{        int unit = ifp->if_unit, len;	struct uba_device *ui = ilinfo[unit];	register struct il_softc *is = &il_softc[unit];	register struct ildevice *addr;	struct mbuf *m;	short csr;	IF_DEQUEUE(&is->is_if.if_snd, m);	addr = (struct ildevice *)ui->ui_addr;	if (m == 0) {		if ((is->is_flags & ILF_STATPENDING) == 0)			return (0);		addr->il_bar = is->is_ubaddr & 0xffff;		addr->il_bcr = sizeof (struct il_stats);		csr = ((is->is_ubaddr >> 2) & IL_EUA)|ILC_STAT|IL_RIE|IL_CIE;		is->is_flags &= ~ILF_STATPENDING;		goto startcmd;	}	len = if_wubaput(&is->is_ifuba, m);	/*	 * Ensure minimum packet length.	 * This makes the safe assumtion that there are no virtual holes	 * after the data.	 * For security, it might be wise to zero out the added bytes,	 * but we're mainly interested in speed at the moment.	 */	if (len - sizeof(struct ether_header) < ETHERMIN)		len = ETHERMIN + sizeof(struct ether_header);	if (is->is_ifuba.ifu_flags & UBA_NEEDBDP)		UBAPURGE(is->is_ifuba.ifu_uba, is->is_ifuba.ifu_w.ifrw_bdp);	addr->il_bar = is->is_ifuba.ifu_w.ifrw_info & 0xffff;	addr->il_bcr = len;	csr =	  ((is->is_ifuba.ifu_w.ifrw_info >> 2) & IL_EUA)|ILC_XMIT|IL_CIE|IL_RIE;startcmd:	is->is_lastcmd = csr & IL_CMD;	addr->il_csr = csr;	is->is_if.if_flags |= IFF_OACTIVE;	return (0);}/* * Command done interrupt. */ilcint(unit)	int unit;{	register struct il_softc *is = &il_softc[unit];	struct uba_device *ui = ilinfo[unit];	register struct ildevice *addr = (struct ildevice *)ui->ui_addr;	short csr;	if ((is->is_if.if_flags & IFF_OACTIVE) == 0) {		printf("il%d: stray xmit interrupt, csr=%b\n", unit,			addr->il_csr, IL_BITS);		return;	}	csr = addr->il_csr;	/*	 * Hang receive buffer if it couldn't	 * be done earlier (in ilrint).	 */	if (is->is_flags & ILF_RCVPENDING) {		int s;		addr->il_bar = is->is_ifuba.ifu_r.ifrw_info & 0xffff;		addr->il_bcr = sizeof(struct il_rheader) + ETHERMTU + 6;		addr->il_csr =		  ((is->is_ifuba.ifu_r.ifrw_info >> 2) & IL_EUA)|ILC_RCV|IL_RIE;		s = splhigh();		while ((addr->il_csr & IL_CDONE) == 0)			;		splx(s);		is->is_flags &= ~ILF_RCVPENDING;	}	is->is_if.if_flags &= ~IFF_OACTIVE;	csr &= IL_STATUS;	switch (is->is_lastcmd) {	case ILC_XMIT:		is->is_if.if_opackets++;		if (csr > ILERR_RETRIES)			is->is_if.if_oerrors++;		break;	case ILC_STAT:		if (csr == ILERR_SUCCESS)			iltotal(is);		break;	}	if (is->is_ifuba.ifu_xtofree) {		m_freem(is->is_ifuba.ifu_xtofree);		is->is_ifuba.ifu_xtofree = 0;	}	(void) ilstart(&is->is_if);}/* * Ethernet interface receiver interrupt. * If input error just drop packet. * Otherwise purge input buffered data path and examine  * packet to determine type.  If can't determine length * from type, then have to drop packet.  Othewise decapsulate * packet based on type and pass to type specific higher-level * input routine. */ilrint(unit)	int unit;{	register struct il_softc *is = &il_softc[unit];	struct ildevice *addr = (struct ildevice *)ilinfo[unit]->ui_addr;	register struct il_rheader *il;    	struct mbuf *m;	int len, off, resid, s;	register struct ifqueue *inq;	is->is_if.if_ipackets++;	if (is->is_ifuba.ifu_flags & UBA_NEEDBDP)		UBAPURGE(is->is_ifuba.ifu_uba, is->is_ifuba.ifu_r.ifrw_bdp);	il = (struct il_rheader *)(is->is_ifuba.ifu_r.ifrw_addr);	len = il->ilr_length - sizeof(struct il_rheader);	if ((il->ilr_status&(ILFSTAT_A|ILFSTAT_C)) || len < 46 ||	    len > ETHERMTU) {		is->is_if.if_ierrors++;#ifdef notdef		if (is->is_if.if_ierrors % 100 == 0)			printf("il%d: += 100 input errors\n", unit);#endif		goto setup;	}	/*	 * Deal with trailer protocol: if type is trailer type	 * get true type from first 16-bit word past data.	 * Remember that type was trailer by setting off.	 */	il->ilr_type = ntohs((u_short)il->ilr_type);#define	ildataaddr(il, off, type)	((type)(((caddr_t)((il)+1)+(off))))	if (il->ilr_type >= ETHERTYPE_TRAIL &&	    il->ilr_type < ETHERTYPE_TRAIL+ETHERTYPE_NTRAILER) {		off = (il->ilr_type - ETHERTYPE_TRAIL) * 512;		if (off >= ETHERMTU)			goto setup;		/* sanity */		il->ilr_type = ntohs(*ildataaddr(il, off, u_short *));		resid = ntohs(*(ildataaddr(il, 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; ilget will then force this header	 * information to be at the front, but we still have to drop	 * the type and length which are at the front of any trailer data.	 */	m = if_rubaget(&is->is_ifuba, len, off, &is->is_if);	if (m)		ether_input(&is->is_if, (struct ether_header *)il->ilr_dhost, m);setup:	/*	 * Reset for next packet if possible.	 * If waiting for transmit command completion, set flag	 * and wait until command completes.	 */	if (is->is_if.if_flags & IFF_OACTIVE) {		is->is_flags |= ILF_RCVPENDING;		return;	}	addr->il_bar = is->is_ifuba.ifu_r.ifrw_info & 0xffff;	addr->il_bcr = sizeof(struct il_rheader) + ETHERMTU + 6;	addr->il_csr =		((is->is_ifuba.ifu_r.ifrw_info >> 2) & IL_EUA)|ILC_RCV|IL_RIE;	s = splhigh();	while ((addr->il_csr & IL_CDONE) == 0)		;	splx(s);}/* * Watchdog routine, request statistics from board. */ilwatch(unit)	int unit;{	register struct il_softc *is = &il_softc[unit];	register struct ifnet *ifp = &is->is_if;	int s;	if (is->is_flags & ILF_STATPENDING) {		ifp->if_timer = is->is_scaninterval;		return;	}	s = splimp();	is->is_flags |= ILF_STATPENDING;	if ((is->is_if.if_flags & IFF_OACTIVE) == 0)		(void) ilstart(ifp);	splx(s);	ifp->if_timer = is->is_scaninterval;}/* * Total up the on-board statistics. */iltotal(is)	register struct il_softc *is;{	register u_short *interval, *sum, *end;	interval = &is->is_stats.ils_frames;	sum = &is->is_sum.ils_frames;	end = is->is_sum.ils_fill2;	while (sum < end)		*sum++ += *interval++;	is->is_if.if_collisions = is->is_sum.ils_collis;	if ((is->is_flags & ILF_SETADDR) &&	    (bcmp((caddr_t)is->is_stats.ils_addr, (caddr_t)is->is_addr,					sizeof (is->is_addr)) != 0)) {		log(LOG_ERR, "il%d: physaddr reverted\n", is->is_if.if_unit);		is->is_flags &= ~ILF_RUNNING;		ilinit(is->is_if.if_unit);	}}/* * Process an ioctl request. */ilioctl(ifp, cmd, data)	register struct ifnet *ifp;	int cmd;	caddr_t data;{	register struct ifaddr *ifa = (struct ifaddr *)data;	register struct il_softc *is = &il_softc[ifp->if_unit];	int s = splimp(), error = 0;	switch (cmd) {	case SIOCSIFADDR:		ifp->if_flags |= IFF_UP;		ilinit(ifp->if_unit);		switch (ifa->ifa_addr->sa_family) {#ifdef INET		case AF_INET:			((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 *) 				     (il_softc[ifp->if_unit].is_addr);			} else {				il_setaddr(ina->x_host.c_host, ifp->if_unit);				return (0);			}			break;		    }#endif		}		break;	case SIOCSIFFLAGS:		if ((ifp->if_flags & IFF_UP) == 0 &&		    is->is_flags & ILF_RUNNING) {			((struct ildevice *)			   (ilinfo[ifp->if_unit]->ui_addr))->il_csr = ILC_RESET;			is->is_flags &= ~ILF_RUNNING;		} else if (ifp->if_flags & IFF_UP &&		    (is->is_flags & ILF_RUNNING) == 0)			ilinit(ifp->if_unit);		break;	default:		error = EINVAL;	}	splx(s);	return (error);}/* * set ethernet address for unit */il_setaddr(physaddr, unit)u_char *physaddr;int unit;{	register struct il_softc *is = &il_softc[unit];		if (! (is->is_flags & ILF_RUNNING))		return;			bcopy((caddr_t)physaddr, (caddr_t)is->is_addr, sizeof is->is_addr);	is->is_flags &= ~ILF_RUNNING;	is->is_flags |= ILF_SETADDR;	ilinit(unit);}#endif

⌨️ 快捷键说明

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