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