From f26dd3a5993144ffbf3f36c372f3796d5decfd31 Mon Sep 17 00:00:00 2001 From: reyk Date: Tue, 29 Jul 2008 00:18:25 +0000 Subject: [PATCH] - fix FIFO overruns on PCI-E chipsets by setting the DMA size RX/TX configuration registers to 128 instead of 512 bytes. - add a few more MAC/RF id strings for the dmesg. - check for PCI-E instead of single chip variants in a few places. ok deraadt@ --- sys/dev/ic/ar5212.c | 20 ++++++++++++-------- sys/dev/ic/ar5xxx.c | 25 +++++-------------------- sys/dev/ic/ar5xxx.h | 34 +++++++++++++++++++++++++++++++--- sys/dev/ic/ath.c | 6 +++--- sys/dev/ic/athvar.h | 4 ++-- sys/dev/pci/if_ath_pci.c | 11 ++++++++--- 6 files changed, 61 insertions(+), 39 deletions(-) diff --git a/sys/dev/ic/ar5212.c b/sys/dev/ic/ar5212.c index 6a52bad746c..3ac49d128d9 100644 --- a/sys/dev/ic/ar5212.c +++ b/sys/dev/ic/ar5212.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ar5212.c,v 1.42 2007/11/01 20:32:16 reyk Exp $ */ +/* $OpenBSD: ar5212.c,v 1.43 2008/07/29 00:18:25 reyk Exp $ */ /* * Copyright (c) 2004, 2005, 2006, 2007 Reyk Floeter @@ -320,10 +320,9 @@ ar5k_ar5212_nic_wakeup(struct ath_hal *hal, u_int16_t flags) * Reset and wakeup the device */ - /* ...reset chipset and PCI device */ - if (hal->ah_single_chip == AH_FALSE && - ar5k_ar5212_nic_reset(hal, - AR5K_AR5212_RC_CHIP | AR5K_AR5212_RC_PCI) == AH_FALSE) { + /* ...reset chipset and PCI device (if not PCI-E) */ + if (hal->ah_pci_express == AH_FALSE && + ar5k_ar5212_nic_reset(hal, AR5K_AR5212_RC_CHIP) == AH_FALSE) { AR5K_PRINT("failed to reset the AR5212 + PCI chipset\n"); return (AH_FALSE); } @@ -436,7 +435,7 @@ ar5k_ar5212_reset(struct ath_hal *hal, HAL_OPMODE op_mode, HAL_CHANNEL *channel, { struct ar5k_eeprom_info *ee = &hal->ah_capabilities.cap_eeprom; u_int8_t mac[IEEE80211_ADDR_LEN]; - u_int32_t data, s_seq, s_ant, s_led[3]; + u_int32_t data, s_seq, s_ant, s_led[3], dmasize; u_int i, phy, mode, freq, off, ee_mode, ant[2]; const HAL_RATE_TABLE *rt; @@ -729,11 +728,16 @@ ar5k_ar5212_reset(struct ath_hal *hal, HAL_OPMODE op_mode, HAL_CHANNEL *channel, /* * Set Rx/Tx DMA Configuration + * + * XXX Limit DMA size on PCI-E chipsets to 128 bytes because + * XXX we saw RX overruns and TX errors with higher values. */ + dmasize = hal->ah_pci_express == AH_TRUE ? + AR5K_AR5212_DMASIZE_128B : AR5K_AR5212_DMASIZE_512B; AR5K_REG_WRITE_BITS(AR5K_AR5212_TXCFG, AR5K_AR5212_TXCFG_SDMAMR, - AR5K_AR5212_DMASIZE_512B | AR5K_AR5212_TXCFG_DMASIZE); + dmasize | AR5K_AR5212_TXCFG_DMASIZE); AR5K_REG_WRITE_BITS(AR5K_AR5212_RXCFG, AR5K_AR5212_RXCFG_SDMAMW, - AR5K_AR5212_DMASIZE_512B); + dmasize); /* * Set channel and calibrate the PHY diff --git a/sys/dev/ic/ar5xxx.c b/sys/dev/ic/ar5xxx.c index 39e66050a66..0cc67ed4f92 100644 --- a/sys/dev/ic/ar5xxx.c +++ b/sys/dev/ic/ar5xxx.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ar5xxx.c,v 1.49 2008/07/28 16:56:06 reyk Exp $ */ +/* $OpenBSD: ar5xxx.c,v 1.50 2008/07/29 00:18:25 reyk Exp $ */ /* * Copyright (c) 2004, 2005, 2006, 2007 Reyk Floeter @@ -152,7 +152,7 @@ ath_hal_probe(u_int16_t vendor, u_int16_t device) */ struct ath_hal * ath_hal_attach(u_int16_t device, void *arg, bus_space_tag_t st, - bus_space_handle_t sh, u_int is_64bit, int *status) + bus_space_handle_t sh, u_int is_pcie, int *status) { struct ath_softc *sc = (struct ath_softc *)arg; struct ath_hal *hal = NULL; @@ -205,6 +205,7 @@ ath_hal_attach(u_int16_t device, void *arg, bus_space_tag_t st, hal->ah_limit_tx_retries = AR5K_INIT_TX_RETRY; hal->ah_software_retry = AH_FALSE; hal->ah_ant_diversity = AR5K_TUNE_ANT_DIVERSITY; + hal->ah_pci_express = is_pcie ? AH_TRUE : AH_FALSE; switch (device) { case PCI_PRODUCT_ATHEROS_AR2413: @@ -215,22 +216,6 @@ ath_hal_attach(u_int16_t device, void *arg, bus_space_tag_t st, */ hal->ah_single_chip = AH_TRUE; break; - case PCI_PRODUCT_ATHEROS_AR5212_IBM: - /* - * IBM ThinkPads use the same device ID for different - * chipset versions. Ugh. - */ - if (is_64bit) { - /* - * PCI Express "Mini Card" interface based on the - * AR5424 chipset - */ - hal->ah_single_chip = AH_TRUE; - } else { - /* Classic Mini PCI interface based on AR5212 */ - hal->ah_single_chip = AH_FALSE; - } - break; default: /* * Multi chip solutions @@ -281,7 +266,7 @@ ath_hal_attach(u_int16_t device, void *arg, bus_space_tag_t st, * XXX to limit 11b operation to 1-2Mbit/s. This * XXX needs to be fixed but allows basic operation for now. */ - if (hal->ah_single_chip == AH_TRUE) + if (hal->ah_pci_express == AH_TRUE) hal->ah_rt_11b.rateCount = 2; } if (hal->ah_capabilities.cap_mode & HAL_MODE_11G) ar5k_rt_copy(&hal->ah_rt_11g, &ar5k_rt_11g); @@ -1279,7 +1264,7 @@ ar5k_ar5112_channel(struct ath_hal *hal, HAL_CHANNEL *channel) * XXX after figuring out how to calculate the Atheros * XXX channel for these chipsets. */ - if (hal->ah_single_chip == AH_TRUE) { + if (hal->ah_pci_express == AH_TRUE) { c += c < 2427 ? -45 : /* channel 1-3 */ (c < 2447 ? -40 : /* channel 4-7 */ (c < 2462 ? -35 : /* channel 8-10 */ diff --git a/sys/dev/ic/ar5xxx.h b/sys/dev/ic/ar5xxx.h index 200e36a58c2..b632e11e3b0 100644 --- a/sys/dev/ic/ar5xxx.h +++ b/sys/dev/ic/ar5xxx.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ar5xxx.h,v 1.42 2007/10/12 15:34:11 reyk Exp $ */ +/* $OpenBSD: ar5xxx.h,v 1.43 2008/07/29 00:18:25 reyk Exp $ */ /* * Copyright (c) 2004, 2005, 2006, 2007 Reyk Floeter @@ -1108,6 +1108,7 @@ struct ath_hal { HAL_BOOL ah_calibration; HAL_BOOL ah_running; HAL_BOOL ah_single_chip; + HAL_BOOL ah_pci_express; HAL_RFGAIN ah_rf_gain; int ah_chanoff; @@ -1207,6 +1208,16 @@ struct ar5k_srev_name { { "5211", AR5K_VERSION_VER, AR5K_SREV_VER_AR5211 }, \ { "5212", AR5K_VERSION_VER, AR5K_SREV_VER_AR5212 }, \ { "5213", AR5K_VERSION_VER, AR5K_SREV_VER_AR5213 }, \ + { "5213A", AR5K_VERSION_VER, AR5K_SREV_VER_AR5213A },\ + { "2413", AR5K_VERSION_VER, AR5K_SREV_VER_AR2413 },\ + { "2414", AR5K_VERSION_VER, AR5K_SREV_VER_AR2414 },\ + { "2424", AR5K_VERSION_VER, AR5K_SREV_VER_AR2424 },\ + { "5424", AR5K_VERSION_VER, AR5K_SREV_VER_AR5424 },\ + { "5413", AR5K_VERSION_VER, AR5K_SREV_VER_AR5413 },\ + { "5414", AR5K_VERSION_VER, AR5K_SREV_VER_AR5414 },\ + { "5416", AR5K_VERSION_VER, AR5K_SREV_VER_AR5416 },\ + { "5418", AR5K_VERSION_VER, AR5K_SREV_VER_AR5418 },\ + { "2425", AR5K_VERSION_VER, AR5K_SREV_VER_AR2425 },\ { "xxxx", AR5K_VERSION_VER, AR5K_SREV_UNKNOWN }, \ { "5110", AR5K_VERSION_RAD, AR5K_SREV_RAD_5110 }, \ { "5111", AR5K_VERSION_RAD, AR5K_SREV_RAD_5111 }, \ @@ -1215,6 +1226,9 @@ struct ar5k_srev_name { { "5112a", AR5K_VERSION_RAD, AR5K_SREV_RAD_5112A }, \ { "2112", AR5K_VERSION_RAD, AR5K_SREV_RAD_2112 }, \ { "2112a", AR5K_VERSION_RAD, AR5K_SREV_RAD_2112A }, \ + { "2413", AR5K_VERSION_RAD, AR5K_SREV_RAD_2413 }, \ + { "2414", AR5K_VERSION_RAD, AR5K_SREV_RAD_5413 }, \ + { "5424", AR5K_VERSION_RAD, AR5K_SREV_RAD_5424 }, \ { "xxxx", AR5K_VERSION_RAD, AR5K_SREV_UNKNOWN }, \ { "2413", AR5K_VERSION_DEV, AR5K_DEVID_AR2413 }, \ { "5413", AR5K_VERSION_DEV, AR5K_DEVID_AR5413 }, \ @@ -1231,7 +1245,17 @@ struct ar5k_srev_name { #define AR5K_SREV_VER_AR5211 0x40 #define AR5K_SREV_VER_AR5212 0x50 #define AR5K_SREV_VER_AR5213 0x55 -#define AR5K_SREV_VER_UNSUPP 0x60 +#define AR5K_SREV_VER_AR5213A 0x59 +#define AR5K_SREV_VER_AR2413 0x78 +#define AR5K_SREV_VER_AR2414 0x79 +#define AR5K_SREV_VER_AR2424 0xa0 /* PCI-Express */ +#define AR5K_SREV_VER_AR5424 0xa3 /* PCI-Express */ +#define AR5K_SREV_VER_AR5413 0xa4 +#define AR5K_SREV_VER_AR5414 0xa5 +#define AR5K_SREV_VER_AR5416 0xc0 /* PCI-Express */ +#define AR5K_SREV_VER_AR5418 0xca /* PCI-Express */ +#define AR5K_SREV_VER_AR2425 0xe2 /* PCI-Express */ +#define AR5K_SREV_VER_UNSUPP 0xff #define AR5K_SREV_RAD_5110 0x00 #define AR5K_SREV_RAD_5111 0x10 @@ -1241,7 +1265,11 @@ struct ar5k_srev_name { #define AR5K_SREV_RAD_5112A 0x35 #define AR5K_SREV_RAD_2112 0x40 #define AR5K_SREV_RAD_2112A 0x45 -#define AR5K_SREV_RAD_UNSUPP 0x50 +#define AR5K_SREV_RAD_2413 0x56 +#define AR5K_SREV_RAD_5413 0x63 +#define AR5K_SREV_RAD_5424 0xa2 +#define AR5K_SREV_RAD_5133 0xc0 +#define AR5K_SREV_RAD_UNSUPP 0xff #define AR5K_DEVID_AR2413 0x001a #define AR5K_DEVID_AR5413 0x001b diff --git a/sys/dev/ic/ath.c b/sys/dev/ic/ath.c index 8d9e9abf71d..07a8c7b0c4a 100644 --- a/sys/dev/ic/ath.c +++ b/sys/dev/ic/ath.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ath.c,v 1.70 2008/07/21 18:43:19 damien Exp $ */ +/* $OpenBSD: ath.c,v 1.71 2008/07/29 00:18:25 reyk Exp $ */ /* $NetBSD: ath.c,v 1.37 2004/08/18 21:59:39 dyoung Exp $ */ /*- @@ -217,8 +217,8 @@ ath_attach(u_int16_t devid, struct ath_softc *sc) bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ); sc->sc_flags &= ~ATH_ATTACHED; /* make sure that it's not attached */ - ah = ath_hal_attach(devid, sc, sc->sc_st, sc->sc_sh, sc->sc_64bit, - &status); + ah = ath_hal_attach(devid, sc, sc->sc_st, sc->sc_sh, + sc->sc_pcie, &status); if (ah == NULL) { printf("%s: unable to attach hardware; HAL status %d\n", ifp->if_xname, status); diff --git a/sys/dev/ic/athvar.h b/sys/dev/ic/athvar.h index 8ca19b847ec..ebaabbe4241 100644 --- a/sys/dev/ic/athvar.h +++ b/sys/dev/ic/athvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: athvar.h,v 1.23 2008/07/21 18:43:19 damien Exp $ */ +/* $OpenBSD: athvar.h,v 1.24 2008/07/29 00:18:25 reyk Exp $ */ /* $NetBSD: athvar.h,v 1.10 2004/08/10 01:03:53 dyoung Exp $ */ /*- @@ -231,7 +231,7 @@ struct ath_softc { sc_veol : 1, /* tx VEOL support */ sc_softled : 1, /* GPIO software LED */ sc_probing : 1, /* probing AP on beacon miss */ - sc_64bit : 1; /* indicates PCI Express */ + sc_pcie : 1; /* indicates PCI Express */ u_int sc_nchan; /* number of valid channels */ const HAL_RATE_TABLE *sc_rates[IEEE80211_MODE_MAX]; const HAL_RATE_TABLE *sc_currates; /* current rate table */ diff --git a/sys/dev/pci/if_ath_pci.c b/sys/dev/pci/if_ath_pci.c index 7c9a50976ad..b0097b3e4e6 100644 --- a/sys/dev/pci/if_ath_pci.c +++ b/sys/dev/pci/if_ath_pci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_ath_pci.c,v 1.16 2008/06/14 02:28:14 jsing Exp $ */ +/* $OpenBSD: if_ath_pci.c,v 1.17 2008/07/29 00:18:25 reyk Exp $ */ /* $NetBSD: if_ath_pci.c,v 1.7 2004/06/30 05:58:17 mycroft Exp $ */ /*- @@ -142,14 +142,19 @@ ath_pci_attach(struct device *parent, struct device *self, void *aux) printf(": bad PCI register type %d\n", (int)mem_type); goto fail; } - if (mem_type == PCI_MAPREG_MEM_TYPE_64BIT) - sc->sc_64bit = 1; if (pci_mapreg_map(pa, ATH_BAR0, mem_type, 0, &sc->sc_st, &sc->sc_sh, NULL, &sc->sc_ss, 0)) { printf(": cannot map register space\n"); goto fail; } + /* + * PCI Express check. + */ + if (pci_get_capability(pc, pa->pa_tag, PCI_CAP_PCIEXPRESS, + NULL, NULL) != 0) + sc->sc_pcie = 1; + sc->sc_invalid = 1; /* -- 2.20.1