aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2010-11-16 13:20:28 -0500
committerJohn W. Linville <linville@tuxdriver.com>2010-11-17 16:19:30 -0500
commit488f6ba75b5deaa7e89d6cdac07e0f2120899b6f (patch)
tree6b1bd30c51735d4646cbeecbd81ebca028a5baa2 /drivers/net/wireless/ath
parent2d42efc44e38d3a8b2bf30e34559036bb6541672 (diff)
ath9k_hw: add support for reading EEPROM data from the internal OTP ROM
Some of the new AR9003 cards do not come with an external EEPROM chip anymore. Calibration data on these cards is stored in the OTP ROM on the chip. This patch adds support for reading this data, and also adds support for different EEPROM chip sizes (512 bytes instead of 1K). Signed-off-by: Felix Fietkau <nbd@openwrt.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath')
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.c90
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.h9
2 files changed, 93 insertions, 6 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index 1b4e99167b6c..230a1228de8e 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -3104,6 +3104,36 @@ error:
3104 return false; 3104 return false;
3105} 3105}
3106 3106
3107static bool ar9300_otp_read_word(struct ath_hw *ah, int addr, u32 *data)
3108{
3109 REG_READ(ah, AR9300_OTP_BASE + (4 * addr));
3110
3111 if (!ath9k_hw_wait(ah, AR9300_OTP_STATUS, AR9300_OTP_STATUS_TYPE,
3112 AR9300_OTP_STATUS_VALID, 1000))
3113 return false;
3114
3115 *data = REG_READ(ah, AR9300_OTP_READ_DATA);
3116 return true;
3117}
3118
3119static bool ar9300_read_otp(struct ath_hw *ah, int address, u8 *buffer,
3120 int count)
3121{
3122 u32 data;
3123 int i;
3124
3125 for (i = 0; i < count; i++) {
3126 int offset = 8 * ((address - i) % 4);
3127 if (!ar9300_otp_read_word(ah, (address - i) / 4, &data))
3128 return false;
3129
3130 buffer[i] = (data >> offset) & 0xff;
3131 }
3132
3133 return true;
3134}
3135
3136
3107static void ar9300_comp_hdr_unpack(u8 *best, int *code, int *reference, 3137static void ar9300_comp_hdr_unpack(u8 *best, int *code, int *reference,
3108 int *length, int *major, int *minor) 3138 int *length, int *major, int *minor)
3109{ 3139{
@@ -3221,6 +3251,26 @@ static int ar9300_compress_decision(struct ath_hw *ah,
3221 return 0; 3251 return 0;
3222} 3252}
3223 3253
3254typedef bool (*eeprom_read_op)(struct ath_hw *ah, int address, u8 *buffer,
3255 int count);
3256
3257static bool ar9300_check_header(void *data)
3258{
3259 u32 *word = data;
3260 return !(*word == 0 || *word == ~0);
3261}
3262
3263static bool ar9300_check_eeprom_header(struct ath_hw *ah, eeprom_read_op read,
3264 int base_addr)
3265{
3266 u8 header[4];
3267
3268 if (!read(ah, base_addr, header, 4))
3269 return false;
3270
3271 return ar9300_check_header(header);
3272}
3273
3224/* 3274/*
3225 * Read the configuration data from the eeprom. 3275 * Read the configuration data from the eeprom.
3226 * The data can be put in any specified memory buffer. 3276 * The data can be put in any specified memory buffer.
@@ -3241,6 +3291,7 @@ static int ar9300_eeprom_restore_internal(struct ath_hw *ah,
3241 int it; 3291 int it;
3242 u16 checksum, mchecksum; 3292 u16 checksum, mchecksum;
3243 struct ath_common *common = ath9k_hw_common(ah); 3293 struct ath_common *common = ath9k_hw_common(ah);
3294 eeprom_read_op read;
3244 3295
3245 word = kzalloc(2048, GFP_KERNEL); 3296 word = kzalloc(2048, GFP_KERNEL);
3246 if (!word) 3297 if (!word)
@@ -3248,14 +3299,42 @@ static int ar9300_eeprom_restore_internal(struct ath_hw *ah,
3248 3299
3249 memcpy(mptr, &ar9300_default, mdata_size); 3300 memcpy(mptr, &ar9300_default, mdata_size);
3250 3301
3302 read = ar9300_read_eeprom;
3251 cptr = AR9300_BASE_ADDR; 3303 cptr = AR9300_BASE_ADDR;
3304 ath_print(common, ATH_DBG_EEPROM,
3305 "Trying EEPROM accesss at Address 0x%04x\n", cptr);
3306 if (ar9300_check_eeprom_header(ah, read, cptr))
3307 goto found;
3308
3309 cptr = AR9300_BASE_ADDR_512;
3310 ath_print(common, ATH_DBG_EEPROM,
3311 "Trying EEPROM accesss at Address 0x%04x\n", cptr);
3312 if (ar9300_check_eeprom_header(ah, read, cptr))
3313 goto found;
3314
3315 read = ar9300_read_otp;
3316 cptr = AR9300_BASE_ADDR;
3317 ath_print(common, ATH_DBG_EEPROM,
3318 "Trying OTP accesss at Address 0x%04x\n", cptr);
3319 if (ar9300_check_eeprom_header(ah, read, cptr))
3320 goto found;
3321
3322 cptr = AR9300_BASE_ADDR_512;
3323 ath_print(common, ATH_DBG_EEPROM,
3324 "Trying OTP accesss at Address 0x%04x\n", cptr);
3325 if (ar9300_check_eeprom_header(ah, read, cptr))
3326 goto found;
3327
3328 goto fail;
3329
3330found:
3331 ath_print(common, ATH_DBG_EEPROM, "Found valid EEPROM data");
3332
3252 for (it = 0; it < MSTATE; it++) { 3333 for (it = 0; it < MSTATE; it++) {
3253 if (!ar9300_read_eeprom(ah, cptr, word, COMP_HDR_LEN)) 3334 if (!read(ah, cptr, word, COMP_HDR_LEN))
3254 goto fail; 3335 goto fail;
3255 3336
3256 if ((word[0] == 0 && word[1] == 0 && word[2] == 0 && 3337 if (!ar9300_check_header(word))
3257 word[3] == 0) || (word[0] == 0xff && word[1] == 0xff
3258 && word[2] == 0xff && word[3] == 0xff))
3259 break; 3338 break;
3260 3339
3261 ar9300_comp_hdr_unpack(word, &code, &reference, 3340 ar9300_comp_hdr_unpack(word, &code, &reference,
@@ -3272,8 +3351,7 @@ static int ar9300_eeprom_restore_internal(struct ath_hw *ah,
3272 } 3351 }
3273 3352
3274 osize = length; 3353 osize = length;
3275 ar9300_read_eeprom(ah, cptr, word, 3354 read(ah, cptr, word, COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
3276 COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
3277 checksum = ar9300_comp_cksum(&word[COMP_HDR_LEN], length); 3355 checksum = ar9300_comp_cksum(&word[COMP_HDR_LEN], length);
3278 mchecksum = word[COMP_HDR_LEN + osize] | 3356 mchecksum = word[COMP_HDR_LEN + osize] |
3279 (word[COMP_HDR_LEN + osize + 1] << 8); 3357 (word[COMP_HDR_LEN + osize + 1] << 8);
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
index 5301df3e9ec0..57f64dbbcd89 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
@@ -79,6 +79,15 @@
79#define FIXED_CCA_THRESHOLD 15 79#define FIXED_CCA_THRESHOLD 15
80 80
81#define AR9300_BASE_ADDR 0x3ff 81#define AR9300_BASE_ADDR 0x3ff
82#define AR9300_BASE_ADDR_512 0x1ff
83
84#define AR9300_OTP_BASE 0x14000
85#define AR9300_OTP_STATUS 0x15f18
86#define AR9300_OTP_STATUS_TYPE 0x7
87#define AR9300_OTP_STATUS_VALID 0x4
88#define AR9300_OTP_STATUS_ACCESS_BUSY 0x2
89#define AR9300_OTP_STATUS_SM_BUSY 0x1
90#define AR9300_OTP_READ_DATA 0x15f1c
82 91
83enum targetPowerHTRates { 92enum targetPowerHTRates {
84 HT_TARGET_RATE_0_8_16, 93 HT_TARGET_RATE_0_8_16,