Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys Add minimal IP-over-Econet support and a load of bug-fix...



details:   https://anonhg.NetBSD.org/src/rev/5875814fb227
branches:  trunk
changeset: 515000:5875814fb227
user:      bjh21 <bjh21%NetBSD.org@localhost>
date:      Sat Sep 15 17:27:24 2001 +0000

description:
Add minimal IP-over-Econet support and a load of bug-fixes.  I can ping,
unreliably, between my RISC iX and NetBSD boxes with this.  There's a lot
of work to go before it's solid, though.

diffstat:

 sys/arch/arm26/ioc/if_eca.c    |   30 +++-
 sys/arch/arm26/ioc/if_ecavar.h |    3 +-
 sys/net/if_eco.h               |   19 ++-
 sys/net/if_ecosubr.c           |  247 ++++++++++++++++++++++++++++++++++++----
 4 files changed, 254 insertions(+), 45 deletions(-)

diffs (truncated from 529 to 300 lines):

diff -r 493cfc66ac65 -r 5875814fb227 sys/arch/arm26/ioc/if_eca.c
--- a/sys/arch/arm26/ioc/if_eca.c       Sat Sep 15 16:47:41 2001 +0000
+++ b/sys/arch/arm26/ioc/if_eca.c       Sat Sep 15 17:27:24 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_eca.c,v 1.1 2001/09/10 23:41:49 bjh21 Exp $ */
+/*     $NetBSD: if_eca.c,v 1.2 2001/09/15 17:27:24 bjh21 Exp $ */
 
 /*-
  * Copyright (c) 2001 Ben Harris
@@ -29,7 +29,7 @@
 
 #include <sys/param.h>
 
-__KERNEL_RCSID(0, "$NetBSD: if_eca.c,v 1.1 2001/09/10 23:41:49 bjh21 Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_eca.c,v 1.2 2001/09/15 17:27:24 bjh21 Exp $");
 
 #include <sys/device.h>
 #include <sys/malloc.h>
@@ -142,6 +142,9 @@
        int sr1, sr2;
        int err;
 
+       if ((err = eco_init(ifp)) != 0)
+               return err;
+
        /* Claim the FIQ early, in case we don't get it. */
        if (fiq_claim(eca_fiqhandler_rx,
            eca_efiqhandler_rx - eca_fiqhandler_rx))
@@ -286,9 +289,12 @@
 eca_txdone(void *arg)
 {
        struct eca_softc *sc = arg;
+       struct ifnet *ifp = &sc->sc_ec.ec_if;
 
        m_freem(sc->sc_txmbuf);
        sc->sc_txmbuf = NULL;
+       ifp->if_flags &= ~IFF_OACTIVE;
+       ifp->if_start(ifp);
 }
 
 /*
@@ -391,8 +397,10 @@
 static void
 eca_rx_downgrade(void)
 {
+       struct eca_softc *sc = eca_fiqowner;
 
-       softintr_schedule(eca_fiqowner->sc_rx_soft);
+       sc->sc_sr2 = bus_space_read_1(sc->sc_iot, sc->sc_ioh, MC6854_SR2);
+       softintr_schedule(sc->sc_rx_soft);
 }
 
 /*
@@ -410,16 +418,15 @@
        struct mbuf *m, *mtail, *n, *reply;
 
        reply = NULL;
-       KASSERT(!sc->sc_transmitting);
-       KASSERT(sc == eca_fiqowner);
-       sr2 = bus_space_read_1(iot, ioh, MC6854_SR2);
+       sr2 = sc->sc_sr2;
        /* OVRN and FV can be set together. */
        if (__predict_false(sr2 & MC6854_SR2_OVRN)) {
                log(LOG_ERR, "%s: Rx overrun\n", sc->sc_dev.dv_xname);
                ifp->if_ierrors++;
                /* Discard the rest of the frame. */
-               bus_space_write_1(iot, ioh, MC6854_CR1,
-                   sc->sc_cr1 | MC6854_CR1_DISCONTINUE);
+               if (!sc->sc_transmitting)
+                       bus_space_write_1(iot, ioh, MC6854_CR1,
+                           sc->sc_cr1 | MC6854_CR1_DISCONTINUE);
        } else if (__predict_true(sr2 & MC6854_SR2_FV)) {
                /* Frame Valid. */
                fiq_getregs(&fr);
@@ -463,8 +470,9 @@
                log(LOG_NOTICE, "%s: Oversized frame\n", sc->sc_dev.dv_xname);
                ifp->if_ierrors++;
                /* Discard the rest of the frame. */
-               bus_space_write_1(iot, ioh, MC6854_CR1,
-                   sc->sc_cr1 | MC6854_CR1_DISCONTINUE);
+               if (!sc->sc_transmitting)
+                       bus_space_write_1(iot, ioh, MC6854_CR1,
+                           sc->sc_cr1 | MC6854_CR1_DISCONTINUE);
        }
 
        bus_space_write_1(iot, ioh, MC6854_CR2,
@@ -472,7 +480,7 @@
 
        if (reply)
                eca_txframe(ifp, reply);
-       else {
+       else if (!sc->sc_transmitting) {
                /* Make sure we're not flag-filling. */
                bus_space_write_1(iot, ioh, MC6854_CR2,
                    sc->sc_cr2);
diff -r 493cfc66ac65 -r 5875814fb227 sys/arch/arm26/ioc/if_ecavar.h
--- a/sys/arch/arm26/ioc/if_ecavar.h    Sat Sep 15 16:47:41 2001 +0000
+++ b/sys/arch/arm26/ioc/if_ecavar.h    Sat Sep 15 17:27:24 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_ecavar.h,v 1.1 2001/09/10 23:41:49 bjh21 Exp $      */
+/*     $NetBSD: if_ecavar.h,v 1.2 2001/09/15 17:27:25 bjh21 Exp $      */
 
 /*-
  * Copyright (c) 2001 Ben Harris
@@ -56,6 +56,7 @@
        struct mbuf     *sc_rcvmbuf;
        void            *sc_rx_soft;
        struct eca_rxstate sc_rxstate;
+       u_int8_t        sc_sr2;
        struct mbuf     *sc_txmbuf;
        void            *sc_tx_soft;
        struct eca_txstate sc_txstate;
diff -r 493cfc66ac65 -r 5875814fb227 sys/net/if_eco.h
--- a/sys/net/if_eco.h  Sat Sep 15 16:47:41 2001 +0000
+++ b/sys/net/if_eco.h  Sat Sep 15 17:27:24 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_eco.h,v 1.1 2001/09/10 23:11:06 bjh21 Exp $ */
+/*     $NetBSD: if_eco.h,v 1.2 2001/09/15 17:27:24 bjh21 Exp $ */
 
 /*-
  * Copyright (c) 2001 Ben Harris
@@ -45,7 +45,9 @@
 #define ECO_ADDR_LEN   2       /* Length of an Econet address */
 #define ECO_HDR_LEN    6       /* Two addresses, a port and a control byte */
 #define ECO_SHDR_LEN   4       /* "Short" Econet header: just two addresses */
-#define ECO_MTU        8192    /* Default MTU */
+/* #define ECO_MTU     8192     * Default MTU */
+#define ECO_IPMTU      1280    /* MTU for IP used by RISC iX */
+#define ECO_MTU                ECO_IPMTU
 
 struct eco_header {
        u_int8_t        eco_dhost[ECO_ADDR_LEN];
@@ -94,11 +96,21 @@
 #define ECO_CTL_MACHINEPEEK    0x88
 #define ECO_CTL_GETREGISTERS   0x89
 
+/* Control bytes for IP */
+#define ECO_CTL_IP             0x81
+#define ECO_CTL_ARP_REQUEST    0xA1
+#define ECO_CTL_ARP_REPLY      0xA2
+
+struct eco_arp {
+       u_int8_t ecar_spa[4];
+       u_int8_t ecar_tpa[4];
+};
+
 /*
  * Common structure used to store state about an Econet interface.
  */
 enum eco_state {
-       ECO_IDLE, ECO_SCOUT_RCVD,
+       ECO_UNKNOWN, ECO_IDLE, ECO_SCOUT_RCVD,
        ECO_SCOUT_SENT, ECO_DATA_SENT, ECO_IMMED_SENT,
        ECO_DONE
 };
@@ -115,6 +127,7 @@
 #ifdef _KERNEL
 void   eco_ifattach(struct ifnet *, const u_int8_t *);
 void   eco_ifdetach(struct ifnet *);
+int    eco_init(struct ifnet *);
 
 char   *eco_sprintf(const u_int8_t *);
 
diff -r 493cfc66ac65 -r 5875814fb227 sys/net/if_ecosubr.c
--- a/sys/net/if_ecosubr.c      Sat Sep 15 16:47:41 2001 +0000
+++ b/sys/net/if_ecosubr.c      Sat Sep 15 17:27:24 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_ecosubr.c,v 1.3 2001/09/13 19:19:21 bjh21 Exp $     */
+/*     $NetBSD: if_ecosubr.c,v 1.4 2001/09/15 17:27:24 bjh21 Exp $     */
 
 /*-
  * Copyright (c) 2001 Ben Harris
@@ -62,10 +62,11 @@
  */
 
 #include "bpfilter.h"
+#include "opt_inet.h"
 
 #include <sys/param.h>
 
-__KERNEL_RCSID(0, "$NetBSD: if_ecosubr.c,v 1.3 2001/09/13 19:19:21 bjh21 Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_ecosubr.c,v 1.4 2001/09/15 17:27:24 bjh21 Exp $");
 
 #include <sys/errno.h>
 #include <sys/kernel.h>
@@ -78,12 +79,20 @@
 #include <net/if_dl.h>
 #include <net/if_eco.h>
 #include <net/if_types.h>
+#include <net/netisr.h>
 #include <net/route.h>
 
 #if NBPFILTER > 0
 #include <net/bpf.h>
 #endif
 
+#ifdef INET
+#include <net/ethertypes.h>
+#include <net/if_arp.h>
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#endif
+
 /* Default broadcast address */
 static const u_int8_t eco_broadcastaddr[] = { 0xff, 0xff };
 
@@ -100,7 +109,7 @@
 void
 eco_ifattach(struct ifnet *ifp, const u_int8_t *lla)
 {
-       struct ecocom *ec = (void *)ifp;
+/*     struct ecocom *ec = (void *)ifp; */
 
        ifp->if_type = IFT_OTHER;
        ifp->if_addrlen = ECO_ADDR_LEN;
@@ -119,7 +128,6 @@
 
        /* XXX cast safe? */
        ifp->if_broadcastaddr = (u_int8_t *)eco_broadcastaddr;
-       ec->ec_state = ECO_IDLE;
 #if NBPFILTER > 0
        bpfattach(ifp, ifp->if_dlt, ECO_HDR_LEN);
 #endif
@@ -130,16 +138,29 @@
        goto bad;                                                       \
 } while (/*CONSTCOND*/0)
 
+int
+eco_init(struct ifnet *ifp) {
+       struct ecocom *ec = (struct ecocom *)ifp;
+
+       ec->ec_state = ECO_UNKNOWN;
+       return 0;
+}
+
 static int
 eco_output(struct ifnet *ifp, struct mbuf *m0, struct sockaddr *dst,
     struct rtentry *rt0)
 {
        struct eco_header ehdr, *eh;
        int error, s;
-       struct mbuf *m = m0;
+       struct mbuf *m = m0, *mcopy = NULL;
        struct rtentry *rt;
        int hdrcmplt;
        size_t len;
+#ifdef INET
+       struct mbuf *m1;
+       struct arphdr *ah;
+       struct eco_arp *ecah;
+#endif
        ALTQ_DECL(struct altq_pktattr pktattr;)
 
        if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
@@ -184,6 +205,59 @@
 
        hdrcmplt = 0;
        switch (dst->sa_family) {
+#ifdef INET
+       case AF_INET:
+               if (m->m_flags & M_BCAST)
+                       memcpy(ehdr.eco_dhost, eco_broadcastaddr,
+                           ECO_ADDR_LEN);
+
+               else if (!arpresolve(ifp, rt, m, dst, ehdr.eco_dhost))
+                       return (0);     /* if not yet resolved */
+               /* If broadcasting on a simplex interface, loopback a copy */
+               if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX))
+                       mcopy = m_copy(m, 0, (int)M_COPYALL);
+               ehdr.eco_port = ECO_PORT_IP;
+               ehdr.eco_control = ECO_CTL_IP;
+               break;
+
+       case AF_ARP:
+               ah = mtod(m, struct arphdr *);
+
+               if (ntohs(ah->ar_pro) != ETHERTYPE_IP)
+                       return EAFNOSUPPORT;
+               ehdr.eco_port = ECO_PORT_IP;
+               switch (ntohs(ah->ar_op)) {
+               case ARPOP_REQUEST:
+                       ehdr.eco_control = ECO_CTL_ARP_REQUEST;
+                       break;
+               case ARPOP_REPLY:
+                       ehdr.eco_control = ECO_CTL_ARP_REPLY;
+                       break;
+               default:
+                       return EOPNOTSUPP;
+               }
+
+               if (m->m_flags & M_BCAST)
+                       memcpy(ehdr.eco_dhost, eco_broadcastaddr,
+                           ECO_ADDR_LEN);
+               else
+                       memcpy(ehdr.eco_dhost, ar_tha(ah), ECO_ADDR_LEN);
+
+               MGETHDR(m1, M_DONTWAIT, MT_DATA);
+               if (m1 == NULL)
+                       senderr(ENOBUFS);
+               M_COPY_PKTHDR(m1, m);



Home | Main Index | Thread Index | Old Index