wlan-ap-Telecominfraproject/feeds/wifi-ax/mac80211/patches/qca/112-ath11k-add-btcoex-debugfs-support.patch
John Crispin 528a778e38 open-converged-wireless: Import 21.02 based uCentral tree
Signed-off-by: John Crispin <john@phrozen.org>
2021-03-25 12:19:47 +01:00

395 lines
11 KiB
Diff

--- a/drivers/net/wireless/ath/ath11k/debug.c
+++ b/drivers/net/wireless/ath/ath11k/debug.c
@@ -1355,6 +1355,186 @@ static const struct file_operations fops
.open = simple_open
};
+static ssize_t ath11k_write_btcoex(struct file *file,
+ const char __user *ubuf,
+ size_t count, loff_t *ppos)
+{
+ struct ath11k_vif *arvif;
+ struct ath11k *ar = file->private_data;
+ char buf[256];
+ size_t buf_size;
+ int ret,coex = -1;
+ enum qca_wlan_priority_type wlan_prio_mask = 0;
+ int wlan_weight = 0;
+
+ if (!ar)
+ return -EINVAL;
+
+ buf_size = min(count, (sizeof(buf) - 1));
+ if (copy_from_user(buf, ubuf, buf_size))
+ return -EFAULT;
+
+ buf[buf_size] = '\0';
+ ret = sscanf(buf, "%d %u %d" , &coex, &wlan_prio_mask, &wlan_weight);
+ if (!ret)
+ return -EINVAL;
+
+ if (wlan_weight == -1)
+ wlan_weight = 0;
+
+ if(wlan_prio_mask == -1)
+ wlan_prio_mask =0;
+
+ if(wlan_weight < 0 || wlan_prio_mask < 0)
+ return -EINVAL;
+
+ if(coex != 1 && coex != -1 && coex)
+ return -EINVAL;
+
+ mutex_lock(&ar->conf_mutex);
+ arvif = list_first_entry(&ar->arvifs, typeof(*arvif), list);
+ if (!arvif->is_started) {
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ if(coex == 1 && !test_bit(ATH11K_FLAG_BTCOEX, &ar->dev_flags))
+ set_bit(ATH11K_FLAG_BTCOEX, &ar->dev_flags);
+
+ if(coex == -1 && !test_bit(ATH11K_FLAG_BTCOEX, &ar->dev_flags)){
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ if (!coex)
+ clear_bit(ATH11K_FLAG_BTCOEX, &ar->dev_flags);
+
+ ret = ath11k_mac_coex_config(ar, arvif, coex, wlan_prio_mask, wlan_weight);
+ if (ret)
+ goto exit;
+
+ ar->coex.wlan_prio_mask = wlan_prio_mask;
+ ar->coex.wlan_weight = wlan_weight;
+ ret = count;
+exit:
+ mutex_unlock(&ar->conf_mutex);
+ return ret;
+}
+
+static ssize_t ath11k_read_btcoex(struct file *file, char __user *ubuf,
+ size_t count, loff_t *ppos)
+{
+ struct ath11k *ar = file->private_data;
+ char buf[256];
+ int len=0;
+
+ if (!ar)
+ return -EINVAL;
+
+ mutex_lock(&ar->conf_mutex);
+ len = scnprintf(buf, sizeof(buf) - len, "%d %d %d\n",
+ test_bit(ATH11K_FLAG_BTCOEX, &ar->dev_flags),
+ ar->coex.wlan_prio_mask,
+ ar->coex.wlan_weight);
+ mutex_unlock(&ar->conf_mutex);
+ return simple_read_from_buffer(ubuf, count, ppos, buf, len);
+}
+
+static const struct file_operations fops__btcoex = {
+ .read = ath11k_read_btcoex,
+ .write = ath11k_write_btcoex,
+ .open = simple_open
+};
+
+
+static ssize_t ath11k_write_btcoex_duty_cycle(struct file *file,
+ const char __user *ubuf,
+ size_t count, loff_t *ppos)
+{
+ struct ath11k_vif *arvif;
+ struct ath11k *ar = file->private_data;
+ struct coex_config_arg coex_config;
+ char buf[256];
+ size_t buf_size;
+ u32 duty_cycle,wlan_duration;
+ int ret;
+
+ if (!ar)
+ return -EINVAL;
+
+ if (!test_bit(ATH11K_FLAG_BTCOEX, &ar->dev_flags))
+ return -EINVAL;
+
+ if (ar->coex.coex_algo_type != COEX_ALGO_OCS) {
+ ath11k_err(ar->ab,"duty cycle algo is not enabled");
+ return -EINVAL;
+ }
+
+ buf_size = min(count, (sizeof(buf) - 1));
+ if (copy_from_user(buf, ubuf, buf_size))
+ return -EFAULT;
+
+ buf[buf_size] = '\0';
+ ret = sscanf(buf, "%d %d" , &duty_cycle, &wlan_duration);
+
+ if (!ret)
+ return -EINVAL;
+
+ /*Maximum duty_cycle period allowed is 100 Miliseconds*/
+ if (duty_cycle < wlan_duration || !duty_cycle || !wlan_duration || duty_cycle > 100000)
+ return -EINVAL;
+
+ mutex_lock(&ar->conf_mutex);
+ arvif = list_first_entry(&ar->arvifs, typeof(*arvif), list);
+ if (!arvif->is_started) {
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ coex_config.vdev_id = arvif->vdev_id;
+ coex_config.config_type = WMI_COEX_CONFIG_AP_TDM;
+ coex_config.duty_cycle = duty_cycle;
+ coex_config.wlan_duration = wlan_duration;
+
+ ret = ath11k_send_coex_config_cmd(ar, &coex_config);
+ if (ret) {
+ ath11k_warn(ar->ab,
+ "failed to set coex config vdev_id %d ret %d\n",
+ coex_config.vdev_id, ret);
+ goto exit;
+ }
+
+ ar->coex.duty_cycle = duty_cycle;
+ ar->coex.wlan_duration = wlan_duration;
+ ret = count;
+exit:
+ mutex_unlock(&ar->conf_mutex);
+ return ret;
+
+}
+
+static ssize_t ath11k_read_btcoex_duty_cycle(struct file *file, char __user *ubuf,
+ size_t count, loff_t *ppos)
+{
+ struct ath11k *ar = file->private_data;
+ char buf[256];
+ int len =0;
+
+ if (!ar)
+ return -EINVAL;
+
+ len = scnprintf(buf, sizeof(buf) - len, "%d %d\n",
+ ar->coex.duty_cycle,ar->coex.wlan_duration);
+ return simple_read_from_buffer(ubuf, count, ppos, buf, len);
+}
+
+
+static const struct file_operations fops__btcoex_duty_cycle = {
+ .read = ath11k_read_btcoex_duty_cycle,
+ .write = ath11k_write_btcoex_duty_cycle,
+ .open = simple_open
+};
+
int ath11k_debug_register(struct ath11k *ar)
{
struct ath11k_base *ab = ar->ab;
@@ -1390,6 +1570,12 @@ int ath11k_debug_register(struct ath11k
debugfs_create_file("pktlog_filter", 0644,
ar->debug.debugfs_pdev, ar,
&fops_pktlog_filter);
+ debugfs_create_file("btcoex", 0644,
+ ar->debug.debugfs_pdev, ar,
+ &fops__btcoex);
+ debugfs_create_file("btcoex_duty_cycle", 0644,
+ ar->debug.debugfs_pdev, ar,
+ &fops__btcoex_duty_cycle);
if (ar->hw->wiphy->bands[NL80211_BAND_5GHZ]) {
debugfs_create_file("dfs_simulate_radar", 0200,
--- a/drivers/net/wireless/ath/ath11k/wmi.c
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
@@ -1556,6 +1556,17 @@ static void ath11k_wmi_copy_coex_config(
coex_config->bt_txrx_time, coex_config->bt_priority_time,
coex_config->pta_algorithm, coex_config->pta_priority);
}
+
+ if (coex_config->config_type == WMI_COEX_CONFIG_AP_TDM) {
+ cmd->duty_cycle = coex_config->duty_cycle;
+ cmd->wlan_duration = coex_config->wlan_duration;
+ ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
+ "WMI coex config type %u vdev id %d duty_cycle %u wlan_duration %u\n",
+ coex_config->config_type,
+ coex_config->vdev_id,
+ coex_config->duty_cycle,
+ coex_config->wlan_duration);
+ }
}
int ath11k_send_coex_config_cmd(struct ath11k *ar,
--- a/drivers/net/wireless/ath/ath11k/wmi.h
+++ b/drivers/net/wireless/ath/ath11k/wmi.h
@@ -4784,6 +4784,10 @@ struct coex_config_arg {
u32 wlan_pkt_weight;
u32 bt_pkt_weight;
};
+ struct {
+ u32 duty_cycle;
+ u32 wlan_duration;
+ };
};
};
@@ -4811,6 +4815,11 @@ struct wmi_coex_config_cmd {
u32 wlan_pkt_weight;
u32 bt_pkt_weight;
} __packed;
+
+ struct {
+ u32 duty_cycle;
+ u32 wlan_duration;
+ } __packed;
} __packed;
} __packed;
--- a/drivers/net/wireless/ath/ath11k/vendor.c
+++ b/drivers/net/wireless/ath/ath11k/vendor.c
@@ -9,102 +9,10 @@
#include "debug.h"
static const struct nla_policy
-ath11k_vendor_btcoex_config_policy[QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_MAX + 1] = {
- [QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_ENABLE] = { .type = NLA_U8 },
- [QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_WLAN_PRIORITY] = { .type = NLA_NESTED },
-};
-
-static const struct nla_policy
-ath11k_vendor_wlan_prio_policy[QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_MAX + 1] = {
- [QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_MASK] = { .type = NLA_U8 },
- [QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_WEIGHT] = { .type = NLA_U8 },
-};
-
-static const struct nla_policy
ath11k_vendor_set_wifi_config_policy[QCA_WLAN_VENDOR_ATTR_CONFIG_MAX + 1] = {
[QCA_WLAN_VENDOR_ATTR_CONFIG_GTX] = {.type = NLA_FLAG}
};
-static int ath11k_vendor_btcoex_configure(struct wiphy *wiphy,
- struct wireless_dev *wdev,
- const void *data,
- int data_len)
-{
- struct ieee80211_vif *vif;
- struct ath11k_vif *arvif;
- struct ath11k *ar;
- struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_MAX + 1];
- struct nlattr *tb_wlan_prio[QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_MAX + 1];
- struct nlattr *wlan_prio;
- enum qca_wlan_priority_type wlan_prio_mask = 0;
- int ret, coex = -1, rem_conf;
- u8 wlan_weight = 0;
-
- if (!wdev)
- return -EINVAL;
-
- vif = wdev_to_ieee80211_vif(wdev);
- if (!vif)
- return -EINVAL;
-
- arvif = (struct ath11k_vif *)vif->drv_priv;
- if (!arvif)
- return -EINVAL;
-
- ar = arvif->ar;
-
- mutex_lock(&ar->conf_mutex);
-
- ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_MAX, data, data_len,
- ath11k_vendor_btcoex_config_policy, NULL);
- if (ret) {
- ath11k_warn(ar->ab, "invalid BTCOEX config policy attribute\n");
- goto out;
- }
-
- if (!tb[QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_ENABLE] &&
- !tb[QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_WLAN_PRIORITY]) {
- ath11k_warn(ar->ab, "invalid BTCOEX config attributes\n");
- ret = -EINVAL;
- goto out;
- }
-
- if (tb[QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_ENABLE]) {
- coex = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_ENABLE]);
- ret = ath11k_mac_coex_config(ar, arvif, coex, wlan_prio_mask, wlan_weight);
- if (ret)
- goto out;
- }
- if (tb[QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_WLAN_PRIORITY]) {
- nla_for_each_nested(wlan_prio,
- tb[QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_WLAN_PRIORITY],
- rem_conf) {
- ret =
- nla_parse_nested(tb_wlan_prio, QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_MAX,
- wlan_prio, ath11k_vendor_wlan_prio_policy,
- NULL);
- if (ret)
- goto out;
- wlan_prio_mask =
- nla_get_u8(tb_wlan_prio[QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_MASK]);
- if (tb_wlan_prio[QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_WEIGHT])
- wlan_weight =
- nla_get_u8(tb_wlan_prio[QCA_WLAN_VENDOR_ATTR_WLAN_PRIO_WEIGHT]);
- ath11k_dbg(ar->ab, ATH11K_DBG_MAC,
- "BTCOEX enable %u WLAN Priority %u wlan weight %u\n",
- coex, wlan_prio_mask, wlan_weight);
-
- ret = ath11k_mac_coex_config(ar, arvif, coex, wlan_prio_mask, wlan_weight);
- if (ret)
- goto out;
- }
- }
-
-out:
- mutex_unlock(&ar->conf_mutex);
- return ret;
-}
-
static int ath11k_vendor_set_wifi_config(struct wiphy *wihpy,
struct wireless_dev *wdev,
const void *data,
@@ -153,15 +61,6 @@ exit:
static struct wiphy_vendor_command ath11k_vendor_commands[] = {
{
.info.vendor_id = QCA_NL80211_VENDOR_ID,
- .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_BTCOEX_CONFIG,
- .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
- WIPHY_VENDOR_CMD_NEED_RUNNING,
- .doit = ath11k_vendor_btcoex_configure,
- .policy = ath11k_vendor_btcoex_config_policy,
- .maxattr = QCA_WLAN_VENDOR_ATTR_BTCOEX_CONFIG_MAX
- },
- {
- .info.vendor_id = QCA_NL80211_VENDOR_ID,
.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
WIPHY_VENDOR_CMD_NEED_RUNNING,
--- a/drivers/net/wireless/ath/ath11k/core.h
+++ b/drivers/net/wireless/ath/ath11k/core.h
@@ -476,6 +476,10 @@ struct ath11k_coex_info {
u32 bt_priority_time_slot;
u32 coex_algo_type;
u32 pta_priority;
+ u32 wlan_prio_mask;
+ u32 wlan_weight;
+ u32 duty_cycle;
+ u32 wlan_duration;
};
enum ath11k_ap_ps_state {
@@ -483,6 +487,12 @@ enum ath11k_ap_ps_state {
ATH11K_AP_PS_STATE_ON,
};
+enum coex_algo {
+ COEX_ALGO_UNCONS_FREERUN = 0,
+ COEX_ALGO_FREERUN,
+ COEX_ALGO_OCS,
+};
+
struct ath11k {
struct ath11k_base *ab;
struct ath11k_pdev *pdev;