diff options
author | Nick Kossifidis <mick@madwifi-project.org> | 2009-02-08 23:06:34 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-02-13 13:44:45 -0500 |
commit | 8892e4ec62f1553d36c88e613890aa4d7c5a372e (patch) | |
tree | 3f7976379576a11d05d1723f3bcf8a03f821413a /drivers | |
parent | 6f3b414aca060a847e243f676b8601731938eb48 (diff) |
ath5k: Update RF Buffer handling
* Use the new way to modify rf buffer and put some rf buffer
documentation on rfbufer.h
* Merge all rf regs functions to one
* Sync with legacy HAL and Sam's HAL
* Set gain_F settings so that gain_F optimization engine works
on RF5111/RF5112 (note that both HALs only use step 0 for RF5111
and they don't use gain_F optimization for this chip, code is
there but is never used)
Signed-off-by: Nick Kossifidis <mickflemm@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/ath5k/ath5k.h | 11 | ||||
-rw-r--r-- | drivers/net/wireless/ath5k/phy.c | 571 | ||||
-rw-r--r-- | drivers/net/wireless/ath5k/reg.h | 24 | ||||
-rw-r--r-- | drivers/net/wireless/ath5k/reset.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath5k/rfbuffer.h | 88 |
5 files changed, 379 insertions, 317 deletions
diff --git a/drivers/net/wireless/ath5k/ath5k.h b/drivers/net/wireless/ath5k/ath5k.h index c870e2ae575..5b2e0da0a22 100644 --- a/drivers/net/wireless/ath5k/ath5k.h +++ b/drivers/net/wireless/ath5k/ath5k.h | |||
@@ -165,9 +165,6 @@ | |||
165 | #define AR5K_INI_VAL_XR 0 | 165 | #define AR5K_INI_VAL_XR 0 |
166 | #define AR5K_INI_VAL_MAX 5 | 166 | #define AR5K_INI_VAL_MAX 5 |
167 | 167 | ||
168 | #define AR5K_RF5111_INI_RF_MAX_BANKS AR5K_MAX_RF_BANKS | ||
169 | #define AR5K_RF5112_INI_RF_MAX_BANKS AR5K_MAX_RF_BANKS | ||
170 | |||
171 | /* Used for BSSID etc manipulation */ | 168 | /* Used for BSSID etc manipulation */ |
172 | #define AR5K_LOW_ID(_a)( \ | 169 | #define AR5K_LOW_ID(_a)( \ |
173 | (_a)[0] | (_a)[1] << 8 | (_a)[2] << 16 | (_a)[3] << 24 \ | 170 | (_a)[0] | (_a)[1] << 8 | (_a)[2] << 16 | (_a)[3] << 24 \ |
@@ -342,6 +339,7 @@ struct ath5k_srev_name { | |||
342 | 339 | ||
343 | #define AR5K_SREV_PHY_5211 0x30 | 340 | #define AR5K_SREV_PHY_5211 0x30 |
344 | #define AR5K_SREV_PHY_5212 0x41 | 341 | #define AR5K_SREV_PHY_5212 0x41 |
342 | #define AR5K_SREV_PHY_5212A 0x42 | ||
345 | #define AR5K_SREV_PHY_2112B 0x43 | 343 | #define AR5K_SREV_PHY_2112B 0x43 |
346 | #define AR5K_SREV_PHY_2413 0x45 | 344 | #define AR5K_SREV_PHY_2413 0x45 |
347 | #define AR5K_SREV_PHY_5413 0x61 | 345 | #define AR5K_SREV_PHY_5413 0x61 |
@@ -1083,8 +1081,9 @@ struct ath5k_hw { | |||
1083 | u32 ah_txq_isr; | 1081 | u32 ah_txq_isr; |
1084 | u32 *ah_rf_banks; | 1082 | u32 *ah_rf_banks; |
1085 | size_t ah_rf_banks_size; | 1083 | size_t ah_rf_banks_size; |
1084 | size_t ah_rf_regs_count; | ||
1086 | struct ath5k_gain ah_gain; | 1085 | struct ath5k_gain ah_gain; |
1087 | u32 ah_offset[AR5K_MAX_RF_BANKS]; | 1086 | u8 ah_offset[AR5K_MAX_RF_BANKS]; |
1088 | 1087 | ||
1089 | struct { | 1088 | struct { |
1090 | u16 txp_pcdac[AR5K_EEPROM_POWER_TABLE_SIZE]; | 1089 | u16 txp_pcdac[AR5K_EEPROM_POWER_TABLE_SIZE]; |
@@ -1232,7 +1231,9 @@ extern int ath5k_hw_disable_pspoll(struct ath5k_hw *ah); | |||
1232 | extern int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel); | 1231 | extern int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel); |
1233 | 1232 | ||
1234 | /* Initialize RF */ | 1233 | /* Initialize RF */ |
1235 | extern int ath5k_hw_rfregs(struct ath5k_hw *ah, struct ieee80211_channel *channel, unsigned int mode); | 1234 | extern int ath5k_hw_rfregs_init(struct ath5k_hw *ah, |
1235 | struct ieee80211_channel *channel, | ||
1236 | unsigned int mode); | ||
1236 | extern int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq); | 1237 | extern int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq); |
1237 | extern enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah); | 1238 | extern enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah); |
1238 | extern int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah); | 1239 | extern int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah); |
diff --git a/drivers/net/wireless/ath5k/phy.c b/drivers/net/wireless/ath5k/phy.c index 2543a718fe3..81f5bebc48b 100644 --- a/drivers/net/wireless/ath5k/phy.c +++ b/drivers/net/wireless/ath5k/phy.c | |||
@@ -32,48 +32,80 @@ | |||
32 | /* | 32 | /* |
33 | * Used to modify RF Banks before writing them to AR5K_RF_BUFFER | 33 | * Used to modify RF Banks before writing them to AR5K_RF_BUFFER |
34 | */ | 34 | */ |
35 | static unsigned int ath5k_hw_rfregs_op(u32 *rf, u32 offset, u32 reg, u32 bits, | 35 | static unsigned int ath5k_hw_rfb_op(struct ath5k_hw *ah, |
36 | u32 first, u32 col, bool set) | 36 | const struct ath5k_rf_reg *rf_regs, |
37 | u32 val, u8 reg_id, bool set) | ||
37 | { | 38 | { |
38 | u32 mask, entry, last, data, shift, position; | 39 | const struct ath5k_rf_reg *rfreg = NULL; |
39 | s32 left; | 40 | u8 offset, bank, num_bits, col, position; |
41 | u16 entry; | ||
42 | u32 mask, data, last_bit, bits_shifted, first_bit; | ||
43 | u32 *rfb; | ||
44 | s32 bits_left; | ||
40 | int i; | 45 | int i; |
41 | 46 | ||
42 | data = 0; | 47 | data = 0; |
48 | rfb = ah->ah_rf_banks; | ||
43 | 49 | ||
44 | if (rf == NULL) | 50 | for (i = 0; i < ah->ah_rf_regs_count; i++) { |
51 | if (rf_regs[i].index == reg_id) { | ||
52 | rfreg = &rf_regs[i]; | ||
53 | break; | ||
54 | } | ||
55 | } | ||
56 | |||
57 | if (rfb == NULL || rfreg == NULL) { | ||
58 | ATH5K_PRINTF("Rf register not found!\n"); | ||
45 | /* should not happen */ | 59 | /* should not happen */ |
46 | return 0; | 60 | return 0; |
61 | } | ||
62 | |||
63 | bank = rfreg->bank; | ||
64 | num_bits = rfreg->field.len; | ||
65 | first_bit = rfreg->field.pos; | ||
66 | col = rfreg->field.col; | ||
67 | |||
68 | /* first_bit is an offset from bank's | ||
69 | * start. Since we have all banks on | ||
70 | * the same array, we use this offset | ||
71 | * to mark each bank's start */ | ||
72 | offset = ah->ah_offset[bank]; | ||
47 | 73 | ||
48 | if (!(col <= 3 && bits <= 32 && first + bits <= 319)) { | 74 | /* Boundary check */ |
75 | if (!(col <= 3 && num_bits <= 32 && first_bit + num_bits <= 319)) { | ||
49 | ATH5K_PRINTF("invalid values at offset %u\n", offset); | 76 | ATH5K_PRINTF("invalid values at offset %u\n", offset); |
50 | return 0; | 77 | return 0; |
51 | } | 78 | } |
52 | 79 | ||
53 | entry = ((first - 1) / 8) + offset; | 80 | entry = ((first_bit - 1) / 8) + offset; |
54 | position = (first - 1) % 8; | 81 | position = (first_bit - 1) % 8; |
55 | 82 | ||
56 | if (set) | 83 | if (set) |
57 | data = ath5k_hw_bitswap(reg, bits); | 84 | data = ath5k_hw_bitswap(val, num_bits); |
85 | |||
86 | for (bits_shifted = 0, bits_left = num_bits; bits_left > 0; | ||
87 | position = 0, entry++) { | ||
88 | |||
89 | last_bit = (position + bits_left > 8) ? 8 : | ||
90 | position + bits_left; | ||
58 | 91 | ||
59 | for (i = shift = 0, left = bits; left > 0; position = 0, entry++, i++) { | 92 | mask = (((1 << last_bit) - 1) ^ ((1 << position) - 1)) << |
60 | last = (position + left > 8) ? 8 : position + left; | 93 | (col * 8); |
61 | mask = (((1 << last) - 1) ^ ((1 << position) - 1)) << (col * 8); | ||
62 | 94 | ||
63 | if (set) { | 95 | if (set) { |
64 | rf[entry] &= ~mask; | 96 | rfb[entry] &= ~mask; |
65 | rf[entry] |= ((data << position) << (col * 8)) & mask; | 97 | rfb[entry] |= ((data << position) << (col * 8)) & mask; |
66 | data >>= (8 - position); | 98 | data >>= (8 - position); |
67 | } else { | 99 | } else { |
68 | data = (((rf[entry] & mask) >> (col * 8)) >> position) | 100 | data |= (((rfb[entry] & mask) >> (col * 8)) >> position) |
69 | << shift; | 101 | << bits_shifted; |
70 | shift += last - position; | 102 | bits_shifted += last_bit - position; |
71 | } | 103 | } |
72 | 104 | ||
73 | left -= 8 - position; | 105 | bits_left -= 8 - position; |
74 | } | 106 | } |
75 | 107 | ||
76 | data = set ? 1 : ath5k_hw_bitswap(data, bits); | 108 | data = set ? 1 : ath5k_hw_bitswap(data, num_bits); |
77 | 109 | ||
78 | return data; | 110 | return data; |
79 | } | 111 | } |
@@ -167,6 +199,7 @@ static u32 ath5k_hw_rf_gainf_corr(struct ath5k_hw *ah) | |||
167 | u32 *rf; | 199 | u32 *rf; |
168 | const struct ath5k_gain_opt *go; | 200 | const struct ath5k_gain_opt *go; |
169 | const struct ath5k_gain_opt_step *g_step; | 201 | const struct ath5k_gain_opt_step *g_step; |
202 | const struct ath5k_rf_reg *rf_regs; | ||
170 | 203 | ||
171 | /* Only RF5112 Rev. 2 supports it */ | 204 | /* Only RF5112 Rev. 2 supports it */ |
172 | if ((ah->ah_radio != AR5K_RF5112) || | 205 | if ((ah->ah_radio != AR5K_RF5112) || |
@@ -174,6 +207,8 @@ static u32 ath5k_hw_rf_gainf_corr(struct ath5k_hw *ah) | |||
174 | return 0; | 207 | return 0; |
175 | 208 | ||
176 | go = &rfgain_opt_5112; | 209 | go = &rfgain_opt_5112; |
210 | rf_regs = rf_regs_5112a; | ||
211 | ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112a); | ||
177 | 212 | ||
178 | g_step = &go->go_step[ah->ah_gain.g_step_idx]; | 213 | g_step = &go->go_step[ah->ah_gain.g_step_idx]; |
179 | 214 | ||
@@ -184,11 +219,11 @@ static u32 ath5k_hw_rf_gainf_corr(struct ath5k_hw *ah) | |||
184 | ah->ah_gain.g_f_corr = 0; | 219 | ah->ah_gain.g_f_corr = 0; |
185 | 220 | ||
186 | /* No VGA (Variable Gain Amplifier) override, skip */ | 221 | /* No VGA (Variable Gain Amplifier) override, skip */ |
187 | if (ath5k_hw_rfregs_op(rf, ah->ah_offset[7], 0, 1, 36, 0, false) != 1) | 222 | if (ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_MIXVGA_OVR, false) != 1) |
188 | return 0; | 223 | return 0; |
189 | 224 | ||
190 | /* Mix gain stepping */ | 225 | /* Mix gain stepping */ |
191 | step = ath5k_hw_rfregs_op(rf, ah->ah_offset[7], 0, 4, 32, 0, false); | 226 | step = ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_MIXGAIN_STEP, false); |
192 | 227 | ||
193 | /* Mix gain override */ | 228 | /* Mix gain override */ |
194 | mix = g_step->gos_param[0]; | 229 | mix = g_step->gos_param[0]; |
@@ -217,6 +252,7 @@ static u32 ath5k_hw_rf_gainf_corr(struct ath5k_hw *ah) | |||
217 | * their detection window) so we must ignore it */ | 252 | * their detection window) so we must ignore it */ |
218 | static bool ath5k_hw_rf_check_gainf_readback(struct ath5k_hw *ah) | 253 | static bool ath5k_hw_rf_check_gainf_readback(struct ath5k_hw *ah) |
219 | { | 254 | { |
255 | const struct ath5k_rf_reg *rf_regs; | ||
220 | u32 step, mix_ovr, level[4]; | 256 | u32 step, mix_ovr, level[4]; |
221 | u32 *rf; | 257 | u32 *rf; |
222 | 258 | ||
@@ -226,8 +262,13 @@ static bool ath5k_hw_rf_check_gainf_readback(struct ath5k_hw *ah) | |||
226 | rf = ah->ah_rf_banks; | 262 | rf = ah->ah_rf_banks; |
227 | 263 | ||
228 | if (ah->ah_radio == AR5K_RF5111) { | 264 | if (ah->ah_radio == AR5K_RF5111) { |
229 | step = ath5k_hw_rfregs_op(rf, ah->ah_offset[7], 0, 6, 37, 0, | 265 | |
230 | false); | 266 | rf_regs = rf_regs_5111; |
267 | ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5111); | ||
268 | |||
269 | step = ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_RFGAIN_STEP, | ||
270 | false); | ||
271 | |||
231 | level[0] = 0; | 272 | level[0] = 0; |
232 | level[1] = (step == 63) ? 50 : step + 4; | 273 | level[1] = (step == 63) ? 50 : step + 4; |
233 | level[2] = (step != 63) ? 64 : level[0]; | 274 | level[2] = (step != 63) ? 64 : level[0]; |
@@ -238,8 +279,13 @@ static bool ath5k_hw_rf_check_gainf_readback(struct ath5k_hw *ah) | |||
238 | ah->ah_gain.g_low = level[0] + | 279 | ah->ah_gain.g_low = level[0] + |
239 | (step == 63 ? AR5K_GAIN_DYN_ADJUST_LO_MARGIN : 0); | 280 | (step == 63 ? AR5K_GAIN_DYN_ADJUST_LO_MARGIN : 0); |
240 | } else { | 281 | } else { |
241 | mix_ovr = ath5k_hw_rfregs_op(rf, ah->ah_offset[7], 0, 1, 36, 0, | 282 | |
242 | false); | 283 | rf_regs = rf_regs_5112; |
284 | ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112); | ||
285 | |||
286 | mix_ovr = ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_MIXVGA_OVR, | ||
287 | false); | ||
288 | |||
243 | level[0] = level[2] = 0; | 289 | level[0] = level[2] = 0; |
244 | 290 | ||
245 | if (mix_ovr == 1) { | 291 | if (mix_ovr == 1) { |
@@ -451,341 +497,320 @@ int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq) | |||
451 | * RF Registers setup * | 497 | * RF Registers setup * |
452 | \********************/ | 498 | \********************/ |
453 | 499 | ||
500 | |||
454 | /* | 501 | /* |
455 | * Read EEPROM Calibration data, modify RF Banks and Initialize RF5111 | 502 | * Setup RF registers by writing rf buffer on hw |
456 | */ | 503 | */ |
457 | static int ath5k_hw_rf5111_rfregs(struct ath5k_hw *ah, | 504 | int ath5k_hw_rfregs_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, |
458 | struct ieee80211_channel *channel, unsigned int mode) | 505 | unsigned int mode) |
459 | { | 506 | { |
507 | const struct ath5k_rf_reg *rf_regs; | ||
508 | const struct ath5k_ini_rfbuffer *ini_rfb; | ||
509 | const struct ath5k_gain_opt *go = NULL; | ||
510 | const struct ath5k_gain_opt_step *g_step; | ||
460 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; | 511 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; |
461 | u32 *rf; | 512 | u8 ee_mode = 0; |
462 | const unsigned int rf_size = ARRAY_SIZE(rfb_5111); | 513 | u32 *rfb; |
463 | unsigned int i; | 514 | int i, obdb = -1, bank = -1; |
464 | int obdb = -1, bank = -1; | ||
465 | u32 ee_mode; | ||
466 | 515 | ||
467 | AR5K_ASSERT_ENTRY(mode, AR5K_MODE_MAX); | 516 | switch (ah->ah_radio) { |
517 | case AR5K_RF5111: | ||
518 | rf_regs = rf_regs_5111; | ||
519 | ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5111); | ||
520 | ini_rfb = rfb_5111; | ||
521 | ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5111); | ||
522 | go = &rfgain_opt_5111; | ||
523 | break; | ||
524 | case AR5K_RF5112: | ||
525 | if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A) { | ||
526 | rf_regs = rf_regs_5112a; | ||
527 | ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112a); | ||
528 | ini_rfb = rfb_5112a; | ||
529 | ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5112a); | ||
530 | } else { | ||
531 | rf_regs = rf_regs_5112; | ||
532 | ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112); | ||
533 | ini_rfb = rfb_5112; | ||
534 | ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5112); | ||
535 | } | ||
536 | go = &rfgain_opt_5112; | ||
537 | break; | ||
538 | case AR5K_RF2413: | ||
539 | rf_regs = rf_regs_2413; | ||
540 | ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2413); | ||
541 | ini_rfb = rfb_2413; | ||
542 | ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2413); | ||
543 | break; | ||
544 | case AR5K_RF2316: | ||
545 | rf_regs = rf_regs_2316; | ||
546 | ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2316); | ||
547 | ini_rfb = rfb_2316; | ||
548 | ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2316); | ||
549 | break; | ||
550 | case AR5K_RF5413: | ||
551 | rf_regs = rf_regs_5413; | ||
552 | ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5413); | ||
553 | ini_rfb = rfb_5413; | ||
554 | ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5413); | ||
555 | break; | ||
556 | case AR5K_RF2317: | ||
557 | rf_regs = rf_regs_2425; | ||
558 | ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2425); | ||
559 | ini_rfb = rfb_2317; | ||
560 | ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2317); | ||
561 | break; | ||
562 | case AR5K_RF2425: | ||
563 | rf_regs = rf_regs_2425; | ||
564 | ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2425); | ||
565 | if (ah->ah_mac_srev < AR5K_SREV_AR2417) { | ||
566 | ini_rfb = rfb_2425; | ||
567 | ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2425); | ||
568 | } else { | ||
569 | ini_rfb = rfb_2417; | ||
570 | ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2417); | ||
571 | } | ||
572 | break; | ||
573 | default: | ||
574 | return -EINVAL; | ||
575 | } | ||
468 | 576 | ||
469 | rf = ah->ah_rf_banks; | 577 | /* If it's the first time we set rf buffer, allocate |
578 | * ah->ah_rf_banks based on ah->ah_rf_banks_size | ||
579 | * we set above */ | ||
580 | if (ah->ah_rf_banks == NULL) { | ||
581 | ah->ah_rf_banks = kmalloc(sizeof(u32) * ah->ah_rf_banks_size, | ||
582 | GFP_KERNEL); | ||
583 | if (ah->ah_rf_banks == NULL) { | ||
584 | ATH5K_ERR(ah->ah_sc, "out of memory\n"); | ||
585 | return -ENOMEM; | ||
586 | } | ||
587 | } | ||
470 | 588 | ||
471 | /* Copy values to modify them */ | 589 | /* Copy values to modify them */ |
472 | for (i = 0; i < rf_size; i++) { | 590 | rfb = ah->ah_rf_banks; |
473 | if (rfb_5111[i].rfb_bank >= AR5K_RF5111_INI_RF_MAX_BANKS) { | 591 | |
592 | for (i = 0; i < ah->ah_rf_banks_size; i++) { | ||
593 | if (ini_rfb[i].rfb_bank >= AR5K_MAX_RF_BANKS) { | ||
474 | ATH5K_ERR(ah->ah_sc, "invalid bank\n"); | 594 | ATH5K_ERR(ah->ah_sc, "invalid bank\n"); |
475 | return -EINVAL; | 595 | return -EINVAL; |
476 | } | 596 | } |
477 | 597 | ||
478 | if (bank != rfb_5111[i].rfb_bank) { | 598 | /* Bank changed, write down the offset */ |
479 | bank = rfb_5111[i].rfb_bank; | 599 | if (bank != ini_rfb[i].rfb_bank) { |
600 | bank = ini_rfb[i].rfb_bank; | ||
480 | ah->ah_offset[bank] = i; | 601 | ah->ah_offset[bank] = i; |
481 | } | 602 | } |
482 | 603 | ||
483 | rf[i] = rfb_5111[i].rfb_mode_data[mode]; | 604 | rfb[i] = ini_rfb[i].rfb_mode_data[mode]; |
484 | } | 605 | } |
485 | 606 | ||
486 | /* Modify bank 0 */ | 607 | /* Set Output and Driver bias current (OB/DB) */ |
487 | if (channel->hw_value & CHANNEL_2GHZ) { | 608 | if (channel->hw_value & CHANNEL_2GHZ) { |
609 | |||
488 | if (channel->hw_value & CHANNEL_CCK) | 610 | if (channel->hw_value & CHANNEL_CCK) |
489 | ee_mode = AR5K_EEPROM_MODE_11B; | 611 | ee_mode = AR5K_EEPROM_MODE_11B; |
490 | else | 612 | else |
491 | ee_mode = AR5K_EEPROM_MODE_11G; | 613 | ee_mode = AR5K_EEPROM_MODE_11G; |
492 | obdb = 0; | ||
493 | 614 | ||
494 | if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[0], | 615 | /* For RF511X/RF211X combination we |
495 | ee->ee_ob[ee_mode][obdb], 3, 119, 0, true)) | 616 | * use b_OB and b_DB parameters stored |
496 | return -EINVAL; | 617 | * in eeprom on ee->ee_ob[ee_mode][0] |
618 | * | ||
619 | * For all other chips we use OB/DB for 2Ghz | ||
620 | * stored in the b/g modal section just like | ||
621 | * 802.11a on ee->ee_ob[ee_mode][1] */ | ||
622 | if ((ah->ah_radio == AR5K_RF5111) || | ||
623 | (ah->ah_radio == AR5K_RF5112)) | ||
624 | obdb = 0; | ||
625 | else | ||
626 | obdb = 1; | ||
497 | 627 | ||
498 | if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[0], | 628 | ath5k_hw_rfb_op(ah, rf_regs, ee->ee_ob[ee_mode][obdb], |
499 | ee->ee_ob[ee_mode][obdb], 3, 122, 0, true)) | 629 | AR5K_RF_OB_2GHZ, true); |
500 | return -EINVAL; | ||
501 | 630 | ||
502 | obdb = 1; | 631 | ath5k_hw_rfb_op(ah, rf_regs, ee->ee_db[ee_mode][obdb], |
503 | /* Modify bank 6 */ | 632 | AR5K_RF_DB_2GHZ, true); |
504 | } else { | 633 | |
505 | /* For 11a, Turbo and XR */ | 634 | /* RF5111 always needs OB/DB for 5GHz, even if we use 2GHz */ |
635 | } else if ((channel->hw_value & CHANNEL_5GHZ) || | ||
636 | (ah->ah_radio == AR5K_RF5111)) { | ||
637 | |||
638 | /* For 11a, Turbo and XR we need to choose | ||
639 | * OB/DB based on frequency range */ | ||
506 | ee_mode = AR5K_EEPROM_MODE_11A; | 640 | ee_mode = AR5K_EEPROM_MODE_11A; |
507 | obdb = channel->center_freq >= 5725 ? 3 : | 641 | obdb = channel->center_freq >= 5725 ? 3 : |
508 | (channel->center_freq >= 5500 ? 2 : | 642 | (channel->center_freq >= 5500 ? 2 : |
509 | (channel->center_freq >= 5260 ? 1 : | 643 | (channel->center_freq >= 5260 ? 1 : |
510 | (channel->center_freq > 4000 ? 0 : -1))); | 644 | (channel->center_freq > 4000 ? 0 : -1))); |
511 | 645 | ||
512 | if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6], | 646 | if (obdb < 0) |
513 | ee->ee_pwd_84, 1, 51, 3, true)) | ||
514 | return -EINVAL; | 647 | return -EINVAL; |
515 | 648 | ||
516 | if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6], | 649 | ath5k_hw_rfb_op(ah, rf_regs, ee->ee_ob[ee_mode][obdb], |
517 | ee->ee_pwd_90, 1, 45, 3, true)) | 650 | AR5K_RF_OB_5GHZ, true); |
518 | return -EINVAL; | ||
519 | } | ||
520 | 651 | ||
521 | if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6], | 652 | ath5k_hw_rfb_op(ah, rf_regs, ee->ee_db[ee_mode][obdb], |
522 | !ee->ee_xpd[ee_mode], 1, 95, 0, true)) | 653 | AR5K_RF_DB_5GHZ, true); |
523 | return -EINVAL; | 654 | } |
524 | 655 | ||
525 | if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6], | 656 | g_step = &go->go_step[ah->ah_gain.g_step_idx]; |
526 | ee->ee_x_gain[ee_mode], 4, 96, 0, true)) | ||
527 | return -EINVAL; | ||
528 | 657 | ||
529 | if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6], obdb >= 0 ? | 658 | /* Bank Modifications (chip-specific) */ |
530 | ee->ee_ob[ee_mode][obdb] : 0, 3, 104, 0, true)) | 659 | if (ah->ah_radio == AR5K_RF5111) { |
531 | return -EINVAL; | ||
532 | 660 | ||
533 | if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6], obdb >= 0 ? | 661 | /* Set gain_F settings according to current step */ |
534 | ee->ee_db[ee_mode][obdb] : 0, 3, 107, 0, true)) | 662 | if (channel->hw_value & CHANNEL_OFDM) { |
535 | return -EINVAL; | ||
536 | 663 | ||
537 | /* Modify bank 7 */ | 664 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_FRAME_CTL, |
538 | if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[7], | 665 | AR5K_PHY_FRAME_CTL_TX_CLIP, |
539 | ee->ee_i_gain[ee_mode], 6, 29, 0, true)) | 666 | g_step->gos_param[0]); |
540 | return -EINVAL; | ||
541 | 667 | ||
542 | if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[7], | 668 | ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[1], |
543 | ee->ee_xpd[ee_mode], 1, 4, 0, true)) | 669 | AR5K_RF_PWD_90, true); |
544 | return -EINVAL; | ||
545 | 670 | ||
546 | /* Write RF values */ | 671 | ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[2], |
547 | for (i = 0; i < rf_size; i++) { | 672 | AR5K_RF_PWD_84, true); |
548 | AR5K_REG_WAIT(i); | ||
549 | ath5k_hw_reg_write(ah, rf[i], rfb_5111[i].rfb_ctrl_register); | ||
550 | } | ||
551 | 673 | ||
552 | ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE; | 674 | ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[3], |
675 | AR5K_RF_RFGAIN_SEL, true); | ||
553 | 676 | ||
554 | return 0; | 677 | /* We programmed gain_F parameters, switch back |
555 | } | 678 | * to active state */ |
679 | ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE; | ||
556 | 680 | ||
557 | /* | 681 | } |
558 | * Read EEPROM Calibration data, modify RF Banks and Initialize RF5112 | ||
559 | */ | ||
560 | static int ath5k_hw_rf5112_rfregs(struct ath5k_hw *ah, | ||
561 | struct ieee80211_channel *channel, unsigned int mode) | ||
562 | { | ||
563 | const struct ath5k_ini_rfbuffer *rf_ini; | ||
564 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; | ||
565 | u32 *rf; | ||
566 | unsigned int rf_size, i; | ||
567 | int obdb = -1, bank = -1; | ||
568 | u32 ee_mode; | ||
569 | 682 | ||
570 | AR5K_ASSERT_ENTRY(mode, AR5K_MODE_MAX); | 683 | /* Bank 6/7 setup */ |
571 | 684 | ||
572 | rf = ah->ah_rf_banks; | 685 | ath5k_hw_rfb_op(ah, rf_regs, !ee->ee_xpd[ee_mode], |
686 | AR5K_RF_PWD_XPD, true); | ||
573 | 687 | ||
574 | if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A) { | 688 | ath5k_hw_rfb_op(ah, rf_regs, ee->ee_x_gain[ee_mode], |
575 | rf_ini = rfb_5112a; | 689 | AR5K_RF_XPD_GAIN, true); |
576 | rf_size = ARRAY_SIZE(rfb_5112a); | ||
577 | } else { | ||
578 | rf_ini = rfb_5112; | ||
579 | rf_size = ARRAY_SIZE(rfb_5112); | ||
580 | } | ||
581 | 690 | ||
582 | /* Copy values to modify them */ | 691 | ath5k_hw_rfb_op(ah, rf_regs, ee->ee_i_gain[ee_mode], |
583 | for (i = 0; i < rf_size; i++) { | 692 | AR5K_RF_GAIN_I, true); |
584 | if (rf_ini[i].rfb_bank >= AR5K_RF5112_INI_RF_MAX_BANKS) { | ||
585 | ATH5K_ERR(ah->ah_sc, "invalid bank\n"); | ||
586 | return -EINVAL; | ||
587 | } | ||
588 | 693 | ||
589 | if (bank != rf_ini[i].rfb_bank) { | 694 | ath5k_hw_rfb_op(ah, rf_regs, ee->ee_xpd[ee_mode], |
590 | bank = rf_ini[i].rfb_bank; | 695 | AR5K_RF_PLO_SEL, true); |
591 | ah->ah_offset[bank] = i; | ||
592 | } | ||
593 | 696 | ||
594 | rf[i] = rf_ini[i].rfb_mode_data[mode]; | 697 | /* TODO: Half/quarter channel support */ |
595 | } | 698 | } |
596 | 699 | ||
597 | /* Modify bank 6 */ | 700 | if (ah->ah_radio == AR5K_RF5112) { |
598 | if (channel->hw_value & CHANNEL_2GHZ) { | ||
599 | if (channel->hw_value & CHANNEL_OFDM) | ||
600 | ee_mode = AR5K_EEPROM_MODE_11G; | ||
601 | else | ||
602 | ee_mode = AR5K_EEPROM_MODE_11B; | ||
603 | obdb = 0; | ||
604 | 701 | ||
605 | if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6], | 702 | /* Set gain_F settings according to current step */ |
606 | ee->ee_ob[ee_mode][obdb], 3, 287, 0, true)) | 703 | if (channel->hw_value & CHANNEL_OFDM) { |
607 | return -EINVAL; | ||
608 | 704 | ||
609 | if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6], | 705 | ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[0], |
610 | ee->ee_ob[ee_mode][obdb], 3, 290, 0, true)) | 706 | AR5K_RF_MIXGAIN_OVR, true); |
611 | return -EINVAL; | ||
612 | } else { | ||
613 | /* For 11a, Turbo and XR */ | ||
614 | ee_mode = AR5K_EEPROM_MODE_11A; | ||
615 | obdb = channel->center_freq >= 5725 ? 3 : | ||
616 | (channel->center_freq >= 5500 ? 2 : | ||
617 | (channel->center_freq >= 5260 ? 1 : | ||
618 | (channel->center_freq > 4000 ? 0 : -1))); | ||
619 | 707 | ||
620 | if (obdb == -1) | 708 | ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[1], |
621 | return -EINVAL; | 709 | AR5K_RF_PWD_138, true); |
622 | 710 | ||
623 | if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6], | 711 | ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[2], |
624 | ee->ee_ob[ee_mode][obdb], 3, 279, 0, true)) | 712 | AR5K_RF_PWD_137, true); |
625 | return -EINVAL; | ||
626 | 713 | ||
627 | if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6], | 714 | ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[3], |
628 | ee->ee_ob[ee_mode][obdb], 3, 282, 0, true)) | 715 | AR5K_RF_PWD_136, true); |
629 | return -EINVAL; | ||
630 | } | ||
631 | 716 | ||
632 | ath5k_hw_rfregs_op(rf, ah->ah_offset[6], | 717 | ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[4], |
633 | ee->ee_x_gain[ee_mode], 2, 270, 0, true); | 718 | AR5K_RF_PWD_132, true); |
634 | ath5k_hw_rfregs_op(rf, ah->ah_offset[6], | ||
635 | ee->ee_x_gain[ee_mode], 2, 257, 0, true); | ||
636 | 719 | ||
637 | if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6], | 720 | ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[5], |
638 | ee->ee_xpd[ee_mode], 1, 302, 0, true)) | 721 | AR5K_RF_PWD_131, true); |
639 | return -EINVAL; | ||
640 | 722 | ||
641 | /* Modify bank 7 */ | 723 | ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[6], |
642 | if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[7], | 724 | AR5K_RF_PWD_130, true); |
643 | ee->ee_i_gain[ee_mode], 6, 14, 0, true)) | ||
644 | return -EINVAL; | ||
645 | 725 | ||
646 | /* Write RF values */ | 726 | /* We programmed gain_F parameters, switch back |
647 | for (i = 0; i < rf_size; i++) | 727 | * to active state */ |
648 | ath5k_hw_reg_write(ah, rf[i], rf_ini[i].rfb_ctrl_register); | 728 | ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE; |
729 | } | ||
649 | 730 | ||
731 | /* Bank 6/7 setup */ | ||
650 | 732 | ||
651 | ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE; | 733 | ath5k_hw_rfb_op(ah, rf_regs, ee->ee_xpd[ee_mode], |
734 | AR5K_RF_XPD_SEL, true); | ||
652 | 735 | ||
653 | return 0; | 736 | if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112A) { |
654 | } | 737 | /* Rev. 1 supports only one xpd */ |
738 | ath5k_hw_rfb_op(ah, rf_regs, | ||
739 | ee->ee_x_gain[ee_mode], | ||
740 | AR5K_RF_XPD_GAIN, true); | ||
655 | 741 | ||
656 | /* | 742 | } else { |
657 | * Initialize RF5413/5414 and future chips | 743 | /* TODO: Set high and low gain bits */ |
658 | * (until we come up with a better solution) | 744 | ath5k_hw_rfb_op(ah, rf_regs, |
659 | */ | 745 | ee->ee_x_gain[ee_mode], |
660 | static int ath5k_hw_rf5413_rfregs(struct ath5k_hw *ah, | 746 | AR5K_RF_PD_GAIN_LO, true); |
661 | struct ieee80211_channel *channel, unsigned int mode) | 747 | ath5k_hw_rfb_op(ah, rf_regs, |
662 | { | 748 | ee->ee_x_gain[ee_mode], |
663 | const struct ath5k_ini_rfbuffer *rf_ini; | 749 | AR5K_RF_PD_GAIN_HI, true); |
664 | u32 *rf; | ||
665 | unsigned int rf_size, i; | ||
666 | int bank = -1; | ||
667 | 750 | ||
668 | AR5K_ASSERT_ENTRY(mode, AR5K_MODE_MAX); | 751 | /* Lower synth voltage on Rev 2 */ |
752 | ath5k_hw_rfb_op(ah, rf_regs, 2, | ||
753 | AR5K_RF_HIGH_VC_CP, true); | ||
669 | 754 | ||
670 | rf = ah->ah_rf_banks; | 755 | ath5k_hw_rfb_op(ah, rf_regs, 2, |
756 | AR5K_RF_MID_VC_CP, true); | ||
671 | 757 | ||
672 | switch (ah->ah_radio) { | 758 | ath5k_hw_rfb_op(ah, rf_regs, 2, |
673 | case AR5K_RF5413: | 759 | AR5K_RF_LOW_VC_CP, true); |
674 | rf_ini = rfb_5413; | ||
675 | rf_size = ARRAY_SIZE(rfb_5413); | ||
676 | break; | ||
677 | case AR5K_RF2413: | ||
678 | rf_ini = rfb_2413; | ||
679 | rf_size = ARRAY_SIZE(rfb_2413); | ||
680 | 760 | ||
681 | if (mode < 2) { | 761 | ath5k_hw_rfb_op(ah, rf_regs, 2, |
682 | ATH5K_ERR(ah->ah_sc, | 762 | AR5K_RF_PUSH_UP, true); |
683 | "invalid channel mode: %i\n", mode); | ||
684 | return -EINVAL; | ||
685 | } | ||
686 | 763 | ||
687 | break; | 764 | /* Decrease power consumption on 5213+ BaseBand */ |
688 | case AR5K_RF2425: | 765 | if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) { |
689 | rf_ini = rfb_2425; | 766 | ath5k_hw_rfb_op(ah, rf_regs, 1, |
690 | rf_size = ARRAY_SIZE(rfb_2425); | 767 | AR5K_RF_PAD2GND, true); |
691 | 768 | ||
692 | if (mode < 2) { | 769 | ath5k_hw_rfb_op(ah, rf_regs, 1, |
693 | ATH5K_ERR(ah->ah_sc, | 770 | AR5K_RF_XB2_LVL, true); |
694 | "invalid channel mode: %i\n", mode); | ||
695 | return -EINVAL; | ||
696 | } | ||
697 | 771 | ||
698 | break; | 772 | ath5k_hw_rfb_op(ah, rf_regs, 1, |
699 | default: | 773 | AR5K_RF_XB5_LVL, true); |
700 | return -EINVAL; | ||
701 | } | ||
702 | 774 | ||
703 | /* Copy values to modify them */ | 775 | ath5k_hw_rfb_op(ah, rf_regs, 1, |
704 | for (i = 0; i < rf_size; i++) { | 776 | AR5K_RF_PWD_167, true); |
705 | if (rf_ini[i].rfb_bank >= AR5K_RF5112_INI_RF_MAX_BANKS) { | ||
706 | ATH5K_ERR(ah->ah_sc, "invalid bank\n"); | ||
707 | return -EINVAL; | ||
708 | } | ||
709 | 777 | ||
710 | if (bank != rf_ini[i].rfb_bank) { | 778 | ath5k_hw_rfb_op(ah, rf_regs, 1, |
711 | bank = rf_ini[i].rfb_bank; | 779 | AR5K_RF_PWD_166, true); |
712 | ah->ah_offset[bank] = i; | 780 | } |
713 | } | 781 | } |
714 | 782 | ||
715 | rf[i] = rf_ini[i].rfb_mode_data[mode]; | 783 | ath5k_hw_rfb_op(ah, rf_regs, ee->ee_i_gain[ee_mode], |
716 | } | 784 | AR5K_RF_GAIN_I, true); |
717 | 785 | ||
718 | /* | 786 | /* TODO: Half/quarter channel support */ |
719 | * After compairing dumps from different cards | ||
720 | * we get the same RF_BUFFER settings (diff returns | ||
721 | * 0 lines). It seems that RF_BUFFER settings are static | ||
722 | * and are written unmodified (no EEPROM stuff | ||
723 | * is used because calibration data would be | ||
724 | * different between different cards and would result | ||
725 | * different RF_BUFFER settings) | ||
726 | */ | ||
727 | 787 | ||
728 | /* Write RF values */ | 788 | } |
729 | for (i = 0; i < rf_size; i++) | ||
730 | ath5k_hw_reg_write(ah, rf[i], rf_ini[i].rfb_ctrl_register); | ||
731 | 789 | ||
732 | return 0; | 790 | if (ah->ah_radio == AR5K_RF5413 && |
733 | } | 791 | channel->hw_value & CHANNEL_2GHZ) { |
734 | 792 | ||
735 | /* | 793 | ath5k_hw_rfb_op(ah, rf_regs, 1, AR5K_RF_DERBY_CHAN_SEL_MODE, |
736 | * Initialize RF | 794 | true); |
737 | */ | ||
738 | int ath5k_hw_rfregs(struct ath5k_hw *ah, struct ieee80211_channel *channel, | ||
739 | unsigned int mode) | ||
740 | { | ||
741 | int (*func)(struct ath5k_hw *, struct ieee80211_channel *, unsigned int); | ||
742 | int ret; | ||
743 | 795 | ||
744 | switch (ah->ah_radio) { | 796 | /* Set optimum value for early revisions (on pci-e chips) */ |
745 | case AR5K_RF5111: | 797 | if (ah->ah_mac_srev >= AR5K_SREV_AR5424 && |
746 | ah->ah_rf_banks_size = sizeof(rfb_5111); | 798 | ah->ah_mac_srev < AR5K_SREV_AR5413) |
747 | func = ath5k_hw_rf5111_rfregs; | 799 | ath5k_hw_rfb_op(ah, rf_regs, ath5k_hw_bitswap(6, 3), |
748 | break; | 800 | AR5K_RF_PWD_ICLOBUF_2G, true); |
749 | case AR5K_RF5112: | ||
750 | if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A) | ||
751 | ah->ah_rf_banks_size = sizeof(rfb_5112a); | ||
752 | else | ||
753 | ah->ah_rf_banks_size = sizeof(rfb_5112); | ||
754 | func = ath5k_hw_rf5112_rfregs; | ||
755 | break; | ||
756 | case AR5K_RF5413: | ||
757 | ah->ah_rf_banks_size = sizeof(rfb_5413); | ||
758 | func = ath5k_hw_rf5413_rfregs; | ||
759 | break; | ||
760 | case AR5K_RF2413: | ||
761 | ah->ah_rf_banks_size = sizeof(rfb_2413); | ||
762 | func = ath5k_hw_rf5413_rfregs; | ||
763 | break; | ||
764 | case AR5K_RF2425: | ||
765 | ah->ah_rf_banks_size = sizeof(rfb_2425); | ||
766 | func = ath5k_hw_rf5413_rfregs; | ||
767 | break; | ||
768 | default: | ||
769 | return -EINVAL; | ||
770 | } | ||
771 | 801 | ||
772 | if (ah->ah_rf_banks == NULL) { | ||
773 | /* XXX do extra checks? */ | ||
774 | ah->ah_rf_banks = kmalloc(ah->ah_rf_banks_size, GFP_KERNEL); | ||
775 | if (ah->ah_rf_banks == NULL) { | ||
776 | ATH5K_ERR(ah->ah_sc, "out of memory\n"); | ||
777 | return -ENOMEM; | ||
778 | } | ||
779 | } | 802 | } |
780 | 803 | ||
781 | ret = func(ah, channel, mode); | 804 | /* Write RF banks on hw */ |
805 | for (i = 0; i < ah->ah_rf_banks_size; i++) { | ||
806 | AR5K_REG_WAIT(i); | ||
807 | ath5k_hw_reg_write(ah, rfb[i], ini_rfb[i].rfb_ctrl_register); | ||
808 | } | ||
782 | 809 | ||
783 | return ret; | 810 | return 0; |
784 | } | 811 | } |
785 | 812 | ||
786 | 813 | ||
787 | |||
788 | |||
789 | /**************************\ | 814 | /**************************\ |
790 | PHY/RF channel functions | 815 | PHY/RF channel functions |
791 | \**************************/ | 816 | \**************************/ |
diff --git a/drivers/net/wireless/ath5k/reg.h b/drivers/net/wireless/ath5k/reg.h index 9189ab13286..9aa22ef8410 100644 --- a/drivers/net/wireless/ath5k/reg.h +++ b/drivers/net/wireless/ath5k/reg.h | |||
@@ -2101,34 +2101,10 @@ | |||
2101 | /* | 2101 | /* |
2102 | * RF Buffer register | 2102 | * RF Buffer register |
2103 | * | 2103 | * |
2104 | * There are some special control registers on the RF chip | ||
2105 | * that hold various operation settings related mostly to | ||
2106 | * the analog parts (channel, gain adjustment etc). | ||
2107 | * | ||
2108 | * We don't write on those registers directly but | ||
2109 | * we send a data packet on the buffer register and | ||
2110 | * then write on another special register to notify hw | ||
2111 | * to apply the settings. This is done so that control registers | ||
2112 | * can be dynamicaly programmed during operation and the settings | ||
2113 | * are applied faster on the hw. | ||
2114 | * | ||
2115 | * We sent such data packets during rf initialization and channel change | ||
2116 | * through ath5k_hw_rf*_rfregs and ath5k_hw_rf*_channel functions. | ||
2117 | * | ||
2118 | * The data packets we send during initializadion are inside ath5k_ini_rf | ||
2119 | * struct (see ath5k_hw.h) and each one is related to an "rf register bank". | ||
2120 | * We use *rfregs functions to modify them acording to current operation | ||
2121 | * mode and eeprom values and pass them all together to the chip. | ||
2122 | * | ||
2123 | * It's obvious from the code that 0x989c is the buffer register but | 2104 | * It's obvious from the code that 0x989c is the buffer register but |
2124 | * for the other special registers that we write to after sending each | 2105 | * for the other special registers that we write to after sending each |
2125 | * packet, i have no idea. So i'll name them BUFFER_CONTROL_X registers | 2106 | * packet, i have no idea. So i'll name them BUFFER_CONTROL_X registers |
2126 | * for now. It's interesting that they are also used for some other operations. | 2107 | * for now. It's interesting that they are also used for some other operations. |
2127 | * | ||
2128 | * Also check out hw.h and U.S. Patent 6677779 B1 (about buffer | ||
2129 | * registers and control registers): | ||
2130 | * | ||
2131 | * http://www.google.com/patents?id=qNURAAAAEBAJ | ||
2132 | */ | 2108 | */ |
2133 | 2109 | ||
2134 | #define AR5K_RF_BUFFER 0x989c | 2110 | #define AR5K_RF_BUFFER 0x989c |
diff --git a/drivers/net/wireless/ath5k/reset.c b/drivers/net/wireless/ath5k/reset.c index f7ce80e67dd..40cf4c7b63b 100644 --- a/drivers/net/wireless/ath5k/reset.c +++ b/drivers/net/wireless/ath5k/reset.c | |||
@@ -600,7 +600,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, | |||
600 | /* | 600 | /* |
601 | * Write RF registers | 601 | * Write RF registers |
602 | */ | 602 | */ |
603 | ret = ath5k_hw_rfregs(ah, channel, mode); | 603 | ret = ath5k_hw_rfregs_init(ah, channel, mode); |
604 | if (ret) | 604 | if (ret) |
605 | return ret; | 605 | return ret; |
606 | 606 | ||
diff --git a/drivers/net/wireless/ath5k/rfbuffer.h b/drivers/net/wireless/ath5k/rfbuffer.h index 28b30163c0e..e50baff6617 100644 --- a/drivers/net/wireless/ath5k/rfbuffer.h +++ b/drivers/net/wireless/ath5k/rfbuffer.h | |||
@@ -17,6 +17,33 @@ | |||
17 | * | 17 | * |
18 | */ | 18 | */ |
19 | 19 | ||
20 | |||
21 | /* | ||
22 | * There are some special registers on the RF chip | ||
23 | * that control various operation settings related mostly to | ||
24 | * the analog parts (channel, gain adjustment etc). | ||
25 | * | ||
26 | * We don't write on those registers directly but | ||
27 | * we send a data packet on the chip, using a special register, | ||
28 | * that holds all the settings we need. After we 've sent the | ||
29 | * data packet, we write on another special register to notify hw | ||
30 | * to apply the settings. This is done so that control registers | ||
31 | * can be dynamicaly programmed during operation and the settings | ||
32 | * are applied faster on the hw. | ||
33 | * | ||
34 | * We call each data packet an "RF Bank" and all the data we write | ||
35 | * (all RF Banks) "RF Buffer". This file holds initial RF Buffer | ||
36 | * data for the different RF chips, and various info to match RF | ||
37 | * Buffer offsets with specific RF registers so that we can access | ||
38 | * them. We tweak these settings on rfregs_init function. | ||
39 | * | ||
40 | * Also check out reg.h and U.S. Patent 6677779 B1 (about buffer | ||
41 | * registers and control registers): | ||
42 | * | ||
43 | * http://www.google.com/patents?id=qNURAAAAEBAJ | ||
44 | */ | ||
45 | |||
46 | |||
20 | /* | 47 | /* |
21 | * Struct to hold default mode specific RF | 48 | * Struct to hold default mode specific RF |
22 | * register values (RF Banks) | 49 | * register values (RF Banks) |
@@ -72,15 +99,28 @@ enum ath5k_rf_regs_idx { | |||
72 | AR5K_RF_XB2_LVL, | 99 | AR5K_RF_XB2_LVL, |
73 | AR5K_RF_XB5_LVL, | 100 | AR5K_RF_XB5_LVL, |
74 | AR5K_RF_PWD_ICLOBUF_2G, | 101 | AR5K_RF_PWD_ICLOBUF_2G, |
102 | AR5K_RF_PWD_84, | ||
103 | AR5K_RF_PWD_90, | ||
104 | AR5K_RF_PWD_130, | ||
105 | AR5K_RF_PWD_131, | ||
106 | AR5K_RF_PWD_132, | ||
107 | AR5K_RF_PWD_136, | ||
108 | AR5K_RF_PWD_137, | ||
109 | AR5K_RF_PWD_138, | ||
110 | AR5K_RF_PWD_166, | ||
111 | AR5K_RF_PWD_167, | ||
75 | AR5K_RF_DERBY_CHAN_SEL_MODE, | 112 | AR5K_RF_DERBY_CHAN_SEL_MODE, |
76 | /* BANK 7 */ | 113 | /* BANK 7 */ |
77 | AR5K_RF_GAIN_I, | 114 | AR5K_RF_GAIN_I, |
78 | AR5K_RF_PLO_SEL, | 115 | AR5K_RF_PLO_SEL, |
79 | AR5K_RF_RFGAIN_SEL, | 116 | AR5K_RF_RFGAIN_SEL, |
117 | AR5K_RF_RFGAIN_STEP, | ||
80 | AR5K_RF_WAIT_S, | 118 | AR5K_RF_WAIT_S, |
81 | AR5K_RF_WAIT_I, | 119 | AR5K_RF_WAIT_I, |
82 | AR5K_RF_MAX_TIME, | 120 | AR5K_RF_MAX_TIME, |
121 | AR5K_RF_MIXVGA_OVR, | ||
83 | AR5K_RF_MIXGAIN_OVR, | 122 | AR5K_RF_MIXGAIN_OVR, |
123 | AR5K_RF_MIXGAIN_STEP, | ||
84 | AR5K_RF_PD_DELAY_A, | 124 | AR5K_RF_PD_DELAY_A, |
85 | AR5K_RF_PD_DELAY_B, | 125 | AR5K_RF_PD_DELAY_B, |
86 | AR5K_RF_PD_DELAY_XR, | 126 | AR5K_RF_PD_DELAY_XR, |
@@ -118,19 +158,21 @@ enum ath5k_rf_regs_idx { | |||
118 | #define AR5K_RF5111_MAX_TIME { 2, 49, 0 } | 158 | #define AR5K_RF5111_MAX_TIME { 2, 49, 0 } |
119 | 159 | ||
120 | static const struct ath5k_rf_reg rf_regs_5111[] = { | 160 | static const struct ath5k_rf_reg rf_regs_5111[] = { |
121 | {6, AR5K_RF_OB_2GHZ, AR5K_RF5111_OB_2GHZ}, | 161 | {6, AR5K_RF_OB_2GHZ, AR5K_RF5111_OB_2GHZ}, |
122 | {6, AR5K_RF_DB_2GHZ, AR5K_RF5111_DB_2GHZ}, | 162 | {6, AR5K_RF_DB_2GHZ, AR5K_RF5111_DB_2GHZ}, |
123 | {6, AR5K_RF_OB_5GHZ, AR5K_RF5111_OB_5GHZ}, | 163 | {6, AR5K_RF_OB_5GHZ, AR5K_RF5111_OB_5GHZ}, |
124 | {6, AR5K_RF_DB_5GHZ, AR5K_RF5111_DB_5GHZ}, | 164 | {6, AR5K_RF_DB_5GHZ, AR5K_RF5111_DB_5GHZ}, |
125 | {6, AR5K_RF_PWD_XPD, AR5K_RF5111_PWD_XPD}, | 165 | {6, AR5K_RF_PWD_XPD, AR5K_RF5111_PWD_XPD}, |
126 | {6, AR5K_RF_XPD_GAIN, AR5K_RF5111_XPD_GAIN}, | 166 | {6, AR5K_RF_XPD_GAIN, AR5K_RF5111_XPD_GAIN}, |
127 | {7, AR5K_RF_GAIN_I, AR5K_RF5111_GAIN_I}, | 167 | {6, AR5K_RF_PWD_84, AR5K_RF5111_PWD(84)}, |
128 | {7, AR5K_RF_PLO_SEL, AR5K_RF5111_PLO_SEL}, | 168 | {6, AR5K_RF_PWD_90, AR5K_RF5111_PWD(90)}, |
129 | {7, AR5K_RF_RFGAIN_SEL, AR5K_RF5111_RFGAIN_SEL}, | 169 | {7, AR5K_RF_GAIN_I, AR5K_RF5111_GAIN_I}, |
130 | {7, AR5K_RF_WAIT_S, AR5K_RF5111_WAIT_S}, | 170 | {7, AR5K_RF_PLO_SEL, AR5K_RF5111_PLO_SEL}, |
131 | {7, AR5K_RF_WAIT_I, AR5K_RF5111_WAIT_I}, | 171 | {7, AR5K_RF_RFGAIN_SEL, AR5K_RF5111_RFGAIN_SEL}, |
132 | {7, AR5K_RF_MAX_TIME, AR5K_RF5111_MAX_TIME} | 172 | {7, AR5K_RF_RFGAIN_STEP, AR5K_RF5111_RFGAIN_STEP}, |
133 | 173 | {7, AR5K_RF_WAIT_S, AR5K_RF5111_WAIT_S}, | |
174 | {7, AR5K_RF_WAIT_I, AR5K_RF5111_WAIT_I}, | ||
175 | {7, AR5K_RF_MAX_TIME, AR5K_RF5111_MAX_TIME} | ||
134 | }; | 176 | }; |
135 | 177 | ||
136 | /* Default mode specific settings */ | 178 | /* Default mode specific settings */ |
@@ -273,8 +315,16 @@ static const struct ath5k_rf_reg rf_regs_5112[] = { | |||
273 | {6, AR5K_RF_FIXED_BIAS_B, AR5K_RF5112_FIXED_BIAS_B}, | 315 | {6, AR5K_RF_FIXED_BIAS_B, AR5K_RF5112_FIXED_BIAS_B}, |
274 | {6, AR5K_RF_XPD_SEL, AR5K_RF5112_XPD_SEL}, | 316 | {6, AR5K_RF_XPD_SEL, AR5K_RF5112_XPD_SEL}, |
275 | {6, AR5K_RF_XPD_GAIN, AR5K_RF5112_XPD_GAIN}, | 317 | {6, AR5K_RF_XPD_GAIN, AR5K_RF5112_XPD_GAIN}, |
318 | {6, AR5K_RF_PWD_130, AR5K_RF5112_PWD(130)}, | ||
319 | {6, AR5K_RF_PWD_131, AR5K_RF5112_PWD(131)}, | ||
320 | {6, AR5K_RF_PWD_132, AR5K_RF5112_PWD(132)}, | ||
321 | {6, AR5K_RF_PWD_136, AR5K_RF5112_PWD(136)}, | ||
322 | {6, AR5K_RF_PWD_137, AR5K_RF5112_PWD(137)}, | ||
323 | {6, AR5K_RF_PWD_138, AR5K_RF5112_PWD(138)}, | ||
276 | {7, AR5K_RF_GAIN_I, AR5K_RF5112X_GAIN_I}, | 324 | {7, AR5K_RF_GAIN_I, AR5K_RF5112X_GAIN_I}, |
325 | {7, AR5K_RF_MIXVGA_OVR, AR5K_RF5112X_MIXVGA_OVR}, | ||
277 | {7, AR5K_RF_MIXGAIN_OVR, AR5K_RF5112X_MIXGAIN_OVR}, | 326 | {7, AR5K_RF_MIXGAIN_OVR, AR5K_RF5112X_MIXGAIN_OVR}, |
327 | {7, AR5K_RF_MIXGAIN_STEP, AR5K_RF5112X_MIXGAIN_STEP}, | ||
278 | {7, AR5K_RF_PD_DELAY_A, AR5K_RF5112X_PD_DELAY_A}, | 328 | {7, AR5K_RF_PD_DELAY_A, AR5K_RF5112X_PD_DELAY_A}, |
279 | {7, AR5K_RF_PD_DELAY_B, AR5K_RF5112X_PD_DELAY_B}, | 329 | {7, AR5K_RF_PD_DELAY_B, AR5K_RF5112X_PD_DELAY_B}, |
280 | {7, AR5K_RF_PD_DELAY_XR, AR5K_RF5112X_PD_DELAY_XR}, | 330 | {7, AR5K_RF_PD_DELAY_XR, AR5K_RF5112X_PD_DELAY_XR}, |
@@ -419,7 +469,7 @@ static const struct ath5k_ini_rfbuffer rfb_5112[] = { | |||
419 | #define AR5K_RF5112A_HIGH_VC_CP { 2, 90, 2 } | 469 | #define AR5K_RF5112A_HIGH_VC_CP { 2, 90, 2 } |
420 | #define AR5K_RF5112A_MID_VC_CP { 2, 92, 2 } | 470 | #define AR5K_RF5112A_MID_VC_CP { 2, 92, 2 } |
421 | #define AR5K_RF5112A_LOW_VC_CP { 2, 94, 2 } | 471 | #define AR5K_RF5112A_LOW_VC_CP { 2, 94, 2 } |
422 | #define AR5K_RF5112A_PUSH_UP { 2, 94, 2 } | 472 | #define AR5K_RF5112A_PUSH_UP { 1, 254, 2 } |
423 | 473 | ||
424 | /* Power consumption */ | 474 | /* Power consumption */ |
425 | #define AR5K_RF5112A_PAD2GND { 1, 281, 1 } | 475 | #define AR5K_RF5112A_PAD2GND { 1, 281, 1 } |
@@ -436,6 +486,14 @@ static const struct ath5k_rf_reg rf_regs_5112a[] = { | |||
436 | {6, AR5K_RF_XPD_SEL, AR5K_RF5112A_XPD_SEL}, | 486 | {6, AR5K_RF_XPD_SEL, AR5K_RF5112A_XPD_SEL}, |
437 | {6, AR5K_RF_PD_GAIN_LO, AR5K_RF5112A_PDGAINLO}, | 487 | {6, AR5K_RF_PD_GAIN_LO, AR5K_RF5112A_PDGAINLO}, |
438 | {6, AR5K_RF_PD_GAIN_HI, AR5K_RF5112A_PDGAINHI}, | 488 | {6, AR5K_RF_PD_GAIN_HI, AR5K_RF5112A_PDGAINHI}, |
489 | {6, AR5K_RF_PWD_130, AR5K_RF5112A_PWD(130)}, | ||
490 | {6, AR5K_RF_PWD_131, AR5K_RF5112A_PWD(131)}, | ||
491 | {6, AR5K_RF_PWD_132, AR5K_RF5112A_PWD(132)}, | ||
492 | {6, AR5K_RF_PWD_136, AR5K_RF5112A_PWD(136)}, | ||
493 | {6, AR5K_RF_PWD_137, AR5K_RF5112A_PWD(137)}, | ||
494 | {6, AR5K_RF_PWD_138, AR5K_RF5112A_PWD(138)}, | ||
495 | {6, AR5K_RF_PWD_166, AR5K_RF5112A_PWD(166)}, | ||
496 | {6, AR5K_RF_PWD_167, AR5K_RF5112A_PWD(167)}, | ||
439 | {6, AR5K_RF_HIGH_VC_CP, AR5K_RF5112A_HIGH_VC_CP}, | 497 | {6, AR5K_RF_HIGH_VC_CP, AR5K_RF5112A_HIGH_VC_CP}, |
440 | {6, AR5K_RF_MID_VC_CP, AR5K_RF5112A_MID_VC_CP}, | 498 | {6, AR5K_RF_MID_VC_CP, AR5K_RF5112A_MID_VC_CP}, |
441 | {6, AR5K_RF_LOW_VC_CP, AR5K_RF5112A_LOW_VC_CP}, | 499 | {6, AR5K_RF_LOW_VC_CP, AR5K_RF5112A_LOW_VC_CP}, |
@@ -444,7 +502,9 @@ static const struct ath5k_rf_reg rf_regs_5112a[] = { | |||
444 | {6, AR5K_RF_XB2_LVL, AR5K_RF5112A_XB2_LVL}, | 502 | {6, AR5K_RF_XB2_LVL, AR5K_RF5112A_XB2_LVL}, |
445 | {6, AR5K_RF_XB5_LVL, AR5K_RF5112A_XB5_LVL}, | 503 | {6, AR5K_RF_XB5_LVL, AR5K_RF5112A_XB5_LVL}, |
446 | {7, AR5K_RF_GAIN_I, AR5K_RF5112X_GAIN_I}, | 504 | {7, AR5K_RF_GAIN_I, AR5K_RF5112X_GAIN_I}, |
505 | {7, AR5K_RF_MIXVGA_OVR, AR5K_RF5112X_MIXVGA_OVR}, | ||
447 | {7, AR5K_RF_MIXGAIN_OVR, AR5K_RF5112X_MIXGAIN_OVR}, | 506 | {7, AR5K_RF_MIXGAIN_OVR, AR5K_RF5112X_MIXGAIN_OVR}, |
507 | {7, AR5K_RF_MIXGAIN_STEP, AR5K_RF5112X_MIXGAIN_STEP}, | ||
448 | {7, AR5K_RF_PD_DELAY_A, AR5K_RF5112X_PD_DELAY_A}, | 508 | {7, AR5K_RF_PD_DELAY_A, AR5K_RF5112X_PD_DELAY_A}, |
449 | {7, AR5K_RF_PD_DELAY_B, AR5K_RF5112X_PD_DELAY_B}, | 509 | {7, AR5K_RF_PD_DELAY_B, AR5K_RF5112X_PD_DELAY_B}, |
450 | {7, AR5K_RF_PD_DELAY_XR, AR5K_RF5112X_PD_DELAY_XR}, | 510 | {7, AR5K_RF_PD_DELAY_XR, AR5K_RF5112X_PD_DELAY_XR}, |