aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath5k/reset.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath5k/reset.c')
-rw-r--r--drivers/net/wireless/ath/ath5k/reset.c69
1 files changed, 32 insertions, 37 deletions
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
index 34e13c700849..cbf28e379843 100644
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -25,6 +25,8 @@
25 Reset functions and helpers 25 Reset functions and helpers
26\*****************************/ 26\*****************************/
27 27
28#include <asm/unaligned.h>
29
28#include <linux/pci.h> /* To determine if a card is pci-e */ 30#include <linux/pci.h> /* To determine if a card is pci-e */
29#include <linux/log2.h> 31#include <linux/log2.h>
30#include "ath5k.h" 32#include "ath5k.h"
@@ -58,12 +60,11 @@ static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah,
58 !(channel->hw_value & CHANNEL_OFDM)); 60 !(channel->hw_value & CHANNEL_OFDM));
59 61
60 /* Get coefficient 62 /* Get coefficient
61 * ALGO: coef = (5 * clock * carrier_freq) / 2) 63 * ALGO: coef = (5 * clock / carrier_freq) / 2
62 * we scale coef by shifting clock value by 24 for 64 * we scale coef by shifting clock value by 24 for
63 * better precision since we use integers */ 65 * better precision since we use integers */
64 /* TODO: Half/quarter rate */ 66 /* TODO: Half/quarter rate */
65 clock = ath5k_hw_htoclock(1, channel->hw_value & CHANNEL_TURBO); 67 clock = (channel->hw_value & CHANNEL_TURBO) ? 80 : 40;
66
67 coef_scaled = ((5 * (clock << 24)) / 2) / channel->center_freq; 68 coef_scaled = ((5 * (clock << 24)) / 2) / channel->center_freq;
68 69
69 /* Get exponent 70 /* Get exponent
@@ -850,12 +851,15 @@ static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah,
850 AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1, 851 AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1,
851 AR5K_INIT_CYCRSSI_THR1); 852 AR5K_INIT_CYCRSSI_THR1);
852 853
853 /* I/Q correction 854 /* I/Q correction (set enable bit last to match HAL sources) */
854 * TODO: Per channel i/q infos ? */ 855 /* TODO: Per channel i/q infos ? */
855 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, 856 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) {
856 AR5K_PHY_IQ_CORR_ENABLE | 857 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_Q_I_COFF,
857 (ee->ee_i_cal[ee_mode] << AR5K_PHY_IQ_CORR_Q_I_COFF_S) | 858 ee->ee_i_cal[ee_mode]);
858 ee->ee_q_cal[ee_mode]); 859 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_Q_Q_COFF,
860 ee->ee_q_cal[ee_mode]);
861 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_ENABLE);
862 }
859 863
860 /* Heavy clipping -disable for now */ 864 /* Heavy clipping -disable for now */
861 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_1) 865 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_1)
@@ -870,6 +874,7 @@ static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah,
870int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, 874int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
871 struct ieee80211_channel *channel, bool change_channel) 875 struct ieee80211_channel *channel, bool change_channel)
872{ 876{
877 struct ath_common *common = ath5k_hw_common(ah);
873 u32 s_seq[10], s_ant, s_led[3], staid1_flags, tsf_up, tsf_lo; 878 u32 s_seq[10], s_ant, s_led[3], staid1_flags, tsf_up, tsf_lo;
874 u32 phy_tst1; 879 u32 phy_tst1;
875 u8 mode, freq, ee_mode, ant[2]; 880 u8 mode, freq, ee_mode, ant[2];
@@ -1171,10 +1176,12 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1171 ath5k_hw_reg_write(ah, s_led[2], AR5K_GPIODO); 1176 ath5k_hw_reg_write(ah, s_led[2], AR5K_GPIODO);
1172 1177
1173 /* Restore sta_id flags and preserve our mac address*/ 1178 /* Restore sta_id flags and preserve our mac address*/
1174 ath5k_hw_reg_write(ah, AR5K_LOW_ID(ah->ah_sta_id), 1179 ath5k_hw_reg_write(ah,
1175 AR5K_STA_ID0); 1180 get_unaligned_le32(common->macaddr),
1176 ath5k_hw_reg_write(ah, staid1_flags | AR5K_HIGH_ID(ah->ah_sta_id), 1181 AR5K_STA_ID0);
1177 AR5K_STA_ID1); 1182 ath5k_hw_reg_write(ah,
1183 staid1_flags | get_unaligned_le16(common->macaddr + 4),
1184 AR5K_STA_ID1);
1178 1185
1179 1186
1180 /* 1187 /*
@@ -1182,8 +1189,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1182 */ 1189 */
1183 1190
1184 /* Restore bssid and bssid mask */ 1191 /* Restore bssid and bssid mask */
1185 /* XXX: add ah->aid once mac80211 gives this to us */ 1192 ath5k_hw_set_associd(ah);
1186 ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
1187 1193
1188 /* Set PCU config */ 1194 /* Set PCU config */
1189 ath5k_hw_set_opmode(ah); 1195 ath5k_hw_set_opmode(ah);
@@ -1289,7 +1295,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1289 * out and/or noise floor calibration might timeout. 1295 * out and/or noise floor calibration might timeout.
1290 */ 1296 */
1291 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL, 1297 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
1292 AR5K_PHY_AGCCTL_CAL); 1298 AR5K_PHY_AGCCTL_CAL | AR5K_PHY_AGCCTL_NF);
1293 1299
1294 /* At the same time start I/Q calibration for QAM constellation 1300 /* At the same time start I/Q calibration for QAM constellation
1295 * -no need for CCK- */ 1301 * -no need for CCK- */
@@ -1310,24 +1316,13 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1310 channel->center_freq); 1316 channel->center_freq);
1311 } 1317 }
1312 1318
1313 /*
1314 * If we run NF calibration before AGC, it always times out.
1315 * Binary HAL starts NF and AGC calibration at the same time
1316 * and only waits for AGC to finish. Also if AGC or NF cal.
1317 * times out, reset doesn't fail on binary HAL. I believe
1318 * that's wrong because since rx path is routed to a detector,
1319 * if cal. doesn't finish we won't have RX. Sam's HAL for AR5210/5211
1320 * enables noise floor calibration after offset calibration and if noise
1321 * floor calibration fails, reset fails. I believe that's
1322 * a better approach, we just need to find a polling interval
1323 * that suits best, even if reset continues we need to make
1324 * sure that rx path is ready.
1325 */
1326 ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
1327
1328 /* Restore antenna mode */ 1319 /* Restore antenna mode */
1329 ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode); 1320 ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode);
1330 1321
1322 /* Restore slot time and ACK timeouts */
1323 if (ah->ah_coverage_class > 0)
1324 ath5k_hw_set_coverage_class(ah, ah->ah_coverage_class);
1325
1331 /* 1326 /*
1332 * Configure QCUs/DCUs 1327 * Configure QCUs/DCUs
1333 */ 1328 */
@@ -1382,15 +1377,15 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1382 * Set clocks to 32KHz operation and use an 1377 * Set clocks to 32KHz operation and use an
1383 * external 32KHz crystal when sleeping if one 1378 * external 32KHz crystal when sleeping if one
1384 * exists */ 1379 * exists */
1385 if (ah->ah_version == AR5K_AR5212) 1380 if (ah->ah_version == AR5K_AR5212 &&
1386 ath5k_hw_set_sleep_clock(ah, true); 1381 ah->ah_op_mode != NL80211_IFTYPE_AP)
1382 ath5k_hw_set_sleep_clock(ah, true);
1387 1383
1388 /* 1384 /*
1389 * Disable beacons and reset the register 1385 * Disable beacons and reset the TSF
1390 */ 1386 */
1391 AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE | 1387 AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE);
1392 AR5K_BEACON_RESET_TSF); 1388 ath5k_hw_reset_tsf(ah);
1393
1394 return 0; 1389 return 0;
1395} 1390}
1396 1391