-/* if_ec.c 4.19 82/06/20 */
+/* if_ec.c 4.29 82/11/13 */
#include "ec.h"
#include "../h/buf.h"
#include "../h/protosw.h"
#include "../h/socket.h"
-#include "../h/ubareg.h"
-#include "../h/ubavar.h"
-#include "../h/ecreg.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_ec.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 <errno.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_ec.h"
+#include "../vaxif/if_ecreg.h"
+#include "../vaxif/if_uba.h"
+#include "../vaxuba/ubareg.h"
+#include "../vaxuba/ubavar.h"
#define ECMTU 1500
+#define ECMIN (60-14)
+#define ECMEM 0000000
int ecprobe(), ecattach(), ecrint(), ecxint(), eccollide();
struct uba_device *ecinfo[NEC];
#define ECUNIT(x) minor(x)
int ecinit(),ecoutput(),ecreset();
-struct mbuf *ecget();
+struct mbuf *ecget();
extern struct ifnet loif;
struct ifuba es_ifuba; /* UNIBUS resources */
short es_mask; /* mask for current output delay */
short es_oactive; /* is output active? */
- caddr_t es_buf[16]; /* virtual addresses of buffers */
+ u_char *es_buf[16]; /* virtual addresses of buffers */
u_char es_enaddr[6]; /* board's ethernet address */
} ec_softc[NEC];
{
register int br, cvec; /* r11, r10 value-result */
register struct ecdevice *addr = (struct ecdevice *)reg;
- register caddr_t ecbuf = (caddr_t) &umem[0][0600000];
+ register caddr_t ecbuf = (caddr_t) &umem[numuba][ECMEM];
#ifdef lint
br = 0; cvec = br; br = cvec;
* Make sure memory is turned on
*/
addr->ec_rcr = EC_AROM;
+ /*
+ * Disable map registers for ec unibus space,
+ * but don't allocate yet.
+ */
+ (void) ubamem(numuba, ECMEM, 32*2, 0);
/*
* Check for existence of buffers on Unibus.
- * This won't work on a 780 until more work is done.
*/
- if (badaddr((caddr_t) ecbuf, 2)) {
- printf("ec: buffer mem not found");
+ if (badaddr((caddr_t)ecbuf, 2)) {
+ bad1:
+ printf("ec: buffer mem not found\n");
+ bad2:
+ (void) ubamem(numuba, 0, 0, 0); /* reenable map (780 only) */
+ addr->ec_rcr = EC_MDISAB; /* disable memory */
return (0);
}
+#if VAX780
+ if (cpu == VAX_780 && uba_hd[numuba].uh_uba->uba_sr) {
+ uba_hd[numuba].uh_uba->uba_sr = uba_hd[numuba].uh_uba->uba_sr;
+ goto bad1;
+ }
+#endif
/*
* Tell the system that the board has memory here, so it won't
* attempt to allocate the addresses later.
*/
- ubamem(0, 0600000, 32*2);
+ if (ubamem(numuba, ECMEM, 32*2, 1) == 0) {
+ printf("ecprobe: cannot reserve uba addresses\n");
+ goto bad2;
+ }
/*
* Make a one byte packet in what should be buffer #0.
DELAY(100000);
addr->ec_xcr = EC_XCLR;
if (cvec > 0 && cvec != 0x200) {
- cvec -= 010;
- br += 2; /* rcv is xmit + 2 */
+ if (cvec & 04) { /* collision interrupt */
+ cvec -= 04;
+ br += 1; /* rcv is collision + 1 */
+ } else { /* xmit interrupt */
+ cvec -= 010;
+ br += 2; /* rcv is xmit + 2 */
+ }
}
return (1);
}
ifp->if_init = ecinit;
ifp->if_output = ecoutput;
- ifp->if_ubareset = ecreset;
+ ifp->if_reset = ecreset;
for (i=0; i<16; i++)
- es->es_buf[i] = &umem[ui->ui_ubanum][0600000+2048*i];
+ es->es_buf[i] = (u_char *)&umem[ui->ui_ubanum][ECMEM+2048*i];
if_attach(ifp);
}
ui->ui_ubanum != uban)
return;
printf(" ec%d", unit);
+ (void) ubamem(uban, ECMEM, 32*2, 0); /* mr disable (no alloc) */
ecinit(unit);
}
ecstart(dev)
dev_t dev;
{
- int unit = ECUNIT(dev), dest;
+ int unit = ECUNIT(dev);
struct ec_softc *es = &ec_softc[unit];
struct ecdevice *addr;
struct mbuf *m;
- caddr_t ecbuf;
if (es->es_oactive)
goto restart;
es->es_oactive = 0;
es->es_mask = ~0;
addr->ec_xcr = EC_XCLR;
- /*
- * There shouldn't ever be any mbuf's to free, but just in case...
- */
- if (es->es_ifuba.ifu_xtofree) {
- m_freem(es->es_ifuba.ifu_xtofree);
- es->es_ifuba.ifu_xtofree = 0;
- }
if (es->es_if.if_snd.ifq_head)
ecstart(unit);
}
{
struct ec_softc *es = &ec_softc[unit];
- printf("ec%d: collision\n", unit);
es->es_if.if_collisions++;
if (es->es_oactive)
ecdocoll(unit);
/*
* Clear the controller's collision flag, thus enabling retransmit.
*/
- addr->ec_xcr = EC_JINTEN|EC_XINTEN|EC_JCLR;
+ addr->ec_xcr = EC_CLEAR;
}
/*
struct ecdevice *addr = (struct ecdevice *)ecinfo[unit]->ui_addr;
register struct ec_header *ec;
struct mbuf *m;
- int len, off, resid, ecoff, buf;
+ int len, off, resid, ecoff, rbuf;
register struct ifqueue *inq;
- caddr_t ecbuf;
+ u_char *ecbuf;
es->es_if.if_ipackets++;
- buf = addr->ec_rcr & EC_RBN;
- if (buf < ECRLBF || buf > ECRHBF)
+ rbuf = addr->ec_rcr & EC_RBN;
+ if (rbuf < ECRLBF || rbuf > ECRHBF)
panic("ecrint");
- ecbuf = es->es_buf[buf];
+ ecbuf = es->es_buf[rbuf];
ecoff = *(short *)ecbuf;
if (ecoff <= ECRDOFF || ecoff > 2046) {
es->es_if.if_ierrors++;
if (es->es_if.if_ierrors % 100 == 0)
printf("ec%d: += 100 input errors\n", unit);
#endif
- printf("ec%d: input error (offset=%d)\n", unit, ecoff);
goto setup;
}
/*
* Reset for next packet.
*/
- addr->ec_rcr = EC_READ|EC_RCLR|buf;
+ addr->ec_rcr = EC_READ|EC_RCLR|rbuf;
}
/*
case AF_INET:
dest = ((struct sockaddr_in *)dst)->sin_addr.s_addr;
if ((dest &~ 0xff) == 0)
- mcopy = m_copy(m, 0, M_COPYALL);
+ mcopy = m_copy(m, 0, (int)M_COPYALL);
else if (dest == ((struct sockaddr_in *)&es->es_if.if_addr)->
sin_addr.s_addr) {
mcopy = m;
}
/*
- * Routine to copy from mbuf chain to transmitter
+ * Routine to copy from mbuf chain to transmit
* buffer in UNIBUS memory.
+ * If packet size is less than the minimum legal size,
+ * the buffer is expanded. We probably should zero out the extra
+ * bytes for security, but that would slow things down.
*/
ecput(ecbuf, m)
u_char *ecbuf;
struct mbuf *m;
{
register struct mbuf *mp;
- register u_char *bp;
register int off;
+ u_char *bp;
for (off = 2048, mp = m; mp; mp = mp->m_next)
off -= mp->m_len;
+ if (2048 - off < ECMIN + sizeof (struct ec_header))
+ off = 2048 - ECMIN - sizeof (struct ec_header);
*(u_short *)ecbuf = off;
bp = (u_char *)(ecbuf + off);
- for (mp = m; mp; mp = m_free(mp)) {
- register unsigned len;
- register u_char *mcp;
+ for (mp = m; mp; mp = mp->m_next) {
+ register unsigned len = mp->m_len;
+ u_char *mcp;
- len = mp->m_len;
if (len == 0)
continue;
mcp = mtod(mp, u_char *);
*bp++ = *mcp++;
len--;
}
- for (; len > 1; len -= sizeof (u_short)) {
- *(u_short *)bp = *(u_short *)mcp;
- bp += sizeof (u_short);
- mcp += sizeof (u_short);
+ if (off = (len >> 1)) {
+ register u_short *to, *from;
+
+ to = (u_short *)bp;
+ from = (u_short *)mcp;
+ do
+ *to++ = *from++;
+ while (--off > 0);
+ bp = (u_char *)to,
+ mcp = (u_char *)from;
}
- if (len)
+ if (len & 01)
*bp++ = *mcp++;
}
#ifdef notdef
if (bp - ecbuf != 2048)
printf("ec: bad ecput, diff=%d\n", bp-ecbuf);
#endif
+ m_freem(m);
}
/*
*/
struct mbuf *
ecget(ecbuf, totlen, off0)
- char *ecbuf;
+ u_char *ecbuf;
int totlen, off0;
{
- struct mbuf *top, **mp, *m;
- int off = off0, len;
- register char *cp, *mcp;
- register int i;
+ register struct mbuf *m;
+ struct mbuf *top = 0, **mp = ⊤
+ register int off = off0, len;
+ u_char *cp;
- top = 0;
- mp = ⊤
cp = ecbuf + ECRDOFF + sizeof (struct ec_header);
while (totlen > 0) {
+ register int words;
+ u_char *mcp;
+
MGET(m, 0);
if (m == 0)
goto bad;
m->m_len = len = MIN(MLEN, len);
m->m_off = MMINOFF;
}
- mcp = mtod(m, char *);
- for (i = 0; i < len; i += sizeof (short)) {
- *(short *)mcp = *(short *)cp;
- mcp += sizeof (short);
- cp += sizeof (short);
+ mcp = mtod(m, u_char *);
+ if (words = (len >> 1)) {
+ register u_short *to, *from;
+
+ to = (u_short *)mcp;
+ from = (u_short *)cp;
+ do
+ *to++ = *from++;
+ while (--words > 0);
+ mcp = (u_char *)to;
+ cp = (u_char *)from;
}
if (len & 01)
*mcp++ = *cp++;
*mp = m;
mp = &m->m_next;
- if (off) {
- off += len;
- if (off == totlen) {
- cp = ecbuf + ECRDOFF +
- sizeof (struct ec_header);
- off = 0;
- totlen = off0;
- }
- } else
+ if (off == 0) {
totlen -= len;
+ continue;
+ }
+ off += len;
+ if (off == totlen) {
+ cp = ecbuf + ECRDOFF + sizeof (struct ec_header);
+ off = 0;
+ totlen = off0;
+ }
}
return (top);
bad: