diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath5k/ani.c')
-rw-r--r-- | drivers/net/wireless/ath/ath5k/ani.c | 87 |
1 files changed, 37 insertions, 50 deletions
diff --git a/drivers/net/wireless/ath/ath5k/ani.c b/drivers/net/wireless/ath/ath5k/ani.c index 26dbe65fedb0..f915f404302d 100644 --- a/drivers/net/wireless/ath/ath5k/ani.c +++ b/drivers/net/wireless/ath/ath5k/ani.c | |||
@@ -58,20 +58,20 @@ ath5k_ani_set_noise_immunity_level(struct ath5k_hw *ah, int level) | |||
58 | { | 58 | { |
59 | /* TODO: | 59 | /* TODO: |
60 | * ANI documents suggest the following five levels to use, but the HAL | 60 | * ANI documents suggest the following five levels to use, but the HAL |
61 | * and ath9k use only use the last two levels, making this | 61 | * and ath9k use only the last two levels, making this |
62 | * essentially an on/off option. There *may* be a reason for this (???), | 62 | * essentially an on/off option. There *may* be a reason for this (???), |
63 | * so i stick with the HAL version for now... | 63 | * so i stick with the HAL version for now... |
64 | */ | 64 | */ |
65 | #if 0 | 65 | #if 0 |
66 | const s8 hi[] = { -18, -18, -16, -14, -12 }; | 66 | static const s8 lo[] = { -52, -56, -60, -64, -70 }; |
67 | const s8 lo[] = { -52, -56, -60, -64, -70 }; | 67 | static const s8 hi[] = { -18, -18, -16, -14, -12 }; |
68 | const s8 sz[] = { -34, -41, -48, -55, -62 }; | 68 | static const s8 sz[] = { -34, -41, -48, -55, -62 }; |
69 | const s8 fr[] = { -70, -72, -75, -78, -80 }; | 69 | static const s8 fr[] = { -70, -72, -75, -78, -80 }; |
70 | #else | 70 | #else |
71 | const s8 sz[] = { -55, -62 }; | 71 | static const s8 lo[] = { -64, -70 }; |
72 | const s8 lo[] = { -64, -70 }; | 72 | static const s8 hi[] = { -14, -12 }; |
73 | const s8 hi[] = { -14, -12 }; | 73 | static const s8 sz[] = { -55, -62 }; |
74 | const s8 fr[] = { -78, -80 }; | 74 | static const s8 fr[] = { -78, -80 }; |
75 | #endif | 75 | #endif |
76 | if (level < 0 || level >= ARRAY_SIZE(sz)) { | 76 | if (level < 0 || level >= ARRAY_SIZE(sz)) { |
77 | ATH5K_ERR(ah->ah_sc, "noise immuniy level %d out of range", | 77 | ATH5K_ERR(ah->ah_sc, "noise immuniy level %d out of range", |
@@ -102,7 +102,7 @@ ath5k_ani_set_noise_immunity_level(struct ath5k_hw *ah, int level) | |||
102 | void | 102 | void |
103 | ath5k_ani_set_spur_immunity_level(struct ath5k_hw *ah, int level) | 103 | ath5k_ani_set_spur_immunity_level(struct ath5k_hw *ah, int level) |
104 | { | 104 | { |
105 | const int val[] = { 2, 4, 6, 8, 10, 12, 14, 16 }; | 105 | static const int val[] = { 2, 4, 6, 8, 10, 12, 14, 16 }; |
106 | 106 | ||
107 | if (level < 0 || level >= ARRAY_SIZE(val) || | 107 | if (level < 0 || level >= ARRAY_SIZE(val) || |
108 | level > ah->ah_sc->ani_state.max_spur_level) { | 108 | level > ah->ah_sc->ani_state.max_spur_level) { |
@@ -127,7 +127,7 @@ ath5k_ani_set_spur_immunity_level(struct ath5k_hw *ah, int level) | |||
127 | void | 127 | void |
128 | ath5k_ani_set_firstep_level(struct ath5k_hw *ah, int level) | 128 | ath5k_ani_set_firstep_level(struct ath5k_hw *ah, int level) |
129 | { | 129 | { |
130 | const int val[] = { 0, 4, 8 }; | 130 | static const int val[] = { 0, 4, 8 }; |
131 | 131 | ||
132 | if (level < 0 || level >= ARRAY_SIZE(val)) { | 132 | if (level < 0 || level >= ARRAY_SIZE(val)) { |
133 | ATH5K_ERR(ah->ah_sc, "firstep level %d out of range", level); | 133 | ATH5K_ERR(ah->ah_sc, "firstep level %d out of range", level); |
@@ -151,12 +151,12 @@ ath5k_ani_set_firstep_level(struct ath5k_hw *ah, int level) | |||
151 | void | 151 | void |
152 | ath5k_ani_set_ofdm_weak_signal_detection(struct ath5k_hw *ah, bool on) | 152 | ath5k_ani_set_ofdm_weak_signal_detection(struct ath5k_hw *ah, bool on) |
153 | { | 153 | { |
154 | const int m1l[] = { 127, 50 }; | 154 | static const int m1l[] = { 127, 50 }; |
155 | const int m2l[] = { 127, 40 }; | 155 | static const int m2l[] = { 127, 40 }; |
156 | const int m1[] = { 127, 0x4d }; | 156 | static const int m1[] = { 127, 0x4d }; |
157 | const int m2[] = { 127, 0x40 }; | 157 | static const int m2[] = { 127, 0x40 }; |
158 | const int m2cnt[] = { 31, 16 }; | 158 | static const int m2cnt[] = { 31, 16 }; |
159 | const int m2lcnt[] = { 63, 48 }; | 159 | static const int m2lcnt[] = { 63, 48 }; |
160 | 160 | ||
161 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_WEAK_OFDM_LOW_THR, | 161 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_WEAK_OFDM_LOW_THR, |
162 | AR5K_PHY_WEAK_OFDM_LOW_THR_M1, m1l[on]); | 162 | AR5K_PHY_WEAK_OFDM_LOW_THR_M1, m1l[on]); |
@@ -192,7 +192,7 @@ ath5k_ani_set_ofdm_weak_signal_detection(struct ath5k_hw *ah, bool on) | |||
192 | void | 192 | void |
193 | ath5k_ani_set_cck_weak_signal_detection(struct ath5k_hw *ah, bool on) | 193 | ath5k_ani_set_cck_weak_signal_detection(struct ath5k_hw *ah, bool on) |
194 | { | 194 | { |
195 | const int val[] = { 8, 6 }; | 195 | static const int val[] = { 8, 6 }; |
196 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_CCK_CROSSCORR, | 196 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_CCK_CROSSCORR, |
197 | AR5K_PHY_CCK_CROSSCORR_WEAK_SIG_THR, val[on]); | 197 | AR5K_PHY_CCK_CROSSCORR_WEAK_SIG_THR, val[on]); |
198 | ah->ah_sc->ani_state.cck_weak_sig = on; | 198 | ah->ah_sc->ani_state.cck_weak_sig = on; |
@@ -216,7 +216,7 @@ static void | |||
216 | ath5k_ani_raise_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as, | 216 | ath5k_ani_raise_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as, |
217 | bool ofdm_trigger) | 217 | bool ofdm_trigger) |
218 | { | 218 | { |
219 | int rssi = ah->ah_beacon_rssi_avg.avg; | 219 | int rssi = ewma_read(&ah->ah_beacon_rssi_avg); |
220 | 220 | ||
221 | ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "raise immunity (%s)", | 221 | ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "raise immunity (%s)", |
222 | ofdm_trigger ? "ODFM" : "CCK"); | 222 | ofdm_trigger ? "ODFM" : "CCK"); |
@@ -301,7 +301,7 @@ ath5k_ani_raise_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as, | |||
301 | static void | 301 | static void |
302 | ath5k_ani_lower_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as) | 302 | ath5k_ani_lower_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as) |
303 | { | 303 | { |
304 | int rssi = ah->ah_beacon_rssi_avg.avg; | 304 | int rssi = ewma_read(&ah->ah_beacon_rssi_avg); |
305 | 305 | ||
306 | ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "lower immunity"); | 306 | ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "lower immunity"); |
307 | 307 | ||
@@ -355,41 +355,28 @@ ath5k_ani_lower_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as) | |||
355 | 355 | ||
356 | 356 | ||
357 | /** | 357 | /** |
358 | * ath5k_hw_ani_get_listen_time() - Calculate time spent listening | 358 | * ath5k_hw_ani_get_listen_time() - Update counters and return listening time |
359 | * | 359 | * |
360 | * Return an approximation of the time spent "listening" in milliseconds (ms) | 360 | * Return an approximation of the time spent "listening" in milliseconds (ms) |
361 | * since the last call of this function by deducting the cycles spent | 361 | * since the last call of this function. |
362 | * transmitting and receiving from the total cycle count. | 362 | * Save a snapshot of the counter values for debugging/statistics. |
363 | * Save profile count values for debugging/statistics and because we might want | ||
364 | * to use them later. | ||
365 | * | ||
366 | * We assume no one else clears these registers! | ||
367 | */ | 363 | */ |
368 | static int | 364 | static int |
369 | ath5k_hw_ani_get_listen_time(struct ath5k_hw *ah, struct ath5k_ani_state *as) | 365 | ath5k_hw_ani_get_listen_time(struct ath5k_hw *ah, struct ath5k_ani_state *as) |
370 | { | 366 | { |
367 | struct ath_common *common = ath5k_hw_common(ah); | ||
371 | int listen; | 368 | int listen; |
372 | 369 | ||
373 | /* freeze */ | 370 | spin_lock_bh(&common->cc_lock); |
374 | ath5k_hw_reg_write(ah, AR5K_MIBC_FMC, AR5K_MIBC); | 371 | |
375 | /* read */ | 372 | ath_hw_cycle_counters_update(common); |
376 | as->pfc_cycles = ath5k_hw_reg_read(ah, AR5K_PROFCNT_CYCLE); | 373 | memcpy(&as->last_cc, &common->cc_ani, sizeof(as->last_cc)); |
377 | as->pfc_busy = ath5k_hw_reg_read(ah, AR5K_PROFCNT_RXCLR); | 374 | |
378 | as->pfc_tx = ath5k_hw_reg_read(ah, AR5K_PROFCNT_TX); | 375 | /* clears common->cc_ani */ |
379 | as->pfc_rx = ath5k_hw_reg_read(ah, AR5K_PROFCNT_RX); | 376 | listen = ath_hw_get_listen_time(common); |
380 | /* clear */ | 377 | |
381 | ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_TX); | 378 | spin_unlock_bh(&common->cc_lock); |
382 | ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RX); | 379 | |
383 | ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RXCLR); | ||
384 | ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_CYCLE); | ||
385 | /* un-freeze */ | ||
386 | ath5k_hw_reg_write(ah, 0, AR5K_MIBC); | ||
387 | |||
388 | /* TODO: where does 44000 come from? (11g clock rate?) */ | ||
389 | listen = (as->pfc_cycles - as->pfc_rx - as->pfc_tx) / 44000; | ||
390 | |||
391 | if (as->pfc_cycles == 0 || listen < 0) | ||
392 | return 0; | ||
393 | return listen; | 380 | return listen; |
394 | } | 381 | } |
395 | 382 | ||
@@ -552,9 +539,9 @@ ath5k_ani_mib_intr(struct ath5k_hw *ah) | |||
552 | if (ah->ah_sc->ani_state.ani_mode != ATH5K_ANI_MODE_AUTO) | 539 | if (ah->ah_sc->ani_state.ani_mode != ATH5K_ANI_MODE_AUTO) |
553 | return; | 540 | return; |
554 | 541 | ||
555 | /* if one of the errors triggered, we can get a superfluous second | 542 | /* If one of the errors triggered, we can get a superfluous second |
556 | * interrupt, even though we have already reset the register. the | 543 | * interrupt, even though we have already reset the register. The |
557 | * function detects that so we can return early */ | 544 | * function detects that so we can return early. */ |
558 | if (ath5k_ani_save_and_clear_phy_errors(ah, as) == 0) | 545 | if (ath5k_ani_save_and_clear_phy_errors(ah, as) == 0) |
559 | return; | 546 | return; |
560 | 547 | ||