Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/ic - Encapsulate the EEPROM reading code into ep_rea...



details:   https://anonhg.NetBSD.org/src/rev/4caaf107ea4f
branches:  trunk
changeset: 477124:4caaf107ea4f
user:      thorpej <thorpej%NetBSD.org@localhost>
date:      Mon Oct 11 17:48:20 1999 +0000

description:
- Encapsulate the EEPROM reading code into ep_read_eeprom(), and use
  the correct "read eeprom" opcode on the RoadRunner (which has a larger
  EEPROM, and thus needs a different opcode to make room for the larger
  offsets).
- Reset and enable the MII before probing for PHYs, and reset and enable
  the MII in epinit().
- Be more conservative when resetting the interface after a transmit error.

Based on PR #8331, from Ryoji KATO.

Closer on 3c574, probably will work fine with the 3CCFEM556BI (which
won't have an older rev TDK Semi PHY, and which was tested by the author
of the PR).

diffstat:

 sys/dev/ic/elink3.c |  99 +++++++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 81 insertions(+), 18 deletions(-)

diffs (203 lines):

diff -r 6fc38f598b62 -r 4caaf107ea4f sys/dev/ic/elink3.c
--- a/sys/dev/ic/elink3.c       Mon Oct 11 17:41:56 1999 +0000
+++ b/sys/dev/ic/elink3.c       Mon Oct 11 17:48:20 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: elink3.c,v 1.58 1999/05/18 23:52:55 thorpej Exp $      */
+/*     $NetBSD: elink3.c,v 1.59 1999/10/11 17:48:20 thorpej Exp $      */
 
 /*-
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -213,6 +213,7 @@
 void   epmbuffill __P((void *));
 void   epmbufempty __P((struct ep_softc *));
 void   epsetfilter __P((struct ep_softc *));
+void   ep_roadrunner_mii_enable __P((struct ep_softc *));
 void   epsetmedia __P((struct ep_softc *));
 
 /* ifmedia callbacks */
@@ -233,6 +234,7 @@
 void   ep_mii_sendbits __P((struct ep_softc *, u_int32_t, int));
 
 static int epbusyeeprom __P((struct ep_softc *));
+u_int16_t ep_read_eeprom __P((struct ep_softc *, u_int16_t));
 static inline void ep_reset_cmd __P((struct ep_softc *sc, 
                                        u_int cmd, u_int arg));
 static inline void ep_finish_reset __P((bus_space_tag_t, bus_space_handle_t));
@@ -353,17 +355,10 @@
 
        if (enaddr == NULL) {
                /*
-                * Read the station address from the eeprom
+                * Read the station address from the eeprom.
                 */
                for (i = 0; i < 3; i++) {
-                       u_int16_t x;
-                       if (epbusyeeprom(sc))
-                               return;         /* XXX why is eeprom busy? */
-                       bus_space_write_2(iot, ioh, ELINK_W0_EEPROM_COMMAND,
-                                         READ_EEPROM | i);
-                       if (epbusyeeprom(sc))
-                               return;         /* XXX why is eeprom busy? */
-                       x = bus_space_read_2(iot, ioh, ELINK_W0_EEPROM_DATA);
+                       u_int16_t x = ep_read_eeprom(sc, i);
                        myla[(i << 1)] = x >> 8;
                        myla[(i << 1) + 1] = x;
                }
@@ -459,8 +454,14 @@
         * Now, determine which media we have.
         */
        switch (sc->ep_chipset) {
+       case ELINK_CHIPSET_ROADRUNNER:
+               if (sc->ep_flags & ELINK_FLAGS_MII) {
+                       ep_roadrunner_mii_enable(sc);
+                       GO_WINDOW(0);
+               }
+               /* FALLTHROUGH */
+
        case ELINK_CHIPSET_BOOMERANG:
-       case ELINK_CHIPSET_ROADRUNNER:
                /*
                 * If the device has MII, probe it.  We won't be using
                 * any `native' media in this case, only PHYs.  If
@@ -591,13 +592,7 @@
        /*
         * Get the default media from the EEPROM.
         */
-       if (epbusyeeprom(sc))
-               return;         /* XXX why is eeprom busy? */
-       bus_space_write_2(iot, ioh, ELINK_W0_EEPROM_COMMAND,
-           READ_EEPROM | EEPROM_ADDR_CFG);
-       if (epbusyeeprom(sc))
-               return;         /* XXX why is  eeprom busy? */
-       port = bus_space_read_2(iot, ioh, ELINK_W0_EEPROM_DATA) >> 14;
+       port = ep_read_eeprom(sc, EEPROM_ADDR_CFG) >> 14;
 
 #define        PRINT(s)        printf("%s%s", sep, s); sep = ", "
 
@@ -796,6 +791,11 @@
 
                bus_space_write_2(iot, ioh, ELINK_W1_RUNNER_WRCTL, 0);
                bus_space_write_2(iot, ioh, ELINK_W1_RUNNER_RDCTL, 0);
+
+               if (sc->ep_flags & ELINK_FLAGS_MII) {
+                       ep_roadrunner_mii_enable(sc);
+                       GO_WINDOW(1);
+               }
        }
 
        /* Enable interrupts. */
@@ -865,6 +865,30 @@
 }
 
 /*
+ * Reset and enable the MII on the RoadRunner.
+ */
+void
+ep_roadrunner_mii_enable(sc)
+       struct ep_softc *sc;
+{
+       bus_space_tag_t iot = sc->sc_iot;
+       bus_space_handle_t ioh = sc->sc_ioh;
+
+       GO_WINDOW(3);
+       bus_space_write_2(iot, ioh, ELINK_W3_RESET_OPTIONS,
+           ELINK_PCI_100BASE_MII|ELINK_RUNNER_ENABLE_MII);
+       delay(1000);
+       bus_space_write_2(iot, ioh, ELINK_W3_RESET_OPTIONS,
+           ELINK_PCI_100BASE_MII|ELINK_RUNNER_MII_RESET|
+           ELINK_RUNNER_ENABLE_MII);
+       ep_reset_cmd(sc, ELINK_COMMAND, TX_RESET);
+       ep_reset_cmd(sc, ELINK_COMMAND, RX_RESET);
+       delay(1000);
+       bus_space_write_2(iot, ioh, ELINK_W3_RESET_OPTIONS,
+           ELINK_PCI_100BASE_MII|ELINK_RUNNER_ENABLE_MII);
+}
+
+/*
  * Set the card to use the specified media.
  */
 void
@@ -891,6 +915,7 @@
 
                GO_WINDOW(3);
 
+#if 0
                if (sc->ep_chipset == ELINK_CHIPSET_ROADRUNNER) {
                        int resopt;
 
@@ -899,6 +924,7 @@
                        bus_space_write_2(iot, ioh,
                            ELINK_W3_RESET_OPTIONS, resopt|ELINK_RUNNER_ENABLE_MII);
                }
+#endif
 
                config0 = (u_int)bus_space_read_2(iot, ioh,
                    ELINK_W3_INTERNAL_CONFIG);
@@ -1312,7 +1338,11 @@
                        if (sc->sc_ethercom.ec_if.if_flags & IFF_DEBUG)
                                printf("%s: jabber (%x)\n",
                                       sc->sc_dev.dv_xname, i);
+#if 1
+                       ep_reset_cmd(sc, ELINK_COMMAND, TX_RESET);
+#else
                        epreset(sc);
+#endif
                } else if (i & TXS_UNDERRUN) {
                        ++sc->sc_ethercom.ec_if.if_oerrors;
                        if (sc->sc_ethercom.ec_if.if_flags & IFF_DEBUG)
@@ -1323,7 +1353,11 @@
                                    sc->tx_start_thresh = min(ETHER_MAX_LEN,
                                            sc->tx_start_thresh + 20);
                        sc->tx_succ_ok = 0;
+#if 1
+                       ep_reset_cmd(sc, ELINK_COMMAND, TX_RESET);
+#else
                        epreset(sc);
+#endif
                } else if (i & TXS_MAX_COLLISION) {
                        ++sc->sc_ethercom.ec_if.if_collisions;
                        bus_space_write_2(iot, ioh, ELINK_COMMAND, TX_ENABLE);
@@ -1404,7 +1438,11 @@
                if (status & S_CARD_FAILURE) {
                        printf("%s: adapter failure (%x)\n",
                            sc->sc_dev.dv_xname, status);
+#if 1
+                       epinit(sc);
+#else
                        epreset(sc);
+#endif
                        return (1);
                }
                if (status & S_TX_COMPLETE) {
@@ -1953,6 +1991,31 @@
        return (0);
 }
 
+u_int16_t
+ep_read_eeprom(sc, offset)
+       struct ep_softc *sc;
+       u_int16_t offset;
+{
+       u_int16_t readcmd;
+
+       /*
+        * RoadRunner has a larger EEPROM, so a different read command
+        * is required.
+        */
+       if (sc->ep_chipset == ELINK_CHIPSET_ROADRUNNER)
+               readcmd = READ_EEPROM_RR;
+       else
+               readcmd = READ_EEPROM;
+
+       if (epbusyeeprom(sc))
+               return (0);             /* XXX why is eeprom busy? */
+       bus_space_write_2(sc->sc_iot, sc->sc_ioh, ELINK_W0_EEPROM_COMMAND,
+           readcmd | offset);
+       if (epbusyeeprom(sc))
+               return (0);             /* XXX why is eeprom busy? */
+       return (bus_space_read_2(sc->sc_iot, sc->sc_ioh, ELINK_W0_EEPROM_DATA));
+}
+
 void
 epmbuffill(v)
        void *v;



Home | Main Index | Thread Index | Old Index