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

📄 if_de.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 3 页
字号:
	}	return (top);bad:	m_freem(top);	return (0);}/* * Map a chain of mbufs onto a network interface * in preparation for an i/o operation. * The argument chain of mbufs includes the local network * header which is copied to be in the mapped, aligned * i/o space. */deput(ifu, n, m)	struct deuba *ifu;	int n;	register struct mbuf *m;{	register caddr_t cp;	register struct ifxmt *ifxp;	register struct ifrw *ifrw;	register int i;	int xswapd = 0;	int x, cc, t;	caddr_t dp;	ifxp = &ifu->ifu_w[n];	ifrw = &ifxp->x_ifrw;	ifxp->x_xtofree = m;	cp = ifrw->ifrw_addr;	while (m) {		dp = mtod(m, char *);		if (claligned(cp) && claligned(dp) && m->m_len == CLBYTES) {			struct pte *pte; int *ip;			pte = &kmempt[mtocl(dp)];			x = btop(cp - ifrw->ifrw_addr);			ip = (int *)&ifrw->ifrw_mr[x];			for (i = 0; i < CLSIZE; i++)				*ip++ =				    ifrw->ifrw_proto | pte++->pg_pfnum;			xswapd |= 1 << (x>>(CLSHIFT-PGSHIFT));			cp += m->m_len;		} else {			bcopy(mtod(m, caddr_t), cp, (unsigned)m->m_len);			cp += m->m_len;		}		m = m->m_next;	}	/*	 * Xswapd is the set of clusters we just mapped out.  Ifxp->x_xswapd	 * is the set of clusters mapped out from before.  We compute	 * the number of clusters involved in this operation in x.	 * Clusters mapped out before and involved in this operation	 * should be unmapped so original pages will be accessed by the device.	 */	cc = cp - ifrw->ifrw_addr;	x = ((cc - ifu->ifu_hlen) + CLBYTES - 1) >> CLSHIFT;	ifxp->x_xswapd &= ~xswapd;#ifdef notdef	xswapd &= ~ifxp->x_xswapd;  /* this was in if_uba.c */#endif	while (i = ffs(ifxp->x_xswapd)) {		i--;		if (i >= x)			break;		ifxp->x_xswapd &= ~(1<<i);		i *= CLSIZE;		for (t = 0; t < CLSIZE; t++) {			ifrw->ifrw_mr[i] = ifxp->x_map[i];			i++;		}	}	ifxp->x_xswapd |= xswapd;	return (cc);}/* * Process an ioctl request. */deioctl(ifp, cmd, data)	register struct ifnet *ifp;	int cmd;	caddr_t data;{	register struct de_softc *ds = &de_softc[ifp->if_unit];	register struct uba_device *ui = deinfo[ifp->if_unit];	register struct dedevice *addr = (struct dedevice *)ui->ui_addr;	struct protosw *pr;	struct sockaddr *sa;	struct ifreq *ifr = (struct ifreq *)data;	struct ifdevea *ifd = (struct ifdevea *)data;	register struct ifaddr *ifa = (struct ifaddr *)data;	int s = splimp(), error = 0;	int csr0;	switch (cmd) {/*LSC001*/        case SIOCENABLBACK:                printf("de%d: internal loopback enable requested\n", ifp->if_unit);                if ( (error = deloopback( ui, ifp, ds, addr, 1 )) != NULL )                        break;                ifp->if_flags |= IFF_LOOPBACK;#ifdef notdef                if (ifp->if_flags & IFF_RUNNING)                        if_rtinit(ifp, -1);     #endif                break;         case SIOCDISABLBACK:                printf("de%d: internal loopback disable requested\n", ifp->if_unit);                if ( (error = deloopback( ui, ifp, ds, addr, 0 )) != NULL )                        break;                ifp->if_flags &= ~IFF_LOOPBACK;#ifdef notdef                if (ifp->if_flags & IFF_RUNNING)                        if_rtinit(ifp, -1);     #endif                deinit(ifp->if_unit);                break;         case SIOCRPHYSADDR:                 /*                 * read default hardware address.                 */		smp_lock(&ds->lk_de_softc, LK_RETRY);                ds->ds_pcbb.pcbb0 = FC_RDDEFAULT;                addr->pclow = CMD_GETCMD|((ds->ds_flags & DSF_RUNNING) ? PCSR0_INTE : 0);                while ((addr->pcsr0 & PCSR0_DNI) == 0)                         ;                csr0 = addr->pcsr0;                addr->pchigh = csr0 >> 8;                if (csr0 & PCSR0_PCEI) {			if (ds->ds_devid == DEUNA)                        	printf("de%d: read default hardware address failed, csr0=%b csr1=%b\n",                         	ui->ui_unit, csr0, PCSR0_BITS, addr->pcsr1, PCSR1_BITS);			else                        	printf("de%d: read default hardware address failed, csr0=%b csr1=%b\n",                         	ui->ui_unit, csr0, PCSR0_BITS, addr->pcsr1, PCSR1_BITS_DELUA);                        error = EIO;                        break;                }                /*                 * copy current physical address and default hardware address                 * for requestor.                 */                bcopy(&ds->ds_pcbb.pcbb2, ifd->default_pa, 6);                bcopy(ds->ds_addr, ifd->current_pa, 6);		smp_unlock(&ds->lk_de_softc);		                break; 	case SIOCSPHYSADDR: 		smp_lock(&ds->lk_de_softc, LK_RETRY);		/* Set the DNA address as the de's physical address */		ds->ds_pcbb.pcbb0 = FC_WTPHYAD;		bcopy (ifr->ifr_addr.sa_data, &ds->ds_pcbb.pcbb2, 6);		addr->pclow = CMD_GETCMD|((ds->ds_flags & DSF_RUNNING) ? PCSR0_INTE : 0);		while ((addr->pcsr0 & PCSR0_DNI) == 0)			;		csr0 = addr->pcsr0;		addr->pchigh = csr0 >> 8;		if (csr0 & PCSR0_PCEI)			if (ds->ds_devid == DEUNA)		  		printf("de%d: wtphyad failed, csr0=%b csr1=%b\n", 		    			ui->ui_unit, csr0, PCSR0_BITS, addr->pcsr1, PCSR1_BITS);			else		 		printf("de%d: wtphyad failed, csr0=%b csr1=%b\n", 		    			ui->ui_unit, csr0, PCSR0_BITS, addr->pcsr1, PCSR1_BITS_DELUA);		bcopy((caddr_t)&ds->ds_pcbb.pcbb2,(caddr_t)ds->ds_addr,	    		sizeof (ds->ds_addr));#if NPACKETFILTER > 0		pfilt_newaddress(ds->ds_ed.ess_enetunit, ds->ds_addr);#endif NPACKETFILTER > 0#ifdef notdef		if (ifp->if_flags & IFF_RUNNING)			if_rtinit(ifp, -1);	#endif		/*		 * Need to unlock before calling deinit()		 */		smp_unlock(&ds->lk_de_softc);				deinit(ifp->if_unit);		break;	case SIOCDELMULTI: 	case SIOCADDMULTI: 		smp_lock(&ds->lk_de_softc, LK_RETRY);		{		int i,j = -1,incaddr = ds->ds_ubaddr + MULTI_OFFSET;		if (cmd==SIOCDELMULTI) {		   for (i = 0; i < NMULTI; i++)		       if (bcmp(&ds->ds_multicast[i],ifr->ifr_addr.sa_data,MULTISIZE) == 0) {			    if (--ds->ds_muse[i] == 0)				bcopy(unused_multi,&ds->ds_multicast[i],MULTISIZE);		       }		} else {		    for (i = 0; i < NMULTI; i++) {			if (bcmp(&ds->ds_multicast[i],ifr->ifr_addr.sa_data,MULTISIZE) == 0) {			    ds->ds_muse[i]++;			    smp_unlock(&ds->lk_de_softc);					    goto done;			}		        if (bcmp(&ds->ds_multicast[i],unused_multi,MULTISIZE) == 0)			    j = i;		    }		    if (j == -1) {			printf("de%d: mtmulti failed, multicast list full: %d\n",				ui->ui_unit, NMULTI);			error = ENOBUFS;			smp_unlock(&ds->lk_de_softc);					goto done;		    }		    bcopy(ifr->ifr_addr.sa_data, &ds->ds_multicast[j], MULTISIZE);		    ds->ds_muse[j]++;		}		ds->ds_pcbb.pcbb0 = FC_WTMULTI;		ds->ds_pcbb.pcbb2 = incaddr & 0xffff;		ds->ds_pcbb.pcbb4 = (NMULTI << 8) | ((incaddr >> 16) & 03);		addr->pclow = CMD_GETCMD|((ds->ds_flags & DSF_RUNNING) ? PCSR0_INTE : 0);		while ((addr->pcsr0 & PCSR0_DNI) == 0)		;		csr0 = addr->pcsr0;		addr->pchigh = csr0 >> 8;		if (csr0 & PCSR0_PCEI)			if (ds->ds_devid == DEUNA)		  		printf("de%d: wtmulti failed, csr0=%b csr1=%b\n", ui->ui_unit,		    		csr0, PCSR0_BITS, addr->pcsr1, PCSR1_BITS);			else		  		printf("de%d: wtmulti failed, csr0=%b csr1=%b\n", ui->ui_unit,		 	   	csr0, PCSR0_BITS, addr->pcsr1, PCSR1_BITS_DELUA);		smp_unlock(&ds->lk_de_softc);				break;		}	case SIOCRDCTRS:	case SIOCRDZCTRS:		smp_lock(&ds->lk_de_softc, LK_RETRY);		{		int incaddr = ds->ds_ubaddr + COUNTER_OFFSET;		register struct ctrreq *ctr = (struct ctrreq *)data;		ds->ds_pcbb.pcbb0 = cmd == SIOCRDCTRS ? FC_RDCNTS : FC_RCCNTS;		ds->ds_pcbb.pcbb2 = incaddr & 0xffff;		ds->ds_pcbb.pcbb4 = (incaddr >> 16) & 03;		ds->ds_pcbb.pcbb6 = sizeof(struct de_counters);		addr->pclow = CMD_GETCMD|((ds->ds_flags & DSF_RUNNING) ? PCSR0_INTE : 0);		while ((addr->pcsr0 & PCSR0_DNI) == 0)			;		csr0 = addr->pcsr0;		addr->pchigh = csr0 >> 8;		if (csr0 & PCSR0_PCEI) {			if (ds->ds_devid == DEUNA)				printf("de%d: rdcnts failed, csr0=%b csr1=%b\n",				  ui->ui_unit, csr0, PCSR0_BITS,				  addr->pcsr1, PCSR1_BITS);			else				printf("de%d: rdcnts failed, csr0=%b csr1=%b\n",				  ui->ui_unit, csr0, PCSR0_BITS,				  addr->pcsr1, PCSR1_BITS_DELUA);			error = ENOBUFS;			break;		}		bzero(&ctr->ctr_ctrs, sizeof(struct estat));		ctr->ctr_type = CTR_ETHER;		ctr->ctr_ether.est_seconds = (time.tv_sec - ds->ds_ztime) > 0xfffe ? 0xffff : (time.tv_sec - ds->ds_ztime);		ctr->ctr_ether.est_bytercvd = *(int *)ds->ds_counters.c_brcvd;		ctr->ctr_ether.est_bytesent = *(int *)ds->ds_counters.c_bsent;		ctr->ctr_ether.est_mbytercvd = *(int *)ds->ds_counters.c_mbrcvd;		ctr->ctr_ether.est_blokrcvd = *(int *)ds->ds_counters.c_prcvd;		ctr->ctr_ether.est_bloksent = *(int *)ds->ds_counters.c_psent;		ctr->ctr_ether.est_mblokrcvd = *(int *)ds->ds_counters.c_mprcvd;		ctr->ctr_ether.est_deferred = *(int *)ds->ds_counters.c_defer;		ctr->ctr_ether.est_single = *(int *)ds->ds_counters.c_single;		ctr->ctr_ether.est_multiple = *(int *)ds->ds_counters.c_multiple;		ctr->ctr_ether.est_sendfail = ds->ds_counters.c_snderr;		ctr->ctr_ether.est_sendfail_bm = ds->ds_counters.c_sbm & 0xff;		ctr->ctr_ether.est_collis = ds->ds_counters.c_collis;		ctr->ctr_ether.est_recvfail = ds->ds_counters.c_rcverr;		ctr->ctr_ether.est_recvfail_bm = ds->ds_counters.c_rbm & 0xff;		ctr->ctr_ether.est_unrecog = ds->ds_unrecog;		ctr->ctr_ether.est_sysbuf = ds->ds_counters.c_ibuferr;		ctr->ctr_ether.est_userbuf = ds->ds_counters.c_lbuferr;		ctr->ctr_ether.est_mbytesent = *(int *)ds->ds_counters.c_mbsent;		ctr->ctr_ether.est_mbloksent = *(int *)ds->ds_counters.c_mpsent;		if (cmd == SIOCRDZCTRS) {			ds->ds_ztime = time.tv_sec;			ds->ds_unrecog = 0;		}		smp_unlock(&ds->lk_de_softc);				break;		}	case SIOCSIFADDR:		ifp->if_flags |= IFF_UP;		deinit(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:		/*		 * Right now we simply make sure of promiscuous		 * mode (other things might need handling, too);		 */		if (ifp->if_flags & IFF_RUNNING)			if (ifp->if_flags & IFF_PROMISC)				error = depromiscuous(ifp, 1);			else				error = depromiscuous(ifp, 0);		break;#endif  IFF_PROMISC	default:		error = EINVAL;	}done:	splx(s);	return (error);}/* * enable or disable internal loopback   LSC001 */deloopback( ui, ifp, ds, addr, lb_ctl )register struct uba_device *ui;register struct ifnet *ifp;register struct de_softc *ds;register struct dedevice *addr;u_char lb_ctl;{        int csr0;        /*         * read current mode register.         */        ds->ds_pcbb.pcbb0 = FC_RDMODE;        addr->pclow = CMD_GETCMD|((ds->ds_flags & DSF_RUNNING) ? PCSR0_INTE : 0);        while ((addr->pcsr0 & PCSR0_DNI) == 0)                 ;        csr0 = addr->pcsr0;        addr->pchigh = csr0 >> 8;        if (csr0 & PCSR0_PCEI) {		if (ds->ds_devid == DEUNA)                	printf("de%d: read mode register failed, csr0=%b csr1=%b\n",                         ui->ui_unit, csr0, PCSR0_BITS, addr->pcsr1, PCSR1_BITS);		else                	printf("de%d: read mode register failed, csr0=%b csr1=%b\n",                         ui->ui_unit, csr0, PCSR0_BITS, addr->pcsr1, PCSR1_BITS_DELUA);                return(EIO);        }        /*         * set or clear the loopback bit as a function of lb_ctl and         * return mode register to driver.         */        if ( lb_ctl == 1 ) {                ds->ds_pcbb.pcbb2 |= MOD_LOOP;		if (ds->ds_devid == DELUA)                	ds->ds_pcbb.pcbb2 |= MOD_INTL;		else                 	ds->ds_pcbb.pcbb2 &= ~MOD_HDX;        } else {                ds->ds_pcbb.pcbb2 &= ~MOD_LOOP;		if (ds->ds_devid == DELUA)                	ds->ds_pcbb.pcbb2 &= ~MOD_INTL;		else                 	ds->ds_pcbb.pcbb2 |= MOD_HDX;        }        ds->ds_pcbb.pcbb0 = FC_WTMODE;        addr->pclow = CMD_GETCMD|((ds->ds_flags & DSF_RUNNING) ? PCSR0_INTE : 0);        while ((addr->pcsr0 & PCSR0_DNI) == 0)                 ;        csr0 = addr->pcsr0;        addr->pchigh = csr0 >> 8;        if (csr0 & PCSR0_PCEI) {		if (ds->ds_devid == DEUNA)                	printf("de%d: write mode register failed, csr0=%b csr1=%b\n",                        		ui->ui_unit, csr0, PCSR0_BITS, addr->pcsr1, PCSR1_BITS);		else                	printf("de%d: write mode register failed, csr0=%b csr1=%b\n",                        		ui->ui_unit, csr0, PCSR0_BITS, addr->pcsr1, PCSR1_BITS_DELUA);                return(EIO);        }        return(NULL);}/* * enable or disable promiscuous mode *	if promisc_ctl is non-zero then promiscuous else not */depromiscuous(ifp, promisc_ctl)register struct ifnet *ifp;int promisc_ctl;{	register struct de_softc *ds = &de_softc[ifp->if_unit];	register struct uba_device *ui = deinfo[ifp->if_unit];	register struct dedevice *addr = (struct dedevice *)ui->ui_addr;        int csr0;        /*         * read current mode register.         */        ds->ds_pcbb.pcbb0 = FC_RDMODE;        addr->pclow =		CMD_GETCMD|((ds->ds_flags & DSF_RUNNING) ? PCSR0_INTE : 0);        while ((addr->pcsr0 & PCSR0_DNI) == 0)                 ;        csr0 = addr->pcsr0;        addr->pchigh = csr0 >> 8;        if (csr0 & PCSR0_PCEI) {	    if (ds->ds_devid == DEUNA)		printf("de%d: read mode register failed, csr0=%b csr1=%b\n", 		    ui->ui_unit, csr0, PCSR0_BITS, addr->pcsr1, PCSR1_BITS);	    else		printf("de%d: read mode register failed, csr0=%b csr1=%b\n", 		    ui->ui_unit, csr0, PCSR0_BITS,		    addr->pcsr1, PCSR1_BITS_DELUA);	    return(EIO);        }        /*         * set or clear the promiscuous bit as a function of promisc_ctl and         * return mode register to driver.         */        if (promisc_ctl == 1) {                ds->ds_pcbb.pcbb2 |= MOD_PROM;        }	else {                ds->ds_pcbb.pcbb2 &= ~MOD_PROM;        }        ds->ds_pcbb.pcbb0 = FC_WTMODE;        addr->pclow =		CMD_GETCMD|((ds->ds_flags & DSF_RUNNING) ? PCSR0_INTE : 0);        while ((addr->pcsr0 & PCSR0_DNI) == 0)                 ;        csr0 = addr->pcsr0;        addr->pchigh = csr0 >> 8;        if (csr0 & PCSR0_PCEI) {	    if (ds->ds_devid == DEUNA)        	printf("de%d: write mode register failed, csr0=%b csr1=%b\n", 			ui->ui_unit, csr0, PCSR0_BITS,			addr->pcsr1, PCSR1_BITS);	    else		printf("de%d: write mode register failed, csr0=%b csr1=%b\n", 			ui->ui_unit, csr0, PCSR0_BITS,			addr->pcsr1, PCSR1_BITS_DELUA);	    return(EIO);        }        return(NULL);}#endif

⌨️ 快捷键说明

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