summaryrefslogtreecommitdiffstats
path: root/package/kernel/mac80211/patches/319-ath9k_htc-add-new-WMI_REG_RMW_CMDID-command.patch
diff options
context:
space:
mode:
Diffstat (limited to 'package/kernel/mac80211/patches/319-ath9k_htc-add-new-WMI_REG_RMW_CMDID-command.patch')
-rw-r--r--package/kernel/mac80211/patches/319-ath9k_htc-add-new-WMI_REG_RMW_CMDID-command.patch307
1 files changed, 0 insertions, 307 deletions
diff --git a/package/kernel/mac80211/patches/319-ath9k_htc-add-new-WMI_REG_RMW_CMDID-command.patch b/package/kernel/mac80211/patches/319-ath9k_htc-add-new-WMI_REG_RMW_CMDID-command.patch
deleted file mode 100644
index 6af69ebd2a..0000000000
--- a/package/kernel/mac80211/patches/319-ath9k_htc-add-new-WMI_REG_RMW_CMDID-command.patch
+++ /dev/null
@@ -1,307 +0,0 @@
-From: Oleksij Rempel <linux@rempel-privat.de>
-Date: Sun, 22 Mar 2015 19:29:46 +0100
-Subject: [PATCH] ath9k_htc: add new WMI_REG_RMW_CMDID command
-
-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>
-Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
----
-
---- 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;
---- 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
- #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;
---- 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 *h
- 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);
-+
-+ 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;
-+ }
-
-- val = ath9k_regread(hw_priv, reg_offset);
-- val &= ~clr;
-- val |= set;
-- ath9k_regwrite(hw_priv, val, reg_offset);
-+ 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_
- 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(s
- 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;
- }
-
---- 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",\
---- 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
- 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_
- 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,
---- 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);