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