Subject: fix for mc*
To: None <port-macppc@netbsd.org>
From: Tim Kelly <hockey@dialectronics.com>
List: port-macppc
Date: 12/05/2004 17:35:38
Attached is a patch that will fix the problem with mc*. I could reproduce
it here and now I'm getting over 1Mb/sec with it. It was fairly simple,
actually. The routines for media status and change had a bad API and did
not match the ifnet* stuff. I'm not sure if the am79c950.c routines were
getting picked up or the caller was just bailing. In any event, I recall
that there was a problem on early PCI Macs that the AAUI connector had
priority over the 10BaseT connection, so if either IFM_MANUAL was used or
the media change routine wasn't properly linked, the chip probably
defaulted to AAUI. I made the API match on the two routines and made the
default be 10BaseT. I left the old stuff in and put the new stuff inside
#ifdef IFM, so you can test before and after. I see no difference now
between my sip* card and the mc* card, and from my G4 in MacOS9 and the mc
connection I downloaded (to G4) a 7M file in about six seconds. Previously
I got the same timeout errors before authentication could even occur with
ssh, but now it's quite useable.
tim
Index: if_mc.c
===================================================================
RCS file: /cvsroot/src/sys/arch/macppc/dev/if_mc.c,v
retrieving revision 1.9
diff -d -u -r1.9 if_mc.c
--- if_mc.c 15 Jul 2003 02:43:29 -0000 1.9
+++ if_mc.c 5 Dec 2004 22:19:36 -0000
@@ -61,6 +61,8 @@
#define MC_BUFSIZE 0x800
+#define IFM
+
hide int mc_match __P((struct device *, struct cfdata *, void *));
hide void mc_attach __P((struct device *, struct device *, void *));
hide void mc_init __P((struct mc_softc *sc));
@@ -70,8 +72,21 @@
hide void mc_reset_txdma __P((struct mc_softc *sc));
hide void mc_select_utp __P((struct mc_softc *sc));
hide void mc_select_aui __P((struct mc_softc *sc));
+
+#ifdef IFM
+static int mc_setup __P((struct mc_softc *, u_int8_t *));
+static int mc_mediachange __P((struct ifnet *));
+static void mc_mediastatus __P((struct ifnet *, struct ifmediareq *));
+
+extern int mcioctl __P((struct ifnet *ifp, u_long cmd, caddr_t data));
+extern void mcstart __P((struct ifnet *ifp));
+extern void mcwatchdog __P((struct ifnet *));
+
+#else
hide int mc_mediachange __P((struct mc_softc *sc));
hide void mc_mediastatus __P((struct mc_softc *sc, struct ifmediareq *));
+#endif
+
int mc_supmedia[] = {
IFM_ETHER | IFM_10_T,
@@ -174,9 +189,9 @@
dbdma_reset(sc->sc_txdma);
/* install interrupt handlers */
- /*intr_establish(ca->ca_intr[1], IST_LEVEL, IPL_NET, mc_dmaintr, sc);*/
- intr_establish(ca->ca_intr[2], IST_LEVEL, IPL_NET, mc_dmaintr, sc);
intr_establish(ca->ca_intr[0], IST_LEVEL, IPL_NET, mcintr, sc);
+ intr_establish(ca->ca_intr[1], IST_LEVEL, IPL_NET, mc_dmaintr, sc);
+ intr_establish(ca->ca_intr[2], IST_LEVEL, IPL_NET, mc_dmaintr, sc);
sc->sc_biucc = XMTSP_64;
sc->sc_fifocc = XMTFW_16 | RCVFW_64 | XMTFWU | RCVFWU |
@@ -184,11 +199,21 @@
/*sc->sc_plscc = PORTSEL_10BT;*/
sc->sc_plscc = PORTSEL_GPSI | ENPLSIO;
+#ifdef IFM
+ /* mc_setup returns 1 if something fails */
+ if (mc_setup(sc, myaddr)) {
+ printf("mcsetup returns non zero\n");
+ return;
+ }
+
+#else
/* mcsetup returns 1 if something fails */
if (mcsetup(sc, myaddr)) {
printf("mcsetup returns non zero\n");
return;
}
+#endif
+
#ifdef NOTYET
sc->sc_mediachange = mc_mediachange;
sc->sc_mediastatus = mc_mediastatus;
@@ -198,6 +223,48 @@
#endif
}
+#ifdef IFM
+/*
+ * Interface exists: make available by filling in network interface
+ * record. System will initialize the interface when it is ready
+ * to accept packets.
+ */
+int
+mc_setup(sc, lladdr)
+ struct mc_softc *sc;
+ u_int8_t *lladdr;
+{
+ struct ifnet *ifp = &sc->sc_if;
+
+ /* reset the chip and disable all interrupts */
+ NIC_PUT(sc, MACE_BIUCC, SWRST);
+ DELAY(100);
+ NIC_PUT(sc, MACE_IMR, ~0);
+
+ bcopy(lladdr, sc->sc_enaddr, ETHER_ADDR_LEN);
+ printf(": address %s\n", ether_sprintf(lladdr));
+
+ bcopy(sc->sc_dev.dv_xname,ifp->if_xname, IFNAMSIZ);
+ ifp->if_softc = sc;
+ ifp->if_ioctl = mcioctl;
+ ifp->if_start = mcstart;
+ ifp->if_flags =
+ IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST;
+ ifp->if_watchdog = mcwatchdog;
+
+ /* initialize ifmedia structures */
+ ifmedia_init(&sc->sc_media, 0, mc_mediachange, mc_mediastatus);
+ ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_10_T, 0, NULL);
+ ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_10_T);
+
+ if_attach(ifp);
+ ether_ifattach(ifp, lladdr);
+
+ return (0);
+}
+#endif
+
+
/* Bus-specific initialization */
hide void
mc_init(sc)
@@ -206,6 +273,7 @@
mc_reset_rxdma(sc);
mc_reset_txdma(sc);
}
+
hide void
mc_putpacket(sc, len)
@@ -371,17 +439,29 @@
}
int
+#ifdef IFM
+mc_mediachange(ifp)
+ struct ifnet *ifp;
+
+{
+ struct mc_softc *sc = ifp->if_softc;
+
+#else
mc_mediachange(sc)
struct mc_softc *sc;
+
{
- struct ifmedia *ifm = &sc->sc_media;
+#endif
+ struct ifmedia *ifm = &sc->sc_media;
+ /* printf("mc_mediachange called\n"); */
if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
return EINVAL;
switch (IFM_SUBTYPE(ifm->ifm_media)) {
case IFM_10_T:
+ case IFM_MANUAL:
mc_select_utp(sc);
break;
@@ -397,10 +477,21 @@
}
void
+#ifdef IFM
+mc_mediastatus(ifp, ifmr)
+ struct ifnet *ifp;
+ struct ifmediareq *ifmr;
+
+{
+ struct mc_softc *sc = ifp->if_softc;
+
+#else
mc_mediastatus(sc, ifmr)
struct mc_softc *sc;
struct ifmediareq *ifmr;
{
+#endif
+ /* printf("mc_mediastatus called\n"); */
if (sc->sc_plscc == PORTSEL_AUI)
ifmr->ifm_active = IFM_ETHER | IFM_10_5;
else
Index: if_mcvar.h
===================================================================
RCS file: /cvsroot/src/sys/arch/macppc/dev/if_mcvar.h,v
retrieving revision 1.7
diff -d -u -r1.7 if_mcvar.h
--- if_mcvar.h 9 Apr 2003 01:54:45 -0000 1.7
+++ if_mcvar.h 5 Dec 2004 22:19:49 -0000
@@ -80,6 +80,8 @@
void (*sc_mediastatus) __P((struct mc_softc *,
struct ifmediareq *));
+ u_int sc_defaultmedia;
+
bus_space_tag_t sc_regt;
bus_space_handle_t sc_regh;