Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/pci - Add the D-Link products, identified by subsyst...



details:   https://anonhg.NetBSD.org/src/rev/d6a91cdf6f1a
branches:  trunk
changeset: 970107:d6a91cdf6f1a
user:      thorpej <thorpej%NetBSD.org@localhost>
date:      Fri Mar 13 00:41:24 2020 +0000

description:
- Add the D-Link products, identified by subsystem ID.
- On some variations, the internal PHY is ghosted at #0 and #1.  Work
  around this by ignoring PHY #0 accesses unless we don't find one, and
  then look for one there as a fall-back if we don't detect anything else.
- Fix access width when setting the TxDMAUrgentThresh register.
- Support MBUFTRACE.

diffstat:

 sys/dev/pci/if_ste.c |  97 +++++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 84 insertions(+), 13 deletions(-)

diffs (193 lines):

diff -r 81d34500c804 -r d6a91cdf6f1a sys/dev/pci/if_ste.c
--- a/sys/dev/pci/if_ste.c      Fri Mar 13 00:32:05 2020 +0000
+++ b/sys/dev/pci/if_ste.c      Fri Mar 13 00:41:24 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_ste.c,v 1.60 2020/02/07 00:04:28 thorpej Exp $      */
+/*     $NetBSD: if_ste.c,v 1.61 2020/03/13 00:41:24 thorpej Exp $      */
 
 /*-
  * Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_ste.c,v 1.60 2020/02/07 00:04:28 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_ste.c,v 1.61 2020/03/13 00:41:24 thorpej Exp $");
 
 
 #include <sys/param.h>
@@ -156,6 +156,8 @@
        uint16_t sc_IntEnable;          /* prototype IntEnable register */
        uint16_t sc_MacCtrl0;           /* prototype MacCtrl0 register */
        uint8_t sc_ReceiveMode;         /* prototype ReceiveMode register */
+
+       bool    sc_enable_phy0;         /* access to phy #0 allowed */
 };
 
 #define        STE_CDTXADDR(sc, x)     ((sc)->sc_cddma + STE_CDTXOFF((x)))
@@ -245,35 +247,81 @@
 /*
  * Devices supported by this driver.
  */
-static const struct ste_product {
+struct ste_product {
        pci_vendor_id_t         ste_vendor;
        pci_product_id_t        ste_product;
        const char              *ste_name;
-} ste_products[] = {
+       const struct ste_product *ste_subs;
+};
+
+static const struct ste_product ste_dlink_products[] = {
+       { PCI_VENDOR_DLINK,             0x1002,
+         "D-Link DFE-550TX 10/100 Ethernet",
+         NULL },
+
+       { PCI_VENDOR_DLINK,             0x1003,
+         "D-Link DFE-550FX Ethernet",
+         NULL },
+
+       { PCI_VENDOR_DLINK,             0x1012,
+         "D-Link DFE-580TX 4-port 10/100 Ethernet",
+         NULL },
+
+       { PCI_VENDOR_DLINK,             0x1040,
+         "D-Link DFE-530TXS 10/100 Ethernet",
+         NULL },
+
+       { 0,                            0,
+         NULL,
+         NULL },
+};
+
+static const struct ste_product ste_products[] = {
        { PCI_VENDOR_SUNDANCETI,        PCI_PRODUCT_SUNDANCETI_IP100A,
-         "IC Plus Corp. IP00A 10/100 Fast Ethernet Adapter" },
+         "IC Plus Corp. IP00A 10/100 Fast Ethernet Adapter",
+         NULL },
 
        { PCI_VENDOR_SUNDANCETI,        PCI_PRODUCT_SUNDANCETI_ST201,
-         "Sundance ST-201 10/100 Ethernet" },
+         "Sundance ST-201 10/100 Ethernet",
+         NULL },
 
        { PCI_VENDOR_DLINK,             PCI_PRODUCT_DLINK_DL1002,
-         "D-Link DL-1002 10/100 Ethernet" },
+         "D-Link DL-1002 10/100 Ethernet",
+         ste_dlink_products },
 
        { 0,                            0,
+         NULL,
          NULL },
 };
 
 static const struct ste_product *
+ste_lookup_table(pcireg_t pci_id, const struct ste_product * const products)
+{
+       const struct ste_product *sp;
+
+       for (sp = products; sp->ste_name != NULL; sp++) {
+               if (PCI_VENDOR(pci_id) == sp->ste_vendor &&
+                   PCI_PRODUCT(pci_id) == sp->ste_product)
+                       return (sp);
+       }
+       return (NULL);
+}
+
+static const struct ste_product *
 ste_lookup(const struct pci_attach_args *pa)
 {
        const struct ste_product *sp;
 
-       for (sp = ste_products; sp->ste_name != NULL; sp++) {
-               if (PCI_VENDOR(pa->pa_id) == sp->ste_vendor &&
-                   PCI_PRODUCT(pa->pa_id) == sp->ste_product)
-                       return (sp);
+       sp = ste_lookup_table(pa->pa_id, ste_products);
+       if (sp && sp->ste_subs) {
+               const pcireg_t subsys =
+                   pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
+               const struct ste_product *ssp =
+                   ste_lookup_table(subsys, sp->ste_subs);
+               if (ssp)
+                       sp = ssp;
        }
-       return (NULL);
+       return (sp);
 }
 
 static int
@@ -471,6 +519,18 @@
        mii_attach(sc->sc_dev, mii, 0xffffffff, MII_PHY_ANY,
            MII_OFFSET_ANY, 0);
        if (LIST_FIRST(&mii->mii_phys) == NULL) {
+               /*
+                * It seems that some variants of this chip "ghost" the
+                * single PHY at #0 and #1.  We will try probing the MII
+                * first while ignoring #0 access.  If we find the PHY,
+                * great!  If not, un-ignore #0 and try probing *just*
+                * #0 to see if we can find it.
+                */
+               sc->sc_enable_phy0 = true;
+               mii_attach(sc->sc_dev, mii, 0xffffffff, 0,
+                   MII_OFFSET_ANY, 0);
+       }
+       if (LIST_FIRST(&mii->mii_phys) == NULL) {
                ifmedia_add(&mii->mii_media, IFM_ETHER | IFM_NONE, 0, NULL);
                ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_NONE);
        } else
@@ -643,6 +703,7 @@
                                    device_xname(sc->sc_dev));
                                break;
                        }
+                       MCLAIM(m, &sc->sc_ethercom.ec_tx_mowner);
                        if (m0->m_pkthdr.len > MHLEN) {
                                MCLGET(m, M_DONTWAIT);
                                if ((m->m_flags & M_EXT) == 0) {
@@ -1029,6 +1090,7 @@
                        MGETHDR(m, M_DONTWAIT, MT_DATA);
                        if (m == NULL)
                                goto dropit;
+                       MCLAIM(m, &sc->sc_ethercom.ec_rx_mowner);
                        m->m_data += 2;
                        memcpy(mtod(m, void *),
                            mtod(ds->ds_mbuf, void *), len);
@@ -1171,7 +1233,7 @@
        bus_space_write_2(sc->sc_st, sc->sc_sh,
            STE_TxStartThresh, sc->sc_txthresh);
        /* Urgent threshold: set to sc_txthresh / 2 */
-       bus_space_write_2(sc->sc_st, sc->sc_sh, STE_TxDMAUrgentThresh,
+       bus_space_write_1(sc->sc_st, sc->sc_sh, STE_TxDMAUrgentThresh,
            sc->sc_txthresh >> 6);
        /* Burst threshold: use default value (256 bytes) */
 }
@@ -1480,6 +1542,7 @@
        if (m == NULL)
                return (ENOBUFS);
 
+       MCLAIM(m, &sc->sc_ethercom.ec_rx_mowner);
        MCLGET(m, M_DONTWAIT);
        if ((m->m_flags & M_EXT) == 0) {
                m_freem(m);
@@ -1611,6 +1674,10 @@
 static int
 ste_mii_readreg(device_t self, int phy, int reg, uint16_t *val)
 {
+       struct ste_softc *sc = device_private(self);
+
+       if (phy == 0 && !sc->sc_enable_phy0)
+               return EIO;
 
        return mii_bitbang_readreg(self, &ste_mii_bitbang_ops, phy, reg, val);
 }
@@ -1623,6 +1690,10 @@
 static int
 ste_mii_writereg(device_t self, int phy, int reg, uint16_t val)
 {
+       struct ste_softc *sc = device_private(self);
+
+       if (phy == 0 && !sc->sc_enable_phy0)
+               return EIO;
 
        return mii_bitbang_writereg(self, &ste_mii_bitbang_ops, phy, reg, val);
 }



Home | Main Index | Thread Index | Old Index