diff options
author | Nick Kossifidis <mick@madwifi-project.org> | 2009-02-08 23:12:58 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-02-13 13:44:49 -0500 |
commit | e8f055f0c3ba226ca599c14c2e5fe829f6f57cbb (patch) | |
tree | 02479a6c4aaa388b13866f0fb596433630863083 /drivers/net/wireless/ath5k | |
parent | a406c139091902acebafb2462b64ba498901e820 (diff) |
ath5k: Update reset code
* Update reset and sync with HALs
* Clean up eeprom settings and tweaking of initvals and
put them on separate functions
* Set/Restore 32KHz ref clk operation
* Add some more documentation
TODO: Spur mitigation, tpc, half/quarter rate, compression etc
v2: Address comments from Bob and Felix and fix RSSI threshold bug
introduced on the first version of the patch
Signed-off-by: Nick Kossifidis <mickflemm@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath5k')
-rw-r--r-- | drivers/net/wireless/ath5k/ath5k.h | 11 | ||||
-rw-r--r-- | drivers/net/wireless/ath5k/attach.c | 16 | ||||
-rw-r--r-- | drivers/net/wireless/ath5k/eeprom.c | 14 | ||||
-rw-r--r-- | drivers/net/wireless/ath5k/eeprom.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ath5k/reg.h | 56 | ||||
-rw-r--r-- | drivers/net/wireless/ath5k/reset.c | 930 |
6 files changed, 732 insertions, 296 deletions
diff --git a/drivers/net/wireless/ath5k/ath5k.h b/drivers/net/wireless/ath5k/ath5k.h index 5b2e0da0a226..b9af2b84c05f 100644 --- a/drivers/net/wireless/ath5k/ath5k.h +++ b/drivers/net/wireless/ath5k/ath5k.h | |||
@@ -222,6 +222,7 @@ | |||
222 | #endif | 222 | #endif |
223 | 223 | ||
224 | /* Initial values */ | 224 | /* Initial values */ |
225 | #define AR5K_INIT_CYCRSSI_THR1 2 | ||
225 | #define AR5K_INIT_TX_LATENCY 502 | 226 | #define AR5K_INIT_TX_LATENCY 502 |
226 | #define AR5K_INIT_USEC 39 | 227 | #define AR5K_INIT_USEC 39 |
227 | #define AR5K_INIT_USEC_TURBO 79 | 228 | #define AR5K_INIT_USEC_TURBO 79 |
@@ -313,7 +314,7 @@ struct ath5k_srev_name { | |||
313 | #define AR5K_SREV_AR5424 0x90 /* Condor */ | 314 | #define AR5K_SREV_AR5424 0x90 /* Condor */ |
314 | #define AR5K_SREV_AR5413 0xa4 /* Eagle lite */ | 315 | #define AR5K_SREV_AR5413 0xa4 /* Eagle lite */ |
315 | #define AR5K_SREV_AR5414 0xa0 /* Eagle */ | 316 | #define AR5K_SREV_AR5414 0xa0 /* Eagle */ |
316 | #define AR5K_SREV_AR2415 0xb0 /* Cobra */ | 317 | #define AR5K_SREV_AR2415 0xb0 /* Talon */ |
317 | #define AR5K_SREV_AR5416 0xc0 /* PCI-E */ | 318 | #define AR5K_SREV_AR5416 0xc0 /* PCI-E */ |
318 | #define AR5K_SREV_AR5418 0xca /* PCI-E */ | 319 | #define AR5K_SREV_AR5418 0xca /* PCI-E */ |
319 | #define AR5K_SREV_AR2425 0xe0 /* Swan */ | 320 | #define AR5K_SREV_AR2425 0xe0 /* Swan */ |
@@ -331,7 +332,7 @@ struct ath5k_srev_name { | |||
331 | #define AR5K_SREV_RAD_2112B 0x46 | 332 | #define AR5K_SREV_RAD_2112B 0x46 |
332 | #define AR5K_SREV_RAD_2413 0x50 | 333 | #define AR5K_SREV_RAD_2413 0x50 |
333 | #define AR5K_SREV_RAD_5413 0x60 | 334 | #define AR5K_SREV_RAD_5413 0x60 |
334 | #define AR5K_SREV_RAD_2316 0x70 | 335 | #define AR5K_SREV_RAD_2316 0x70 /* Cobra SoC */ |
335 | #define AR5K_SREV_RAD_2317 0x80 | 336 | #define AR5K_SREV_RAD_2317 0x80 |
336 | #define AR5K_SREV_RAD_5424 0xa0 /* Mostly same as 5413 */ | 337 | #define AR5K_SREV_RAD_5424 0xa0 /* Mostly same as 5413 */ |
337 | #define AR5K_SREV_RAD_2425 0xa2 | 338 | #define AR5K_SREV_RAD_2425 0xa2 |
@@ -340,7 +341,7 @@ struct ath5k_srev_name { | |||
340 | #define AR5K_SREV_PHY_5211 0x30 | 341 | #define AR5K_SREV_PHY_5211 0x30 |
341 | #define AR5K_SREV_PHY_5212 0x41 | 342 | #define AR5K_SREV_PHY_5212 0x41 |
342 | #define AR5K_SREV_PHY_5212A 0x42 | 343 | #define AR5K_SREV_PHY_5212A 0x42 |
343 | #define AR5K_SREV_PHY_2112B 0x43 | 344 | #define AR5K_SREV_PHY_5212B 0x43 |
344 | #define AR5K_SREV_PHY_2413 0x45 | 345 | #define AR5K_SREV_PHY_2413 0x45 |
345 | #define AR5K_SREV_PHY_5413 0x61 | 346 | #define AR5K_SREV_PHY_5413 0x61 |
346 | #define AR5K_SREV_PHY_2425 0x70 | 347 | #define AR5K_SREV_PHY_2425 0x70 |
@@ -1030,7 +1031,6 @@ struct ath5k_hw { | |||
1030 | u16 ah_phy_revision; | 1031 | u16 ah_phy_revision; |
1031 | u16 ah_radio_5ghz_revision; | 1032 | u16 ah_radio_5ghz_revision; |
1032 | u16 ah_radio_2ghz_revision; | 1033 | u16 ah_radio_2ghz_revision; |
1033 | u32 ah_phy_spending; | ||
1034 | 1034 | ||
1035 | enum ath5k_version ah_version; | 1035 | enum ath5k_version ah_version; |
1036 | enum ath5k_radio ah_radio; | 1036 | enum ath5k_radio ah_radio; |
@@ -1156,6 +1156,7 @@ extern void ath5k_hw_update_mib_counters(struct ath5k_hw *ah, struct ieee80211_l | |||
1156 | /* EEPROM access functions */ | 1156 | /* EEPROM access functions */ |
1157 | extern int ath5k_eeprom_init(struct ath5k_hw *ah); | 1157 | extern int ath5k_eeprom_init(struct ath5k_hw *ah); |
1158 | extern int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac); | 1158 | extern int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac); |
1159 | extern bool ath5k_eeprom_is_hb63(struct ath5k_hw *ah); | ||
1159 | 1160 | ||
1160 | /* Protocol Control Unit Functions */ | 1161 | /* Protocol Control Unit Functions */ |
1161 | extern int ath5k_hw_set_opmode(struct ath5k_hw *ah); | 1162 | extern int ath5k_hw_set_opmode(struct ath5k_hw *ah); |
@@ -1258,6 +1259,7 @@ extern int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, unsigned int power); | |||
1258 | 1259 | ||
1259 | /* | 1260 | /* |
1260 | * Translate usec to hw clock units | 1261 | * Translate usec to hw clock units |
1262 | * TODO: Half/quarter rate | ||
1261 | */ | 1263 | */ |
1262 | static inline unsigned int ath5k_hw_htoclock(unsigned int usec, bool turbo) | 1264 | static inline unsigned int ath5k_hw_htoclock(unsigned int usec, bool turbo) |
1263 | { | 1265 | { |
@@ -1266,6 +1268,7 @@ static inline unsigned int ath5k_hw_htoclock(unsigned int usec, bool turbo) | |||
1266 | 1268 | ||
1267 | /* | 1269 | /* |
1268 | * Translate hw clock units to usec | 1270 | * Translate hw clock units to usec |
1271 | * TODO: Half/quarter rate | ||
1269 | */ | 1272 | */ |
1270 | static inline unsigned int ath5k_hw_clocktoh(unsigned int clock, bool turbo) | 1273 | static inline unsigned int ath5k_hw_clocktoh(unsigned int clock, bool turbo) |
1271 | { | 1274 | { |
diff --git a/drivers/net/wireless/ath5k/attach.c b/drivers/net/wireless/ath5k/attach.c index a3f07a4ebf41..05bc5cb44e88 100644 --- a/drivers/net/wireless/ath5k/attach.c +++ b/drivers/net/wireless/ath5k/attach.c | |||
@@ -169,7 +169,6 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version) | |||
169 | ah->ah_single_chip = false; | 169 | ah->ah_single_chip = false; |
170 | ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah, | 170 | ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah, |
171 | CHANNEL_2GHZ); | 171 | CHANNEL_2GHZ); |
172 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5111; | ||
173 | break; | 172 | break; |
174 | case AR5K_SREV_RAD_5112: | 173 | case AR5K_SREV_RAD_5112: |
175 | case AR5K_SREV_RAD_2112: | 174 | case AR5K_SREV_RAD_2112: |
@@ -177,38 +176,31 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version) | |||
177 | ah->ah_single_chip = false; | 176 | ah->ah_single_chip = false; |
178 | ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah, | 177 | ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah, |
179 | CHANNEL_2GHZ); | 178 | CHANNEL_2GHZ); |
180 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112; | ||
181 | break; | 179 | break; |
182 | case AR5K_SREV_RAD_2413: | 180 | case AR5K_SREV_RAD_2413: |
183 | ah->ah_radio = AR5K_RF2413; | 181 | ah->ah_radio = AR5K_RF2413; |
184 | ah->ah_single_chip = true; | 182 | ah->ah_single_chip = true; |
185 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2413; | ||
186 | break; | 183 | break; |
187 | case AR5K_SREV_RAD_5413: | 184 | case AR5K_SREV_RAD_5413: |
188 | ah->ah_radio = AR5K_RF5413; | 185 | ah->ah_radio = AR5K_RF5413; |
189 | ah->ah_single_chip = true; | 186 | ah->ah_single_chip = true; |
190 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5413; | ||
191 | break; | 187 | break; |
192 | case AR5K_SREV_RAD_2316: | 188 | case AR5K_SREV_RAD_2316: |
193 | ah->ah_radio = AR5K_RF2316; | 189 | ah->ah_radio = AR5K_RF2316; |
194 | ah->ah_single_chip = true; | 190 | ah->ah_single_chip = true; |
195 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2316; | ||
196 | break; | 191 | break; |
197 | case AR5K_SREV_RAD_2317: | 192 | case AR5K_SREV_RAD_2317: |
198 | ah->ah_radio = AR5K_RF2317; | 193 | ah->ah_radio = AR5K_RF2317; |
199 | ah->ah_single_chip = true; | 194 | ah->ah_single_chip = true; |
200 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2317; | ||
201 | break; | 195 | break; |
202 | case AR5K_SREV_RAD_5424: | 196 | case AR5K_SREV_RAD_5424: |
203 | if (ah->ah_mac_version == AR5K_SREV_AR2425 || | 197 | if (ah->ah_mac_version == AR5K_SREV_AR2425 || |
204 | ah->ah_mac_version == AR5K_SREV_AR2417){ | 198 | ah->ah_mac_version == AR5K_SREV_AR2417){ |
205 | ah->ah_radio = AR5K_RF2425; | 199 | ah->ah_radio = AR5K_RF2425; |
206 | ah->ah_single_chip = true; | 200 | ah->ah_single_chip = true; |
207 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2425; | ||
208 | } else { | 201 | } else { |
209 | ah->ah_radio = AR5K_RF5413; | 202 | ah->ah_radio = AR5K_RF5413; |
210 | ah->ah_single_chip = true; | 203 | ah->ah_single_chip = true; |
211 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5413; | ||
212 | } | 204 | } |
213 | break; | 205 | break; |
214 | default: | 206 | default: |
@@ -227,29 +219,25 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version) | |||
227 | ah->ah_radio = AR5K_RF2425; | 219 | ah->ah_radio = AR5K_RF2425; |
228 | ah->ah_single_chip = true; | 220 | ah->ah_single_chip = true; |
229 | ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2425; | 221 | ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2425; |
230 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2425; | ||
231 | } else if (srev == AR5K_SREV_AR5213A && | 222 | } else if (srev == AR5K_SREV_AR5213A && |
232 | ah->ah_phy_revision == AR5K_SREV_PHY_2112B) { | 223 | ah->ah_phy_revision == AR5K_SREV_PHY_5212B) { |
233 | ah->ah_radio = AR5K_RF5112; | 224 | ah->ah_radio = AR5K_RF5112; |
234 | ah->ah_single_chip = false; | 225 | ah->ah_single_chip = false; |
235 | ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2112B; | 226 | ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_5112B; |
236 | } else if (ah->ah_mac_version == (AR5K_SREV_AR2415 >> 4)) { | 227 | } else if (ah->ah_mac_version == (AR5K_SREV_AR2415 >> 4)) { |
237 | ah->ah_radio = AR5K_RF2316; | 228 | ah->ah_radio = AR5K_RF2316; |
238 | ah->ah_single_chip = true; | 229 | ah->ah_single_chip = true; |
239 | ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2316; | 230 | ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2316; |
240 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2316; | ||
241 | } else if (ah->ah_mac_version == (AR5K_SREV_AR5414 >> 4) || | 231 | } else if (ah->ah_mac_version == (AR5K_SREV_AR5414 >> 4) || |
242 | ah->ah_phy_revision == AR5K_SREV_PHY_5413) { | 232 | ah->ah_phy_revision == AR5K_SREV_PHY_5413) { |
243 | ah->ah_radio = AR5K_RF5413; | 233 | ah->ah_radio = AR5K_RF5413; |
244 | ah->ah_single_chip = true; | 234 | ah->ah_single_chip = true; |
245 | ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_5413; | 235 | ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_5413; |
246 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5413; | ||
247 | } else if (ah->ah_mac_version == (AR5K_SREV_AR2414 >> 4) || | 236 | } else if (ah->ah_mac_version == (AR5K_SREV_AR2414 >> 4) || |
248 | ah->ah_phy_revision == AR5K_SREV_PHY_2413) { | 237 | ah->ah_phy_revision == AR5K_SREV_PHY_2413) { |
249 | ah->ah_radio = AR5K_RF2413; | 238 | ah->ah_radio = AR5K_RF2413; |
250 | ah->ah_single_chip = true; | 239 | ah->ah_single_chip = true; |
251 | ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2413; | 240 | ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2413; |
252 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2413; | ||
253 | } else { | 241 | } else { |
254 | ATH5K_ERR(sc, "Couldn't identify radio revision.\n"); | 242 | ATH5K_ERR(sc, "Couldn't identify radio revision.\n"); |
255 | ret = -ENODEV; | 243 | ret = -ENODEV; |
diff --git a/drivers/net/wireless/ath5k/eeprom.c b/drivers/net/wireless/ath5k/eeprom.c index b4ec539c464b..21b9334eeaf2 100644 --- a/drivers/net/wireless/ath5k/eeprom.c +++ b/drivers/net/wireless/ath5k/eeprom.c | |||
@@ -204,7 +204,7 @@ static int ath5k_eeprom_read_ants(struct ath5k_hw *ah, u32 *offset, | |||
204 | 204 | ||
205 | /* Get antenna modes */ | 205 | /* Get antenna modes */ |
206 | ah->ah_antenna[mode][0] = | 206 | ah->ah_antenna[mode][0] = |
207 | (ee->ee_ant_control[mode][0] << 4) | 0x1; | 207 | (ee->ee_ant_control[mode][0] << 4); |
208 | ah->ah_antenna[mode][AR5K_ANT_FIXED_A] = | 208 | ah->ah_antenna[mode][AR5K_ANT_FIXED_A] = |
209 | ee->ee_ant_control[mode][1] | | 209 | ee->ee_ant_control[mode][1] | |
210 | (ee->ee_ant_control[mode][2] << 6) | | 210 | (ee->ee_ant_control[mode][2] << 6) | |
@@ -1412,6 +1412,7 @@ ath5k_eeprom_init(struct ath5k_hw *ah) | |||
1412 | 1412 | ||
1413 | return 0; | 1413 | return 0; |
1414 | } | 1414 | } |
1415 | |||
1415 | /* | 1416 | /* |
1416 | * Read the MAC address from eeprom | 1417 | * Read the MAC address from eeprom |
1417 | */ | 1418 | */ |
@@ -1448,3 +1449,14 @@ int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac) | |||
1448 | return 0; | 1449 | return 0; |
1449 | } | 1450 | } |
1450 | 1451 | ||
1452 | bool ath5k_eeprom_is_hb63(struct ath5k_hw *ah) | ||
1453 | { | ||
1454 | u16 data; | ||
1455 | |||
1456 | ath5k_hw_eeprom_read(ah, AR5K_EEPROM_IS_HB63, &data); | ||
1457 | |||
1458 | if ((ah->ah_mac_version == (AR5K_SREV_AR2425 >> 4)) && data) | ||
1459 | return true; | ||
1460 | else | ||
1461 | return false; | ||
1462 | } | ||
diff --git a/drivers/net/wireless/ath5k/eeprom.h b/drivers/net/wireless/ath5k/eeprom.h index 09eb7d0176a4..1deebc0257d4 100644 --- a/drivers/net/wireless/ath5k/eeprom.h +++ b/drivers/net/wireless/ath5k/eeprom.h | |||
@@ -25,6 +25,7 @@ | |||
25 | #define AR5K_EEPROM_MAGIC_5211 0x0000145b /* 5211 */ | 25 | #define AR5K_EEPROM_MAGIC_5211 0x0000145b /* 5211 */ |
26 | #define AR5K_EEPROM_MAGIC_5210 0x0000145a /* 5210 */ | 26 | #define AR5K_EEPROM_MAGIC_5210 0x0000145a /* 5210 */ |
27 | 27 | ||
28 | #define AR5K_EEPROM_IS_HB63 0x000b /* Talon detect */ | ||
28 | #define AR5K_EEPROM_REG_DOMAIN 0x00bf /* EEPROM regdom */ | 29 | #define AR5K_EEPROM_REG_DOMAIN 0x00bf /* EEPROM regdom */ |
29 | #define AR5K_EEPROM_CHECKSUM 0x00c0 /* EEPROM checksum */ | 30 | #define AR5K_EEPROM_CHECKSUM 0x00c0 /* EEPROM checksum */ |
30 | #define AR5K_EEPROM_INFO_BASE 0x00c0 /* EEPROM header */ | 31 | #define AR5K_EEPROM_INFO_BASE 0x00c0 /* EEPROM header */ |
diff --git a/drivers/net/wireless/ath5k/reg.h b/drivers/net/wireless/ath5k/reg.h index 84f4669278a7..2dc008e10226 100644 --- a/drivers/net/wireless/ath5k/reg.h +++ b/drivers/net/wireless/ath5k/reg.h | |||
@@ -187,6 +187,7 @@ | |||
187 | #define AR5K_TXCFG_FRMPAD_DIS 0x00002000 /* [5211+] */ | 187 | #define AR5K_TXCFG_FRMPAD_DIS 0x00002000 /* [5211+] */ |
188 | #define AR5K_TXCFG_RDY_CBR_DIS 0x00004000 /* Ready time CBR disable [5211+] */ | 188 | #define AR5K_TXCFG_RDY_CBR_DIS 0x00004000 /* Ready time CBR disable [5211+] */ |
189 | #define AR5K_TXCFG_JUMBO_FRM_MODE 0x00008000 /* Jumbo frame mode [5211+] */ | 189 | #define AR5K_TXCFG_JUMBO_FRM_MODE 0x00008000 /* Jumbo frame mode [5211+] */ |
190 | #define AR5K_TXCFG_DCU_DBL_BUF_DIS 0x00008000 /* Disable double buffering on DCU */ | ||
190 | #define AR5K_TXCFG_DCU_CACHING_DIS 0x00010000 /* Disable DCU caching */ | 191 | #define AR5K_TXCFG_DCU_CACHING_DIS 0x00010000 /* Disable DCU caching */ |
191 | 192 | ||
192 | /* | 193 | /* |
@@ -753,7 +754,7 @@ | |||
753 | */ | 754 | */ |
754 | #define AR5K_DCU_SEQNUM_BASE 0x1140 | 755 | #define AR5K_DCU_SEQNUM_BASE 0x1140 |
755 | #define AR5K_DCU_SEQNUM_M 0x00000fff | 756 | #define AR5K_DCU_SEQNUM_M 0x00000fff |
756 | #define AR5K_QUEUE_DFS_SEQNUM(_q) AR5K_QUEUE_REG(AR5K_DCU_SEQNUM_BASE, _q) | 757 | #define AR5K_QUEUE_DCU_SEQNUM(_q) AR5K_QUEUE_REG(AR5K_DCU_SEQNUM_BASE, _q) |
757 | 758 | ||
758 | /* | 759 | /* |
759 | * DCU global IFS SIFS register | 760 | * DCU global IFS SIFS register |
@@ -1467,7 +1468,7 @@ | |||
1467 | #define AR5K_ADDAC_TEST_TRIG_PTY 0x00020000 /* Trigger polarity */ | 1468 | #define AR5K_ADDAC_TEST_TRIG_PTY 0x00020000 /* Trigger polarity */ |
1468 | #define AR5K_ADDAC_TEST_RXCONT 0x00040000 /* Continuous capture */ | 1469 | #define AR5K_ADDAC_TEST_RXCONT 0x00040000 /* Continuous capture */ |
1469 | #define AR5K_ADDAC_TEST_CAPTURE 0x00080000 /* Begin capture */ | 1470 | #define AR5K_ADDAC_TEST_CAPTURE 0x00080000 /* Begin capture */ |
1470 | #define AR5K_ADDAC_TEST_TST_ARM 0x00100000 /* Test ARM (Adaptive Radio Mode ?) */ | 1471 | #define AR5K_ADDAC_TEST_TST_ARM 0x00100000 /* ARM rx buffer for capture */ |
1471 | 1472 | ||
1472 | /* | 1473 | /* |
1473 | * Default antenna register [5211+] | 1474 | * Default antenna register [5211+] |
@@ -1679,7 +1680,7 @@ | |||
1679 | * TSF parameter register | 1680 | * TSF parameter register |
1680 | */ | 1681 | */ |
1681 | #define AR5K_TSF_PARM 0x8104 /* Register Address */ | 1682 | #define AR5K_TSF_PARM 0x8104 /* Register Address */ |
1682 | #define AR5K_TSF_PARM_INC_M 0x000000ff /* Mask for TSF increment */ | 1683 | #define AR5K_TSF_PARM_INC 0x000000ff /* Mask for TSF increment */ |
1683 | #define AR5K_TSF_PARM_INC_S 0 | 1684 | #define AR5K_TSF_PARM_INC_S 0 |
1684 | 1685 | ||
1685 | /* | 1686 | /* |
@@ -1691,7 +1692,7 @@ | |||
1691 | #define AR5K_QOS_NOACK_BIT_OFFSET 0x00000070 /* ??? */ | 1692 | #define AR5K_QOS_NOACK_BIT_OFFSET 0x00000070 /* ??? */ |
1692 | #define AR5K_QOS_NOACK_BIT_OFFSET_S 4 | 1693 | #define AR5K_QOS_NOACK_BIT_OFFSET_S 4 |
1693 | #define AR5K_QOS_NOACK_BYTE_OFFSET 0x00000180 /* ??? */ | 1694 | #define AR5K_QOS_NOACK_BYTE_OFFSET 0x00000180 /* ??? */ |
1694 | #define AR5K_QOS_NOACK_BYTE_OFFSET_S 8 | 1695 | #define AR5K_QOS_NOACK_BYTE_OFFSET_S 7 |
1695 | 1696 | ||
1696 | /* | 1697 | /* |
1697 | * PHY error filter register | 1698 | * PHY error filter register |
@@ -1850,15 +1851,14 @@ | |||
1850 | * TST_2 (Misc config parameters) | 1851 | * TST_2 (Misc config parameters) |
1851 | */ | 1852 | */ |
1852 | #define AR5K_PHY_TST2 0x9800 /* Register Address */ | 1853 | #define AR5K_PHY_TST2 0x9800 /* Register Address */ |
1853 | #define AR5K_PHY_TST2_TRIG_SEL 0x00000001 /* Trigger select (?) (field ?) */ | 1854 | #define AR5K_PHY_TST2_TRIG_SEL 0x00000007 /* Trigger select (?)*/ |
1854 | #define AR5K_PHY_TST2_TRIG 0x00000010 /* Trigger (?) (field ?) */ | 1855 | #define AR5K_PHY_TST2_TRIG 0x00000010 /* Trigger (?) */ |
1855 | #define AR5K_PHY_TST2_CBUS_MODE 0x00000100 /* Cardbus mode (?) */ | 1856 | #define AR5K_PHY_TST2_CBUS_MODE 0x00000060 /* Cardbus mode (?) */ |
1856 | /* bit reserved */ | ||
1857 | #define AR5K_PHY_TST2_CLK32 0x00000400 /* CLK_OUT is CLK32 (32Khz external) */ | 1857 | #define AR5K_PHY_TST2_CLK32 0x00000400 /* CLK_OUT is CLK32 (32Khz external) */ |
1858 | #define AR5K_PHY_TST2_CHANCOR_DUMP_EN 0x00000800 /* Enable Chancor dump (?) */ | 1858 | #define AR5K_PHY_TST2_CHANCOR_DUMP_EN 0x00000800 /* Enable Chancor dump (?) */ |
1859 | #define AR5K_PHY_TST2_EVEN_CHANCOR_DUMP 0x00001000 /* Even Chancor dump (?) */ | 1859 | #define AR5K_PHY_TST2_EVEN_CHANCOR_DUMP 0x00001000 /* Even Chancor dump (?) */ |
1860 | #define AR5K_PHY_TST2_RFSILENT_EN 0x00002000 /* Enable RFSILENT */ | 1860 | #define AR5K_PHY_TST2_RFSILENT_EN 0x00002000 /* Enable RFSILENT */ |
1861 | #define AR5K_PHY_TST2_ALT_RFDATA 0x00004000 /* Alternate RFDATA (5-2GHz switch) */ | 1861 | #define AR5K_PHY_TST2_ALT_RFDATA 0x00004000 /* Alternate RFDATA (5-2GHz switch ?) */ |
1862 | #define AR5K_PHY_TST2_MINI_OBS_EN 0x00008000 /* Enable mini OBS (?) */ | 1862 | #define AR5K_PHY_TST2_MINI_OBS_EN 0x00008000 /* Enable mini OBS (?) */ |
1863 | #define AR5K_PHY_TST2_RX2_IS_RX5_INV 0x00010000 /* 2GHz rx path is the 5GHz path inverted (?) */ | 1863 | #define AR5K_PHY_TST2_RX2_IS_RX5_INV 0x00010000 /* 2GHz rx path is the 5GHz path inverted (?) */ |
1864 | #define AR5K_PHY_TST2_SLOW_CLK160 0x00020000 /* Slow CLK160 (?) */ | 1864 | #define AR5K_PHY_TST2_SLOW_CLK160 0x00020000 /* Slow CLK160 (?) */ |
@@ -1928,8 +1928,8 @@ | |||
1928 | #define AR5K_PHY_RF_CTL2_TXF2TXD_START_S 0 | 1928 | #define AR5K_PHY_RF_CTL2_TXF2TXD_START_S 0 |
1929 | 1929 | ||
1930 | #define AR5K_PHY_RF_CTL3 0x9828 /* Register Address */ | 1930 | #define AR5K_PHY_RF_CTL3 0x9828 /* Register Address */ |
1931 | #define AR5K_PHY_RF_CTL3_TXE2XLNA_ON 0x0000000f /* TX end to XLNA on */ | 1931 | #define AR5K_PHY_RF_CTL3_TXE2XLNA_ON 0x0000ff00 /* TX end to XLNA on */ |
1932 | #define AR5K_PHY_RF_CTL3_TXE2XLNA_ON_S 0 | 1932 | #define AR5K_PHY_RF_CTL3_TXE2XLNA_ON_S 8 |
1933 | 1933 | ||
1934 | #define AR5K_PHY_ADC_CTL 0x982c | 1934 | #define AR5K_PHY_ADC_CTL 0x982c |
1935 | #define AR5K_PHY_ADC_CTL_INBUFGAIN_OFF 0x00000003 | 1935 | #define AR5K_PHY_ADC_CTL_INBUFGAIN_OFF 0x00000003 |
@@ -1963,7 +1963,7 @@ | |||
1963 | #define AR5K_PHY_SETTLING_AGC 0x0000007f /* AGC settling time */ | 1963 | #define AR5K_PHY_SETTLING_AGC 0x0000007f /* AGC settling time */ |
1964 | #define AR5K_PHY_SETTLING_AGC_S 0 | 1964 | #define AR5K_PHY_SETTLING_AGC_S 0 |
1965 | #define AR5K_PHY_SETTLING_SWITCH 0x00003f80 /* Switch settlig time */ | 1965 | #define AR5K_PHY_SETTLING_SWITCH 0x00003f80 /* Switch settlig time */ |
1966 | #define AR5K_PHY_SETTLINK_SWITCH_S 7 | 1966 | #define AR5K_PHY_SETTLING_SWITCH_S 7 |
1967 | 1967 | ||
1968 | /* | 1968 | /* |
1969 | * PHY Gain registers | 1969 | * PHY Gain registers |
@@ -2069,14 +2069,14 @@ | |||
2069 | * PHY sleep registers [5112+] | 2069 | * PHY sleep registers [5112+] |
2070 | */ | 2070 | */ |
2071 | #define AR5K_PHY_SCR 0x9870 | 2071 | #define AR5K_PHY_SCR 0x9870 |
2072 | #define AR5K_PHY_SCR_32MHZ 0x0000001f | ||
2073 | 2072 | ||
2074 | #define AR5K_PHY_SLMT 0x9874 | 2073 | #define AR5K_PHY_SLMT 0x9874 |
2075 | #define AR5K_PHY_SLMT_32MHZ 0x0000007f | 2074 | #define AR5K_PHY_SLMT_32MHZ 0x0000007f |
2076 | 2075 | ||
2077 | #define AR5K_PHY_SCAL 0x9878 | 2076 | #define AR5K_PHY_SCAL 0x9878 |
2078 | #define AR5K_PHY_SCAL_32MHZ 0x0000000e | 2077 | #define AR5K_PHY_SCAL_32MHZ 0x0000000e |
2079 | 2078 | #define AR5K_PHY_SCAL_32MHZ_2417 0x0000000a | |
2079 | #define AR5K_PHY_SCAL_32MHZ_HB63 0x00000032 | ||
2080 | 2080 | ||
2081 | /* | 2081 | /* |
2082 | * PHY PLL (Phase Locked Loop) control register | 2082 | * PHY PLL (Phase Locked Loop) control register |
@@ -2156,7 +2156,8 @@ | |||
2156 | #define AR5K_PHY_ANT_CTL_TXRX_EN 0x00000001 /* Enable TX/RX (?) */ | 2156 | #define AR5K_PHY_ANT_CTL_TXRX_EN 0x00000001 /* Enable TX/RX (?) */ |
2157 | #define AR5K_PHY_ANT_CTL_SECTORED_ANT 0x00000004 /* Sectored Antenna */ | 2157 | #define AR5K_PHY_ANT_CTL_SECTORED_ANT 0x00000004 /* Sectored Antenna */ |
2158 | #define AR5K_PHY_ANT_CTL_HITUNE5 0x00000008 /* Hitune5 (?) */ | 2158 | #define AR5K_PHY_ANT_CTL_HITUNE5 0x00000008 /* Hitune5 (?) */ |
2159 | #define AR5K_PHY_ANT_CTL_SWTABLE_IDLE 0x00000010 /* Switch table idle (?) */ | 2159 | #define AR5K_PHY_ANT_CTL_SWTABLE_IDLE 0x000003f0 /* Switch table idle (?) */ |
2160 | #define AR5K_PHY_ANT_CTL_SWTABLE_IDLE_S 4 | ||
2160 | 2161 | ||
2161 | /* | 2162 | /* |
2162 | * PHY receiver delay register [5111+] | 2163 | * PHY receiver delay register [5111+] |
@@ -2196,7 +2197,7 @@ | |||
2196 | #define AR5K_PHY_OFDM_SELFCORR 0x9924 /* Register Address */ | 2197 | #define AR5K_PHY_OFDM_SELFCORR 0x9924 /* Register Address */ |
2197 | #define AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1_EN 0x00000001 /* Enable cyclic RSSI thr 1 */ | 2198 | #define AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1_EN 0x00000001 /* Enable cyclic RSSI thr 1 */ |
2198 | #define AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1 0x000000fe /* Mask for Cyclic RSSI threshold 1 */ | 2199 | #define AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1 0x000000fe /* Mask for Cyclic RSSI threshold 1 */ |
2199 | #define AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1_S 0 | 2200 | #define AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1_S 1 |
2200 | #define AR5K_PHY_OFDM_SELFCORR_CYPWR_THR3 0x00000100 /* Cyclic RSSI threshold 3 (field) (?) */ | 2201 | #define AR5K_PHY_OFDM_SELFCORR_CYPWR_THR3 0x00000100 /* Cyclic RSSI threshold 3 (field) (?) */ |
2201 | #define AR5K_PHY_OFDM_SELFCORR_RSSI_1ATHR_EN 0x00008000 /* Enable 1A RSSI threshold (?) */ | 2202 | #define AR5K_PHY_OFDM_SELFCORR_RSSI_1ATHR_EN 0x00008000 /* Enable 1A RSSI threshold (?) */ |
2202 | #define AR5K_PHY_OFDM_SELFCORR_RSSI_1ATHR 0x00010000 /* 1A RSSI threshold (field) (?) */ | 2203 | #define AR5K_PHY_OFDM_SELFCORR_RSSI_1ATHR 0x00010000 /* 1A RSSI threshold (field) (?) */ |
@@ -2279,6 +2280,15 @@ | |||
2279 | AR5K_PHY_FRAME_CTL_TIMING_ERR | 2280 | AR5K_PHY_FRAME_CTL_TIMING_ERR |
2280 | 2281 | ||
2281 | /* | 2282 | /* |
2283 | * PHY Tx Power adjustment register [5212A+] | ||
2284 | */ | ||
2285 | #define AR5K_PHY_TX_PWR_ADJ 0x994c | ||
2286 | #define AR5K_PHY_TX_PWR_ADJ_CCK_GAIN_DELTA 0x00000fc0 | ||
2287 | #define AR5K_PHY_TX_PWR_ADJ_CCK_GAIN_DELTA_S 6 | ||
2288 | #define AR5K_PHY_TX_PWR_ADJ_CCK_PCDAC_INDEX 0x00fc0000 | ||
2289 | #define AR5K_PHY_TX_PWR_ADJ_CCK_PCDAC_INDEX_S 18 | ||
2290 | |||
2291 | /* | ||
2282 | * PHY radar detection register [5111+] | 2292 | * PHY radar detection register [5111+] |
2283 | */ | 2293 | */ |
2284 | #define AR5K_PHY_RADAR 0x9954 | 2294 | #define AR5K_PHY_RADAR 0x9954 |
@@ -2331,7 +2341,7 @@ | |||
2331 | #define AR5K_PHY_SIGMA_DELTA_FILT2_S 3 | 2341 | #define AR5K_PHY_SIGMA_DELTA_FILT2_S 3 |
2332 | #define AR5K_PHY_SIGMA_DELTA_FILT1 0x00001f00 | 2342 | #define AR5K_PHY_SIGMA_DELTA_FILT1 0x00001f00 |
2333 | #define AR5K_PHY_SIGMA_DELTA_FILT1_S 8 | 2343 | #define AR5K_PHY_SIGMA_DELTA_FILT1_S 8 |
2334 | #define AR5K_PHY_SIGMA_DELTA_ADC_CLIP 0x01ff3000 | 2344 | #define AR5K_PHY_SIGMA_DELTA_ADC_CLIP 0x01ffe000 |
2335 | #define AR5K_PHY_SIGMA_DELTA_ADC_CLIP_S 13 | 2345 | #define AR5K_PHY_SIGMA_DELTA_ADC_CLIP_S 13 |
2336 | 2346 | ||
2337 | /* | 2347 | /* |
@@ -2459,17 +2469,7 @@ | |||
2459 | #define AR5K_PHY_SDELAY 0x99f4 | 2469 | #define AR5K_PHY_SDELAY 0x99f4 |
2460 | #define AR5K_PHY_SDELAY_32MHZ 0x000000ff | 2470 | #define AR5K_PHY_SDELAY_32MHZ 0x000000ff |
2461 | #define AR5K_PHY_SPENDING 0x99f8 | 2471 | #define AR5K_PHY_SPENDING 0x99f8 |
2462 | #define AR5K_PHY_SPENDING_14 0x00000014 | 2472 | |
2463 | #define AR5K_PHY_SPENDING_18 0x00000018 | ||
2464 | #define AR5K_PHY_SPENDING_RF5111 0x00000018 | ||
2465 | #define AR5K_PHY_SPENDING_RF5112 0x00000014 | ||
2466 | /* #define AR5K_PHY_SPENDING_RF5112A 0x0000000e */ | ||
2467 | /* #define AR5K_PHY_SPENDING_RF5424 0x00000012 */ | ||
2468 | #define AR5K_PHY_SPENDING_RF5413 0x00000018 | ||
2469 | #define AR5K_PHY_SPENDING_RF2413 0x00000018 | ||
2470 | #define AR5K_PHY_SPENDING_RF2316 0x00000018 | ||
2471 | #define AR5K_PHY_SPENDING_RF2317 0x00000018 | ||
2472 | #define AR5K_PHY_SPENDING_RF2425 0x00000014 | ||
2473 | 2473 | ||
2474 | /* | 2474 | /* |
2475 | * PHY PAPD I (power?) table (?) | 2475 | * PHY PAPD I (power?) table (?) |
diff --git a/drivers/net/wireless/ath5k/reset.c b/drivers/net/wireless/ath5k/reset.c index 579c64ce6108..1531ccd35066 100644 --- a/drivers/net/wireless/ath5k/reset.c +++ b/drivers/net/wireless/ath5k/reset.c | |||
@@ -25,7 +25,8 @@ | |||
25 | Reset functions and helpers | 25 | Reset functions and helpers |
26 | \*****************************/ | 26 | \*****************************/ |
27 | 27 | ||
28 | #include <linux/pci.h> | 28 | #include <linux/pci.h> /* To determine if a card is pci-e */ |
29 | #include <linux/bitops.h> /* For get_bitmask_order */ | ||
29 | #include "ath5k.h" | 30 | #include "ath5k.h" |
30 | #include "reg.h" | 31 | #include "reg.h" |
31 | #include "base.h" | 32 | #include "base.h" |
@@ -37,10 +38,14 @@ | |||
37 | * @ah: the &struct ath5k_hw | 38 | * @ah: the &struct ath5k_hw |
38 | * @channel: the currently set channel upon reset | 39 | * @channel: the currently set channel upon reset |
39 | * | 40 | * |
40 | * Write the OFDM timings for the AR5212 upon reset. This is a helper for | 41 | * Write the delta slope coefficient (used on pilot tracking ?) for OFDM |
41 | * ath5k_hw_reset(). This seems to tune the PLL a specified frequency | 42 | * operation on the AR5212 upon reset. This is a helper for ath5k_hw_reset(). |
42 | * depending on the bandwidth of the channel. | ||
43 | * | 43 | * |
44 | * Since delta slope is floating point we split it on its exponent and | ||
45 | * mantissa and provide these values on hw. | ||
46 | * | ||
47 | * For more infos i think this patent is related | ||
48 | * http://www.freepatentsonline.com/7184495.html | ||
44 | */ | 49 | */ |
45 | static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah, | 50 | static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah, |
46 | struct ieee80211_channel *channel) | 51 | struct ieee80211_channel *channel) |
@@ -53,23 +58,34 @@ static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah, | |||
53 | !(channel->hw_value & CHANNEL_OFDM)) | 58 | !(channel->hw_value & CHANNEL_OFDM)) |
54 | BUG(); | 59 | BUG(); |
55 | 60 | ||
56 | /* Seems there are two PLLs, one for baseband sampling and one | 61 | /* Get coefficient |
57 | * for tuning. Tuning basebands are 40 MHz or 80MHz when in | 62 | * ALGO: coef = (5 * clock * carrier_freq) / 2) |
58 | * turbo. */ | 63 | * we scale coef by shifting clock value by 24 for |
59 | clock = channel->hw_value & CHANNEL_TURBO ? 80 : 40; | 64 | * better precision since we use integers */ |
60 | coef_scaled = ((5 * (clock << 24)) / 2) / | 65 | /* TODO: Half/quarter rate */ |
61 | channel->center_freq; | 66 | clock = ath5k_hw_htoclock(1, channel->hw_value & CHANNEL_TURBO); |
62 | 67 | ||
63 | for (coef_exp = 31; coef_exp > 0; coef_exp--) | 68 | coef_scaled = ((5 * (clock << 24)) / 2) / channel->center_freq; |
64 | if ((coef_scaled >> coef_exp) & 0x1) | 69 | |
65 | break; | 70 | /* Get exponent |
71 | * ALGO: coef_exp = 14 - highest set bit position */ | ||
72 | coef_exp = get_bitmask_order(coef_scaled); | ||
66 | 73 | ||
74 | /* Doesn't make sense if it's zero*/ | ||
67 | if (!coef_exp) | 75 | if (!coef_exp) |
68 | return -EINVAL; | 76 | return -EINVAL; |
69 | 77 | ||
78 | /* Note: we've shifted coef_scaled by 24 */ | ||
70 | coef_exp = 14 - (coef_exp - 24); | 79 | coef_exp = 14 - (coef_exp - 24); |
80 | |||
81 | |||
82 | /* Get mantissa (significant digits) | ||
83 | * ALGO: coef_mant = floor(coef_scaled* 2^coef_exp+0.5) */ | ||
71 | coef_man = coef_scaled + | 84 | coef_man = coef_scaled + |
72 | (1 << (24 - coef_exp - 1)); | 85 | (1 << (24 - coef_exp - 1)); |
86 | |||
87 | /* Calculate delta slope coefficient exponent | ||
88 | * and mantissa (remove scaling) and set them on hw */ | ||
73 | ds_coef_man = coef_man >> (24 - coef_exp); | 89 | ds_coef_man = coef_man >> (24 - coef_exp); |
74 | ds_coef_exp = coef_exp - 16; | 90 | ds_coef_exp = coef_exp - 16; |
75 | 91 | ||
@@ -90,16 +106,23 @@ static int control_rates[] = | |||
90 | { 0, 1, 1, 1, 4, 4, 6, 6, 8, 8, 8, 8 }; | 106 | { 0, 1, 1, 1, 4, 4, 6, 6, 8, 8, 8, 8 }; |
91 | 107 | ||
92 | /** | 108 | /** |
93 | * ath5k_hw_write_rate_duration - set rate duration during hw resets | 109 | * ath5k_hw_write_rate_duration - fill rate code to duration table |
94 | * | 110 | * |
95 | * @ah: the &struct ath5k_hw | 111 | * @ah: the &struct ath5k_hw |
96 | * @mode: one of enum ath5k_driver_mode | 112 | * @mode: one of enum ath5k_driver_mode |
97 | * | 113 | * |
98 | * Write the rate duration table upon hw reset. This is a helper for | 114 | * Write the rate code to duration table upon hw reset. This is a helper for |
99 | * ath5k_hw_reset(). It seems all this is doing is setting an ACK timeout for | 115 | * ath5k_hw_reset(). It seems all this is doing is setting an ACK timeout on |
100 | * the hardware for the current mode for each rate. The rates which are capable | 116 | * the hardware, based on current mode, for each rate. The rates which are |
101 | * of short preamble (802.11b rates 2Mbps, 5.5Mbps, and 11Mbps) have another | 117 | * capable of short preamble (802.11b rates 2Mbps, 5.5Mbps, and 11Mbps) have |
102 | * register for the short preamble ACK timeout calculation. | 118 | * different rate code so we write their value twice (one for long preample |
119 | * and one for short). | ||
120 | * | ||
121 | * Note: Band doesn't matter here, if we set the values for OFDM it works | ||
122 | * on both a and g modes. So all we have to do is set values for all g rates | ||
123 | * that include all OFDM and CCK rates. If we operate in turbo or xr/half/ | ||
124 | * quarter rate mode, we need to use another set of bitrates (that's why we | ||
125 | * need the mode parameter) but we don't handle these proprietary modes yet. | ||
103 | */ | 126 | */ |
104 | static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah, | 127 | static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah, |
105 | unsigned int mode) | 128 | unsigned int mode) |
@@ -275,7 +298,8 @@ commit: | |||
275 | } | 298 | } |
276 | 299 | ||
277 | /* | 300 | /* |
278 | * Bring up MAC + PHY Chips | 301 | * Bring up MAC + PHY Chips and program PLL |
302 | * TODO: Half/Quarter rate support | ||
279 | */ | 303 | */ |
280 | int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial) | 304 | int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial) |
281 | { | 305 | { |
@@ -333,7 +357,11 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial) | |||
333 | } | 357 | } |
334 | } else if (flags & CHANNEL_5GHZ) { | 358 | } else if (flags & CHANNEL_5GHZ) { |
335 | mode |= AR5K_PHY_MODE_FREQ_5GHZ; | 359 | mode |= AR5K_PHY_MODE_FREQ_5GHZ; |
336 | clock |= AR5K_PHY_PLL_40MHZ; | 360 | |
361 | if (ah->ah_radio == AR5K_RF5413) | ||
362 | clock |= AR5K_PHY_PLL_40MHZ_5413; | ||
363 | else | ||
364 | clock |= AR5K_PHY_PLL_40MHZ; | ||
337 | 365 | ||
338 | if (flags & CHANNEL_OFDM) | 366 | if (flags & CHANNEL_OFDM) |
339 | mode |= AR5K_PHY_MODE_MOD_OFDM; | 367 | mode |= AR5K_PHY_MODE_MOD_OFDM; |
@@ -391,10 +419,14 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial) | |||
391 | } | 419 | } |
392 | 420 | ||
393 | if (ah->ah_version != AR5K_AR5210) { | 421 | if (ah->ah_version != AR5K_AR5210) { |
394 | /* ...set the PHY operating mode */ | ||
395 | ath5k_hw_reg_write(ah, clock, AR5K_PHY_PLL); | ||
396 | udelay(300); | ||
397 | 422 | ||
423 | /* ...update PLL if needed */ | ||
424 | if (ath5k_hw_reg_read(ah, AR5K_PHY_PLL) != clock) { | ||
425 | ath5k_hw_reg_write(ah, clock, AR5K_PHY_PLL); | ||
426 | udelay(300); | ||
427 | } | ||
428 | |||
429 | /* ...set the PHY operating mode */ | ||
398 | ath5k_hw_reg_write(ah, mode, AR5K_PHY_MODE); | 430 | ath5k_hw_reg_write(ah, mode, AR5K_PHY_MODE); |
399 | ath5k_hw_reg_write(ah, turbo, AR5K_PHY_TURBO); | 431 | ath5k_hw_reg_write(ah, turbo, AR5K_PHY_TURBO); |
400 | } | 432 | } |
@@ -403,22 +435,393 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial) | |||
403 | } | 435 | } |
404 | 436 | ||
405 | /* | 437 | /* |
438 | * If there is an external 32KHz crystal available, use it | ||
439 | * as ref. clock instead of 32/40MHz clock and baseband clocks | ||
440 | * to save power during sleep or restore normal 32/40MHz | ||
441 | * operation. | ||
442 | * | ||
443 | * XXX: When operating on 32KHz certain PHY registers (27 - 31, | ||
444 | * 123 - 127) require delay on access. | ||
445 | */ | ||
446 | static void ath5k_hw_set_sleep_clock(struct ath5k_hw *ah, bool enable) | ||
447 | { | ||
448 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; | ||
449 | u32 scal, spending, usec32; | ||
450 | |||
451 | /* Only set 32KHz settings if we have an external | ||
452 | * 32KHz crystal present */ | ||
453 | if ((AR5K_EEPROM_HAS32KHZCRYSTAL(ee->ee_misc1) || | ||
454 | AR5K_EEPROM_HAS32KHZCRYSTAL_OLD(ee->ee_misc1)) && | ||
455 | enable) { | ||
456 | |||
457 | /* 1 usec/cycle */ | ||
458 | AR5K_REG_WRITE_BITS(ah, AR5K_USEC_5211, AR5K_USEC_32, 1); | ||
459 | /* Set up tsf increment on each cycle */ | ||
460 | AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 61); | ||
461 | |||
462 | /* Set baseband sleep control registers | ||
463 | * and sleep control rate */ | ||
464 | ath5k_hw_reg_write(ah, 0x1f, AR5K_PHY_SCR); | ||
465 | |||
466 | if ((ah->ah_radio == AR5K_RF5112) || | ||
467 | (ah->ah_radio == AR5K_RF5413) || | ||
468 | (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) | ||
469 | spending = 0x14; | ||
470 | else | ||
471 | spending = 0x18; | ||
472 | ath5k_hw_reg_write(ah, spending, AR5K_PHY_SPENDING); | ||
473 | |||
474 | if ((ah->ah_radio == AR5K_RF5112) || | ||
475 | (ah->ah_radio == AR5K_RF5413) || | ||
476 | (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) { | ||
477 | ath5k_hw_reg_write(ah, 0x26, AR5K_PHY_SLMT); | ||
478 | ath5k_hw_reg_write(ah, 0x0d, AR5K_PHY_SCAL); | ||
479 | ath5k_hw_reg_write(ah, 0x07, AR5K_PHY_SCLOCK); | ||
480 | ath5k_hw_reg_write(ah, 0x3f, AR5K_PHY_SDELAY); | ||
481 | AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG, | ||
482 | AR5K_PCICFG_SLEEP_CLOCK_RATE, 0x02); | ||
483 | } else { | ||
484 | ath5k_hw_reg_write(ah, 0x0a, AR5K_PHY_SLMT); | ||
485 | ath5k_hw_reg_write(ah, 0x0c, AR5K_PHY_SCAL); | ||
486 | ath5k_hw_reg_write(ah, 0x03, AR5K_PHY_SCLOCK); | ||
487 | ath5k_hw_reg_write(ah, 0x20, AR5K_PHY_SDELAY); | ||
488 | AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG, | ||
489 | AR5K_PCICFG_SLEEP_CLOCK_RATE, 0x03); | ||
490 | } | ||
491 | |||
492 | /* Enable sleep clock operation */ | ||
493 | AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, | ||
494 | AR5K_PCICFG_SLEEP_CLOCK_EN); | ||
495 | |||
496 | } else { | ||
497 | |||
498 | /* Disable sleep clock operation and | ||
499 | * restore default parameters */ | ||
500 | AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG, | ||
501 | AR5K_PCICFG_SLEEP_CLOCK_EN); | ||
502 | |||
503 | AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG, | ||
504 | AR5K_PCICFG_SLEEP_CLOCK_RATE, 0); | ||
505 | |||
506 | ath5k_hw_reg_write(ah, 0x1f, AR5K_PHY_SCR); | ||
507 | ath5k_hw_reg_write(ah, AR5K_PHY_SLMT_32MHZ, AR5K_PHY_SLMT); | ||
508 | |||
509 | if (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)) | ||
510 | scal = AR5K_PHY_SCAL_32MHZ_2417; | ||
511 | else if (ath5k_eeprom_is_hb63(ah)) | ||
512 | scal = AR5K_PHY_SCAL_32MHZ_HB63; | ||
513 | else | ||
514 | scal = AR5K_PHY_SCAL_32MHZ; | ||
515 | ath5k_hw_reg_write(ah, scal, AR5K_PHY_SCAL); | ||
516 | |||
517 | ath5k_hw_reg_write(ah, AR5K_PHY_SCLOCK_32MHZ, AR5K_PHY_SCLOCK); | ||
518 | ath5k_hw_reg_write(ah, AR5K_PHY_SDELAY_32MHZ, AR5K_PHY_SDELAY); | ||
519 | |||
520 | if ((ah->ah_radio == AR5K_RF5112) || | ||
521 | (ah->ah_radio == AR5K_RF5413) || | ||
522 | (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) | ||
523 | spending = 0x14; | ||
524 | else | ||
525 | spending = 0x18; | ||
526 | ath5k_hw_reg_write(ah, spending, AR5K_PHY_SPENDING); | ||
527 | |||
528 | if ((ah->ah_radio == AR5K_RF5112) || | ||
529 | (ah->ah_radio == AR5K_RF5413)) | ||
530 | usec32 = 39; | ||
531 | else | ||
532 | usec32 = 31; | ||
533 | AR5K_REG_WRITE_BITS(ah, AR5K_USEC_5211, AR5K_USEC_32, usec32); | ||
534 | |||
535 | AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 1); | ||
536 | } | ||
537 | return; | ||
538 | } | ||
539 | |||
540 | static bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah, | ||
541 | struct ieee80211_channel *channel) | ||
542 | { | ||
543 | u8 refclk_freq; | ||
544 | |||
545 | if ((ah->ah_radio == AR5K_RF5112) || | ||
546 | (ah->ah_radio == AR5K_RF5413) || | ||
547 | (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) | ||
548 | refclk_freq = 40; | ||
549 | else | ||
550 | refclk_freq = 32; | ||
551 | |||
552 | if ((channel->center_freq % refclk_freq != 0) && | ||
553 | ((channel->center_freq % refclk_freq < 10) || | ||
554 | (channel->center_freq % refclk_freq > 22))) | ||
555 | return true; | ||
556 | else | ||
557 | return false; | ||
558 | } | ||
559 | |||
560 | /* TODO: Half/Quarter rate */ | ||
561 | static void ath5k_hw_tweak_initval_settings(struct ath5k_hw *ah, | ||
562 | struct ieee80211_channel *channel) | ||
563 | { | ||
564 | if (ah->ah_version == AR5K_AR5212 && | ||
565 | ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) { | ||
566 | |||
567 | /* Setup ADC control */ | ||
568 | ath5k_hw_reg_write(ah, | ||
569 | (AR5K_REG_SM(2, | ||
570 | AR5K_PHY_ADC_CTL_INBUFGAIN_OFF) | | ||
571 | AR5K_REG_SM(2, | ||
572 | AR5K_PHY_ADC_CTL_INBUFGAIN_ON) | | ||
573 | AR5K_PHY_ADC_CTL_PWD_DAC_OFF | | ||
574 | AR5K_PHY_ADC_CTL_PWD_ADC_OFF), | ||
575 | AR5K_PHY_ADC_CTL); | ||
576 | |||
577 | |||
578 | |||
579 | /* Disable barker RSSI threshold */ | ||
580 | AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_DAG_CCK_CTL, | ||
581 | AR5K_PHY_DAG_CCK_CTL_EN_RSSI_THR); | ||
582 | |||
583 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DAG_CCK_CTL, | ||
584 | AR5K_PHY_DAG_CCK_CTL_RSSI_THR, 2); | ||
585 | |||
586 | /* Set the mute mask */ | ||
587 | ath5k_hw_reg_write(ah, 0x0000000f, AR5K_SEQ_MASK); | ||
588 | } | ||
589 | |||
590 | /* Clear PHY_BLUETOOTH to allow RX_CLEAR line debug */ | ||
591 | if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212B) | ||
592 | ath5k_hw_reg_write(ah, 0, AR5K_PHY_BLUETOOTH); | ||
593 | |||
594 | /* Enable DCU double buffering */ | ||
595 | if (ah->ah_phy_revision > AR5K_SREV_PHY_5212B) | ||
596 | AR5K_REG_DISABLE_BITS(ah, AR5K_TXCFG, | ||
597 | AR5K_TXCFG_DCU_DBL_BUF_DIS); | ||
598 | |||
599 | /* Set DAC/ADC delays */ | ||
600 | if (ah->ah_version == AR5K_AR5212) { | ||
601 | u32 scal; | ||
602 | if (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)) | ||
603 | scal = AR5K_PHY_SCAL_32MHZ_2417; | ||
604 | else if (ath5k_eeprom_is_hb63(ah)) | ||
605 | scal = AR5K_PHY_SCAL_32MHZ_HB63; | ||
606 | else | ||
607 | scal = AR5K_PHY_SCAL_32MHZ; | ||
608 | ath5k_hw_reg_write(ah, scal, AR5K_PHY_SCAL); | ||
609 | } | ||
610 | |||
611 | /* Set fast ADC */ | ||
612 | if ((ah->ah_radio == AR5K_RF5413) || | ||
613 | (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) { | ||
614 | u32 fast_adc = true; | ||
615 | |||
616 | if (channel->center_freq == 2462 || | ||
617 | channel->center_freq == 2467) | ||
618 | fast_adc = 0; | ||
619 | |||
620 | /* Only update if needed */ | ||
621 | if (ath5k_hw_reg_read(ah, AR5K_PHY_FAST_ADC) != fast_adc) | ||
622 | ath5k_hw_reg_write(ah, fast_adc, | ||
623 | AR5K_PHY_FAST_ADC); | ||
624 | } | ||
625 | |||
626 | /* Fix for first revision of the RF5112 RF chipset */ | ||
627 | if (ah->ah_radio == AR5K_RF5112 && | ||
628 | ah->ah_radio_5ghz_revision < | ||
629 | AR5K_SREV_RAD_5112A) { | ||
630 | u32 data; | ||
631 | ath5k_hw_reg_write(ah, AR5K_PHY_CCKTXCTL_WORLD, | ||
632 | AR5K_PHY_CCKTXCTL); | ||
633 | if (channel->hw_value & CHANNEL_5GHZ) | ||
634 | data = 0xffb81020; | ||
635 | else | ||
636 | data = 0xffb80d20; | ||
637 | ath5k_hw_reg_write(ah, data, AR5K_PHY_FRAME_CTL); | ||
638 | } | ||
639 | |||
640 | if (ah->ah_mac_srev < AR5K_SREV_AR5211) { | ||
641 | u32 usec_reg; | ||
642 | /* 5311 has different tx/rx latency masks | ||
643 | * from 5211, since we deal 5311 the same | ||
644 | * as 5211 when setting initvals, shift | ||
645 | * values here to their proper locations */ | ||
646 | usec_reg = ath5k_hw_reg_read(ah, AR5K_USEC_5211); | ||
647 | ath5k_hw_reg_write(ah, usec_reg & (AR5K_USEC_1 | | ||
648 | AR5K_USEC_32 | | ||
649 | AR5K_USEC_TX_LATENCY_5211 | | ||
650 | AR5K_REG_SM(29, | ||
651 | AR5K_USEC_RX_LATENCY_5210)), | ||
652 | AR5K_USEC_5211); | ||
653 | /* Clear QCU/DCU clock gating register */ | ||
654 | ath5k_hw_reg_write(ah, 0, AR5K_QCUDCU_CLKGT); | ||
655 | /* Set DAC/ADC delays */ | ||
656 | ath5k_hw_reg_write(ah, 0x08, AR5K_PHY_SCAL); | ||
657 | /* Enable PCU FIFO corruption ECO */ | ||
658 | AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5211, | ||
659 | AR5K_DIAG_SW_ECO_ENABLE); | ||
660 | } | ||
661 | } | ||
662 | |||
663 | static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah, | ||
664 | struct ieee80211_channel *channel, u8 *ant, u8 ee_mode) | ||
665 | { | ||
666 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; | ||
667 | |||
668 | /* Set CCK to OFDM power delta */ | ||
669 | if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) { | ||
670 | int16_t cck_ofdm_pwr_delta; | ||
671 | |||
672 | /* Adjust power delta for channel 14 */ | ||
673 | if (channel->center_freq == 2484) | ||
674 | cck_ofdm_pwr_delta = | ||
675 | ((ee->ee_cck_ofdm_power_delta - | ||
676 | ee->ee_scaled_cck_delta) * 2) / 10; | ||
677 | else | ||
678 | cck_ofdm_pwr_delta = | ||
679 | (ee->ee_cck_ofdm_power_delta * 2) / 10; | ||
680 | |||
681 | if (channel->hw_value == CHANNEL_G) | ||
682 | ath5k_hw_reg_write(ah, | ||
683 | AR5K_REG_SM((ee->ee_cck_ofdm_power_delta * -1), | ||
684 | AR5K_PHY_TX_PWR_ADJ_CCK_GAIN_DELTA) | | ||
685 | AR5K_REG_SM((cck_ofdm_pwr_delta * -1), | ||
686 | AR5K_PHY_TX_PWR_ADJ_CCK_PCDAC_INDEX), | ||
687 | AR5K_PHY_TX_PWR_ADJ); | ||
688 | else | ||
689 | ath5k_hw_reg_write(ah, 0, AR5K_PHY_TX_PWR_ADJ); | ||
690 | } | ||
691 | |||
692 | /* Set antenna idle switch table */ | ||
693 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_ANT_CTL, | ||
694 | AR5K_PHY_ANT_CTL_SWTABLE_IDLE, | ||
695 | (ah->ah_antenna[ee_mode][0] | | ||
696 | AR5K_PHY_ANT_CTL_TXRX_EN)); | ||
697 | |||
698 | /* Set antenna switch table */ | ||
699 | ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[0]], | ||
700 | AR5K_PHY_ANT_SWITCH_TABLE_0); | ||
701 | ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[1]], | ||
702 | AR5K_PHY_ANT_SWITCH_TABLE_1); | ||
703 | |||
704 | /* Noise floor threshold */ | ||
705 | ath5k_hw_reg_write(ah, | ||
706 | AR5K_PHY_NF_SVAL(ee->ee_noise_floor_thr[ee_mode]), | ||
707 | AR5K_PHY_NFTHRES); | ||
708 | |||
709 | if ((channel->hw_value & CHANNEL_TURBO) && | ||
710 | (ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_0)) { | ||
711 | /* Switch settling time (Turbo) */ | ||
712 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SETTLING, | ||
713 | AR5K_PHY_SETTLING_SWITCH, | ||
714 | ee->ee_switch_settling_turbo[ee_mode]); | ||
715 | |||
716 | /* Tx/Rx attenuation (Turbo) */ | ||
717 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN, | ||
718 | AR5K_PHY_GAIN_TXRX_ATTEN, | ||
719 | ee->ee_atn_tx_rx_turbo[ee_mode]); | ||
720 | |||
721 | /* ADC/PGA desired size (Turbo) */ | ||
722 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE, | ||
723 | AR5K_PHY_DESIRED_SIZE_ADC, | ||
724 | ee->ee_adc_desired_size_turbo[ee_mode]); | ||
725 | |||
726 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE, | ||
727 | AR5K_PHY_DESIRED_SIZE_PGA, | ||
728 | ee->ee_pga_desired_size_turbo[ee_mode]); | ||
729 | |||
730 | /* Tx/Rx margin (Turbo) */ | ||
731 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN_2GHZ, | ||
732 | AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX, | ||
733 | ee->ee_margin_tx_rx_turbo[ee_mode]); | ||
734 | |||
735 | } else { | ||
736 | /* Switch settling time */ | ||
737 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SETTLING, | ||
738 | AR5K_PHY_SETTLING_SWITCH, | ||
739 | ee->ee_switch_settling[ee_mode]); | ||
740 | |||
741 | /* Tx/Rx attenuation */ | ||
742 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN, | ||
743 | AR5K_PHY_GAIN_TXRX_ATTEN, | ||
744 | ee->ee_atn_tx_rx[ee_mode]); | ||
745 | |||
746 | /* ADC/PGA desired size */ | ||
747 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE, | ||
748 | AR5K_PHY_DESIRED_SIZE_ADC, | ||
749 | ee->ee_adc_desired_size[ee_mode]); | ||
750 | |||
751 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE, | ||
752 | AR5K_PHY_DESIRED_SIZE_PGA, | ||
753 | ee->ee_pga_desired_size[ee_mode]); | ||
754 | |||
755 | /* Tx/Rx margin */ | ||
756 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1) | ||
757 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN_2GHZ, | ||
758 | AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX, | ||
759 | ee->ee_margin_tx_rx[ee_mode]); | ||
760 | } | ||
761 | |||
762 | /* XPA delays */ | ||
763 | ath5k_hw_reg_write(ah, | ||
764 | (ee->ee_tx_end2xpa_disable[ee_mode] << 24) | | ||
765 | (ee->ee_tx_end2xpa_disable[ee_mode] << 16) | | ||
766 | (ee->ee_tx_frm2xpa_enable[ee_mode] << 8) | | ||
767 | (ee->ee_tx_frm2xpa_enable[ee_mode]), AR5K_PHY_RF_CTL4); | ||
768 | |||
769 | /* XLNA delay */ | ||
770 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RF_CTL3, | ||
771 | AR5K_PHY_RF_CTL3_TXE2XLNA_ON, | ||
772 | ee->ee_tx_end2xlna_enable[ee_mode]); | ||
773 | |||
774 | /* Thresh64 (ANI) */ | ||
775 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_NF, | ||
776 | AR5K_PHY_NF_THRESH62, | ||
777 | ee->ee_thr_62[ee_mode]); | ||
778 | |||
779 | |||
780 | /* False detect backoff for channels | ||
781 | * that have spur noise. Write the new | ||
782 | * cyclic power RSSI threshold. */ | ||
783 | if (ath5k_hw_chan_has_spur_noise(ah, channel)) | ||
784 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_OFDM_SELFCORR, | ||
785 | AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1, | ||
786 | AR5K_INIT_CYCRSSI_THR1 + | ||
787 | ee->ee_false_detect[ee_mode]); | ||
788 | else | ||
789 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_OFDM_SELFCORR, | ||
790 | AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1, | ||
791 | AR5K_INIT_CYCRSSI_THR1); | ||
792 | |||
793 | /* I/Q correction | ||
794 | * TODO: Per channel i/q infos ? */ | ||
795 | AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, | ||
796 | AR5K_PHY_IQ_CORR_ENABLE | | ||
797 | (ee->ee_i_cal[ee_mode] << AR5K_PHY_IQ_CORR_Q_I_COFF_S) | | ||
798 | ee->ee_q_cal[ee_mode]); | ||
799 | |||
800 | /* Heavy clipping -disable for now */ | ||
801 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_1) | ||
802 | ath5k_hw_reg_write(ah, 0, AR5K_PHY_HEAVY_CLIP_ENABLE); | ||
803 | |||
804 | return; | ||
805 | } | ||
806 | |||
807 | /* | ||
406 | * Main reset function | 808 | * Main reset function |
407 | */ | 809 | */ |
408 | int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, | 810 | int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, |
409 | struct ieee80211_channel *channel, bool change_channel) | 811 | struct ieee80211_channel *channel, bool change_channel) |
410 | { | 812 | { |
411 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; | 813 | u32 s_seq[10], s_ant, s_led[3], staid1_flags, tsf_up, tsf_lo; |
412 | struct pci_dev *pdev = ah->ah_sc->pdev; | 814 | u32 phy_tst1; |
413 | u32 data, s_seq, s_ant, s_led[3], dma_size; | 815 | u8 mode, freq, ee_mode, ant[2]; |
414 | unsigned int i, mode, freq, ee_mode, ant[2]; | 816 | int i, ret; |
415 | int ret; | ||
416 | 817 | ||
417 | ATH5K_TRACE(ah->ah_sc); | 818 | ATH5K_TRACE(ah->ah_sc); |
418 | 819 | ||
419 | s_seq = 0; | ||
420 | s_ant = 0; | 820 | s_ant = 0; |
421 | ee_mode = 0; | 821 | ee_mode = 0; |
822 | staid1_flags = 0; | ||
823 | tsf_up = 0; | ||
824 | tsf_lo = 0; | ||
422 | freq = 0; | 825 | freq = 0; |
423 | mode = 0; | 826 | mode = 0; |
424 | 827 | ||
@@ -427,36 +830,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, | |||
427 | */ | 830 | */ |
428 | /*DCU/Antenna selection not available on 5210*/ | 831 | /*DCU/Antenna selection not available on 5210*/ |
429 | if (ah->ah_version != AR5K_AR5210) { | 832 | if (ah->ah_version != AR5K_AR5210) { |
430 | if (change_channel) { | ||
431 | /* Seq number for queue 0 -do this for all queues ? */ | ||
432 | s_seq = ath5k_hw_reg_read(ah, | ||
433 | AR5K_QUEUE_DFS_SEQNUM(0)); | ||
434 | /*Default antenna*/ | ||
435 | s_ant = ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA); | ||
436 | } | ||
437 | } | ||
438 | |||
439 | /*GPIOs*/ | ||
440 | s_led[0] = ath5k_hw_reg_read(ah, AR5K_PCICFG) & AR5K_PCICFG_LEDSTATE; | ||
441 | s_led[1] = ath5k_hw_reg_read(ah, AR5K_GPIOCR); | ||
442 | s_led[2] = ath5k_hw_reg_read(ah, AR5K_GPIODO); | ||
443 | |||
444 | |||
445 | /*Wakeup the device*/ | ||
446 | ret = ath5k_hw_nic_wakeup(ah, channel->hw_value, false); | ||
447 | if (ret) | ||
448 | return ret; | ||
449 | |||
450 | /* | ||
451 | * Initialize operating mode | ||
452 | */ | ||
453 | ah->ah_op_mode = op_mode; | ||
454 | |||
455 | /* | ||
456 | * 5111/5112 Settings | ||
457 | * 5210 only comes with RF5110 | ||
458 | */ | ||
459 | if (ah->ah_version != AR5K_AR5210) { | ||
460 | 833 | ||
461 | switch (channel->hw_value & CHANNEL_MODES) { | 834 | switch (channel->hw_value & CHANNEL_MODES) { |
462 | case CHANNEL_A: | 835 | case CHANNEL_A: |
@@ -479,8 +852,12 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, | |||
479 | freq = AR5K_INI_RFGAIN_5GHZ; | 852 | freq = AR5K_INI_RFGAIN_5GHZ; |
480 | ee_mode = AR5K_EEPROM_MODE_11A; | 853 | ee_mode = AR5K_EEPROM_MODE_11A; |
481 | break; | 854 | break; |
482 | /*Is this ok on 5211 too ?*/ | ||
483 | case CHANNEL_TG: | 855 | case CHANNEL_TG: |
856 | if (ah->ah_version == AR5K_AR5211) { | ||
857 | ATH5K_ERR(ah->ah_sc, | ||
858 | "TurboG mode not available on 5211"); | ||
859 | return -EINVAL; | ||
860 | } | ||
484 | mode = AR5K_MODE_11G_TURBO; | 861 | mode = AR5K_MODE_11G_TURBO; |
485 | freq = AR5K_INI_RFGAIN_2GHZ; | 862 | freq = AR5K_INI_RFGAIN_2GHZ; |
486 | ee_mode = AR5K_EEPROM_MODE_11G; | 863 | ee_mode = AR5K_EEPROM_MODE_11G; |
@@ -501,11 +878,93 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, | |||
501 | return -EINVAL; | 878 | return -EINVAL; |
502 | } | 879 | } |
503 | 880 | ||
881 | if (change_channel) { | ||
882 | /* | ||
883 | * Save frame sequence count | ||
884 | * For revs. after Oahu, only save | ||
885 | * seq num for DCU 0 (Global seq num) | ||
886 | */ | ||
887 | if (ah->ah_mac_srev < AR5K_SREV_AR5211) { | ||
888 | |||
889 | for (i = 0; i < 10; i++) | ||
890 | s_seq[i] = ath5k_hw_reg_read(ah, | ||
891 | AR5K_QUEUE_DCU_SEQNUM(i)); | ||
892 | |||
893 | } else { | ||
894 | s_seq[0] = ath5k_hw_reg_read(ah, | ||
895 | AR5K_QUEUE_DCU_SEQNUM(0)); | ||
896 | } | ||
897 | |||
898 | /* TSF accelerates on AR5211 durring reset | ||
899 | * As a workaround save it here and restore | ||
900 | * it later so that it's back in time after | ||
901 | * reset. This way it'll get re-synced on the | ||
902 | * next beacon without breaking ad-hoc. | ||
903 | * | ||
904 | * On AR5212 TSF is almost preserved across a | ||
905 | * reset so it stays back in time anyway and | ||
906 | * we don't have to save/restore it. | ||
907 | * | ||
908 | * XXX: Since this breaks power saving we have | ||
909 | * to disable power saving until we receive the | ||
910 | * next beacon, so we can resync beacon timers */ | ||
911 | if (ah->ah_version == AR5K_AR5211) { | ||
912 | tsf_up = ath5k_hw_reg_read(ah, AR5K_TSF_U32); | ||
913 | tsf_lo = ath5k_hw_reg_read(ah, AR5K_TSF_L32); | ||
914 | } | ||
915 | } | ||
916 | |||
917 | /* Save default antenna */ | ||
918 | s_ant = ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA); | ||
919 | |||
920 | if (ah->ah_version == AR5K_AR5212) { | ||
921 | /* Restore normal 32/40MHz clock operation | ||
922 | * to avoid register access delay on certain | ||
923 | * PHY registers */ | ||
924 | ath5k_hw_set_sleep_clock(ah, false); | ||
925 | |||
926 | /* Since we are going to write rf buffer | ||
927 | * check if we have any pending gain_F | ||
928 | * optimization settings */ | ||
929 | if (change_channel && ah->ah_rf_banks != NULL) | ||
930 | ath5k_hw_gainf_calibrate(ah); | ||
931 | } | ||
504 | } | 932 | } |
505 | 933 | ||
934 | /*GPIOs*/ | ||
935 | s_led[0] = ath5k_hw_reg_read(ah, AR5K_PCICFG) & | ||
936 | AR5K_PCICFG_LEDSTATE; | ||
937 | s_led[1] = ath5k_hw_reg_read(ah, AR5K_GPIOCR); | ||
938 | s_led[2] = ath5k_hw_reg_read(ah, AR5K_GPIODO); | ||
939 | |||
940 | /* AR5K_STA_ID1 flags, only preserve antenna | ||
941 | * settings and ack/cts rate mode */ | ||
942 | staid1_flags = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & | ||
943 | (AR5K_STA_ID1_DEFAULT_ANTENNA | | ||
944 | AR5K_STA_ID1_DESC_ANTENNA | | ||
945 | AR5K_STA_ID1_RTS_DEF_ANTENNA | | ||
946 | AR5K_STA_ID1_ACKCTS_6MB | | ||
947 | AR5K_STA_ID1_BASE_RATE_11B | | ||
948 | AR5K_STA_ID1_SELFGEN_DEF_ANT); | ||
949 | |||
950 | /* Wakeup the device */ | ||
951 | ret = ath5k_hw_nic_wakeup(ah, channel->hw_value, false); | ||
952 | if (ret) | ||
953 | return ret; | ||
954 | |||
955 | /* | ||
956 | * Initialize operating mode | ||
957 | */ | ||
958 | ah->ah_op_mode = op_mode; | ||
959 | |||
506 | /* PHY access enable */ | 960 | /* PHY access enable */ |
507 | ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0)); | 961 | if (ah->ah_mac_srev >= AR5K_SREV_AR5211) |
962 | ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0)); | ||
963 | else | ||
964 | ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ | 0x40, | ||
965 | AR5K_PHY(0)); | ||
508 | 966 | ||
967 | /* Write initial settings */ | ||
509 | ret = ath5k_hw_write_initvals(ah, mode, change_channel); | 968 | ret = ath5k_hw_write_initvals(ah, mode, change_channel); |
510 | if (ret) | 969 | if (ret) |
511 | return ret; | 970 | return ret; |
@@ -514,6 +973,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, | |||
514 | * 5211/5212 Specific | 973 | * 5211/5212 Specific |
515 | */ | 974 | */ |
516 | if (ah->ah_version != AR5K_AR5210) { | 975 | if (ah->ah_version != AR5K_AR5210) { |
976 | |||
517 | /* | 977 | /* |
518 | * Write initial RF gain settings | 978 | * Write initial RF gain settings |
519 | * This should work for both 5111/5112 | 979 | * This should work for both 5111/5112 |
@@ -525,53 +985,11 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, | |||
525 | mdelay(1); | 985 | mdelay(1); |
526 | 986 | ||
527 | /* | 987 | /* |
528 | * Write some more initial register settings for revised chips | 988 | * Tweak initval settings for revised |
989 | * chipsets and add some more config | ||
990 | * bits | ||
529 | */ | 991 | */ |
530 | if (ah->ah_version == AR5K_AR5212 && | 992 | ath5k_hw_tweak_initval_settings(ah, channel); |
531 | ah->ah_phy_revision > 0x41) { | ||
532 | ath5k_hw_reg_write(ah, 0x0002a002, 0x982c); | ||
533 | |||
534 | if (channel->hw_value == CHANNEL_G) | ||
535 | if (ah->ah_mac_srev < AR5K_SREV_AR2413) | ||
536 | ath5k_hw_reg_write(ah, 0x00f80d80, | ||
537 | 0x994c); | ||
538 | else if (ah->ah_mac_srev < AR5K_SREV_AR5424) | ||
539 | ath5k_hw_reg_write(ah, 0x00380140, | ||
540 | 0x994c); | ||
541 | else if (ah->ah_mac_srev < AR5K_SREV_AR2425) | ||
542 | ath5k_hw_reg_write(ah, 0x00fc0ec0, | ||
543 | 0x994c); | ||
544 | else /* 2425 */ | ||
545 | ath5k_hw_reg_write(ah, 0x00fc0fc0, | ||
546 | 0x994c); | ||
547 | else | ||
548 | ath5k_hw_reg_write(ah, 0x00000000, 0x994c); | ||
549 | |||
550 | /* Got this from legacy-hal */ | ||
551 | AR5K_REG_DISABLE_BITS(ah, 0xa228, 0x200); | ||
552 | |||
553 | AR5K_REG_MASKED_BITS(ah, 0xa228, 0x800, 0xfffe03ff); | ||
554 | |||
555 | /* Just write 0x9b5 ? */ | ||
556 | /* ath5k_hw_reg_write(ah, 0x000009b5, 0xa228); */ | ||
557 | ath5k_hw_reg_write(ah, 0x0000000f, AR5K_SEQ_MASK); | ||
558 | ath5k_hw_reg_write(ah, 0x00000000, 0xa254); | ||
559 | ath5k_hw_reg_write(ah, 0x0000000e, AR5K_PHY_SCAL); | ||
560 | } | ||
561 | |||
562 | /* Fix for first revision of the RF5112 RF chipset */ | ||
563 | if (ah->ah_radio >= AR5K_RF5112 && | ||
564 | ah->ah_radio_5ghz_revision < | ||
565 | AR5K_SREV_RAD_5112A) { | ||
566 | ath5k_hw_reg_write(ah, AR5K_PHY_CCKTXCTL_WORLD, | ||
567 | AR5K_PHY_CCKTXCTL); | ||
568 | if (channel->hw_value & CHANNEL_5GHZ) | ||
569 | data = 0xffb81020; | ||
570 | else | ||
571 | data = 0xffb80d20; | ||
572 | ath5k_hw_reg_write(ah, data, AR5K_PHY_FRAME_CTL); | ||
573 | data = 0; | ||
574 | } | ||
575 | 993 | ||
576 | /* | 994 | /* |
577 | * Set TX power (FIXME) | 995 | * Set TX power (FIXME) |
@@ -589,15 +1007,12 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, | |||
589 | ath5k_hw_write_rate_duration(ah, mode); | 1007 | ath5k_hw_write_rate_duration(ah, mode); |
590 | 1008 | ||
591 | /* | 1009 | /* |
592 | * Write RF registers | 1010 | * Write RF buffer |
593 | */ | 1011 | */ |
594 | ret = ath5k_hw_rfregs_init(ah, channel, mode); | 1012 | ret = ath5k_hw_rfregs_init(ah, channel, mode); |
595 | if (ret) | 1013 | if (ret) |
596 | return ret; | 1014 | return ret; |
597 | 1015 | ||
598 | /* | ||
599 | * Configure additional registers | ||
600 | */ | ||
601 | 1016 | ||
602 | /* Write OFDM timings on 5212*/ | 1017 | /* Write OFDM timings on 5212*/ |
603 | if (ah->ah_version == AR5K_AR5212 && | 1018 | if (ah->ah_version == AR5K_AR5212 && |
@@ -619,17 +1034,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, | |||
619 | } | 1034 | } |
620 | 1035 | ||
621 | /* | 1036 | /* |
622 | * Set channel and calibrate the PHY | ||
623 | */ | ||
624 | ret = ath5k_hw_channel(ah, channel); | ||
625 | if (ret) | ||
626 | return ret; | ||
627 | |||
628 | /* Set antenna mode */ | ||
629 | AR5K_REG_MASKED_BITS(ah, AR5K_PHY_ANT_CTL, | ||
630 | ah->ah_antenna[ee_mode][0], 0xfffffc06); | ||
631 | |||
632 | /* | ||
633 | * In case a fixed antenna was set as default | 1037 | * In case a fixed antenna was set as default |
634 | * write the same settings on both AR5K_PHY_ANT_SWITCH_TABLE | 1038 | * write the same settings on both AR5K_PHY_ANT_SWITCH_TABLE |
635 | * registers. | 1039 | * registers. |
@@ -644,54 +1048,16 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, | |||
644 | ant[1] = AR5K_ANT_FIXED_B; | 1048 | ant[1] = AR5K_ANT_FIXED_B; |
645 | } | 1049 | } |
646 | 1050 | ||
647 | ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[0]], | ||
648 | AR5K_PHY_ANT_SWITCH_TABLE_0); | ||
649 | ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[1]], | ||
650 | AR5K_PHY_ANT_SWITCH_TABLE_1); | ||
651 | |||
652 | /* Commit values from EEPROM */ | 1051 | /* Commit values from EEPROM */ |
653 | if (ah->ah_radio == AR5K_RF5111) | 1052 | ath5k_hw_commit_eeprom_settings(ah, channel, ant, ee_mode); |
654 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_FRAME_CTL, | ||
655 | AR5K_PHY_FRAME_CTL_TX_CLIP, ee->ee_tx_clip); | ||
656 | |||
657 | ath5k_hw_reg_write(ah, | ||
658 | AR5K_PHY_NF_SVAL(ee->ee_noise_floor_thr[ee_mode]), | ||
659 | AR5K_PHY_NFTHRES); | ||
660 | |||
661 | AR5K_REG_MASKED_BITS(ah, AR5K_PHY_SETTLING, | ||
662 | (ee->ee_switch_settling[ee_mode] << 7) & 0x3f80, | ||
663 | 0xffffc07f); | ||
664 | AR5K_REG_MASKED_BITS(ah, AR5K_PHY_GAIN, | ||
665 | (ee->ee_atn_tx_rx[ee_mode] << 12) & 0x3f000, | ||
666 | 0xfffc0fff); | ||
667 | AR5K_REG_MASKED_BITS(ah, AR5K_PHY_DESIRED_SIZE, | ||
668 | (ee->ee_adc_desired_size[ee_mode] & 0x00ff) | | ||
669 | ((ee->ee_pga_desired_size[ee_mode] << 8) & 0xff00), | ||
670 | 0xffff0000); | ||
671 | |||
672 | ath5k_hw_reg_write(ah, | ||
673 | (ee->ee_tx_end2xpa_disable[ee_mode] << 24) | | ||
674 | (ee->ee_tx_end2xpa_disable[ee_mode] << 16) | | ||
675 | (ee->ee_tx_frm2xpa_enable[ee_mode] << 8) | | ||
676 | (ee->ee_tx_frm2xpa_enable[ee_mode]), AR5K_PHY_RF_CTL4); | ||
677 | |||
678 | AR5K_REG_MASKED_BITS(ah, AR5K_PHY_RF_CTL3, | ||
679 | ee->ee_tx_end2xlna_enable[ee_mode] << 8, 0xffff00ff); | ||
680 | AR5K_REG_MASKED_BITS(ah, AR5K_PHY_NF, | ||
681 | (ee->ee_thr_62[ee_mode] << 12) & 0x7f000, 0xfff80fff); | ||
682 | AR5K_REG_MASKED_BITS(ah, AR5K_PHY_OFDM_SELFCORR, 4, 0xffffff01); | ||
683 | |||
684 | AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, | ||
685 | AR5K_PHY_IQ_CORR_ENABLE | | ||
686 | (ee->ee_i_cal[ee_mode] << AR5K_PHY_IQ_CORR_Q_I_COFF_S) | | ||
687 | ee->ee_q_cal[ee_mode]); | ||
688 | |||
689 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1) | ||
690 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN_2GHZ, | ||
691 | AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX, | ||
692 | ee->ee_margin_tx_rx[ee_mode]); | ||
693 | 1053 | ||
694 | } else { | 1054 | } else { |
1055 | /* | ||
1056 | * For 5210 we do all initialization using | ||
1057 | * initvals, so we don't have to modify | ||
1058 | * any settings (5210 also only supports | ||
1059 | * a/aturbo modes) | ||
1060 | */ | ||
695 | mdelay(1); | 1061 | mdelay(1); |
696 | /* Disable phy and wait */ | 1062 | /* Disable phy and wait */ |
697 | ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT); | 1063 | ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT); |
@@ -701,100 +1067,154 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, | |||
701 | /* | 1067 | /* |
702 | * Restore saved values | 1068 | * Restore saved values |
703 | */ | 1069 | */ |
1070 | |||
704 | /*DCU/Antenna selection not available on 5210*/ | 1071 | /*DCU/Antenna selection not available on 5210*/ |
705 | if (ah->ah_version != AR5K_AR5210) { | 1072 | if (ah->ah_version != AR5K_AR5210) { |
706 | ath5k_hw_reg_write(ah, s_seq, AR5K_QUEUE_DFS_SEQNUM(0)); | 1073 | |
1074 | if (change_channel) { | ||
1075 | if (ah->ah_mac_srev < AR5K_SREV_AR5211) { | ||
1076 | for (i = 0; i < 10; i++) | ||
1077 | ath5k_hw_reg_write(ah, s_seq[i], | ||
1078 | AR5K_QUEUE_DCU_SEQNUM(i)); | ||
1079 | } else { | ||
1080 | ath5k_hw_reg_write(ah, s_seq[0], | ||
1081 | AR5K_QUEUE_DCU_SEQNUM(0)); | ||
1082 | } | ||
1083 | |||
1084 | |||
1085 | if (ah->ah_version == AR5K_AR5211) { | ||
1086 | ath5k_hw_reg_write(ah, tsf_up, AR5K_TSF_U32); | ||
1087 | ath5k_hw_reg_write(ah, tsf_lo, AR5K_TSF_L32); | ||
1088 | } | ||
1089 | } | ||
1090 | |||
707 | ath5k_hw_reg_write(ah, s_ant, AR5K_DEFAULT_ANTENNA); | 1091 | ath5k_hw_reg_write(ah, s_ant, AR5K_DEFAULT_ANTENNA); |
708 | } | 1092 | } |
1093 | |||
1094 | /* Ledstate */ | ||
709 | AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, s_led[0]); | 1095 | AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, s_led[0]); |
1096 | |||
1097 | /* Gpio settings */ | ||
710 | ath5k_hw_reg_write(ah, s_led[1], AR5K_GPIOCR); | 1098 | ath5k_hw_reg_write(ah, s_led[1], AR5K_GPIOCR); |
711 | ath5k_hw_reg_write(ah, s_led[2], AR5K_GPIODO); | 1099 | ath5k_hw_reg_write(ah, s_led[2], AR5K_GPIODO); |
712 | 1100 | ||
1101 | /* Restore sta_id flags and preserve our mac address*/ | ||
1102 | ath5k_hw_reg_write(ah, AR5K_LOW_ID(ah->ah_sta_id), | ||
1103 | AR5K_STA_ID0); | ||
1104 | ath5k_hw_reg_write(ah, staid1_flags | AR5K_HIGH_ID(ah->ah_sta_id), | ||
1105 | AR5K_STA_ID1); | ||
1106 | |||
1107 | |||
713 | /* | 1108 | /* |
714 | * Misc | 1109 | * Configure PCU |
715 | */ | 1110 | */ |
1111 | |||
1112 | /* Restore bssid and bssid mask */ | ||
716 | /* XXX: add ah->aid once mac80211 gives this to us */ | 1113 | /* XXX: add ah->aid once mac80211 gives this to us */ |
717 | ath5k_hw_set_associd(ah, ah->ah_bssid, 0); | 1114 | ath5k_hw_set_associd(ah, ah->ah_bssid, 0); |
718 | 1115 | ||
1116 | /* Set PCU config */ | ||
719 | ath5k_hw_set_opmode(ah); | 1117 | ath5k_hw_set_opmode(ah); |
720 | /*PISR/SISR Not available on 5210*/ | 1118 | |
721 | if (ah->ah_version != AR5K_AR5210) { | 1119 | /* Clear any pending interrupts |
1120 | * PISR/SISR Not available on 5210 */ | ||
1121 | if (ah->ah_version != AR5K_AR5210) | ||
722 | ath5k_hw_reg_write(ah, 0xffffffff, AR5K_PISR); | 1122 | ath5k_hw_reg_write(ah, 0xffffffff, AR5K_PISR); |
723 | /* If we later allow tuning for this, store into sc structure */ | 1123 | |
724 | data = AR5K_TUNE_RSSI_THRES | | 1124 | /* Set RSSI/BRSSI thresholds |
725 | AR5K_TUNE_BMISS_THRES << AR5K_RSSI_THR_BMISS_S; | 1125 | * |
726 | ath5k_hw_reg_write(ah, data, AR5K_RSSI_THR); | 1126 | * Note: If we decide to set this value |
1127 | * dynamicaly, have in mind that when AR5K_RSSI_THR | ||
1128 | * register is read it might return 0x40 if we haven't | ||
1129 | * wrote anything to it plus BMISS RSSI threshold is zeroed. | ||
1130 | * So doing a save/restore procedure here isn't the right | ||
1131 | * choice. Instead store it on ath5k_hw */ | ||
1132 | ath5k_hw_reg_write(ah, (AR5K_TUNE_RSSI_THRES | | ||
1133 | AR5K_TUNE_BMISS_THRES << | ||
1134 | AR5K_RSSI_THR_BMISS_S), | ||
1135 | AR5K_RSSI_THR); | ||
1136 | |||
1137 | /* MIC QoS support */ | ||
1138 | if (ah->ah_mac_srev >= AR5K_SREV_AR2413) { | ||
1139 | ath5k_hw_reg_write(ah, 0x000100aa, AR5K_MIC_QOS_CTL); | ||
1140 | ath5k_hw_reg_write(ah, 0x00003210, AR5K_MIC_QOS_SEL); | ||
1141 | } | ||
1142 | |||
1143 | /* QoS NOACK Policy */ | ||
1144 | if (ah->ah_version == AR5K_AR5212) { | ||
1145 | ath5k_hw_reg_write(ah, | ||
1146 | AR5K_REG_SM(2, AR5K_QOS_NOACK_2BIT_VALUES) | | ||
1147 | AR5K_REG_SM(5, AR5K_QOS_NOACK_BIT_OFFSET) | | ||
1148 | AR5K_REG_SM(0, AR5K_QOS_NOACK_BYTE_OFFSET), | ||
1149 | AR5K_QOS_NOACK); | ||
727 | } | 1150 | } |
728 | 1151 | ||
1152 | |||
729 | /* | 1153 | /* |
730 | * Set Rx/Tx DMA Configuration | 1154 | * Configure PHY |
731 | * | ||
732 | * Set maximum DMA size (512) except for PCI-E cards since | ||
733 | * it causes rx overruns and tx errors (tested on 5424 but since | ||
734 | * rx overruns also occur on 5416/5418 with madwifi we set 128 | ||
735 | * for all PCI-E cards to be safe). | ||
736 | * | ||
737 | * In dumps this is 128 for allchips. | ||
738 | * | ||
739 | * XXX: need to check 5210 for this | ||
740 | * TODO: Check out tx triger level, it's always 64 on dumps but I | ||
741 | * guess we can tweak it and see how it goes ;-) | ||
742 | */ | 1155 | */ |
743 | dma_size = (pdev->is_pcie) ? AR5K_DMASIZE_128B : AR5K_DMASIZE_512B; | 1156 | |
744 | if (ah->ah_version != AR5K_AR5210) { | 1157 | /* Set channel on PHY */ |
745 | AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG, | 1158 | ret = ath5k_hw_channel(ah, channel); |
746 | AR5K_TXCFG_SDMAMR, dma_size); | 1159 | if (ret) |
747 | AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG, | 1160 | return ret; |
748 | AR5K_RXCFG_SDMAMW, dma_size); | ||
749 | } | ||
750 | 1161 | ||
751 | /* | 1162 | /* |
752 | * Enable the PHY and wait until completion | 1163 | * Enable the PHY and wait until completion |
1164 | * This includes BaseBand and Synthesizer | ||
1165 | * activation. | ||
753 | */ | 1166 | */ |
754 | ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT); | 1167 | ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT); |
755 | 1168 | ||
756 | /* | 1169 | /* |
757 | * On 5211+ read activation -> rx delay | 1170 | * On 5211+ read activation -> rx delay |
758 | * and use it. | 1171 | * and use it. |
1172 | * | ||
1173 | * TODO: Half/quarter rate support | ||
759 | */ | 1174 | */ |
760 | if (ah->ah_version != AR5K_AR5210) { | 1175 | if (ah->ah_version != AR5K_AR5210) { |
761 | data = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) & | 1176 | u32 delay; |
1177 | delay = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) & | ||
762 | AR5K_PHY_RX_DELAY_M; | 1178 | AR5K_PHY_RX_DELAY_M; |
763 | data = (channel->hw_value & CHANNEL_CCK) ? | 1179 | delay = (channel->hw_value & CHANNEL_CCK) ? |
764 | ((data << 2) / 22) : (data / 10); | 1180 | ((delay << 2) / 22) : (delay / 10); |
765 | 1181 | ||
766 | udelay(100 + (2 * data)); | 1182 | udelay(100 + (2 * delay)); |
767 | data = 0; | ||
768 | } else { | 1183 | } else { |
769 | mdelay(1); | 1184 | mdelay(1); |
770 | } | 1185 | } |
771 | 1186 | ||
772 | /* | 1187 | /* |
773 | * Perform ADC test (?) | 1188 | * Perform ADC test to see if baseband is ready |
1189 | * Set tx hold and check adc test register | ||
774 | */ | 1190 | */ |
775 | data = ath5k_hw_reg_read(ah, AR5K_PHY_TST1); | 1191 | phy_tst1 = ath5k_hw_reg_read(ah, AR5K_PHY_TST1); |
776 | ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1); | 1192 | ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1); |
777 | for (i = 0; i <= 20; i++) { | 1193 | for (i = 0; i <= 20; i++) { |
778 | if (!(ath5k_hw_reg_read(ah, AR5K_PHY_ADC_TEST) & 0x10)) | 1194 | if (!(ath5k_hw_reg_read(ah, AR5K_PHY_ADC_TEST) & 0x10)) |
779 | break; | 1195 | break; |
780 | udelay(200); | 1196 | udelay(200); |
781 | } | 1197 | } |
782 | ath5k_hw_reg_write(ah, data, AR5K_PHY_TST1); | 1198 | ath5k_hw_reg_write(ah, phy_tst1, AR5K_PHY_TST1); |
783 | data = 0; | ||
784 | 1199 | ||
785 | /* | 1200 | /* |
786 | * Start automatic gain calibration | 1201 | * Start automatic gain control calibration |
787 | * | 1202 | * |
788 | * During AGC calibration RX path is re-routed to | 1203 | * During AGC calibration RX path is re-routed to |
789 | * a signal detector so we don't receive anything. | 1204 | * a power detector so we don't receive anything. |
790 | * | 1205 | * |
791 | * This method is used to calibrate some static offsets | 1206 | * This method is used to calibrate some static offsets |
792 | * used together with on-the fly I/Q calibration (the | 1207 | * used together with on-the fly I/Q calibration (the |
793 | * one performed via ath5k_hw_phy_calibrate), that doesn't | 1208 | * one performed via ath5k_hw_phy_calibrate), that doesn't |
794 | * interrupt rx path. | 1209 | * interrupt rx path. |
795 | * | 1210 | * |
1211 | * While rx path is re-routed to the power detector we also | ||
1212 | * start a noise floor calibration, to measure the | ||
1213 | * card's noise floor (the noise we measure when we are not | ||
1214 | * transmiting or receiving anything). | ||
1215 | * | ||
796 | * If we are in a noisy environment AGC calibration may time | 1216 | * If we are in a noisy environment AGC calibration may time |
797 | * out. | 1217 | * out and/or noise floor calibration might timeout. |
798 | */ | 1218 | */ |
799 | AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL, | 1219 | AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL, |
800 | AR5K_PHY_AGCCTL_CAL); | 1220 | AR5K_PHY_AGCCTL_CAL); |
@@ -816,30 +1236,37 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, | |||
816 | AR5K_PHY_AGCCTL_CAL, 0, false)) { | 1236 | AR5K_PHY_AGCCTL_CAL, 0, false)) { |
817 | ATH5K_ERR(ah->ah_sc, "gain calibration timeout (%uMHz)\n", | 1237 | ATH5K_ERR(ah->ah_sc, "gain calibration timeout (%uMHz)\n", |
818 | channel->center_freq); | 1238 | channel->center_freq); |
819 | return -EAGAIN; | ||
820 | } | 1239 | } |
821 | 1240 | ||
822 | /* | 1241 | /* |
823 | * Start noise floor calibration | ||
824 | * | ||
825 | * If we run NF calibration before AGC, it always times out. | 1242 | * If we run NF calibration before AGC, it always times out. |
826 | * Binary HAL starts NF and AGC calibration at the same time | 1243 | * Binary HAL starts NF and AGC calibration at the same time |
827 | * and only waits for AGC to finish. I believe that's wrong because | 1244 | * and only waits for AGC to finish. Also if AGC or NF cal. |
828 | * during NF calibration, rx path is also routed to a detector, so if | 1245 | * times out, reset doesn't fail on binary HAL. I believe |
829 | * it doesn't finish we won't have RX. | 1246 | * that's wrong because since rx path is routed to a detector, |
830 | * | 1247 | * if cal. doesn't finish we won't have RX. Sam's HAL for AR5210/5211 |
831 | * XXX: Find an interval that's OK for all cards... | 1248 | * enables noise floor calibration after offset calibration and if noise |
1249 | * floor calibration fails, reset fails. I believe that's | ||
1250 | * a better approach, we just need to find a polling interval | ||
1251 | * that suits best, even if reset continues we need to make | ||
1252 | * sure that rx path is ready. | ||
832 | */ | 1253 | */ |
833 | ath5k_hw_noise_floor_calibration(ah, channel->center_freq); | 1254 | ath5k_hw_noise_floor_calibration(ah, channel->center_freq); |
834 | 1255 | ||
1256 | |||
1257 | /* | ||
1258 | * Configure QCUs/DCUs | ||
1259 | */ | ||
1260 | |||
1261 | /* TODO: HW Compression support for data queues */ | ||
1262 | /* TODO: Burst prefetch for data queues */ | ||
1263 | |||
835 | /* | 1264 | /* |
836 | * Reset queues and start beacon timers at the end of the reset routine | 1265 | * Reset queues and start beacon timers at the end of the reset routine |
1266 | * This also sets QCU mask on each DCU for 1:1 qcu to dcu mapping | ||
1267 | * Note: If we want we can assign multiple qcus on one dcu. | ||
837 | */ | 1268 | */ |
838 | for (i = 0; i < ah->ah_capabilities.cap_queues.q_tx_num; i++) { | 1269 | for (i = 0; i < ah->ah_capabilities.cap_queues.q_tx_num; i++) { |
839 | /*No QCU on 5210*/ | ||
840 | if (ah->ah_version != AR5K_AR5210) | ||
841 | AR5K_REG_WRITE_Q(ah, AR5K_QUEUE_QCUMASK(i), i); | ||
842 | |||
843 | ret = ath5k_hw_reset_tx_queue(ah, i); | 1270 | ret = ath5k_hw_reset_tx_queue(ah, i); |
844 | if (ret) { | 1271 | if (ret) { |
845 | ATH5K_ERR(ah->ah_sc, | 1272 | ATH5K_ERR(ah->ah_sc, |
@@ -848,14 +1275,40 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, | |||
848 | } | 1275 | } |
849 | } | 1276 | } |
850 | 1277 | ||
1278 | |||
1279 | /* | ||
1280 | * Configure DMA/Interrupts | ||
1281 | */ | ||
1282 | |||
1283 | /* | ||
1284 | * Set Rx/Tx DMA Configuration | ||
1285 | * | ||
1286 | * Set standard DMA size (128). Note that | ||
1287 | * a DMA size of 512 causes rx overruns and tx errors | ||
1288 | * on pci-e cards (tested on 5424 but since rx overruns | ||
1289 | * also occur on 5416/5418 with madwifi we set 128 | ||
1290 | * for all PCI-E cards to be safe). | ||
1291 | * | ||
1292 | * XXX: need to check 5210 for this | ||
1293 | * TODO: Check out tx triger level, it's always 64 on dumps but I | ||
1294 | * guess we can tweak it and see how it goes ;-) | ||
1295 | */ | ||
1296 | if (ah->ah_version != AR5K_AR5210) { | ||
1297 | AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG, | ||
1298 | AR5K_TXCFG_SDMAMR, AR5K_DMASIZE_128B); | ||
1299 | AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG, | ||
1300 | AR5K_RXCFG_SDMAMW, AR5K_DMASIZE_128B); | ||
1301 | } | ||
1302 | |||
851 | /* Pre-enable interrupts on 5211/5212*/ | 1303 | /* Pre-enable interrupts on 5211/5212*/ |
852 | if (ah->ah_version != AR5K_AR5210) | 1304 | if (ah->ah_version != AR5K_AR5210) |
853 | ath5k_hw_set_imr(ah, ah->ah_imr); | 1305 | ath5k_hw_set_imr(ah, ah->ah_imr); |
854 | 1306 | ||
855 | /* | 1307 | /* |
856 | * Set RF kill flags if supported by the device (read from the EEPROM) | 1308 | * Setup RFKill interrupt if rfkill flag is set on eeprom. |
857 | * Disable gpio_intr for now since it results system hang. | 1309 | * TODO: Use gpio pin and polarity infos from eeprom |
858 | * TODO: Handle this in ath5k_intr | 1310 | * TODO: Handle this in ath5k_intr because it'll result |
1311 | * a nasty interrupt storm. | ||
859 | */ | 1312 | */ |
860 | #if 0 | 1313 | #if 0 |
861 | if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header)) { | 1314 | if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header)) { |
@@ -868,33 +1321,12 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, | |||
868 | } | 1321 | } |
869 | #endif | 1322 | #endif |
870 | 1323 | ||
871 | /* | 1324 | /* Enable 32KHz clock function for AR5212+ chips |
872 | * Set the 32MHz reference clock on 5212 phy clock sleep register | 1325 | * Set clocks to 32KHz operation and use an |
873 | * | 1326 | * external 32KHz crystal when sleeping if one |
874 | * TODO: Find out how to switch to external 32Khz clock to save power | 1327 | * exists */ |
875 | */ | 1328 | if (ah->ah_version == AR5K_AR5212) |
876 | if (ah->ah_version == AR5K_AR5212) { | 1329 | ath5k_hw_set_sleep_clock(ah, true); |
877 | ath5k_hw_reg_write(ah, AR5K_PHY_SCR_32MHZ, AR5K_PHY_SCR); | ||
878 | ath5k_hw_reg_write(ah, AR5K_PHY_SLMT_32MHZ, AR5K_PHY_SLMT); | ||
879 | ath5k_hw_reg_write(ah, AR5K_PHY_SCAL_32MHZ, AR5K_PHY_SCAL); | ||
880 | ath5k_hw_reg_write(ah, AR5K_PHY_SCLOCK_32MHZ, AR5K_PHY_SCLOCK); | ||
881 | ath5k_hw_reg_write(ah, AR5K_PHY_SDELAY_32MHZ, AR5K_PHY_SDELAY); | ||
882 | ath5k_hw_reg_write(ah, ah->ah_phy_spending, AR5K_PHY_SPENDING); | ||
883 | |||
884 | data = ath5k_hw_reg_read(ah, AR5K_USEC_5211) & 0xffffc07f ; | ||
885 | data |= (ah->ah_phy_spending == AR5K_PHY_SPENDING_18) ? | ||
886 | 0x00000f80 : 0x00001380 ; | ||
887 | ath5k_hw_reg_write(ah, data, AR5K_USEC_5211); | ||
888 | data = 0; | ||
889 | } | ||
890 | |||
891 | if (ah->ah_version == AR5K_AR5212) { | ||
892 | ath5k_hw_reg_write(ah, 0x000100aa, 0x8118); | ||
893 | ath5k_hw_reg_write(ah, 0x00003210, 0x811c); | ||
894 | ath5k_hw_reg_write(ah, 0x00000052, 0x8108); | ||
895 | if (ah->ah_mac_srev >= AR5K_SREV_AR2413) | ||
896 | ath5k_hw_reg_write(ah, 0x00000004, 0x8120); | ||
897 | } | ||
898 | 1330 | ||
899 | /* | 1331 | /* |
900 | * Disable beacons and reset the register | 1332 | * Disable beacons and reset the register |