Module Name:    src
Committed By:   martin
Date:           Thu Oct 24 16:23:17 UTC 2019

Modified Files:
        src/share/man/man4 [netbsd-9]: alc.4
        src/sys/dev/pci [netbsd-9]: if_alc.c if_alcreg.h

Log Message:
Pull up following revision(s) (requested by msaitoh in ticket #375):

        sys/dev/pci/if_alc.c: revision 1.40
        sys/dev/pci/if_alc.c: revision 1.41
        sys/dev/pci/if_alc.c: revision 1.42
        sys/dev/pci/if_alc.c: revision 1.39
        sys/dev/pci/if_alcreg.h: revision 1.8
        share/man/man4/alc.4: revision 1.6

Apply FreeBSD r218141:
 > alc_rev was used without initialization such that it failed to
 > apply AR8152 v1.0 specific initialization code. Fix this bug by
 > explicitly reading PCI device revision id via PCI accessor.
 >
 > Reported by: Gabriel Linder ( linder.gabriel <> gmail dot com )

 Move PCIe initialization code from alc_attach() to alc_init_pcie().
No functional change.

Some alc(4) fixes:
- Apply FreeBSD r218141:
 > alc_rev was used without initialization such that it failed to
 > apply AR8152 v1.0 specific initialization code. Fix this bug by
 > explicitly reading PCI device revision id via PCI accessor.
 >
 > Reported by: Gabriel Linder ( linder.gabriel <> gmail dot com )

- Apply FreeBSD r304574:
 > Correct DMA channel number selection on AR816x family of
 > controllers. For Gigabit Ethernet version of AR816x, AR813x/AR815x
 > except L1D controller, use vendor recommended ASPM parameters.
 > While here, increase alc_dma_burst array size.  Broken H/W can
 > return bogus value in theory.

- Use static.

- Whitespace fix. Remove extra backslash.

Add support for Killer E2400 and E2500.


To generate a diff of this commit:
cvs rdiff -u -r1.5 -r1.5.18.1 src/share/man/man4/alc.4
cvs rdiff -u -r1.38 -r1.38.2.1 src/sys/dev/pci/if_alc.c
cvs rdiff -u -r1.6 -r1.6.22.1 src/sys/dev/pci/if_alcreg.h

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

Modified files:

Index: src/share/man/man4/alc.4
diff -u src/share/man/man4/alc.4:1.5 src/share/man/man4/alc.4:1.5.18.1
--- src/share/man/man4/alc.4:1.5	Mon Jan 19 11:53:59 2015
+++ src/share/man/man4/alc.4	Thu Oct 24 16:23:17 2019
@@ -1,4 +1,4 @@
-.\"	$NetBSD: alc.4,v 1.5 2015/01/19 11:53:59 wiz Exp $
+.\"	$NetBSD: alc.4,v 1.5.18.1 2019/10/24 16:23:17 martin Exp $
 .\"
 .\" Copyright (c) 2009 Kevin Lo <ke...@openbsd.org>
 .\"
@@ -14,12 +14,12 @@
 .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 .\"
-.Dd January 18, 2015
+.Dd October 16, 2019
 .Dt ALC 4
 .Os
 .Sh NAME
 .Nm alc
-.Nd Atheros AR813x/AR815x/AR816x/AR817x Ethernet device
+.Nd Atheros AR813x/AR815x/AR816x/AR817x Killer E2200/2400/2500 Ethernet device
 .Sh SYNOPSIS
 .Cd "alc* at pci?"
 .Cd "atphy* at mii?"
@@ -27,7 +27,8 @@
 The
 .Nm
 driver provides support for Ethernet interfaces based on the
-Atheros AR813x/AR815x/AR816x/AR817x Gigabit/Fast Ethernet chipsets.
+Atheros AR813x/AR815x/AR816x/AR817x Gigabit/Fast Ethernet chipsets and
+Killer E2200/2400/2500 Ethernet chipsets.
 .Pp
 The following
 .Ar media

Index: src/sys/dev/pci/if_alc.c
diff -u src/sys/dev/pci/if_alc.c:1.38 src/sys/dev/pci/if_alc.c:1.38.2.1
--- src/sys/dev/pci/if_alc.c:1.38	Tue Jul  9 08:46:58 2019
+++ src/sys/dev/pci/if_alc.c	Thu Oct 24 16:23:17 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_alc.c,v 1.38 2019/07/09 08:46:58 msaitoh Exp $	*/
+/*	$NetBSD: if_alc.c,v 1.38.2.1 2019/10/24 16:23:17 martin Exp $	*/
 /*	$OpenBSD: if_alc.c,v 1.1 2009/08/08 09:31:13 kevlo Exp $	*/
 /*-
  * Copyright (c) 2009, Pyun YongHyeon <yong...@freebsd.org>
@@ -101,6 +101,10 @@ static struct alc_ident alc_ident_table[
 		"Atheros AR8172 PCIe Fast Ethernet" },
 	{ PCI_VENDOR_ATTANSIC, PCI_PRODUCT_ATTANSIC_E2200, 9 * 1024,
 		"Killer E2200 Gigabit Ethernet" },
+	{ PCI_VENDOR_ATTANSIC, PCI_PRODUCT_ATTANSIC_E2400, 9 * 1024,
+		"Killer E2400 Gigabit Ethernet" },
+	{ PCI_VENDOR_ATTANSIC, PCI_PRODUCT_ATTANSIC_E2500, 9 * 1024,
+		"Killer E2500 Gigabit Ethernet" },
 	{ 0, 0, 0, NULL },
 };
 
@@ -166,8 +170,9 @@ static void	alc_stop_mac(struct alc_soft
 static void	alc_stop_queue(struct alc_softc *);
 static void	alc_tick(void *);
 static void	alc_txeof(struct alc_softc *);
+static void	alc_init_pcie(struct alc_softc *);
 
-uint32_t alc_dma_burst[] = { 128, 256, 512, 1024, 2048, 4096, 0 };
+static uint32_t alc_dma_burst[] = { 128, 256, 512, 1024, 2048, 4096, 0, 0 };
 
 CFATTACH_DECL_NEW(alc, sizeof(struct alc_softc),
     alc_match, alc_attach, alc_detach, NULL);
@@ -763,7 +768,6 @@ alc_get_macaddr_816x(struct alc_softc *s
 	alc_get_macaddr_par(sc);
 }
 
-
 static void
 alc_get_macaddr_par(struct alc_softc *sc)
 {
@@ -1002,6 +1006,8 @@ alc_phy_down(struct alc_softc *sc)
 	switch (sc->alc_ident->deviceid) {
 	case PCI_PRODUCT_ATTANSIC_AR8161:
 	case PCI_PRODUCT_ATTANSIC_E2200:
+	case PCI_PRODUCT_ATTANSIC_E2400:
+	case PCI_PRODUCT_ATTANSIC_E2500:
 	case PCI_PRODUCT_ATTANSIC_AR8162:
 	case PCI_PRODUCT_ATTANSIC_AR8171:
 	case PCI_PRODUCT_ATTANSIC_AR8172:
@@ -1172,6 +1178,83 @@ alc_aspm_816x(struct alc_softc *sc, int 
 }
 
 static void
+alc_init_pcie(struct alc_softc *sc)
+{
+	const char *aspm_state[] = { "L0s/L1", "L0s", "L1", "L0s/L1" };
+	uint32_t cap, ctl, val;
+	int state;
+
+	/* Clear data link and flow-control protocol error. */
+	val = CSR_READ_4(sc, ALC_PEX_UNC_ERR_SEV);
+	val &= ~(PEX_UNC_ERR_SEV_DLP | PEX_UNC_ERR_SEV_FCP);
+	CSR_WRITE_4(sc, ALC_PEX_UNC_ERR_SEV, val);
+
+	if ((sc->alc_flags & ALC_FLAG_AR816X_FAMILY) == 0) {
+		CSR_WRITE_4(sc, ALC_LTSSM_ID_CFG,
+		    CSR_READ_4(sc, ALC_LTSSM_ID_CFG) & ~LTSSM_ID_WRO_ENB);
+		CSR_WRITE_4(sc, ALC_PCIE_PHYMISC,
+		    CSR_READ_4(sc, ALC_PCIE_PHYMISC) |
+		    PCIE_PHYMISC_FORCE_RCV_DET);
+		if (sc->alc_ident->deviceid == PCI_PRODUCT_ATTANSIC_AR8152_B &&
+		    sc->alc_rev == ATHEROS_AR8152_B_V10) {
+			val = CSR_READ_4(sc, ALC_PCIE_PHYMISC2);
+			val &= ~(PCIE_PHYMISC2_SERDES_CDR_MASK |
+			    PCIE_PHYMISC2_SERDES_TH_MASK);
+			val |= 3 << PCIE_PHYMISC2_SERDES_CDR_SHIFT;
+			val |= 3 << PCIE_PHYMISC2_SERDES_TH_SHIFT;
+			CSR_WRITE_4(sc, ALC_PCIE_PHYMISC2, val);
+		}
+		/* Disable ASPM L0S and L1. */
+		cap = pci_conf_read(sc->sc_pct, sc->sc_pcitag,
+		    sc->alc_expcap + PCIE_LCAP) >> 16;
+		if ((cap & PCIE_LCAP_ASPM) != 0) {
+			ctl = pci_conf_read(sc->sc_pct, sc->sc_pcitag,
+			    sc->alc_expcap + PCIE_LCSR) >> 16;
+			if ((ctl & 0x08) != 0)
+				sc->alc_rcb = DMA_CFG_RCB_128;
+			if (alcdebug)
+				printf("%s: RCB %u bytes\n",
+				    device_xname(sc->sc_dev),
+				    sc->alc_rcb == DMA_CFG_RCB_64 ? 64 : 128);
+			state = ctl & 0x03;
+			if (state & 0x01)
+				sc->alc_flags |= ALC_FLAG_L0S;
+			if (state & 0x02)
+				sc->alc_flags |= ALC_FLAG_L1S;
+			if (alcdebug)
+				printf("%s: ASPM %s %s\n",
+				    device_xname(sc->sc_dev),
+				    aspm_state[state],
+				    state == 0 ? "disabled" : "enabled");
+			alc_disable_l0s_l1(sc);
+		} else {
+			aprint_debug_dev(sc->sc_dev, "no ASPM support\n");
+		}
+	} else {
+		val = CSR_READ_4(sc, ALC_PDLL_TRNS1);
+		val &= ~PDLL_TRNS1_D3PLLOFF_ENB;
+		CSR_WRITE_4(sc, ALC_PDLL_TRNS1, val);
+		val = CSR_READ_4(sc, ALC_MASTER_CFG);
+		if (AR816X_REV(sc->alc_rev) <= AR816X_REV_A1 &&
+		    (sc->alc_rev & 0x01) != 0) {
+			if ((val & MASTER_WAKEN_25M) == 0 ||
+			    (val & MASTER_CLK_SEL_DIS) == 0) {
+				val |= MASTER_WAKEN_25M | MASTER_CLK_SEL_DIS;
+				CSR_WRITE_4(sc, ALC_MASTER_CFG, val);
+			}
+		} else {
+			if ((val & MASTER_WAKEN_25M) == 0 ||
+			    (val & MASTER_CLK_SEL_DIS) != 0) {
+				val |= MASTER_WAKEN_25M;
+				val &= ~MASTER_CLK_SEL_DIS;
+				CSR_WRITE_4(sc, ALC_MASTER_CFG, val);
+			}
+		}
+	}
+	alc_aspm(sc, 1, IFM_UNKNOWN);
+}
+
+static void
 alc_attach(device_t parent, device_t self, void *aux)
 {
 
@@ -1183,13 +1266,12 @@ alc_attach(device_t parent, device_t sel
 	struct ifnet *ifp;
 	struct mii_data * const mii = &sc->sc_miibus;
 	pcireg_t memtype;
-	const char *aspm_state[] = { "L0s/L1", "L0s", "L1", "L0s/L1" };
 	uint16_t burst;
-	int base, mii_flags, state, error = 0;
-	uint32_t cap, ctl, val;
+	int base, mii_flags, error = 0;
 	char intrbuf[PCI_INTRSTR_LEN];
 
 	sc->alc_ident = alc_find_ident(pa);
+	sc->alc_rev = PCI_REVISION(pa->pa_class);
 
 	aprint_naive("\n");
 	aprint_normal(": %s\n", sc->alc_ident->name);
@@ -1266,75 +1348,14 @@ alc_attach(device_t parent, device_t sel
 			sc->alc_dma_rd_burst = 3;
 		if (alc_dma_burst[sc->alc_dma_wr_burst] > 1024)
 			sc->alc_dma_wr_burst = 3;
-
-		/* Clear data link and flow-control protocol error. */
-		val = CSR_READ_4(sc, ALC_PEX_UNC_ERR_SEV);
-		val &= ~(PEX_UNC_ERR_SEV_DLP | PEX_UNC_ERR_SEV_FCP);
-		CSR_WRITE_4(sc, ALC_PEX_UNC_ERR_SEV, val);
-
-		if ((sc->alc_flags & ALC_FLAG_AR816X_FAMILY) == 0) {
-			CSR_WRITE_4(sc, ALC_LTSSM_ID_CFG,
-			    CSR_READ_4(sc, ALC_LTSSM_ID_CFG) & ~LTSSM_ID_WRO_ENB);
-			CSR_WRITE_4(sc, ALC_PCIE_PHYMISC,
-			    CSR_READ_4(sc, ALC_PCIE_PHYMISC) |
-			    PCIE_PHYMISC_FORCE_RCV_DET);
-			if (sc->alc_ident->deviceid == PCI_PRODUCT_ATTANSIC_AR8152_B &&
-			    sc->alc_rev == ATHEROS_AR8152_B_V10) {
-				val = CSR_READ_4(sc, ALC_PCIE_PHYMISC2);
-				val &= ~(PCIE_PHYMISC2_SERDES_CDR_MASK |
-				    PCIE_PHYMISC2_SERDES_TH_MASK);
-				val |= 3 << PCIE_PHYMISC2_SERDES_CDR_SHIFT;
-				val |= 3 << PCIE_PHYMISC2_SERDES_TH_SHIFT;
-				CSR_WRITE_4(sc, ALC_PCIE_PHYMISC2, val);
-			}
-			/* Disable ASPM L0S and L1. */
-			cap = pci_conf_read(sc->sc_pct, sc->sc_pcitag,
-			    base + PCIE_LCAP) >> 16;
-			if ((cap & PCIE_LCAP_ASPM) != 0) {
-				ctl = pci_conf_read(sc->sc_pct, sc->sc_pcitag,
-				    base + PCIE_LCSR) >> 16;
-				if ((ctl & 0x08) != 0)
-					sc->alc_rcb = DMA_CFG_RCB_128;
-				if (alcdebug)
-					printf("%s: RCB %u bytes\n",
-					    device_xname(sc->sc_dev),
-					    sc->alc_rcb == DMA_CFG_RCB_64 ? 64 : 128);
-				state = ctl & 0x03;
-				if (state & 0x01)
-					sc->alc_flags |= ALC_FLAG_L0S;
-				if (state & 0x02)
-					sc->alc_flags |= ALC_FLAG_L1S;
-				if (alcdebug)
-					printf("%s: ASPM %s %s\n",
-					    device_xname(sc->sc_dev),
-					    aspm_state[state],
-					    state == 0 ? "disabled" : "enabled");
-				alc_disable_l0s_l1(sc);
-			} else {
-				aprint_debug_dev(sc->sc_dev, "no ASPM support\n");
-			}
-		} else {
-			val = CSR_READ_4(sc, ALC_PDLL_TRNS1);
-			val &= ~PDLL_TRNS1_D3PLLOFF_ENB;
-			CSR_WRITE_4(sc, ALC_PDLL_TRNS1, val);
-			val = CSR_READ_4(sc, ALC_MASTER_CFG);
-			if (AR816X_REV(sc->alc_rev) <= AR816X_REV_A1 &&
-			    (sc->alc_rev & 0x01) != 0) {
-				if ((val & MASTER_WAKEN_25M) == 0 ||
-				    (val & MASTER_CLK_SEL_DIS) == 0) {
-					val |= MASTER_WAKEN_25M | MASTER_CLK_SEL_DIS;
-					CSR_WRITE_4(sc, ALC_MASTER_CFG, val);
-				}
-			} else {
-				if ((val & MASTER_WAKEN_25M) == 0 ||
-				    (val & MASTER_CLK_SEL_DIS) != 0) {
-					val |= MASTER_WAKEN_25M;
-					val &= ~MASTER_CLK_SEL_DIS;
-					CSR_WRITE_4(sc, ALC_MASTER_CFG, val);
-				}
-			}
-		}
-		alc_aspm(sc, 1, IFM_UNKNOWN);
+		/*
+		 * Force maximum payload size to 128 bytes for
+		 * E2200/E2400/E2500.
+		 * Otherwise it triggers DMA write error.
+		 */
+		if ((sc->alc_flags & ALC_FLAG_E2X00) != 0)
+			sc->alc_dma_wr_burst = 0;
+		alc_init_pcie(sc);
 	}
 
 	/* Reset PHY. */
@@ -1352,13 +1373,17 @@ alc_attach(device_t parent, device_t sel
 	 * shows the same PHY model/revision number of AR8131.
 	 */
 	switch (sc->alc_ident->deviceid) {
+	case PCI_PRODUCT_ATTANSIC_E2200:
+	case PCI_PRODUCT_ATTANSIC_E2400:
+	case PCI_PRODUCT_ATTANSIC_E2500:
+		sc->alc_flags |= ALC_FLAG_E2X00;
+		/* FALLTHROUGH */
 	case PCI_PRODUCT_ATTANSIC_AR8161:
 		if (PCI_SUBSYS_ID(pci_conf_read(
 		   sc->sc_pct, sc->sc_pcitag, PCI_SUBSYS_ID_REG)) == 0x0091 &&
 		   sc->alc_rev == 0)
 			sc->alc_flags |= ALC_FLAG_LINK_WAR;
 		/* FALLTHROUGH */
-	case PCI_PRODUCT_ATTANSIC_E2200:
 	case PCI_PRODUCT_ATTANSIC_AR8171:
 		sc->alc_flags |= ALC_FLAG_AR816X_FAMILY;
 		break;
@@ -1393,7 +1418,6 @@ alc_attach(device_t parent, device_t sel
 	 * Don't use Tx CMB. It is known to have silicon bug.
 	 */
 	sc->alc_flags |= ALC_FLAG_CMB_BUG;
-	sc->alc_rev = PCI_REVISION(pa->pa_class);
 	sc->alc_chip_rev = CSR_READ_4(sc, ALC_MASTER_CFG) >>
 	    MASTER_CHIP_REV_SHIFT;
 	if (alcdebug) {
@@ -1782,7 +1806,6 @@ alc_dma_alloc(struct alc_softc *sc)
 	return (0);
 }
 
-
 static void
 alc_dma_free(struct alc_softc *sc)
 {
@@ -2847,7 +2870,7 @@ alc_init_backend(struct ifnet *ifp, bool
 		CSR_WRITE_4(sc, ALC_RRD1_HEAD_ADDR_LO, 0);
 		CSR_WRITE_4(sc, ALC_RRD2_HEAD_ADDR_LO, 0);
 		CSR_WRITE_4(sc, ALC_RRD3_HEAD_ADDR_LO, 0);
-	}\
+	}
 	/* Set Rx return descriptor counter. */
 	CSR_WRITE_4(sc, ALC_RRD_RING_CNT,
 	    (ALC_RR_RING_CNT << RRD_RING_CNT_SHIFT) & RRD_RING_CNT_MASK);
@@ -3044,13 +3067,17 @@ alc_init_backend(struct ifnet *ifp, bool
 	reg = (RXQ_CFG_RD_BURST_DEFAULT << RXQ_CFG_RD_BURST_SHIFT) &
 	    RXQ_CFG_RD_BURST_MASK;
 	reg |= RXQ_CFG_RSS_MODE_DIS;
-	if ((sc->alc_flags & ALC_FLAG_AR816X_FAMILY) != 0)
+	if ((sc->alc_flags & ALC_FLAG_AR816X_FAMILY) != 0) {
 		reg |= (RXQ_CFG_816X_IDT_TBL_SIZE_DEFAULT <<
 		    RXQ_CFG_816X_IDT_TBL_SIZE_SHIFT) &
 		    RXQ_CFG_816X_IDT_TBL_SIZE_MASK;
-	if ((sc->alc_flags & ALC_FLAG_FASTETHER) == 0 &&
-	    sc->alc_ident->deviceid != PCI_PRODUCT_ATTANSIC_AR8151_V2)
-		reg |= RXQ_CFG_ASPM_THROUGHPUT_LIMIT_1M;
+		if ((sc->alc_flags & ALC_FLAG_FASTETHER) == 0)
+			reg |= RXQ_CFG_ASPM_THROUGHPUT_LIMIT_100M;
+	} else {
+		if ((sc->alc_flags & ALC_FLAG_FASTETHER) == 0 &&
+		    sc->alc_ident->deviceid != PCI_PRODUCT_ATTANSIC_AR8151_V2)
+			reg |= RXQ_CFG_ASPM_THROUGHPUT_LIMIT_100M;
+	}
 	CSR_WRITE_4(sc, ALC_RXQ_CFG, reg);
 
 	/* Configure DMA parameters. */
@@ -3074,12 +3101,12 @@ alc_init_backend(struct ifnet *ifp, bool
 		switch (AR816X_REV(sc->alc_rev)) {
 		case AR816X_REV_A0:
 		case AR816X_REV_A1:
-			reg |= DMA_CFG_RD_CHNL_SEL_1;
+			reg |= DMA_CFG_RD_CHNL_SEL_2;
 			break;
 		case AR816X_REV_B0:
 			/* FALLTHROUGH */
 		default:
-			reg |= DMA_CFG_RD_CHNL_SEL_3;
+			reg |= DMA_CFG_RD_CHNL_SEL_4;
 			break;
 		}
 	}

Index: src/sys/dev/pci/if_alcreg.h
diff -u src/sys/dev/pci/if_alcreg.h:1.6 src/sys/dev/pci/if_alcreg.h:1.6.22.1
--- src/sys/dev/pci/if_alcreg.h:1.6	Thu Dec 29 19:22:51 2016
+++ src/sys/dev/pci/if_alcreg.h	Thu Oct 24 16:23:17 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_alcreg.h,v 1.6 2016/12/29 19:22:51 leot Exp $	*/
+/*	$NetBSD: if_alcreg.h,v 1.6.22.1 2019/10/24 16:23:17 martin Exp $	*/
 /*	$OpenBSD: if_alcreg.h,v 1.1 2009/08/08 09:31:13 kevlo Exp $	*/
 /*-
  * Copyright (c) 2009, Pyun YongHyeon <yong...@freebsd.org>
@@ -1475,7 +1475,8 @@ struct alc_softc {
 #define	ALC_FLAG_APS		0x1000
 #define	ALC_FLAG_AR816X_FAMILY	0x2000
 #define	ALC_FLAG_LINK_WAR	0x4000
-#define	ALC_FLAG_LINK		0x8000
+#define	ALC_FLAG_E2X00		0x8000
+#define	ALC_FLAG_LINK		0x10000
 
 	callout_t		sc_tick_ch;
 	struct alc_hw_stats	alc_stats;

Reply via email to