Subject: Re: half-working Conexant LANfinity driver
To: None <port-i386@NetBSD.org>
From: Frank Wille <frank@phoenix.owl.de>
List: port-i386
Date: 03/25/2006 21:45:44
Rui Paulo wrote:

> Around line 295 of ic/tulip.c are you adding RS7112 to the 21143-like
> switch statement ? I didn't found it in your patch.

You're right! That was it! Great! :)
The default code enabled ring mode, but the tlp_2114x_preinit was missing!

The only thing left to do was to filter the "receive process failed to idle"
messages whenver the interface was brought up. Now it's perfect!

Here is the polished patch for Conexant LANfinity. Maybe somebody with CVS
access might want to add it.

--- sys/dev/pci/pcidevs.orig    2006-03-23 16:25:06.000000000 +0100
+++ sys/dev/pci/pcidevs 2006-03-23 16:36:15.000000000 +0100
@@ -1308,6 +1308,7 @@
 /* Conexant Systems products */
 product CONEXANT SOFTK56       0x2443  SoftK56 PCI Software Modem
 product CONEXANT 56KFAXMODEM   0x1085  HW 56K Fax Modem
+product CONEXANT LANFINITY     0x1803  LANfinity MiniPCI 10/100 Ethernet
 
 /* Contaq Microsystems products */
 product CONTAQ 82C599          0x0600  82C599 PCI-VLB Bridge
--- sys/dev/pci/if_tlp_pci.c.orig       2006-03-23 16:36:34.000000000 +0100
+++ sys/dev/pci/if_tlp_pci.c    2006-03-25 20:57:30.000000000 +0100
@@ -172,6 +172,9 @@
        { PCI_VENDOR_ASIX,              PCI_PRODUCT_ASIX_AX88140A,
          TULIP_CHIP_AX88140 },
 
+       { PCI_VENDOR_CONEXANT,          PCI_PRODUCT_CONEXANT_LANFINITY,
+         TULIP_CHIP_RS7112 },
+
        { 0,                            0,
          TULIP_CHIP_INVALID },
 };
@@ -486,6 +489,7 @@
        case TULIP_CHIP_DM9102A:
        case TULIP_CHIP_AX88140:
        case TULIP_CHIP_AX88141:
+       case TULIP_CHIP_RS7112:
                /*
                 * Clear the "sleep mode" bit in the CFDA register.
                 */
@@ -945,6 +949,16 @@
                sc->sc_mediasw = &tlp_asix_mediasw;
                break;
 
+       case TULIP_CHIP_RS7112:
+               /*
+                * RS7112 Ethernet Address is located of offset 0x19a
+                * of the SROM
+                */
+               memcpy(enaddr, &sc->sc_srom[0x19a], ETHER_ADDR_LEN);
+
+               /* RS7112 chip has a PHY at MII address 1 */
+               sc->sc_mediasw = &tlp_rs7112_mediasw;
+               break;
        default:
  cant_cope:
                printf("%s: sorry, unable to handle your board\n",
--- sys/dev/ic/tulipvar.h.orig  2006-03-23 16:41:01.000000000 +0100
+++ sys/dev/ic/tulipvar.h       2006-03-23 19:05:40.000000000 +0100
@@ -153,7 +153,8 @@
        TULIP_CHIP_AN985     = 22,      /* ADMtek AN985 */
        TULIP_CHIP_AX88140   = 23,      /* ASIX AX88140 */
        TULIP_CHIP_AX88141   = 24,      /* ASIX AX88141 */
-       TULIP_CHIP_X3201_3   = 25       /* Xircom X3201-3 */
+       TULIP_CHIP_X3201_3   = 25,      /* Xircom X3201-3 */
+       TULIP_CHIP_RS7112    = 26       /* Conexant RS7112 LANfinity */
 } tulip_chip_t;
 
 #define        TULIP_CHIP_NAMES                                                \
@@ -184,6 +185,7 @@
        "ASIX AX88140",                                                 \
        "ASIX AX88141",                                                 \
        "Xircom X3201-3",                                               \
+       "Conexant RS7112",                                              \
 }
 
 struct tulip_softc;
@@ -596,6 +598,7 @@
 extern const struct tulip_mediasw tlp_an985_mediasw;
 extern const struct tulip_mediasw tlp_dm9102_mediasw;
 extern const struct tulip_mediasw tlp_asix_mediasw;
+extern const struct tulip_mediasw tlp_rs7112_mediasw;
 
 void   tlp_attach(struct tulip_softc *, const u_int8_t *);
 int    tlp_activate(struct device *, enum devact);
--- sys/dev/ic/tulip.c.orig     2006-03-23 16:59:02.000000000 +0100
+++ sys/dev/ic/tulip.c  2006-03-25 21:31:59.000000000 +0100
@@ -316,6 +316,7 @@
        case TULIP_CHIP_MX98715A:       /* 21143-like */
        case TULIP_CHIP_MX98715AEC_X:   /* 21143-like */
        case TULIP_CHIP_MX98725:        /* 21143-like */
+       case TULIP_CHIP_RS7112:         /* 21143-like */
                /*
                 * Run these chips in ring mode.
                 */
@@ -1605,7 +1606,8 @@
         */
        if (sc->sc_chip == TULIP_CHIP_X3201_3 ||
            sc->sc_chip == TULIP_CHIP_AX88140 ||
-           sc->sc_chip == TULIP_CHIP_AX88141) {
+           sc->sc_chip == TULIP_CHIP_AX88141 ||
+           sc->sc_chip == TULIP_CHIP_RS7112) {
                delay(10);
                TULIP_WRITE(sc, CSR_BUSMODE, 0);
        }
@@ -3204,6 +3206,7 @@
                        case TULIP_CHIP_AN983:
                        case TULIP_CHIP_AN985:
                        case TULIP_CHIP_DM9102A:
+                       case TULIP_CHIP_RS7112:
                                /*
                                 * Filter the message out on noisy chips.
                                 */
@@ -6328,3 +6331,48 @@
        return (tlp_mii_setmedia(sc));
 }
 
+/*
+ * RS7112 media switch.  Handles only MII attached to the SIO.
+ * We only have a PHY at 1.
+ */
+void   tlp_rs7112_tmsw_init(struct tulip_softc *);
+
+const struct tulip_mediasw tlp_rs7112_mediasw = {
+       tlp_rs7112_tmsw_init, tlp_mii_getmedia, tlp_mii_setmedia
+};
+
+void
+tlp_rs7112_tmsw_init(sc)
+       struct tulip_softc *sc;
+{
+       struct ifnet *ifp = &sc->sc_ethercom.ec_if;
+
+       /*
+        * We don't attach any media info structures to the ifmedia
+        * entries, so if we're using a pre-init function that needs
+        * that info, override it to one that doesn't.
+        */
+       if (sc->sc_preinit == tlp_2114x_preinit)
+               sc->sc_preinit = tlp_2114x_mii_preinit;
+
+       sc->sc_mii.mii_ifp = ifp;
+       sc->sc_mii.mii_readreg = tlp_bitbang_mii_readreg;
+       sc->sc_mii.mii_writereg = tlp_bitbang_mii_writereg;
+       sc->sc_mii.mii_statchg = sc->sc_statchg;
+       ifmedia_init(&sc->sc_mii.mii_media, 0, tlp_mediachange,
+           tlp_mediastatus);
+       /*
+        * The RS7112 reports a PHY at 0 (possibly HomePNA?)
+        * and 1 (ethernet). We attach ethernet only.
+        */
+       mii_attach(&sc->sc_dev, &sc->sc_mii, 0xffffffff, 1,
+           MII_OFFSET_ANY, 0);
+       if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
+               ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE, 0, NULL);
+               ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE);
+       } else {
+               sc->sc_flags |= TULIPF_HAS_MII;
+               sc->sc_tick = tlp_mii_tick;
+               ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO);
+       }
+}


-- 
    _  Frank Wille (frank@phoenix.owl.de)
 _ //  http://sun.hasenbraten.de/~frank/
 \X/   Phx @ #AmigaGer