wlan-ap-Telecominfraproject/feeds/ipq807x/mac80211/patches/112-ath11k-add-btcoex-debugfs-support.patch
John Crispin 3affbc1cad QualComm/AX: add Hawkeye and Cypress support
This series is based on
* 2020-07-10 ipq6018-ilq-11-0_qca_oem-034672b0676c37b1f4519e5720e18e95fe6236ef

Add support for
* qsdk kernel/v4.4
* qsdk ethernet subsystem
* v5.7 ath11k backport + QualComm staging patches (wlan_ap_1.0)
* ath11k-firmware
* hostapd/iw/...

Feature support
* full boot, system detection
* sysupgrade to nand
* HE support via latest hostapd
* driver support for usb, crypto, hwmon, cpufreq, ...

Missing
* NSS/HW flow offloading - FW blob is not redistributable

Using the qsdk v4.4 is an intermediate solution while the vanilla is being
tested. Vanilla kernel is almost on feature par. Work has already started
to upstream the ethernet and switch drivers. Once complete the target will
be fully upstream.

Signed-off-by: John Crispin <john@phrozen.org>
2020-07-23 18:54:03 +02:00

395 lines
11 KiB
Diff

--- a/drivers/net/wireless/ath/ath11k/debug.c
+++ b/drivers/net/wireless/ath/ath11k/debug.c
@@ -1371,6 +1371,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;
@@ -1406,6 +1586,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
@@ -1537,6 +1537,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
@@ -4754,6 +4754,10 @@ struct coex_config_arg {
u32 wlan_pkt_weight;
u32 bt_pkt_weight;
};
+ struct {
+ u32 duty_cycle;
+ u32 wlan_duration;
+ };
};
};
@@ -4781,6 +4785,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
@@ -478,6 +478,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 {
@@ -485,6 +489,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;