diff mbox

[1/5] ath: Add common function for reading cycle counters

Message ID 20101005095510.3083.46174.stgit@tt-desk (mailing list archive)
State Not Applicable, archived
Headers show

Commit Message

Bruno Randolf Oct. 5, 2010, 9:55 a.m. UTC
None
diff mbox

Patch

diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h
index dd236c3..699c904 100644
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
@@ -97,6 +97,13 @@  enum ath_cipher {
 	ATH_CIPHER_MIC = 127
 };
 
+struct ath_cycle_counters {
+	u32 cycles;
+	u32 rx_busy; /* register is called "rx clear" but it's the inverse */
+	u32 rx_frame;
+	u32 tx_frame;
+};
+
 /**
  * struct ath_ops - Register read/write operations
  *
@@ -148,6 +155,10 @@  struct ath_common {
 	DECLARE_BITMAP(tkip_keymap, ATH_KEYMAX);
 	enum ath_crypt_caps crypt_caps;
 
+	struct ath_cycle_counters cc_ani;
+	struct ath_cycle_counters cc_survey;
+	spinlock_t cc_lock;
+
 	struct ath_regulatory regulatory;
 	const struct ath_ops *ops;
 	const struct ath_bus_ops *bus_ops;
@@ -165,4 +176,16 @@  int ath_key_config(struct ath_common *common,
 			  struct ieee80211_key_conf *key);
 bool ath_hw_keyreset(struct ath_common *common, u16 entry);
 
+void ath_hw_cycle_counters_update(struct ath_common *common);
+
+static inline void ath_hw_cycle_counters_lock(struct ath_common *common)
+{
+	spin_lock_bh(&common->cc_lock);
+}
+
+static inline void ath_hw_cycle_counters_unlock(struct ath_common *common)
+{
+	spin_unlock_bh(&common->cc_lock);
+}
+
 #endif /* ATH_H */
diff --git a/drivers/net/wireless/ath/hw.c b/drivers/net/wireless/ath/hw.c
index a8f81ea..f26730f 100644
--- a/drivers/net/wireless/ath/hw.c
+++ b/drivers/net/wireless/ath/hw.c
@@ -124,3 +124,43 @@  void ath_hw_setbssidmask(struct ath_common *common)
 	REG_WRITE(ah, get_unaligned_le16(common->bssidmask + 4), AR_BSSMSKU);
 }
 EXPORT_SYMBOL(ath_hw_setbssidmask);
+
+/**
+ * ath_hw_cycle_counters_update - common function to update cycle counters
+ *
+ * @common: the ath_common struct for the device.
+ *
+ * This function is used to update all cycle counters in one place.
+ * It has to be called while holding common->cc_lock!
+ */
+void ath_hw_cycle_counters_update(struct ath_common *common)
+{
+	u32 cycles, busy, rx, tx;
+
+	/* freeze */
+	REG_WRITE(common, AR_MIBC_FMC, AR_MIBC);
+	/* read */
+	cycles = REG_READ(common, AR_CCCNT);
+	busy = REG_READ(common, AR_RCCNT);
+	rx = REG_READ(common, AR_RFCNT);
+	tx = REG_READ(common, AR_TFCNT);
+	/* clear */
+	REG_WRITE(common, 0, AR_CCCNT);
+	REG_WRITE(common, 0, AR_RFCNT);
+	REG_WRITE(common, 0, AR_RCCNT);
+	REG_WRITE(common, 0, AR_TFCNT);
+	/* unfreeze */
+	REG_WRITE(common, 0, AR_MIBC);
+
+	/* update all cycle counters here */
+	common->cc_ani.cycles += cycles;
+	common->cc_ani.rx_busy += busy;
+	common->cc_ani.rx_frame += rx;
+	common->cc_ani.tx_frame += tx;
+
+	common->cc_survey.cycles += cycles;
+	common->cc_survey.rx_busy += busy;
+	common->cc_survey.rx_frame += rx;
+	common->cc_survey.tx_frame += tx;
+}
+EXPORT_SYMBOL(ath_hw_cycle_counters_update);
diff --git a/drivers/net/wireless/ath/reg.h b/drivers/net/wireless/ath/reg.h
index e798ef4..298e53f 100644
--- a/drivers/net/wireless/ath/reg.h
+++ b/drivers/net/wireless/ath/reg.h
@@ -17,6 +17,12 @@ 
 #ifndef ATH_REGISTERS_H
 #define ATH_REGISTERS_H
 
+#define AR_MIBC			0x0040
+#define AR_MIBC_COW		0x00000001
+#define AR_MIBC_FMC		0x00000002
+#define AR_MIBC_CMC		0x00000004
+#define AR_MIBC_MCS		0x00000008
+
 /*
  * BSSID mask registers. See ath_hw_set_bssid_mask()
  * for detailed documentation about these registers.
@@ -24,6 +30,11 @@ 
 #define AR_BSSMSKL		0x80e0
 #define AR_BSSMSKU		0x80e4
 
+#define AR_TFCNT		0x80ec
+#define AR_RFCNT		0x80f0
+#define AR_RCCNT		0x80f4
+#define AR_CCCNT		0x80f8
+
 #define AR_KEYTABLE_0           0x8800
 #define AR_KEYTABLE(_n)         (AR_KEYTABLE_0 + ((_n)*32))
 #define AR_KEY_CACHE_SIZE       128