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

📄 if_fza.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 5 页
字号:
		/*		 * Trim off fddi header		 */		m->m_off += sizeof (struct fddi_header);		m->m_len -= sizeof (struct fddi_header);	}	/*	 * Subtract length of header from len	 */	len -= sizeof (struct fddi_header);	/*	 * feed the ehter struct by the fddi struct	 */	/*	bcopy(&eptr->fddi_dhost[0],&eh.ether_dhost[0],6); */	/*	bcopy(&eptr->fddi_shost[0],&eh.ether_shost[0],6); */	/*      eh.ether_type = len; */	/*	 * Bunp up the DECnet counter	 */	sc->is_if.if_ipackets++;	fstc_bytercvd += len;	if ( fstc_pdurcvd != (unsigned) 0xffffffff)		fstc_pdurcvd++;	if( eptr->fddi_dhost[0] & 1 ) {		fstc_mbytercvd += len;		if(fstc_mpdurcvd != 0xffffffff)			fstc_mpdurcvd++;	}	/* Dispatch this packet */	net_read(&(sc->is_ed), (struct ether_header *)eptr, m, len, (swloop != NULL), 0 );}/* * Perform a node halt/reset (SOFT reset) due to the HALT state change * interrupt. */fzareset(unit)	int unit;{	register struct fza_softc *sc = &fza_softc[unit];	struct ifnet *ifp = &sc->is_if;	struct mbuf *mp, *m, *m1;	struct rmbuf *bp;	FZAXMTRING *tp;	FZARCVRING *rp;		int i;	/*	 * release all of the receive mbufs, transmit mbufs , and then reset 	 * the adapter	 */	for (i = 0, bp = &sc->rmbuf[0];  i < NFZARCV ; i++ ,bp++) {		if(bp->mbufa)			m_freem(bp->mbufa);		if(bp->mbufb)			m_freem(bp->mbufb);		bp->mbufa = bp->mbufb = 0; 		bp->phymbufa = bp->phymbufb = 0;	}	for ( i=0, tp = &sc->tring[0]; i < sc->nrmcxmt && tp->xmt_mbuf ; i++, tp++ ) {		m_freem(tp->xmt_mbuf);	}	/*	 * If the adapter is in SHUT state, don't do the selftest         */         if((sc->flag == FZA_NORMAL || sc->flag == FZA_PC_TRACED )) {		/*		 * take out this because it may happen FZAMAXRESET		 * times per year; the best way is use a ratio of 		 * how many times per hour . 		 */		/* 		if (!(sc->flag & FZA_PC_TRACED) && (++fzanreset > FZAMAXRESET))		 {			ifp->if_flags &= ~IFF_UP;			printf("fza %d: exceed the maximum number of reset\n",unit);			return(0);		}		*/		/*	 	 * do the adapter selftest	 	 */		if(!(fzaselftest(sc,unit))) { 			printf("fza%d: fzareset selftest fail \n",unit);			return(0);						}		/* set the interrup mask */		sc->reg_mask = FZA_INTR_MASK;	}        sc->tindex = sc->nxmit = sc->rindex = 0;        sc->tsmtindex = sc->rsmtindex = 0;        sc->cmdindex = sc->unsindex = 0;        sc->ltindex = sc->lcmdindex = -1;	sc->smtrmcindex = sc->lsmtrmcindex = 0;		if(!fzacmdinit(sc,unit)) {			printf("fza%d: fzrestart init command fail \n",unit);			return(0);	}	/*	 * fill the information	 */	fzafillinit(sc,sc->initblk);	/* set the interrup mask */	sc->reg_mask = FZA_INTR_MASK;	if(sc->flag == FZA_DLU) {		printf("fza%d: Firmware revision %c%c%c%c \n",unit,				sc->fw_rev[0],sc->fw_rev[1],sc->fw_rev[2],				sc->fw_rev[3]);		if(sc->nduflag & IFF_UP ) /* turn on this device */			ifp->if_flags |= IFF_RUNNING ;		else 			  /* turn off this device */			ifp->if_flags &= ~IFF_RUNNING ;	}	/*	 * clean the flag	 */	sc->flag = FZA_NORMAL;        /*         * allocate mbufs for receive ring         */        for (i = 0, rp = &sc->rring[0], bp = &sc->rmbuf[0] ; (i < NFZARCV ); 		i++, rp++ , bp++) {                FZAMCLGET(m)                if(m) {                         FZAMCLGET(m1)                	if (m1)                         	fzainitdesc(rp,bp, m, m1);			else                        	goto free;                 }  else                         goto free;        }        /*         * clear the transmit ring mbuf entry         */        for ( i=0, tp = &sc->tring[0]; i < sc->nrmcxmt ; i++, tp++)                         tp->xmt_mbuf = (struct mbuf *)0;		if(ifp->if_flags & IFF_RUNNING) {			ifp->if_flags &= ~(IFF_RUNNING);			untimeout(fzainit, unit); 			timeout(fzainit, unit, 1);	}		return(1);free:        for (i = 0, bp = &sc->rmbuf[i]; (i < NFZARCV ); i++, rp++) {                if(bp->mbufa)                        m_freem(bp->mbufa);                if(bp->mbufb)                        m_freem(bp->mbufb);        }	printf("fza%d: fzareset fail - can not allocate enough receive buffer \n",unit);	return(0);	}/* * Process an ioctl request. */fzaioctl(ifp, cmd, data)	register struct ifnet *ifp;	int cmd;	caddr_t data;{	register struct fza_softc *sc = &fza_softc[ifp->if_unit];	register struct fzacmd_buf *xcmd;	struct protosw *pr;	struct mbuf *m;	struct ifreq *ifr = (struct ifreq *)data;	struct ifdevea *ifd = (struct ifdevea *)data;	register struct ifaddr *ifa = (struct ifaddr *)data;	struct ctrreq *ctr = (struct ctrreq *)data;	struct ifeeprom *ife = (struct ifeeprom *)data;	int s, delay, error = 0, timeout = 0;	switch (cmd) {        case SIOCENABLBACK:        case SIOCDISABLBACK:		if (cmd == SIOCENABLBACK) { 			if(fzadebug) printf("SIOCENABLBACK");                	ifp->if_flags |= IFF_LOOPBACK;		} else {			if(fzadebug) printf("SIOCDISABLBACK");                	ifp->if_flags &= ~IFF_LOOPBACK;		}		if (ifp->if_flags & IFF_RUNNING) {			/*			 * Lock softc. issue a SHUT command 			 * to cause a state change and then		         * bring down the adapter and reset it 			 */			s = splimp();			smp_lock(&sc->lk_fza_softc, LK_RETRY);			sc->reg_ctla = SHUT;			sc->flag = FZA_SHUT;			/*		 	 * Wait 30 seconds for FZA change to Uninitialized state		 	 */ 				for (delay = 3000; delay > 0 && ((sc->reg_status & ADAPTER_STATE) != STATE_UNINITIALIZED) ; delay--)  				 DELAY(10000);			if((sc->reg_status & ADAPTER_STATE) == STATE_UNINITIALIZED)				fzareset(ifp->if_unit);			else				printf("fza%d: Can't transition to Uninitialize State \n",ifp->if_unit); 			smp_unlock(&sc->lk_fza_softc);			splx(s);		}                break;         case SIOCRPHYSADDR:                 /*                 * read default hardware address. Lock softc while accessing		 * per-unit physical address info.                 */		s = splimp();		smp_lock(&sc->lk_fza_softc, LK_RETRY);		bcopy(sc->is_dpaddr, ifd->default_pa, 6);		bcopy(sc->is_addr, ifd->current_pa, 6);		smp_unlock(&sc->lk_fza_softc);		splx(s);                break; 	case SIOCSPHYSADDR: 	case SIOCDELMULTI: 	case SIOCADDMULTI: 		/*		 * Lock softc while updating per-unit multicast address		 * list and for command processing as in "fzainit()".		 */		s = splimp();		smp_lock(&sc->lk_fza_softc, LK_RETRY);		if (cmd == SIOCDELMULTI) {			int i;			if(fzadebug > 1 ) printf("SIOCDELMULTI");			/*			 * If we're deleting a multicast address, decrement			 * the is_muse count and invalidate the address if			 * count goes to zero.			 */			for (i = 0; i < NMULTI; i++) {				if (bcmp(sc->is_multi[i],				    ifr->ifr_addr.sa_data,6) == 0)					break;			}			if ((i < NMULTI) && (--sc->is_muse[i] == 0))				bcopy(etherbroadcastaddr,sc->is_multi[i],6);			else {				smp_unlock(&sc->lk_fza_softc);				splx(s);				goto done;			}		} else {			int i, j = -1;			if( cmd == SIOCSPHYSADDR ) {			/*			 * we can not change the physical station			 * address; just add an entry to the CAM as 			 * an alais address			 */				if(fzadebug > 1)					printf("SIOCSPHYSADDR");		               			bcopy(ifr->ifr_addr.sa_data, sc->is_addr, 6);#if NPACKETFILTER > 0                		pfilt_newaddress(sc->is_ed.ess_enetunit, ifr->ifr_addr.sa_data);#endif NPACKETFILTER > 0						}			else {				if(fzadebug > 1 ) 					printf("SIOCADDMULTI");						} 			/*			 * If we're adding a multicat address, increment the			 * is_muse count if it's already in our table, and			 * return. Otherwise, add it to the table or return			 * ENOBUFS if we're out of entries.			 */			for (i = 0; i < NMULTI; i++) {				if (bcmp(sc->is_multi[i],				    ifr->ifr_addr.sa_data,6) == 0) {					sc->is_muse[i]++;					smp_unlock(&sc->lk_fza_softc);					splx(s);					goto done;				}				if ((j < 0) && (bcmp(sc->is_multi[i],				    etherbroadcastaddr,6) == 0))					j = i;			}			if (j < 0) {				printf("fza%d: addmulti failed, multicast list full: %d\n",					ifp->if_unit, NMULTI);				smp_unlock(&sc->lk_fza_softc);				error = ENOBUFS;				splx(s);				goto done;			} else {		    		bcopy(ifr->ifr_addr.sa_data,				      sc->is_multi[j], 6);		    		sc->is_muse[j]++;			}		}		if (ifp->if_flags & IFF_RUNNING) {			/*			 * If we've successfully init'ed the interface,			 * issue a MODCAM command to update the fddi			 * user's multicast address list. Otherwise, the			 * list will be initialized upon the first call			 * to "fzainit()".			 */			FZACMDRING *cp;			if (cp=fzamkcmd(sc, CMD_MODCAM,ifp->if_unit)) {				smp_unlock(&sc->lk_fza_softc);				splx(s);				FZATIMEOUT(cp,timeout)/* Wait */				if(timeout ||  (cp->status_id != CMD_SUCCESS)) 						error = EINVAL;			} else {				smp_unlock(&sc->lk_fza_softc);				error = ENOBUFS;				splx(s);			}		}		else {			smp_unlock(&sc->lk_fza_softc);			splx(s);		}		break;	case SIOCRDZCTRS:	case SIOCRDCTRS:		if(fzadebug) {			if (cmd == SIOCRDZCTRS) 					printf("SIOCRDZCTRS");			else 					printf("SIOCRDCTRS");		}					/*		 * The adapter does not support clear counter command.		 * So, we only support read counter. 		 *		 * Copyin most recent contents of unit's counter		 * block.		 */		if ((ifp->if_flags & IFF_RUNNING) ||		   (sc->reg_status & ADAPTER_STATE) == STATE_RUNNING || 		   (sc->reg_status & ADAPTER_STATE) == STATE_MAINTENANCE || 		   (sc->reg_status & ADAPTER_STATE) == STATE_INITIALIZED ) 		{			switch (ctr->ctr_type) {				case FDDIMIB_SMT:				case FDDIMIB_MAC:				case FDDIMIB_PATH:				case FDDIMIB_PORT:				case FDDIMIB_ATTA:					fmib_fill(sc,ctr,ctr->ctr_type);					break;					case FDDI_STATUS:					fzagetstatus(sc, &ctr->sts_fddi,sc->statusblk);					break;				default:					fzagetctrs(sc, &ctr->ctr_fddi,sc->ctrblk);					ctr->ctr_type = CTR_FDDI;					break;			}		}		break;	case SIOCSIFADDR:		/*		 * Init the interface if its not already running		 */		if(fzadebug) printf("SIOCSIFADDR");		fzainit(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 INET		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 MODPROM command to update the ethernet 			 * user's promiscuous bit based upon the interface			 * flags.			 *			 * Only support LLC promiscuous mode for now 			 */			FZACMDRING *cp;			s = splimp();			smp_lock(&sc->lk_fza_softc, LK_RETRY);			if (cp =fzamkcmd(sc, CMD_MODPROM,ifp->if_unit)) {				smp_unlock(&sc->lk_fza_softc);				splx(s);				FZATIMEOUT(cp,timeout)				if(timeout ||  (cp->status_id != CMD_SUCCESS)) 						error = EINVAL;			} else {				smp_unlock(&sc->lk_fza_softc);				error = ENOBUFS;				splx(s);			}		}		break;#endif	IFF_PROMISC	case SIOCIFRESET: /* reset the adapter */					if(fzadebug) printf ("SIOCIFRESET \n");		s = splimp();		smp_lock(&sc->lk_fza_softc, LK_RETRY);		if(!fzaselftest(sc,ifp->if_unit)) {			printf(" SIOCIFRESET selftest fail \n");			smp_unlock(&sc->lk_fza_softc);			splx(s);			return(sc->reg_status & ID_FIELD);		} else			/*			 * self test successed the adapter is in			 * Uninitialized state, do the driver 			 * reset.			 */			sc->flag = FZA_DLU;			fzareset(ifp->if_unit);			/*			 * turn on the timer 			 */			ifp->if_timer = 1;			smp_unlock(&sc->lk_fza_softc);			splx(s);			return(0);		break;	case SIOCEEUPDATE: /* EEPROM update */			if(fzadebug) printf("SIOCEEUPDATE \n");		s = splimp();		smp_lock(&sc->lk_fza_softc, LK_RETRY);		/*	 	 * if the adapter is not in the uninitialized mode, force it	 	 * to that mode.	 	 */		if(((sc->reg_status & ADAPTER_STATE) != STATE_UNINITIALIZED) && 			((sc->reg_status & ADAPTER_STATE) !=  STATE_RESET )) {			/*turn off the read counters routine */			ifp->if_timer = 0; 			/* save the original state */			sc->nduflag = ifp->if_flags ;			/* disable the interface */			ifp->if_flags &= ~IFF_UP;			sc->reg_intr = sc->reg_intr ;				sc->reg_ctla = SHUT;			/*		 	 * Wait 30 seconds for FZA state change		 	 */ 				for (delay = 3000; delay > 0 && !(sc->reg_intr & STATE_CHG); delay-- )				 DELAY(10000);			/*		 	 * check for state change			 */			if(!(sc->reg_intr & STATE_CHG)) {				printf("fza%d: Down Line Upgrade state change time out\n",ifp->if_unit);				smp_unlock(&sc->lk_fza_softc);				splx(s);

⌨️ 快捷键说明

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