diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath5k/phy.c')
-rw-r--r-- | drivers/net/wireless/ath/ath5k/phy.c | 676 |
1 files changed, 513 insertions, 163 deletions
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index 219367884e64..f84afb420bd8 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c | |||
@@ -29,6 +29,95 @@ | |||
29 | #include "rfbuffer.h" | 29 | #include "rfbuffer.h" |
30 | #include "rfgain.h" | 30 | #include "rfgain.h" |
31 | 31 | ||
32 | |||
33 | /******************\ | ||
34 | * Helper functions * | ||
35 | \******************/ | ||
36 | |||
37 | /* | ||
38 | * Get the PHY Chip revision | ||
39 | */ | ||
40 | u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan) | ||
41 | { | ||
42 | unsigned int i; | ||
43 | u32 srev; | ||
44 | u16 ret; | ||
45 | |||
46 | /* | ||
47 | * Set the radio chip access register | ||
48 | */ | ||
49 | switch (chan) { | ||
50 | case CHANNEL_2GHZ: | ||
51 | ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_2GHZ, AR5K_PHY(0)); | ||
52 | break; | ||
53 | case CHANNEL_5GHZ: | ||
54 | ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0)); | ||
55 | break; | ||
56 | default: | ||
57 | return 0; | ||
58 | } | ||
59 | |||
60 | mdelay(2); | ||
61 | |||
62 | /* ...wait until PHY is ready and read the selected radio revision */ | ||
63 | ath5k_hw_reg_write(ah, 0x00001c16, AR5K_PHY(0x34)); | ||
64 | |||
65 | for (i = 0; i < 8; i++) | ||
66 | ath5k_hw_reg_write(ah, 0x00010000, AR5K_PHY(0x20)); | ||
67 | |||
68 | if (ah->ah_version == AR5K_AR5210) { | ||
69 | srev = ath5k_hw_reg_read(ah, AR5K_PHY(256) >> 28) & 0xf; | ||
70 | ret = (u16)ath5k_hw_bitswap(srev, 4) + 1; | ||
71 | } else { | ||
72 | srev = (ath5k_hw_reg_read(ah, AR5K_PHY(0x100)) >> 24) & 0xff; | ||
73 | ret = (u16)ath5k_hw_bitswap(((srev & 0xf0) >> 4) | | ||
74 | ((srev & 0x0f) << 4), 8); | ||
75 | } | ||
76 | |||
77 | /* Reset to the 5GHz mode */ | ||
78 | ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0)); | ||
79 | |||
80 | return ret; | ||
81 | } | ||
82 | |||
83 | /* | ||
84 | * Check if a channel is supported | ||
85 | */ | ||
86 | bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags) | ||
87 | { | ||
88 | /* Check if the channel is in our supported range */ | ||
89 | if (flags & CHANNEL_2GHZ) { | ||
90 | if ((freq >= ah->ah_capabilities.cap_range.range_2ghz_min) && | ||
91 | (freq <= ah->ah_capabilities.cap_range.range_2ghz_max)) | ||
92 | return true; | ||
93 | } else if (flags & CHANNEL_5GHZ) | ||
94 | if ((freq >= ah->ah_capabilities.cap_range.range_5ghz_min) && | ||
95 | (freq <= ah->ah_capabilities.cap_range.range_5ghz_max)) | ||
96 | return true; | ||
97 | |||
98 | return false; | ||
99 | } | ||
100 | |||
101 | bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah, | ||
102 | struct ieee80211_channel *channel) | ||
103 | { | ||
104 | u8 refclk_freq; | ||
105 | |||
106 | if ((ah->ah_radio == AR5K_RF5112) || | ||
107 | (ah->ah_radio == AR5K_RF5413) || | ||
108 | (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) | ||
109 | refclk_freq = 40; | ||
110 | else | ||
111 | refclk_freq = 32; | ||
112 | |||
113 | if ((channel->center_freq % refclk_freq != 0) && | ||
114 | ((channel->center_freq % refclk_freq < 10) || | ||
115 | (channel->center_freq % refclk_freq > 22))) | ||
116 | return true; | ||
117 | else | ||
118 | return false; | ||
119 | } | ||
120 | |||
32 | /* | 121 | /* |
33 | * Used to modify RF Banks before writing them to AR5K_RF_BUFFER | 122 | * Used to modify RF Banks before writing them to AR5K_RF_BUFFER |
34 | */ | 123 | */ |
@@ -110,6 +199,90 @@ static unsigned int ath5k_hw_rfb_op(struct ath5k_hw *ah, | |||
110 | return data; | 199 | return data; |
111 | } | 200 | } |
112 | 201 | ||
202 | /** | ||
203 | * ath5k_hw_write_ofdm_timings - set OFDM timings on AR5212 | ||
204 | * | ||
205 | * @ah: the &struct ath5k_hw | ||
206 | * @channel: the currently set channel upon reset | ||
207 | * | ||
208 | * Write the delta slope coefficient (used on pilot tracking ?) for OFDM | ||
209 | * operation on the AR5212 upon reset. This is a helper for ath5k_hw_phy_init. | ||
210 | * | ||
211 | * Since delta slope is floating point we split it on its exponent and | ||
212 | * mantissa and provide these values on hw. | ||
213 | * | ||
214 | * For more infos i think this patent is related | ||
215 | * http://www.freepatentsonline.com/7184495.html | ||
216 | */ | ||
217 | static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah, | ||
218 | struct ieee80211_channel *channel) | ||
219 | { | ||
220 | /* Get exponent and mantissa and set it */ | ||
221 | u32 coef_scaled, coef_exp, coef_man, | ||
222 | ds_coef_exp, ds_coef_man, clock; | ||
223 | |||
224 | BUG_ON(!(ah->ah_version == AR5K_AR5212) || | ||
225 | !(channel->hw_value & CHANNEL_OFDM)); | ||
226 | |||
227 | /* Get coefficient | ||
228 | * ALGO: coef = (5 * clock / carrier_freq) / 2 | ||
229 | * we scale coef by shifting clock value by 24 for | ||
230 | * better precision since we use integers */ | ||
231 | switch (ah->ah_bwmode) { | ||
232 | case AR5K_BWMODE_40MHZ: | ||
233 | clock = 40 * 2; | ||
234 | break; | ||
235 | case AR5K_BWMODE_10MHZ: | ||
236 | clock = 40 / 2; | ||
237 | break; | ||
238 | case AR5K_BWMODE_5MHZ: | ||
239 | clock = 40 / 4; | ||
240 | break; | ||
241 | default: | ||
242 | clock = 40; | ||
243 | break; | ||
244 | } | ||
245 | coef_scaled = ((5 * (clock << 24)) / 2) / channel->center_freq; | ||
246 | |||
247 | /* Get exponent | ||
248 | * ALGO: coef_exp = 14 - highest set bit position */ | ||
249 | coef_exp = ilog2(coef_scaled); | ||
250 | |||
251 | /* Doesn't make sense if it's zero*/ | ||
252 | if (!coef_scaled || !coef_exp) | ||
253 | return -EINVAL; | ||
254 | |||
255 | /* Note: we've shifted coef_scaled by 24 */ | ||
256 | coef_exp = 14 - (coef_exp - 24); | ||
257 | |||
258 | |||
259 | /* Get mantissa (significant digits) | ||
260 | * ALGO: coef_mant = floor(coef_scaled* 2^coef_exp+0.5) */ | ||
261 | coef_man = coef_scaled + | ||
262 | (1 << (24 - coef_exp - 1)); | ||
263 | |||
264 | /* Calculate delta slope coefficient exponent | ||
265 | * and mantissa (remove scaling) and set them on hw */ | ||
266 | ds_coef_man = coef_man >> (24 - coef_exp); | ||
267 | ds_coef_exp = coef_exp - 16; | ||
268 | |||
269 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3, | ||
270 | AR5K_PHY_TIMING_3_DSC_MAN, ds_coef_man); | ||
271 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3, | ||
272 | AR5K_PHY_TIMING_3_DSC_EXP, ds_coef_exp); | ||
273 | |||
274 | return 0; | ||
275 | } | ||
276 | |||
277 | int ath5k_hw_phy_disable(struct ath5k_hw *ah) | ||
278 | { | ||
279 | /*Just a try M.F.*/ | ||
280 | ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT); | ||
281 | |||
282 | return 0; | ||
283 | } | ||
284 | |||
285 | |||
113 | /**********************\ | 286 | /**********************\ |
114 | * RF Gain optimization * | 287 | * RF Gain optimization * |
115 | \**********************/ | 288 | \**********************/ |
@@ -436,7 +609,7 @@ done: | |||
436 | /* Write initial RF gain table to set the RF sensitivity | 609 | /* Write initial RF gain table to set the RF sensitivity |
437 | * this one works on all RF chips and has nothing to do | 610 | * this one works on all RF chips and has nothing to do |
438 | * with gain_F calibration */ | 611 | * with gain_F calibration */ |
439 | int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq) | 612 | static int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq) |
440 | { | 613 | { |
441 | const struct ath5k_ini_rfgain *ath5k_rfg; | 614 | const struct ath5k_ini_rfgain *ath5k_rfg; |
442 | unsigned int i, size; | 615 | unsigned int i, size; |
@@ -494,12 +667,11 @@ int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq) | |||
494 | * RF Registers setup * | 667 | * RF Registers setup * |
495 | \********************/ | 668 | \********************/ |
496 | 669 | ||
497 | |||
498 | /* | 670 | /* |
499 | * Setup RF registers by writing RF buffer on hw | 671 | * Setup RF registers by writing RF buffer on hw |
500 | */ | 672 | */ |
501 | int ath5k_hw_rfregs_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, | 673 | static int ath5k_hw_rfregs_init(struct ath5k_hw *ah, |
502 | unsigned int mode) | 674 | struct ieee80211_channel *channel, unsigned int mode) |
503 | { | 675 | { |
504 | const struct ath5k_rf_reg *rf_regs; | 676 | const struct ath5k_rf_reg *rf_regs; |
505 | const struct ath5k_ini_rfbuffer *ini_rfb; | 677 | const struct ath5k_ini_rfbuffer *ini_rfb; |
@@ -652,6 +824,11 @@ int ath5k_hw_rfregs_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, | |||
652 | 824 | ||
653 | g_step = &go->go_step[ah->ah_gain.g_step_idx]; | 825 | g_step = &go->go_step[ah->ah_gain.g_step_idx]; |
654 | 826 | ||
827 | /* Set turbo mode (N/A on RF5413) */ | ||
828 | if ((ah->ah_bwmode == AR5K_BWMODE_40MHZ) && | ||
829 | (ah->ah_radio != AR5K_RF5413)) | ||
830 | ath5k_hw_rfb_op(ah, rf_regs, 1, AR5K_RF_TURBO, false); | ||
831 | |||
655 | /* Bank Modifications (chip-specific) */ | 832 | /* Bank Modifications (chip-specific) */ |
656 | if (ah->ah_radio == AR5K_RF5111) { | 833 | if (ah->ah_radio == AR5K_RF5111) { |
657 | 834 | ||
@@ -691,7 +868,23 @@ int ath5k_hw_rfregs_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, | |||
691 | ath5k_hw_rfb_op(ah, rf_regs, ee->ee_xpd[ee_mode], | 868 | ath5k_hw_rfb_op(ah, rf_regs, ee->ee_xpd[ee_mode], |
692 | AR5K_RF_PLO_SEL, true); | 869 | AR5K_RF_PLO_SEL, true); |
693 | 870 | ||
694 | /* TODO: Half/quarter channel support */ | 871 | /* Tweak power detectors for half/quarter rate support */ |
872 | if (ah->ah_bwmode == AR5K_BWMODE_5MHZ || | ||
873 | ah->ah_bwmode == AR5K_BWMODE_10MHZ) { | ||
874 | u8 wait_i; | ||
875 | |||
876 | ath5k_hw_rfb_op(ah, rf_regs, 0x1f, | ||
877 | AR5K_RF_WAIT_S, true); | ||
878 | |||
879 | wait_i = (ah->ah_bwmode == AR5K_BWMODE_5MHZ) ? | ||
880 | 0x1f : 0x10; | ||
881 | |||
882 | ath5k_hw_rfb_op(ah, rf_regs, wait_i, | ||
883 | AR5K_RF_WAIT_I, true); | ||
884 | ath5k_hw_rfb_op(ah, rf_regs, 3, | ||
885 | AR5K_RF_MAX_TIME, true); | ||
886 | |||
887 | } | ||
695 | } | 888 | } |
696 | 889 | ||
697 | if (ah->ah_radio == AR5K_RF5112) { | 890 | if (ah->ah_radio == AR5K_RF5112) { |
@@ -789,8 +982,20 @@ int ath5k_hw_rfregs_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, | |||
789 | ath5k_hw_rfb_op(ah, rf_regs, ee->ee_i_gain[ee_mode], | 982 | ath5k_hw_rfb_op(ah, rf_regs, ee->ee_i_gain[ee_mode], |
790 | AR5K_RF_GAIN_I, true); | 983 | AR5K_RF_GAIN_I, true); |
791 | 984 | ||
792 | /* TODO: Half/quarter channel support */ | 985 | /* Tweak power detector for half/quarter rates */ |
986 | if (ah->ah_bwmode == AR5K_BWMODE_5MHZ || | ||
987 | ah->ah_bwmode == AR5K_BWMODE_10MHZ) { | ||
988 | u8 pd_delay; | ||
989 | |||
990 | pd_delay = (ah->ah_bwmode == AR5K_BWMODE_5MHZ) ? | ||
991 | 0xf : 0x8; | ||
992 | |||
993 | ath5k_hw_rfb_op(ah, rf_regs, pd_delay, | ||
994 | AR5K_RF_PD_PERIOD_A, true); | ||
995 | ath5k_hw_rfb_op(ah, rf_regs, 0xf, | ||
996 | AR5K_RF_PD_DELAY_A, true); | ||
793 | 997 | ||
998 | } | ||
794 | } | 999 | } |
795 | 1000 | ||
796 | if (ah->ah_radio == AR5K_RF5413 && | 1001 | if (ah->ah_radio == AR5K_RF5413 && |
@@ -822,24 +1027,6 @@ int ath5k_hw_rfregs_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, | |||
822 | \**************************/ | 1027 | \**************************/ |
823 | 1028 | ||
824 | /* | 1029 | /* |
825 | * Check if a channel is supported | ||
826 | */ | ||
827 | bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags) | ||
828 | { | ||
829 | /* Check if the channel is in our supported range */ | ||
830 | if (flags & CHANNEL_2GHZ) { | ||
831 | if ((freq >= ah->ah_capabilities.cap_range.range_2ghz_min) && | ||
832 | (freq <= ah->ah_capabilities.cap_range.range_2ghz_max)) | ||
833 | return true; | ||
834 | } else if (flags & CHANNEL_5GHZ) | ||
835 | if ((freq >= ah->ah_capabilities.cap_range.range_5ghz_min) && | ||
836 | (freq <= ah->ah_capabilities.cap_range.range_5ghz_max)) | ||
837 | return true; | ||
838 | |||
839 | return false; | ||
840 | } | ||
841 | |||
842 | /* | ||
843 | * Convertion needed for RF5110 | 1030 | * Convertion needed for RF5110 |
844 | */ | 1031 | */ |
845 | static u32 ath5k_hw_rf5110_chan2athchan(struct ieee80211_channel *channel) | 1032 | static u32 ath5k_hw_rf5110_chan2athchan(struct ieee80211_channel *channel) |
@@ -1045,7 +1232,8 @@ static int ath5k_hw_rf2425_channel(struct ath5k_hw *ah, | |||
1045 | /* | 1232 | /* |
1046 | * Set a channel on the radio chip | 1233 | * Set a channel on the radio chip |
1047 | */ | 1234 | */ |
1048 | int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel) | 1235 | static int ath5k_hw_channel(struct ath5k_hw *ah, |
1236 | struct ieee80211_channel *channel) | ||
1049 | { | 1237 | { |
1050 | int ret; | 1238 | int ret; |
1051 | /* | 1239 | /* |
@@ -1092,8 +1280,6 @@ int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel) | |||
1092 | } | 1280 | } |
1093 | 1281 | ||
1094 | ah->ah_current_channel = channel; | 1282 | ah->ah_current_channel = channel; |
1095 | ah->ah_turbo = channel->hw_value == CHANNEL_T ? true : false; | ||
1096 | ath5k_hw_set_clockrate(ah); | ||
1097 | 1283 | ||
1098 | return 0; | 1284 | return 0; |
1099 | } | 1285 | } |
@@ -1102,18 +1288,12 @@ int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel) | |||
1102 | PHY calibration | 1288 | PHY calibration |
1103 | \*****************/ | 1289 | \*****************/ |
1104 | 1290 | ||
1105 | static int sign_extend(int val, const int nbits) | ||
1106 | { | ||
1107 | int order = BIT(nbits-1); | ||
1108 | return (val ^ order) - order; | ||
1109 | } | ||
1110 | |||
1111 | static s32 ath5k_hw_read_measured_noise_floor(struct ath5k_hw *ah) | 1291 | static s32 ath5k_hw_read_measured_noise_floor(struct ath5k_hw *ah) |
1112 | { | 1292 | { |
1113 | s32 val; | 1293 | s32 val; |
1114 | 1294 | ||
1115 | val = ath5k_hw_reg_read(ah, AR5K_PHY_NF); | 1295 | val = ath5k_hw_reg_read(ah, AR5K_PHY_NF); |
1116 | return sign_extend(AR5K_REG_MS(val, AR5K_PHY_NF_MINCCA_PWR), 9); | 1296 | return sign_extend32(AR5K_REG_MS(val, AR5K_PHY_NF_MINCCA_PWR), 8); |
1117 | } | 1297 | } |
1118 | 1298 | ||
1119 | void ath5k_hw_init_nfcal_hist(struct ath5k_hw *ah) | 1299 | void ath5k_hw_init_nfcal_hist(struct ath5k_hw *ah) |
@@ -1183,12 +1363,10 @@ void ath5k_hw_update_noise_floor(struct ath5k_hw *ah) | |||
1183 | 1363 | ||
1184 | switch (ah->ah_current_channel->hw_value & CHANNEL_MODES) { | 1364 | switch (ah->ah_current_channel->hw_value & CHANNEL_MODES) { |
1185 | case CHANNEL_A: | 1365 | case CHANNEL_A: |
1186 | case CHANNEL_T: | ||
1187 | case CHANNEL_XR: | 1366 | case CHANNEL_XR: |
1188 | ee_mode = AR5K_EEPROM_MODE_11A; | 1367 | ee_mode = AR5K_EEPROM_MODE_11A; |
1189 | break; | 1368 | break; |
1190 | case CHANNEL_G: | 1369 | case CHANNEL_G: |
1191 | case CHANNEL_TG: | ||
1192 | ee_mode = AR5K_EEPROM_MODE_11G; | 1370 | ee_mode = AR5K_EEPROM_MODE_11G; |
1193 | break; | 1371 | break; |
1194 | default: | 1372 | default: |
@@ -1425,31 +1603,12 @@ int ath5k_hw_phy_calibrate(struct ath5k_hw *ah, | |||
1425 | return ret; | 1603 | return ret; |
1426 | } | 1604 | } |
1427 | 1605 | ||
1606 | |||
1428 | /***************************\ | 1607 | /***************************\ |
1429 | * Spur mitigation functions * | 1608 | * Spur mitigation functions * |
1430 | \***************************/ | 1609 | \***************************/ |
1431 | 1610 | ||
1432 | bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah, | 1611 | static void |
1433 | struct ieee80211_channel *channel) | ||
1434 | { | ||
1435 | u8 refclk_freq; | ||
1436 | |||
1437 | if ((ah->ah_radio == AR5K_RF5112) || | ||
1438 | (ah->ah_radio == AR5K_RF5413) || | ||
1439 | (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) | ||
1440 | refclk_freq = 40; | ||
1441 | else | ||
1442 | refclk_freq = 32; | ||
1443 | |||
1444 | if ((channel->center_freq % refclk_freq != 0) && | ||
1445 | ((channel->center_freq % refclk_freq < 10) || | ||
1446 | (channel->center_freq % refclk_freq > 22))) | ||
1447 | return true; | ||
1448 | else | ||
1449 | return false; | ||
1450 | } | ||
1451 | |||
1452 | void | ||
1453 | ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah, | 1612 | ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah, |
1454 | struct ieee80211_channel *channel) | 1613 | struct ieee80211_channel *channel) |
1455 | { | 1614 | { |
@@ -1478,7 +1637,7 @@ ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah, | |||
1478 | spur_chan_fbin = AR5K_EEPROM_NO_SPUR; | 1637 | spur_chan_fbin = AR5K_EEPROM_NO_SPUR; |
1479 | spur_detection_window = AR5K_SPUR_CHAN_WIDTH; | 1638 | spur_detection_window = AR5K_SPUR_CHAN_WIDTH; |
1480 | /* XXX: Half/Quarter channels ?*/ | 1639 | /* XXX: Half/Quarter channels ?*/ |
1481 | if (channel->hw_value & CHANNEL_TURBO) | 1640 | if (ah->ah_bwmode == AR5K_BWMODE_40MHZ) |
1482 | spur_detection_window *= 2; | 1641 | spur_detection_window *= 2; |
1483 | 1642 | ||
1484 | for (i = 0; i < AR5K_EEPROM_N_SPUR_CHANS; i++) { | 1643 | for (i = 0; i < AR5K_EEPROM_N_SPUR_CHANS; i++) { |
@@ -1507,32 +1666,43 @@ ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah, | |||
1507 | * Calculate deltas: | 1666 | * Calculate deltas: |
1508 | * spur_freq_sigma_delta -> spur_offset / sample_freq << 21 | 1667 | * spur_freq_sigma_delta -> spur_offset / sample_freq << 21 |
1509 | * spur_delta_phase -> spur_offset / chip_freq << 11 | 1668 | * spur_delta_phase -> spur_offset / chip_freq << 11 |
1510 | * Note: Both values have 100KHz resolution | 1669 | * Note: Both values have 100Hz resolution |
1511 | */ | 1670 | */ |
1512 | /* XXX: Half/Quarter rate channels ? */ | 1671 | switch (ah->ah_bwmode) { |
1513 | switch (channel->hw_value) { | 1672 | case AR5K_BWMODE_40MHZ: |
1514 | case CHANNEL_A: | ||
1515 | /* Both sample_freq and chip_freq are 40MHz */ | ||
1516 | spur_delta_phase = (spur_offset << 17) / 25; | ||
1517 | spur_freq_sigma_delta = (spur_delta_phase >> 10); | ||
1518 | symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz; | ||
1519 | break; | ||
1520 | case CHANNEL_G: | ||
1521 | /* sample_freq -> 40MHz chip_freq -> 44MHz | ||
1522 | * (for b compatibility) */ | ||
1523 | spur_freq_sigma_delta = (spur_offset << 8) / 55; | ||
1524 | spur_delta_phase = (spur_offset << 17) / 25; | ||
1525 | symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz; | ||
1526 | break; | ||
1527 | case CHANNEL_T: | ||
1528 | case CHANNEL_TG: | ||
1529 | /* Both sample_freq and chip_freq are 80MHz */ | 1673 | /* Both sample_freq and chip_freq are 80MHz */ |
1530 | spur_delta_phase = (spur_offset << 16) / 25; | 1674 | spur_delta_phase = (spur_offset << 16) / 25; |
1531 | spur_freq_sigma_delta = (spur_delta_phase >> 10); | 1675 | spur_freq_sigma_delta = (spur_delta_phase >> 10); |
1532 | symbol_width = AR5K_SPUR_SYMBOL_WIDTH_TURBO_100Hz; | 1676 | symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz * 2; |
1533 | break; | 1677 | break; |
1678 | case AR5K_BWMODE_10MHZ: | ||
1679 | /* Both sample_freq and chip_freq are 20MHz (?) */ | ||
1680 | spur_delta_phase = (spur_offset << 18) / 25; | ||
1681 | spur_freq_sigma_delta = (spur_delta_phase >> 10); | ||
1682 | symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz / 2; | ||
1683 | case AR5K_BWMODE_5MHZ: | ||
1684 | /* Both sample_freq and chip_freq are 10MHz (?) */ | ||
1685 | spur_delta_phase = (spur_offset << 19) / 25; | ||
1686 | spur_freq_sigma_delta = (spur_delta_phase >> 10); | ||
1687 | symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz / 4; | ||
1534 | default: | 1688 | default: |
1535 | return; | 1689 | if (channel->hw_value == CHANNEL_A) { |
1690 | /* Both sample_freq and chip_freq are 40MHz */ | ||
1691 | spur_delta_phase = (spur_offset << 17) / 25; | ||
1692 | spur_freq_sigma_delta = | ||
1693 | (spur_delta_phase >> 10); | ||
1694 | symbol_width = | ||
1695 | AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz; | ||
1696 | } else { | ||
1697 | /* sample_freq -> 40MHz chip_freq -> 44MHz | ||
1698 | * (for b compatibility) */ | ||
1699 | spur_delta_phase = (spur_offset << 17) / 25; | ||
1700 | spur_freq_sigma_delta = | ||
1701 | (spur_offset << 8) / 55; | ||
1702 | symbol_width = | ||
1703 | AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz; | ||
1704 | } | ||
1705 | break; | ||
1536 | } | 1706 | } |
1537 | 1707 | ||
1538 | /* Calculate pilot and magnitude masks */ | 1708 | /* Calculate pilot and magnitude masks */ |
@@ -1672,63 +1842,6 @@ ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah, | |||
1672 | } | 1842 | } |
1673 | } | 1843 | } |
1674 | 1844 | ||
1675 | /********************\ | ||
1676 | Misc PHY functions | ||
1677 | \********************/ | ||
1678 | |||
1679 | int ath5k_hw_phy_disable(struct ath5k_hw *ah) | ||
1680 | { | ||
1681 | /*Just a try M.F.*/ | ||
1682 | ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT); | ||
1683 | |||
1684 | return 0; | ||
1685 | } | ||
1686 | |||
1687 | /* | ||
1688 | * Get the PHY Chip revision | ||
1689 | */ | ||
1690 | u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan) | ||
1691 | { | ||
1692 | unsigned int i; | ||
1693 | u32 srev; | ||
1694 | u16 ret; | ||
1695 | |||
1696 | /* | ||
1697 | * Set the radio chip access register | ||
1698 | */ | ||
1699 | switch (chan) { | ||
1700 | case CHANNEL_2GHZ: | ||
1701 | ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_2GHZ, AR5K_PHY(0)); | ||
1702 | break; | ||
1703 | case CHANNEL_5GHZ: | ||
1704 | ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0)); | ||
1705 | break; | ||
1706 | default: | ||
1707 | return 0; | ||
1708 | } | ||
1709 | |||
1710 | mdelay(2); | ||
1711 | |||
1712 | /* ...wait until PHY is ready and read the selected radio revision */ | ||
1713 | ath5k_hw_reg_write(ah, 0x00001c16, AR5K_PHY(0x34)); | ||
1714 | |||
1715 | for (i = 0; i < 8; i++) | ||
1716 | ath5k_hw_reg_write(ah, 0x00010000, AR5K_PHY(0x20)); | ||
1717 | |||
1718 | if (ah->ah_version == AR5K_AR5210) { | ||
1719 | srev = ath5k_hw_reg_read(ah, AR5K_PHY(256) >> 28) & 0xf; | ||
1720 | ret = (u16)ath5k_hw_bitswap(srev, 4) + 1; | ||
1721 | } else { | ||
1722 | srev = (ath5k_hw_reg_read(ah, AR5K_PHY(0x100)) >> 24) & 0xff; | ||
1723 | ret = (u16)ath5k_hw_bitswap(((srev & 0xf0) >> 4) | | ||
1724 | ((srev & 0x0f) << 4), 8); | ||
1725 | } | ||
1726 | |||
1727 | /* Reset to the 5GHz mode */ | ||
1728 | ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0)); | ||
1729 | |||
1730 | return ret; | ||
1731 | } | ||
1732 | 1845 | ||
1733 | /*****************\ | 1846 | /*****************\ |
1734 | * Antenna control * | 1847 | * Antenna control * |
@@ -1836,12 +1949,10 @@ ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode) | |||
1836 | 1949 | ||
1837 | switch (channel->hw_value & CHANNEL_MODES) { | 1950 | switch (channel->hw_value & CHANNEL_MODES) { |
1838 | case CHANNEL_A: | 1951 | case CHANNEL_A: |
1839 | case CHANNEL_T: | ||
1840 | case CHANNEL_XR: | 1952 | case CHANNEL_XR: |
1841 | ee_mode = AR5K_EEPROM_MODE_11A; | 1953 | ee_mode = AR5K_EEPROM_MODE_11A; |
1842 | break; | 1954 | break; |
1843 | case CHANNEL_G: | 1955 | case CHANNEL_G: |
1844 | case CHANNEL_TG: | ||
1845 | ee_mode = AR5K_EEPROM_MODE_11G; | 1956 | ee_mode = AR5K_EEPROM_MODE_11G; |
1846 | break; | 1957 | break; |
1847 | case CHANNEL_B: | 1958 | case CHANNEL_B: |
@@ -2275,20 +2386,20 @@ ath5k_get_max_ctl_power(struct ath5k_hw *ah, | |||
2275 | 2386 | ||
2276 | switch (channel->hw_value & CHANNEL_MODES) { | 2387 | switch (channel->hw_value & CHANNEL_MODES) { |
2277 | case CHANNEL_A: | 2388 | case CHANNEL_A: |
2278 | ctl_mode |= AR5K_CTL_11A; | 2389 | if (ah->ah_bwmode == AR5K_BWMODE_40MHZ) |
2390 | ctl_mode |= AR5K_CTL_TURBO; | ||
2391 | else | ||
2392 | ctl_mode |= AR5K_CTL_11A; | ||
2279 | break; | 2393 | break; |
2280 | case CHANNEL_G: | 2394 | case CHANNEL_G: |
2281 | ctl_mode |= AR5K_CTL_11G; | 2395 | if (ah->ah_bwmode == AR5K_BWMODE_40MHZ) |
2396 | ctl_mode |= AR5K_CTL_TURBOG; | ||
2397 | else | ||
2398 | ctl_mode |= AR5K_CTL_11G; | ||
2282 | break; | 2399 | break; |
2283 | case CHANNEL_B: | 2400 | case CHANNEL_B: |
2284 | ctl_mode |= AR5K_CTL_11B; | 2401 | ctl_mode |= AR5K_CTL_11B; |
2285 | break; | 2402 | break; |
2286 | case CHANNEL_T: | ||
2287 | ctl_mode |= AR5K_CTL_TURBO; | ||
2288 | break; | ||
2289 | case CHANNEL_TG: | ||
2290 | ctl_mode |= AR5K_CTL_TURBOG; | ||
2291 | break; | ||
2292 | case CHANNEL_XR: | 2403 | case CHANNEL_XR: |
2293 | /* Fall through */ | 2404 | /* Fall through */ |
2294 | default: | 2405 | default: |
@@ -2631,10 +2742,12 @@ ath5k_combine_pwr_to_pdadc_curves(struct ath5k_hw *ah, | |||
2631 | 2742 | ||
2632 | /* Write PDADC values on hw */ | 2743 | /* Write PDADC values on hw */ |
2633 | static void | 2744 | static void |
2634 | ath5k_setup_pwr_to_pdadc_table(struct ath5k_hw *ah, | 2745 | ath5k_setup_pwr_to_pdadc_table(struct ath5k_hw *ah, u8 ee_mode) |
2635 | u8 pdcurves, u8 *pdg_to_idx) | ||
2636 | { | 2746 | { |
2747 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; | ||
2637 | u8 *pdadc_out = ah->ah_txpower.txp_pd_table; | 2748 | u8 *pdadc_out = ah->ah_txpower.txp_pd_table; |
2749 | u8 *pdg_to_idx = ee->ee_pdc_to_idx[ee_mode]; | ||
2750 | u8 pdcurves = ee->ee_pd_gains[ee_mode]; | ||
2638 | u32 reg; | 2751 | u32 reg; |
2639 | u8 i; | 2752 | u8 i; |
2640 | 2753 | ||
@@ -2881,7 +2994,7 @@ ath5k_setup_channel_powertable(struct ath5k_hw *ah, | |||
2881 | ee->ee_pd_gains[ee_mode]); | 2994 | ee->ee_pd_gains[ee_mode]); |
2882 | 2995 | ||
2883 | /* Write settings on hw */ | 2996 | /* Write settings on hw */ |
2884 | ath5k_setup_pwr_to_pdadc_table(ah, pdg, pdg_curve_to_idx); | 2997 | ath5k_setup_pwr_to_pdadc_table(ah, ee_mode); |
2885 | 2998 | ||
2886 | /* Set txp.offset, note that table_min | 2999 | /* Set txp.offset, note that table_min |
2887 | * can be negative */ | 3000 | * can be negative */ |
@@ -2990,9 +3103,9 @@ ath5k_setup_rate_powertable(struct ath5k_hw *ah, u16 max_pwr, | |||
2990 | /* | 3103 | /* |
2991 | * Set transmission power | 3104 | * Set transmission power |
2992 | */ | 3105 | */ |
2993 | int | 3106 | static int |
2994 | ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, | 3107 | ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, |
2995 | u8 ee_mode, u8 txpower) | 3108 | u8 ee_mode, u8 txpower, bool fast) |
2996 | { | 3109 | { |
2997 | struct ath5k_rate_pcal_info rate_info; | 3110 | struct ath5k_rate_pcal_info rate_info; |
2998 | u8 type; | 3111 | u8 type; |
@@ -3003,14 +3116,11 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, | |||
3003 | return -EINVAL; | 3116 | return -EINVAL; |
3004 | } | 3117 | } |
3005 | 3118 | ||
3006 | /* Reset TX power values */ | ||
3007 | memset(&ah->ah_txpower, 0, sizeof(ah->ah_txpower)); | ||
3008 | ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER; | ||
3009 | ah->ah_txpower.txp_min_pwr = 0; | ||
3010 | ah->ah_txpower.txp_max_pwr = AR5K_TUNE_MAX_TXPOWER; | ||
3011 | |||
3012 | /* Initialize TX power table */ | 3119 | /* Initialize TX power table */ |
3013 | switch (ah->ah_radio) { | 3120 | switch (ah->ah_radio) { |
3121 | case AR5K_RF5110: | ||
3122 | /* TODO */ | ||
3123 | return 0; | ||
3014 | case AR5K_RF5111: | 3124 | case AR5K_RF5111: |
3015 | type = AR5K_PWRTABLE_PWR_TO_PCDAC; | 3125 | type = AR5K_PWRTABLE_PWR_TO_PCDAC; |
3016 | break; | 3126 | break; |
@@ -3028,10 +3138,28 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, | |||
3028 | return -EINVAL; | 3138 | return -EINVAL; |
3029 | } | 3139 | } |
3030 | 3140 | ||
3031 | /* FIXME: Only on channel/mode change */ | 3141 | /* If fast is set it means we are on the same channel/mode |
3032 | ret = ath5k_setup_channel_powertable(ah, channel, ee_mode, type); | 3142 | * so there is no need to recalculate the powertable, we 'll |
3033 | if (ret) | 3143 | * just use the cached one */ |
3034 | return ret; | 3144 | if (!fast) { |
3145 | /* Reset TX power values */ | ||
3146 | memset(&ah->ah_txpower, 0, sizeof(ah->ah_txpower)); | ||
3147 | ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER; | ||
3148 | ah->ah_txpower.txp_min_pwr = 0; | ||
3149 | ah->ah_txpower.txp_max_pwr = AR5K_TUNE_MAX_TXPOWER; | ||
3150 | |||
3151 | /* Calculate the powertable */ | ||
3152 | ret = ath5k_setup_channel_powertable(ah, channel, | ||
3153 | ee_mode, type); | ||
3154 | if (ret) | ||
3155 | return ret; | ||
3156 | /* Write cached table on hw */ | ||
3157 | } else if (type == AR5K_PWRTABLE_PWR_TO_PDADC) | ||
3158 | ath5k_setup_pwr_to_pdadc_table(ah, ee_mode); | ||
3159 | else | ||
3160 | ath5k_setup_pcdac_table(ah); | ||
3161 | |||
3162 | |||
3035 | 3163 | ||
3036 | /* Limit max power if we have a CTL available */ | 3164 | /* Limit max power if we have a CTL available */ |
3037 | ath5k_get_max_ctl_power(ah, channel); | 3165 | ath5k_get_max_ctl_power(ah, channel); |
@@ -3092,12 +3220,10 @@ int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower) | |||
3092 | 3220 | ||
3093 | switch (channel->hw_value & CHANNEL_MODES) { | 3221 | switch (channel->hw_value & CHANNEL_MODES) { |
3094 | case CHANNEL_A: | 3222 | case CHANNEL_A: |
3095 | case CHANNEL_T: | ||
3096 | case CHANNEL_XR: | 3223 | case CHANNEL_XR: |
3097 | ee_mode = AR5K_EEPROM_MODE_11A; | 3224 | ee_mode = AR5K_EEPROM_MODE_11A; |
3098 | break; | 3225 | break; |
3099 | case CHANNEL_G: | 3226 | case CHANNEL_G: |
3100 | case CHANNEL_TG: | ||
3101 | ee_mode = AR5K_EEPROM_MODE_11G; | 3227 | ee_mode = AR5K_EEPROM_MODE_11G; |
3102 | break; | 3228 | break; |
3103 | case CHANNEL_B: | 3229 | case CHANNEL_B: |
@@ -3112,5 +3238,229 @@ int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower) | |||
3112 | ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_TXPOWER, | 3238 | ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_TXPOWER, |
3113 | "changing txpower to %d\n", txpower); | 3239 | "changing txpower to %d\n", txpower); |
3114 | 3240 | ||
3115 | return ath5k_hw_txpower(ah, channel, ee_mode, txpower); | 3241 | return ath5k_hw_txpower(ah, channel, ee_mode, txpower, true); |
3242 | } | ||
3243 | |||
3244 | /*************\ | ||
3245 | Init function | ||
3246 | \*************/ | ||
3247 | |||
3248 | int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, | ||
3249 | u8 mode, u8 ee_mode, u8 freq, bool fast) | ||
3250 | { | ||
3251 | struct ieee80211_channel *curr_channel; | ||
3252 | int ret, i; | ||
3253 | u32 phy_tst1; | ||
3254 | bool fast_txp; | ||
3255 | ret = 0; | ||
3256 | |||
3257 | /* | ||
3258 | * Sanity check for fast flag | ||
3259 | * Don't try fast channel change when changing modulation | ||
3260 | * mode/band. We check for chip compatibility on | ||
3261 | * ath5k_hw_reset. | ||
3262 | */ | ||
3263 | curr_channel = ah->ah_current_channel; | ||
3264 | if (fast && (channel->hw_value != curr_channel->hw_value)) | ||
3265 | return -EINVAL; | ||
3266 | |||
3267 | /* | ||
3268 | * On fast channel change we only set the synth parameters | ||
3269 | * while PHY is running, enable calibration and skip the rest. | ||
3270 | */ | ||
3271 | if (fast) { | ||
3272 | AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_RFBUS_REQ, | ||
3273 | AR5K_PHY_RFBUS_REQ_REQUEST); | ||
3274 | for (i = 0; i < 100; i++) { | ||
3275 | if (ath5k_hw_reg_read(ah, AR5K_PHY_RFBUS_GRANT)) | ||
3276 | break; | ||
3277 | udelay(5); | ||
3278 | } | ||
3279 | /* Failed */ | ||
3280 | if (i >= 100) | ||
3281 | return -EIO; | ||
3282 | } | ||
3283 | |||
3284 | /* | ||
3285 | * If we don't change channel/mode skip | ||
3286 | * tx powertable calculation and use the | ||
3287 | * cached one. | ||
3288 | */ | ||
3289 | if ((channel->hw_value == curr_channel->hw_value) && | ||
3290 | (channel->center_freq == curr_channel->center_freq)) | ||
3291 | fast_txp = true; | ||
3292 | else | ||
3293 | fast_txp = false; | ||
3294 | |||
3295 | /* | ||
3296 | * Set TX power | ||
3297 | * | ||
3298 | * Note: We need to do that before we set | ||
3299 | * RF buffer settings on 5211/5212+ so that we | ||
3300 | * properly set curve indices. | ||
3301 | */ | ||
3302 | ret = ath5k_hw_txpower(ah, channel, ee_mode, | ||
3303 | ah->ah_txpower.txp_max_pwr / 2, | ||
3304 | fast_txp); | ||
3305 | if (ret) | ||
3306 | return ret; | ||
3307 | |||
3308 | /* | ||
3309 | * For 5210 we do all initialization using | ||
3310 | * initvals, so we don't have to modify | ||
3311 | * any settings (5210 also only supports | ||
3312 | * a/aturbo modes) | ||
3313 | */ | ||
3314 | if ((ah->ah_version != AR5K_AR5210) && !fast) { | ||
3315 | |||
3316 | /* | ||
3317 | * Write initial RF gain settings | ||
3318 | * This should work for both 5111/5112 | ||
3319 | */ | ||
3320 | ret = ath5k_hw_rfgain_init(ah, freq); | ||
3321 | if (ret) | ||
3322 | return ret; | ||
3323 | |||
3324 | mdelay(1); | ||
3325 | |||
3326 | /* | ||
3327 | * Write RF buffer | ||
3328 | */ | ||
3329 | ret = ath5k_hw_rfregs_init(ah, channel, mode); | ||
3330 | if (ret) | ||
3331 | return ret; | ||
3332 | |||
3333 | /* Write OFDM timings on 5212*/ | ||
3334 | if (ah->ah_version == AR5K_AR5212 && | ||
3335 | channel->hw_value & CHANNEL_OFDM) { | ||
3336 | |||
3337 | ret = ath5k_hw_write_ofdm_timings(ah, channel); | ||
3338 | if (ret) | ||
3339 | return ret; | ||
3340 | |||
3341 | /* Spur info is available only from EEPROM versions | ||
3342 | * greater than 5.3, but the EEPROM routines will use | ||
3343 | * static values for older versions */ | ||
3344 | if (ah->ah_mac_srev >= AR5K_SREV_AR5424) | ||
3345 | ath5k_hw_set_spur_mitigation_filter(ah, | ||
3346 | channel); | ||
3347 | } | ||
3348 | |||
3349 | /*Enable/disable 802.11b mode on 5111 | ||
3350 | (enable 2111 frequency converter + CCK)*/ | ||
3351 | if (ah->ah_radio == AR5K_RF5111) { | ||
3352 | if (mode == AR5K_MODE_11B) | ||
3353 | AR5K_REG_ENABLE_BITS(ah, AR5K_TXCFG, | ||
3354 | AR5K_TXCFG_B_MODE); | ||
3355 | else | ||
3356 | AR5K_REG_DISABLE_BITS(ah, AR5K_TXCFG, | ||
3357 | AR5K_TXCFG_B_MODE); | ||
3358 | } | ||
3359 | |||
3360 | } else if (ah->ah_version == AR5K_AR5210) { | ||
3361 | mdelay(1); | ||
3362 | /* Disable phy and wait */ | ||
3363 | ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT); | ||
3364 | mdelay(1); | ||
3365 | } | ||
3366 | |||
3367 | /* Set channel on PHY */ | ||
3368 | ret = ath5k_hw_channel(ah, channel); | ||
3369 | if (ret) | ||
3370 | return ret; | ||
3371 | |||
3372 | /* | ||
3373 | * Enable the PHY and wait until completion | ||
3374 | * This includes BaseBand and Synthesizer | ||
3375 | * activation. | ||
3376 | */ | ||
3377 | ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT); | ||
3378 | |||
3379 | /* | ||
3380 | * On 5211+ read activation -> rx delay | ||
3381 | * and use it. | ||
3382 | */ | ||
3383 | if (ah->ah_version != AR5K_AR5210) { | ||
3384 | u32 delay; | ||
3385 | delay = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) & | ||
3386 | AR5K_PHY_RX_DELAY_M; | ||
3387 | delay = (channel->hw_value & CHANNEL_CCK) ? | ||
3388 | ((delay << 2) / 22) : (delay / 10); | ||
3389 | if (ah->ah_bwmode == AR5K_BWMODE_10MHZ) | ||
3390 | delay = delay << 1; | ||
3391 | if (ah->ah_bwmode == AR5K_BWMODE_5MHZ) | ||
3392 | delay = delay << 2; | ||
3393 | /* XXX: /2 on turbo ? Let's be safe | ||
3394 | * for now */ | ||
3395 | udelay(100 + delay); | ||
3396 | } else { | ||
3397 | mdelay(1); | ||
3398 | } | ||
3399 | |||
3400 | if (fast) | ||
3401 | /* | ||
3402 | * Release RF Bus grant | ||
3403 | */ | ||
3404 | AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_RFBUS_REQ, | ||
3405 | AR5K_PHY_RFBUS_REQ_REQUEST); | ||
3406 | else { | ||
3407 | /* | ||
3408 | * Perform ADC test to see if baseband is ready | ||
3409 | * Set tx hold and check adc test register | ||
3410 | */ | ||
3411 | phy_tst1 = ath5k_hw_reg_read(ah, AR5K_PHY_TST1); | ||
3412 | ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1); | ||
3413 | for (i = 0; i <= 20; i++) { | ||
3414 | if (!(ath5k_hw_reg_read(ah, AR5K_PHY_ADC_TEST) & 0x10)) | ||
3415 | break; | ||
3416 | udelay(200); | ||
3417 | } | ||
3418 | ath5k_hw_reg_write(ah, phy_tst1, AR5K_PHY_TST1); | ||
3419 | } | ||
3420 | |||
3421 | /* | ||
3422 | * Start automatic gain control calibration | ||
3423 | * | ||
3424 | * During AGC calibration RX path is re-routed to | ||
3425 | * a power detector so we don't receive anything. | ||
3426 | * | ||
3427 | * This method is used to calibrate some static offsets | ||
3428 | * used together with on-the fly I/Q calibration (the | ||
3429 | * one performed via ath5k_hw_phy_calibrate), which doesn't | ||
3430 | * interrupt rx path. | ||
3431 | * | ||
3432 | * While rx path is re-routed to the power detector we also | ||
3433 | * start a noise floor calibration to measure the | ||
3434 | * card's noise floor (the noise we measure when we are not | ||
3435 | * transmitting or receiving anything). | ||
3436 | * | ||
3437 | * If we are in a noisy environment, AGC calibration may time | ||
3438 | * out and/or noise floor calibration might timeout. | ||
3439 | */ | ||
3440 | AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL, | ||
3441 | AR5K_PHY_AGCCTL_CAL | AR5K_PHY_AGCCTL_NF); | ||
3442 | |||
3443 | /* At the same time start I/Q calibration for QAM constellation | ||
3444 | * -no need for CCK- */ | ||
3445 | ah->ah_calibration = false; | ||
3446 | if (!(mode == AR5K_MODE_11B)) { | ||
3447 | ah->ah_calibration = true; | ||
3448 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, | ||
3449 | AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15); | ||
3450 | AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, | ||
3451 | AR5K_PHY_IQ_RUN); | ||
3452 | } | ||
3453 | |||
3454 | /* Wait for gain calibration to finish (we check for I/Q calibration | ||
3455 | * during ath5k_phy_calibrate) */ | ||
3456 | if (ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL, | ||
3457 | AR5K_PHY_AGCCTL_CAL, 0, false)) { | ||
3458 | ATH5K_ERR(ah->ah_sc, "gain calibration timeout (%uMHz)\n", | ||
3459 | channel->center_freq); | ||
3460 | } | ||
3461 | |||
3462 | /* Restore antenna mode */ | ||
3463 | ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode); | ||
3464 | |||
3465 | return ret; | ||
3116 | } | 3466 | } |