Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Sujith Manoharan and committed by
John W. Linville
09a525d3 fcdc403c

+34
+2
drivers/net/wireless/ath/ath.h
··· 108 108 * struct ath_ops - Register read/write operations 109 109 * 110 110 * @read: Register read 111 + * @multi_read: Multiple register read 111 112 * @write: Register write 112 113 * @enable_write_buffer: Enable multiple register writes 113 114 * @write_flush: flush buffered register writes and disable buffering 114 115 */ 115 116 struct ath_ops { 116 117 unsigned int (*read)(void *, u32 reg_offset); 118 + void (*multi_read)(void *, u32 *addr, u32 *val, u16 count); 117 119 void (*write)(void *, u32 val, u32 reg_offset); 118 120 void (*enable_write_buffer)(void *); 119 121 void (*write_flush) (void *);
+29
drivers/net/wireless/ath/ath9k/htc_drv_init.c
··· 297 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 328 static void ath9k_regwrite_single(void *hw_priv, u32 val, u32 reg_offset) 301 329 { 302 330 struct ath_hw *ah = (struct ath_hw *) hw_priv; ··· 435 407 436 408 static const struct ath_ops ath9k_common_ops = { 437 409 .read = ath9k_regread, 410 + .multi_read = ath9k_multi_regread, 438 411 .write = ath9k_regwrite, 439 412 .enable_write_buffer = ath9k_enable_regwrite_buffer, 440 413 .write_flush = ath9k_regwrite_flush,
+3
drivers/net/wireless/ath/ath9k/hw.h
··· 70 70 #define REG_READ(_ah, _reg) \ 71 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 76 #define ENABLE_REGWRITE_BUFFER(_ah) \ 74 77 do { \ 75 78 if (ath9k_hw_common(_ah)->ops->enable_write_buffer) \