diff options
Diffstat (limited to 'drivers/net/wireless/ath5k/hw.c')
-rw-r--r-- | drivers/net/wireless/ath5k/hw.c | 239 |
1 files changed, 149 insertions, 90 deletions
diff --git a/drivers/net/wireless/ath5k/hw.c b/drivers/net/wireless/ath5k/hw.c index 7ca87a557312..ad1a5b422c8c 100644 --- a/drivers/net/wireless/ath5k/hw.c +++ b/drivers/net/wireless/ath5k/hw.c | |||
@@ -139,6 +139,8 @@ static int ath5k_hw_post(struct ath5k_hw *ah) | |||
139 | for (c = 0; c < 2; c++) { | 139 | for (c = 0; c < 2; c++) { |
140 | 140 | ||
141 | cur_reg = regs[c]; | 141 | cur_reg = regs[c]; |
142 | |||
143 | /* Save previous value */ | ||
142 | init_val = ath5k_hw_reg_read(ah, cur_reg); | 144 | init_val = ath5k_hw_reg_read(ah, cur_reg); |
143 | 145 | ||
144 | for (i = 0; i < 256; i++) { | 146 | for (i = 0; i < 256; i++) { |
@@ -170,6 +172,10 @@ static int ath5k_hw_post(struct ath5k_hw *ah) | |||
170 | var_pattern = 0x003b080f; | 172 | var_pattern = 0x003b080f; |
171 | ath5k_hw_reg_write(ah, var_pattern, cur_reg); | 173 | ath5k_hw_reg_write(ah, var_pattern, cur_reg); |
172 | } | 174 | } |
175 | |||
176 | /* Restore previous value */ | ||
177 | ath5k_hw_reg_write(ah, init_val, cur_reg); | ||
178 | |||
173 | } | 179 | } |
174 | 180 | ||
175 | return 0; | 181 | return 0; |
@@ -287,67 +293,42 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version) | |||
287 | /* Identify the radio chip*/ | 293 | /* Identify the radio chip*/ |
288 | if (ah->ah_version == AR5K_AR5210) { | 294 | if (ah->ah_version == AR5K_AR5210) { |
289 | ah->ah_radio = AR5K_RF5110; | 295 | ah->ah_radio = AR5K_RF5110; |
296 | /* | ||
297 | * Register returns 0x0/0x04 for radio revision | ||
298 | * so ath5k_hw_radio_revision doesn't parse the value | ||
299 | * correctly. For now we are based on mac's srev to | ||
300 | * identify RF2425 radio. | ||
301 | */ | ||
302 | } else if (srev == AR5K_SREV_VER_AR2425) { | ||
303 | ah->ah_radio = AR5K_RF2425; | ||
304 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2425; | ||
290 | } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112) { | 305 | } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112) { |
291 | ah->ah_radio = AR5K_RF5111; | 306 | ah->ah_radio = AR5K_RF5111; |
292 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5111; | 307 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5111; |
293 | } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC0) { | 308 | } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC0) { |
294 | |||
295 | ah->ah_radio = AR5K_RF5112; | 309 | ah->ah_radio = AR5K_RF5112; |
296 | 310 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112; | |
297 | if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112A) { | ||
298 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112; | ||
299 | } else { | ||
300 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112A; | ||
301 | } | ||
302 | |||
303 | } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC1) { | 311 | } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC1) { |
304 | ah->ah_radio = AR5K_RF2413; | 312 | ah->ah_radio = AR5K_RF2413; |
305 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112A; | 313 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2413; |
306 | } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC2) { | 314 | } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC2) { |
307 | ah->ah_radio = AR5K_RF5413; | 315 | ah->ah_radio = AR5K_RF5413; |
308 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112A; | 316 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5413; |
309 | } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5133) { | 317 | } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5133) { |
310 | |||
311 | /* AR5424 */ | 318 | /* AR5424 */ |
312 | if (srev >= AR5K_SREV_VER_AR5424) { | 319 | if (srev >= AR5K_SREV_VER_AR5424) { |
313 | ah->ah_radio = AR5K_RF5413; | 320 | ah->ah_radio = AR5K_RF5413; |
314 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5424; | 321 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5413; |
315 | /* AR2424 */ | 322 | /* AR2424 */ |
316 | } else { | 323 | } else { |
317 | ah->ah_radio = AR5K_RF2413; /* For testing */ | 324 | ah->ah_radio = AR5K_RF2413; /* For testing */ |
318 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112A; | 325 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2413; |
319 | } | 326 | } |
320 | |||
321 | /* | ||
322 | * Register returns 0x4 for radio revision | ||
323 | * so ath5k_hw_radio_revision doesn't parse the value | ||
324 | * correctly. For now we are based on mac's srev to | ||
325 | * identify RF2425 radio. | ||
326 | */ | ||
327 | } else if (srev == AR5K_SREV_VER_AR2425) { | ||
328 | ah->ah_radio = AR5K_RF2425; | ||
329 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112; | ||
330 | } | 327 | } |
331 | |||
332 | ah->ah_phy = AR5K_PHY(0); | 328 | ah->ah_phy = AR5K_PHY(0); |
333 | 329 | ||
334 | /* | 330 | /* |
335 | * Identify AR5212-based PCI-E cards | 331 | * Write PCI-E power save settings |
336 | * And write some initial settings. | ||
337 | * | ||
338 | * (doing a "strings" on ndis driver | ||
339 | * -ar5211.sys- reveals the following | ||
340 | * pci-e related functions: | ||
341 | * | ||
342 | * pcieClockReq | ||
343 | * pcieRxErrNotify | ||
344 | * pcieL1SKPEnable | ||
345 | * pcieAspm | ||
346 | * pcieDisableAspmOnRfWake | ||
347 | * pciePowerSaveEnable | ||
348 | * | ||
349 | * I guess these point to ClockReq but | ||
350 | * i'm not sure.) | ||
351 | */ | 332 | */ |
352 | if ((ah->ah_version == AR5K_AR5212) && (pdev->is_pcie)) { | 333 | if ((ah->ah_version == AR5K_AR5212) && (pdev->is_pcie)) { |
353 | ath5k_hw_reg_write(ah, 0x9248fc00, 0x4080); | 334 | ath5k_hw_reg_write(ah, 0x9248fc00, 0x4080); |
@@ -369,10 +350,15 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version) | |||
369 | if (ret) | 350 | if (ret) |
370 | goto err_free; | 351 | goto err_free; |
371 | 352 | ||
353 | /* Write AR5K_PCICFG_UNK on 2112B and later chips */ | ||
354 | if (ah->ah_radio_5ghz_revision > AR5K_SREV_RAD_2112B || | ||
355 | srev > AR5K_SREV_VER_AR2413) { | ||
356 | ath5k_hw_reg_write(ah, AR5K_PCICFG_UNK, AR5K_PCICFG); | ||
357 | } | ||
358 | |||
372 | /* | 359 | /* |
373 | * Get card capabilities, values, ... | 360 | * Get card capabilities, values, ... |
374 | */ | 361 | */ |
375 | |||
376 | ret = ath5k_eeprom_init(ah); | 362 | ret = ath5k_eeprom_init(ah); |
377 | if (ret) { | 363 | if (ret) { |
378 | ATH5K_ERR(sc, "unable to init EEPROM\n"); | 364 | ATH5K_ERR(sc, "unable to init EEPROM\n"); |
@@ -843,27 +829,41 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, | |||
843 | * Write some more initial register settings | 829 | * Write some more initial register settings |
844 | */ | 830 | */ |
845 | if (ah->ah_version == AR5K_AR5212) { | 831 | if (ah->ah_version == AR5K_AR5212) { |
846 | ath5k_hw_reg_write(ah, 0x0002a002, AR5K_PHY(11)); | 832 | ath5k_hw_reg_write(ah, 0x0002a002, 0x982c); |
847 | 833 | ||
848 | if (channel->hw_value == CHANNEL_G) | 834 | if (channel->hw_value == CHANNEL_G) |
849 | if (ah->ah_mac_srev < AR5K_SREV_VER_AR2413) | 835 | if (ah->ah_mac_srev < AR5K_SREV_VER_AR2413) |
850 | ath5k_hw_reg_write(ah, 0x00f80d80, | 836 | ath5k_hw_reg_write(ah, 0x00f80d80, |
851 | AR5K_PHY(83)); | 837 | 0x994c); |
852 | else if (ah->ah_mac_srev < AR5K_SREV_VER_AR2424) | 838 | else if (ah->ah_mac_srev < AR5K_SREV_VER_AR2424) |
853 | ath5k_hw_reg_write(ah, 0x00380140, | 839 | ath5k_hw_reg_write(ah, 0x00380140, |
854 | AR5K_PHY(83)); | 840 | 0x994c); |
855 | else if (ah->ah_mac_srev < AR5K_SREV_VER_AR2425) | 841 | else if (ah->ah_mac_srev < AR5K_SREV_VER_AR2425) |
856 | ath5k_hw_reg_write(ah, 0x00fc0ec0, | 842 | ath5k_hw_reg_write(ah, 0x00fc0ec0, |
857 | AR5K_PHY(83)); | 843 | 0x994c); |
858 | else /* 2425 */ | 844 | else /* 2425 */ |
859 | ath5k_hw_reg_write(ah, 0x00fc0fc0, | 845 | ath5k_hw_reg_write(ah, 0x00fc0fc0, |
860 | AR5K_PHY(83)); | 846 | 0x994c); |
861 | else | 847 | else |
862 | ath5k_hw_reg_write(ah, 0x00000000, | 848 | ath5k_hw_reg_write(ah, 0x00000000, 0x994c); |
863 | AR5K_PHY(83)); | 849 | |
864 | 850 | /* Some bits are disabled here, we know nothing about | |
865 | ath5k_hw_reg_write(ah, 0x000009b5, 0xa228); | 851 | * register 0xa228 yet, most of the times this ends up |
866 | ath5k_hw_reg_write(ah, 0x0000000f, 0x8060); | 852 | * with a value 0x9b5 -haven't seen any dump with |
853 | * a different value- */ | ||
854 | /* Got this from decompiling binary HAL */ | ||
855 | data = ath5k_hw_reg_read(ah, 0xa228); | ||
856 | data &= 0xfffffdff; | ||
857 | ath5k_hw_reg_write(ah, data, 0xa228); | ||
858 | |||
859 | data = ath5k_hw_reg_read(ah, 0xa228); | ||
860 | data &= 0xfffe03ff; | ||
861 | ath5k_hw_reg_write(ah, data, 0xa228); | ||
862 | data = 0; | ||
863 | |||
864 | /* Just write 0x9b5 ? */ | ||
865 | /* ath5k_hw_reg_write(ah, 0x000009b5, 0xa228); */ | ||
866 | ath5k_hw_reg_write(ah, 0x0000000f, AR5K_SEQ_MASK); | ||
867 | ath5k_hw_reg_write(ah, 0x00000000, 0xa254); | 867 | ath5k_hw_reg_write(ah, 0x00000000, 0xa254); |
868 | ath5k_hw_reg_write(ah, 0x0000000e, AR5K_PHY_SCAL); | 868 | ath5k_hw_reg_write(ah, 0x0000000e, AR5K_PHY_SCAL); |
869 | } | 869 | } |
@@ -879,6 +879,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, | |||
879 | else | 879 | else |
880 | data = 0xffb80d20; | 880 | data = 0xffb80d20; |
881 | ath5k_hw_reg_write(ah, data, AR5K_PHY_FRAME_CTL); | 881 | ath5k_hw_reg_write(ah, data, AR5K_PHY_FRAME_CTL); |
882 | data = 0; | ||
882 | } | 883 | } |
883 | 884 | ||
884 | /* | 885 | /* |
@@ -898,7 +899,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, | |||
898 | 899 | ||
899 | /* | 900 | /* |
900 | * Write RF registers | 901 | * Write RF registers |
901 | * TODO:Does this work on 5211 (5111) ? | ||
902 | */ | 902 | */ |
903 | ret = ath5k_hw_rfregs(ah, channel, mode); | 903 | ret = ath5k_hw_rfregs(ah, channel, mode); |
904 | if (ret) | 904 | if (ret) |
@@ -935,7 +935,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, | |||
935 | return ret; | 935 | return ret; |
936 | 936 | ||
937 | /* Set antenna mode */ | 937 | /* Set antenna mode */ |
938 | AR5K_REG_MASKED_BITS(ah, AR5K_PHY(0x44), | 938 | AR5K_REG_MASKED_BITS(ah, AR5K_PHY_ANT_CTL, |
939 | ah->ah_antenna[ee_mode][0], 0xfffffc06); | 939 | ah->ah_antenna[ee_mode][0], 0xfffffc06); |
940 | 940 | ||
941 | /* | 941 | /* |
@@ -965,15 +965,15 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, | |||
965 | 965 | ||
966 | ath5k_hw_reg_write(ah, | 966 | ath5k_hw_reg_write(ah, |
967 | AR5K_PHY_NF_SVAL(ee->ee_noise_floor_thr[ee_mode]), | 967 | AR5K_PHY_NF_SVAL(ee->ee_noise_floor_thr[ee_mode]), |
968 | AR5K_PHY(0x5a)); | 968 | AR5K_PHY_NFTHRES); |
969 | 969 | ||
970 | AR5K_REG_MASKED_BITS(ah, AR5K_PHY(0x11), | 970 | AR5K_REG_MASKED_BITS(ah, AR5K_PHY_SETTLING, |
971 | (ee->ee_switch_settling[ee_mode] << 7) & 0x3f80, | 971 | (ee->ee_switch_settling[ee_mode] << 7) & 0x3f80, |
972 | 0xffffc07f); | 972 | 0xffffc07f); |
973 | AR5K_REG_MASKED_BITS(ah, AR5K_PHY(0x12), | 973 | AR5K_REG_MASKED_BITS(ah, AR5K_PHY_GAIN, |
974 | (ee->ee_ant_tx_rx[ee_mode] << 12) & 0x3f000, | 974 | (ee->ee_ant_tx_rx[ee_mode] << 12) & 0x3f000, |
975 | 0xfffc0fff); | 975 | 0xfffc0fff); |
976 | AR5K_REG_MASKED_BITS(ah, AR5K_PHY(0x14), | 976 | AR5K_REG_MASKED_BITS(ah, AR5K_PHY_DESIRED_SIZE, |
977 | (ee->ee_adc_desired_size[ee_mode] & 0x00ff) | | 977 | (ee->ee_adc_desired_size[ee_mode] & 0x00ff) | |
978 | ((ee->ee_pga_desired_size[ee_mode] << 8) & 0xff00), | 978 | ((ee->ee_pga_desired_size[ee_mode] << 8) & 0xff00), |
979 | 0xffff0000); | 979 | 0xffff0000); |
@@ -982,13 +982,13 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, | |||
982 | (ee->ee_tx_end2xpa_disable[ee_mode] << 24) | | 982 | (ee->ee_tx_end2xpa_disable[ee_mode] << 24) | |
983 | (ee->ee_tx_end2xpa_disable[ee_mode] << 16) | | 983 | (ee->ee_tx_end2xpa_disable[ee_mode] << 16) | |
984 | (ee->ee_tx_frm2xpa_enable[ee_mode] << 8) | | 984 | (ee->ee_tx_frm2xpa_enable[ee_mode] << 8) | |
985 | (ee->ee_tx_frm2xpa_enable[ee_mode]), AR5K_PHY(0x0d)); | 985 | (ee->ee_tx_frm2xpa_enable[ee_mode]), AR5K_PHY_RF_CTL4); |
986 | 986 | ||
987 | AR5K_REG_MASKED_BITS(ah, AR5K_PHY(0x0a), | 987 | AR5K_REG_MASKED_BITS(ah, AR5K_PHY_RF_CTL3, |
988 | ee->ee_tx_end2xlna_enable[ee_mode] << 8, 0xffff00ff); | 988 | ee->ee_tx_end2xlna_enable[ee_mode] << 8, 0xffff00ff); |
989 | AR5K_REG_MASKED_BITS(ah, AR5K_PHY(0x19), | 989 | AR5K_REG_MASKED_BITS(ah, AR5K_PHY_NF, |
990 | (ee->ee_thr_62[ee_mode] << 12) & 0x7f000, 0xfff80fff); | 990 | (ee->ee_thr_62[ee_mode] << 12) & 0x7f000, 0xfff80fff); |
991 | AR5K_REG_MASKED_BITS(ah, AR5K_PHY(0x49), 4, 0xffffff01); | 991 | AR5K_REG_MASKED_BITS(ah, AR5K_PHY_OFDM_SELFCORR, 4, 0xffffff01); |
992 | 992 | ||
993 | AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, | 993 | AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, |
994 | AR5K_PHY_IQ_CORR_ENABLE | | 994 | AR5K_PHY_IQ_CORR_ENABLE | |
@@ -1063,7 +1063,8 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, | |||
1063 | ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT); | 1063 | ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT); |
1064 | 1064 | ||
1065 | /* | 1065 | /* |
1066 | * 5111/5112 Specific | 1066 | * On 5211+ read activation -> rx delay |
1067 | * and use it. | ||
1067 | */ | 1068 | */ |
1068 | if (ah->ah_version != AR5K_AR5210) { | 1069 | if (ah->ah_version != AR5K_AR5210) { |
1069 | data = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) & | 1070 | data = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) & |
@@ -1071,40 +1072,77 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, | |||
1071 | data = (channel->hw_value & CHANNEL_CCK) ? | 1072 | data = (channel->hw_value & CHANNEL_CCK) ? |
1072 | ((data << 2) / 22) : (data / 10); | 1073 | ((data << 2) / 22) : (data / 10); |
1073 | 1074 | ||
1074 | udelay(100 + data); | 1075 | udelay(100 + (2 * data)); |
1076 | data = 0; | ||
1075 | } else { | 1077 | } else { |
1076 | mdelay(1); | 1078 | mdelay(1); |
1077 | } | 1079 | } |
1078 | 1080 | ||
1079 | /* | 1081 | /* |
1080 | * Enable calibration and wait until completion | 1082 | * Perform ADC test (?) |
1083 | */ | ||
1084 | data = ath5k_hw_reg_read(ah, AR5K_PHY_TST1); | ||
1085 | ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1); | ||
1086 | for (i = 0; i <= 20; i++) { | ||
1087 | if (!(ath5k_hw_reg_read(ah, AR5K_PHY_ADC_TEST) & 0x10)) | ||
1088 | break; | ||
1089 | udelay(200); | ||
1090 | } | ||
1091 | ath5k_hw_reg_write(ah, data, AR5K_PHY_TST1); | ||
1092 | data = 0; | ||
1093 | |||
1094 | /* | ||
1095 | * Start automatic gain calibration | ||
1096 | * | ||
1097 | * During AGC calibration RX path is re-routed to | ||
1098 | * a signal detector so we don't receive anything. | ||
1099 | * | ||
1100 | * This method is used to calibrate some static offsets | ||
1101 | * used together with on-the fly I/Q calibration (the | ||
1102 | * one performed via ath5k_hw_phy_calibrate), that doesn't | ||
1103 | * interrupt rx path. | ||
1104 | * | ||
1105 | * If we are in a noisy environment AGC calibration may time | ||
1106 | * out. | ||
1081 | */ | 1107 | */ |
1082 | AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL, | 1108 | AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL, |
1083 | AR5K_PHY_AGCCTL_CAL); | 1109 | AR5K_PHY_AGCCTL_CAL); |
1084 | 1110 | ||
1111 | /* At the same time start I/Q calibration for QAM constellation | ||
1112 | * -no need for CCK- */ | ||
1113 | ah->ah_calibration = false; | ||
1114 | if (!(mode == AR5K_MODE_11B)) { | ||
1115 | ah->ah_calibration = true; | ||
1116 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, | ||
1117 | AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15); | ||
1118 | AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, | ||
1119 | AR5K_PHY_IQ_RUN); | ||
1120 | } | ||
1121 | |||
1122 | /* Wait for gain calibration to finish (we check for I/Q calibration | ||
1123 | * during ath5k_phy_calibrate) */ | ||
1085 | if (ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL, | 1124 | if (ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL, |
1086 | AR5K_PHY_AGCCTL_CAL, 0, false)) { | 1125 | AR5K_PHY_AGCCTL_CAL, 0, false)) { |
1087 | ATH5K_ERR(ah->ah_sc, "calibration timeout (%uMHz)\n", | 1126 | ATH5K_ERR(ah->ah_sc, "gain calibration timeout (%uMHz)\n", |
1088 | channel->center_freq); | 1127 | channel->center_freq); |
1089 | return -EAGAIN; | 1128 | return -EAGAIN; |
1090 | } | 1129 | } |
1091 | 1130 | ||
1131 | /* | ||
1132 | * Start noise floor calibration | ||
1133 | * | ||
1134 | * If we run NF calibration before AGC, it always times out. | ||
1135 | * Binary HAL starts NF and AGC calibration at the same time | ||
1136 | * and only waits for AGC to finish. I believe that's wrong because | ||
1137 | * during NF calibration, rx path is also routed to a detector, so if | ||
1138 | * it doesn't finish we won't have RX. | ||
1139 | * | ||
1140 | * XXX: Find an interval that's OK for all cards... | ||
1141 | */ | ||
1092 | ret = ath5k_hw_noise_floor_calibration(ah, channel->center_freq); | 1142 | ret = ath5k_hw_noise_floor_calibration(ah, channel->center_freq); |
1093 | if (ret) | 1143 | if (ret) |
1094 | return ret; | 1144 | return ret; |
1095 | 1145 | ||
1096 | ah->ah_calibration = false; | ||
1097 | |||
1098 | /* A and G modes can use QAM modulation which requires enabling | ||
1099 | * I and Q calibration. Don't bother in B mode. */ | ||
1100 | if (!(mode == AR5K_MODE_11B)) { | ||
1101 | ah->ah_calibration = true; | ||
1102 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, | ||
1103 | AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15); | ||
1104 | AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, | ||
1105 | AR5K_PHY_IQ_RUN); | ||
1106 | } | ||
1107 | |||
1108 | /* | 1146 | /* |
1109 | * Reset queues and start beacon timers at the end of the reset routine | 1147 | * Reset queues and start beacon timers at the end of the reset routine |
1110 | */ | 1148 | */ |
@@ -1154,6 +1192,12 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, | |||
1154 | ath5k_hw_reg_write(ah, AR5K_PHY_SCLOCK_32MHZ, AR5K_PHY_SCLOCK); | 1192 | ath5k_hw_reg_write(ah, AR5K_PHY_SCLOCK_32MHZ, AR5K_PHY_SCLOCK); |
1155 | ath5k_hw_reg_write(ah, AR5K_PHY_SDELAY_32MHZ, AR5K_PHY_SDELAY); | 1193 | ath5k_hw_reg_write(ah, AR5K_PHY_SDELAY_32MHZ, AR5K_PHY_SDELAY); |
1156 | ath5k_hw_reg_write(ah, ah->ah_phy_spending, AR5K_PHY_SPENDING); | 1194 | ath5k_hw_reg_write(ah, ah->ah_phy_spending, AR5K_PHY_SPENDING); |
1195 | |||
1196 | data = ath5k_hw_reg_read(ah, AR5K_USEC_5211) & 0xffffc07f ; | ||
1197 | data |= (ah->ah_phy_spending == AR5K_PHY_SPENDING_18) ? | ||
1198 | 0x00000f80 : 0x00001380 ; | ||
1199 | ath5k_hw_reg_write(ah, data, AR5K_USEC_5211); | ||
1200 | data = 0; | ||
1157 | } | 1201 | } |
1158 | 1202 | ||
1159 | if (ah->ah_version == AR5K_AR5212) { | 1203 | if (ah->ah_version == AR5K_AR5212) { |
@@ -1226,7 +1270,7 @@ int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode, | |||
1226 | bool set_chip, u16 sleep_duration) | 1270 | bool set_chip, u16 sleep_duration) |
1227 | { | 1271 | { |
1228 | unsigned int i; | 1272 | unsigned int i; |
1229 | u32 staid; | 1273 | u32 staid, data; |
1230 | 1274 | ||
1231 | ATH5K_TRACE(ah->ah_sc); | 1275 | ATH5K_TRACE(ah->ah_sc); |
1232 | staid = ath5k_hw_reg_read(ah, AR5K_STA_ID1); | 1276 | staid = ath5k_hw_reg_read(ah, AR5K_STA_ID1); |
@@ -1238,7 +1282,8 @@ int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode, | |||
1238 | case AR5K_PM_NETWORK_SLEEP: | 1282 | case AR5K_PM_NETWORK_SLEEP: |
1239 | if (set_chip) | 1283 | if (set_chip) |
1240 | ath5k_hw_reg_write(ah, | 1284 | ath5k_hw_reg_write(ah, |
1241 | AR5K_SLEEP_CTL_SLE | sleep_duration, | 1285 | AR5K_SLEEP_CTL_SLE_ALLOW | |
1286 | sleep_duration, | ||
1242 | AR5K_SLEEP_CTL); | 1287 | AR5K_SLEEP_CTL); |
1243 | 1288 | ||
1244 | staid |= AR5K_STA_ID1_PWR_SV; | 1289 | staid |= AR5K_STA_ID1_PWR_SV; |
@@ -1253,13 +1298,24 @@ int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode, | |||
1253 | break; | 1298 | break; |
1254 | 1299 | ||
1255 | case AR5K_PM_AWAKE: | 1300 | case AR5K_PM_AWAKE: |
1301 | |||
1302 | staid &= ~AR5K_STA_ID1_PWR_SV; | ||
1303 | |||
1256 | if (!set_chip) | 1304 | if (!set_chip) |
1257 | goto commit; | 1305 | goto commit; |
1258 | 1306 | ||
1259 | ath5k_hw_reg_write(ah, AR5K_SLEEP_CTL_SLE_WAKE, | 1307 | /* Preserve sleep duration */ |
1260 | AR5K_SLEEP_CTL); | 1308 | data = ath5k_hw_reg_read(ah, AR5K_SLEEP_CTL); |
1309 | if( data & 0xffc00000 ){ | ||
1310 | data = 0; | ||
1311 | } else { | ||
1312 | data = data & 0xfffcffff; | ||
1313 | } | ||
1314 | |||
1315 | ath5k_hw_reg_write(ah, data, AR5K_SLEEP_CTL); | ||
1316 | udelay(15); | ||
1261 | 1317 | ||
1262 | for (i = 5000; i > 0; i--) { | 1318 | for (i = 50; i > 0; i--) { |
1263 | /* Check if the chip did wake up */ | 1319 | /* Check if the chip did wake up */ |
1264 | if ((ath5k_hw_reg_read(ah, AR5K_PCICFG) & | 1320 | if ((ath5k_hw_reg_read(ah, AR5K_PCICFG) & |
1265 | AR5K_PCICFG_SPWR_DN) == 0) | 1321 | AR5K_PCICFG_SPWR_DN) == 0) |
@@ -1267,15 +1323,13 @@ int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode, | |||
1267 | 1323 | ||
1268 | /* Wait a bit and retry */ | 1324 | /* Wait a bit and retry */ |
1269 | udelay(200); | 1325 | udelay(200); |
1270 | ath5k_hw_reg_write(ah, AR5K_SLEEP_CTL_SLE_WAKE, | 1326 | ath5k_hw_reg_write(ah, data, AR5K_SLEEP_CTL); |
1271 | AR5K_SLEEP_CTL); | ||
1272 | } | 1327 | } |
1273 | 1328 | ||
1274 | /* Fail if the chip didn't wake up */ | 1329 | /* Fail if the chip didn't wake up */ |
1275 | if (i <= 0) | 1330 | if (i <= 0) |
1276 | return -EIO; | 1331 | return -EIO; |
1277 | 1332 | ||
1278 | staid &= ~AR5K_STA_ID1_PWR_SV; | ||
1279 | break; | 1333 | break; |
1280 | 1334 | ||
1281 | default: | 1335 | default: |
@@ -1304,6 +1358,7 @@ void ath5k_hw_start_rx(struct ath5k_hw *ah) | |||
1304 | { | 1358 | { |
1305 | ATH5K_TRACE(ah->ah_sc); | 1359 | ATH5K_TRACE(ah->ah_sc); |
1306 | ath5k_hw_reg_write(ah, AR5K_CR_RXE, AR5K_CR); | 1360 | ath5k_hw_reg_write(ah, AR5K_CR_RXE, AR5K_CR); |
1361 | ath5k_hw_reg_read(ah, AR5K_CR); | ||
1307 | } | 1362 | } |
1308 | 1363 | ||
1309 | /* | 1364 | /* |
@@ -1390,6 +1445,7 @@ int ath5k_hw_tx_start(struct ath5k_hw *ah, unsigned int queue) | |||
1390 | } | 1445 | } |
1391 | /* Start queue */ | 1446 | /* Start queue */ |
1392 | ath5k_hw_reg_write(ah, tx_queue, AR5K_CR); | 1447 | ath5k_hw_reg_write(ah, tx_queue, AR5K_CR); |
1448 | ath5k_hw_reg_read(ah, AR5K_CR); | ||
1393 | } else { | 1449 | } else { |
1394 | /* Return if queue is disabled */ | 1450 | /* Return if queue is disabled */ |
1395 | if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXD, queue)) | 1451 | if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXD, queue)) |
@@ -1687,6 +1743,7 @@ enum ath5k_int ath5k_hw_set_intr(struct ath5k_hw *ah, enum ath5k_int new_mask) | |||
1687 | * (they will be re-enabled afterwards). | 1743 | * (they will be re-enabled afterwards). |
1688 | */ | 1744 | */ |
1689 | ath5k_hw_reg_write(ah, AR5K_IER_DISABLE, AR5K_IER); | 1745 | ath5k_hw_reg_write(ah, AR5K_IER_DISABLE, AR5K_IER); |
1746 | ath5k_hw_reg_read(ah, AR5K_IER); | ||
1690 | 1747 | ||
1691 | old_mask = ah->ah_imr; | 1748 | old_mask = ah->ah_imr; |
1692 | 1749 | ||
@@ -3363,11 +3420,13 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) | |||
3363 | ath5k_hw_reg_write(ah, ah->ah_turbo ? | 3420 | ath5k_hw_reg_write(ah, ah->ah_turbo ? |
3364 | AR5K_INIT_PROTO_TIME_CNTRL_TURBO : | 3421 | AR5K_INIT_PROTO_TIME_CNTRL_TURBO : |
3365 | AR5K_INIT_PROTO_TIME_CNTRL, AR5K_IFS1); | 3422 | AR5K_INIT_PROTO_TIME_CNTRL, AR5K_IFS1); |
3366 | /* Set PHY register 0x9844 (??) */ | 3423 | /* Set AR5K_PHY_SETTLING */ |
3367 | ath5k_hw_reg_write(ah, ah->ah_turbo ? | 3424 | ath5k_hw_reg_write(ah, ah->ah_turbo ? |
3368 | (ath5k_hw_reg_read(ah, AR5K_PHY(17)) & ~0x7F) | 0x38 : | 3425 | (ath5k_hw_reg_read(ah, AR5K_PHY_SETTLING) & ~0x7F) |
3369 | (ath5k_hw_reg_read(ah, AR5K_PHY(17)) & ~0x7F) | 0x1C, | 3426 | | 0x38 : |
3370 | AR5K_PHY(17)); | 3427 | (ath5k_hw_reg_read(ah, AR5K_PHY_SETTLING) & ~0x7F) |
3428 | | 0x1C, | ||
3429 | AR5K_PHY_SETTLING); | ||
3371 | /* Set Frame Control Register */ | 3430 | /* Set Frame Control Register */ |
3372 | ath5k_hw_reg_write(ah, ah->ah_turbo ? | 3431 | ath5k_hw_reg_write(ah, ah->ah_turbo ? |
3373 | (AR5K_PHY_FRAME_CTL_INI | AR5K_PHY_TURBO_MODE | | 3432 | (AR5K_PHY_FRAME_CTL_INI | AR5K_PHY_TURBO_MODE | |
@@ -3488,7 +3547,7 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) | |||
3488 | if (tq->tqi_flags & AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE) | 3547 | if (tq->tqi_flags & AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE) |
3489 | AR5K_REG_ENABLE_BITS(ah, | 3548 | AR5K_REG_ENABLE_BITS(ah, |
3490 | AR5K_QUEUE_MISC(queue), | 3549 | AR5K_QUEUE_MISC(queue), |
3491 | AR5K_QCU_MISC_TXE); | 3550 | AR5K_QCU_MISC_RDY_VEOL_POLICY); |
3492 | } | 3551 | } |
3493 | 3552 | ||
3494 | if (tq->tqi_flags & AR5K_TXQ_FLAG_BACKOFF_DISABLE) | 3553 | if (tq->tqi_flags & AR5K_TXQ_FLAG_BACKOFF_DISABLE) |