📄 if_en.c
字号:
en->enr_type < ETHERTYPE_TRAIL+ETHERTYPE_NTRAILER) { off = (en->enr_type - ETHERTYPE_TRAIL) * 512; if (off >= ETHERMTU) return; en->enr_type = ntohs(*endataaddr(en, off, u_short *)); resid = ntohs(*(endataaddr(en, off+2, u_short *))); if (off + resid > len) return; len = off + resid; } else off = 0; /* * Pull packet off interface. Off is nonzero if packet * has trailing header; m_devget will then force this header * information to be at the front, but we still have to drop * the type and length which are at the front of any trailer data. * KU:XXX really? */ type = en->enr_type;#if defined(mips) && defined(CPU_SINGLE) m = m_devget((char *)(en + 1), len, off, &es->es_if, bxcopy);#else m = m_devget((char *)(en + 1), len, off, &es->es_if, 0);#endif if (m == 0) return; ether_input(&es->es_if, (struct ether_header *) en->enr_dhost, m);}/* * Watchdog routine, request statistics from board. */enwatch(unit) int unit;{ register struct en_softc *es = &en_softc[unit]; register struct ifnet *ifp = &es->es_if; ifp->if_timer = es->es_interval;}/* * Process an ioctl request. */enioctl(ifp, cmd, data) register struct ifnet *ifp; int cmd; caddr_t data;{ register struct ifaddr *ifa = (struct ifaddr *)data; register struct en_softc *es = &en_softc[ifp->if_unit]; register struct ensw *esp; register int family; int s = splimp(), error = 0; switch (cmd) { case SIOCSIFADDR: ifp->if_flags |= IFF_UP; eninit(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 } break; case SIOCSIFFLAGS: if ((ifp->if_flags & IFF_UP) == 0 && es->es_flags & ENF_RUNNING) { es->es_flags &= ~ENF_RUNNING; } else if (ifp->if_flags & IFF_UP && (es->es_flags & ENF_RUNNING) == 0) eninit(ifp->if_unit);#if NBPFILTER > 0 else if (ifp->if_flags & IFF_UP && (ifp->if_flags & IFF_RUNNING) == 0) { en_prom_mode(ifp->if_unit, ifp->if_flags & IFF_PROMISC); ifp->if_flags |= IFF_RUNNING; }#endif break; default: error = EINVAL; } splx(s); return (error);}/* * set ethernet address for unit */ensetaddr(physaddr, unit) u_char *physaddr; int unit;{ register struct en_softc *es = &en_softc[unit]; if (!(es->es_flags & ENF_RUNNING)) return; bcopy((caddr_t)physaddr, (caddr_t)es->es_addr, sizeof es->es_addr); es->es_flags &= ~ENF_RUNNING; es->es_flags |= ENF_SETADDR; eninit(unit);}/* * Machine dependent functions * * en_probe(); * en_attach(); * en_init(); * enxint(); * enrint(); * en_prom_mode() */#ifdef CPU_SINGLE#include <machine/cpu.h>en_probe(hi) struct hb_device *hi;{ return (lance_probe(hi->hi_unit));}en_attach(unit) int unit;{ register struct en_softc *es = &en_softc[unit]; register u_char *p; register int i; extern lance_intr();#if !defined(news700) && !defined(mips) register_hb_intr4(lance_intr, unit, eninfo[unit]->ii_intr);#endif if (lance_open(unit) < 0) printf("lance initialize error\n"); lance_get_addr(unit, (caddr_t)es->es_addr);}en_init(unit) int unit;{}en_start(unit, len) int unit; int len;{ lance_transmit(unit, len);}enxint(unit) register int unit;{ _enxint(unit, lance_xmit_error(unit), lance_collision(unit));}enrint(unit) register int unit;{ register struct en_softc *es = &en_softc[unit]; caddr_t get_recv_buffer(); while (es->es_ifnews.ifn_raddr = get_recv_buffer(unit)) { _enrint(unit, get_recv_length(unit) - sizeof(struct en_rheader)); free_recv_buffer(unit); }}en_prom_mode(unit, mode) int unit, mode;{ lance_prom_mode(unit, mode);}#endif /* CPU_SINGLE */#ifdef IPC_MRX#include "../ipc/newsipc.h"#include "../mrx/h/lancereg.h"#include "../mrx/h/lance.h"int port_enxmit[NEN];int port_enrecv[NEN];int port_enctrl[NEN];int port_enxmit_iop[NEN];int port_enrecv_iop[NEN];int port_enctrl_iop[NEN];en_probe(ii) register struct iop_device *ii;{ int unit = ii->ii_unit; int lance_func, *reply; char name[32]; extern char *make_name(); if (port_enrecv[unit] == 0) {#define PT_CREATE(buf, name, unit, func) \ port_create(make_name(buf, name, unit), func, unit)#define OB_QUERY(buf, name, unit) \ object_query(make_name(buf, name, unit)) make_name(name, "@enrecvX", unit); port_enrecv[unit] = PT_CREATE(name, "@enrecvX", unit, enrint); port_enxmit[unit] = PT_CREATE(name, "@enxmitX", unit, enxint); port_enctrl[unit] = PT_CREATE(name, "@enctrlX", unit, NULL); /* use NULL action port */ port_enrecv_iop[unit] = OB_QUERY(name, "lance_inputX", unit); port_enxmit_iop[unit] = OB_QUERY(name, "lance_outputX", unit); port_enctrl_iop[unit] = OB_QUERY(name, "lance_ctrlX", unit); } if (port_enctrl_iop[unit] < 0) goto bad; lance_func = EN_START; msg_send(port_enctrl_iop[unit], port_enctrl[unit], &lance_func, sizeof(lance_func), 0); msg_recv(port_enctrl[unit], NULL, &reply, NULL, 0); if (*reply < 0) goto bad; lance_func = EN_STOP; msg_send(port_enctrl_iop[unit], port_enctrl[unit], &lance_func, sizeof(lance_func), 0); msg_recv(port_enctrl[unit], NULL, &reply, NULL, 0); return (1);bad: return (0);}en_attach(unit) int unit;{ register struct en_softc *es = &en_softc[unit]; int lance_func; struct ether_addr *ether_addr; lance_func = EN_GETADDR; msg_send(port_enctrl_iop[unit], port_enctrl[unit], &lance_func, sizeof(lance_func), 0); msg_recv(port_enctrl[unit], NULL, ðer_addr, NULL, 0); bcopy(ether_addr, es->es_addr, sizeof(struct ether_addr)); msg_free(port_enctrl[unit]);}en_init(unit) int unit;{ register struct en_softc *es = &en_softc[unit]; register int port; struct lance_ctrl_req req; int *reply; req.lance_func = EN_SETXMITBUF; mapsetup(&req.lance_map, es->es_ifnews.ifn_waddr, ETHERMTU + sizeof(struct en_rheader)); msg_send(port_enctrl_iop[unit], port_enctrl[unit], &req, sizeof(req), 0); msg_recv(port_enctrl[unit], NULL, &reply, NULL, 0); req.lance_func = EN_START; msg_send(port_enctrl_iop[unit], port_enctrl[unit], &req, sizeof(req), 0); msg_recv(port_enctrl[unit], NULL, &reply, NULL, 0); msg_free(port_enctrl[unit]); msg_send(port_enrecv_iop[unit], port_enrecv[unit], es->es_ifnews.ifn_raddr, ETHERMTU + sizeof(struct en_rheader), MSG_INDIRECT);}en_start(unit, len) int unit; int len;{ msg_send(port_enxmit_iop[unit], port_enxmit[unit], &len, sizeof(len), 0);}enxint(unit) register int unit;{ int *len; struct en_softc *es = &en_softc[unit]; if (msg_recv(port_enxmit[unit], NULL, &len, NULL, 0) < 0) { printf("stray enxint\n"); return; } if (es->es_ifnews.ifn_mbuf) m_freem(es->es_ifnews.ifn_mbuf); _enxint(unit, *len < 0, *len & 0x10000);}enrint(unit) int unit;{ int len; int *reply; if (msg_recv(port_enrecv[unit], NULL, &reply, NULL, 0) < 0) { printf("stray enrint\n"); return; } len = *reply - sizeof(struct en_rheader); msg_free(port_enrecv[unit]);#ifdef mips /* * cache flush address must aligned long word boundary. * so, add 3 for sanity. */ clean_k2dcache((int)en_softc[unit].es_ifnews.ifn_raddr & ~03, len + sizeof (struct en_rheader) + 3);#endif _enrint(unit, len); msg_send(port_enrecv_iop[unit], port_enrecv[unit], en_softc[unit].es_ifnews.ifn_raddr, ETHERMTU + sizeof(struct en_rheader), MSG_INDIRECT);}en_prom_mode(unit, mode) int unit, mode;{ static int port; struct lance_ctrl_req req; extern int port_enctrl_iop[]; req.lance_func = EN_PROMMODE; req.lance_mode = mode; msg_send(port_enctrl_iop[unit], 0, &req, sizeof(req), 0);}#endif /* IPC_MRX */#endif /* NEN > 0 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -