📄 if_enp.c
字号:
} MGETHDR(m, M_DONTWAIT, MT_DATA); if (m == 0) return (0); m->m_pkthdr.rcvif = ifp; m->m_pkthdr.len = totlen; m->m_len = MHLEN; while (totlen > 0) { if (top) { MGET(m, M_DONTWAIT, MT_DATA); if (m == 0) { m_freem(top); return (0); } m->m_len = MLEN; } len = min(totlen, (packet_end - cp)); if (len >= MINCLSIZE) { MCLGET(m, M_DONTWAIT); if (m->m_flags & M_EXT) m->m_len = len = min(len, MCLBYTES); else len = m->m_len; } else { /* * Place initial small packet/header at end of mbuf. */ if (len < m->m_len) { if (top == 0 && len + max_linkhdr <= m->m_len) m->m_data += max_linkhdr; m->m_len = len; } else len = m->m_len; } enpcopy(cp, mtod(m, u_char *), (u_int)len); *mp = m; mp = &m->m_next; totlen -= len; cp += len; if (cp == packet_end) cp = rxbuf; } return (top);}enpcopy(from, to, cnt) register u_char *from, *to; register u_int cnt;{ register c; register short *f, *t; if (((int)from&01) && ((int)to&01)) { /* source & dest at odd addresses */ *to++ = *from++; --cnt; } if (cnt > 1 && (((int)to&01) == 0) && (((int)from&01) == 0)) { t = (short *)to; f = (short *)from; for (c = cnt>>1; c; --c) /* even address copy */ *t++ = *f++; cnt &= 1; if (cnt) { /* odd len */ from = (u_char *)f; to = (u_char *)t; *to = *from; } } while ((int)cnt-- > 0) /* one of the address(es) must be odd */ *to++ = *from++;}/* * Process an ioctl request. */enpioctl(ifp, cmd, data) register struct ifnet *ifp; int cmd; caddr_t data;{ register struct ifaddr *ifa = (struct ifaddr *)data; struct enpdevice *addr; int s = splimp(), error = 0; switch (cmd) { case SIOCSIFADDR: ifp->if_flags |= IFF_UP; switch (ifa->ifa_addr->sa_family) {#ifdef INET case AF_INET: enpinit(ifp->if_unit); ((struct arpcom *)ifp)->ac_ipaddr = IA_SIN(ifa)->sin_addr; arpwhohas((struct arpcom *)ifp, &IA_SIN(ifa)->sin_addr); break;#endif#ifdef NS case AF_NS: { struct ns_addr *ina = &IA_SNS(ifa)->sns_addr; struct enp_softc *es = &enp_softc[ifp->if_unit]; if (!ns_nullhost(*ina)) { ifp->if_flags &= ~IFF_RUNNING; addr = (struct enpdevice *) enpinfo[ifp->if_unit]->ui_addr; enpsetaddr(ifp->if_unit, addr, ina->x_host.c_host); } else ina->x_host = *(union ns_host *)es->es_addr; enpinit(ifp->if_unit); break; }#endif default: enpinit(ifp->if_unit); break; } break; case SIOCSIFFLAGS: if ((ifp->if_flags&IFF_UP) == 0 && ifp->if_flags&IFF_RUNNING) { enpinit(ifp->if_unit); /* reset board */ ifp->if_flags &= ~IFF_RUNNING; } else if (ifp->if_flags&IFF_UP && (ifp->if_flags&IFF_RUNNING) == 0) enpinit(ifp->if_unit); break; default: error = EINVAL; } splx(s); return (error);}enpsetaddr(unit, addr, enaddr) int unit; struct enpdevice *addr; u_char *enaddr;{ enpcopy(enaddr, addr->enp_addr.e_baseaddr.ea_addr, sizeof (struct ether_addr)); enpinit(unit); enpgetaddr(unit, addr);}enpgetaddr(unit, addr) int unit; struct enpdevice *addr;{ struct enp_softc *es = &enp_softc[unit]; enpcopy(addr->enp_addr.e_baseaddr.ea_addr, es->es_addr, sizeof (struct ether_addr)); printf("enp%d: hardware address %s\n", unit, ether_sprintf(es->es_addr));}/* * Routines to synchronize enp and host. */#ifdef notdefstaticringinit(rp, size) register RING *rp;{ rp->r_rdidx = rp->r_wrtidx = 0; rp->r_size = size;}staticringfull(rp) register RING *rp;{ register short idx; idx = (rp->r_wrtidx + 1) & (rp->r_size-1); return (idx == rp->r_rdidx);}staticfir(rp) register RING *rp;{ return (rp->r_rdidx != rp->r_wrtidx ? rp->r_slot[rp->r_rdidx] : 0);}#endifstaticringempty(rp) register RING *rp;{ return (rp->r_rdidx == rp->r_wrtidx);}staticringput(rp, v) register RING *rp; BCB *v;{ register int idx; idx = (rp->r_wrtidx + 1) & (rp->r_size-1); if (idx != rp->r_rdidx) { ENPSETLONG(&rp->r_slot[rp->r_wrtidx], v); rp->r_wrtidx = idx; if ((idx -= rp->r_rdidx) < 0) idx += rp->r_size; return (idx); /* num ring entries */ } return (0);}staticringget(rp) register RING *rp;{ register int i = 0; if (rp->r_rdidx != rp->r_wrtidx) { i = ENPGETLONG(&rp->r_slot[rp->r_rdidx]); rp->r_rdidx = (++rp->r_rdidx) & (rp->r_size-1); } return (i);}/* * ENP Ram device. */enpr_open(dev) dev_t dev;{ register int unit = ENPUNIT(dev); struct vba_device *ui; struct enpdevice *addr; if (unit >= NENP || (ui = enpinfo[unit]) == 0 || ui->ui_alive == 0 || (addr = (struct enpdevice *)ui->ui_addr) == 0) return (ENODEV); if (addr->enp_state != S_ENPRESET) return (EACCES); /* enp is not in reset state, don't open */ return (0);}/*ARGSUSED*/enpr_close(dev) dev_t dev;{ return (0);}enpr_read(dev, uio) dev_t dev; register struct uio *uio;{ register struct iovec *iov; struct enpdevice *addr; if (uio->uio_offset > RAM_SIZE) return (ENODEV); iov = uio->uio_iov; if (uio->uio_offset + iov->iov_len > RAM_SIZE) iov->iov_len = RAM_SIZE - uio->uio_offset; addr = (struct enpdevice *)enpinfo[ENPUNIT(dev)]->ui_addr; if (useracc(iov->iov_base, (unsigned)iov->iov_len, 0) == 0) return (EFAULT); enpcopy((u_char *)&addr->enp_ram[uio->uio_offset], (u_char *)iov->iov_base, (u_int)iov->iov_len); uio->uio_resid -= iov->iov_len; iov->iov_len = 0; return (0);}enpr_write(dev, uio) dev_t dev; register struct uio *uio;{ register struct enpdevice *addr; register struct iovec *iov; addr = (struct enpdevice *)enpinfo[ENPUNIT(dev)]->ui_addr; iov = uio->uio_iov; if (uio->uio_offset > RAM_SIZE) return (ENODEV); if (uio->uio_offset + iov->iov_len > RAM_SIZE) iov->iov_len = RAM_SIZE - uio->uio_offset; if (useracc(iov->iov_base, (unsigned)iov->iov_len, 1) == 0) return (EFAULT); enpcopy((u_char *)iov->iov_base, (u_char *)&addr->enp_ram[uio->uio_offset], (u_int)iov->iov_len); uio->uio_resid -= iov->iov_len; uio->uio_offset += iov->iov_len; iov->iov_len = 0; return (0);}/*ARGSUSED*/enpr_ioctl(dev, cmd, data) dev_t dev; caddr_t data;{ register unit = ENPUNIT(dev); struct enpdevice *addr; addr = (struct enpdevice *)enpinfo[unit]->ui_addr; switch(cmd) { case ENPIOGO: ENPSETLONG(&addr->enp_base, addr); addr->enp_intrvec = enp_softc[unit].es_ivec; ENP_GO(addr, ENPSTART); DELAY(200000); enpinit(unit); /* * Fetch Ethernet address after link level * is booted (firmware copies manufacturer's * address from on-board ROM). */ enpgetaddr(unit, addr); addr->enp_state = S_ENPRUN; break; case ENPIORESET: RESET_ENP(addr); addr->enp_state = S_ENPRESET; DELAY(100000); break; default: return (EINVAL); } return (0);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -