Module Name:    src
Committed By:   thorpej
Date:           Fri Mar 13 00:41:24 UTC 2020

Modified Files:
        src/sys/dev/pci: if_ste.c

Log Message:
- 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.


To generate a diff of this commit:
cvs rdiff -u -r1.60 -r1.61 src/sys/dev/pci/if_ste.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/pci/if_ste.c
diff -u src/sys/dev/pci/if_ste.c:1.60 src/sys/dev/pci/if_ste.c:1.61
--- src/sys/dev/pci/if_ste.c:1.60	Fri Feb  7 00:04:28 2020
+++ src/sys/dev/pci/if_ste.c	Fri Mar 13 00:41:24 2020
@@ -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 @@ struct ste_softc {
 	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,37 +247,83 @@ static const struct mii_bitbang_ops ste_
 /*
  * 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(const struct pci_attach_args *pa)
+ste_lookup_table(pcireg_t pci_id, const struct ste_product * const products)
 {
 	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)
+	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;
+
+	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 (sp);
+}
+
 static int
 ste_match(device_t parent, cfdata_t cf, void *aux)
 {
@@ -471,6 +519,18 @@ ste_attach(device_t parent, device_t sel
 	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 @@ ste_start(struct ifnet *ifp)
 				    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 @@ ste_rxintr(struct ste_softc *sc)
 			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 @@ ste_setthresh(struct ste_softc *sc)
 	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 @@ ste_add_rxbuf(struct ste_softc *sc, int 
 	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 @@ ste_set_filter(struct ste_softc *sc)
 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 @@ ste_mii_readreg(device_t self, int phy, 
 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);
 }

Reply via email to