From: Tamizh chelvam <c_tr...@qti.qualcomm.com>

This patch add support to enable or disable btcoex via nl80211.
The firmware support this feature since 10.2.4.54 on 2G-only board,
dual band or 5G boards don't support this. WMI service
WMI_SERVICE_COEX_GPIO is used to identify the firmware support of this
feature.

Signed-off-by: Tamizh chelvam <c_tr...@qti.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/debug.c |   37 ++------------------
 drivers/net/wireless/ath/ath10k/mac.c   |   58 +++++++++++++++++++++++++++++++
 drivers/net/wireless/ath/ath10k/mac.h   |    1 +
 3 files changed, 62 insertions(+), 34 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/debug.c 
b/drivers/net/wireless/ath/ath10k/debug.c
index 82a4c67..ea30fbe 100644
--- a/drivers/net/wireless/ath/ath10k/debug.c
+++ b/drivers/net/wireless/ath/ath10k/debug.c
@@ -26,6 +26,7 @@
 #include "debug.h"
 #include "hif.h"
 #include "wmi-ops.h"
+#include "mac.h"
 
 /* ms */
 #define ATH10K_DEBUG_HTT_STATS_INTERVAL 1000
@@ -2138,7 +2139,6 @@ static ssize_t ath10k_write_btcoex(struct file *file,
        size_t buf_size;
        int ret;
        bool val;
-       u32 pdev_param;
 
        buf_size = min(count, (sizeof(buf) - 1));
        if (copy_from_user(buf, ubuf, buf_size))
@@ -2150,40 +2150,9 @@ static ssize_t ath10k_write_btcoex(struct file *file,
                return -EINVAL;
 
        mutex_lock(&ar->conf_mutex);
-
-       if (ar->state != ATH10K_STATE_ON &&
-           ar->state != ATH10K_STATE_RESTARTED) {
-               ret = -ENETDOWN;
-               goto exit;
-       }
-
-       if (!(test_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags) ^ val)) {
+       ret = ath10k_mac_set_btcoex(ar, val);
+       if (!ret)
                ret = count;
-               goto exit;
-       }
-
-       pdev_param = ar->wmi.pdev_param->enable_btcoex;
-       if (test_bit(ATH10K_FW_FEATURE_BTCOEX_PARAM,
-                    ar->running_fw->fw_file.fw_features)) {
-               ret = ath10k_wmi_pdev_set_param(ar, pdev_param, val);
-               if (ret) {
-                       ath10k_warn(ar, "failed to enable btcoex: %d\n", ret);
-                       ret = count;
-                       goto exit;
-               }
-       } else {
-               ath10k_info(ar, "restarting firmware due to btcoex change");
-               queue_work(ar->workqueue, &ar->restart_work);
-       }
-
-       if (val)
-               set_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags);
-       else
-               clear_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags);
-
-       ret = count;
-
-exit:
        mutex_unlock(&ar->conf_mutex);
 
        return ret;
diff --git a/drivers/net/wireless/ath/ath10k/mac.c 
b/drivers/net/wireless/ath/ath10k/mac.c
index 717b2fa..e7131b9 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -7445,6 +7445,63 @@ struct ath10k_mac_change_chanctx_arg {
        return 0;
 }
 
+static inline void ath10k_mac_update_btcoex_flag(struct ath10k *ar, bool val)
+{
+       if (val)
+               set_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags);
+       else
+               clear_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags);
+}
+
+int ath10k_mac_set_btcoex(struct ath10k *ar, bool val)
+{
+       u32 pdev_param;
+       int ret;
+
+       lockdep_assert_held(&ar->conf_mutex);
+
+       if (ar->state != ATH10K_STATE_ON &&
+           ar->state != ATH10K_STATE_RESTARTED)
+               return -ENETDOWN;
+
+       if (!(test_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags) ^ val))
+               return 0;
+
+       pdev_param = ar->wmi.pdev_param->enable_btcoex;
+       if (test_bit(ATH10K_FW_FEATURE_BTCOEX_PARAM,
+                    ar->running_fw->fw_file.fw_features)) {
+               ret = ath10k_wmi_pdev_set_param(ar, pdev_param, val);
+
+               if (ret) {
+                       ath10k_warn(ar,
+                                   "failed to modify btcoex state: %d\n", ret);
+                       return ret;
+               }
+               ath10k_mac_update_btcoex_flag(ar, val);
+       } else {
+               ath10k_info(ar, "restarting firmware due to btcoex change");
+               ath10k_mac_update_btcoex_flag(ar, val);
+               queue_work(ar->workqueue, &ar->restart_work);
+       }
+
+       return 0;
+}
+
+static int ath10k_mac_op_set_btcoex(struct ieee80211_hw *hw, bool enabled)
+{
+       int ret;
+       struct ath10k *ar = hw->priv;
+
+       if (!test_bit(WMI_SERVICE_COEX_GPIO, ar->wmi.svc_map))
+               return -EOPNOTSUPP;
+
+       mutex_lock(&ar->conf_mutex);
+       ret = ath10k_mac_set_btcoex(ar, enabled);
+       mutex_unlock(&ar->conf_mutex);
+
+       return ret;
+}
+
 static const struct ieee80211_ops ath10k_ops = {
        .tx                             = ath10k_mac_op_tx,
        .wake_tx_queue                  = ath10k_mac_op_wake_tx_queue,
@@ -7486,6 +7543,7 @@ struct ath10k_mac_change_chanctx_arg {
        .assign_vif_chanctx             = ath10k_mac_op_assign_vif_chanctx,
        .unassign_vif_chanctx           = ath10k_mac_op_unassign_vif_chanctx,
        .switch_vif_chanctx             = ath10k_mac_op_switch_vif_chanctx,
+       .set_btcoex                     = ath10k_mac_op_set_btcoex,
 
        CFG80211_TESTMODE_CMD(ath10k_tm_cmd)
 
diff --git a/drivers/net/wireless/ath/ath10k/mac.h 
b/drivers/net/wireless/ath/ath10k/mac.h
index 1bd29ec..de1fa72 100644
--- a/drivers/net/wireless/ath/ath10k/mac.h
+++ b/drivers/net/wireless/ath/ath10k/mac.h
@@ -82,6 +82,7 @@ struct ieee80211_txq *ath10k_mac_txq_lookup(struct ath10k *ar,
                                            u16 peer_id,
                                            u8 tid);
 int ath10k_mac_ext_resource_config(struct ath10k *ar, u32 val);
+int ath10k_mac_set_btcoex(struct ath10k *ar, bool val);
 
 static inline struct ath10k_vif *ath10k_vif_to_arvif(struct ieee80211_vif *vif)
 {
-- 
1.7.9.5

Reply via email to