aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2011-03-23 15:57:25 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-03-30 14:15:19 -0400
commit845e03c93dda2c00ffb5c68a1f7c8efc412d7c1a (patch)
tree9c48d7b82ef167d9346ef1a3689f636a471c14f2 /drivers/net/wireless
parentf9f84e96f6d642aa7b337c22cbb7d6f936039fda (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')
-rw-r--r--drivers/net/wireless/ath/ath.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_init.c12
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h12
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c23
4 files changed, 42 insertions, 6 deletions
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h
index a6c6a466000f..6d7105b7e8f1 100644
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
@@ -119,6 +119,7 @@ struct ath_ops {
119 void (*write)(void *, u32 val, u32 reg_offset); 119 void (*write)(void *, u32 val, u32 reg_offset);
120 void (*enable_write_buffer)(void *); 120 void (*enable_write_buffer)(void *);
121 void (*write_flush) (void *); 121 void (*write_flush) (void *);
122 u32 (*rmw)(void *, u32 reg_offset, u32 set, u32 clr);
122}; 123};
123 124
124struct ath_common; 125struct ath_common;
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
433static 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
433static void ath_usb_read_cachesize(struct ath_common *common, int *csz) 444static 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
199static 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) {