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

📄 if_xna.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 4 页
字号:
						break;				}			} else {				smp_unlock(&sc->lk_xna_softc);				error = ENOBUFS;				splx(s);			}		}		else {			smp_unlock(&sc->lk_xna_softc);			splx(s);		}		break;	case SIOCRDZCTRS:		/*		 * Schedule a read-and-clear counters cmd, and report		 * the most recent version of the counter block for		 * this unit. xnaintr() will free m.		 */		if (ifp->if_flags & IFF_RUNNING) {			MGET(m, M_DONTWAIT, MT_DATA);			if (m) {				/*				 * Point the data region of m to the				 * ctrblk in the softc for this unit.				 */				m->m_off = (int)&sc->ctrblk;				m->m_len = sizeof(sc->ctrblk.opcode) +					   sizeof(struct _xnactrs);				/*				 * Lock softc while setting the opcode				 * to prevent xnawatch() from blowing				 * away the "CMD_RCCNTR" opcode.				 */				s = splimp();				smp_lock(&sc->lk_xna_softc, LK_RETRY);				sc->ctrblk.opcode = CMD_RCCNTR;				xnacmd(sc, m);				smp_unlock(&sc->lk_xna_softc);				splx(s);				xnagetctrs (sc, &ctr->ctr_ether, &sc->ctrblk);				ctr->ctr_type = CTR_ETHER;			} else				error = ENOBUFS;		}		break;	case SIOCRDCTRS:		/*		 * Copyin most recent contents of unit's counter		 * block.		 */		if (ifp->if_flags & IFF_RUNNING) {			xnagetctrs (sc, &ctr->ctr_ether, &sc->ctrblk);			ctr->ctr_type = CTR_ETHER;		}		break;	case SIOCSIFADDR:		/*		 * Init the interface if its not already running		 */		xnainit(ifp->if_unit);		switch(ifa->ifa_addr.sa_family) {#ifdef INET		case AF_INET:			s = splimp();			smp_lock(&lk_ifnet, LK_RETRY);			((struct arpcom *)ifp)->ac_ipaddr =				IA_SIN(ifa)->sin_addr;			smp_unlock(&lk_ifnet);			splx(s);			/* 1st packet out */			arpwhohas((struct arpcom *)ifp, &IA_SIN(ifa)->sin_addr);			break;#endif		default:			if (pr=iffamily_to_proto(ifa->ifa_addr.sa_family))				error = (*pr->pr_ifioctl)(ifp, cmd, data);			break;		}		break;#ifdef	IFF_PROMISC	/* IFF_ALLMULTI and NPACKETFILTER, as well */	case SIOCSIFFLAGS:		if (ifp->if_flags & IFF_RUNNING) {			/*			 * If we've successfully init'ed the interface,			 * issue a UCHANGE command to update the ethernet			 * user's promiscuous bit based upon the interface			 * flags.			 */			s = splimp();			smp_lock(&sc->lk_xna_softc, LK_RETRY);			if (m = xnamkuser(sc, XNA_ETHERU, CMD_UCHANGE)) {				xnacmd(sc, m);				smp_unlock(&sc->lk_xna_softc);				splx(s);				xcmd = mtod(m, struct xnacmd_buf *);				XNATIMEOUT(xcmd, CMD_UCHANGE);	/* Wait */				switch (xcmd->opcode) {					case CMD_COMPLETE:						m_freem(m);						break;					case CMD_INVAL:						m_freem(m);					case CMD_NOP:					default:						error = EINVAL;						break;				}			} else {				smp_unlock(&sc->lk_xna_softc);				error = ENOBUFS;				splx(s);			}		}		break;#endif	IFF_PROMISC	default:		error = EINVAL;	}done:	return (error);}/* * XNA watchdog timer (runs once per second). Schedule a "read counters" * command to update the per-unit counter block. Look at the "p_sbua" * counter in the port data block to determine if we should bump up * (or reduce) the number of active receive descriptors. Descriptors * will be activated/deactivated on the next interrupt service. */xnawatch (unit)	int unit;{	register struct xna_softc *sc = &xna_softc[unit];	register struct ifnet *ifp = &sc->is_if;	register struct xnapdb *xpdb = sc->xpdb;	struct mbuf *m;	static int callno = 0;	int s;	if (ifp->if_flags & IFF_RUNNING) {		/*		 * Lock softc while writing opcode and updating sbua count		 */		s = splimp();		smp_lock(&sc->lk_xna_softc, LK_RETRY);		/*		 * Schedule a read counters cmd to update the counter		 * block for this unit. xnaintr() will free m.		 */		MGET(m, M_DONTWAIT, MT_DATA);		if (m) {			m->m_off = (int)&sc->ctrblk;			m->m_len = sizeof(sc->ctrblk.opcode) +				   sizeof(struct _xnactrs);			sc->ctrblk.opcode = CMD_RDCNTR;			xnacmd(sc, m);		}		/*		 * Tweak sc->nactv based upon the "potential sbua"		 * count provided by the adapter. We bump up the number		 * of active descriptors if the p_sbua count has gone up		 * during the last second, but bump it down if it has		 * stayed the same for the last 60 seconds.		 */		if (*(u_long *)xpdb->p_sbua.lo >		    *(u_long *)sc->xna_sbuacnt.lo) {			if (sc->nactv < XNANMAX) {				sc->nactv++;				callno = 0;			}		} else {			if ((++callno > 60) && (sc->nactv > XNANMIN)) {				sc->nactv--;				callno = 0;			}		}		sc->xna_sbuacnt = xpdb->p_sbua;		smp_unlock(&sc->lk_xna_softc);		splx(s);		/*		 * Get collision count for ifnet readers (i.e. netstat, mon)		 */		ifp->if_collisions = *(u_long *)sc->ctrblk.xnactrs.single.lo +			(*(u_long *)sc->ctrblk.xnactrs.multiple.lo * 2);	}	ifp->if_timer = 1;}xnainitdesc(rp, m)	register struct xnarecv_ring *rp;	register struct mbuf *m;{	/*	 * Tie cluster mbuf to ring descriptor. Bump up m_off by 2 bytes in	 * order to satisfy NFS, which needs longword-aligned data.	 * (Otherwise, the 14 byte ethernet header would place the	 * data at a non-longword alignment.	 */	m->m_off += 2;#ifdef	vax	rp->bseg.xaddr_lo = mtod(m, u_long);#endif	vax#ifdef	mips	rp->bseg.xaddr_lo = svtophy(mtod(m, u_long));#endif	mips	rp->bseg.xaddr_hi = rp->bseg.xmbz = 0;	rp->mbuf_recv = m;	rp->status &= ~ST_ROWN;}	struct	mbuf *xnamkparam(sc, ifp)	struct xna_softc *sc;	struct ifnet *ifp;{	register struct mbuf *m;	register struct xnacmd_buf *xparam;	/*	 * Allocate PARAM buffer	 */	XNAMCLGET(m);	if (!m)		return (0);	xparam = mtod(m, struct xnacmd_buf *);	m->m_len = sizeof(xparam->opcode) + sizeof(struct _xnaparam);	bzero(xparam, m->m_len);	xparam->opcode = CMD_PARAM;	/*	 * Copies 0's if the physical address hasn't been set. This signals	 * the port to use the default physical address.	 */	bcopy(sc->is_addr, &xparam->xnaparam.apa, 6);	bzero(xparam->xnaparam.bvc, 8);	if (ifp->if_flags & IFF_LOOPBACK)		xparam->xnaparam.loop_mode = PARAM_ELOOP;	else		xparam->xnaparam.loop_mode = PARAM_NOLOOP;	xparam->xnaparam.flags = 0;	/*	 * Can't support the VMS-style binary quad-word date format.	 * Just write zero's here.	 */	xparam->xnaparam.sysdate_lo = xparam->xnaparam.sysdate_hi = 0;	return ((struct mbuf *)m);}struct	mbuf *xnamkuser(sc, index, opcode)	struct xna_softc *sc;	int index, opcode;{	register struct mbuf *m;	register struct xnacmd_buf *xuser;	register int cnt;	int i;	/*	 * Allocate USER buffer	 */	XNAMCLGET(m);	if (!m)		return (0);	xuser = mtod(m, struct xnacmd_buf *);	m->m_len = sizeof(xuser->opcode) + sizeof(struct _xnaustart);	bzero(xuser, m->m_len);	xuser->opcode = opcode;	switch (index) {		/* 		 * Only handle the "generic ethernet user" for now		 */		case XNA_ETHERU:			xuser->xnaustart.sap_ptt = ETHERTYPE_IP;			xuser->xnaustart.mode =			    (USTART_UNK|USTART_BDC|USTART_BAD);			bcopy(sc->is_addr,&xuser->xnaustart.user_phys,6);			xuser->xnaustart.user_phys.xlen =			    ETHERMTU + sizeof(struct ether_header) + 4;			xuser->xnaustart.addr_alloc = NMULTI;			cnt = 0;			for (i = 0; i < NMULTI; i++) { 				if (sc->is_muse[i] > 0)					bcopy(sc->is_multi[i],					  &xuser->xnaustart.multi_addr[cnt++],6);			}			xuser->xnaustart.addr_len = cnt;#ifdef	IFF_PROMISC			if (sc->is_if.if_flags & IFF_PROMISC)				xuser->xnaustart.mode |= USTART_PROM;#endif	IFF_PROMISC			break;		default:			m_freem(xuser);			return (0);	}	return ((struct mbuf *)m);}xnagetctrs (sc, ctr, xcmd)	register struct xna_softc *sc;	register struct estat *ctr;	register struct xnacmd_buf *xcmd;{	register int seconds;	/*	 * Fill out the ethernet counters based upon the information	 * returned by the CMD_{RDC,RCC}CNTR command. This is pretty	 * disgusting, but necessary...	 */	bzero (ctr, sizeof(struct estat));	seconds = time.tv_sec - sc->ztime;	if (seconds & 0xffff0000)	    ctr->est_seconds = 0xffff;	else	    ctr->est_seconds = seconds & 0xffff;	if (*(u_long *)xcmd->xnactrs.bytercvd.hi)	    ctr->est_bytercvd = 0xffffffff;	else	    ctr->est_bytercvd = *(u_int *)xcmd->xnactrs.bytercvd.lo;	if (*(u_long *)xcmd->xnactrs.bytesent.hi)	    ctr->est_bytesent = 0xffffffff;	else	    ctr->est_bytesent = *(u_int *)xcmd->xnactrs.bytesent.lo;	if (*(u_long *)xcmd->xnactrs.blokrcvd.hi)	    ctr->est_blokrcvd = 0xffffffff;	else	    ctr->est_blokrcvd = *(u_int *)xcmd->xnactrs.blokrcvd.lo;	if (*(u_long *)xcmd->xnactrs.bloksent.hi)	    ctr->est_bloksent = 0xffffffff;	else	    ctr->est_bloksent = *(u_int *)xcmd->xnactrs.bloksent.lo;	if (*(u_long *)xcmd->xnactrs.mbytercvd.hi)	    ctr->est_mbytercvd = 0xffffffff;	else	    ctr->est_mbytercvd = *(u_int *)xcmd->xnactrs.mbytercvd.lo;	if (*(u_long *)xcmd->xnactrs.mblokrcvd.hi)	    ctr->est_mblokrcvd = 0xffffffff;	else	    ctr->est_mblokrcvd = *(u_int *)xcmd->xnactrs.mblokrcvd.lo;	if (*(u_long *)xcmd->xnactrs.mbytesent.hi)	    ctr->est_mbytesent = 0xffffffff;	else	    ctr->est_mbytesent = *(u_int *)xcmd->xnactrs.mbytesent.lo;	if (*(u_long *)xcmd->xnactrs.mbloksent.hi)	    ctr->est_mbloksent = 0xffffffff;	else	    ctr->est_mbloksent = *(u_int *)xcmd->xnactrs.mbloksent.lo;	if (*(u_long *)xcmd->xnactrs.deferred.hi)	    ctr->est_deferred = 0xffffffff;	else	    ctr->est_deferred = *(u_int *)xcmd->xnactrs.deferred.lo;	if (*(u_long *)xcmd->xnactrs.single.hi)	    ctr->est_single = 0xffffffff;	else	    ctr->est_single = *(u_int *)xcmd->xnactrs.single.lo;	if (*(u_long *)xcmd->xnactrs.multiple.hi)	    ctr->est_multiple = 0xffffffff;	else	    ctr->est_multiple = *(u_int *)xcmd->xnactrs.multiple.lo;	if ((*(u_long *)xcmd->xnactrs.collis.hi) ||	    (*(u_long *)xcmd->xnactrs.collis.lo & 0xffff0000))	    ctr->est_collis = 0xffff;	else	    ctr->est_collis = *(u_short *)xcmd->xnactrs.collis.lo;	if ((*(u_long *)xcmd->xnactrs.unrecog.hi) ||	    ((*(u_long *)xcmd->xnactrs.unrecog.lo) & 0xffff0000))	    ctr->est_unrecog = 0xffff;	else	    ctr->est_unrecog = *(u_short *)xcmd->xnactrs.unrecog.lo;	if ((*(u_long *)xcmd->xnactrs.overrun.hi) ||	    (*(u_long *)xcmd->xnactrs.overrun.lo & 0xffff0000))	    ctr->est_overrun = 0xffff;	else	    ctr->est_overrun = *(u_short *)xcmd->xnactrs.overrun.lo;	if ((*(u_long *)xcmd->xnactrs.sysbuf.hi) ||	    (*(u_long *)xcmd->xnactrs.sysbuf.lo & 0xffff0000))	    ctr->est_sysbuf = 0xffff;	else	    ctr->est_sysbuf = *(u_short *)xcmd->xnactrs.sysbuf.lo;	if ((*(u_long *)xcmd->xnactrs.userbuf.hi) ||	    (*(u_long *)xcmd->xnactrs.userbuf.lo & 0xffff0000))	    ctr->est_userbuf = 0xffff;	else	    ctr->est_userbuf = *(u_short *)xcmd->xnactrs.userbuf.lo;	if ((*(u_long *)xcmd->xnactrs.sendfail_retry.hi) ||	    (*(u_long *)xcmd->xnactrs.sendfail_retry.lo)) {	    ctr->est_sendfail_bm |= 0x01;	    ctr->est_sendfail =	    			*(u_long *)xcmd->xnactrs.sendfail_retry.lo;	}	if ((*(u_long *)xcmd->xnactrs.sendfail_carrier.hi) ||	    (*(u_long *)xcmd->xnactrs.sendfail_carrier.lo)) {	    ctr->est_sendfail_bm |= 0x02;	    ctr->est_sendfail +=	    			*(u_long *)xcmd->xnactrs.sendfail_carrier.lo;	}	if ((*(u_long *)xcmd->xnactrs.sendfail_short.hi) ||	    (*(u_long *)xcmd->xnactrs.sendfail_short.lo)) {	    ctr->est_sendfail_bm |= 0x04;	    ctr->est_sendfail +=	    			*(u_long *)xcmd->xnactrs.sendfail_short.lo;	}	if ((*(u_long *)xcmd->xnactrs.sendfail_open.hi) ||	    (*(u_long *)xcmd->xnactrs.sendfail_open.lo)) {	    ctr->est_sendfail_bm |= 0x08;	    ctr->est_sendfail +=	    			*(u_long *)xcmd->xnactrs.sendfail_open.lo;	}	if ((*(u_long *)xcmd->xnactrs.sendfail_long.hi) ||	    (*(u_long *)xcmd->xnactrs.sendfail_long.lo)) {	    ctr->est_sendfail_bm |= 0x10;	    ctr->est_sendfail +=	    			*(u_long *)xcmd->xnactrs.sendfail_long.lo;	}	if ((*(u_long *)xcmd->xnactrs.sendfail_defer.hi) ||	    (*(u_long *)xcmd->xnactrs.sendfail_defer.lo)) {	    ctr->est_sendfail_bm |= 0x20;	    ctr->est_sendfail +=	    			*(u_long *)xcmd->xnactrs.sendfail_defer.lo;	}	if ((*(u_long *)xcmd->xnactrs.recvfail_crc.hi) ||	    (*(u_long *)xcmd->xnactrs.recvfail_crc.lo)) {	    ctr->est_recvfail_bm |= 0x01;	    ctr->est_recvfail =	    			*(u_long *)xcmd->xnactrs.recvfail_crc.lo;	}	if ((*(u_long *)xcmd->xnactrs.recvfail_frame.hi) ||	    (*(u_long *)xcmd->xnactrs.recvfail_frame.lo)) {	    ctr->est_recvfail_bm |= 0x02;	    ctr->est_recvfail +=	    			*(u_long *)xcmd->xnactrs.recvfail_frame.lo;	}	if ((*(u_long *)xcmd->xnactrs.recvfail_long.hi) ||	    (*(u_long *)xcmd->xnactrs.recvfail_long.lo)) {	    ctr->est_recvfail_bm |= 0x04;	    ctr->est_recvfail +=	    			*(u_long *)xcmd->xnactrs.recvfail_long.lo;	}}#endif

⌨️ 快捷键说明

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