diff options
author | Sujith Manoharan <Sujith.Manoharan@atheros.com> | 2011-01-04 02:47:18 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-01-19 11:36:06 -0500 |
commit | 09a525d33870e8a16076ec0200cc5002f6bef35d (patch) | |
tree | 75f3ae04c9175d569c7ef2add7bfe1eb913b3f09 | |
parent | fcdc403c31ed5bb5f3baf42f4e2b5e7198fef0c0 (diff) |
ath9k_htc: Add multiple register read API
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>
-rw-r--r-- | drivers/net/wireless/ath/ath.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/htc_drv_init.c | 29 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/hw.h | 3 |
3 files changed, 34 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index e43210c8585c..a6c6a466000f 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h | |||
@@ -108,12 +108,14 @@ enum ath_cipher { | |||
108 | * struct ath_ops - Register read/write operations | 108 | * struct ath_ops - Register read/write operations |
109 | * | 109 | * |
110 | * @read: Register read | 110 | * @read: Register read |
111 | * @multi_read: Multiple register read | ||
111 | * @write: Register write | 112 | * @write: Register write |
112 | * @enable_write_buffer: Enable multiple register writes | 113 | * @enable_write_buffer: Enable multiple register writes |
113 | * @write_flush: flush buffered register writes and disable buffering | 114 | * @write_flush: flush buffered register writes and disable buffering |
114 | */ | 115 | */ |
115 | struct ath_ops { | 116 | struct ath_ops { |
116 | unsigned int (*read)(void *, u32 reg_offset); | 117 | unsigned int (*read)(void *, u32 reg_offset); |
118 | void (*multi_read)(void *, u32 *addr, u32 *val, u16 count); | ||
117 | void (*write)(void *, u32 val, u32 reg_offset); | 119 | void (*write)(void *, u32 val, u32 reg_offset); |
118 | void (*enable_write_buffer)(void *); | 120 | void (*enable_write_buffer)(void *); |
119 | void (*write_flush) (void *); | 121 | void (*write_flush) (void *); |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 38433f9bfe59..8e04586c5256 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c | |||
@@ -297,6 +297,34 @@ static unsigned int ath9k_regread(void *hw_priv, u32 reg_offset) | |||
297 | return be32_to_cpu(val); | 297 | return be32_to_cpu(val); |
298 | } | 298 | } |
299 | 299 | ||
300 | static void ath9k_multi_regread(void *hw_priv, u32 *addr, | ||
301 | u32 *val, u16 count) | ||
302 | { | ||
303 | struct ath_hw *ah = (struct ath_hw *) hw_priv; | ||
304 | struct ath_common *common = ath9k_hw_common(ah); | ||
305 | struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv; | ||
306 | __be32 tmpaddr[8]; | ||
307 | __be32 tmpval[8]; | ||
308 | int i, ret; | ||
309 | |||
310 | for (i = 0; i < count; i++) { | ||
311 | tmpaddr[i] = cpu_to_be32(addr[i]); | ||
312 | } | ||
313 | |||
314 | ret = ath9k_wmi_cmd(priv->wmi, WMI_REG_READ_CMDID, | ||
315 | (u8 *)tmpaddr , sizeof(u32) * count, | ||
316 | (u8 *)tmpval, sizeof(u32) * count, | ||
317 | 100); | ||
318 | if (unlikely(ret)) { | ||
319 | ath_dbg(common, ATH_DBG_WMI, | ||
320 | "Multiple REGISTER READ FAILED (count: %d)\n", count); | ||
321 | } | ||
322 | |||
323 | for (i = 0; i < count; i++) { | ||
324 | val[i] = be32_to_cpu(tmpval[i]); | ||
325 | } | ||
326 | } | ||
327 | |||
300 | static void ath9k_regwrite_single(void *hw_priv, u32 val, u32 reg_offset) | 328 | static void ath9k_regwrite_single(void *hw_priv, u32 val, u32 reg_offset) |
301 | { | 329 | { |
302 | struct ath_hw *ah = (struct ath_hw *) hw_priv; | 330 | struct ath_hw *ah = (struct ath_hw *) hw_priv; |
@@ -407,6 +435,7 @@ static void ath9k_regwrite_flush(void *hw_priv) | |||
407 | 435 | ||
408 | static const struct ath_ops ath9k_common_ops = { | 436 | static const struct ath_ops ath9k_common_ops = { |
409 | .read = ath9k_regread, | 437 | .read = ath9k_regread, |
438 | .multi_read = ath9k_multi_regread, | ||
410 | .write = ath9k_regwrite, | 439 | .write = ath9k_regwrite, |
411 | .enable_write_buffer = ath9k_enable_regwrite_buffer, | 440 | .enable_write_buffer = ath9k_enable_regwrite_buffer, |
412 | .write_flush = ath9k_regwrite_flush, | 441 | .write_flush = ath9k_regwrite_flush, |
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 5a3dfec45e96..c2b3515deea1 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
@@ -70,6 +70,9 @@ | |||
70 | #define REG_READ(_ah, _reg) \ | 70 | #define REG_READ(_ah, _reg) \ |
71 | ath9k_hw_common(_ah)->ops->read((_ah), (_reg)) | 71 | ath9k_hw_common(_ah)->ops->read((_ah), (_reg)) |
72 | 72 | ||
73 | #define REG_READ_MULTI(_ah, _addr, _val, _cnt) \ | ||
74 | ath9k_hw_common(_ah)->ops->multi_read((_ah), (_addr), (_val), (_cnt)) | ||
75 | |||
73 | #define ENABLE_REGWRITE_BUFFER(_ah) \ | 76 | #define ENABLE_REGWRITE_BUFFER(_ah) \ |
74 | do { \ | 77 | do { \ |
75 | if (ath9k_hw_common(_ah)->ops->enable_write_buffer) \ | 78 | if (ath9k_hw_common(_ah)->ops->enable_write_buffer) \ |