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;