diff options
author | Felix Fietkau <nbd@openwrt.org> | 2011-03-23 15:57:25 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-03-30 14:15:19 -0400 |
commit | 845e03c93dda2c00ffb5c68a1f7c8efc412d7c1a (patch) | |
tree | 9c48d7b82ef167d9346ef1a3689f636a471c14f2 /drivers/net/wireless/ath/ath9k | |
parent | f9f84e96f6d642aa7b337c22cbb7d6f936039fda (diff) |
ath9k_hw: add a new register op for read-mask-write
Reduces the number of calls to register ops. On MIPS this reduces the
ath9k_hw binary size from 321k down to 310k
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath9k')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/htc_drv_init.c | 12 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/hw.h | 12 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/init.c | 23 |
3 files changed, 41 insertions, 6 deletions
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 4e26946f7ab2..ca69e7ccfd80 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c | |||
@@ -430,6 +430,17 @@ static void ath9k_regwrite_flush(void *hw_priv) | |||
430 | mutex_unlock(&priv->wmi->multi_write_mutex); | 430 | mutex_unlock(&priv->wmi->multi_write_mutex); |
431 | } | 431 | } |
432 | 432 | ||
433 | static u32 ath9k_reg_rmw(void *hw_priv, u32 reg_offset, u32 set, u32 clr) | ||
434 | { | ||
435 | u32 val; | ||
436 | |||
437 | val = ath9k_regread(hw_priv, reg_offset); | ||
438 | val &= ~clr; | ||
439 | val |= set; | ||
440 | ath9k_regwrite(hw_priv, val, reg_offset); | ||
441 | return val; | ||
442 | } | ||
443 | |||
433 | static void ath_usb_read_cachesize(struct ath_common *common, int *csz) | 444 | static void ath_usb_read_cachesize(struct ath_common *common, int *csz) |
434 | { | 445 | { |
435 | *csz = L1_CACHE_BYTES >> 2; | 446 | *csz = L1_CACHE_BYTES >> 2; |
@@ -655,6 +666,7 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, | |||
655 | ah->reg_ops.write = ath9k_regwrite; | 666 | ah->reg_ops.write = ath9k_regwrite; |
656 | ah->reg_ops.enable_write_buffer = ath9k_enable_regwrite_buffer; | 667 | ah->reg_ops.enable_write_buffer = ath9k_enable_regwrite_buffer; |
657 | ah->reg_ops.write_flush = ath9k_regwrite_flush; | 668 | ah->reg_ops.write_flush = ath9k_regwrite_flush; |
669 | ah->reg_ops.rmw = ath9k_reg_rmw; | ||
658 | priv->ah = ah; | 670 | priv->ah = ah; |
659 | 671 | ||
660 | common = ath9k_hw_common(ah); | 672 | common = ath9k_hw_common(ah); |
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index ef387a2f54b2..e256658c740a 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
@@ -73,6 +73,9 @@ | |||
73 | #define REG_READ_MULTI(_ah, _addr, _val, _cnt) \ | 73 | #define REG_READ_MULTI(_ah, _addr, _val, _cnt) \ |
74 | (_ah)->reg_ops.multi_read((_ah), (_addr), (_val), (_cnt)) | 74 | (_ah)->reg_ops.multi_read((_ah), (_addr), (_val), (_cnt)) |
75 | 75 | ||
76 | #define REG_RMW(_ah, _reg, _set, _clr) \ | ||
77 | (_ah)->reg_ops.rmw((_ah), (_reg), (_set), (_clr)) | ||
78 | |||
76 | #define ENABLE_REGWRITE_BUFFER(_ah) \ | 79 | #define ENABLE_REGWRITE_BUFFER(_ah) \ |
77 | do { \ | 80 | do { \ |
78 | if ((_ah)->reg_ops.enable_write_buffer) \ | 81 | if ((_ah)->reg_ops.enable_write_buffer) \ |
@@ -87,17 +90,14 @@ | |||
87 | 90 | ||
88 | #define SM(_v, _f) (((_v) << _f##_S) & _f) | 91 | #define SM(_v, _f) (((_v) << _f##_S) & _f) |
89 | #define MS(_v, _f) (((_v) & _f) >> _f##_S) | 92 | #define MS(_v, _f) (((_v) & _f) >> _f##_S) |
90 | #define REG_RMW(_a, _r, _set, _clr) \ | ||
91 | REG_WRITE(_a, _r, (REG_READ(_a, _r) & ~(_clr)) | (_set)) | ||
92 | #define REG_RMW_FIELD(_a, _r, _f, _v) \ | 93 | #define REG_RMW_FIELD(_a, _r, _f, _v) \ |
93 | REG_WRITE(_a, _r, \ | 94 | REG_RMW(_a, _r, (((_v) << _f##_S) & _f), (_f)) |
94 | (REG_READ(_a, _r) & ~_f) | (((_v) << _f##_S) & _f)) | ||
95 | #define REG_READ_FIELD(_a, _r, _f) \ | 95 | #define REG_READ_FIELD(_a, _r, _f) \ |
96 | (((REG_READ(_a, _r) & _f) >> _f##_S)) | 96 | (((REG_READ(_a, _r) & _f) >> _f##_S)) |
97 | #define REG_SET_BIT(_a, _r, _f) \ | 97 | #define REG_SET_BIT(_a, _r, _f) \ |
98 | REG_WRITE(_a, _r, REG_READ(_a, _r) | (_f)) | 98 | REG_RMW(_a, _r, (_f), 0) |
99 | #define REG_CLR_BIT(_a, _r, _f) \ | 99 | #define REG_CLR_BIT(_a, _r, _f) \ |
100 | REG_WRITE(_a, _r, REG_READ(_a, _r) & ~(_f)) | 100 | REG_RMW(_a, _r, 0, (_f)) |
101 | 101 | ||
102 | #define DO_DELAY(x) do { \ | 102 | #define DO_DELAY(x) do { \ |
103 | if (((++(x) % 64) == 0) && \ | 103 | if (((++(x) % 64) == 0) && \ |
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index da114c2f0dbe..db1b7553c684 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
@@ -196,6 +196,28 @@ static unsigned int ath9k_ioread32(void *hw_priv, u32 reg_offset) | |||
196 | return val; | 196 | return val; |
197 | } | 197 | } |
198 | 198 | ||
199 | static unsigned int ath9k_reg_rmw(void *hw_priv, u32 reg_offset, u32 set, u32 clr) | ||
200 | { | ||
201 | struct ath_hw *ah = (struct ath_hw *) hw_priv; | ||
202 | struct ath_common *common = ath9k_hw_common(ah); | ||
203 | struct ath_softc *sc = (struct ath_softc *) common->priv; | ||
204 | unsigned long uninitialized_var(flags); | ||
205 | u32 val; | ||
206 | |||
207 | if (ah->config.serialize_regmode == SER_REG_MODE_ON) | ||
208 | spin_lock_irqsave(&sc->sc_serial_rw, flags); | ||
209 | |||
210 | val = ioread32(sc->mem + reg_offset); | ||
211 | val &= ~clr; | ||
212 | val |= set; | ||
213 | iowrite32(val, sc->mem + reg_offset); | ||
214 | |||
215 | if (ah->config.serialize_regmode == SER_REG_MODE_ON) | ||
216 | spin_unlock_irqrestore(&sc->sc_serial_rw, flags); | ||
217 | |||
218 | return val; | ||
219 | } | ||
220 | |||
199 | /**************************/ | 221 | /**************************/ |
200 | /* Initialization */ | 222 | /* Initialization */ |
201 | /**************************/ | 223 | /**************************/ |
@@ -548,6 +570,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, | |||
548 | ah->hw_version.subsysid = subsysid; | 570 | ah->hw_version.subsysid = subsysid; |
549 | ah->reg_ops.read = ath9k_ioread32; | 571 | ah->reg_ops.read = ath9k_ioread32; |
550 | ah->reg_ops.write = ath9k_iowrite32; | 572 | ah->reg_ops.write = ath9k_iowrite32; |
573 | ah->reg_ops.rmw = ath9k_reg_rmw; | ||
551 | sc->sc_ah = ah; | 574 | sc->sc_ah = ah; |
552 | 575 | ||
553 | if (!pdata) { | 576 | if (!pdata) { |