ath9k_htc: Add multiple register read API
authorSujith Manoharan <Sujith.Manoharan@atheros.com>
Tue, 4 Jan 2011 07:47:18 +0000 (13:17 +0530)
committerJohn W. Linville <linville@tuxdriver.com>
Wed, 19 Jan 2011 16:36:06 +0000 (11:36 -0500)
This would decrease latency in reading bulk registers.

Signed-off-by: Sujith Manoharan <Sujith.Manoharan@atheros.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/ath/ath.h
drivers/net/wireless/ath/ath9k/htc_drv_init.c
drivers/net/wireless/ath/ath9k/hw.h

index e43210c8585c20e14e8ec91d1923e2081d0a9769..a6c6a466000f737ab8ca0c1f8737031faaba55ec 100644 (file)
@@ -108,12 +108,14 @@ enum ath_cipher {
  * struct ath_ops - Register read/write operations
  *
  * @read: Register read
+ * @multi_read: Multiple register read
  * @write: Register write
  * @enable_write_buffer: Enable multiple register writes
  * @write_flush: flush buffered register writes and disable buffering
  */
 struct ath_ops {
        unsigned int (*read)(void *, u32 reg_offset);
+       void (*multi_read)(void *, u32 *addr, u32 *val, u16 count);
        void (*write)(void *, u32 val, u32 reg_offset);
        void (*enable_write_buffer)(void *);
        void (*write_flush) (void *);
index 38433f9bfe596abcb84a08d672a6476b994748a3..8e04586c52565a1c03673b9eaf6104cdb3bc14c6 100644 (file)
@@ -297,6 +297,34 @@ static unsigned int ath9k_regread(void *hw_priv, u32 reg_offset)
        return be32_to_cpu(val);
 }
 
+static void ath9k_multi_regread(void *hw_priv, u32 *addr,
+                               u32 *val, u16 count)
+{
+       struct ath_hw *ah = (struct ath_hw *) hw_priv;
+       struct ath_common *common = ath9k_hw_common(ah);
+       struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
+       __be32 tmpaddr[8];
+       __be32 tmpval[8];
+       int i, ret;
+
+       for (i = 0; i < count; i++) {
+              tmpaddr[i] = cpu_to_be32(addr[i]);
+       }
+
+       ret = ath9k_wmi_cmd(priv->wmi, WMI_REG_READ_CMDID,
+                          (u8 *)tmpaddr , sizeof(u32) * count,
+                          (u8 *)tmpval, sizeof(u32) * count,
+                          100);
+       if (unlikely(ret)) {
+               ath_dbg(common, ATH_DBG_WMI,
+                       "Multiple REGISTER READ FAILED (count: %d)\n", count);
+       }
+
+       for (i = 0; i < count; i++) {
+              val[i] = be32_to_cpu(tmpval[i]);
+       }
+}
+
 static void ath9k_regwrite_single(void *hw_priv, u32 val, u32 reg_offset)
 {
        struct ath_hw *ah = (struct ath_hw *) hw_priv;
@@ -407,6 +435,7 @@ static void ath9k_regwrite_flush(void *hw_priv)
 
 static const struct ath_ops ath9k_common_ops = {
        .read = ath9k_regread,
+       .multi_read = ath9k_multi_regread,
        .write = ath9k_regwrite,
        .enable_write_buffer = ath9k_enable_regwrite_buffer,
        .write_flush = ath9k_regwrite_flush,
index 5a3dfec45e96004d02c84a33cbb39ff9aa201d45..c2b3515deea1ccac54539c944a3ef4bde21138ab 100644 (file)
@@ -70,6 +70,9 @@
 #define REG_READ(_ah, _reg) \
        ath9k_hw_common(_ah)->ops->read((_ah), (_reg))
 
+#define REG_READ_MULTI(_ah, _addr, _val, _cnt)         \
+       ath9k_hw_common(_ah)->ops->multi_read((_ah), (_addr), (_val), (_cnt))
+
 #define ENABLE_REGWRITE_BUFFER(_ah)                                    \
        do {                                                            \
                if (ath9k_hw_common(_ah)->ops->enable_write_buffer)     \