ath10k: debugfs file to enable Bluetooth coexistence feature
As not all QCA98XX radios are not connected to Bluetooth modules, enabling the BT coex feature in firmware will have side effects if the radio's GPIO are connected with other (non-BT) HW modules. Add debugfs file to control the firmware BT coex logic and set the feature as disable by default to avoid that btcoex is accidentally enabled. To enable this feature, execute: echo 1 > /sys/kernel/debug/ieee80211/phyX/ath10k/btcoex To disable: echo 0 > /sys/kernel/debug/ieee80211/phyX/ath10k/btcoex The firmware support this feature since 10.2.4.54 on 2G-only board, dual band or 5G boards don't support this. The feature's name is WMI_SERVICE_COEX_GPIO and the btcoex file is not created if firmware doesn't support it. Signed-off-by: Yanbo Li <yanbol@qca.qualcomm.com> [kvalo@qca.qualcomm.com: use btcoex filename and other smaller fixes] Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
This commit is contained in:
parent
afb0bf7f53
commit
844fa57227
@ -538,6 +538,9 @@ enum ath10k_dev_flags {
|
||||
|
||||
/* Disable HW crypto engine */
|
||||
ATH10K_FLAG_HW_CRYPTO_DISABLED,
|
||||
|
||||
/* Bluetooth coexistance enabled */
|
||||
ATH10K_FLAG_BTCOEX,
|
||||
};
|
||||
|
||||
enum ath10k_cal_mode {
|
||||
|
@ -2074,6 +2074,68 @@ static const struct file_operations fops_quiet_period = {
|
||||
.open = simple_open
|
||||
};
|
||||
|
||||
static ssize_t ath10k_write_btcoex(struct file *file,
|
||||
const char __user *ubuf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ath10k *ar = file->private_data;
|
||||
char buf[32];
|
||||
size_t buf_size;
|
||||
bool val;
|
||||
|
||||
buf_size = min(count, (sizeof(buf) - 1));
|
||||
if (copy_from_user(buf, ubuf, buf_size))
|
||||
return -EFAULT;
|
||||
|
||||
buf[buf_size] = '\0';
|
||||
|
||||
if (strtobool(buf, &val) != 0)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
|
||||
if (!(test_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags) ^ val))
|
||||
goto exit;
|
||||
|
||||
if (val)
|
||||
set_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags);
|
||||
else
|
||||
clear_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags);
|
||||
|
||||
if (ar->state != ATH10K_STATE_ON)
|
||||
goto exit;
|
||||
|
||||
ath10k_info(ar, "restarting firmware due to btcoex change");
|
||||
|
||||
queue_work(ar->workqueue, &ar->restart_work);
|
||||
|
||||
exit:
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t ath10k_read_btcoex(struct file *file, char __user *ubuf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
char buf[32];
|
||||
struct ath10k *ar = file->private_data;
|
||||
int len = 0;
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
len = scnprintf(buf, sizeof(buf) - len, "%d\n",
|
||||
test_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags));
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
|
||||
return simple_read_from_buffer(ubuf, count, ppos, buf, len);
|
||||
}
|
||||
|
||||
static const struct file_operations fops_btcoex = {
|
||||
.read = ath10k_read_btcoex,
|
||||
.write = ath10k_write_btcoex,
|
||||
.open = simple_open
|
||||
};
|
||||
|
||||
int ath10k_debug_create(struct ath10k *ar)
|
||||
{
|
||||
ar->debug.fw_crash_data = vzalloc(sizeof(*ar->debug.fw_crash_data));
|
||||
@ -2183,6 +2245,10 @@ int ath10k_debug_register(struct ath10k *ar)
|
||||
debugfs_create_file("tpc_stats", S_IRUSR,
|
||||
ar->debug.debugfs_phy, ar, &fops_tpc_stats);
|
||||
|
||||
if (test_bit(WMI_SERVICE_COEX_GPIO, ar->wmi.svc_map))
|
||||
debugfs_create_file("btcoex", S_IRUGO | S_IWUSR,
|
||||
ar->debug.debugfs_phy, ar, &fops_btcoex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -5476,8 +5476,11 @@ static struct sk_buff *ath10k_wmi_10_2_op_gen_init(struct ath10k *ar)
|
||||
cmd = (struct wmi_init_cmd_10_2 *)buf->data;
|
||||
|
||||
features = WMI_10_2_RX_BATCH_MODE;
|
||||
if (test_bit(WMI_SERVICE_COEX_GPIO, ar->wmi.svc_map))
|
||||
|
||||
if (test_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags) &&
|
||||
test_bit(WMI_SERVICE_COEX_GPIO, ar->wmi.svc_map))
|
||||
features |= WMI_10_2_COEX_GPIO;
|
||||
|
||||
cmd->resource_config.feature_mask = __cpu_to_le32(features);
|
||||
|
||||
memcpy(&cmd->resource_config.common, &config, sizeof(config));
|
||||
|
Loading…
Reference in New Issue
Block a user