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

📄 if_ne.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 3 页
字号:
		 m0->m_off += sizeof (struct ether_header);		 m0->m_len -= sizeof (struct ether_header);		/*	 	 * Subtract length of header from len	 	 */		len -= sizeof (struct ether_header);	 }	/*	 * Bump up DECnet counters. Input packets for "netstat" include	 * ALL directed, multicast, and error inputs. For DECnet, only	 * error-free input packets are counted.	 */	sc->is_if.if_ipackets++;	sc->ctrblk.est_bytercvd += len ;	if (sc->ctrblk.est_blokrcvd != (unsigned) 0xffffffff)		sc->ctrblk.est_blokrcvd++;	if( eptr->ether_dhost[0] & 1 ) {		sc->ctrblk.est_mbytercvd += len;			if (sc->ctrblk.est_mblokrcvd != (unsigned) 0xffffffff)					sc->ctrblk.est_mblokrcvd++;	}	/* Dispatch this packet */	net_read(&(sc->is_ed), eptr, m, len, (swloop != NULL), (off != 0));}/* * Process an ioctl request */neioctl(ifp, cmd, data)register struct ifnet *ifp;int cmd;caddr_t data;{	register struct ne_softc *sc = &ne_softc[ifp->if_unit];	struct ifreq *ifr = (struct ifreq *)data;	struct ifdevea *ifd = (struct ifdevea *)data;	struct ctrreq *ctr = (struct ctrreq *)data;	struct protosw *pr;	struct ifaddr *ifa = (struct ifaddr *)data;	NECSRS	*csrpt = sc->ne_csrs;	int s, i, error = 0 , j = -1, delay;	s = splimp();	switch (cmd) {	case SIOCENABLBACK:	case SIOCDISABLBACK:		if ( cmd == SIOCENABLBACK ) { 			if (nedebug>1) printf("SIOCENABLBACK ");			mprintf("ne%d: internal loopback enable requested\n",				ifp->if_unit);       		        ifp->if_flags |= IFF_LOOPBACK;		} else {			if (nedebug>1) printf("SIOCDISABLBACK ");			mprintf("ne%d: internal loopback disable requested\n", 				ifp->if_unit);                	ifp->if_flags &= ~IFF_LOOPBACK;		}		if ( ifp->if_flags & IFF_RUNNING ) { 			csrpt->csr6 = ~(NE_CSR6_SR | NE_CSR6_ST);			/*			 *  polling CSR5 <TS> and <RS>			 */			for (delay = 10000; delay && (csrpt->csr5 &			(NE_TS_STP | NE_RS_STP)) ; delay--);			neinit(ifp->if_unit);		}		break; 	case SIOCRPHYSADDR:		/*		 * read default hardware address		 */		if (nedebug>1) printf("SIOCRPHYSADDR ");		bcopy(sc->is_addr, ifd->current_pa, 6);		for ( i = 0 ; i < 6 ; i++ ) 				ifd->default_pa[i] = sc->ne_narom[i * 4 ];		break; 	case SIOCSPHYSADDR:		if (nedebug>1) printf("SIOCSPHYSADDR ");		bcopy(ifr->ifr_addr.sa_data,sc->is_addr,6);#if NPACKETFILTER > 0		pfilt_newaddress(sc->is_ed.ess_enetunit, sc->is_addr);#endif NPACKETFILTER > 0		for ( i = 0; i < 6; i++ )			sc->ne_setup[0].setup_char[i] = sc->is_addr[i];		if (ifp->if_flags & IFF_RUNNING) {			nesetup( sc,0 );			nestart( ifp->if_unit ); 		} else			nesetup( sc, 0 );		break;	case SIOCDELMULTI:	case SIOCADDMULTI:		if (cmd == SIOCDELMULTI) {			if (nedebug>1) printf("SIOCDELMULTI ");			for (i = 0; i < NMULTI - 1 ; i++) {				if (bcmp(&sc->multi[i],ifr->ifr_addr.sa_data,MULTISIZE) == 0) {					if (--sc->muse[i] == 0)						bcopy(ne_multi,&sc->multi[i],MULTISIZE);					if (neshowmulti) 						printf("%d deleted.  \n",i);				}			}		} else {			if (nedebug>1) printf("SIOCADDDMULTI ");			for (i = 0; i < NMULTI - 1 ; i++) {				if (bcmp(&sc->multi[i],ifr->ifr_addr.sa_data,MULTISIZE) == 0) {					sc->muse[i]++;					if (neshowmulti) printf("already using index %d\n",i);					goto done;				}				if (bcmp(&sc->multi[i],ne_multi,MULTISIZE) == 0)					j = i;			}			/*			 * j is initialized to -1; if j > 0, then			 * represents the last valid unused location			 * in the multicast table.			 */			if (j == -1) {				printf("ne%d: SIOCADDMULTI failed, multicast list full: %d\n",ifp->if_unit,NMULTI);				error = ENOBUFS;				goto done;			}			bcopy(ifr->ifr_addr.sa_data, &sc->multi[j], MULTISIZE);			sc->muse[j]++;			if (neshowmulti)				printf("added index %d.\n", j);		}		for ( i = 0; i < 6; i++ )			sc->ne_setup[0].setup_char[i] = sc->is_addr[i];		if (ifp->if_flags & IFF_RUNNING) {			nesetup( sc, 0 );			nestart ( ifp->if_unit );		} else			nesetup( sc, 0 );		break;	case SIOCRDCTRS:	case SIOCRDZCTRS:		if (nedebug>1) printf("SIOCRDCTRS ");		ctr->ctr_ether = sc->ctrblk;		ctr->ctr_type = CTR_ETHER;		ctr->ctr_ether.est_seconds = (time.tv_sec - sc->ztime) > 0xfffe ? 0xffff : (time.tv_sec - sc->ztime);		if (cmd == SIOCRDZCTRS) {			if (nedebug>1) printf("SIOCRDZCTRS ");			sc->ztime = time.tv_sec;			bzero(&sc->ctrblk, sizeof(struct estat));		}		break;	case SIOCSIFADDR:		if (nedebug>1) printf("SIOCSIFADDR ");		ifp->if_flags |= IFF_UP;		neinit(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		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:		/* 		* Run a setup packet in case things have changed; 		* someone may be trying to turn on (or off) promiscuous 		* mode, for example. 		*/		if (ifp->if_flags & IFF_RUNNING) { 			ifp->if_flags &= ~IFF_RUNNING;  			neinit( ifp->if_unit );			}		break;#endif IFF_PROMISC	default:		error = EINVAL;	}done:	splx(s);	return (error);}/* * Put an mbuf chain into the appropriate transmit mbuf */neput(sc, index, m)struct ne_softc *sc;int index;register struct mbuf *m;{	register caddr_t dp,bp;	register int len = 0;	struct mbuf *m0;	m0 = m;	bp = mtod(sc->tmbuf[index],caddr_t);	while(m) {		if (m->m_len != 0) { 			dp = mtod(m,caddr_t);			bcopy(dp,bp,(unsigned)m->m_len);			bp += m->m_len;			len += m->m_len;		}		m = m->m_next;	}		if(len < MINDATA) {		bzero(bp,MINDATA - len);		len = MINDATA;	}	/* 	 * save the mbuf chain pointer	 */	sc->smbuf[index]=m0;return(len);}/*			  * fill out the setup packet - the physical address will already be * presented in first row */nesetup(sc,flag)struct ne_softc *sc;int flag;{	register int i, j;	/* 	 * fill out the broadcast address to the rest of the entries 	 * the first one will be the station address. The second one         * will be all 1's 	 *  	 */	for( j=1; j <= 15  ; j ++ )		bcopy(ne_multi,&sc->ne_setup[j],6);	/* 	 * If there have multicast addresses, just fill in the rest of	 * setup frame. 	 */	for( i = 0, j = 2 ; i < NMULTI - 2 ; i++) {		if(bcmp(&sc->multi[i],ne_multi,6) != 0) {			bcopy(&sc->multi[i],&sc->ne_setup[j],6);				j++;		}	}	sc->setupqueued++;	if(flag)		sc->ne_setup_ic = 1;}			/*  * Initialize a ring descriptor */neinitdesc(descp,m,type) register NEDESC *descp;register struct mbuf *m;int type;{	/* 	 * Zero the descriptor	 */	 bzero (descp, sizeof(NEDESC));	/* 	 * 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.	 */	if(type)		m->m_off +=2;	/* +4 for CRC */	descp->ne_bsize = ETHERMTU + sizeof(struct ether_header) + 4; #ifdef vax	descp->ne_bfaddr = svtopte(mtod(m,u_long *));	descp->ne_pg_off = (unsigned)dp&PGOFFSET;	descp->ne_info = NE_VA;#else 	descp->ne_bfaddr = svtophy(mtod(m,u_long *));	descp->ne_info = 0; #endif	return;}/* * Reset the SGEC chip, check the selftest, reallocate the mbuf  */nereset(sc)struct ne_softc *sc;{	struct ifnet *ifp = &sc->is_if;	int i;	neresets++;	/*	 * Stop network activity	 */	if (ifp->if_flags & IFF_RUNNING)                 ifp->if_flags &= ~(IFF_UP | IFF_RUNNING);	if (nedebug)		mprintf("nereset: reseted ne%d %d\n",ifp->if_unit,neresets);	nesoftreset(sc,ifp->if_unit);	nesetcsr0(sc,ifp->if_unit);#ifdef vax	csrpt->csr7 = (u_long) mfpr(SBR);#endif	/*	 * free up all the xmt mbufs 	 */	for (i=0; i < sc->ntring; i++) {		if(sc->tmbuf[i])			m_freem(sc->tmbuf[i]);		sc->tmbuf[i] = (struct mbuf *)NULL;		if(sc->smbuf[i])			m_freem(sc->smbuf[i]);		sc->smbuf[i] = (struct mbuf *)NULL;	}	/*	 * free up all the rcv mbufs	 */	for (i=0; i < sc->nrring; i++) {		if(sc->rmbuf[i])			m_freem(sc->rmbuf[i]);		sc->rmbuf[i] = (struct mbuf *)NULL;	}	neinit(ifp->if_unit);}	/* * Reset the SGEC chip, check the selftest result and initialize the * CSR1 */nesoftreset(sc,unit)struct ne_softc *sc;int unit;{	register NECSRS *csrpt = sc->ne_csrs; 	int delay;	/* 	 * Reset the SGEC chip 	 * Wait up to 25ms for complete the reset	 * and initialization 	 */	csrpt->csr6 = NE_CSR6_RE ;	for(delay=100; !(csrpt->csr5 & NE_CSR5_ID) || delay < 0 ; delay--) 			DELAY(2500);	if (!(csrpt->csr5 & NE_CSR5_ID)) {			printf("ne%d : cannot reset the SGEC chip \n",unit);			return(0);			}	/* 	 * self test check routine  	 * SGEC self test takes 25ms to complete after Hardware or software 	 * reset  	 */	if(!(csrpt->csr5 & NE_CSR5_SF )) 		return ((int)csrpt); /* selftest success */	else if(csrpt->csr5 & NE_SS_ROM) 		printf("ne%d : self test failed - ROM error\n",unit); 	else if(csrpt->csr5 & NE_SS_RAM)		printf("ne%d : self test failed - RAM error\n",unit);	else if(csrpt->csr5 & NE_SS_AFR)		printf("ne%d : self test failed - Address Filter RAM error\n",unit);	else if(csrpt->csr5 & NE_SS_TFF)		printf("ne%d : self test failed - Transmit FIFO error\n",unit);	else if(csrpt->csr5 & NE_SS_RFF)		printf("ne%d : self test failed - Receive FIFO error\n",unit);	else if(csrpt->csr5 & NE_SS_SLE)		printf("ne%d : self test failed - Lookback error\n",unit);	return(0);}/*  * initialize the CSR0 with IPL, SA and IV */nesetcsr0(sc,unit)struct ne_softc *sc;int unit;{	u_long csr=sc->ne_initcsr;	NECSRS *csrpt=sc->ne_csrs;	int s,retry,csr0;	s = splimp();  /* raise the ipl to disable other interrupt */ 	for (retry=5; (csr0 != sc->ne_initcsr) && (retry >= 0); retry--) 		{  		csrpt->csr0 = sc->ne_initcsr;		wbflush();		csr0 = csrpt->csr0 ;			}	splx(s);	if(csr0 != sc->ne_initcsr) { 		printf("ne %d : fail to write CSR0",unit);		return(0);		}	else {		/* check for the pending parrity error interrupt */		if( csrpt->csr5 & NE_CSR5_ME )			csrpt->csr5 = NE_CSR5_IS | NE_CSR5_ME ; 		return(csr);		}}newatch(unit)int unit;{	register struct ne_softc *sc = &ne_softc[unit];	register struct ifnet *ifp = &sc->is_if;	int s;	s = splimp();	ifp->if_timer = 0;	nereset(sc);	splx(s);}

⌨️ 快捷键说明

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