- fix FIFO overruns on PCI-E chipsets by setting the DMA size
authorreyk <reyk@openbsd.org>
Tue, 29 Jul 2008 00:18:25 +0000 (00:18 +0000)
committerreyk <reyk@openbsd.org>
Tue, 29 Jul 2008 00:18:25 +0000 (00:18 +0000)
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
sys/dev/ic/ar5xxx.c
sys/dev/ic/ar5xxx.h
sys/dev/ic/ath.c
sys/dev/ic/athvar.h
sys/dev/pci/if_ath_pci.c

index 6a52bad..3ac49d1 100644 (file)
@@ -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 <reyk@openbsd.org>
@@ -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
index 39e6605..0cc67ed 100644 (file)
@@ -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 <reyk@openbsd.org>
@@ -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 */
index 200e36a..b632e11 100644 (file)
@@ -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 <reyk@openbsd.org>
@@ -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
index 8d9e9ab..07a8c7b 100644 (file)
@@ -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);
index 8ca19b8..ebaabbe 100644 (file)
@@ -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 */
index 7c9a509..b0097b3 100644 (file)
@@ -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;
 
        /*