X-Git-Url: http://git.ozo.com/?a=blobdiff_plain;f=ath%2Fif_ath_hal_extensions.c;h=0e6a458e51b550ee36ad5a5c067ace8679b757ff;hb=f1873dba18f1031ecf8c1969d81e9a02a6c7d2c9;hp=927f5a0c565cc05fef09855ad23aa5aaa0d41aa5;hpb=e6646f6f0a611ddf39a95a487df06e5e38cb744c;p=madwifi%2F.git diff --git a/ath/if_ath_hal_extensions.c b/ath/if_ath_hal_extensions.c index 927f5a0..0e6a458 100644 --- a/ath/if_ath_hal_extensions.c +++ b/ath/if_ath_hal_extensions.c @@ -36,7 +36,7 @@ * $Id: br1 $ */ -#include "hal/ah_devid.h" +#include "ath_hal/ah_devid.h" #include "if_media.h" #include #include "if_athvar.h" @@ -80,56 +80,35 @@ static struct ath5k_srev_name srev_names[] = { { "xxxxx", AR5K_VERSION_RAD, AR5K_SREV_UNKNOWN }, }; +#define AR5210_MAGIC 0x19980124 +#define AR5211_MAGIC 0x19570405 +#define AR5212_MAGIC 0x19541014 +#define AR5416_MAGIC 0x20065416 int -ar_device(int devid) +ar_device(struct ath_softc *sc) { - switch (devid) { - case AR5210_DEFAULT: - case AR5210_PROD: - case AR5210_AP: + int magic = sc->sc_ah->ah_magic; + + switch (magic) { + case AR5210_MAGIC: return 5210; - case AR5211_DEFAULT: - case AR5311_DEVID: - case AR5211_LEGACY: - case AR5211_FPGA11B: + case AR5211_MAGIC: return 5211; - case AR5212_DEFAULT: - case AR5212_DEVID: - case AR5212_FPGA: - case AR5212_DEVID_IBM: - case AR5212_AR5312_REV2: - case AR5212_AR5312_REV7: - case AR5212_AR2313_REV8: - case AR5212_AR2315_REV6: - case AR5212_AR2315_REV7: - case AR5212_AR2317_REV1: - case AR5212_DEVID_0014: - case AR5212_DEVID_0015: - case AR5212_DEVID_0016: - case AR5212_DEVID_0017: - case AR5212_DEVID_0018: - case AR5212_DEVID_0019: - case AR5212_AR2413: - case AR5212_AR5413: - case AR5212_AR5424: - case AR5212_DEVID_FF19: + case AR5212_MAGIC: return 5212; - case AR5213_SREV_1_0: - case AR5213_SREV_REG: - case AR_SUBVENDOR_ID_NOG: - case AR_SUBVENDOR_ID_NEW_A: - return 5213; + case AR5416_MAGIC: + return 5416; default: - return 0; /* unknown */ + printk(KERN_WARNING "unknown HAL magic 0x%08x\n", magic); + return 0; } } - int ath_set_ack_bitrate(struct ath_softc *sc, int high) { - if (ar_device(sc->devid) == 5212 || ar_device(sc->devid) == 5213) { + if (ar_device(sc) == 5212) { /* set ack to be sent at low bit-rate */ u_int32_t v = AR5K_STA_ID1_BASE_RATE_11B | AR5K_STA_ID1_ACKCTS_6MB; if (high) @@ -161,3 +140,72 @@ ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val) return name; } + + +void +ath_hw_beacon_stop(struct ath_softc *sc) { + HAL_BEACON_TIMERS btimers; + + btimers.bt_intval = 0; + btimers.bt_nexttbtt = 0; + btimers.bt_nextdba = 0xffffffff; + btimers.bt_nextswba = 0xffffffff; + btimers.bt_nextatim = 0; + + ath_hal_setbeacontimers(sc->sc_ah, &btimers); +} + + +/* + * IBSS mode: check the ATIM window size and fix it if necessary. + * + * the need for this function arises from the problem that due to unlucky timing + * of beacon timer configuration (which we try to avoid) and due to unlucky + * timing of local TSF updates (triggered by the reception of a beacon with the + * same BSSID - something we can't avoid) the beacon timers can be up updated + * seperately, leaving one of them in the past, not beeing updated until the + * timers wrap around. due to the fact that the beacon interval does not fit + * into the timer period (16 bit) a whole number of times the size of the ATIM + * window can get bigger than desired. + * + * usually we have an ATIM window size of 1 but this function is written to + * handle other window sizes as well. + */ +int +ath_hw_check_atim(struct ath_softc *sc, int window, int intval) +{ + struct ath_hal *ah = sc->sc_ah; + unsigned int nbtt, atim, is5210 = 0; + + if (ATH_SREV_FROM_AH(ah) >= AR5K_SREV_VER_AR5416) + return 0; /* AR5416+ doesn't do ATIM in HW */ + + if (ATH_SREV_FROM_AH(ah) == AR5K_SREV_VER_AR5210) { + nbtt = OS_REG_READ(ah, AR5K_TIMER0_5210); + atim = OS_REG_READ(ah, AR5K_TIMER3_5210); + is5210 = 1; + } + else { + nbtt = OS_REG_READ(ah, AR5K_TIMER0_5211); + atim = OS_REG_READ(ah, AR5K_TIMER3_5211); + } + + /* + * check if the ATIM window is still correct: + * 1.) usually ATIM should be NBTT + window + * 2.) nbtt already updated + * 3.) nbtt already updated and has wrapped around + * 4.) atim has wrapped around + */ + if ((atim - nbtt != window) && /* 1.) */ + (nbtt - atim != intval - window) && /* 2.) */ + ((nbtt | 0x10000) - atim != intval - window) && /* 3.) */ + ((atim | 0x10000) - nbtt != window)) { /* 4.) */ + if (is5210) + OS_REG_WRITE(ah, AR5K_TIMER3_5210, nbtt + window ); + else + OS_REG_WRITE(ah, AR5K_TIMER3_5211, nbtt + window ); + return atim - nbtt; + } + return 0; +}