All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/18] reduce some of ath9k_htc performance problems
@ 2015-03-20 12:38 ` Oleksij Rempel
  0 siblings, 0 replies; 50+ messages in thread
From: Oleksij Rempel @ 2015-03-20 12:38 UTC (permalink / raw)
  To: linux-wireless, ath9k-devel, kvalo, adrian; +Cc: Oleksij Rempel

This patchset adds new WMI_RMW handler to reduce some of usb related
performance problems.

Oleksij Rempel (18):
  ath9k_htc: add new WMI_REG_RMW_CMDID command
  ath9k: ar9271_hw_pa_cal - use defs instead of magin numbers
  ath9k: ar9271_hw_pa_cal: use proper makroses.
  ath9k: ar9271_hw_pa_cal: use RMW buffer
  ath9k: add multi_read to be compatible with ath9k_htc
  ath9k: add new function ath9k_hw_read_array
  ath9k: ar9271_hw_pa_cal: use REG_READ_ARRAY
  ath9k: use one shot read in ath9k_hw_update_mibstats
  ath9k: ath9k_hw_loadnf: use REG_RMW
  ath9k: write buffer related optimisation in ar5008_hw_set_channel_regs
  ath9k: ath9k_hw_set_4k_power_cal_tabl: use rmw buffer
  ath9k: use rmw buffer in ath9k_hw_set_operating_mode and
    ath9k_hw_reset
  ath9k: ath9k_hw_4k_set_board_values: use rmw buffer
  ath9k: ath9k_hw_analog_shift_rmw: use REG_RMW
  ath9k: ath9k_hw_4k_set_board_values: use rmw buffer
  ath9k: use REG_RMW and rmw buffer in ath9k_hw_4k_set_gain
  ath9k: use REG_RMW and rmw buffer in ath9k_hw_4k_set_board_values
  ath9k: use REG_RMW and rmw buffer in ath9k_hw_def_set_gain

 drivers/net/wireless/ath/ath.h                |   3 +
 drivers/net/wireless/ath/ath9k/ani.c          |  20 +++-
 drivers/net/wireless/ath/ath9k/ar5008_phy.c   |   5 +-
 drivers/net/wireless/ath/ath9k/ar9002_calib.c |  77 +++++++-------
 drivers/net/wireless/ath/ath9k/calib.c        |  19 ++--
 drivers/net/wireless/ath/ath9k/eeprom.c       |   7 +-
 drivers/net/wireless/ath/ath9k/eeprom_4k.c    |  38 ++++---
 drivers/net/wireless/ath/ath9k/eeprom_def.c   |  19 ++--
 drivers/net/wireless/ath/ath9k/htc.h          |   5 +
 drivers/net/wireless/ath/ath9k/htc_drv_init.c | 142 ++++++++++++++++++++++++--
 drivers/net/wireless/ath/ath9k/hw.c           |  24 +++++
 drivers/net/wireless/ath/ath9k/hw.h           |  15 +++
 drivers/net/wireless/ath/ath9k/init.c         |  11 ++
 drivers/net/wireless/ath/ath9k/wmi.c          |   3 +
 drivers/net/wireless/ath/ath9k/wmi.h          |  16 +++
 15 files changed, 313 insertions(+), 91 deletions(-)

-- 
1.9.1


^ permalink raw reply	[flat|nested] 50+ messages in thread

* [ath9k-devel] [PATCH 00/18] reduce some of ath9k_htc performance problems
@ 2015-03-20 12:38 ` Oleksij Rempel
  0 siblings, 0 replies; 50+ messages in thread
From: Oleksij Rempel @ 2015-03-20 12:38 UTC (permalink / raw)
  To: ath9k-devel

This patchset adds new WMI_RMW handler to reduce some of usb related
performance problems.

Oleksij Rempel (18):
  ath9k_htc: add new WMI_REG_RMW_CMDID command
  ath9k: ar9271_hw_pa_cal - use defs instead of magin numbers
  ath9k: ar9271_hw_pa_cal: use proper makroses.
  ath9k: ar9271_hw_pa_cal: use RMW buffer
  ath9k: add multi_read to be compatible with ath9k_htc
  ath9k: add new function ath9k_hw_read_array
  ath9k: ar9271_hw_pa_cal: use REG_READ_ARRAY
  ath9k: use one shot read in ath9k_hw_update_mibstats
  ath9k: ath9k_hw_loadnf: use REG_RMW
  ath9k: write buffer related optimisation in ar5008_hw_set_channel_regs
  ath9k: ath9k_hw_set_4k_power_cal_tabl: use rmw buffer
  ath9k: use rmw buffer in ath9k_hw_set_operating_mode and
    ath9k_hw_reset
  ath9k: ath9k_hw_4k_set_board_values: use rmw buffer
  ath9k: ath9k_hw_analog_shift_rmw: use REG_RMW
  ath9k: ath9k_hw_4k_set_board_values: use rmw buffer
  ath9k: use REG_RMW and rmw buffer in ath9k_hw_4k_set_gain
  ath9k: use REG_RMW and rmw buffer in ath9k_hw_4k_set_board_values
  ath9k: use REG_RMW and rmw buffer in ath9k_hw_def_set_gain

 drivers/net/wireless/ath/ath.h                |   3 +
 drivers/net/wireless/ath/ath9k/ani.c          |  20 +++-
 drivers/net/wireless/ath/ath9k/ar5008_phy.c   |   5 +-
 drivers/net/wireless/ath/ath9k/ar9002_calib.c |  77 +++++++-------
 drivers/net/wireless/ath/ath9k/calib.c        |  19 ++--
 drivers/net/wireless/ath/ath9k/eeprom.c       |   7 +-
 drivers/net/wireless/ath/ath9k/eeprom_4k.c    |  38 ++++---
 drivers/net/wireless/ath/ath9k/eeprom_def.c   |  19 ++--
 drivers/net/wireless/ath/ath9k/htc.h          |   5 +
 drivers/net/wireless/ath/ath9k/htc_drv_init.c | 142 ++++++++++++++++++++++++--
 drivers/net/wireless/ath/ath9k/hw.c           |  24 +++++
 drivers/net/wireless/ath/ath9k/hw.h           |  15 +++
 drivers/net/wireless/ath/ath9k/init.c         |  11 ++
 drivers/net/wireless/ath/ath9k/wmi.c          |   3 +
 drivers/net/wireless/ath/ath9k/wmi.h          |  16 +++
 15 files changed, 313 insertions(+), 91 deletions(-)

-- 
1.9.1

^ permalink raw reply	[flat|nested] 50+ messages in thread

* [PATCH 01/18] ath9k_htc: add new WMI_REG_RMW_CMDID command
  2015-03-20 12:38 ` [ath9k-devel] " Oleksij Rempel
@ 2015-03-20 12:38   ` Oleksij Rempel
  -1 siblings, 0 replies; 50+ messages in thread
From: Oleksij Rempel @ 2015-03-20 12:38 UTC (permalink / raw)
  To: linux-wireless, ath9k-devel, kvalo, adrian; +Cc: Oleksij Rempel

Since usb bus add extra delay on each request, a command
with read + write requests is too expensive. We can dramtically
reduce usb load by moving this command to firmware.

In my tests, this patch will reduce channel scan time
for about 5-10 seconds.

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 drivers/net/wireless/ath/ath.h                |   3 +
 drivers/net/wireless/ath/ath9k/htc.h          |   5 +
 drivers/net/wireless/ath/ath9k/htc_drv_init.c | 142 ++++++++++++++++++++++++--
 drivers/net/wireless/ath/ath9k/hw.h           |  12 +++
 drivers/net/wireless/ath/ath9k/wmi.c          |   3 +
 drivers/net/wireless/ath/ath9k/wmi.h          |  16 +++
 6 files changed, 175 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h
index 1eebe2e..7e94810 100644
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
@@ -131,6 +131,9 @@ struct ath_ops {
 	void (*enable_write_buffer)(void *);
 	void (*write_flush) (void *);
 	u32 (*rmw)(void *, u32 reg_offset, u32 set, u32 clr);
+	void (*enable_rmw_buffer)(void *);
+	void (*rmw_flush) (void *);
+
 };
 
 struct ath_common;
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
index 300d367..e82a0d4 100644
--- a/drivers/net/wireless/ath/ath9k/htc.h
+++ b/drivers/net/wireless/ath/ath9k/htc.h
@@ -444,6 +444,10 @@ static inline void ath9k_htc_stop_btcoex(struct ath9k_htc_priv *priv)
 #define OP_BT_SCAN                 BIT(4)
 #define OP_TSF_RESET               BIT(6)
 
+enum htc_op_flags {
+	HTC_FWFLAG_NO_RMW,
+};
+
 struct ath9k_htc_priv {
 	struct device *dev;
 	struct ieee80211_hw *hw;
@@ -482,6 +486,7 @@ struct ath9k_htc_priv {
 	bool reconfig_beacon;
 	unsigned int rxfilter;
 	unsigned long op_flags;
+	unsigned long fw_flags;
 
 	struct ath9k_hw_cal_data caldata;
 	struct ath_spec_scan_priv spec_priv;
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
index fd22940..d7beefe 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -376,17 +376,139 @@ static void ath9k_regwrite_flush(void *hw_priv)
 	mutex_unlock(&priv->wmi->multi_write_mutex);
 }
 
-static u32 ath9k_reg_rmw(void *hw_priv, u32 reg_offset, u32 set, u32 clr)
+static void ath9k_reg_rmw_buffer(void *hw_priv,
+				 u32 reg_offset, u32 set, u32 clr)
+{
+	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;
+	u32 rsp_status;
+	int r;
+
+	mutex_lock(&priv->wmi->multi_rmw_mutex);
+
+	/* Store the register/value */
+	priv->wmi->multi_rmw[priv->wmi->multi_rmw_idx].reg =
+		cpu_to_be32(reg_offset);
+	priv->wmi->multi_rmw[priv->wmi->multi_rmw_idx].set =
+		cpu_to_be32(set);
+	priv->wmi->multi_rmw[priv->wmi->multi_rmw_idx].clr =
+		cpu_to_be32(clr);
+
+	priv->wmi->multi_rmw_idx++;
+
+	/* If the buffer is full, send it out. */
+	if (priv->wmi->multi_rmw_idx == MAX_RMW_CMD_NUMBER) {
+		r = ath9k_wmi_cmd(priv->wmi, WMI_REG_RMW_CMDID,
+			  (u8 *) &priv->wmi->multi_rmw,
+			  sizeof(struct register_write) * priv->wmi->multi_rmw_idx,
+			  (u8 *) &rsp_status, sizeof(rsp_status),
+			  100);
+		if (unlikely(r)) {
+			ath_dbg(common, WMI,
+				"REGISTER RMW FAILED, multi len: %d\n",
+				priv->wmi->multi_rmw_idx);
+		}
+		priv->wmi->multi_rmw_idx = 0;
+	}
+
+	mutex_unlock(&priv->wmi->multi_rmw_mutex);
+}
+
+static void ath9k_reg_rmw_flush(void *hw_priv)
 {
-	u32 val;
+	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;
+	u32 rsp_status;
+	int r;
+
+	if (test_bit(HTC_FWFLAG_NO_RMW, &priv->fw_flags))
+		return;
+
+	atomic_dec(&priv->wmi->m_rmw_cnt);
 
-	val = ath9k_regread(hw_priv, reg_offset);
-	val &= ~clr;
-	val |= set;
-	ath9k_regwrite(hw_priv, val, reg_offset);
+	mutex_lock(&priv->wmi->multi_rmw_mutex);
+
+	if (priv->wmi->multi_rmw_idx) {
+		r = ath9k_wmi_cmd(priv->wmi, WMI_REG_RMW_CMDID,
+			  (u8 *) &priv->wmi->multi_rmw,
+			  sizeof(struct register_rmw) * priv->wmi->multi_rmw_idx,
+			  (u8 *) &rsp_status, sizeof(rsp_status),
+			  100);
+		if (unlikely(r)) {
+			ath_dbg(common, WMI,
+				"REGISTER RMW FAILED, multi len: %d\n",
+				priv->wmi->multi_rmw_idx);
+		}
+		priv->wmi->multi_rmw_idx = 0;
+	}
+
+	mutex_unlock(&priv->wmi->multi_rmw_mutex);
+}
+
+static void ath9k_enable_rmw_buffer(void *hw_priv)
+{
+	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;
+
+	if (test_bit(HTC_FWFLAG_NO_RMW, &priv->fw_flags))
+		return;
+
+	atomic_inc(&priv->wmi->m_rmw_cnt);
+}
+
+static u32 ath9k_reg_rmw_single(void *hw_priv,
+				 u32 reg_offset, u32 set, u32 clr)
+{
+	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;
+	struct register_rmw buf, buf_ret;
+	int ret;
+	u32 val = 0;
+
+	buf.reg = cpu_to_be32(reg_offset);
+	buf.set = cpu_to_be32(set);
+	buf.clr = cpu_to_be32(clr);
+
+	ret = ath9k_wmi_cmd(priv->wmi, WMI_REG_RMW_CMDID,
+			  (u8 *) &buf, sizeof(buf),
+			  (u8 *) &buf_ret, sizeof(buf_ret),
+			  100);
+	if (unlikely(ret)) {
+		ath_dbg(common, WMI, "REGISTER RMW FAILED:(0x%04x, %d)\n",
+			reg_offset, ret);
+	}
 	return val;
 }
 
+static u32 ath9k_reg_rmw(void *hw_priv, u32 reg_offset, u32 set, u32 clr)
+{
+	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;
+
+	if (test_bit(HTC_FWFLAG_NO_RMW, &priv->fw_flags)) {
+		u32 val;
+
+		val = REG_READ(ah, reg_offset);
+		val &= ~clr;
+		val |= set;
+		REG_WRITE(ah, reg_offset, val);
+
+		return 0;
+	}
+
+	if (atomic_read(&priv->wmi->m_rmw_cnt))
+		ath9k_reg_rmw_buffer(hw_priv, reg_offset, set, clr);
+	else
+		ath9k_reg_rmw_single(hw_priv, reg_offset, set, clr);
+
+	return 0;
+}
+
 static void ath_usb_read_cachesize(struct ath_common *common, int *csz)
 {
 	*csz = L1_CACHE_BYTES >> 2;
@@ -501,6 +623,8 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv,
 	ah->reg_ops.write = ath9k_regwrite;
 	ah->reg_ops.enable_write_buffer = ath9k_enable_regwrite_buffer;
 	ah->reg_ops.write_flush = ath9k_regwrite_flush;
+	ah->reg_ops.enable_rmw_buffer = ath9k_enable_rmw_buffer;
+	ah->reg_ops.rmw_flush = ath9k_reg_rmw_flush;
 	ah->reg_ops.rmw = ath9k_reg_rmw;
 	priv->ah = ah;
 
@@ -686,6 +810,12 @@ static int ath9k_init_firmware_version(struct ath9k_htc_priv *priv)
 		return -EINVAL;
 	}
 
+	if (priv->fw_version_major == 1 && priv->fw_version_minor < 4)
+		set_bit(HTC_FWFLAG_NO_RMW, &priv->fw_flags);
+
+	dev_info(priv->dev, "FW RMW support: %s\n",
+		test_bit(HTC_FWFLAG_NO_RMW, &priv->fw_flags) ? "Off" : "On");
+
 	return 0;
 }
 
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 29a25d9..f1864cc 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -100,6 +100,18 @@
 			(_ah)->reg_ops.write_flush((_ah));	\
 	} while (0)
 
+#define ENABLE_REG_RMW_BUFFER(_ah)					\
+	do {								\
+		if ((_ah)->reg_ops.enable_rmw_buffer)	\
+			(_ah)->reg_ops.enable_rmw_buffer((_ah)); \
+	} while (0)
+
+#define REG_RMW_BUFFER_FLUSH(_ah)					\
+	do {								\
+		if ((_ah)->reg_ops.rmw_flush)		\
+			(_ah)->reg_ops.rmw_flush((_ah));	\
+	} while (0)
+
 #define PR_EEP(_s, _val)						\
 	do {								\
 		len += scnprintf(buf + len, size - len, "%20s : %10d\n",\
diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c
index 65c8894..67a2f8c 100644
--- a/drivers/net/wireless/ath/ath9k/wmi.c
+++ b/drivers/net/wireless/ath/ath9k/wmi.c
@@ -61,6 +61,8 @@ static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd)
 		return "WMI_REG_READ_CMDID";
 	case WMI_REG_WRITE_CMDID:
 		return "WMI_REG_WRITE_CMDID";
+	case WMI_REG_RMW_CMDID:
+		return "WMI_REG_RMW_CMDID";
 	case WMI_RC_STATE_CHANGE_CMDID:
 		return "WMI_RC_STATE_CHANGE_CMDID";
 	case WMI_RC_RATE_UPDATE_CMDID:
@@ -101,6 +103,7 @@ struct wmi *ath9k_init_wmi(struct ath9k_htc_priv *priv)
 	spin_lock_init(&wmi->event_lock);
 	mutex_init(&wmi->op_mutex);
 	mutex_init(&wmi->multi_write_mutex);
+	mutex_init(&wmi->multi_rmw_mutex);
 	init_completion(&wmi->cmd_wait);
 	INIT_LIST_HEAD(&wmi->pending_tx_events);
 	tasklet_init(&wmi->wmi_event_tasklet, ath9k_wmi_event_tasklet,
diff --git a/drivers/net/wireless/ath/ath9k/wmi.h b/drivers/net/wireless/ath/ath9k/wmi.h
index 0db37f2..aa84a33 100644
--- a/drivers/net/wireless/ath/ath9k/wmi.h
+++ b/drivers/net/wireless/ath/ath9k/wmi.h
@@ -112,6 +112,7 @@ enum wmi_cmd_id {
 	WMI_TX_STATS_CMDID,
 	WMI_RX_STATS_CMDID,
 	WMI_BITRATE_MASK_CMDID,
+	WMI_REG_RMW_CMDID,
 };
 
 enum wmi_event_id {
@@ -125,12 +126,19 @@ enum wmi_event_id {
 };
 
 #define MAX_CMD_NUMBER 62
+#define MAX_RMW_CMD_NUMBER 15
 
 struct register_write {
 	__be32 reg;
 	__be32 val;
 };
 
+struct register_rmw {
+	__be32 reg;
+	__be32 set;
+	__be32 clr;
+} __packed;
+
 struct ath9k_htc_tx_event {
 	int count;
 	struct __wmi_event_txstatus txs;
@@ -156,10 +164,18 @@ struct wmi {
 
 	spinlock_t wmi_lock;
 
+	/* multi write section */
 	atomic_t mwrite_cnt;
 	struct register_write multi_write[MAX_CMD_NUMBER];
 	u32 multi_write_idx;
 	struct mutex multi_write_mutex;
+
+	/* multi rmw section */
+	atomic_t m_rmw_cnt;
+	struct register_rmw multi_rmw[MAX_RMW_CMD_NUMBER];
+	u32 multi_rmw_idx;
+	struct mutex multi_rmw_mutex;
+
 };
 
 struct wmi *ath9k_init_wmi(struct ath9k_htc_priv *priv);
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [ath9k-devel] [PATCH 01/18] ath9k_htc: add new WMI_REG_RMW_CMDID command
@ 2015-03-20 12:38   ` Oleksij Rempel
  0 siblings, 0 replies; 50+ messages in thread
From: Oleksij Rempel @ 2015-03-20 12:38 UTC (permalink / raw)
  To: ath9k-devel

Since usb bus add extra delay on each request, a command
with read + write requests is too expensive. We can dramtically
reduce usb load by moving this command to firmware.

In my tests, this patch will reduce channel scan time
for about 5-10 seconds.

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 drivers/net/wireless/ath/ath.h                |   3 +
 drivers/net/wireless/ath/ath9k/htc.h          |   5 +
 drivers/net/wireless/ath/ath9k/htc_drv_init.c | 142 ++++++++++++++++++++++++--
 drivers/net/wireless/ath/ath9k/hw.h           |  12 +++
 drivers/net/wireless/ath/ath9k/wmi.c          |   3 +
 drivers/net/wireless/ath/ath9k/wmi.h          |  16 +++
 6 files changed, 175 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h
index 1eebe2e..7e94810 100644
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
@@ -131,6 +131,9 @@ struct ath_ops {
 	void (*enable_write_buffer)(void *);
 	void (*write_flush) (void *);
 	u32 (*rmw)(void *, u32 reg_offset, u32 set, u32 clr);
+	void (*enable_rmw_buffer)(void *);
+	void (*rmw_flush) (void *);
+
 };
 
 struct ath_common;
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
index 300d367..e82a0d4 100644
--- a/drivers/net/wireless/ath/ath9k/htc.h
+++ b/drivers/net/wireless/ath/ath9k/htc.h
@@ -444,6 +444,10 @@ static inline void ath9k_htc_stop_btcoex(struct ath9k_htc_priv *priv)
 #define OP_BT_SCAN                 BIT(4)
 #define OP_TSF_RESET               BIT(6)
 
+enum htc_op_flags {
+	HTC_FWFLAG_NO_RMW,
+};
+
 struct ath9k_htc_priv {
 	struct device *dev;
 	struct ieee80211_hw *hw;
@@ -482,6 +486,7 @@ struct ath9k_htc_priv {
 	bool reconfig_beacon;
 	unsigned int rxfilter;
 	unsigned long op_flags;
+	unsigned long fw_flags;
 
 	struct ath9k_hw_cal_data caldata;
 	struct ath_spec_scan_priv spec_priv;
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
index fd22940..d7beefe 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -376,17 +376,139 @@ static void ath9k_regwrite_flush(void *hw_priv)
 	mutex_unlock(&priv->wmi->multi_write_mutex);
 }
 
-static u32 ath9k_reg_rmw(void *hw_priv, u32 reg_offset, u32 set, u32 clr)
+static void ath9k_reg_rmw_buffer(void *hw_priv,
+				 u32 reg_offset, u32 set, u32 clr)
+{
+	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;
+	u32 rsp_status;
+	int r;
+
+	mutex_lock(&priv->wmi->multi_rmw_mutex);
+
+	/* Store the register/value */
+	priv->wmi->multi_rmw[priv->wmi->multi_rmw_idx].reg =
+		cpu_to_be32(reg_offset);
+	priv->wmi->multi_rmw[priv->wmi->multi_rmw_idx].set =
+		cpu_to_be32(set);
+	priv->wmi->multi_rmw[priv->wmi->multi_rmw_idx].clr =
+		cpu_to_be32(clr);
+
+	priv->wmi->multi_rmw_idx++;
+
+	/* If the buffer is full, send it out. */
+	if (priv->wmi->multi_rmw_idx == MAX_RMW_CMD_NUMBER) {
+		r = ath9k_wmi_cmd(priv->wmi, WMI_REG_RMW_CMDID,
+			  (u8 *) &priv->wmi->multi_rmw,
+			  sizeof(struct register_write) * priv->wmi->multi_rmw_idx,
+			  (u8 *) &rsp_status, sizeof(rsp_status),
+			  100);
+		if (unlikely(r)) {
+			ath_dbg(common, WMI,
+				"REGISTER RMW FAILED, multi len: %d\n",
+				priv->wmi->multi_rmw_idx);
+		}
+		priv->wmi->multi_rmw_idx = 0;
+	}
+
+	mutex_unlock(&priv->wmi->multi_rmw_mutex);
+}
+
+static void ath9k_reg_rmw_flush(void *hw_priv)
 {
-	u32 val;
+	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;
+	u32 rsp_status;
+	int r;
+
+	if (test_bit(HTC_FWFLAG_NO_RMW, &priv->fw_flags))
+		return;
+
+	atomic_dec(&priv->wmi->m_rmw_cnt);
 
-	val = ath9k_regread(hw_priv, reg_offset);
-	val &= ~clr;
-	val |= set;
-	ath9k_regwrite(hw_priv, val, reg_offset);
+	mutex_lock(&priv->wmi->multi_rmw_mutex);
+
+	if (priv->wmi->multi_rmw_idx) {
+		r = ath9k_wmi_cmd(priv->wmi, WMI_REG_RMW_CMDID,
+			  (u8 *) &priv->wmi->multi_rmw,
+			  sizeof(struct register_rmw) * priv->wmi->multi_rmw_idx,
+			  (u8 *) &rsp_status, sizeof(rsp_status),
+			  100);
+		if (unlikely(r)) {
+			ath_dbg(common, WMI,
+				"REGISTER RMW FAILED, multi len: %d\n",
+				priv->wmi->multi_rmw_idx);
+		}
+		priv->wmi->multi_rmw_idx = 0;
+	}
+
+	mutex_unlock(&priv->wmi->multi_rmw_mutex);
+}
+
+static void ath9k_enable_rmw_buffer(void *hw_priv)
+{
+	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;
+
+	if (test_bit(HTC_FWFLAG_NO_RMW, &priv->fw_flags))
+		return;
+
+	atomic_inc(&priv->wmi->m_rmw_cnt);
+}
+
+static u32 ath9k_reg_rmw_single(void *hw_priv,
+				 u32 reg_offset, u32 set, u32 clr)
+{
+	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;
+	struct register_rmw buf, buf_ret;
+	int ret;
+	u32 val = 0;
+
+	buf.reg = cpu_to_be32(reg_offset);
+	buf.set = cpu_to_be32(set);
+	buf.clr = cpu_to_be32(clr);
+
+	ret = ath9k_wmi_cmd(priv->wmi, WMI_REG_RMW_CMDID,
+			  (u8 *) &buf, sizeof(buf),
+			  (u8 *) &buf_ret, sizeof(buf_ret),
+			  100);
+	if (unlikely(ret)) {
+		ath_dbg(common, WMI, "REGISTER RMW FAILED:(0x%04x, %d)\n",
+			reg_offset, ret);
+	}
 	return val;
 }
 
+static u32 ath9k_reg_rmw(void *hw_priv, u32 reg_offset, u32 set, u32 clr)
+{
+	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;
+
+	if (test_bit(HTC_FWFLAG_NO_RMW, &priv->fw_flags)) {
+		u32 val;
+
+		val = REG_READ(ah, reg_offset);
+		val &= ~clr;
+		val |= set;
+		REG_WRITE(ah, reg_offset, val);
+
+		return 0;
+	}
+
+	if (atomic_read(&priv->wmi->m_rmw_cnt))
+		ath9k_reg_rmw_buffer(hw_priv, reg_offset, set, clr);
+	else
+		ath9k_reg_rmw_single(hw_priv, reg_offset, set, clr);
+
+	return 0;
+}
+
 static void ath_usb_read_cachesize(struct ath_common *common, int *csz)
 {
 	*csz = L1_CACHE_BYTES >> 2;
@@ -501,6 +623,8 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv,
 	ah->reg_ops.write = ath9k_regwrite;
 	ah->reg_ops.enable_write_buffer = ath9k_enable_regwrite_buffer;
 	ah->reg_ops.write_flush = ath9k_regwrite_flush;
+	ah->reg_ops.enable_rmw_buffer = ath9k_enable_rmw_buffer;
+	ah->reg_ops.rmw_flush = ath9k_reg_rmw_flush;
 	ah->reg_ops.rmw = ath9k_reg_rmw;
 	priv->ah = ah;
 
@@ -686,6 +810,12 @@ static int ath9k_init_firmware_version(struct ath9k_htc_priv *priv)
 		return -EINVAL;
 	}
 
+	if (priv->fw_version_major == 1 && priv->fw_version_minor < 4)
+		set_bit(HTC_FWFLAG_NO_RMW, &priv->fw_flags);
+
+	dev_info(priv->dev, "FW RMW support: %s\n",
+		test_bit(HTC_FWFLAG_NO_RMW, &priv->fw_flags) ? "Off" : "On");
+
 	return 0;
 }
 
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 29a25d9..f1864cc 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -100,6 +100,18 @@
 			(_ah)->reg_ops.write_flush((_ah));	\
 	} while (0)
 
+#define ENABLE_REG_RMW_BUFFER(_ah)					\
+	do {								\
+		if ((_ah)->reg_ops.enable_rmw_buffer)	\
+			(_ah)->reg_ops.enable_rmw_buffer((_ah)); \
+	} while (0)
+
+#define REG_RMW_BUFFER_FLUSH(_ah)					\
+	do {								\
+		if ((_ah)->reg_ops.rmw_flush)		\
+			(_ah)->reg_ops.rmw_flush((_ah));	\
+	} while (0)
+
 #define PR_EEP(_s, _val)						\
 	do {								\
 		len += scnprintf(buf + len, size - len, "%20s : %10d\n",\
diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c
index 65c8894..67a2f8c 100644
--- a/drivers/net/wireless/ath/ath9k/wmi.c
+++ b/drivers/net/wireless/ath/ath9k/wmi.c
@@ -61,6 +61,8 @@ static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd)
 		return "WMI_REG_READ_CMDID";
 	case WMI_REG_WRITE_CMDID:
 		return "WMI_REG_WRITE_CMDID";
+	case WMI_REG_RMW_CMDID:
+		return "WMI_REG_RMW_CMDID";
 	case WMI_RC_STATE_CHANGE_CMDID:
 		return "WMI_RC_STATE_CHANGE_CMDID";
 	case WMI_RC_RATE_UPDATE_CMDID:
@@ -101,6 +103,7 @@ struct wmi *ath9k_init_wmi(struct ath9k_htc_priv *priv)
 	spin_lock_init(&wmi->event_lock);
 	mutex_init(&wmi->op_mutex);
 	mutex_init(&wmi->multi_write_mutex);
+	mutex_init(&wmi->multi_rmw_mutex);
 	init_completion(&wmi->cmd_wait);
 	INIT_LIST_HEAD(&wmi->pending_tx_events);
 	tasklet_init(&wmi->wmi_event_tasklet, ath9k_wmi_event_tasklet,
diff --git a/drivers/net/wireless/ath/ath9k/wmi.h b/drivers/net/wireless/ath/ath9k/wmi.h
index 0db37f2..aa84a33 100644
--- a/drivers/net/wireless/ath/ath9k/wmi.h
+++ b/drivers/net/wireless/ath/ath9k/wmi.h
@@ -112,6 +112,7 @@ enum wmi_cmd_id {
 	WMI_TX_STATS_CMDID,
 	WMI_RX_STATS_CMDID,
 	WMI_BITRATE_MASK_CMDID,
+	WMI_REG_RMW_CMDID,
 };
 
 enum wmi_event_id {
@@ -125,12 +126,19 @@ enum wmi_event_id {
 };
 
 #define MAX_CMD_NUMBER 62
+#define MAX_RMW_CMD_NUMBER 15
 
 struct register_write {
 	__be32 reg;
 	__be32 val;
 };
 
+struct register_rmw {
+	__be32 reg;
+	__be32 set;
+	__be32 clr;
+} __packed;
+
 struct ath9k_htc_tx_event {
 	int count;
 	struct __wmi_event_txstatus txs;
@@ -156,10 +164,18 @@ struct wmi {
 
 	spinlock_t wmi_lock;
 
+	/* multi write section */
 	atomic_t mwrite_cnt;
 	struct register_write multi_write[MAX_CMD_NUMBER];
 	u32 multi_write_idx;
 	struct mutex multi_write_mutex;
+
+	/* multi rmw section */
+	atomic_t m_rmw_cnt;
+	struct register_rmw multi_rmw[MAX_RMW_CMD_NUMBER];
+	u32 multi_rmw_idx;
+	struct mutex multi_rmw_mutex;
+
 };
 
 struct wmi *ath9k_init_wmi(struct ath9k_htc_priv *priv);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 02/18] ath9k: ar9271_hw_pa_cal - use defs instead of magin numbers
  2015-03-20 12:38 ` [ath9k-devel] " Oleksij Rempel
@ 2015-03-20 12:38   ` Oleksij Rempel
  -1 siblings, 0 replies; 50+ messages in thread
From: Oleksij Rempel @ 2015-03-20 12:38 UTC (permalink / raw)
  To: linux-wireless, ath9k-devel, kvalo, adrian; +Cc: Oleksij Rempel

This function uses mixed styles for register names/numbers which
is make harder reading and optimisation.

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 drivers/net/wireless/ath/ath9k/ar9002_calib.c | 35 ++++++++++++++-------------
 1 file changed, 18 insertions(+), 17 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
index 42190b6..4576b99 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
@@ -430,22 +430,22 @@ static void ar9271_hw_pa_cal(struct ath_hw *ah, bool is_reset)
 	u32 regVal;
 	unsigned int i;
 	u32 regList[][2] = {
-		{ 0x786c, 0 },
-		{ 0x7854, 0 },
-		{ 0x7820, 0 },
-		{ 0x7824, 0 },
-		{ 0x7868, 0 },
-		{ 0x783c, 0 },
-		{ 0x7838, 0 } ,
-		{ 0x7828, 0 } ,
+		{ AR9285_AN_TOP3, 0 },
+		{ AR9285_AN_RXTXBB1, 0 },
+		{ AR9285_AN_RF2G1, 0 },
+		{ AR9285_AN_RF2G2, 0 },
+		{ AR9285_AN_TOP2, 0 },
+		{ AR9285_AN_RF2G8, 0 },
+		{ AR9285_AN_RF2G7, 0 } ,
+		{ AR9285_AN_RF2G3, 0 } ,
 	};
 
 	for (i = 0; i < ARRAY_SIZE(regList); i++)
 		regList[i][1] = REG_READ(ah, regList[i][0]);
 
-	regVal = REG_READ(ah, 0x7834);
+	regVal = REG_READ(ah, AR9285_AN_RF2G6);
 	regVal &= (~(0x1));
-	REG_WRITE(ah, 0x7834, regVal);
+	REG_WRITE(ah, AR9285_AN_RF2G6, regVal);
 	regVal = REG_READ(ah, 0x9808);
 	regVal |= (0x1 << 27);
 	REG_WRITE(ah, 0x9808, regVal);
@@ -477,7 +477,7 @@ static void ar9271_hw_pa_cal(struct ath_hw *ah, bool is_reset)
 	 * does not matter since we turn it off
 	 */
 	REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PADRVGN2TAB0, 0);
-
+	/* 7828, b0-11, ccom=fff */
 	REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9271_AN_RF2G3_CCOMP, 0xfff);
 
 	/* Set:
@@ -490,15 +490,16 @@ static void ar9271_hw_pa_cal(struct ath_hw *ah, bool is_reset)
 
 	/* find off_6_1; */
 	for (i = 6; i > 0; i--) {
-		regVal = REG_READ(ah, 0x7834);
+		regVal = REG_READ(ah, AR9285_AN_RF2G6);
 		regVal |= (1 << (20 + i));
-		REG_WRITE(ah, 0x7834, regVal);
+		REG_WRITE(ah, AR9285_AN_RF2G6, regVal);
 		udelay(1);
 		/* regVal = REG_READ(ah, 0x7834); */
 		regVal &= (~(0x1 << (20 + i)));
-		regVal |= (MS(REG_READ(ah, 0x7840), AR9285_AN_RXTXBB1_SPARE9)
+		regVal |= (MS(REG_READ(ah, AR9285_AN_RF2G9),
+			      AR9285_AN_RXTXBB1_SPARE9)
 			    << (20 + i));
-		REG_WRITE(ah, 0x7834, regVal);
+		REG_WRITE(ah, AR9285_AN_RF2G6, regVal);
 	}
 
 	regVal = (regVal >> 20) & 0x7f;
@@ -517,9 +518,9 @@ static void ar9271_hw_pa_cal(struct ath_hw *ah, bool is_reset)
 
 	ENABLE_REGWRITE_BUFFER(ah);
 
-	regVal = REG_READ(ah, 0x7834);
+	regVal = REG_READ(ah, AR_AN_RF2G1_CH1);
 	regVal |= 0x1;
-	REG_WRITE(ah, 0x7834, regVal);
+	REG_WRITE(ah, AR_AN_RF2G1_CH1, regVal);
 	regVal = REG_READ(ah, 0x9808);
 	regVal &= (~(0x1 << 27));
 	REG_WRITE(ah, 0x9808, regVal);
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [ath9k-devel] [PATCH 02/18] ath9k: ar9271_hw_pa_cal - use defs instead of magin numbers
@ 2015-03-20 12:38   ` Oleksij Rempel
  0 siblings, 0 replies; 50+ messages in thread
From: Oleksij Rempel @ 2015-03-20 12:38 UTC (permalink / raw)
  To: ath9k-devel

This function uses mixed styles for register names/numbers which
is make harder reading and optimisation.

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 drivers/net/wireless/ath/ath9k/ar9002_calib.c | 35 ++++++++++++++-------------
 1 file changed, 18 insertions(+), 17 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
index 42190b6..4576b99 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
@@ -430,22 +430,22 @@ static void ar9271_hw_pa_cal(struct ath_hw *ah, bool is_reset)
 	u32 regVal;
 	unsigned int i;
 	u32 regList[][2] = {
-		{ 0x786c, 0 },
-		{ 0x7854, 0 },
-		{ 0x7820, 0 },
-		{ 0x7824, 0 },
-		{ 0x7868, 0 },
-		{ 0x783c, 0 },
-		{ 0x7838, 0 } ,
-		{ 0x7828, 0 } ,
+		{ AR9285_AN_TOP3, 0 },
+		{ AR9285_AN_RXTXBB1, 0 },
+		{ AR9285_AN_RF2G1, 0 },
+		{ AR9285_AN_RF2G2, 0 },
+		{ AR9285_AN_TOP2, 0 },
+		{ AR9285_AN_RF2G8, 0 },
+		{ AR9285_AN_RF2G7, 0 } ,
+		{ AR9285_AN_RF2G3, 0 } ,
 	};
 
 	for (i = 0; i < ARRAY_SIZE(regList); i++)
 		regList[i][1] = REG_READ(ah, regList[i][0]);
 
-	regVal = REG_READ(ah, 0x7834);
+	regVal = REG_READ(ah, AR9285_AN_RF2G6);
 	regVal &= (~(0x1));
-	REG_WRITE(ah, 0x7834, regVal);
+	REG_WRITE(ah, AR9285_AN_RF2G6, regVal);
 	regVal = REG_READ(ah, 0x9808);
 	regVal |= (0x1 << 27);
 	REG_WRITE(ah, 0x9808, regVal);
@@ -477,7 +477,7 @@ static void ar9271_hw_pa_cal(struct ath_hw *ah, bool is_reset)
 	 * does not matter since we turn it off
 	 */
 	REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PADRVGN2TAB0, 0);
-
+	/* 7828, b0-11, ccom=fff */
 	REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9271_AN_RF2G3_CCOMP, 0xfff);
 
 	/* Set:
@@ -490,15 +490,16 @@ static void ar9271_hw_pa_cal(struct ath_hw *ah, bool is_reset)
 
 	/* find off_6_1; */
 	for (i = 6; i > 0; i--) {
-		regVal = REG_READ(ah, 0x7834);
+		regVal = REG_READ(ah, AR9285_AN_RF2G6);
 		regVal |= (1 << (20 + i));
-		REG_WRITE(ah, 0x7834, regVal);
+		REG_WRITE(ah, AR9285_AN_RF2G6, regVal);
 		udelay(1);
 		/* regVal = REG_READ(ah, 0x7834); */
 		regVal &= (~(0x1 << (20 + i)));
-		regVal |= (MS(REG_READ(ah, 0x7840), AR9285_AN_RXTXBB1_SPARE9)
+		regVal |= (MS(REG_READ(ah, AR9285_AN_RF2G9),
+			      AR9285_AN_RXTXBB1_SPARE9)
 			    << (20 + i));
-		REG_WRITE(ah, 0x7834, regVal);
+		REG_WRITE(ah, AR9285_AN_RF2G6, regVal);
 	}
 
 	regVal = (regVal >> 20) & 0x7f;
@@ -517,9 +518,9 @@ static void ar9271_hw_pa_cal(struct ath_hw *ah, bool is_reset)
 
 	ENABLE_REGWRITE_BUFFER(ah);
 
-	regVal = REG_READ(ah, 0x7834);
+	regVal = REG_READ(ah, AR_AN_RF2G1_CH1);
 	regVal |= 0x1;
-	REG_WRITE(ah, 0x7834, regVal);
+	REG_WRITE(ah, AR_AN_RF2G1_CH1, regVal);
 	regVal = REG_READ(ah, 0x9808);
 	regVal &= (~(0x1 << 27));
 	REG_WRITE(ah, 0x9808, regVal);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 03/18] ath9k: ar9271_hw_pa_cal: use proper makroses.
  2015-03-20 12:38 ` [ath9k-devel] " Oleksij Rempel
@ 2015-03-20 12:38   ` Oleksij Rempel
  -1 siblings, 0 replies; 50+ messages in thread
From: Oleksij Rempel @ 2015-03-20 12:38 UTC (permalink / raw)
  To: linux-wireless, ath9k-devel, kvalo, adrian; +Cc: Oleksij Rempel

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 drivers/net/wireless/ath/ath9k/ar9002_calib.c | 43 ++++++++++++---------------
 1 file changed, 19 insertions(+), 24 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
index 4576b99..8d24a73 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
@@ -443,33 +443,30 @@ static void ar9271_hw_pa_cal(struct ath_hw *ah, bool is_reset)
 	for (i = 0; i < ARRAY_SIZE(regList); i++)
 		regList[i][1] = REG_READ(ah, regList[i][0]);
 
-	regVal = REG_READ(ah, AR9285_AN_RF2G6);
-	regVal &= (~(0x1));
-	REG_WRITE(ah, AR9285_AN_RF2G6, regVal);
-	regVal = REG_READ(ah, 0x9808);
-	regVal |= (0x1 << 27);
-	REG_WRITE(ah, 0x9808, regVal);
-
+	/* 7834, b1=0 */
+	REG_CLR_BIT(ah, AR9285_AN_RF2G6, 1 << 0);
+	/* 9808, b27=1 */
+	REG_SET_BIT(ah, 0x9808, 1 << 27);
 	/* 786c,b23,1, pwddac=1 */
-	REG_RMW_FIELD(ah, AR9285_AN_TOP3, AR9285_AN_TOP3_PWDDAC, 1);
+	REG_SET_BIT(ah, AR9285_AN_TOP3, AR9285_AN_TOP3_PWDDAC);
 	/* 7854, b5,1, pdrxtxbb=1 */
-	REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDRXTXBB1, 1);
+	REG_SET_BIT(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDRXTXBB1);
 	/* 7854, b7,1, pdv2i=1 */
-	REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDV2I, 1);
+	REG_SET_BIT(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDV2I);
 	/* 7854, b8,1, pddacinterface=1 */
-	REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDDACIF, 1);
+	REG_SET_BIT(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDDACIF);
 	/* 7824,b12,0, offcal=0 */
-	REG_RMW_FIELD(ah, AR9285_AN_RF2G2, AR9285_AN_RF2G2_OFFCAL, 0);
+	REG_CLR_BIT(ah, AR9285_AN_RF2G2, AR9285_AN_RF2G2_OFFCAL);
 	/* 7838, b1,0, pwddb=0 */
-	REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PWDDB, 0);
+	REG_CLR_BIT(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PWDDB);
 	/* 7820,b11,0, enpacal=0 */
-	REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_ENPACAL, 0);
+	REG_CLR_BIT(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_ENPACAL);
 	/* 7820,b25,1, pdpadrv1=0 */
-	REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV1, 0);
+	REG_CLR_BIT(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV1);
 	/* 7820,b24,0, pdpadrv2=0 */
-	REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV2, 0);
+	REG_CLR_BIT(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV2);
 	/* 7820,b23,0, pdpaout=0 */
-	REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPAOUT, 0);
+	REG_CLR_BIT(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPAOUT);
 	/* 783c,b14-16,7, padrvgn2tab_0=7 */
 	REG_RMW_FIELD(ah, AR9285_AN_RF2G8, AR9285_AN_RF2G8_PADRVGN2TAB0, 7);
 	/*
@@ -516,15 +513,13 @@ static void ar9271_hw_pa_cal(struct ath_hw *ah, bool is_reset)
 		ah->pacal_info.prev_offset = regVal;
 	}
 
-	ENABLE_REGWRITE_BUFFER(ah);
 
-	regVal = REG_READ(ah, AR_AN_RF2G1_CH1);
-	regVal |= 0x1;
-	REG_WRITE(ah, AR_AN_RF2G1_CH1, regVal);
-	regVal = REG_READ(ah, 0x9808);
-	regVal &= (~(0x1 << 27));
-	REG_WRITE(ah, 0x9808, regVal);
+	/* 7834, b1=1 */
+	REG_SET_BIT(ah, AR9285_AN_RF2G6, 1 << 0);
+	/* 9808, b27=0 */
+	REG_CLR_BIT(ah, 0x9808, 1 << 27);
 
+	ENABLE_REGWRITE_BUFFER(ah);
 	for (i = 0; i < ARRAY_SIZE(regList); i++)
 		REG_WRITE(ah, regList[i][0], regList[i][1]);
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [ath9k-devel] [PATCH 03/18] ath9k: ar9271_hw_pa_cal: use proper makroses.
@ 2015-03-20 12:38   ` Oleksij Rempel
  0 siblings, 0 replies; 50+ messages in thread
From: Oleksij Rempel @ 2015-03-20 12:38 UTC (permalink / raw)
  To: ath9k-devel

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 drivers/net/wireless/ath/ath9k/ar9002_calib.c | 43 ++++++++++++---------------
 1 file changed, 19 insertions(+), 24 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
index 4576b99..8d24a73 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
@@ -443,33 +443,30 @@ static void ar9271_hw_pa_cal(struct ath_hw *ah, bool is_reset)
 	for (i = 0; i < ARRAY_SIZE(regList); i++)
 		regList[i][1] = REG_READ(ah, regList[i][0]);
 
-	regVal = REG_READ(ah, AR9285_AN_RF2G6);
-	regVal &= (~(0x1));
-	REG_WRITE(ah, AR9285_AN_RF2G6, regVal);
-	regVal = REG_READ(ah, 0x9808);
-	regVal |= (0x1 << 27);
-	REG_WRITE(ah, 0x9808, regVal);
-
+	/* 7834, b1=0 */
+	REG_CLR_BIT(ah, AR9285_AN_RF2G6, 1 << 0);
+	/* 9808, b27=1 */
+	REG_SET_BIT(ah, 0x9808, 1 << 27);
 	/* 786c,b23,1, pwddac=1 */
-	REG_RMW_FIELD(ah, AR9285_AN_TOP3, AR9285_AN_TOP3_PWDDAC, 1);
+	REG_SET_BIT(ah, AR9285_AN_TOP3, AR9285_AN_TOP3_PWDDAC);
 	/* 7854, b5,1, pdrxtxbb=1 */
-	REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDRXTXBB1, 1);
+	REG_SET_BIT(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDRXTXBB1);
 	/* 7854, b7,1, pdv2i=1 */
-	REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDV2I, 1);
+	REG_SET_BIT(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDV2I);
 	/* 7854, b8,1, pddacinterface=1 */
-	REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDDACIF, 1);
+	REG_SET_BIT(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDDACIF);
 	/* 7824,b12,0, offcal=0 */
-	REG_RMW_FIELD(ah, AR9285_AN_RF2G2, AR9285_AN_RF2G2_OFFCAL, 0);
+	REG_CLR_BIT(ah, AR9285_AN_RF2G2, AR9285_AN_RF2G2_OFFCAL);
 	/* 7838, b1,0, pwddb=0 */
-	REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PWDDB, 0);
+	REG_CLR_BIT(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PWDDB);
 	/* 7820,b11,0, enpacal=0 */
-	REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_ENPACAL, 0);
+	REG_CLR_BIT(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_ENPACAL);
 	/* 7820,b25,1, pdpadrv1=0 */
-	REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV1, 0);
+	REG_CLR_BIT(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV1);
 	/* 7820,b24,0, pdpadrv2=0 */
-	REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV2, 0);
+	REG_CLR_BIT(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV2);
 	/* 7820,b23,0, pdpaout=0 */
-	REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPAOUT, 0);
+	REG_CLR_BIT(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPAOUT);
 	/* 783c,b14-16,7, padrvgn2tab_0=7 */
 	REG_RMW_FIELD(ah, AR9285_AN_RF2G8, AR9285_AN_RF2G8_PADRVGN2TAB0, 7);
 	/*
@@ -516,15 +513,13 @@ static void ar9271_hw_pa_cal(struct ath_hw *ah, bool is_reset)
 		ah->pacal_info.prev_offset = regVal;
 	}
 
-	ENABLE_REGWRITE_BUFFER(ah);
 
-	regVal = REG_READ(ah, AR_AN_RF2G1_CH1);
-	regVal |= 0x1;
-	REG_WRITE(ah, AR_AN_RF2G1_CH1, regVal);
-	regVal = REG_READ(ah, 0x9808);
-	regVal &= (~(0x1 << 27));
-	REG_WRITE(ah, 0x9808, regVal);
+	/* 7834, b1=1 */
+	REG_SET_BIT(ah, AR9285_AN_RF2G6, 1 << 0);
+	/* 9808, b27=0 */
+	REG_CLR_BIT(ah, 0x9808, 1 << 27);
 
+	ENABLE_REGWRITE_BUFFER(ah);
 	for (i = 0; i < ARRAY_SIZE(regList); i++)
 		REG_WRITE(ah, regList[i][0], regList[i][1]);
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 04/18] ath9k: ar9271_hw_pa_cal: use RMW buffer
  2015-03-20 12:38 ` [ath9k-devel] " Oleksij Rempel
@ 2015-03-20 12:38   ` Oleksij Rempel
  -1 siblings, 0 replies; 50+ messages in thread
From: Oleksij Rempel @ 2015-03-20 12:38 UTC (permalink / raw)
  To: linux-wireless, ath9k-devel, kvalo, adrian; +Cc: Oleksij Rempel

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 drivers/net/wireless/ath/ath9k/ar9002_calib.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
index 8d24a73..62a2314 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
@@ -436,13 +436,14 @@ static void ar9271_hw_pa_cal(struct ath_hw *ah, bool is_reset)
 		{ AR9285_AN_RF2G2, 0 },
 		{ AR9285_AN_TOP2, 0 },
 		{ AR9285_AN_RF2G8, 0 },
-		{ AR9285_AN_RF2G7, 0 } ,
-		{ AR9285_AN_RF2G3, 0 } ,
+		{ AR9285_AN_RF2G7, 0 },
+		{ AR9285_AN_RF2G3, 0 },
 	};
 
 	for (i = 0; i < ARRAY_SIZE(regList); i++)
 		regList[i][1] = REG_READ(ah, regList[i][0]);
 
+	ENABLE_REG_RMW_BUFFER(ah);
 	/* 7834, b1=0 */
 	REG_CLR_BIT(ah, AR9285_AN_RF2G6, 1 << 0);
 	/* 9808, b27=1 */
@@ -476,6 +477,7 @@ static void ar9271_hw_pa_cal(struct ath_hw *ah, bool is_reset)
 	REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PADRVGN2TAB0, 0);
 	/* 7828, b0-11, ccom=fff */
 	REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9271_AN_RF2G3_CCOMP, 0xfff);
+	REG_RMW_BUFFER_FLUSH(ah);
 
 	/* Set:
 	 * localmode=1,bmode=1,bmoderxtx=1,synthon=1,
@@ -514,10 +516,12 @@ static void ar9271_hw_pa_cal(struct ath_hw *ah, bool is_reset)
 	}
 
 
+	ENABLE_REG_RMW_BUFFER(ah);
 	/* 7834, b1=1 */
 	REG_SET_BIT(ah, AR9285_AN_RF2G6, 1 << 0);
 	/* 9808, b27=0 */
 	REG_CLR_BIT(ah, 0x9808, 1 << 27);
+	REG_RMW_BUFFER_FLUSH(ah);
 
 	ENABLE_REGWRITE_BUFFER(ah);
 	for (i = 0; i < ARRAY_SIZE(regList); i++)
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [ath9k-devel] [PATCH 04/18] ath9k: ar9271_hw_pa_cal: use RMW buffer
@ 2015-03-20 12:38   ` Oleksij Rempel
  0 siblings, 0 replies; 50+ messages in thread
From: Oleksij Rempel @ 2015-03-20 12:38 UTC (permalink / raw)
  To: ath9k-devel

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 drivers/net/wireless/ath/ath9k/ar9002_calib.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
index 8d24a73..62a2314 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
@@ -436,13 +436,14 @@ static void ar9271_hw_pa_cal(struct ath_hw *ah, bool is_reset)
 		{ AR9285_AN_RF2G2, 0 },
 		{ AR9285_AN_TOP2, 0 },
 		{ AR9285_AN_RF2G8, 0 },
-		{ AR9285_AN_RF2G7, 0 } ,
-		{ AR9285_AN_RF2G3, 0 } ,
+		{ AR9285_AN_RF2G7, 0 },
+		{ AR9285_AN_RF2G3, 0 },
 	};
 
 	for (i = 0; i < ARRAY_SIZE(regList); i++)
 		regList[i][1] = REG_READ(ah, regList[i][0]);
 
+	ENABLE_REG_RMW_BUFFER(ah);
 	/* 7834, b1=0 */
 	REG_CLR_BIT(ah, AR9285_AN_RF2G6, 1 << 0);
 	/* 9808, b27=1 */
@@ -476,6 +477,7 @@ static void ar9271_hw_pa_cal(struct ath_hw *ah, bool is_reset)
 	REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PADRVGN2TAB0, 0);
 	/* 7828, b0-11, ccom=fff */
 	REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9271_AN_RF2G3_CCOMP, 0xfff);
+	REG_RMW_BUFFER_FLUSH(ah);
 
 	/* Set:
 	 * localmode=1,bmode=1,bmoderxtx=1,synthon=1,
@@ -514,10 +516,12 @@ static void ar9271_hw_pa_cal(struct ath_hw *ah, bool is_reset)
 	}
 
 
+	ENABLE_REG_RMW_BUFFER(ah);
 	/* 7834, b1=1 */
 	REG_SET_BIT(ah, AR9285_AN_RF2G6, 1 << 0);
 	/* 9808, b27=0 */
 	REG_CLR_BIT(ah, 0x9808, 1 << 27);
+	REG_RMW_BUFFER_FLUSH(ah);
 
 	ENABLE_REGWRITE_BUFFER(ah);
 	for (i = 0; i < ARRAY_SIZE(regList); i++)
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 05/18] ath9k: add multi_read to be compatible with ath9k_htc
  2015-03-20 12:38 ` [ath9k-devel] " Oleksij Rempel
@ 2015-03-20 12:38   ` Oleksij Rempel
  -1 siblings, 0 replies; 50+ messages in thread
From: Oleksij Rempel @ 2015-03-20 12:38 UTC (permalink / raw)
  To: linux-wireless, ath9k-devel, kvalo, adrian; +Cc: Oleksij Rempel

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 drivers/net/wireless/ath/ath9k/init.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 6c6e884..041decc 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -141,6 +141,16 @@ static unsigned int ath9k_ioread32(void *hw_priv, u32 reg_offset)
 	return val;
 }
 
+static void ath9k_multi_ioread32(void *hw_priv, u32 *addr,
+                                u32 *val, u16 count)
+{
+	int i;
+
+	for (i = 0; i < count; i++)
+		val[i] = ath9k_ioread32(hw_priv, addr[i]);
+}
+
+
 static unsigned int __ath9k_reg_rmw(struct ath_softc *sc, u32 reg_offset,
 				    u32 set, u32 clr)
 {
@@ -530,6 +540,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
 	ah->hw = sc->hw;
 	ah->hw_version.devid = devid;
 	ah->reg_ops.read = ath9k_ioread32;
+	ah->reg_ops.multi_read = ath9k_multi_ioread32;
 	ah->reg_ops.write = ath9k_iowrite32;
 	ah->reg_ops.rmw = ath9k_reg_rmw;
 	pCap = &ah->caps;
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [ath9k-devel] [PATCH 05/18] ath9k: add multi_read to be compatible with ath9k_htc
@ 2015-03-20 12:38   ` Oleksij Rempel
  0 siblings, 0 replies; 50+ messages in thread
From: Oleksij Rempel @ 2015-03-20 12:38 UTC (permalink / raw)
  To: ath9k-devel

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 drivers/net/wireless/ath/ath9k/init.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 6c6e884..041decc 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -141,6 +141,16 @@ static unsigned int ath9k_ioread32(void *hw_priv, u32 reg_offset)
 	return val;
 }
 
+static void ath9k_multi_ioread32(void *hw_priv, u32 *addr,
+                                u32 *val, u16 count)
+{
+	int i;
+
+	for (i = 0; i < count; i++)
+		val[i] = ath9k_ioread32(hw_priv, addr[i]);
+}
+
+
 static unsigned int __ath9k_reg_rmw(struct ath_softc *sc, u32 reg_offset,
 				    u32 set, u32 clr)
 {
@@ -530,6 +540,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
 	ah->hw = sc->hw;
 	ah->hw_version.devid = devid;
 	ah->reg_ops.read = ath9k_ioread32;
+	ah->reg_ops.multi_read = ath9k_multi_ioread32;
 	ah->reg_ops.write = ath9k_iowrite32;
 	ah->reg_ops.rmw = ath9k_reg_rmw;
 	pCap = &ah->caps;
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 06/18] ath9k: add new function ath9k_hw_read_array
  2015-03-20 12:38 ` [ath9k-devel] " Oleksij Rempel
@ 2015-03-20 12:38   ` Oleksij Rempel
  -1 siblings, 0 replies; 50+ messages in thread
From: Oleksij Rempel @ 2015-03-20 12:38 UTC (permalink / raw)
  To: linux-wireless, ath9k-devel, kvalo, adrian; +Cc: Oleksij Rempel

REG_READ generate most overhead on usb bus. It send and read micro packages
and reduce usb bandwidth. To reduce this overhead we should read in batches.

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 drivers/net/wireless/ath/ath9k/hw.c | 20 ++++++++++++++++++++
 drivers/net/wireless/ath/ath9k/hw.h |  3 +++
 2 files changed, 23 insertions(+)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 60aa8d7..15433c7 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -121,6 +121,26 @@ void ath9k_hw_write_array(struct ath_hw *ah, const struct ar5416IniArray *array,
 	REGWRITE_BUFFER_FLUSH(ah);
 }
 
+void ath9k_hw_read_array(struct ath_hw *ah, u32 array[][2], int size)
+{
+	u32 *tmp_reg_list, *tmp_data;
+	int i;
+
+	tmp_reg_list = kmalloc(size * sizeof(u32), GFP_KERNEL);
+	tmp_data = kmalloc(size * sizeof(u32), GFP_KERNEL);
+
+	for (i = 0; i < size; i++)
+		tmp_reg_list[i] = array[i][0];
+
+	REG_READ_MULTI(ah, tmp_reg_list, tmp_data, size);
+
+	for (i = 0; i < size; i++)
+		array[i][1] = tmp_data[i];
+
+	kfree(tmp_reg_list);
+	kfree(tmp_data);
+}
+
 u32 ath9k_hw_reverse_bits(u32 val, u32 n)
 {
 	u32 retval;
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index f1864cc..66aba10 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -138,6 +138,8 @@
 
 #define REG_WRITE_ARRAY(iniarray, column, regWr) \
 	ath9k_hw_write_array(ah, iniarray, column, &(regWr))
+#define REG_READ_ARRAY(ah, array, size) \
+	ath9k_hw_read_array(ah, array, size)
 
 #define AR_GPIO_OUTPUT_MUX_AS_OUTPUT             0
 #define AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED 1
@@ -1020,6 +1022,7 @@ void ath9k_hw_synth_delay(struct ath_hw *ah, struct ath9k_channel *chan,
 bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout);
 void ath9k_hw_write_array(struct ath_hw *ah, const struct ar5416IniArray *array,
 			  int column, unsigned int *writecnt);
+void ath9k_hw_read_array(struct ath_hw *ah, u32 array[][2], int size);
 u32 ath9k_hw_reverse_bits(u32 val, u32 n);
 u16 ath9k_hw_computetxtime(struct ath_hw *ah,
 			   u8 phy, int kbps,
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [ath9k-devel] [PATCH 06/18] ath9k: add new function ath9k_hw_read_array
@ 2015-03-20 12:38   ` Oleksij Rempel
  0 siblings, 0 replies; 50+ messages in thread
From: Oleksij Rempel @ 2015-03-20 12:38 UTC (permalink / raw)
  To: ath9k-devel

REG_READ generate most overhead on usb bus. It send and read micro packages
and reduce usb bandwidth. To reduce this overhead we should read in batches.

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 drivers/net/wireless/ath/ath9k/hw.c | 20 ++++++++++++++++++++
 drivers/net/wireless/ath/ath9k/hw.h |  3 +++
 2 files changed, 23 insertions(+)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 60aa8d7..15433c7 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -121,6 +121,26 @@ void ath9k_hw_write_array(struct ath_hw *ah, const struct ar5416IniArray *array,
 	REGWRITE_BUFFER_FLUSH(ah);
 }
 
+void ath9k_hw_read_array(struct ath_hw *ah, u32 array[][2], int size)
+{
+	u32 *tmp_reg_list, *tmp_data;
+	int i;
+
+	tmp_reg_list = kmalloc(size * sizeof(u32), GFP_KERNEL);
+	tmp_data = kmalloc(size * sizeof(u32), GFP_KERNEL);
+
+	for (i = 0; i < size; i++)
+		tmp_reg_list[i] = array[i][0];
+
+	REG_READ_MULTI(ah, tmp_reg_list, tmp_data, size);
+
+	for (i = 0; i < size; i++)
+		array[i][1] = tmp_data[i];
+
+	kfree(tmp_reg_list);
+	kfree(tmp_data);
+}
+
 u32 ath9k_hw_reverse_bits(u32 val, u32 n)
 {
 	u32 retval;
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index f1864cc..66aba10 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -138,6 +138,8 @@
 
 #define REG_WRITE_ARRAY(iniarray, column, regWr) \
 	ath9k_hw_write_array(ah, iniarray, column, &(regWr))
+#define REG_READ_ARRAY(ah, array, size) \
+	ath9k_hw_read_array(ah, array, size)
 
 #define AR_GPIO_OUTPUT_MUX_AS_OUTPUT             0
 #define AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED 1
@@ -1020,6 +1022,7 @@ void ath9k_hw_synth_delay(struct ath_hw *ah, struct ath9k_channel *chan,
 bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout);
 void ath9k_hw_write_array(struct ath_hw *ah, const struct ar5416IniArray *array,
 			  int column, unsigned int *writecnt);
+void ath9k_hw_read_array(struct ath_hw *ah, u32 array[][2], int size);
 u32 ath9k_hw_reverse_bits(u32 val, u32 n);
 u16 ath9k_hw_computetxtime(struct ath_hw *ah,
 			   u8 phy, int kbps,
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 07/18] ath9k: ar9271_hw_pa_cal: use REG_READ_ARRAY
  2015-03-20 12:38 ` [ath9k-devel] " Oleksij Rempel
@ 2015-03-20 12:38   ` Oleksij Rempel
  -1 siblings, 0 replies; 50+ messages in thread
From: Oleksij Rempel @ 2015-03-20 12:38 UTC (permalink / raw)
  To: linux-wireless, ath9k-devel, kvalo, adrian; +Cc: Oleksij Rempel

insted of reading each register separatly
and waste 4ms on each operation, we can
use one shot read.

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 drivers/net/wireless/ath/ath9k/ar9002_calib.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
index 62a2314..50fcd34 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
@@ -440,8 +440,7 @@ static void ar9271_hw_pa_cal(struct ath_hw *ah, bool is_reset)
 		{ AR9285_AN_RF2G3, 0 },
 	};
 
-	for (i = 0; i < ARRAY_SIZE(regList); i++)
-		regList[i][1] = REG_READ(ah, regList[i][0]);
+	REG_READ_ARRAY(ah, regList, ARRAY_SIZE(regList));
 
 	ENABLE_REG_RMW_BUFFER(ah);
 	/* 7834, b1=0 */
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [ath9k-devel] [PATCH 07/18] ath9k: ar9271_hw_pa_cal: use REG_READ_ARRAY
@ 2015-03-20 12:38   ` Oleksij Rempel
  0 siblings, 0 replies; 50+ messages in thread
From: Oleksij Rempel @ 2015-03-20 12:38 UTC (permalink / raw)
  To: ath9k-devel

insted of reading each register separatly
and waste 4ms on each operation, we can
use one shot read.

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 drivers/net/wireless/ath/ath9k/ar9002_calib.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
index 62a2314..50fcd34 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
@@ -440,8 +440,7 @@ static void ar9271_hw_pa_cal(struct ath_hw *ah, bool is_reset)
 		{ AR9285_AN_RF2G3, 0 },
 	};
 
-	for (i = 0; i < ARRAY_SIZE(regList); i++)
-		regList[i][1] = REG_READ(ah, regList[i][0]);
+	REG_READ_ARRAY(ah, regList, ARRAY_SIZE(regList));
 
 	ENABLE_REG_RMW_BUFFER(ah);
 	/* 7834, b1=0 */
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 08/18] ath9k: use one shot read in ath9k_hw_update_mibstats
  2015-03-20 12:38 ` [ath9k-devel] " Oleksij Rempel
@ 2015-03-20 12:38   ` Oleksij Rempel
  -1 siblings, 0 replies; 50+ messages in thread
From: Oleksij Rempel @ 2015-03-20 12:38 UTC (permalink / raw)
  To: linux-wireless, ath9k-devel, kvalo, adrian; +Cc: Oleksij Rempel

this will reduce some overhead on usb bus.

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 drivers/net/wireless/ath/ath9k/ani.c | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
index ca01d17..25e45e4 100644
--- a/drivers/net/wireless/ath/ath9k/ani.c
+++ b/drivers/net/wireless/ath/ath9k/ani.c
@@ -107,11 +107,21 @@ static const struct ani_cck_level_entry cck_level_table[] = {
 static void ath9k_hw_update_mibstats(struct ath_hw *ah,
 				     struct ath9k_mib_stats *stats)
 {
-	stats->ackrcv_bad += REG_READ(ah, AR_ACK_FAIL);
-	stats->rts_bad += REG_READ(ah, AR_RTS_FAIL);
-	stats->fcs_bad += REG_READ(ah, AR_FCS_FAIL);
-	stats->rts_good += REG_READ(ah, AR_RTS_OK);
-	stats->beacons += REG_READ(ah, AR_BEACON_CNT);
+	u32 addr[5] = {AR_RTS_OK, AR_RTS_FAIL, AR_ACK_FAIL,
+		       AR_FCS_FAIL, AR_BEACON_CNT};
+	u32 data[5];
+
+	REG_READ_MULTI(ah, &addr[0], &data[0], 5);
+	/* AR_RTS_OK */
+	stats->rts_good += data[0];
+	/* AR_RTS_FAIL */
+	stats->rts_bad += data[1];
+	/* AR_ACK_FAIL */
+	stats->ackrcv_bad += data[2];
+	/* AR_FCS_FAIL */
+	stats->fcs_bad += data[3];
+	/* AR_BEACON_CNT */
+	stats->beacons += data[4];
 }
 
 static void ath9k_ani_restart(struct ath_hw *ah)
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [ath9k-devel] [PATCH 08/18] ath9k: use one shot read in ath9k_hw_update_mibstats
@ 2015-03-20 12:38   ` Oleksij Rempel
  0 siblings, 0 replies; 50+ messages in thread
From: Oleksij Rempel @ 2015-03-20 12:38 UTC (permalink / raw)
  To: ath9k-devel

this will reduce some overhead on usb bus.

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 drivers/net/wireless/ath/ath9k/ani.c | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
index ca01d17..25e45e4 100644
--- a/drivers/net/wireless/ath/ath9k/ani.c
+++ b/drivers/net/wireless/ath/ath9k/ani.c
@@ -107,11 +107,21 @@ static const struct ani_cck_level_entry cck_level_table[] = {
 static void ath9k_hw_update_mibstats(struct ath_hw *ah,
 				     struct ath9k_mib_stats *stats)
 {
-	stats->ackrcv_bad += REG_READ(ah, AR_ACK_FAIL);
-	stats->rts_bad += REG_READ(ah, AR_RTS_FAIL);
-	stats->fcs_bad += REG_READ(ah, AR_FCS_FAIL);
-	stats->rts_good += REG_READ(ah, AR_RTS_OK);
-	stats->beacons += REG_READ(ah, AR_BEACON_CNT);
+	u32 addr[5] = {AR_RTS_OK, AR_RTS_FAIL, AR_ACK_FAIL,
+		       AR_FCS_FAIL, AR_BEACON_CNT};
+	u32 data[5];
+
+	REG_READ_MULTI(ah, &addr[0], &data[0], 5);
+	/* AR_RTS_OK */
+	stats->rts_good += data[0];
+	/* AR_RTS_FAIL */
+	stats->rts_bad += data[1];
+	/* AR_ACK_FAIL */
+	stats->ackrcv_bad += data[2];
+	/* AR_FCS_FAIL */
+	stats->fcs_bad += data[3];
+	/* AR_BEACON_CNT */
+	stats->beacons += data[4];
 }
 
 static void ath9k_ani_restart(struct ath_hw *ah)
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 09/18] ath9k: ath9k_hw_loadnf: use REG_RMW
  2015-03-20 12:38 ` [ath9k-devel] " Oleksij Rempel
@ 2015-03-20 12:38   ` Oleksij Rempel
  -1 siblings, 0 replies; 50+ messages in thread
From: Oleksij Rempel @ 2015-03-20 12:38 UTC (permalink / raw)
  To: linux-wireless, ath9k-devel, kvalo, adrian; +Cc: Oleksij Rempel

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 drivers/net/wireless/ath/ath9k/calib.c | 19 ++++++++-----------
 1 file changed, 8 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index e200a6e..3e2e24e 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -238,7 +238,6 @@ int ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
 {
 	struct ath9k_nfcal_hist *h = NULL;
 	unsigned i, j;
-	int32_t val;
 	u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask;
 	struct ath_common *common = ath9k_hw_common(ah);
 	s16 default_nf = ath9k_hw_get_default_nf(ah, chan);
@@ -246,6 +245,7 @@ int ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
 	if (ah->caldata)
 		h = ah->caldata->nfCalHist;
 
+	ENABLE_REG_RMW_BUFFER(ah);
 	for (i = 0; i < NUM_NF_READINGS; i++) {
 		if (chainmask & (1 << i)) {
 			s16 nfval;
@@ -258,10 +258,8 @@ int ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
 			else
 				nfval = default_nf;
 
-			val = REG_READ(ah, ah->nf_regs[i]);
-			val &= 0xFFFFFE00;
-			val |= (((u32) nfval << 1) & 0x1ff);
-			REG_WRITE(ah, ah->nf_regs[i], val);
+			REG_RMW(ah, ah->nf_regs[i],
+				(((u32) nfval << 1) & 0x1ff), 0x1ff);
 		}
 	}
 
@@ -274,6 +272,7 @@ int ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
 	REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
 		    AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
 	REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
+	REG_RMW_BUFFER_FLUSH(ah);
 
 	/*
 	 * Wait for load to complete, should be fast, a few 10s of us.
@@ -309,19 +308,17 @@ int ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
 	 * by the median we just loaded.  This will be initial (and max) value
 	 * of next noise floor calibration the baseband does.
 	 */
-	ENABLE_REGWRITE_BUFFER(ah);
+	ENABLE_REG_RMW_BUFFER(ah);
 	for (i = 0; i < NUM_NF_READINGS; i++) {
 		if (chainmask & (1 << i)) {
 			if ((i >= AR5416_MAX_CHAINS) && !IS_CHAN_HT40(chan))
 				continue;
 
-			val = REG_READ(ah, ah->nf_regs[i]);
-			val &= 0xFFFFFE00;
-			val |= (((u32) (-50) << 1) & 0x1ff);
-			REG_WRITE(ah, ah->nf_regs[i], val);
+			REG_RMW(ah, ah->nf_regs[i],
+					(((u32) (-50) << 1) & 0x1ff), 0x1ff);
 		}
 	}
-	REGWRITE_BUFFER_FLUSH(ah);
+	REG_RMW_BUFFER_FLUSH(ah);
 
 	return 0;
 }
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [ath9k-devel] [PATCH 09/18] ath9k: ath9k_hw_loadnf: use REG_RMW
@ 2015-03-20 12:38   ` Oleksij Rempel
  0 siblings, 0 replies; 50+ messages in thread
From: Oleksij Rempel @ 2015-03-20 12:38 UTC (permalink / raw)
  To: ath9k-devel

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 drivers/net/wireless/ath/ath9k/calib.c | 19 ++++++++-----------
 1 file changed, 8 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index e200a6e..3e2e24e 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -238,7 +238,6 @@ int ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
 {
 	struct ath9k_nfcal_hist *h = NULL;
 	unsigned i, j;
-	int32_t val;
 	u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask;
 	struct ath_common *common = ath9k_hw_common(ah);
 	s16 default_nf = ath9k_hw_get_default_nf(ah, chan);
@@ -246,6 +245,7 @@ int ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
 	if (ah->caldata)
 		h = ah->caldata->nfCalHist;
 
+	ENABLE_REG_RMW_BUFFER(ah);
 	for (i = 0; i < NUM_NF_READINGS; i++) {
 		if (chainmask & (1 << i)) {
 			s16 nfval;
@@ -258,10 +258,8 @@ int ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
 			else
 				nfval = default_nf;
 
-			val = REG_READ(ah, ah->nf_regs[i]);
-			val &= 0xFFFFFE00;
-			val |= (((u32) nfval << 1) & 0x1ff);
-			REG_WRITE(ah, ah->nf_regs[i], val);
+			REG_RMW(ah, ah->nf_regs[i],
+				(((u32) nfval << 1) & 0x1ff), 0x1ff);
 		}
 	}
 
@@ -274,6 +272,7 @@ int ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
 	REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
 		    AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
 	REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
+	REG_RMW_BUFFER_FLUSH(ah);
 
 	/*
 	 * Wait for load to complete, should be fast, a few 10s of us.
@@ -309,19 +308,17 @@ int ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
 	 * by the median we just loaded.  This will be initial (and max) value
 	 * of next noise floor calibration the baseband does.
 	 */
-	ENABLE_REGWRITE_BUFFER(ah);
+	ENABLE_REG_RMW_BUFFER(ah);
 	for (i = 0; i < NUM_NF_READINGS; i++) {
 		if (chainmask & (1 << i)) {
 			if ((i >= AR5416_MAX_CHAINS) && !IS_CHAN_HT40(chan))
 				continue;
 
-			val = REG_READ(ah, ah->nf_regs[i]);
-			val &= 0xFFFFFE00;
-			val |= (((u32) (-50) << 1) & 0x1ff);
-			REG_WRITE(ah, ah->nf_regs[i], val);
+			REG_RMW(ah, ah->nf_regs[i],
+					(((u32) (-50) << 1) & 0x1ff), 0x1ff);
 		}
 	}
-	REGWRITE_BUFFER_FLUSH(ah);
+	REG_RMW_BUFFER_FLUSH(ah);
 
 	return 0;
 }
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 10/18] ath9k: write buffer related optimisation in ar5008_hw_set_channel_regs
  2015-03-20 12:38 ` [ath9k-devel] " Oleksij Rempel
@ 2015-03-20 12:38   ` Oleksij Rempel
  -1 siblings, 0 replies; 50+ messages in thread
From: Oleksij Rempel @ 2015-03-20 12:38 UTC (permalink / raw)
  To: linux-wireless, ath9k-devel, kvalo, adrian; +Cc: Oleksij Rempel

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 drivers/net/wireless/ath/ath9k/ar5008_phy.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
index f273427..6c23d27 100644
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
@@ -681,12 +681,13 @@ static void ar5008_hw_set_channel_regs(struct ath_hw *ah,
 			phymode |= AR_PHY_FC_DYN2040_PRI_CH;
 
 	}
+	ENABLE_REGWRITE_BUFFER(ah);
 	REG_WRITE(ah, AR_PHY_TURBO, phymode);
 
+	/* This function do only REG_WRITE, so
+	 * we can include it to REGWRITE_BUFFER. */
 	ath9k_hw_set11nmac2040(ah, chan);
 
-	ENABLE_REGWRITE_BUFFER(ah);
-
 	REG_WRITE(ah, AR_GTXTO, 25 << AR_GTXTO_TIMEOUT_LIMIT_S);
 	REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S);
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [ath9k-devel] [PATCH 10/18] ath9k: write buffer related optimisation in ar5008_hw_set_channel_regs
@ 2015-03-20 12:38   ` Oleksij Rempel
  0 siblings, 0 replies; 50+ messages in thread
From: Oleksij Rempel @ 2015-03-20 12:38 UTC (permalink / raw)
  To: ath9k-devel

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 drivers/net/wireless/ath/ath9k/ar5008_phy.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
index f273427..6c23d27 100644
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
@@ -681,12 +681,13 @@ static void ar5008_hw_set_channel_regs(struct ath_hw *ah,
 			phymode |= AR_PHY_FC_DYN2040_PRI_CH;
 
 	}
+	ENABLE_REGWRITE_BUFFER(ah);
 	REG_WRITE(ah, AR_PHY_TURBO, phymode);
 
+	/* This function do only REG_WRITE, so
+	 * we can include it to REGWRITE_BUFFER. */
 	ath9k_hw_set11nmac2040(ah, chan);
 
-	ENABLE_REGWRITE_BUFFER(ah);
-
 	REG_WRITE(ah, AR_GTXTO, 25 << AR_GTXTO_TIMEOUT_LIMIT_S);
 	REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S);
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 11/18] ath9k: ath9k_hw_set_4k_power_cal_tabl: use rmw buffer
  2015-03-20 12:38 ` [ath9k-devel] " Oleksij Rempel
@ 2015-03-20 12:38   ` Oleksij Rempel
  -1 siblings, 0 replies; 50+ messages in thread
From: Oleksij Rempel @ 2015-03-20 12:38 UTC (permalink / raw)
  To: linux-wireless, ath9k-devel, kvalo, adrian; +Cc: Oleksij Rempel

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 drivers/net/wireless/ath/ath9k/eeprom_4k.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
index e5a78d4..fc54fc7 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
@@ -389,6 +389,7 @@ static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
 		}
 	}
 
+	ENABLE_REG_RMW_BUFFER(ah);
 	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
 		      (numXpdGain - 1) & 0x3);
 	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
@@ -396,6 +397,7 @@ static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
 	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
 		      xpdGainValues[1]);
 	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3, 0);
+	REG_RMW_BUFFER_FLUSH(ah);
 
 	for (i = 0; i < AR5416_EEP4K_MAX_CHAINS; i++) {
 		regChainOffset = i * 0x1000;
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [ath9k-devel] [PATCH 11/18] ath9k: ath9k_hw_set_4k_power_cal_tabl: use rmw buffer
@ 2015-03-20 12:38   ` Oleksij Rempel
  0 siblings, 0 replies; 50+ messages in thread
From: Oleksij Rempel @ 2015-03-20 12:38 UTC (permalink / raw)
  To: ath9k-devel

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 drivers/net/wireless/ath/ath9k/eeprom_4k.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
index e5a78d4..fc54fc7 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
@@ -389,6 +389,7 @@ static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
 		}
 	}
 
+	ENABLE_REG_RMW_BUFFER(ah);
 	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
 		      (numXpdGain - 1) & 0x3);
 	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
@@ -396,6 +397,7 @@ static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
 	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
 		      xpdGainValues[1]);
 	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3, 0);
+	REG_RMW_BUFFER_FLUSH(ah);
 
 	for (i = 0; i < AR5416_EEP4K_MAX_CHAINS; i++) {
 		regChainOffset = i * 0x1000;
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 12/18] ath9k: use rmw buffer in ath9k_hw_set_operating_mode and ath9k_hw_reset
  2015-03-20 12:38 ` [ath9k-devel] " Oleksij Rempel
@ 2015-03-20 12:38   ` Oleksij Rempel
  -1 siblings, 0 replies; 50+ messages in thread
From: Oleksij Rempel @ 2015-03-20 12:38 UTC (permalink / raw)
  To: linux-wireless, ath9k-devel, kvalo, adrian; +Cc: Oleksij Rempel

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 drivers/net/wireless/ath/ath9k/hw.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 15433c7..523a6a8 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1217,6 +1217,7 @@ static void ath9k_hw_set_operating_mode(struct ath_hw *ah, int opmode)
 	u32 mask = AR_STA_ID1_STA_AP | AR_STA_ID1_ADHOC;
 	u32 set = AR_STA_ID1_KSRCH_MODE;
 
+	ENABLE_REG_RMW_BUFFER(ah);
 	switch (opmode) {
 	case NL80211_IFTYPE_ADHOC:
 		if (!AR_SREV_9340_13(ah)) {
@@ -1238,6 +1239,7 @@ static void ath9k_hw_set_operating_mode(struct ath_hw *ah, int opmode)
 		break;
 	}
 	REG_RMW(ah, AR_STA_ID1, set, mask);
+	REG_RMW_BUFFER_FLUSH(ah);
 }
 
 void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled,
@@ -1950,6 +1952,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
 	if (!ath9k_hw_mci_is_enabled(ah))
 		REG_WRITE(ah, AR_OBS, 8);
 
+	ENABLE_REG_RMW_BUFFER(ah);
 	if (ah->config.rx_intr_mitigation) {
 		REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, ah->config.rimt_last);
 		REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, ah->config.rimt_first);
@@ -1959,6 +1962,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
 		REG_RMW_FIELD(ah, AR_TIMT, AR_TIMT_LAST, 300);
 		REG_RMW_FIELD(ah, AR_TIMT, AR_TIMT_FIRST, 750);
 	}
+	REG_RMW_BUFFER_FLUSH(ah);
 
 	ath9k_hw_init_bb(ah, chan);
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [ath9k-devel] [PATCH 12/18] ath9k: use rmw buffer in ath9k_hw_set_operating_mode and ath9k_hw_reset
@ 2015-03-20 12:38   ` Oleksij Rempel
  0 siblings, 0 replies; 50+ messages in thread
From: Oleksij Rempel @ 2015-03-20 12:38 UTC (permalink / raw)
  To: ath9k-devel

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 drivers/net/wireless/ath/ath9k/hw.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 15433c7..523a6a8 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1217,6 +1217,7 @@ static void ath9k_hw_set_operating_mode(struct ath_hw *ah, int opmode)
 	u32 mask = AR_STA_ID1_STA_AP | AR_STA_ID1_ADHOC;
 	u32 set = AR_STA_ID1_KSRCH_MODE;
 
+	ENABLE_REG_RMW_BUFFER(ah);
 	switch (opmode) {
 	case NL80211_IFTYPE_ADHOC:
 		if (!AR_SREV_9340_13(ah)) {
@@ -1238,6 +1239,7 @@ static void ath9k_hw_set_operating_mode(struct ath_hw *ah, int opmode)
 		break;
 	}
 	REG_RMW(ah, AR_STA_ID1, set, mask);
+	REG_RMW_BUFFER_FLUSH(ah);
 }
 
 void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled,
@@ -1950,6 +1952,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
 	if (!ath9k_hw_mci_is_enabled(ah))
 		REG_WRITE(ah, AR_OBS, 8);
 
+	ENABLE_REG_RMW_BUFFER(ah);
 	if (ah->config.rx_intr_mitigation) {
 		REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, ah->config.rimt_last);
 		REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, ah->config.rimt_first);
@@ -1959,6 +1962,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
 		REG_RMW_FIELD(ah, AR_TIMT, AR_TIMT_LAST, 300);
 		REG_RMW_FIELD(ah, AR_TIMT, AR_TIMT_FIRST, 750);
 	}
+	REG_RMW_BUFFER_FLUSH(ah);
 
 	ath9k_hw_init_bb(ah, chan);
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 13/18] ath9k: ath9k_hw_4k_set_board_values: use rmw buffer
  2015-03-20 12:38 ` [ath9k-devel] " Oleksij Rempel
@ 2015-03-20 12:38   ` Oleksij Rempel
  -1 siblings, 0 replies; 50+ messages in thread
From: Oleksij Rempel @ 2015-03-20 12:38 UTC (permalink / raw)
  To: linux-wireless, ath9k-devel, kvalo, adrian; +Cc: Oleksij Rempel

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 drivers/net/wireless/ath/ath9k/eeprom_4k.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
index fc54fc7..0600562 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
@@ -1082,6 +1082,7 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah,
 		mask = BIT(0)|BIT(5)|BIT(10)|BIT(15)|BIT(20)|BIT(25);
 		pwrctrl = mask * bb_desired_scale;
 		clr = mask * 0x1f;
+		ENABLE_REG_RMW_BUFFER(ah);
 		REG_RMW(ah, AR_PHY_TX_PWRCTRL8, pwrctrl, clr);
 		REG_RMW(ah, AR_PHY_TX_PWRCTRL10, pwrctrl, clr);
 		REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL12, pwrctrl, clr);
@@ -1096,6 +1097,7 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah,
 		clr = mask * 0x1f;
 		REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL11, pwrctrl, clr);
 		REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL13, pwrctrl, clr);
+		REG_RMW_BUFFER_FLUSH(ah);
 	}
 }
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [ath9k-devel] [PATCH 13/18] ath9k: ath9k_hw_4k_set_board_values: use rmw buffer
@ 2015-03-20 12:38   ` Oleksij Rempel
  0 siblings, 0 replies; 50+ messages in thread
From: Oleksij Rempel @ 2015-03-20 12:38 UTC (permalink / raw)
  To: ath9k-devel

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 drivers/net/wireless/ath/ath9k/eeprom_4k.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
index fc54fc7..0600562 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
@@ -1082,6 +1082,7 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah,
 		mask = BIT(0)|BIT(5)|BIT(10)|BIT(15)|BIT(20)|BIT(25);
 		pwrctrl = mask * bb_desired_scale;
 		clr = mask * 0x1f;
+		ENABLE_REG_RMW_BUFFER(ah);
 		REG_RMW(ah, AR_PHY_TX_PWRCTRL8, pwrctrl, clr);
 		REG_RMW(ah, AR_PHY_TX_PWRCTRL10, pwrctrl, clr);
 		REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL12, pwrctrl, clr);
@@ -1096,6 +1097,7 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah,
 		clr = mask * 0x1f;
 		REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL11, pwrctrl, clr);
 		REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL13, pwrctrl, clr);
+		REG_RMW_BUFFER_FLUSH(ah);
 	}
 }
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 14/18] ath9k: ath9k_hw_analog_shift_rmw: use REG_RMW
  2015-03-20 12:38 ` [ath9k-devel] " Oleksij Rempel
@ 2015-03-20 12:38   ` Oleksij Rempel
  -1 siblings, 0 replies; 50+ messages in thread
From: Oleksij Rempel @ 2015-03-20 12:38 UTC (permalink / raw)
  To: linux-wireless, ath9k-devel, kvalo, adrian; +Cc: Oleksij Rempel

use REG_RMW in ath9k_hw_analog_shift_rmw.
It will double execution speed on usb bus.

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 drivers/net/wireless/ath/ath9k/eeprom.c | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c
index 971d770..cc81482 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom.c
@@ -27,12 +27,7 @@ void ath9k_hw_analog_shift_regwrite(struct ath_hw *ah, u32 reg, u32 val)
 void ath9k_hw_analog_shift_rmw(struct ath_hw *ah, u32 reg, u32 mask,
 			       u32 shift, u32 val)
 {
-	u32 regVal;
-
-	regVal = REG_READ(ah, reg) & ~mask;
-	regVal |= (val << shift) & mask;
-
-	REG_WRITE(ah, reg, regVal);
+	REG_RMW(ah, reg, ((val << shift) & mask), mask);
 
 	if (ah->config.analog_shiftreg)
 		udelay(100);
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [ath9k-devel] [PATCH 14/18] ath9k: ath9k_hw_analog_shift_rmw: use REG_RMW
@ 2015-03-20 12:38   ` Oleksij Rempel
  0 siblings, 0 replies; 50+ messages in thread
From: Oleksij Rempel @ 2015-03-20 12:38 UTC (permalink / raw)
  To: ath9k-devel

use REG_RMW in ath9k_hw_analog_shift_rmw.
It will double execution speed on usb bus.

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 drivers/net/wireless/ath/ath9k/eeprom.c | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c
index 971d770..cc81482 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom.c
@@ -27,12 +27,7 @@ void ath9k_hw_analog_shift_regwrite(struct ath_hw *ah, u32 reg, u32 val)
 void ath9k_hw_analog_shift_rmw(struct ath_hw *ah, u32 reg, u32 mask,
 			       u32 shift, u32 val)
 {
-	u32 regVal;
-
-	regVal = REG_READ(ah, reg) & ~mask;
-	regVal |= (val << shift) & mask;
-
-	REG_WRITE(ah, reg, regVal);
+	REG_RMW(ah, reg, ((val << shift) & mask), mask);
 
 	if (ah->config.analog_shiftreg)
 		udelay(100);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 15/18] ath9k: ath9k_hw_4k_set_board_values: use rmw buffer
  2015-03-20 12:38 ` [ath9k-devel] " Oleksij Rempel
@ 2015-03-20 12:38   ` Oleksij Rempel
  -1 siblings, 0 replies; 50+ messages in thread
From: Oleksij Rempel @ 2015-03-20 12:38 UTC (permalink / raw)
  To: linux-wireless, ath9k-devel, kvalo, adrian; +Cc: Oleksij Rempel

it will reduce exution time from 14ms to 2ms on ar9271

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 drivers/net/wireless/ath/ath9k/eeprom_4k.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
index 0600562..291c1d1 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
@@ -930,6 +930,7 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah,
 		}
 	}
 
+	ENABLE_REG_RMW_BUFFER(ah);
 	if (AR_SREV_9271(ah)) {
 		ath9k_hw_analog_shift_rmw(ah,
 					  AR9285_AN_RF2G3,
@@ -1034,6 +1035,7 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah,
 					  AR9285_AN_RF2G4_DB2_4_S,
 					  db2[4]);
 	}
+	REG_RMW_BUFFER_FLUSH(ah);
 
 
 	REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [ath9k-devel] [PATCH 15/18] ath9k: ath9k_hw_4k_set_board_values: use rmw buffer
@ 2015-03-20 12:38   ` Oleksij Rempel
  0 siblings, 0 replies; 50+ messages in thread
From: Oleksij Rempel @ 2015-03-20 12:38 UTC (permalink / raw)
  To: ath9k-devel

it will reduce exution time from 14ms to 2ms on ar9271

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 drivers/net/wireless/ath/ath9k/eeprom_4k.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
index 0600562..291c1d1 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
@@ -930,6 +930,7 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah,
 		}
 	}
 
+	ENABLE_REG_RMW_BUFFER(ah);
 	if (AR_SREV_9271(ah)) {
 		ath9k_hw_analog_shift_rmw(ah,
 					  AR9285_AN_RF2G3,
@@ -1034,6 +1035,7 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah,
 					  AR9285_AN_RF2G4_DB2_4_S,
 					  db2[4]);
 	}
+	REG_RMW_BUFFER_FLUSH(ah);
 
 
 	REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 16/18] ath9k: use REG_RMW and rmw buffer in ath9k_hw_4k_set_gain
  2015-03-20 12:38 ` [ath9k-devel] " Oleksij Rempel
@ 2015-03-20 12:38   ` Oleksij Rempel
  -1 siblings, 0 replies; 50+ messages in thread
From: Oleksij Rempel @ 2015-03-20 12:38 UTC (permalink / raw)
  To: linux-wireless, ath9k-devel, kvalo, adrian; +Cc: Oleksij Rempel

it is possible to reduce time needed for this function
by rplacing REG_WRITE with REG_RMW (plus dummy 0) and putt all commands
in same buffer.

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 drivers/net/wireless/ath/ath9k/eeprom_4k.c | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
index 291c1d1..56621be 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
@@ -772,15 +772,16 @@ static void ath9k_hw_4k_set_gain(struct ath_hw *ah,
 				 struct ar5416_eeprom_4k *eep,
 				 u8 txRxAttenLocal)
 {
-	REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0,
-		  pModal->antCtrlChain[0]);
+	ENABLE_REG_RMW_BUFFER(ah);
+	REG_RMW(ah, AR_PHY_SWITCH_CHAIN_0,
+		pModal->antCtrlChain[0], 0);
 
-	REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0),
-		  (REG_READ(ah, AR_PHY_TIMING_CTRL4(0)) &
-		   ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
-		     AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
-		  SM(pModal->iqCalICh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
-		  SM(pModal->iqCalQCh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
+	REG_RMW(ah, AR_PHY_TIMING_CTRL4(0),
+		(REG_READ(ah, AR_PHY_TIMING_CTRL4(0)) &
+		 ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
+		   AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
+		SM(pModal->iqCalICh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
+		SM(pModal->iqCalQCh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF), 0);
 
 	if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
 	    AR5416_EEP_MINOR_VER_3) {
@@ -819,6 +820,7 @@ static void ath9k_hw_4k_set_gain(struct ath_hw *ah,
 		      AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);
 	REG_RMW_FIELD(ah, AR_PHY_RXGAIN + 0x1000,
 		      AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[0]);
+	REG_RMW_BUFFER_FLUSH(ah);
 }
 
 /*
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [ath9k-devel] [PATCH 16/18] ath9k: use REG_RMW and rmw buffer in ath9k_hw_4k_set_gain
@ 2015-03-20 12:38   ` Oleksij Rempel
  0 siblings, 0 replies; 50+ messages in thread
From: Oleksij Rempel @ 2015-03-20 12:38 UTC (permalink / raw)
  To: ath9k-devel

it is possible to reduce time needed for this function
by rplacing REG_WRITE with REG_RMW (plus dummy 0) and putt all commands
in same buffer.

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 drivers/net/wireless/ath/ath9k/eeprom_4k.c | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
index 291c1d1..56621be 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
@@ -772,15 +772,16 @@ static void ath9k_hw_4k_set_gain(struct ath_hw *ah,
 				 struct ar5416_eeprom_4k *eep,
 				 u8 txRxAttenLocal)
 {
-	REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0,
-		  pModal->antCtrlChain[0]);
+	ENABLE_REG_RMW_BUFFER(ah);
+	REG_RMW(ah, AR_PHY_SWITCH_CHAIN_0,
+		pModal->antCtrlChain[0], 0);
 
-	REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0),
-		  (REG_READ(ah, AR_PHY_TIMING_CTRL4(0)) &
-		   ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
-		     AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
-		  SM(pModal->iqCalICh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
-		  SM(pModal->iqCalQCh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
+	REG_RMW(ah, AR_PHY_TIMING_CTRL4(0),
+		(REG_READ(ah, AR_PHY_TIMING_CTRL4(0)) &
+		 ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
+		   AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
+		SM(pModal->iqCalICh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
+		SM(pModal->iqCalQCh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF), 0);
 
 	if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
 	    AR5416_EEP_MINOR_VER_3) {
@@ -819,6 +820,7 @@ static void ath9k_hw_4k_set_gain(struct ath_hw *ah,
 		      AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);
 	REG_RMW_FIELD(ah, AR_PHY_RXGAIN + 0x1000,
 		      AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[0]);
+	REG_RMW_BUFFER_FLUSH(ah);
 }
 
 /*
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 17/18] ath9k: use REG_RMW and rmw buffer in ath9k_hw_4k_set_board_values
  2015-03-20 12:38 ` [ath9k-devel] " Oleksij Rempel
@ 2015-03-20 12:38   ` Oleksij Rempel
  -1 siblings, 0 replies; 50+ messages in thread
From: Oleksij Rempel @ 2015-03-20 12:38 UTC (permalink / raw)
  To: linux-wireless, ath9k-devel, kvalo, adrian; +Cc: Oleksij Rempel

replace REG_WRITE to REG_RMW and place every thing in one
RMW buffer.

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 drivers/net/wireless/ath/ath9k/eeprom_4k.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
index 56621be..a631962 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
@@ -1039,17 +1039,17 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah,
 	}
 	REG_RMW_BUFFER_FLUSH(ah);
 
-
+	ENABLE_REG_RMW_BUFFER(ah);
 	REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
 		      pModal->switchSettling);
 	REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC,
 		      pModal->adcDesiredSize);
 
-	REG_WRITE(ah, AR_PHY_RF_CTL4,
-		  SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF) |
-		  SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF) |
-		  SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON)  |
-		  SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON));
+	REG_RMW(ah, AR_PHY_RF_CTL4,
+		SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF) |
+		SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF) |
+		SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON)  |
+		SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON), 0);
 
 	REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,
 		      pModal->txEndToRxOn);
@@ -1078,6 +1078,8 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah,
 				      pModal->swSettleHt40);
 	}
 
+	REG_RMW_BUFFER_FLUSH(ah);
+
 	bb_desired_scale = (pModal->bb_scale_smrt_antenna &
 			EEP_4K_BB_DESIRED_SCALE_MASK);
 	if ((pBase->txGainType == 0) && (bb_desired_scale != 0)) {
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [ath9k-devel] [PATCH 17/18] ath9k: use REG_RMW and rmw buffer in ath9k_hw_4k_set_board_values
@ 2015-03-20 12:38   ` Oleksij Rempel
  0 siblings, 0 replies; 50+ messages in thread
From: Oleksij Rempel @ 2015-03-20 12:38 UTC (permalink / raw)
  To: ath9k-devel

replace REG_WRITE to REG_RMW and place every thing in one
RMW buffer.

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 drivers/net/wireless/ath/ath9k/eeprom_4k.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
index 56621be..a631962 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
@@ -1039,17 +1039,17 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah,
 	}
 	REG_RMW_BUFFER_FLUSH(ah);
 
-
+	ENABLE_REG_RMW_BUFFER(ah);
 	REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
 		      pModal->switchSettling);
 	REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC,
 		      pModal->adcDesiredSize);
 
-	REG_WRITE(ah, AR_PHY_RF_CTL4,
-		  SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF) |
-		  SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF) |
-		  SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON)  |
-		  SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON));
+	REG_RMW(ah, AR_PHY_RF_CTL4,
+		SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF) |
+		SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF) |
+		SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON)  |
+		SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON), 0);
 
 	REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,
 		      pModal->txEndToRxOn);
@@ -1078,6 +1078,8 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah,
 				      pModal->swSettleHt40);
 	}
 
+	REG_RMW_BUFFER_FLUSH(ah);
+
 	bb_desired_scale = (pModal->bb_scale_smrt_antenna &
 			EEP_4K_BB_DESIRED_SCALE_MASK);
 	if ((pBase->txGainType == 0) && (bb_desired_scale != 0)) {
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 18/18] ath9k: use REG_RMW and rmw buffer in ath9k_hw_def_set_gain
  2015-03-20 12:38 ` [ath9k-devel] " Oleksij Rempel
@ 2015-03-20 12:38   ` Oleksij Rempel
  -1 siblings, 0 replies; 50+ messages in thread
From: Oleksij Rempel @ 2015-03-20 12:38 UTC (permalink / raw)
  To: linux-wireless, ath9k-devel, kvalo, adrian; +Cc: Oleksij Rempel

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 drivers/net/wireless/ath/ath9k/eeprom_def.c | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c
index 0980590..4b43539 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_def.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c
@@ -466,6 +466,7 @@ static void ath9k_hw_def_set_gain(struct ath_hw *ah,
 				  struct ar5416_eeprom_def *eep,
 				  u8 txRxAttenLocal, int regChainOffset, int i)
 {
+	ENABLE_REG_RMW_BUFFER(ah);
 	if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) {
 		txRxAttenLocal = pModal->txRxAttenCh[i];
 
@@ -483,16 +484,16 @@ static void ath9k_hw_def_set_gain(struct ath_hw *ah,
 			      AR_PHY_GAIN_2GHZ_XATTEN2_DB,
 			      pModal->xatten2Db[i]);
 		} else {
-			REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+			REG_RMW(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
 			  (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
 			   ~AR_PHY_GAIN_2GHZ_BSW_MARGIN)
 			  | SM(pModal-> bswMargin[i],
-			       AR_PHY_GAIN_2GHZ_BSW_MARGIN));
-			REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+			       AR_PHY_GAIN_2GHZ_BSW_MARGIN), 0);
+			REG_RMW(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
 			  (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
 			   ~AR_PHY_GAIN_2GHZ_BSW_ATTEN)
 			  | SM(pModal->bswAtten[i],
-			       AR_PHY_GAIN_2GHZ_BSW_ATTEN));
+			       AR_PHY_GAIN_2GHZ_BSW_ATTEN), 0);
 		}
 	}
 
@@ -504,17 +505,19 @@ static void ath9k_hw_def_set_gain(struct ath_hw *ah,
 		      AR_PHY_RXGAIN + regChainOffset,
 		      AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[i]);
 	} else {
-		REG_WRITE(ah,
+		REG_RMW(ah,
 			  AR_PHY_RXGAIN + regChainOffset,
 			  (REG_READ(ah, AR_PHY_RXGAIN + regChainOffset) &
 			   ~AR_PHY_RXGAIN_TXRX_ATTEN)
-			  | SM(txRxAttenLocal, AR_PHY_RXGAIN_TXRX_ATTEN));
-		REG_WRITE(ah,
+			  | SM(txRxAttenLocal, AR_PHY_RXGAIN_TXRX_ATTEN), 0);
+		REG_RMW(ah,
 			  AR_PHY_GAIN_2GHZ + regChainOffset,
 			  (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
 			   ~AR_PHY_GAIN_2GHZ_RXTX_MARGIN) |
-			  SM(pModal->rxTxMarginCh[i], AR_PHY_GAIN_2GHZ_RXTX_MARGIN));
+			  SM(pModal->rxTxMarginCh[i],
+			  AR_PHY_GAIN_2GHZ_RXTX_MARGIN), 0);
 	}
+	REG_RMW_BUFFER_FLUSH(ah);
 }
 
 static void ath9k_hw_def_set_board_values(struct ath_hw *ah,
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [ath9k-devel] [PATCH 18/18] ath9k: use REG_RMW and rmw buffer in ath9k_hw_def_set_gain
@ 2015-03-20 12:38   ` Oleksij Rempel
  0 siblings, 0 replies; 50+ messages in thread
From: Oleksij Rempel @ 2015-03-20 12:38 UTC (permalink / raw)
  To: ath9k-devel

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 drivers/net/wireless/ath/ath9k/eeprom_def.c | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c
index 0980590..4b43539 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_def.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c
@@ -466,6 +466,7 @@ static void ath9k_hw_def_set_gain(struct ath_hw *ah,
 				  struct ar5416_eeprom_def *eep,
 				  u8 txRxAttenLocal, int regChainOffset, int i)
 {
+	ENABLE_REG_RMW_BUFFER(ah);
 	if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) {
 		txRxAttenLocal = pModal->txRxAttenCh[i];
 
@@ -483,16 +484,16 @@ static void ath9k_hw_def_set_gain(struct ath_hw *ah,
 			      AR_PHY_GAIN_2GHZ_XATTEN2_DB,
 			      pModal->xatten2Db[i]);
 		} else {
-			REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+			REG_RMW(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
 			  (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
 			   ~AR_PHY_GAIN_2GHZ_BSW_MARGIN)
 			  | SM(pModal-> bswMargin[i],
-			       AR_PHY_GAIN_2GHZ_BSW_MARGIN));
-			REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+			       AR_PHY_GAIN_2GHZ_BSW_MARGIN), 0);
+			REG_RMW(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
 			  (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
 			   ~AR_PHY_GAIN_2GHZ_BSW_ATTEN)
 			  | SM(pModal->bswAtten[i],
-			       AR_PHY_GAIN_2GHZ_BSW_ATTEN));
+			       AR_PHY_GAIN_2GHZ_BSW_ATTEN), 0);
 		}
 	}
 
@@ -504,17 +505,19 @@ static void ath9k_hw_def_set_gain(struct ath_hw *ah,
 		      AR_PHY_RXGAIN + regChainOffset,
 		      AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[i]);
 	} else {
-		REG_WRITE(ah,
+		REG_RMW(ah,
 			  AR_PHY_RXGAIN + regChainOffset,
 			  (REG_READ(ah, AR_PHY_RXGAIN + regChainOffset) &
 			   ~AR_PHY_RXGAIN_TXRX_ATTEN)
-			  | SM(txRxAttenLocal, AR_PHY_RXGAIN_TXRX_ATTEN));
-		REG_WRITE(ah,
+			  | SM(txRxAttenLocal, AR_PHY_RXGAIN_TXRX_ATTEN), 0);
+		REG_RMW(ah,
 			  AR_PHY_GAIN_2GHZ + regChainOffset,
 			  (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
 			   ~AR_PHY_GAIN_2GHZ_RXTX_MARGIN) |
-			  SM(pModal->rxTxMarginCh[i], AR_PHY_GAIN_2GHZ_RXTX_MARGIN));
+			  SM(pModal->rxTxMarginCh[i],
+			  AR_PHY_GAIN_2GHZ_RXTX_MARGIN), 0);
 	}
+	REG_RMW_BUFFER_FLUSH(ah);
 }
 
 static void ath9k_hw_def_set_board_values(struct ath_hw *ah,
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* Re: [PATCH 16/18] ath9k: use REG_RMW and rmw buffer in ath9k_hw_4k_set_gain
  2015-03-20 12:38   ` [ath9k-devel] " Oleksij Rempel
@ 2015-03-20 13:00     ` Felix Fietkau
  -1 siblings, 0 replies; 50+ messages in thread
From: Felix Fietkau @ 2015-03-20 13:00 UTC (permalink / raw)
  To: Oleksij Rempel, linux-wireless, ath9k-devel, kvalo, adrian

On 2015-03-20 13:38, Oleksij Rempel wrote:
> it is possible to reduce time needed for this function
> by rplacing REG_WRITE with REG_RMW (plus dummy 0) and putt all commands
> in same buffer.
> 
> Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
> ---
>  drivers/net/wireless/ath/ath9k/eeprom_4k.c | 18 ++++++++++--------
>  1 file changed, 10 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
> index 291c1d1..56621be 100644
> --- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
> +++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
> @@ -772,15 +772,16 @@ static void ath9k_hw_4k_set_gain(struct ath_hw *ah,
>  				 struct ar5416_eeprom_4k *eep,
>  				 u8 txRxAttenLocal)
>  {
> -	REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0,
> -		  pModal->antCtrlChain[0]);
> +	ENABLE_REG_RMW_BUFFER(ah);
> +	REG_RMW(ah, AR_PHY_SWITCH_CHAIN_0,
> +		pModal->antCtrlChain[0], 0);
How about combining the WRITE/RMW buffering in ath9k_htc (automatically
deciding whether to use RMW or WRITE for the whole transaction), instead
of quirky looking REG_WRITE to REG_RMW conversions?

> -	REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0),
> -		  (REG_READ(ah, AR_PHY_TIMING_CTRL4(0)) &
> -		   ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
> -		     AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
> -		  SM(pModal->iqCalICh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
> -		  SM(pModal->iqCalQCh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
> +	REG_RMW(ah, AR_PHY_TIMING_CTRL4(0),
> +		(REG_READ(ah, AR_PHY_TIMING_CTRL4(0)) &
> +		 ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
> +		   AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
> +		SM(pModal->iqCalICh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
> +		SM(pModal->iqCalQCh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF), 0);
If you translate it to REG_RMW, you should get rid of the REG_READ part.

- Felix

^ permalink raw reply	[flat|nested] 50+ messages in thread

* [ath9k-devel] [PATCH 16/18] ath9k: use REG_RMW and rmw buffer in ath9k_hw_4k_set_gain
@ 2015-03-20 13:00     ` Felix Fietkau
  0 siblings, 0 replies; 50+ messages in thread
From: Felix Fietkau @ 2015-03-20 13:00 UTC (permalink / raw)
  To: ath9k-devel

On 2015-03-20 13:38, Oleksij Rempel wrote:
> it is possible to reduce time needed for this function
> by rplacing REG_WRITE with REG_RMW (plus dummy 0) and putt all commands
> in same buffer.
> 
> Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
> ---
>  drivers/net/wireless/ath/ath9k/eeprom_4k.c | 18 ++++++++++--------
>  1 file changed, 10 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
> index 291c1d1..56621be 100644
> --- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
> +++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
> @@ -772,15 +772,16 @@ static void ath9k_hw_4k_set_gain(struct ath_hw *ah,
>  				 struct ar5416_eeprom_4k *eep,
>  				 u8 txRxAttenLocal)
>  {
> -	REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0,
> -		  pModal->antCtrlChain[0]);
> +	ENABLE_REG_RMW_BUFFER(ah);
> +	REG_RMW(ah, AR_PHY_SWITCH_CHAIN_0,
> +		pModal->antCtrlChain[0], 0);
How about combining the WRITE/RMW buffering in ath9k_htc (automatically
deciding whether to use RMW or WRITE for the whole transaction), instead
of quirky looking REG_WRITE to REG_RMW conversions?

> -	REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0),
> -		  (REG_READ(ah, AR_PHY_TIMING_CTRL4(0)) &
> -		   ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
> -		     AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
> -		  SM(pModal->iqCalICh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
> -		  SM(pModal->iqCalQCh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
> +	REG_RMW(ah, AR_PHY_TIMING_CTRL4(0),
> +		(REG_READ(ah, AR_PHY_TIMING_CTRL4(0)) &
> +		 ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
> +		   AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
> +		SM(pModal->iqCalICh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
> +		SM(pModal->iqCalQCh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF), 0);
If you translate it to REG_RMW, you should get rid of the REG_READ part.

- Felix

^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 18/18] ath9k: use REG_RMW and rmw buffer in ath9k_hw_def_set_gain
  2015-03-20 12:38   ` [ath9k-devel] " Oleksij Rempel
@ 2015-03-20 13:01     ` Felix Fietkau
  -1 siblings, 0 replies; 50+ messages in thread
From: Felix Fietkau @ 2015-03-20 13:01 UTC (permalink / raw)
  To: Oleksij Rempel, linux-wireless, ath9k-devel, kvalo, adrian

On 2015-03-20 13:38, Oleksij Rempel wrote:
> Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
> ---
>  drivers/net/wireless/ath/ath9k/eeprom_def.c | 19 +++++++++++--------
>  1 file changed, 11 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c
> index 0980590..4b43539 100644
> --- a/drivers/net/wireless/ath/ath9k/eeprom_def.c
> +++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c
> @@ -466,6 +466,7 @@ static void ath9k_hw_def_set_gain(struct ath_hw *ah,
>  				  struct ar5416_eeprom_def *eep,
>  				  u8 txRxAttenLocal, int regChainOffset, int i)
>  {
> +	ENABLE_REG_RMW_BUFFER(ah);
>  	if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) {
>  		txRxAttenLocal = pModal->txRxAttenCh[i];
>  
> @@ -483,16 +484,16 @@ static void ath9k_hw_def_set_gain(struct ath_hw *ah,
>  			      AR_PHY_GAIN_2GHZ_XATTEN2_DB,
>  			      pModal->xatten2Db[i]);
>  		} else {
> -			REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
> +			REG_RMW(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
>  			  (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
>  			   ~AR_PHY_GAIN_2GHZ_BSW_MARGIN)
>  			  | SM(pModal-> bswMargin[i],
> -			       AR_PHY_GAIN_2GHZ_BSW_MARGIN));
> -			REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
> +			       AR_PHY_GAIN_2GHZ_BSW_MARGIN), 0);
> +			REG_RMW(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
>  			  (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
>  			   ~AR_PHY_GAIN_2GHZ_BSW_ATTEN)
>  			  | SM(pModal->bswAtten[i],
> -			       AR_PHY_GAIN_2GHZ_BSW_ATTEN));
> +			       AR_PHY_GAIN_2GHZ_BSW_ATTEN), 0);
>  		}
>  	}
>  
> @@ -504,17 +505,19 @@ static void ath9k_hw_def_set_gain(struct ath_hw *ah,
>  		      AR_PHY_RXGAIN + regChainOffset,
>  		      AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[i]);
>  	} else {
> -		REG_WRITE(ah,
> +		REG_RMW(ah,
>  			  AR_PHY_RXGAIN + regChainOffset,
>  			  (REG_READ(ah, AR_PHY_RXGAIN + regChainOffset) &
>  			   ~AR_PHY_RXGAIN_TXRX_ATTEN)
> -			  | SM(txRxAttenLocal, AR_PHY_RXGAIN_TXRX_ATTEN));
> -		REG_WRITE(ah,
> +			  | SM(txRxAttenLocal, AR_PHY_RXGAIN_TXRX_ATTEN), 0);
> +		REG_RMW(ah,
>  			  AR_PHY_GAIN_2GHZ + regChainOffset,
>  			  (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
>  			   ~AR_PHY_GAIN_2GHZ_RXTX_MARGIN) |
> -			  SM(pModal->rxTxMarginCh[i], AR_PHY_GAIN_2GHZ_RXTX_MARGIN));
> +			  SM(pModal->rxTxMarginCh[i],
> +			  AR_PHY_GAIN_2GHZ_RXTX_MARGIN), 0);
>  	}
> +	REG_RMW_BUFFER_FLUSH(ah);
Same in those chunks as in the other patch, do proper conversion to
REG_RMW by eliminating the REG_READ.

- Felix

^ permalink raw reply	[flat|nested] 50+ messages in thread

* [ath9k-devel] [PATCH 18/18] ath9k: use REG_RMW and rmw buffer in ath9k_hw_def_set_gain
@ 2015-03-20 13:01     ` Felix Fietkau
  0 siblings, 0 replies; 50+ messages in thread
From: Felix Fietkau @ 2015-03-20 13:01 UTC (permalink / raw)
  To: ath9k-devel

On 2015-03-20 13:38, Oleksij Rempel wrote:
> Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
> ---
>  drivers/net/wireless/ath/ath9k/eeprom_def.c | 19 +++++++++++--------
>  1 file changed, 11 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c
> index 0980590..4b43539 100644
> --- a/drivers/net/wireless/ath/ath9k/eeprom_def.c
> +++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c
> @@ -466,6 +466,7 @@ static void ath9k_hw_def_set_gain(struct ath_hw *ah,
>  				  struct ar5416_eeprom_def *eep,
>  				  u8 txRxAttenLocal, int regChainOffset, int i)
>  {
> +	ENABLE_REG_RMW_BUFFER(ah);
>  	if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) {
>  		txRxAttenLocal = pModal->txRxAttenCh[i];
>  
> @@ -483,16 +484,16 @@ static void ath9k_hw_def_set_gain(struct ath_hw *ah,
>  			      AR_PHY_GAIN_2GHZ_XATTEN2_DB,
>  			      pModal->xatten2Db[i]);
>  		} else {
> -			REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
> +			REG_RMW(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
>  			  (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
>  			   ~AR_PHY_GAIN_2GHZ_BSW_MARGIN)
>  			  | SM(pModal-> bswMargin[i],
> -			       AR_PHY_GAIN_2GHZ_BSW_MARGIN));
> -			REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
> +			       AR_PHY_GAIN_2GHZ_BSW_MARGIN), 0);
> +			REG_RMW(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
>  			  (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
>  			   ~AR_PHY_GAIN_2GHZ_BSW_ATTEN)
>  			  | SM(pModal->bswAtten[i],
> -			       AR_PHY_GAIN_2GHZ_BSW_ATTEN));
> +			       AR_PHY_GAIN_2GHZ_BSW_ATTEN), 0);
>  		}
>  	}
>  
> @@ -504,17 +505,19 @@ static void ath9k_hw_def_set_gain(struct ath_hw *ah,
>  		      AR_PHY_RXGAIN + regChainOffset,
>  		      AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[i]);
>  	} else {
> -		REG_WRITE(ah,
> +		REG_RMW(ah,
>  			  AR_PHY_RXGAIN + regChainOffset,
>  			  (REG_READ(ah, AR_PHY_RXGAIN + regChainOffset) &
>  			   ~AR_PHY_RXGAIN_TXRX_ATTEN)
> -			  | SM(txRxAttenLocal, AR_PHY_RXGAIN_TXRX_ATTEN));
> -		REG_WRITE(ah,
> +			  | SM(txRxAttenLocal, AR_PHY_RXGAIN_TXRX_ATTEN), 0);
> +		REG_RMW(ah,
>  			  AR_PHY_GAIN_2GHZ + regChainOffset,
>  			  (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
>  			   ~AR_PHY_GAIN_2GHZ_RXTX_MARGIN) |
> -			  SM(pModal->rxTxMarginCh[i], AR_PHY_GAIN_2GHZ_RXTX_MARGIN));
> +			  SM(pModal->rxTxMarginCh[i],
> +			  AR_PHY_GAIN_2GHZ_RXTX_MARGIN), 0);
>  	}
> +	REG_RMW_BUFFER_FLUSH(ah);
Same in those chunks as in the other patch, do proper conversion to
REG_RMW by eliminating the REG_READ.

- Felix

^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH 16/18] ath9k: use REG_RMW and rmw buffer in ath9k_hw_4k_set_gain
  2015-03-20 13:00     ` [ath9k-devel] " Felix Fietkau
@ 2015-03-21  5:25       ` Oleksij Rempel
  -1 siblings, 0 replies; 50+ messages in thread
From: Oleksij Rempel @ 2015-03-21  5:25 UTC (permalink / raw)
  To: Felix Fietkau, linux-wireless, ath9k-devel, kvalo, adrian

[-- Attachment #1: Type: text/plain, Size: 2185 bytes --]

Am 20.03.2015 um 14:00 schrieb Felix Fietkau:
> On 2015-03-20 13:38, Oleksij Rempel wrote:
>> it is possible to reduce time needed for this function
>> by rplacing REG_WRITE with REG_RMW (plus dummy 0) and putt all commands
>> in same buffer.
>>
>> Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
>> ---
>>  drivers/net/wireless/ath/ath9k/eeprom_4k.c | 18 ++++++++++--------
>>  1 file changed, 10 insertions(+), 8 deletions(-)
>>
>> diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
>> index 291c1d1..56621be 100644
>> --- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
>> +++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
>> @@ -772,15 +772,16 @@ static void ath9k_hw_4k_set_gain(struct ath_hw *ah,
>>  				 struct ar5416_eeprom_4k *eep,
>>  				 u8 txRxAttenLocal)
>>  {
>> -	REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0,
>> -		  pModal->antCtrlChain[0]);
>> +	ENABLE_REG_RMW_BUFFER(ah);
>> +	REG_RMW(ah, AR_PHY_SWITCH_CHAIN_0,
>> +		pModal->antCtrlChain[0], 0);
> How about combining the WRITE/RMW buffering in ath9k_htc (automatically
> deciding whether to use RMW or WRITE for the whole transaction), instead
> of quirky looking REG_WRITE to REG_RMW conversions?

Yea, i was thinking about this too, but decided to go readable way. Not
to produce unexpected behaviour of WRITE or READ cmd.

>> -	REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0),
>> -		  (REG_READ(ah, AR_PHY_TIMING_CTRL4(0)) &
>> -		   ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
>> -		     AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
>> -		  SM(pModal->iqCalICh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
>> -		  SM(pModal->iqCalQCh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
>> +	REG_RMW(ah, AR_PHY_TIMING_CTRL4(0),
>> +		(REG_READ(ah, AR_PHY_TIMING_CTRL4(0)) &
>> +		 ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
>> +		   AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
>> +		SM(pModal->iqCalICh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
>> +		SM(pModal->iqCalQCh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF), 0);
> If you translate it to REG_RMW, you should get rid of the REG_READ part.

Ok, thank you. I'll take a look.


-- 
Regards,
Oleksij


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 213 bytes --]

^ permalink raw reply	[flat|nested] 50+ messages in thread

* [ath9k-devel] [PATCH 16/18] ath9k: use REG_RMW and rmw buffer in ath9k_hw_4k_set_gain
@ 2015-03-21  5:25       ` Oleksij Rempel
  0 siblings, 0 replies; 50+ messages in thread
From: Oleksij Rempel @ 2015-03-21  5:25 UTC (permalink / raw)
  To: ath9k-devel

Am 20.03.2015 um 14:00 schrieb Felix Fietkau:
> On 2015-03-20 13:38, Oleksij Rempel wrote:
>> it is possible to reduce time needed for this function
>> by rplacing REG_WRITE with REG_RMW (plus dummy 0) and putt all commands
>> in same buffer.
>>
>> Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
>> ---
>>  drivers/net/wireless/ath/ath9k/eeprom_4k.c | 18 ++++++++++--------
>>  1 file changed, 10 insertions(+), 8 deletions(-)
>>
>> diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
>> index 291c1d1..56621be 100644
>> --- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
>> +++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
>> @@ -772,15 +772,16 @@ static void ath9k_hw_4k_set_gain(struct ath_hw *ah,
>>  				 struct ar5416_eeprom_4k *eep,
>>  				 u8 txRxAttenLocal)
>>  {
>> -	REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0,
>> -		  pModal->antCtrlChain[0]);
>> +	ENABLE_REG_RMW_BUFFER(ah);
>> +	REG_RMW(ah, AR_PHY_SWITCH_CHAIN_0,
>> +		pModal->antCtrlChain[0], 0);
> How about combining the WRITE/RMW buffering in ath9k_htc (automatically
> deciding whether to use RMW or WRITE for the whole transaction), instead
> of quirky looking REG_WRITE to REG_RMW conversions?

Yea, i was thinking about this too, but decided to go readable way. Not
to produce unexpected behaviour of WRITE or READ cmd.

>> -	REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0),
>> -		  (REG_READ(ah, AR_PHY_TIMING_CTRL4(0)) &
>> -		   ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
>> -		     AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
>> -		  SM(pModal->iqCalICh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
>> -		  SM(pModal->iqCalQCh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
>> +	REG_RMW(ah, AR_PHY_TIMING_CTRL4(0),
>> +		(REG_READ(ah, AR_PHY_TIMING_CTRL4(0)) &
>> +		 ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
>> +		   AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
>> +		SM(pModal->iqCalICh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
>> +		SM(pModal->iqCalQCh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF), 0);
> If you translate it to REG_RMW, you should get rid of the REG_READ part.

Ok, thank you. I'll take a look.


-- 
Regards,
Oleksij

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 213 bytes
Desc: OpenPGP digital signature
Url : http://lists.ath9k.org/pipermail/ath9k-devel/attachments/20150321/2d764310/attachment.pgp 

^ permalink raw reply	[flat|nested] 50+ messages in thread

* [PATCH 18/18 v2] ath9k: use REG_RMW and rmw buffer in ath9k_hw_def_set_gain
  2015-03-20 13:01     ` [ath9k-devel] " Felix Fietkau
@ 2015-03-21  8:04       ` Oleksij Rempel
  -1 siblings, 0 replies; 50+ messages in thread
From: Oleksij Rempel @ 2015-03-21  8:04 UTC (permalink / raw)
  To: linux-wireless, kvalo, ath9k-devel, nbd, adrian; +Cc: Oleksij Rempel

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 drivers/net/wireless/ath/ath9k/eeprom_def.c | 34 ++++++++++++-----------------
 1 file changed, 14 insertions(+), 20 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c
index 0980590..056f516 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_def.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c
@@ -466,6 +466,7 @@ static void ath9k_hw_def_set_gain(struct ath_hw *ah,
 				  struct ar5416_eeprom_def *eep,
 				  u8 txRxAttenLocal, int regChainOffset, int i)
 {
+	ENABLE_REG_RMW_BUFFER(ah);
 	if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) {
 		txRxAttenLocal = pModal->txRxAttenCh[i];
 
@@ -483,16 +484,12 @@ static void ath9k_hw_def_set_gain(struct ath_hw *ah,
 			      AR_PHY_GAIN_2GHZ_XATTEN2_DB,
 			      pModal->xatten2Db[i]);
 		} else {
-			REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
-			  (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
-			   ~AR_PHY_GAIN_2GHZ_BSW_MARGIN)
-			  | SM(pModal-> bswMargin[i],
-			       AR_PHY_GAIN_2GHZ_BSW_MARGIN));
-			REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
-			  (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
-			   ~AR_PHY_GAIN_2GHZ_BSW_ATTEN)
-			  | SM(pModal->bswAtten[i],
-			       AR_PHY_GAIN_2GHZ_BSW_ATTEN));
+			REG_RMW(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+				SM(pModal-> bswMargin[i], AR_PHY_GAIN_2GHZ_BSW_MARGIN),
+				AR_PHY_GAIN_2GHZ_BSW_MARGIN);
+			REG_RMW(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+				SM(pModal->bswAtten[i], AR_PHY_GAIN_2GHZ_BSW_ATTEN),
+				AR_PHY_GAIN_2GHZ_BSW_ATTEN);
 		}
 	}
 
@@ -504,17 +501,14 @@ static void ath9k_hw_def_set_gain(struct ath_hw *ah,
 		      AR_PHY_RXGAIN + regChainOffset,
 		      AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[i]);
 	} else {
-		REG_WRITE(ah,
-			  AR_PHY_RXGAIN + regChainOffset,
-			  (REG_READ(ah, AR_PHY_RXGAIN + regChainOffset) &
-			   ~AR_PHY_RXGAIN_TXRX_ATTEN)
-			  | SM(txRxAttenLocal, AR_PHY_RXGAIN_TXRX_ATTEN));
-		REG_WRITE(ah,
-			  AR_PHY_GAIN_2GHZ + regChainOffset,
-			  (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
-			   ~AR_PHY_GAIN_2GHZ_RXTX_MARGIN) |
-			  SM(pModal->rxTxMarginCh[i], AR_PHY_GAIN_2GHZ_RXTX_MARGIN));
+		REG_RMW(ah, AR_PHY_RXGAIN + regChainOffset,
+			SM(txRxAttenLocal, AR_PHY_RXGAIN_TXRX_ATTEN),
+			AR_PHY_RXGAIN_TXRX_ATTEN);
+		REG_RMW(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+			SM(pModal->rxTxMarginCh[i], AR_PHY_GAIN_2GHZ_RXTX_MARGIN),
+			AR_PHY_GAIN_2GHZ_RXTX_MARGIN);
 	}
+	REG_RMW_BUFFER_FLUSH(ah);
 }
 
 static void ath9k_hw_def_set_board_values(struct ath_hw *ah,
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [ath9k-devel] [PATCH 18/18 v2] ath9k: use REG_RMW and rmw buffer in ath9k_hw_def_set_gain
@ 2015-03-21  8:04       ` Oleksij Rempel
  0 siblings, 0 replies; 50+ messages in thread
From: Oleksij Rempel @ 2015-03-21  8:04 UTC (permalink / raw)
  To: ath9k-devel

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 drivers/net/wireless/ath/ath9k/eeprom_def.c | 34 ++++++++++++-----------------
 1 file changed, 14 insertions(+), 20 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c
index 0980590..056f516 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_def.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c
@@ -466,6 +466,7 @@ static void ath9k_hw_def_set_gain(struct ath_hw *ah,
 				  struct ar5416_eeprom_def *eep,
 				  u8 txRxAttenLocal, int regChainOffset, int i)
 {
+	ENABLE_REG_RMW_BUFFER(ah);
 	if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) {
 		txRxAttenLocal = pModal->txRxAttenCh[i];
 
@@ -483,16 +484,12 @@ static void ath9k_hw_def_set_gain(struct ath_hw *ah,
 			      AR_PHY_GAIN_2GHZ_XATTEN2_DB,
 			      pModal->xatten2Db[i]);
 		} else {
-			REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
-			  (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
-			   ~AR_PHY_GAIN_2GHZ_BSW_MARGIN)
-			  | SM(pModal-> bswMargin[i],
-			       AR_PHY_GAIN_2GHZ_BSW_MARGIN));
-			REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
-			  (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
-			   ~AR_PHY_GAIN_2GHZ_BSW_ATTEN)
-			  | SM(pModal->bswAtten[i],
-			       AR_PHY_GAIN_2GHZ_BSW_ATTEN));
+			REG_RMW(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+				SM(pModal-> bswMargin[i], AR_PHY_GAIN_2GHZ_BSW_MARGIN),
+				AR_PHY_GAIN_2GHZ_BSW_MARGIN);
+			REG_RMW(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+				SM(pModal->bswAtten[i], AR_PHY_GAIN_2GHZ_BSW_ATTEN),
+				AR_PHY_GAIN_2GHZ_BSW_ATTEN);
 		}
 	}
 
@@ -504,17 +501,14 @@ static void ath9k_hw_def_set_gain(struct ath_hw *ah,
 		      AR_PHY_RXGAIN + regChainOffset,
 		      AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[i]);
 	} else {
-		REG_WRITE(ah,
-			  AR_PHY_RXGAIN + regChainOffset,
-			  (REG_READ(ah, AR_PHY_RXGAIN + regChainOffset) &
-			   ~AR_PHY_RXGAIN_TXRX_ATTEN)
-			  | SM(txRxAttenLocal, AR_PHY_RXGAIN_TXRX_ATTEN));
-		REG_WRITE(ah,
-			  AR_PHY_GAIN_2GHZ + regChainOffset,
-			  (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
-			   ~AR_PHY_GAIN_2GHZ_RXTX_MARGIN) |
-			  SM(pModal->rxTxMarginCh[i], AR_PHY_GAIN_2GHZ_RXTX_MARGIN));
+		REG_RMW(ah, AR_PHY_RXGAIN + regChainOffset,
+			SM(txRxAttenLocal, AR_PHY_RXGAIN_TXRX_ATTEN),
+			AR_PHY_RXGAIN_TXRX_ATTEN);
+		REG_RMW(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+			SM(pModal->rxTxMarginCh[i], AR_PHY_GAIN_2GHZ_RXTX_MARGIN),
+			AR_PHY_GAIN_2GHZ_RXTX_MARGIN);
 	}
+	REG_RMW_BUFFER_FLUSH(ah);
 }
 
 static void ath9k_hw_def_set_board_values(struct ath_hw *ah,
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH 16/18 v2] ath9k: use REG_RMW and rmw buffer in ath9k_hw_4k_set_gain
  2015-03-20 13:00     ` [ath9k-devel] " Felix Fietkau
@ 2015-03-21  8:07       ` Oleksij Rempel
  -1 siblings, 0 replies; 50+ messages in thread
From: Oleksij Rempel @ 2015-03-21  8:07 UTC (permalink / raw)
  To: linux-wireless, kvalo, ath9k-devel, nbd, adrian; +Cc: Oleksij Rempel

it is possible to reduce time needed for this function
by rplacing REG_WRITE with REG_RMW (plus dummy 0) and putt all commands
in same buffer.

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 drivers/net/wireless/ath/ath9k/eeprom_4k.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
index 291c1d1..38dc965 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
@@ -772,15 +772,14 @@ static void ath9k_hw_4k_set_gain(struct ath_hw *ah,
 				 struct ar5416_eeprom_4k *eep,
 				 u8 txRxAttenLocal)
 {
-	REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0,
-		  pModal->antCtrlChain[0]);
+	ENABLE_REG_RMW_BUFFER(ah);
+	REG_RMW(ah, AR_PHY_SWITCH_CHAIN_0,
+		pModal->antCtrlChain[0], 0);
 
-	REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0),
-		  (REG_READ(ah, AR_PHY_TIMING_CTRL4(0)) &
-		   ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
-		     AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
-		  SM(pModal->iqCalICh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
-		  SM(pModal->iqCalQCh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
+	REG_RMW(ah, AR_PHY_TIMING_CTRL4(0),
+		SM(pModal->iqCalICh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
+		SM(pModal->iqCalQCh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF),
+		AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF | AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF);
 
 	if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
 	    AR5416_EEP_MINOR_VER_3) {
@@ -819,6 +818,7 @@ static void ath9k_hw_4k_set_gain(struct ath_hw *ah,
 		      AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);
 	REG_RMW_FIELD(ah, AR_PHY_RXGAIN + 0x1000,
 		      AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[0]);
+	REG_RMW_BUFFER_FLUSH(ah);
 }
 
 /*
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [ath9k-devel] [PATCH 16/18 v2] ath9k: use REG_RMW and rmw buffer in ath9k_hw_4k_set_gain
@ 2015-03-21  8:07       ` Oleksij Rempel
  0 siblings, 0 replies; 50+ messages in thread
From: Oleksij Rempel @ 2015-03-21  8:07 UTC (permalink / raw)
  To: ath9k-devel

it is possible to reduce time needed for this function
by rplacing REG_WRITE with REG_RMW (plus dummy 0) and putt all commands
in same buffer.

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 drivers/net/wireless/ath/ath9k/eeprom_4k.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
index 291c1d1..38dc965 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
@@ -772,15 +772,14 @@ static void ath9k_hw_4k_set_gain(struct ath_hw *ah,
 				 struct ar5416_eeprom_4k *eep,
 				 u8 txRxAttenLocal)
 {
-	REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0,
-		  pModal->antCtrlChain[0]);
+	ENABLE_REG_RMW_BUFFER(ah);
+	REG_RMW(ah, AR_PHY_SWITCH_CHAIN_0,
+		pModal->antCtrlChain[0], 0);
 
-	REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0),
-		  (REG_READ(ah, AR_PHY_TIMING_CTRL4(0)) &
-		   ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
-		     AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
-		  SM(pModal->iqCalICh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
-		  SM(pModal->iqCalQCh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
+	REG_RMW(ah, AR_PHY_TIMING_CTRL4(0),
+		SM(pModal->iqCalICh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
+		SM(pModal->iqCalQCh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF),
+		AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF | AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF);
 
 	if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
 	    AR5416_EEP_MINOR_VER_3) {
@@ -819,6 +818,7 @@ static void ath9k_hw_4k_set_gain(struct ath_hw *ah,
 		      AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);
 	REG_RMW_FIELD(ah, AR_PHY_RXGAIN + 0x1000,
 		      AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[0]);
+	REG_RMW_BUFFER_FLUSH(ah);
 }
 
 /*
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* Re: [PATCH 16/18 v2] ath9k: use REG_RMW and rmw buffer in ath9k_hw_4k_set_gain
  2015-03-21  8:07       ` [ath9k-devel] " Oleksij Rempel
@ 2015-03-21  8:43         ` Kalle Valo
  -1 siblings, 0 replies; 50+ messages in thread
From: Kalle Valo @ 2015-03-21  8:43 UTC (permalink / raw)
  To: Oleksij Rempel; +Cc: linux-wireless, ath9k-devel, nbd, adrian

Oleksij Rempel <linux@rempel-privat.de> writes:

> it is possible to reduce time needed for this function
> by rplacing REG_WRITE with REG_RMW (plus dummy 0) and putt all commands
> in same buffer.
>
> Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>

Please resend the whole patchset, much more reliable that way.

-- 
Kalle Valo

^ permalink raw reply	[flat|nested] 50+ messages in thread

* [ath9k-devel] [PATCH 16/18 v2] ath9k: use REG_RMW and rmw buffer in ath9k_hw_4k_set_gain
@ 2015-03-21  8:43         ` Kalle Valo
  0 siblings, 0 replies; 50+ messages in thread
From: Kalle Valo @ 2015-03-21  8:43 UTC (permalink / raw)
  To: ath9k-devel

Oleksij Rempel <linux@rempel-privat.de> writes:

> it is possible to reduce time needed for this function
> by rplacing REG_WRITE with REG_RMW (plus dummy 0) and putt all commands
> in same buffer.
>
> Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>

Please resend the whole patchset, much more reliable that way.

-- 
Kalle Valo

^ permalink raw reply	[flat|nested] 50+ messages in thread

end of thread, other threads:[~2015-03-21  8:43 UTC | newest]

Thread overview: 50+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-03-20 12:38 [PATCH 00/18] reduce some of ath9k_htc performance problems Oleksij Rempel
2015-03-20 12:38 ` [ath9k-devel] " Oleksij Rempel
2015-03-20 12:38 ` [PATCH 01/18] ath9k_htc: add new WMI_REG_RMW_CMDID command Oleksij Rempel
2015-03-20 12:38   ` [ath9k-devel] " Oleksij Rempel
2015-03-20 12:38 ` [PATCH 02/18] ath9k: ar9271_hw_pa_cal - use defs instead of magin numbers Oleksij Rempel
2015-03-20 12:38   ` [ath9k-devel] " Oleksij Rempel
2015-03-20 12:38 ` [PATCH 03/18] ath9k: ar9271_hw_pa_cal: use proper makroses Oleksij Rempel
2015-03-20 12:38   ` [ath9k-devel] " Oleksij Rempel
2015-03-20 12:38 ` [PATCH 04/18] ath9k: ar9271_hw_pa_cal: use RMW buffer Oleksij Rempel
2015-03-20 12:38   ` [ath9k-devel] " Oleksij Rempel
2015-03-20 12:38 ` [PATCH 05/18] ath9k: add multi_read to be compatible with ath9k_htc Oleksij Rempel
2015-03-20 12:38   ` [ath9k-devel] " Oleksij Rempel
2015-03-20 12:38 ` [PATCH 06/18] ath9k: add new function ath9k_hw_read_array Oleksij Rempel
2015-03-20 12:38   ` [ath9k-devel] " Oleksij Rempel
2015-03-20 12:38 ` [PATCH 07/18] ath9k: ar9271_hw_pa_cal: use REG_READ_ARRAY Oleksij Rempel
2015-03-20 12:38   ` [ath9k-devel] " Oleksij Rempel
2015-03-20 12:38 ` [PATCH 08/18] ath9k: use one shot read in ath9k_hw_update_mibstats Oleksij Rempel
2015-03-20 12:38   ` [ath9k-devel] " Oleksij Rempel
2015-03-20 12:38 ` [PATCH 09/18] ath9k: ath9k_hw_loadnf: use REG_RMW Oleksij Rempel
2015-03-20 12:38   ` [ath9k-devel] " Oleksij Rempel
2015-03-20 12:38 ` [PATCH 10/18] ath9k: write buffer related optimisation in ar5008_hw_set_channel_regs Oleksij Rempel
2015-03-20 12:38   ` [ath9k-devel] " Oleksij Rempel
2015-03-20 12:38 ` [PATCH 11/18] ath9k: ath9k_hw_set_4k_power_cal_tabl: use rmw buffer Oleksij Rempel
2015-03-20 12:38   ` [ath9k-devel] " Oleksij Rempel
2015-03-20 12:38 ` [PATCH 12/18] ath9k: use rmw buffer in ath9k_hw_set_operating_mode and ath9k_hw_reset Oleksij Rempel
2015-03-20 12:38   ` [ath9k-devel] " Oleksij Rempel
2015-03-20 12:38 ` [PATCH 13/18] ath9k: ath9k_hw_4k_set_board_values: use rmw buffer Oleksij Rempel
2015-03-20 12:38   ` [ath9k-devel] " Oleksij Rempel
2015-03-20 12:38 ` [PATCH 14/18] ath9k: ath9k_hw_analog_shift_rmw: use REG_RMW Oleksij Rempel
2015-03-20 12:38   ` [ath9k-devel] " Oleksij Rempel
2015-03-20 12:38 ` [PATCH 15/18] ath9k: ath9k_hw_4k_set_board_values: use rmw buffer Oleksij Rempel
2015-03-20 12:38   ` [ath9k-devel] " Oleksij Rempel
2015-03-20 12:38 ` [PATCH 16/18] ath9k: use REG_RMW and rmw buffer in ath9k_hw_4k_set_gain Oleksij Rempel
2015-03-20 12:38   ` [ath9k-devel] " Oleksij Rempel
2015-03-20 13:00   ` Felix Fietkau
2015-03-20 13:00     ` [ath9k-devel] " Felix Fietkau
2015-03-21  5:25     ` Oleksij Rempel
2015-03-21  5:25       ` [ath9k-devel] " Oleksij Rempel
2015-03-21  8:07     ` [PATCH 16/18 v2] " Oleksij Rempel
2015-03-21  8:07       ` [ath9k-devel] " Oleksij Rempel
2015-03-21  8:43       ` Kalle Valo
2015-03-21  8:43         ` [ath9k-devel] " Kalle Valo
2015-03-20 12:38 ` [PATCH 17/18] ath9k: use REG_RMW and rmw buffer in ath9k_hw_4k_set_board_values Oleksij Rempel
2015-03-20 12:38   ` [ath9k-devel] " Oleksij Rempel
2015-03-20 12:38 ` [PATCH 18/18] ath9k: use REG_RMW and rmw buffer in ath9k_hw_def_set_gain Oleksij Rempel
2015-03-20 12:38   ` [ath9k-devel] " Oleksij Rempel
2015-03-20 13:01   ` Felix Fietkau
2015-03-20 13:01     ` [ath9k-devel] " Felix Fietkau
2015-03-21  8:04     ` [PATCH 18/18 v2] " Oleksij Rempel
2015-03-21  8:04       ` [ath9k-devel] " Oleksij Rempel

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.