summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoryongari <yongari@FreeBSD.org>2017-01-18 01:53:07 +0000
committeryongari <yongari@FreeBSD.org>2017-01-18 01:53:07 +0000
commitddc04a9e46d0a8e08f366a5542e69cd353c5427f (patch)
treeedb458e371fa869482d277db91559839d5206e35
parentda7662fc549a036244738efc973241d9e0db73e4 (diff)
downloadFreeBSD-src-ddc04a9e46d0a8e08f366a5542e69cd353c5427f.zip
FreeBSD-src-ddc04a9e46d0a8e08f366a5542e69cd353c5427f.tar.gz
MFC r304574-304575,304584:
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. r304575: Add Killer E2400 Gigabit Ethernet support. It seems Killer E2200/E2400 has a BIOS misconfiguration or silicon bug which triggers DMA write errors when driver uses advertised maximum payload size. Force the maximum payload size to 128 bytes in DMA configuration. This change should fix occasional DMA write errors reported on Killer E2200. r304584: Add a missing change in r304575.
-rw-r--r--sys/dev/alc/if_alc.c32
-rw-r--r--sys/dev/alc/if_alcreg.h3
-rw-r--r--sys/dev/alc/if_alcvar.h3
-rw-r--r--sys/dev/pci/pci.c7
4 files changed, 32 insertions, 13 deletions
diff --git a/sys/dev/alc/if_alc.c b/sys/dev/alc/if_alc.c
index ba37b5f..ec12da2 100644
--- a/sys/dev/alc/if_alc.c
+++ b/sys/dev/alc/if_alc.c
@@ -120,6 +120,8 @@ static struct alc_ident alc_ident_table[] = {
"Atheros AR8172 PCIe Fast Ethernet" },
{ VENDORID_ATHEROS, DEVICEID_ATHEROS_E2200, 9 * 1024,
"Killer E2200 Gigabit Ethernet" },
+ { VENDORID_ATHEROS, DEVICEID_ATHEROS_E2400, 9 * 1024,
+ "Killer E2400 Gigabit Ethernet" },
{ 0, 0, 0, NULL}
};
@@ -254,7 +256,7 @@ static struct resource_spec alc_irq_spec_msix[] = {
{ -1, 0, 0 }
};
-static 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 };
static int
alc_miibus_readreg(device_t dev, int phy, int reg)
@@ -1079,6 +1081,7 @@ alc_phy_down(struct alc_softc *sc)
switch (sc->alc_ident->deviceid) {
case DEVICEID_ATHEROS_AR8161:
case DEVICEID_ATHEROS_E2200:
+ case DEVICEID_ATHEROS_E2400:
case DEVICEID_ATHEROS_AR8162:
case DEVICEID_ATHEROS_AR8171:
case DEVICEID_ATHEROS_AR8172:
@@ -1396,12 +1399,15 @@ alc_attach(device_t dev)
* shows the same PHY model/revision number of AR8131.
*/
switch (sc->alc_ident->deviceid) {
+ case DEVICEID_ATHEROS_E2200:
+ case DEVICEID_ATHEROS_E2400:
+ sc->alc_flags |= ALC_FLAG_E2X00;
+ /* FALLTHROUGH */
case DEVICEID_ATHEROS_AR8161:
if (pci_get_subvendor(dev) == VENDORID_ATHEROS &&
pci_get_subdevice(dev) == 0x0091 && sc->alc_rev == 0)
sc->alc_flags |= ALC_FLAG_LINK_WAR;
/* FALLTHROUGH */
- case DEVICEID_ATHEROS_E2200:
case DEVICEID_ATHEROS_AR8171:
sc->alc_flags |= ALC_FLAG_AR816X_FAMILY;
break;
@@ -1472,6 +1478,12 @@ alc_attach(device_t dev)
sc->alc_dma_rd_burst = 3;
if (alc_dma_burst[sc->alc_dma_wr_burst] > 1024)
sc->alc_dma_wr_burst = 3;
+ /*
+ * Force maximum payload size to 128 bytes for E2200/E2400.
+ * Otherwise it triggers DMA write error.
+ */
+ if ((sc->alc_flags & ALC_FLAG_E2X00) != 0)
+ sc->alc_dma_wr_burst = 0;
alc_init_pcie(sc);
}
@@ -4194,13 +4206,17 @@ alc_init_locked(struct alc_softc *sc)
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 != DEVICEID_ATHEROS_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 != DEVICEID_ATHEROS_AR8151_V2)
+ reg |= RXQ_CFG_ASPM_THROUGHPUT_LIMIT_100M;
+ }
CSR_WRITE_4(sc, ALC_RXQ_CFG, reg);
/* Configure DMA parameters. */
@@ -4224,12 +4240,12 @@ alc_init_locked(struct alc_softc *sc)
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;
}
}
diff --git a/sys/dev/alc/if_alcreg.h b/sys/dev/alc/if_alcreg.h
index 1ad75a3..ae63084 100644
--- a/sys/dev/alc/if_alcreg.h
+++ b/sys/dev/alc/if_alcreg.h
@@ -45,10 +45,11 @@
#define DEVICEID_ATHEROS_AR8152_B 0x2060 /* L2C V1.1 */
#define DEVICEID_ATHEROS_AR8152_B2 0x2062 /* L2C V2.0 */
#define DEVICEID_ATHEROS_AR8161 0x1091
-#define DEVICEID_ATHEROS_E2200 0xE091
#define DEVICEID_ATHEROS_AR8162 0x1090
#define DEVICEID_ATHEROS_AR8171 0x10A1
#define DEVICEID_ATHEROS_AR8172 0x10A0
+#define DEVICEID_ATHEROS_E2200 0xE091
+#define DEVICEID_ATHEROS_E2400 0xE0A1
#define ATHEROS_AR8152_B_V10 0xC0
#define ATHEROS_AR8152_B_V11 0xC1
diff --git a/sys/dev/alc/if_alcvar.h b/sys/dev/alc/if_alcvar.h
index 9a73ef4..a1c3382 100644
--- a/sys/dev/alc/if_alcvar.h
+++ b/sys/dev/alc/if_alcvar.h
@@ -235,7 +235,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
struct callout alc_tick_ch;
struct alc_hw_stats alc_stats;
diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c
index 792469f..26cf526 100644
--- a/sys/dev/pci/pci.c
+++ b/sys/dev/pci/pci.c
@@ -269,12 +269,13 @@ static const struct pci_quirk pci_quirks[] = {
{ 0x43851002, PCI_QUIRK_UNMAP_REG, 0x14, 0 },
/*
- * Atheros AR8161/AR8162/E2200 Ethernet controllers have a bug that
- * MSI interrupt does not assert if PCIM_CMD_INTxDIS bit of the
- * command register is set.
+ * Atheros AR8161/AR8162/E2200/E2400 Ethernet controllers have a
+ * bug that MSI interrupt does not assert if PCIM_CMD_INTxDIS bit
+ * of the command register is set.
*/
{ 0x10911969, PCI_QUIRK_MSI_INTX_BUG, 0, 0 },
{ 0xE0911969, PCI_QUIRK_MSI_INTX_BUG, 0, 0 },
+ { 0xE0A11969, PCI_QUIRK_MSI_INTX_BUG, 0, 0 },
{ 0x10901969, PCI_QUIRK_MSI_INTX_BUG, 0, 0 },
/*
OpenPOWER on IntegriCloud