📄 if_de.c
字号:
} 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 + -