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 17:44:53
Rui Paulo wrote:

>> tlp0: receive process failed to idle: state RUNNING - WAIT
>> -- status=f0670005 rxtatus=00000000 txstatus=00000001
>> tlp0: receive process failed to idle: state RUNNING - WAIT
> 
> [...]
> 
> Can you show us your patch to the tlp driver ?

Sure. Here it is:

--- pci/pcidevs.orig    2006-03-23 16:25:06.000000000 +0100
+++ 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
--- pci/if_tlp_pci.c.orig   2006-03-23 16:36:34.000000000 +0100
+++ pci/if_tlp_pci.c    2006-03-24 18:36:48.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 ... ? */
+       sc->sc_mediasw = &tlp_rs7112_mediasw;
+       break;
    default:
  cant_cope:
        printf("%s: sorry, unable to handle your board\n",
--- ic/tulipvar.h.orig  2006-03-23 16:41:01.000000000 +0100
+++ 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);
--- ic/tulip.c.orig 2006-03-23 16:59:02.000000000 +0100
+++ ic/tulip.c  2006-03-25 01:19:55.000000000 +0100
@@ -1,3 +1,4 @@
+#define TLP_DEBUG
 /* $NetBSD: tulip.c,v 1.135.2.1 2005/07/01 12:28:32 tron Exp $ */
 
 /*-
@@ -1115,6 +1116,7 @@
 
        rxstatus = status & sc->sc_rxint_mask;
        txstatus = status & sc->sc_txint_mask;
+/*@@@*/printf("-- status=%08x rxtatus=%08x txstatus=%08x\n",status,rxstatus,txstatus);
 
        if (rxstatus) {
            /* Grab new any new packets. */
@@ -1605,7 +1607,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);
    }
@@ -1898,9 +1901,9 @@
        /* Nothing. */
        break;
    }
-
    sc->sc_rxint_mask &= sc->sc_inten;
    sc->sc_txint_mask &= sc->sc_inten;
+/*@@@*/printf("** rxint_mask=%08x txint_mask=%08x **\n",sc->sc_rxint_mask,sc->sc_txint_mask);
 
    TULIP_WRITE(sc, CSR_INTEN, sc->sc_inten);
    TULIP_WRITE(sc, CSR_STATUS, 0xffffffff);
@@ -6328,3 +6331,66 @@
    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 *);
+void   tlp_rs7112_tmsw_getmedia(struct tulip_softc *, struct ifmediareq *);
+int    tlp_rs7112_tmsw_setmedia(struct tulip_softc *);
+
+const struct tulip_mediasw tlp_rs7112_mediasw = {
+   tlp_rs7112_tmsw_init, tlp_rs7112_tmsw_getmedia,
+   tlp_rs7112_tmsw_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);
+   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);
+   }
+}
+
+void
+tlp_rs7112_tmsw_getmedia(sc, ifmr)
+   struct tulip_softc *sc;
+   struct ifmediareq *ifmr;
+{
+   
+   /* XXX PHY handling. */
+   tlp_mii_getmedia(sc, ifmr);
+}
+
+int
+tlp_rs7112_tmsw_setmedia(sc)
+   struct tulip_softc *sc;
+{
+   
+   /* XXX PHY handling. */
+   return (tlp_mii_setmedia(sc));
+}


>> From what I can see in the FreeBSD dc driver the RS7112 is a simple
> 21143 with some small quirks.

Yes, so I hoped. But the FreeBSD and Linux drivers had workarounds for
different quirks, so I'm a bit confused. ;)


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