diff options
author | nbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2010-11-16 18:23:05 +0000 |
---|---|---|
committer | nbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2010-11-16 18:23:05 +0000 |
commit | 75c0610d60b6ae67b0d5355e487800b2f711f2b2 (patch) | |
tree | dc36da286964b3d7e5ae4d2fdafc8ffd6f28ce1b /package/mac80211/patches/530-ath9k_otp_rom.patch | |
parent | 3fc5f9de73cd9a08b08b44a2f798e8cc2c235707 (diff) |
ath9k: add some fixes for AR9003
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@24016 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'package/mac80211/patches/530-ath9k_otp_rom.patch')
-rw-r--r-- | package/mac80211/patches/530-ath9k_otp_rom.patch | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/package/mac80211/patches/530-ath9k_otp_rom.patch b/package/mac80211/patches/530-ath9k_otp_rom.patch new file mode 100644 index 0000000000..81f8de52fa --- /dev/null +++ b/package/mac80211/patches/530-ath9k_otp_rom.patch @@ -0,0 +1,149 @@ +--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c ++++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +@@ -3104,6 +3104,36 @@ error: + return false; + } + ++static bool ar9300_otp_read_word(struct ath_hw *ah, int addr, u32 *data) ++{ ++ REG_READ(ah, AR9300_OTP_BASE + (4 * addr)); ++ ++ if (!ath9k_hw_wait(ah, AR9300_OTP_STATUS, AR9300_OTP_STATUS_TYPE, ++ AR9300_OTP_STATUS_VALID, 1000)) ++ return false; ++ ++ *data = REG_READ(ah, AR9300_OTP_READ_DATA); ++ return true; ++} ++ ++static bool ar9300_read_otp(struct ath_hw *ah, int address, u8 *buffer, ++ int count) ++{ ++ u32 data; ++ int i; ++ ++ for (i = 0; i < count; i++) { ++ int offset = 8 * ((address - i) % 4); ++ if (!ar9300_otp_read_word(ah, (address - i) / 4, &data)) ++ return false; ++ ++ buffer[i] = (data >> offset) & 0xff; ++ } ++ ++ return true; ++} ++ ++ + static void ar9300_comp_hdr_unpack(u8 *best, int *code, int *reference, + int *length, int *major, int *minor) + { +@@ -3221,6 +3251,26 @@ static int ar9300_compress_decision(stru + return 0; + } + ++typedef bool (*eeprom_read_op)(struct ath_hw *ah, int address, u8 *buffer, ++ int count); ++ ++static bool ar9300_check_header(void *data) ++{ ++ u32 *word = data; ++ return !(*word == 0 || *word == ~0); ++} ++ ++static bool ar9300_check_eeprom_header(struct ath_hw *ah, eeprom_read_op read, ++ int base_addr) ++{ ++ u8 header[4]; ++ ++ if (!read(ah, base_addr, header, 4)) ++ return false; ++ ++ return ar9300_check_header(header); ++} ++ + /* + * Read the configuration data from the eeprom. + * The data can be put in any specified memory buffer. +@@ -3241,6 +3291,7 @@ static int ar9300_eeprom_restore_interna + int it; + u16 checksum, mchecksum; + struct ath_common *common = ath9k_hw_common(ah); ++ eeprom_read_op read; + + word = kzalloc(2048, GFP_KERNEL); + if (!word) +@@ -3248,14 +3299,42 @@ static int ar9300_eeprom_restore_interna + + memcpy(mptr, &ar9300_default, mdata_size); + ++ read = ar9300_read_eeprom; + cptr = AR9300_BASE_ADDR; ++ ath_print(common, ATH_DBG_EEPROM, ++ "Trying EEPROM accesss at Address 0x%04x\n", cptr); ++ if (ar9300_check_eeprom_header(ah, read, cptr)) ++ goto found; ++ ++ cptr = AR9300_BASE_ADDR_512; ++ ath_print(common, ATH_DBG_EEPROM, ++ "Trying EEPROM accesss at Address 0x%04x\n", cptr); ++ if (ar9300_check_eeprom_header(ah, read, cptr)) ++ goto found; ++ ++ read = ar9300_read_otp; ++ cptr = AR9300_BASE_ADDR; ++ ath_print(common, ATH_DBG_EEPROM, ++ "Trying OTP accesss at Address 0x%04x\n", cptr); ++ if (ar9300_check_eeprom_header(ah, read, cptr)) ++ goto found; ++ ++ cptr = AR9300_BASE_ADDR_512; ++ ath_print(common, ATH_DBG_EEPROM, ++ "Trying OTP accesss at Address 0x%04x\n", cptr); ++ if (ar9300_check_eeprom_header(ah, read, cptr)) ++ goto found; ++ ++ goto fail; ++ ++found: ++ ath_print(common, ATH_DBG_EEPROM, "Found valid EEPROM data"); ++ + for (it = 0; it < MSTATE; it++) { +- if (!ar9300_read_eeprom(ah, cptr, word, COMP_HDR_LEN)) ++ if (!read(ah, cptr, word, COMP_HDR_LEN)) + goto fail; + +- if ((word[0] == 0 && word[1] == 0 && word[2] == 0 && +- word[3] == 0) || (word[0] == 0xff && word[1] == 0xff +- && word[2] == 0xff && word[3] == 0xff)) ++ if (!ar9300_check_header(word)) + break; + + ar9300_comp_hdr_unpack(word, &code, &reference, +@@ -3272,8 +3351,7 @@ static int ar9300_eeprom_restore_interna + } + + osize = length; +- ar9300_read_eeprom(ah, cptr, word, +- COMP_HDR_LEN + osize + COMP_CKSUM_LEN); ++ read(ah, cptr, word, COMP_HDR_LEN + osize + COMP_CKSUM_LEN); + checksum = ar9300_comp_cksum(&word[COMP_HDR_LEN], length); + mchecksum = word[COMP_HDR_LEN + osize] | + (word[COMP_HDR_LEN + osize + 1] << 8); +--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h ++++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h +@@ -79,6 +79,15 @@ + #define FIXED_CCA_THRESHOLD 15 + + #define AR9300_BASE_ADDR 0x3ff ++#define AR9300_BASE_ADDR_512 0x1ff ++ ++#define AR9300_OTP_BASE 0x14000 ++#define AR9300_OTP_STATUS 0x15f18 ++#define AR9300_OTP_STATUS_TYPE 0x7 ++#define AR9300_OTP_STATUS_VALID 0x4 ++#define AR9300_OTP_STATUS_ACCESS_BUSY 0x2 ++#define AR9300_OTP_STATUS_SM_BUSY 0x1 ++#define AR9300_OTP_READ_DATA 0x15f1c + + enum targetPowerHTRates { + HT_TARGET_RATE_0_8_16, |