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

📄 if_ne.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 3 页
字号:
				return;			}			tlen = neput(sc,index,m);			rp->ne_info |=  NE_TFS | NE_TLS ; 		}		rp->ne_bsize = tlen;		rp->ne_own = NE_OWN;			sc->nxmit++;		sc->is_if.if_flags |= IFF_OACTIVE;		csrpt->csr1 = NE_CSR1_PD; 		wbflush();		sc->is_if.if_timer = 5;			 	} } /* * Ethernet interface interrup processor  */neintr(unit)	int	unit;{        register struct ne_softc *sc = &ne_softc[unit];	register struct ifnet *ifp = &sc->is_if;	register u_long	csr;	u_long csr6;	NECSRS *csrpt = sc->ne_csrs;	int s;	s = splimp();	csr =csrpt->csr5;	/* save the old csr5 */	csrpt->csr5 = csr; 	/* clear the csr5 */	wbflush();	if ( csr & NE_CSR5_TW ) {		netbablcnt++;		if(nedebug)			mprintf("ne%d: transmit timeout (TW)\n",unit);		/* reset the chip */		nereset(sc);		splx(s);		return;	}	if ( csr & NE_CSR5_RU ) {			/* Receive Buffer Unavailable. 			 * When set, indicateds that the next descriptor			 * on the receive list is owned by the host.			 * That means a packet was lost			 */		 nemisscnt++;		 if(nedebug)			mprintf("ne%d: missed packet (Receiv Buffer Unavailable)",unit);		if(sc->ctrblk.est_sysbuf != 0xffff)			sc->ctrblk.est_sysbuf++;		/* Do not need to poll the receive. The SGEC will turn		 * on the receive running state when next frame arrive 	         */ 	}	if ( csr & NE_CSR5_ME ) {			/*			 * Memory Error			 * It happened when any one of followings occur: 			 * 1) host memory problem			 * 2) Parity error detected on an host to SGEC			 *   CSR write or SGEC read from memory			 */				nemerrcnt++;		mprintf("ne%d: memory error (MERR) \n", unit);		nereset(sc);		splx(s);		return;		}	if ( csr & NE_CSR5_RI )		nerint(unit);	if ( csr & NE_CSR5_TI )		netint(unit);	splx(s);}/* * Ethernet interface transmit interrupt */netint(unit)	int unit;{	register struct ne_softc *sc = &ne_softc[unit];	register int index = sc->otindex;	register int i;	register NEDESC *rp= &sc->tring[sc->otindex];	register u_long status;	struct mbuf *mp,*mp0;	struct ether_header *eh;	NECSRS *csrpt = sc->ne_csrs;	int 	nNENXMT = sc->ntring;	struct ifnet *ifp = &sc->is_if;	int	ccount;	short   tlen;	while ( (sc->otindex != sc->tindex) && ( rp->ne_own != NE_OWN ) && sc->nxmit > 0 ) { 		status = rp->ne_flag;		tlen = rp->ne_bsize; 		/*		 * Found last buffer in the packet		 * (hence a valid string of descriptors)		 * so free things up.		 */		mp = sc->smbuf[index];		sc->smbuf[index] = (struct mbuf *)NULL; 		if(!(--sc->nxmit)) {			ifp->if_timer=0; 			sc->is_if.if_flags &= ~IFF_OACTIVE;		}		if(!(rp->ne_info & NE_DT_TSET)) { /* not a setup packet */			/* 			 * Network statistics			 */			sc->is_if.if_opackets++;			ccount = (status & NE_CC) >> 3;				if(ccount && !(status & NE_LC)) {				sc->is_if.if_collisions += ccount;				/*				 * Decnet statistics				 */				if (ccount) { /* collision happened */					if(ccount == 1) {						if (sc->ctrblk.est_single != (unsigned)0xffffffff)							sc->ctrblk.est_single++;					} else  /* more than one */						if(sc->ctrblk.est_multiple != (unsigned)0xffffffff);							sc->ctrblk.est_multiple++;			  	} 			}			if(status & NE_DE) 				if (sc->ctrblk.est_deferred != (unsigned) 0xffffffff)			 		sc->ctrblk.est_deferred++;						 /* Heartbeat Fail */			 if((status & NE_HF) && !(status & NE_UF)) 				if (sc->ctrblk.est_collis != 0xffff)					sc->ctrblk.est_collis++;			/*			 * Check for transmission errors			 */			 if(status & NE_ES) {				sc->is_if.if_oerrors++;				if (sc->ctrblk.est_sendfail != 0xffff) {					sc->ctrblk.est_sendfail++;					if (status & NE_EC ) {/* Excessive Collisions */						if (nedebug) mprintf("ne%d: excseeive collision (EC)\n",unit);							sc->ctrblk.est_sendfail_bm |= 1;					}					if (status & NE_LC && !(status & NE_UF)) {						if (nedebug) mprintf("ne%d: late transmit collision (LC)\n",unit);							sc->ctrblk.est_sendfail_bm |= 2; 						; /* not implemented */					}					if (status & (NE_NC | NE_LO) ) {					/* no carrier */						if (nedebug) mprintf("ne%d: no carrier or lost carrier (LO or NC)\n",unit);							sc->ctrblk.est_sendfail_bm |= 4;					}					if (status & NE_UF ) {/* Underflow error */						if (nedebug) mprintf("ne%d: underflow error (UF)\n",unit);					}					if (status & NE_TLE ) {/* Length error */						if (nedebug) mprintf("ne%d: transmit buffer length error (LE)\n",unit);					}				}				m_freem(mp);			}  else {				/*			 	 * Accumulate statistics for DECnet		 		 */				if ((sc->ctrblk.est_bytesent + tlen) > sc->ctrblk.est_bytesent)					sc->ctrblk.est_bytesent += tlen;                		if (sc->ctrblk.est_bloksent != (unsigned)0xffffffff)					sc->ctrblk.est_bloksent++;				/*			 	 * If this was a broadcast packet or if we				 * are in COPYALL mode, loop it back.				 * We will not free this buffer. 			 	 * This buffer will be reused. 			 	 */				if (mp) {					eh = mtod( mp, struct ether_header *);					if ((!(bcmp(eh->ether_dhost,ne_multi,6))) || (sc->is_if.if_flags & IFF_PFCOPYALL)) {						for(mp0 = mp ,tlen=0; mp0 ;mp0 =mp0->m_next) {	tlen += mp0->m_len; }						neread(sc,0,mp,index,tlen);					} else						m_freem( mp );				}			}		} else { /* this is a setup frame */			if ( status & NE_SETUP_SE ) {				printf("ne%d: setup frame buffer size error ( should be 128 bytes ) \n ",unit);				neinit(unit);			}		}		/*		 * Init the buffer descriptor		 */		neinitdesc(&sc->tring[index],sc->tmbuf[index],0);		sc->otindex = index = ++index % nNENXMT;		rp = (NEDESC *) &sc->tring[index];	}	/*	 * Dequeue next transmit request	 */	if (sc->nxmit > 0 && (sc->tring[sc->otindex].ne_own == NE_OWN )) {		csrpt->csr1 = NE_CSR1_PD;		wbflush();	}	if (!(ifp->if_flags & IFF_OACTIVE)) 		nestart( unit );}/* * Ethernet interface  receiver interrupt. */nerint(unit)	int	unit;{	register struct ne_softc *sc = &ne_softc[unit];	register NEDESC  *rp;	register int index;	register struct ifnet *ifp = &sc->is_if;	register int first;	int	nNENRCV = sc->nrring;	int	rlen;		/*	* Traverse the receive ring looking for packets to pass back.	* The search is complete when we find a descriptor not in use (	* which means own by SGEC ).	*/	rp = &sc->rring[sc->rindex];	for (index = sc->rindex; !(rp->ne_own & NE_OWN) ; rp = &sc->rring[index]) {				/*		 * We don't need to check the chained packet.		 * The SGEC will filter out those chained packet by		 * setting the CSR6 DC bit on. The RDES0<FS,LS> will		 * always be set		 */				if(!(rp->ne_flag & NE_ES)) { /* valid descriptor */			struct mbuf *m1;			/*		 	 * If can not allocate a cluster mbuf for switch, just		 	 * drop this packet		 	 */			NEMCLGET(m1);			if(m1 == 0) {				nenolmbuf++;				/*				 * already bumpped up 2 bytes				 */				neinitdesc(rp,sc->rmbuf[index],0);							} else {				rlen = rp->ne_com & 0x00007fff ;#ifdef mips				clean_dcache(PHYS_TO_K0(rp->ne_bfaddr),rlen);#endif mips				neread(sc,rp,(struct mbuf *)0,index,rlen);				neinitdesc(rp,m1,1);				sc->rmbuf[index]=m1;			}		/* 		 * Else not a good packet, check for errors		 */		} else {			sc->is_if.if_ierrors++;			if(nedebug)  				mprintf("ne%d: recv err %02x\n",unit,rp->ne_flag&0xff);			if(sc->ctrblk.est_recvfail != 0xffff) {				sc->ctrblk.est_recvfail++;				if(rp->ne_flag & NE_OF) { /* overflow */					sc->ctrblk.est_recvfail_bm |=4 ;#if NPACKETFILTER > 0					sc->is_ed.ess_missed++;#endif NPACKETFILTER > 0				}				if(rp->ne_flag & NE_CE ) { /* CRC error */					if(rp->ne_flag & NE_DB ) 					/* Block check error */						sc->ctrblk.est_recvfail_bm |=1 ;					else					/* Frame error */						sc->ctrblk.est_recvfail_bm |=2 ;				}				if(rp->ne_flag & NE_CS) { /* Collision seen */					sc->ctrblk.est_recvfail_bm |=2 ;				}				if(rp->ne_flag & NE_RTL) { /* Frame too long */					sc->ctrblk.est_recvfail_bm |=4 ;				}				if((rp->ne_flag & NE_RF) && !(rp->ne_flag & NE_OF)) { 				/* Runt Frame - will only receive if */				/* CSRT6 <PB> is set. Meaningless if */				/* RDES0<OF> is set	*/					sc->ctrblk.est_recvfail_bm |=4 ;				}				if(rp->ne_flag & NE_RLE ) { /* length error */							;				}			neinitdesc(rp,sc->rmbuf[index],0);			} 		}		rp->ne_own = NE_OWN;		sc->rindex = index =  ++index % nNENRCV;	}}		/*  * Pass a packet to the higher levels. * We deal with the trailer protocol */neread(sc,dp,swloop,index,rlen)register struct ne_softc *sc;register NEDESC *dp;int index,rlen;struct mbuf *swloop;{	register struct ether_header *eptr, eh;	struct mbuf *m, *swloop_tmp1;	int off,resid,len;	struct ifqueue *inq;	/*	 * Deal with trailer protocol: if type is INET trailer	 * get true type from first 16-bit word past data.	 * Remember that type was trailer by setting off.	 */	if (swloop) {		eptr = mtod(swloop, struct ether_header *);                eh = *eptr;		eptr = &eh;		if ( swloop->m_len > sizeof(struct ether_header))			m_adj(swloop, sizeof(struct ether_header));		else {			MFREE(swloop,swloop_tmp1);			if ( ! swloop_tmp1 )				return;			else				 swloop = swloop_tmp1;		}	} else {		m = sc->rmbuf[index];		m->m_len = len = rlen - 4;	/* CRC */		eptr = mtod(m, struct ether_header *);		eh = *eptr;		eptr = &eh;	}        eptr->ether_type = ntohs((u_short)eptr->ether_type);	if ((eptr->ether_type >= ETHERTYPE_TRAIL &&	    eptr->ether_type < ETHERTYPE_TRAIL+ETHERTYPE_NTRAILER)) {	    	off = (eptr->ether_type - ETHERTYPE_TRAIL) * 512 +			  sizeof(struct ether_header);		if (off >= ETHERMTU)			  return;         /* sanity */		if (swloop) {			struct mbuf *mprev, *m0 = swloop;			mprev = m0;			while (swloop->m_next){/*real header at end of chain*/				mprev = swloop;				swloop = swloop->m_next;			}					/* move to beginning of chain */			mprev->m_next = 0;			swloop->m_next = m0;			eptr->ether_type = ntohs( *mtod(swloop, u_short *));		} else {			eptr->ether_type = 				ntohs(*(short *)(mtod(m, caddr_t) + off));			resid = ntohs(*(short *)(mtod(m, caddr_t) + off +2));			if (off + resid > m->m_len)				return;            /* sanity */		}	 } else {		off = 0;	 }	/*	 * Pull packet off interface.  (In the case of NE, only need	 * to allocate another mbuf to switch the old one )	 * Off is nonzero if packet has trailing header; 	 * this routine 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.	 */	if (swloop) {		m = m_copy(swloop, 0, M_COPYALL);		m_freem(swloop);		if (m == 0)			return;		len = m_length(m);	} else {		struct mbuf *m0 = m;		if (off) {			int nbytes;			int cnt = resid;			struct mbuf *n;			struct mbuf **mp = &m;			while (cnt > 0) {				MGET(n,M_DONTWAIT,MT_DATA);				if (n == 0) {					m_freem(m);					nenosmbuf++;					return;				}				nbytes = MIN(MLEN,cnt);				bcopy((mtod(m, caddr_t) + off),				       mtod(n, caddr_t), nbytes);				n->m_len = nbytes;				off += nbytes;				cnt -= nbytes;				*mp = n;				mp = &n->m_next;			}			*mp = m0;			m0->m_len -= resid;			/* strip out the trailer header */			m->m_off += 2 * sizeof (u_short);			m->m_len -= 2 * sizeof (u_short);		}		/*		 * Trim off ethernet header		 */

⌨️ 快捷键说明

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