-/* if_en.c 4.51 82/04/04 */
+/* if_en.c 4.71 82/10/24 */
#include "en.h"
-#include "imp.h"
/*
* Xerox prototype (3 Mb) Ethernet interface driver.
#include "../h/buf.h"
#include "../h/protosw.h"
#include "../h/socket.h"
-#include "../h/ubareg.h"
-#include "../h/ubavar.h"
-#include "../h/enreg.h"
-#include "../h/cpu.h"
-#include "../h/mtpr.h"
#include "../h/vmmac.h"
-#include "../net/in.h"
-#include "../net/in_systm.h"
+#include <errno.h>
+
#include "../net/if.h"
-#include "../net/if_en.h"
-#include "../net/if_uba.h"
-#include "../net/ip.h"
-#include "../net/ip_var.h"
-#include "../net/pup.h"
+#include "../net/netisr.h"
#include "../net/route.h"
+#include "../netinet/in.h"
+#include "../netinet/in_systm.h"
+#include "../netinet/ip.h"
+#include "../netinet/ip_var.h"
+#include "../netpup/pup.h"
+
+#include "../vax/cpu.h"
+#include "../vax/mtpr.h"
+#include "../vaxif/if_en.h"
+#include "../vaxif/if_enreg.h"
+#include "../vaxif/if_uba.h"
+#include "../vaxuba/ubareg.h"
+#include "../vaxuba/ubavar.h"
#define ENMTU (1024+512)
+#define ENMRU (1024+512+16) /* 16 is enough to receive trailer */
int enprobe(), enattach(), enrint(), enxint(), encollide();
struct uba_device *eninfo[NEN];
register int br, cvec; /* r11, r10 value-result */
register struct endevice *addr = (struct endevice *)reg;
-COUNT(ENPROBE);
#ifdef lint
br = 0; cvec = br; br = cvec;
enrint(0); enxint(0); encollide(0);
addr->en_ostat = EN_IEN|EN_GO;
DELAY(100000);
addr->en_ostat = 0;
+#ifdef ECHACK
+ br = 0x16;
+#endif
return (1);
}
{
register struct en_softc *es = &en_softc[ui->ui_unit];
register struct sockaddr_in *sin;
-COUNT(ENATTACH);
es->es_if.if_unit = ui->ui_unit;
es->es_if.if_name = "en";
es->es_if.if_mtu = ENMTU;
- es->es_if.if_net = ui->ui_flags & 0xff;
+ es->es_if.if_net = ui->ui_flags;
es->es_if.if_host[0] =
(~(((struct endevice *)eninfo[ui->ui_unit]->ui_addr)->en_addr)) & 0xff;
sin = (struct sockaddr_in *)&es->es_if.if_addr;
es->es_if.if_init = eninit;
es->es_if.if_output = enoutput;
es->es_if.if_ubareset = enreset;
- es->es_ifuba.ifu_flags = UBA_NEEDBDP | UBA_NEED16;
+ es->es_ifuba.ifu_flags = UBA_NEEDBDP | UBA_NEED16 | UBA_CANTWAIT;
if_attach(&es->es_if);
-#if NIMP == 0
- /* here's one for you john baby.... */
- enlhinit((ui->ui_flags &~ 0xff) | 0x0a);
-#endif
}
/*
int unit, uban;
{
register struct uba_device *ui;
-COUNT(ENRESET);
if (unit >= NEN || (ui = eninfo[unit]) == 0 || ui->ui_alive == 0 ||
ui->ui_ubanum != uban)
int s;
if (if_ubainit(&es->es_ifuba, ui->ui_ubanum,
- sizeof (struct en_header), (int)btoc(ENMTU)) == 0) {
+ sizeof (struct en_header), (int)btoc(ENMRU)) == 0) {
printf("en%d: can't initialize\n", unit);
es->es_if.if_flags &= ~IFF_UP;
return;
*/
s = splimp();
addr->en_iba = es->es_ifuba.ifu_r.ifrw_info;
- addr->en_iwc = -(sizeof (struct en_header) + ENMTU) >> 1;
+ addr->en_iwc = -(sizeof (struct en_header) + ENMRU) >> 1;
addr->en_istat = EN_IEN|EN_GO;
es->es_oactive = 1;
es->es_if.if_flags |= IFF_UP;
enxint(unit);
splx(s);
- if_rtinit(&es->es_if, RTF_DIRECT|RTF_UP);
+ if_rtinit(&es->es_if, RTF_UP);
}
int enalldelay = 0;
-int enlastdel = 25;
+int enlastdel = 50;
int enlastmask = (~0) << 5;
/*
register struct endevice *addr;
struct mbuf *m;
int dest;
-COUNT(ENSTART);
if (es->es_oactive)
goto restart;
register struct uba_device *ui = eninfo[unit];
register struct en_softc *es = &en_softc[unit];
register struct endevice *addr = (struct endevice *)ui->ui_addr;
-COUNT(ENXINT);
if (es->es_oactive == 0)
return;
if (es->es_mask && (addr->en_ostat&EN_OERROR)) {
es->es_if.if_oerrors++;
- if (es->es_if.if_oerrors % 100 == 0)
- printf("en%d: += 100 output errors\n", unit);
endocoll(unit);
return;
}
int unit;
{
struct en_softc *es = &en_softc[unit];
-COUNT(ENCOLLIDE);
es->es_if.if_collisions++;
if (es->es_oactive == 0)
struct endevice *addr = (struct endevice *)eninfo[unit]->ui_addr;
register struct en_header *en;
struct mbuf *m;
- int len, plen; short resid;
+ int len; short resid;
register struct ifqueue *inq;
int off;
-COUNT(ENRINT);
es->es_if.if_ipackets++;
UBAPURGE(es->es_ifuba.ifu_uba, es->es_ifuba.ifu_r.ifrw_bdp);
if (addr->en_istat&EN_IERROR) {
es->es_if.if_ierrors++;
- if (es->es_if.if_ierrors % 100 == 0)
- printf("en%d: += 100 input errors\n", unit);
goto setup;
}
resid = addr->en_iwc;
if (resid)
resid |= 0176000;
- len = (((sizeof (struct en_header) + ENMTU) >> 1) + resid) << 1;
+ len = (((sizeof (struct en_header) + ENMRU) >> 1) + resid) << 1;
len -= sizeof (struct en_header);
- if (len >= ENMTU)
+ if (len > ENMRU)
goto setup; /* sanity */
en = (struct en_header *)(es->es_ifuba.ifu_r.ifrw_addr);
#define endataaddr(en, off, type) ((type)(((caddr_t)((en)+1)+(off))))
if (en->en_type >= ENPUP_TRAIL &&
en->en_type < ENPUP_TRAIL+ENPUP_NTRAILER) {
off = (en->en_type - ENPUP_TRAIL) * 512;
- if (off >= ENMTU)
+ if (off > ENMTU)
goto setup; /* sanity */
en->en_type = *endataaddr(en, off, u_short *);
resid = *(endataaddr(en, off+2, u_short *));
pupproto.sp_protocol = pup->pup_type;
pupdst.spup_addr = pup->pup_dport;
pupsrc.spup_addr = pup->pup_sport;
- raw_input(m, &pupproto, (struct sockaddr *)&pupdst,
- (struct sockaddr *)&pupsrc);
+ raw_input(m, &pupproto, (struct sockaddr *)&pupsrc,
+ (struct sockaddr *)&pupdst);
goto setup;
}
#endif
+ default:
+ m_freem(m);
+ goto setup;
}
if (IF_QFULL(inq)) {
* Reset for next packet.
*/
addr->en_iba = es->es_ifuba.ifu_r.ifrw_info;
- addr->en_iwc = -(sizeof (struct en_header) + ENMTU) >> 1;
+ addr->en_iwc = -(sizeof (struct en_header) + ENMRU) >> 1;
addr->en_istat = EN_IEN|EN_GO;
}
struct mbuf *m0;
struct sockaddr *dst;
{
- int type, dest, s;
+ int type, dest, s, error;
register struct mbuf *m = m0;
register struct en_header *en;
register int off;
-COUNT(ENOUTPUT);
switch (dst->sa_family) {
#ifdef INET
case AF_INET:
- dest = ((struct sockaddr_in *)dst)->sin_addr.s_addr >> 24;
+ dest = ((struct sockaddr_in *)dst)->sin_addr.s_addr;
+ if (dest & 0x00ffff00) {
+ error = EPERM; /* ??? */
+ goto bad;
+ }
+ dest = (dest >> 24) & 0xff;
off = ntohs((u_short)mtod(m, struct ip *)->ip_len) - m->m_len;
if (off > 0 && (off & 0x1ff) == 0 &&
m->m_off >= MMINOFF + 2 * sizeof (u_short)) {
default:
printf("en%d: can't handle af%d\n", ifp->if_unit,
dst->sa_family);
- m_freem(m0);
- return (0);
+ error = EAFNOSUPPORT;
+ goto bad;
}
gottrailertype:
MMINOFF + sizeof (struct en_header) > m->m_off) {
m = m_get(M_DONTWAIT);
if (m == 0) {
- m_freem(m0);
- return (0);
+ error = ENOBUFS;
+ goto bad;
}
m->m_next = m0;
m->m_off = MMINOFF;
s = splimp();
if (IF_QFULL(&ifp->if_snd)) {
IF_DROP(&ifp->if_snd);
- m_freem(m);
- splx(s);
- return (0);
+ error = ENOBUFS;
+ goto qfull;
}
IF_ENQUEUE(&ifp->if_snd, m);
if (en_softc[ifp->if_unit].es_oactive == 0)
enstart(ifp->if_unit);
splx(s);
- return (1);
-}
-
-#if NIMP == 0 && NEN > 0
-/*
- * Logical host interface driver.
- * Allows host to appear as an ARPAnet
- * logical host. Must also have routing
- * table entry set up to forward packets
- * to appropriate gateway on localnet.
- */
-
-struct ifnet enlhif;
-int enlhoutput();
-
-/*
- * Called by localnet interface to allow logical
- * host interface to "attach". Nothing should ever
- * be sent locally to this interface, it's purpose
- * is simply to establish the host's arpanet address.
- */
-enlhinit(addr)
- int addr;
-{
- register struct ifnet *ifp = &enlhif;
- register struct sockaddr_in *sin;
-
-COUNT(ENLHINIT);
- ifp->if_name = "lh";
- ifp->if_mtu = ENMTU;
- sin = (struct sockaddr_in *)&ifp->if_addr;
- sin->sin_family = AF_INET;
- sin->sin_addr.s_addr = addr;
- ifp->if_net = sin->sin_addr.s_net;
- ifp->if_flags = IFF_UP;
- ifp->if_output = enlhoutput; /* should never be used */
- if_attach(ifp);
-}
-
-enlhoutput(ifp, m0, dst)
- struct ifnet *ifp;
- struct mbuf *m0;
- struct sockaddr *dst;
-{
-COUNT(ENLHOUTPUT);
- ifp->if_oerrors++;
- m_freem(m0);
return (0);
+qfull:
+ m0 = m;
+ splx(s);
+bad:
+ m_freem(m0);
+ return (error);
}
-#endif