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

📄 if_enp.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
	}	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;		}		enpcopy(cp, mtod(m, u_char *), (u_int)len);		*mp = m;		mp = &m->m_next;		totlen -= len;		cp += len;		if (cp == packet_end)			cp = rxbuf;	}	return (top);}enpcopy(from, to, cnt)	register u_char *from, *to;	register u_int cnt;{	register c;	register short *f, *t;	if (((int)from&01) && ((int)to&01)) {		/* source & dest at odd addresses */		*to++ = *from++;		--cnt;	}	if (cnt > 1 && (((int)to&01) == 0) && (((int)from&01) == 0)) {		t = (short *)to;		f = (short *)from;		for (c = cnt>>1; c; --c)	/* even address copy */			*t++ = *f++;		cnt &= 1;		if (cnt) {			/* odd len */			from = (u_char *)f;			to = (u_char *)t;			*to = *from;		}	}	while ((int)cnt-- > 0)	/* one of the address(es) must be odd */		*to++ = *from++;}/* * Process an ioctl request. */enpioctl(ifp, cmd, data)	register struct ifnet *ifp;	int cmd;	caddr_t data;{	register struct ifaddr *ifa = (struct ifaddr *)data;	struct enpdevice *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:			enpinit(ifp->if_unit);			((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 enp_softc *es = &enp_softc[ifp->if_unit];			if (!ns_nullhost(*ina)) {				ifp->if_flags &= ~IFF_RUNNING;				addr = (struct enpdevice *)				    enpinfo[ifp->if_unit]->ui_addr;				enpsetaddr(ifp->if_unit, addr,				    ina->x_host.c_host);			} else				ina->x_host = *(union ns_host *)es->es_addr;			enpinit(ifp->if_unit);			break;		}#endif		default:			enpinit(ifp->if_unit);			break;		}		break;	case SIOCSIFFLAGS:		if ((ifp->if_flags&IFF_UP) == 0 && ifp->if_flags&IFF_RUNNING) {			enpinit(ifp->if_unit);		/* reset board */			ifp->if_flags &= ~IFF_RUNNING;		} else if (ifp->if_flags&IFF_UP &&		     (ifp->if_flags&IFF_RUNNING) == 0)			enpinit(ifp->if_unit);		break;	default:		error = EINVAL;	}	splx(s);	return (error);}enpsetaddr(unit, addr, enaddr)	int unit;	struct enpdevice *addr;	u_char *enaddr;{	enpcopy(enaddr, addr->enp_addr.e_baseaddr.ea_addr,	    sizeof (struct ether_addr));	enpinit(unit);	enpgetaddr(unit, addr);}enpgetaddr(unit, addr)	int unit;	struct enpdevice *addr;{	struct enp_softc *es = &enp_softc[unit];	enpcopy(addr->enp_addr.e_baseaddr.ea_addr, es->es_addr,	    sizeof (struct ether_addr));	printf("enp%d: hardware address %s\n",	    unit, ether_sprintf(es->es_addr));}/*  * Routines to synchronize enp and host. */#ifdef notdefstaticringinit(rp, size)	register RING *rp;{	rp->r_rdidx = rp->r_wrtidx = 0;	rp->r_size = size;}staticringfull(rp)	register RING *rp;{	register short idx;	idx = (rp->r_wrtidx + 1) & (rp->r_size-1);	return (idx == rp->r_rdidx);}staticfir(rp)	register RING *rp;{	return (rp->r_rdidx != rp->r_wrtidx ? rp->r_slot[rp->r_rdidx] : 0);}#endifstaticringempty(rp)	register RING *rp;{	return (rp->r_rdidx == rp->r_wrtidx);}staticringput(rp, v)	register RING *rp;	BCB *v;{	register int idx;	idx = (rp->r_wrtidx + 1) & (rp->r_size-1);	if (idx != rp->r_rdidx) {		ENPSETLONG(&rp->r_slot[rp->r_wrtidx], v);		rp->r_wrtidx = idx;		if ((idx -= rp->r_rdidx) < 0)			idx += rp->r_size;		return (idx);			/* num ring entries */	}	return (0);}staticringget(rp)	register RING *rp;{	register int i = 0;	if (rp->r_rdidx != rp->r_wrtidx) {		i = ENPGETLONG(&rp->r_slot[rp->r_rdidx]);		rp->r_rdidx = (++rp->r_rdidx) & (rp->r_size-1);	}	return (i);}/* * ENP Ram device. */enpr_open(dev)	dev_t dev;{	register int unit = ENPUNIT(dev);	struct vba_device *ui;	struct enpdevice *addr;	if (unit >= NENP || (ui = enpinfo[unit]) == 0 || ui->ui_alive == 0 ||	    (addr = (struct enpdevice *)ui->ui_addr) == 0)		return (ENODEV);	if (addr->enp_state != S_ENPRESET)		return (EACCES);  /* enp is not in reset state, don't open  */	return (0);}/*ARGSUSED*/enpr_close(dev)	dev_t dev;{	return (0);}enpr_read(dev, uio)	dev_t dev;	register struct uio *uio;{	register struct iovec *iov;	struct enpdevice *addr;	if (uio->uio_offset > RAM_SIZE)		return (ENODEV);	iov = uio->uio_iov;	if (uio->uio_offset + iov->iov_len > RAM_SIZE)		iov->iov_len = RAM_SIZE - uio->uio_offset;	addr = (struct enpdevice *)enpinfo[ENPUNIT(dev)]->ui_addr;	if (useracc(iov->iov_base, (unsigned)iov->iov_len, 0) == 0)		return (EFAULT);	enpcopy((u_char *)&addr->enp_ram[uio->uio_offset],	    (u_char *)iov->iov_base, (u_int)iov->iov_len);	uio->uio_resid -= iov->iov_len;	iov->iov_len = 0;	return (0);}enpr_write(dev, uio)	dev_t dev;	register struct uio *uio;{	register struct enpdevice *addr;	register struct iovec *iov;	addr = (struct enpdevice *)enpinfo[ENPUNIT(dev)]->ui_addr;	iov = uio->uio_iov;	if (uio->uio_offset > RAM_SIZE)		return (ENODEV);	if (uio->uio_offset + iov->iov_len > RAM_SIZE)		iov->iov_len = RAM_SIZE - uio->uio_offset;	if (useracc(iov->iov_base, (unsigned)iov->iov_len, 1) == 0)		return (EFAULT);	enpcopy((u_char *)iov->iov_base,	    (u_char *)&addr->enp_ram[uio->uio_offset], (u_int)iov->iov_len);	uio->uio_resid -= iov->iov_len;	uio->uio_offset += iov->iov_len;	iov->iov_len = 0;	return (0);}/*ARGSUSED*/enpr_ioctl(dev, cmd, data)	dev_t dev;	caddr_t data;{	register unit = ENPUNIT(dev);	struct enpdevice *addr;	addr = (struct enpdevice *)enpinfo[unit]->ui_addr;	switch(cmd) {	case ENPIOGO:		ENPSETLONG(&addr->enp_base, addr);		addr->enp_intrvec = enp_softc[unit].es_ivec;		ENP_GO(addr, ENPSTART);		DELAY(200000);		enpinit(unit);		/*		 * Fetch Ethernet address after link level		 * is booted (firmware copies manufacturer's		 * address from on-board ROM).		 */		enpgetaddr(unit, addr);		addr->enp_state = S_ENPRUN;		break;	case ENPIORESET:		RESET_ENP(addr);		addr->enp_state = S_ENPRESET;		DELAY(100000);		break;	default:		return (EINVAL);	}	return (0);}#endif

⌨️ 快捷键说明

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