aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/ath/ath.h14
-rw-r--r--drivers/net/wireless/ath/ath9k/ani.c64
-rw-r--r--drivers/net/wireless/ath/ath9k/ani.h8
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.c7
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c12
-rw-r--r--drivers/net/wireless/ath/ath9k/reg.h11
-rw-r--r--drivers/net/wireless/ath/hw.c59
-rw-r--r--drivers/net/wireless/ath/reg.h11
9 files changed, 101 insertions, 87 deletions
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h
index b36d9d770ff1..501050c0296f 100644
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
@@ -19,6 +19,7 @@
19 19
20#include <linux/skbuff.h> 20#include <linux/skbuff.h>
21#include <linux/if_ether.h> 21#include <linux/if_ether.h>
22#include <linux/spinlock.h>
22#include <net/mac80211.h> 23#include <net/mac80211.h>
23 24
24/* 25/*
@@ -42,6 +43,13 @@ struct ath_ani {
42 struct timer_list timer; 43 struct timer_list timer;
43}; 44};
44 45
46struct ath_cycle_counters {
47 u32 cycles;
48 u32 rx_busy;
49 u32 rx_frame;
50 u32 tx_frame;
51};
52
45enum ath_device_state { 53enum ath_device_state {
46 ATH_HW_UNAVAILABLE, 54 ATH_HW_UNAVAILABLE,
47 ATH_HW_INITIALIZED, 55 ATH_HW_INITIALIZED,
@@ -147,6 +155,10 @@ struct ath_common {
147 155
148 unsigned int clockrate; 156 unsigned int clockrate;
149 157
158 spinlock_t cc_lock;
159 struct ath_cycle_counters cc_ani;
160 struct ath_cycle_counters cc_survey;
161
150 struct ath_regulatory regulatory; 162 struct ath_regulatory regulatory;
151 const struct ath_ops *ops; 163 const struct ath_ops *ops;
152 const struct ath_bus_ops *bus_ops; 164 const struct ath_bus_ops *bus_ops;
@@ -163,5 +175,7 @@ int ath_key_config(struct ath_common *common,
163 struct ieee80211_sta *sta, 175 struct ieee80211_sta *sta,
164 struct ieee80211_key_conf *key); 176 struct ieee80211_key_conf *key);
165bool ath_hw_keyreset(struct ath_common *common, u16 entry); 177bool ath_hw_keyreset(struct ath_common *common, u16 entry);
178void ath_hw_cycle_counters_update(struct ath_common *common);
179int32_t ath_hw_get_listen_time(struct ath_common *common);
166 180
167#endif /* ATH_H */ 181#endif /* ATH_H */
diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
index f2aa68405d2f..3aa8fb1ad77f 100644
--- a/drivers/net/wireless/ath/ath9k/ani.c
+++ b/drivers/net/wireless/ath/ath9k/ani.c
@@ -465,18 +465,6 @@ static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah)
465 ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel - 1); 465 ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel - 1);
466} 466}
467 467
468static int32_t ath9k_hw_ani_get_listen_time(struct ath_hw *ah)
469{
470 struct ath_common *common = ath9k_hw_common(ah);
471 int32_t listen_time;
472
473 ath9k_hw_update_cycle_counters(ah);
474 listen_time = ah->listen_time / (common->clockrate * 1000);
475 ah->listen_time = 0;
476
477 return listen_time;
478}
479
480static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning) 468static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning)
481{ 469{
482 struct ar5416AniState *aniState; 470 struct ar5416AniState *aniState;
@@ -655,7 +643,9 @@ static void ath9k_hw_ani_read_counters(struct ath_hw *ah)
655 u32 phyCnt1, phyCnt2; 643 u32 phyCnt1, phyCnt2;
656 int32_t listenTime; 644 int32_t listenTime;
657 645
658 listenTime = ath9k_hw_ani_get_listen_time(ah); 646 ath_hw_cycle_counters_update(common);
647 listenTime = ath_hw_get_listen_time(common);
648
659 if (listenTime < 0) { 649 if (listenTime < 0) {
660 ah->stats.ast_ani_lneg++; 650 ah->stats.ast_ani_lneg++;
661 ath9k_ani_restart(ah); 651 ath9k_ani_restart(ah);
@@ -796,54 +786,6 @@ void ath9k_hw_disable_mib_counters(struct ath_hw *ah)
796} 786}
797EXPORT_SYMBOL(ath9k_hw_disable_mib_counters); 787EXPORT_SYMBOL(ath9k_hw_disable_mib_counters);
798 788
799void ath9k_hw_update_cycle_counters(struct ath_hw *ah)
800{
801 struct ath_cycle_counters cc;
802 bool clear;
803
804 memcpy(&cc, &ah->cc, sizeof(cc));
805
806 /* freeze counters */
807 REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC);
808
809 ah->cc.cycles = REG_READ(ah, AR_CCCNT);
810 if (ah->cc.cycles < cc.cycles) {
811 clear = true;
812 goto skip;
813 }
814
815 ah->cc.rx_clear = REG_READ(ah, AR_RCCNT);
816 ah->cc.rx_frame = REG_READ(ah, AR_RFCNT);
817 ah->cc.tx_frame = REG_READ(ah, AR_TFCNT);
818
819 /* prevent wraparound */
820 if (ah->cc.cycles & BIT(31))
821 clear = true;
822
823#define CC_DELTA(_field, _reg) ah->cc_delta._field += ah->cc._field - cc._field
824 CC_DELTA(cycles, AR_CCCNT);
825 CC_DELTA(rx_frame, AR_RFCNT);
826 CC_DELTA(rx_clear, AR_RCCNT);
827 CC_DELTA(tx_frame, AR_TFCNT);
828#undef CC_DELTA
829
830 ah->listen_time += (ah->cc.cycles - cc.cycles) -
831 ((ah->cc.rx_frame - cc.rx_frame) +
832 (ah->cc.tx_frame - cc.tx_frame));
833
834skip:
835 if (clear) {
836 REG_WRITE(ah, AR_CCCNT, 0);
837 REG_WRITE(ah, AR_RFCNT, 0);
838 REG_WRITE(ah, AR_RCCNT, 0);
839 REG_WRITE(ah, AR_TFCNT, 0);
840 memset(&ah->cc, 0, sizeof(ah->cc));
841 }
842
843 /* unfreeze counters */
844 REG_WRITE(ah, AR_MIBC, 0);
845}
846
847/* 789/*
848 * Process a MIB interrupt. We may potentially be invoked because 790 * Process a MIB interrupt. We may potentially be invoked because
849 * any of the MIB counters overflow/trigger so don't assume we're 791 * any of the MIB counters overflow/trigger so don't assume we're
diff --git a/drivers/net/wireless/ath/ath9k/ani.h b/drivers/net/wireless/ath/ath9k/ani.h
index 98cfd8154c71..0cd6783de883 100644
--- a/drivers/net/wireless/ath/ath9k/ani.h
+++ b/drivers/net/wireless/ath/ath9k/ani.h
@@ -93,13 +93,6 @@ struct ath9k_mib_stats {
93 u32 beacons; 93 u32 beacons;
94}; 94};
95 95
96struct ath_cycle_counters {
97 u32 cycles;
98 u32 rx_frame;
99 u32 rx_clear;
100 u32 tx_frame;
101};
102
103/* INI default values for ANI registers */ 96/* INI default values for ANI registers */
104struct ath9k_ani_default { 97struct ath9k_ani_default {
105 u16 m1ThreshLow; 98 u16 m1ThreshLow;
@@ -164,7 +157,6 @@ struct ar5416Stats {
164 157
165void ath9k_enable_mib_counters(struct ath_hw *ah); 158void ath9k_enable_mib_counters(struct ath_hw *ah);
166void ath9k_hw_disable_mib_counters(struct ath_hw *ah); 159void ath9k_hw_disable_mib_counters(struct ath_hw *ah);
167void ath9k_hw_update_cycle_counters(struct ath_hw *ah);
168void ath9k_hw_ani_setup(struct ath_hw *ah); 160void ath9k_hw_ani_setup(struct ath_hw *ah);
169void ath9k_hw_ani_init(struct ath_hw *ah); 161void ath9k_hw_ani_init(struct ath_hw *ah);
170int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah, 162int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah,
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index efb05599b84c..669b777729b3 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -1254,13 +1254,12 @@ void ar9003_hw_bb_watchdog_dbg_info(struct ath_hw *ah)
1254 "** BB mode: BB_gen_controls=0x%08x **\n", 1254 "** BB mode: BB_gen_controls=0x%08x **\n",
1255 REG_READ(ah, AR_PHY_GEN_CTRL)); 1255 REG_READ(ah, AR_PHY_GEN_CTRL));
1256 1256
1257 ath9k_hw_update_cycle_counters(ah); 1257#define PCT(_field) (common->cc_survey._field * 100 / common->cc_survey.cycles)
1258#define PCT(_field) (ah->cc_delta._field * 100 / ah->cc_delta.cycles) 1258 if (common->cc_survey.cycles)
1259 if (ah->cc_delta.cycles)
1260 ath_print(common, ATH_DBG_RESET, 1259 ath_print(common, ATH_DBG_RESET,
1261 "** BB busy times: rx_clear=%d%%, " 1260 "** BB busy times: rx_clear=%d%%, "
1262 "rx_frame=%d%%, tx_frame=%d%% **\n", 1261 "rx_frame=%d%%, tx_frame=%d%% **\n",
1263 PCT(rx_clear), PCT(rx_frame), PCT(tx_frame)); 1262 PCT(rx_busy), PCT(rx_frame), PCT(tx_frame));
1264 1263
1265 ath_print(common, ATH_DBG_RESET, 1264 ath_print(common, ATH_DBG_RESET,
1266 "==== BB update: done ====\n\n"); 1265 "==== BB update: done ====\n\n");
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 87627dd63463..7f696c82ca0a 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -740,8 +740,6 @@ struct ath_hw {
740 int coarse_low[5]; 740 int coarse_low[5];
741 int firpwr[5]; 741 int firpwr[5];
742 enum ath9k_ani_cmd ani_function; 742 enum ath9k_ani_cmd ani_function;
743 struct ath_cycle_counters cc, cc_delta;
744 int32_t listen_time;
745 743
746 /* Bluetooth coexistance */ 744 /* Bluetooth coexistance */
747 struct ath_btcoex_hw btcoex_hw; 745 struct ath_btcoex_hw btcoex_hw;
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 74c2dc8a8b8a..360c6f5e843a 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -399,6 +399,7 @@ void ath_ani_calibrate(unsigned long data)
399 bool aniflag = false; 399 bool aniflag = false;
400 unsigned int timestamp = jiffies_to_msecs(jiffies); 400 unsigned int timestamp = jiffies_to_msecs(jiffies);
401 u32 cal_interval, short_cal_interval, long_cal_interval; 401 u32 cal_interval, short_cal_interval, long_cal_interval;
402 unsigned long flags;
402 403
403 if (ah->caldata && ah->caldata->nfcal_interference) 404 if (ah->caldata && ah->caldata->nfcal_interference)
404 long_cal_interval = ATH_LONG_CALINTERVAL_INT; 405 long_cal_interval = ATH_LONG_CALINTERVAL_INT;
@@ -449,8 +450,11 @@ void ath_ani_calibrate(unsigned long data)
449 /* Skip all processing if there's nothing to do. */ 450 /* Skip all processing if there's nothing to do. */
450 if (longcal || shortcal || aniflag) { 451 if (longcal || shortcal || aniflag) {
451 /* Call ANI routine if necessary */ 452 /* Call ANI routine if necessary */
452 if (aniflag) 453 if (aniflag) {
454 spin_lock_irqsave(&common->cc_lock, flags);
453 ath9k_hw_ani_monitor(ah, ah->curchan); 455 ath9k_hw_ani_monitor(ah, ah->curchan);
456 spin_unlock_irqrestore(&common->cc_lock, flags);
457 }
454 458
455 /* Perform calibration if necessary */ 459 /* Perform calibration if necessary */
456 if (longcal || shortcal) { 460 if (longcal || shortcal) {
@@ -635,6 +639,7 @@ irqreturn_t ath_isr(int irq, void *dev)
635 639
636 struct ath_softc *sc = dev; 640 struct ath_softc *sc = dev;
637 struct ath_hw *ah = sc->sc_ah; 641 struct ath_hw *ah = sc->sc_ah;
642 struct ath_common *common = ath9k_hw_common(ah);
638 enum ath9k_int status; 643 enum ath9k_int status;
639 bool sched = false; 644 bool sched = false;
640 645
@@ -684,7 +689,12 @@ irqreturn_t ath_isr(int irq, void *dev)
684 689
685 if ((ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) && 690 if ((ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) &&
686 (status & ATH9K_INT_BB_WATCHDOG)) { 691 (status & ATH9K_INT_BB_WATCHDOG)) {
692
693 spin_lock(&common->cc_lock);
694 ath_hw_cycle_counters_update(common);
687 ar9003_hw_bb_watchdog_dbg_info(ah); 695 ar9003_hw_bb_watchdog_dbg_info(ah);
696 spin_unlock(&common->cc_lock);
697
688 goto chip_reset; 698 goto chip_reset;
689 } 699 }
690 700
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index 6d01e501b9b4..017617894533 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -107,12 +107,6 @@
107#define AR_RXCFG_DMASZ_256B 6 107#define AR_RXCFG_DMASZ_256B 6
108#define AR_RXCFG_DMASZ_512B 7 108#define AR_RXCFG_DMASZ_512B 7
109 109
110#define AR_MIBC 0x0040
111#define AR_MIBC_COW 0x00000001
112#define AR_MIBC_FMC 0x00000002
113#define AR_MIBC_CMC 0x00000004
114#define AR_MIBC_MCS 0x00000008
115
116#define AR_TOPS 0x0044 110#define AR_TOPS 0x0044
117#define AR_TOPS_MASK 0x0000FFFF 111#define AR_TOPS_MASK 0x0000FFFF
118 112
@@ -1524,11 +1518,6 @@ enum {
1524#define AR_TPC_CHIRP 0x003f0000 1518#define AR_TPC_CHIRP 0x003f0000
1525#define AR_TPC_CHIRP_S 0x16 1519#define AR_TPC_CHIRP_S 0x16
1526 1520
1527#define AR_TFCNT 0x80ec
1528#define AR_RFCNT 0x80f0
1529#define AR_RCCNT 0x80f4
1530#define AR_CCCNT 0x80f8
1531
1532#define AR_QUIET1 0x80fc 1521#define AR_QUIET1 0x80fc
1533#define AR_QUIET1_NEXT_QUIET_S 0 1522#define AR_QUIET1_NEXT_QUIET_S 0
1534#define AR_QUIET1_NEXT_QUIET_M 0x0000ffff 1523#define AR_QUIET1_NEXT_QUIET_M 0x0000ffff
diff --git a/drivers/net/wireless/ath/hw.c b/drivers/net/wireless/ath/hw.c
index a8f81ea09f14..183c28281385 100644
--- a/drivers/net/wireless/ath/hw.c
+++ b/drivers/net/wireless/ath/hw.c
@@ -124,3 +124,62 @@ void ath_hw_setbssidmask(struct ath_common *common)
124 REG_WRITE(ah, get_unaligned_le16(common->bssidmask + 4), AR_BSSMSKU); 124 REG_WRITE(ah, get_unaligned_le16(common->bssidmask + 4), AR_BSSMSKU);
125} 125}
126EXPORT_SYMBOL(ath_hw_setbssidmask); 126EXPORT_SYMBOL(ath_hw_setbssidmask);
127
128
129/**
130 * ath_hw_cycle_counters_update - common function to update cycle counters
131 *
132 * @common: the ath_common struct for the device.
133 *
134 * This function is used to update all cycle counters in one place.
135 * It has to be called while holding common->cc_lock!
136 */
137void ath_hw_cycle_counters_update(struct ath_common *common)
138{
139 u32 cycles, busy, rx, tx;
140 void *ah = common->ah;
141
142 /* freeze */
143 REG_WRITE(ah, AR_MIBC_FMC, AR_MIBC);
144
145 /* read */
146 cycles = REG_READ(ah, AR_CCCNT);
147 busy = REG_READ(ah, AR_RCCNT);
148 rx = REG_READ(ah, AR_RFCNT);
149 tx = REG_READ(ah, AR_TFCNT);
150
151 /* clear */
152 REG_WRITE(ah, 0, AR_CCCNT);
153 REG_WRITE(ah, 0, AR_RFCNT);
154 REG_WRITE(ah, 0, AR_RCCNT);
155 REG_WRITE(ah, 0, AR_TFCNT);
156
157 /* unfreeze */
158 REG_WRITE(ah, 0, AR_MIBC);
159
160 /* update all cycle counters here */
161 common->cc_ani.cycles += cycles;
162 common->cc_ani.rx_busy += busy;
163 common->cc_ani.rx_frame += rx;
164 common->cc_ani.tx_frame += tx;
165
166 common->cc_survey.cycles += cycles;
167 common->cc_survey.rx_busy += busy;
168 common->cc_survey.rx_frame += rx;
169 common->cc_survey.tx_frame += tx;
170}
171EXPORT_SYMBOL(ath_hw_cycle_counters_update);
172
173int32_t ath_hw_get_listen_time(struct ath_common *common)
174{
175 struct ath_cycle_counters *cc = &common->cc_ani;
176 int32_t listen_time;
177
178 listen_time = (cc->cycles - cc->rx_frame - cc->tx_frame) /
179 (common->clockrate * 1000);
180
181 memset(cc, 0, sizeof(*cc));
182
183 return listen_time;
184}
185EXPORT_SYMBOL(ath_hw_get_listen_time);
diff --git a/drivers/net/wireless/ath/reg.h b/drivers/net/wireless/ath/reg.h
index e798ef476581..298e53f3fa48 100644
--- a/drivers/net/wireless/ath/reg.h
+++ b/drivers/net/wireless/ath/reg.h
@@ -17,6 +17,12 @@
17#ifndef ATH_REGISTERS_H 17#ifndef ATH_REGISTERS_H
18#define ATH_REGISTERS_H 18#define ATH_REGISTERS_H
19 19
20#define AR_MIBC 0x0040
21#define AR_MIBC_COW 0x00000001
22#define AR_MIBC_FMC 0x00000002
23#define AR_MIBC_CMC 0x00000004
24#define AR_MIBC_MCS 0x00000008
25
20/* 26/*
21 * BSSID mask registers. See ath_hw_set_bssid_mask() 27 * BSSID mask registers. See ath_hw_set_bssid_mask()
22 * for detailed documentation about these registers. 28 * for detailed documentation about these registers.
@@ -24,6 +30,11 @@
24#define AR_BSSMSKL 0x80e0 30#define AR_BSSMSKL 0x80e0
25#define AR_BSSMSKU 0x80e4 31#define AR_BSSMSKU 0x80e4
26 32
33#define AR_TFCNT 0x80ec
34#define AR_RFCNT 0x80f0
35#define AR_RCCNT 0x80f4
36#define AR_CCCNT 0x80f8
37
27#define AR_KEYTABLE_0 0x8800 38#define AR_KEYTABLE_0 0x8800
28#define AR_KEYTABLE(_n) (AR_KEYTABLE_0 + ((_n)*32)) 39#define AR_KEYTABLE(_n) (AR_KEYTABLE_0 + ((_n)*32))
29#define AR_KEY_CACHE_SIZE 128 40#define AR_KEY_CACHE_SIZE 128