aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath5k
diff options
context:
space:
mode:
authorNick Kossifidis <mick@madwifi-project.org>2009-02-08 23:12:58 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-02-13 13:44:49 -0500
commite8f055f0c3ba226ca599c14c2e5fe829f6f57cbb (patch)
tree02479a6c4aaa388b13866f0fb596433630863083 /drivers/net/wireless/ath5k
parenta406c139091902acebafb2462b64ba498901e820 (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.h11
-rw-r--r--drivers/net/wireless/ath5k/attach.c16
-rw-r--r--drivers/net/wireless/ath5k/eeprom.c14
-rw-r--r--drivers/net/wireless/ath5k/eeprom.h1
-rw-r--r--drivers/net/wireless/ath5k/reg.h56
-rw-r--r--drivers/net/wireless/ath5k/reset.c930
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 */
1157extern int ath5k_eeprom_init(struct ath5k_hw *ah); 1157extern int ath5k_eeprom_init(struct ath5k_hw *ah);
1158extern int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac); 1158extern int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac);
1159extern bool ath5k_eeprom_is_hb63(struct ath5k_hw *ah);
1159 1160
1160/* Protocol Control Unit Functions */ 1161/* Protocol Control Unit Functions */
1161extern int ath5k_hw_set_opmode(struct ath5k_hw *ah); 1162extern 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 */
1262static inline unsigned int ath5k_hw_htoclock(unsigned int usec, bool turbo) 1264static 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 */
1270static inline unsigned int ath5k_hw_clocktoh(unsigned int clock, bool turbo) 1273static 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
1452bool 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 */
45static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah, 50static 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 */
104static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah, 127static 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 */
280int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial) 304int 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 */
446static 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
540static 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 */
561static 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
663static 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 */
408int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, 810int 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